[
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\nlfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry\npolar: # Replace with a single Polar username\nbuy_me_a_coffee: # Replace with a single Buy Me a Coffee username\nthanks_dev: # Replace with a single thanks.dev username\ncustom: ['https://boosty.to/t8rin']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug Report\ndescription: Create a report to help us improve\nlabels: [\"bug\"]\n\nbody:\n  - type: textarea\n    id: description\n    attributes:\n      label: Describe the bug\n      description: A clear and concise description of what the bug is.\n      placeholder: Tell us what happened...\n    validations:\n      required: true\n\n  - type: textarea\n    id: reproduce\n    attributes:\n      label: Steps to reproduce\n      description: Steps to reproduce the behavior\n      placeholder: |\n        1. Go to '...'\n        2. Click on '....'\n        3. Scroll down to '....'\n        4. See error\n    validations:\n      required: true\n\n  - type: textarea\n    id: expected\n    attributes:\n      label: Expected behavior\n      description: A clear and concise description of what you expected to happen.\n      placeholder: Tell us what should have happened...\n    validations:\n      required: true\n\n  - type: textarea\n    id: screenshots\n    attributes:\n      label: Screenshots\n      description: If applicable, add screenshots to help explain your problem.\n      placeholder: You can drag and drop images here...\n\n  - type: input\n    id: device\n    attributes:\n      label: Device\n      placeholder: e.g., Samsung Galaxy S23\n    validations:\n      required: true\n\n  - type: input\n    id: os\n    attributes:\n      label: OS\n      placeholder: e.g., Android 14\n    validations:\n      required: true\n\n  - type: input\n    id: locale\n    attributes:\n      label: Locale\n      placeholder: e.g., en-US, ru-RU\n\n  - type: input\n    id: version\n    attributes:\n      label: App Version\n      placeholder: e.g., 1.2.3\n    validations:\n      required: true\n\n  - type: dropdown\n    id: variant\n    attributes:\n      label: FOSS or Market\n      description: Which variant of the app are you using?\n      options:\n        - FOSS\n        - Market (Google Play)\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "content": "name: Feature Request\ndescription: Suggest an idea for this project\nlabels: [\"enhancement\"]\n\nbody:\n  - type: textarea\n    id: problem\n    attributes:\n      label: Is your feature request related to a problem? Please describe.\n      placeholder: A clear and concise description of what the problem is...\n    validations:\n      required: false\n\n  - type: textarea\n    id: solution\n    attributes:\n      label: Describe the solution you'd like\n      placeholder: A clear and concise description of what you want to happen...\n    validations:\n      required: true\n\n  - type: textarea\n    id: alternatives\n    attributes:\n      label: Describe alternatives you've considered\n      placeholder: A clear and concise description of any alternative solutions or features you've considered...\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"gradle\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/android.yml",
    "content": "name: Android CI\n\non:\n  workflow_dispatch:\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Set Swap Space\n        uses: pierotofy/set-swap-space@master\n        with:\n          swap-size-gb: 10\n\n      - uses: actions/checkout@v4\n\n      - name: set up JDK 21\n        uses: actions/setup-java@v4\n        with:\n          java-version: '21'\n          distribution: 'adopt'\n          java-package: 'jdk'\n          cache: gradle\n\n      - name: Set up Keystore\n        run: |\n          sudo apt update -y || true\n          sudo apt install -y --no-install-recommends coreutils\n          mkdir -p $RUNNER_TEMP/keystores\n          echo \"${{ secrets.SIGNING_KEY }}\" | base64 --decode > $RUNNER_TEMP/keystores/keystore.jks\n\n      - name: Build FOSS APKs\n        run: bash ./gradlew assembleFossRelease\n\n      - name: Sign FOSS APKs\n        run: |\n          ANDROID_SDK_PATH=$ANDROID_HOME/build-tools/35.0.0/apksigner\n          for apk in app/build/outputs/apk/foss/release/*.apk; do\n            $ANDROID_SDK_PATH sign \\\n              --ks $RUNNER_TEMP/keystores/keystore.jks \\\n              --ks-key-alias ${{ secrets.ALIAS }} \\\n              --ks-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --key-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --out \"$apk\" \\\n              \"$apk\"\n          done\n\n      - name: Upload FOSS APKs\n        uses: actions/upload-artifact@v4\n        with:\n          name: Signed FOSS APKs\n          path: app/build/outputs/apk/foss/release/*.apk\n\n      - name: Delete FOSS APKs\n        run: rm -rf app/build/outputs/apk/foss\n\n      - name: Build Market APKs\n        run: bash ./gradlew assembleMarketRelease\n\n      - name: Sign Market APKs\n        run: |\n          ANDROID_SDK_PATH=$ANDROID_HOME/build-tools/35.0.0/apksigner\n          for apk in app/build/outputs/apk/market/release/*.apk; do\n            $ANDROID_SDK_PATH sign \\\n              --ks $RUNNER_TEMP/keystores/keystore.jks \\\n              --ks-key-alias ${{ secrets.ALIAS }} \\\n              --ks-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --key-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --out \"$apk\" \\\n              \"$apk\"\n          done\n\n      - name: Upload Market APKs\n        uses: actions/upload-artifact@v4\n        with:\n          name: Signed Market APKs\n          path: app/build/outputs/apk/market/release/*.apk\n\n      - name: Delete Market APKs\n        run: rm -rf app/build/outputs/apk/market"
  },
  {
    "path": ".github/workflows/android_foss.yml",
    "content": "name: Android CI FOSS\n\non:\n  workflow_dispatch:\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Set Swap Space\n        uses: pierotofy/set-swap-space@master\n        with:\n          swap-size-gb: 10\n\n      - uses: actions/checkout@v4\n\n      - name: set up JDK 21\n        uses: actions/setup-java@v4\n        with:\n          java-version: '21'\n          distribution: 'adopt'\n          java-package: 'jdk'\n          cache: gradle\n\n      - name: Set up Keystore\n        run: |\n          sudo apt update -y || true\n          sudo apt install -y --no-install-recommends coreutils\n          mkdir -p $RUNNER_TEMP/keystores\n          echo \"${{ secrets.SIGNING_KEY }}\" | base64 --decode > $RUNNER_TEMP/keystores/keystore.jks\n\n      - name: Build FOSS APKs\n        run: bash ./gradlew assembleFossRelease\n\n      - name: Sign FOSS APKs\n        run: |\n          ANDROID_SDK_PATH=$ANDROID_HOME/build-tools/35.0.0/apksigner\n          for apk in app/build/outputs/apk/foss/release/*.apk; do\n            $ANDROID_SDK_PATH sign \\\n              --ks $RUNNER_TEMP/keystores/keystore.jks \\\n              --ks-key-alias ${{ secrets.ALIAS }} \\\n              --ks-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --key-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --out \"$apk\" \\\n              \"$apk\"\n          done\n\n      - name: Upload FOSS APKs\n        uses: actions/upload-artifact@v4\n        with:\n          name: Signed FOSS APKs\n          path: app/build/outputs/apk/foss/release/*.apk\n\n      - name: Delete FOSS APKs\n        run: rm -rf app/build/outputs/apk/foss"
  },
  {
    "path": ".github/workflows/android_market.yml",
    "content": "name: Android CI Market\n\non:\n  workflow_dispatch:\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Set Swap Space\n        uses: pierotofy/set-swap-space@master\n        with:\n          swap-size-gb: 10\n\n      - uses: actions/checkout@v4\n\n      - name: set up JDK 21\n        uses: actions/setup-java@v4\n        with:\n          java-version: '21'\n          distribution: 'adopt'\n          java-package: 'jdk'\n          cache: gradle\n\n      - name: Set up Keystore\n        run: |\n          sudo apt update -y || true\n          sudo apt install -y --no-install-recommends coreutils\n          mkdir -p $RUNNER_TEMP/keystores\n          echo \"${{ secrets.SIGNING_KEY }}\" | base64 --decode > $RUNNER_TEMP/keystores/keystore.jks\n\n      - name: Build Market APKs\n        run: bash ./gradlew assembleMarketRelease\n\n      - name: Sign Market APKs\n        run: |\n          ANDROID_SDK_PATH=$ANDROID_HOME/build-tools/35.0.0/apksigner\n          for apk in app/build/outputs/apk/market/release/*.apk; do\n            $ANDROID_SDK_PATH sign \\\n              --ks $RUNNER_TEMP/keystores/keystore.jks \\\n              --ks-key-alias ${{ secrets.ALIAS }} \\\n              --ks-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --key-pass pass:${{ secrets.KEY_STORE_PASS }} \\\n              --out \"$apk\" \\\n              \"$apk\"\n          done\n\n      - name: Upload Market APKs\n        uses: actions/upload-artifact@v4\n        with:\n          name: Signed Market APKs\n          path: app/build/outputs/apk/market/release/*.apk\n\n      - name: Delete Market APKs\n        run: rm -rf app/build/outputs/apk/market"
  },
  {
    "path": ".github/workflows/tb_release.yml",
    "content": "name: Create Release\n\non:\n  workflow_dispatch:\n#on:\n#  push:\n#    tags:\n#      - '*'\n\njobs:\n  build_and_release:\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v3\n      - name: set up JDK 17\n        uses: actions/setup-java@v3\n        with:\n          java-version: '17'\n          distribution: 'adopt'\n          cache: gradle\n\n      - name: Set version variable\n        run: echo \"GITHUB_REF_NAME=$GITHUB_REF_NAME\" >> $GITHUB_ENV\n\n      - name: Assemble release\n        env:\n          VERSION_NAME: ${{ env.GITHUB_REF_NAME }}\n        run: bash ./gradlew assembleRelease\n\n      - uses: iota9star/sign-android-release@v1.0.5\n        name: Sign FOSS APK\n        # ID used to access action output\n        id: sign_app_foss\n        with:\n          releaseDirectory: app/build/outputs/apk/foss/release\n          fileRex: .*apk\n          signingKeyBase64: ${{ secrets.SIGNING_KEY }}\n          alias: ${{ secrets.ALIAS }}\n          keyStorePassword: ${{ secrets.KEY_STORE_PASS }}\n          keyPassword: ${{ secrets.KEY_STORE_PASS }}\n        env:\n          BUILD_TOOLS_VERSION: \"34.0.0\"\n\n      - name: Rename foss file stage\n        run: |\n          ls -la app/build/outputs/apk/market/release\n          mv \"app/build/outputs/apk/foss/release/image-toolbox-$GITHUB_REF_NAME-foss-arm64-v8a-release-unsigned-signed.apk\" \"image-toolbox-$GITHUB_REF_NAME-foss-arm64-v8a.apk\"\n          mv \"app/build/outputs/apk/foss/release/image-toolbox-$GITHUB_REF_NAME-foss-universal-release-unsigned-signed.apk\" \"image-toolbox-$GITHUB_REF_NAME-foss-universal.apk\"\n          mv \"app/build/outputs/apk/foss/release/image-toolbox-$GITHUB_REF_NAME-foss-armeabi-v7a-release-unsigned-signed.apk\" \"image-toolbox-$GITHUB_REF_NAME-foss-armeabi-v7a.apk\"\n          mv \"app/build/outputs/apk/foss/release/image-toolbox-$GITHUB_REF_NAME-foss-x86_64-release-unsigned-signed.apk\" \"image-toolbox-$GITHUB_REF_NAME-foss-x86_64.apk\"\n\n      - uses: iota9star/sign-android-release@v1.0.5\n        name: Sign Market APK\n        # ID used to access action output\n        id: sign_app_market\n        with:\n          releaseDirectory: app/build/outputs/apk/market/release\n          fileRex: .*apk\n          signingKeyBase64: ${{ secrets.SIGNING_KEY }}\n          alias: ${{ secrets.ALIAS }}\n          keyStorePassword: ${{ secrets.KEY_STORE_PASS }}\n          keyPassword: ${{ secrets.KEY_STORE_PASS }}\n        env:\n          BUILD_TOOLS_VERSION: \"34.0.0\"\n\n      - name: Rename market file stage\n        env:\n          VERSION_NAME: ${{ env.GITHUB_REF_NAME }}\n        run: |\n          ls -la app/build/outputs/apk/market/release\n          mv \"app/build/outputs/apk/market/release/image-toolbox-$VERSION_NAME-market-arm64-v8a-release-unsigned-signed.apk\" \"image-toolbox-$VERSION_NAME-arm64-v8a.apk\"\n          mv \"app/build/outputs/apk/market/release/image-toolbox-$VERSION_NAME-market-universal-release-unsigned-signed.apk\" \"image-toolbox-$VERSION_NAME-universal.apk\"\n          mv \"app/build/outputs/apk/market/release/image-toolbox-$VERSION_NAME-market-armeabi-v7a-release-unsigned-signed.apk\" \"image-toolbox-$VERSION_NAME-armeabi-v7a.apk\"\n          mv \"app/build/outputs/apk/market/release/image-toolbox-$VERSION_NAME-market-x86_64-release-unsigned-signed.apk\" \"image-toolbox-$VERSION_NAME-x86_64.apk\"\n\n      - uses: actions/upload-artifact@v4\n        id: signed-market-apk\n        with:\n          name: Signed apks Market\n          path: \"*.apk\"\n\n  create_release:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    needs:\n      - build_and_release\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n      - name: Download All Artifacts\n        uses: actions/download-artifact@v4\n        with:\n          merge-multiple: true\n      - name: Display all downloaded files\n        run: ls -la\n      - name: Set version variable\n        run: echo \"GITHUB_REF_NAME=$GITHUB_REF_NAME\" >> $GITHUB_ENV\n      - name: Set Pre-release flag\n        run: |\n          if [[ \"$GITHUB_REF_NAME\" == *-* ]]; then\n              # If GITHUB_REF_NAME contains a hyphen, set GITHUB_OTHER_ENV to true\n              echo \"PRE_RELEASE_FLAG=true\" >> $GITHUB_ENV\n          else\n              # If GITHUB_REF_NAME does not contain a hyphen, set GITHUB_OTHER_ENV to false\n              echo \"PRE_RELEASE_FLAG=false\" >> $GITHUB_ENV\n          fi\n      - uses: ncipollo/release-action@v1\n        with:\n          artifacts: \"*.apk\"\n          prerelease: ${{ env.PRE_RELEASE_FLAG }}"
  },
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n.DS_Store\n/build\n/app/release\n/captures\n.externalNativeBuild\n.cxx\n/.idea\n/libs/nQuant/build\n/.kotlin/errors/\n/.kotlin\n"
  },
  {
    "path": "ARCHITECTURE.md",
    "content": "# 📐 Modules Graph\n\n```mermaid\n%%{\n    init: {\n      \"theme\": \"base\",\n      \"themeVariables\": {\n        \"mainBkg\": \"#121418\",\n        \"primaryColor\": \"#1b3a1b\",\n        \"primaryTextColor\": \"#e0e3de\",\n        \"primaryBorderColor\": \"#76c893\",\n        \"nodeBorder\": \"#76c893\",\n        \"lineColor\": \"#76c893\",\n        \"secondaryColor\": \"#1f2721\",\n        \"tertiaryColor\": \"#232c26\",\n        \"clusterBkg\": \"#182018\",\n        \"clusterBorder\": \"#4caf50\",\n        \"nodeTextColor\": \"#e0e3de\",\n        \"edgeLabelBackground\": \"#111316\",\n        \"edgeLabelColor\": \"#cfe9de\",\n        \"fontSize\": \"28px\",\n        \"fontFamily\": \"JetBrains Mono, Inter, system-ui\"\n      }\n    }\n}%%\n\ngraph LR\n    subgraph :core\n        :core:data(\"data\")\n        :core:ui(\"ui\")\n        :core:domain(\"domain\")\n        :core:resources(\"resources\")\n        :core:settings(\"settings\")\n        :core:di(\"di\")\n        :core:crash(\"crash\")\n        :core:utils(\"utils\")\n        :core:filters(\"filters\")\n        :core:ksp(\"ksp\")\n    end\n    subgraph :feature\n        :feature:root(\"root\")\n        :feature:main(\"main\")\n        :feature:load-net-image(\"load-net-image\")\n        :feature:crop(\"crop\")\n        :feature:limits-resize(\"limits-resize\")\n        :feature:cipher(\"cipher\")\n        :feature:image-preview(\"image-preview\")\n        :feature:weight-resize(\"weight-resize\")\n        :feature:compare(\"compare\")\n        :feature:delete-exif(\"delete-exif\")\n        :feature:palette-tools(\"palette-tools\")\n        :feature:resize-convert(\"resize-convert\")\n        :feature:pdf-tools(\"pdf-tools\")\n        :feature:single-edit(\"single-edit\")\n        :feature:erase-background(\"erase-background\")\n        :feature:draw(\"draw\")\n        :feature:filters(\"filters\")\n        :feature:image-stitch(\"image-stitch\")\n        :feature:pick-color(\"pick-color\")\n        :feature:recognize-text(\"recognize-text\")\n        :feature:gradient-maker(\"gradient-maker\")\n        :feature:watermarking(\"watermarking\")\n        :feature:gif-tools(\"gif-tools\")\n        :feature:apng-tools(\"apng-tools\")\n        :feature:zip(\"zip\")\n        :feature:jxl-tools(\"jxl-tools\")\n        :feature:settings(\"settings\")\n        :feature:easter-egg(\"easter-egg\")\n        :feature:svg-maker(\"svg-maker\")\n        :feature:format-conversion(\"format-conversion\")\n        :feature:document-scanner(\"document-scanner\")\n        :feature:scan-qr-code(\"scan-qr-code\")\n        :feature:image-stacking(\"image-stacking\")\n        :feature:image-splitting(\"image-splitting\")\n        :feature:color-tools(\"color-tools\")\n        :feature:webp-tools(\"webp-tools\")\n        :feature:noise-generation(\"noise-generation\")\n        :feature:collage-maker(\"collage-maker\")\n        :feature:libraries-info(\"libraries-info\")\n        :feature:markup-layers(\"markup-layers\")\n        :feature:base64-tools(\"base64-tools\")\n        :feature:checksum-tools(\"checksum-tools\")\n        :feature:mesh-gradients(\"mesh-gradients\")\n        :feature:edit-exif(\"edit-exif\")\n        :feature:image-cutting(\"image-cutting\")\n        :feature:audio-cover-extractor(\"audio-cover-extractor\")\n        :feature:library-details(\"library-details\")\n        :feature:wallpapers-export(\"wallpapers-export\")\n        :feature:ascii-art(\"ascii-art\")\n        :feature:ai-tools(\"ai-tools\")\n        :feature:media-picker(\"media-picker\")\n        :feature:quick-tiles(\"quick-tiles\")\n    end\n    :feature:root --> :core:data\n    :feature:root --> :core:ui\n    :feature:root --> :core:domain\n    :feature:root --> :core:resources\n    :feature:root --> :core:settings\n    :feature:root --> :core:di\n    :feature:root --> :core:crash\n    :feature:root --> :feature:main\n    :feature:root --> :feature:load-net-image\n    :feature:root --> :feature:crop\n    :feature:root --> :feature:limits-resize\n    :feature:root --> :feature:cipher\n    :feature:root --> :feature:image-preview\n    :feature:root --> :feature:weight-resize\n    :feature:root --> :feature:compare\n    :feature:root --> :feature:delete-exif\n    :feature:root --> :feature:palette-tools\n    :feature:root --> :feature:resize-convert\n    :feature:root --> :feature:pdf-tools\n    :feature:root --> :feature:single-edit\n    :feature:root --> :feature:erase-background\n    :feature:root --> :feature:draw\n    :feature:root --> :feature:filters\n    :feature:root --> :feature:image-stitch\n    :feature:root --> :feature:pick-color\n    :feature:root --> :feature:recognize-text\n    :feature:root --> :feature:gradient-maker\n    :feature:root --> :feature:watermarking\n    :feature:root --> :feature:gif-tools\n    :feature:root --> :feature:apng-tools\n    :feature:root --> :feature:zip\n    :feature:root --> :feature:jxl-tools\n    :feature:root --> :feature:settings\n    :feature:root --> :feature:easter-egg\n    :feature:root --> :feature:svg-maker\n    :feature:root --> :feature:format-conversion\n    :feature:root --> :feature:document-scanner\n    :feature:root --> :feature:scan-qr-code\n    :feature:root --> :feature:image-stacking\n    :feature:root --> :feature:image-splitting\n    :feature:root --> :feature:color-tools\n    :feature:root --> :feature:webp-tools\n    :feature:root --> :feature:noise-generation\n    :feature:root --> :feature:collage-maker\n    :feature:root --> :feature:libraries-info\n    :feature:root --> :feature:markup-layers\n    :feature:root --> :feature:base64-tools\n    :feature:root --> :feature:checksum-tools\n    :feature:root --> :feature:mesh-gradients\n    :feature:root --> :feature:edit-exif\n    :feature:root --> :feature:image-cutting\n    :feature:root --> :feature:audio-cover-extractor\n    :feature:root --> :feature:library-details\n    :feature:root --> :feature:wallpapers-export\n    :feature:root --> :feature:ascii-art\n    :feature:root --> :feature:ai-tools\n    :feature:erase-background --> :core:data\n    :feature:erase-background --> :core:ui\n    :feature:erase-background --> :core:domain\n    :feature:erase-background --> :core:resources\n    :feature:erase-background --> :core:settings\n    :feature:erase-background --> :core:di\n    :feature:erase-background --> :core:crash\n    :feature:erase-background --> :feature:draw\n    :feature:edit-exif --> :core:data\n    :feature:edit-exif --> :core:ui\n    :feature:edit-exif --> :core:domain\n    :feature:edit-exif --> :core:resources\n    :feature:edit-exif --> :core:settings\n    :feature:edit-exif --> :core:di\n    :feature:edit-exif --> :core:crash\n    :feature:limits-resize --> :core:data\n    :feature:limits-resize --> :core:ui\n    :feature:limits-resize --> :core:domain\n    :feature:limits-resize --> :core:resources\n    :feature:limits-resize --> :core:settings\n    :feature:limits-resize --> :core:di\n    :feature:limits-resize --> :core:crash\n    :feature:jxl-tools --> :core:data\n    :feature:jxl-tools --> :core:ui\n    :feature:jxl-tools --> :core:domain\n    :feature:jxl-tools --> :core:resources\n    :feature:jxl-tools --> :core:settings\n    :feature:jxl-tools --> :core:di\n    :feature:jxl-tools --> :core:crash\n    :feature:libraries-info --> :core:data\n    :feature:libraries-info --> :core:ui\n    :feature:libraries-info --> :core:domain\n    :feature:libraries-info --> :core:resources\n    :feature:libraries-info --> :core:settings\n    :feature:libraries-info --> :core:di\n    :feature:libraries-info --> :core:crash\n    :feature:gif-tools --> :core:data\n    :feature:gif-tools --> :core:ui\n    :feature:gif-tools --> :core:domain\n    :feature:gif-tools --> :core:resources\n    :feature:gif-tools --> :core:settings\n    :feature:gif-tools --> :core:di\n    :feature:gif-tools --> :core:crash\n    :feature:library-details --> :core:data\n    :feature:library-details --> :core:ui\n    :feature:library-details --> :core:domain\n    :feature:library-details --> :core:resources\n    :feature:library-details --> :core:settings\n    :feature:library-details --> :core:di\n    :feature:library-details --> :core:crash\n    :feature:pdf-tools --> :core:data\n    :feature:pdf-tools --> :core:ui\n    :feature:pdf-tools --> :core:domain\n    :feature:pdf-tools --> :core:resources\n    :feature:pdf-tools --> :core:settings\n    :feature:pdf-tools --> :core:di\n    :feature:pdf-tools --> :core:crash\n    :feature:watermarking --> :core:data\n    :feature:watermarking --> :core:ui\n    :feature:watermarking --> :core:domain\n    :feature:watermarking --> :core:resources\n    :feature:watermarking --> :core:settings\n    :feature:watermarking --> :core:di\n    :feature:watermarking --> :core:crash\n    :feature:watermarking --> :feature:compare\n    :app --> :core:data\n    :app --> :core:ui\n    :app --> :core:domain\n    :app --> :core:resources\n    :app --> :core:settings\n    :app --> :core:di\n    :app --> :core:crash\n    :app --> :core:utils\n    :app --> :feature:root\n    :app --> :feature:media-picker\n    :app --> :feature:quick-tiles\n    :feature:resize-convert --> :core:data\n    :feature:resize-convert --> :core:ui\n    :feature:resize-convert --> :core:domain\n    :feature:resize-convert --> :core:resources\n    :feature:resize-convert --> :core:settings\n    :feature:resize-convert --> :core:di\n    :feature:resize-convert --> :core:crash\n    :feature:resize-convert --> :feature:compare\n    :feature:easter-egg --> :core:data\n    :feature:easter-egg --> :core:ui\n    :feature:easter-egg --> :core:domain\n    :feature:easter-egg --> :core:resources\n    :feature:easter-egg --> :core:settings\n    :feature:easter-egg --> :core:di\n    :feature:easter-egg --> :core:crash\n    :feature:webp-tools --> :core:data\n    :feature:webp-tools --> :core:ui\n    :feature:webp-tools --> :core:domain\n    :feature:webp-tools --> :core:resources\n    :feature:webp-tools --> :core:settings\n    :feature:webp-tools --> :core:di\n    :feature:webp-tools --> :core:crash\n    :feature:markup-layers --> :core:data\n    :feature:markup-layers --> :core:ui\n    :feature:markup-layers --> :core:domain\n    :feature:markup-layers --> :core:resources\n    :feature:markup-layers --> :core:settings\n    :feature:markup-layers --> :core:di\n    :feature:markup-layers --> :core:crash\n    :feature:media-picker --> :core:data\n    :feature:media-picker --> :core:ui\n    :feature:media-picker --> :core:domain\n    :feature:media-picker --> :core:resources\n    :feature:media-picker --> :core:settings\n    :feature:media-picker --> :core:di\n    :feature:media-picker --> :core:crash\n    :feature:image-stitch --> :core:data\n    :feature:image-stitch --> :core:ui\n    :feature:image-stitch --> :core:domain\n    :feature:image-stitch --> :core:resources\n    :feature:image-stitch --> :core:settings\n    :feature:image-stitch --> :core:di\n    :feature:image-stitch --> :core:crash\n    :feature:image-stitch --> :core:filters\n    :core:ui --> :core:resources\n    :core:ui --> :core:domain\n    :core:ui --> :core:utils\n    :core:ui --> :core:di\n    :core:ui --> :core:settings\n    :feature:noise-generation --> :core:data\n    :feature:noise-generation --> :core:ui\n    :feature:noise-generation --> :core:domain\n    :feature:noise-generation --> :core:resources\n    :feature:noise-generation --> :core:settings\n    :feature:noise-generation --> :core:di\n    :feature:noise-generation --> :core:crash\n    :feature:wallpapers-export --> :core:data\n    :feature:wallpapers-export --> :core:ui\n    :feature:wallpapers-export --> :core:domain\n    :feature:wallpapers-export --> :core:resources\n    :feature:wallpapers-export --> :core:settings\n    :feature:wallpapers-export --> :core:di\n    :feature:wallpapers-export --> :core:crash\n    :feature:document-scanner --> :core:data\n    :feature:document-scanner --> :core:ui\n    :feature:document-scanner --> :core:domain\n    :feature:document-scanner --> :core:resources\n    :feature:document-scanner --> :core:settings\n    :feature:document-scanner --> :core:di\n    :feature:document-scanner --> :core:crash\n    :feature:document-scanner --> :feature:pdf-tools\n    :feature:gradient-maker --> :core:data\n    :feature:gradient-maker --> :core:ui\n    :feature:gradient-maker --> :core:domain\n    :feature:gradient-maker --> :core:resources\n    :feature:gradient-maker --> :core:settings\n    :feature:gradient-maker --> :core:di\n    :feature:gradient-maker --> :core:crash\n    :feature:gradient-maker --> :feature:compare\n    :feature:zip --> :core:data\n    :feature:zip --> :core:ui\n    :feature:zip --> :core:domain\n    :feature:zip --> :core:resources\n    :feature:zip --> :core:settings\n    :feature:zip --> :core:di\n    :feature:zip --> :core:crash\n    :core:utils --> :core:domain\n    :core:utils --> :core:resources\n    :core:utils --> :core:settings\n    :feature:cipher --> :core:data\n    :feature:cipher --> :core:ui\n    :feature:cipher --> :core:domain\n    :feature:cipher --> :core:resources\n    :feature:cipher --> :core:settings\n    :feature:cipher --> :core:di\n    :feature:cipher --> :core:crash\n    :feature:draw --> :core:data\n    :feature:draw --> :core:ui\n    :feature:draw --> :core:domain\n    :feature:draw --> :core:resources\n    :feature:draw --> :core:settings\n    :feature:draw --> :core:di\n    :feature:draw --> :core:crash\n    :feature:draw --> :core:filters\n    :feature:draw --> :feature:pick-color\n    :feature:ai-tools --> :core:data\n    :feature:ai-tools --> :core:ui\n    :feature:ai-tools --> :core:domain\n    :feature:ai-tools --> :core:resources\n    :feature:ai-tools --> :core:settings\n    :feature:ai-tools --> :core:di\n    :feature:ai-tools --> :core:crash\n    :feature:audio-cover-extractor --> :core:data\n    :feature:audio-cover-extractor --> :core:ui\n    :feature:audio-cover-extractor --> :core:domain\n    :feature:audio-cover-extractor --> :core:resources\n    :feature:audio-cover-extractor --> :core:settings\n    :feature:audio-cover-extractor --> :core:di\n    :feature:audio-cover-extractor --> :core:crash\n    :core:crash --> :core:ui\n    :core:crash --> :core:settings\n    :feature:delete-exif --> :core:data\n    :feature:delete-exif --> :core:ui\n    :feature:delete-exif --> :core:domain\n    :feature:delete-exif --> :core:resources\n    :feature:delete-exif --> :core:settings\n    :feature:delete-exif --> :core:di\n    :feature:delete-exif --> :core:crash\n    :feature:collage-maker --> :core:data\n    :feature:collage-maker --> :core:ui\n    :feature:collage-maker --> :core:domain\n    :feature:collage-maker --> :core:resources\n    :feature:collage-maker --> :core:settings\n    :feature:collage-maker --> :core:di\n    :feature:collage-maker --> :core:crash\n    :feature:compare --> :core:data\n    :feature:compare --> :core:ui\n    :feature:compare --> :core:domain\n    :feature:compare --> :core:resources\n    :feature:compare --> :core:settings\n    :feature:compare --> :core:di\n    :feature:compare --> :core:crash\n    :feature:mesh-gradients --> :core:data\n    :feature:mesh-gradients --> :core:ui\n    :feature:mesh-gradients --> :core:domain\n    :feature:mesh-gradients --> :core:resources\n    :feature:mesh-gradients --> :core:settings\n    :feature:mesh-gradients --> :core:di\n    :feature:mesh-gradients --> :core:crash\n    :core:settings --> :core:domain\n    :core:settings --> :core:resources\n    :core:settings --> :core:di\n    :feature:scan-qr-code --> :core:data\n    :feature:scan-qr-code --> :core:ui\n    :feature:scan-qr-code --> :core:domain\n    :feature:scan-qr-code --> :core:resources\n    :feature:scan-qr-code --> :core:settings\n    :feature:scan-qr-code --> :core:di\n    :feature:scan-qr-code --> :core:crash\n    :feature:scan-qr-code --> :core:filters\n    :feature:svg-maker --> :core:data\n    :feature:svg-maker --> :core:ui\n    :feature:svg-maker --> :core:domain\n    :feature:svg-maker --> :core:resources\n    :feature:svg-maker --> :core:settings\n    :feature:svg-maker --> :core:di\n    :feature:svg-maker --> :core:crash\n    :feature:weight-resize --> :core:data\n    :feature:weight-resize --> :core:ui\n    :feature:weight-resize --> :core:domain\n    :feature:weight-resize --> :core:resources\n    :feature:weight-resize --> :core:settings\n    :feature:weight-resize --> :core:di\n    :feature:weight-resize --> :core:crash\n    :feature:image-splitting --> :core:data\n    :feature:image-splitting --> :core:ui\n    :feature:image-splitting --> :core:domain\n    :feature:image-splitting --> :core:resources\n    :feature:image-splitting --> :core:settings\n    :feature:image-splitting --> :core:di\n    :feature:image-splitting --> :core:crash\n    :benchmark --> :app\n    :feature:checksum-tools --> :core:data\n    :feature:checksum-tools --> :core:ui\n    :feature:checksum-tools --> :core:domain\n    :feature:checksum-tools --> :core:resources\n    :feature:checksum-tools --> :core:settings\n    :feature:checksum-tools --> :core:di\n    :feature:checksum-tools --> :core:crash\n    :feature:base64-tools --> :core:data\n    :feature:base64-tools --> :core:ui\n    :feature:base64-tools --> :core:domain\n    :feature:base64-tools --> :core:resources\n    :feature:base64-tools --> :core:settings\n    :feature:base64-tools --> :core:di\n    :feature:base64-tools --> :core:crash\n    :feature:palette-tools --> :core:data\n    :feature:palette-tools --> :core:ui\n    :feature:palette-tools --> :core:domain\n    :feature:palette-tools --> :core:resources\n    :feature:palette-tools --> :core:settings\n    :feature:palette-tools --> :core:di\n    :feature:palette-tools --> :core:crash\n    :feature:palette-tools --> :feature:pick-color\n    :feature:settings --> :core:data\n    :feature:settings --> :core:ui\n    :feature:settings --> :core:domain\n    :feature:settings --> :core:resources\n    :feature:settings --> :core:settings\n    :feature:settings --> :core:di\n    :feature:settings --> :core:crash\n    :core:data --> :core:utils\n    :core:data --> :core:domain\n    :core:data --> :core:resources\n    :core:data --> :core:filters\n    :core:data --> :core:settings\n    :core:data --> :core:di\n    :feature:pick-color --> :core:data\n    :feature:pick-color --> :core:ui\n    :feature:pick-color --> :core:domain\n    :feature:pick-color --> :core:resources\n    :feature:pick-color --> :core:settings\n    :feature:pick-color --> :core:di\n    :feature:pick-color --> :core:crash\n    :feature:load-net-image --> :core:data\n    :feature:load-net-image --> :core:ui\n    :feature:load-net-image --> :core:domain\n    :feature:load-net-image --> :core:resources\n    :feature:load-net-image --> :core:settings\n    :feature:load-net-image --> :core:di\n    :feature:load-net-image --> :core:crash\n    :feature:quick-tiles --> :core:data\n    :feature:quick-tiles --> :core:ui\n    :feature:quick-tiles --> :core:domain\n    :feature:quick-tiles --> :core:resources\n    :feature:quick-tiles --> :core:settings\n    :feature:quick-tiles --> :core:di\n    :feature:quick-tiles --> :core:crash\n    :feature:quick-tiles --> :feature:erase-background\n    :feature:recognize-text --> :core:data\n    :feature:recognize-text --> :core:ui\n    :feature:recognize-text --> :core:domain\n    :feature:recognize-text --> :core:resources\n    :feature:recognize-text --> :core:settings\n    :feature:recognize-text --> :core:di\n    :feature:recognize-text --> :core:crash\n    :feature:recognize-text --> :core:filters\n    :feature:recognize-text --> :feature:single-edit\n    :core:domain --> :core:resources\n    :feature:single-edit --> :core:data\n    :feature:single-edit --> :core:ui\n    :feature:single-edit --> :core:domain\n    :feature:single-edit --> :core:resources\n    :feature:single-edit --> :core:settings\n    :feature:single-edit --> :core:di\n    :feature:single-edit --> :core:crash\n    :feature:single-edit --> :feature:crop\n    :feature:single-edit --> :feature:erase-background\n    :feature:single-edit --> :feature:draw\n    :feature:single-edit --> :feature:filters\n    :feature:single-edit --> :feature:pick-color\n    :feature:single-edit --> :feature:compare\n    :feature:image-cutting --> :core:data\n    :feature:image-cutting --> :core:ui\n    :feature:image-cutting --> :core:domain\n    :feature:image-cutting --> :core:resources\n    :feature:image-cutting --> :core:settings\n    :feature:image-cutting --> :core:di\n    :feature:image-cutting --> :core:crash\n    :feature:image-cutting --> :feature:compare\n    :feature:crop --> :core:data\n    :feature:crop --> :core:ui\n    :feature:crop --> :core:domain\n    :feature:crop --> :core:resources\n    :feature:crop --> :core:settings\n    :feature:crop --> :core:di\n    :feature:crop --> :core:crash\n    :feature:color-tools --> :core:data\n    :feature:color-tools --> :core:ui\n    :feature:color-tools --> :core:domain\n    :feature:color-tools --> :core:resources\n    :feature:color-tools --> :core:settings\n    :feature:color-tools --> :core:di\n    :feature:color-tools --> :core:crash\n    :feature:format-conversion --> :core:data\n    :feature:format-conversion --> :core:ui\n    :feature:format-conversion --> :core:domain\n    :feature:format-conversion --> :core:resources\n    :feature:format-conversion --> :core:settings\n    :feature:format-conversion --> :core:di\n    :feature:format-conversion --> :core:crash\n    :feature:format-conversion --> :feature:compare\n    :feature:ascii-art --> :core:data\n    :feature:ascii-art --> :core:ui\n    :feature:ascii-art --> :core:domain\n    :feature:ascii-art --> :core:resources\n    :feature:ascii-art --> :core:settings\n    :feature:ascii-art --> :core:di\n    :feature:ascii-art --> :core:crash\n    :feature:ascii-art --> :feature:filters\n    :core:filters --> :core:domain\n    :core:filters --> :core:ui\n    :core:filters --> :core:resources\n    :core:filters --> :core:settings\n    :core:filters --> :core:utils\n    :feature:apng-tools --> :core:data\n    :feature:apng-tools --> :core:ui\n    :feature:apng-tools --> :core:domain\n    :feature:apng-tools --> :core:resources\n    :feature:apng-tools --> :core:settings\n    :feature:apng-tools --> :core:di\n    :feature:apng-tools --> :core:crash\n    :feature:image-preview --> :core:data\n    :feature:image-preview --> :core:ui\n    :feature:image-preview --> :core:domain\n    :feature:image-preview --> :core:resources\n    :feature:image-preview --> :core:settings\n    :feature:image-preview --> :core:di\n    :feature:image-preview --> :core:crash\n    :feature:filters --> :core:filters\n    :feature:filters --> :core:data\n    :feature:filters --> :core:ui\n    :feature:filters --> :core:domain\n    :feature:filters --> :core:resources\n    :feature:filters --> :core:settings\n    :feature:filters --> :core:di\n    :feature:filters --> :core:crash\n    :feature:filters --> :core:ksp\n    :feature:filters --> :feature:draw\n    :feature:filters --> :feature:pick-color\n    :feature:filters --> :feature:compare\n    :feature:image-stacking --> :core:data\n    :feature:image-stacking --> :core:ui\n    :feature:image-stacking --> :core:domain\n    :feature:image-stacking --> :core:resources\n    :feature:image-stacking --> :core:settings\n    :feature:image-stacking --> :core:di\n    :feature:image-stacking --> :core:crash\n    :feature:main --> :core:data\n    :feature:main --> :core:ui\n    :feature:main --> :core:domain\n    :feature:main --> :core:resources\n    :feature:main --> :core:settings\n    :feature:main --> :core:di\n    :feature:main --> :core:crash\n    :feature:main --> :feature:settings\n```"
  },
  {
    "path": "ARCHITECTURE_2",
    "content": "%%{\n    init: {\n      \"theme\": \"base\",\n      \"maxEdges\": 1000,\n      \"themeVariables\": {\n        \"mainBkg\": \"#121418\",\n        \"primaryColor\": \"#1b3a1b\",\n        \"primaryTextColor\": \"#e0e3de\",\n        \"primaryBorderColor\": \"#76c893\",\n        \"nodeBorder\": \"#76c893\",\n        \"lineColor\": \"#76c893\",\n        \"secondaryColor\": \"#1f2721\",\n        \"tertiaryColor\": \"#232c26\",\n        \"clusterBkg\": \"#182018\",\n        \"clusterBorder\": \"#4caf50\",\n        \"nodeTextColor\": \"#e0e3de\",\n        \"edgeLabelBackground\": \"#111316\",\n        \"edgeLabelColor\": \"#cfe9de\",\n        \"fontSize\": \"28px\",\n        \"fontFamily\": \"JetBrains Mono, Inter, system-ui\"\n      }\n    }\n}%%\n\ngraph LR\n    subgraph :core\n        :core:data(\"data\")\n        :core:ui(\"ui\")\n        :core:domain(\"domain\")\n        :core:resources(\"resources\")\n        :core:settings(\"settings\")\n        :core:di(\"di\")\n        :core:crash(\"crash\")\n        :core:utils(\"utils\")\n        :core:filters(\"filters\")\n        :core:ksp(\"ksp\")\n    end\n    subgraph :feature\n        :feature:root(\"root\")\n        :feature:main(\"main\")\n        :feature:load-net-image(\"load-net-image\")\n        :feature:crop(\"crop\")\n        :feature:limits-resize(\"limits-resize\")\n        :feature:cipher(\"cipher\")\n        :feature:image-preview(\"image-preview\")\n        :feature:weight-resize(\"weight-resize\")\n        :feature:compare(\"compare\")\n        :feature:delete-exif(\"delete-exif\")\n        :feature:palette-tools(\"palette-tools\")\n        :feature:resize-convert(\"resize-convert\")\n        :feature:pdf-tools(\"pdf-tools\")\n        :feature:single-edit(\"single-edit\")\n        :feature:erase-background(\"erase-background\")\n        :feature:draw(\"draw\")\n        :feature:filters(\"filters\")\n        :feature:image-stitch(\"image-stitch\")\n        :feature:pick-color(\"pick-color\")\n        :feature:recognize-text(\"recognize-text\")\n        :feature:gradient-maker(\"gradient-maker\")\n        :feature:watermarking(\"watermarking\")\n        :feature:gif-tools(\"gif-tools\")\n        :feature:apng-tools(\"apng-tools\")\n        :feature:zip(\"zip\")\n        :feature:jxl-tools(\"jxl-tools\")\n        :feature:settings(\"settings\")\n        :feature:easter-egg(\"easter-egg\")\n        :feature:svg-maker(\"svg-maker\")\n        :feature:format-conversion(\"format-conversion\")\n        :feature:document-scanner(\"document-scanner\")\n        :feature:scan-qr-code(\"scan-qr-code\")\n        :feature:image-stacking(\"image-stacking\")\n        :feature:image-splitting(\"image-splitting\")\n        :feature:color-tools(\"color-tools\")\n        :feature:webp-tools(\"webp-tools\")\n        :feature:noise-generation(\"noise-generation\")\n        :feature:collage-maker(\"collage-maker\")\n        :feature:libraries-info(\"libraries-info\")\n        :feature:markup-layers(\"markup-layers\")\n        :feature:base64-tools(\"base64-tools\")\n        :feature:checksum-tools(\"checksum-tools\")\n        :feature:mesh-gradients(\"mesh-gradients\")\n        :feature:edit-exif(\"edit-exif\")\n        :feature:image-cutting(\"image-cutting\")\n        :feature:audio-cover-extractor(\"audio-cover-extractor\")\n        :feature:library-details(\"library-details\")\n        :feature:wallpapers-export(\"wallpapers-export\")\n        :feature:ascii-art(\"ascii-art\")\n        :feature:ai-tools(\"ai-tools\")\n        :feature:color-library(\"color-library\")\n        :feature:media-picker(\"media-picker\")\n        :feature:quick-tiles(\"quick-tiles\")\n    end\n    subgraph :lib\n        :lib:neural-tools(\"neural-tools\")\n        :lib:opencv-tools(\"opencv-tools\")\n        :lib:dynamic-theme(\"dynamic-theme\")\n        :lib:snowfall(\"snowfall\")\n        :lib:documentscanner(\"documentscanner\")\n        :lib:collages(\"collages\")\n        :lib:palette(\"palette\")\n        :lib:curves(\"curves\")\n        :lib:ascii(\"ascii\")\n    end\n    :feature:root --> :core:data\n    :feature:root --> :core:ui\n    :feature:root --> :core:domain\n    :feature:root --> :core:resources\n    :feature:root --> :core:settings\n    :feature:root --> :core:di\n    :feature:root --> :core:crash\n    :feature:root --> :feature:main\n    :feature:root --> :feature:load-net-image\n    :feature:root --> :feature:crop\n    :feature:root --> :feature:limits-resize\n    :feature:root --> :feature:cipher\n    :feature:root --> :feature:image-preview\n    :feature:root --> :feature:weight-resize\n    :feature:root --> :feature:compare\n    :feature:root --> :feature:delete-exif\n    :feature:root --> :feature:palette-tools\n    :feature:root --> :feature:resize-convert\n    :feature:root --> :feature:pdf-tools\n    :feature:root --> :feature:single-edit\n    :feature:root --> :feature:erase-background\n    :feature:root --> :feature:draw\n    :feature:root --> :feature:filters\n    :feature:root --> :feature:image-stitch\n    :feature:root --> :feature:pick-color\n    :feature:root --> :feature:recognize-text\n    :feature:root --> :feature:gradient-maker\n    :feature:root --> :feature:watermarking\n    :feature:root --> :feature:gif-tools\n    :feature:root --> :feature:apng-tools\n    :feature:root --> :feature:zip\n    :feature:root --> :feature:jxl-tools\n    :feature:root --> :feature:settings\n    :feature:root --> :feature:easter-egg\n    :feature:root --> :feature:svg-maker\n    :feature:root --> :feature:format-conversion\n    :feature:root --> :feature:document-scanner\n    :feature:root --> :feature:scan-qr-code\n    :feature:root --> :feature:image-stacking\n    :feature:root --> :feature:image-splitting\n    :feature:root --> :feature:color-tools\n    :feature:root --> :feature:webp-tools\n    :feature:root --> :feature:noise-generation\n    :feature:root --> :feature:collage-maker\n    :feature:root --> :feature:libraries-info\n    :feature:root --> :feature:markup-layers\n    :feature:root --> :feature:base64-tools\n    :feature:root --> :feature:checksum-tools\n    :feature:root --> :feature:mesh-gradients\n    :feature:root --> :feature:edit-exif\n    :feature:root --> :feature:image-cutting\n    :feature:root --> :feature:audio-cover-extractor\n    :feature:root --> :feature:library-details\n    :feature:root --> :feature:wallpapers-export\n    :feature:root --> :feature:ascii-art\n    :feature:root --> :feature:ai-tools\n    :feature:root --> :feature:color-library\n    :feature:erase-background --> :core:data\n    :feature:erase-background --> :core:ui\n    :feature:erase-background --> :core:domain\n    :feature:erase-background --> :core:resources\n    :feature:erase-background --> :core:settings\n    :feature:erase-background --> :core:di\n    :feature:erase-background --> :core:crash\n    :feature:erase-background --> :lib:neural-tools\n    :feature:erase-background --> :feature:draw\n    :feature:edit-exif --> :core:data\n    :feature:edit-exif --> :core:ui\n    :feature:edit-exif --> :core:domain\n    :feature:edit-exif --> :core:resources\n    :feature:edit-exif --> :core:settings\n    :feature:edit-exif --> :core:di\n    :feature:edit-exif --> :core:crash\n    :feature:limits-resize --> :core:data\n    :feature:limits-resize --> :core:ui\n    :feature:limits-resize --> :core:domain\n    :feature:limits-resize --> :core:resources\n    :feature:limits-resize --> :core:settings\n    :feature:limits-resize --> :core:di\n    :feature:limits-resize --> :core:crash\n    :feature:jxl-tools --> :core:data\n    :feature:jxl-tools --> :core:ui\n    :feature:jxl-tools --> :core:domain\n    :feature:jxl-tools --> :core:resources\n    :feature:jxl-tools --> :core:settings\n    :feature:jxl-tools --> :core:di\n    :feature:jxl-tools --> :core:crash\n    :feature:libraries-info --> :core:data\n    :feature:libraries-info --> :core:ui\n    :feature:libraries-info --> :core:domain\n    :feature:libraries-info --> :core:resources\n    :feature:libraries-info --> :core:settings\n    :feature:libraries-info --> :core:di\n    :feature:libraries-info --> :core:crash\n    :feature:gif-tools --> :core:data\n    :feature:gif-tools --> :core:ui\n    :feature:gif-tools --> :core:domain\n    :feature:gif-tools --> :core:resources\n    :feature:gif-tools --> :core:settings\n    :feature:gif-tools --> :core:di\n    :feature:gif-tools --> :core:crash\n    :feature:library-details --> :core:data\n    :feature:library-details --> :core:ui\n    :feature:library-details --> :core:domain\n    :feature:library-details --> :core:resources\n    :feature:library-details --> :core:settings\n    :feature:library-details --> :core:di\n    :feature:library-details --> :core:crash\n    :feature:pdf-tools --> :core:data\n    :feature:pdf-tools --> :core:ui\n    :feature:pdf-tools --> :core:domain\n    :feature:pdf-tools --> :core:resources\n    :feature:pdf-tools --> :core:settings\n    :feature:pdf-tools --> :core:di\n    :feature:pdf-tools --> :core:crash\n    :feature:watermarking --> :core:data\n    :feature:watermarking --> :core:ui\n    :feature:watermarking --> :core:domain\n    :feature:watermarking --> :core:resources\n    :feature:watermarking --> :core:settings\n    :feature:watermarking --> :core:di\n    :feature:watermarking --> :core:crash\n    :feature:watermarking --> :feature:compare\n    :app --> :core:data\n    :app --> :core:ui\n    :app --> :core:domain\n    :app --> :core:resources\n    :app --> :core:settings\n    :app --> :core:di\n    :app --> :core:crash\n    :app --> :core:utils\n    :app --> :feature:root\n    :app --> :feature:media-picker\n    :app --> :feature:quick-tiles\n    :app --> :lib:opencv-tools\n    :app --> :lib:neural-tools\n    :feature:resize-convert --> :core:data\n    :feature:resize-convert --> :core:ui\n    :feature:resize-convert --> :core:domain\n    :feature:resize-convert --> :core:resources\n    :feature:resize-convert --> :core:settings\n    :feature:resize-convert --> :core:di\n    :feature:resize-convert --> :core:crash\n    :feature:resize-convert --> :feature:compare\n    :feature:easter-egg --> :core:data\n    :feature:easter-egg --> :core:ui\n    :feature:easter-egg --> :core:domain\n    :feature:easter-egg --> :core:resources\n    :feature:easter-egg --> :core:settings\n    :feature:easter-egg --> :core:di\n    :feature:easter-egg --> :core:crash\n    :feature:webp-tools --> :core:data\n    :feature:webp-tools --> :core:ui\n    :feature:webp-tools --> :core:domain\n    :feature:webp-tools --> :core:resources\n    :feature:webp-tools --> :core:settings\n    :feature:webp-tools --> :core:di\n    :feature:webp-tools --> :core:crash\n    :feature:markup-layers --> :core:data\n    :feature:markup-layers --> :core:ui\n    :feature:markup-layers --> :core:domain\n    :feature:markup-layers --> :core:resources\n    :feature:markup-layers --> :core:settings\n    :feature:markup-layers --> :core:di\n    :feature:markup-layers --> :core:crash\n    :feature:media-picker --> :core:data\n    :feature:media-picker --> :core:ui\n    :feature:media-picker --> :core:domain\n    :feature:media-picker --> :core:resources\n    :feature:media-picker --> :core:settings\n    :feature:media-picker --> :core:di\n    :feature:media-picker --> :core:crash\n    :feature:image-stitch --> :core:data\n    :feature:image-stitch --> :core:ui\n    :feature:image-stitch --> :core:domain\n    :feature:image-stitch --> :core:resources\n    :feature:image-stitch --> :core:settings\n    :feature:image-stitch --> :core:di\n    :feature:image-stitch --> :core:crash\n    :feature:image-stitch --> :core:filters\n    :feature:image-stitch --> :lib:opencv-tools\n    :core:ui --> :core:resources\n    :core:ui --> :core:domain\n    :core:ui --> :core:utils\n    :core:ui --> :lib:dynamic-theme\n    :core:ui --> :lib:snowfall\n    :core:ui --> :core:di\n    :core:ui --> :core:settings\n    :core:ui --> :lib:documentscanner\n    :feature:color-library --> :core:data\n    :feature:color-library --> :core:ui\n    :feature:color-library --> :core:domain\n    :feature:color-library --> :core:resources\n    :feature:color-library --> :core:settings\n    :feature:color-library --> :core:di\n    :feature:color-library --> :core:crash\n    :feature:noise-generation --> :core:data\n    :feature:noise-generation --> :core:ui\n    :feature:noise-generation --> :core:domain\n    :feature:noise-generation --> :core:resources\n    :feature:noise-generation --> :core:settings\n    :feature:noise-generation --> :core:di\n    :feature:noise-generation --> :core:crash\n    :feature:wallpapers-export --> :core:data\n    :feature:wallpapers-export --> :core:ui\n    :feature:wallpapers-export --> :core:domain\n    :feature:wallpapers-export --> :core:resources\n    :feature:wallpapers-export --> :core:settings\n    :feature:wallpapers-export --> :core:di\n    :feature:wallpapers-export --> :core:crash\n    :feature:document-scanner --> :core:data\n    :feature:document-scanner --> :core:ui\n    :feature:document-scanner --> :core:domain\n    :feature:document-scanner --> :core:resources\n    :feature:document-scanner --> :core:settings\n    :feature:document-scanner --> :core:di\n    :feature:document-scanner --> :core:crash\n    :feature:document-scanner --> :feature:pdf-tools\n    :feature:gradient-maker --> :core:data\n    :feature:gradient-maker --> :core:ui\n    :feature:gradient-maker --> :core:domain\n    :feature:gradient-maker --> :core:resources\n    :feature:gradient-maker --> :core:settings\n    :feature:gradient-maker --> :core:di\n    :feature:gradient-maker --> :core:crash\n    :feature:gradient-maker --> :feature:compare\n    :feature:zip --> :core:data\n    :feature:zip --> :core:ui\n    :feature:zip --> :core:domain\n    :feature:zip --> :core:resources\n    :feature:zip --> :core:settings\n    :feature:zip --> :core:di\n    :feature:zip --> :core:crash\n    :core:utils --> :core:domain\n    :core:utils --> :core:resources\n    :core:utils --> :core:settings\n    :feature:cipher --> :core:data\n    :feature:cipher --> :core:ui\n    :feature:cipher --> :core:domain\n    :feature:cipher --> :core:resources\n    :feature:cipher --> :core:settings\n    :feature:cipher --> :core:di\n    :feature:cipher --> :core:crash\n    :feature:draw --> :core:data\n    :feature:draw --> :core:ui\n    :feature:draw --> :core:domain\n    :feature:draw --> :core:resources\n    :feature:draw --> :core:settings\n    :feature:draw --> :core:di\n    :feature:draw --> :core:crash\n    :feature:draw --> :core:filters\n    :feature:draw --> :feature:pick-color\n    :feature:ai-tools --> :core:data\n    :feature:ai-tools --> :core:ui\n    :feature:ai-tools --> :core:domain\n    :feature:ai-tools --> :core:resources\n    :feature:ai-tools --> :core:settings\n    :feature:ai-tools --> :core:di\n    :feature:ai-tools --> :core:crash\n    :feature:ai-tools --> :lib:neural-tools\n    :feature:audio-cover-extractor --> :core:data\n    :feature:audio-cover-extractor --> :core:ui\n    :feature:audio-cover-extractor --> :core:domain\n    :feature:audio-cover-extractor --> :core:resources\n    :feature:audio-cover-extractor --> :core:settings\n    :feature:audio-cover-extractor --> :core:di\n    :feature:audio-cover-extractor --> :core:crash\n    :core:crash --> :core:ui\n    :core:crash --> :core:settings\n    :lib:documentscanner --> :lib:opencv-tools\n    :feature:delete-exif --> :core:data\n    :feature:delete-exif --> :core:ui\n    :feature:delete-exif --> :core:domain\n    :feature:delete-exif --> :core:resources\n    :feature:delete-exif --> :core:settings\n    :feature:delete-exif --> :core:di\n    :feature:delete-exif --> :core:crash\n    :feature:collage-maker --> :core:data\n    :feature:collage-maker --> :core:ui\n    :feature:collage-maker --> :core:domain\n    :feature:collage-maker --> :core:resources\n    :feature:collage-maker --> :core:settings\n    :feature:collage-maker --> :core:di\n    :feature:collage-maker --> :core:crash\n    :feature:collage-maker --> :lib:collages\n    :feature:compare --> :core:data\n    :feature:compare --> :core:ui\n    :feature:compare --> :core:domain\n    :feature:compare --> :core:resources\n    :feature:compare --> :core:settings\n    :feature:compare --> :core:di\n    :feature:compare --> :core:crash\n    :feature:compare --> :lib:opencv-tools\n    :feature:mesh-gradients --> :core:data\n    :feature:mesh-gradients --> :core:ui\n    :feature:mesh-gradients --> :core:domain\n    :feature:mesh-gradients --> :core:resources\n    :feature:mesh-gradients --> :core:settings\n    :feature:mesh-gradients --> :core:di\n    :feature:mesh-gradients --> :core:crash\n    :core:settings --> :lib:dynamic-theme\n    :core:settings --> :core:domain\n    :core:settings --> :core:resources\n    :core:settings --> :core:di\n    :feature:scan-qr-code --> :core:data\n    :feature:scan-qr-code --> :core:ui\n    :feature:scan-qr-code --> :core:domain\n    :feature:scan-qr-code --> :core:resources\n    :feature:scan-qr-code --> :core:settings\n    :feature:scan-qr-code --> :core:di\n    :feature:scan-qr-code --> :core:crash\n    :feature:scan-qr-code --> :core:filters\n    :feature:svg-maker --> :core:data\n    :feature:svg-maker --> :core:ui\n    :feature:svg-maker --> :core:domain\n    :feature:svg-maker --> :core:resources\n    :feature:svg-maker --> :core:settings\n    :feature:svg-maker --> :core:di\n    :feature:svg-maker --> :core:crash\n    :feature:weight-resize --> :core:data\n    :feature:weight-resize --> :core:ui\n    :feature:weight-resize --> :core:domain\n    :feature:weight-resize --> :core:resources\n    :feature:weight-resize --> :core:settings\n    :feature:weight-resize --> :core:di\n    :feature:weight-resize --> :core:crash\n    :feature:image-splitting --> :core:data\n    :feature:image-splitting --> :core:ui\n    :feature:image-splitting --> :core:domain\n    :feature:image-splitting --> :core:resources\n    :feature:image-splitting --> :core:settings\n    :feature:image-splitting --> :core:di\n    :feature:image-splitting --> :core:crash\n    :benchmark --> :app\n    :feature:checksum-tools --> :core:data\n    :feature:checksum-tools --> :core:ui\n    :feature:checksum-tools --> :core:domain\n    :feature:checksum-tools --> :core:resources\n    :feature:checksum-tools --> :core:settings\n    :feature:checksum-tools --> :core:di\n    :feature:checksum-tools --> :core:crash\n    :feature:base64-tools --> :core:data\n    :feature:base64-tools --> :core:ui\n    :feature:base64-tools --> :core:domain\n    :feature:base64-tools --> :core:resources\n    :feature:base64-tools --> :core:settings\n    :feature:base64-tools --> :core:di\n    :feature:base64-tools --> :core:crash\n    :feature:palette-tools --> :core:data\n    :feature:palette-tools --> :core:ui\n    :feature:palette-tools --> :core:domain\n    :feature:palette-tools --> :core:resources\n    :feature:palette-tools --> :core:settings\n    :feature:palette-tools --> :core:di\n    :feature:palette-tools --> :core:crash\n    :feature:palette-tools --> :feature:pick-color\n    :feature:palette-tools --> :lib:palette\n    :feature:settings --> :core:data\n    :feature:settings --> :core:ui\n    :feature:settings --> :core:domain\n    :feature:settings --> :core:resources\n    :feature:settings --> :core:settings\n    :feature:settings --> :core:di\n    :feature:settings --> :core:crash\n    :core:data --> :core:utils\n    :core:data --> :core:domain\n    :core:data --> :core:resources\n    :core:data --> :core:filters\n    :core:data --> :core:settings\n    :core:data --> :core:di\n    :feature:pick-color --> :core:data\n    :feature:pick-color --> :core:ui\n    :feature:pick-color --> :core:domain\n    :feature:pick-color --> :core:resources\n    :feature:pick-color --> :core:settings\n    :feature:pick-color --> :core:di\n    :feature:pick-color --> :core:crash\n    :feature:load-net-image --> :core:data\n    :feature:load-net-image --> :core:ui\n    :feature:load-net-image --> :core:domain\n    :feature:load-net-image --> :core:resources\n    :feature:load-net-image --> :core:settings\n    :feature:load-net-image --> :core:di\n    :feature:load-net-image --> :core:crash\n    :feature:quick-tiles --> :core:data\n    :feature:quick-tiles --> :core:ui\n    :feature:quick-tiles --> :core:domain\n    :feature:quick-tiles --> :core:resources\n    :feature:quick-tiles --> :core:settings\n    :feature:quick-tiles --> :core:di\n    :feature:quick-tiles --> :core:crash\n    :feature:quick-tiles --> :feature:erase-background\n    :feature:recognize-text --> :core:data\n    :feature:recognize-text --> :core:ui\n    :feature:recognize-text --> :core:domain\n    :feature:recognize-text --> :core:resources\n    :feature:recognize-text --> :core:settings\n    :feature:recognize-text --> :core:di\n    :feature:recognize-text --> :core:crash\n    :feature:recognize-text --> :core:filters\n    :feature:recognize-text --> :feature:single-edit\n    :core:domain --> :core:resources\n    :feature:single-edit --> :core:data\n    :feature:single-edit --> :core:ui\n    :feature:single-edit --> :core:domain\n    :feature:single-edit --> :core:resources\n    :feature:single-edit --> :core:settings\n    :feature:single-edit --> :core:di\n    :feature:single-edit --> :core:crash\n    :feature:single-edit --> :feature:crop\n    :feature:single-edit --> :feature:erase-background\n    :feature:single-edit --> :feature:draw\n    :feature:single-edit --> :feature:filters\n    :feature:single-edit --> :feature:pick-color\n    :feature:single-edit --> :feature:compare\n    :feature:single-edit --> :lib:curves\n    :feature:image-cutting --> :core:data\n    :feature:image-cutting --> :core:ui\n    :feature:image-cutting --> :core:domain\n    :feature:image-cutting --> :core:resources\n    :feature:image-cutting --> :core:settings\n    :feature:image-cutting --> :core:di\n    :feature:image-cutting --> :core:crash\n    :feature:image-cutting --> :feature:compare\n    :feature:crop --> :core:data\n    :feature:crop --> :core:ui\n    :feature:crop --> :core:domain\n    :feature:crop --> :core:resources\n    :feature:crop --> :core:settings\n    :feature:crop --> :core:di\n    :feature:crop --> :core:crash\n    :feature:crop --> :lib:opencv-tools\n    :feature:color-tools --> :core:data\n    :feature:color-tools --> :core:ui\n    :feature:color-tools --> :core:domain\n    :feature:color-tools --> :core:resources\n    :feature:color-tools --> :core:settings\n    :feature:color-tools --> :core:di\n    :feature:color-tools --> :core:crash\n    :feature:format-conversion --> :core:data\n    :feature:format-conversion --> :core:ui\n    :feature:format-conversion --> :core:domain\n    :feature:format-conversion --> :core:resources\n    :feature:format-conversion --> :core:settings\n    :feature:format-conversion --> :core:di\n    :feature:format-conversion --> :core:crash\n    :feature:format-conversion --> :feature:compare\n    :feature:ascii-art --> :core:data\n    :feature:ascii-art --> :core:ui\n    :feature:ascii-art --> :core:domain\n    :feature:ascii-art --> :core:resources\n    :feature:ascii-art --> :core:settings\n    :feature:ascii-art --> :core:di\n    :feature:ascii-art --> :core:crash\n    :feature:ascii-art --> :feature:filters\n    :feature:ascii-art --> :lib:ascii\n    :core:filters --> :core:domain\n    :core:filters --> :core:ui\n    :core:filters --> :core:resources\n    :core:filters --> :core:settings\n    :core:filters --> :core:utils\n    :core:filters --> :lib:curves\n    :core:filters --> :lib:ascii\n    :core:filters --> :lib:neural-tools\n    :feature:apng-tools --> :core:data\n    :feature:apng-tools --> :core:ui\n    :feature:apng-tools --> :core:domain\n    :feature:apng-tools --> :core:resources\n    :feature:apng-tools --> :core:settings\n    :feature:apng-tools --> :core:di\n    :feature:apng-tools --> :core:crash\n    :feature:image-preview --> :core:data\n    :feature:image-preview --> :core:ui\n    :feature:image-preview --> :core:domain\n    :feature:image-preview --> :core:resources\n    :feature:image-preview --> :core:settings\n    :feature:image-preview --> :core:di\n    :feature:image-preview --> :core:crash\n    :feature:filters --> :core:filters\n    :feature:filters --> :core:data\n    :feature:filters --> :core:ui\n    :feature:filters --> :core:domain\n    :feature:filters --> :core:resources\n    :feature:filters --> :core:settings\n    :feature:filters --> :core:di\n    :feature:filters --> :core:crash\n    :feature:filters --> :core:ksp\n    :feature:filters --> :feature:draw\n    :feature:filters --> :feature:pick-color\n    :feature:filters --> :feature:compare\n    :feature:filters --> :lib:opencv-tools\n    :feature:filters --> :lib:neural-tools\n    :feature:filters --> :lib:curves\n    :feature:filters --> :lib:ascii\n    :feature:image-stacking --> :core:data\n    :feature:image-stacking --> :core:ui\n    :feature:image-stacking --> :core:domain\n    :feature:image-stacking --> :core:resources\n    :feature:image-stacking --> :core:settings\n    :feature:image-stacking --> :core:di\n    :feature:image-stacking --> :core:crash\n    :feature:main --> :core:data\n    :feature:main --> :core:ui\n    :feature:main --> :core:domain\n    :feature:main --> :core:resources\n    :feature:main --> :core:settings\n    :feature:main --> :core:di\n    :feature:main --> :core:crash\n    :feature:main --> :feature:settings"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing Guidelines\n\nThis documentation contains set of guidelines to help you during the contribution process.\n\n# Submitting Contributions👨🏻‍💻\nBelow you will find the process and workflow used to review and merge your changes.\n## 🌟 : Choose an issue/ Create an issue\n\n- Look for the existing issue or create your own issue.\n- Comment on the respective issue you would like to work before creating a Pull Request.\n- Wait for the issue to be assigned to you after which you can start working on it.\n\n## 🌟 : Fork the repository\n\n- Fork this repository \"ImageToolbox\" by clicking on the \"Fork\" button. This will create a local copy of this respository on your GitHub profile.\n\n## 🌟 : Clone the forked repository\n\n- Once the repository is forked you need to clone it to your local machine.\n- Click on the \"Code\" button in the repository page and copy the link provided in the dropdown menu.\n\n\n```bash\ngit clone https://github.com/<your-username>/<ImageToolbox>  \n```\n\n- Keep a reference to the original project in `upstream` remote.\n\n```bash  \ncd <repo-name>  \ngit remote add upstream https://github.com/<upstream-owner>/<ImageToolbox>\ngit remote -v # To the check the remotes for this repository \n```  \n\n- If the project is forked already, update the copy before working.\n\n```bash\ngit remote update\ngit checkout <branch-name>\ngit rebase upstream/<branch-name>\n``` \n\n## 🌟 : Create a new branch\n\n- Always create a new branch and name it accordingly so as to identify the issue you are addressing.\n\n```bash\n# It will create a new branch with name branch_name and switch to that branch \ngit checkout -b branch_name\n```\n## 🌟 : Work on the issue assigned\n\n- Work on the issue(s) assigned to you, make the necessary changes in the files/folders needed.\n- After making the changes add them to the branch you've created.\n\n```bash  \n# To add all new files to branch Branch_Name  \ngit add .  \n\n# To add only a few files to Branch_Name\ngit add <file name>\n```\n## 🌟 : Commit the changes\n\n- Add your commits.\n- Along with the commit give a descriptive message that reflects your changes.\n\n```bash\ngit commit -m \"message\"  \n```\n- Note : A Pull Request should always have only one commit. \n\n## 🌟 : Push the changes\n\n- Push the committed changes in your branch to your remote repository.\n\n```bash  \ngit push origin branch_name\n```\n## 🌟 : Create a Pull Request\n\n- Go to your repository in the browser and click on compare and pull request.\n- Add a title and description to your pull request that best describes your contribution.\n- After which the pull request will be reviewed and the maintainer will provide the reviews required for the changes.\n\nIf no changes are needed, this means that your Pull Request has been reviewed and will be merged to the original code base by the maintainer.\n\n\nHappy Hacking!"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n</br>\n<img src=\"./fastlane/metadata/android/en-US/images/logo/logo.png\" width=\"200\" />\n\n</div>\n\n<div align=\"center\">\n\n# Image Toolbox\n\n</div>\n\n</br>\n\n<p align=\"center\">\n  <img alt=\"API\" src=\"https://img.shields.io/badge/Api%2023+-50f270?logo=android&logoColor=black&style=for-the-badge\"/></a>\n  <img alt=\"Kotlin\" src=\"https://img.shields.io/badge/Kotlin-a503fc?logo=kotlin&logoColor=white&style=for-the-badge\"/></a>\n  <img alt=\"Jetpack Compose\" src=\"https://img.shields.io/static/v1?style=for-the-badge&message=Jetpack+Compose&color=4285F4&logo=Jetpack+Compose&logoColor=FFFFFF&label=\"/></a> \n    <img alt=\"material\" src=\"https://custom-icon-badges.demolab.com/badge/material%20you-lightblue?style=for-the-badge&logoColor=333&logo=material-you\"/></a>\n  </br>\n  </br>\n  \n <img src=\"https://img.shields.io/badge/327.8K-aeff4d?style=for-the-badge&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BCiAgICA8cGF0aCBkPSJNMTIuODksM0wxNC44NSwzLjRMMTEuMTEsMjFMOS4xNSwyMC42TDEyLjg5LDNNMTkuNTksMTJMMTYsOC40MVY1LjU4TDIyLjQyLDEyTDE2LDE4LjQxVjE1LjU4TDE5LjU5LDEyTTEuNTgsMTJMOCw1LjU4VjguNDFMNC40MSwxMkw4LDE1LjU4VjE4LjQxTDEuNTgsMTJaIgogICAgICAgIGZpbGw9IndoaXRlIiAvPgo8L3N2Zz4%3D&label=Lines%20of%20code&labelColor=4b731a\"/>\n\n<img src=\"https://img.shields.io/github/commits-since/t8rin/ImageResizer/v1.0?color=palegreen&label=Commits&style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHRpdGxlPnNvdXJjZS1jb21taXQ8L3RpdGxlPjxwYXRoIGQ9Ik0xNywxMkMxNywxNC40MiAxNS4yOCwxNi40NCAxMywxNi45VjIxSDExVjE2LjlDOC43MiwxNi40NCA3LDE0LjQyIDcsMTJDNyw5LjU4IDguNzIsNy41NiAxMSw3LjFWM0gxM1Y3LjFDMTUuMjgsNy41NiAxNyw5LjU4IDE3LDEyTTEyLDlBMywzIDAgMCwwIDksMTJBMywzIDAgMCwwIDEyLDE1QTMsMyAwIDAsMCAxNSwxMkEzLDMgMCAwLDAgMTIsOVoiIGZpbGw9IndoaXRlIiAvPjwvc3ZnPg==&labelColor=07ab4e\">\n \n<img src=\"https://img.shields.io/github/languages/code-size/t8rin/imageresizer?style=for-the-badge&color=8ce2ff&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHRpdGxlPndlaWdodDwvdGl0bGU+PHBhdGggZD0iTTEyLDNBNCw0IDAgMCwxIDE2LDdDMTYsNy43MyAxNS44MSw4LjQxIDE1LjQ2LDlIMThDMTguOTUsOSAxOS43NSw5LjY3IDE5Ljk1LDEwLjU2QzIxLjk2LDE4LjU3IDIyLDE4Ljc4IDIyLDE5QTIsMiAwIDAsMSAyMCwyMUg0QTIsMiAwIDAsMSAyLDE5QzIsMTguNzggMi4wNCwxOC41NyA0LjA1LDEwLjU2QzQuMjUsOS42NyA1LjA1LDkgNiw5SDguNTRDOC4xOSw4LjQxIDgsNy43MyA4LDdBNCw0IDAgMCwxIDEyLDNNMTIsNUEyLDIgMCAwLDAgMTAsN0EyLDIgMCAwLDAgMTIsOUEyLDIgMCAwLDAgMTQsN0EyLDIgMCAwLDAgMTIsNVoiIGZpbGw9IndoaXRlIiAvPjwvc3ZnPg==&labelColor=0782ab\">\n \n</br>\n</br>\n\n<a href=\"https://hits.sh/github.com/t8rin/ImageResizer/\">\n\n  <img src=\"https://hits.sh/github.com/t8rin/ImageResizer.svg?style=for-the-badge&label=Page%20Views&extraCount=7500&color=ff3f6f&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNsYXNzPSJzdmctaWNvbiIgc3R5bGU9IndpZHRoOiAxZW07IGhlaWdodDogMWVtO3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7ZmlsbDojZmZmZmZmO292ZXJmbG93OiBoaWRkZW47IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiPjxwYXRoIGQ9Ik01MTIgMzg0YTEyOCAxMjggMCAwIDAtMTI4IDEyOCAxMjggMTI4IDAgMCAwIDEyOCAxMjggMTI4IDEyOCAwIDAgMCAxMjgtMTI4IDEyOCAxMjggMCAwIDAtMTI4LTEyOG0wIDM0MS4zMzMzMzNhMjEzLjMzMzMzMyAyMTMuMzMzMzMzIDAgMCAxLTIxMy4zMzMzMzMtMjEzLjMzMzMzMyAyMTMuMzMzMzMzIDIxMy4zMzMzMzMgMCAwIDEgMjEzLjMzMzMzMy0yMTMuMzMzMzMzIDIxMy4zMzMzMzMgMjEzLjMzMzMzMyAwIDAgMSAyMTMuMzMzMzMzIDIxMy4zMzMzMzMgMjEzLjMzMzMzMyAyMTMuMzMzMzMzIDAgMCAxLTIxMy4zMzMzMzMgMjEzLjMzMzMzM20wLTUzMy4zMzMzMzNDMjk4LjY2NjY2NyAxOTIgMTE2LjQ4IDMyNC42OTMzMzMgNDIuNjY2NjY3IDUxMmM3My44MTMzMzMgMTg3LjMwNjY2NyAyNTYgMzIwIDQ2OS4zMzMzMzMgMzIwczM5NS41Mi0xMzIuNjkzMzMzIDQ2OS4zMzMzMzMtMzIwYy03My44MTMzMzMtMTg3LjMwNjY2Ny0yNTYtMzIwLTQ2OS4zMzMzMzMtMzIweiIgZmlsbD0iIi8%2BPC9zdmc%2B&labelColor=870b2a\"/>\n  \n</a>\n  \n<a href=\"https://github.com/t8rin/ImageResizer/releases\">\n  \n  <img src=\"https://img.shields.io/github/downloads/t8rin/ImageResizer/total?color=ff9500&style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHRpdGxlPmRvd25sb2FkPC90aXRsZT48cGF0aCBkPSJNNSwyMEgxOVYxOEg1TTE5LDlIMTVWM0g5VjlINUwxMiwxNkwxOSw5WiIgZmlsbD0id2hpdGUiIC8+PC9zdmc+&labelColor=a6660d\"/>\n  \n</a>\n  \n<a href=\"https://github.com/t8rin/ImageResizer/stargazers\">\n  \n  <img src=\"https://img.shields.io/github/stars/t8rin/imageresizer?color=ffff00&style=for-the-badge&labelColor=a1a116&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHRpdGxlPnN0YXI8L3RpdGxlPjxwYXRoIGQ9Ik0xMiwxNy4yN0wxOC4xOCwyMUwxNi41NCwxMy45N0wyMiw5LjI0TDE0LjgxLDguNjJMMTIsMkw5LjE5LDguNjJMMiw5LjI0TDcuNDUsMTMuOTdMNS44MiwyMUwxMiwxNy4yN1oiIGZpbGw9IndoaXRlIiAvPjwvc3ZnPg==\"/>\n  \n</a>\n  \n</br>\n\n<a href=\"https://github.com/t8rin/imageresizer/releases/latest\">\n\n  <img src=\"https://img.shields.io/github/v/release/t8rin/imageresizer?color=a1168e&include_prereleases&logo=github&style=for-the-badge&labelColor=700f63\"/>\n  \n</a>\n\n<a href=\"https://play.google.com/store/apps/details?id=ru.tech.imageresizershrinker\">\n\n  <img src=\"https://img.shields.io/endpoint?color=a1168e&logo=google-play&style=for-the-badge&label=Play%20store&url=https%3A%2F%2Fplay.cuzi.workers.dev%2Fplay%3Fi%3Dru.tech.imageresizershrinker%26l%3DAndroid%26m%3D%24version&labelColor=700f63\"/>\n  \n</a>\n\n<a href=\"https://f-droid.org/packages/ru.tech.imageresizershrinker\">\n\n  <img src=\"https://img.shields.io/f-droid/v/ru.tech.imageresizershrinker?color=a1168e&include_prereleases&logo=FDROID&style=for-the-badge&labelColor=700f63\"/>\n  \n</a>\n\n</br>\n</br>\n\n<img src=\"https://wakatime.com/badge/user/7fa5ec35-3afd-4c14-984e-6ea7daf545c7.svg?style=social\" style=\"height: 28px;\"/>\n\n</br>\n</br>\n\n  <a href=\"https://hellogithub.com/repository/4c5f2fae4eb545ab87cad9ffd19870ca\" target=\"_blank\">\n    <img src=\"https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=4c5f2fae4eb545ab87cad9ffd19870ca&claim_uid=ubtZe5aXVz0n2QA&theme=dark\" alt=\"Featured｜HelloGitHub\" style=\"width: 250px; height: 54px;\" width=\"250\" height=\"54\" />\n  </a>\n  \n\n</p>\n\n<div align=\"center\">\n\n\n# 🗺️ Project Overview\n\nImageToolbox is a versatile image editing tool designed for efficient photo manipulation. It allows\nusers to crop, apply filters, edit EXIF data, erase backgrounds, and even enhance images with AI.\nIdeal for both photographers and developers, the tool offers a simple interface with powerful\ncapabilities.\n\n</div>\n\n<p align=\"middle\">\n    <img src=\"./fastlane/metadata/android/en-US/images/banner/banner1.png\" width=\"99%\" />\n    <img src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/01.png\" width=\"13%\" />\n    <img src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/02.png\" width=\"13%\" />\n    <img src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/03.png\" width=\"13%\" />\n    <img src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/04.png\" width=\"13%\" />\n    <img src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/05.png\" width=\"13%\" />\n    <img src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/06.png\" width=\"13%\" />\n    <img src=\"./fastlane/metadata/android/en-US/images/phoneScreenshots/07.png\" width=\"13%\" />\n</p>\n\n<div align=\"center\">\n\n# 📔 Wiki\nCheck out Image Toolbox [Wiki](https://github.com/T8RIN/ImageToolbox/wiki) for FAQ and useful info\n</br>\n</br>\n\n# ✈️ Telegram Links\n\n</br>\n\n  [![ImageToolbox Chat](https://img.shields.io/endpoint?&style=for-the-badge&colorA=246732&colorB=A2FFB0&logo=telegram&logoColor=A2FFB0&label=ImageToolbox%20Chat&url=https://tg.sumanjay.workers.dev/t8rin_imagetoolbox)](https://t.me/t8rin_imagetoolbox)\n[![CI Telegram](https://img.shields.io/endpoint?&style=for-the-badge&colorA=29626B&colorB=B5DFE8&logo=telegram&logoColor=B5DFE8&url=https://tg.sumanjay.workers.dev/t8rin_imagetoolbox_ci)](https://t.me/t8rin_imagetoolbox_ci)\n\n\n  </br>\n  </br>\n  Join our chat where you can discuss anything you want and also look into the CI channel where I post betas and announcements\n  </br>\n\n# ☕ Buy me a coffee\n\nThis application is completely free, but if you want to support the project development, you can\nsend a donation to the crypto wallets below\n\n| </br> ![Boosty](https://img.shields.io/badge/Boosty-F15F2C?style=for-the-badge&logo=Boosty&logoColor=white) <br/> <br/> [https://boosty.to/t8rin](https://boosty.to/t8rin) <br/> <br/> | </br> ![Bitcoin](https://img.shields.io/badge/Bitcoin-EAB300?style=for-the-badge&logo=Bitcoin%20SV&logoColor=white) <br/> <br/> `18QFWMREkjzQa4yetfYsN5Ua51UubKmJut` <br/> <br/> | </br> ![Tether](https://img.shields.io/badge/USDT%20(TRC20)-168363?style=for-the-badge&logo=tether&logoColor=white) <br/> <br/> `TVdw6fP8dYsYA6HgQiSYNijBqPJ3k5BbYo` <br/> <br/> |\n|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|\n\n# 📲 Download\n\nGo to the [Releases](https://github.com/t8rin/imageresizer/releases/latest) and the download latest\napk\nor click one of the badges below.\n\n</br>\n\n<p align=\"middle\">\n    <a href=\"https://play.google.com/store/apps/details?id=ru.tech.imageresizershrinker\"><img alt=\"Google Play\" src=\"./fastlane/metadata/android/en-US/images/buttons/gplay.svg\" height=\"60\"></a>\n    <a href=\"https://f-droid.org/packages/ru.tech.imageresizershrinker\"><img alt=\"F-Droid\" src=\"./fastlane/metadata/android/en-US/images/buttons/fdroid.svg\" height=\"60\"/></a>\n    <a href=\"https://github.com/t8rin/imageresizer/releases/latest\"><img alt=\"GitHub\" src=\"./fastlane/metadata/android/en-US/images/buttons/github.svg\" height=\"60\"/></a>\n    <a href=\"https://apps.obtainium.imranr.dev/redirect?r=obtainium://app/%7B%22id%22%3A%22ru.tech.imageresizershrinker%22%2C%22url%22%3A%22https%3A%2F%2Fgithub.com%2FT8RIN%2FImageToolbox%22%2C%22author%22%3A%22T8RIN%22%2C%22name%22%3A%22Image%20Toolbox%22%2C%22preferredApkIndex%22%3A1%2C%22additionalSettings%22%3A%22%7B%5C%22includePrereleases%5C%22%3Afalse%2C%5C%22fallbackToOlderReleases%5C%22%3Atrue%2C%5C%22filterReleaseTitlesByRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22filterReleaseNotesByRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22verifyLatestTag%5C%22%3Afalse%2C%5C%22dontSortReleasesList%5C%22%3Afalse%2C%5C%22useLatestAssetDateAsReleaseDate%5C%22%3Afalse%2C%5C%22trackOnly%5C%22%3Afalse%2C%5C%22versionExtractionRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22matchGroupToUse%5C%22%3A%5C%22%5C%22%2C%5C%22versionDetection%5C%22%3Atrue%2C%5C%22releaseDateAsVersion%5C%22%3Afalse%2C%5C%22useVersionCodeAsOSVersion%5C%22%3Afalse%2C%5C%22apkFilterRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22invertAPKFilter%5C%22%3Afalse%2C%5C%22autoApkFilterByArch%5C%22%3Atrue%2C%5C%22appName%5C%22%3A%5C%22Image%20Toolbox%5C%22%2C%5C%22shizukuPretendToBeGooglePlay%5C%22%3Afalse%2C%5C%22exemptFromBackgroundUpdates%5C%22%3Afalse%2C%5C%22skipUpdateNotifications%5C%22%3Afalse%2C%5C%22about%5C%22%3A%5C%22Image%20Toolbox%20is%20an%20powerful%20picture%20editor%2C%20which%20can%20crop%2C%20apply%20filters%2C%20add%20some%20drawing%2C%20erase%20background%2C%20edit%20EXIF%20or%20even%20create%20PDF%20file.%5C%22%2C%5C%22appAuthor%5C%22%3A%5C%22T8RIN%5C%22%7D%22%7D\"><img alt=\"Obtainium\" src=\"./fastlane/metadata/android/en-US/images/buttons/obtainium.svg\" height=\"60\"/></a>\n    <a href=\"https://apps.obtainium.imranr.dev/redirect?r=obtainium://app/%7B%22id%22%3A%22ru.tech.imageresizershrinker%22%2C%22url%22%3A%22https%3A%2F%2Fgithub.com%2FT8RIN%2FImageToolbox%22%2C%22author%22%3A%22T8RIN%22%2C%22name%22%3A%22Image%20Toolbox%22%2C%22preferredApkIndex%22%3A1%2C%22additionalSettings%22%3A%22%7B%5C%22includePrereleases%5C%22%3Atrue%2C%5C%22fallbackToOlderReleases%5C%22%3Atrue%2C%5C%22filterReleaseTitlesByRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22filterReleaseNotesByRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22verifyLatestTag%5C%22%3Afalse%2C%5C%22dontSortReleasesList%5C%22%3Afalse%2C%5C%22useLatestAssetDateAsReleaseDate%5C%22%3Afalse%2C%5C%22trackOnly%5C%22%3Afalse%2C%5C%22versionExtractionRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22matchGroupToUse%5C%22%3A%5C%22%5C%22%2C%5C%22versionDetection%5C%22%3Atrue%2C%5C%22releaseDateAsVersion%5C%22%3Afalse%2C%5C%22useVersionCodeAsOSVersion%5C%22%3Afalse%2C%5C%22apkFilterRegEx%5C%22%3A%5C%22%5C%22%2C%5C%22invertAPKFilter%5C%22%3Afalse%2C%5C%22autoApkFilterByArch%5C%22%3Atrue%2C%5C%22appName%5C%22%3A%5C%22Image%20Toolbox%5C%22%2C%5C%22shizukuPretendToBeGooglePlay%5C%22%3Afalse%2C%5C%22exemptFromBackgroundUpdates%5C%22%3Afalse%2C%5C%22skipUpdateNotifications%5C%22%3Afalse%2C%5C%22about%5C%22%3A%5C%22Image%20Toolbox%20is%20an%20powerful%20picture%20editor%2C%20which%20can%20crop%2C%20apply%20filters%2C%20add%20some%20drawing%2C%20erase%20background%2C%20edit%20EXIF%20or%20even%20create%20PDF%20file.%5C%22%2C%5C%22appAuthor%5C%22%3A%5C%22T8RIN%5C%22%7D%22%7D\"><img alt=\"Obtainium (Pre-release)\" src=\"./fastlane/metadata/android/en-US/images/buttons/obtainium-pre-release.svg\" height=\"60\"/></a>\n\n</p>\n</div>\n\n# 💻 Installation Instructions\n\n1. Clone the repository:\n   ```bash\n   git clone https://github.com/yourusername/ImageToolbox.git\n   ```\n2. Install dependencies using your preferred package manager (e.g., Gradle).\n3. Build the project:\n   bash ./gradlew build\n4. Run the application:\n   bash ./gradlew run\n\n# ⚔️ FOSS vs MARKET\n\n|       **Feature**       |      **FOSS**      |     **Market**     |\n|:-----------------------:|:------------------:|:------------------:|\n|       QR Scanner        |       Zxing        |       MlKit        |\n| Auto Background Remover |        ONNX        |       MlKit        |\n|    Document Scanner     |       OpenCV       |       MlKit        |\n|        Analytics        |        :x:         | :white_check_mark: |\n|       Crashlytics       |        :x:         | :white_check_mark: |\n|    Other Google deps    |        :x:         | :white_check_mark: |\n|   All Other Features    | :white_check_mark: | :white_check_mark: |\n\n# ✨ Features\n\n- Batch processing\n- Applying filter chains (More than 310 various filters)\n\n  <details>\n  <summary>Available filters</summary>\n  <br>\n\n    - [x] Saturation\n    - [x] Contrast\n    - [x] Brightness\n    - [x] Exposure\n    - [x] RGB\n    - [x] Hue\n    - [x] White Balance\n    - [x] Monochrome\n    - [x] Black and White\n    - [x] False Color\n    - [x] Sharpen\n    - [x] Gamma\n    - [x] Highlights and Shadows\n    - [x] Haze\n    - [x] Sepia Tone\n    - [x] Color Inversion\n    - [x] Solarize\n    - [x] Vibrance\n    - [x] Luminance Threshold\n    - [x] Pixellate\n    - [x] Halftone\n    - [x] Crosshatch\n    - [x] Sobel Edge Detection\n    - [x] Sketch Filter\n    - [x] Toon Filter\n    - [x] SmoothToon Filter\n    - [x] CGA Colorspace Filter\n    - [x] Posterize\n    - [x] Convolution 3x3\n    - [x] Emboss Filter\n    - [x] Laplacian\n    - [x] Kuwahara Filter\n    - [x] Vignette\n    - [x] Gaussian Blur\n    - [x] Box Blur\n    - [x] Stack Blur\n    - [x] Fast Blur\n    - [x] Bilaterial Blur\n    - [x] Zoom Blur\n    - [x] Median Blur\n    - [x] Pixelation\n    - [x] Enhanced Pixelation\n    - [x] Stroke Pixelation\n    - [x] Circle Pixelation\n    - [x] Enhanced Circle Pixelation\n    - [x] Diamond Pixelation\n    - [x] Enhanced Diamond Pixelation\n    - [x] Swirl Distortion\n    - [x] Bulge Distortion\n    - [x] Sphere Refraction\n    - [x] Glass Sphere Refraction\n    - [x] Dilation\n    - [x] Non Maximum Suppression\n    - [x] Opacity\n    - [x] Weak Pixel Inclusion Filter\n    - [x] Color Matrix 4x4\n    - [x] Lookup\n    - [x] Color Replacement\n    - [x] Color Removance\n    - [x] Bayer Two Dithering\n    - [x] Bayer Three Dithering\n    - [x] Bayer Four Dithering\n    - [x] Bayer Eight Dithering\n    - [x] Floyd Steinberg Dithering\n    - [x] Jarvis Judice Ninke Dithering\n    - [x] Sierra Dithering\n    - [x] Two Row Sierra Dithering\n    - [x] Sierra Lite Dithering\n    - [x] Atkinson Dithering\n    - [x] Stucki Dithering\n    - [x] Burkes Dithering\n    - [x] False Floyd Steinberg Dithering\n    - [x] Left To Right Dithering\n    - [x] Random Dithering\n    - [x] Simple Threshold Dithering\n    - [x] Quantizier\n    - [x] Glitch Effect\n    - [x] Enhanced Glitch Effect\n    - [x] Anaglyph\n    - [x] Noise\n    - [x] Tent Blur\n    - [x] Side Fade\n    - [x] Erode\n    - [x] Anisotropic Diffusion\n    - [x] Horizontal Wind Stagger\n    - [x] Fast Bilaterial Blur\n    - [x] Poisson Blur\n    - [x] Logarithmic Tone Mapping\n    - [x] Aces Filmic Tone Mapping\n    - [x] Crystallize\n    - [x] Fractal Glass\n    - [x] Marble\n    - [x] Oil\n    - [x] Water Effect\n    - [x] Hable Filmic Tone Mapping\n    - [x] Aces Hill Tone Mapping\n    - [x] Hejl Burgess Tone Mapping\n    - [x] Perlin Distortion\n    - [x] Grayscale\n    - [x] Dehaze\n    - [x] Color Matrix 3x3\n    - [x] Achromatomaly\n    - [x] Achromatopsia\n    - [x] Browni\n    - [x] CodaChrome\n    - [x] Cool\n    - [x] Deutaromaly\n    - [x] Deutaronotopia\n    - [x] Night Vision\n    - [x] Polaroid\n    - [x] Protanopia\n    - [x] Protonomaly\n    - [x] Tritanopia\n    - [x] Tritonomaly\n    - [x] Vintage\n    - [x] Warm\n    - [x] Grain\n    - [x] Unsharp\n    - [x] Pastel\n    - [x] Orange Haze\n    - [x] Pink Dream\n    - [x] Golden Hour\n    - [x] Hot Summer\n    - [x] Purple Mist\n    - [x] Sunrise\n    - [x] Colorful Swirl\n    - [x] Soft Spring Light\n    - [x] Autumn Tones\n    - [x] Lavender Dream\n    - [x] Cyberpunk\n    - [x] Lemonade Light\n    - [x] Spectral Fire\n    - [x] Night Magic\n    - [x] Fantasy Landscape\n    - [x] Color Explosion\n    - [x] Electric Gradient\n    - [x] Caramel Darkness\n    - [x] Futuristic Gradient\n    - [x] Green Sun\n    - [x] Rainbow World\n    - [x] Deep Purple\n    - [x] Space Portal\n    - [x] Red Swirl\n    - [x] Digital Code\n    - [x] Bokeh\n    - [x] Neon\n    - [x] Old Tv\n    - [x] Shuffle Blur\n    - [x] Mobius\n    - [x] Uchimura\n    - [x] Aldridge\n    - [x] Drago\n    - [x] Color Anomaly\n    - [x] Quantizier\n    - [x] Ring Blur\n    - [x] Cross Blur\n    - [x] Circle Blur\n    - [x] Star Blur\n    - [x] Motion Blur\n    - [x] Fast Gaussian Blur 2D\n    - [x] Fast Gaussian Blur 3D\n    - [x] Fast Gaussian Blur 4D\n    - [x] Equalize Histogram\n    - [x] Equalize Histogram HSV\n    - [x] Equalize Histogram Pixelation\n    - [x] Equalize Histogram Adaptive\n    - [x] Equalize Histogram Adaptive LUV\n    - [x] Equalize Histogram Adaptive LAB\n    - [x] Equalize Histogram Adaptive HSV\n    - [x] Equalize Histogram Adaptive HSL\n    - [x] Clahe\n    - [x] Clahe LUV\n    - [x] Clahe LAB\n    - [x] Clahe HSL\n    - [x] Clahe HSV\n    - [x] Crop To Content\n    - [x] Linear Box Blur\n    - [x] Linear Tent Blur\n    - [x] Linear Gaussian Box Blur\n    - [x] Linear Stack Blur\n    - [x] Gaussian Box Blur\n    - [x] Linear Fast Gaussian Next\n    - [x] LinearFast Gaussian\n    - [x] Linear Gaussian\n    - [x] Low Poly\n    - [x] Sand Painting\n    - [x] Palette Transfer\n    - [x] Enhanced Oil\n    - [x] Simple Old TV\n    - [x] HDR\n    - [x] Simple Sketch\n    - [x] Gotham\n    - [x] Color Poster\n    - [x] Tri Tone\n    - [x] Clahe Oklch\n    - [x] Clahe Jzazbz\n    - [x] Clahe Oklab\n    - [x] Yililoma Dithering\n    - [x] Clustered 2x2 Dithering\n    - [x] Clustered 4x4 Dithering\n    - [x] Clustered8x8 Dithering\n    - [x] Polka Dot\n    - [x] LUT 512\\*512\n    - [x] Amatorka\n    - [x] Miss Etikate\n    - [x] Soft Elegance\n    - [x] Soft Elegance Variant\n    - [x] Bleach Bypass\n    - [x] Candlelight\n    - [x] Drop Blues\n    - [x] Edgy Amber\n    - [x] Fall Colors\n    - [x] Film Stock 50\n    - [x] Foggy Night\n    - [x] Kodak\n    - [x] Palette Transfer Variant\n    - [x] 3D LUT (.cube / .CUBE)\n    - [x] Pop Art\n    - [x] Celluloid\n    - [x] Coffee\n    - [x] Golden Forest\n    - [x] Greenish\n    - [x] Retro Yellow\n    - [x] Auto Crop\n    - [x] Opening\n    - [x] Closing\n    - [x] Morphological Gradient\n    - [x] Top Hat\n    - [x] Black Hat\n    - [x] Enhanced Zoom Blur\n    - [x] Simple Sobel\n    - [x] Simple Laplacian\n    - [x] Auto Red Eyes remover\n    - [x] Tone Curves \n    - [x] Mirror\n    - [x] Kaleidoscope  \n    - [x] Channel Mix  \n    - [x] Color Halftone  \n    - [x] Contour  \n    - [x] Voronoi Crystallize  \n    - [x] Despeckle  \n    - [x] Diffuse  \n    - [x] DoG  \n    - [x] Equalize  \n    - [x] Glow  \n    - [x] Offset  \n    - [x] Pinch  \n    - [x] Pointillize  \n    - [x] Polar Coordinates  \n    - [x] Reduce Noise  \n    - [x] Simple Solarize  \n    - [x] Weave  \n    - [x] Twirl  \n    - [x] Rubber Stamp  \n    - [x] Smear  \n    - [x] Sphere Lens Distortion  \n    - [x] Arc  \n    - [x] Sparkle\n    - [x] ASCII\n    - [x] Moire\n    - [x] Autumn\n    - [x] Bone\n    - [x] Jet\n    - [x] Winter\n    - [x] Rainbow\n    - [x] Ocean\n    - [x] Summer\n    - [x] Spring\n    - [x] Cool Variant \n    - [x] Hsv\n    - [x] Pink\n    - [x] Hot\n    - [x] Parula\n    - [x] Magma\n    - [x] Inferno\n    - [x] Plasma\n    - [x] Viridis\n    - [x] Cividis\n    - [x] Twilight\n    - [x] Twilight Shifted\n    - [x] Deskew\n    - [x] Auto Perspective\n    - [x] Crop Or Perspective\n    - [x] Turbo\n    - [x] Deep Green \n    - [x] Lens Correction\n    - [x] Seam Carving\n    - [x] Error Level Analysis\n    - [x] Luminance Gradient\n    - [x] Average Distance\n    - [x] Copy Move Detection\n    - [x] Simple Weave Pixelization\n    - [x] Staggered Pixelization\n    - [x] Cross Pixelization\n    - [x] Micro Macro Pixelization\n    - [x] Orbital Pixelization\n    - [x] Vortex Pixelization\n    - [x] Pulse Grid Pixelization\n    - [x] Nucleus Pixelization\n    - [x] Radial Weave Pixelization\n    - [x] Border Frame\n    - [x] Glitch Variant\n    - [x] VHS\n    - [x] Block Glitch\n    - [x] Crt Curvature\n    - [x] Pixel Melt\n    - [x] Bloom\n\n\n  </details>\n\n- Custom Filters Creation by Template filters\n    - You can create filter from any filter chain\n    - Share created filters by QR code\n    - Scan filters from the app to get them on your device\n- Files encryption and decryption with 100+ different algorithms available\n- Adding Stickers and Text (Markup Layers Mode)\n- Extract Text From Images (OCR)\n    - 120+ languages\n    - 3 Type of data: Fast, Standard, Best\n    - Segmentation Mode Selection\n    - Engine Mode Selection\n    - Custom Tesseract options entering\n    - Multiple languages at the same time\n    - Reading from batch of images to file\n    - Placing in EXIF metadata of batch images\n    - Creating searchable PDF with recognized text behind images\n- EXIF metadata editing/deleting\n- Loading images from internet\n- Image Stitching\n- Image Stacking\n- Image Splitting\n- Background Removal\n    - By drawing\n  - Automatically (MlKit, U2NetP, U2Net, RMBG, InSPyReNet, BiRefNet, ISNet)\n- Watermarking\n    - Repeating Text\n    - Image\n    - Stamp\n    - Timestamp\n    - Digital (Steganography)\n- Drawing on Image/Background\n    - Pen\n    - Flood Fil\n    - Spray\n    - Neon\n    - Highlighter\n    - Warp (Move, Grow, Shrink, Swirl, Mix)\n    - Privacy Blur\n    - Pixelation Paint\n    - Text\n    - Image Brush\n    - Filter Brush\n    - Spot Healing (with ability to download AI model for generative inpainting)\n    - Pointing Arrow\n    - Line\n    - Double Pointing Arrow\n    - Line Pointing Arrow\n    - Double Line Pointing Arrow\n    - Outlined Rect\n    - Outlined Oval\n    - Outlined Triangle\n    - Outlined Polygon\n    - Outlined Star\n    - Rect\n    - Oval\n    - Triangle\n    - Polygon\n    - Star\n    - Lasso\n    - Line Style\n        - Dashed\n        - Dot Dashed\n        - Zigzag\n        - Stamped\n- Image Resizing\n    - Width changing\n    - Height changing\n    - Adaptive resize\n    - Resize retaining aspect ratio\n    - Resize by given limits\n    - Center Crop with\n        - Background color changing\n        - Background blur drawing\n    - Different Scaling Algorithms\n\n      <details>\n      <summary>Available methods</summary>\n      <br>\n\n      - Bilinear\n      - Nearest Neighbour\n      - Cubic\n      - Mitchell-Netravalli\n      - Catmull-Rom\n      - Hermite\n      - B-Spline\n      - Hann\n      - Bicubic\n      - Hamming\n      - Hanning\n      - Blackman\n      - Welch\n      - Quadric\n      - Gaussian\n      - Sphinx\n      - Bartlett\n      - Robidoux\n      - Robidoux Sharp\n      - Spline 16\n      - Spline 36\n      - Spline 64\n      - Kaiser\n      - Bartlett-Hann\n      - Box\n      - Bohman\n      - Lanczos 2\n      - Lanczos 3\n      - Lanczos 4\n      - Lanczos 2 Jinc\n      - Lanczos 3 Jinc\n      - Lanczos 4 Jinc\n      - Ewa Hanning\n      - Ewa Robidoux\n      - Ewa Blackman\n      - Ewa Quadric\n      - Ewa Robidoux Sharp\n      - Ewa Lanczos 3 Jinc\n      - Ginseng\n      - Ginseng EWA\n      - Lanczos Sharp EWA\n      - Lanczos 4 Sharpest EWA\n      - Lanczos Soft EWA\n      - Haasn Soft\n      - Lagrange 2\n      - Lagrange 3\n      - Lanczos 6\n      - Lanczos 6 Jinc\n\n      </details>\n\n    - Different Scale Color Spaces\n        - Linear\n        - sRGB\n        - LAB\n        - LUV\n        - Sigmoidal\n        - XYZ\n        - F32 Gamma 2.2\n        - F32 Gamma 2.8\n        - F32 Rec.709\n        - F32 sRGB\n        - LCH\n        - Oklab sRGB\n        - Oklab Rec.709\n        - Oklab Gamma 2.2\n        - Oklab Gamma 2.8\n        - Jzazbz sRGB\n        - Jzazbz Rec.709\n        - Jzazbz Gamma 2.2\n        - Jzazbz Gamma 2.8\n- GIF conversion\n    - GIF to images\n    - Images to GIF\n    - GIF to WEBP\n- WEBP conversion\n    - WEBP to images\n    - Images to WEBP\n- APNG conversion\n    - APNG to images\n    - Images to APNG\n- JXL transcoding\n    - JXL to JPEG\n    - JPEG to JXL\n- Animated JXL conversion\n    - Images to JXL\n    - JXL to Images\n    - APNG to JXL\n    - GIF to JXL\n- PDF tools\n    - PDF to images\n    - Images to PDF\n    - PDF previewing\n    - Merge\n    - Split\n    - Rotate\n    - Rearrange\n    - Page Numbering\n    - Watermark\n    - Signature\n    - Compress\n    - Grayscale\n    - Repair\n    - Protect\n    - Unlock\n    - Metadata\n    - Remove Pages\n    - Crop\n    - Flatten\n    - Extract Images\n    - Zip PDF\n    - Print PDF\n    - PDF to Text (OCR)\n- Document Scanning\n- AI tools (95+ ready to use models available)\n    - Upscale\n    - Remove BG\n    - DeJPEG\n    - DeNoise\n    - Colorize\n    - Artifacts\n    - Enhance\n    - Anime\n    - Scans\n- Barcodes\n    - Scanning\n    - Creating & Parsing common types\n      - Plain\n      - Url\n      - WiFi\n      - Email\n      - Geolocation\n      - Phone\n      - SMS\n      - Contact (vCard)\n      - Calendar event\n    - Sharing as images\n    - 13 formats available\n      - QR CODE\n      - AZTEC\n      - CODABAR\n      - CODE 39\n      - CODE 93\n      - CODE 128\n      - DATA MATRIX\n      - EAN 8\n      - EAN 13\n      - ITF\n      - PDF 417\n      - UPC A\n      - UPC E\n- Collage Creation\n    - From 1 to 20 images\n    - More than 310 various collage layouts\n- Image Shrinking\n    - Quality compressing\n    - Preset shrinking\n    - Reducing size by given weight (in KB)\n- Cropping\n    - Regular crop\n    - Free rotation crop\n    - Free corners crop (can be used as Perspective Correction)\n    - Crop by aspect ratio\n    - Crop with shape mask\n        \n        <details>\n          <summary>List of shapes</summary>\n          <br/>\n          \n        - Rounded Corners\n        - Cut Corners\n        - Oval\n        - Squircle\n        - Octagon\n        - Rounded Pentagon\n        - Clover\n        - Material Star\n        - Kotlin Logo\n        - Small Material Star\n        - Heart\n        - Shuriken\n        - Explosion\n        - Bookmark\n        - Pill\n        - Burger\n        - Shield\n        - Droplet\n        - Arrow\n        - Egg\n        - Map\n        - Enhanced Heart\n        - Star\n        - Image Mask\n        - <details>\n          <summary>Additional Shapes</summary>\n          </br>\n        \n          ![image](./fastlane/metadata/android/en-US/images/banner/banner_shapes.png)\n\n          </details>\n        \n        </details>\n\n\n- Image Cutting (can be used as batch crop)         \n- Tracing raster images to SVG\n- Format Conversion\n    - HEIF\n    - HEIC\n    - AVIF\n    - WEBP\n    - JPEG\n    - JPG\n    - PNG Lossless\n    - PNG Lossy\n    - OxiPNG\n    - MozJpeg\n    - Jpegli\n    - JXL\n    - JP2\n    - J2K\n    - TIFF\n    - TIF\n    - QOI\n    - ICO\n    - SVG, DNG, PSD, GIF to static raster images\n    - Telegram sticker PNG format\n- Files to Zip\n- Comparing images\n    - Slide\n    - Toggle Tap\n    - Transparency\n    - Side By Side\n    - Pixel By Pixel (7 Methods)\n        - SSIM\n        - AE\n        - MAE\n        - NCC\n        - PSNR\n        - RMSE\n- Color Utils\n    - Palette generation\n        - Material You Scheme\n        - Simple Colors\n    - Import/Export palette across 41 format\n      - ACB\n      - ACO\n      - ACT  \n      - Android Xml  \n      - ASE\n      - Basic Xml  \n      - Corel Painter  \n      - Corel Draw  \n      - Scribus Xml  \n      - Corel Palette  \n      - CSV\n      - DCP\n      - Gimp\n      - Hex Rgba  \n      - Image  \n      - Json  \n      - Open Office  \n      - Paint Net  \n      - Paint Shop Pro  \n      - Rgba  \n      - Rgb  \n      - Riff  \n      - Sketch  \n      - SKP\n      - SVG  \n      - Swift  \n      - Kotlin  \n      - Corel Draw V3  \n      - CLF\n      - Swatches  \n      - Autodesk Color Book  \n      - Simple Palette  \n      - Swatchbooker  \n      - Afpalette  \n      - Xara  \n      - Koffice\n      - KPL\n      - HPL\n      - Skencil  \n      - Vga 24Bit  \n      - Vga 18Bit  \n    - Picking color from image\n    - Gradient creation (Mesh gradients too)\n    - Overlaying image with gradient\n    - Mixing\n    - Conversion\n    - Harmonies\n    - Shading\n    - Tone Curves applying\n- Color Library with more than 33k different colors\n- Histograms\n    - RGB\n    - Brightness\n    - Camera Like RGB\n- Image source selection\n- Additional Features\n    - Base64 Decode/Encode\n    - Rotating\n    - Flipping\n    - Perlin Noise Generation\n    - Previewing SVG, DNG, PSD, DJVU and almost all types of images\n    - Saving to any specific folder\n    - Long press on save to choose one time output folder\n    - Randomizing output filename\n    - Using image cheksum as filename\n    - Checksum Tools with ability to calculate and compare hashes\n    - 64 different hashing algorithms\n    - Audio files Album Cover export\n    - Embedded media picker\n    - Wallpapers Export\n    - Ascii Art\n\n**And More!**\n\n#\n\n<img src=\"./fastlane/metadata/android/en-US/images/banner/banner2.png\" width=\"99%\" />\n\n# 🌟 UI tweaks\n\n- Selecting Emoji for top app bar\n- Ability to use Pixel like switch instead of Material You\n- Secure Mode for app\n- Maximum brightness for selected screens\n- In app language changing\n- Enabling or Disabling confetti\n- Custom app color scheme\n    - Different palette styles\n    - Predefined schemes\n    - Color inversion\n    - Contrast adjusting\n- Controlling borders thickness\n- Enabling and disabling each existing shadow\n- Haptics controls\n- Light/Dark mode\n- AMOLED mode\n- Monet implementation (Dynamic colors) even for Android versions less than 12\n  by [Dynamic Theme](https://github.com/T8RIN/DynamicTheme)\n- Image based color scheme\n- Icons Background shape selection\n    - Rounded Corners\n    - Cut Corners\n    - Oval\n    - Squircle\n    - Octagon\n    - Rounded Pentagon\n    - Clover\n    - Material Star\n    - Small Material Star\n    - Heart\n    - Enhanced Heart\n- Custom fonts\n\n  <details>\n  <summary>Preinstalled fonts</summary>\n  <br>\n\n    - Montserrat\n    - Comfortaa\n    - Caveat\n    - Handjet\n    - Jura\n    - Podkova\n    - Tektur\n    - YsabeauSC\n    - DejaVu\n    - BadScript\n    - RuslanDisplay\n    - Catterdale\n    - FRM32\n    - Tokeely Brookings\n    - Nunito\n    - Nothing\n    - WOPR Tweaked\n    - Alegreya Sans\n    - Minecraft Gnu\n    - Granite Fixed\n    - Nokia Pixel\n    - Ztivalia\n    - Axotrel\n    - Lcd Octagon\n    - Lcd Moving\n    - Unisource\n\n  </details>\n\n- Ability to import any font (OTF/TTF) to further use\n- In app font scale changing\n- Changing between options list and grouped view\n- Confetti Type selection\n    - Default\n    - Festive\n    - Explode\n    - Rain\n    - Side\n    - Corners\n    - ImageToolbox\n- Switch Type selection:\n    - Material You\n    - Compose\n    - Pixel\n    - Fluent\n    - Cupertino\n  - Liquid Glass\n    - HyperOS\n- Slider Type Selection:\n    - Fancy\n    - Material You\n    - Material\n    - HyperOS\n- Shapes Type Selection with size adjustment:\n    - Rounded\n    - Cut\n    - Squircle\n    - Smooth\n- Main screen layout customization\n\n(Yes, the app supports dynamic coloring based on wallpapers for every android version)\n\n# 📚 Tech stack & Open-source libraries\n\n- Minimum SDK level 23\n\n- [Kotlin](https://kotlinlang.org/) based\n\n- [Image Toolbox Libs](https://github.com/T8RIN/ImageToolboxLibs) - set of essential libraries for\n  Image Toolbox.\n\n- [Dynamic Theme](https://github.com/T8RIN/DynamicTheme) - library, which allows you to easily\n  implement custom color theming.\n\n- [Modal Sheet](https://github.com/T8RIN/ModalSheet) - modal bottom sheet that follows M3\n  guidelines.\n\n- [Coroutines](https://github.com/Kotlin/kotlinx.coroutines) for asynchronous work.\n\n- [Flow](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/)\n  to emit values from data layer reactively.\n\n- [Accompanist](https://github.com/google/accompanist) to expand jetpack compose opportunities.\n\n- [Decompose](https://github.com/arkivanov/Decompose) - KMP lifecycle-aware business logic\n  components (aka BLoCs) with routing (navigation) and pluggable UI\n\n- [Hilt](https://dagger.dev/hilt/) for dependency injection.\n\n- [Coil](https://github.com/coil-kt/coil) for loading images.\n\n- [Konfetti](https://github.com/DanielMartinus/Konfetti) to establish beautiful particle system.\n\n- Jetpack\n\n    - [Compose](https://developer.android.com/jetpack/compose) - Modern Declarative UI style\n      framework based on composable functions.\n\n    - [Material You Kit](https://developer.android.com/jetpack/androidx/releases/compose-material3) -\n      Material 3 powerful UI components.\n\n    - [Data Store](https://developer.android.com/jetpack/androidx/releases/datastore) - Store data\n      asynchronously, consistently, and transactionally.\n\n    - [Lifecycle](https://developer.android.com/jetpack/androidx/releases/lifecycle) - Observe\n      Android lifecycles and handle UI states upon the lifecycle changes.\n\n    - [Exif Interface](https://developer.android.com/jetpack/androidx/releases/exifinterface) - Read\n      and write image file EXIF tags.\n\n- [GPU Image](https://github.com/cats-oss/android-gpuimage) for creating and applying filters to the\n  images.\n\n- [SmartToolFactory](https://github.com/SmartToolFactory) provides a bunch of helpful libraries.\n\n- [AVIF Coder](https://github.com/awxkee/avif-coder)\n  and [JXL Coder](https://github.com/awxkee/jxl-coder) libraries which provide avif, heic, heif and\n  jxl support.\n\n- [Aire](https://github.com/awxkee/aire) and [Trickle](https://github.com/T8RIN/Trickle) for\n  creating and applying filters to the images on CPU\n  using native cpp code.\n\n\n# 📐 App Architecture\n\nSee Modules Graph at [ARCHITECTURE.md](https://github.com/T8RIN/ImageToolbox/blob/master/ARCHITECTURE.md)\n\n<div align=\"center\">\n\n#\n\n<img src=\"./fastlane/metadata/android/en-US/images/banner/banner3.png\" width=\"99%\" />\n\n# 🌐 Translation\n\nYou can help translate Image Toolbox into your language\non [Hosted Weblate](https://hosted.weblate.org/engage/image-resizer/)\n\n[![Состояние перевода](https://hosted.weblate.org/widgets/image-resizer/-/horizontal-auto.svg)](https://hosted.weblate.org/engage/image-resizer/)\n</br>\n[![Translation status](https://hosted.weblate.org/widgets/image-resizer/-/image-resizer/287x66-black.png)](https://hosted.weblate.org/engage/image-resizer/)\n\n# ❤️ Find this repository useful?\n\nSupport it by joining **[stargazers](https://github.com/t8rin/ImageToolbox/stargazers)** for this\nrepository. :star: <br>\nAnd **[follow](https://github.com/t8rin)** me for my next creations! 🤩\n\n# ⭐ Star History\n\n<a href=\"https://star-history.com/#T8RIN/ImageToolbox&Date\">\n <picture>\n   <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=T8RIN/ImageToolbox&type=Date&theme=dark\" />\n   <source media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=T8RIN/ImageToolbox&type=Date\" />\n   <img alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=T8RIN/ImageToolbox&type=Date\" />\n </picture>\n</a>\n\n![](https://repobeats.axiom.co/api/embed/c62092c6ec0d00e67496223d50e39f48a582c532.svg)\n\n# 📢 Contributors\n\n<a href=\"https://github.com/t8rin/imageresizer/graphs/contributors\">\n  <img src=\"https://contrib.rocks/image?repo=t8rin/Imageresizer\"/>\n</a>\n\n# 🔒 Signing Certificate Hashes\n\nSHA-256: `20d7689de0874f00015ea3e31fa067c15c03457d362d41d5e793db3a864fa534`\n\nSHA-1: `d69eacb30eeae804e8b72d2384c3c616b1906785`\n\nMD5: `db6f6b76c503d31099e4754e676353cf`\n\nFor more info, see [wiki](https://github.com/T8RIN/ImageToolbox/wiki/FAQ#how-can-i-verify-my-download-of-imagetoolbox-is-legitimate)\n\n# ⚖️ License\n\n```xml\nDesigned and developed by 2023 T8RIN\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");you may not use this file except in compliance with the License.You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an \"AS IS\" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.\n```\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build/\n/release/\n/foss/\n/market/\n/jxl/\n/build\n/release\n/foss\n/market\n/jxl"
  },
  {
    "path": "app/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnstableApiUsage\")\n\nplugins {\n    alias(libs.plugins.image.toolbox.application)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid {\n    val supportedAbi = arrayOf(\"armeabi-v7a\", \"arm64-v8a\", \"x86_64\")\n\n    namespace = \"com.t8rin.imagetoolbox\"\n\n    defaultConfig {\n        vectorDrawables.useSupportLibrary = true\n\n        //Maintained for compatibility with old version\n        applicationId = \"ru.tech.imageresizershrinker\"\n\n        versionCode = libs.versions.versionCode.get().toIntOrNull()\n        versionName = System.getenv(\"VERSION_NAME\") ?: libs.versions.versionName.get()\n\n        ndk {\n            abiFilters.clear()\n            //noinspection ChromeOsAbiSupport\n            abiFilters += supportedAbi.toSet()\n        }\n    }\n\n    androidResources {\n        generateLocaleConfig = true\n    }\n\n    flavorDimensions += \"app\"\n\n    productFlavors {\n        create(\"foss\") {\n            dimension = \"app\"\n            versionNameSuffix = \"-foss\"\n            extra.set(\"gmsEnabled\", false)\n        }\n        create(\"market\") {\n            dimension = \"app\"\n            extra.set(\"gmsEnabled\", true)\n        }\n    }\n\n    buildTypes {\n        debug {\n            applicationIdSuffix = \".debug\"\n            resValue(\"string\", \"app_launcher_name\", \"Image Toolbox DEBUG\")\n            resValue(\"string\", \"file_provider\", \"com.t8rin.imagetoolbox.fileprovider.debug\")\n        }\n        release {\n            isMinifyEnabled = true\n            isShrinkResources = true\n            proguardFiles(\n                getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n                \"proguard-rules.pro\"\n            )\n            resValue(\"string\", \"app_launcher_name\", \"Image Toolbox\")\n            resValue(\"string\", \"file_provider\", \"com.t8rin.imagetoolbox.fileprovider\")\n        }\n        create(\"benchmark\") {\n            initWith(buildTypes.getByName(\"release\"))\n            signingConfig = signingConfigs.getByName(\"debug\")\n            matchingFallbacks += listOf(\"release\")\n            isMinifyEnabled = false\n            isShrinkResources = false\n        }\n    }\n\n    splits {\n        abi {\n            // Detect app bundle and conditionally disable split abis\n            // This is needed due to a \"Sequence contains more than one matching element\" error\n            // present since AGP 8.9.0, for more info see:\n            // https://issuetracker.google.com/issues/402800800\n\n            // AppBundle tasks usually contain \"bundle\" in their name\n            //noinspection WrongGradleMethod\n            val isBuildingBundle =\n                gradle.startParameter.taskNames.any { it.lowercase().contains(\"bundle\") }\n\n            // Disable split abis when building appBundle\n            isEnable = !isBuildingBundle\n            reset()\n            //noinspection ChromeOsAbiSupport\n            include(*supportedAbi)\n            isUniversalApk = true\n        }\n    }\n\n    lint {\n        disable += \"Instantiatable\"\n    }\n\n    packaging {\n        jniLibs {\n            keepDebugSymbols.add(\"**/*.so\")\n            pickFirsts.add(\"lib/*/libcoder.so\")\n            pickFirsts.add(\"**/libc++_shared.so\")\n            pickFirsts.add(\"**/libdatstore_shared_counter.so\")\n            useLegacyPackaging = true\n        }\n        resources {\n            excludes += \"META-INF/\"\n            excludes += \"kotlin/\"\n            excludes += \"org/\"\n            excludes += \".properties\"\n            excludes += \".bin\"\n            excludes += \"META-INF/versions/9/OSGI-INF/MANIFEST.MF\"\n        }\n    }\n\n    buildFeatures {\n        resValues = true\n    }\n}\n\nbase {\n    archivesName = \"image-toolbox-${android.defaultConfig.versionName}\"\n}\n\naboutLibraries {\n    export.excludeFields.addAll(\"generated\")\n}\n\ndependencies {\n    implementation(projects.feature.root)\n    implementation(projects.feature.mediaPicker)\n    implementation(projects.feature.quickTiles)\n\n    implementation(projects.lib.opencvTools)\n    implementation(projects.lib.neuralTools)\n    implementation(projects.lib.collages)\n\n    implementation(libs.bouncycastle.pkix)\n    implementation(libs.bouncycastle.provider)\n    implementation(libs.pdfbox)\n\n    \"marketImplementation\"(libs.quickie.bundled)\n    \"fossImplementation\"(libs.quickie.foss)\n}\n\ndependencySubstitution {\n    substitute(\n        dependency = \"com.caverock:androidsvg-aar:1.4\",\n        using = \"com.github.deckerst:androidsvg:cc9d59a88f\"\n    )\n}\n\nafterEvaluate {\n    android.productFlavors.forEach { flavor ->\n        tasks.matching { task ->\n            listOf(\"GoogleServices\", \"Crashlytics\").any {\n                task.name.contains(it)\n            }.and(\n                task.name.contains(\n                    flavor.name.replaceFirstChar(Char::uppercase)\n                )\n            )\n        }.forEach { task ->\n            task.enabled = flavor.extra.get(\"gmsEnabled\") == true\n        }\n    }\n}\n\nfun Project.dependencySubstitution(action: DependencySubstitutions.() -> Unit) {\n    allprojects {\n        configurations.all {\n            resolutionStrategy.dependencySubstitution(action)\n        }\n    }\n}\n\nfun DependencySubstitutions.substitute(\n    dependency: String,\n    using: String\n) {\n    substitute(module(dependency)).using(module(using))\n}"
  },
  {
    "path": "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.kts.\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-keepclassmembers class * implements android.os.Parcelable {\n  public static final android.os.Parcelable$Creator CREATOR;\n}\n\n-keep class * implements com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\n-keepclassmembers class * implements com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter {\n    <init>(...);\n}\n-keep class * implements com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n-keepclassmembers class * implements com.t8rin.imagetoolbox.core.filters.domain.model.Filter {\n    <init>(...);\n}\n-keepclassmembers class com.t8rin.imagetoolbox.core.filters.** {\n    <init>(...);\n}\n-keep class com.t8rin.imagetoolbox.core.filters.**\n-keep class com.t8rin.imagetoolbox.core.filters.*\n\n# Please add these rules to your existing keep rules in order to suppress warnings.\n# This is generated automatically by the Android Gradle plugin.\n-dontwarn org.bouncycastle.jsse.BCSSLParameters\n-dontwarn org.bouncycastle.jsse.BCSSLSocket\n-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider\n-dontwarn org.conscrypt.Conscrypt$Version\n-dontwarn org.conscrypt.Conscrypt\n-dontwarn org.conscrypt.ConscryptHostnameVerifier\n-dontwarn org.openjsse.javax.net.ssl.SSLParameters\n-dontwarn org.openjsse.javax.net.ssl.SSLSocket\n-dontwarn org.openjsse.net.ssl.OpenJSSE\n\n-keep class org.beyka.tiffbitmapfactory.**{ *; }\n\n-keep class org.bouncycastle.jcajce.provider.** { *; }\n-keep class org.bouncycastle.jce.provider.** { *; }\n\n-dontwarn com.google.re2j.Matcher\n-dontwarn com.google.re2j.Pattern\n\n-keepclassmembers class * {\n    public java.lang.String name();\n}\n\n-keep enum * { *; }\n\n-keepclassmembers enum * {\n    public static **[] values();\n    public static ** valueOf(java.lang.String);\n}\n\n-keepclassmembers class * extends java.lang.Enum {\n    public java.lang.String name();\n}\n\n-keep class ai.onnxruntime.** { *; }\n\n-keep class com.google.firebase.crashlytics.** { *; }\n-keep class com.google.firebase.analytics.** { *; }\n-keep class androidx.pdf.** { *; }\n-keepnames class androidx.pdf.** { *; }\n\n# Moshi reflective adapters need generic signatures in release.\n-keepattributes Signature\n-keepattributes *Annotation*\n-keep class kotlin.Metadata { *; }\n\n-keep class com.t8rin.imagetoolbox.feature.markup_layers.data.project.** { *; }\n-keep class  com.t8rin.imagetoolbox.feature.markup_layers.data.project.**\n-keep class  com.t8rin.imagetoolbox.feature.markup_layers.data.project.*"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <uses-sdk tools:overrideLibrary=\"com.github.awxkee.avifcodercoil, com.github.awxkee.avifcoder, com.google.mlkit.vision.segmentation.subject, androidx.pdf,androidx.pdf.viewer.fragment, androidx.pdf.document.service\" />\n\n    <uses-feature\n        android:name=\"android.hardware.camera\"\n        android:required=\"false\" />\n\n    <uses-feature\n        android:name=\"android.hardware.screen.portrait\"\n        android:required=\"false\" />\n\n    <uses-permission\n        android:name=\"com.google.android.gms.permission.AD_ID\"\n        tools:node=\"remove\" />\n    <uses-permission\n        android:name=\"android.permission.ACCESS_ADSERVICES_AD_ID\"\n        tools:node=\"remove\" />\n    <uses-permission\n        android:name=\"android.permission.READ_PHONE_STATE\"\n        tools:node=\"remove\" />\n\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_MEDIA_LOCATION\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION\" />\n    <uses-permission android:name=\"android.permission.PROJECT_MEDIA\" />\n    <uses-permission android:name=\"android.permission.READ_CONTACTS\" />\n\n    <uses-permission\n        android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"\n        tools:ignore=\"ScopedStorage\" />\n\n    <application\n        android:name=\".app.presentation.components.ImageToolboxApplication\"\n        android:allowBackup=\"true\"\n        android:colorMode=\"wideColorGamut\"\n        android:dataExtractionRules=\"@xml/data_extraction_rules\"\n        android:enableOnBackInvokedCallback=\"true\"\n        android:fullBackupContent=\"@xml/backup_rules\"\n        android:hardwareAccelerated=\"true\"\n        android:hasFragileUserData=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_launcher_name\"\n        android:largeHeap=\"true\"\n        android:requestLegacyExternalStorage=\"true\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.ImageToolbox.Launcher\"\n        android:usesCleartextTraffic=\"true\"\n        tools:replace=\"android:allowBackup, android:label\"\n        tools:targetApi=\"tiramisu\">\n\n        <profileable\n            android:shell=\"true\"\n            tools:targetApi=\"29\" />\n\n        <meta-data\n            android:name=\"firebase_crashlytics_collection_enabled\"\n            android:value=\"false\" />\n        <meta-data\n            android:name=\"firebase_analytics_collection_enabled\"\n            android:value=\"false\" />\n\n        <activity\n            android:name=\".app.presentation.AppActivity\"\n            android:exported=\"true\"\n            android:launchMode=\"singleTop\">\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n\n            <intent-filter android:label=\"@string/app_launcher_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n                <action android:name=\"com.android.camera.action.REVIEW\" />\n                <action android:name=\"android.provider.action.REVIEW\" />\n                <action android:name=\"android.provider.action.REVIEW_SECURE\" />\n\n                <data\n                    android:scheme=\"content\"\n                    tools:ignore=\"AppLinkUrlError\" />\n                <data android:scheme=\"file\" />\n                <data android:mimeType=\"image/*\" />\n                <data android:pathSuffix=\".jxl\" />\n                <data android:pathSuffix=\".qoi\" />\n                <data android:pathSuffix=\".itp\" />\n                <data android:mimeType=\"application/vnd.shana.informed.formtemplate\" />\n                <data android:mimeType=\"application/x-imagetoolbox-project\" />\n                <data android:mimeType=\"application/octet-stream\" />\n                <data android:mimeType=\"application/zip\" />\n                <data android:mimeType=\"application/pdf\" />\n                <data android:mimeType=\"*/pdf\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n            </intent-filter>\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.SEND\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data android:mimeType=\"*/*\" />\n            </intent-filter>\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.ACTION_BUG_REPORT\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.SEND_MULTIPLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data android:mimeType=\"*/*\" />\n            </intent-filter>\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.EDIT\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"image/*\"\n                    tools:ignore=\"AppLinkUrlError\" />\n                <data android:mimeType=\"application/vnd.shana.informed.formtemplate\" />\n                <data android:mimeType=\"application/x-imagetoolbox-project\" />\n                <data android:mimeType=\"application/octet-stream\" />\n                <data android:mimeType=\"application/zip\" />\n                <data android:pathSuffix=\".jxl\" />\n                <data android:pathSuffix=\".qoi\" />\n                <data android:pathSuffix=\".itp\" />\n                <data android:mimeType=\"application/pdf\" />\n                <data android:mimeType=\"*/pdf\" />\n            </intent-filter>\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.INSERT_OR_EDIT\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"image/*\"\n                    tools:ignore=\"AppLinkUrlError\" />\n                <data android:mimeType=\"application/vnd.shana.informed.formtemplate\" />\n                <data android:mimeType=\"application/x-imagetoolbox-project\" />\n                <data android:mimeType=\"application/octet-stream\" />\n                <data android:mimeType=\"application/zip\" />\n                <data android:pathSuffix=\".jxl\" />\n                <data android:pathSuffix=\".qoi\" />\n                <data android:pathSuffix=\".itp\" />\n                <data android:mimeType=\"application/pdf\" />\n                <data android:mimeType=\"*/pdf\" />\n            </intent-filter>\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.INSERT\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"image/*\"\n                    tools:ignore=\"AppLinkUrlError\" />\n                <data android:mimeType=\"application/vnd.shana.informed.formtemplate\" />\n                <data android:mimeType=\"application/x-imagetoolbox-project\" />\n                <data android:mimeType=\"application/octet-stream\" />\n                <data android:mimeType=\"application/zip\" />\n                <data android:pathSuffix=\".jxl\" />\n                <data android:pathSuffix=\".qoi\" />\n                <data android:pathSuffix=\".itp\" />\n                <data android:mimeType=\"application/pdf\" />\n                <data android:mimeType=\"*/pdf\" />\n            </intent-filter>\n        </activity>\n\n        <provider\n            android:name=\"androidx.core.content.FileProvider\"\n            android:authorities=\"@string/file_provider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/file_paths\" />\n        </provider>\n\n        <service\n            android:name=\"androidx.appcompat.app.AppLocalesMetadataHolderService\"\n            android:enabled=\"false\"\n            android:exported=\"false\">\n            <meta-data\n                android:name=\"autoStoreLocales\"\n                android:value=\"true\" />\n        </service>\n\n        <!-- Prompt Google Play services to install the backported photo picker module -->\n        <!--suppress AndroidDomInspection -->\n        <service\n            android:name=\"com.google.android.gms.metadata.ModuleDependencies\"\n            android:enabled=\"false\"\n            android:exported=\"false\"\n            tools:ignore=\"MissingClass\">\n            <intent-filter>\n                <action android:name=\"com.google.android.gms.metadata.MODULE_DEPENDENCIES\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"photopicker_activity:0:required\"\n                android:value=\"\" />\n        </service>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/AppActivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation\n\nimport android.content.Intent\nimport androidx.compose.runtime.Composable\nimport com.arkivanov.decompose.retainedComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.ComposeActivity\nimport com.t8rin.imagetoolbox.feature.root.presentation.RootContent\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\nimport dagger.hilt.android.AndroidEntryPoint\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nclass AppActivity : ComposeActivity() {\n\n    @Inject\n    lateinit var rootComponentFactory: RootComponent.Factory\n\n    private val component: RootComponent by lazy {\n        retainedComponent(factory = rootComponentFactory::invoke)\n    }\n\n    override fun handleIntent(intent: Intent) = component.handleDeeplinks(intent)\n\n    @Composable\n    override fun Content() = RootContent(component = component)\n\n}"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/ImageToolboxApplication.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components\n\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.attachLogWriter\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.initCollages\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.initColorNames\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.initNeuralTool\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.initOpenCV\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.initPdfBox\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.initQrScanner\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.injectBaseComponent\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.registerSecurityProviders\nimport com.t8rin.imagetoolbox.app.presentation.components.functions.setupFlags\nimport com.t8rin.imagetoolbox.app.presentation.components.utils.isMain\nimport com.t8rin.imagetoolbox.core.crash.presentation.components.applyGlobalExceptionHandler\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.ui.utils.ComposeApplication\nimport com.t8rin.imagetoolbox.core.utils.initAppContext\nimport dagger.hilt.android.HiltAndroidApp\nimport io.ktor.client.HttpClient\nimport javax.inject.Inject\n\n\n@HiltAndroidApp\nclass ImageToolboxApplication : ComposeApplication() {\n\n    @Inject\n    lateinit var keepAliveService: KeepAliveService\n\n    @Inject\n    lateinit var appScope: AppScope\n\n    @Inject\n    lateinit var httpClient: HttpClient\n\n    private var isSetupCompleted: Boolean = false\n\n    override fun onCreate() {\n        super.onCreate()\n        runSetup()\n    }\n\n    override fun runSetup() {\n        if (isSetupCompleted) return\n\n        if (isMain()) {\n            setupFlags()\n            initAppContext()\n            initOpenCV()\n            initNeuralTool()\n            initColorNames()\n            initQrScanner()\n            attachLogWriter()\n            applyGlobalExceptionHandler()\n            registerSecurityProviders()\n            initPdfBox()\n            injectBaseComponent()\n            initCollages()\n\n            isSetupCompleted = true\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/AttachLogWriter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport android.app.Application\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.DeviceInfo\nimport com.t8rin.logger.Logger\nimport com.t8rin.logger.attachLogWriter\n\n\ninternal fun Application.attachLogWriter() {\n    Logger.attachLogWriter(\n        context = this@attachLogWriter,\n        fileProvider = getString(R.string.file_provider),\n        logsFilename = \"image_toolbox_logs.txt\",\n        startupLog = Logger.Log(\n            tag = \"Device Info\",\n            message = \"--${DeviceInfo.get()}--\",\n            level = Logger.Level.Info\n        ),\n        isSyncCreate = false\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/InitCollages.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport com.t8rin.collages.public.CollageConstants\nimport com.t8rin.imagetoolbox.core.data.image.utils.static\n\nfun initCollages() =\n    CollageConstants.requestMapper { static() }"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/InitColorNames.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport com.t8rin.colors.parser.ColorNameParser\nimport com.t8rin.imagetoolbox.app.presentation.components.ImageToolboxApplication\nimport kotlinx.coroutines.launch\n\ninternal fun ImageToolboxApplication.initColorNames() =\n    appScope.launch { ColorNameParser.init(this@initColorNames) }"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/InitNeuralTool.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport com.t8rin.imagetoolbox.app.presentation.components.ImageToolboxApplication\nimport com.t8rin.imagetoolbox.core.domain.HF_BASE_URL\nimport com.t8rin.neural_tools.NeuralTool\n\ninternal fun ImageToolboxApplication.initNeuralTool() = NeuralTool.init(\n    context = this,\n    httpClient = httpClient,\n    baseUrl = HF_BASE_URL\n)"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/InitOpenCV.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport android.app.Application\nimport com.t8rin.opencv_tools.utils.OpenCV\n\ninternal fun Application.initOpenCV() = OpenCV.init(this)"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/InitPdfBox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport android.app.Application\nimport com.tom_roush.pdfbox.android.PDFBoxResourceLoader\n\ninternal fun Application.initPdfBox() = PDFBoxResourceLoader.init(this)"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/InitQrScanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.applyPadding\nimport com.t8rin.opencv_tools.qr_prepare.QrPrepareHelper\nimport io.github.g00fy2.quickie.extensions.QrProcessor\n\ninternal fun initQrScanner() = QrProcessor.setProcessor(::prepareBitmap)\n\nprivate fun prepareBitmap(bitmap: Bitmap): Bitmap =\n    QrPrepareHelper.prepareQrForDecode(bitmap.applyPadding(100))"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/InjectBaseComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport com.t8rin.imagetoolbox.app.presentation.components.ImageToolboxApplication\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\n\ninternal fun ImageToolboxApplication.injectBaseComponent() = BaseComponent.inject(keepAliveService)"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/RegisterSecurityProviders.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport com.t8rin.imagetoolbox.core.domain.model.CipherType\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.logger.makeLog\nimport org.bouncycastle.asn1.ASN1ObjectIdentifier\nimport org.bouncycastle.jce.provider.BouncyCastleProvider\nimport org.bouncycastle.operator.DefaultAlgorithmNameFinder\nimport java.security.Provider\nimport java.security.Security\n\ninternal fun registerSecurityProviders() {\n    initBouncyCastle()\n\n    HashingType.registerSecurityMessageDigests(\n        Security.getAlgorithms(\"MessageDigest\").filterNotNull()\n    )\n\n    val finder = DefaultAlgorithmNameFinder()\n\n    CipherType.registerSecurityCiphers(\n        Security.getAlgorithms(\"Cipher\").filterNotNull().mapNotNull { cipher ->\n            if (CipherType.BROKEN.any { cipher.contains(it, true) }) return@mapNotNull null\n\n            val oid = cipher.removePrefix(\"OID.\")\n            if (oid.all { it.isDigit() || it.isWhitespace() || it == '.' }) {\n                CipherType.getInstance(\n                    cipher = cipher,\n                    name = finder.getAlgorithmName(\n                        ASN1ObjectIdentifier(oid)\n                    )\n                )\n            } else {\n                CipherType.getInstance(\n                    cipher = cipher\n                )\n            }.also {\n                val extraExclude = it.cipher == \"DES\"\n                        || it.name == \"DES/CBC\"\n                        || it.name == \"THREEFISH-512\"\n                        || it.name == \"THREEFISH-1024\"\n                        || it.name == \"CCM\"\n\n                if (extraExclude) return@mapNotNull null\n            }\n        }\n    )\n}\n\nprivate fun initBouncyCastle() {\n    if (Security.getProvider(WORKAROUND_NAME) != null) return\n\n    try {\n        logProviders(\"OLD\")\n\n        Security.addProvider(BouncyCastleWorkaroundProvider())\n\n        logProviders(\"NEW\")\n    } catch (e: Exception) {\n        e.makeLog()\n        \"Failed to register BouncyCastleWorkaroundProvider\".makeLog()\n    }\n}\n\nprivate fun logProviders(tag: String): Int {\n    val providers = Security.getProviders()\n    providers.forEachIndexed { index, provider ->\n        \"$tag [$index]: ${provider.name} - ${provider.info}\".makeLog(\"Providers\")\n    }\n    return providers.size\n}\n\nprivate class BouncyCastleWorkaroundProvider(\n    bouncyCastleProvider: Provider = BouncyCastleProvider()\n) : Provider(\n    WORKAROUND_NAME,\n    bouncyCastleProvider.version,\n    bouncyCastleProvider.info\n) {\n    init {\n        for ((key, value) in bouncyCastleProvider.entries) {\n            put(key.toString(), value.toString())\n        }\n    }\n}\n\nprivate const val WORKAROUND_NAME = \"BC_WORKAROUND\""
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/functions/SetupFlags.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.functions\n\nimport androidx.compose.foundation.ComposeFoundationFlags.isPausableCompositionInPrefetchEnabled\nimport androidx.compose.material3.ComposeMaterial3Flags.isCheckboxStylingFixEnabled\nimport com.arkivanov.decompose.DecomposeSettings\n\ninternal fun setupFlags() {\n    isCheckboxStylingFixEnabled = true\n    DecomposeSettings.update { it.copy(duplicateConfigurationsEnabled = true) }\n    isPausableCompositionInPrefetchEnabled = true\n}"
  },
  {
    "path": "app/src/main/java/com/t8rin/imagetoolbox/app/presentation/components/utils/GetProcessName.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.app.presentation.components.utils\n\nimport android.annotation.SuppressLint\nimport android.app.ActivityManager\nimport android.app.Application\nimport android.content.Context.ACTIVITY_SERVICE\nimport android.os.Build.VERSION.SDK_INT\nimport com.t8rin.logger.makeLog\n\ninternal fun Application.isMain(): Boolean =\n    getProcessName().makeLog(\"Current Process\") == packageName.makeLog(\"Current packageName\")\n\n\n@SuppressLint(\"PrivateApi\")\ninternal fun Application.getProcessName(): String? {\n    if (SDK_INT >= 28) {\n        return Application.getProcessName()\n    }\n\n    // Try using ActivityThread to determine the current process name.\n    try {\n        val activityThread = Class.forName(\n            \"android.app.ActivityThread\",\n            false,\n            this::class.java.getClassLoader()\n        )\n        val packageName: Any?\n        val currentProcessName = activityThread.getDeclaredMethod(\"currentProcessName\")\n        currentProcessName.isAccessible = true\n        packageName = currentProcessName.invoke(null)\n        if (packageName is String) {\n            return packageName\n        }\n    } catch (exception: Throwable) {\n        exception.makeLog()\n    }\n\n    // Fallback to the most expensive way\n    val pid: Int = android.os.Process.myPid()\n    val am = getSystemService(ACTIVITY_SERVICE) as ActivityManager\n\n    val processes = am.runningAppProcesses\n    if (processes != null && processes.isNotEmpty()) {\n        for (process in processes) {\n            if (process.pid == pid) {\n                return process.processName\n            }\n        }\n    }\n\n    return null\n}"
  },
  {
    "path": "app/src/main/res/resources.properties",
    "content": "#\n# ImageToolbox is an image editor for android\n# Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n# You should have received a copy of the Apache License\n# along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n#\nunqualifiedResLocale=en"
  },
  {
    "path": "app/src/market/debug/google-services.json",
    "content": "{\n  \"project_info\": {\n    \"project_number\": \"698299287298\",\n    \"project_id\": \"imagetoolbox-13e3c\",\n    \"storage_bucket\": \"imagetoolbox-13e3c.appspot.com\"\n  },\n  \"client\": [\n    {\n      \"client_info\": {\n        \"mobilesdk_app_id\": \"1:698299287298:android:11af7edf43198644b6e41b\",\n        \"android_client_info\": {\n          \"package_name\": \"ru.tech.imageresizershrinker.debug\"\n        }\n      },\n      \"oauth_client\": [\n        {\n          \"client_id\": \"698299287298-5ukroo831v2bn1vj8ff0oa7ch5h94mfg.apps.googleusercontent.com\",\n          \"client_type\": 3\n        }\n      ],\n      \"api_key\": [\n        {\n          \"current_key\": \"AIzaSyBH5QgaBw6XAfuxhPVJzq-r9s8ZMFalXzU\"\n        }\n      ],\n      \"services\": {\n        \"appinvite_service\": {\n          \"other_platform_oauth_client\": [\n            {\n              \"client_id\": \"698299287298-5ukroo831v2bn1vj8ff0oa7ch5h94mfg.apps.googleusercontent.com\",\n              \"client_type\": 3\n            }\n          ]\n        }\n      }\n    }\n  ],\n  \"configuration_version\": \"1\"\n}"
  },
  {
    "path": "app/src/market/release/google-services.json",
    "content": "{\n  \"project_info\": {\n    \"project_number\": \"698299287298\",\n    \"project_id\": \"imagetoolbox-13e3c\",\n    \"storage_bucket\": \"imagetoolbox-13e3c.appspot.com\"\n  },\n  \"client\": [\n    {\n      \"client_info\": {\n        \"mobilesdk_app_id\": \"1:698299287298:android:11af7edf43198644b6e41b\",\n        \"android_client_info\": {\n          \"package_name\": \"ru.tech.imageresizershrinker\"\n        }\n      },\n      \"oauth_client\": [\n        {\n          \"client_id\": \"698299287298-5ukroo831v2bn1vj8ff0oa7ch5h94mfg.apps.googleusercontent.com\",\n          \"client_type\": 3\n        }\n      ],\n      \"api_key\": [\n        {\n          \"current_key\": \"AIzaSyBH5QgaBw6XAfuxhPVJzq-r9s8ZMFalXzU\"\n        }\n      ],\n      \"services\": {\n        \"appinvite_service\": {\n          \"other_platform_oauth_client\": [\n            {\n              \"client_id\": \"698299287298-5ukroo831v2bn1vj8ff0oa7ch5h94mfg.apps.googleusercontent.com\",\n              \"client_type\": 3\n            }\n          ]\n        }\n      }\n    }\n  ],\n  \"configuration_version\": \"1\"\n}"
  },
  {
    "path": "benchmark/.gitignore",
    "content": "/build"
  },
  {
    "path": "benchmark/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnstableApiUsage\")\n\nimport org.jetbrains.kotlin.gradle.dsl.JvmTarget\n\n\nplugins {\n    id(\"com.android.test\")\n    id(\"androidx.baselineprofile\")\n}\n\nandroid {\n    namespace = \"com.t8rin.imagetoolbox.benchmark\"\n    compileSdk = libs.versions.androidCompileSdk.get().toIntOrNull()\n\n    defaultConfig {\n        minSdk = 23\n        targetSdk = libs.versions.androidTargetSdk.get().toIntOrNull()\n\n        testInstrumentationRunner = \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n\n    compileOptions {\n        sourceCompatibility = JavaVersion.toVersion(libs.versions.jvmTarget.get())\n        targetCompatibility = JavaVersion.toVersion(libs.versions.jvmTarget.get())\n    }\n\n    kotlin {\n        compilerOptions {\n            jvmTarget.set(JvmTarget.fromTarget(libs.versions.jvmTarget.get()))\n        }\n    }\n\n    buildTypes {\n        // This benchmark buildType is used for benchmarking, and should function like your\n        // release build (for example, with minification on). It\"s signed with a debug key\n        // for easy local/CI testing.\n        create(\"benchmark\") {\n            isDebuggable = true\n            signingConfig = getByName(\"debug\").signingConfig\n            matchingFallbacks += listOf(\"release\")\n        }\n    }\n\n    flavorDimensions += listOf(\"app\")\n    productFlavors {\n        create(\"foss\") { dimension = \"app\" }\n        create(\"market\") { dimension = \"app\" }\n    }\n\n    targetProjectPath = \":app\"\n    experimentalProperties[\"android.experimental.self-instrumenting\"] = true\n}\n\ndependencies {\n    implementation(libs.androidx.test.ext.junit)\n    implementation(libs.espresso)\n    implementation(libs.uiautomator)\n    implementation(libs.benchmark.macro.junit4)\n}\n\nandroidComponents {\n    beforeVariants(selector().all()) {\n        it.enable = it.buildType == \"benchmark\"\n    }\n}"
  },
  {
    "path": "benchmark/src/main/AndroidManifest.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest />"
  },
  {
    "path": "benchmark/src/main/java/com/t8rin/imagetoolbox/benchmark/BaselineProfileGenerator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.benchmark\n\nimport androidx.annotation.RequiresApi\nimport androidx.benchmark.macro.junit4.BaselineProfileRule\nimport org.junit.Rule\nimport org.junit.Test\n\n@RequiresApi(28)\nclass BaselineProfileGenerator {\n    @get:Rule\n    val baselineProfileRule = BaselineProfileRule()\n\n    @Test\n    fun startup() = baselineProfileRule.collect(\n        packageName = \"com.t8rin.imagetoolbox\",\n        includeInStartupProfile = true,\n        profileBlock = {\n            startActivityAndWait()\n            device.pressBack()\n        }\n    )\n}"
  },
  {
    "path": "build-logic/.gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n.DS_Store\n/build\n/app/release\n/captures\n.externalNativeBuild\n.cxx\n/.idea"
  },
  {
    "path": "build-logic/convention/.gitignore",
    "content": "/build"
  },
  {
    "path": "build-logic/convention/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nimport org.jetbrains.kotlin.gradle.dsl.JvmTarget\nimport org.jetbrains.kotlin.gradle.tasks.KotlinCompile\n\nplugins {\n    `kotlin-dsl`\n}\n\ngroup = \"com.t8rin.imagetoolbox.buildlogic\"\n\n// Configure the build-logic plugins to target JDK 17\n// This matches the JDK used to build the project, and is not related to what is running on device.\njava {\n    sourceCompatibility = JavaVersion.VERSION_17\n    targetCompatibility = JavaVersion.VERSION_17\n}\ntasks.withType<KotlinCompile>().configureEach {\n    compilerOptions {\n        jvmTarget.set(JvmTarget.JVM_17)\n    }\n}\n\ndependencies {\n    compileOnly(libs.agp.gradle)\n    compileOnly(libs.kotlin.gradle)\n    compileOnly(libs.detekt.gradle)\n    compileOnly(libs.compose.compiler.gradle)\n    compileOnly(files(libs.javaClass.superclass.protectionDomain.codeSource.location))\n}\n\ngradlePlugin {\n    // register the convention plugin\n    plugins {\n        register(\"imageToolboxLibrary\") {\n            id = \"image.toolbox.library\"\n            implementationClass = \"ImageToolboxLibraryPlugin\"\n        }\n        register(\"imageToolboxHiltPlugin\") {\n            id = \"image.toolbox.hilt\"\n            implementationClass = \"ImageToolboxHiltPlugin\"\n        }\n        register(\"imageToolboxLibraryFeature\") {\n            id = \"image.toolbox.feature\"\n            implementationClass = \"ImageToolboxLibraryFeaturePlugin\"\n        }\n        register(\"imageToolboxLibraryComposePlugin\") {\n            id = \"image.toolbox.compose\"\n            implementationClass = \"ImageToolboxLibraryComposePlugin\"\n        }\n        register(\"imageToolboxApplicationPlugin\") {\n            id = \"image.toolbox.application\"\n            implementationClass = \"ImageToolboxApplicationPlugin\"\n        }\n    }\n}"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/ImageToolboxApplicationPlugin.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nimport com.android.build.api.dsl.ApplicationExtension\nimport com.t8rin.imagetoolbox.configureCompose\nimport com.t8rin.imagetoolbox.configureDetekt\nimport com.t8rin.imagetoolbox.configureKotlinAndroid\nimport com.t8rin.imagetoolbox.core\nimport com.t8rin.imagetoolbox.crash\nimport com.t8rin.imagetoolbox.data\nimport com.t8rin.imagetoolbox.di\nimport com.t8rin.imagetoolbox.domain\nimport com.t8rin.imagetoolbox.implementation\nimport com.t8rin.imagetoolbox.libs\nimport com.t8rin.imagetoolbox.projects\nimport com.t8rin.imagetoolbox.resources\nimport com.t8rin.imagetoolbox.settings\nimport com.t8rin.imagetoolbox.ui\nimport com.t8rin.imagetoolbox.utils\nimport io.gitlab.arturbosch.detekt.extensions.DetektExtension\nimport org.gradle.api.Plugin\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.apply\nimport org.gradle.kotlin.dsl.configure\nimport org.gradle.kotlin.dsl.dependencies\nimport org.gradle.kotlin.dsl.getByType\n\n@Suppress(\"UNUSED\")\nclass ImageToolboxApplicationPlugin : Plugin<Project> {\n    override fun apply(target: Project) {\n        with(target) {\n            apply(plugin = \"com.android.application\")\n            apply(plugin = \"kotlin-parcelize\")\n            apply(plugin = \"com.google.gms.google-services\")\n            apply(plugin = \"com.google.firebase.crashlytics\")\n            apply(plugin = \"com.mikepenz.aboutlibraries.plugin.android\")\n            apply(plugin = \"org.jetbrains.kotlin.plugin.compose\")\n            apply(plugin = \"io.gitlab.arturbosch.detekt\")\n\n            configureDetekt(extensions.getByType<DetektExtension>())\n\n            extensions.configure<ApplicationExtension> {\n                configureKotlinAndroid(\n                    commonExtension = this,\n                    createFlavors = false\n                )\n                defaultConfig.targetSdk = libs.versions.androidTargetSdk.get().toIntOrNull()\n            }\n\n            dependencies {\n                implementation(libs.androidxCore)\n                implementation(projects.core.data)\n                implementation(projects.core.ui)\n                implementation(projects.core.domain)\n                implementation(projects.core.resources)\n                implementation(projects.core.settings)\n                implementation(projects.core.di)\n                implementation(projects.core.crash)\n                implementation(projects.core.utils)\n            }\n\n            configureCompose(extensions.getByType<ApplicationExtension>())\n        }\n    }\n}"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/ImageToolboxHiltPlugin.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nimport com.t8rin.imagetoolbox.implementation\nimport com.t8rin.imagetoolbox.ksp\nimport com.t8rin.imagetoolbox.libs\nimport org.gradle.api.Plugin\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.apply\nimport org.gradle.kotlin.dsl.dependencies\n\n@Suppress(\"UNUSED\")\nclass ImageToolboxHiltPlugin : Plugin<Project> {\n    override fun apply(target: Project) {\n        with(target) {\n            apply(plugin = \"dagger.hilt.android.plugin\")\n            apply(plugin = \"com.google.devtools.ksp\")\n\n            dependencies {\n                implementation(libs.dagger.hilt.android)\n                ksp(libs.dagger.hilt.compiler)\n            }\n        }\n    }\n}"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/ImageToolboxLibraryComposePlugin.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nimport com.android.build.api.dsl.LibraryExtension\nimport com.t8rin.imagetoolbox.configureCompose\nimport org.gradle.api.Plugin\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.apply\nimport org.gradle.kotlin.dsl.getByType\n\n@Suppress(\"UNUSED\")\nclass ImageToolboxLibraryComposePlugin : Plugin<Project> {\n    override fun apply(target: Project) {\n        with(target) {\n            apply(plugin = \"com.android.library\")\n            apply(plugin = \"org.jetbrains.kotlin.plugin.compose\")\n\n            configureCompose(extensions.getByType<LibraryExtension>())\n        }\n    }\n}\n"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/ImageToolboxLibraryFeaturePlugin.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nimport com.t8rin.imagetoolbox.configureDetekt\nimport com.t8rin.imagetoolbox.core\nimport com.t8rin.imagetoolbox.crash\nimport com.t8rin.imagetoolbox.data\nimport com.t8rin.imagetoolbox.di\nimport com.t8rin.imagetoolbox.domain\nimport com.t8rin.imagetoolbox.implementation\nimport com.t8rin.imagetoolbox.projects\nimport com.t8rin.imagetoolbox.resources\nimport com.t8rin.imagetoolbox.settings\nimport com.t8rin.imagetoolbox.ui\nimport io.gitlab.arturbosch.detekt.extensions.DetektExtension\nimport org.gradle.api.Plugin\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.dependencies\nimport org.gradle.kotlin.dsl.getByType\n\n@Suppress(\"UNUSED\")\nclass ImageToolboxLibraryFeaturePlugin : Plugin<Project> {\n    override fun apply(target: Project) {\n        with(target) {\n            configureDetekt(extensions.getByType<DetektExtension>())\n            dependencies {\n                implementation(projects.core.data)\n                implementation(projects.core.ui)\n                implementation(projects.core.domain)\n                implementation(projects.core.resources)\n                implementation(projects.core.settings)\n                implementation(projects.core.di)\n                implementation(projects.core.crash)\n            }\n        }\n    }\n}"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/ImageToolboxLibraryPlugin.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nimport com.android.build.api.dsl.LibraryExtension\nimport com.t8rin.imagetoolbox.configureDetekt\nimport com.t8rin.imagetoolbox.configureKotlinAndroid\nimport com.t8rin.imagetoolbox.implementation\nimport com.t8rin.imagetoolbox.libs\nimport io.gitlab.arturbosch.detekt.extensions.DetektExtension\nimport org.gradle.api.Plugin\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.configure\nimport org.gradle.kotlin.dsl.dependencies\nimport org.gradle.kotlin.dsl.getByType\n\n@Suppress(\"UNUSED\")\nclass ImageToolboxLibraryPlugin : Plugin<Project> {\n    override fun apply(target: Project) {\n        with(target) {\n            with(pluginManager) {\n                apply(\"com.android.library\")\n                apply(\"kotlin-parcelize\")\n                apply(\"kotlinx-serialization\")\n                apply(libs.detekt.gradle.get().group)\n            }\n\n            configureDetekt(extensions.getByType<DetektExtension>())\n\n            extensions.configure<LibraryExtension> {\n                configureKotlinAndroid(this)\n                defaultConfig.minSdk = libs.versions.androidMinSdk.get().toIntOrNull()\n            }\n\n            dependencies {\n                implementation(libs.androidxCore)\n            }\n        }\n    }\n}"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/com/t8rin/imagetoolbox/ConfigureCompose.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox\n\nimport com.android.build.api.dsl.CommonExtension\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.configure\nimport org.gradle.kotlin.dsl.dependencies\nimport org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension\n\ninternal fun Project.configureCompose(\n    commonExtension: CommonExtension\n) {\n    commonExtension.apply {\n        buildFeatures.apply {\n            compose = true\n        }\n\n        dependencies {\n            implementation(libs.androidx.material3)\n            implementation(libs.window.sizeclass)\n            implementation(libs.androidx.material)\n            implementation(libs.icons.extended)\n            implementation(libs.compose.preview)\n        }\n    }\n\n    extensions.configure<ComposeCompilerGradlePluginExtension> {\n        stabilityConfigurationFiles.addAll(\n            rootProject.layout.projectDirectory.file(\"compose_compiler_config.conf\")\n        )\n    }\n}\n"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/com/t8rin/imagetoolbox/ConfigureDetekt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox\n\n\nimport io.gitlab.arturbosch.detekt.Detekt\nimport io.gitlab.arturbosch.detekt.extensions.DetektExtension\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.dependencies\nimport org.gradle.kotlin.dsl.named\n\ninternal fun Project.configureDetekt(extension: DetektExtension) = extension.apply {\n    tasks.named<Detekt>(\"detekt\") {\n        reports {\n            xml.required.set(true)\n            html.required.set(true)\n            txt.required.set(true)\n            sarif.required.set(true)\n            md.required.set(true)\n        }\n    }\n    dependencies {\n        detektPlugins(libs.detekt.formatting)\n        detektPlugins(libs.detekt.compose)\n    }\n}"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/com/t8rin/imagetoolbox/ConfigureKotlinAndroid.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox\n\nimport com.android.build.api.dsl.CommonExtension\nimport org.gradle.api.JavaVersion\nimport org.gradle.api.Project\nimport org.gradle.kotlin.dsl.assign\nimport org.gradle.kotlin.dsl.configure\nimport org.gradle.kotlin.dsl.dependencies\nimport org.gradle.kotlin.dsl.provideDelegate\nimport org.gradle.kotlin.dsl.withType\nimport org.jetbrains.kotlin.gradle.dsl.JvmTarget\nimport org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension\nimport org.jetbrains.kotlin.gradle.dsl.KotlinBaseExtension\nimport org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension\nimport org.jetbrains.kotlin.gradle.tasks.KotlinCompile\n\ninternal fun Project.configureKotlinAndroid(\n    commonExtension: CommonExtension,\n    createFlavors: Boolean = true\n) {\n    commonExtension.apply {\n        compileSdk = libs.versions.androidCompileSdk.get().toIntOrNull()\n        compileSdkExtension = libs.versions.androidCompileSdkExtension.get().toIntOrNull()\n\n        defaultConfig.apply {\n            minSdk = libs.versions.androidMinSdk.get().toIntOrNull()\n        }\n\n        if (createFlavors) {\n            flavorDimensions += \"app\"\n\n            productFlavors.apply {\n                create(\"foss\") {\n                    dimension = \"app\"\n                }\n                create(\"market\") {\n                    dimension = \"app\"\n                }\n            }\n        }\n\n        compileOptions.apply {\n            sourceCompatibility = javaVersion\n            targetCompatibility = javaVersion\n            isCoreLibraryDesugaringEnabled = true\n        }\n\n        buildFeatures.apply {\n            compose = false\n            aidl = false\n            shaders = false\n            buildConfig = false\n            resValues = false\n        }\n\n        packaging.apply {\n            resources {\n                excludes.add(\"/META-INF/{AL2.0,LGPL2.1}\")\n            }\n        }\n\n        lint.apply {\n            disable += \"UsingMaterialAndMaterial3Libraries\"\n            disable += \"ModifierParameter\"\n        }\n    }\n\n    configureKotlin<KotlinAndroidProjectExtension>()\n\n    dependencies {\n        coreLibraryDesugaring(libs.desugaring)\n    }\n}\n\nval Project.javaVersion: JavaVersion\n    get() = JavaVersion.toVersion(\n        libs.versions.jvmTarget.get()\n    )\n\n/**\n * Configure base Kotlin options\n */\nprivate inline fun <reified T : KotlinBaseExtension> Project.configureKotlin() = configure<T> {\n    val args = listOf(\n        \"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api\",\n        \"-opt-in=androidx.compose.material3.ExperimentalMaterial3ExpressiveApi\",\n        \"-opt-in=androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi\",\n        \"-opt-in=androidx.compose.animation.ExperimentalAnimationApi\",\n        \"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi\",\n        \"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi\",\n        \"-opt-in=androidx.compose.ui.unit.ExperimentalUnitApi\",\n        \"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi\",\n        \"-opt-in=kotlinx.coroutines.FlowPreview\",\n        \"-opt-in=androidx.compose.material.ExperimentalMaterialApi\",\n        \"-opt-in=com.arkivanov.decompose.ExperimentalDecomposeApi\",\n        \"-opt-in=coil3.annotation.ExperimentalCoilApi\",\n        \"-opt-in=coil3.annotation.DelicateCoilApi\",\n        \"-opt-in=kotlin.contracts.ExperimentalContracts\",\n        \"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi\",\n        \"-opt-in=androidx.compose.ui.text.ExperimentalTextApi\",\n        \"-opt-in=kotlinx.coroutines.DelicateCoroutinesApi\",\n        \"-Xannotation-default-target=param-property\",\n        \"-XXLanguage:+PropertyParamAnnotationDefaultTargetMode\"\n    )\n    // Treat all Kotlin warnings as errors (disabled by default)\n    // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties\n    val warningsAsErrors: String? by project\n    when (this) {\n        is KotlinAndroidProjectExtension -> compilerOptions\n        is KotlinJvmProjectExtension -> compilerOptions\n        else -> error(\"Unsupported project extension $this ${T::class}\")\n    }.apply {\n        jvmTarget = JvmTarget.fromTarget(libs.versions.jvmTarget.get())\n        allWarningsAsErrors = warningsAsErrors.toBoolean()\n        freeCompilerArgs.addAll(args)\n    }\n    tasks.withType<KotlinCompile>().configureEach {\n        compilerOptions.freeCompilerArgs.addAll(args)\n    }\n}"
  },
  {
    "path": "build-logic/convention/src/main/kotlin/com/t8rin/imagetoolbox/ProjectExtensions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox\n\nimport org.gradle.accessors.dm.LibrariesForLibs\nimport org.gradle.api.Project\nimport org.gradle.api.artifacts.MinimalExternalModuleDependency\nimport org.gradle.api.provider.Provider\nimport org.gradle.kotlin.dsl.DependencyHandlerScope\nimport org.gradle.kotlin.dsl.the\n\nval Project.libs\n    get(): LibrariesForLibs = the<LibrariesForLibs>()\n\nval Project.projects\n    get(): Projects = object : Projects, ProjectHolder {\n        override fun project(path: String): Project = this@projects.project(path)\n    }\n\nval Projects.core\n    get(): CoreProjects = object : CoreProjects, ProjectHolder by this {}\n\nval CoreProjects.data\n    get(): ProjectLibrary = project(\":core:data\")\n\nval CoreProjects.ui\n    get(): ProjectLibrary = project(\":core:ui\")\n\nval CoreProjects.domain\n    get(): ProjectLibrary = project(\":core:domain\")\n\nval CoreProjects.resources\n    get(): ProjectLibrary = project(\":core:resources\")\n\nval CoreProjects.settings\n    get(): ProjectLibrary = project(\":core:settings\")\n\nval CoreProjects.di\n    get(): ProjectLibrary = project(\":core:di\")\n\nval CoreProjects.crash\n    get(): ProjectLibrary = project(\":core:crash\")\n\nval CoreProjects.utils\n    get(): ProjectLibrary = project(\":core:utils\")\n\nfun DependencyHandlerScope.implementation(\n    dependency: Library\n) = add(\"implementation\", dependency)\n\nfun DependencyHandlerScope.coreLibraryDesugaring(\n    dependency: Library\n) = add(\"coreLibraryDesugaring\", dependency)\n\nfun DependencyHandlerScope.implementation(\n    dependency: ProjectLibrary\n) = add(\"implementation\", dependency)\n\nfun DependencyHandlerScope.ksp(\n    dependency: Library\n) = add(\"ksp\", dependency)\n\nfun DependencyHandlerScope.detektPlugins(\n    dependency: Library\n) = add(\"detektPlugins\", dependency)\n\ntypealias Library = Provider<MinimalExternalModuleDependency>\n\ntypealias ProjectLibrary = Project\n\ninterface Projects : ProjectHolder\n\ninterface CoreProjects : ProjectHolder\n\ninterface ProjectHolder {\n    fun project(path: String): Project\n}"
  },
  {
    "path": "build-logic/settings.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnstableApiUsage\")\n\ndependencyResolutionManagement {\n    repositories {\n        google()\n        mavenCentral()\n    }\n    versionCatalogs {\n        create(\"libs\") {\n            // make sure the file rootProject/gradle/verison.toml exists!\n            from(files(\"../gradle/libs.versions.toml\"))\n        }\n    }\n}\n\nrootProject.name = \"build-logic\"\ninclude(\":convention\")"
  },
  {
    "path": "build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nbuildscript {\n    repositories {\n        gradlePluginPortal()\n        google()\n        mavenCentral()\n        maven { setUrl(\"https://jitpack.io\") }\n    }\n\n    dependencies {\n        classpath(libs.kotlinx.serialization.gradle)\n        classpath(libs.ksp.gradle)\n        classpath(libs.agp.gradle)\n        classpath(libs.kotlin.gradle)\n        classpath(libs.hilt.gradle)\n        classpath(libs.gms.gradle)\n        classpath(libs.firebase.crashlytics.gradle)\n        classpath(libs.baselineprofile.gradle)\n        classpath(libs.detekt.gradle)\n        classpath(libs.aboutlibraries.gradle)\n        classpath(libs.compose.compiler.gradle)\n    }\n}\n\ntasks.register(\"clean\", Delete::class) {\n    delete(rootProject.layout.buildDirectory)\n}"
  },
  {
    "path": "compose_compiler_config.conf",
    "content": "java.time.ZoneId\njava.time.ZoneOffset\njava.text.DecimalFormat\njava.text.NumberFormat\njava.time.Instant\njava.time.Duration\njava.time.LocalDate\njava.time.LocalDateTime\njava.time.LocalTime\njava.time.ZonedDateTime\njava.util.Date\njava.util.Locale\njava.io.File\n\nkotlin.collections.*\nkotlin.time.Duration\n\nandroid.net.Uri\nandroid.graphics.Bitmap\n\nandroidx.compose.ui.graphics.painter.Painter\nandroidx.compose.ui.graphics.vector.ImageVector\nandroidx.compose.ui.graphics.ImageBitmap\n\ncom.t8rin.imagetoolbox.core.crash.*\ncom.t8rin.imagetoolbox.core.filters.*\ncom.t8rin.imagetoolbox.core.resources.*\ncom.t8rin.imagetoolbox.core.data.*\ncom.t8rin.imagetoolbox.core.domain.*\ncom.t8rin.imagetoolbox.core.ui.*\ncom.t8rin.imagetoolbox.core.settings.*\n\ncom.t8rin.imagetoolbox.core.*\ncom.t8rin.imagetoolbox.feature.*\n\nnl.dionsegijn.konfetti.core.*"
  },
  {
    "path": "core/crash/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/crash/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.crash\"\n\ndependencies {\n    implementation(projects.core.ui)\n    implementation(projects.core.settings)\n\n    \"marketImplementation\"(platform(libs.firebase.bom))\n    \"marketImplementation\"(libs.firebase.crashlytics)\n    \"marketImplementation\"(libs.firebase.analytics)\n}"
  },
  {
    "path": "core/crash/src/foss/java/com/t8rin/imagetoolbox/core/crash/data/AnalyticsManagerImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.data\n\nimport com.t8rin.imagetoolbox.core.domain.remote.AnalyticsManager\n\ninternal object AnalyticsManagerImpl : AnalyticsManager {\n\n    override var allowCollectCrashlytics: Boolean = false\n\n    override var allowCollectAnalytics: Boolean = false\n\n    override fun updateAnalyticsCollectionEnabled(value: Boolean) = Unit\n\n    override fun updateAllowCollectCrashlytics(value: Boolean) = Unit\n\n    override fun sendReport(throwable: Throwable) = Unit\n\n    override fun registerScreenOpen(screenName: String) = Unit\n}"
  },
  {
    "path": "core/crash/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application>\n        <activity android:name=\".presentation.CrashActivity\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/di/CrashModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.di\n\nimport com.t8rin.imagetoolbox.core.crash.data.AnalyticsManagerImpl\nimport com.t8rin.imagetoolbox.core.domain.remote.AnalyticsManager\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal object CrashModule {\n\n    @Provides\n    @Singleton\n    fun analyticsManager(): AnalyticsManager = AnalyticsManagerImpl\n\n}"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/CrashActivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation\n\nimport androidx.compose.runtime.Composable\nimport com.arkivanov.decompose.retainedComponent\nimport com.t8rin.imagetoolbox.core.crash.presentation.components.CrashHandler\nimport com.t8rin.imagetoolbox.core.crash.presentation.components.CrashRootContent\nimport com.t8rin.imagetoolbox.core.crash.presentation.screenLogic.CrashComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.ComposeActivity\nimport dagger.hilt.android.AndroidEntryPoint\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nclass CrashActivity : ComposeActivity(), CrashHandler {\n\n    @Inject\n    lateinit var componentFactory: CrashComponent.Factory\n\n    private val component: CrashComponent by lazy {\n        retainedComponent { componentContext ->\n            componentFactory(\n                componentContext = componentContext,\n                crashInfo = getCrashInfo()\n            )\n        }\n    }\n\n    @Composable\n    override fun Content() = CrashRootContent(component = component)\n\n}"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/components/CrashActionButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.TELEGRAM_GROUP_LINK\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Github\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileShare\nimport com.t8rin.imagetoolbox.core.resources.icons.Telegram\nimport com.t8rin.imagetoolbox.core.ui.theme.Black\nimport com.t8rin.imagetoolbox.core.ui.theme.Blue\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\ninternal fun CrashActionButtons(\n    onCopyCrashInfo: () -> Unit,\n    onShareLogs: () -> Unit,\n    githubLink: String\n) {\n    BoxWithConstraints(\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        val containerWidth = maxWidth\n        Column {\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                horizontalArrangement = Arrangement.Center,\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                val linkHandler = LocalUriHandler.current\n                LargeEnhancedButton(\n                    onClick = {\n                        onCopyCrashInfo()\n                        linkHandler.openUri(TELEGRAM_GROUP_LINK)\n                    },\n                    modifier = Modifier\n                        .weight(1f)\n                        .width(containerWidth / 2f)\n                        .padding(end = 8.dp),\n                    containerColor = Blue,\n                    contentColor = White,\n                    icon = Icons.Rounded.Telegram,\n                    text = stringResource(R.string.contact_me)\n                )\n                LargeEnhancedButton(\n                    onClick = {\n                        onCopyCrashInfo()\n                        linkHandler.openUri(githubLink)\n                    },\n                    modifier = Modifier\n                        .weight(1f)\n                        .width(containerWidth / 2f),\n                    containerColor = Black,\n                    contentColor = White,\n                    icon = Icons.Rounded.Github,\n                    text = stringResource(id = R.string.create_issue),\n                )\n            }\n            Spacer(modifier = Modifier.height(12.dp))\n            LargeEnhancedButton(\n                onClick = {\n                    onCopyCrashInfo()\n                    onShareLogs()\n                },\n                modifier = Modifier.fillMaxWidth(),\n                containerColor = MaterialTheme.colorScheme.primary,\n                contentColor = MaterialTheme.colorScheme.onPrimary,\n                icon = Icons.Rounded.MobileShare,\n                text = stringResource(id = R.string.send_logs),\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun LargeEnhancedButton(\n    onClick: () -> Unit,\n    containerColor: Color,\n    contentColor: Color,\n    icon: ImageVector,\n    text: String,\n    modifier: Modifier = Modifier,\n) {\n    EnhancedButton(\n        onClick = onClick,\n        modifier = modifier\n            .height(48.dp),\n        containerColor = containerColor,\n        contentColor = contentColor,\n        borderColor = MaterialTheme.colorScheme.outlineVariant(\n            onTopOf = containerColor\n        ),\n        contentPadding = ButtonDefaults.ButtonWithIconContentPadding\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.Center\n        ) {\n            Icon(\n                imageVector = icon,\n                contentDescription = text\n            )\n            Spacer(modifier = Modifier.width(8.dp))\n            AutoSizeText(\n                text = text,\n                maxLines = 1\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/components/CrashAttentionCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.statusBarsPadding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageToolboxBroken\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun CrashAttentionCard() {\n    val isNightMode = LocalSettingsState.current.isNightMode\n    Spacer(modifier = Modifier.height(16.dp))\n    Column(\n        modifier = Modifier\n            .fillMaxWidth()\n            .container(\n                shape = ShapeDefaults.large,\n                resultPadding = 16.dp,\n                color = takeColorFromScheme {\n                    if (isNightMode) {\n                        errorContainer.blend(surfaceContainerLow, 0.75f)\n                    } else {\n                        errorContainer.blend(surfaceContainerLow, 0.65f)\n                    }\n                }\n            ),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        val contentColor = takeColorFromScheme {\n            if (isNightMode) {\n                onError.blend(onSurface, 0.75f)\n            } else {\n                error.blend(onSurface, 0.6f)\n            }\n        }\n\n        Icon(\n            imageVector = Icons.Outlined.ImageToolboxBroken,\n            contentDescription = null,\n            modifier = Modifier\n                .size(80.dp)\n                .statusBarsPadding(),\n            tint = contentColor\n        )\n        Spacer(modifier = Modifier.height(16.dp))\n        Text(\n            text = stringResource(R.string.crash_title),\n            fontWeight = FontWeight.Bold,\n            textAlign = TextAlign.Center,\n            fontSize = 22.sp,\n            lineHeight = 26.sp,\n            color = contentColor\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        Text(\n            text = stringResource(R.string.crash_subtitle),\n            textAlign = TextAlign.Center,\n            fontSize = 16.sp,\n            lineHeight = 20.sp,\n            color = contentColor\n        )\n    }\n}"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/components/CrashBottomButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.components\n\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.displayCutoutPadding\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material.icons.rounded.RestartAlt\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButtonType\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\ninternal fun CrashBottomButtons(\n    modifier: Modifier,\n    onCopy: () -> Unit,\n    onRestartApp: () -> Unit\n) {\n    Row(\n        modifier = modifier\n            .padding(8.dp)\n            .navigationBarsPadding()\n            .displayCutoutPadding()\n    ) {\n        EnhancedFloatingActionButton(\n            modifier = Modifier\n                .weight(1f, false),\n            onClick = onRestartApp,\n            content = {\n                Spacer(Modifier.width(16.dp))\n                Icon(\n                    imageVector = Icons.Rounded.RestartAlt,\n                    contentDescription = stringResource(R.string.restart_app)\n                )\n                Spacer(Modifier.width(16.dp))\n                AutoSizeText(\n                    text = stringResource(R.string.restart_app),\n                    maxLines = 1\n                )\n                Spacer(Modifier.width(16.dp))\n            }\n        )\n        Spacer(Modifier.width(8.dp))\n        EnhancedFloatingActionButton(\n            containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n            onClick = onCopy,\n            type = EnhancedFloatingActionButtonType.SecondaryHorizontal\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.ContentCopy,\n                contentDescription = stringResource(R.string.copy)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/components/CrashHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.components\n\nimport android.content.Intent\nimport android.util.Log\nimport com.t8rin.imagetoolbox.core.domain.ISSUE_TRACKER\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.DeviceInfo\nimport com.t8rin.imagetoolbox.core.utils.encodeEscaped\n\ninterface CrashHandler {\n\n    fun getIntent(): Intent\n\n    private val intent: Intent\n        @JvmName(\"getIntentValue\")\n        get() = getIntent()\n\n    private fun getCrashReason(): String = intent.getStringExtra(EXCEPTION_EXTRA) ?: \"\"\n\n    fun getCrashInfo(): CrashInfo {\n        val crashReason = getCrashReason()\n        val splitData = crashReason.split(DELIMITER)\n        val exceptionName = splitData.first().trim()\n        val stackTrace = splitData.drop(1).joinToString(DELIMITER)\n\n        val title = \"[Bug] App Crash: $exceptionName\"\n\n        val deviceInfo = DeviceInfo.getAsString()\n\n        val body = listOf(deviceInfo, stackTrace).joinToString(DELIMITER)\n\n        return CrashInfo(\n            title = title,\n            body = body,\n            exceptionName = exceptionName,\n            stackTrace = stackTrace\n        )\n    }\n\n    companion object {\n        internal const val EXCEPTION_EXTRA = \"EXCEPTION_EXTRA\"\n\n        fun getCrashInfoAsExtra(\n            throwable: Throwable\n        ): String {\n            val exceptionName = throwable::class.java.simpleName\n            val stackTrace = Log.getStackTraceString(throwable)\n\n            return listOf(exceptionName, stackTrace).joinToString(DELIMITER)\n        }\n    }\n}\n\ndata class CrashInfo(\n    val title: String,\n    val body: String,\n    val exceptionName: String,\n    val stackTrace: String\n) {\n    val textToSend = listOf(title, body).joinToString(DELIMITER)\n\n    val githubLink =\n        \"$ISSUE_TRACKER/new?title=${title.encodeEscaped()}&body=${body.encodeEscaped()}\"\n}\n\nprivate const val DELIMITER = \"\\n\\n\""
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/components/CrashInfoCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.selection.SelectionContainer\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BugReport\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\ninternal fun CrashInfoCard(crashInfo: CrashInfo) {\n    ExpandableItem(\n        shape = ShapeDefaults.extraLarge,\n        modifier = Modifier.fillMaxWidth(),\n        visibleContent = {\n            Icon(\n                imageVector = Icons.Rounded.BugReport,\n                contentDescription = \"crash\",\n                modifier = Modifier.padding(\n                    start = 16.dp,\n                    top = 16.dp,\n                    bottom = 16.dp\n                )\n            )\n            AutoSizeText(\n                text = crashInfo.exceptionName,\n                fontWeight = FontWeight.Bold,\n                textAlign = TextAlign.Start,\n                modifier = Modifier\n                    .padding(16.dp)\n                    .weight(1f)\n            )\n        },\n        expandableContent = {\n            AnimatedVisibility(visible = it) {\n                SelectionContainer {\n                    Text(\n                        text = crashInfo.stackTrace,\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier.padding(16.dp)\n                    )\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/components/CrashRootContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.components\n\nimport android.content.Intent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.displayCutoutPadding\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.crash.presentation.screenLogic.CrashComponent\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppActivityClass\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ImageToolboxCompositionLocals\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\n\n@Composable\ninternal fun CrashRootContent(component: CrashComponent) {\n    val context = LocalContext.current\n    val crashInfo = component.crashInfo\n\n\n    ImageToolboxCompositionLocals(\n        settingsState = component.settingsState.toUiState()\n    ) {\n        val copyCrashInfo: () -> Unit = {\n            Clipboard.copy(crashInfo.textToSend)\n        }\n\n        Column(\n            modifier = Modifier\n                .align(Alignment.Center)\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(horizontal = 16.dp)\n                .padding(bottom = 80.dp)\n                .navigationBarsPadding()\n                .displayCutoutPadding(),\n            verticalArrangement = Arrangement.Center,\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            CrashAttentionCard()\n            Spacer(modifier = Modifier.height(24.dp))\n            CrashActionButtons(\n                onCopyCrashInfo = copyCrashInfo,\n                onShareLogs = component::shareLogs,\n                githubLink = crashInfo.githubLink\n            )\n            Spacer(modifier = Modifier.height(24.dp))\n            CrashInfoCard(crashInfo = crashInfo)\n        }\n\n        CrashBottomButtons(\n            modifier = Modifier.align(Alignment.BottomCenter),\n            onCopy = copyCrashInfo,\n            onRestartApp = {\n                context.startActivity(\n                    Intent(context, AppActivityClass)\n                )\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/components/GlobalExceptionHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.components\n\nimport android.content.Context\nimport android.content.Intent\nimport com.t8rin.imagetoolbox.core.crash.di.CrashModule\nimport com.t8rin.imagetoolbox.core.crash.presentation.CrashActivity\nimport com.t8rin.imagetoolbox.core.domain.remote.AnalyticsManager\nimport com.t8rin.logger.makeLog\nimport kotlin.system.exitProcess\n\nprivate class GlobalExceptionHandler<T : CrashHandler> private constructor(\n    private val applicationContext: Context,\n    private val defaultHandler: Thread.UncaughtExceptionHandler?,\n    private val activityToBeLaunched: Class<T>\n) : Thread.UncaughtExceptionHandler {\n\n    override fun uncaughtException(\n        p0: Thread,\n        p1: Throwable\n    ) {\n        sendReport(p1)\n\n        runCatching {\n            p1.makeLog(\"FATAL_EXCEPTION\")\n\n            applicationContext.launchActivity(activityToBeLaunched, p1)\n            exitProcess(0)\n        }.getOrElse {\n            defaultHandler?.uncaughtException(p0, p1)\n        }\n    }\n\n    private fun Context.launchActivity(\n        activity: Class<*>,\n        throwable: Throwable\n    ) = applicationContext.startActivity(\n        Intent(applicationContext, activity).putExtra(\n            CrashHandler.EXCEPTION_EXTRA,\n            CrashHandler.getCrashInfoAsExtra(throwable)\n        ).addFlags(defFlags)\n    )\n\n    companion object : AnalyticsManager by CrashModule.analyticsManager() {\n\n        fun <T : CrashHandler> initialize(\n            applicationContext: Context,\n            activityToBeLaunched: Class<T>,\n        ) = Thread.setDefaultUncaughtExceptionHandler(\n            GlobalExceptionHandler(\n                applicationContext = applicationContext,\n                defaultHandler = Thread.getDefaultUncaughtExceptionHandler()!!,\n                activityToBeLaunched = activityToBeLaunched\n            )\n        )\n\n    }\n}\n\nprivate const val defFlags = Intent.FLAG_ACTIVITY_CLEAR_TOP or\n        Intent.FLAG_ACTIVITY_NEW_TASK or\n        Intent.FLAG_ACTIVITY_CLEAR_TASK\n\nfun Context.applyGlobalExceptionHandler() = GlobalExceptionHandler.initialize(\n    applicationContext = applicationContext,\n    activityToBeLaunched = CrashActivity::class.java,\n)"
  },
  {
    "path": "core/crash/src/main/java/com/t8rin/imagetoolbox/core/crash/presentation/screenLogic/CrashComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.presentation.screenLogic\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.crash.presentation.components.CrashInfo\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.runBlocking\n\nclass CrashComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val crashInfo: CrashInfo,\n    private val settingsManager: SettingsManager,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _settingsState = mutableStateOf(SettingsState.Default)\n    val settingsState: SettingsState by _settingsState\n\n    init {\n        runBlocking {\n            _settingsState.value = settingsManager.getSettingsState()\n        }\n        settingsManager.settingsState.onEach {\n            _settingsState.value = it\n        }.launchIn(componentScope)\n    }\n\n    fun shareLogs() {\n        componentScope.launch {\n            shareProvider.shareUri(\n                uri = settingsManager.createLogsExport(),\n                onComplete = {}\n            )\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            crashInfo: CrashInfo\n        ): CrashComponent\n    }\n\n}"
  },
  {
    "path": "core/crash/src/market/java/com/t8rin/imagetoolbox/core/crash/data/AnalyticsManagerImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.crash.data\n\nimport com.google.firebase.Firebase\nimport com.google.firebase.analytics.FirebaseAnalytics.Event\nimport com.google.firebase.analytics.FirebaseAnalytics.Param\nimport com.google.firebase.analytics.analytics\nimport com.google.firebase.analytics.logEvent\nimport com.google.firebase.crashlytics.crashlytics\nimport com.t8rin.imagetoolbox.core.domain.remote.AnalyticsManager\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.DeviceInfo.Companion.get\n\ninternal object AnalyticsManagerImpl : AnalyticsManager {\n\n    override var allowCollectCrashlytics: Boolean = false\n\n    override var allowCollectAnalytics: Boolean = false\n\n    override fun updateAnalyticsCollectionEnabled(value: Boolean) {\n        analytics.setAnalyticsCollectionEnabled(value)\n        allowCollectAnalytics = value\n    }\n\n    override fun updateAllowCollectCrashlytics(value: Boolean) {\n        crashlytics.isCrashlyticsCollectionEnabled = value\n        allowCollectCrashlytics = value\n\n        if (value) {\n            crashlytics.sendUnsentReports()\n        }\n    }\n\n    override fun sendReport(throwable: Throwable) {\n        if (allowCollectCrashlytics) {\n            crashlytics.apply {\n                recordException(throwable)\n                sendUnsentReports()\n            }\n        }\n    }\n\n    override fun registerScreenOpen(screenName: String) {\n        if (allowCollectAnalytics) {\n            analytics.apply {\n                logEvent(Event.SELECT_CONTENT) { param(Param.CONTENT_TYPE, screenName) }\n                logEvent(screenName) { param(Param.CONTENT, deviceInfo()) }\n            }\n        }\n    }\n\n    private fun deviceInfo(): String {\n        val info = get()\n\n        return listOf(\n            \"Device: ${info.device}\",\n            \"App Version: ${info.appVersion}\"\n        ).joinToString(\",\")\n    }\n\n    private val analytics get() = Firebase.analytics\n    private val crashlytics get() = Firebase.crashlytics\n}"
  },
  {
    "path": "core/data/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/data/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.data\"\n\ndependencies {\n    api(libs.coil)\n    api(libs.coilNetwork)\n    api(libs.ktor)\n    api(libs.ktor.logging)\n    implementation(libs.coilGif)\n    implementation(libs.coilSvg)\n    implementation(libs.trickle)\n\n    implementation(libs.androidx.compose.ui.graphics)\n\n    api(libs.datastore.preferences.android)\n    api(libs.datastore.core.android)\n\n    implementation(libs.avif.coder.coil) {\n        exclude(module = \"com.github.awxkee:avif-coder\")\n    }\n    implementation(libs.avif.coder)\n    implementation(libs.jxl.coder.coil) {\n        exclude(module = \"com.github.awxkee:jxl-coder\")\n    }\n    implementation(libs.jxl.coder)\n\n    implementation(libs.aire)\n    implementation(libs.jpegli.coder)\n\n    implementation(libs.moshi)\n    implementation(libs.moshi.adapters)\n\n    api(libs.androidx.documentfile)\n\n    api(libs.logger)\n\n    implementation(libs.toolbox.gifConverter)\n    implementation(libs.toolbox.exif)\n    implementation(libs.tiffdecoder)\n    implementation(libs.toolbox.qoiCoder)\n    implementation(libs.toolbox.jp2decoder)\n    implementation(libs.toolbox.awebp)\n    implementation(libs.toolbox.psd)\n    implementation(libs.toolbox.apng)\n    implementation(libs.toolbox.djvuCoder)\n    implementation(libs.pdfbox)\n    implementation(libs.trickle)\n\n    implementation(projects.core.domain)\n    implementation(projects.core.resources)\n\n    implementation(projects.core.filters)\n\n    implementation(projects.core.settings)\n    implementation(projects.core.di)\n    api(projects.core.utils)\n}\n"
  },
  {
    "path": "core/data/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_DATA_SYNC\" />\n    <uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\" />\n\n    <application>\n        <service\n            android:name=\".saving.KeepAliveForegroundService\"\n            android:exported=\"false\"\n            android:foregroundServiceType=\"dataSync\"\n            android:stopWithTask=\"true\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coil/Base64Fetcher.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coil\n\nimport android.util.Base64\nimport coil3.ImageLoader\nimport coil3.Uri\nimport coil3.decode.DataSource\nimport coil3.decode.ImageSource\nimport coil3.fetch.FetchResult\nimport coil3.fetch.Fetcher\nimport coil3.fetch.SourceFetchResult\nimport coil3.request.Options\nimport com.t8rin.imagetoolbox.core.domain.utils.isBase64\nimport com.t8rin.imagetoolbox.core.domain.utils.trimToBase64\nimport okio.Buffer\n\ninternal class Base64Fetcher(\n    private val options: Options,\n    private val base64: String\n) : Fetcher {\n\n    override suspend fun fetch(): FetchResult? {\n        val byteArray = runCatching {\n            Base64.decode(base64, Base64.DEFAULT)\n        }.getOrNull() ?: return null\n\n        return SourceFetchResult(\n            source = ImageSource(\n                source = Buffer().apply { write(byteArray) },\n                fileSystem = options.fileSystem,\n            ),\n            mimeType = null,\n            dataSource = DataSource.MEMORY,\n        )\n    }\n\n    class Factory : Fetcher.Factory<Uri> {\n        override fun create(\n            data: Uri,\n            options: Options,\n            imageLoader: ImageLoader,\n        ): Fetcher? {\n            val stripped = data.toString().trimToBase64()\n            return if (stripped.isBase64()) {\n                Base64Fetcher(\n                    options = options,\n                    base64 = stripped\n                )\n            } else null\n        }\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coil/CoilLogger.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coil\n\nimport coil3.util.DebugLogger\nimport coil3.util.Logger\nimport com.t8rin.logger.makeLog\nimport com.t8rin.logger.Logger as RealLogger\n\ninternal class CoilLogger : Logger {\n\n    private val delegate = DebugLogger()\n\n    override var minLevel: Logger.Level\n        get() = delegate.minLevel\n        set(value) {\n            delegate.minLevel = value\n        }\n\n    override fun log(\n        tag: String,\n        level: Logger.Level,\n        message: String?,\n        throwable: Throwable?\n    ) {\n        message?.takeIf {\n            \"NullRequestData\" !in it && \"PDF\" !in it\n        }?.makeLog(tag, level.toLogger())\n\n        throwable?.takeIf {\n            \"The request's data is null\" !in it.message.orEmpty() && \"PDF\" !in it.message.orEmpty()\n        }?.makeLog(tag)\n\n        delegate.log(\n            tag = tag,\n            level = level,\n            message = message,\n            throwable = throwable\n        )\n    }\n\n    private fun Logger.Level.toLogger(): RealLogger.Level = when (this) {\n        Logger.Level.Verbose -> RealLogger.Level.Verbose\n        Logger.Level.Debug -> RealLogger.Level.Debug\n        Logger.Level.Info -> RealLogger.Level.Info\n        Logger.Level.Warn -> RealLogger.Level.Warn\n        Logger.Level.Error -> RealLogger.Level.Error\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coil/MemoryCache.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coil\n\nimport coil3.memory.MemoryCache\n\nfun MemoryCache.remove(key: String) = keys.filter {\n    it.key == key\n}.ifEmpty {\n    listOf(MemoryCache.Key(key))\n}.all(::remove)"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coil/PdfDecoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\", \"unused\")\n\npackage com.t8rin.imagetoolbox.core.data.coil\n\nimport coil3.Extras\nimport coil3.ImageLoader\nimport coil3.asImage\nimport coil3.decode.DecodeResult\nimport coil3.decode.Decoder\nimport coil3.decode.ImageSource\nimport coil3.fetch.SourceFetchResult\nimport coil3.getExtra\nimport coil3.request.ImageRequest\nimport coil3.request.Options\nimport coil3.size.Size\nimport coil3.size.pxOrElse\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.flexibleResize\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.logger.makeLog\nimport com.tom_roush.pdfbox.pdmodel.PDDocument\nimport com.tom_roush.pdfbox.rendering.PDFRenderer\nimport okio.ByteString.Companion.toByteString\nimport kotlin.math.roundToInt\n\ninternal class PdfDecoder(\n    private val source: ImageSource,\n    private val options: Options,\n) : Decoder {\n\n    override suspend fun decode(): DecodeResult {\n        val file = source.file().toFile()\n\n        val image = PDDocument.load(file, options.password.orEmpty()).use { document ->\n            val renderer = PDFRenderer(document)\n\n            val pageIndex = options.pdfPage.coerceIn(0, document.numberOfPages - 1)\n            val box = document.getPage(pageIndex).cropBox\n\n            val originalWidth = box.width\n            val originalHeight = box.height\n\n            val targetSize = IntegerSize(\n                width = originalWidth.roundToInt(),\n                height = originalHeight.roundToInt()\n            ).flexibleResize(\n                w = options.size.width.pxOrElse { 0 },\n                h = options.size.height.pxOrElse { 0 }\n            )\n\n            val scaleX = targetSize.width / originalWidth\n            val scaleY = targetSize.height / originalHeight\n            val scale = minOf(scaleX, scaleY)\n\n            val bitmap = renderer.renderImage(\n                pageIndex,\n                scale.coerceAtMost(2f).makeLog(\"PdfDecoder, scale\")\n            )\n\n            bitmap.asImage()\n        }\n\n        return DecodeResult(\n            image = image,\n            isSampled = true\n        )\n    }\n\n    class Factory : Decoder.Factory {\n        override fun create(\n            result: SourceFetchResult,\n            options: Options,\n            imageLoader: ImageLoader\n        ): Decoder? {\n            return if (isPdf(result)) {\n                PdfDecoder(\n                    source = result.source,\n                    options = options\n                )\n            } else null\n        }\n\n        private fun isPdf(result: SourceFetchResult): Boolean {\n            val pdfMagic = byteArrayOf(0x25, 0x50, 0x44, 0x46).toByteString()\n\n            return result.source.source()\n                .rangeEquals(0, pdfMagic) || result.mimeType == \"application/pdf\"\n        }\n    }\n\n}\n\nfun PdfImageRequest(\n    data: Any?,\n    pdfPage: Int = 0,\n    password: String? = null,\n    size: Size? = null\n): ImageRequest = ImageRequest.Builder(appContext)\n    .data(data)\n    .pdfPage(pdfPage)\n    .password(password)\n    .memoryCacheKey(data.toString() + pdfPage)\n    .diskCacheKey(data.toString() + pdfPage)\n    .apply {\n        size?.let(::size)\n    }\n    .build()\n\nfun ImageRequest.Builder.password(password: String?) = apply {\n    extras[passwordKey] = password\n}\n\nfun ImageRequest.Builder.pdfPage(pdfPage: Int) = apply {\n    extras[pdfPageKey] = pdfPage\n}\n\nval ImageRequest.password: String?\n    get() = getExtra(passwordKey)\n\nval ImageRequest.pdfPage: Int\n    get() = getExtra(pdfPageKey)\n\nval Options.password: String?\n    get() = getExtra(passwordKey)\n\nval Options.pdfPage: Int\n    get() = getExtra(pdfPageKey)\n\nval Extras.Key.Companion.password: Extras.Key<String?>\n    get() = passwordKey\n\nval Extras.Key.Companion.pdfPage: Extras.Key<Int>\n    get() = pdfPageKey\n\nprivate val pdfPageKey = Extras.Key(default = 0)\nprivate val passwordKey = Extras.Key<String?>(default = null)"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coil/TiffDecoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coil\n\nimport android.graphics.Bitmap\nimport android.os.Build\nimport coil3.ImageLoader\nimport coil3.asImage\nimport coil3.decode.DecodeResult\nimport coil3.decode.Decoder\nimport coil3.decode.ImageSource\nimport coil3.fetch.SourceFetchResult\nimport coil3.request.Options\nimport coil3.request.bitmapConfig\nimport coil3.size.Size\nimport coil3.size.pxOrElse\nimport okio.BufferedSource\nimport okio.ByteString.Companion.toByteString\nimport org.beyka.tiffbitmapfactory.TiffBitmapFactory\nimport oupson.apng.utils.Utils.flexibleResize\n\ninternal class TiffDecoder private constructor(\n    private val source: ImageSource,\n    private val options: Options\n) : Decoder {\n\n    @Suppress(\"DEPRECATION\")\n    override suspend fun decode(): DecodeResult? {\n        val config = options.bitmapConfig.takeIf {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n                it != Bitmap.Config.HARDWARE\n            } else true\n        } ?: Bitmap.Config.ARGB_8888\n\n        val decoded = TiffBitmapFactory.decodeFile(\n            source.file().toFile()\n        ) ?: return null\n\n        val image = decoded\n            .createScaledBitmap(options.size)\n            .copy(config, false)\n            .asImage()\n\n        return DecodeResult(\n            image = image,\n            isSampled = options.size != Size.ORIGINAL\n        )\n    }\n\n    private fun Bitmap.createScaledBitmap(\n        size: Size\n    ): Bitmap {\n        if (size == Size.ORIGINAL) return this\n\n        return flexibleResize(\n            maxOf(\n                size.width.pxOrElse { 1 },\n                size.height.pxOrElse { 1 }\n            )\n        )\n    }\n\n    class Factory : Decoder.Factory {\n\n        override fun create(\n            result: SourceFetchResult,\n            options: Options,\n            imageLoader: ImageLoader\n        ): Decoder? {\n            return if (isTiff(result.source.source())) {\n                TiffDecoder(\n                    source = result.source,\n                    options = options\n                )\n            } else null\n        }\n\n        private fun isTiff(source: BufferedSource): Boolean {\n            val magic1 = byteArrayOf(0x49, 0x49, 0x2a, 0x00)\n            val magic2 = byteArrayOf(0x4d, 0x4d, 0x00, 0x2a)\n            val cr2Magic = byteArrayOf(0x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x43, 0x52)\n\n            if (source.rangeEquals(0, cr2Magic.toByteString())) return false\n            if (source.rangeEquals(0, magic1.toByteString())) return true\n            return source.rangeEquals(0, magic2.toByteString())\n        }\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coil/TimeMeasureInterceptor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coil\n\nimport coil3.intercept.Interceptor\nimport coil3.request.ImageResult\nimport coil3.request.transformations\nimport com.t8rin.logger.makeLog\n\ninternal object TimeMeasureInterceptor : Interceptor {\n\n    override suspend fun intercept(\n        chain: Interceptor.Chain\n    ): ImageResult {\n        val time = System.currentTimeMillis()\n        val result = chain.proceed()\n        val endTime = System.currentTimeMillis()\n\n        val delta = endTime - time\n\n        val transformations = chain.request.transformations.joinToString(\", \") {\n            it.toString()\n        }\n        if (transformations.isNotEmpty()) {\n            \"Time $delta ms for transformations = $transformations, with ${result.request.sizeResolver.size()}\".makeLog(\n                \"RealImageLoader\"\n            )\n        }\n        \"Time $delta ms for ${chain.size}\".makeLog(\"RealImageLoader\")\n\n        return result\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coil/UpscaleSvgDecoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coil\n\nimport coil3.ImageLoader\nimport coil3.decode.DecodeResult\nimport coil3.decode.DecodeUtils\nimport coil3.decode.Decoder\nimport coil3.decode.ImageSource\nimport coil3.fetch.SourceFetchResult\nimport coil3.request.Options\nimport coil3.size.Size\nimport coil3.size.pxOrElse\nimport coil3.svg.SvgDecoder\nimport coil3.svg.isSvg\n\ninternal class UpscaleSvgDecoder(\n    private val source: ImageSource,\n    private val options: Options\n) : Decoder {\n\n    override suspend fun decode(): DecodeResult = SvgDecoder(\n        source = source,\n        options = options.copy(\n            size = options.size.coerceAtLeast(2048)\n        )\n    ).decode()\n\n    private fun Size.coerceAtLeast(size: Int): Size = Size(\n        width = width.pxOrElse { 0 }.coerceAtLeast(size),\n        height = height.pxOrElse { 0 }.coerceAtLeast(size)\n    )\n\n\n    class Factory : Decoder.Factory {\n\n        override fun create(\n            result: SourceFetchResult,\n            options: Options,\n            imageLoader: ImageLoader\n        ): Decoder? {\n            if (!isApplicable(result)) return null\n            return UpscaleSvgDecoder(\n                source = result.source,\n                options = options\n            )\n        }\n\n        private fun isApplicable(result: SourceFetchResult): Boolean {\n            return result.mimeType == \"image/svg+xml\" || DecodeUtils.isSvg(result.source.source())\n        }\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coroutines/AndroidDispatchersHolder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coroutines\n\nimport com.t8rin.imagetoolbox.core.di.DecodingDispatcher\nimport com.t8rin.imagetoolbox.core.di.DefaultDispatcher\nimport com.t8rin.imagetoolbox.core.di.EncodingDispatcher\nimport com.t8rin.imagetoolbox.core.di.IoDispatcher\nimport com.t8rin.imagetoolbox.core.di.UiDispatcher\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport javax.inject.Inject\nimport kotlin.coroutines.CoroutineContext\n\ninternal data class AndroidDispatchersHolder @Inject constructor(\n    @UiDispatcher override val uiDispatcher: CoroutineContext,\n    @IoDispatcher override val ioDispatcher: CoroutineContext,\n    @EncodingDispatcher override val encodingDispatcher: CoroutineContext,\n    @DecodingDispatcher override val decodingDispatcher: CoroutineContext,\n    @DefaultDispatcher override val defaultDispatcher: CoroutineContext\n) : DispatchersHolder"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/coroutines/AppScopeImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.coroutines\n\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.CoroutineExceptionHandler\nimport kotlinx.coroutines.SupervisorJob\nimport javax.inject.Inject\nimport kotlin.coroutines.CoroutineContext\n\n\ninternal class AppScopeImpl @Inject constructor(\n    dispatchersHolder: DispatchersHolder\n) : AppScope, DispatchersHolder by dispatchersHolder {\n    override val coroutineContext: CoroutineContext =\n        defaultDispatcher + CoroutineExceptionHandler { _, e -> e.makeLog(\"AppScopeImpl\") } + SupervisorJob()\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/CoroutinesModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport com.t8rin.imagetoolbox.core.data.coroutines.AndroidDispatchersHolder\nimport com.t8rin.imagetoolbox.core.data.coroutines.AppScopeImpl\nimport com.t8rin.imagetoolbox.core.data.utils.executorDispatcher\nimport com.t8rin.imagetoolbox.core.di.DecodingDispatcher\nimport com.t8rin.imagetoolbox.core.di.DefaultDispatcher\nimport com.t8rin.imagetoolbox.core.di.EncodingDispatcher\nimport com.t8rin.imagetoolbox.core.di.IoDispatcher\nimport com.t8rin.imagetoolbox.core.di.UiDispatcher\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport dagger.Binds\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport kotlinx.coroutines.Dispatchers\nimport java.util.concurrent.Executors\nimport javax.inject.Singleton\nimport kotlin.coroutines.CoroutineContext\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface CoroutinesModule {\n\n    @Binds\n    @Singleton\n    fun dispatchersHolder(\n        dispatchers: AndroidDispatchersHolder\n    ): DispatchersHolder\n\n    @Binds\n    @Singleton\n    fun appScope(\n        impl: AppScopeImpl\n    ): AppScope\n\n    companion object {\n\n        @DefaultDispatcher\n        @Singleton\n        @Provides\n        fun defaultDispatcher(): CoroutineContext = executorDispatcher {\n            Executors.newCachedThreadPool()\n        }\n\n        @DecodingDispatcher\n        @Singleton\n        @Provides\n        fun decodingDispatcher(): CoroutineContext = executorDispatcher {\n            Executors.newFixedThreadPool(\n                2 * Runtime.getRuntime().availableProcessors() + 1\n            )\n        }\n\n        @EncodingDispatcher\n        @Singleton\n        @Provides\n        fun encodingDispatcher(): CoroutineContext = executorDispatcher {\n            Executors.newSingleThreadExecutor()\n        }\n\n        @IoDispatcher\n        @Singleton\n        @Provides\n        fun ioDispatcher(): CoroutineContext = Dispatchers.IO\n\n        @UiDispatcher\n        @Singleton\n        @Provides\n        fun uiDispatcher(): CoroutineContext = Dispatchers.Main.immediate\n\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/ImageLoaderModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport android.content.Context\nimport android.os.Build\nimport coil3.ComponentRegistry\nimport coil3.ImageLoader\nimport coil3.SingletonImageLoader\nimport coil3.disk.DiskCache\nimport coil3.disk.directory\nimport coil3.gif.AnimatedImageDecoder\nimport coil3.gif.GifDecoder\nimport coil3.imageLoader\nimport coil3.memory.MemoryCache\nimport coil3.network.DeDupeConcurrentRequestStrategy\nimport coil3.network.ktor3.KtorNetworkFetcherFactory\nimport coil3.request.allowHardware\nimport coil3.request.maxBitmapSize\nimport coil3.size.Size\nimport coil3.svg.SvgDecoder\nimport coil3.util.Logger\nimport com.awxkee.jxlcoder.coil.AnimatedJxlDecoder\nimport com.gemalto.jp2.coil.Jpeg2000Decoder\nimport com.github.awxkee.avifcoil.decoder.HeifDecoder\nimport com.t8rin.awebp.coil.AnimatedWebPDecoder\nimport com.t8rin.djvu_coder.coil.DjvuDecoder\nimport com.t8rin.imagetoolbox.core.data.coil.Base64Fetcher\nimport com.t8rin.imagetoolbox.core.data.coil.CoilLogger\nimport com.t8rin.imagetoolbox.core.data.coil.PdfDecoder\nimport com.t8rin.imagetoolbox.core.data.coil.TiffDecoder\nimport com.t8rin.imagetoolbox.core.data.coil.TimeMeasureInterceptor\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\nimport com.t8rin.psd.coil.PsdDecoder\nimport com.t8rin.qoi_coder.coil.QoiDecoder\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport dagger.hilt.components.SingletonComponent\nimport io.ktor.client.HttpClient\nimport oupson.apng.coil.AnimatedPngDecoder\nimport java.io.File\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal object ImageLoaderModule {\n\n    @Provides\n    @Singleton\n    fun provideImageLoader(\n        @ApplicationContext context: Context,\n        logger: Logger?,\n        componentRegistry: ComponentRegistry,\n        dispatchersHolder: DispatchersHolder\n    ): ImageLoader = context.imageLoader.newBuilder()\n        .components(componentRegistry)\n        .coroutineContext(dispatchersHolder.defaultDispatcher)\n        .decoderCoroutineContext(dispatchersHolder.decodingDispatcher)\n        .fetcherCoroutineContext(dispatchersHolder.ioDispatcher)\n        .allowHardware(false)\n        .maxBitmapSize(Size.ORIGINAL)\n        .diskCache {\n            DiskCache.Builder()\n                .directory(File(context.cacheDir, \"coil\").apply(File::mkdirs))\n                .maxSizePercent(0.2)\n                .cleanupCoroutineContext(dispatchersHolder.ioDispatcher)\n                .build()\n        }\n        .memoryCache {\n            MemoryCache.Builder()\n                .maxSizePercent(context, 0.3)\n                .build()\n        }\n        .logger(logger)\n        .build()\n        .also(SingletonImageLoader::setUnsafe)\n\n    @Provides\n    @Singleton\n    fun provideCoilLogger(): Logger = CoilLogger()\n\n    @Provides\n    @Singleton\n    fun provideComponentRegistry(\n        client: HttpClient\n    ): ComponentRegistry = ComponentRegistry.Builder()\n        .apply {\n            add(\n                KtorNetworkFetcherFactory(\n                    httpClient = client,\n                    concurrentRequestStrategy = DeDupeConcurrentRequestStrategy()\n                )\n            )\n            add(AnimatedPngDecoder.Factory())\n            if (Build.VERSION.SDK_INT >= 28) add(AnimatedImageDecoder.Factory())\n            else {\n                add(GifDecoder.Factory())\n                add(AnimatedWebPDecoder.Factory())\n            }\n            add(SvgDecoder.Factory())\n            if (Build.VERSION.SDK_INT >= 24) {\n                add(HeifDecoder.Factory())\n            }\n            add(AnimatedJxlDecoder.Factory())\n            add(Jpeg2000Decoder.Factory())\n            add(TiffDecoder.Factory())\n            add(QoiDecoder.Factory())\n            add(PsdDecoder.Factory())\n            add(DjvuDecoder.Factory())\n            add(Base64Fetcher.Factory())\n            add(PdfDecoder.Factory())\n            if (BuildConfig.DEBUG) add(TimeMeasureInterceptor)\n        }\n        .build()\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/ImageModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.AndroidImageCompressor\nimport com.t8rin.imagetoolbox.core.data.image.AndroidImageGetter\nimport com.t8rin.imagetoolbox.core.data.image.AndroidImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.data.image.AndroidImageScaler\nimport com.t8rin.imagetoolbox.core.data.image.AndroidImageTransformer\nimport com.t8rin.imagetoolbox.core.data.image.AndroidShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ImageModule {\n\n    @Singleton\n    @Binds\n    fun provideImageManager(\n        transformer: AndroidImageTransformer\n    ): ImageTransformer<Bitmap>\n\n    @Singleton\n    @Binds\n    fun provideImageScaler(\n        scaler: AndroidImageScaler\n    ): ImageScaler<Bitmap>\n\n    @Singleton\n    @Binds\n    fun provideImageCompressor(\n        compressor: AndroidImageCompressor\n    ): ImageCompressor<Bitmap>\n\n    @Singleton\n    @Binds\n    fun provideImageGetter(\n        getter: AndroidImageGetter\n    ): ImageGetter<Bitmap>\n\n    @Singleton\n    @Binds\n    fun provideImagePreviewCreator(\n        creator: AndroidImagePreviewCreator\n    ): ImagePreviewCreator<Bitmap>\n\n    @Singleton\n    @Binds\n    fun provideShareProvider(\n        provider: AndroidShareProvider\n    ): ShareProvider\n\n    @Singleton\n    @Binds\n    fun provideImageShareProvider(\n        provider: AndroidShareProvider\n    ): ImageShareProvider<Bitmap>\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/JsonModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport com.squareup.moshi.Moshi\nimport com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory\nimport com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory\nimport com.t8rin.imagetoolbox.core.data.json.MoshiParser\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.json.JsonParser\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport dagger.Binds\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface JsonModule {\n\n    @Binds\n    @Singleton\n    fun parser(\n        impl: MoshiParser,\n    ): JsonParser\n\n    companion object {\n\n        @Provides\n        @Singleton\n        fun moshi(): Moshi = Moshi.Builder()\n            .add(\n                PolymorphicJsonAdapterFactory.of(Quality::class.java, \"quality_type\")\n                    .withSubtype(Quality.Jxl::class.java, \"jxl\")\n                    .withSubtype(Quality.Avif::class.java, \"avif\")\n                    .withSubtype(Quality.PngLossy::class.java, \"png\")\n                    .withSubtype(Quality.Tiff::class.java, \"tiff\")\n                    .withSubtype(Quality.Base::class.java, \"base\")\n                    .withDefaultValue(Quality.Base())\n            )\n            .add(\n                PolymorphicJsonAdapterFactory.of(ShapeType::class.java, \"shape_type\")\n                    .withSubtype(ShapeType.Rounded::class.java, \"rounded\")\n                    .withSubtype(ShapeType.Cut::class.java, \"cut\")\n                    .withSubtype(ShapeType.Squircle::class.java, \"squircle\")\n                    .withSubtype(ShapeType.Smooth::class.java, \"smooth\")\n                    .withDefaultValue(ShapeType.Rounded())\n            )\n            .add(\n                PolymorphicJsonAdapterFactory.of(FilenameBehavior::class.java, \"filename_type\")\n                    .withSubtype(FilenameBehavior.None::class.java, \"none\")\n                    .withSubtype(FilenameBehavior.Overwrite::class.java, \"overwrite\")\n                    .withSubtype(FilenameBehavior.Checksum::class.java, \"checksum\")\n                    .withSubtype(FilenameBehavior.Random::class.java, \"random\")\n                    .withDefaultValue(FilenameBehavior.None())\n            )\n            .addLast(KotlinJsonAdapterFactory())\n            .build()\n\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/LocalModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport android.content.Context\nimport androidx.datastore.core.DataStore\nimport androidx.datastore.preferences.core.PreferenceDataStoreFactory\nimport androidx.datastore.preferences.core.Preferences\nimport androidx.datastore.preferences.preferencesDataStoreFile\nimport com.t8rin.imagetoolbox.core.domain.GLOBAL_STORAGE_NAME\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal object LocalModule {\n\n    @Provides\n    @Singleton\n    fun dataStore(\n        @ApplicationContext context: Context\n    ): DataStore<Preferences> = PreferenceDataStoreFactory.create(\n        produceFile = { context.preferencesDataStoreFile(GLOBAL_STORAGE_NAME) }\n    )\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/RemoteModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport com.t8rin.imagetoolbox.core.data.remote.AndroidDownloadManager\nimport com.t8rin.imagetoolbox.core.data.remote.AndroidRemoteResourcesStore\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadManager\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResourcesStore\nimport com.t8rin.logger.makeLog\nimport dagger.Binds\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport io.ktor.client.HttpClient\nimport io.ktor.client.plugins.HttpTimeout\nimport io.ktor.client.plugins.logging.LogLevel\nimport io.ktor.client.plugins.logging.Logger\nimport io.ktor.client.plugins.logging.Logging\nimport javax.inject.Singleton\nimport kotlin.time.Duration.Companion.minutes\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface RemoteModule {\n\n    @Binds\n    @Singleton\n    fun remoteResources(\n        impl: AndroidRemoteResourcesStore\n    ): RemoteResourcesStore\n\n    @Binds\n    @Singleton\n    fun downloadManager(\n        impl: AndroidDownloadManager\n    ): DownloadManager\n\n    companion object {\n        @Provides\n        @Singleton\n        fun client(): HttpClient = HttpClient {\n            install(HttpTimeout) {\n                val timeout = 5.minutes.inWholeMilliseconds\n                requestTimeoutMillis = timeout\n                connectTimeoutMillis = timeout\n                socketTimeoutMillis = timeout\n            }\n\n            install(Logging) {\n                logger = object : Logger {\n                    override fun log(message: String) {\n                        message.makeLog(\"Ktor\")\n                    }\n                }\n                level = LogLevel.HEADERS\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/ResourcesModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport com.t8rin.imagetoolbox.core.data.resource.AndroidResourceManager\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ResourcesModule {\n\n    @Binds\n    @Singleton\n    fun resManager(\n        impl: AndroidResourceManager\n    ): ResourceManager\n\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/di/SavingModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.di\n\nimport com.t8rin.imagetoolbox.core.data.saving.AndroidFileController\nimport com.t8rin.imagetoolbox.core.data.saving.AndroidFilenameCreator\nimport com.t8rin.imagetoolbox.core.data.saving.AndroidKeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.image.MetadataProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController.Companion.toMetadataProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport dagger.Binds\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface SavingModule {\n\n    @Singleton\n    @Binds\n    fun provideFileController(\n        impl: AndroidFileController\n    ): FileController\n\n    @Singleton\n    @Binds\n    fun filenameCreator(\n        impl: AndroidFilenameCreator\n    ): FilenameCreator\n\n    @Singleton\n    @Binds\n    fun service(\n        impl: AndroidKeepAliveService\n    ): KeepAliveService\n\n    companion object {\n        @Singleton\n        @Provides\n        fun provideMetadata(\n            impl: AndroidFileController\n        ): MetadataProvider = impl.toMetadataProvider()\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/AndroidImageCompressor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n\n\npackage com.t8rin.imagetoolbox.core.data.image\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.data.utils.toSoftware\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.alphaContainedEntries\nimport com.t8rin.imagetoolbox.core.domain.model.sizeTo\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.utils.fileSize\nimport com.t8rin.trickle.Trickle\nimport dagger.Lazy\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport kotlinx.coroutines.yield\nimport javax.inject.Inject\n\ninternal class AndroidImageCompressor @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: Lazy<ShareProvider>,\n    settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, ImageCompressor<Bitmap> {\n\n    private val _settingsState = settingsProvider.settingsState\n    private val settingsState get() = _settingsState.value\n\n    override suspend fun compress(\n        image: Bitmap,\n        imageFormat: ImageFormat,\n        quality: Quality\n    ): ByteArray = withContext(encodingDispatcher) {\n        val transformedImage = image.toSoftware().let { software ->\n            val enableForAlpha = settingsState.enableBackgroundColorForAlphaFormats\n            val isNonAlpha = imageFormat !in ImageFormat.alphaContainedEntries\n\n            if (isNonAlpha || quality.isNonAlpha() || enableForAlpha) {\n                withContext(defaultDispatcher) {\n                    if (isNonAlpha && settingsState.backgroundForNoAlphaImageFormats.colorInt == Color.Black.toArgb()) {\n                        software\n                    } else {\n                        Trickle.drawColorBehind(\n                            color = settingsState.backgroundForNoAlphaImageFormats.colorInt,\n                            input = software\n                        )\n                    }\n                }\n            } else software\n        }\n\n        ImageCompressorBackend.Factory()\n            .create(\n                imageFormat = imageFormat,\n                context = context,\n                imageScaler = imageScaler\n            )\n            .compress(\n                image = transformedImage,\n                quality = quality.coerceIn(imageFormat)\n            )\n    }\n\n\n    override suspend fun compressAndTransform(\n        image: Bitmap,\n        imageInfo: ImageInfo,\n        onImageReadyToCompressInterceptor: suspend (Bitmap) -> Bitmap,\n        applyImageTransformations: Boolean\n    ): ByteArray = withContext(encodingDispatcher) {\n        val currentImage: Bitmap\n        if (applyImageTransformations) {\n            val size = imageInfo.originalUri?.let {\n                imageGetter.getImage(\n                    data = it,\n                    originalSize = true\n                )?.run { width sizeTo height }\n            }\n            currentImage = imageScaler\n                .scaleImage(\n                    image = imageTransformer.rotate(\n                        image = image.apply { setHasAlpha(true) },\n                        degrees = imageInfo.rotationDegrees\n                    ),\n                    width = imageInfo.width,\n                    height = imageInfo.height,\n                    resizeType = imageInfo.resizeType.withOriginalSizeIfCrop(size),\n                    imageScaleMode = imageInfo.imageScaleMode\n                )\n                .let {\n                    imageTransformer.flip(\n                        image = it,\n                        isFlipped = imageInfo.isFlipped\n                    )\n                }\n                .let {\n                    onImageReadyToCompressInterceptor(it)\n                }\n        } else currentImage = onImageReadyToCompressInterceptor(image)\n\n        val extension = imageInfo.originalUri?.let { imageGetter.getExtension(it) }\n\n        val imageFormat =\n            if (settingsState.filenameBehavior is FilenameBehavior.Overwrite && extension != null) {\n                val target = ImageFormat[extension]\n\n                if (imageInfo.imageFormat.extension == target.extension) {\n                    imageInfo.imageFormat\n                } else {\n                    target\n                }\n            } else imageInfo.imageFormat\n\n        yield()\n        compress(\n            image = currentImage,\n            imageFormat = imageFormat,\n            quality = imageInfo.quality\n        )\n    }\n\n    override suspend fun calculateImageSize(\n        image: Bitmap,\n        imageInfo: ImageInfo\n    ): Long = withContext(encodingDispatcher) {\n        val newInfo = imageInfo.let {\n            if (it.width == 0 || it.height == 0) {\n                it.copy(\n                    width = image.width,\n                    height = image.height\n                )\n            } else it\n        }\n        compressAndTransform(\n            image = image,\n            imageInfo = newInfo\n        ).let {\n            shareProvider.get().cacheByteArray(\n                byteArray = it,\n                filename = \"temp.${newInfo.imageFormat.extension}\"\n            )?.toUri()\n                ?.fileSize() ?: it.size.toLong()\n        }\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/AndroidImageGetter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.core.net.toUri\nimport coil3.ImageLoader\nimport coil3.request.ImageRequest\nimport coil3.request.transformations\nimport coil3.size.Precision\nimport coil3.size.Size\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.static\nimport com.t8rin.imagetoolbox.core.data.utils.toCoil\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.MetadataProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageData\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.core.utils.extension\nimport com.t8rin.logger.makeLog\nimport dagger.Lazy\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidImageGetter @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageLoader: ImageLoader,\n    private val appScope: AppScope,\n    metadataProvider: Lazy<MetadataProvider>,\n    settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder,\n) : DispatchersHolder by dispatchersHolder, ImageGetter<Bitmap> {\n\n    private val _settingsState = settingsProvider.settingsState\n\n    private val settingsState get() = _settingsState.value\n\n    private val metadataProvider by lazy {\n        metadataProvider.get()\n    }\n\n    override suspend fun getImage(\n        uri: String,\n        originalSize: Boolean,\n        onFailure: (Throwable) -> Unit\n    ): ImageData<Bitmap>? = withContext(defaultDispatcher) {\n        getImageImpl(\n            data = uri,\n            size = null,\n            addSizeToRequest = originalSize,\n            onFailure = onFailure\n        )?.let { bitmap ->\n            ImageData(\n                image = bitmap,\n                imageInfo = ImageInfo(\n                    width = bitmap.width,\n                    height = bitmap.height,\n                    imageFormat = settingsState.defaultImageFormat\n                        ?: ImageFormat[getExtension(uri)],\n                    originalUri = uri,\n                    resizeType = settingsState.defaultResizeType\n                ),\n                metadata = metadataProvider.readMetadata(uri)\n            )\n        }\n    }\n\n    override suspend fun getImage(\n        data: Any,\n        originalSize: Boolean\n    ): Bitmap? = getImageImpl(\n        data = data,\n        size = null,\n        addSizeToRequest = originalSize\n    )\n\n    override suspend fun getImage(\n        data: Any,\n        size: IntegerSize?\n    ): Bitmap? = getImageImpl(\n        data = data,\n        size = size\n    )\n\n    override suspend fun getImage(\n        data: Any,\n        size: Int?\n    ): Bitmap? = getImageImpl(\n        data = data,\n        size = size?.let {\n            IntegerSize(\n                width = it,\n                height = it\n            )\n        },\n        precision = Precision.INEXACT\n    )\n\n    override suspend fun getImageData(\n        uri: String,\n        size: Int?,\n        onFailure: (Throwable) -> Unit\n    ): ImageData<Bitmap>? = withContext(defaultDispatcher) {\n        getImageImpl(\n            data = uri,\n            size = size?.let {\n                IntegerSize(\n                    width = it,\n                    height = it\n                )\n            },\n            precision = Precision.INEXACT,\n            onFailure = onFailure\n        )?.let { bitmap ->\n            ImageData(\n                image = bitmap,\n                imageInfo = ImageInfo(\n                    width = bitmap.width,\n                    height = bitmap.height,\n                    imageFormat = settingsState.defaultImageFormat\n                        ?: ImageFormat[getExtension(uri)],\n                    originalUri = uri,\n                    resizeType = settingsState.defaultResizeType\n                ),\n                metadata = metadataProvider.readMetadata(uri)\n            )\n        }\n    }\n\n    override suspend fun getImageWithTransformations(\n        uri: String,\n        transformations: List<Transformation<Bitmap>>,\n        originalSize: Boolean\n    ): ImageData<Bitmap>? = withContext(defaultDispatcher) {\n        getImageImpl(\n            data = uri,\n            transformations = transformations,\n            size = null,\n            addSizeToRequest = originalSize\n        )?.let { bitmap ->\n            ImageData(\n                image = bitmap,\n                imageInfo = ImageInfo(\n                    width = bitmap.width,\n                    height = bitmap.height,\n                    imageFormat = ImageFormat[getExtension(uri)],\n                    originalUri = uri,\n                    resizeType = settingsState.defaultResizeType\n                ),\n                metadata = metadataProvider.readMetadata(uri)\n            )\n        }\n    }\n\n    override suspend fun getImageWithTransformations(\n        data: Any,\n        transformations: List<Transformation<Bitmap>>,\n        size: IntegerSize?\n    ): Bitmap? = getImageImpl(\n        data = data,\n        transformations = transformations,\n        size = size\n    )\n\n    override fun getImageAsync(\n        uri: String,\n        originalSize: Boolean,\n        onGetImage: (ImageData<Bitmap>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        appScope.launch {\n            var failureDelivered = false\n\n            val imageData = getImage(\n                uri = uri,\n                originalSize = originalSize,\n                onFailure = {\n                    failureDelivered = true\n                    onFailure(it)\n                }\n            )\n\n            if (imageData != null) {\n                onGetImage(imageData)\n            } else if (!failureDelivered) {\n                onFailure(\n                    IllegalStateException(context.getString(R.string.failed_to_open))\n                )\n            }\n        }\n    }\n\n    override fun getExtension(uri: String): String? = uri.toUri().extension(context)\n\n    private suspend fun getImageImpl(\n        data: Any,\n        size: IntegerSize?,\n        precision: Precision = Precision.EXACT,\n        transformations: List<Transformation<Bitmap>> = emptyList(),\n        onFailure: (Throwable) -> Unit = {},\n        addSizeToRequest: Boolean = true\n    ): Bitmap? = withContext(defaultDispatcher) {\n        if ((size == null || !addSizeToRequest) && data is Bitmap) return@withContext data\n\n        val request = ImageRequest\n            .Builder(context)\n            .data(data)\n            .static()\n            .precision(precision)\n            .transformations(\n                transformations.map(Transformation<Bitmap>::toCoil)\n            )\n            .apply {\n                if (addSizeToRequest) {\n                    size(\n                        size?.let {\n                            Size(size.width, size.height)\n                        } ?: Size.ORIGINAL\n                    )\n                }\n            }\n            .build()\n\n        runSuspendCatching {\n            imageLoader.execute(request).image?.toBitmap()\n        }.onFailure {\n            it.makeLog(\"ImageGetter\")\n            onFailure(it)\n        }.getOrNull()\n    }\n\n}\n"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/AndroidImagePreviewCreator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image\n\nimport android.graphics.Bitmap\nimport android.os.Build\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport kotlinx.coroutines.yield\nimport javax.inject.Inject\nimport kotlin.math.roundToInt\n\ninternal class AndroidImagePreviewCreator @Inject constructor(\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, ImagePreviewCreator<Bitmap> {\n\n    private val _settingsState = settingsProvider.settingsState\n    private val settingsState get() = _settingsState.value\n\n    override suspend fun createPreview(\n        image: Bitmap,\n        imageInfo: ImageInfo,\n        transformations: List<Transformation<Bitmap>>,\n        onGetByteCount: (Int) -> Unit\n    ): Bitmap? = withContext(defaultDispatcher) {\n        launch(encodingDispatcher) {\n            onGetByteCount(0)\n            yield()\n            onGetByteCount(\n                imageCompressor.calculateImageSize(\n                    image = image,\n                    imageInfo = imageInfo\n                ).toInt()\n            )\n        }\n\n        if (!settingsState.generatePreviews) return@withContext null\n\n        if (imageInfo.height == 0 || imageInfo.width == 0) return@withContext image\n        val targetImage: Bitmap\n\n        yield()\n        val shouldTransform = transformations.isNotEmpty()\n                || (imageInfo.width != image.width)\n                || (imageInfo.height != image.height)\n                || !imageInfo.quality.isDefault()\n                || (imageInfo.rotationDegrees != 0f)\n                || imageInfo.isFlipped\n\n        if (shouldTransform) {\n            var width = imageInfo.width\n            var height = imageInfo.height\n\n            var scaleFactor = 1f\n            while (height * width * 4 > SMALL_SIZE) {\n                height = (height * 0.85f).roundToInt()\n                width = (width * 0.85f).roundToInt()\n                scaleFactor *= 0.85f\n            }\n            yield()\n            val bytes = imageCompressor.compressAndTransform(\n                image = image,\n                imageInfo = imageInfo.copy(\n                    width = width,\n                    height = height,\n                    resizeType = if (imageInfo.resizeType is ResizeType.CenterCrop) {\n                        (imageInfo.resizeType as ResizeType.CenterCrop).copy(scaleFactor = scaleFactor)\n                    } else imageInfo.resizeType\n                ),\n                onImageReadyToCompressInterceptor = {\n                    yield()\n                    imageTransformer.transform(\n                        image = it,\n                        transformations = transformations\n                    ) ?: it\n                }\n            )\n\n            targetImage = imageGetter.getImage(bytes) ?: image\n        } else {\n            targetImage = image\n        }\n        yield()\n        imageScaler.scaleUntilCanShow(targetImage)\n    }\n\n    override fun canShow(image: Bitmap?): Boolean = image?.run { size() <= BIG_SIZE } ?: false\n\n    private val Bitmap.configSize: Int\n        get() = when (config) {\n            Bitmap.Config.RGB_565 -> 2\n            else -> {\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n                    if (config == Bitmap.Config.RGBA_F16) 8 else 4\n                } else 4\n            }\n        }\n\n    private fun Bitmap.size(): Int = width * height * configSize\n\n}\n\nprivate const val SMALL_SIZE = 1500 * 1500 * 3\nprivate const val BIG_SIZE = 3096 * 3096 * 4"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/AndroidImageScaler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image\n\nimport android.graphics.Bitmap\nimport android.graphics.Color\nimport android.graphics.PorterDuff\nimport androidx.core.graphics.BitmapCompat\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.scale\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ResizeFunction\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.aspectRatio\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.data.utils.toSoftware\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeAnchor\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.image.model.ScaleColorSpace\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.createFilter\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.math.abs\nimport kotlin.math.max\nimport kotlin.math.roundToInt\nimport com.awxkee.aire.ScaleColorSpace as AireScaleColorSpace\n\ninternal class AndroidImageScaler @Inject constructor(\n    settingsProvider: SettingsProvider,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, ImageScaler<Bitmap> {\n\n    private val _settingsState = settingsProvider.settingsState\n    private val settingsState get() = _settingsState.value\n\n    override suspend fun scaleImage(\n        image: Bitmap,\n        width: Int,\n        height: Int,\n        resizeType: ResizeType,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap = withContext(defaultDispatcher) {\n\n        val widthInternal = width.takeIf { it > 0 } ?: image.width\n        val heightInternal = height.takeIf { it > 0 } ?: image.height\n\n        runSuspendCatching {\n            when (resizeType) {\n                ResizeType.Explicit -> {\n                    createScaledBitmap(\n                        image = image,\n                        width = widthInternal,\n                        height = heightInternal,\n                        imageScaleMode = imageScaleMode\n                    )\n                }\n\n                is ResizeType.Flexible -> {\n                    flexibleResize(\n                        image = image,\n                        width = widthInternal,\n                        height = heightInternal,\n                        resizeAnchor = resizeType.resizeAnchor,\n                        imageScaleMode = imageScaleMode\n                    )\n                }\n\n                is ResizeType.CenterCrop -> {\n                    resizeType.performCenterCrop(\n                        image = image,\n                        targetWidth = widthInternal,\n                        targetHeight = heightInternal,\n                        imageScaleMode = imageScaleMode\n                    )\n                }\n\n                is ResizeType.Fit -> {\n                    resizeType.performFitResize(\n                        image = image,\n                        targetWidth = widthInternal,\n                        targetHeight = heightInternal,\n                        imageScaleMode = imageScaleMode\n                    )\n                }\n            }\n        }.onFailure {\n            it.makeLog(\"AndroidImageScaler\")\n        }.getOrNull() ?: image\n    }\n\n    override suspend fun scaleUntilCanShow(\n        image: Bitmap?\n    ): Bitmap? = withContext(defaultDispatcher) {\n        if (image == null) return@withContext null\n        if (canShow(image.width * image.height * 4)) return@withContext image\n\n        var (height, width) = image.run { height to width }\n\n        var iterations = 0\n        while (!canShow(size = height * width * 4)) {\n            height = (height * 0.85f).roundToInt()\n            width = (width * 0.85f).roundToInt()\n            iterations++\n        }\n\n        if (iterations == 0) image\n        else scaleImage(\n            image = image,\n            height = height,\n            width = width,\n            imageScaleMode = ImageScaleMode.Bicubic()\n        )\n    }\n\n    private fun canShow(size: Int): Boolean {\n        return size < 3096 * 3096 * 3\n    }\n\n    private suspend fun Bitmap.fitResize(\n        targetWidth: Int,\n        targetHeight: Int,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap {\n        val aspectRatio = width.toFloat() / height.toFloat()\n        val targetAspectRatio = targetWidth.toFloat() / targetHeight.toFloat()\n\n        val finalWidth: Int\n        val finalHeight: Int\n\n        if (aspectRatio > targetAspectRatio) {\n            // Image is wider than the target aspect ratio\n            finalWidth = targetWidth\n            finalHeight = (targetWidth / aspectRatio).toInt()\n        } else {\n            // Image is taller than or equal to the target aspect ratio\n            finalWidth = (targetHeight * aspectRatio).toInt()\n            finalHeight = targetHeight\n        }\n\n        return createScaledBitmap(\n            image = this,\n            width = finalWidth,\n            height = finalHeight,\n            imageScaleMode = imageScaleMode\n        )\n    }\n\n    private suspend fun ResizeType.Fit.performFitResize(\n        image: Bitmap,\n        targetWidth: Int,\n        targetHeight: Int,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap = withContext(defaultDispatcher) {\n        if (targetWidth == image.width && targetHeight == image.height) {\n            return@withContext image\n        }\n\n        val originalWidth: Int\n        val originalHeight: Int\n\n        val aspect = image.aspectRatio\n        val originalAspect = image.aspectRatio\n\n        if (abs(aspect - originalAspect) > 0.001f) {\n            originalWidth = image.height\n            originalHeight = image.width\n        } else {\n            originalWidth = image.width\n            originalHeight = image.height\n        }\n\n        val drawImage = image.fitResize(\n            targetWidth = targetWidth,\n            targetHeight = targetHeight,\n            imageScaleMode = imageScaleMode\n        )\n\n        val blurredBitmap = imageTransformer.transform(\n            image = drawImage.let { bitmap ->\n                val xScale: Float = targetWidth.toFloat() / originalWidth\n                val yScale: Float = targetHeight.toFloat() / originalHeight\n                val scale = xScale.coerceAtLeast(yScale)\n                createScaledBitmap(\n                    image = bitmap,\n                    width = (scale * originalWidth).toInt(),\n                    height = (scale * originalHeight).toInt(),\n                    imageScaleMode = imageScaleMode\n                )\n            },\n            transformations = listOf(\n                filterProvider.filterToTransformation(\n                    createFilter<Float, Filter.NativeStackBlur>(\n                        blurRadius.toFloat() / 1000 * max(targetWidth, targetHeight)\n                    )\n                )\n            )\n        )\n\n        createBitmap(targetWidth, targetHeight, drawImage.safeConfig).apply { setHasAlpha(true) }\n            .applyCanvas {\n                drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)\n                canvasColor?.let {\n                    drawColor(it)\n                } ?: blurredBitmap?.let {\n                    drawBitmap(\n                        bitmap = blurredBitmap,\n                        position = Position.Center\n                    )\n                }\n                drawBitmap(\n                    bitmap = drawImage,\n                    position = position\n                )\n            }\n    }\n\n    private suspend fun ResizeType.CenterCrop.performCenterCrop(\n        image: Bitmap,\n        targetWidth: Int,\n        targetHeight: Int,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap = withContext(defaultDispatcher) {\n        val originalSize = if (!originalSize.isDefined()) {\n            IntegerSize(\n                width = image.width,\n                height = image.height\n            )\n        } else {\n            originalSize\n        } * scaleFactor\n\n        if (targetWidth == originalSize.width && targetHeight == originalSize.height) {\n            return@withContext image\n        }\n\n        val originalWidth: Int\n        val originalHeight: Int\n\n        val aspect = image.aspectRatio\n        val originalAspect = originalSize.aspectRatio\n\n        if (abs(aspect - originalAspect) > 0.001f) {\n            originalWidth = originalSize.height\n            originalHeight = originalSize.width\n        } else {\n            originalWidth = originalSize.width\n            originalHeight = originalSize.height\n        }\n\n        val drawImage = createScaledBitmap(\n            image = image,\n            width = originalWidth,\n            height = originalHeight,\n            imageScaleMode = imageScaleMode\n        )\n\n        val blurredBitmap = if (canvasColor == null) {\n            imageTransformer.transform(\n                image = drawImage.let { bitmap ->\n                    val xScale: Float = targetWidth.toFloat() / originalWidth\n                    val yScale: Float = targetHeight.toFloat() / originalHeight\n                    val scale = xScale.coerceAtLeast(yScale)\n                    createScaledBitmap(\n                        image = bitmap,\n                        width = (scale * originalWidth).toInt(),\n                        height = (scale * originalHeight).toInt(),\n                        imageScaleMode = imageScaleMode\n                    )\n                },\n                transformations = listOf(\n                    filterProvider.filterToTransformation(\n                        createFilter<Float, Filter.NativeStackBlur>(\n                            blurRadius.toFloat() / 1000 * max(targetWidth, targetHeight)\n                        )\n                    )\n                )\n            )\n        } else null\n\n        createBitmap(targetWidth, targetHeight, drawImage.safeConfig).apply { setHasAlpha(true) }\n            .applyCanvas {\n                drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)\n                canvasColor?.let {\n                    drawColor(it)\n                } ?: blurredBitmap?.let {\n                    drawBitmap(\n                        bitmap = blurredBitmap,\n                        position = Position.Center\n                    )\n                }\n                drawBitmap(\n                    bitmap = drawImage,\n                    position = position\n                )\n            }\n    }\n\n    private suspend fun createScaledBitmap(\n        image: Bitmap,\n        width: Int,\n        height: Int,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap = withContext(defaultDispatcher) {\n        if (width == image.width && height == image.height) return@withContext image\n\n        val softwareImage = image.toSoftware()\n\n        if (imageScaleMode is ImageScaleMode.Base) {\n            return@withContext if (width < softwareImage.width && height < softwareImage.width) {\n                BitmapCompat.createScaledBitmap(softwareImage, width, height, null, true)\n            } else {\n                softwareImage.scale(width, height)\n            }\n        }\n\n        val mode = imageScaleMode.takeIf {\n            it != ImageScaleMode.NotPresent && it.value >= 0\n        } ?: settingsState.defaultImageScaleMode\n\n        Aire.scale(\n            bitmap = softwareImage,\n            dstWidth = width,\n            dstHeight = height,\n            scaleMode = mode.toResizeFunction(),\n            colorSpace = mode.scaleColorSpace.toColorSpace()\n        )\n    }\n\n    private fun ImageScaleMode.toResizeFunction(): ResizeFunction = when (this) {\n        ImageScaleMode.NotPresent,\n        ImageScaleMode.Base -> ResizeFunction.Bilinear\n\n        is ImageScaleMode.Bilinear -> ResizeFunction.Bilinear\n        is ImageScaleMode.Nearest -> ResizeFunction.Nearest\n        is ImageScaleMode.Cubic -> ResizeFunction.Cubic\n        is ImageScaleMode.Mitchell -> ResizeFunction.MitchellNetravalli\n        is ImageScaleMode.Catmull -> ResizeFunction.CatmullRom\n        is ImageScaleMode.Hermite -> ResizeFunction.Hermite\n        is ImageScaleMode.BSpline -> ResizeFunction.BSpline\n        is ImageScaleMode.Hann -> ResizeFunction.Hann\n        is ImageScaleMode.Bicubic -> ResizeFunction.Bicubic\n        is ImageScaleMode.Hamming -> ResizeFunction.Hamming\n        is ImageScaleMode.Hanning -> ResizeFunction.Hanning\n        is ImageScaleMode.Blackman -> ResizeFunction.Blackman\n        is ImageScaleMode.Welch -> ResizeFunction.Welch\n        is ImageScaleMode.Quadric -> ResizeFunction.Quadric\n        is ImageScaleMode.Gaussian -> ResizeFunction.Gaussian\n        is ImageScaleMode.Sphinx -> ResizeFunction.Sphinx\n        is ImageScaleMode.Bartlett -> ResizeFunction.Bartlett\n        is ImageScaleMode.Robidoux -> ResizeFunction.Robidoux\n        is ImageScaleMode.RobidouxSharp -> ResizeFunction.RobidouxSharp\n        is ImageScaleMode.Spline16 -> ResizeFunction.Spline16\n        is ImageScaleMode.Spline36 -> ResizeFunction.Spline36\n        is ImageScaleMode.Spline64 -> ResizeFunction.Spline64\n        is ImageScaleMode.Kaiser -> ResizeFunction.Kaiser\n        is ImageScaleMode.BartlettHann -> ResizeFunction.BartlettHann\n        is ImageScaleMode.Box -> ResizeFunction.Box\n        is ImageScaleMode.Bohman -> ResizeFunction.Bohman\n        is ImageScaleMode.Lanczos2 -> ResizeFunction.Lanczos2\n        is ImageScaleMode.Lanczos3 -> ResizeFunction.Lanczos3\n        is ImageScaleMode.Lanczos4 -> ResizeFunction.Lanczos4\n        is ImageScaleMode.Lanczos2Jinc -> ResizeFunction.Lanczos2Jinc\n        is ImageScaleMode.Lanczos3Jinc -> ResizeFunction.Lanczos3Jinc\n        is ImageScaleMode.Lanczos4Jinc -> ResizeFunction.Lanczos4Jinc\n        is ImageScaleMode.EwaHanning -> ResizeFunction.EwaHanning\n        is ImageScaleMode.EwaRobidoux -> ResizeFunction.EwaRobidoux\n        is ImageScaleMode.EwaBlackman -> ResizeFunction.EwaBlackman\n        is ImageScaleMode.EwaQuadric -> ResizeFunction.EwaQuadric\n        is ImageScaleMode.EwaRobidouxSharp -> ResizeFunction.EwaRobidouxSharp\n        is ImageScaleMode.EwaLanczos3Jinc -> ResizeFunction.EwaLanczos3Jinc\n        is ImageScaleMode.Ginseng -> ResizeFunction.Ginseng\n        is ImageScaleMode.EwaGinseng -> ResizeFunction.EwaGinseng\n        is ImageScaleMode.EwaLanczosSharp -> ResizeFunction.EwaLanczosSharp\n        is ImageScaleMode.EwaLanczos4Sharpest -> ResizeFunction.EwaLanczos4Sharpest\n        is ImageScaleMode.EwaLanczosSoft -> ResizeFunction.EwaLanczosSoft\n        is ImageScaleMode.HaasnSoft -> ResizeFunction.HaasnSoft\n        is ImageScaleMode.Lagrange2 -> ResizeFunction.Lagrange2\n        is ImageScaleMode.Lagrange3 -> ResizeFunction.Lagrange3\n        is ImageScaleMode.Lanczos6 -> ResizeFunction.Lanczos6\n        is ImageScaleMode.Lanczos6Jinc -> ResizeFunction.Lanczos6Jinc\n        is ImageScaleMode.Area -> ResizeFunction.Area\n    }\n\n    private fun ScaleColorSpace.toColorSpace(): AireScaleColorSpace = when (this) {\n        ScaleColorSpace.LAB -> AireScaleColorSpace.LAB\n        ScaleColorSpace.Linear -> AireScaleColorSpace.LINEAR\n        ScaleColorSpace.SRGB -> AireScaleColorSpace.SRGB\n        ScaleColorSpace.LUV -> AireScaleColorSpace.LUV\n        ScaleColorSpace.Sigmoidal -> AireScaleColorSpace.SIGMOIDAL\n        ScaleColorSpace.XYZ -> AireScaleColorSpace.XYZ\n        ScaleColorSpace.F32Gamma22 -> AireScaleColorSpace.LINEAR_F32_GAMMA_2_2\n        ScaleColorSpace.F32Gamma28 -> AireScaleColorSpace.LINEAR_F32_GAMMA_2_8\n        ScaleColorSpace.F32Rec709 -> AireScaleColorSpace.LINEAR_F32_REC709\n        ScaleColorSpace.F32sRGB -> AireScaleColorSpace.LINEAR_F32_SRGB\n        ScaleColorSpace.LCH -> AireScaleColorSpace.LCH\n        ScaleColorSpace.OklabGamma22 -> AireScaleColorSpace.OKLAB_GAMMA_2_2\n        ScaleColorSpace.OklabGamma28 -> AireScaleColorSpace.OKLAB_GAMMA_2_8\n        ScaleColorSpace.OklabRec709 -> AireScaleColorSpace.OKLAB_REC709\n        ScaleColorSpace.OklabSRGB -> AireScaleColorSpace.OKLAB_SRGB\n        ScaleColorSpace.JzazbzGamma22 -> AireScaleColorSpace.JZAZBZ_GAMMA_2_2\n        ScaleColorSpace.JzazbzGamma28 -> AireScaleColorSpace.JZAZBZ_GAMMA_2_8\n        ScaleColorSpace.JzazbzRec709 -> AireScaleColorSpace.JZAZBZ_REC709\n        ScaleColorSpace.JzazbzSRGB -> AireScaleColorSpace.JZAZBZ_SRGB\n    }\n\n    private suspend fun flexibleResize(\n        image: Bitmap,\n        width: Int,\n        height: Int,\n        resizeAnchor: ResizeAnchor,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap = withContext(defaultDispatcher) {\n        val max = max(width, height)\n\n        val scaleByWidth = suspend {\n            val aspectRatio = image.aspectRatio\n            createScaledBitmap(\n                image = image,\n                width = width,\n                height = (width / aspectRatio).toInt(),\n                imageScaleMode = imageScaleMode\n            )\n        }\n\n        val scaleByHeight = suspend {\n            val aspectRatio = image.aspectRatio\n            createScaledBitmap(\n                image = image,\n                width = (height * aspectRatio).toInt(),\n                height = height,\n                imageScaleMode = imageScaleMode\n            )\n        }\n\n        when (resizeAnchor) {\n            ResizeAnchor.Max -> {\n                if (width >= height) {\n                    scaleByWidth()\n                } else scaleByHeight()\n            }\n\n            ResizeAnchor.Min -> {\n                if (width >= height) {\n                    scaleByHeight()\n                } else scaleByWidth()\n            }\n\n            ResizeAnchor.Width -> scaleByWidth()\n\n            ResizeAnchor.Height -> scaleByHeight()\n\n            ResizeAnchor.Default -> {\n                runSuspendCatching {\n                    if (image.height >= image.width) {\n                        val aspectRatio = image.aspectRatio\n                        val targetWidth = (max * aspectRatio).toInt()\n                        createScaledBitmap(image, targetWidth, max, imageScaleMode)\n                    } else {\n                        val aspectRatio = 1f / image.aspectRatio\n                        val targetHeight = (max * aspectRatio).toInt()\n                        createScaledBitmap(image, max, targetHeight, imageScaleMode)\n                    }\n                }.getOrNull() ?: image\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/AndroidImageTransformer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.Matrix\nimport coil3.ImageLoader\nimport coil3.request.ImageRequest\nimport coil3.request.transformations\nimport coil3.size.Size\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.toCoil\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.sizeTo\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.math.abs\nimport kotlin.math.roundToInt\n\n\ninternal class AndroidImageTransformer @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageLoader: ImageLoader,\n    defaultDispatchersHolder: DispatchersHolder\n) : DispatchersHolder by defaultDispatchersHolder, ImageTransformer<Bitmap> {\n\n    override suspend fun transform(\n        image: Bitmap,\n        transformations: List<Transformation<Bitmap>>,\n        originalSize: Boolean\n    ): Bitmap? = withContext(defaultDispatcher) {\n        if (transformations.isEmpty()) return@withContext image\n\n        val request = ImageRequest\n            .Builder(context)\n            .data(image)\n            .transformations(\n                transformations.map {\n                    it.toCoil()\n                }\n            )\n            .apply {\n                if (originalSize) size(Size.ORIGINAL)\n            }\n            .build()\n\n        return@withContext imageLoader.execute(request).image?.toBitmap()\n    }\n\n    override suspend fun transform(\n        image: Bitmap,\n        transformations: List<Transformation<Bitmap>>,\n        size: IntegerSize\n    ): Bitmap? = withContext(defaultDispatcher) {\n        if (transformations.isEmpty()) return@withContext image\n\n        val request = ImageRequest\n            .Builder(context)\n            .data(image)\n            .transformations(\n                transformations.map {\n                    it.toCoil()\n                }\n            )\n            .size(size.width, size.height)\n            .build()\n\n        return@withContext imageLoader.execute(request).image?.toBitmap()\n    }\n\n    override suspend fun applyPresetBy(\n        image: Bitmap?,\n        preset: Preset,\n        currentInfo: ImageInfo\n    ): ImageInfo = withContext(defaultDispatcher) {\n        if (image == null || preset is Preset.None) return@withContext currentInfo\n\n        val size = currentInfo.originalUri.makeLog(\"applyPresetBy originalUri\")?.let { uri ->\n            imageLoader.execute(\n                ImageRequest.Builder(context)\n                    .data(uri)\n                    .size(Size.ORIGINAL)\n                    .build()\n            ).image?.run { width sizeTo height }.makeLog(\"applyPresetBy using orig size\")\n        } ?: IntegerSize(image.width, image.height).makeLog(\"applyPresetBy using image size\")\n\n        val rotated = abs(currentInfo.rotationDegrees) % 180 != 0f\n        fun calcWidth() = if (rotated) size.height else size.width\n        fun calcHeight() = if (rotated) size.width else size.height\n        fun Int.calc(cnt: Int): Int = (this * (cnt / 100f)).toInt()\n\n        when (preset) {\n            is Preset.Telegram -> {\n                currentInfo.copy(\n                    width = 512,\n                    height = 512,\n                    imageFormat = ImageFormat.Png.Lossless,\n                    resizeType = ResizeType.Flexible,\n                    quality = Quality.Base(100)\n                )\n            }\n\n            is Preset.Percentage -> currentInfo.copy(\n                width = calcWidth().calc(preset.value),\n                height = calcHeight().calc(preset.value),\n            )\n\n            is Preset.AspectRatio -> {\n                val originalWidth = calcWidth().toFloat()\n                val originalHeight = calcHeight().toFloat()\n\n                val newWidth: Float\n                val newHeight: Float\n\n                val condition = if (preset.isFit) preset.ratio > originalWidth / originalHeight\n                else preset.ratio < originalWidth / originalHeight\n\n                if (condition) {\n                    newWidth = originalHeight * preset.ratio\n                    newHeight = originalHeight\n                } else {\n                    newWidth = originalWidth\n                    newHeight = originalWidth / preset.ratio\n                }\n\n                currentInfo.copy(\n                    width = newWidth.roundToInt(),\n                    height = newHeight.roundToInt()\n                )\n            }\n\n            Preset.None -> currentInfo\n        }\n    }\n\n    override suspend fun flip(\n        image: Bitmap,\n        isFlipped: Boolean\n    ): Bitmap = withContext(defaultDispatcher) {\n        if (isFlipped) {\n            val matrix = Matrix().apply { postScale(-1f, 1f, image.width / 2f, image.height / 2f) }\n            Bitmap.createBitmap(image, 0, 0, image.width, image.height, matrix, true)\n        } else image\n    }\n\n    override suspend fun rotate(\n        image: Bitmap,\n        degrees: Float\n    ): Bitmap = withContext(defaultDispatcher) {\n        if (degrees == 0f) return@withContext image\n\n        if (degrees % 90 == 0f) {\n            val matrix = Matrix().apply { postRotate(degrees) }\n            Bitmap.createBitmap(image, 0, 0, image.width, image.height, matrix, true)\n        } else {\n            val matrix = Matrix().apply {\n                setRotate(degrees, image.width.toFloat() / 2, image.height.toFloat() / 2)\n            }\n            Bitmap.createBitmap(image, 0, 0, image.width, image.height, matrix, true)\n        }\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/AndroidMetadata.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image\n\nimport com.t8rin.exif.ExifInterface\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.image.toMap\nimport java.io.FileDescriptor\n\nprivate data class ExifInterfaceMetadata(\n    private val exifInterface: ExifInterface\n) : Metadata {\n\n    override fun saveAttributes(): Metadata = apply {\n        exifInterface.saveAttributes()\n    }\n\n    override fun getAttribute(\n        tag: MetadataTag\n    ): String? = exifInterface.getAttribute(tag.key)\n\n    override fun setAttribute(\n        tag: MetadataTag,\n        value: String?\n    ): Metadata = apply {\n        exifInterface.setAttribute(tag.key, value)\n    }\n\n    override fun toString(): String = \"Android(${toMap()})\"\n\n}\n\ninternal fun ExifInterface.toMetadata(): Metadata = ExifInterfaceMetadata(this)\n\ninternal fun FileDescriptor.toMetadata(): Metadata = ExifInterface(this).toMetadata()\n"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/AndroidShareProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image\n\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport android.webkit.MimeTypeMap\nimport androidx.core.content.FileProvider\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.saving.io.FileWriteable\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriReadable\nimport com.t8rin.imagetoolbox.core.domain.PDF\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.model.toMimeType\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\nimport com.t8rin.imagetoolbox.core.domain.saving.io.use\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.logger.makeLog\nimport dagger.Lazy\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport javax.inject.Inject\nimport kotlin.random.Random\n\ninternal class AndroidShareProvider @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val filenameCreator: Lazy<FilenameCreator>,\n    resourceManager: ResourceManager,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder,\n    ResourceManager by resourceManager,\n    ShareProvider, ImageShareProvider<Bitmap> {\n\n    override suspend fun shareImages(\n        uris: List<String>,\n        imageLoader: suspend (String) -> Pair<Bitmap, ImageInfo>?,\n        onProgressChange: (Int) -> Unit\n    ) = withContext(ioDispatcher) {\n        val cachedUris = uris.mapIndexedNotNull { index, uri ->\n            imageLoader(uri)?.let { (image, imageInfo) ->\n                cacheImage(\n                    image = image,\n                    imageInfo = imageInfo\n                )?.also {\n                    onProgressChange(index + 1)\n                }\n            }\n        }\n        onProgressChange(-1)\n        shareUris(cachedUris)\n    }\n\n    override suspend fun cacheImage(\n        image: Bitmap,\n        imageInfo: ImageInfo,\n        filename: String?\n    ): String? = withContext(ioDispatcher) {\n        runSuspendCatching {\n            val saveTarget = ImageSaveTarget(\n                imageInfo = imageInfo,\n                originalUri = imageInfo.originalUri ?: \"share\",\n                sequenceNumber = null,\n                data = byteArrayOf()\n            )\n\n            val realFilename = filename ?: filenameCreator.get().constructImageFilename(saveTarget)\n            val byteArray = imageCompressor.compressAndTransform(image, imageInfo)\n\n            cacheByteArray(\n                byteArray = byteArray,\n                filename = realFilename\n            )\n        }.getOrNull()\n    }\n\n    override suspend fun shareImage(\n        imageInfo: ImageInfo,\n        image: Bitmap,\n        onComplete: () -> Unit\n    ) = withContext(ioDispatcher) {\n        cacheImage(\n            image = image,\n            imageInfo = imageInfo\n        )?.let {\n            shareUri(\n                uri = it,\n                type = imageInfo.imageFormat.mimeType,\n                onComplete = {}\n            )\n        }\n        onComplete()\n    }\n\n    override suspend fun shareUri(\n        uri: String,\n        type: MimeType.Single?,\n        onComplete: () -> Unit\n    ) {\n        withContext(defaultDispatcher) {\n            runSuspendCatching {\n                shareUriImpl(\n                    uri = uri,\n                    type = type\n                )\n                onComplete()\n            }.onFailure {\n                val newUri = cacheData(\n                    writeData = {\n                        UriReadable(\n                            uri = uri.toUri(),\n                            context = context\n                        ).copyTo(it)\n                    },\n                    filename = filenameCreator.get()\n                        .constructRandomFilename(\n                            extension = imageGetter.getExtension(uri) ?: \"\"\n                        )\n                )\n                shareUriImpl(\n                    uri = newUri ?: return@onFailure,\n                    type = type\n                )\n                onComplete()\n            }\n        }\n    }\n\n    private fun shareUriImpl(\n        uri: String,\n        type: MimeType.Single?\n    ) {\n        val mimeType = type ?: MimeTypeMap.getSingleton()\n            .getMimeTypeFromExtension(\n                imageGetter.getExtension(uri)\n            )?.toMimeType() ?: MimeType.All\n\n        val sendIntent = Intent(Intent.ACTION_SEND).apply {\n            putExtra(Intent.EXTRA_STREAM, uri.toUri())\n            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)\n            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n            this.type = mimeType.entry\n        }\n        val shareIntent = Intent.createChooser(sendIntent, getString(R.string.share))\n        shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        context.startActivity(shareIntent)\n    }\n\n    override suspend fun shareUris(\n        uris: List<String>\n    ) = shareImageUris(uris.map { it.toUri() })\n\n    private suspend fun shareImageUris(\n        uris: List<Uri>\n    ) = withContext(defaultDispatcher) {\n        if (uris.isEmpty()) return@withContext\n\n        val sendIntent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {\n            putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(uris))\n            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)\n            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n            val mimeType = MimeTypeMap.getSingleton()\n                .getMimeTypeFromExtension(\n                    imageGetter.getExtension(uris.first().toString())\n                ) ?: \"*/*\"\n\n            type = mimeType.makeLog(\"shareImageUris\")\n        }\n        val shareIntent = Intent.createChooser(sendIntent, getString(R.string.share))\n        shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        context.startActivity(shareIntent)\n    }\n\n    override suspend fun cacheByteArray(\n        byteArray: ByteArray,\n        filename: String\n    ): String? = withContext(ioDispatcher) {\n        cacheData(\n            writeData = { it.writeBytes(byteArray) },\n            filename = filename,\n        )\n    }\n\n    override suspend fun shareByteArray(\n        byteArray: ByteArray,\n        filename: String,\n        onComplete: () -> Unit\n    ) = withContext(ioDispatcher) {\n        shareData(\n            writeData = { it.writeBytes(byteArray) },\n            filename = filename,\n            onComplete = {}\n        )\n        onComplete()\n    }\n\n    override suspend fun cacheData(\n        filename: String,\n        writeData: suspend (Writeable) -> Unit\n    ): String? = withContext(ioDispatcher) {\n        runSuspendCatching {\n            cacheDataOrThrow(\n                filename = filename,\n                writeData = writeData\n            )\n        }.onFailure { it.makeLog(\"cacheData\") }.getOrNull()\n    }\n\n    override suspend fun cacheDataOrThrow(\n        filename: String,\n        writeData: suspend (Writeable) -> Unit\n    ): String = withContext(ioDispatcher) {\n        val imagesFolder = if (filename.startsWith(\"temp.\")) {\n            File(context.cacheDir, \"temp\")\n        } else if (filename.startsWith(PDF)) {\n            File(context.cacheDir, \"$PDF${Random.nextInt()}\")\n        } else {\n            File(context.cacheDir, \"cache/${Random.nextInt()}\")\n        }\n\n        imagesFolder.mkdirs()\n        val file = File(imagesFolder, filename.removePrefix(PDF))\n        FileWriteable(file).use {\n            writeData(it)\n        }\n\n        FileProvider.getUriForFile(\n            context,\n            getString(R.string.file_provider),\n            file\n        ).also { uri ->\n            runCatching {\n                context.grantUriPermission(\n                    context.packageName,\n                    uri,\n                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION\n                )\n            }\n        }.toString()\n    }\n\n    override suspend fun shareData(\n        writeData: suspend (Writeable) -> Unit,\n        filename: String,\n        onComplete: () -> Unit\n    ) = withContext(ioDispatcher) {\n        cacheData(\n            writeData = writeData,\n            filename = filename\n        )?.let {\n            val mimeType = MimeTypeMap.getSingleton()\n                .getMimeTypeFromExtension(\n                    imageGetter.getExtension(it)\n                )?.toMimeType() ?: MimeType.All\n\n            shareUri(\n                uri = it,\n                type = mimeType,\n                onComplete = {}\n            )\n        }\n\n        onComplete()\n    }\n\n    override fun shareText(\n        value: String,\n        onComplete: () -> Unit\n    ) {\n        val sendIntent = Intent().apply {\n            action = Intent.ACTION_SEND\n            type = \"text/plain\"\n            putExtra(Intent.EXTRA_TEXT, value)\n        }\n        val shareIntent = Intent.createChooser(sendIntent, getString(R.string.share))\n        shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        context.startActivity(shareIntent)\n\n        onComplete()\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/BlendingModeExt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils\n\nimport android.graphics.Paint\nimport android.graphics.PorterDuffXfermode\nimport android.os.Build\nimport androidx.annotation.RequiresApi\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport android.graphics.BlendMode as AndroidBlendMode\nimport android.graphics.PorterDuff.Mode as PorterDuffMode\n\n\nfun BlendingMode.toPorterDuffMode(): PorterDuffMode = when (this) {\n    BlendingMode.Clear -> PorterDuffMode.CLEAR\n    BlendingMode.Src -> PorterDuffMode.SRC\n    BlendingMode.Dst -> PorterDuffMode.DST\n    BlendingMode.SrcOver -> PorterDuffMode.SRC_OVER\n    BlendingMode.DstOver -> PorterDuffMode.DST_OVER\n    BlendingMode.SrcIn -> PorterDuffMode.SRC_IN\n    BlendingMode.DstIn -> PorterDuffMode.DST_IN\n    BlendingMode.SrcOut -> PorterDuffMode.SRC_OUT\n    BlendingMode.DstOut -> PorterDuffMode.DST_OUT\n    BlendingMode.SrcAtop -> PorterDuffMode.SRC_ATOP\n    BlendingMode.DstAtop -> PorterDuffMode.DST_ATOP\n    BlendingMode.Xor -> PorterDuffMode.XOR\n    BlendingMode.Plus -> PorterDuffMode.ADD\n    BlendingMode.Screen -> PorterDuffMode.SCREEN\n    BlendingMode.Overlay -> PorterDuffMode.OVERLAY\n    BlendingMode.Darken -> PorterDuffMode.DARKEN\n    BlendingMode.Lighten -> PorterDuffMode.LIGHTEN\n    BlendingMode.Modulate -> {\n        // b/73224934 Android PorterDuff Multiply maps to Skia Modulate\n        PorterDuffMode.MULTIPLY\n    }\n    // Always return SRC_OVER as the default if there is no valid alternative\n    else -> PorterDuffMode.SRC_OVER\n}\n\n/**\n * Convert the domain [BlendingMode] to the underlying Android platform [AndroidBlendMode]\n */\n@RequiresApi(Build.VERSION_CODES.Q)\nfun BlendingMode.toAndroidBlendMode(): AndroidBlendMode = when (this) {\n    BlendingMode.Clear -> AndroidBlendMode.CLEAR\n    BlendingMode.Src -> AndroidBlendMode.SRC\n    BlendingMode.Dst -> AndroidBlendMode.DST\n    BlendingMode.SrcOver -> AndroidBlendMode.SRC_OVER\n    BlendingMode.DstOver -> AndroidBlendMode.DST_OVER\n    BlendingMode.SrcIn -> AndroidBlendMode.SRC_IN\n    BlendingMode.DstIn -> AndroidBlendMode.DST_IN\n    BlendingMode.SrcOut -> AndroidBlendMode.SRC_OUT\n    BlendingMode.DstOut -> AndroidBlendMode.DST_OUT\n    BlendingMode.SrcAtop -> AndroidBlendMode.SRC_ATOP\n    BlendingMode.DstAtop -> AndroidBlendMode.DST_ATOP\n    BlendingMode.Xor -> AndroidBlendMode.XOR\n    BlendingMode.Plus -> AndroidBlendMode.PLUS\n    BlendingMode.Modulate -> AndroidBlendMode.MODULATE\n    BlendingMode.Screen -> AndroidBlendMode.SCREEN\n    BlendingMode.Overlay -> AndroidBlendMode.OVERLAY\n    BlendingMode.Darken -> AndroidBlendMode.DARKEN\n    BlendingMode.Lighten -> AndroidBlendMode.LIGHTEN\n    BlendingMode.ColorDodge -> AndroidBlendMode.COLOR_DODGE\n    BlendingMode.ColorBurn -> AndroidBlendMode.COLOR_BURN\n    BlendingMode.Hardlight -> AndroidBlendMode.HARD_LIGHT\n    BlendingMode.Softlight -> AndroidBlendMode.SOFT_LIGHT\n    BlendingMode.Difference -> AndroidBlendMode.DIFFERENCE\n    BlendingMode.Exclusion -> AndroidBlendMode.EXCLUSION\n    BlendingMode.Multiply -> AndroidBlendMode.MULTIPLY\n    BlendingMode.Hue -> AndroidBlendMode.HUE\n    BlendingMode.Saturation -> AndroidBlendMode.SATURATION\n    BlendingMode.Color -> AndroidBlendMode.COLOR\n    BlendingMode.Luminosity -> AndroidBlendMode.LUMINOSITY\n    // Always return SRC_OVER as the default if there is no valid alternative\n    else -> AndroidBlendMode.SRC_OVER\n}\n\nfun BlendingMode.toPaint(): Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n        blendMode = toAndroidBlendMode()\n    } else {\n        xfermode = PorterDuffXfermode(toPorterDuffMode())\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/CanvasUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Paint\nimport android.graphics.RectF\nimport androidx.core.graphics.get\nimport androidx.core.graphics.set\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.ensureActive\n\nfun Canvas.drawBitmap(\n    bitmap: Bitmap,\n    position: Position,\n    paint: Paint? = null,\n    horizontalPadding: Float = 0f,\n    verticalPadding: Float = 0f\n) {\n    val left = when (position) {\n        Position.TopLeft, Position.CenterLeft, Position.BottomLeft -> horizontalPadding\n        Position.TopCenter, Position.Center, Position.BottomCenter -> (width - bitmap.width) / 2f\n        Position.TopRight, Position.CenterRight, Position.BottomRight -> (width - bitmap.width - horizontalPadding)\n    }\n\n    val top = when (position) {\n        Position.TopLeft, Position.TopCenter, Position.TopRight -> verticalPadding\n        Position.CenterLeft, Position.Center, Position.CenterRight -> (height - bitmap.height) / 2f\n        Position.BottomLeft, Position.BottomCenter, Position.BottomRight -> (height - bitmap.height - verticalPadding)\n    }\n\n    drawBitmap(\n        bitmap,\n        null,\n        RectF(\n            left,\n            top,\n            bitmap.width + left,\n            bitmap.height + top\n        ),\n        paint\n    )\n}\n\nfun Canvas.drawBitmap(\n    bitmap: Bitmap,\n    left: Float = 0f,\n    top: Float = 0f\n) = drawBitmap(bitmap, left, top, Paint(Paint.ANTI_ALIAS_FLAG))\n\nfun Canvas.drawBitmap(\n    bitmap: Bitmap,\n    left: Float = 0f,\n    top: Float = 0f,\n    paint: Paint\n) = drawBitmap(bitmap, left, top, paint)\n\nsuspend fun Bitmap.healAlpha(\n    original: Bitmap\n): Bitmap = coroutineScope {\n    val processed = this@healAlpha\n\n    copy(Bitmap.Config.ARGB_8888, true).also { result ->\n        for (y in 0 until original.height) {\n            for (x in 0 until original.width) {\n                ensureActive()\n                val origPixel = original[x, y]\n                val procPixel = processed[x, y]\n\n                val origAlpha = origPixel ushr 24\n                if (origAlpha >= 255) continue\n                val newPixel = (origAlpha shl 24) or (procPixel and 0x00FFFFFF)\n\n                result[x, y] = newPixel\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/ColorUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.data.image.utils\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\n\nobject ColorUtils {\n\n    inline fun ColorModel.toColor() = Color(colorInt)\n\n    inline fun Color.toModel() = ColorModel(toArgb())\n\n    inline val ColorModel.red: Float\n        get() = toColor().red\n\n    inline val ColorModel.green: Float\n        get() = toColor().green\n\n    inline val ColorModel.blue: Float\n        get() = toColor().blue\n\n    inline val ColorModel.alpha: Float\n        get() = toColor().alpha\n\n    inline fun Color.toAbgr() = run {\n        Color(\n            red = alpha,\n            green = blue,\n            blue = green,\n            alpha = red,\n            colorSpace = colorSpace\n        ).toArgb()\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/ImageCompressorBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.AvifBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.BmpBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.HeicBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.IcoBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.Jpeg2000Backend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.JpegliBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.JpgBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.JxlBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.MozJpegBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.OxiPngBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.PngLosslessBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.PngLossyBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.QoiBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.StaticGifBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.TiffBackend\nimport com.t8rin.imagetoolbox.core.data.image.utils.compressor.WebpBackend\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.isLossless\n\n\ninternal interface ImageCompressorBackend {\n\n    suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray\n\n    class Factory {\n        fun create(\n            imageFormat: ImageFormat,\n            context: Context,\n            imageScaler: ImageScaler<Bitmap>\n        ): ImageCompressorBackend = when (imageFormat) {\n            ImageFormat.Jpeg,\n            ImageFormat.Jpg -> JpgBackend\n\n            ImageFormat.Jpegli -> JpegliBackend\n            ImageFormat.MozJpeg -> MozJpegBackend\n\n            ImageFormat.Png.Lossless -> PngLosslessBackend\n            ImageFormat.Png.Lossy -> PngLossyBackend\n            ImageFormat.Png.OxiPNG -> OxiPngBackend\n\n            ImageFormat.Webp.Lossless,\n            ImageFormat.Webp.Lossy -> WebpBackend(isLossless = imageFormat.isLossless)\n\n            ImageFormat.Jxl.Lossless,\n            ImageFormat.Jxl.Lossy -> JxlBackend(isLossless = imageFormat.isLossless)\n\n            ImageFormat.Tif,\n            ImageFormat.Tiff -> TiffBackend(context)\n\n            ImageFormat.Heic.Lossless,\n            ImageFormat.Heif.Lossless,\n            ImageFormat.Heic.Lossy,\n            ImageFormat.Heif.Lossy -> HeicBackend(isLossless = imageFormat.isLossless)\n\n            ImageFormat.Avif.Lossless,\n            ImageFormat.Avif.Lossy -> AvifBackend(isLossless = imageFormat.isLossless)\n\n            ImageFormat.Jpeg2000.J2k -> Jpeg2000Backend(isJ2K = true)\n            ImageFormat.Jpeg2000.Jp2 -> Jpeg2000Backend(isJ2K = false)\n\n            ImageFormat.Gif -> StaticGifBackend\n            ImageFormat.Bmp -> BmpBackend\n            ImageFormat.Qoi -> QoiBackend\n            ImageFormat.Ico -> IcoBackend(imageScaler)\n        }\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/StaticOptions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils\n\nimport coil3.gif.repeatCount\nimport coil3.request.ImageRequest\nimport com.awxkee.jxlcoder.coil.enableJxlAnimation\nimport com.github.awxkee.avifcoil.decoder.animation.enableAvifAnimation\nimport com.t8rin.imagetoolbox.core.data.coil.UpscaleSvgDecoder\n\nfun ImageRequest.Builder.static() = repeatCount(0)\n    .enableAvifAnimation(false)\n    .enableJxlAnimation(false)\n    .decoderFactory(UpscaleSvgDecoder.Factory())"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/AvifBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.radzivon.bartoshyk.avif.coder.AvifSpeed\nimport com.radzivon.bartoshyk.avif.coder.HeifCoder\nimport com.radzivon.bartoshyk.avif.coder.PreciseMode\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data class AvifBackend(\n    private val isLossless: Boolean\n) : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray {\n        val avifQuality = quality as? Quality.Avif ?: Quality.Avif()\n\n        return HeifCoder().encodeAvif(\n            bitmap = image,\n            quality = avifQuality.qualityValue,\n            preciseMode = if (isLossless) {\n                PreciseMode.LOSSLESS\n            } else {\n                PreciseMode.LOSSY\n            },\n            speed = AvifSpeed.entries.firstOrNull {\n                it.ordinal == (10 - avifQuality.effort)\n            } ?: AvifSpeed.TEN\n        )\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/BmpBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.trickle.BmpCompressor\n\ninternal data object BmpBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = runCatching {\n        BmpCompressor.compress(image)\n    }.getOrNull() ?: ByteArray(0)\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/HeicBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.radzivon.bartoshyk.avif.coder.HeifCoder\nimport com.radzivon.bartoshyk.avif.coder.HeifQualityArg\nimport com.radzivon.bartoshyk.avif.coder.PreciseMode\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data class HeicBackend(\n    private val isLossless: Boolean\n) : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray {\n        return HeifCoder().encodeHeic(\n            bitmap = image,\n            quality = HeifQualityArg.Quality(quality.qualityValue),\n            preciseMode = if (isLossless) {\n                PreciseMode.LOSSLESS\n            } else {\n                PreciseMode.LOSSY\n            }\n        )\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/IcoBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.get\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport kotlinx.coroutines.coroutineScope\nimport java.io.ByteArrayOutputStream\nimport java.nio.ByteBuffer\nimport java.nio.ByteOrder\n\ninternal data class IcoBackend(\n    private val imageScaler: ImageScaler<Bitmap>\n) : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = coroutineScope {\n        val bitmap = if (image.width > 256 || image.height > 256) {\n            imageScaler.scaleImage(\n                image = image,\n                width = 256,\n                height = 256,\n                resizeType = ResizeType.Flexible\n            )\n        } else image\n\n        val width = bitmap.width\n        val height = bitmap.height\n\n        val outputStream = ByteArrayOutputStream()\n        val header = ByteArray(6)\n        val entry = ByteArray(16)\n        val infoHeader = ByteArray(40)\n\n        // ICO Header\n        header[2] = 1 // Image type: Icon\n        header[4] = 1 // Number of images\n\n        outputStream.write(header)\n\n        // Image entry\n        entry[0] = if (width > 256) 0 else width.toByte()\n        entry[1] = if (height > 256) 0 else height.toByte()\n        entry[4] = 1 // Color planes\n        entry[6] = 32 // Bits per pixel\n\n        val andMaskSize = ((width + 31) / 32) * 4 * height\n        val xorMaskSize = width * height * 4\n        val imageDataSize = infoHeader.size + xorMaskSize + andMaskSize\n\n        ByteBuffer.wrap(entry, 8, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(imageDataSize)\n        ByteBuffer.wrap(entry, 12, 4)\n            .order(ByteOrder.LITTLE_ENDIAN)\n            .putInt(header.size + entry.size)\n\n        outputStream.write(entry)\n\n        // BITMAP INFO HEADER\n        ByteBuffer.wrap(infoHeader).order(ByteOrder.LITTLE_ENDIAN).apply {\n            putInt(40) // Header size\n            putInt(width) // Width\n            putInt(height * 2) // Height (XOR + AND masks)\n            putShort(1) // Color planes\n            putShort(32) // Bits per pixel\n            putInt(0) // Compression (BI_RGB)\n            putInt(xorMaskSize + andMaskSize) // Image size\n        }\n\n        outputStream.write(infoHeader)\n\n        // XOR mask (pixel data)\n        for (y in height - 1 downTo 0) {\n            for (x in 0 until width) {\n                val pixel = bitmap[x, y]\n                outputStream.write(pixel and 0xFF) // B\n                outputStream.write((pixel shr 8) and 0xFF) // G\n                outputStream.write((pixel shr 16) and 0xFF) // R\n                outputStream.write((pixel shr 24) and 0xFF) // A\n            }\n        }\n\n        // AND mask (all 0 for no transparency mask)\n        outputStream.write(ByteArray(andMaskSize))\n\n        outputStream.toByteArray()\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/Jpeg2000Backend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.gemalto.jp2.JP2Encoder\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data class Jpeg2000Backend(\n    private val isJ2K: Boolean\n) : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = JP2Encoder(image)\n        .setOutputFormat(\n            if (isJ2K) {\n                JP2Encoder.FORMAT_J2K\n            } else {\n                JP2Encoder.FORMAT_JP2\n            }\n        )\n        .setVisualQuality(quality.qualityValue.toFloat())\n        .encode()\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/JpegliBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport io.github.awxkee.jpegli.coder.IccStrategy\nimport io.github.awxkee.jpegli.coder.JpegliCoder\nimport io.github.awxkee.jpegli.coder.Scalar\nimport java.io.ByteArrayOutputStream\n\ninternal data object JpegliBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = ByteArrayOutputStream().apply {\n        use { out ->\n            JpegliCoder.compress(\n                bitmap = image,\n                quality = quality.qualityValue,\n                background = Scalar.ZERO,\n                progressive = true,\n                strategy = IccStrategy.DEFAULT,\n                outputStream = out\n            )\n        }\n    }.toByteArray()\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/JpgBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.data.utils.compress\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data object JpgBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = image.compress(\n        format = Bitmap.CompressFormat.JPEG,\n        quality = quality.qualityValue\n    )\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/JxlBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.jxlcoder.JxlChannelsConfiguration\nimport com.awxkee.jxlcoder.JxlCoder\nimport com.awxkee.jxlcoder.JxlCompressionOption\nimport com.awxkee.jxlcoder.JxlDecodingSpeed\nimport com.awxkee.jxlcoder.JxlEffort\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data class JxlBackend(\n    private val isLossless: Boolean\n) : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray {\n        val jxlQuality = quality as? Quality.Jxl ?: Quality.Jxl()\n        return JxlCoder.encode(\n            bitmap = if (jxlQuality.channels == Quality.Channels.Monochrome) {\n                Aire.grayscale(image)\n            } else image,\n            channelsConfiguration = when (jxlQuality.channels) {\n                Quality.Channels.RGBA -> JxlChannelsConfiguration.RGBA\n                Quality.Channels.RGB -> JxlChannelsConfiguration.RGB\n                Quality.Channels.Monochrome -> JxlChannelsConfiguration.MONOCHROME\n            },\n            compressionOption = if (isLossless) {\n                JxlCompressionOption.LOSSLESS\n            } else {\n                JxlCompressionOption.LOSSY\n            },\n            quality = if (isLossless) 100 else jxlQuality.qualityValue,\n            effort = JxlEffort.entries.first { it.ordinal == jxlQuality.effort - 1 },\n            decodingSpeed = JxlDecodingSpeed.entries.first { it.ordinal == jxlQuality.speed }\n        )\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/MozJpegBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data object MozJpegBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = Aire.mozjpeg(\n        bitmap = image,\n        quality = quality.qualityValue\n    )\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/OxiPngBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.trickle.Oxipng\n\ninternal data object OxiPngBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = Oxipng.optimize(\n        bitmap = image,\n        options = Oxipng.SimpleOptions(\n            level = quality.qualityValue.coerceIn(0..6)\n        )\n    )\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/PngLosslessBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.data.utils.compress\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data object PngLosslessBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = image.compress(\n        format = Bitmap.CompressFormat.PNG,\n        quality = quality.qualityValue\n    )\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/PngLossyBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.AireColorMapper\nimport com.awxkee.aire.AirePaletteDithering\nimport com.awxkee.aire.AireQuantize\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data object PngLossyBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray {\n        val pngLossyQuality = quality as? Quality.PngLossy ?: Quality.PngLossy()\n        return Aire.toPNG(\n            bitmap = image,\n            maxColors = pngLossyQuality.maxColors,\n            quantize = AireQuantize.XIAOLING_WU,\n            dithering = AirePaletteDithering.JARVIS_JUDICE_NINKE,\n            colorMapper = AireColorMapper.COVER_TREE,\n            compressionLevel = pngLossyQuality.compressionLevel.coerceIn(0..9)\n        )\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/QoiBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.qoi_coder.QOIEncoder\n\ninternal data object QoiBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = QOIEncoder(image).encode()\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/StaticGifBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.gif_converter.GifEncoder\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport java.io.ByteArrayOutputStream\n\ninternal data object StaticGifBackend : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = ByteArrayOutputStream().use { out ->\n        GifEncoder().apply {\n            setSize(\n                image.width,\n                image.height\n            )\n            setRepeat(1)\n            setQuality(\n                (100 - ((quality.qualityValue - 1) * (100 / 19f))).toInt()\n            )\n            setTransparent(Color.Transparent.toArgb())\n            start(out)\n            addFrame(image)\n            finish()\n        }\n\n        out.toByteArray()\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/TiffBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport org.beyka.tiffbitmapfactory.CompressionScheme\nimport org.beyka.tiffbitmapfactory.Orientation\nimport org.beyka.tiffbitmapfactory.TiffSaver\nimport java.io.File\n\ninternal data class TiffBackend(\n    private val context: Context\n) : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray {\n        val tiffQuality = quality as? Quality.Tiff ?: Quality.Tiff()\n\n        val file = File(context.cacheDir, \"temp.tiff\").apply { createNewFile() }\n        val options = TiffSaver.SaveOptions().apply {\n            compressionScheme = CompressionScheme.entries[tiffQuality.compressionScheme]\n            orientation = Orientation.TOP_LEFT\n        }\n        TiffSaver.saveBitmap(file, image, options)\n\n        return file.readBytes().also {\n            file.delete()\n        }\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/image/utils/compressor/WebpBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.image.utils.compressor\n\nimport android.graphics.Bitmap\nimport android.os.Build\nimport com.t8rin.imagetoolbox.core.data.image.utils.ImageCompressorBackend\nimport com.t8rin.imagetoolbox.core.data.utils.compress\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninternal data class WebpBackend(\n    private val isLossless: Boolean\n) : ImageCompressorBackend {\n\n    override suspend fun compress(\n        image: Bitmap,\n        quality: Quality\n    ): ByteArray = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {\n        image.compress(\n            format = if (isLossless) {\n                Bitmap.CompressFormat.WEBP_LOSSLESS\n            } else {\n                Bitmap.CompressFormat.WEBP_LOSSY\n            },\n            quality = quality.qualityValue\n        )\n    } else {\n        @Suppress(\"DEPRECATION\")\n        image.compress(\n            format = Bitmap.CompressFormat.WEBP,\n            quality = quality.qualityValue\n        )\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/json/MoshiParser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.json\n\nimport com.squareup.moshi.Moshi\nimport com.squareup.moshi.rawType\nimport com.t8rin.imagetoolbox.core.domain.json.JsonParser\nimport com.t8rin.logger.makeLog\nimport java.lang.reflect.Type\nimport javax.inject.Inject\n\ninternal class MoshiParser @Inject constructor(\n    private val moshi: Moshi\n) : JsonParser {\n\n    override fun <T> toJson(\n        obj: T,\n        type: Type,\n    ): String? = runCatching {\n        moshi.adapter<T>(type).toJson(obj)\n    }.onFailure { it.makeLog(\"MoshiParser toJson T = ${obj?.run { this::class }}\") }.getOrNull()\n\n    override fun <T> fromJson(\n        json: String,\n        type: Type,\n    ): T? = if (json.isBlank()) {\n        \"json is empty\".makeLog(\"MoshiParser fromJson T = ${type.rawType.name}\")\n        null\n    } else {\n        runCatching {\n            moshi.adapter<T>(type).fromJson(json)\n        }.onFailure { it.makeLog(\"MoshiParser fromJson T = ${type.rawType.name}\") }.getOrNull()\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/remote/AndroidDownloadManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.remote\n\nimport android.content.Context\nimport com.t8rin.imagetoolbox.core.data.utils.getWithProgress\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadManager\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.saving.track\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.throttleLatest\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.decodeEscaped\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport io.ktor.client.HttpClient\nimport io.ktor.utils.io.jvm.javaio.copyTo\nimport io.ktor.utils.io.jvm.javaio.toInputStream\nimport kotlinx.coroutines.flow.channelFlow\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipInputStream\nimport javax.inject.Inject\nimport kotlin.math.roundToInt\n\ninternal class AndroidDownloadManager @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val keepAliveService: KeepAliveService,\n    private val client: HttpClient,\n    resourceManager: ResourceManager,\n    dispatchersHolder: DispatchersHolder\n) : DownloadManager,\n    ResourceManager by resourceManager,\n    DispatchersHolder by dispatchersHolder {\n\n    override suspend fun download(\n        url: String,\n        destinationPath: String,\n        onStart: suspend () -> Unit,\n        onProgress: suspend (DownloadProgress) -> Unit,\n        onFinish: suspend (Throwable?) -> Unit\n    ): Unit = withContext(defaultDispatcher) {\n        keepAliveService.track(\n            initial = {\n                updateOrStart(\n                    title = getString(R.string.downloading)\n                )\n            },\n            onFailure = onFinish\n        ) {\n            channelFlow {\n                onStart()\n                url.makeLog(\"Start Download\")\n\n                val tmp = File(\n                    File(context.cacheDir, \"downloadCache\").apply(File::mkdirs),\n                    \"${url.substringAfterLast('/').substringBefore('?')}.tmp\"\n                )\n\n                client.getWithProgress(\n                    url = url,\n                    onFailure = onFinish,\n                    onProgress = { bytesSentTotal, contentLength ->\n                        val progress = contentLength?.let {\n                            bytesSentTotal.toFloat() / contentLength.toFloat()\n                        } ?: 0f\n\n                        onProgress(\n                            DownloadProgress(\n                                currentPercent = progress,\n                                currentTotalSize = contentLength ?: -1\n                            ).also(::trySend)\n                        )\n                    },\n                    onOpen = { response ->\n                        tmp.outputStream().use { fos ->\n                            response.copyTo(fos)\n                            tmp.renameTo(File(destinationPath))\n                            tmp.delete()\n                            onFinish(null)\n                        }\n                    }\n                )\n\n                tmp.delete()\n                close()\n            }.throttleLatest(50).collect {\n                updateProgress(\n                    title = getString(R.string.downloading),\n                    done = (it.currentPercent * 100).roundToInt(),\n                    total = 100\n                )\n            }\n        }\n    }\n\n    override suspend fun downloadZip(\n        url: String,\n        destinationPath: String,\n        onStart: suspend () -> Unit,\n        onProgress: (DownloadProgress) -> Unit,\n        downloadOnlyNewData: Boolean\n    ): Unit = withContext(defaultDispatcher) {\n        keepAliveService.track(\n            initial = {\n                updateOrStart(\n                    title = getString(R.string.downloading)\n                )\n            }\n        ) {\n            channelFlow {\n                client.getWithProgress(\n                    url = url,\n                    onProgress = { bytesSentTotal, contentLength ->\n                        val progress = contentLength?.let {\n                            bytesSentTotal.toFloat() / contentLength.toFloat()\n                        } ?: 0f\n\n                        onProgress(\n                            DownloadProgress(\n                                currentPercent = progress,\n                                currentTotalSize = contentLength ?: -1\n                            ).also(::trySend)\n                        )\n                    },\n                    onOpen = { response ->\n                        ZipInputStream(response.toInputStream()).use { zipIn ->\n                            var entry: ZipEntry?\n                            while (zipIn.nextEntry.also { entry = it } != null) {\n                                entry?.let { zipEntry ->\n                                    val filename = zipEntry.name\n\n                                    if (filename.isNullOrBlank() || filename.startsWith(\"__\")) return@let\n\n                                    val outFile = File(\n                                        destinationPath,\n                                        filename.decodeEscaped()\n                                    ).apply {\n                                        delete()\n                                        parentFile?.mkdirs()\n                                        createNewFile()\n                                    }\n\n                                    if (downloadOnlyNewData) {\n                                        val file = File(destinationPath).listFiles()?.find {\n                                            it.name == filename && it.length() > 0L\n                                        }\n\n                                        if (file != null) return@let\n                                    }\n\n                                    FileOutputStream(outFile).use { fos ->\n                                        zipIn.copyTo(fos)\n                                    }\n                                    zipIn.closeEntry()\n                                }\n                            }\n                        }\n                    }\n                )\n\n                close()\n            }.throttleLatest(50).collect {\n                updateProgress(\n                    title = getString(R.string.downloading),\n                    done = (it.currentPercent * 100).roundToInt(),\n                    total = 100\n                )\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/remote/AndroidRemoteResourcesStore.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.remote\n\nimport android.content.Context\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.RES_BASE_URL\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadManager\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResource\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResources\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResourcesStore\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.utils.decodeEscaped\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport javax.inject.Inject\n\n\ninternal class AndroidRemoteResourcesStore @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val downloadManager: DownloadManager,\n    resourceManager: ResourceManager,\n    dispatchersHolder: DispatchersHolder\n) : RemoteResourcesStore,\n    DispatchersHolder by dispatchersHolder,\n    ResourceManager by resourceManager {\n\n    override suspend fun getResources(\n        name: String,\n        forceUpdate: Boolean,\n        onDownloadRequest: suspend (name: String) -> RemoteResources?\n    ): RemoteResources? = withContext(ioDispatcher) {\n        val availableFiles = getSavingDir(name).listFiles()\n        val shouldDownload = forceUpdate || availableFiles.isNullOrEmpty()\n\n        val availableResources = if (!availableFiles.isNullOrEmpty()) {\n            RemoteResources(\n                name = name,\n                list = availableFiles.mapNotNull {\n                    it.toUri().toString()\n                }.map { uri ->\n                    RemoteResource(\n                        uri = uri,\n                        name = uri.takeLastWhile { it != '/' }.decodeEscaped()\n                    )\n                }.sortedBy { it.name }\n            )\n        } else null\n\n        if (shouldDownload) onDownloadRequest(name) ?: availableResources\n        else availableResources\n    }\n\n    override suspend fun downloadResources(\n        name: String,\n        onProgress: (DownloadProgress) -> Unit,\n        onFailure: (Throwable) -> Unit,\n        downloadOnlyNewData: Boolean\n    ): RemoteResources? = withContext(defaultDispatcher) {\n        runSuspendCatching {\n            val url = getResourcesLink(name)\n            val savingDir = getSavingDir(name)\n\n            downloadManager.downloadZip(\n                url = url,\n                destinationPath = savingDir.absolutePath,\n                onProgress = onProgress,\n                downloadOnlyNewData = downloadOnlyNewData\n            )\n\n            name to url makeLog \"downloadResources\"\n\n            val savedAlready = savingDir.listFiles()?.mapNotNull {\n                it.toUri().toString()\n            }?.map { uri ->\n                RemoteResource(\n                    uri = uri,\n                    name = uri.takeLastWhile { it != '/' }.decodeEscaped()\n                )\n            } ?: emptyList()\n\n            RemoteResources(\n                name = name,\n                list = savedAlready.sortedBy { it.name }\n            )\n        }.onFailure {\n            it.makeLog()\n            onFailure(it)\n        }.getOrNull()\n    }\n\n    private fun getResourcesLink(\n        dirName: String\n    ): String = RES_BASE_URL.replace(\"*\", dirName)\n\n\n    private fun getSavingDir(\n        dirName: String\n    ): File = File(rootDir, dirName.substringBefore(\"/\")).apply(File::mkdirs)\n\n    private val rootDir = File(context.filesDir, \"remoteResources\").apply(File::mkdirs)\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/resource/AndroidResourceManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.resource\n\nimport android.content.Context\nimport android.content.res.Configuration\nimport androidx.annotation.StringRes\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport java.util.Locale\nimport javax.inject.Inject\n\ninternal class AndroidResourceManager @Inject constructor(\n    @ApplicationContext private val context: Context\n) : ResourceManager {\n\n    override fun getString(\n        resId: Int\n    ): String = context.getString(resId)\n\n    override fun getString(\n        resId: Int,\n        vararg formatArgs: Any\n    ): String = context.getString(resId, *formatArgs)\n\n    override fun getStringLocalized(\n        resId: Int,\n        language: String\n    ): String = context.getStringLocalized(\n        resId = resId,\n        locale = Locale.forLanguageTag(language)\n    )\n\n    override fun getStringLocalized(\n        resId: Int,\n        language: String,\n        vararg formatArgs: Any\n    ): String = context.getStringLocalized(\n        resId = resId,\n        locale = Locale.forLanguageTag(language),\n        formatArgs = formatArgs\n    )\n\n    private fun Context.getStringLocalized(\n        @StringRes\n        resId: Int,\n        locale: Locale,\n    ): String = createConfigurationContext(\n        Configuration(resources.configuration).apply { setLocale(locale) }\n    ).getText(resId).toString()\n\n    private fun Context.getStringLocalized(\n        @StringRes\n        resId: Int,\n        locale: Locale,\n        vararg formatArgs: Any\n    ): String = createConfigurationContext(\n        Configuration(resources.configuration).apply { setLocale(locale) }\n    ).getString(resId, *formatArgs)\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/AndroidFileController.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving\n\nimport android.content.ClipData\nimport android.content.ClipboardManager\nimport android.content.Context\nimport android.net.Uri\nimport androidx.core.content.getSystemService\nimport androidx.core.net.toUri\nimport androidx.datastore.core.DataStore\nimport androidx.datastore.preferences.core.Preferences\nimport androidx.datastore.preferences.core.edit\nimport androidx.datastore.preferences.core.stringPreferencesKey\nimport androidx.documentfile.provider.DocumentFile\nimport coil3.ImageLoader\nimport com.t8rin.exif.ExifInterface\nimport com.t8rin.imagetoolbox.core.data.coil.remove\nimport com.t8rin.imagetoolbox.core.data.image.toMetadata\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriReadable\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriWriteable\nimport com.t8rin.imagetoolbox.core.data.utils.cacheSize\nimport com.t8rin.imagetoolbox.core.data.utils.clearCache\nimport com.t8rin.imagetoolbox.core.data.utils.isExternalStorageWritable\nimport com.t8rin.imagetoolbox.core.data.utils.openFileDescriptor\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.clearAllAttributes\nimport com.t8rin.imagetoolbox.core.domain.image.copyTo\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.image.readOnly\nimport com.t8rin.imagetoolbox.core.domain.json.JsonParser\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\nimport com.t8rin.imagetoolbox.core.domain.saving.io.use\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.FileMode\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation\nimport com.t8rin.imagetoolbox.core.utils.fileSize\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.core.utils.getPath\nimport com.t8rin.imagetoolbox.core.utils.listFilesInDirectory\nimport com.t8rin.imagetoolbox.core.utils.listFilesInDirectoryProgressive\nimport com.t8rin.imagetoolbox.core.utils.tryExtractOriginal\nimport com.t8rin.imagetoolbox.core.utils.uiPath\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.io.FileOutputStream\nimport javax.inject.Inject\nimport kotlin.reflect.KClass\n\n\ninternal class AndroidFileController @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val settingsManager: SettingsManager,\n    private val shareProvider: ShareProvider,\n    private val filenameCreator: FilenameCreator,\n    private val jsonParser: JsonParser,\n    private val appScope: AppScope,\n    private val dataStore: DataStore<Preferences>,\n    private val imageLoader: ImageLoader,\n    dispatchersHolder: DispatchersHolder,\n    resourceManager: ResourceManager,\n) : DispatchersHolder by dispatchersHolder,\n    ResourceManager by resourceManager,\n    FileController {\n\n    private val _settingsState = settingsManager.settingsState\n    private val settingsState get() = _settingsState.value\n\n    override fun getSize(uri: String): Long? = uri.toUri().fileSize()\n\n    override val defaultSavingPath: String\n        get() = settingsState.saveFolderUri.getPath(context)\n\n    override suspend fun save(\n        saveTarget: SaveTarget,\n        keepOriginalMetadata: Boolean,\n        oneTimeSaveLocationUri: String?,\n    ): SaveResult {\n        val result = saveImpl(\n            saveTarget = saveTarget,\n            keepOriginalMetadata = keepOriginalMetadata,\n            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n        )\n\n        Triple(\n            first = result,\n            second = keepOriginalMetadata,\n            third = oneTimeSaveLocationUri\n        ).makeLog(\"File Controller save\")\n\n        return result\n    }\n\n    private suspend fun saveImpl(\n        saveTarget: SaveTarget,\n        keepOriginalMetadata: Boolean,\n        oneTimeSaveLocationUri: String?,\n    ): SaveResult = withContext(ioDispatcher) {\n        if (!context.isExternalStorageWritable()) {\n            return@withContext SaveResult.Error.MissingPermissions\n        }\n\n        val data = if (saveTarget is ImageSaveTarget && saveTarget.readFromUriInsteadOfData) {\n            readBytes(saveTarget.originalUri)\n        } else {\n            saveTarget.data\n        }\n\n        val savingPath = oneTimeSaveLocationUri?.getPath(context) ?: defaultSavingPath\n\n        runSuspendCatching {\n            if (settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled) {\n                val clipboardManager = context.getSystemService<ClipboardManager>()\n\n                shareProvider.cacheByteArray(\n                    byteArray = data,\n                    filename = filenameCreator.constructRandomFilename(saveTarget.extension)\n                )?.toUri()?.let { uri ->\n                    clipboardManager?.setPrimaryClip(\n                        ClipData.newUri(\n                            context.contentResolver,\n                            \"IMAGE\",\n                            uri\n                        )\n                    )\n                }\n            }\n\n            if (settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled.WithoutSaving) {\n                return@withContext SaveResult.Success(\n                    message = getString(R.string.copied),\n                    savingPath = savingPath\n                )\n            }\n\n            val originalUri = saveTarget.originalUri.toUri()\n\n            if (saveTarget is ImageSaveTarget && saveTarget.canSkipIfLarger && settingsState.allowSkipIfLarger) {\n                val originalSize = originalUri.fileSize()\n                val newSize = data.size\n\n                if (originalSize != null && newSize > originalSize) {\n                    return@withContext SaveResult.Skipped\n                }\n            }\n\n            if (settingsState.filenameBehavior is FilenameBehavior.Overwrite) {\n                val providedMetadata = (saveTarget as? ImageSaveTarget)?.metadata\n                val targetMetadata = if (keepOriginalMetadata) {\n                    readMetadata(originalUri.toString()) ?: providedMetadata\n                } else {\n                    providedMetadata\n                }\n\n                runCatching {\n                    if (originalUri == Uri.EMPTY) throw IllegalStateException()\n\n                    context.openFileDescriptor(\n                        uri = originalUri,\n                        mode = FileMode.WriteTruncate\n                    )\n                }.getOrNull()?.use { parcel ->\n                    FileOutputStream(parcel.fileDescriptor).use { out ->\n                        out.write(data)\n\n                        copyMetadata(\n                            initialExif = targetMetadata,\n                            fileUri = originalUri,\n                            keepOriginalMetadata = keepOriginalMetadata,\n                            originalUri = originalUri\n                        )\n                    }\n\n                    imageLoader.apply {\n                        memoryCache?.remove(originalUri.toString())\n                        diskCache?.remove(originalUri.toString())\n                    }\n\n                    return@withContext SaveResult.Success(\n                        message = getString(\n                            R.string.saved_to_original,\n                            originalUri.filename(context).toString()\n                        ),\n                        isOverwritten = true,\n                        savingPath = savingPath\n                    )\n                }\n            } else {\n                val documentFile: DocumentFile?\n                val treeUri = (oneTimeSaveLocationUri ?: settingsState.saveFolderUri).takeIf {\n                    !it.isNullOrEmpty()\n                }\n\n                if (treeUri != null) {\n                    documentFile = runCatching {\n                        treeUri.toUri().let {\n                            if (DocumentFile.isDocumentUri(context, it)) {\n                                DocumentFile.fromSingleUri(context, it)\n                            } else DocumentFile.fromTreeUri(context, it)\n                        }\n                    }.getOrNull()\n\n                    if (documentFile == null || !documentFile.exists()) {\n                        if (oneTimeSaveLocationUri == null) {\n                            settingsManager.setSaveFolderUri(null)\n                        } else {\n                            settingsManager.setOneTimeSaveLocations(\n                                settingsState.oneTimeSaveLocations.let { locations ->\n                                    (locations - locations.find { it.uri == oneTimeSaveLocationUri }).filterNotNull()\n                                }\n                            )\n                        }\n                        return@withContext SaveResult.Error.Exception(\n                            Exception(\n                                getString(\n                                    R.string.no_such_directory,\n                                    treeUri.toUri().uiPath(treeUri)\n                                )\n                            )\n                        )\n                    }\n                } else {\n                    documentFile = null\n                }\n\n                var initialExif: Metadata? = null\n\n                val newSaveTarget = if (saveTarget is ImageSaveTarget) {\n                    initialExif = saveTarget.metadata\n\n                    saveTarget.copy(\n                        filename = filenameCreator.constructImageFilename(\n                            saveTarget = saveTarget,\n                            forceNotAddSizeInFilename = saveTarget.imageInfo.height <= 0 || saveTarget.imageInfo.width <= 0\n                        )\n                    )\n                } else saveTarget\n\n                val savingFolder = SavingFolder.getInstance(\n                    context = context,\n                    treeUri = treeUri?.toUri(),\n                    saveTarget = newSaveTarget\n                ) ?: throw IllegalArgumentException(getString(R.string.error_while_saving))\n\n                savingFolder.use {\n                    it.writeBytes(data)\n                }\n\n                copyMetadata(\n                    initialExif = initialExif,\n                    fileUri = savingFolder.fileUri,\n                    keepOriginalMetadata = keepOriginalMetadata,\n                    originalUri = saveTarget.originalUri.toUri()\n                )\n\n                val filename = newSaveTarget.filename\n                    ?: throw IllegalArgumentException(getString(R.string.filename_is_not_set))\n\n                oneTimeSaveLocationUri?.let {\n                    if (documentFile?.isDirectory == true) {\n                        val currentLocation =\n                            settingsState.oneTimeSaveLocations.find { it.uri == oneTimeSaveLocationUri }\n\n                        settingsManager.setOneTimeSaveLocations(\n                            currentLocation?.let {\n                                settingsState.oneTimeSaveLocations.toMutableList().apply {\n                                    remove(currentLocation)\n                                    add(\n                                        currentLocation.copy(\n                                            uri = oneTimeSaveLocationUri,\n                                            date = System.currentTimeMillis(),\n                                            count = currentLocation.count + 1\n                                        )\n                                    )\n                                }\n                            } ?: settingsState.oneTimeSaveLocations.plus(\n                                OneTimeSaveLocation(\n                                    uri = oneTimeSaveLocationUri,\n                                    date = System.currentTimeMillis(),\n                                    count = 1\n                                )\n                            )\n                        )\n                    }\n                }\n\n                return@withContext SaveResult.Success(\n                    message = if (savingPath.isNotEmpty()) {\n                        val isFile =\n                            (documentFile?.isDirectory != true && oneTimeSaveLocationUri != null)\n                        if (isFile) {\n                            getString(R.string.saved_to_custom)\n                        } else if (filename.isNotEmpty()) {\n                            getString(\n                                R.string.saved_to,\n                                savingPath,\n                                filename\n                            )\n                        } else {\n                            getString(\n                                R.string.saved_to_without_filename,\n                                savingPath\n                            )\n                        }\n                    } else null,\n                    savingPath = savingPath\n                )\n            }\n        }.onFailure {\n            return@withContext SaveResult.Error.Exception(it)\n        }\n\n        SaveResult.Error.Exception(\n            SaveException(\n                message = getString(R.string.something_went_wrong)\n            )\n        )\n    }\n\n    override fun clearCache(\n        onComplete: (Long) -> Unit,\n    ) {\n        appScope.launch {\n            context.clearCache()\n            onComplete(getCacheSize())\n            \"cache cleared\".makeLog(\"AndroidFileController\")\n        }\n    }\n\n    override fun getCacheSize(): Long = context.cacheSize()\n\n    override suspend fun readBytes(\n        uri: String,\n    ): ByteArray = withContext(ioDispatcher) {\n        runSuspendCatching {\n            context.contentResolver.openInputStream(uri.toUri())?.use {\n                it.buffered().readBytes()\n            }\n        }.onFailure {\n            uri.makeLog(\"File Controller read\")\n            it.makeLog(\"File Controller read\")\n        }.getOrNull() ?: ByteArray(0)\n    }\n\n    override suspend fun writeBytes(\n        uri: String,\n        block: suspend (Writeable) -> Unit,\n    ): SaveResult = withContext(ioDispatcher) {\n        runSuspendCatching {\n            block(\n                UriWriteable(\n                    uri = uri.toUri(),\n                    context = context\n                )\n            )\n        }.onSuccess {\n            return@withContext SaveResult.Success(\n                message = null,\n                savingPath = \"\"\n            )\n        }.onFailure {\n            uri.makeLog(\"File Controller write\")\n            it.makeLog(\"File Controller write\")\n            return@withContext SaveResult.Error.Exception(it)\n        }\n\n        return@withContext SaveResult.Error.Exception(IllegalStateException())\n    }\n\n    override suspend fun transferBytes(\n        fromUri: String,\n        toUri: String\n    ): SaveResult = transferBytes(\n        fromUri = fromUri,\n        to = UriWriteable(\n            uri = toUri.toUri(),\n            context = context\n        )\n    )\n\n    override suspend fun transferBytes(\n        fromUri: String,\n        to: Writeable\n    ): SaveResult = withContext(ioDispatcher) {\n        runSuspendCatching {\n            UriReadable(\n                uri = fromUri.toUri(),\n                context = context\n            ).copyTo(to)\n        }.onSuccess {\n            return@withContext SaveResult.Success(\n                message = null,\n                savingPath = \"\"\n            )\n        }.onFailure {\n            to.makeLog(\"File Controller write\")\n            it.makeLog(\"File Controller write\")\n            return@withContext SaveResult.Error.Exception(it)\n        }\n\n        return@withContext SaveResult.Error.Exception(IllegalStateException())\n    }\n\n    override suspend fun <O : Any> saveObject(\n        key: String,\n        value: O,\n    ): Boolean = withContext(ioDispatcher) {\n        \"saveObject value = $value\".makeLog(key)\n        runCatching {\n            dataStore.edit {\n                it[stringPreferencesKey(\"fast_$key\")] =\n                    jsonParser.toJson(value, value::class.java)!!\n            }\n        }.onSuccess {\n            \"saveObject success\".makeLog(key)\n            return@withContext true\n        }.onFailure {\n            it.makeLog(\"saveObject $key\")\n            return@withContext false\n        }\n\n        return@withContext false\n    }\n\n    override suspend fun <O : Any> restoreObject(\n        key: String,\n        kClass: KClass<O>,\n    ): O? = withContext(ioDispatcher) {\n        runCatching {\n            \"restoreObject\".makeLog(key)\n            jsonParser.fromJson<O>(\n                json = dataStore.data.first()[stringPreferencesKey(\"fast_$key\")].orEmpty(),\n                type = kClass.java\n            )\n        }.onFailure {\n            it.makeLog(\"restoreObject $key\")\n        }.onSuccess {\n            \"restoreObject success value = $it\".makeLog(key)\n        }.getOrNull()\n    }\n\n    override suspend fun writeMetadata(\n        imageUri: String,\n        metadata: Metadata?\n    ) {\n        copyMetadata(\n            initialExif = metadata,\n            fileUri = imageUri.toUri(),\n            keepOriginalMetadata = false,\n            originalUri = imageUri.toUri()\n        )\n    }\n\n    override suspend fun readMetadata(\n        imageUri: String\n    ): Metadata? = runSuspendCatching {\n        context.contentResolver.openInputStream(imageUri.toUri().tryExtractOriginal())?.use {\n            ExifInterface(it).toMetadata().readOnly().makeLog(\"readMetadata\")\n        }\n    }.getOrNull()\n\n    override suspend fun listFilesInDirectory(\n        treeUri: String\n    ): List<String> = withContext(ioDispatcher) {\n        treeUri.toUri().listFilesInDirectory().map { it.toString() }\n    }\n\n    override fun listFilesInDirectoryAsFlow(\n        treeUri: String\n    ): Flow<String> = treeUri.toUri().listFilesInDirectoryProgressive().map {\n        it.toString()\n    }.flowOn(ioDispatcher)\n\n    private suspend fun copyMetadata(\n        initialExif: Metadata?,\n        fileUri: Uri,\n        keepOriginalMetadata: Boolean,\n        originalUri: Uri\n    ) = runSuspendCatching {\n        if (initialExif != null) {\n            openFileDescriptor(fileUri)?.use {\n                initialExif.makeLog(\"initialMetadata\")\n                    .copyTo(it.fileDescriptor.toMetadata().makeLog(\"dstMetadata\"))\n            }\n        } else if (keepOriginalMetadata) {\n            if (fileUri != originalUri) {\n                openFileDescriptor(fileUri)?.use {\n                    readMetadata(originalUri.toString()).makeLog(\"srcMetadata\")?.copyTo(\n                        it.fileDescriptor.toMetadata().makeLog(\"dstMetadata\")\n                    )\n                }\n            } else {\n                \"Nothing, copying from self to self is pointless\".makeLog(\"copyMetadata\")\n            }\n        } else {\n            openFileDescriptor(fileUri)?.use {\n                it.fileDescriptor.toMetadata().apply {\n                    clearAllAttributes()\n\n                    if (settingsState.keepDateTime) {\n                        readMetadata(originalUri.toString()).makeLog(\"srcMetadata\")\n                            ?.copyTo(\n                                metadata = this,\n                                tags = MetadataTag.dateEntries\n                            )\n                    } else {\n                        saveAttributes()\n                    }\n                }\n            }.makeLog(\"metadataCleared\")\n        }\n    }\n\n    private fun openFileDescriptor(\n        imageUri: Uri\n    ) = context.openFileDescriptor(\n        uri = imageUri.tryExtractOriginal(),\n        mode = FileMode.ReadWrite\n    )\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/AndroidFilenameCreator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving\n\nimport android.content.Context\nimport android.net.Uri\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.utils.computeFromByteArray\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.title\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.RandomStringGenerator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Date\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.DateUpper\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Extension\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.ExtensionUpper\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Height\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.OriginalName\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.OriginalNameUpper\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Prefix\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.PrefixUpper\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.PresetInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.PresetInfoUpper\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Rand\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.ScaleMode\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.ScaleModeUpper\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Sequence\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Suffix\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.SuffixUpper\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Width\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.replace\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport java.util.Date\nimport java.util.Locale\nimport javax.inject.Inject\nimport kotlin.random.Random\n\ninternal class AndroidFilenameCreator @Inject constructor(\n    private val randomStringGenerator: RandomStringGenerator,\n    @ApplicationContext private val context: Context,\n    settingsManager: SettingsManager,\n    dispatchersHolder: DispatchersHolder,\n    resourceManager: ResourceManager\n) : FilenameCreator,\n    DispatchersHolder by dispatchersHolder,\n    ResourceManager by resourceManager {\n\n    private val _settingsState = settingsManager.settingsState\n    private val settingsState get() = _settingsState.value\n\n    override fun constructImageFilename(\n        saveTarget: ImageSaveTarget,\n        oneTimePrefix: String?,\n        forceNotAddSizeInFilename: Boolean,\n        pattern: String?\n    ): String {\n        val extension = saveTarget.extension\n\n        return when (val behavior = settingsState.filenameBehavior) {\n            is FilenameBehavior.Checksum -> \"${behavior.hashingType.computeFromByteArray(saveTarget.data)}.$extension\"\n            is FilenameBehavior.Random -> \"${randomStringGenerator.generate(32)}.$extension\"\n            is FilenameBehavior.Overwrite,\n            is FilenameBehavior.None -> constructImageFilename(\n                saveTarget = saveTarget,\n                oneTimePrefix = oneTimePrefix,\n                pattern = (pattern ?: settingsState.filenamePattern).orEmpty().ifBlank {\n                    if (settingsState.addOriginalFilename) {\n                        FilenamePattern.ForOriginal\n                    } else {\n                        FilenamePattern.Default\n                    }\n                }\n            )\n        }.makeLog(\"Filename\")\n    }\n\n    private fun constructImageFilename(\n        saveTarget: ImageSaveTarget,\n        oneTimePrefix: String?,\n        pattern: String\n    ): String {\n        val random = Random(Date().time)\n        val extension = saveTarget.extension\n\n        val isOriginalEmpty = saveTarget.originalUri.toUri() == Uri.EMPTY\n\n        val widthString = if (settingsState.addSizeInFilename) {\n            if (isOriginalEmpty) \"\" else saveTarget.imageInfo.width.toString()\n        } else \"\"\n        val heightString = if (settingsState.addSizeInFilename) {\n            if (isOriginalEmpty) \"\" else saveTarget.imageInfo.height.toString()\n        } else \"\"\n\n        val prefix = oneTimePrefix ?: settingsState.filenamePrefix\n        val suffix = settingsState.filenameSuffix\n\n        val originalName = if (settingsState.addOriginalFilename && !isOriginalEmpty) {\n            saveTarget.originalUri.toUri().filename(context)\n                ?.substringBeforeLast('.').orEmpty()\n        } else \"\"\n\n        val presetInfo =\n            if (settingsState.addPresetInfoToFilename && saveTarget.presetInfo != null && saveTarget.presetInfo != Preset.None) {\n                saveTarget.presetInfo?.asString().orEmpty()\n            } else \"\"\n\n        val scaleModeInfo =\n            if (settingsState.addImageScaleModeInfoToFilename && saveTarget.imageInfo.imageScaleMode != ImageScaleMode.NotPresent) {\n                getStringLocalized(\n                    resId = saveTarget.imageInfo.imageScaleMode.title,\n                    language = Locale.ENGLISH.language\n                ).replace(\" \", \"-\")\n            } else \"\"\n\n        val randomNumber: (count: Int) -> String = { count ->\n            buildString {\n                repeat(count.coerceAtMost(500)) {\n                    append(random.nextInt(0, 10))\n                }\n            }.take(count)\n        }\n\n        val timestampString = if (settingsState.addTimestampToFilename) {\n            if (settingsState.useFormattedFilenameTimestamp) {\n                \"${timestamp()}_${randomNumber(4)}\"\n            } else Date().time.toString()\n        } else \"\"\n\n        val sequenceNumber = saveTarget.sequenceNumber?.toString() ?: \"\"\n\n        var result = pattern\n\n        runCatching {\n            result = result.replace(\"\"\"\\\\d\\{(.*?)\\}\"\"\".toRegex()) { match ->\n                if (settingsState.addTimestampToFilename) {\n                    timestamp(\n                        format = match.groupValues[1]\n                    )\n                } else {\n                    \"\"\n                }\n            }\n\n            result = result.replace(\"\"\"\\\\D\\{(.*?)\\}\"\"\".toRegex()) { match ->\n                if (settingsState.addTimestampToFilename) {\n                    timestamp(\n                        format = match.groupValues[1]\n                    ).uppercase()\n                } else {\n                    \"\"\n                }\n            }\n        }.onFailure {\n            it.makeLog(\"pattern date\")\n        }\n\n        runCatching {\n            result = result.replace(\"\"\"\\\\r\\{(\\d+)\\}\"\"\".toRegex()) { match ->\n                randomNumber(match.groupValues[1].toIntOrNull() ?: 4)\n            }\n        }.onFailure {\n            it.makeLog(\"pattern random\")\n        }\n\n        return result\n            .replace(Width, widthString)\n            .replace(Height, heightString)\n            .replace(Prefix, prefix)\n            .replace(Suffix, suffix)\n            .replace(OriginalName, originalName)\n            .replace(Sequence, sequenceNumber)\n            .replace(PresetInfo, presetInfo)\n            .replace(ScaleMode, scaleModeInfo)\n            .replace(Extension, extension)\n            .replace(Rand, randomNumber(4))\n            .replace(Date, timestampString)\n            .replace(PrefixUpper, prefix.uppercase())\n            .replace(SuffixUpper, suffix.uppercase())\n            .replace(OriginalNameUpper, originalName.uppercase())\n            .replace(PresetInfoUpper, presetInfo.uppercase())\n            .replace(ScaleModeUpper, scaleModeInfo.uppercase())\n            .replace(ExtensionUpper, extension.uppercase())\n            .replace(DateUpper, timestampString.uppercase())\n            .clean()\n            .let { str ->\n                if (str.split(\".\").filter { it.isNotBlank() }.size < 2) {\n                    \"image${randomNumber(4)}.$extension\"\n                } else {\n                    str\n                }\n            }\n            .clean()\n    }\n\n    private fun String.clean(): String = this\n        .replace(\"[]\", \"\")\n        .replace(\"{}\", \"\")\n        .replace(\"()x()\", \"\")\n        .replace(\"()\", \"\")\n        .replace(\"___\", \"_\")\n        .replace(\"__\", \"_\")\n        .replace(\"_.\", \".\")\n        .removePrefix(\"_\")\n\n    override fun constructRandomFilename(\n        extension: String,\n        length: Int\n    ): String = \"${randomStringGenerator.generate(length)}.${extension}\"\n\n    override fun getFilename(uri: String): String = uri.toUri().filename(context) ?: \"\"\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/AndroidKeepAliveService.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving\n\nimport android.content.Context\nimport android.content.Intent\nimport androidx.core.content.ContextCompat\nimport com.t8rin.imagetoolbox.core.data.saving.KeepAliveForegroundService.Companion.ACTION_STOP\nimport com.t8rin.imagetoolbox.core.data.saving.KeepAliveForegroundService.Companion.ACTION_UPDATE\nimport com.t8rin.imagetoolbox.core.data.saving.KeepAliveForegroundService.Companion.EXTRA_DESC\nimport com.t8rin.imagetoolbox.core.data.saving.KeepAliveForegroundService.Companion.EXTRA_PROGRESS\nimport com.t8rin.imagetoolbox.core.data.saving.KeepAliveForegroundService.Companion.EXTRA_REMOVE_NOTIFICATION\nimport com.t8rin.imagetoolbox.core.data.saving.KeepAliveForegroundService.Companion.EXTRA_TITLE\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.utils.tryAll\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport javax.inject.Inject\n\ninternal class AndroidKeepAliveService @Inject constructor(\n    @ApplicationContext private val context: Context\n) : KeepAliveService {\n\n    private val baseIntent: Intent\n        get() = Intent(context, KeepAliveForegroundService::class.java)\n\n    override fun updateOrStart(\n        title: String,\n        description: String,\n        progress: Float\n    ) {\n        val intent = baseIntent\n            .setAction(ACTION_UPDATE)\n            .putExtra(EXTRA_TITLE, title)\n            .putExtra(EXTRA_DESC, description)\n            .putExtra(EXTRA_PROGRESS, progress)\n\n        tryAll(\n            { ContextCompat.startForegroundService(context, intent) },\n            { context.startService(intent) }\n        )\n    }\n\n    override fun stop(removeNotification: Boolean) {\n        val intent = baseIntent\n            .setAction(ACTION_STOP)\n            .putExtra(EXTRA_REMOVE_NOTIFICATION, removeNotification)\n\n        tryAll(\n            { context.startService(intent) },\n            { context.stopService(intent) }\n        )\n    }\n\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/KeepAliveForegroundService.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving\n\nimport android.app.Notification\nimport android.app.NotificationChannel\nimport android.app.NotificationManager\nimport android.app.PendingIntent\nimport android.app.Service\nimport android.content.Intent\nimport android.content.pm.ServiceInfo\nimport android.os.Build\nimport android.os.Handler\nimport android.os.Looper\nimport androidx.core.app.NotificationCompat\nimport androidx.core.app.ServiceCompat\nimport androidx.core.content.getSystemService\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.logger.makeLog\nimport kotlin.math.roundToInt\n\ninternal class KeepAliveForegroundService : Service() {\n\n    private val notificationManager: NotificationManager by lazy {\n        getSystemService<NotificationManager>()!!\n    }\n    private var title = \"\"\n    private var description = \"\"\n    private var progress: Float = KeepAliveService.PROGRESS_NO_PROGRESS\n    private var removeNotification: Boolean = true\n\n    override fun onCreate() {\n        super.onCreate()\n        createChannel()\n        startForeground()\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        stopForegroundSafe()\n    }\n\n    override fun onStartCommand(\n        intent: Intent?,\n        flags: Int,\n        startId: Int\n    ): Int {\n        if (intent == null) {\n            startForeground()\n            Handler(Looper.getMainLooper()).postDelayed(\n                ::stopForegroundSafe,\n                1000\n            )\n            return START_NOT_STICKY\n        }\n\n        handleIntent(intent)\n\n        return START_NOT_STICKY\n    }\n\n    private fun handleIntent(intent: Intent) {\n        when (intent.action.makeLog(\"KeepAliveForegroundService\")) {\n            ACTION_UPDATE -> {\n                title = intent.getStringExtra(EXTRA_TITLE) ?: title\n                description = intent.getStringExtra(EXTRA_DESC) ?: description\n                progress = intent.getFloatExtra(\n                    EXTRA_PROGRESS,\n                    KeepAliveService.PROGRESS_NO_PROGRESS\n                )\n\n                \"UPDATE: title = $title, description = $description, progress = $progress\".makeLog(\"KeepAliveForegroundService\")\n\n                startForeground()\n            }\n\n            ACTION_STOP -> {\n                startForeground()\n\n                removeNotification = intent.getBooleanExtra(\n                    EXTRA_REMOVE_NOTIFICATION, true\n                ).makeLog(\"KeepAliveForegroundService\")\n\n                Handler(Looper.getMainLooper()).postDelayed(\n                    ::stopForegroundSafe,\n                    1000\n                )\n            }\n\n            else -> startForeground()\n        }\n    }\n\n    private fun startForeground() {\n        val action = {\n            ServiceCompat.startForeground(\n                this,\n                NOTIFICATION_ID,\n                buildNotification(),\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {\n                    ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC\n                } else {\n                    0\n                }\n            )\n        }\n        runCatching {\n            action()\n        }.onFailure {\n            action()\n            it.makeLog()\n            \"startForeground failed\".makeLog(\"KeepAliveForegroundService\")\n        }\n    }\n\n    private fun createChannel() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            val channel = NotificationChannel(\n                CHANNEL_ID,\n                getString(R.string.processing_channel),\n                NotificationManager.IMPORTANCE_LOW\n            ).apply {\n                setSound(null, null)\n                enableVibration(false)\n            }\n            notificationManager.createNotificationChannel(channel)\n        }\n    }\n\n    @Suppress(\"DEPRECATION\")\n    private fun stopForegroundSafe() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n            stopForeground(\n                if (removeNotification) {\n                    STOP_FOREGROUND_REMOVE\n                } else {\n                    STOP_FOREGROUND_DETACH\n                }\n            )\n        } else {\n            stopForeground(removeNotification)\n        }\n        if (removeNotification) {\n            notificationManager.cancel(NOTIFICATION_ID)\n        }\n        stopSelf()\n    }\n\n    private fun buildNotification(): Notification {\n        val launchIntent = Intent(\n            this, Class.forName(\n                \"com.t8rin.imagetoolbox.app.presentation.AppActivity\"\n            )\n        ).apply {\n            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP\n        }\n        val contentPendingIntent = PendingIntent.getActivity(\n            this,\n            0,\n            launchIntent,\n            PendingIntent.FLAG_UPDATE_CURRENT or (PendingIntent.FLAG_IMMUTABLE)\n        )\n\n        return NotificationCompat.Builder(this, CHANNEL_ID)\n            .setContentTitle(title.ifEmpty { getString(R.string.processing) })\n            .setContentText(description.takeIf { it.isNotEmpty() })\n            .setSmallIcon(R.drawable.ic_notification_icon)\n            .run {\n                when (progress) {\n                    KeepAliveService.PROGRESS_NO_PROGRESS -> this\n                    KeepAliveService.PROGRESS_INDETERMINATE -> setProgress(0, 0, true)\n                    else -> setProgress(100, (progress * 100).roundToInt(), false)\n                }\n            }\n            .setOngoing(true)\n            .setContentIntent(contentPendingIntent)\n            .build()\n            .also { notification ->\n                runCatching {\n                    notificationManager.notify(NOTIFICATION_ID, notification)\n                }.onFailure { it.makeLog(\"KeepAliveForegroundService\") }\n            }\n    }\n\n    override fun onBind(intent: Intent?) = null\n\n    companion object {\n        internal const val CHANNEL_ID = \"keep_alive_channel\"\n        internal const val NOTIFICATION_ID = 1\n\n        internal const val ACTION_STOP = \"ACTION_STOP\"\n        internal const val ACTION_UPDATE = \"ACTION_UPDATE\"\n        internal const val EXTRA_TITLE = \"EXTRA_TITLE\"\n        internal const val EXTRA_DESC = \"EXTRA_DESC\"\n        internal const val EXTRA_PROGRESS = \"EXTRA_PROGRESS\"\n        internal const val EXTRA_REMOVE_NOTIFICATION = \"REMOVE_NOTIFICATION\"\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/SaveException.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving\n\nclass SaveException(override val message: String?) : Throwable(message)"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/SavingFolder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving\n\nimport android.content.ContentValues\nimport android.content.Context\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Environment\nimport android.provider.MediaStore\nimport androidx.core.net.toUri\nimport androidx.documentfile.provider.DocumentFile\nimport com.t8rin.imagetoolbox.core.data.saving.io.StreamWriteable\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport kotlinx.coroutines.coroutineScope\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.io.OutputStream\n\n@ConsistentCopyVisibility\ninternal data class SavingFolder private constructor(\n    val outputStream: OutputStream,\n    val fileUri: Uri\n) : StreamWriteable by StreamWriteable(outputStream) {\n    companion object {\n        suspend fun getInstance(\n            context: Context,\n            treeUri: Uri?,\n            saveTarget: SaveTarget\n        ): SavingFolder? = coroutineScope {\n            if (treeUri == null) {\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                    val type = saveTarget.mimeType.entry\n                    val path = \"${Environment.DIRECTORY_DOCUMENTS}/ImageToolbox\"\n                    val contentValues = ContentValues().apply {\n                        put(MediaStore.MediaColumns.DISPLAY_NAME, saveTarget.filename)\n                        put(\n                            MediaStore.MediaColumns.MIME_TYPE,\n                            type\n                        )\n                        put(\n                            MediaStore.MediaColumns.RELATIVE_PATH,\n                            path\n                        )\n                    }\n                    val imageUri = context.contentResolver.insert(\n                        MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY),\n                        contentValues\n                    ) ?: return@coroutineScope null\n\n                    SavingFolder(\n                        outputStream = context.contentResolver.openOutputStream(imageUri)\n                            ?: return@coroutineScope null,\n                        fileUri = imageUri\n                    )\n                } else {\n                    val imagesDir = File(\n                        Environment.getExternalStoragePublicDirectory(\n                            Environment.DIRECTORY_DOCUMENTS\n                        ), \"ImageToolbox\"\n                    )\n                    if (!imagesDir.exists()) imagesDir.mkdir()\n\n                    val filename = saveTarget.filename ?: return@coroutineScope null\n\n                    SavingFolder(\n                        outputStream = FileOutputStream(File(imagesDir, filename)),\n                        fileUri = File(imagesDir, filename).toUri()\n                    )\n                }\n            } else if (DocumentFile.isDocumentUri(context, treeUri)) {\n                SavingFolder(\n                    outputStream = context.contentResolver.openOutputStream(treeUri)\n                        ?: return@coroutineScope null,\n                    fileUri = treeUri\n                )\n            } else {\n                val documentFile = DocumentFile.fromTreeUri(context, treeUri)\n\n                if (documentFile == null || !documentFile.exists()) return@coroutineScope null\n\n                val filename = saveTarget.filename ?: return@coroutineScope null\n\n                val file = documentFile.createFile(saveTarget.mimeType.entry, filename)\n\n                val imageUri = file?.uri ?: return@coroutineScope null\n\n                SavingFolder(\n                    outputStream = context.contentResolver.openOutputStream(imageUri)\n                        ?: return@coroutineScope null,\n                    fileUri = imageUri\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/io/FileWriteable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving.io\n\nimport java.io.File\n\nclass FileWriteable(\n    private val file: File\n) : StreamWriteable by StreamWriteable(file.outputStream())\n\nclass FileReadable(\n    private val file: File\n) : StreamReadable by StreamReadable(file.inputStream())"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/io/StreamWriteable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving.io\n\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Readable\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\nimport com.t8rin.logger.makeLog\nimport java.io.InputStream\nimport java.io.OutputStream\n\nprivate class StreamWriteableImpl(\n    outputStream: OutputStream\n) : StreamWriteable {\n\n    override val stream = outputStream\n\n    override fun writeBytes(byteArray: ByteArray) = stream.write(byteArray)\n\n    override fun close() {\n        stream.flush()\n        stream.close()\n    }\n\n}\n\nprivate class StreamReadableImpl(\n    inputStream: InputStream\n) : StreamReadable {\n\n    override val stream = inputStream\n\n    override fun readBytes(): ByteArray = stream.readBytes()\n\n    override fun copyTo(writeable: Writeable) {\n        if (writeable is StreamWriteable) {\n            stream.copyTo(writeable.stream)\n        } else {\n            writeable.writeBytes(readBytes())\n        }\n    }\n\n    override fun close() = stream.close()\n\n}\n\ninterface StreamReadable : Readable {\n    val stream: InputStream\n\n    companion object {\n        operator fun invoke(\n            inputStream: InputStream\n        ): StreamReadable = StreamReadableImpl(inputStream)\n    }\n}\n\ninterface StreamWriteable : Writeable {\n    val stream: OutputStream\n\n    companion object {\n        operator fun invoke(\n            outputStream: OutputStream\n        ): StreamWriteable = StreamWriteableImpl(outputStream)\n    }\n}\n\nfun StreamWriteable.shielded(): StreamWriteable = CloseShieldWriteable(this)\n\nprivate class CloseShieldWriteable(wrapped: StreamWriteable) : StreamWriteable by wrapped {\n    override fun close() {\n        \"can't be closed\".makeLog(\"CloseShieldWriteable\")\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/saving/io/UriReadable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.saving.io\n\nimport android.content.Context\nimport android.net.Uri\nimport com.t8rin.imagetoolbox.core.data.utils.openWriteableStream\nimport com.t8rin.logger.makeLog\nimport io.ktor.utils.io.charsets.Charset\nimport java.io.ByteArrayOutputStream\n\n\nclass UriReadable(\n    private val uri: Uri,\n    private val context: Context\n) : StreamReadable by StreamReadable(\n    inputStream = context.contentResolver.openInputStream(uri) ?: ByteArray(0).inputStream()\n)\n\nclass UriWriteable(\n    private val uri: Uri,\n    private val context: Context\n) : StreamWriteable by StreamWriteable(\n    outputStream = context.openWriteableStream(\n        uri = uri,\n        onFailure = {\n            uri.makeLog(\"UriWriteable write\")\n            it.makeLog(\"UriWriteable write\")\n            throw it\n        }\n    ) ?: ByteArrayOutputStream(0)\n)\n\nclass ByteArrayReadable(\n    private val byteArray: ByteArray\n) : StreamReadable by StreamReadable(\n    inputStream = byteArray.inputStream()\n)\n\nclass StringReadable(\n    private val string: String,\n    private val charset: Charset = Charsets.UTF_8\n) : StreamReadable by ByteArrayReadable(\n    byteArray = string.toByteArray(charset)\n)"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/BitmapUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\nimport android.os.Build\nimport android.os.Build.VERSION.SDK_INT\nimport androidx.core.graphics.drawable.toBitmap\nimport coil3.Image\nimport java.io.ByteArrayOutputStream\n\nprivate val possibleConfigs = mutableListOf<Bitmap.Config>().apply {\n    if (SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n        add(Bitmap.Config.RGBA_1010102)\n    }\n    if (SDK_INT >= Build.VERSION_CODES.O) {\n        add(Bitmap.Config.RGBA_F16)\n    }\n    add(Bitmap.Config.ARGB_8888)\n    add(Bitmap.Config.RGB_565)\n}\n\nfun getSuitableConfig(\n    image: Bitmap? = null\n): Bitmap.Config = image?.config?.takeIf {\n    it in possibleConfigs\n} ?: Bitmap.Config.ARGB_8888\n\nfun Bitmap.toSoftware(): Bitmap = copy(getSuitableConfig(this), false) ?: this\n\nval Bitmap.aspectRatio: Float get() = width / height.toFloat()\n\nval Image.aspectRatio: Float get() = width / height.toFloat()\n\nval Drawable.aspectRatio: Float get() = intrinsicWidth / intrinsicHeight.toFloat()\n\nval Bitmap.safeAspectRatio: Float\n    get() = aspectRatio\n        .coerceAtLeast(0.005f)\n        .coerceAtMost(1000f)\n\nval Bitmap.safeConfig: Bitmap.Config\n    get() = config ?: getSuitableConfig(this)\n\nval Drawable.safeAspectRatio: Float\n    get() = aspectRatio\n        .coerceAtLeast(0.005f)\n        .coerceAtMost(1000f)\n\nfun Drawable.toBitmap(): Bitmap = toBitmap(config = getSuitableConfig())\n\nfun Bitmap.compress(\n    format: Bitmap.CompressFormat,\n    quality: Int\n): ByteArray = ByteArrayOutputStream().apply {\n    use { out ->\n        compress(format, quality, out)\n    }\n}.toByteArray()\n\nval Bitmap.Config.isHardware: Boolean\n    get() = SDK_INT >= 26 && this == Bitmap.Config.HARDWARE\n\nfun Bitmap.Config?.toSoftware(): Bitmap.Config {\n    return if (this == null || isHardware) Bitmap.Config.ARGB_8888 else this\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/ChecksumUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport com.t8rin.imagetoolbox.core.data.saving.io.StreamReadable\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Readable\nimport java.io.InputStream\nimport java.security.MessageDigest\n\nprivate const val STREAM_BUFFER_LENGTH = 1024\n\nfun HashingType.computeBytesFromReadable(\n    readable: Readable\n): ByteArray = if (readable is StreamReadable) {\n    computeBytesFromInputStream(readable.stream)\n} else {\n    computeBytesFromByteArray(readable.readBytes())\n}\n\nfun HashingType.computeFromReadable(\n    readable: Readable\n): String = if (readable is StreamReadable) {\n    computeFromInputStream(readable.stream)\n} else {\n    computeFromByteArray(readable.readBytes())\n}\n\ninternal fun HashingType.computeFromByteArray(\n    byteArray: ByteArray\n): String = computeFromInputStream(byteArray.inputStream())\n\ninternal fun HashingType.computeFromInputStream(\n    inputStream: InputStream\n): String = inputStream.buffered().use {\n    val byteArray = updateDigest(it).digest()\n    val hexCode = encodeHex(byteArray, true)\n\n    return@use String(hexCode)\n}\n\ninternal fun HashingType.computeBytesFromByteArray(\n    byteArray: ByteArray\n): ByteArray = computeBytesFromInputStream(byteArray.inputStream())\n\ninternal fun HashingType.computeBytesFromInputStream(\n    inputStream: InputStream\n): ByteArray = inputStream.buffered().use {\n    return@use updateDigest(it).digest()\n}\n\n/**\n * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.\n * The returned array will be double the length of the passed array, as it takes two characters to represent any\n * given byte.\n *\n * @param data a byte[] to convert to Hex characters\n * @param toLowerCase `true` converts to lowercase, `false` to uppercase\n * @return A char[] containing hexadecimal characters in the selected case\n */\ninternal fun encodeHex(\n    data: ByteArray,\n    toLowerCase: Boolean\n): CharArray = encodeHex(\n    data = data,\n    toDigits = if (toLowerCase) {\n        DIGITS_LOWER\n    } else {\n        DIGITS_UPPER\n    }\n)\n\n/**\n * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.\n * The returned array will be double the length of the passed array, as it takes two characters to represent any\n * given byte.\n *\n * @param data a byte[] to convert to Hex characters\n * @param toDigits the output alphabet (must contain at least 16 chars)\n * @return A char[] containing the appropriate characters from the alphabet\n *         For best results, this should be either upper- or lower-case hex.\n */\ninternal fun encodeHex(\n    data: ByteArray,\n    toDigits: CharArray\n): CharArray {\n    val l = data.size\n    val out = CharArray(l shl 1)\n    // two characters form the hex value.\n    var i = 0\n    var j = 0\n    while (i < l) {\n        out[j++] = toDigits[0xF0 and data[i].toInt() ushr 4]\n        out[j++] = toDigits[0x0F and data[i].toInt()]\n        i++\n    }\n    return out\n}\n\n/**\n * Reads through an InputStream and updates the digest for the data\n *\n * @param HashingType The ChecksumType to use (e.g. MD5)\n * @param data Data to digest\n * @return the digest\n */\nprivate fun HashingType.updateDigest(\n    data: InputStream\n): MessageDigest {\n    val digest = toDigest()\n\n    val buffer = ByteArray(STREAM_BUFFER_LENGTH)\n    var read = data.read(buffer, 0, STREAM_BUFFER_LENGTH)\n    while (read > -1) {\n        digest.update(buffer, 0, read)\n        read = data.read(buffer, 0, STREAM_BUFFER_LENGTH)\n    }\n    return digest\n}\n\n/**\n * Used to build output as Hex\n */\nprivate val DIGITS_LOWER =\n    charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')\n\n/**\n * Used to build output as Hex\n */\nprivate val DIGITS_UPPER =\n    charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')\n\n\nprivate fun HashingType.toDigest(): MessageDigest = MessageDigest.getInstance(digest)"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/CoilUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport android.graphics.Bitmap\nimport coil3.size.Size\nimport coil3.size.pxOrElse\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport coil3.transform.Transformation as CoilTransformation\n\nfun Size.asDomain(): IntegerSize = if (this == Size.ORIGINAL) IntegerSize.Undefined\nelse IntegerSize(width.pxOrElse { 1 }, height.pxOrElse { 1 })\n\nfun IntegerSize.asCoil(): Size = if (this == IntegerSize.Undefined) Size.ORIGINAL\nelse Size(width, height)\n\nfun Transformation<Bitmap>.toCoil(): CoilTransformation = object : CoilTransformation() {\n    override fun toString(): String = this@toCoil::class.simpleName.toString()\n\n    override val cacheKey: String\n        get() = this@toCoil.cacheKey\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: Size\n    ): Bitmap = this@toCoil.transform(input, size.asDomain())\n\n}\n\nfun CoilTransformation.asDomain(): Transformation<Bitmap> = object : Transformation<Bitmap> {\n    override val cacheKey: String\n        get() = this@asDomain.cacheKey\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = this@asDomain.transform(input, size.asCoil())\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/ContextUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport android.Manifest\nimport android.content.Context\nimport android.content.pm.PackageManager\nimport android.net.Uri\nimport android.os.Build\nimport androidx.compose.ui.unit.Density\nimport androidx.core.content.ContextCompat\nimport com.t8rin.imagetoolbox.core.domain.utils.FileMode\nimport kotlinx.coroutines.coroutineScope\nimport java.io.OutputStream\n\nfun Context.isExternalStorageWritable(): Boolean {\n    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) true\n    else ContextCompat.checkSelfPermission(\n        this,\n        Manifest.permission.WRITE_EXTERNAL_STORAGE\n    ) == PackageManager.PERMISSION_GRANTED\n}\n\nfun Context.openWriteableStream(\n    uri: Uri?,\n    onFailure: (Throwable) -> Unit = {}\n): OutputStream? = uri?.let {\n    runCatching {\n        openOutputStream(\n            uri = uri,\n            mode = FileMode.ReadWrite\n        )\n    }.getOrElse {\n        runCatching {\n            openOutputStream(\n                uri = uri,\n                mode = FileMode.Write\n            )\n        }.onFailure(onFailure).getOrNull()\n    }\n}\n\nfun Context.openFileDescriptor(uri: Uri, mode: FileMode = FileMode.Read) =\n    contentResolver.openFileDescriptor(uri, mode.mode)\n\nfun Context.openOutputStream(uri: Uri, mode: FileMode) =\n    contentResolver.openOutputStream(uri, mode.mode)\n\ninternal suspend fun Context.clearCache() = coroutineScope {\n    runCatching {\n        cacheDir?.deleteRecursively()\n        codeCacheDir?.deleteRecursively()\n        externalCacheDir?.deleteRecursively()\n        externalCacheDirs?.forEach {\n            it.deleteRecursively()\n        }\n    }\n}\n\ninternal fun Context.cacheSize(): Long = runCatching {\n    val cache =\n        cacheDir?.walkTopDown()?.sumOf { if (it.isFile) it.length() else 0 } ?: 0\n    val code =\n        codeCacheDir?.walkTopDown()?.sumOf { if (it.isFile) it.length() else 0 } ?: 0\n    var size = cache + code\n    externalCacheDirs?.forEach { file ->\n        size += file?.walkTopDown()?.sumOf { if (it.isFile) it.length() else 0 } ?: 0\n    }\n\n    size\n}.getOrNull() ?: 0\n\n\nfun Context.isInstalledFromPlayStore(): Boolean = verifyInstallerId(\n    listOf(\n        \"com.android.vending\",\n        \"com.google.android.feedback\"\n    )\n)\n\nprivate fun Context.verifyInstallerId(\n    validInstallers: List<String>,\n): Boolean = validInstallers.contains(getInstallerPackageName(packageName))\n\nprivate fun Context.getInstallerPackageName(\n    packageName: String\n): String? = runCatching {\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {\n        packageManager.getInstallSourceInfo(packageName).installingPackageName\n    } else {\n        @Suppress(\"DEPRECATION\")\n        packageManager.getInstallerPackageName(packageName)\n    }\n}.getOrNull()\n\nval Context.density: Density\n    get() = object : Density {\n        override val density: Float\n            get() = resources.displayMetrics.density\n        override val fontScale: Float\n            get() = resources.configuration.fontScale\n    }"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/CoroutinesUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport kotlinx.coroutines.asCoroutineDispatcher\nimport java.util.concurrent.ExecutorService\nimport kotlin.coroutines.CoroutineContext\n\ninline fun executorDispatcher(\n    executor: () -> ExecutorService\n): CoroutineContext = executor().asCoroutineDispatcher()"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/FileUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport android.os.Build\nimport android.os.FileObserver\nimport kotlinx.coroutines.channels.awaitClose\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.callbackFlow\nimport java.io.File\n\n@Suppress(\"DEPRECATION\")\nfun File.observeHasChanges(\n    flags: Int = FileObserver.ALL_EVENTS\n): Flow<Unit> = callbackFlow {\n    val observer = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n        object : FileObserver(this@observeHasChanges, flags) {\n            override fun onEvent(event: Int, path: String?) {\n                trySend(Unit)\n            }\n        }\n    } else {\n        object : FileObserver(absolutePath, flags) {\n            override fun onEvent(event: Int, path: String?) {\n                trySend(Unit)\n            }\n        }\n    }\n    send(Unit)\n    observer.startWatching()\n    awaitClose { observer.stopWatching() }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/HttpClientUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport io.ktor.client.HttpClient\nimport io.ktor.client.plugins.onDownload\nimport io.ktor.client.request.prepareGet\nimport io.ktor.client.statement.bodyAsChannel\nimport io.ktor.utils.io.ByteReadChannel\nimport kotlinx.coroutines.supervisorScope\n\nsuspend fun HttpClient.getWithProgress(\n    url: String,\n    onFailure: suspend (Throwable) -> Unit = {},\n    onProgress: suspend (bytesSentTotal: Long, contentLength: Long?) -> Unit,\n    onOpen: suspend (ByteReadChannel) -> Unit\n) = supervisorScope {\n    runSuspendCatching {\n        prepareGet(\n            urlString = url,\n            block = {\n                onDownload(onProgress)\n            }\n        ).execute { response ->\n            onOpen(response.bodyAsChannel())\n        }\n    }.onFailure {\n        onFailure(it)\n    }\n}"
  },
  {
    "path": "core/data/src/main/java/com/t8rin/imagetoolbox/core/data/utils/WriteableUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.data.utils\n\nimport com.t8rin.imagetoolbox.core.data.saving.io.StreamWriteable\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\nimport java.io.OutputStream\n\nfun Writeable.outputStream(): OutputStream = if (this is StreamWriteable) {\n    stream\n} else {\n    object : OutputStream() {\n        override fun write(b: Int) = writeBytes(byteArrayOf(b.toByte()))\n    }\n}"
  },
  {
    "path": "core/di/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/di/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.di\""
  },
  {
    "path": "core/di/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "core/di/src/main/java/com/t8rin/imagetoolbox/core/di/EntryPointUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.di\n\nimport android.content.Context\nimport dagger.hilt.android.EntryPointAccessors\n\ninline fun <reified T> Context.entryPoint(\n    action: T.() -> Unit = {}\n) = action(\n    EntryPointAccessors.fromApplication(\n        context = this,\n        entryPoint = T::class.java\n    )\n)"
  },
  {
    "path": "core/di/src/main/java/com/t8rin/imagetoolbox/core/di/Qualifiers.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.di\n\nimport javax.inject.Qualifier\n\n@Qualifier\n@Retention(AnnotationRetention.RUNTIME)\nannotation class DefaultDispatcher\n\n@Qualifier\n@Retention(AnnotationRetention.RUNTIME)\nannotation class EncodingDispatcher\n\n@Qualifier\n@Retention(AnnotationRetention.RUNTIME)\nannotation class DecodingDispatcher\n\n@Qualifier\n@Retention(AnnotationRetention.RUNTIME)\nannotation class IoDispatcher\n\n@Qualifier\n@Retention(AnnotationRetention.RUNTIME)\nannotation class UiDispatcher"
  },
  {
    "path": "core/domain/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/domain/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.domain\"\n\ndependencies {\n    implementation(projects.core.resources)\n}"
  },
  {
    "path": "core/domain/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/Constants.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain\n\nconst val AUTHOR_NICK = \"T8RIN\"\n\nconst val AUTHOR_TELEGRAM = \"http://t.me/$AUTHOR_NICK\"\nconst val TELEGRAM_GROUP_LINK = \"https://t.me/t8rin_imagetoolbox\"\nconst val TELEGRAM_CHANNEL_LINK = \"https://t.me/t8rin_imagetoolbox_ci\"\n\n\nconst val AUTHOR_GITHUB = \"https://github.com/$AUTHOR_NICK\"\nconst val APP_GITHUB_LINK = \"$AUTHOR_GITHUB/ImageToolbox\"\nconst val ISSUE_TRACKER = \"$APP_GITHUB_LINK/issues\"\nconst val APP_RELEASES = \"$APP_GITHUB_LINK/releases\"\nconst val APP_CHANGELOG = \"$APP_RELEASES.atom\"\n\n\nconst val RES_HOST = \"$AUTHOR_GITHUB/ImageToolboxRemoteResources\"\nconst val LENS_PROFILES_LINK = \"$RES_HOST/tree/main/lens_profile\"\nconst val RES_BASE_URL = \"$RES_HOST/raw/refs/heads/main/*\"\nconst val HF_BASE_URL = \"https://huggingface.co/T8RIN/imagetoolbox-models/resolve/main/*\"\n\n\nconst val GLOBAL_STORAGE_NAME = \"image_resizer\"\nconst val BACKUP_FILE_EXT = \"imtbx_backup\"\nconst val PDF = \"pdf/\"\n\n\nconst val WEBLATE_LINK = \"https://hosted.weblate.org/engage/image-resizer/\"\nconst val PARTNER_FREE_SOFTWARE = \"https://t.me/FreeApkexe\"\nconst val JAVA_FORMAT_SPECIFICATION =\n    \"https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html\"\nconst val USER_AGENT =\n    \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36\"\n\n\nconst val BTC_WALLET = \"18QFWMREkjzQa4yetfYsN5Ua51UubKmJut\"\nconst val USDT_WALLET = \"TVdw6fP8dYsYA6HgQiSYNijBqPJ3k5BbYo\"\nconst val TON_SPACE_WALLET = \"UQDMePBU-FaxwaIME8p7h2spRITeRxvtCPegtKefeV5v-sN1\"\nconst val TON_WALLET = \"UQB8YI7eEJsFkr05juS-Ix1pRxhgRvCDF9S0g_aXayVJoGtg\"\nconst val BOOSTY_LINK = \"https://boosty.to/t8rin\""
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/coroutines/AppScope.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.coroutines\n\nimport kotlinx.coroutines.CoroutineScope\n\ninterface AppScope : CoroutineScope"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/coroutines/DispatchersHolder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.coroutines\n\nimport kotlin.coroutines.CoroutineContext\n\ninterface DispatchersHolder {\n    val uiDispatcher: CoroutineContext\n    val ioDispatcher: CoroutineContext\n    val encodingDispatcher: CoroutineContext\n    val decodingDispatcher: CoroutineContext\n    val defaultDispatcher: CoroutineContext\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/ImageCompressor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninterface ImageCompressor<Image> {\n\n    suspend fun compress(\n        image: Image,\n        imageFormat: ImageFormat,\n        quality: Quality\n    ): ByteArray\n\n    suspend fun compressAndTransform(\n        image: Image,\n        imageInfo: ImageInfo,\n        onImageReadyToCompressInterceptor: suspend (Bitmap) -> Bitmap = { it },\n        applyImageTransformations: Boolean = true\n    ): ByteArray\n\n    suspend fun calculateImageSize(\n        image: Image,\n        imageInfo: ImageInfo\n    ): Long\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/ImageGetter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageData\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\n\ninterface ImageGetter<I> {\n\n    suspend fun getImage(\n        uri: String,\n        originalSize: Boolean = true,\n        onFailure: (Throwable) -> Unit = {}\n    ): ImageData<I>?\n\n    fun getImageAsync(\n        uri: String,\n        originalSize: Boolean = true,\n        onGetImage: (ImageData<I>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    )\n\n    suspend fun getImageWithTransformations(\n        uri: String,\n        transformations: List<Transformation<I>>,\n        originalSize: Boolean = true\n    ): ImageData<I>?\n\n    suspend fun getImageWithTransformations(\n        data: Any,\n        transformations: List<Transformation<I>>,\n        size: IntegerSize?\n    ): I?\n\n    suspend fun getImage(\n        data: Any,\n        originalSize: Boolean = true\n    ): I?\n\n    suspend fun getImage(\n        data: Any,\n        size: IntegerSize?\n    ): I?\n\n    suspend fun getImage(\n        data: Any,\n        size: Int?\n    ): I?\n\n    suspend fun getImageData(\n        uri: String,\n        size: Int?,\n        onFailure: (Throwable) -> Unit\n    ): ImageData<I>?\n\n    fun getExtension(\n        uri: String\n    ): String?\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/ImagePreviewCreator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\n\ninterface ImagePreviewCreator<I> {\n\n    suspend fun createPreview(\n        image: I,\n        imageInfo: ImageInfo,\n        transformations: List<Transformation<I>> = emptyList(),\n        onGetByteCount: (Int) -> Unit\n    ): I?\n\n    fun canShow(image: I?): Boolean\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/ImageScaler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\n\ninterface ImageScaler<I> {\n\n    suspend fun scaleImage(\n        image: I,\n        width: Int,\n        height: Int,\n        resizeType: ResizeType = ResizeType.Explicit,\n        imageScaleMode: ImageScaleMode = ImageScaleMode.NotPresent\n    ): I\n\n    suspend fun scaleUntilCanShow(\n        image: I?\n    ): I?\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/ImageShareProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\n\ninterface ImageShareProvider<I> : ShareProvider {\n\n    suspend fun shareImage(\n        imageInfo: ImageInfo,\n        image: I,\n        onComplete: () -> Unit\n    )\n\n    suspend fun cacheImage(\n        image: I,\n        imageInfo: ImageInfo,\n        filename: String? = null\n    ): String?\n\n    suspend fun shareImages(\n        uris: List<String>,\n        imageLoader: suspend (String) -> Pair<I, ImageInfo>?,\n        onProgressChange: (Int) -> Unit\n    )\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/ImageTransformer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\n\ninterface ImageTransformer<I> {\n\n    suspend fun transform(\n        image: I,\n        transformations: List<Transformation<I>>,\n        originalSize: Boolean = true\n    ): I?\n\n    suspend fun transform(\n        image: I,\n        transformations: List<Transformation<I>>,\n        size: IntegerSize\n    ): I?\n\n    suspend fun rotate(\n        image: I,\n        degrees: Float\n    ): I\n\n    suspend fun flip(\n        image: I,\n        isFlipped: Boolean\n    ): I\n\n    suspend fun applyPresetBy(\n        image: I?,\n        preset: Preset,\n        currentInfo: ImageInfo\n    ): ImageInfo\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/Metadata.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\n\ninterface Metadata {\n    fun saveAttributes(): Metadata\n\n    fun getAttribute(tag: MetadataTag): String?\n\n    fun setAttribute(\n        tag: MetadataTag,\n        value: String?\n    ): Metadata\n}\n\nprivate class TagMapMetadata(\n    initialTags: Map<MetadataTag, String>\n) : Metadata {\n    private val tags: MutableMap<MetadataTag, String> = initialTags.toMutableMap()\n\n    override fun saveAttributes(): Metadata = this\n\n    override fun getAttribute(tag: MetadataTag): String? = tags[tag]\n\n    override fun setAttribute(\n        tag: MetadataTag,\n        value: String?\n    ): Metadata = apply {\n        if (value == null) {\n            tags.remove(tag)\n        } else {\n            tags[tag] = value\n        }\n    }\n\n    override fun toString(): String = \"ReadOnly(${toMap()})\"\n}\n\nfun Metadata.readOnly(): Metadata = TagMapMetadata(toMap())\n\ninline operator fun Metadata.get(\n    tag: MetadataTag\n): String? = getAttribute(tag)\n\ninline operator fun Metadata.set(\n    tag: MetadataTag,\n    value: String?\n): Metadata = setAttribute(tag, value)\n\ninline fun Metadata.clearAttribute(\n    tag: MetadataTag\n) = apply {\n    setAttribute(\n        tag = tag,\n        value = null\n    )\n}\n\ninline fun Metadata.clearAttributes(\n    attributes: List<MetadataTag>\n): Metadata = apply {\n    attributes.forEach(::clearAttribute)\n}\n\ninline fun Metadata.clearAllAttributes(): Metadata =\n    clearAttributes(attributes = MetadataTag.entries)\n\ninline fun Metadata.toMap(): Map<MetadataTag, String> = mutableMapOf<MetadataTag, String>().apply {\n    MetadataTag.entries.forEach { tag ->\n        getAttribute(tag)?.let { put(tag, it) }\n    }\n}\n\ninline fun Metadata.copyTo(\n    metadata: Metadata,\n    tags: List<MetadataTag> = MetadataTag.entries\n): Metadata {\n    tags.forEach { attr ->\n        getAttribute(attr).let { metadata.setAttribute(attr, it) }\n    }\n    metadata.saveAttributes()\n\n    return metadata\n}\n\nfun interface MetadataProvider {\n    suspend fun readMetadata(imageUri: String): Metadata?\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/ShareProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image\n\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\n\ninterface ShareProvider {\n\n    suspend fun cacheByteArray(\n        byteArray: ByteArray,\n        filename: String\n    ): String?\n\n    suspend fun shareByteArray(\n        byteArray: ByteArray,\n        filename: String,\n        onComplete: () -> Unit = {}\n    )\n\n    suspend fun cacheData(\n        filename: String,\n        writeData: suspend (Writeable) -> Unit,\n    ): String?\n\n    suspend fun cacheDataOrThrow(\n        filename: String,\n        writeData: suspend (Writeable) -> Unit,\n    ): String\n\n    suspend fun shareData(\n        writeData: suspend (Writeable) -> Unit,\n        filename: String,\n        onComplete: () -> Unit = {}\n    )\n\n    suspend fun shareUri(\n        uri: String,\n        type: MimeType.Single? = null,\n        onComplete: () -> Unit\n    )\n\n    suspend fun shareUris(\n        uris: List<String>\n    )\n\n    fun shareText(\n        value: String,\n        onComplete: () -> Unit\n    )\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/BlendingMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Color\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.ColorBurn\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.ColorDodge\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Difference\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.DstAtop\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.DstIn\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.DstOut\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.DstOver\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Exclusion\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Hardlight\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Hue\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Luminosity\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Modulate\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Multiply\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Overlay\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Saturation\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Screen\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.Softlight\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.SrcAtop\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.SrcIn\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.SrcOut\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode.Companion.SrcOver\n\n\n@JvmInline\nvalue class BlendingMode internal constructor(val value: Int) {\n\n    companion object {\n\n        /**\n         * Drop both the source and destination images, leaving nothing.\n         */\n        val Clear = BlendingMode(0)\n\n        /**\n         * Drop the destination image, only paint the source image.\n         *\n         * Conceptually, the destination is first cleared, then the source image is\n         * painted.\n         */\n        val Src = BlendingMode(1)\n\n        /**\n         * Drop the source image, only paint the destination image.\n         *\n         * Conceptually, the source image is discarded, leaving the destination\n         * untouched.\n         */\n        val Dst = BlendingMode(2)\n\n        /**\n         * Composite the source image over the destination image.\n         *\n         * This is the default value. It represents the most intuitive case, where\n         * shapes are painted on top of what is below, with transparent areas showing\n         * the destination layer.\n         */\n        val SrcOver = BlendingMode(3)\n\n        /**\n         * Composite the source image under the destination image.\n         *\n         * This is the opposite of [SrcOver].\n         *\n         * This is useful when the source image should have been painted before the\n         * destination image, but could not be.\n         */\n        val DstOver = BlendingMode(4)\n\n        /**\n         * Show the source image, but only where the two images overlap. The\n         * destination image is not rendered, it is treated merely as a mask. The\n         * color channels of the destination are ignored, only the opacity has an\n         * effect.\n         *\n         * To show the destination image instead, consider [DstIn].\n         *\n         * To reverse the semantic of the mask (only showing the source where the\n         * destination is absent, rather than where it is present), consider\n         * [SrcOut].\n         */\n        val SrcIn = BlendingMode(5)\n\n        /**\n         * Show the destination image, but only where the two images overlap. The\n         * source image is not rendered, it is treated merely as a mask. The color\n         * channels of the source are ignored, only the opacity has an effect.\n         *\n         * To show the source image instead, consider [SrcIn].\n         *\n         * To reverse the semantic of the mask (only showing the source where the\n         * destination is present, rather than where it is absent), consider [DstOut].\n         */\n        val DstIn = BlendingMode(6)\n\n        /**\n         * Show the source image, but only where the two images do not overlap. The\n         * destination image is not rendered, it is treated merely as a mask. The color\n         * channels of the destination are ignored, only the opacity has an effect.\n         *\n         * To show the destination image instead, consider [DstOut].\n         *\n         * To reverse the semantic of the mask (only showing the source where the\n         * destination is present, rather than where it is absent), consider [SrcIn].\n         *\n         * This corresponds to the \"Source out Destination\" Porter-Duff operator.\n         */\n        val SrcOut = BlendingMode(7)\n\n        /**\n         * Show the destination image, but only where the two images do not overlap. The\n         * source image is not rendered, it is treated merely as a mask. The color\n         * channels of the source are ignored, only the opacity has an effect.\n         *\n         * To show the source image instead, consider [SrcOut].\n         *\n         * To reverse the semantic of the mask (only showing the destination where the\n         * source is present, rather than where it is absent), consider [DstIn].\n         *\n         * This corresponds to the \"Destination out Source\" Porter-Duff operator.\n         */\n        val DstOut = BlendingMode(8)\n\n        /**\n         * Composite the source image over the destination image, but only where it\n         * overlaps the destination.\n         *\n         * This is essentially the [SrcOver] operator, but with the output's opacity\n         * channel being set to that of the destination image instead of being a\n         * combination of both image's opacity channels.\n         *\n         * For a variant with the destination on top instead of the source, see\n         * [DstAtop].\n         */\n        val SrcAtop = BlendingMode(9)\n\n        /**\n         * Composite the destination image over the source image, but only where it\n         * overlaps the source.\n         *\n         * This is essentially the [DstOver] operator, but with the output's opacity\n         * channel being set to that of the source image instead of being a\n         * combination of both image's opacity channels.\n         *\n         * For a variant with the source on top instead of the destination, see\n         * [SrcAtop].\n         */\n        val DstAtop = BlendingMode(10)\n\n        /**\n         * Apply a bitwise `xor` operator to the source and destination images. This\n         * leaves transparency where they would overlap.\n         */\n        val Xor = BlendingMode(11)\n\n        /**\n         * Sum the components of the source and destination images.\n         *\n         * Transparency in a pixel of one of the images reduces the contribution of\n         * that image to the corresponding output pixel, as if the color of that\n         * pixel in that image was darker.\n         *\n         */\n        val Plus = BlendingMode(12)\n\n        /**\n         * Multiply the color components of the source and destination images.\n         *\n         * This can only result in the same or darker colors (multiplying by white,\n         * 1.0, results in no change; multiplying by black, 0.0, results in black).\n         *\n         * When compositing two opaque images, this has similar effect to overlapping\n         * two transparencies on a projector.\n         *\n         * For a variant that also multiplies the alpha channel, consider [Multiply].\n         *\n         * See also:\n         *\n         *  * [Screen], which does a similar computation but inverted.\n         *  * [Overlay], which combines [Modulate] and [Screen] to favor the\n         *    destination image.\n         *  * [Hardlight], which combines [Modulate] and [Screen] to favor the\n         *    source image.\n         */\n        val Modulate = BlendingMode(13)\n\n        /**\n         * Multiply the inverse of the components of the source and destination\n         * images, and inverse the result.\n         *\n         * Inverting the components means that a fully saturated channel (opaque\n         * white) is treated as the value 0.0, and values normally treated as 0.0\n         * (black, transparent) are treated as 1.0.\n         *\n         * This is essentially the same as [Modulate] blend mode, but with the values\n         * of the colors inverted before the multiplication and the result being\n         * inverted back before rendering.\n         *\n         * This can only result in the same or lighter colors (multiplying by black,\n         * 1.0, results in no change; multiplying by white, 0.0, results in white).\n         * Similarly, in the alpha channel, it can only result in more opaque colors.\n         *\n         * This has similar effect to two projectors displaying their images on the\n         * same screen simultaneously.\n         *\n         * See also:\n         *\n         *  * [Modulate], which does a similar computation but without inverting the\n         *    values.\n         *  * [Overlay], which combines [Modulate] and [Screen] to favor the\n         *    destination image.\n         *  * [Hardlight], which combines [Modulate] and [Screen] to favor the\n         *    source image.\n         */\n        val Screen = BlendingMode(14) // The last coeff mode.\n\n        /**\n         * Multiply the components of the source and destination images after\n         * adjusting them to favor the destination.\n         *\n         * Specifically, if the destination value is smaller, this multiplies it with\n         * the source value, whereas is the source value is smaller, it multiplies\n         * the inverse of the source value with the inverse of the destination value,\n         * then inverts the result.\n         *\n         * Inverting the components means that a fully saturated channel (opaque\n         * white) is treated as the value 0.0, and values normally treated as 0.0\n         * (black, transparent) are treated as 1.0.\n         *\n         * See also:\n         *\n         *  * [Modulate], which always multiplies the values.\n         *  * [Screen], which always multiplies the inverses of the values.\n         *  * [Hardlight], which is similar to [Overlay] but favors the source image\n         *    instead of the destination image.\n         */\n        val Overlay = BlendingMode(15)\n\n        /**\n         * Composite the source and destination image by choosing the lowest value\n         * from each color channel.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver].\n         */\n        val Darken = BlendingMode(16)\n\n        /**\n         * Composite the source and destination image by choosing the highest value\n         * from each color channel.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver].\n         */\n        val Lighten = BlendingMode(17)\n\n        /**\n         * Divide the destination by the inverse of the source.\n         *\n         * Inverting the components means that a fully saturated channel (opaque\n         * white) is treated as the value 0.0, and values normally treated as 0.0\n         * (black, transparent) are treated as 1.0.\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         */\n        val ColorDodge = BlendingMode(18)\n\n        /**\n         * Divide the inverse of the destination by the source, and inverse the result.\n         *\n         * Inverting the components means that a fully saturated channel (opaque\n         * white) is treated as the value 0.0, and values normally treated as 0.0\n         * (black, transparent) are treated as 1.0.\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         */\n        val ColorBurn = BlendingMode(19)\n\n        /**\n         * Multiply the components of the source and destination images after\n         * adjusting them to favor the source.\n         *\n         * Specifically, if the source value is smaller, this multiplies it with the\n         * destination value, whereas is the destination value is smaller, it\n         * multiplies the inverse of the destination value with the inverse of the\n         * source value, then inverts the result.\n         *\n         * Inverting the components means that a fully saturated channel (opaque\n         * white) is treated as the value 0.0, and values normally treated as 0.0\n         * (black, transparent) are treated as 1.0.\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         *\n         * See also:\n         *\n         *  * [Modulate], which always multiplies the values.\n         *  * [Screen], which always multiplies the inverses of the values.\n         *  * [Overlay], which is similar to [Hardlight] but favors the destination\n         *    image instead of the source image.\n         */\n        val Hardlight = BlendingMode(20)\n\n        /**\n         * Use [ColorDodge] for source values below 0.5 and [ColorBurn] for source\n         * values above 0.5.\n         *\n         * This results in a similar but softer effect than [Overlay].\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         *\n         * See also:\n         *\n         *  * [Color], which is a more subtle tinting effect.\n         */\n        val Softlight = BlendingMode(21)\n\n        /**\n         * Subtract the smaller value from the bigger value for each channel.\n         *\n         * Compositing black has no effect; compositing white inverts the colors of\n         * the other image.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver].\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         *\n         * The effect is similar to [Exclusion] but harsher.\n         */\n        val Difference = BlendingMode(22)\n\n        /**\n         * Subtract double the product of the two images from the sum of the two\n         * images.\n         *\n         * Compositing black has no effect; compositing white inverts the colors of\n         * the other image.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver].\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         *\n         * The effect is similar to [Difference] but softer.\n         */\n        val Exclusion = BlendingMode(23)\n\n        /**\n         * Multiply the components of the source and destination images, including\n         * the alpha channel.\n         *\n         * This can only result in the same or darker colors (multiplying by white,\n         * 1.0, results in no change; multiplying by black, 0.0, results in black).\n         *\n         * Since the alpha channel is also multiplied, a fully-transparent pixel\n         * (opacity 0.0) in one image results in a fully transparent pixel in the\n         * output. This is similar to [DstIn], but with the colors combined.\n         *\n         * For a variant that multiplies the colors but does not multiply the alpha\n         * channel, consider [Modulate].\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         */\n        val Multiply = BlendingMode(24) // The last separable mode.\n\n        /**\n         * Take the hue of the source image, and the saturation and luminosity of the\n         * destination image.\n         *\n         * The effect is to tint the destination image with the source image.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver]. Regions that are entirely transparent in the source image take\n         * their hue from the destination.\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         */\n        val Hue = BlendingMode(25)\n\n        /**\n         * Take the saturation of the source image, and the hue and luminosity of the\n         * destination image.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver]. Regions that are entirely transparent in the source image take\n         * their saturation from the destination.\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         *\n         * See also:\n         *\n         *  * [Color], which also applies the hue of the source image.\n         *  * [Luminosity], which applies the luminosity of the source image to the\n         *    destination.\n         */\n        val Saturation = BlendingMode(26)\n\n        /**\n         * Take the hue and saturation of the source image, and the luminosity of the\n         * destination image.\n         *\n         * The effect is to tint the destination image with the source image.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver]. Regions that are entirely transparent in the source image take\n         * their hue and saturation from the destination.\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         *\n         * See also:\n         *\n         *  * [Hue], which is a similar but weaker effect.\n         *  * [Softlight], which is a similar tinting effect but also tints white.\n         *  * [Saturation], which only applies the saturation of the source image.\n         */\n        val Color = BlendingMode(27)\n\n        /**\n         * Take the luminosity of the source image, and the hue and saturation of the\n         * destination image.\n         *\n         * The opacity of the output image is computed in the same way as for\n         * [SrcOver]. Regions that are entirely transparent in the source image take\n         * their luminosity from the destination.\n         *\n         * **NOTE** This [BlendingMode] can only be used on Android API level 29 and above\n         *\n         * See also:\n         *\n         *  * [Saturation], which applies the saturation of the source image to the\n         *    destination.\n         */\n        val Luminosity = BlendingMode(28)\n\n        val newEntries by lazy {\n            listOf(\n                Clear,\n                Src,\n                Dst,\n                SrcOver,\n                DstOver,\n                SrcIn,\n                DstIn,\n                SrcOut,\n                DstOut,\n                SrcAtop,\n                DstAtop,\n                Xor,\n                Plus,\n                Modulate,\n                Screen,\n                Overlay,\n                Darken,\n                Lighten,\n                ColorDodge,\n                ColorBurn,\n                Hardlight,\n                Softlight,\n                Difference,\n                Exclusion,\n                Multiply,\n                Hue,\n                Saturation,\n                Color,\n                Luminosity,\n            )\n        }\n        val oldEntries by lazy {\n            listOf(\n                Clear,\n                Src,\n                Dst,\n                SrcOver,\n                DstOver,\n                SrcIn,\n                DstIn,\n                SrcOut,\n                DstOut,\n                SrcAtop,\n                DstAtop,\n                Xor,\n                Plus,\n                Modulate,\n                Screen,\n                Overlay,\n                Darken,\n                Lighten,\n            )\n        }\n    }\n\n    override fun toString() = when (this) {\n        Clear -> \"Clear\"\n        Src -> \"Src\"\n        Dst -> \"Dst\"\n        SrcOver -> \"SrcOver\"\n        DstOver -> \"DstOver\"\n        SrcIn -> \"SrcIn\"\n        DstIn -> \"DstIn\"\n        SrcOut -> \"SrcOut\"\n        DstOut -> \"DstOut\"\n        SrcAtop -> \"SrcAtop\"\n        DstAtop -> \"DstAtop\"\n        Xor -> \"Xor\"\n        Plus -> \"Plus\"\n        Modulate -> \"Modulate\"\n        Screen -> \"Screen\"\n        Overlay -> \"Overlay\"\n        Darken -> \"Darken\"\n        Lighten -> \"Lighten\"\n        ColorDodge -> \"ColorDodge\"\n        ColorBurn -> \"ColorBurn\"\n        Hardlight -> \"HardLight\"\n        Softlight -> \"Softlight\"\n        Difference -> \"Difference\"\n        Exclusion -> \"Exclusion\"\n        Multiply -> \"Multiply\"\n        Hue -> \"Hue\"\n        Saturation -> \"Saturation\"\n        Color -> \"Color\"\n        Luminosity -> \"Luminosity\"\n        else -> \"Unknown\" // Should not get here since we have an internal constructor\n    }\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ImageData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\n\ninterface ImageData<I> {\n    val image: I\n    val imageInfo: ImageInfo\n    val metadata: Metadata?\n\n    fun copy(\n        image: I = this.image,\n        imageInfo: ImageInfo = this.imageInfo,\n        metadata: Metadata? = this.metadata,\n    ): ImageData<I> = ImageData(image, imageInfo, metadata)\n\n    operator fun component1() = image\n    operator fun component2() = imageInfo\n    operator fun component3() = metadata\n\n    companion object {\n        operator fun <I> invoke(\n            image: I,\n            imageInfo: ImageInfo,\n            metadata: Metadata? = null,\n        ): ImageData<I> = ImageDataWrapper(image, imageInfo, metadata)\n    }\n}\n\nprivate class ImageDataWrapper<I>(\n    override val image: I,\n    override val imageInfo: ImageInfo,\n    override val metadata: Metadata? = null,\n) : ImageData<I>"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ImageFormat.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\n\nsealed class ImageFormat(\n    val title: String,\n    val extension: String,\n    val mimeType: MimeType.Single,\n    val canChangeCompressionValue: Boolean,\n    val canWriteExif: Boolean = false,\n    val compressionTypes: List<CompressionType> = listOf(CompressionType.Quality(0..100))\n) {\n\n    sealed class Png(\n        title: String,\n        compressionTypes: List<CompressionType>,\n        canChangeCompressionValue: Boolean\n    ) : ImageFormat(\n        extension = \"png\",\n        mimeType = MimeType.StaticPng,\n        canChangeCompressionValue = canChangeCompressionValue,\n        title = title,\n        canWriteExif = true,\n        compressionTypes = compressionTypes\n    ) {\n        data object Lossless : Png(\n            title = \"PNG Lossless\",\n            compressionTypes = emptyList(),\n            canChangeCompressionValue = false\n        ), LosslessMarker\n\n        data object Lossy : Png(\n            title = \"PNG Lossy\",\n            compressionTypes = listOf(\n                CompressionType.Effort(0..9)\n            ),\n            canChangeCompressionValue = true\n        )\n\n        data object OxiPNG : Png(\n            title = \"OxiPNG\",\n            compressionTypes = listOf(\n                CompressionType.Effort(0..6)\n            ),\n            canChangeCompressionValue = true\n        )\n    }\n\n    data object Jpg : ImageFormat(\n        title = \"JPG\",\n        extension = \"jpg\",\n        mimeType = MimeType.Jpeg,\n        canChangeCompressionValue = true,\n        canWriteExif = true\n    )\n\n    data object Jpeg : ImageFormat(\n        title = \"JPEG\",\n        extension = \"jpeg\",\n        mimeType = MimeType.Jpeg,\n        canChangeCompressionValue = true,\n        canWriteExif = true\n    )\n\n    data object MozJpeg : ImageFormat(\n        title = \"MozJPEG\",\n        extension = \"jpg\",\n        mimeType = MimeType.Jpeg,\n        canChangeCompressionValue = true,\n        canWriteExif = true\n    )\n\n    data object Jpegli : ImageFormat(\n        title = \"Jpegli\",\n        extension = \"jpg\",\n        mimeType = MimeType.Jpeg,\n        canChangeCompressionValue = true,\n        canWriteExif = true\n    )\n\n    sealed class Webp(\n        title: String,\n        compressionTypes: List<CompressionType>\n    ) : ImageFormat(\n        extension = \"webp\",\n        mimeType = MimeType.Webp,\n        canChangeCompressionValue = true,\n        title = title,\n        canWriteExif = true,\n        compressionTypes = compressionTypes\n    ) {\n        data object Lossless : Webp(\n            title = \"WEBP Lossless\",\n            compressionTypes = listOf(CompressionType.Effort(0..100))\n        ), LosslessMarker\n\n        data object Lossy : Webp(\n            title = \"WEBP Lossy\",\n            compressionTypes = listOf(CompressionType.Quality(0..100))\n        )\n    }\n\n    data object Bmp : ImageFormat(\n        title = \"BMP\",\n        extension = \"bmp\",\n        mimeType = MimeType.Bmp,\n        canChangeCompressionValue = false\n    )\n\n    sealed class Avif(\n        title: String,\n        compressionTypes: List<CompressionType>\n    ) : ImageFormat(\n        title = title,\n        extension = \"avif\",\n        mimeType = MimeType.Avif,\n        canChangeCompressionValue = true,\n        compressionTypes = compressionTypes\n    ) {\n        data object Lossless : Avif(\n            title = \"AVIF Lossless\",\n            compressionTypes = listOf(\n                CompressionType.Effort(0..10)\n            )\n        ), LosslessMarker\n\n        data object Lossy : Avif(\n            title = \"AVIF Lossy\",\n            compressionTypes = listOf(\n                CompressionType.Quality(1..100),\n                CompressionType.Effort(0..10)\n            )\n        )\n    }\n\n    sealed class Heif(\n        title: String,\n        compressionTypes: List<CompressionType>\n    ) : ImageFormat(\n        title = title,\n        extension = \"heif\",\n        mimeType = MimeType.Heif,\n        compressionTypes = compressionTypes,\n        canChangeCompressionValue = compressionTypes.isNotEmpty()\n    ) {\n        data object Lossless : Heif(\n            title = \"HEIF Lossless\",\n            compressionTypes = listOf()\n        ), LosslessMarker\n\n        data object Lossy : Heif(\n            title = \"HEIF Lossy\",\n            compressionTypes = listOf(\n                CompressionType.Quality(0..100)\n            )\n        )\n    }\n\n    sealed class Heic(\n        title: String,\n        compressionTypes: List<CompressionType>\n    ) : ImageFormat(\n        title = title,\n        extension = \"heic\",\n        mimeType = MimeType.Heic,\n        compressionTypes = compressionTypes,\n        canChangeCompressionValue = compressionTypes.isNotEmpty()\n    ) {\n        data object Lossless : Heic(\n            title = \"HEIC Lossless\",\n            compressionTypes = listOf()\n        ), LosslessMarker\n\n        data object Lossy : Heic(\n            title = \"HEIC Lossy\",\n            compressionTypes = listOf(\n                CompressionType.Quality(0..100)\n            )\n        )\n    }\n\n    sealed class Jxl(\n        title: String,\n        compressionTypes: List<CompressionType>\n    ) : ImageFormat(\n        extension = \"jxl\",\n        mimeType = MimeType.Jxl,\n        canChangeCompressionValue = true,\n        title = title,\n        compressionTypes = compressionTypes\n    ) {\n        data object Lossless : Jxl(\n            title = \"JXL Lossless\",\n            compressionTypes = listOf(\n                CompressionType.Effort(1..10)\n            )\n        ), LosslessMarker\n\n        data object Lossy : Jxl(\n            title = \"JXL Lossy\",\n            compressionTypes = listOf(\n                CompressionType.Quality(1..100),\n                CompressionType.Effort(1..10)\n            )\n        )\n    }\n\n    sealed class Jpeg2000(\n        title: String,\n        extension: String\n    ) : ImageFormat(\n        title = title,\n        extension = extension,\n        mimeType = MimeType.Jp2,\n        canChangeCompressionValue = true,\n        compressionTypes = listOf(\n            CompressionType.Quality(20..100)\n        )\n    ) {\n\n        data object Jp2 : Jpeg2000(\n            title = \"JP2\",\n            extension = \"jp2\"\n        )\n\n        data object J2k : Jpeg2000(\n            title = \"J2K\",\n            extension = \"j2k\"\n        )\n\n    }\n\n    data object Tiff : ImageFormat(\n        title = \"TIFF\",\n        extension = \"tiff\",\n        mimeType = MimeType.Tiff,\n        canChangeCompressionValue = true,\n        compressionTypes = emptyList()\n    )\n\n    data object Tif : ImageFormat(\n        title = \"TIF\",\n        extension = \"tif\",\n        mimeType = MimeType.Tiff,\n        canChangeCompressionValue = true,\n        compressionTypes = emptyList()\n    )\n\n    data object Qoi : ImageFormat(\n        title = \"QOI\",\n        extension = \"qoi\",\n        mimeType = MimeType.Qoi,\n        canChangeCompressionValue = false\n    )\n\n    data object Ico : ImageFormat(\n        title = \"ICO\",\n        extension = \"ico\",\n        mimeType = MimeType.Ico,\n        canChangeCompressionValue = false\n    )\n\n    data object Gif : ImageFormat(\n        title = \"GIF\",\n        extension = \"gif\",\n        mimeType = MimeType.Gif,\n        canChangeCompressionValue = true\n    )\n\n    interface LosslessMarker\n\n    sealed class CompressionType(\n        open val compressionRange: IntRange = 0..100\n    ) {\n        data class Quality(\n            override val compressionRange: IntRange = 0..100\n        ) : CompressionType(compressionRange)\n\n        data class Effort(\n            override val compressionRange: IntRange = 0..100\n        ) : CompressionType(compressionRange)\n    }\n\n    companion object {\n        val Default: ImageFormat by lazy { Jpg }\n\n        operator fun get(typeString: String?): ImageFormat = when {\n            typeString == null -> Default\n            typeString.contains(\"tiff\") -> Tiff\n            typeString.contains(\"tif\") -> Tif\n            typeString.contains(\"jp2\") -> Jpeg2000.Jp2\n            typeString.contains(\"j2k\") -> Jpeg2000.J2k\n            typeString.contains(\"jxl\") -> Jxl.Lossless\n            typeString.contains(\"png\") -> Png.Lossless\n            typeString.contains(\"bmp\") -> Bmp\n            typeString.contains(\"jpeg\") -> Jpeg\n            typeString.contains(\"jpg\") -> Jpg\n            typeString.contains(\"webp\") -> Webp.Lossless\n            typeString.contains(\"avif\") -> Avif.Lossless\n            typeString.contains(\"heif\") -> Heif.Lossless\n            typeString.contains(\"heic\") -> Heic.Lossless\n            typeString.contains(\"qoi\") -> Qoi\n            typeString.contains(\"ico\") -> Ico\n            typeString.contains(\"svg\") -> Png.Lossless\n            typeString.contains(\"gif\") -> Gif\n            else -> Default\n        }\n\n        val highLevelFormats by lazy {\n            listOf(\n                Avif.Lossy,\n                Avif.Lossless,\n                Heic.Lossy,\n                Heic.Lossless,\n                Heif.Lossy,\n                Heif.Lossless\n            )\n        }\n\n        val entries by lazy {\n            listOf(\n                Jpg,\n                Jpeg,\n                MozJpeg,\n                Jpegli,\n                Png.Lossless,\n                Png.Lossy,\n                Bmp,\n                Webp.Lossless,\n                Webp.Lossy,\n                Avif.Lossless,\n                Avif.Lossy,\n                Heic.Lossless,\n                Heic.Lossy,\n                Heif.Lossless,\n                Heif.Lossy,\n                Jxl.Lossless,\n                Jxl.Lossy,\n                Tif,\n                Tiff,\n                Jpeg2000.Jp2,\n                Jpeg2000.J2k,\n                Qoi,\n                Ico,\n                Gif\n            )\n        }\n    }\n}\n\nval ImageFormat.isLossless get() = this is ImageFormat.LosslessMarker"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ImageFormatGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nsealed class ImageFormatGroup(\n    open val title: String,\n    open val formats: List<ImageFormat>\n) {\n    data object Jpg : ImageFormatGroup(\n        title = \"JPG\",\n        formats = listOf(\n            ImageFormat.Jpg,\n            ImageFormat.Jpeg,\n            ImageFormat.MozJpeg,\n            ImageFormat.Jpegli\n        )\n    )\n\n    data object Png : ImageFormatGroup(\n        title = \"PNG\",\n        formats = listOf(\n            ImageFormat.Png.Lossless,\n            ImageFormat.Png.Lossy,\n            ImageFormat.Png.OxiPNG\n        )\n    )\n\n    data object Bmp : ImageFormatGroup(\n        title = \"BMP\",\n        formats = listOf(\n            ImageFormat.Bmp\n        )\n    )\n\n    data object Webp : ImageFormatGroup(\n        title = \"WEBP\",\n        formats = listOf(\n            ImageFormat.Webp.Lossless,\n            ImageFormat.Webp.Lossy\n        )\n    )\n\n    data object Avif : ImageFormatGroup(\n        title = \"AVIF\",\n        formats = listOf(\n            ImageFormat.Avif.Lossless,\n            ImageFormat.Avif.Lossy\n        )\n    )\n\n    data object Heic : ImageFormatGroup(\n        title = \"HEIC\",\n        formats = listOf(\n            ImageFormat.Heic.Lossless,\n            ImageFormat.Heic.Lossy,\n            ImageFormat.Heif.Lossless,\n            ImageFormat.Heif.Lossy\n        )\n    )\n\n    data object Jxl : ImageFormatGroup(\n        title = \"JXL\",\n        formats = listOf(\n            ImageFormat.Jxl.Lossless,\n            ImageFormat.Jxl.Lossy\n        )\n    )\n\n    data object Jpeg2000 : ImageFormatGroup(\n        title = \"JPEG 2000\",\n        formats = listOf(\n            ImageFormat.Jpeg2000.Jp2,\n            ImageFormat.Jpeg2000.J2k\n        )\n    )\n\n    data object Tiff : ImageFormatGroup(\n        title = \"TIFF\",\n        formats = listOf(\n            ImageFormat.Tif,\n            ImageFormat.Tiff\n        )\n    )\n\n    data object Qoi : ImageFormatGroup(\n        title = \"QOI\",\n        formats = listOf(\n            ImageFormat.Qoi\n        )\n    )\n\n    data object Ico : ImageFormatGroup(\n        title = \"ICO\",\n        formats = listOf(\n            ImageFormat.Ico\n        )\n    )\n\n    data object Gif : ImageFormatGroup(\n        title = \"GIF\",\n        formats = listOf(\n            ImageFormat.Gif\n        )\n    )\n\n    data class Custom(\n        override val title: String,\n        override val formats: List<ImageFormat>\n    ) : ImageFormatGroup(title, formats)\n\n    companion object {\n        val entries by lazy {\n            listOf(Jpg, Png, Webp, Avif, Heic, Jxl, Bmp, Jpeg2000, Tiff, Qoi, Ico, Gif)\n        }\n\n        val alphaContainedEntries\n            get() = listOf(\n                Png,\n                Webp,\n                Avif,\n                Heic,\n                Jxl,\n                Jpeg2000,\n                Qoi,\n                Ico,\n                Gif\n            )\n\n        val highLevelFormats by lazy {\n            listOf(\n                Avif,\n                Heic\n            )\n        }\n\n        fun fromFormat(\n            imageFormat: ImageFormat\n        ): ImageFormatGroup = entries.first { imageFormat in it.formats }\n    }\n}\n\nval ImageFormat.Companion.alphaContainedEntries: List<ImageFormat> by lazy {\n    ImageFormatGroup.alphaContainedEntries.flatMap { it.formats }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ImageFrames.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nsealed interface ImageFrames {\n\n    data object All : ImageFrames {\n        override fun getFramePositions(\n            frameCount: Int\n        ): List<Int> = List(frameCount) { it + 1 }\n    }\n\n    data class ManualSelection(\n        val framePositions: List<Int>\n    ) : ImageFrames {\n        override fun getFramePositions(\n            frameCount: Int\n        ): List<Int> = framePositions.filter { it - 1 < frameCount }\n    }\n\n    fun isEmpty(): Boolean = when (this) {\n        All -> false\n        is ManualSelection -> framePositions.isEmpty()\n    }\n\n    fun isNotEmpty(): Boolean = !isEmpty()\n\n    fun getFramePositions(\n        frameCount: Int\n    ): List<Int>\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ImageInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\ndata class ImageInfo(\n    val width: Int = 0,\n    val height: Int = 0,\n    val quality: Quality = Quality.Base(),\n    val imageFormat: ImageFormat = ImageFormat.Default,\n    val resizeType: ResizeType = ResizeType.Explicit,\n    val rotationDegrees: Float = 0f,\n    val isFlipped: Boolean = false,\n    val sizeInBytes: Int = 0,\n    val imageScaleMode: ImageScaleMode = ImageScaleMode.Default,\n    val originalUri: String? = null\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ImageScaleMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nimport com.t8rin.imagetoolbox.core.resources.R\n\nsealed interface ScaleColorSpace {\n    data object SRGB : ScaleColorSpace\n    data object LAB : ScaleColorSpace\n    data object LUV : ScaleColorSpace\n    data object Linear : ScaleColorSpace\n    data object Sigmoidal : ScaleColorSpace\n    data object XYZ : ScaleColorSpace\n    data object F32sRGB : ScaleColorSpace\n    data object F32Rec709 : ScaleColorSpace\n    data object F32Gamma22 : ScaleColorSpace\n    data object F32Gamma28 : ScaleColorSpace\n    data object LCH : ScaleColorSpace\n    data object OklabSRGB : ScaleColorSpace\n    data object OklabRec709 : ScaleColorSpace\n    data object OklabGamma22 : ScaleColorSpace\n    data object OklabGamma28 : ScaleColorSpace\n    data object JzazbzSRGB : ScaleColorSpace\n    data object JzazbzRec709 : ScaleColorSpace\n    data object JzazbzGamma22 : ScaleColorSpace\n    data object JzazbzGamma28 : ScaleColorSpace\n\n    val ordinal: Int\n        get() = entries.indexOf(this)\n\n    companion object {\n        val Default = Linear\n\n        val entries by lazy {\n            listOf(\n                Linear,\n                SRGB,\n                F32sRGB,\n                XYZ,\n                LAB,\n                LUV,\n                Sigmoidal,\n                F32Rec709,\n                F32Gamma22,\n                F32Gamma28,\n                LCH,\n                OklabSRGB,\n                OklabRec709,\n                OklabGamma22,\n                OklabGamma28,\n                JzazbzSRGB,\n                JzazbzRec709,\n                JzazbzGamma22,\n                JzazbzGamma28\n            )\n        }\n\n        fun fromOrdinal(ordinal: Int) = entries.getOrNull(ordinal) ?: Default\n    }\n}\n\nsealed class ImageScaleMode(val value: Int) {\n\n    abstract val scaleColorSpace: ScaleColorSpace\n\n    abstract fun copy(\n        scaleColorSpace: ScaleColorSpace = this.scaleColorSpace\n    ): ImageScaleMode\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is ImageScaleMode) return false\n\n        if (value != other.value) return false\n        if (scaleColorSpace != other.scaleColorSpace) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = value\n        result = 31 * result + scaleColorSpace.hashCode()\n        return result\n    }\n\n    object NotPresent : ImageScaleMode(-2) {\n        override val scaleColorSpace: ScaleColorSpace\n            get() = ScaleColorSpace.Default\n\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = NotPresent\n\n        override fun toString(): String = \"NotPresent\"\n    }\n\n    object Base : ImageScaleMode(-3) {\n        override val scaleColorSpace: ScaleColorSpace\n            get() = ScaleColorSpace.Default\n\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Base\n\n        override fun toString(): String = \"Base\"\n    }\n\n    class Bilinear(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(0) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Bilinear(scaleColorSpace)\n    }\n\n    class Nearest(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(1) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Nearest(scaleColorSpace)\n    }\n\n    class Cubic(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(2) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Cubic(scaleColorSpace)\n    }\n\n    class Mitchell(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(3) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Mitchell(scaleColorSpace)\n    }\n\n    class Catmull(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(4) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Catmull(scaleColorSpace)\n    }\n\n    class Hermite(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(5) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Hermite(scaleColorSpace)\n    }\n\n    class BSpline(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(6) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = BSpline(scaleColorSpace)\n    }\n\n    class Hann(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(7) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Hann(scaleColorSpace)\n    }\n\n    class Bicubic(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(8) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Bicubic(scaleColorSpace)\n    }\n\n    class Hamming(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(9) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Hamming(scaleColorSpace)\n    }\n\n    class Hanning(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(10) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Hanning(scaleColorSpace)\n    }\n\n    class Blackman(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(11) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Blackman(scaleColorSpace)\n    }\n\n    class Welch(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(12) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Welch(scaleColorSpace)\n    }\n\n    class Quadric(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(13) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Quadric(scaleColorSpace)\n    }\n\n    class Gaussian(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(14) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Gaussian(scaleColorSpace)\n    }\n\n    class Sphinx(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(15) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Sphinx(scaleColorSpace)\n    }\n\n    class Bartlett(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(16) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Bartlett(scaleColorSpace)\n    }\n\n    class Robidoux(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(17) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Robidoux(scaleColorSpace)\n    }\n\n    class RobidouxSharp(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(18) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = RobidouxSharp(scaleColorSpace)\n    }\n\n    class Spline16(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(19) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Spline16(scaleColorSpace)\n    }\n\n    class Spline36(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(20) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Spline36(scaleColorSpace)\n    }\n\n    class Spline64(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(21) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Spline64(scaleColorSpace)\n    }\n\n    class Kaiser(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(22) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Kaiser(scaleColorSpace)\n    }\n\n    class BartlettHann(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(23) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = BartlettHann(scaleColorSpace)\n    }\n\n    class Box(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(24) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Box(scaleColorSpace)\n    }\n\n    class Bohman(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(25) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Bohman(scaleColorSpace)\n    }\n\n    class Lanczos2(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(26) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos2(scaleColorSpace)\n    }\n\n    class Lanczos3(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(27) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos3(scaleColorSpace)\n    }\n\n    class Lanczos4(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(28) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos4(scaleColorSpace)\n    }\n\n    class Lanczos2Jinc(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(29) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos2Jinc(scaleColorSpace)\n    }\n\n    class Lanczos3Jinc(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(30) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos3Jinc(scaleColorSpace)\n    }\n\n    class Lanczos4Jinc(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(31) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos4Jinc(scaleColorSpace)\n    }\n\n    class EwaHanning(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(32) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaHanning(scaleColorSpace)\n    }\n\n    class EwaRobidoux(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(33) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaRobidoux(scaleColorSpace)\n    }\n\n    class EwaBlackman(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(34) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaBlackman(scaleColorSpace)\n    }\n\n    class EwaQuadric(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(35) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaQuadric(scaleColorSpace)\n    }\n\n    class EwaRobidouxSharp(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(36) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaRobidouxSharp(scaleColorSpace)\n    }\n\n    class EwaLanczos3Jinc(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(37) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaLanczos3Jinc(scaleColorSpace)\n    }\n\n    class Ginseng(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(38) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Ginseng(scaleColorSpace)\n    }\n\n    class EwaGinseng(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(39) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaGinseng(scaleColorSpace)\n    }\n\n    class EwaLanczosSharp(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(40) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaLanczosSharp(scaleColorSpace)\n    }\n\n    class EwaLanczos4Sharpest(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(41) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaLanczos4Sharpest(scaleColorSpace)\n    }\n\n    class EwaLanczosSoft(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(42) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = EwaLanczosSoft(scaleColorSpace)\n    }\n\n    class HaasnSoft(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(43) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = HaasnSoft(scaleColorSpace)\n    }\n\n    class Lagrange2(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(44) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lagrange2(scaleColorSpace)\n    }\n\n    class Lagrange3(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(45) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lagrange3(scaleColorSpace)\n    }\n\n    class Lanczos6(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(46) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos6(scaleColorSpace)\n    }\n\n    class Lanczos6Jinc(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(47) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Lanczos6Jinc(scaleColorSpace)\n    }\n\n    class Area(\n        override val scaleColorSpace: ScaleColorSpace = ScaleColorSpace.Default\n    ) : ImageScaleMode(48) {\n        override fun copy(\n            scaleColorSpace: ScaleColorSpace\n        ): ImageScaleMode = Area(scaleColorSpace)\n    }\n\n    companion object {\n        val Default = Bilinear()\n\n        val entries by lazy {\n            simpleEntries + complexEntries\n        }\n\n        val simpleEntries by lazy {\n            listOf(\n                EwaQuadric(),\n                Quadric(),\n                Bilinear(),\n                Nearest(),\n                Cubic(),\n                Mitchell(),\n                Catmull(),\n                Hermite(),\n                BSpline(),\n                Bicubic(),\n                Box(),\n                Lanczos2(),\n                Lanczos3(),\n                Lanczos4(),\n                Lanczos2Jinc(),\n                Lanczos3Jinc(),\n                Lanczos4Jinc(),\n                Hamming(),\n                Hanning(),\n                EwaHanning(),\n                EwaRobidoux(),\n                Robidoux(),\n                RobidouxSharp(),\n                EwaLanczosSharp(),\n                EwaLanczos4Sharpest(),\n                EwaLanczosSoft(),\n                EwaRobidouxSharp(),\n                EwaLanczos3Jinc(),\n                Lagrange2(),\n                Lagrange3(),\n                Lanczos6(),\n                Lanczos6Jinc(),\n                Area()\n            )\n        }\n\n        val complexEntries by lazy {\n            listOf(\n                Blackman(),\n                Welch(),\n                Gaussian(),\n                Sphinx(),\n                Bartlett(),\n                Spline16(),\n                Spline36(),\n                Spline64(),\n                Kaiser(),\n                BartlettHann(),\n                Bohman(),\n                EwaBlackman(),\n                Ginseng(),\n                EwaGinseng(),\n                HaasnSoft(),\n                Hann(),\n            )\n        }\n\n        fun fromInt(value: Int): ImageScaleMode = when {\n            value == -3 -> Base\n            value >= 0 -> entries.associateBy { it.value }[value] ?: NotPresent\n            else -> NotPresent\n        }\n    }\n}\n\nval ImageScaleMode.title: Int\n    get() = when (this) {\n        ImageScaleMode.Base,\n        ImageScaleMode.NotPresent -> R.string.basic\n\n        is ImageScaleMode.Bilinear -> R.string.bilinear\n        is ImageScaleMode.Nearest -> R.string.nearest\n        is ImageScaleMode.Cubic -> R.string.cubic\n        is ImageScaleMode.Mitchell -> R.string.mitchell\n        is ImageScaleMode.Catmull -> R.string.catmull\n        is ImageScaleMode.Hermite -> R.string.hermite\n        is ImageScaleMode.BSpline -> R.string.bspline\n        is ImageScaleMode.Hann -> R.string.hann\n        is ImageScaleMode.Bicubic -> R.string.bicubic\n        is ImageScaleMode.Hamming -> R.string.hamming\n        is ImageScaleMode.Hanning -> R.string.hanning\n        is ImageScaleMode.Blackman -> R.string.blackman\n        is ImageScaleMode.Welch -> R.string.welch\n        is ImageScaleMode.Quadric -> R.string.quadric\n        is ImageScaleMode.Gaussian -> R.string.gaussian\n        is ImageScaleMode.Sphinx -> R.string.sphinx\n        is ImageScaleMode.Bartlett -> R.string.bartlett\n        is ImageScaleMode.Robidoux -> R.string.robidoux\n        is ImageScaleMode.RobidouxSharp -> R.string.robidoux_sharp\n        is ImageScaleMode.Spline16 -> R.string.spline16\n        is ImageScaleMode.Spline36 -> R.string.spline36\n        is ImageScaleMode.Spline64 -> R.string.spline64\n        is ImageScaleMode.Kaiser -> R.string.kaiser\n        is ImageScaleMode.BartlettHann -> R.string.bartlett_hann\n        is ImageScaleMode.Box -> R.string.box\n        is ImageScaleMode.Bohman -> R.string.bohman\n        is ImageScaleMode.Lanczos2 -> R.string.lanczos2\n        is ImageScaleMode.Lanczos3 -> R.string.lanczos3\n        is ImageScaleMode.Lanczos4 -> R.string.lanczos4\n        is ImageScaleMode.Lanczos2Jinc -> R.string.lanczos2_jinc\n        is ImageScaleMode.Lanczos3Jinc -> R.string.lanczos3_jinc\n        is ImageScaleMode.Lanczos4Jinc -> R.string.lanczos4_jinc\n        is ImageScaleMode.EwaHanning -> R.string.ewa_hanning\n        is ImageScaleMode.EwaRobidoux -> R.string.ewa_robidoux\n        is ImageScaleMode.EwaBlackman -> R.string.ewa_blackman\n        is ImageScaleMode.EwaQuadric -> R.string.ewa_quadric\n        is ImageScaleMode.EwaRobidouxSharp -> R.string.ewa_robidoux_sharp\n        is ImageScaleMode.EwaLanczos3Jinc -> R.string.ewa_lanczos3_jinc\n        is ImageScaleMode.Ginseng -> R.string.ginseng\n        is ImageScaleMode.EwaGinseng -> R.string.ewa_ginseng\n        is ImageScaleMode.EwaLanczosSharp -> R.string.ewa_lanczos_sharp\n        is ImageScaleMode.EwaLanczos4Sharpest -> R.string.ewa_lanczos_4_sharpest\n        is ImageScaleMode.EwaLanczosSoft -> R.string.ewa_lanczos_soft\n        is ImageScaleMode.HaasnSoft -> R.string.haasn_soft\n        is ImageScaleMode.Lagrange2 -> R.string.lagrange_2\n        is ImageScaleMode.Lagrange3 -> R.string.lagrange_3\n        is ImageScaleMode.Lanczos6 -> R.string.lanczos_6\n        is ImageScaleMode.Lanczos6Jinc -> R.string.lanczos_6_jinc\n        is ImageScaleMode.Area -> R.string.area\n    }"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ImageWithSize.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ndata class ImageWithSize<I>(\n    val image: I,\n    val size: IntegerSize\n)\n\ninfix fun <I> I.withSize(\n    size: IntegerSize\n): ImageWithSize<I> = ImageWithSize(\n    image = this,\n    size = size\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/MetadataTag.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"SpellCheckingInspection\")\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nsealed class MetadataTag(\n    val key: String\n) : Comparable<MetadataTag> {\n    object BitsPerSample : MetadataTag(TAG_BITS_PER_SAMPLE)\n    object Compression : MetadataTag(TAG_COMPRESSION)\n    object PhotometricInterpretation : MetadataTag(TAG_PHOTOMETRIC_INTERPRETATION)\n    object SamplesPerPixel : MetadataTag(TAG_SAMPLES_PER_PIXEL)\n    object PlanarConfiguration : MetadataTag(TAG_PLANAR_CONFIGURATION)\n    object YCbCrSubSampling : MetadataTag(TAG_Y_CB_CR_SUB_SAMPLING)\n    object YCbCrPositioning : MetadataTag(TAG_Y_CB_CR_POSITIONING)\n    object XResolution : MetadataTag(TAG_X_RESOLUTION)\n    object YResolution : MetadataTag(TAG_Y_RESOLUTION)\n    object ResolutionUnit : MetadataTag(TAG_RESOLUTION_UNIT)\n    object StripOffsets : MetadataTag(TAG_STRIP_OFFSETS)\n    object RowsPerStrip : MetadataTag(TAG_ROWS_PER_STRIP)\n    object StripByteCounts : MetadataTag(TAG_STRIP_BYTE_COUNTS)\n    object JpegInterchangeFormat : MetadataTag(TAG_JPEG_INTERCHANGE_FORMAT)\n    object JpegInterchangeFormatLength : MetadataTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH)\n    object TransferFunction : MetadataTag(TAG_TRANSFER_FUNCTION)\n    object WhitePoint : MetadataTag(TAG_WHITE_POINT)\n    object PrimaryChromaticities : MetadataTag(TAG_PRIMARY_CHROMATICITIES)\n    object YCbCrCoefficients : MetadataTag(TAG_Y_CB_CR_COEFFICIENTS)\n    object ReferenceBlackWhite : MetadataTag(TAG_REFERENCE_BLACK_WHITE)\n    object Datetime : MetadataTag(TAG_DATETIME)\n    object ImageDescription : MetadataTag(TAG_IMAGE_DESCRIPTION)\n    object Make : MetadataTag(TAG_MAKE)\n    object Model : MetadataTag(TAG_MODEL)\n    object Software : MetadataTag(TAG_SOFTWARE)\n    object Artist : MetadataTag(TAG_ARTIST)\n    object Copyright : MetadataTag(TAG_COPYRIGHT)\n    object ExifVersion : MetadataTag(TAG_EXIF_VERSION)\n    object FlashpixVersion : MetadataTag(TAG_FLASHPIX_VERSION)\n    object ColorSpace : MetadataTag(TAG_COLOR_SPACE)\n    object Gamma : MetadataTag(TAG_GAMMA)\n    object PixelXDimension : MetadataTag(TAG_PIXEL_X_DIMENSION)\n    object PixelYDimension : MetadataTag(TAG_PIXEL_Y_DIMENSION)\n    object CompressedBitsPerPixel : MetadataTag(TAG_COMPRESSED_BITS_PER_PIXEL)\n    object MakerNote : MetadataTag(TAG_MAKER_NOTE)\n    object UserComment : MetadataTag(TAG_USER_COMMENT)\n    object RelatedSoundFile : MetadataTag(TAG_RELATED_SOUND_FILE)\n    object DatetimeOriginal : MetadataTag(TAG_DATETIME_ORIGINAL)\n    object DatetimeDigitized : MetadataTag(TAG_DATETIME_DIGITIZED)\n    object OffsetTime : MetadataTag(TAG_OFFSET_TIME)\n    object OffsetTimeOriginal : MetadataTag(TAG_OFFSET_TIME_ORIGINAL)\n    object OffsetTimeDigitized : MetadataTag(TAG_OFFSET_TIME_DIGITIZED)\n    object SubsecTime : MetadataTag(TAG_SUBSEC_TIME)\n    object SubsecTimeOriginal : MetadataTag(TAG_SUBSEC_TIME_ORIGINAL)\n    object SubsecTimeDigitized : MetadataTag(TAG_SUBSEC_TIME_DIGITIZED)\n    object ExposureTime : MetadataTag(TAG_EXPOSURE_TIME)\n    object FNumber : MetadataTag(TAG_F_NUMBER)\n    object ExposureProgram : MetadataTag(TAG_EXPOSURE_PROGRAM)\n    object SpectralSensitivity : MetadataTag(TAG_SPECTRAL_SENSITIVITY)\n    object PhotographicSensitivity : MetadataTag(TAG_PHOTOGRAPHIC_SENSITIVITY)\n    object Oecf : MetadataTag(TAG_OECF)\n    object SensitivityType : MetadataTag(TAG_SENSITIVITY_TYPE)\n    object StandardOutputSensitivity : MetadataTag(TAG_STANDARD_OUTPUT_SENSITIVITY)\n    object RecommendedExposureIndex : MetadataTag(TAG_RECOMMENDED_EXPOSURE_INDEX)\n    object IsoSpeed : MetadataTag(TAG_ISO_SPEED)\n    object IsoSpeedLatitudeYyy : MetadataTag(TAG_ISO_SPEED_LATITUDE_YYY)\n    object IsoSpeedLatitudeZzz : MetadataTag(TAG_ISO_SPEED_LATITUDE_ZZZ)\n    object ShutterSpeedValue : MetadataTag(TAG_SHUTTER_SPEED_VALUE)\n    object ApertureValue : MetadataTag(TAG_APERTURE_VALUE)\n    object BrightnessValue : MetadataTag(TAG_BRIGHTNESS_VALUE)\n    object ExposureBiasValue : MetadataTag(TAG_EXPOSURE_BIAS_VALUE)\n    object MaxApertureValue : MetadataTag(TAG_MAX_APERTURE_VALUE)\n    object SubjectDistance : MetadataTag(TAG_SUBJECT_DISTANCE)\n    object MeteringMode : MetadataTag(TAG_METERING_MODE)\n    object Flash : MetadataTag(TAG_FLASH)\n    object SubjectArea : MetadataTag(TAG_SUBJECT_AREA)\n    object FocalLength : MetadataTag(TAG_FOCAL_LENGTH)\n    object FlashEnergy : MetadataTag(TAG_FLASH_ENERGY)\n    object SpatialFrequencyResponse : MetadataTag(TAG_SPATIAL_FREQUENCY_RESPONSE)\n    object FocalPlaneXResolution : MetadataTag(TAG_FOCAL_PLANE_X_RESOLUTION)\n    object FocalPlaneYResolution : MetadataTag(TAG_FOCAL_PLANE_Y_RESOLUTION)\n    object FocalPlaneResolutionUnit : MetadataTag(TAG_FOCAL_PLANE_RESOLUTION_UNIT)\n    object SubjectLocation : MetadataTag(TAG_SUBJECT_LOCATION)\n    object ExposureIndex : MetadataTag(TAG_EXPOSURE_INDEX)\n    object SensingMethod : MetadataTag(TAG_SENSING_METHOD)\n    object FileSource : MetadataTag(TAG_FILE_SOURCE)\n    object CfaPattern : MetadataTag(TAG_CFA_PATTERN)\n    object CustomRendered : MetadataTag(TAG_CUSTOM_RENDERED)\n    object ExposureMode : MetadataTag(TAG_EXPOSURE_MODE)\n    object WhiteBalance : MetadataTag(TAG_WHITE_BALANCE)\n    object DigitalZoomRatio : MetadataTag(TAG_DIGITAL_ZOOM_RATIO)\n    object FocalLengthIn35mmFilm : MetadataTag(TAG_FOCAL_LENGTH_IN_35MM_FILM)\n    object SceneCaptureType : MetadataTag(TAG_SCENE_CAPTURE_TYPE)\n    object GainControl : MetadataTag(TAG_GAIN_CONTROL)\n    object Contrast : MetadataTag(TAG_CONTRAST)\n    object Saturation : MetadataTag(TAG_SATURATION)\n    object Sharpness : MetadataTag(TAG_SHARPNESS)\n    object DeviceSettingDescription : MetadataTag(TAG_DEVICE_SETTING_DESCRIPTION)\n    object SubjectDistanceRange : MetadataTag(TAG_SUBJECT_DISTANCE_RANGE)\n    object ImageUniqueId : MetadataTag(TAG_IMAGE_UNIQUE_ID)\n    object CameraOwnerName : MetadataTag(TAG_CAMERA_OWNER_NAME)\n    object BodySerialNumber : MetadataTag(TAG_BODY_SERIAL_NUMBER)\n    object LensSpecification : MetadataTag(TAG_LENS_SPECIFICATION)\n    object LensMake : MetadataTag(TAG_LENS_MAKE)\n    object LensModel : MetadataTag(TAG_LENS_MODEL)\n    object LensSerialNumber : MetadataTag(TAG_LENS_SERIAL_NUMBER)\n    object GpsVersionId : MetadataTag(TAG_GPS_VERSION_ID)\n    object GpsLatitudeRef : MetadataTag(TAG_GPS_LATITUDE_REF)\n    object GpsLatitude : MetadataTag(TAG_GPS_LATITUDE)\n    object GpsLongitudeRef : MetadataTag(TAG_GPS_LONGITUDE_REF)\n    object GpsLongitude : MetadataTag(TAG_GPS_LONGITUDE)\n    object GpsAltitudeRef : MetadataTag(TAG_GPS_ALTITUDE_REF)\n    object GpsAltitude : MetadataTag(TAG_GPS_ALTITUDE)\n    object GpsTimestamp : MetadataTag(TAG_GPS_TIMESTAMP)\n    object GpsSatellites : MetadataTag(TAG_GPS_SATELLITES)\n    object GpsStatus : MetadataTag(TAG_GPS_STATUS)\n    object GpsMeasureMode : MetadataTag(TAG_GPS_MEASURE_MODE)\n    object GpsDop : MetadataTag(TAG_GPS_DOP)\n    object GpsSpeedRef : MetadataTag(TAG_GPS_SPEED_REF)\n    object GpsSpeed : MetadataTag(TAG_GPS_SPEED)\n    object GpsTrackRef : MetadataTag(TAG_GPS_TRACK_REF)\n    object GpsTrack : MetadataTag(TAG_GPS_TRACK)\n    object GpsImgDirectionRef : MetadataTag(TAG_GPS_IMG_DIRECTION_REF)\n    object GpsImgDirection : MetadataTag(TAG_GPS_IMG_DIRECTION)\n    object GpsMapDatum : MetadataTag(TAG_GPS_MAP_DATUM)\n    object GpsDestLatitudeRef : MetadataTag(TAG_GPS_DEST_LATITUDE_REF)\n    object GpsDestLatitude : MetadataTag(TAG_GPS_DEST_LATITUDE)\n    object GpsDestLongitudeRef : MetadataTag(TAG_GPS_DEST_LONGITUDE_REF)\n    object GpsDestLongitude : MetadataTag(TAG_GPS_DEST_LONGITUDE)\n    object GpsDestBearingRef : MetadataTag(TAG_GPS_DEST_BEARING_REF)\n    object GpsDestBearing : MetadataTag(TAG_GPS_DEST_BEARING)\n    object GpsDestDistanceRef : MetadataTag(TAG_GPS_DEST_DISTANCE_REF)\n    object GpsDestDistance : MetadataTag(TAG_GPS_DEST_DISTANCE)\n    object GpsProcessingMethod : MetadataTag(TAG_GPS_PROCESSING_METHOD)\n    object GpsAreaInformation : MetadataTag(TAG_GPS_AREA_INFORMATION)\n    object GpsDatestamp : MetadataTag(TAG_GPS_DATESTAMP)\n    object GpsDifferential : MetadataTag(TAG_GPS_DIFFERENTIAL)\n    object GpsHPositioningError : MetadataTag(TAG_GPS_H_POSITIONING_ERROR)\n    object InteroperabilityIndex : MetadataTag(TAG_INTEROPERABILITY_INDEX)\n    object DngVersion : MetadataTag(TAG_DNG_VERSION)\n    object DefaultCropSize : MetadataTag(TAG_DEFAULT_CROP_SIZE)\n    object OrfPreviewImageStart : MetadataTag(TAG_ORF_PREVIEW_IMAGE_START)\n    object OrfPreviewImageLength : MetadataTag(TAG_ORF_PREVIEW_IMAGE_LENGTH)\n    object OrfAspectFrame : MetadataTag(TAG_ORF_ASPECT_FRAME)\n    object Rw2SensorBottomBorder : MetadataTag(TAG_RW2_SENSOR_BOTTOM_BORDER)\n    object Rw2SensorLeftBorder : MetadataTag(TAG_RW2_SENSOR_LEFT_BORDER)\n    object Rw2SensorRightBorder : MetadataTag(TAG_RW2_SENSOR_RIGHT_BORDER)\n    object Rw2SensorTopBorder : MetadataTag(TAG_RW2_SENSOR_TOP_BORDER)\n    object Rw2Iso : MetadataTag(TAG_RW2_ISO)\n\n    override fun compareTo(other: MetadataTag): Int = key.compareTo(other.key)\n\n    override fun toString(): String = key\n\n    override fun equals(other: Any?): Boolean {\n        if (other !is MetadataTag) return false\n        return other.key == key\n    }\n\n    override fun hashCode(): Int = key.hashCode()\n\n    companion object {\n        const val TAG_BITS_PER_SAMPLE: String = \"BitsPerSample\"\n        const val TAG_COMPRESSION: String = \"Compression\"\n        const val TAG_PHOTOMETRIC_INTERPRETATION: String = \"PhotometricInterpretation\"\n        const val TAG_SAMPLES_PER_PIXEL: String = \"SamplesPerPixel\"\n        const val TAG_PLANAR_CONFIGURATION: String = \"PlanarConfiguration\"\n        const val TAG_Y_CB_CR_SUB_SAMPLING: String = \"YCbCrSubSampling\"\n        const val TAG_Y_CB_CR_POSITIONING: String = \"YCbCrPositioning\"\n        const val TAG_X_RESOLUTION: String = \"XResolution\"\n        const val TAG_Y_RESOLUTION: String = \"YResolution\"\n        const val TAG_RESOLUTION_UNIT: String = \"ResolutionUnit\"\n        const val TAG_STRIP_OFFSETS: String = \"StripOffsets\"\n        const val TAG_ROWS_PER_STRIP: String = \"RowsPerStrip\"\n        const val TAG_STRIP_BYTE_COUNTS: String = \"StripByteCounts\"\n        const val TAG_JPEG_INTERCHANGE_FORMAT: String = \"JPEGInterchangeFormat\"\n        const val TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: String = \"JPEGInterchangeFormatLength\"\n        const val TAG_TRANSFER_FUNCTION: String = \"TransferFunction\"\n        const val TAG_WHITE_POINT: String = \"WhitePoint\"\n        const val TAG_PRIMARY_CHROMATICITIES: String = \"PrimaryChromaticities\"\n        const val TAG_Y_CB_CR_COEFFICIENTS: String = \"YCbCrCoefficients\"\n        const val TAG_REFERENCE_BLACK_WHITE: String = \"ReferenceBlackWhite\"\n        const val TAG_DATETIME: String = \"DateTime\"\n        const val TAG_IMAGE_DESCRIPTION: String = \"ImageDescription\"\n        const val TAG_MAKE: String = \"Make\"\n        const val TAG_MODEL: String = \"Model\"\n        const val TAG_SOFTWARE: String = \"Software\"\n        const val TAG_ARTIST: String = \"Artist\"\n        const val TAG_COPYRIGHT: String = \"Copyright\"\n        const val TAG_EXIF_VERSION: String = \"ExifVersion\"\n        const val TAG_FLASHPIX_VERSION: String = \"FlashpixVersion\"\n        const val TAG_COLOR_SPACE: String = \"ColorSpace\"\n        const val TAG_GAMMA: String = \"Gamma\"\n        const val TAG_PIXEL_X_DIMENSION: String = \"PixelXDimension\"\n        const val TAG_PIXEL_Y_DIMENSION: String = \"PixelYDimension\"\n        const val TAG_COMPRESSED_BITS_PER_PIXEL: String = \"CompressedBitsPerPixel\"\n        const val TAG_MAKER_NOTE: String = \"MakerNote\"\n        const val TAG_USER_COMMENT: String = \"UserComment\"\n        const val TAG_RELATED_SOUND_FILE: String = \"RelatedSoundFile\"\n        const val TAG_DATETIME_ORIGINAL: String = \"DateTimeOriginal\"\n        const val TAG_DATETIME_DIGITIZED: String = \"DateTimeDigitized\"\n        const val TAG_OFFSET_TIME: String = \"OffsetTime\"\n        const val TAG_OFFSET_TIME_ORIGINAL: String = \"OffsetTimeOriginal\"\n        const val TAG_OFFSET_TIME_DIGITIZED: String = \"OffsetTimeDigitized\"\n        const val TAG_SUBSEC_TIME: String = \"SubSecTime\"\n        const val TAG_SUBSEC_TIME_ORIGINAL: String = \"SubSecTimeOriginal\"\n        const val TAG_SUBSEC_TIME_DIGITIZED: String = \"SubSecTimeDigitized\"\n        const val TAG_EXPOSURE_TIME: String = \"ExposureTime\"\n        const val TAG_F_NUMBER: String = \"FNumber\"\n        const val TAG_EXPOSURE_PROGRAM: String = \"ExposureProgram\"\n        const val TAG_SPECTRAL_SENSITIVITY: String = \"SpectralSensitivity\"\n        const val TAG_PHOTOGRAPHIC_SENSITIVITY: String = \"PhotographicSensitivity\"\n        const val TAG_OECF: String = \"OECF\"\n        const val TAG_SENSITIVITY_TYPE: String = \"SensitivityType\"\n        const val TAG_STANDARD_OUTPUT_SENSITIVITY: String = \"StandardOutputSensitivity\"\n        const val TAG_RECOMMENDED_EXPOSURE_INDEX: String = \"RecommendedExposureIndex\"\n        const val TAG_ISO_SPEED: String = \"ISOSpeed\"\n        const val TAG_ISO_SPEED_LATITUDE_YYY: String = \"ISOSpeedLatitudeyyy\"\n        const val TAG_ISO_SPEED_LATITUDE_ZZZ: String = \"ISOSpeedLatitudezzz\"\n        const val TAG_SHUTTER_SPEED_VALUE: String = \"ShutterSpeedValue\"\n        const val TAG_APERTURE_VALUE: String = \"ApertureValue\"\n        const val TAG_BRIGHTNESS_VALUE: String = \"BrightnessValue\"\n        const val TAG_EXPOSURE_BIAS_VALUE: String = \"ExposureBiasValue\"\n        const val TAG_MAX_APERTURE_VALUE: String = \"MaxApertureValue\"\n        const val TAG_SUBJECT_DISTANCE: String = \"SubjectDistance\"\n        const val TAG_METERING_MODE: String = \"MeteringMode\"\n        const val TAG_FLASH: String = \"Flash\"\n        const val TAG_SUBJECT_AREA: String = \"SubjectArea\"\n        const val TAG_FOCAL_LENGTH: String = \"FocalLength\"\n        const val TAG_FLASH_ENERGY: String = \"FlashEnergy\"\n        const val TAG_SPATIAL_FREQUENCY_RESPONSE: String = \"SpatialFrequencyResponse\"\n        const val TAG_FOCAL_PLANE_X_RESOLUTION: String = \"FocalPlaneXResolution\"\n        const val TAG_FOCAL_PLANE_Y_RESOLUTION: String = \"FocalPlaneYResolution\"\n        const val TAG_FOCAL_PLANE_RESOLUTION_UNIT: String = \"FocalPlaneResolutionUnit\"\n        const val TAG_SUBJECT_LOCATION: String = \"SubjectLocation\"\n        const val TAG_EXPOSURE_INDEX: String = \"ExposureIndex\"\n        const val TAG_SENSING_METHOD: String = \"SensingMethod\"\n        const val TAG_FILE_SOURCE: String = \"FileSource\"\n        const val TAG_CFA_PATTERN: String = \"CFAPattern\"\n        const val TAG_CUSTOM_RENDERED: String = \"CustomRendered\"\n        const val TAG_EXPOSURE_MODE: String = \"ExposureMode\"\n        const val TAG_WHITE_BALANCE: String = \"WhiteBalance\"\n        const val TAG_DIGITAL_ZOOM_RATIO: String = \"DigitalZoomRatio\"\n        const val TAG_FOCAL_LENGTH_IN_35MM_FILM: String = \"FocalLengthIn35mmFilm\"\n        const val TAG_SCENE_CAPTURE_TYPE: String = \"SceneCaptureType\"\n        const val TAG_GAIN_CONTROL: String = \"GainControl\"\n        const val TAG_CONTRAST: String = \"Contrast\"\n        const val TAG_SATURATION: String = \"Saturation\"\n        const val TAG_SHARPNESS: String = \"Sharpness\"\n        const val TAG_DEVICE_SETTING_DESCRIPTION: String = \"DeviceSettingDescription\"\n        const val TAG_SUBJECT_DISTANCE_RANGE: String = \"SubjectDistanceRange\"\n        const val TAG_IMAGE_UNIQUE_ID: String = \"ImageUniqueID\"\n        const val TAG_CAMERA_OWNER_NAME: String = \"CameraOwnerName\"\n        const val TAG_BODY_SERIAL_NUMBER: String = \"BodySerialNumber\"\n        const val TAG_LENS_SPECIFICATION: String = \"LensSpecification\"\n        const val TAG_LENS_MAKE: String = \"LensMake\"\n        const val TAG_LENS_MODEL: String = \"LensModel\"\n        const val TAG_LENS_SERIAL_NUMBER: String = \"LensSerialNumber\"\n        const val TAG_GPS_VERSION_ID: String = \"GPSVersionID\"\n        const val TAG_GPS_LATITUDE_REF: String = \"GPSLatitudeRef\"\n        const val TAG_GPS_LATITUDE: String = \"GPSLatitude\"\n        const val TAG_GPS_LONGITUDE_REF: String = \"GPSLongitudeRef\"\n        const val TAG_GPS_LONGITUDE: String = \"GPSLongitude\"\n        const val TAG_GPS_ALTITUDE_REF: String = \"GPSAltitudeRef\"\n        const val TAG_GPS_ALTITUDE: String = \"GPSAltitude\"\n        const val TAG_GPS_TIMESTAMP: String = \"GPSTimeStamp\"\n        const val TAG_GPS_SATELLITES: String = \"GPSSatellites\"\n        const val TAG_GPS_STATUS: String = \"GPSStatus\"\n        const val TAG_GPS_MEASURE_MODE: String = \"GPSMeasureMode\"\n        const val TAG_GPS_DOP: String = \"GPSDOP\"\n        const val TAG_GPS_SPEED_REF: String = \"GPSSpeedRef\"\n        const val TAG_GPS_SPEED: String = \"GPSSpeed\"\n        const val TAG_GPS_TRACK_REF: String = \"GPSTrackRef\"\n        const val TAG_GPS_TRACK: String = \"GPSTrack\"\n        const val TAG_GPS_IMG_DIRECTION_REF: String = \"GPSImgDirectionRef\"\n        const val TAG_GPS_IMG_DIRECTION: String = \"GPSImgDirection\"\n        const val TAG_GPS_MAP_DATUM: String = \"GPSMapDatum\"\n        const val TAG_GPS_DEST_LATITUDE_REF: String = \"GPSDestLatitudeRef\"\n        const val TAG_GPS_DEST_LATITUDE: String = \"GPSDestLatitude\"\n        const val TAG_GPS_DEST_LONGITUDE_REF: String = \"GPSDestLongitudeRef\"\n        const val TAG_GPS_DEST_LONGITUDE: String = \"GPSDestLongitude\"\n        const val TAG_GPS_DEST_BEARING_REF: String = \"GPSDestBearingRef\"\n        const val TAG_GPS_DEST_BEARING: String = \"GPSDestBearing\"\n        const val TAG_GPS_DEST_DISTANCE_REF: String = \"GPSDestDistanceRef\"\n        const val TAG_GPS_DEST_DISTANCE: String = \"GPSDestDistance\"\n        const val TAG_GPS_PROCESSING_METHOD: String = \"GPSProcessingMethod\"\n        const val TAG_GPS_AREA_INFORMATION: String = \"GPSAreaInformation\"\n        const val TAG_GPS_DATESTAMP: String = \"GPSDateStamp\"\n        const val TAG_GPS_DIFFERENTIAL: String = \"GPSDifferential\"\n        const val TAG_GPS_H_POSITIONING_ERROR: String = \"GPSHPositioningError\"\n        const val TAG_INTEROPERABILITY_INDEX: String = \"InteroperabilityIndex\"\n        const val TAG_DNG_VERSION: String = \"DNGVersion\"\n        const val TAG_DEFAULT_CROP_SIZE: String = \"DefaultCropSize\"\n        const val TAG_ORF_PREVIEW_IMAGE_START: String = \"PreviewImageStart\"\n        const val TAG_ORF_PREVIEW_IMAGE_LENGTH: String = \"PreviewImageLength\"\n        const val TAG_ORF_ASPECT_FRAME: String = \"AspectFrame\"\n        const val TAG_RW2_SENSOR_BOTTOM_BORDER: String = \"SensorBottomBorder\"\n        const val TAG_RW2_SENSOR_LEFT_BORDER: String = \"SensorLeftBorder\"\n        const val TAG_RW2_SENSOR_RIGHT_BORDER: String = \"SensorRightBorder\"\n        const val TAG_RW2_SENSOR_TOP_BORDER: String = \"SensorTopBorder\"\n        const val TAG_RW2_ISO: String = \"ISO\"\n\n        val entries by lazy {\n            listOf(\n                BitsPerSample,\n                Compression,\n                PhotometricInterpretation,\n                SamplesPerPixel,\n                PlanarConfiguration,\n                YCbCrSubSampling,\n                YCbCrPositioning,\n                XResolution,\n                YResolution,\n                ResolutionUnit,\n                StripOffsets,\n                RowsPerStrip,\n                StripByteCounts,\n                JpegInterchangeFormat,\n                JpegInterchangeFormatLength,\n                TransferFunction,\n                WhitePoint,\n                PrimaryChromaticities,\n                YCbCrCoefficients,\n                ReferenceBlackWhite,\n                Datetime,\n                ImageDescription,\n                Make,\n                Model,\n                Software,\n                Artist,\n                Copyright,\n                ExifVersion,\n                FlashpixVersion,\n                ColorSpace,\n                Gamma,\n                PixelXDimension,\n                PixelYDimension,\n                CompressedBitsPerPixel,\n                MakerNote,\n                UserComment,\n                RelatedSoundFile,\n                DatetimeOriginal,\n                DatetimeDigitized,\n                OffsetTime,\n                OffsetTimeOriginal,\n                OffsetTimeDigitized,\n                SubsecTime,\n                SubsecTimeOriginal,\n                SubsecTimeDigitized,\n                ExposureTime,\n                FNumber,\n                ExposureProgram,\n                SpectralSensitivity,\n                PhotographicSensitivity,\n                Oecf,\n                SensitivityType,\n                StandardOutputSensitivity,\n                RecommendedExposureIndex,\n                IsoSpeed,\n                IsoSpeedLatitudeYyy,\n                IsoSpeedLatitudeZzz,\n                ShutterSpeedValue,\n                ApertureValue,\n                BrightnessValue,\n                ExposureBiasValue,\n                MaxApertureValue,\n                SubjectDistance,\n                MeteringMode,\n                Flash,\n                SubjectArea,\n                FocalLength,\n                FlashEnergy,\n                SpatialFrequencyResponse,\n                FocalPlaneXResolution,\n                FocalPlaneYResolution,\n                FocalPlaneResolutionUnit,\n                SubjectLocation,\n                ExposureIndex,\n                SensingMethod,\n                FileSource,\n                CfaPattern,\n                CustomRendered,\n                ExposureMode,\n                WhiteBalance,\n                DigitalZoomRatio,\n                FocalLengthIn35mmFilm,\n                SceneCaptureType,\n                GainControl,\n                Contrast,\n                Saturation,\n                Sharpness,\n                DeviceSettingDescription,\n                SubjectDistanceRange,\n                ImageUniqueId,\n                CameraOwnerName,\n                BodySerialNumber,\n                LensSpecification,\n                LensMake,\n                LensModel,\n                LensSerialNumber,\n                GpsVersionId,\n                GpsLatitudeRef,\n                GpsLatitude,\n                GpsLongitudeRef,\n                GpsLongitude,\n                GpsAltitudeRef,\n                GpsAltitude,\n                GpsTimestamp,\n                GpsSatellites,\n                GpsStatus,\n                GpsMeasureMode,\n                GpsDop,\n                GpsSpeedRef,\n                GpsSpeed,\n                GpsTrackRef,\n                GpsTrack,\n                GpsImgDirectionRef,\n                GpsImgDirection,\n                GpsMapDatum,\n                GpsDestLatitudeRef,\n                GpsDestLatitude,\n                GpsDestLongitudeRef,\n                GpsDestLongitude,\n                GpsDestBearingRef,\n                GpsDestBearing,\n                GpsDestDistanceRef,\n                GpsDestDistance,\n                GpsProcessingMethod,\n                GpsAreaInformation,\n                GpsDatestamp,\n                GpsDifferential,\n                GpsHPositioningError,\n                InteroperabilityIndex,\n                DngVersion,\n                DefaultCropSize,\n                OrfPreviewImageStart,\n                OrfPreviewImageLength,\n                OrfAspectFrame,\n                Rw2SensorBottomBorder,\n                Rw2SensorLeftBorder,\n                Rw2SensorRightBorder,\n                Rw2SensorTopBorder,\n                Rw2Iso,\n            )\n        }\n\n        val dateEntries by lazy {\n            listOf(\n                Datetime,\n                DatetimeOriginal,\n                DatetimeDigitized,\n                OffsetTime,\n                OffsetTimeOriginal,\n                OffsetTimeDigitized,\n                SubsecTime,\n                SubsecTimeOriginal,\n                SubsecTimeDigitized,\n                GpsTimestamp,\n                GpsDatestamp\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/Preset.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nsealed class Preset {\n\n    data object Telegram : Preset()\n\n    data object None : Preset()\n\n    data class Percentage(val value: Int) : Preset()\n\n    data class AspectRatio(\n        val ratio: Float,\n        val isFit: Boolean\n    ) : Preset()\n\n    fun isTelegram(): Boolean = this is Telegram\n\n    fun value(): Int? = (this as? Percentage)?.value\n\n    fun isEmpty(): Boolean = this is None\n\n    fun isAspectRatio(): Boolean = this is AspectRatio\n\n    fun asString() = when (this) {\n        is AspectRatio -> \"ratio($ratio)\"\n        None -> \"\"\n        is Percentage -> \"$value%\"\n        Telegram -> \"telegram\"\n    }\n\n    companion object {\n        val Original by lazy {\n            Percentage(100)\n        }\n\n        fun createListFromInts(presets: String?): List<Preset>? {\n            return presets?.split(\"*\")?.map {\n                it.toInt()\n            }?.map { Percentage(it) }\n        }\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/Quality.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nimport androidx.annotation.IntRange\n\nsealed interface Quality {\n    val qualityValue: Int\n\n    fun coerceIn(\n        imageFormat: ImageFormat\n    ): Quality {\n        return when (imageFormat) {\n            is ImageFormat.Jxl -> {\n                val value = this as? Jxl ?: return Jxl()\n                value.copy(\n                    qualityValue = qualityValue.coerceIn(1..100),\n                    effort = effort.coerceIn(1..10),\n                    speed = speed.coerceIn(0..4)\n                )\n            }\n\n            is ImageFormat.Png.Lossy -> {\n                val value = this as? PngLossy\n                    ?: return PngLossy()\n                value.copy(\n                    maxColors = value.maxColors.coerceIn(2..1024),\n                    compressionLevel = compressionLevel.coerceIn(0..9)\n                )\n            }\n\n            is ImageFormat.Avif -> {\n                val value = this as? Avif\n                    ?: return Avif()\n                value.copy(\n                    qualityValue = qualityValue.coerceIn(1..100),\n                    effort = effort.coerceIn(0..9)\n                )\n            }\n\n            is ImageFormat.Tif,\n            is ImageFormat.Tiff -> {\n                val value = this as? Tiff\n                    ?: return Tiff()\n                value.copy(\n                    compressionScheme = value.compressionScheme.coerceIn(0..9)\n                )\n            }\n\n            is ImageFormat.Jpeg2000 -> Base(qualityValue.coerceIn(20..100))\n\n            else -> {\n                Base(qualityValue.coerceIn(0..100))\n            }\n        }\n    }\n\n    fun isNonAlpha(): Boolean = if (this is Jxl) {\n        channels == Channels.RGB || channels == Channels.Monochrome\n    } else false\n\n    fun isDefault(): Boolean = when (this) {\n        is Base -> this == Base()\n        is Avif -> this == Avif()\n        is Jxl -> this == Jxl()\n        is PngLossy -> this == PngLossy()\n        is Tiff -> this == Tiff()\n    }\n\n    data class Jxl(\n        @IntRange(from = 1, to = 100)\n        override val qualityValue: Int = 50,\n        @IntRange(from = 1, to = 10)\n        val effort: Int = 2,\n        @IntRange(from = 0, to = 4)\n        val speed: Int = 0,\n        val channels: Channels = Channels.RGBA\n    ) : Quality\n\n    data class Avif(\n        @IntRange(from = 1, to = 100)\n        override val qualityValue: Int = 50,\n        @IntRange(from = 0, to = 9)\n        val effort: Int = 0\n    ) : Quality\n\n    data class PngLossy(\n        @IntRange(from = 2, to = 1024)\n        val maxColors: Int = 512,\n        @IntRange(from = 0, to = 9)\n        val compressionLevel: Int = 7,\n    ) : Quality {\n        override val qualityValue: Int = compressionLevel\n    }\n\n    data class Tiff(\n        val compressionScheme: Int = 5\n    ) : Quality {\n        override val qualityValue: Int = compressionScheme\n    }\n\n    data class Base(\n        override val qualityValue: Int = 100\n    ) : Quality\n\n    enum class Channels {\n        RGBA, RGB, Monochrome;\n\n        companion object {\n            fun fromInt(int: Int) = when (int) {\n                1 -> RGB\n                2 -> Monochrome\n                else -> RGBA\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ResizeAnchor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nenum class ResizeAnchor {\n    Default,\n    Width,\n    Height,\n    Max,\n    Min\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/ResizeType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Position\n\nsealed class ResizeType {\n    data object Explicit : ResizeType()\n\n    data class Flexible(\n        val resizeAnchor: ResizeAnchor = ResizeAnchor.Default\n    ) : ResizeType()\n\n    data class CenterCrop(\n        val canvasColor: Int? = 0,\n        val blurRadius: Int = 35,\n        val originalSize: IntegerSize = IntegerSize.Undefined,\n        val scaleFactor: Float = 1f,\n        val position: Position = Position.Center\n    ) : ResizeType()\n\n    data class Fit(\n        val canvasColor: Int? = 0,\n        val blurRadius: Int = 35,\n        val position: Position = Position.Center\n    ) : ResizeType()\n\n    fun withOriginalSizeIfCrop(\n        originalSize: IntegerSize?\n    ): ResizeType = if (this is CenterCrop) {\n        copy(originalSize = originalSize ?: IntegerSize.Undefined)\n    } else this\n\n    companion object {\n        val Flexible = Flexible()\n\n        val entries by lazy {\n            listOf(\n                Explicit,\n                Flexible(),\n                CenterCrop(),\n                Fit()\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/image/model/TiffCompressionScheme.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.image.model\n\nenum class TiffCompressionScheme(val value: Int) {\n    /**\n     * No compression\n     */\n    NONE(1),\n\n    /**\n     * CCITT modified Huffman RLE\n     */\n    CCITTRLE(2),\n\n    /**\n     * CCITT Group 3 fax encoding\n     */\n    CCITTFAX3(3),\n\n    /**\n     * CCITT Group 4 fax encoding\n     */\n    CCITTFAX4(4),\n\n    /**\n     * LZW\n     */\n    LZW(5),\n\n    /**\n     * JPEG ('new-style' JPEG)\n     */\n    JPEG(7),\n    PACKBITS(32773),\n    DEFLATE(32946),\n    ADOBE_DEFLATE(8),\n\n    /**\n     * All other compression schemes\n     */\n    OTHER(0);\n\n    companion object {\n        val safeEntries by lazy { TiffCompressionScheme.entries - OTHER }\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/json/JsonParser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.json\n\nimport java.lang.reflect.Type\n\ninterface JsonParser {\n\n    /**\n     * [type] is type of [obj]: [T], which is converted to json\n     *\n     * @return Json from given object\n     */\n    fun <T> toJson(\n        obj: T,\n        type: Type,\n    ): String?\n\n    /**\n     * [type] is type of [T], which is will be parsed from json\n     *\n     * @return Object from given json\n     */\n    fun <T> fromJson(\n        json: String,\n        type: Type,\n    ): T?\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/CipherType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.CipherType.Companion.registerSecurityCiphers\n\n\n@ConsistentCopyVisibility\n/**\n * [CipherType] multiplatform domain wrapper for java Cipher, in order to add custom digests, you need to call [registerSecurityCiphers] when process created\n **/\ndata class CipherType private constructor(\n    val cipher: String,\n    val name: String = cipher\n) {\n    companion object {\n        val AES_NO_PADDING = CipherType(\"AES/GCM/NoPadding\")\n\n        val BROKEN by lazy {\n            listOf(\n                \"IES\",\n                \"SM2\",\n                \"ML-KEM\",\n                \"1.2.840.113533.7.66.10\",\n                \"CAST5\",\n                \"ElGAMAL\",\n                \"KW\",\n                \"RC2WRAP\",\n                \"1.2.840.113549.1.1.7\",\n                \"RSA\",\n                \"OID.2.5.8.1.1\",\n                \"RC5-64\",\n                \"NTRU\",\n                \"1.2.804.2\",\n                \"GRAINV1\",\n                \"1.3.14.3.2.7\",\n                \"DSTU7624\",\n                \"1.2.840.113549.1.1.1\",\n                \"ETSIKEMWITHSHA256\",\n                \"2.5.8.1.1\",\n                \"GOST3412-2015\",\n                \"SEEDWRAP\",\n                \"2.16.840.1.101.3.4.1\",\n                \"WRAP\",\n                \"ARIACCM\",\n                \"AES_128/ECB/NOPADDING\",\n                \"AES_128/ECB/PKCS5PADDING\",\n                \"DESEDE/ECB/NOPADDING\",\n                \"1.2.392.200011.61.1.1.3\",\n                \"AES/CBC/NOPADDING\",\n                \"AES/ECB/NOPADDING\",\n                \"AES/GCM-SIV/NOPADDING\",\n                \"AES_128/CBC/NOPADDING\",\n                \"AES_128/GCM-SIV/NOPADDING\",\n                \"AES_128/GCM/NOPADDING\",\n                \"AES_256/CBC/NOPADDING\",\n                \"AES_256/ECB/NOPADDING\",\n                \"AES_256/GCM-SIV/NOPADDING\",\n                \"AES_256/GCM/NOPADDING\",\n                \"1.2.840.113549.1.9.16.3.6\",\n                \"DESEDE/CBC/NOPADDING\",\n                \"CHACHA20-POLY1305\",\n                \"CHACHA20/POLY1305\"\n            )\n        }\n\n        private var securityCiphers: List<CipherType>? = null\n\n        fun registerSecurityCiphers(ciphers: List<CipherType>) {\n            if (!securityCiphers.isNullOrEmpty()) {\n                throw IllegalArgumentException(\"SecurityCiphers already registered\")\n            }\n            securityCiphers = ciphers.distinctBy { it.cipher.replace(\"OID.\", \"\").uppercase() }\n        }\n\n        val entries: List<CipherType> by lazy {\n            val available = securityCiphers?.mapNotNull { cipher ->\n                val oid = cipher.cipher\n\n                fun checkForBadOid(\n                    oid: String\n                ) = oid.isEmpty() || oid.contains(\"BROKEN\", true) || oid.contains(\"OLD\", true)\n\n                if (checkForBadOid(oid)) null\n                else {\n                    val strippedCipher = oid.replace(\"OID.\", \"\")\n                    SecureAlgorithmsMapping.findMatch(strippedCipher)?.let { mapping ->\n                        if (checkForBadOid(oid + mapping.algorithm)) return@mapNotNull null\n\n                        CipherType(\n                            cipher = oid,\n                            name = mapping.algorithm\n                        )\n                    } ?: cipher\n                }\n            }?.sortedBy { it.name } ?: emptyList()\n\n            listOf(\n                AES_NO_PADDING\n            ).let {\n                it + available\n            }.distinctBy { it.name.replace(\"-\", \"\") }\n        }\n\n        fun fromString(\n            cipher: String?\n        ): CipherType? = cipher?.let {\n            entries.find {\n                it.cipher == cipher\n            }\n        }\n\n        fun getInstance(\n            cipher: String,\n            name: String = cipher\n        ): CipherType = CipherType(\n            cipher = cipher,\n            name = name\n        )\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/ColorModel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\n@JvmInline\nvalue class ColorModel(\n    val colorInt: Int\n)\n\nfun Int.toColorModel() = ColorModel(this)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/DomainAspectRatio.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nsealed class DomainAspectRatio(\n    open val widthProportion: Float,\n    open val heightProportion: Float\n) {\n    val value: Float get() = widthProportion / heightProportion\n\n    data class Numeric(\n        override val widthProportion: Float,\n        override val heightProportion: Float\n    ) : DomainAspectRatio(widthProportion = widthProportion, heightProportion = heightProportion)\n\n    data object Free : DomainAspectRatio(widthProportion = -2f, heightProportion = 1f)\n    data object Original : DomainAspectRatio(widthProportion = -1f, heightProportion = 1f)\n\n    data class Custom(\n        override val widthProportion: Float = 1f,\n        override val heightProportion: Float = 1f\n    ) : DomainAspectRatio(widthProportion = widthProportion, heightProportion = heightProportion)\n\n    companion object {\n        val defaultList: List<DomainAspectRatio> by lazy {\n            listOf(\n                Free,\n                Original,\n                Custom(),\n                Numeric(widthProportion = 1f, heightProportion = 1f),\n                Numeric(widthProportion = 10f, heightProportion = 16f),\n                Numeric(widthProportion = 9f, heightProportion = 16f),\n                Numeric(widthProportion = 9f, heightProportion = 18.5f),\n                Numeric(widthProportion = 9f, heightProportion = 20f),\n                Numeric(widthProportion = 9f, heightProportion = 21f),\n                Numeric(widthProportion = 1f, heightProportion = 1.91f),\n                Numeric(widthProportion = 2f, heightProportion = 3f),\n                Numeric(widthProportion = 1f, heightProportion = 2f),\n                Numeric(widthProportion = 5f, heightProportion = 3f),\n                Numeric(widthProportion = 5f, heightProportion = 4f),\n                Numeric(widthProportion = 4f, heightProportion = 3f),\n                Numeric(widthProportion = 21f, heightProportion = 9f),\n                Numeric(widthProportion = 20f, heightProportion = 9f),\n                Numeric(widthProportion = 18.5f, heightProportion = 9f),\n                Numeric(widthProportion = 16f, heightProportion = 9f),\n                Numeric(widthProportion = 16f, heightProportion = 10f),\n                Numeric(widthProportion = 1.91f, heightProportion = 1f),\n                Numeric(widthProportion = 3f, heightProportion = 2f),\n                Numeric(widthProportion = 3f, heightProportion = 4f),\n                Numeric(widthProportion = 4f, heightProportion = 5f),\n                Numeric(widthProportion = 3f, heightProportion = 5f),\n                Numeric(widthProportion = 2f, heightProportion = 1f)\n            )\n        }\n\n        fun fromString(value: String): DomainAspectRatio? = when {\n            value == Free::class.simpleName -> Free\n            value == Original::class.simpleName -> Original\n            value.contains(Custom::class.simpleName!!) -> {\n                val (w, h) = value.split(\"|\")[1].split(\":\").map { it.toFloat() }\n                Custom(w, h)\n            }\n\n            value.contains(Numeric::class.simpleName!!) -> {\n                val (w, h) = value.split(\"|\")[1].split(\":\").map { it.toFloat() }\n                Numeric(w, h)\n            }\n\n            else -> null\n        }\n    }\n\n    fun asString(): String = when {\n        this is Custom || this is Numeric -> \"${this::class.simpleName}|${widthProportion}:${heightProportion}\"\n        else -> this::class.simpleName!!\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/ExtraDataType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nsealed interface ExtraDataType {\n    data object Gif : ExtraDataType\n    data object Pdf : ExtraDataType\n    data object File : ExtraDataType\n    data object Audio : ExtraDataType\n\n    data class Backup(val uri: String) : ExtraDataType\n    data class Text(val text: String) : ExtraDataType\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/FileModel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\n@JvmInline\nvalue class FileModel(\n    val uri: String\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/FloatSize.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\ndata class FloatSize(\n    val width: Float,\n    val height: Float\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/HashingType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType.Companion.registerSecurityMessageDigests\n\n\n@ConsistentCopyVisibility\n/**\n * [HashingType] multiplatform domain wrapper for java MessageDigest, in order to add custom digests, you need to call [registerSecurityMessageDigests] when process created\n **/\ndata class HashingType private constructor(\n    val digest: String,\n    val name: String = digest\n) {\n    companion object {\n        val MD5 = HashingType(\"MD5\")\n        val SHA_1 = HashingType(\"SHA-1\")\n        val SHA_224 = HashingType(\"SHA-224\")\n        val SHA_256 = HashingType(\"SHA-256\")\n        val SHA_384 = HashingType(\"SHA-384\")\n        val SHA_512 = HashingType(\"SHA-512\")\n\n        private var securityMessageDigests: List<String>? = null\n\n        fun registerSecurityMessageDigests(digests: List<String>) {\n            if (!securityMessageDigests.isNullOrEmpty()) {\n                throw IllegalArgumentException(\"SecurityMessageDigests already registered\")\n            }\n            securityMessageDigests = digests.distinctBy { it.replace(\"OID.\", \"\").uppercase() }\n        }\n\n        val entries: List<HashingType> by lazy {\n            val available = securityMessageDigests?.mapNotNull { messageDigest ->\n                if (messageDigest.isEmpty()) null\n                else {\n                    val digest = messageDigest.replace(\"OID.\", \"\")\n                    SecureAlgorithmsMapping.findMatch(digest)?.let { mapping ->\n                        HashingType(\n                            digest = messageDigest,\n                            name = mapping.algorithm\n                        )\n                    } ?: HashingType(digest = messageDigest)\n                }\n            }?.sortedBy { it.digest } ?: emptyList()\n\n            listOf(\n                MD5,\n                SHA_1,\n                SHA_224,\n                SHA_256,\n                SHA_384,\n                SHA_512,\n            ).let {\n                it + available\n            }.distinctBy { it.name.replace(\"-\", \"\") }\n        }\n\n        fun fromString(\n            digest: String?\n        ): HashingType? = digest?.let {\n            entries.find {\n                it.digest == digest\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/ImageModel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\n@JvmInline\nvalue class ImageModel(\n    val data: Any\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/IntegerSize.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"SameParameterValue\")\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nimport kotlin.math.max\n\ndata class IntegerSize(\n    val width: Int,\n    val height: Int\n) {\n    val aspectRatio: Float\n        get() = runCatching {\n            val value = width.toFloat() / height\n            if (value.isNaN()) throw IllegalArgumentException()\n\n            value\n        }.getOrNull() ?: 1f\n\n    val safeAspectRatio: Float\n        get() = aspectRatio\n            .coerceAtLeast(0.005f)\n            .coerceAtMost(1000f)\n\n    operator fun times(i: Float): IntegerSize = IntegerSize(\n        width = (width * i).toInt(),\n        height = (height * i).toInt()\n    ).coerceAtLeast(0, 0)\n\n    private fun coerceAtLeast(\n        minWidth: Int,\n        minHeight: Int\n    ): IntegerSize = IntegerSize(\n        width = width.coerceAtLeast(minWidth),\n        height = height.coerceAtLeast(minHeight)\n    )\n\n    fun isZero(): Boolean = width == 0 || height == 0\n\n    fun isDefined(): Boolean = this != Undefined\n\n    companion object {\n        val Undefined by lazy {\n            IntegerSize(-1, -1)\n        }\n\n        val Zero by lazy {\n            IntegerSize(0, 0)\n        }\n    }\n}\n\nfun max(size: IntegerSize): Int = maxOf(size.width, size.height)\n\ninfix fun Int.sizeTo(int: Int): IntegerSize = IntegerSize(this, int)\n\nfun IntegerSize.flexibleResize(\n    w: Int,\n    h: Int\n): IntegerSize {\n    val max = max(w, h)\n    return runCatching {\n        if (width > w) {\n            val aspectRatio = width.toDouble() / height.toDouble()\n            val targetHeight = w / aspectRatio\n            return@runCatching IntegerSize(w, targetHeight.toInt())\n        }\n\n        if (height >= width) {\n            val aspectRatio = width.toDouble() / height.toDouble()\n            val targetWidth = (max * aspectRatio).toInt()\n            IntegerSize(targetWidth, max)\n        } else {\n            val aspectRatio = height.toDouble() / width.toDouble()\n            val targetHeight = (max * aspectRatio).toInt()\n            IntegerSize(max, targetHeight)\n        }\n    }.getOrNull() ?: this\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/MimeType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\", \"MemberVisibilityCanBePrivate\")\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType.Multiple\n\nsealed class MimeType(\n    val entries: Set<String>\n) {\n    constructor(type: String) : this(setOf(type))\n\n    data class Single(\n        private val type: String\n    ) : MimeType(type) {\n        val entry = type\n    }\n\n    data class Multiple(\n        private val types: Set<String>\n    ) : MimeType(types)\n\n    companion object {\n        val All = Single(\"*/*\")\n\n        val Txt = Single(\"text/plain\")\n        val Pdf = Single(\"application/pdf\")\n        val Zip = Single(\"application/zip\")\n        val Webp = Single(\"image/webp\")\n        val Gif = Single(\"image/gif\")\n        val Apng = Single(\"image/apng\")\n        val StaticPng = Single(\"image/png\")\n        val Png = Apng + StaticPng\n        val Audio = Single(\"audio/*\")\n        val Jpg = Single(\"image/jpg\")\n        val Jpeg = Single(\"image/jpeg\")\n        val JpgAll = Jpg + Jpeg\n        val Font = Multiple(\n            setOf(\n                \"font/ttf\",\n                \"application/x-font-ttf\",\n                \"font/otf\"\n            )\n        )\n        val Bmp = Single(\"image/bmp\")\n        val Avif = Single(\"image/avif\")\n        val Heif = Single(\"image/heif\")\n        val Heic = Single(\"image/heic\")\n        val Jxl = Single(\"image/jxl\")\n        val Jp2 = Single(\"image/jp2\")\n        val Tiff = Single(\"image/tiff\")\n        val Qoi = Single(\"image/qoi\")\n        val Ico = Single(\"image/x-icon\")\n        val Svg = Single(\"image/svg+xml\")\n        val MarkupProject = Single(\"application/x-imagetoolbox-project\")\n        val MarkupProjectList = Multiple(\n            setOf(\n                MarkupProject.entry,\n                Zip.entry,\n                \"application/octet-stream\"\n            )\n        )\n    }\n\n}\n\nfun mimeType(\n    type: String\n): MimeType.Single = MimeType.Single(type)\n\nfun String.toMimeType() = mimeType(this)\n\nfun mimeTypeOf(\n    vararg types: String\n): Multiple = Multiple(types.toSet())\n\nfun mimeTypeOf(\n    vararg types: MimeType\n): Multiple = Multiple(types.flatMapTo(mutableSetOf()) { it.entries })\n\noperator fun MimeType.plus(\n    type: MimeType\n): Multiple = Multiple(types = entries + type.entries)\n\noperator fun Multiple.minus(\n    type: MimeType\n): Multiple = Multiple(types = entries - type.entries)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/OffsetModel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\ndata class OffsetModel(\n    val x: Float,\n    val y: Float\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/Outline.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\ndata class Outline(\n    val color: Int,\n    val width: Float\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/PerformanceClass.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nsealed interface PerformanceClass {\n    data object Low : PerformanceClass\n    data object Average : PerformanceClass\n    data object High : PerformanceClass\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/Position.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nenum class Position {\n    Center,\n    TopLeft,\n    TopRight,\n    BottomLeft,\n    BottomRight,\n    TopCenter,\n    CenterRight,\n    BottomCenter,\n    CenterLeft\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/Pt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nimport kotlin.math.min\n\nprivate const val NORMALIZATION_FACTOR = 500\n\n@JvmInline\nvalue class Pt(val value: Float) {\n    fun toPx(\n        size: IntegerSize\n    ): Float = min(\n        size.width * (value / NORMALIZATION_FACTOR),\n        size.height * (value / NORMALIZATION_FACTOR)\n    )\n\n\n    /**\n     * Add two [Pt]s together.\n     */\n    inline operator fun plus(other: Pt) = Pt(this.value + other.value)\n\n    /**\n     * Subtract a Pt from another one.\n     */\n    inline operator fun minus(other: Pt) = Pt(this.value - other.value)\n\n    /**\n     * This is the same as multiplying the Pt by -1.0.\n     */\n    inline operator fun unaryMinus() = Pt(-value)\n\n    /**\n     * Divide a Pt by a scalar.\n     */\n    inline operator fun div(other: Float): Pt = Pt(value / other)\n\n\n    inline operator fun div(other: Int): Pt = Pt(value / other)\n\n    /**\n     * Divide by another Pt to get a scalar.\n     */\n    inline operator fun div(other: Pt): Float = value / other.value\n\n    /**\n     * Multiply a Pt by a scalar.\n     */\n    inline operator fun times(other: Float): Pt = Pt(value * other)\n\n\n    inline operator fun times(other: Int): Pt = Pt(value * other)\n\n    /**\n     * Support comparing Dimensions with comparison operators.\n     */\n    inline operator fun compareTo(other: Pt) = value.compareTo(other.value)\n\n    companion object {\n        val Zero = Pt(0f)\n    }\n}\n\ninline val Float.pt: Pt get() = Pt(this)\ninline val Int.pt: Pt get() = Pt(this.toFloat())\n\ninline fun Pt.coerceIn(\n    min: Pt,\n    max: Pt\n) = Pt(value.coerceIn(min.value, max.value))"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/QrType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.cast\nimport java.util.Date\n\nsealed interface QrType {\n    val raw: String\n\n    fun isEmpty(): Boolean\n\n    data class Plain(\n        override val raw: String\n    ) : QrType {\n        constructor() : this(raw = \"\")\n\n        override fun isEmpty(): Boolean = raw.isBlank()\n    }\n\n    data class Url(\n        override val raw: String,\n        val title: String,\n        val url: String\n    ) : QrType {\n        constructor() : this(\n            raw = \"\",\n            title = \"\",\n            url = \"\"\n        )\n\n        override fun isEmpty(): Boolean = title.isBlank() && url.isBlank()\n    }\n\n    sealed interface Complex : QrType\n\n    data class Wifi(\n        override val raw: String,\n        val ssid: String,\n        val password: String,\n        val encryptionType: EncryptionType\n    ) : Complex {\n        constructor() : this(\n            raw = \"\",\n            ssid = \"\",\n            password = \"\",\n            encryptionType = EncryptionType.WPA\n        )\n\n        enum class EncryptionType {\n            OPEN, WPA, WEP\n        }\n\n        override fun isEmpty(): Boolean = ssid.isBlank() && password.isBlank()\n    }\n\n    data class Sms(\n        override val raw: String,\n        val message: String,\n        val phoneNumber: String\n    ) : Complex {\n        constructor() : this(\n            raw = \"\",\n            message = \"\",\n            phoneNumber = \"\"\n        )\n\n        override fun isEmpty(): Boolean = message.isBlank() && phoneNumber.isBlank()\n    }\n\n    data class Geo(\n        override val raw: String,\n        val latitude: Double?,\n        val longitude: Double?\n    ) : Complex {\n        constructor() : this(\n            raw = \"\",\n            latitude = null,\n            longitude = null\n        )\n\n        override fun isEmpty(): Boolean = latitude == null || longitude == null\n    }\n\n    data class Email(\n        override val raw: String,\n        val address: String,\n        val body: String,\n        val subject: String,\n        val type: Int\n    ) : Complex {\n        constructor() : this(\n            raw = \"\",\n            address = \"\",\n            body = \"\",\n            subject = \"\",\n            type = 0\n        )\n\n        override fun isEmpty(): Boolean = address.isBlank() && body.isBlank() && subject.isBlank()\n    }\n\n    data class Phone(\n        override val raw: String,\n        val number: String,\n        val type: Int\n    ) : Complex {\n        constructor() : this(\n            raw = \"\",\n            number = \"\",\n            type = 0\n        )\n\n        override fun isEmpty(): Boolean = number.isBlank()\n    }\n\n    data class Contact(\n        override val raw: String,\n        val addresses: List<Address>,\n        val emails: List<Email>,\n        val name: PersonName,\n        val organization: String,\n        val phones: List<Phone>,\n        val title: String,\n        val urls: List<String>\n    ) : Complex {\n        constructor() : this(\n            raw = \"\",\n            addresses = emptyList(),\n            emails = emptyList(),\n            name = PersonName(),\n            organization = \"\",\n            phones = emptyList(),\n            title = \"\",\n            urls = emptyList()\n        )\n\n        data class Address(\n            val addressLines: List<String>,\n            val type: Int\n        ) {\n            constructor() : this(\n                addressLines = emptyList(),\n                type = 0\n            )\n        }\n\n        data class PersonName(\n            val first: String,\n            val formattedName: String,\n            val last: String,\n            val middle: String,\n            val prefix: String,\n            val pronunciation: String,\n            val suffix: String\n        ) {\n            constructor() : this(\n                first = \"\",\n                formattedName = \"\",\n                last = \"\",\n                middle = \"\",\n                prefix = \"\",\n                pronunciation = \"\",\n                suffix = \"\"\n            )\n\n            fun isEmpty() = first.isBlank() &&\n                    formattedName.isBlank() &&\n                    last.isBlank() &&\n                    middle.isBlank() &&\n                    prefix.isBlank() &&\n                    pronunciation.isBlank() &&\n                    suffix.isBlank()\n        }\n\n        override fun isEmpty(): Boolean =\n            addresses.isEmpty() && emails.isEmpty() && name.isEmpty() && organization.isBlank() && phones.isEmpty() && title.isBlank() && urls.isEmpty()\n    }\n\n    data class Calendar(\n        override val raw: String,\n        val description: String,\n        val end: Date?,\n        val location: String,\n        val organizer: String,\n        val start: Date?,\n        val status: String,\n        val summary: String\n    ) : Complex {\n        constructor() : this(\n            raw = \"\",\n            description = \"\",\n            end = null,\n            location = \"\",\n            organizer = \"\",\n            start = null,\n            status = \"\",\n            summary = \"\",\n        )\n\n        override fun isEmpty(): Boolean =\n            description.isBlank() && end == null && location.isBlank() && organizer.isBlank() && start == null && status.isBlank() && summary.isBlank()\n    }\n\n    companion object {\n        val Empty = Plain(\"\")\n\n        val complexEntries: List<Complex> by lazy {\n            listOf(\n                Wifi(),\n                Sms(),\n                Geo(),\n                Email(),\n                Phone(),\n                Contact(),\n                Calendar()\n            )\n        }\n    }\n}\n\ninline fun <reified T : QrType> T.copy(raw: String): T = when (this) {\n    is QrType.Plain -> this.copy(raw = raw)\n    is QrType.Wifi -> this.copy(raw = raw)\n    is QrType.Url -> this.copy(raw = raw)\n    is QrType.Sms -> this.copy(raw = raw)\n    is QrType.Geo -> this.copy(raw = raw)\n    is QrType.Email -> this.copy(raw = raw)\n    is QrType.Phone -> this.copy(raw = raw)\n    is QrType.Contact -> this.copy(raw = raw)\n    is QrType.Calendar -> this.copy(raw = raw)\n}.cast()\n\n\ninline fun <T> QrType.ifNotEmpty(action: () -> T): T? = if (!isEmpty()) action() else null"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/RectModel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nimport kotlin.math.absoluteValue\nimport kotlin.math.max\nimport kotlin.math.min\n\ndata class RectModel(\n    /** The OffsetModel of the left edge of this rectangle from the x axis. */\n    val left: Float,\n\n    /** The OffsetModel of the top edge of this rectangle from the y axis. */\n    val top: Float,\n\n    /** The OffsetModel of the right edge of this rectangle from the x axis. */\n    val right: Float,\n\n    /** The OffsetModel of the bottom edge of this rectangle from the y axis. */\n    val bottom: Float,\n) {\n\n    companion object {\n        /** A rectangle with left, top, right, and bottom edges all at zero. */\n        val Zero: RectModel = RectModel(0.0f, 0.0f, 0.0f, 0.0f)\n    }\n\n    /** The distance between the left and right edges of this rectangle. */\n\n    inline val width: Float\n        get() = right - left\n\n    /** The distance between the top and bottom edges of this rectangle. */\n\n    inline val height: Float\n        get() = bottom - top\n\n    /** The distance between the upper-left corner and the lower-right corner of this rectangle. */\n\n    val size: FloatSize\n        get() = FloatSize(width, height)\n\n    /** Whether any of the coordinates of this rectangle are equal to positive infinity. */\n    // included for consistency with OffsetModel and Size\n\n    val isInfinite: Boolean\n        get() =\n            (left == Float.POSITIVE_INFINITY) or\n                    (top == Float.POSITIVE_INFINITY) or\n                    (right == Float.POSITIVE_INFINITY) or\n                    (bottom == Float.POSITIVE_INFINITY)\n\n    /** Whether all coordinates of this rectangle are finite. */\n\n    val isFinite: Boolean\n        get() =\n            ((left.toRawBits() and 0x7fffffff) < FloatInfinityBase) and\n                    ((top.toRawBits() and 0x7fffffff) < FloatInfinityBase) and\n                    ((right.toRawBits() and 0x7fffffff) < FloatInfinityBase) and\n                    ((bottom.toRawBits() and 0x7fffffff) < FloatInfinityBase)\n\n    /** Whether this rectangle encloses a non-zero area. Negative areas are considered empty. */\n\n    val isEmpty: Boolean\n        get() = (left >= right) or (top >= bottom)\n\n    /**\n     * Returns a new rectangle translated by the given OffsetModel.\n     *\n     * To translate a rectangle by separate x and y components rather than by an [offset], consider\n     * [translate].\n     */\n\n    fun translate(offset: OffsetModel): RectModel {\n        return RectModel(\n            left + offset.x,\n            top + offset.y,\n            right + offset.x,\n            bottom + offset.y\n        )\n    }\n\n    /**\n     * Returns a new rectangle with translateX added to the x components and translateY added to the\n     * y components.\n     */\n\n    fun translate(translateX: Float, translateY: Float): RectModel {\n        return RectModel(\n            left + translateX,\n            top + translateY,\n            right + translateX,\n            bottom + translateY\n        )\n    }\n\n    /** Returns a new rectangle with edges moved outwards by the given delta. */\n\n    fun inflate(delta: Float): RectModel {\n        return RectModel(left - delta, top - delta, right + delta, bottom + delta)\n    }\n\n    /** Returns a new rectangle with edges moved inwards by the given delta. */\n    fun deflate(delta: Float): RectModel = inflate(-delta)\n\n    /**\n     * Returns a new rectangle that is the intersection of the given rectangle and this rectangle.\n     * The two rectangles must overlap for this to be meaningful. If the two rectangles do not\n     * overlap, then the resulting RectModel will have a negative width or height.\n     */\n\n    fun intersect(other: RectModel): RectModel {\n        return RectModel(\n            max(left, other.left),\n            max(top, other.top),\n            min(right, other.right),\n            min(bottom, other.bottom),\n        )\n    }\n\n    /**\n     * Returns a new rectangle that is the intersection of the given rectangle and this rectangle.\n     * The two rectangles must overlap for this to be meaningful. If the two rectangles do not\n     * overlap, then the resulting RectModel will have a negative width or height.\n     */\n\n    fun intersect(\n        otherLeft: Float,\n        otherTop: Float,\n        otherRight: Float,\n        otherBottom: Float\n    ): RectModel {\n        return RectModel(\n            max(left, otherLeft),\n            max(top, otherTop),\n            min(right, otherRight),\n            min(bottom, otherBottom),\n        )\n    }\n\n    /** Whether `other` has a nonzero area of overlap with this rectangle. */\n    fun overlaps(other: RectModel): Boolean {\n        return (left < other.right) and\n                (other.left < right) and\n                (top < other.bottom) and\n                (other.top < bottom)\n    }\n\n    /** The lesser of the magnitudes of the [width] and the [height] of this rectangle. */\n    val minDimension: Float\n        get() = min(width.absoluteValue, height.absoluteValue)\n\n    /** The greater of the magnitudes of the [width] and the [height] of this rectangle. */\n    val maxDimension: Float\n        get() = max(width.absoluteValue, height.absoluteValue)\n\n    /** The OffsetModel to the intersection of the top and left edges of this rectangle. */\n    val topLeft: OffsetModel\n        get() = OffsetModel(left, top)\n\n    /** The OffsetModel to the center of the top edge of this rectangle. */\n    val topCenter: OffsetModel\n        get() = OffsetModel(left + width / 2.0f, top)\n\n    /** The OffsetModel to the intersection of the top and right edges of this rectangle. */\n    val topRight: OffsetModel\n        get() = OffsetModel(right, top)\n\n    /** The OffsetModel to the center of the left edge of this rectangle. */\n    val centerLeft: OffsetModel\n        get() = OffsetModel(left, top + height / 2.0f)\n\n    /**\n     * The OffsetModel to the point halfway between the left and right and the top and bottom edges of\n     * this rectangle.\n     *\n     * See also [Size.center].\n     */\n    val center: OffsetModel\n        get() = OffsetModel(left + width / 2.0f, top + height / 2.0f)\n\n    /** The OffsetModel to the center of the right edge of this rectangle. */\n    val centerRight: OffsetModel\n        get() = OffsetModel(right, top + height / 2.0f)\n\n    /** The OffsetModel to the intersection of the bottom and left edges of this rectangle. */\n    val bottomLeft: OffsetModel\n        get() = OffsetModel(left, bottom)\n\n    /** The OffsetModel to the center of the bottom edge of this rectangle. */\n    val bottomCenter: OffsetModel\n        get() {\n            return OffsetModel(left + width / 2.0f, bottom)\n        }\n\n    /** The OffsetModel to the intersection of the bottom and right edges of this rectangle. */\n    val bottomRight: OffsetModel\n        get() {\n            return OffsetModel(right, bottom)\n        }\n\n    /**\n     * Whether the point specified by the given OffsetModel (which is assumed to be relative to the\n     * origin) lies between the left and right and the top and bottom edges of this rectangle.\n     *\n     * Rectangles include their top and left edges but exclude their bottom and right edges.\n     */\n    operator fun contains(offset: OffsetModel): Boolean {\n        val x = offset.x\n        val y = offset.y\n        return (x >= left) and (x < right) and (y >= top) and (y < bottom)\n    }\n}\n\ninternal const val FloatInfinityBase = 0x7f800000"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/SecureAlgorithmsMapping.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n@file:Suppress(\"EnumEntryName\", \"unused\")\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\n/**\n * This utility class maps algorithm name to the corresponding oid strings.\n * NOTE: for 100% backward compatibility, the standard name for the enum\n * is determined by existing usage and may be in lowercase/uppercase in\n * order to match existing output.\n */\nenum class SecureAlgorithmsMapping {\n    // X.500 Attributes 2.5.4.*\n    CommonName(\"2.5.4.3\"),\n    Surname(\"2.5.4.4\"),\n    SerialNumber(\"2.5.4.5\"),\n    CountryName(\"2.5.4.6\"),\n    LocalityName(\"2.5.4.7\"),\n    StateName(\"2.5.4.8\"),\n    StreetAddress(\"2.5.4.9\"),\n    OrgName(\"2.5.4.10\"),\n    OrgUnitName(\"2.5.4.11\"),\n    Title(\"2.5.4.12\"),\n    GivenName(\"2.5.4.42\"),\n    Initials(\"2.5.4.43\"),\n    GenerationQualifier(\"2.5.4.44\"),\n    DNQualifier(\"2.5.4.46\"),\n\n    // Certificate Extension 2.5.29.*\n    SubjectDirectoryAttributes(\"2.5.29.9\"),\n    SubjectKeyID(\"2.5.29.14\"),\n    KeyUsage(\"2.5.29.15\"),\n    PrivateKeyUsage(\"2.5.29.16\"),\n    SubjectAlternativeName(\"2.5.29.17\"),\n    IssuerAlternativeName(\"2.5.29.18\"),\n    BasicConstraints(\"2.5.29.19\"),\n    CRLNumber(\"2.5.29.20\"),\n    ReasonCode(\"2.5.29.21\"),\n    HoldInstructionCode(\"2.5.29.23\"),\n    InvalidityDate(\"2.5.29.24\"),\n    DeltaCRLIndicator(\"2.5.29.27\"),\n    IssuingDistributionPoint(\"2.5.29.28\"),\n    CertificateIssuer(\"2.5.29.29\"),\n    NameConstraints(\"2.5.29.30\"),\n    CRLDistributionPoints(\"2.5.29.31\"),\n    CertificatePolicies(\"2.5.29.32\"),\n    CE_CERT_POLICIES_ANY(\"2.5.29.32.0\"),\n    PolicyMappings(\"2.5.29.33\"),\n    AuthorityKeyID(\"2.5.29.35\"),\n    PolicyConstraints(\"2.5.29.36\"),\n    extendedKeyUsage(\"2.5.29.37\"),\n    anyExtendedKeyUsage(\"2.5.29.37.0\"),\n    FreshestCRL(\"2.5.29.46\"),\n    InhibitAnyPolicy(\"2.5.29.54\"),\n\n    // PKIX 1.3.6.1.5.5.7.\n    AuthInfoAccess(\"1.3.6.1.5.5.7.1.1\"),\n    SubjectInfoAccess(\"1.3.6.1.5.5.7.1.11\"),\n\n    // key usage purposes - PKIX.3.*\n    serverAuth(\"1.3.6.1.5.5.7.3.1\"),\n    clientAuth(\"1.3.6.1.5.5.7.3.2\"),\n    codeSigning(\"1.3.6.1.5.5.7.3.3\"),\n    emailProtection(\"1.3.6.1.5.5.7.3.4\"),\n    ipsecEndSystem(\"1.3.6.1.5.5.7.3.5\"),\n    ipsecTunnel(\"1.3.6.1.5.5.7.3.6\"),\n    ipsecUser(\"1.3.6.1.5.5.7.3.7\"),\n    KP_TimeStamping(\"1.3.6.1.5.5.7.3.8\", \"timeStamping\"),\n    OCSPSigning(\"1.3.6.1.5.5.7.3.9\"),\n\n    // access descriptors - PKIX.48.*\n    OCSP(\"1.3.6.1.5.5.7.48.1\"),\n    OCSPBasicResponse(\"1.3.6.1.5.5.7.48.1.1\"),\n    OCSPNonceExt(\"1.3.6.1.5.5.7.48.1.2\"),\n    OCSPNoCheck(\"1.3.6.1.5.5.7.48.1.5\"),\n    caIssuers(\"1.3.6.1.5.5.7.48.2\"),\n    AD_TimeStamping(\"1.3.6.1.5.5.7.48.3\", \"timeStamping\"),\n    caRepository(\"1.3.6.1.5.5.7.48.5\", \"caRepository\"),\n\n    // NIST --\n    // AES 2.16.840.1.101.3.4.1.*\n    AES(\"2.16.840.1.101.3.4.1\"),\n    AES_128_ECB_NoPadding(\"2.16.840.1.101.3.4.1.1\", \"AES_128/ECB/NoPadding\"),\n    AES_128_CBC_NoPadding(\"2.16.840.1.101.3.4.1.2\", \"AES_128/CBC/NoPadding\"),\n    AES_128_OFB_NoPadding(\"2.16.840.1.101.3.4.1.3\", \"AES_128/OFB/NoPadding\"),\n    AES_128_CFB_NoPadding(\"2.16.840.1.101.3.4.1.4\", \"AES_128/CFB/NoPadding\"),\n    AES_128_KW_NoPadding(\n        \"2.16.840.1.101.3.4.1.5\", \"AES_128/KW/NoPadding\",\n        \"AESWrap_128\"\n    ),\n    AES_128_GCM_NoPadding(\"2.16.840.1.101.3.4.1.6\", \"AES_128/GCM/NoPadding\"),\n    AES_128_KWP_NoPadding(\n        \"2.16.840.1.101.3.4.1.8\", \"AES_128/KWP/NoPadding\",\n        \"AESWrapPad_128\"\n    ),\n\n    AES_192_ECB_NoPadding(\"2.16.840.1.101.3.4.1.21\", \"AES_192/ECB/NoPadding\"),\n    AES_192_CBC_NoPadding(\"2.16.840.1.101.3.4.1.22\", \"AES_192/CBC/NoPadding\"),\n    AES_192_OFB_NoPadding(\"2.16.840.1.101.3.4.1.23\", \"AES_192/OFB/NoPadding\"),\n    AES_192_CFB_NoPadding(\"2.16.840.1.101.3.4.1.24\", \"AES_192/CFB/NoPadding\"),\n    AES_192_KW_NoPadding(\n        \"2.16.840.1.101.3.4.1.25\", \"AES_192/KW/NoPadding\",\n        \"AESWrap_192\"\n    ),\n    AES_192_GCM_NoPadding(\"2.16.840.1.101.3.4.1.26\", \"AES_192/GCM/NoPadding\"),\n    AES_192_KWP_NoPadding(\n        \"2.16.840.1.101.3.4.1.28\", \"AES_192/KWP/NoPadding\",\n        \"AESWrapPad_192\"\n    ),\n\n    AES_256_ECB_NoPadding(\"2.16.840.1.101.3.4.1.41\", \"AES_256/ECB/NoPadding\"),\n    AES_256_CBC_NoPadding(\"2.16.840.1.101.3.4.1.42\", \"AES_256/CBC/NoPadding\"),\n    AES_256_OFB_NoPadding(\"2.16.840.1.101.3.4.1.43\", \"AES_256/OFB/NoPadding\"),\n    AES_256_CFB_NoPadding(\"2.16.840.1.101.3.4.1.44\", \"AES_256/CFB/NoPadding\"),\n    AES_256_KW_NoPadding(\n        \"2.16.840.1.101.3.4.1.45\", \"AES_256/KW/NoPadding\",\n        \"AESWrap_256\"\n    ),\n    AES_256_GCM_NoPadding(\"2.16.840.1.101.3.4.1.46\", \"AES_256/GCM/NoPadding\"),\n    AES_256_KWP_NoPadding(\n        \"2.16.840.1.101.3.4.1.48\", \"AES_256/KWP/NoPadding\",\n        \"AESWrapPad_256\"\n    ),\n\n    // hashAlgs 2.16.840.1.101.3.4.2.*\n    SHA_256(\"2.16.840.1.101.3.4.2.1\", \"SHA-256\", \"SHA256\"),\n    SHA_384(\"2.16.840.1.101.3.4.2.2\", \"SHA-384\", \"SHA384\"),\n    SHA_512(\"2.16.840.1.101.3.4.2.3\", \"SHA-512\", \"SHA512\"),\n    SHA_224(\"2.16.840.1.101.3.4.2.4\", \"SHA-224\", \"SHA224\"),\n    SHA_512_224(\"2.16.840.1.101.3.4.2.5\", \"SHA-512/224\", \"SHA512/224\"),\n    SHA_512_256(\"2.16.840.1.101.3.4.2.6\", \"SHA-512/256\", \"SHA512/256\"),\n    SHA3_224(\"2.16.840.1.101.3.4.2.7\", \"SHA3-224\"),\n    SHA3_256(\"2.16.840.1.101.3.4.2.8\", \"SHA3-256\"),\n    SHA3_384(\"2.16.840.1.101.3.4.2.9\", \"SHA3-384\"),\n    SHA3_512(\"2.16.840.1.101.3.4.2.10\", \"SHA3-512\"),\n    SHAKE128(\"2.16.840.1.101.3.4.2.11\"),\n    SHAKE256(\"2.16.840.1.101.3.4.2.12\"),\n    HmacSHA3_224(\"2.16.840.1.101.3.4.2.13\", \"HmacSHA3-224\"),\n    HmacSHA3_256(\"2.16.840.1.101.3.4.2.14\", \"HmacSHA3-256\"),\n    HmacSHA3_384(\"2.16.840.1.101.3.4.2.15\", \"HmacSHA3-384\"),\n    HmacSHA3_512(\"2.16.840.1.101.3.4.2.16\", \"HmacSHA3-512\"),\n    SHAKE128_LEN(\"2.16.840.1.101.3.4.2.17\", \"SHAKE128-LEN\"),\n    SHAKE256_LEN(\"2.16.840.1.101.3.4.2.18\", \"SHAKE256-LEN\"),\n    SHA512_224(\"1.0.10118.3.0.55\", \"SHA-512/224\"),\n    SHA512_256(\"2.16.840.1.101.3.4.2.12\", \"SHA-512/256\"),\n    SHA384(\"2.16.840.1.101.3.4.2.11\", \"SHA-384\"),\n    SHA512(\"2.16.840.1.101.3.4.2.10\", \"SHA-512\"),\n    DSTU7564_256(\"1.2.804.2.1.1.1.1.2.2.3\", \"DSTU-7564-256\"),\n    DSTU7564_384(\"1.2.804.2.1.1.1.1.2.2.2\", \"DSTU-7564-384\"),\n    DSTU7564_512(\"1.2.804.2.1.1.1.1.2.2.1\", \"DSTU-7564-512\"),\n    SHA224(\"2.16.840.1.101.3.4.2.9\", \"SHA-224\"),\n    SHA256(\"2.16.840.1.101.3.4.2.8\", \"SHA-256\"),\n    SHA1(\"2.16.840.1.101.3.4.2.7\", \"SHA-1\"),\n\n    // sigAlgs 2.16.840.1.101.3.4.3.*\n    SHA224withDSA(\"2.16.840.1.101.3.4.3.1\"),\n    SHA256withDSA(\"2.16.840.1.101.3.4.3.2\"),\n    SHA384withDSA(\"2.16.840.1.101.3.4.3.3\"),\n    SHA512withDSA(\"2.16.840.1.101.3.4.3.4\"),\n    SHA3_224withDSA(\"2.16.840.1.101.3.4.3.5\", \"SHA3-224withDSA\"),\n    SHA3_256withDSA(\"2.16.840.1.101.3.4.3.6\", \"SHA3-256withDSA\"),\n    SHA3_384withDSA(\"2.16.840.1.101.3.4.3.7\", \"SHA3-384withDSA\"),\n    SHA3_512withDSA(\"2.16.840.1.101.3.4.3.8\", \"SHA3-512withDSA\"),\n    SHA3_224withECDSA(\"2.16.840.1.101.3.4.3.9\", \"SHA3-224withECDSA\"),\n    SHA3_256withECDSA(\"2.16.840.1.101.3.4.3.10\", \"SHA3-256withECDSA\"),\n    SHA3_384withECDSA(\"2.16.840.1.101.3.4.3.11\", \"SHA3-384withECDSA\"),\n    SHA3_512withECDSA(\"2.16.840.1.101.3.4.3.12\", \"SHA3-512withECDSA\"),\n    SHA3_224withRSA(\"2.16.840.1.101.3.4.3.13\", \"SHA3-224withRSA\"),\n    SHA3_256withRSA(\"2.16.840.1.101.3.4.3.14\", \"SHA3-256withRSA\"),\n    SHA3_384withRSA(\"2.16.840.1.101.3.4.3.15\", \"SHA3-384withRSA\"),\n    SHA3_512withRSA(\"2.16.840.1.101.3.4.3.16\", \"SHA3-512withRSA\"),\n    ML_DSA_44(\"2.16.840.1.101.3.4.3.17\", \"ML-DSA-44\"),\n    ML_DSA_65(\"2.16.840.1.101.3.4.3.18\", \"ML-DSA-65\"),\n    ML_DSA_87(\"2.16.840.1.101.3.4.3.19\", \"ML-DSA-87\"),\n\n    // kems 2.16.840.1.101.3.4.4.*\n    ML_KEM_512(\"2.16.840.1.101.3.4.4.1\", \"ML-KEM-512\"),\n    ML_KEM_768(\"2.16.840.1.101.3.4.4.2\", \"ML-KEM-768\"),\n    ML_KEM_1024(\"2.16.840.1.101.3.4.4.3\", \"ML-KEM-1024\"),\n\n    // RSASecurity\n    // PKCS1 1.2.840.113549.1.1.*\n    PKCS1(\"1.2.840.113549.1.1\", \"RSA\"),\n    RSA(\"1.2.840.113549.1.1.1\"),  // RSA encryption\n\n    MD2withRSA(\"1.2.840.113549.1.1.2\"),\n    MD5withRSA(\"1.2.840.113549.1.1.4\"),\n    SHA1withRSA(\"1.2.840.113549.1.1.5\"),\n    OAEP(\"1.2.840.113549.1.1.7\"),\n    MGF1(\"1.2.840.113549.1.1.8\"),\n    PSpecified(\"1.2.840.113549.1.1.9\"),\n    RSASSA_PSS(\"1.2.840.113549.1.1.10\", \"RSASSA-PSS\", \"PSS\"),\n    SHA256withRSA(\"1.2.840.113549.1.1.11\"),\n    SHA384withRSA(\"1.2.840.113549.1.1.12\"),\n    SHA512withRSA(\"1.2.840.113549.1.1.13\"),\n    SHA224withRSA(\"1.2.840.113549.1.1.14\"),\n    SHA512_224withRSA(\"1.2.840.113549.1.1.15\", \"SHA512/224withRSA\"),\n    SHA512_256withRSA(\"1.2.840.113549.1.1.16\", \"SHA512/256withRSA\"),\n\n    // PKCS3 1.2.840.113549.1.3.*\n    DiffieHellman(\"1.2.840.113549.1.3.1\", \"DiffieHellman\", \"DH\"),\n\n    // PKCS5 1.2.840.113549.1.5.*\n    PBEWithMD5AndDES(\"1.2.840.113549.1.5.3\"),\n    PBEWithMD5AndRC2(\"1.2.840.113549.1.5.6\"),\n    PBEWithSHA1AndDES(\"1.2.840.113549.1.5.10\"),\n    PBEWithSHA1AndRC2(\"1.2.840.113549.1.5.11\"),\n    PBKDF2WithHmacSHA1(\"1.2.840.113549.1.5.12\"),\n    PBES2(\"1.2.840.113549.1.5.13\"),\n\n    // PKCS7 1.2.840.113549.1.7.*\n    PKCS7(\"1.2.840.113549.1.7\"),\n    Data(\"1.2.840.113549.1.7.1\"),\n    SignedData(\"1.2.840.113549.1.7.2\"),\n    JDK_OLD_Data(\"1.2.840.1113549.1.7.1\"),  // extra 1 in 4th component\n    JDK_OLD_SignedData(\"1.2.840.1113549.1.7.2\"),\n    EnvelopedData(\"1.2.840.113549.1.7.3\"),\n    SignedAndEnvelopedData(\"1.2.840.113549.1.7.4\"),\n    DigestedData(\"1.2.840.113549.1.7.5\"),\n    EncryptedData(\"1.2.840.113549.1.7.6\"),\n\n    // PKCS9 1.2.840.113549.1.9.*\n    EmailAddress(\"1.2.840.113549.1.9.1\"),\n    UnstructuredName(\"1.2.840.113549.1.9.2\"),\n    ContentType(\"1.2.840.113549.1.9.3\"),\n    MessageDigest(\"1.2.840.113549.1.9.4\"),\n    SigningTime(\"1.2.840.113549.1.9.5\"),\n    CounterSignature(\"1.2.840.113549.1.9.6\"),\n    ChallengePassword(\"1.2.840.113549.1.9.7\"),\n    UnstructuredAddress(\"1.2.840.113549.1.9.8\"),\n    ExtendedCertificateAttributes(\"1.2.840.113549.1.9.9\"),\n    IssuerAndSerialNumber(\"1.2.840.113549.1.9.10\"),\n    ExtensionRequest(\"1.2.840.113549.1.9.14\"),\n    SMIMECapability(\"1.2.840.113549.1.9.15\"),\n    TimeStampTokenInfo(\"1.2.840.113549.1.9.16.1.4\"),\n    SigningCertificate(\"1.2.840.113549.1.9.16.2.12\"),\n    SignatureTimestampToken(\"1.2.840.113549.1.9.16.2.14\"),\n    HSSLMS(\"1.2.840.113549.1.9.16.3.17\", \"HSS/LMS\"),\n    CHACHA20_POLY1305(\"1.2.840.113549.1.9.16.3.18\", \"CHACHA20-POLY1305\"),\n    FriendlyName(\"1.2.840.113549.1.9.20\"),\n    LocalKeyID(\"1.2.840.113549.1.9.21\"),\n    CertTypeX509(\"1.2.840.113549.1.9.22.1\"),\n    CMSAlgorithmProtection(\"1.2.840.113549.1.9.52\"),\n\n    // PKCS12 1.2.840.113549.1.12.*\n    PBEWithSHA1AndRC4_128(\"1.2.840.113549.1.12.1.1\"),\n    PBEWithSHA1AndRC4_40(\"1.2.840.113549.1.12.1.2\"),\n    PBEWithSHA1AndDESede(\"1.2.840.113549.1.12.1.3\"),\n    PBEWithSHA1AndRC2_128(\"1.2.840.113549.1.12.1.5\"),\n    PBEWithSHA1AndRC2_40(\"1.2.840.113549.1.12.1.6\"),\n    PKCS8ShroudedKeyBag(\"1.2.840.113549.1.12.10.1.2\"),\n    CertBag(\"1.2.840.113549.1.12.10.1.3\"),\n    SecretBag(\"1.2.840.113549.1.12.10.1.5\"),\n\n    // digestAlgs 1.2.840.113549.2.*\n    MD2(\"1.2.840.113549.2.2\"),\n    MD5(\"1.2.840.113549.2.5\"),\n    HmacSHA1(\"1.2.840.113549.2.7\"),\n    HmacSHA224(\"1.2.840.113549.2.8\"),\n    HmacSHA256(\"1.2.840.113549.2.9\"),\n    HmacSHA384(\"1.2.840.113549.2.10\"),\n    HmacSHA512(\"1.2.840.113549.2.11\"),\n    HmacSHA512_224(\"1.2.840.113549.2.12\", \"HmacSHA512/224\"),\n    HmacSHA512_256(\"1.2.840.113549.2.13\", \"HmacSHA512/256\"),\n\n    // encryptionAlgs 1.2.840.113549.3.*\n    RC2_CBC_PKCS5Padding(\"1.2.840.113549.3.2\", \"RC2/CBC/PKCS5Padding\", \"RC2\"),\n    ARCFOUR(\"1.2.840.113549.3.4\", \"ARCFOUR\", \"RC4\"),\n    DESede_CBC_NoPadding(\"1.2.840.113549.3.7\", \"DESede/CBC/NoPadding\"),\n    RC5_CBC_PKCS5Padding(\"1.2.840.113549.3.9\", \"RC5/CBC/PKCS5Padding\"),\n\n    // ANSI --\n    // X9 1.2.840.10040.4.*\n    DSA(\"1.2.840.10040.4.1\"),\n    SHA1withDSA(\"1.2.840.10040.4.3\", \"SHA1withDSA\", \"DSS\"),\n\n    // X9.62 1.2.840.10045.*\n    EC(\"1.2.840.10045.2.1\"),\n\n    c2pnb163v1(\"1.2.840.10045.3.0.1\", \"X9.62 c2pnb163v1\"),\n    c2pnb163v2(\"1.2.840.10045.3.0.2\", \"X9.62 c2pnb163v2\"),\n    c2pnb163v3(\"1.2.840.10045.3.0.3\", \"X9.62 c2pnb163v3\"),\n    c2pnb176w1(\"1.2.840.10045.3.0.4\", \"X9.62 c2pnb176w1\"),\n    c2tnb191v1(\"1.2.840.10045.3.0.5\", \"X9.62 c2tnb191v1\"),\n    c2tnb191v2(\"1.2.840.10045.3.0.6\", \"X9.62 c2tnb191v2\"),\n    c2tnb191v3(\"1.2.840.10045.3.0.7\", \"X9.62 c2tnb191v3\"),\n\n    c2pnb208w1(\"1.2.840.10045.3.0.10\", \"X9.62 c2pnb208w1\"),\n    c2tnb239v1(\"1.2.840.10045.3.0.11\", \"X9.62 c2tnb239v1\"),\n    c2tnb239v2(\"1.2.840.10045.3.0.12\", \"X9.62 c2tnb239v2\"),\n    c2tnb239v3(\"1.2.840.10045.3.0.13\", \"X9.62 c2tnb239v3\"),\n\n    c2pnb272w1(\"1.2.840.10045.3.0.16\", \"X9.62 c2pnb272w1\"),\n    c2pnb304w1(\"1.2.840.10045.3.0.17\", \"X9.62 c2pnb304w1\"),\n    c2tnb359v1(\"1.2.840.10045.3.0.18\", \"X9.62 c2tnb359v1\"),\n\n    c2pnb368w1(\"1.2.840.10045.3.0.19\", \"X9.62 c2pnb368w1\"),\n    c2tnb431r1(\"1.2.840.10045.3.0.20\", \"X9.62 c2tnb431r1\"),\n\n    secp192r1(\n        \"1.2.840.10045.3.1.1\",\n        \"secp192r1\", \"NIST P-192\", \"X9.62 prime192v1\"\n    ),\n    prime192v2(\"1.2.840.10045.3.1.2\", \"X9.62 prime192v2\"),\n    prime192v3(\"1.2.840.10045.3.1.3\", \"X9.62 prime192v3\"),\n    prime239v1(\"1.2.840.10045.3.1.4\", \"X9.62 prime239v1\"),\n    prime239v2(\"1.2.840.10045.3.1.5\", \"X9.62 prime239v2\"),\n    prime239v3(\"1.2.840.10045.3.1.6\", \"X9.62 prime239v3\"),\n    secp256r1(\n        \"1.2.840.10045.3.1.7\",\n        \"secp256r1\", \"NIST P-256\", \"X9.62 prime256v1\"\n    ),\n    SHA1withECDSA(\"1.2.840.10045.4.1\"),\n    SHA224withECDSA(\"1.2.840.10045.4.3.1\"),\n    SHA256withECDSA(\"1.2.840.10045.4.3.2\"),\n    SHA384withECDSA(\"1.2.840.10045.4.3.3\"),\n    SHA512withECDSA(\"1.2.840.10045.4.3.4\"),\n    SpecifiedSHA2withECDSA(\"1.2.840.10045.4.3\"),\n\n    // X9.42 1.2.840.10046.2.*\n    X942_DH(\"1.2.840.10046.2.1\", \"DiffieHellman\"),\n\n    // Teletrust 1.3.36.*\n    brainpoolP160r1(\"1.3.36.3.3.2.8.1.1.1\"),\n    brainpoolP192r1(\"1.3.36.3.3.2.8.1.1.3\"),\n    brainpoolP224r1(\"1.3.36.3.3.2.8.1.1.5\"),\n    brainpoolP256r1(\"1.3.36.3.3.2.8.1.1.7\"),\n    brainpoolP320r1(\"1.3.36.3.3.2.8.1.1.9\"),\n    brainpoolP384r1(\"1.3.36.3.3.2.8.1.1.11\"),\n    brainpoolP512r1(\"1.3.36.3.3.2.8.1.1.13\"),\n\n    // Certicom 1.3.132.*\n    sect163k1(\"1.3.132.0.1\", \"sect163k1\", \"NIST K-163\"),\n    sect163r1(\"1.3.132.0.2\"),\n    sect239k1(\"1.3.132.0.3\"),\n    sect113r1(\"1.3.132.0.4\"),\n    sect113r2(\"1.3.132.0.5\"),\n    secp112r1(\"1.3.132.0.6\"),\n    secp112r2(\"1.3.132.0.7\"),\n    secp160r1(\"1.3.132.0.8\"),\n    secp160k1(\"1.3.132.0.9\"),\n    secp256k1(\"1.3.132.0.10\"),\n    sect163r2(\"1.3.132.0.15\", \"sect163r2\", \"NIST B-163\"),\n    sect283k1(\"1.3.132.0.16\", \"sect283k1\", \"NIST K-283\"),\n    sect283r1(\"1.3.132.0.17\", \"sect283r1\", \"NIST B-283\"),\n\n    sect131r1(\"1.3.132.0.22\"),\n    sect131r2(\"1.3.132.0.23\"),\n    sect193r1(\"1.3.132.0.24\"),\n    sect193r2(\"1.3.132.0.25\"),\n    sect233k1(\"1.3.132.0.26\", \"sect233k1\", \"NIST K-233\"),\n    sect233r1(\"1.3.132.0.27\", \"sect233r1\", \"NIST B-233\"),\n    secp128r1(\"1.3.132.0.28\"),\n    secp128r2(\"1.3.132.0.29\"),\n    secp160r2(\"1.3.132.0.30\"),\n    secp192k1(\"1.3.132.0.31\"),\n    secp224k1(\"1.3.132.0.32\"),\n    secp224r1(\"1.3.132.0.33\", \"secp224r1\", \"NIST P-224\"),\n    secp384r1(\"1.3.132.0.34\", \"secp384r1\", \"NIST P-384\"),\n    secp521r1(\"1.3.132.0.35\", \"secp521r1\", \"NIST P-521\"),\n    sect409k1(\"1.3.132.0.36\", \"sect409k1\", \"NIST K-409\"),\n    sect409r1(\"1.3.132.0.37\", \"sect409r1\", \"NIST B-409\"),\n    sect571k1(\"1.3.132.0.38\", \"sect571k1\", \"NIST K-571\"),\n    sect571r1(\"1.3.132.0.39\", \"sect571r1\", \"NIST B-571\"),\n\n    ECDH(\"1.3.132.1.12\"),\n\n    // OIW secsig 1.3.14.3.*\n    OIW_DES_CBC(\"1.3.14.3.2.7\", \"DES/CBC\", \"DES\"),\n\n    OIW_DSA(\"1.3.14.3.2.12\", \"DSA\"),\n\n    OIW_JDK_SHA1withDSA(\"1.3.14.3.2.13\", \"SHA1withDSA\"),\n\n    OIW_SHA1withRSA_Odd(\"1.3.14.3.2.15\", \"SHA1withRSA\"),\n\n    DESede(\"1.3.14.3.2.17\", \"DESede\"),\n\n    SHA_1(\"1.3.14.3.2.26\", \"SHA-1\", \"SHA\", \"SHA1\"),\n\n    OIW_SHA1withDSA(\"1.3.14.3.2.27\", \"SHA1withDSA\"),\n\n    OIW_SHA1withRSA(\"1.3.14.3.2.29\", \"SHA1withRSA\"),\n\n    // Thawte 1.3.101.*\n    X25519(\"1.3.101.110\"),\n    X448(\"1.3.101.111\"),\n    Ed25519(\"1.3.101.112\"),\n    Ed448(\"1.3.101.113\"),\n\n    // University College London (UCL) 0.9.2342.19200300.*\n    UCL_UserID(\"0.9.2342.19200300.100.1.1\"),\n    UCL_DomainComponent(\"0.9.2342.19200300.100.1.25\"),\n\n    // Netscape 2.16.840.1.113730.*\n    NETSCAPE_CertType(\"2.16.840.1.113730.1.1\"),\n    NETSCAPE_CertSequence(\"2.16.840.1.113730.2.5\"),\n    NETSCAPE_ExportApproved(\"2.16.840.1.113730.4.1\"),\n\n    // Oracle 2.16.840.1.113894.*\n    ORACLE_TrustedKeyUsage(\"2.16.840.1.113894.746875.1.1\"),  // Miscellaneous oids below which are legacy, and not well known\n    // Consider removing them in future releases when their usage\n    // have died out\n\n    ITUX509_RSA(\"2.5.8.1.1\", \"RSA\"),\n\n    SkipIPAddress(\"1.3.6.1.4.1.42.2.11.2.1\"),\n    JAVASOFT_JDKKeyProtector(\"1.3.6.1.4.1.42.2.17.1.1\"),\n    JAVASOFT_JCEKeyProtector(\"1.3.6.1.4.1.42.2.19.1\"),\n    MICROSOFT_ExportApproved(\"1.3.6.1.4.1.311.10.3.3\"),\n\n    Blowfish(\"1.3.6.1.4.1.3029.1.1.2\"),\n\n    asn1_module(\"1.2.410.200046.1.1.1\", \"ASN1-module\"),\n    aria256_ecb(\"1.2.410.200046.1.1.11\", \"ARIA256/ECB\"),\n    aria256_cbc(\"1.2.410.200046.1.1.12\", \"ARIA256/CBC\"),\n    aria256_cfb(\"1.2.410.200046.1.1.13\", \"ARIA256/CFB\"),\n    aria256_ofb(\"1.2.410.200046.1.1.14\", \"ARIA256/OFB\"),\n    aria128_cbc(\"1.2.410.200046.1.1.2\", \"ARIA128/CBC\"),\n    aria128_cfb(\"1.2.410.200046.1.1.3\", \"ARIA128/CFB\"),\n    aria128_ofb(\"1.2.410.200046.1.1.4\", \"ARIA128/OFB\"),\n    aria192_ecb(\"1.2.410.200046.1.1.6\", \"ARIA192/ECB\"),\n    aria192_cbc(\"1.2.410.200046.1.1.7\", \"ARIA192/CBC\"),\n    aria192_cfb(\"1.2.410.200046.1.1.8\", \"ARIA192/CFB\"),\n    aria192_ofb(\"1.2.410.200046.1.1.9\", \"ARIA192/OFB\"),\n    BROKEN_GOST_R28147_89(\"1.2.643.2.2.13.0\"),\n    BROKEN_CryptoPro(\"1.2.643.2.2.13.1\"),\n    GOST_28147_89(\"1.2.643.2.2.21\", \"GOST-28147-89\"),\n    dstu7624_ecb_128(\"1.2.804.2.1.1.1.1.1.3.1.1\", \"DSTU7624/ECB-128\"),\n    dstu7624_ecb_256(\"1.2.804.2.1.1.1.1.1.3.1.2\", \"DSTU7624/ECB-256\"),\n    dstu7624_ecb_512(\"1.2.804.2.1.1.1.1.1.3.1.3\", \"DSTU7624/ECB-512\"),\n    dstu7624_ctr_128(\"1.2.804.2.1.1.1.1.1.3.2.1\", \"DSTU7624/CTR-128\"),\n    dstu7624_ctr_256(\"1.2.804.2.1.1.1.1.1.3.2.2\", \"DSTU7624/CTR-256\"),\n    dstu7624_ctr_512(\"1.2.804.2.1.1.1.1.1.3.2.3\", \"DSTU7624/CTR-512\"),\n    dstu7624_cfb_128(\"1.2.804.2.1.1.1.1.1.3.3.1\", \"DSTU7624/CFB-128\"),\n    dstu7624_cfb_256(\"1.2.804.2.1.1.1.1.1.3.3.2\", \"DSTU7624/CFB-256\"),\n    dstu7624_cfb_512(\"1.2.804.2.1.1.1.1.1.3.3.3\", \"DSTU7624/CFB-512\"),\n    dstu7624_cbc_128(\"1.2.804.2.1.1.1.1.1.3.5.1\", \"DSTU7624/CBC-128\"),\n    dstu7624_cbc_256(\"1.2.804.2.1.1.1.1.1.3.5.2\", \"DSTU7624/CBC-256\"),\n    dstu7624_cbc_512(\"1.2.804.2.1.1.1.1.1.3.5.3\", \"DSTU7624/CBC-512\"),\n    dstu7624_ofb_128(\"1.2.804.2.1.1.1.1.1.3.6.1\", \"DSTU7624/OFB-128\"),\n    dstu7624_ofb_256(\"1.2.804.2.1.1.1.1.1.3.6.2\", \"DSTU7624/OFB-256\"),\n    dstu7624_ofb_512(\"1.2.804.2.1.1.1.1.1.3.6.3\", \"DSTU7624/OFB-512\"),\n    dstu7624_ccm_128(\"1.2.804.2.1.1.1.1.1.3.8.1\", \"DSTU7624/CCM-128\"),\n    dstu7624_ccm_256(\"1.2.804.2.1.1.1.1.1.3.8.2\", \"DSTU7624/CCM-256\"),\n    dstu7624_ccm_512(\"1.2.804.2.1.1.1.1.1.3.8.3\", \"DSTU7624/CCM-512\"),\n    CMS3DESwrap(\"1.2.840.113549.1.9.16.3.6\", \"CMS3DESwrap\"),\n    des_CBC(\"1.3.14.3.2.7\", \"DES/CBC\"),\n    Joint_RSA(\"2.5.8.1.1\", \"Joint-RSA\"),\n    camellia128_wrap(\"1.2.392.200011.61.1.1.3.2\", \"camellia128/wrap\"),\n    camellia192_wrap(\"1.2.392.200011.61.1.1.3.3\", \"camellia192/wrap\"),\n    camellia256_wrap(\"1.2.392.200011.61.1.1.3.4\", \"camellia256/wrap\"),\n    id_aes192_CCM(\"2.16.840.1.101.3.4.1.27\", \"AES192/CCM\"),\n    aes256_CCM(\"2.16.840.1.101.3.4.1.47\", \"AES256/CCM\"),\n    aes128_CCM(\"2.16.840.1.101.3.4.1.7\", \"AES128/CCM\");\n\n    val algorithm: String\n    val oid: String\n    val aliases: Array<String>\n\n    constructor(oid: String) {\n        this.oid = oid\n        this.algorithm = name // defaults to enum name\n        this.aliases = arrayOf(oid, name)\n    }\n\n    constructor(\n        oid: String,\n        algorithm: String,\n        vararg aliases: String\n    ) {\n        this.oid = oid\n        this.algorithm = algorithm\n        this.aliases = aliases.toList().toTypedArray()\n    }\n\n    companion object {\n        fun findMatch(\n            oidOrName: String\n        ): SecureAlgorithmsMapping? = SecureAlgorithmsMapping.entries.find {\n            it.oid == oidOrName || it.algorithm == oidOrName || it.aliases.contains(oidOrName)\n        }\n    }\n}\n"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/SortType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nenum class SortType {\n    DateModified, DateModifiedReversed,\n    Name, NameReversed,\n    Size, SizeReversed,\n    MimeType, MimeTypeReversed,\n    Extension, ExtensionReversed,\n    DateAdded, DateAddedReversed\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/SystemBarsVisibility.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\nsealed class SystemBarsVisibility(\n    val ordinal: Int\n) {\n\n    data object Auto : SystemBarsVisibility(0)\n\n    data object ShowAll : SystemBarsVisibility(1)\n\n    data object HideAll : SystemBarsVisibility(2)\n\n    data object HideNavigationBar : SystemBarsVisibility(3)\n\n    data object HideStatusBar : SystemBarsVisibility(4)\n\n    companion object {\n\n        val entries: List<SystemBarsVisibility> by lazy {\n            listOf(\n                Auto,\n                ShowAll,\n                HideAll,\n                HideNavigationBar,\n                HideStatusBar\n            )\n        }\n\n        fun fromOrdinal(ordinal: Int?): SystemBarsVisibility? = ordinal?.let {\n            entries[ordinal]\n        }\n    }\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/model/VisibilityOwner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.model\n\ninterface VisibilityOwner {\n    val isVisible: Boolean\n        get() = true\n}\n\ninline fun <T : VisibilityOwner, R> T.ifVisible(\n    action: T.() -> R\n): R? = takeIf { it.isVisible }?.let(action)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/remote/AnalyticsManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.remote\n\ninterface AnalyticsManager {\n\n    val allowCollectCrashlytics: Boolean\n\n    val allowCollectAnalytics: Boolean\n\n    fun updateAnalyticsCollectionEnabled(value: Boolean)\n\n    fun updateAllowCollectCrashlytics(value: Boolean)\n\n    fun sendReport(throwable: Throwable)\n\n    fun registerScreenOpen(screenName: String)\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/remote/Cache.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.remote\n\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport java.util.concurrent.ConcurrentHashMap\nimport java.util.concurrent.ConcurrentMap\nimport kotlin.time.Clock\nimport kotlin.time.Duration\nimport kotlin.time.Instant\n\nprivate data class CacheItem<V>(\n    val value: V,\n    val created: Instant,\n)\n\nclass Cache<K, V>(private val maxAge: Duration) {\n    private val map: ConcurrentMap<K, CacheItem<V>> = ConcurrentHashMap()\n    private val scope: CoroutineScope = CoroutineScope(Dispatchers.IO)\n\n    suspend fun call(key: K, dataGetter: suspend () -> V): V {\n        val now = Clock.System.now()\n        val prevItem = map[key]?.takeIf {\n            it.created + maxAge > now\n        }\n\n        return if (prevItem != null) {\n            prevItem.value\n        } else {\n            val data = dataGetter()\n            val item = CacheItem(\n                value = data,\n                created = now\n            )\n            map[key] = item\n            scope.launch {\n                delay(maxAge)\n                map.remove(key, item)\n            }\n\n            data\n        }\n    }\n\n    fun reset() {\n        map.clear()\n    }\n\n    fun reset(key: K) {\n        map.remove(key)\n    }\n}\n"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/remote/DownloadManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.remote\n\ninterface DownloadManager {\n    suspend fun download(\n        url: String,\n        destinationPath: String,\n        onStart: suspend () -> Unit = {},\n        onProgress: suspend (DownloadProgress) -> Unit,\n        onFinish: suspend (Throwable?) -> Unit = {}\n    )\n\n    suspend fun downloadZip(\n        url: String,\n        destinationPath: String,\n        onStart: suspend () -> Unit = {},\n        onProgress: (DownloadProgress) -> Unit,\n        downloadOnlyNewData: Boolean\n    )\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/remote/DownloadProgress.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.remote\n\ndata class DownloadProgress(\n    val currentPercent: Float,\n    val currentTotalSize: Long\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/remote/RemoteResources.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.remote\n\ndata class RemoteResources(\n    val name: String,\n    val list: List<RemoteResource>\n) {\n\n    companion object {\n        const val CUBE_LUT = \"cubelut/luts.zip\"\n        const val MESH_GRADIENTS = \"mesh_gradient/mesh_gradients.zip\"\n\n        val CubeLutDefault = RemoteResources(\n            name = CUBE_LUT,\n            list = emptyList()\n        )\n\n        val MeshGradientsDefault = RemoteResources(\n            name = MESH_GRADIENTS,\n            list = emptyList()\n        )\n    }\n\n}\n\ndata class RemoteResource(\n    val uri: String,\n    val name: String\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/remote/RemoteResourcesStore.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.remote\n\ninterface RemoteResourcesStore {\n\n    /**\n     *  Get cached remote resources\n     *\n     *      val resourcesStore: RemoteResourcesStore = ...\n     *\n     *      resourcesStore.getResources(\n     *          name = RemoteResources.CUBE_LUT,\n     *          forceUpdate = true,\n     *          onDownloadRequest = { name ->\n     *              resourcesStore.downloadResources(\n     *                  name = name,\n     *                  onProgress = { progress ->\n     *\n     *                  },\n     *                  onFailure = { throwable ->\n     *\n     *                  }\n     *              )\n     *          }\n     *     )\n     **/\n    suspend fun getResources(\n        name: String,\n        forceUpdate: Boolean,\n        onDownloadRequest: suspend (name: String) -> RemoteResources?\n    ): RemoteResources?\n\n\n    /**\n     * Download Resources from [ImageToolboxRemoteResources](https://github.com/T8RIN/ImageToolboxRemoteResources)\n     *\n     *      val resourcesStore: RemoteResourcesStore = ...\n     *\n     *      resourcesStore.downloadResources(\n     *           name = name,\n     *           onProgress = { progress ->\n     *\n     *           },\n     *           onFailure = { throwable ->\n     *\n     *           }\n     *      )\n     */\n    suspend fun downloadResources(\n        name: String,\n        onProgress: (DownloadProgress) -> Unit,\n        onFailure: (Throwable) -> Unit,\n        downloadOnlyNewData: Boolean = false\n    ): RemoteResources?\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/resource/ResourceManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.resource\n\ninterface ResourceManager {\n\n    fun getString(resId: Int): String\n\n    fun getString(\n        resId: Int,\n        vararg formatArgs: Any\n    ): String\n\n    fun getStringLocalized(\n        resId: Int,\n        language: String\n    ): String\n\n    fun getStringLocalized(\n        resId: Int,\n        language: String,\n        vararg formatArgs: Any\n    ): String\n\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/FileController.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving\n\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.MetadataProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport kotlinx.coroutines.flow.Flow\n\ninterface FileController : ObjectSaver, MetadataProvider {\n    val defaultSavingPath: String\n\n    suspend fun save(\n        saveTarget: SaveTarget,\n        keepOriginalMetadata: Boolean,\n        oneTimeSaveLocationUri: String? = null,\n    ): SaveResult\n\n    fun getSize(uri: String): Long?\n\n    fun clearCache(onComplete: (Long) -> Unit = {})\n\n    fun getCacheSize(): Long\n\n    suspend fun readBytes(uri: String): ByteArray\n\n    suspend fun writeBytes(\n        uri: String,\n        block: suspend (Writeable) -> Unit,\n    ): SaveResult\n\n    suspend fun transferBytes(\n        fromUri: String,\n        toUri: String\n    ): SaveResult\n\n    suspend fun transferBytes(\n        fromUri: String,\n        to: Writeable\n    ): SaveResult\n\n    suspend fun writeMetadata(\n        imageUri: String,\n        metadata: Metadata?\n    )\n\n    suspend fun listFilesInDirectory(treeUri: String): List<String>\n\n    fun listFilesInDirectoryAsFlow(treeUri: String): Flow<String>\n\n    companion object {\n        fun FileController.toMetadataProvider(): MetadataProvider =\n            object : MetadataProvider by this {}\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/FilenameCreator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving\n\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\n\ninterface FilenameCreator {\n\n    fun constructImageFilename(\n        saveTarget: ImageSaveTarget,\n        oneTimePrefix: String? = null,\n        forceNotAddSizeInFilename: Boolean = false,\n        pattern: String? = null\n    ): String\n\n    fun constructRandomFilename(\n        extension: String,\n        length: Int = 32\n    ): String\n\n    fun getFilename(uri: String): String\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/KeepAliveService.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving\n\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.supervisorScope\n\ninterface KeepAliveService {\n    fun updateOrStart(\n        title: String = \"\",\n        description: String = \"\",\n        progress: Float = PROGRESS_INDETERMINATE\n    )\n\n    fun stop(removeNotification: Boolean = true)\n\n    companion object {\n        const val PROGRESS_NO_PROGRESS = -2f\n        const val PROGRESS_INDETERMINATE = -1f\n    }\n}\n\nfun KeepAliveService.updateProgress(\n    title: String = \"\",\n    done: Int,\n    total: Int\n) {\n    updateOrStart(\n        title = title,\n        description = \"$done / $total\",\n        progress = (done / total.toFloat()).takeIf { it > 0f }\n            ?: KeepAliveService.PROGRESS_INDETERMINATE\n    )\n}\n\nsuspend fun <R> KeepAliveService.track(\n    initial: KeepAliveService.() -> Unit = { updateOrStart() },\n    onCancel: () -> Unit = {},\n    onFailure: suspend (Throwable) -> Unit = {},\n    onComplete: KeepAliveService.(isSuccess: Boolean) -> Unit = { stop(true) },\n    action: suspend KeepAliveService.() -> R\n): R? = supervisorScope {\n    try {\n        initial()\n        action()\n    } catch (e: CancellationException) {\n        onComplete(false)\n        onCancel()\n        throw e\n    } catch (e: Throwable) {\n        onComplete(false)\n        onFailure(e)\n        null\n    } finally {\n        onComplete(true)\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/ObjectSaver.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving\n\nimport kotlin.reflect.KClass\n\ninterface ObjectSaver {\n\n    suspend fun <O : Any> saveObject(\n        key: String,\n        value: O,\n    ): Boolean\n\n    suspend fun <O : Any> restoreObject(\n        key: String,\n        kClass: KClass<O>,\n    ): O?\n\n}\n\nsuspend inline fun <reified O : Any> ObjectSaver.saveObject(value: O): Boolean = saveObject(\n    key = O::class.simpleName.toString(),\n    value = value\n)\n\nsuspend inline fun <reified O : Any> ObjectSaver.restoreObject(): O? = restoreObject(\n    key = O::class.simpleName.toString(),\n    kClass = O::class\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/RandomStringGenerator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving\n\ninterface RandomStringGenerator {\n\n    fun generate(length: Int): String\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/io/IoCloseable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving.io\n\nimport kotlin.contracts.InvocationKind\nimport kotlin.contracts.contract\n\ninterface IoCloseable {\n    fun close()\n}\n\ninline fun <T : IoCloseable?, R> T.use(block: (T) -> R): R {\n    contract {\n        callsInPlace(block, InvocationKind.EXACTLY_ONCE)\n    }\n    var exception: Throwable? = null\n    try {\n        return block(this)\n    } catch (e: Throwable) {\n        exception = e\n        throw e\n    } finally {\n        closeFinally(exception)\n    }\n}\n\n@SinceKotlin(\"1.1\")\n@PublishedApi\ninternal fun IoCloseable?.closeFinally(cause: Throwable?) = when {\n    this == null -> {}\n    cause == null -> close()\n    else ->\n        try {\n            close()\n        } catch (closeException: Throwable) {\n            cause.addSuppressed(closeException)\n        }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/io/Readable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving.io\n\ninterface Readable : IoCloseable {\n\n    fun readBytes(): ByteArray\n\n    fun copyTo(writeable: Writeable)\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/io/Writeable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving.io\n\ninterface Writeable : IoCloseable {\n\n    fun writeBytes(byteArray: ByteArray)\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/model/FileSaveTarget.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving.model\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\n\n\ndata class FileSaveTarget(\n    override val originalUri: String,\n    override val filename: String,\n    override val data: ByteArray,\n    override val mimeType: MimeType.Single,\n    override val extension: String,\n) : SaveTarget {\n\n    constructor(\n        originalUri: String,\n        filename: String,\n        data: ByteArray,\n        imageFormat: ImageFormat\n    ) : this(originalUri, filename, data, imageFormat.mimeType, imageFormat.extension)\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as FileSaveTarget\n\n        if (originalUri != other.originalUri) return false\n        if (filename != other.filename) return false\n        if (!data.contentEquals(other.data)) return false\n        if (mimeType != other.mimeType) return false\n        if (extension != other.extension) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = originalUri.hashCode()\n        result = 31 * result + filename.hashCode()\n        result = 31 * result + data.contentHashCode()\n        result = 31 * result + mimeType.hashCode()\n        result = 31 * result + extension.hashCode()\n        return result\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/model/FilenamePattern.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"ConstPropertyName\")\n\npackage com.t8rin.imagetoolbox.core.domain.saving.model\n\n@JvmInline\nvalue class FilenamePattern(\n    val value: String\n) {\n    override fun toString(): String = value\n\n    fun upper() = FilenamePattern(value.uppercase())\n\n    fun hasUpper() = upperEntries.contains(this.upper())\n\n    companion object {\n        val Prefix = FilenamePattern(\"\\\\p\")\n        val OriginalName = FilenamePattern(\"\\\\o\")\n        val Width = FilenamePattern(\"\\\\w\")\n        val Height = FilenamePattern(\"\\\\h\")\n        val Date = FilenamePattern(\"\\\\d\")\n        val Rand = FilenamePattern(\"\\\\r\")\n        val Sequence = FilenamePattern(\"\\\\c\")\n        val PresetInfo = FilenamePattern(\"\\\\i\")\n        val ScaleMode = FilenamePattern(\"\\\\m\")\n        val Suffix = FilenamePattern(\"\\\\s\")\n        val Extension = FilenamePattern(\"\\\\e\")\n\n        val PrefixUpper = FilenamePattern(\"\\\\p\").upper()\n        val OriginalNameUpper = FilenamePattern(\"\\\\o\").upper()\n        val DateUpper = FilenamePattern(\"\\\\d\").upper()\n        val PresetInfoUpper = FilenamePattern(\"\\\\i\").upper()\n        val ScaleModeUpper = FilenamePattern(\"\\\\m\").upper()\n        val SuffixUpper = FilenamePattern(\"\\\\s\").upper()\n        val ExtensionUpper = FilenamePattern(\"\\\\e\").upper()\n\n        val Default =\n            \"${Prefix}_$OriginalName($Width)x($Height)${Date}{yyyy-MM-dd_HH-mm-ss}_${Rand}{4}[${Sequence}]_${PresetInfo}_${ScaleMode}_${Suffix}.$Extension\"\n\n        val ForOriginal =\n            \"${Prefix}_$OriginalName($Width)x($Height)[${Sequence}]_${PresetInfo}_${ScaleMode}_${Suffix}.$Extension\"\n\n\n        fun String.replace(\n            pattern: FilenamePattern,\n            newValue: String,\n            ignoreCase: Boolean = false\n        ): String = replace(\n            oldValue = pattern.value,\n            newValue = newValue,\n            ignoreCase = ignoreCase\n        )\n\n        val entries by lazy {\n            listOf(\n                Prefix,\n                OriginalName,\n                Width,\n                Height,\n                Date,\n                Rand,\n                Sequence,\n                PresetInfo,\n                ScaleMode,\n                Suffix,\n                Extension\n            )\n        }\n\n        val upperEntries by lazy {\n            listOf(\n                PrefixUpper,\n                OriginalNameUpper,\n                DateUpper,\n                PresetInfoUpper,\n                ScaleModeUpper,\n                SuffixUpper,\n                ExtensionUpper\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/model/ImageSaveTarget.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving.model\n\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\n\ndata class ImageSaveTarget(\n    val imageInfo: ImageInfo,\n    override val originalUri: String,\n    val sequenceNumber: Int?,\n    val metadata: Metadata? = null,\n    override val filename: String? = null,\n    val imageFormat: ImageFormat = imageInfo.imageFormat,\n    override val data: ByteArray,\n    override val mimeType: MimeType.Single = imageFormat.mimeType,\n    override val extension: String = imageFormat.extension,\n    val readFromUriInsteadOfData: Boolean = false,\n    val presetInfo: Preset? = null,\n    val canSkipIfLarger: Boolean = false\n) : SaveTarget {\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as ImageSaveTarget\n\n        if (imageInfo != other.imageInfo) return false\n        if (originalUri != other.originalUri) return false\n        if (sequenceNumber != other.sequenceNumber) return false\n        if (metadata != other.metadata) return false\n        if (filename != other.filename) return false\n        if (imageFormat != other.imageFormat) return false\n        if (!data.contentEquals(other.data)) return false\n        if (mimeType != other.mimeType) return false\n        if (extension != other.extension) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = imageInfo.hashCode()\n        result = 31 * result + originalUri.hashCode()\n        result = 31 * result + (sequenceNumber ?: 0)\n        result = 31 * result + (metadata?.hashCode() ?: 0)\n        result = 31 * result + (filename?.hashCode() ?: 0)\n        result = 31 * result + imageFormat.hashCode()\n        result = 31 * result + data.contentHashCode()\n        result = 31 * result + mimeType.hashCode()\n        result = 31 * result + extension.hashCode()\n        return result\n    }\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/model/SaveResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving.model\n\nsealed class SaveResult(\n    open val savingPath: String\n) {\n\n    data class Success(\n        val message: String? = null,\n        override val savingPath: String,\n        val isOverwritten: Boolean = false,\n    ) : SaveResult(savingPath)\n\n    sealed class Error(open val throwable: Throwable) : SaveResult(\"\") {\n        data object MissingPermissions : Error(IllegalAccessException(\"MissingPermissions\"))\n\n        data class Exception(\n            override val throwable: Throwable\n        ) : Error(throwable)\n    }\n\n    data object Skipped : SaveResult(\"\")\n\n    fun onSuccess(\n        action: () -> Unit\n    ): SaveResult = apply {\n        if (this is Success) action()\n    }\n}\n\nfun List<SaveResult>.onSuccess(\n    action: () -> Unit\n): List<SaveResult> = apply {\n    if (this.any { it is SaveResult.Success }) action()\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/saving/model/SaveTarget.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.saving.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\n\ninterface SaveTarget {\n    val originalUri: String\n    val data: ByteArray\n    val filename: String?\n    val mimeType: MimeType.Single\n    val extension: String\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/transformation/ChainTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.transformation\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ninterface ChainTransformation<T> : Transformation<T> {\n\n    fun getTransformations(): List<Transformation<T>>\n\n    override suspend fun transform(\n        input: T,\n        size: IntegerSize\n    ): T = getTransformations().fold(input) { acc, filter ->\n        filter.transform(acc, size)\n    }\n\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/transformation/GenericTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.transformation\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport kotlin.random.Random\n\nclass GenericTransformation<T>(\n    val key: Any? = Random.nextInt(),\n    val action: suspend (T, IntegerSize) -> T\n) : Transformation<T> {\n\n    constructor(\n        key: Any? = Random.nextInt(),\n        action: suspend (T) -> T\n    ) : this(\n        key, { t, _ -> action(t) }\n    )\n\n    override val cacheKey: String\n        get() = (action to key).hashCode().toString()\n\n    override suspend fun transform(\n        input: T,\n        size: IntegerSize\n    ): T = action(input, size)\n}\n\nclass EmptyTransformation<T> : Transformation<T> by GenericTransformation(\n    key = Random.nextInt(),\n    action = { i -> i }\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/transformation/Transformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.transformation\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ninterface Transformation<T> {\n\n    /**\n     * The unique cache key for this transformation.\n     *\n     * The key is added to the image request's memory cache key and should contain any params that\n     * are part of this transformation (e.g. size, scale, color, radius, etc.).\n     */\n    val cacheKey: String\n\n    /**\n     * Apply the transformation to [input] and return the transformed [T].\n     *\n     * @param input The input [T] to transform.\n     *  Its config will always be ARGB_8888 or RGBA_F16.\n     * @param size The size of the image request.\n     * @return The transformed [T].\n     */\n    suspend fun transform(\n        input: T,\n        size: IntegerSize\n    ): T\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/ByteUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport java.text.CharacterIterator\nimport java.text.StringCharacterIterator\nimport java.util.Locale\n\n\nfun humanFileSize(\n    bytes: Long\n): String {\n    var tempBytes = bytes\n    if (-1024 < tempBytes && tempBytes < 1024) {\n        return \"$tempBytes B\"\n    }\n    val ci: CharacterIterator = StringCharacterIterator(\"kMGTPE\")\n    while (tempBytes <= -999950 || tempBytes >= 999950) {\n        tempBytes /= 1024\n        ci.next()\n    }\n    return java.lang.String.format(\n        Locale.getDefault(),\n        \"%.1f %cB\",\n        tempBytes / 1024.0,\n        ci.current()\n    ).replace(\",0\", \"\")\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/Delegates.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport kotlin.reflect.KProperty\n\ninterface ReadWriteDelegate<V> : ReadOnlyDelegate<V> {\n    fun set(value: V)\n\n    operator fun setValue(thisRef: Any, property: KProperty<*>, value: V) = set(value)\n}\n\ninterface ReadOnlyDelegate<V> {\n    fun get(): V\n\n    operator fun getValue(thisRef: Any, property: KProperty<*>): V = get()\n}\n\ninline fun <T> ReadWriteDelegate<T>.update(\n    transform: (T) -> T\n): T = run {\n    transform(get()).also(::set)\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/FileMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\n@JvmInline\nvalue class FileMode(val mode: String) {\n    operator fun plus(mode: FileMode) = FileMode(this.mode + mode.mode)\n\n    override fun toString(): String = this.mode\n\n    companion object {\n        val Read = FileMode(\"r\")\n        val Write = FileMode(\"w\")\n        val Truncate = FileMode(\"t\")\n        val ReadWrite = Read + Write\n        val WriteTruncate = Write + Truncate\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/Flavor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"SimplifyBooleanWithConstants\", \"KotlinConstantConditions\")\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\n\nobject Flavor {\n    fun isFoss() = BuildConfig.FLAVOR == \"foss\"\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/IntUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nfun Int.toBoolean() = this != 0\n\nfun Boolean.toInt() = if (this) 1 else 0"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/KotlinUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.conflate\nimport kotlinx.coroutines.flow.transform\nimport java.io.Closeable\nimport kotlin.reflect.KClass\n\n\ninline fun <reified T> T?.notNullAnd(\n    predicate: (T) -> Boolean\n): Boolean = if (this != null) predicate(this)\nelse false\n\nfun CharSequence.isBase64() = isNotEmpty() && BASE64_PATTERN.matches(this)\n\nfun CharSequence.trimToBase64() = toString().filter { !it.isWhitespace() }.substringAfter(\",\")\n\nprivate val BASE64_PATTERN = Regex(\n    \"^(?=(.{4})*$)[A-Za-z0-9+/]*={0,2}$\"\n)\n\ninline fun <reified R> Any.cast(): R = this as R\n\ninline fun <reified T, reified R> T.autoCast(block: T.() -> Any): R = block() as R\n\ninline fun <reified R> Any.safeCast(): R? = this as? R\n\ninline fun <reified R> Any?.ifCasts(action: (R) -> Unit) = (this as? R)?.let(action)\n\n\ninline operator fun CharSequence.times(\n    count: Int\n): CharSequence = repeat(count.coerceAtLeast(0))\n\n\nsuspend inline fun <T, R> T.runSuspendCatching(block: T.() -> R): Result<R> {\n    currentCoroutineContext().ensureActive()\n\n    return runCatching(block).onFailure {\n        println(\"ERROR: $it\")\n        currentCoroutineContext().ensureActive()\n    }\n}\n\ninline fun <T : Any> KClass<T>.simpleName() = simpleName!!\n\ninline fun <T> Boolean.then(value: T): T? = if (this) value else null\n\ninline fun tryAll(\n    vararg actions: () -> Unit\n): Boolean {\n    for (action in actions) {\n        runCatching { action() }.onSuccess { return true }\n    }\n\n    return false\n}\n\ninline fun <T> Result<T>.onResult(\n    action: (isSuccess: Boolean) -> Unit\n): Result<T> = apply { action(isSuccess) }\n\nfun <T> Flow<T>.throttleLatest(delayMillis: Long): Flow<T> = this\n    .conflate()\n    .transform {\n        emit(it)\n        delay(delayMillis)\n    }\n\ninline fun <T : Closeable?, R> T.applyUse(block: T.() -> R): R = use(block)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/ListUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport kotlin.reflect.KClass\n\nobject ListUtils {\n    fun <T> List<T>.nearestFor(item: T): T? {\n        return if (isEmpty()) null\n        else if (size == 1) first()\n        else {\n            val curIndex = indexOf(item)\n            if (curIndex - 1 >= 0) {\n                get(curIndex - 1)\n            } else if (curIndex + 1 <= lastIndex) {\n                get(curIndex + 1)\n            } else {\n                null\n            }\n        }\n    }\n\n    inline fun <T, reified R> Iterable<T>.filterIsNotInstance(): List<T> {\n        val destination = mutableListOf<T>()\n        for (element in this) if (element !is R) destination.add(element)\n        return destination\n    }\n\n    inline fun <T> Iterable<T>.filterIsNotInstance(vararg types: KClass<*>): List<T> {\n        val destination = mutableListOf<T>()\n        for (element in this) if (types.all { !it.isInstance(element) }) destination.add(element)\n        return destination\n    }\n\n    fun <T> Iterable<T>.toggle(item: T): List<T> = run {\n        if (item in this) this - item\n        else this + item\n    }\n\n    fun <T : Any> Iterable<T>.toggleByClass(item: T): List<T> {\n        val clazz = item::class\n        val hasClass = any { clazz.isInstance(it) }\n\n        return if (hasClass) filterNot { clazz.isInstance(it) }\n        else this + item\n    }\n\n    inline fun <T> Iterable<T>.replaceAt(index: Int, transform: (T) -> T): List<T> =\n        toMutableList().apply {\n            this[index] = transform(this[index])\n        }\n\n    fun <T> Set<T>.toggle(item: T): Set<T> = run {\n        if (item in this) this - item\n        else this + item\n    }\n\n    inline fun <reified R : Any> Iterable<Any?>.firstOfType(): R? = firstOrNull { it is R } as? R\n\n    operator fun <E> List<E>.component6(): E = get(5)\n    operator fun <E> List<E>.component7(): E = get(6)\n    operator fun <E> List<E>.component8(): E = get(7)\n    operator fun <E> List<E>.component9(): E = get(8)\n    operator fun <E> List<E>.component10(): E = get(9)\n\n    inline fun <E> List<E>.leftFrom(index: Int): E = getOrNull(index - 1) ?: get(lastIndex)\n\n    inline fun <E> List<E>.rightFrom(index: Int): E = getOrNull(index + 1) ?: get(0)\n\n    inline fun <E, T : Comparable<T>> List<E>.sortedByKey(\n        descending: Boolean,\n        crossinline selector: (E) -> T?\n    ): List<E> = if (descending) {\n        sortedByDescending { selector(it) }\n    } else {\n        sortedBy { selector(it) }\n    }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/ProgressInputStream.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport java.io.InputStream\n\nfun InputStream.withProgress(\n    total: Long,\n    onProgress: (Float) -> Unit\n): InputStream = ProgressInputStream(\n    source = this,\n    total = total,\n    onProgress = onProgress\n)\n\nprivate class ProgressInputStream(\n    private val source: InputStream,\n    private val total: Long,\n    private val onProgress: (Float) -> Unit\n) : InputStream() {\n\n    private var readBytes = 0L\n\n    override fun read(): Int {\n        val r = source.read()\n        if (r != -1) {\n            readBytes++\n            report()\n        }\n        return r\n    }\n\n    override fun read(b: ByteArray, off: Int, len: Int): Int {\n        val r = source.read(b, off, len)\n        if (r > 0) {\n            readBytes += r\n            report()\n        }\n        return r\n    }\n\n    private fun report() {\n        if (total > 0) {\n            onProgress(readBytes.toFloat() / total)\n        }\n    }\n\n    override fun close() = source.close()\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/Quad.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\ndata class Quad<A, B, C, D>(\n    val first: A,\n    val second: B,\n    val third: C,\n    val fourth: D\n)\n\ninline infix fun <A, B, C, D> Pair<A, B>.qto(\n    other: Pair<C, D>\n) = Quad(\n    first = first,\n    second = second,\n    third = other.first,\n    fourth = other.second\n)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/Rounding.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport kotlin.math.pow\nimport kotlin.math.roundToInt\n\nconst val NEAREST_ODD_ROUNDING = -3\n\nfun roundToNearestOdd(\n    number: Float\n): Float = number.roundToInt().let {\n    if (it % 2 != 0) it\n    else it + 1\n}.toFloat()\n\nfun Float.roundTo(\n    digits: Int\n): Float = if (digits == NEAREST_ODD_ROUNDING) roundToNearestOdd(this)\nelse (this * 10f.pow(digits)).roundToInt() / (10f.pow(digits))"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/SmartJob.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.cancelChildren\n\n/**\n * [Job] delegate which automatically cancels previous instance after setting new value,\n * @param onCancelled called when previous job is about to cancel\n **/\nprivate class SmartJobImpl(\n    private val onCancelled: (Job) -> Unit = {}\n) : ReadWriteDelegate<Job?> {\n\n    private var job: Job? = null\n\n    override fun get(): Job? = job\n\n    override fun set(value: Job?) {\n        job?.apply {\n            onCancelled(this)\n            cancelChildren()\n            cancel()\n        }\n        job = value\n    }\n}\n\n/**\n * [Job] delegate which automatically cancels previous instance after setting new value,\n * @param onCancelled called when previous job is about to cancel\n **/\nfun smartJob(\n    onCancelled: (Job) -> Unit = {}\n): ReadWriteDelegate<Job?> = SmartJobImpl(onCancelled)"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/StringUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nfun String.trimTrailingZero(): String {\n    val value = this\n    return if (value.isNotEmpty()) {\n        if (value.indexOf(\".\") < 0) {\n            value\n        } else {\n            value.replace(\"0*$\".toRegex(), \"\").replace(\"\\\\.$\".toRegex(), \"\")\n        }\n    } else {\n        value\n    }\n}\n\n/**\n * Returns a minimal set of characters that have to be removed from (or added to) the respective\n * strings to make the strings equal.\n */\nfun String.differenceFrom(\n    other: String\n): Pair<String, String> = diffHelper(\n    a = this,\n    b = other,\n    lookup = HashMap()\n)\n\n/**\n * Recursively compute a minimal set of characters while remembering already computed substrings.\n * Runs in O(n^2).\n */\nprivate fun diffHelper(\n    a: String,\n    b: String,\n    lookup: MutableMap<Long, Pair<String, String>>\n): Pair<String, String> {\n    val key = (a.length.toLong()) shl 32 or b.length.toLong()\n    if (!lookup.containsKey(key)) {\n        val value: Pair<String, String> = if (a.isEmpty() || b.isEmpty()) {\n            a to b\n        } else if (a[0] == b[0]) {\n            diffHelper(\n                a = a.substring(1),\n                b = b.substring(1),\n                lookup = lookup\n            )\n        } else {\n            val aa = diffHelper(a.substring(1), b, lookup)\n            val bb = diffHelper(a, b.substring(1), lookup)\n\n            if (aa.first.length + aa.second.length < bb.first.length + bb.second.length) {\n                (b[0].toString() + bb.second) to aa.second\n            } else {\n                bb.first to (b[0].toString() + bb.second)\n            }\n        }\n        lookup[key] = value\n    }\n    return lookup.getOrElse(key) { \"\" to \"\" }\n}"
  },
  {
    "path": "core/domain/src/main/kotlin/com/t8rin/imagetoolbox/core/domain/utils/TimeUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.domain.utils\n\nimport java.text.SimpleDateFormat\nimport java.util.Date\nimport java.util.Locale\n\nfun timestamp(\n    format: String? = \"yyyy-MM-dd_HH-mm-ss\",\n    date: Long? = null\n): String = runCatching {\n    val dateObject = date?.let(::Date) ?: Date()\n\n    format?.let {\n        SimpleDateFormat(format, Locale.getDefault()).format(dateObject)\n    } ?: dateObject.time.toString()\n}.getOrNull() ?: Date().time.toString()"
  },
  {
    "path": "core/filters/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/filters/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.filters\"\n\ndependencies {\n    implementation(projects.core.domain)\n    implementation(projects.core.ui)\n    implementation(projects.core.resources)\n    implementation(projects.core.settings)\n    implementation(projects.core.utils)\n    implementation(projects.core.ksp)\n    ksp(projects.core.ksp)\n\n    implementation(projects.lib.curves)\n    implementation(projects.lib.ascii)\n    implementation(projects.lib.neuralTools)\n    implementation(libs.trickle)\n}\n"
  },
  {
    "path": "core/filters/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/data/SideFadePaint.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.data\n\nimport android.graphics.Bitmap\nimport android.graphics.LinearGradient\nimport android.graphics.Paint\nimport android.graphics.PorterDuff\nimport android.graphics.PorterDuffXfermode\nimport android.graphics.Shader\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\n\nfun FadeSide.getPaint(\n    bmp: Bitmap,\n    length: Int,\n    strength: Float\n): Paint {\n    val paint = Paint().apply {\n        xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN)\n    }\n\n    val w = bmp.width.toFloat()\n    val h = bmp.height.toFloat()\n    val l = length.toFloat()\n\n    val gradientStart = l * (1f - strength.coerceAtLeast(0.001f))\n\n    val (x1, y1, x2, y2) = when (this) {\n        FadeSide.Start -> {\n            arrayOf(\n                gradientStart, h / 2,\n                l, h / 2\n            )\n        }\n\n        FadeSide.Top -> {\n            arrayOf(\n                w / 2, gradientStart,\n                w / 2, l\n            )\n        }\n\n        FadeSide.End -> {\n            arrayOf(\n                w - gradientStart, h / 2,\n                w - l, h / 2\n            )\n        }\n\n        FadeSide.Bottom -> {\n            arrayOf(\n                w / 2, h - gradientStart,\n                w / 2, h - l\n            )\n        }\n    }\n\n    paint.shader = LinearGradient(\n        x1, y1, x2, y2,\n        intArrayOf(\n            Color.Black.copy(alpha = 0f).toArgb(),\n            Color.Black.toArgb()\n        ),\n        floatArrayOf(\n            0f,\n            1f\n        ),\n        Shader.TileMode.CLAMP\n    )\n\n    return paint\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/FilterParamsInteractor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport kotlinx.coroutines.flow.Flow\n\ninterface FilterParamsInteractor {\n\n    fun getFavoriteFilters(): Flow<List<Filter<*>>>\n\n    suspend fun toggleFavorite(filter: Filter<*>)\n\n    suspend fun addTemplateFilter(templateFilter: TemplateFilter)\n\n    fun getTemplateFilters(): Flow<List<TemplateFilter>>\n\n    suspend fun addTemplateFilterFromString(\n        string: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    )\n\n    suspend fun convertTemplateFilterToString(templateFilter: TemplateFilter): String\n\n    suspend fun removeTemplateFilter(templateFilter: TemplateFilter)\n\n    suspend fun addTemplateFilterFromUri(\n        uri: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    )\n\n    fun isValidTemplateFilter(string: String): Boolean\n\n    suspend fun reorderFavoriteFilters(newOrder: List<Filter<*>>)\n\n    fun getFilterPreviewModel(): Flow<ImageModel>\n\n    fun getCanSetDynamicFilterPreview(): Flow<Boolean>\n\n    suspend fun setCanSetDynamicFilterPreview(value: Boolean)\n\n    suspend fun setFilterPreviewModel(uri: String)\n\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/FilterProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain\n\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\ninterface FilterProvider<Image> {\n\n    fun filterToTransformation(\n        filter: Filter<*>\n    ): Transformation<Image>\n\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.VisibilityOwner\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PaletteTransferSpace\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PolarCoordinatesType\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.SpotHealMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ArcParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.AsciiParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BilaterialBlurParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BloomParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ChannelMixParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.CropOrPerspectiveParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.EnhancedZoomBlurParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.GlitchParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.KaleidoscopeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearGaussianParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.PinchParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RadialTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RubberStampParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SideFadeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SmearParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SparkleParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ToneCurvesParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.WaterParams\n\n\ninterface Filter<Value : Any> : VisibilityOwner {\n    val value: Value\n\n    interface BilaterialBlur : Filter<BilaterialBlurParams>\n    interface BlackAndWhite : SimpleFilter\n    interface BoxBlur : FloatFilter\n    interface Brightness : FloatFilter\n    interface BulgeDistortion : PairFloatFilter\n    interface CGAColorSpace : SimpleFilter\n    interface ColorBalance : FloatArrayFilter\n    interface ColorOverlay : ColorValueFilter\n    interface ColorMatrix4x4 : FloatArrayFilter\n    interface Contrast : FloatFilter\n    interface Convolution3x3 : FloatArrayFilter\n    interface Crosshatch : PairFloatFilter\n    interface Dilation : FloatBooleanFilter\n    interface Emboss : FloatFilter\n    interface Exposure : FloatFilter\n    interface FalseColor : PairFilter<Color, Color>\n    interface FastBlur : PairFloatFilter\n    interface Gamma : FloatFilter\n    interface GaussianBlur : TripleFilter<Float, Float, BlurEdgeMode>\n    interface GlassSphereRefraction : PairFloatFilter\n    interface Halftone : FloatFilter\n    interface Haze : PairFloatFilter\n    interface HighlightsAndShadows : FloatFilter\n    interface Hue : FloatFilter\n    interface Kuwahara : FloatFilter\n    interface Laplacian : SimpleFilter\n    interface Lookup : FloatFilter\n    interface Monochrome : FloatColorModelFilter\n    interface Negative : SimpleFilter\n    interface NonMaximumSuppression : SimpleFilter\n    interface Opacity : FloatFilter\n    interface Posterize : FloatFilter\n    interface RGB : ColorValueFilter\n    interface Saturation : FloatBooleanFilter\n    interface Sepia : SimpleFilter\n    interface Sharpen : FloatFilter\n    interface Sketch : FloatFilter\n    interface SmoothToon : TripleFloatFilter\n    interface SobelEdgeDetection : FloatFilter\n    interface Solarize : FloatFilter\n    interface SphereRefraction : PairFloatFilter\n    interface StackBlur : PairFloatFilter\n    interface SwirlDistortion : QuadFloatFilter\n    interface Toon : PairFloatFilter\n    interface Vibrance : FloatFilter\n    interface Vignette : TripleFilter<Float, Float, Color>\n    interface WeakPixel : SimpleFilter\n    interface WhiteBalance : PairFloatFilter\n    interface ZoomBlur : TripleFloatFilter\n    interface Pixelation : FloatFilter\n    interface EnhancedPixelation : FloatFilter\n    interface StrokePixelation : FloatColorModelFilter\n    interface CirclePixelation : FloatFilter\n    interface DiamondPixelation : FloatFilter\n    interface EnhancedCirclePixelation : FloatFilter\n    interface EnhancedDiamondPixelation : FloatFilter\n    interface ReplaceColor : TripleFilter<Float, Color, Color>\n    interface RemoveColor : FloatColorModelFilter\n    interface SideFade : Filter<SideFadeParams>\n    interface BayerTwoDithering : FloatBooleanFilter\n    interface BayerThreeDithering : FloatBooleanFilter\n    interface BayerFourDithering : FloatBooleanFilter\n    interface BayerEightDithering : FloatBooleanFilter\n    interface RandomDithering : FloatBooleanFilter\n    interface FloydSteinbergDithering : FloatBooleanFilter\n    interface JarvisJudiceNinkeDithering : FloatBooleanFilter\n    interface SierraDithering : FloatBooleanFilter\n    interface TwoRowSierraDithering : FloatBooleanFilter\n    interface SierraLiteDithering : FloatBooleanFilter\n    interface AtkinsonDithering : FloatBooleanFilter\n    interface StuckiDithering : FloatBooleanFilter\n    interface BurkesDithering : FloatBooleanFilter\n    interface FalseFloydSteinbergDithering : FloatBooleanFilter\n    interface LeftToRightDithering : FloatBooleanFilter\n    interface SimpleThresholdDithering : FloatBooleanFilter\n    interface MedianBlur : FloatFilter\n    interface NativeStackBlur : FloatFilter\n    interface RadialTiltShift : Filter<RadialTiltShiftParams>\n    interface Glitch : TripleFloatFilter\n    interface Noise : FloatFilter\n    interface Anaglyph : FloatFilter\n    interface EnhancedGlitch : Filter<GlitchParams>\n    interface TentBlur : FloatFilter\n    interface Erode : FloatBooleanFilter\n    interface AnisotropicDiffusion : TripleFloatFilter\n    interface HorizontalWindStagger : TripleFilter<Float, Int, Color>\n    interface FastBilaterialBlur : TripleFloatFilter\n    interface PoissonBlur : FloatFilter\n    interface LogarithmicToneMapping : FloatFilter\n    interface AcesFilmicToneMapping : FloatFilter\n    interface Crystallize : FloatColorModelFilter\n    interface FractalGlass : PairFloatFilter\n    interface Marble : TripleFloatFilter\n    interface Oil : PairFloatFilter\n    interface WaterEffect : Filter<WaterParams>\n    interface HableFilmicToneMapping : FloatFilter\n    interface AcesHillToneMapping : FloatFilter\n    interface HejlBurgessToneMapping : FloatFilter\n    interface PerlinDistortion : TripleFloatFilter\n    interface Grayscale : TripleFloatFilter\n    interface Dehaze : PairFloatFilter\n    interface Threshold : FloatFilter\n    interface ColorMatrix3x3 : FloatArrayFilter\n    interface Polaroid : SimpleFilter\n    interface Cool : SimpleFilter\n    interface Warm : SimpleFilter\n    interface NightVision : SimpleFilter\n    interface CodaChrome : SimpleFilter\n    interface Browni : SimpleFilter\n    interface Vintage : SimpleFilter\n    interface Protonomaly : SimpleFilter\n    interface Deutaromaly : SimpleFilter\n    interface Tritonomaly : SimpleFilter\n    interface Protanopia : SimpleFilter\n    interface Deutaronotopia : SimpleFilter\n    interface Tritanopia : SimpleFilter\n    interface Achromatopsia : SimpleFilter\n    interface Achromatomaly : SimpleFilter\n    interface Grain : FloatFilter\n    interface Unsharp : FloatFilter\n    interface Pastel : SimpleFilter\n    interface OrangeHaze : SimpleFilter\n    interface PinkDream : SimpleFilter\n    interface GoldenHour : SimpleFilter\n    interface HotSummer : SimpleFilter\n    interface PurpleMist : SimpleFilter\n    interface Sunrise : SimpleFilter\n    interface ColorfulSwirl : SimpleFilter\n    interface SoftSpringLight : SimpleFilter\n    interface AutumnTones : SimpleFilter\n    interface LavenderDream : SimpleFilter\n    interface Cyberpunk : SimpleFilter\n    interface LemonadeLight : SimpleFilter\n    interface SpectralFire : SimpleFilter\n    interface NightMagic : SimpleFilter\n    interface FantasyLandscape : SimpleFilter\n    interface ColorExplosion : SimpleFilter\n    interface ElectricGradient : SimpleFilter\n    interface CaramelDarkness : SimpleFilter\n    interface FuturisticGradient : SimpleFilter\n    interface GreenSun : SimpleFilter\n    interface RainbowWorld : SimpleFilter\n    interface DeepPurple : SimpleFilter\n    interface SpacePortal : SimpleFilter\n    interface RedSwirl : SimpleFilter\n    interface DigitalCode : SimpleFilter\n    interface Bokeh : PairFloatFilter\n    interface Neon : TripleFilter<Float, Float, Color>\n    interface OldTv : SimpleFilter\n    interface ShuffleBlur : PairFloatFilter\n    interface Mobius : TripleFloatFilter\n    interface Uchimura : FloatFilter\n    interface Aldridge : PairFloatFilter\n    interface Drago : PairFloatFilter\n    interface ColorAnomaly : FloatFilter\n    interface Quantizier : FloatFilter\n    interface RingBlur : FloatFilter\n    interface CrossBlur : FloatFilter\n    interface CircleBlur : FloatFilter\n    interface StarBlur : FloatFilter\n    interface LinearTiltShift : Filter<LinearTiltShiftParams>\n    interface EnhancedZoomBlur : Filter<EnhancedZoomBlurParams>\n    interface Convex : FloatFilter\n    interface FastGaussianBlur2D : PairFilter<Float, BlurEdgeMode>\n    interface FastGaussianBlur3D : PairFilter<Float, BlurEdgeMode>\n    interface FastGaussianBlur4D : FloatFilter\n    interface EqualizeHistogram : SimpleFilter\n    interface EqualizeHistogramHSV : FloatFilter\n    interface EqualizeHistogramPixelation : PairFloatFilter\n    interface EqualizeHistogramAdaptive : PairFloatFilter\n    interface EqualizeHistogramAdaptiveLUV : TripleFloatFilter\n    interface EqualizeHistogramAdaptiveLAB : TripleFloatFilter\n    interface Clahe : TripleFloatFilter\n    interface ClaheLUV : ClaheValueFilter\n    interface ClaheLAB : ClaheValueFilter\n    interface CropToContent : FloatColorModelFilter\n    interface ClaheHSL : ClaheValueFilter\n    interface ClaheHSV : ClaheValueFilter\n    interface EqualizeHistogramAdaptiveHSV : TripleFloatFilter\n    interface EqualizeHistogramAdaptiveHSL : TripleFloatFilter\n    interface LinearBoxBlur : PairFilter<Int, TransferFunc>\n    interface LinearTentBlur : PairFilter<Float, TransferFunc>\n    interface LinearGaussianBoxBlur : PairFilter<Float, TransferFunc>\n    interface LinearStackBlur : PairFilter<Int, TransferFunc>\n    interface GaussianBoxBlur : FloatFilter\n    interface LinearFastGaussianBlurNext : TripleFilter<Int, TransferFunc, BlurEdgeMode>\n    interface LinearFastGaussianBlur : TripleFilter<Int, TransferFunc, BlurEdgeMode>\n    interface LinearGaussianBlur : Filter<LinearGaussianParams>\n    interface LowPoly : FloatBooleanFilter\n    interface SandPainting : TripleFilter<Int, Int, Color>\n    interface PaletteTransfer : FileImageFilter\n    interface EnhancedOil : FloatFilter\n    interface SimpleOldTv : SimpleFilter\n    interface HDR : SimpleFilter\n    interface SimpleSketch : SimpleFilter\n    interface Gotham : SimpleFilter\n    interface ColorPoster : FloatColorModelFilter\n    interface TriTone : TripleFilter<Color, Color, Color>\n    interface ClaheOklch : ClaheValueFilter\n    interface ClaheJzazbz : ClaheValueFilter\n    interface ClaheOklab : ClaheValueFilter\n    interface PolkaDot : TripleFilter<Int, Int, Color>\n    interface Clustered2x2Dithering : BooleanFilter\n    interface Clustered4x4Dithering : BooleanFilter\n    interface Clustered8x8Dithering : BooleanFilter\n    interface YililomaDithering : BooleanFilter\n    interface LUT512x512 : FileImageFilter\n    interface Amatorka : FloatFilter\n    interface MissEtikate : FloatFilter\n    interface SoftElegance : FloatFilter\n    interface SoftEleganceVariant : FloatFilter\n    interface PaletteTransferVariant : TripleFilter<Float, PaletteTransferSpace, Image>\n    interface CubeLut : FileFilter\n    interface BleachBypass : FloatFilter\n    interface Candlelight : FloatFilter\n    interface DropBlues : FloatFilter\n    interface EdgyAmber : FloatFilter\n    interface FallColors : FloatFilter\n    interface FilmStock50 : FloatFilter\n    interface FoggyNight : FloatFilter\n    interface Kodak : FloatFilter\n    interface PopArt : TripleFilter<Float, Color, PopArtBlendingMode>\n    interface Celluloid : FloatFilter\n    interface Coffee : FloatFilter\n    interface GoldenForest : FloatFilter\n    interface Greenish : FloatFilter\n    interface RetroYellow : FloatFilter\n    interface AutoCrop : FloatFilter\n    interface SpotHeal : PairFilter<Image, SpotHealMode>\n    interface Opening : FloatBooleanFilter\n    interface Closing : FloatBooleanFilter\n    interface MorphologicalGradient : FloatBooleanFilter\n    interface TopHat : FloatBooleanFilter\n    interface BlackHat : FloatBooleanFilter\n    interface Canny : PairFloatFilter\n    interface SobelSimple : SimpleFilter\n    interface LaplacianSimple : SimpleFilter\n    interface MotionBlur : TripleFilter<Int, Float, BlurEdgeMode>\n    interface AutoRemoveRedEyes : FloatFilter\n    interface ToneCurves : Filter<ToneCurvesParams>\n    interface Mirror : PairFilter<Float, MirrorSide>\n    interface Kaleidoscope : Filter<KaleidoscopeParams>\n    interface ChannelMix : Filter<ChannelMixParams>\n    interface ColorHalftone : QuadFloatFilter\n    interface Contour : QuadFilter<Float, Float, Float, Color>\n    interface VoronoiCrystallize : Filter<VoronoiCrystallizeParams>\n    interface Despeckle : SimpleFilter\n    interface Diffuse : FloatFilter\n    interface DoG : PairFloatFilter\n    interface Equalize : SimpleFilter\n    interface Glow : FloatFilter\n    interface Offset : PairFloatFilter\n    interface Pinch : Filter<PinchParams>\n    interface Pointillize : Filter<VoronoiCrystallizeParams>\n    interface PolarCoordinates : Filter<PolarCoordinatesType>\n    interface ReduceNoise : SimpleFilter\n    interface SimpleSolarize : SimpleFilter\n    interface Weave : QuadFloatFilter\n    interface Twirl : QuadFloatFilter\n    interface RubberStamp : Filter<RubberStampParams>\n    interface Smear : Filter<SmearParams>\n    interface SphereLensDistortion : QuadFloatFilter\n    interface Arc : Filter<ArcParams>\n    interface Sparkle : Filter<SparkleParams>\n    interface Ascii : Filter<AsciiParams>\n    interface Moire : SimpleFilter\n    interface Autumn : SimpleFilter\n    interface Bone : SimpleFilter\n    interface Jet : SimpleFilter\n    interface Winter : SimpleFilter\n    interface Rainbow : SimpleFilter\n    interface Ocean : SimpleFilter\n    interface Summer : SimpleFilter\n    interface Spring : SimpleFilter\n    interface CoolVariant : SimpleFilter\n    interface Hsv : SimpleFilter\n    interface Pink : SimpleFilter\n    interface Hot : SimpleFilter\n    interface Parula : SimpleFilter\n    interface Magma : SimpleFilter\n    interface Inferno : SimpleFilter\n    interface Plasma : SimpleFilter\n    interface Viridis : SimpleFilter\n    interface Cividis : SimpleFilter\n    interface Twilight : SimpleFilter\n    interface TwilightShifted : SimpleFilter\n    interface AutoPerspective : SimpleFilter\n    interface Deskew : FloatBooleanFilter\n    interface CropOrPerspective : Filter<CropOrPerspectiveParams>\n    interface Turbo : SimpleFilter\n    interface DeepGreen : SimpleFilter\n    interface LensCorrection : FileFilter\n    interface SeamCarving : Filter<IntegerSize>\n    interface ErrorLevelAnalysis : FloatFilter\n    interface LuminanceGradient : SimpleFilter\n    interface AverageDistance : SimpleFilter\n    interface CopyMoveDetection : PairFloatFilter\n    interface SimpleWeavePixelation : FloatFilter\n    interface StaggeredPixelation : FloatFilter\n    interface CrossPixelation : FloatFilter\n    interface MicroMacroPixelation : FloatFilter\n    interface OrbitalPixelation : FloatFilter\n    interface VortexPixelation : FloatFilter\n    interface PulseGridPixelation : FloatFilter\n    interface NucleusPixelation : FloatFilter\n    interface RadialWeavePixelation : FloatFilter\n    interface BorderFrame : TripleFilter<Float, Float, Color>\n    interface GlitchVariant : TripleFloatFilter\n    interface VHS : PairFloatFilter\n    interface BlockGlitch : PairFloatFilter\n    interface CrtCurvature : TripleFloatFilter\n    interface PixelMelt : PairFloatFilter\n    interface Bloom : Filter<BloomParams>\n}\n\ninterface SimpleFilter : Filter<Unit>\ninterface PairFilter<Value1, Value2> : Filter<Pair<Value1, Value2>>\ninterface TripleFilter<Value1, Value2, Value3> : Filter<Triple<Value1, Value2, Value3>>\ninterface QuadFilter<Value1, Value2, Value3, Value4> : Filter<Quad<Value1, Value2, Value3, Value4>>\n\ninterface FloatFilter : Filter<Float>\ninterface PairFloatFilter : PairFilter<Float, Float>\ninterface TripleFloatFilter : TripleFilter<Float, Float, Float>\ninterface QuadFloatFilter : QuadFilter<Float, Float, Float, Float>\n\ninterface FloatArrayFilter : Filter<FloatArray>\ninterface FileFilter : PairFilter<Float, File>\ninterface FileImageFilter : PairFilter<Float, Image>\ninterface FloatBooleanFilter : PairFilter<Float, Boolean>\ninterface FloatColorModelFilter : PairFilter<Float, Color>\ninterface BooleanFilter : Filter<Boolean>\ninterface ClaheValueFilter : Filter<ClaheParams>\ninterface ColorValueFilter : WrapperFilter<Color>\n\ninterface WrapperFilter<Wrapped : Any> : Filter<FilterValueWrapper<Wrapped>>\n\nprivate typealias Image = ImageModel\nprivate typealias File = FileModel\nprivate typealias Color = ColorModel"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/FilterParam.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model\n\n\ndata class FilterParam(\n    val title: Int? = null,\n    val valueRange: ClosedFloatingPointRange<Float>,\n    val roundTo: Int = 2\n)"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/FilterUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model\n\nimport java.lang.reflect.Proxy\n\n\ninline fun <V : Any, reified T : Filter<V>> createFilter(\n    value: V\n): T = Proxy.newProxyInstance(\n    T::class.java.classLoader,\n    arrayOf(T::class.java)\n) { _, method, _ ->\n    when {\n        method.name == \"getValue\" -> value\n        method.name.contains(\"isVisible\") -> true\n        else -> null\n    }\n} as T"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/FilterValueWrapper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model\n\ndata class FilterValueWrapper<V : Any>(\n    val wrapped: V\n)\n\nfun <T : Any> T.wrap(): FilterValueWrapper<T> = FilterValueWrapper(this)"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/TemplateFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model\n\ndata class TemplateFilter(\n    val name: String,\n    val filters: List<Filter<*>>\n) {\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is TemplateFilter) return false\n\n        if (name != other.name) return false\n        if (filters.size != other.filters.size) return false\n\n        val filters1 = filters.sortedBy { it::class.simpleName }\n        val filters2 = other.filters.sortedBy { it::class.simpleName }\n\n        filters1.forEachIndexed { index, filter1 ->\n            val filter2 = filters2[index]\n            val filter1Name = filter1::class.simpleName\n            val filter2Name = filter2::class.simpleName\n\n            if (filter1Name != filter2Name) return false\n\n            val v1 = filter1.value\n            val v2 = filter2.value\n\n            when {\n                v1 is FloatArray && v2 is FloatArray -> {\n                    if (!v1.contentEquals(v2)) return false\n                }\n\n                v1 is IntArray && v2 is IntArray -> {\n                    if (!v1.contentEquals(v2)) return false\n                }\n\n                v1 is DoubleArray && v2 is DoubleArray -> {\n                    if (!v1.contentEquals(v2)) return false\n                }\n\n                else -> if (v1 != v2) return false\n            }\n        }\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = name.hashCode()\n        filters.forEach { filter ->\n            result = 31 * result + filter::class.simpleName.hashCode()\n            val v = filter.value\n            result = 31 * result + when (v) {\n                is FloatArray -> v.contentHashCode()\n                is IntArray -> v.contentHashCode()\n                is DoubleArray -> v.contentHashCode()\n                else -> v.hashCode()\n            }\n        }\n        return result\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/BlurEdgeMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class BlurEdgeMode {\n    Clamp,\n    Wrap,\n    Reflect,\n    Reflect101\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/ColorMapType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class ColorMapType {\n    AUTUMN,\n    BONE,\n    JET,\n    WINTER,\n    RAINBOW,\n    OCEAN,\n    SUMMER,\n    SPRING,\n    COOL,\n    HSV,\n    PINK,\n    HOT,\n    PARULA,\n    MAGMA,\n    INFERNO,\n    PLASMA,\n    VIRIDIS,\n    CIVIDIS,\n    TWILIGHT,\n    TWILIGHT_SHIFTED,\n    TURBO,\n    DEEPGREEN\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/FadeSide.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class FadeSide {\n    Start,\n    End,\n    Top,\n    Bottom\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/MirrorSide.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class MirrorSide {\n    LeftToRight,\n    RightToLeft,\n    TopToBottom,\n    BottomToTop\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/PaletteTransferSpace.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class PaletteTransferSpace {\n    OKLAB,\n    LAB,\n    LUV,\n    LALPHABETA\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/PolarCoordinatesType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class PolarCoordinatesType {\n    /**\n     * Convert from rectangular to polar coordinates.\n     */\n    RECT_TO_POLAR,\n\n    /**\n     * Convert from polar to rectangular coordinates.\n     */\n    POLAR_TO_RECT,\n\n    /**\n     * Invert the image in a circle.\n     */\n    INVERT_IN_CIRCLE;\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/PopArtBlendingMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class PopArtBlendingMode {\n    MULTIPLY,\n    COLOR_BURN,\n    SOFT_LIGHT,\n    HSL_COLOR,\n    HSL_HUE,\n    DIFFERENCE\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/SpotHealMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class SpotHealMode {\n    OpenCV, LaMa\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/enums/TransferFunc.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.enums\n\nenum class TransferFunc {\n    SRGB,\n    REC709,\n    GAMMA2P2,\n    GAMMA2P8\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/ArcParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class ArcParams(\n    val radius: Float,\n    val height: Float,\n    val angle: Float,\n    val spreadAngle: Float,\n    val centreX: Float,\n    val centreY: Float,\n) {\n    companion object {\n        val Default = ArcParams(\n            radius = 0.2f,\n            height = 0.3f,\n            angle = 0f,\n            spreadAngle = 360f,\n            centreX = 0.5f,\n            centreY = 0.5f\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/AsciiParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.ascii.Gradient\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FontType\n\ndata class AsciiParams(\n    val gradient: String,\n    val fontSize: Float,\n    val backgroundColor: ColorModel,\n    val isGrayscale: Boolean,\n    val font: FontType?\n) {\n    companion object {\n        val Default = AsciiParams(\n            gradient = Gradient.OLD.value,\n            fontSize = 10f,\n            backgroundColor = Color.Black.toArgb().toColorModel(),\n            isGrayscale = false,\n            font = null\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/BilaterialBlurParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\n\ndata class BilaterialBlurParams(\n    val radius: Int,\n    val spatialSigma: Float,\n    val rangeSigma: Float,\n    val edgeMode: BlurEdgeMode,\n) {\n    companion object {\n        val Default by lazy {\n            BilaterialBlurParams(\n                spatialSigma = 10f,\n                rangeSigma = 3f,\n                edgeMode = BlurEdgeMode.Reflect101,\n                radius = 12,\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/BloomParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class BloomParams(\n    val threshold: Float,\n    val intensity: Float,\n    val radius: Int,\n    val softKnee: Float,\n    val exposure: Float,\n    val gamma: Float\n) {\n    companion object {\n        val Default = BloomParams(\n            threshold = 0.6f,\n            intensity = 1.5f,\n            radius = 25,\n            softKnee = 0.5f,\n            exposure = 0.02f,\n            gamma = 1.1f\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/ChannelMixParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class ChannelMixParams(\n    val blueGreen: Int,\n    val redBlue: Int,\n    val greenRed: Int,\n    val intoR: Int,\n    val intoG: Int,\n    val intoB: Int\n) {\n    companion object {\n        val Default = ChannelMixParams(\n            blueGreen = 255,\n            redBlue = 255,\n            greenRed = 255,\n            intoR = 255,\n            intoG = 255,\n            intoB = 127\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/ClaheParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class ClaheParams(\n    val threshold: Float,\n    val gridSizeHorizontal: Int,\n    val gridSizeVertical: Int,\n    val binsCount: Int\n) {\n\n    companion object {\n\n        val Default by lazy {\n            ClaheParams(\n                threshold = 0.5f,\n                gridSizeHorizontal = 8,\n                gridSizeVertical = 8,\n                binsCount = 128\n            )\n        }\n\n    }\n\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/CropOrPerspectiveParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class CropOrPerspectiveParams(\n    val topLeft: FloatPair,\n    val topRight: FloatPair,\n    val bottomLeft: FloatPair,\n    val bottomRight: FloatPair,\n    val isAbsolute: Boolean = false\n) {\n    companion object {\n        val Default by lazy {\n            CropOrPerspectiveParams(\n                topLeft = Pair(0.1f, 0.0f),\n                topRight = Pair(1.0f, 0.0f),\n                bottomRight = Pair(0.9f, 1.0f),\n                bottomLeft = Pair(0.0f, 1.0f),\n                isAbsolute = false\n            )\n        }\n    }\n}\n\ntypealias FloatPair = Pair<Float, Float>"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/EnhancedZoomBlurParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class EnhancedZoomBlurParams(\n    val radius: Int,\n    val sigma: Float,\n    val centerX: Float,\n    val centerY: Float,\n    val strength: Float,\n    val angle: Float,\n) {\n    companion object {\n        val Default by lazy {\n            EnhancedZoomBlurParams(\n                radius = 25,\n                sigma = 5f,\n                centerX = 0.5f,\n                centerY = 0.5f,\n                strength = 1f,\n                angle = 135f\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/GlitchParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class GlitchParams(\n    val channelsShiftX: Float = -0.08f,\n    val channelsShiftY: Float = -0.08f,\n    val corruptionSize: Float = 0.01f,\n    val corruptionCount: Int = 60,\n    val corruptionShiftX: Float = -0.05f,\n    val corruptionShiftY: Float = 0.0f,\n)"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/KaleidoscopeParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class KaleidoscopeParams(\n    val angle: Float,\n    val angle2: Float,\n    val centreX: Float,\n    val centreY: Float,\n    val sides: Int,\n    val radius: Float,\n) {\n    companion object {\n        val Default = KaleidoscopeParams(\n            angle = 0f,\n            angle2 = 0f,\n            centreX = 0.5f,\n            centreY = 0.5f,\n            sides = 5,\n            radius = 0f,\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/LinearGaussianParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\n\ndata class LinearGaussianParams(\n    val kernelSize: Int,\n    val sigma: Float,\n    val edgeMode: BlurEdgeMode,\n    val transferFunction: TransferFunc\n) {\n    companion object {\n        val Default by lazy {\n            LinearGaussianParams(\n                kernelSize = 25,\n                sigma = 10f,\n                edgeMode = BlurEdgeMode.Reflect101,\n                transferFunction = TransferFunc.SRGB\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/LinearTiltShiftParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class LinearTiltShiftParams(\n    val blurRadius: Float,\n    val sigma: Float,\n    val anchorX: Float,\n    val anchorY: Float,\n    val holeRadius: Float,\n    val angle: Float\n) {\n    companion object {\n        val Default by lazy {\n            LinearTiltShiftParams(\n                blurRadius = 25f,\n                sigma = 10f,\n                anchorX = 0.5f,\n                anchorY = 0.5f,\n                holeRadius = 0.2f,\n                angle = 45f\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/PinchParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class PinchParams(\n    val angle: Float,\n    val centreX: Float,\n    val centreY: Float,\n    val radius: Float,\n    val amount: Float\n) {\n    companion object {\n        val Default = PinchParams(\n            angle = 15f,\n            centreX = 0.5f,\n            centreY = 0.5f,\n            radius = 1f,\n            amount = 0.5f\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/RadialTiltShiftParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class RadialTiltShiftParams(\n    val blurRadius: Float,\n    val sigma: Float,\n    val anchorX: Float,\n    val anchorY: Float,\n    val holeRadius: Float\n) {\n    companion object {\n        val Default by lazy {\n            RadialTiltShiftParams(\n                blurRadius = 25f,\n                sigma = 10f,\n                anchorX = 0.5f,\n                anchorY = 0.5f,\n                holeRadius = 0.2f\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/RubberStampParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\n\ndata class RubberStampParams(\n    val threshold: Float,\n    val softness: Float,\n    val radius: Float,\n    val firstColor: ColorModel,\n    val secondColor: ColorModel\n) {\n    companion object {\n        val Default = RubberStampParams(\n            threshold = 0.3f,\n            softness = 0.1f,\n            radius = 0.05f,\n            firstColor = Color(0xff3FA08F).toArgb().toColorModel(),\n            secondColor = Color(0xff003027).toArgb().toColorModel(),\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/SideFadeParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport androidx.annotation.FloatRange\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\n\nsealed class SideFadeParams(\n    open val side: FadeSide\n) {\n    data class Relative(\n        override val side: FadeSide,\n        @FloatRange(0.0, 1.0)\n        val scale: Float\n    ) : SideFadeParams(side)\n\n    data class Absolute(\n        override val side: FadeSide,\n        val size: Int,\n        val strength: Float = 1f\n    ) : SideFadeParams(side)\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/SmearParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class SmearParams(\n    val angle: Float,\n    val density: Float,\n    val mix: Float,\n    val distance: Int,\n    val shape: Int\n) {\n    companion object {\n        val Default = SmearParams(\n            angle = 45f,\n            density = 1f,\n            mix = 1f,\n            distance = 100,\n            shape = 0\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/SparkleParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\n\ndata class SparkleParams(\n    val amount: Int,\n    val rays: Int,\n    val radius: Float,\n    val randomness: Int,\n    val centreX: Float,\n    val centreY: Float,\n    val color: ColorModel\n) {\n    companion object {\n        val Default = SparkleParams(\n            amount = 50,\n            rays = 50,\n            radius = 0.3f,\n            randomness = 25,\n            centreX = 0.5f,\n            centreY = 0.5f,\n            color = Color.White.toArgb().toColorModel()\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/ToneCurvesParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport com.t8rin.curves.ImageCurvesEditorState\n\ndata class ToneCurvesParams(\n    val controlPoints: List<List<Float>>\n) {\n    companion object {\n        val Default by lazy {\n            ToneCurvesParams(ImageCurvesEditorState.Default.controlPoints)\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/VoronoiCrystallizeParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\ndata class VoronoiCrystallizeParams(\n    val borderThickness: Float,\n    val scale: Float,\n    val randomness: Float,\n    val shape: Int,\n    val turbulence: Float,\n    val angle: Float,\n    val stretch: Float,\n    val amount: Float,\n    val color: ColorModel,\n) {\n    companion object {\n        val Default = VoronoiCrystallizeParams(\n            borderThickness = 0.4f,\n            color = Color(0xff000000).toModel(),\n            scale = 32f,\n            randomness = 5f,\n            shape = 0,\n            turbulence = 1f,\n            angle = 0f,\n            stretch = 1f,\n            amount = 1f\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/domain/model/params/WaterParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.domain.model.params\n\ndata class WaterParams(\n    val fractionSize: Float = 0.2f,\n    val frequencyX: Float = 2f,\n    val frequencyY: Float = 2f,\n    val amplitudeX: Float = 0.5f,\n    val amplitudeY: Float = 0.5f,\n)"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAcesFilmicToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiAcesFilmicToneMappingFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.aces_filmic_tone_mapping,\n    value = value,\n    valueRange = -4f..4f\n), Filter.AcesFilmicToneMapping"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAcesHillToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiAcesHillToneMappingFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.aces_hill_tone_mapping,\n    value = value,\n    valueRange = -4f..4f\n), Filter.AcesHillToneMapping"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAchromatomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiAchromatomalyFilter : UiFilter<Unit>(\n    title = R.string.achromatomaly,\n    value = Unit\n), Filter.Achromatomaly"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAchromatopsiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiAchromatopsiaFilter : UiFilter<Unit>(\n    title = R.string.achromatopsia,\n    value = Unit\n), Filter.Achromatopsia"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAldridgeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiAldridgeFilter(\n    override val value: Pair<Float, Float> = 1f to 0.025f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.aldridge,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.exposure,\n            valueRange = 0f..2f\n        ),\n        FilterParam(\n            title = R.string.cutoff,\n            valueRange = -1f..1f,\n            roundTo = 3\n        ),\n    )\n), Filter.Aldridge"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAmatorkaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiAmatorkaFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.amatorka,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.Amatorka"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAnaglyphFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiAnaglyphFilter(\n    override val value: Float = 20f\n) : UiFilter<Float>(\n    title = R.string.anaglyph,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            valueRange = 0f..100f,\n            roundTo = 0\n        )\n    )\n), Filter.Anaglyph"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAnisotropicDiffusionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiAnisotropicDiffusionFilter(\n    override val value: Triple<Float, Float, Float> = Triple(20f, 0.6f, 0.5f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.anisotropic_diffusion,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.repeat_count,\n            valueRange = 1f..100f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.conduction,\n            valueRange = 0.1f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.diffusion,\n            valueRange = 0.01f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.AnisotropicDiffusion"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiArcFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ArcParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiArcFilter(\n    override val value: ArcParams = ArcParams.Default\n) : UiFilter<ArcParams>(\n    title = R.string.arc,\n    paramsInfo = listOf(\n        R.string.radius paramTo 0f..1f,\n        R.string.just_size paramTo 0f..1f,\n        R.string.angle paramTo 0f..360f,\n        R.string.spread_angle paramTo 0f..360f,\n        R.string.center_x paramTo 0f..1f,\n        R.string.center_y paramTo 0f..1f\n    ),\n    value = value\n), Filter.Arc"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAsciiFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.AsciiParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiAsciiFilter(\n    override val value: AsciiParams = AsciiParams.Default\n) : UiFilter<AsciiParams>(\n    title = R.string.ascii,\n    paramsInfo = listOf(\n        FilterParam(R.string.gradient, 0f..0f),\n        FilterParam(R.string.font_size, 1f..100f),\n        FilterParam(R.string.font, 0f..0f),\n        FilterParam(R.string.background_color, 0f..0f),\n        FilterParam(R.string.gray_scale, 0f..0f)\n    ),\n    value = value\n), Filter.Ascii"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAtkinsonDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiAtkinsonDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.atkinson_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.AtkinsonDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAutoCropFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiAutoCropFilter(\n    override val value: Float = 5f\n) : UiFilter<Float>(\n    title = R.string.auto_crop,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.tolerance,\n            valueRange = 0f..10f,\n            roundTo = 0\n        )\n    )\n), Filter.AutoCrop"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAutoPerspectiveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiAutoPerspectiveFilter(\n    override val value: Unit = Unit\n) : UiFilter<Unit>(\n    title = R.string.auto_perspective,\n    value = value\n), Filter.AutoPerspective"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAutoRemoveRedEyesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiAutoRemoveRedEyesFilter(\n    override val value: Float = 150f\n) : UiFilter<Float>(\n    title = R.string.auto_remove_red_eyes,\n    value = value,\n    paramsInfo = listOf(\n        R.string.threshold paramTo 0f..255f\n    )\n), Filter.AutoRemoveRedEyes"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAutumnTonesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiAutumnTonesFilter : UiFilter<Unit>(\n    title = R.string.autumn_tones,\n    value = Unit\n), Filter.AutumnTones"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiAverageDistanceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiAverageDistanceFilter : UiFilter<Unit>(\n    title = R.string.average_distance,\n    value = Unit\n), Filter.AverageDistance"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBayerEightDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiBayerEightDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.bayer_eight_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.BayerEightDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBayerFourDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiBayerFourDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.bayer_four_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.BayerFourDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBayerThreeDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiBayerThreeDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.bayer_three_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.BayerThreeDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBayerTwoDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiBayerTwoDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.bayer_two_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.BayerTwoDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBilaterialBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BilaterialBlurParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiBilaterialBlurFilter(\n    override val value: BilaterialBlurParams = BilaterialBlurParams.Default,\n) : UiFilter<BilaterialBlurParams>(\n    title = R.string.bilaterial_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..50f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.sigma,\n            valueRange = 1f..100f,\n            roundTo = 1\n        ),\n        FilterParam(\n            title = R.string.spatial_sigma,\n            valueRange = 1f..100f,\n            roundTo = 1\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f,\n            roundTo = 0\n        ),\n    )\n), Filter.BilaterialBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBlackAndWhiteFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiBlackAndWhiteFilter : UiFilter<Unit>(\n    title = R.string.black_and_white,\n    value = Unit\n), Filter.BlackAndWhite"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBlackHatFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiBlackHatFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.black_hat,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.use_circle_kernel,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.BlackHat"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBleachBypassFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiBleachBypassFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.bleach_bypass,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.BleachBypass"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBlockGlitchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiBlockGlitchFilter(\n    override val value: Pair<Float, Float> = 0.02f to 0.5f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.block_glitch,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.block_size,\n            valueRange = 0f..1f,\n            roundTo = 3\n        ),\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 3\n        ),\n    )\n), Filter.BlockGlitch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBloomFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BloomParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiBloomFilter(\n    override val value: BloomParams = BloomParams.Default\n) : UiFilter<BloomParams>(\n    title = R.string.bloom,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, 0f..1f),\n        FilterParam(R.string.strength, 0f..3f),\n        FilterParam(R.string.radius, 1f..100f, roundTo = 0),\n        FilterParam(R.string.soft_knee, 0f..1f),\n        FilterParam(R.string.exposure, 0f..1f),\n        FilterParam(R.string.gamma, 0f..2f)\n    ),\n    value = value\n), Filter.Bloom"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBokehFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiBokehFilter(\n    override val value: Pair<Float, Float> = 6f to 6f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.bokeh,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.amount,\n            valueRange = 3f..40f,\n            roundTo = 0\n        )\n    )\n), Filter.Bokeh"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBorderFrameFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiBorderFrameFilter(\n    override val value: Triple<Float, Float, ColorModel> = Triple(20f, 40f, Color.White.toModel())\n) : UiFilter<Triple<Float, Float, ColorModel>>(\n    title = R.string.border_frame,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.horizontal_border_thickness,\n            valueRange = 0f..500f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.vertical_border_thickness,\n            valueRange = 0f..500f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.border_color,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.BorderFrame"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiBoxBlurFilter(\n    override val value: Float = 10f,\n) : UiFilter<Float>(\n    title = R.string.box_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            valueRange = 0f..100f,\n            roundTo = 0\n        )\n    )\n), Filter.BoxBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBrightnessFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiBrightnessFilter(\n    override val value: Float = 0.5f,\n) : UiFilter<Float>(\n    title = R.string.brightness,\n    value = value,\n    valueRange = -1f..1f\n), Filter.Brightness"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBrowniFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiBrowniFilter : UiFilter<Unit>(\n    title = R.string.browni,\n    value = Unit\n), Filter.Browni"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBulgeDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiBulgeDistortionFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.5f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.bulge,\n    value = value,\n    paramsInfo = listOf(\n        R.string.radius paramTo 0f..1f,\n        R.string.scale paramTo -1f..1f\n    )\n), Filter.BulgeDistortion"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiBurkesDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiBurkesDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.burkes_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.BurkesDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCGAColorSpaceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiCGAColorSpaceFilter : UiFilter<Unit>(\n    title = R.string.cga_colorspace,\n    value = Unit\n), Filter.CGAColorSpace"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCandlelightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiCandlelightFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.candlelight,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.Candlelight"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCannyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiCannyFilter(\n    override val value: Pair<Float, Float> = 100f to 200f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.canny,\n    value = value,\n    paramsInfo = listOf(\n        R.string.threshold_one paramTo 0f..1000f,\n        R.string.threshold_two paramTo 0f..1000f\n    )\n), Filter.Canny"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCaramelDarknessFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiCaramelDarknessFilter : UiFilter<Unit>(\n    title = R.string.caramel_darkness,\n    value = Unit\n), Filter.CaramelDarkness"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCelluloidFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiCelluloidFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.celluloid,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.Celluloid"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiChannelMixFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ChannelMixParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiChannelMixFilter(\n    override val value: ChannelMixParams = ChannelMixParams.Default\n) : UiFilter<ChannelMixParams>(\n    title = R.string.channel_mix,\n    paramsInfo = listOf(\n        FilterParam(R.string.blue_green, 0f..255f, 0),\n        FilterParam(R.string.red_blue, 0f..255f, 0),\n        FilterParam(R.string.green_red, 0f..255f, 0),\n        FilterParam(R.string.into_red, 0f..255f, 0),\n        FilterParam(R.string.into_green, 0f..255f, 0),\n        FilterParam(R.string.into_blue, 0f..255f, 0),\n    ),\n    value = value\n), Filter.ChannelMix"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCircleBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiCircleBlurFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.circle_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 3f..200f,\n            roundTo = NEAREST_ODD_ROUNDING\n        )\n    )\n), Filter.CircleBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCirclePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiCirclePixelationFilter(\n    override val value: Float = 24f,\n) : UiFilter<Float>(\n    title = R.string.circle_pixelation,\n    value = value,\n    valueRange = 5f..200f\n), Filter.CirclePixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.5f, 8f, 8f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.clahe,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0)\n    ),\n    value = value\n), Filter.Clahe"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheHSLFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheHSLFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : UiFilter<ClaheParams>(\n    title = R.string.clahe_hsl,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.ClaheHSL"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheHSVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheHSVFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : UiFilter<ClaheParams>(\n    title = R.string.clahe_hsv,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.ClaheHSV"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheJzazbzFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheJzazbzFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : UiFilter<ClaheParams>(\n    title = R.string.clahe_jzazbz,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.ClaheJzazbz"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheLABFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheLABFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : UiFilter<ClaheParams>(\n    title = R.string.clahe_lab,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.ClaheLAB"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheLUVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheLUVFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : UiFilter<ClaheParams>(\n    title = R.string.clahe_luv,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.ClaheLUV"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheOklabFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheOklabFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : UiFilter<ClaheParams>(\n    title = R.string.clahe_oklab,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.ClaheOklab"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClaheOklchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiClaheOklchFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : UiFilter<ClaheParams>(\n    title = R.string.clahe_oklch,\n    paramsInfo = listOf(\n        FilterParam(R.string.threshold, -10f..10f, 2),\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.ClaheOklch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClosingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiClosingFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.closing,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.use_circle_kernel,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Closing"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClustered2x2DitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiClustered2x2DitheringFilter(\n    override val value: Boolean = false,\n) : UiFilter<Boolean>(\n    title = R.string.clustered_2x2_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Clustered2x2Dithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClustered4x4DitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiClustered4x4DitheringFilter(\n    override val value: Boolean = false,\n) : UiFilter<Boolean>(\n    title = R.string.clustered_4x4_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Clustered4x4Dithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiClustered8x8DitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiClustered8x8DitheringFilter(\n    override val value: Boolean = false,\n) : UiFilter<Boolean>(\n    title = R.string.clustered_8x8_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Clustered8x8Dithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCodaChromeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiCodaChromeFilter : UiFilter<Unit>(\n    title = R.string.coda_chrome,\n    value = Unit\n), Filter.CodaChrome"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCoffeeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiCoffeeFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.coffee,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.Coffee"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorAnomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiColorAnomalyFilter(\n    override val value: Float = 0.56f\n) : UiFilter<Float>(\n    title = R.string.color_anomaly,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 0.56f..0.8f,\n            roundTo = 3\n        )\n    )\n), Filter.ColorAnomaly"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorBalanceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiColorBalanceFilter(\n    override val value: FloatArray = floatArrayOf(\n        0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f\n    ),\n) : UiFilter<FloatArray>(\n    title = R.string.color_balance,\n    value = value,\n    valueRange = 3f..3f\n), Filter.ColorBalance"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorExplosionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiColorExplosionFilter : UiFilter<Unit>(\n    title = R.string.color_explosion,\n    value = Unit\n), Filter.ColorExplosion"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorHalftoneFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiColorHalftoneFilter(\n    override val value: Quad<Float, Float, Float, Float> = Quad(\n        first = 2f,\n        second = 108f,\n        third = 162f,\n        fourth = 90f\n    )\n) : UiFilter<Quad<Float, Float, Float, Float>>(\n    title = R.string.color_halftone,\n    paramsInfo = listOf(\n        FilterParam(R.string.radius, 0f..50f, 2),\n        FilterParam(R.string.cyan, 0f..360f, 0),\n        FilterParam(R.string.magenta, 0f..360f, 0),\n        FilterParam(R.string.yellow, 0f..360f, 0),\n    ),\n    value = value\n), Filter.ColorHalftone"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorMapFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiAutumnFilter : UiFilter<Unit>(\n    title = R.string.autumn,\n    value = Unit\n), Filter.Autumn\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiBoneFilter : UiFilter<Unit>(\n    title = R.string.bone,\n    value = Unit\n), Filter.Bone\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiJetFilter : UiFilter<Unit>(\n    title = R.string.jet,\n    value = Unit\n), Filter.Jet\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiWinterFilter : UiFilter<Unit>(\n    title = R.string.winter,\n    value = Unit\n), Filter.Winter\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiRainbowFilter : UiFilter<Unit>(\n    title = R.string.rainbow,\n    value = Unit\n), Filter.Rainbow\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiOceanFilter : UiFilter<Unit>(\n    title = R.string.ocean,\n    value = Unit\n), Filter.Ocean\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSummerFilter : UiFilter<Unit>(\n    title = R.string.summer,\n    value = Unit\n), Filter.Summer\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSpringFilter : UiFilter<Unit>(\n    title = R.string.spring,\n    value = Unit\n), Filter.Spring\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiCoolVariantFilter : UiFilter<Unit>(\n    title = R.string.cool_variant,\n    value = Unit\n), Filter.CoolVariant\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiHsvFilter : UiFilter<Unit>(\n    title = R.string.hsv,\n    value = Unit\n), Filter.Hsv\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiPinkFilter : UiFilter<Unit>(\n    title = R.string.pink,\n    value = Unit\n), Filter.Pink\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiHotFilter : UiFilter<Unit>(\n    title = R.string.hot,\n    value = Unit\n), Filter.Hot\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiParulaFilter : UiFilter<Unit>(\n    title = R.string.parula,\n    value = Unit\n), Filter.Parula\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiMagmaFilter : UiFilter<Unit>(\n    title = R.string.magma,\n    value = Unit\n), Filter.Magma\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiInfernoFilter : UiFilter<Unit>(\n    title = R.string.inferno,\n    value = Unit\n), Filter.Inferno\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiPlasmaFilter : UiFilter<Unit>(\n    title = R.string.plasma,\n    value = Unit\n), Filter.Plasma\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiViridisFilter : UiFilter<Unit>(\n    title = R.string.viridis,\n    value = Unit\n), Filter.Viridis\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiCividisFilter : UiFilter<Unit>(\n    title = R.string.cividis,\n    value = Unit\n), Filter.Cividis\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiTwilightFilter : UiFilter<Unit>(\n    title = R.string.twilight,\n    value = Unit\n), Filter.Twilight\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiTwilightShiftedFilter : UiFilter<Unit>(\n    title = R.string.twilight_shifted,\n    value = Unit\n), Filter.TwilightShifted\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiTurboFilter : UiFilter<Unit>(\n    title = R.string.turbo,\n    value = Unit\n), Filter.Turbo\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiDeepGreenFilter : UiFilter<Unit>(\n    title = R.string.deep_green,\n    value = Unit\n), Filter.DeepGreen"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorMatrix3x3Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiColorMatrix3x3Filter(\n    override val value: FloatArray = floatArrayOf(\n        1.0f, 0.0f, 0.0f,\n        0.0f, 1.0f, 0.0f,\n        0.0f, 0.0f, 1.0f,\n    ),\n) : UiFilter<FloatArray>(\n    title = R.string.color_matrix_3x3,\n    value = value,\n    valueRange = 3f..3f\n), Filter.ColorMatrix3x3"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorMatrix4x4Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiColorMatrix4x4Filter(\n    override val value: FloatArray = floatArrayOf(\n        1.0f, 0.0f, 0.0f, 0.0f,\n        0.0f, 1.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 1.0f, 0.0f,\n        0.0f, 0.0f, 0.0f, 1.0f\n    ),\n) : UiFilter<FloatArray>(\n    title = R.string.color_matrix_4x4,\n    value = value,\n    valueRange = 4f..4f\n), Filter.ColorMatrix4x4"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorOverlayFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterValueWrapper\nimport com.t8rin.imagetoolbox.core.filters.domain.model.wrap\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiColorOverlayFilter(\n    override val value: FilterValueWrapper<ColorModel> = Color.Yellow.copy(0.3f).toModel().wrap(),\n) : UiFilter<FilterValueWrapper<ColorModel>>(\n    title = R.string.color_filter,\n    value = value\n), Filter.ColorOverlay"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorPosterFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiColorPosterFilter(\n    override val value: Pair<Float, ColorModel> = 0.5f to Color(0xFF4DFFE4).toModel()\n) : UiFilter<Pair<Float, ColorModel>>(\n    title = R.string.color_poster,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.color,\n            valueRange = 0f..0f\n        )\n    ),\n    value = value\n), Filter.ColorPoster"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiColorfulSwirlFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiColorfulSwirlFilter : UiFilter<Unit>(\n    title = R.string.colorful_swirl,\n    value = Unit\n), Filter.ColorfulSwirl"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiContourFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiContourFilter(\n    override val value: Quad<Float, Float, Float, ColorModel> = Quad(\n        first = 5f,\n        second = 1f,\n        third = 0f,\n        fourth = Color(0xff000000).toModel()\n    )\n) : UiFilter<Quad<Float, Float, Float, ColorModel>>(\n    title = R.string.contour,\n    paramsInfo = listOf(\n        FilterParam(R.string.levels, 0f..50f, 2),\n        FilterParam(R.string.scale, 0f..1f, 0),\n        FilterParam(R.string.offset, 0f..255f, 0),\n        FilterParam(R.string.color, 0f..0f, 0),\n    ),\n    value = value\n), Filter.Contour"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiContrastFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiContrastFilter(\n    override val value: Float = 2f,\n) : UiFilter<Float>(\n    title = R.string.contrast,\n    value = value,\n    valueRange = 0f..2f\n), Filter.Contrast"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiConvexFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiConvexFilter(\n    override val value: Float = 3f\n) : UiFilter<Float>(\n    title = R.string.spline,\n    value = value,\n    valueRange = 0f..30f\n), Filter.Convex"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiConvolution3x3Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiConvolution3x3Filter(\n    override val value: FloatArray = floatArrayOf(\n        0.0f, 0.0f, 0.0f,\n        0.0f, 1.0f, 0.0f,\n        0.0f, 0.0f, 0.0f\n    ),\n) : UiFilter<FloatArray>(\n    title = R.string.convolution3x3,\n    value = value,\n    valueRange = 3f..3f\n), Filter.Convolution3x3"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCoolFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiCoolFilter : UiFilter<Unit>(\n    title = R.string.cool,\n    value = Unit\n), Filter.Cool"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCopyMoveDetectionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiCopyMoveDetectionFilter(\n    override val value: Pair<Float, Float> = 4f to 0f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.copy_move_detection,\n    paramsInfo = listOf(\n        FilterParam(R.string.retain, 1f..40f),\n        FilterParam(R.string.coefficent, 0f..1f),\n    ),\n    value = value\n), Filter.CopyMoveDetection"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCropOrPerspectiveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.CropOrPerspectiveParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiCropOrPerspectiveFilter(\n    override val value: CropOrPerspectiveParams = CropOrPerspectiveParams.Default\n) : UiFilter<CropOrPerspectiveParams>(\n    title = R.string.crop_or_perspective,\n    paramsInfo = listOf(\n        FilterParam(R.string.top_left, 0f..0f),\n        FilterParam(R.string.top_right, 0f..0f),\n        FilterParam(R.string.bottom_left, 0f..0f),\n        FilterParam(R.string.bottom_right, 0f..0f),\n        FilterParam(R.string.absolute, 0f..0f),\n    ),\n    value = value\n), Filter.CropOrPerspective"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCropToContentFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiCropToContentFilter(\n    override val value: Pair<Float, ColorModel> = 0f to Color.Black.toModel()\n) : UiFilter<Pair<Float, ColorModel>>(\n    title = R.string.crop_to_content,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.tolerance,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.color_to_ignore,\n            valueRange = 0f..0f\n        )\n    ),\n    value = value\n), Filter.CropToContent"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCrossBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiCrossBlurFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.cross_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 3f..200f,\n            roundTo = NEAREST_ODD_ROUNDING\n        )\n    )\n), Filter.CrossBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCrossPixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiCrossPixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.cross_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.CrossPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCrosshatchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiCrosshatchFilter(\n    override val value: Pair<Float, Float> = 0.01f to 0.003f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.crosshatch,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(title = R.string.spacing, valueRange = 0.001f..0.05f, roundTo = 4),\n        FilterParam(title = R.string.line_width, valueRange = 0.001f..0.02f, roundTo = 4)\n    )\n), Filter.Crosshatch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCrtCurvatureFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiCrtCurvatureFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.25f, 0.65f, 0.015f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.crt_curvature,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.curvature,\n            valueRange = -1f..1f,\n            roundTo = 3\n        ),\n        FilterParam(\n            title = R.string.vignette,\n            valueRange = 0f..1f,\n            roundTo = 3\n        ),\n        FilterParam(\n            title = R.string.chroma,\n            valueRange = 0f..1f,\n            roundTo = 3\n        ),\n    )\n), Filter.CrtCurvature"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCrystallizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiCrystallizeFilter(\n    override val value: Pair<Float, ColorModel> = 1f to Color.Transparent.toModel()\n) : UiFilter<Pair<Float, ColorModel>>(\n    title = R.string.crystallize,\n    value = value,\n    paramsInfo = listOf(\n        R.string.amount paramTo 0.01f..2f,\n        R.string.stroke_color paramTo 0f..0f\n    )\n), Filter.Crystallize"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCubeLutFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiCubeLutFilter(\n    override val value: Pair<Float, FileModel> = 1f to FileModel(\"\")\n) : UiFilter<Pair<Float, FileModel>>(\n    title = R.string.cube_lut,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.target_cube_lut_file,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.CubeLut"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiCyberpunkFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiCyberpunkFilter : UiFilter<Unit>(\n    title = R.string.cyberpunk,\n    value = Unit\n), Filter.Cyberpunk"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDeepPurpleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiDeepPurpleFilter : UiFilter<Unit>(\n    title = R.string.deep_purple,\n    value = Unit\n), Filter.DeepPurple"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDehazeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiDehazeFilter(\n    override val value: Pair<Float, Float> = 17f to 0.45f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.dehaze,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..50f,\n            roundTo = 0\n        ),\n        R.string.omega paramTo 0f..1f\n    )\n), Filter.Dehaze"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDeskewFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiDeskewFilter(\n    override val value: Pair<Float, Boolean> = 15f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.deskew,\n    paramsInfo = listOf(\n        FilterParam(R.string.max, 0f..89f, 0),\n        FilterParam(R.string.allow_crop, 0f..0f, 0)\n    ),\n    value = value\n), Filter.Deskew"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDespeckleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiDespeckleFilter : UiFilter<Unit>(\n    title = R.string.despeckle,\n    value = Unit\n), Filter.Despeckle"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDeutaromalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiDeutaromalyFilter : UiFilter<Unit>(\n    title = R.string.deutaromaly,\n    value = Unit\n), Filter.Deutaromaly"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDeutaronotopiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiDeutaronotopiaFilter : UiFilter<Unit>(\n    title = R.string.deutaronotopia,\n    value = Unit\n), Filter.Deutaronotopia"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDiamondPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiDiamondPixelationFilter(\n    override val value: Float = 24f,\n) : UiFilter<Float>(\n    title = R.string.diamond_pixelation,\n    value = value,\n    valueRange = 10f..200f\n), Filter.DiamondPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDiffuseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiDiffuseFilter(\n    override val value: Float = 50f\n) : UiFilter<Float>(\n    title = R.string.diffuse,\n    value = value,\n    paramsInfo = listOf(\n        R.string.scale paramTo 0f..500f\n    )\n), Filter.Diffuse"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDigitalCodeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiDigitalCodeFilter : UiFilter<Unit>(\n    title = R.string.digital_code,\n    value = Unit\n), Filter.DigitalCode"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDilationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiDilationFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.dilation,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.use_circle_kernel,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Dilation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDoGFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiDoGFilter(\n    override val value: Pair<Float, Float> = 1f to 2f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.dog,\n    value = value,\n    paramsInfo = listOf(\n        R.string.radius paramTo 0f..100f,\n        R.string.second_radius paramTo 0f..100f\n    )\n), Filter.DoG"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDragoFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiDragoFilter(\n    override val value: Pair<Float, Float> = 1f to 250f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.drago,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.exposure,\n            valueRange = 0f..2f\n        ),\n        R.string.threshold paramTo 0f..500f\n    )\n), Filter.Drago"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiDropBluesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiDropBluesFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.drop_blues,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.DropBlues"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEdgyAmberFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiEdgyAmberFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.edgy_amber,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.EdgyAmber"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiElectricGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiElectricGradientFilter : UiFilter<Unit>(\n    title = R.string.electric_gradient,\n    value = Unit\n), Filter.ElectricGradient"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEmbossFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiEmbossFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.emboss,\n    value = value,\n    valueRange = 0f..4f\n), Filter.Emboss"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEnhancedCirclePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiEnhancedCirclePixelationFilter(\n    override val value: Float = 32f,\n) : UiFilter<Float>(\n    title = R.string.enhanced_circle_pixelation,\n    value = value,\n    valueRange = 15f..200f\n), Filter.EnhancedCirclePixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEnhancedDiamondPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiEnhancedDiamondPixelationFilter(\n    override val value: Float = 48f,\n) : UiFilter<Float>(\n    title = R.string.enhanced_diamond_pixelation,\n    value = value,\n    valueRange = 20f..200f\n), Filter.EnhancedDiamondPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEnhancedGlitchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.GlitchParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiEnhancedGlitchFilter(\n    override val value: GlitchParams = GlitchParams()\n) : UiFilter<GlitchParams>(\n    title = R.string.enhanced_glitch,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.channel_shift_x, -1f..1f, 2),\n        FilterParam(R.string.channel_shift_y, -1f..1f, 2),\n        FilterParam(R.string.corruption_size, 0f..1f, 2),\n        FilterParam(R.string.amount, 1f..100f, 0),\n        FilterParam(R.string.corruption_shift_x, -1f..1f, 2),\n        FilterParam(R.string.corruption_shift_y, -1f..1f, 2)\n    )\n), Filter.EnhancedGlitch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEnhancedOilFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiEnhancedOilFilter(\n    override val value: Float = 10f\n) : UiFilter<Float>(\n    title = R.string.enhanced_oil,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 1f..25f,\n            roundTo = 0\n        )\n    )\n), Filter.EnhancedOil"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEnhancedPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiEnhancedPixelationFilter(\n    override val value: Float = 48f,\n) : UiFilter<Float>(\n    title = R.string.enhanced_pixelation,\n    value = value,\n    valueRange = 10f..200f\n), Filter.EnhancedPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEnhancedZoomBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.EnhancedZoomBlurParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiEnhancedZoomBlurFilter(\n    override val value: EnhancedZoomBlurParams = EnhancedZoomBlurParams.Default,\n) : UiFilter<EnhancedZoomBlurParams>(\n    title = R.string.enhanced_zoom_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.radius, 1f..100f, 2),\n        FilterParam(R.string.sigma, 1f..100f, 2),\n        FilterParam(R.string.blur_center_x, 0f..1f, 2),\n        FilterParam(R.string.blur_center_y, 0f..1f, 2),\n        FilterParam(R.string.strength, 0f..3f, 2),\n        FilterParam(R.string.angle, 0f..360f, 0)\n    )\n), Filter.EnhancedZoomBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiEqualizeFilter(\n    override val value: Unit = Unit\n) : UiFilter<Unit>(\n    title = R.string.equalize,\n    value = value\n), Filter.Equalize"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramAdaptiveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiEqualizeHistogramAdaptiveFilter(\n    override val value: Pair<Float, Float> = 3f to 3f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.equalize_histogram_adaptive,\n    paramsInfo = listOf(\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0)\n    ),\n    value = value\n), Filter.EqualizeHistogramAdaptive"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramAdaptiveHSLFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiEqualizeHistogramAdaptiveHSLFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.equalize_histogram_adaptive_hsl,\n    paramsInfo = listOf(\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.EqualizeHistogramAdaptiveHSL"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramAdaptiveHSVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiEqualizeHistogramAdaptiveHSVFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.equalize_histogram_adaptive_hsv,\n    paramsInfo = listOf(\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.EqualizeHistogramAdaptiveHSV"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramAdaptiveLABFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiEqualizeHistogramAdaptiveLABFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.equalize_histogram_adaptive_lab,\n    paramsInfo = listOf(\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.EqualizeHistogramAdaptiveLAB"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramAdaptiveLUVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiEqualizeHistogramAdaptiveLUVFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.equalize_histogram_adaptive_luv,\n    paramsInfo = listOf(\n        FilterParam(R.string.grid_size_x, 1f..100f, 0),\n        FilterParam(R.string.grid_size_y, 1f..100f, 0),\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    ),\n    value = value\n), Filter.EqualizeHistogramAdaptiveLUV"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiEqualizeHistogramFilter : UiFilter<Unit>(\n    title = R.string.equalize_histogram,\n    value = Unit\n), Filter.EqualizeHistogram"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramHSVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiEqualizeHistogramHSVFilter(\n    override val value: Float = 128f\n) : UiFilter<Float>(\n    title = R.string.equalize_histogram_hsv,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.bins_count, 2f..256f, 0)\n    )\n), Filter.EqualizeHistogramHSV"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiEqualizeHistogramPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiEqualizeHistogramPixelationFilter(\n    override val value: Pair<Float, Float> = 50f to 50f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.equalize_histogram_pixelation,\n    paramsInfo = listOf(\n        FilterParam(R.string.grid_size_x, 1f..200f, 0),\n        FilterParam(R.string.grid_size_y, 1f..200f, 0)\n    ),\n    value = value\n), Filter.EqualizeHistogramPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiErodeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiErodeFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.erode,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.use_circle_kernel,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Erode"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiErrorLevelAnalysisFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiErrorLevelAnalysisFilter(\n    override val value: Float = 90f\n) : UiFilter<Float>(\n    title = R.string.error_level_analysis,\n    paramsInfo = listOf(\n        FilterParam(R.string.quality, 0f..100f, roundTo = 0),\n    ),\n    value = value\n), Filter.ErrorLevelAnalysis"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiExposureFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiExposureFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.exposure,\n    value = value,\n    valueRange = -4f..4f\n), Filter.Exposure"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFallColorsFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiFallColorsFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.fall_colors,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.FallColors"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFalseColorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiFalseColorFilter(\n    override val value: Pair<ColorModel, ColorModel> = Color.Yellow.toModel() to Color.Magenta.toModel()\n) : UiFilter<Pair<ColorModel, ColorModel>>(\n    title = R.string.false_color,\n    value = value,\n), Filter.FalseColor"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFalseFloydSteinbergDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiFalseFloydSteinbergDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.false_floyd_steinberg_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.FalseFloydSteinbergDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFantasyLandscapeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiFantasyLandscapeFilter : UiFilter<Unit>(\n    title = R.string.fantasy_landscape,\n    value = Unit\n), Filter.FantasyLandscape"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFastBilaterialBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiFastBilaterialBlurFilter(\n    override val value: Triple<Float, Float, Float> = Triple(11f, 10f, 3f),\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.fast_bilaterial_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..200f,\n            roundTo = NEAREST_ODD_ROUNDING\n        ),\n        FilterParam(\n            title = R.string.sigma,\n            valueRange = 1f..100f,\n            roundTo = 1\n        ),\n        FilterParam(\n            title = R.string.spatial_sigma,\n            valueRange = 1f..100f,\n            roundTo = 1\n        )\n    )\n), Filter.FastBilaterialBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFastBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiFastBlurFilter(\n    override val value: Pair<Float, Float> = 0.5f to 5f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.fast_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.scale, 0.1f..1f, 2),\n        FilterParam(R.string.radius, 0f..100f, 0)\n    )\n), Filter.FastBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFastGaussianBlur2DFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiFastGaussianBlur2DFilter(\n    override val value: Pair<Float, BlurEdgeMode> = 10f to BlurEdgeMode.Reflect101\n) : UiFilter<Pair<Float, BlurEdgeMode>>(\n    title = R.string.fast_gaussian_blur_2d,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..300f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.FastGaussianBlur2D"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFastGaussianBlur3DFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiFastGaussianBlur3DFilter(\n    override val value: Pair<Float, BlurEdgeMode> = 10f to BlurEdgeMode.Reflect101\n) : UiFilter<Pair<Float, BlurEdgeMode>>(\n    title = R.string.fast_gaussian_blur_3d,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..500f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.FastGaussianBlur3D"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFastGaussianBlur4DFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiFastGaussianBlur4DFilter(\n    override val value: Float = 10f\n) : UiFilter<Float>(\n    title = R.string.fast_gaussian_blur_4d,\n    value = value,\n    valueRange = 1f..100f\n), Filter.FastGaussianBlur4D"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFilmStock50Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiFilmStock50Filter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.film_stock_50,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.FilmStock50"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.annotation.StringRes\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Bookmark\nimport androidx.compose.material.icons.rounded.Extension\nimport androidx.compose.material.icons.rounded.FilterHdr\nimport androidx.compose.material.icons.rounded.Lightbulb\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.filterIsNotInstance\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.blurGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.colorGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.copyUiFilterInstance\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.distortionGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.ditheringGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.effectsGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.lightGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.lutGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.mapFilterToUiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.newUiFilterInstance\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.pixelationGroupFilters\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.generated.simpleGroupFilters\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Animation\nimport com.t8rin.imagetoolbox.core.resources.icons.BlurCircular\nimport com.t8rin.imagetoolbox.core.resources.icons.Cube\nimport com.t8rin.imagetoolbox.core.resources.icons.FloodFill\nimport com.t8rin.imagetoolbox.core.resources.icons.Gradient\nimport com.t8rin.imagetoolbox.core.resources.icons.Speed\nimport com.t8rin.imagetoolbox.core.resources.icons.TableEye\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\nsealed class UiFilter<T : Any>(\n    @StringRes val title: Int,\n    val paramsInfo: List<FilterParam> = listOf(),\n    override val value: T,\n) : Filter<T> {\n\n    override var isVisible: Boolean by mutableStateOf(true)\n\n    constructor(\n        @StringRes title: Int,\n        valueRange: ClosedFloatingPointRange<Float>,\n        value: T,\n    ) : this(\n        title = title,\n        paramsInfo = listOf(\n            FilterParam(valueRange = valueRange)\n        ),\n        value = value\n    )\n\n    fun <T : Any> copy(\n        value: T\n    ): UiFilter<*> = copyUiFilterInstance(\n        filter = this,\n        newValue = value\n    )\n\n    fun newInstance(): UiFilter<*> = newUiFilterInstance(this)\n\n    sealed class Group(\n        val icon: ImageVector,\n        val title: Int,\n        data: List<UiFilter<*>>\n    ) {\n        operator fun component1() = icon\n        operator fun component2() = title\n\n        internal val filters: List<UiFilter<*>> by lazy {\n            data.sortedBy { appContext.getString(it.title) }\n        }\n\n        private val filtersForTemplateCreation: List<UiFilter<*>> by lazy {\n            filters.filterIsNotInstance(\n                Filter.PaletteTransfer::class,\n                Filter.LUT512x512::class,\n                Filter.PaletteTransferVariant::class,\n                Filter.CubeLut::class,\n                Filter.LensCorrection::class\n            )\n        }\n\n        fun filters(canAddTemplates: Boolean) =\n            if (canAddTemplates) filters else filtersForTemplateCreation\n\n        data object Template : Group(\n            icon = Icons.Rounded.Extension,\n            title = R.string.template,\n            data = emptyList()\n        )\n\n        class Favorite(\n            data: List<UiFilter<*>>\n        ) : Group(\n            icon = Icons.Rounded.Bookmark,\n            title = R.string.favorite,\n            data = data\n        ) {\n            override fun toString(): String = \"Favorite\"\n        }\n\n        data object Simple : Group(\n            icon = Icons.Rounded.Speed,\n            title = R.string.simple_effects,\n            data = simpleGroupFilters()\n        )\n\n        data object Color : Group(\n            icon = Icons.Rounded.FloodFill,\n            title = R.string.color,\n            data = colorGroupFilters()\n        )\n\n        data object LUT : Group(\n            icon = Icons.Rounded.TableEye,\n            title = R.string.lut,\n            data = lutGroupFilters()\n        )\n\n        data object Light : Group(\n            icon = Icons.Rounded.Lightbulb,\n            title = R.string.light_aka_illumination,\n            data = lightGroupFilters()\n        )\n\n        data object Effects : Group(\n            icon = Icons.Rounded.FilterHdr,\n            title = R.string.effect,\n            data = effectsGroupFilters()\n        )\n\n        data object Blur : Group(\n            icon = Icons.Rounded.BlurCircular,\n            title = R.string.blur,\n            data = blurGroupFilters()\n        )\n\n        data object Pixelation : Group(\n            icon = Icons.Rounded.Cube,\n            title = R.string.pixelation,\n            data = pixelationGroupFilters()\n        )\n\n        data object Distortion : Group(\n            icon = Icons.Rounded.Animation,\n            title = R.string.distortion,\n            data = distortionGroupFilters()\n        )\n\n        data object Dithering : Group(\n            icon = Icons.Rounded.Gradient,\n            title = R.string.dithering,\n            data = ditheringGroupFilters()\n        )\n    }\n\n    companion object {\n        val groups: List<Group> by lazy {\n            listOf(\n                Group.Simple,\n                Group.Color,\n                Group.LUT,\n                Group.Light,\n                Group.Effects,\n                Group.Blur,\n                Group.Pixelation,\n                Group.Distortion,\n                Group.Dithering\n            )\n        }\n\n        val count: Int by lazy {\n            groups.sumOf { it.filters.size }\n        }\n    }\n\n}\n\nfun Filter<*>.toUiFilter(\n    preserveVisibility: Boolean = true\n): UiFilter<*> = mapFilterToUiFilter(\n    filter = this,\n    preserveVisibility = preserveVisibility\n)\n\n\ninfix fun Int.paramTo(valueRange: ClosedFloatingPointRange<Float>) = FilterParam(\n    title = this,\n    valueRange = valueRange\n)"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFloydSteinbergDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiFloydSteinbergDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.floyd_steinberg_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.FloydSteinbergDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFoggyNightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiFoggyNightFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.foggy_night,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.FoggyNight"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFractalGlassFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiFractalGlassFilter(\n    override val value: Pair<Float, Float> = 0.02f to 0.02f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.fractal_glass,\n    value = value,\n    paramsInfo = listOf(\n        R.string.strength paramTo 0f..1f,\n        R.string.amplitude paramTo 0f..1f\n    )\n), Filter.FractalGlass"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiFuturisticGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiFuturisticGradientFilter : UiFilter<Unit>(\n    title = R.string.futuristic_gradient,\n    value = Unit\n), Filter.FuturisticGradient"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGammaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiGammaFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.gamma,\n    value = value,\n    valueRange = 0f..2f\n), Filter.Gamma"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGaussianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiGaussianBlurFilter(\n    override val value: Triple<Float, Float, BlurEdgeMode> = Triple(\n        25f,\n        10f,\n        BlurEdgeMode.Reflect101\n    ),\n) : UiFilter<Triple<Float, Float, BlurEdgeMode>>(\n    title = R.string.gaussian_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 0f..100f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.sigma,\n            valueRange = 1f..100f\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.GaussianBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGaussianBoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiGaussianBoxBlurFilter(\n    override val value: Float = 10f\n) : UiFilter<Float>(\n    title = R.string.gaussian_box_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.sigma,\n            valueRange = 1f..300f,\n            roundTo = 0\n        )\n    )\n), Filter.GaussianBoxBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGlassSphereRefractionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiGlassSphereRefractionFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.71f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.glass_sphere_refraction,\n    value = value,\n    paramsInfo = listOf(\n        R.string.radius paramTo 0f..1f,\n        R.string.refractive_index paramTo 0f..1f\n    )\n), Filter.GlassSphereRefraction"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGlitchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiGlitchFilter(\n    override val value: Triple<Float, Float, Float> = Triple(20f, 15f, 9f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.glitch,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.amount,\n            valueRange = 0f..100f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.seed,\n            valueRange = 0f..100f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.repeat_count,\n            valueRange = 0f..100f,\n            roundTo = 0\n        )\n    )\n), Filter.Glitch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGlitchVariantFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiGlitchVariantFilter(\n    override val value: Triple<Float, Float, Float> = Triple(30f, 0.25f, 0.3f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.glitch_variant,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.repeat_count,\n            valueRange = 0f..100f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.max_offset,\n            valueRange = 0f..1f,\n            roundTo = 3\n        ),\n        FilterParam(\n            title = R.string.channel_shift,\n            valueRange = 0f..1f,\n            roundTo = 3\n        ),\n    )\n), Filter.GlitchVariant"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGlowFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiGlowFilter(\n    override val value: Float = 0.5f\n) : UiFilter<Float>(\n    title = R.string.glow,\n    value = value,\n    paramsInfo = listOf(\n        R.string.amount paramTo 0f..1f\n    )\n), Filter.Glow"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGoldenForestFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiGoldenForestFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.golden_forest,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.GoldenForest"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGoldenHourFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiGoldenHourFilter : UiFilter<Unit>(\n    title = R.string.golden_hour,\n    value = Unit\n), Filter.GoldenHour"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGothamFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiGothamFilter : UiFilter<Unit>(\n    title = R.string.gotham,\n    value = Unit\n), Filter.Gotham"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGrainFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiGrainFilter(\n    override val value: Float = 0.75f,\n) : UiFilter<Float>(\n    title = R.string.grain,\n    value = value,\n    valueRange = 0f..2f\n), Filter.Grain"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGrayscaleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiGrayscaleFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.299f, 0.587f, 0.114f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.gray_scale,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.color_red,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.color_green,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.color_blue,\n            valueRange = 0f..1f\n        )\n    )\n), Filter.Grayscale"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGreenSunFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiGreenSunFilter : UiFilter<Unit>(\n    title = R.string.green_sun,\n    value = Unit\n), Filter.GreenSun"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiGreenishFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiGreenishFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.greenish,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.Greenish"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHDRFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiHDRFilter : UiFilter<Unit>(\n    title = R.string.hdr,\n    value = Unit\n), Filter.HDR"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHableFilmicToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiHableFilmicToneMappingFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.hable_filmic_tone_mapping,\n    value = value,\n    valueRange = -4f..4f\n), Filter.HableFilmicToneMapping"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHalftoneFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiHalftoneFilter(\n    override val value: Float = 0.005f,\n) : UiFilter<Float>(\n    title = R.string.halftone,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(valueRange = 0.001f..0.02f, roundTo = 4)\n    )\n), Filter.Halftone"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHazeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiHazeFilter(\n    override val value: Pair<Float, Float> = 0.2f to 0f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.haze,\n    value = value,\n    paramsInfo = listOf(\n        R.string.distance paramTo -0.3f..0.3f,\n        R.string.slope paramTo -0.3f..0.3f\n    )\n), Filter.Haze"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHejlBurgessToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiHejlBurgessToneMappingFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.heji_burgess_tone_mapping,\n    value = value,\n    valueRange = 0f..4f\n), Filter.HejlBurgessToneMapping"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHighlightsAndShadowsFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiHighlightsAndShadowsFilter(\n    override val value: Float = 0.25f\n) : UiFilter<Float>(\n    title = R.string.highlights_shadows,\n    value = value,\n    valueRange = 0f..2f\n), Filter.HighlightsAndShadows"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHorizontalWindStaggerFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiHorizontalWindStaggerFilter(\n    override val value: Triple<Float, Int, ColorModel> = Triple(\n        first = 0.2f,\n        second = 90,\n        third = Color.Transparent.toModel()\n    )\n) : UiFilter<Triple<Float, Int, ColorModel>>(\n    title = R.string.horizontal_wind_stagger,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..100f,\n            roundTo = 1\n        ),\n        FilterParam(\n            title = R.string.amount,\n            valueRange = 10f..200f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.color,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.HorizontalWindStagger"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHotSummerFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiHotSummerFilter : UiFilter<Unit>(\n    title = R.string.hot_summer,\n    value = Unit\n), Filter.HotSummer"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiHueFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiHueFilter(\n    override val value: Float = 90f,\n) : UiFilter<Float>(\n    title = R.string.hue,\n    value = value,\n    valueRange = 0f..255f\n), Filter.Hue"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiJarvisJudiceNinkeDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiJarvisJudiceNinkeDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.jarvis_judice_ninke_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.JarvisJudiceNinkeDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiKaleidoscopeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.KaleidoscopeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiKaleidoscopeFilter(\n    override val value: KaleidoscopeParams = KaleidoscopeParams.Default\n) : UiFilter<KaleidoscopeParams>(\n    title = R.string.kaleidoscope,\n    paramsInfo = listOf(\n        FilterParam(R.string.angle, 0f..360f, 0),\n        FilterParam(R.string.secondary_angle, 0f..360f, 0),\n        FilterParam(R.string.center_x, 0f..1f, 2),\n        FilterParam(R.string.center_y, 0f..1f, 2),\n        FilterParam(R.string.sides, 2f..12f, 0),\n        FilterParam(R.string.radius, 0f..100f, 2),\n    ),\n    value = value\n), Filter.Kaleidoscope"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiKodakFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiKodakFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.kodak,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.Kodak"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiKuwaharaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiKuwaharaFilter(\n    override val value: Float = 9f,\n) : UiFilter<Float>(\n    title = R.string.kuwahara,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(null, 0f..10f, 0)\n    )\n), Filter.Kuwahara"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLUT512x512Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiLUT512x512Filter(\n    override val value: Pair<Float, ImageModel> = 1f to ImageModel(R.drawable.lookup)\n) : UiFilter<Pair<Float, ImageModel>>(\n    title = R.string.lut512x512,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.target_lut_image,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LUT512x512"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLaplacianFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiLaplacianFilter : UiFilter<Unit>(\n    title = R.string.laplacian,\n    value = Unit,\n    valueRange = 0f..0f\n), Filter.Laplacian"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLaplacianSimpleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiLaplacianSimpleFilter : UiFilter<Unit>(\n    title = R.string.laplacian_simple,\n    value = Unit\n), Filter.LaplacianSimple"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLavenderDreamFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiLavenderDreamFilter : UiFilter<Unit>(\n    title = R.string.lavender_dream,\n    value = Unit\n), Filter.LavenderDream"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLeftToRightDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiLeftToRightDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.left_to_right_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LeftToRightDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLemonadeLightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiLemonadeLightFilter : UiFilter<Unit>(\n    title = R.string.lemonade_light,\n    value = Unit\n), Filter.LemonadeLight"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLensCorrectionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiLensCorrectionFilter(\n    override val value: Pair<Float, FileModel> = 1f to FileModel(\"\")\n) : UiFilter<Pair<Float, FileModel>>(\n    title = R.string.lens_correction,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = -1f..3f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.target_lens_profile,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LensCorrection"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearBoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearBoxBlurFilter(\n    override val value: Pair<Int, TransferFunc> = 10 to TransferFunc.SRGB\n) : UiFilter<Pair<Int, TransferFunc>>(\n    title = R.string.linear_box_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..300f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.tag_transfer_function,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LinearBoxBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearFastGaussianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearFastGaussianBlurFilter(\n    override val value: Triple<Int, TransferFunc, BlurEdgeMode> = Triple(\n        first = 10,\n        second = TransferFunc.SRGB,\n        third = BlurEdgeMode.Reflect101\n    )\n) : UiFilter<Triple<Int, TransferFunc, BlurEdgeMode>>(\n    title = R.string.linear_fast_gaussian_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..300f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.tag_transfer_function,\n            valueRange = 0f..0f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LinearFastGaussianBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearFastGaussianBlurNextFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearFastGaussianBlurNextFilter(\n    override val value: Triple<Int, TransferFunc, BlurEdgeMode> = Triple(\n        first = 10,\n        second = TransferFunc.SRGB,\n        third = BlurEdgeMode.Reflect101\n    )\n) : UiFilter<Triple<Int, TransferFunc, BlurEdgeMode>>(\n    title = R.string.linear_fast_gaussian_blur_next,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..300f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.tag_transfer_function,\n            valueRange = 0f..0f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LinearFastGaussianBlurNext"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearGaussianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearGaussianParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearGaussianBlurFilter(\n    override val value: LinearGaussianParams = LinearGaussianParams.Default\n) : UiFilter<LinearGaussianParams>(\n    title = R.string.linear_gaussian_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 3f..600f,\n            roundTo = NEAREST_ODD_ROUNDING\n        ),\n        FilterParam(\n            title = R.string.sigma,\n            valueRange = 1f..50f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.tag_transfer_function,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LinearGaussianBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearGaussianBoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearGaussianBoxBlurFilter(\n    override val value: Pair<Float, TransferFunc> = 10f to TransferFunc.SRGB\n) : UiFilter<Pair<Float, TransferFunc>>(\n    title = R.string.linear_gaussian_box_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.sigma,\n            valueRange = 1f..300f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.tag_transfer_function,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LinearGaussianBoxBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearStackBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearStackBlurFilter(\n    override val value: Pair<Int, TransferFunc> = 10 to TransferFunc.SRGB\n) : UiFilter<Pair<Int, TransferFunc>>(\n    title = R.string.linear_stack_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..300f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.tag_transfer_function,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LinearStackBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearTentBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearTentBlurFilter(\n    override val value: Pair<Float, TransferFunc> = 11f to TransferFunc.SRGB\n) : UiFilter<Pair<Float, TransferFunc>>(\n    title = R.string.linear_tent_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.sigma,\n            valueRange = 1f..300f,\n            roundTo = NEAREST_ODD_ROUNDING\n        ),\n        FilterParam(\n            title = R.string.tag_transfer_function,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LinearTentBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLinearTiltShiftFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearTiltShiftParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiLinearTiltShiftFilter(\n    override val value: LinearTiltShiftParams = LinearTiltShiftParams.Default\n) : UiFilter<LinearTiltShiftParams>(\n    title = R.string.linear_tilt_shift,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.blur_radius, 1f..100f, 0),\n        FilterParam(R.string.sigma, 1f..50f, 2),\n        FilterParam(R.string.center_x, 0f..1f, 2),\n        FilterParam(R.string.center_y, 0f..1f, 2),\n        FilterParam(R.string.size, 0f..1f, 2),\n        FilterParam(R.string.angle, 0f..360f, 0)\n    )\n), Filter.LinearTiltShift"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLogarithmicToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiLogarithmicToneMappingFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.logarithmic_tone_mapping,\n    value = value,\n    valueRange = 0f..4f\n), Filter.LogarithmicToneMapping"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLookupFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiLookupFilter(\n    override val value: Float = -1f,\n) : UiFilter<Float>(\n    title = R.string.lookup,\n    value = value,\n    valueRange = -10f..10f\n), Filter.Lookup"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLowPolyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiLowPolyFilter(\n    override val value: Pair<Float, Boolean> = 2000f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.low_poly,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 50f..30000f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.fill,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.LowPoly"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiLuminanceGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiLuminanceGradientFilter : UiFilter<Unit>(\n    title = R.string.luminance_gradient,\n    value = Unit\n), Filter.LuminanceGradient"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMarbleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiMarbleFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.02f, 1f, 1f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.marble,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.turbulence,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.amplitude,\n            valueRange = 0f..1f\n        )\n    )\n), Filter.Marble"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMedianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiMedianBlurFilter(\n    override val value: Float = 10f\n) : UiFilter<Float>(\n    title = R.string.median_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.radius, 0f..100f, 0)\n    )\n), Filter.MedianBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMicroMacroPixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiMicroMacroPixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.micro_macro_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.MicroMacroPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMirrorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiMirrorFilter(\n    override val value: Pair<Float, MirrorSide> = 0.5f to MirrorSide.LeftToRight,\n) : UiFilter<Pair<Float, MirrorSide>>(\n    title = R.string.tile_mode_mirror,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.center,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.side,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.Mirror"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMissEtikateFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiMissEtikateFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.miss_etikate,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.MissEtikate"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMobiusFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiMobiusFilter(\n    override val value: Triple<Float, Float, Float> = Triple(1f, 0.9f, 1f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.mobius,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.exposure,\n            valueRange = 0f..2f\n        ),\n        FilterParam(\n            title = R.string.transition,\n            valueRange = -2f..2f\n        ),\n        FilterParam(\n            title = R.string.peak,\n            valueRange = -2f..2f\n        )\n    )\n), Filter.Mobius"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMoireFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiMoireFilter(\n    override val value: Unit = Unit\n) : UiFilter<Unit>(\n    title = R.string.moire,\n    value = value\n), Filter.Moire"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMonochromeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiMonochromeFilter(\n    override val value: Pair<Float, ColorModel> = 1f to Color(\n        red = 0.6f,\n        green = 0.45f,\n        blue = 0.3f,\n        alpha = 1.0f\n    ).toModel()\n) : UiFilter<Pair<Float, ColorModel>>(\n    title = R.string.monochrome,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.color,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.Monochrome"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMorphologicalGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiMorphologicalGradientFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.morphological_gradient,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.use_circle_kernel,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.MorphologicalGradient"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiMotionBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiMotionBlurFilter(\n    override val value: Triple<Int, Float, BlurEdgeMode> = Triple(25, 45f, BlurEdgeMode.Reflect101),\n) : UiFilter<Triple<Int, Float, BlurEdgeMode>>(\n    title = R.string.motion_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 0f..201f,\n            roundTo = NEAREST_ODD_ROUNDING\n        ),\n        FilterParam(\n            title = R.string.angle,\n            valueRange = 0f..360f\n        ),\n        FilterParam(\n            title = R.string.edge_mode,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.MotionBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNativeStackBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiNativeStackBlurFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.native_stack_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 3f..250f,\n            roundTo = 0\n        )\n    )\n), Filter.NativeStackBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNegativeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiNegativeFilter : UiFilter<Unit>(\n    title = R.string.negative,\n    value = Unit\n), Filter.Negative"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNeonFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiNeonFilter(\n    override val value: Triple<Float, Float, ColorModel> = Triple(\n        first = 1f,\n        second = 0.26f,\n        third = Color.Magenta.toModel()\n    )\n) : UiFilter<Triple<Float, Float, ColorModel>>(\n    title = R.string.neon,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.amount,\n            valueRange = 1f..25f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.color,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.Neon"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNightMagicFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiNightMagicFilter : UiFilter<Unit>(\n    title = R.string.night_magic,\n    value = Unit\n), Filter.NightMagic"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNightVisionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiNightVisionFilter : UiFilter<Unit>(\n    title = R.string.night_vision,\n    value = Unit\n), Filter.NightVision"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNoiseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiNoiseFilter(\n    override val value: Float = 128f\n) : UiFilter<Float>(\n    title = R.string.noise,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            valueRange = 0f..255f,\n            roundTo = 0\n        )\n    )\n), Filter.Noise"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNonMaximumSuppressionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiNonMaximumSuppressionFilter : UiFilter<Unit>(\n    title = R.string.non_maximum_suppression,\n    value = Unit\n), Filter.NonMaximumSuppression"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiNucleusPixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiNucleusPixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.nucleus_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.NucleusPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiOffsetFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiOffsetFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.25f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.offset,\n    value = value,\n    paramsInfo = listOf(\n        R.string.offset_x paramTo 0f..1f,\n        R.string.offset_y paramTo 0f..1f\n    )\n), Filter.Offset"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiOilFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiOilFilter(\n    override val value: Pair<Float, Float> = 4f to 1f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.oil,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..20f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..4f,\n            roundTo = 1\n        )\n    )\n), Filter.Oil"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiOldTvFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiOldTvFilter : UiFilter<Unit>(\n    title = R.string.old_tv,\n    value = Unit\n), Filter.OldTv"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiOpacityFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiOpacityFilter(\n    override val value: Float = 0.5f,\n) : UiFilter<Float>(\n    title = R.string.opacity,\n    value = value,\n    valueRange = 0f..1f\n), Filter.Opacity"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiOpeningFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiOpeningFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.opening,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.use_circle_kernel,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Opening"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiOrangeHazeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiOrangeHazeFilter : UiFilter<Unit>(\n    title = R.string.orange_haze,\n    value = Unit\n), Filter.OrangeHaze"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiOrbitalPixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiOrbitalPixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.orbital_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.OrbitalPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPaletteTransferFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiPaletteTransferFilter(\n    override val value: Pair<Float, ImageModel> = 1f to ImageModel(R.drawable.filter_preview_source_2)\n) : UiFilter<Pair<Float, ImageModel>>(\n    title = R.string.palette_transfer,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.target_image,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.PaletteTransfer"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPaletteTransferVariantFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PaletteTransferSpace\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiPaletteTransferVariantFilter(\n    override val value: Triple<Float, PaletteTransferSpace, ImageModel> = Triple(\n        first = 1f,\n        second = PaletteTransferSpace.OKLAB,\n        third = ImageModel(R.drawable.filter_preview_source_2)\n    )\n) : UiFilter<Triple<Float, PaletteTransferSpace, ImageModel>>(\n    title = R.string.palette_transfer_variant,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.tag_color_space,\n            valueRange = 0f..1f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.target_image,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.PaletteTransferVariant"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPastelFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiPastelFilter : UiFilter<Unit>(\n    title = R.string.pastel,\n    value = Unit\n), Filter.Pastel"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPerlinDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiPerlinDistortionFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.02f, 1f, 1f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.perlin_distortion,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.turbulence,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.amplitude,\n            valueRange = 0f..1f\n        )\n    )\n), Filter.PerlinDistortion"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPinchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.PinchParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiPinchFilter(\n    override val value: PinchParams = PinchParams.Default\n) : UiFilter<PinchParams>(\n    title = R.string.whirl_and_pinch,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.angle, 0f..360f, 0),\n        R.string.center_x paramTo 0f..1f,\n        R.string.center_y paramTo 0f..1f,\n        R.string.radius paramTo 0f..2f,\n        R.string.amount paramTo -1f..1f\n    )\n), Filter.Pinch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPinkDreamFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiPinkDreamFilter : UiFilter<Unit>(\n    title = R.string.pink_dream,\n    value = Unit\n), Filter.PinkDream"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPixelMeltFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiPixelMeltFilter(\n    override val value: Pair<Float, Float> = 20f to 0.5f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.pixel_melt,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.max_drop,\n            valueRange = 0f..250f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 3\n        ),\n    )\n), Filter.PixelMelt"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiPixelationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.pixelation,\n    value = value,\n    valueRange = 5f..200f\n), Filter.Pixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPointillizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiPointillizeFilter(\n    override val value: VoronoiCrystallizeParams = VoronoiCrystallizeParams.Default\n) : UiFilter<VoronoiCrystallizeParams>(\n    title = R.string.pointillize,\n    paramsInfo = listOf(\n        FilterParam(R.string.border_thickness, 0f..5f, 2),\n        FilterParam(R.string.scale, 1f..300f, 2),\n        FilterParam(R.string.randomness, 0f..10f, 2),\n        FilterParam(R.string.shape, 0f..4f, 0),\n        FilterParam(R.string.turbulence, 0f..1f, 2),\n        FilterParam(R.string.angle, 0f..360f, 0),\n        FilterParam(R.string.stretch, 1f..6f, 2),\n        FilterParam(R.string.amount, 0f..1f, 2),\n        FilterParam(R.string.border_color, 0f..0f, 0),\n    ),\n    value = value\n), Filter.Pointillize"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPoissonBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiPoissonBlurFilter(\n    override val value: Float = 10f,\n) : UiFilter<Float>(\n    title = R.string.poisson_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 3f..200f,\n            roundTo = 0\n        )\n    )\n), Filter.PoissonBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPolarCoordinatesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PolarCoordinatesType\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiPolarCoordinatesFilter(\n    override val value: PolarCoordinatesType = PolarCoordinatesType.RECT_TO_POLAR\n) : UiFilter<PolarCoordinatesType>(\n    title = R.string.polar_coordinates,\n    value = value\n), Filter.PolarCoordinates"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPolaroidFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiPolaroidFilter : UiFilter<Unit>(\n    title = R.string.polaroid,\n    value = Unit\n), Filter.Polaroid"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPolkaDotFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiPolkaDotFilter(\n    override val value: Triple<Int, Int, ColorModel> = Triple(\n        first = 10,\n        second = 8,\n        third = Color.Black.toModel()\n    )\n) : UiFilter<Triple<Int, Int, ColorModel>>(\n    title = R.string.polka_dot,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 1f..40f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.spacing,\n            valueRange = 1f..40f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.background_color,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.PolkaDot"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPopArtFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiPopArtFilter(\n    override val value: Triple<Float, ColorModel, PopArtBlendingMode> = Triple(\n        first = 1f,\n        second = Color.Red.toModel(),\n        third = PopArtBlendingMode.MULTIPLY\n    )\n) : UiFilter<Triple<Float, ColorModel, PopArtBlendingMode>>(\n    title = R.string.pop_art,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.color,\n            valueRange = 0f..1f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.overlay_mode,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.PopArt"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPosterizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiPosterizeFilter(\n    override val value: Float = 5f,\n) : UiFilter<Float>(\n    title = R.string.posterize,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(null, 1f..40f, 0)\n    )\n), Filter.Posterize"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiProtanopiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiProtanopiaFilter : UiFilter<Unit>(\n    title = R.string.protanopia,\n    value = Unit\n), Filter.Protanopia"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiProtonomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiProtonomalyFilter : UiFilter<Unit>(\n    title = R.string.protonomaly,\n    value = Unit\n), Filter.Protonomaly"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPulseGridPixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiPulseGridPixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.pulse_grid_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.PulseGridPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiPurpleMistFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiPurpleMistFilter : UiFilter<Unit>(\n    title = R.string.purple_mist,\n    value = Unit\n), Filter.PurpleMist"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiQuantizierFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiQuantizierFilter(\n    override val value: Float = 256f\n) : UiFilter<Float>(\n    title = R.string.quantizier,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 2f..4096f,\n            roundTo = 0\n        )\n    )\n), Filter.Quantizier"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRGBFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterValueWrapper\nimport com.t8rin.imagetoolbox.core.filters.domain.model.wrap\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiRGBFilter(\n    override val value: FilterValueWrapper<ColorModel> = Color.Green.toModel().wrap(),\n) : UiFilter<FilterValueWrapper<ColorModel>>(\n    title = R.string.rgb_filter,\n    value = value,\n), Filter.RGB"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRadialTiltShiftFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RadialTiltShiftParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiRadialTiltShiftFilter(\n    override val value: RadialTiltShiftParams = RadialTiltShiftParams.Default\n) : UiFilter<RadialTiltShiftParams>(\n    title = R.string.tilt_shift,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.blur_radius, 1f..100f, 0),\n        FilterParam(R.string.sigma, 1f..50f, 2),\n        FilterParam(R.string.center_x, 0f..1f, 2),\n        FilterParam(R.string.center_y, 0f..1f, 2),\n        FilterParam(R.string.radius, 0f..1f, 2)\n    )\n), Filter.RadialTiltShift"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRadialWeavePixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiRadialWeavePixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.radial_weave_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.RadialWeavePixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRainbowWorldFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiRainbowWorldFilter : UiFilter<Unit>(\n    title = R.string.rainbow_world,\n    value = Unit\n), Filter.RainbowWorld"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRandomDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiRandomDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.random_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.RandomDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRedSwirlFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiRedSwirlFilter : UiFilter<Unit>(\n    title = R.string.red_swirl,\n    value = Unit\n), Filter.RedSwirl"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiReduceNoiseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiReduceNoiseFilter(\n    override val value: Unit = Unit\n) : UiFilter<Unit>(\n    title = R.string.reduce_noise,\n    value = value\n), Filter.ReduceNoise"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRemoveColorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiRemoveColorFilter(\n    override val value: Pair<Float, ColorModel> = 0f to Color(0xFF000000).toModel(),\n) : UiFilter<Pair<Float, ColorModel>>(\n    title = R.string.remove_color,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.tolerance,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.color_to_remove,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.RemoveColor"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiReplaceColorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiReplaceColorFilter(\n    override val value: Triple<Float, ColorModel, ColorModel> = Triple(\n        first = 0f,\n        second = Color(red = 0.0f, green = 0.0f, blue = 0.0f, alpha = 1.0f).toModel(),\n        third = Color(red = 1.0f, green = 1.0f, blue = 1.0f, alpha = 1.0f).toModel()\n    ),\n) : UiFilter<Triple<Float, ColorModel, ColorModel>>(\n    title = R.string.replace_color,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.tolerance,\n            valueRange = 0f..1f\n        ),\n        FilterParam(\n            title = R.string.color_to_replace,\n            valueRange = 0f..0f\n        ),\n        FilterParam(\n            title = R.string.target_color,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.ReplaceColor"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRetroYellowFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiRetroYellowFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.retro_yellow,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.RetroYellow"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRingBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiRingBlurFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.ring_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 3f..200f,\n            roundTo = NEAREST_ODD_ROUNDING\n        )\n    )\n), Filter.RingBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiRubberStampFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RubberStampParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiRubberStampFilter(\n    override val value: RubberStampParams = RubberStampParams.Default\n) : UiFilter<RubberStampParams>(\n    title = R.string.rubber_stmp,\n    paramsInfo = listOf(\n        R.string.threshold paramTo 0f..1f,\n        R.string.brush_softness paramTo 0f..1f,\n        R.string.radius paramTo 0f..2f,\n        R.string.first_color paramTo 0f..0f,\n        R.string.second_color paramTo 0f..0f\n    ),\n    value = value\n), Filter.RubberStamp"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSandPaintingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiSandPaintingFilter(\n    override val value: Triple<Int, Int, ColorModel> = Triple(5000, 50, Color.Black.toModel())\n) : UiFilter<Triple<Int, Int, ColorModel>>(\n    title = R.string.sand_painting,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 50f..75000f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 30f..90f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.background_color,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.SandPainting"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSaturationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiSaturationFilter(\n    override val value: Pair<Float, Boolean> = 2f to true,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.saturation,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..2f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.enable_tonemapping,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.Saturation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSeamCarvingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiSeamCarvingFilter(\n    override val value: IntegerSize = IntegerSize.Zero\n) : UiFilter<IntegerSize>(\n    title = R.string.seam_carving,\n    paramsInfo = listOf(\n        FilterParam(R.string.width, 0f..0f),\n        FilterParam(R.string.height, 0f..0f),\n    ),\n    value = value\n), Filter.SeamCarving"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSepiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSepiaFilter : UiFilter<Unit>(\n    title = R.string.sepia,\n    value = Unit\n), Filter.Sepia"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSharpenFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiSharpenFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.sharpen,\n    value = value,\n    valueRange = -1f..1f\n), Filter.Sharpen"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiShuffleBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiShuffleBlurFilter(\n    override val value: Pair<Float, Float> = 35f to 1f\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.shuffle_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.radius,\n            valueRange = 0f..70f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = -1f..1f,\n            roundTo = 2\n        ),\n    )\n), Filter.ShuffleBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSideFadeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SideFadeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiSideFadeFilter(\n    override val value: SideFadeParams = SideFadeParams.Relative(FadeSide.End, 0.5f),\n) : UiFilter<SideFadeParams>(\n    title = R.string.side_fade,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        ),\n        FilterParam(\n            title = R.string.side,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.SideFade"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSierraDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiSierraDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.sierra_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.SierraDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSierraLiteDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiSierraLiteDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.sierra_lite_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.SierraLiteDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSimpleOldTvFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSimpleOldTvFilter : UiFilter<Unit>(\n    title = R.string.simple_old_tv,\n    value = Unit\n), Filter.SimpleOldTv"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSimpleSketchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSimpleSketchFilter : UiFilter<Unit>(\n    title = R.string.simple_sketch,\n    value = Unit\n), Filter.SimpleSketch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSimpleSolarizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSimpleSolarizeFilter(\n    override val value: Unit = Unit\n) : UiFilter<Unit>(\n    title = R.string.simple_solarize,\n    value = value\n), Filter.SimpleSolarize"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSimpleThresholdDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiSimpleThresholdDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.simple_threshold_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.SimpleThresholdDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSimpleWeavePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiSimpleWeavePixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.simple_weave_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.SimpleWeavePixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSketchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiSketchFilter(\n    override val value: Float = 5f,\n) : UiFilter<Float>(\n    title = R.string.sketch,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 3f..9f,\n            roundTo = 0\n        )\n    )\n), Filter.Sketch"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSmearFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SmearParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiSmearFilter(\n    override val value: SmearParams = SmearParams.Default\n) : UiFilter<SmearParams>(\n    title = R.string.smear,\n    paramsInfo = listOf(\n        FilterParam(R.string.angle, 0f..360f, 0),\n        R.string.density paramTo 0f..1f,\n        R.string.mix paramTo 0f..1f,\n        FilterParam(R.string.distance, 0f..200f, 0),\n        FilterParam(R.string.shape, 0f..3f, 0)\n    ),\n    value = value\n), Filter.Smear"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSmoothToonFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiSmoothToonFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.5f, 0.2f, 10f)\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.smooth_toon,\n    value = value,\n    paramsInfo = listOf(\n        R.string.blur_size paramTo 0f..100f,\n        R.string.threshold paramTo 0f..5f,\n        R.string.quantizationLevels paramTo 0f..100f\n    )\n), Filter.SmoothToon"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSobelEdgeDetectionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiSobelEdgeDetectionFilter(\n    override val value: Float = 1f,\n) : UiFilter<Float>(\n    title = R.string.sobel_edge,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(title = R.string.line_width, valueRange = 1f..25f, roundTo = 0)\n    )\n), Filter.SobelEdgeDetection"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSobelSimpleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSobelSimpleFilter : UiFilter<Unit>(\n    title = R.string.sobel_simple,\n    value = Unit\n), Filter.SobelSimple"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSoftEleganceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiSoftEleganceFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.soft_elegance,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.SoftElegance"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSoftEleganceVariantFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LUT)\nclass UiSoftEleganceVariantFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.soft_elegance_variant,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..1f,\n            roundTo = 2\n        )\n    )\n), Filter.SoftEleganceVariant"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSoftSpringLightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSoftSpringLightFilter : UiFilter<Unit>(\n    title = R.string.soft_spring_light,\n    value = Unit\n), Filter.SoftSpringLight"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSolarizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiSolarizeFilter(\n    override val value: Float = 0.5f,\n) : UiFilter<Float>(\n    title = R.string.solarize,\n    value = value,\n    valueRange = 0f..1f\n), Filter.Solarize"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSpacePortalFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSpacePortalFilter : UiFilter<Unit>(\n    title = R.string.space_portal,\n    value = Unit\n), Filter.SpacePortal"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSparkleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SparkleParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiSparkleFilter(\n    override val value: SparkleParams = SparkleParams.Default\n) : UiFilter<SparkleParams>(\n    title = R.string.sparkle,\n    paramsInfo = listOf(\n        FilterParam(R.string.amount, 0f..200f, 0),\n        FilterParam(R.string.rays, 0f..200f, 0),\n        FilterParam(R.string.radius, 0f..1f),\n        FilterParam(R.string.randomness, 0f..100f, 0),\n        FilterParam(R.string.center_x, 0f..1f),\n        FilterParam(R.string.center_y, 0f..1f),\n        FilterParam(R.string.color, 0f..0f)\n    ),\n    value = value\n), Filter.Sparkle"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSpectralFireFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSpectralFireFilter : UiFilter<Unit>(\n    title = R.string.spectral_fire,\n    value = Unit\n), Filter.SpectralFire"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSphereLensDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiSphereLensDistortionFilter(\n    override val value: Quad<Float, Float, Float, Float> = 2.5f to 0.5f qto (0.5f to 0.5f)\n) : UiFilter<Quad<Float, Float, Float, Float>>(\n    title = R.string.sphere_lensh_distortion,\n    paramsInfo = listOf(\n        R.string.refraction_index paramTo 1f..10f,\n        R.string.radius paramTo 0f..1f,\n        R.string.center_x paramTo 0f..1f,\n        R.string.center_y paramTo 0f..1f\n    ),\n    value = value\n), Filter.SphereLensDistortion"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSphereRefractionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiSphereRefractionFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.71f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.sphere_refraction,\n    value = value,\n    paramsInfo = listOf(\n        R.string.radius paramTo 0f..1f,\n        R.string.refractive_index paramTo 0f..1f\n    )\n), Filter.SphereRefraction"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiStackBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiStackBlurFilter(\n    override val value: Pair<Float, Float> = 0.5f to 10f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.stack_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.scale, 0.1f..1f, 2),\n        FilterParam(R.string.radius, 0f..100f, 0)\n    )\n), Filter.StackBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiStaggeredPixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiStaggeredPixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.staggered_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.StaggeredPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiStarBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiStarBlurFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.star_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 3f..200f,\n            roundTo = NEAREST_ODD_ROUNDING\n        )\n    )\n), Filter.StarBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiStrokePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiStrokePixelationFilter(\n    override val value: Pair<Float, ColorModel> = 20f to Color.Black.toModel(),\n) : UiFilter<Pair<Float, ColorModel>>(\n    title = R.string.stroke_pixelation,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.pixel_size,\n            valueRange = 5f..200f\n        ),\n        FilterParam(\n            title = R.string.background_color,\n            valueRange = 0f..0f\n        )\n    )\n), Filter.StrokePixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiStuckiDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiStuckiDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.stucki_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.StuckiDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSunriseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiSunriseFilter : UiFilter<Unit>(\n    title = R.string.sunrise,\n    value = Unit\n), Filter.Sunrise"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiSwirlDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiSwirlDistortionFilter(\n    override val value: Quad<Float, Float, Float, Float> = 0.5f to 1f qto (0.5f to 0.5f),\n) : UiFilter<Quad<Float, Float, Float, Float>>(\n    title = R.string.swirl,\n    value = value,\n    paramsInfo = listOf(\n        R.string.radius paramTo 0f..1f,\n        R.string.angle paramTo -1f..1f,\n        R.string.center_x paramTo 0.01f..1f,\n        R.string.center_y paramTo 0.01f..1f\n    )\n), Filter.SwirlDistortion"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiTentBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiTentBlurFilter(\n    override val value: Float = 10f,\n) : UiFilter<Float>(\n    title = R.string.tent_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 1f..300f,\n            roundTo = NEAREST_ODD_ROUNDING\n        )\n    )\n), Filter.TentBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiThresholdFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiThresholdFilter(\n    override val value: Float = 128f,\n) : UiFilter<Float>(\n    title = R.string.luminance_threshold,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = null,\n            valueRange = 0f..255f,\n            roundTo = 0\n        )\n    )\n), Filter.Threshold"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiToneCurvesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ToneCurvesParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiToneCurvesFilter(\n    override val value: ToneCurvesParams = ToneCurvesParams.Default\n) : UiFilter<ToneCurvesParams>(\n    title = R.string.tone_curves,\n    paramsInfo = listOf(\n        FilterParam(R.string.values, 0f..0f)\n    ),\n    value = value\n), Filter.ToneCurves"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiToonFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiToonFilter(\n    override val value: Pair<Float, Float> = 0.2f to 10f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.toon,\n    value = value,\n    paramsInfo = listOf(\n        R.string.threshold paramTo 0f..5f,\n        R.string.quantizationLevels paramTo 0f..100f\n    )\n), Filter.Toon"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiTopHatFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiTopHatFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.top_hat,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.just_size,\n            valueRange = 1f..150f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.use_circle_kernel,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.TopHat"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiTriToneFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.COLOR)\nclass UiTriToneFilter(\n    override val value: Triple<ColorModel, ColorModel, ColorModel> = Triple(\n        first = Color(0xFFFF003B).toModel(),\n        second = Color(0xFF831111).toModel(),\n        third = Color(0xFFFF0099).toModel()\n    )\n) : UiFilter<Triple<ColorModel, ColorModel, ColorModel>>(\n    title = R.string.tri_tone,\n    value = value,\n), Filter.TriTone"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiTritanopiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiTritanopiaFilter : UiFilter<Unit>(\n    title = R.string.tritanopia,\n    value = Unit\n), Filter.Tritanopia"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiTritonomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiTritonomalyFilter : UiFilter<Unit>(\n    title = R.string.tritonomaly,\n    value = Unit\n), Filter.Tritonomaly"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiTwirlFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiTwirlFilter(\n    override val value: Quad<Float, Float, Float, Float> = 45f to 0.5f qto (0.5f to 0.5f)\n) : UiFilter<Quad<Float, Float, Float, Float>>(\n    title = R.string.twirl,\n    paramsInfo = listOf(\n        R.string.angle paramTo -360f..360f,\n        R.string.center_x paramTo 0f..1f,\n        R.string.center_y paramTo 0f..1f,\n        R.string.radius paramTo 0f..1f,\n    ),\n    value = value\n), Filter.Twirl"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiTwoRowSierraDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiTwoRowSierraDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : UiFilter<Pair<Float, Boolean>>(\n    title = R.string.two_row_sierra_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.threshold,\n            valueRange = 1f..255f,\n            roundTo = 0\n        ),\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.TwoRowSierraDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiUchimuraFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiUchimuraFilter(\n    override val value: Float = 1f\n) : UiFilter<Float>(\n    title = R.string.uchimura,\n    value = value,\n    valueRange = 0f..2f\n), Filter.Uchimura"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiUnsharpFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiUnsharpFilter(\n    override val value: Float = 0.5f,\n) : UiFilter<Float>(\n    title = R.string.unsharp,\n    value = value,\n    valueRange = 0f..1f\n), Filter.Unsharp"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiVHSFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport kotlin.math.PI\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiVHSFilter(\n    override val value: Pair<Float, Float> = 2f to 3f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.vhs,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.seed,\n            valueRange = 0f..PI.toFloat(),\n            roundTo = 3\n        ),\n        FilterParam(\n            title = R.string.strength,\n            valueRange = 0f..10f,\n            roundTo = 3\n        ),\n    )\n), Filter.VHS"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiVibranceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiVibranceFilter(\n    override val value: Float = 3f,\n) : UiFilter<Float>(\n    title = R.string.vibrance,\n    value = value,\n    valueRange = -5f..5f\n), Filter.Vibrance"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiVignetteFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\n\n@UiFilterInject(group = UiFilterInject.Groups.EFFECTS)\nclass UiVignetteFilter(\n    override val value: Triple<Float, Float, ColorModel> = Triple(\n        first = 0.3f,\n        second = 0.75f,\n        third = Color.Black.toModel()\n    ),\n) : UiFilter<Triple<Float, Float, ColorModel>>(\n    title = R.string.vignette,\n    value = value,\n    paramsInfo = listOf(\n        R.string.start paramTo -2f..2f,\n        R.string.end paramTo -2f..2f,\n        R.string.color paramTo 0f..0f\n    )\n), Filter.Vignette"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiVintageFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiVintageFilter : UiFilter<Unit>(\n    title = R.string.vintage,\n    value = Unit\n), Filter.Vintage"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiVoronoiCrystallizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiVoronoiCrystallizeFilter(\n    override val value: VoronoiCrystallizeParams = VoronoiCrystallizeParams.Default\n) : UiFilter<VoronoiCrystallizeParams>(\n    title = R.string.voronoi_crystallize,\n    paramsInfo = listOf(\n        FilterParam(R.string.border_thickness, 0f..5f, 2),\n        FilterParam(R.string.scale, 1f..300f, 2),\n        FilterParam(R.string.randomness, 0f..10f, 2),\n        FilterParam(R.string.shape, 0f..4f, 0),\n        FilterParam(R.string.turbulence, 0f..1f, 2),\n        FilterParam(R.string.angle, 0f..360f, 0),\n        FilterParam(R.string.stretch, 1f..6f, 2),\n        FilterParam(R.string.amount, 0f..1f, 2),\n        FilterParam(R.string.border_color, 0f..0f, 0),\n    ),\n    value = value\n), Filter.VoronoiCrystallize"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiVortexPixelizationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiVortexPixelizationFilter(\n    override val value: Float = 25f,\n) : UiFilter<Float>(\n    title = R.string.vortex_pixelization,\n    value = value,\n    valueRange = 5f..200f\n), Filter.VortexPixelation"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiWarmFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiWarmFilter : UiFilter<Unit>(\n    title = R.string.warm,\n    value = Unit\n), Filter.Warm"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiWaterEffectFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.WaterParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DISTORTION)\nclass UiWaterEffectFilter(\n    override val value: WaterParams = WaterParams()\n) : UiFilter<WaterParams>(\n    title = R.string.water_effect,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.just_size, 0f..1f, 2),\n        FilterParam(R.string.frequency_x, -4f..4f, 2),\n        FilterParam(R.string.frequency_y, -4f..4f, 2),\n        FilterParam(R.string.amplitude_x, -4f..4f, 2),\n        FilterParam(R.string.amplitude_y, -4f..4f, 2)\n    )\n), Filter.WaterEffect"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiWeakPixelFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.SIMPLE)\nclass UiWeakPixelFilter : UiFilter<Unit>(\n    title = R.string.weak_pixel_inclusion,\n    value = Unit\n), Filter.WeakPixel"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiWeaveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.PIXELATION)\nclass UiWeaveFilter(\n    override val value: Quad<Float, Float, Float, Float> = 16f to 16f qto (6f to 6f)\n) : UiFilter<Quad<Float, Float, Float, Float>>(\n    title = R.string.weave,\n    paramsInfo = listOf(\n        R.string.x_width paramTo 0f..100f,\n        R.string.y_wdth paramTo 0f..100f,\n        R.string.x_gap paramTo 0f..100f,\n        R.string.y_gap paramTo 0f..100f,\n    ),\n    value = value\n), Filter.Weave"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiWhiteBalanceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.LIGHT)\nclass UiWhiteBalanceFilter(\n    override val value: Pair<Float, Float> = 7000.0f to 100f,\n) : UiFilter<Pair<Float, Float>>(\n    title = R.string.white_balance,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.temperature, 1000f..10000f, 0),\n        FilterParam(R.string.tint, -100f..100f, 2)\n    )\n), Filter.WhiteBalance"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiYililomaDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.DITHERING)\nclass UiYililomaDitheringFilter(\n    override val value: Boolean = false,\n) : UiFilter<Boolean>(\n    title = R.string.yililoma_dithering,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(\n            title = R.string.gray_scale,\n            valueRange = 0f..0f,\n            roundTo = 0\n        )\n    )\n), Filter.YililomaDithering"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/model/UiZoomBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterParam\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@UiFilterInject(group = UiFilterInject.Groups.BLUR)\nclass UiZoomBlurFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.5f, 0.5f, 5f),\n) : UiFilter<Triple<Float, Float, Float>>(\n    title = R.string.zoom_blur,\n    value = value,\n    paramsInfo = listOf(\n        FilterParam(R.string.blur_center_x, 0f..1f, 2),\n        FilterParam(R.string.blur_center_y, 0f..1f, 2),\n        FilterParam(R.string.blur_size, 0f..10f, 2)\n    )\n), Filter.ZoomBlur"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/utils/CollectAsUiState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.utils\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.collectAsState\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.map\n\n@JvmName(\"collectAsUiState1\")\n@Composable\nfun Flow<List<Filter<*>>>.collectAsUiState(): State<List<UiFilter<*>>> = this\n    .map { list ->\n        list.map {\n            it.toUiFilter()\n        }\n    }\n    .collectAsState(emptyList())\n\n\n@Composable\nfun Flow<List<TemplateFilter>>.collectAsUiState(): State<List<TemplateFilter>> = this\n    .map { list ->\n        list.sortedBy { it.name }\n    }\n    .collectAsState(emptyList())"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/utils/LamaLoader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.utils\n\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.neural_tools.inpaint.LaMaProcessor\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.onEach\n\ninterface LamaLoader {\n    val isDownloaded: Boolean\n    fun download(): Flow<DownloadProgress>\n\n    companion object Companion : LamaLoader by LamaLoaderImpl\n}\n\nprivate object LamaLoaderImpl : LamaLoader {\n    private val _isDownloaded: MutableState<Boolean> =\n        mutableStateOf(LaMaProcessor.isDownloaded.value)\n    override val isDownloaded: Boolean by _isDownloaded\n\n    init {\n        LaMaProcessor.isDownloaded.onEach {\n            _isDownloaded.value = it\n        }.launchIn(CoroutineScope(Dispatchers.IO))\n    }\n\n    override fun download(): Flow<DownloadProgress> =\n        LaMaProcessor.startDownload().map {\n            DownloadProgress(\n                currentPercent = it.currentPercent,\n                currentTotalSize = it.currentTotalSize\n            )\n        }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/utils/Mappings.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.utils\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PaletteTransferSpace\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PolarCoordinatesType\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.resources.R\n\ninternal val PopArtBlendingMode.translatedName: String\n    @Composable\n    get() = when (this) {\n        PopArtBlendingMode.MULTIPLY -> \"Multiply\"\n        PopArtBlendingMode.COLOR_BURN -> \"Color Burn\"\n        PopArtBlendingMode.SOFT_LIGHT -> \"Soft Light\"\n        PopArtBlendingMode.HSL_COLOR -> \"HSL Color\"\n        PopArtBlendingMode.HSL_HUE -> \"HSL Hue\"\n        PopArtBlendingMode.DIFFERENCE -> \"Difference\"\n    }\n\ninternal val PaletteTransferSpace.translatedName: String\n    @Composable\n    get() = when (this) {\n        PaletteTransferSpace.LALPHABETA -> \"Lαβ\"\n        PaletteTransferSpace.LAB -> \"LAB\"\n        PaletteTransferSpace.OKLAB -> \"OKLAB\"\n        PaletteTransferSpace.LUV -> \"LUV\"\n    }\n\ninternal val TransferFunc.translatedName: String\n    @Composable\n    get() = when (this) {\n        TransferFunc.SRGB -> \"sRGB\"\n        TransferFunc.REC709 -> \"Rec.709\"\n        TransferFunc.GAMMA2P2 -> \"${stringResource(R.string.gamma)} 2.2\"\n        TransferFunc.GAMMA2P8 -> \"${stringResource(R.string.gamma)} 2.8\"\n    }\n\ninternal val BlurEdgeMode.translatedName: String\n    @Composable\n    get() = when (this) {\n        BlurEdgeMode.Clamp -> stringResource(R.string.tile_mode_clamp)\n        BlurEdgeMode.Reflect101 -> stringResource(R.string.mirror_101)\n        BlurEdgeMode.Wrap -> stringResource(R.string.wrap)\n        BlurEdgeMode.Reflect -> stringResource(R.string.tile_mode_mirror)\n    }\n\ninternal val FadeSide.translatedName: String\n    @Composable\n    get() = when (this) {\n        FadeSide.Start -> stringResource(R.string.start)\n        FadeSide.End -> stringResource(R.string.end)\n        FadeSide.Top -> stringResource(R.string.top)\n        FadeSide.Bottom -> stringResource(R.string.bottom)\n    }\n\ninternal val MirrorSide.translatedName: String\n    @Composable\n    get() = when (this) {\n        MirrorSide.LeftToRight -> stringResource(R.string.left_to_right)\n        MirrorSide.RightToLeft -> stringResource(R.string.right_to_left)\n        MirrorSide.TopToBottom -> stringResource(R.string.top_to_bottom)\n        MirrorSide.BottomToTop -> stringResource(R.string.bottom_to_top)\n    }\n\ninternal val PolarCoordinatesType.translatedName: String\n    @Composable\n    get() = when (this) {\n        PolarCoordinatesType.RECT_TO_POLAR -> stringResource(R.string.rect_to_polar)\n        PolarCoordinatesType.POLAR_TO_RECT -> stringResource(R.string.polar_to_rect)\n        PolarCoordinatesType.INVERT_IN_CIRCLE -> stringResource(R.string.invert_in_circle)\n    }"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/AddFilterButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material.icons.rounded.Extension\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\n\n@Composable\nfun AddFilterButton(\n    modifier: Modifier = Modifier,\n    containerColor: Color = MaterialTheme.colorScheme.mixedContainer,\n    onClick: () -> Unit,\n    onCreateTemplate: (() -> Unit)? = null\n) {\n    Row(\n        modifier = modifier,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        onCreateTemplate?.let {\n            EnhancedIconButton(\n                onClick = onCreateTemplate,\n                containerColor = MaterialTheme.colorScheme.tertiaryContainer\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Extension,\n                    contentDescription = \"extension\"\n                )\n            }\n        }\n\n        EnhancedButton(\n            containerColor = containerColor,\n            onClick = onClick\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.AutoFixHigh,\n                contentDescription = stringResource(R.string.add_filter)\n            )\n            Spacer(Modifier.width(8.dp))\n            Text(stringResource(id = R.string.add_filter))\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/CalculateBrightnessEstimate.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport android.graphics.Bitmap\nimport com.t8rin.trickle.TrickleUtils\n\ninternal fun calculateBrightnessEstimate(\n    bitmap: Bitmap,\n    pixelSpacing: Int = 1\n): Int = TrickleUtils.calculateBrightness(\n    bitmap = bitmap,\n    pixelSpacing = pixelSpacing\n)"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/CubeLutDownloadDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.TableChart\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.BasicEnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\n\n@Composable\ninternal fun CubeLutDownloadDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onDownload: () -> Unit,\n    downloadOnlyNewData: Boolean,\n    cubeLutDownloadProgress: DownloadProgress?\n) {\n    EnhancedAlertDialog(\n        visible = visible,\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.TableChart,\n                contentDescription = \"lut\"\n            )\n        },\n        title = { Text(stringResource(id = R.string.cube_lut)) },\n        text = {\n            Text(\n                stringResource(\n                    if (downloadOnlyNewData) R.string.lut_library_update_sub\n                    else R.string.lut_library_sub\n                )\n            )\n        },\n        onDismissRequest = {},\n        confirmButton = {\n            EnhancedButton(\n                onClick = onDownload\n            ) {\n                Text(stringResource(R.string.download))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    )\n\n    BasicEnhancedAlertDialog(\n        onDismissRequest = {},\n        visible = cubeLutDownloadProgress != null,\n        modifier = Modifier.fillMaxSize()\n    ) {\n        EnhancedLoadingIndicator(\n            progress = (cubeLutDownloadProgress?.currentPercent ?: 0f),\n            loaderSize = 72.dp\n        ) {\n            Column(\n                verticalArrangement = Arrangement.Center,\n                horizontalAlignment = Alignment.CenterHorizontally,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(8.dp)\n            ) {\n                Text(\n                    text = rememberHumanFileSize(cubeLutDownloadProgress?.currentTotalSize ?: 0),\n                    maxLines = 1,\n                    textAlign = TextAlign.Center,\n                    fontSize = 10.sp,\n                    lineHeight = 10.sp\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.VisibilityOff\nimport androidx.compose.material.icons.rounded.DragHandle\nimport androidx.compose.material.icons.rounded.Extension\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material.icons.rounded.MoreVert\nimport androidx.compose.material.icons.rounded.RemoveCircleOutline\nimport androidx.compose.material.icons.rounded.Visibility\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextDecoration\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedDropdownMenu\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueText\n\n@Composable\nfun <T : Any> FilterItem(\n    filter: UiFilter<T>,\n    showDragHandle: Boolean,\n    onRemove: () -> Unit,\n    modifier: Modifier = Modifier,\n    onLongPress: (() -> Unit)? = null,\n    previewOnly: Boolean = false,\n    onFilterChange: (value: Any) -> Unit,\n    onCreateTemplate: (() -> Unit)?,\n    backgroundColor: Color = Color.Unspecified,\n    shape: Shape = MaterialTheme.shapes.extraLarge,\n    canHide: Boolean = true\n) {\n    var isControlsExpanded by rememberSaveable {\n        mutableStateOf(true)\n    }\n\n    val isVisible = filter.isVisible\n\n    if (!canHide && !isVisible) {\n        SideEffect {\n            filter.isVisible = true\n        }\n    }\n\n    Box(\n        modifier = Modifier.then(\n            onLongPress?.let {\n                Modifier.pointerInput(Unit) {\n                    detectTapGestures(\n                        onLongPress = { it() }\n                    )\n                }\n            } ?: Modifier\n        )\n    ) {\n        Row(\n            modifier = modifier\n                .container(color = backgroundColor, shape = shape)\n                .animateContentSizeNoClip(),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Column(\n                modifier = Modifier\n                    .weight(1f)\n                    .alpha(if (previewOnly) 0.5f else 1f)\n                    .then(\n                        if (previewOnly) {\n                            Modifier\n                                .heightIn(max = 120.dp)\n                                .fadingEdges(\n                                    scrollableState = null,\n                                    isVertical = true,\n                                    length = 12.dp\n                                )\n                                .enhancedVerticalScroll(rememberScrollState())\n                        } else Modifier\n                    )\n            ) {\n                var sliderValue by remember(filter) {\n                    mutableFloatStateOf(\n                        ((filter.value as? Number)?.toFloat()) ?: 0f\n                    )\n                }\n                Row(verticalAlignment = Alignment.CenterVertically) {\n                    if (!previewOnly) {\n                        if (canHide) {\n                            Box {\n                                var showPopup by remember {\n                                    mutableStateOf(false)\n                                }\n\n                                EnhancedIconButton(\n                                    onClick = {\n                                        showPopup = true\n                                    }\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.MoreVert,\n                                        contentDescription = \"more\"\n                                    )\n                                }\n\n                                EnhancedDropdownMenu(\n                                    expanded = showPopup,\n                                    onDismissRequest = { showPopup = false },\n                                    shape = ShapeDefaults.large\n                                ) {\n                                    Column(\n                                        modifier = Modifier\n                                            .width(IntrinsicSize.Max)\n                                            .padding(horizontal = 8.dp)\n                                    ) {\n                                        EnhancedButton(\n                                            modifier = Modifier.fillMaxWidth(),\n                                            onClick = {\n                                                onRemove()\n                                                showPopup = false\n                                            },\n                                            shape = ShapeDefaults.top,\n                                            containerColor = MaterialTheme.colorScheme.secondary\n                                        ) {\n                                            Icon(\n                                                imageVector = Icons.Rounded.RemoveCircleOutline,\n                                                contentDescription = stringResource(R.string.create_template)\n                                            )\n                                            Spacer(Modifier.width(8.dp))\n                                            Text(stringResource(R.string.remove))\n                                        }\n                                        Spacer(Modifier.height(4.dp))\n                                        EnhancedButton(\n                                            modifier = Modifier.fillMaxWidth(),\n                                            onClick = {\n                                                filter.isVisible = !isVisible\n                                                onFilterChange(filter.value as Any)\n                                                showPopup = false\n                                            },\n                                            shape = onCreateTemplate?.let {\n                                                ShapeDefaults.center\n                                            } ?: ShapeDefaults.bottom,\n                                            containerColor = MaterialTheme.colorScheme.primary\n                                        ) {\n                                            Icon(\n                                                imageVector = if (isVisible) {\n                                                    Icons.Outlined.VisibilityOff\n                                                } else {\n                                                    Icons.Rounded.Visibility\n                                                },\n                                                contentDescription = stringResource(R.string.remove)\n                                            )\n                                            Spacer(Modifier.width(8.dp))\n                                            Text(\n                                                stringResource(\n                                                    if (isVisible) R.string.hide\n                                                    else R.string.show\n                                                )\n                                            )\n                                        }\n                                        onCreateTemplate?.let {\n                                            Spacer(Modifier.height(4.dp))\n                                            EnhancedButton(\n                                                modifier = Modifier.fillMaxWidth(),\n                                                onClick = {\n                                                    onCreateTemplate()\n                                                    showPopup = false\n                                                },\n                                                shape = ShapeDefaults.bottom,\n                                                containerColor = MaterialTheme.colorScheme.tertiary\n                                            ) {\n                                                Icon(\n                                                    imageVector = Icons.Rounded.Extension,\n                                                    contentDescription = stringResource(R.string.remove)\n                                                )\n                                                Spacer(Modifier.width(8.dp))\n                                                Text(stringResource(R.string.create_template))\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        } else {\n                            EnhancedIconButton(\n                                onClick = onRemove\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.RemoveCircleOutline,\n                                    contentDescription = stringResource(R.string.remove)\n                                )\n                            }\n                        }\n                    }\n                    Row(\n                        modifier = Modifier.weight(1f),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        Text(\n                            text = stringResource(filter.title),\n                            fontWeight = FontWeight.SemiBold,\n                            modifier = Modifier\n                                .alpha(\n                                    animateFloatAsState(if (isVisible) 1f else 0.5f).value\n                                )\n                                .padding(\n                                    top = 8.dp,\n                                    end = 8.dp,\n                                    start = 16.dp,\n                                    bottom = 8.dp\n                                )\n                                .fillMaxWidth(),\n                            textDecoration = if (!isVisible) {\n                                TextDecoration.LineThrough\n                            } else null\n                        )\n                    }\n                    if (!filter.value.isSingle() && !previewOnly) {\n                        EnhancedIconButton(\n                            onClick = {\n                                isControlsExpanded = !isControlsExpanded\n                            }\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.KeyboardArrowDown,\n                                contentDescription = \"Expand\",\n                                modifier = Modifier.rotate(\n                                    animateFloatAsState(\n                                        if (isControlsExpanded) 180f\n                                        else 0f\n                                    ).value\n                                )\n                            )\n                        }\n                    }\n                    if (filter.value is Number) {\n                        var showValueDialog by remember { mutableStateOf(false) }\n                        ValueText(\n                            value = sliderValue,\n                            onClick = { showValueDialog = true }\n                        )\n                        ValueDialog(\n                            roundTo = filter.paramsInfo[0].roundTo,\n                            valueRange = filter.paramsInfo[0].valueRange,\n                            valueState = sliderValue.toString(),\n                            expanded = showValueDialog && !previewOnly,\n                            onDismiss = { showValueDialog = false },\n                            onValueUpdate = {\n                                sliderValue = it\n                                onFilterChange(it)\n                            }\n                        )\n                    }\n                }\n                AnimatedVisibility(\n                    visible = isControlsExpanded || filter.value.isSingle() || previewOnly\n                ) {\n                    FilterItemContent(\n                        filter = filter,\n                        onFilterChange = onFilterChange,\n                        previewOnly = previewOnly\n                    )\n                }\n            }\n            if (showDragHandle) {\n                Box(\n                    modifier = Modifier\n                        .height(if (filter.value is Unit) 32.dp else 64.dp)\n                        .width(1.dp)\n                        .background(MaterialTheme.colorScheme.outlineVariant())\n                        .padding(start = 20.dp)\n                )\n                Spacer(Modifier.width(8.dp))\n                Icon(\n                    imageVector = Icons.Rounded.DragHandle,\n                    contentDescription = stringResource(R.string.drag_handle_width),\n                    modifier = Modifier\n                        .size(48.dp)\n                        .padding(12.dp)\n                )\n                Spacer(Modifier.width(8.dp))\n            }\n        }\n        if (previewOnly) {\n            Surface(\n                color = Color.Transparent,\n                modifier = modifier.matchParentSize()\n            ) {}\n        }\n    }\n}\n\nprivate fun Any?.isSingle(): Boolean = this is Number || this is Unit"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterItemContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.cast\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterValueWrapper\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PolarCoordinatesType\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ArcParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.AsciiParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BilaterialBlurParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BloomParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ChannelMixParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.CropOrPerspectiveParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.EnhancedZoomBlurParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.GlitchParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.KaleidoscopeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearGaussianParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.PinchParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RadialTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RubberStampParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SideFadeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SmearParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SparkleParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ToneCurvesParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.WaterParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.translatedName\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.ArcParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.AsciiParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.BilaterialBlurParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.BloomParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.BooleanItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.ChannelMixParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.ClaheParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.CropOrPerspectiveParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.EnhancedZoomBlurParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.FilterValueWrapperItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.FloatArrayItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.FloatItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.GlitchParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.IntegerSizeParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.KaleidoscopeParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.LinearGaussianParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.LinearTiltShiftParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.PairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.PinchParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.QuadItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.RadialTiltShiftParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.RubberStampParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.SideFadeRelativeItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.SmearParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.SparkleParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.ToneCurvesParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.TripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.VoronoiCrystallizeParamsItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.WaterParamsItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\n\n@Composable\ninternal fun <T : Any> FilterItemContent(\n    filter: UiFilter<T>,\n    onFilterChange: (value: Any) -> Unit,\n    modifier: Modifier = Modifier,\n    previewOnly: Boolean = false,\n) {\n    Column(\n        modifier = modifier\n    ) {\n        when (val value = filter.value) {\n            is FilterValueWrapper<*> -> {\n                FilterValueWrapperItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is FloatArray -> {\n                FloatArrayItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is Float -> {\n                FloatItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is Boolean -> {\n                BooleanItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is PolarCoordinatesType -> {\n                EnhancedButtonGroup(\n                    inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                    items = PolarCoordinatesType.entries.map { it.translatedName },\n                    selectedIndex = PolarCoordinatesType.entries.indexOf(value),\n                    onIndexChange = {\n                        onFilterChange(PolarCoordinatesType.entries[it])\n                    }\n                )\n            }\n\n            is Pair<*, *> -> {\n                PairItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is Triple<*, *, *> -> {\n                TripleItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is Quad<*, *, *, *> -> {\n                QuadItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is RadialTiltShiftParams -> {\n                RadialTiltShiftParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is LinearTiltShiftParams -> {\n                LinearTiltShiftParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is GlitchParams -> {\n                GlitchParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is SideFadeParams.Relative -> {\n                SideFadeRelativeItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is WaterParams -> {\n                WaterParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is EnhancedZoomBlurParams -> {\n                EnhancedZoomBlurParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is ClaheParams -> {\n                ClaheParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is LinearGaussianParams -> {\n                LinearGaussianParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is ToneCurvesParams -> {\n                ToneCurvesParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is BilaterialBlurParams -> {\n                BilaterialBlurParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is KaleidoscopeParams -> {\n                KaleidoscopeParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is ChannelMixParams -> {\n                ChannelMixParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is VoronoiCrystallizeParams -> {\n                VoronoiCrystallizeParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is PinchParams -> {\n                PinchParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is RubberStampParams -> {\n                RubberStampParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is SmearParams -> {\n                SmearParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is ArcParams -> {\n                ArcParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is SparkleParams -> {\n                SparkleParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is AsciiParams -> {\n                AsciiParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is CropOrPerspectiveParams -> {\n                CropOrPerspectiveParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is IntegerSize -> {\n                IntegerSizeParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n\n            is BloomParams -> {\n                BloomParamsItem(\n                    value = value,\n                    filter = filter.cast(),\n                    onFilterChange = onFilterChange,\n                    previewOnly = previewOnly\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterPreviewSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.SimplePicture\nimport com.t8rin.imagetoolbox.core.ui.widget.image.imageStickyHeader\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberAvailableHeight\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberImageState\n\n@Composable\ninternal fun FilterPreviewSheet(\n    component: AddFiltersSheetComponent,\n    onFilterPickedWithParams: (UiFilter<*>) -> Unit,\n    onVisibleChange: (Boolean) -> Unit,\n    previewBitmap: Bitmap?\n) {\n    val previewSheetData = component.previewData\n    var imageState by rememberImageState()\n    LaunchedEffect(previewSheetData) {\n        if (previewBitmap != null && previewSheetData != null) {\n            if (previewSheetData.size == 1 && previewSheetData.firstOrNull()?.value is Unit) {\n                imageState = imageState.copy(position = 2)\n            }\n            component.updatePreview(previewBitmap)\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        dragHandle = {\n            EnhancedModalSheetDragHandle(\n                showDragHandle = false\n            ) {\n                EnhancedTopAppBar(\n                    type = EnhancedTopAppBarType.Center,\n                    drawHorizontalStroke = false,\n                    navigationIcon = {\n                        EnhancedIconButton(\n                            onClick = {\n                                component.setPreviewData(null)\n                            }\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Close,\n                                contentDescription = stringResource(R.string.close)\n                            )\n                        }\n                    },\n                    colors = EnhancedTopAppBarDefaults.colors(\n                        containerColor = EnhancedBottomSheetDefaults.barContainerColor\n                    ),\n                    actions = {\n                        EnhancedIconButton(\n                            onClick = {\n                                previewSheetData?.forEach { filter ->\n                                    onFilterPickedWithParams(\n                                        filter.copy(filter.value).also {\n                                            it.isVisible = true\n                                        }\n                                    )\n                                }\n                                component.setPreviewData(null)\n                                onVisibleChange(false)\n                            }\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Done,\n                                contentDescription = \"Done\"\n                            )\n                        }\n                    },\n                    title = {\n                        Text(\n                            text = stringResource(\n                                id = previewSheetData?.let {\n                                    if (it.size == 1) it.first().title\n                                    else R.string.filter_preview\n                                } ?: R.string.filter_preview\n                            ),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n            }\n        },\n        sheetContent = {\n            val backgroundColor = MaterialTheme.colorScheme.surfaceContainerLow\n\n            DisposableEffect(Unit) {\n                onDispose {\n                    imageState = imageState.copy(position = 2)\n                }\n            }\n            Column(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                val imageBlock = @Composable {\n                    AnimatedContent(\n                        targetState = component.previewBitmap == null,\n                        transitionSpec = { fadeIn() togetherWith fadeOut() }\n                    ) { isNull ->\n                        if (isNull) {\n                            Box(\n                                modifier = if (component.previewBitmap == null) {\n                                    Modifier\n                                        .aspectRatio(\n                                            previewBitmap?.safeAspectRatio ?: (1 / 2f)\n                                        )\n                                        .clip(ShapeDefaults.mini)\n                                        .shimmer(true)\n                                } else Modifier\n                            )\n                        } else {\n                            SimplePicture(\n                                bitmap = component.previewBitmap,\n                                loading = component.isImageLoading,\n                                modifier = Modifier\n                            )\n                        }\n                    }\n                }\n                val isPortrait by isPortraitOrientationAsState()\n\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.Center,\n                ) {\n                    val isUnit =\n                        previewSheetData?.size == 1 && previewSheetData.firstOrNull()?.value is Unit\n                    if (!isPortrait) {\n                        Box(\n                            modifier = Modifier\n                                .container(RectangleShape)\n                                .weight(1.2f)\n                                .padding(20.dp)\n                        ) {\n                            Box(Modifier.align(Alignment.Center)) {\n                                imageBlock()\n                            }\n                        }\n                    }\n\n                    val internalHeight = rememberAvailableHeight(imageState = imageState)\n                    LazyColumn(\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        modifier = Modifier\n                            .then(\n                                if (!isPortrait && !isUnit) Modifier.weight(1f)\n                                else Modifier\n                            )\n                            .clipToBounds(),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        imageStickyHeader(\n                            visible = isPortrait,\n                            imageState = imageState,\n                            internalHeight = internalHeight,\n                            onStateChange = { imageState = it },\n                            imageBlock = imageBlock,\n                            backgroundColor = backgroundColor\n                        )\n                        item {\n                            previewSheetData?.takeIf { !isUnit }?.let { list ->\n                                list.forEachIndexed { index, filter ->\n                                    FilterItem(\n                                        backgroundColor = MaterialTheme\n                                            .colorScheme\n                                            .surface,\n                                        modifier = Modifier.padding(horizontal = 16.dp),\n                                        filter = filter,\n                                        showDragHandle = false,\n                                        onRemove = {\n                                            if (list.size == 1) {\n                                                component.setPreviewData(null)\n                                            } else component.removeFilterAtIndex(index)\n                                        },\n                                        onCreateTemplate = null,\n                                        onFilterChange = { value ->\n                                            component.updateFilter(value, index)\n                                        }\n                                    )\n                                    if (index != list.lastIndex) {\n                                        Spacer(Modifier.height(8.dp))\n                                    }\n                                }\n                                Spacer(Modifier.height(16.dp))\n                            }\n                            Spacer(\n                                Modifier.height(\n                                    WindowInsets\n                                        .navigationBars\n                                        .asPaddingValues()\n                                        .calculateBottomPadding()\n                                )\n                            )\n                        }\n                    }\n                }\n            }\n        },\n        visible = previewSheetData != null,\n        onDismiss = {\n            if (!it) {\n                component.setPreviewData(null)\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterReorderSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Reorder\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\n\n@Composable\nfun FilterReorderSheet(\n    filterList: List<UiFilter<*>>,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onReorder: (List<UiFilter<*>>) -> Unit\n) {\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            if (filterList.size < 2) onDismiss()\n\n            Box {\n                val data = remember { mutableStateOf(filterList) }\n                val listState = rememberLazyListState()\n                val haptics = LocalHapticFeedback.current\n                val state = rememberReorderableLazyListState(\n                    onMove = { from, to ->\n                        haptics.press()\n                        data.value = data.value.toMutableList().apply {\n                            add(to.index, removeAt(from.index))\n                        }\n                    },\n                    lazyListState = listState\n                )\n                LazyColumn(\n                    state = listState,\n                    contentPadding = PaddingValues(16.dp),\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    itemsIndexed(\n                        items = data.value,\n                        key = { _, v -> v.hashCode() }\n                    ) { index, filter ->\n                        ReorderableItem(\n                            state = state,\n                            key = filter.hashCode()\n                        ) { isDragging ->\n                            FilterItem(\n                                filter = filter,\n                                onFilterChange = {},\n                                modifier = Modifier\n                                    .longPressDraggableHandle(\n                                        onDragStarted = {\n                                            haptics.longPress()\n                                        },\n                                        onDragStopped = {\n                                            onReorder(data.value)\n                                        }\n                                    )\n                                    .scale(\n                                        animateFloatAsState(\n                                            if (isDragging) 1.05f\n                                            else 1f\n                                        ).value\n                                    ),\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = data.value.size\n                                ),\n                                previewOnly = true,\n                                showDragHandle = filterList.size >= 2,\n                                onRemove = {},\n                                onCreateTemplate = null\n                            )\n                        }\n                    }\n                }\n            }\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.reorder),\n                icon = Icons.Rounded.Reorder\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterSelectionCubeLutBottomContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Download\nimport androidx.compose.material.icons.rounded.Search\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material.icons.rounded.TableChart\nimport androidx.compose.material.icons.rounded.Update\nimport androidx.compose.material.icons.rounded.Visibility\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport coil3.request.ImageRequest\nimport coil3.request.error\nimport coil3.request.transformations\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResources\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiCubeLutFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\ninternal fun FilterSelectionCubeLutBottomContent(\n    cubeLutRemoteResources: RemoteResources?,\n    shape: Shape,\n    onShowDownloadDialog: (\n        forceUpdate: Boolean,\n        downloadOnlyNewData: Boolean\n    ) -> Unit,\n    onRequestFilterMapping: ((UiFilter<*>) -> Transformation),\n    onClick: (UiCubeLutFilter) -> Unit\n) {\n    cubeLutRemoteResources?.let { resources ->\n        val previewModel = LocalFilterPreviewModelProvider.current.preview\n\n        var showSelection by rememberSaveable {\n            mutableStateOf(false)\n        }\n\n        Row(\n            modifier = Modifier\n                .padding(\n                    start = 8.dp,\n                    end = 8.dp,\n                    bottom = 8.dp\n                )\n                .container(\n                    color = MaterialTheme.colorScheme.surface,\n                    resultPadding = 0.dp,\n                    shape = shape\n                )\n                .hapticsClickable {\n                    if (resources.list.isEmpty()) {\n                        onShowDownloadDialog(false, false)\n                    } else {\n                        showSelection = true\n                    }\n                }\n                .padding(8.dp),\n            verticalAlignment = Alignment.CenterVertically,\n        ) {\n            TitleItem(\n                text = stringResource(R.string.lut_library),\n                modifier = Modifier\n                    .padding(start = 8.dp)\n                    .weight(1f)\n            )\n            Spacer(Modifier.width(8.dp))\n            EnhancedIconButton(\n                onClick = {\n                    onShowDownloadDialog(true, false)\n                },\n                containerColor = if (resources.list.isEmpty()) {\n                    MaterialTheme.colorScheme.secondary\n                } else Color.Transparent\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Download,\n                    contentDescription = null\n                )\n            }\n            if (resources.list.isNotEmpty()) {\n                EnhancedIconButton(\n                    onClick = {\n                        onShowDownloadDialog(true, true)\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.Update,\n                        contentDescription = null\n                    )\n                }\n                EnhancedIconButton(\n                    containerColor = MaterialTheme.colorScheme.secondary,\n                    onClick = {\n                        showSelection = true\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.Visibility,\n                        contentDescription = \"View\"\n                    )\n                }\n            }\n        }\n\n        var isSearching by rememberSaveable {\n            mutableStateOf(false)\n        }\n        var searchKeyword by rememberSaveable(isSearching) {\n            mutableStateOf(\"\")\n        }\n        EnhancedModalBottomSheet(\n            visible = showSelection,\n            onDismiss = { showSelection = it },\n            confirmButton = {},\n            enableBottomContentWeight = false,\n            title = {\n                AnimatedContent(\n                    targetState = isSearching\n                ) { searching ->\n                    if (searching) {\n                        BackHandler {\n                            searchKeyword = \"\"\n                            isSearching = false\n                        }\n                        ProvideTextStyle(value = MaterialTheme.typography.bodyLarge) {\n                            RoundedTextField(\n                                maxLines = 1,\n                                hint = { Text(stringResource(id = R.string.search_here)) },\n                                keyboardOptions = KeyboardOptions.Default.copy(\n                                    imeAction = ImeAction.Search,\n                                    autoCorrectEnabled = null\n                                ),\n                                value = searchKeyword,\n                                onValueChange = {\n                                    searchKeyword = it\n                                },\n                                startIcon = {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            searchKeyword = \"\"\n                                            isSearching = false\n                                        },\n                                        modifier = Modifier.padding(start = 4.dp)\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                            contentDescription = stringResource(R.string.exit),\n                                            tint = MaterialTheme.colorScheme.onSurface\n                                        )\n                                    }\n                                },\n                                endIcon = {\n                                    AnimatedVisibility(\n                                        visible = searchKeyword.isNotEmpty(),\n                                        enter = fadeIn() + scaleIn(),\n                                        exit = fadeOut() + scaleOut()\n                                    ) {\n                                        EnhancedIconButton(\n                                            onClick = {\n                                                searchKeyword = \"\"\n                                            },\n                                            modifier = Modifier.padding(end = 4.dp)\n                                        ) {\n                                            Icon(\n                                                imageVector = Icons.Rounded.Close,\n                                                contentDescription = stringResource(R.string.close),\n                                                tint = MaterialTheme.colorScheme.onSurface\n                                            )\n                                        }\n                                    }\n                                },\n                                shape = ShapeDefaults.circle\n                            )\n                        }\n                    } else {\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically\n                        ) {\n                            TitleItem(\n                                text = stringResource(R.string.lut_library),\n                                icon = Icons.Rounded.TableChart\n                            )\n                            Spacer(modifier = Modifier.weight(1f))\n                            EnhancedIconButton(\n                                onClick = { isSearching = true },\n                                containerColor = MaterialTheme.colorScheme.tertiaryContainer\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Search,\n                                    contentDescription = stringResource(R.string.search_here)\n                                )\n                            }\n                            EnhancedButton(\n                                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                                onClick = { showSelection = false }\n                            ) {\n                                AutoSizeText(stringResource(R.string.close))\n                            }\n                            Spacer(Modifier.width(8.dp))\n                        }\n                    }\n                }\n            }\n        ) {\n            val data by remember(resources.list, searchKeyword) {\n                derivedStateOf {\n                    if (searchKeyword.isEmpty()) resources.list\n                    else resources.list.filter {\n                        it.name.trim()\n                            .contains(searchKeyword.trim(), true)\n                    }\n                }\n            }\n            AnimatedContent(data.isNotEmpty()) { haveData ->\n                if (haveData) {\n                    LazyColumn(\n                        verticalArrangement = Arrangement.spacedBy(4.dp),\n                        contentPadding = PaddingValues(8.dp),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        itemsIndexed(\n                            items = data,\n                            key = { _, d -> d.name + d.uri }\n                        ) { index, (uri, name) ->\n                            PreferenceItemOverload(\n                                title = remember(name) {\n                                    name.removeSuffix(\".cube\")\n                                        .removeSuffix(\"_LUT\")\n                                        .replace(\"_\", \" \")\n                                },\n                                drawStartIconContainer = false,\n                                startIcon = {\n                                    Row(\n                                        verticalAlignment = Alignment.CenterVertically\n                                    ) {\n                                        Picture(\n                                            model = remember(uri, previewModel) {\n                                                ImageRequest.Builder(appContext)\n                                                    .data(previewModel.data)\n                                                    .error(R.drawable.filter_preview_source)\n                                                    .transformations(\n                                                        onRequestFilterMapping(\n                                                            UiCubeLutFilter(\n                                                                1f to FileModel(uri)\n                                                            )\n                                                        )\n                                                    )\n                                                    .diskCacheKey(uri + previewModel.data.hashCode())\n                                                    .memoryCacheKey(uri + previewModel.data.hashCode())\n                                                    .size(300, 300)\n                                                    .build()\n                                            },\n                                            shape = MaterialTheme.shapes.medium,\n                                            contentScale = ContentScale.Crop,\n                                            modifier = Modifier\n                                                .size(48.dp)\n                                                .scale(1.2f)\n                                        )\n                                        Spacer(Modifier.width(16.dp))\n                                        Box(\n                                            modifier = Modifier\n                                                .height(36.dp)\n                                                .width(1.dp)\n                                                .background(MaterialTheme.colorScheme.outlineVariant())\n                                        )\n                                    }\n                                },\n                                onClick = {\n                                    showSelection = false\n                                    onClick(\n                                        UiCubeLutFilter(1f to FileModel(uri))\n                                    )\n                                },\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = data.size\n                                ),\n                                modifier = Modifier\n                                    .fillMaxWidth()\n                                    .animateItem()\n                            )\n                        }\n                    }\n                } else {\n                    Column(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .fillMaxHeight(0.5f),\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        Spacer(Modifier.weight(1f))\n                        Text(\n                            text = stringResource(R.string.nothing_found_by_search),\n                            fontSize = 18.sp,\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier.padding(\n                                start = 24.dp,\n                                end = 24.dp,\n                                top = 8.dp,\n                                bottom = 8.dp\n                            )\n                        )\n                        Icon(\n                            imageVector = Icons.Rounded.SearchOff,\n                            contentDescription = null,\n                            modifier = Modifier\n                                .weight(2f)\n                                .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                                .fillMaxSize()\n                        )\n                        Spacer(Modifier.weight(1f))\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterSelectionItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.SignalCellularConnectedNoInternet0Bar\nimport androidx.compose.material.icons.rounded.Bookmark\nimport androidx.compose.material.icons.rounded.BookmarkBorder\nimport androidx.compose.material.icons.rounded.Slideshow\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.request.ImageRequest\nimport coil3.request.error\nimport coil3.request.transformations\nimport coil3.toBitmap\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResources\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BookmarkRemove\nimport com.t8rin.imagetoolbox.core.ui.theme.StrongBlack\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isNetworkAvailable\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun FilterSelectionItem(\n    filter: UiFilter<*>,\n    isFavoritePage: Boolean,\n    canOpenPreview: Boolean,\n    favoriteFilters: List<UiFilter<*>>,\n    onLongClick: (() -> Unit)?,\n    onOpenPreview: () -> Unit,\n    onClick: (UiFilter<*>?) -> Unit,\n    onToggleFavorite: () -> Unit,\n    onRequestFilterMapping: ((UiFilter<*>) -> Transformation),\n    shape: Shape,\n    modifier: Modifier,\n    cubeLutRemoteResources: RemoteResources? = null,\n    cubeLutDownloadProgress: DownloadProgress? = null,\n    onCubeLutDownloadRequest: (forceUpdate: Boolean, downloadOnlyNewData: Boolean) -> Unit = { _, _ -> }\n) {\n    val previewModel = LocalFilterPreviewModelProvider.current.preview\n\n    var isBitmapDark by remember {\n        mutableStateOf(true)\n    }\n    var loading by remember {\n        mutableStateOf(false)\n    }\n\n    var showDownloadDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    var downloadOnlyNewData by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    var forceUpdate by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItemOverload(\n        title = stringResource(filter.title),\n        startIcon = {\n            val scope = rememberCoroutineScope()\n            Row(verticalAlignment = Alignment.CenterVertically) {\n                Box(contentAlignment = Alignment.Center) {\n                    Picture(\n                        model = remember(filter, previewModel) {\n                            ImageRequest.Builder(appContext)\n                                .data(previewModel.data)\n                                .error(R.drawable.filter_preview_source)\n                                .transformations(onRequestFilterMapping(filter))\n                                .diskCacheKey(filter::class.simpleName + previewModel.data.hashCode())\n                                .memoryCacheKey(filter::class.simpleName + previewModel.data.hashCode())\n                                .size(300, 300)\n                                .build()\n                        },\n                        contentScale = ContentScale.Crop,\n                        contentDescription = null,\n                        onLoading = {\n                            loading = true\n                        },\n                        onSuccess = {\n                            loading = false\n                            scope.launch {\n                                isBitmapDark =\n                                    calculateBrightnessEstimate(it.result.image.toBitmap()) < 110\n                            }\n                        },\n                        modifier = Modifier\n                            .size(48.dp)\n                            .scale(1.2f)\n                            .clip(MaterialTheme.shapes.medium)\n                            .transparencyChecker()\n                            .shimmer(loading)\n                    )\n                    if (canOpenPreview) {\n                        Box(\n                            modifier = Modifier\n                                .size(36.dp)\n                                .clip(ShapeDefaults.circle)\n                                .hapticsClickable(onClick = onOpenPreview),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Slideshow,\n                                contentDescription = stringResource(R.string.image_preview),\n                                tint = if (isBitmapDark) StrongBlack\n                                else White,\n                                modifier = Modifier.scale(1.2f)\n                            )\n                            Icon(\n                                imageVector = Icons.Rounded.Slideshow,\n                                contentDescription = stringResource(R.string.image_preview),\n                                tint = if (isBitmapDark) White\n                                else StrongBlack\n                            )\n                        }\n                    }\n                }\n                Spacer(Modifier.width(16.dp))\n                Box(\n                    modifier = Modifier\n                        .height(36.dp)\n                        .width(1.dp)\n                        .background(MaterialTheme.colorScheme.outlineVariant())\n                )\n            }\n        },\n        endIcon = {\n            EnhancedIconButton(\n                onClick = onToggleFavorite,\n                modifier = Modifier.offset(8.dp)\n            ) {\n                val inFavorite by remember(favoriteFilters, filter) {\n                    derivedStateOf {\n                        favoriteFilters.filterIsInstance(filter::class.java).isNotEmpty()\n                    }\n                }\n                AnimatedContent(\n                    targetState = inFavorite to isFavoritePage,\n                    transitionSpec = {\n                        (fadeIn() + scaleIn(initialScale = 0.85f))\n                            .togetherWith(fadeOut() + scaleOut(targetScale = 0.85f))\n                    }\n                ) { (isInFavorite, isFavPage) ->\n                    val icon by remember(isInFavorite, isFavPage) {\n                        derivedStateOf {\n                            when {\n                                isFavPage && isInFavorite -> Icons.Rounded.BookmarkRemove\n                                isInFavorite -> Icons.Rounded.Bookmark\n                                else -> Icons.Rounded.BookmarkBorder\n                            }\n                        }\n                    }\n                    Icon(\n                        imageVector = icon,\n                        contentDescription = null\n                    )\n                }\n            }\n        },\n        modifier = modifier.fillMaxWidth(),\n        shape = shape,\n        onLongClick = onLongClick,\n        onClick = { onClick(null) },\n        drawStartIconContainer = false,\n        bottomContent = {\n            FilterSelectionCubeLutBottomContent(\n                cubeLutRemoteResources = cubeLutRemoteResources,\n                shape = shape,\n                onShowDownloadDialog = { forceUpdateP, downloadOnlyNewDataP ->\n                    showDownloadDialog = true\n                    forceUpdate = forceUpdateP\n                    downloadOnlyNewData = downloadOnlyNewDataP\n                },\n                onRequestFilterMapping = onRequestFilterMapping,\n                onClick = onClick\n            )\n        }\n    )\n\n    CubeLutDownloadDialog(\n        visible = showDownloadDialog,\n        onDismiss = { showDownloadDialog = false },\n        onDownload = {\n            if (appContext.isNetworkAvailable()) {\n                onCubeLutDownloadRequest(\n                    forceUpdate, downloadOnlyNewData\n                )\n                showDownloadDialog = false\n            } else {\n                AppToastHost.showToast(\n                    message = getString(R.string.no_connection),\n                    icon = Icons.Outlined.SignalCellularConnectedNoInternet0Bar,\n                    duration = ToastDuration.Long\n                )\n            }\n        },\n        downloadOnlyNewData = downloadOnlyNewData,\n        cubeLutDownloadProgress = cubeLutDownloadProgress\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterTemplateAddingGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport android.annotation.SuppressLint\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.AutoFixHigh\nimport androidx.compose.material.icons.outlined.FileOpen\nimport androidx.compose.material.icons.rounded.QrCodeScanner\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberBarcodeScanner\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\n\n@SuppressLint(\"StringFormatInvalid\")\n@Composable\ninternal fun FilterTemplateAddingGroup(\n    component: FilterTemplateCreationSheetComponent,\n    onAddTemplateFilterFromString: (\n        string: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    ) -> Unit,\n    onAddTemplateFilterFromUri: (\n        uri: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    ) -> Unit\n) {\n    val context = LocalResourceManager.current\n\n    fun addTemplateFilterFromString(\n        string: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    ) = onAddTemplateFilterFromString(string, onSuccess, onFailure)\n\n    fun addTemplateFilterFromUri(\n        uri: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    ) = onAddTemplateFilterFromUri(uri, onSuccess, onFailure)\n\n    val scanner = rememberBarcodeScanner {\n        addTemplateFilterFromString(\n            string = it.raw,\n            onSuccess = { filterName, filtersCount ->\n                AppToastHost.showToast(\n                    message = context.getString(\n                        R.string.added_filter_template,\n                        filterName,\n                        filtersCount\n                    ),\n                    icon = Icons.Outlined.AutoFixHigh\n                )\n            },\n            onFailure = {\n                AppToastHost.showToast(\n                    message = context.getString(R.string.scanned_qr_code_isnt_filter_template),\n                    icon = Icons.Rounded.QrCodeScanner\n                )\n            }\n        )\n    }\n\n    val importFromFileLauncher = rememberFilePicker { uri: Uri ->\n        addTemplateFilterFromUri(\n            uri = uri.toString(),\n            onSuccess = { filterName, filtersCount ->\n                AppToastHost.showToast(\n                    message = context.getString(\n                        R.string.added_filter_template,\n                        filterName,\n                        filtersCount\n                    ),\n                    icon = Icons.Outlined.AutoFixHigh\n                )\n            },\n            onFailure = {\n                AppToastHost.showToast(\n                    message = context.getString(R.string.opened_file_have_no_filter_template),\n                    icon = Icons.Outlined.AutoFixHigh\n                )\n            }\n        )\n    }\n\n    var showFilterTemplateCreationSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    Row(\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.Center,\n        modifier = Modifier\n            .padding(top = 16.dp)\n            .fillMaxWidth()\n    ) {\n        EnhancedIconButton(\n            onClick = scanner::scan,\n            containerColor = MaterialTheme.colorScheme.tertiary\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.QrCodeScanner,\n                contentDescription = \"Scan QR\"\n            )\n        }\n        EnhancedIconButton(\n            onClick = importFromFileLauncher::pickFile,\n            containerColor = MaterialTheme.colorScheme.secondary\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.FileOpen,\n                contentDescription = \"Import From File\"\n            )\n        }\n        Spacer(modifier = Modifier.width(8.dp))\n        EnhancedButton(\n            onClick = { showFilterTemplateCreationSheet = true },\n            containerColor = MaterialTheme.colorScheme.primary\n        ) {\n            Text(stringResource(R.string.create_new))\n        }\n    }\n\n    FilterTemplateCreationSheet(\n        visible = showFilterTemplateCreationSheet,\n        onDismiss = { showFilterTemplateCreationSheet = false },\n        component = component\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterTemplateCreationSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.outlined.Extension\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.childContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterParamsInteractor\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageHeaderState\nimport com.t8rin.imagetoolbox.core.ui.widget.image.SimplePicture\nimport com.t8rin.imagetoolbox.core.ui.widget.image.imageStickyHeader\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.CornerSides\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.only\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberAvailableHeight\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\n\n@Composable\nfun FilterTemplateCreationSheet(\n    component: FilterTemplateCreationSheetComponent,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    initialTemplateFilter: TemplateFilter? = null\n) {\n    val previewModel = LocalFilterPreviewModelProvider.current.preview\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showAddFilterSheet by rememberSaveable { mutableStateOf(false) }\n\n    var showExitDialog by remember { mutableStateOf(false) }\n\n    var showReorderSheet by rememberSaveable { mutableStateOf(false) }\n\n    val canSave = component.filterList.isNotEmpty()\n\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!canSave) onDismiss()\n            else showExitDialog = true\n        },\n        cancelable = false,\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.create_template),\n                icon = Icons.Outlined.Extension\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                enabled = canSave && component.templateName.isNotEmpty(),\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    component.saveTemplate(initialTemplateFilter)\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(id = R.string.save))\n            }\n        },\n        dragHandle = {\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .drawHorizontalStroke(autoElevation = 3.dp)\n                    .zIndex(Float.MAX_VALUE)\n                    .background(EnhancedBottomSheetDefaults.barContainerColor)\n                    .padding(8.dp)\n            ) {\n                EnhancedIconButton(\n                    onClick = {\n                        if (!canSave) onDismiss()\n                        else showExitDialog = true\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                        contentDescription = stringResource(R.string.exit)\n                    )\n                }\n            }\n        },\n        enableBackHandler = !canSave\n    ) {\n        component.AttachLifecycle()\n\n        var imageState by remember { mutableStateOf(ImageHeaderState(2)) }\n\n        var selectedUri by rememberSaveable {\n            mutableStateOf<Uri?>(null)\n        }\n\n        LaunchedEffect(selectedUri) {\n            component.setUri(selectedUri)\n        }\n\n        LaunchedEffect(initialTemplateFilter) {\n            initialTemplateFilter?.let {\n                component.setInitialTemplateFilter(it)\n            }\n        }\n\n        if (visible) {\n            BackHandler(enabled = canSave) {\n                showExitDialog = true\n            }\n        }\n        val preview: @Composable () -> Unit = {\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .clip(\n                        if (isPortrait) ShapeDefaults.extraLarge.only(CornerSides.Bottom)\n                        else RectangleShape\n                    )\n                    .background(\n                        color = MaterialTheme.colorScheme\n                            .surfaceContainer\n                            .copy(0.8f)\n                    )\n                    .shimmer(component.previewBitmap == null && component.isImageLoading),\n                contentAlignment = Alignment.Center\n            ) {\n                SimplePicture(\n                    enableContainer = false,\n                    boxModifier = Modifier.padding(24.dp),\n                    bitmap = component.previewBitmap,\n                    loading = component.isImageLoading\n                )\n            }\n        }\n        Row {\n            val backgroundColor = MaterialTheme.colorScheme.surfaceContainerLow\n            if (!isPortrait) {\n                Box(modifier = Modifier.weight(1.3f)) {\n                    preview()\n                }\n            }\n            val internalHeight = rememberAvailableHeight(imageState = imageState)\n            LazyColumn(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                modifier = Modifier.weight(1f),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                imageStickyHeader(\n                    visible = isPortrait,\n                    internalHeight = internalHeight,\n                    imageState = imageState,\n                    onStateChange = {\n                        imageState = it\n                    },\n                    padding = 0.dp,\n                    backgroundColor = backgroundColor,\n                    imageBlock = preview\n                )\n                item {\n                    AnimatedContent(\n                        targetState = component.filterList.isNotEmpty(),\n                        transitionSpec = {\n                            fadeIn() + expandVertically() togetherWith fadeOut() + shrinkVertically()\n                        }\n                    ) { notEmpty ->\n                        Column(\n                            modifier = Modifier.padding(horizontal = 16.dp),\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            Spacer(Modifier.height(16.dp))\n                            ImageSelector(\n                                value = selectedUri ?: previewModel.data,\n                                onValueChange = { selectedUri = it },\n                                subtitle = stringResource(id = R.string.select_template_preview),\n                                shape = ShapeDefaults.default,\n                                color = Color.Unspecified\n                            )\n                            Spacer(Modifier.height(8.dp))\n                            RoundedTextField(\n                                modifier = Modifier\n                                    .container(\n                                        shape = MaterialTheme.shapes.large,\n                                        resultPadding = 8.dp\n                                    ),\n                                keyboardOptions = KeyboardOptions(\n                                    keyboardType = KeyboardType.Text\n                                ),\n                                onValueChange = component::updateTemplateName,\n                                value = component.templateName,\n                                label = stringResource(R.string.template_name)\n                            )\n                            if (notEmpty) {\n                                Spacer(Modifier.height(8.dp))\n                                Column(\n                                    modifier = Modifier\n                                        .container(MaterialTheme.shapes.extraLarge)\n                                ) {\n                                    TitleItem(text = stringResource(R.string.filters))\n                                    Column(\n                                        horizontalAlignment = Alignment.CenterHorizontally,\n                                        verticalArrangement = Arrangement.spacedBy(8.dp),\n                                        modifier = Modifier.padding(8.dp)\n                                    ) {\n                                        component.filterList.forEachIndexed { index, filter ->\n                                            FilterItem(\n                                                backgroundColor = MaterialTheme.colorScheme.surface,\n                                                filter = filter,\n                                                onFilterChange = {\n                                                    component.updateFilter(\n                                                        value = it,\n                                                        index = index,\n                                                        showError = AppToastHost::showFailureToast\n                                                    )\n                                                },\n                                                onLongPress = {\n                                                    showReorderSheet = true\n                                                },\n                                                showDragHandle = false,\n                                                onRemove = {\n                                                    component.removeFilterAtIndex(\n                                                        index\n                                                    )\n                                                },\n                                                onCreateTemplate = null\n                                            )\n                                        }\n                                        AddFilterButton(\n                                            onClick = {\n                                                showAddFilterSheet = true\n                                            },\n                                            modifier = Modifier.padding(\n                                                horizontal = 16.dp\n                                            )\n                                        )\n                                    }\n                                }\n                                Spacer(Modifier.height(16.dp))\n                            } else {\n                                Spacer(Modifier.height(8.dp))\n                                AddFilterButton(\n                                    onClick = {\n                                        showAddFilterSheet = true\n                                    }\n                                )\n                                Spacer(Modifier.height(16.dp))\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    AddFiltersSheet(\n        component = component.addFiltersSheetComponent,\n        visible = showAddFilterSheet,\n        onVisibleChange = { showAddFilterSheet = it },\n        canAddTemplates = false,\n        previewBitmap = component.previewBitmap,\n        onFilterPicked = { component.addFilter(it.newInstance()) },\n        onFilterPickedWithParams = { component.addFilter(it) },\n        filterTemplateCreationSheetComponent = component\n    )\n\n    FilterReorderSheet(\n        filterList = component.filterList,\n        visible = showReorderSheet,\n        onDismiss = {\n            showReorderSheet = false\n        },\n        onReorder = component::updateFiltersOrder\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = onDismiss,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog,\n        placeAboveAll = true\n    )\n}\n\nclass FilterTemplateCreationSheetComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val filterParamsInteractor: FilterParamsInteractor,\n    private val filterProvider: FilterProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n    addFiltersSheetComponentFactory: AddFiltersSheetComponent.Factory\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    val addFiltersSheetComponent: AddFiltersSheetComponent = addFiltersSheetComponentFactory(\n        componentContext = componentContext.childContext(\n            key = \"addFiltersTemplate\"\n        )\n    )\n\n    private val _previewModel: MutableState<ImageModel> = mutableStateOf(ImageModel(\"\"))\n\n    private val _filterList: MutableState<List<UiFilter<*>>> = mutableStateOf(emptyList())\n    val filterList by _filterList\n\n    private val _templateName: MutableState<String> = mutableStateOf(\"\")\n    val templateName by _templateName\n\n    private var bitmapUri: Uri? by mutableStateOf(null)\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap by _previewBitmap\n\n    init {\n        filterParamsInteractor\n            .getFilterPreviewModel().onEach { data ->\n                _previewModel.update { data }\n            }.launchIn(componentScope)\n    }\n\n    fun updateTemplateName(newName: String) {\n        _templateName.update { newName.filter { it.isLetter() || it.isWhitespace() }.trim() }\n    }\n\n    private fun updatePreview() {\n        debouncedImageCalculation {\n            _previewBitmap.update {\n                imageGetter.getImageWithTransformations(\n                    data = bitmapUri ?: _previewModel.value.data,\n                    transformations = filterList.map { filterProvider.filterToTransformation(it) },\n                    size = IntegerSize(1000, 1000)\n                )\n            }\n        }\n    }\n\n    fun removeFilterAtIndex(index: Int) {\n        _filterList.update {\n            it.toMutableList().apply {\n                removeAt(index)\n            }\n        }\n        updatePreview()\n    }\n\n    fun <T : Any> updateFilter(\n        value: T,\n        index: Int,\n        showError: (Throwable) -> Unit\n    ) {\n        val list = _filterList.value.toMutableList()\n        runCatching {\n            list[index] = list[index].copy(value)\n            _filterList.update { list }\n        }.exceptionOrNull()?.let { throwable ->\n            showError(throwable)\n            list[index] = list[index].newInstance()\n            _filterList.update { list }\n        }\n        updatePreview()\n    }\n\n    fun updateFiltersOrder(uiFilters: List<UiFilter<*>>) {\n        _filterList.update { uiFilters }\n        updatePreview()\n    }\n\n    fun addFilter(filter: UiFilter<*>) {\n        _filterList.update {\n            it + filter\n        }\n        updatePreview()\n    }\n\n    fun saveTemplate(initialTemplateFilter: TemplateFilter?) {\n        componentScope.launch {\n            if (initialTemplateFilter != null) {\n                filterParamsInteractor.removeTemplateFilter(initialTemplateFilter)\n            }\n            filterParamsInteractor.addTemplateFilter(\n                TemplateFilter(\n                    name = templateName,\n                    filters = filterList\n                )\n            )\n        }\n    }\n\n    fun setUri(selectedUri: Uri?) {\n        bitmapUri = selectedUri\n        updatePreview()\n    }\n\n    private var isInitialValueSetAlready: Boolean = false\n\n    fun setInitialTemplateFilter(filter: TemplateFilter) {\n        if (templateName.isEmpty() && filterList.isEmpty() && !isInitialValueSetAlready) {\n            _templateName.update { filter.name }\n            _filterList.update { filter.filters.map { it.toUiFilter() } }\n            isInitialValueSetAlready = true\n        }\n    }\n\n    override fun resetState() {\n        _filterList.update { emptyList() }\n        _templateName.update { \"\" }\n        cancelImageLoading()\n        _previewBitmap.update { null }\n        bitmapUri = null\n        isInitialValueSetAlready = false\n        addFiltersSheetComponent.resetState()\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext\n        ): FilterTemplateCreationSheetComponent\n    }\n\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/FilterTemplateInfoSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.AutoFixHigh\nimport androidx.compose.material.icons.outlined.Extension\nimport androidx.compose.material.icons.rounded.FilePresent\nimport androidx.compose.material.icons.rounded.QrCode\nimport androidx.compose.material.icons.rounded.QrCode2\nimport androidx.compose.material.icons.rounded.Save\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.min\nimport coil3.request.ImageRequest\nimport coil3.request.error\nimport coil3.request.transformations\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.EditAlt\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.capturable\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.rememberCaptureController\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCode\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun FilterTemplateInfoSheet(\n    component: FilterTemplateCreationSheetComponent,\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    templateFilter: TemplateFilter,\n    onShareImage: (Bitmap) -> Unit,\n    onSaveImage: (Bitmap) -> Unit,\n    onSaveFile: (fileUri: Uri, content: String) -> Unit,\n    onConvertTemplateFilterToString: suspend (TemplateFilter) -> String,\n    onRemoveTemplateFilter: (TemplateFilter) -> Unit,\n    onShareFile: (content: String) -> Unit,\n    onRequestTemplateFilename: () -> String,\n    onRequestFilterMapping: (UiFilter<*>) -> Transformation\n) {\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    onDismiss(false)\n                }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.template_filter),\n                icon = Icons.Outlined.Extension\n            )\n        }\n    ) {\n        var filterContent by rememberSaveable {\n            mutableStateOf(\"\")\n        }\n        LaunchedEffect(filterContent) {\n            if (filterContent.isEmpty()) {\n                filterContent = onConvertTemplateFilterToString(templateFilter)\n            }\n        }\n\n        var showShareDialog by rememberSaveable {\n            mutableStateOf(false)\n        }\n\n        var showDeleteDialog by rememberSaveable {\n            mutableStateOf(false)\n        }\n\n        var showEditTemplateSheet by rememberSaveable {\n            mutableStateOf(false)\n        }\n\n        val scope = rememberCoroutineScope()\n        val captureController = rememberCaptureController()\n\n        LazyColumn(\n            modifier = Modifier.fillMaxWidth(),\n            contentPadding = PaddingValues(16.dp),\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n            horizontalAlignment = Alignment.CenterHorizontally,\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            item {\n                Column(Modifier.capturable(captureController)) {\n                    Spacer(modifier = Modifier.height(32.dp))\n                    BoxWithConstraints(\n                        modifier = Modifier\n                            .background(\n                                color = MaterialTheme.colorScheme.surfaceContainerLowest,\n                                shape = ShapeDefaults.default\n                            )\n                            .padding(16.dp)\n                    ) {\n                        val targetSize = min(min(this.maxWidth, maxHeight), 300.dp)\n                        Column(\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            QrCode(\n                                content = filterContent,\n                                qrParams = QrCodeParams(),\n                                modifier = Modifier\n                                    .padding(top = 36.dp, bottom = 16.dp)\n                                    .size(targetSize)\n                            )\n\n                            Text(\n                                text = templateFilter.name,\n                                style = MaterialTheme.typography.headlineSmall,\n                                textAlign = TextAlign.Center,\n                                modifier = Modifier.width(targetSize)\n                            )\n                        }\n\n                        TemplateFilterPreviewItem(\n                            modifier = Modifier\n                                .align(Alignment.TopCenter)\n                                .offset(y = (-48).dp)\n                                .size(64.dp),\n                            templateFilter = templateFilter,\n                            onRequestFilterMapping = onRequestFilterMapping\n                        )\n                    }\n                }\n\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    modifier = Modifier.padding(top = 8.dp)\n                ) {\n                    EnhancedIconButton(\n                        onClick = { showDeleteDialog = true },\n                        containerColor = MaterialTheme.colorScheme.error\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Delete,\n                            contentDescription = stringResource(R.string.delete)\n                        )\n                    }\n                    EnhancedButton(\n                        onClick = { showShareDialog = true },\n                        modifier = Modifier.fillMaxWidth(0.75f)\n                    ) {\n                        Text(stringResource(R.string.share))\n                    }\n                    EnhancedIconButton(\n                        onClick = { showEditTemplateSheet = true },\n                        containerColor = MaterialTheme.colorScheme.secondary\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.EditAlt,\n                            contentDescription = stringResource(R.string.edit)\n                        )\n                    }\n                }\n            }\n        }\n\n        EnhancedAlertDialog(\n            visible = showDeleteDialog,\n            onDismissRequest = { showDeleteDialog = false },\n            confirmButton = {\n                EnhancedButton(\n                    onClick = { showDeleteDialog = false }\n                ) {\n                    Text(stringResource(R.string.cancel))\n                }\n            },\n            dismissButton = {\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    onClick = {\n                        onRemoveTemplateFilter(templateFilter)\n                        onDismiss(false)\n                        showDeleteDialog = false\n                    }\n                ) {\n                    Text(stringResource(R.string.delete))\n                }\n            },\n            title = {\n                Text(stringResource(R.string.delete_template))\n            },\n            icon = {\n                Icon(\n                    imageVector = Icons.Outlined.Delete,\n                    contentDescription = stringResource(R.string.delete)\n                )\n            },\n            text = {\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    TemplateFilterPreviewItem(\n                        modifier = Modifier\n                            .sizeIn(\n                                maxHeight = 80.dp,\n                                maxWidth = 80.dp\n                            )\n                            .aspectRatio(1f),\n                        templateFilter = templateFilter,\n                        onRequestFilterMapping = onRequestFilterMapping\n                    )\n                    Spacer(modifier = Modifier.height(16.dp))\n                    Text(stringResource(R.string.delete_template_warn))\n                }\n            }\n        )\n\n        val saveLauncher = rememberFileCreator(\n            onSuccess = { uri ->\n                showShareDialog = false\n                onSaveFile(uri, filterContent)\n            }\n        )\n\n        EnhancedAlertDialog(\n            visible = showShareDialog,\n            onDismissRequest = { showShareDialog = false },\n            confirmButton = {\n                EnhancedButton(\n                    onClick = { showShareDialog = false },\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer\n                ) {\n                    Text(stringResource(R.string.cancel))\n                }\n            },\n            title = {\n                Text(stringResource(R.string.share))\n            },\n            icon = {\n                Icon(\n                    imageVector = Icons.Outlined.AutoFixHigh,\n                    contentDescription = null\n                )\n            },\n            text = {\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    PreferenceItem(\n                        title = stringResource(R.string.as_qr_code),\n                        shape = ShapeDefaults.top,\n                        startIcon = Icons.Rounded.QrCode,\n                        onClick = {\n                            showShareDialog = false\n                            scope.launch {\n                                captureController.captureAsync()\n                                    .await()\n                                    .asAndroidBitmap()\n                                    .let(onShareImage)\n                            }\n                        },\n                        titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                    )\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        title = stringResource(R.string.as_file),\n                        shape = ShapeDefaults.center,\n                        startIcon = Icons.Rounded.FilePresent,\n                        onClick = {\n                            showShareDialog = false\n                            onShareFile(filterContent)\n                        },\n                        titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                    )\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        title = stringResource(R.string.save_as_qr_code_image),\n                        shape = ShapeDefaults.center,\n                        startIcon = Icons.Rounded.QrCode2,\n                        onClick = {\n                            showShareDialog = false\n                            scope.launch {\n                                captureController.captureAsync()\n                                    .await()\n                                    .asAndroidBitmap()\n                                    .let(onSaveImage)\n                            }\n                        },\n                        titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                    )\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        title = stringResource(R.string.save_as_file),\n                        shape = ShapeDefaults.bottom,\n                        startIcon = Icons.Rounded.Save,\n                        onClick = {\n                            saveLauncher.make(onRequestTemplateFilename())\n                        },\n                        titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                    )\n                }\n            }\n        )\n\n        FilterTemplateCreationSheet(\n            visible = showEditTemplateSheet,\n            onDismiss = { showEditTemplateSheet = false },\n            initialTemplateFilter = templateFilter,\n            component = component\n        )\n    }\n}\n\n@Composable\ninternal fun TemplateFilterPreviewItem(\n    modifier: Modifier,\n    onRequestFilterMapping: (UiFilter<*>) -> Transformation,\n    templateFilter: TemplateFilter\n) {\n    val previewModel = LocalFilterPreviewModelProvider.current.preview\n\n    var loading by remember {\n        mutableStateOf(false)\n    }\n\n    Picture(\n        model = remember(templateFilter, previewModel) {\n            ImageRequest.Builder(appContext)\n                .data(previewModel.data)\n                .error(R.drawable.filter_preview_source)\n                .transformations(templateFilter.filters.map { onRequestFilterMapping(it.toUiFilter()) })\n                .diskCacheKey(templateFilter.toString() + previewModel.data.hashCode())\n                .memoryCacheKey(templateFilter.toString() + previewModel.data.hashCode())\n                .size(300, 300)\n                .build()\n        },\n        onLoading = {\n            loading = true\n        },\n        onSuccess = {\n            loading = false\n        },\n        contentScale = ContentScale.Crop,\n        contentDescription = null,\n        modifier = modifier\n            .clip(MaterialTheme.shapes.medium)\n            .transparencyChecker()\n            .shimmer(loading)\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/TemplateFilterSelectionItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.rounded.Slideshow\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.request.ImageRequest\nimport coil3.request.error\nimport coil3.request.transformations\nimport coil3.toBitmap\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.StrongBlack\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun TemplateFilterSelectionItem(\n    templateFilter: TemplateFilter,\n    onClick: () -> Unit,\n    onLongClick: () -> Unit,\n    onRequestFilterMapping: (UiFilter<*>) -> Transformation,\n    onInfoClick: () -> Unit,\n    shape: Shape,\n    modifier: Modifier\n) {\n    val previewModel = LocalFilterPreviewModelProvider.current.preview\n    var loading by remember {\n        mutableStateOf(false)\n    }\n    var isBitmapDark by remember {\n        mutableStateOf(true)\n    }\n    val scope = rememberCoroutineScope()\n\n    PreferenceItemOverload(\n        title = templateFilter.name,\n        startIcon = {\n            Row(verticalAlignment = Alignment.CenterVertically) {\n                Box(contentAlignment = Alignment.Center) {\n                    Picture(\n                        model = remember(templateFilter, previewModel) {\n                            ImageRequest.Builder(appContext)\n                                .data(previewModel.data)\n                                .error(R.drawable.filter_preview_source)\n                                .transformations(\n                                    templateFilter.filters.map {\n                                        onRequestFilterMapping(\n                                            it.toUiFilter()\n                                        )\n                                    }\n                                )\n                                .diskCacheKey(templateFilter.toString() + previewModel.data.hashCode())\n                                .memoryCacheKey(templateFilter.toString() + previewModel.data.hashCode())\n                                .size(300, 300)\n                                .build()\n                        },\n                        onLoading = {\n                            loading = true\n                        },\n                        onSuccess = {\n                            loading = false\n                            scope.launch {\n                                isBitmapDark =\n                                    calculateBrightnessEstimate(it.result.image.toBitmap()) < 110\n                            }\n                        },\n                        contentScale = ContentScale.Crop,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .size(48.dp)\n                            .scale(1.2f)\n                            .clip(MaterialTheme.shapes.medium)\n                            .transparencyChecker()\n                            .shimmer(loading)\n                    )\n                    Box(\n                        modifier = Modifier\n                            .size(36.dp)\n                            .clip(ShapeDefaults.circle)\n                            .hapticsClickable(onClick = onLongClick),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Slideshow,\n                            contentDescription = stringResource(R.string.image_preview),\n                            tint = if (isBitmapDark) StrongBlack\n                            else White,\n                            modifier = Modifier.scale(1.2f)\n                        )\n                        Icon(\n                            imageVector = Icons.Rounded.Slideshow,\n                            contentDescription = stringResource(R.string.image_preview),\n                            tint = if (isBitmapDark) White\n                            else StrongBlack\n                        )\n                    }\n                }\n                Spacer(Modifier.width(16.dp))\n                Box(\n                    modifier = Modifier\n                        .height(36.dp)\n                        .width(1.dp)\n                        .background(MaterialTheme.colorScheme.outlineVariant())\n                )\n            }\n        },\n        endIcon = {\n            EnhancedIconButton(\n                onClick = onInfoClick,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                modifier = Modifier.offset(8.dp)\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.Info,\n                    contentDescription = null\n                )\n            }\n        },\n        modifier = modifier.fillMaxWidth(),\n        shape = shape,\n        onClick = onClick,\n        drawStartIconContainer = false\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/addFilters/AddFiltersSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters\n\nimport android.graphics.Bitmap\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Search\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.PrimaryScrollableTabRow\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Tab\nimport androidx.compose.material3.TabRowDefaults\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.collectAsUiState\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterPreviewSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterSelectionItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberRetainedLazyListState\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.util.Locale\n\n@Composable\nfun AddFiltersSheet(\n    component: AddFiltersSheetComponent,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent,\n    visible: Boolean,\n    onVisibleChange: (Boolean) -> Unit,\n    previewBitmap: Bitmap?,\n    onFilterPicked: (UiFilter<*>) -> Unit,\n    onFilterPickedWithParams: (UiFilter<*>) -> Unit,\n    canAddTemplates: Boolean = true\n) {\n    val favoriteFilters by component.favoritesFlow.collectAsUiState()\n\n    val tabs: List<UiFilter.Group> by remember(canAddTemplates, favoriteFilters) {\n        derivedStateOf {\n            buildList {\n                if (canAddTemplates) {\n                    add(UiFilter.Group.Template)\n                }\n                add(UiFilter.Group.Favorite(favoriteFilters))\n                addAll(UiFilter.groups)\n            }\n        }\n    }\n\n    val haptics = LocalHapticFeedback.current\n    val pagerState = rememberPagerState(\n        pageCount = { tabs.size },\n        initialPage = 2\n    )\n\n    val onRequestFilterMapping = component::filterToTransformation\n\n    var isSearching by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var searchKeyword by rememberSaveable(isSearching) {\n        mutableStateOf(\"\")\n    }\n    val allFilters = remember {\n        tabs.flatMap { group ->\n            group.filters(canAddTemplates).sortedBy { getString(it.title) }\n        }\n    }\n    var filtersForSearch by remember(allFilters) {\n        mutableStateOf(allFilters)\n    }\n    val resourceManager = LocalResourceManager.current\n    LaunchedEffect(searchKeyword) {\n        withContext(Dispatchers.Default) {\n            delay(400L) // Debounce calculations\n            if (searchKeyword.isEmpty()) {\n                filtersForSearch = allFilters\n                return@withContext\n            }\n\n            filtersForSearch = allFilters.filter {\n                resourceManager.getString(it.title).contains(\n                    other = searchKeyword,\n                    ignoreCase = true\n                ) || resourceManager.getStringLocalized(\n                    resId = it.title,\n                    language = Locale.ENGLISH.language\n                ).contains(\n                    other = searchKeyword,\n                    ignoreCase = true\n                )\n            }.sortedBy { getString(it.title) }\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        dragHandle = {\n            EnhancedModalSheetDragHandle {\n                AnimatedVisibility(visible = !isSearching) {\n                    Row(\n                        modifier = Modifier.fillMaxWidth(),\n                        horizontalArrangement = Arrangement.Center\n                    ) {\n                        PrimaryScrollableTabRow(\n                            divider = {},\n                            edgePadding = 16.dp,\n                            containerColor = EnhancedBottomSheetDefaults.barContainerColor,\n                            selectedTabIndex = pagerState.currentPage,\n                            indicator = {\n                                TabRowDefaults.PrimaryIndicator(\n                                    modifier = Modifier.tabIndicatorOffset(\n                                        selectedTabIndex = pagerState.currentPage,\n                                        matchContentSize = true\n                                    ),\n                                    width = Dp.Unspecified,\n                                    height = 4.dp,\n                                    shape = AutoCornersShape(\n                                        topStart = 100f,\n                                        topEnd = 100f\n                                    )\n                                )\n                            }\n                        ) {\n                            val scope = rememberCoroutineScope()\n\n                            tabs.forEachIndexed { index, (icon, title) ->\n                                val selected = pagerState.currentPage == index\n                                val color by animateColorAsState(\n                                    if (selected) {\n                                        MaterialTheme.colorScheme.primary\n                                    } else MaterialTheme.colorScheme.onSurface\n                                )\n                                val interactionSource = remember { MutableInteractionSource() }\n                                val shape = shapeByInteraction(\n                                    shape = AutoCornersShape(42.dp),\n                                    pressedShape = ShapeDefaults.default,\n                                    interactionSource = interactionSource\n                                )\n\n                                Tab(\n                                    interactionSource = interactionSource,\n                                    unselectedContentColor = MaterialTheme.colorScheme.onSurface,\n                                    modifier = Modifier\n                                        .padding(8.dp)\n                                        .clip(shape),\n                                    selected = selected,\n                                    onClick = {\n                                        haptics.longPress()\n                                        scope.launch {\n                                            pagerState.animateScrollToPage(index)\n                                        }\n                                    },\n                                    icon = {\n                                        Icon(\n                                            imageVector = icon,\n                                            contentDescription = null,\n                                            tint = color\n                                        )\n                                    },\n                                    text = {\n                                        Text(\n                                            text = stringResource(title),\n                                            color = color\n                                        )\n                                    }\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        sheetContent = {\n            component.AttachLifecycle()\n\n            AnimatedContent(\n                modifier = Modifier.weight(1f, false),\n                targetState = isSearching\n            ) { isSearching ->\n                if (isSearching) {\n                    AnimatedContent(\n                        targetState = filtersForSearch.isNotEmpty()\n                    ) { isNotEmpty ->\n                        if (isNotEmpty) {\n                            LazyColumn(\n                                state = rememberRetainedLazyListState(\"sheet\"),\n                                verticalArrangement = Arrangement.spacedBy(4.dp),\n                                modifier = Modifier.animateContentSizeNoClip(),\n                                contentPadding = PaddingValues(16.dp),\n                                flingBehavior = enhancedFlingBehavior()\n                            ) {\n                                itemsIndexed(\n                                    items = filtersForSearch,\n                                    key = { _, f -> f.hashCode() }\n                                ) { index, filter ->\n                                    FilterSelectionItem(\n                                        filter = filter,\n                                        isFavoritePage = false,\n                                        canOpenPreview = previewBitmap != null,\n                                        favoriteFilters = favoriteFilters,\n                                        onLongClick = {\n                                            component.setPreviewData(filter)\n                                        },\n                                        onOpenPreview = {\n                                            component.setPreviewData(filter)\n                                        },\n                                        onClick = {\n                                            onVisibleChange(false)\n                                            onFilterPicked(filter)\n                                        },\n                                        onRequestFilterMapping = onRequestFilterMapping,\n                                        shape = ShapeDefaults.byIndex(\n                                            index = index,\n                                            size = filtersForSearch.size\n                                        ),\n                                        onToggleFavorite = {\n                                            component.toggleFavorite(filter)\n                                        },\n                                        modifier = Modifier.animateItem()\n                                    )\n                                }\n                            }\n                        } else {\n                            Column(\n                                modifier = Modifier\n                                    .fillMaxWidth()\n                                    .fillMaxHeight(0.5f),\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                verticalArrangement = Arrangement.Center\n                            ) {\n                                Spacer(Modifier.weight(1f))\n                                Text(\n                                    text = stringResource(R.string.nothing_found_by_search),\n                                    fontSize = 18.sp,\n                                    textAlign = TextAlign.Center,\n                                    modifier = Modifier.padding(\n                                        start = 24.dp,\n                                        end = 24.dp,\n                                        top = 8.dp,\n                                        bottom = 8.dp\n                                    )\n                                )\n                                Icon(\n                                    imageVector = Icons.Rounded.SearchOff,\n                                    contentDescription = null,\n                                    modifier = Modifier\n                                        .weight(2f)\n                                        .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                                        .fillMaxSize()\n                                )\n                                Spacer(Modifier.weight(1f))\n                            }\n                        }\n                    }\n                } else {\n                    HorizontalPager(\n                        state = pagerState,\n                        beyondViewportPageCount = 2\n                    ) { page ->\n                        when (val group = tabs[page]) {\n                            is UiFilter.Group.Template -> {\n                                TemplatesContent(\n                                    component = component,\n                                    filterTemplateCreationSheetComponent = filterTemplateCreationSheetComponent,\n                                    onVisibleChange = onVisibleChange,\n                                    onFilterPickedWithParams = onFilterPickedWithParams\n                                )\n                            }\n\n                            is UiFilter.Group.Favorite -> {\n                                FavoritesContent(\n                                    component = component,\n                                    onVisibleChange = onVisibleChange,\n                                    onFilterPickedWithParams = onFilterPickedWithParams,\n                                    onFilterPicked = onFilterPicked,\n                                    previewBitmap = previewBitmap\n                                )\n                            }\n\n                            else -> {\n                                val filters by remember(group, canAddTemplates) {\n                                    derivedStateOf {\n                                        group.filters(canAddTemplates)\n                                    }\n                                }\n                                OtherContent(\n                                    component = component,\n                                    currentGroup = group,\n                                    filters = filters,\n                                    onVisibleChange = onVisibleChange,\n                                    onFilterPickedWithParams = onFilterPickedWithParams,\n                                    onFilterPicked = onFilterPicked,\n                                    previewBitmap = previewBitmap\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        title = {\n            AnimatedContent(\n                targetState = isSearching\n            ) { searching ->\n                if (searching) {\n                    BackHandler {\n                        searchKeyword = \"\"\n                        isSearching = false\n                    }\n                    ProvideTextStyle(value = MaterialTheme.typography.bodyLarge) {\n                        RoundedTextField(\n                            maxLines = 1,\n                            hint = { Text(stringResource(id = R.string.search_here)) },\n                            keyboardOptions = KeyboardOptions.Default.copy(\n                                imeAction = ImeAction.Search,\n                                autoCorrectEnabled = null\n                            ),\n                            value = searchKeyword,\n                            onValueChange = {\n                                searchKeyword = it\n                            },\n                            startIcon = {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        searchKeyword = \"\"\n                                        isSearching = false\n                                    },\n                                    modifier = Modifier.padding(start = 4.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit),\n                                        tint = MaterialTheme.colorScheme.onSurface\n                                    )\n                                }\n                            },\n                            endIcon = {\n                                AnimatedVisibility(\n                                    visible = searchKeyword.isNotEmpty(),\n                                    enter = fadeIn() + scaleIn(),\n                                    exit = fadeOut() + scaleOut()\n                                ) {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            searchKeyword = \"\"\n                                        },\n                                        modifier = Modifier.padding(end = 4.dp)\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.Close,\n                                            contentDescription = stringResource(R.string.close),\n                                            tint = MaterialTheme.colorScheme.onSurface\n                                        )\n                                    }\n                                }\n                            },\n                            shape = ShapeDefaults.circle\n                        )\n                    }\n                } else {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.filter),\n                            icon = Icons.Rounded.AutoFixHigh\n                        )\n                        Spacer(modifier = Modifier.weight(1f))\n                        EnhancedIconButton(\n                            onClick = { isSearching = true },\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Search,\n                                contentDescription = stringResource(R.string.search_here)\n                            )\n                        }\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            onClick = { onVisibleChange(false) }\n                        ) {\n                            AutoSizeText(stringResource(R.string.close))\n                        }\n                        Spacer(Modifier.width(8.dp))\n                    }\n                }\n            }\n        },\n        confirmButton = {},\n        enableBottomContentWeight = false,\n        visible = visible,\n        onDismiss = onVisibleChange\n    )\n\n    FilterPreviewSheet(\n        component = component,\n        onFilterPickedWithParams = onFilterPickedWithParams,\n        onVisibleChange = onVisibleChange,\n        previewBitmap = previewBitmap\n    )\n}\n\n@Composable\nfun AddFiltersSheet(\n    component: AddFiltersSheetComponent,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    previewBitmap: Bitmap?,\n    onFilterPicked: (UiFilter<*>) -> Unit,\n    onFilterPickedWithParams: (UiFilter<*>) -> Unit,\n    canAddTemplates: Boolean = true\n) {\n    AddFiltersSheet(\n        component = component,\n        filterTemplateCreationSheetComponent = filterTemplateCreationSheetComponent,\n        visible = visible,\n        onVisibleChange = { if (!it) onDismiss() },\n        previewBitmap = previewBitmap,\n        onFilterPicked = onFilterPicked,\n        onFilterPickedWithParams = onFilterPickedWithParams,\n        canAddTemplates = canAddTemplates\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/addFilters/AddFiltersSheetComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport coil3.transform.Transformation\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResources\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResourcesStore\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterParamsInteractor\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toCoil\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.Flow\n\nclass AddFiltersSheetComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    private val filterProvider: FilterProvider<Bitmap>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val favoriteInteractor: FilterParamsInteractor,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val remoteResourcesStore: RemoteResourcesStore,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _previewData: MutableState<List<UiFilter<*>>?> = mutableStateOf(null)\n    val previewData by _previewData\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap by _previewBitmap\n\n    private val _cubeLutRemoteResources: MutableState<RemoteResources> =\n        mutableStateOf(RemoteResources.CubeLutDefault)\n    val cubeLutRemoteResources by _cubeLutRemoteResources\n\n    private val _cubeLutDownloadProgress: MutableState<DownloadProgress?> =\n        mutableStateOf(null)\n    val cubeLutDownloadProgress by _cubeLutDownloadProgress\n\n    init {\n        updateCubeLuts(\n            startDownloadIfNeeded = false,\n            forceUpdate = false,\n            onFailure = {},\n            downloadOnlyNewData = false\n        )\n    }\n\n    fun setFilterPreviewModel(uri: String) {\n        componentScope.launch {\n            favoriteInteractor.setFilterPreviewModel(uri)\n            favoriteInteractor.setCanSetDynamicFilterPreview(false)\n        }\n    }\n\n    fun setCanSetDynamicFilterPreview(value: Boolean) {\n        componentScope.launch {\n            favoriteInteractor.setCanSetDynamicFilterPreview(value)\n        }\n    }\n\n    fun updateCubeLuts(\n        startDownloadIfNeeded: Boolean,\n        forceUpdate: Boolean,\n        onFailure: (Throwable) -> Unit,\n        downloadOnlyNewData: Boolean = false\n    ) {\n        componentScope.launch {\n            remoteResourcesStore.getResources(\n                name = RemoteResources.CUBE_LUT,\n                forceUpdate = forceUpdate,\n                onDownloadRequest = { name ->\n                    if (startDownloadIfNeeded) {\n                        remoteResourcesStore.downloadResources(\n                            name = name,\n                            onProgress = { progress ->\n                                _cubeLutDownloadProgress.update { progress }\n                            },\n                            onFailure = onFailure,\n                            downloadOnlyNewData = downloadOnlyNewData\n                        )\n                    } else null\n                }\n            )?.let { data ->\n                _cubeLutRemoteResources.update { data }\n            }\n            _cubeLutDownloadProgress.update { null }\n        }\n    }\n\n    fun setPreviewData(data: UiFilter<*>?) {\n        _previewData.update {\n            data?.let { filter ->\n                listOf(\n                    filter.copy(filter.value).apply { isVisible = true }\n                )\n            }\n        }\n    }\n\n    fun setPreviewData(data: List<Filter<*>>) {\n        _previewData.update { data.map { it.toUiFilter() } }\n    }\n\n    fun filterToTransformation(\n        filter: UiFilter<*>\n    ): Transformation = filterProvider.filterToTransformation(filter).toCoil()\n\n    fun updatePreview(previewBitmap: Bitmap) {\n        debouncedImageCalculation {\n            _previewBitmap.update {\n                imageTransformer.transform(\n                    image = previewBitmap,\n                    transformations = previewData?.map {\n                        filterProvider.filterToTransformation(it)\n                    } ?: emptyList(),\n                    size = IntegerSize(2000, 2000)\n                )\n            }\n        }\n    }\n\n    fun removeFilterAtIndex(index: Int) {\n        _previewData.update {\n            it?.toMutableList()?.apply {\n                removeAt(index)\n            }\n        }\n    }\n\n    fun <T : Any> updateFilter(\n        value: T,\n        index: Int\n    ) {\n        val list = (previewData ?: emptyList()).toMutableList()\n        runCatching {\n            list[index] = list[index].copy(value)\n            _previewData.update { list }\n        }.onFailure {\n            list[index] = list[index].newInstance()\n            _previewData.update { list }\n        }\n    }\n\n    fun shareImage(\n        bitmap: Bitmap\n    ) {\n        componentScope.launch {\n            shareProvider.shareImage(\n                imageInfo = ImageInfo(\n                    width = bitmap.width,\n                    height = bitmap.height,\n                    imageFormat = ImageFormat.Png.Lossless\n                ),\n                image = bitmap,\n                onComplete = AppToastHost::showConfetti\n            )\n        }\n    }\n\n    fun saveImage(\n        bitmap: Bitmap\n    ) {\n        componentScope.launch {\n            val imageInfo = ImageInfo(\n                width = bitmap.width,\n                height = bitmap.height,\n                imageFormat = ImageFormat.Png.Lossless\n            )\n            parseSaveResult(\n                fileController.save(\n                    saveTarget = ImageSaveTarget(\n                        imageInfo = imageInfo,\n                        originalUri = \"\",\n                        sequenceNumber = null,\n                        data = imageCompressor.compress(\n                            image = bitmap,\n                            imageFormat = imageInfo.imageFormat,\n                            quality = Quality.Base()\n                        )\n                    ),\n                    keepOriginalMetadata = true\n                )\n            )\n        }\n    }\n\n    fun saveContentTo(\n        content: String,\n        fileUri: Uri\n    ) {\n        componentScope.launch {\n            fileController.writeBytes(\n                uri = fileUri.toString(),\n                block = { it.writeBytes(content.toByteArray()) }\n            ).also(::parseFileSaveResult).onSuccess(::registerSave)\n        }\n    }\n\n    fun shareContent(\n        content: String,\n        filename: String\n    ) {\n        componentScope.launch {\n            shareProvider.shareData(\n                writeData = { it.writeBytes(content.toByteArray()) },\n                filename = filename,\n                onComplete = AppToastHost::showConfetti\n            )\n        }\n    }\n\n    fun createTemplateFilename(templateFilter: TemplateFilter): String {\n        return \"template(${templateFilter.name})${timestamp()}.imtbx_template\"\n    }\n\n    fun reorderFavoriteFilters(value: List<UiFilter<*>>) {\n        componentScope.launch {\n            favoriteInteractor.reorderFavoriteFilters(value)\n        }\n    }\n\n    val favoritesFlow: Flow<List<Filter<*>>>\n        get() = favoriteInteractor.getFavoriteFilters()\n\n    val templatesFlow: Flow<List<TemplateFilter>>\n        get() = favoriteInteractor.getTemplateFilters()\n\n    fun toggleFavorite(filter: UiFilter<*>) {\n        componentScope.launch {\n            favoriteInteractor.toggleFavorite(filter)\n        }\n    }\n\n    fun removeTemplateFilter(templateFilter: TemplateFilter) {\n        componentScope.launch {\n            favoriteInteractor.removeTemplateFilter(templateFilter)\n        }\n    }\n\n    suspend fun convertTemplateFilterToString(\n        templateFilter: TemplateFilter\n    ): String = favoriteInteractor.convertTemplateFilterToString(templateFilter)\n\n    fun addTemplateFilterFromString(\n        string: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    ) {\n        componentScope.launch {\n            favoriteInteractor.addTemplateFilterFromString(\n                string = string,\n                onSuccess = onSuccess,\n                onFailure = onFailure\n            )\n        }\n    }\n\n    fun addTemplateFilterFromUri(\n        uri: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit\n    ) {\n        componentScope.launch {\n            favoriteInteractor.addTemplateFilterFromUri(\n                uri = uri,\n                onSuccess = onSuccess,\n                onFailure = onFailure\n            )\n        }\n    }\n\n    fun cacheNeutralLut() {\n        componentScope.launch {\n            imageGetter.getImage(R.drawable.lookup)?.let {\n                shareProvider.cacheImage(\n                    image = it,\n                    imageInfo = ImageInfo(\n                        width = 512,\n                        height = 512,\n                        imageFormat = ImageFormat.Png.Lossless\n                    )\n                )?.let { uri ->\n                    Clipboard.copy(uri.toUri())\n                }\n            }\n        }\n    }\n\n    fun shareNeutralLut() {\n        componentScope.launch {\n            imageGetter.getImage(R.drawable.lookup)?.let {\n                shareProvider.shareImage(\n                    image = it,\n                    imageInfo = ImageInfo(\n                        width = 512,\n                        height = 512,\n                        imageFormat = ImageFormat.Png.Lossless\n                    ),\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n        }\n    }\n\n    fun saveNeutralLut(\n        oneTimeSaveLocationUri: String? = null\n    ) {\n        componentScope.launch {\n            imageGetter.getImage(R.drawable.lookup)?.let { bitmap ->\n                val imageInfo = ImageInfo(\n                    width = 512,\n                    height = 512,\n                    imageFormat = ImageFormat.Png.Lossless\n                )\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = imageInfo,\n                            originalUri = \"\",\n                            sequenceNumber = null,\n                            data = imageCompressor.compress(\n                                image = bitmap,\n                                imageFormat = imageInfo.imageFormat,\n                                quality = Quality.Base()\n                            )\n                        ),\n                        keepOriginalMetadata = false,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    )\n                )\n            }\n        }\n    }\n\n    override fun resetState() {\n        _previewData.update { null }\n        _previewBitmap.update { null }\n        cancelImageLoading()\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext\n        ): AddFiltersSheetComponent\n    }\n\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/addFilters/FavoritesContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiCubeLutFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.collectAsUiState\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterSelectionItem\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BookmarkOff\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\n\n@Composable\ninternal fun FavoritesContent(\n    component: AddFiltersSheetComponent,\n    onVisibleChange: (Boolean) -> Unit,\n    onFilterPickedWithParams: (UiFilter<*>) -> Unit,\n    onFilterPicked: (UiFilter<*>) -> Unit,\n    previewBitmap: Bitmap?\n) {\n    val onRequestFilterMapping = component::filterToTransformation\n    val favoriteFilters by component.favoritesFlow.collectAsUiState()\n\n    AnimatedContent(\n        targetState = favoriteFilters.isEmpty()\n    ) { noFav ->\n        if (noFav) {\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .fillMaxHeight(0.5f),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                Spacer(Modifier.weight(1f))\n                Text(\n                    text = stringResource(R.string.no_favorite_filters),\n                    fontSize = 18.sp,\n                    textAlign = TextAlign.Center,\n                    modifier = Modifier.padding(\n                        start = 24.dp,\n                        end = 24.dp,\n                        top = 8.dp,\n                        bottom = 8.dp\n                    )\n                )\n                Icon(\n                    imageVector = Icons.Outlined.BookmarkOff,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .weight(2f)\n                        .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                        .fillMaxSize()\n                )\n                Spacer(Modifier.weight(1f))\n            }\n        } else {\n            val data = remember {\n                mutableStateOf(favoriteFilters)\n            }\n            val haptics = LocalHapticFeedback.current\n            val listState = rememberLazyListState()\n            val state = rememberReorderableLazyListState(\n                lazyListState = listState,\n                onMove = { from, to ->\n                    haptics.press()\n                    data.value = data.value.toMutableList().apply {\n                        add(to.index, removeAt(from.index))\n                    }\n                }\n            )\n            LaunchedEffect(favoriteFilters) {\n                if (data.value.size != favoriteFilters.size) {\n                    data.value = favoriteFilters\n                }\n            }\n            LazyColumn(\n                state = listState,\n                modifier = Modifier.fillMaxHeight(),\n                verticalArrangement = Arrangement.spacedBy(\n                    space = 4.dp,\n                    alignment = Alignment.CenterVertically\n                ),\n                contentPadding = PaddingValues(16.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                itemsIndexed(\n                    items = data.value,\n                    key = { _, f -> f.hashCode() }\n                ) { index, filter ->\n                    ReorderableItem(\n                        state = state,\n                        key = filter.hashCode()\n                    ) { isDragging ->\n                        FilterSelectionItem(\n                            filter = filter,\n                            isFavoritePage = true,\n                            canOpenPreview = previewBitmap != null,\n                            favoriteFilters = favoriteFilters,\n                            onLongClick = null,\n                            onOpenPreview = {\n                                component.setPreviewData(filter)\n                            },\n                            onClick = { custom ->\n                                onVisibleChange(false)\n                                if (custom != null) {\n                                    onFilterPickedWithParams(custom)\n                                } else {\n                                    onFilterPicked(filter)\n                                }\n                            },\n                            onRequestFilterMapping = onRequestFilterMapping,\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = favoriteFilters.size\n                            ),\n                            onToggleFavorite = {\n                                component.toggleFavorite(filter)\n                            },\n                            modifier = Modifier\n                                .longPressDraggableHandle(\n                                    onDragStarted = {\n                                        haptics.longPress()\n                                    },\n                                    onDragStopped = {\n                                        component.reorderFavoriteFilters(data.value)\n                                    }\n                                )\n                                .scale(\n                                    animateFloatAsState(\n                                        if (isDragging) 1.05f\n                                        else 1f\n                                    ).value\n                                ),\n                            cubeLutRemoteResources = if (filter is UiCubeLutFilter) {\n                                component.cubeLutRemoteResources\n                            } else null,\n                            cubeLutDownloadProgress = if (filter is UiCubeLutFilter) {\n                                component.cubeLutDownloadProgress\n                            } else null,\n                            onCubeLutDownloadRequest = { forceUpdate, downloadOnlyNewData ->\n                                component.updateCubeLuts(\n                                    startDownloadIfNeeded = true,\n                                    forceUpdate = forceUpdate,\n                                    onFailure = AppToastHost::showFailureToast,\n                                    downloadOnlyNewData = downloadOnlyNewData\n                                )\n                            }\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/addFilters/OtherContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ImageSearch\nimport androidx.compose.material.icons.rounded.Save\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiCubeLutFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.collectAsUiState\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterSelectionItem\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberRetainedLazyListState\n\n@Composable\ninternal fun OtherContent(\n    component: AddFiltersSheetComponent,\n    currentGroup: UiFilter.Group,\n    filters: List<UiFilter<*>>,\n    onVisibleChange: (Boolean) -> Unit,\n    onFilterPickedWithParams: (UiFilter<*>) -> Unit,\n    onFilterPicked: (UiFilter<*>) -> Unit,\n    previewBitmap: Bitmap?,\n) {\n    val favoriteFilters by component.favoritesFlow.collectAsUiState()\n    val onRequestFilterMapping = component::filterToTransformation\n\n    LazyColumn(\n        state = rememberRetainedLazyListState(\"sheet$currentGroup\"),\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        contentPadding = PaddingValues(16.dp),\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        if (currentGroup is UiFilter.Group.Simple) simpleAdditionalSection(component)\n        if (currentGroup is UiFilter.Group.LUT) lutAdditionalSection(component)\n\n        itemsIndexed(\n            items = filters,\n            key = { _, f -> f.hashCode() }\n        ) { index, filter ->\n            FilterSelectionItem(\n                filter = filter,\n                canOpenPreview = previewBitmap != null,\n                favoriteFilters = favoriteFilters,\n                onLongClick = {\n                    component.setPreviewData(filter)\n                },\n                onOpenPreview = {\n                    component.setPreviewData(filter)\n                },\n                onClick = { custom ->\n                    onVisibleChange(false)\n                    custom?.also(onFilterPickedWithParams) ?: onFilterPicked(filter)\n                },\n                onRequestFilterMapping = onRequestFilterMapping,\n                shape = ShapeDefaults.byIndex(\n                    index = index,\n                    size = filters.size\n                ),\n                onToggleFavorite = {\n                    component.toggleFavorite(filter)\n                },\n                isFavoritePage = false,\n                modifier = Modifier.animateItem(),\n                cubeLutRemoteResources = component.cubeLutRemoteResources.takeIf { filter is UiCubeLutFilter },\n                cubeLutDownloadProgress = component.cubeLutDownloadProgress.takeIf { filter is UiCubeLutFilter },\n                onCubeLutDownloadRequest = { forceUpdate, downloadOnlyNewData ->\n                    component.updateCubeLuts(\n                        startDownloadIfNeeded = true,\n                        forceUpdate = forceUpdate,\n                        onFailure = AppToastHost::showFailureToast,\n                        downloadOnlyNewData = downloadOnlyNewData\n                    )\n                }\n            )\n        }\n    }\n}\n\nprivate fun LazyListScope.lutAdditionalSection(\n    component: AddFiltersSheetComponent\n) {\n    item {\n        PreferenceItemOverload(\n            title = stringResource(R.string.save_empty_lut),\n            subtitle = stringResource(R.string.save_empty_lut_sub),\n            shape = ShapeDefaults.default,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(bottom = 8.dp),\n            endIcon = {\n                Column(\n                    verticalArrangement = Arrangement.Center,\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Picture(\n                        model = R.drawable.lookup,\n                        contentScale = ContentScale.Crop,\n                        modifier = Modifier\n                            .size(48.dp)\n                            .scale(1.1f)\n                            .clip(MaterialTheme.shapes.extraSmall),\n                        shape = MaterialTheme.shapes.extraSmall\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    var showFolderSelection by rememberSaveable {\n                        mutableStateOf(false)\n                    }\n                    val saveNeutralLut: (String?) -> Unit = {\n                        component.saveNeutralLut(\n                            oneTimeSaveLocationUri = it\n                        )\n                    }\n                    Row {\n                        ShareButton(\n                            onShare = component::shareNeutralLut,\n                            onCopy = component::cacheNeutralLut\n                        )\n                        EnhancedIconButton(\n                            onClick = {\n                                saveNeutralLut(null)\n                            },\n                            onLongClick = {\n                                showFolderSelection = true\n                            }\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Save,\n                                contentDescription = stringResource(R.string.save)\n                            )\n                        }\n\n                        OneTimeSaveLocationSelectionDialog(\n                            visible = showFolderSelection,\n                            onDismiss = {\n                                showFolderSelection = false\n                            },\n                            onSaveRequest = saveNeutralLut\n                        )\n                    }\n                }\n            }\n        )\n    }\n}\n\nprivate fun LazyListScope.simpleAdditionalSection(\n    component: AddFiltersSheetComponent\n) {\n    item {\n        val previewProvider = LocalFilterPreviewModelProvider.current\n        val previewModel = previewProvider.preview\n        val canSetDynamicFilterPreview = previewProvider.canSetDynamicFilterPreview\n\n        Row(\n            modifier = Modifier\n                .padding(bottom = 8.dp)\n                .height(intrinsicSize = IntrinsicSize.Max),\n            horizontalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            ImageSelector(\n                value = previewModel.data,\n                onValueChange = {\n                    component.setFilterPreviewModel(it.toString())\n                },\n                title = stringResource(R.string.filter_preview_image),\n                subtitle = stringResource(R.string.filter_preview_image_sub),\n                contentScale = ContentScale.Crop,\n                color = Color.Unspecified,\n                modifier = Modifier\n                    .weight(1f)\n                    .fillMaxHeight(),\n                shape = ShapeDefaults.start\n            )\n            val containerColor by animateColorAsState(\n                if (canSetDynamicFilterPreview) {\n                    MaterialTheme.colorScheme.secondary\n                } else {\n                    MaterialTheme.colorScheme.secondaryContainer\n                }\n            )\n\n            Box(\n                modifier = Modifier\n                    .fillMaxHeight()\n                    .clip(ShapeDefaults.center)\n                    .hapticsClickable {\n                        component.setCanSetDynamicFilterPreview(true)\n                    }\n                    .container(\n                        color = containerColor,\n                        shape = ShapeDefaults.center,\n                        resultPadding = 0.dp\n                    )\n                    .padding(horizontal = 8.dp),\n                contentAlignment = Alignment.Center\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.ImageSearch,\n                    contentDescription = null,\n                    tint = MaterialTheme.colorScheme.contentColorFor(containerColor)\n                )\n            }\n            Column(\n                modifier = Modifier.fillMaxHeight(),\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                repeat(2) { index ->\n                    val shape = if (index == 0) {\n                        ShapeDefaults.topEnd\n                    } else {\n                        ShapeDefaults.bottomEnd\n                    }\n                    val containerColor = takeColorFromScheme {\n                        when {\n                            canSetDynamicFilterPreview -> secondaryContainer\n                            previewModel.data == R.drawable.filter_preview_source && index == 0 -> secondary\n                            previewModel.data == R.drawable.filter_preview_source_3 && index == 1 -> secondary\n                            else -> secondaryContainer\n                        }\n                    }\n                    Box(\n                        modifier = Modifier\n                            .weight(1f)\n                            .clip(shape)\n                            .hapticsClickable {\n                                component.setFilterPreviewModel(\n                                    index.toString()\n                                )\n                            }\n                            .container(\n                                color = containerColor,\n                                shape = shape,\n                                resultPadding = 0.dp\n                            )\n                            .padding(horizontal = 12.dp),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        AutoSizeText(\n                            text = (index + 1).toString(),\n                            color = contentColorFor(\n                                containerColor\n                            )\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/addFilters/TemplatesContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ExtensionOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.collectAsUiState\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateAddingGroup\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateInfoSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.TemplateFilterSelectionItem\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberRetainedLazyListState\n\n@Composable\ninternal fun TemplatesContent(\n    component: AddFiltersSheetComponent,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent,\n    onVisibleChange: (Boolean) -> Unit,\n    onFilterPickedWithParams: (UiFilter<*>) -> Unit,\n) {\n    val templateFilters by component.templatesFlow.collectAsUiState()\n    val onRequestFilterMapping = component::filterToTransformation\n\n    AnimatedContent(\n        targetState = templateFilters.isEmpty()\n    ) { noTemplates ->\n        if (noTemplates) {\n            Column(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(16.dp),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                Spacer(Modifier.weight(1f))\n                Text(\n                    text = stringResource(R.string.no_template_filters),\n                    fontSize = 18.sp,\n                    textAlign = TextAlign.Center\n                )\n                Spacer(Modifier.height(16.dp))\n                Icon(\n                    imageVector = Icons.Outlined.ExtensionOff,\n                    contentDescription = null,\n                    modifier = Modifier.size(128.dp)\n                )\n                FilterTemplateAddingGroup(\n                    onAddTemplateFilterFromString = component::addTemplateFilterFromString,\n                    onAddTemplateFilterFromUri = component::addTemplateFilterFromUri,\n                    component = filterTemplateCreationSheetComponent\n                )\n                Spacer(Modifier.weight(1f))\n            }\n        } else {\n            LazyColumn(\n                state = rememberRetainedLazyListState(\"templates\"),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.spacedBy(4.dp),\n                contentPadding = PaddingValues(16.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                itemsIndexed(\n                    items = templateFilters,\n                    key = { _, f -> f.hashCode() }\n                ) { index, templateFilter ->\n                    var showFilterTemplateInfoSheet by rememberSaveable {\n                        mutableStateOf(false)\n                    }\n                    TemplateFilterSelectionItem(\n                        templateFilter = templateFilter,\n                        onClick = {\n                            onVisibleChange(false)\n                            templateFilter.filters.forEach {\n                                onFilterPickedWithParams(it.toUiFilter())\n                            }\n                        },\n                        onLongClick = {\n                            component.setPreviewData(templateFilter.filters)\n                        },\n                        onInfoClick = {\n                            showFilterTemplateInfoSheet = true\n                        },\n                        onRequestFilterMapping = onRequestFilterMapping,\n                        shape = ShapeDefaults.byIndex(\n                            index = index,\n                            size = templateFilters.size\n                        ),\n                        modifier = Modifier.animateItem()\n                    )\n                    FilterTemplateInfoSheet(\n                        visible = showFilterTemplateInfoSheet,\n                        onDismiss = {\n                            showFilterTemplateInfoSheet = it\n                        },\n                        templateFilter = templateFilter,\n                        onRequestFilterMapping = onRequestFilterMapping,\n                        onShareImage = component::shareImage,\n                        onSaveImage = component::saveImage,\n                        onSaveFile = { fileUri, content ->\n                            component.saveContentTo(\n                                content = content,\n                                fileUri = fileUri\n                            )\n                        },\n                        onConvertTemplateFilterToString = component::convertTemplateFilterToString,\n                        onRemoveTemplateFilter = component::removeTemplateFilter,\n                        onRequestTemplateFilename = {\n                            component.createTemplateFilename(templateFilter)\n                        },\n                        onShareFile = { content ->\n                            component.shareContent(\n                                content = content,\n                                filename = component.createTemplateFilename(templateFilter)\n                            )\n                        },\n                        component = filterTemplateCreationSheetComponent\n                    )\n                }\n                item {\n                    FilterTemplateAddingGroup(\n                        onAddTemplateFilterFromString = component::addTemplateFilterFromString,\n                        onAddTemplateFilterFromUri = component::addTemplateFilterFromUri,\n                        component = filterTemplateCreationSheetComponent\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/ArcParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ArcParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun ArcParamsItem(\n    value: ArcParams,\n    filter: UiFilter<ArcParams>,\n    onFilterChange: (value: ArcParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.radius) }\n    val height: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.height) }\n    val angle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.angle) }\n    val spreadAngle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.spreadAngle) }\n    val centreX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreX) }\n    val centreY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreY) }\n\n    LaunchedEffect(\n        radius.value,\n        height.value,\n        angle.value,\n        spreadAngle.value,\n        centreX.value,\n        centreY.value\n    ) {\n        onFilterChange(\n            ArcParams(\n                radius = radius.value,\n                height = height.value,\n                angle = angle.value,\n                spreadAngle = spreadAngle.value,\n                centreX = centreX.value,\n                centreY = centreY.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> radius\n                    1 -> height\n                    2 -> angle\n                    3 -> spreadAngle\n                    4 -> centreX\n                    else -> centreY\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.Companion.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                steps = if (valueRange == 0f..3f) 2 else 0,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/AsciiParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.slideInHorizontally\nimport androidx.compose.animation.slideOutHorizontally\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Save\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.ascii.Gradient\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.AsciiParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiAsciiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.asUi\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FontSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun AsciiParamsItem(\n    value: AsciiParams,\n    filter: UiFilter<AsciiParams>,\n    onFilterChange: (value: AsciiParams) -> Unit,\n    previewOnly: Boolean,\n    itemShape: @Composable (Int) -> Shape = {\n        ShapeDefaults.byIndex(\n            index = it,\n            size = 4\n        )\n    },\n    isForText: Boolean = false\n) {\n    val gradientState: MutableState<String> =\n        remember(value) { mutableStateOf(value.gradient) }\n    val fontSize: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.fontSize) }\n    val backgroundColor: MutableState<ColorModel> =\n        remember(value) { mutableStateOf(value.backgroundColor) }\n    var isGrayscale by remember(value) { mutableStateOf(value.isGrayscale) }\n\n    val settings = LocalSettingsState.current\n    val currentFont = settings.font\n\n    var font by remember(value) {\n        mutableStateOf(\n            value.font?.asUi() ?: currentFont\n        )\n    }\n\n    LaunchedEffect(\n        gradientState.value,\n        fontSize.value,\n        backgroundColor.value,\n        isGrayscale,\n        font\n    ) {\n        onFilterChange(\n            AsciiParams(\n                gradient = gradientState.value,\n                fontSize = fontSize.value,\n                backgroundColor = backgroundColor.value,\n                isGrayscale = isGrayscale,\n                font = font.type\n            )\n        )\n    }\n\n    Column(\n        modifier = Modifier.padding(if (isForText) 0.dp else 8.dp),\n        verticalArrangement = Arrangement.spacedBy(\n            if (isForText) 4.dp else 8.dp\n        )\n    ) {\n        filter.paramsInfo.take(\n            if (isForText) 2 else 5\n        ).forEachIndexed { index, (title, valueRange, roundTo) ->\n            when (index) {\n                0 -> {\n                    Column(\n                        verticalArrangement = Arrangement.spacedBy(8.dp),\n                        modifier = if (isForText) {\n                            Modifier.container(\n                                color = MaterialTheme.colorScheme.surface,\n                                shape = itemShape(index)\n                            )\n                        } else Modifier\n                    ) {\n                        val scope = rememberCoroutineScope()\n                        val interactor = LocalSimpleSettingsInteractor.current\n                        val defaultItems = remember {\n                            listOf(\n                                Gradient.NORMAL,\n                                Gradient.NORMAL2,\n                                Gradient.ARROWS,\n                                Gradient.OLD,\n                                Gradient.EXTENDED_HIGH,\n                                Gradient.MINIMAL,\n                                Gradient.MATH,\n                                Gradient.NUMERICAL\n                            ).map { it.value }\n                        }\n                        val customEntries = settings.customAsciiGradients - defaultItems\n\n                        val items = defaultItems + customEntries\n\n                        RoundedTextField(\n                            value = gradientState.value,\n                            onValueChange = { value ->\n                                gradientState.value =\n                                    value.toList().distinct().filter { !it.isWhitespace() }\n                                        .joinToString(\"\")\n                            },\n                            endIcon = {\n                                AnimatedContent(\n                                    targetState = Triple(\n                                        gradientState.value,\n                                        defaultItems,\n                                        customEntries\n                                    ),\n                                    transitionSpec = {\n                                        slideInHorizontally { it / 2 } + fadeIn() togetherWith slideOutHorizontally { it / 2 } + fadeOut()\n                                    },\n                                    contentKey = { (g, d, c) -> (g in d) to (g in c) },\n                                ) { (gradient, default, custom) ->\n                                    if (gradient.length > 1 && gradient !in default) {\n                                        val saved = gradient in custom\n\n                                        EnhancedIconButton(\n                                            onClick = {\n                                                scope.launch {\n                                                    interactor.toggleCustomAsciiGradient(gradient)\n                                                }\n                                            },\n                                            modifier = Modifier.padding(end = 4.dp)\n                                        ) {\n                                            Icon(\n                                                imageVector = if (saved) Icons.Outlined.Delete else Icons.Outlined.Save,\n                                                contentDescription = if (saved) \"delete\" else \"add\"\n                                            )\n                                        }\n                                    } else {\n                                        Spacer(Modifier.height(40.dp))\n                                    }\n                                }\n                            },\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .then(if (isForText) Modifier.padding(top = 4.dp) else Modifier)\n                                .padding(\n                                    horizontal = 4.dp\n                                ),\n                            label = stringResource(title!!)\n                        )\n\n                        EnhancedButtonGroup(\n                            items = items,\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .padding(\n                                    horizontal = 4.dp\n                                ),\n                            selectedIndex = items.indexOf(gradientState.value),\n                            onIndexChange = {\n                                gradientState.value = items[it]\n                            },\n                            inactiveButtonColor = Color.Unspecified\n                        )\n                    }\n                }\n\n                1 -> {\n                    EnhancedSliderItem(\n                        enabled = !previewOnly,\n                        value = fontSize.value,\n                        title = stringResource(title!!),\n                        valueRange = valueRange,\n                        steps = if (valueRange == 0f..3f) 2 else 0,\n                        onValueChange = {\n                            fontSize.value = it\n                        },\n                        internalStateTransformation = {\n                            it.roundTo(roundTo)\n                        },\n                        behaveAsContainer = isForText,\n                        containerColor = MaterialTheme.colorScheme.surface,\n                        shape = itemShape(index)\n                    )\n                }\n\n                2 -> {\n                    FontSelector(\n                        value = font,\n                        onValueChange = { font = it },\n                        behaveAsContainer = false,\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                }\n\n                3 -> {\n                    ColorRowSelector(\n                        title = stringResource(title!!),\n                        value = backgroundColor.value.toColor(),\n                        onValueChange = {\n                            backgroundColor.value = it.toModel()\n                        },\n                        allowScroll = !previewOnly,\n                        icon = null,\n                        defaultColors = ColorSelectionRowDefaults.colorList,\n                        contentHorizontalPadding = 16.dp,\n                    )\n                }\n\n                4 -> {\n                    PreferenceRowSwitch(\n                        title = stringResource(id = title!!),\n                        checked = isGrayscale,\n                        onClick = {\n                            isGrayscale = it\n                        },\n                        modifier = Modifier.padding(\n                            top = 8.dp,\n                            start = 4.dp,\n                            end = 4.dp\n                        ),\n                        applyHorizontalPadding = false,\n                        startContent = {},\n                        resultModifier = Modifier.padding(\n                            horizontal = 16.dp,\n                            vertical = 8.dp\n                        ),\n                        enabled = !previewOnly\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nfun AsciiParamsSelector(\n    value: AsciiParams,\n    onValueChange: (value: AsciiParams) -> Unit,\n    itemShapes: @Composable (Int) -> Shape = {\n        ShapeDefaults.byIndex(\n            index = it,\n            size = 4\n        )\n    }\n) {\n    val filter by remember(value) {\n        derivedStateOf {\n            UiAsciiFilter(value)\n        }\n    }\n\n    AsciiParamsItem(\n        value = value,\n        filter = filter,\n        onFilterChange = onValueChange,\n        previewOnly = false,\n        isForText = true,\n        itemShape = itemShapes\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/BilaterialBlurParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BilaterialBlurParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun BilaterialBlurParamsItem(\n    value: BilaterialBlurParams,\n    filter: UiFilter<BilaterialBlurParams>,\n    onFilterChange: (value: BilaterialBlurParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.radius.toFloat()) }\n    val spatialSigma: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.spatialSigma) }\n    val rangeSigma: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.rangeSigma) }\n    val edgeMode: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.edgeMode.ordinal.toFloat()) }\n\n    LaunchedEffect(\n        radius.value,\n        spatialSigma.value,\n        rangeSigma.value,\n        edgeMode.value\n    ) {\n        onFilterChange(\n            BilaterialBlurParams(\n                radius = radius.value.toInt(),\n                spatialSigma = spatialSigma.value,\n                rangeSigma = rangeSigma.value,\n                edgeMode = BlurEdgeMode.entries[edgeMode.value.toInt()],\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> radius\n                    1 -> spatialSigma\n                    2 -> rangeSigma\n                    else -> edgeMode\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.take(3).forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n        paramsInfo[3].let { (state, info) ->\n            EdgeModeSelector(\n                title = info.title!!,\n                value = BlurEdgeMode.entries[state.value.toInt()],\n                onValueChange = { state.value = it.ordinal.toFloat() }\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/BloomParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BloomParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun BloomParamsItem(\n    value: BloomParams,\n    filter: UiFilter<BloomParams>,\n    onFilterChange: (value: BloomParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val threshold: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.threshold) }\n    val intensity: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.intensity) }\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.radius.toFloat()) }\n    val softKnee: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.softKnee) }\n    val exposure: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.exposure) }\n    val gamma: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.gamma) }\n\n    LaunchedEffect(\n        threshold.value,\n        intensity.value,\n        radius.value,\n        softKnee.value,\n        exposure.value,\n        gamma.value\n    ) {\n        onFilterChange(\n            BloomParams(\n                threshold = threshold.value,\n                intensity = intensity.value,\n                radius = radius.value.roundToInt(),\n                softKnee = softKnee.value,\n                exposure = exposure.value,\n                gamma = gamma.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> threshold\n                    1 -> intensity\n                    2 -> radius\n                    3 -> softKnee\n                    4 -> exposure\n                    else -> gamma\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/BooleanItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\ninternal fun BooleanItem(\n    value: Boolean,\n    filter: UiFilter<Boolean>,\n    onFilterChange: (value: Boolean) -> Unit,\n    previewOnly: Boolean\n) {\n    filter.paramsInfo[0].takeIf { it.title != null }\n        ?.let { (title, _, _) ->\n            PreferenceRowSwitch(\n                title = stringResource(id = title!!),\n                checked = value,\n                onClick = {\n                    onFilterChange(value)\n                },\n                modifier = Modifier.padding(\n                    top = 16.dp,\n                    start = 12.dp,\n                    end = 12.dp,\n                    bottom = 12.dp\n                ),\n                applyHorizontalPadding = false,\n                startContent = {},\n                resultModifier = Modifier.padding(\n                    horizontal = 16.dp,\n                    vertical = 8.dp\n                ),\n                enabled = !previewOnly\n            )\n        }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/ChannelMixParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ChannelMixParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun ChannelMixParamsItem(\n    value: ChannelMixParams,\n    filter: UiFilter<ChannelMixParams>,\n    onFilterChange: (value: ChannelMixParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val blueGreen: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.blueGreen.toFloat()) }\n    val redBlue: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.redBlue.toFloat()) }\n    val greenRed: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.greenRed.toFloat()) }\n    val intoR: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.intoR.toFloat()) }\n    val intoG: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.intoG.toFloat()) }\n    val intoB: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.intoB.toFloat()) }\n\n    LaunchedEffect(\n        blueGreen.value,\n        redBlue.value,\n        greenRed.value,\n        intoR.value,\n        intoG.value,\n        intoB.value\n    ) {\n        onFilterChange(\n            ChannelMixParams(\n                blueGreen = blueGreen.value.roundToInt(),\n                redBlue = redBlue.value.roundToInt(),\n                greenRed = greenRed.value.roundToInt(),\n                intoR = intoR.value.roundToInt(),\n                intoG = intoG.value.roundToInt(),\n                intoB = intoB.value.roundToInt(),\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> blueGreen\n                    1 -> redBlue\n                    2 -> greenRed\n                    3 -> intoR\n                    4 -> intoG\n                    else -> intoB\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/ClaheParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun ClaheParamsItem(\n    value: ClaheParams,\n    filter: UiFilter<ClaheParams>,\n    onFilterChange: (value: ClaheParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val threshold: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.threshold) }\n    val gridSizeHorizontal: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.gridSizeHorizontal.toFloat()) }\n    val gridSizeVertical: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.gridSizeVertical.toFloat()) }\n    val binsCount: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.binsCount.toFloat()) }\n\n    LaunchedEffect(\n        threshold.value,\n        gridSizeHorizontal.value,\n        gridSizeVertical.value,\n        binsCount.value\n    ) {\n        onFilterChange(\n            ClaheParams(\n                threshold = threshold.value,\n                gridSizeHorizontal = gridSizeHorizontal.value.toInt(),\n                gridSizeVertical = gridSizeVertical.value.toInt(),\n                binsCount = binsCount.value.toInt()\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> threshold\n                    1 -> gridSizeHorizontal\n                    2 -> gridSizeVertical\n                    else -> binsCount\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/CropOrPerspectiveParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.CropOrPerspectiveParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.FloatPair\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun CropOrPerspectiveParamsItem(\n    value: CropOrPerspectiveParams,\n    filter: UiFilter<CropOrPerspectiveParams>,\n    onFilterChange: (value: CropOrPerspectiveParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val topLeft: MutableState<FloatPair> =\n        remember(value) { mutableStateOf(value.topLeft) }\n    val topRight: MutableState<FloatPair> =\n        remember(value) { mutableStateOf(value.topRight) }\n    val bottomLeft: MutableState<FloatPair> =\n        remember(value) { mutableStateOf(value.bottomLeft) }\n    val bottomRight: MutableState<FloatPair> =\n        remember(value) { mutableStateOf(value.bottomRight) }\n    val isAbsolute: MutableState<Boolean> = remember(value) { mutableStateOf(value.isAbsolute) }\n\n    LaunchedEffect(\n        topLeft.value,\n        topRight.value,\n        bottomLeft.value,\n        bottomRight.value,\n        isAbsolute.value,\n    ) {\n        onFilterChange(\n            CropOrPerspectiveParams(\n                topLeft = topLeft.value,\n                topRight = topRight.value,\n                bottomLeft = bottomLeft.value,\n                bottomRight = bottomRight.value,\n                isAbsolute = isAbsolute.value\n            )\n        )\n    }\n\n    fun stateByIndex(index: Int) = when (index) {\n        0 -> topLeft\n        1 -> topRight\n        2 -> bottomLeft\n        else -> bottomRight\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp),\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        filter.paramsInfo.forEachIndexed { index, (title) ->\n            when (index) {\n                0, 1, 2, 3 -> {\n                    val state = stateByIndex(index)\n                    var x by remember {\n                        mutableStateOf(\n                            state.value.first.toString().trimTrailingZero()\n                        )\n                    }\n                    var y by remember {\n                        mutableStateOf(\n                            state.value.second.toString().trimTrailingZero()\n                        )\n                    }\n\n                    LaunchedEffect(x, y) {\n                        state.update {\n                            it.copy(\n                                first = x.toFloatOrNull() ?: it.first,\n                                second = y.toFloatOrNull() ?: it.second,\n                            )\n                        }\n                    }\n\n                    Column {\n                        TitleItem(\n                            text = stringResource(title!!),\n                            modifier = Modifier.padding(\n                                horizontal = 8.dp\n                            )\n                        )\n                        Spacer(Modifier.height(8.dp))\n                        Row {\n                            RoundedTextField(\n                                value = x,\n                                onValueChange = { x = it },\n                                shape = ShapeDefaults.smallStart,\n                                keyboardOptions = KeyboardOptions(\n                                    keyboardType = KeyboardType.Number\n                                ),\n                                label = {\n                                    Text(\"X\")\n                                },\n                                modifier = Modifier\n                                    .weight(1f)\n                                    .padding(\n                                        start = 8.dp,\n                                        top = 8.dp,\n                                        bottom = 8.dp,\n                                        end = 2.dp\n                                    )\n                            )\n                            RoundedTextField(\n                                value = y,\n                                onValueChange = { y = it },\n                                keyboardOptions = KeyboardOptions(\n                                    keyboardType = KeyboardType.Number\n                                ),\n                                shape = ShapeDefaults.smallEnd,\n                                label = {\n                                    Text(\"Y\")\n                                },\n                                modifier = Modifier\n                                    .weight(1f)\n                                    .padding(\n                                        start = 2.dp,\n                                        top = 8.dp,\n                                        bottom = 8.dp,\n                                        end = 8.dp\n                                    ),\n                            )\n                        }\n                    }\n                }\n\n                4 -> {\n                    PreferenceRowSwitch(\n                        title = stringResource(id = title!!),\n                        checked = isAbsolute.value,\n                        onClick = {\n                            isAbsolute.value = it\n                        },\n                        modifier = Modifier.padding(\n                            top = 8.dp,\n                            start = 4.dp,\n                            end = 4.dp\n                        ),\n                        applyHorizontalPadding = false,\n                        startContent = {},\n                        resultModifier = Modifier.padding(\n                            horizontal = 16.dp,\n                            vertical = 8.dp\n                        ),\n                        enabled = !previewOnly\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/EdgeModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.translatedName\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\n\n@Composable\ninternal fun EdgeModeSelector(\n    title: Int?,\n    value: BlurEdgeMode,\n    onValueChange: (BlurEdgeMode) -> Unit,\n) {\n    Text(\n        text = stringResource(title!!),\n        modifier = Modifier.padding(\n            top = 8.dp,\n            start = 12.dp,\n            end = 12.dp,\n        )\n    )\n    val entries = BlurEdgeMode.entries\n\n    EnhancedButtonGroup(\n        inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n        items = entries.map { it.translatedName },\n        selectedIndex = entries.indexOf(value),\n        onIndexChange = {\n            onValueChange(entries[it])\n        }\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/EnhancedZoomBlurParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.EnhancedZoomBlurParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun EnhancedZoomBlurParamsItem(\n    value: EnhancedZoomBlurParams,\n    filter: UiFilter<EnhancedZoomBlurParams>,\n    onFilterChange: (value: EnhancedZoomBlurParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.radius as Number).toFloat()) }\n    val sigma: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.sigma as Number).toFloat()) }\n    val anchorX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.centerX as Number).toFloat()) }\n    val anchorY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.centerY as Number).toFloat()) }\n    val strength: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.strength as Number).toFloat()) }\n    val angle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.angle as Number).toFloat()) }\n\n    LaunchedEffect(\n        radius.value,\n        sigma.value,\n        anchorX.value,\n        anchorY.value,\n        strength.value,\n        angle.value\n    ) {\n        onFilterChange(\n            EnhancedZoomBlurParams(\n                radius = radius.value.toInt(),\n                sigma = sigma.value,\n                centerX = anchorX.value,\n                centerY = anchorY.value,\n                strength = strength.value,\n                angle = angle.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> radius\n                    1 -> sigma\n                    2 -> anchorX\n                    3 -> anchorY\n                    4 -> strength\n                    else -> angle\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/FilterValueWrapperItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterValueWrapper\nimport com.t8rin.imagetoolbox.core.filters.domain.model.wrap\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiColorOverlayFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiRGBFilter\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRow\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\n\n@Composable\ninternal fun FilterValueWrapperItem(\n    value: FilterValueWrapper<*>,\n    filter: UiFilter<FilterValueWrapper<*>>,\n    onFilterChange: (value: FilterValueWrapper<*>) -> Unit,\n    previewOnly: Boolean\n) {\n    when (val wrapped = value.wrapped) {\n        is ColorModel -> {\n            Box(\n                modifier = Modifier.padding(\n                    start = 16.dp,\n                    end = 16.dp\n                )\n            ) {\n                ColorSelectionRow(\n                    value = remember(wrapped) {\n                        wrapped.toColor()\n                    },\n                    defaultColors = remember(filter) {\n                        derivedStateOf {\n                            ColorSelectionRowDefaults.colorList.map {\n                                if (filter is UiColorOverlayFilter) it.copy(0.5f)\n                                else it\n                            }\n                        }\n                    }.value,\n                    allowAlpha = filter !is UiRGBFilter,\n                    allowScroll = !previewOnly,\n                    onValueChange = {\n                        onFilterChange(it.toModel().wrap())\n                    }\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/FloatArrayItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport kotlin.math.absoluteValue\n\n@Composable\ninternal fun FloatArrayItem(\n    value: FloatArray,\n    filter: UiFilter<FloatArray>,\n    onFilterChange: (value: FloatArray) -> Unit,\n    previewOnly: Boolean\n) {\n    val rows = filter.paramsInfo[0].valueRange.start.toInt().absoluteValue\n    var text by rememberSaveable(value) {\n        mutableStateOf(\n            value.let {\n                var string = \"\"\n                it.forEachIndexed { index, float ->\n                    string += \"$float, \"\n                    if (index % rows == (rows - 1)) string += \"\\n\"\n                }\n                string.dropLast(3)\n            }\n        )\n    }\n    RoundedTextField(\n        enabled = !previewOnly,\n        modifier = Modifier.padding(16.dp),\n        singleLine = false,\n        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),\n        onValueChange = { text = it },\n        onLoseFocusTransformation = {\n            val matrix = filter.newInstance().value as FloatArray\n            this.trim { it.isWhitespace() }.split(\",\").mapIndexed { index, num ->\n                num.toFloatOrNull()?.let {\n                    matrix[index] = it\n                }\n            }\n            onFilterChange(matrix)\n            this\n        },\n        endIcon = {\n            EnhancedIconButton(\n                onClick = {\n                    val matrix = filter.newInstance().value as FloatArray\n                    text.trim { it.isWhitespace() }.split(\",\")\n                        .mapIndexed { index, num ->\n                            num.toFloatOrNull()?.let {\n                                matrix[index] = it\n                            }\n                        }\n                    onFilterChange(matrix)\n                }\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Done,\n                    contentDescription = \"Done\"\n                )\n            }\n        },\n        value = text,\n        label = {\n            Text(stringResource(R.string.float_array_of))\n        }\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/FloatItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSlider\n\n@Composable\ninternal fun FloatItem(\n    value: Float,\n    filter: UiFilter<Float>,\n    onFilterChange: (value: Float) -> Unit,\n    previewOnly: Boolean\n) {\n    EnhancedSlider(\n        modifier = Modifier\n            .padding(top = 16.dp, start = 12.dp, end = 12.dp, bottom = 8.dp)\n            .offset(y = (-2).dp),\n        enabled = !previewOnly,\n        value = value,\n        onValueChange = {\n            onFilterChange(it.roundTo(filter.paramsInfo.first().roundTo))\n        },\n        valueRange = filter.paramsInfo.first().valueRange\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/GlitchParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.GlitchParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun GlitchParamsItem(\n    value: GlitchParams,\n    filter: UiFilter<GlitchParams>,\n    onFilterChange: (value: GlitchParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val channelsShiftX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.channelsShiftX as Number).toFloat()) }\n    val channelsShiftY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.channelsShiftY as Number).toFloat()) }\n    val corruptionSize: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.corruptionSize as Number).toFloat()) }\n    val corruptionCount: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.corruptionCount as Number).toFloat()) }\n    val corruptionShiftX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.corruptionShiftX as Number).toFloat()) }\n    val corruptionShiftY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.corruptionShiftY as Number).toFloat()) }\n\n    LaunchedEffect(\n        channelsShiftX.value,\n        channelsShiftY.value,\n        corruptionSize.value,\n        corruptionCount.value,\n        corruptionShiftX.value,\n        corruptionShiftY.value\n    ) {\n        onFilterChange(\n            GlitchParams(\n                channelsShiftX = channelsShiftX.value,\n                channelsShiftY = channelsShiftY.value,\n                corruptionSize = corruptionSize.value,\n                corruptionCount = corruptionCount.value.toInt(),\n                corruptionShiftX = corruptionShiftX.value,\n                corruptionShiftY = corruptionShiftY.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> channelsShiftX\n                    1 -> channelsShiftY\n                    2 -> corruptionSize\n                    3 -> corruptionCount\n                    4 -> corruptionShiftX\n                    else -> corruptionShiftY\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/IntegerSizeParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport kotlinx.coroutines.delay\n\n@Composable\ninternal fun IntegerSizeParamsItem(\n    value: IntegerSize,\n    filter: UiFilter<IntegerSize>,\n    onFilterChange: (value: IntegerSize) -> Unit,\n    previewOnly: Boolean\n) {\n    var width by remember(value) { mutableIntStateOf(value.width) }\n    var height by remember(value) { mutableIntStateOf(value.height) }\n\n    val imageInfo by remember(width, height) {\n        derivedStateOf {\n            ImageInfo(\n                width = width,\n                height = height\n            )\n        }\n    }\n\n    LaunchedEffect(imageInfo) {\n        delay(500)\n        onFilterChange(\n            IntegerSize(\n                width = imageInfo.width,\n                height = imageInfo.height\n            )\n        )\n    }\n\n    ResizeImageField(\n        modifier = Modifier.padding(8.dp),\n        imageInfo = imageInfo,\n        originalSize = null,\n        onWidthChange = {\n            width = it\n        },\n        onHeightChange = {\n            height = it\n        },\n        enabled = !previewOnly\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/KaleidoscopeParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.KaleidoscopeParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport kotlin.math.roundToInt\n\n\n@Composable\ninternal fun KaleidoscopeParamsItem(\n    value: KaleidoscopeParams,\n    filter: UiFilter<KaleidoscopeParams>,\n    onFilterChange: (value: KaleidoscopeParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val angle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.angle) }\n    val angle2: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.angle2) }\n    val centreX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreX) }\n    val centreY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreY) }\n    val sides: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.sides.toFloat()) }\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.radius) }\n\n    LaunchedEffect(\n        angle.value,\n        angle2.value,\n        centreX.value,\n        centreY.value,\n        sides.value,\n        radius.value\n    ) {\n        onFilterChange(\n            KaleidoscopeParams(\n                angle = angle.value,\n                angle2 = angle2.value,\n                centreX = centreX.value,\n                centreY = centreY.value,\n                sides = sides.value.roundToInt(),\n                radius = radius.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> angle\n                    1 -> angle2\n                    2 -> centreX\n                    3 -> centreY\n                    4 -> sides\n                    else -> radius\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/LinearGaussianParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearGaussianParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun LinearGaussianParamsItem(\n    value: LinearGaussianParams,\n    filter: UiFilter<LinearGaussianParams>,\n    onFilterChange: (value: LinearGaussianParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val kernelSize: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.kernelSize.toFloat()) }\n    val sigma: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.sigma) }\n    val edgeMode: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.edgeMode.ordinal.toFloat()) }\n    val transferFunction: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.transferFunction.ordinal.toFloat()) }\n\n    LaunchedEffect(\n        kernelSize.value,\n        sigma.value,\n        edgeMode.value,\n        transferFunction.value\n    ) {\n        onFilterChange(\n            LinearGaussianParams(\n                kernelSize = kernelSize.value.toInt(),\n                sigma = sigma.value,\n                edgeMode = BlurEdgeMode.entries[edgeMode.value.toInt()],\n                transferFunction = TransferFunc.entries[transferFunction.value.toInt()]\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> kernelSize\n                    1 -> sigma\n                    2 -> edgeMode\n                    else -> transferFunction\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.take(2).forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n        paramsInfo[2].let { (state, info) ->\n            EdgeModeSelector(\n                title = info.title!!,\n                value = BlurEdgeMode.entries[state.value.toInt()],\n                onValueChange = { state.value = it.ordinal.toFloat() }\n            )\n        }\n        paramsInfo[3].let { (state, info) ->\n            TransferFuncSelector(\n                title = info.title!!,\n                value = TransferFunc.entries[state.value.toInt()],\n                onValueChange = { state.value = it.ordinal.toFloat() }\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/LinearTiltShiftParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun LinearTiltShiftParamsItem(\n    value: LinearTiltShiftParams,\n    filter: UiFilter<LinearTiltShiftParams>,\n    onFilterChange: (value: LinearTiltShiftParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val blurRadius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.blurRadius as Number).toFloat()) }\n    val sigma: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.sigma as Number).toFloat()) }\n    val anchorX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.anchorX as Number).toFloat()) }\n    val anchorY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.anchorY as Number).toFloat()) }\n    val holeRadius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.holeRadius as Number).toFloat()) }\n    val angle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.angle as Number).toFloat()) }\n\n    LaunchedEffect(\n        blurRadius.value,\n        sigma.value,\n        anchorX.value,\n        anchorY.value,\n        holeRadius.value,\n        angle.value\n    ) {\n        onFilterChange(\n            LinearTiltShiftParams(\n                blurRadius = blurRadius.value,\n                sigma = sigma.value,\n                anchorX = anchorX.value,\n                anchorY = anchorY.value,\n                holeRadius = holeRadius.value,\n                angle = angle.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> blurRadius\n                    1 -> sigma\n                    2 -> anchorX\n                    3 -> anchorY\n                    4 -> holeRadius\n                    else -> angle\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/MirrorSideSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.translatedName\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\n\n@Composable\ninternal fun MirrorSideSelector(\n    title: Int,\n    value: MirrorSide,\n    onValueChange: (MirrorSide) -> Unit,\n) {\n    Text(\n        text = stringResource(title),\n        modifier = Modifier.padding(\n            top = 8.dp,\n            start = 12.dp,\n            end = 12.dp,\n        )\n    )\n    val entries = remember {\n        MirrorSide.entries\n    }\n    EnhancedButtonGroup(\n        inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n        items = entries.map { it.translatedName },\n        selectedIndex = entries.indexOf(value),\n        onIndexChange = {\n            onValueChange(entries[it])\n        }\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/PairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.runtime.Composable\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.utils.cast\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.ColorModelPairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.FloatColorModelPairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.FloatFileModelPairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.FloatImageModelPairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.NumberBlurEdgeModePairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.NumberBooleanPairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.NumberMirrorSidePairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.NumberPairItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components.NumberTransferFuncPairItem\n\n@Composable\ninternal fun PairItem(\n    value: Pair<*, *>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<*, *>) -> Unit,\n    previewOnly: Boolean\n) {\n    when {\n        value.first is Number && value.second is Number -> {\n            NumberPairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is ColorModel && value.second is ColorModel -> {\n            ColorModelPairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Float && value.second is ColorModel -> {\n            FloatColorModelPairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Float && value.second is ImageModel -> {\n            FloatImageModelPairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Float && value.second is FileModel -> {\n            FloatFileModelPairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is Boolean -> {\n            NumberBooleanPairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is BlurEdgeMode -> {\n            NumberBlurEdgeModePairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is TransferFunc -> {\n            NumberTransferFuncPairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is MirrorSide -> {\n            NumberMirrorSidePairItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/PinchParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.PinchParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun PinchParamsItem(\n    value: PinchParams,\n    filter: UiFilter<PinchParams>,\n    onFilterChange: (value: PinchParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val angle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.angle) }\n    val centreX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreX) }\n    val centreY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreY) }\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.radius) }\n    val amount: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.amount) }\n\n    LaunchedEffect(\n        angle.value,\n        centreX.value,\n        centreY.value,\n        radius.value,\n        amount.value,\n    ) {\n        onFilterChange(\n            PinchParams(\n                angle = angle.value,\n                centreX = centreX.value,\n                centreY = centreY.value,\n                radius = radius.value,\n                amount = amount.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> angle\n                    1 -> centreX\n                    2 -> centreY\n                    3 -> radius\n                    else -> amount\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/QuadItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.runtime.Composable\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.cast\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.quad_components.NumberColorModelQuadItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.quad_components.NumberQuadItem\n\n\n@Composable\ninternal fun QuadItem(\n    value: Quad<*, *, *, *>,\n    filter: UiFilter<Quad<*, *, *, *>>,\n    onFilterChange: (value: Quad<*, *, *, *>) -> Unit,\n    previewOnly: Boolean\n) {\n    when {\n        value.first is Number && value.second is Number && value.third is Number && value.fourth is Number -> {\n            NumberQuadItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is Number && value.third is Number && value.fourth is ColorModel -> {\n            NumberColorModelQuadItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/RadialTiltShiftParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RadialTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun RadialTiltShiftParamsItem(\n    value: RadialTiltShiftParams,\n    filter: UiFilter<RadialTiltShiftParams>,\n    onFilterChange: (value: RadialTiltShiftParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val blurRadius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.blurRadius as Number).toFloat()) }\n    val sigma: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.sigma as Number).toFloat()) }\n    val anchorX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.anchorX as Number).toFloat()) }\n    val anchorY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.anchorY as Number).toFloat()) }\n    val holeRadius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf((value.holeRadius as Number).toFloat()) }\n\n    LaunchedEffect(\n        blurRadius.value,\n        sigma.value,\n        anchorX.value,\n        anchorY.value,\n        holeRadius.value\n    ) {\n        onFilterChange(\n            RadialTiltShiftParams(\n                blurRadius = blurRadius.value,\n                sigma = sigma.value,\n                anchorX = anchorX.value,\n                anchorY = anchorY.value,\n                holeRadius = holeRadius.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> blurRadius\n                    1 -> sigma\n                    2 -> anchorX\n                    3 -> anchorY\n                    else -> holeRadius\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/RubberStampParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RubberStampParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun RubberStampParamsItem(\n    value: RubberStampParams,\n    filter: UiFilter<RubberStampParams>,\n    onFilterChange: (value: RubberStampParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val threshold: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.threshold) }\n    val softness: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.softness) }\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.radius) }\n    val firstColor: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.firstColor.colorInt.toFloat()) }\n    val secondColor: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.secondColor.colorInt.toFloat()) }\n\n    LaunchedEffect(\n        threshold.value,\n        softness.value,\n        radius.value,\n        firstColor.value,\n        secondColor.value,\n    ) {\n        onFilterChange(\n            RubberStampParams(\n                threshold = threshold.value,\n                softness = softness.value,\n                radius = radius.value,\n                firstColor = firstColor.value.toInt().toColorModel(),\n                secondColor = secondColor.value.toInt().toColorModel(),\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> threshold\n                    1 -> softness\n                    2 -> radius\n                    3 -> firstColor\n                    else -> secondColor\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.take(3).forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                steps = if (valueRange == 0f..4f) 3 else 0,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n        paramsInfo[3].let { (state, info) ->\n            ColorRowSelector(\n                title = stringResource(info.title!!),\n                value = state.value.roundToInt().toColor(),\n                onValueChange = {\n                    state.value = it.toArgb().toFloat()\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 16.dp,\n                modifier = Modifier.padding(start = 4.dp)\n            )\n        }\n        paramsInfo[4].let { (state, info) ->\n            ColorRowSelector(\n                title = stringResource(info.title!!),\n                value = state.value.roundToInt().toColor(),\n                onValueChange = {\n                    state.value = it.toArgb().toFloat()\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 16.dp,\n                modifier = Modifier.padding(start = 4.dp)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/SideFadeRelativeItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SideFadeParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.translatedName\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun SideFadeRelativeItem(\n    value: SideFadeParams.Relative,\n    filter: UiFilter<SideFadeParams.Relative>,\n    onFilterChange: (value: SideFadeParams.Relative) -> Unit,\n    previewOnly: Boolean\n) {\n    var scale by remember(value) { mutableFloatStateOf(value.scale) }\n    var sideFade by remember(value) { mutableStateOf(value.side) }\n\n    LaunchedEffect(scale, sideFade) {\n        onFilterChange(\n            SideFadeParams.Relative(\n                side = sideFade,\n                scale = scale\n            )\n        )\n    }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = scale,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            scale = it\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    filter.paramsInfo[1].takeIf { it.title != null }\n        ?.let { (title, _, _) ->\n            Text(\n                text = stringResource(title!!),\n                modifier = Modifier.padding(\n                    top = 8.dp,\n                    start = 12.dp,\n                    end = 12.dp,\n                )\n            )\n            EnhancedButtonGroup(\n                inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                items = FadeSide.entries.map { it.translatedName },\n                selectedIndex = FadeSide.entries.indexOf(sideFade),\n                onIndexChange = {\n                    sideFade = FadeSide.entries[it]\n                }\n            )\n        }\n}\n\n"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/SmearParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SmearParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun SmearParamsItem(\n    value: SmearParams,\n    filter: UiFilter<SmearParams>,\n    onFilterChange: (value: SmearParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val angle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.angle) }\n    val density: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.density) }\n    val mix: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.mix) }\n    val distance: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.distance.toFloat()) }\n    val shape: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.shape.toFloat()) }\n\n    LaunchedEffect(\n        angle.value,\n        density.value,\n        mix.value,\n        distance.value,\n        shape.value\n    ) {\n        onFilterChange(\n            SmearParams(\n                angle = angle.value,\n                density = density.value,\n                mix = mix.value,\n                distance = distance.value.toInt(),\n                shape = shape.value.toInt()\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> angle\n                    1 -> density\n                    2 -> mix\n                    3 -> distance\n                    else -> shape\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.Companion.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                steps = if (valueRange == 0f..3f) 2 else 0,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/SparkleParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SparkleParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun SparkleParamsItem(\n    value: SparkleParams,\n    filter: UiFilter<SparkleParams>,\n    onFilterChange: (value: SparkleParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val amount: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.amount.toFloat()) }\n    val rays: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.rays.toFloat()) }\n    val radius: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.radius) }\n    val randomness: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.randomness.toFloat()) }\n    val centreX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreX) }\n    val centreY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.centreY) }\n    val color: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.color.colorInt.toFloat()) }\n\n    LaunchedEffect(\n        amount.value,\n        rays.value,\n        radius.value,\n        randomness.value,\n        centreX.value,\n        centreY.value,\n        color.value\n    ) {\n        onFilterChange(\n            SparkleParams(\n                amount = amount.value.toInt(),\n                rays = rays.value.toInt(),\n                radius = radius.value,\n                randomness = randomness.value.toInt(),\n                centreX = centreX.value,\n                centreY = centreY.value,\n                color = color.value.roundToInt().toColorModel()\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> amount\n                    1 -> rays\n                    2 -> radius\n                    3 -> randomness\n                    4 -> centreX\n                    5 -> centreY\n                    else -> color\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.take(6).forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n        paramsInfo[6].let { (state, info) ->\n            ColorRowSelector(\n                title = stringResource(info.title!!),\n                value = state.value.roundToInt().toColor(),\n                onValueChange = {\n                    state.value = it.toArgb().toFloat()\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 16.dp,\n                modifier = Modifier.padding(start = 4.dp)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/ToneCurvesParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.toBitmap\nimport com.t8rin.curves.ImageCurvesEditor\nimport com.t8rin.curves.ImageCurvesEditorState\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ToneCurvesParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\ninternal fun ToneCurvesParamsItem(\n    value: ToneCurvesParams,\n    filter: UiFilter<ToneCurvesParams>,\n    onFilterChange: (value: ToneCurvesParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val editorState: MutableState<ImageCurvesEditorState> =\n        remember { mutableStateOf(ImageCurvesEditorState(value.controlPoints)) }\n\n    Box(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        var bitmap by remember {\n            mutableStateOf<Bitmap?>(null)\n        }\n\n        val previewModel = LocalFilterPreviewModelProvider.current.preview\n\n        LaunchedEffect(previewModel) {\n            bitmap = appContext.imageLoader.execute(\n                ImageRequest.Builder(appContext)\n                    .data(previewModel.data)\n                    .build()\n            ).image?.toBitmap()\n        }\n\n        ImageCurvesEditor(\n            bitmap = bitmap,\n            state = editorState.value,\n            curvesSelectionText = {\n                Text(\n                    text = when (it) {\n                        0 -> stringResource(R.string.all)\n                        1 -> stringResource(R.string.color_red)\n                        2 -> stringResource(R.string.color_green)\n                        3 -> stringResource(R.string.color_blue)\n                        else -> \"\"\n                    },\n                    style = MaterialTheme.typography.bodySmall\n                )\n            },\n            imageObtainingTrigger = false,\n            onImageObtained = { },\n            //shape = ShapeDefaults.extraSmall,\n            containerModifier = Modifier.fillMaxWidth(),\n            onStateChange = {\n                onFilterChange(\n                    ToneCurvesParams(\n                        controlPoints = it.controlPoints\n                    )\n                )\n            }\n        )\n\n        if (previewOnly) {\n            Surface(\n                modifier = Modifier.matchParentSize(),\n                color = Color.Transparent,\n                content = {}\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/TransferFuncSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.translatedName\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\n\n@Composable\ninternal fun TransferFuncSelector(\n    title: Int,\n    value: TransferFunc,\n    onValueChange: (TransferFunc) -> Unit,\n) {\n    Text(\n        text = stringResource(title),\n        modifier = Modifier.padding(\n            top = 8.dp,\n            start = 12.dp,\n            end = 12.dp,\n        )\n    )\n    val entries = remember {\n        TransferFunc.entries\n    }\n    EnhancedButtonGroup(\n        inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n        items = entries.map { it.translatedName },\n        selectedIndex = entries.indexOf(value),\n        onIndexChange = {\n            onValueChange(entries[it])\n        }\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/TripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.runtime.Composable\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.utils.cast\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PaletteTransferSpace\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.ColorModelTripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.FloatPaletteImageModelTripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.NumberColorModelColorModelTripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.NumberColorModelPopArtTripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.NumberNumberBlurEdgeModeTripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.NumberNumberColorModelTripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.NumberTransferFuncBlurEdgeModeTripleItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components.NumberTripleItem\n\n@Composable\ninternal fun TripleItem(\n    value: Triple<*, *, *>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<*, *, *>) -> Unit,\n    previewOnly: Boolean\n) {\n    when {\n        value.first is Float && value.second is PaletteTransferSpace && value.third is ImageModel -> {\n            FloatPaletteImageModelTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is Number && value.third is Number -> {\n            NumberTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is Number && value.third is ColorModel -> {\n            NumberNumberColorModelTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is ColorModel && value.third is ColorModel -> {\n            NumberColorModelColorModelTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is Number && value.third is BlurEdgeMode -> {\n            NumberNumberBlurEdgeModeTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is TransferFunc && value.third is BlurEdgeMode -> {\n            NumberTransferFuncBlurEdgeModeTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is ColorModel && value.second is ColorModel && value.third is ColorModel -> {\n            ColorModelTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n\n        value.first is Number && value.second is ColorModel && value.third is PopArtBlendingMode -> {\n            NumberColorModelPopArtTripleItem(\n                value = value.cast(),\n                filter = filter,\n                onFilterChange = onFilterChange,\n                previewOnly = previewOnly\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/VoronoiCrystallizeParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun VoronoiCrystallizeParamsItem(\n    value: VoronoiCrystallizeParams,\n    filter: UiFilter<VoronoiCrystallizeParams>,\n    onFilterChange: (value: VoronoiCrystallizeParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val borderThickness: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.borderThickness) }\n    val scale: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.scale) }\n    val randomness: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.randomness) }\n    val shape: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.shape.toFloat()) }\n    val turbulence: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.turbulence) }\n    val angle: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.angle) }\n    val stretch: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.stretch) }\n    val amount: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.amount) }\n    val color: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.color.colorInt.toFloat()) }\n\n    LaunchedEffect(\n        borderThickness.value,\n        scale.value,\n        randomness.value,\n        shape.value,\n        turbulence.value,\n        angle.value,\n        stretch.value,\n        amount.value,\n        color.value\n    ) {\n        onFilterChange(\n            VoronoiCrystallizeParams(\n                borderThickness = borderThickness.value,\n                scale = scale.value,\n                randomness = randomness.value,\n                shape = shape.value.roundToInt(),\n                turbulence = turbulence.value,\n                angle = angle.value,\n                stretch = stretch.value,\n                amount = amount.value,\n                color = color.value.roundToInt().toColorModel()\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> borderThickness\n                    1 -> scale\n                    2 -> randomness\n                    3 -> shape\n                    4 -> turbulence\n                    5 -> angle\n                    6 -> stretch\n                    7 -> amount\n                    else -> color\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.take(8).forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                steps = if (valueRange == 0f..4f) 3 else 0,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n        paramsInfo[8].let { (state, info) ->\n            ColorRowSelector(\n                title = stringResource(info.title!!),\n                value = state.value.roundToInt().toColor(),\n                onValueChange = {\n                    state.value = it.toArgb().toFloat()\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 16.dp,\n                modifier = Modifier.padding(start = 4.dp)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/WaterParamsItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.WaterParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun WaterParamsItem(\n    value: WaterParams,\n    filter: UiFilter<WaterParams>,\n    onFilterChange: (value: WaterParams) -> Unit,\n    previewOnly: Boolean\n) {\n    val fractionSize: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.fractionSize) }\n    val frequencyX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.frequencyX) }\n    val frequencyY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.frequencyY) }\n    val amplitudeX: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.amplitudeX) }\n    val amplitudeY: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.amplitudeY) }\n\n    LaunchedEffect(\n        fractionSize.value,\n        frequencyX.value,\n        frequencyY.value,\n        amplitudeX.value,\n        amplitudeY.value\n    ) {\n        onFilterChange(\n            WaterParams(\n                fractionSize = fractionSize.value,\n                frequencyX = frequencyX.value,\n                frequencyY = frequencyY.value,\n                amplitudeX = amplitudeX.value,\n                amplitudeY = amplitudeY.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> fractionSize\n                    1 -> frequencyX\n                    2 -> frequencyY\n                    3 -> amplitudeX\n                    else -> amplitudeY\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/ColorModelPairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\n\n@Composable\ninternal fun ColorModelPairItem(\n    value: Pair<ColorModel, ColorModel>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<ColorModel, ColorModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    Box(\n        modifier = Modifier.padding(\n            start = 16.dp,\n            top = 16.dp,\n            end = 16.dp\n        )\n    ) {\n        var color1 by remember(value) { mutableStateOf(value.first.toColor()) }\n        var color2 by remember(value) { mutableStateOf(value.second.toColor()) }\n\n        Column {\n            ColorRowSelector(\n                title = stringResource(R.string.first_color),\n                value = color1,\n                onValueChange = {\n                    color1 = it\n                    onFilterChange(color1.toModel() to color2.toModel())\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n            Spacer(Modifier.height(8.dp))\n            ColorRowSelector(\n                title = stringResource(R.string.second_color),\n                value = color2,\n                onValueChange = {\n                    color2 = it\n                    onFilterChange(color1.toModel() to color2.toModel())\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/FloatColorModelPairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun FloatColorModelPairItem(\n    value: Pair<Float, ColorModel>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Float, ColorModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember { mutableFloatStateOf(value.first) }\n    var color1 by remember(value) { mutableStateOf(value.second.toColor()) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(sliderState1 to color1.toModel())\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    Box(\n        modifier = Modifier.padding(\n            start = 16.dp,\n            end = 16.dp\n        )\n    ) {\n        ColorRowSelector(\n            title = stringResource(filter.paramsInfo[1].title!!),\n            value = color1,\n            onValueChange = {\n                color1 = it\n                onFilterChange(sliderState1 to color1.toModel())\n            },\n            allowScroll = !previewOnly,\n            icon = null,\n            defaultColors = ColorSelectionRowDefaults.colorList,\n            contentHorizontalPadding = 0.dp,\n            modifier = Modifier.padding(start = 4.dp)\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/FloatFileModelPairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.Icon\nimport androidx.compose.material.Text\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.LENS_PROFILES_LINK\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Github\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FileSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.utils.toFileModel\n\n@Composable\ninternal fun FloatFileModelPairItem(\n    value: Pair<Float, FileModel>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Float, FileModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember { mutableFloatStateOf(value.first) }\n    var uri1 by remember(value) { mutableStateOf(value.second.uri) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(sliderState1 to uri1.toFileModel())\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    FileSelector(\n        modifier = Modifier.padding(16.dp),\n        value = uri1,\n        title = filter.paramsInfo[1].title?.let {\n            stringResource(it)\n        } ?: stringResource(R.string.pick_file),\n        onValueChange = {\n            uri1 = it.toString()\n            onFilterChange(sliderState1 to uri1.toFileModel())\n        },\n        subtitle = null\n    )\n\n    if (filter is Filter.LensCorrection) {\n        val linkHandler = LocalUriHandler.current\n\n        EnhancedButton(\n            onClick = {\n                linkHandler.openUri(LENS_PROFILES_LINK)\n            },\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 16.dp)\n                .padding(bottom = 16.dp)\n                .height(44.dp),\n            containerColor = MaterialTheme.colorScheme.secondary\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.Github,\n                contentDescription = null\n            )\n            Spacer(Modifier.width(8.dp))\n            Text(\n                text = stringResource(R.string.download_ready_lens_profiles),\n                modifier = Modifier.weight(1f, false)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/FloatImageModelPairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.utils.toImageModel\n\n@Composable\ninternal fun FloatImageModelPairItem(\n    value: Pair<Float, ImageModel>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Float, ImageModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember { mutableFloatStateOf(value.first) }\n    var uri1 by remember(value) { mutableStateOf(value.second.data) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(sliderState1 to uri1.toImageModel())\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    ImageSelector(\n        modifier = Modifier.padding(16.dp),\n        value = uri1,\n        title = filter.paramsInfo[1].title?.let {\n            stringResource(it)\n        } ?: stringResource(R.string.image),\n        onValueChange = {\n            uri1 = it.toString()\n            onFilterChange(sliderState1 to uri1.toImageModel())\n        },\n        subtitle = null\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/NumberBlurEdgeModePairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.EdgeModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberBlurEdgeModePairItem(\n    value: Pair<Number, BlurEdgeMode>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Number, BlurEdgeMode>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    var edgeMode by remember(value) { mutableStateOf(value.second) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(sliderState1 to edgeMode)\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    filter.paramsInfo[1].title?.let { title ->\n        EdgeModeSelector(\n            title = title,\n            value = edgeMode,\n            onValueChange = {\n                edgeMode = it\n                onFilterChange(sliderState1 to edgeMode)\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/NumberBooleanPairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\ninternal fun NumberBooleanPairItem(\n    value: Pair<Number, Boolean>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Number, Boolean>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    var booleanState2 by remember(value) { mutableStateOf(value.second) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(sliderState1 to booleanState2)\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    filter.paramsInfo[1].takeIf { it.title != null }\n        ?.let { (title, _, _) ->\n            PreferenceRowSwitch(\n                title = stringResource(id = title!!),\n                checked = booleanState2,\n                onClick = {\n                    booleanState2 = it\n                    onFilterChange(sliderState1 to it)\n                },\n                modifier = Modifier.padding(\n                    top = 16.dp,\n                    start = 12.dp,\n                    end = 12.dp,\n                    bottom = 12.dp\n                ),\n                applyHorizontalPadding = false,\n                startContent = {},\n                resultModifier = Modifier.padding(\n                    horizontal = 16.dp,\n                    vertical = 8.dp\n                )\n            )\n        }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/NumberMirrorSidePairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.MirrorSideSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberMirrorSidePairItem(\n    value: Pair<Number, MirrorSide>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Number, MirrorSide>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    var mirrorSide by remember(value) { mutableStateOf(value.second) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(sliderState1 to mirrorSide)\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    filter.paramsInfo[1].title?.let { title ->\n        MirrorSideSelector(\n            title = title,\n            value = mirrorSide,\n            onValueChange = {\n                mirrorSide = it\n                onFilterChange(sliderState1 to mirrorSide)\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/NumberPairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberPairItem(\n    value: Pair<Number, Number>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Number, Number>) -> Unit,\n    previewOnly: Boolean\n) {\n    val sliderState1: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    val sliderState2: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.second.toFloat()) }\n\n    LaunchedEffect(\n        sliderState1.value,\n        sliderState2.value\n    ) {\n        onFilterChange(\n            sliderState1.value to sliderState2.value\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> sliderState1\n                    else -> sliderState2\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/pair_components/NumberTransferFuncPairItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.pair_components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.TransferFuncSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberTransferFuncPairItem(\n    value: Pair<Number, TransferFunc>,\n    filter: UiFilter<Pair<*, *>>,\n    onFilterChange: (value: Pair<Number, TransferFunc>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    var transferFunction by remember(value) { mutableStateOf(value.second) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(sliderState1 to transferFunction)\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    filter.paramsInfo[1].title?.let { title ->\n        TransferFuncSelector(\n            title = title,\n            value = transferFunction,\n            onValueChange = {\n                transferFunction = it\n                onFilterChange(sliderState1 to transferFunction)\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/quad_components/NumberColorModelQuadItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.quad_components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n\n@Composable\ninternal fun NumberColorModelQuadItem(\n    value: Quad<Number, Number, Number, ColorModel>,\n    filter: UiFilter<Quad<*, *, *, *>>,\n    onFilterChange: (Quad<Number, Number, Number, ColorModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    val sliderState1: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    val sliderState2: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.second.toFloat()) }\n    val sliderState3: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.third.toFloat()) }\n    var color4 by remember(value) { mutableStateOf(value.fourth.toColor()) }\n\n    LaunchedEffect(\n        sliderState1.value,\n        sliderState2.value,\n        sliderState3.value,\n        color4\n    ) {\n        onFilterChange(\n            Quad(\n                first = sliderState1.value,\n                second = sliderState2.value,\n                third = sliderState3.value,\n                fourth = color4.toModel()\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null || index > 2) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> sliderState1\n                    1 -> sliderState2\n                    else -> sliderState3\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(\n            top = 8.dp,\n            start = 8.dp,\n            end = 8.dp\n        )\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n\n    ColorRowSelector(\n        title = stringResource(filter.paramsInfo[3].title!!),\n        value = color4,\n        onValueChange = {\n            color4 = it\n        },\n        allowScroll = !previewOnly,\n        icon = null,\n        defaultColors = ColorSelectionRowDefaults.colorList,\n        contentHorizontalPadding = 16.dp,\n        modifier = Modifier.padding(start = 4.dp)\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/quad_components/NumberQuadItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.quad_components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberQuadItem(\n    value: Quad<Number, Number, Number, Number>,\n    filter: UiFilter<Quad<*, *, *, *>>,\n    onFilterChange: (Quad<Number, Number, Number, Number>) -> Unit,\n    previewOnly: Boolean\n) {\n    val sliderState1: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    val sliderState2: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.second.toFloat()) }\n    val sliderState3: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.third.toFloat()) }\n    val sliderState4: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.fourth.toFloat()) }\n\n    LaunchedEffect(\n        sliderState1.value,\n        sliderState2.value,\n        sliderState3.value,\n        sliderState4.value\n    ) {\n        onFilterChange(\n            Quad(\n                sliderState1.value,\n                sliderState2.value,\n                sliderState3.value,\n                sliderState4.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> sliderState1\n                    1 -> sliderState2\n                    2 -> sliderState3\n                    else -> sliderState4\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/ColorModelTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\n\n@Composable\ninternal fun ColorModelTripleItem(\n    value: Triple<ColorModel, ColorModel, ColorModel>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<ColorModel, ColorModel, ColorModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    Box(\n        modifier = Modifier.padding(\n            start = 16.dp,\n            top = 16.dp,\n            end = 16.dp\n        )\n    ) {\n        var color1 by remember(value) { mutableStateOf(value.first.toColor()) }\n        var color2 by remember(value) { mutableStateOf(value.second.toColor()) }\n        var color3 by remember(value) { mutableStateOf(value.third.toColor()) }\n\n        Column {\n            ColorRowSelector(\n                title = stringResource(R.string.first_color),\n                value = color1,\n                onValueChange = {\n                    color1 = it\n                    onFilterChange(\n                        Triple(\n                            color1.toModel(),\n                            color2.toModel(),\n                            color3.toModel()\n                        )\n                    )\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n            Spacer(Modifier.height(8.dp))\n            ColorRowSelector(\n                title = stringResource(R.string.second_color),\n                value = color2,\n                onValueChange = {\n                    color2 = it\n                    onFilterChange(\n                        Triple(\n                            color1.toModel(),\n                            color2.toModel(),\n                            color3.toModel()\n                        )\n                    )\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n            Spacer(Modifier.height(8.dp))\n            ColorRowSelector(\n                title = stringResource(R.string.third_color),\n                value = color3,\n                onValueChange = {\n                    color3 = it\n                    onFilterChange(\n                        Triple(\n                            color1.toModel(),\n                            color2.toModel(),\n                            color3.toModel()\n                        )\n                    )\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/FloatPaletteImageModelTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PaletteTransferSpace\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.translatedName\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.utils.toImageModel\n\n@Composable\ninternal fun FloatPaletteImageModelTripleItem(\n    value: Triple<Float, PaletteTransferSpace, ImageModel>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<Float, PaletteTransferSpace, ImageModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember { mutableFloatStateOf(value.first) }\n    var colorSpace1 by remember { mutableStateOf(value.second) }\n    var uri1 by remember(value) { mutableStateOf(value.third.data) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(\n                Triple(\n                    sliderState1,\n                    colorSpace1,\n                    uri1.toImageModel()\n                )\n            )\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    Spacer(Modifier.height(8.dp))\n    Column(\n        modifier = Modifier\n            .padding(horizontal = 16.dp)\n            .container(\n                shape = ShapeDefaults.top,\n                color = MaterialTheme.colorScheme.surfaceContainerLow\n            )\n    ) {\n        Text(\n            text = stringResource(filter.paramsInfo[1].title!!),\n            modifier = Modifier.padding(\n                top = 8.dp,\n                start = 12.dp,\n                end = 12.dp,\n            )\n        )\n        val entries by remember(filter) {\n            derivedStateOf {\n                PaletteTransferSpace.entries\n            }\n        }\n        EnhancedButtonGroup(\n            inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n            items = entries.map { it.translatedName },\n            selectedIndex = entries.indexOf(colorSpace1),\n            onIndexChange = {\n                colorSpace1 = entries[it]\n                onFilterChange(\n                    Triple(\n                        sliderState1,\n                        colorSpace1,\n                        uri1.toImageModel()\n                    )\n                )\n            }\n        )\n    }\n    Spacer(Modifier.height(4.dp))\n    ImageSelector(\n        modifier = Modifier.padding(\n            horizontal = 16.dp\n        ),\n        value = uri1,\n        title = filter.paramsInfo[2].title?.let {\n            stringResource(it)\n        } ?: stringResource(R.string.image),\n        onValueChange = {\n            uri1 = it.toString()\n            onFilterChange(\n                Triple(\n                    sliderState1,\n                    colorSpace1,\n                    uri1.toImageModel()\n                )\n            )\n        },\n        subtitle = null,\n        shape = ShapeDefaults.bottom\n    )\n    Spacer(Modifier.height(16.dp))\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/NumberColorModelColorModelTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberColorModelColorModelTripleItem(\n    value: Triple<Number, ColorModel, ColorModel>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<Number, ColorModel, ColorModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember { mutableFloatStateOf(value.first.toFloat()) }\n    var color1 by remember(value) { mutableStateOf(value.second.toColor()) }\n    var color2 by remember(value) { mutableStateOf(value.third.toColor()) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(\n                Triple(\n                    sliderState1,\n                    color1.toModel(),\n                    color2.toModel()\n                )\n            )\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    Box(\n        modifier = Modifier.padding(\n            start = 16.dp,\n            top = 16.dp,\n            end = 16.dp\n        )\n    ) {\n        Column {\n            ColorRowSelector(\n                title = stringResource(filter.paramsInfo[1].title!!),\n                value = color1,\n                onValueChange = {\n                    color1 = it\n                    onFilterChange(\n                        Triple(\n                            sliderState1,\n                            color1.toModel(),\n                            color2.toModel()\n                        )\n                    )\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n            Spacer(Modifier.height(8.dp))\n            ColorRowSelector(\n                title = stringResource(filter.paramsInfo[2].title!!),\n                value = color2,\n                onValueChange = {\n                    color2 = it\n                    onFilterChange(\n                        Triple(\n                            sliderState1,\n                            color1.toModel(),\n                            color2.toModel()\n                        )\n                    )\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/NumberColorModelPopArtTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.translatedName\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberColorModelPopArtTripleItem(\n    value: Triple<Number, ColorModel, PopArtBlendingMode>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<Number, ColorModel, PopArtBlendingMode>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember { mutableFloatStateOf(value.first.toFloat()) }\n    var color1 by remember(value) { mutableStateOf(value.second.toColor()) }\n    var blendMode1 by remember(value) { mutableStateOf(value.third) }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n            onFilterChange(\n                Triple(\n                    sliderState1,\n                    color1.toModel(),\n                    blendMode1\n                )\n            )\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    Box(\n        modifier = Modifier.padding(\n            start = 16.dp,\n            top = 16.dp,\n            end = 16.dp\n        )\n    ) {\n        Column {\n            ColorRowSelector(\n                title = stringResource(filter.paramsInfo[1].title!!),\n                value = color1,\n                onValueChange = {\n                    color1 = it\n                    onFilterChange(\n                        Triple(\n                            sliderState1,\n                            color1.toModel(),\n                            blendMode1\n                        )\n                    )\n                },\n                allowScroll = !previewOnly,\n                icon = null,\n                defaultColors = ColorSelectionRowDefaults.colorList,\n                contentHorizontalPadding = 0.dp\n            )\n            Text(\n                text = stringResource(filter.paramsInfo[2].title!!),\n                modifier = Modifier.padding(\n                    top = 8.dp,\n                    start = 12.dp,\n                    end = 12.dp,\n                )\n            )\n            val entries by remember(filter) {\n                derivedStateOf {\n                    PopArtBlendingMode.entries\n                }\n            }\n            EnhancedButtonGroup(\n                inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                items = entries.map { it.translatedName },\n                selectedIndex = entries.indexOf(blendMode1),\n                onIndexChange = {\n                    blendMode1 = entries[it]\n                    onFilterChange(\n                        Triple(\n                            sliderState1,\n                            color1.toModel(),\n                            blendMode1\n                        )\n                    )\n                }\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/NumberNumberBlurEdgeModeTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.EdgeModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberNumberBlurEdgeModeTripleItem(\n    value: Triple<Number, Number, BlurEdgeMode>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<Number, Number, BlurEdgeMode>) -> Unit,\n    previewOnly: Boolean\n) {\n    val sliderState1: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    val sliderState2: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.second.toFloat()) }\n    var edgeMode by remember(value) { mutableStateOf(value.third) }\n\n    LaunchedEffect(\n        sliderState1.value,\n        sliderState2.value,\n        edgeMode\n    ) {\n        onFilterChange(\n            Triple(sliderState1.value, sliderState2.value, edgeMode)\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null || index > 1) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> sliderState1\n                    else -> sliderState2\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n    filter.paramsInfo[2].title?.let { title ->\n        EdgeModeSelector(\n            title = title,\n            value = edgeMode,\n            onValueChange = { edgeMode = it }\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/NumberNumberColorModelTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberNumberColorModelTripleItem(\n    value: Triple<Number, Number, ColorModel>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<Number, Number, ColorModel>) -> Unit,\n    previewOnly: Boolean\n) {\n    val sliderState1: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    val sliderState2: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.second.toFloat()) }\n    var color3 by remember(value) { mutableStateOf(value.third.toColor()) }\n\n    LaunchedEffect(\n        sliderState1.value,\n        sliderState2.value,\n        color3\n    ) {\n        onFilterChange(\n            Triple(sliderState1.value, sliderState2.value, color3.toModel())\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null || index > 1) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> sliderState1\n                    else -> sliderState2\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(\n            top = 8.dp,\n            start = 8.dp,\n            end = 8.dp\n        )\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n\n    ColorRowSelector(\n        title = stringResource(filter.paramsInfo[2].title!!),\n        value = color3,\n        onValueChange = {\n            color3 = it\n        },\n        allowScroll = !previewOnly,\n        icon = null,\n        defaultColors = ColorSelectionRowDefaults.colorList,\n        contentHorizontalPadding = 16.dp,\n        modifier = Modifier.padding(start = 4.dp)\n    )\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/NumberTransferFuncBlurEdgeModeTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.EdgeModeSelector\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.TransferFuncSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberTransferFuncBlurEdgeModeTripleItem(\n    value: Triple<Number, TransferFunc, BlurEdgeMode>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<Number, TransferFunc, BlurEdgeMode>) -> Unit,\n    previewOnly: Boolean\n) {\n    var sliderState1 by remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    var transferFunction by remember(value) { mutableStateOf(value.second) }\n    var edgeMode by remember(value) { mutableStateOf(value.third) }\n\n    LaunchedEffect(\n        sliderState1,\n        transferFunction,\n        edgeMode\n    ) {\n        onFilterChange(\n            Triple(sliderState1, transferFunction, edgeMode)\n        )\n    }\n\n    EnhancedSliderItem(\n        modifier = Modifier\n            .padding(\n                top = 8.dp,\n                start = 8.dp,\n                end = 8.dp\n            ),\n        enabled = !previewOnly,\n        value = sliderState1,\n        title = filter.paramsInfo[0].title?.let {\n            stringResource(it)\n        } ?: \"\",\n        onValueChange = {\n            sliderState1 = it\n        },\n        internalStateTransformation = {\n            it.roundTo(filter.paramsInfo[0].roundTo)\n        },\n        valueRange = filter.paramsInfo[0].valueRange,\n        behaveAsContainer = false\n    )\n    filter.paramsInfo[1].title?.let { title ->\n        TransferFuncSelector(\n            title = title,\n            value = transferFunction,\n            onValueChange = { transferFunction = it }\n        )\n    }\n    filter.paramsInfo[2].title?.let { title ->\n        EdgeModeSelector(\n            title = title,\n            value = edgeMode,\n            onValueChange = { edgeMode = it }\n        )\n    }\n}"
  },
  {
    "path": "core/filters/src/main/java/com/t8rin/imagetoolbox/core/filters/presentation/widget/filterItem/triple_components/NumberTripleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.triple_components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\ninternal fun NumberTripleItem(\n    value: Triple<Number, Number, Number>,\n    filter: UiFilter<Triple<*, *, *>>,\n    onFilterChange: (value: Triple<Number, Number, Number>) -> Unit,\n    previewOnly: Boolean\n) {\n    val sliderState1: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.first.toFloat()) }\n    val sliderState2: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.second.toFloat()) }\n    val sliderState3: MutableState<Float> =\n        remember(value) { mutableFloatStateOf(value.third.toFloat()) }\n\n    LaunchedEffect(\n        sliderState1.value,\n        sliderState2.value,\n        sliderState3.value\n    ) {\n        onFilterChange(\n            Triple(\n                sliderState1.value,\n                sliderState2.value,\n                sliderState3.value\n            )\n        )\n    }\n\n    val paramsInfo by remember(filter) {\n        derivedStateOf {\n            filter.paramsInfo.mapIndexedNotNull { index, filterParam ->\n                if (filterParam.title == null) return@mapIndexedNotNull null\n                when (index) {\n                    0 -> sliderState1\n                    1 -> sliderState2\n                    else -> sliderState3\n                } to filterParam\n            }\n        }\n    }\n\n    Column(\n        modifier = Modifier.padding(8.dp)\n    ) {\n        paramsInfo.forEach { (state, info) ->\n            val (title, valueRange, roundTo) = info\n            EnhancedSliderItem(\n                enabled = !previewOnly,\n                value = state.value,\n                title = stringResource(title!!),\n                valueRange = valueRange,\n                onValueChange = {\n                    state.value = it\n                },\n                internalStateTransformation = {\n                    it.roundTo(roundTo)\n                },\n                behaveAsContainer = false\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ksp/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/ksp/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    kotlin(\"jvm\")\n    id(\"com.google.devtools.ksp\")\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib\"))\n    implementation(libs.symbol.processing.api)\n}"
  },
  {
    "path": "core/ksp/src/main/java/com/t8rin/imagetoolbox/core/ksp/annotations/FilterInject.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ksp.annotations\n\n@Target(AnnotationTarget.CLASS)\n@Retention(AnnotationRetention.SOURCE)\nannotation class FilterInject"
  },
  {
    "path": "core/ksp/src/main/java/com/t8rin/imagetoolbox/core/ksp/annotations/UiFilterInject.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ksp.annotations\n\n@Target(AnnotationTarget.CLASS)\n@Retention(AnnotationRetention.SOURCE)\nannotation class UiFilterInject(\n    val group: String = Groups.UNSPECIFIED\n) {\n    object Groups {\n        const val SIMPLE = \"Simple\"\n        const val COLOR = \"Color\"\n        const val LUT = \"LUT\"\n        const val LIGHT = \"Light\"\n        const val EFFECTS = \"Effects\"\n        const val BLUR = \"Blur\"\n        const val PIXELATION = \"Pixelation\"\n        const val DISTORTION = \"Distortion\"\n        const val DITHERING = \"Dithering\"\n        const val UNSPECIFIED = \"Unspecified\"\n    }\n}\n"
  },
  {
    "path": "core/ksp/src/main/java/com/t8rin/imagetoolbox/core/ksp/processor/FilterInjectProcessor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.core.ksp.processor\n\nimport com.google.devtools.ksp.processing.Dependencies\nimport com.google.devtools.ksp.processing.Resolver\nimport com.google.devtools.ksp.processing.SymbolProcessor\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport com.google.devtools.ksp.symbol.KSAnnotated\nimport com.google.devtools.ksp.symbol.KSClassDeclaration\n\ninternal class FilterInjectProcessor : SymbolProcessorProvider {\n    override fun create(\n        environment: SymbolProcessorEnvironment\n    ): SymbolProcessor = FilterInjectProcessorImpl(environment)\n}\n\nprivate class FilterInjectProcessorImpl(\n    environment: SymbolProcessorEnvironment\n) : SymbolProcessor {\n\n    private val logger = environment.logger\n    private val codegen = environment.codeGenerator\n\n    override fun process(resolver: Resolver): List<KSAnnotated> {\n        logger.warn(\"START generation of filter map\")\n        val annotationFqn = \"$PACKAGE.core.ksp.annotations.FilterInject\"\n\n        val annotated = resolver.getSymbolsWithAnnotation(annotationFqn)\n            .filterIsInstance<KSClassDeclaration>()\n            .sortedBy { it.simpleName.asString() }\n            .toList()\n\n        if (annotated.isEmpty()) {\n            logger.warn(\"No annotated classes found\")\n            return emptyList()\n        }\n\n        val fileName = \"FilterMappings\"\n        val packageName = \"$PACKAGE.generated\"\n        val files = annotated.mapNotNull { it.containingFile }.toTypedArray()\n\n        val file = codegen.createNewFile(\n            dependencies = Dependencies(false, *files),\n            packageName = packageName,\n            fileName = fileName\n        )\n\n        file.bufferedWriter().use { writer ->\n            writer.apply {\n                appendLine(\"// Generated by KSP — do not edit\")\n                appendLine(\"package $PACKAGE.generated\")\n                appendLine()\n                appendLine(\"import android.graphics.Bitmap\")\n                appendLine(\"import $PACKAGE.core.domain.transformation.*\")\n                appendLine(\"import $PACKAGE.feature.filters.data.model.*\")\n                appendLine(\"import $PACKAGE.core.filters.domain.model.*\")\n                appendLine()\n                appendLine(\"internal fun mapFilter(filter: Filter<*>): Transformation<Bitmap> = filter.run {\")\n                appendLine(\"    when (this) {\")\n\n                annotated.forEach { filter ->\n                    val filterName = filter.simpleName.asString()\n                    appendLine(\"        is Filter.${filterName.removeSuffix(\"Filter\")} -> ${filterName}(value)\")\n                }\n\n                appendLine()\n                appendLine(\"        else -> throw IllegalArgumentException(\\\"No filter implementation for interface \\${this::class.simpleName}\\\")\")\n                appendLine(\"    }\")\n                appendLine(\"}\")\n            }\n        }\n\n        logger.info(\"FilterMappings generated successfully\")\n\n        return emptyList()\n    }\n\n    companion object {\n        private const val PACKAGE = \"com.t8rin.imagetoolbox\"\n    }\n}"
  },
  {
    "path": "core/ksp/src/main/java/com/t8rin/imagetoolbox/core/ksp/processor/UiFilterInjectProcessor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.core.ksp.processor\n\nimport com.google.devtools.ksp.processing.Dependencies\nimport com.google.devtools.ksp.processing.KSPLogger\nimport com.google.devtools.ksp.processing.Resolver\nimport com.google.devtools.ksp.processing.SymbolProcessor\nimport com.google.devtools.ksp.processing.SymbolProcessorEnvironment\nimport com.google.devtools.ksp.processing.SymbolProcessorProvider\nimport com.google.devtools.ksp.symbol.KSAnnotated\nimport com.google.devtools.ksp.symbol.KSClassDeclaration\nimport com.google.devtools.ksp.symbol.KSType\nimport com.google.devtools.ksp.symbol.Variance\nimport com.t8rin.imagetoolbox.core.ksp.annotations.UiFilterInject\n\ninternal class UiFilterInjectProcessor : SymbolProcessorProvider {\n    override fun create(\n        environment: SymbolProcessorEnvironment\n    ): SymbolProcessor = UiFilterInjectProcessorImpl(environment)\n}\n\nprivate class UiFilterInjectProcessorImpl(\n    environment: SymbolProcessorEnvironment\n) : SymbolProcessor {\n\n    private val logger = environment.logger\n    private val codegen = environment.codeGenerator\n\n    private var generated = false\n\n    override fun process(resolver: Resolver): List<KSAnnotated> {\n        if (generated) return emptyList()\n\n        val annotationFqn = \"$PACKAGE.core.ksp.annotations.UiFilterInject\"\n\n        val annotated = resolver.getSymbolsWithAnnotation(annotationFqn)\n            .filterIsInstance<KSClassDeclaration>()\n            .sortedBy { it.simpleName.asString() }\n            .toList()\n\n        if (annotated.isEmpty()) return emptyList()\n\n        val entries = annotated.mapNotNull { declaration ->\n            declaration.toUiFilterEntry(annotationFqn, logger)\n        }\n\n        if (entries.isEmpty()) return emptyList()\n\n        val duplicates = entries.groupBy { it.filterInterface }\n            .filterValues { it.size > 1 }\n        if (duplicates.isNotEmpty()) {\n            duplicates.forEach { (filterInterface, declarations) ->\n                logger.error(\n                    \"Multiple UiFilters mapped to $filterInterface: \" +\n                            declarations.joinToString { it.uiClassName }\n                )\n            }\n            return emptyList()\n        }\n\n        val file = codegen.createNewFile(\n            dependencies = Dependencies(\n                aggregating = false,\n                *annotated.mapNotNull { it.containingFile }.toTypedArray()\n            ),\n            packageName = GENERATED_PACKAGE,\n            fileName = GENERATED_FILE\n        )\n\n        file.bufferedWriter().use { writer ->\n            writer.apply {\n                appendLine(\"// Generated by KSP — do not edit\")\n                appendLine(\"package $GENERATED_PACKAGE\")\n                appendLine()\n                appendLine(\"import $PACKAGE.core.filters.domain.model.Filter\")\n                appendLine(\"import $PACKAGE.core.filters.presentation.model.*\")\n                appendLine()\n\n                appendCopyFunction(entries)\n                appendLine()\n                appendNewInstanceFunction(entries)\n                appendLine()\n                appendToUiMapping(entries)\n                appendLine()\n                appendGroupFactories(entries)\n            }\n        }\n\n        generated = true\n        return emptyList()\n    }\n\n    private fun Appendable.appendCopyFunction(entries: List<UiFilterEntry>) {\n        appendLine(\"@Suppress(\\\"UNCHECKED_CAST\\\")\")\n        appendLine(\"internal fun copyUiFilterInstance(\")\n        appendLine(\"    filter: UiFilter<*>,\")\n        appendLine(\"    newValue: Any\")\n        appendLine(\"): UiFilter<*> = when (filter) {\")\n\n        entries.forEach { entry ->\n            val fallback = entry.defaultConstructorCall(receiverName = \"filter\")\n            val line = if (entry.valueType != null) {\n                \"    is ${entry.uiClassName} -> runCatching { ${entry.uiClassName}(newValue as ${entry.valueType}) }.getOrElse { $fallback }\"\n            } else {\n                \"    is ${entry.uiClassName} -> $fallback\"\n            }\n            appendLine(line)\n        }\n\n        appendLine(\"    else -> error(\\\"No copy mapping for \\${filter::class.qualifiedName}\\\")\")\n        appendLine(\"}.also { copied ->\")\n        appendLine(\"    copied.isVisible = filter.isVisible\")\n        appendLine(\"}\")\n    }\n\n    private fun Appendable.appendNewInstanceFunction(entries: List<UiFilterEntry>) {\n        appendLine(\"internal fun newUiFilterInstance(filter: UiFilter<*>): UiFilter<*> = when (filter) {\")\n\n        entries.forEach { entry ->\n            appendLine(\"    is ${entry.uiClassName} -> ${entry.defaultConstructorCall(receiverName = \"filter\")}\")\n        }\n\n        appendLine(\"    else -> error(\\\"No newInstance mapping for \\${filter::class.qualifiedName}\\\")\")\n        appendLine(\"}.also { instance ->\")\n        appendLine(\"    if (filter.value is Unit) {\")\n        appendLine(\"        instance.isVisible = filter.isVisible\")\n        appendLine(\"    }\")\n        appendLine(\"}\")\n    }\n\n    private fun Appendable.appendToUiMapping(entries: List<UiFilterEntry>) {\n        appendLine(\"internal fun mapFilterToUiFilter(\")\n        appendLine(\"    filter: Filter<*>,\")\n        appendLine(\"    preserveVisibility: Boolean = true\")\n        appendLine(\"): UiFilter<*> = when (filter) {\")\n\n        entries.forEach { entry ->\n            val constructorCall = if (entry.valueType != null) {\n                \"${entry.uiClassName}(filter.value)\"\n            } else {\n                \"${entry.uiClassName}()\"\n            }\n            appendLine(\"    is ${entry.filterInterface} -> $constructorCall\")\n        }\n\n        appendLine(\"    else -> error(\\\"No UiFilter mapping for \\${filter::class.qualifiedName}\\\")\")\n        appendLine(\"}.also { uiFilter ->\")\n        appendLine(\"    if (preserveVisibility) {\")\n        appendLine(\"        uiFilter.isVisible = filter.isVisible\")\n        appendLine(\"    }\")\n        appendLine(\"}\")\n    }\n\n    private fun Appendable.appendGroupFactories(entries: List<UiFilterEntry>) {\n        val grouped = entries.groupBy { it.group }\n\n        GROUP_ORDER.forEach { group ->\n            val functionName = groupFunctionName(group)\n            val groupEntries = grouped[group].orEmpty().sortedBy { it.uiClassName }\n\n            appendLine(\"internal fun $functionName(): List<UiFilter<*>> = listOf(\")\n\n            if (groupEntries.isEmpty()) {\n                appendLine(\"    // No filters for $group\")\n            } else {\n                groupEntries.forEachIndexed { index, entry ->\n                    val constructorCall = entry.defaultConstructorCall(receiverName = \"it\")\n                        .replace(\"it.\", \"\")\n                    val suffix = if (index == groupEntries.lastIndex) \"\" else \",\"\n                    appendLine(\"    $constructorCall$suffix\")\n                }\n            }\n\n            appendLine(\")\")\n            appendLine()\n        }\n    }\n\n    private fun KSClassDeclaration.toUiFilterEntry(\n        annotationFqn: String,\n        logger: KSPLogger\n    ): UiFilterEntry? {\n        val className = simpleName.asString()\n\n        val filterInterface = superTypes\n            .map { it.resolve().declaration as? KSClassDeclaration }\n            .filterNotNull()\n            .firstOrNull {\n                it.qualifiedName?.asString()\n                    ?.startsWith(\"$PACKAGE.core.filters.domain.model.Filter.\") == true\n            }\n            ?.qualifiedName\n            ?.asString()\n            ?.removePrefix(\"$PACKAGE.core.filters.domain.model.\")\n\n        if (filterInterface == null) {\n            logger.error(\"$className is annotated with @UiFilterInject but does not implement Filter.*\")\n            return null\n        }\n\n        val constructorParameters = primaryConstructor?.parameters.orEmpty()\n        if (constructorParameters.size > 1) {\n            logger.error(\"$className should declare zero or one constructor parameter\")\n            return null\n        }\n\n        val valueParameter = constructorParameters.firstOrNull()\n        val valueType = valueParameter?.type?.resolve()?.renderType()\n        val hasDefaultValue = valueParameter?.hasDefault ?: false\n\n        val group = annotations.firstOrNull {\n            it.annotationType.resolve().declaration.qualifiedName?.asString() == annotationFqn\n        }?.arguments?.firstOrNull {\n            it.name?.asString() == \"group\"\n        }?.value as? String ?: UiFilterInject.Groups.UNSPECIFIED\n\n        if (group !in GROUP_ORDER && group != UiFilterInject.Groups.UNSPECIFIED) {\n            logger.error(\"Unknown UiFilter group '$group' on $className\")\n            return null\n        }\n\n        return UiFilterEntry(\n            uiClassName = className,\n            filterInterface = filterInterface,\n            valueType = valueType,\n            valueParamHasDefault = hasDefaultValue,\n            group = group\n        )\n    }\n\n    private fun KSType.renderType(): String {\n        val declarationName = declaration.qualifiedName?.asString()\n            ?: declaration.simpleName.asString()\n\n        val argumentsRendered = arguments.takeIf { it.isNotEmpty() }\n            ?.joinToString(\", \") { argument ->\n                val type = argument.type?.resolve()\n                if (type == null || argument.variance == Variance.STAR) {\n                    \"*\"\n                } else {\n                    val rendered = type.renderType()\n                    when (argument.variance) {\n                        Variance.COVARIANT -> \"out $rendered\"\n                        Variance.CONTRAVARIANT -> \"in $rendered\"\n                        else -> rendered\n                    }\n                }\n            }\n            ?.let { \"<$it>\" }\n            ?: \"\"\n\n        val nullable = if (isMarkedNullable) \"?\" else \"\"\n\n        return declarationName + argumentsRendered + nullable\n    }\n\n    private fun UiFilterEntry.defaultConstructorCall(receiverName: String): String = when {\n        valueType == null -> \"$uiClassName()\"\n        valueParamHasDefault -> \"$uiClassName()\"\n        else -> \"$uiClassName($receiverName.value as $valueType)\"\n    }\n\n    private fun groupFunctionName(group: String): String = when (group) {\n        UiFilterInject.Groups.SIMPLE -> \"simpleGroupFilters\"\n        UiFilterInject.Groups.COLOR -> \"colorGroupFilters\"\n        UiFilterInject.Groups.LUT -> \"lutGroupFilters\"\n        UiFilterInject.Groups.LIGHT -> \"lightGroupFilters\"\n        UiFilterInject.Groups.EFFECTS -> \"effectsGroupFilters\"\n        UiFilterInject.Groups.BLUR -> \"blurGroupFilters\"\n        UiFilterInject.Groups.PIXELATION -> \"pixelationGroupFilters\"\n        UiFilterInject.Groups.DISTORTION -> \"distortionGroupFilters\"\n        UiFilterInject.Groups.DITHERING -> \"ditheringGroupFilters\"\n        else -> \"unspecifiedGroupFilters\"\n    }\n\n    private data class UiFilterEntry(\n        val uiClassName: String,\n        val filterInterface: String,\n        val valueType: String?,\n        val valueParamHasDefault: Boolean,\n        val group: String\n    )\n\n    private companion object {\n        private const val PACKAGE = \"com.t8rin.imagetoolbox\"\n        private const val GENERATED_PACKAGE =\n            \"com.t8rin.imagetoolbox.core.filters.presentation.model.generated\"\n        private const val GENERATED_FILE = \"UiFilterMappings\"\n\n        private val GROUP_ORDER = listOf(\n            UiFilterInject.Groups.SIMPLE,\n            UiFilterInject.Groups.COLOR,\n            UiFilterInject.Groups.LUT,\n            UiFilterInject.Groups.LIGHT,\n            UiFilterInject.Groups.EFFECTS,\n            UiFilterInject.Groups.BLUR,\n            UiFilterInject.Groups.PIXELATION,\n            UiFilterInject.Groups.DISTORTION,\n            UiFilterInject.Groups.DITHERING\n        )\n    }\n}\n"
  },
  {
    "path": "core/ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider",
    "content": "#\n# ImageToolbox is an image editor for android\n# Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n# You should have received a copy of the Apache License\n# along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n#\n\ncom.t8rin.imagetoolbox.core.ksp.processor.FilterInjectProcessor\ncom.t8rin.imagetoolbox.core.ksp.processor.UiFilterInjectProcessor\n"
  },
  {
    "path": "core/resources/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/resources/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid {\n    namespace = \"com.t8rin.imagetoolbox.core.resources\"\n\n    defaultConfig.vectorDrawables.useSupportLibrary = true\n\n    buildFeatures {\n        buildConfig = true\n    }\n\n    buildTypes {\n        getByName(\"release\") {\n            buildConfigField(\"String\", \"VERSION_NAME\", \"\\\"${libs.versions.versionName.get()}\\\"\")\n            buildConfigField(\"int\", \"VERSION_CODE\", libs.versions.versionCode.get())\n        }\n        getByName(\"debug\") {\n            buildConfigField(\"String\", \"VERSION_NAME\", \"\\\"${libs.versions.versionName.get()}\\\"\")\n            buildConfigField(\"int\", \"VERSION_CODE\", libs.versions.versionCode.get())\n        }\n    }\n}\n\ndependencies {\n    implementation(libs.material)\n    implementation(libs.androidxCore)\n    implementation(libs.appCompat)\n    implementation(libs.splashScreen)\n    implementation(libs.kotlinx.collections.immutable)\n}"
  },
  {
    "path": "core/resources/src/debug/res/drawable/ic_launcher_foreground.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"1305\"\n    android:viewportHeight=\"1295\">\n    <group\n        android:scaleX=\"0.38\"\n        android:scaleY=\"0.37\"\n        android:translateX=\"412\"\n        android:translateY=\"410.5\">\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:fillType=\"evenOdd\"\n            android:pathData=\"M761,383.8v99.7c0,17.1 5.8,31.5 17.4,43.1C790,538.2 804.3,544 821.4,544h99.7c8.1,0 15.9,-1.5 23.4,-4.5c7.6,-3 14.4,-7.6 20.4,-13.6l314.3,-314.3c9.1,-9.1 15.6,-19.4 19.6,-31c4,-11.6 6,-22.9 6,-34c0,-11.1 -2.3,-22.2 -6.8,-33.2c-4.5,-11.1 -10.8,-21.2 -18.9,-30.2l-55.9,-55.9c-9.1,-9.1 -19.1,-15.9 -30.2,-20.4c-11.1,-4.5 -22.7,-6.8 -34.8,-6.8c-11.1,0 -22.2,2 -33.2,6c-11.1,4 -21.2,10.6 -30.2,19.6L779.1,340c-6,6 -10.6,12.8 -13.6,20.4C762.5,368 761,375.8 761,383.8zM909.1,453.3h-57.4v-57.4l184.4,-182.8l55.9,55.9L909.1,453.3z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M1072,705c0,-74.8 -0.1,-135.5 -1.6,-186.2l101.8,-101.8C1180,489.6 1180,582.1 1180,705c0,248.5 0,372.8 -64.4,459.2c-18.8,25.2 -41.2,47.6 -66.4,66.4C962.8,1295 838.5,1295 590,1295s-372.8,0 -459.2,-64.4c-25.2,-18.8 -47.6,-41.2 -66.4,-66.4C0,1077.8 0,953.5 0,705s0,-372.8 64.4,-459.2c18.8,-25.2 41.2,-47.6 66.4,-66.4C217.2,115 341.5,115 590,115c134.7,0 232.8,0 308.3,10.2L798.1,225.4C743.2,223.1 675.9,223 590,223c-126.7,0 -212.9,0.2 -278.5,7.4c-63.5,7 -94.6,19.6 -116.1,35.6c-16.9,12.6 -31.8,27.5 -44.3,44.3c-16,21.5 -28.6,52.6 -35.6,116.1C108.2,492.1 108,578.3 108,705s0.2,212.9 7.4,278.5c1.6,14.3 3.4,26.9 5.5,38.2l1.1,-0.8c97.7,-71.2 198.9,-145 285.5,-95.1l74,45.5c72.3,44.8 155.5,-31.6 245.8,-114.5c60.9,-55.9 125,-114.8 191.2,-141.5c60.5,-24.4 101,-3.4 153.5,40.2C1072,739.5 1072,722.6 1072,705z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M450.2,491.9h-84.4V449.7h84.4M450.2,576.3h-84.4v-42.2h84.4M576.8,407.5h-59.3c-9.5,-16.5 -22.6,-30.6 -38.4,-41.3l34.4,-34.4l-29.7,-29.7l-45.8,45.8c-9.7,-2.3 -19.4,-3.6 -30,-3.6s-20.3,1.3 -29.7,3.6l-46,-45.8l-29.7,29.7l34.2,34.4c-15.6,10.8 -28.7,24.9 -38.2,41.3h-59.3v42.2h44.1c-1.1,7 -1.9,13.9 -1.9,21.1v21.1h-42.2v42.2h42.2v21.1c0,7.2 0.8,14.1 1.9,21.1h-44.1v42.2h59.3C320.5,656.2 361.2,681.8 408,681.8s87.5,-25.5 109.5,-63.3h59.3v-42.2h-44.1c1.1,-7 1.9,-13.9 1.9,-21.1v-21.1h42.2v-42.2h-42.2v-21.1c0,-7.2 -0.8,-14.1 -1.9,-21.1h44.1V407.5z\" />\n    </group>\n</vector>\n"
  },
  {
    "path": "core/resources/src/debug/res/drawable/ic_logo_animated.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"1305\"\n    android:viewportHeight=\"1295\">\n    <group\n        android:scaleX=\"0.38\"\n        android:scaleY=\"0.37\"\n        android:translateX=\"412\"\n        android:translateY=\"410.5\">\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:fillType=\"evenOdd\"\n            android:pathData=\"M761,383.8v99.7c0,17.1 5.8,31.5 17.4,43.1C790,538.2 804.3,544 821.4,544h99.7c8.1,0 15.9,-1.5 23.4,-4.5c7.6,-3 14.4,-7.6 20.4,-13.6l314.3,-314.3c9.1,-9.1 15.6,-19.4 19.6,-31c4,-11.6 6,-22.9 6,-34c0,-11.1 -2.3,-22.2 -6.8,-33.2c-4.5,-11.1 -10.8,-21.2 -18.9,-30.2l-55.9,-55.9c-9.1,-9.1 -19.1,-15.9 -30.2,-20.4c-11.1,-4.5 -22.7,-6.8 -34.8,-6.8c-11.1,0 -22.2,2 -33.2,6c-11.1,4 -21.2,10.6 -30.2,19.6L779.1,340c-6,6 -10.6,12.8 -13.6,20.4C762.5,368 761,375.8 761,383.8zM909.1,453.3h-57.4v-57.4l184.4,-182.8l55.9,55.9L909.1,453.3z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M1072,705c0,-74.8 -0.1,-135.5 -1.6,-186.2l101.8,-101.8C1180,489.6 1180,582.1 1180,705c0,248.5 0,372.8 -64.4,459.2c-18.8,25.2 -41.2,47.6 -66.4,66.4C962.8,1295 838.5,1295 590,1295s-372.8,0 -459.2,-64.4c-25.2,-18.8 -47.6,-41.2 -66.4,-66.4C0,1077.8 0,953.5 0,705s0,-372.8 64.4,-459.2c18.8,-25.2 41.2,-47.6 66.4,-66.4C217.2,115 341.5,115 590,115c134.7,0 232.8,0 308.3,10.2L798.1,225.4C743.2,223.1 675.9,223 590,223c-126.7,0 -212.9,0.2 -278.5,7.4c-63.5,7 -94.6,19.6 -116.1,35.6c-16.9,12.6 -31.8,27.5 -44.3,44.3c-16,21.5 -28.6,52.6 -35.6,116.1C108.2,492.1 108,578.3 108,705s0.2,212.9 7.4,278.5c1.6,14.3 3.4,26.9 5.5,38.2l1.1,-0.8c97.7,-71.2 198.9,-145 285.5,-95.1l74,45.5c72.3,44.8 155.5,-31.6 245.8,-114.5c60.9,-55.9 125,-114.8 191.2,-141.5c60.5,-24.4 101,-3.4 153.5,40.2C1072,739.5 1072,722.6 1072,705z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M450.2,491.9h-84.4V449.7h84.4M450.2,576.3h-84.4v-42.2h84.4M576.8,407.5h-59.3c-9.5,-16.5 -22.6,-30.6 -38.4,-41.3l34.4,-34.4l-29.7,-29.7l-45.8,45.8c-9.7,-2.3 -19.4,-3.6 -30,-3.6s-20.3,1.3 -29.7,3.6l-46,-45.8l-29.7,29.7l34.2,34.4c-15.6,10.8 -28.7,24.9 -38.2,41.3h-59.3v42.2h44.1c-1.1,7 -1.9,13.9 -1.9,21.1v21.1h-42.2v42.2h42.2v21.1c0,7.2 0.8,14.1 1.9,21.1h-44.1v42.2h59.3C320.5,656.2 361.2,681.8 408,681.8s87.5,-25.5 109.5,-63.3h59.3v-42.2h-44.1c1.1,-7 1.9,-13.9 1.9,-21.1v-21.1h42.2v-42.2h-42.2v-21.1c0,-7.2 -0.8,-14.1 -1.9,-21.1h44.1V407.5z\" />\n    </group>\n</vector>\n"
  },
  {
    "path": "core/resources/src/debug/res/drawable/ic_notification_icon.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"1305\"\n    android:viewportHeight=\"1295\">\n    <group\n        android:scaleX=\"1\"\n        android:scaleY=\"1\"\n        android:translateX=\"0\"\n        android:translateY=\"0\">\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:fillType=\"evenOdd\"\n            android:pathData=\"M761,383.8v99.7c0,17.1 5.8,31.5 17.4,43.1C790,538.2 804.3,544 821.4,544h99.7c8.1,0 15.9,-1.5 23.4,-4.5c7.6,-3 14.4,-7.6 20.4,-13.6l314.3,-314.3c9.1,-9.1 15.6,-19.4 19.6,-31c4,-11.6 6,-22.9 6,-34c0,-11.1 -2.3,-22.2 -6.8,-33.2c-4.5,-11.1 -10.8,-21.2 -18.9,-30.2l-55.9,-55.9c-9.1,-9.1 -19.1,-15.9 -30.2,-20.4c-11.1,-4.5 -22.7,-6.8 -34.8,-6.8c-11.1,0 -22.2,2 -33.2,6c-11.1,4 -21.2,10.6 -30.2,19.6L779.1,340c-6,6 -10.6,12.8 -13.6,20.4C762.5,368 761,375.8 761,383.8zM909.1,453.3h-57.4v-57.4l184.4,-182.8l55.9,55.9L909.1,453.3z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M1072,705c0,-74.8 -0.1,-135.5 -1.6,-186.2l101.8,-101.8C1180,489.6 1180,582.1 1180,705c0,248.5 0,372.8 -64.4,459.2c-18.8,25.2 -41.2,47.6 -66.4,66.4C962.8,1295 838.5,1295 590,1295s-372.8,0 -459.2,-64.4c-25.2,-18.8 -47.6,-41.2 -66.4,-66.4C0,1077.8 0,953.5 0,705s0,-372.8 64.4,-459.2c18.8,-25.2 41.2,-47.6 66.4,-66.4C217.2,115 341.5,115 590,115c134.7,0 232.8,0 308.3,10.2L798.1,225.4C743.2,223.1 675.9,223 590,223c-126.7,0 -212.9,0.2 -278.5,7.4c-63.5,7 -94.6,19.6 -116.1,35.6c-16.9,12.6 -31.8,27.5 -44.3,44.3c-16,21.5 -28.6,52.6 -35.6,116.1C108.2,492.1 108,578.3 108,705s0.2,212.9 7.4,278.5c1.6,14.3 3.4,26.9 5.5,38.2l1.1,-0.8c97.7,-71.2 198.9,-145 285.5,-95.1l74,45.5c72.3,44.8 155.5,-31.6 245.8,-114.5c60.9,-55.9 125,-114.8 191.2,-141.5c60.5,-24.4 101,-3.4 153.5,40.2C1072,739.5 1072,722.6 1072,705z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M450.2,491.9h-84.4V449.7h84.4M450.2,576.3h-84.4v-42.2h84.4M576.8,407.5h-59.3c-9.5,-16.5 -22.6,-30.6 -38.4,-41.3l34.4,-34.4l-29.7,-29.7l-45.8,45.8c-9.7,-2.3 -19.4,-3.6 -30,-3.6s-20.3,1.3 -29.7,3.6l-46,-45.8l-29.7,29.7l34.2,34.4c-15.6,10.8 -28.7,24.9 -38.2,41.3h-59.3v42.2h44.1c-1.1,7 -1.9,13.9 -1.9,21.1v21.1h-42.2v42.2h42.2v21.1c0,7.2 0.8,14.1 1.9,21.1h-44.1v42.2h59.3C320.5,656.2 361.2,681.8 408,681.8s87.5,-25.5 109.5,-63.3h59.3v-42.2h-44.1c1.1,-7 1.9,-13.9 1.9,-21.1v-21.1h42.2v-42.2h-42.2v-21.1c0,-7.2 -0.8,-14.1 -1.9,-21.1h44.1V407.5z\" />\n    </group>\n</vector>\n"
  },
  {
    "path": "core/resources/src/debug/res/drawable-v31/ic_logo_animated.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animated-vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\">\n\n    <aapt:attr name=\"android:drawable\">\n        <vector\n            android:width=\"108dp\"\n            android:height=\"108dp\"\n            android:viewportWidth=\"108\"\n            android:viewportHeight=\"108\">\n\n            <group\n                android:name=\"root\"\n                android:scaleX=\"0.8\"\n                android:scaleY=\"0.8\"\n                android:translateX=\"12\"\n                android:translateY=\"11\">\n\n                <group\n                    android:name=\"pencil\"\n                    android:alpha=\"1\"\n                    android:pivotX=\"54\"\n                    android:pivotY=\"54\"\n                    android:scaleX=\"2.4\"\n                    android:scaleY=\"2.4\"\n                    android:translateX=\"-36\"\n                    android:translateY=\"36\">\n\n                    <path\n                        android:fillColor=\"@color/onPrimary\"\n                        android:fillType=\"evenOdd\"\n                        android:pathData=\"M57.74,43.82V47.67C57.74,48.33 57.97,48.89 58.42,49.33C58.87,49.78 59.43,50 60.1,50H64C64.32,50 64.62,49.95 64.92,49.83C65.21,49.71 65.48,49.54 65.71,49.3L78,37.17C78.35,36.82 78.61,36.42 78.76,35.97C78.92,35.52 79,35.09 79,34.66C79,34.23 78.91,33.8 78.73,33.38C78.56,32.95 78.31,32.56 78,32.21L75.81,30.05C75.46,29.7 75.06,29.44 74.63,29.26C74.2,29.09 73.74,29 73.27,29C72.84,29 72.41,29.08 71.97,29.23C71.54,29.39 71.15,29.64 70.79,29.99L58.45,42.13C58.21,42.36 58.04,42.62 57.92,42.92C57.8,43.21 57.74,43.51 57.74,43.82ZM63.53,46.5H61.28V44.29L68.49,37.23L70.67,39.39L63.53,46.5Z\" />\n                </group>\n\n                <group android:name=\"body\">\n\n                    <path\n                        android:name=\"body_path1\"\n                        android:alpha=\"0.0\"\n                        android:fillColor=\"@color/onPrimary\"\n                        android:pathData=\"M69.89,56.22C69.89,53.33 69.89,50.99 69.83,49.03L73.81,45.1C74.11,47.9 74.11,51.47 74.11,56.22C74.11,65.82 74.11,70.61 71.6,73.95C70.86,74.92 69.99,75.79 69,76.51C65.63,79 60.77,79 51.06,79C41.35,79 36.49,79 33.11,76.51C32.13,75.79 31.25,74.92 30.52,73.95C28,70.61 28,65.82 28,56.22C28,46.62 28,41.83 30.52,38.49C31.25,37.52 32.13,36.65 33.11,35.93C36.49,33.44 41.35,33.44 51.06,33.44C56.32,33.44 60.16,33.44 63.1,33.84L59.19,37.7C57.05,37.61 54.42,37.61 51.06,37.61C46.11,37.61 42.74,37.62 40.17,37.9C37.69,38.17 36.47,38.65 35.63,39.27C34.98,39.75 34.39,40.33 33.9,40.98C33.27,41.81 32.78,43.01 32.51,45.47C32.23,48 32.22,51.33 32.22,56.22C32.22,61.11 32.23,64.44 32.51,66.97C32.57,67.53 32.64,68.01 32.73,68.45L32.77,68.42C36.59,65.67 40.54,62.82 43.92,64.75L46.82,66.5C49.64,68.23 52.89,65.29 56.42,62.08C58.8,59.93 61.31,57.65 63.89,56.62C66.26,55.68 67.84,56.49 69.89,58.17C69.89,57.55 69.89,56.9 69.89,56.22Z\" />\n\n                    <group\n                        android:name=\"body_path2_wrapper\"\n                        android:scaleX=\"0.04\"\n                        android:scaleY=\"0.04\"\n                        android:translateX=\"27\"\n                        android:translateY=\"29\">\n\n                        <path\n                            android:name=\"body_path2\"\n                            android:alpha=\"0.0\"\n                            android:fillColor=\"@color/onPrimary\"\n                            android:pathData=\"M450.2,491.9h-84.4V449.7h84.4M450.2,576.3h-84.4v-42.2h84.4M576.8,407.5h-59.3c-9.5,-16.5 -22.6,-30.6 -38.4,-41.3l34.4,-34.4l-29.7,-29.7l-45.8,45.8c-9.7,-2.3 -19.4,-3.6 -30,-3.6s-20.3,1.3 -29.7,3.6l-46,-45.8l-29.7,29.7l34.2,34.4c-15.6,10.8 -28.7,24.9 -38.2,41.3h-59.3v42.2h44.1c-1.1,7 -1.9,13.9 -1.9,21.1v21.1h-42.2v42.2h42.2v21.1c0,7.2 0.8,14.1 1.9,21.1h-44.1v42.2h59.3C320.5,656.2 361.2,681.8 408,681.8s87.5,-25.5 109.5,-63.3h59.3v-42.2h-44.1c1.1,-7 1.9,-13.9 1.9,-21.1v-21.1h42.2v-42.2h-42.2v-21.1c0,-7.2 -0.8,-14.1 -1.9,-21.1h44.1V407.5z\" />\n                    </group>\n                </group>\n\n            </group>\n        </vector>\n    </aapt:attr>\n\n    <target android:name=\"pencil\">\n        <aapt:attr name=\"android:animation\">\n            <set android:ordering=\"together\">\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"translateX\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"-36\"\n                    android:valueTo=\"0\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"translateY\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"36\"\n                    android:valueTo=\"0\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"scaleX\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"2.4\"\n                    android:valueTo=\"1\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"scaleY\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"2.4\"\n                    android:valueTo=\"1\" />\n            </set>\n        </aapt:attr>\n    </target>\n\n    <target android:name=\"body_path1\">\n        <aapt:attr name=\"android:animation\">\n            <set android:ordering=\"together\">\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/decelerate_quad\"\n                    android:propertyName=\"fillAlpha\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"0.0\"\n                    android:valueTo=\"1.0\"\n                    android:valueType=\"floatType\" />\n            </set>\n        </aapt:attr>\n    </target>\n\n    <target android:name=\"body_path2\">\n        <aapt:attr name=\"android:animation\">\n            <set android:ordering=\"together\">\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/decelerate_quad\"\n                    android:propertyName=\"fillAlpha\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"0.0\"\n                    android:valueTo=\"1.0\"\n                    android:valueType=\"floatType\" />\n            </set>\n        </aapt:attr>\n    </target>\n\n\n</animated-vector>"
  },
  {
    "path": "core/resources/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n    <monochrome android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "core/resources/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n    <monochrome android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "core/resources/src/debug/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">#00B1D3</color>\n    <color name=\"onPrimary\">#003131</color>\n</resources>"
  },
  {
    "path": "core/resources/src/debug/res/values/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"ic_launcher_background\">@color/primary</color>\n</resources>"
  },
  {
    "path": "core/resources/src/debug/res/values-night/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">#003131</color>\n    <color name=\"onPrimary\">#00B1D3</color>\n</resources>"
  },
  {
    "path": "core/resources/src/debug/res/values-night-v31/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">@android:color/system_accent2_800</color>\n    <color name=\"onPrimary\">@android:color/system_accent1_100</color>\n</resources>"
  },
  {
    "path": "core/resources/src/debug/res/values-v31/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">@android:color/system_accent1_100</color>\n    <color name=\"onPrimary\">@android:color/system_accent1_700</color>\n</resources>"
  },
  {
    "path": "core/resources/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/emoji/Emoji.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.emoji\n\nimport android.content.Context\nimport android.content.res.Resources\nimport android.net.Uri\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.EmojiEmotions\nimport androidx.compose.material.icons.outlined.EmojiEvents\nimport androidx.compose.material.icons.outlined.EmojiFoodBeverage\nimport androidx.compose.material.icons.outlined.EmojiNature\nimport androidx.compose.material.icons.outlined.EmojiObjects\nimport androidx.compose.material.icons.outlined.EmojiSymbols\nimport androidx.compose.material.icons.outlined.EmojiTransportation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalResources\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.collections.immutable.persistentListOf\nimport kotlinx.collections.immutable.toPersistentList\n\nobject Emoji {\n    private var Emotions: List<Uri>? = null\n    private var Food: List<Uri>? = null\n    private var Nature: List<Uri>? = null\n    private var Objects: List<Uri>? = null\n    private var Events: List<Uri>? = null\n    private var Transportation: List<Uri>? = null\n    private var Symbols: List<Uri>? = null\n\n    @Composable\n    fun allIcons(\n        context: Context = LocalContext.current\n    ): ImmutableList<Uri> = remember {\n        derivedStateOf {\n            initializeEmojis(context)\n            (Emotions!! + Food!! + Nature!! + Objects!! + Events!! + Transportation!! + Symbols!!).toPersistentList()\n        }.value\n    }\n\n    @Composable\n    fun allIconsCategorized(\n        context: Context = LocalContext.current,\n        resources: Resources = LocalResources.current\n    ): ImmutableList<EmojiData> = remember {\n        derivedStateOf {\n            initializeEmojis(context)\n            persistentListOf(\n                EmojiData(\n                    title = resources.getString(R.string.emotions),\n                    icon = Icons.Outlined.EmojiEmotions,\n                    emojis = Emotions!!\n                ),\n                EmojiData(\n                    title = resources.getString(R.string.food_and_drink),\n                    icon = Icons.Outlined.EmojiFoodBeverage,\n                    emojis = Food!!\n                ),\n                EmojiData(\n                    title = resources.getString(R.string.nature_and_animals),\n                    icon = Icons.Outlined.EmojiNature,\n                    emojis = Nature!!\n                ),\n                EmojiData(\n                    title = resources.getString(R.string.objects),\n                    icon = Icons.Outlined.EmojiObjects,\n                    emojis = Objects!!\n                ),\n                EmojiData(\n                    title = resources.getString(R.string.activities),\n                    icon = Icons.Outlined.EmojiEvents,\n                    emojis = Events!!\n                ),\n                EmojiData(\n                    title = resources.getString(R.string.travels_and_places),\n                    icon = Icons.Outlined.EmojiTransportation,\n                    emojis = Transportation!!\n                ),\n                EmojiData(\n                    title = resources.getString(R.string.symbols),\n                    icon = Icons.Outlined.EmojiSymbols,\n                    emojis = Symbols!!\n                )\n            )\n        }.value\n    }\n\n    private fun Context.listAssetFiles(\n        path: String\n    ): List<String> = assets\n        .list(path)\n        ?.toMutableList() ?: emptyList()\n\n    /**\n     * Generates Uri of the assets path.\n     */\n    private fun getFileFromAssets(\n        cat: String,\n        filename: String\n    ): Uri = \"file:///android_asset/svg/$cat/$filename\".toUri()\n\n    private fun initializeEmojis(context: Context) {\n        if (\n            !listOf(\n                Emotions,\n                Food,\n                Nature,\n                Objects,\n                Events,\n                Transportation,\n                Symbols\n            ).all { it != null }\n        ) {\n            Emotions = context\n                .listAssetFiles(\"svg/emotions\")\n                .sortedWith(String.CASE_INSENSITIVE_ORDER)\n                .map {\n                    getFileFromAssets(\n                        cat = \"emotions\",\n                        filename = it\n                    )\n                }\n            Food = context\n                .listAssetFiles(\"svg/food\")\n                .sortedWith(String.CASE_INSENSITIVE_ORDER)\n                .map {\n                    getFileFromAssets(\n                        cat = \"food\",\n                        filename = it\n                    )\n                }\n            Nature = context\n                .listAssetFiles(\"svg/nature\")\n                .sortedWith(String.CASE_INSENSITIVE_ORDER)\n                .map {\n                    getFileFromAssets(\n                        cat = \"nature\",\n                        filename = it\n                    )\n                }\n            Objects = context\n                .listAssetFiles(\"svg/objects\")\n                .sortedWith(String.CASE_INSENSITIVE_ORDER)\n                .map {\n                    getFileFromAssets(\n                        cat = \"objects\",\n                        filename = it\n                    )\n                }\n            Events = context\n                .listAssetFiles(\"svg/events\")\n                .sortedWith(String.CASE_INSENSITIVE_ORDER)\n                .map {\n                    getFileFromAssets(\n                        cat = \"events\",\n                        filename = it\n                    )\n                }\n            Transportation = context\n                .listAssetFiles(\"svg/transportation\")\n                .sortedWith(String.CASE_INSENSITIVE_ORDER)\n                .map {\n                    getFileFromAssets(\n                        cat = \"transportation\",\n                        filename = it\n                    )\n                }\n            Symbols = context\n                .listAssetFiles(\"svg/symbols\")\n                .sortedWith(String.CASE_INSENSITIVE_ORDER)\n                .map {\n                    getFileFromAssets(\n                        cat = \"symbols\",\n                        filename = it\n                    )\n                }\n        }\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/emoji/EmojiData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.emoji\n\nimport android.net.Uri\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.vector.ImageVector\n\n@Stable\n@Immutable\ndata class EmojiData(\n    val title: String,\n    val icon: ImageVector,\n    val emojis: List<Uri>\n)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/AddPhotoAlt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.AddPhotoAlt: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.AddPhotoAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            close()\n            moveTo(200f, 840f)\n            quadTo(167f, 840f, 143.5f, 816.5f)\n            quadTo(120f, 793f, 120f, 760f)\n            lineTo(120f, 200f)\n            quadTo(120f, 167f, 143.5f, 143.5f)\n            quadTo(167f, 120f, 200f, 120f)\n            lineTo(520f, 120f)\n            quadTo(520f, 137f, 520f, 157f)\n            quadTo(520f, 177f, 520f, 200f)\n            lineTo(200f, 200f)\n            quadTo(200f, 200f, 200f, 200f)\n            quadTo(200f, 200f, 200f, 200f)\n            lineTo(200f, 760f)\n            quadTo(200f, 760f, 200f, 760f)\n            quadTo(200f, 760f, 200f, 760f)\n            lineTo(760f, 760f)\n            quadTo(760f, 760f, 760f, 760f)\n            quadTo(760f, 760f, 760f, 760f)\n            lineTo(760f, 440f)\n            quadTo(783f, 440f, 803f, 440f)\n            quadTo(823f, 440f, 840f, 440f)\n            lineTo(840f, 760f)\n            quadTo(840f, 793f, 816.5f, 816.5f)\n            quadTo(793f, 840f, 760f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(240f, 680f)\n            lineTo(720f, 680f)\n            lineTo(570f, 480f)\n            lineTo(450f, 640f)\n            lineTo(360f, 520f)\n            lineTo(240f, 680f)\n            close()\n            moveTo(680f, 360f)\n            lineTo(680f, 280f)\n            lineTo(600f, 280f)\n            lineTo(600f, 200f)\n            lineTo(680f, 200f)\n            lineTo(680f, 120f)\n            lineTo(760f, 120f)\n            lineTo(760f, 200f)\n            lineTo(840f, 200f)\n            lineTo(840f, 280f)\n            lineTo(760f, 280f)\n            lineTo(760f, 360f)\n            lineTo(680f, 360f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.AddPhotoAlt: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Rounded.AddPhotoAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(200f, 840f)\n            quadTo(167f, 840f, 143.5f, 816.5f)\n            quadTo(120f, 793f, 120f, 760f)\n            lineTo(120f, 200f)\n            quadTo(120f, 167f, 143.5f, 143.5f)\n            quadTo(167f, 120f, 200f, 120f)\n            lineTo(560f, 120f)\n            quadTo(540f, 146f, 530f, 177f)\n            quadTo(520f, 208f, 520f, 240f)\n            quadTo(520f, 323f, 578.5f, 381.5f)\n            quadTo(637f, 440f, 720f, 440f)\n            quadTo(752f, 440f, 783f, 430f)\n            quadTo(814f, 420f, 840f, 400f)\n            lineTo(840f, 760f)\n            quadTo(840f, 793f, 816.5f, 816.5f)\n            quadTo(793f, 840f, 760f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(240f, 680f)\n            lineTo(720f, 680f)\n            lineTo(570f, 480f)\n            lineTo(450f, 640f)\n            lineTo(360f, 520f)\n            lineTo(240f, 680f)\n            close()\n            moveTo(680f, 360f)\n            lineTo(680f, 280f)\n            lineTo(600f, 280f)\n            lineTo(600f, 200f)\n            lineTo(680f, 200f)\n            lineTo(680f, 120f)\n            lineTo(760f, 120f)\n            lineTo(760f, 200f)\n            lineTo(840f, 200f)\n            lineTo(840f, 280f)\n            lineTo(760f, 280f)\n            lineTo(760f, 360f)\n            lineTo(680f, 360f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.AddPhotoAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.AddPhotoAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 12f)\n            horizontalLineToRelative(0f)\n            close()\n            moveTo(5f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(8f)\n            verticalLineToRelative(2f)\n            horizontalLineTo(5f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(-8f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(8f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(5f)\n            close()\n            moveTo(6f, 17f)\n            horizontalLineToRelative(12f)\n            lineToRelative(-3.75f, -5f)\n            lineToRelative(-3f, 4f)\n            lineToRelative(-2.25f, -3f)\n            lineToRelative(-3f, 4f)\n            close()\n            moveTo(17f, 9f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13.099f, 5.001f)\n            curveToRelative(0.039f, -0.193f, 0.089f, -0.385f, 0.151f, -0.576f)\n            curveToRelative(0.167f, -0.517f, 0.417f, -0.992f, 0.75f, -1.425f)\n            horizontalLineToRelative(-1f)\n            verticalLineToRelative(2f)\n            lineToRelative(0.099f, 0.001f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(19f, 10.9f)\n            curveToRelative(-0.33f, 0.066f, -0.664f, 0.1f, -1f, 0.1f)\n            curveToRelative(-1.383f, 0f, -2.563f, -0.487f, -3.538f, -1.463f)\n            curveToRelative(-0.975f, -0.975f, -1.462f, -2.154f, -1.462f, -3.537f)\n            curveToRelative(0f, -0.336f, 0.033f, -0.669f, 0.099f, -0.999f)\n            lineToRelative(-0.099f, -0.001f)\n            horizontalLineToRelative(-8f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(-8f)\n            lineToRelative(0f, -0.1f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 11f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-1f)\n            curveToRelative(-0.433f, 0.333f, -0.908f, 0.583f, -1.425f, 0.75f)\n            curveToRelative(-0.19f, 0.061f, -0.382f, 0.111f, -0.575f, 0.15f)\n            lineToRelative(-0f, 0.1f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6f, 17f)\n            lineToRelative(3f, -4f)\n            lineToRelative(2.25f, 3f)\n            lineToRelative(3f, -4f)\n            lineToRelative(3.75f, 5f)\n            lineToRelative(-12f, 0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/AddSticky.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.AddSticky: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.AddSticky\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 13f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.712f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            horizontalLineToRelative(2f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.412f, 3.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(5f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10.175f)\n            curveToRelative(0.267f, 0f, 0.521f, -0.05f, 0.763f, -0.15f)\n            curveToRelative(0.242f, -0.1f, 0.454f, -0.242f, 0.638f, -0.425f)\n            lineToRelative(3.85f, -3.85f)\n            curveToRelative(0.183f, -0.183f, 0.325f, -0.396f, 0.425f, -0.638f)\n            curveToRelative(0.1f, -0.242f, 0.15f, -0.496f, 0.15f, -0.763f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(19f, 15f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(2f)\n            horizontalLineTo(5f)\n            verticalLineTo(5f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 19f)\n            verticalLineTo(5f)\n            verticalLineToRelative(14f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Analogous.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Analogous: ImageVector by lazy {\n    Builder(\n        name = \"Analogous\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.0f, 8.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(16.9f, 8.0f, 18.0f, 8.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.0f, 8.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(4.9f, 8.0f, 6.0f, 8.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(10.9f, 4.0f, 12.0f, 4.0f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/AnalogousComplementary.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.AnalogousComplementary: ImageVector by lazy {\n    Builder(\n        name = \"AnalogousComplementary\", defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(10.9f, 16.0f, 12.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.0f, 8.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(16.9f, 8.0f, 18.0f, 8.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.0f, 8.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(4.9f, 8.0f, 6.0f, 8.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(10.9f, 4.0f, 12.0f, 4.0f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Analytics.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Analytics: ImageVector by lazy {\n    Builder(\n        name = \"Analytics\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 192.0f, viewportHeight = 192.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFFF9AB00)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(130.0f, 29.0f)\n            verticalLineToRelative(132.0f)\n            curveToRelative(0.0f, 14.77f, 10.19f, 23.0f, 21.0f, 23.0f)\n            curveToRelative(10.0f, 0.0f, 21.0f, -7.0f, 21.0f, -23.0f)\n            verticalLineTo(30.0f)\n            curveToRelative(0.0f, -13.54f, -10.0f, -22.0f, -21.0f, -22.0f)\n            reflectiveCurveTo(130.0f, 17.33f, 130.0f, 29.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFFE37400)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(75.0f, 96.0f)\n            verticalLineToRelative(65.0f)\n            curveToRelative(0.0f, 14.77f, 10.19f, 23.0f, 21.0f, 23.0f)\n            curveToRelative(10.0f, 0.0f, 21.0f, -7.0f, 21.0f, -23.0f)\n            verticalLineTo(97.0f)\n            curveToRelative(0.0f, -13.54f, -10.0f, -22.0f, -21.0f, -22.0f)\n            reflectiveCurveTo(75.0f, 84.33f, 75.0f, 96.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFFE37400)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(41.0f, 163.0f)\n            moveToRelative(-21.0f, 0.0f)\n            arcToRelative(\n                21.0f, 21.0f, 0.0f,\n                isMoreThanHalf = true,\n                isPositiveArc = true,\n                dx1 = 42.0f,\n                dy1 = 0.0f\n            )\n            arcToRelative(\n                21.0f, 21.0f, 0.0f,\n                isMoreThanHalf = true,\n                isPositiveArc = true,\n                dx1 = -42.0f,\n                dy1 = 0.0f\n            )\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Animation.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Animation: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Animation\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(360f, 880f)\n            quadTo(302f, 880f, 251f, 858f)\n            quadTo(200f, 836f, 162f, 798f)\n            quadTo(124f, 760f, 102f, 709f)\n            quadTo(80f, 658f, 80f, 600f)\n            quadTo(80f, 519f, 122f, 452f)\n            quadTo(164f, 385f, 232f, 350f)\n            quadTo(252f, 311f, 281.5f, 281.5f)\n            quadTo(311f, 252f, 350f, 232f)\n            quadTo(383f, 164f, 451f, 122f)\n            quadTo(519f, 80f, 600f, 80f)\n            quadTo(658f, 80f, 709f, 102f)\n            quadTo(760f, 124f, 798f, 162f)\n            quadTo(836f, 200f, 858f, 251f)\n            quadTo(880f, 302f, 880f, 360f)\n            quadTo(880f, 445f, 838f, 510f)\n            quadTo(796f, 575f, 728f, 610f)\n            quadTo(708f, 649f, 678.5f, 678.5f)\n            quadTo(649f, 708f, 610f, 728f)\n            quadTo(575f, 796f, 508f, 838f)\n            quadTo(441f, 880f, 360f, 880f)\n            close()\n            moveTo(360f, 800f)\n            quadTo(393f, 800f, 423.5f, 790f)\n            quadTo(454f, 780f, 480f, 760f)\n            quadTo(422f, 760f, 371f, 738f)\n            quadTo(320f, 716f, 282f, 678f)\n            quadTo(244f, 640f, 222f, 589f)\n            quadTo(200f, 538f, 200f, 480f)\n            quadTo(180f, 506f, 170f, 536.5f)\n            quadTo(160f, 567f, 160f, 600f)\n            quadTo(160f, 642f, 176f, 678f)\n            quadTo(192f, 714f, 219f, 741f)\n            quadTo(246f, 768f, 282f, 784f)\n            quadTo(318f, 800f, 360f, 800f)\n            close()\n            moveTo(480f, 680f)\n            quadTo(513f, 680f, 544.5f, 670f)\n            quadTo(576f, 660f, 602f, 640f)\n            quadTo(543f, 640f, 492f, 617.5f)\n            quadTo(441f, 595f, 403f, 557f)\n            quadTo(365f, 519f, 342.5f, 468f)\n            quadTo(320f, 417f, 320f, 358f)\n            quadTo(300f, 384f, 290f, 415.5f)\n            quadTo(280f, 447f, 280f, 480f)\n            quadTo(280f, 522f, 295.5f, 558f)\n            quadTo(311f, 594f, 339f, 621f)\n            quadTo(366f, 649f, 402f, 664.5f)\n            quadTo(438f, 680f, 480f, 680f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Apng.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Apng: ImageVector by lazy {\n    Builder(\n        name = \"Apng\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.0713f, 14.9742f)\n            lineToRelative(-1.3831f, 0.0f)\n            lineToRelative(-0.9221f, -2.4742f)\n            lineToRelative(0.0f, 2.4742f)\n            lineToRelative(-1.3831f, 0.0f)\n            lineToRelative(0.0f, -5.938f)\n            lineToRelative(1.3831f, 0.0f)\n            lineToRelative(0.9221f, 2.4741f)\n            lineToRelative(0.0f, -2.4741f)\n            lineToRelative(1.3831f, 0.0f)\n            lineToRelative(0.0f, 5.938f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.9922f, 10.5208f)\n            horizontalLineTo(18.518f)\n            verticalLineToRelative(2.969f)\n            horizontalLineToRelative(0.9897f)\n            verticalLineToRelative(-1.4845f)\n            horizontalLineToRelative(1.4845f)\n            verticalLineToRelative(1.6824f)\n            curveToRelative(0.0f, 0.6928f, -0.4948f, 1.2866f, -1.2866f, 1.2866f)\n            horizontalLineToRelative(-1.2866f)\n            curveToRelative(-0.7917f, 0.0f, -1.2866f, -0.6928f, -1.2866f, -1.2866f)\n            verticalLineTo(10.4218f)\n            curveToRelative(-0.099f, -0.6928f, 0.3959f, -1.3855f, 1.1876f, -1.3855f)\n            horizontalLineToRelative(1.2866f)\n            curveToRelative(0.7917f, 0.0f, 1.2866f, 0.6928f, 1.2866f, 1.2866f)\n            verticalLineToRelative(0.1979f)\n            horizontalLineTo(20.9922f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(10.0217f, 9.0258f)\n            horizontalLineTo(7.5476f)\n            verticalLineToRelative(5.938f)\n            horizontalLineToRelative(1.4845f)\n            verticalLineToRelative(-1.9793f)\n            horizontalLineToRelative(0.9897f)\n            curveToRelative(0.7917f, 0.0f, 1.4845f, -0.6928f, 1.4845f, -1.4845f)\n            verticalLineToRelative(-0.9897f)\n            curveTo(11.5062f, 9.7185f, 10.8134f, 9.0258f, 10.0217f, 9.0258f)\n            close()\n            moveTo(10.0217f, 11.4999f)\n            horizontalLineTo(9.0321f)\n            verticalLineToRelative(-0.9897f)\n            horizontalLineToRelative(0.9897f)\n            verticalLineTo(11.4999f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(5.3746f, 9.0363f)\n            horizontalLineTo(4.1912f)\n            curveToRelative(-0.6536f, 0.0f, -1.1834f, 0.5299f, -1.1834f, 1.1834f)\n            verticalLineToRelative(4.7335f)\n            horizontalLineToRelative(1.1834f)\n            verticalLineToRelative(-1.9688f)\n            horizontalLineToRelative(1.1834f)\n            verticalLineToRelative(1.9688f)\n            horizontalLineToRelative(1.1834f)\n            verticalLineTo(10.2197f)\n            curveTo(6.5579f, 9.5661f, 6.0281f, 9.0363f, 5.3746f, 9.0363f)\n            close()\n            moveTo(4.288f, 10.5208f)\n            horizontalLineToRelative(0.9897f)\n            verticalLineToRelative(0.9897f)\n            horizontalLineTo(4.288f)\n            verticalLineTo(10.5208f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ApngBox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ApngBox: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Apng Box\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(19.0f, 3.0f)\n            horizontalLineTo(5.0f)\n            curveTo(3.89f, 3.0f, 3.0f, 3.89f, 3.0f, 5.0f)\n            verticalLineToRelative(14.0f)\n            curveToRelative(0.0f, 1.1046f, 0.8954f, 2.0f, 2.0f, 2.0f)\n            horizontalLineToRelative(14.0f)\n            curveToRelative(1.1046f, 0.0f, 2.0f, -0.8954f, 2.0f, -2.0f)\n            verticalLineTo(5.0f)\n            curveTo(21.0f, 3.89f, 20.1f, 3.0f, 19.0f, 3.0f)\n            moveTo(19.0f, 5.0f)\n            verticalLineToRelative(14.0f)\n            horizontalLineTo(5.0f)\n            verticalLineTo(5.0f)\n            horizontalLineTo(19.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(17.9844f, 11.0121f)\n            horizontalLineTo(16.3378f)\n            verticalLineToRelative(1.9759f)\n            horizontalLineToRelative(0.6586f)\n            verticalLineToRelative(-0.9879f)\n            horizontalLineToRelative(0.9879f)\n            verticalLineToRelative(1.1197f)\n            curveToRelative(0.0f, 0.461f, -0.3293f, 0.8562f, -0.8562f, 0.8562f)\n            horizontalLineToRelative(-0.8562f)\n            curveToRelative(-0.5269f, 0.0f, -0.8562f, -0.461f, -0.8562f, -0.8562f)\n            verticalLineTo(10.9462f)\n            curveToRelative(-0.0659f, -0.461f, 0.2635f, -0.9221f, 0.7904f, -0.9221f)\n            horizontalLineToRelative(0.8562f)\n            curveToRelative(0.5269f, 0.0f, 0.8562f, 0.461f, 0.8562f, 0.8562f)\n            verticalLineToRelative(0.1317f)\n            horizontalLineTo(17.9844f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(10.6834f, 10.0171f)\n            horizontalLineTo(9.0369f)\n            verticalLineToRelative(3.9518f)\n            horizontalLineToRelative(0.9879f)\n            verticalLineToRelative(-1.3173f)\n            horizontalLineToRelative(0.6586f)\n            curveToRelative(0.5269f, 0.0f, 0.9879f, -0.461f, 0.9879f, -0.9879f)\n            verticalLineToRelative(-0.6586f)\n            curveTo(11.6714f, 10.4782f, 11.2103f, 10.0171f, 10.6834f, 10.0171f)\n            close()\n            moveTo(10.6834f, 11.6637f)\n            horizontalLineToRelative(-0.6586f)\n            verticalLineToRelative(-0.6586f)\n            horizontalLineToRelative(0.6586f)\n            verticalLineTo(11.6637f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(7.5907f, 10.0241f)\n            horizontalLineTo(6.8032f)\n            curveToRelative(-0.435f, 0.0f, -0.7875f, 0.3526f, -0.7875f, 0.7876f)\n            verticalLineToRelative(3.1502f)\n            horizontalLineToRelative(0.7875f)\n            verticalLineToRelative(-1.3103f)\n            horizontalLineToRelative(0.7875f)\n            verticalLineToRelative(1.3103f)\n            horizontalLineToRelative(0.7875f)\n            verticalLineTo(10.8117f)\n            curveTo(8.3783f, 10.3767f, 8.0257f, 10.0241f, 7.5907f, 10.0241f)\n            close()\n            moveTo(6.8676f, 11.0121f)\n            horizontalLineToRelative(0.6586f)\n            verticalLineToRelative(0.6586f)\n            horizontalLineTo(6.8676f)\n            verticalLineTo(11.0121f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(14.7095f, 13.981f)\n            lineToRelative(-0.9217f, 0.0f)\n            lineToRelative(-0.6145f, -1.6487f)\n            lineToRelative(0.0f, 1.6487f)\n            lineToRelative(-0.9217f, 0.0f)\n            lineToRelative(0.0f, -3.9569f)\n            lineToRelative(0.9217f, 0.0f)\n            lineToRelative(0.6145f, 1.6487f)\n            lineToRelative(0.0f, -1.6487f)\n            lineToRelative(0.9217f, 0.0f)\n            lineToRelative(0.0f, 3.9569f)\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ApngBox: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ApngBox\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 5f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(-14f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19f, 3f)\n            horizontalLineTo(5f)\n            curveToRelative(-1.11f, 0f, -2f, 0.89f, -2f, 2f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 1.105f, 0.895f, 2f, 2f, 2f)\n            horizontalLineToRelative(14f)\n            curveToRelative(1.105f, 0f, 2f, -0.895f, 2f, -2f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -1.11f, -0.9f, -2f, -2f, -2f)\n            moveTo(19f, 5f)\n            verticalLineToRelative(14f)\n            horizontalLineTo(5f)\n            verticalLineTo(5f)\n            horizontalLineToRelative(14f)\n            close()\n            moveTo(17.984f, 11.012f)\n            horizontalLineToRelative(-1.647f)\n            verticalLineToRelative(1.976f)\n            horizontalLineToRelative(0.659f)\n            verticalLineToRelative(-0.988f)\n            horizontalLineToRelative(0.988f)\n            verticalLineToRelative(1.12f)\n            curveToRelative(0f, 0.461f, -0.329f, 0.856f, -0.856f, 0.856f)\n            horizontalLineToRelative(-0.856f)\n            curveToRelative(-0.527f, 0f, -0.856f, -0.461f, -0.856f, -0.856f)\n            verticalLineToRelative(-2.174f)\n            curveToRelative(-0.066f, -0.461f, 0.264f, -0.922f, 0.79f, -0.922f)\n            horizontalLineToRelative(0.856f)\n            curveToRelative(0.527f, 0f, 0.856f, 0.461f, 0.856f, 0.856f)\n            verticalLineToRelative(0.132f)\n            horizontalLineToRelative(0.066f)\n            moveTo(10.683f, 10.017f)\n            horizontalLineToRelative(-1.647f)\n            verticalLineToRelative(3.952f)\n            horizontalLineToRelative(0.988f)\n            verticalLineToRelative(-1.317f)\n            horizontalLineToRelative(0.659f)\n            curveToRelative(0.527f, 0f, 0.988f, -0.461f, 0.988f, -0.988f)\n            verticalLineToRelative(-0.659f)\n            curveToRelative(0f, -0.527f, -0.461f, -0.988f, -0.988f, -0.988f)\n            close()\n            moveTo(10.683f, 11.664f)\n            horizontalLineToRelative(-0.659f)\n            verticalLineToRelative(-0.659f)\n            horizontalLineToRelative(0.659f)\n            verticalLineToRelative(0.659f)\n            close()\n            moveTo(7.591f, 10.024f)\n            horizontalLineToRelative(-0.788f)\n            curveToRelative(-0.435f, 0f, -0.787f, 0.353f, -0.787f, 0.788f)\n            verticalLineToRelative(3.15f)\n            horizontalLineToRelative(0.787f)\n            verticalLineToRelative(-1.31f)\n            horizontalLineToRelative(0.787f)\n            verticalLineToRelative(1.31f)\n            horizontalLineToRelative(0.787f)\n            verticalLineToRelative(-3.15f)\n            curveToRelative(0f, -0.435f, -0.352f, -0.788f, -0.787f, -0.788f)\n            close()\n            moveTo(6.868f, 11.012f)\n            horizontalLineToRelative(0.659f)\n            verticalLineToRelative(0.659f)\n            horizontalLineToRelative(-0.659f)\n            verticalLineToRelative(-0.659f)\n            close()\n            moveTo(14.71f, 13.981f)\n            horizontalLineToRelative(-0.922f)\n            lineToRelative(-0.614f, -1.649f)\n            verticalLineToRelative(1.649f)\n            horizontalLineToRelative(-0.922f)\n            verticalLineToRelative(-3.957f)\n            horizontalLineToRelative(0.922f)\n            lineToRelative(0.614f, 1.649f)\n            verticalLineToRelative(-1.649f)\n            horizontalLineToRelative(0.922f)\n            verticalLineToRelative(3.957f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/AppShortcut.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.AppShortcut: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"AppShortcutOutlined\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(280f, 800f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            lineTo(680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            lineTo(680f, 800f)\n            lineTo(280f, 800f)\n            close()\n            moveTo(280f, 160f)\n            lineTo(680f, 160f)\n            lineTo(680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 160f)\n            close()\n            moveTo(280f, 160f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 160f)\n            close()\n            moveTo(280f, 800f)\n            lineTo(280f, 800f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            lineTo(280f, 800f)\n            close()\n            moveTo(686f, 520f)\n            lineTo(480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            lineTo(480f, 600f)\n            quadTo(480f, 617f, 468.5f, 628.5f)\n            quadTo(457f, 640f, 440f, 640f)\n            quadTo(423f, 640f, 411.5f, 628.5f)\n            quadTo(400f, 617f, 400f, 600f)\n            lineTo(400f, 520f)\n            quadTo(400f, 487f, 423.5f, 463.5f)\n            quadTo(447f, 440f, 480f, 440f)\n            lineTo(686f, 440f)\n            lineTo(651f, 404f)\n            quadTo(640f, 393f, 640f, 376.5f)\n            quadTo(640f, 360f, 652f, 348f)\n            quadTo(663f, 337f, 680f, 337f)\n            quadTo(697f, 337f, 708f, 348f)\n            lineTo(812f, 452f)\n            quadTo(824f, 464f, 824f, 480f)\n            quadTo(824f, 496f, 812f, 508f)\n            lineTo(708f, 612f)\n            quadTo(697f, 623f, 680.5f, 623.5f)\n            quadTo(664f, 624f, 652f, 612f)\n            quadTo(641f, 601f, 640.5f, 584.5f)\n            quadTo(640f, 568f, 651f, 556f)\n            lineTo(686f, 520f)\n            close()\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 240f)\n            quadTo(760f, 257f, 748.5f, 268.5f)\n            quadTo(737f, 280f, 720f, 280f)\n            quadTo(703f, 280f, 691.5f, 268.5f)\n            quadTo(680f, 257f, 680f, 240f)\n            lineTo(680f, 240f)\n            lineTo(280f, 240f)\n            lineTo(280f, 720f)\n            lineTo(680f, 720f)\n            lineTo(680f, 720f)\n            quadTo(680f, 703f, 691.5f, 691.5f)\n            quadTo(703f, 680f, 720f, 680f)\n            quadTo(737f, 680f, 748.5f, 691.5f)\n            quadTo(760f, 703f, 760f, 720f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.AppShortcut: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"AppShortcut\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(686f, 520f)\n            lineTo(480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            lineTo(480f, 600f)\n            quadTo(480f, 617f, 468.5f, 628.5f)\n            quadTo(457f, 640f, 440f, 640f)\n            quadTo(423f, 640f, 411.5f, 628.5f)\n            quadTo(400f, 617f, 400f, 600f)\n            lineTo(400f, 520f)\n            quadTo(400f, 487f, 423.5f, 463.5f)\n            quadTo(447f, 440f, 480f, 440f)\n            lineTo(686f, 440f)\n            lineTo(651f, 404f)\n            quadTo(640f, 393f, 640f, 376.5f)\n            quadTo(640f, 360f, 652f, 348f)\n            quadTo(663f, 337f, 680f, 337f)\n            quadTo(697f, 337f, 708f, 348f)\n            lineTo(812f, 452f)\n            quadTo(824f, 464f, 824f, 480f)\n            quadTo(824f, 496f, 812f, 508f)\n            lineTo(708f, 612f)\n            quadTo(697f, 623f, 680.5f, 623.5f)\n            quadTo(664f, 624f, 652f, 612f)\n            quadTo(641f, 601f, 640.5f, 584.5f)\n            quadTo(640f, 568f, 651f, 556f)\n            lineTo(686f, 520f)\n            close()\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 240f)\n            quadTo(760f, 257f, 748.5f, 268.5f)\n            quadTo(737f, 280f, 720f, 280f)\n            quadTo(703f, 280f, 691.5f, 268.5f)\n            quadTo(680f, 257f, 680f, 240f)\n            lineTo(680f, 240f)\n            lineTo(280f, 240f)\n            lineTo(280f, 720f)\n            lineTo(680f, 720f)\n            lineTo(680f, 720f)\n            quadTo(680f, 703f, 691.5f, 691.5f)\n            quadTo(703f, 680f, 720f, 680f)\n            quadTo(737f, 680f, 748.5f, 691.5f)\n            quadTo(760f, 703f, 760f, 720f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Apps.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Apps: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Apps\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(240f, 800f)\n            quadTo(207f, 800f, 183.5f, 776.5f)\n            quadTo(160f, 753f, 160f, 720f)\n            quadTo(160f, 687f, 183.5f, 663.5f)\n            quadTo(207f, 640f, 240f, 640f)\n            quadTo(273f, 640f, 296.5f, 663.5f)\n            quadTo(320f, 687f, 320f, 720f)\n            quadTo(320f, 753f, 296.5f, 776.5f)\n            quadTo(273f, 800f, 240f, 800f)\n            close()\n            moveTo(480f, 800f)\n            quadTo(447f, 800f, 423.5f, 776.5f)\n            quadTo(400f, 753f, 400f, 720f)\n            quadTo(400f, 687f, 423.5f, 663.5f)\n            quadTo(447f, 640f, 480f, 640f)\n            quadTo(513f, 640f, 536.5f, 663.5f)\n            quadTo(560f, 687f, 560f, 720f)\n            quadTo(560f, 753f, 536.5f, 776.5f)\n            quadTo(513f, 800f, 480f, 800f)\n            close()\n            moveTo(720f, 800f)\n            quadTo(687f, 800f, 663.5f, 776.5f)\n            quadTo(640f, 753f, 640f, 720f)\n            quadTo(640f, 687f, 663.5f, 663.5f)\n            quadTo(687f, 640f, 720f, 640f)\n            quadTo(753f, 640f, 776.5f, 663.5f)\n            quadTo(800f, 687f, 800f, 720f)\n            quadTo(800f, 753f, 776.5f, 776.5f)\n            quadTo(753f, 800f, 720f, 800f)\n            close()\n            moveTo(240f, 560f)\n            quadTo(207f, 560f, 183.5f, 536.5f)\n            quadTo(160f, 513f, 160f, 480f)\n            quadTo(160f, 447f, 183.5f, 423.5f)\n            quadTo(207f, 400f, 240f, 400f)\n            quadTo(273f, 400f, 296.5f, 423.5f)\n            quadTo(320f, 447f, 320f, 480f)\n            quadTo(320f, 513f, 296.5f, 536.5f)\n            quadTo(273f, 560f, 240f, 560f)\n            close()\n            moveTo(480f, 560f)\n            quadTo(447f, 560f, 423.5f, 536.5f)\n            quadTo(400f, 513f, 400f, 480f)\n            quadTo(400f, 447f, 423.5f, 423.5f)\n            quadTo(447f, 400f, 480f, 400f)\n            quadTo(513f, 400f, 536.5f, 423.5f)\n            quadTo(560f, 447f, 560f, 480f)\n            quadTo(560f, 513f, 536.5f, 536.5f)\n            quadTo(513f, 560f, 480f, 560f)\n            close()\n            moveTo(720f, 560f)\n            quadTo(687f, 560f, 663.5f, 536.5f)\n            quadTo(640f, 513f, 640f, 480f)\n            quadTo(640f, 447f, 663.5f, 423.5f)\n            quadTo(687f, 400f, 720f, 400f)\n            quadTo(753f, 400f, 776.5f, 423.5f)\n            quadTo(800f, 447f, 800f, 480f)\n            quadTo(800f, 513f, 776.5f, 536.5f)\n            quadTo(753f, 560f, 720f, 560f)\n            close()\n            moveTo(240f, 320f)\n            quadTo(207f, 320f, 183.5f, 296.5f)\n            quadTo(160f, 273f, 160f, 240f)\n            quadTo(160f, 207f, 183.5f, 183.5f)\n            quadTo(207f, 160f, 240f, 160f)\n            quadTo(273f, 160f, 296.5f, 183.5f)\n            quadTo(320f, 207f, 320f, 240f)\n            quadTo(320f, 273f, 296.5f, 296.5f)\n            quadTo(273f, 320f, 240f, 320f)\n            close()\n            moveTo(480f, 320f)\n            quadTo(447f, 320f, 423.5f, 296.5f)\n            quadTo(400f, 273f, 400f, 240f)\n            quadTo(400f, 207f, 423.5f, 183.5f)\n            quadTo(447f, 160f, 480f, 160f)\n            quadTo(513f, 160f, 536.5f, 183.5f)\n            quadTo(560f, 207f, 560f, 240f)\n            quadTo(560f, 273f, 536.5f, 296.5f)\n            quadTo(513f, 320f, 480f, 320f)\n            close()\n            moveTo(720f, 320f)\n            quadTo(687f, 320f, 663.5f, 296.5f)\n            quadTo(640f, 273f, 640f, 240f)\n            quadTo(640f, 207f, 663.5f, 183.5f)\n            quadTo(687f, 160f, 720f, 160f)\n            quadTo(753f, 160f, 776.5f, 183.5f)\n            quadTo(800f, 207f, 800f, 240f)\n            quadTo(800f, 273f, 776.5f, 296.5f)\n            quadTo(753f, 320f, 720f, 320f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Archive.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Archive: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Archive\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(451.5f, 411.5f)\n            quadTo(440f, 423f, 440f, 440f)\n            verticalLineToRelative(128f)\n            lineToRelative(-36f, -36f)\n            quadToRelative(-11f, -11f, -28f, -11f)\n            reflectiveQuadToRelative(-28f, 11f)\n            quadToRelative(-11f, 11f, -11f, 28f)\n            reflectiveQuadToRelative(11f, 28f)\n            lineToRelative(104f, 104f)\n            quadToRelative(12f, 12f, 28f, 12f)\n            reflectiveQuadToRelative(28f, -12f)\n            lineToRelative(104f, -104f)\n            quadToRelative(11f, -11f, 11f, -28f)\n            reflectiveQuadToRelative(-11f, -28f)\n            quadToRelative(-11f, -11f, -28f, -11f)\n            reflectiveQuadToRelative(-28f, 11f)\n            lineToRelative(-36f, 36f)\n            verticalLineToRelative(-128f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(480f, 400f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            close()\n            moveTo(200f, 320f)\n            verticalLineToRelative(440f)\n            horizontalLineToRelative(560f)\n            verticalLineToRelative(-440f)\n            lineTo(200f, 320f)\n            close()\n            moveTo(200f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120f, 760f)\n            verticalLineToRelative(-499f)\n            quadToRelative(0f, -14f, 4.5f, -27f)\n            reflectiveQuadToRelative(13.5f, -24f)\n            lineToRelative(50f, -61f)\n            quadToRelative(11f, -14f, 27.5f, -21.5f)\n            reflectiveQuadTo(250f, 120f)\n            horizontalLineToRelative(460f)\n            quadToRelative(18f, 0f, 34.5f, 7.5f)\n            reflectiveQuadTo(772f, 149f)\n            lineToRelative(50f, 61f)\n            quadToRelative(9f, 11f, 13.5f, 24f)\n            reflectiveQuadToRelative(4.5f, 27f)\n            verticalLineToRelative(499f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(760f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(216f, 240f)\n            horizontalLineToRelative(528f)\n            lineToRelative(-34f, -40f)\n            lineTo(250f, 200f)\n            lineToRelative(-34f, 40f)\n            close()\n            moveTo(480f, 540f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/AreaChart.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.AreaChart: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.AreaChart\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(840f, 640f)\n            lineTo(464f, 346f)\n            lineTo(305f, 565f)\n            lineTo(120f, 420f)\n            lineTo(120f, 280f)\n            lineTo(280f, 400f)\n            lineTo(480f, 120f)\n            lineTo(680f, 280f)\n            lineTo(840f, 280f)\n            lineTo(840f, 640f)\n            close()\n            moveTo(120f, 800f)\n            lineTo(120f, 520f)\n            lineTo(320f, 680f)\n            lineTo(480f, 460f)\n            lineTo(840f, 741f)\n            lineTo(840f, 800f)\n            lineTo(120f, 800f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ArtTrack.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ArtTrack: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Outlined\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.412f, 5.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(3f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(10f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(7f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(13f, 17f)\n            horizontalLineTo(3f)\n            verticalLineTo(7f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.5f, 14f)\n            lineToRelative(-1f, -1.325f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.196f, -0.4f, -0.188f)\n            reflectiveCurveToRelative(-0.3f, 0.079f, -0.4f, 0.213f)\n            lineToRelative(-1.125f, 1.5f)\n            curveToRelative(-0.133f, 0.167f, -0.146f, 0.342f, -0.038f, 0.525f)\n            reflectiveCurveToRelative(0.262f, 0.275f, 0.463f, 0.275f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.2f, 0f, 0.35f, -0.092f, 0.45f, -0.275f)\n            reflectiveCurveToRelative(0.083f, -0.358f, -0.05f, -0.525f)\n            lineToRelative(-1.6f, -2.175f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-1.5f, 1.975f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17.288f, 18.712f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.288f, 18.712f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 17f)\n            verticalLineTo(7f)\n            verticalLineToRelative(10f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ArtTrack: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ArtTrack\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.412f, 5.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(3f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(10f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(7f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(13f, 17f)\n            horizontalLineTo(3f)\n            verticalLineTo(7f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.5f, 14f)\n            lineToRelative(-1f, -1.325f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.196f, -0.4f, -0.188f)\n            reflectiveCurveToRelative(-0.3f, 0.079f, -0.4f, 0.213f)\n            lineToRelative(-1.125f, 1.5f)\n            curveToRelative(-0.133f, 0.167f, -0.146f, 0.342f, -0.038f, 0.525f)\n            reflectiveCurveToRelative(0.262f, 0.275f, 0.463f, 0.275f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.2f, 0f, 0.35f, -0.092f, 0.45f, -0.275f)\n            reflectiveCurveToRelative(0.083f, -0.358f, -0.05f, -0.525f)\n            lineToRelative(-1.6f, -2.175f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-1.5f, 1.975f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17.288f, 18.712f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.288f, 18.712f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 17f)\n            verticalLineTo(7f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(2.989f, 7f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(10f)\n            horizontalLineToRelative(-10f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Ascii.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Ascii: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Ascii\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.55f, 12.45f)\n            verticalLineToRelative(1.71f)\n            horizontalLineToRelative(-0.9f)\n            verticalLineToRelative(5.13f)\n            horizontalLineToRelative(0.9f)\n            verticalLineToRelative(1.71f)\n            horizontalLineToRelative(-3.6f)\n            verticalLineToRelative(-1.71f)\n            horizontalLineToRelative(0.9f)\n            verticalLineToRelative(-5.13f)\n            horizontalLineToRelative(-0.9f)\n            verticalLineToRelative(-1.71f)\n            horizontalLineToRelative(3.6f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4.8f, 3f)\n            curveToRelative(-0.994f, 0f, -1.8f, 0.766f, -1.8f, 1.71f)\n            verticalLineToRelative(6.84f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(-3.42f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(3.42f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(-6.84f)\n            curveToRelative(0f, -0.944f, -0.806f, -1.71f, -1.8f, -1.71f)\n            horizontalLineToRelative(-1.8f)\n            moveTo(4.8f, 4.71f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(1.71f)\n            horizontalLineToRelative(-1.8f)\n            verticalLineToRelative(-1.71f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.1f, 3f)\n            curveToRelative(-0.994f, 0f, -1.8f, 0.766f, -1.8f, 1.71f)\n            verticalLineToRelative(1.71f)\n            curveToRelative(0f, 0.944f, 0.806f, 1.71f, 1.8f, 1.71f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(1.71f)\n            horizontalLineToRelative(-3.6f)\n            verticalLineToRelative(1.71f)\n            horizontalLineToRelative(3.6f)\n            curveToRelative(0.994f, 0f, 1.8f, -0.766f, 1.8f, -1.71f)\n            verticalLineToRelative(-1.71f)\n            curveToRelative(0f, -0.944f, -0.806f, -1.71f, -1.8f, -1.71f)\n            horizontalLineToRelative(-1.8f)\n            verticalLineToRelative(-1.71f)\n            horizontalLineToRelative(3.6f)\n            verticalLineToRelative(-1.71f)\n            horizontalLineToRelative(-3.6f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17.4f, 3f)\n            curveToRelative(-0.994f, 0f, -1.8f, 0.766f, -1.8f, 1.71f)\n            verticalLineToRelative(5.13f)\n            curveToRelative(0f, 0.944f, 0.806f, 1.71f, 1.8f, 1.71f)\n            horizontalLineToRelative(1.8f)\n            curveToRelative(0.994f, 0f, 1.8f, -0.766f, 1.8f, -1.71f)\n            verticalLineToRelative(-0.855f)\n            horizontalLineToRelative(-1.8f)\n            verticalLineToRelative(0.855f)\n            horizontalLineToRelative(-1.8f)\n            verticalLineToRelative(-5.13f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(0.855f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(-0.855f)\n            curveToRelative(0f, -0.944f, -0.806f, -1.71f, -1.8f, -1.71f)\n            horizontalLineToRelative(-1.8f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.05f, 12.45f)\n            verticalLineToRelative(1.71f)\n            horizontalLineToRelative(-0.9f)\n            verticalLineToRelative(5.13f)\n            horizontalLineToRelative(0.9f)\n            verticalLineToRelative(1.71f)\n            horizontalLineToRelative(-3.6f)\n            verticalLineToRelative(-1.71f)\n            horizontalLineToRelative(0.9f)\n            verticalLineToRelative(-5.13f)\n            horizontalLineToRelative(-0.9f)\n            verticalLineToRelative(-1.71f)\n            horizontalLineToRelative(3.6f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/AutoDelete.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.AutoDelete: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.AutoDelete\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 240f)\n            lineTo(280f, 240f)\n            lineTo(280f, 400f)\n            quadTo(280f, 400f, 280f, 481.5f)\n            quadTo(280f, 563f, 280f, 680f)\n            quadTo(280f, 701f, 280f, 721f)\n            quadTo(280f, 741f, 280f, 760f)\n            lineTo(280f, 760f)\n            quadTo(280f, 760f, 280f, 760f)\n            quadTo(280f, 760f, 280f, 760f)\n            lineTo(280f, 240f)\n            close()\n            moveTo(450f, 840f)\n            lineTo(280f, 840f)\n            quadTo(247f, 840f, 223.5f, 816.5f)\n            quadTo(200f, 793f, 200f, 760f)\n            lineTo(200f, 240f)\n            lineTo(160f, 240f)\n            lineTo(160f, 160f)\n            lineTo(360f, 160f)\n            lineTo(360f, 120f)\n            lineTo(600f, 120f)\n            lineTo(600f, 160f)\n            lineTo(800f, 160f)\n            lineTo(800f, 240f)\n            lineTo(760f, 240f)\n            lineTo(760f, 412f)\n            quadTo(743f, 407f, 720.5f, 403.5f)\n            quadTo(698f, 400f, 680f, 400f)\n            lineTo(680f, 240f)\n            lineTo(280f, 240f)\n            lineTo(280f, 760f)\n            quadTo(280f, 760f, 280f, 760f)\n            quadTo(280f, 760f, 280f, 760f)\n            lineTo(412f, 760f)\n            quadTo(418f, 781f, 428f, 801.5f)\n            quadTo(438f, 822f, 450f, 840f)\n            close()\n            moveTo(360f, 680f)\n            lineTo(400f, 680f)\n            quadTo(400f, 617f, 420f, 576.5f)\n            quadTo(440f, 536f, 440f, 536f)\n            lineTo(440f, 320f)\n            lineTo(360f, 320f)\n            lineTo(360f, 680f)\n            close()\n            moveTo(520f, 450f)\n            quadTo(537f, 439f, 558.5f, 428f)\n            quadTo(580f, 417f, 600f, 412f)\n            lineTo(600f, 320f)\n            lineTo(520f, 320f)\n            lineTo(520f, 450f)\n            close()\n            moveTo(680f, 880f)\n            quadTo(597f, 880f, 538.5f, 821.5f)\n            quadTo(480f, 763f, 480f, 680f)\n            quadTo(480f, 597f, 538.5f, 538.5f)\n            quadTo(597f, 480f, 680f, 480f)\n            quadTo(763f, 480f, 821.5f, 538.5f)\n            quadTo(880f, 597f, 880f, 680f)\n            quadTo(880f, 763f, 821.5f, 821.5f)\n            quadTo(763f, 880f, 680f, 880f)\n            close()\n            moveTo(746f, 774f)\n            lineTo(774f, 746f)\n            lineTo(700f, 672f)\n            lineTo(700f, 560f)\n            lineTo(660f, 560f)\n            lineTo(660f, 688f)\n            lineTo(746f, 774f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BackgroundColor.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.BackgroundColor: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.BackgroundColor\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3.88f, 3f)\n            curveToRelative(-0.5f, 0.06f, -0.88f, 0.5f, -0.88f, 1f)\n            horizontalLineToRelative(0f)\n            verticalLineToRelative(1f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-1.12f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 3f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 3f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15f, 3f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 3f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-1.12f)\n            curveToRelative(-0.06f, -0.5f, -0.5f, -0.88f, -1f, -0.88f)\n            horizontalLineToRelative(-1f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 7f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 7f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 11f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 15f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 19f)\n            verticalLineToRelative(1.12f)\n            curveToRelative(0.06f, 0.5f, 0.5f, 0.88f, 1f, 0.88f)\n            horizontalLineToRelative(1f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 19f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.462f, 21f)\n            curveToRelative(-0.615f, 0f, -1.196f, -0.118f, -1.744f, -0.354f)\n            reflectiveCurveToRelative(-1.026f, -0.559f, -1.434f, -0.967f)\n            reflectiveCurveToRelative(-0.731f, -0.887f, -0.967f, -1.434f)\n            reflectiveCurveToRelative(-0.354f, -1.129f, -0.354f, -1.744f)\n            curveToRelative(0f, -0.622f, 0.122f, -1.207f, 0.366f, -1.755f)\n            curveToRelative(0.244f, -0.548f, 0.574f, -1.024f, 0.99f, -1.429f)\n            reflectiveCurveToRelative(0.902f, -0.726f, 1.457f, -0.962f)\n            reflectiveCurveToRelative(1.148f, -0.354f, 1.778f, -0.354f)\n            curveToRelative(0.6f, 0f, 1.166f, 0.103f, 1.699f, 0.309f)\n            reflectiveCurveToRelative(0.999f, 0.491f, 1.401f, 0.855f)\n            reflectiveCurveToRelative(0.72f, 0.795f, 0.956f, 1.294f)\n            reflectiveCurveToRelative(0.354f, 1.037f, 0.354f, 1.614f)\n            curveToRelative(0f, 0.862f, -0.262f, 1.524f, -0.788f, 1.986f)\n            reflectiveCurveToRelative(-1.162f, 0.692f, -1.913f, 0.692f)\n            horizontalLineToRelative(-0.832f)\n            curveToRelative(-0.068f, 0f, -0.114f, 0.019f, -0.141f, 0.056f)\n            reflectiveCurveToRelative(-0.039f, 0.079f, -0.039f, 0.124f)\n            curveToRelative(0f, 0.09f, 0.056f, 0.219f, 0.169f, 0.388f)\n            reflectiveCurveToRelative(0.169f, 0.362f, 0.169f, 0.579f)\n            curveToRelative(0f, 0.375f, -0.103f, 0.652f, -0.309f, 0.832f)\n            reflectiveCurveToRelative(-0.478f, 0.27f, -0.816f, 0.27f)\n            close()\n            moveTo(13.988f, 16.95f)\n            curveToRelative(0.195f, 0f, 0.356f, -0.064f, 0.484f, -0.191f)\n            reflectiveCurveToRelative(0.191f, -0.289f, 0.191f, -0.484f)\n            curveToRelative(0f, -0.195f, -0.064f, -0.356f, -0.191f, -0.484f)\n            reflectiveCurveToRelative(-0.289f, -0.191f, -0.484f, -0.191f)\n            curveToRelative(-0.195f, 0f, -0.356f, 0.064f, -0.484f, 0.191f)\n            reflectiveCurveToRelative(-0.191f, 0.289f, -0.191f, 0.484f)\n            curveToRelative(0f, 0.195f, 0.064f, 0.356f, 0.191f, 0.484f)\n            reflectiveCurveToRelative(0.289f, 0.191f, 0.484f, 0.191f)\n            close()\n            moveTo(15.338f, 15.15f)\n            curveToRelative(0.195f, 0f, 0.356f, -0.064f, 0.484f, -0.191f)\n            reflectiveCurveToRelative(0.191f, -0.289f, 0.191f, -0.484f)\n            reflectiveCurveToRelative(-0.064f, -0.356f, -0.191f, -0.484f)\n            reflectiveCurveToRelative(-0.289f, -0.191f, -0.484f, -0.191f)\n            reflectiveCurveToRelative(-0.356f, 0.064f, -0.484f, 0.191f)\n            reflectiveCurveToRelative(-0.191f, 0.289f, -0.191f, 0.484f)\n            reflectiveCurveToRelative(0.064f, 0.356f, 0.191f, 0.484f)\n            reflectiveCurveToRelative(0.289f, 0.191f, 0.484f, 0.191f)\n            close()\n            moveTo(17.587f, 15.15f)\n            curveToRelative(0.195f, 0f, 0.356f, -0.064f, 0.484f, -0.191f)\n            reflectiveCurveToRelative(0.191f, -0.289f, 0.191f, -0.484f)\n            reflectiveCurveToRelative(-0.064f, -0.356f, -0.191f, -0.484f)\n            reflectiveCurveToRelative(-0.289f, -0.191f, -0.484f, -0.191f)\n            reflectiveCurveToRelative(-0.356f, 0.064f, -0.484f, 0.191f)\n            reflectiveCurveToRelative(-0.191f, 0.289f, -0.191f, 0.484f)\n            reflectiveCurveToRelative(0.064f, 0.356f, 0.191f, 0.484f)\n            reflectiveCurveToRelative(0.289f, 0.191f, 0.484f, 0.191f)\n            close()\n            moveTo(18.938f, 16.95f)\n            curveToRelative(0.195f, 0f, 0.356f, -0.064f, 0.484f, -0.191f)\n            reflectiveCurveToRelative(0.191f, -0.289f, 0.191f, -0.484f)\n            curveToRelative(0f, -0.195f, -0.064f, -0.356f, -0.191f, -0.484f)\n            reflectiveCurveToRelative(-0.289f, -0.191f, -0.484f, -0.191f)\n            reflectiveCurveToRelative(-0.356f, 0.064f, -0.484f, 0.191f)\n            reflectiveCurveToRelative(-0.191f, 0.289f, -0.191f, 0.484f)\n            curveToRelative(0f, 0.195f, 0.064f, 0.356f, 0.191f, 0.484f)\n            reflectiveCurveToRelative(0.289f, 0.191f, 0.484f, 0.191f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BarcodeScanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.BarcodeScanner: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.BarcodeScanner\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(228.5f, 828.5f)\n            quadTo(217f, 840f, 200f, 840f)\n            lineTo(80f, 840f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(40f, 800f)\n            verticalLineToRelative(-120f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(80f, 640f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(120f, 680f)\n            verticalLineToRelative(80f)\n            horizontalLineToRelative(80f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(240f, 800f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            close()\n            moveTo(908.5f, 651.5f)\n            quadTo(920f, 663f, 920f, 680f)\n            verticalLineToRelative(120f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(880f, 840f)\n            lineTo(760f, 840f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(720f, 800f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(760f, 760f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-80f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(880f, 640f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            close()\n            moveTo(180f, 720f)\n            quadToRelative(-8f, 0f, -14f, -6f)\n            reflectiveQuadToRelative(-6f, -14f)\n            verticalLineToRelative(-440f)\n            quadToRelative(0f, -8f, 6f, -14f)\n            reflectiveQuadToRelative(14f, -6f)\n            horizontalLineToRelative(40f)\n            quadToRelative(8f, 0f, 14f, 6f)\n            reflectiveQuadToRelative(6f, 14f)\n            verticalLineToRelative(440f)\n            quadToRelative(0f, 8f, -6f, 14f)\n            reflectiveQuadToRelative(-14f, 6f)\n            horizontalLineToRelative(-40f)\n            close()\n            moveTo(286f, 714f)\n            quadToRelative(-6f, -6f, -6f, -14f)\n            verticalLineToRelative(-440f)\n            quadToRelative(0f, -8f, 6f, -14f)\n            reflectiveQuadToRelative(14f, -6f)\n            quadToRelative(8f, 0f, 14f, 6f)\n            reflectiveQuadToRelative(6f, 14f)\n            verticalLineToRelative(440f)\n            quadToRelative(0f, 8f, -6f, 14f)\n            reflectiveQuadToRelative(-14f, 6f)\n            quadToRelative(-8f, 0f, -14f, -6f)\n            close()\n            moveTo(420f, 720f)\n            quadToRelative(-8f, 0f, -14f, -6f)\n            reflectiveQuadToRelative(-6f, -14f)\n            verticalLineToRelative(-440f)\n            quadToRelative(0f, -8f, 6f, -14f)\n            reflectiveQuadToRelative(14f, -6f)\n            horizontalLineToRelative(40f)\n            quadToRelative(8f, 0f, 14f, 6f)\n            reflectiveQuadToRelative(6f, 14f)\n            verticalLineToRelative(440f)\n            quadToRelative(0f, 8f, -6f, 14f)\n            reflectiveQuadToRelative(-14f, 6f)\n            horizontalLineToRelative(-40f)\n            close()\n            moveTo(540f, 720f)\n            quadToRelative(-8f, 0f, -14f, -6f)\n            reflectiveQuadToRelative(-6f, -14f)\n            verticalLineToRelative(-440f)\n            quadToRelative(0f, -8f, 6f, -14f)\n            reflectiveQuadToRelative(14f, -6f)\n            horizontalLineToRelative(80f)\n            quadToRelative(8f, 0f, 14f, 6f)\n            reflectiveQuadToRelative(6f, 14f)\n            verticalLineToRelative(440f)\n            quadToRelative(0f, 8f, -6f, 14f)\n            reflectiveQuadToRelative(-14f, 6f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(686f, 714f)\n            quadToRelative(-6f, -6f, -6f, -14f)\n            verticalLineToRelative(-440f)\n            quadToRelative(0f, -8f, 6f, -14f)\n            reflectiveQuadToRelative(14f, -6f)\n            quadToRelative(8f, 0f, 14f, 6f)\n            reflectiveQuadToRelative(6f, 14f)\n            verticalLineToRelative(440f)\n            quadToRelative(0f, 8f, -6f, 14f)\n            reflectiveQuadToRelative(-14f, 6f)\n            quadToRelative(-8f, 0f, -14f, -6f)\n            close()\n            moveTo(766f, 714f)\n            quadToRelative(-6f, -6f, -6f, -14f)\n            verticalLineToRelative(-440f)\n            quadToRelative(0f, -8f, 6f, -14f)\n            reflectiveQuadToRelative(14f, -6f)\n            quadToRelative(8f, 0f, 14f, 6f)\n            reflectiveQuadToRelative(6f, 14f)\n            verticalLineToRelative(440f)\n            quadToRelative(0f, 8f, -6f, 14f)\n            reflectiveQuadToRelative(-14f, 6f)\n            quadToRelative(-8f, 0f, -14f, -6f)\n            close()\n            moveTo(228.5f, 188.5f)\n            quadTo(217f, 200f, 200f, 200f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(80f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(80f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(40f, 280f)\n            verticalLineToRelative(-120f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(80f, 120f)\n            horizontalLineToRelative(120f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(240f, 160f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            close()\n            moveTo(731.5f, 131.5f)\n            quadTo(743f, 120f, 760f, 120f)\n            horizontalLineToRelative(120f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(920f, 160f)\n            verticalLineToRelative(120f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(880f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(840f, 280f)\n            verticalLineToRelative(-80f)\n            horizontalLineToRelative(-80f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(720f, 160f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Base64.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Base64: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Base64\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(22f, 10.889f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            curveToRelative(0f, -1.227f, -0.995f, -2.222f, -2.222f, -2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            curveToRelative(-1.227f, 0f, -2.222f, 0.995f, -2.222f, 2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            curveToRelative(0f, 1.227f, 0.995f, 2.222f, 2.222f, 2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            curveToRelative(1.227f, 0f, 2.222f, -0.995f, 2.222f, -2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            close()\n            moveTo(11.523f, 10.57f)\n            horizontalLineToRelative(-2.86f)\n            verticalLineToRelative(0.715f)\n            horizontalLineToRelative(1.906f)\n            curveToRelative(0.526f, 0f, 0.953f, 0.427f, 0.953f, 0.953f)\n            verticalLineToRelative(1.668f)\n            curveToRelative(0f, 0.526f, -0.427f, 0.953f, -0.953f, 0.953f)\n            horizontalLineToRelative(-2.383f)\n            curveToRelative(-0.526f, 0f, -0.953f, -0.427f, -0.953f, -0.953f)\n            verticalLineToRelative(-3.813f)\n            curveToRelative(0f, -0.526f, 0.427f, -0.953f, 0.953f, -0.953f)\n            horizontalLineToRelative(3.336f)\n            verticalLineToRelative(1.43f)\n            close()\n            moveTo(16.766f, 14.86f)\n            horizontalLineToRelative(-1.43f)\n            verticalLineToRelative(-2.383f)\n            horizontalLineToRelative(-2.86f)\n            verticalLineToRelative(-3.336f)\n            horizontalLineToRelative(1.43f)\n            verticalLineToRelative(1.906f)\n            horizontalLineToRelative(1.43f)\n            verticalLineToRelative(-1.906f)\n            horizontalLineToRelative(1.43f)\n            verticalLineToRelative(5.719f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(8.664f, 12.715f)\n            horizontalLineToRelative(1.43f)\n            verticalLineToRelative(0.715f)\n            horizontalLineToRelative(-1.43f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Base64: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Base64\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(22f, 10.889f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            curveToRelative(0f, -1.227f, -0.995f, -2.222f, -2.222f, -2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            curveToRelative(-1.227f, 0f, -2.222f, 0.995f, -2.222f, 2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            curveToRelative(0f, 1.227f, 0.995f, 2.222f, 2.222f, 2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            curveToRelative(1.227f, 0f, 2.222f, -0.995f, 2.222f, -2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            close()\n            moveTo(17.852f, 17.235f)\n            curveToRelative(0f, 0.341f, -0.276f, 0.618f, -0.618f, 0.618f)\n            horizontalLineTo(6.765f)\n            curveToRelative(-0.341f, 0f, -0.618f, -0.276f, -0.618f, -0.618f)\n            verticalLineTo(6.765f)\n            curveToRelative(0f, -0.341f, 0.276f, -0.618f, 0.618f, -0.618f)\n            horizontalLineToRelative(10.469f)\n            curveToRelative(0.341f, 0f, 0.618f, 0.276f, 0.618f, 0.618f)\n            verticalLineToRelative(10.469f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12.477f, 9.14f)\n            lineToRelative(1.43f, 0f)\n            lineToRelative(0f, 1.906f)\n            lineToRelative(1.43f, 0f)\n            lineToRelative(0f, -1.906f)\n            lineToRelative(1.43f, 0f)\n            lineToRelative(0f, 5.719f)\n            lineToRelative(-1.43f, 0f)\n            lineToRelative(0f, -2.383f)\n            lineToRelative(-2.86f, 0f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(11.523f, 10.57f)\n            verticalLineToRelative(-1.43f)\n            horizontalLineToRelative(-3.336f)\n            curveToRelative(-0.526f, 0f, -0.953f, 0.427f, -0.953f, 0.953f)\n            verticalLineToRelative(3.813f)\n            curveToRelative(0f, 0.526f, 0.427f, 0.953f, 0.953f, 0.953f)\n            horizontalLineToRelative(2.383f)\n            curveToRelative(0.526f, 0f, 0.953f, -0.427f, 0.953f, -0.953f)\n            verticalLineToRelative(-1.668f)\n            curveToRelative(0f, -0.526f, -0.427f, -0.953f, -0.953f, -0.953f)\n            horizontalLineToRelative(-1.906f)\n            verticalLineToRelative(-0.715f)\n            horizontalLineToRelative(2.86f)\n            close()\n            moveTo(10.094f, 12.715f)\n            verticalLineToRelative(0.715f)\n            horizontalLineToRelative(-1.43f)\n            verticalLineToRelative(-0.715f)\n            horizontalLineToRelative(1.43f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Base64: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Base64\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6.765f, 6.148f)\n            lineTo(17.235f, 6.148f)\n            arcTo(0.618f, 0.618f, 0f, isMoreThanHalf = false, isPositiveArc = true, 17.852f, 6.765f)\n            lineTo(17.852f, 17.235f)\n            arcTo(\n                0.618f,\n                0.618f,\n                0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                17.235f,\n                17.852f\n            )\n            lineTo(6.765f, 17.852f)\n            arcTo(0.618f, 0.618f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6.148f, 17.235f)\n            lineTo(6.148f, 6.765f)\n            arcTo(0.618f, 0.618f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6.765f, 6.148f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12.477f, 9.14f)\n            lineToRelative(1.43f, 0f)\n            lineToRelative(0f, 1.906f)\n            lineToRelative(1.43f, 0f)\n            lineToRelative(0f, -1.906f)\n            lineToRelative(1.43f, 0f)\n            lineToRelative(0f, 5.719f)\n            lineToRelative(-1.43f, 0f)\n            lineToRelative(0f, -2.383f)\n            lineToRelative(-2.86f, 0f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(11.523f, 10.57f)\n            verticalLineToRelative(-1.43f)\n            horizontalLineToRelative(-3.336f)\n            curveToRelative(-0.526f, 0f, -0.953f, 0.427f, -0.953f, 0.953f)\n            verticalLineToRelative(3.813f)\n            curveToRelative(0f, 0.526f, 0.427f, 0.953f, 0.953f, 0.953f)\n            horizontalLineToRelative(2.383f)\n            curveToRelative(0.526f, 0f, 0.953f, -0.427f, 0.953f, -0.953f)\n            verticalLineToRelative(-1.668f)\n            curveToRelative(0f, -0.526f, -0.427f, -0.953f, -0.953f, -0.953f)\n            horizontalLineToRelative(-1.906f)\n            verticalLineToRelative(-0.715f)\n            horizontalLineToRelative(2.86f)\n            close()\n            moveTo(10.094f, 12.715f)\n            verticalLineToRelative(0.715f)\n            horizontalLineToRelative(-1.43f)\n            verticalLineToRelative(-0.715f)\n            horizontalLineToRelative(1.43f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(22f, 10.889f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            curveToRelative(0f, -1.227f, -0.995f, -2.222f, -2.222f, -2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            curveToRelative(-1.227f, 0f, -2.222f, 0.995f, -2.222f, 2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            curveToRelative(0f, 1.227f, 0.995f, 2.222f, 2.222f, 2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            curveToRelative(1.227f, 0f, 2.222f, -0.995f, 2.222f, -2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(-2.222f)\n            verticalLineToRelative(-2.222f)\n            horizontalLineToRelative(2.222f)\n            close()\n            moveTo(17.852f, 17.235f)\n            curveToRelative(0f, 0.341f, -0.276f, 0.618f, -0.618f, 0.618f)\n            horizontalLineTo(6.765f)\n            curveToRelative(-0.341f, 0f, -0.618f, -0.276f, -0.618f, -0.618f)\n            verticalLineTo(6.765f)\n            curveToRelative(0f, -0.341f, 0.276f, -0.618f, 0.618f, -0.618f)\n            horizontalLineToRelative(10.469f)\n            curveToRelative(0.341f, 0f, 0.618f, 0.276f, 0.618f, 0.618f)\n            verticalLineToRelative(10.469f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BatchPrediction.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.BatchPrediction: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.BatchPrediction\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 880f)\n            quadTo(247f, 880f, 223.5f, 856.5f)\n            quadTo(200f, 833f, 200f, 800f)\n            lineTo(200f, 400f)\n            quadTo(200f, 367f, 223.5f, 343.5f)\n            quadTo(247f, 320f, 280f, 320f)\n            lineTo(680f, 320f)\n            quadTo(713f, 320f, 736.5f, 343.5f)\n            quadTo(760f, 367f, 760f, 400f)\n            lineTo(760f, 800f)\n            quadTo(760f, 833f, 736.5f, 856.5f)\n            quadTo(713f, 880f, 680f, 880f)\n            lineTo(280f, 880f)\n            close()\n            moveTo(280f, 800f)\n            lineTo(680f, 800f)\n            quadTo(680f, 800f, 680f, 800f)\n            quadTo(680f, 800f, 680f, 800f)\n            lineTo(680f, 400f)\n            quadTo(680f, 400f, 680f, 400f)\n            quadTo(680f, 400f, 680f, 400f)\n            lineTo(280f, 400f)\n            quadTo(280f, 400f, 280f, 400f)\n            quadTo(280f, 400f, 280f, 400f)\n            lineTo(280f, 800f)\n            quadTo(280f, 800f, 280f, 800f)\n            quadTo(280f, 800f, 280f, 800f)\n            close()\n            moveTo(440f, 760f)\n            lineTo(520f, 760f)\n            lineTo(520f, 720f)\n            lineTo(440f, 720f)\n            lineTo(440f, 760f)\n            close()\n            moveTo(440f, 680f)\n            lineTo(520f, 680f)\n            quadTo(520f, 661f, 529.5f, 645.5f)\n            quadTo(539f, 630f, 550f, 615f)\n            quadTo(562f, 598f, 571f, 578.5f)\n            quadTo(580f, 559f, 580f, 538f)\n            quadTo(580f, 497f, 551f, 468.5f)\n            quadTo(522f, 440f, 480f, 440f)\n            quadTo(438f, 440f, 409f, 468.5f)\n            quadTo(380f, 497f, 380f, 538f)\n            quadTo(380f, 559f, 389.5f, 578f)\n            quadTo(399f, 597f, 410f, 614f)\n            quadTo(421f, 630f, 430.5f, 645.5f)\n            quadTo(440f, 661f, 440f, 680f)\n            close()\n            moveTo(240f, 260f)\n            quadTo(240f, 235f, 257.5f, 217.5f)\n            quadTo(275f, 200f, 300f, 200f)\n            lineTo(660f, 200f)\n            quadTo(685f, 200f, 702.5f, 217.5f)\n            quadTo(720f, 235f, 720f, 260f)\n            lineTo(240f, 260f)\n            close()\n            moveTo(280f, 140f)\n            quadTo(280f, 115f, 297.5f, 97.5f)\n            quadTo(315f, 80f, 340f, 80f)\n            lineTo(620f, 80f)\n            quadTo(645f, 80f, 662.5f, 97.5f)\n            quadTo(680f, 115f, 680f, 140f)\n            lineTo(280f, 140f)\n            close()\n            moveTo(480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            lineTo(480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            lineTo(480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            lineTo(480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            quadTo(480f, 600f, 480f, 600f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Beta.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Beta: ImageVector by lazy {\n    Builder(\n        name = \"Beta\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(9.23f, 17.59f)\n            verticalLineTo(23.12f)\n            horizontalLineTo(6.88f)\n            verticalLineTo(6.72f)\n            curveTo(6.88f, 5.27f, 7.31f, 4.13f, 8.16f, 3.28f)\n            curveTo(9.0f, 2.43f, 10.17f, 2.0f, 11.61f, 2.0f)\n            curveTo(13.0f, 2.0f, 14.07f, 2.34f, 14.87f, 3.0f)\n            curveTo(15.66f, 3.68f, 16.05f, 4.62f, 16.05f, 5.81f)\n            curveTo(16.05f, 6.63f, 15.79f, 7.4f, 15.27f, 8.11f)\n            curveTo(14.75f, 8.82f, 14.08f, 9.31f, 13.25f, 9.58f)\n            verticalLineTo(9.62f)\n            curveTo(14.5f, 9.82f, 15.47f, 10.27f, 16.13f, 11.0f)\n            curveTo(16.79f, 11.71f, 17.12f, 12.62f, 17.12f, 13.74f)\n            curveTo(17.12f, 15.06f, 16.66f, 16.14f, 15.75f, 16.97f)\n            curveTo(14.83f, 17.8f, 13.63f, 18.21f, 12.13f, 18.21f)\n            curveTo(11.07f, 18.21f, 10.1f, 18.0f, 9.23f, 17.59f)\n            moveTo(10.72f, 10.75f)\n            verticalLineTo(8.83f)\n            curveTo(11.59f, 8.72f, 12.3f, 8.4f, 12.87f, 7.86f)\n            curveTo(13.43f, 7.31f, 13.71f, 6.7f, 13.71f, 6.0f)\n            curveTo(13.71f, 4.62f, 13.0f, 3.92f, 11.6f, 3.92f)\n            curveTo(10.84f, 3.92f, 10.25f, 4.16f, 9.84f, 4.65f)\n            curveTo(9.43f, 5.14f, 9.23f, 5.82f, 9.23f, 6.71f)\n            verticalLineTo(15.5f)\n            curveTo(10.14f, 16.03f, 11.03f, 16.29f, 11.89f, 16.29f)\n            curveTo(12.73f, 16.29f, 13.39f, 16.07f, 13.86f, 15.64f)\n            curveTo(14.33f, 15.2f, 14.56f, 14.58f, 14.56f, 13.79f)\n            curveTo(14.56f, 12.0f, 13.28f, 11.0f, 10.72f, 10.75f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Bitcoin.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Bitcoin: ImageVector by lazy {\n    Builder(\n        name = \"Bitcoin\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(14.24f, 10.56f)\n            curveTo(13.93f, 11.8f, 12.0f, 11.17f, 11.4f, 11.0f)\n            lineTo(11.95f, 8.82f)\n            curveTo(12.57f, 9.0f, 14.56f, 9.26f, 14.24f, 10.56f)\n            moveTo(11.13f, 12.12f)\n            lineTo(10.53f, 14.53f)\n            curveTo(11.27f, 14.72f, 13.56f, 15.45f, 13.9f, 14.09f)\n            curveTo(14.26f, 12.67f, 11.87f, 12.3f, 11.13f, 12.12f)\n            moveTo(21.7f, 14.42f)\n            curveTo(20.36f, 19.78f, 14.94f, 23.04f, 9.58f, 21.7f)\n            curveTo(4.22f, 20.36f, 0.963f, 14.94f, 2.3f, 9.58f)\n            curveTo(3.64f, 4.22f, 9.06f, 0.964f, 14.42f, 2.3f)\n            curveTo(19.77f, 3.64f, 23.03f, 9.06f, 21.7f, 14.42f)\n            moveTo(14.21f, 8.05f)\n            lineTo(14.66f, 6.25f)\n            lineTo(13.56f, 6.0f)\n            lineTo(13.12f, 7.73f)\n            curveTo(12.83f, 7.66f, 12.54f, 7.59f, 12.24f, 7.53f)\n            lineTo(12.68f, 5.76f)\n            lineTo(11.59f, 5.5f)\n            lineTo(11.14f, 7.29f)\n            curveTo(10.9f, 7.23f, 10.66f, 7.18f, 10.44f, 7.12f)\n            lineTo(10.44f, 7.12f)\n            lineTo(8.93f, 6.74f)\n            lineTo(8.63f, 7.91f)\n            curveTo(8.63f, 7.91f, 9.45f, 8.1f, 9.43f, 8.11f)\n            curveTo(9.88f, 8.22f, 9.96f, 8.5f, 9.94f, 8.75f)\n            lineTo(8.71f, 13.68f)\n            curveTo(8.66f, 13.82f, 8.5f, 14.0f, 8.21f, 13.95f)\n            curveTo(8.22f, 13.96f, 7.41f, 13.75f, 7.41f, 13.75f)\n            lineTo(6.87f, 15.0f)\n            lineTo(8.29f, 15.36f)\n            curveTo(8.56f, 15.43f, 8.82f, 15.5f, 9.08f, 15.56f)\n            lineTo(8.62f, 17.38f)\n            lineTo(9.72f, 17.66f)\n            lineTo(10.17f, 15.85f)\n            curveTo(10.47f, 15.93f, 10.76f, 16.0f, 11.04f, 16.08f)\n            lineTo(10.59f, 17.87f)\n            lineTo(11.69f, 18.15f)\n            lineTo(12.15f, 16.33f)\n            curveTo(14.0f, 16.68f, 15.42f, 16.54f, 16.0f, 14.85f)\n            curveTo(16.5f, 13.5f, 16.0f, 12.7f, 15.0f, 12.19f)\n            curveTo(15.72f, 12.0f, 16.26f, 11.55f, 16.41f, 10.57f)\n            curveTo(16.61f, 9.24f, 15.59f, 8.53f, 14.21f, 8.05f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Block.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.TwoTone.Block: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Block\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 2f)\n            lineTo(12f, 2f)\n            arcTo(10f, 10f, 0f, isMoreThanHalf = false, isPositiveArc = true, 22f, 12f)\n            lineTo(22f, 12f)\n            arcTo(10f, 10f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12f, 22f)\n            lineTo(12f, 22f)\n            arcTo(10f, 10f, 0f, isMoreThanHalf = false, isPositiveArc = true, 2f, 12f)\n            lineTo(2f, 12f)\n            arcTo(10f, 10f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12f, 2f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 22f)\n            curveToRelative(-1.383f, 0f, -2.683f, -0.262f, -3.9f, -0.788f)\n            reflectiveCurveToRelative(-2.275f, -1.237f, -3.175f, -2.138f)\n            reflectiveCurveToRelative(-1.612f, -1.958f, -2.138f, -3.175f)\n            reflectiveCurveToRelative(-0.788f, -2.517f, -0.788f, -3.9f)\n            curveToRelative(0f, -1.383f, 0.262f, -2.683f, 0.788f, -3.9f)\n            reflectiveCurveToRelative(1.237f, -2.275f, 2.138f, -3.175f)\n            reflectiveCurveToRelative(1.958f, -1.612f, 3.175f, -2.138f)\n            reflectiveCurveToRelative(2.517f, -0.788f, 3.9f, -0.788f)\n            curveToRelative(1.383f, 0f, 2.683f, 0.262f, 3.9f, 0.788f)\n            reflectiveCurveToRelative(2.275f, 1.237f, 3.175f, 2.138f)\n            reflectiveCurveToRelative(1.612f, 1.958f, 2.138f, 3.175f)\n            reflectiveCurveToRelative(0.788f, 2.517f, 0.788f, 3.9f)\n            curveToRelative(0f, 1.383f, -0.262f, 2.683f, -0.788f, 3.9f)\n            reflectiveCurveToRelative(-1.237f, 2.275f, -2.138f, 3.175f)\n            reflectiveCurveToRelative(-1.958f, 1.612f, -3.175f, 2.138f)\n            reflectiveCurveToRelative(-2.517f, 0.788f, -3.9f, 0.788f)\n            close()\n            moveTo(12f, 20f)\n            curveToRelative(0.9f, 0f, 1.767f, -0.146f, 2.6f, -0.438f)\n            reflectiveCurveToRelative(1.6f, -0.712f, 2.3f, -1.263f)\n            lineTo(5.7f, 7.1f)\n            curveToRelative(-0.55f, 0.7f, -0.971f, 1.467f, -1.263f, 2.3f)\n            reflectiveCurveToRelative(-0.438f, 1.7f, -0.438f, 2.6f)\n            curveToRelative(0f, 2.233f, 0.775f, 4.125f, 2.325f, 5.675f)\n            reflectiveCurveToRelative(3.442f, 2.325f, 5.675f, 2.325f)\n            close()\n            moveTo(18.3f, 16.9f)\n            curveToRelative(0.55f, -0.7f, 0.971f, -1.467f, 1.263f, -2.3f)\n            reflectiveCurveToRelative(0.438f, -1.7f, 0.438f, -2.6f)\n            curveToRelative(0f, -2.233f, -0.775f, -4.125f, -2.325f, -5.675f)\n            reflectiveCurveToRelative(-3.442f, -2.325f, -5.675f, -2.325f)\n            curveToRelative(-0.9f, 0f, -1.767f, 0.146f, -2.6f, 0.438f)\n            reflectiveCurveToRelative(-1.6f, 0.712f, -2.3f, 1.263f)\n            lineToRelative(11.2f, 11.2f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BlurCircular.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.BlurCircular: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.BlurCircular\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(400f, 440f)\n            quadTo(417f, 440f, 428.5f, 428.5f)\n            quadTo(440f, 417f, 440f, 400f)\n            quadTo(440f, 383f, 428.5f, 371.5f)\n            quadTo(417f, 360f, 400f, 360f)\n            quadTo(383f, 360f, 371.5f, 371.5f)\n            quadTo(360f, 383f, 360f, 400f)\n            quadTo(360f, 417f, 371.5f, 428.5f)\n            quadTo(383f, 440f, 400f, 440f)\n            close()\n            moveTo(400f, 600f)\n            quadTo(417f, 600f, 428.5f, 588.5f)\n            quadTo(440f, 577f, 440f, 560f)\n            quadTo(440f, 543f, 428.5f, 531.5f)\n            quadTo(417f, 520f, 400f, 520f)\n            quadTo(383f, 520f, 371.5f, 531.5f)\n            quadTo(360f, 543f, 360f, 560f)\n            quadTo(360f, 577f, 371.5f, 588.5f)\n            quadTo(383f, 600f, 400f, 600f)\n            close()\n            moveTo(280f, 420f)\n            quadTo(288f, 420f, 294f, 414f)\n            quadTo(300f, 408f, 300f, 400f)\n            quadTo(300f, 392f, 294f, 386f)\n            quadTo(288f, 380f, 280f, 380f)\n            quadTo(272f, 380f, 266f, 386f)\n            quadTo(260f, 392f, 260f, 400f)\n            quadTo(260f, 408f, 266f, 414f)\n            quadTo(272f, 420f, 280f, 420f)\n            close()\n            moveTo(400f, 700f)\n            quadTo(408f, 700f, 414f, 694f)\n            quadTo(420f, 688f, 420f, 680f)\n            quadTo(420f, 672f, 414f, 666f)\n            quadTo(408f, 660f, 400f, 660f)\n            quadTo(392f, 660f, 386f, 666f)\n            quadTo(380f, 672f, 380f, 680f)\n            quadTo(380f, 688f, 386f, 694f)\n            quadTo(392f, 700f, 400f, 700f)\n            close()\n            moveTo(280f, 580f)\n            quadTo(288f, 580f, 294f, 574f)\n            quadTo(300f, 568f, 300f, 560f)\n            quadTo(300f, 552f, 294f, 546f)\n            quadTo(288f, 540f, 280f, 540f)\n            quadTo(272f, 540f, 266f, 546f)\n            quadTo(260f, 552f, 260f, 560f)\n            quadTo(260f, 568f, 266f, 574f)\n            quadTo(272f, 580f, 280f, 580f)\n            close()\n            moveTo(400f, 300f)\n            quadTo(408f, 300f, 414f, 294f)\n            quadTo(420f, 288f, 420f, 280f)\n            quadTo(420f, 272f, 414f, 266f)\n            quadTo(408f, 260f, 400f, 260f)\n            quadTo(392f, 260f, 386f, 266f)\n            quadTo(380f, 272f, 380f, 280f)\n            quadTo(380f, 288f, 386f, 294f)\n            quadTo(392f, 300f, 400f, 300f)\n            close()\n            moveTo(560f, 440f)\n            quadTo(577f, 440f, 588.5f, 428.5f)\n            quadTo(600f, 417f, 600f, 400f)\n            quadTo(600f, 383f, 588.5f, 371.5f)\n            quadTo(577f, 360f, 560f, 360f)\n            quadTo(543f, 360f, 531.5f, 371.5f)\n            quadTo(520f, 383f, 520f, 400f)\n            quadTo(520f, 417f, 531.5f, 428.5f)\n            quadTo(543f, 440f, 560f, 440f)\n            close()\n            moveTo(560f, 300f)\n            quadTo(568f, 300f, 574f, 294f)\n            quadTo(580f, 288f, 580f, 280f)\n            quadTo(580f, 272f, 574f, 266f)\n            quadTo(568f, 260f, 560f, 260f)\n            quadTo(552f, 260f, 546f, 266f)\n            quadTo(540f, 272f, 540f, 280f)\n            quadTo(540f, 288f, 546f, 294f)\n            quadTo(552f, 300f, 560f, 300f)\n            close()\n            moveTo(680f, 580f)\n            quadTo(688f, 580f, 694f, 574f)\n            quadTo(700f, 568f, 700f, 560f)\n            quadTo(700f, 552f, 694f, 546f)\n            quadTo(688f, 540f, 680f, 540f)\n            quadTo(672f, 540f, 666f, 546f)\n            quadTo(660f, 552f, 660f, 560f)\n            quadTo(660f, 568f, 666f, 574f)\n            quadTo(672f, 580f, 680f, 580f)\n            close()\n            moveTo(680f, 420f)\n            quadTo(688f, 420f, 694f, 414f)\n            quadTo(700f, 408f, 700f, 400f)\n            quadTo(700f, 392f, 694f, 386f)\n            quadTo(688f, 380f, 680f, 380f)\n            quadTo(672f, 380f, 666f, 386f)\n            quadTo(660f, 392f, 660f, 400f)\n            quadTo(660f, 408f, 666f, 414f)\n            quadTo(672f, 420f, 680f, 420f)\n            close()\n            moveTo(480f, 880f)\n            quadTo(397f, 880f, 324f, 848.5f)\n            quadTo(251f, 817f, 197f, 763f)\n            quadTo(143f, 709f, 111.5f, 636f)\n            quadTo(80f, 563f, 80f, 480f)\n            quadTo(80f, 397f, 111.5f, 324f)\n            quadTo(143f, 251f, 197f, 197f)\n            quadTo(251f, 143f, 324f, 111.5f)\n            quadTo(397f, 80f, 480f, 80f)\n            quadTo(563f, 80f, 636f, 111.5f)\n            quadTo(709f, 143f, 763f, 197f)\n            quadTo(817f, 251f, 848.5f, 324f)\n            quadTo(880f, 397f, 880f, 480f)\n            quadTo(880f, 563f, 848.5f, 636f)\n            quadTo(817f, 709f, 763f, 763f)\n            quadTo(709f, 817f, 636f, 848.5f)\n            quadTo(563f, 880f, 480f, 880f)\n            close()\n            moveTo(560f, 700f)\n            quadTo(568f, 700f, 574f, 694f)\n            quadTo(580f, 688f, 580f, 680f)\n            quadTo(580f, 672f, 574f, 666f)\n            quadTo(568f, 660f, 560f, 660f)\n            quadTo(552f, 660f, 546f, 666f)\n            quadTo(540f, 672f, 540f, 680f)\n            quadTo(540f, 688f, 546f, 694f)\n            quadTo(552f, 700f, 560f, 700f)\n            close()\n            moveTo(560f, 600f)\n            quadTo(577f, 600f, 588.5f, 588.5f)\n            quadTo(600f, 577f, 600f, 560f)\n            quadTo(600f, 543f, 588.5f, 531.5f)\n            quadTo(577f, 520f, 560f, 520f)\n            quadTo(543f, 520f, 531.5f, 531.5f)\n            quadTo(520f, 543f, 520f, 560f)\n            quadTo(520f, 577f, 531.5f, 588.5f)\n            quadTo(543f, 600f, 560f, 600f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BoldLine.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.BoldLine: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"BoldLine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19.071f, 4.929f)\n            curveToRelative(-0.585f, -0.585f, -1.534f, -0.585f, -2.12f, 0f)\n            lineTo(12.709f, 9.172f)\n            curveToRelative(-0f, 0f, -0f, 0f, -0f, 0f)\n            lineToRelative(-3.537f, 3.537f)\n            curveToRelative(-0f, 0f, -0f, 0f, -0f, 0f)\n            lineToRelative(-4.242f, 4.242f)\n            curveToRelative(-0.585f, 0.585f, -0.585f, 1.534f, 0f, 2.119f)\n            curveToRelative(0.585f, 0.585f, 1.534f, 0.585f, 2.12f, 0f)\n            lineToRelative(4.242f, -4.242f)\n            curveToRelative(0f, -0f, 0f, -0f, 0f, -0f)\n            lineToRelative(3.537f, -3.537f)\n            lineToRelative(4.242f, -4.242f)\n            curveTo(19.656f, 6.464f, 19.656f, 5.515f, 19.071f, 4.929f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Bolt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Bolt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Bolt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10.55f, 18.2f)\n            lineToRelative(5.175f, -6.2f)\n            horizontalLineToRelative(-4f)\n            lineToRelative(0.725f, -5.675f)\n            lineToRelative(-4.625f, 6.675f)\n            horizontalLineToRelative(3.475f)\n            lineToRelative(-0.75f, 5.2f)\n            close()\n            moveTo(9f, 15f)\n            horizontalLineToRelative(-3.1f)\n            curveToRelative(-0.4f, 0f, -0.696f, -0.179f, -0.887f, -0.538f)\n            reflectiveCurveToRelative(-0.171f, -0.704f, 0.063f, -1.038f)\n            lineTo(12.55f, 2.675f)\n            curveToRelative(0.167f, -0.233f, 0.383f, -0.396f, 0.65f, -0.488f)\n            reflectiveCurveToRelative(0.542f, -0.087f, 0.825f, 0.013f)\n            reflectiveCurveToRelative(0.492f, 0.275f, 0.625f, 0.525f)\n            reflectiveCurveToRelative(0.183f, 0.517f, 0.15f, 0.8f)\n            lineToRelative(-0.8f, 6.475f)\n            horizontalLineToRelative(3.875f)\n            curveToRelative(0.433f, 0f, 0.738f, 0.192f, 0.913f, 0.575f)\n            reflectiveCurveToRelative(0.121f, 0.742f, -0.162f, 1.075f)\n            lineToRelative(-8.225f, 9.85f)\n            curveToRelative(-0.183f, 0.217f, -0.408f, 0.358f, -0.675f, 0.425f)\n            reflectiveCurveToRelative(-0.525f, 0.042f, -0.775f, -0.075f)\n            reflectiveCurveToRelative(-0.446f, -0.296f, -0.587f, -0.538f)\n            reflectiveCurveToRelative(-0.196f, -0.504f, -0.162f, -0.788f)\n            lineToRelative(0.8f, -5.525f)\n            close()\n        }\n    }.build()\n}\n\n\nval Icons.TwoTone.Bolt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoToneBolt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.787f, 10.575f)\n            curveToRelative(-0.175f, -0.383f, -0.479f, -0.575f, -0.912f, -0.575f)\n            horizontalLineToRelative(-3.875f)\n            lineToRelative(0.8f, -6.475f)\n            curveToRelative(0.033f, -0.283f, -0.017f, -0.55f, -0.15f, -0.8f)\n            curveToRelative(-0.133f, -0.25f, -0.342f, -0.425f, -0.625f, -0.525f)\n            curveToRelative(-0.283f, -0.1f, -0.558f, -0.104f, -0.825f, -0.013f)\n            reflectiveCurveToRelative(-0.483f, 0.254f, -0.65f, 0.487f)\n            lineToRelative(-7.475f, 10.75f)\n            curveToRelative(-0.233f, 0.333f, -0.254f, 0.679f, -0.063f, 1.038f)\n            reflectiveCurveToRelative(0.487f, 0.537f, 0.888f, 0.537f)\n            horizontalLineToRelative(3.1f)\n            lineToRelative(-0.8f, 5.525f)\n            curveToRelative(-0.033f, 0.283f, 0.021f, 0.546f, 0.162f, 0.787f)\n            reflectiveCurveToRelative(0.338f, 0.421f, 0.588f, 0.537f)\n            curveToRelative(0.25f, 0.117f, 0.508f, 0.142f, 0.775f, 0.075f)\n            reflectiveCurveToRelative(0.492f, -0.208f, 0.675f, -0.425f)\n            lineToRelative(8.225f, -9.85f)\n            curveToRelative(0.283f, -0.333f, 0.338f, -0.692f, 0.162f, -1.075f)\n            close()\n            moveTo(10.55f, 18.2f)\n            lineToRelative(0.75f, -5.2f)\n            horizontalLineToRelative(-3.475f)\n            lineToRelative(4.625f, -6.675f)\n            lineToRelative(-0.725f, 5.675f)\n            horizontalLineToRelative(4f)\n            lineToRelative(-5.175f, 6.2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(10.55f, 18.2f)\n            lineToRelative(5.175f, -6.2f)\n            lineToRelative(-4f, 0f)\n            lineToRelative(0.725f, -5.675f)\n            lineToRelative(-4.625f, 6.675f)\n            lineToRelative(3.475f, 0f)\n            lineToRelative(-0.75f, 5.2f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BookmarkOff.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.BookmarkOff: ImageVector by lazy {\n    Builder(\n        name = \"Bookmark Off\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(3.28f, 4.0f)\n            lineTo(2.0f, 5.27f)\n            lineTo(5.0f, 8.27f)\n            verticalLineTo(21.0f)\n            lineTo(12.0f, 18.0f)\n            lineTo(16.78f, 20.05f)\n            lineTo(18.73f, 22.0f)\n            lineTo(20.0f, 20.72f)\n            lineTo(3.28f, 4.0f)\n            moveTo(7.0f, 18.0f)\n            verticalLineTo(10.27f)\n            lineTo(13.0f, 16.25f)\n            lineTo(12.0f, 15.82f)\n            lineTo(7.0f, 18.0f)\n            moveTo(7.0f, 5.16f)\n            lineTo(5.5f, 3.67f)\n            curveTo(5.88f, 3.26f, 6.41f, 3.0f, 7.0f, 3.0f)\n            horizontalLineTo(17.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 19.0f,\n                y1 = 5.0f\n            )\n            verticalLineTo(17.16f)\n            lineTo(17.0f, 15.16f)\n            verticalLineTo(5.0f)\n            horizontalLineTo(7.0f)\n            verticalLineTo(5.16f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BookmarkRemove.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.BookmarkRemove: ImageVector by lazy {\n    Builder(\n        name = \"Bookmark Remove\", defaultWidth = 24.0.dp, defaultHeight\n        = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.0f, 3.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 19.0f,\n                y1 = 5.0f\n            )\n            verticalLineTo(21.0f)\n            lineTo(12.0f, 18.0f)\n            lineTo(5.0f, 21.0f)\n            verticalLineTo(5.0f)\n            curveTo(5.0f, 3.89f, 5.9f, 3.0f, 7.0f, 3.0f)\n            horizontalLineTo(17.0f)\n            moveTo(8.17f, 8.58f)\n            lineTo(10.59f, 11.0f)\n            lineTo(8.17f, 13.41f)\n            lineTo(9.59f, 14.83f)\n            lineTo(12.0f, 12.41f)\n            lineTo(14.41f, 14.83f)\n            lineTo(15.83f, 13.41f)\n            lineTo(13.41f, 11.0f)\n            lineTo(15.83f, 8.58f)\n            lineTo(14.41f, 7.17f)\n            lineTo(12.0f, 9.58f)\n            lineTo(9.59f, 7.17f)\n            lineTo(8.17f, 8.58f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Boosty.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Boosty: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Boosty\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(2.661f, 14.337f)\n            lineTo(6.801f, 0f)\n            horizontalLineToRelative(6.362f)\n            lineTo(11.88f, 4.444f)\n            lineToRelative(-0.038f, 0.077f)\n            lineToRelative(-3.378f, 11.733f)\n            horizontalLineToRelative(3.15f)\n            curveToRelative(-1.321f, 3.289f, -2.35f, 5.867f, -3.086f, 7.733f)\n            curveToRelative(-5.816f, -0.063f, -7.442f, -4.228f, -6.02f, -9.155f)\n            moveTo(8.554f, 24f)\n            lineToRelative(7.67f, -11.035f)\n            horizontalLineToRelative(-3.25f)\n            lineToRelative(2.83f, -7.073f)\n            curveToRelative(4.852f, 0.508f, 7.137f, 4.33f, 5.791f, 8.952f)\n            curveTo(20.16f, 19.81f, 14.344f, 24f, 8.68f, 24f)\n            horizontalLineToRelative(-0.127f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BorderColor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.BorderColor: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"BorderColor\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(160f, 960f)\n            quadTo(127f, 960f, 103.5f, 936.5f)\n            quadTo(80f, 913f, 80f, 880f)\n            quadTo(80f, 847f, 103.5f, 823.5f)\n            quadTo(127f, 800f, 160f, 800f)\n            lineTo(800f, 800f)\n            quadTo(833f, 800f, 856.5f, 823.5f)\n            quadTo(880f, 847f, 880f, 880f)\n            quadTo(880f, 913f, 856.5f, 936.5f)\n            quadTo(833f, 960f, 800f, 960f)\n            lineTo(160f, 960f)\n            close()\n            moveTo(240f, 640f)\n            lineTo(296f, 640f)\n            lineTo(608f, 329f)\n            lineTo(579f, 300f)\n            lineTo(551f, 272f)\n            lineTo(240f, 584f)\n            lineTo(240f, 640f)\n            close()\n            moveTo(160f, 680f)\n            lineTo(160f, 567f)\n            quadTo(160f, 559f, 163f, 551.5f)\n            quadTo(166f, 544f, 172f, 538f)\n            lineTo(608f, 103f)\n            quadTo(619f, 92f, 633.5f, 86f)\n            quadTo(648f, 80f, 664f, 80f)\n            quadTo(680f, 80f, 695f, 86f)\n            quadTo(710f, 92f, 722f, 104f)\n            lineTo(777f, 160f)\n            quadTo(789f, 171f, 794.5f, 186f)\n            quadTo(800f, 201f, 800f, 217f)\n            quadTo(800f, 232f, 794.5f, 246.5f)\n            quadTo(789f, 261f, 777f, 273f)\n            lineTo(342f, 708f)\n            quadTo(336f, 714f, 328.5f, 717f)\n            quadTo(321f, 720f, 313f, 720f)\n            lineTo(200f, 720f)\n            quadTo(183f, 720f, 171.5f, 708.5f)\n            quadTo(160f, 697f, 160f, 680f)\n            close()\n            moveTo(720f, 216f)\n            lineTo(720f, 216f)\n            lineTo(664f, 160f)\n            lineTo(664f, 160f)\n            lineTo(720f, 216f)\n            close()\n            moveTo(608f, 329f)\n            lineTo(579f, 300f)\n            lineTo(551f, 272f)\n            lineTo(551f, 272f)\n            lineTo(608f, 329f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BrokenImageAlt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.BrokenImageAlt: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"BrokenImageAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19f, 3f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 21f, 5f)\n            verticalLineTo(11f)\n            horizontalLineTo(19f)\n            verticalLineTo(13f)\n            horizontalLineTo(19f)\n            lineTo(17f, 13f)\n            verticalLineTo(15f)\n            horizontalLineTo(15f)\n            verticalLineTo(17f)\n            horizontalLineTo(13f)\n            verticalLineTo(19f)\n            horizontalLineTo(11f)\n            verticalLineTo(21f)\n            horizontalLineTo(5f)\n            curveTo(3.89f, 21f, 3f, 20.1f, 3f, 19f)\n            verticalLineTo(5f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 5f, 3f)\n            horizontalLineTo(19f)\n            moveTo(21f, 15f)\n            verticalLineTo(19f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 19f, 21f)\n            horizontalLineTo(19f)\n            lineTo(15f, 21f)\n            verticalLineTo(19f)\n            horizontalLineTo(17f)\n            verticalLineTo(17f)\n            horizontalLineTo(19f)\n            verticalLineTo(15f)\n            horizontalLineTo(21f)\n            moveTo(19f, 8.5f)\n            arcTo(0.5f, 0.5f, 0f, isMoreThanHalf = false, isPositiveArc = false, 18.5f, 8f)\n            horizontalLineTo(5.5f)\n            arcTo(0.5f, 0.5f, 0f, isMoreThanHalf = false, isPositiveArc = false, 5f, 8.5f)\n            verticalLineTo(15.5f)\n            arcTo(0.5f, 0.5f, 0f, isMoreThanHalf = false, isPositiveArc = false, 5.5f, 16f)\n            horizontalLineTo(11f)\n            verticalLineTo(15f)\n            horizontalLineTo(13f)\n            verticalLineTo(13f)\n            horizontalLineTo(15f)\n            verticalLineTo(11f)\n            horizontalLineTo(17f)\n            verticalLineTo(9f)\n            horizontalLineTo(19f)\n            verticalLineTo(8.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BrushColor.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.BrushColor: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.BrushColor\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6.332f, 17.919f)\n            curveToRelative(-0.625f, 0f, -1.243f, -0.153f, -1.853f, -0.458f)\n            curveToRelative(-0.611f, -0.305f, -1.104f, -0.708f, -1.479f, -1.208f)\n            curveToRelative(0.361f, 0f, 0.729f, -0.142f, 1.104f, -0.427f)\n            reflectiveCurveToRelative(0.562f, -0.698f, 0.562f, -1.239f)\n            curveToRelative(0f, -0.694f, 0.243f, -1.284f, 0.729f, -1.77f)\n            reflectiveCurveToRelative(1.076f, -0.729f, 1.77f, -0.729f)\n            reflectiveCurveToRelative(1.284f, 0.243f, 1.77f, 0.729f)\n            reflectiveCurveToRelative(0.729f, 1.076f, 0.729f, 1.77f)\n            curveToRelative(0f, 0.916f, -0.326f, 1.701f, -0.979f, 2.353f)\n            reflectiveCurveToRelative(-1.437f, 0.979f, -2.353f, 0.979f)\n            close()\n            moveTo(6.332f, 16.253f)\n            curveToRelative(0.458f, 0f, 0.85f, -0.163f, 1.177f, -0.489f)\n            reflectiveCurveToRelative(0.489f, -0.718f, 0.489f, -1.177f)\n            curveToRelative(0f, -0.236f, -0.08f, -0.434f, -0.239f, -0.594f)\n            reflectiveCurveToRelative(-0.358f, -0.239f, -0.594f, -0.239f)\n            reflectiveCurveToRelative(-0.434f, 0.08f, -0.594f, 0.239f)\n            curveToRelative(-0.16f, 0.16f, -0.239f, 0.358f, -0.239f, 0.594f)\n            curveToRelative(0f, 0.319f, -0.038f, 0.611f, -0.115f, 0.875f)\n            reflectiveCurveToRelative(-0.177f, 0.514f, -0.302f, 0.75f)\n            curveToRelative(0.069f, 0.028f, 0.139f, 0.042f, 0.208f, 0.042f)\n            horizontalLineToRelative(0.208f)\n            close()\n            moveTo(11.122f, 12.92f)\n            lineToRelative(-2.291f, -2.291f)\n            lineToRelative(7.456f, -7.456f)\n            curveToRelative(0.153f, -0.153f, 0.344f, -0.233f, 0.573f, -0.239f)\n            reflectiveCurveToRelative(0.427f, 0.073f, 0.594f, 0.239f)\n            lineToRelative(1.125f, 1.125f)\n            curveToRelative(0.167f, 0.167f, 0.25f, 0.361f, 0.25f, 0.583f)\n            reflectiveCurveToRelative(-0.083f, 0.417f, -0.25f, 0.583f)\n            lineToRelative(-7.456f, 7.456f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.656f, 21.066f)\n            curveToRelative(-0.594f, 0f, -1.155f, -0.114f, -1.683f, -0.342f)\n            reflectiveCurveToRelative(-0.99f, -0.539f, -1.385f, -0.934f)\n            reflectiveCurveToRelative(-0.706f, -0.856f, -0.934f, -1.385f)\n            reflectiveCurveToRelative(-0.342f, -1.09f, -0.342f, -1.683f)\n            curveToRelative(0f, -0.601f, 0.118f, -1.166f, 0.353f, -1.694f)\n            curveToRelative(0.235f, -0.529f, 0.554f, -0.988f, 0.956f, -1.379f)\n            reflectiveCurveToRelative(0.871f, -0.701f, 1.406f, -0.929f)\n            reflectiveCurveToRelative(1.108f, -0.342f, 1.716f, -0.342f)\n            curveToRelative(0.579f, 0f, 1.126f, 0.1f, 1.64f, 0.299f)\n            reflectiveCurveToRelative(0.965f, 0.474f, 1.352f, 0.825f)\n            reflectiveCurveToRelative(0.695f, 0.767f, 0.923f, 1.249f)\n            reflectiveCurveToRelative(0.342f, 1.001f, 0.342f, 1.558f)\n            curveToRelative(0f, 0.833f, -0.253f, 1.472f, -0.76f, 1.917f)\n            reflectiveCurveToRelative(-1.122f, 0.668f, -1.846f, 0.668f)\n            horizontalLineToRelative(-0.804f)\n            curveToRelative(-0.065f, 0f, -0.11f, 0.018f, -0.136f, 0.054f)\n            reflectiveCurveToRelative(-0.038f, 0.076f, -0.038f, 0.119f)\n            curveToRelative(0f, 0.087f, 0.054f, 0.212f, 0.163f, 0.375f)\n            reflectiveCurveToRelative(0.163f, 0.349f, 0.163f, 0.559f)\n            curveToRelative(0f, 0.362f, -0.1f, 0.63f, -0.299f, 0.804f)\n            reflectiveCurveToRelative(-0.462f, 0.261f, -0.787f, 0.261f)\n            close()\n            moveTo(14.266f, 17.156f)\n            curveToRelative(0.188f, 0f, 0.344f, -0.062f, 0.467f, -0.185f)\n            reflectiveCurveToRelative(0.185f, -0.279f, 0.185f, -0.467f)\n            curveToRelative(0f, -0.188f, -0.062f, -0.344f, -0.185f, -0.467f)\n            reflectiveCurveToRelative(-0.279f, -0.185f, -0.467f, -0.185f)\n            curveToRelative(-0.188f, 0f, -0.344f, 0.062f, -0.467f, 0.185f)\n            reflectiveCurveToRelative(-0.185f, 0.279f, -0.185f, 0.467f)\n            curveToRelative(0f, 0.188f, 0.062f, 0.344f, 0.185f, 0.467f)\n            reflectiveCurveToRelative(0.279f, 0.185f, 0.467f, 0.185f)\n            close()\n            moveTo(15.569f, 15.418f)\n            curveToRelative(0.188f, 0f, 0.344f, -0.062f, 0.467f, -0.185f)\n            reflectiveCurveToRelative(0.185f, -0.279f, 0.185f, -0.467f)\n            reflectiveCurveToRelative(-0.062f, -0.344f, -0.185f, -0.467f)\n            reflectiveCurveToRelative(-0.279f, -0.185f, -0.467f, -0.185f)\n            reflectiveCurveToRelative(-0.344f, 0.062f, -0.467f, 0.185f)\n            reflectiveCurveToRelative(-0.185f, 0.279f, -0.185f, 0.467f)\n            reflectiveCurveToRelative(0.062f, 0.344f, 0.185f, 0.467f)\n            reflectiveCurveToRelative(0.279f, 0.185f, 0.467f, 0.185f)\n            close()\n            moveTo(17.742f, 15.418f)\n            curveToRelative(0.188f, 0f, 0.344f, -0.062f, 0.467f, -0.185f)\n            reflectiveCurveToRelative(0.185f, -0.279f, 0.185f, -0.467f)\n            reflectiveCurveToRelative(-0.062f, -0.344f, -0.185f, -0.467f)\n            reflectiveCurveToRelative(-0.279f, -0.185f, -0.467f, -0.185f)\n            reflectiveCurveToRelative(-0.344f, 0.062f, -0.467f, 0.185f)\n            reflectiveCurveToRelative(-0.185f, 0.279f, -0.185f, 0.467f)\n            reflectiveCurveToRelative(0.062f, 0.344f, 0.185f, 0.467f)\n            reflectiveCurveToRelative(0.279f, 0.185f, 0.467f, 0.185f)\n            close()\n            moveTo(19.045f, 17.156f)\n            curveToRelative(0.188f, 0f, 0.344f, -0.062f, 0.467f, -0.185f)\n            reflectiveCurveToRelative(0.185f, -0.279f, 0.185f, -0.467f)\n            curveToRelative(0f, -0.188f, -0.062f, -0.344f, -0.185f, -0.467f)\n            reflectiveCurveToRelative(-0.279f, -0.185f, -0.467f, -0.185f)\n            reflectiveCurveToRelative(-0.344f, 0.062f, -0.467f, 0.185f)\n            reflectiveCurveToRelative(-0.185f, 0.279f, -0.185f, 0.467f)\n            curveToRelative(0f, 0.188f, 0.062f, 0.344f, 0.185f, 0.467f)\n            reflectiveCurveToRelative(0.279f, 0.185f, 0.467f, 0.185f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/BubbleDelete.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.BubbleDelete: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.BubbleDelete\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 3.285f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(15.575f)\n            curveToRelative(0f, 0.45f, 0.204f, 0.763f, 0.612f, 0.938f)\n            reflectiveCurveToRelative(0.771f, 0.104f, 1.088f, -0.213f)\n            lineToRelative(2.3f, -2.3f)\n            horizontalLineToRelative(14f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(4.697f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(20f, 16.697f)\n            horizontalLineTo(5.15f)\n            lineToRelative(-1.15f, 1.125f)\n            verticalLineTo(4.697f)\n            horizontalLineToRelative(16f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15.536f, 7.272f)\n            horizontalLineToRelative(-2.341f)\n            verticalLineToRelative(-0.687f)\n            curveToRelative(0f, -0.276f, -0.224f, -0.5f, -0.5f, -0.5f)\n            horizontalLineToRelative(-1.135f)\n            curveToRelative(-0.276f, 0f, -0.5f, 0.224f, -0.5f, 0.5f)\n            verticalLineToRelative(0.687f)\n            horizontalLineToRelative(-2.153f)\n            curveToRelative(-0.539f, 0f, -0.977f, 0.437f, -0.977f, 0.977f)\n            curveToRelative(0f, 0.539f, 0.437f, 0.977f, 0.977f, 0.977f)\n            horizontalLineToRelative(0.291f)\n            verticalLineToRelative(3.906f)\n            curveToRelative(0f, 1.079f, 0.874f, 1.953f, 1.953f, 1.953f)\n            horizontalLineToRelative(1.93f)\n            curveToRelative(0.073f, 0f, 0.137f, -0.027f, 0.205f, -0.041f)\n            verticalLineToRelative(0.041f)\n            curveToRelative(1.079f, 0f, 1.953f, -0.874f, 1.953f, -1.953f)\n            verticalLineToRelative(-3.906f)\n            horizontalLineToRelative(0.297f)\n            curveToRelative(0.539f, 0f, 0.977f, -0.437f, 0.977f, -0.977f)\n            curveToRelative(0f, -0.539f, -0.437f, -0.977f, -0.977f, -0.977f)\n            close()\n            moveTo(13.286f, 13.131f)\n            horizontalLineToRelative(-2.135f)\n            verticalLineToRelative(-3.906f)\n            horizontalLineToRelative(2.135f)\n            verticalLineToRelative(3.906f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.BubbleDelete: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.BubbleDelete\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 3.285f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(15.575f)\n            curveToRelative(0f, 0.45f, 0.204f, 0.763f, 0.612f, 0.938f)\n            reflectiveCurveToRelative(0.771f, 0.104f, 1.088f, -0.213f)\n            lineToRelative(2.3f, -2.3f)\n            horizontalLineToRelative(14f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(4.697f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(20f, 16.697f)\n            horizontalLineTo(5.15f)\n            lineToRelative(-1.15f, 1.125f)\n            verticalLineTo(4.697f)\n            horizontalLineToRelative(16f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15.536f, 7.272f)\n            horizontalLineToRelative(-2.341f)\n            verticalLineToRelative(-0.687f)\n            curveToRelative(0f, -0.276f, -0.224f, -0.5f, -0.5f, -0.5f)\n            horizontalLineToRelative(-1.135f)\n            curveToRelative(-0.276f, 0f, -0.5f, 0.224f, -0.5f, 0.5f)\n            verticalLineToRelative(0.687f)\n            horizontalLineToRelative(-2.153f)\n            curveToRelative(-0.539f, 0f, -0.977f, 0.437f, -0.977f, 0.977f)\n            curveToRelative(0f, 0.539f, 0.437f, 0.977f, 0.977f, 0.977f)\n            horizontalLineToRelative(0.291f)\n            verticalLineToRelative(3.906f)\n            curveToRelative(0f, 1.079f, 0.874f, 1.953f, 1.953f, 1.953f)\n            horizontalLineToRelative(1.93f)\n            curveToRelative(0.073f, 0f, 0.137f, -0.027f, 0.205f, -0.041f)\n            verticalLineToRelative(0.041f)\n            curveToRelative(1.079f, 0f, 1.953f, -0.874f, 1.953f, -1.953f)\n            verticalLineToRelative(-3.906f)\n            horizontalLineToRelative(0.297f)\n            curveToRelative(0.539f, 0f, 0.977f, -0.437f, 0.977f, -0.977f)\n            curveToRelative(0f, -0.539f, -0.437f, -0.977f, -0.977f, -0.977f)\n            close()\n            moveTo(13.286f, 13.131f)\n            horizontalLineToRelative(-2.135f)\n            verticalLineToRelative(-3.906f)\n            horizontalLineToRelative(2.135f)\n            verticalLineToRelative(3.906f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(4f, 4.697f)\n            horizontalLineToRelative(16f)\n            verticalLineToRelative(13.125f)\n            horizontalLineToRelative(-16f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Build.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Build: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Build\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9f, 15f)\n            curveToRelative(-1.667f, 0f, -3.083f, -0.583f, -4.25f, -1.75f)\n            reflectiveCurveToRelative(-1.75f, -2.583f, -1.75f, -4.25f)\n            curveToRelative(0f, -0.333f, 0.025f, -0.667f, 0.075f, -1f)\n            reflectiveCurveToRelative(0.142f, -0.65f, 0.275f, -0.95f)\n            curveToRelative(0.083f, -0.167f, 0.188f, -0.292f, 0.313f, -0.375f)\n            reflectiveCurveToRelative(0.262f, -0.142f, 0.412f, -0.175f)\n            reflectiveCurveToRelative(0.304f, -0.029f, 0.463f, 0.013f)\n            reflectiveCurveToRelative(0.304f, 0.129f, 0.438f, 0.262f)\n            lineToRelative(2.625f, 2.625f)\n            lineToRelative(1.8f, -1.8f)\n            lineToRelative(-2.625f, -2.625f)\n            curveToRelative(-0.133f, -0.133f, -0.221f, -0.279f, -0.262f, -0.438f)\n            reflectiveCurveToRelative(-0.046f, -0.313f, -0.013f, -0.463f)\n            reflectiveCurveToRelative(0.092f, -0.287f, 0.175f, -0.412f)\n            reflectiveCurveToRelative(0.208f, -0.229f, 0.375f, -0.313f)\n            curveToRelative(0.3f, -0.133f, 0.617f, -0.225f, 0.95f, -0.275f)\n            reflectiveCurveToRelative(0.667f, -0.075f, 1f, -0.075f)\n            curveToRelative(1.667f, 0f, 3.083f, 0.583f, 4.25f, 1.75f)\n            curveToRelative(1.167f, 1.167f, 1.75f, 2.583f, 1.75f, 4.25f)\n            curveToRelative(0f, 0.383f, -0.033f, 0.746f, -0.1f, 1.087f)\n            reflectiveCurveToRelative(-0.167f, 0.679f, -0.3f, 1.013f)\n            lineToRelative(5.05f, 5f)\n            curveToRelative(0.483f, 0.483f, 0.725f, 1.075f, 0.725f, 1.775f)\n            reflectiveCurveToRelative(-0.242f, 1.292f, -0.725f, 1.775f)\n            reflectiveCurveToRelative(-1.075f, 0.725f, -1.775f, 0.725f)\n            reflectiveCurveToRelative(-1.292f, -0.25f, -1.775f, -0.75f)\n            lineToRelative(-5f, -5.025f)\n            curveToRelative(-0.333f, 0.133f, -0.671f, 0.233f, -1.013f, 0.3f)\n            reflectiveCurveToRelative(-0.704f, 0.1f, -1.087f, 0.1f)\n            close()\n            moveTo(9f, 13f)\n            curveToRelative(0.433f, 0f, 0.867f, -0.067f, 1.3f, -0.2f)\n            reflectiveCurveToRelative(0.825f, -0.342f, 1.175f, -0.625f)\n            lineToRelative(6.075f, 6.075f)\n            curveToRelative(0.083f, 0.083f, 0.196f, 0.121f, 0.338f, 0.112f)\n            reflectiveCurveToRelative(0.254f, -0.054f, 0.338f, -0.138f)\n            reflectiveCurveToRelative(0.125f, -0.196f, 0.125f, -0.338f)\n            reflectiveCurveToRelative(-0.042f, -0.254f, -0.125f, -0.338f)\n            lineToRelative(-6.075f, -6.05f)\n            curveToRelative(0.3f, -0.333f, 0.517f, -0.721f, 0.65f, -1.163f)\n            curveToRelative(0.133f, -0.442f, 0.2f, -0.887f, 0.2f, -1.337f)\n            curveToRelative(0f, -1f, -0.321f, -1.871f, -0.962f, -2.612f)\n            reflectiveCurveToRelative(-1.438f, -1.188f, -2.388f, -1.337f)\n            lineToRelative(1.85f, 1.85f)\n            curveToRelative(0.2f, 0.2f, 0.3f, 0.433f, 0.3f, 0.7f)\n            reflectiveCurveToRelative(-0.1f, 0.5f, -0.3f, 0.7f)\n            lineToRelative(-3.2f, 3.2f)\n            curveToRelative(-0.2f, 0.2f, -0.433f, 0.3f, -0.7f, 0.3f)\n            reflectiveCurveToRelative(-0.5f, -0.1f, -0.7f, -0.3f)\n            lineToRelative(-1.85f, -1.85f)\n            curveToRelative(0.15f, 0.95f, 0.596f, 1.746f, 1.337f, 2.388f)\n            curveToRelative(0.742f, 0.642f, 1.612f, 0.962f, 2.612f, 0.962f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Build: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoToneBuild\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.65f, 16.1f)\n            lineToRelative(-5.05f, -5f)\n            curveToRelative(0.133f, -0.333f, 0.233f, -0.671f, 0.3f, -1.012f)\n            curveToRelative(0.067f, -0.342f, 0.1f, -0.704f, 0.1f, -1.088f)\n            curveToRelative(0f, -1.667f, -0.583f, -3.083f, -1.75f, -4.25f)\n            reflectiveCurveToRelative(-2.583f, -1.75f, -4.25f, -1.75f)\n            curveToRelative(-0.333f, 0f, -0.667f, 0.025f, -1f, 0.075f)\n            reflectiveCurveToRelative(-0.65f, 0.142f, -0.95f, 0.275f)\n            curveToRelative(-0.167f, 0.083f, -0.292f, 0.188f, -0.375f, 0.313f)\n            curveToRelative(-0.083f, 0.125f, -0.142f, 0.263f, -0.175f, 0.413f)\n            curveToRelative(-0.033f, 0.15f, -0.029f, 0.304f, 0.013f, 0.462f)\n            curveToRelative(0.042f, 0.158f, 0.129f, 0.304f, 0.263f, 0.438f)\n            lineToRelative(2.625f, 2.625f)\n            lineToRelative(-1.8f, 1.8f)\n            lineToRelative(-2.625f, -2.625f)\n            curveToRelative(-0.133f, -0.133f, -0.279f, -0.221f, -0.438f, -0.263f)\n            curveToRelative(-0.158f, -0.042f, -0.313f, -0.046f, -0.462f, -0.013f)\n            curveToRelative(-0.15f, 0.033f, -0.288f, 0.092f, -0.413f, 0.175f)\n            curveToRelative(-0.125f, 0.083f, -0.229f, 0.208f, -0.313f, 0.375f)\n            curveToRelative(-0.133f, 0.3f, -0.225f, 0.617f, -0.275f, 0.95f)\n            reflectiveCurveToRelative(-0.075f, 0.667f, -0.075f, 1f)\n            curveToRelative(0f, 1.667f, 0.583f, 3.083f, 1.75f, 4.25f)\n            reflectiveCurveToRelative(2.583f, 1.75f, 4.25f, 1.75f)\n            curveToRelative(0.383f, 0f, 0.746f, -0.033f, 1.088f, -0.1f)\n            curveToRelative(0.342f, -0.067f, 0.679f, -0.167f, 1.012f, -0.3f)\n            lineToRelative(5f, 5.025f)\n            curveToRelative(0.483f, 0.5f, 1.075f, 0.75f, 1.775f, 0.75f)\n            reflectiveCurveToRelative(1.292f, -0.242f, 1.775f, -0.725f)\n            reflectiveCurveToRelative(0.725f, -1.075f, 0.725f, -1.775f)\n            reflectiveCurveToRelative(-0.242f, -1.292f, -0.725f, -1.775f)\n            close()\n            moveTo(18.225f, 18.225f)\n            curveToRelative(-0.083f, 0.083f, -0.196f, 0.129f, -0.337f, 0.138f)\n            curveToRelative(-0.142f, 0.008f, -0.254f, -0.029f, -0.338f, -0.112f)\n            lineToRelative(-6.075f, -6.075f)\n            curveToRelative(-0.35f, 0.283f, -0.742f, 0.492f, -1.175f, 0.625f)\n            curveToRelative(-0.433f, 0.133f, -0.867f, 0.2f, -1.3f, 0.2f)\n            curveToRelative(-1f, 0f, -1.871f, -0.321f, -2.612f, -0.963f)\n            curveToRelative(-0.742f, -0.642f, -1.188f, -1.438f, -1.338f, -2.387f)\n            lineToRelative(1.85f, 1.85f)\n            curveToRelative(0.2f, 0.2f, 0.433f, 0.3f, 0.7f, 0.3f)\n            reflectiveCurveToRelative(0.5f, -0.1f, 0.7f, -0.3f)\n            lineToRelative(3.2f, -3.2f)\n            curveToRelative(0.2f, -0.2f, 0.3f, -0.433f, 0.3f, -0.7f)\n            reflectiveCurveToRelative(-0.1f, -0.5f, -0.3f, -0.7f)\n            lineToRelative(-1.85f, -1.85f)\n            curveToRelative(0.95f, 0.15f, 1.746f, 0.596f, 2.387f, 1.338f)\n            curveToRelative(0.642f, 0.742f, 0.963f, 1.612f, 0.963f, 2.612f)\n            curveToRelative(0f, 0.45f, -0.067f, 0.896f, -0.2f, 1.338f)\n            curveToRelative(-0.133f, 0.442f, -0.35f, 0.829f, -0.65f, 1.162f)\n            lineToRelative(6.075f, 6.05f)\n            curveToRelative(0.083f, 0.083f, 0.125f, 0.196f, 0.125f, 0.338f)\n            reflectiveCurveToRelative(-0.042f, 0.254f, -0.125f, 0.337f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(9f, 13f)\n            curveToRelative(0.433f, 0f, 0.867f, -0.067f, 1.3f, -0.2f)\n            reflectiveCurveToRelative(0.825f, -0.342f, 1.175f, -0.625f)\n            lineToRelative(6.075f, 6.075f)\n            curveToRelative(0.083f, 0.083f, 0.196f, 0.121f, 0.338f, 0.112f)\n            reflectiveCurveToRelative(0.254f, -0.054f, 0.338f, -0.138f)\n            reflectiveCurveToRelative(0.125f, -0.196f, 0.125f, -0.338f)\n            reflectiveCurveToRelative(-0.042f, -0.254f, -0.125f, -0.338f)\n            lineToRelative(-6.075f, -6.05f)\n            curveToRelative(0.3f, -0.333f, 0.517f, -0.721f, 0.65f, -1.163f)\n            curveToRelative(0.133f, -0.442f, 0.2f, -0.887f, 0.2f, -1.337f)\n            curveToRelative(0f, -1f, -0.321f, -1.871f, -0.962f, -2.612f)\n            reflectiveCurveToRelative(-1.438f, -1.188f, -2.388f, -1.337f)\n            lineToRelative(1.85f, 1.85f)\n            curveToRelative(0.2f, 0.2f, 0.3f, 0.433f, 0.3f, 0.7f)\n            reflectiveCurveToRelative(-0.1f, 0.5f, -0.3f, 0.7f)\n            lineToRelative(-3.2f, 3.2f)\n            curveToRelative(-0.2f, 0.2f, -0.433f, 0.3f, -0.7f, 0.3f)\n            reflectiveCurveToRelative(-0.5f, -0.1f, -0.7f, -0.3f)\n            lineToRelative(-1.85f, -1.85f)\n            curveToRelative(0.15f, 0.95f, 0.596f, 1.746f, 1.337f, 2.388f)\n            curveToRelative(0.742f, 0.642f, 1.612f, 0.962f, 2.612f, 0.962f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/CancelSmall.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.CancelSmall: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.CancelSmall\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveToRelative(480f, 536f)\n            lineToRelative(116f, 116f)\n            quadToRelative(11f, 11f, 28f, 11f)\n            reflectiveQuadToRelative(28f, -11f)\n            quadToRelative(11f, -11f, 11f, -28f)\n            reflectiveQuadToRelative(-11f, -28f)\n            lineTo(536f, 480f)\n            lineToRelative(116f, -116f)\n            quadToRelative(11f, -11f, 11f, -28f)\n            reflectiveQuadToRelative(-11f, -28f)\n            quadToRelative(-11f, -11f, -28f, -11f)\n            reflectiveQuadToRelative(-28f, 11f)\n            lineTo(480f, 424f)\n            lineTo(364f, 308f)\n            quadToRelative(-11f, -11f, -28f, -11f)\n            reflectiveQuadToRelative(-28f, 11f)\n            quadToRelative(-11f, 11f, -11f, 28f)\n            reflectiveQuadToRelative(11f, 28f)\n            lineToRelative(116f, 116f)\n            lineToRelative(-116f, 116f)\n            quadToRelative(-11f, 11f, -11f, 28f)\n            reflectiveQuadToRelative(11f, 28f)\n            quadToRelative(11f, 11f, 28f, 11f)\n            reflectiveQuadToRelative(28f, -11f)\n            lineToRelative(116f, -116f)\n            close()\n            moveTo(480f, 480f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ClipboardFile.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ClipboardFile: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"ClipboardFile\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19f, 3f)\n            curveTo(20.1f, 3f, 21f, 3.9f, 21f, 5f)\n            verticalLineTo(9.17f)\n            lineTo(19.83f, 8f)\n            horizontalLineTo(15f)\n            curveTo(12.79f, 8f, 11f, 9.79f, 11f, 12f)\n            verticalLineTo(21f)\n            horizontalLineTo(5f)\n            curveTo(3.9f, 21f, 3f, 20.1f, 3f, 19f)\n            verticalLineTo(5f)\n            curveTo(3f, 3.9f, 3.9f, 3f, 5f, 3f)\n            horizontalLineTo(9.18f)\n            curveTo(9.6f, 1.84f, 10.7f, 1f, 12f, 1f)\n            curveTo(13.3f, 1f, 14.4f, 1.84f, 14.82f, 3f)\n            horizontalLineTo(19f)\n            moveTo(12f, 3f)\n            curveTo(11.45f, 3f, 11f, 3.45f, 11f, 4f)\n            curveTo(11f, 4.55f, 11.45f, 5f, 12f, 5f)\n            curveTo(12.55f, 5f, 13f, 4.55f, 13f, 4f)\n            curveTo(13f, 3.45f, 12.55f, 3f, 12f, 3f)\n            moveTo(15f, 23f)\n            curveTo(13.9f, 23f, 13f, 22.11f, 13f, 21f)\n            verticalLineTo(12f)\n            curveTo(13f, 10.9f, 13.9f, 10f, 15f, 10f)\n            horizontalLineTo(19f)\n            lineTo(23f, 14f)\n            verticalLineTo(21f)\n            curveTo(23f, 22.11f, 22.11f, 23f, 21f, 23f)\n            horizontalLineTo(15f)\n            moveTo(21f, 14.83f)\n            lineTo(18.17f, 12f)\n            horizontalLineTo(18f)\n            verticalLineTo(15f)\n            horizontalLineTo(21f)\n            verticalLineTo(14.83f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Collage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Collage: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.Collage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(120f, 520f)\n            lineTo(120f, 200f)\n            quadTo(120f, 167f, 143.5f, 143.5f)\n            quadTo(167f, 120f, 200f, 120f)\n            lineTo(440f, 120f)\n            lineTo(440f, 520f)\n            lineTo(120f, 520f)\n            close()\n            moveTo(360f, 440f)\n            lineTo(360f, 440f)\n            lineTo(360f, 440f)\n            lineTo(360f, 440f)\n            lineTo(360f, 440f)\n            quadTo(360f, 440f, 360f, 440f)\n            quadTo(360f, 440f, 360f, 440f)\n            close()\n            moveTo(520f, 120f)\n            lineTo(760f, 120f)\n            quadTo(793f, 120f, 816.5f, 143.5f)\n            quadTo(840f, 167f, 840f, 200f)\n            lineTo(840f, 360f)\n            lineTo(520f, 360f)\n            lineTo(520f, 120f)\n            close()\n            moveTo(520f, 840f)\n            lineTo(520f, 440f)\n            lineTo(840f, 440f)\n            lineTo(840f, 760f)\n            quadTo(840f, 793f, 816.5f, 816.5f)\n            quadTo(793f, 840f, 760f, 840f)\n            lineTo(520f, 840f)\n            close()\n            moveTo(120f, 600f)\n            lineTo(440f, 600f)\n            lineTo(440f, 840f)\n            lineTo(200f, 840f)\n            quadTo(167f, 840f, 143.5f, 816.5f)\n            quadTo(120f, 793f, 120f, 760f)\n            lineTo(120f, 600f)\n            close()\n            moveTo(360f, 680f)\n            lineTo(360f, 680f)\n            lineTo(360f, 680f)\n            lineTo(360f, 680f)\n            lineTo(360f, 680f)\n            quadTo(360f, 680f, 360f, 680f)\n            quadTo(360f, 680f, 360f, 680f)\n            close()\n            moveTo(600f, 280f)\n            lineTo(600f, 280f)\n            lineTo(600f, 280f)\n            lineTo(600f, 280f)\n            lineTo(600f, 280f)\n            quadTo(600f, 280f, 600f, 280f)\n            quadTo(600f, 280f, 600f, 280f)\n            close()\n            moveTo(600f, 520f)\n            quadTo(600f, 520f, 600f, 520f)\n            quadTo(600f, 520f, 600f, 520f)\n            lineTo(600f, 520f)\n            lineTo(600f, 520f)\n            lineTo(600f, 520f)\n            close()\n            moveTo(200f, 440f)\n            lineTo(360f, 440f)\n            lineTo(360f, 200f)\n            lineTo(200f, 200f)\n            quadTo(200f, 200f, 200f, 200f)\n            quadTo(200f, 200f, 200f, 200f)\n            lineTo(200f, 440f)\n            close()\n            moveTo(600f, 280f)\n            lineTo(760f, 280f)\n            lineTo(760f, 200f)\n            quadTo(760f, 200f, 760f, 200f)\n            quadTo(760f, 200f, 760f, 200f)\n            lineTo(600f, 200f)\n            lineTo(600f, 280f)\n            close()\n            moveTo(600f, 520f)\n            lineTo(600f, 760f)\n            lineTo(760f, 760f)\n            quadTo(760f, 760f, 760f, 760f)\n            quadTo(760f, 760f, 760f, 760f)\n            lineTo(760f, 520f)\n            lineTo(600f, 520f)\n            close()\n            moveTo(200f, 680f)\n            lineTo(200f, 760f)\n            quadTo(200f, 760f, 200f, 760f)\n            quadTo(200f, 760f, 200f, 760f)\n            lineTo(360f, 760f)\n            lineTo(360f, 680f)\n            lineTo(200f, 680f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Collage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Collage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9f, 11f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9f, 17f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15f, 7f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15f, 13f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 11f)\n            lineToRelative(4f, 0f)\n            lineToRelative(0f, -6f)\n            lineToRelative(-4f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 6f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(15f, 7f)\n            lineToRelative(4f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(-4f, 0f)\n            lineToRelative(0f, 2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(15f, 13f)\n            lineToRelative(0f, 6f)\n            lineToRelative(4f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, -6f)\n            lineToRelative(-4f, 0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 17f)\n            lineToRelative(0f, 2f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(4f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-4f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(5f, 3f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.587f)\n            reflectiveCurveToRelative(-0.588f, 0.863f, -0.588f, 1.413f)\n            verticalLineToRelative(8f)\n            horizontalLineToRelative(8f)\n            verticalLineTo(3f)\n            horizontalLineToRelative(-6f)\n            close()\n            moveTo(9f, 11f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(-6f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(6f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(20.412f, 3.587f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.587f, -1.412f, -0.587f)\n            horizontalLineToRelative(-6f)\n            verticalLineToRelative(6f)\n            horizontalLineToRelative(8f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.413f)\n            close()\n            moveTo(19f, 7f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(2f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13f, 11f)\n            verticalLineToRelative(10f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineToRelative(-8f)\n            horizontalLineToRelative(-8f)\n            close()\n            moveTo(19f, 19f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(-6f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(6f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(3f, 15f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(6f)\n            verticalLineToRelative(-6f)\n            horizontalLineTo(3f)\n            close()\n            moveTo(9f, 19f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(2f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Communication.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Communication: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Communication\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(408f, 528f)\n            lineTo(366f, 486f)\n            quadTo(374f, 475f, 377f, 463.5f)\n            quadTo(380f, 452f, 380f, 440f)\n            quadTo(380f, 428f, 377f, 416.5f)\n            quadTo(374f, 405f, 366f, 395f)\n            lineTo(408f, 352f)\n            quadTo(424f, 371f, 432f, 394f)\n            quadTo(440f, 417f, 440f, 440f)\n            quadTo(440f, 463f, 432f, 485.5f)\n            quadTo(424f, 508f, 408f, 528f)\n            close()\n            moveTo(493f, 614f)\n            lineTo(450f, 571f)\n            quadTo(475f, 543f, 487.5f, 509f)\n            quadTo(500f, 475f, 500f, 440f)\n            quadTo(500f, 405f, 487.5f, 371.5f)\n            quadTo(475f, 338f, 450f, 310f)\n            lineTo(493f, 267f)\n            quadTo(527f, 304f, 543.5f, 348.5f)\n            quadTo(560f, 393f, 560f, 440f)\n            quadTo(560f, 487f, 543.5f, 532f)\n            quadTo(527f, 577f, 493f, 614f)\n            close()\n            moveTo(200f, 480f)\n            quadTo(167f, 480f, 143.5f, 456.5f)\n            quadTo(120f, 433f, 120f, 400f)\n            quadTo(120f, 367f, 143.5f, 343.5f)\n            quadTo(167f, 320f, 200f, 320f)\n            quadTo(233f, 320f, 256.5f, 343.5f)\n            quadTo(280f, 367f, 280f, 400f)\n            quadTo(280f, 433f, 256.5f, 456.5f)\n            quadTo(233f, 480f, 200f, 480f)\n            close()\n            moveTo(40f, 640f)\n            lineTo(40f, 617f)\n            quadTo(40f, 593f, 53f, 573f)\n            quadTo(66f, 553f, 89f, 543f)\n            quadTo(115f, 532f, 142.5f, 526f)\n            quadTo(170f, 520f, 200f, 520f)\n            quadTo(230f, 520f, 257.5f, 526f)\n            quadTo(285f, 532f, 311f, 543f)\n            quadTo(334f, 553f, 347f, 573f)\n            quadTo(360f, 593f, 360f, 617f)\n            lineTo(360f, 640f)\n            lineTo(40f, 640f)\n            close()\n            moveTo(760f, 480f)\n            quadTo(727f, 480f, 703.5f, 456.5f)\n            quadTo(680f, 433f, 680f, 400f)\n            quadTo(680f, 367f, 703.5f, 343.5f)\n            quadTo(727f, 320f, 760f, 320f)\n            quadTo(793f, 320f, 816.5f, 343.5f)\n            quadTo(840f, 367f, 840f, 400f)\n            quadTo(840f, 433f, 816.5f, 456.5f)\n            quadTo(793f, 480f, 760f, 480f)\n            close()\n            moveTo(600f, 640f)\n            lineTo(600f, 617f)\n            quadTo(600f, 593f, 613f, 573f)\n            quadTo(626f, 553f, 649f, 543f)\n            quadTo(675f, 532f, 702.5f, 526f)\n            quadTo(730f, 520f, 760f, 520f)\n            quadTo(790f, 520f, 817.5f, 526f)\n            quadTo(845f, 532f, 871f, 543f)\n            quadTo(894f, 553f, 907f, 573f)\n            quadTo(920f, 593f, 920f, 617f)\n            lineTo(920f, 640f)\n            lineTo(600f, 640f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Compare.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Compare: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Compare\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.713f, 1.287f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.713f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.713f)\n            verticalLineToRelative(1f)\n            horizontalLineToRelative(-5f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(5f)\n            verticalLineToRelative(1f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.713f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            verticalLineTo(2f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.713f)\n            close()\n            moveTo(10f, 18f)\n            horizontalLineToRelative(-5f)\n            lineToRelative(5f, -6f)\n            verticalLineToRelative(6f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14f, 21f)\n            verticalLineToRelative(-9f)\n            lineToRelative(5f, 6f)\n            verticalLineTo(5f)\n            horizontalLineToRelative(-5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(5f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-5f)\n            close()\n        }\n    }.build()\n}\n\n\nval Icons.TwoTone.Compare: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Compare\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.713f, 1.287f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.713f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.713f)\n            verticalLineToRelative(1f)\n            horizontalLineToRelative(-5f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(5f)\n            verticalLineToRelative(1f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.713f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            verticalLineTo(2f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.713f)\n            close()\n            moveTo(10f, 18f)\n            horizontalLineToRelative(-5f)\n            lineToRelative(5f, -6f)\n            verticalLineToRelative(6f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14f, 21f)\n            verticalLineToRelative(-9f)\n            lineToRelative(5f, 6f)\n            verticalLineTo(5f)\n            horizontalLineToRelative(-5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(5f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-5f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 18f)\n            lineToRelative(5f, 0f)\n            lineToRelative(0f, -6f)\n            lineToRelative(-5f, 6f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(14f, 5f)\n            horizontalLineToRelative(5f)\n            verticalLineToRelative(13f)\n            horizontalLineToRelative(-5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/CompareArrows.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.CompareArrows: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.CompareArrows\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(367f, 640f)\n            lineTo(120f, 640f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(80f, 600f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(120f, 560f)\n            horizontalLineToRelative(247f)\n            lineToRelative(-75f, -75f)\n            quadToRelative(-11f, -11f, -11f, -27.5f)\n            reflectiveQuadToRelative(11f, -28.5f)\n            quadToRelative(12f, -12f, 28.5f, -12f)\n            reflectiveQuadToRelative(28.5f, 12f)\n            lineToRelative(143f, 143f)\n            quadToRelative(6f, 6f, 8.5f, 13f)\n            reflectiveQuadToRelative(2.5f, 15f)\n            quadToRelative(0f, 8f, -2.5f, 15f)\n            reflectiveQuadToRelative(-8.5f, 13f)\n            lineTo(348f, 772f)\n            quadToRelative(-12f, 12f, -28f, 11.5f)\n            reflectiveQuadTo(292f, 771f)\n            quadToRelative(-11f, -12f, -11.5f, -28f)\n            reflectiveQuadToRelative(11.5f, -28f)\n            lineToRelative(75f, -75f)\n            close()\n            moveTo(593f, 400f)\n            lineTo(668f, 475f)\n            quadToRelative(11f, 11f, 11f, 27.5f)\n            reflectiveQuadTo(668f, 531f)\n            quadToRelative(-12f, 12f, -28.5f, 12f)\n            reflectiveQuadTo(611f, 531f)\n            lineTo(468f, 388f)\n            quadToRelative(-6f, -6f, -8.5f, -13f)\n            reflectiveQuadToRelative(-2.5f, -15f)\n            quadToRelative(0f, -8f, 2.5f, -15f)\n            reflectiveQuadToRelative(8.5f, -13f)\n            lineToRelative(144f, -144f)\n            quadToRelative(12f, -12f, 28f, -11.5f)\n            reflectiveQuadToRelative(28f, 12.5f)\n            quadToRelative(11f, 12f, 11.5f, 28f)\n            reflectiveQuadTo(668f, 245f)\n            lineToRelative(-75f, 75f)\n            horizontalLineToRelative(247f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(880f, 360f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(840f, 400f)\n            lineTo(593f, 400f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Complementary.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Complementary: ImageVector by lazy {\n    Builder(\n        name = \"Complementary\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(10.9f, 16.0f, 12.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(10.9f, 4.0f, 12.0f, 4.0f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ContractEdit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ContractEdit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ContractEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(400f, 280f)\n            horizontalLineToRelative(280f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(720f, 320f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(680f, 360f)\n            lineTo(400f, 360f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(360f, 320f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(400f, 280f)\n            close()\n            moveTo(400f, 400f)\n            horizontalLineToRelative(280f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(720f, 440f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(680f, 480f)\n            lineTo(400f, 480f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(360f, 440f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(400f, 400f)\n            close()\n            moveTo(480f, 800f)\n            lineTo(200f, 800f)\n            horizontalLineToRelative(280f)\n            close()\n            moveTo(240f, 880f)\n            quadToRelative(-50f, 0f, -85f, -35f)\n            reflectiveQuadToRelative(-35f, -85f)\n            verticalLineToRelative(-80f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(160f, 640f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-480f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(320f, 80f)\n            horizontalLineToRelative(440f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(840f, 160f)\n            verticalLineToRelative(240f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(800f, 440f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(760f, 400f)\n            verticalLineToRelative(-240f)\n            lineTo(320f, 160f)\n            verticalLineToRelative(480f)\n            horizontalLineToRelative(120f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(480f, 680f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(440f, 720f)\n            lineTo(200f, 720f)\n            verticalLineToRelative(40f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(240f, 800f)\n            horizontalLineToRelative(200f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(480f, 840f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(440f, 880f)\n            lineTo(240f, 880f)\n            close()\n            moveTo(560f, 840f)\n            verticalLineToRelative(-66f)\n            quadToRelative(0f, -8f, 3f, -15.5f)\n            reflectiveQuadToRelative(9f, -13.5f)\n            lineToRelative(209f, -208f)\n            quadToRelative(9f, -9f, 20f, -13f)\n            reflectiveQuadToRelative(22f, -4f)\n            quadToRelative(12f, 0f, 23f, 4.5f)\n            reflectiveQuadToRelative(20f, 13.5f)\n            lineToRelative(37f, 37f)\n            quadToRelative(8f, 9f, 12.5f, 20f)\n            reflectiveQuadToRelative(4.5f, 22f)\n            quadToRelative(0f, 11f, -4f, 22.5f)\n            reflectiveQuadTo(903f, 660f)\n            lineTo(695f, 868f)\n            quadToRelative(-6f, 6f, -13.5f, 9f)\n            reflectiveQuadTo(666f, 880f)\n            horizontalLineToRelative(-66f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(560f, 840f)\n            close()\n            moveTo(860f, 617f)\n            lineTo(823f, 580f)\n            lineTo(860f, 617f)\n            close()\n            moveTo(620f, 820f)\n            horizontalLineToRelative(38f)\n            lineToRelative(121f, -122f)\n            lineToRelative(-18f, -19f)\n            lineToRelative(-19f, -18f)\n            lineToRelative(-122f, 121f)\n            verticalLineToRelative(38f)\n            close()\n            moveTo(761f, 679f)\n            lineTo(742f, 661f)\n            lineTo(779f, 698f)\n            lineTo(761f, 679f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ContractImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ContractImage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ContractImage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.412f, 2.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-11f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            horizontalLineToRelative(-1f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(1f)\n            curveToRelative(0f, 0.833f, 0.292f, 1.542f, 0.875f, 2.125f)\n            reflectiveCurveToRelative(1.292f, 0.875f, 2.125f, 0.875f)\n            horizontalLineToRelative(12f)\n            curveToRelative(0.833f, 0f, 1.542f, -0.292f, 2.125f, -0.875f)\n            reflectiveCurveToRelative(0.875f, -1.292f, 0.875f, -2.125f)\n            verticalLineTo(4f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(15f, 20f)\n            horizontalLineTo(6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.713f)\n            verticalLineToRelative(-1f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(2f)\n            close()\n            moveTo(19f, 19f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.713f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.713f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-7f)\n            verticalLineTo(4f)\n            horizontalLineToRelative(11f)\n            verticalLineToRelative(15f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 20f)\n            lineToRelative(-1f, 0f)\n            lineToRelative(10f, 0f)\n            lineToRelative(-9f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.42f, 11.981f)\n            horizontalLineToRelative(8.161f)\n            curveToRelative(0.163f, 0f, 0.286f, -0.078f, 0.367f, -0.233f)\n            reflectiveCurveToRelative(0.068f, -0.304f, -0.041f, -0.445f)\n            lineToRelative(-2.244f, -3.113f)\n            curveToRelative(-0.082f, -0.113f, -0.19f, -0.169f, -0.326f, -0.169f)\n            reflectiveCurveToRelative(-0.245f, 0.056f, -0.326f, 0.169f)\n            lineToRelative(-2.122f, 2.944f)\n            lineToRelative(-1.51f, -2.097f)\n            curveToRelative(-0.082f, -0.113f, -0.19f, -0.169f, -0.326f, -0.169f)\n            reflectiveCurveToRelative(-0.245f, 0.056f, -0.326f, 0.169f)\n            lineToRelative(-1.632f, 2.266f)\n            curveToRelative(-0.109f, 0.141f, -0.122f, 0.289f, -0.041f, 0.445f)\n            reflectiveCurveToRelative(0.204f, 0.233f, 0.367f, 0.233f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ContractImage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ContractImage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.412f, 2.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-11f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            horizontalLineToRelative(-1f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(1f)\n            curveToRelative(0f, 0.833f, 0.292f, 1.542f, 0.875f, 2.125f)\n            reflectiveCurveToRelative(1.292f, 0.875f, 2.125f, 0.875f)\n            horizontalLineToRelative(12f)\n            curveToRelative(0.833f, 0f, 1.542f, -0.292f, 2.125f, -0.875f)\n            reflectiveCurveToRelative(0.875f, -1.292f, 0.875f, -2.125f)\n            verticalLineTo(4f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(15f, 20f)\n            horizontalLineTo(6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.713f)\n            verticalLineToRelative(-1f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(2f)\n            close()\n            moveTo(19f, 19f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.713f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.713f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-7f)\n            verticalLineTo(4f)\n            horizontalLineToRelative(11f)\n            verticalLineToRelative(15f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 20f)\n            lineToRelative(-1f, 0f)\n            lineToRelative(10f, 0f)\n            lineToRelative(-9f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.42f, 11.981f)\n            horizontalLineToRelative(8.161f)\n            curveToRelative(0.163f, 0f, 0.286f, -0.078f, 0.367f, -0.233f)\n            reflectiveCurveToRelative(0.068f, -0.304f, -0.041f, -0.445f)\n            lineToRelative(-2.244f, -3.113f)\n            curveToRelative(-0.082f, -0.113f, -0.19f, -0.169f, -0.326f, -0.169f)\n            reflectiveCurveToRelative(-0.245f, 0.056f, -0.326f, 0.169f)\n            lineToRelative(-2.122f, 2.944f)\n            lineToRelative(-1.51f, -2.097f)\n            curveToRelative(-0.082f, -0.113f, -0.19f, -0.169f, -0.326f, -0.169f)\n            reflectiveCurveToRelative(-0.245f, 0.056f, -0.326f, 0.169f)\n            lineToRelative(-1.632f, 2.266f)\n            curveToRelative(-0.109f, 0.141f, -0.122f, 0.289f, -0.041f, 0.445f)\n            reflectiveCurveToRelative(0.204f, 0.233f, 0.367f, 0.233f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(15f, 20f)\n            horizontalLineTo(6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.713f)\n            verticalLineToRelative(-1f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(19f, 19f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.713f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.713f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-7f)\n            verticalLineTo(4f)\n            horizontalLineToRelative(11f)\n            verticalLineToRelative(15f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Cool.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Cool: ImageVector by lazy {\n    Builder(\n        name = \"Outlined.Cool\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(19.0f, 10.0f)\n            curveTo(19.0f, 11.38f, 16.88f, 12.5f, 15.5f, 12.5f)\n            curveTo(14.12f, 12.5f, 12.75f, 11.38f, 12.75f, 10.0f)\n            horizontalLineTo(11.25f)\n            curveTo(11.25f, 11.38f, 9.88f, 12.5f, 8.5f, 12.5f)\n            curveTo(7.12f, 12.5f, 5.0f, 11.38f, 5.0f, 10.0f)\n            horizontalLineTo(4.25f)\n            curveTo(4.09f, 10.64f, 4.0f, 11.31f, 4.0f, 12.0f)\n            arcTo(\n                8.0f, 8.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 12.0f,\n                y1 = 20.0f\n            )\n            arcTo(\n                8.0f, 8.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 20.0f,\n                y1 = 12.0f\n            )\n            curveTo(20.0f, 11.31f, 19.91f, 10.64f, 19.75f, 10.0f)\n            horizontalLineTo(19.0f)\n            moveTo(12.0f, 4.0f)\n            curveTo(9.04f, 4.0f, 6.45f, 5.61f, 5.07f, 8.0f)\n            horizontalLineTo(18.93f)\n            curveTo(17.55f, 5.61f, 14.96f, 4.0f, 12.0f, 4.0f)\n            moveTo(22.0f, 12.0f)\n            arcTo(\n                10.0f, 10.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 12.0f,\n                y1 = 22.0f\n            )\n            arcTo(\n                10.0f, 10.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 2.0f,\n                y1 = 12.0f\n            )\n            arcTo(\n                10.0f, 10.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 12.0f,\n                y1 = 2.0f\n            )\n            arcTo(\n                10.0f, 10.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 22.0f,\n                y1 = 12.0f\n            )\n            moveTo(12.0f, 17.23f)\n            curveTo(10.25f, 17.23f, 8.71f, 16.5f, 7.81f, 15.42f)\n            lineTo(9.23f, 14.0f)\n            curveTo(9.68f, 14.72f, 10.75f, 15.23f, 12.0f, 15.23f)\n            curveTo(13.25f, 15.23f, 14.32f, 14.72f, 14.77f, 14.0f)\n            lineTo(16.19f, 15.42f)\n            curveTo(15.29f, 16.5f, 13.75f, 17.23f, 12.0f, 17.23f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Cool: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"Rounded.Cool\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3.22f, 7.22f)\n            curveTo(4.91f, 4.11f, 8.21f, 2f, 12f, 2f)\n            curveTo(15.79f, 2f, 19.09f, 4.11f, 20.78f, 7.22f)\n            lineTo(20f, 8f)\n            horizontalLineTo(4f)\n            lineTo(3.22f, 7.22f)\n            moveTo(21.4f, 8.6f)\n            curveTo(21.78f, 9.67f, 22f, 10.81f, 22f, 12f)\n            arcTo(10f, 10f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12f, 22f)\n            arcTo(10f, 10f, 0f, isMoreThanHalf = false, isPositiveArc = true, 2f, 12f)\n            curveTo(2f, 10.81f, 2.22f, 9.67f, 2.6f, 8.6f)\n            lineTo(4f, 10f)\n            horizontalLineTo(5f)\n            curveTo(5f, 11.38f, 7.12f, 12.5f, 8.5f, 12.5f)\n            curveTo(9.88f, 12.5f, 11.25f, 11.38f, 11.25f, 10f)\n            horizontalLineTo(12.75f)\n            curveTo(12.75f, 11.38f, 14.12f, 12.5f, 15.5f, 12.5f)\n            curveTo(16.88f, 12.5f, 19f, 11.38f, 19f, 10f)\n            horizontalLineTo(20f)\n            lineTo(21.4f, 8.6f)\n            moveTo(16.19f, 15.42f)\n            lineTo(14.77f, 14f)\n            curveTo(14.32f, 14.72f, 13.25f, 15.23f, 12f, 15.23f)\n            curveTo(10.75f, 15.23f, 9.68f, 14.72f, 9.23f, 14f)\n            lineTo(7.81f, 15.42f)\n            curveTo(8.71f, 16.5f, 10.25f, 17.23f, 12f, 17.23f)\n            curveTo(13.75f, 17.23f, 15.29f, 16.5f, 16.19f, 15.42f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Counter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Counter: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Counter\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 4f)\n            horizontalLineTo(20f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 22f, 6f)\n            verticalLineTo(18f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 20f, 20f)\n            horizontalLineTo(4f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 2f, 18f)\n            verticalLineTo(6f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 4f, 4f)\n            moveTo(4f, 6f)\n            verticalLineTo(18f)\n            horizontalLineTo(11f)\n            verticalLineTo(6f)\n            horizontalLineTo(4f)\n            moveTo(20f, 18f)\n            verticalLineTo(6f)\n            horizontalLineTo(18.76f)\n            curveTo(19f, 6.54f, 18.95f, 7.07f, 18.95f, 7.13f)\n            curveTo(18.88f, 7.8f, 18.41f, 8.5f, 18.24f, 8.75f)\n            lineTo(15.91f, 11.3f)\n            lineTo(19.23f, 11.28f)\n            lineTo(19.24f, 12.5f)\n            lineTo(14.04f, 12.47f)\n            lineTo(14f, 11.47f)\n            curveTo(14f, 11.47f, 17.05f, 8.24f, 17.2f, 7.95f)\n            curveTo(17.34f, 7.67f, 17.91f, 6f, 16.5f, 6f)\n            curveTo(15.27f, 6.05f, 15.41f, 7.3f, 15.41f, 7.3f)\n            lineTo(13.87f, 7.31f)\n            curveTo(13.87f, 7.31f, 13.88f, 6.65f, 14.25f, 6f)\n            horizontalLineTo(13f)\n            verticalLineTo(18f)\n            horizontalLineTo(15.58f)\n            lineTo(15.57f, 17.14f)\n            lineTo(16.54f, 17.13f)\n            curveTo(16.54f, 17.13f, 17.45f, 16.97f, 17.46f, 16.08f)\n            curveTo(17.5f, 15.08f, 16.65f, 15.08f, 16.5f, 15.08f)\n            curveTo(16.37f, 15.08f, 15.43f, 15.13f, 15.43f, 15.95f)\n            horizontalLineTo(13.91f)\n            curveTo(13.91f, 15.95f, 13.95f, 13.89f, 16.5f, 13.89f)\n            curveTo(19.1f, 13.89f, 18.96f, 15.91f, 18.96f, 15.91f)\n            curveTo(18.96f, 15.91f, 19f, 17.16f, 17.85f, 17.63f)\n            lineTo(18.37f, 18f)\n            horizontalLineTo(20f)\n            moveTo(8.92f, 16f)\n            horizontalLineTo(7.42f)\n            verticalLineTo(10.2f)\n            lineTo(5.62f, 10.76f)\n            verticalLineTo(9.53f)\n            lineTo(8.76f, 8.41f)\n            horizontalLineTo(8.92f)\n            verticalLineTo(16f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Counter: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Counter\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 4f)\n            horizontalLineTo(4f)\n            curveToRelative(-1.105f, 0f, -2f, 0.895f, -2f, 2f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 1.105f, 0.895f, 2f, 2f, 2f)\n            horizontalLineToRelative(16f)\n            curveToRelative(1.105f, 0f, 2f, -0.895f, 2f, -2f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -1.105f, -0.895f, -2f, -2f, -2f)\n            close()\n            moveTo(11f, 18f)\n            horizontalLineToRelative(-7f)\n            verticalLineTo(6f)\n            horizontalLineToRelative(7f)\n            verticalLineToRelative(12f)\n            close()\n            moveTo(20f, 18f)\n            horizontalLineToRelative(-1.63f)\n            lineToRelative(-0.52f, -0.37f)\n            curveToRelative(1.15f, -0.47f, 1.11f, -1.72f, 1.11f, -1.72f)\n            curveToRelative(0f, 0f, 0.14f, -2.02f, -2.46f, -2.02f)\n            curveToRelative(-2.55f, 0f, -2.59f, 2.06f, -2.59f, 2.06f)\n            horizontalLineToRelative(1.52f)\n            curveToRelative(0f, -0.82f, 0.94f, -0.87f, 1.07f, -0.87f)\n            curveToRelative(0.15f, 0f, 1f, 0f, 0.96f, 1f)\n            curveToRelative(-0.01f, 0.89f, -0.92f, 1.05f, -0.92f, 1.05f)\n            lineToRelative(-0.97f, 0.01f)\n            lineToRelative(0.01f, 0.86f)\n            horizontalLineToRelative(-2.58f)\n            verticalLineTo(6f)\n            horizontalLineToRelative(1.25f)\n            curveToRelative(-0.37f, 0.65f, -0.38f, 1.31f, -0.38f, 1.31f)\n            lineToRelative(1.54f, -0.01f)\n            reflectiveCurveToRelative(-0.14f, -1.25f, 1.09f, -1.3f)\n            curveToRelative(1.41f, 0f, 0.84f, 1.67f, 0.7f, 1.95f)\n            curveToRelative(-0.15f, 0.29f, -3.2f, 3.52f, -3.2f, 3.52f)\n            lineToRelative(0.04f, 1f)\n            lineToRelative(5.2f, 0.03f)\n            lineToRelative(-0.01f, -1.22f)\n            lineToRelative(-3.32f, 0.02f)\n            lineToRelative(2.33f, -2.55f)\n            curveToRelative(0.17f, -0.25f, 0.64f, -0.95f, 0.71f, -1.62f)\n            curveToRelative(0f, -0.06f, 0.05f, -0.59f, -0.19f, -1.13f)\n            horizontalLineToRelative(1.24f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.92f, 16f)\n            lineToRelative(-1.5f, 0f)\n            lineToRelative(0f, -5.8f)\n            lineToRelative(-1.8f, 0.56f)\n            lineToRelative(0f, -1.23f)\n            lineToRelative(3.14f, -1.12f)\n            lineToRelative(0.16f, 0f)\n            lineToRelative(0f, 7.59f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(4f, 6f)\n            lineToRelative(0f, 12f)\n            lineToRelative(7f, 0f)\n            lineToRelative(0f, -12f)\n            lineToRelative(-7f, 0f)\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(20f, 18f)\n            verticalLineTo(6f)\n            horizontalLineToRelative(-1.24f)\n            curveToRelative(0.24f, 0.54f, 0.19f, 1.07f, 0.19f, 1.13f)\n            curveToRelative(-0.07f, 0.67f, -0.54f, 1.37f, -0.71f, 1.62f)\n            lineToRelative(-2.33f, 2.55f)\n            lineToRelative(3.32f, -0.02f)\n            lineToRelative(0.01f, 1.22f)\n            lineToRelative(-5.2f, -0.03f)\n            lineToRelative(-0.04f, -1f)\n            reflectiveCurveToRelative(3.05f, -3.23f, 3.2f, -3.52f)\n            curveToRelative(0.14f, -0.28f, 0.71f, -1.95f, -0.7f, -1.95f)\n            curveToRelative(-1.23f, 0.05f, -1.09f, 1.3f, -1.09f, 1.3f)\n            lineToRelative(-1.54f, 0.01f)\n            reflectiveCurveToRelative(0.01f, -0.66f, 0.38f, -1.31f)\n            horizontalLineToRelative(-1.25f)\n            verticalLineToRelative(12f)\n            horizontalLineToRelative(2.58f)\n            lineToRelative(-0.01f, -0.86f)\n            lineToRelative(0.97f, -0.01f)\n            reflectiveCurveToRelative(0.91f, -0.16f, 0.92f, -1.05f)\n            curveToRelative(0.04f, -1f, -0.81f, -1f, -0.96f, -1f)\n            curveToRelative(-0.13f, 0f, -1.07f, 0.05f, -1.07f, 0.87f)\n            horizontalLineToRelative(-1.52f)\n            reflectiveCurveToRelative(0.04f, -2.06f, 2.59f, -2.06f)\n            curveToRelative(2.6f, 0f, 2.46f, 2.02f, 2.46f, 2.02f)\n            curveToRelative(0f, 0f, 0.04f, 1.25f, -1.11f, 1.72f)\n            lineToRelative(0.52f, 0.37f)\n            horizontalLineToRelative(1.63f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Crashlytics.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Crashlytics: ImageVector by lazy {\n    Builder(\n        name = \"Crashlytics\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 276.0f, viewportHeight = 276.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF9B1B1D)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(115.637f, 54.539f)\n            curveTo(115.637f, 54.539f, 115.636f, 29.056f, 115.706f, 18.677f)\n            curveTo(115.783f, 7.471f, 122.854f, 0.407f, 133.949f, 0.374f)\n            curveTo(144.848f, 0.341f, 155.747f, 0.342f, 166.646f, 0.374f)\n            curveTo(177.628f, 0.405f, 184.719f, 7.384f, 184.745f, 18.306f)\n            curveTo(184.795f, 39.585f, 184.763f, 60.864f, 184.752f, 82.143f)\n            curveTo(184.751f, 83.264f, 184.626f, 84.384f, 184.531f, 85.969f)\n            curveTo(164.491f, 74.365f, 144.042f, 72.644f, 123.252f, 82.272f)\n            curveTo(107.71f, 89.469f, 96.94f, 101.464f, 91.214f, 117.64f)\n            curveTo(79.796f, 149.899f, 97.261f, 185.336f, 129.91f, 196.39f)\n            curveTo(163.792f, 207.86f, 202.118f, 189.008f, 211.618f, 150.299f)\n            curveTo(212.59f, 151.109f, 244.73f, 182.672f, 259.843f, 197.651f)\n            curveTo(268.055f, 205.79f, 268.042f, 215.538f, 259.865f, 223.673f)\n            curveTo(252.415f, 231.086f, 244.941f, 238.476f, 237.449f, 245.846f)\n            curveTo(229.122f, 254.036f, 219.251f, 254.069f, 210.983f, 245.944f)\n            curveTo(203.487f, 238.578f, 184.663f, 220.176f, 184.663f, 220.176f)\n            curveTo(184.663f, 220.176f, 184.815f, 246.647f, 184.743f, 257.416f)\n            curveTo(184.673f, 267.888f, 177.571f, 274.994f, 167.134f, 275.051f)\n            curveTo(155.976f, 275.113f, 144.817f, 275.104f, 133.659f, 275.054f)\n            curveTo(123.009f, 275.008f, 115.847f, 267.956f, 115.719f, 257.243f)\n            curveTo(115.596f, 246.865f, 115.69f, 220.393f, 115.69f, 220.393f)\n            curveTo(115.69f, 220.393f, 97.538f, 238.619f, 90.13f, 245.89f)\n            curveTo(81.808f, 254.058f, 71.98f, 254.059f, 63.664f, 245.904f)\n            curveTo(56.253f, 238.636f, 48.868f, 231.342f, 41.498f, 224.032f)\n            curveTo(32.917f, 215.52f, 32.948f, 205.998f, 41.368f, 197.458f)\n            curveTo(49.551f, 189.158f, 66.505f, 171.787f, 66.505f, 171.787f)\n            curveTo(66.505f, 171.787f, 39.662f, 171.832f, 28.374f, 171.774f)\n            curveTo(16.755f, 171.715f, 10.067f, 164.983f, 10.029f, 153.365f)\n            curveTo(9.994f, 142.855f, 9.986f, 132.345f, 10.032f, 121.835f)\n            curveTo(10.081f, 110.499f, 16.825f, 103.738f, 28.222f, 103.662f)\n            curveTo(39.25f, 103.589f, 66.644f, 103.644f, 66.644f, 103.644f)\n            curveTo(66.644f, 103.644f, 48.143f, 85.149f, 40.516f, 77.547f)\n            curveTo(32.688f, 69.744f, 32.622f, 59.87f, 40.378f, 52.11f)\n            curveTo(48.175f, 44.31f, 56.007f, 36.545f, 63.91f, 28.852f)\n            curveTo(71.35f, 21.611f, 81.62f, 21.541f, 88.948f, 28.901f)\n            curveTo(97.447f, 37.436f, 115.637f, 54.539f, 115.637f, 54.539f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF9B1B1D)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(175.772f, 137.581f)\n            curveTo(175.784f, 151.544f, 164.634f, 162.635f, 150.54f, 162.68f)\n            curveTo(136.224f, 162.725f, 125.011f, 151.617f, 125.067f, 137.448f)\n            curveTo(125.122f, 123.581f, 136.491f, 112.401f, 150.48f, 112.458f)\n            curveTo(164.512f, 112.515f, 175.759f, 123.688f, 175.772f, 137.581f)\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/CropSmall.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.CropSmall: ImageVector by lazy {\n    Builder(\n        name = \"Crop Small\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.4286f, 5.5714f)\n            horizontalLineToRelative(-5.7143f)\n            horizontalLineTo(9.2128f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(1.5015f)\n            horizontalLineToRelative(5.7143f)\n            verticalLineToRelative(5.7143f)\n            verticalLineToRelative(1.5015f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(-1.5015f)\n            verticalLineTo(7.5714f)\n            curveTo(18.4286f, 6.4669f, 17.5331f, 5.5714f, 16.4286f, 5.5714f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.0f, 16.4282f)\n            horizontalLineToRelative(-0.5015f)\n            horizontalLineToRelative(-2.8389f)\n            verticalLineToRelative(4.0E-4f)\n            horizontalLineToRelative(-3.3743f)\n            verticalLineToRelative(-0.005f)\n            horizontalLineTo(7.5714f)\n            verticalLineTo(5.5714f)\n            horizontalLineTo(7.571f)\n            verticalLineTo(4.4164f)\n            verticalLineTo(3.9149f)\n            curveToRelative(0.0f, -0.5523f, -0.4477f, -1.0f, -1.0f, -1.0f)\n            reflectiveCurveToRelative(-1.0f, 0.4477f, -1.0f, 1.0f)\n            verticalLineToRelative(0.5015f)\n            verticalLineToRelative(1.155f)\n            horizontalLineToRelative(-1.0695f)\n            horizontalLineTo(4.0f)\n            curveToRelative(-0.5523f, 0.0f, -1.0f, 0.4477f, -1.0f, 1.0f)\n            reflectiveCurveToRelative(0.4477f, 1.0f, 1.0f, 1.0f)\n            horizontalLineToRelative(0.5015f)\n            horizontalLineToRelative(1.0699f)\n            verticalLineToRelative(0.5715f)\n            verticalLineToRelative(0.2162f)\n            verticalLineToRelative(1.7838f)\n            verticalLineToRelative(0.5664f)\n            horizontalLineTo(5.571f)\n            verticalLineToRelative(5.7143f)\n            curveToRelative(0.0f, 1.1046f, 0.8954f, 2.0f, 2.0f, 2.0f)\n            horizontalLineToRelative(0.5171f)\n            curveToRelative(0.0188f, 4.0E-4f, 0.0358f, 0.0051f, 0.0548f, 0.0051f)\n            horizontalLineToRelative(6.9582f)\n            horizontalLineToRelative(0.756f)\n            horizontalLineToRelative(0.5719f)\n            verticalLineToRelative(0.6154f)\n            verticalLineToRelative(0.3693f)\n            verticalLineToRelative(0.1699f)\n            verticalLineToRelative(0.0764f)\n            verticalLineToRelative(0.2553f)\n            curveToRelative(0.0f, 0.5523f, 0.4477f, 1.0f, 1.0f, 1.0f)\n            reflectiveCurveToRelative(1.0f, -0.4477f, 1.0f, -1.0f)\n            verticalLineToRelative(-0.2553f)\n            verticalLineToRelative(-0.0764f)\n            verticalLineToRelative(-0.1699f)\n            verticalLineToRelative(-0.3693f)\n            verticalLineToRelative(-0.6154f)\n            horizontalLineToRelative(0.0497f)\n            verticalLineToRelative(-4.0E-4f)\n            horizontalLineToRelative(1.0198f)\n            horizontalLineTo(20.0f)\n            curveToRelative(0.5523f, 0.0f, 1.0f, -0.4477f, 1.0f, -1.0f)\n            reflectiveCurveTo(20.5523f, 16.4282f, 20.0f, 16.4282f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.CropSmall: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.CropSmall\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(16.429f, 5.571f)\n            horizontalLineToRelative(-7.216f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(7.216f)\n            verticalLineToRelative(7.216f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-7.216f)\n            curveToRelative(0f, -1.105f, -0.896f, -2f, -2f, -2f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(20f, 16.428f)\n            horizontalLineToRelative(-3.34f)\n            verticalLineToRelative(0f)\n            horizontalLineToRelative(-3.374f)\n            verticalLineToRelative(-0.005f)\n            horizontalLineToRelative(-5.714f)\n            verticalLineTo(5.571f)\n            horizontalLineToRelative(-0f)\n            verticalLineToRelative(-1.657f)\n            curveToRelative(0f, -0.552f, -0.448f, -1f, -1f, -1f)\n            reflectiveCurveToRelative(-1f, 0.448f, -1f, 1f)\n            verticalLineToRelative(1.656f)\n            horizontalLineToRelative(-1.571f)\n            curveToRelative(-0.552f, 0f, -1f, 0.448f, -1f, 1f)\n            reflectiveCurveToRelative(0.448f, 1f, 1f, 1f)\n            horizontalLineToRelative(1.571f)\n            verticalLineToRelative(3.138f)\n            horizontalLineToRelative(-0f)\n            verticalLineToRelative(5.714f)\n            curveToRelative(0f, 1.105f, 0.895f, 2f, 2f, 2f)\n            horizontalLineToRelative(0.517f)\n            curveToRelative(0.019f, 0f, 0.036f, 0.005f, 0.055f, 0.005f)\n            horizontalLineToRelative(8.286f)\n            verticalLineToRelative(1.486f)\n            curveToRelative(0f, 0.552f, 0.448f, 1f, 1f, 1f)\n            reflectiveCurveToRelative(1f, -0.448f, 1f, -1f)\n            verticalLineToRelative(-1.486f)\n            horizontalLineToRelative(0.05f)\n            verticalLineToRelative(-0f)\n            horizontalLineToRelative(1.521f)\n            curveToRelative(0.552f, 0f, 1f, -0.448f, 1f, -1f)\n            reflectiveCurveToRelative(-0.448f, -1f, -1f, -1f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(7.571f, 7.571f)\n            horizontalLineToRelative(8.857f)\n            verticalLineToRelative(8.852f)\n            horizontalLineToRelative(-8.857f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Cube.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Cube: ImageVector by lazy {\n    Builder(\n        name = \"Cube\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(21.0f, 16.5f)\n            curveTo(21.0f, 16.88f, 20.79f, 17.21f, 20.47f, 17.38f)\n            lineTo(12.57f, 21.82f)\n            curveTo(12.41f, 21.94f, 12.21f, 22.0f, 12.0f, 22.0f)\n            curveTo(11.79f, 22.0f, 11.59f, 21.94f, 11.43f, 21.82f)\n            lineTo(3.53f, 17.38f)\n            curveTo(3.21f, 17.21f, 3.0f, 16.88f, 3.0f, 16.5f)\n            verticalLineTo(7.5f)\n            curveTo(3.0f, 7.12f, 3.21f, 6.79f, 3.53f, 6.62f)\n            lineTo(11.43f, 2.18f)\n            curveTo(11.59f, 2.06f, 11.79f, 2.0f, 12.0f, 2.0f)\n            curveTo(12.21f, 2.0f, 12.41f, 2.06f, 12.57f, 2.18f)\n            lineTo(20.47f, 6.62f)\n            curveTo(20.79f, 6.79f, 21.0f, 7.12f, 21.0f, 7.5f)\n            verticalLineTo(16.5f)\n            moveTo(12.0f, 4.15f)\n            lineTo(6.04f, 7.5f)\n            lineTo(12.0f, 10.85f)\n            lineTo(17.96f, 7.5f)\n            lineTo(12.0f, 4.15f)\n            moveTo(5.0f, 15.91f)\n            lineTo(11.0f, 19.29f)\n            verticalLineTo(12.58f)\n            lineTo(5.0f, 9.21f)\n            verticalLineTo(15.91f)\n            moveTo(19.0f, 15.91f)\n            verticalLineTo(9.21f)\n            lineTo(13.0f, 12.58f)\n            verticalLineTo(19.29f)\n            lineTo(19.0f, 15.91f)\n            close()\n        }\n    }\n        .build()\n}\n\nval Icons.Rounded.Cube: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"Rounded.DeployedCode\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(440f, 869f)\n            lineTo(160f, 708f)\n            quadTo(141f, 697f, 130.5f, 679f)\n            quadTo(120f, 661f, 120f, 639f)\n            lineTo(120f, 321f)\n            quadTo(120f, 299f, 130.5f, 281f)\n            quadTo(141f, 263f, 160f, 252f)\n            lineTo(440f, 91f)\n            quadTo(459f, 80f, 480f, 80f)\n            quadTo(501f, 80f, 520f, 91f)\n            lineTo(800f, 252f)\n            quadTo(819f, 263f, 829.5f, 281f)\n            quadTo(840f, 299f, 840f, 321f)\n            lineTo(840f, 639f)\n            quadTo(840f, 661f, 829.5f, 679f)\n            quadTo(819f, 697f, 800f, 708f)\n            lineTo(520f, 869f)\n            quadTo(501f, 880f, 480f, 880f)\n            quadTo(459f, 880f, 440f, 869f)\n            close()\n            moveTo(440f, 503f)\n            lineTo(440f, 777f)\n            lineTo(480f, 800f)\n            quadTo(480f, 800f, 480f, 800f)\n            quadTo(480f, 800f, 480f, 800f)\n            lineTo(520f, 777f)\n            lineTo(520f, 503f)\n            lineTo(760f, 364f)\n            lineTo(760f, 322f)\n            quadTo(760f, 322f, 760f, 322f)\n            quadTo(760f, 322f, 760f, 322f)\n            lineTo(717f, 297f)\n            lineTo(480f, 434f)\n            lineTo(243f, 297f)\n            lineTo(200f, 322f)\n            quadTo(200f, 322f, 200f, 322f)\n            quadTo(200f, 322f, 200f, 322f)\n            lineTo(200f, 364f)\n            lineTo(440f, 503f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Curve.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Curve: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Curve\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9.96f, 11.31f)\n            curveTo(10.82f, 8.1f, 11.5f, 6f, 13f, 6f)\n            curveTo(14.5f, 6f, 15.18f, 8.1f, 16.04f, 11.31f)\n            curveTo(17f, 14.92f, 18.1f, 19f, 22f, 19f)\n            verticalLineTo(17f)\n            curveTo(19.8f, 17f, 19f, 14.54f, 17.97f, 10.8f)\n            curveTo(17.08f, 7.46f, 16.15f, 4f, 13f, 4f)\n            curveTo(9.85f, 4f, 8.92f, 7.46f, 8.03f, 10.8f)\n            curveTo(7.03f, 14.54f, 6.2f, 17f, 4f, 17f)\n            verticalLineTo(2f)\n            horizontalLineTo(2f)\n            verticalLineTo(22f)\n            horizontalLineTo(22f)\n            verticalLineTo(20f)\n            horizontalLineTo(4f)\n            verticalLineTo(19f)\n            curveTo(7.9f, 19f, 9f, 14.92f, 9.96f, 11.31f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/DashedLine.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.DashedLine: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"DashedLine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(11.291f, 14.828f)\n            lineToRelative(-4.242f, 4.242f)\n            curveToRelative(-0.585f, 0.585f, -1.534f, 0.585f, -2.119f, 0f)\n            lineToRelative(-0f, -0f)\n            curveToRelative(-0.585f, -0.585f, -0.585f, -1.534f, 0f, -2.119f)\n            lineToRelative(4.242f, -4.242f)\n            curveToRelative(0.585f, -0.585f, 1.534f, -0.585f, 2.119f, 0f)\n            lineToRelative(0f, 0f)\n            curveTo(11.877f, 13.294f, 11.877f, 14.243f, 11.291f, 14.828f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19.071f, 7.049f)\n            lineToRelative(-4.242f, 4.242f)\n            curveToRelative(-0.585f, 0.585f, -1.534f, 0.585f, -2.119f, 0f)\n            lineToRelative(-0f, -0f)\n            curveToRelative(-0.585f, -0.585f, -0.585f, -1.534f, 0f, -2.119f)\n            lineToRelative(4.242f, -4.242f)\n            curveToRelative(0.585f, -0.585f, 1.534f, -0.585f, 2.119f, 0f)\n            lineToRelative(0f, 0f)\n            curveTo(19.656f, 5.515f, 19.656f, 6.464f, 19.071f, 7.049f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Database.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Database: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Database\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(480f, 440f)\n            quadTo(630f, 440f, 735f, 393f)\n            quadTo(840f, 346f, 840f, 280f)\n            quadTo(840f, 214f, 735f, 167f)\n            quadTo(630f, 120f, 480f, 120f)\n            quadTo(330f, 120f, 225f, 167f)\n            quadTo(120f, 214f, 120f, 280f)\n            quadTo(120f, 346f, 225f, 393f)\n            quadTo(330f, 440f, 480f, 440f)\n            close()\n            moveTo(480f, 540f)\n            quadTo(521f, 540f, 582.5f, 531.5f)\n            quadTo(644f, 523f, 701f, 504f)\n            quadTo(758f, 485f, 799f, 454.5f)\n            quadTo(840f, 424f, 840f, 380f)\n            lineTo(840f, 480f)\n            quadTo(840f, 524f, 799f, 554.5f)\n            quadTo(758f, 585f, 701f, 604f)\n            quadTo(644f, 623f, 582.5f, 631.5f)\n            quadTo(521f, 640f, 480f, 640f)\n            quadTo(439f, 640f, 377.5f, 631.5f)\n            quadTo(316f, 623f, 259f, 604f)\n            quadTo(202f, 585f, 161f, 554.5f)\n            quadTo(120f, 524f, 120f, 480f)\n            lineTo(120f, 380f)\n            quadTo(120f, 424f, 161f, 454.5f)\n            quadTo(202f, 485f, 259f, 504f)\n            quadTo(316f, 523f, 377.5f, 531.5f)\n            quadTo(439f, 540f, 480f, 540f)\n            close()\n            moveTo(480f, 740f)\n            quadTo(521f, 740f, 582.5f, 731.5f)\n            quadTo(644f, 723f, 701f, 704f)\n            quadTo(758f, 685f, 799f, 654.5f)\n            quadTo(840f, 624f, 840f, 580f)\n            lineTo(840f, 680f)\n            quadTo(840f, 724f, 799f, 754.5f)\n            quadTo(758f, 785f, 701f, 804f)\n            quadTo(644f, 823f, 582.5f, 831.5f)\n            quadTo(521f, 840f, 480f, 840f)\n            quadTo(439f, 840f, 377.5f, 831.5f)\n            quadTo(316f, 823f, 259f, 804f)\n            quadTo(202f, 785f, 161f, 754.5f)\n            quadTo(120f, 724f, 120f, 680f)\n            lineTo(120f, 580f)\n            quadTo(120f, 624f, 161f, 654.5f)\n            quadTo(202f, 685f, 259f, 704f)\n            quadTo(316f, 723f, 377.5f, 731.5f)\n            quadTo(439f, 740f, 480f, 740f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Delete.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Delete: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Delete\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(200f, 760f)\n            verticalLineToRelative(-520f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(160f, 200f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(200f, 160f)\n            horizontalLineToRelative(160f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(400f, 120f)\n            horizontalLineToRelative(160f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(600f, 160f)\n            horizontalLineToRelative(160f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(800f, 200f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(760f, 240f)\n            verticalLineToRelative(520f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(680f, 840f)\n            lineTo(280f, 840f)\n            close()\n            moveTo(428.5f, 668.5f)\n            quadTo(440f, 657f, 440f, 640f)\n            verticalLineToRelative(-280f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(400f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            reflectiveQuadTo(360f, 360f)\n            verticalLineToRelative(280f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(400f, 680f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            close()\n            moveTo(588.5f, 668.5f)\n            quadTo(600f, 657f, 600f, 640f)\n            verticalLineToRelative(-280f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(560f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            reflectiveQuadTo(520f, 360f)\n            verticalLineToRelative(280f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(560f, 680f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Delete: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.DeleteOutline\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(200f, 760f)\n            verticalLineToRelative(-520f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(160f, 200f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(200f, 160f)\n            horizontalLineToRelative(160f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(400f, 120f)\n            horizontalLineToRelative(160f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(600f, 160f)\n            horizontalLineToRelative(160f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(800f, 200f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(760f, 240f)\n            verticalLineToRelative(520f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(680f, 840f)\n            lineTo(280f, 840f)\n            close()\n            moveTo(680f, 240f)\n            lineTo(280f, 240f)\n            verticalLineToRelative(520f)\n            horizontalLineToRelative(400f)\n            verticalLineToRelative(-520f)\n            close()\n            moveTo(428.5f, 668.5f)\n            quadTo(440f, 657f, 440f, 640f)\n            verticalLineToRelative(-280f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(400f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            reflectiveQuadTo(360f, 360f)\n            verticalLineToRelative(280f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(400f, 680f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            close()\n            moveTo(588.5f, 668.5f)\n            quadTo(600f, 657f, 600f, 640f)\n            verticalLineToRelative(-280f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(560f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            reflectiveQuadTo(520f, 360f)\n            verticalLineToRelative(280f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(560f, 680f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            close()\n            moveTo(280f, 240f)\n            verticalLineToRelative(520f)\n            verticalLineToRelative(-520f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/DeleteSweep.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.DeleteSweep: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.DeleteSweep\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(200f, 760f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120f, 680f)\n            verticalLineToRelative(-360f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(80f, 280f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(120f, 240f)\n            horizontalLineToRelative(120f)\n            verticalLineToRelative(-20f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(280f, 180f)\n            horizontalLineToRelative(80f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(400f, 220f)\n            verticalLineToRelative(20f)\n            horizontalLineToRelative(120f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(560f, 280f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(520f, 320f)\n            verticalLineToRelative(360f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(440f, 760f)\n            lineTo(200f, 760f)\n            close()\n            moveTo(640f, 720f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(600f, 680f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(640f, 640f)\n            horizontalLineToRelative(80f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(760f, 680f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(720f, 720f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(640f, 560f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(600f, 520f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(640f, 480f)\n            horizontalLineToRelative(160f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(840f, 520f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(800f, 560f)\n            lineTo(640f, 560f)\n            close()\n            moveTo(640f, 400f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(600f, 360f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(640f, 320f)\n            horizontalLineToRelative(200f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(880f, 360f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(840f, 400f)\n            lineTo(640f, 400f)\n            close()\n            moveTo(200f, 320f)\n            verticalLineToRelative(360f)\n            horizontalLineToRelative(240f)\n            verticalLineToRelative(-360f)\n            lineTo(200f, 320f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.DeleteSweep: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.DeleteSweep\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 19f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(8f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(3f)\n            verticalLineToRelative(-0.5f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(0.5f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            verticalLineToRelative(9f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-6f)\n            close()\n            moveTo(16f, 18f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(16f, 14f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-4f)\n            close()\n            moveTo(16f, 10f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(5f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-5f)\n            close()\n            moveTo(5f, 8f)\n            verticalLineToRelative(9f)\n            horizontalLineToRelative(6f)\n            verticalLineTo(8f)\n            horizontalLineToRelative(-6f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 8f)\n            horizontalLineToRelative(6f)\n            verticalLineToRelative(9f)\n            horizontalLineToRelative(-6f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Deselect.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Deselect: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Deselect\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(763f, 876f)\n            lineTo(567f, 680f)\n            lineTo(360f, 680f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(280f, 600f)\n            verticalLineToRelative(-207f)\n            lineTo(84f, 197f)\n            quadToRelative(-11f, -11f, -11f, -27.5f)\n            reflectiveQuadTo(84f, 141f)\n            quadToRelative(12f, -12f, 28.5f, -12f)\n            reflectiveQuadToRelative(28.5f, 12f)\n            lineToRelative(679f, 679f)\n            quadToRelative(12f, 12f, 11.5f, 28f)\n            reflectiveQuadTo(819f, 876f)\n            quadToRelative(-12f, 11f, -28f, 11.5f)\n            reflectiveQuadTo(763f, 876f)\n            close()\n            moveTo(487f, 600f)\n            lineTo(360f, 473f)\n            verticalLineToRelative(127f)\n            horizontalLineToRelative(127f)\n            close()\n            moveTo(680f, 567f)\n            lineTo(600f, 487f)\n            verticalLineToRelative(-127f)\n            lineTo(473f, 360f)\n            lineToRelative(-80f, -80f)\n            horizontalLineToRelative(207f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(680f, 360f)\n            verticalLineToRelative(207f)\n            close()\n            moveTo(291.5f, 188.5f)\n            quadTo(280f, 177f, 280f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(303f, 120f, 320f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(360f, 143f, 360f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(337f, 200f, 320f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(451.5f, 188.5f)\n            quadTo(440f, 177f, 440f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(463f, 120f, 480f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(520f, 143f, 520f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(497f, 200f, 480f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(611.5f, 188.5f)\n            quadTo(600f, 177f, 600f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(623f, 120f, 640f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(680f, 143f, 680f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(657f, 200f, 640f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 188.5f)\n            quadTo(760f, 177f, 760f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 120f, 800f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 143f, 840f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 200f, 800f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 348.5f)\n            quadTo(120f, 337f, 120f, 320f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 280f, 160f, 280f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 303f, 200f, 320f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 360f, 160f, 360f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 348.5f)\n            quadTo(760f, 337f, 760f, 320f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 280f, 800f, 280f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 303f, 840f, 320f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 360f, 800f, 360f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 508.5f)\n            quadTo(120f, 497f, 120f, 480f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 440f, 160f, 440f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 463f, 200f, 480f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 520f, 160f, 520f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 508.5f)\n            quadTo(760f, 497f, 760f, 480f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 440f, 800f, 440f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 463f, 840f, 480f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 520f, 800f, 520f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 668.5f)\n            quadTo(120f, 657f, 120f, 640f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 600f, 160f, 600f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 623f, 200f, 640f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 680f, 160f, 680f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 668.5f)\n            quadTo(760f, 657f, 760f, 640f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 600f, 800f, 600f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 623f, 840f, 640f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 680f, 800f, 680f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 828.5f)\n            quadTo(120f, 817f, 120f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 760f, 160f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 783f, 200f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 840f, 160f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(291.5f, 828.5f)\n            quadTo(280f, 817f, 280f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(303f, 760f, 320f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(360f, 783f, 360f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(337f, 840f, 320f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(451.5f, 828.5f)\n            quadTo(440f, 817f, 440f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(463f, 760f, 480f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(520f, 783f, 520f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(497f, 840f, 480f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(611.5f, 828.5f)\n            quadTo(600f, 817f, 600f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(623f, 760f, 640f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(680f, 783f, 680f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(657f, 840f, 640f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/DesignServices.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.DesignServices: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.DesignServices\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(352f, 438f)\n            lineTo(438f, 351f)\n            lineTo(382f, 294f)\n            lineTo(338f, 338f)\n            lineTo(282f, 282f)\n            lineTo(325f, 238f)\n            lineTo(280f, 193f)\n            lineTo(193f, 280f)\n            lineTo(352f, 438f)\n            close()\n            moveTo(680f, 767f)\n            lineTo(767f, 680f)\n            lineTo(722f, 635f)\n            lineTo(678f, 678f)\n            lineTo(622f, 622f)\n            lineTo(665f, 578f)\n            lineTo(608f, 522f)\n            lineTo(522f, 608f)\n            lineTo(680f, 767f)\n            close()\n            moveTo(649f, 257f)\n            lineTo(705f, 313f)\n            lineTo(761f, 257f)\n            lineTo(704f, 200f)\n            lineTo(649f, 257f)\n            close()\n            moveTo(290f, 840f)\n            lineTo(120f, 840f)\n            lineTo(120f, 670f)\n            lineTo(295f, 495f)\n            lineTo(80f, 280f)\n            lineTo(280f, 80f)\n            lineTo(496f, 296f)\n            lineTo(647f, 144f)\n            quadTo(659f, 132f, 674f, 126f)\n            quadTo(689f, 120f, 705f, 120f)\n            quadTo(721f, 120f, 736f, 126f)\n            quadTo(751f, 132f, 763f, 144f)\n            lineTo(816f, 198f)\n            quadTo(828f, 210f, 834f, 225f)\n            quadTo(840f, 240f, 840f, 256f)\n            quadTo(840f, 272f, 834f, 286.5f)\n            quadTo(828f, 301f, 816f, 313f)\n            lineTo(665f, 465f)\n            lineTo(880f, 680f)\n            lineTo(680f, 880f)\n            lineTo(465f, 665f)\n            lineTo(290f, 840f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.DesignServices: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.DesignServices\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17.6f, 5f)\n            lineToRelative(1.425f, 1.425f)\n            lineToRelative(-1.425f, -1.425f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.625f, 11.625f)\n            lineToRelative(3.775f, -3.8f)\n            curveToRelative(0.2f, -0.2f, 0.35f, -0.421f, 0.45f, -0.663f)\n            curveToRelative(0.1f, -0.242f, 0.15f, -0.496f, 0.15f, -0.762f)\n            reflectiveCurveToRelative(-0.05f, -0.525f, -0.15f, -0.775f)\n            curveToRelative(-0.1f, -0.25f, -0.25f, -0.475f, -0.45f, -0.675f)\n            lineToRelative(-1.325f, -1.35f)\n            curveToRelative(-0.2f, -0.2f, -0.425f, -0.35f, -0.675f, -0.45f)\n            curveToRelative(-0.25f, -0.1f, -0.508f, -0.15f, -0.775f, -0.15f)\n            reflectiveCurveToRelative(-0.525f, 0.05f, -0.775f, 0.15f)\n            curveToRelative(-0.25f, 0.1f, -0.475f, 0.25f, -0.675f, 0.45f)\n            lineToRelative(-3.775f, 3.8f)\n            lineTo(7f, 2f)\n            lineTo(2f, 7f)\n            lineToRelative(5.375f, 5.375f)\n            lineToRelative(-4.375f, 4.375f)\n            verticalLineToRelative(4.25f)\n            horizontalLineToRelative(4.25f)\n            lineToRelative(4.375f, -4.375f)\n            lineToRelative(5.375f, 5.375f)\n            lineToRelative(5f, -5f)\n            lineToRelative(-5.375f, -5.375f)\n            close()\n            moveTo(4.825f, 7f)\n            lineToRelative(2.175f, -2.175f)\n            lineToRelative(1.125f, 1.125f)\n            lineToRelative(-1.075f, 1.1f)\n            lineToRelative(1.4f, 1.4f)\n            lineToRelative(1.1f, -1.1f)\n            lineToRelative(1.4f, 1.425f)\n            lineToRelative(-2.15f, 2.175f)\n            lineToRelative(-3.975f, -3.95f)\n            close()\n            moveTo(6.4f, 19f)\n            horizontalLineToRelative(-1.4f)\n            verticalLineToRelative(-1.4f)\n            lineTo(14.775f, 7.8f)\n            lineToRelative(1.425f, 1.425f)\n            lineToRelative(-9.8f, 9.775f)\n            close()\n            moveTo(13.05f, 15.2f)\n            lineToRelative(2.15f, -2.15f)\n            lineToRelative(1.425f, 1.4f)\n            lineToRelative(-1.075f, 1.1f)\n            lineToRelative(1.4f, 1.4f)\n            lineToRelative(1.1f, -1.075f)\n            lineToRelative(1.125f, 1.125f)\n            lineToRelative(-2.175f, 2.175f)\n            lineToRelative(-3.95f, -3.975f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15.5f, 8.525f)\n            lineToRelative(-0.725f, -0.725f)\n            lineToRelative(1.425f, 1.425f)\n            lineToRelative(-0.7f, -0.7f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(8.8f, 10.95f)\n            lineToRelative(2.15f, -2.175f)\n            lineToRelative(-1.4f, -1.425f)\n            lineToRelative(-1.1f, 1.1f)\n            lineToRelative(-1.4f, -1.4f)\n            lineToRelative(1.075f, -1.1f)\n            lineToRelative(-1.125f, -1.125f)\n            lineToRelative(-2.175f, 2.175f)\n            lineToRelative(3.975f, 3.95f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(17f, 19.175f)\n            lineToRelative(2.175f, -2.175f)\n            lineToRelative(-1.125f, -1.125f)\n            lineToRelative(-1.1f, 1.075f)\n            lineToRelative(-1.4f, -1.4f)\n            lineToRelative(1.075f, -1.1f)\n            lineToRelative(-1.425f, -1.4f)\n            lineToRelative(-2.15f, 2.15f)\n            lineToRelative(3.95f, 3.975f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 19f)\n            lineToRelative(1.4f, 0f)\n            lineToRelative(9.8f, -9.775f)\n            lineToRelative(-1.425f, -1.425f)\n            lineToRelative(-9.775f, 9.8f)\n            lineToRelative(0f, 1.4f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.DesignServices: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.DesignServices\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(352f, 438f)\n            lineTo(438f, 351f)\n            lineTo(382f, 294f)\n            lineTo(338f, 338f)\n            lineTo(282f, 282f)\n            lineTo(325f, 238f)\n            lineTo(280f, 193f)\n            lineTo(193f, 280f)\n            lineTo(352f, 438f)\n            close()\n            moveTo(680f, 767f)\n            lineTo(767f, 680f)\n            lineTo(722f, 635f)\n            lineTo(678f, 678f)\n            lineTo(622f, 622f)\n            lineTo(665f, 578f)\n            lineTo(608f, 522f)\n            lineTo(522f, 608f)\n            lineTo(680f, 767f)\n            close()\n            moveTo(704f, 200f)\n            lineTo(761f, 257f)\n            lineTo(761f, 257f)\n            lineTo(704f, 200f)\n            close()\n            moveTo(290f, 840f)\n            lineTo(120f, 840f)\n            lineTo(120f, 670f)\n            lineTo(295f, 495f)\n            lineTo(80f, 280f)\n            lineTo(280f, 80f)\n            lineTo(496f, 296f)\n            lineTo(647f, 144f)\n            quadTo(659f, 132f, 674f, 126f)\n            quadTo(689f, 120f, 705f, 120f)\n            quadTo(721f, 120f, 736f, 126f)\n            quadTo(751f, 132f, 763f, 144f)\n            lineTo(816f, 198f)\n            quadTo(828f, 210f, 834f, 225f)\n            quadTo(840f, 240f, 840f, 256f)\n            quadTo(840f, 272f, 834f, 286.5f)\n            quadTo(828f, 301f, 816f, 313f)\n            lineTo(665f, 465f)\n            lineTo(880f, 680f)\n            lineTo(680f, 880f)\n            lineTo(465f, 665f)\n            lineTo(290f, 840f)\n            close()\n            moveTo(200f, 760f)\n            lineTo(256f, 760f)\n            lineTo(648f, 369f)\n            lineTo(591f, 312f)\n            lineTo(200f, 704f)\n            lineTo(200f, 760f)\n            close()\n            moveTo(620f, 341f)\n            lineTo(591f, 312f)\n            lineTo(591f, 312f)\n            lineTo(648f, 369f)\n            lineTo(648f, 369f)\n            lineTo(620f, 341f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/DocumentScanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.DocumentScanner: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.DocumentScanner\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(2f, 5f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(20f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(2f, 21f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            close()\n            moveTo(20f, 23f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            close()\n            moveTo(7f, 18f)\n            horizontalLineToRelative(10f)\n            verticalLineTo(6f)\n            horizontalLineTo(7f)\n            verticalLineToRelative(12f)\n            close()\n            moveTo(7f, 20f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(7f)\n            close()\n            moveTo(10f, 10f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(10f, 13f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(10f, 16f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(7f, 18f)\n            verticalLineTo(6f)\n            verticalLineToRelative(12f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.DocumentScanner: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.DocumentScanner\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(2f, 5f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(20f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(2f, 21f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            close()\n            moveTo(20f, 23f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            close()\n            moveTo(7f, 18f)\n            horizontalLineToRelative(10f)\n            verticalLineTo(6f)\n            horizontalLineTo(7f)\n            verticalLineToRelative(12f)\n            close()\n            moveTo(7f, 20f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(7f)\n            close()\n            moveTo(10f, 10f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(10f, 13f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(10f, 16f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(7f, 18f)\n            verticalLineTo(6f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(7f, 6f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(12f)\n            horizontalLineToRelative(-10f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/DotDashedLine.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.DotDashedLine: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"DotDashedLine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9.877f, 16.243f)\n            lineToRelative(-2.828f, 2.828f)\n            curveToRelative(-0.585f, 0.585f, -1.534f, 0.585f, -2.119f, 0f)\n            lineToRelative(-0f, -0f)\n            curveToRelative(-0.585f, -0.585f, -0.585f, -1.534f, -0f, -2.119f)\n            lineToRelative(2.828f, -2.828f)\n            curveToRelative(0.585f, -0.585f, 1.534f, -0.585f, 2.119f, 0f)\n            lineToRelative(0f, 0f)\n            curveTo(10.462f, 14.708f, 10.462f, 15.657f, 9.877f, 16.243f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19.071f, 7.049f)\n            lineToRelative(-2.83f, 2.83f)\n            curveToRelative(-0.585f, 0.585f, -1.534f, 0.585f, -2.119f, 0f)\n            lineToRelative(-0f, -0f)\n            curveToRelative(-0.585f, -0.585f, -0.585f, -1.534f, 0f, -2.119f)\n            lineToRelative(2.83f, -2.83f)\n            curveToRelative(0.585f, -0.585f, 1.534f, -0.585f, 2.119f, 0f)\n            lineToRelative(0f, 0f)\n            curveTo(19.656f, 5.515f, 19.656f, 6.464f, 19.071f, 7.049f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13.06f, 13.06f)\n            lineToRelative(-0f, 0f)\n            curveToRelative(-0.585f, 0.585f, -1.534f, 0.585f, -2.119f, 0f)\n            lineToRelative(-0f, -0f)\n            curveToRelative(-0.585f, -0.585f, -0.585f, -1.534f, 0f, -2.119f)\n            lineToRelative(0f, -0f)\n            curveToRelative(0.585f, -0.585f, 1.534f, -0.585f, 2.119f, 0f)\n            lineToRelative(0f, 0f)\n            curveTo(13.645f, 11.526f, 13.645f, 12.474f, 13.06f, 13.06f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Dots.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Dots: ImageVector by lazy {\n    Builder(\n        name = \"Dots\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 19.0f)\n            curveTo(13.1f, 19.0f, 14.0f, 19.9f, 14.0f, 21.0f)\n            reflectiveCurveTo(13.1f, 23.0f, 12.0f, 23.0f)\n            reflectiveCurveTo(10.0f, 22.1f, 10.0f, 21.0f)\n            reflectiveCurveTo(10.9f, 19.0f, 12.0f, 19.0f)\n            moveTo(12.0f, 1.0f)\n            curveTo(13.1f, 1.0f, 14.0f, 1.9f, 14.0f, 3.0f)\n            reflectiveCurveTo(13.1f, 5.0f, 12.0f, 5.0f)\n            reflectiveCurveTo(10.0f, 4.1f, 10.0f, 3.0f)\n            reflectiveCurveTo(10.9f, 1.0f, 12.0f, 1.0f)\n            moveTo(6.0f, 16.0f)\n            curveTo(7.1f, 16.0f, 8.0f, 16.9f, 8.0f, 18.0f)\n            reflectiveCurveTo(7.1f, 20.0f, 6.0f, 20.0f)\n            reflectiveCurveTo(4.0f, 19.1f, 4.0f, 18.0f)\n            reflectiveCurveTo(4.9f, 16.0f, 6.0f, 16.0f)\n            moveTo(3.0f, 10.0f)\n            curveTo(4.1f, 10.0f, 5.0f, 10.9f, 5.0f, 12.0f)\n            reflectiveCurveTo(4.1f, 14.0f, 3.0f, 14.0f)\n            reflectiveCurveTo(1.0f, 13.1f, 1.0f, 12.0f)\n            reflectiveCurveTo(1.9f, 10.0f, 3.0f, 10.0f)\n            moveTo(6.0f, 4.0f)\n            curveTo(7.1f, 4.0f, 8.0f, 4.9f, 8.0f, 6.0f)\n            reflectiveCurveTo(7.1f, 8.0f, 6.0f, 8.0f)\n            reflectiveCurveTo(4.0f, 7.1f, 4.0f, 6.0f)\n            reflectiveCurveTo(4.9f, 4.0f, 6.0f, 4.0f)\n            moveTo(18.0f, 16.0f)\n            curveTo(19.1f, 16.0f, 20.0f, 16.9f, 20.0f, 18.0f)\n            reflectiveCurveTo(19.1f, 20.0f, 18.0f, 20.0f)\n            reflectiveCurveTo(16.0f, 19.1f, 16.0f, 18.0f)\n            reflectiveCurveTo(16.9f, 16.0f, 18.0f, 16.0f)\n            moveTo(21.0f, 10.0f)\n            curveTo(22.1f, 10.0f, 23.0f, 10.9f, 23.0f, 12.0f)\n            reflectiveCurveTo(22.1f, 14.0f, 21.0f, 14.0f)\n            reflectiveCurveTo(19.0f, 13.1f, 19.0f, 12.0f)\n            reflectiveCurveTo(19.9f, 10.0f, 21.0f, 10.0f)\n            moveTo(18.0f, 4.0f)\n            curveTo(19.1f, 4.0f, 20.0f, 4.9f, 20.0f, 6.0f)\n            reflectiveCurveTo(19.1f, 8.0f, 18.0f, 8.0f)\n            reflectiveCurveTo(16.0f, 7.1f, 16.0f, 6.0f)\n            reflectiveCurveTo(16.9f, 4.0f, 18.0f, 4.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/DownloadFile.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.DownloadFile: ImageVector by lazy {\n    Builder(\n        name = \"Download File\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(14.0f, 2.0f)\n            horizontalLineTo(6.0f)\n            curveTo(4.89f, 2.0f, 4.0f, 2.89f, 4.0f, 4.0f)\n            verticalLineTo(20.0f)\n            curveTo(4.0f, 21.11f, 4.89f, 22.0f, 6.0f, 22.0f)\n            horizontalLineTo(18.0f)\n            curveTo(19.11f, 22.0f, 20.0f, 21.11f, 20.0f, 20.0f)\n            verticalLineTo(8.0f)\n            lineTo(14.0f, 2.0f)\n            moveTo(12.0f, 19.0f)\n            lineTo(8.0f, 15.0f)\n            horizontalLineTo(10.5f)\n            verticalLineTo(12.0f)\n            horizontalLineTo(13.5f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(16.0f)\n            lineTo(12.0f, 19.0f)\n            moveTo(13.0f, 9.0f)\n            verticalLineTo(3.5f)\n            lineTo(18.5f, 9.0f)\n            horizontalLineTo(13.0f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.DownloadFile: ImageVector by lazy {\n    Builder(\n        name = \"Download File Outline\", defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(14.0f, 2.0f)\n            lineTo(20.0f, 8.0f)\n            verticalLineTo(20.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 18.0f,\n                y1 = 22.0f\n            )\n            horizontalLineTo(6.0f)\n            arcTo(\n                horizontalEllipseRadius = 2.0f,\n                verticalEllipseRadius = 2.0f,\n                theta = 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 4.0f,\n                y1 = 20.0f\n            )\n            verticalLineTo(4.0f)\n            arcTo(\n                horizontalEllipseRadius = 2.0f,\n                verticalEllipseRadius = 2.0f,\n                theta = 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 6.0f,\n                y1 = 2.0f\n            )\n            horizontalLineTo(14.0f)\n            moveTo(18.0f, 20.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(4.0f)\n            horizontalLineTo(6.0f)\n            verticalLineTo(20.0f)\n            horizontalLineTo(18.0f)\n            moveTo(12.0f, 19.0f)\n            lineTo(8.0f, 15.0f)\n            horizontalLineTo(10.5f)\n            verticalLineTo(12.0f)\n            horizontalLineTo(13.5f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(16.0f)\n            lineTo(12.0f, 19.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Draw.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Draw: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Draw\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(200f, 840f)\n            quadTo(183f, 840f, 171.5f, 828.5f)\n            quadTo(160f, 817f, 160f, 800f)\n            lineTo(160f, 703f)\n            quadTo(160f, 687f, 166f, 672.5f)\n            quadTo(172f, 658f, 183f, 647f)\n            lineTo(687f, 144f)\n            quadTo(699f, 132f, 714f, 126f)\n            quadTo(729f, 120f, 744f, 120f)\n            quadTo(760f, 120f, 774.5f, 126f)\n            quadTo(789f, 132f, 800f, 144f)\n            lineTo(856f, 200f)\n            quadTo(868f, 211f, 874f, 225.5f)\n            quadTo(880f, 240f, 880f, 256f)\n            quadTo(880f, 271f, 874f, 286f)\n            quadTo(868f, 301f, 856f, 313f)\n            lineTo(353f, 817f)\n            quadTo(342f, 828f, 327.5f, 834f)\n            quadTo(313f, 840f, 297f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(240f, 760f)\n            lineTo(296f, 760f)\n            lineTo(689f, 368f)\n            lineTo(661f, 339f)\n            lineTo(632f, 311f)\n            lineTo(240f, 704f)\n            lineTo(240f, 760f)\n            close()\n            moveTo(800f, 257f)\n            lineTo(800f, 257f)\n            lineTo(743f, 200f)\n            lineTo(743f, 200f)\n            lineTo(800f, 257f)\n            close()\n            moveTo(661f, 339f)\n            lineTo(632f, 311f)\n            lineTo(632f, 311f)\n            lineTo(689f, 368f)\n            lineTo(689f, 368f)\n            lineTo(661f, 339f)\n            close()\n            moveTo(560f, 840f)\n            quadTo(634f, 840f, 697f, 803f)\n            quadTo(760f, 766f, 760f, 700f)\n            quadTo(760f, 668f, 744f, 644.5f)\n            quadTo(728f, 621f, 702f, 601f)\n            quadTo(688f, 591f, 672f, 591f)\n            quadTo(656f, 591f, 645f, 603f)\n            quadTo(634f, 615f, 634f, 632.5f)\n            quadTo(634f, 650f, 648f, 660f)\n            quadTo(662f, 671f, 671f, 680f)\n            quadTo(680f, 689f, 680f, 700f)\n            quadTo(680f, 723f, 643.5f, 741.5f)\n            quadTo(607f, 760f, 560f, 760f)\n            quadTo(543f, 760f, 531.5f, 771.5f)\n            quadTo(520f, 783f, 520f, 800f)\n            quadTo(520f, 817f, 531.5f, 828.5f)\n            quadTo(543f, 840f, 560f, 840f)\n            close()\n            moveTo(360f, 240f)\n            quadTo(360f, 254f, 342.5f, 265.5f)\n            quadTo(325f, 277f, 262f, 306f)\n            quadTo(182f, 341f, 151f, 369.5f)\n            quadTo(120f, 398f, 120f, 440f)\n            quadTo(120f, 466f, 132f, 486f)\n            quadTo(144f, 506f, 163f, 521f)\n            quadTo(176f, 532f, 192f, 530.5f)\n            quadTo(208f, 529f, 219f, 516f)\n            quadTo(230f, 503f, 229f, 487f)\n            quadTo(228f, 471f, 215f, 460f)\n            quadTo(208f, 455f, 204f, 450f)\n            quadTo(200f, 445f, 200f, 440f)\n            quadTo(200f, 428f, 218f, 416f)\n            quadTo(236f, 404f, 294f, 379f)\n            quadTo(382f, 341f, 411f, 310f)\n            quadTo(440f, 279f, 440f, 240f)\n            quadTo(440f, 185f, 396f, 152.5f)\n            quadTo(352f, 120f, 280f, 120f)\n            quadTo(235f, 120f, 199.5f, 136f)\n            quadTo(164f, 152f, 145f, 175f)\n            quadTo(134f, 188f, 136f, 204f)\n            quadTo(138f, 220f, 151f, 230f)\n            quadTo(164f, 241f, 180f, 239f)\n            quadTo(196f, 237f, 207f, 226f)\n            quadTo(221f, 212f, 238f, 206f)\n            quadTo(255f, 200f, 280f, 200f)\n            quadTo(321f, 200f, 340.5f, 212f)\n            quadTo(360f, 224f, 360f, 240f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Draw: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Draw\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(200f, 840f)\n            quadTo(183f, 840f, 171.5f, 828.5f)\n            quadTo(160f, 817f, 160f, 800f)\n            lineTo(160f, 703f)\n            quadTo(160f, 687f, 166f, 672.5f)\n            quadTo(172f, 658f, 183f, 647f)\n            lineTo(687f, 144f)\n            quadTo(699f, 132f, 714f, 126f)\n            quadTo(729f, 120f, 744f, 120f)\n            quadTo(760f, 120f, 774.5f, 126f)\n            quadTo(789f, 132f, 800f, 144f)\n            lineTo(856f, 200f)\n            quadTo(868f, 211f, 874f, 225.5f)\n            quadTo(880f, 240f, 880f, 256f)\n            quadTo(880f, 271f, 874f, 286f)\n            quadTo(868f, 301f, 856f, 313f)\n            lineTo(353f, 817f)\n            quadTo(342f, 828f, 327.5f, 834f)\n            quadTo(313f, 840f, 297f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(746f, 311f)\n            lineTo(800f, 257f)\n            lineTo(743f, 200f)\n            lineTo(689f, 254f)\n            lineTo(746f, 311f)\n            close()\n            moveTo(560f, 840f)\n            quadTo(634f, 840f, 697f, 803f)\n            quadTo(760f, 766f, 760f, 700f)\n            quadTo(760f, 668f, 744f, 644.5f)\n            quadTo(728f, 621f, 702f, 601f)\n            quadTo(688f, 591f, 672f, 591f)\n            quadTo(656f, 591f, 645f, 603f)\n            quadTo(634f, 615f, 634f, 632.5f)\n            quadTo(634f, 650f, 648f, 660f)\n            quadTo(662f, 671f, 671f, 680f)\n            quadTo(680f, 689f, 680f, 700f)\n            quadTo(680f, 723f, 643.5f, 741.5f)\n            quadTo(607f, 760f, 560f, 760f)\n            quadTo(543f, 760f, 531.5f, 771.5f)\n            quadTo(520f, 783f, 520f, 800f)\n            quadTo(520f, 817f, 531.5f, 828.5f)\n            quadTo(543f, 840f, 560f, 840f)\n            close()\n            moveTo(360f, 240f)\n            quadTo(360f, 254f, 342.5f, 265.5f)\n            quadTo(325f, 277f, 262f, 306f)\n            quadTo(182f, 341f, 151f, 369.5f)\n            quadTo(120f, 398f, 120f, 440f)\n            quadTo(120f, 466f, 132f, 486f)\n            quadTo(144f, 506f, 163f, 521f)\n            quadTo(176f, 532f, 192f, 530.5f)\n            quadTo(208f, 529f, 219f, 516f)\n            quadTo(230f, 503f, 229f, 487f)\n            quadTo(228f, 471f, 215f, 460f)\n            quadTo(208f, 455f, 204f, 450f)\n            quadTo(200f, 445f, 200f, 440f)\n            quadTo(200f, 428f, 218f, 416f)\n            quadTo(236f, 404f, 294f, 379f)\n            quadTo(382f, 341f, 411f, 310f)\n            quadTo(440f, 279f, 440f, 240f)\n            quadTo(440f, 185f, 396f, 152.5f)\n            quadTo(352f, 120f, 280f, 120f)\n            quadTo(235f, 120f, 199.5f, 136f)\n            quadTo(164f, 152f, 145f, 175f)\n            quadTo(134f, 188f, 136f, 204f)\n            quadTo(138f, 220f, 151f, 230f)\n            quadTo(164f, 241f, 180f, 239f)\n            quadTo(196f, 237f, 207f, 226f)\n            quadTo(221f, 212f, 238f, 206f)\n            quadTo(255f, 200f, 280f, 200f)\n            quadTo(321f, 200f, 340.5f, 212f)\n            quadTo(360f, 224f, 360f, 240f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Draw: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Draw\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6f, 19f)\n            lineToRelative(1.4f, 0f)\n            lineToRelative(9.825f, -9.8f)\n            lineToRelative(-0.7f, -0.725f)\n            lineToRelative(-0.725f, -0.7f)\n            lineToRelative(-9.8f, 9.825f)\n            lineToRelative(0f, 1.4f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(16.525f, 8.475f)\n            lineToRelative(-0.725f, -0.7f)\n            lineToRelative(0f, 0f)\n            lineToRelative(1.425f, 1.425f)\n            lineToRelative(0f, 0f)\n            lineToRelative(-0.7f, -0.725f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(14f, 21f)\n            curveToRelative(1.233f, 0f, 2.375f, -0.308f, 3.425f, -0.925f)\n            reflectiveCurveToRelative(1.575f, -1.475f, 1.575f, -2.575f)\n            curveToRelative(0f, -0.533f, -0.133f, -0.996f, -0.4f, -1.388f)\n            reflectiveCurveToRelative(-0.617f, -0.754f, -1.05f, -1.087f)\n            curveToRelative(-0.233f, -0.167f, -0.483f, -0.25f, -0.75f, -0.25f)\n            reflectiveCurveToRelative(-0.492f, 0.1f, -0.675f, 0.3f)\n            reflectiveCurveToRelative(-0.275f, 0.446f, -0.275f, 0.738f)\n            reflectiveCurveToRelative(0.117f, 0.521f, 0.35f, 0.688f)\n            curveToRelative(0.233f, 0.183f, 0.425f, 0.35f, 0.575f, 0.5f)\n            reflectiveCurveToRelative(0.225f, 0.317f, 0.225f, 0.5f)\n            curveToRelative(0f, 0.383f, -0.304f, 0.729f, -0.913f, 1.038f)\n            reflectiveCurveToRelative(-1.304f, 0.463f, -2.088f, 0.463f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9f, 6f)\n            curveToRelative(0f, 0.233f, -0.146f, 0.446f, -0.438f, 0.637f)\n            reflectiveCurveToRelative(-0.962f, 0.529f, -2.013f, 1.013f)\n            curveToRelative(-1.333f, 0.583f, -2.258f, 1.112f, -2.775f, 1.587f)\n            reflectiveCurveToRelative(-0.775f, 1.063f, -0.775f, 1.763f)\n            curveToRelative(0f, 0.433f, 0.1f, 0.817f, 0.3f, 1.15f)\n            reflectiveCurveToRelative(0.458f, 0.625f, 0.775f, 0.875f)\n            curveToRelative(0.217f, 0.183f, 0.458f, 0.262f, 0.725f, 0.237f)\n            reflectiveCurveToRelative(0.492f, -0.146f, 0.675f, -0.363f)\n            curveToRelative(0.183f, -0.217f, 0.267f, -0.458f, 0.25f, -0.725f)\n            reflectiveCurveToRelative(-0.133f, -0.492f, -0.35f, -0.675f)\n            curveToRelative(-0.117f, -0.083f, -0.208f, -0.167f, -0.275f, -0.25f)\n            reflectiveCurveToRelative(-0.1f, -0.167f, -0.1f, -0.25f)\n            curveToRelative(0f, -0.2f, 0.15f, -0.4f, 0.45f, -0.6f)\n            reflectiveCurveToRelative(0.933f, -0.508f, 1.9f, -0.925f)\n            curveToRelative(1.467f, -0.633f, 2.442f, -1.208f, 2.925f, -1.725f)\n            reflectiveCurveToRelative(0.725f, -1.1f, 0.725f, -1.75f)\n            curveToRelative(0f, -0.917f, -0.367f, -1.646f, -1.1f, -2.188f)\n            reflectiveCurveToRelative(-1.7f, -0.813f, -2.9f, -0.813f)\n            curveToRelative(-0.75f, 0f, -1.421f, 0.133f, -2.013f, 0.4f)\n            curveToRelative(-0.592f, 0.267f, -1.046f, 0.592f, -1.362f, 0.975f)\n            curveToRelative(-0.183f, 0.217f, -0.258f, 0.458f, -0.225f, 0.725f)\n            reflectiveCurveToRelative(0.158f, 0.483f, 0.375f, 0.65f)\n            curveToRelative(0.217f, 0.183f, 0.458f, 0.258f, 0.725f, 0.225f)\n            reflectiveCurveToRelative(0.492f, -0.142f, 0.675f, -0.325f)\n            curveToRelative(0.233f, -0.233f, 0.492f, -0.4f, 0.775f, -0.5f)\n            reflectiveCurveToRelative(0.633f, -0.15f, 1.05f, -0.15f)\n            curveToRelative(0.683f, 0f, 1.188f, 0.1f, 1.513f, 0.3f)\n            reflectiveCurveToRelative(0.488f, 0.433f, 0.488f, 0.7f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(21.85f, 5.638f)\n            curveToRelative(-0.1f, -0.242f, -0.25f, -0.454f, -0.45f, -0.638f)\n            lineToRelative(-1.4f, -1.4f)\n            curveToRelative(-0.183f, -0.2f, -0.396f, -0.35f, -0.638f, -0.45f)\n            curveToRelative(-0.242f, -0.1f, -0.496f, -0.15f, -0.763f, -0.15f)\n            curveToRelative(-0.25f, 0f, -0.5f, 0.05f, -0.75f, 0.15f)\n            curveToRelative(-0.25f, 0.1f, -0.475f, 0.25f, -0.675f, 0.45f)\n            lineToRelative(-12.6f, 12.575f)\n            curveToRelative(-0.183f, 0.183f, -0.325f, 0.396f, -0.425f, 0.638f)\n            curveToRelative(-0.1f, 0.242f, -0.15f, 0.496f, -0.15f, 0.763f)\n            verticalLineToRelative(2.425f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.288f, 0.713f, 0.288f)\n            horizontalLineToRelative(2.425f)\n            curveToRelative(0.267f, 0f, 0.521f, -0.05f, 0.763f, -0.15f)\n            curveToRelative(0.242f, -0.1f, 0.454f, -0.242f, 0.638f, -0.425f)\n            lineToRelative(12.575f, -12.6f)\n            curveToRelative(0.2f, -0.2f, 0.35f, -0.425f, 0.45f, -0.675f)\n            curveToRelative(0.1f, -0.25f, 0.15f, -0.5f, 0.15f, -0.75f)\n            curveToRelative(0f, -0.267f, -0.05f, -0.521f, -0.15f, -0.762f)\n            close()\n            moveTo(7.4f, 19f)\n            horizontalLineToRelative(-1.4f)\n            verticalLineToRelative(-1.4f)\n            lineTo(15.8f, 7.775f)\n            lineToRelative(0.725f, 0.7f)\n            lineToRelative(0.7f, 0.725f)\n            lineToRelative(-9.825f, 9.8f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/EditAlt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.EditAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.EditAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000))\n        ) {\n            moveTo(200f, 760f)\n            horizontalLineToRelative(57f)\n            lineToRelative(391f, -391f)\n            lineToRelative(-57f, -57f)\n            lineToRelative(-391f, 391f)\n            verticalLineToRelative(57f)\n            close()\n            moveTo(160f, 840f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(120f, 800f)\n            verticalLineToRelative(-97f)\n            quadToRelative(0f, -16f, 6f, -30.5f)\n            reflectiveQuadToRelative(17f, -25.5f)\n            lineToRelative(505f, -504f)\n            quadToRelative(12f, -11f, 26.5f, -17f)\n            reflectiveQuadToRelative(30.5f, -6f)\n            quadToRelative(16f, 0f, 31f, 6f)\n            reflectiveQuadToRelative(26f, 18f)\n            lineToRelative(55f, 56f)\n            quadToRelative(12f, 11f, 17.5f, 26f)\n            reflectiveQuadToRelative(5.5f, 30f)\n            quadToRelative(0f, 16f, -5.5f, 30.5f)\n            reflectiveQuadTo(817f, 313f)\n            lineTo(313f, 817f)\n            quadToRelative(-11f, 11f, -25.5f, 17f)\n            reflectiveQuadToRelative(-30.5f, 6f)\n            horizontalLineToRelative(-97f)\n            close()\n            moveTo(760f, 256f)\n            lineTo(704f, 200f)\n            lineTo(760f, 256f)\n            close()\n            moveTo(619f, 341f)\n            lineTo(591f, 312f)\n            lineTo(648f, 369f)\n            lineTo(619f, 341f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Filled.EditAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Filled.EditAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(160f, 840f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(120f, 800f)\n            verticalLineToRelative(-97f)\n            quadToRelative(0f, -16f, 6f, -30.5f)\n            reflectiveQuadToRelative(17f, -25.5f)\n            lineToRelative(505f, -504f)\n            quadToRelative(12f, -11f, 26.5f, -17f)\n            reflectiveQuadToRelative(30.5f, -6f)\n            quadToRelative(16f, 0f, 31f, 6f)\n            reflectiveQuadToRelative(26f, 18f)\n            lineToRelative(55f, 56f)\n            quadToRelative(12f, 11f, 17.5f, 26f)\n            reflectiveQuadToRelative(5.5f, 30f)\n            quadToRelative(0f, 16f, -5.5f, 30.5f)\n            reflectiveQuadTo(817f, 313f)\n            lineTo(313f, 817f)\n            quadToRelative(-11f, 11f, -25.5f, 17f)\n            reflectiveQuadToRelative(-30.5f, 6f)\n            horizontalLineToRelative(-97f)\n            close()\n            moveTo(704f, 312f)\n            lineTo(760f, 256f)\n            lineTo(704f, 200f)\n            lineTo(648f, 256f)\n            lineTo(704f, 312f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/EmojiMultiple.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.EmojiMultiple: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.EmojiMultiple\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13.747f, 6.657f)\n            curveToRelative(-1.458f, -1.458f, -3.229f, -2.188f, -5.313f, -2.188f)\n            reflectiveCurveToRelative(-3.854f, 0.729f, -5.313f, 2.188f)\n            reflectiveCurveTo(0.935f, 9.886f, 0.935f, 11.969f)\n            reflectiveCurveToRelative(0.729f, 3.854f, 2.188f, 5.313f)\n            reflectiveCurveToRelative(3.229f, 2.188f, 5.313f, 2.188f)\n            reflectiveCurveToRelative(3.854f, -0.729f, 5.313f, -2.188f)\n            reflectiveCurveToRelative(2.188f, -3.229f, 2.188f, -5.313f)\n            reflectiveCurveToRelative(-0.729f, -3.854f, -2.188f, -5.313f)\n            close()\n            moveTo(12.322f, 15.857f)\n            curveToRelative(-1.075f, 1.075f, -2.371f, 1.612f, -3.888f, 1.612f)\n            reflectiveCurveToRelative(-2.813f, -0.537f, -3.888f, -1.612f)\n            reflectiveCurveToRelative(-1.612f, -2.371f, -1.612f, -3.888f)\n            reflectiveCurveToRelative(0.537f, -2.813f, 1.612f, -3.888f)\n            reflectiveCurveToRelative(2.371f, -1.612f, 3.888f, -1.612f)\n            reflectiveCurveToRelative(2.813f, 0.537f, 3.888f, 1.612f)\n            reflectiveCurveToRelative(1.612f, 2.371f, 1.612f, 3.888f)\n            reflectiveCurveToRelative(-0.537f, 2.813f, -1.612f, 3.888f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5.935f, 11.469f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.435f, 15.869f)\n            curveToRelative(0.8f, 0f, 1.513f, -0.225f, 2.138f, -0.675f)\n            reflectiveCurveToRelative(1.079f, -1.025f, 1.362f, -1.725f)\n            horizontalLineToRelative(-7f)\n            curveToRelative(0.283f, 0.7f, 0.738f, 1.275f, 1.362f, 1.725f)\n            reflectiveCurveToRelative(1.337f, 0.675f, 2.138f, 0.675f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10.935f, 11.469f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.878f, 6.718f)\n            curveToRelative(-1.458f, -1.458f, -3.229f, -2.188f, -5.313f, -2.188f)\n            curveToRelative(-0.626f, 0f, -1.221f, 0.074f, -1.791f, 0.206f)\n            curveToRelative(0.689f, 0.51f, 1.302f, 1.114f, 1.821f, 1.797f)\n            curveToRelative(1.503f, 0.007f, 2.79f, 0.542f, 3.857f, 1.61f)\n            curveToRelative(1.075f, 1.075f, 1.612f, 2.371f, 1.612f, 3.888f)\n            reflectiveCurveToRelative(-0.537f, 2.813f, -1.612f, 3.888f)\n            reflectiveCurveToRelative(-2.371f, 1.612f, -3.888f, 1.612f)\n            curveToRelative(-0.021f, 0f, -0.039f, -0.005f, -0.06f, -0.005f)\n            curveToRelative(-0.531f, 0.675f, -1.155f, 1.27f, -1.855f, 1.769f)\n            curveToRelative(0.607f, 0.152f, 1.243f, 0.236f, 1.915f, 0.236f)\n            curveToRelative(2.083f, 0f, 3.854f, -0.729f, 5.313f, -2.188f)\n            reflectiveCurveToRelative(2.188f, -3.229f, 2.188f, -5.313f)\n            reflectiveCurveToRelative(-0.729f, -3.854f, -2.188f, -5.313f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/EmojiSticky.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.EmojiSticky: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.EmojiSticky\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(460f, 600f)\n            quadToRelative(64f, 0f, 113.5f, -39.5f)\n            reflectiveQuadTo(637f, 460f)\n            quadToRelative(2f, -6f, -3f, -10.5f)\n            reflectiveQuadToRelative(-11f, -2.5f)\n            lineToRelative(-282f, 79f)\n            quadToRelative(-8f, 2f, -9.5f, 9.5f)\n            reflectiveQuadTo(335f, 548f)\n            quadToRelative(25f, 24f, 57f, 38f)\n            reflectiveQuadToRelative(68f, 14f)\n            close()\n            moveTo(294f, 450f)\n            lineToRelative(106f, -30f)\n            quadToRelative(4f, -28f, -14f, -49f)\n            reflectiveQuadToRelative(-46f, -21f)\n            quadToRelative(-25f, 0f, -42.5f, 17.5f)\n            reflectiveQuadTo(280f, 410f)\n            quadToRelative(0f, 11f, 4f, 21f)\n            reflectiveQuadToRelative(10f, 19f)\n            close()\n            moveTo(534f, 380f)\n            lineTo(640f, 350f)\n            quadToRelative(5f, -28f, -13.5f, -49f)\n            reflectiveQuadTo(580f, 280f)\n            quadToRelative(-25f, 0f, -42.5f, 17.5f)\n            reflectiveQuadTo(520f, 340f)\n            quadToRelative(0f, 11f, 4f, 21f)\n            reflectiveQuadToRelative(10f, 19f)\n            close()\n            moveTo(200f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120f, 760f)\n            verticalLineToRelative(-560f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(200f, 120f)\n            horizontalLineToRelative(560f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(840f, 200f)\n            verticalLineToRelative(407f)\n            quadToRelative(0f, 16f, -6f, 30.5f)\n            reflectiveQuadTo(817f, 663f)\n            lineTo(663f, 817f)\n            quadToRelative(-11f, 11f, -25.5f, 17f)\n            reflectiveQuadToRelative(-30.5f, 6f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(600f, 760f)\n            verticalLineToRelative(-80f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(680f, 600f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-400f)\n            lineTo(200f, 200f)\n            verticalLineToRelative(560f)\n            horizontalLineToRelative(400f)\n            close()\n            moveTo(600f, 760f)\n            close()\n            moveTo(200f, 760f)\n            verticalLineToRelative(-560f)\n            verticalLineToRelative(560f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Encrypted.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Encrypted: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Encrypted\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.1f, 15f)\n            horizontalLineToRelative(1.8f)\n            curveToRelative(0.15f, 0f, 0.279f, -0.063f, 0.387f, -0.188f)\n            reflectiveCurveToRelative(0.146f, -0.262f, 0.112f, -0.412f)\n            lineToRelative(-0.475f, -2.625f)\n            curveToRelative(0.333f, -0.167f, 0.596f, -0.408f, 0.788f, -0.725f)\n            curveToRelative(0.192f, -0.317f, 0.287f, -0.667f, 0.287f, -1.05f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.863f, -0.587f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.413f, 0.587f)\n            reflectiveCurveToRelative(-0.587f, 0.863f, -0.587f, 1.413f)\n            curveToRelative(0f, 0.383f, 0.096f, 0.733f, 0.287f, 1.05f)\n            curveToRelative(0.192f, 0.317f, 0.454f, 0.558f, 0.788f, 0.725f)\n            lineToRelative(-0.475f, 2.625f)\n            curveToRelative(-0.033f, 0.15f, 0.004f, 0.287f, 0.112f, 0.412f)\n            reflectiveCurveToRelative(0.237f, 0.188f, 0.387f, 0.188f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.638f, 5.25f)\n            curveToRelative(-0.242f, -0.333f, -0.554f, -0.575f, -0.938f, -0.725f)\n            lineToRelative(-6f, -2.25f)\n            curveToRelative(-0.233f, -0.083f, -0.467f, -0.125f, -0.7f, -0.125f)\n            reflectiveCurveToRelative(-0.467f, 0.042f, -0.7f, 0.125f)\n            lineToRelative(-6f, 2.25f)\n            curveToRelative(-0.383f, 0.15f, -0.696f, 0.392f, -0.938f, 0.725f)\n            curveToRelative(-0.242f, 0.333f, -0.362f, 0.708f, -0.362f, 1.125f)\n            verticalLineToRelative(4.725f)\n            curveToRelative(0f, 2.333f, 0.667f, 4.513f, 2f, 6.538f)\n            curveToRelative(1.333f, 2.025f, 3.125f, 3.412f, 5.375f, 4.162f)\n            curveToRelative(0.1f, 0.033f, 0.2f, 0.058f, 0.3f, 0.075f)\n            curveToRelative(0.1f, 0.017f, 0.208f, 0.025f, 0.325f, 0.025f)\n            reflectiveCurveToRelative(0.225f, -0.008f, 0.325f, -0.025f)\n            curveToRelative(0.1f, -0.017f, 0.2f, -0.042f, 0.3f, -0.075f)\n            curveToRelative(2.25f, -0.75f, 4.042f, -2.138f, 5.375f, -4.162f)\n            curveToRelative(1.333f, -2.025f, 2f, -4.204f, 2f, -6.538f)\n            verticalLineToRelative(-4.725f)\n            curveToRelative(0f, -0.417f, -0.121f, -0.792f, -0.362f, -1.125f)\n            close()\n            moveTo(18f, 11.1f)\n            curveToRelative(0f, 2.017f, -0.567f, 3.85f, -1.7f, 5.5f)\n            curveToRelative(-1.133f, 1.65f, -2.567f, 2.75f, -4.3f, 3.3f)\n            curveToRelative(-1.733f, -0.55f, -3.167f, -1.65f, -4.3f, -3.3f)\n            curveToRelative(-1.133f, -1.65f, -1.7f, -3.483f, -1.7f, -5.5f)\n            verticalLineToRelative(-4.725f)\n            lineToRelative(6f, -2.25f)\n            lineToRelative(6f, 2.25f)\n            verticalLineToRelative(4.725f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Encrypted: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Encrypted\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.1f, 15f)\n            horizontalLineToRelative(1.8f)\n            curveToRelative(0.15f, 0f, 0.279f, -0.063f, 0.387f, -0.188f)\n            reflectiveCurveToRelative(0.146f, -0.262f, 0.112f, -0.412f)\n            lineToRelative(-0.475f, -2.625f)\n            curveToRelative(0.333f, -0.167f, 0.596f, -0.408f, 0.788f, -0.725f)\n            curveToRelative(0.192f, -0.317f, 0.287f, -0.667f, 0.287f, -1.05f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.863f, -0.587f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.413f, 0.587f)\n            reflectiveCurveToRelative(-0.587f, 0.863f, -0.587f, 1.413f)\n            curveToRelative(0f, 0.383f, 0.096f, 0.733f, 0.287f, 1.05f)\n            curveToRelative(0.192f, 0.317f, 0.454f, 0.558f, 0.788f, 0.725f)\n            lineToRelative(-0.475f, 2.625f)\n            curveToRelative(-0.033f, 0.15f, 0.004f, 0.287f, 0.112f, 0.412f)\n            reflectiveCurveToRelative(0.237f, 0.188f, 0.387f, 0.188f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.638f, 5.25f)\n            curveToRelative(-0.242f, -0.333f, -0.554f, -0.575f, -0.938f, -0.725f)\n            lineToRelative(-6f, -2.25f)\n            curveToRelative(-0.233f, -0.083f, -0.467f, -0.125f, -0.7f, -0.125f)\n            reflectiveCurveToRelative(-0.467f, 0.042f, -0.7f, 0.125f)\n            lineToRelative(-6f, 2.25f)\n            curveToRelative(-0.383f, 0.15f, -0.696f, 0.392f, -0.938f, 0.725f)\n            curveToRelative(-0.242f, 0.333f, -0.362f, 0.708f, -0.362f, 1.125f)\n            verticalLineToRelative(4.725f)\n            curveToRelative(0f, 2.333f, 0.667f, 4.513f, 2f, 6.538f)\n            curveToRelative(1.333f, 2.025f, 3.125f, 3.412f, 5.375f, 4.162f)\n            curveToRelative(0.1f, 0.033f, 0.2f, 0.058f, 0.3f, 0.075f)\n            curveToRelative(0.1f, 0.017f, 0.208f, 0.025f, 0.325f, 0.025f)\n            reflectiveCurveToRelative(0.225f, -0.008f, 0.325f, -0.025f)\n            curveToRelative(0.1f, -0.017f, 0.2f, -0.042f, 0.3f, -0.075f)\n            curveToRelative(2.25f, -0.75f, 4.042f, -2.138f, 5.375f, -4.162f)\n            curveToRelative(1.333f, -2.025f, 2f, -4.204f, 2f, -6.538f)\n            verticalLineToRelative(-4.725f)\n            curveToRelative(0f, -0.417f, -0.121f, -0.792f, -0.362f, -1.125f)\n            close()\n            moveTo(18f, 11.1f)\n            curveToRelative(0f, 2.017f, -0.567f, 3.85f, -1.7f, 5.5f)\n            curveToRelative(-1.133f, 1.65f, -2.567f, 2.75f, -4.3f, 3.3f)\n            curveToRelative(-1.733f, -0.55f, -3.167f, -1.65f, -4.3f, -3.3f)\n            curveToRelative(-1.133f, -1.65f, -1.7f, -3.483f, -1.7f, -5.5f)\n            verticalLineToRelative(-4.725f)\n            lineToRelative(6f, -2.25f)\n            lineToRelative(6f, 2.25f)\n            verticalLineToRelative(4.725f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 19.888f)\n            curveToRelative(1.733f, -0.55f, 3.167f, -1.65f, 4.3f, -3.3f)\n            reflectiveCurveToRelative(1.7f, -3.483f, 1.7f, -5.5f)\n            verticalLineToRelative(-4.725f)\n            lineToRelative(-6f, -2.25f)\n            lineToRelative(-6f, 2.25f)\n            verticalLineToRelative(4.725f)\n            curveToRelative(0f, 2.017f, 0.567f, 3.85f, 1.7f, 5.5f)\n            reflectiveCurveToRelative(2.567f, 2.75f, 4.3f, 3.3f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Eraser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Eraser: ImageVector by lazy {\n    Builder(\n        name = \"Eraser\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.24f, 3.56f)\n            lineTo(21.19f, 8.5f)\n            curveTo(21.97f, 9.29f, 21.97f, 10.55f, 21.19f, 11.34f)\n            lineTo(12.0f, 20.53f)\n            curveTo(10.44f, 22.09f, 7.91f, 22.09f, 6.34f, 20.53f)\n            lineTo(2.81f, 17.0f)\n            curveTo(2.03f, 16.21f, 2.03f, 14.95f, 2.81f, 14.16f)\n            lineTo(13.41f, 3.56f)\n            curveTo(14.2f, 2.78f, 15.46f, 2.78f, 16.24f, 3.56f)\n            moveTo(4.22f, 15.58f)\n            lineTo(7.76f, 19.11f)\n            curveTo(8.54f, 19.9f, 9.8f, 19.9f, 10.59f, 19.11f)\n            lineTo(14.12f, 15.58f)\n            lineTo(9.17f, 10.63f)\n            lineTo(4.22f, 15.58f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Eraser: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"TwoTone.Eraser\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(4.22f, 15.58f)\n            lineToRelative(3.54f, 3.53f)\n            curveToRelative(0.78f, 0.79f, 2.04f, 0.79f, 2.83f, 0f)\n            lineToRelative(3.53f, -3.53f)\n            lineToRelative(-4.95f, -4.95f)\n            lineToRelative(-4.95f, 4.95f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(21.19f, 8.5f)\n            lineToRelative(-4.95f, -4.94f)\n            curveToRelative(-0.78f, -0.78f, -2.04f, -0.78f, -2.83f, 0f)\n            lineTo(2.81f, 14.16f)\n            curveToRelative(-0.78f, 0.79f, -0.78f, 2.05f, 0f, 2.84f)\n            lineToRelative(3.53f, 3.53f)\n            curveToRelative(1.57f, 1.56f, 4.1f, 1.56f, 5.66f, 0f)\n            lineToRelative(9.19f, -9.19f)\n            curveToRelative(0.78f, -0.79f, 0.78f, -2.05f, 0f, -2.84f)\n            close()\n            moveTo(10.59f, 19.11f)\n            curveToRelative(-0.79f, 0.79f, -2.05f, 0.79f, -2.83f, 0f)\n            lineToRelative(-3.54f, -3.53f)\n            lineToRelative(4.95f, -4.95f)\n            lineToRelative(4.95f, 4.95f)\n            lineToRelative(-3.53f, 3.53f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Exercise.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Exercise: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Exercise\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(826f, 375f)\n            lineTo(770f, 319f)\n            lineTo(800f, 288f)\n            quadTo(800f, 288f, 800f, 288f)\n            quadTo(800f, 288f, 800f, 288f)\n            lineTo(672f, 160f)\n            quadTo(672f, 160f, 672f, 160f)\n            quadTo(672f, 160f, 672f, 160f)\n            lineTo(641f, 190f)\n            lineTo(584f, 133f)\n            lineTo(614f, 102f)\n            quadTo(637f, 79f, 671f, 79.5f)\n            quadTo(705f, 80f, 728f, 103f)\n            lineTo(857f, 232f)\n            quadTo(880f, 255f, 880f, 288.5f)\n            quadTo(880f, 322f, 857f, 345f)\n            lineTo(826f, 375f)\n            close()\n            moveTo(346f, 856f)\n            quadTo(323f, 879f, 289.5f, 879f)\n            quadTo(256f, 879f, 233f, 856f)\n            lineTo(104f, 727f)\n            quadTo(81f, 704f, 81f, 670.5f)\n            quadTo(81f, 637f, 104f, 614f)\n            lineTo(134f, 584f)\n            lineTo(191f, 641f)\n            lineTo(160f, 671f)\n            quadTo(160f, 671f, 160f, 671f)\n            quadTo(160f, 671f, 160f, 671f)\n            lineTo(289f, 800f)\n            quadTo(289f, 800f, 289f, 800f)\n            quadTo(289f, 800f, 289f, 800f)\n            lineTo(319f, 769f)\n            lineTo(376f, 826f)\n            lineTo(346f, 856f)\n            close()\n            moveTo(743f, 520f)\n            lineTo(800f, 463f)\n            quadTo(800f, 463f, 800f, 463f)\n            quadTo(800f, 463f, 800f, 463f)\n            lineTo(497f, 160f)\n            quadTo(497f, 160f, 497f, 160f)\n            quadTo(497f, 160f, 497f, 160f)\n            lineTo(440f, 217f)\n            quadTo(440f, 217f, 440f, 217f)\n            quadTo(440f, 217f, 440f, 217f)\n            lineTo(743f, 520f)\n            quadTo(743f, 520f, 743f, 520f)\n            quadTo(743f, 520f, 743f, 520f)\n            close()\n            moveTo(463f, 800f)\n            lineTo(520f, 742f)\n            quadTo(520f, 742f, 520f, 742f)\n            quadTo(520f, 742f, 520f, 742f)\n            lineTo(218f, 440f)\n            quadTo(218f, 440f, 218f, 440f)\n            quadTo(218f, 440f, 218f, 440f)\n            lineTo(160f, 497f)\n            quadTo(160f, 497f, 160f, 497f)\n            quadTo(160f, 497f, 160f, 497f)\n            lineTo(463f, 800f)\n            quadTo(463f, 800f, 463f, 800f)\n            quadTo(463f, 800f, 463f, 800f)\n            close()\n            moveTo(457f, 566f)\n            lineTo(567f, 457f)\n            lineTo(503f, 393f)\n            lineTo(394f, 503f)\n            lineTo(457f, 566f)\n            close()\n            moveTo(520f, 856f)\n            quadTo(497f, 879f, 463f, 879f)\n            quadTo(429f, 879f, 406f, 856f)\n            lineTo(104f, 554f)\n            quadTo(81f, 531f, 81f, 497f)\n            quadTo(81f, 463f, 104f, 440f)\n            lineTo(161f, 383f)\n            quadTo(184f, 360f, 217.5f, 360f)\n            quadTo(251f, 360f, 274f, 383f)\n            lineTo(337f, 446f)\n            lineTo(447f, 336f)\n            lineTo(384f, 274f)\n            quadTo(361f, 251f, 361f, 217f)\n            quadTo(361f, 183f, 384f, 160f)\n            lineTo(441f, 103f)\n            quadTo(464f, 80f, 497.5f, 80f)\n            quadTo(531f, 80f, 554f, 103f)\n            lineTo(857f, 406f)\n            quadTo(880f, 429f, 880f, 462.5f)\n            quadTo(880f, 496f, 857f, 519f)\n            lineTo(800f, 576f)\n            quadTo(777f, 599f, 743f, 599f)\n            quadTo(709f, 599f, 686f, 576f)\n            lineTo(624f, 513f)\n            lineTo(514f, 623f)\n            lineTo(577f, 686f)\n            quadTo(600f, 709f, 600f, 742.5f)\n            quadTo(600f, 776f, 577f, 799f)\n            lineTo(520f, 856f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Exif.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Exif: ImageVector by lazy {\n    Builder(\n        name = \"Exif\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(22.37f, 11.58f)\n            lineToRelative(-9.45f, -9.45f)\n            curveTo(12.5f, 1.71f, 11.975f, 1.5f, 11.45f, 1.5f)\n            horizontalLineTo(4.1f)\n            curveTo(2.945f, 1.5f, 2.0f, 2.445f, 2.0f, 3.6f)\n            verticalLineToRelative(7.35f)\n            curveTo(2.0f, 11.475f, 2.21f, 12.0f, 2.63f, 12.42f)\n            lineToRelative(9.45f, 9.45f)\n            curveTo(12.5f, 22.29f, 13.025f, 22.5f, 13.55f, 22.5f)\n            curveToRelative(0.525f, 0.0f, 1.05f, -0.21f, 1.47f, -0.63f)\n            lineToRelative(7.35f, -7.35f)\n            curveTo(22.79f, 14.1f, 23.0f, 13.575f, 23.0f, 13.05f)\n            curveTo(23.0f, 12.525f, 22.79f, 12.0f, 22.37f, 11.58f)\n            close()\n            moveTo(13.55f, 20.4f)\n            lineToRelative(-9.45f, -9.45f)\n            verticalLineTo(3.6f)\n            horizontalLineToRelative(7.35f)\n            lineToRelative(9.45f, 9.45f)\n            lineTo(13.55f, 20.4f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.4701f, 4.65f)\n            curveToRelative(0.704f, 0.0f, 1.3201f, 0.616f, 1.3201f, 1.3201f)\n            reflectiveCurveTo(7.1741f, 7.2901f, 6.4701f, 7.2901f)\n            reflectiveCurveTo(5.15f, 6.6741f, 5.15f, 5.9701f)\n            reflectiveCurveTo(5.766f, 4.65f, 6.4701f, 4.65f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.233f, 14.8042f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(3.0977f, -3.0977f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(-3.0977f, 3.0977f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.8796f, 14.8042f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(-0.5163f, 0.5163f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(-0.7744f, 0.7744f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(-1.0326f, 1.0326f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(3.0977f, -3.0977f)\n            lineToRelative(1.5489f, 1.5489f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(10.231f, 8.1556f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(0.7744f, -0.7744f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(-1.2159f, 1.2159f)\n            lineToRelative(-0.666f, 0.666f)\n            lineToRelative(-1.2159f, 1.2159f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(0.7744f, -0.7744f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(0.2581f, -0.2581f)\n            lineToRelative(0.1833f, -0.1833f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(0.666f, -0.666f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(0.1833f, -0.1833f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.2426f, 8.5991f)\n            lineToRelative(-0.9351f, 2.1819f)\n            lineToRelative(-2.1819f, 0.9351f)\n            lineToRelative(0.6234f, 0.6234f)\n            lineToRelative(1.0909f, -0.4675f)\n            lineToRelative(-0.4675f, 1.0909f)\n            lineToRelative(0.6234f, 0.6234f)\n            lineToRelative(0.9351f, -2.1819f)\n            lineToRelative(2.1819f, -0.9351f)\n            lineToRelative(-0.6234f, -0.6234f)\n            lineToRelative(-1.0909f, 0.4675f)\n            lineToRelative(0.4675f, -1.0909f)\n            lineTo(12.2426f, 8.5991f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Exif: ImageVector by lazy {\n    Builder(\n        name = \"Exif Rounded\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(22.3701f, 11.58f)\n            lineToRelative(-9.45f, -9.45f)\n            curveTo(12.5f, 1.71f, 11.975f, 1.5f, 11.45f, 1.5f)\n            horizontalLineTo(4.1f)\n            curveTo(2.945f, 1.5f, 2.0f, 2.445f, 2.0f, 3.6f)\n            verticalLineToRelative(7.35f)\n            curveTo(2.0f, 11.475f, 2.21f, 12.0f, 2.63f, 12.42f)\n            lineToRelative(9.45f, 9.45f)\n            curveTo(12.5f, 22.29f, 13.025f, 22.5f, 13.55f, 22.5f)\n            curveToRelative(0.525f, 0.0f, 1.05f, -0.21f, 1.47f, -0.63f)\n            lineToRelative(7.35f, -7.35f)\n            curveTo(22.79f, 14.1f, 23.0f, 13.575f, 23.0f, 13.05f)\n            curveTo(23.0f, 12.525f, 22.79f, 12.0f, 22.3701f, 11.58f)\n            close()\n            moveTo(5.15f, 5.9701f)\n            curveToRelative(0.0f, -0.704f, 0.616f, -1.3201f, 1.3201f, -1.3201f)\n            curveToRelative(0.704f, 0.0f, 1.3201f, 0.616f, 1.3201f, 1.3201f)\n            curveToRelative(0.0f, 0.704f, -0.6161f, 1.3201f, -1.3201f, 1.3201f)\n            curveTo(5.7661f, 7.2902f, 5.15f, 6.6741f, 5.15f, 5.9701f)\n            close()\n            moveTo(7.9077f, 10.4789f)\n            lineTo(7.1332f, 9.7044f)\n            lineToRelative(1.2159f, -1.2159f)\n            lineToRelative(0.666f, -0.666f)\n            lineToRelative(1.2159f, -1.2159f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(0.7745f, 0.7745f)\n            lineToRelative(-0.7745f, 0.7744f)\n            lineTo(10.231f, 8.1556f)\n            lineTo(9.9728f, 8.4137f)\n            lineTo(9.7895f, 8.597f)\n            lineTo(10.564f, 9.3715f)\n            lineToRelative(-0.666f, 0.666f)\n            lineTo(9.1235f, 9.263f)\n            lineTo(8.9402f, 9.4463f)\n            lineTo(8.6821f, 9.7044f)\n            lineToRelative(0.7745f, 0.7745f)\n            lineToRelative(-0.7745f, 0.7744f)\n            lineTo(7.9077f, 10.4789f)\n            close()\n            moveTo(10.3724f, 12.9628f)\n            lineToRelative(0.4676f, -1.0909f)\n            lineToRelative(-1.0909f, 0.4675f)\n            lineToRelative(-0.6234f, -0.6234f)\n            lineToRelative(2.1819f, -0.9351f)\n            lineToRelative(0.9351f, -2.1819f)\n            lineToRelative(0.6234f, 0.6234f)\n            lineToRelative(-0.4675f, 1.0909f)\n            lineToRelative(1.0909f, -0.4675f)\n            lineToRelative(0.6234f, 0.6234f)\n            lineToRelative(-2.1819f, 0.9351f)\n            lineToRelative(-0.9351f, 2.1819f)\n            lineTo(10.3724f, 12.9628f)\n            close()\n            moveTo(11.4585f, 14.0297f)\n            lineToRelative(3.0978f, -3.0977f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(-3.0977f, 3.0977f)\n            lineTo(11.4585f, 14.0297f)\n            close()\n            moveTo(16.8796f, 14.8041f)\n            lineToRelative(-0.7744f, -0.7744f)\n            lineToRelative(-0.5163f, 0.5163f)\n            lineToRelative(0.7744f, 0.7744f)\n            lineToRelative(-0.7744f, 0.7745f)\n            lineToRelative(-0.7745f, -0.7745f)\n            lineToRelative(-1.0325f, 1.0326f)\n            lineToRelative(-0.7745f, -0.7744f)\n            lineToRelative(3.0978f, -3.0978f)\n            lineToRelative(1.5488f, 1.5489f)\n            lineTo(16.8796f, 14.8041f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Exif: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"TwoTone.Exif\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(22.37f, 11.58f)\n            lineTo(12.92f, 2.13f)\n            curveToRelative(-0.42f, -0.42f, -0.945f, -0.63f, -1.47f, -0.63f)\n            horizontalLineToRelative(-7.35f)\n            curveToRelative(-1.155f, 0f, -2.1f, 0.945f, -2.1f, 2.1f)\n            verticalLineToRelative(7.35f)\n            curveToRelative(0f, 0.525f, 0.21f, 1.05f, 0.63f, 1.47f)\n            lineToRelative(9.45f, 9.45f)\n            curveToRelative(0.42f, 0.42f, 0.945f, 0.63f, 1.47f, 0.63f)\n            curveToRelative(0.525f, 0f, 1.05f, -0.21f, 1.47f, -0.63f)\n            lineToRelative(7.35f, -7.35f)\n            curveToRelative(0.42f, -0.42f, 0.63f, -0.945f, 0.63f, -1.47f)\n            reflectiveCurveToRelative(-0.21f, -1.05f, -0.63f, -1.47f)\n            close()\n            moveTo(13.55f, 20.4f)\n            lineTo(4.1f, 10.95f)\n            verticalLineTo(3.6f)\n            horizontalLineToRelative(7.35f)\n            lineToRelative(9.45f, 9.45f)\n            lineToRelative(-7.35f, 7.35f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(13.55f, 20.4f)\n            lineToRelative(-9.45f, -9.45f)\n            lineToRelative(0f, -7.35f)\n            lineToRelative(7.35f, 0f)\n            lineToRelative(9.45f, 9.45f)\n            lineToRelative(-7.35f, 7.35f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(6.47f, 4.65f)\n            curveToRelative(0.704f, 0f, 1.32f, 0.616f, 1.32f, 1.32f)\n            reflectiveCurveToRelative(-0.616f, 1.32f, -1.32f, 1.32f)\n            reflectiveCurveToRelative(-1.32f, -0.616f, -1.32f, -1.32f)\n            reflectiveCurveToRelative(0.616f, -1.32f, 1.32f, -1.32f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12.233f, 14.804f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(3.098f, -3.098f)\n            lineToRelative(0.774f, 0.774f)\n            lineToRelative(-3.098f, 3.098f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(16.88f, 14.804f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(-0.516f, 0.516f)\n            lineToRelative(0.774f, 0.774f)\n            lineToRelative(-0.774f, 0.774f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(-1.033f, 1.033f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(3.098f, -3.098f)\n            lineToRelative(1.549f, 1.549f)\n            lineToRelative(-0.775f, 0.774f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(10.231f, 8.156f)\n            lineToRelative(0.774f, 0.774f)\n            lineToRelative(0.774f, -0.774f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(-1.216f, 1.216f)\n            lineToRelative(-0.666f, 0.666f)\n            lineToRelative(-1.216f, 1.216f)\n            lineToRelative(0.774f, 0.774f)\n            lineToRelative(0.774f, 0.774f)\n            lineToRelative(0.774f, -0.774f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(0.258f, -0.258f)\n            lineToRelative(0.183f, -0.183f)\n            lineToRelative(0.774f, 0.774f)\n            lineToRelative(0.666f, -0.666f)\n            lineToRelative(-0.774f, -0.774f)\n            lineToRelative(0.183f, -0.183f)\n            lineToRelative(0.258f, -0.258f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12.243f, 8.599f)\n            lineToRelative(-0.935f, 2.182f)\n            lineToRelative(-2.182f, 0.935f)\n            lineToRelative(0.623f, 0.623f)\n            lineToRelative(1.091f, -0.467f)\n            lineToRelative(-0.467f, 1.091f)\n            lineToRelative(0.623f, 0.623f)\n            lineToRelative(0.935f, -2.182f)\n            lineToRelative(2.182f, -0.935f)\n            lineToRelative(-0.623f, -0.623f)\n            lineToRelative(-1.091f, 0.467f)\n            lineToRelative(0.467f, -1.091f)\n            lineToRelative(-0.623f, -0.623f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ExifEdit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ExifEdit: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.ExifEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(17.138f, 9.874f)\n            lineToRelative(-7.023f, -7.023f)\n            curveTo(9.803f, 2.539f, 9.413f, 2.383f, 9.023f, 2.383f)\n            horizontalLineTo(3.561f)\n            curveTo(2.702f, 2.383f, 2f, 3.085f, 2f, 3.944f)\n            verticalLineToRelative(5.462f)\n            curveToRelative(0f, 0.39f, 0.156f, 0.78f, 0.468f, 1.092f)\n            lineToRelative(7.023f, 7.023f)\n            curveToRelative(0.312f, 0.312f, 0.702f, 0.468f, 1.092f, 0.468f)\n            reflectiveCurveToRelative(0.78f, -0.156f, 1.092f, -0.468f)\n            lineToRelative(5.462f, -5.462f)\n            curveToRelative(0.312f, -0.312f, 0.468f, -0.702f, 0.468f, -1.092f)\n            curveTo(17.606f, 10.576f, 17.45f, 10.186f, 17.138f, 9.874f)\n            close()\n            moveTo(10.584f, 16.429f)\n            lineToRelative(-7.023f, -7.023f)\n            verticalLineTo(3.944f)\n            horizontalLineTo(9.023f)\n            lineToRelative(7.023f, 7.023f)\n            lineTo(10.584f, 16.429f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(5.322f, 4.724f)\n            curveToRelative(0.523f, 0f, 0.981f, 0.458f, 0.981f, 0.981f)\n            reflectiveCurveTo(5.845f, 6.686f, 5.322f, 6.686f)\n            reflectiveCurveTo(4.341f, 6.228f, 4.341f, 5.705f)\n            reflectiveCurveTo(4.799f, 4.724f, 5.322f, 4.724f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9.605f, 12.27f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(2.302f, -2.302f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(-2.302f, 2.302f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13.058f, 12.27f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.384f, 0.384f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(-0.576f, 0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.767f, 0.767f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(2.302f, -2.302f)\n            lineToRelative(1.151f, 1.151f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(8.117f, 7.329f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.576f, -0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.904f, 0.904f)\n            lineToRelative(-0.495f, 0.495f)\n            lineToRelative(-0.904f, 0.904f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.576f, -0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(0.192f, -0.192f)\n            lineToRelative(0.136f, -0.136f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.495f, -0.495f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(0.136f, -0.136f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9.612f, 7.659f)\n            lineTo(8.917f, 9.28f)\n            lineTo(7.295f, 9.975f)\n            lineToRelative(0.463f, 0.463f)\n            lineToRelative(0.811f, -0.347f)\n            lineToRelative(-0.347f, 0.811f)\n            lineToRelative(0.463f, 0.463f)\n            lineToRelative(0.695f, -1.621f)\n            lineToRelative(1.621f, -0.695f)\n            lineToRelative(-0.463f, -0.463f)\n            lineTo(9.728f, 8.933f)\n            lineToRelative(0.347f, -0.811f)\n            lineTo(9.612f, 7.659f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(21.886f, 14.399f)\n            curveToRelative(-0.076f, -0.186f, -0.182f, -0.355f, -0.317f, -0.507f)\n            lineToRelative(-0.937f, -0.937f)\n            curveToRelative(-0.152f, -0.152f, -0.321f, -0.266f, -0.507f, -0.342f)\n            curveTo(19.94f, 12.538f, 19.746f, 12.5f, 19.543f, 12.5f)\n            curveToRelative(-0.186f, 0f, -0.371f, 0.034f, -0.557f, 0.101f)\n            curveToRelative(-0.186f, 0.068f, -0.355f, 0.177f, -0.507f, 0.329f)\n            lineToRelative(-5.293f, 5.268f)\n            curveToRelative(-0.101f, 0.101f, -0.177f, 0.215f, -0.228f, 0.342f)\n            reflectiveCurveToRelative(-0.076f, 0.258f, -0.076f, 0.393f)\n            verticalLineToRelative(1.671f)\n            curveToRelative(0f, 0.287f, 0.097f, 0.528f, 0.291f, 0.722f)\n            curveToRelative(0.194f, 0.194f, 0.435f, 0.291f, 0.722f, 0.291f)\n            horizontalLineToRelative(1.671f)\n            curveToRelative(0.135f, 0f, 0.266f, -0.025f, 0.392f, -0.076f)\n            curveToRelative(0.127f, -0.051f, 0.241f, -0.127f, 0.342f, -0.228f)\n            lineToRelative(5.268f, -5.268f)\n            curveToRelative(0.152f, -0.152f, 0.262f, -0.325f, 0.329f, -0.519f)\n            curveTo(21.966f, 15.332f, 22f, 15.142f, 22f, 14.957f)\n            reflectiveCurveTo(21.962f, 14.585f, 21.886f, 14.399f)\n            close()\n            moveTo(15.365f, 20.098f)\n            horizontalLineTo(14.402f)\n            verticalLineToRelative(-0.962f)\n            lineToRelative(3.09f, -3.064f)\n            lineToRelative(0.481f, 0.456f)\n            lineToRelative(0.456f, 0.481f)\n            lineTo(15.365f, 20.098f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ExifEdit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ExifEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(10.584f, 16.429f)\n            lineToRelative(-7.023f, -7.023f)\n            lineToRelative(0f, -5.462f)\n            lineToRelative(5.462f, 0f)\n            lineToRelative(7.023f, 7.023f)\n            lineToRelative(-5.462f, 5.462f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(5.322f, 4.724f)\n            curveToRelative(0.523f, 0f, 0.981f, 0.458f, 0.981f, 0.981f)\n            reflectiveCurveToRelative(-0.458f, 0.981f, -0.981f, 0.981f)\n            reflectiveCurveToRelative(-0.981f, -0.458f, -0.981f, -0.981f)\n            reflectiveCurveToRelative(0.458f, -0.981f, 0.981f, -0.981f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9.605f, 12.27f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(2.302f, -2.302f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(-2.302f, 2.302f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13.058f, 12.27f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.384f, 0.384f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(-0.576f, 0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.767f, 0.767f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(2.302f, -2.302f)\n            lineToRelative(1.151f, 1.151f)\n            lineToRelative(-0.574f, 0.576f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(8.117f, 7.329f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.576f, -0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(-0.904f, 0.904f)\n            lineToRelative(-0.495f, 0.495f)\n            lineToRelative(-0.904f, 0.904f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.576f, -0.576f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(0.192f, -0.192f)\n            lineToRelative(0.136f, -0.136f)\n            lineToRelative(0.576f, 0.576f)\n            lineToRelative(0.495f, -0.495f)\n            lineToRelative(-0.576f, -0.576f)\n            lineToRelative(0.136f, -0.136f)\n            lineToRelative(0.192f, -0.192f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9.612f, 7.659f)\n            lineToRelative(-0.695f, 1.621f)\n            lineToRelative(-1.622f, 0.695f)\n            lineToRelative(0.463f, 0.463f)\n            lineToRelative(0.811f, -0.347f)\n            lineToRelative(-0.347f, 0.811f)\n            lineToRelative(0.463f, 0.463f)\n            lineToRelative(0.695f, -1.621f)\n            lineToRelative(1.621f, -0.695f)\n            lineToRelative(-0.463f, -0.463f)\n            lineToRelative(-0.81f, 0.347f)\n            lineToRelative(0.347f, -0.811f)\n            lineToRelative(-0.463f, -0.463f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(15.365f, 20.098f)\n            lineToRelative(-0.963f, 0f)\n            lineToRelative(0f, -0.962f)\n            lineToRelative(3.09f, -3.064f)\n            lineToRelative(0.481f, 0.456f)\n            lineToRelative(0.456f, 0.481f)\n            lineToRelative(-3.064f, 3.089f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(21.886f, 14.399f)\n            curveToRelative(-0.076f, -0.186f, -0.182f, -0.355f, -0.317f, -0.507f)\n            lineToRelative(-0.937f, -0.937f)\n            curveToRelative(-0.152f, -0.152f, -0.321f, -0.266f, -0.507f, -0.342f)\n            curveToRelative(-0.185f, -0.075f, -0.379f, -0.113f, -0.582f, -0.113f)\n            curveToRelative(-0.186f, 0f, -0.371f, 0.034f, -0.557f, 0.101f)\n            curveToRelative(-0.186f, 0.068f, -0.355f, 0.177f, -0.507f, 0.329f)\n            lineToRelative(-5.293f, 5.268f)\n            curveToRelative(-0.101f, 0.101f, -0.177f, 0.215f, -0.228f, 0.342f)\n            curveToRelative(-0.051f, 0.127f, -0.076f, 0.258f, -0.076f, 0.393f)\n            verticalLineToRelative(1.671f)\n            curveToRelative(0f, 0.287f, 0.097f, 0.528f, 0.291f, 0.722f)\n            curveToRelative(0.194f, 0.194f, 0.435f, 0.291f, 0.722f, 0.291f)\n            horizontalLineToRelative(1.671f)\n            curveToRelative(0.135f, 0f, 0.266f, -0.025f, 0.392f, -0.076f)\n            curveToRelative(0.127f, -0.051f, 0.241f, -0.127f, 0.342f, -0.228f)\n            lineToRelative(5.268f, -5.268f)\n            curveToRelative(0.152f, -0.152f, 0.262f, -0.325f, 0.329f, -0.519f)\n            curveToRelative(0.069f, -0.194f, 0.103f, -0.384f, 0.103f, -0.569f)\n            reflectiveCurveToRelative(-0.038f, -0.372f, -0.114f, -0.558f)\n            close()\n            moveTo(15.365f, 20.098f)\n            horizontalLineToRelative(-0.963f)\n            verticalLineToRelative(-0.962f)\n            lineToRelative(3.09f, -3.064f)\n            lineToRelative(0.481f, 0.456f)\n            lineToRelative(0.456f, 0.481f)\n            lineToRelative(-3.064f, 3.089f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(17.138f, 9.874f)\n            lineToRelative(-7.023f, -7.023f)\n            curveToRelative(-0.312f, -0.312f, -0.702f, -0.468f, -1.092f, -0.468f)\n            horizontalLineTo(3.561f)\n            curveToRelative(-0.859f, 0f, -1.561f, 0.702f, -1.561f, 1.561f)\n            verticalLineToRelative(5.462f)\n            curveToRelative(0f, 0.39f, 0.156f, 0.78f, 0.468f, 1.092f)\n            lineToRelative(7.023f, 7.023f)\n            curveToRelative(0.312f, 0.312f, 0.702f, 0.468f, 1.092f, 0.468f)\n            reflectiveCurveToRelative(0.78f, -0.156f, 1.092f, -0.468f)\n            lineToRelative(5.462f, -5.462f)\n            curveToRelative(0.312f, -0.312f, 0.468f, -0.702f, 0.468f, -1.092f)\n            curveToRelative(0.001f, -0.391f, -0.155f, -0.781f, -0.467f, -1.093f)\n            close()\n            moveTo(10.584f, 16.429f)\n            lineToRelative(-7.023f, -7.023f)\n            verticalLineTo(3.944f)\n            horizontalLineToRelative(5.462f)\n            lineToRelative(7.023f, 7.023f)\n            lineToRelative(-5.462f, 5.462f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Eyedropper.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Eyedropper: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Eyedropper\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19.35f, 11.72f)\n            lineTo(17.22f, 13.85f)\n            lineTo(15.81f, 12.43f)\n            lineTo(8.1f, 20.14f)\n            lineTo(3.5f, 22f)\n            lineTo(2f, 20.5f)\n            lineTo(3.86f, 15.9f)\n            lineTo(11.57f, 8.19f)\n            lineTo(10.15f, 6.78f)\n            lineTo(12.28f, 4.65f)\n            lineTo(19.35f, 11.72f)\n            moveTo(16.76f, 3f)\n            curveTo(17.93f, 1.83f, 19.83f, 1.83f, 21f, 3f)\n            curveTo(22.17f, 4.17f, 22.17f, 6.07f, 21f, 7.24f)\n            lineTo(19.08f, 9.16f)\n            lineTo(14.84f, 4.92f)\n            lineTo(16.76f, 3f)\n            moveTo(5.56f, 17.03f)\n            lineTo(4.5f, 19.5f)\n            lineTo(6.97f, 18.44f)\n            lineTo(14.4f, 11f)\n            lineTo(13f, 9.6f)\n            lineTo(5.56f, 17.03f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Eyedropper: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Eyedropper\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(16.76f, 3f)\n            curveToRelative(1.17f, -1.17f, 3.07f, -1.17f, 4.24f, 0f)\n            curveToRelative(1.17f, 1.17f, 1.17f, 3.07f, 0f, 4.24f)\n            lineToRelative(-1.92f, 1.92f)\n            lineToRelative(-4.24f, -4.24f)\n            lineToRelative(1.92f, -1.92f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5.56f, 17.03f)\n            lineToRelative(-1.06f, 2.47f)\n            lineToRelative(2.47f, -1.06f)\n            lineToRelative(7.43f, -7.44f)\n            lineToRelative(-1.4f, -1.4f)\n            lineToRelative(-7.44f, 7.43f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12.28f, 4.65f)\n            lineToRelative(-2.13f, 2.13f)\n            lineToRelative(1.42f, 1.41f)\n            lineToRelative(-7.71f, 7.71f)\n            lineToRelative(-1.86f, 4.6f)\n            lineToRelative(1.5f, 1.5f)\n            lineToRelative(4.6f, -1.86f)\n            lineToRelative(7.71f, -7.71f)\n            lineToRelative(1.41f, 1.42f)\n            lineToRelative(2.13f, -2.13f)\n            lineToRelative(-7.07f, -7.07f)\n            close()\n            moveTo(6.97f, 18.44f)\n            lineToRelative(-2.47f, 1.06f)\n            lineToRelative(1.06f, -2.47f)\n            lineToRelative(7.44f, -7.43f)\n            lineToRelative(1.4f, 1.4f)\n            lineToRelative(-7.43f, 7.44f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FabCorner.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.FabCorner: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.FabCorner\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(2f, 20f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(18f)\n            verticalLineTo(4f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(2f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10f, 8f)\n            horizontalLineToRelative(8f)\n            verticalLineToRelative(8f)\n            horizontalLineToRelative(-8f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FileExport.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FileExport: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Rounded.FileExport\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(6f, 2f)\n            curveTo(4.89f, 2f, 4f, 2.9f, 4f, 4f)\n            verticalLineTo(20f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 6f, 22f)\n            horizontalLineTo(18f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 20f, 20f)\n            verticalLineTo(8f)\n            lineTo(14f, 2f)\n            moveTo(13f, 3.5f)\n            lineTo(18.5f, 9f)\n            horizontalLineTo(13f)\n            moveTo(8.93f, 12.22f)\n            horizontalLineTo(16f)\n            verticalLineTo(19.29f)\n            lineTo(13.88f, 17.17f)\n            lineTo(11.05f, 20f)\n            lineTo(8.22f, 17.17f)\n            lineTo(11.05f, 14.35f)\n        }\n    }.build()\n}\n\nval Icons.Outlined.FileExport: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.FileExport\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(14f, 2f)\n            horizontalLineTo(6f)\n            curveTo(4.9f, 2f, 4f, 2.9f, 4f, 4f)\n            verticalLineTo(20f)\n            curveTo(4f, 21.1f, 4.9f, 22f, 6f, 22f)\n            horizontalLineTo(18f)\n            curveTo(19.1f, 22f, 20f, 21.1f, 20f, 20f)\n            verticalLineTo(8f)\n            lineTo(14f, 2f)\n            moveTo(18f, 20f)\n            horizontalLineTo(6f)\n            verticalLineTo(4f)\n            horizontalLineTo(13f)\n            verticalLineTo(9f)\n            horizontalLineTo(18f)\n            verticalLineTo(20f)\n            moveTo(16f, 11f)\n            verticalLineTo(18.1f)\n            lineTo(13.9f, 16f)\n            lineTo(11.1f, 18.8f)\n            lineTo(8.3f, 16f)\n            lineTo(11.1f, 13.2f)\n            lineTo(8.9f, 11f)\n            horizontalLineTo(16f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FileImage.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FileImage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.FileImage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13f, 9f)\n            horizontalLineTo(18.5f)\n            lineTo(13f, 3.5f)\n            verticalLineTo(9f)\n            moveTo(6f, 2f)\n            horizontalLineTo(14f)\n            lineTo(20f, 8f)\n            verticalLineTo(20f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 18f, 22f)\n            horizontalLineTo(6f)\n            curveTo(4.89f, 22f, 4f, 21.1f, 4f, 20f)\n            verticalLineTo(4f)\n            curveTo(4f, 2.89f, 4.89f, 2f, 6f, 2f)\n            moveTo(6f, 20f)\n            horizontalLineTo(15f)\n            lineTo(18f, 20f)\n            verticalLineTo(12f)\n            lineTo(14f, 16f)\n            lineTo(12f, 14f)\n            lineTo(6f, 20f)\n            moveTo(8f, 9f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 6f, 11f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 8f, 13f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 10f, 11f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 8f, 9f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.FileImage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.FileImage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14f, 2f)\n            lineTo(20f, 8f)\n            verticalLineTo(20f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 18f, 22f)\n            horizontalLineTo(6f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 4f, 20f)\n            verticalLineTo(4f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6f, 2f)\n            horizontalLineTo(14f)\n            moveTo(18f, 20f)\n            verticalLineTo(9f)\n            horizontalLineTo(13f)\n            verticalLineTo(4f)\n            horizontalLineTo(6f)\n            verticalLineTo(20f)\n            horizontalLineTo(18f)\n            moveTo(17f, 13f)\n            verticalLineTo(19f)\n            horizontalLineTo(7f)\n            lineTo(12f, 14f)\n            lineTo(14f, 16f)\n            moveTo(10f, 10.5f)\n            arcTo(1.5f, 1.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8.5f, 12f)\n            arcTo(1.5f, 1.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 7f, 10.5f)\n            arcTo(1.5f, 1.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8.5f, 9f)\n            arcTo(1.5f, 1.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 10f, 10.5f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FileImport.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FileImport: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Rounded.FileImport\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(6f, 2f)\n            curveTo(4.89f, 2f, 4f, 2.9f, 4f, 4f)\n            verticalLineTo(20f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 6f, 22f)\n            horizontalLineTo(18f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 20f, 20f)\n            verticalLineTo(8f)\n            lineTo(14f, 2f)\n            moveTo(13f, 3.5f)\n            lineTo(18.5f, 9f)\n            horizontalLineTo(13f)\n            moveTo(10.05f, 11.22f)\n            lineTo(12.88f, 14.05f)\n            lineTo(15f, 11.93f)\n            verticalLineTo(19f)\n            horizontalLineTo(7.93f)\n            lineTo(10.05f, 16.88f)\n            lineTo(7.22f, 14.05f)\n        }\n    }.build()\n}\n\nval Icons.Outlined.FileImport: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.FileImport\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(14f, 2f)\n            horizontalLineTo(6f)\n            curveTo(4.89f, 2f, 4f, 2.9f, 4f, 4f)\n            verticalLineTo(20f)\n            curveTo(4f, 21.11f, 4.89f, 22f, 6f, 22f)\n            horizontalLineTo(18f)\n            curveTo(19.11f, 22f, 20f, 21.11f, 20f, 20f)\n            verticalLineTo(8f)\n            lineTo(14f, 2f)\n            moveTo(18f, 20f)\n            horizontalLineTo(6f)\n            verticalLineTo(4f)\n            horizontalLineTo(13f)\n            verticalLineTo(9f)\n            horizontalLineTo(18f)\n            verticalLineTo(20f)\n            moveTo(15f, 11.93f)\n            verticalLineTo(19f)\n            horizontalLineTo(7.93f)\n            lineTo(10.05f, 16.88f)\n            lineTo(7.22f, 14.05f)\n            lineTo(10.05f, 11.22f)\n            lineTo(12.88f, 14.05f)\n            lineTo(15f, 11.93f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FileReplace.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.FileReplace: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"FileReplace\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(14f, 3f)\n            lineTo(12f, 1f)\n            horizontalLineTo(4f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 2f, 3f)\n            verticalLineTo(15f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = false, 4f, 17f)\n            horizontalLineTo(11f)\n            verticalLineTo(19f)\n            lineTo(15f, 16f)\n            lineTo(11f, 13f)\n            verticalLineTo(15f)\n            horizontalLineTo(4f)\n            verticalLineTo(3f)\n            horizontalLineTo(14f)\n            moveTo(21f, 10f)\n            verticalLineTo(21f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 19f, 23f)\n            horizontalLineTo(8f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6f, 21f)\n            verticalLineTo(19f)\n            horizontalLineTo(8f)\n            verticalLineTo(21f)\n            horizontalLineTo(19f)\n            verticalLineTo(12f)\n            horizontalLineTo(14f)\n            verticalLineTo(7f)\n            horizontalLineTo(8f)\n            verticalLineTo(13f)\n            horizontalLineTo(6f)\n            verticalLineTo(7f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8f, 5f)\n            horizontalLineTo(16f)\n            lineTo(21f, 10f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FindInPage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.FindInPage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.FindInPage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.75f, 20f)\n            lineToRelative(2f, 2f)\n            horizontalLineTo(6f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(4f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(9f)\n            lineToRelative(5f, 6f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.333f, -0.071f, 0.637f, -0.213f, 0.913f)\n            reflectiveCurveToRelative(-0.338f, 0.504f, -0.587f, 0.688f)\n            lineToRelative(-5.2f, -5.15f)\n            curveToRelative(-0.283f, 0.183f, -0.592f, 0.321f, -0.925f, 0.412f)\n            curveToRelative(-0.333f, 0.092f, -0.692f, 0.138f, -1.075f, 0.138f)\n            curveToRelative(-1.1f, 0f, -2.042f, -0.392f, -2.825f, -1.175f)\n            reflectiveCurveToRelative(-1.175f, -1.725f, -1.175f, -2.825f)\n            reflectiveCurveToRelative(0.392f, -2.042f, 1.175f, -2.825f)\n            reflectiveCurveToRelative(1.725f, -1.175f, 2.825f, -1.175f)\n            reflectiveCurveToRelative(2.042f, 0.392f, 2.825f, 1.175f)\n            reflectiveCurveToRelative(1.175f, 1.725f, 1.175f, 2.825f)\n            curveToRelative(0f, 0.383f, -0.046f, 0.742f, -0.138f, 1.075f)\n            reflectiveCurveToRelative(-0.229f, 0.642f, -0.412f, 0.925f)\n            lineToRelative(2.55f, 2.6f)\n            verticalLineToRelative(-8.9f)\n            lineToRelative(-3.95f, -4.7f)\n            horizontalLineTo(6f)\n            verticalLineToRelative(16f)\n            horizontalLineToRelative(8.75f)\n            close()\n            moveTo(13.413f, 14.412f)\n            curveToRelative(0.392f, -0.392f, 0.587f, -0.863f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.196f, -1.021f, -0.587f, -1.413f)\n            curveToRelative(-0.392f, -0.392f, -0.863f, -0.587f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.413f, 0.587f)\n            curveToRelative(-0.392f, 0.392f, -0.587f, 0.863f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(0.196f, 1.021f, 0.587f, 1.413f)\n            reflectiveCurveToRelative(0.863f, 0.587f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(1.021f, -0.196f, 1.413f, -0.587f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.FindInPage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.FindInPage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15f, 2f)\n            horizontalLineTo(6f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(16f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10.75f)\n            lineToRelative(-2f, -2f)\n            horizontalLineTo(6f)\n            verticalLineTo(4f)\n            horizontalLineToRelative(8.05f)\n            lineToRelative(3.95f, 4.7f)\n            verticalLineToRelative(8.9f)\n            lineToRelative(-2.55f, -2.6f)\n            curveToRelative(0.183f, -0.283f, 0.321f, -0.592f, 0.412f, -0.925f)\n            curveToRelative(0.092f, -0.333f, 0.138f, -0.692f, 0.138f, -1.075f)\n            curveToRelative(0f, -1.1f, -0.392f, -2.042f, -1.175f, -2.825f)\n            reflectiveCurveToRelative(-1.725f, -1.175f, -2.825f, -1.175f)\n            reflectiveCurveToRelative(-2.042f, 0.392f, -2.825f, 1.175f)\n            reflectiveCurveToRelative(-1.175f, 1.725f, -1.175f, 2.825f)\n            reflectiveCurveToRelative(0.392f, 2.042f, 1.175f, 2.825f)\n            reflectiveCurveToRelative(1.725f, 1.175f, 2.825f, 1.175f)\n            curveToRelative(0.383f, 0f, 0.742f, -0.046f, 1.075f, -0.138f)\n            curveToRelative(0.333f, -0.092f, 0.642f, -0.229f, 0.925f, -0.412f)\n            lineToRelative(5.2f, 5.15f)\n            curveToRelative(0.25f, -0.183f, 0.446f, -0.412f, 0.587f, -0.688f)\n            curveToRelative(0.142f, -0.275f, 0.213f, -0.579f, 0.213f, -0.912f)\n            verticalLineToRelative(-12f)\n            lineToRelative(-5f, -6f)\n            close()\n            moveTo(13.412f, 14.412f)\n            curveToRelative(-0.392f, 0.392f, -0.862f, 0.588f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-1.021f, -0.196f, -1.412f, -0.588f)\n            reflectiveCurveToRelative(-0.588f, -0.862f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(0.196f, -1.021f, 0.588f, -1.412f)\n            reflectiveCurveToRelative(0.862f, -0.588f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(1.021f, 0.196f, 1.412f, 0.588f)\n            reflectiveCurveToRelative(0.588f, 0.862f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(-0.196f, 1.021f, -0.588f, 1.412f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(18.003f, 8.623f)\n            lineToRelative(-3.88f, -4.625f)\n            horizontalLineTo(6.003f)\n            verticalLineToRelative(16f)\n            horizontalLineToRelative(12f)\n            verticalLineToRelative(-11.375f)\n            close()\n            moveTo(13.415f, 14.411f)\n            curveToRelative(-0.392f, 0.392f, -0.862f, 0.588f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-1.021f, -0.196f, -1.412f, -0.588f)\n            reflectiveCurveToRelative(-0.588f, -0.862f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(0.196f, -1.021f, 0.588f, -1.412f)\n            reflectiveCurveToRelative(0.862f, -0.588f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(1.021f, 0.196f, 1.412f, 0.588f)\n            reflectiveCurveToRelative(0.588f, 0.862f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(-0.196f, 1.021f, -0.588f, 1.412f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(18.003f, 19.999f)\n            horizontalLineToRelative(-5.186f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(5.186f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FingerprintOff.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FingerprintOff: ImageVector by lazy {\n    Builder(\n        name = \"Fingerprint Off\", defaultWidth = 24.0.dp, defaultHeight\n        = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(1.5f, 4.77f)\n            lineTo(2.78f, 3.5f)\n            lineTo(20.5f, 21.22f)\n            lineTo(19.23f, 22.5f)\n            lineTo(16.67f, 19.94f)\n            curveTo(15.58f, 19.9f, 14.62f, 19.6f, 13.82f, 19.05f)\n            curveTo(12.34f, 18.05f, 11.46f, 16.43f, 11.44f, 14.71f)\n            lineTo(10.27f, 13.53f)\n            curveTo(10.03f, 13.85f, 9.89f, 14.23f, 9.89f, 14.65f)\n            curveTo(9.89f, 16.36f, 10.55f, 17.96f, 11.76f, 19.16f)\n            curveTo(12.71f, 20.1f, 13.62f, 20.62f, 15.03f, 21.0f)\n            curveTo(15.3f, 21.08f, 15.45f, 21.36f, 15.38f, 21.62f)\n            curveTo(15.33f, 21.85f, 15.12f, 22.0f, 14.91f, 22.0f)\n            horizontalLineTo(14.78f)\n            curveTo(13.19f, 21.54f, 12.15f, 20.95f, 11.06f, 19.88f)\n            curveTo(9.66f, 18.5f, 8.89f, 16.64f, 8.89f, 14.66f)\n            curveTo(8.89f, 13.97f, 9.14f, 13.33f, 9.56f, 12.83f)\n            lineTo(8.5f, 11.77f)\n            curveTo(7.78f, 12.54f, 7.34f, 13.55f, 7.34f, 14.66f)\n            curveTo(7.34f, 16.1f, 7.66f, 17.43f, 8.27f, 18.5f)\n            curveTo(8.91f, 19.66f, 9.35f, 20.15f, 10.12f, 20.93f)\n            curveTo(10.31f, 21.13f, 10.31f, 21.44f, 10.12f, 21.64f)\n            curveTo(10.0f, 21.74f, 9.88f, 21.79f, 9.75f, 21.79f)\n            curveTo(9.62f, 21.79f, 9.5f, 21.74f, 9.4f, 21.64f)\n            curveTo(8.53f, 20.77f, 8.06f, 20.21f, 7.39f, 19.0f)\n            curveTo(6.7f, 17.77f, 6.34f, 16.27f, 6.34f, 14.66f)\n            curveTo(6.34f, 13.28f, 6.89f, 12.0f, 7.79f, 11.06f)\n            lineTo(6.7f, 9.97f)\n            curveTo(6.15f, 10.5f, 5.69f, 11.15f, 5.35f, 11.86f)\n            curveTo(4.96f, 12.67f, 4.76f, 13.62f, 4.76f, 14.66f)\n            curveTo(4.76f, 15.44f, 4.83f, 16.67f, 5.43f, 18.27f)\n            curveTo(5.53f, 18.53f, 5.4f, 18.82f, 5.14f, 18.91f)\n            curveTo(4.88f, 19.0f, 4.59f, 18.87f, 4.5f, 18.62f)\n            curveTo(4.0f, 17.31f, 3.77f, 16.0f, 3.77f, 14.66f)\n            curveTo(3.77f, 13.46f, 4.0f, 12.37f, 4.45f, 11.42f)\n            curveTo(4.84f, 10.61f, 5.36f, 9.88f, 6.0f, 9.26f)\n            lineTo(4.97f, 8.24f)\n            curveTo(4.58f, 8.63f, 4.22f, 9.05f, 3.89f, 9.5f)\n            curveTo(3.81f, 9.65f, 3.66f, 9.72f, 3.5f, 9.72f)\n            lineTo(3.21f, 9.63f)\n            curveTo(3.0f, 9.47f, 2.93f, 9.16f, 3.09f, 8.93f)\n            curveTo(3.45f, 8.43f, 3.84f, 7.96f, 4.27f, 7.53f)\n            lineTo(1.5f, 4.77f)\n            moveTo(17.81f, 4.47f)\n            lineTo(17.58f, 4.41f)\n            curveTo(15.66f, 3.42f, 14.0f, 3.0f, 12.0f, 3.0f)\n            curveTo(10.03f, 3.0f, 8.15f, 3.47f, 6.44f, 4.41f)\n            lineTo(6.29f, 4.46f)\n            lineTo(5.71f, 3.89f)\n            curveTo(5.73f, 3.74f, 5.82f, 3.61f, 5.96f, 3.53f)\n            curveTo(7.82f, 2.5f, 9.86f, 2.0f, 12.0f, 2.0f)\n            curveTo(14.14f, 2.0f, 16.0f, 2.47f, 18.04f, 3.5f)\n            curveTo(18.29f, 3.65f, 18.38f, 3.95f, 18.25f, 4.19f)\n            curveTo(18.16f, 4.37f, 18.0f, 4.47f, 17.81f, 4.47f)\n            moveTo(17.15f, 5.65f)\n            curveTo(18.65f, 6.42f, 19.91f, 7.5f, 20.9f, 8.9f)\n            curveTo(21.06f, 9.12f, 21.0f, 9.44f, 20.78f, 9.6f)\n            curveTo(20.55f, 9.76f, 20.24f, 9.71f, 20.08f, 9.5f)\n            curveTo(19.18f, 8.22f, 18.04f, 7.23f, 16.69f, 6.54f)\n            curveTo(14.06f, 5.19f, 10.76f, 5.08f, 8.03f, 6.21f)\n            lineTo(7.27f, 5.45f)\n            curveTo(10.34f, 4.04f, 14.14f, 4.1f, 17.15f, 5.65f)\n            moveTo(12.0f, 9.27f)\n            curveTo(15.12f, 9.27f, 17.66f, 11.69f, 17.66f, 14.66f)\n            arcTo(\n                0.5f, 0.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 17.16f,\n                y1 = 15.16f\n            )\n            lineTo(16.93f, 15.11f)\n            lineTo(16.72f, 14.89f)\n            lineTo(16.66f, 14.66f)\n            curveTo(16.66f, 12.27f, 14.62f, 10.32f, 12.09f, 10.27f)\n            lineTo(11.15f, 9.33f)\n            lineTo(12.0f, 9.27f)\n            moveTo(14.38f, 18.22f)\n            curveTo(14.71f, 18.45f, 15.07f, 18.62f, 15.47f, 18.73f)\n            lineTo(12.63f, 15.9f)\n            curveTo(12.92f, 16.82f, 13.53f, 17.65f, 14.38f, 18.22f)\n            moveTo(19.21f, 14.66f)\n            curveTo(19.21f, 10.89f, 15.96f, 7.83f, 11.96f, 7.83f)\n            curveTo(11.26f, 7.83f, 10.58f, 7.93f, 9.93f, 8.11f)\n            lineTo(9.12f, 7.3f)\n            curveTo(10.0f, 7.0f, 10.97f, 6.82f, 11.96f, 6.82f)\n            curveTo(16.5f, 6.82f, 20.21f, 10.33f, 20.21f, 14.65f)\n            curveTo(20.21f, 15.65f, 19.69f, 16.53f, 18.89f, 17.06f)\n            lineTo(18.17f, 16.34f)\n            curveTo(18.79f, 16.0f, 19.21f, 15.38f, 19.21f, 14.66f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Firebase.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.TwoTone.Firebase: ImageVector by lazy {\n    Builder(\n        name = \"Firebase\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFFFF9100)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(8.4f, 23.3f)\n            curveToRelative(1.0f, 0.4f, 2.1f, 0.6f, 3.2f, 0.7f)\n            curveToRelative(1.5f, 0.1f, 3.0f, -0.3f, 4.3f, -0.9f)\n            curveToRelative(-1.6f, -0.6f, -3.0f, -1.5f, -4.2f, -2.7f)\n            curveTo(11.0f, 21.7f, 9.8f, 22.7f, 8.4f, 23.3f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFFFFC400)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(11.8f, 20.5f)\n            curveTo(9.0f, 17.9f, 7.3f, 14.2f, 7.4f, 10.1f)\n            curveToRelative(0.0f, -0.1f, 0.0f, -0.3f, 0.0f, -0.4f)\n            curveTo(7.0f, 9.5f, 6.4f, 9.5f, 5.9f, 9.5f)\n            curveToRelative(-0.8f, 0.0f, -1.5f, 0.1f, -2.2f, 0.3f)\n            curveTo(3.0f, 11.0f, 2.5f, 12.5f, 2.5f, 14.1f)\n            curveToRelative(-0.1f, 4.1f, 2.4f, 7.7f, 6.0f, 9.2f)\n            curveTo(9.8f, 22.7f, 11.0f, 21.7f, 11.8f, 20.5f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFFFF9100)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(11.8f, 20.5f)\n            curveToRelative(0.6f, -1.0f, 1.0f, -2.3f, 1.1f, -3.6f)\n            curveToRelative(0.1f, -3.4f, -2.2f, -6.4f, -5.4f, -7.2f)\n            curveToRelative(0.0f, 0.1f, 0.0f, 0.3f, 0.0f, 0.4f)\n            curveTo(7.3f, 14.2f, 9.0f, 17.9f, 11.8f, 20.5f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFFDD2C00)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.5f, 0.0f)\n            curveToRelative(-1.8f, 1.5f, -3.3f, 3.4f, -4.1f, 5.6f)\n            curveTo(7.9f, 6.9f, 7.6f, 8.2f, 7.5f, 9.7f)\n            curveToRelative(3.2f, 0.8f, 5.5f, 3.8f, 5.4f, 7.2f)\n            curveToRelative(0.0f, 1.3f, -0.4f, 2.5f, -1.1f, 3.6f)\n            curveToRelative(1.2f, 1.1f, 2.6f, 2.0f, 4.2f, 2.7f)\n            curveToRelative(3.2f, -1.5f, 5.4f, -4.6f, 5.5f, -8.3f)\n            curveToRelative(0.1f, -2.4f, -0.8f, -4.6f, -2.2f, -6.4f)\n            curveTo(18.0f, 6.5f, 12.5f, 0.0f, 12.5f, 0.0f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Firebase: ImageVector by lazy {\n    Builder(\n        name = \"Outlined.Firebase\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = SolidColor(Color(0xFF000000)),\n            strokeLineWidth = 0.5f\n        ) {\n            moveTo(18.213f, 8.974f)\n            curveToRelative(-0.449f, -0.623f, -1.482f, -1.904f, -3.068f, -3.808f)\n            curveToRelative(-0.689f, -0.826f, -1.279f, -1.526f, -1.57f, -1.87f)\n            curveToRelative(-0.16f, -0.19f, -0.298f, -0.352f, -0.406f, -0.481f)\n            lineToRelative(-0.173f, -0.204f)\n            lineToRelative(-0.094f, -0.111f)\n            lineToRelative(-0.018f, -0.027f)\n            lineToRelative(-0.008f, -0.004f)\n            lineTo(12.475f, 2f)\n            lineToRelative(-0.507f, 0.407f)\n            curveToRelative(-1.295f, 1.038f, -2.356f, 2.375f, -3.067f, 3.866f)\n            curveTo(8.464f, 7.16f, 8.18f, 8.027f, 8.03f, 8.92f)\n            curveTo(7.991f, 9.121f, 7.958f, 9.328f, 7.93f, 9.535f)\n            curveTo(7.756f, 9.52f, 7.579f, 9.511f, 7.403f, 9.507f)\n            curveToRelative(-0.015f, -0.001f, -0.029f, -0.002f, -0.049f, -0.002f)\n            curveToRelative(-0.643f, -0.022f, -1.282f, 0.054f, -1.9f, 0.228f)\n            lineTo(5.19f, 9.808f)\n            lineToRelative(-0.136f, 0.238f)\n            curveToRelative(-0.637f, 1.118f, -0.998f, 2.39f, -1.043f, 3.68f)\n            curveToRelative(-0.058f, 1.674f, 0.398f, 3.295f, 1.319f, 4.687f)\n            curveToRelative(0.902f, 1.361f, 2.175f, 2.402f, 3.683f, 3.01f)\n            lineToRelative(0.196f, 0.079f)\n            lineToRelative(0.059f, 0.021f)\n            lineToRelative(0.003f, -0.001f)\n            curveToRelative(0.786f, 0.285f, 1.61f, 0.445f, 2.451f, 0.473f)\n            curveTo(11.818f, 21.998f, 11.913f, 22f, 12.008f, 22f)\n            curveToRelative(1.061f, 0f, 2.094f, -0.208f, 3.074f, -0.618f)\n            lineToRelative(0.007f, 0.003f)\n            lineToRelative(0.261f, -0.121f)\n            curveToRelative(1.322f, -0.611f, 2.454f, -1.573f, 3.272f, -2.78f)\n            curveToRelative(0.842f, -1.242f, 1.315f, -2.694f, 1.367f, -4.201f)\n            curveToRelative(0.063f, -1.801f, -0.535f, -3.587f, -1.777f, -5.309f)\n            lineTo(18.213f, 8.974f)\n            close()\n            moveTo(12.31f, 14.554f)\n            curveToRelative(0.274f, 1.037f, 0.22f, 2.033f, -0.159f, 2.965f)\n            curveToRelative(-0.946f, -0.934f, -1.64f, -1.96f, -2.063f, -3.054f)\n            curveToRelative(-0.453f, -1.17f, -0.726f, -2.283f, -0.812f, -3.313f)\n            curveToRelative(0.4f, 0.131f, 0.768f, 0.305f, 1.096f, 0.519f)\n            curveToRelative(0.943f, 0.614f, 1.595f, 1.585f, 1.937f, 2.884f)\n            verticalLineTo(14.554f)\n            close()\n            moveTo(12.483f, 19.572f)\n            curveToRelative(0.402f, 0.306f, 0.825f, 0.593f, 1.26f, 0.857f)\n            curveToRelative(-0.642f, 0.175f, -1.304f, 0.251f, -1.974f, 0.227f)\n            curveToRelative(-0.103f, -0.004f, -0.207f, -0.01f, -0.311f, -0.018f)\n            curveToRelative(0.382f, -0.329f, 0.725f, -0.686f, 1.024f, -1.066f)\n            horizontalLineTo(12.483f)\n            close()\n            moveTo(13.605f, 14.212f)\n            curveToRelative(-0.43f, -1.631f, -1.272f, -2.864f, -2.502f, -3.665f)\n            curveToRelative(-0.539f, -0.351f, -1.154f, -0.618f, -1.829f, -0.792f)\n            curveTo(9.284f, 9.644f, 9.296f, 9.532f, 9.311f, 9.423f)\n            curveToRelative(0.012f, -0.094f, 0.025f, -0.18f, 0.039f, -0.261f)\n            curveToRelative(0.111f, -0.574f, 0.277f, -1.142f, 0.491f, -1.687f)\n            curveToRelative(0.082f, -0.209f, 0.172f, -0.417f, 0.267f, -0.617f)\n            lineToRelative(0.004f, -0.007f)\n            curveToRelative(0.147f, -0.298f, 0.313f, -0.599f, 0.508f, -0.92f)\n            lineToRelative(0.077f, -0.126f)\n            lineToRelative(-0.003f, -0.002f)\n            curveToRelative(0.454f, -0.709f, 0.997f, -1.355f, 1.619f, -1.925f)\n            lineToRelative(0.24f, 0.284f)\n            curveToRelative(0.56f, 0.663f, 1.086f, 1.29f, 1.564f, 1.864f)\n            curveToRelative(1.076f, 1.291f, 2.472f, 2.986f, 3.01f, 3.734f)\n            curveToRelative(1.065f, 1.476f, 1.578f, 2.982f, 1.525f, 4.479f)\n            curveToRelative(-0.041f, 1.162f, -0.385f, 2.296f, -0.996f, 3.277f)\n            curveToRelative(-0.578f, 0.93f, -1.384f, 1.708f, -2.334f, 2.256f)\n            curveToRelative(-0.53f, -0.264f, -1.299f, -0.699f, -2.116f, -1.332f)\n            curveToRelative(0.659f, -1.313f, 0.793f, -2.734f, 0.399f, -4.227f)\n            horizontalLineTo(13.605f)\n            close()\n            moveTo(11.459f, 18.71f)\n            curveToRelative(-0.604f, 0.782f, -1.322f, 1.291f, -1.741f, 1.547f)\n            curveToRelative(-0.068f, -0.025f, -0.136f, -0.051f, -0.203f, -0.078f)\n            lineTo(9.461f, 20.158f)\n            curveToRelative(-1.242f, -0.513f, -2.289f, -1.38f, -3.029f, -2.509f)\n            curveToRelative(-0.756f, -1.153f, -1.131f, -2.494f, -1.082f, -3.877f)\n            curveTo(5.384f, 12.78f, 5.631f, 11.833f, 6.085f, 10.955f)\n            curveToRelative(0.263f, -0.058f, 0.532f, -0.095f, 0.8f, -0.109f)\n            lineToRelative(0.069f, -0.002f)\n            curveToRelative(0.136f, -0.003f, 0.27f, -0.003f, 0.399f, 0f)\n            curveToRelative(0.189f, 0.009f, 0.378f, 0.028f, 0.564f, 0.058f)\n            curveToRelative(0.061f, 1.26f, 0.37f, 2.62f, 0.921f, 4.043f)\n            curveToRelative(0.53f, 1.37f, 1.411f, 2.635f, 2.62f, 3.763f)\n            lineTo(11.459f, 18.71f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Flip.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Flip: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Flip\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(611.5f, 188.5f)\n            quadTo(600f, 177f, 600f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(623f, 120f, 640f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(680f, 143f, 680f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(657f, 200f, 640f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 188.5f)\n            quadTo(760f, 177f, 760f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 120f, 800f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 143f, 840f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 200f, 800f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 348.5f)\n            quadTo(760f, 337f, 760f, 320f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 280f, 800f, 280f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 303f, 840f, 320f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 360f, 800f, 360f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 508.5f)\n            quadTo(760f, 497f, 760f, 480f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 440f, 800f, 440f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 463f, 840f, 480f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 520f, 800f, 520f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 668.5f)\n            quadTo(760f, 657f, 760f, 640f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 600f, 800f, 600f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 623f, 840f, 640f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 680f, 800f, 680f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(611.5f, 828.5f)\n            quadTo(600f, 817f, 600f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(623f, 760f, 640f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(680f, 783f, 680f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(657f, 840f, 640f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 828.5f)\n            quadTo(760f, 817f, 760f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 760f, 800f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 783f, 840f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 840f, 800f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(200f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120f, 760f)\n            verticalLineToRelative(-560f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(200f, 120f)\n            horizontalLineToRelative(120f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(360f, 160f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(320f, 200f)\n            lineTo(200f, 200f)\n            verticalLineToRelative(560f)\n            horizontalLineToRelative(120f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(360f, 800f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(320f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(440f, 880f)\n            verticalLineToRelative(-800f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(480f, 40f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(520f, 80f)\n            verticalLineToRelative(800f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(480f, 920f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(440f, 880f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FlipVertical.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.FlipVertical: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.FlipVertical\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.288f, 15.287f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.712f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(19.288f, 19.287f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(15.288f, 19.287f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(11.288f, 19.288f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.288f, 0.429f, 0.288f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.713f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.712f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(7.288f, 19.288f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.712f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(3.288f, 15.288f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.288f, -0.429f, -0.288f, -0.712f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(3.288f, 19.288f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.288f, -0.429f, -0.288f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(3f, 5f)\n            curveToRelative(-0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.862f, -0.588f, 1.412f, -0.588f)\n            lineToRelative(14f, -0f)\n            curveToRelative(0.55f, -0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            curveToRelative(0.392f, 0.392f, 0.588f, 0.862f, 0.588f, 1.412f)\n            lineToRelative(0f, 3f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.712f)\n            lineToRelative(-0f, -3f)\n            lineToRelative(-14f, 0f)\n            lineToRelative(0f, 3f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.712f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.288f, -0.429f, -0.288f, -0.712f)\n            lineToRelative(-0f, -3f)\n            close()\n            moveTo(2f, 11f)\n            lineToRelative(20f, -0f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.713f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.288f, -0.712f, 0.288f)\n            lineToRelative(-20f, 0f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.713f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.288f, -0.429f, -0.288f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.713f)\n            reflectiveCurveToRelative(0.429f, -0.288f, 0.712f, -0.288f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FloatingActionButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FloatingActionButton: ImageVector by lazy {\n    Builder(\n        name = \"Floating Action Button\", defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.9692f, 10.67f)\n            lineToRelative(-3.0954f, 3.0955f)\n            lineToRelative(0.0f, 0.4512f)\n            lineToRelative(0.4512f, 0.0f)\n            lineToRelative(3.0954f, -3.0954f)\n            lineToRelative(-0.2296f, -0.2217f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.8593f, 3.1335f)\n            horizontalLineTo(8.1407f)\n            curveTo(5.3016f, 3.1335f, 3.0f, 5.4351f, 3.0f, 8.2742f)\n            verticalLineToRelative(7.7186f)\n            curveToRelative(0.0f, 2.8392f, 2.3016f, 5.1407f, 5.1407f, 5.1407f)\n            horizontalLineToRelative(7.7186f)\n            curveToRelative(2.8391f, 0.0f, 5.1407f, -2.3015f, 5.1407f, -5.1407f)\n            verticalLineTo(8.2742f)\n            curveTo(21.0f, 5.4351f, 18.6984f, 3.1335f, 15.8593f, 3.1335f)\n            close()\n            moveTo(14.7643f, 10.672f)\n            curveToRelative(-0.001f, 0.001f, -0.0026f, 0.0013f, -0.0036f, 0.0024f)\n            curveToRelative(-0.001f, 0.0011f, -0.0012f, 0.0024f, -0.0023f, 0.0035f)\n            lineToRelative(-4.1721f, 4.1721f)\n            horizontalLineTo(9.2404f)\n            verticalLineToRelative(-1.3458f)\n            lineToRelative(4.18f, -4.1721f)\n            curveToRelative(4.0E-4f, -3.0E-4f, 8.0E-4f, -4.0E-4f, 0.0012f, -7.0E-4f)\n            curveToRelative(4.0E-4f, -4.0E-4f, 4.0E-4f, -9.0E-4f, 8.0E-4f, -0.0012f)\n            curveToRelative(0.2612f, -0.2612f, 0.6848f, -0.2612f, 0.946f, 0.0f)\n            lineToRelative(0.3959f, 0.3959f)\n            curveTo(15.0255f, 9.9872f, 15.0255f, 10.4108f, 14.7643f, 10.672f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FloodFill.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FloodFill: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.FloodFill\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(346f, 820f)\n            lineTo(100f, 574f)\n            quadTo(90f, 564f, 85f, 552f)\n            quadTo(80f, 540f, 80f, 527f)\n            quadTo(80f, 514f, 85f, 502f)\n            quadTo(90f, 490f, 100f, 480f)\n            lineTo(330f, 251f)\n            lineTo(224f, 145f)\n            lineTo(286f, 80f)\n            lineTo(686f, 480f)\n            quadTo(696f, 490f, 700.5f, 502f)\n            quadTo(705f, 514f, 705f, 527f)\n            quadTo(705f, 540f, 700.5f, 552f)\n            quadTo(696f, 564f, 686f, 574f)\n            lineTo(440f, 820f)\n            quadTo(430f, 830f, 418f, 835f)\n            quadTo(406f, 840f, 393f, 840f)\n            quadTo(380f, 840f, 368f, 835f)\n            quadTo(356f, 830f, 346f, 820f)\n            close()\n            moveTo(393f, 314f)\n            lineTo(179f, 528f)\n            quadTo(179f, 528f, 179f, 528f)\n            quadTo(179f, 528f, 179f, 528f)\n            lineTo(607f, 528f)\n            quadTo(607f, 528f, 607f, 528f)\n            quadTo(607f, 528f, 607f, 528f)\n            lineTo(393f, 314f)\n            close()\n            moveTo(792f, 840f)\n            quadTo(756f, 840f, 731f, 814.5f)\n            quadTo(706f, 789f, 706f, 752f)\n            quadTo(706f, 725f, 719.5f, 701f)\n            quadTo(733f, 677f, 750f, 654f)\n            lineTo(792f, 600f)\n            lineTo(836f, 654f)\n            quadTo(852f, 677f, 866f, 701f)\n            quadTo(880f, 725f, 880f, 752f)\n            quadTo(880f, 789f, 854f, 814.5f)\n            quadTo(828f, 840f, 792f, 840f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FolderCompare.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FolderCompare: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"FolderCompare\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13f, 19f)\n            curveTo(13f, 19.34f, 13.04f, 19.67f, 13.09f, 20f)\n            horizontalLineTo(4f)\n            curveTo(2.9f, 20f, 2f, 19.11f, 2f, 18f)\n            verticalLineTo(6f)\n            curveTo(2f, 4.89f, 2.89f, 4f, 4f, 4f)\n            horizontalLineTo(10f)\n            lineTo(12f, 6f)\n            horizontalLineTo(20f)\n            curveTo(21.1f, 6f, 22f, 6.89f, 22f, 8f)\n            verticalLineTo(13.81f)\n            curveTo(21.12f, 13.3f, 20.1f, 13f, 19f, 13f)\n            curveTo(15.69f, 13f, 13f, 15.69f, 13f, 19f)\n            moveTo(23f, 17f)\n            lineTo(20f, 14.5f)\n            verticalLineTo(16f)\n            horizontalLineTo(16f)\n            verticalLineTo(18f)\n            horizontalLineTo(20f)\n            verticalLineTo(19.5f)\n            lineTo(23f, 17f)\n            moveTo(18f, 18.5f)\n            lineTo(15f, 21f)\n            lineTo(18f, 23.5f)\n            verticalLineTo(22f)\n            horizontalLineTo(22f)\n            verticalLineTo(20f)\n            horizontalLineTo(18f)\n            verticalLineTo(18.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FolderImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.FolderImage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.FolderImage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6.667f, 15.733f)\n            lineToRelative(10.667f, 0f)\n            lineToRelative(-3.68f, -4.8f)\n            lineToRelative(-2.453f, 3.2f)\n            lineToRelative(-1.653f, -2.133f)\n            lineToRelative(-2.88f, 3.733f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.973f, 6.76f)\n            curveToRelative(-0.418f, -0.418f, -0.92f, -0.627f, -1.507f, -0.627f)\n            horizontalLineToRelative(-7.467f)\n            lineToRelative(-2.133f, -2.133f)\n            horizontalLineToRelative(-5.333f)\n            curveToRelative(-0.587f, 0f, -1.089f, 0.209f, -1.507f, 0.627f)\n            reflectiveCurveToRelative(-0.627f, 0.92f, -0.627f, 1.507f)\n            verticalLineToRelative(11.733f)\n            curveToRelative(0f, 0.587f, 0.209f, 1.089f, 0.627f, 1.507f)\n            reflectiveCurveToRelative(0.92f, 0.627f, 1.507f, 0.627f)\n            horizontalLineToRelative(14.933f)\n            curveToRelative(0.587f, 0f, 1.089f, -0.209f, 1.507f, -0.627f)\n            reflectiveCurveToRelative(0.627f, -0.92f, 0.627f, -1.507f)\n            verticalLineToRelative(-9.6f)\n            curveToRelative(0f, -0.587f, -0.209f, -1.089f, -0.627f, -1.507f)\n            close()\n            moveTo(19.467f, 17.867f)\n            horizontalLineTo(4.533f)\n            verticalLineTo(6.133f)\n            horizontalLineToRelative(4.453f)\n            lineToRelative(2.133f, 2.133f)\n            horizontalLineToRelative(8.347f)\n            verticalLineToRelative(9.6f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.FolderImage: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.FolderImage\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.973f, 6.76f)\n            curveToRelative(-0.418f, -0.418f, -0.92f, -0.627f, -1.507f, -0.627f)\n            horizontalLineToRelative(-7.467f)\n            lineToRelative(-2.133f, -2.133f)\n            horizontalLineToRelative(-5.333f)\n            curveToRelative(-0.587f, 0f, -1.089f, 0.209f, -1.507f, 0.627f)\n            curveToRelative(-0.418f, 0.418f, -0.627f, 0.92f, -0.627f, 1.507f)\n            verticalLineToRelative(11.733f)\n            curveToRelative(0f, 0.587f, 0.209f, 1.089f, 0.627f, 1.507f)\n            curveToRelative(0.418f, 0.418f, 0.92f, 0.627f, 1.507f, 0.627f)\n            horizontalLineToRelative(14.933f)\n            curveToRelative(0.587f, 0f, 1.089f, -0.209f, 1.507f, -0.627f)\n            curveToRelative(0.418f, -0.418f, 0.627f, -0.92f, 0.627f, -1.507f)\n            verticalLineToRelative(-9.6f)\n            curveToRelative(0f, -0.587f, -0.209f, -1.089f, -0.627f, -1.507f)\n            close()\n            moveTo(6.667f, 15.733f)\n            lineToRelative(2.88f, -3.733f)\n            lineToRelative(1.653f, 2.133f)\n            lineToRelative(2.453f, -3.2f)\n            lineToRelative(3.68f, 4.8f)\n            horizontalLineTo(6.667f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FolderImageAlt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FolderImageAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.FolderImageAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10.509f, 20.464f)\n            lineToRelative(2.457f, -3.272f)\n            curveToRelative(0.061f, -0.082f, 0.136f, -0.143f, 0.223f, -0.184f)\n            reflectiveCurveToRelative(0.177f, -0.061f, 0.269f, -0.061f)\n            reflectiveCurveToRelative(0.182f, 0.02f, 0.269f, 0.061f)\n            reflectiveCurveToRelative(0.161f, 0.102f, 0.223f, 0.184f)\n            lineToRelative(2.089f, 2.78f)\n            curveToRelative(0.061f, 0.082f, 0.133f, 0.143f, 0.215f, 0.184f)\n            reflectiveCurveToRelative(0.174f, 0.061f, 0.276f, 0.061f)\n            curveToRelative(0.256f, 0f, 0.44f, -0.115f, 0.553f, -0.346f)\n            curveToRelative(0.113f, -0.23f, 0.092f, -0.448f, -0.061f, -0.653f)\n            lineToRelative(-1.29f, -1.705f)\n            curveToRelative(-0.082f, -0.113f, -0.123f, -0.236f, -0.123f, -0.369f)\n            curveToRelative(0f, -0.133f, 0.041f, -0.256f, 0.123f, -0.369f)\n            lineToRelative(1.536f, -2.043f)\n            curveToRelative(0.061f, -0.082f, 0.136f, -0.143f, 0.223f, -0.184f)\n            reflectiveCurveToRelative(0.177f, -0.061f, 0.269f, -0.061f)\n            reflectiveCurveToRelative(0.182f, 0.02f, 0.269f, 0.061f)\n            reflectiveCurveToRelative(0.161f, 0.102f, 0.223f, 0.184f)\n            lineToRelative(4.301f, 5.729f)\n            curveToRelative(0.154f, 0.205f, 0.174f, 0.42f, 0.061f, 0.645f)\n            curveToRelative(-0.113f, 0.225f, -0.297f, 0.338f, -0.553f, 0.338f)\n            horizontalLineToRelative(-11.059f)\n            curveToRelative(-0.256f, 0f, -0.44f, -0.113f, -0.553f, -0.338f)\n            curveToRelative(-0.113f, -0.225f, -0.092f, -0.44f, 0.061f, -0.645f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 20f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.412f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.588f, -0.863f, -0.588f, -1.413f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.588f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.412f, -0.587f)\n            horizontalLineToRelative(5.175f)\n            curveToRelative(0.267f, 0f, 0.521f, 0.05f, 0.762f, 0.15f)\n            curveToRelative(0.242f, 0.1f, 0.454f, 0.242f, 0.637f, 0.425f)\n            lineToRelative(1.425f, 1.425f)\n            horizontalLineToRelative(8f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            curveToRelative(0.392f, 0.392f, 0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.288f, 0.713f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-1.667f, 0f, -3.083f, 0.583f, -4.25f, 1.75f)\n            curveToRelative(-1.167f, 1.167f, -1.75f, 2.583f, -1.75f, 4.25f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.288f, -0.713f, 0.288f)\n            horizontalLineToRelative(-4f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.FolderImageAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.FolderImageAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 18f)\n            lineToRelative(0f, -12f)\n            lineToRelative(0f, 6.925f)\n            lineToRelative(0f, -0.925f)\n            lineToRelative(0f, 6f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10.617f, 20.464f)\n            lineToRelative(2.457f, -3.272f)\n            curveToRelative(0.061f, -0.082f, 0.136f, -0.143f, 0.223f, -0.184f)\n            reflectiveCurveToRelative(0.177f, -0.061f, 0.269f, -0.061f)\n            reflectiveCurveToRelative(0.182f, 0.02f, 0.269f, 0.061f)\n            reflectiveCurveToRelative(0.161f, 0.102f, 0.223f, 0.184f)\n            lineToRelative(2.089f, 2.78f)\n            curveToRelative(0.061f, 0.082f, 0.133f, 0.143f, 0.215f, 0.184f)\n            reflectiveCurveToRelative(0.174f, 0.061f, 0.276f, 0.061f)\n            curveToRelative(0.256f, 0f, 0.44f, -0.115f, 0.553f, -0.346f)\n            curveToRelative(0.113f, -0.23f, 0.092f, -0.448f, -0.061f, -0.653f)\n            lineToRelative(-1.29f, -1.705f)\n            curveToRelative(-0.082f, -0.113f, -0.123f, -0.236f, -0.123f, -0.369f)\n            curveToRelative(0f, -0.133f, 0.041f, -0.256f, 0.123f, -0.369f)\n            lineToRelative(1.536f, -2.043f)\n            curveToRelative(0.061f, -0.082f, 0.136f, -0.143f, 0.223f, -0.184f)\n            reflectiveCurveToRelative(0.177f, -0.061f, 0.269f, -0.061f)\n            reflectiveCurveToRelative(0.182f, 0.02f, 0.269f, 0.061f)\n            reflectiveCurveToRelative(0.161f, 0.102f, 0.223f, 0.184f)\n            lineToRelative(4.301f, 5.729f)\n            curveToRelative(0.154f, 0.205f, 0.174f, 0.42f, 0.061f, 0.645f)\n            curveToRelative(-0.113f, 0.225f, -0.297f, 0.338f, -0.553f, 0.338f)\n            horizontalLineToRelative(-11.059f)\n            curveToRelative(-0.256f, 0f, -0.44f, -0.113f, -0.553f, -0.338f)\n            curveToRelative(-0.113f, -0.225f, -0.092f, -0.44f, 0.061f, -0.645f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 6.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-8f)\n            lineToRelative(-1.425f, -1.425f)\n            curveToRelative(-0.183f, -0.183f, -0.396f, -0.325f, -0.638f, -0.425f)\n            curveToRelative(-0.242f, -0.1f, -0.496f, -0.15f, -0.763f, -0.15f)\n            horizontalLineToRelative(-5.175f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.552f, 0f, 1f, -0.448f, 1f, -1f)\n            reflectiveCurveToRelative(-0.448f, -1f, -1f, -1f)\n            horizontalLineToRelative(-4f)\n            verticalLineTo(6f)\n            horizontalLineToRelative(5.175f)\n            lineToRelative(1.425f, 1.425f)\n            curveToRelative(0.183f, 0.183f, 0.396f, 0.325f, 0.638f, 0.425f)\n            curveToRelative(0.242f, 0.1f, 0.496f, 0.15f, 0.763f, 0.15f)\n            horizontalLineToRelative(8f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.552f, 0.448f, 1f, 1f, 1f)\n            reflectiveCurveToRelative(1f, -0.448f, 1f, -1f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FolderMatch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FolderMatch: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.FolderMatch\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(230f, 680f)\n            quadToRelative(-20f, -24f, -33.5f, -51.5f)\n            reflectiveQuadTo(174f, 571f)\n            quadToRelative(-5f, -16f, 4f, -28.5f)\n            reflectiveQuadToRelative(26f, -15.5f)\n            quadToRelative(17f, -3f, 30.5f, 6f)\n            reflectiveQuadToRelative(18.5f, 25f)\n            quadToRelative(5f, 16f, 12.5f, 30.5f)\n            reflectiveQuadTo(283f, 617f)\n            quadToRelative(10f, 14f, 21f, 25.5f)\n            reflectiveQuadToRelative(24f, 22.5f)\n            quadToRelative(13f, 11f, 16.5f, 27f)\n            reflectiveQuadToRelative(-4.5f, 30f)\n            quadToRelative(-8f, 14f, -24f, 18.5f)\n            reflectiveQuadToRelative(-29f, -5.5f)\n            quadToRelative(-16f, -12f, -30.5f, -26f)\n            reflectiveQuadTo(230f, 680f)\n            close()\n            moveTo(500f, 880f)\n            quadToRelative(-25f, 0f, -42.5f, -17.5f)\n            reflectiveQuadTo(440f, 820f)\n            verticalLineToRelative(-240f)\n            quadToRelative(0f, -25f, 17.5f, -42.5f)\n            reflectiveQuadTo(500f, 520f)\n            horizontalLineToRelative(88f)\n            quadToRelative(15f, 0f, 28.5f, 7f)\n            reflectiveQuadToRelative(21.5f, 20f)\n            lineToRelative(22f, 33f)\n            horizontalLineToRelative(160f)\n            quadToRelative(25f, 0f, 42.5f, 17.5f)\n            reflectiveQuadTo(880f, 640f)\n            verticalLineToRelative(180f)\n            quadToRelative(0f, 25f, -17.5f, 42.5f)\n            reflectiveQuadTo(820f, 880f)\n            lineTo(500f, 880f)\n            close()\n            moveTo(140f, 440f)\n            quadToRelative(-25f, 0f, -42.5f, -17.5f)\n            reflectiveQuadTo(80f, 380f)\n            verticalLineToRelative(-240f)\n            quadToRelative(0f, -25f, 17.5f, -42.5f)\n            reflectiveQuadTo(140f, 80f)\n            horizontalLineToRelative(88f)\n            quadToRelative(15f, 0f, 28.5f, 7f)\n            reflectiveQuadToRelative(21.5f, 20f)\n            lineToRelative(22f, 33f)\n            horizontalLineToRelative(160f)\n            quadToRelative(25f, 0f, 42.5f, 17.5f)\n            reflectiveQuadTo(520f, 200f)\n            verticalLineToRelative(180f)\n            quadToRelative(0f, 25f, -17.5f, 42.5f)\n            reflectiveQuadTo(460f, 440f)\n            lineTo(140f, 440f)\n            close()\n            moveTo(688f, 360f)\n            quadToRelative(-11f, -19f, -25f, -35f)\n            reflectiveQuadToRelative(-31f, -30f)\n            quadToRelative(-13f, -11f, -16.5f, -27f)\n            reflectiveQuadToRelative(4.5f, -30f)\n            quadToRelative(8f, -14f, 24f, -18.5f)\n            reflectiveQuadToRelative(29f, 5.5f)\n            quadToRelative(21f, 16f, 39f, 35f)\n            reflectiveQuadToRelative(33f, 41f)\n            quadToRelative(21f, 31f, 34.5f, 66.5f)\n            reflectiveQuadTo(798f, 441f)\n            quadToRelative(2f, 16f, -9.5f, 27.5f)\n            reflectiveQuadTo(760f, 480f)\n            quadToRelative(-17f, 0f, -28.5f, -11f)\n            reflectiveQuadTo(717f, 441f)\n            quadToRelative(-4f, -22f, -11f, -42f)\n            reflectiveQuadToRelative(-18f, -39f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FolderOpened.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FolderOpened: ImageVector by lazy {\n    Builder(\n        name = \"Folder Opened\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(160.0f, 800.0f)\n            quadToRelative(-33.0f, 0.0f, -56.5f, -23.5f)\n            reflectiveQuadTo(80.0f, 720.0f)\n            verticalLineToRelative(-480.0f)\n            quadToRelative(0.0f, -33.0f, 23.5f, -56.5f)\n            reflectiveQuadTo(160.0f, 160.0f)\n            horizontalLineToRelative(240.0f)\n            lineToRelative(80.0f, 80.0f)\n            horizontalLineToRelative(320.0f)\n            quadToRelative(33.0f, 0.0f, 56.5f, 23.5f)\n            reflectiveQuadTo(880.0f, 320.0f)\n            lineTo(160.0f, 320.0f)\n            verticalLineToRelative(400.0f)\n            lineToRelative(96.0f, -320.0f)\n            horizontalLineToRelative(684.0f)\n            lineTo(837.0f, 743.0f)\n            quadToRelative(-8.0f, 26.0f, -29.5f, 41.5f)\n            reflectiveQuadTo(760.0f, 800.0f)\n            lineTo(160.0f, 800.0f)\n            close()\n        }\n    }\n        .build()\n}\n\nval Icons.Outlined.FolderOpened: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"Outlined.FolderOpened\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(160f, 800f)\n            quadTo(127f, 800f, 103.5f, 776.5f)\n            quadTo(80f, 753f, 80f, 720f)\n            lineTo(80f, 240f)\n            quadTo(80f, 207f, 103.5f, 183.5f)\n            quadTo(127f, 160f, 160f, 160f)\n            lineTo(400f, 160f)\n            lineTo(480f, 240f)\n            lineTo(800f, 240f)\n            quadTo(833f, 240f, 856.5f, 263.5f)\n            quadTo(880f, 287f, 880f, 320f)\n            lineTo(447f, 320f)\n            lineTo(367f, 240f)\n            lineTo(160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            lineTo(160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            lineTo(256f, 400f)\n            lineTo(940f, 400f)\n            lineTo(837f, 743f)\n            quadTo(829f, 769f, 807.5f, 784.5f)\n            quadTo(786f, 800f, 760f, 800f)\n            lineTo(160f, 800f)\n            close()\n            moveTo(244f, 720f)\n            lineTo(760f, 720f)\n            lineTo(832f, 480f)\n            lineTo(316f, 480f)\n            lineTo(244f, 720f)\n            close()\n            moveTo(244f, 720f)\n            lineTo(316f, 480f)\n            lineTo(316f, 480f)\n            lineTo(244f, 720f)\n            close()\n            moveTo(160f, 320f)\n            lineTo(160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            lineTo(160f, 240f)\n            lineTo(160f, 320f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FontFamily.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FontFamily: ImageVector by lazy {\n    Builder(\n        name = \"Font Family\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(186.0f, 880.0f)\n            quadToRelative(-54.0f, 0.0f, -80.0f, -22.0f)\n            reflectiveQuadToRelative(-26.0f, -66.0f)\n            quadToRelative(0.0f, -58.0f, 49.0f, -74.0f)\n            reflectiveQuadToRelative(116.0f, -16.0f)\n            horizontalLineToRelative(21.0f)\n            verticalLineToRelative(-56.0f)\n            quadToRelative(0.0f, -34.0f, -1.0f, -55.5f)\n            reflectiveQuadToRelative(-6.0f, -35.5f)\n            quadToRelative(-5.0f, -14.0f, -11.5f, -19.5f)\n            reflectiveQuadTo(230.0f, 530.0f)\n            quadToRelative(-9.0f, 0.0f, -16.5f, 3.0f)\n            reflectiveQuadToRelative(-12.5f, 8.0f)\n            quadToRelative(-4.0f, 5.0f, -5.0f, 10.5f)\n            reflectiveQuadToRelative(1.0f, 11.5f)\n            quadToRelative(6.0f, 11.0f, 14.0f, 21.5f)\n            reflectiveQuadToRelative(8.0f, 24.5f)\n            quadToRelative(0.0f, 25.0f, -17.5f, 42.5f)\n            reflectiveQuadTo(159.0f, 669.0f)\n            quadToRelative(-25.0f, 0.0f, -42.5f, -17.5f)\n            reflectiveQuadTo(99.0f, 609.0f)\n            quadToRelative(0.0f, -27.0f, 12.0f, -44.0f)\n            reflectiveQuadToRelative(32.5f, -27.0f)\n            quadToRelative(20.5f, -10.0f, 47.5f, -14.0f)\n            reflectiveQuadToRelative(58.0f, -4.0f)\n            quadToRelative(85.0f, 0.0f, 118.0f, 30.5f)\n            reflectiveQuadTo(400.0f, 658.0f)\n            verticalLineToRelative(147.0f)\n            quadToRelative(0.0f, 19.0f, 4.5f, 28.0f)\n            reflectiveQuadToRelative(15.5f, 9.0f)\n            quadToRelative(12.0f, 0.0f, 19.5f, -18.0f)\n            reflectiveQuadToRelative(9.5f, -56.0f)\n            horizontalLineToRelative(11.0f)\n            quadToRelative(-3.0f, 62.0f, -23.5f, 87.0f)\n            reflectiveQuadTo(368.0f, 880.0f)\n            quadToRelative(-43.0f, 0.0f, -67.5f, -13.5f)\n            reflectiveQuadTo(269.0f, 826.0f)\n            quadToRelative(-10.0f, 29.0f, -29.5f, 41.5f)\n            reflectiveQuadTo(186.0f, 880.0f)\n            close()\n            moveTo(559.0f, 880.0f)\n            quadToRelative(-20.0f, 0.0f, -32.5f, -16.5f)\n            reflectiveQuadTo(522.0f, 828.0f)\n            lineToRelative(102.0f, -269.0f)\n            quadToRelative(7.0f, -17.0f, 22.0f, -28.0f)\n            reflectiveQuadToRelative(34.0f, -11.0f)\n            quadToRelative(19.0f, 0.0f, 34.0f, 11.0f)\n            reflectiveQuadToRelative(22.0f, 28.0f)\n            lineToRelative(102.0f, 269.0f)\n            quadToRelative(8.0f, 19.0f, -4.5f, 35.5f)\n            reflectiveQuadTo(801.0f, 880.0f)\n            quadToRelative(-12.0f, 0.0f, -22.0f, -7.0f)\n            reflectiveQuadToRelative(-15.0f, -19.0f)\n            lineToRelative(-20.0f, -58.0f)\n            lineTo(616.0f, 796.0f)\n            lineToRelative(-20.0f, 58.0f)\n            quadToRelative(-4.0f, 11.0f, -14.0f, 18.5f)\n            reflectiveQuadTo(559.0f, 880.0f)\n            close()\n            moveTo(235.0f, 851.0f)\n            quadToRelative(13.0f, 0.0f, 22.0f, -20.5f)\n            reflectiveQuadToRelative(9.0f, -49.5f)\n            verticalLineToRelative(-67.0f)\n            quadToRelative(-26.0f, 0.0f, -38.0f, 15.5f)\n            reflectiveQuadTo(216.0f, 780.0f)\n            verticalLineToRelative(11.0f)\n            quadToRelative(0.0f, 36.0f, 4.0f, 48.0f)\n            reflectiveQuadToRelative(15.0f, 12.0f)\n            close()\n            moveTo(642.0f, 726.0f)\n            horizontalLineToRelative(77.0f)\n            lineToRelative(-39.0f, -114.0f)\n            lineToRelative(-38.0f, 114.0f)\n            close()\n            moveTo(605.0f, 441.0f)\n            quadToRelative(-48.0f, 0.0f, -76.5f, -33.5f)\n            reflectiveQuadTo(500.0f, 317.0f)\n            quadToRelative(0.0f, -104.0f, 66.0f, -170.5f)\n            reflectiveQuadTo(735.0f, 80.0f)\n            quadToRelative(42.0f, 0.0f, 68.0f, 9.5f)\n            reflectiveQuadToRelative(26.0f, 24.5f)\n            quadToRelative(0.0f, 6.0f, -2.0f, 12.0f)\n            reflectiveQuadToRelative(-7.0f, 11.0f)\n            quadToRelative(-5.0f, 7.0f, -12.5f, 10.0f)\n            reflectiveQuadToRelative(-15.5f, 1.0f)\n            quadToRelative(-14.0f, -4.0f, -32.0f, -7.0f)\n            reflectiveQuadToRelative(-33.0f, -3.0f)\n            quadToRelative(-71.0f, 0.0f, -114.0f, 48.0f)\n            reflectiveQuadToRelative(-43.0f, 127.0f)\n            quadToRelative(0.0f, 22.0f, 8.0f, 46.0f)\n            reflectiveQuadToRelative(36.0f, 24.0f)\n            quadToRelative(11.0f, 0.0f, 21.5f, -5.0f)\n            reflectiveQuadToRelative(18.5f, -14.0f)\n            quadToRelative(17.0f, -18.0f, 31.5f, -60.0f)\n            reflectiveQuadTo(712.0f, 202.0f)\n            quadToRelative(2.0f, -13.0f, 10.5f, -18.5f)\n            reflectiveQuadTo(746.0f, 178.0f)\n            quadToRelative(18.0f, 0.0f, 27.5f, 9.5f)\n            reflectiveQuadTo(779.0f, 211.0f)\n            quadToRelative(-12.0f, 43.0f, -17.5f, 75.0f)\n            reflectiveQuadToRelative(-5.5f, 58.0f)\n            quadToRelative(0.0f, 20.0f, 5.5f, 29.0f)\n            reflectiveQuadToRelative(16.5f, 9.0f)\n            quadToRelative(11.0f, 0.0f, 21.5f, -8.0f)\n            reflectiveQuadToRelative(29.5f, -30.0f)\n            quadToRelative(2.0f, -3.0f, 15.0f, -7.0f)\n            quadToRelative(8.0f, 0.0f, 12.0f, 6.0f)\n            reflectiveQuadToRelative(4.0f, 17.0f)\n            quadToRelative(0.0f, 28.0f, -32.0f, 54.0f)\n            reflectiveQuadToRelative(-67.0f, 26.0f)\n            quadToRelative(-26.0f, 0.0f, -44.5f, -14.0f)\n            reflectiveQuadTo(691.0f, 386.0f)\n            quadToRelative(-15.0f, 26.0f, -37.0f, 40.5f)\n            reflectiveQuadTo(605.0f, 441.0f)\n            close()\n            moveTo(120.0f, 440.0f)\n            verticalLineToRelative(-220.0f)\n            quadToRelative(0.0f, -58.0f, 41.0f, -99.0f)\n            reflectiveQuadToRelative(99.0f, -41.0f)\n            quadToRelative(58.0f, 0.0f, 99.0f, 41.0f)\n            reflectiveQuadToRelative(41.0f, 99.0f)\n            verticalLineToRelative(220.0f)\n            horizontalLineToRelative(-80.0f)\n            verticalLineToRelative(-80.0f)\n            lineTo(200.0f, 360.0f)\n            verticalLineToRelative(80.0f)\n            horizontalLineToRelative(-80.0f)\n            close()\n            moveTo(200.0f, 280.0f)\n            horizontalLineToRelative(120.0f)\n            verticalLineToRelative(-60.0f)\n            quadToRelative(0.0f, -25.0f, -17.5f, -42.5f)\n            reflectiveQuadTo(260.0f, 160.0f)\n            quadToRelative(-25.0f, 0.0f, -42.5f, 17.5f)\n            reflectiveQuadTo(200.0f, 220.0f)\n            verticalLineToRelative(60.0f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FormatPaintVariant.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.FormatPaintVariant: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.FormatPaintVariant\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(440f, 880f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(360f, 800f)\n            verticalLineToRelative(-160f)\n            lineTo(240f, 640f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(160f, 560f)\n            verticalLineToRelative(-280f)\n            quadToRelative(0f, -66f, 47f, -113f)\n            reflectiveQuadToRelative(113f, -47f)\n            horizontalLineToRelative(480f)\n            verticalLineToRelative(440f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(720f, 640f)\n            lineTo(600f, 640f)\n            verticalLineToRelative(160f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(520f, 880f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(240f, 400f)\n            horizontalLineToRelative(480f)\n            verticalLineToRelative(-200f)\n            horizontalLineToRelative(-40f)\n            verticalLineToRelative(160f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(-160f)\n            horizontalLineToRelative(-40f)\n            verticalLineToRelative(80f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(-80f)\n            lineTo(320f, 200f)\n            quadToRelative(-33f, 0f, -56.5f, 23.5f)\n            reflectiveQuadTo(240f, 280f)\n            verticalLineToRelative(120f)\n            close()\n            moveTo(240f, 560f)\n            horizontalLineToRelative(480f)\n            verticalLineToRelative(-80f)\n            lineTo(240f, 480f)\n            verticalLineToRelative(80f)\n            close()\n            moveTo(240f, 560f)\n            verticalLineToRelative(-80f)\n            verticalLineToRelative(80f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.FormatPaintVariant: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.FormatPaintVariant\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 3f)\n            curveToRelative(-1.1f, 0f, -2.042f, 0.392f, -2.825f, 1.175f)\n            reflectiveCurveToRelative(-1.175f, 1.725f, -1.175f, 2.825f)\n            verticalLineToRelative(7f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(3f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(3f)\n            horizontalLineToRelative(-12f)\n            close()\n            moveTo(18f, 14f)\n            horizontalLineTo(6f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(12f)\n            verticalLineToRelative(2f)\n            close()\n            moveTo(18f, 10f)\n            horizontalLineTo(6f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.588f, -1.412f)\n            reflectiveCurveToRelative(0.862f, -0.588f, 1.412f, -0.588f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(1f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(1f)\n            verticalLineToRelative(5f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 14f)\n            verticalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6f, 10f)\n            horizontalLineToRelative(12f)\n            verticalLineToRelative(-5f)\n            horizontalLineToRelative(-1f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-1f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.413f, 0.587f)\n            curveToRelative(-0.392f, 0.392f, -0.587f, 0.863f, -0.587f, 1.413f)\n            verticalLineToRelative(3f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6f, 12f)\n            horizontalLineToRelative(12f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-12f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Forum.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Forum: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Forum\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 720f)\n            quadTo(263f, 720f, 251.5f, 708.5f)\n            quadTo(240f, 697f, 240f, 680f)\n            lineTo(240f, 600f)\n            lineTo(760f, 600f)\n            lineTo(760f, 600f)\n            lineTo(760f, 240f)\n            lineTo(840f, 240f)\n            quadTo(857f, 240f, 868.5f, 251.5f)\n            quadTo(880f, 263f, 880f, 280f)\n            lineTo(880f, 880f)\n            lineTo(720f, 720f)\n            lineTo(280f, 720f)\n            close()\n            moveTo(80f, 680f)\n            lineTo(80f, 120f)\n            quadTo(80f, 103f, 91.5f, 91.5f)\n            quadTo(103f, 80f, 120f, 80f)\n            lineTo(640f, 80f)\n            quadTo(657f, 80f, 668.5f, 91.5f)\n            quadTo(680f, 103f, 680f, 120f)\n            lineTo(680f, 480f)\n            quadTo(680f, 497f, 668.5f, 508.5f)\n            quadTo(657f, 520f, 640f, 520f)\n            lineTo(240f, 520f)\n            lineTo(80f, 680f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Forum: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Forum\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(880f, 880f)\n            lineTo(720f, 720f)\n            lineTo(320f, 720f)\n            quadTo(287f, 720f, 263.5f, 696.5f)\n            quadTo(240f, 673f, 240f, 640f)\n            lineTo(240f, 600f)\n            lineTo(680f, 600f)\n            quadTo(713f, 600f, 736.5f, 576.5f)\n            quadTo(760f, 553f, 760f, 520f)\n            lineTo(760f, 240f)\n            lineTo(800f, 240f)\n            quadTo(833f, 240f, 856.5f, 263.5f)\n            quadTo(880f, 287f, 880f, 320f)\n            lineTo(880f, 880f)\n            close()\n            moveTo(160f, 487f)\n            lineTo(207f, 440f)\n            lineTo(600f, 440f)\n            quadTo(600f, 440f, 600f, 440f)\n            quadTo(600f, 440f, 600f, 440f)\n            lineTo(600f, 160f)\n            quadTo(600f, 160f, 600f, 160f)\n            quadTo(600f, 160f, 600f, 160f)\n            lineTo(160f, 160f)\n            quadTo(160f, 160f, 160f, 160f)\n            quadTo(160f, 160f, 160f, 160f)\n            lineTo(160f, 487f)\n            close()\n            moveTo(80f, 680f)\n            lineTo(80f, 160f)\n            quadTo(80f, 127f, 103.5f, 103.5f)\n            quadTo(127f, 80f, 160f, 80f)\n            lineTo(600f, 80f)\n            quadTo(633f, 80f, 656.5f, 103.5f)\n            quadTo(680f, 127f, 680f, 160f)\n            lineTo(680f, 440f)\n            quadTo(680f, 473f, 656.5f, 496.5f)\n            quadTo(633f, 520f, 600f, 520f)\n            lineTo(240f, 520f)\n            lineTo(80f, 680f)\n            close()\n            moveTo(160f, 440f)\n            lineTo(160f, 160f)\n            quadTo(160f, 160f, 160f, 160f)\n            quadTo(160f, 160f, 160f, 160f)\n            lineTo(160f, 160f)\n            quadTo(160f, 160f, 160f, 160f)\n            quadTo(160f, 160f, 160f, 160f)\n            lineTo(160f, 440f)\n            quadTo(160f, 440f, 160f, 440f)\n            quadTo(160f, 440f, 160f, 440f)\n            lineTo(160f, 440f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FreeArrow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FreeArrow: ImageVector by lazy {\n    Builder(\n        name = \"FreeArrow\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(800.0f, 377.0f)\n            lineTo(621.0f, 555.0f)\n            quadToRelative(-35.0f, 35.0f, -85.0f, 35.0f)\n            reflectiveQuadToRelative(-85.0f, -35.0f)\n            lineToRelative(-47.0f, -47.0f)\n            quadToRelative(-11.0f, -11.0f, -28.0f, -11.0f)\n            reflectiveQuadToRelative(-28.0f, 11.0f)\n            lineTo(164.0f, 692.0f)\n            quadToRelative(-11.0f, 11.0f, -28.0f, 11.0f)\n            reflectiveQuadToRelative(-28.0f, -11.0f)\n            quadToRelative(-11.0f, -11.0f, -11.0f, -28.0f)\n            reflectiveQuadToRelative(11.0f, -28.0f)\n            lineToRelative(184.0f, -184.0f)\n            quadToRelative(35.0f, -35.0f, 85.0f, -35.0f)\n            reflectiveQuadToRelative(85.0f, 35.0f)\n            lineToRelative(46.0f, 46.0f)\n            quadToRelative(12.0f, 12.0f, 28.5f, 12.0f)\n            reflectiveQuadToRelative(28.5f, -12.0f)\n            lineToRelative(178.0f, -178.0f)\n            horizontalLineToRelative(-63.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(640.0f, 280.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(680.0f, 240.0f)\n            horizontalLineToRelative(160.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(880.0f, 280.0f)\n            verticalLineToRelative(160.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(840.0f, 480.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(800.0f, 440.0f)\n            verticalLineToRelative(-63.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FreeDoubleArrow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FreeDoubleArrow: ImageVector by lazy {\n    Builder(\n        name = \"FreeDoubleArrow\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(21.7125f, 6.2875f)\n            curveTo(21.5208f, 6.0958f, 21.2833f, 6.0f, 21.0f, 6.0f)\n            horizontalLineToRelative(-4.0f)\n            curveToRelative(-0.2833f, 0.0f, -0.5208f, 0.0958f, -0.7125f, 0.2875f)\n            curveTo(16.0958f, 6.4791f, 16.0f, 6.7167f, 16.0f, 7.0f)\n            reflectiveCurveToRelative(0.0958f, 0.5208f, 0.2875f, 0.7125f)\n            curveTo(16.4792f, 7.9042f, 16.7167f, 8.0f, 17.0f, 8.0f)\n            horizontalLineToRelative(1.575f)\n            lineTo(14.125f, 12.45f)\n            curveTo(13.925f, 12.65f, 13.6875f, 12.75f, 13.4125f, 12.75f)\n            curveToRelative(-0.275f, 0.0f, -0.5125f, -0.1f, -0.7125f, -0.3f)\n            lineToRelative(-1.15f, -1.15f)\n            curveToRelative(-0.5833f, -0.5833f, -1.2916f, -0.875f, -2.125f, -0.875f)\n            curveToRelative(-0.8333f, 0.0f, -1.5416f, 0.2917f, -2.125f, 0.875f)\n            lineTo(4.2344f, 14.3656f)\n            lineToRelative(-0.2177f, 0.2165f)\n            verticalLineToRelative(-1.5488f)\n            curveToRelative(0.0f, -0.2786f, -0.0942f, -0.5122f, -0.2827f, -0.7007f)\n            curveToRelative(-0.1885f, -0.1884f, -0.4221f, -0.2827f, -0.7007f, -0.2827f)\n            curveToRelative(-0.2786f, 0.0f, -0.5121f, 0.0942f, -0.7006f, 0.2827f)\n            curveToRelative(-0.1885f, 0.1885f, -0.2827f, 0.4221f, -0.2827f, 0.7007f)\n            verticalLineToRelative(3.9333f)\n            curveToRelative(0.0f, 0.2786f, 0.0942f, 0.5121f, 0.2827f, 0.7006f)\n            curveToRelative(0.1885f, 0.1885f, 0.4221f, 0.2828f, 0.7006f, 0.2828f)\n            horizontalLineToRelative(3.9333f)\n            curveToRelative(0.2786f, 0.0f, 0.5121f, -0.0942f, 0.7006f, -0.2828f)\n            curveToRelative(0.1885f, -0.1885f, 0.2827f, -0.422f, 0.2827f, -0.7006f)\n            curveToRelative(0.0f, -0.2786f, -0.0942f, -0.5122f, -0.2827f, -0.7007f)\n            curveToRelative(-0.1885f, -0.1884f, -0.422f, -0.2827f, -0.7006f, -0.2827f)\n            horizontalLineTo(5.4179f)\n            lineToRelative(1.4227f, -1.4227f)\n            curveTo(6.8403f, 14.5605f, 6.8402f, 14.5602f, 6.84f, 14.5601f)\n            lineToRelative(1.86f, -1.86f)\n            curveToRelative(0.1833f, -0.1833f, 0.4166f, -0.275f, 0.7f, -0.275f)\n            curveToRelative(0.2833f, 0.0f, 0.5167f, 0.0917f, 0.7f, 0.275f)\n            lineTo(11.275f, 13.875f)\n            curveToRelative(0.5833f, 0.5833f, 1.2916f, 0.875f, 2.125f, 0.875f)\n            curveToRelative(0.8333f, 0.0f, 1.5416f, -0.2917f, 2.125f, -0.875f)\n            lineTo(20.0f, 9.425f)\n            verticalLineTo(11.0f)\n            curveToRelative(0.0f, 0.2833f, 0.0958f, 0.5208f, 0.2875f, 0.7125f)\n            curveTo(20.4792f, 11.9042f, 20.7167f, 12.0f, 21.0f, 12.0f)\n            reflectiveCurveToRelative(0.5208f, -0.0958f, 0.7125f, -0.2875f)\n            curveTo(21.9042f, 11.5208f, 22.0f, 11.2833f, 22.0f, 11.0f)\n            verticalLineTo(7.0f)\n            curveTo(22.0f, 6.7167f, 21.9042f, 6.4791f, 21.7125f, 6.2875f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/FreeDraw.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.FreeDraw: ImageVector by lazy {\n    Builder(\n        name = \"FreeDraw\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(554.0f, 840.0f)\n            quadToRelative(-54.0f, 0.0f, -91.0f, -37.0f)\n            reflectiveQuadToRelative(-37.0f, -89.0f)\n            quadToRelative(0.0f, -76.0f, 61.5f, -137.5f)\n            reflectiveQuadTo(641.0f, 500.0f)\n            quadToRelative(-3.0f, -36.0f, -18.0f, -54.5f)\n            reflectiveQuadTo(582.0f, 427.0f)\n            quadToRelative(-30.0f, 0.0f, -65.0f, 25.0f)\n            reflectiveQuadToRelative(-83.0f, 82.0f)\n            quadToRelative(-78.0f, 93.0f, -114.5f, 121.0f)\n            reflectiveQuadTo(241.0f, 683.0f)\n            quadToRelative(-51.0f, 0.0f, -86.0f, -38.0f)\n            reflectiveQuadToRelative(-35.0f, -92.0f)\n            quadToRelative(0.0f, -54.0f, 23.5f, -110.5f)\n            reflectiveQuadTo(223.0f, 307.0f)\n            quadToRelative(19.0f, -26.0f, 28.0f, -44.0f)\n            reflectiveQuadToRelative(9.0f, -29.0f)\n            quadToRelative(0.0f, -7.0f, -2.5f, -10.5f)\n            reflectiveQuadTo(250.0f, 220.0f)\n            quadToRelative(-10.0f, 0.0f, -25.0f, 12.5f)\n            reflectiveQuadTo(190.0f, 271.0f)\n            lineToRelative(-70.0f, -71.0f)\n            quadToRelative(32.0f, -39.0f, 65.0f, -59.5f)\n            reflectiveQuadToRelative(65.0f, -20.5f)\n            quadToRelative(46.0f, 0.0f, 78.0f, 32.0f)\n            reflectiveQuadToRelative(32.0f, 80.0f)\n            quadToRelative(0.0f, 29.0f, -15.0f, 64.0f)\n            reflectiveQuadToRelative(-50.0f, 84.0f)\n            quadToRelative(-38.0f, 54.0f, -56.5f, 95.0f)\n            reflectiveQuadTo(220.0f, 547.0f)\n            quadToRelative(0.0f, 17.0f, 5.5f, 26.5f)\n            reflectiveQuadTo(241.0f, 583.0f)\n            quadToRelative(10.0f, 0.0f, 17.5f, -5.5f)\n            reflectiveQuadTo(286.0f, 551.0f)\n            quadToRelative(13.0f, -14.0f, 31.0f, -34.5f)\n            reflectiveQuadToRelative(44.0f, -50.5f)\n            quadToRelative(63.0f, -75.0f, 114.0f, -107.0f)\n            reflectiveQuadToRelative(107.0f, -32.0f)\n            quadToRelative(67.0f, 0.0f, 110.0f, 45.0f)\n            reflectiveQuadToRelative(49.0f, 123.0f)\n            horizontalLineToRelative(99.0f)\n            verticalLineToRelative(100.0f)\n            horizontalLineToRelative(-99.0f)\n            quadToRelative(-8.0f, 112.0f, -58.5f, 178.5f)\n            reflectiveQuadTo(554.0f, 840.0f)\n            close()\n            moveTo(556.0f, 740.0f)\n            quadToRelative(32.0f, 0.0f, 54.0f, -36.5f)\n            reflectiveQuadTo(640.0f, 602.0f)\n            quadToRelative(-46.0f, 11.0f, -80.0f, 43.5f)\n            reflectiveQuadTo(526.0f, 710.0f)\n            quadToRelative(0.0f, 14.0f, 8.0f, 22.0f)\n            reflectiveQuadToRelative(22.0f, 8.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Github.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Github: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Github\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(12.0f, 2.0f)\n            arcTo(\n                10.0f, 10.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 2.0f,\n                y1 = 12.0f\n            )\n            curveTo(2.0f, 16.42f, 4.87f, 20.17f, 8.84f, 21.5f)\n            curveTo(9.34f, 21.58f, 9.5f, 21.27f, 9.5f, 21.0f)\n            curveTo(9.5f, 20.77f, 9.5f, 20.14f, 9.5f, 19.31f)\n            curveTo(6.73f, 19.91f, 6.14f, 17.97f, 6.14f, 17.97f)\n            curveTo(5.68f, 16.81f, 5.03f, 16.5f, 5.03f, 16.5f)\n            curveTo(4.12f, 15.88f, 5.1f, 15.9f, 5.1f, 15.9f)\n            curveTo(6.1f, 15.97f, 6.63f, 16.93f, 6.63f, 16.93f)\n            curveTo(7.5f, 18.45f, 8.97f, 18.0f, 9.54f, 17.76f)\n            curveTo(9.63f, 17.11f, 9.89f, 16.67f, 10.17f, 16.42f)\n            curveTo(7.95f, 16.17f, 5.62f, 15.31f, 5.62f, 11.5f)\n            curveTo(5.62f, 10.39f, 6.0f, 9.5f, 6.65f, 8.79f)\n            curveTo(6.55f, 8.54f, 6.2f, 7.5f, 6.75f, 6.15f)\n            curveTo(6.75f, 6.15f, 7.59f, 5.88f, 9.5f, 7.17f)\n            curveTo(10.29f, 6.95f, 11.15f, 6.84f, 12.0f, 6.84f)\n            curveTo(12.85f, 6.84f, 13.71f, 6.95f, 14.5f, 7.17f)\n            curveTo(16.41f, 5.88f, 17.25f, 6.15f, 17.25f, 6.15f)\n            curveTo(17.8f, 7.5f, 17.45f, 8.54f, 17.35f, 8.79f)\n            curveTo(18.0f, 9.5f, 18.38f, 10.39f, 18.38f, 11.5f)\n            curveTo(18.38f, 15.32f, 16.04f, 16.16f, 13.81f, 16.41f)\n            curveTo(14.17f, 16.72f, 14.5f, 17.33f, 14.5f, 18.26f)\n            curveTo(14.5f, 19.6f, 14.5f, 20.68f, 14.5f, 21.0f)\n            curveTo(14.5f, 21.27f, 14.66f, 21.59f, 15.17f, 21.5f)\n            curveTo(19.14f, 20.16f, 22.0f, 16.42f, 22.0f, 12.0f)\n            arcTo(\n                10.0f, 10.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 12.0f,\n                y1 = 2.0f\n            )\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Glyphs.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Glyphs: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Glyphs\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(224f, 82f)\n            lineTo(302f, 82f)\n            lineTo(437f, 442f)\n            lineTo(362f, 442f)\n            lineTo(332f, 356f)\n            lineTo(194f, 356f)\n            lineTo(164f, 442f)\n            lineTo(89f, 442f)\n            lineTo(224f, 82f)\n            close()\n            moveTo(229f, 484f)\n            quadTo(271f, 484f, 300f, 513f)\n            quadTo(329f, 542f, 329f, 584f)\n            quadTo(329f, 604f, 321.5f, 622.5f)\n            quadTo(314f, 641f, 300f, 655f)\n            lineTo(285f, 669f)\n            lineTo(313f, 697f)\n            lineTo(370f, 641f)\n            lineTo(427f, 698f)\n            lineTo(371f, 754f)\n            lineTo(427f, 811f)\n            lineTo(370f, 867f)\n            lineTo(314f, 811f)\n            lineTo(272f, 853f)\n            quadTo(257f, 868f, 238f, 875.5f)\n            quadTo(219f, 883f, 198f, 883f)\n            quadTo(156f, 883f, 128f, 853.5f)\n            quadTo(100f, 824f, 100f, 782f)\n            quadTo(100f, 762f, 108f, 743.5f)\n            quadTo(116f, 725f, 130f, 711f)\n            lineTo(172f, 669f)\n            lineTo(158f, 655f)\n            quadTo(144f, 641f, 136f, 623f)\n            quadTo(128f, 605f, 128f, 585f)\n            quadTo(128f, 543f, 157.5f, 513.5f)\n            quadTo(187f, 484f, 229f, 484f)\n            close()\n            moveTo(229f, 726f)\n            lineTo(186f, 768f)\n            quadTo(183f, 771f, 182f, 774.5f)\n            quadTo(181f, 778f, 181f, 782f)\n            quadTo(181f, 790f, 186.5f, 796f)\n            quadTo(192f, 802f, 200f, 802f)\n            quadTo(204f, 802f, 207.5f, 800.5f)\n            quadTo(211f, 799f, 214f, 796f)\n            lineTo(257f, 754f)\n            lineTo(229f, 726f)\n            close()\n            moveTo(228f, 564f)\n            quadTo(220f, 564f, 214.5f, 570f)\n            quadTo(209f, 576f, 209f, 584f)\n            quadTo(209f, 588f, 210f, 591.5f)\n            quadTo(211f, 595f, 214f, 598f)\n            lineTo(229f, 612f)\n            lineTo(242f, 599f)\n            quadTo(245f, 596f, 246.5f, 592.5f)\n            quadTo(248f, 589f, 248f, 585f)\n            quadTo(248f, 577f, 242f, 570.5f)\n            quadTo(236f, 564f, 228f, 564f)\n            close()\n            moveTo(261f, 160f)\n            lineTo(215f, 294f)\n            lineTo(311f, 294f)\n            lineTo(265f, 160f)\n            lineTo(261f, 160f)\n            close()\n            moveTo(699f, 55f)\n            quadTo(707f, 68f, 712.5f, 82f)\n            quadTo(718f, 96f, 722f, 110f)\n            lineTo(679f, 123f)\n            lineTo(880f, 123f)\n            lineTo(880f, 203f)\n            lineTo(813f, 203f)\n            quadTo(802f, 236f, 784.5f, 265.5f)\n            quadTo(767f, 295f, 744f, 320f)\n            quadTo(771f, 336f, 800f, 346.5f)\n            quadTo(829f, 357f, 860f, 365f)\n            lineTo(841f, 442f)\n            quadTo(798f, 431f, 757.5f, 415f)\n            quadTo(717f, 399f, 680f, 374f)\n            quadTo(643f, 398f, 602.5f, 414.5f)\n            quadTo(562f, 431f, 519f, 442f)\n            lineTo(501f, 365f)\n            quadTo(531f, 357f, 560f, 346.5f)\n            quadTo(589f, 336f, 616f, 320f)\n            quadTo(593f, 295f, 575.5f, 265.5f)\n            quadTo(558f, 236f, 548f, 203f)\n            lineTo(480f, 203f)\n            lineTo(480f, 123f)\n            lineTo(656f, 123f)\n            quadTo(653f, 110f, 648f, 97.5f)\n            quadTo(643f, 85f, 638f, 73f)\n            lineTo(699f, 55f)\n            close()\n            moveTo(803f, 499f)\n            lineTo(860f, 555f)\n            lineTo(549f, 866f)\n            lineTo(492f, 810f)\n            lineTo(803f, 499f)\n            close()\n            moveTo(580f, 522f)\n            quadTo(605f, 522f, 622.5f, 539.5f)\n            quadTo(640f, 557f, 640f, 582f)\n            quadTo(640f, 607f, 622.5f, 624.5f)\n            quadTo(605f, 642f, 580f, 642f)\n            quadTo(555f, 642f, 537.5f, 624.5f)\n            quadTo(520f, 607f, 520f, 582f)\n            quadTo(520f, 557f, 537.5f, 539.5f)\n            quadTo(555f, 522f, 580f, 522f)\n            close()\n            moveTo(633f, 203f)\n            quadTo(641f, 222f, 653f, 239f)\n            quadTo(665f, 256f, 680f, 271f)\n            quadTo(695f, 256f, 707f, 239f)\n            quadTo(719f, 222f, 728f, 203f)\n            lineTo(633f, 203f)\n            close()\n            moveTo(780f, 722f)\n            quadTo(805f, 722f, 822.5f, 739.5f)\n            quadTo(840f, 757f, 840f, 782f)\n            quadTo(840f, 807f, 822.5f, 824.5f)\n            quadTo(805f, 842f, 780f, 842f)\n            quadTo(755f, 842f, 737.5f, 824.5f)\n            quadTo(720f, 807f, 720f, 782f)\n            quadTo(720f, 757f, 737.5f, 739.5f)\n            quadTo(755f, 722f, 780f, 722f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/GooglePlay.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.GooglePlay: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Google Play\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(3.0f, 20.5f)\n            verticalLineTo(3.5f)\n            curveTo(3.0f, 2.91f, 3.34f, 2.39f, 3.84f, 2.15f)\n            lineTo(13.69f, 12.0f)\n            lineTo(3.84f, 21.85f)\n            curveTo(3.34f, 21.6f, 3.0f, 21.09f, 3.0f, 20.5f)\n            moveTo(16.81f, 15.12f)\n            lineTo(6.05f, 21.34f)\n            lineTo(14.54f, 12.85f)\n            lineTo(16.81f, 15.12f)\n            moveTo(20.16f, 10.81f)\n            curveTo(20.5f, 11.08f, 20.75f, 11.5f, 20.75f, 12.0f)\n            curveTo(20.75f, 12.5f, 20.53f, 12.9f, 20.18f, 13.18f)\n            lineTo(17.89f, 14.5f)\n            lineTo(15.39f, 12.0f)\n            lineTo(17.89f, 9.5f)\n            lineTo(20.16f, 10.81f)\n            moveTo(6.05f, 2.66f)\n            lineTo(16.81f, 8.88f)\n            lineTo(14.54f, 11.15f)\n            lineTo(6.05f, 2.66f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Gradient.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Gradient: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Gradient\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(200f, 840f)\n            quadTo(167f, 840f, 143.5f, 816.5f)\n            quadTo(120f, 793f, 120f, 760f)\n            lineTo(120f, 200f)\n            quadTo(120f, 167f, 143.5f, 143.5f)\n            quadTo(167f, 120f, 200f, 120f)\n            lineTo(760f, 120f)\n            quadTo(793f, 120f, 816.5f, 143.5f)\n            quadTo(840f, 167f, 840f, 200f)\n            lineTo(840f, 760f)\n            quadTo(840f, 793f, 816.5f, 816.5f)\n            quadTo(793f, 840f, 760f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(440f, 440f)\n            lineTo(440f, 520f)\n            lineTo(520f, 520f)\n            lineTo(520f, 440f)\n            lineTo(440f, 440f)\n            close()\n            moveTo(280f, 440f)\n            lineTo(280f, 520f)\n            lineTo(360f, 520f)\n            lineTo(360f, 440f)\n            lineTo(280f, 440f)\n            close()\n            moveTo(360f, 520f)\n            lineTo(360f, 600f)\n            lineTo(440f, 600f)\n            lineTo(440f, 520f)\n            lineTo(360f, 520f)\n            close()\n            moveTo(520f, 520f)\n            lineTo(520f, 600f)\n            lineTo(600f, 600f)\n            lineTo(600f, 520f)\n            lineTo(520f, 520f)\n            close()\n            moveTo(200f, 520f)\n            lineTo(200f, 600f)\n            lineTo(280f, 600f)\n            lineTo(280f, 520f)\n            lineTo(200f, 520f)\n            close()\n            moveTo(600f, 440f)\n            lineTo(600f, 520f)\n            lineTo(680f, 520f)\n            lineTo(680f, 600f)\n            lineTo(760f, 600f)\n            lineTo(760f, 520f)\n            lineTo(680f, 520f)\n            lineTo(680f, 440f)\n            lineTo(600f, 440f)\n            close()\n            moveTo(280f, 600f)\n            lineTo(280f, 680f)\n            lineTo(200f, 680f)\n            lineTo(200f, 760f)\n            quadTo(200f, 760f, 200f, 760f)\n            quadTo(200f, 760f, 200f, 760f)\n            lineTo(280f, 760f)\n            lineTo(280f, 680f)\n            lineTo(360f, 680f)\n            lineTo(360f, 760f)\n            lineTo(440f, 760f)\n            lineTo(440f, 680f)\n            lineTo(520f, 680f)\n            lineTo(520f, 760f)\n            lineTo(600f, 760f)\n            lineTo(600f, 680f)\n            lineTo(680f, 680f)\n            lineTo(680f, 760f)\n            lineTo(760f, 760f)\n            quadTo(760f, 760f, 760f, 760f)\n            quadTo(760f, 760f, 760f, 760f)\n            lineTo(760f, 680f)\n            lineTo(680f, 680f)\n            lineTo(680f, 600f)\n            lineTo(600f, 600f)\n            lineTo(600f, 680f)\n            lineTo(520f, 680f)\n            lineTo(520f, 600f)\n            lineTo(440f, 600f)\n            lineTo(440f, 680f)\n            lineTo(360f, 680f)\n            lineTo(360f, 600f)\n            lineTo(280f, 600f)\n            close()\n            moveTo(760f, 440f)\n            lineTo(760f, 440f)\n            lineTo(760f, 520f)\n            lineTo(760f, 520f)\n            lineTo(760f, 440f)\n            close()\n            moveTo(760f, 600f)\n            lineTo(760f, 680f)\n            lineTo(760f, 680f)\n            lineTo(760f, 600f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Group.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Group: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Group\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(1f, 1f)\n            verticalLineTo(5f)\n            horizontalLineTo(2f)\n            verticalLineTo(19f)\n            horizontalLineTo(1f)\n            verticalLineTo(23f)\n            horizontalLineTo(5f)\n            verticalLineTo(22f)\n            horizontalLineTo(19f)\n            verticalLineTo(23f)\n            horizontalLineTo(23f)\n            verticalLineTo(19f)\n            horizontalLineTo(22f)\n            verticalLineTo(5f)\n            horizontalLineTo(23f)\n            verticalLineTo(1f)\n            horizontalLineTo(19f)\n            verticalLineTo(2f)\n            horizontalLineTo(5f)\n            verticalLineTo(1f)\n            moveTo(5f, 4f)\n            horizontalLineTo(19f)\n            verticalLineTo(5f)\n            horizontalLineTo(20f)\n            verticalLineTo(19f)\n            horizontalLineTo(19f)\n            verticalLineTo(20f)\n            horizontalLineTo(5f)\n            verticalLineTo(19f)\n            horizontalLineTo(4f)\n            verticalLineTo(5f)\n            horizontalLineTo(5f)\n            moveTo(6f, 6f)\n            verticalLineTo(14f)\n            horizontalLineTo(9f)\n            verticalLineTo(18f)\n            horizontalLineTo(18f)\n            verticalLineTo(9f)\n            horizontalLineTo(14f)\n            verticalLineTo(6f)\n            moveTo(8f, 8f)\n            horizontalLineTo(12f)\n            verticalLineTo(12f)\n            horizontalLineTo(8f)\n            moveTo(14f, 11f)\n            horizontalLineTo(16f)\n            verticalLineTo(16f)\n            horizontalLineTo(11f)\n            verticalLineTo(14f)\n            horizontalLineTo(14f)\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/HandshakeAlt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.HandshakeAlt: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"HandshakeAltOutline\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(21.71f, 8.71f)\n            curveTo(22.96f, 7.46f, 22.39f, 6f, 21.71f, 5.29f)\n            lineTo(18.71f, 2.29f)\n            curveTo(17.45f, 1.04f, 16f, 1.61f, 15.29f, 2.29f)\n            lineTo(13.59f, 4f)\n            horizontalLineTo(11f)\n            curveTo(9.1f, 4f, 8f, 5f, 7.44f, 6.15f)\n            lineTo(3f, 10.59f)\n            verticalLineTo(14.59f)\n            lineTo(2.29f, 15.29f)\n            curveTo(1.04f, 16.55f, 1.61f, 18f, 2.29f, 18.71f)\n            lineTo(5.29f, 21.71f)\n            curveTo(5.83f, 22.25f, 6.41f, 22.45f, 6.96f, 22.45f)\n            curveTo(7.67f, 22.45f, 8.32f, 22.1f, 8.71f, 21.71f)\n            lineTo(11.41f, 19f)\n            horizontalLineTo(15f)\n            curveTo(16.7f, 19f, 17.56f, 17.94f, 17.87f, 16.9f)\n            curveTo(19f, 16.6f, 19.62f, 15.74f, 19.87f, 14.9f)\n            curveTo(21.42f, 14.5f, 22f, 13.03f, 22f, 12f)\n            verticalLineTo(9f)\n            horizontalLineTo(21.41f)\n            lineTo(21.71f, 8.71f)\n            moveTo(20f, 12f)\n            curveTo(20f, 12.45f, 19.81f, 13f, 19f, 13f)\n            lineTo(18f, 13f)\n            lineTo(18f, 14f)\n            curveTo(18f, 14.45f, 17.81f, 15f, 17f, 15f)\n            lineTo(16f, 15f)\n            lineTo(16f, 16f)\n            curveTo(16f, 16.45f, 15.81f, 17f, 15f, 17f)\n            horizontalLineTo(10.59f)\n            lineTo(7.31f, 20.28f)\n            curveTo(7f, 20.57f, 6.82f, 20.4f, 6.71f, 20.29f)\n            lineTo(3.72f, 17.31f)\n            curveTo(3.43f, 17f, 3.6f, 16.82f, 3.71f, 16.71f)\n            lineTo(5f, 15.41f)\n            verticalLineTo(11.41f)\n            lineTo(7f, 9.41f)\n            verticalLineTo(11f)\n            curveTo(7f, 12.21f, 7.8f, 14f, 10f, 14f)\n            reflectiveCurveTo(13f, 12.21f, 13f, 11f)\n            horizontalLineTo(20f)\n            verticalLineTo(12f)\n            moveTo(20.29f, 7.29f)\n            lineTo(18.59f, 9f)\n            horizontalLineTo(11f)\n            verticalLineTo(11f)\n            curveTo(11f, 11.45f, 10.81f, 12f, 10f, 12f)\n            reflectiveCurveTo(9f, 11.45f, 9f, 11f)\n            verticalLineTo(8f)\n            curveTo(9f, 7.54f, 9.17f, 6f, 11f, 6f)\n            horizontalLineTo(14.41f)\n            lineTo(16.69f, 3.72f)\n            curveTo(17f, 3.43f, 17.18f, 3.6f, 17.29f, 3.71f)\n            lineTo(20.28f, 6.69f)\n            curveTo(20.57f, 7f, 20.4f, 7.18f, 20.29f, 7.29f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/HardDrive.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.HardDrive: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.HardDrive\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(680f, 640f)\n            quadTo(705f, 640f, 722.5f, 623f)\n            quadTo(740f, 606f, 740f, 580f)\n            quadTo(740f, 555f, 722.5f, 537.5f)\n            quadTo(705f, 520f, 680f, 520f)\n            quadTo(654f, 520f, 637f, 537.5f)\n            quadTo(620f, 555f, 620f, 580f)\n            quadTo(620f, 606f, 637f, 623f)\n            quadTo(654f, 640f, 680f, 640f)\n            close()\n            moveTo(80f, 360f)\n            lineTo(216f, 224f)\n            quadTo(227f, 213f, 241.5f, 206.5f)\n            quadTo(256f, 200f, 273f, 200f)\n            lineTo(686f, 200f)\n            quadTo(703f, 200f, 717.5f, 206.5f)\n            quadTo(732f, 213f, 743f, 224f)\n            lineTo(880f, 360f)\n            lineTo(80f, 360f)\n            close()\n            moveTo(160f, 760f)\n            quadTo(126f, 760f, 103f, 737f)\n            quadTo(80f, 714f, 80f, 680f)\n            lineTo(80f, 440f)\n            lineTo(880f, 440f)\n            lineTo(880f, 680f)\n            quadTo(880f, 714f, 856.5f, 737f)\n            quadTo(833f, 760f, 800f, 760f)\n            lineTo(160f, 760f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/HighRes.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.HighRes: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.HighRes\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(180f, 740f)\n            lineTo(240f, 740f)\n            lineTo(240f, 660f)\n            lineTo(264f, 660f)\n            lineTo(300f, 740f)\n            lineTo(360f, 740f)\n            lineTo(324f, 656f)\n            quadTo(339f, 647f, 349.5f, 632.5f)\n            quadTo(360f, 618f, 360f, 600f)\n            lineTo(360f, 560f)\n            quadTo(360f, 535f, 342.5f, 517.5f)\n            quadTo(325f, 500f, 300f, 500f)\n            lineTo(180f, 500f)\n            lineTo(180f, 740f)\n            close()\n            moveTo(400f, 740f)\n            lineTo(560f, 740f)\n            lineTo(560f, 680f)\n            lineTo(460f, 680f)\n            lineTo(460f, 650f)\n            lineTo(540f, 650f)\n            lineTo(540f, 590f)\n            lineTo(460f, 590f)\n            lineTo(460f, 560f)\n            lineTo(560f, 560f)\n            lineTo(560f, 500f)\n            lineTo(400f, 500f)\n            lineTo(400f, 740f)\n            close()\n            moveTo(600f, 740f)\n            lineTo(740f, 740f)\n            quadTo(757f, 740f, 768.5f, 728.5f)\n            quadTo(780f, 717f, 780f, 700f)\n            lineTo(780f, 640f)\n            quadTo(780f, 623f, 768.5f, 611.5f)\n            quadTo(757f, 600f, 740f, 600f)\n            lineTo(660f, 600f)\n            lineTo(660f, 560f)\n            lineTo(780f, 560f)\n            lineTo(780f, 500f)\n            lineTo(640f, 500f)\n            quadTo(623f, 500f, 611.5f, 511.5f)\n            quadTo(600f, 523f, 600f, 540f)\n            lineTo(600f, 600f)\n            quadTo(600f, 617f, 611.5f, 628.5f)\n            quadTo(623f, 640f, 640f, 640f)\n            lineTo(720f, 640f)\n            lineTo(720f, 680f)\n            lineTo(600f, 680f)\n            lineTo(600f, 740f)\n            close()\n            moveTo(240f, 600f)\n            lineTo(240f, 560f)\n            lineTo(300f, 560f)\n            quadTo(300f, 560f, 300f, 560f)\n            quadTo(300f, 560f, 300f, 560f)\n            lineTo(300f, 600f)\n            quadTo(300f, 600f, 300f, 600f)\n            quadTo(300f, 600f, 300f, 600f)\n            lineTo(240f, 600f)\n            close()\n            moveTo(300f, 460f)\n            lineTo(360f, 460f)\n            lineTo(360f, 370f)\n            lineTo(420f, 370f)\n            lineTo(420f, 460f)\n            lineTo(480f, 460f)\n            lineTo(480f, 220f)\n            lineTo(420f, 220f)\n            lineTo(420f, 310f)\n            lineTo(360f, 310f)\n            lineTo(360f, 220f)\n            lineTo(300f, 220f)\n            lineTo(300f, 460f)\n            close()\n            moveTo(580f, 460f)\n            lineTo(640f, 460f)\n            lineTo(640f, 220f)\n            lineTo(580f, 220f)\n            lineTo(580f, 460f)\n            close()\n            moveTo(120f, 840f)\n            quadTo(87f, 840f, 63.5f, 816.5f)\n            quadTo(40f, 793f, 40f, 760f)\n            lineTo(40f, 200f)\n            quadTo(40f, 167f, 63.5f, 143.5f)\n            quadTo(87f, 120f, 120f, 120f)\n            lineTo(840f, 120f)\n            quadTo(873f, 120f, 896.5f, 143.5f)\n            quadTo(920f, 167f, 920f, 200f)\n            lineTo(920f, 760f)\n            quadTo(920f, 793f, 896.5f, 816.5f)\n            quadTo(873f, 840f, 840f, 840f)\n            lineTo(120f, 840f)\n            close()\n            moveTo(120f, 760f)\n            lineTo(840f, 760f)\n            quadTo(840f, 760f, 840f, 760f)\n            quadTo(840f, 760f, 840f, 760f)\n            lineTo(840f, 200f)\n            quadTo(840f, 200f, 840f, 200f)\n            quadTo(840f, 200f, 840f, 200f)\n            lineTo(120f, 200f)\n            quadTo(120f, 200f, 120f, 200f)\n            quadTo(120f, 200f, 120f, 200f)\n            lineTo(120f, 760f)\n            quadTo(120f, 760f, 120f, 760f)\n            quadTo(120f, 760f, 120f, 760f)\n            close()\n            moveTo(120f, 760f)\n            quadTo(120f, 760f, 120f, 760f)\n            quadTo(120f, 760f, 120f, 760f)\n            lineTo(120f, 200f)\n            quadTo(120f, 200f, 120f, 200f)\n            quadTo(120f, 200f, 120f, 200f)\n            lineTo(120f, 200f)\n            quadTo(120f, 200f, 120f, 200f)\n            quadTo(120f, 200f, 120f, 200f)\n            lineTo(120f, 760f)\n            quadTo(120f, 760f, 120f, 760f)\n            quadTo(120f, 760f, 120f, 760f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.HighRes: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.HighRes\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(180f, 740f)\n            lineTo(240f, 740f)\n            lineTo(240f, 660f)\n            lineTo(264f, 660f)\n            lineTo(300f, 740f)\n            lineTo(360f, 740f)\n            lineTo(324f, 656f)\n            quadTo(339f, 647f, 349.5f, 632.5f)\n            quadTo(360f, 618f, 360f, 600f)\n            lineTo(360f, 560f)\n            quadTo(360f, 535f, 342.5f, 517.5f)\n            quadTo(325f, 500f, 300f, 500f)\n            lineTo(180f, 500f)\n            lineTo(180f, 740f)\n            close()\n            moveTo(400f, 740f)\n            lineTo(560f, 740f)\n            lineTo(560f, 680f)\n            lineTo(460f, 680f)\n            lineTo(460f, 650f)\n            lineTo(540f, 650f)\n            lineTo(540f, 590f)\n            lineTo(460f, 590f)\n            lineTo(460f, 560f)\n            lineTo(560f, 560f)\n            lineTo(560f, 500f)\n            lineTo(400f, 500f)\n            lineTo(400f, 740f)\n            close()\n            moveTo(600f, 740f)\n            lineTo(740f, 740f)\n            quadTo(757f, 740f, 768.5f, 728.5f)\n            quadTo(780f, 717f, 780f, 700f)\n            lineTo(780f, 640f)\n            quadTo(780f, 623f, 768.5f, 611.5f)\n            quadTo(757f, 600f, 740f, 600f)\n            lineTo(660f, 600f)\n            lineTo(660f, 560f)\n            lineTo(780f, 560f)\n            lineTo(780f, 500f)\n            lineTo(640f, 500f)\n            quadTo(623f, 500f, 611.5f, 511.5f)\n            quadTo(600f, 523f, 600f, 540f)\n            lineTo(600f, 600f)\n            quadTo(600f, 617f, 611.5f, 628.5f)\n            quadTo(623f, 640f, 640f, 640f)\n            lineTo(720f, 640f)\n            lineTo(720f, 680f)\n            lineTo(600f, 680f)\n            lineTo(600f, 740f)\n            close()\n            moveTo(240f, 600f)\n            lineTo(240f, 560f)\n            lineTo(300f, 560f)\n            quadTo(300f, 560f, 300f, 560f)\n            quadTo(300f, 560f, 300f, 560f)\n            lineTo(300f, 600f)\n            quadTo(300f, 600f, 300f, 600f)\n            quadTo(300f, 600f, 300f, 600f)\n            lineTo(240f, 600f)\n            close()\n            moveTo(300f, 460f)\n            lineTo(360f, 460f)\n            lineTo(360f, 370f)\n            lineTo(420f, 370f)\n            lineTo(420f, 460f)\n            lineTo(480f, 460f)\n            lineTo(480f, 220f)\n            lineTo(420f, 220f)\n            lineTo(420f, 310f)\n            lineTo(360f, 310f)\n            lineTo(360f, 220f)\n            lineTo(300f, 220f)\n            lineTo(300f, 460f)\n            close()\n            moveTo(580f, 460f)\n            lineTo(640f, 460f)\n            lineTo(640f, 220f)\n            lineTo(580f, 220f)\n            lineTo(580f, 460f)\n            close()\n            moveTo(120f, 840f)\n            quadTo(87f, 840f, 63.5f, 816.5f)\n            quadTo(40f, 793f, 40f, 760f)\n            lineTo(40f, 200f)\n            quadTo(40f, 167f, 63.5f, 143.5f)\n            quadTo(87f, 120f, 120f, 120f)\n            lineTo(840f, 120f)\n            quadTo(873f, 120f, 896.5f, 143.5f)\n            quadTo(920f, 167f, 920f, 200f)\n            lineTo(920f, 760f)\n            quadTo(920f, 793f, 896.5f, 816.5f)\n            quadTo(873f, 840f, 840f, 840f)\n            lineTo(120f, 840f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Highlighter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Highlighter: ImageVector by lazy {\n    Builder(\n        name = \"Highlighter\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(544f, 560f)\n            lineTo(440f, 456f)\n            lineTo(240f, 656f)\n            quadTo(240f, 656f, 240f, 656f)\n            quadTo(240f, 656f, 240f, 656f)\n            lineTo(344f, 760f)\n            quadTo(344f, 760f, 344f, 760f)\n            quadTo(344f, 760f, 344f, 760f)\n            lineTo(544f, 560f)\n            close()\n            moveTo(497f, 399f)\n            lineTo(601f, 503f)\n            lineTo(800f, 304f)\n            quadTo(800f, 304f, 800f, 304f)\n            quadTo(800f, 304f, 800f, 304f)\n            lineTo(696f, 200f)\n            quadTo(696f, 200f, 696f, 200f)\n            quadTo(696f, 200f, 696f, 200f)\n            lineTo(497f, 399f)\n            close()\n            moveTo(413f, 371f)\n            lineTo(629f, 587f)\n            lineTo(400f, 816f)\n            quadTo(376f, 840f, 344f, 840f)\n            quadTo(312f, 840f, 288f, 816f)\n            lineTo(286f, 814f)\n            lineTo(283f, 817f)\n            quadTo(272f, 828f, 257.5f, 834f)\n            quadTo(243f, 840f, 227f, 840f)\n            lineTo(108f, 840f)\n            quadTo(94f, 840f, 89f, 828f)\n            quadTo(84f, 816f, 94f, 806f)\n            lineTo(186f, 714f)\n            lineTo(184f, 712f)\n            quadTo(160f, 688f, 160f, 656f)\n            quadTo(160f, 624f, 184f, 600f)\n            lineTo(413f, 371f)\n            close()\n            moveTo(413f, 371f)\n            lineTo(640f, 144f)\n            quadTo(664f, 120f, 696f, 120f)\n            quadTo(728f, 120f, 752f, 144f)\n            lineTo(856f, 248f)\n            quadTo(880f, 272f, 880f, 304f)\n            quadTo(880f, 336f, 856f, 360f)\n            lineTo(629f, 587f)\n            lineTo(413f, 371f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/HistoryCreate.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.HistoryCreate: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.HistoryEdu\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(320f, 800f)\n            quadTo(287f, 800f, 263.5f, 776.5f)\n            quadTo(240f, 753f, 240f, 720f)\n            lineTo(240f, 600f)\n            lineTo(360f, 600f)\n            lineTo(360f, 510f)\n            quadTo(325f, 508f, 293.5f, 494.5f)\n            quadTo(262f, 481f, 236f, 454f)\n            lineTo(236f, 410f)\n            lineTo(190f, 410f)\n            lineTo(60f, 280f)\n            quadTo(96f, 234f, 149f, 215f)\n            quadTo(202f, 196f, 256f, 196f)\n            quadTo(283f, 196f, 308.5f, 200f)\n            quadTo(334f, 204f, 360f, 215f)\n            lineTo(360f, 160f)\n            lineTo(840f, 160f)\n            lineTo(840f, 680f)\n            quadTo(840f, 730f, 805f, 765f)\n            quadTo(770f, 800f, 720f, 800f)\n            lineTo(320f, 800f)\n            close()\n            moveTo(440f, 600f)\n            lineTo(680f, 600f)\n            lineTo(680f, 680f)\n            quadTo(680f, 697f, 691.5f, 708.5f)\n            quadTo(703f, 720f, 720f, 720f)\n            quadTo(737f, 720f, 748.5f, 708.5f)\n            quadTo(760f, 697f, 760f, 680f)\n            lineTo(760f, 240f)\n            lineTo(440f, 240f)\n            lineTo(440f, 264f)\n            lineTo(680f, 504f)\n            lineTo(680f, 560f)\n            lineTo(624f, 560f)\n            lineTo(510f, 446f)\n            lineTo(502f, 454f)\n            quadTo(488f, 468f, 472.5f, 479f)\n            quadTo(457f, 490f, 440f, 496f)\n            lineTo(440f, 600f)\n            close()\n            moveTo(224f, 330f)\n            lineTo(316f, 330f)\n            lineTo(316f, 416f)\n            quadTo(328f, 424f, 341f, 427f)\n            quadTo(354f, 430f, 368f, 430f)\n            quadTo(391f, 430f, 409.5f, 423f)\n            quadTo(428f, 416f, 446f, 398f)\n            lineTo(454f, 390f)\n            lineTo(398f, 334f)\n            quadTo(369f, 305f, 333f, 290.5f)\n            quadTo(297f, 276f, 256f, 276f)\n            quadTo(236f, 276f, 218f, 279f)\n            quadTo(200f, 282f, 182f, 288f)\n            lineTo(224f, 330f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.HistoryCreate: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.HistoryEdu\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(320f, 800f)\n            quadTo(287f, 800f, 263.5f, 776.5f)\n            quadTo(240f, 753f, 240f, 720f)\n            lineTo(240f, 600f)\n            lineTo(360f, 600f)\n            lineTo(360f, 510f)\n            quadTo(325f, 508f, 293.5f, 494.5f)\n            quadTo(262f, 481f, 236f, 454f)\n            lineTo(236f, 410f)\n            lineTo(190f, 410f)\n            lineTo(60f, 280f)\n            quadTo(96f, 234f, 149f, 215f)\n            quadTo(202f, 196f, 256f, 196f)\n            quadTo(283f, 196f, 308.5f, 200f)\n            quadTo(334f, 204f, 360f, 215f)\n            lineTo(360f, 160f)\n            lineTo(840f, 160f)\n            lineTo(840f, 680f)\n            quadTo(840f, 730f, 805f, 765f)\n            quadTo(770f, 800f, 720f, 800f)\n            lineTo(320f, 800f)\n            close()\n            moveTo(440f, 600f)\n            lineTo(680f, 600f)\n            lineTo(680f, 680f)\n            quadTo(680f, 697f, 691.5f, 708.5f)\n            quadTo(703f, 720f, 720f, 720f)\n            quadTo(737f, 720f, 748.5f, 708.5f)\n            quadTo(760f, 697f, 760f, 680f)\n            lineTo(760f, 240f)\n            lineTo(440f, 240f)\n            lineTo(440f, 264f)\n            lineTo(680f, 504f)\n            lineTo(680f, 560f)\n            lineTo(624f, 560f)\n            lineTo(510f, 446f)\n            lineTo(502f, 454f)\n            quadTo(488f, 468f, 472.5f, 479f)\n            quadTo(457f, 490f, 440f, 496f)\n            lineTo(440f, 600f)\n            close()\n            moveTo(224f, 330f)\n            lineTo(316f, 330f)\n            lineTo(316f, 416f)\n            quadTo(328f, 424f, 341f, 427f)\n            quadTo(354f, 430f, 368f, 430f)\n            quadTo(391f, 430f, 409.5f, 423f)\n            quadTo(428f, 416f, 446f, 398f)\n            lineTo(454f, 390f)\n            lineTo(398f, 334f)\n            quadTo(369f, 305f, 333f, 290.5f)\n            quadTo(297f, 276f, 256f, 276f)\n            quadTo(236f, 276f, 218f, 279f)\n            quadTo(200f, 282f, 182f, 288f)\n            lineTo(224f, 330f)\n            close()\n            moveTo(600f, 680f)\n            lineTo(320f, 680f)\n            lineTo(320f, 720f)\n            quadTo(320f, 720f, 320f, 720f)\n            quadTo(320f, 720f, 320f, 720f)\n            lineTo(606f, 720f)\n            quadTo(603f, 711f, 601.5f, 701f)\n            quadTo(600f, 691f, 600f, 680f)\n            close()\n            moveTo(320f, 720f)\n            quadTo(320f, 711f, 320f, 701f)\n            quadTo(320f, 691f, 320f, 680f)\n            lineTo(320f, 680f)\n            quadTo(320f, 690f, 320f, 700f)\n            quadTo(320f, 710f, 320f, 720f)\n            lineTo(320f, 720f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/HyperOS.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.HyperOS: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.HyperOS\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF1D1D1B)),\n            pathFillType = PathFillType.EvenOdd\n        ) {\n            moveTo(13.899f, 3.031f)\n            curveToRelative(-0.089f, -0f, -0.187f, 0.022f, -0.295f, 0.051f)\n            curveToRelative(-0.192f, 0.051f, -0.346f, 0.104f, -0.425f, 0.242f)\n            curveToRelative(-0.08f, 0.138f, -0.049f, 0.297f, 0.002f, 0.489f)\n            curveToRelative(0.051f, 0.191f, 0.105f, 0.345f, 0.243f, 0.425f)\n            horizontalLineToRelative(0f)\n            curveToRelative(0.138f, 0.079f, 0.298f, 0.049f, 0.49f, -0.002f)\n            curveToRelative(0.192f, -0.051f, 0.345f, -0.106f, 0.425f, -0.243f)\n            curveToRelative(0.08f, -0.138f, 0.049f, -0.297f, -0.002f, -0.488f)\n            curveToRelative(-0.051f, -0.191f, -0.104f, -0.345f, -0.243f, -0.424f)\n            curveToRelative(-0.06f, -0.035f, -0.125f, -0.048f, -0.195f, -0.048f)\n            lineToRelative(0f, -0f)\n            close()\n            moveTo(9.322f, 3.238f)\n            curveToRelative(-0.156f, -0f, -0.277f, 0.104f, -0.415f, 0.242f)\n            curveToRelative(-0.138f, 0.138f, -0.242f, 0.258f, -0.242f, 0.414f)\n            curveToRelative(0.001f, 0.156f, 0.104f, 0.277f, 0.242f, 0.414f)\n            curveToRelative(0.138f, 0.138f, 0.259f, 0.241f, 0.416f, 0.241f)\n            curveToRelative(0.156f, 0f, 0.277f, -0.104f, 0.414f, -0.242f)\n            curveToRelative(0.138f, -0.137f, 0.242f, -0.258f, 0.242f, -0.414f)\n            curveToRelative(0f, -0.156f, -0.105f, -0.277f, -0.243f, -0.414f)\n            curveToRelative(-0.138f, -0.138f, -0.258f, -0.242f, -0.415f, -0.242f)\n            horizontalLineToRelative(-0f)\n            close()\n            moveTo(11.974f, 3.796f)\n            curveToRelative(-0.211f, -0f, -0.373f, 0.141f, -0.559f, 0.326f)\n            curveToRelative(-0.186f, 0.185f, -0.327f, 0.348f, -0.326f, 0.559f)\n            curveToRelative(0f, 0.21f, 0.14f, 0.374f, 0.326f, 0.559f)\n            curveToRelative(0.186f, 0.185f, 0.349f, 0.325f, 0.56f, 0.325f)\n            curveToRelative(0.211f, 0f, 0.373f, -0.141f, 0.559f, -0.326f)\n            curveToRelative(0.185f, -0.185f, 0.327f, -0.347f, 0.326f, -0.558f)\n            curveToRelative(0f, -0.211f, -0.141f, -0.373f, -0.327f, -0.558f)\n            curveToRelative(-0.186f, -0.185f, -0.348f, -0.326f, -0.559f, -0.326f)\n            close()\n            moveTo(8.108f, 4.841f)\n            curveToRelative(-0.091f, 0f, -0.176f, 0.018f, -0.255f, 0.064f)\n            curveToRelative(-0.181f, 0.104f, -0.25f, 0.305f, -0.318f, 0.556f)\n            curveToRelative(-0.067f, 0.25f, -0.108f, 0.459f, -0.003f, 0.64f)\n            curveToRelative(0.105f, 0.181f, 0.306f, 0.251f, 0.557f, 0.319f)\n            curveToRelative(0.251f, 0.067f, 0.46f, 0.106f, 0.641f, 0.002f)\n            curveToRelative(0.181f, -0.104f, 0.251f, -0.305f, 0.318f, -0.556f)\n            curveToRelative(0.067f, -0.251f, 0.108f, -0.459f, 0.003f, -0.64f)\n            curveToRelative(-0.105f, -0.181f, -0.306f, -0.25f, -0.557f, -0.317f)\n            curveToRelative(-0.141f, -0.038f, -0.269f, -0.067f, -0.386f, -0.067f)\n            lineToRelative(0f, 0f)\n            close()\n            moveTo(15.834f, 4.841f)\n            curveToRelative(-0.117f, -0f, -0.245f, 0.029f, -0.386f, 0.067f)\n            curveToRelative(-0.251f, 0.067f, -0.453f, 0.137f, -0.557f, 0.317f)\n            curveToRelative(-0.105f, 0.181f, -0.064f, 0.389f, 0.003f, 0.64f)\n            curveToRelative(0.067f, 0.251f, 0.137f, 0.452f, 0.318f, 0.556f)\n            curveToRelative(0.181f, 0.104f, 0.39f, 0.065f, 0.641f, -0.002f)\n            curveToRelative(0.251f, -0.067f, 0.452f, -0.138f, 0.557f, -0.319f)\n            curveToRelative(0.105f, -0.181f, 0.064f, -0.389f, -0.003f, -0.64f)\n            curveToRelative(-0.067f, -0.25f, -0.137f, -0.452f, -0.318f, -0.556f)\n            curveToRelative(-0.079f, -0.046f, -0.164f, -0.063f, -0.255f, -0.064f)\n            verticalLineToRelative(-0f)\n            close()\n            moveTo(17.563f, 5.054f)\n            curveToRelative(-0.07f, 0f, -0.134f, 0.014f, -0.195f, 0.048f)\n            curveToRelative(-0.138f, 0.08f, -0.191f, 0.233f, -0.242f, 0.424f)\n            curveToRelative(-0.051f, 0.191f, -0.082f, 0.351f, -0.002f, 0.488f)\n            curveToRelative(0.08f, 0.138f, 0.233f, 0.192f, 0.425f, 0.243f)\n            curveToRelative(0.191f, 0.051f, 0.351f, 0.081f, 0.49f, 0.002f)\n            horizontalLineToRelative(0f)\n            curveToRelative(0.138f, -0.079f, 0.192f, -0.233f, 0.243f, -0.425f)\n            curveToRelative(0.051f, -0.191f, 0.082f, -0.351f, 0.002f, -0.489f)\n            curveToRelative(-0.08f, -0.138f, -0.234f, -0.191f, -0.425f, -0.242f)\n            curveToRelative(-0.108f, -0.029f, -0.206f, -0.051f, -0.295f, -0.051f)\n            lineToRelative(0f, 0f)\n            close()\n            moveTo(10.321f, 5.359f)\n            curveToRelative(-0.047f, 0.001f, -0.093f, 0.007f, -0.141f, 0.019f)\n            curveToRelative(-0.252f, 0.067f, -0.4f, 0.287f, -0.562f, 0.567f)\n            curveToRelative(-0.162f, 0.28f, -0.278f, 0.518f, -0.211f, 0.77f)\n            curveToRelative(0.068f, 0.251f, 0.287f, 0.401f, 0.568f, 0.563f)\n            curveToRelative(0.28f, 0.162f, 0.52f, 0.276f, 0.771f, 0.209f)\n            curveToRelative(0.252f, -0.067f, 0.401f, -0.287f, 0.563f, -0.567f)\n            curveToRelative(0.162f, -0.28f, 0.278f, -0.519f, 0.211f, -0.77f)\n            curveToRelative(-0.068f, -0.251f, -0.288f, -0.4f, -0.569f, -0.562f)\n            curveToRelative(-0.228f, -0.132f, -0.429f, -0.233f, -0.631f, -0.23f)\n            lineToRelative(-0f, -0f)\n            close()\n            moveTo(13.618f, 5.359f)\n            curveToRelative(-0.202f, -0.003f, -0.403f, 0.099f, -0.631f, 0.23f)\n            curveToRelative(-0.281f, 0.162f, -0.501f, 0.31f, -0.569f, 0.562f)\n            curveToRelative(-0.068f, 0.251f, 0.049f, 0.49f, 0.211f, 0.77f)\n            curveToRelative(0.162f, 0.28f, 0.311f, 0.5f, 0.563f, 0.567f)\n            curveToRelative(0.251f, 0.067f, 0.491f, -0.048f, 0.771f, -0.209f)\n            curveToRelative(0.281f, -0.162f, 0.5f, -0.312f, 0.568f, -0.563f)\n            curveToRelative(0.068f, -0.251f, -0.049f, -0.49f, -0.211f, -0.77f)\n            curveToRelative(-0.162f, -0.28f, -0.311f, -0.5f, -0.562f, -0.567f)\n            curveToRelative(-0.047f, -0.013f, -0.094f, -0.019f, -0.141f, -0.019f)\n            verticalLineToRelative(0f)\n            close()\n            moveTo(5.459f, 5.681f)\n            curveToRelative(-0.07f, 0f, -0.134f, 0.014f, -0.195f, 0.048f)\n            curveToRelative(-0.138f, 0.08f, -0.191f, 0.233f, -0.242f, 0.424f)\n            curveToRelative(-0.051f, 0.191f, -0.082f, 0.351f, -0.002f, 0.488f)\n            curveToRelative(0.08f, 0.138f, 0.233f, 0.192f, 0.425f, 0.243f)\n            curveToRelative(0.192f, 0.051f, 0.351f, 0.081f, 0.49f, 0.002f)\n            curveToRelative(0.138f, -0.079f, 0.192f, -0.233f, 0.243f, -0.425f)\n            curveToRelative(0.051f, -0.191f, 0.082f, -0.351f, 0.002f, -0.489f)\n            curveToRelative(-0.08f, -0.138f, -0.234f, -0.191f, -0.425f, -0.242f)\n            curveToRelative(-0.108f, -0.029f, -0.206f, -0.051f, -0.295f, -0.051f)\n            lineToRelative(0f, 0f)\n            close()\n            moveTo(7.864f, 6.961f)\n            curveToRelative(-0.323f, 0f, -0.587f, 0.019f, -0.771f, 0.202f)\n            curveToRelative(-0.184f, 0.183f, -0.202f, 0.447f, -0.202f, 0.769f)\n            curveToRelative(0f, 0.323f, 0.019f, 0.587f, 0.203f, 0.769f)\n            curveToRelative(0.184f, 0.183f, 0.448f, 0.203f, 0.77f, 0.203f)\n            curveToRelative(0.323f, -0f, 0.587f, -0.021f, 0.771f, -0.204f)\n            curveToRelative(0.184f, -0.183f, 0.202f, -0.447f, 0.202f, -0.769f)\n            curveToRelative(0f, -0.322f, -0.019f, -0.586f, -0.202f, -0.769f)\n            curveToRelative(-0.183f, -0.183f, -0.448f, -0.202f, -0.771f, -0.202f)\n            close()\n            moveTo(16.082f, 6.961f)\n            curveToRelative(-0.323f, 0f, -0.587f, 0.019f, -0.771f, 0.202f)\n            curveToRelative(-0.184f, 0.183f, -0.202f, 0.447f, -0.202f, 0.769f)\n            curveToRelative(0f, 0.323f, 0.019f, 0.587f, 0.203f, 0.769f)\n            curveToRelative(0.184f, 0.183f, 0.448f, 0.203f, 0.77f, 0.203f)\n            curveToRelative(0.323f, -0f, 0.587f, -0.021f, 0.771f, -0.204f)\n            curveToRelative(0.184f, -0.183f, 0.202f, -0.447f, 0.202f, -0.769f)\n            reflectiveCurveToRelative(-0.018f, -0.586f, -0.202f, -0.769f)\n            curveToRelative(-0.183f, -0.183f, -0.448f, -0.202f, -0.771f, -0.202f)\n            horizontalLineToRelative(0f)\n            close()\n            moveTo(5.78f, 7.536f)\n            curveToRelative(-0.117f, -0f, -0.245f, 0.029f, -0.387f, 0.067f)\n            curveToRelative(-0.251f, 0.067f, -0.453f, 0.137f, -0.557f, 0.317f)\n            curveToRelative(-0.105f, 0.181f, -0.064f, 0.389f, 0.003f, 0.64f)\n            curveToRelative(0.067f, 0.251f, 0.137f, 0.452f, 0.318f, 0.556f)\n            curveToRelative(0.181f, 0.104f, 0.39f, 0.065f, 0.641f, -0.002f)\n            curveToRelative(0.251f, -0.067f, 0.452f, -0.138f, 0.557f, -0.319f)\n            curveToRelative(0.105f, -0.181f, 0.064f, -0.389f, -0.003f, -0.64f)\n            curveToRelative(-0.067f, -0.251f, -0.137f, -0.452f, -0.318f, -0.556f)\n            curveToRelative(-0.079f, -0.046f, -0.164f, -0.063f, -0.255f, -0.064f)\n            lineToRelative(-0f, -0f)\n            close()\n            moveTo(18.159f, 7.537f)\n            curveToRelative(-0.091f, 0f, -0.176f, 0.018f, -0.255f, 0.064f)\n            curveToRelative(-0.181f, 0.104f, -0.251f, 0.305f, -0.318f, 0.556f)\n            curveToRelative(-0.067f, 0.251f, -0.108f, 0.46f, -0.003f, 0.64f)\n            curveToRelative(0.105f, 0.181f, 0.306f, 0.25f, 0.557f, 0.317f)\n            curveToRelative(0.251f, 0.067f, 0.461f, 0.108f, 0.642f, 0.004f)\n            curveToRelative(0.181f, -0.104f, 0.25f, -0.305f, 0.318f, -0.556f)\n            curveToRelative(0.067f, -0.251f, 0.108f, -0.459f, 0.003f, -0.64f)\n            curveToRelative(-0.105f, -0.181f, -0.306f, -0.252f, -0.557f, -0.319f)\n            curveToRelative(-0.141f, -0.038f, -0.269f, -0.067f, -0.386f, -0.066f)\n            horizontalLineToRelative(0f)\n            close()\n            moveTo(20.118f, 8.727f)\n            curveToRelative(-0.156f, 0f, -0.278f, 0.104f, -0.415f, 0.241f)\n            curveToRelative(-0.138f, 0.138f, -0.242f, 0.259f, -0.242f, 0.415f)\n            curveToRelative(0f, 0.156f, 0.105f, 0.277f, 0.242f, 0.414f)\n            curveToRelative(0.138f, 0.137f, 0.258f, 0.242f, 0.415f, 0.242f)\n            curveToRelative(0.157f, -0f, 0.277f, -0.105f, 0.415f, -0.242f)\n            curveToRelative(0.138f, -0.138f, 0.242f, -0.258f, 0.243f, -0.414f)\n            curveToRelative(0f, -0.156f, -0.105f, -0.277f, -0.242f, -0.414f)\n            curveToRelative(-0.138f, -0.138f, -0.259f, -0.242f, -0.415f, -0.242f)\n            close()\n            moveTo(6.497f, 9.449f)\n            curveToRelative(-0.202f, -0.003f, -0.402f, 0.099f, -0.63f, 0.23f)\n            curveToRelative(-0.28f, 0.162f, -0.5f, 0.31f, -0.568f, 0.561f)\n            curveToRelative(-0.067f, 0.251f, 0.049f, 0.489f, 0.21f, 0.769f)\n            curveToRelative(0.162f, 0.28f, 0.311f, 0.5f, 0.562f, 0.566f)\n            curveToRelative(0.251f, 0.067f, 0.49f, -0.048f, 0.77f, -0.209f)\n            curveToRelative(0.28f, -0.162f, 0.499f, -0.312f, 0.567f, -0.562f)\n            curveToRelative(0.067f, -0.251f, -0.049f, -0.489f, -0.21f, -0.768f)\n            curveToRelative(-0.162f, -0.28f, -0.31f, -0.499f, -0.561f, -0.566f)\n            curveToRelative(-0.047f, -0.013f, -0.094f, -0.019f, -0.14f, -0.019f)\n            verticalLineToRelative(-0f)\n            close()\n            moveTo(17.442f, 9.45f)\n            curveToRelative(-0.047f, 0.001f, -0.093f, 0.007f, -0.14f, 0.019f)\n            curveToRelative(-0.251f, 0.067f, -0.4f, 0.286f, -0.562f, 0.566f)\n            curveToRelative(-0.162f, 0.28f, -0.278f, 0.518f, -0.211f, 0.769f)\n            curveToRelative(0.067f, 0.251f, 0.287f, 0.399f, 0.568f, 0.561f)\n            curveToRelative(0.28f, 0.162f, 0.519f, 0.278f, 0.77f, 0.211f)\n            curveToRelative(0.251f, -0.067f, 0.4f, -0.287f, 0.561f, -0.566f)\n            curveToRelative(0.162f, -0.28f, 0.278f, -0.518f, 0.21f, -0.768f)\n            curveToRelative(-0.067f, -0.251f, -0.286f, -0.401f, -0.567f, -0.562f)\n            curveToRelative(-0.227f, -0.131f, -0.428f, -0.231f, -0.63f, -0.228f)\n            lineToRelative(0f, 0f)\n            close()\n            moveTo(3.724f, 9.636f)\n            curveToRelative(-0.088f, -0f, -0.184f, 0.022f, -0.29f, 0.05f)\n            curveToRelative(-0.188f, 0.05f, -0.339f, 0.102f, -0.418f, 0.238f)\n            curveToRelative(-0.078f, 0.135f, -0.048f, 0.292f, 0.002f, 0.48f)\n            curveToRelative(0.05f, 0.188f, 0.103f, 0.339f, 0.238f, 0.417f)\n            horizontalLineToRelative(0f)\n            curveToRelative(0.136f, 0.078f, 0.292f, 0.049f, 0.48f, -0.002f)\n            curveToRelative(0.188f, -0.05f, 0.339f, -0.104f, 0.417f, -0.239f)\n            curveToRelative(0.078f, -0.135f, 0.048f, -0.292f, -0.002f, -0.479f)\n            curveToRelative(-0.05f, -0.188f, -0.102f, -0.338f, -0.238f, -0.416f)\n            curveToRelative(-0.059f, -0.034f, -0.123f, -0.048f, -0.191f, -0.048f)\n            lineToRelative(-0f, -0f)\n            close()\n            moveTo(19.333f, 11.133f)\n            curveToRelative(-0.211f, -0f, -0.373f, 0.141f, -0.559f, 0.326f)\n            curveToRelative(-0.186f, 0.185f, -0.327f, 0.348f, -0.326f, 0.559f)\n            curveToRelative(0f, 0.21f, 0.14f, 0.374f, 0.326f, 0.559f)\n            curveToRelative(0.186f, 0.185f, 0.349f, 0.325f, 0.56f, 0.325f)\n            curveToRelative(0.211f, 0f, 0.373f, -0.141f, 0.559f, -0.326f)\n            curveToRelative(0.185f, -0.185f, 0.327f, -0.347f, 0.326f, -0.558f)\n            curveToRelative(0f, -0.211f, -0.141f, -0.373f, -0.327f, -0.558f)\n            curveToRelative(-0.186f, -0.185f, -0.348f, -0.326f, -0.559f, -0.327f)\n            close()\n            moveTo(4.605f, 11.151f)\n            curveToRelative(-0.211f, -0f, -0.373f, 0.141f, -0.559f, 0.326f)\n            reflectiveCurveToRelative(-0.327f, 0.347f, -0.326f, 0.558f)\n            curveToRelative(0f, 0.211f, 0.141f, 0.373f, 0.327f, 0.558f)\n            curveToRelative(0.186f, 0.185f, 0.348f, 0.326f, 0.559f, 0.327f)\n            curveToRelative(0.211f, 0f, 0.373f, -0.141f, 0.559f, -0.326f)\n            curveToRelative(0.186f, -0.185f, 0.327f, -0.348f, 0.326f, -0.559f)\n            curveToRelative(-0f, -0.21f, -0.14f, -0.374f, -0.326f, -0.559f)\n            curveToRelative(-0.186f, -0.185f, -0.349f, -0.325f, -0.56f, -0.325f)\n            verticalLineToRelative(-0f)\n            close()\n            moveTo(6.211f, 12.458f)\n            curveToRelative(-0.047f, 0.001f, -0.093f, 0.007f, -0.14f, 0.019f)\n            curveToRelative(-0.251f, 0.067f, -0.4f, 0.287f, -0.561f, 0.566f)\n            reflectiveCurveToRelative(-0.278f, 0.518f, -0.21f, 0.768f)\n            curveToRelative(0.067f, 0.251f, 0.286f, 0.401f, 0.567f, 0.562f)\n            curveToRelative(0.28f, 0.161f, 0.519f, 0.276f, 0.77f, 0.209f)\n            curveToRelative(0.251f, -0.067f, 0.4f, -0.286f, 0.562f, -0.566f)\n            curveToRelative(0.162f, -0.28f, 0.278f, -0.518f, 0.21f, -0.769f)\n            curveToRelative(-0.067f, -0.251f, -0.287f, -0.399f, -0.568f, -0.561f)\n            curveToRelative(-0.228f, -0.131f, -0.428f, -0.233f, -0.63f, -0.23f)\n            verticalLineToRelative(-0f)\n            close()\n            moveTo(17.726f, 12.459f)\n            curveToRelative(-0.202f, -0.003f, -0.402f, 0.097f, -0.63f, 0.228f)\n            curveToRelative(-0.28f, 0.162f, -0.499f, 0.312f, -0.567f, 0.562f)\n            curveToRelative(-0.067f, 0.251f, 0.049f, 0.489f, 0.21f, 0.768f)\n            reflectiveCurveToRelative(0.31f, 0.499f, 0.561f, 0.566f)\n            curveToRelative(0.251f, 0.067f, 0.49f, -0.049f, 0.77f, -0.211f)\n            curveToRelative(0.28f, -0.162f, 0.5f, -0.31f, 0.568f, -0.561f)\n            curveToRelative(0.067f, -0.251f, -0.049f, -0.489f, -0.21f, -0.769f)\n            curveToRelative(-0.162f, -0.28f, -0.311f, -0.5f, -0.562f, -0.566f)\n            curveToRelative(-0.047f, -0.012f, -0.094f, -0.019f, -0.14f, -0.019f)\n            verticalLineToRelative(0f)\n            close()\n            moveTo(20.489f, 13.185f)\n            curveToRelative(-0.088f, -0f, -0.184f, 0.021f, -0.289f, 0.05f)\n            curveToRelative(-0.188f, 0.05f, -0.339f, 0.104f, -0.417f, 0.239f)\n            curveToRelative(-0.078f, 0.135f, -0.048f, 0.292f, 0.002f, 0.479f)\n            curveToRelative(0.05f, 0.188f, 0.102f, 0.339f, 0.238f, 0.417f)\n            curveToRelative(0.136f, 0.078f, 0.292f, 0.048f, 0.481f, -0.003f)\n            curveToRelative(0.188f, -0.05f, 0.339f, -0.102f, 0.418f, -0.238f)\n            curveToRelative(0.078f, -0.135f, 0.048f, -0.292f, -0.002f, -0.48f)\n            curveToRelative(-0.05f, -0.188f, -0.103f, -0.339f, -0.238f, -0.417f)\n            curveToRelative(-0.059f, -0.034f, -0.123f, -0.048f, -0.191f, -0.048f)\n            verticalLineToRelative(0f)\n            close()\n            moveTo(3.821f, 14.013f)\n            curveToRelative(-0.157f, 0f, -0.277f, 0.105f, -0.415f, 0.242f)\n            curveToRelative(-0.138f, 0.138f, -0.243f, 0.258f, -0.243f, 0.414f)\n            curveToRelative(-0f, 0.156f, 0.105f, 0.277f, 0.242f, 0.414f)\n            curveToRelative(0.138f, 0.138f, 0.259f, 0.242f, 0.415f, 0.242f)\n            curveToRelative(0.156f, -0f, 0.278f, -0.104f, 0.415f, -0.241f)\n            curveToRelative(0.138f, -0.138f, 0.242f, -0.259f, 0.242f, -0.415f)\n            curveToRelative(0f, -0.156f, -0.105f, -0.277f, -0.242f, -0.414f)\n            curveToRelative(-0.138f, -0.137f, -0.258f, -0.242f, -0.415f, -0.242f)\n            close()\n            moveTo(5.412f, 14.872f)\n            curveToRelative(-0.091f, 0f, -0.176f, 0.018f, -0.255f, 0.064f)\n            curveToRelative(-0.181f, 0.104f, -0.25f, 0.306f, -0.318f, 0.556f)\n            curveToRelative(-0.067f, 0.251f, -0.108f, 0.459f, -0.003f, 0.64f)\n            curveToRelative(0.105f, 0.181f, 0.306f, 0.252f, 0.557f, 0.319f)\n            curveToRelative(0.251f, 0.067f, 0.46f, 0.106f, 0.641f, 0.002f)\n            curveToRelative(0.181f, -0.104f, 0.251f, -0.305f, 0.318f, -0.556f)\n            curveToRelative(0.067f, -0.251f, 0.108f, -0.46f, 0.003f, -0.64f)\n            curveToRelative(-0.105f, -0.181f, -0.306f, -0.25f, -0.557f, -0.317f)\n            curveToRelative(-0.141f, -0.038f, -0.269f, -0.067f, -0.387f, -0.067f)\n            lineToRelative(0f, 0f)\n            close()\n            moveTo(18.526f, 14.872f)\n            curveToRelative(-0.117f, -0f, -0.245f, 0.028f, -0.386f, 0.066f)\n            curveToRelative(-0.251f, 0.067f, -0.452f, 0.138f, -0.557f, 0.319f)\n            curveToRelative(-0.105f, 0.181f, -0.064f, 0.389f, 0.003f, 0.64f)\n            curveToRelative(0.067f, 0.251f, 0.137f, 0.452f, 0.318f, 0.556f)\n            curveToRelative(0.181f, 0.104f, 0.39f, 0.064f, 0.641f, -0.004f)\n            curveToRelative(0.251f, -0.067f, 0.453f, -0.137f, 0.557f, -0.317f)\n            curveToRelative(0.105f, -0.181f, 0.064f, -0.389f, -0.003f, -0.64f)\n            curveToRelative(-0.067f, -0.251f, -0.137f, -0.452f, -0.318f, -0.556f)\n            curveToRelative(-0.079f, -0.045f, -0.164f, -0.063f, -0.255f, -0.064f)\n            lineToRelative(0f, 0f)\n            close()\n            moveTo(7.859f, 15.158f)\n            curveToRelative(-0.323f, 0f, -0.587f, 0.021f, -0.771f, 0.204f)\n            curveToRelative(-0.184f, 0.183f, -0.202f, 0.447f, -0.202f, 0.769f)\n            curveToRelative(-0f, 0.322f, 0.019f, 0.586f, 0.202f, 0.769f)\n            curveToRelative(0.183f, 0.183f, 0.448f, 0.202f, 0.771f, 0.202f)\n            curveToRelative(0.323f, -0f, 0.587f, -0.019f, 0.771f, -0.202f)\n            curveToRelative(0.184f, -0.183f, 0.202f, -0.447f, 0.202f, -0.769f)\n            curveToRelative(-0f, -0.323f, -0.019f, -0.587f, -0.203f, -0.769f)\n            curveToRelative(-0.184f, -0.183f, -0.448f, -0.203f, -0.77f, -0.203f)\n            close()\n            moveTo(16.077f, 15.158f)\n            curveToRelative(-0.323f, 0f, -0.587f, 0.021f, -0.771f, 0.204f)\n            curveToRelative(-0.184f, 0.183f, -0.202f, 0.447f, -0.202f, 0.769f)\n            curveToRelative(0f, 0.322f, 0.018f, 0.586f, 0.202f, 0.769f)\n            curveToRelative(0.183f, 0.183f, 0.448f, 0.202f, 0.771f, 0.202f)\n            curveToRelative(0.323f, -0f, 0.587f, -0.019f, 0.771f, -0.202f)\n            curveToRelative(0.184f, -0.183f, 0.202f, -0.447f, 0.202f, -0.769f)\n            curveToRelative(0f, -0.323f, -0.019f, -0.587f, -0.203f, -0.769f)\n            curveToRelative(-0.184f, -0.183f, -0.448f, -0.203f, -0.77f, -0.203f)\n            horizontalLineToRelative(-0f)\n            close()\n            moveTo(10.607f, 16.554f)\n            curveToRelative(-0.202f, -0.003f, -0.403f, 0.097f, -0.631f, 0.229f)\n            curveToRelative(-0.281f, 0.162f, -0.5f, 0.312f, -0.568f, 0.563f)\n            curveToRelative(-0.068f, 0.251f, 0.049f, 0.49f, 0.211f, 0.77f)\n            curveToRelative(0.162f, 0.28f, 0.311f, 0.5f, 0.562f, 0.567f)\n            curveToRelative(0.252f, 0.067f, 0.491f, -0.049f, 0.771f, -0.211f)\n            curveToRelative(0.281f, -0.162f, 0.501f, -0.31f, 0.569f, -0.562f)\n            curveToRelative(0.068f, -0.251f, -0.049f, -0.49f, -0.211f, -0.77f)\n            curveToRelative(-0.162f, -0.28f, -0.311f, -0.5f, -0.563f, -0.567f)\n            horizontalLineToRelative(-0f)\n            curveToRelative(-0.047f, -0.012f, -0.094f, -0.019f, -0.14f, -0.019f)\n            horizontalLineToRelative(0f)\n            close()\n            moveTo(13.334f, 16.554f)\n            curveToRelative(-0.047f, 0.001f, -0.093f, 0.007f, -0.14f, 0.019f)\n            curveToRelative(-0.252f, 0.067f, -0.401f, 0.287f, -0.563f, 0.567f)\n            curveToRelative(-0.162f, 0.28f, -0.278f, 0.519f, -0.211f, 0.77f)\n            curveToRelative(0.068f, 0.251f, 0.288f, 0.4f, 0.569f, 0.562f)\n            curveToRelative(0.281f, 0.162f, 0.52f, 0.278f, 0.771f, 0.211f)\n            curveToRelative(0.252f, -0.067f, 0.4f, -0.287f, 0.562f, -0.567f)\n            curveToRelative(0.162f, -0.28f, 0.278f, -0.518f, 0.211f, -0.77f)\n            curveToRelative(-0.068f, -0.251f, -0.287f, -0.401f, -0.568f, -0.563f)\n            curveToRelative(-0.228f, -0.131f, -0.429f, -0.231f, -0.631f, -0.229f)\n            horizontalLineToRelative(0f)\n            close()\n            moveTo(18.201f, 17.126f)\n            curveToRelative(-0.07f, 0f, -0.134f, 0.014f, -0.195f, 0.049f)\n            curveToRelative(-0.138f, 0.079f, -0.192f, 0.233f, -0.243f, 0.425f)\n            curveToRelative(-0.051f, 0.191f, -0.082f, 0.351f, -0.002f, 0.489f)\n            curveToRelative(0.08f, 0.138f, 0.234f, 0.191f, 0.425f, 0.242f)\n            curveToRelative(0.192f, 0.051f, 0.352f, 0.082f, 0.49f, 0.003f)\n            curveToRelative(0.138f, -0.08f, 0.191f, -0.233f, 0.242f, -0.424f)\n            curveToRelative(0.051f, -0.191f, 0.082f, -0.351f, 0.002f, -0.489f)\n            curveToRelative(-0.08f, -0.138f, -0.233f, -0.192f, -0.425f, -0.243f)\n            curveToRelative(-0.108f, -0.029f, -0.205f, -0.051f, -0.295f, -0.051f)\n            verticalLineToRelative(-0f)\n            close()\n            moveTo(8.474f, 17.577f)\n            curveToRelative(-0.117f, -0f, -0.245f, 0.028f, -0.386f, 0.066f)\n            curveToRelative(-0.251f, 0.067f, -0.452f, 0.138f, -0.557f, 0.319f)\n            curveToRelative(-0.105f, 0.181f, -0.064f, 0.389f, 0.003f, 0.64f)\n            curveToRelative(0.067f, 0.25f, 0.137f, 0.452f, 0.318f, 0.556f)\n            curveToRelative(0.181f, 0.104f, 0.39f, 0.064f, 0.641f, -0.004f)\n            curveToRelative(0.251f, -0.067f, 0.453f, -0.137f, 0.557f, -0.317f)\n            curveToRelative(0.105f, -0.181f, 0.064f, -0.389f, -0.003f, -0.64f)\n            curveToRelative(-0.067f, -0.251f, -0.137f, -0.452f, -0.318f, -0.556f)\n            curveToRelative(-0.079f, -0.045f, -0.164f, -0.064f, -0.255f, -0.064f)\n            lineToRelative(-0f, 0f)\n            close()\n            moveTo(15.466f, 17.577f)\n            curveToRelative(-0.091f, 0f, -0.176f, 0.019f, -0.255f, 0.064f)\n            curveToRelative(-0.181f, 0.104f, -0.251f, 0.305f, -0.318f, 0.556f)\n            curveToRelative(-0.067f, 0.251f, -0.108f, 0.459f, -0.003f, 0.64f)\n            curveToRelative(0.105f, 0.181f, 0.306f, 0.25f, 0.557f, 0.317f)\n            curveToRelative(0.251f, 0.067f, 0.46f, 0.108f, 0.641f, 0.004f)\n            curveToRelative(0.181f, -0.104f, 0.25f, -0.305f, 0.317f, -0.556f)\n            reflectiveCurveToRelative(0.108f, -0.459f, 0.003f, -0.64f)\n            curveToRelative(-0.105f, -0.181f, -0.306f, -0.252f, -0.557f, -0.319f)\n            curveToRelative(-0.141f, -0.038f, -0.269f, -0.067f, -0.386f, -0.066f)\n            horizontalLineToRelative(0f)\n            close()\n            moveTo(6.097f, 17.752f)\n            curveToRelative(-0.07f, 0f, -0.134f, 0.014f, -0.195f, 0.049f)\n            curveToRelative(-0.138f, 0.079f, -0.192f, 0.233f, -0.243f, 0.425f)\n            curveToRelative(-0.051f, 0.191f, -0.082f, 0.351f, -0.002f, 0.489f)\n            curveToRelative(0.08f, 0.138f, 0.234f, 0.191f, 0.425f, 0.242f)\n            curveToRelative(0.192f, 0.051f, 0.352f, 0.082f, 0.49f, 0.003f)\n            curveToRelative(0.138f, -0.08f, 0.191f, -0.233f, 0.242f, -0.424f)\n            reflectiveCurveToRelative(0.082f, -0.351f, 0.002f, -0.488f)\n            curveToRelative(-0.08f, -0.138f, -0.233f, -0.192f, -0.425f, -0.243f)\n            curveToRelative(-0.108f, -0.029f, -0.205f, -0.051f, -0.295f, -0.051f)\n            verticalLineToRelative(0f)\n            close()\n            moveTo(11.966f, 18.498f)\n            curveToRelative(-0.211f, -0f, -0.373f, 0.141f, -0.559f, 0.326f)\n            reflectiveCurveToRelative(-0.327f, 0.347f, -0.326f, 0.558f)\n            curveToRelative(0f, 0.211f, 0.141f, 0.373f, 0.327f, 0.558f)\n            curveToRelative(0.186f, 0.185f, 0.348f, 0.326f, 0.559f, 0.326f)\n            curveToRelative(0.211f, 0f, 0.373f, -0.141f, 0.559f, -0.326f)\n            curveToRelative(0.186f, -0.185f, 0.327f, -0.348f, 0.326f, -0.559f)\n            curveToRelative(-0f, -0.21f, -0.14f, -0.374f, -0.326f, -0.559f)\n            curveToRelative(-0.186f, -0.185f, -0.349f, -0.325f, -0.56f, -0.325f)\n            verticalLineToRelative(-0f)\n            close()\n            moveTo(14.618f, 19.512f)\n            curveToRelative(-0.156f, -0f, -0.277f, 0.104f, -0.415f, 0.242f)\n            curveToRelative(-0.138f, 0.137f, -0.242f, 0.258f, -0.242f, 0.414f)\n            curveToRelative(0f, 0.156f, 0.105f, 0.277f, 0.242f, 0.414f)\n            curveToRelative(0.138f, 0.138f, 0.258f, 0.242f, 0.415f, 0.242f)\n            curveToRelative(0.156f, 0f, 0.277f, -0.104f, 0.415f, -0.242f)\n            curveToRelative(0.138f, -0.138f, 0.242f, -0.258f, 0.242f, -0.414f)\n            curveToRelative(-0.001f, -0.156f, -0.104f, -0.277f, -0.242f, -0.415f)\n            curveToRelative(-0.138f, -0.138f, -0.259f, -0.241f, -0.416f, -0.241f)\n            lineToRelative(0f, -0f)\n            close()\n            moveTo(10.322f, 19.776f)\n            curveToRelative(-0.089f, -0f, -0.187f, 0.022f, -0.295f, 0.051f)\n            curveToRelative(-0.192f, 0.051f, -0.345f, 0.105f, -0.425f, 0.243f)\n            curveToRelative(-0.08f, 0.138f, -0.049f, 0.297f, 0.002f, 0.489f)\n            reflectiveCurveToRelative(0.104f, 0.345f, 0.243f, 0.424f)\n            curveToRelative(0.138f, 0.08f, 0.298f, 0.049f, 0.49f, -0.003f)\n            curveToRelative(0.192f, -0.051f, 0.346f, -0.104f, 0.425f, -0.242f)\n            curveToRelative(0.08f, -0.138f, 0.049f, -0.297f, -0.002f, -0.489f)\n            curveToRelative(-0.051f, -0.191f, -0.105f, -0.345f, -0.243f, -0.425f)\n            horizontalLineToRelative(-0f)\n            curveToRelative(-0.06f, -0.035f, -0.125f, -0.048f, -0.195f, -0.049f)\n            lineToRelative(0f, 0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/IOS.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.IOS: ImageVector by lazy {\n    Builder(\n        name = \"IOS\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.71f, 19.5f)\n            curveTo(17.88f, 20.74f, 17.0f, 21.95f, 15.66f, 21.97f)\n            curveTo(14.32f, 22.0f, 13.89f, 21.18f, 12.37f, 21.18f)\n            curveTo(10.84f, 21.18f, 10.37f, 21.95f, 9.1f, 22.0f)\n            curveTo(7.79f, 22.05f, 6.8f, 20.68f, 5.96f, 19.47f)\n            curveTo(4.25f, 17.0f, 2.94f, 12.45f, 4.7f, 9.39f)\n            curveTo(5.57f, 7.87f, 7.13f, 6.91f, 8.82f, 6.88f)\n            curveTo(10.1f, 6.86f, 11.32f, 7.75f, 12.11f, 7.75f)\n            curveTo(12.89f, 7.75f, 14.37f, 6.68f, 15.92f, 6.84f)\n            curveTo(16.57f, 6.87f, 18.39f, 7.1f, 19.56f, 8.82f)\n            curveTo(19.47f, 8.88f, 17.39f, 10.1f, 17.41f, 12.63f)\n            curveTo(17.44f, 15.65f, 20.06f, 16.66f, 20.09f, 16.67f)\n            curveTo(20.06f, 16.74f, 19.67f, 18.11f, 18.71f, 19.5f)\n            moveTo(13.0f, 3.5f)\n            curveTo(13.73f, 2.67f, 14.94f, 2.04f, 15.94f, 2.0f)\n            curveTo(16.07f, 3.17f, 15.6f, 4.35f, 14.9f, 5.19f)\n            curveTo(14.21f, 6.04f, 13.07f, 6.7f, 11.95f, 6.61f)\n            curveTo(11.8f, 5.46f, 12.36f, 4.26f, 13.0f, 3.5f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageCombine.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ImageCombine: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Image Combine\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(160.0f, 360.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(120.0f, 320.0f)\n            verticalLineToRelative(-120.0f)\n            quadToRelative(0.0f, -33.0f, 23.5f, -56.5f)\n            reflectiveQuadTo(200.0f, 120.0f)\n            horizontalLineToRelative(120.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(360.0f, 160.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(320.0f, 200.0f)\n            lineTo(200.0f, 200.0f)\n            verticalLineToRelative(120.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(160.0f, 360.0f)\n            close()\n            moveTo(800.0f, 360.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(760.0f, 320.0f)\n            verticalLineToRelative(-120.0f)\n            lineTo(640.0f, 200.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(600.0f, 160.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(640.0f, 120.0f)\n            horizontalLineToRelative(120.0f)\n            quadToRelative(33.0f, 0.0f, 56.5f, 23.5f)\n            reflectiveQuadTo(840.0f, 200.0f)\n            verticalLineToRelative(120.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(800.0f, 360.0f)\n            close()\n            moveTo(645.0f, 605.0f)\n            lineToRelative(-97.0f, -97.0f)\n            quadToRelative(-12.0f, -12.0f, -12.0f, -28.0f)\n            reflectiveQuadToRelative(12.0f, -28.0f)\n            lineToRelative(97.0f, -97.0f)\n            quadToRelative(12.0f, -12.0f, 28.5f, -12.0f)\n            reflectiveQuadToRelative(28.5f, 12.0f)\n            quadToRelative(12.0f, 12.0f, 12.0f, 28.5f)\n            reflectiveQuadTo(702.0f, 412.0f)\n            lineToRelative(-29.0f, 28.0f)\n            horizontalLineToRelative(167.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(880.0f, 480.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(840.0f, 520.0f)\n            lineTo(673.0f, 520.0f)\n            lineToRelative(29.0f, 28.0f)\n            quadToRelative(12.0f, 12.0f, 12.0f, 28.5f)\n            reflectiveQuadTo(702.0f, 605.0f)\n            quadToRelative(-12.0f, 12.0f, -28.5f, 12.0f)\n            reflectiveQuadTo(645.0f, 605.0f)\n            close()\n            moveTo(259.0f, 605.0f)\n            quadToRelative(-12.0f, -12.0f, -12.5f, -28.5f)\n            reflectiveQuadTo(258.0f, 548.0f)\n            lineToRelative(29.0f, -28.0f)\n            lineTo(120.0f, 520.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(80.0f, 480.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(120.0f, 440.0f)\n            horizontalLineToRelative(167.0f)\n            lineToRelative(-29.0f, -28.0f)\n            quadToRelative(-12.0f, -12.0f, -11.5f, -28.5f)\n            reflectiveQuadTo(259.0f, 355.0f)\n            quadToRelative(12.0f, -12.0f, 28.0f, -12.0f)\n            reflectiveQuadToRelative(28.0f, 12.0f)\n            lineToRelative(97.0f, 97.0f)\n            quadToRelative(12.0f, 12.0f, 12.0f, 28.0f)\n            reflectiveQuadToRelative(-12.0f, 28.0f)\n            lineToRelative(-97.0f, 97.0f)\n            quadToRelative(-12.0f, 12.0f, -28.0f, 12.0f)\n            reflectiveQuadToRelative(-28.0f, -12.0f)\n            close()\n            moveTo(200.0f, 840.0f)\n            quadToRelative(-33.0f, 0.0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120.0f, 760.0f)\n            verticalLineToRelative(-120.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(160.0f, 600.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(200.0f, 640.0f)\n            verticalLineToRelative(120.0f)\n            horizontalLineToRelative(120.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(360.0f, 800.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(320.0f, 840.0f)\n            lineTo(200.0f, 840.0f)\n            close()\n            moveTo(640.0f, 840.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(600.0f, 800.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(640.0f, 760.0f)\n            horizontalLineToRelative(120.0f)\n            verticalLineToRelative(-120.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(800.0f, 600.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(840.0f, 640.0f)\n            verticalLineToRelative(120.0f)\n            quadToRelative(0.0f, 33.0f, -23.5f, 56.5f)\n            reflectiveQuadTo(760.0f, 840.0f)\n            lineTo(640.0f, 840.0f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageCombine: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ImageCombine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5.075f, 3f)\n            lineTo(18.925f, 3f)\n            arcTo(2.075f, 2.075f, 0f, isMoreThanHalf = false, isPositiveArc = true, 21f, 5.075f)\n            lineTo(21f, 18.925f)\n            arcTo(2.075f, 2.075f, 0f, isMoreThanHalf = false, isPositiveArc = true, 18.925f, 21f)\n            lineTo(5.075f, 21f)\n            arcTo(2.075f, 2.075f, 0f, isMoreThanHalf = false, isPositiveArc = true, 3f, 18.925f)\n            lineTo(3f, 5.075f)\n            arcTo(2.075f, 2.075f, 0f, isMoreThanHalf = false, isPositiveArc = true, 5.075f, 3f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(4f, 9f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-3f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n            moveTo(20f, 9f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            verticalLineToRelative(-3f)\n            horizontalLineToRelative(-3f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            curveToRelative(0.392f, 0.392f, 0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n            moveTo(16.125f, 15.125f)\n            lineToRelative(-2.425f, -2.425f)\n            curveToRelative(-0.2f, -0.2f, -0.3f, -0.433f, -0.3f, -0.7f)\n            reflectiveCurveToRelative(0.1f, -0.5f, 0.3f, -0.7f)\n            lineToRelative(2.425f, -2.425f)\n            curveToRelative(0.2f, -0.2f, 0.438f, -0.3f, 0.712f, -0.3f)\n            reflectiveCurveToRelative(0.512f, 0.1f, 0.712f, 0.3f)\n            reflectiveCurveToRelative(0.3f, 0.438f, 0.3f, 0.712f)\n            reflectiveCurveToRelative(-0.1f, 0.512f, -0.3f, 0.712f)\n            lineToRelative(-0.725f, 0.7f)\n            horizontalLineToRelative(4.175f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-4.175f)\n            lineToRelative(0.725f, 0.7f)\n            curveToRelative(0.2f, 0.2f, 0.3f, 0.438f, 0.3f, 0.712f)\n            reflectiveCurveToRelative(-0.1f, 0.512f, -0.3f, 0.712f)\n            reflectiveCurveToRelative(-0.438f, 0.3f, -0.712f, 0.3f)\n            reflectiveCurveToRelative(-0.512f, -0.1f, -0.712f, -0.3f)\n            close()\n            moveTo(6.475f, 15.125f)\n            curveToRelative(-0.2f, -0.2f, -0.304f, -0.438f, -0.313f, -0.712f)\n            reflectiveCurveToRelative(0.087f, -0.512f, 0.287f, -0.712f)\n            lineToRelative(0.725f, -0.7f)\n            horizontalLineTo(3f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(4.175f)\n            lineToRelative(-0.725f, -0.7f)\n            curveToRelative(-0.2f, -0.2f, -0.296f, -0.438f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.112f, -0.512f, 0.313f, -0.712f)\n            reflectiveCurveToRelative(0.433f, -0.3f, 0.7f, -0.3f)\n            reflectiveCurveToRelative(0.5f, 0.1f, 0.7f, 0.3f)\n            lineToRelative(2.425f, 2.425f)\n            curveToRelative(0.2f, 0.2f, 0.3f, 0.433f, 0.3f, 0.7f)\n            reflectiveCurveToRelative(-0.1f, 0.5f, -0.3f, 0.7f)\n            lineToRelative(-2.425f, 2.425f)\n            curveToRelative(-0.2f, 0.2f, -0.433f, 0.3f, -0.7f, 0.3f)\n            reflectiveCurveToRelative(-0.5f, -0.1f, -0.7f, -0.3f)\n            close()\n            moveTo(5f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-3f)\n            close()\n            moveTo(16f, 21f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(3f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-3f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageConvert.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageConvert: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImageConvert\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15.6f, 8.9f)\n            verticalLineToRelative(-1.9f)\n            horizontalLineToRelative(2.4f)\n            curveToRelative(-0.7f, -0.9f, -1.5f, -1.5f, -2.5f, -2f)\n            reflectiveCurveToRelative(-2f, -0.7f, -3.2f, -0.7f)\n            curveToRelative(-0.8f, 0f, -1.6f, 0.1f, -2.4f, 0.4f)\n            curveToRelative(-0.7f, 0.3f, -1.4f, 0.6f, -2f, 1.1f)\n            lineToRelative(-0.9f, -1.6f)\n            curveToRelative(0.8f, -0.5f, 1.6f, -0.9f, 2.5f, -1.2f)\n            reflectiveCurveToRelative(1.9f, -0.5f, 2.9f, -0.5f)\n            curveToRelative(1.2f, 0f, 2.4f, 0.2f, 3.5f, 0.7f)\n            reflectiveCurveToRelative(2.1f, 1.1f, 2.9f, 1.9f)\n            verticalLineToRelative(-1.2f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(5f)\n            horizontalLineToRelative(-5f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(8.2f, 13.5f)\n            horizontalLineToRelative(8f)\n            lineToRelative(-2.6f, -3.5f)\n            lineToRelative(-1.9f, 2.5f)\n            lineToRelative(-1.3f, -1.8f)\n            lineToRelative(-2.2f, 2.8f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13.11f, 15.744f)\n            lineToRelative(1.645f, 0.95f)\n            lineToRelative(-1.2f, 2.078f)\n            curveToRelative(1.129f, -0.156f, 2.049f, -0.549f, 2.982f, -1.165f)\n            reflectiveCurveToRelative(1.606f, -1.382f, 2.206f, -2.421f)\n            curveToRelative(0.4f, -0.693f, 0.713f, -1.436f, 0.854f, -2.278f)\n            curveToRelative(0.09f, -0.756f, 0.18f, -1.512f, 0.047f, -2.282f)\n            lineToRelative(1.836f, 0.021f)\n            curveToRelative(0.033f, 0.943f, -0.021f, 1.836f, -0.211f, 2.765f)\n            reflectiveCurveToRelative(-0.517f, 1.895f, -1.017f, 2.761f)\n            curveToRelative(-0.6f, 1.039f, -1.373f, 1.978f, -2.356f, 2.681f)\n            reflectiveCurveToRelative(-2.003f, 1.269f, -3.095f, 1.561f)\n            lineToRelative(1.039f, 0.6f)\n            lineToRelative(-0.9f, 1.559f)\n            lineToRelative(-4.33f, -2.5f)\n            lineToRelative(2.5f, -4.33f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(8.33f, 10.126f)\n            lineToRelative(-1.634f, 0.969f)\n            lineToRelative(-1.224f, -2.065f)\n            curveToRelative(-0.417f, 1.061f, -0.525f, 2.055f, -0.446f, 3.17f)\n            reflectiveCurveToRelative(0.418f, 2.077f, 1.03f, 3.11f)\n            curveToRelative(0.408f, 0.688f, 0.902f, 1.325f, 1.568f, 1.861f)\n            curveToRelative(0.615f, 0.449f, 1.23f, 0.898f, 1.966f, 1.16f)\n            lineToRelative(-0.917f, 1.59f)\n            curveToRelative(-0.838f, -0.433f, -1.59f, -0.917f, -2.307f, -1.539f)\n            reflectiveCurveToRelative(-1.399f, -1.379f, -1.909f, -2.24f)\n            curveToRelative(-0.612f, -1.032f, -1.052f, -2.167f, -1.183f, -3.368f)\n            reflectiveCurveToRelative(-0.125f, -2.367f, 0.156f, -3.463f)\n            lineToRelative(-1.032f, 0.612f)\n            lineToRelative(-0.918f, -1.548f)\n            lineToRelative(4.301f, -2.55f)\n            lineToRelative(2.55f, 4.301f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageConvert: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ImageConvert\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12.267f, 4.3f)\n            lineTo(12.487f, 4.3f)\n            arcTo(\n                7.264f,\n                7.264f,\n                0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                19.751f,\n                11.564f\n            )\n            lineTo(19.751f, 11.609f)\n            arcTo(\n                7.264f,\n                7.264f,\n                0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                12.487f,\n                18.874f\n            )\n            lineTo(12.267f, 18.874f)\n            arcTo(7.264f, 7.264f, 0f, isMoreThanHalf = false, isPositiveArc = true, 5.002f, 11.609f)\n            lineTo(5.002f, 11.564f)\n            arcTo(7.264f, 7.264f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12.267f, 4.3f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15.6f, 8.9f)\n            verticalLineToRelative(-1.9f)\n            horizontalLineToRelative(2.4f)\n            curveToRelative(-0.7f, -0.9f, -1.5f, -1.5f, -2.5f, -2f)\n            reflectiveCurveToRelative(-2f, -0.7f, -3.2f, -0.7f)\n            curveToRelative(-0.8f, 0f, -1.6f, 0.1f, -2.4f, 0.4f)\n            curveToRelative(-0.7f, 0.3f, -1.4f, 0.6f, -2f, 1.1f)\n            lineToRelative(-0.9f, -1.6f)\n            curveToRelative(0.8f, -0.5f, 1.6f, -0.9f, 2.5f, -1.2f)\n            reflectiveCurveToRelative(1.9f, -0.5f, 2.9f, -0.5f)\n            curveToRelative(1.2f, 0f, 2.4f, 0.2f, 3.5f, 0.7f)\n            reflectiveCurveToRelative(2.1f, 1.1f, 2.9f, 1.9f)\n            verticalLineToRelative(-1.2f)\n            horizontalLineToRelative(1.8f)\n            verticalLineToRelative(5f)\n            horizontalLineToRelative(-5f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(8.2f, 13.5f)\n            horizontalLineToRelative(8f)\n            lineToRelative(-2.6f, -3.5f)\n            lineToRelative(-1.9f, 2.5f)\n            lineToRelative(-1.3f, -1.8f)\n            lineToRelative(-2.2f, 2.8f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13.11f, 15.744f)\n            lineToRelative(1.645f, 0.95f)\n            lineToRelative(-1.2f, 2.078f)\n            curveToRelative(1.129f, -0.156f, 2.049f, -0.549f, 2.982f, -1.165f)\n            reflectiveCurveToRelative(1.606f, -1.382f, 2.206f, -2.421f)\n            curveToRelative(0.4f, -0.693f, 0.713f, -1.436f, 0.854f, -2.278f)\n            curveToRelative(0.09f, -0.756f, 0.18f, -1.512f, 0.047f, -2.282f)\n            lineToRelative(1.836f, 0.021f)\n            curveToRelative(0.033f, 0.943f, -0.021f, 1.836f, -0.211f, 2.765f)\n            reflectiveCurveToRelative(-0.517f, 1.895f, -1.017f, 2.761f)\n            curveToRelative(-0.6f, 1.039f, -1.373f, 1.978f, -2.356f, 2.681f)\n            reflectiveCurveToRelative(-2.003f, 1.269f, -3.095f, 1.561f)\n            lineToRelative(1.039f, 0.6f)\n            lineToRelative(-0.9f, 1.559f)\n            lineToRelative(-4.33f, -2.5f)\n            lineToRelative(2.5f, -4.33f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(8.33f, 10.126f)\n            lineToRelative(-1.634f, 0.969f)\n            lineToRelative(-1.224f, -2.065f)\n            curveToRelative(-0.417f, 1.061f, -0.525f, 2.055f, -0.446f, 3.17f)\n            reflectiveCurveToRelative(0.418f, 2.077f, 1.03f, 3.11f)\n            curveToRelative(0.408f, 0.688f, 0.902f, 1.325f, 1.568f, 1.861f)\n            curveToRelative(0.615f, 0.449f, 1.23f, 0.898f, 1.966f, 1.16f)\n            lineToRelative(-0.917f, 1.59f)\n            curveToRelative(-0.838f, -0.433f, -1.59f, -0.917f, -2.307f, -1.539f)\n            reflectiveCurveToRelative(-1.399f, -1.379f, -1.909f, -2.24f)\n            curveToRelative(-0.612f, -1.032f, -1.052f, -2.167f, -1.183f, -3.368f)\n            reflectiveCurveToRelative(-0.125f, -2.367f, 0.156f, -3.463f)\n            lineToRelative(-1.032f, 0.612f)\n            lineToRelative(-0.918f, -1.548f)\n            lineToRelative(4.301f, -2.55f)\n            lineToRelative(2.55f, 4.301f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageDownload.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageDownload: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.ImageDownload\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(7f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-7f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(-6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(5f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.474f, 6.243f)\n            lineToRelative(0.9f, -0.875f)\n            curveToRelative(0.183f, -0.183f, 0.412f, -0.279f, 0.688f, -0.287f)\n            reflectiveCurveToRelative(0.512f, 0.087f, 0.712f, 0.287f)\n            curveToRelative(0.183f, 0.183f, 0.275f, 0.417f, 0.275f, 0.7f)\n            reflectiveCurveToRelative(-0.092f, 0.517f, -0.275f, 0.7f)\n            lineToRelative(-2.6f, 2.6f)\n            curveToRelative(-0.1f, 0.1f, -0.208f, 0.175f, -0.325f, 0.225f)\n            reflectiveCurveToRelative(-0.242f, 0.075f, -0.375f, 0.075f)\n            reflectiveCurveToRelative(-0.258f, -0.025f, -0.375f, -0.075f)\n            reflectiveCurveToRelative(-0.225f, -0.125f, -0.325f, -0.225f)\n            lineToRelative(-2.6f, -2.6f)\n            curveToRelative(-0.183f, -0.183f, -0.279f, -0.412f, -0.287f, -0.688f)\n            reflectiveCurveToRelative(0.087f, -0.512f, 0.287f, -0.712f)\n            curveToRelative(0.183f, -0.183f, 0.417f, -0.275f, 0.7f, -0.275f)\n            reflectiveCurveToRelative(0.517f, 0.092f, 0.7f, 0.275f)\n            lineToRelative(0.9f, 0.875f)\n            verticalLineToRelative(-3.175f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(3.175f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 17f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.2f, 0f, 0.35f, -0.092f, 0.45f, -0.275f)\n            reflectiveCurveToRelative(0.083f, -0.358f, -0.05f, -0.525f)\n            lineToRelative(-2.75f, -3.675f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2.6f, 3.475f)\n            lineToRelative(-1.85f, -2.475f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2f, 2.675f)\n            curveToRelative(-0.133f, 0.167f, -0.15f, 0.342f, -0.05f, 0.525f)\n            reflectiveCurveToRelative(0.25f, 0.275f, 0.45f, 0.275f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageDownload: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ImageDownload\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(7f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-7f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(-6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(5f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.474f, 6.243f)\n            lineToRelative(0.9f, -0.875f)\n            curveToRelative(0.183f, -0.183f, 0.412f, -0.279f, 0.688f, -0.287f)\n            reflectiveCurveToRelative(0.512f, 0.087f, 0.712f, 0.287f)\n            curveToRelative(0.183f, 0.183f, 0.275f, 0.417f, 0.275f, 0.7f)\n            reflectiveCurveToRelative(-0.092f, 0.517f, -0.275f, 0.7f)\n            lineToRelative(-2.6f, 2.6f)\n            curveToRelative(-0.1f, 0.1f, -0.208f, 0.175f, -0.325f, 0.225f)\n            reflectiveCurveToRelative(-0.242f, 0.075f, -0.375f, 0.075f)\n            reflectiveCurveToRelative(-0.258f, -0.025f, -0.375f, -0.075f)\n            reflectiveCurveToRelative(-0.225f, -0.125f, -0.325f, -0.225f)\n            lineToRelative(-2.6f, -2.6f)\n            curveToRelative(-0.183f, -0.183f, -0.279f, -0.412f, -0.287f, -0.688f)\n            reflectiveCurveToRelative(0.087f, -0.512f, 0.287f, -0.712f)\n            curveToRelative(0.183f, -0.183f, 0.417f, -0.275f, 0.7f, -0.275f)\n            reflectiveCurveToRelative(0.517f, 0.092f, 0.7f, 0.275f)\n            lineToRelative(0.9f, 0.875f)\n            verticalLineToRelative(-3.175f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(3.175f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 17f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.2f, 0f, 0.35f, -0.092f, 0.45f, -0.275f)\n            reflectiveCurveToRelative(0.083f, -0.358f, -0.05f, -0.525f)\n            lineToRelative(-2.75f, -3.675f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2.6f, 3.475f)\n            lineToRelative(-1.85f, -2.475f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2f, 2.675f)\n            curveToRelative(-0.133f, 0.167f, -0.15f, 0.342f, -0.05f, 0.525f)\n            reflectiveCurveToRelative(0.25f, 0.275f, 0.45f, 0.275f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(18.271f, 12.599f)\n            curveToRelative(-0.231f, -0.099f, -0.445f, -0.247f, -0.643f, -0.445f)\n            lineToRelative(-5.141f, -5.141f)\n            curveToRelative(-0.362f, -0.362f, -0.552f, -0.816f, -0.568f, -1.359f)\n            curveToRelative(-0.007f, -0.233f, 0.032f, -0.449f, 0.1f, -0.654f)\n            horizontalLineToRelative(-7.02f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(-6.254f)\n            curveToRelative(-0.259f, -0.002f, -0.502f, -0.05f, -0.729f, -0.147f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageEdit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageEdit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"Outlined.ImageEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(22.459f, 13.864f)\n            curveToRelative(-0.075f, -0.183f, -0.179f, -0.35f, -0.313f, -0.5f)\n            lineToRelative(-0.925f, -0.925f)\n            curveToRelative(-0.15f, -0.15f, -0.317f, -0.262f, -0.5f, -0.337f)\n            reflectiveCurveToRelative(-0.375f, -0.113f, -0.575f, -0.113f)\n            curveToRelative(-0.183f, 0f, -0.367f, 0.033f, -0.55f, 0.1f)\n            reflectiveCurveToRelative(-0.35f, 0.175f, -0.5f, 0.325f)\n            lineToRelative(-5.525f, 5.5f)\n            verticalLineToRelative(3.075f)\n            horizontalLineToRelative(3.075f)\n            lineToRelative(5.5f, -5.5f)\n            curveToRelative(0.15f, -0.15f, 0.258f, -0.321f, 0.325f, -0.512f)\n            curveToRelative(0.067f, -0.192f, 0.1f, -0.379f, 0.1f, -0.563f)\n            reflectiveCurveToRelative(-0.038f, -0.367f, -0.113f, -0.55f)\n            close()\n            moveTo(16.021f, 19.489f)\n            horizontalLineToRelative(-0.95f)\n            verticalLineToRelative(-0.95f)\n            lineToRelative(3.05f, -3.025f)\n            lineToRelative(0.475f, 0.45f)\n            lineToRelative(0.45f, 0.475f)\n            lineToRelative(-3.025f, 3.05f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.018f, 18.608f)\n            horizontalLineToRelative(-5.625f)\n            verticalLineTo(5.468f)\n            horizontalLineToRelative(13.214f)\n            verticalLineToRelative(4.895f)\n            horizontalLineToRelative(1.888f)\n            verticalLineToRelative(-4.895f)\n            curveToRelative(0f, -1.032f, -0.84f, -1.877f, -1.888f, -1.877f)\n            horizontalLineTo(5.393f)\n            curveToRelative(-1.038f, 0f, -1.888f, 0.845f, -1.888f, 1.877f)\n            verticalLineToRelative(13.14f)\n            curveToRelative(0f, 1.042f, 0.849f, 1.877f, 1.888f, 1.877f)\n            horizontalLineToRelative(6.394f)\n            verticalLineToRelative(-1.877f)\n            horizontalLineToRelative(-0.769f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.047f, 12.914f)\n            lineToRelative(-1.656f, -2.208f)\n            lineToRelative(-2.475f, 3.3f)\n            lineToRelative(-1.815f, -2.409f)\n            lineToRelative(-2.805f, 3.729f)\n            lineToRelative(6.339f, 0f)\n            lineToRelative(2.412f, -2.412f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageEdit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"TwoTone.ImageEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(22.459f, 13.864f)\n            curveToRelative(-0.075f, -0.183f, -0.179f, -0.35f, -0.313f, -0.5f)\n            lineToRelative(-0.925f, -0.925f)\n            curveToRelative(-0.15f, -0.15f, -0.317f, -0.262f, -0.5f, -0.337f)\n            reflectiveCurveToRelative(-0.375f, -0.113f, -0.575f, -0.113f)\n            curveToRelative(-0.183f, 0f, -0.367f, 0.033f, -0.55f, 0.1f)\n            reflectiveCurveToRelative(-0.35f, 0.175f, -0.5f, 0.325f)\n            lineToRelative(-5.525f, 5.5f)\n            verticalLineToRelative(3.075f)\n            horizontalLineToRelative(3.075f)\n            lineToRelative(5.5f, -5.5f)\n            curveToRelative(0.15f, -0.15f, 0.258f, -0.321f, 0.325f, -0.512f)\n            curveToRelative(0.067f, -0.192f, 0.1f, -0.379f, 0.1f, -0.563f)\n            reflectiveCurveToRelative(-0.038f, -0.367f, -0.113f, -0.55f)\n            close()\n            moveTo(16.021f, 19.489f)\n            horizontalLineToRelative(-0.95f)\n            verticalLineToRelative(-0.95f)\n            lineToRelative(3.05f, -3.025f)\n            lineToRelative(0.475f, 0.45f)\n            lineToRelative(0.45f, 0.475f)\n            lineToRelative(-3.025f, 3.05f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.018f, 18.608f)\n            horizontalLineToRelative(-5.625f)\n            verticalLineTo(5.468f)\n            horizontalLineToRelative(13.214f)\n            verticalLineToRelative(4.895f)\n            horizontalLineToRelative(1.888f)\n            verticalLineToRelative(-4.895f)\n            curveToRelative(0f, -1.032f, -0.84f, -1.877f, -1.888f, -1.877f)\n            horizontalLineTo(5.393f)\n            curveToRelative(-1.038f, 0f, -1.888f, 0.845f, -1.888f, 1.877f)\n            verticalLineToRelative(13.14f)\n            curveToRelative(0f, 1.042f, 0.849f, 1.877f, 1.888f, 1.877f)\n            horizontalLineToRelative(6.394f)\n            verticalLineToRelative(-1.877f)\n            horizontalLineToRelative(-0.769f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.047f, 12.914f)\n            lineToRelative(-1.656f, -2.208f)\n            lineToRelative(-2.475f, 3.3f)\n            lineToRelative(-1.815f, -2.409f)\n            lineToRelative(-2.805f, 3.729f)\n            lineToRelative(6.339f, 0f)\n            lineToRelative(2.412f, -2.412f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(11.787f, 5.468f)\n            lineToRelative(-1.655f, 0f)\n            lineToRelative(-4.739f, 0f)\n            lineToRelative(0f, 13.14f)\n            lineToRelative(4.739f, 0f)\n            lineToRelative(1.651f, 0f)\n            lineToRelative(0f, -1.431f)\n            lineToRelative(0.001f, 0f)\n            lineToRelative(6.822f, -6.822f)\n            lineToRelative(0f, -4.886f)\n            lineToRelative(-6.82f, 0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(14.065f, 18.646f)\n            lineToRelative(4.057f, -4.057f)\n            lineToRelative(1.825f, 1.825f)\n            lineToRelative(-4.057f, 4.057f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageEmbedded.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageEmbedded: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImageEmbedded\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 8f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.713f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.412f)\n            reflectiveCurveToRelative(0.863f, -0.588f, 1.413f, -0.588f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.713f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.713f, 0.287f)\n            horizontalLineToRelative(-3f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.713f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 22f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.412f, -0.587f)\n            reflectiveCurveToRelative(-0.588f, -0.862f, -0.588f, -1.413f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.288f, 0.713f, -0.288f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.713f, 0.288f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.713f, 0.288f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.288f, -0.713f, 0.288f)\n            horizontalLineToRelative(-3f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 22f)\n            horizontalLineToRelative(-3f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.288f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.288f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.288f, 0.712f, -0.288f)\n            horizontalLineToRelative(3f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.288f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.288f, 0.712f, -0.288f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.288f)\n            reflectiveCurveToRelative(0.288f, 0.429f, 0.288f, 0.712f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.862f, 0.587f, -1.413f, 0.587f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 7f)\n            verticalLineToRelative(-3f)\n            horizontalLineToRelative(-3f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.713f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.288f, -0.713f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(3f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.288f, 0.713f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.288f, -0.429f, -0.288f, -0.713f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5.943f, 14.011f)\n            lineToRelative(2.472f, -3.291f)\n            curveToRelative(0.062f, -0.082f, 0.136f, -0.144f, 0.224f, -0.185f)\n            reflectiveCurveToRelative(0.178f, -0.062f, 0.27f, -0.062f)\n            reflectiveCurveToRelative(0.183f, 0.021f, 0.27f, 0.062f)\n            reflectiveCurveToRelative(0.162f, 0.103f, 0.224f, 0.185f)\n            lineToRelative(2.102f, 2.797f)\n            curveToRelative(0.062f, 0.082f, 0.134f, 0.144f, 0.216f, 0.185f)\n            reflectiveCurveToRelative(0.175f, 0.062f, 0.278f, 0.062f)\n            curveToRelative(0.258f, 0f, 0.443f, -0.116f, 0.556f, -0.348f)\n            curveToRelative(0.113f, -0.232f, 0.093f, -0.451f, -0.062f, -0.657f)\n            lineToRelative(-1.298f, -1.715f)\n            curveToRelative(-0.082f, -0.113f, -0.124f, -0.237f, -0.124f, -0.371f)\n            curveToRelative(0f, -0.134f, 0.041f, -0.258f, 0.124f, -0.371f)\n            lineToRelative(1.545f, -2.055f)\n            curveToRelative(0.062f, -0.082f, 0.136f, -0.144f, 0.224f, -0.185f)\n            reflectiveCurveToRelative(0.178f, -0.062f, 0.27f, -0.062f)\n            reflectiveCurveToRelative(0.183f, 0.021f, 0.27f, 0.062f)\n            reflectiveCurveToRelative(0.162f, 0.103f, 0.224f, 0.185f)\n            lineToRelative(4.327f, 5.764f)\n            curveToRelative(0.155f, 0.206f, 0.175f, 0.422f, 0.062f, 0.649f)\n            curveToRelative(-0.113f, 0.227f, -0.299f, 0.34f, -0.556f, 0.34f)\n            horizontalLineTo(6.437f)\n            curveToRelative(-0.258f, 0f, -0.443f, -0.113f, -0.556f, -0.34f)\n            reflectiveCurveToRelative(-0.093f, -0.443f, 0.062f, -0.649f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageLimit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageLimit: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Image Limit\",\n        defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f,\n        viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(7.6702f, 15.289f)\n            lineToRelative(8.6596f, 0.0f)\n            lineToRelative(-2.7061f, -3.6082f)\n            lineToRelative(-2.1649f, 2.8865f)\n            lineToRelative(-1.6237f, -2.1649f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 3.1136f)\n            curveToRelative(-5.5228f, 0.0f, -10.0f, 4.4772f, -10.0f, 10.0f)\n            curveToRelative(0.0f, 3.1172f, 1.4398f, 5.8854f, 3.6758f, 7.7189f)\n            lineToRelative(2.6348f, -2.6348f)\n            lineToRelative(-1.4087f, -1.4088f)\n            lineToRelative(-1.2151f, 1.2151f)\n            curveToRelative(-0.8453f, -1.0906f, -1.418f, -2.4037f, -1.6085f, -3.8388f)\n            horizontalLineToRelative(1.7119f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineTo(4.0599f)\n            curveToRelative(0.1718f, -1.465f, 0.7408f, -2.8074f, 1.5935f, -3.9208f)\n            lineToRelative(1.2126f, 1.2126f)\n            lineToRelative(1.4142f, -1.4142f)\n            lineTo(7.0601f, 6.8227f)\n            curveTo(8.1728f, 5.9452f, 9.5237f, 5.3609f, 11.0f, 5.1748f)\n            verticalLineToRelative(1.7205f)\n            horizontalLineToRelative(2.0f)\n            verticalLineTo(5.1747f)\n            curveToRelative(1.4588f, 0.1837f, 2.7955f, 0.7556f, 3.9005f, 1.6158f)\n            lineToRelative(-1.2166f, 1.2166f)\n            lineToRelative(1.4142f, 1.4142f)\n            lineToRelative(1.2186f, -1.2186f)\n            curveToRelative(0.8701f, 1.1213f, 1.4495f, 2.4799f, 1.6234f, 3.9627f)\n            horizontalLineToRelative(-1.7303f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(1.7119f)\n            curveToRelative(-0.1929f, 1.4529f, -0.776f, 2.7819f, -1.6387f, 3.8804f)\n            lineToRelative(-1.2208f, -1.2208f)\n            lineToRelative(-1.4142f, 1.4142f)\n            lineToRelative(1.2112f, 1.2112f)\n            lineToRelative(1.4319f, 1.4319f)\n            horizontalLineToRelative(1.0E-4f)\n            lineToRelative(0.0042f, 0.0042f)\n            lineToRelative(0.0287f, -0.0287f)\n            curveTo(20.567f, 19.0238f, 22.0f, 16.2367f, 22.0f, 13.1136f)\n            curveTo(22.0f, 7.5908f, 17.5228f, 3.1136f, 12.0f, 3.1136f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageLimit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ImageLimit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(7.67f, 15.289f)\n            horizontalLineToRelative(8.66f)\n            lineToRelative(-2.706f, -3.608f)\n            lineToRelative(-2.165f, 2.886f)\n            lineToRelative(-1.624f, -2.165f)\n            lineToRelative(-2.165f, 2.887f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 3.114f)\n            curveTo(6.477f, 3.114f, 2f, 7.591f, 2f, 13.114f)\n            curveToRelative(0f, 3.117f, 1.44f, 5.885f, 3.676f, 7.719f)\n            lineToRelative(2.635f, -2.635f)\n            lineToRelative(-1.409f, -1.409f)\n            lineToRelative(-1.215f, 1.215f)\n            curveToRelative(-0.845f, -1.091f, -1.418f, -2.404f, -1.609f, -3.839f)\n            horizontalLineToRelative(1.712f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-1.73f)\n            curveToRelative(0.172f, -1.465f, 0.741f, -2.807f, 1.594f, -3.921f)\n            lineToRelative(1.213f, 1.213f)\n            lineToRelative(1.414f, -1.414f)\n            lineToRelative(-1.22f, -1.22f)\n            curveToRelative(1.113f, -0.878f, 2.464f, -1.462f, 3.94f, -1.648f)\n            verticalLineToRelative(1.72f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-1.721f)\n            curveToRelative(1.459f, 0.184f, 2.795f, 0.756f, 3.9f, 1.616f)\n            lineToRelative(-1.217f, 1.217f)\n            lineToRelative(1.414f, 1.414f)\n            lineToRelative(1.219f, -1.219f)\n            curveToRelative(0.87f, 1.121f, 1.449f, 2.48f, 1.623f, 3.963f)\n            horizontalLineToRelative(-1.73f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(1.712f)\n            curveToRelative(-0.193f, 1.453f, -0.776f, 2.782f, -1.639f, 3.88f)\n            lineToRelative(-1.221f, -1.221f)\n            lineToRelative(-1.414f, 1.414f)\n            lineToRelative(1.211f, 1.211f)\n            lineToRelative(1.432f, 1.432f)\n            horizontalLineToRelative(0f)\n            lineToRelative(0.004f, 0.004f)\n            lineToRelative(0.029f, -0.029f)\n            curveToRelative(2.243f, -1.834f, 3.676f, -4.621f, 3.676f, -7.744f)\n            curveToRelative(0f, -5.523f, -4.477f, -10f, -10f, -10f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(20.554f, 18.274f)\n            curveToRelative(0.912f, -1.508f, 1.446f, -3.27f, 1.446f, -5.16f)\n            curveToRelative(0f, -5.523f, -4.477f, -10f, -10f, -10f)\n            reflectiveCurveTo(2f, 7.591f, 2f, 13.114f)\n            curveToRelative(0f, 1.841f, 0.506f, 3.559f, 1.373f, 5.04f)\n            lineToRelative(17.18f, 0.12f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageOverlay.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageOverlay: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.ImageOverlay\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(3.5f, 1.5f)\n            curveToRelative(-1.11f, 0f, -2f, 0.89f, -2f, 2f)\n            verticalLineToRelative(11f)\n            curveToRelative(0f, 1.11f, 0.89f, 2f, 2f, 2f)\n            curveToRelative(3.67f, 0f, 7.33f, 0f, 11f, 0f)\n            curveToRelative(1.11f, 0f, 2f, -0.89f, 2f, -2f)\n            curveToRelative(0f, -3.67f, 0f, -7.33f, 0f, -11f)\n            curveToRelative(0f, -1.11f, -0.89f, -2f, -2f, -2f)\n            horizontalLineTo(3.5f)\n            moveTo(3.5f, 3.5f)\n            horizontalLineToRelative(11f)\n            verticalLineToRelative(11f)\n            horizontalLineToRelative(-11f)\n            verticalLineTo(3.5f)\n            moveTo(18.5f, 7.5f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(11f)\n            horizontalLineToRelative(-11f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 1.11f, 0.89f, 2f, 2f, 2f)\n            horizontalLineToRelative(11f)\n            curveToRelative(1.11f, 0f, 2f, -0.89f, 2f, -2f)\n            verticalLineToRelative(-11f)\n            curveToRelative(0f, -1.11f, -0.89f, -2f, -2f, -2f)\n            horizontalLineTo(18.5f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(10.633f, 9.242f)\n            lineToRelative(-2.292f, 2.95f)\n            lineToRelative(-1.633f, -1.967f)\n            lineToRelative(-2.292f, 2.942f)\n            lineToRelative(9.167f, 0f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageOverlay: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ImageOverlay\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(3.5f, 1.5f)\n            curveToRelative(-1.11f, 0f, -2f, 0.89f, -2f, 2f)\n            verticalLineToRelative(11f)\n            curveToRelative(0f, 1.11f, 0.89f, 2f, 2f, 2f)\n            horizontalLineToRelative(11f)\n            curveToRelative(1.11f, 0f, 2f, -0.89f, 2f, -2f)\n            verticalLineTo(3.5f)\n            curveToRelative(0f, -1.11f, -0.89f, -2f, -2f, -2f)\n            horizontalLineTo(3.5f)\n            moveTo(3.5f, 3.5f)\n            horizontalLineToRelative(11f)\n            verticalLineToRelative(11f)\n            horizontalLineTo(3.5f)\n            verticalLineTo(3.5f)\n            moveTo(18.5f, 7.5f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(11f)\n            horizontalLineToRelative(-11f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 1.11f, 0.89f, 2f, 2f, 2f)\n            horizontalLineToRelative(11f)\n            curveToRelative(1.11f, 0f, 2f, -0.89f, 2f, -2f)\n            verticalLineToRelative(-11f)\n            curveToRelative(0f, -1.11f, -0.89f, -2f, -2f, -2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(3.5f, 3.5f)\n            horizontalLineToRelative(11f)\n            verticalLineToRelative(11f)\n            horizontalLineToRelative(-11f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(10.633f, 9.242f)\n            lineToRelative(-2.292f, 2.95f)\n            lineToRelative(-1.633f, -1.967f)\n            lineToRelative(-2.292f, 2.942f)\n            horizontalLineToRelative(9.167f)\n            lineToRelative(-2.95f, -3.925f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageReset.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ImageReset: ImageVector by lazy {\n    Builder(\n        name = \"ImageReset\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(120.0f, 360.0f)\n            verticalLineToRelative(-240.0f)\n            horizontalLineToRelative(80.0f)\n            verticalLineToRelative(134.0f)\n            quadToRelative(50.0f, -62.0f, 122.5f, -98.0f)\n            reflectiveQuadTo(480.0f, 120.0f)\n            quadToRelative(118.0f, 0.0f, 210.5f, 67.0f)\n            reflectiveQuadTo(820.0f, 360.0f)\n            horizontalLineToRelative(-87.0f)\n            quadToRelative(-34.0f, -72.0f, -101.0f, -116.0f)\n            reflectiveQuadToRelative(-152.0f, -44.0f)\n            quadToRelative(-57.0f, 0.0f, -107.5f, 21.0f)\n            reflectiveQuadTo(284.0f, 280.0f)\n            horizontalLineToRelative(76.0f)\n            verticalLineToRelative(80.0f)\n            lineTo(120.0f, 360.0f)\n            close()\n            moveTo(240.0f, 720.0f)\n            horizontalLineToRelative(480.0f)\n            lineTo(570.0f, 520.0f)\n            lineTo(450.0f, 680.0f)\n            lineToRelative(-90.0f, -120.0f)\n            lineToRelative(-120.0f, 160.0f)\n            close()\n            moveTo(200.0f, 880.0f)\n            quadToRelative(-33.0f, 0.0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120.0f, 800.0f)\n            verticalLineToRelative(-320.0f)\n            horizontalLineToRelative(80.0f)\n            verticalLineToRelative(320.0f)\n            horizontalLineToRelative(560.0f)\n            verticalLineToRelative(-320.0f)\n            horizontalLineToRelative(80.0f)\n            verticalLineToRelative(320.0f)\n            quadToRelative(0.0f, 33.0f, -23.5f, 56.5f)\n            reflectiveQuadTo(760.0f, 880.0f)\n            lineTo(200.0f, 880.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageResize.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageResize: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImageResize\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 9f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(6f)\n            verticalLineToRelative(6f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(3f, 21f)\n            verticalLineToRelative(-6f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(2f)\n            horizontalLineTo(3f)\n            close()\n            moveTo(3f, 13f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(3f, 9f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(3f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(7f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(11f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(11f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(15f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 17f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 13f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6.5f, 16.792f)\n            lineToRelative(11f, 0f)\n            lineToRelative(-3.438f, -4.583f)\n            lineToRelative(-2.75f, 3.667f)\n            lineToRelative(-2.063f, -2.75f)\n            lineToRelative(-2.75f, 3.667f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageResize: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ImageResize\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 9f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(6f)\n            verticalLineToRelative(6f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(3f, 21f)\n            verticalLineToRelative(-6f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(2f)\n            horizontalLineTo(3f)\n            close()\n            moveTo(3f, 13f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(3f, 9f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(3f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(7f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(11f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(11f, 5f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(15f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 17f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 13f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 5f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(-14f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6.5f, 16.792f)\n            lineToRelative(11f, 0f)\n            lineToRelative(-3.438f, -4.583f)\n            lineToRelative(-2.75f, 3.667f)\n            lineToRelative(-2.063f, -2.75f)\n            lineToRelative(-2.75f, 3.667f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageSaw.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageSaw: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImageSawTwoTone\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 14.143f)\n            lineToRelative(10f, 0f)\n            lineToRelative(-3.214f, -4.286f)\n            lineToRelative(-2.5f, 3.214f)\n            lineToRelative(-1.786f, -2.143f)\n            lineToRelative(-2.5f, 3.214f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 15f)\n            lineToRelative(2f, -2f)\n            verticalLineToRelative(-4f)\n            curveToRelative(-2.3f, 1.4f, -2.2f, -0.5f, -2.2f, -0.5f)\n            verticalLineToRelative(-2.9f)\n            lineToRelative(-2.8f, -2.8f)\n            curveToRelative(-0.7f, 2.6f, -2f, 1.2f, -2f, 1.2f)\n            lineToRelative(-2f, -2f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(1.4f, 2.3f, -0.5f, 2.2f, -0.5f, 2.2f)\n            horizontalLineToRelative(-2.9f)\n            lineToRelative(-2.8f, 2.9f)\n            curveToRelative(2.6f, 0.6f, 1.2f, 1.9f, 1.2f, 1.9f)\n            lineToRelative(-2f, 2f)\n            verticalLineToRelative(4f)\n            curveToRelative(2.3f, -1.4f, 2.2f, 0.5f, 2.2f, 0.5f)\n            verticalLineToRelative(2.8f)\n            lineToRelative(2.8f, 2.8f)\n            curveToRelative(0.7f, -2.5f, 2f, -1.1f, 2f, -1.1f)\n            lineToRelative(2f, 2f)\n            horizontalLineToRelative(4f)\n            curveToRelative(-1.4f, -2.3f, 0.5f, -2.2f, 0.5f, -2.2f)\n            horizontalLineToRelative(2.8f)\n            lineToRelative(2.8f, -2.8f)\n            curveToRelative(-2.5f, -0.7f, -1.1f, -2f, -1.1f, -2f)\n            close()\n            moveTo(12f, 19f)\n            curveToRelative(-3.866f, 0f, -7f, -3.134f, -7f, -7f)\n            reflectiveCurveToRelative(3.134f, -7f, 7f, -7f)\n            reflectiveCurveToRelative(7f, 3.134f, 7f, 7f)\n            reflectiveCurveToRelative(-3.134f, 7f, -7f, 7f)\n            close()\n        }\n    }.build()\n}\nval Icons.TwoTone.ImageSaw: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ImageSawTwoTone\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 5f)\n            lineTo(12f, 5f)\n            arcTo(7f, 7f, 0f, isMoreThanHalf = false, isPositiveArc = true, 19f, 12f)\n            lineTo(19f, 12f)\n            arcTo(7f, 7f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12f, 19f)\n            lineTo(12f, 19f)\n            arcTo(7f, 7f, 0f, isMoreThanHalf = false, isPositiveArc = true, 5f, 12f)\n            lineTo(5f, 12f)\n            arcTo(7f, 7f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12f, 5f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 14.143f)\n            lineToRelative(10f, 0f)\n            lineToRelative(-3.214f, -4.286f)\n            lineToRelative(-2.5f, 3.214f)\n            lineToRelative(-1.786f, -2.143f)\n            lineToRelative(-2.5f, 3.214f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 15f)\n            lineToRelative(2f, -2f)\n            verticalLineToRelative(-4f)\n            curveToRelative(-2.3f, 1.4f, -2.2f, -0.5f, -2.2f, -0.5f)\n            verticalLineToRelative(-2.9f)\n            lineToRelative(-2.8f, -2.8f)\n            curveToRelative(-0.7f, 2.6f, -2f, 1.2f, -2f, 1.2f)\n            lineToRelative(-2f, -2f)\n            horizontalLineToRelative(-4f)\n            curveToRelative(1.4f, 2.3f, -0.5f, 2.2f, -0.5f, 2.2f)\n            horizontalLineToRelative(-2.9f)\n            lineToRelative(-2.8f, 2.9f)\n            curveToRelative(2.6f, 0.6f, 1.2f, 1.9f, 1.2f, 1.9f)\n            lineToRelative(-2f, 2f)\n            verticalLineToRelative(4f)\n            curveToRelative(2.3f, -1.4f, 2.2f, 0.5f, 2.2f, 0.5f)\n            verticalLineToRelative(2.8f)\n            lineToRelative(2.8f, 2.8f)\n            curveToRelative(0.7f, -2.5f, 2f, -1.1f, 2f, -1.1f)\n            lineToRelative(2f, 2f)\n            horizontalLineToRelative(4f)\n            curveToRelative(-1.4f, -2.3f, 0.5f, -2.2f, 0.5f, -2.2f)\n            horizontalLineToRelative(2.8f)\n            lineToRelative(2.8f, -2.8f)\n            curveToRelative(-2.5f, -0.7f, -1.1f, -2f, -1.1f, -2f)\n            close()\n            moveTo(12f, 19f)\n            curveToRelative(-3.866f, 0f, -7f, -3.134f, -7f, -7f)\n            reflectiveCurveToRelative(3.134f, -7f, 7f, -7f)\n            reflectiveCurveToRelative(7f, 3.134f, 7f, 7f)\n            reflectiveCurveToRelative(-3.134f, 7f, -7f, 7f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageSearch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ImageSearch: ImageVector by lazy {\n    Builder(\n        name = \"ImageSearch\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.5f, 2.0f)\n            curveTo(18.0f, 2.0f, 20.0f, 4.0f, 20.0f, 6.5f)\n            curveTo(20.0f, 7.38f, 19.75f, 8.21f, 19.31f, 8.9f)\n            lineTo(22.39f, 12.0f)\n            lineTo(21.0f, 13.39f)\n            lineTo(17.88f, 10.32f)\n            curveTo(17.19f, 10.75f, 16.37f, 11.0f, 15.5f, 11.0f)\n            curveTo(13.0f, 11.0f, 11.0f, 9.0f, 11.0f, 6.5f)\n            curveTo(11.0f, 4.0f, 13.0f, 2.0f, 15.5f, 2.0f)\n            moveTo(15.5f, 4.0f)\n            arcTo(\n                2.5f, 2.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 13.0f,\n                y1 = 6.5f\n            )\n            arcTo(\n                2.5f, 2.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 15.5f,\n                y1 = 9.0f\n            )\n            arcTo(\n                2.5f, 2.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 18.0f,\n                y1 = 6.5f\n            )\n            arcTo(\n                2.5f, 2.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 15.5f,\n                y1 = 4.0f\n            )\n            moveTo(7.5f, 14.5f)\n            lineTo(4.0f, 19.0f)\n            horizontalLineTo(18.0f)\n            lineTo(13.5f, 13.0f)\n            lineTo(10.0f, 17.5f)\n            lineTo(7.5f, 14.5f)\n            moveTo(20.0f, 20.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 18.0f,\n                y1 = 22.0f\n            )\n            horizontalLineTo(4.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 2.0f,\n                y1 = 20.0f\n            )\n            verticalLineTo(6.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 4.0f,\n                y1 = 4.0f\n            )\n            horizontalLineTo(9.5f)\n            curveTo(9.18f, 4.77f, 9.0f, 5.61f, 9.0f, 6.5f)\n            arcTo(\n                6.5f, 6.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 15.5f,\n                y1 = 13.0f\n            )\n            curveTo(16.18f, 13.0f, 16.84f, 12.89f, 17.46f, 12.7f)\n            lineTo(20.0f, 15.24f)\n            verticalLineTo(20.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageSticky.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageSticky: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImageSticky\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.412f, 3.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(5f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10.175f)\n            curveToRelative(0.267f, 0f, 0.521f, -0.05f, 0.763f, -0.15f)\n            curveToRelative(0.242f, -0.1f, 0.454f, -0.242f, 0.638f, -0.425f)\n            lineToRelative(3.85f, -3.85f)\n            curveToRelative(0.183f, -0.183f, 0.325f, -0.396f, 0.425f, -0.638f)\n            curveToRelative(0.1f, -0.242f, 0.15f, -0.496f, 0.15f, -0.763f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(19f, 15f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(2f)\n            horizontalLineTo(5f)\n            verticalLineTo(5f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 19f)\n            verticalLineTo(5f)\n            verticalLineToRelative(14f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.281f, 13.968f)\n            curveToRelative(-0.248f, 0f, -0.434f, -0.114f, -0.558f, -0.341f)\n            reflectiveCurveToRelative(-0.103f, -0.444f, 0.062f, -0.651f)\n            lineToRelative(1.395f, -1.86f)\n            curveToRelative(0.124f, -0.165f, 0.289f, -0.248f, 0.496f, -0.248f)\n            reflectiveCurveToRelative(0.372f, 0.083f, 0.496f, 0.248f)\n            lineToRelative(1.209f, 1.612f)\n            lineToRelative(1.829f, -2.449f)\n            curveToRelative(0.124f, -0.165f, 0.289f, -0.248f, 0.496f, -0.248f)\n            reflectiveCurveToRelative(0.372f, 0.083f, 0.496f, 0.248f)\n            lineToRelative(2.015f, 2.697f)\n            curveToRelative(0.165f, 0.207f, 0.186f, 0.424f, 0.062f, 0.651f)\n            reflectiveCurveToRelative(-0.31f, 0.341f, -0.558f, 0.341f)\n            horizontalLineToRelative(-7.439f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageSync.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ImageSync: ImageVector by lazy {\n    Builder(\n        name = \"ImageSync\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(8.5f, 13.5f)\n            lineTo(5.0f, 18.0f)\n            horizontalLineTo(13.03f)\n            curveTo(13.11f, 19.1f, 13.47f, 20.12f, 14.03f, 21.0f)\n            horizontalLineTo(5.0f)\n            curveTo(3.9f, 21.0f, 3.0f, 20.11f, 3.0f, 19.0f)\n            verticalLineTo(5.0f)\n            curveTo(3.0f, 3.9f, 3.9f, 3.0f, 5.0f, 3.0f)\n            horizontalLineTo(19.0f)\n            curveTo(20.1f, 3.0f, 21.0f, 3.89f, 21.0f, 5.0f)\n            verticalLineTo(11.18f)\n            curveTo(20.5f, 11.07f, 20.0f, 11.0f, 19.5f, 11.0f)\n            curveTo(17.78f, 11.0f, 16.23f, 11.67f, 15.07f, 12.76f)\n            lineTo(14.5f, 12.0f)\n            lineTo(11.0f, 16.5f)\n            lineTo(8.5f, 13.5f)\n            moveTo(19.0f, 20.0f)\n            curveTo(17.62f, 20.0f, 16.5f, 18.88f, 16.5f, 17.5f)\n            curveTo(16.5f, 17.1f, 16.59f, 16.72f, 16.76f, 16.38f)\n            lineTo(15.67f, 15.29f)\n            curveTo(15.25f, 15.92f, 15.0f, 16.68f, 15.0f, 17.5f)\n            curveTo(15.0f, 19.71f, 16.79f, 21.5f, 19.0f, 21.5f)\n            verticalLineTo(23.0f)\n            lineTo(21.25f, 20.75f)\n            lineTo(19.0f, 18.5f)\n            verticalLineTo(20.0f)\n            moveTo(19.0f, 13.5f)\n            verticalLineTo(12.0f)\n            lineTo(16.75f, 14.25f)\n            lineTo(19.0f, 16.5f)\n            verticalLineTo(15.0f)\n            curveTo(20.38f, 15.0f, 21.5f, 16.12f, 21.5f, 17.5f)\n            curveTo(21.5f, 17.9f, 21.41f, 18.28f, 21.24f, 18.62f)\n            lineTo(22.33f, 19.71f)\n            curveTo(22.75f, 19.08f, 23.0f, 18.32f, 23.0f, 17.5f)\n            curveTo(23.0f, 15.29f, 21.21f, 13.5f, 19.0f, 13.5f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.ImageSync: ImageVector by lazy {\n    Builder(\n        name = \"ImageSync Outline\", defaultWidth = 24.0.dp, defaultHeight\n        = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(13.18f, 19.0f)\n            curveTo(13.35f, 19.72f, 13.64f, 20.39f, 14.03f, 21.0f)\n            horizontalLineTo(5.0f)\n            curveTo(3.9f, 21.0f, 3.0f, 20.11f, 3.0f, 19.0f)\n            verticalLineTo(5.0f)\n            curveTo(3.0f, 3.9f, 3.9f, 3.0f, 5.0f, 3.0f)\n            horizontalLineTo(19.0f)\n            curveTo(20.11f, 3.0f, 21.0f, 3.9f, 21.0f, 5.0f)\n            verticalLineTo(11.18f)\n            curveTo(20.5f, 11.07f, 20.0f, 11.0f, 19.5f, 11.0f)\n            curveTo(19.33f, 11.0f, 19.17f, 11.0f, 19.0f, 11.03f)\n            verticalLineTo(5.0f)\n            horizontalLineTo(5.0f)\n            verticalLineTo(19.0f)\n            horizontalLineTo(13.18f)\n            moveTo(11.21f, 15.83f)\n            lineTo(9.25f, 13.47f)\n            lineTo(6.5f, 17.0f)\n            horizontalLineTo(13.03f)\n            curveTo(13.14f, 15.54f, 13.73f, 14.22f, 14.64f, 13.19f)\n            lineTo(13.96f, 12.29f)\n            lineTo(11.21f, 15.83f)\n            moveTo(19.0f, 13.5f)\n            verticalLineTo(12.0f)\n            lineTo(16.75f, 14.25f)\n            lineTo(19.0f, 16.5f)\n            verticalLineTo(15.0f)\n            curveTo(20.38f, 15.0f, 21.5f, 16.12f, 21.5f, 17.5f)\n            curveTo(21.5f, 17.9f, 21.41f, 18.28f, 21.24f, 18.62f)\n            lineTo(22.33f, 19.71f)\n            curveTo(22.75f, 19.08f, 23.0f, 18.32f, 23.0f, 17.5f)\n            curveTo(23.0f, 15.29f, 21.21f, 13.5f, 19.0f, 13.5f)\n            moveTo(19.0f, 20.0f)\n            curveTo(17.62f, 20.0f, 16.5f, 18.88f, 16.5f, 17.5f)\n            curveTo(16.5f, 17.1f, 16.59f, 16.72f, 16.76f, 16.38f)\n            lineTo(15.67f, 15.29f)\n            curveTo(15.25f, 15.92f, 15.0f, 16.68f, 15.0f, 17.5f)\n            curveTo(15.0f, 19.71f, 16.79f, 21.5f, 19.0f, 21.5f)\n            verticalLineTo(23.0f)\n            lineTo(21.25f, 20.75f)\n            lineTo(19.0f, 18.5f)\n            verticalLineTo(20.0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageText.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageText: ImageVector by lazy {\n    Builder(\n        name = \"ImageText\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(14.4125f, 5.5875f)\n            curveTo(14.0208f, 5.1959f, 13.55f, 5.0f, 13.0f, 5.0f)\n            horizontalLineTo(3.0f)\n            curveTo(2.45f, 5.0f, 1.9792f, 5.1959f, 1.5875f, 5.5875f)\n            reflectiveCurveTo(1.0f, 6.45f, 1.0f, 7.0f)\n            verticalLineToRelative(10.0f)\n            curveToRelative(0.0f, 0.55f, 0.1959f, 1.0208f, 0.5875f, 1.4125f)\n            reflectiveCurveTo(2.45f, 19.0f, 3.0f, 19.0f)\n            horizontalLineToRelative(10.0f)\n            curveToRelative(0.55f, 0.0f, 1.0208f, -0.1959f, 1.4125f, -0.5875f)\n            reflectiveCurveTo(15.0f, 17.55f, 15.0f, 17.0f)\n            verticalLineTo(7.0f)\n            curveTo(15.0f, 6.45f, 14.8041f, 5.9792f, 14.4125f, 5.5875f)\n            close()\n            moveTo(13.0f, 17.0f)\n            horizontalLineTo(3.0f)\n            verticalLineTo(7.0f)\n            horizontalLineToRelative(10.0f)\n            verticalLineTo(17.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(4.0f, 15.0f)\n            lineToRelative(8.0f, 0.0f)\n            lineToRelative(-2.6f, -3.5f)\n            lineToRelative(-1.9f, 2.5f)\n            lineToRelative(-1.4f, -1.85f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(3.0f, 17.0f)\n            verticalLineToRelative(-10.0f)\n            verticalLineTo(17.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.0f, 5.1755f)\n            horizontalLineToRelative(6.0f)\n            verticalLineToRelative(3.0f)\n            horizontalLineToRelative(-6.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.0f, 15.8245f)\n            horizontalLineToRelative(6.0f)\n            verticalLineToRelative(3.0f)\n            horizontalLineToRelative(-6.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.8404f, 10.5f)\n            horizontalLineToRelative(6.0f)\n            verticalLineToRelative(3.0f)\n            horizontalLineToRelative(-6.0f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageText: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"TwoTone.ImageText\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(14.413f, 5.587f)\n            curveToRelative(-0.392f, -0.392f, -0.863f, -0.588f, -1.413f, -0.588f)\n            horizontalLineTo(3f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.413f, 0.588f)\n            reflectiveCurveToRelative(-0.587f, 0.862f, -0.587f, 1.412f)\n            verticalLineToRelative(10f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.587f, 1.413f)\n            reflectiveCurveToRelative(0.863f, 0.587f, 1.413f, 0.587f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.587f)\n            reflectiveCurveToRelative(0.587f, -0.863f, 0.587f, -1.413f)\n            verticalLineTo(7f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.587f, -1.412f)\n            close()\n            moveTo(13f, 17f)\n            horizontalLineTo(3f)\n            verticalLineTo(7f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(3f, 7f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(10f)\n            horizontalLineToRelative(-10f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(4f, 15f)\n            horizontalLineToRelative(8f)\n            lineToRelative(-2.6f, -3.5f)\n            lineToRelative(-1.9f, 2.5f)\n            lineToRelative(-1.4f, -1.85f)\n            lineToRelative(-2.1f, 2.85f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(3f, 17f)\n            verticalLineTo(7f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(17f, 5.175f)\n            horizontalLineToRelative(6f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-6f)\n            verticalLineToRelative(-3f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(17f, 15.824f)\n            horizontalLineToRelative(6f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-6f)\n            verticalLineToRelative(-3f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(16.84f, 10.5f)\n            horizontalLineToRelative(6f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-6f)\n            verticalLineToRelative(-3f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageToText.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageToText: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImageToText\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.399f, 18f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.713f, -0.288f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.288f, 0.713f, -0.288f)\n            horizontalLineToRelative(5f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.288f)\n            curveToRelative(0.192f, 0.192f, 0.288f, 0.429f, 0.288f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.288f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.288f, -0.712f, 0.288f)\n            curveToRelative(0f, 0f, -5f, 0f, -5f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.542f, 9.349f)\n            lineToRelative(2.636f, -3.509f)\n            curveToRelative(0.066f, -0.088f, 0.146f, -0.154f, 0.239f, -0.198f)\n            reflectiveCurveToRelative(0.189f, -0.066f, 0.288f, -0.066f)\n            reflectiveCurveToRelative(0.195f, 0.022f, 0.288f, 0.066f)\n            reflectiveCurveToRelative(0.173f, 0.11f, 0.239f, 0.198f)\n            lineToRelative(2.241f, 2.982f)\n            curveToRelative(0.066f, 0.088f, 0.143f, 0.154f, 0.231f, 0.198f)\n            reflectiveCurveToRelative(0.187f, 0.066f, 0.297f, 0.066f)\n            curveToRelative(0.275f, 0f, 0.472f, -0.124f, 0.593f, -0.371f)\n            reflectiveCurveToRelative(0.099f, -0.481f, -0.066f, -0.7f)\n            lineToRelative(-1.384f, -1.829f)\n            curveToRelative(-0.088f, -0.121f, -0.132f, -0.253f, -0.132f, -0.395f)\n            curveToRelative(0f, -0.143f, 0.044f, -0.275f, 0.132f, -0.395f)\n            lineToRelative(1.647f, -2.191f)\n            curveToRelative(0.066f, -0.088f, 0.146f, -0.154f, 0.239f, -0.198f)\n            reflectiveCurveToRelative(0.189f, -0.066f, 0.288f, -0.066f)\n            reflectiveCurveToRelative(0.195f, 0.022f, 0.288f, 0.066f)\n            reflectiveCurveToRelative(0.173f, 0.11f, 0.239f, 0.198f)\n            lineToRelative(4.613f, 6.145f)\n            curveToRelative(0.165f, 0.22f, 0.187f, 0.45f, 0.066f, 0.692f)\n            reflectiveCurveToRelative(-0.319f, 0.362f, -0.593f, 0.362f)\n            horizontalLineToRelative(-11.862f)\n            curveToRelative(-0.275f, 0f, -0.472f, -0.121f, -0.593f, -0.362f)\n            curveToRelative(-0.121f, -0.242f, -0.099f, -0.472f, 0.066f, -0.692f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.399f, 15f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.713f, -0.288f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.288f, 0.713f, -0.288f)\n            horizontalLineToRelative(5f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.288f)\n            curveToRelative(0.192f, 0.192f, 0.288f, 0.429f, 0.288f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.288f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.288f, -0.712f, 0.288f)\n            curveToRelative(0f, 0f, -5f, 0f, -5f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.112f, 12.287f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.288f, 0.429f, -0.288f, 0.713f)\n            verticalLineToRelative(5.822f)\n            curveToRelative(0f, 0.032f, 0.014f, 0.058f, 0.016f, 0.089f)\n            curveToRelative(-0.003f, 0.031f, -0.016f, 0.057f, -0.016f, 0.089f)\n            verticalLineToRelative(1f)\n            horizontalLineTo(5.399f)\n            verticalLineTo(4f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.713f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(16f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(11f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.588f)\n            curveToRelative(0.392f, -0.392f, 0.587f, -0.862f, 0.587f, -1.412f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.032f, -0.014f, -0.058f, -0.016f, -0.089f)\n            curveToRelative(0.003f, -0.031f, 0.016f, -0.057f, 0.016f, -0.089f)\n            verticalLineToRelative(-5.822f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.713f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageToolboxBroken.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageToolboxBroken: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.ImageToolboxBroken\",\n        defaultWidth = 1305.dp,\n        defaultHeight = 1295.dp,\n        viewportWidth = 1305f,\n        viewportHeight = 1295f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            pathFillType = PathFillType.EvenOdd\n        ) {\n            moveTo(794.4f, 452.5f)\n            verticalLineToRelative(93.6f)\n            curveToRelative(0f, 16.1f, 5.4f, 29.5f, 16.3f, 40.4f)\n            curveToRelative(10.9f, 10.9f, 24.3f, 16.3f, 40.4f, 16.3f)\n            horizontalLineToRelative(93.6f)\n            curveToRelative(7.6f, 0f, 14.9f, -1.4f, 22f, -4.3f)\n            curveToRelative(7.1f, -2.8f, 13.5f, -7.1f, 19.1f, -12.8f)\n            lineToRelative(295f, -295f)\n            curveToRelative(8.5f, -8.5f, 14.7f, -18.2f, 18.4f, -29.1f)\n            curveToRelative(3.8f, -10.9f, 5.7f, -21.5f, 5.7f, -31.9f)\n            curveToRelative(0f, -10.4f, -2.1f, -20.8f, -6.4f, -31.2f)\n            curveToRelative(-4.3f, -10.4f, -10.2f, -19.9f, -17.7f, -28.4f)\n            lineToRelative(-52.5f, -52.5f)\n            curveToRelative(-8.5f, -8.5f, -18f, -14.9f, -28.4f, -19.1f)\n            curveToRelative(-10.4f, -4.3f, -21.3f, -6.4f, -32.6f, -6.4f)\n            curveToRelative(-10.4f, 0f, -20.8f, 1.9f, -31.2f, 5.7f)\n            curveToRelative(-10.4f, 3.8f, -19.9f, 9.9f, -28.4f, 18.4f)\n            lineToRelative(-296.4f, 295f)\n            curveToRelative(-5.7f, 5.7f, -9.9f, 12.1f, -12.8f, 19.1f)\n            curveTo(795.8f, 437.6f, 794.4f, 444.9f, 794.4f, 452.5f)\n            close()\n            moveTo(933.4f, 517.7f)\n            horizontalLineToRelative(-53.9f)\n            verticalLineToRelative(-53.9f)\n            lineToRelative(173f, -171.6f)\n            lineToRelative(52.5f, 52.5f)\n            lineTo(933.4f, 517.7f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(657.8f, 301.6f)\n            curveToRelative(69.4f, 0f, 125.2f, 0.3f, 171.5f, 2.2f)\n            lineToRelative(94f, -94f)\n            curveToRelative(-70.8f, -9.6f, -162.9f, -9.6f, -289.3f, -9.6f)\n            curveToRelative(-5.1f, 0f, -10.1f, 0f, -15.1f, 0f)\n            lineTo(657.8f, 301.6f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(1029f, 1268.8f)\n            curveToRelative(12.8f, -6.2f, 24.6f, -13.4f, 35.8f, -21.7f)\n            curveToRelative(23.7f, -17.6f, 44.7f, -38.6f, 62.3f, -62.3f)\n            curveToRelative(60.4f, -81.1f, 60.4f, -197.7f, 60.4f, -430.9f)\n            curveToRelative(0f, -115.3f, 0f, -202.2f, -7.3f, -270.3f)\n            lineToRelative(-95.5f, 95.5f)\n            curveToRelative(1.4f, 47.6f, 1.5f, 104.5f, 1.5f, 174.7f)\n            curveToRelative(0f, 16.5f, 0f, 32.3f, 0f, 47.5f)\n            curveToRelative(-49.3f, -41f, -87.3f, -60.7f, -144.1f, -37.7f)\n            curveToRelative(-29.4f, 11.9f, -58.5f, 30.6f, -86.9f, 52.5f)\n            lineTo(1029f, 1268.8f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(493.8f, 352.3f)\n            curveToRelative(-6.3f, -14.6f, -14.9f, -27.4f, -25.7f, -38.2f)\n            curveToRelative(-10.8f, -10.8f, -23.6f, -19.4f, -38.2f, -25.7f)\n            curveToRelative(-14.6f, -6.3f, -30.3f, -9.5f, -46.9f, -9.5f)\n            reflectiveCurveToRelative(-32.3f, 3.2f, -46.9f, 9.5f)\n            reflectiveCurveToRelative(-27.4f, 14.9f, -38.2f, 25.7f)\n            curveToRelative(-10.8f, 10.8f, -19.4f, 23.6f, -25.7f, 38.2f)\n            curveToRelative(-6.3f, 14.6f, -9.5f, 30.3f, -9.5f, 46.9f)\n            reflectiveCurveToRelative(3.2f, 32.3f, 9.5f, 46.9f)\n            reflectiveCurveToRelative(14.9f, 27.4f, 25.7f, 38.2f)\n            curveToRelative(10.8f, 10.8f, 23.6f, 19.4f, 38.2f, 25.7f)\n            curveToRelative(14.6f, 6.3f, 30.3f, 9.5f, 46.9f, 9.5f)\n            reflectiveCurveToRelative(32.3f, -3.2f, 46.9f, -9.5f)\n            curveToRelative(14.6f, -6.3f, 27.4f, -14.9f, 38.2f, -25.7f)\n            curveToRelative(10.8f, -10.8f, 19.4f, -23.6f, 25.7f, -38.2f)\n            curveToRelative(6.3f, -14.6f, 9.5f, -30.3f, 9.5f, -46.9f)\n            reflectiveCurveTo(500.1f, 367f, 493.8f, 352.3f)\n            close()\n            moveTo(392.2f, 460f)\n            curveToRelative(-2.5f, 2.5f, -5.5f, 3.7f, -9.2f, 3.7f)\n            reflectiveCurveToRelative(-6.7f, -1.2f, -9.2f, -3.7f)\n            curveToRelative(-2.5f, -2.5f, -3.7f, -5.5f, -3.7f, -9.2f)\n            reflectiveCurveToRelative(1.2f, -6.7f, 3.7f, -9.2f)\n            curveToRelative(2.5f, -2.5f, 5.5f, -3.7f, 9.2f, -3.7f)\n            reflectiveCurveToRelative(6.7f, 1.2f, 9.2f, 3.7f)\n            curveToRelative(2.5f, 2.5f, 3.7f, 5.5f, 3.7f, 9.2f)\n            reflectiveCurveTo(394.6f, 457.6f, 392.2f, 460f)\n            close()\n            moveTo(395.9f, 399.3f)\n            curveToRelative(0f, 3.7f, -1.2f, 6.7f, -3.7f, 9.2f)\n            curveToRelative(-2.5f, 2.5f, -5.5f, 3.7f, -9.2f, 3.7f)\n            reflectiveCurveToRelative(-6.7f, -1.2f, -9.2f, -3.7f)\n            reflectiveCurveToRelative(-3.7f, -5.5f, -3.7f, -9.2f)\n            verticalLineToRelative(-51.6f)\n            curveToRelative(0f, -3.7f, 1.2f, -6.7f, 3.7f, -9.2f)\n            curveToRelative(2.5f, -2.5f, 5.5f, -3.7f, 9.2f, -3.7f)\n            reflectiveCurveToRelative(6.7f, 1.2f, 9.2f, 3.7f)\n            curveToRelative(2.5f, 2.5f, 3.7f, 5.5f, 3.7f, 9.2f)\n            verticalLineTo(399.3f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(338.5f, 837.2f)\n            lineToRelative(75.9f, 22.8f)\n            lineToRelative(32.7f, -33.6f)\n            lineToRelative(-64.6f, -39.7f)\n            curveToRelative(-6.5f, -3.7f, -13.1f, -6.7f, -19.7f, -9.1f)\n            lineTo(338.5f, 837.2f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(763.4f, 887.4f)\n            lineToRelative(-24.2f, -69.5f)\n            lineToRelative(-201f, 42.6f)\n            lineToRelative(128f, 108.2f)\n            lineTo(528.8f, 890f)\n            lineToRelative(0f, 0.6f)\n            lineToRelative(-3f, -2.3f)\n            lineToRelative(-80.6f, -1.7f)\n            lineToRelative(81.4f, 186.8f)\n            horizontalLineToRelative(0f)\n            lineToRelative(-78.3f, -115f)\n            lineToRelative(-123.7f, 100.7f)\n            lineToRelative(99.7f, -135.8f)\n            lineToRelative(-25.4f, -37.4f)\n            lineToRelative(-84.1f, -25.2f)\n            lineToRelative(-15.3f, -4.6f)\n            lineToRelative(6f, -14.9f)\n            lineToRelative(28.3f, -69.5f)\n            curveToRelative(-69.2f, -5f, -145.2f, 50.4f, -219.1f, 104.2f)\n            lineToRelative(-1f, 0.7f)\n            curveToRelative(-2f, -10.6f, -3.7f, -22.4f, -5.2f, -35.8f)\n            curveToRelative(-6.8f, -61.6f, -6.9f, -142.5f, -6.9f, -261.4f)\n            reflectiveCurveToRelative(0.1f, -199.8f, 6.9f, -261.4f)\n            curveToRelative(6.6f, -59.6f, 18.4f, -88.8f, 33.4f, -109f)\n            curveToRelative(11.8f, -15.8f, 25.8f, -29.8f, 41.6f, -41.6f)\n            curveToRelative(20.2f, -15f, 49.3f, -26.8f, 109f, -33.4f)\n            curveToRelative(46.2f, -5.1f, 103.3f, -6.5f, 179.2f, -6.8f)\n            lineTo(432.8f, 26.2f)\n            curveToRelative(-155.3f, 1.8f, -244.3f, 11.1f, -310f, 60f)\n            curveToRelative(-23.7f, 17.6f, -44.7f, 38.6f, -62.3f, 62.3f)\n            curveTo(0.1f, 229.6f, 0.1f, 346.2f, 0.1f, 579.4f)\n            reflectiveCurveToRelative(0f, 349.8f, 60.4f, 430.9f)\n            curveToRelative(17.6f, 23.7f, 38.6f, 44.7f, 62.3f, 62.3f)\n            curveToRelative(81.1f, 60.4f, 197.7f, 60.4f, 430.9f, 60.4f)\n            curveToRelative(132.7f, 0f, 227.6f, 0f, 299.7f, -11.1f)\n            lineTo(763.4f, 887.4f)\n            close()\n            moveTo(299.4f, 1073.4f)\n            lineTo(299.4f, 1073.4f)\n            curveTo(299.4f, 1073.3f, 299.4f, 1073.3f, 299.4f, 1073.4f)\n            lineTo(299.4f, 1073.4f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(723.5f, 783.5f)\n            lineToRelative(-9f, -23.4f)\n            lineToRelative(-17.5f, -45.5f)\n            lineToRelative(-47.9f, 37.7f)\n            curveToRelative(-14.6f, 13.1f, -29f, 25.5f, -43.1f, 36.7f)\n            lineToRelative(-8.8f, 6.8f)\n            curveToRelative(-0.2f, 0.2f, -0.4f, 0.3f, -0.6f, 0.5f)\n            lineToRelative(0f, 0f)\n            lineToRelative(-29.4f, 20.4f)\n            lineTo(723.5f, 783.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageTooltip.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageTooltip: ImageVector by lazy {\n    Builder(\n        name = \"Image Tooltip\", defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(4.0f, 2.0f)\n            horizontalLineTo(20.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 22.0f,\n                y1 = 4.0f\n            )\n            verticalLineTo(16.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 20.0f,\n                y1 = 18.0f\n            )\n            horizontalLineTo(16.0f)\n            lineTo(12.0f, 22.0f)\n            lineTo(8.0f, 18.0f)\n            horizontalLineTo(4.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 2.0f,\n                y1 = 16.0f\n            )\n            verticalLineTo(4.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 4.0f,\n                y1 = 2.0f\n            )\n            moveTo(4.0f, 4.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(8.83f)\n            lineTo(12.0f, 19.17f)\n            lineTo(15.17f, 16.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(4.0f)\n            horizontalLineTo(4.0f)\n            moveTo(7.5f, 6.0f)\n            arcTo(\n                1.5f, 1.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 9.0f,\n                y1 = 7.5f\n            )\n            arcTo(\n                1.5f, 1.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 7.5f,\n                y1 = 9.0f\n            )\n            arcTo(\n                1.5f, 1.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 6.0f,\n                y1 = 7.5f\n            )\n            arcTo(\n                1.5f, 1.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 7.5f,\n                y1 = 6.0f\n            )\n            moveTo(6.0f, 14.0f)\n            lineTo(11.0f, 9.0f)\n            lineTo(13.0f, 11.0f)\n            lineTo(18.0f, 6.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(6.0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImageWeight.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImageWeight: ImageVector by lazy {\n    Builder(\n        name = \"Image Weight\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.0f, 19.0f)\n            horizontalLineToRelative(12.0f)\n            lineTo(16.575f, 9.0f)\n            horizontalLineTo(7.425f)\n            lineTo(6.0f, 19.0f)\n            close()\n            moveTo(12.0f, 7.0f)\n            curveToRelative(0.2833f, 0.0f, 0.5208f, -0.0958f, 0.7125f, -0.2875f)\n            reflectiveCurveTo(13.0f, 6.2833f, 13.0f, 6.0f)\n            reflectiveCurveToRelative(-0.0958f, -0.5208f, -0.2875f, -0.7125f)\n            curveTo(12.5208f, 5.0958f, 12.2833f, 5.0f, 12.0f, 5.0f)\n            reflectiveCurveToRelative(-0.5208f, 0.0958f, -0.7125f, 0.2875f)\n            curveTo(11.0958f, 5.4792f, 11.0f, 5.7167f, 11.0f, 6.0f)\n            reflectiveCurveToRelative(0.0958f, 0.5208f, 0.2875f, 0.7125f)\n            reflectiveCurveTo(11.7167f, 7.0f, 12.0f, 7.0f)\n            close()\n            moveTo(14.825f, 7.0f)\n            horizontalLineToRelative(1.75f)\n            curveToRelative(0.5f, 0.0f, 0.9333f, 0.1667f, 1.3f, 0.5f)\n            curveToRelative(0.3667f, 0.3333f, 0.5917f, 0.7417f, 0.675f, 1.225f)\n            lineToRelative(1.425f, 10.0f)\n            curveToRelative(0.0833f, 0.6f, -0.0708f, 1.1292f, -0.4625f, 1.5875f)\n            curveTo(19.1208f, 20.7708f, 18.6167f, 21.0f, 18.0f, 21.0f)\n            horizontalLineTo(6.0f)\n            curveToRelative(-0.6167f, 0.0f, -1.1208f, -0.2292f, -1.5125f, -0.6875f)\n            reflectiveCurveToRelative(-0.5458f, -0.9875f, -0.4625f, -1.5875f)\n            lineToRelative(1.425f, -10.0f)\n            curveTo(5.5333f, 8.2417f, 5.7583f, 7.8333f, 6.125f, 7.5f)\n            curveToRelative(0.3667f, -0.3333f, 0.8f, -0.5f, 1.3f, -0.5f)\n            horizontalLineToRelative(1.75f)\n            curveTo(9.125f, 6.8333f, 9.0833f, 6.6708f, 9.05f, 6.5125f)\n            reflectiveCurveTo(9.0f, 6.1833f, 9.0f, 6.0f)\n            curveToRelative(0.0f, -0.8333f, 0.2917f, -1.5417f, 0.875f, -2.125f)\n            curveToRelative(0.5833f, -0.5833f, 1.2917f, -0.875f, 2.125f, -0.875f)\n            reflectiveCurveToRelative(1.5417f, 0.2917f, 2.125f, 0.875f)\n            reflectiveCurveTo(15.0f, 5.1667f, 15.0f, 6.0f)\n            curveToRelative(0.0f, 0.1833f, -0.0167f, 0.3542f, -0.05f, 0.5125f)\n            reflectiveCurveTo(14.875f, 6.8333f, 14.825f, 7.0f)\n            close()\n            moveTo(6.0f, 19.0f)\n            horizontalLineToRelative(12.0f)\n            horizontalLineTo(6.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.2442f, 15.1263f)\n            curveToRelative(-0.1654f, -0.2197f, -0.4357f, -0.5795f, -0.6007f, -0.7995f)\n            lineToRelative(-0.9704f, -1.2938f)\n            curveToRelative(-0.165f, -0.22f, -0.435f, -0.22f, -0.6f, 0.0f)\n            lineToRelative(-1.275f, 1.7f)\n            curveToRelative(-0.165f, 0.22f, -0.4354f, 0.2203f, -0.6009f, 7.0E-4f)\n            lineToRelative(-0.7733f, -1.0263f)\n            curveToRelative(-0.1655f, -0.2196f, -0.4361f, -0.2195f, -0.6014f, 2.0E-4f)\n            lineToRelative(-1.5239f, 2.0259f)\n            curveToRelative(-0.1653f, 0.2198f, -0.0756f, 0.3996f, 0.1994f, 0.3996f)\n            horizontalLineToRelative(0.9267f)\n            curveToRelative(0.275f, 0.0f, 0.725f, 0.0f, 1.0f, 0.0f)\n            horizontalLineToRelative(3.1464f)\n            curveToRelative(0.275f, 0.0f, 0.725f, 0.0f, 1.0f, 0.0f)\n            horizontalLineToRelative(0.9308f)\n            curveToRelative(0.275f, 0.0f, 0.3647f, -0.1798f, 0.1993f, -0.3995f)\n            lineTo(15.2442f, 15.1263f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ImageWeight: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"TwoTone.ImageWeight\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19.975f, 18.725f)\n            lineToRelative(-1.425f, -10f)\n            curveToRelative(-0.083f, -0.483f, -0.308f, -0.892f, -0.675f, -1.225f)\n            reflectiveCurveToRelative(-0.8f, -0.5f, -1.3f, -0.5f)\n            horizontalLineToRelative(-1.75f)\n            curveToRelative(0.05f, -0.167f, 0.092f, -0.329f, 0.125f, -0.487f)\n            curveToRelative(0.033f, -0.158f, 0.05f, -0.329f, 0.05f, -0.513f)\n            curveToRelative(0f, -0.833f, -0.292f, -1.542f, -0.875f, -2.125f)\n            reflectiveCurveToRelative(-1.292f, -0.875f, -2.125f, -0.875f)\n            reflectiveCurveToRelative(-1.542f, 0.292f, -2.125f, 0.875f)\n            reflectiveCurveToRelative(-0.875f, 1.292f, -0.875f, 2.125f)\n            curveToRelative(0f, 0.183f, 0.017f, 0.354f, 0.05f, 0.513f)\n            curveToRelative(0.033f, 0.158f, 0.075f, 0.321f, 0.125f, 0.487f)\n            horizontalLineToRelative(-1.75f)\n            curveToRelative(-0.5f, 0f, -0.933f, 0.167f, -1.3f, 0.5f)\n            reflectiveCurveToRelative(-0.592f, 0.742f, -0.675f, 1.225f)\n            lineToRelative(-1.425f, 10f)\n            curveToRelative(-0.083f, 0.6f, 0.071f, 1.129f, 0.462f, 1.588f)\n            curveToRelative(0.392f, 0.458f, 0.896f, 0.688f, 1.513f, 0.688f)\n            horizontalLineToRelative(12f)\n            curveToRelative(0.617f, 0f, 1.121f, -0.229f, 1.513f, -0.688f)\n            curveToRelative(0.392f, -0.458f, 0.546f, -0.987f, 0.462f, -1.588f)\n            close()\n            moveTo(11.287f, 5.287f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.713f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.713f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.288f, -0.713f, 0.288f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.713f, -0.288f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.713f)\n            close()\n            moveTo(6f, 19f)\n            lineToRelative(1.425f, -10f)\n            horizontalLineToRelative(9.15f)\n            lineToRelative(1.425f, 10f)\n            horizontalLineTo(6f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15.244f, 15.126f)\n            curveToRelative(-0.165f, -0.22f, -0.436f, -0.58f, -0.601f, -0.8f)\n            lineToRelative(-0.97f, -1.294f)\n            curveToRelative(-0.165f, -0.22f, -0.435f, -0.22f, -0.6f, 0f)\n            lineToRelative(-1.275f, 1.7f)\n            curveToRelative(-0.165f, 0.22f, -0.435f, 0.22f, -0.601f, 0.001f)\n            lineToRelative(-0.773f, -1.026f)\n            curveToRelative(-0.165f, -0.22f, -0.436f, -0.219f, -0.601f, 0f)\n            lineToRelative(-1.524f, 2.026f)\n            curveToRelative(-0.165f, 0.22f, -0.076f, 0.4f, 0.199f, 0.4f)\n            horizontalLineToRelative(7.004f)\n            curveToRelative(0.275f, 0f, 0.365f, -0.18f, 0.199f, -0.399f)\n            lineToRelative(-0.457f, -0.607f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6f, 19f)\n            lineToRelative(12f, 0f)\n            lineToRelative(-1.425f, -10f)\n            lineToRelative(-9.15f, 0f)\n            lineToRelative(-1.425f, 10f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 7f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.288f, -0.429f, 0.288f, -0.713f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.288f, -0.713f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.288f, 0.429f, -0.288f, 0.713f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.288f, 0.713f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(6f, 19f)\n            horizontalLineToRelative(12f)\n            horizontalLineTo(6f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImagesMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ImagesMode: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImagesMode\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(200f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120f, 760f)\n            verticalLineToRelative(-560f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(200f, 120f)\n            horizontalLineToRelative(560f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(840f, 200f)\n            verticalLineToRelative(560f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(760f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(200f, 760f)\n            horizontalLineToRelative(560f)\n            verticalLineToRelative(-560f)\n            lineTo(200f, 200f)\n            verticalLineToRelative(560f)\n            close()\n            moveTo(200f, 760f)\n            verticalLineToRelative(-560f)\n            verticalLineToRelative(560f)\n            close()\n            moveTo(280f, 680f)\n            horizontalLineToRelative(400f)\n            quadToRelative(12f, 0f, 18f, -11f)\n            reflectiveQuadToRelative(-2f, -21f)\n            lineTo(586f, 501f)\n            quadToRelative(-6f, -8f, -16f, -8f)\n            reflectiveQuadToRelative(-16f, 8f)\n            lineTo(450f, 640f)\n            lineToRelative(-74f, -99f)\n            quadToRelative(-6f, -8f, -16f, -8f)\n            reflectiveQuadToRelative(-16f, 8f)\n            lineToRelative(-80f, 107f)\n            quadToRelative(-8f, 10f, -2f, 21f)\n            reflectiveQuadToRelative(18f, 11f)\n            close()\n            moveTo(382.5f, 382.5f)\n            quadTo(400f, 365f, 400f, 340f)\n            reflectiveQuadToRelative(-17.5f, -42.5f)\n            quadTo(365f, 280f, 340f, 280f)\n            reflectiveQuadToRelative(-42.5f, 17.5f)\n            quadTo(280f, 315f, 280f, 340f)\n            reflectiveQuadToRelative(17.5f, 42.5f)\n            quadTo(315f, 400f, 340f, 400f)\n            reflectiveQuadToRelative(42.5f, -17.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ImagesearchRoller.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ImagesearchRoller: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.ImagesearchRoller\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(600f, 920f)\n            lineTo(440f, 920f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(400f, 880f)\n            verticalLineToRelative(-240f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(440f, 600f)\n            horizontalLineToRelative(40f)\n            verticalLineToRelative(-120f)\n            lineTo(160f, 480f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(80f, 400f)\n            verticalLineToRelative(-160f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(160f, 160f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-40f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(280f, 80f)\n            horizontalLineToRelative(480f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(800f, 120f)\n            verticalLineToRelative(160f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(760f, 320f)\n            lineTo(280f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(240f, 280f)\n            verticalLineToRelative(-40f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(160f)\n            horizontalLineToRelative(320f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(560f, 480f)\n            verticalLineToRelative(120f)\n            horizontalLineToRelative(40f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(640f, 640f)\n            verticalLineToRelative(240f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(600f, 920f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.ImagesearchRoller: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ImagesearchRoller\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(600f, 920f)\n            lineTo(440f, 920f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(400f, 880f)\n            verticalLineToRelative(-240f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(440f, 600f)\n            horizontalLineToRelative(40f)\n            verticalLineToRelative(-120f)\n            lineTo(160f, 480f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(80f, 400f)\n            verticalLineToRelative(-160f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(160f, 160f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-40f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(280f, 80f)\n            horizontalLineToRelative(480f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(800f, 120f)\n            verticalLineToRelative(160f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(760f, 320f)\n            lineTo(280f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(240f, 280f)\n            verticalLineToRelative(-40f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(160f)\n            horizontalLineToRelative(320f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(560f, 480f)\n            verticalLineToRelative(120f)\n            horizontalLineToRelative(40f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(640f, 640f)\n            verticalLineToRelative(240f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(600f, 920f)\n            close()\n            moveTo(480f, 840f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-160f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(160f)\n            close()\n            moveTo(320f, 240f)\n            horizontalLineToRelative(400f)\n            verticalLineToRelative(-80f)\n            lineTo(320f, 160f)\n            verticalLineToRelative(80f)\n            close()\n            moveTo(480f, 840f)\n            horizontalLineToRelative(80f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(320f, 240f)\n            verticalLineToRelative(-80f)\n            verticalLineToRelative(80f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Interface.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Interface: ImageVector by lazy {\n    Builder(\n        name = \"Interface\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.0f, 9.0f)\n            verticalLineTo(4.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(23.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(18.0f)\n            verticalLineTo(21.0f)\n            horizontalLineTo(11.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(1.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(6.0f)\n            moveTo(16.0f, 16.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(19.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(16.0f)\n            moveTo(8.0f, 9.0f)\n            horizontalLineTo(11.0f)\n            verticalLineTo(6.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(9.0f)\n            moveTo(6.0f, 14.0f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(3.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(6.0f)\n            moveTo(18.0f, 11.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(21.0f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(18.0f)\n            moveTo(13.0f, 11.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(13.0f)\n            moveTo(8.0f, 11.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(11.0f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(8.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Jpg.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Jpg: ImageVector by lazy {\n    Builder(\n        name = \"Jpg\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp, viewportWidth\n        = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(8.1429f, 13.9286f)\n            curveToRelative(0.0f, 1.4143f, -1.1571f, 1.9286f, -2.5714f, 1.9286f)\n            reflectiveCurveTo(3.0f, 15.3429f, 3.0f, 13.9286f)\n            verticalLineTo(12.0f)\n            horizontalLineToRelative(1.9286f)\n            verticalLineToRelative(1.9286f)\n            horizontalLineToRelative(1.2857f)\n            verticalLineTo(8.1429f)\n            horizontalLineToRelative(1.9286f)\n            verticalLineTo(13.9286f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(21.0f, 10.0714f)\n            horizontalLineToRelative(-3.2143f)\n            verticalLineToRelative(3.8571f)\n            horizontalLineToRelative(1.2857f)\n            verticalLineTo(12.0f)\n            horizontalLineTo(21.0f)\n            verticalLineToRelative(2.1857f)\n            curveToRelative(0.0f, 0.9f, -0.6429f, 1.6714f, -1.6714f, 1.6714f)\n            horizontalLineToRelative(-1.6714f)\n            curveToRelative(-1.0286f, 0.0f, -1.6714f, -0.9f, -1.6714f, -1.6714f)\n            verticalLineToRelative(-4.2429f)\n            curveTo(15.8571f, 9.0429f, 16.5f, 8.1429f, 17.5286f, 8.1429f)\n            horizontalLineToRelative(1.6714f)\n            curveToRelative(1.0286f, 0.0f, 1.6714f, 0.9f, 1.6714f, 1.6714f)\n            verticalLineToRelative(0.2571f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.6429f, 8.1429f)\n            horizontalLineTo(9.4286f)\n            verticalLineToRelative(7.7142f)\n            horizontalLineToRelative(1.9285f)\n            verticalLineToRelative(-2.5714f)\n            horizontalLineToRelative(1.2858f)\n            curveToRelative(1.0286f, 0.0f, 1.9285f, -0.9f, 1.9285f, -1.9286f)\n            verticalLineToRelative(-1.2857f)\n            curveTo(14.5714f, 9.0428f, 13.6714f, 8.1429f, 12.6429f, 8.1429f)\n            close()\n            moveTo(12.6429f, 11.3571f)\n            horizontalLineToRelative(-1.2858f)\n            verticalLineToRelative(-1.2857f)\n            horizontalLineToRelative(1.2858f)\n            verticalLineTo(11.3571f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Jxl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Jxl: ImageVector by lazy {\n    Builder(\n        name = \"Jxl\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp, viewportWidth\n        = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(13.1206f, 12.0514f)\n            curveToRelative(0.8368f, -1.7278f, 1.6713f, -3.4556f, 2.5059f, -5.1834f)\n            horizontalLineToRelative(-2.3242f)\n            curveToRelative(-0.5384f, 1.1136f, -1.0791f, 2.2297f, -1.6175f, 3.3433f)\n            curveTo(10.8144f, 9.0976f, 9.9439f, 7.9816f, 9.0735f, 6.868f)\n            horizontalLineTo(6.7493f)\n            lineToRelative(4.0449f, 5.1834f)\n            curveToRelative(-0.8188f, 1.692f, -1.6377f, 3.3863f, -2.4565f, 5.0783f)\n            horizontalLineToRelative(2.3242f)\n            curveToRelative(0.5227f, -1.0802f, 1.0454f, -2.1604f, 1.5659f, -3.2381f)\n            curveToRelative(0.8435f, 1.0802f, 1.6848f, 2.1604f, 2.5283f, 3.2381f)\n            horizontalLineToRelative(2.3242f)\n            curveToRelative(-1.3169f, -1.692f, -2.6382f, -3.3839f, -3.9596f, -5.0783f)\n            verticalLineTo(12.0514f)\n            close()\n            moveTo(5.4324f, 16.9504f)\n            lineToRelative(0.0067f, 0.055f)\n            lineToRelative(0.0157f, 0.0621f)\n            curveToRelative(0.0852f, 0.3609f, 0.1997f, 1.4219f, -0.2692f, 2.0624f)\n            curveToRelative(-0.1391f, 0.1912f, -0.332f, 0.3465f, -0.5743f, 0.4612f)\n            lineTo(3.2092f, 22.0f)\n            curveToRelative(0.8278f, 0.0f, 1.5569f, -0.1386f, 2.1649f, -0.4158f)\n            curveToRelative(0.581f, -0.2629f, 1.0589f, -0.65f, 1.4178f, -1.1495f)\n            curveToRelative(0.498f, -0.6906f, 0.7605f, -1.5916f, 0.7583f, -2.6072f)\n            curveToRelative(0.0f, -0.5927f, -0.0897f, -1.0658f, -0.1279f, -1.2427f)\n            lineToRelative(-0.9176f, -6.5312f)\n            horizontalLineToRelative(0.0022f)\n            verticalLineTo(7.898f)\n            horizontalLineTo(2.0f)\n            verticalLineToRelative(2.1556f)\n            horizontalLineToRelative(2.4633f)\n            lineTo(5.4324f, 16.9504f)\n            close()\n            moveTo(18.5676f, 7.0472f)\n            lineToRelative(-0.0067f, -0.055f)\n            lineToRelative(-0.0157f, -0.0621f)\n            curveToRelative(-0.0852f, -0.3609f, -0.1997f, -1.4219f, 0.2692f, -2.0624f)\n            curveToRelative(0.1391f, -0.1912f, 0.332f, -0.3465f, 0.5743f, -0.4612f)\n            lineTo(20.7908f, 2.0f)\n            curveToRelative(-0.8278f, 0.0f, -1.5569f, 0.1386f, -2.1649f, 0.4158f)\n            curveToRelative(-0.581f, 0.2629f, -1.0589f, 0.65f, -1.4178f, 1.1495f)\n            curveToRelative(-0.498f, 0.6906f, -0.7605f, 1.5916f, -0.7583f, 2.6072f)\n            curveToRelative(0.0f, 0.5927f, 0.0897f, 1.0658f, 0.1279f, 1.2427f)\n            lineToRelative(0.9176f, 6.5312f)\n            horizontalLineToRelative(-0.0022f)\n            verticalLineToRelative(2.1556f)\n            horizontalLineTo(22.0f)\n            verticalLineToRelative(-2.1556f)\n            horizontalLineToRelative(-2.4633f)\n            lineToRelative(-0.9692f, -6.8993f)\n            verticalLineTo(7.0472f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(5.4324f, 16.9504f)\n            lineToRelative(0.0067f, 0.055f)\n            lineToRelative(0.0157f, 0.0621f)\n            curveToRelative(0.0852f, 0.3609f, 0.1997f, 1.4219f, -0.2692f, 2.0624f)\n            curveToRelative(-0.1391f, 0.1912f, -0.332f, 0.3465f, -0.5743f, 0.4612f)\n            lineTo(3.2092f, 22.0f)\n            curveToRelative(0.8278f, 0.0f, 1.5569f, -0.1386f, 2.1649f, -0.4158f)\n            curveToRelative(0.581f, -0.2629f, 1.0589f, -0.65f, 1.4178f, -1.1495f)\n            curveToRelative(0.498f, -0.6906f, 0.7605f, -1.5916f, 0.7583f, -2.6072f)\n            curveToRelative(0.0f, -0.5927f, -0.0897f, -1.0658f, -0.1279f, -1.2427f)\n            lineToRelative(-0.9176f, -6.5312f)\n            horizontalLineToRelative(0.0022f)\n            verticalLineTo(7.898f)\n            horizontalLineTo(2.0f)\n            verticalLineToRelative(2.1556f)\n            horizontalLineToRelative(2.4633f)\n            lineTo(5.4324f, 16.9504f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/KeyVariant.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.KeyVariant: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"KeyVariant\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.855f, 9.083f)\n            curveToRelative(0f, -0.538f, -0.189f, -0.995f, -0.566f, -1.373f)\n            reflectiveCurveToRelative(-0.835f, -0.566f, -1.373f, -0.566f)\n            reflectiveCurveToRelative(-0.995f, 0.189f, -1.373f, 0.566f)\n            reflectiveCurveToRelative(-0.566f, 0.835f, -0.566f, 1.373f)\n            reflectiveCurveToRelative(0.189f, 0.995f, 0.566f, 1.373f)\n            reflectiveCurveToRelative(0.835f, 0.566f, 1.373f, 0.566f)\n            reflectiveCurveToRelative(0.995f, -0.189f, 1.373f, -0.566f)\n            curveToRelative(0.377f, -0.377f, 0.566f, -0.835f, 0.566f, -1.373f)\n            close()\n            moveTo(19.034f, 13.201f)\n            curveToRelative(1.144f, -1.144f, 1.716f, -2.516f, 1.716f, -4.118f)\n            reflectiveCurveToRelative(-0.572f, -2.974f, -1.716f, -4.118f)\n            reflectiveCurveToRelative(-2.516f, -1.716f, -4.118f, -1.716f)\n            reflectiveCurveToRelative(-2.974f, 0.572f, -4.118f, 1.716f)\n            curveToRelative(-0.766f, 0.766f, -1.272f, 1.65f, -1.518f, 2.651f)\n            reflectiveCurveToRelative(-0.243f, 1.993f, 0.009f, 2.977f)\n            lineToRelative(-5.748f, 5.748f)\n            curveToRelative(-0.092f, 0.092f, -0.163f, 0.197f, -0.214f, 0.317f)\n            reflectiveCurveToRelative(-0.077f, 0.249f, -0.077f, 0.386f)\n            lineToRelative(-0f, 2.745f)\n            curveToRelative(0f, 0.137f, 0.026f, 0.26f, 0.077f, 0.369f)\n            curveToRelative(0.051f, 0.109f, 0.123f, 0.209f, 0.214f, 0.3f)\n            reflectiveCurveToRelative(0.192f, 0.163f, 0.3f, 0.214f)\n            reflectiveCurveToRelative(0.232f, 0.077f, 0.369f, 0.077f)\n            horizontalLineToRelative(4.358f)\n            curveToRelative(0.114f, 0f, 0.229f, -0.023f, 0.343f, -0.069f)\n            reflectiveCurveToRelative(0.217f, -0.103f, 0.309f, -0.172f)\n            reflectiveCurveToRelative(0.166f, -0.154f, 0.223f, -0.257f)\n            reflectiveCurveToRelative(0.092f, -0.217f, 0.103f, -0.343f)\n            lineToRelative(0.223f, -1.561f)\n            lineToRelative(1.716f, -0.24f)\n            curveToRelative(0.103f, -0.011f, 0.2f, -0.04f, 0.292f, -0.086f)\n            reflectiveCurveToRelative(0.172f, -0.103f, 0.24f, -0.172f)\n            reflectiveCurveToRelative(0.129f, -0.152f, 0.18f, -0.249f)\n            reflectiveCurveToRelative(0.083f, -0.197f, 0.094f, -0.3f)\n            lineToRelative(0.309f, -1.784f)\n            lineToRelative(0.806f, -0.806f)\n            curveToRelative(0.984f, 0.252f, 1.976f, 0.254f, 2.977f, 0.009f)\n            reflectiveCurveToRelative(1.884f, -0.752f, 2.651f, -1.518f)\n            close()\n            moveTo(17.662f, 11.828f)\n            curveToRelative(-0.641f, 0.641f, -1.398f, 1.009f, -2.273f, 1.107f)\n            reflectiveCurveToRelative(-1.69f, -0.071f, -2.445f, -0.506f)\n            lineToRelative(-2.145f, 2.145f)\n            lineToRelative(-0.292f, 1.699f)\n            lineToRelative(0.009f, 0.009f)\n            lineToRelative(-0.009f, -0.009f)\n            lineToRelative(-2.453f, 0.36f)\n            lineToRelative(-0.275f, 2.162f)\n            horizontalLineToRelative(-2.574f)\n            lineToRelative(0.009f, -0.009f)\n            lineToRelative(-0.009f, 0.009f)\n            verticalLineToRelative(-1.373f)\n            lineToRelative(-0.009f, -0.009f)\n            lineToRelative(0.009f, 0.009f)\n            lineToRelative(6.365f, -6.365f)\n            curveToRelative(-0.435f, -0.755f, -0.603f, -1.57f, -0.506f, -2.445f)\n            reflectiveCurveToRelative(0.466f, -1.633f, 1.107f, -2.273f)\n            curveToRelative(0.755f, -0.755f, 1.67f, -1.132f, 2.745f, -1.132f)\n            reflectiveCurveToRelative(1.99f, 0.377f, 2.745f, 1.132f)\n            reflectiveCurveToRelative(1.132f, 1.67f, 1.132f, 2.745f)\n            reflectiveCurveToRelative(-0.377f, 1.99f, -1.132f, 2.745f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.KeyVariant: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoToneKeyVariant\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.855f, 9.083f)\n            curveToRelative(0f, -0.538f, -0.189f, -0.995f, -0.566f, -1.373f)\n            reflectiveCurveToRelative(-0.835f, -0.566f, -1.373f, -0.566f)\n            reflectiveCurveToRelative(-0.995f, 0.189f, -1.373f, 0.566f)\n            reflectiveCurveToRelative(-0.566f, 0.835f, -0.566f, 1.373f)\n            reflectiveCurveToRelative(0.189f, 0.995f, 0.566f, 1.373f)\n            reflectiveCurveToRelative(0.835f, 0.566f, 1.373f, 0.566f)\n            reflectiveCurveToRelative(0.995f, -0.189f, 1.373f, -0.566f)\n            curveToRelative(0.377f, -0.377f, 0.566f, -0.835f, 0.566f, -1.373f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.034f, 4.966f)\n            curveToRelative(-1.144f, -1.144f, -2.516f, -1.716f, -4.118f, -1.716f)\n            reflectiveCurveToRelative(-2.974f, 0.572f, -4.118f, 1.716f)\n            curveToRelative(-0.766f, 0.766f, -1.272f, 1.65f, -1.518f, 2.651f)\n            curveToRelative(-0.246f, 1.001f, -0.243f, 1.993f, 0.009f, 2.977f)\n            lineToRelative(-5.748f, 5.748f)\n            curveToRelative(-0.092f, 0.091f, -0.163f, 0.197f, -0.214f, 0.317f)\n            reflectiveCurveToRelative(-0.077f, 0.249f, -0.077f, 0.386f)\n            verticalLineToRelative(2.745f)\n            curveToRelative(0f, 0.137f, 0.026f, 0.26f, 0.077f, 0.369f)\n            reflectiveCurveToRelative(0.123f, 0.209f, 0.214f, 0.3f)\n            curveToRelative(0.091f, 0.091f, 0.192f, 0.163f, 0.3f, 0.214f)\n            reflectiveCurveToRelative(0.232f, 0.077f, 0.369f, 0.077f)\n            horizontalLineToRelative(4.358f)\n            curveToRelative(0.114f, 0f, 0.229f, -0.023f, 0.343f, -0.069f)\n            curveToRelative(0.114f, -0.046f, 0.217f, -0.103f, 0.309f, -0.172f)\n            curveToRelative(0.091f, -0.069f, 0.166f, -0.154f, 0.223f, -0.257f)\n            curveToRelative(0.057f, -0.103f, 0.092f, -0.217f, 0.103f, -0.343f)\n            lineToRelative(0.223f, -1.561f)\n            lineToRelative(1.716f, -0.24f)\n            curveToRelative(0.103f, -0.011f, 0.2f, -0.04f, 0.292f, -0.086f)\n            curveToRelative(0.091f, -0.046f, 0.172f, -0.103f, 0.24f, -0.172f)\n            curveToRelative(0.069f, -0.069f, 0.129f, -0.152f, 0.18f, -0.249f)\n            curveToRelative(0.051f, -0.097f, 0.083f, -0.197f, 0.094f, -0.3f)\n            lineToRelative(0.309f, -1.784f)\n            lineToRelative(0.806f, -0.806f)\n            curveToRelative(0.984f, 0.252f, 1.976f, 0.255f, 2.977f, 0.009f)\n            curveToRelative(1.001f, -0.246f, 1.884f, -0.752f, 2.651f, -1.518f)\n            curveToRelative(1.144f, -1.144f, 1.716f, -2.516f, 1.716f, -4.118f)\n            curveToRelative(0f, -1.601f, -0.572f, -2.974f, -1.716f, -4.118f)\n            close()\n            moveTo(17.666f, 11.828f)\n            curveToRelative(-0.641f, 0.641f, -1.398f, 1.009f, -2.273f, 1.107f)\n            reflectiveCurveToRelative(-1.69f, -0.071f, -2.445f, -0.506f)\n            lineToRelative(-2.145f, 2.145f)\n            lineToRelative(-0.292f, 1.698f)\n            lineToRelative(-2.453f, 0.36f)\n            lineToRelative(-0.275f, 2.162f)\n            horizontalLineToRelative(-2.574f)\n            verticalLineToRelative(-1.373f)\n            lineToRelative(6.365f, -6.365f)\n            curveToRelative(-0.435f, -0.755f, -0.603f, -1.57f, -0.506f, -2.445f)\n            curveToRelative(0.097f, -0.875f, 0.466f, -1.633f, 1.107f, -2.273f)\n            curveToRelative(0.755f, -0.755f, 1.67f, -1.132f, 2.745f, -1.132f)\n            reflectiveCurveToRelative(1.99f, 0.377f, 2.745f, 1.132f)\n            curveToRelative(0.755f, 0.755f, 1.132f, 1.67f, 1.132f, 2.745f)\n            curveToRelative(0f, 1.075f, -0.377f, 1.99f, -1.132f, 2.745f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(17.666f, 11.828f)\n            curveToRelative(-0.641f, 0.641f, -1.398f, 1.009f, -2.273f, 1.107f)\n            reflectiveCurveToRelative(-1.69f, -0.071f, -2.445f, -0.506f)\n            lineToRelative(-2.145f, 2.145f)\n            lineToRelative(-0.292f, 1.699f)\n            lineToRelative(0.009f, 0.009f)\n            lineToRelative(-0.009f, -0.009f)\n            lineToRelative(-2.453f, 0.36f)\n            lineToRelative(-0.275f, 2.162f)\n            horizontalLineToRelative(-2.574f)\n            lineToRelative(0.009f, -0.009f)\n            lineToRelative(-0.009f, 0.009f)\n            verticalLineToRelative(-1.373f)\n            lineToRelative(-0.009f, -0.009f)\n            lineToRelative(0.009f, 0.009f)\n            lineToRelative(6.365f, -6.365f)\n            curveToRelative(-0.435f, -0.755f, -0.603f, -1.57f, -0.506f, -2.445f)\n            reflectiveCurveToRelative(0.466f, -1.633f, 1.107f, -2.273f)\n            curveToRelative(0.755f, -0.755f, 1.67f, -1.132f, 2.745f, -1.132f)\n            reflectiveCurveToRelative(1.99f, 0.377f, 2.745f, 1.132f)\n            reflectiveCurveToRelative(1.132f, 1.67f, 1.132f, 2.745f)\n            reflectiveCurveToRelative(-0.377f, 1.99f, -1.132f, 2.745f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/KeyVertical.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.KeyVertical: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.KeyVertical\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(565f, 365f)\n            quadToRelative(35f, -35f, 35f, -85f)\n            reflectiveQuadToRelative(-35f, -85f)\n            quadToRelative(-35f, -35f, -85f, -35f)\n            reflectiveQuadToRelative(-85f, 35f)\n            quadToRelative(-35f, 35f, -35f, 85f)\n            reflectiveQuadToRelative(35f, 85f)\n            quadToRelative(35f, 35f, 85f, 35f)\n            reflectiveQuadToRelative(85f, -35f)\n            close()\n            moveTo(466f, 902.5f)\n            quadToRelative(-7f, -2.5f, -13f, -7.5f)\n            lineToRelative(-103f, -90f)\n            quadToRelative(-6f, -5f, -9.5f, -11.5f)\n            reflectiveQuadTo(336f, 779f)\n            quadToRelative(-1f, -8f, 1.5f, -15.5f)\n            reflectiveQuadTo(345f, 750f)\n            lineToRelative(55f, -70f)\n            lineToRelative(-52f, -52f)\n            quadToRelative(-6f, -6f, -8.5f, -13f)\n            reflectiveQuadToRelative(-2.5f, -15f)\n            quadToRelative(0f, -8f, 2.5f, -15f)\n            reflectiveQuadToRelative(8.5f, -13f)\n            lineToRelative(52f, -52f)\n            verticalLineToRelative(-14f)\n            quadToRelative(-72f, -25f, -116f, -87f)\n            reflectiveQuadToRelative(-44f, -139f)\n            quadToRelative(0f, -100f, 70f, -170f)\n            reflectiveQuadToRelative(170f, -70f)\n            quadToRelative(100f, 0f, 170f, 70f)\n            reflectiveQuadToRelative(70f, 170f)\n            quadToRelative(0f, 81f, -46f, 141.5f)\n            reflectiveQuadTo(560f, 506f)\n            verticalLineToRelative(318f)\n            quadToRelative(0f, 8f, -3f, 15.5f)\n            reflectiveQuadToRelative(-9f, 13.5f)\n            lineToRelative(-41f, 41f)\n            quadToRelative(-5f, 5f, -11.5f, 8f)\n            reflectiveQuadTo(481f, 905f)\n            quadToRelative(-8f, 0f, -15f, -2.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/LabelPercent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.LabelPercent: ImageVector by lazy {\n    Builder(\n        name = \"Label Percent\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.0f, 17.0f)\n            horizontalLineTo(5.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(16.0f)\n            lineTo(19.55f, 12.0f)\n            moveTo(17.63f, 5.84f)\n            curveTo(17.27f, 5.33f, 16.67f, 5.0f, 16.0f, 5.0f)\n            horizontalLineTo(5.0f)\n            curveTo(3.9f, 5.0f, 3.0f, 5.9f, 3.0f, 7.0f)\n            verticalLineTo(17.0f)\n            curveTo(3.0f, 18.11f, 3.9f, 19.0f, 5.0f, 19.0f)\n            horizontalLineTo(16.0f)\n            curveTo(16.67f, 19.0f, 17.27f, 18.66f, 17.63f, 18.15f)\n            lineTo(22.0f, 12.0f)\n            lineTo(17.63f, 5.84f)\n            moveTo(13.8f, 8.0f)\n            lineTo(15.0f, 9.2f)\n            lineTo(8.2f, 16.0f)\n            lineTo(7.0f, 14.8f)\n            moveTo(8.45f, 8.03f)\n            curveTo(9.23f, 8.03f, 9.87f, 8.67f, 9.87f, 9.45f)\n            reflectiveCurveTo(9.23f, 10.87f, 8.45f, 10.87f)\n            reflectiveCurveTo(7.03f, 10.23f, 7.03f, 9.45f)\n            reflectiveCurveTo(7.67f, 8.03f, 8.45f, 8.03f)\n            moveTo(13.55f, 13.13f)\n            curveTo(14.33f, 13.13f, 14.97f, 13.77f, 14.97f, 14.55f)\n            curveTo(14.97f, 15.33f, 14.33f, 15.97f, 13.55f, 15.97f)\n            curveTo(12.77f, 15.97f, 12.13f, 15.33f, 12.13f, 14.55f)\n            curveTo(12.13f, 13.77f, 12.77f, 13.13f, 13.55f, 13.13f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.LabelPercent: ImageVector by lazy {\n    Builder(\n        name = \"Label Percent\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.63f, 5.84f)\n            curveTo(17.27f, 5.33f, 16.67f, 5.0f, 16.0f, 5.0f)\n            horizontalLineTo(5.0f)\n            curveTo(3.9f, 5.0f, 3.0f, 5.9f, 3.0f, 7.0f)\n            verticalLineTo(17.0f)\n            curveTo(3.0f, 18.11f, 3.9f, 19.0f, 5.0f, 19.0f)\n            horizontalLineTo(16.0f)\n            curveTo(16.67f, 19.0f, 17.27f, 18.66f, 17.63f, 18.15f)\n            lineTo(22.0f, 12.0f)\n            lineTo(17.63f, 5.84f)\n            moveTo(8.45f, 8.03f)\n            curveTo(9.23f, 8.03f, 9.87f, 8.67f, 9.87f, 9.45f)\n            reflectiveCurveTo(9.23f, 10.87f, 8.45f, 10.87f)\n            reflectiveCurveTo(7.03f, 10.23f, 7.03f, 9.45f)\n            reflectiveCurveTo(7.67f, 8.03f, 8.45f, 8.03f)\n            moveTo(13.55f, 15.97f)\n            curveTo(12.77f, 15.97f, 12.13f, 15.33f, 12.13f, 14.55f)\n            reflectiveCurveTo(12.77f, 13.13f, 13.55f, 13.13f)\n            reflectiveCurveTo(14.97f, 13.77f, 14.97f, 14.55f)\n            reflectiveCurveTo(14.33f, 15.97f, 13.55f, 15.97f)\n            moveTo(8.2f, 16.0f)\n            lineTo(7.0f, 14.8f)\n            lineTo(13.8f, 8.0f)\n            lineTo(15.0f, 9.2f)\n            lineTo(8.2f, 16.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Landscape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Landscape: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Landscape\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 18f)\n            curveToRelative(-0.417f, 0f, -0.717f, -0.183f, -0.9f, -0.55f)\n            curveToRelative(-0.183f, -0.367f, -0.15f, -0.717f, 0.1f, -1.05f)\n            lineToRelative(4f, -5.325f)\n            curveToRelative(0.1f, -0.133f, 0.221f, -0.233f, 0.363f, -0.3f)\n            reflectiveCurveToRelative(0.287f, -0.1f, 0.438f, -0.1f)\n            reflectiveCurveToRelative(0.296f, 0.033f, 0.438f, 0.1f)\n            reflectiveCurveToRelative(0.262f, 0.167f, 0.363f, 0.3f)\n            lineToRelative(3.7f, 4.925f)\n            horizontalLineToRelative(7.5f)\n            lineToRelative(-5f, -6.65f)\n            lineToRelative(-1.7f, 2.25f)\n            curveToRelative(-0.2f, 0.267f, -0.433f, 0.404f, -0.7f, 0.412f)\n            reflectiveCurveToRelative(-0.5f, -0.063f, -0.7f, -0.213f)\n            reflectiveCurveToRelative(-0.333f, -0.354f, -0.4f, -0.613f)\n            curveToRelative(-0.067f, -0.258f, 0f, -0.521f, 0.2f, -0.788f)\n            lineToRelative(2.5f, -3.325f)\n            curveToRelative(0.1f, -0.133f, 0.221f, -0.233f, 0.363f, -0.3f)\n            reflectiveCurveToRelative(0.287f, -0.1f, 0.438f, -0.1f)\n            reflectiveCurveToRelative(0.296f, 0.033f, 0.438f, 0.1f)\n            reflectiveCurveToRelative(0.262f, 0.167f, 0.363f, 0.3f)\n            lineToRelative(7f, 9.325f)\n            curveToRelative(0.25f, 0.333f, 0.283f, 0.683f, 0.1f, 1.05f)\n            curveToRelative(-0.183f, 0.367f, -0.483f, 0.55f, -0.9f, 0.55f)\n            horizontalLineTo(3f)\n            close()\n            moveTo(11.5f, 16f)\n            horizontalLineToRelative(7.5f)\n            horizontalLineToRelative(-7.8f)\n            horizontalLineToRelative(1.712f)\n            horizontalLineToRelative(-1.413f)\n            close()\n            moveTo(5f, 16f)\n            horizontalLineToRelative(4f)\n            lineToRelative(-2f, -2.675f)\n            lineToRelative(-2f, 2.675f)\n            close()\n            moveTo(5f, 16f)\n            horizontalLineToRelative(4f)\n            horizontalLineToRelative(-4f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Landscape: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Landscape\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.5f, 16f)\n            lineToRelative(7.5f, 0f)\n            lineToRelative(-7.8f, 0f)\n            lineToRelative(1.713f, 0f)\n            lineToRelative(-1.413f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 16f)\n            horizontalLineToRelative(4f)\n            horizontalLineToRelative(-4f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 16f)\n            lineToRelative(4f, 0f)\n            lineToRelative(-2f, -2.675f)\n            lineToRelative(-2f, 2.675f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(10.111f, 16.915f)\n            lineToRelative(10.845f, 0f)\n            lineToRelative(0.477f, -0.886f)\n            lineToRelative(-1.691f, -2.249f)\n            lineToRelative(-0.845f, -1.125f)\n            lineToRelative(-2.536f, -3.373f)\n            lineToRelative(0f, -0.005f)\n            lineToRelative(-2.315f, 0f)\n            lineToRelative(-2.536f, 3.373f)\n            lineToRelative(-0.846f, 1.125f)\n            lineToRelative(-1.071f, 1.425f)\n            lineToRelative(0.519f, 0f)\n            lineToRelative(0f, 1.716f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.8f, 16.4f)\n            lineToRelative(-7f, -9.325f)\n            curveToRelative(-0.1f, -0.133f, -0.221f, -0.233f, -0.362f, -0.3f)\n            curveToRelative(-0.142f, -0.067f, -0.287f, -0.1f, -0.438f, -0.1f)\n            reflectiveCurveToRelative(-0.296f, 0.033f, -0.438f, 0.1f)\n            curveToRelative(-0.142f, 0.067f, -0.263f, 0.167f, -0.362f, 0.3f)\n            lineToRelative(-1.898f, 2.524f)\n            lineToRelative(-0.002f, -0.001f)\n            lineToRelative(-1.202f, 1.599f)\n            lineToRelative(1.247f, 1.669f)\n            lineToRelative(0.351f, -0.467f)\n            lineToRelative(0.595f, -0.791f)\n            curveToRelative(0.003f, -0.003f, 0.006f, -0.004f, 0.008f, -0.008f)\n            lineToRelative(1.7f, -2.25f)\n            lineToRelative(5f, 6.65f)\n            horizontalLineToRelative(-7.5f)\n            lineToRelative(-3.7f, -4.925f)\n            curveToRelative(-0.1f, -0.133f, -0.221f, -0.233f, -0.362f, -0.3f)\n            curveToRelative(-0.142f, -0.067f, -0.287f, -0.1f, -0.438f, -0.1f)\n            reflectiveCurveToRelative(-0.296f, 0.033f, -0.438f, 0.1f)\n            curveToRelative(-0.142f, 0.067f, -0.263f, 0.167f, -0.362f, 0.3f)\n            lineToRelative(-4f, 5.325f)\n            curveToRelative(-0.25f, 0.333f, -0.283f, 0.683f, -0.1f, 1.05f)\n            curveToRelative(0.183f, 0.367f, 0.483f, 0.55f, 0.9f, 0.55f)\n            horizontalLineToRelative(18f)\n            curveToRelative(0.417f, 0f, 0.717f, -0.183f, 0.9f, -0.55f)\n            curveToRelative(0.183f, -0.367f, 0.15f, -0.717f, -0.1f, -1.05f)\n            close()\n            moveTo(5f, 16f)\n            lineToRelative(2f, -2.675f)\n            lineToRelative(2f, 2.675f)\n            horizontalLineToRelative(-4f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Landscape2.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Landscape2: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Landscape2\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(46f, 800f)\n            lineTo(184f, 524f)\n            quadTo(194f, 504f, 212.5f, 492f)\n            quadTo(231f, 480f, 254f, 480f)\n            quadTo(278f, 480f, 298f, 492.5f)\n            quadTo(318f, 505f, 327f, 528f)\n            lineTo(354f, 594f)\n            quadTo(356f, 600f, 363f, 599.5f)\n            quadTo(370f, 599f, 372f, 593f)\n            lineTo(458f, 306f)\n            quadTo(472f, 258f, 511.5f, 229f)\n            quadTo(551f, 200f, 601f, 200f)\n            quadTo(650f, 200f, 688.5f, 228.5f)\n            quadTo(727f, 257f, 742f, 303f)\n            lineTo(915f, 800f)\n            lineTo(46f, 800f)\n            close()\n            moveTo(240f, 400f)\n            quadTo(190f, 400f, 155f, 364.5f)\n            quadTo(120f, 329f, 120f, 280f)\n            quadTo(120f, 230f, 155f, 195f)\n            quadTo(190f, 160f, 240f, 160f)\n            quadTo(290f, 160f, 325f, 195f)\n            quadTo(360f, 230f, 360f, 280f)\n            quadTo(360f, 329f, 325f, 364.5f)\n            quadTo(290f, 400f, 240f, 400f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Landscape2: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Landscape2\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(46f, 800f)\n            lineTo(184f, 524f)\n            quadTo(194f, 504f, 212.5f, 492f)\n            quadTo(231f, 480f, 254f, 480f)\n            quadTo(278f, 480f, 298f, 492.5f)\n            quadTo(318f, 505f, 327f, 528f)\n            lineTo(354f, 594f)\n            quadTo(356f, 600f, 363f, 599.5f)\n            quadTo(370f, 599f, 372f, 593f)\n            lineTo(458f, 306f)\n            quadTo(472f, 258f, 511.5f, 229f)\n            quadTo(551f, 200f, 601f, 200f)\n            quadTo(650f, 200f, 688.5f, 228.5f)\n            quadTo(727f, 257f, 742f, 303f)\n            lineTo(915f, 800f)\n            lineTo(830f, 800f)\n            lineTo(666f, 328f)\n            quadTo(658f, 305f, 641f, 292.5f)\n            quadTo(624f, 280f, 601f, 280f)\n            quadTo(578f, 280f, 560.5f, 293f)\n            quadTo(543f, 306f, 535f, 329f)\n            lineTo(449f, 616f)\n            quadTo(440f, 644f, 416.5f, 662f)\n            quadTo(393f, 680f, 363f, 680f)\n            quadTo(336f, 680f, 313f, 665.5f)\n            quadTo(290f, 651f, 280f, 625f)\n            lineTo(253f, 559f)\n            quadTo(253f, 559f, 253f, 559f)\n            quadTo(253f, 559f, 253f, 559f)\n            lineTo(135f, 800f)\n            lineTo(46f, 800f)\n            close()\n            moveTo(240f, 400f)\n            quadTo(190f, 400f, 155f, 364.5f)\n            quadTo(120f, 329f, 120f, 280f)\n            quadTo(120f, 230f, 155f, 195f)\n            quadTo(190f, 160f, 240f, 160f)\n            quadTo(290f, 160f, 325f, 195f)\n            quadTo(360f, 230f, 360f, 280f)\n            quadTo(360f, 329f, 325f, 364.5f)\n            quadTo(290f, 400f, 240f, 400f)\n            close()\n            moveTo(240f, 320f)\n            quadTo(257f, 320f, 268.5f, 308.5f)\n            quadTo(280f, 297f, 280f, 280f)\n            quadTo(280f, 263f, 268.5f, 251.5f)\n            quadTo(257f, 240f, 240f, 240f)\n            quadTo(223f, 240f, 211.5f, 251.5f)\n            quadTo(200f, 263f, 200f, 280f)\n            quadTo(200f, 297f, 211.5f, 308.5f)\n            quadTo(223f, 320f, 240f, 320f)\n            close()\n            moveTo(363f, 680f)\n            lineTo(363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            lineTo(363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            lineTo(363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            quadTo(363f, 680f, 363f, 680f)\n            lineTo(363f, 680f)\n            close()\n            moveTo(240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            quadTo(240f, 280f, 240f, 280f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Lasso.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Lasso: ImageVector by lazy {\n    Builder(\n        name = \"Lasso\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 2.0f)\n            curveTo(17.5f, 2.0f, 22.0f, 5.13f, 22.0f, 9.0f)\n            curveTo(22.0f, 12.26f, 18.81f, 15.0f, 14.5f, 15.78f)\n            lineTo(14.5f, 15.5f)\n            curveTo(14.5f, 14.91f, 14.4f, 14.34f, 14.21f, 13.81f)\n            curveTo(17.55f, 13.21f, 20.0f, 11.28f, 20.0f, 9.0f)\n            curveTo(20.0f, 6.24f, 16.42f, 4.0f, 12.0f, 4.0f)\n            curveTo(7.58f, 4.0f, 4.0f, 6.24f, 4.0f, 9.0f)\n            curveTo(4.0f, 10.19f, 4.67f, 11.29f, 5.79f, 12.15f)\n            curveTo(5.35f, 12.64f, 5.0f, 13.21f, 4.78f, 13.85f)\n            curveTo(3.06f, 12.59f, 2.0f, 10.88f, 2.0f, 9.0f)\n            curveTo(2.0f, 5.13f, 6.5f, 2.0f, 12.0f, 2.0f)\n            moveTo(9.5f, 12.0f)\n            curveTo(11.43f, 12.0f, 13.0f, 13.57f, 13.0f, 15.5f)\n            curveTo(13.0f, 17.4f, 11.5f, 18.95f, 9.6f, 19.0f)\n            curveTo(9.39f, 19.36f, 9.18f, 20.0f, 9.83f, 20.68f)\n            curveTo(11.0f, 21.88f, 13.28f, 19.72f, 16.39f, 19.71f)\n            curveTo(18.43f, 19.7f, 20.03f, 19.97f, 20.03f, 19.97f)\n            curveTo(20.03f, 19.97f, 21.08f, 20.1f, 20.97f, 21.04f)\n            curveTo(20.86f, 21.97f, 19.91f, 21.97f, 19.91f, 21.97f)\n            curveTo(19.53f, 21.93f, 18.03f, 21.58f, 16.22f, 21.68f)\n            curveTo(14.41f, 21.77f, 13.47f, 22.41f, 12.56f, 22.69f)\n            curveTo(11.66f, 22.97f, 9.91f, 23.38f, 8.3f, 22.05f)\n            curveTo(6.97f, 20.96f, 7.46f, 19.11f, 7.67f, 18.5f)\n            curveTo(6.67f, 17.87f, 6.0f, 16.76f, 6.0f, 15.5f)\n            curveTo(6.0f, 13.57f, 7.57f, 12.0f, 9.5f, 12.0f)\n            moveTo(9.5f, 14.0f)\n            curveTo(8.67f, 14.0f, 8.0f, 14.67f, 8.0f, 15.5f)\n            curveTo(8.0f, 16.33f, 8.67f, 17.0f, 9.5f, 17.0f)\n            curveTo(10.33f, 17.0f, 11.0f, 16.33f, 11.0f, 15.5f)\n            curveTo(11.0f, 14.67f, 10.33f, 14.0f, 9.5f, 14.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Latitude.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Latitude: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Latitude\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 2f)\n            curveTo(6.5f, 2f, 2f, 6.5f, 2f, 12f)\n            reflectiveCurveTo(6.5f, 22f, 12f, 22f)\n            reflectiveCurveTo(22f, 17.5f, 22f, 12f)\n            reflectiveCurveTo(17.5f, 2f, 12f, 2f)\n            moveTo(12f, 4f)\n            curveTo(15f, 4f, 17.5f, 5.6f, 18.9f, 8f)\n            horizontalLineTo(5.1f)\n            curveTo(6.5f, 5.6f, 9f, 4f, 12f, 4f)\n            moveTo(12f, 20f)\n            curveTo(9f, 20f, 6.5f, 18.4f, 5.1f, 16f)\n            horizontalLineTo(18.9f)\n            curveTo(17.5f, 18.4f, 15f, 20f, 12f, 20f)\n            moveTo(4.3f, 14f)\n            curveTo(4.1f, 13.4f, 4f, 12.7f, 4f, 12f)\n            reflectiveCurveTo(4.1f, 10.6f, 4.3f, 10f)\n            horizontalLineTo(19.8f)\n            curveTo(20f, 10.6f, 20.1f, 11.3f, 20.1f, 12f)\n            reflectiveCurveTo(20f, 13.4f, 19.8f, 14f)\n            horizontalLineTo(4.3f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Layers.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Layers: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Layers\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(161f, 594f)\n            quadToRelative(-16f, -12f, -15.5f, -31.5f)\n            reflectiveQuadTo(162f, 531f)\n            quadToRelative(11f, -8f, 24f, -8f)\n            reflectiveQuadToRelative(24f, 8f)\n            lineToRelative(270f, 209f)\n            lineToRelative(270f, -209f)\n            quadToRelative(11f, -8f, 24f, -8f)\n            reflectiveQuadToRelative(24f, 8f)\n            quadToRelative(16f, 12f, 16.5f, 31.5f)\n            reflectiveQuadTo(799f, 594f)\n            lineTo(529f, 804f)\n            quadToRelative(-22f, 17f, -49f, 17f)\n            reflectiveQuadToRelative(-49f, -17f)\n            lineTo(161f, 594f)\n            close()\n            moveTo(431f, 602f)\n            lineTo(201f, 423f)\n            quadToRelative(-31f, -24f, -31f, -63f)\n            reflectiveQuadToRelative(31f, -63f)\n            lineToRelative(230f, -179f)\n            quadToRelative(22f, -17f, 49f, -17f)\n            reflectiveQuadToRelative(49f, 17f)\n            lineToRelative(230f, 179f)\n            quadToRelative(31f, 24f, 31f, 63f)\n            reflectiveQuadToRelative(-31f, 63f)\n            lineTo(529f, 602f)\n            quadToRelative(-22f, 17f, -49f, 17f)\n            reflectiveQuadToRelative(-49f, -17f)\n            close()\n            moveTo(480f, 538f)\n            lineTo(710f, 360f)\n            lineTo(480f, 182f)\n            lineTo(250f, 360f)\n            lineTo(480f, 538f)\n            close()\n            moveTo(480f, 360f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Layers: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Layers\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(161f, 594f)\n            quadToRelative(-16f, -12f, -15.5f, -31.5f)\n            reflectiveQuadTo(162f, 531f)\n            quadToRelative(11f, -8f, 24f, -8f)\n            reflectiveQuadToRelative(24f, 8f)\n            lineToRelative(270f, 209f)\n            lineToRelative(270f, -209f)\n            quadToRelative(11f, -8f, 24f, -8f)\n            reflectiveQuadToRelative(24f, 8f)\n            quadToRelative(16f, 12f, 16.5f, 31.5f)\n            reflectiveQuadTo(799f, 594f)\n            lineTo(529f, 804f)\n            quadToRelative(-22f, 17f, -49f, 17f)\n            reflectiveQuadToRelative(-49f, -17f)\n            lineTo(161f, 594f)\n            close()\n            moveTo(431f, 602f)\n            lineTo(201f, 423f)\n            quadToRelative(-31f, -24f, -31f, -63f)\n            reflectiveQuadToRelative(31f, -63f)\n            lineToRelative(230f, -179f)\n            quadToRelative(22f, -17f, 49f, -17f)\n            reflectiveQuadToRelative(49f, 17f)\n            lineToRelative(230f, 179f)\n            quadToRelative(31f, 24f, 31f, 63f)\n            reflectiveQuadToRelative(-31f, 63f)\n            lineTo(529f, 602f)\n            quadToRelative(-22f, 17f, -49f, 17f)\n            reflectiveQuadToRelative(-49f, -17f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/LayersSearchOutline.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.LayersSearchOutline: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.LayersSearchOutline\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.31f, 18.9f)\n            curveTo(19.75f, 18.21f, 20f, 17.38f, 20f, 16.5f)\n            curveTo(20f, 14f, 18f, 12f, 15.5f, 12f)\n            reflectiveCurveTo(11f, 14f, 11f, 16.5f)\n            reflectiveCurveTo(13f, 21f, 15.5f, 21f)\n            curveTo(16.37f, 21f, 17.19f, 20.75f, 17.88f, 20.32f)\n            lineTo(21f, 23.39f)\n            lineTo(22.39f, 22f)\n            lineTo(19.31f, 18.9f)\n            moveTo(15.5f, 19f)\n            curveTo(14.12f, 19f, 13f, 17.88f, 13f, 16.5f)\n            reflectiveCurveTo(14.12f, 14f, 15.5f, 14f)\n            reflectiveCurveTo(18f, 15.12f, 18f, 16.5f)\n            reflectiveCurveTo(16.88f, 19f, 15.5f, 19f)\n            moveTo(9.59f, 19.2f)\n            lineTo(3f, 14.07f)\n            lineTo(4.62f, 12.81f)\n            lineTo(9f, 16.22f)\n            curveTo(9f, 16.32f, 9f, 16.41f, 9f, 16.5f)\n            curveTo(9f, 17.46f, 9.22f, 18.38f, 9.59f, 19.2f)\n            moveTo(9.5f, 14.04f)\n            lineTo(3f, 9f)\n            lineTo(12f, 2f)\n            lineTo(21f, 9f)\n            lineTo(18.66f, 10.82f)\n            curveTo(17.96f, 10.44f, 17.19f, 10.18f, 16.37f, 10.07f)\n            lineTo(17.74f, 9f)\n            lineTo(12f, 4.53f)\n            lineTo(6.26f, 9f)\n            lineTo(10.53f, 12.32f)\n            curveTo(10.1f, 12.84f, 9.74f, 13.42f, 9.5f, 14.04f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/LetterO.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.LetterO: ImageVector by lazy {\n    Builder(\n        name = \"Letter O\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp, viewportWidth =\n            24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(11.0f, 7.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 9.0f,\n                y1 = 9.0f\n            )\n            verticalLineTo(15.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 11.0f,\n                y1 = 17.0f\n            )\n            horizontalLineTo(13.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 15.0f,\n                y1 = 15.0f\n            )\n            verticalLineTo(9.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 13.0f,\n                y1 = 7.0f\n            )\n            horizontalLineTo(11.0f)\n            moveTo(11.0f, 9.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(11.0f)\n            verticalLineTo(9.0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/LetterS.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.LetterS: ImageVector by lazy {\n    Builder(\n        name = \"Letter S\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp, viewportWidth =\n            24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(11.0f, 7.0f)\n            curveTo(9.9f, 7.0f, 9.0f, 7.9f, 9.0f, 9.0f)\n            verticalLineTo(11.0f)\n            curveTo(9.0f, 12.11f, 9.9f, 13.0f, 11.0f, 13.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(9.0f)\n            verticalLineTo(17.0f)\n            horizontalLineTo(13.0f)\n            curveTo(14.11f, 17.0f, 15.0f, 16.11f, 15.0f, 15.0f)\n            verticalLineTo(13.0f)\n            curveTo(15.0f, 11.9f, 14.11f, 11.0f, 13.0f, 11.0f)\n            horizontalLineTo(11.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(15.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(11.0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/License.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.License: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.License\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(480f, 520f)\n            quadTo(430f, 520f, 395f, 485f)\n            quadTo(360f, 450f, 360f, 400f)\n            quadTo(360f, 350f, 395f, 315f)\n            quadTo(430f, 280f, 480f, 280f)\n            quadTo(530f, 280f, 565f, 315f)\n            quadTo(600f, 350f, 600f, 400f)\n            quadTo(600f, 450f, 565f, 485f)\n            quadTo(530f, 520f, 480f, 520f)\n            close()\n            moveTo(240f, 920f)\n            lineTo(240f, 611f)\n            quadTo(202f, 569f, 181f, 515f)\n            quadTo(160f, 461f, 160f, 400f)\n            quadTo(160f, 266f, 253f, 173f)\n            quadTo(346f, 80f, 480f, 80f)\n            quadTo(614f, 80f, 707f, 173f)\n            quadTo(800f, 266f, 800f, 400f)\n            quadTo(800f, 461f, 779f, 515f)\n            quadTo(758f, 569f, 720f, 611f)\n            lineTo(720f, 920f)\n            lineTo(480f, 840f)\n            lineTo(240f, 920f)\n            close()\n            moveTo(480f, 640f)\n            quadTo(580f, 640f, 650f, 570f)\n            quadTo(720f, 500f, 720f, 400f)\n            quadTo(720f, 300f, 650f, 230f)\n            quadTo(580f, 160f, 480f, 160f)\n            quadTo(380f, 160f, 310f, 230f)\n            quadTo(240f, 300f, 240f, 400f)\n            quadTo(240f, 500f, 310f, 570f)\n            quadTo(380f, 640f, 480f, 640f)\n            close()\n            moveTo(320f, 801f)\n            lineTo(480f, 760f)\n            lineTo(640f, 801f)\n            lineTo(640f, 677f)\n            quadTo(605f, 697f, 564.5f, 708.5f)\n            quadTo(524f, 720f, 480f, 720f)\n            quadTo(436f, 720f, 395.5f, 708.5f)\n            quadTo(355f, 697f, 320f, 677f)\n            lineTo(320f, 801f)\n            close()\n            moveTo(480f, 739f)\n            lineTo(480f, 739f)\n            quadTo(480f, 739f, 480f, 739f)\n            quadTo(480f, 739f, 480f, 739f)\n            quadTo(480f, 739f, 480f, 739f)\n            quadTo(480f, 739f, 480f, 739f)\n            lineTo(480f, 739f)\n            lineTo(480f, 739f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Line.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Line: ImageVector by lazy {\n    Builder(\n        name = \"Line\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(212.0f, 748.0f)\n            quadToRelative(-11.0f, -11.0f, -11.0f, -28.0f)\n            reflectiveQuadToRelative(11.0f, -28.0f)\n            lineToRelative(480.0f, -480.0f)\n            quadToRelative(11.0f, -12.0f, 27.5f, -12.0f)\n            reflectiveQuadToRelative(28.5f, 12.0f)\n            quadToRelative(11.0f, 11.0f, 11.0f, 28.0f)\n            reflectiveQuadToRelative(-11.0f, 28.0f)\n            lineTo(268.0f, 748.0f)\n            quadToRelative(-11.0f, 11.0f, -28.0f, 11.0f)\n            reflectiveQuadToRelative(-28.0f, -11.0f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/LineArrow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.LineArrow: ImageVector by lazy {\n    Builder(\n        name = \"LineArrow\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(680.0f, 336.0f)\n            lineTo(244.0f, 772.0f)\n            quadToRelative(-11.0f, 11.0f, -28.0f, 11.0f)\n            reflectiveQuadToRelative(-28.0f, -11.0f)\n            quadToRelative(-11.0f, -11.0f, -11.0f, -28.0f)\n            reflectiveQuadToRelative(11.0f, -28.0f)\n            lineToRelative(436.0f, -436.0f)\n            lineTo(400.0f, 280.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(360.0f, 240.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(400.0f, 200.0f)\n            horizontalLineToRelative(320.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(760.0f, 240.0f)\n            verticalLineToRelative(320.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(720.0f, 600.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(680.0f, 560.0f)\n            verticalLineToRelative(-224.0f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/LineDoubleArrow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.LineDoubleArrow: ImageVector by lazy {\n    Builder(\n        name = \"LineDoubleArrow\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(160.0f, 840.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(120.0f, 800.0f)\n            verticalLineToRelative(-240.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(160.0f, 520.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(200.0f, 560.0f)\n            verticalLineToRelative(144.0f)\n            lineToRelative(504.0f, -504.0f)\n            lineTo(560.0f, 200.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(520.0f, 160.0f)\n            quadToRelative(0.0f, -17.0f, 11.5f, -28.5f)\n            reflectiveQuadTo(560.0f, 120.0f)\n            horizontalLineToRelative(240.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(840.0f, 160.0f)\n            verticalLineToRelative(240.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(800.0f, 440.0f)\n            quadToRelative(-17.0f, 0.0f, -28.5f, -11.5f)\n            reflectiveQuadTo(760.0f, 400.0f)\n            verticalLineToRelative(-144.0f)\n            lineTo(256.0f, 760.0f)\n            horizontalLineToRelative(144.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, 11.5f)\n            reflectiveQuadTo(440.0f, 800.0f)\n            quadToRelative(0.0f, 17.0f, -11.5f, 28.5f)\n            reflectiveQuadTo(400.0f, 840.0f)\n            lineTo(160.0f, 840.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Longitude.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Longitude: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Longitude\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 2f)\n            arcTo(10f, 10f, 0f, isMoreThanHalf = true, isPositiveArc = false, 22f, 12f)\n            arcTo(10.03f, 10.03f, 0f, isMoreThanHalf = false, isPositiveArc = false, 12f, 2f)\n            moveTo(9.4f, 19.6f)\n            arcTo(8.05f, 8.05f, 0f, isMoreThanHalf = false, isPositiveArc = true, 9.4f, 4.4f)\n            arcTo(16.45f, 16.45f, 0f, isMoreThanHalf = false, isPositiveArc = false, 7.5f, 12f)\n            arcTo(16.45f, 16.45f, 0f, isMoreThanHalf = false, isPositiveArc = false, 9.4f, 19.6f)\n            moveTo(12f, 20f)\n            arcTo(13.81f, 13.81f, 0f, isMoreThanHalf = false, isPositiveArc = true, 9.5f, 12f)\n            arcTo(13.81f, 13.81f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12f, 4f)\n            arcTo(13.81f, 13.81f, 0f, isMoreThanHalf = false, isPositiveArc = true, 14.5f, 12f)\n            arcTo(13.81f, 13.81f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12f, 20f)\n            moveTo(14.6f, 19.6f)\n            arcTo(16.15f, 16.15f, 0f, isMoreThanHalf = false, isPositiveArc = false, 14.6f, 4.4f)\n            arcTo(8.03f, 8.03f, 0f, isMoreThanHalf = false, isPositiveArc = true, 20f, 12f)\n            arcTo(7.9f, 7.9f, 0f, isMoreThanHalf = false, isPositiveArc = true, 14.6f, 19.6f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Manga.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Manga: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Manga\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(160f, 800f)\n            quadTo(127f, 800f, 103.5f, 776.5f)\n            quadTo(80f, 753f, 80f, 720f)\n            lineTo(80f, 240f)\n            quadTo(80f, 207f, 103.5f, 183.5f)\n            quadTo(127f, 160f, 160f, 160f)\n            lineTo(800f, 160f)\n            quadTo(833f, 160f, 856.5f, 183.5f)\n            quadTo(880f, 207f, 880f, 240f)\n            lineTo(880f, 720f)\n            quadTo(880f, 753f, 856.5f, 776.5f)\n            quadTo(833f, 800f, 800f, 800f)\n            lineTo(160f, 800f)\n            close()\n            moveTo(423f, 720f)\n            lineTo(800f, 720f)\n            quadTo(800f, 720f, 800f, 720f)\n            quadTo(800f, 720f, 800f, 720f)\n            lineTo(800f, 411f)\n            lineTo(773f, 374f)\n            lineTo(680f, 404f)\n            lineTo(588f, 374f)\n            lineTo(530f, 453f)\n            lineTo(437f, 483f)\n            lineTo(437f, 581f)\n            lineTo(380f, 660f)\n            lineTo(423f, 720f)\n            close()\n            moveTo(324f, 720f)\n            lineTo(281f, 660f)\n            lineTo(357f, 555f)\n            lineTo(357f, 425f)\n            lineTo(480f, 385f)\n            lineTo(557f, 280f)\n            lineTo(680f, 320f)\n            lineTo(800f, 281f)\n            lineTo(800f, 240f)\n            quadTo(800f, 240f, 800f, 240f)\n            quadTo(800f, 240f, 800f, 240f)\n            lineTo(160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            lineTo(160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            lineTo(324f, 720f)\n            close()\n            moveTo(437f, 483f)\n            lineTo(437f, 483f)\n            quadTo(437f, 483f, 437f, 483f)\n            quadTo(437f, 483f, 437f, 483f)\n            lineTo(437f, 483f)\n            quadTo(437f, 483f, 437f, 483f)\n            quadTo(437f, 483f, 437f, 483f)\n            lineTo(437f, 483f)\n            quadTo(437f, 483f, 437f, 483f)\n            quadTo(437f, 483f, 437f, 483f)\n            lineTo(437f, 483f)\n            lineTo(437f, 483f)\n            lineTo(437f, 483f)\n            lineTo(437f, 483f)\n            lineTo(437f, 483f)\n            lineTo(437f, 483f)\n            lineTo(437f, 483f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Manga: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Manga\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(160f, 800f)\n            quadTo(127f, 800f, 103.5f, 776.5f)\n            quadTo(80f, 753f, 80f, 720f)\n            lineTo(80f, 240f)\n            quadTo(80f, 207f, 103.5f, 183.5f)\n            quadTo(127f, 160f, 160f, 160f)\n            lineTo(800f, 160f)\n            quadTo(833f, 160f, 856.5f, 183.5f)\n            quadTo(880f, 207f, 880f, 240f)\n            lineTo(880f, 720f)\n            quadTo(880f, 753f, 856.5f, 776.5f)\n            quadTo(833f, 800f, 800f, 800f)\n            lineTo(160f, 800f)\n            close()\n            moveTo(324f, 720f)\n            lineTo(800f, 720f)\n            quadTo(800f, 720f, 800f, 720f)\n            quadTo(800f, 720f, 800f, 720f)\n            lineTo(800f, 281f)\n            lineTo(800f, 281f)\n            lineTo(680f, 320f)\n            lineTo(557f, 280f)\n            lineTo(480f, 385f)\n            lineTo(357f, 425f)\n            lineTo(357f, 555f)\n            lineTo(281f, 660f)\n            lineTo(324f, 720f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MaterialDesign.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MaterialDesign: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"MaterialDesign\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(21f, 12f)\n            curveTo(21f, 9.97f, 20.33f, 8.09f, 19f, 6.38f)\n            verticalLineTo(17.63f)\n            curveTo(20.33f, 15.97f, 21f, 14.09f, 21f, 12f)\n            moveTo(17.63f, 19f)\n            horizontalLineTo(6.38f)\n            curveTo(7.06f, 19.55f, 7.95f, 20f, 9.05f, 20.41f)\n            curveTo(10.14f, 20.8f, 11.13f, 21f, 12f, 21f)\n            curveTo(12.88f, 21f, 13.86f, 20.8f, 14.95f, 20.41f)\n            curveTo(16.05f, 20f, 16.94f, 19.55f, 17.63f, 19f)\n            moveTo(11f, 17f)\n            lineTo(7f, 9f)\n            verticalLineTo(17f)\n            horizontalLineTo(11f)\n            moveTo(17f, 9f)\n            lineTo(13f, 17f)\n            horizontalLineTo(17f)\n            verticalLineTo(9f)\n            moveTo(12f, 14.53f)\n            lineTo(15.75f, 7f)\n            horizontalLineTo(8.25f)\n            lineTo(12f, 14.53f)\n            moveTo(17.63f, 5f)\n            curveTo(15.97f, 3.67f, 14.09f, 3f, 12f, 3f)\n            curveTo(9.91f, 3f, 8.03f, 3.67f, 6.38f, 5f)\n            horizontalLineTo(17.63f)\n            moveTo(5f, 17.63f)\n            verticalLineTo(6.38f)\n            curveTo(3.67f, 8.09f, 3f, 9.97f, 3f, 12f)\n            curveTo(3f, 14.09f, 3.67f, 15.97f, 5f, 17.63f)\n            moveTo(23f, 12f)\n            curveTo(23f, 15.03f, 21.94f, 17.63f, 19.78f, 19.78f)\n            curveTo(17.63f, 21.94f, 15.03f, 23f, 12f, 23f)\n            curveTo(8.97f, 23f, 6.38f, 21.94f, 4.22f, 19.78f)\n            curveTo(2.06f, 17.63f, 1f, 15.03f, 1f, 12f)\n            curveTo(1f, 8.97f, 2.06f, 6.38f, 4.22f, 4.22f)\n            curveTo(6.38f, 2.06f, 8.97f, 1f, 12f, 1f)\n            curveTo(15.03f, 1f, 17.63f, 2.06f, 19.78f, 4.22f)\n            curveTo(21.94f, 6.38f, 23f, 8.97f, 23f, 12f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MeshDownload.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MeshDownload: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"MeshDownloadOutlined\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15f, 20f)\n            curveToRelative(0f, -0.552f, -0.448f, -1f, -1f, -1f)\n            horizontalLineToRelative(-1f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(4f)\n            curveToRelative(1.105f, 0f, 2f, -0.895f, 2f, -2f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -1.105f, -0.895f, -2f, -2f, -2f)\n            horizontalLineTo(7f)\n            curveTo(5.895f, 3f, 5f, 3.895f, 5f, 5f)\n            verticalLineToRelative(10f)\n            curveToRelative(0f, 1.105f, 0.895f, 2f, 2f, 2f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-1f)\n            curveToRelative(-0.552f, 0f, -1f, 0.448f, -1f, 1f)\n            horizontalLineTo(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(7f)\n            curveToRelative(0f, 0.552f, 0.448f, 1f, 1f, 1f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.552f, 0f, 1f, -0.448f, 1f, -1f)\n            horizontalLineToRelative(7f)\n            verticalLineToRelative(-2f)\n            horizontalLineTo(15f)\n            close()\n            moveTo(17f, 15f)\n            horizontalLineToRelative(-1.518f)\n            curveToRelative(-0.017f, -0.055f, -0.533f, -1.283f, -0.562f, -1.348f)\n            curveToRelative(0.703f, -0.081f, 1.37f, -0.296f, 1.994f, -0.631f)\n            lineToRelative(0f, -0f)\n            curveTo(16.934f, 13.01f, 16.967f, 12.996f, 17f, 12.982f)\n            verticalLineTo(15f)\n            close()\n            moveTo(17f, 5f)\n            verticalLineToRelative(1.59f)\n            lineToRelative(-0.004f, 0.001f)\n            curveTo(16.94f, 6.609f, 16.5f, 6.784f, 16.5f, 6.784f)\n            curveToRelative(-0.138f, 0.055f, -0.275f, 0.098f, -0.414f, 0.17f)\n            curveToRelative(-0.139f, 0.072f, -0.273f, 0.138f, -0.405f, 0.196f)\n            curveToRelative(-0.087f, -0.745f, -0.324f, -1.445f, -0.674f, -2.095f)\n            curveTo(15.001f, 5.044f, 14.992f, 5.02f, 14.984f, 5f)\n            horizontalLineTo(17f)\n            close()\n            moveTo(14.982f, 10.612f)\n            curveToRelative(0.224f, -0.445f, 0.454f, -0.928f, 0.585f, -1.478f)\n            curveTo(16.104f, 9.003f, 16.569f, 8.783f, 17f, 8.574f)\n            verticalLineToRelative(2.413f)\n            lineToRelative(-0.169f, 0.06f)\n            curveToRelative(-0.214f, 0.077f, -0.446f, 0.16f, -0.685f, 0.282f)\n            curveToRelative(-0.406f, 0.208f, -0.776f, 0.379f, -1.146f, 0.442f)\n            curveToRelative(-0.112f, 0.019f, -0.226f, 0.021f, -0.339f, 0.032f)\n            curveTo(14.699f, 11.389f, 14.79f, 10.992f, 14.982f, 10.612f)\n            close()\n            moveTo(13.002f, 5f)\n            lineToRelative(0.032f, 0.098f)\n            curveToRelative(0.007f, 0.023f, 0.011f, 0.041f, 0.019f, 0.064f)\n            lineTo(13.169f, 5.5f)\n            lineToRelative(0.126f, 0.277f)\n            lineToRelative(0.002f, -0.004f)\n            curveToRelative(0.008f, 0.017f, 0.012f, 0.034f, 0.02f, 0.051f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.202f, 0.404f, 0.382f, 0.761f, 0.458f, 1.113f)\n            curveToRelative(0.032f, 0.146f, 0.034f, 0.302f, 0.049f, 0.453f)\n            curveToRelative(-0.421f, -0.039f, -0.825f, -0.136f, -1.215f, -0.335f)\n            curveToRelative(-0.433f, -0.22f, -0.911f, -0.429f, -1.443f, -0.557f)\n            curveTo(11.032f, 5.937f, 10.796f, 5.45f, 10.575f, 5f)\n            horizontalLineTo(13.002f)\n            close()\n            moveTo(10.695f, 10.376f)\n            curveToRelative(0.311f, -0.596f, 0.508f, -1.233f, 0.582f, -1.899f)\n            curveToRelative(0.19f, 0.084f, 0.387f, 0.18f, 0.597f, 0.285f)\n            curveToRelative(0.544f, 0.268f, 1.116f, 0.424f, 1.701f, 0.489f)\n            curveToRelative(-0.134f, 0.29f, -0.276f, 0.583f, -0.412f, 0.89f)\n            curveToRelative(-0.205f, 0.46f, -0.312f, 0.933f, -0.362f, 1.404f)\n            curveToRelative(-0.22f, -0.098f, -0.448f, -0.209f, -0.702f, -0.33f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.516f, -0.243f, -1.053f, -0.38f, -1.599f, -0.439f)\n            curveTo(10.558f, 10.645f, 10.624f, 10.512f, 10.695f, 10.376f)\n            close()\n            moveTo(7f, 5f)\n            horizontalLineToRelative(1.592f)\n            lineToRelative(0.197f, 0.5f)\n            curveToRelative(0.069f, 0.173f, 0.128f, 0.347f, 0.218f, 0.519f)\n            curveToRelative(0.062f, 0.119f, 0.117f, 0.236f, 0.168f, 0.352f)\n            curveTo(8.494f, 6.448f, 7.842f, 6.648f, 7.232f, 6.974f)\n            horizontalLineToRelative(-0f)\n            curveTo(7.168f, 7.008f, 7.079f, 7.043f, 7f, 7.076f)\n            verticalLineTo(5f)\n            close()\n            moveTo(7f, 15f)\n            verticalLineToRelative(-1.52f)\n            lineToRelative(0.159f, -0.054f)\n            curveToRelative(0.315f, -0.106f, 0.619f, -0.238f, 0.912f, -0.391f)\n            horizontalLineToRelative(-0f)\n            curveToRelative(0.11f, -0.057f, 0.22f, -0.089f, 0.329f, -0.137f)\n            curveToRelative(0.078f, 0.674f, 0.279f, 1.32f, 0.601f, 1.924f)\n            verticalLineToRelative(0f)\n            curveTo(9.026f, 14.867f, 9.055f, 14.941f, 9.08f, 15f)\n            horizontalLineTo(7f)\n            close()\n            moveTo(9.114f, 9.383f)\n            curveToRelative(-0.225f, 0.452f, -0.465f, 0.944f, -0.6f, 1.509f)\n            curveTo(7.943f, 11.03f, 7.453f, 11.273f, 7f, 11.492f)\n            verticalLineTo(9.067f)\n            lineToRelative(0.159f, -0.053f)\n            curveToRelative(0.228f, -0.077f, 0.47f, -0.164f, 0.714f, -0.286f)\n            lineToRelative(0f, -0f)\n            curveToRelative(0.396f, -0.199f, 0.75f, -0.376f, 1.099f, -0.45f)\n            horizontalLineToRelative(-0f)\n            curveToRelative(0.147f, -0.032f, 0.299f, -0.033f, 0.449f, -0.047f)\n            curveTo(9.384f, 8.631f, 9.297f, 9.015f, 9.114f, 9.383f)\n            close()\n            moveTo(11.018f, 14.835f)\n            curveToRelative(-0.08f, -0.228f, -0.169f, -0.47f, -0.293f, -0.715f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.183f, -0.36f, -0.341f, -0.688f, -0.414f, -1.013f)\n            curveToRelative(-0.035f, -0.152f, -0.037f, -0.313f, -0.053f, -0.471f)\n            curveToRelative(0.426f, 0.04f, 0.835f, 0.139f, 1.233f, 0.342f)\n            horizontalLineToRelative(0f)\n            curveToRelative(0.352f, 0.179f, 0.733f, 0.374f, 1.174f, 0.499f)\n            curveToRelative(0.09f, 0.025f, 0.176f, 0.044f, 0.263f, 0.065f)\n            curveToRelative(0.117f, 0.486f, 0.3f, 0.933f, 0.51f, 1.342f)\n            verticalLineToRelative(0f)\n            curveTo(13.454f, 14.91f, 13.474f, 14.964f, 13.49f, 15f)\n            horizontalLineToRelative(-2.413f)\n            lineTo(11.018f, 14.835f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MeshGradient.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MeshGradient: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.MeshGradient\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 3f)\n            horizontalLineTo(5f)\n            curveToRelative(-1.11f, 0f, -2f, 0.89f, -2f, 2f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 1.105f, 0.895f, 2f, 2f, 2f)\n            horizontalLineToRelative(14f)\n            curveToRelative(1.105f, 0f, 2f, -0.895f, 2f, -2f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -1.11f, -0.9f, -2f, -2f, -2f)\n            close()\n            moveTo(19f, 13.086f)\n            curveToRelative(-1.067f, 0.87f, -2.173f, 1.365f, -3.294f, 1.453f)\n            curveToRelative(-0.259f, 0.022f, -0.499f, 0.012f, -0.734f, -0.007f)\n            curveToRelative(0.073f, -0.827f, 0.363f, -1.543f, 0.698f, -2.34f)\n            curveToRelative(0.2f, -0.476f, 0.41f, -0.983f, 0.576f, -1.535f)\n            curveToRelative(0.943f, -0.129f, 1.863f, -0.464f, 2.754f, -0.974f)\n            verticalLineToRelative(3.403f)\n            close()\n            moveTo(5f, 11.005f)\n            curveToRelative(1.239f, -1.126f, 2.488f, -1.75f, 3.717f, -1.851f)\n            curveToRelative(-0.087f, 0.799f, -0.38f, 1.492f, -0.703f, 2.264f)\n            curveToRelative(-0.226f, 0.538f, -0.46f, 1.118f, -0.633f, 1.757f)\n            curveToRelative(-0.805f, 0.215f, -1.6f, 0.602f, -2.381f, 1.121f)\n            verticalLineToRelative(-3.29f)\n            close()\n            moveTo(14.54f, 8.294f)\n            curveToRelative(0.011f, 0.128f, -0.004f, 0.242f, -0.003f, 0.364f)\n            curveToRelative(-0.67f, -0.121f, -1.286f, -0.364f, -1.954f, -0.644f)\n            curveToRelative(-0.603f, -0.254f, -1.262f, -0.514f, -1.996f, -0.687f)\n            curveToRelative(-0.159f, -0.795f, -0.468f, -1.571f, -0.9f, -2.327f)\n            horizontalLineToRelative(3.4f)\n            curveToRelative(0.87f, 1.067f, 1.365f, 2.173f, 1.453f, 3.294f)\n            close()\n            moveTo(14.144f, 10.634f)\n            curveToRelative(-0.098f, 0.257f, -0.205f, 0.516f, -0.318f, 0.784f)\n            curveToRelative(-0.32f, 0.762f, -0.665f, 1.599f, -0.808f, 2.586f)\n            curveToRelative(-0.145f, -0.059f, -0.287f, -0.115f, -0.436f, -0.178f)\n            curveToRelative(-0.875f, -0.368f, -1.855f, -0.756f, -3.043f, -0.844f)\n            curveToRelative(0.098f, -0.258f, 0.205f, -0.519f, 0.319f, -0.789f)\n            curveToRelative(0.34f, -0.807f, 0.71f, -1.696f, 0.838f, -2.762f)\n            curveToRelative(0.365f, 0.123f, 0.729f, 0.266f, 1.112f, 0.427f)\n            curveToRelative(0.698f, 0.294f, 1.455f, 0.613f, 2.337f, 0.776f)\n            close()\n            moveTo(9.145f, 15.232f)\n            curveToRelative(-0.007f, -0.094f, 0.007f, -0.177f, 0.006f, -0.267f)\n            curveToRelative(0.964f, 0.017f, 1.762f, 0.329f, 2.657f, 0.705f)\n            curveToRelative(0.398f, 0.168f, 0.817f, 0.342f, 1.266f, 0.493f)\n            curveToRelative(0.187f, 0.961f, 0.61f, 1.909f, 1.226f, 2.837f)\n            horizontalLineToRelative(-3.294f)\n            curveToRelative(-1.142f, -1.256f, -1.772f, -2.523f, -1.86f, -3.768f)\n            close()\n            moveTo(19f, 7.277f)\n            curveToRelative(-0.798f, 0.65f, -1.618f, 1.091f, -2.45f, 1.306f)\n            curveToRelative(-0.002f, -0.147f, -0.003f, -0.294f, -0.016f, -0.449f)\n            curveToRelative(-0.086f, -1.077f, -0.445f, -2.124f, -1.031f, -3.135f)\n            horizontalLineToRelative(3.497f)\n            verticalLineToRelative(2.277f)\n            close()\n            moveTo(7.278f, 5f)\n            curveToRelative(0.575f, 0.707f, 0.974f, 1.432f, 1.209f, 2.167f)\n            curveToRelative(-1.183f, 0.109f, -2.35f, 0.55f, -3.487f, 1.304f)\n            verticalLineToRelative(-3.472f)\n            horizontalLineToRelative(2.278f)\n            close()\n            moveTo(5f, 16.815f)\n            curveToRelative(0.716f, -0.65f, 1.435f, -1.116f, 2.152f, -1.427f)\n            curveToRelative(0.089f, 1.226f, 0.536f, 2.435f, 1.318f, 3.612f)\n            horizontalLineToRelative(-3.47f)\n            verticalLineToRelative(-2.185f)\n            close()\n            moveTo(16.815f, 19f)\n            curveToRelative(-0.739f, -0.813f, -1.242f, -1.631f, -1.542f, -2.445f)\n            curveToRelative(0.192f, 0.002f, 0.389f, -0.004f, 0.592f, -0.021f)\n            curveToRelative(1.077f, -0.086f, 2.124f, -0.445f, 3.135f, -1.031f)\n            verticalLineToRelative(3.497f)\n            horizontalLineToRelative(-2.185f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MiniEdit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.MiniEdit: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Mini Edit\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(18.7912f, 7.9369f)\n            curveToRelative(-0.1161f, -0.2838f, -0.2774f, -0.5418f, -0.4837f, -0.7739f)\n            lineToRelative(-1.4317f, -1.4318f)\n            curveToRelative(-0.2322f, -0.2321f, -0.4902f, -0.4062f, -0.7739f, -0.5223f)\n            curveToRelative(-0.2838f, -0.1161f, -0.5804f, -0.1741f, -0.89f, -0.1741f)\n            curveToRelative(-0.2838f, 0.0f, -0.5676f, 0.0516f, -0.8513f, 0.1547f)\n            curveToRelative(-0.2838f, 0.1032f, -0.5418f, 0.2709f, -0.7739f, 0.5031f)\n            lineToRelative(-8.5519f, 8.5132f)\n            verticalLineToRelative(4.7596f)\n            horizontalLineToRelative(4.7596f)\n            lineToRelative(8.5132f, -8.5132f)\n            curveToRelative(0.2321f, -0.2322f, 0.3998f, -0.4966f, 0.5031f, -0.7933f)\n            curveToRelative(0.1032f, -0.2966f, 0.1547f, -0.5869f, 0.1547f, -0.8707f)\n            curveTo(18.9653f, 8.5044f, 18.9073f, 8.2206f, 18.7912f, 7.9369f)\n            close()\n            moveTo(8.8269f, 16.6435f)\n            horizontalLineTo(7.3565f)\n            verticalLineToRelative(-1.4705f)\n            lineToRelative(4.7209f, -4.6823f)\n            lineToRelative(0.7353f, 0.6965f)\n            lineToRelative(0.6965f, 0.7352f)\n            lineTo(8.8269f, 16.6435f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MiniEditLarge.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.MiniEditLarge: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"MiniEditLarge\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(20.775f, 6.75f)\n            curveToRelative(-0.15f, -0.367f, -0.358f, -0.7f, -0.625f, -1f)\n            lineToRelative(-1.85f, -1.85f)\n            curveTo(18f, 3.6f, 17.667f, 3.375f, 17.3f, 3.225f)\n            curveTo(16.933f, 3.075f, 16.55f, 3f, 16.15f, 3f)\n            curveToRelative(-0.183f, 0f, -0.367f, 0.017f, -0.55f, 0.05f)\n            curveToRelative(-0.183f, 0.033f, -0.367f, 0.083f, -0.55f, 0.15f)\n            curveToRelative(-0.367f, 0.133f, -0.7f, 0.35f, -1f, 0.65f)\n            lineToRelative(-0.461f, 0.458f)\n            lineTo(3.6f, 14.25f)\n            curveTo(3.4f, 14.45f, 3.25f, 14.675f, 3.15f, 14.925f)\n            reflectiveCurveTo(3f, 15.433f, 3f, 15.7f)\n            verticalLineTo(19f)\n            curveToRelative(0f, 0.567f, 0.192f, 1.042f, 0.575f, 1.425f)\n            curveTo(3.958f, 20.808f, 4.433f, 21f, 5f, 21f)\n            horizontalLineToRelative(3.3f)\n            curveToRelative(0.267f, 0f, 0.525f, -0.05f, 0.775f, -0.15f)\n            reflectiveCurveToRelative(0.475f, -0.25f, 0.675f, -0.45f)\n            lineToRelative(2.002f, -2.002f)\n            lineTo(20.15f, 10f)\n            curveToRelative(0.15f, -0.15f, 0.279f, -0.31f, 0.387f, -0.481f)\n            reflectiveCurveToRelative(0.196f, -0.352f, 0.263f, -0.544f)\n            curveTo(20.867f, 8.783f, 20.917f, 8.594f, 20.95f, 8.406f)\n            reflectiveCurveTo(21f, 8.033f, 21f, 7.85f)\n            curveTo(21f, 7.483f, 20.925f, 7.117f, 20.775f, 6.75f)\n            close()\n            moveTo(16.15f, 6f)\n            lineTo(18f, 7.85f)\n            lineToRelative(-1.85f, 1.95f)\n            lineTo(14.25f, 7.9f)\n            lineTo(16.15f, 6f)\n            close()\n        }\n    }.build()\n}\n\n\nval Icons.Outlined.MiniEditLarge: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"MiniEditLarge Outlined\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(20.775f, 6.75f)\n            curveToRelative(-0.15f, -0.367f, -0.358f, -0.7f, -0.625f, -1f)\n            lineToRelative(-1.85f, -1.85f)\n            curveTo(18f, 3.6f, 17.667f, 3.375f, 17.3f, 3.225f)\n            curveTo(16.933f, 3.075f, 16.55f, 3f, 16.15f, 3f)\n            curveToRelative(-0.367f, 0f, -0.733f, 0.067f, -1.1f, 0.2f)\n            curveToRelative(-0.367f, 0.133f, -0.7f, 0.35f, -1f, 0.65f)\n            lineTo(3.6f, 14.25f)\n            curveTo(3.4f, 14.45f, 3.25f, 14.675f, 3.15f, 14.925f)\n            reflectiveCurveTo(3f, 15.433f, 3f, 15.7f)\n            verticalLineTo(19f)\n            curveToRelative(0f, 0.567f, 0.192f, 1.042f, 0.575f, 1.425f)\n            curveTo(3.958f, 20.808f, 4.433f, 21f, 5f, 21f)\n            horizontalLineToRelative(3.3f)\n            curveToRelative(0.267f, 0f, 0.525f, -0.05f, 0.775f, -0.15f)\n            reflectiveCurveToRelative(0.475f, -0.25f, 0.675f, -0.45f)\n            lineTo(20.15f, 10f)\n            curveToRelative(0.3f, -0.3f, 0.517f, -0.642f, 0.65f, -1.025f)\n            curveTo(20.933f, 8.592f, 21f, 8.217f, 21f, 7.85f)\n            reflectiveCurveTo(20.925f, 7.117f, 20.775f, 6.75f)\n            close()\n            moveTo(7.9f, 18f)\n            horizontalLineTo(6f)\n            verticalLineToRelative(-1.9f)\n            lineToRelative(6.1f, -6.05f)\n            lineToRelative(0.95f, 0.9f)\n            lineToRelative(0.9f, 0.95f)\n            lineTo(7.9f, 18f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Mobile.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Mobile: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Mobile\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(280f, 840f)\n            lineTo(680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            lineTo(680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n            moveTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n            moveTo(480f, 240f)\n            quadTo(497f, 240f, 508.5f, 228.5f)\n            quadTo(520f, 217f, 520f, 200f)\n            quadTo(520f, 183f, 508.5f, 171.5f)\n            quadTo(497f, 160f, 480f, 160f)\n            quadTo(463f, 160f, 451.5f, 171.5f)\n            quadTo(440f, 183f, 440f, 200f)\n            quadTo(440f, 217f, 451.5f, 228.5f)\n            quadTo(463f, 240f, 480f, 240f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Mobile: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Mobile\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(480f, 240f)\n            quadTo(497f, 240f, 508.5f, 228.5f)\n            quadTo(520f, 217f, 520f, 200f)\n            quadTo(520f, 183f, 508.5f, 171.5f)\n            quadTo(497f, 160f, 480f, 160f)\n            quadTo(463f, 160f, 451.5f, 171.5f)\n            quadTo(440f, 183f, 440f, 200f)\n            quadTo(440f, 217f, 451.5f, 228.5f)\n            quadTo(463f, 240f, 480f, 240f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileArrowDown.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MobileArrowDown: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.MobileArrowDown\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(280f, 840f)\n            lineTo(680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            lineTo(680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n            moveTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n            moveTo(480f, 640f)\n            lineTo(640f, 480f)\n            lineTo(584f, 424f)\n            lineTo(520f, 486f)\n            lineTo(520f, 320f)\n            lineTo(440f, 320f)\n            lineTo(440f, 486f)\n            lineTo(376f, 424f)\n            lineTo(320f, 480f)\n            lineTo(480f, 640f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.MobileArrowDown: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.MobileArrowDown\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(480f, 640f)\n            lineTo(640f, 480f)\n            lineTo(584f, 424f)\n            lineTo(520f, 486f)\n            lineTo(520f, 320f)\n            lineTo(440f, 320f)\n            lineTo(440f, 486f)\n            lineTo(376f, 424f)\n            lineTo(320f, 480f)\n            lineTo(480f, 640f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileArrowUpRight.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MobileArrowUpRight: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.MobileArrowUpRight\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f,\n        autoMirror = true\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(280f, 840f)\n            lineTo(680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            lineTo(680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n            moveTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n            moveTo(396f, 620f)\n            lineTo(520f, 496f)\n            lineTo(520f, 600f)\n            lineTo(600f, 600f)\n            lineTo(600f, 360f)\n            lineTo(360f, 360f)\n            lineTo(360f, 440f)\n            lineTo(464f, 440f)\n            lineTo(340f, 564f)\n            lineTo(396f, 620f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.MobileArrowUpRight: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.MobileArrowUpRight\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f,\n        autoMirror = true\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(396f, 620f)\n            lineTo(520f, 496f)\n            lineTo(520f, 600f)\n            lineTo(600f, 600f)\n            lineTo(600f, 360f)\n            lineTo(360f, 360f)\n            lineTo(360f, 440f)\n            lineTo(464f, 440f)\n            lineTo(340f, 564f)\n            lineTo(396f, 620f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileCast.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.MobileCast: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.MobileCast\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(200f, 920f)\n            lineTo(200f, 840f)\n            quadTo(233f, 840f, 256.5f, 863.5f)\n            quadTo(280f, 887f, 280f, 920f)\n            lineTo(200f, 920f)\n            close()\n            moveTo(360f, 920f)\n            quadTo(360f, 854f, 313f, 807f)\n            quadTo(266f, 760f, 200f, 760f)\n            lineTo(200f, 680f)\n            quadTo(300f, 680f, 370f, 750f)\n            quadTo(440f, 820f, 440f, 920f)\n            lineTo(360f, 920f)\n            close()\n            moveTo(520f, 920f)\n            quadTo(520f, 786f, 427f, 693f)\n            quadTo(334f, 600f, 200f, 600f)\n            lineTo(200f, 520f)\n            quadTo(283f, 520f, 356f, 551.5f)\n            quadTo(429f, 583f, 483f, 637f)\n            quadTo(537f, 691f, 568.5f, 764f)\n            quadTo(600f, 837f, 600f, 920f)\n            lineTo(520f, 920f)\n            close()\n            moveTo(480f, 240f)\n            quadTo(497f, 240f, 508.5f, 228.5f)\n            quadTo(520f, 217f, 520f, 200f)\n            quadTo(520f, 183f, 508.5f, 171.5f)\n            quadTo(497f, 160f, 480f, 160f)\n            quadTo(463f, 160f, 451.5f, 171.5f)\n            quadTo(440f, 183f, 440f, 200f)\n            quadTo(440f, 217f, 451.5f, 228.5f)\n            quadTo(463f, 240f, 480f, 240f)\n            close()\n            moveTo(680f, 920f)\n            quadTo(680f, 820f, 642f, 732.5f)\n            quadTo(604f, 645f, 538.5f, 580f)\n            quadTo(473f, 515f, 386f, 477.5f)\n            quadTo(299f, 440f, 200f, 440f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileLandscape.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MobileLandscape: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.MobileLandscape\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(120f, 760f)\n            quadTo(87f, 760f, 63.5f, 736.5f)\n            quadTo(40f, 713f, 40f, 680f)\n            lineTo(40f, 280f)\n            quadTo(40f, 247f, 63.5f, 223.5f)\n            quadTo(87f, 200f, 120f, 200f)\n            lineTo(244f, 200f)\n            quadTo(251f, 182f, 266f, 171f)\n            quadTo(281f, 160f, 300f, 160f)\n            lineTo(380f, 160f)\n            quadTo(399f, 160f, 414f, 171f)\n            quadTo(429f, 182f, 436f, 200f)\n            lineTo(840f, 200f)\n            quadTo(873f, 200f, 896.5f, 223.5f)\n            quadTo(920f, 247f, 920f, 280f)\n            lineTo(920f, 680f)\n            quadTo(920f, 713f, 896.5f, 736.5f)\n            quadTo(873f, 760f, 840f, 760f)\n            lineTo(120f, 760f)\n            close()\n            moveTo(840f, 680f)\n            lineTo(840f, 280f)\n            quadTo(840f, 280f, 840f, 280f)\n            quadTo(840f, 280f, 840f, 280f)\n            lineTo(120f, 280f)\n            quadTo(120f, 280f, 120f, 280f)\n            quadTo(120f, 280f, 120f, 280f)\n            lineTo(120f, 680f)\n            quadTo(120f, 680f, 120f, 680f)\n            quadTo(120f, 680f, 120f, 680f)\n            lineTo(840f, 680f)\n            quadTo(840f, 680f, 840f, 680f)\n            quadTo(840f, 680f, 840f, 680f)\n            close()\n            moveTo(120f, 280f)\n            lineTo(120f, 280f)\n            quadTo(120f, 280f, 120f, 280f)\n            quadTo(120f, 280f, 120f, 280f)\n            lineTo(120f, 680f)\n            quadTo(120f, 680f, 120f, 680f)\n            quadTo(120f, 680f, 120f, 680f)\n            lineTo(120f, 680f)\n            quadTo(120f, 680f, 120f, 680f)\n            quadTo(120f, 680f, 120f, 680f)\n            lineTo(120f, 280f)\n            quadTo(120f, 280f, 120f, 280f)\n            quadTo(120f, 280f, 120f, 280f)\n            close()\n            moveTo(200f, 520f)\n            quadTo(217f, 520f, 228.5f, 508.5f)\n            quadTo(240f, 497f, 240f, 480f)\n            quadTo(240f, 463f, 228.5f, 451.5f)\n            quadTo(217f, 440f, 200f, 440f)\n            quadTo(183f, 440f, 171.5f, 451.5f)\n            quadTo(160f, 463f, 160f, 480f)\n            quadTo(160f, 497f, 171.5f, 508.5f)\n            quadTo(183f, 520f, 200f, 520f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileLayout.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.MobileLayout: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.MobileLayout\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(120f, 840f)\n            quadTo(87f, 840f, 63.5f, 816.5f)\n            quadTo(40f, 793f, 40f, 760f)\n            lineTo(40f, 680f)\n            quadTo(40f, 647f, 63.5f, 623.5f)\n            quadTo(87f, 600f, 120f, 600f)\n            lineTo(360f, 600f)\n            quadTo(393f, 600f, 416.5f, 623.5f)\n            quadTo(440f, 647f, 440f, 680f)\n            lineTo(440f, 760f)\n            quadTo(440f, 793f, 416.5f, 816.5f)\n            quadTo(393f, 840f, 360f, 840f)\n            lineTo(120f, 840f)\n            close()\n            moveTo(600f, 840f)\n            quadTo(567f, 840f, 543.5f, 816.5f)\n            quadTo(520f, 793f, 520f, 760f)\n            lineTo(520f, 200f)\n            quadTo(520f, 167f, 543.5f, 143.5f)\n            quadTo(567f, 120f, 600f, 120f)\n            lineTo(840f, 120f)\n            quadTo(873f, 120f, 896.5f, 143.5f)\n            quadTo(920f, 167f, 920f, 200f)\n            lineTo(920f, 760f)\n            quadTo(920f, 793f, 896.5f, 816.5f)\n            quadTo(873f, 840f, 840f, 840f)\n            lineTo(600f, 840f)\n            close()\n            moveTo(720f, 720f)\n            quadTo(737f, 720f, 748.5f, 708.5f)\n            quadTo(760f, 697f, 760f, 680f)\n            quadTo(760f, 663f, 748.5f, 651.5f)\n            quadTo(737f, 640f, 720f, 640f)\n            quadTo(703f, 640f, 691.5f, 651.5f)\n            quadTo(680f, 663f, 680f, 680f)\n            quadTo(680f, 697f, 691.5f, 708.5f)\n            quadTo(703f, 720f, 720f, 720f)\n            close()\n            moveTo(120f, 520f)\n            quadTo(87f, 520f, 63.5f, 496.5f)\n            quadTo(40f, 473f, 40f, 440f)\n            lineTo(40f, 200f)\n            quadTo(40f, 167f, 63.5f, 143.5f)\n            quadTo(87f, 120f, 120f, 120f)\n            lineTo(360f, 120f)\n            quadTo(393f, 120f, 416.5f, 143.5f)\n            quadTo(440f, 167f, 440f, 200f)\n            lineTo(440f, 440f)\n            quadTo(440f, 473f, 416.5f, 496.5f)\n            quadTo(393f, 520f, 360f, 520f)\n            lineTo(120f, 520f)\n            close()\n            moveTo(280f, 320f)\n            quadTo(297f, 320f, 308.5f, 308.5f)\n            quadTo(320f, 297f, 320f, 280f)\n            quadTo(320f, 263f, 308.5f, 251.5f)\n            quadTo(297f, 240f, 280f, 240f)\n            quadTo(263f, 240f, 251.5f, 251.5f)\n            quadTo(240f, 263f, 240f, 280f)\n            quadTo(240f, 297f, 251.5f, 308.5f)\n            quadTo(263f, 320f, 280f, 320f)\n            close()\n            moveTo(110f, 440f)\n            lineTo(290f, 440f)\n            lineTo(200f, 320f)\n            lineTo(110f, 440f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileRotateLock.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MobileRotateLock: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.MobileRotateLock\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(714f, 360f)\n            quadTo(700f, 360f, 690f, 350f)\n            quadTo(680f, 340f, 680f, 326f)\n            lineTo(680f, 194f)\n            quadTo(680f, 180f, 690f, 170f)\n            quadTo(700f, 160f, 714f, 160f)\n            lineTo(720f, 160f)\n            lineTo(720f, 120f)\n            quadTo(720f, 87f, 743.5f, 63.5f)\n            quadTo(767f, 40f, 800f, 40f)\n            quadTo(833f, 40f, 856.5f, 63.5f)\n            quadTo(880f, 87f, 880f, 120f)\n            lineTo(880f, 160f)\n            lineTo(886f, 160f)\n            quadTo(900f, 160f, 910f, 170f)\n            quadTo(920f, 180f, 920f, 194f)\n            lineTo(920f, 326f)\n            quadTo(920f, 340f, 910f, 350f)\n            quadTo(900f, 360f, 886f, 360f)\n            lineTo(714f, 360f)\n            close()\n            moveTo(760f, 160f)\n            lineTo(840f, 160f)\n            lineTo(840f, 120f)\n            quadTo(840f, 103f, 828.5f, 91.5f)\n            quadTo(817f, 80f, 800f, 80f)\n            quadTo(783f, 80f, 771.5f, 91.5f)\n            quadTo(760f, 103f, 760f, 120f)\n            lineTo(760f, 160f)\n            close()\n            moveTo(496f, 778f)\n            lineTo(183f, 464f)\n            quadTo(172f, 453f, 166.5f, 438.5f)\n            quadTo(161f, 424f, 161f, 410f)\n            quadTo(161f, 395f, 166.5f, 381f)\n            quadTo(172f, 367f, 183f, 356f)\n            lineTo(356f, 183f)\n            quadTo(367f, 172f, 381.5f, 166f)\n            quadTo(396f, 160f, 410f, 160f)\n            quadTo(425f, 160f, 439f, 166f)\n            quadTo(453f, 172f, 464f, 183f)\n            lineTo(777f, 496f)\n            quadTo(788f, 507f, 794f, 521f)\n            quadTo(800f, 535f, 800f, 550f)\n            quadTo(800f, 564f, 794f, 578.5f)\n            quadTo(788f, 593f, 777f, 604f)\n            lineTo(604f, 778f)\n            quadTo(593f, 789f, 579f, 794.5f)\n            quadTo(565f, 800f, 550f, 800f)\n            quadTo(536f, 800f, 521.5f, 794.5f)\n            quadTo(507f, 789f, 496f, 778f)\n            close()\n            moveTo(550f, 720f)\n            quadTo(550f, 720f, 550f, 720f)\n            quadTo(550f, 720f, 550f, 720f)\n            lineTo(720f, 550f)\n            quadTo(720f, 550f, 720f, 550f)\n            quadTo(720f, 550f, 720f, 550f)\n            lineTo(410f, 240f)\n            quadTo(410f, 240f, 410f, 240f)\n            quadTo(410f, 240f, 410f, 240f)\n            lineTo(240f, 410f)\n            quadTo(240f, 410f, 240f, 410f)\n            quadTo(240f, 410f, 240f, 410f)\n            lineTo(550f, 720f)\n            close()\n            moveTo(480f, 960f)\n            quadTo(381f, 960f, 293.5f, 922.5f)\n            quadTo(206f, 885f, 140.5f, 819.5f)\n            quadTo(75f, 754f, 37.5f, 666.5f)\n            quadTo(0f, 579f, 0f, 480f)\n            lineTo(80f, 480f)\n            quadTo(80f, 551f, 104f, 616f)\n            quadTo(128f, 681f, 170.5f, 733f)\n            quadTo(213f, 785f, 272f, 821.5f)\n            quadTo(331f, 858f, 401f, 873f)\n            lineTo(296f, 768f)\n            lineTo(352f, 712f)\n            lineTo(588f, 948f)\n            quadTo(562f, 954f, 534.5f, 957f)\n            quadTo(507f, 960f, 480f, 960f)\n            close()\n            moveTo(480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            close()\n            moveTo(373f, 404f)\n            quadTo(386f, 404f, 394.5f, 395f)\n            quadTo(403f, 386f, 403f, 374f)\n            quadTo(403f, 361f, 394.5f, 352.5f)\n            quadTo(386f, 344f, 373f, 344f)\n            quadTo(361f, 344f, 352f, 352.5f)\n            quadTo(343f, 361f, 343f, 374f)\n            quadTo(343f, 386f, 352f, 395f)\n            quadTo(361f, 404f, 373f, 404f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileShare.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MobileShare: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.MobileShare\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f,\n        autoMirror = true\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(320f, 640f)\n            lineTo(400f, 640f)\n            lineTo(400f, 520f)\n            quadTo(400f, 520f, 400f, 520f)\n            quadTo(400f, 520f, 400f, 520f)\n            lineTo(486f, 520f)\n            lineTo(444f, 564f)\n            lineTo(500f, 620f)\n            lineTo(640f, 480f)\n            lineTo(500f, 340f)\n            lineTo(444f, 396f)\n            lineTo(486f, 440f)\n            lineTo(400f, 440f)\n            quadTo(367f, 440f, 343.5f, 463.5f)\n            quadTo(320f, 487f, 320f, 520f)\n            lineTo(320f, 640f)\n            close()\n            moveTo(280f, 920f)\n            quadTo(247f, 920f, 223.5f, 896.5f)\n            quadTo(200f, 873f, 200f, 840f)\n            lineTo(200f, 120f)\n            quadTo(200f, 87f, 223.5f, 63.5f)\n            quadTo(247f, 40f, 280f, 40f)\n            lineTo(680f, 40f)\n            quadTo(713f, 40f, 736.5f, 63.5f)\n            quadTo(760f, 87f, 760f, 120f)\n            lineTo(760f, 244f)\n            quadTo(778f, 251f, 789f, 266f)\n            quadTo(800f, 281f, 800f, 300f)\n            lineTo(800f, 380f)\n            quadTo(800f, 399f, 789f, 414f)\n            quadTo(778f, 429f, 760f, 436f)\n            lineTo(760f, 840f)\n            quadTo(760f, 873f, 736.5f, 896.5f)\n            quadTo(713f, 920f, 680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(280f, 840f)\n            lineTo(680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            quadTo(680f, 840f, 680f, 840f)\n            lineTo(680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            quadTo(680f, 120f, 680f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n            moveTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            quadTo(280f, 120f, 280f, 120f)\n            lineTo(280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            quadTo(280f, 840f, 280f, 840f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.MobileShare: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.MobileShare\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(320f, 640f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-120f)\n            horizontalLineToRelative(86f)\n            lineToRelative(-42f, 44f)\n            lineToRelative(56f, 56f)\n            lineToRelative(140f, -140f)\n            lineToRelative(-140f, -140f)\n            lineToRelative(-56f, 56f)\n            lineToRelative(42f, 44f)\n            horizontalLineToRelative(-86f)\n            quadToRelative(-33f, 0f, -56.5f, 23.5f)\n            reflectiveQuadTo(320f, 520f)\n            verticalLineToRelative(120f)\n            close()\n            moveTo(280f, 920f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(200f, 840f)\n            verticalLineToRelative(-720f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(280f, 40f)\n            horizontalLineToRelative(400f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(760f, 120f)\n            verticalLineToRelative(124f)\n            quadToRelative(18f, 7f, 29f, 22f)\n            reflectiveQuadToRelative(11f, 34f)\n            verticalLineToRelative(80f)\n            quadToRelative(0f, 19f, -11f, 34f)\n            reflectiveQuadToRelative(-29f, 22f)\n            verticalLineToRelative(404f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(680f, 920f)\n            lineTo(280f, 920f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MobileVibrate.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MobileVibrate: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.MobileVibrate\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(320f, 840f)\n            quadTo(287f, 840f, 263.5f, 816.5f)\n            quadTo(240f, 793f, 240f, 760f)\n            lineTo(240f, 200f)\n            quadTo(240f, 167f, 263.5f, 143.5f)\n            quadTo(287f, 120f, 320f, 120f)\n            lineTo(640f, 120f)\n            quadTo(673f, 120f, 696.5f, 143.5f)\n            quadTo(720f, 167f, 720f, 200f)\n            lineTo(720f, 760f)\n            quadTo(720f, 793f, 696.5f, 816.5f)\n            quadTo(673f, 840f, 640f, 840f)\n            lineTo(320f, 840f)\n            close()\n            moveTo(640f, 760f)\n            lineTo(640f, 200f)\n            quadTo(640f, 200f, 640f, 200f)\n            quadTo(640f, 200f, 640f, 200f)\n            lineTo(320f, 200f)\n            quadTo(320f, 200f, 320f, 200f)\n            quadTo(320f, 200f, 320f, 200f)\n            lineTo(320f, 760f)\n            quadTo(320f, 760f, 320f, 760f)\n            quadTo(320f, 760f, 320f, 760f)\n            lineTo(640f, 760f)\n            quadTo(640f, 760f, 640f, 760f)\n            quadTo(640f, 760f, 640f, 760f)\n            close()\n            moveTo(480f, 320f)\n            quadTo(497f, 320f, 508.5f, 308.5f)\n            quadTo(520f, 297f, 520f, 280f)\n            quadTo(520f, 263f, 508.5f, 251.5f)\n            quadTo(497f, 240f, 480f, 240f)\n            quadTo(463f, 240f, 451.5f, 251.5f)\n            quadTo(440f, 263f, 440f, 280f)\n            quadTo(440f, 297f, 451.5f, 308.5f)\n            quadTo(463f, 320f, 480f, 320f)\n            close()\n            moveTo(0f, 600f)\n            lineTo(0f, 360f)\n            lineTo(80f, 360f)\n            lineTo(80f, 600f)\n            lineTo(0f, 600f)\n            close()\n            moveTo(120f, 680f)\n            lineTo(120f, 280f)\n            lineTo(200f, 280f)\n            lineTo(200f, 680f)\n            lineTo(120f, 680f)\n            close()\n            moveTo(880f, 600f)\n            lineTo(880f, 360f)\n            lineTo(960f, 360f)\n            lineTo(960f, 600f)\n            lineTo(880f, 600f)\n            close()\n            moveTo(760f, 680f)\n            lineTo(760f, 280f)\n            lineTo(840f, 280f)\n            lineTo(840f, 680f)\n            lineTo(760f, 680f)\n            close()\n            moveTo(320f, 760f)\n            quadTo(320f, 760f, 320f, 760f)\n            quadTo(320f, 760f, 320f, 760f)\n            lineTo(320f, 760f)\n            quadTo(320f, 760f, 320f, 760f)\n            quadTo(320f, 760f, 320f, 760f)\n            lineTo(320f, 200f)\n            quadTo(320f, 200f, 320f, 200f)\n            quadTo(320f, 200f, 320f, 200f)\n            lineTo(320f, 200f)\n            quadTo(320f, 200f, 320f, 200f)\n            quadTo(320f, 200f, 320f, 200f)\n            lineTo(320f, 760f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.MobileVibrate: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.MobileVibrate\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(320f, 840f)\n            quadTo(287f, 840f, 263.5f, 816.5f)\n            quadTo(240f, 793f, 240f, 760f)\n            lineTo(240f, 200f)\n            quadTo(240f, 167f, 263.5f, 143.5f)\n            quadTo(287f, 120f, 320f, 120f)\n            lineTo(640f, 120f)\n            quadTo(673f, 120f, 696.5f, 143.5f)\n            quadTo(720f, 167f, 720f, 200f)\n            lineTo(720f, 760f)\n            quadTo(720f, 793f, 696.5f, 816.5f)\n            quadTo(673f, 840f, 640f, 840f)\n            lineTo(320f, 840f)\n            close()\n            moveTo(480f, 320f)\n            quadTo(497f, 320f, 508.5f, 308.5f)\n            quadTo(520f, 297f, 520f, 280f)\n            quadTo(520f, 263f, 508.5f, 251.5f)\n            quadTo(497f, 240f, 480f, 240f)\n            quadTo(463f, 240f, 451.5f, 251.5f)\n            quadTo(440f, 263f, 440f, 280f)\n            quadTo(440f, 297f, 451.5f, 308.5f)\n            quadTo(463f, 320f, 480f, 320f)\n            close()\n            moveTo(0f, 600f)\n            lineTo(0f, 360f)\n            lineTo(80f, 360f)\n            lineTo(80f, 600f)\n            lineTo(0f, 600f)\n            close()\n            moveTo(120f, 680f)\n            lineTo(120f, 280f)\n            lineTo(200f, 280f)\n            lineTo(200f, 680f)\n            lineTo(120f, 680f)\n            close()\n            moveTo(880f, 600f)\n            lineTo(880f, 360f)\n            lineTo(960f, 360f)\n            lineTo(960f, 600f)\n            lineTo(880f, 600f)\n            close()\n            moveTo(760f, 680f)\n            lineTo(760f, 280f)\n            lineTo(840f, 280f)\n            lineTo(840f, 680f)\n            lineTo(760f, 680f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Mop.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Mop: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Mop\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(142f, 840f)\n            lineTo(240f, 840f)\n            lineTo(240f, 760f)\n            quadTo(240f, 743f, 251.5f, 731.5f)\n            quadTo(263f, 720f, 280f, 720f)\n            quadTo(297f, 720f, 308.5f, 731.5f)\n            quadTo(320f, 743f, 320f, 760f)\n            lineTo(320f, 840f)\n            lineTo(440f, 840f)\n            lineTo(440f, 760f)\n            quadTo(440f, 743f, 451.5f, 731.5f)\n            quadTo(463f, 720f, 480f, 720f)\n            quadTo(497f, 720f, 508.5f, 731.5f)\n            quadTo(520f, 743f, 520f, 760f)\n            lineTo(520f, 840f)\n            lineTo(640f, 840f)\n            lineTo(640f, 760f)\n            quadTo(640f, 743f, 651.5f, 731.5f)\n            quadTo(663f, 720f, 680f, 720f)\n            quadTo(697f, 720f, 708.5f, 731.5f)\n            quadTo(720f, 743f, 720f, 760f)\n            lineTo(720f, 840f)\n            lineTo(818f, 840f)\n            quadTo(818f, 840f, 818f, 840f)\n            quadTo(818f, 840f, 818f, 840f)\n            lineTo(778f, 680f)\n            lineTo(182f, 680f)\n            lineTo(142f, 840f)\n            quadTo(142f, 840f, 142f, 840f)\n            quadTo(142f, 840f, 142f, 840f)\n            close()\n            moveTo(818f, 920f)\n            lineTo(142f, 920f)\n            quadTo(103f, 920f, 79f, 889f)\n            quadTo(55f, 858f, 65f, 820f)\n            lineTo(120f, 600f)\n            lineTo(120f, 520f)\n            quadTo(120f, 487f, 143.5f, 463.5f)\n            quadTo(167f, 440f, 200f, 440f)\n            lineTo(360f, 440f)\n            lineTo(360f, 160f)\n            quadTo(360f, 110f, 395f, 75f)\n            quadTo(430f, 40f, 480f, 40f)\n            quadTo(530f, 40f, 565f, 75f)\n            quadTo(600f, 110f, 600f, 160f)\n            lineTo(600f, 440f)\n            lineTo(760f, 440f)\n            quadTo(793f, 440f, 816.5f, 463.5f)\n            quadTo(840f, 487f, 840f, 520f)\n            lineTo(840f, 600f)\n            lineTo(895f, 820f)\n            quadTo(908f, 858f, 883.5f, 889f)\n            quadTo(859f, 920f, 818f, 920f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MultipleImageEdit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.MultipleImageEdit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"Outlined.MultipleImageEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 6.5f)\n            curveToRelative(0f, -0.417f, 0.146f, -0.771f, 0.438f, -1.063f)\n            curveToRelative(0.292f, -0.292f, 0.646f, -0.438f, 1.063f, -0.438f)\n            horizontalLineToRelative(9f)\n            curveToRelative(0.417f, 0f, 0.771f, 0.146f, 1.063f, 0.438f)\n            reflectiveCurveToRelative(0.438f, 0.646f, 0.438f, 1.063f)\n            horizontalLineTo(6f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 3.5f)\n            curveToRelative(0f, -0.417f, 0.146f, -0.771f, 0.438f, -1.063f)\n            reflectiveCurveToRelative(0.646f, -0.438f, 1.063f, -0.438f)\n            horizontalLineToRelative(7f)\n            curveToRelative(0.417f, 0f, 0.771f, 0.146f, 1.063f, 0.438f)\n            reflectiveCurveToRelative(0.438f, 0.646f, 0.438f, 1.063f)\n            horizontalLineTo(7f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.615f, 16.463f)\n            curveToRelative(-0.062f, -0.151f, -0.148f, -0.288f, -0.257f, -0.412f)\n            lineToRelative(-0.762f, -0.762f)\n            curveToRelative(-0.124f, -0.124f, -0.261f, -0.216f, -0.412f, -0.278f)\n            reflectiveCurveToRelative(-0.309f, -0.093f, -0.474f, -0.093f)\n            curveToRelative(-0.151f, 0f, -0.302f, 0.027f, -0.453f, 0.082f)\n            reflectiveCurveToRelative(-0.288f, 0.144f, -0.412f, 0.268f)\n            lineToRelative(-4.552f, 4.531f)\n            verticalLineToRelative(2.533f)\n            horizontalLineToRelative(2.533f)\n            lineToRelative(4.531f, -4.531f)\n            curveToRelative(0.124f, -0.124f, 0.213f, -0.264f, 0.268f, -0.422f)\n            curveToRelative(0.055f, -0.158f, 0.082f, -0.312f, 0.082f, -0.463f)\n            reflectiveCurveToRelative(-0.031f, -0.302f, -0.093f, -0.453f)\n            close()\n            moveTo(15.311f, 21.097f)\n            horizontalLineToRelative(-0.783f)\n            verticalLineToRelative(-0.783f)\n            lineToRelative(2.513f, -2.492f)\n            lineToRelative(0.391f, 0.371f)\n            lineToRelative(0.371f, 0.391f)\n            lineToRelative(-2.492f, 2.513f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.412f, 8.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(7f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(10f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(4.801f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-4.801f)\n            verticalLineToRelative(-10f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(3.642f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-3.642f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.93f, 15.73f)\n            lineToRelative(-1.387f, -1.849f)\n            lineToRelative(-1.875f, 2.5f)\n            lineToRelative(-1.375f, -1.825f)\n            lineToRelative(-2.125f, 2.825f)\n            lineToRelative(5.111f, 0f)\n            lineToRelative(1.651f, -1.651f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.MultipleImageEdit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"TwoTone.MultipleImageEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 6.5f)\n            curveToRelative(0f, -0.417f, 0.146f, -0.771f, 0.438f, -1.063f)\n            curveToRelative(0.292f, -0.292f, 0.646f, -0.438f, 1.063f, -0.438f)\n            horizontalLineToRelative(9f)\n            curveToRelative(0.417f, 0f, 0.771f, 0.146f, 1.063f, 0.438f)\n            reflectiveCurveToRelative(0.438f, 0.646f, 0.438f, 1.063f)\n            horizontalLineTo(6f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7f, 3.5f)\n            curveToRelative(0f, -0.417f, 0.146f, -0.771f, 0.438f, -1.063f)\n            reflectiveCurveToRelative(0.646f, -0.438f, 1.063f, -0.438f)\n            horizontalLineToRelative(7f)\n            curveToRelative(0.417f, 0f, 0.771f, 0.146f, 1.063f, 0.438f)\n            reflectiveCurveToRelative(0.438f, 0.646f, 0.438f, 1.063f)\n            horizontalLineTo(7f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.615f, 16.463f)\n            curveToRelative(-0.062f, -0.151f, -0.148f, -0.288f, -0.257f, -0.412f)\n            lineToRelative(-0.762f, -0.762f)\n            curveToRelative(-0.124f, -0.124f, -0.261f, -0.216f, -0.412f, -0.278f)\n            reflectiveCurveToRelative(-0.309f, -0.093f, -0.474f, -0.093f)\n            curveToRelative(-0.151f, 0f, -0.302f, 0.027f, -0.453f, 0.082f)\n            reflectiveCurveToRelative(-0.288f, 0.144f, -0.412f, 0.268f)\n            lineToRelative(-4.552f, 4.531f)\n            verticalLineToRelative(2.533f)\n            horizontalLineToRelative(2.533f)\n            lineToRelative(4.531f, -4.531f)\n            curveToRelative(0.124f, -0.124f, 0.213f, -0.264f, 0.268f, -0.422f)\n            curveToRelative(0.055f, -0.158f, 0.082f, -0.312f, 0.082f, -0.463f)\n            reflectiveCurveToRelative(-0.031f, -0.302f, -0.093f, -0.453f)\n            close()\n            moveTo(15.311f, 21.097f)\n            horizontalLineToRelative(-0.783f)\n            verticalLineToRelative(-0.783f)\n            lineToRelative(2.513f, -2.492f)\n            lineToRelative(0.391f, 0.371f)\n            lineToRelative(0.371f, 0.391f)\n            lineToRelative(-2.492f, 2.513f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.412f, 8.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(7f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(10f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(4.801f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-4.801f)\n            verticalLineToRelative(-10f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(3.642f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-3.642f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.93f, 15.73f)\n            lineToRelative(-1.387f, -1.849f)\n            lineToRelative(-1.875f, 2.5f)\n            lineToRelative(-1.375f, -1.825f)\n            lineToRelative(-2.125f, 2.825f)\n            lineToRelative(5.111f, 0f)\n            lineToRelative(1.651f, -1.651f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(11.801f, 18.862f)\n            lineToRelative(0.007f, 0f)\n            lineToRelative(-0.005f, -0.005f)\n            lineToRelative(5.195f, -5.195f)\n            lineToRelative(0.002f, 0.002f)\n            lineToRelative(0f, -0.002f)\n            lineToRelative(0f, -3.662f)\n            lineToRelative(-10f, 0f)\n            lineToRelative(0f, 10f)\n            lineToRelative(4.801f, 0f)\n            lineToRelative(0f, -1.138f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(13.628f, 20.412f)\n            lineToRelative(4.057f, -4.057f)\n            lineToRelative(1.49f, 1.49f)\n            lineToRelative(-4.057f, 4.057f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/MusicAdd.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.MusicAdd: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.MusicAdd\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(17f, 9f)\n            verticalLineTo(12f)\n            horizontalLineTo(14f)\n            verticalLineTo(14f)\n            horizontalLineTo(17f)\n            verticalLineTo(17f)\n            horizontalLineTo(19f)\n            verticalLineTo(14f)\n            horizontalLineTo(22f)\n            verticalLineTo(12f)\n            horizontalLineTo(19f)\n            verticalLineTo(9f)\n            horizontalLineTo(17f)\n            moveTo(9f, 3f)\n            verticalLineTo(13.55f)\n            curveTo(8.41f, 13.21f, 7.73f, 13f, 7f, 13f)\n            curveTo(4.79f, 13f, 3f, 14.79f, 3f, 17f)\n            reflectiveCurveTo(4.79f, 21f, 7f, 21f)\n            reflectiveCurveTo(11f, 19.21f, 11f, 17f)\n            verticalLineTo(7f)\n            horizontalLineTo(15f)\n            verticalLineTo(3f)\n            horizontalLineTo(9f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/NeonBrush.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.NeonBrush: ImageVector by lazy {\n    Builder(\n        name = \"NeonBrush\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19.443f, 6.414f)\n            lineToRelative(-1.858f, -1.858f)\n            curveToRelative(-0.354f, -0.354f, -0.774f, -0.531f, -1.261f, -0.531f)\n            curveToRelative(-0.487f, 0f, -0.907f, 0.177f, -1.261f, 0.531f)\n            lineTo(4.927f, 14.694f)\n            lineToRelative(-0.876f, 4.22f)\n            curveToRelative(-0.071f, 0.301f, 0.009f, 0.566f, 0.239f, 0.796f)\n            curveToRelative(0.23f, 0.23f, 0.495f, 0.31f, 0.796f, 0.239f)\n            lineToRelative(4.22f, -0.876f)\n            lineTo(19.443f, 8.936f)\n            curveToRelative(0.354f, -0.354f, 0.531f, -0.774f, 0.531f, -1.261f)\n            curveTo(19.974f, 7.188f, 19.797f, 6.768f, 19.443f, 6.414f)\n            close()\n            moveTo(8.801f, 16.579f)\n            lineToRelative(-1.38f, -1.38f)\n            lineToRelative(8.89f, -8.89f)\n            lineToRelative(1.38f, 1.38f)\n            lineTo(8.801f, 16.579f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = SolidColor(Color(0xFF000000)),\n            strokeAlpha = 0.3f,\n            strokeLineWidth = 6f\n        ) {\n            moveTo(19.443f, 6.415f)\n            lineToRelative(-1.858f, -1.858f)\n            curveToRelative(-0.354f, -0.354f, -0.774f, -0.531f, -1.261f, -0.531f)\n            reflectiveCurveToRelative(-0.907f, 0.177f, -1.261f, 0.531f)\n            lineTo(5.04f, 14.581f)\n            curveToRelative(-0.074f, 0.074f, -0.124f, 0.168f, -0.146f, 0.27f)\n            lineToRelative(-0.843f, 4.063f)\n            curveToRelative(-0.071f, 0.301f, 0.009f, 0.566f, 0.239f, 0.796f)\n            curveToRelative(0.23f, 0.23f, 0.495f, 0.31f, 0.796f, 0.239f)\n            lineToRelative(4.063f, -0.843f)\n            curveToRelative(0.102f, -0.021f, 0.196f, -0.072f, 0.27f, -0.146f)\n            lineTo(19.443f, 8.936f)\n            curveToRelative(0.354f, -0.354f, 0.531f, -0.774f, 0.531f, -1.261f)\n            curveTo(19.974f, 7.188f, 19.797f, 6.768f, 19.443f, 6.415f)\n            close()\n            moveTo(18.698f, 9.026f)\n            lineToRelative(-8.888f, 8.888f)\n            curveTo(9.178f, 18.546f, 8.153f, 18.546f, 7.521f, 17.914f)\n            horizontalLineTo(7.521f)\n            curveToRelative(-0.154f, -0.006f, -0.308f, -0.009f, -0.459f, -0.047f)\n            curveToRelative(-0.285f, -0.072f, -0.569f, -0.226f, -0.777f, -0.435f)\n            curveToRelative(-0.29f, -0.293f, -0.397f, -0.639f, -0.444f, -1.036f)\n            curveToRelative(-0.007f, -0.055f, -0.001f, -0.11f, -0.004f, -0.165f)\n            lineToRelative(-0.055f, -0.055f)\n            curveToRelative(-0.423f, -0.423f, -0.423f, -1.109f, 0f, -1.532f)\n            lineToRelative(9.267f, -9.267f)\n            curveToRelative(0.632f, -0.632f, 1.657f, -0.632f, 2.289f, 0f)\n            lineToRelative(1.36f, 1.36f)\n            curveTo(19.33f, 7.369f, 19.33f, 8.394f, 18.698f, 9.026f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Neurology.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Neurology: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Neurology\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(390f, 840f)\n            quadToRelative(-51f, 0f, -88f, -35.5f)\n            reflectiveQuadTo(260f, 719f)\n            quadToRelative(-60f, -8f, -100f, -53f)\n            reflectiveQuadToRelative(-40f, -106f)\n            quadToRelative(0f, -21f, 5.5f, -41.5f)\n            reflectiveQuadTo(142f, 480f)\n            quadToRelative(-11f, -18f, -16.5f, -38f)\n            reflectiveQuadToRelative(-5.5f, -42f)\n            quadToRelative(0f, -61f, 40f, -105.5f)\n            reflectiveQuadToRelative(99f, -52.5f)\n            quadToRelative(3f, -51f, 41f, -86.5f)\n            reflectiveQuadToRelative(90f, -35.5f)\n            quadToRelative(26f, 0f, 48.5f, 10f)\n            reflectiveQuadToRelative(41.5f, 27f)\n            quadToRelative(18f, -17f, 41f, -27f)\n            reflectiveQuadToRelative(49f, -10f)\n            quadToRelative(52f, 0f, 89.5f, 35f)\n            reflectiveQuadToRelative(40.5f, 86f)\n            quadToRelative(59f, 8f, 99.5f, 53f)\n            reflectiveQuadTo(840f, 400f)\n            quadToRelative(0f, 22f, -5.5f, 42f)\n            reflectiveQuadTo(818f, 480f)\n            quadToRelative(11f, 18f, 16.5f, 38.5f)\n            reflectiveQuadTo(840f, 560f)\n            quadToRelative(0f, 62f, -40.5f, 106.5f)\n            reflectiveQuadTo(699f, 719f)\n            quadToRelative(-5f, 50f, -41.5f, 85.5f)\n            reflectiveQuadTo(570f, 840f)\n            quadToRelative(-25f, 0f, -48.5f, -9.5f)\n            reflectiveQuadTo(480f, 804f)\n            quadToRelative(-19f, 17f, -42f, 26.5f)\n            reflectiveQuadToRelative(-48f, 9.5f)\n            close()\n            moveTo(520f, 250f)\n            verticalLineToRelative(460f)\n            quadToRelative(0f, 21f, 14.5f, 35.5f)\n            reflectiveQuadTo(570f, 760f)\n            quadToRelative(20f, 0f, 34.5f, -16f)\n            reflectiveQuadToRelative(15.5f, -36f)\n            quadToRelative(-21f, -8f, -38.5f, -21.5f)\n            reflectiveQuadTo(550f, 654f)\n            quadToRelative(-10f, -14f, -7.5f, -30f)\n            reflectiveQuadToRelative(16.5f, -26f)\n            quadToRelative(14f, -10f, 30f, -7.5f)\n            reflectiveQuadToRelative(26f, 16.5f)\n            quadToRelative(11f, 16f, 28f, 24.5f)\n            reflectiveQuadToRelative(37f, 8.5f)\n            quadToRelative(33f, 0f, 56.5f, -23.5f)\n            reflectiveQuadTo(760f, 560f)\n            quadToRelative(0f, -5f, -0.5f, -10f)\n            reflectiveQuadToRelative(-2.5f, -10f)\n            quadToRelative(-17f, 10f, -36.5f, 15f)\n            reflectiveQuadToRelative(-40.5f, 5f)\n            quadToRelative(-17f, 0f, -28.5f, -11.5f)\n            reflectiveQuadTo(640f, 520f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(680f, 480f)\n            quadToRelative(33f, 0f, 56.5f, -23.5f)\n            reflectiveQuadTo(760f, 400f)\n            quadToRelative(0f, -33f, -23.5f, -56f)\n            reflectiveQuadTo(680f, 320f)\n            quadToRelative(-11f, 18f, -28.5f, 31.5f)\n            reflectiveQuadTo(613f, 373f)\n            quadToRelative(-16f, 6f, -31f, -1f)\n            reflectiveQuadToRelative(-20f, -23f)\n            quadToRelative(-5f, -16f, 1.5f, -31f)\n            reflectiveQuadToRelative(22.5f, -20f)\n            quadToRelative(15f, -5f, 24.5f, -18f)\n            reflectiveQuadToRelative(9.5f, -30f)\n            quadToRelative(0f, -21f, -14.5f, -35.5f)\n            reflectiveQuadTo(570f, 200f)\n            quadToRelative(-21f, 0f, -35.5f, 14.5f)\n            reflectiveQuadTo(520f, 250f)\n            close()\n            moveTo(440f, 710f)\n            verticalLineToRelative(-460f)\n            quadToRelative(0f, -21f, -14.5f, -35.5f)\n            reflectiveQuadTo(390f, 200f)\n            quadToRelative(-21f, 0f, -35.5f, 14.5f)\n            reflectiveQuadTo(340f, 250f)\n            quadToRelative(0f, 16f, 9f, 29.5f)\n            reflectiveQuadToRelative(24f, 18.5f)\n            quadToRelative(16f, 5f, 23f, 20f)\n            reflectiveQuadToRelative(2f, 31f)\n            quadToRelative(-6f, 16f, -21f, 23f)\n            reflectiveQuadToRelative(-31f, 1f)\n            quadToRelative(-21f, -8f, -38.5f, -21.5f)\n            reflectiveQuadTo(279f, 320f)\n            quadToRelative(-32f, 1f, -55.5f, 24.5f)\n            reflectiveQuadTo(200f, 400f)\n            quadToRelative(0f, 33f, 23.5f, 56.5f)\n            reflectiveQuadTo(280f, 480f)\n            quadToRelative(17f, 0f, 28.5f, 11.5f)\n            reflectiveQuadTo(320f, 520f)\n            quadToRelative(0f, 17f, -11.5f, 28.5f)\n            reflectiveQuadTo(280f, 560f)\n            quadToRelative(-21f, 0f, -40.5f, -5f)\n            reflectiveQuadTo(203f, 540f)\n            quadToRelative(-2f, 5f, -2.5f, 10f)\n            reflectiveQuadToRelative(-0.5f, 10f)\n            quadToRelative(0f, 33f, 23.5f, 56.5f)\n            reflectiveQuadTo(280f, 640f)\n            quadToRelative(20f, 0f, 37f, -8.5f)\n            reflectiveQuadToRelative(28f, -24.5f)\n            quadToRelative(10f, -14f, 26f, -16.5f)\n            reflectiveQuadToRelative(30f, 7.5f)\n            quadToRelative(14f, 10f, 16.5f, 26f)\n            reflectiveQuadToRelative(-7.5f, 30f)\n            quadToRelative(-14f, 19f, -32f, 33f)\n            reflectiveQuadToRelative(-39f, 22f)\n            quadToRelative(1f, 20f, 16f, 35.5f)\n            reflectiveQuadToRelative(35f, 15.5f)\n            quadToRelative(21f, 0f, 35.5f, -14.5f)\n            reflectiveQuadTo(440f, 710f)\n            close()\n            moveTo(480f, 480f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Neurology: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Neurology\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(13f, 6.25f)\n            verticalLineToRelative(11.5f)\n            curveToRelative(0f, 0.35f, 0.121f, 0.646f, 0.363f, 0.887f)\n            reflectiveCurveToRelative(0.538f, 0.363f, 0.887f, 0.363f)\n            curveToRelative(0.333f, 0f, 0.621f, -0.133f, 0.863f, -0.4f)\n            reflectiveCurveToRelative(0.371f, -0.567f, 0.387f, -0.9f)\n            curveToRelative(-0.35f, -0.133f, -0.671f, -0.313f, -0.962f, -0.538f)\n            reflectiveCurveToRelative(-0.554f, -0.496f, -0.788f, -0.813f)\n            curveToRelative(-0.167f, -0.233f, -0.229f, -0.483f, -0.188f, -0.75f)\n            reflectiveCurveToRelative(0.179f, -0.483f, 0.412f, -0.65f)\n            reflectiveCurveToRelative(0.483f, -0.229f, 0.75f, -0.188f)\n            reflectiveCurveToRelative(0.483f, 0.179f, 0.65f, 0.412f)\n            curveToRelative(0.183f, 0.267f, 0.417f, 0.471f, 0.7f, 0.613f)\n            reflectiveCurveToRelative(0.592f, 0.213f, 0.925f, 0.213f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.587f)\n            reflectiveCurveToRelative(0.587f, -0.863f, 0.587f, -1.413f)\n            curveToRelative(0f, -0.083f, -0.004f, -0.167f, -0.013f, -0.25f)\n            reflectiveCurveToRelative(-0.029f, -0.167f, -0.063f, -0.25f)\n            curveToRelative(-0.283f, 0.167f, -0.587f, 0.292f, -0.913f, 0.375f)\n            reflectiveCurveToRelative(-0.663f, 0.125f, -1.013f, 0.125f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.587f)\n            curveToRelative(0.392f, -0.392f, 0.587f, -0.863f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.196f, -1.017f, -0.587f, -1.4f)\n            reflectiveCurveToRelative(-0.863f, -0.583f, -1.413f, -0.6f)\n            curveToRelative(-0.183f, 0.3f, -0.421f, 0.563f, -0.712f, 0.788f)\n            reflectiveCurveToRelative(-0.613f, 0.404f, -0.962f, 0.538f)\n            curveToRelative(-0.267f, 0.1f, -0.525f, 0.092f, -0.775f, -0.025f)\n            reflectiveCurveToRelative(-0.417f, -0.308f, -0.5f, -0.575f)\n            reflectiveCurveToRelative(-0.071f, -0.525f, 0.038f, -0.775f)\n            reflectiveCurveToRelative(0.296f, -0.417f, 0.563f, -0.5f)\n            curveToRelative(0.25f, -0.083f, 0.454f, -0.233f, 0.613f, -0.45f)\n            reflectiveCurveToRelative(0.237f, -0.467f, 0.237f, -0.75f)\n            curveToRelative(0f, -0.35f, -0.121f, -0.646f, -0.363f, -0.887f)\n            reflectiveCurveToRelative(-0.538f, -0.363f, -0.887f, -0.363f)\n            reflectiveCurveToRelative(-0.646f, 0.121f, -0.887f, 0.363f)\n            reflectiveCurveToRelative(-0.363f, 0.538f, -0.363f, 0.887f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(11f, 17.75f)\n            verticalLineTo(6.25f)\n            curveToRelative(0f, -0.35f, -0.121f, -0.646f, -0.363f, -0.887f)\n            reflectiveCurveToRelative(-0.538f, -0.363f, -0.887f, -0.363f)\n            reflectiveCurveToRelative(-0.646f, 0.121f, -0.887f, 0.363f)\n            reflectiveCurveToRelative(-0.363f, 0.538f, -0.363f, 0.887f)\n            curveToRelative(0f, 0.267f, 0.075f, 0.512f, 0.225f, 0.738f)\n            reflectiveCurveToRelative(0.35f, 0.379f, 0.6f, 0.463f)\n            curveToRelative(0.267f, 0.083f, 0.458f, 0.25f, 0.575f, 0.5f)\n            reflectiveCurveToRelative(0.133f, 0.508f, 0.05f, 0.775f)\n            curveToRelative(-0.1f, 0.267f, -0.275f, 0.458f, -0.525f, 0.575f)\n            reflectiveCurveToRelative(-0.508f, 0.125f, -0.775f, 0.025f)\n            curveToRelative(-0.35f, -0.133f, -0.671f, -0.313f, -0.962f, -0.538f)\n            reflectiveCurveToRelative(-0.529f, -0.488f, -0.712f, -0.788f)\n            curveToRelative(-0.533f, 0.017f, -0.996f, 0.221f, -1.388f, 0.613f)\n            reflectiveCurveToRelative(-0.587f, 0.854f, -0.587f, 1.388f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.587f, 1.413f)\n            curveToRelative(0.392f, 0.392f, 0.863f, 0.587f, 1.413f, 0.587f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            curveToRelative(-0.35f, 0f, -0.688f, -0.042f, -1.013f, -0.125f)\n            reflectiveCurveToRelative(-0.629f, -0.208f, -0.913f, -0.375f)\n            curveToRelative(-0.033f, 0.083f, -0.054f, 0.167f, -0.063f, 0.25f)\n            reflectiveCurveToRelative(-0.013f, 0.167f, -0.013f, 0.25f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.587f, 1.413f)\n            reflectiveCurveToRelative(0.863f, 0.587f, 1.413f, 0.587f)\n            curveToRelative(0.333f, 0f, 0.642f, -0.071f, 0.925f, -0.213f)\n            reflectiveCurveToRelative(0.517f, -0.346f, 0.7f, -0.613f)\n            curveToRelative(0.167f, -0.233f, 0.383f, -0.371f, 0.65f, -0.412f)\n            reflectiveCurveToRelative(0.517f, 0.021f, 0.75f, 0.188f)\n            reflectiveCurveToRelative(0.371f, 0.383f, 0.412f, 0.65f)\n            reflectiveCurveToRelative(-0.021f, 0.517f, -0.188f, 0.75f)\n            curveToRelative(-0.233f, 0.317f, -0.5f, 0.592f, -0.8f, 0.825f)\n            reflectiveCurveToRelative(-0.625f, 0.417f, -0.975f, 0.55f)\n            curveToRelative(0.017f, 0.333f, 0.15f, 0.629f, 0.4f, 0.887f)\n            reflectiveCurveToRelative(0.542f, 0.387f, 0.875f, 0.387f)\n            curveToRelative(0.35f, 0f, 0.646f, -0.121f, 0.887f, -0.363f)\n            reflectiveCurveToRelative(0.363f, -0.538f, 0.363f, -0.887f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.45f, 12f)\n            curveToRelative(0.183f, -0.3f, 0.321f, -0.617f, 0.412f, -0.95f)\n            curveToRelative(0.092f, -0.333f, 0.138f, -0.683f, 0.138f, -1.05f)\n            curveToRelative(0f, -1.017f, -0.338f, -1.9f, -1.013f, -2.65f)\n            reflectiveCurveToRelative(-1.504f, -1.192f, -2.487f, -1.325f)\n            curveToRelative(-0.05f, -0.85f, -0.388f, -1.567f, -1.013f, -2.15f)\n            reflectiveCurveToRelative(-1.371f, -0.875f, -2.237f, -0.875f)\n            curveToRelative(-0.433f, 0f, -0.842f, 0.083f, -1.225f, 0.25f)\n            curveToRelative(-0.383f, 0.167f, -0.725f, 0.392f, -1.025f, 0.675f)\n            curveToRelative(-0.317f, -0.283f, -0.662f, -0.508f, -1.037f, -0.675f)\n            reflectiveCurveToRelative(-0.779f, -0.25f, -1.213f, -0.25f)\n            curveToRelative(-0.867f, 0f, -1.617f, 0.296f, -2.25f, 0.888f)\n            reflectiveCurveToRelative(-0.975f, 1.313f, -1.025f, 2.162f)\n            curveToRelative(-0.983f, 0.133f, -1.808f, 0.571f, -2.475f, 1.313f)\n            curveToRelative(-0.667f, 0.742f, -1f, 1.621f, -1f, 2.638f)\n            curveToRelative(0f, 0.367f, 0.046f, 0.717f, 0.138f, 1.05f)\n            curveToRelative(0.092f, 0.333f, 0.229f, 0.65f, 0.412f, 0.95f)\n            curveToRelative(-0.183f, 0.3f, -0.321f, 0.621f, -0.412f, 0.963f)\n            curveToRelative(-0.092f, 0.342f, -0.138f, 0.688f, -0.138f, 1.037f)\n            curveToRelative(0f, 1.017f, 0.333f, 1.9f, 1f, 2.65f)\n            reflectiveCurveToRelative(1.5f, 1.192f, 2.5f, 1.325f)\n            curveToRelative(0.083f, 0.833f, 0.433f, 1.546f, 1.05f, 2.138f)\n            curveToRelative(0.617f, 0.592f, 1.35f, 0.888f, 2.2f, 0.888f)\n            curveToRelative(0.417f, 0f, 0.817f, -0.079f, 1.2f, -0.237f)\n            curveToRelative(0.383f, -0.158f, 0.733f, -0.379f, 1.05f, -0.663f)\n            curveToRelative(0.3f, 0.283f, 0.646f, 0.504f, 1.037f, 0.663f)\n            reflectiveCurveToRelative(0.796f, 0.237f, 1.213f, 0.237f)\n            curveToRelative(0.85f, 0f, 1.579f, -0.296f, 2.188f, -0.888f)\n            reflectiveCurveToRelative(0.954f, -1.304f, 1.037f, -2.138f)\n            curveToRelative(1f, -0.133f, 1.838f, -0.571f, 2.513f, -1.313f)\n            curveToRelative(0.675f, -0.742f, 1.013f, -1.629f, 1.013f, -2.662f)\n            curveToRelative(0f, -0.35f, -0.046f, -0.696f, -0.138f, -1.037f)\n            curveToRelative(-0.092f, -0.342f, -0.229f, -0.663f, -0.412f, -0.963f)\n            close()\n            moveTo(11f, 17.75f)\n            curveToRelative(0f, 0.35f, -0.121f, 0.646f, -0.362f, 0.888f)\n            curveToRelative(-0.242f, 0.242f, -0.538f, 0.362f, -0.888f, 0.362f)\n            curveToRelative(-0.333f, 0f, -0.625f, -0.129f, -0.875f, -0.388f)\n            curveToRelative(-0.25f, -0.258f, -0.383f, -0.554f, -0.4f, -0.888f)\n            curveToRelative(0.35f, -0.133f, 0.675f, -0.317f, 0.975f, -0.55f)\n            reflectiveCurveToRelative(0.567f, -0.508f, 0.8f, -0.825f)\n            curveToRelative(0.167f, -0.233f, 0.229f, -0.483f, 0.188f, -0.75f)\n            reflectiveCurveToRelative(-0.179f, -0.483f, -0.412f, -0.65f)\n            curveToRelative(-0.233f, -0.167f, -0.483f, -0.229f, -0.75f, -0.188f)\n            curveToRelative(-0.267f, 0.042f, -0.483f, 0.179f, -0.65f, 0.412f)\n            curveToRelative(-0.183f, 0.267f, -0.417f, 0.471f, -0.7f, 0.612f)\n            reflectiveCurveToRelative(-0.592f, 0.213f, -0.925f, 0.213f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.412f, -0.588f)\n            reflectiveCurveToRelative(-0.588f, -0.862f, -0.588f, -1.412f)\n            curveToRelative(0f, -0.083f, 0.004f, -0.167f, 0.013f, -0.25f)\n            curveToRelative(0.008f, -0.083f, 0.029f, -0.167f, 0.063f, -0.25f)\n            curveToRelative(0.283f, 0.167f, 0.587f, 0.292f, 0.912f, 0.375f)\n            reflectiveCurveToRelative(0.663f, 0.125f, 1.013f, 0.125f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.713f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.412f, -0.588f)\n            reflectiveCurveToRelative(-0.588f, -0.862f, -0.588f, -1.412f)\n            curveToRelative(0f, -0.533f, 0.196f, -0.996f, 0.588f, -1.388f)\n            reflectiveCurveToRelative(0.854f, -0.596f, 1.387f, -0.612f)\n            curveToRelative(0.183f, 0.3f, 0.421f, 0.563f, 0.713f, 0.787f)\n            curveToRelative(0.292f, 0.225f, 0.612f, 0.404f, 0.963f, 0.538f)\n            curveToRelative(0.267f, 0.1f, 0.525f, 0.092f, 0.775f, -0.025f)\n            curveToRelative(0.25f, -0.117f, 0.425f, -0.308f, 0.525f, -0.575f)\n            curveToRelative(0.083f, -0.267f, 0.067f, -0.525f, -0.05f, -0.775f)\n            curveToRelative(-0.117f, -0.25f, -0.308f, -0.417f, -0.575f, -0.5f)\n            curveToRelative(-0.25f, -0.083f, -0.45f, -0.237f, -0.6f, -0.463f)\n            curveToRelative(-0.15f, -0.225f, -0.225f, -0.471f, -0.225f, -0.737f)\n            curveToRelative(0f, -0.35f, 0.121f, -0.646f, 0.362f, -0.888f)\n            curveToRelative(0.242f, -0.242f, 0.538f, -0.362f, 0.888f, -0.362f)\n            reflectiveCurveToRelative(0.646f, 0.121f, 0.888f, 0.362f)\n            curveToRelative(0.242f, 0.242f, 0.362f, 0.538f, 0.362f, 0.888f)\n            verticalLineToRelative(11.5f)\n            close()\n            moveTo(16.287f, 13.713f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.713f, 0.287f)\n            curveToRelative(0.35f, 0f, 0.688f, -0.042f, 1.013f, -0.125f)\n            reflectiveCurveToRelative(0.629f, -0.208f, 0.912f, -0.375f)\n            curveToRelative(0.033f, 0.083f, 0.054f, 0.167f, 0.063f, 0.25f)\n            curveToRelative(0.008f, 0.083f, 0.013f, 0.167f, 0.013f, 0.25f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.588f, 1.412f)\n            reflectiveCurveToRelative(-0.862f, 0.588f, -1.412f, 0.588f)\n            curveToRelative(-0.333f, 0f, -0.642f, -0.071f, -0.925f, -0.213f)\n            reflectiveCurveToRelative(-0.517f, -0.346f, -0.7f, -0.612f)\n            curveToRelative(-0.167f, -0.233f, -0.383f, -0.371f, -0.65f, -0.412f)\n            curveToRelative(-0.267f, -0.042f, -0.517f, 0.021f, -0.75f, 0.188f)\n            curveToRelative(-0.233f, 0.167f, -0.371f, 0.383f, -0.412f, 0.65f)\n            reflectiveCurveToRelative(0.021f, 0.517f, 0.188f, 0.75f)\n            curveToRelative(0.233f, 0.317f, 0.496f, 0.588f, 0.787f, 0.813f)\n            curveToRelative(0.292f, 0.225f, 0.613f, 0.404f, 0.963f, 0.538f)\n            curveToRelative(-0.017f, 0.333f, -0.146f, 0.633f, -0.388f, 0.9f)\n            curveToRelative(-0.242f, 0.267f, -0.529f, 0.4f, -0.862f, 0.4f)\n            curveToRelative(-0.35f, 0f, -0.646f, -0.121f, -0.888f, -0.362f)\n            curveToRelative(-0.242f, -0.242f, -0.362f, -0.538f, -0.362f, -0.888f)\n            verticalLineTo(6.25f)\n            curveToRelative(0f, -0.35f, 0.121f, -0.646f, 0.362f, -0.888f)\n            curveToRelative(0.242f, -0.242f, 0.538f, -0.362f, 0.888f, -0.362f)\n            reflectiveCurveToRelative(0.646f, 0.121f, 0.888f, 0.362f)\n            curveToRelative(0.242f, 0.242f, 0.362f, 0.538f, 0.362f, 0.888f)\n            curveToRelative(0f, 0.283f, -0.079f, 0.533f, -0.237f, 0.75f)\n            reflectiveCurveToRelative(-0.362f, 0.367f, -0.612f, 0.45f)\n            curveToRelative(-0.267f, 0.083f, -0.454f, 0.25f, -0.563f, 0.5f)\n            reflectiveCurveToRelative(-0.121f, 0.508f, -0.038f, 0.775f)\n            curveToRelative(0.083f, 0.267f, 0.25f, 0.458f, 0.5f, 0.575f)\n            curveToRelative(0.25f, 0.117f, 0.508f, 0.125f, 0.775f, 0.025f)\n            curveToRelative(0.35f, -0.133f, 0.671f, -0.313f, 0.962f, -0.538f)\n            curveToRelative(0.292f, -0.225f, 0.529f, -0.487f, 0.713f, -0.787f)\n            curveToRelative(0.55f, 0.017f, 1.021f, 0.217f, 1.412f, 0.6f)\n            curveToRelative(0.392f, 0.383f, 0.588f, 0.85f, 0.588f, 1.4f)\n            reflectiveCurveToRelative(-0.196f, 1.021f, -0.588f, 1.412f)\n            reflectiveCurveToRelative(-0.862f, 0.588f, -1.412f, 0.588f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.713f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.713f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.713f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/NextPlan.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.NextPlan: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.NextPlan\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f,\n        autoMirror = true\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(240f, 560f)\n            lineTo(320f, 560f)\n            quadTo(320f, 501f, 363f, 460.5f)\n            quadTo(406f, 420f, 466f, 420f)\n            quadTo(502f, 420f, 533f, 436.5f)\n            quadTo(564f, 453f, 584f, 480f)\n            lineTo(520f, 480f)\n            lineTo(520f, 560f)\n            lineTo(720f, 560f)\n            lineTo(720f, 360f)\n            lineTo(640f, 360f)\n            lineTo(640f, 422f)\n            quadTo(608f, 384f, 563.5f, 362f)\n            quadTo(519f, 340f, 466f, 340f)\n            quadTo(371f, 340f, 305.5f, 404f)\n            quadTo(240f, 468f, 240f, 560f)\n            close()\n            moveTo(480f, 880f)\n            quadTo(397f, 880f, 324f, 848.5f)\n            quadTo(251f, 817f, 197f, 763f)\n            quadTo(143f, 709f, 111.5f, 636f)\n            quadTo(80f, 563f, 80f, 480f)\n            quadTo(80f, 397f, 111.5f, 324f)\n            quadTo(143f, 251f, 197f, 197f)\n            quadTo(251f, 143f, 324f, 111.5f)\n            quadTo(397f, 80f, 480f, 80f)\n            quadTo(563f, 80f, 636f, 111.5f)\n            quadTo(709f, 143f, 763f, 197f)\n            quadTo(817f, 251f, 848.5f, 324f)\n            quadTo(880f, 397f, 880f, 480f)\n            quadTo(880f, 563f, 848.5f, 636f)\n            quadTo(817f, 709f, 763f, 763f)\n            quadTo(709f, 817f, 636f, 848.5f)\n            quadTo(563f, 880f, 480f, 880f)\n            close()\n            moveTo(480f, 800f)\n            quadTo(614f, 800f, 707f, 707f)\n            quadTo(800f, 614f, 800f, 480f)\n            quadTo(800f, 346f, 707f, 253f)\n            quadTo(614f, 160f, 480f, 160f)\n            quadTo(346f, 160f, 253f, 253f)\n            quadTo(160f, 346f, 160f, 480f)\n            quadTo(160f, 614f, 253f, 707f)\n            quadTo(346f, 800f, 480f, 800f)\n            close()\n            moveTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Noise.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Noise: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Noise\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 21f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 17f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 13f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 9f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 5f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14f, 19f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14f, 15f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14f, 11f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14f, 7f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16f, 21f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16f, 17f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16f, 13f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16f, 9f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16f, 5f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18f, 19f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18f, 15f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18f, 11f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18f, 7f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 21f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 17f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 13f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 9f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20f, 5f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10f, 19f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10f, 15f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10f, 11f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10f, 7f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 21f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 17f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 13f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 9f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 5f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 19f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 15f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 11f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6f, 7f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 21f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 17f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 13f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 9f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 5f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/NoiseAlt.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.NoiseAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.NoiseAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4.982f, 17.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.482f, 17.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13.982f, 17.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.482f, 17.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(2.982f, 13.011f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.482f, 13.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.982f, 13.011f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.482f, 13.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.982f, 13.011f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4.982f, 9.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.482f, 9.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13.982f, 9.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.482f, 9.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            reflectiveCurveToRelative(0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.482f, 5.011f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.982f, 5.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            curveToRelative(0.288f, 0.288f, 0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            curveToRelative(-0.287f, 0.288f, -0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.482f, 5.011f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.482f, 21.011f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.982f, 21.511f)\n            curveToRelative(-0.425f, 0f, -0.781f, -0.144f, -1.069f, -0.431f)\n            reflectiveCurveToRelative(-0.431f, -0.644f, -0.431f, -1.069f)\n            reflectiveCurveToRelative(0.144f, -0.781f, 0.431f, -1.069f)\n            reflectiveCurveToRelative(0.644f, -0.431f, 1.069f, -0.431f)\n            reflectiveCurveToRelative(0.781f, 0.144f, 1.069f, 0.431f)\n            curveToRelative(0.288f, 0.287f, 0.431f, 0.644f, 0.431f, 1.069f)\n            reflectiveCurveToRelative(-0.144f, 0.781f, -0.431f, 1.069f)\n            curveToRelative(-0.287f, 0.287f, -0.644f, 0.431f, -1.069f, 0.431f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(16.482f, 21.011f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Numeric.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Numeric: ImageVector by lazy {\n    Builder(\n        name = \"Numeric\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(4.0f, 17.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(2.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(6.0f)\n            verticalLineTo(17.0f)\n            horizontalLineTo(4.0f)\n            moveTo(22.0f, 15.0f)\n            curveTo(22.0f, 16.11f, 21.1f, 17.0f, 20.0f, 17.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(13.0f)\n            horizontalLineTo(18.0f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(20.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 22.0f,\n                y1 = 9.0f\n            )\n            verticalLineTo(10.5f)\n            arcTo(\n                1.5f, 1.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 20.5f,\n                y1 = 12.0f\n            )\n            arcTo(\n                1.5f, 1.5f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 22.0f,\n                y1 = 13.5f\n            )\n            verticalLineTo(15.0f)\n            moveTo(14.0f, 15.0f)\n            verticalLineTo(17.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(13.0f)\n            curveTo(8.0f, 11.89f, 8.9f, 11.0f, 10.0f, 11.0f)\n            horizontalLineTo(12.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(12.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 14.0f,\n                y1 = 9.0f\n            )\n            verticalLineTo(11.0f)\n            curveTo(14.0f, 12.11f, 13.1f, 13.0f, 12.0f, 13.0f)\n            horizontalLineTo(10.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(14.0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/OverlayAbove.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.OverlayAbove: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"OverlayAbove\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(3f, 1f)\n            curveTo(1.89f, 1f, 1f, 1.89f, 1f, 3f)\n            verticalLineTo(14f)\n            curveTo(1f, 15.11f, 1.89f, 16f, 3f, 16f)\n            curveTo(6.67f, 16f, 10.33f, 16f, 14f, 16f)\n            curveTo(15.11f, 16f, 16f, 15.11f, 16f, 14f)\n            curveTo(16f, 10.33f, 16f, 6.67f, 16f, 3f)\n            curveTo(16f, 1.89f, 15.11f, 1f, 14f, 1f)\n            horizontalLineTo(3f)\n            moveTo(3f, 3f)\n            horizontalLineTo(14f)\n            verticalLineTo(14f)\n            horizontalLineTo(3f)\n            verticalLineTo(3f)\n            moveTo(18f, 7f)\n            verticalLineTo(9f)\n            horizontalLineTo(20f)\n            verticalLineTo(20f)\n            horizontalLineTo(9f)\n            verticalLineTo(18f)\n            horizontalLineTo(7f)\n            verticalLineTo(20f)\n            curveTo(7f, 21.11f, 7.89f, 22f, 9f, 22f)\n            horizontalLineTo(20f)\n            curveTo(21.11f, 22f, 22f, 21.11f, 22f, 20f)\n            verticalLineTo(9f)\n            curveTo(22f, 7.89f, 21.11f, 7f, 20f, 7f)\n            horizontalLineTo(18f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/PaletteBox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.PaletteBox: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.PaletteBox\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 20f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(4f)\n            close()\n            moveTo(17.5f, 8.675f)\n            horizontalLineToRelative(2.5f)\n            verticalLineToRelative(-2.675f)\n            horizontalLineToRelative(-2.5f)\n            verticalLineToRelative(2.675f)\n            close()\n            moveTo(17.5f, 13.325f)\n            horizontalLineToRelative(2.5f)\n            verticalLineToRelative(-2.65f)\n            horizontalLineToRelative(-2.5f)\n            verticalLineToRelative(2.65f)\n            close()\n            moveTo(4f, 18f)\n            horizontalLineToRelative(11.5f)\n            verticalLineTo(6f)\n            horizontalLineTo(4f)\n            verticalLineToRelative(12f)\n            close()\n            moveTo(17.5f, 18f)\n            horizontalLineToRelative(2.5f)\n            verticalLineToRelative(-2.675f)\n            horizontalLineToRelative(-2.5f)\n            verticalLineToRelative(2.675f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.75f, 15f)\n            curveToRelative(-0.7f, 0f, -1.296f, -0.242f, -1.788f, -0.726f)\n            curveToRelative(-0.492f, -0.484f, -0.738f, -1.074f, -0.738f, -1.768f)\n            curveToRelative(0f, -0.332f, 0.064f, -0.649f, 0.193f, -0.951f)\n            curveToRelative(0.129f, -0.303f, 0.312f, -0.57f, 0.549f, -0.801f)\n            lineToRelative(1.784f, -1.753f)\n            lineToRelative(1.784f, 1.753f)\n            curveToRelative(0.237f, 0.232f, 0.42f, 0.499f, 0.549f, 0.801f)\n            curveToRelative(0.129f, 0.303f, 0.193f, 0.62f, 0.193f, 0.951f)\n            curveToRelative(0f, 0.695f, -0.246f, 1.284f, -0.738f, 1.768f)\n            reflectiveCurveToRelative(-1.088f, 0.726f, -1.788f, 0.726f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.PaletteBox: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.PaletteBox\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 4.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(11.538f, 14.274f)\n            curveToRelative(-0.492f, 0.484f, -1.088f, 0.726f, -1.788f, 0.726f)\n            reflectiveCurveToRelative(-1.296f, -0.242f, -1.788f, -0.726f)\n            curveToRelative(-0.492f, -0.484f, -0.738f, -1.074f, -0.738f, -1.768f)\n            curveToRelative(0f, -0.332f, 0.064f, -0.649f, 0.193f, -0.951f)\n            reflectiveCurveToRelative(0.312f, -0.57f, 0.549f, -0.801f)\n            lineToRelative(1.784f, -1.753f)\n            lineToRelative(1.784f, 1.753f)\n            curveToRelative(0.237f, 0.232f, 0.42f, 0.499f, 0.549f, 0.801f)\n            reflectiveCurveToRelative(0.193f, 0.62f, 0.193f, 0.951f)\n            curveToRelative(0f, 0.695f, -0.246f, 1.284f, -0.738f, 1.768f)\n            close()\n            moveTo(20f, 18f)\n            horizontalLineToRelative(-2.5f)\n            verticalLineToRelative(-2.675f)\n            horizontalLineToRelative(2.5f)\n            verticalLineToRelative(2.675f)\n            close()\n            moveTo(20f, 13.325f)\n            horizontalLineToRelative(-2.5f)\n            verticalLineToRelative(-2.65f)\n            horizontalLineToRelative(2.5f)\n            verticalLineToRelative(2.65f)\n            close()\n            moveTo(20f, 8.675f)\n            horizontalLineToRelative(-2.5f)\n            verticalLineToRelative(-2.675f)\n            horizontalLineToRelative(2.5f)\n            verticalLineToRelative(2.675f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/PaletteSwatch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.PaletteSwatch: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Palette Swatch\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(2.53f, 19.65f)\n            lineTo(3.87f, 20.21f)\n            verticalLineTo(11.18f)\n            lineTo(1.44f, 17.04f)\n            curveTo(1.03f, 18.06f, 1.5f, 19.23f, 2.53f, 19.65f)\n            moveTo(22.03f, 15.95f)\n            lineTo(17.07f, 4.0f)\n            curveTo(16.76f, 3.23f, 16.03f, 2.77f, 15.26f, 2.75f)\n            curveTo(15.0f, 2.75f, 14.73f, 2.79f, 14.47f, 2.9f)\n            lineTo(7.1f, 5.95f)\n            curveTo(6.35f, 6.26f, 5.89f, 7.0f, 5.87f, 7.75f)\n            curveTo(5.86f, 8.0f, 5.91f, 8.29f, 6.0f, 8.55f)\n            lineTo(11.0f, 20.5f)\n            curveTo(11.29f, 21.28f, 12.03f, 21.74f, 12.81f, 21.75f)\n            curveTo(13.07f, 21.75f, 13.33f, 21.7f, 13.58f, 21.6f)\n            lineTo(20.94f, 18.55f)\n            curveTo(21.96f, 18.13f, 22.45f, 16.96f, 22.03f, 15.95f)\n            moveTo(7.88f, 8.75f)\n            arcTo(\n                1.0f, 1.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 6.88f,\n                y1 = 7.75f\n            )\n            arcTo(\n                1.0f, 1.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 7.88f,\n                y1 = 6.75f\n            )\n            curveTo(8.43f, 6.75f, 8.88f, 7.2f, 8.88f, 7.75f)\n            curveTo(8.88f, 8.3f, 8.43f, 8.75f, 7.88f, 8.75f)\n            moveTo(5.88f, 19.75f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 7.88f,\n                y1 = 21.75f\n            )\n            horizontalLineTo(9.33f)\n            lineTo(5.88f, 13.41f)\n            verticalLineTo(19.75f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.PaletteSwatch: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Palette Swatch\", defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(2.5f, 19.6f)\n            lineTo(3.8f, 20.2f)\n            verticalLineTo(11.2f)\n            lineTo(1.4f, 17.0f)\n            curveTo(1.0f, 18.1f, 1.5f, 19.2f, 2.5f, 19.6f)\n            moveTo(15.2f, 4.8f)\n            lineTo(20.2f, 16.8f)\n            lineTo(12.9f, 19.8f)\n            lineTo(7.9f, 7.9f)\n            verticalLineTo(7.8f)\n            lineTo(15.2f, 4.8f)\n            moveTo(15.3f, 2.8f)\n            curveTo(15.0f, 2.8f, 14.8f, 2.8f, 14.5f, 2.9f)\n            lineTo(7.1f, 6.0f)\n            curveTo(6.4f, 6.3f, 5.9f, 7.0f, 5.9f, 7.8f)\n            curveTo(5.9f, 8.0f, 5.9f, 8.3f, 6.0f, 8.6f)\n            lineTo(11.0f, 20.5f)\n            curveTo(11.3f, 21.3f, 12.0f, 21.7f, 12.8f, 21.7f)\n            curveTo(13.1f, 21.7f, 13.3f, 21.7f, 13.6f, 21.6f)\n            lineTo(21.0f, 18.5f)\n            curveTo(22.0f, 18.1f, 22.5f, 16.9f, 22.1f, 15.9f)\n            lineTo(17.1f, 4.0f)\n            curveTo(16.8f, 3.2f, 16.0f, 2.8f, 15.3f, 2.8f)\n            moveTo(10.5f, 9.9f)\n            curveTo(9.9f, 9.9f, 9.5f, 9.5f, 9.5f, 8.9f)\n            reflectiveCurveTo(9.9f, 7.9f, 10.5f, 7.9f)\n            curveTo(11.1f, 7.9f, 11.5f, 8.4f, 11.5f, 8.9f)\n            reflectiveCurveTo(11.1f, 9.9f, 10.5f, 9.9f)\n            moveTo(5.9f, 19.8f)\n            curveTo(5.9f, 20.9f, 6.8f, 21.8f, 7.9f, 21.8f)\n            horizontalLineTo(9.3f)\n            lineTo(5.9f, 13.5f)\n            verticalLineTo(19.8f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.PaletteSwatch: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.PaletteSwatch\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(2.5f, 19.6f)\n            lineToRelative(1.3f, 0.6f)\n            verticalLineToRelative(-9f)\n            lineToRelative(-2.4f, 5.8f)\n            curveToRelative(-0.4f, 1.1f, 0.1f, 2.2f, 1.1f, 2.6f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(15.2f, 4.8f)\n            lineToRelative(5f, 12f)\n            lineToRelative(-7.3f, 3f)\n            lineToRelative(-5f, -11.9f)\n            lineToRelative(0f, -0.1f)\n            lineToRelative(7.3f, -3f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(10.5f, 9.9f)\n            curveToRelative(-0.6f, 0f, -1f, -0.4f, -1f, -1f)\n            reflectiveCurveToRelative(0.4f, -1f, 1f, -1f)\n            reflectiveCurveToRelative(1f, 0.5f, 1f, 1f)\n            reflectiveCurveToRelative(-0.4f, 1f, -1f, 1f)\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(5.9f, 19.8f)\n            curveToRelative(0f, 1.1f, 0.9f, 2f, 2f, 2f)\n            horizontalLineToRelative(1.4f)\n            lineToRelative(-3.4f, -8.3f)\n            verticalLineToRelative(6.3f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(22.1f, 15.9f)\n            lineToRelative(-5f, -11.9f)\n            curveToRelative(-0.3f, -0.8f, -1.1f, -1.2f, -1.8f, -1.2f)\n            curveToRelative(-0.3f, 0f, -0.5f, 0f, -0.8f, 0.1f)\n            lineToRelative(-7.4f, 3.1f)\n            curveToRelative(-0.7f, 0.3f, -1.2f, 1f, -1.2f, 1.8f)\n            curveToRelative(0f, 0.2f, 0f, 0.5f, 0.1f, 0.8f)\n            lineToRelative(5f, 11.9f)\n            curveToRelative(0.3f, 0.8f, 1f, 1.2f, 1.8f, 1.2f)\n            curveToRelative(0.3f, 0f, 0.5f, 0f, 0.8f, -0.1f)\n            lineToRelative(7.4f, -3.1f)\n            curveToRelative(1f, -0.4f, 1.5f, -1.6f, 1.1f, -2.6f)\n            close()\n            moveTo(12.9f, 19.8f)\n            lineTo(7.9f, 7.9f)\n            verticalLineToRelative(-0.1f)\n            lineToRelative(7.3f, -3f)\n            lineToRelative(5f, 12f)\n            lineToRelative(-7.3f, 3f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Panorama.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Panorama: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Panorama\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 20f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(4f)\n            close()\n            moveTo(4f, 18f)\n            horizontalLineToRelative(16f)\n            verticalLineTo(6f)\n            horizontalLineTo(4f)\n            verticalLineToRelative(12f)\n            close()\n            moveTo(11.25f, 15f)\n            lineToRelative(-1.85f, -2.475f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2f, 2.675f)\n            curveToRelative(-0.133f, 0.167f, -0.15f, 0.342f, -0.05f, 0.525f)\n            reflectiveCurveToRelative(0.25f, 0.275f, 0.45f, 0.275f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.2f, 0f, 0.35f, -0.092f, 0.45f, -0.275f)\n            reflectiveCurveToRelative(0.083f, -0.358f, -0.05f, -0.525f)\n            lineToRelative(-2.75f, -3.675f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2.6f, 3.475f)\n            close()\n            moveTo(4f, 18f)\n            verticalLineTo(6f)\n            verticalLineToRelative(12f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Panorama: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Panorama\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 20f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(4f)\n            close()\n            moveTo(4f, 18f)\n            horizontalLineToRelative(16f)\n            verticalLineTo(6f)\n            horizontalLineTo(4f)\n            verticalLineToRelative(12f)\n            close()\n            moveTo(11.25f, 15f)\n            lineToRelative(-1.85f, -2.475f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2f, 2.675f)\n            curveToRelative(-0.133f, 0.167f, -0.15f, 0.342f, -0.05f, 0.525f)\n            reflectiveCurveToRelative(0.25f, 0.275f, 0.45f, 0.275f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.2f, 0f, 0.35f, -0.092f, 0.45f, -0.275f)\n            reflectiveCurveToRelative(0.083f, -0.358f, -0.05f, -0.525f)\n            lineToRelative(-2.75f, -3.675f)\n            curveToRelative(-0.1f, -0.133f, -0.233f, -0.2f, -0.4f, -0.2f)\n            reflectiveCurveToRelative(-0.3f, 0.067f, -0.4f, 0.2f)\n            lineToRelative(-2.6f, 3.475f)\n            close()\n            moveTo(4f, 18f)\n            verticalLineTo(6f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(4f, 6f)\n            horizontalLineToRelative(16f)\n            verticalLineToRelative(12f)\n            horizontalLineToRelative(-16f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Pdf.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Pdf: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Pdf\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.427f, 9.511f)\n            curveToRelative(-0.216f, -0.216f, -0.483f, -0.323f, -0.802f, -0.323f)\n            horizontalLineToRelative(-2.25f)\n            verticalLineToRelative(5.625f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(-2.25f)\n            horizontalLineToRelative(1.125f)\n            curveToRelative(0.319f, 0f, 0.586f, -0.108f, 0.802f, -0.323f)\n            curveToRelative(0.216f, -0.216f, 0.323f, -0.483f, 0.323f, -0.802f)\n            verticalLineToRelative(-1.125f)\n            curveToRelative(0f, -0.319f, -0.108f, -0.586f, -0.323f, -0.802f)\n            close()\n            moveTo(8.625f, 11.438f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(-1.125f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(1.125f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13.927f, 9.511f)\n            curveToRelative(-0.216f, -0.216f, -0.483f, -0.323f, -0.802f, -0.323f)\n            horizontalLineToRelative(-2.25f)\n            verticalLineToRelative(5.625f)\n            horizontalLineToRelative(2.25f)\n            curveToRelative(0.319f, 0f, 0.586f, -0.108f, 0.802f, -0.323f)\n            curveToRelative(0.216f, -0.216f, 0.323f, -0.483f, 0.323f, -0.802f)\n            verticalLineToRelative(-3.375f)\n            curveToRelative(0f, -0.319f, -0.108f, -0.586f, -0.323f, -0.802f)\n            close()\n            moveTo(13.125f, 13.688f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(-3.375f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(3.375f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15.375f, 14.813f)\n            lineToRelative(1.125f, 0f)\n            lineToRelative(0f, -2.25f)\n            lineToRelative(1.125f, 0f)\n            lineToRelative(0f, -1.125f)\n            lineToRelative(-1.125f, 0f)\n            lineToRelative(0f, -1.125f)\n            lineToRelative(1.125f, 0f)\n            lineToRelative(0f, -1.125f)\n            lineToRelative(-2.25f, 0f)\n            lineToRelative(0f, 5.625f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.339f, 3.661f)\n            curveToRelative(-0.441f, -0.441f, -0.97f, -0.661f, -1.589f, -0.661f)\n            horizontalLineTo(5.25f)\n            curveToRelative(-0.619f, 0f, -1.148f, 0.22f, -1.589f, 0.661f)\n            reflectiveCurveToRelative(-0.661f, 0.97f, -0.661f, 1.589f)\n            verticalLineToRelative(13.5f)\n            curveToRelative(0f, 0.619f, 0.22f, 1.148f, 0.661f, 1.589f)\n            reflectiveCurveToRelative(0.97f, 0.661f, 1.589f, 0.661f)\n            horizontalLineToRelative(13.5f)\n            curveToRelative(0.619f, 0f, 1.148f, -0.22f, 1.589f, -0.661f)\n            reflectiveCurveToRelative(0.661f, -0.97f, 0.661f, -1.589f)\n            verticalLineTo(5.25f)\n            curveToRelative(0f, -0.619f, -0.22f, -1.148f, -0.661f, -1.589f)\n            close()\n            moveTo(18.75f, 18.75f)\n            horizontalLineTo(5.25f)\n            verticalLineTo(5.25f)\n            horizontalLineToRelative(13.5f)\n            verticalLineToRelative(13.5f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5.25f, 5.25f)\n            verticalLineToRelative(13.5f)\n            verticalLineTo(5.25f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Pdf: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Pdf\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.427f, 9.511f)\n            curveToRelative(-0.216f, -0.216f, -0.483f, -0.323f, -0.802f, -0.323f)\n            horizontalLineToRelative(-2.25f)\n            verticalLineToRelative(5.625f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(-2.25f)\n            horizontalLineToRelative(1.125f)\n            curveToRelative(0.319f, 0f, 0.586f, -0.108f, 0.802f, -0.323f)\n            curveToRelative(0.216f, -0.216f, 0.323f, -0.483f, 0.323f, -0.802f)\n            verticalLineToRelative(-1.125f)\n            curveToRelative(0f, -0.319f, -0.108f, -0.586f, -0.323f, -0.802f)\n            close()\n            moveTo(8.625f, 11.438f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(-1.125f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(1.125f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13.927f, 9.511f)\n            curveToRelative(-0.216f, -0.216f, -0.483f, -0.323f, -0.802f, -0.323f)\n            horizontalLineToRelative(-2.25f)\n            verticalLineToRelative(5.625f)\n            horizontalLineToRelative(2.25f)\n            curveToRelative(0.319f, 0f, 0.586f, -0.108f, 0.802f, -0.323f)\n            curveToRelative(0.216f, -0.216f, 0.323f, -0.483f, 0.323f, -0.802f)\n            verticalLineToRelative(-3.375f)\n            curveToRelative(0f, -0.319f, -0.108f, -0.586f, -0.323f, -0.802f)\n            close()\n            moveTo(13.125f, 13.688f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(-3.375f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(3.375f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15.375f, 14.813f)\n            lineToRelative(1.125f, 0f)\n            lineToRelative(0f, -2.25f)\n            lineToRelative(1.125f, 0f)\n            lineToRelative(0f, -1.125f)\n            lineToRelative(-1.125f, 0f)\n            lineToRelative(0f, -1.125f)\n            lineToRelative(1.125f, 0f)\n            lineToRelative(0f, -1.125f)\n            lineToRelative(-2.25f, 0f)\n            lineToRelative(0f, 5.625f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.339f, 3.661f)\n            curveToRelative(-0.441f, -0.441f, -0.97f, -0.661f, -1.589f, -0.661f)\n            horizontalLineTo(5.25f)\n            curveToRelative(-0.619f, 0f, -1.148f, 0.22f, -1.589f, 0.661f)\n            reflectiveCurveToRelative(-0.661f, 0.97f, -0.661f, 1.589f)\n            verticalLineToRelative(13.5f)\n            curveToRelative(0f, 0.619f, 0.22f, 1.148f, 0.661f, 1.589f)\n            reflectiveCurveToRelative(0.97f, 0.661f, 1.589f, 0.661f)\n            horizontalLineToRelative(13.5f)\n            curveToRelative(0.619f, 0f, 1.148f, -0.22f, 1.589f, -0.661f)\n            reflectiveCurveToRelative(0.661f, -0.97f, 0.661f, -1.589f)\n            verticalLineTo(5.25f)\n            curveToRelative(0f, -0.619f, -0.22f, -1.148f, -0.661f, -1.589f)\n            close()\n            moveTo(18.75f, 18.75f)\n            horizontalLineTo(5.25f)\n            verticalLineTo(5.25f)\n            horizontalLineToRelative(13.5f)\n            verticalLineToRelative(13.5f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5.25f, 5.25f)\n            verticalLineToRelative(13.5f)\n            verticalLineTo(5.25f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5.25f, 5.25f)\n            horizontalLineToRelative(13.5f)\n            verticalLineToRelative(13.5f)\n            horizontalLineToRelative(-13.5f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Pdf: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Pdf\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 10.313f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(3.375f)\n            horizontalLineToRelative(-1.125f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.5f, 10.313f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(1.125f)\n            horizontalLineToRelative(-1.125f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.339f, 3.661f)\n            curveToRelative(-0.441f, -0.441f, -0.97f, -0.661f, -1.589f, -0.661f)\n            horizontalLineTo(5.25f)\n            curveToRelative(-0.619f, 0f, -1.148f, 0.22f, -1.589f, 0.661f)\n            reflectiveCurveToRelative(-0.661f, 0.97f, -0.661f, 1.589f)\n            verticalLineToRelative(13.5f)\n            curveToRelative(0f, 0.619f, 0.22f, 1.148f, 0.661f, 1.589f)\n            reflectiveCurveToRelative(0.97f, 0.661f, 1.589f, 0.661f)\n            horizontalLineToRelative(13.5f)\n            curveToRelative(0.619f, 0f, 1.148f, -0.22f, 1.589f, -0.661f)\n            reflectiveCurveToRelative(0.661f, -0.97f, 0.661f, -1.589f)\n            verticalLineTo(5.25f)\n            curveToRelative(0f, -0.619f, -0.22f, -1.148f, -0.661f, -1.589f)\n            close()\n            moveTo(9.75f, 11.438f)\n            curveToRelative(0f, 0.319f, -0.108f, 0.586f, -0.323f, 0.802f)\n            reflectiveCurveToRelative(-0.483f, 0.323f, -0.802f, 0.323f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(2.25f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(-5.625f)\n            horizontalLineToRelative(2.25f)\n            curveToRelative(0.319f, 0f, 0.586f, 0.108f, 0.802f, 0.323f)\n            reflectiveCurveToRelative(0.323f, 0.483f, 0.323f, 0.802f)\n            verticalLineToRelative(1.125f)\n            close()\n            moveTo(14.25f, 13.688f)\n            curveToRelative(0f, 0.319f, -0.108f, 0.586f, -0.323f, 0.802f)\n            reflectiveCurveToRelative(-0.483f, 0.323f, -0.802f, 0.323f)\n            horizontalLineToRelative(-2.25f)\n            verticalLineToRelative(-5.625f)\n            horizontalLineToRelative(2.25f)\n            curveToRelative(0.319f, 0f, 0.586f, 0.108f, 0.802f, 0.323f)\n            reflectiveCurveToRelative(0.323f, 0.483f, 0.323f, 0.802f)\n            verticalLineToRelative(3.375f)\n            close()\n            moveTo(17.625f, 10.313f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(1.125f)\n            horizontalLineToRelative(1.125f)\n            verticalLineToRelative(1.125f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(2.25f)\n            horizontalLineToRelative(-1.125f)\n            verticalLineToRelative(-5.625f)\n            horizontalLineToRelative(2.25f)\n            verticalLineToRelative(1.125f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Pen.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Pen: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Pen\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(490f, 433f)\n            lineTo(527f, 470f)\n            lineTo(744f, 253f)\n            lineTo(707f, 216f)\n            lineTo(490f, 433f)\n            close()\n            moveTo(200f, 760f)\n            lineTo(237f, 760f)\n            lineTo(470f, 527f)\n            lineTo(433f, 490f)\n            lineTo(200f, 723f)\n            lineTo(200f, 760f)\n            close()\n            moveTo(555f, 555f)\n            lineTo(405f, 405f)\n            lineTo(572f, 238f)\n            lineTo(543f, 209f)\n            quadTo(543f, 209f, 543f, 209f)\n            quadTo(543f, 209f, 543f, 209f)\n            lineTo(352f, 400f)\n            quadTo(340f, 412f, 324f, 412f)\n            quadTo(308f, 412f, 296f, 400f)\n            quadTo(284f, 388f, 284f, 371.5f)\n            quadTo(284f, 355f, 296f, 343f)\n            lineTo(486f, 153f)\n            quadTo(510f, 129f, 542.5f, 129f)\n            quadTo(575f, 129f, 599f, 153f)\n            lineTo(628f, 182f)\n            lineTo(678f, 132f)\n            quadTo(690f, 120f, 706.5f, 120f)\n            quadTo(723f, 120f, 735f, 132f)\n            lineTo(828f, 225f)\n            quadTo(840f, 237f, 840f, 253.5f)\n            quadTo(840f, 270f, 828f, 282f)\n            lineTo(555f, 555f)\n            close()\n            moveTo(160f, 840f)\n            quadTo(143f, 840f, 131.5f, 828.5f)\n            quadTo(120f, 817f, 120f, 800f)\n            lineTo(120f, 723f)\n            quadTo(120f, 707f, 126f, 692.5f)\n            quadTo(132f, 678f, 143f, 667f)\n            lineTo(405f, 405f)\n            lineTo(555f, 555f)\n            lineTo(293f, 817f)\n            quadTo(282f, 828f, 267.5f, 834f)\n            quadTo(253f, 840f, 237f, 840f)\n            lineTo(160f, 840f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Perspective.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Perspective: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Perspective\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            stroke = SolidColor(Color(0xFF000000)),\n            strokeLineWidth = 1f\n        ) {\n            moveTo(5.892f, 7.771f)\n            lineToRelative(12.216f, -1.879f)\n            lineToRelative(0.94f, 12.216f)\n            lineToRelative(-14.096f, -2.819f)\n            lineTo(5.892f, 7.771f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = SolidColor(Color(0xFF000000)),\n            strokeLineWidth = 1f\n        ) {\n            moveTo(4.482f, 7.771f)\n            curveToRelative(0f, -0.778f, 0.631f, -1.41f, 1.41f, -1.41f)\n            reflectiveCurveToRelative(1.41f, 0.631f, 1.41f, 1.41f)\n            reflectiveCurveTo(6.67f, 9.181f, 5.892f, 9.181f)\n            reflectiveCurveTo(4.482f, 8.55f, 4.482f, 7.771f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = SolidColor(Color(0xFF000000)),\n            strokeLineWidth = 1f\n        ) {\n            moveTo(16.699f, 5.892f)\n            curveToRelative(0f, -0.778f, 0.631f, -1.41f, 1.41f, -1.41f)\n            reflectiveCurveToRelative(1.41f, 0.631f, 1.41f, 1.41f)\n            reflectiveCurveToRelative(-0.631f, 1.41f, -1.41f, 1.41f)\n            reflectiveCurveTo(16.699f, 6.67f, 16.699f, 5.892f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = SolidColor(Color(0xFF000000)),\n            strokeLineWidth = 1f\n        ) {\n            moveTo(17.638f, 18.108f)\n            curveToRelative(0f, -0.778f, 0.631f, -1.41f, 1.41f, -1.41f)\n            reflectiveCurveToRelative(1.41f, 0.631f, 1.41f, 1.41f)\n            reflectiveCurveToRelative(-0.631f, 1.41f, -1.41f, 1.41f)\n            reflectiveCurveTo(17.638f, 18.887f, 17.638f, 18.108f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = SolidColor(Color(0xFF000000)),\n            strokeLineWidth = 1f\n        ) {\n            moveTo(3.543f, 15.289f)\n            curveToRelative(0f, -0.778f, 0.631f, -1.41f, 1.41f, -1.41f)\n            reflectiveCurveToRelative(1.41f, 0.631f, 1.41f, 1.41f)\n            reflectiveCurveToRelative(-0.631f, 1.41f, -1.41f, 1.41f)\n            reflectiveCurveTo(3.543f, 16.067f, 3.543f, 15.289f)\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/PhotoPicker.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.PhotoPicker: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.PhotoPicker\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.563f, 18.875f)\n            lineToRelative(-1.312f, -1.749f)\n            lineToRelative(-1.75f, 2.333f)\n            lineToRelative(6.998f, 0f)\n            lineToRelative(-2.187f, -2.916f)\n            lineToRelative(-1.749f, 2.333f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.725f, 6.65f)\n            curveToRelative(-0.183f, -0.25f, -0.425f, -0.433f, -0.725f, -0.55f)\n            verticalLineToRelative(-3.1f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(7f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(18f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineToRelative(-10.1f)\n            curveToRelative(0.3f, -0.117f, 0.542f, -0.3f, 0.725f, -0.55f)\n            curveToRelative(0.183f, -0.25f, 0.275f, -0.533f, 0.275f, -0.85f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.317f, -0.092f, -0.6f, -0.275f, -0.85f)\n            close()\n            moveTo(7f, 3f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(5.943f)\n            curveToRelative(-0.297f, -0.181f, -0.614f, -0.318f, -0.951f, -0.409f)\n            curveToRelative(-0.34f, -0.092f, -0.685f, -0.138f, -1.034f, -0.138f)\n            horizontalLineToRelative(-6.015f)\n            curveToRelative(-0.35f, 0f, -0.696f, 0.046f, -1.038f, 0.138f)\n            reflectiveCurveToRelative(-0.662f, 0.229f, -0.962f, 0.412f)\n            verticalLineTo(3f)\n            close()\n            moveTo(7f, 21f)\n            verticalLineToRelative(-8.603f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.412f)\n            reflectiveCurveToRelative(0.862f, -0.588f, 1.413f, -0.588f)\n            horizontalLineToRelative(6.015f)\n            curveToRelative(0.548f, 0f, 1.017f, 0.196f, 1.407f, 0.588f)\n            curveToRelative(0.37f, 0.371f, 0.558f, 0.816f, 0.578f, 1.329f)\n            verticalLineToRelative(8.687f)\n            horizontalLineTo(7f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/PhotoPickerMobile.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.PhotoPickerMobile: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.PhotoPickerMobile\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.563f, 18.875f)\n            lineToRelative(-1.312f, -1.749f)\n            lineToRelative(-1.75f, 2.333f)\n            lineToRelative(6.998f, 0f)\n            lineToRelative(-2.187f, -2.916f)\n            lineToRelative(-1.749f, 2.333f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.725f, 6.65f)\n            curveToRelative(-0.183f, -0.25f, -0.425f, -0.433f, -0.725f, -0.55f)\n            verticalLineToRelative(-3.1f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(7f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(18f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineToRelative(-10.1f)\n            curveToRelative(0.3f, -0.117f, 0.542f, -0.3f, 0.725f, -0.55f)\n            curveToRelative(0.183f, -0.25f, 0.275f, -0.533f, 0.275f, -0.85f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.317f, -0.092f, -0.6f, -0.275f, -0.85f)\n            close()\n            moveTo(7f, 3f)\n            horizontalLineToRelative(10f)\n            verticalLineToRelative(5.943f)\n            curveToRelative(-0.297f, -0.181f, -0.614f, -0.318f, -0.951f, -0.409f)\n            curveToRelative(-0.34f, -0.092f, -0.685f, -0.138f, -1.034f, -0.138f)\n            horizontalLineToRelative(-6.015f)\n            curveToRelative(-0.35f, 0f, -0.696f, 0.046f, -1.038f, 0.138f)\n            reflectiveCurveToRelative(-0.662f, 0.229f, -0.962f, 0.412f)\n            verticalLineTo(3f)\n            close()\n            moveTo(7f, 21f)\n            verticalLineToRelative(-8.603f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.412f)\n            reflectiveCurveToRelative(0.862f, -0.588f, 1.413f, -0.588f)\n            horizontalLineToRelative(6.015f)\n            curveToRelative(0.548f, 0f, 1.017f, 0.196f, 1.407f, 0.588f)\n            curveToRelative(0.37f, 0.371f, 0.558f, 0.816f, 0.578f, 1.329f)\n            verticalLineToRelative(8.687f)\n            horizontalLineTo(7f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 6f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/PhotoPrints.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.PhotoPrints: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.PhotoPrints\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(508f, 760f)\n            lineTo(732f, 760f)\n            quadTo(725f, 786f, 708f, 802f)\n            quadTo(691f, 818f, 664f, 822f)\n            lineTo(228f, 875f)\n            quadTo(195f, 880f, 168.5f, 859.5f)\n            quadTo(142f, 839f, 138f, 806f)\n            lineTo(85f, 369f)\n            quadTo(81f, 336f, 101f, 310f)\n            quadTo(121f, 284f, 154f, 280f)\n            lineTo(200f, 274f)\n            lineTo(200f, 354f)\n            lineTo(164f, 359f)\n            quadTo(164f, 359f, 164f, 359f)\n            quadTo(164f, 359f, 164f, 359f)\n            lineTo(218f, 796f)\n            quadTo(218f, 796f, 218f, 796f)\n            quadTo(218f, 796f, 218f, 796f)\n            lineTo(508f, 760f)\n            close()\n            moveTo(360f, 680f)\n            quadTo(327f, 680f, 303.5f, 656.5f)\n            quadTo(280f, 633f, 280f, 600f)\n            lineTo(280f, 160f)\n            quadTo(280f, 127f, 303.5f, 103.5f)\n            quadTo(327f, 80f, 360f, 80f)\n            lineTo(800f, 80f)\n            quadTo(833f, 80f, 856.5f, 103.5f)\n            quadTo(880f, 127f, 880f, 160f)\n            lineTo(880f, 600f)\n            quadTo(880f, 633f, 856.5f, 656.5f)\n            quadTo(833f, 680f, 800f, 680f)\n            lineTo(360f, 680f)\n            close()\n            moveTo(360f, 600f)\n            lineTo(800f, 600f)\n            quadTo(800f, 600f, 800f, 600f)\n            quadTo(800f, 600f, 800f, 600f)\n            lineTo(800f, 160f)\n            quadTo(800f, 160f, 800f, 160f)\n            quadTo(800f, 160f, 800f, 160f)\n            lineTo(360f, 160f)\n            quadTo(360f, 160f, 360f, 160f)\n            quadTo(360f, 160f, 360f, 160f)\n            lineTo(360f, 600f)\n            quadTo(360f, 600f, 360f, 600f)\n            quadTo(360f, 600f, 360f, 600f)\n            close()\n            moveTo(580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            lineTo(580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            lineTo(580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            lineTo(580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            quadTo(580f, 380f, 580f, 380f)\n            close()\n            moveTo(218f, 796f)\n            lineTo(218f, 796f)\n            lineTo(218f, 796f)\n            lineTo(218f, 796f)\n            lineTo(218f, 796f)\n            quadTo(218f, 796f, 218f, 796f)\n            quadTo(218f, 796f, 218f, 796f)\n            close()\n            moveTo(581f, 560f)\n            quadTo(649f, 560f, 696.5f, 513f)\n            quadTo(744f, 466f, 749f, 400f)\n            quadTo(681f, 400f, 632.5f, 447f)\n            quadTo(584f, 494f, 581f, 560f)\n            close()\n            moveTo(581f, 560f)\n            quadTo(578f, 494f, 529.5f, 447f)\n            quadTo(481f, 400f, 413f, 400f)\n            quadTo(418f, 466f, 465.5f, 513f)\n            quadTo(513f, 560f, 581f, 560f)\n            close()\n            moveTo(581f, 440f)\n            quadTo(598f, 440f, 609.5f, 428.5f)\n            quadTo(621f, 417f, 621f, 400f)\n            lineTo(621f, 390f)\n            lineTo(631f, 394f)\n            quadTo(646f, 400f, 661.5f, 397f)\n            quadTo(677f, 394f, 685f, 380f)\n            quadTo(694f, 365f, 691f, 348f)\n            quadTo(688f, 331f, 671f, 324f)\n            lineTo(661f, 320f)\n            lineTo(671f, 316f)\n            quadTo(688f, 309f, 690.5f, 291.5f)\n            quadTo(693f, 274f, 685f, 260f)\n            quadTo(676f, 245f, 661f, 242.5f)\n            quadTo(646f, 240f, 631f, 246f)\n            lineTo(621f, 250f)\n            lineTo(621f, 240f)\n            quadTo(621f, 223f, 609.5f, 211.5f)\n            quadTo(598f, 200f, 581f, 200f)\n            quadTo(564f, 200f, 552.5f, 211.5f)\n            quadTo(541f, 223f, 541f, 240f)\n            lineTo(541f, 250f)\n            lineTo(531f, 246f)\n            quadTo(516f, 240f, 501f, 242.5f)\n            quadTo(486f, 245f, 477f, 260f)\n            quadTo(469f, 274f, 471.5f, 291.5f)\n            quadTo(474f, 309f, 491f, 316f)\n            lineTo(501f, 320f)\n            lineTo(491f, 324f)\n            quadTo(474f, 331f, 471f, 348f)\n            quadTo(468f, 365f, 477f, 380f)\n            quadTo(485f, 394f, 500.5f, 397f)\n            quadTo(516f, 400f, 531f, 394f)\n            lineTo(541f, 390f)\n            lineTo(541f, 400f)\n            quadTo(541f, 417f, 552.5f, 428.5f)\n            quadTo(564f, 440f, 581f, 440f)\n            close()\n            moveTo(581f, 360f)\n            quadTo(564f, 360f, 552.5f, 348.5f)\n            quadTo(541f, 337f, 541f, 320f)\n            quadTo(541f, 303f, 552.5f, 291.5f)\n            quadTo(564f, 280f, 581f, 280f)\n            quadTo(598f, 280f, 609.5f, 291.5f)\n            quadTo(621f, 303f, 621f, 320f)\n            quadTo(621f, 337f, 609.5f, 348.5f)\n            quadTo(598f, 360f, 581f, 360f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/PhotoSizeSelectSmall.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.PhotoSizeSelectSmall: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.PhotoSizeSelectSmall\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(520f, 840f)\n            lineTo(200f, 840f)\n            quadTo(167f, 840f, 143.5f, 816.5f)\n            quadTo(120f, 793f, 120f, 760f)\n            lineTo(120f, 440f)\n            lineTo(520f, 440f)\n            lineTo(520f, 840f)\n            close()\n            moveTo(160f, 760f)\n            lineTo(480f, 760f)\n            lineTo(376f, 620f)\n            lineTo(300f, 720f)\n            lineTo(244f, 646f)\n            lineTo(160f, 760f)\n            close()\n            moveTo(200f, 200f)\n            lineTo(120f, 200f)\n            quadTo(120f, 167f, 143.5f, 143.5f)\n            quadTo(167f, 120f, 200f, 120f)\n            lineTo(200f, 200f)\n            close()\n            moveTo(280f, 200f)\n            lineTo(280f, 120f)\n            lineTo(360f, 120f)\n            lineTo(360f, 200f)\n            lineTo(280f, 200f)\n            close()\n            moveTo(440f, 200f)\n            lineTo(440f, 120f)\n            lineTo(520f, 120f)\n            lineTo(520f, 200f)\n            lineTo(440f, 200f)\n            close()\n            moveTo(600f, 200f)\n            lineTo(600f, 120f)\n            lineTo(680f, 120f)\n            lineTo(680f, 200f)\n            lineTo(600f, 200f)\n            close()\n            moveTo(600f, 840f)\n            lineTo(600f, 760f)\n            lineTo(680f, 760f)\n            lineTo(680f, 840f)\n            lineTo(600f, 840f)\n            close()\n            moveTo(760f, 200f)\n            lineTo(760f, 120f)\n            quadTo(793f, 120f, 816.5f, 143.5f)\n            quadTo(840f, 167f, 840f, 200f)\n            lineTo(760f, 200f)\n            close()\n            moveTo(120f, 360f)\n            lineTo(120f, 280f)\n            lineTo(200f, 280f)\n            lineTo(200f, 360f)\n            lineTo(120f, 360f)\n            close()\n            moveTo(760f, 760f)\n            lineTo(840f, 760f)\n            quadTo(840f, 793f, 816.5f, 816.5f)\n            quadTo(793f, 840f, 760f, 840f)\n            lineTo(760f, 760f)\n            close()\n            moveTo(760f, 680f)\n            lineTo(760f, 600f)\n            lineTo(840f, 600f)\n            lineTo(840f, 680f)\n            lineTo(760f, 680f)\n            close()\n            moveTo(760f, 520f)\n            lineTo(760f, 440f)\n            lineTo(840f, 440f)\n            lineTo(840f, 520f)\n            lineTo(760f, 520f)\n            close()\n            moveTo(760f, 360f)\n            lineTo(760f, 280f)\n            lineTo(840f, 280f)\n            lineTo(840f, 360f)\n            lineTo(760f, 360f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/PictureInPictureCenter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.PictureInPictureCenter: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"PictureInPictureCenter\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(160f, 800f)\n            quadTo(127f, 800f, 103.5f, 776.5f)\n            quadTo(80f, 753f, 80f, 720f)\n            lineTo(80f, 240f)\n            quadTo(80f, 207f, 103.5f, 183.5f)\n            quadTo(127f, 160f, 160f, 160f)\n            lineTo(800f, 160f)\n            quadTo(833f, 160f, 856.5f, 183.5f)\n            quadTo(880f, 207f, 880f, 240f)\n            lineTo(880f, 720f)\n            quadTo(880f, 753f, 856.5f, 776.5f)\n            quadTo(833f, 800f, 800f, 800f)\n            lineTo(160f, 800f)\n            close()\n            moveTo(160f, 720f)\n            lineTo(800f, 720f)\n            quadTo(800f, 720f, 800f, 720f)\n            quadTo(800f, 720f, 800f, 720f)\n            lineTo(800f, 240f)\n            quadTo(800f, 240f, 800f, 240f)\n            quadTo(800f, 240f, 800f, 240f)\n            lineTo(160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            lineTo(160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            close()\n            moveTo(320f, 600f)\n            lineTo(640f, 600f)\n            lineTo(640f, 360f)\n            lineTo(320f, 360f)\n            lineTo(320f, 600f)\n            close()\n            moveTo(160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            lineTo(160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            lineTo(160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            quadTo(160f, 240f, 160f, 240f)\n            lineTo(160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            quadTo(160f, 720f, 160f, 720f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Png.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Png: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Png\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(260f, 460f)\n            verticalLineToRelative(-40f)\n            horizontalLineToRelative(40f)\n            verticalLineToRelative(40f)\n            horizontalLineToRelative(-40f)\n            close()\n            moveTo(660f, 600f)\n            horizontalLineToRelative(40f)\n            quadToRelative(25f, 0f, 42.5f, -17.5f)\n            reflectiveQuadTo(760f, 540f)\n            verticalLineToRelative(-60f)\n            horizontalLineToRelative(-60f)\n            verticalLineToRelative(60f)\n            horizontalLineToRelative(-40f)\n            verticalLineToRelative(-120f)\n            horizontalLineToRelative(100f)\n            quadToRelative(0f, -25f, -17.5f, -42.5f)\n            reflectiveQuadTo(700f, 360f)\n            horizontalLineToRelative(-40f)\n            quadToRelative(-25f, 0f, -42.5f, 17.5f)\n            reflectiveQuadTo(600f, 420f)\n            verticalLineToRelative(120f)\n            quadToRelative(0f, 25f, 17.5f, 42.5f)\n            reflectiveQuadTo(660f, 600f)\n            close()\n            moveTo(200f, 600f)\n            horizontalLineToRelative(60f)\n            verticalLineToRelative(-80f)\n            horizontalLineToRelative(60f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            reflectiveQuadTo(360f, 480f)\n            verticalLineToRelative(-80f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(320f, 360f)\n            lineTo(200f, 360f)\n            verticalLineToRelative(240f)\n            close()\n            moveTo(400f, 600f)\n            horizontalLineToRelative(60f)\n            verticalLineToRelative(-96f)\n            lineToRelative(40f, 96f)\n            horizontalLineToRelative(60f)\n            verticalLineToRelative(-240f)\n            horizontalLineToRelative(-60f)\n            verticalLineToRelative(94f)\n            lineToRelative(-40f, -94f)\n            horizontalLineToRelative(-60f)\n            verticalLineToRelative(240f)\n            close()\n            moveTo(160f, 800f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(80f, 720f)\n            verticalLineToRelative(-480f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(160f, 160f)\n            horizontalLineToRelative(640f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(880f, 240f)\n            verticalLineToRelative(480f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(800f, 800f)\n            lineTo(160f, 800f)\n            close()\n            moveTo(160f, 720f)\n            horizontalLineToRelative(640f)\n            verticalLineToRelative(-480f)\n            lineTo(160f, 240f)\n            verticalLineToRelative(480f)\n            close()\n            moveTo(160f, 720f)\n            verticalLineToRelative(-480f)\n            verticalLineToRelative(480f)\n            close()\n            moveTo(160f, 720f)\n            verticalLineToRelative(-480f)\n            verticalLineToRelative(480f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Polygon.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Polygon: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Polygon\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(7.45f, 21.0f)\n            curveTo(7.0167f, 21.0f, 6.625f, 20.875f, 6.275f, 20.625f)\n            reflectiveCurveToRelative(-0.5917f, -0.5833f, -0.725f, -1.0f)\n            lineToRelative(-3.075f, -9.2f)\n            curveToRelative(-0.1333f, -0.4333f, -0.1333f, -0.8583f, 0.0f, -1.275f)\n            curveToRelative(0.1333f, -0.4167f, 0.3833f, -0.75f, 0.75f, -1.0f)\n            lineToRelative(7.625f, -5.35f)\n            curveTo(11.2f, 2.5667f, 11.5833f, 2.45f, 12.0f, 2.45f)\n            curveToRelative(0.4167f, 0.0f, 0.8f, 0.1167f, 1.15f, 0.35f)\n            lineToRelative(7.625f, 5.35f)\n            curveToRelative(0.3667f, 0.25f, 0.6167f, 0.5833f, 0.75f, 1.0f)\n            curveToRelative(0.1333f, 0.4167f, 0.1333f, 0.8417f, 0.0f, 1.275f)\n            lineTo(18.45f, 19.625f)\n            curveToRelative(-0.1333f, 0.4167f, -0.375f, 0.75f, -0.725f, 1.0f)\n            reflectiveCurveTo(16.9833f, 21.0f, 16.55f, 21.0f)\n            horizontalLineTo(7.45f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Polygon: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"OutlinedPolygon\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(298.0f, 760.0f)\n            horizontalLineToRelative(364.0f)\n            lineToRelative(123.0f, -369.0f)\n            lineToRelative(-305.0f, -213.0f)\n            lineToRelative(-305.0f, 213.0f)\n            lineToRelative(123.0f, 369.0f)\n            close()\n            moveTo(298.0f, 840.0f)\n            quadToRelative(-26.0f, 0.0f, -47.0f, -15.0f)\n            reflectiveQuadToRelative(-29.0f, -40.0f)\n            lineTo(99.0f, 417.0f)\n            quadToRelative(-8.0f, -26.0f, 0.0f, -51.0f)\n            reflectiveQuadToRelative(30.0f, -40.0f)\n            lineToRelative(305.0f, -214.0f)\n            quadToRelative(21.0f, -14.0f, 46.0f, -14.0f)\n            reflectiveQuadToRelative(46.0f, 14.0f)\n            lineToRelative(305.0f, 214.0f)\n            quadToRelative(22.0f, 15.0f, 30.0f, 40.0f)\n            reflectiveQuadToRelative(0.0f, 51.0f)\n            lineTo(738.0f, 785.0f)\n            quadToRelative(-8.0f, 25.0f, -29.0f, 40.0f)\n            reflectiveQuadToRelative(-47.0f, 15.0f)\n            lineTo(298.0f, 840.0f)\n            close()\n            moveTo(480.0f, 469.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Prefix.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Prefix: ImageVector by lazy {\n    Builder(\n        name = \"Prefix\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(11.14f, 4.0f)\n            lineTo(6.43f, 16.0f)\n            horizontalLineTo(8.36f)\n            lineTo(9.32f, 13.43f)\n            horizontalLineTo(14.67f)\n            lineTo(15.64f, 16.0f)\n            horizontalLineTo(17.57f)\n            lineTo(12.86f, 4.0f)\n            moveTo(12.0f, 6.29f)\n            lineTo(14.03f, 11.71f)\n            horizontalLineTo(9.96f)\n            moveTo(4.0f, 18.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(2.0f)\n            verticalLineTo(20.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(18.0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Preview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Preview: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Preview\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(200f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120f, 760f)\n            verticalLineToRelative(-560f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(200f, 120f)\n            horizontalLineToRelative(560f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(840f, 200f)\n            verticalLineToRelative(560f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(760f, 840f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(200f, 760f)\n            horizontalLineToRelative(560f)\n            verticalLineToRelative(-480f)\n            lineTo(200f, 280f)\n            verticalLineToRelative(480f)\n            close()\n            moveTo(333.5f, 635.5f)\n            quadTo(269f, 591f, 240f, 520f)\n            quadToRelative(29f, -71f, 93.5f, -115.5f)\n            reflectiveQuadTo(480f, 360f)\n            quadToRelative(82f, 0f, 146.5f, 44.5f)\n            reflectiveQuadTo(720f, 520f)\n            quadToRelative(-29f, 71f, -93.5f, 115.5f)\n            reflectiveQuadTo(480f, 680f)\n            quadToRelative(-82f, 0f, -146.5f, -44.5f)\n            close()\n            moveTo(582f, 593.5f)\n            quadToRelative(46f, -26.5f, 72f, -73.5f)\n            quadToRelative(-26f, -47f, -72f, -73.5f)\n            reflectiveQuadTo(480f, 420f)\n            quadToRelative(-56f, 0f, -102f, 26.5f)\n            reflectiveQuadTo(306f, 520f)\n            quadToRelative(26f, 47f, 72f, 73.5f)\n            reflectiveQuadTo(480f, 620f)\n            quadToRelative(56f, 0f, 102f, -26.5f)\n            close()\n            moveTo(480f, 520f)\n            close()\n            moveTo(522.5f, 562.5f)\n            quadTo(540f, 545f, 540f, 520f)\n            reflectiveQuadToRelative(-17.5f, -42.5f)\n            quadTo(505f, 460f, 480f, 460f)\n            reflectiveQuadToRelative(-42.5f, 17.5f)\n            quadTo(420f, 495f, 420f, 520f)\n            reflectiveQuadToRelative(17.5f, 42.5f)\n            quadTo(455f, 580f, 480f, 580f)\n            reflectiveQuadToRelative(42.5f, -17.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Print.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Print: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Print\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.85f, 0.292f, -1.563f, 0.875f, -2.138f)\n            curveToRelative(0.583f, -0.575f, 1.292f, -0.863f, 2.125f, -0.863f)\n            horizontalLineToRelative(14f)\n            curveToRelative(0.85f, 0f, 1.563f, 0.287f, 2.138f, 0.863f)\n            reflectiveCurveToRelative(0.863f, 1.288f, 0.863f, 2.138f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-8f)\n            close()\n            moveTo(4f, 15f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(8f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineTo(5f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(16f, 8f)\n            verticalLineToRelative(-3f)\n            horizontalLineToRelative(-8f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(8f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(18f, 12.5f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(16f, 19f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-8f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(8f)\n            close()\n            moveTo(4f, 10f)\n            horizontalLineToRelative(16f)\n            horizontalLineTo(4f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Print: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Print\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.85f, 0.292f, -1.563f, 0.875f, -2.138f)\n            curveToRelative(0.583f, -0.575f, 1.292f, -0.863f, 2.125f, -0.863f)\n            horizontalLineToRelative(14f)\n            curveToRelative(0.85f, 0f, 1.563f, 0.287f, 2.138f, 0.863f)\n            reflectiveCurveToRelative(0.863f, 1.288f, 0.863f, 2.138f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-8f)\n            close()\n            moveTo(4f, 15f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(8f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineTo(5f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(16f, 8f)\n            verticalLineToRelative(-3f)\n            horizontalLineToRelative(-8f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(8f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(18f, 12.5f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(16f, 19f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-8f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(8f)\n            close()\n            moveTo(4f, 10f)\n            horizontalLineToRelative(16f)\n            horizontalLineTo(4f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(8f, 5f)\n            horizontalLineToRelative(8f)\n            verticalLineToRelative(3f)\n            horizontalLineToRelative(-8f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(4f, 10f)\n            horizontalLineToRelative(16f)\n            verticalLineToRelative(5f)\n            horizontalLineToRelative(-16f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Psychology.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Psychology: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Psychology\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(434f, 550f)\n            lineTo(438f, 582f)\n            quadTo(439f, 590f, 444.5f, 595f)\n            quadTo(450f, 600f, 458f, 600f)\n            lineTo(502f, 600f)\n            quadTo(510f, 600f, 515.5f, 595f)\n            quadTo(521f, 590f, 522f, 582f)\n            lineTo(526f, 550f)\n            quadTo(534f, 547f, 540.5f, 543f)\n            quadTo(547f, 539f, 552f, 534f)\n            lineTo(582f, 547f)\n            quadTo(589f, 550f, 596f, 548f)\n            quadTo(603f, 546f, 607f, 539f)\n            lineTo(629f, 501f)\n            quadTo(633f, 494f, 631.5f, 487f)\n            quadTo(630f, 480f, 624f, 475f)\n            lineTo(598f, 456f)\n            quadTo(600f, 448f, 600f, 440f)\n            quadTo(600f, 432f, 598f, 424f)\n            lineTo(624f, 405f)\n            quadTo(630f, 400f, 631.5f, 393f)\n            quadTo(633f, 386f, 629f, 379f)\n            lineTo(607f, 341f)\n            quadTo(603f, 334f, 596f, 332f)\n            quadTo(589f, 330f, 582f, 333f)\n            lineTo(552f, 346f)\n            quadTo(547f, 341f, 540.5f, 337f)\n            quadTo(534f, 333f, 526f, 330f)\n            lineTo(522f, 298f)\n            quadTo(521f, 290f, 515.5f, 285f)\n            quadTo(510f, 280f, 502f, 280f)\n            lineTo(458f, 280f)\n            quadTo(450f, 280f, 444.5f, 285f)\n            quadTo(439f, 290f, 438f, 298f)\n            lineTo(434f, 330f)\n            quadTo(426f, 333f, 419.5f, 337f)\n            quadTo(413f, 341f, 408f, 346f)\n            lineTo(378f, 333f)\n            quadTo(371f, 330f, 364f, 332f)\n            quadTo(357f, 334f, 353f, 341f)\n            lineTo(331f, 379f)\n            quadTo(327f, 386f, 328.5f, 393f)\n            quadTo(330f, 400f, 336f, 405f)\n            lineTo(362f, 424f)\n            quadTo(360f, 432f, 360f, 440f)\n            quadTo(360f, 448f, 362f, 456f)\n            lineTo(336f, 475f)\n            quadTo(330f, 480f, 328.5f, 487f)\n            quadTo(327f, 494f, 331f, 501f)\n            lineTo(353f, 539f)\n            quadTo(357f, 546f, 364f, 548f)\n            quadTo(371f, 550f, 378f, 547f)\n            lineTo(408f, 534f)\n            quadTo(413f, 539f, 419.5f, 543f)\n            quadTo(426f, 547f, 434f, 550f)\n            close()\n            moveTo(480f, 500f)\n            quadTo(455f, 500f, 437.5f, 482.5f)\n            quadTo(420f, 465f, 420f, 440f)\n            quadTo(420f, 415f, 437.5f, 397.5f)\n            quadTo(455f, 380f, 480f, 380f)\n            quadTo(505f, 380f, 522.5f, 397.5f)\n            quadTo(540f, 415f, 540f, 440f)\n            quadTo(540f, 465f, 522.5f, 482.5f)\n            quadTo(505f, 500f, 480f, 500f)\n            close()\n            moveTo(280f, 880f)\n            quadTo(263f, 880f, 251.5f, 868.5f)\n            quadTo(240f, 857f, 240f, 840f)\n            lineTo(240f, 708f)\n            quadTo(183f, 656f, 151.5f, 586.5f)\n            quadTo(120f, 517f, 120f, 440f)\n            quadTo(120f, 290f, 225f, 185f)\n            quadTo(330f, 80f, 480f, 80f)\n            quadTo(605f, 80f, 701.5f, 153.5f)\n            quadTo(798f, 227f, 827f, 345f)\n            lineTo(879f, 550f)\n            quadTo(884f, 569f, 872f, 584.5f)\n            quadTo(860f, 600f, 840f, 600f)\n            lineTo(760f, 600f)\n            lineTo(760f, 720f)\n            quadTo(760f, 753f, 736.5f, 776.5f)\n            quadTo(713f, 800f, 680f, 800f)\n            lineTo(600f, 800f)\n            lineTo(600f, 840f)\n            quadTo(600f, 857f, 588.5f, 868.5f)\n            quadTo(577f, 880f, 560f, 880f)\n            lineTo(280f, 880f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Puzzle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Puzzle: ImageVector by lazy {\n    Builder(\n        name = \"Puzzle\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(349.0f, 859.0f)\n            lineTo(174.0f, 859.0f)\n            quadToRelative(-28.725f, 0.0f, -50.863f, -22.137f)\n            quadTo(101.0f, 814.725f, 101.0f, 786.0f)\n            verticalLineToRelative(-169.0f)\n            quadToRelative(46.0f, -5.0f, 78.0f, -37.5f)\n            reflectiveQuadToRelative(32.0f, -78.5f)\n            quadToRelative(0.0f, -46.0f, -32.0f, -78.5f)\n            reflectiveQuadTo(101.0f, 385.0f)\n            verticalLineToRelative(-170.0f)\n            quadToRelative(0.0f, -28.725f, 22.137f, -50.862f)\n            quadTo(145.275f, 142.0f, 174.0f, 142.0f)\n            horizontalLineToRelative(172.0f)\n            quadToRelative(11.0f, -43.0f, 41.958f, -72.5f)\n            quadToRelative(30.957f, -29.5f, 73.0f, -29.5f)\n            quadTo(503.0f, 40.0f, 534.0f, 69.68f)\n            reflectiveQuadTo(576.0f, 142.0f)\n            horizontalLineToRelative(169.0f)\n            quadToRelative(28.725f, 0.0f, 50.862f, 22.138f)\n            quadTo(818.0f, 186.275f, 818.0f, 215.0f)\n            verticalLineToRelative(169.0f)\n            quadToRelative(43.0f, 11.0f, 71.0f, 43.958f)\n            quadToRelative(28.0f, 32.957f, 28.0f, 75.0f)\n            quadTo(917.0f, 545.0f, 888.82f, 574.5f)\n            reflectiveQuadTo(818.0f, 615.0f)\n            verticalLineToRelative(171.0f)\n            quadToRelative(0.0f, 28.725f, -22.138f, 50.863f)\n            quadTo(773.725f, 859.0f, 745.0f, 859.0f)\n            lineTo(569.0f, 859.0f)\n            quadToRelative(-2.0f, -53.0f, -33.75f, -86.5f)\n            reflectiveQuadTo(459.0f, 739.0f)\n            quadToRelative(-44.5f, 0.0f, -76.25f, 33.5f)\n            reflectiveQuadTo(349.0f, 859.0f)\n            close()\n            moveTo(174.0f, 786.0f)\n            horizontalLineToRelative(116.0f)\n            quadToRelative(24.0f, -62.0f, 71.388f, -91.0f)\n            quadToRelative(47.388f, -29.0f, 97.5f, -29.0f)\n            reflectiveQuadTo(557.0f, 695.0f)\n            quadToRelative(48.0f, 29.0f, 73.0f, 91.0f)\n            horizontalLineToRelative(115.0f)\n            verticalLineToRelative(-237.0f)\n            horizontalLineToRelative(53.0f)\n            quadToRelative(20.0f, 0.0f, 33.0f, -13.0f)\n            reflectiveQuadToRelative(13.0f, -33.0f)\n            quadToRelative(0.0f, -20.0f, -13.0f, -33.0f)\n            reflectiveQuadToRelative(-33.0f, -13.0f)\n            horizontalLineToRelative(-53.0f)\n            verticalLineToRelative(-242.0f)\n            lineTo(507.0f, 215.0f)\n            verticalLineToRelative(-56.0f)\n            quadToRelative(0.0f, -20.0f, -13.0f, -33.0f)\n            reflectiveQuadToRelative(-33.0f, -13.0f)\n            quadToRelative(-20.0f, 0.0f, -33.0f, 13.0f)\n            reflectiveQuadToRelative(-13.0f, 33.0f)\n            verticalLineToRelative(56.0f)\n            lineTo(174.0f, 215.0f)\n            verticalLineToRelative(115.0f)\n            quadToRelative(49.15f, 24.817f, 79.575f, 70.186f)\n            quadTo(284.0f, 445.555f, 284.0f, 501.223f)\n            quadToRelative(0.0f, 54.929f, -30.5f, 100.353f)\n            quadTo(223.0f, 647.0f, 174.0f, 671.0f)\n            verticalLineToRelative(115.0f)\n            close()\n            moveTo(461.0f, 503.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/QrCode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.QrCode: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.QrCode\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 10f)\n            verticalLineTo(4f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(5f, 9f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(3f, 20f)\n            verticalLineToRelative(-6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(5f, 19f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(13f, 10f)\n            verticalLineTo(4f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(15f, 9f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(19f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(13f, 15f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(15f, 17f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(13f, 19f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(15f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(17f, 19f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(17f, 15f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 17f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.QrCode: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.QrCode\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(3f, 10f)\n            verticalLineTo(4f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(5f, 9f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(3f, 20f)\n            verticalLineToRelative(-6f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            curveToRelative(-0.192f, -0.192f, -0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(5f, 19f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(13f, 10f)\n            verticalLineTo(4f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(-0.429f, 0.287f, -0.712f, 0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(15f, 9f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n            moveTo(19f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(13f, 15f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(15f, 17f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(13f, 19f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(15f, 21f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(17f, 19f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(17f, 15f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n            moveTo(19f, 17f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 5f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(-4f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 15f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(-4f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(15f, 5f)\n            horizontalLineToRelative(4f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(-4f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/QualityHigh.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.QualityHigh: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.QualityHigh\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(590f, 600f)\n            verticalLineToRelative(30f)\n            quadToRelative(0f, 13f, 8.5f, 21.5f)\n            reflectiveQuadTo(620f, 660f)\n            quadToRelative(13f, 0f, 21.5f, -8.5f)\n            reflectiveQuadTo(650f, 630f)\n            verticalLineToRelative(-30f)\n            horizontalLineToRelative(30f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            reflectiveQuadTo(720f, 560f)\n            verticalLineToRelative(-160f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(680f, 360f)\n            lineTo(560f, 360f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            reflectiveQuadTo(520f, 400f)\n            verticalLineToRelative(160f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(560f, 600f)\n            horizontalLineToRelative(30f)\n            close()\n            moveTo(300f, 520f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(50f)\n            quadToRelative(0f, 13f, 8.5f, 21.5f)\n            reflectiveQuadTo(410f, 600f)\n            quadToRelative(13f, 0f, 21.5f, -8.5f)\n            reflectiveQuadTo(440f, 570f)\n            verticalLineToRelative(-180f)\n            quadToRelative(0f, -13f, -8.5f, -21.5f)\n            reflectiveQuadTo(410f, 360f)\n            quadToRelative(-13f, 0f, -21.5f, 8.5f)\n            reflectiveQuadTo(380f, 390f)\n            verticalLineToRelative(70f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(-70f)\n            quadToRelative(0f, -13f, -8.5f, -21.5f)\n            reflectiveQuadTo(270f, 360f)\n            quadToRelative(-13f, 0f, -21.5f, 8.5f)\n            reflectiveQuadTo(240f, 390f)\n            verticalLineToRelative(180f)\n            quadToRelative(0f, 13f, 8.5f, 21.5f)\n            reflectiveQuadTo(270f, 600f)\n            quadToRelative(13f, 0f, 21.5f, -8.5f)\n            reflectiveQuadTo(300f, 570f)\n            verticalLineToRelative(-50f)\n            close()\n            moveTo(580f, 540f)\n            verticalLineToRelative(-120f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(120f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(160f, 800f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(80f, 720f)\n            verticalLineToRelative(-480f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(160f, 160f)\n            horizontalLineToRelative(640f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(880f, 240f)\n            verticalLineToRelative(480f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(800f, 800f)\n            lineTo(160f, 800f)\n            close()\n            moveTo(160f, 720f)\n            horizontalLineToRelative(640f)\n            verticalLineToRelative(-480f)\n            lineTo(160f, 240f)\n            verticalLineToRelative(480f)\n            close()\n            moveTo(160f, 720f)\n            verticalLineToRelative(-480f)\n            verticalLineToRelative(480f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/QualityLow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.QualityLow: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.QualityLow\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17.592f, 9.287f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            horizontalLineToRelative(-3f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.713f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.713f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.713f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.713f, 0.287f)\n            horizontalLineToRelative(0.75f)\n            verticalLineToRelative(0.75f)\n            curveToRelative(0f, 0.217f, 0.071f, 0.396f, 0.213f, 0.537f)\n            reflectiveCurveToRelative(0.321f, 0.213f, 0.537f, 0.213f)\n            reflectiveCurveToRelative(0.396f, -0.071f, 0.537f, -0.213f)\n            reflectiveCurveToRelative(0.213f, -0.321f, 0.213f, -0.537f)\n            verticalLineToRelative(-0.75f)\n            horizontalLineToRelative(0.75f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.713f)\n            close()\n            moveTo(16.38f, 13.5f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-3f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(3f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 4.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(20f, 18f)\n            horizontalLineTo(4f)\n            verticalLineTo(6f)\n            horizontalLineToRelative(16f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 18f)\n            verticalLineTo(6f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10.62f, 13.5f)\n            horizontalLineToRelative(-2.74f)\n            verticalLineToRelative(-3.75f)\n            curveToRelative(0f, -0.414f, -0.336f, -0.75f, -0.75f, -0.75f)\n            reflectiveCurveToRelative(-0.75f, 0.336f, -0.75f, 0.75f)\n            verticalLineToRelative(4.5f)\n            curveToRelative(0f, 0.414f, 0.336f, 0.75f, 0.75f, 0.75f)\n            horizontalLineToRelative(3.49f)\n            curveToRelative(0.414f, 0f, 0.75f, -0.336f, 0.75f, -0.75f)\n            reflectiveCurveToRelative(-0.336f, -0.75f, -0.75f, -0.75f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/QualityMedium.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.QualityMedium: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.QualityMedium\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.088f, 9.287f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            horizontalLineToRelative(-3f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.713f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.713f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.713f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.713f, 0.287f)\n            horizontalLineToRelative(0.75f)\n            verticalLineToRelative(0.75f)\n            curveToRelative(0f, 0.217f, 0.071f, 0.396f, 0.213f, 0.537f)\n            reflectiveCurveToRelative(0.321f, 0.213f, 0.537f, 0.213f)\n            reflectiveCurveToRelative(0.396f, -0.071f, 0.537f, -0.213f)\n            reflectiveCurveToRelative(0.213f, -0.321f, 0.213f, -0.537f)\n            verticalLineToRelative(-0.75f)\n            horizontalLineToRelative(0.75f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.713f)\n            close()\n            moveTo(16.875f, 13.5f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-3f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(3f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 4.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(20f, 18f)\n            horizontalLineTo(4f)\n            verticalLineTo(6f)\n            horizontalLineToRelative(16f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 18f)\n            verticalLineTo(6f)\n            verticalLineToRelative(12f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.125f, 10.5f)\n            horizontalLineToRelative(1f)\n            verticalLineToRelative(2.25f)\n            curveToRelative(0f, 0.217f, 0.071f, 0.396f, 0.213f, 0.538f)\n            reflectiveCurveToRelative(0.321f, 0.213f, 0.538f, 0.213f)\n            reflectiveCurveToRelative(0.396f, -0.071f, 0.538f, -0.213f)\n            reflectiveCurveToRelative(0.213f, -0.321f, 0.213f, -0.538f)\n            verticalLineToRelative(-2.25f)\n            horizontalLineToRelative(1f)\n            verticalLineToRelative(3.75f)\n            curveToRelative(0f, 0.217f, 0.071f, 0.396f, 0.213f, 0.538f)\n            reflectiveCurveToRelative(0.321f, 0.213f, 0.538f, 0.213f)\n            reflectiveCurveToRelative(0.396f, -0.071f, 0.538f, -0.213f)\n            reflectiveCurveToRelative(0.213f, -0.321f, 0.213f, -0.538f)\n            verticalLineToRelative(-4.25f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-4.5f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(4.25f)\n            curveToRelative(0f, 0.217f, 0.071f, 0.396f, 0.213f, 0.538f)\n            reflectiveCurveToRelative(0.321f, 0.213f, 0.538f, 0.213f)\n            reflectiveCurveToRelative(0.396f, -0.071f, 0.538f, -0.213f)\n            reflectiveCurveToRelative(0.213f, -0.321f, 0.213f, -0.538f)\n            verticalLineToRelative(-3.75f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Rabbit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Rabbit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Rabbit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.05f, 21f)\n            lineTo(15.32f, 16.26f)\n            curveTo(15.32f, 14.53f, 14.25f, 13.42f, 12.95f, 13.42f)\n            curveTo(12.05f, 13.42f, 11.27f, 13.92f, 10.87f, 14.66f)\n            curveTo(11.2f, 14.47f, 11.59f, 14.37f, 12f, 14.37f)\n            curveTo(13.3f, 14.37f, 14.36f, 15.43f, 14.36f, 16.73f)\n            curveTo(14.36f, 18.04f, 13.31f, 19.11f, 12f, 19.11f)\n            horizontalLineTo(15.3f)\n            verticalLineTo(21f)\n            horizontalLineTo(6.79f)\n            curveTo(6.55f, 21f, 6.3f, 20.91f, 6.12f, 20.72f)\n            curveTo(5.75f, 20.35f, 5.75f, 19.75f, 6.12f, 19.38f)\n            verticalLineTo(19.38f)\n            lineTo(6.62f, 18.88f)\n            curveTo(6.28f, 18.73f, 6f, 18.5f, 5.72f, 18.26f)\n            curveTo(5.5f, 18.76f, 5f, 19.11f, 4.42f, 19.11f)\n            curveTo(3.64f, 19.11f, 3f, 18.47f, 3f, 17.68f)\n            curveTo(3f, 16.9f, 3.64f, 16.26f, 4.42f, 16.26f)\n            lineTo(4.89f, 16.34f)\n            verticalLineTo(14.37f)\n            curveTo(4.89f, 11.75f, 7f, 9.63f, 9.63f, 9.63f)\n            horizontalLineTo(9.65f)\n            curveTo(11.77f, 9.64f, 13.42f, 10.47f, 13.42f, 9.16f)\n            curveTo(13.42f, 8.23f, 13.62f, 7.86f, 13.96f, 7.34f)\n            curveTo(13.23f, 7f, 12.4f, 6.79f, 11.53f, 6.79f)\n            curveTo(11f, 6.79f, 10.58f, 6.37f, 10.58f, 5.84f)\n            curveTo(10.58f, 5.41f, 10.86f, 5.05f, 11.25f, 4.93f)\n            lineTo(10.58f, 4.89f)\n            curveTo(10.06f, 4.89f, 9.63f, 4.47f, 9.63f, 3.95f)\n            curveTo(9.63f, 3.42f, 10.06f, 3f, 10.58f, 3f)\n            horizontalLineTo(11.53f)\n            curveTo(13.63f, 3f, 15.47f, 4.15f, 16.46f, 5.85f)\n            lineTo(16.74f, 5.84f)\n            curveTo(17.45f, 5.84f, 18.11f, 6.07f, 18.65f, 6.45f)\n            lineTo(19.1f, 6.83f)\n            curveTo(21.27f, 8.78f, 21f, 10.1f, 21f, 10.11f)\n            curveTo(21f, 11.39f, 19.94f, 12.44f, 18.65f, 12.44f)\n            lineTo(18.16f, 12.39f)\n            verticalLineTo(12.47f)\n            curveTo(18.16f, 13.58f, 17.68f, 14.57f, 16.93f, 15.27f)\n            lineTo(20.24f, 21f)\n            horizontalLineTo(18.05f)\n            moveTo(18.16f, 7.74f)\n            curveTo(17.63f, 7.74f, 17.21f, 8.16f, 17.21f, 8.68f)\n            curveTo(17.21f, 9.21f, 17.63f, 9.63f, 18.16f, 9.63f)\n            curveTo(18.68f, 9.63f, 19.11f, 9.21f, 19.11f, 8.68f)\n            curveTo(19.11f, 8.16f, 18.68f, 7.74f, 18.16f, 7.74f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Resize.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Resize: ImageVector by lazy {\n    Builder(\n        name = \"Resize\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(9.0024f, 4.0f)\n            horizontalLineTo(8.0f)\n            verticalLineToRelative(1.0024f)\n            curveTo(8.0f, 4.4488f, 8.4488f, 4.0f, 9.0024f, 4.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.9976f, 4.0f)\n            curveTo(19.5512f, 4.0f, 20.0f, 4.4488f, 20.0f, 5.0024f)\n            verticalLineTo(4.0f)\n            horizontalLineTo(18.9976f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.9976f, 16.0f)\n            horizontalLineTo(20.0f)\n            verticalLineToRelative(-1.0024f)\n            curveTo(20.0f, 15.5512f, 19.5512f, 16.0f, 18.9976f, 16.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.0f, 2.0f)\n            horizontalLineTo(8.0f)\n            curveTo(6.8954f, 2.0f, 6.0f, 2.8954f, 6.0f, 4.0f)\n            verticalLineToRelative(8.0f)\n            horizontalLineTo(4.0f)\n            curveToRelative(-1.1046f, 0.0f, -2.0f, 0.8954f, -2.0f, 2.0f)\n            verticalLineToRelative(6.0f)\n            curveToRelative(0.0f, 1.1046f, 0.8954f, 2.0f, 2.0f, 2.0f)\n            horizontalLineToRelative(6.0f)\n            curveToRelative(1.1046f, 0.0f, 2.0f, -0.8954f, 2.0f, -2.0f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineToRelative(8.0f)\n            curveToRelative(1.1046f, 0.0f, 2.0f, -0.8954f, 2.0f, -2.0f)\n            verticalLineTo(4.0f)\n            curveTo(22.0f, 2.8954f, 21.1046f, 2.0f, 20.0f, 2.0f)\n            close()\n            moveTo(18.3137f, 13.5529f)\n            curveToRelative(-0.2004f, 0.1885f, -0.442f, 0.2828f, -0.7248f, 0.2828f)\n            curveToRelative(-0.2711f, -0.0118f, -0.5038f, -0.109f, -0.6982f, -0.2917f)\n            curveToRelative(-0.1945f, -0.1827f, -0.2917f, -0.4154f, -0.2917f, -0.6982f)\n            verticalLineTo(8.8152f)\n            lineToRelative(-4.5139f, 4.5139f)\n            verticalLineToRelative(-1.0E-4f)\n            lineTo(10.0f, 15.4142f)\n            verticalLineTo(16.0f)\n            verticalLineToRelative(0.7035f)\n            verticalLineToRelative(0.3228f)\n            verticalLineTo(17.75f)\n            verticalLineToRelative(1.2473f)\n            curveTo(10.0f, 19.5511f, 9.5511f, 20.0f, 8.9974f, 20.0f)\n            horizontalLineTo(5.0027f)\n            curveTo(4.4489f, 20.0f, 4.0f, 19.5511f, 4.0f, 18.9973f)\n            verticalLineTo(17.75f)\n            verticalLineToRelative(-2.7474f)\n            curveTo(4.0f, 14.4489f, 4.4489f, 14.0f, 5.0027f, 14.0f)\n            horizontalLineToRelative(1.3095f)\n            horizontalLineToRelative(0.741f)\n            horizontalLineToRelative(0.9415f)\n            horizontalLineTo(8.0f)\n            horizontalLineToRelative(0.5858f)\n            lineToRelative(2.1463f, -2.1463f)\n            horizontalLineToRelative(-1.0E-4f)\n            lineToRelative(4.4527f, -4.4527f)\n            horizontalLineToRelative(-4.0305f)\n            curveToRelative(-0.2828f, 0.0f, -0.5156f, -0.0972f, -0.6982f, -0.2917f)\n            curveToRelative(-0.1827f, -0.1944f, -0.2799f, -0.4272f, -0.2917f, -0.6982f)\n            curveToRelative(0.0f, -0.2828f, 0.0943f, -0.5244f, 0.2828f, -0.7248f)\n            curveToRelative(0.1885f, -0.2003f, 0.4243f, -0.3005f, 0.7071f, -0.3005f)\n            horizontalLineToRelative(6.47f)\n            curveToRelative(0.1414f, 0.0f, 0.2681f, 0.0266f, 0.3801f, 0.0796f)\n            curveToRelative(0.112f, 0.053f, 0.2151f, 0.1266f, 0.3094f, 0.2209f)\n            curveToRelative(0.0942f, 0.0943f, 0.1679f, 0.1974f, 0.2209f, 0.3094f)\n            curveToRelative(0.053f, 0.1119f, 0.0795f, 0.2386f, 0.0795f, 0.3801f)\n            lineToRelative(1.0E-4f, 6.47f)\n            curveTo(18.6143f, 13.1286f, 18.514f, 13.3643f, 18.3137f, 13.5529f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Resize: ImageVector by lazy {\n    Builder(\n        name = \"Resize\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.0f, 2.0f)\n            horizontalLineTo(8.0f)\n            curveTo(6.8954f, 2.0f, 6.0f, 2.8954f, 6.0f, 4.0f)\n            verticalLineToRelative(8.0f)\n            horizontalLineTo(4.0f)\n            curveToRelative(-1.1046f, 0.0f, -2.0f, 0.8954f, -2.0f, 2.0f)\n            verticalLineToRelative(6.0f)\n            curveToRelative(0.0f, 1.1046f, 0.8954f, 2.0f, 2.0f, 2.0f)\n            horizontalLineToRelative(6.0f)\n            curveToRelative(1.1046f, 0.0f, 2.0f, -0.8954f, 2.0f, -2.0f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineToRelative(8.0f)\n            curveToRelative(1.1046f, 0.0f, 2.0f, -0.8954f, 2.0f, -2.0f)\n            verticalLineTo(4.0f)\n            curveTo(22.0f, 2.8954f, 21.1046f, 2.0f, 20.0f, 2.0f)\n            close()\n            moveTo(10.0f, 15.4142f)\n            verticalLineToRelative(1.6121f)\n            verticalLineTo(17.75f)\n            verticalLineToRelative(1.2473f)\n            curveTo(10.0f, 19.5511f, 9.5511f, 20.0f, 8.9974f, 20.0f)\n            horizontalLineTo(5.0027f)\n            curveTo(4.4489f, 20.0f, 4.0f, 19.5511f, 4.0f, 18.9973f)\n            verticalLineTo(17.75f)\n            verticalLineToRelative(-2.7474f)\n            curveTo(4.0f, 14.4489f, 4.4489f, 14.0f, 5.0027f, 14.0f)\n            horizontalLineToRelative(2.0505f)\n            horizontalLineToRelative(0.9415f)\n            horizontalLineToRelative(0.5911f)\n            horizontalLineToRelative(0.4116f)\n            curveTo(9.5511f, 14.0f, 10.0f, 14.4489f, 10.0f, 15.0026f)\n            verticalLineTo(15.4142f)\n            close()\n            moveTo(20.0f, 16.0f)\n            horizontalLineToRelative(-8.0f)\n            verticalLineToRelative(-0.3495f)\n            verticalLineTo(14.0f)\n            curveToRelative(0.0f, -0.1779f, -0.0307f, -0.3472f, -0.0743f, -0.5115f)\n            lineToRelative(4.6733f, -4.6733f)\n            verticalLineToRelative(4.0305f)\n            curveToRelative(0.0f, 0.2828f, 0.0972f, 0.5156f, 0.2917f, 0.6982f)\n            curveToRelative(0.1944f, 0.1827f, 0.4272f, 0.2799f, 0.6982f, 0.2917f)\n            curveToRelative(0.2828f, 0.0f, 0.5244f, -0.0943f, 0.7248f, -0.2828f)\n            curveToRelative(0.2003f, -0.1885f, 0.3005f, -0.4243f, 0.3005f, -0.7071f)\n            lineToRelative(-1.0E-4f, -6.47f)\n            curveToRelative(0.0f, -0.1414f, -0.0265f, -0.2681f, -0.0795f, -0.3801f)\n            curveToRelative(-0.053f, -0.112f, -0.1267f, -0.2151f, -0.2209f, -0.3094f)\n            curveTo(18.2194f, 5.592f, 18.1163f, 5.5184f, 18.0043f, 5.4653f)\n            curveToRelative(-0.1119f, -0.053f, -0.2386f, -0.0796f, -0.3801f, -0.0796f)\n            horizontalLineToRelative(-6.47f)\n            curveToRelative(-0.2828f, 0.0f, -0.5186f, 0.1002f, -0.7071f, 0.3005f)\n            curveToRelative(-0.1885f, 0.2004f, -0.2828f, 0.442f, -0.2828f, 0.7248f)\n            curveToRelative(0.0118f, 0.2711f, 0.109f, 0.5038f, 0.2917f, 0.6982f)\n            curveToRelative(0.1827f, 0.1945f, 0.4154f, 0.2917f, 0.6982f, 0.2917f)\n            horizontalLineToRelative(4.0305f)\n            lineToRelative(-4.6733f, 4.6733f)\n            curveTo(10.3472f, 12.0307f, 10.1779f, 12.0f, 10.0f, 12.0f)\n            horizontalLineTo(9.9947f)\n            horizontalLineTo(8.2906f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(4.0f)\n            horizontalLineToRelative(12.0f)\n            verticalLineTo(16.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(9.0024f, 4.0f)\n            horizontalLineTo(8.0f)\n            verticalLineToRelative(1.0024f)\n            curveTo(8.0f, 4.4488f, 8.4488f, 4.0f, 9.0024f, 4.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.9976f, 4.0f)\n            curveTo(19.5512f, 4.0f, 20.0f, 4.4488f, 20.0f, 5.0024f)\n            verticalLineTo(4.0f)\n            horizontalLineTo(18.9976f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.9976f, 16.0f)\n            horizontalLineTo(20.0f)\n            verticalLineToRelative(-1.0024f)\n            curveTo(20.0f, 15.5512f, 19.5512f, 16.0f, 18.9976f, 16.0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ResponsiveLayout.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ResponsiveLayout: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.ResponsiveLayout\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(680f, 840f)\n            quadTo(663f, 840f, 651.5f, 828.5f)\n            quadTo(640f, 817f, 640f, 800f)\n            lineTo(640f, 400f)\n            quadTo(640f, 367f, 616.5f, 343.5f)\n            quadTo(593f, 320f, 560f, 320f)\n            lineTo(420f, 320f)\n            quadTo(403f, 320f, 391.5f, 308.5f)\n            quadTo(380f, 297f, 380f, 280f)\n            lineTo(380f, 160f)\n            quadTo(380f, 143f, 391.5f, 131.5f)\n            quadTo(403f, 120f, 420f, 120f)\n            lineTo(800f, 120f)\n            quadTo(817f, 120f, 828.5f, 131.5f)\n            quadTo(840f, 143f, 840f, 160f)\n            lineTo(840f, 800f)\n            quadTo(840f, 817f, 828.5f, 828.5f)\n            quadTo(817f, 840f, 800f, 840f)\n            lineTo(680f, 840f)\n            close()\n            moveTo(420f, 840f)\n            quadTo(403f, 840f, 391.5f, 828.5f)\n            quadTo(380f, 817f, 380f, 800f)\n            lineTo(380f, 440f)\n            quadTo(380f, 423f, 391.5f, 411.5f)\n            quadTo(403f, 400f, 420f, 400f)\n            lineTo(520f, 400f)\n            quadTo(537f, 400f, 548.5f, 411.5f)\n            quadTo(560f, 423f, 560f, 440f)\n            lineTo(560f, 800f)\n            quadTo(560f, 817f, 548.5f, 828.5f)\n            quadTo(537f, 840f, 520f, 840f)\n            lineTo(420f, 840f)\n            close()\n            moveTo(160f, 840f)\n            quadTo(143f, 840f, 131.5f, 828.5f)\n            quadTo(120f, 817f, 120f, 800f)\n            lineTo(120f, 440f)\n            quadTo(120f, 423f, 131.5f, 411.5f)\n            quadTo(143f, 400f, 160f, 400f)\n            lineTo(260f, 400f)\n            quadTo(277f, 400f, 288.5f, 411.5f)\n            quadTo(300f, 423f, 300f, 440f)\n            lineTo(300f, 800f)\n            quadTo(300f, 817f, 288.5f, 828.5f)\n            quadTo(277f, 840f, 260f, 840f)\n            lineTo(160f, 840f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Robot.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Robot: ImageVector by lazy {\n    Builder(\n        name = \"Robot\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.0f, 4.0f)\n            horizontalLineTo(18.0f)\n            verticalLineTo(3.0f)\n            horizontalLineTo(20.5f)\n            curveTo(20.78f, 3.0f, 21.0f, 3.22f, 21.0f, 3.5f)\n            verticalLineTo(5.5f)\n            curveTo(21.0f, 5.78f, 20.78f, 6.0f, 20.5f, 6.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(19.0f)\n            verticalLineTo(5.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(4.0f)\n            moveTo(19.0f, 9.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(8.0f)\n            horizontalLineTo(19.0f)\n            verticalLineTo(9.0f)\n            moveTo(17.0f, 3.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(17.0f)\n            verticalLineTo(3.0f)\n            moveTo(23.0f, 15.0f)\n            verticalLineTo(18.0f)\n            curveTo(23.0f, 18.55f, 22.55f, 19.0f, 22.0f, 19.0f)\n            horizontalLineTo(21.0f)\n            verticalLineTo(20.0f)\n            curveTo(21.0f, 21.11f, 20.11f, 22.0f, 19.0f, 22.0f)\n            horizontalLineTo(5.0f)\n            curveTo(3.9f, 22.0f, 3.0f, 21.11f, 3.0f, 20.0f)\n            verticalLineTo(19.0f)\n            horizontalLineTo(2.0f)\n            curveTo(1.45f, 19.0f, 1.0f, 18.55f, 1.0f, 18.0f)\n            verticalLineTo(15.0f)\n            curveTo(1.0f, 14.45f, 1.45f, 14.0f, 2.0f, 14.0f)\n            horizontalLineTo(3.0f)\n            curveTo(3.0f, 10.13f, 6.13f, 7.0f, 10.0f, 7.0f)\n            horizontalLineTo(11.0f)\n            verticalLineTo(5.73f)\n            curveTo(10.4f, 5.39f, 10.0f, 4.74f, 10.0f, 4.0f)\n            curveTo(10.0f, 2.9f, 10.9f, 2.0f, 12.0f, 2.0f)\n            reflectiveCurveTo(14.0f, 2.9f, 14.0f, 4.0f)\n            curveTo(14.0f, 4.74f, 13.6f, 5.39f, 13.0f, 5.73f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(14.0f)\n            curveTo(14.34f, 7.0f, 14.67f, 7.03f, 15.0f, 7.08f)\n            verticalLineTo(10.0f)\n            horizontalLineTo(19.74f)\n            curveTo(20.53f, 11.13f, 21.0f, 12.5f, 21.0f, 14.0f)\n            horizontalLineTo(22.0f)\n            curveTo(22.55f, 14.0f, 23.0f, 14.45f, 23.0f, 15.0f)\n            moveTo(10.0f, 15.5f)\n            curveTo(10.0f, 14.12f, 8.88f, 13.0f, 7.5f, 13.0f)\n            reflectiveCurveTo(5.0f, 14.12f, 5.0f, 15.5f)\n            reflectiveCurveTo(6.12f, 18.0f, 7.5f, 18.0f)\n            reflectiveCurveTo(10.0f, 16.88f, 10.0f, 15.5f)\n            moveTo(19.0f, 15.5f)\n            curveTo(19.0f, 14.12f, 17.88f, 13.0f, 16.5f, 13.0f)\n            reflectiveCurveTo(14.0f, 14.12f, 14.0f, 15.5f)\n            reflectiveCurveTo(15.12f, 18.0f, 16.5f, 18.0f)\n            reflectiveCurveTo(19.0f, 16.88f, 19.0f, 15.5f)\n            moveTo(17.0f, 8.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(17.0f)\n            verticalLineTo(8.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/RobotExcited.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.RobotExcited: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Robot Excited\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(22.0f, 14.0f)\n            horizontalLineTo(21.0f)\n            curveTo(21.0f, 10.13f, 17.87f, 7.0f, 14.0f, 7.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(5.73f)\n            curveTo(13.6f, 5.39f, 14.0f, 4.74f, 14.0f, 4.0f)\n            curveTo(14.0f, 2.9f, 13.11f, 2.0f, 12.0f, 2.0f)\n            reflectiveCurveTo(10.0f, 2.9f, 10.0f, 4.0f)\n            curveTo(10.0f, 4.74f, 10.4f, 5.39f, 11.0f, 5.73f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(10.0f)\n            curveTo(6.13f, 7.0f, 3.0f, 10.13f, 3.0f, 14.0f)\n            horizontalLineTo(2.0f)\n            curveTo(1.45f, 14.0f, 1.0f, 14.45f, 1.0f, 15.0f)\n            verticalLineTo(18.0f)\n            curveTo(1.0f, 18.55f, 1.45f, 19.0f, 2.0f, 19.0f)\n            horizontalLineTo(3.0f)\n            verticalLineTo(20.0f)\n            curveTo(3.0f, 21.11f, 3.9f, 22.0f, 5.0f, 22.0f)\n            horizontalLineTo(19.0f)\n            curveTo(20.11f, 22.0f, 21.0f, 21.11f, 21.0f, 20.0f)\n            verticalLineTo(19.0f)\n            horizontalLineTo(22.0f)\n            curveTo(22.55f, 19.0f, 23.0f, 18.55f, 23.0f, 18.0f)\n            verticalLineTo(15.0f)\n            curveTo(23.0f, 14.45f, 22.55f, 14.0f, 22.0f, 14.0f)\n            moveTo(21.0f, 17.0f)\n            horizontalLineTo(19.0f)\n            verticalLineTo(20.0f)\n            horizontalLineTo(5.0f)\n            verticalLineTo(17.0f)\n            horizontalLineTo(3.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(5.0f)\n            verticalLineTo(14.0f)\n            curveTo(5.0f, 11.24f, 7.24f, 9.0f, 10.0f, 9.0f)\n            horizontalLineTo(14.0f)\n            curveTo(16.76f, 9.0f, 19.0f, 11.24f, 19.0f, 14.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(21.0f)\n            verticalLineTo(17.0f)\n            moveTo(8.5f, 13.5f)\n            lineTo(10.86f, 15.86f)\n            lineTo(9.68f, 17.04f)\n            lineTo(8.5f, 15.86f)\n            lineTo(7.32f, 17.04f)\n            lineTo(6.14f, 15.86f)\n            lineTo(8.5f, 13.5f)\n            moveTo(15.5f, 13.5f)\n            lineTo(17.86f, 15.86f)\n            lineTo(16.68f, 17.04f)\n            lineTo(15.5f, 15.86f)\n            lineTo(14.32f, 17.04f)\n            lineTo(13.14f, 15.86f)\n            lineTo(15.5f, 13.5f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Rotate90Cw.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Rotate90Cw: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rotate90Cw\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 22f)\n            curveToRelative(-2.5f, 0f, -4.625f, -0.875f, -6.375f, -2.625f)\n            reflectiveCurveToRelative(-2.625f, -3.875f, -2.625f, -6.375f)\n            reflectiveCurveToRelative(0.879f, -4.625f, 2.638f, -6.375f)\n            curveToRelative(1.758f, -1.75f, 3.888f, -2.625f, 6.388f, -2.625f)\n            horizontalLineToRelative(0.175f)\n            lineToRelative(-0.9f, -0.9f)\n            curveToRelative(-0.183f, -0.183f, -0.275f, -0.417f, -0.275f, -0.7f)\n            reflectiveCurveToRelative(0.092f, -0.517f, 0.275f, -0.7f)\n            reflectiveCurveToRelative(0.417f, -0.275f, 0.7f, -0.275f)\n            reflectiveCurveToRelative(0.517f, 0.092f, 0.7f, 0.275f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.083f, 0.083f, 0.15f, 0.188f, 0.2f, 0.313f)\n            reflectiveCurveToRelative(0.075f, 0.254f, 0.075f, 0.387f)\n            reflectiveCurveToRelative(-0.025f, 0.262f, -0.075f, 0.387f)\n            reflectiveCurveToRelative(-0.117f, 0.229f, -0.2f, 0.313f)\n            lineToRelative(-2.6f, 2.6f)\n            curveToRelative(-0.183f, 0.183f, -0.417f, 0.275f, -0.7f, 0.275f)\n            reflectiveCurveToRelative(-0.517f, -0.092f, -0.7f, -0.275f)\n            reflectiveCurveToRelative(-0.275f, -0.417f, -0.275f, -0.7f)\n            reflectiveCurveToRelative(0.092f, -0.517f, 0.275f, -0.7f)\n            lineToRelative(0.9f, -0.9f)\n            horizontalLineToRelative(-0.175f)\n            curveToRelative(-1.95f, 0f, -3.608f, 0.679f, -4.975f, 2.037f)\n            curveToRelative(-1.367f, 1.358f, -2.05f, 3.013f, -2.05f, 4.963f)\n            reflectiveCurveToRelative(0.679f, 3.604f, 2.037f, 4.963f)\n            curveToRelative(1.358f, 1.358f, 3.013f, 2.037f, 4.963f, 2.037f)\n            curveToRelative(0.483f, 0f, 0.954f, -0.046f, 1.413f, -0.138f)\n            curveToRelative(0.458f, -0.092f, 0.904f, -0.229f, 1.337f, -0.412f)\n            curveToRelative(0.25f, -0.117f, 0.5f, -0.121f, 0.75f, -0.013f)\n            reflectiveCurveToRelative(0.425f, 0.287f, 0.525f, 0.538f)\n            reflectiveCurveToRelative(0.108f, 0.504f, 0.025f, 0.762f)\n            curveToRelative(-0.083f, 0.258f, -0.25f, 0.438f, -0.5f, 0.538f)\n            curveToRelative(-0.567f, 0.233f, -1.146f, 0.412f, -1.737f, 0.538f)\n            curveToRelative(-0.592f, 0.125f, -1.196f, 0.188f, -1.813f, 0.188f)\n            close()\n            moveTo(16.3f, 18.3f)\n            lineToRelative(-4.6f, -4.6f)\n            curveToRelative(-0.1f, -0.1f, -0.171f, -0.208f, -0.213f, -0.325f)\n            reflectiveCurveToRelative(-0.063f, -0.242f, -0.063f, -0.375f)\n            reflectiveCurveToRelative(0.021f, -0.258f, 0.063f, -0.375f)\n            reflectiveCurveToRelative(0.112f, -0.225f, 0.213f, -0.325f)\n            lineToRelative(4.6f, -4.6f)\n            curveToRelative(0.1f, -0.1f, 0.208f, -0.171f, 0.325f, -0.213f)\n            reflectiveCurveToRelative(0.242f, -0.063f, 0.375f, -0.063f)\n            reflectiveCurveToRelative(0.258f, 0.021f, 0.375f, 0.063f)\n            reflectiveCurveToRelative(0.225f, 0.112f, 0.325f, 0.213f)\n            lineToRelative(4.6f, 4.6f)\n            curveToRelative(0.1f, 0.1f, 0.171f, 0.208f, 0.213f, 0.325f)\n            reflectiveCurveToRelative(0.063f, 0.242f, 0.063f, 0.375f)\n            reflectiveCurveToRelative(-0.021f, 0.258f, -0.063f, 0.375f)\n            reflectiveCurveToRelative(-0.112f, 0.225f, -0.213f, 0.325f)\n            lineToRelative(-4.6f, 4.6f)\n            curveToRelative(-0.1f, 0.1f, -0.208f, 0.171f, -0.325f, 0.213f)\n            reflectiveCurveToRelative(-0.242f, 0.063f, -0.375f, 0.063f)\n            reflectiveCurveToRelative(-0.258f, -0.021f, -0.375f, -0.063f)\n            reflectiveCurveToRelative(-0.225f, -0.112f, -0.325f, -0.213f)\n            close()\n            moveTo(17f, 16.15f)\n            lineToRelative(3.15f, -3.15f)\n            lineToRelative(-3.15f, -3.15f)\n            lineToRelative(-3.15f, 3.15f)\n            lineToRelative(3.15f, 3.15f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Rotate90Cw: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoToneRotate90Cw\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 22f)\n            curveToRelative(-2.5f, 0f, -4.625f, -0.875f, -6.375f, -2.625f)\n            reflectiveCurveToRelative(-2.625f, -3.875f, -2.625f, -6.375f)\n            reflectiveCurveToRelative(0.879f, -4.625f, 2.638f, -6.375f)\n            curveToRelative(1.758f, -1.75f, 3.888f, -2.625f, 6.388f, -2.625f)\n            horizontalLineToRelative(0.175f)\n            lineToRelative(-0.9f, -0.9f)\n            curveToRelative(-0.183f, -0.183f, -0.275f, -0.417f, -0.275f, -0.7f)\n            reflectiveCurveToRelative(0.092f, -0.517f, 0.275f, -0.7f)\n            reflectiveCurveToRelative(0.417f, -0.275f, 0.7f, -0.275f)\n            reflectiveCurveToRelative(0.517f, 0.092f, 0.7f, 0.275f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.083f, 0.083f, 0.15f, 0.188f, 0.2f, 0.313f)\n            reflectiveCurveToRelative(0.075f, 0.254f, 0.075f, 0.387f)\n            reflectiveCurveToRelative(-0.025f, 0.262f, -0.075f, 0.387f)\n            reflectiveCurveToRelative(-0.117f, 0.229f, -0.2f, 0.313f)\n            lineToRelative(-2.6f, 2.6f)\n            curveToRelative(-0.183f, 0.183f, -0.417f, 0.275f, -0.7f, 0.275f)\n            reflectiveCurveToRelative(-0.517f, -0.092f, -0.7f, -0.275f)\n            reflectiveCurveToRelative(-0.275f, -0.417f, -0.275f, -0.7f)\n            reflectiveCurveToRelative(0.092f, -0.517f, 0.275f, -0.7f)\n            lineToRelative(0.9f, -0.9f)\n            horizontalLineToRelative(-0.175f)\n            curveToRelative(-1.95f, 0f, -3.608f, 0.679f, -4.975f, 2.037f)\n            curveToRelative(-1.367f, 1.358f, -2.05f, 3.013f, -2.05f, 4.963f)\n            reflectiveCurveToRelative(0.679f, 3.604f, 2.037f, 4.963f)\n            curveToRelative(1.358f, 1.358f, 3.013f, 2.037f, 4.963f, 2.037f)\n            curveToRelative(0.483f, 0f, 0.954f, -0.046f, 1.413f, -0.138f)\n            curveToRelative(0.458f, -0.092f, 0.904f, -0.229f, 1.337f, -0.412f)\n            curveToRelative(0.25f, -0.117f, 0.5f, -0.121f, 0.75f, -0.013f)\n            reflectiveCurveToRelative(0.425f, 0.287f, 0.525f, 0.538f)\n            reflectiveCurveToRelative(0.108f, 0.504f, 0.025f, 0.762f)\n            curveToRelative(-0.083f, 0.258f, -0.25f, 0.438f, -0.5f, 0.538f)\n            curveToRelative(-0.567f, 0.233f, -1.146f, 0.412f, -1.737f, 0.538f)\n            curveToRelative(-0.592f, 0.125f, -1.196f, 0.188f, -1.813f, 0.188f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(22.513f, 12.625f)\n            curveToRelative(-0.042f, -0.117f, -0.112f, -0.225f, -0.213f, -0.325f)\n            lineToRelative(-4.6f, -4.6f)\n            curveToRelative(-0.1f, -0.1f, -0.208f, -0.171f, -0.325f, -0.213f)\n            curveToRelative(-0.117f, -0.042f, -0.242f, -0.063f, -0.375f, -0.063f)\n            reflectiveCurveToRelative(-0.258f, 0.021f, -0.375f, 0.063f)\n            curveToRelative(-0.117f, 0.042f, -0.225f, 0.112f, -0.325f, 0.213f)\n            lineToRelative(-4.6f, 4.6f)\n            curveToRelative(-0.1f, 0.1f, -0.171f, 0.208f, -0.213f, 0.325f)\n            curveToRelative(-0.042f, 0.117f, -0.063f, 0.242f, -0.063f, 0.375f)\n            reflectiveCurveToRelative(0.021f, 0.258f, 0.063f, 0.375f)\n            curveToRelative(0.042f, 0.117f, 0.112f, 0.225f, 0.213f, 0.325f)\n            lineToRelative(4.6f, 4.6f)\n            curveToRelative(0.1f, 0.1f, 0.208f, 0.171f, 0.325f, 0.213f)\n            curveToRelative(0.117f, 0.042f, 0.242f, 0.063f, 0.375f, 0.063f)\n            reflectiveCurveToRelative(0.258f, -0.021f, 0.375f, -0.063f)\n            curveToRelative(0.117f, -0.042f, 0.225f, -0.112f, 0.325f, -0.213f)\n            lineToRelative(4.6f, -4.6f)\n            curveToRelative(0.1f, -0.1f, 0.171f, -0.208f, 0.213f, -0.325f)\n            curveToRelative(0.042f, -0.117f, 0.063f, -0.242f, 0.063f, -0.375f)\n            reflectiveCurveToRelative(-0.021f, -0.258f, -0.063f, -0.375f)\n            close()\n            moveTo(17f, 16.15f)\n            lineToRelative(-3.15f, -3.15f)\n            lineToRelative(3.15f, -3.15f)\n            lineToRelative(3.15f, 3.15f)\n            lineToRelative(-3.15f, 3.15f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(13.85f, 13f)\n            lineToRelative(3.15f, -3.15f)\n            lineToRelative(3.15f, 3.15f)\n            lineToRelative(-3.15f, 3.15f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Routine.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Routine: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Routine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(453f, 508f)\n            quadTo(504f, 559f, 567f, 595.5f)\n            quadTo(630f, 632f, 702f, 652f)\n            quadTo(662f, 703f, 604f, 731.5f)\n            quadTo(546f, 760f, 481f, 760f)\n            quadTo(364f, 760f, 282.5f, 678.5f)\n            quadTo(201f, 597f, 201f, 480f)\n            quadTo(201f, 415f, 229.5f, 357f)\n            quadTo(258f, 299f, 309f, 259f)\n            quadTo(329f, 331f, 365.5f, 394f)\n            quadTo(402f, 457f, 453f, 508f)\n            close()\n            moveTo(743f, 580f)\n            quadTo(723f, 575f, 703.5f, 569f)\n            quadTo(684f, 563f, 665f, 555f)\n            quadTo(673f, 537f, 676.5f, 518.5f)\n            quadTo(680f, 500f, 680f, 480f)\n            quadTo(680f, 397f, 621.5f, 338.5f)\n            quadTo(563f, 280f, 480f, 280f)\n            quadTo(460f, 280f, 441.5f, 283.5f)\n            quadTo(423f, 287f, 405f, 295f)\n            quadTo(397f, 276f, 391.5f, 257f)\n            quadTo(386f, 238f, 381f, 218f)\n            quadTo(405f, 209f, 430f, 204.5f)\n            quadTo(455f, 200f, 481f, 200f)\n            quadTo(598f, 200f, 679.5f, 281.5f)\n            quadTo(761f, 363f, 761f, 480f)\n            quadTo(761f, 506f, 756.5f, 531f)\n            quadTo(752f, 556f, 743f, 580f)\n            close()\n            moveTo(440f, 120f)\n            lineTo(440f, 0f)\n            lineTo(520f, 0f)\n            lineTo(520f, 120f)\n            lineTo(440f, 120f)\n            close()\n            moveTo(440f, 960f)\n            lineTo(440f, 840f)\n            lineTo(520f, 840f)\n            lineTo(520f, 960f)\n            lineTo(440f, 960f)\n            close()\n            moveTo(763f, 254f)\n            lineTo(706f, 197f)\n            lineTo(791f, 113f)\n            lineTo(848f, 169f)\n            lineTo(763f, 254f)\n            close()\n            moveTo(169f, 847f)\n            lineTo(112f, 791f)\n            lineTo(197f, 706f)\n            lineTo(254f, 763f)\n            lineTo(169f, 847f)\n            close()\n            moveTo(840f, 520f)\n            lineTo(840f, 440f)\n            lineTo(960f, 440f)\n            lineTo(960f, 520f)\n            lineTo(840f, 520f)\n            close()\n            moveTo(0f, 520f)\n            lineTo(0f, 440f)\n            lineTo(120f, 440f)\n            lineTo(120f, 520f)\n            lineTo(0f, 520f)\n            close()\n            moveTo(791f, 848f)\n            lineTo(706f, 763f)\n            lineTo(763f, 706f)\n            lineTo(847f, 791f)\n            lineTo(791f, 848f)\n            close()\n            moveTo(197f, 254f)\n            lineTo(113f, 169f)\n            lineTo(169f, 112f)\n            lineTo(254f, 197f)\n            lineTo(197f, 254f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SamsungLetter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SamsungLetter: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.SamsungLetter\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF010101))) {\n            moveTo(13.706f, 15.551f)\n            curveToRelative(0.163f, 0.401f, 0.113f, 0.919f, 0.036f, 1.231f)\n            curveToRelative(-0.139f, 0.551f, -0.514f, 1.115f, -1.616f, 1.115f)\n            curveToRelative(-1.042f, 0f, -1.672f, -0.597f, -1.672f, -1.506f)\n            verticalLineToRelative(-1.606f)\n            horizontalLineToRelative(-4.452f)\n            lineToRelative(-0.003f, 1.284f)\n            curveToRelative(0f, 3.699f, 2.913f, 4.817f, 6.034f, 4.817f)\n            curveToRelative(3.002f, 0f, 5.474f, -1.025f, 5.865f, -3.791f)\n            curveToRelative(0.202f, -1.433f, 0.05f, -2.372f, -0.017f, -2.727f)\n            curveToRelative(-0.7f, -3.473f, -6.999f, -4.511f, -7.467f, -6.452f)\n            curveToRelative(-0.08f, -0.331f, -0.056f, -0.687f, -0.017f, -0.876f)\n            curveToRelative(0.116f, -0.527f, 0.478f, -1.111f, 1.516f, -1.111f)\n            curveToRelative(0.969f, 0f, 1.542f, 0.601f, 1.542f, 1.506f)\n            verticalLineToRelative(1.025f)\n            horizontalLineToRelative(4.136f)\n            verticalLineToRelative(-1.164f)\n            curveToRelative(0f, -3.616f, -3.244f, -4.18f, -5.593f, -4.18f)\n            curveToRelative(-2.952f, 0f, -5.364f, 0.975f, -5.805f, 3.675f)\n            curveToRelative(-0.119f, 0.746f, -0.136f, 1.41f, 0.036f, 2.243f)\n            curveToRelative(0.726f, 3.387f, 6.618f, 4.369f, 7.474f, 6.518f)\n            lineToRelative(0.001f, -0.001f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SaveConfirm.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SaveConfirm: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.SaveConfirm\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(14f, 12.8f)\n            curveTo(13.5f, 12.31f, 12.78f, 12f, 12f, 12f)\n            curveTo(10.34f, 12f, 9f, 13.34f, 9f, 15f)\n            curveTo(9f, 16.31f, 9.84f, 17.41f, 11f, 17.82f)\n            curveTo(11.07f, 15.67f, 12.27f, 13.8f, 14f, 12.8f)\n            moveTo(11.09f, 19f)\n            horizontalLineTo(5f)\n            verticalLineTo(5f)\n            horizontalLineTo(16.17f)\n            lineTo(19f, 7.83f)\n            verticalLineTo(12.35f)\n            curveTo(19.75f, 12.61f, 20.42f, 13f, 21f, 13.54f)\n            verticalLineTo(7f)\n            lineTo(17f, 3f)\n            horizontalLineTo(5f)\n            curveTo(3.89f, 3f, 3f, 3.9f, 3f, 5f)\n            verticalLineTo(19f)\n            curveTo(3f, 20.1f, 3.89f, 21f, 5f, 21f)\n            horizontalLineTo(11.81f)\n            curveTo(11.46f, 20.39f, 11.21f, 19.72f, 11.09f, 19f)\n            moveTo(6f, 10f)\n            horizontalLineTo(15f)\n            verticalLineTo(6f)\n            horizontalLineTo(6f)\n            verticalLineTo(10f)\n            moveTo(15.75f, 21f)\n            lineTo(13f, 18f)\n            lineTo(14.16f, 16.84f)\n            lineTo(15.75f, 18.43f)\n            lineTo(19.34f, 14.84f)\n            lineTo(20.5f, 16.25f)\n            lineTo(15.75f, 21f)\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ScaleUnbalanced.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ScaleUnbalanced: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"ScaleUnbalanced\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(13f, 20f)\n            verticalLineTo(8.8f)\n            curveTo(13.5f, 8.6f, 14f, 8.3f, 14.3f, 7.9f)\n            lineTo(17.8f, 9.2f)\n            lineTo(14.9f, 16f)\n            curveTo(14.4f, 18f, 15.9f, 19f, 18.4f, 19f)\n            reflectiveCurveTo(22.5f, 18f, 21.9f, 16f)\n            lineTo(19.3f, 9.7f)\n            lineTo(20.2f, 10f)\n            lineTo(20.9f, 8.1f)\n            lineTo(15f, 6f)\n            curveTo(15f, 4.8f, 14.3f, 3.6f, 13f, 3.1f)\n            curveTo(11.8f, 2.6f, 10.5f, 3.1f, 9.7f, 4f)\n            lineTo(3.9f, 2f)\n            lineTo(3.2f, 3.8f)\n            lineTo(4.8f, 4.4f)\n            lineTo(2.1f, 11f)\n            curveTo(1.6f, 13f, 3.1f, 14f, 5.6f, 14f)\n            reflectiveCurveTo(9.7f, 13f, 9.1f, 11f)\n            lineTo(6.6f, 5.1f)\n            lineTo(9f, 6f)\n            curveTo(9f, 7.2f, 9.7f, 8.4f, 11f, 8.9f)\n            verticalLineTo(20f)\n            horizontalLineTo(2f)\n            verticalLineTo(22f)\n            horizontalLineTo(22f)\n            verticalLineTo(20f)\n            horizontalLineTo(13f)\n            moveTo(19.9f, 16f)\n            horizontalLineTo(16.9f)\n            lineTo(18.4f, 12.2f)\n            lineTo(19.9f, 16f)\n            moveTo(7.1f, 11f)\n            horizontalLineTo(4.1f)\n            lineTo(5.6f, 7.2f)\n            lineTo(7.1f, 11f)\n            moveTo(11.1f, 5.7f)\n            curveTo(11.3f, 5.2f, 11.9f, 4.9f, 12.4f, 5.1f)\n            reflectiveCurveTo(13.2f, 5.9f, 13f, 6.4f)\n            reflectiveCurveTo(12.2f, 7.2f, 11.7f, 7f)\n            reflectiveCurveTo(10.9f, 6.2f, 11.1f, 5.7f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Scanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Scanner: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Scanner\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17.6f, 12f)\n            lineTo(4.45f, 7.25f)\n            curveToRelative(-0.267f, -0.1f, -0.458f, -0.275f, -0.575f, -0.525f)\n            reflectiveCurveToRelative(-0.125f, -0.508f, -0.025f, -0.775f)\n            reflectiveCurveToRelative(0.275f, -0.458f, 0.525f, -0.575f)\n            reflectiveCurveToRelative(0.508f, -0.125f, 0.775f, -0.025f)\n            lineToRelative(14.65f, 5.35f)\n            curveToRelative(0.333f, 0.133f, 0.617f, 0.367f, 0.85f, 0.7f)\n            curveToRelative(0.233f, 0.333f, 0.35f, 0.7f, 0.35f, 1.1f)\n            verticalLineToRelative(5.5f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(5f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(12.6f)\n            close()\n            moveTo(19f, 18f)\n            verticalLineToRelative(-4f)\n            horizontalLineTo(5f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(14f)\n            close()\n            moveTo(11f, 17f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n            moveTo(7.713f, 16.712f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.712f, -0.287f)\n            close()\n            moveTo(5f, 18f)\n            verticalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Scanner: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Scanner\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.65f, 11.4f)\n            curveToRelative(-0.233f, -0.333f, -0.517f, -0.567f, -0.85f, -0.7f)\n            lineTo(5.15f, 5.35f)\n            curveToRelative(-0.267f, -0.1f, -0.525f, -0.092f, -0.775f, 0.025f)\n            reflectiveCurveToRelative(-0.425f, 0.308f, -0.525f, 0.575f)\n            curveToRelative(-0.1f, 0.267f, -0.092f, 0.525f, 0.025f, 0.775f)\n            reflectiveCurveToRelative(0.308f, 0.425f, 0.575f, 0.525f)\n            lineToRelative(13.15f, 4.75f)\n            horizontalLineTo(5f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(14f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineToRelative(-5.5f)\n            curveToRelative(0f, -0.4f, -0.117f, -0.767f, -0.35f, -1.1f)\n            close()\n            moveTo(19f, 18f)\n            horizontalLineTo(5f)\n            verticalLineToRelative(-4f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(4f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 17f)\n            horizontalLineToRelative(6f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(7.713f, 16.712f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.096f, -0.521f, -0.287f, -0.712f)\n            reflectiveCurveToRelative(-0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            reflectiveCurveToRelative(0.096f, 0.521f, 0.287f, 0.712f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.712f, -0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 18f)\n            verticalLineToRelative(-4f)\n            verticalLineToRelative(4f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 14f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(4f)\n            horizontalLineToRelative(-14f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Scissors.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.TwoTone.Scissors: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Scissors\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 14f)\n            lineToRelative(-2.35f, 2.35f)\n            curveToRelative(0.133f, 0.25f, 0.225f, 0.517f, 0.275f, 0.8f)\n            reflectiveCurveToRelative(0.075f, 0.567f, 0.075f, 0.85f)\n            curveToRelative(0f, 1.1f, -0.392f, 2.042f, -1.175f, 2.825f)\n            curveToRelative(-0.783f, 0.783f, -1.725f, 1.175f, -2.825f, 1.175f)\n            reflectiveCurveToRelative(-2.042f, -0.392f, -2.825f, -1.175f)\n            curveToRelative(-0.783f, -0.783f, -1.175f, -1.725f, -1.175f, -2.825f)\n            reflectiveCurveToRelative(0.392f, -2.042f, 1.175f, -2.825f)\n            curveToRelative(0.783f, -0.783f, 1.725f, -1.175f, 2.825f, -1.175f)\n            curveToRelative(0.283f, 0f, 0.567f, 0.025f, 0.85f, 0.075f)\n            reflectiveCurveToRelative(0.55f, 0.142f, 0.8f, 0.275f)\n            lineToRelative(2.35f, -2.35f)\n            lineToRelative(-2.35f, -2.35f)\n            curveToRelative(-0.25f, 0.133f, -0.517f, 0.225f, -0.8f, 0.275f)\n            reflectiveCurveToRelative(-0.567f, 0.075f, -0.85f, 0.075f)\n            curveToRelative(-1.1f, 0f, -2.042f, -0.392f, -2.825f, -1.175f)\n            curveToRelative(-0.783f, -0.783f, -1.175f, -1.725f, -1.175f, -2.825f)\n            reflectiveCurveToRelative(0.392f, -2.042f, 1.175f, -2.825f)\n            curveToRelative(0.783f, -0.783f, 1.725f, -1.175f, 2.825f, -1.175f)\n            reflectiveCurveToRelative(2.042f, 0.392f, 2.825f, 1.175f)\n            reflectiveCurveToRelative(1.175f, 1.725f, 1.175f, 2.825f)\n            curveToRelative(0f, 0.283f, -0.025f, 0.567f, -0.075f, 0.85f)\n            reflectiveCurveToRelative(-0.142f, 0.55f, -0.275f, 0.8f)\n            lineToRelative(10.95f, 10.95f)\n            curveToRelative(0.45f, 0.45f, 0.55f, 0.962f, 0.3f, 1.538f)\n            reflectiveCurveToRelative(-0.692f, 0.863f, -1.325f, 0.863f)\n            curveToRelative(-0.183f, 0f, -0.363f, -0.038f, -0.538f, -0.112f)\n            reflectiveCurveToRelative(-0.329f, -0.179f, -0.463f, -0.313f)\n            lineToRelative(-6.575f, -6.575f)\n            close()\n            moveTo(15f, 11f)\n            lineToRelative(-2f, -2f)\n            lineToRelative(5.575f, -5.575f)\n            curveToRelative(0.133f, -0.133f, 0.287f, -0.237f, 0.463f, -0.313f)\n            reflectiveCurveToRelative(0.354f, -0.112f, 0.538f, -0.112f)\n            curveToRelative(0.633f, 0f, 1.071f, 0.292f, 1.313f, 0.875f)\n            reflectiveCurveToRelative(0.138f, 1.1f, -0.313f, 1.55f)\n            lineToRelative(-5.575f, 5.575f)\n            close()\n            moveTo(6f, 8f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.587f)\n            reflectiveCurveToRelative(0.587f, -0.863f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.196f, -1.021f, -0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.863f, -0.587f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.413f, 0.587f)\n            reflectiveCurveToRelative(-0.587f, 0.863f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(0.196f, 1.021f, 0.587f, 1.413f)\n            reflectiveCurveToRelative(0.863f, 0.587f, 1.413f, 0.587f)\n            close()\n            moveTo(12f, 12.5f)\n            curveToRelative(0.133f, 0f, 0.25f, -0.05f, 0.35f, -0.15f)\n            reflectiveCurveToRelative(0.15f, -0.217f, 0.15f, -0.35f)\n            reflectiveCurveToRelative(-0.05f, -0.25f, -0.15f, -0.35f)\n            reflectiveCurveToRelative(-0.217f, -0.15f, -0.35f, -0.15f)\n            reflectiveCurveToRelative(-0.25f, 0.05f, -0.35f, 0.15f)\n            reflectiveCurveToRelative(-0.15f, 0.217f, -0.15f, 0.35f)\n            reflectiveCurveToRelative(0.05f, 0.25f, 0.15f, 0.35f)\n            reflectiveCurveToRelative(0.217f, 0.15f, 0.35f, 0.15f)\n            close()\n            moveTo(6f, 20f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.587f)\n            reflectiveCurveToRelative(0.587f, -0.863f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.196f, -1.021f, -0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.863f, -0.587f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.413f, 0.587f)\n            reflectiveCurveToRelative(-0.587f, 0.863f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(0.196f, 1.021f, 0.587f, 1.413f)\n            reflectiveCurveToRelative(0.863f, 0.587f, 1.413f, 0.587f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6f, 4f)\n            lineTo(6f, 4f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8f, 6f)\n            lineTo(8f, 6f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6f, 8f)\n            lineTo(6f, 8f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 4f, 6f)\n            lineTo(4f, 6f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6f, 4f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6f, 16f)\n            lineTo(6f, 16f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8f, 18f)\n            lineTo(8f, 18f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6f, 20f)\n            lineTo(6f, 20f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 4f, 18f)\n            lineTo(4f, 18f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 6f, 16f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12.008f, 11.5f)\n            lineTo(12.008f, 11.5f)\n            arcTo(0.5f, 0.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12.508f, 12f)\n            lineTo(12.508f, 12f)\n            arcTo(0.5f, 0.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12.008f, 12.5f)\n            lineTo(12.008f, 12.5f)\n            arcTo(0.5f, 0.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 11.508f, 12f)\n            lineTo(11.508f, 12f)\n            arcTo(0.5f, 0.5f, 0f, isMoreThanHalf = false, isPositiveArc = true, 12.008f, 11.5f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Scissors: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Scissors\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 14f)\n            lineToRelative(-2.35f, 2.35f)\n            curveToRelative(0.133f, 0.25f, 0.225f, 0.517f, 0.275f, 0.8f)\n            reflectiveCurveToRelative(0.075f, 0.567f, 0.075f, 0.85f)\n            curveToRelative(0f, 1.1f, -0.392f, 2.042f, -1.175f, 2.825f)\n            curveToRelative(-0.783f, 0.783f, -1.725f, 1.175f, -2.825f, 1.175f)\n            reflectiveCurveToRelative(-2.042f, -0.392f, -2.825f, -1.175f)\n            curveToRelative(-0.783f, -0.783f, -1.175f, -1.725f, -1.175f, -2.825f)\n            reflectiveCurveToRelative(0.392f, -2.042f, 1.175f, -2.825f)\n            curveToRelative(0.783f, -0.783f, 1.725f, -1.175f, 2.825f, -1.175f)\n            curveToRelative(0.283f, 0f, 0.567f, 0.025f, 0.85f, 0.075f)\n            reflectiveCurveToRelative(0.55f, 0.142f, 0.8f, 0.275f)\n            lineToRelative(2.35f, -2.35f)\n            lineToRelative(-2.35f, -2.35f)\n            curveToRelative(-0.25f, 0.133f, -0.517f, 0.225f, -0.8f, 0.275f)\n            reflectiveCurveToRelative(-0.567f, 0.075f, -0.85f, 0.075f)\n            curveToRelative(-1.1f, 0f, -2.042f, -0.392f, -2.825f, -1.175f)\n            curveToRelative(-0.783f, -0.783f, -1.175f, -1.725f, -1.175f, -2.825f)\n            reflectiveCurveToRelative(0.392f, -2.042f, 1.175f, -2.825f)\n            curveToRelative(0.783f, -0.783f, 1.725f, -1.175f, 2.825f, -1.175f)\n            reflectiveCurveToRelative(2.042f, 0.392f, 2.825f, 1.175f)\n            reflectiveCurveToRelative(1.175f, 1.725f, 1.175f, 2.825f)\n            curveToRelative(0f, 0.283f, -0.025f, 0.567f, -0.075f, 0.85f)\n            reflectiveCurveToRelative(-0.142f, 0.55f, -0.275f, 0.8f)\n            lineToRelative(10.95f, 10.95f)\n            curveToRelative(0.45f, 0.45f, 0.55f, 0.962f, 0.3f, 1.538f)\n            reflectiveCurveToRelative(-0.692f, 0.863f, -1.325f, 0.863f)\n            curveToRelative(-0.183f, 0f, -0.363f, -0.038f, -0.538f, -0.112f)\n            reflectiveCurveToRelative(-0.329f, -0.179f, -0.463f, -0.313f)\n            lineToRelative(-6.575f, -6.575f)\n            close()\n            moveTo(15f, 11f)\n            lineToRelative(-2f, -2f)\n            lineToRelative(5.575f, -5.575f)\n            curveToRelative(0.133f, -0.133f, 0.287f, -0.237f, 0.463f, -0.313f)\n            reflectiveCurveToRelative(0.354f, -0.112f, 0.538f, -0.112f)\n            curveToRelative(0.633f, 0f, 1.071f, 0.292f, 1.313f, 0.875f)\n            reflectiveCurveToRelative(0.138f, 1.1f, -0.313f, 1.55f)\n            lineToRelative(-5.575f, 5.575f)\n            close()\n            moveTo(6f, 8f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.587f)\n            reflectiveCurveToRelative(0.587f, -0.863f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.196f, -1.021f, -0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.863f, -0.587f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.413f, 0.587f)\n            reflectiveCurveToRelative(-0.587f, 0.863f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(0.196f, 1.021f, 0.587f, 1.413f)\n            reflectiveCurveToRelative(0.863f, 0.587f, 1.413f, 0.587f)\n            close()\n            moveTo(12f, 12.5f)\n            curveToRelative(0.133f, 0f, 0.25f, -0.05f, 0.35f, -0.15f)\n            reflectiveCurveToRelative(0.15f, -0.217f, 0.15f, -0.35f)\n            reflectiveCurveToRelative(-0.05f, -0.25f, -0.15f, -0.35f)\n            reflectiveCurveToRelative(-0.217f, -0.15f, -0.35f, -0.15f)\n            reflectiveCurveToRelative(-0.25f, 0.05f, -0.35f, 0.15f)\n            reflectiveCurveToRelative(-0.15f, 0.217f, -0.15f, 0.35f)\n            reflectiveCurveToRelative(0.05f, 0.25f, 0.15f, 0.35f)\n            reflectiveCurveToRelative(0.217f, 0.15f, 0.35f, 0.15f)\n            close()\n            moveTo(6f, 20f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.413f, -0.587f)\n            reflectiveCurveToRelative(0.587f, -0.863f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.196f, -1.021f, -0.587f, -1.413f)\n            reflectiveCurveToRelative(-0.863f, -0.587f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.413f, 0.587f)\n            reflectiveCurveToRelative(-0.587f, 0.863f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(0.196f, 1.021f, 0.587f, 1.413f)\n            reflectiveCurveToRelative(0.863f, 0.587f, 1.413f, 0.587f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ScissorsSmall.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ScissorsSmall: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ScissorsSmall\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.3f, 20.1f)\n            lineToRelative(-6.3f, -6.3f)\n            lineToRelative(-2.115f, 2.115f)\n            curveToRelative(0.12f, 0.225f, 0.203f, 0.465f, 0.248f, 0.72f)\n            reflectiveCurveToRelative(0.068f, 0.51f, 0.068f, 0.765f)\n            curveToRelative(0f, 0.99f, -0.352f, 1.838f, -1.058f, 2.543f)\n            curveToRelative(-0.705f, 0.705f, -1.553f, 1.058f, -2.543f, 1.058f)\n            reflectiveCurveToRelative(-1.838f, -0.352f, -2.543f, -1.058f)\n            curveToRelative(-0.705f, -0.705f, -1.058f, -1.553f, -1.058f, -2.543f)\n            reflectiveCurveToRelative(0.352f, -1.837f, 1.058f, -2.543f)\n            curveToRelative(0.705f, -0.705f, 1.553f, -1.058f, 2.543f, -1.058f)\n            curveToRelative(0.255f, 0f, 0.51f, 0.023f, 0.765f, 0.068f)\n            reflectiveCurveToRelative(0.495f, 0.127f, 0.72f, 0.248f)\n            lineToRelative(2.115f, -2.115f)\n            lineToRelative(-2.115f, -2.115f)\n            curveToRelative(-0.225f, 0.12f, -0.465f, 0.203f, -0.72f, 0.248f)\n            reflectiveCurveToRelative(-0.51f, 0.068f, -0.765f, 0.068f)\n            curveToRelative(-0.99f, 0f, -1.838f, -0.353f, -2.543f, -1.058f)\n            curveToRelative(-0.705f, -0.705f, -1.058f, -1.553f, -1.058f, -2.543f)\n            reflectiveCurveToRelative(0.352f, -1.838f, 1.058f, -2.543f)\n            curveToRelative(0.705f, -0.705f, 1.553f, -1.058f, 2.543f, -1.058f)\n            reflectiveCurveToRelative(1.837f, 0.353f, 2.543f, 1.058f)\n            reflectiveCurveToRelative(1.058f, 1.553f, 1.058f, 2.543f)\n            curveToRelative(0f, 0.255f, -0.023f, 0.51f, -0.068f, 0.765f)\n            reflectiveCurveToRelative(-0.127f, 0.495f, -0.248f, 0.72f)\n            lineToRelative(11.115f, 11.115f)\n            verticalLineToRelative(0.9f)\n            horizontalLineToRelative(-2.7f)\n            close()\n            moveTo(14.7f, 11.1f)\n            lineToRelative(-1.8f, -1.8f)\n            lineToRelative(5.4f, -5.4f)\n            horizontalLineToRelative(2.7f)\n            verticalLineToRelative(0.9f)\n            lineToRelative(-6.3f, 6.3f)\n            close()\n            moveTo(7.871f, 7.871f)\n            curveToRelative(0.352f, -0.353f, 0.529f, -0.776f, 0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.176f, -0.919f, -0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.776f, -0.529f, -1.271f, -0.529f)\n            reflectiveCurveToRelative(-0.919f, 0.176f, -1.271f, 0.529f)\n            reflectiveCurveToRelative(-0.529f, 0.776f, -0.529f, 1.271f)\n            reflectiveCurveToRelative(0.176f, 0.919f, 0.529f, 1.271f)\n            reflectiveCurveToRelative(0.776f, 0.529f, 1.271f, 0.529f)\n            reflectiveCurveToRelative(0.919f, -0.176f, 1.271f, -0.529f)\n            close()\n            moveTo(12.315f, 12.315f)\n            curveToRelative(0.09f, -0.09f, 0.135f, -0.195f, 0.135f, -0.315f)\n            reflectiveCurveToRelative(-0.045f, -0.225f, -0.135f, -0.315f)\n            reflectiveCurveToRelative(-0.195f, -0.135f, -0.315f, -0.135f)\n            reflectiveCurveToRelative(-0.225f, 0.045f, -0.315f, 0.135f)\n            reflectiveCurveToRelative(-0.135f, 0.195f, -0.135f, 0.315f)\n            reflectiveCurveToRelative(0.045f, 0.225f, 0.135f, 0.315f)\n            reflectiveCurveToRelative(0.195f, 0.135f, 0.315f, 0.135f)\n            reflectiveCurveToRelative(0.225f, -0.045f, 0.315f, -0.135f)\n            close()\n            moveTo(7.871f, 18.671f)\n            curveToRelative(0.352f, -0.353f, 0.529f, -0.776f, 0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.176f, -0.919f, -0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.776f, -0.529f, -1.271f, -0.529f)\n            reflectiveCurveToRelative(-0.919f, 0.176f, -1.271f, 0.529f)\n            reflectiveCurveToRelative(-0.529f, 0.776f, -0.529f, 1.271f)\n            reflectiveCurveToRelative(0.176f, 0.919f, 0.529f, 1.271f)\n            reflectiveCurveToRelative(0.776f, 0.529f, 1.271f, 0.529f)\n            reflectiveCurveToRelative(0.919f, -0.176f, 1.271f, -0.529f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ScissorsSmall: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ScissorsSmall\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.7f, 11.1f)\n            lineToRelative(-1.8f, -1.8f)\n            lineToRelative(5.4f, -5.4f)\n            lineToRelative(2.7f, 0f)\n            lineToRelative(0f, 0.9f)\n            lineToRelative(-6.3f, 6.3f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9.885f, 8.085f)\n            curveToRelative(0.12f, -0.225f, 0.203f, -0.465f, 0.247f, -0.72f)\n            reflectiveCurveToRelative(0.068f, -0.51f, 0.068f, -0.765f)\n            curveToRelative(0f, -0.99f, -0.353f, -1.837f, -1.057f, -2.542f)\n            curveToRelative(-0.705f, -0.705f, -1.552f, -1.057f, -2.543f, -1.057f)\n            curveToRelative(-0.99f, 0f, -1.837f, 0.352f, -2.542f, 1.057f)\n            reflectiveCurveToRelative(-1.057f, 1.552f, -1.057f, 2.542f)\n            curveToRelative(0f, 0.99f, 0.352f, 1.838f, 1.057f, 2.543f)\n            curveToRelative(0.705f, 0.705f, 1.552f, 1.057f, 2.542f, 1.057f)\n            curveToRelative(0.255f, 0f, 0.51f, -0.023f, 0.765f, -0.068f)\n            reflectiveCurveToRelative(0.495f, -0.128f, 0.72f, -0.247f)\n            lineToRelative(2.115f, 2.115f)\n            lineToRelative(-2.115f, 2.115f)\n            curveToRelative(-0.225f, -0.12f, -0.465f, -0.203f, -0.72f, -0.247f)\n            reflectiveCurveToRelative(-0.51f, -0.068f, -0.765f, -0.068f)\n            curveToRelative(-0.99f, 0f, -1.837f, 0.353f, -2.542f, 1.057f)\n            curveToRelative(-0.705f, 0.705f, -1.057f, 1.552f, -1.057f, 2.543f)\n            curveToRelative(0f, 0.99f, 0.352f, 1.837f, 1.057f, 2.542f)\n            reflectiveCurveToRelative(1.552f, 1.057f, 2.542f, 1.057f)\n            curveToRelative(0.99f, 0f, 1.838f, -0.352f, 2.543f, -1.057f)\n            curveToRelative(0.705f, -0.705f, 1.057f, -1.552f, 1.057f, -2.542f)\n            curveToRelative(0f, -0.255f, -0.023f, -0.51f, -0.068f, -0.765f)\n            reflectiveCurveToRelative(-0.128f, -0.495f, -0.247f, -0.72f)\n            lineToRelative(2.115f, -2.115f)\n            lineToRelative(6.3f, 6.3f)\n            horizontalLineToRelative(2.7f)\n            verticalLineToRelative(-0.9f)\n            lineToRelative(-11.115f, -11.115f)\n            close()\n            moveTo(7.871f, 7.871f)\n            curveToRelative(-0.353f, 0.352f, -0.776f, 0.529f, -1.271f, 0.529f)\n            reflectiveCurveToRelative(-0.919f, -0.176f, -1.271f, -0.529f)\n            curveToRelative(-0.352f, -0.353f, -0.529f, -0.776f, -0.529f, -1.271f)\n            reflectiveCurveToRelative(0.176f, -0.919f, 0.529f, -1.271f)\n            curveToRelative(0.353f, -0.352f, 0.776f, -0.529f, 1.271f, -0.529f)\n            reflectiveCurveToRelative(0.919f, 0.176f, 1.271f, 0.529f)\n            curveToRelative(0.352f, 0.353f, 0.529f, 0.776f, 0.529f, 1.271f)\n            reflectiveCurveToRelative(-0.176f, 0.919f, -0.529f, 1.271f)\n            close()\n            moveTo(7.871f, 18.671f)\n            curveToRelative(-0.353f, 0.352f, -0.776f, 0.529f, -1.271f, 0.529f)\n            reflectiveCurveToRelative(-0.919f, -0.176f, -1.271f, -0.529f)\n            curveToRelative(-0.352f, -0.353f, -0.529f, -0.776f, -0.529f, -1.271f)\n            reflectiveCurveToRelative(0.176f, -0.919f, 0.529f, -1.271f)\n            curveToRelative(0.353f, -0.352f, 0.776f, -0.529f, 1.271f, -0.529f)\n            reflectiveCurveToRelative(0.919f, 0.176f, 1.271f, 0.529f)\n            curveToRelative(0.352f, 0.353f, 0.529f, 0.776f, 0.529f, 1.271f)\n            reflectiveCurveToRelative(-0.176f, 0.919f, -0.529f, 1.271f)\n            close()\n            moveTo(12.315f, 12.315f)\n            curveToRelative(-0.09f, 0.09f, -0.195f, 0.135f, -0.315f, 0.135f)\n            reflectiveCurveToRelative(-0.225f, -0.045f, -0.315f, -0.135f)\n            reflectiveCurveToRelative(-0.135f, -0.195f, -0.135f, -0.315f)\n            reflectiveCurveToRelative(0.045f, -0.225f, 0.135f, -0.315f)\n            reflectiveCurveToRelative(0.195f, -0.135f, 0.315f, -0.135f)\n            reflectiveCurveToRelative(0.225f, 0.045f, 0.315f, 0.135f)\n            reflectiveCurveToRelative(0.135f, 0.195f, 0.135f, 0.315f)\n            reflectiveCurveToRelative(-0.045f, 0.225f, -0.135f, 0.315f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(7.871f, 7.871f)\n            curveToRelative(0.352f, -0.353f, 0.529f, -0.776f, 0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.176f, -0.919f, -0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.776f, -0.529f, -1.271f, -0.529f)\n            reflectiveCurveToRelative(-0.919f, 0.176f, -1.271f, 0.529f)\n            reflectiveCurveToRelative(-0.529f, 0.776f, -0.529f, 1.271f)\n            reflectiveCurveToRelative(0.176f, 0.919f, 0.529f, 1.271f)\n            reflectiveCurveToRelative(0.776f, 0.529f, 1.271f, 0.529f)\n            reflectiveCurveToRelative(0.919f, -0.176f, 1.271f, -0.529f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12.315f, 12.315f)\n            curveToRelative(0.09f, -0.09f, 0.135f, -0.195f, 0.135f, -0.315f)\n            reflectiveCurveToRelative(-0.045f, -0.225f, -0.135f, -0.315f)\n            reflectiveCurveToRelative(-0.195f, -0.135f, -0.315f, -0.135f)\n            reflectiveCurveToRelative(-0.225f, 0.045f, -0.315f, 0.135f)\n            reflectiveCurveToRelative(-0.135f, 0.195f, -0.135f, 0.315f)\n            reflectiveCurveToRelative(0.045f, 0.225f, 0.135f, 0.315f)\n            reflectiveCurveToRelative(0.195f, 0.135f, 0.315f, 0.135f)\n            reflectiveCurveToRelative(0.225f, -0.045f, 0.315f, -0.135f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(7.871f, 18.671f)\n            curveToRelative(0.352f, -0.353f, 0.529f, -0.776f, 0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.176f, -0.919f, -0.529f, -1.271f)\n            reflectiveCurveToRelative(-0.776f, -0.529f, -1.271f, -0.529f)\n            reflectiveCurveToRelative(-0.919f, 0.176f, -1.271f, 0.529f)\n            reflectiveCurveToRelative(-0.529f, 0.776f, -0.529f, 1.271f)\n            reflectiveCurveToRelative(0.176f, 0.919f, 0.529f, 1.271f)\n            reflectiveCurveToRelative(0.776f, 0.529f, 1.271f, 0.529f)\n            reflectiveCurveToRelative(0.919f, -0.176f, 1.271f, -0.529f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12.9f, 9.3f)\n            lineToRelative(1.8f, 1.8f)\n            lineToRelative(-0.9f, 0.9f)\n            lineToRelative(-1.8f, -1.8f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SelectAll.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SelectAll: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.SelectAll\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(131.5f, 188.5f)\n            quadTo(120f, 177f, 120f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 120f, 160f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 143f, 200f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 200f, 160f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(291.5f, 188.5f)\n            quadTo(280f, 177f, 280f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(303f, 120f, 320f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(360f, 143f, 360f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(337f, 200f, 320f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(451.5f, 188.5f)\n            quadTo(440f, 177f, 440f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(463f, 120f, 480f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(520f, 143f, 520f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(497f, 200f, 480f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(611.5f, 188.5f)\n            quadTo(600f, 177f, 600f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(623f, 120f, 640f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(680f, 143f, 680f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(657f, 200f, 640f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 188.5f)\n            quadTo(760f, 177f, 760f, 160f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 120f, 800f, 120f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 143f, 840f, 160f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 200f, 800f, 200f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 348.5f)\n            quadTo(120f, 337f, 120f, 320f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 280f, 160f, 280f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 303f, 200f, 320f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 360f, 160f, 360f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 348.5f)\n            quadTo(760f, 337f, 760f, 320f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 280f, 800f, 280f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 303f, 840f, 320f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 360f, 800f, 360f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 508.5f)\n            quadTo(120f, 497f, 120f, 480f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 440f, 160f, 440f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 463f, 200f, 480f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 520f, 160f, 520f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 508.5f)\n            quadTo(760f, 497f, 760f, 480f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 440f, 800f, 440f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 463f, 840f, 480f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 520f, 800f, 520f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 668.5f)\n            quadTo(120f, 657f, 120f, 640f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 600f, 160f, 600f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 623f, 200f, 640f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 680f, 160f, 680f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 668.5f)\n            quadTo(760f, 657f, 760f, 640f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 600f, 800f, 600f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 623f, 840f, 640f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 680f, 800f, 680f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(131.5f, 828.5f)\n            quadTo(120f, 817f, 120f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 760f, 160f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 783f, 200f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 840f, 160f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(291.5f, 828.5f)\n            quadTo(280f, 817f, 280f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(303f, 760f, 320f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(360f, 783f, 360f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(337f, 840f, 320f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(451.5f, 828.5f)\n            quadTo(440f, 817f, 440f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(463f, 760f, 480f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(520f, 783f, 520f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(497f, 840f, 480f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(611.5f, 828.5f)\n            quadTo(600f, 817f, 600f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(623f, 760f, 640f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(680f, 783f, 680f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(657f, 840f, 640f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 828.5f)\n            quadTo(760f, 817f, 760f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 760f, 800f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 783f, 840f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 840f, 800f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(360f, 680f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(280f, 600f)\n            verticalLineToRelative(-240f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(360f, 280f)\n            horizontalLineToRelative(240f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(680f, 360f)\n            verticalLineToRelative(240f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(600f, 680f)\n            lineTo(360f, 680f)\n            close()\n            moveTo(360f, 600f)\n            horizontalLineToRelative(240f)\n            verticalLineToRelative(-240f)\n            lineTo(360f, 360f)\n            verticalLineToRelative(240f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SelectInverse.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.SelectInverse: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Rounded.SelectInverse\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(5f, 3f)\n            horizontalLineTo(7f)\n            verticalLineTo(5f)\n            horizontalLineTo(9f)\n            verticalLineTo(3f)\n            horizontalLineTo(11f)\n            verticalLineTo(5f)\n            horizontalLineTo(13f)\n            verticalLineTo(3f)\n            horizontalLineTo(15f)\n            verticalLineTo(5f)\n            horizontalLineTo(17f)\n            verticalLineTo(3f)\n            horizontalLineTo(19f)\n            verticalLineTo(5f)\n            horizontalLineTo(21f)\n            verticalLineTo(7f)\n            horizontalLineTo(19f)\n            verticalLineTo(9f)\n            horizontalLineTo(21f)\n            verticalLineTo(11f)\n            horizontalLineTo(19f)\n            verticalLineTo(13f)\n            horizontalLineTo(21f)\n            verticalLineTo(15f)\n            horizontalLineTo(19f)\n            verticalLineTo(17f)\n            horizontalLineTo(21f)\n            verticalLineTo(19f)\n            horizontalLineTo(19f)\n            verticalLineTo(21f)\n            horizontalLineTo(17f)\n            verticalLineTo(19f)\n            horizontalLineTo(15f)\n            verticalLineTo(21f)\n            horizontalLineTo(13f)\n            verticalLineTo(19f)\n            horizontalLineTo(11f)\n            verticalLineTo(21f)\n            horizontalLineTo(9f)\n            verticalLineTo(19f)\n            horizontalLineTo(7f)\n            verticalLineTo(21f)\n            horizontalLineTo(5f)\n            verticalLineTo(19f)\n            horizontalLineTo(3f)\n            verticalLineTo(17f)\n            horizontalLineTo(5f)\n            verticalLineTo(15f)\n            horizontalLineTo(3f)\n            verticalLineTo(13f)\n            horizontalLineTo(5f)\n            verticalLineTo(11f)\n            horizontalLineTo(3f)\n            verticalLineTo(9f)\n            horizontalLineTo(5f)\n            verticalLineTo(7f)\n            horizontalLineTo(3f)\n            verticalLineTo(5f)\n            horizontalLineTo(5f)\n            verticalLineTo(3f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ServiceToolbox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ServiceToolbox: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.ServiceToolbox\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(160f, 800f)\n            quadTo(127f, 800f, 103.5f, 776.5f)\n            quadTo(80f, 753f, 80f, 720f)\n            lineTo(80f, 560f)\n            lineTo(280f, 560f)\n            lineTo(280f, 560f)\n            quadTo(280f, 577f, 291.5f, 588.5f)\n            quadTo(303f, 600f, 320f, 600f)\n            quadTo(336f, 600f, 342.5f, 585.5f)\n            quadTo(349f, 571f, 360f, 560f)\n            lineTo(360f, 560f)\n            lineTo(600f, 560f)\n            lineTo(600f, 560f)\n            quadTo(600f, 577f, 611.5f, 588.5f)\n            quadTo(623f, 600f, 640f, 600f)\n            quadTo(656f, 600f, 662.5f, 585.5f)\n            quadTo(669f, 571f, 680f, 560f)\n            lineTo(680f, 560f)\n            lineTo(880f, 560f)\n            lineTo(880f, 720f)\n            quadTo(880f, 753f, 856.5f, 776.5f)\n            quadTo(833f, 800f, 800f, 800f)\n            lineTo(160f, 800f)\n            close()\n            moveTo(97f, 480f)\n            lineTo(180f, 288f)\n            quadTo(189f, 266f, 209f, 253f)\n            quadTo(229f, 240f, 252f, 240f)\n            lineTo(280f, 240f)\n            lineTo(280f, 200f)\n            quadTo(280f, 167f, 303.5f, 143.5f)\n            quadTo(327f, 120f, 360f, 120f)\n            lineTo(600f, 120f)\n            quadTo(633f, 120f, 656.5f, 143.5f)\n            quadTo(680f, 167f, 680f, 200f)\n            lineTo(680f, 240f)\n            lineTo(708f, 240f)\n            quadTo(731f, 240f, 751f, 253f)\n            quadTo(771f, 266f, 780f, 288f)\n            lineTo(863f, 480f)\n            lineTo(680f, 480f)\n            lineTo(680f, 480f)\n            quadTo(680f, 463f, 668.5f, 451.5f)\n            quadTo(657f, 440f, 640f, 440f)\n            quadTo(624f, 440f, 617.5f, 454.5f)\n            quadTo(611f, 469f, 600f, 480f)\n            lineTo(600f, 480f)\n            lineTo(360f, 480f)\n            lineTo(360f, 480f)\n            quadTo(360f, 463f, 348.5f, 451.5f)\n            quadTo(337f, 440f, 320f, 440f)\n            quadTo(304f, 440f, 297.5f, 454.5f)\n            quadTo(291f, 469f, 280f, 480f)\n            lineTo(280f, 480f)\n            lineTo(97f, 480f)\n            close()\n            moveTo(360f, 240f)\n            lineTo(600f, 240f)\n            lineTo(600f, 200f)\n            lineTo(360f, 200f)\n            lineTo(360f, 240f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.ServiceToolbox: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ServiceToolbox\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 240f)\n            lineTo(280f, 200f)\n            quadTo(280f, 167f, 303.5f, 143.5f)\n            quadTo(327f, 120f, 360f, 120f)\n            lineTo(600f, 120f)\n            quadTo(633f, 120f, 656.5f, 143.5f)\n            quadTo(680f, 167f, 680f, 200f)\n            lineTo(680f, 240f)\n            lineTo(708f, 240f)\n            quadTo(731f, 240f, 751f, 253f)\n            quadTo(771f, 266f, 780f, 288f)\n            lineTo(874f, 504f)\n            quadTo(877f, 512f, 878.5f, 520f)\n            quadTo(880f, 528f, 880f, 536f)\n            lineTo(880f, 720f)\n            quadTo(880f, 753f, 856.5f, 776.5f)\n            quadTo(833f, 800f, 800f, 800f)\n            lineTo(160f, 800f)\n            quadTo(127f, 800f, 103.5f, 776.5f)\n            quadTo(80f, 753f, 80f, 720f)\n            lineTo(80f, 536f)\n            quadTo(80f, 528f, 81.5f, 520f)\n            quadTo(83f, 512f, 86f, 504f)\n            lineTo(180f, 288f)\n            quadTo(189f, 266f, 209f, 253f)\n            quadTo(229f, 240f, 252f, 240f)\n            lineTo(280f, 240f)\n            close()\n            moveTo(360f, 240f)\n            lineTo(600f, 240f)\n            lineTo(600f, 200f)\n            lineTo(360f, 200f)\n            lineTo(360f, 240f)\n            close()\n            moveTo(280f, 480f)\n            lineTo(280f, 479f)\n            quadTo(280f, 462f, 291.5f, 450.5f)\n            quadTo(303f, 439f, 320f, 439f)\n            quadTo(337f, 439f, 348.5f, 450.5f)\n            quadTo(360f, 462f, 360f, 479f)\n            lineTo(360f, 480f)\n            lineTo(600f, 480f)\n            lineTo(600f, 479f)\n            quadTo(600f, 462f, 611.5f, 450.5f)\n            quadTo(623f, 439f, 640f, 439f)\n            quadTo(657f, 439f, 668.5f, 450.5f)\n            quadTo(680f, 462f, 680f, 479f)\n            lineTo(680f, 480f)\n            lineTo(776f, 480f)\n            lineTo(708f, 320f)\n            lineTo(252f, 320f)\n            lineTo(184f, 480f)\n            lineTo(280f, 480f)\n            close()\n            moveTo(280f, 560f)\n            lineTo(160f, 560f)\n            lineTo(160f, 720f)\n            lineTo(800f, 720f)\n            lineTo(800f, 560f)\n            lineTo(680f, 560f)\n            lineTo(680f, 561f)\n            quadTo(680f, 578f, 668.5f, 589.5f)\n            quadTo(657f, 601f, 640f, 601f)\n            quadTo(623f, 601f, 611.5f, 589.5f)\n            quadTo(600f, 578f, 600f, 561f)\n            lineTo(600f, 560f)\n            lineTo(360f, 560f)\n            lineTo(360f, 561f)\n            quadTo(360f, 578f, 348.5f, 589.5f)\n            quadTo(337f, 601f, 320f, 601f)\n            quadTo(303f, 601f, 291.5f, 589.5f)\n            quadTo(280f, 578f, 280f, 561f)\n            lineTo(280f, 560f)\n            close()\n            moveTo(480f, 520f)\n            lineTo(480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            quadTo(480f, 520f, 480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            lineTo(480f, 520f)\n            close()\n            moveTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            close()\n            moveTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            lineTo(480f, 560f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SettingsTimelapse.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SettingsTimelapse: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"SettingsTimelapse\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(720f, 840f)\n            lineTo(720f, 600f)\n            lineTo(920f, 720f)\n            lineTo(720f, 840f)\n            close()\n            moveTo(520f, 840f)\n            lineTo(520f, 600f)\n            lineTo(720f, 720f)\n            lineTo(520f, 840f)\n            close()\n            moveTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            lineTo(480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            quadTo(480f, 480f, 480f, 480f)\n            close()\n            moveTo(370f, 880f)\n            lineTo(354f, 752f)\n            quadTo(341f, 747f, 329.5f, 740f)\n            quadTo(318f, 733f, 307f, 725f)\n            lineTo(188f, 775f)\n            lineTo(78f, 585f)\n            lineTo(181f, 507f)\n            quadTo(180f, 500f, 180f, 493.5f)\n            quadTo(180f, 487f, 180f, 480f)\n            quadTo(180f, 473f, 180f, 466.5f)\n            quadTo(180f, 460f, 181f, 453f)\n            lineTo(78f, 375f)\n            lineTo(188f, 185f)\n            lineTo(307f, 235f)\n            quadTo(318f, 227f, 330f, 220f)\n            quadTo(342f, 213f, 354f, 208f)\n            lineTo(370f, 80f)\n            lineTo(590f, 80f)\n            lineTo(606f, 208f)\n            quadTo(619f, 213f, 630.5f, 220f)\n            quadTo(642f, 227f, 653f, 235f)\n            lineTo(772f, 185f)\n            lineTo(882f, 375f)\n            lineTo(779f, 453f)\n            quadTo(780f, 460f, 780f, 466.5f)\n            quadTo(780f, 473f, 780f, 480f)\n            quadTo(780f, 490f, 780f, 500f)\n            quadTo(780f, 510f, 778f, 520f)\n            lineTo(696f, 520f)\n            quadTo(698f, 510f, 699f, 500f)\n            quadTo(700f, 490f, 700f, 480f)\n            quadTo(699f, 461f, 697f, 446.5f)\n            quadTo(695f, 432f, 691f, 419f)\n            lineTo(777f, 354f)\n            lineTo(738f, 286f)\n            lineTo(639f, 328f)\n            quadTo(617f, 305f, 590.5f, 289.5f)\n            quadTo(564f, 274f, 533f, 266f)\n            lineTo(520f, 160f)\n            lineTo(441f, 160f)\n            lineTo(427f, 266f)\n            quadTo(396f, 274f, 369.5f, 289.5f)\n            quadTo(343f, 305f, 321f, 327f)\n            lineTo(222f, 286f)\n            lineTo(183f, 354f)\n            lineTo(269f, 418f)\n            quadTo(264f, 433f, 262f, 448f)\n            quadTo(260f, 463f, 260f, 480f)\n            quadTo(260f, 496f, 262f, 511f)\n            quadTo(264f, 526f, 269f, 541f)\n            lineTo(183f, 606f)\n            lineTo(222f, 674f)\n            lineTo(321f, 632f)\n            quadTo(345f, 657f, 375f, 674f)\n            quadTo(405f, 691f, 440f, 696f)\n            lineTo(440f, 880f)\n            lineTo(370f, 880f)\n            close()\n            moveTo(440f, 614f)\n            lineTo(440f, 523f)\n            quadTo(432f, 515f, 427f, 504f)\n            quadTo(422f, 493f, 422f, 480f)\n            quadTo(422f, 455f, 439.5f, 437.5f)\n            quadTo(457f, 420f, 482f, 420f)\n            quadTo(507f, 420f, 524.5f, 437.5f)\n            quadTo(542f, 455f, 542f, 480f)\n            quadTo(542f, 491f, 538.5f, 501.5f)\n            quadTo(535f, 512f, 527f, 520f)\n            lineTo(616f, 520f)\n            quadTo(619f, 510f, 620.5f, 500.5f)\n            quadTo(622f, 491f, 622f, 480f)\n            quadTo(622f, 422f, 581f, 381f)\n            quadTo(540f, 340f, 482f, 340f)\n            quadTo(423f, 340f, 382.5f, 381f)\n            quadTo(342f, 422f, 342f, 480f)\n            quadTo(342f, 528f, 369.5f, 564f)\n            quadTo(397f, 600f, 440f, 614f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Shadow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Shadow: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Shadow\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(160f, 880f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(80f, 800f)\n            verticalLineToRelative(-480f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(160f, 240f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-80f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(320f, 80f)\n            horizontalLineToRelative(480f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(880f, 160f)\n            verticalLineToRelative(480f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(800f, 720f)\n            horizontalLineToRelative(-80f)\n            verticalLineToRelative(80f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(640f, 880f)\n            lineTo(160f, 880f)\n            close()\n            moveTo(320f, 640f)\n            horizontalLineToRelative(480f)\n            verticalLineToRelative(-480f)\n            lineTo(320f, 160f)\n            verticalLineToRelative(480f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ShareOff.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ShareOff: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ShareOff\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(680f, 800f)\n            quadTo(697f, 800f, 708.5f, 788.5f)\n            quadTo(720f, 777f, 720f, 760f)\n            quadTo(720f, 743f, 708.5f, 731.5f)\n            quadTo(697f, 720f, 680f, 720f)\n            quadTo(663f, 720f, 651.5f, 731.5f)\n            quadTo(640f, 743f, 640f, 760f)\n            quadTo(640f, 777f, 651.5f, 788.5f)\n            quadTo(663f, 800f, 680f, 800f)\n            close()\n            moveTo(708.5f, 228.5f)\n            quadTo(720f, 217f, 720f, 200f)\n            quadTo(720f, 183f, 708.5f, 171.5f)\n            quadTo(697f, 160f, 680f, 160f)\n            quadTo(663f, 160f, 651.5f, 171.5f)\n            quadTo(640f, 183f, 640f, 200f)\n            quadTo(640f, 217f, 651.5f, 228.5f)\n            quadTo(663f, 240f, 680f, 240f)\n            quadTo(697f, 240f, 708.5f, 228.5f)\n            close()\n            moveTo(80f, 490f)\n            quadTo(80f, 488f, 80f, 485f)\n            quadTo(80f, 482f, 80f, 480f)\n            quadTo(80f, 430f, 115f, 395f)\n            quadTo(150f, 360f, 200f, 360f)\n            quadTo(224f, 360f, 245f, 368.5f)\n            quadTo(266f, 377f, 282f, 392f)\n            lineTo(563f, 228f)\n            quadTo(561f, 221f, 560.5f, 214.5f)\n            quadTo(560f, 208f, 560f, 200f)\n            quadTo(560f, 150f, 595f, 115f)\n            quadTo(630f, 80f, 680f, 80f)\n            quadTo(730f, 80f, 765f, 115f)\n            quadTo(800f, 150f, 800f, 200f)\n            quadTo(800f, 250f, 765f, 285f)\n            quadTo(730f, 320f, 680f, 320f)\n            quadTo(656f, 320f, 635f, 311.5f)\n            quadTo(614f, 303f, 598f, 288f)\n            lineTo(318f, 451f)\n            quadTo(299f, 446f, 279.5f, 443f)\n            quadTo(260f, 440f, 240f, 440f)\n            quadTo(195f, 440f, 154.5f, 453f)\n            quadTo(114f, 466f, 80f, 490f)\n            close()\n            moveTo(680f, 880f)\n            quadTo(630f, 880f, 595f, 845f)\n            quadTo(560f, 810f, 560f, 760f)\n            quadTo(560f, 754f, 563f, 732f)\n            lineTo(520f, 706f)\n            quadTo(518f, 682f, 513f, 659.5f)\n            quadTo(508f, 637f, 499f, 615f)\n            lineTo(598f, 672f)\n            quadTo(614f, 657f, 635f, 648.5f)\n            quadTo(656f, 640f, 680f, 640f)\n            quadTo(730f, 640f, 765f, 675f)\n            quadTo(800f, 710f, 800f, 760f)\n            quadTo(800f, 810f, 765f, 845f)\n            quadTo(730f, 880f, 680f, 880f)\n            close()\n            moveTo(98.5f, 861.5f)\n            quadTo(40f, 803f, 40f, 720f)\n            quadTo(40f, 637f, 98.5f, 578.5f)\n            quadTo(157f, 520f, 240f, 520f)\n            quadTo(323f, 520f, 381.5f, 578.5f)\n            quadTo(440f, 637f, 440f, 720f)\n            quadTo(440f, 803f, 381.5f, 861.5f)\n            quadTo(323f, 920f, 240f, 920f)\n            quadTo(157f, 920f, 98.5f, 861.5f)\n            close()\n            moveTo(240f, 748f)\n            lineTo(310f, 819f)\n            lineTo(339f, 791f)\n            lineTo(268f, 720f)\n            lineTo(339f, 649f)\n            lineTo(311f, 621f)\n            lineTo(240f, 692f)\n            lineTo(169f, 621f)\n            lineTo(141f, 649f)\n            lineTo(212f, 720f)\n            lineTo(141f, 791f)\n            lineTo(169f, 819f)\n            lineTo(240f, 748f)\n            close()\n            moveTo(680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            quadTo(680f, 760f, 680f, 760f)\n            close()\n            moveTo(680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            quadTo(680f, 200f, 680f, 200f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.ShareOff: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.ShareOff\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(80f, 490f)\n            quadTo(80f, 488f, 80f, 485f)\n            quadTo(80f, 482f, 80f, 480f)\n            quadTo(80f, 430f, 115f, 395f)\n            quadTo(150f, 360f, 200f, 360f)\n            quadTo(224f, 360f, 245f, 368.5f)\n            quadTo(266f, 377f, 282f, 392f)\n            lineTo(563f, 228f)\n            quadTo(561f, 221f, 560.5f, 214.5f)\n            quadTo(560f, 208f, 560f, 200f)\n            quadTo(560f, 150f, 595f, 115f)\n            quadTo(630f, 80f, 680f, 80f)\n            quadTo(730f, 80f, 765f, 115f)\n            quadTo(800f, 150f, 800f, 200f)\n            quadTo(800f, 250f, 765f, 285f)\n            quadTo(730f, 320f, 680f, 320f)\n            quadTo(656f, 320f, 635f, 311.5f)\n            quadTo(614f, 303f, 598f, 288f)\n            lineTo(318f, 451f)\n            quadTo(299f, 446f, 279.5f, 443f)\n            quadTo(260f, 440f, 240f, 440f)\n            quadTo(195f, 440f, 154.5f, 453f)\n            quadTo(114f, 466f, 80f, 490f)\n            close()\n            moveTo(680f, 880f)\n            quadTo(630f, 880f, 595f, 845f)\n            quadTo(560f, 810f, 560f, 760f)\n            quadTo(560f, 754f, 563f, 732f)\n            lineTo(520f, 706f)\n            quadTo(518f, 682f, 513f, 659.5f)\n            quadTo(508f, 637f, 499f, 615f)\n            lineTo(598f, 672f)\n            quadTo(614f, 657f, 635f, 648.5f)\n            quadTo(656f, 640f, 680f, 640f)\n            quadTo(730f, 640f, 765f, 675f)\n            quadTo(800f, 710f, 800f, 760f)\n            quadTo(800f, 810f, 765f, 845f)\n            quadTo(730f, 880f, 680f, 880f)\n            close()\n            moveTo(98.5f, 861.5f)\n            quadTo(40f, 803f, 40f, 720f)\n            quadTo(40f, 637f, 98.5f, 578.5f)\n            quadTo(157f, 520f, 240f, 520f)\n            quadTo(323f, 520f, 381.5f, 578.5f)\n            quadTo(440f, 637f, 440f, 720f)\n            quadTo(440f, 803f, 381.5f, 861.5f)\n            quadTo(323f, 920f, 240f, 920f)\n            quadTo(157f, 920f, 98.5f, 861.5f)\n            close()\n            moveTo(240f, 748f)\n            lineTo(310f, 819f)\n            lineTo(339f, 791f)\n            lineTo(268f, 720f)\n            lineTo(339f, 649f)\n            lineTo(311f, 621f)\n            lineTo(240f, 692f)\n            lineTo(169f, 621f)\n            lineTo(141f, 649f)\n            lineTo(212f, 720f)\n            lineTo(141f, 791f)\n            lineTo(169f, 819f)\n            lineTo(240f, 748f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ShieldKey.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ShieldKey: ImageVector by lazy {\n    Builder(\n        name = \"Shield Key\",\n        defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f,\n        viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = Butt,\n            strokeLineJoin = Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 8.0f)\n            arcTo(\n                1.0f, 1.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 13.0f,\n                y1 = 9.0f\n            )\n            arcTo(\n                1.0f, 1.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 12.0f,\n                y1 = 10.0f\n            )\n            arcTo(\n                1.0f, 1.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 11.0f,\n                y1 = 9.0f\n            )\n            arcTo(\n                1.0f, 1.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 12.0f,\n                y1 = 8.0f\n            )\n            moveTo(21.0f, 11.0f)\n            curveTo(21.0f, 16.55f, 17.16f, 21.74f, 12.0f, 23.0f)\n            curveTo(6.84f, 21.74f, 3.0f, 16.55f, 3.0f, 11.0f)\n            verticalLineTo(5.0f)\n            lineTo(12.0f, 1.0f)\n            lineTo(21.0f, 5.0f)\n            verticalLineTo(11.0f)\n            moveTo(12.0f, 6.0f)\n            arcTo(\n                3.0f, 3.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 9.0f,\n                y1 = 9.0f\n            )\n            curveTo(9.0f, 10.31f, 9.83f, 11.42f, 11.0f, 11.83f)\n            verticalLineTo(18.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(15.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(13.0f)\n            verticalLineTo(11.83f)\n            curveTo(14.17f, 11.42f, 15.0f, 10.31f, 15.0f, 9.0f)\n            arcTo(\n                3.0f, 3.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 12.0f,\n                y1 = 6.0f\n            )\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ShieldLock.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ShieldLock: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ShieldLock\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.713f, 11.287f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(1f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.713f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.713f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.713f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.713f, 0.287f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.713f)\n            close()\n            moveTo(13f, 11f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.713f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.713f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.713f)\n            verticalLineToRelative(1f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.638f, 5.25f)\n            curveToRelative(-0.242f, -0.333f, -0.554f, -0.575f, -0.938f, -0.725f)\n            lineToRelative(-6f, -2.25f)\n            curveToRelative(-0.233f, -0.083f, -0.467f, -0.125f, -0.7f, -0.125f)\n            reflectiveCurveToRelative(-0.467f, 0.042f, -0.7f, 0.125f)\n            lineToRelative(-6f, 2.25f)\n            curveToRelative(-0.383f, 0.15f, -0.696f, 0.392f, -0.938f, 0.725f)\n            curveToRelative(-0.242f, 0.333f, -0.362f, 0.708f, -0.362f, 1.125f)\n            verticalLineToRelative(4.725f)\n            curveToRelative(0f, 2.333f, 0.667f, 4.513f, 2f, 6.538f)\n            curveToRelative(1.333f, 2.025f, 3.125f, 3.412f, 5.375f, 4.162f)\n            curveToRelative(0.1f, 0.033f, 0.2f, 0.058f, 0.3f, 0.075f)\n            curveToRelative(0.1f, 0.017f, 0.208f, 0.025f, 0.325f, 0.025f)\n            reflectiveCurveToRelative(0.225f, -0.008f, 0.325f, -0.025f)\n            curveToRelative(0.1f, -0.017f, 0.2f, -0.042f, 0.3f, -0.075f)\n            curveToRelative(2.25f, -0.75f, 4.042f, -2.138f, 5.375f, -4.162f)\n            curveToRelative(1.333f, -2.025f, 2f, -4.204f, 2f, -6.538f)\n            verticalLineToRelative(-4.725f)\n            curveToRelative(0f, -0.417f, -0.121f, -0.792f, -0.362f, -1.125f)\n            close()\n            moveTo(18f, 11.1f)\n            curveToRelative(0f, 2.017f, -0.567f, 3.85f, -1.7f, 5.5f)\n            curveToRelative(-1.133f, 1.65f, -2.567f, 2.75f, -4.3f, 3.3f)\n            curveToRelative(-1.733f, -0.55f, -3.167f, -1.65f, -4.3f, -3.3f)\n            curveToRelative(-1.133f, -1.65f, -1.7f, -3.483f, -1.7f, -5.5f)\n            verticalLineToRelative(-4.725f)\n            lineToRelative(6f, -2.25f)\n            lineToRelative(6f, 2.25f)\n            verticalLineToRelative(4.725f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.ShieldLock: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.ShieldLock\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.713f, 11.287f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.713f, -0.287f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            reflectiveCurveToRelative(-1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(1f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.713f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.713f)\n            verticalLineToRelative(3f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.713f)\n            curveToRelative(0.192f, 0.192f, 0.429f, 0.287f, 0.713f, 0.287f)\n            horizontalLineToRelative(4f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.713f, -0.287f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.713f)\n            verticalLineToRelative(-3f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.713f)\n            close()\n            moveTo(13f, 11f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-1f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.713f)\n            curveToRelative(0.192f, -0.192f, 0.429f, -0.287f, 0.713f, -0.287f)\n            reflectiveCurveToRelative(0.521f, 0.096f, 0.713f, 0.287f)\n            curveToRelative(0.192f, 0.192f, 0.287f, 0.429f, 0.287f, 0.713f)\n            verticalLineToRelative(1f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.638f, 5.25f)\n            curveToRelative(-0.242f, -0.333f, -0.554f, -0.575f, -0.938f, -0.725f)\n            lineToRelative(-6f, -2.25f)\n            curveToRelative(-0.233f, -0.083f, -0.467f, -0.125f, -0.7f, -0.125f)\n            reflectiveCurveToRelative(-0.467f, 0.042f, -0.7f, 0.125f)\n            lineToRelative(-6f, 2.25f)\n            curveToRelative(-0.383f, 0.15f, -0.696f, 0.392f, -0.938f, 0.725f)\n            curveToRelative(-0.242f, 0.333f, -0.362f, 0.708f, -0.362f, 1.125f)\n            verticalLineToRelative(4.725f)\n            curveToRelative(0f, 2.333f, 0.667f, 4.513f, 2f, 6.538f)\n            curveToRelative(1.333f, 2.025f, 3.125f, 3.412f, 5.375f, 4.162f)\n            curveToRelative(0.1f, 0.033f, 0.2f, 0.058f, 0.3f, 0.075f)\n            curveToRelative(0.1f, 0.017f, 0.208f, 0.025f, 0.325f, 0.025f)\n            reflectiveCurveToRelative(0.225f, -0.008f, 0.325f, -0.025f)\n            curveToRelative(0.1f, -0.017f, 0.2f, -0.042f, 0.3f, -0.075f)\n            curveToRelative(2.25f, -0.75f, 4.042f, -2.138f, 5.375f, -4.162f)\n            curveToRelative(1.333f, -2.025f, 2f, -4.204f, 2f, -6.538f)\n            verticalLineToRelative(-4.725f)\n            curveToRelative(0f, -0.417f, -0.121f, -0.792f, -0.362f, -1.125f)\n            close()\n            moveTo(18f, 11.1f)\n            curveToRelative(0f, 2.017f, -0.567f, 3.85f, -1.7f, 5.5f)\n            curveToRelative(-1.133f, 1.65f, -2.567f, 2.75f, -4.3f, 3.3f)\n            curveToRelative(-1.733f, -0.55f, -3.167f, -1.65f, -4.3f, -3.3f)\n            curveToRelative(-1.133f, -1.65f, -1.7f, -3.483f, -1.7f, -5.5f)\n            verticalLineToRelative(-4.725f)\n            lineToRelative(6f, -2.25f)\n            lineToRelative(6f, 2.25f)\n            verticalLineToRelative(4.725f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 19.904f)\n            curveToRelative(1.733f, -0.55f, 3.167f, -1.65f, 4.3f, -3.3f)\n            reflectiveCurveToRelative(1.7f, -3.483f, 1.7f, -5.5f)\n            verticalLineToRelative(-4.725f)\n            lineToRelative(-6f, -2.25f)\n            lineToRelative(-6f, 2.25f)\n            verticalLineToRelative(4.725f)\n            curveToRelative(0f, 2.017f, 0.567f, 3.85f, 1.7f, 5.5f)\n            reflectiveCurveToRelative(2.567f, 2.75f, 4.3f, 3.3f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ShieldOpen.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ShieldOpen: ImageVector by lazy {\n    Builder(\n        name = \"Shield Open\",\n        defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f,\n        viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = Butt,\n            strokeLineJoin = Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 1.0f)\n            lineTo(3.0f, 5.0f)\n            verticalLineTo(11.0f)\n            curveTo(3.0f, 16.5f, 6.8f, 21.7f, 12.0f, 23.0f)\n            curveTo(17.2f, 21.7f, 21.0f, 16.5f, 21.0f, 11.0f)\n            verticalLineTo(5.0f)\n            lineTo(12.0f, 1.0f)\n            moveTo(16.0f, 15.8f)\n            curveTo(16.0f, 16.4f, 15.4f, 17.0f, 14.7f, 17.0f)\n            horizontalLineTo(9.2f)\n            curveTo(8.6f, 17.0f, 8.0f, 16.4f, 8.0f, 15.7f)\n            verticalLineTo(12.2f)\n            curveTo(8.0f, 11.6f, 8.6f, 11.0f, 9.2f, 11.0f)\n            verticalLineTo(8.5f)\n            curveTo(9.2f, 7.1f, 10.6f, 6.0f, 12.0f, 6.0f)\n            reflectiveCurveTo(14.8f, 7.1f, 14.8f, 8.5f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(13.5f)\n            verticalLineTo(8.5f)\n            curveTo(13.5f, 7.7f, 12.8f, 7.2f, 12.0f, 7.2f)\n            reflectiveCurveTo(10.5f, 7.7f, 10.5f, 8.5f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(14.8f)\n            curveTo(15.4f, 11.0f, 16.0f, 11.6f, 16.0f, 12.3f)\n            verticalLineTo(15.8f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ShineDiamond.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.ShineDiamond: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.ShineDiamond\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(480f, 880f)\n            lineTo(120f, 524f)\n            lineToRelative(200f, -244f)\n            horizontalLineToRelative(320f)\n            lineToRelative(200f, 244f)\n            lineTo(480f, 880f)\n            close()\n            moveTo(183f, 280f)\n            lineToRelative(-85f, -85f)\n            lineToRelative(57f, -56f)\n            lineToRelative(85f, 85f)\n            lineToRelative(-57f, 56f)\n            close()\n            moveTo(440f, 200f)\n            verticalLineToRelative(-120f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(120f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(775f, 280f)\n            lineTo(718f, 223f)\n            lineTo(803f, 138f)\n            lineTo(860f, 195f)\n            lineTo(775f, 280f)\n            close()\n            moveTo(480f, 768f)\n            lineToRelative(210f, -208f)\n            lineTo(270f, 560f)\n            lineToRelative(210f, 208f)\n            close()\n            moveTo(358f, 360f)\n            lineToRelative(-99f, 120f)\n            horizontalLineToRelative(442f)\n            lineToRelative(-99f, -120f)\n            lineTo(358f, 360f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Signature.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Signature: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Signature\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(563f, 469f)\n            quadToRelative(73f, -54f, 114f, -118.5f)\n            reflectiveQuadTo(718f, 222f)\n            quadToRelative(0f, -32f, -10.5f, -47f)\n            reflectiveQuadTo(679f, 160f)\n            quadToRelative(-47f, 0f, -83f, 79.5f)\n            reflectiveQuadTo(560f, 419f)\n            quadToRelative(0f, 14f, 0.5f, 26.5f)\n            reflectiveQuadTo(563f, 469f)\n            close()\n            moveTo(164f, 652f)\n            quadToRelative(-11f, 11f, -28f, 11f)\n            reflectiveQuadToRelative(-28f, -11f)\n            quadToRelative(-11f, -11f, -11f, -28f)\n            reflectiveQuadToRelative(11f, -28f)\n            lineToRelative(36f, -36f)\n            lineToRelative(-36f, -36f)\n            quadToRelative(-11f, -11f, -11f, -28f)\n            reflectiveQuadToRelative(11f, -28f)\n            quadToRelative(11f, -11f, 28f, -11f)\n            reflectiveQuadToRelative(28f, 11f)\n            lineToRelative(36f, 36f)\n            lineToRelative(36f, -36f)\n            quadToRelative(11f, -11f, 28f, -11f)\n            reflectiveQuadToRelative(28f, 11f)\n            quadToRelative(11f, 11f, 11f, 28f)\n            reflectiveQuadToRelative(-11f, 28f)\n            lineToRelative(-36f, 36f)\n            lineToRelative(36f, 36f)\n            quadToRelative(11f, 11f, 11f, 28f)\n            reflectiveQuadToRelative(-11f, 28f)\n            quadToRelative(-11f, 11f, -28f, 11f)\n            reflectiveQuadToRelative(-28f, -11f)\n            lineToRelative(-36f, -36f)\n            lineToRelative(-36f, 36f)\n            close()\n            moveTo(618f, 640f)\n            quadToRelative(-30f, 0f, -55f, -11.5f)\n            reflectiveQuadTo(520f, 591f)\n            quadToRelative(-16f, 8f, -33f, 16f)\n            lineToRelative(-34f, 16f)\n            quadToRelative(-16f, 7f, -31.5f, 0.5f)\n            reflectiveQuadTo(400f, 601f)\n            quadToRelative(-6f, -16f, 1.5f, -31f)\n            reflectiveQuadToRelative(23.5f, -22f)\n            quadToRelative(17f, -8f, 33f, -15.5f)\n            reflectiveQuadToRelative(31f, -15.5f)\n            quadToRelative(-5f, -22f, -7.5f, -48f)\n            reflectiveQuadToRelative(-2.5f, -56f)\n            quadToRelative(0f, -144f, 57f, -238.5f)\n            reflectiveQuadTo(679f, 80f)\n            quadToRelative(52f, 0f, 85f, 38.5f)\n            reflectiveQuadTo(797f, 226f)\n            quadToRelative(0f, 86f, -54.5f, 170f)\n            reflectiveQuadTo(591f, 547f)\n            quadToRelative(7f, 7f, 14.5f, 10.5f)\n            reflectiveQuadTo(621f, 561f)\n            quadToRelative(21f, 0f, 49f, -23f)\n            reflectiveQuadToRelative(54f, -62f)\n            quadToRelative(10f, -14f, 25.5f, -19.5f)\n            reflectiveQuadTo(780f, 458f)\n            quadToRelative(15f, 8f, 22f, 23.5f)\n            reflectiveQuadToRelative(4f, 32.5f)\n            quadToRelative(-2f, 12f, -2f, 23f)\n            reflectiveQuadToRelative(3f, 21f)\n            quadToRelative(5f, -2f, 11.5f, -6.5f)\n            reflectiveQuadTo(832f, 540f)\n            quadToRelative(12f, -11f, 28.5f, -12.5f)\n            reflectiveQuadTo(890f, 536f)\n            quadToRelative(14f, 11f, 15f, 27f)\n            reflectiveQuadToRelative(-10f, 27f)\n            quadToRelative(-23f, 23f, -48.5f, 36.5f)\n            reflectiveQuadTo(798f, 640f)\n            quadToRelative(-21f, 0f, -37.5f, -12.5f)\n            reflectiveQuadTo(733f, 589f)\n            quadToRelative(-28f, 25f, -57f, 38f)\n            reflectiveQuadToRelative(-58f, 13f)\n            close()\n            moveTo(131.5f, 828.5f)\n            quadTo(120f, 817f, 120f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(143f, 760f, 160f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(200f, 783f, 200f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(177f, 840f, 160f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(291.5f, 828.5f)\n            quadTo(280f, 817f, 280f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(303f, 760f, 320f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(360f, 783f, 360f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(337f, 840f, 320f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(451.5f, 828.5f)\n            quadTo(440f, 817f, 440f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(463f, 760f, 480f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(520f, 783f, 520f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(497f, 840f, 480f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(611.5f, 828.5f)\n            quadTo(600f, 817f, 600f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(623f, 760f, 640f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(680f, 783f, 680f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(657f, 840f, 640f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n            moveTo(771.5f, 828.5f)\n            quadTo(760f, 817f, 760f, 800f)\n            reflectiveQuadToRelative(11.5f, -28.5f)\n            quadTo(783f, 760f, 800f, 760f)\n            reflectiveQuadToRelative(28.5f, 11.5f)\n            quadTo(840f, 783f, 840f, 800f)\n            reflectiveQuadToRelative(-11.5f, 28.5f)\n            quadTo(817f, 840f, 800f, 840f)\n            reflectiveQuadToRelative(-28.5f, -11.5f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SkewMore.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SkewMore: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.SkewMore\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12.5f, 11f)\n            lineTo(10.41f, 20f)\n            horizontalLineTo(5.5f)\n            lineTo(7.59f, 11f)\n            horizontalLineTo(12.5f)\n            moveTo(15f, 9f)\n            horizontalLineTo(6f)\n            lineTo(3f, 22f)\n            horizontalLineTo(12f)\n            lineTo(15f, 9f)\n            moveTo(21f, 6f)\n            lineTo(17f, 2f)\n            verticalLineTo(5f)\n            horizontalLineTo(9f)\n            verticalLineTo(7f)\n            horizontalLineTo(17f)\n            verticalLineTo(10f)\n            lineTo(21f, 6f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Slider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Slider: ImageVector by lazy {\n    Builder(\n        name = \"Slider\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960.0f, viewportHeight = 960.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(200.0f, 600.0f)\n            quadToRelative(-50.0f, 0.0f, -85.0f, -35.0f)\n            reflectiveQuadToRelative(-35.0f, -85.0f)\n            quadToRelative(0.0f, -50.0f, 35.0f, -85.0f)\n            reflectiveQuadToRelative(85.0f, -35.0f)\n            horizontalLineToRelative(560.0f)\n            quadToRelative(50.0f, 0.0f, 85.0f, 35.0f)\n            reflectiveQuadToRelative(35.0f, 85.0f)\n            quadToRelative(0.0f, 50.0f, -35.0f, 85.0f)\n            reflectiveQuadToRelative(-85.0f, 35.0f)\n            lineTo(200.0f, 600.0f)\n            close()\n            moveTo(560.0f, 520.0f)\n            horizontalLineToRelative(200.0f)\n            quadToRelative(17.0f, 0.0f, 28.5f, -11.5f)\n            reflectiveQuadTo(800.0f, 480.0f)\n            quadToRelative(0.0f, -17.0f, -11.5f, -28.5f)\n            reflectiveQuadTo(760.0f, 440.0f)\n            lineTo(560.0f, 440.0f)\n            verticalLineToRelative(80.0f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Snail.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Snail: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Snail\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.31f, 8.03f)\n            lineTo(21.24f, 4.95f)\n            curveTo(21.67f, 4.85f, 22f, 4.47f, 22f, 4f)\n            curveTo(22f, 3.45f, 21.55f, 3f, 21f, 3f)\n            reflectiveCurveTo(20f, 3.45f, 20f, 4f)\n            curveTo(20f, 4.26f, 20.11f, 4.5f, 20.27f, 4.68f)\n            lineTo(19.5f, 7.26f)\n            lineTo(18.73f, 4.68f)\n            curveTo(18.89f, 4.5f, 19f, 4.26f, 19f, 4f)\n            curveTo(19f, 3.45f, 18.55f, 3f, 18f, 3f)\n            reflectiveCurveTo(17f, 3.45f, 17f, 4f)\n            curveTo(17f, 4.47f, 17.33f, 4.85f, 17.76f, 4.95f)\n            lineTo(18.69f, 8.03f)\n            curveTo(17.73f, 8.18f, 17f, 9f, 17f, 10f)\n            verticalLineTo(12.25f)\n            curveTo(15.65f, 9.16f, 12.63f, 7f, 9.11f, 7f)\n            curveTo(5.19f, 7f, 2f, 10.26f, 2f, 14.26f)\n            curveTo(2f, 16.1f, 2.82f, 17.75f, 4.1f, 18.85f)\n            lineTo(2.88f, 19f)\n            curveTo(2.38f, 19.06f, 2f, 19.5f, 2f, 20f)\n            curveTo(2f, 20.55f, 2.45f, 21f, 3f, 21f)\n            lineTo(19.12f, 21f)\n            curveTo(20.16f, 21f, 21f, 20.16f, 21f, 19.12f)\n            verticalLineTo(11.72f)\n            curveTo(21.6f, 11.38f, 22f, 10.74f, 22f, 10f)\n            curveTo(22f, 9f, 21.27f, 8.18f, 20.31f, 8.03f)\n            moveTo(15.6f, 17.41f)\n            lineTo(12.07f, 17.86f)\n            curveTo(12.5f, 17.1f, 12.8f, 16.21f, 12.8f, 15.26f)\n            curveTo(12.8f, 12.94f, 10.95f, 11.06f, 8.67f, 11.06f)\n            curveTo(8.14f, 11.06f, 7.62f, 11.18f, 7.14f, 11.41f)\n            curveTo(6.65f, 11.66f, 6.44f, 12.26f, 6.69f, 12.75f)\n            curveTo(6.93f, 13.25f, 7.53f, 13.45f, 8.03f, 13.21f)\n            curveTo(8.23f, 13.11f, 8.45f, 13.06f, 8.67f, 13.06f)\n            curveTo(9.85f, 13.06f, 10.8f, 14.04f, 10.8f, 15.26f)\n            curveTo(10.8f, 16.92f, 9.5f, 18.27f, 7.89f, 18.27f)\n            curveTo(5.75f, 18.27f, 4f, 16.47f, 4f, 14.26f)\n            curveTo(4f, 11.36f, 6.29f, 9f, 9.11f, 9f)\n            curveTo(12.77f, 9f, 15.75f, 12.06f, 15.75f, 15.82f)\n            curveTo(15.75f, 16.36f, 15.69f, 16.89f, 15.6f, 17.41f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Snowflake.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Snowflake: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Snowflake\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.79f, 13.95f)\n            lineTo(18.46f, 14.57f)\n            lineTo(16.46f, 13.44f)\n            verticalLineTo(10.56f)\n            lineTo(18.46f, 9.43f)\n            lineTo(20.79f, 10.05f)\n            lineTo(21.31f, 8.12f)\n            lineTo(19.54f, 7.65f)\n            lineTo(20f, 5.88f)\n            lineTo(18.07f, 5.36f)\n            lineTo(17.45f, 7.69f)\n            lineTo(15.45f, 8.82f)\n            lineTo(13f, 7.38f)\n            verticalLineTo(5.12f)\n            lineTo(14.71f, 3.41f)\n            lineTo(13.29f, 2f)\n            lineTo(12f, 3.29f)\n            lineTo(10.71f, 2f)\n            lineTo(9.29f, 3.41f)\n            lineTo(11f, 5.12f)\n            verticalLineTo(7.38f)\n            lineTo(8.5f, 8.82f)\n            lineTo(6.5f, 7.69f)\n            lineTo(5.92f, 5.36f)\n            lineTo(4f, 5.88f)\n            lineTo(4.47f, 7.65f)\n            lineTo(2.7f, 8.12f)\n            lineTo(3.22f, 10.05f)\n            lineTo(5.55f, 9.43f)\n            lineTo(7.55f, 10.56f)\n            verticalLineTo(13.45f)\n            lineTo(5.55f, 14.58f)\n            lineTo(3.22f, 13.96f)\n            lineTo(2.7f, 15.89f)\n            lineTo(4.47f, 16.36f)\n            lineTo(4f, 18.12f)\n            lineTo(5.93f, 18.64f)\n            lineTo(6.55f, 16.31f)\n            lineTo(8.55f, 15.18f)\n            lineTo(11f, 16.62f)\n            verticalLineTo(18.88f)\n            lineTo(9.29f, 20.59f)\n            lineTo(10.71f, 22f)\n            lineTo(12f, 20.71f)\n            lineTo(13.29f, 22f)\n            lineTo(14.7f, 20.59f)\n            lineTo(13f, 18.88f)\n            verticalLineTo(16.62f)\n            lineTo(15.5f, 15.17f)\n            lineTo(17.5f, 16.3f)\n            lineTo(18.12f, 18.63f)\n            lineTo(20f, 18.12f)\n            lineTo(19.53f, 16.35f)\n            lineTo(21.3f, 15.88f)\n            lineTo(20.79f, 13.95f)\n            moveTo(9.5f, 10.56f)\n            lineTo(12f, 9.11f)\n            lineTo(14.5f, 10.56f)\n            verticalLineTo(13.44f)\n            lineTo(12f, 14.89f)\n            lineTo(9.5f, 13.44f)\n            verticalLineTo(10.56f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Speed.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Speed: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Speed\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(418f, 620f)\n            quadTo(443f, 645f, 481f, 643.5f)\n            quadTo(519f, 642f, 536f, 616f)\n            lineTo(705f, 363f)\n            quadTo(714f, 349f, 702.5f, 337.5f)\n            quadTo(691f, 326f, 677f, 335f)\n            lineTo(424f, 504f)\n            quadTo(398f, 522f, 395.5f, 558.5f)\n            quadTo(393f, 595f, 418f, 620f)\n            close()\n            moveTo(204f, 800f)\n            quadTo(182f, 800f, 163.5f, 790.5f)\n            quadTo(145f, 781f, 134f, 762f)\n            quadTo(108f, 715f, 94f, 664.5f)\n            quadTo(80f, 614f, 80f, 560f)\n            quadTo(80f, 477f, 111.5f, 404f)\n            quadTo(143f, 331f, 197f, 277f)\n            quadTo(251f, 223f, 324f, 191.5f)\n            quadTo(397f, 160f, 480f, 160f)\n            quadTo(562f, 160f, 634f, 191f)\n            quadTo(706f, 222f, 760f, 275.5f)\n            quadTo(814f, 329f, 846f, 400.5f)\n            quadTo(878f, 472f, 879f, 554f)\n            quadTo(880f, 609f, 866.5f, 661.5f)\n            quadTo(853f, 714f, 825f, 762f)\n            quadTo(814f, 781f, 795.5f, 790.5f)\n            quadTo(777f, 800f, 755f, 800f)\n            lineTo(204f, 800f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SplitAlt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SplitAlt: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.SplitAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 21f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.933f, -0.142f, -1.625f, -0.425f, -2.075f)\n            reflectiveCurveToRelative(-0.658f, -0.892f, -1.125f, -1.325f)\n            lineToRelative(1.425f, -1.425f)\n            curveToRelative(0.2f, 0.183f, 0.392f, 0.379f, 0.575f, 0.587f)\n            reflectiveCurveToRelative(0.367f, 0.429f, 0.55f, 0.663f)\n            curveToRelative(0.233f, -0.317f, 0.471f, -0.596f, 0.712f, -0.837f)\n            curveToRelative(0.242f, -0.242f, 0.488f, -0.479f, 0.738f, -0.712f)\n            curveToRelative(0.633f, -0.583f, 1.208f, -1.258f, 1.725f, -2.025f)\n            reflectiveCurveToRelative(0.792f, -2.108f, 0.825f, -4.025f)\n            lineToRelative(-0.875f, 0.875f)\n            curveToRelative(-0.183f, 0.183f, -0.412f, 0.275f, -0.688f, 0.275f)\n            reflectiveCurveToRelative(-0.512f, -0.092f, -0.712f, -0.275f)\n            curveToRelative(-0.2f, -0.2f, -0.3f, -0.438f, -0.3f, -0.712f)\n            reflectiveCurveToRelative(0.1f, -0.512f, 0.3f, -0.712f)\n            lineToRelative(2.575f, -2.575f)\n            curveToRelative(0.1f, -0.1f, 0.208f, -0.171f, 0.325f, -0.213f)\n            reflectiveCurveToRelative(0.242f, -0.063f, 0.375f, -0.063f)\n            reflectiveCurveToRelative(0.258f, 0.021f, 0.375f, 0.063f)\n            reflectiveCurveToRelative(0.225f, 0.112f, 0.325f, 0.213f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.183f, 0.183f, 0.279f, 0.412f, 0.287f, 0.688f)\n            reflectiveCurveToRelative(-0.087f, 0.512f, -0.287f, 0.712f)\n            curveToRelative(-0.183f, 0.183f, -0.417f, 0.275f, -0.7f, 0.275f)\n            reflectiveCurveToRelative(-0.517f, -0.092f, -0.7f, -0.275f)\n            lineToRelative(-0.9f, -0.875f)\n            curveToRelative(-0.033f, 2.383f, -0.4f, 4.079f, -1.1f, 5.088f)\n            curveToRelative(-0.7f, 1.008f, -1.4f, 1.829f, -2.1f, 2.463f)\n            curveToRelative(-0.533f, 0.483f, -0.967f, 0.954f, -1.3f, 1.413f)\n            reflectiveCurveToRelative(-0.5f, 1.196f, -0.5f, 2.213f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(6.2f, 8.175f)\n            curveToRelative(-0.067f, -0.333f, -0.112f, -0.7f, -0.138f, -1.1f)\n            reflectiveCurveToRelative(-0.046f, -0.817f, -0.063f, -1.25f)\n            lineToRelative(-0.9f, 0.9f)\n            curveToRelative(-0.183f, 0.183f, -0.412f, 0.275f, -0.688f, 0.275f)\n            reflectiveCurveToRelative(-0.512f, -0.1f, -0.712f, -0.3f)\n            curveToRelative(-0.183f, -0.183f, -0.275f, -0.417f, -0.275f, -0.7f)\n            reflectiveCurveToRelative(0.092f, -0.517f, 0.275f, -0.7f)\n            lineToRelative(2.6f, -2.6f)\n            curveToRelative(0.1f, -0.1f, 0.208f, -0.171f, 0.325f, -0.213f)\n            reflectiveCurveToRelative(0.242f, -0.063f, 0.375f, -0.063f)\n            reflectiveCurveToRelative(0.258f, 0.021f, 0.375f, 0.063f)\n            reflectiveCurveToRelative(0.225f, 0.112f, 0.325f, 0.213f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.2f, 0.2f, 0.296f, 0.433f, 0.287f, 0.7f)\n            reflectiveCurveToRelative(-0.112f, 0.5f, -0.313f, 0.7f)\n            curveToRelative(-0.2f, 0.183f, -0.433f, 0.275f, -0.7f, 0.275f)\n            reflectiveCurveToRelative(-0.5f, -0.092f, -0.7f, -0.275f)\n            lineToRelative(-0.875f, -0.85f)\n            curveToRelative(0f, 0.35f, 0.017f, 0.679f, 0.05f, 0.988f)\n            reflectiveCurveToRelative(0.067f, 0.596f, 0.1f, 0.863f)\n            lineToRelative(-1.95f, 0.475f)\n            close()\n            moveTo(8.35f, 12.575f)\n            curveToRelative(-0.333f, -0.35f, -0.654f, -0.758f, -0.963f, -1.225f)\n            curveToRelative(-0.308f, -0.467f, -0.579f, -1.042f, -0.813f, -1.725f)\n            lineToRelative(1.925f, -0.475f)\n            curveToRelative(0.167f, 0.45f, 0.358f, 0.833f, 0.575f, 1.15f)\n            curveToRelative(0.217f, 0.317f, 0.45f, 0.6f, 0.7f, 0.85f)\n            lineToRelative(-1.425f, 1.425f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.SplitAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.SplitAlt\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 21f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.933f, -0.142f, -1.625f, -0.425f, -2.075f)\n            reflectiveCurveToRelative(-0.658f, -0.892f, -1.125f, -1.325f)\n            lineToRelative(1.425f, -1.425f)\n            curveToRelative(0.2f, 0.183f, 0.392f, 0.379f, 0.575f, 0.587f)\n            reflectiveCurveToRelative(0.367f, 0.429f, 0.55f, 0.663f)\n            curveToRelative(0.233f, -0.317f, 0.471f, -0.596f, 0.712f, -0.837f)\n            curveToRelative(0.242f, -0.242f, 0.488f, -0.479f, 0.738f, -0.712f)\n            curveToRelative(0.633f, -0.583f, 1.208f, -1.258f, 1.725f, -2.025f)\n            reflectiveCurveToRelative(0.792f, -2.108f, 0.825f, -4.025f)\n            lineToRelative(-0.875f, 0.875f)\n            curveToRelative(-0.183f, 0.183f, -0.412f, 0.275f, -0.688f, 0.275f)\n            reflectiveCurveToRelative(-0.512f, -0.092f, -0.712f, -0.275f)\n            curveToRelative(-0.2f, -0.2f, -0.3f, -0.438f, -0.3f, -0.712f)\n            reflectiveCurveToRelative(0.1f, -0.512f, 0.3f, -0.712f)\n            lineToRelative(2.575f, -2.575f)\n            curveToRelative(0.1f, -0.1f, 0.208f, -0.171f, 0.325f, -0.213f)\n            reflectiveCurveToRelative(0.242f, -0.063f, 0.375f, -0.063f)\n            reflectiveCurveToRelative(0.258f, 0.021f, 0.375f, 0.063f)\n            reflectiveCurveToRelative(0.225f, 0.112f, 0.325f, 0.213f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.183f, 0.183f, 0.279f, 0.412f, 0.287f, 0.688f)\n            reflectiveCurveToRelative(-0.087f, 0.512f, -0.287f, 0.712f)\n            curveToRelative(-0.183f, 0.183f, -0.417f, 0.275f, -0.7f, 0.275f)\n            reflectiveCurveToRelative(-0.517f, -0.092f, -0.7f, -0.275f)\n            lineToRelative(-0.9f, -0.875f)\n            curveToRelative(-0.033f, 2.383f, -0.4f, 4.079f, -1.1f, 5.088f)\n            curveToRelative(-0.7f, 1.008f, -1.4f, 1.829f, -2.1f, 2.463f)\n            curveToRelative(-0.533f, 0.483f, -0.967f, 0.954f, -1.3f, 1.413f)\n            reflectiveCurveToRelative(-0.5f, 1.196f, -0.5f, 2.213f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.283f, -0.096f, 0.521f, -0.287f, 0.712f)\n            curveToRelative(-0.192f, 0.192f, -0.429f, 0.287f, -0.712f, 0.287f)\n            reflectiveCurveToRelative(-0.521f, -0.096f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.287f, -0.429f, -0.287f, -0.712f)\n            close()\n            moveTo(6.2f, 8.175f)\n            curveToRelative(-0.067f, -0.333f, -0.112f, -0.7f, -0.138f, -1.1f)\n            reflectiveCurveToRelative(-0.046f, -0.817f, -0.063f, -1.25f)\n            lineToRelative(-0.9f, 0.9f)\n            curveToRelative(-0.183f, 0.183f, -0.412f, 0.275f, -0.688f, 0.275f)\n            reflectiveCurveToRelative(-0.512f, -0.1f, -0.712f, -0.3f)\n            curveToRelative(-0.183f, -0.183f, -0.275f, -0.417f, -0.275f, -0.7f)\n            reflectiveCurveToRelative(0.092f, -0.517f, 0.275f, -0.7f)\n            lineToRelative(2.6f, -2.6f)\n            curveToRelative(0.1f, -0.1f, 0.208f, -0.171f, 0.325f, -0.213f)\n            reflectiveCurveToRelative(0.242f, -0.063f, 0.375f, -0.063f)\n            reflectiveCurveToRelative(0.258f, 0.021f, 0.375f, 0.063f)\n            reflectiveCurveToRelative(0.225f, 0.112f, 0.325f, 0.213f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.2f, 0.2f, 0.296f, 0.433f, 0.287f, 0.7f)\n            reflectiveCurveToRelative(-0.112f, 0.5f, -0.313f, 0.7f)\n            curveToRelative(-0.2f, 0.183f, -0.433f, 0.275f, -0.7f, 0.275f)\n            reflectiveCurveToRelative(-0.5f, -0.092f, -0.7f, -0.275f)\n            lineToRelative(-0.875f, -0.85f)\n            curveToRelative(0f, 0.35f, 0.017f, 0.679f, 0.05f, 0.988f)\n            reflectiveCurveToRelative(0.067f, 0.596f, 0.1f, 0.863f)\n            lineToRelative(-1.95f, 0.475f)\n            close()\n            moveTo(8.35f, 12.575f)\n            curveToRelative(-0.333f, -0.35f, -0.654f, -0.758f, -0.963f, -1.225f)\n            curveToRelative(-0.308f, -0.467f, -0.579f, -1.042f, -0.813f, -1.725f)\n            lineToRelative(1.925f, -0.475f)\n            curveToRelative(0.167f, 0.45f, 0.358f, 0.833f, 0.575f, 1.15f)\n            curveToRelative(0.217f, 0.317f, 0.45f, 0.6f, 0.7f, 0.85f)\n            lineToRelative(-1.425f, 1.425f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(6.2f, 8.175f)\n            curveToRelative(0.045f, 0.218f, 0.097f, 0.445f, 0.157f, 0.678f)\n            curveToRelative(0.069f, 0.27f, 0.142f, 0.528f, 0.218f, 0.772f)\n            curveToRelative(0.642f, -0.158f, 1.283f, -0.317f, 1.925f, -0.475f)\n            curveToRelative(-0.073f, -0.234f, -0.142f, -0.485f, -0.206f, -0.752f)\n            curveToRelative(-0.058f, -0.243f, -0.105f, -0.476f, -0.144f, -0.698f)\n            curveToRelative(-0.65f, 0.158f, -1.3f, 0.317f, -1.95f, 0.475f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(8.35f, 12.575f)\n            lineToRelative(1.1f, 1.025f)\n            lineToRelative(1.425f, -1.425f)\n            lineToRelative(-1.1f, -1.025f)\n            lineToRelative(-1.425f, 1.425f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SplitComplementary.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.SplitComplementary: ImageVector by lazy {\n    Builder(\n        name = \"SplitComplementary\", defaultWidth = 24.0.dp,\n        defaultHeight = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(8.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(6.9f, 16.0f, 8.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(10.9f, 4.0f, 12.0f, 4.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(14.9f, 16.0f, 16.0f, 16.0f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Spray.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Spray: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Spray\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(10f, 4f)\n            horizontalLineTo(12f)\n            verticalLineTo(6f)\n            horizontalLineTo(10f)\n            verticalLineTo(4f)\n            moveTo(7f, 3f)\n            horizontalLineTo(9f)\n            verticalLineTo(5f)\n            horizontalLineTo(7f)\n            verticalLineTo(3f)\n            moveTo(7f, 6f)\n            horizontalLineTo(9f)\n            verticalLineTo(8f)\n            horizontalLineTo(7f)\n            verticalLineTo(6f)\n            moveTo(6f, 8f)\n            verticalLineTo(10f)\n            horizontalLineTo(4f)\n            verticalLineTo(8f)\n            horizontalLineTo(6f)\n            moveTo(6f, 5f)\n            verticalLineTo(7f)\n            horizontalLineTo(4f)\n            verticalLineTo(5f)\n            horizontalLineTo(6f)\n            moveTo(6f, 2f)\n            verticalLineTo(4f)\n            horizontalLineTo(4f)\n            verticalLineTo(2f)\n            horizontalLineTo(6f)\n            moveTo(13f, 22f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 11f, 20f)\n            verticalLineTo(10f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 13f, 8f)\n            verticalLineTo(7f)\n            horizontalLineTo(14f)\n            verticalLineTo(4f)\n            horizontalLineTo(17f)\n            verticalLineTo(7f)\n            horizontalLineTo(18f)\n            verticalLineTo(8f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 20f, 10f)\n            verticalLineTo(20f)\n            arcTo(2f, 2f, 0f, isMoreThanHalf = false, isPositiveArc = true, 18f, 22f)\n            horizontalLineTo(13f)\n            moveTo(13f, 10f)\n            verticalLineTo(20f)\n            horizontalLineTo(18f)\n            verticalLineTo(10f)\n            horizontalLineTo(13f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Square.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Square: ImageVector by lazy {\n    Builder(\n        name = \"Square\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.4125f, 3.5875f)\n            curveTo(20.0208f, 3.1959f, 19.55f, 3.0f, 19.0f, 3.0f)\n            horizontalLineTo(5.0f)\n            curveTo(4.45f, 3.0f, 3.9792f, 3.1959f, 3.5875f, 3.5875f)\n            reflectiveCurveTo(3.0f, 4.45f, 3.0f, 5.0f)\n            verticalLineToRelative(14.0f)\n            curveToRelative(0.0f, 0.55f, 0.1959f, 1.0208f, 0.5875f, 1.4125f)\n            reflectiveCurveTo(4.45f, 21.0f, 5.0f, 21.0f)\n            horizontalLineToRelative(14.0f)\n            curveToRelative(0.55f, 0.0f, 1.0208f, -0.1959f, 1.4125f, -0.5875f)\n            reflectiveCurveTo(21.0f, 19.55f, 21.0f, 19.0f)\n            verticalLineTo(5.0f)\n            curveTo(21.0f, 4.45f, 20.8041f, 3.9792f, 20.4125f, 3.5875f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SquareEdit.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.SquareEdit: ImageVector by lazy {\n    Builder(\n        name = \"Square Edit\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(5.0f, 3.0f)\n            curveTo(3.89f, 3.0f, 3.0f, 3.89f, 3.0f, 5.0f)\n            verticalLineTo(19.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 5.0f,\n                y1 = 21.0f\n            )\n            horizontalLineTo(19.0f)\n            arcTo(\n                2.0f, 2.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 21.0f,\n                y1 = 19.0f\n            )\n            verticalLineTo(12.0f)\n            horizontalLineTo(19.0f)\n            verticalLineTo(19.0f)\n            horizontalLineTo(5.0f)\n            verticalLineTo(5.0f)\n            horizontalLineTo(12.0f)\n            verticalLineTo(3.0f)\n            horizontalLineTo(5.0f)\n            moveTo(17.78f, 4.0f)\n            curveTo(17.61f, 4.0f, 17.43f, 4.07f, 17.3f, 4.2f)\n            lineTo(16.08f, 5.41f)\n            lineTo(18.58f, 7.91f)\n            lineTo(19.8f, 6.7f)\n            curveTo(20.06f, 6.44f, 20.06f, 6.0f, 19.8f, 5.75f)\n            lineTo(18.25f, 4.2f)\n            curveTo(18.12f, 4.07f, 17.95f, 4.0f, 17.78f, 4.0f)\n            moveTo(15.37f, 6.12f)\n            lineTo(8.0f, 13.5f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(10.5f)\n            lineTo(17.87f, 8.62f)\n            lineTo(15.37f, 6.12f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SquareFoot.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.SquareFoot: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.SquareFoot\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(208f, 840f)\n            quadTo(171f, 840f, 145.5f, 814.5f)\n            quadTo(120f, 789f, 120f, 752f)\n            lineTo(120f, 204f)\n            quadTo(120f, 175f, 147f, 163.5f)\n            quadTo(174f, 152f, 194f, 172f)\n            lineTo(284f, 262f)\n            lineTo(230f, 316f)\n            lineTo(258f, 344f)\n            lineTo(312f, 290f)\n            lineTo(416f, 394f)\n            lineTo(362f, 448f)\n            lineTo(390f, 476f)\n            lineTo(444f, 422f)\n            lineTo(548f, 526f)\n            lineTo(494f, 580f)\n            lineTo(522f, 608f)\n            lineTo(576f, 554f)\n            lineTo(680f, 658f)\n            lineTo(626f, 712f)\n            lineTo(654f, 740f)\n            lineTo(708f, 686f)\n            lineTo(788f, 766f)\n            quadTo(808f, 786f, 796.5f, 813f)\n            quadTo(785f, 840f, 756f, 840f)\n            lineTo(208f, 840f)\n            close()\n            moveTo(240f, 720f)\n            lineTo(572f, 720f)\n            lineTo(240f, 388f)\n            lineTo(240f, 720f)\n            quadTo(240f, 720f, 240f, 720f)\n            quadTo(240f, 720f, 240f, 720f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SquareHarmony.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.SquareHarmony: ImageVector by lazy {\n    Builder(\n        name = \"SquareHarmony\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(4.9f, 16.0f, 6.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(16.9f, 16.0f, 18.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveTo(7.1f, 8.0f, 6.0f, 8.0f)\n            reflectiveCurveTo(4.0f, 7.1f, 4.0f, 6.0f)\n            reflectiveCurveTo(4.9f, 4.0f, 6.0f, 4.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(16.9f, 4.0f, 18.0f, 4.0f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Stack.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Stack: ImageVector by lazy {\n    Builder(\n        name = \"Stack\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 960f, viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(480f, 560f)\n            lineTo(40f, 320f)\n            lineTo(480f, 80f)\n            lineTo(920f, 320f)\n            lineTo(480f, 560f)\n            close()\n            moveTo(480f, 720f)\n            lineTo(63f, 493f)\n            lineTo(147f, 447f)\n            lineTo(480f, 629f)\n            lineTo(813f, 447f)\n            lineTo(897f, 493f)\n            lineTo(480f, 720f)\n            close()\n            moveTo(480f, 880f)\n            lineTo(63f, 653f)\n            lineTo(147f, 607f)\n            lineTo(480f, 789f)\n            lineTo(813f, 607f)\n            lineTo(897f, 653f)\n            lineTo(480f, 880f)\n            close()\n            moveTo(480f, 469f)\n            lineTo(753f, 320f)\n            lineTo(480f, 171f)\n            lineTo(207f, 320f)\n            lineTo(480f, 469f)\n            close()\n            moveTo(480f, 320f)\n            lineTo(480f, 320f)\n            lineTo(480f, 320f)\n            lineTo(480f, 320f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Stack: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    Builder(\n        name = \"TwoTone.Stack\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 18f)\n            lineToRelative(-10.425f, -5.675f)\n            lineToRelative(2.1f, -1.15f)\n            lineToRelative(8.325f, 4.55f)\n            lineToRelative(8.325f, -4.55f)\n            lineToRelative(2.1f, 1.15f)\n            lineToRelative(-10.425f, 5.675f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 22f)\n            lineToRelative(-10.425f, -5.675f)\n            lineToRelative(2.1f, -1.15f)\n            lineToRelative(8.325f, 4.55f)\n            lineToRelative(8.325f, -4.55f)\n            lineToRelative(2.1f, 1.15f)\n            lineToRelative(-10.425f, 5.675f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 11.725f)\n            lineToRelative(6.825f, -3.725f)\n            lineToRelative(-6.825f, -3.725f)\n            lineToRelative(-6.825f, 3.725f)\n            lineToRelative(6.825f, 3.725f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 8f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            lineToRelative(0f, 0f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 2f)\n            lineTo(1f, 8f)\n            lineToRelative(11f, 6f)\n            lineToRelative(11f, -6f)\n            lineTo(12f, 2f)\n            close()\n            moveTo(5.175f, 8f)\n            lineToRelative(6.825f, -3.725f)\n            lineToRelative(6.825f, 3.725f)\n            lineToRelative(-6.825f, 3.725f)\n            lineToRelative(-6.825f, -3.725f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/StackSticky.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.StackSticky: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.StackSticky\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(360f, 360f)\n            verticalLineToRelative(440f)\n            horizontalLineToRelative(280f)\n            verticalLineToRelative(-120f)\n            quadToRelative(0f, -17f, 11.5f, -28.5f)\n            reflectiveQuadTo(680f, 640f)\n            horizontalLineToRelative(120f)\n            verticalLineToRelative(-280f)\n            lineTo(360f, 360f)\n            close()\n            moveTo(580f, 580f)\n            close()\n            moveTo(280f, 800f)\n            verticalLineToRelative(-441f)\n            quadToRelative(0f, -33f, 24f, -56f)\n            reflectiveQuadToRelative(57f, -23f)\n            horizontalLineToRelative(439f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(880f, 360f)\n            verticalLineToRelative(287f)\n            quadToRelative(0f, 16f, -6f, 30.5f)\n            reflectiveQuadTo(857f, 703f)\n            lineTo(703f, 857f)\n            quadToRelative(-11f, 11f, -25.5f, 17f)\n            reflectiveQuadTo(647f, 880f)\n            lineTo(360f, 880f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(280f, 800f)\n            close()\n            moveTo(81f, 250f)\n            quadToRelative(-6f, -33f, 13f, -59.5f)\n            reflectiveQuadToRelative(52f, -32.5f)\n            lineToRelative(434f, -77f)\n            quadToRelative(32f, -6f, 58f, 13.5f)\n            reflectiveQuadToRelative(34f, 51.5f)\n            lineToRelative(7f, 31f)\n            quadToRelative(5f, 20f, -6f, 32f)\n            reflectiveQuadToRelative(-26f, 14f)\n            quadToRelative(-15f, 2f, -28.5f, -5.5f)\n            reflectiveQuadTo(600f, 190f)\n            lineToRelative(-7f, -30f)\n            lineToRelative(-433f, 77f)\n            lineToRelative(60f, 344f)\n            quadToRelative(3f, 17f, -6f, 30.5f)\n            reflectiveQuadTo(188f, 628f)\n            quadToRelative(-17f, 3f, -30f, -6.5f)\n            reflectiveQuadTo(142f, 595f)\n            lineTo(81f, 250f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/StackStickyOff.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.StackStickyOff: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.StackStickyOff\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(14.825f, 4f)\n            lineToRelative(0.175f, 0.75f)\n            curveToRelative(0.083f, 0.333f, 0.237f, 0.563f, 0.463f, 0.688f)\n            curveToRelative(0.225f, 0.125f, 0.462f, 0.171f, 0.712f, 0.138f)\n            reflectiveCurveToRelative(0.467f, -0.15f, 0.65f, -0.35f)\n            curveToRelative(0.183f, -0.2f, 0.233f, -0.467f, 0.15f, -0.8f)\n            lineToRelative(-0.175f, -0.775f)\n            curveToRelative(-0.133f, -0.533f, -0.417f, -0.963f, -0.85f, -1.288f)\n            reflectiveCurveToRelative(-0.917f, -0.438f, -1.45f, -0.337f)\n            lineToRelative(-9.38f, 1.664f)\n            lineToRelative(1.729f, 1.729f)\n            lineToRelative(7.976f, -1.418f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 7.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-10.975f)\n            curveToRelative(-0.183f, 0f, -0.355f, 0.029f, -0.522f, 0.072f)\n            lineToRelative(1.928f, 1.928f)\n            horizontalLineToRelative(9.569f)\n            verticalLineToRelative(7f)\n            horizontalLineToRelative(-2.569f)\n            lineToRelative(2.785f, 2.785f)\n            lineToRelative(1.21f, -1.21f)\n            curveToRelative(0.183f, -0.183f, 0.325f, -0.396f, 0.425f, -0.638f)\n            curveToRelative(0.1f, -0.242f, 0.15f, -0.496f, 0.15f, -0.763f)\n            verticalLineToRelative(-7.175f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(2.49f, 3.844f)\n            curveToRelative(-0.395f, -0.395f, -1.036f, -0.395f, -1.431f, 0f)\n            curveToRelative(-0.395f, 0.395f, -0.395f, 1.036f, 0f, 1.431f)\n            lineToRelative(0.965f, 0.965f)\n            curveToRelative(0.001f, 0.004f, 0f, 0.007f, 0.001f, 0.01f)\n            lineToRelative(1.525f, 8.625f)\n            curveToRelative(0.05f, 0.283f, 0.183f, 0.504f, 0.4f, 0.662f)\n            curveToRelative(0.217f, 0.158f, 0.467f, 0.213f, 0.75f, 0.163f)\n            reflectiveCurveToRelative(0.5f, -0.188f, 0.65f, -0.413f)\n            curveToRelative(0.15f, -0.225f, 0.2f, -0.479f, 0.15f, -0.762f)\n            lineToRelative(-1.016f, -5.826f)\n            lineToRelative(2.516f, 2.516f)\n            verticalLineToRelative(8.784f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(7.175f)\n            curveToRelative(0.267f, 0f, 0.521f, -0.05f, 0.763f, -0.15f)\n            curveToRelative(0.16f, -0.066f, 0.302f, -0.157f, 0.437f, -0.26f)\n            lineToRelative(1.244f, 1.244f)\n            curveToRelative(0.395f, 0.395f, 1.036f, 0.395f, 1.431f, 0f)\n            reflectiveCurveToRelative(0.395f, -1.036f, 0f, -1.431f)\n            lineTo(2.49f, 3.844f)\n            close()\n            moveTo(9f, 20f)\n            verticalLineToRelative(-6.784f)\n            lineToRelative(6.785f, 6.784f)\n            horizontalLineToRelative(-6.785f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Stacks.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Stacks: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Stacks\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11.512f, 13.662f)\n            curveToRelative(-0.158f, -0.042f, -0.313f, -0.104f, -0.463f, -0.188f)\n            lineTo(2.6f, 8.875f)\n            curveToRelative(-0.183f, -0.1f, -0.313f, -0.225f, -0.387f, -0.375f)\n            reflectiveCurveToRelative(-0.112f, -0.317f, -0.112f, -0.5f)\n            reflectiveCurveToRelative(0.038f, -0.35f, 0.112f, -0.5f)\n            reflectiveCurveToRelative(0.204f, -0.275f, 0.387f, -0.375f)\n            lineTo(11.05f, 2.525f)\n            curveToRelative(0.15f, -0.083f, 0.304f, -0.146f, 0.463f, -0.188f)\n            reflectiveCurveToRelative(0.321f, -0.063f, 0.488f, -0.063f)\n            reflectiveCurveToRelative(0.329f, 0.021f, 0.488f, 0.063f)\n            reflectiveCurveToRelative(0.313f, 0.104f, 0.463f, 0.188f)\n            lineToRelative(8.45f, 4.6f)\n            curveToRelative(0.183f, 0.1f, 0.313f, 0.225f, 0.387f, 0.375f)\n            reflectiveCurveToRelative(0.112f, 0.317f, 0.112f, 0.5f)\n            reflectiveCurveToRelative(-0.038f, 0.35f, -0.112f, 0.5f)\n            reflectiveCurveToRelative(-0.204f, 0.275f, -0.387f, 0.375f)\n            lineToRelative(-8.45f, 4.6f)\n            curveToRelative(-0.15f, 0.083f, -0.304f, 0.146f, -0.463f, 0.188f)\n            reflectiveCurveToRelative(-0.321f, 0.063f, -0.488f, 0.063f)\n            reflectiveCurveToRelative(-0.329f, -0.021f, -0.488f, -0.063f)\n            close()\n            moveTo(12f, 11.725f)\n            lineToRelative(6.825f, -3.725f)\n            lineToRelative(-6.825f, -3.725f)\n            lineToRelative(-6.825f, 3.725f)\n            lineToRelative(6.825f, 3.725f)\n            close()\n            moveTo(12f, 15.725f)\n            lineToRelative(7.85f, -4.275f)\n            curveToRelative(0.033f, -0.017f, 0.192f, -0.058f, 0.475f, -0.125f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            curveToRelative(0f, 0.183f, -0.042f, 0.35f, -0.125f, 0.5f)\n            reflectiveCurveToRelative(-0.217f, 0.275f, -0.4f, 0.375f)\n            lineToRelative(-7.85f, 4.275f)\n            curveToRelative(-0.15f, 0.083f, -0.304f, 0.146f, -0.463f, 0.188f)\n            reflectiveCurveToRelative(-0.321f, 0.063f, -0.488f, 0.063f)\n            reflectiveCurveToRelative(-0.329f, -0.021f, -0.488f, -0.063f)\n            reflectiveCurveToRelative(-0.313f, -0.104f, -0.463f, -0.188f)\n            lineToRelative(-7.85f, -4.275f)\n            curveToRelative(-0.183f, -0.1f, -0.317f, -0.225f, -0.4f, -0.375f)\n            reflectiveCurveToRelative(-0.125f, -0.317f, -0.125f, -0.5f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.083f, 0f, 0.162f, 0.013f, 0.237f, 0.038f)\n            reflectiveCurveToRelative(0.154f, 0.054f, 0.237f, 0.087f)\n            lineToRelative(7.85f, 4.275f)\n            close()\n            moveTo(12f, 19.725f)\n            lineToRelative(7.85f, -4.275f)\n            curveToRelative(0.033f, -0.017f, 0.192f, -0.058f, 0.475f, -0.125f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            curveToRelative(0f, 0.183f, -0.042f, 0.35f, -0.125f, 0.5f)\n            reflectiveCurveToRelative(-0.217f, 0.275f, -0.4f, 0.375f)\n            lineToRelative(-7.85f, 4.275f)\n            curveToRelative(-0.15f, 0.083f, -0.304f, 0.146f, -0.463f, 0.188f)\n            reflectiveCurveToRelative(-0.321f, 0.063f, -0.488f, 0.063f)\n            reflectiveCurveToRelative(-0.329f, -0.021f, -0.488f, -0.063f)\n            reflectiveCurveToRelative(-0.313f, -0.104f, -0.463f, -0.188f)\n            lineToRelative(-7.85f, -4.275f)\n            curveToRelative(-0.183f, -0.1f, -0.317f, -0.225f, -0.4f, -0.375f)\n            reflectiveCurveToRelative(-0.125f, -0.317f, -0.125f, -0.5f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.083f, 0f, 0.162f, 0.013f, 0.237f, 0.038f)\n            reflectiveCurveToRelative(0.154f, 0.054f, 0.237f, 0.087f)\n            lineToRelative(7.85f, 4.275f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Stacks: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Stacks\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.787f, 7.5f)\n            curveToRelative(-0.075f, -0.15f, -0.204f, -0.275f, -0.387f, -0.375f)\n            lineTo(12.95f, 2.525f)\n            curveToRelative(-0.15f, -0.083f, -0.304f, -0.146f, -0.463f, -0.188f)\n            curveToRelative(-0.158f, -0.042f, -0.321f, -0.063f, -0.487f, -0.063f)\n            reflectiveCurveToRelative(-0.329f, 0.021f, -0.487f, 0.063f)\n            curveToRelative(-0.158f, 0.042f, -0.313f, 0.104f, -0.463f, 0.188f)\n            lineTo(2.6f, 7.125f)\n            curveToRelative(-0.183f, 0.1f, -0.313f, 0.225f, -0.387f, 0.375f)\n            curveToRelative(-0.075f, 0.15f, -0.113f, 0.317f, -0.113f, 0.5f)\n            reflectiveCurveToRelative(0.038f, 0.35f, 0.113f, 0.5f)\n            curveToRelative(0.075f, 0.15f, 0.204f, 0.275f, 0.387f, 0.375f)\n            lineToRelative(8.45f, 4.6f)\n            curveToRelative(0.15f, 0.083f, 0.304f, 0.146f, 0.463f, 0.188f)\n            curveToRelative(0.158f, 0.042f, 0.321f, 0.063f, 0.487f, 0.063f)\n            reflectiveCurveToRelative(0.329f, -0.021f, 0.487f, -0.063f)\n            curveToRelative(0.158f, -0.042f, 0.313f, -0.104f, 0.463f, -0.188f)\n            lineToRelative(8.45f, -4.6f)\n            curveToRelative(0.183f, -0.1f, 0.313f, -0.225f, 0.387f, -0.375f)\n            curveToRelative(0.075f, -0.15f, 0.113f, -0.317f, 0.113f, -0.5f)\n            reflectiveCurveToRelative(-0.038f, -0.35f, -0.113f, -0.5f)\n            close()\n            moveTo(12f, 11.725f)\n            lineToRelative(-6.825f, -3.725f)\n            lineToRelative(6.825f, -3.725f)\n            lineToRelative(6.825f, 3.725f)\n            lineToRelative(-6.825f, 3.725f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 15.725f)\n            lineToRelative(7.85f, -4.275f)\n            curveToRelative(0.033f, -0.017f, 0.192f, -0.058f, 0.475f, -0.125f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            curveToRelative(0f, 0.183f, -0.042f, 0.35f, -0.125f, 0.5f)\n            reflectiveCurveToRelative(-0.217f, 0.275f, -0.4f, 0.375f)\n            lineToRelative(-7.85f, 4.275f)\n            curveToRelative(-0.15f, 0.083f, -0.304f, 0.146f, -0.463f, 0.188f)\n            reflectiveCurveToRelative(-0.321f, 0.063f, -0.488f, 0.063f)\n            reflectiveCurveToRelative(-0.329f, -0.021f, -0.488f, -0.063f)\n            reflectiveCurveToRelative(-0.313f, -0.104f, -0.463f, -0.188f)\n            lineToRelative(-7.85f, -4.275f)\n            curveToRelative(-0.183f, -0.1f, -0.317f, -0.225f, -0.4f, -0.375f)\n            reflectiveCurveToRelative(-0.125f, -0.317f, -0.125f, -0.5f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.083f, 0f, 0.162f, 0.013f, 0.237f, 0.038f)\n            reflectiveCurveToRelative(0.154f, 0.054f, 0.237f, 0.087f)\n            lineToRelative(7.85f, 4.275f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 19.725f)\n            lineToRelative(7.85f, -4.275f)\n            curveToRelative(0.033f, -0.017f, 0.192f, -0.058f, 0.475f, -0.125f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            curveToRelative(0f, 0.183f, -0.042f, 0.35f, -0.125f, 0.5f)\n            reflectiveCurveToRelative(-0.217f, 0.275f, -0.4f, 0.375f)\n            lineToRelative(-7.85f, 4.275f)\n            curveToRelative(-0.15f, 0.083f, -0.304f, 0.146f, -0.463f, 0.188f)\n            reflectiveCurveToRelative(-0.321f, 0.063f, -0.488f, 0.063f)\n            reflectiveCurveToRelative(-0.329f, -0.021f, -0.488f, -0.063f)\n            reflectiveCurveToRelative(-0.313f, -0.104f, -0.463f, -0.188f)\n            lineToRelative(-7.85f, -4.275f)\n            curveToRelative(-0.183f, -0.1f, -0.317f, -0.225f, -0.4f, -0.375f)\n            reflectiveCurveToRelative(-0.125f, -0.317f, -0.125f, -0.5f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.083f, 0f, 0.162f, 0.013f, 0.237f, 0.038f)\n            reflectiveCurveToRelative(0.154f, 0.054f, 0.237f, 0.087f)\n            lineToRelative(7.85f, 4.275f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 11.725f)\n            lineToRelative(6.825f, -3.725f)\n            lineToRelative(-6.825f, -3.725f)\n            lineToRelative(-6.825f, 3.725f)\n            lineToRelative(6.825f, 3.725f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.Stacks: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Stacks\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.787f, 7.5f)\n            curveToRelative(-0.075f, -0.15f, -0.204f, -0.275f, -0.387f, -0.375f)\n            lineTo(12.95f, 2.525f)\n            curveToRelative(-0.15f, -0.083f, -0.304f, -0.146f, -0.463f, -0.188f)\n            curveToRelative(-0.158f, -0.042f, -0.321f, -0.063f, -0.487f, -0.063f)\n            reflectiveCurveToRelative(-0.329f, 0.021f, -0.487f, 0.063f)\n            curveToRelative(-0.158f, 0.042f, -0.313f, 0.104f, -0.463f, 0.188f)\n            lineTo(2.6f, 7.125f)\n            curveToRelative(-0.183f, 0.1f, -0.313f, 0.225f, -0.387f, 0.375f)\n            curveToRelative(-0.075f, 0.15f, -0.113f, 0.317f, -0.113f, 0.5f)\n            reflectiveCurveToRelative(0.038f, 0.35f, 0.113f, 0.5f)\n            curveToRelative(0.075f, 0.15f, 0.204f, 0.275f, 0.387f, 0.375f)\n            lineToRelative(8.45f, 4.6f)\n            curveToRelative(0.15f, 0.083f, 0.304f, 0.146f, 0.463f, 0.188f)\n            curveToRelative(0.158f, 0.042f, 0.321f, 0.063f, 0.487f, 0.063f)\n            reflectiveCurveToRelative(0.329f, -0.021f, 0.487f, -0.063f)\n            curveToRelative(0.158f, -0.042f, 0.313f, -0.104f, 0.463f, -0.188f)\n            lineToRelative(8.45f, -4.6f)\n            curveToRelative(0.183f, -0.1f, 0.313f, -0.225f, 0.387f, -0.375f)\n            curveToRelative(0.075f, -0.15f, 0.113f, -0.317f, 0.113f, -0.5f)\n            reflectiveCurveToRelative(-0.038f, -0.35f, -0.113f, -0.5f)\n            close()\n            moveTo(12f, 11.725f)\n            lineToRelative(-6.825f, -3.725f)\n            lineToRelative(6.825f, -3.725f)\n            lineToRelative(6.825f, 3.725f)\n            lineToRelative(-6.825f, 3.725f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 15.725f)\n            lineToRelative(7.85f, -4.275f)\n            curveToRelative(0.033f, -0.017f, 0.192f, -0.058f, 0.475f, -0.125f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            curveToRelative(0f, 0.183f, -0.042f, 0.35f, -0.125f, 0.5f)\n            reflectiveCurveToRelative(-0.217f, 0.275f, -0.4f, 0.375f)\n            lineToRelative(-7.85f, 4.275f)\n            curveToRelative(-0.15f, 0.083f, -0.304f, 0.146f, -0.463f, 0.188f)\n            reflectiveCurveToRelative(-0.321f, 0.063f, -0.488f, 0.063f)\n            reflectiveCurveToRelative(-0.329f, -0.021f, -0.488f, -0.063f)\n            reflectiveCurveToRelative(-0.313f, -0.104f, -0.463f, -0.188f)\n            lineToRelative(-7.85f, -4.275f)\n            curveToRelative(-0.183f, -0.1f, -0.317f, -0.225f, -0.4f, -0.375f)\n            reflectiveCurveToRelative(-0.125f, -0.317f, -0.125f, -0.5f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.083f, 0f, 0.162f, 0.013f, 0.237f, 0.038f)\n            reflectiveCurveToRelative(0.154f, 0.054f, 0.237f, 0.087f)\n            lineToRelative(7.85f, 4.275f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 19.725f)\n            lineToRelative(7.85f, -4.275f)\n            curveToRelative(0.033f, -0.017f, 0.192f, -0.058f, 0.475f, -0.125f)\n            curveToRelative(0.283f, 0f, 0.521f, 0.096f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.287f, 0.429f, 0.287f, 0.712f)\n            curveToRelative(0f, 0.183f, -0.042f, 0.35f, -0.125f, 0.5f)\n            reflectiveCurveToRelative(-0.217f, 0.275f, -0.4f, 0.375f)\n            lineToRelative(-7.85f, 4.275f)\n            curveToRelative(-0.15f, 0.083f, -0.304f, 0.146f, -0.463f, 0.188f)\n            reflectiveCurveToRelative(-0.321f, 0.063f, -0.488f, 0.063f)\n            reflectiveCurveToRelative(-0.329f, -0.021f, -0.488f, -0.063f)\n            reflectiveCurveToRelative(-0.313f, -0.104f, -0.463f, -0.188f)\n            lineToRelative(-7.85f, -4.275f)\n            curveToRelative(-0.183f, -0.1f, -0.317f, -0.225f, -0.4f, -0.375f)\n            reflectiveCurveToRelative(-0.125f, -0.317f, -0.125f, -0.5f)\n            curveToRelative(0f, -0.283f, 0.096f, -0.521f, 0.287f, -0.712f)\n            reflectiveCurveToRelative(0.429f, -0.287f, 0.712f, -0.287f)\n            curveToRelative(0.083f, 0f, 0.162f, 0.013f, 0.237f, 0.038f)\n            reflectiveCurveToRelative(0.154f, 0.054f, 0.237f, 0.087f)\n            lineToRelative(7.85f, 4.275f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black)\n        ) {\n            moveTo(12f, 11.725f)\n            lineToRelative(6.825f, -3.725f)\n            lineToRelative(-6.825f, -3.725f)\n            lineToRelative(-6.825f, 3.725f)\n            lineToRelative(6.825f, 3.725f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/StampedLine.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.StampedLine: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"StampedLine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(7.427f, 17.754f)\n            curveToRelative(0.116f, 0.124f, 0.118f, 0.317f, 0.003f, 0.443f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.072f, 0.079f, -0.101f, 0.189f, -0.077f, 0.294f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.039f, 0.166f, -0.057f, 0.333f, -0.219f, 0.385f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.102f, 0.033f, -0.182f, 0.113f, -0.213f, 0.216f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.05f, 0.163f, -0.216f, 0.26f, -0.382f, 0.224f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.105f, -0.023f, -0.214f, 0.007f, -0.293f, 0.081f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.124f, 0.116f, -0.317f, 0.118f, -0.443f, 0.003f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.079f, -0.072f, -0.189f, -0.101f, -0.294f, -0.077f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.166f, 0.039f, -0.333f, -0.057f, -0.385f, -0.219f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.033f, -0.102f, -0.113f, -0.182f, -0.216f, -0.213f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.163f, -0.05f, -0.26f, -0.216f, -0.224f, -0.382f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.023f, -0.105f, -0.007f, -0.214f, -0.081f, -0.293f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.116f, -0.124f, -0.118f, -0.317f, -0.003f, -0.443f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.072f, -0.079f, 0.101f, -0.189f, 0.077f, -0.294f)\n            lineToRelative(0f, 0f)\n            curveToRelative(-0.039f, -0.166f, 0.057f, -0.333f, 0.219f, -0.385f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.102f, -0.033f, 0.182f, -0.113f, 0.213f, -0.216f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.05f, -0.163f, 0.216f, -0.26f, 0.382f, -0.224f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.105f, 0.023f, 0.214f, -0.007f, 0.293f, -0.081f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.124f, -0.116f, 0.317f, -0.118f, 0.443f, -0.003f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.079f, 0.072f, 0.189f, 0.101f, 0.294f, 0.077f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.166f, -0.039f, 0.333f, 0.057f, 0.385f, 0.219f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.033f, 0.102f, 0.113f, 0.182f, 0.216f, 0.213f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.163f, 0.05f, 0.26f, 0.216f, 0.224f, 0.382f)\n            lineToRelative(0f, 0f)\n            curveTo(7.324f, 17.566f, 7.354f, 17.676f, 7.427f, 17.754f)\n            lineTo(7.427f, 17.754f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(18.015f, 4.515f)\n            curveToRelative(-0.022f, -0.011f, -0.048f, -0.011f, -0.07f, 0.002f)\n            curveToRelative(-0.123f, 0.071f, -0.537f, 0.306f, -0.629f, 0.306f)\n            curveToRelative(-0.076f, 0f, -0.432f, -0.158f, -0.642f, -0.254f)\n            curveToRelative(-0.059f, -0.027f, -0.12f, 0.029f, -0.1f, 0.09f)\n            curveToRelative(0.078f, 0.233f, 0.21f, 0.639f, 0.187f, 0.678f)\n            curveToRelative(-0.029f, 0.047f, -0.214f, 0.527f, -0.264f, 0.654f)\n            curveToRelative(-0.008f, 0.02f, -0.006f, 0.041f, 0.004f, 0.06f)\n            curveToRelative(0.062f, 0.117f, 0.286f, 0.554f, 0.268f, 0.652f)\n            curveToRelative(-0.015f, 0.08f, -0.15f, 0.435f, -0.228f, 0.638f)\n            curveToRelative(-0.022f, 0.058f, 0.032f, 0.115f, 0.091f, 0.096f)\n            curveToRelative(0.224f, -0.071f, 0.632f, -0.2f, 0.668f, -0.2f)\n            curveToRelative(0.044f, 0f, 0.563f, 0.212f, 0.69f, 0.264f)\n            curveToRelative(0.018f, 0.008f, 0.038f, 0.007f, 0.056f, 0f)\n            curveToRelative(0.129f, -0.054f, 0.664f, -0.277f, 0.686f, -0.277f)\n            curveToRelative(0.018f, 0f, 0.369f, 0.134f, 0.569f, 0.211f)\n            curveToRelative(0.056f, 0.022f, 0.113f, -0.03f, 0.097f, -0.088f)\n            curveToRelative(-0.058f, -0.209f, -0.16f, -0.584f, -0.157f, -0.628f)\n            curveToRelative(0.004f, -0.055f, 0.198f, -0.573f, 0.248f, -0.704f)\n            curveToRelative(0.007f, -0.019f, 0.006f, -0.04f, -0.003f, -0.059f)\n            curveToRelative(-0.057f, -0.114f, -0.265f, -0.537f, -0.261f, -0.645f)\n            curveToRelative(0.003f, -0.085f, 0.122f, -0.434f, 0.198f, -0.646f)\n            curveToRelative(0.022f, -0.062f, -0.042f, -0.119f, -0.101f, -0.091f)\n            curveToRelative(-0.218f, 0.104f, -0.583f, 0.277f, -0.615f, 0.277f)\n            curveTo(18.667f, 4.852f, 18.155f, 4.588f, 18.015f, 4.515f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(7.424f, 15.775f)\n            curveToRelative(0f, 0.399f, 0.321f, 0.722f, 0.717f, 0.722f)\n            curveToRelative(0.108f, 0f, 0.21f, -0.024f, 0.302f, -0.067f)\n            curveToRelative(0f, 0f, 0.001f, -0f, 0.002f, -0.001f)\n            curveToRelative(0.009f, -0.004f, 0.017f, -0.008f, 0.026f, -0.013f)\n            curveToRelative(0.085f, -0.041f, 0.346f, -0.165f, 0.468f, -0.174f)\n            curveToRelative(0.146f, -0.011f, 0.403f, 0.068f, 0.403f, 0.068f)\n            lineToRelative(0.216f, 0.104f)\n            curveToRelative(0.014f, 0.007f, 0.028f, 0.014f, 0.043f, 0.021f)\n            lineToRelative(0.001f, 0f)\n            horizontalLineToRelative(0f)\n            curveToRelative(0.061f, 0.027f, 0.125f, 0.045f, 0.193f, 0.054f)\n            horizontalLineToRelative(0f)\n            lineToRelative(0f, 0f)\n            curveToRelative(0.018f, 0.002f, 0.036f, 0.004f, 0.055f, 0.005f)\n            horizontalLineToRelative(0f)\n            curveToRelative(0.013f, 0.001f, 0.026f, 0.001f, 0.039f, 0.001f)\n            curveToRelative(0.396f, 0f, 0.717f, -0.324f, 0.717f, -0.722f)\n            verticalLineTo(15.772f)\n            curveToRelative(0f, -0.135f, -0.037f, -0.262f, -0.101f, -0.37f)\n            lineTo(9.664f, 13.902f)\n            curveToRelative(-0.118f, -0.237f, -0.361f, -0.4f, -0.642f, -0.4f)\n            curveToRelative(-0.281f, 0f, -0.524f, 0.163f, -0.642f, 0.4f)\n            lineToRelative(-0.839f, 1.473f)\n            curveToRelative(-0.016f, 0.024f, -0.03f, 0.05f, -0.043f, 0.076f)\n            lineTo(7.498f, 15.452f)\n            curveToRelative(-0.047f, 0.096f, -0.074f, 0.205f, -0.074f, 0.32f)\n            verticalLineToRelative(0.003f)\n            horizontalLineTo(7.424f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(12f, 10.5f)\n            curveToRelative(-0.828f, 0f, -1.5f, 0.672f, -1.5f, 1.5f)\n            curveToRelative(0f, 0.014f, 0f, 0.029f, 0.001f, 0.043f)\n            curveTo(10.5f, 12.05f, 10.5f, 12.057f, 10.5f, 12.064f)\n            verticalLineToRelative(1.085f)\n            curveTo(10.5f, 13.343f, 10.657f, 13.5f, 10.851f, 13.5f)\n            horizontalLineToRelative(1.105f)\n            curveToRelative(0.005f, 0f, 0.01f, -0f, 0.014f, -0f)\n            curveTo(11.98f, 13.5f, 11.99f, 13.5f, 12f, 13.5f)\n            curveToRelative(0.828f, 0f, 1.5f, -0.672f, 1.5f, -1.5f)\n            reflectiveCurveTo(12.828f, 10.5f, 12f, 10.5f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(16.132f, 10.14f)\n            curveToRelative(0f, 0f, -0.096f, -0.124f, 0f, -0.301f)\n            curveToRelative(0.599f, -0.999f, 0.285f, -2.17f, 0.285f, -2.17f)\n            lineToRelative(-0.285f, 0.204f)\n            curveToRelative(0f, 0f, -0.131f, 0.088f, -0.293f, 0f)\n            curveToRelative(-1.002f, -0.598f, -2.177f, -0.285f, -2.177f, -0.285f)\n            lineToRelative(0.205f, 0.285f)\n            curveToRelative(0f, 0f, 0.105f, 0.107f, 0f, 0.302f)\n            curveToRelative(-0.004f, 0.006f, -0.006f, 0.012f, -0.01f, 0.017f)\n            curveToRelative(-0.586f, 0.995f, -0.275f, 2.153f, -0.275f, 2.153f)\n            lineToRelative(0.285f, -0.204f)\n            curveToRelative(0f, 0f, 0.124f, -0.092f, 0.293f, 0f)\n            curveToRelative(1.002f, 0.598f, 2.177f, 0.285f, 2.177f, 0.285f)\n            lineTo(16.132f, 10.14f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/StarSticky.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.StarSticky: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.StarSticky\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.412f, 3.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(5f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(10.175f)\n            curveToRelative(0.267f, 0f, 0.521f, -0.05f, 0.763f, -0.15f)\n            curveToRelative(0.242f, -0.1f, 0.454f, -0.242f, 0.638f, -0.425f)\n            lineToRelative(3.85f, -3.85f)\n            curveToRelative(0.183f, -0.183f, 0.325f, -0.396f, 0.425f, -0.638f)\n            curveToRelative(0.1f, -0.242f, 0.15f, -0.496f, 0.15f, -0.763f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(19f, 15f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(2f)\n            horizontalLineTo(5f)\n            verticalLineTo(5f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(10f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 19f)\n            verticalLineTo(5f)\n            verticalLineToRelative(14f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12.11f, 13.595f)\n            lineToRelative(1.938f, 1.454f)\n            curveToRelative(0.114f, 0.095f, 0.223f, 0.105f, 0.328f, 0.029f)\n            reflectiveCurveToRelative(0.138f, -0.181f, 0.1f, -0.314f)\n            lineToRelative(-0.713f, -2.423f)\n            lineToRelative(1.995f, -1.596f)\n            curveToRelative(0.095f, -0.095f, 0.124f, -0.204f, 0.086f, -0.328f)\n            reflectiveCurveToRelative(-0.124f, -0.185f, -0.257f, -0.185f)\n            horizontalLineToRelative(-2.451f)\n            lineToRelative(-0.741f, -2.337f)\n            curveToRelative(-0.038f, -0.133f, -0.133f, -0.2f, -0.285f, -0.2f)\n            reflectiveCurveToRelative(-0.247f, 0.067f, -0.285f, 0.2f)\n            lineToRelative(-0.741f, 2.337f)\n            horizontalLineToRelative(-2.451f)\n            curveToRelative(-0.133f, 0f, -0.219f, 0.062f, -0.257f, 0.185f)\n            reflectiveCurveToRelative(-0.01f, 0.233f, 0.086f, 0.328f)\n            lineToRelative(1.995f, 1.596f)\n            lineToRelative(-0.713f, 2.423f)\n            curveToRelative(-0.038f, 0.133f, -0.005f, 0.238f, 0.1f, 0.314f)\n            reflectiveCurveToRelative(0.214f, 0.067f, 0.328f, -0.029f)\n            lineToRelative(1.938f, -1.454f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/StickerEmoji.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.StickerEmoji: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.StickerEmoji\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(5.5f, 2f)\n            curveTo(3.56f, 2f, 2f, 3.56f, 2f, 5.5f)\n            verticalLineTo(18.5f)\n            curveTo(2f, 20.44f, 3.56f, 22f, 5.5f, 22f)\n            horizontalLineTo(16f)\n            lineTo(22f, 16f)\n            verticalLineTo(5.5f)\n            curveTo(22f, 3.56f, 20.44f, 2f, 18.5f, 2f)\n            horizontalLineTo(5.5f)\n            moveTo(5.75f, 4f)\n            horizontalLineTo(18.25f)\n            arcTo(1.75f, 1.75f, 0f, isMoreThanHalf = false, isPositiveArc = true, 20f, 5.75f)\n            verticalLineTo(15f)\n            horizontalLineTo(18.5f)\n            curveTo(16.56f, 15f, 15f, 16.56f, 15f, 18.5f)\n            verticalLineTo(20f)\n            horizontalLineTo(5.75f)\n            arcTo(1.75f, 1.75f, 0f, isMoreThanHalf = false, isPositiveArc = true, 4f, 18.25f)\n            verticalLineTo(5.75f)\n            arcTo(1.75f, 1.75f, 0f, isMoreThanHalf = false, isPositiveArc = true, 5.75f, 4f)\n            moveTo(14.44f, 6.77f)\n            curveTo(14.28f, 6.77f, 14.12f, 6.79f, 13.97f, 6.83f)\n            curveTo(13.03f, 7.09f, 12.5f, 8.05f, 12.74f, 9f)\n            curveTo(12.79f, 9.15f, 12.86f, 9.3f, 12.95f, 9.44f)\n            lineTo(16.18f, 8.56f)\n            curveTo(16.18f, 8.39f, 16.16f, 8.22f, 16.12f, 8.05f)\n            curveTo(15.91f, 7.3f, 15.22f, 6.77f, 14.44f, 6.77f)\n            moveTo(8.17f, 8.5f)\n            curveTo(8f, 8.5f, 7.85f, 8.5f, 7.7f, 8.55f)\n            curveTo(6.77f, 8.81f, 6.22f, 9.77f, 6.47f, 10.7f)\n            curveTo(6.5f, 10.86f, 6.59f, 11f, 6.68f, 11.16f)\n            lineTo(9.91f, 10.28f)\n            curveTo(9.91f, 10.11f, 9.89f, 9.94f, 9.85f, 9.78f)\n            curveTo(9.64f, 9f, 8.95f, 8.5f, 8.17f, 8.5f)\n            moveTo(16.72f, 11.26f)\n            lineTo(7.59f, 13.77f)\n            curveTo(8.91f, 15.3f, 11f, 15.94f, 12.95f, 15.41f)\n            curveTo(14.9f, 14.87f, 16.36f, 13.25f, 16.72f, 11.26f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Stylus.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Stylus: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"StylusFountainPen\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.727f, 8.55f)\n            curveToRelative(-0.044f, -0.177f, -0.137f, -0.336f, -0.279f, -0.478f)\n            lineToRelative(-5.732f, -5.281f)\n            curveToRelative(-0.195f, -0.195f, -0.433f, -0.292f, -0.716f, -0.292f)\n            reflectiveCurveToRelative(-0.522f, 0.097f, -0.716f, 0.292f)\n            lineToRelative(-5.732f, 5.281f)\n            curveToRelative(-0.141f, 0.142f, -0.234f, 0.301f, -0.279f, 0.478f)\n            curveToRelative(-0.044f, 0.177f, -0.049f, 0.363f, -0.013f, 0.557f)\n            lineToRelative(1.937f, 8.12f)\n            curveToRelative(0.053f, 0.248f, 0.177f, 0.447f, 0.372f, 0.597f)\n            reflectiveCurveToRelative(0.416f, 0.226f, 0.663f, 0.226f)\n            lineToRelative(7.536f, -0f)\n            curveToRelative(0.248f, 0f, 0.469f, -0.075f, 0.663f, -0.226f)\n            reflectiveCurveToRelative(0.318f, -0.349f, 0.372f, -0.597f)\n            lineToRelative(1.937f, -8.12f)\n            curveToRelative(0.035f, -0.195f, 0.031f, -0.38f, -0.013f, -0.557f)\n            close()\n            moveTo(14.919f, 15.927f)\n            lineToRelative(-5.838f, 0f)\n            lineToRelative(-1.619f, -6.714f)\n            lineToRelative(3.476f, -3.211f)\n            verticalLineToRelative(2.813f)\n            curveToRelative(-0.248f, 0.177f, -0.442f, 0.398f, -0.584f, 0.663f)\n            curveToRelative(-0.142f, 0.265f, -0.212f, 0.557f, -0.212f, 0.876f)\n            curveToRelative(0f, 0.513f, 0.181f, 0.951f, 0.544f, 1.314f)\n            curveToRelative(0.363f, 0.363f, 0.8f, 0.544f, 1.314f, 0.544f)\n            reflectiveCurveToRelative(0.951f, -0.181f, 1.314f, -0.544f)\n            curveToRelative(0.363f, -0.363f, 0.544f, -0.8f, 0.544f, -1.314f)\n            curveToRelative(0f, -0.318f, -0.071f, -0.61f, -0.212f, -0.876f)\n            curveToRelative(-0.141f, -0.265f, -0.336f, -0.486f, -0.584f, -0.663f)\n            lineToRelative(-0f, -2.813f)\n            lineToRelative(3.476f, 3.211f)\n            lineToRelative(-1.619f, 6.714f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.22f, 18.846f)\n            lineTo(15.78f, 18.846f)\n            arcTo(\n                0.997f,\n                0.997f,\n                0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                16.777f,\n                19.843f\n            )\n            lineTo(16.777f, 20.503f)\n            arcTo(0.997f, 0.997f, 0f, isMoreThanHalf = false, isPositiveArc = true, 15.78f, 21.5f)\n            lineTo(8.22f, 21.5f)\n            arcTo(0.997f, 0.997f, 0f, isMoreThanHalf = false, isPositiveArc = true, 7.223f, 20.503f)\n            lineTo(7.223f, 19.843f)\n            arcTo(0.997f, 0.997f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8.22f, 18.846f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Stylus: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoToneStylusFountainPen\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(18.727f, 8.55f)\n            curveToRelative(-0.044f, -0.177f, -0.137f, -0.336f, -0.279f, -0.478f)\n            lineToRelative(-5.732f, -5.281f)\n            curveToRelative(-0.195f, -0.195f, -0.433f, -0.292f, -0.716f, -0.292f)\n            reflectiveCurveToRelative(-0.522f, 0.097f, -0.716f, 0.292f)\n            lineToRelative(-5.732f, 5.281f)\n            curveToRelative(-0.141f, 0.142f, -0.234f, 0.301f, -0.279f, 0.478f)\n            curveToRelative(-0.044f, 0.177f, -0.049f, 0.363f, -0.013f, 0.557f)\n            lineToRelative(1.937f, 8.12f)\n            curveToRelative(0.053f, 0.248f, 0.177f, 0.447f, 0.372f, 0.597f)\n            reflectiveCurveToRelative(0.416f, 0.226f, 0.663f, 0.226f)\n            lineToRelative(7.536f, -0f)\n            curveToRelative(0.248f, 0f, 0.469f, -0.075f, 0.663f, -0.226f)\n            reflectiveCurveToRelative(0.318f, -0.349f, 0.372f, -0.597f)\n            lineToRelative(1.937f, -8.12f)\n            curveToRelative(0.035f, -0.195f, 0.031f, -0.38f, -0.013f, -0.557f)\n            close()\n            moveTo(14.919f, 15.927f)\n            lineToRelative(-5.838f, 0f)\n            lineToRelative(-1.619f, -6.714f)\n            lineToRelative(3.476f, -3.211f)\n            verticalLineToRelative(2.813f)\n            curveToRelative(-0.248f, 0.177f, -0.442f, 0.398f, -0.584f, 0.663f)\n            curveToRelative(-0.142f, 0.265f, -0.212f, 0.557f, -0.212f, 0.876f)\n            curveToRelative(0f, 0.513f, 0.181f, 0.951f, 0.544f, 1.314f)\n            curveToRelative(0.363f, 0.363f, 0.8f, 0.544f, 1.314f, 0.544f)\n            reflectiveCurveToRelative(0.951f, -0.181f, 1.314f, -0.544f)\n            curveToRelative(0.363f, -0.363f, 0.544f, -0.8f, 0.544f, -1.314f)\n            curveToRelative(0f, -0.318f, -0.071f, -0.61f, -0.212f, -0.876f)\n            curveToRelative(-0.141f, -0.265f, -0.336f, -0.486f, -0.584f, -0.663f)\n            lineToRelative(-0f, -2.813f)\n            lineToRelative(3.476f, 3.211f)\n            lineToRelative(-1.619f, 6.714f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.22f, 18.846f)\n            lineTo(15.78f, 18.846f)\n            arcTo(\n                0.997f,\n                0.997f,\n                0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                16.777f,\n                19.843f\n            )\n            lineTo(16.777f, 20.503f)\n            arcTo(0.997f, 0.997f, 0f, isMoreThanHalf = false, isPositiveArc = true, 15.78f, 21.5f)\n            lineTo(8.22f, 21.5f)\n            arcTo(0.997f, 0.997f, 0f, isMoreThanHalf = false, isPositiveArc = true, 7.223f, 20.503f)\n            lineTo(7.223f, 19.843f)\n            arcTo(0.997f, 0.997f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8.22f, 18.846f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(14.919f, 15.927f)\n            lineToRelative(-5.838f, 0f)\n            lineToRelative(-1.619f, -6.714f)\n            lineToRelative(3.476f, -3.211f)\n            lineToRelative(0f, 2.813f)\n            curveToRelative(-0.248f, 0.177f, -0.442f, 0.398f, -0.584f, 0.663f)\n            curveToRelative(-0.142f, 0.265f, -0.212f, 0.557f, -0.212f, 0.876f)\n            curveToRelative(0f, 0.513f, 0.181f, 0.951f, 0.544f, 1.314f)\n            reflectiveCurveToRelative(0.8f, 0.544f, 1.314f, 0.544f)\n            reflectiveCurveToRelative(0.951f, -0.181f, 1.314f, -0.544f)\n            reflectiveCurveToRelative(0.544f, -0.8f, 0.544f, -1.314f)\n            curveToRelative(0f, -0.318f, -0.071f, -0.61f, -0.212f, -0.876f)\n            curveToRelative(-0.141f, -0.265f, -0.336f, -0.486f, -0.584f, -0.663f)\n            lineToRelative(-0f, -2.813f)\n            lineToRelative(3.476f, 3.211f)\n            lineToRelative(-1.619f, 6.714f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Suffix.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Suffix: ImageVector by lazy {\n    Builder(\n        name = \"Suffix\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.8f, 4.6f)\n            horizontalLineToRelative(-1.5f)\n            lineToRelative(-4.8f, 11.0f)\n            horizontalLineToRelative(2.1f)\n            lineToRelative(0.9f, -2.2f)\n            horizontalLineToRelative(5.0f)\n            lineToRelative(0.9f, 2.2f)\n            horizontalLineToRelative(2.1f)\n            lineTo(12.8f, 4.6f)\n            close()\n            moveTo(10.1f, 11.6f)\n            lineToRelative(1.9f, -5.0f)\n            lineToRelative(1.9f, 5.0f)\n            horizontalLineTo(10.1f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(19.0f, 14.7f)\n            lineToRelative(0.0f, 2.5f)\n            lineToRelative(-12.0f, 0.0f)\n            lineToRelative(-2.3f, 0.0f)\n            lineToRelative(-1.3f, 0.0f)\n            lineToRelative(0.0f, 2.0f)\n            lineToRelative(1.3f, 0.0f)\n            lineToRelative(2.3f, 0.0f)\n            lineToRelative(12.0f, 0.0f)\n            lineToRelative(2.0f, 0.0f)\n            lineToRelative(0.0f, -2.0f)\n            lineToRelative(0.0f, -2.5f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Svg.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Svg: ImageVector by lazy {\n    Builder(\n        name = \"Svg\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp, viewportWidth\n        = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(5.13f, 10.71f)\n            horizontalLineTo(8.87f)\n            lineTo(6.22f, 8.06f)\n            curveTo(5.21f, 8.06f, 4.39f, 7.24f, 4.39f, 6.22f)\n            arcTo(\n                1.83f, 1.83f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 6.22f,\n                y1 = 4.39f\n            )\n            curveTo(7.24f, 4.39f, 8.06f, 5.21f, 8.06f, 6.22f)\n            lineTo(10.71f, 8.87f)\n            verticalLineTo(5.13f)\n            curveTo(10.0f, 4.41f, 10.0f, 3.25f, 10.71f, 2.54f)\n            curveTo(11.42f, 1.82f, 12.58f, 1.82f, 13.29f, 2.54f)\n            curveTo(14.0f, 3.25f, 14.0f, 4.41f, 13.29f, 5.13f)\n            verticalLineTo(8.87f)\n            lineTo(15.95f, 6.22f)\n            curveTo(15.95f, 5.21f, 16.76f, 4.39f, 17.78f, 4.39f)\n            curveTo(18.79f, 4.39f, 19.61f, 5.21f, 19.61f, 6.22f)\n            curveTo(19.61f, 7.24f, 18.79f, 8.06f, 17.78f, 8.06f)\n            lineTo(15.13f, 10.71f)\n            horizontalLineTo(18.87f)\n            curveTo(19.59f, 10.0f, 20.75f, 10.0f, 21.46f, 10.71f)\n            curveTo(22.18f, 11.42f, 22.18f, 12.58f, 21.46f, 13.29f)\n            curveTo(20.75f, 14.0f, 19.59f, 14.0f, 18.87f, 13.29f)\n            horizontalLineTo(15.13f)\n            lineTo(17.78f, 15.95f)\n            curveTo(18.79f, 15.95f, 19.61f, 16.76f, 19.61f, 17.78f)\n            arcTo(\n                1.83f, 1.83f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                x1 = 17.78f,\n                y1 = 19.61f\n            )\n            curveTo(16.76f, 19.61f, 15.95f, 18.79f, 15.95f, 17.78f)\n            lineTo(13.29f, 15.13f)\n            verticalLineTo(18.87f)\n            curveTo(14.0f, 19.59f, 14.0f, 20.75f, 13.29f, 21.46f)\n            curveTo(12.58f, 22.18f, 11.42f, 22.18f, 10.71f, 21.46f)\n            curveTo(10.0f, 20.75f, 10.0f, 19.59f, 10.71f, 18.87f)\n            verticalLineTo(15.13f)\n            lineTo(8.06f, 17.78f)\n            curveTo(8.06f, 18.79f, 7.24f, 19.61f, 6.22f, 19.61f)\n            curveTo(5.21f, 19.61f, 4.39f, 18.79f, 4.39f, 17.78f)\n            curveTo(4.39f, 16.76f, 5.21f, 15.95f, 6.22f, 15.95f)\n            lineTo(8.87f, 13.29f)\n            horizontalLineTo(5.13f)\n            curveTo(4.41f, 14.0f, 3.25f, 14.0f, 2.54f, 13.29f)\n            curveTo(1.82f, 12.58f, 1.82f, 11.42f, 2.54f, 10.71f)\n            curveTo(3.25f, 10.0f, 4.41f, 10.0f, 5.13f, 10.71f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SwapVerticalCircle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SwapVerticalCircle: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"SwapVerticalCircle\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9f, 8.85f)\n            verticalLineToRelative(3.15f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            verticalLineToRelative(-3.15f)\n            lineToRelative(0.9f, 0.875f)\n            curveToRelative(0.183f, 0.183f, 0.412f, 0.275f, 0.688f, 0.275f)\n            reflectiveCurveToRelative(0.512f, -0.1f, 0.712f, -0.3f)\n            curveToRelative(0.183f, -0.183f, 0.275f, -0.417f, 0.275f, -0.7f)\n            reflectiveCurveToRelative(-0.092f, -0.517f, -0.275f, -0.7f)\n            lineToRelative(-2.575f, -2.575f)\n            curveToRelative(-0.2f, -0.2f, -0.438f, -0.3f, -0.712f, -0.3f)\n            reflectiveCurveToRelative(-0.512f, 0.1f, -0.712f, 0.3f)\n            lineToRelative(-2.6f, 2.575f)\n            curveToRelative(-0.183f, 0.183f, -0.279f, 0.412f, -0.287f, 0.688f)\n            reflectiveCurveToRelative(0.087f, 0.512f, 0.287f, 0.712f)\n            curveToRelative(0.183f, 0.183f, 0.412f, 0.279f, 0.688f, 0.287f)\n            reflectiveCurveToRelative(0.512f, -0.079f, 0.712f, -0.262f)\n            lineToRelative(0.9f, -0.875f)\n            close()\n            moveTo(13f, 15.15f)\n            lineToRelative(-0.9f, -0.875f)\n            curveToRelative(-0.183f, -0.183f, -0.412f, -0.275f, -0.688f, -0.275f)\n            reflectiveCurveToRelative(-0.512f, 0.1f, -0.712f, 0.3f)\n            curveToRelative(-0.183f, 0.183f, -0.275f, 0.417f, -0.275f, 0.7f)\n            reflectiveCurveToRelative(0.092f, 0.517f, 0.275f, 0.7f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.2f, 0.2f, 0.438f, 0.3f, 0.712f, 0.3f)\n            reflectiveCurveToRelative(0.512f, -0.1f, 0.712f, -0.3f)\n            lineToRelative(2.575f, -2.6f)\n            curveToRelative(0.183f, -0.183f, 0.279f, -0.412f, 0.287f, -0.688f)\n            reflectiveCurveToRelative(-0.087f, -0.512f, -0.287f, -0.712f)\n            curveToRelative(-0.183f, -0.183f, -0.412f, -0.279f, -0.688f, -0.287f)\n            reflectiveCurveToRelative(-0.512f, 0.079f, -0.712f, 0.262f)\n            lineToRelative(-0.9f, 0.875f)\n            verticalLineToRelative(-3.15f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(3.15f)\n            close()\n            moveTo(12f, 22f)\n            curveToRelative(-1.383f, 0f, -2.683f, -0.262f, -3.9f, -0.788f)\n            reflectiveCurveToRelative(-2.275f, -1.237f, -3.175f, -2.138f)\n            reflectiveCurveToRelative(-1.612f, -1.958f, -2.138f, -3.175f)\n            reflectiveCurveToRelative(-0.788f, -2.517f, -0.788f, -3.9f)\n            curveToRelative(0f, -1.383f, 0.262f, -2.683f, 0.788f, -3.9f)\n            reflectiveCurveToRelative(1.237f, -2.275f, 2.138f, -3.175f)\n            reflectiveCurveToRelative(1.958f, -1.612f, 3.175f, -2.138f)\n            reflectiveCurveToRelative(2.517f, -0.788f, 3.9f, -0.788f)\n            curveToRelative(1.383f, 0f, 2.683f, 0.262f, 3.9f, 0.788f)\n            reflectiveCurveToRelative(2.275f, 1.237f, 3.175f, 2.138f)\n            reflectiveCurveToRelative(1.612f, 1.958f, 2.138f, 3.175f)\n            reflectiveCurveToRelative(0.788f, 2.517f, 0.788f, 3.9f)\n            curveToRelative(0f, 1.383f, -0.262f, 2.683f, -0.788f, 3.9f)\n            reflectiveCurveToRelative(-1.237f, 2.275f, -2.138f, 3.175f)\n            reflectiveCurveToRelative(-1.958f, 1.612f, -3.175f, 2.138f)\n            reflectiveCurveToRelative(-2.517f, 0.788f, -3.9f, 0.788f)\n            close()\n            moveTo(12f, 20f)\n            curveToRelative(2.233f, 0f, 4.125f, -0.775f, 5.675f, -2.325f)\n            reflectiveCurveToRelative(2.325f, -3.442f, 2.325f, -5.675f)\n            reflectiveCurveToRelative(-0.775f, -4.125f, -2.325f, -5.675f)\n            reflectiveCurveToRelative(-3.442f, -2.325f, -5.675f, -2.325f)\n            reflectiveCurveToRelative(-4.125f, 0.775f, -5.675f, 2.325f)\n            reflectiveCurveToRelative(-2.325f, 3.442f, -2.325f, 5.675f)\n            reflectiveCurveToRelative(0.775f, 4.125f, 2.325f, 5.675f)\n            reflectiveCurveToRelative(3.442f, 2.325f, 5.675f, 2.325f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.SwapVerticalCircle: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoToneSwapVerticalCircle\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9f, 8.85f)\n            verticalLineToRelative(3.15f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            verticalLineToRelative(-3.15f)\n            lineToRelative(0.9f, 0.875f)\n            curveToRelative(0.183f, 0.183f, 0.412f, 0.275f, 0.688f, 0.275f)\n            reflectiveCurveToRelative(0.512f, -0.1f, 0.712f, -0.3f)\n            curveToRelative(0.183f, -0.183f, 0.275f, -0.417f, 0.275f, -0.7f)\n            reflectiveCurveToRelative(-0.092f, -0.517f, -0.275f, -0.7f)\n            lineToRelative(-2.575f, -2.575f)\n            curveToRelative(-0.2f, -0.2f, -0.438f, -0.3f, -0.712f, -0.3f)\n            reflectiveCurveToRelative(-0.512f, 0.1f, -0.712f, 0.3f)\n            lineToRelative(-2.6f, 2.575f)\n            curveToRelative(-0.183f, 0.183f, -0.279f, 0.412f, -0.287f, 0.688f)\n            reflectiveCurveToRelative(0.087f, 0.512f, 0.287f, 0.712f)\n            curveToRelative(0.183f, 0.183f, 0.412f, 0.279f, 0.688f, 0.287f)\n            reflectiveCurveToRelative(0.512f, -0.079f, 0.712f, -0.262f)\n            lineToRelative(0.9f, -0.875f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13f, 15.15f)\n            lineToRelative(-0.9f, -0.875f)\n            curveToRelative(-0.183f, -0.183f, -0.412f, -0.275f, -0.688f, -0.275f)\n            reflectiveCurveToRelative(-0.512f, 0.1f, -0.712f, 0.3f)\n            curveToRelative(-0.183f, 0.183f, -0.275f, 0.417f, -0.275f, 0.7f)\n            reflectiveCurveToRelative(0.092f, 0.517f, 0.275f, 0.7f)\n            lineToRelative(2.6f, 2.6f)\n            curveToRelative(0.2f, 0.2f, 0.438f, 0.3f, 0.712f, 0.3f)\n            reflectiveCurveToRelative(0.512f, -0.1f, 0.712f, -0.3f)\n            lineToRelative(2.575f, -2.6f)\n            curveToRelative(0.183f, -0.183f, 0.279f, -0.412f, 0.287f, -0.688f)\n            reflectiveCurveToRelative(-0.087f, -0.512f, -0.287f, -0.712f)\n            curveToRelative(-0.183f, -0.183f, -0.412f, -0.279f, -0.688f, -0.287f)\n            reflectiveCurveToRelative(-0.512f, 0.079f, -0.712f, 0.262f)\n            lineToRelative(-0.9f, 0.875f)\n            verticalLineToRelative(-3.15f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            reflectiveCurveToRelative(-0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(3.15f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.213f, 8.1f)\n            curveToRelative(-0.525f, -1.217f, -1.238f, -2.275f, -2.138f, -3.175f)\n            curveToRelative(-0.9f, -0.9f, -1.958f, -1.612f, -3.175f, -2.138f)\n            curveToRelative(-1.217f, -0.525f, -2.517f, -0.787f, -3.9f, -0.787f)\n            reflectiveCurveToRelative(-2.683f, 0.263f, -3.9f, 0.787f)\n            curveToRelative(-1.217f, 0.525f, -2.275f, 1.238f, -3.175f, 2.138f)\n            curveToRelative(-0.9f, 0.9f, -1.612f, 1.958f, -2.138f, 3.175f)\n            curveToRelative(-0.525f, 1.217f, -0.787f, 2.517f, -0.787f, 3.9f)\n            reflectiveCurveToRelative(0.263f, 2.683f, 0.787f, 3.9f)\n            curveToRelative(0.525f, 1.217f, 1.238f, 2.275f, 2.138f, 3.175f)\n            curveToRelative(0.9f, 0.9f, 1.958f, 1.612f, 3.175f, 2.138f)\n            curveToRelative(1.217f, 0.525f, 2.517f, 0.787f, 3.9f, 0.787f)\n            reflectiveCurveToRelative(2.683f, -0.263f, 3.9f, -0.787f)\n            curveToRelative(1.217f, -0.525f, 2.275f, -1.238f, 3.175f, -2.138f)\n            curveToRelative(0.9f, -0.9f, 1.612f, -1.958f, 2.138f, -3.175f)\n            curveToRelative(0.525f, -1.217f, 0.787f, -2.517f, 0.787f, -3.9f)\n            reflectiveCurveToRelative(-0.263f, -2.683f, -0.787f, -3.9f)\n            close()\n            moveTo(17.675f, 17.675f)\n            curveToRelative(-1.55f, 1.55f, -3.442f, 2.325f, -5.675f, 2.325f)\n            reflectiveCurveToRelative(-4.125f, -0.775f, -5.675f, -2.325f)\n            reflectiveCurveToRelative(-2.325f, -3.442f, -2.325f, -5.675f)\n            reflectiveCurveToRelative(0.775f, -4.125f, 2.325f, -5.675f)\n            reflectiveCurveToRelative(3.442f, -2.325f, 5.675f, -2.325f)\n            reflectiveCurveToRelative(4.125f, 0.775f, 5.675f, 2.325f)\n            reflectiveCurveToRelative(2.325f, 3.442f, 2.325f, 5.675f)\n            reflectiveCurveToRelative(-0.775f, 4.125f, -2.325f, 5.675f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 20f)\n            curveToRelative(2.233f, 0f, 4.125f, -0.775f, 5.675f, -2.325f)\n            reflectiveCurveToRelative(2.325f, -3.442f, 2.325f, -5.675f)\n            reflectiveCurveToRelative(-0.775f, -4.125f, -2.325f, -5.675f)\n            reflectiveCurveToRelative(-3.442f, -2.325f, -5.675f, -2.325f)\n            reflectiveCurveToRelative(-4.125f, 0.775f, -5.675f, 2.325f)\n            reflectiveCurveToRelative(-2.325f, 3.442f, -2.325f, 5.675f)\n            reflectiveCurveToRelative(0.775f, 4.125f, 2.325f, 5.675f)\n            reflectiveCurveToRelative(3.442f, 2.325f, 5.675f, 2.325f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Swatch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Swatch: ImageVector by lazy {\n    Builder(\n        name = \"Swatch\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.0f, 14.0f)\n            horizontalLineTo(6.0f)\n            curveTo(3.8f, 14.0f, 2.0f, 15.8f, 2.0f, 18.0f)\n            reflectiveCurveTo(3.8f, 22.0f, 6.0f, 22.0f)\n            horizontalLineTo(20.0f)\n            curveTo(21.1f, 22.0f, 22.0f, 21.1f, 22.0f, 20.0f)\n            verticalLineTo(16.0f)\n            curveTo(22.0f, 14.9f, 21.1f, 14.0f, 20.0f, 14.0f)\n            moveTo(6.0f, 20.0f)\n            curveTo(4.9f, 20.0f, 4.0f, 19.1f, 4.0f, 18.0f)\n            reflectiveCurveTo(4.9f, 16.0f, 6.0f, 16.0f)\n            reflectiveCurveTo(8.0f, 16.9f, 8.0f, 18.0f)\n            reflectiveCurveTo(7.1f, 20.0f, 6.0f, 20.0f)\n            moveTo(6.3f, 12.0f)\n            lineTo(13.0f, 5.3f)\n            curveTo(13.8f, 4.5f, 15.0f, 4.5f, 15.8f, 5.3f)\n            lineTo(18.6f, 8.1f)\n            curveTo(19.4f, 8.9f, 19.4f, 10.1f, 18.6f, 10.9f)\n            lineTo(17.7f, 12.0f)\n            horizontalLineTo(6.3f)\n            moveTo(2.0f, 13.5f)\n            verticalLineTo(4.0f)\n            curveTo(2.0f, 2.9f, 2.9f, 2.0f, 4.0f, 2.0f)\n            horizontalLineTo(8.0f)\n            curveTo(9.1f, 2.0f, 10.0f, 2.9f, 10.0f, 4.0f)\n            verticalLineTo(5.5f)\n            lineTo(2.0f, 13.5f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Symbol.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Symbol: ImageVector by lazy {\n    Builder(\n        name = \"Symbol\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(2.0f, 7.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(4.0f)\n            verticalLineTo(7.0f)\n            horizontalLineTo(2.0f)\n            moveTo(6.0f, 7.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(10.0f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(10.0f)\n            verticalLineTo(13.0f)\n            curveTo(11.11f, 13.0f, 12.0f, 12.11f, 12.0f, 11.0f)\n            verticalLineTo(9.0f)\n            curveTo(12.0f, 7.89f, 11.11f, 7.0f, 10.0f, 7.0f)\n            horizontalLineTo(6.0f)\n            moveTo(15.8f, 7.0f)\n            lineTo(15.6f, 9.0f)\n            horizontalLineTo(14.0f)\n            verticalLineTo(11.0f)\n            horizontalLineTo(15.4f)\n            lineTo(15.2f, 13.0f)\n            horizontalLineTo(14.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(15.0f)\n            lineTo(14.8f, 17.0f)\n            horizontalLineTo(16.8f)\n            lineTo(17.0f, 15.0f)\n            horizontalLineTo(18.4f)\n            lineTo(18.2f, 17.0f)\n            horizontalLineTo(20.2f)\n            lineTo(20.4f, 15.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(13.0f)\n            horizontalLineTo(20.6f)\n            lineTo(20.8f, 11.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(21.0f)\n            lineTo(21.2f, 7.0f)\n            horizontalLineTo(19.2f)\n            lineTo(19.0f, 9.0f)\n            horizontalLineTo(17.6f)\n            lineTo(17.8f, 7.0f)\n            horizontalLineTo(15.8f)\n            moveTo(17.4f, 11.0f)\n            horizontalLineTo(18.8f)\n            lineTo(18.6f, 13.0f)\n            horizontalLineTo(17.2f)\n            lineTo(17.4f, 11.0f)\n            moveTo(2.0f, 15.0f)\n            verticalLineTo(17.0f)\n            horizontalLineTo(4.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(2.0f)\n            moveTo(8.0f, 15.0f)\n            verticalLineTo(17.0f)\n            horizontalLineTo(10.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(8.0f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/SyncArrowDown.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.SyncArrowDown: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.SyncArrowDown\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(80f, 780f)\n            lineTo(80f, 700f)\n            lineTo(137f, 700f)\n            quadTo(90f, 658f, 65f, 600.5f)\n            quadTo(40f, 543f, 40f, 480f)\n            quadTo(40f, 373f, 107f, 290.5f)\n            quadTo(174f, 208f, 280f, 186f)\n            lineTo(280f, 268f)\n            quadTo(208f, 288f, 164f, 346.5f)\n            quadTo(120f, 405f, 120f, 479f)\n            quadTo(120f, 529f, 141f, 572.5f)\n            quadTo(162f, 616f, 200f, 648f)\n            lineTo(200f, 580f)\n            lineTo(280f, 580f)\n            lineTo(280f, 780f)\n            lineTo(80f, 780f)\n            close()\n            moveTo(400f, 774f)\n            lineTo(400f, 692f)\n            quadTo(472f, 672f, 516f, 613.5f)\n            quadTo(560f, 555f, 560f, 481f)\n            quadTo(560f, 431f, 539f, 387.5f)\n            quadTo(518f, 344f, 480f, 312f)\n            lineTo(480f, 380f)\n            lineTo(400f, 380f)\n            lineTo(400f, 180f)\n            lineTo(600f, 180f)\n            lineTo(600f, 260f)\n            lineTo(543f, 260f)\n            quadTo(590f, 302f, 615f, 359.5f)\n            quadTo(640f, 417f, 640f, 480f)\n            quadTo(640f, 587f, 573f, 669.5f)\n            quadTo(506f, 752f, 400f, 774f)\n            close()\n            moveTo(780f, 800f)\n            lineTo(640f, 660f)\n            lineTo(697f, 604f)\n            lineTo(740f, 647f)\n            lineTo(740f, 160f)\n            lineTo(820f, 160f)\n            lineTo(820f, 648f)\n            lineTo(864f, 604f)\n            lineTo(920f, 660f)\n            lineTo(780f, 800f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TableEye.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.TableEye: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.TableEye\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(120f, 640f)\n            lineTo(328f, 640f)\n            quadTo(318f, 654f, 309f, 668.5f)\n            quadTo(300f, 683f, 292f, 700f)\n            quadTo(282f, 719f, 282.5f, 740f)\n            quadTo(283f, 761f, 292f, 780f)\n            quadTo(300f, 797f, 309f, 811.5f)\n            quadTo(318f, 826f, 328f, 840f)\n            lineTo(200f, 840f)\n            quadTo(167f, 840f, 143.5f, 816.5f)\n            quadTo(120f, 793f, 120f, 760f)\n            lineTo(120f, 640f)\n            close()\n            moveTo(120f, 560f)\n            lineTo(120f, 360f)\n            lineTo(440f, 360f)\n            lineTo(440f, 533f)\n            quadTo(430f, 539f, 420.5f, 545.5f)\n            quadTo(411f, 552f, 402f, 560f)\n            lineTo(120f, 560f)\n            close()\n            moveTo(520f, 360f)\n            lineTo(840f, 360f)\n            lineTo(840f, 533f)\n            quadTo(796f, 507f, 746.5f, 493.5f)\n            quadTo(697f, 480f, 640f, 480f)\n            quadTo(608f, 480f, 578f, 484.5f)\n            quadTo(548f, 489f, 520f, 497f)\n            lineTo(520f, 360f)\n            close()\n            moveTo(120f, 280f)\n            lineTo(120f, 200f)\n            quadTo(120f, 167f, 143.5f, 143.5f)\n            quadTo(167f, 120f, 200f, 120f)\n            lineTo(760f, 120f)\n            quadTo(793f, 120f, 816.5f, 143.5f)\n            quadTo(840f, 167f, 840f, 200f)\n            lineTo(840f, 280f)\n            lineTo(120f, 280f)\n            close()\n            moveTo(640f, 920f)\n            quadTo(561f, 920f, 492.5f, 884f)\n            quadTo(424f, 848f, 382f, 782f)\n            quadTo(376f, 773f, 373f, 762.5f)\n            quadTo(370f, 752f, 370f, 741f)\n            quadTo(370f, 730f, 373f, 719f)\n            quadTo(376f, 708f, 382f, 698f)\n            quadTo(424f, 632f, 492.5f, 596f)\n            quadTo(561f, 560f, 640f, 560f)\n            quadTo(719f, 560f, 787.5f, 596f)\n            quadTo(856f, 632f, 898f, 698f)\n            quadTo(904f, 708f, 907f, 718.5f)\n            quadTo(910f, 729f, 910f, 740f)\n            quadTo(910f, 751f, 907f, 761.5f)\n            quadTo(904f, 772f, 898f, 782f)\n            quadTo(856f, 848f, 787.5f, 884f)\n            quadTo(719f, 920f, 640f, 920f)\n            close()\n            moveTo(640f, 840f)\n            quadTo(682f, 840f, 711f, 811f)\n            quadTo(740f, 782f, 740f, 740f)\n            quadTo(740f, 698f, 711f, 669f)\n            quadTo(682f, 640f, 640f, 640f)\n            quadTo(598f, 640f, 569f, 669f)\n            quadTo(540f, 698f, 540f, 740f)\n            quadTo(540f, 782f, 569f, 811f)\n            quadTo(598f, 840f, 640f, 840f)\n            close()\n            moveTo(640f, 800f)\n            quadTo(615f, 800f, 597.5f, 782.5f)\n            quadTo(580f, 765f, 580f, 740f)\n            quadTo(580f, 715f, 597.5f, 697.5f)\n            quadTo(615f, 680f, 640f, 680f)\n            quadTo(665f, 680f, 682.5f, 697.5f)\n            quadTo(700f, 715f, 700f, 740f)\n            quadTo(700f, 765f, 682.5f, 782.5f)\n            quadTo(665f, 800f, 640f, 800f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TagText.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.TagText: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.TagText\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.4f, 11.6f)\n            lineTo(12.4f, 2.6f)\n            curveToRelative(-0.4f, -0.4f, -0.9f, -0.6f, -1.4f, -0.6f)\n            horizontalLineToRelative(-7f)\n            curveToRelative(-1.1f, 0f, -2f, 0.9f, -2f, 2f)\n            verticalLineToRelative(7f)\n            curveToRelative(0f, 0.5f, 0.2f, 1f, 0.6f, 1.4f)\n            lineToRelative(9f, 9f)\n            curveToRelative(0.4f, 0.4f, 0.9f, 0.6f, 1.4f, 0.6f)\n            reflectiveCurveToRelative(1f, -0.2f, 1.4f, -0.6f)\n            lineToRelative(7f, -7f)\n            curveToRelative(0.4f, -0.4f, 0.6f, -0.9f, 0.6f, -1.4f)\n            reflectiveCurveToRelative(-0.2f, -1f, -0.6f, -1.4f)\n            close()\n            moveTo(13f, 20f)\n            lineTo(4f, 11f)\n            verticalLineToRelative(-7f)\n            horizontalLineToRelative(7f)\n            lineToRelative(9f, 9f)\n            lineToRelative(-7f, 7f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6.5f, 5f)\n            curveToRelative(0.8f, 0f, 1.5f, 0.7f, 1.5f, 1.5f)\n            reflectiveCurveToRelative(-0.7f, 1.5f, -1.5f, 1.5f)\n            reflectiveCurveToRelative(-1.5f, -0.7f, -1.5f, -1.5f)\n            reflectiveCurveToRelative(0.7f, -1.5f, 1.5f, -1.5f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.3f, 10.7f)\n            lineTo(8.3f, 10.7f)\n            arcTo(0.99f, 0.99f, 90f, isMoreThanHalf = false, isPositiveArc = true, 9.7f, 10.7f)\n            lineTo(12.3f, 13.3f)\n            arcTo(0.99f, 0.99f, 90f, isMoreThanHalf = false, isPositiveArc = true, 12.3f, 14.7f)\n            lineTo(12.3f, 14.7f)\n            arcTo(0.99f, 0.99f, 0f, isMoreThanHalf = false, isPositiveArc = true, 10.9f, 14.7f)\n            lineTo(8.3f, 12.1f)\n            arcTo(0.99f, 0.99f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8.3f, 10.7f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15.609f, 13.988f)\n            curveToRelative(0.25f, -0.002f, 0.5f, -0.097f, 0.691f, -0.288f)\n            curveToRelative(0.387f, -0.387f, 0.387f, -1.013f, 0f, -1.4f)\n            lineToRelative(-4.1f, -4.1f)\n            curveToRelative(-0.191f, -0.191f, -0.441f, -0.286f, -0.691f, -0.288f)\n            curveToRelative(-0.25f, 0.002f, -0.5f, 0.097f, -0.691f, 0.288f)\n            curveToRelative(-0.387f, 0.387f, -0.387f, 1.013f, 0f, 1.4f)\n            lineToRelative(4.1f, 4.1f)\n            curveToRelative(0.191f, 0.191f, 0.441f, 0.286f, 0.691f, 0.288f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.TagText: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.TagText\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(13f, 20f)\n            lineToRelative(-9f, -9f)\n            lineToRelative(0f, -7f)\n            lineToRelative(7f, 0f)\n            lineToRelative(9f, 9f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.4f, 11.6f)\n            lineTo(12.4f, 2.6f)\n            curveToRelative(-0.4f, -0.4f, -0.9f, -0.6f, -1.4f, -0.6f)\n            horizontalLineToRelative(-7f)\n            curveToRelative(-1.1f, 0f, -2f, 0.9f, -2f, 2f)\n            verticalLineToRelative(7f)\n            curveToRelative(0f, 0.5f, 0.2f, 1f, 0.6f, 1.4f)\n            lineToRelative(9f, 9f)\n            curveToRelative(0.4f, 0.4f, 0.9f, 0.6f, 1.4f, 0.6f)\n            reflectiveCurveToRelative(1f, -0.2f, 1.4f, -0.6f)\n            lineToRelative(7f, -7f)\n            curveToRelative(0.4f, -0.4f, 0.6f, -0.9f, 0.6f, -1.4f)\n            reflectiveCurveToRelative(-0.2f, -1f, -0.6f, -1.4f)\n            close()\n            moveTo(13f, 20f)\n            lineTo(4f, 11f)\n            verticalLineToRelative(-7f)\n            horizontalLineToRelative(7f)\n            lineToRelative(9f, 9f)\n            lineToRelative(-7f, 7f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(6.5f, 5f)\n            curveToRelative(0.8f, 0f, 1.5f, 0.7f, 1.5f, 1.5f)\n            reflectiveCurveToRelative(-0.7f, 1.5f, -1.5f, 1.5f)\n            reflectiveCurveToRelative(-1.5f, -0.7f, -1.5f, -1.5f)\n            reflectiveCurveToRelative(0.7f, -1.5f, 1.5f, -1.5f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(8.3f, 10.7f)\n            lineTo(8.3f, 10.7f)\n            arcTo(0.99f, 0.99f, 90f, isMoreThanHalf = false, isPositiveArc = true, 9.7f, 10.7f)\n            lineTo(12.3f, 13.3f)\n            arcTo(0.99f, 0.99f, 90f, isMoreThanHalf = false, isPositiveArc = true, 12.3f, 14.7f)\n            lineTo(12.3f, 14.7f)\n            arcTo(0.99f, 0.99f, 0f, isMoreThanHalf = false, isPositiveArc = true, 10.9f, 14.7f)\n            lineTo(8.3f, 12.1f)\n            arcTo(0.99f, 0.99f, 0f, isMoreThanHalf = false, isPositiveArc = true, 8.3f, 10.7f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(15.609f, 13.988f)\n            curveToRelative(0.25f, -0.002f, 0.5f, -0.097f, 0.691f, -0.288f)\n            curveToRelative(0.387f, -0.387f, 0.387f, -1.013f, 0f, -1.4f)\n            lineToRelative(-4.1f, -4.1f)\n            curveToRelative(-0.191f, -0.191f, -0.441f, -0.286f, -0.691f, -0.288f)\n            curveToRelative(-0.25f, 0.002f, -0.5f, 0.097f, -0.691f, 0.288f)\n            curveToRelative(-0.387f, 0.387f, -0.387f, 1.013f, 0f, 1.4f)\n            lineToRelative(4.1f, 4.1f)\n            curveToRelative(0.191f, 0.191f, 0.441f, 0.286f, 0.691f, 0.288f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Telegram.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Telegram: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Telegram\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(11.944f, 0.0f)\n            arcTo(\n                12.0f, 12.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 0.0f,\n                y1 = 12.0f\n            )\n            arcToRelative(\n                12.0f, 12.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                dx1 = 12.0f,\n                dy1 = 12.0f\n            )\n            arcToRelative(\n                12.0f, 12.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                dx1 = 12.0f,\n                dy1 = -12.0f\n            )\n            arcTo(\n                12.0f, 12.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 12.0f,\n                y1 = 0.0f\n            )\n            arcToRelative(\n                12.0f, 12.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                dx1 = -0.056f,\n                dy1 = 0.0f\n            )\n            close()\n            moveTo(16.906f, 7.224f)\n            curveToRelative(0.1f, -0.002f, 0.321f, 0.023f, 0.465f, 0.14f)\n            arcToRelative(\n                0.506f, 0.506f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                dx1 = 0.171f,\n                dy1 = 0.325f\n            )\n            curveToRelative(0.016f, 0.093f, 0.036f, 0.306f, 0.02f, 0.472f)\n            curveToRelative(-0.18f, 1.898f, -0.962f, 6.502f, -1.36f, 8.627f)\n            curveToRelative(-0.168f, 0.9f, -0.499f, 1.201f, -0.82f, 1.23f)\n            curveToRelative(-0.696f, 0.065f, -1.225f, -0.46f, -1.9f, -0.902f)\n            curveToRelative(-1.056f, -0.693f, -1.653f, -1.124f, -2.678f, -1.8f)\n            curveToRelative(-1.185f, -0.78f, -0.417f, -1.21f, 0.258f, -1.91f)\n            curveToRelative(0.177f, -0.184f, 3.247f, -2.977f, 3.307f, -3.23f)\n            curveToRelative(0.007f, -0.032f, 0.014f, -0.15f, -0.056f, -0.212f)\n            reflectiveCurveToRelative(-0.174f, -0.041f, -0.249f, -0.024f)\n            curveToRelative(-0.106f, 0.024f, -1.793f, 1.14f, -5.061f, 3.345f)\n            curveToRelative(-0.48f, 0.33f, -0.913f, 0.49f, -1.302f, 0.48f)\n            curveToRelative(-0.428f, -0.008f, -1.252f, -0.241f, -1.865f, -0.44f)\n            curveToRelative(-0.752f, -0.245f, -1.349f, -0.374f, -1.297f, -0.789f)\n            curveToRelative(0.027f, -0.216f, 0.325f, -0.437f, 0.893f, -0.663f)\n            curveToRelative(3.498f, -1.524f, 5.83f, -2.529f, 6.998f, -3.014f)\n            curveToRelative(3.332f, -1.386f, 4.025f, -1.627f, 4.476f, -1.635f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TelevisionAmbientLight.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.TelevisionAmbientLight: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"TelevisionAmbientLight\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(3f, 11f)\n            horizontalLineTo(0f)\n            verticalLineTo(9f)\n            horizontalLineTo(3f)\n            verticalLineTo(11f)\n            moveTo(3f, 14f)\n            horizontalLineTo(0f)\n            verticalLineTo(16f)\n            horizontalLineTo(3f)\n            verticalLineTo(14f)\n            moveTo(5f, 5.12f)\n            lineTo(2.88f, 3f)\n            lineTo(1.46f, 4.41f)\n            lineTo(3.59f, 6.54f)\n            lineTo(5f, 5.12f)\n            moveTo(10f, 5f)\n            verticalLineTo(2f)\n            horizontalLineTo(8f)\n            verticalLineTo(5f)\n            horizontalLineTo(10f)\n            moveTo(24f, 9f)\n            horizontalLineTo(21f)\n            verticalLineTo(11f)\n            horizontalLineTo(24f)\n            verticalLineTo(9f)\n            moveTo(16f, 5f)\n            verticalLineTo(2f)\n            horizontalLineTo(14f)\n            verticalLineTo(5f)\n            horizontalLineTo(16f)\n            moveTo(20.41f, 6.54f)\n            lineTo(22.54f, 4.42f)\n            lineTo(21.12f, 3f)\n            lineTo(19f, 5.12f)\n            lineTo(20.41f, 6.54f)\n            moveTo(24f, 14f)\n            horizontalLineTo(21f)\n            verticalLineTo(16f)\n            horizontalLineTo(24f)\n            verticalLineTo(14f)\n            moveTo(19f, 9f)\n            verticalLineTo(16f)\n            curveTo(19f, 17.1f, 18.1f, 18f, 17f, 18f)\n            horizontalLineTo(15f)\n            verticalLineTo(20f)\n            horizontalLineTo(9f)\n            verticalLineTo(18f)\n            horizontalLineTo(7f)\n            curveTo(5.9f, 18f, 5f, 17.1f, 5f, 16f)\n            verticalLineTo(9f)\n            curveTo(5f, 7.9f, 5.9f, 7f, 7f, 7f)\n            horizontalLineTo(17f)\n            curveTo(18.1f, 7f, 19f, 7.9f, 19f, 9f)\n            moveTo(17f, 9f)\n            horizontalLineTo(7f)\n            verticalLineTo(16f)\n            horizontalLineTo(17f)\n            verticalLineTo(9f)\n            moveTo(19f, 19.88f)\n            lineTo(21.12f, 22f)\n            lineTo(22.54f, 20.59f)\n            lineTo(20.41f, 18.47f)\n            lineTo(19f, 19.88f)\n            moveTo(3.59f, 18.46f)\n            lineTo(1.47f, 20.59f)\n            lineTo(2.88f, 22f)\n            lineTo(5f, 19.88f)\n            lineTo(3.59f, 18.46f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Tetradic.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Tetradic: ImageVector by lazy {\n    Builder(\n        name = \"Tetradic\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(8.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(6.9f, 16.0f, 8.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(14.9f, 16.0f, 16.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(8.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveTo(9.1f, 8.0f, 8.0f, 8.0f)\n            reflectiveCurveTo(6.0f, 7.1f, 6.0f, 6.0f)\n            reflectiveCurveTo(6.9f, 4.0f, 8.0f, 4.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(16.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(14.9f, 4.0f, 16.0f, 4.0f)\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TextFields.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.TextFields: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.TextFields\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 800f)\n            lineTo(280f, 280f)\n            lineTo(80f, 280f)\n            lineTo(80f, 160f)\n            lineTo(600f, 160f)\n            lineTo(600f, 280f)\n            lineTo(400f, 280f)\n            lineTo(400f, 800f)\n            lineTo(280f, 800f)\n            close()\n            moveTo(640f, 800f)\n            lineTo(640f, 480f)\n            lineTo(520f, 480f)\n            lineTo(520f, 360f)\n            lineTo(880f, 360f)\n            lineTo(880f, 480f)\n            lineTo(760f, 480f)\n            lineTo(760f, 800f)\n            lineTo(640f, 800f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TextSearch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.TextSearch: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.TextSearch\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.31f, 18.9f)\n            lineTo(22.39f, 22f)\n            lineTo(21f, 23.39f)\n            lineTo(17.88f, 20.32f)\n            curveTo(17.19f, 20.75f, 16.37f, 21f, 15.5f, 21f)\n            curveTo(13f, 21f, 11f, 19f, 11f, 16.5f)\n            curveTo(11f, 14f, 13f, 12f, 15.5f, 12f)\n            curveTo(18f, 12f, 20f, 14f, 20f, 16.5f)\n            curveTo(20f, 17.38f, 19.75f, 18.21f, 19.31f, 18.9f)\n            moveTo(15.5f, 19f)\n            curveTo(16.88f, 19f, 18f, 17.88f, 18f, 16.5f)\n            curveTo(18f, 15.12f, 16.88f, 14f, 15.5f, 14f)\n            curveTo(14.12f, 14f, 13f, 15.12f, 13f, 16.5f)\n            curveTo(13f, 17.88f, 14.12f, 19f, 15.5f, 19f)\n            moveTo(21f, 4f)\n            verticalLineTo(6f)\n            horizontalLineTo(3f)\n            verticalLineTo(4f)\n            horizontalLineTo(21f)\n            moveTo(3f, 16f)\n            verticalLineTo(14f)\n            horizontalLineTo(9f)\n            verticalLineTo(16f)\n            horizontalLineTo(3f)\n            moveTo(3f, 11f)\n            verticalLineTo(9f)\n            horizontalLineTo(21f)\n            verticalLineTo(11f)\n            horizontalLineTo(18.97f)\n            curveTo(17.96f, 10.37f, 16.77f, 10f, 15.5f, 10f)\n            curveTo(14.23f, 10f, 13.04f, 10.37f, 12.03f, 11f)\n            horizontalLineTo(3f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TextSticky.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.TextSticky: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.TextSticky\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(200f, 840f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(120f, 760f)\n            verticalLineToRelative(-560f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(200f, 120f)\n            horizontalLineToRelative(560f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(840f, 200f)\n            verticalLineToRelative(407f)\n            quadToRelative(0f, 16f, -6f, 30.5f)\n            reflectiveQuadTo(817f, 663f)\n            lineTo(663f, 817f)\n            quadToRelative(-11f, 11f, -25.5f, 17f)\n            reflectiveQuadToRelative(-30.5f, 6f)\n            lineTo(200f, 840f)\n            close()\n            moveTo(600f, 760f)\n            verticalLineToRelative(-80f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(680f, 600f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(-400f)\n            lineTo(200f, 200f)\n            verticalLineToRelative(560f)\n            horizontalLineToRelative(400f)\n            close()\n            moveTo(440f, 400f)\n            verticalLineToRelative(200f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(480f, 640f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            reflectiveQuadTo(520f, 600f)\n            verticalLineToRelative(-200f)\n            horizontalLineToRelative(80f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            reflectiveQuadTo(640f, 360f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(600f, 320f)\n            lineTo(360f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            reflectiveQuadTo(320f, 360f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(360f, 400f)\n            horizontalLineToRelative(80f)\n            close()\n            moveTo(600f, 760f)\n            close()\n            moveTo(200f, 760f)\n            verticalLineToRelative(-560f)\n            verticalLineToRelative(560f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Theme.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Theme: ImageVector by lazy {\n    Builder(\n        name = \"Theme\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(22.0f, 22.0f)\n            horizontalLineTo(10.0f)\n            verticalLineTo(20.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(22.0f)\n            moveTo(2.0f, 22.0f)\n            verticalLineTo(20.0f)\n            horizontalLineTo(9.0f)\n            verticalLineTo(22.0f)\n            horizontalLineTo(2.0f)\n            moveTo(18.0f, 18.0f)\n            verticalLineTo(10.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(18.0f)\n            horizontalLineTo(18.0f)\n            moveTo(18.0f, 3.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(9.0f)\n            horizontalLineTo(18.0f)\n            verticalLineTo(3.0f)\n            moveTo(2.0f, 18.0f)\n            verticalLineTo(3.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(18.0f)\n            horizontalLineTo(2.0f)\n            moveTo(9.0f, 14.56f)\n            arcTo(\n                3.0f, 3.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 12.0f,\n                y1 = 11.56f\n            )\n            curveTo(12.0f, 9.56f, 9.0f, 6.19f, 9.0f, 6.19f)\n            curveTo(9.0f, 6.19f, 6.0f, 9.56f, 6.0f, 11.56f)\n            arcTo(\n                3.0f, 3.0f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = false,\n                x1 = 9.0f,\n                y1 = 14.56f\n            )\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TimerEdit.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.TimerEdit: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.TimerEdit\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13f, 14f)\n            horizontalLineTo(11f)\n            verticalLineTo(8f)\n            horizontalLineTo(13f)\n            verticalLineTo(14f)\n            moveTo(15f, 1f)\n            horizontalLineTo(9f)\n            verticalLineTo(3f)\n            horizontalLineTo(15f)\n            verticalLineTo(1f)\n            moveTo(5f, 13f)\n            curveTo(5f, 9.13f, 8.13f, 6f, 12f, 6f)\n            curveTo(15.29f, 6f, 18.05f, 8.28f, 18.79f, 11.34f)\n            lineTo(19.39f, 10.74f)\n            curveTo(19.71f, 10.42f, 20.1f, 10.21f, 20.5f, 10.1f)\n            curveTo(20.18f, 9.11f, 19.67f, 8.19f, 19.03f, 7.39f)\n            lineTo(20.45f, 5.97f)\n            curveTo(20f, 5.46f, 19.55f, 5f, 19.04f, 4.56f)\n            lineTo(17.62f, 6f)\n            curveTo(16.07f, 4.74f, 14.12f, 4f, 12f, 4f)\n            curveTo(7.03f, 4f, 3f, 8.03f, 3f, 13f)\n            curveTo(3f, 17.63f, 6.5f, 21.44f, 11f, 21.94f)\n            verticalLineTo(19.92f)\n            curveTo(7.61f, 19.43f, 5f, 16.53f, 5f, 13f)\n            moveTo(13f, 19.96f)\n            verticalLineTo(22f)\n            horizontalLineTo(15.04f)\n            lineTo(21.17f, 15.88f)\n            lineTo(19.13f, 13.83f)\n            lineTo(13f, 19.96f)\n            moveTo(22.85f, 13.47f)\n            lineTo(21.53f, 12.15f)\n            curveTo(21.33f, 11.95f, 21f, 11.95f, 20.81f, 12.15f)\n            lineTo(19.83f, 13.13f)\n            lineTo(21.87f, 15.17f)\n            lineTo(22.85f, 14.19f)\n            curveTo(23.05f, 14f, 23.05f, 13.67f, 22.85f, 13.47f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Titlecase.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Titlecase: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Titlecase\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(344f, 710f)\n            lineTo(344f, 344f)\n            lineTo(224f, 344f)\n            lineTo(224f, 280f)\n            lineTo(532f, 280f)\n            lineTo(532f, 344f)\n            lineTo(412f, 344f)\n            lineTo(412f, 710f)\n            lineTo(344f, 710f)\n            close()\n            moveTo(688f, 720f)\n            quadTo(644f, 720f, 619f, 694.5f)\n            quadTo(594f, 669f, 594f, 624f)\n            lineTo(594f, 462f)\n            lineTo(540f, 462f)\n            lineTo(540f, 404f)\n            lineTo(594f, 404f)\n            lineTo(594f, 317f)\n            lineTo(660f, 317f)\n            lineTo(660f, 404f)\n            lineTo(734f, 404f)\n            lineTo(734f, 462f)\n            lineTo(660f, 462f)\n            lineTo(660f, 610f)\n            quadTo(660f, 633f, 670.5f, 646f)\n            quadTo(681f, 659f, 699f, 659f)\n            quadTo(708f, 659f, 717.5f, 655.5f)\n            quadTo(727f, 652f, 736f, 646f)\n            lineTo(736f, 711f)\n            quadTo(726f, 716f, 714f, 718f)\n            quadTo(702f, 720f, 688f, 720f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Ton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Ton: ImageVector by lazy {\n    Builder(\n        name = \"Ton\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp, viewportWidth\n        = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.0777f, 3.0f)\n            horizontalLineTo(5.9216f)\n            curveTo(3.6865f, 3.0f, 2.2699f, 5.4109f, 3.3943f, 7.3599f)\n            lineToRelative(7.5023f, 13.0033f)\n            curveToRelative(0.4896f, 0.8491f, 1.7165f, 0.8491f, 2.206f, 0.0f)\n            lineToRelative(7.5038f, -13.0033f)\n            curveTo(21.7294f, 5.414f, 20.3128f, 3.0f, 18.0792f, 3.0f)\n            horizontalLineTo(18.0777f)\n            close()\n            moveTo(10.8905f, 16.4637f)\n            lineToRelative(-1.6339f, -3.1621f)\n            lineTo(5.3143f, 6.2508f)\n            curveToRelative(-0.2601f, -0.4513f, 0.0612f, -1.0296f, 0.6058f, -1.0296f)\n            horizontalLineToRelative(4.9689f)\n            verticalLineToRelative(11.244f)\n            lineTo(10.8905f, 16.4637f)\n            close()\n            moveTo(18.682f, 6.2493f)\n            lineToRelative(-3.9409f, 7.0539f)\n            lineToRelative(-1.6339f, 3.1605f)\n            verticalLineTo(5.2197f)\n            horizontalLineToRelative(4.9689f)\n            curveTo(18.6208f, 5.2197f, 18.942f, 5.798f, 18.682f, 6.2493f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Tonality.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Tonality: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Tonality\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(480f, 880f)\n            quadTo(397f, 880f, 324f, 848.5f)\n            quadTo(251f, 817f, 197f, 763f)\n            quadTo(143f, 709f, 111.5f, 636f)\n            quadTo(80f, 563f, 80f, 480f)\n            quadTo(80f, 397f, 111.5f, 324f)\n            quadTo(143f, 251f, 197f, 197f)\n            quadTo(251f, 143f, 324f, 111.5f)\n            quadTo(397f, 80f, 480f, 80f)\n            quadTo(563f, 80f, 636f, 111.5f)\n            quadTo(709f, 143f, 763f, 197f)\n            quadTo(817f, 251f, 848.5f, 324f)\n            quadTo(880f, 397f, 880f, 480f)\n            quadTo(880f, 563f, 848.5f, 636f)\n            quadTo(817f, 709f, 763f, 763f)\n            quadTo(709f, 817f, 636f, 848.5f)\n            quadTo(563f, 880f, 480f, 880f)\n            close()\n            moveTo(520f, 798f)\n            quadTo(550f, 793f, 579f, 784.5f)\n            quadTo(608f, 776f, 634f, 760f)\n            lineTo(520f, 760f)\n            lineTo(520f, 798f)\n            close()\n            moveTo(520f, 680f)\n            lineTo(730f, 680f)\n            quadTo(738f, 671f, 744f, 661f)\n            quadTo(750f, 651f, 756f, 640f)\n            lineTo(520f, 640f)\n            lineTo(520f, 680f)\n            close()\n            moveTo(520f, 560f)\n            lineTo(790f, 560f)\n            quadTo(792f, 550f, 794f, 540f)\n            quadTo(796f, 530f, 798f, 520f)\n            lineTo(520f, 520f)\n            lineTo(520f, 560f)\n            close()\n            moveTo(520f, 440f)\n            lineTo(798f, 440f)\n            quadTo(796f, 430f, 794f, 420f)\n            quadTo(792f, 410f, 790f, 400f)\n            lineTo(520f, 400f)\n            lineTo(520f, 440f)\n            close()\n            moveTo(520f, 320f)\n            lineTo(756f, 320f)\n            quadTo(750f, 309f, 744f, 299f)\n            quadTo(738f, 289f, 730f, 280f)\n            lineTo(520f, 280f)\n            lineTo(520f, 320f)\n            close()\n            moveTo(520f, 200f)\n            lineTo(634f, 200f)\n            quadTo(608f, 184f, 579f, 175.5f)\n            quadTo(550f, 167f, 520f, 162f)\n            lineTo(520f, 200f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Tonality: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Tonality\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(480f, 880f)\n            quadTo(397f, 880f, 324f, 848.5f)\n            quadTo(251f, 817f, 197f, 763f)\n            quadTo(143f, 709f, 111.5f, 636f)\n            quadTo(80f, 563f, 80f, 480f)\n            quadTo(80f, 397f, 111.5f, 324f)\n            quadTo(143f, 251f, 197f, 197f)\n            quadTo(251f, 143f, 324f, 111.5f)\n            quadTo(397f, 80f, 480f, 80f)\n            quadTo(563f, 80f, 636f, 111.5f)\n            quadTo(709f, 143f, 763f, 197f)\n            quadTo(817f, 251f, 848.5f, 324f)\n            quadTo(880f, 397f, 880f, 480f)\n            quadTo(880f, 563f, 848.5f, 636f)\n            quadTo(817f, 709f, 763f, 763f)\n            quadTo(709f, 817f, 636f, 848.5f)\n            quadTo(563f, 880f, 480f, 880f)\n            close()\n            moveTo(440f, 798f)\n            lineTo(440f, 162f)\n            quadTo(319f, 177f, 239.5f, 268f)\n            quadTo(160f, 359f, 160f, 480f)\n            quadTo(160f, 601f, 239.5f, 692f)\n            quadTo(319f, 783f, 440f, 798f)\n            close()\n            moveTo(520f, 798f)\n            quadTo(550f, 793f, 579f, 784.5f)\n            quadTo(608f, 776f, 634f, 760f)\n            lineTo(520f, 760f)\n            lineTo(520f, 798f)\n            close()\n            moveTo(520f, 680f)\n            lineTo(730f, 680f)\n            quadTo(738f, 671f, 744f, 661f)\n            quadTo(750f, 651f, 756f, 640f)\n            lineTo(520f, 640f)\n            lineTo(520f, 680f)\n            close()\n            moveTo(520f, 560f)\n            lineTo(790f, 560f)\n            quadTo(792f, 550f, 794f, 540f)\n            quadTo(796f, 530f, 798f, 520f)\n            lineTo(520f, 520f)\n            lineTo(520f, 560f)\n            close()\n            moveTo(520f, 440f)\n            lineTo(798f, 440f)\n            quadTo(796f, 430f, 794f, 420f)\n            quadTo(792f, 410f, 790f, 400f)\n            lineTo(520f, 400f)\n            lineTo(520f, 440f)\n            close()\n            moveTo(520f, 320f)\n            lineTo(756f, 320f)\n            quadTo(750f, 309f, 744f, 299f)\n            quadTo(738f, 289f, 730f, 280f)\n            lineTo(520f, 280f)\n            lineTo(520f, 320f)\n            close()\n            moveTo(520f, 200f)\n            lineTo(634f, 200f)\n            quadTo(608f, 184f, 579f, 175.5f)\n            quadTo(550f, 167f, 520f, 162f)\n            lineTo(520f, 200f)\n            close()\n            moveTo(440f, 480f)\n            quadTo(440f, 480f, 440f, 480f)\n            quadTo(440f, 480f, 440f, 480f)\n            quadTo(440f, 480f, 440f, 480f)\n            quadTo(440f, 480f, 440f, 480f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Toolbox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Toolbox: ImageVector by lazy {\n    Builder(\n        name = \"Toolbox\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.0f, 16.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(6.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(2.0f)\n            verticalLineTo(20.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(18.0f)\n            verticalLineTo(16.0f)\n            moveTo(20.0f, 8.0f)\n            horizontalLineTo(17.0f)\n            verticalLineTo(6.0f)\n            curveTo(17.0f, 4.9f, 16.1f, 4.0f, 15.0f, 4.0f)\n            horizontalLineTo(9.0f)\n            curveTo(7.9f, 4.0f, 7.0f, 4.9f, 7.0f, 6.0f)\n            verticalLineTo(8.0f)\n            horizontalLineTo(4.0f)\n            curveTo(2.9f, 8.0f, 2.0f, 8.9f, 2.0f, 10.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(6.0f)\n            verticalLineTo(12.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(12.0f)\n            horizontalLineTo(18.0f)\n            verticalLineTo(14.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(10.0f)\n            curveTo(22.0f, 8.9f, 21.1f, 8.0f, 20.0f, 8.0f)\n            moveTo(15.0f, 8.0f)\n            horizontalLineTo(9.0f)\n            verticalLineTo(6.0f)\n            horizontalLineTo(15.0f)\n            verticalLineTo(8.0f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.Toolbox: ImageVector by lazy {\n    Builder(\n        name = \"Toolbox Outline\", defaultWidth = 24.0.dp, defaultHeight\n        = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.0f, 8.0f)\n            horizontalLineTo(17.0f)\n            verticalLineTo(6.0f)\n            curveTo(17.0f, 4.9f, 16.1f, 4.0f, 15.0f, 4.0f)\n            horizontalLineTo(9.0f)\n            curveTo(7.9f, 4.0f, 7.0f, 4.9f, 7.0f, 6.0f)\n            verticalLineTo(8.0f)\n            horizontalLineTo(4.0f)\n            curveTo(2.9f, 8.0f, 2.0f, 8.9f, 2.0f, 10.0f)\n            verticalLineTo(20.0f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(10.0f)\n            curveTo(22.0f, 8.9f, 21.1f, 8.0f, 20.0f, 8.0f)\n            moveTo(9.0f, 6.0f)\n            horizontalLineTo(15.0f)\n            verticalLineTo(8.0f)\n            horizontalLineTo(9.0f)\n            verticalLineTo(6.0f)\n            moveTo(20.0f, 18.0f)\n            horizontalLineTo(4.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(6.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(16.0f)\n            horizontalLineTo(18.0f)\n            verticalLineTo(15.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(18.0f)\n            moveTo(18.0f, 13.0f)\n            verticalLineTo(12.0f)\n            horizontalLineTo(16.0f)\n            verticalLineTo(13.0f)\n            horizontalLineTo(8.0f)\n            verticalLineTo(12.0f)\n            horizontalLineTo(6.0f)\n            verticalLineTo(13.0f)\n            horizontalLineTo(4.0f)\n            verticalLineTo(10.0f)\n            horizontalLineTo(20.0f)\n            verticalLineTo(13.0f)\n            horizontalLineTo(18.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/TopLeft.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.TopLeft: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.TopLeft\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 15f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 11f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 9f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 5f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 7f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 17f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 13f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17f, 3f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13f, 3f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 3f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13f, 11f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9f, 3f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19f, 21f)\n            lineToRelative(2f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(17f, 19f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(13f, 19f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 19f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(9f, 19f)\n            lineToRelative(-2f, 0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(2f, 0f)\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(5f, 13f)\n            lineToRelative(0f, -8f)\n            lineToRelative(8f, 0f)\n            lineToRelative(0f, -2f)\n            lineToRelative(-8f, -0f)\n            lineToRelative(-2f, -0f)\n            lineToRelative(0f, 2f)\n            lineToRelative(0f, 8f)\n            lineToRelative(2f, 0f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Tortoise.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Tortoise: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.Tortoise\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(19.31f, 5.6f)\n            curveTo(18.09f, 5.56f, 16.88f, 6.5f, 16.5f, 8f)\n            curveTo(16f, 10f, 16f, 10f, 15f, 11f)\n            curveTo(13f, 13f, 10f, 14f, 4f, 15f)\n            curveTo(3f, 15.16f, 2.5f, 15.5f, 2f, 16f)\n            curveTo(4f, 16f, 6f, 16f, 4.5f, 17.5f)\n            lineTo(3f, 19f)\n            horizontalLineTo(6f)\n            lineTo(8f, 17f)\n            curveTo(10f, 18f, 11.33f, 18f, 13.33f, 17f)\n            lineTo(14f, 19f)\n            horizontalLineTo(17f)\n            lineTo(16f, 16f)\n            curveTo(16f, 16f, 17f, 12f, 18f, 11f)\n            curveTo(19f, 10f, 19f, 11f, 20f, 11f)\n            curveTo(21f, 11f, 22f, 10f, 22f, 8.5f)\n            curveTo(22f, 8f, 22f, 7f, 20.5f, 6f)\n            curveTo(20.15f, 5.76f, 19.74f, 5.62f, 19.31f, 5.6f)\n            moveTo(9f, 6f)\n            arcTo(6f, 6f, 0f, isMoreThanHalf = false, isPositiveArc = false, 3f, 12f)\n            curveTo(3f, 12.6f, 3.13f, 13.08f, 3.23f, 13.6f)\n            curveTo(9.15f, 12.62f, 12.29f, 11.59f, 13.93f, 9.94f)\n            lineTo(14.43f, 9.44f)\n            curveTo(13.44f, 7.34f, 11.32f, 6f, 9f, 6f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Transparency.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Transparency: ImageVector by lazy {\n    Builder(\n        name = \"Transparency\", defaultWidth = 24.0.dp, defaultHeight =\n            24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(19.0f, 11.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(19.0f, 7.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.0f, 15.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.0f, 19.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(21.0f, 19.0f)\n            horizontalLineToRelative(-2.0f)\n            verticalLineToRelative(2.0f)\n            curveTo(20.1046f, 21.0f, 21.0f, 20.1046f, 21.0f, 19.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(19.0f, 15.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.0f, 3.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.0f, 17.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.0f, 5.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(19.0f, 3.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(2.0f)\n            curveTo(21.0f, 3.8954f, 20.1046f, 3.0f, 19.0f, 3.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.0f, 9.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(13.0f, 17.0f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineToRelative(-2.0f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineTo(9.0f)\n            horizontalLineToRelative(-2.0f)\n            verticalLineTo(7.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineTo(5.0f)\n            horizontalLineToRelative(-2.0f)\n            verticalLineTo(3.0f)\n            horizontalLineTo(5.0f)\n            curveTo(3.8954f, 3.0f, 3.0f, 3.8954f, 3.0f, 5.0f)\n            verticalLineToRelative(14.0f)\n            curveToRelative(0.0f, 1.1046f, 0.8954f, 2.0f, 2.0f, 2.0f)\n            horizontalLineToRelative(8.0f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(-2.0f)\n            horizontalLineTo(13.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.0f, 7.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(15.0f, 11.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(17.0f, 13.0f)\n            horizontalLineToRelative(2.0f)\n            verticalLineToRelative(2.0f)\n            horizontalLineToRelative(-2.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Triadic.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.Triadic: ImageVector by lazy {\n    Builder(\n        name = \"Triadic\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(6.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(4.9f, 16.0f, 6.0f, 16.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.0f, 4.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(10.9f, 4.0f, 12.0f, 4.0f)\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.0f, 16.0f)\n            curveToRelative(1.1f, 0.0f, 2.0f, 0.9f, 2.0f, 2.0f)\n            reflectiveCurveToRelative(-0.9f, 2.0f, -2.0f, 2.0f)\n            reflectiveCurveToRelative(-2.0f, -0.9f, -2.0f, -2.0f)\n            reflectiveCurveTo(16.9f, 16.0f, 18.0f, 16.0f)\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Triangle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Triangle: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"OutlinedTriangle\", defaultWidth = 24.0.dp, defaultHeight\n        = 24.0.dp, viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(22.125f, 19.5f)\n            lineToRelative(-9.25f, -16.0f)\n            curveToRelative(-0.1f, -0.1667f, -0.2292f, -0.2917f, -0.3875f, -0.375f)\n            reflectiveCurveTo(12.1667f, 3.0f, 12.0f, 3.0f)\n            reflectiveCurveToRelative(-0.3292f, 0.0417f, -0.4875f, 0.125f)\n            reflectiveCurveTo(11.225f, 3.3333f, 11.125f, 3.5f)\n            lineToRelative(-9.25f, 16.0f)\n            curveToRelative(-0.1f, 0.1667f, -0.1458f, 0.3375f, -0.1375f, 0.5125f)\n            curveTo(1.7458f, 20.1875f, 1.7917f, 20.35f, 1.875f, 20.5f)\n            reflectiveCurveToRelative(0.2f, 0.2708f, 0.35f, 0.3625f)\n            curveTo(2.375f, 20.9542f, 2.5417f, 21.0f, 2.725f, 21.0f)\n            horizontalLineToRelative(18.55f)\n            curveToRelative(0.1833f, 0.0f, 0.35f, -0.0458f, 0.5f, -0.1375f)\n            curveTo(21.925f, 20.7708f, 22.0417f, 20.65f, 22.125f, 20.5f)\n            reflectiveCurveToRelative(0.1292f, -0.3125f, 0.1375f, -0.4875f)\n            curveTo(22.2708f, 19.8375f, 22.225f, 19.6667f, 22.125f, 19.5f)\n            close()\n            moveTo(4.45f, 19.0f)\n            lineTo(12.0f, 6.0f)\n            lineToRelative(7.55f, 13.0f)\n            horizontalLineTo(4.45f)\n            close()\n        }\n    }\n        .build()\n}\n\nval Icons.Rounded.Triangle: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Triangle\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(2.725f, 21.0f)\n            curveToRelative(-0.1833f, 0.0f, -0.35f, -0.0458f, -0.5f, -0.1375f)\n            curveTo(2.075f, 20.7708f, 1.9583f, 20.65f, 1.875f, 20.5f)\n            reflectiveCurveToRelative(-0.1292f, -0.3125f, -0.1375f, -0.4875f)\n            curveTo(1.7292f, 19.8375f, 1.775f, 19.6667f, 1.875f, 19.5f)\n            lineToRelative(9.25f, -16.0f)\n            curveToRelative(0.1f, -0.1667f, 0.2292f, -0.2917f, 0.3875f, -0.375f)\n            curveToRelative(0.1583f, -0.0833f, 0.3208f, -0.125f, 0.4875f, -0.125f)\n            curveToRelative(0.1667f, 0.0f, 0.3292f, 0.0417f, 0.4875f, 0.125f)\n            curveToRelative(0.1583f, 0.0833f, 0.2875f, 0.2083f, 0.3875f, 0.375f)\n            lineToRelative(9.25f, 16.0f)\n            curveToRelative(0.1f, 0.1667f, 0.1458f, 0.3375f, 0.1375f, 0.5125f)\n            curveTo(22.2542f, 20.1875f, 22.2083f, 20.35f, 22.125f, 20.5f)\n            curveToRelative(-0.0833f, 0.15f, -0.2f, 0.2708f, -0.35f, 0.3625f)\n            curveTo(21.625f, 20.9542f, 21.4583f, 21.0f, 21.275f, 21.0f)\n            horizontalLineTo(2.725f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            stroke = null,\n            strokeLineWidth = 0.0f,\n            strokeLineCap = StrokeCap.Butt,\n            strokeLineJoin = StrokeJoin.Miter,\n            strokeLineMiter = 4.0f,\n            pathFillType = PathFillType.NonZero\n        ) {\n            moveTo(4.45f, 19.0f)\n            lineToRelative(15.1f, 0.0f)\n            lineToRelative(-7.55f, -13.0f)\n            close()\n        }\n    }\n        .build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/USDT.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Filled.USDT: ImageVector by lazy {\n    Builder(\n        name = \"USDT\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(18.7538f, 10.5176f)\n            curveToRelative(0.0f, 0.6251f, -2.2379f, 1.1483f, -5.2381f, 1.2812f)\n            lineToRelative(0.0028f, 7.0E-4f)\n            curveToRelative(-0.0848f, 0.0064f, -0.5233f, 0.0325f, -1.5012f, 0.0325f)\n            curveToRelative(-0.7778f, 0.0f, -1.33f, -0.0233f, -1.5237f, -0.0325f)\n            curveToRelative(-3.0059f, -0.1322f, -5.2495f, -0.6555f, -5.2495f, -1.2819f)\n            reflectiveCurveToRelative(2.2436f, -1.149f, 5.2495f, -1.2834f)\n            verticalLineToRelative(2.0442f)\n            curveToRelative(0.1965f, 0.0142f, 0.7594f, 0.0474f, 1.5372f, 0.0474f)\n            curveToRelative(0.9334f, 0.0f, 1.4008f, -0.0389f, 1.4849f, -0.0466f)\n            lineTo(13.5157f, 9.2356f)\n            curveToRelative(2.9994f, 0.1337f, 5.2381f, 0.657f, 5.2381f, 1.282f)\n            close()\n            moveTo(23.9438f, 11.0642f)\n            lineTo(12.1248f, 22.389f)\n            arcToRelative(\n                0.1803f, 0.1803f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                dx1 = -0.2496f,\n                dy1 = 0.0f\n            )\n            lineTo(0.0562f, 11.0635f)\n            arcToRelative(\n                0.1781f, 0.1781f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                dx1 = -0.0382f,\n                dy1 = -0.2079f\n            )\n            lineToRelative(4.3762f, -9.1921f)\n            arcToRelative(\n                0.1767f, 0.1767f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                dx1 = 0.1626f,\n                dy1 = -0.1026f\n            )\n            horizontalLineToRelative(14.8878f)\n            arcToRelative(\n                0.1768f, 0.1768f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                dx1 = 0.1612f,\n                dy1 = 0.1032f\n            )\n            lineToRelative(4.3762f, 9.1922f)\n            arcToRelative(\n                0.1782f, 0.1782f, 0.0f,\n                isMoreThanHalf = false,\n                isPositiveArc = true,\n                dx1 = -0.0382f,\n                dy1 = 0.2079f\n            )\n            close()\n            moveTo(19.4658f, 10.6604f)\n            curveToRelative(0.0f, -0.8068f, -2.5515f, -1.4799f, -5.9473f, -1.6369f)\n            lineTo(13.5185f, 7.195f)\n            horizontalLineToRelative(4.186f)\n            lineTo(17.7045f, 4.4055f)\n            lineTo(6.3076f, 4.4055f)\n            lineTo(6.3076f, 7.195f)\n            horizontalLineToRelative(4.1852f)\n            verticalLineToRelative(1.8286f)\n            curveToRelative(-3.4018f, 0.1562f, -5.9601f, 0.83f, -5.9601f, 1.6376f)\n            curveToRelative(0.0f, 0.8075f, 2.5583f, 1.4806f, 5.9601f, 1.6376f)\n            verticalLineToRelative(5.8618f)\n            horizontalLineToRelative(3.025f)\n            verticalLineToRelative(-5.8639f)\n            curveToRelative(3.394f, -0.1563f, 5.948f, -0.8295f, 5.948f, -1.6363f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Unarchive.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Unarchive: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Unarchive\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12.713f, 17.388f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            verticalLineToRelative(-3.2f)\n            lineToRelative(0.9f, 0.9f)\n            curveToRelative(0.183f, 0.183f, 0.417f, 0.275f, 0.7f, 0.275f)\n            reflectiveCurveToRelative(0.517f, -0.092f, 0.7f, -0.275f)\n            reflectiveCurveToRelative(0.275f, -0.417f, 0.275f, -0.7f)\n            reflectiveCurveToRelative(-0.092f, -0.517f, -0.275f, -0.7f)\n            lineToRelative(-2.6f, -2.575f)\n            curveToRelative(-0.2f, -0.2f, -0.433f, -0.3f, -0.7f, -0.3f)\n            reflectiveCurveToRelative(-0.5f, 0.1f, -0.7f, 0.3f)\n            lineToRelative(-2.6f, 2.575f)\n            curveToRelative(-0.183f, 0.183f, -0.275f, 0.417f, -0.275f, 0.7f)\n            reflectiveCurveToRelative(0.092f, 0.517f, 0.275f, 0.7f)\n            reflectiveCurveToRelative(0.417f, 0.275f, 0.7f, 0.275f)\n            reflectiveCurveToRelative(0.517f, -0.092f, 0.7f, -0.275f)\n            lineToRelative(0.9f, -0.9f)\n            verticalLineToRelative(3.2f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.712f, -0.287f)\n            close()\n            moveTo(5f, 8f)\n            verticalLineToRelative(11f)\n            horizontalLineToRelative(14f)\n            verticalLineTo(8f)\n            horizontalLineTo(5f)\n            close()\n            moveTo(5f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(6.525f)\n            curveToRelative(0f, -0.233f, 0.038f, -0.458f, 0.112f, -0.675f)\n            reflectiveCurveToRelative(0.188f, -0.417f, 0.338f, -0.6f)\n            lineToRelative(1.25f, -1.525f)\n            curveToRelative(0.183f, -0.233f, 0.412f, -0.412f, 0.688f, -0.538f)\n            reflectiveCurveToRelative(0.563f, -0.188f, 0.863f, -0.188f)\n            horizontalLineToRelative(11.5f)\n            curveToRelative(0.3f, 0f, 0.587f, 0.063f, 0.863f, 0.188f)\n            reflectiveCurveToRelative(0.504f, 0.304f, 0.688f, 0.538f)\n            lineToRelative(1.25f, 1.525f)\n            curveToRelative(0.15f, 0.183f, 0.262f, 0.383f, 0.338f, 0.6f)\n            reflectiveCurveToRelative(0.112f, 0.442f, 0.112f, 0.675f)\n            verticalLineToRelative(12.475f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(5f)\n            close()\n            moveTo(5.4f, 6f)\n            horizontalLineToRelative(13.2f)\n            lineToRelative(-0.85f, -1f)\n            horizontalLineTo(6.25f)\n            lineToRelative(-0.85f, 1f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.Unarchive: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.Unarchive\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12.713f, 17.388f)\n            curveToRelative(0.192f, -0.192f, 0.287f, -0.429f, 0.287f, -0.712f)\n            verticalLineToRelative(-3.2f)\n            lineToRelative(0.9f, 0.9f)\n            curveToRelative(0.183f, 0.183f, 0.417f, 0.275f, 0.7f, 0.275f)\n            reflectiveCurveToRelative(0.517f, -0.092f, 0.7f, -0.275f)\n            reflectiveCurveToRelative(0.275f, -0.417f, 0.275f, -0.7f)\n            reflectiveCurveToRelative(-0.092f, -0.517f, -0.275f, -0.7f)\n            lineToRelative(-2.6f, -2.575f)\n            curveToRelative(-0.2f, -0.2f, -0.433f, -0.3f, -0.7f, -0.3f)\n            reflectiveCurveToRelative(-0.5f, 0.1f, -0.7f, 0.3f)\n            lineToRelative(-2.6f, 2.575f)\n            curveToRelative(-0.183f, 0.183f, -0.275f, 0.417f, -0.275f, 0.7f)\n            reflectiveCurveToRelative(0.092f, 0.517f, 0.275f, 0.7f)\n            reflectiveCurveToRelative(0.417f, 0.275f, 0.7f, 0.275f)\n            reflectiveCurveToRelative(0.517f, -0.092f, 0.7f, -0.275f)\n            lineToRelative(0.9f, -0.9f)\n            verticalLineToRelative(3.2f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            reflectiveCurveToRelative(0.521f, -0.096f, 0.712f, -0.287f)\n            close()\n            moveTo(5f, 8f)\n            verticalLineToRelative(11f)\n            horizontalLineToRelative(14f)\n            verticalLineTo(8f)\n            horizontalLineTo(5f)\n            close()\n            moveTo(5f, 21f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineTo(6.525f)\n            curveToRelative(0f, -0.233f, 0.038f, -0.458f, 0.112f, -0.675f)\n            reflectiveCurveToRelative(0.188f, -0.417f, 0.338f, -0.6f)\n            lineToRelative(1.25f, -1.525f)\n            curveToRelative(0.183f, -0.233f, 0.412f, -0.412f, 0.688f, -0.538f)\n            reflectiveCurveToRelative(0.563f, -0.188f, 0.863f, -0.188f)\n            horizontalLineToRelative(11.5f)\n            curveToRelative(0.3f, 0f, 0.587f, 0.063f, 0.863f, 0.188f)\n            reflectiveCurveToRelative(0.504f, 0.304f, 0.688f, 0.538f)\n            lineToRelative(1.25f, 1.525f)\n            curveToRelative(0.15f, 0.183f, 0.262f, 0.383f, 0.338f, 0.6f)\n            reflectiveCurveToRelative(0.112f, 0.442f, 0.112f, 0.675f)\n            verticalLineToRelative(12.475f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            curveToRelative(-0.392f, 0.392f, -0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineTo(5f)\n            close()\n            moveTo(5.4f, 6f)\n            horizontalLineToRelative(13.2f)\n            lineToRelative(-0.85f, -1f)\n            horizontalLineTo(6.25f)\n            lineToRelative(-0.85f, 1f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 8f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(11f)\n            horizontalLineToRelative(-14f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Ungroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Ungroup: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Ungroup\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(2f, 2f)\n            horizontalLineTo(6f)\n            verticalLineTo(3f)\n            horizontalLineTo(13f)\n            verticalLineTo(2f)\n            horizontalLineTo(17f)\n            verticalLineTo(6f)\n            horizontalLineTo(16f)\n            verticalLineTo(9f)\n            horizontalLineTo(18f)\n            verticalLineTo(8f)\n            horizontalLineTo(22f)\n            verticalLineTo(12f)\n            horizontalLineTo(21f)\n            verticalLineTo(18f)\n            horizontalLineTo(22f)\n            verticalLineTo(22f)\n            horizontalLineTo(18f)\n            verticalLineTo(21f)\n            horizontalLineTo(12f)\n            verticalLineTo(22f)\n            horizontalLineTo(8f)\n            verticalLineTo(18f)\n            horizontalLineTo(9f)\n            verticalLineTo(16f)\n            horizontalLineTo(6f)\n            verticalLineTo(17f)\n            horizontalLineTo(2f)\n            verticalLineTo(13f)\n            horizontalLineTo(3f)\n            verticalLineTo(6f)\n            horizontalLineTo(2f)\n            verticalLineTo(2f)\n            moveTo(18f, 12f)\n            verticalLineTo(11f)\n            horizontalLineTo(16f)\n            verticalLineTo(13f)\n            horizontalLineTo(17f)\n            verticalLineTo(17f)\n            horizontalLineTo(13f)\n            verticalLineTo(16f)\n            horizontalLineTo(11f)\n            verticalLineTo(18f)\n            horizontalLineTo(12f)\n            verticalLineTo(19f)\n            horizontalLineTo(18f)\n            verticalLineTo(18f)\n            horizontalLineTo(19f)\n            verticalLineTo(12f)\n            horizontalLineTo(18f)\n            moveTo(13f, 6f)\n            verticalLineTo(5f)\n            horizontalLineTo(6f)\n            verticalLineTo(6f)\n            horizontalLineTo(5f)\n            verticalLineTo(13f)\n            horizontalLineTo(6f)\n            verticalLineTo(14f)\n            horizontalLineTo(9f)\n            verticalLineTo(12f)\n            horizontalLineTo(8f)\n            verticalLineTo(8f)\n            horizontalLineTo(12f)\n            verticalLineTo(9f)\n            horizontalLineTo(14f)\n            verticalLineTo(6f)\n            horizontalLineTo(13f)\n            moveTo(12f, 12f)\n            horizontalLineTo(11f)\n            verticalLineTo(14f)\n            horizontalLineTo(13f)\n            verticalLineTo(13f)\n            horizontalLineTo(14f)\n            verticalLineTo(11f)\n            horizontalLineTo(12f)\n            verticalLineTo(12f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/VectorPolyline.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.VectorPolyline: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Outlined.VectorPolyline\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(12f, 6f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            close()\n            moveTo(5f, 14f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            close()\n            moveTo(17f, 20f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(2f)\n            close()\n            moveTo(15f, 20f)\n            verticalLineToRelative(-0.5f)\n            lineToRelative(-7f, -3.5f)\n            horizontalLineToRelative(-3f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            curveToRelative(-0.392f, -0.392f, -0.587f, -0.863f, -0.587f, -1.413f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            curveToRelative(0.392f, -0.392f, 0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(2.3f)\n            lineToRelative(2.7f, -3.1f)\n            verticalLineToRelative(-2.9f)\n            curveToRelative(0f, -0.55f, 0.196f, -1.021f, 0.587f, -1.413f)\n            reflectiveCurveToRelative(0.863f, -0.587f, 1.413f, -0.587f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-2.3f)\n            lineToRelative(-2.7f, 3.1f)\n            verticalLineToRelative(3.15f)\n            lineToRelative(6.125f, 3.05f)\n            curveToRelative(0.133f, -0.383f, 0.371f, -0.696f, 0.712f, -0.938f)\n            reflectiveCurveToRelative(0.729f, -0.363f, 1.163f, -0.363f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.55f, 0f, 1.021f, 0.196f, 1.413f, 0.587f)\n            reflectiveCurveToRelative(0.587f, 0.863f, 0.587f, 1.413f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.55f, -0.196f, 1.021f, -0.587f, 1.413f)\n            reflectiveCurveToRelative(-0.863f, 0.587f, -1.413f, 0.587f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, -0.196f, -1.413f, -0.587f)\n            reflectiveCurveToRelative(-0.587f, -0.863f, -0.587f, -1.413f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.VectorPolyline: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.VectorPolyline\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(20.412f, 16.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.433f, 0f, -0.821f, 0.121f, -1.162f, 0.362f)\n            curveToRelative(-0.342f, 0.242f, -0.579f, 0.554f, -0.713f, 0.938f)\n            lineToRelative(-6.125f, -3.05f)\n            verticalLineToRelative(-3.15f)\n            lineToRelative(2.7f, -3.1f)\n            horizontalLineToRelative(2.3f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            reflectiveCurveToRelative(-0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineToRelative(-2f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(2.9f)\n            lineToRelative(-2.7f, 3.1f)\n            horizontalLineToRelative(-2.3f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(2f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(3f)\n            lineToRelative(7f, 3.5f)\n            verticalLineToRelative(0.5f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(2f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineToRelative(-2f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(12f, 4f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-2f)\n            close()\n            moveTo(7f, 14f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            close()\n            moveTo(19f, 20f)\n            horizontalLineToRelative(-2f)\n            verticalLineToRelative(-2f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(12f, 4f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 12f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(17f, 18f)\n            horizontalLineToRelative(2f)\n            verticalLineToRelative(2f)\n            horizontalLineToRelative(-2f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/VolunteerActivism.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.VolunteerActivism: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.VolunteerActivism\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(280f, 801f)\n            lineTo(280f, 440f)\n            lineTo(344f, 440f)\n            quadTo(351f, 440f, 358f, 441.5f)\n            quadTo(365f, 443f, 372f, 445f)\n            lineTo(649f, 548f)\n            quadTo(663f, 553f, 671.5f, 566f)\n            quadTo(680f, 579f, 680f, 593f)\n            quadTo(680f, 614f, 665.5f, 627f)\n            quadTo(651f, 640f, 632f, 640f)\n            lineTo(527f, 640f)\n            quadTo(522f, 640f, 519.5f, 639.5f)\n            quadTo(517f, 639f, 513f, 637f)\n            lineTo(449f, 612f)\n            lineTo(436f, 651f)\n            lineTo(513f, 678f)\n            quadTo(515f, 679f, 519f, 679.5f)\n            quadTo(523f, 680f, 526f, 680f)\n            lineTo(800f, 680f)\n            quadTo(832f, 680f, 856f, 703f)\n            quadTo(880f, 726f, 880f, 760f)\n            lineTo(561f, 880f)\n            lineTo(280f, 801f)\n            close()\n            moveTo(40f, 880f)\n            lineTo(40f, 440f)\n            lineTo(200f, 440f)\n            lineTo(200f, 880f)\n            lineTo(40f, 880f)\n            close()\n            moveTo(640f, 520f)\n            lineTo(474f, 358f)\n            quadTo(443f, 328f, 421.5f, 291.5f)\n            quadTo(400f, 255f, 400f, 212f)\n            quadTo(400f, 157f, 438.5f, 118.5f)\n            quadTo(477f, 80f, 532f, 80f)\n            quadTo(564f, 80f, 592f, 93.5f)\n            quadTo(620f, 107f, 640f, 130f)\n            quadTo(660f, 107f, 688f, 93.5f)\n            quadTo(716f, 80f, 748f, 80f)\n            quadTo(803f, 80f, 841.5f, 118.5f)\n            quadTo(880f, 157f, 880f, 212f)\n            quadTo(880f, 255f, 859f, 291.5f)\n            quadTo(838f, 328f, 807f, 358f)\n            lineTo(640f, 520f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Outlined.VolunteerActivism: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.VolunteerActivism\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(640f, 520f)\n            lineTo(474f, 358f)\n            quadTo(443f, 328f, 421.5f, 291.5f)\n            quadTo(400f, 255f, 400f, 212f)\n            quadTo(400f, 157f, 438.5f, 118.5f)\n            quadTo(477f, 80f, 532f, 80f)\n            quadTo(564f, 80f, 592f, 93.5f)\n            quadTo(620f, 107f, 640f, 130f)\n            quadTo(660f, 107f, 688f, 93.5f)\n            quadTo(716f, 80f, 748f, 80f)\n            quadTo(803f, 80f, 841.5f, 118.5f)\n            quadTo(880f, 157f, 880f, 212f)\n            quadTo(880f, 255f, 859f, 291.5f)\n            quadTo(838f, 328f, 807f, 358f)\n            lineTo(640f, 520f)\n            close()\n            moveTo(640f, 408f)\n            lineTo(749f, 301f)\n            quadTo(768f, 282f, 784f, 260.5f)\n            quadTo(800f, 239f, 800f, 212f)\n            quadTo(800f, 190f, 785f, 175f)\n            quadTo(770f, 160f, 748f, 160f)\n            quadTo(734f, 160f, 721.5f, 165.5f)\n            quadTo(709f, 171f, 700f, 182f)\n            lineTo(640f, 254f)\n            lineTo(580f, 182f)\n            quadTo(571f, 171f, 558.5f, 165.5f)\n            quadTo(546f, 160f, 532f, 160f)\n            quadTo(510f, 160f, 495f, 175f)\n            quadTo(480f, 190f, 480f, 212f)\n            quadTo(480f, 239f, 496f, 260.5f)\n            quadTo(512f, 282f, 531f, 301f)\n            lineTo(640f, 408f)\n            close()\n            moveTo(280f, 740f)\n            lineTo(558f, 816f)\n            lineTo(796f, 742f)\n            quadTo(791f, 733f, 781.5f, 726.5f)\n            quadTo(772f, 720f, 760f, 720f)\n            lineTo(558f, 720f)\n            quadTo(531f, 720f, 515f, 718f)\n            quadTo(499f, 716f, 482f, 710f)\n            lineTo(389f, 679f)\n            lineTo(411f, 601f)\n            lineTo(492f, 628f)\n            quadTo(509f, 633f, 532f, 636f)\n            quadTo(555f, 639f, 600f, 640f)\n            lineTo(600f, 640f)\n            quadTo(600f, 640f, 600f, 640f)\n            quadTo(600f, 640f, 600f, 640f)\n            quadTo(600f, 629f, 593.5f, 619f)\n            quadTo(587f, 609f, 578f, 606f)\n            lineTo(344f, 520f)\n            quadTo(344f, 520f, 344f, 520f)\n            quadTo(344f, 520f, 344f, 520f)\n            lineTo(280f, 520f)\n            lineTo(280f, 740f)\n            close()\n            moveTo(40f, 880f)\n            lineTo(40f, 440f)\n            lineTo(344f, 440f)\n            quadTo(351f, 440f, 358f, 441.5f)\n            quadTo(365f, 443f, 371f, 445f)\n            lineTo(606f, 532f)\n            quadTo(639f, 544f, 659.5f, 574f)\n            quadTo(680f, 604f, 680f, 640f)\n            lineTo(760f, 640f)\n            quadTo(810f, 640f, 845f, 673f)\n            quadTo(880f, 706f, 880f, 760f)\n            lineTo(880f, 800f)\n            lineTo(560f, 900f)\n            lineTo(280f, 822f)\n            lineTo(280f, 822f)\n            lineTo(280f, 880f)\n            lineTo(40f, 880f)\n            close()\n            moveTo(120f, 800f)\n            lineTo(200f, 800f)\n            lineTo(200f, 520f)\n            lineTo(120f, 520f)\n            lineTo(120f, 800f)\n            close()\n            moveTo(640f, 254f)\n            lineTo(640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            lineTo(640f, 254f)\n            lineTo(640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            quadTo(640f, 254f, 640f, 254f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/WallpaperAlt.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.WallpaperAlt: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.Wallpaper\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(280f, 920f)\n            quadToRelative(-33f, 0f, -56.5f, -23.5f)\n            reflectiveQuadTo(200f, 840f)\n            verticalLineToRelative(-720f)\n            quadToRelative(0f, -33f, 23.5f, -56.5f)\n            reflectiveQuadTo(280f, 40f)\n            horizontalLineToRelative(400f)\n            quadToRelative(33f, 0f, 56.5f, 23.5f)\n            reflectiveQuadTo(760f, 120f)\n            verticalLineToRelative(124f)\n            quadToRelative(18f, 7f, 29f, 22f)\n            reflectiveQuadToRelative(11f, 34f)\n            verticalLineToRelative(80f)\n            quadToRelative(0f, 19f, -11f, 34f)\n            reflectiveQuadToRelative(-29f, 22f)\n            verticalLineToRelative(404f)\n            quadToRelative(0f, 33f, -23.5f, 56.5f)\n            reflectiveQuadTo(680f, 920f)\n            lineTo(280f, 920f)\n            close()\n            moveTo(280f, 840f)\n            horizontalLineToRelative(400f)\n            verticalLineToRelative(-720f)\n            lineTo(280f, 120f)\n            verticalLineToRelative(720f)\n            close()\n            moveTo(320f, 600f)\n            horizontalLineToRelative(320f)\n            lineTo(535f, 460f)\n            lineToRelative(-75f, 100f)\n            lineToRelative(-55f, -73f)\n            lineToRelative(-85f, 113f)\n            close()\n            moveTo(600f, 400f)\n            quadToRelative(17f, 0f, 28.5f, -11.5f)\n            reflectiveQuadTo(640f, 360f)\n            quadToRelative(0f, -17f, -11.5f, -28.5f)\n            reflectiveQuadTo(600f, 320f)\n            quadToRelative(-17f, 0f, -28.5f, 11.5f)\n            reflectiveQuadTo(560f, 360f)\n            quadToRelative(0f, 17f, 11.5f, 28.5f)\n            reflectiveQuadTo(600f, 400f)\n            close()\n            moveTo(280f, 840f)\n            verticalLineToRelative(-720f)\n            verticalLineToRelative(720f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/WandShine.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.WandShine: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.WandShine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(331f, 309f)\n            lineTo(211f, 189f)\n            lineToRelative(57f, -57f)\n            lineToRelative(120f, 120f)\n            lineToRelative(-57f, 57f)\n            close()\n            moveTo(480f, 214f)\n            verticalLineToRelative(-170f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(170f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(771f, 749f)\n            lineTo(651f, 629f)\n            lineToRelative(57f, -57f)\n            lineToRelative(120f, 120f)\n            lineToRelative(-57f, 57f)\n            close()\n            moveTo(708f, 309f)\n            lineTo(651f, 252f)\n            lineTo(771f, 132f)\n            lineTo(828f, 189f)\n            lineTo(708f, 309f)\n            close()\n            moveTo(746f, 480f)\n            verticalLineToRelative(-80f)\n            horizontalLineToRelative(170f)\n            verticalLineToRelative(80f)\n            lineTo(746f, 480f)\n            close()\n            moveTo(205f, 868f)\n            lineTo(92f, 755f)\n            quadToRelative(-12f, -12f, -12f, -28f)\n            reflectiveQuadToRelative(12f, -28f)\n            lineToRelative(363f, -364f)\n            quadToRelative(35f, -35f, 85f, -35f)\n            reflectiveQuadToRelative(85f, 35f)\n            quadToRelative(35f, 35f, 35f, 85f)\n            reflectiveQuadToRelative(-35f, 85f)\n            lineTo(261f, 868f)\n            quadToRelative(-12f, 12f, -28f, 12f)\n            reflectiveQuadToRelative(-28f, -12f)\n            close()\n            moveTo(484f, 533f)\n            lineTo(469.5f, 519f)\n            lineTo(455f, 505f)\n            lineTo(441f, 491f)\n            lineTo(427f, 477f)\n            lineTo(455f, 505f)\n            lineTo(484f, 533f)\n            close()\n            moveTo(233f, 784f)\n            lineToRelative(251f, -251f)\n            lineToRelative(-57f, -56f)\n            lineToRelative(-250f, 250f)\n            lineToRelative(56f, 57f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.WandShine: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.WandShine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(331f, 309f)\n            lineTo(211f, 189f)\n            lineToRelative(57f, -57f)\n            lineToRelative(120f, 120f)\n            lineToRelative(-57f, 57f)\n            close()\n            moveTo(480f, 214f)\n            verticalLineToRelative(-170f)\n            horizontalLineToRelative(80f)\n            verticalLineToRelative(170f)\n            horizontalLineToRelative(-80f)\n            close()\n            moveTo(771f, 749f)\n            lineTo(651f, 629f)\n            lineToRelative(57f, -57f)\n            lineToRelative(120f, 120f)\n            lineToRelative(-57f, 57f)\n            close()\n            moveTo(708f, 309f)\n            lineTo(651f, 252f)\n            lineTo(771f, 132f)\n            lineTo(828f, 189f)\n            lineTo(708f, 309f)\n            close()\n            moveTo(746f, 480f)\n            verticalLineToRelative(-80f)\n            horizontalLineToRelative(170f)\n            verticalLineToRelative(80f)\n            lineTo(746f, 480f)\n            close()\n            moveTo(205f, 868f)\n            lineTo(92f, 755f)\n            quadToRelative(-12f, -12f, -12f, -28f)\n            reflectiveQuadToRelative(12f, -28f)\n            lineToRelative(363f, -364f)\n            quadToRelative(35f, -35f, 85f, -35f)\n            reflectiveQuadToRelative(85f, 35f)\n            quadToRelative(35f, 35f, 35f, 85f)\n            reflectiveQuadToRelative(-35f, 85f)\n            lineTo(261f, 868f)\n            quadToRelative(-12f, 12f, -28f, 12f)\n            reflectiveQuadToRelative(-28f, -12f)\n            close()\n            moveTo(484f, 533f)\n            lineTo(568f, 448f)\n            quadToRelative(12f, -12f, 12f, -28f)\n            reflectiveQuadToRelative(-12f, -28f)\n            quadToRelative(-12f, -12f, -28f, -12f)\n            reflectiveQuadToRelative(-28f, 12f)\n            lineToRelative(-85f, 85f)\n            lineToRelative(57f, 56f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/WandStars.kt",
    "content": "package com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.WandStars: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Outlined.WandStars\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(646f, 522f)\n            lineTo(560f, 660f)\n            quadTo(549f, 677f, 529.5f, 674f)\n            quadTo(510f, 671f, 505f, 651f)\n            lineTo(477f, 539f)\n            lineTo(204f, 812f)\n            quadTo(193f, 823f, 176.5f, 823.5f)\n            quadTo(160f, 824f, 148f, 812f)\n            quadTo(137f, 801f, 137f, 784f)\n            quadTo(137f, 767f, 148f, 756f)\n            lineTo(421f, 482f)\n            lineTo(309f, 454f)\n            quadTo(289f, 449f, 286f, 429.5f)\n            quadTo(283f, 410f, 300f, 399f)\n            lineTo(438f, 314f)\n            lineTo(426f, 151f)\n            quadTo(424f, 131f, 442f, 122f)\n            quadTo(460f, 113f, 475f, 126f)\n            lineTo(600f, 231f)\n            lineTo(751f, 170f)\n            quadTo(770f, 162f, 784f, 176f)\n            quadTo(798f, 190f, 790f, 209f)\n            lineTo(729f, 360f)\n            lineTo(834f, 484f)\n            quadTo(847f, 499f, 838f, 517f)\n            quadTo(829f, 535f, 809f, 533f)\n            lineTo(646f, 522f)\n            close()\n            moveTo(134f, 254f)\n            quadTo(128f, 248f, 128f, 240f)\n            quadTo(128f, 232f, 134f, 226f)\n            lineTo(186f, 174f)\n            quadTo(192f, 168f, 200f, 168f)\n            quadTo(208f, 168f, 214f, 174f)\n            lineTo(266f, 226f)\n            quadTo(272f, 232f, 272f, 240f)\n            quadTo(272f, 248f, 266f, 254f)\n            lineTo(214f, 306f)\n            quadTo(208f, 312f, 200f, 312f)\n            quadTo(192f, 312f, 186f, 306f)\n            lineTo(134f, 254f)\n            close()\n            moveTo(555f, 517f)\n            lineTo(603f, 438f)\n            lineTo(696f, 445f)\n            lineTo(636f, 374f)\n            lineTo(671f, 288f)\n            lineTo(585f, 323f)\n            lineTo(514f, 264f)\n            lineTo(521f, 356f)\n            lineTo(442f, 405f)\n            lineTo(532f, 427f)\n            lineTo(555f, 517f)\n            close()\n            moveTo(706f, 826f)\n            lineTo(654f, 774f)\n            quadTo(648f, 768f, 648f, 760f)\n            quadTo(648f, 752f, 654f, 746f)\n            lineTo(706f, 694f)\n            quadTo(712f, 688f, 720f, 688f)\n            quadTo(728f, 688f, 734f, 694f)\n            lineTo(786f, 746f)\n            quadTo(792f, 752f, 792f, 760f)\n            quadTo(792f, 768f, 786f, 774f)\n            lineTo(734f, 826f)\n            quadTo(728f, 832f, 720f, 832f)\n            quadTo(712f, 832f, 706f, 826f)\n            close()\n            moveTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            lineTo(569f, 390f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.Rounded.WandStars: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Rounded.WandStars\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 960f,\n        viewportHeight = 960f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(646f, 522f)\n            lineTo(560f, 660f)\n            quadTo(549f, 677f, 529.5f, 674f)\n            quadTo(510f, 671f, 505f, 651f)\n            lineTo(477f, 539f)\n            lineTo(204f, 812f)\n            quadTo(193f, 823f, 176.5f, 823.5f)\n            quadTo(160f, 824f, 148f, 812f)\n            quadTo(137f, 801f, 137f, 784f)\n            quadTo(137f, 767f, 148f, 756f)\n            lineTo(421f, 482f)\n            lineTo(309f, 454f)\n            quadTo(289f, 449f, 286f, 429.5f)\n            quadTo(283f, 410f, 300f, 399f)\n            lineTo(438f, 314f)\n            lineTo(426f, 151f)\n            quadTo(424f, 131f, 442f, 122f)\n            quadTo(460f, 113f, 475f, 126f)\n            lineTo(600f, 231f)\n            lineTo(751f, 170f)\n            quadTo(770f, 162f, 784f, 176f)\n            quadTo(798f, 190f, 790f, 209f)\n            lineTo(729f, 360f)\n            lineTo(834f, 484f)\n            quadTo(847f, 499f, 838f, 517f)\n            quadTo(829f, 535f, 809f, 533f)\n            lineTo(646f, 522f)\n            close()\n            moveTo(134f, 254f)\n            quadTo(128f, 248f, 128f, 240f)\n            quadTo(128f, 232f, 134f, 226f)\n            lineTo(186f, 174f)\n            quadTo(192f, 168f, 200f, 168f)\n            quadTo(208f, 168f, 214f, 174f)\n            lineTo(266f, 226f)\n            quadTo(272f, 232f, 272f, 240f)\n            quadTo(272f, 248f, 266f, 254f)\n            lineTo(214f, 306f)\n            quadTo(208f, 312f, 200f, 312f)\n            quadTo(192f, 312f, 186f, 306f)\n            lineTo(134f, 254f)\n            close()\n            moveTo(706f, 826f)\n            lineTo(654f, 774f)\n            quadTo(648f, 768f, 648f, 760f)\n            quadTo(648f, 752f, 654f, 746f)\n            lineTo(706f, 694f)\n            quadTo(712f, 688f, 720f, 688f)\n            quadTo(728f, 688f, 734f, 694f)\n            lineTo(786f, 746f)\n            quadTo(792f, 752f, 792f, 760f)\n            quadTo(792f, 768f, 786f, 774f)\n            lineTo(734f, 826f)\n            quadTo(728f, 832f, 720f, 832f)\n            quadTo(712f, 832f, 706f, 826f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Watermark.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.Watermark: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"Watermark\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 17f)\n            horizontalLineToRelative(7f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-7f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 4.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(20f, 17.398f)\n            curveToRelative(0f, 0.333f, -0.27f, 0.602f, -0.602f, 0.602f)\n            horizontalLineTo(4.602f)\n            curveToRelative(-0.333f, 0f, -0.602f, -0.27f, -0.602f, -0.602f)\n            verticalLineTo(6.602f)\n            curveToRelative(0f, -0.333f, 0.27f, -0.602f, 0.602f, -0.602f)\n            horizontalLineToRelative(14.795f)\n            curveToRelative(0.333f, 0f, 0.602f, 0.27f, 0.602f, 0.602f)\n            verticalLineToRelative(10.795f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(4f, 18f)\n            verticalLineTo(6f)\n            verticalLineToRelative(12f)\n            close()\n        }\n    }.build()\n}\n\n\nval Icons.TwoTone.Watermark: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoToneWatermark\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(21.412f, 4.588f)\n            curveToRelative(-0.392f, -0.392f, -0.862f, -0.588f, -1.412f, -0.588f)\n            horizontalLineTo(4f)\n            curveToRelative(-0.55f, 0f, -1.021f, 0.196f, -1.412f, 0.588f)\n            reflectiveCurveToRelative(-0.588f, 0.862f, -0.588f, 1.412f)\n            verticalLineToRelative(12f)\n            curveToRelative(0f, 0.55f, 0.196f, 1.021f, 0.588f, 1.412f)\n            reflectiveCurveToRelative(0.862f, 0.588f, 1.412f, 0.588f)\n            horizontalLineToRelative(16f)\n            curveToRelative(0.55f, 0f, 1.021f, -0.196f, 1.412f, -0.588f)\n            reflectiveCurveToRelative(0.588f, -0.862f, 0.588f, -1.412f)\n            verticalLineTo(6f)\n            curveToRelative(0f, -0.55f, -0.196f, -1.021f, -0.588f, -1.412f)\n            close()\n            moveTo(20f, 17.398f)\n            curveToRelative(0f, 0.333f, -0.27f, 0.602f, -0.602f, 0.602f)\n            horizontalLineTo(4.602f)\n            curveToRelative(-0.333f, 0f, -0.602f, -0.27f, -0.602f, -0.602f)\n            verticalLineTo(6.602f)\n            curveToRelative(0f, -0.333f, 0.27f, -0.602f, 0.602f, -0.602f)\n            horizontalLineToRelative(14.795f)\n            curveToRelative(0.333f, 0f, 0.602f, 0.27f, 0.602f, 0.602f)\n            verticalLineToRelative(10.795f)\n            close()\n        }\n        path(fill = SolidColor(Color.Black)) {\n            moveTo(11f, 17f)\n            horizontalLineToRelative(7f)\n            curveToRelative(0.283f, 0f, 0.521f, -0.096f, 0.712f, -0.287f)\n            reflectiveCurveToRelative(0.287f, -0.429f, 0.287f, -0.712f)\n            verticalLineToRelative(-4f)\n            curveToRelative(0f, -0.283f, -0.096f, -0.521f, -0.287f, -0.712f)\n            curveToRelative(-0.192f, -0.192f, -0.429f, -0.287f, -0.712f, -0.287f)\n            horizontalLineToRelative(-7f)\n            curveToRelative(-0.283f, 0f, -0.521f, 0.096f, -0.712f, 0.287f)\n            curveToRelative(-0.192f, 0.192f, -0.287f, 0.429f, -0.287f, 0.712f)\n            verticalLineToRelative(4f)\n            curveToRelative(0f, 0.283f, 0.096f, 0.521f, 0.287f, 0.712f)\n            reflectiveCurveToRelative(0.429f, 0.287f, 0.712f, 0.287f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color.Black),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(4.602f, 6f)\n            lineTo(19.398f, 6f)\n            arcTo(0.602f, 0.602f, 0f, isMoreThanHalf = false, isPositiveArc = true, 20f, 6.602f)\n            lineTo(20f, 17.398f)\n            arcTo(0.602f, 0.602f, 0f, isMoreThanHalf = false, isPositiveArc = true, 19.398f, 18f)\n            lineTo(4.602f, 18f)\n            arcTo(0.602f, 0.602f, 0f, isMoreThanHalf = false, isPositiveArc = true, 4f, 17.398f)\n            lineTo(4f, 6.602f)\n            arcTo(0.602f, 0.602f, 0f, isMoreThanHalf = false, isPositiveArc = true, 4.602f, 6f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Webp.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Webp: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"Webp\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(4.115f, 14.781f)\n            curveTo(3.499f, 14.781f, 3f, 14.282f, 3f, 13.666f)\n            verticalLineTo(9.207f)\n            horizontalLineToRelative(1.115f)\n            verticalLineToRelative(4.459f)\n            horizontalLineToRelative(1.115f)\n            verticalLineTo(9.764f)\n            horizontalLineToRelative(1.115f)\n            verticalLineToRelative(3.902f)\n            horizontalLineToRelative(1.115f)\n            verticalLineTo(9.207f)\n            horizontalLineToRelative(1.115f)\n            verticalLineToRelative(4.459f)\n            curveToRelative(0f, 0.616f, -0.499f, 1.115f, -1.115f, 1.115f)\n            horizontalLineTo(4.115f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(9.372f, 9.202f)\n            verticalLineToRelative(5.574f)\n            horizontalLineToRelative(3.344f)\n            verticalLineToRelative(-1.115f)\n            horizontalLineToRelative(-2.23f)\n            verticalLineToRelative(-1.115f)\n            horizontalLineToRelative(2.23f)\n            verticalLineToRelative(-1.115f)\n            horizontalLineToRelative(-2.23f)\n            verticalLineToRelative(-1.115f)\n            horizontalLineToRelative(2.23f)\n            verticalLineTo(9.202f)\n            horizontalLineTo(9.372f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(16.858f, 11.158f)\n            verticalLineToRelative(-0.836f)\n            curveToRelative(0f, -0.616f, -0.499f, -1.115f, -1.115f, -1.115f)\n            horizontalLineToRelative(-2.23f)\n            verticalLineToRelative(5.574f)\n            horizontalLineToRelative(2.23f)\n            curveToRelative(0.616f, 0f, 1.115f, -0.499f, 1.115f, -1.115f)\n            verticalLineToRelative(-0.836f)\n            curveToRelative(0f, -0.446f, -0.39f, -0.836f, -0.836f, -0.836f)\n            curveTo(16.468f, 11.994f, 16.858f, 11.604f, 16.858f, 11.158f)\n            moveTo(15.743f, 13.666f)\n            horizontalLineTo(14.628f)\n            verticalLineToRelative(-1.115f)\n            horizontalLineToRelative(1.115f)\n            verticalLineTo(13.666f)\n            moveTo(15.743f, 11.437f)\n            horizontalLineTo(14.628f)\n            verticalLineToRelative(-1.115f)\n            horizontalLineToRelative(1.115f)\n            verticalLineTo(11.437f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(17.656f, 9.207f)\n            verticalLineToRelative(5.574f)\n            horizontalLineToRelative(1.115f)\n            verticalLineToRelative(-2.23f)\n            horizontalLineToRelative(1.115f)\n            curveTo(20.501f, 12.552f, 21f, 12.052f, 21f, 11.437f)\n            verticalLineToRelative(-1.115f)\n            curveToRelative(0f, -0.616f, -0.499f, -1.115f, -1.115f, -1.115f)\n            horizontalLineTo(17.656f)\n            moveTo(18.77f, 10.322f)\n            horizontalLineToRelative(1.115f)\n            verticalLineToRelative(1.115f)\n            horizontalLineToRelative(-1.115f)\n            verticalLineTo(10.322f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/WebpBox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Outlined.WebpBox: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"WebpBox\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(6.757f, 13.855f)\n            curveToRelative(-0.409f, 0f, -0.741f, -0.332f, -0.741f, -0.741f)\n            verticalLineToRelative(-2.965f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(2.965f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(-2.594f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(2.594f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(-2.965f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(2.965f)\n            curveToRelative(0f, 0.409f, -0.332f, 0.741f, -0.741f, 0.741f)\n            horizontalLineTo(6.757f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(10.252f, 10.145f)\n            verticalLineToRelative(3.706f)\n            horizontalLineToRelative(2.224f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(-1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(-1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineTo(10.252f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15.23f, 11.446f)\n            verticalLineToRelative(-0.556f)\n            curveToRelative(0f, -0.409f, -0.332f, -0.741f, -0.741f, -0.741f)\n            horizontalLineToRelative(-1.483f)\n            verticalLineToRelative(3.706f)\n            horizontalLineToRelative(1.483f)\n            curveToRelative(0.409f, 0f, 0.741f, -0.332f, 0.741f, -0.741f)\n            verticalLineToRelative(-0.556f)\n            curveToRelative(0f, -0.297f, -0.259f, -0.556f, -0.556f, -0.556f)\n            curveTo(14.971f, 12.002f, 15.23f, 11.742f, 15.23f, 11.446f)\n            moveTo(14.489f, 13.114f)\n            horizontalLineToRelative(-0.741f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(0.741f)\n            verticalLineTo(13.114f)\n            moveTo(14.489f, 11.631f)\n            horizontalLineToRelative(-0.741f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(0.741f)\n            verticalLineTo(11.631f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15.761f, 10.148f)\n            verticalLineToRelative(3.706f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(-1.483f)\n            horizontalLineToRelative(0.741f)\n            curveToRelative(0.409f, 0f, 0.741f, -0.332f, 0.741f, -0.741f)\n            verticalLineToRelative(-0.741f)\n            curveToRelative(0f, -0.409f, -0.332f, -0.741f, -0.741f, -0.741f)\n            horizontalLineTo(15.761f)\n            moveTo(16.502f, 10.89f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(0.741f)\n            horizontalLineToRelative(-0.741f)\n            verticalLineTo(10.89f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19f, 3f)\n            horizontalLineTo(5f)\n            curveTo(3.89f, 3f, 3f, 3.89f, 3f, 5f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 1.105f, 0.895f, 2f, 2f, 2f)\n            horizontalLineToRelative(14f)\n            curveToRelative(1.105f, 0f, 2f, -0.895f, 2f, -2f)\n            verticalLineTo(5f)\n            curveTo(21f, 3.89f, 20.1f, 3f, 19f, 3f)\n            moveTo(19f, 5f)\n            verticalLineToRelative(14f)\n            horizontalLineTo(5f)\n            verticalLineTo(5f)\n            horizontalLineTo(19f)\n            close()\n        }\n    }.build()\n}\n\nval Icons.TwoTone.WebpBox: ImageVector by lazy(LazyThreadSafetyMode.NONE) {\n    ImageVector.Builder(\n        name = \"TwoTone.WebpBox\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)),\n            fillAlpha = 0.3f,\n            strokeAlpha = 0.3f\n        ) {\n            moveTo(5f, 5f)\n            horizontalLineToRelative(14f)\n            verticalLineToRelative(14f)\n            horizontalLineToRelative(-14f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(6.757f, 13.855f)\n            curveToRelative(-0.409f, 0f, -0.741f, -0.332f, -0.741f, -0.741f)\n            verticalLineToRelative(-2.965f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(2.965f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(-2.594f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(2.594f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(-2.965f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(2.965f)\n            curveToRelative(0f, 0.409f, -0.332f, 0.741f, -0.741f, 0.741f)\n            horizontalLineToRelative(-2.223f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(10.252f, 10.145f)\n            verticalLineToRelative(3.706f)\n            horizontalLineToRelative(2.224f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(-1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(-1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(1.483f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(-2.224f)\n            verticalLineToRelative(-0.001f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15.23f, 11.446f)\n            verticalLineToRelative(-0.556f)\n            curveToRelative(0f, -0.409f, -0.332f, -0.741f, -0.741f, -0.741f)\n            horizontalLineToRelative(-1.483f)\n            verticalLineToRelative(3.706f)\n            horizontalLineToRelative(1.483f)\n            curveToRelative(0.409f, 0f, 0.741f, -0.332f, 0.741f, -0.741f)\n            verticalLineToRelative(-0.556f)\n            curveToRelative(0f, -0.297f, -0.259f, -0.556f, -0.556f, -0.556f)\n            curveToRelative(0.297f, -0f, 0.556f, -0.26f, 0.556f, -0.556f)\n            moveTo(14.489f, 13.114f)\n            horizontalLineToRelative(-0.741f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(0.741f)\n            moveTo(14.489f, 11.631f)\n            horizontalLineToRelative(-0.741f)\n            verticalLineToRelative(-0.741f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(0.741f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(15.761f, 10.148f)\n            verticalLineToRelative(3.706f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(-1.483f)\n            horizontalLineToRelative(0.741f)\n            curveToRelative(0.409f, 0f, 0.741f, -0.332f, 0.741f, -0.741f)\n            verticalLineToRelative(-0.741f)\n            curveToRelative(0f, -0.409f, -0.332f, -0.741f, -0.741f, -0.741f)\n            horizontalLineToRelative(-1.482f)\n            moveTo(16.502f, 10.89f)\n            horizontalLineToRelative(0.741f)\n            verticalLineToRelative(0.741f)\n            horizontalLineToRelative(-0.741f)\n            verticalLineToRelative(-0.741f)\n            close()\n        }\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19f, 3f)\n            horizontalLineTo(5f)\n            curveToRelative(-1.11f, 0f, -2f, 0.89f, -2f, 2f)\n            verticalLineToRelative(14f)\n            curveToRelative(0f, 1.105f, 0.895f, 2f, 2f, 2f)\n            horizontalLineToRelative(14f)\n            curveToRelative(1.105f, 0f, 2f, -0.895f, 2f, -2f)\n            verticalLineTo(5f)\n            curveToRelative(0f, -1.11f, -0.9f, -2f, -2f, -2f)\n            moveTo(19f, 5f)\n            verticalLineToRelative(14f)\n            horizontalLineTo(5f)\n            verticalLineTo(5f)\n            horizontalLineToRelative(14f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/Windows.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathFillType.Companion.NonZero\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.StrokeCap.Companion.Butt\nimport androidx.compose.ui.graphics.StrokeJoin.Companion.Miter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.ImageVector.Builder\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.Windows: ImageVector by lazy {\n    Builder(\n        name = \"Windows\", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,\n        viewportWidth = 24.0f, viewportHeight = 24.0f\n    ).apply {\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(2.0f, 4.0f)\n            verticalLineToRelative(7.4769f)\n            horizontalLineToRelative(9.481f)\n            verticalLineTo(2.0f)\n            horizontalLineTo(4.0f)\n            curveTo(2.8954f, 2.0f, 2.0f, 2.8954f, 2.0f, 4.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(2.0f, 20.0f)\n            curveToRelative(0.0f, 1.1046f, 0.8954f, 2.0f, 2.0f, 2.0f)\n            horizontalLineToRelative(7.481f)\n            verticalLineToRelative(-9.481f)\n            horizontalLineTo(2.0f)\n            verticalLineTo(20.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(20.0f, 2.0f)\n            horizontalLineToRelative(-7.481f)\n            verticalLineToRelative(9.4769f)\n            horizontalLineTo(22.0f)\n            verticalLineTo(4.0f)\n            curveTo(22.0f, 2.8954f, 21.1046f, 2.0f, 20.0f, 2.0f)\n            close()\n        }\n        path(\n            fill = SolidColor(Color(0xFF000000)), stroke = null, strokeLineWidth = 0.0f,\n            strokeLineCap = Butt, strokeLineJoin = Miter, strokeLineMiter = 4.0f,\n            pathFillType = NonZero\n        ) {\n            moveTo(12.519f, 22.0f)\n            horizontalLineTo(20.0f)\n            curveToRelative(1.1046f, 0.0f, 2.0f, -0.8954f, 2.0f, -2.0f)\n            verticalLineToRelative(-7.481f)\n            horizontalLineToRelative(-9.481f)\n            verticalLineTo(22.0f)\n            close()\n        }\n    }.build()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/icons/ZigzagLine.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.icons\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.path\nimport androidx.compose.ui.unit.dp\n\nval Icons.Rounded.ZigzagLine: ImageVector by lazy {\n    ImageVector.Builder(\n        name = \"ZigzagLine\",\n        defaultWidth = 24.dp,\n        defaultHeight = 24.dp,\n        viewportWidth = 24f,\n        viewportHeight = 24f\n    ).apply {\n        path(fill = SolidColor(Color(0xFF000000))) {\n            moveTo(19.011f, 5.493f)\n            horizontalLineToRelative(-6f)\n            curveToRelative(-0.828f, 0f, -1.499f, 0.671f, -1.499f, 1.499f)\n            curveToRelative(0f, 0.002f, 0.001f, 0.004f, 0.001f, 0.006f)\n            reflectiveCurveToRelative(-0.001f, 0.004f, -0.001f, 0.006f)\n            verticalLineToRelative(4.495f)\n            horizontalLineTo(6.989f)\n            curveToRelative(-0.828f, 0f, -1.499f, 0.671f, -1.499f, 1.499f)\n            curveToRelative(0f, 0.002f, 0.001f, 0.004f, 0.001f, 0.006f)\n            reflectiveCurveToRelative(-0.001f, 0.004f, -0.001f, 0.006f)\n            verticalLineToRelative(6f)\n            curveToRelative(0f, 0.828f, 0.671f, 1.499f, 1.499f, 1.499f)\n            reflectiveCurveToRelative(1.499f, -0.671f, 1.499f, -1.499f)\n            verticalLineToRelative(-4.512f)\n            horizontalLineToRelative(4.467f)\n            curveToRelative(0.019f, 0.001f, 0.037f, 0.006f, 0.056f, 0.006f)\n            curveToRelative(0.828f, 0f, 1.499f, -0.671f, 1.499f, -1.499f)\n            verticalLineToRelative(-4.512f)\n            horizontalLineToRelative(4.501f)\n            curveToRelative(0.828f, 0f, 1.499f, -0.671f, 1.499f, -1.499f)\n            reflectiveCurveTo(19.839f, 5.493f, 19.011f, 5.493f)\n            close()\n        }\n    }.build()\n}\n"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/ArrowShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val ArrowPathData =\n    \"M0.00127574 36.4191C0.00127574 42.8145 5.14768 48 11.4949 48C13.2236 48 14.863 47.6147 16.3341 46.9262C16.3341 46.9262 16.343 46.9223 16.3583 46.9146C16.496 46.8491 16.6337 46.7823 16.7676 46.7117C18.1252 46.0476 22.3143 44.0656 24.2634 43.9205C26.6065 43.7458 30.7293 45.0136 30.7293 45.0136L34.1891 46.6885C34.4147 46.808 34.6455 46.9185 34.88 47.0225L34.8915 47.0289H34.8953C35.8655 47.4579 36.9057 47.7559 37.9944 47.9011H37.997L38.0033 47.9024C38.2914 47.9409 38.5834 47.9679 38.8778 47.9833H38.8855C39.0907 47.9949 39.2973 48 39.5063 48C45.8536 48 51 42.8145 51 36.4191V36.3703C51 34.1995 50.4059 32.1687 49.3746 30.4321L35.905 6.40702C34.0195 2.6088 30.1225 1.30422e-06 25.6198 1.30422e-06C21.1172 1.30422e-06 17.2214 2.6088 15.3347 6.40702L1.88672 30.0133C1.63175 30.4051 1.39846 30.8123 1.19067 31.2349L1.18557 31.2439C0.427059 32.7904 -3.11934e-07 34.5296 -3.11934e-07 36.3703V36.4191H0.00127574Z\"\n\nval ArrowShape = PathShape(ArrowPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/BookmarkShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val BookmarkPathData =\n    \"M10 0C4.47715 0 0 4.47715 0 10V44.3522C0 46.1924 0.832489 48.0327 4 47.9996C5.04582 47.9996 11.1957 46.5617 16.3492 45.3564C18.5872 44.833 20.6375 44.3535 22 44.0549C22.5203 43.9314 23 44.0549 23 44.0549C26.0208 44.6465 29.2917 45.4016 32.2846 46.0925C36.4967 47.0648 40.158 47.91 41.796 47.9935L42.0617 47.9925C45.2368 47.8668 46 46.0449 46 43.8424V10C46 4.47715 41.5228 0 36 0H10Z\"\n\nval BookmarkShape = PathShape(BookmarkPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/BurgerShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val BurgerPathData =\n    \"M0.369565 7.44186C0.369565 3.33212 3.67833 0 7.76087 0H43.6087C47.6912 0 51 3.33212 51 7.44186V8.55814C51 12.6679 47.6912 16 43.6087 16C47.6912 16 51 19.3321 51 23.4419V24.5581C51 28.6679 47.6912 32 43.6087 32H43.2391C47.3217 32 50.6304 35.3321 50.6304 39.4419V40.5581C50.6304 44.6679 47.3217 48 43.2391 48H7.3913C3.30876 48 0 44.6679 0 40.5581V39.4419C0 35.3321 3.30876 32 7.3913 32H7.76087C3.67833 32 0.369565 28.6679 0.369565 24.5581V23.4419C0.369565 19.3321 3.67833 16 7.76087 16C3.67833 16 0.369565 12.6679 0.369565 8.55814V7.44186Z\"\n\nval BurgerShape = PathShape(BurgerPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/CloverShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval CloverShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 200f\n        val baseHeight = 200f\n\n        val path = Path().apply {\n            moveTo(12f, 100f)\n            cubicTo(12f, 76f, 0f, 77.6142f, 0f, 50f)\n            cubicTo(0f, 22.3858f, 22.3858f, 0f, 50f, 0f)\n            cubicTo(77.6142f, 0f, 76f, 12f, 100f, 12f)\n            cubicTo(124f, 12f, 122.3858f, 0f, 150f, 0f)\n            cubicTo(177.6142f, 0f, 200f, 22.3858f, 200f, 50f)\n            cubicTo(200f, 77.6142f, 188f, 76f, 188f, 100f)\n            cubicTo(188f, 124f, 200f, 122.3858f, 200f, 150f)\n            cubicTo(200f, 177.6142f, 177.6142f, 200f, 150f, 200f)\n            cubicTo(122.3858f, 200f, 124f, 188f, 100f, 188f)\n            cubicTo(76f, 188f, 77.6142f, 200f, 50f, 200f)\n            cubicTo(22.3858f, 200f, 0f, 177.6142f, 0f, 150f)\n            cubicTo(0f, 122.3858f, 12f, 124f, 12f, 100f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(Matrix().apply {\n                        setScale(size.width / baseWidth, size.height / baseHeight)\n                    })\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/DropletShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val DropletPathData =\n    \"M24 0C10.7452 0 0 10.7452 0 24C0 24.2317 0.00328295 24.4626 0.00980488 24.6927C0.00329738 24.8032 0 24.9144 0 25.0264V42.3896C0 45.4881 2.51186 48 5.61039 48H23.2847C23.3623 48 23.4396 47.9984 23.5167 47.9952C23.6774 47.9984 23.8385 48 24 48C37.2548 48 48 37.2548 48 24C48 10.7452 37.2548 0 24 0Z\"\n\nval DropletShape = PathShape(DropletPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/EggShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val EggPathData =\n    \"M37 29.0542C36.8496 35.2815 34.6566 40.4326 29.781 44.0763C24.0677 48.3452 17.7493 49.1448 11.1127 46.4063C6.52734 44.5131 3.32181 41.1353 1.35268 36.5987C0.595451 34.8535 0.132022 32.9832 0.0428338 31.0619C-0.236972 25.0372 0.852523 19.2731 3.35679 13.7856C5.28745 9.55367 7.91064 5.81135 11.3033 2.65723C13.3004 0.799282 15.7172 0.0455345 18.4891 0.00150717C22.8523 -0.0689365 25.743 2.33848 28.263 5.43624C30.0888 7.67987 31.7082 10.0732 32.997 12.6972C35.0484 16.871 36.346 21.2403 36.7639 25.8755C36.8636 26.9849 36.93 28.0962 37 29.056V29.0542Z\"\n\nval EggShape = PathShape(EggPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/ExplosionShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val ExplosionPathData =\n    \"M24.3629 0.130582C24.0071 -0.0526879 23.5886 -0.0422153 23.2434 0.156763C21.2763 1.29304 14.6586 5.04745 13.1833 5.04745C11.9748 5.04745 6.27256 2.52356 2.91398 0.984095C1.97755 0.55472 0.988809 1.45012 1.31839 2.42407C2.57394 6.1523 4.68221 12.6505 4.30554 13.2684C3.84518 14.0224 0.873717 21.6936 0.0890009 23.7357C-0.0313222 24.0499 -0.0103964 24.3955 0.146547 24.6992C1.13529 26.579 4.72929 33.5695 4.44156 35.1299C4.20614 36.4023 2.04556 42.0941 0.790014 45.3406C0.434276 46.2622 1.3027 47.1785 2.23912 46.8801C5.82789 45.7386 12.3463 43.686 12.9217 43.686C13.6227 43.686 21.925 47.0791 23.9601 47.9116C24.2478 48.0321 24.5669 48.0268 24.8546 47.9116C26.9211 47.0476 35.4745 43.487 35.8302 43.487C36.1179 43.487 41.7417 45.6286 44.9381 46.8591C45.8379 47.2047 46.743 46.3774 46.4866 45.4506C45.5554 42.0994 43.9285 36.1143 43.9756 35.3969C44.0331 34.5225 47.1458 26.223 47.9358 24.1284C48.0508 23.8247 48.0352 23.4844 47.8887 23.1912C46.9784 21.3689 43.6512 14.5984 43.7088 12.8704C43.7558 11.5038 45.6653 5.93238 46.8738 2.53403C47.2243 1.54961 46.2094 0.633265 45.2625 1.08358C41.7731 2.75396 35.9348 5.51871 35.4221 5.51871C34.7891 5.51871 26.6072 1.29827 24.3629 0.130582Z\"\n\nval ExplosionShape = PathShape(ExplosionPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/HeartShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval HeartShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val path = Path().apply {\n            val height = size.height\n            val width = size.width\n            moveTo(0.5f * width, 0.25f * height)\n            cubicTo(\n                0.5f * width,\n                0.225f * height,\n                0.45833334f * width,\n                0.125f * height,\n                0.29166666f * width,\n                0.125f * height\n            )\n            cubicTo(\n                0.041666668f * width,\n                0.125f * height,\n                0.041666668f * width,\n                0.4f * height,\n                0.041666668f * width,\n                0.4f * height\n            )\n            cubicTo(\n                0.041666668f * width,\n                0.5833333f * height,\n                0.20833333f * width,\n                0.76666665f * height,\n                0.5f * width,\n                0.9166667f * height\n            )\n            cubicTo(\n                0.7916667f * width,\n                0.76666665f * height,\n                0.9583333f * width,\n                0.5833333f * height,\n                0.9583333f * width,\n                0.4f * height\n            )\n            cubicTo(\n                0.9583333f * width,\n                0.4f * height,\n                0.9583333f * width,\n                0.125f * height,\n                0.7083333f * width,\n                0.125f * height\n            )\n            cubicTo(\n                0.5833333f * width,\n                0.125f * height,\n                0.5f * width,\n                0.225f * height,\n                0.5f * width,\n                0.25f * height\n            )\n            close()\n        }\n\n\n        return Outline.Generic(path)\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/KotlinShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval KotlinShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 1000f\n        val baseHeight = 1000f\n\n        val path = Path().apply {\n            moveTo(0f, 0f)\n            lineTo(1000f, 0f)\n            lineTo(473.5f, 500f)\n            lineTo(1000f, 1000f)\n            lineTo(0f, 1000f)\n            lineTo(0f, 0f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(Matrix().apply {\n                        setScale(size.width / baseWidth, size.height / baseHeight)\n                    })\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/MapShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val MapPathData =\n    \"M25.0702 4.38833C28.2859 2.26692 31.4412 0.185367 35.9294 0.00690002C41.3166 -0.204493 48 4.51158 48 4.51158L47.914 43.5389C41.8695 39.5777 37.3361 38.7019 34.1848 38.9888C29.4365 39.4182 26.0316 41.6001 22.7395 43.7097C19.4728 45.803 16.3173 47.8251 12.0706 47.9931C6.68339 48.2045 0 43.4884 0 43.4884V4.80351C5.84797 8.59348 10.4858 9.24276 13.8152 9.01123C18.563 8.68117 21.847 6.51473 25.0702 4.38833Z\"\n\nval MapShape = PathShape(MapPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/MaterialStarShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval MaterialStarShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 865.0807f\n        val baseHeight = 865.0807f\n\n        val path = Path().apply {\n            moveTo(403.3913f, 8.7356f)\n            cubicTo(421.0787f, -2.9119f, 444.002f, -2.9119f, 461.6894f, 8.7356f)\n            lineTo(518.743f, 46.3066f)\n            cubicTo(528.2839f, 52.5895f, 539.5995f, 55.6215f, 551.0036f, 54.9508f)\n            lineTo(619.1989f, 50.9402f)\n            cubicTo(640.3404f, 49.6968f, 660.1926f, 61.1585f, 669.6865f, 80.0892f)\n            lineTo(700.3109f, 141.1534f)\n            cubicTo(705.4321f, 151.365f, 713.7157f, 159.6486f, 723.9273f, 164.7699f)\n            lineTo(784.9915f, 195.3942f)\n            cubicTo(803.9222f, 204.8881f, 815.3839f, 224.7403f, 814.1406f, 245.8818f)\n            lineTo(810.1299f, 314.0771f)\n            cubicTo(809.4593f, 325.4812f, 812.4913f, 336.7969f, 818.7742f, 346.3378f)\n            lineTo(856.3451f, 403.3913f)\n            cubicTo(867.9926f, 421.0787f, 867.9927f, 444.002f, 856.3452f, 461.6894f)\n            lineTo(818.7742f, 518.743f)\n            cubicTo(812.4913f, 528.2839f, 809.4593f, 539.5995f, 810.1299f, 551.0036f)\n            lineTo(814.1406f, 619.1989f)\n            cubicTo(815.3839f, 640.3404f, 803.9223f, 660.1926f, 784.9916f, 669.6865f)\n            lineTo(723.9274f, 700.3109f)\n            cubicTo(713.7158f, 705.4321f, 705.4321f, 713.7157f, 700.3109f, 723.9273f)\n            lineTo(669.6866f, 784.9915f)\n            cubicTo(660.1926f, 803.9222f, 640.3404f, 815.3839f, 619.1989f, 814.1406f)\n            lineTo(551.0036f, 810.1299f)\n            cubicTo(539.5995f, 809.4593f, 528.2839f, 812.4913f, 518.743f, 818.7742f)\n            lineTo(461.6894f, 856.3451f)\n            cubicTo(444.0021f, 867.9926f, 421.0787f, 867.9927f, 403.3914f, 856.3452f)\n            lineTo(346.3378f, 818.7742f)\n            cubicTo(336.7969f, 812.4913f, 325.4812f, 809.4593f, 314.0771f, 810.1299f)\n            lineTo(245.8818f, 814.1406f)\n            cubicTo(224.7404f, 815.3839f, 204.8882f, 803.9223f, 195.3942f, 784.9916f)\n            lineTo(164.7699f, 723.9274f)\n            cubicTo(159.6486f, 713.7158f, 151.365f, 705.4321f, 141.1534f, 700.3109f)\n            lineTo(80.0892f, 669.6866f)\n            cubicTo(61.1585f, 660.1926f, 49.6968f, 640.3404f, 50.9402f, 619.199f)\n            lineTo(54.9508f, 551.0036f)\n            cubicTo(55.6215f, 539.5995f, 52.5895f, 528.2839f, 46.3066f, 518.743f)\n            lineTo(8.7356f, 461.6894f)\n            cubicTo(-2.9119f, 444.0021f, -2.9119f, 421.0787f, 8.7356f, 403.3914f)\n            lineTo(46.3066f, 346.3378f)\n            cubicTo(52.5895f, 336.7969f, 55.6215f, 325.4813f, 54.9508f, 314.0771f)\n            lineTo(50.9402f, 245.8818f)\n            cubicTo(49.6968f, 224.7404f, 61.1585f, 204.8882f, 80.0892f, 195.3942f)\n            lineTo(141.1534f, 164.7699f)\n            cubicTo(151.365f, 159.6486f, 159.6486f, 151.365f, 164.7699f, 141.1534f)\n            lineTo(195.3942f, 80.0892f)\n            cubicTo(204.8882f, 61.1585f, 224.7403f, 49.6968f, 245.8818f, 50.9402f)\n            lineTo(314.0771f, 54.9508f)\n            cubicTo(325.4813f, 55.6215f, 336.7969f, 52.5895f, 346.3378f, 46.3066f)\n            lineTo(403.3913f, 8.7356f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(Matrix().apply {\n                        setScale(size.width / baseWidth, size.height / baseHeight)\n                    })\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/MorphShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport androidx.compose.material3.toPath\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Matrix\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.graphics.shapes.Morph\n\nclass MorphShape(\n    private val morph: Morph,\n    private val percentage: () -> Float,\n    private val rotation: Float = 0f,\n) : Shape {\n\n    private val matrix = Matrix()\n\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density,\n    ): Outline {\n        matrix.reset()\n        matrix.scale(size.width, size.height)\n        matrix.rotateZ(rotation)\n\n        val path = morph.toPath(progress = percentage())\n        path.transform(matrix)\n        return Outline.Generic(path)\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/OctagonShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval OctagonShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 1000f\n        val baseHeight = 1000f\n\n        val path = Path().apply {\n            moveTo(500f, 0f)\n            lineTo(853.5534f, 146.4466f)\n            lineTo(1000f, 500f)\n            lineTo(853.5534f, 853.5534f)\n            lineTo(500f, 1000f)\n            lineTo(146.4466f, 853.5534f)\n            lineTo(0f, 500f)\n            lineTo(146.4466f, 146.4466f)\n            lineTo(500f, 0f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(Matrix().apply {\n                        setScale(size.width / baseWidth, size.height / baseHeight)\n                    })\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/OvalShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval OvalShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 1000f\n        val baseHeight = 1000f\n\n        val path = Path().apply {\n            moveTo(1000f, 500f)\n            cubicTo(1000f, 776.1424f, 776.1424f, 1000f, 500f, 1000f)\n            cubicTo(223.8576f, 1000f, 0f, 776.1424f, 0f, 500f)\n            cubicTo(0f, 223.8576f, 223.8576f, 0f, 500f, 0f)\n            cubicTo(776.1424f, 0f, 1000f, 223.8576f, 1000f, 500f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(Matrix().apply {\n                        setScale(size.width / baseWidth, size.height / baseHeight)\n                    })\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/PathShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nimport android.graphics.Matrix\nimport android.graphics.RectF\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.graphics.toAndroidRectF\nimport androidx.compose.ui.graphics.vector.PathParser\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\ninternal fun PathShape(pathData: String): Shape = PathShapeImpl(pathData)\n\nprivate class PathShapeImpl(private val pathData: String) : Shape {\n\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        return Outline.Generic(path = drawPath(size))\n    }\n\n    private fun drawPath(size: Size): Path {\n        return Path().apply {\n            reset()\n            addPath(pathData.toPath(size))\n            close()\n        }\n    }\n}\n\nprivate fun String.toPath(\n    size: Size\n): Path {\n    if (isNotEmpty()) {\n        val scaleMatrix = Matrix()\n        val rectF = RectF()\n        val path = PathParser().parsePathString(this).toPath()\n        val rectPath = path.getBounds().toAndroidRectF()\n        val scaleXFactor = size.width / rectPath.width()\n        val scaleYFactor = size.height / rectPath.height()\n        val androidPath = path.asAndroidPath()\n        scaleMatrix.setScale(scaleXFactor, scaleYFactor, rectF.centerX(), rectF.centerY())\n        @Suppress(\"DEPRECATION\")\n        androidPath.computeBounds(rectF, true)\n        androidPath.transform(scaleMatrix)\n        return androidPath.asComposePath()\n    }\n    return Path()\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/PentagonShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval PentagonShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 1224.1858f\n        val baseHeight = 1137.3882f\n\n        val path = Path().apply {\n            moveTo(521.133f, 28.588f)\n            cubicTo(575.7829f, -9.5293f, 648.4028f, -9.5293f, 703.0528f, 28.588f)\n            lineTo(1156.1332f, 344.6029f)\n            cubicTo(1214.148f, 385.0671f, 1238.4572f, 458.9902f, 1215.7808f, 525.9892f)\n            lineTo(1045.41f, 1029.3625f)\n            cubicTo(1023.5555f, 1093.9333f, 962.9716f, 1137.3882f, 894.8026f, 1137.3882f)\n            lineTo(329.3832f, 1137.3882f)\n            cubicTo(261.2142f, 1137.3882f, 200.6302f, 1093.9333f, 178.7757f, 1029.3625f)\n            lineTo(8.405f, 525.9893f)\n            cubicTo(-14.2714f, 458.9903f, 10.0377f, 385.0671f, 68.0526f, 344.6029f)\n            lineTo(521.133f, 28.588f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(Matrix().apply {\n                        setScale(size.width / baseWidth, size.height / baseHeight)\n                    })\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/PillShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val PillPathData =\n    \"M48 20.4342C48 9.14772 38.8281 0 27.5193 0C21.8632 0 16.743 2.28863 13.036 5.98382L5.99744 13.1154C2.29384 16.814 0 21.9225 0 27.5658C0 38.8523 9.16854 48 20.4807 48C26.1368 48 31.257 45.7114 34.964 42.0162L42.0026 34.8846C45.7096 31.186 48 26.0775 48 20.4342Z\"\n\nval PillShape = PathShape(PillPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/ShieldShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val ShieldPathData =\n    \"M22.8468 0.551384C24.8376 2.58461 34.1326 7.39938 41.7392 9.94215C42.1061 10.0645 42.4253 10.2994 42.6515 10.6135C42.8778 10.9276 42.9997 11.305 43 11.6923C43 32.5957 39.9697 42.7864 22.0137 47.9286C21.6828 48.0238 21.3319 48.0238 21.0011 47.9286C3.14341 42.8184 1.89533e-09 32.2757 1.89533e-09 12.0123C-1.82005e-05 11.6104 0.131069 11.2195 0.373309 10.8992C0.615549 10.5788 0.955673 10.3465 1.34191 10.2375C8.26315 8.39719 14.7081 5.08702 20.2392 0.531692C20.5968 0.202432 21.0611 0.0136179 21.5467 0C21.789 0.00155783 22.0286 0.051074 22.2517 0.145701C22.4748 0.240328 22.6771 0.378198 22.8468 0.551384Z\"\n\nval ShieldShape = PathShape(ShieldPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/ShurikenShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\n\nprivate const val ShurikenPathData =\n    \"M46.1183 46.1349C46.1183 46.1349 44.5771 44.149 46.1183 41.3152 55.7085 25.337 50.6851 6.5989 50.6851 6.5989L46.1183 9.8651C46.1183 9.8651 44.0233 11.2763 41.4317 9.8651 25.4025.2998 6.599 5.3129 6.599 5.3129L9.8756 9.8651C9.8756 9.8651 11.5539 11.5722 9.8756 14.6905 9.8185 14.7929 9.7729 14.8783 9.7215 14.9579.3483 30.8736 5.3146 49.4011 5.3146 49.4011L9.8813 46.1349C9.8813 46.1349 11.8621 44.6668 14.5622 46.1349 30.5971 55.7002 49.395 50.6871 49.395 50.6871L46.1183 46.1349Z\"\n\nval ShurikenShape = PathShape(ShurikenPathData)"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/SimpleHeartShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval SimpleHeartShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 24f\n        val baseHeight = 24f\n\n        val path = Path().apply {\n            moveTo(12.0f, 21.35f)\n            relativeLineTo(-1.45f, -1.32f)\n            cubicTo(5.4f, 15.36f, 2.0f, 12.28f, 2.0f, 8.5f)\n            cubicTo(2.0f, 5.42f, 4.42f, 3.0f, 7.5f, 3.0f)\n            relativeCubicTo(1.74f, 0.0f, 3.41f, 0.81f, 4.5f, 2.09f)\n            cubicTo(13.09f, 3.81f, 14.76f, 3.0f, 16.5f, 3.0f)\n            cubicTo(19.58f, 3.0f, 22.0f, 5.42f, 22.0f, 8.5f)\n            relativeCubicTo(0.0f, 3.78f, -3.4f, 6.86f, -8.55f, 11.54f)\n            lineTo(12.0f, 21.35f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(\n                        Matrix().apply {\n                            setScale(size.width / baseWidth, size.height / baseHeight)\n                        }\n                    )\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/SmallMaterialStarShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval SmallMaterialStarShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 2695.79f\n        val baseHeight = 2680.65f\n\n        val path = Path().apply {\n            moveTo(2537.8f, 975.157f)\n            cubicTo(2623.02f, 1101.61f, 2665.64f, 1164.84f, 2683.13f, 1233.15f)\n            cubicTo(2699.69f, 1297.82f, 2700.13f, 1365.57f, 2684.42f, 1430.45f)\n            cubicTo(2667.81f, 1498.98f, 2626.03f, 1562.76f, 2542.46f, 1690.32f)\n            cubicTo(2517.24f, 1728.81f, 2504.64f, 1748.05f, 2494.33f, 1768.43f)\n            cubicTo(2484.53f, 1787.8f, 2476.3f, 1807.93f, 2469.7f, 1828.61f)\n            cubicTo(2462.77f, 1850.37f, 2458.26f, 1872.96f, 2449.25f, 1918.15f)\n            cubicTo(2419.3f, 2068.37f, 2404.33f, 2143.48f, 2367.9f, 2204.19f)\n            cubicTo(2334.18f, 2260.38f, 2287.43f, 2307.62f, 2231.59f, 2341.92f)\n            cubicTo(2171.26f, 2378.98f, 2095.52f, 2394.9f, 1944.04f, 2426.74f)\n            cubicTo(1897.48f, 2436.53f, 1874.19f, 2441.42f, 1852.04f, 2448.8f)\n            cubicTo(1832.55f, 2455.29f, 1813.57f, 2463.25f, 1795.28f, 2472.6f)\n            cubicTo(1774.49f, 2483.22f, 1754.88f, 2496.27f, 1715.65f, 2522.35f)\n            cubicTo(1584.84f, 2609.34f, 1519.44f, 2652.83f, 1448.72f, 2669.7f)\n            cubicTo(1388.23f, 2684.12f, 1325.25f, 2684.53f, 1264.59f, 2670.89f)\n            cubicTo(1193.65f, 2654.95f, 1127.69f, 2612.31f, 995.759f, 2527.04f)\n            cubicTo(956.196f, 2501.47f, 936.414f, 2488.68f, 915.487f, 2478.33f)\n            cubicTo(897.073f, 2469.21f, 877.998f, 2461.51f, 858.423f, 2455.27f)\n            cubicTo(836.176f, 2448.18f, 812.831f, 2443.59f, 766.142f, 2434.41f)\n            cubicTo(614.258f, 2404.54f, 538.317f, 2389.61f, 477.51f, 2353.34f)\n            cubicTo(421.231f, 2319.77f, 373.865f, 2273.14f, 339.421f, 2217.4f)\n            cubicTo(302.205f, 2157.16f, 286.253f, 2082.26f, 254.349f, 1932.44f)\n            cubicTo(244.752f, 1887.38f, 239.953f, 1864.84f, 232.735f, 1843.18f)\n            cubicTo(225.871f, 1822.58f, 217.375f, 1802.56f, 207.326f, 1783.32f)\n            cubicTo(196.758f, 1763.08f, 183.9f, 1744f, 158.185f, 1705.84f)\n            cubicTo(72.9637f, 1579.38f, 30.3531f, 1516.16f, 12.8577f, 1447.85f)\n            cubicTo(-3.7056f, 1383.18f, -4.1467f, 1315.43f, 11.5731f, 1250.55f)\n            cubicTo(28.1775f, 1182.01f, 69.9612f, 1118.24f, 153.529f, 990.681f)\n            cubicTo(178.745f, 952.192f, 191.353f, 932.947f, 201.657f, 912.571f)\n            cubicTo(211.454f, 893.196f, 219.689f, 873.069f, 226.284f, 852.384f)\n            cubicTo(233.219f, 830.629f, 237.724f, 808.034f, 246.734f, 762.845f)\n            cubicTo(276.684f, 612.629f, 291.659f, 537.521f, 328.088f, 476.81f)\n            cubicTo(361.804f, 420.62f, 408.558f, 373.377f, 464.395f, 339.08f)\n            cubicTo(524.724f, 302.023f, 600.465f, 286.102f, 751.947f, 254.26f)\n            cubicTo(798.513f, 244.472f, 821.796f, 239.578f, 843.949f, 232.199f)\n            cubicTo(863.44f, 225.707f, 882.414f, 217.752f, 900.708f, 208.401f)\n            cubicTo(921.498f, 197.775f, 941.112f, 184.732f, 980.339f, 158.647f)\n            cubicTo(1111.14f, 71.6626f, 1176.55f, 28.1706f, 1247.27f, 11.3026f)\n            cubicTo(1307.75f, -3.122f, 1370.73f, -3.5321f, 1431.4f, 10.1038f)\n            cubicTo(1502.34f, 26.0493f, 1568.3f, 68.686f, 1700.23f, 153.959f)\n            cubicTo(1739.79f, 179.532f, 1759.57f, 192.318f, 1780.5f, 202.673f)\n            cubicTo(1798.91f, 211.784f, 1817.99f, 219.492f, 1837.57f, 225.73f)\n            cubicTo(1859.81f, 232.819f, 1883.16f, 237.41f, 1929.85f, 246.591f)\n            cubicTo(2081.73f, 276.457f, 2157.67f, 291.391f, 2218.48f, 327.659f)\n            cubicTo(2274.76f, 361.227f, 2322.12f, 407.856f, 2356.57f, 463.603f)\n            cubicTo(2393.78f, 523.834f, 2409.74f, 598.741f, 2441.64f, 748.554f)\n            cubicTo(2451.24f, 793.622f, 2456.04f, 816.156f, 2463.25f, 837.819f)\n            cubicTo(2470.12f, 858.417f, 2478.61f, 878.434f, 2488.66f, 897.68f)\n            cubicTo(2499.23f, 917.921f, 2512.09f, 937f, 2537.8f, 975.157f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(\n                        Matrix().apply {\n                            setScale(size.width / baseWidth, size.height / baseHeight)\n                        }\n                    )\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/java/com/t8rin/imagetoolbox/core/resources/shapes/SquircleShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.resources.shapes\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\n\nval SquircleShape: Shape = object : Shape {\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline {\n        val baseWidth = 1000f\n        val baseHeight = 1000f\n\n        val path = Path().apply {\n            moveTo(0f, 500f)\n            cubicTo(0f, 88.25f, 88.25f, 0f, 500f, 0f)\n            cubicTo(911.75f, 0f, 1000f, 88.25f, 1000f, 500f)\n            cubicTo(1000f, 911.75f, 911.75f, 1000f, 500f, 1000f)\n            cubicTo(88.25f, 1000f, 0f, 911.75f, 0f, 500f)\n            close()\n        }\n\n        return Outline.Generic(\n            path\n                .asAndroidPath()\n                .apply {\n                    transform(Matrix().apply {\n                        setScale(size.width / baseWidth, size.height / baseHeight)\n                    })\n                }\n                .asComposePath()\n        )\n    }\n}"
  },
  {
    "path": "core/resources/src/main/res/drawable/app_registration_24px.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?attr/colorControlNormal\"\n    android:viewportWidth=\"960\"\n    android:viewportHeight=\"960\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M240,800Q207,800 183.5,776.5Q160,753 160,720Q160,687 183.5,663.5Q207,640 240,640Q273,640 296.5,663.5Q320,687 320,720Q320,753 296.5,776.5Q273,800 240,800ZM240,560Q207,560 183.5,536.5Q160,513 160,480Q160,447 183.5,423.5Q207,400 240,400Q273,400 296.5,423.5Q320,447 320,480Q320,513 296.5,536.5Q273,560 240,560ZM240,320Q207,320 183.5,296.5Q160,273 160,240Q160,207 183.5,183.5Q207,160 240,160Q273,160 296.5,183.5Q320,207 320,240Q320,273 296.5,296.5Q273,320 240,320ZM480,320Q447,320 423.5,296.5Q400,273 400,240Q400,207 423.5,183.5Q447,160 480,160Q513,160 536.5,183.5Q560,207 560,240Q560,273 536.5,296.5Q513,320 480,320ZM720,320Q687,320 663.5,296.5Q640,273 640,240Q640,207 663.5,183.5Q687,160 720,160Q753,160 776.5,183.5Q800,207 800,240Q800,273 776.5,296.5Q753,320 720,320ZM480,560Q447,560 423.5,536.5Q400,513 400,480Q400,447 423.5,423.5Q447,400 480,400Q513,400 536.5,423.5Q560,447 560,480Q560,513 536.5,536.5Q513,560 480,560ZM520,800L520,677L741,457Q750,448 761,444Q772,440 783,440Q795,440 806,444.5Q817,449 826,458L863,495Q871,504 875.5,515Q880,526 880,537Q880,548 876,559.5Q872,571 863,580L643,800L520,800ZM820,537L820,537L783,500L783,500L820,537ZM580,740L618,740L739,618L721,599L702,581L580,702L580,740ZM721,599L702,581L702,581L739,618L739,618L721,599Z\" />\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/ic_24_barcode_scanner.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"960\"\n    android:viewportHeight=\"960\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:pathData=\"M228.5,828.5Q217,840 200,840L80,840q-17,0 -28.5,-11.5T40,800v-120q0,-17 11.5,-28.5T80,640q17,0 28.5,11.5T120,680v80h80q17,0 28.5,11.5T240,800q0,17 -11.5,28.5ZM908.5,651.5Q920,663 920,680v120q0,17 -11.5,28.5T880,840L760,840q-17,0 -28.5,-11.5T720,800q0,-17 11.5,-28.5T760,760h80v-80q0,-17 11.5,-28.5T880,640q17,0 28.5,11.5ZM180,720q-8,0 -14,-6t-6,-14v-440q0,-8 6,-14t14,-6h40q8,0 14,6t6,14v440q0,8 -6,14t-14,6h-40ZM286,714q-6,-6 -6,-14v-440q0,-8 6,-14t14,-6q8,0 14,6t6,14v440q0,8 -6,14t-14,6q-8,0 -14,-6ZM420,720q-8,0 -14,-6t-6,-14v-440q0,-8 6,-14t14,-6h40q8,0 14,6t6,14v440q0,8 -6,14t-14,6h-40ZM540,720q-8,0 -14,-6t-6,-14v-440q0,-8 6,-14t14,-6h80q8,0 14,6t6,14v440q0,8 -6,14t-14,6h-80ZM686,714q-6,-6 -6,-14v-440q0,-8 6,-14t14,-6q8,0 14,6t6,14v440q0,8 -6,14t-14,6q-8,0 -14,-6ZM766,714q-6,-6 -6,-14v-440q0,-8 6,-14t14,-6q8,0 14,6t6,14v440q0,8 -6,14t-14,6q-8,0 -14,-6ZM228.5,188.5Q217,200 200,200h-80v80q0,17 -11.5,28.5T80,320q-17,0 -28.5,-11.5T40,280v-120q0,-17 11.5,-28.5T80,120h120q17,0 28.5,11.5T240,160q0,17 -11.5,28.5ZM731.5,131.5Q743,120 760,120h120q17,0 28.5,11.5T920,160v120q0,17 -11.5,28.5T880,320q-17,0 -28.5,-11.5T840,280v-80h-80q-17,0 -28.5,-11.5T720,160q0,-17 11.5,-28.5Z\" />\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/ic_launcher_foreground.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <group\n        android:scaleX=\"0.8\"\n        android:scaleY=\"0.8\"\n        android:translateX=\"12\"\n        android:translateY=\"11\">\n\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:fillType=\"evenOdd\"\n            android:pathData=\"M57.74,43.82V47.67C57.74,48.33 57.97,48.89 58.42,49.33C58.87,49.78 59.43,50 60.1,50H64C64.32,50 64.62,49.95 64.92,49.83C65.21,49.71 65.48,49.54 65.71,49.3L78,37.17C78.35,36.82 78.61,36.42 78.76,35.97C78.92,35.52 79,35.09 79,34.66C79,34.23 78.91,33.8 78.73,33.38C78.56,32.95 78.31,32.56 78,32.21L75.81,30.05C75.46,29.7 75.06,29.44 74.63,29.26C74.2,29.09 73.74,29 73.27,29C72.84,29 72.41,29.08 71.97,29.23C71.54,29.39 71.15,29.64 70.79,29.99L58.45,42.13C58.21,42.36 58.04,42.62 57.92,42.92C57.8,43.21 57.74,43.51 57.74,43.82ZM63.53,46.5H61.28V44.29L68.49,37.23L70.67,39.39L63.53,46.5Z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M69.89,56.22C69.89,53.33 69.89,50.99 69.83,49.03L73.81,45.1C74.11,47.9 74.11,51.47 74.11,56.22C74.11,65.82 74.11,70.61 71.6,73.95C70.86,74.92 69.99,75.79 69,76.51C65.63,79 60.77,79 51.06,79C41.35,79 36.49,79 33.11,76.51C32.13,75.79 31.25,74.92 30.52,73.95C28,70.61 28,65.82 28,56.22C28,46.62 28,41.83 30.52,38.49C31.25,37.52 32.13,36.65 33.11,35.93C36.49,33.44 41.35,33.44 51.06,33.44C56.32,33.44 60.16,33.44 63.1,33.84L59.19,37.7C57.05,37.61 54.42,37.61 51.06,37.61C46.11,37.61 42.74,37.62 40.17,37.9C37.69,38.17 36.47,38.65 35.63,39.27C34.98,39.75 34.39,40.33 33.9,40.98C33.27,41.81 32.78,43.01 32.51,45.47C32.23,48 32.22,51.33 32.22,56.22C32.22,61.11 32.23,64.44 32.51,66.97C32.57,67.53 32.64,68.01 32.73,68.45L32.77,68.42C36.59,65.67 40.54,62.82 43.92,64.75L46.82,66.5C49.64,68.23 52.89,65.29 56.42,62.08C58.8,59.93 61.31,57.65 63.89,56.62C66.26,55.68 67.84,56.49 69.89,58.17C69.89,57.55 69.89,56.9 69.89,56.22Z\"\n            tools:ignore=\"VectorPath\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M38.98,48.81C38.98,51.54 41.18,53.71 43.94,53.71C46.71,53.71 48.91,51.45 48.91,48.81C48.91,46.07 46.71,43.9 43.94,43.9C41.18,43.9 38.98,46.07 38.98,48.81Z\" />\n\n    </group>\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/ic_launcher_monochrome_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <group>\n        <path\n            android:fillColor=\"#FFFFFF\"\n            android:fillType=\"evenOdd\"\n            android:pathData=\"M13.995,7.113V8.962C13.995,9.279 14.102,9.545 14.315,9.76C14.528,9.974 14.792,10.082 15.107,10.082H16.941C17.089,10.082 17.233,10.054 17.372,9.998C17.511,9.942 17.636,9.858 17.747,9.746L23.528,3.921C23.694,3.753 23.815,3.561 23.889,3.347C23.963,3.132 24,2.922 24,2.717C24,2.511 23.958,2.306 23.875,2.1C23.792,1.895 23.676,1.708 23.528,1.54L22.499,0.504C22.333,0.336 22.147,0.21 21.944,0.126C21.74,0.042 21.527,0 21.304,0C21.101,0 20.897,0.037 20.693,0.112C20.489,0.187 20.304,0.308 20.137,0.476L14.329,6.301C14.218,6.413 14.134,6.539 14.079,6.679C14.023,6.819 13.995,6.964 13.995,7.113ZM16.719,8.402H15.663V7.337L19.053,3.949L20.081,4.985L16.719,8.402Z\" />\n        <path\n            android:fillColor=\"#FFFFFF\"\n            android:pathData=\"M19.715,13.066C19.715,11.679 19.714,10.554 19.686,9.615L21.558,7.728C21.701,9.073 21.701,10.788 21.701,13.066C21.701,17.671 21.701,19.974 20.517,21.576C20.171,22.044 19.76,22.458 19.295,22.806C17.706,24 15.421,24 10.851,24C6.28,24 3.995,24 2.406,22.806C1.942,22.458 1.53,22.044 1.184,21.576C0,19.974 0,17.671 0,13.066C0,8.46 0,6.157 1.184,4.555C1.53,4.088 1.942,3.673 2.406,3.325C3.995,2.131 6.28,2.131 10.851,2.131C13.327,2.131 15.132,2.131 16.52,2.321L14.678,4.177C13.669,4.134 12.431,4.133 10.851,4.133C8.52,4.133 6.935,4.136 5.728,4.27C4.56,4.4 3.988,4.633 3.592,4.93C3.283,5.162 3.008,5.439 2.777,5.751C2.482,6.15 2.251,6.726 2.122,7.904C1.989,9.12 1.986,10.717 1.986,13.066C1.986,15.414 1.989,17.011 2.122,18.228C2.151,18.492 2.185,18.726 2.224,18.935L2.244,18.921C4.041,17.601 5.901,16.234 7.493,17.159L8.854,18.002C10.184,18.832 11.713,17.417 13.374,15.88C14.494,14.845 15.673,13.754 16.891,13.257C18.003,12.804 18.749,13.194 19.714,14.003C19.715,13.704 19.715,13.392 19.715,13.066Z\" />\n        <path\n            android:fillColor=\"#FFFFFF\"\n            android:pathData=\"M5.168,9.507C5.168,10.82 6.201,11.861 7.503,11.861C8.806,11.861 9.839,10.775 9.839,9.507C9.839,8.195 8.806,7.154 7.503,7.154C6.201,7.154 5.168,8.195 5.168,9.507Z\" />\n    </group>\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/ic_logo_animated.xml",
    "content": "<!--\n     ~ ImageToolbox is an image editor for android\n     ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n     ~\n     ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n     ~ you may not use this file except in compliance with the License.\n     ~\n     ~ Unless required by applicable law or agreed to in writing, software\n     ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n     ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     ~ See the License for the specific language governing permissions and\n     ~ limitations under the License.\n     ~\n     ~ You should have received a copy of the Apache License\n     ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n     -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <group\n        android:scaleX=\"0.8\"\n        android:scaleY=\"0.8\"\n        android:translateX=\"12\"\n        android:translateY=\"11\">\n\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:fillType=\"evenOdd\"\n            android:pathData=\"M57.74,43.82V47.67C57.74,48.33 57.97,48.89 58.42,49.33C58.87,49.78 59.43,50 60.1,50H64C64.32,50 64.62,49.95 64.92,49.83C65.21,49.71 65.48,49.54 65.71,49.3L78,37.17C78.35,36.82 78.61,36.42 78.76,35.97C78.92,35.52 79,35.09 79,34.66C79,34.23 78.91,33.8 78.73,33.38C78.56,32.95 78.31,32.56 78,32.21L75.81,30.05C75.46,29.7 75.06,29.44 74.63,29.26C74.2,29.09 73.74,29 73.27,29C72.84,29 72.41,29.08 71.97,29.23C71.54,29.39 71.15,29.64 70.79,29.99L58.45,42.13C58.21,42.36 58.04,42.62 57.92,42.92C57.8,43.21 57.74,43.51 57.74,43.82ZM63.53,46.5H61.28V44.29L68.49,37.23L70.67,39.39L63.53,46.5Z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M69.89,56.22C69.89,53.33 69.89,50.99 69.83,49.03L73.81,45.1C74.11,47.9 74.11,51.47 74.11,56.22C74.11,65.82 74.11,70.61 71.6,73.95C70.86,74.92 69.99,75.79 69,76.51C65.63,79 60.77,79 51.06,79C41.35,79 36.49,79 33.11,76.51C32.13,75.79 31.25,74.92 30.52,73.95C28,70.61 28,65.82 28,56.22C28,46.62 28,41.83 30.52,38.49C31.25,37.52 32.13,36.65 33.11,35.93C36.49,33.44 41.35,33.44 51.06,33.44C56.32,33.44 60.16,33.44 63.1,33.84L59.19,37.7C57.05,37.61 54.42,37.61 51.06,37.61C46.11,37.61 42.74,37.62 40.17,37.9C37.69,38.17 36.47,38.65 35.63,39.27C34.98,39.75 34.39,40.33 33.9,40.98C33.27,41.81 32.78,43.01 32.51,45.47C32.23,48 32.22,51.33 32.22,56.22C32.22,61.11 32.23,64.44 32.51,66.97C32.57,67.53 32.64,68.01 32.73,68.45L32.77,68.42C36.59,65.67 40.54,62.82 43.92,64.75L46.82,66.5C49.64,68.23 52.89,65.29 56.42,62.08C58.8,59.93 61.31,57.65 63.89,56.62C66.26,55.68 67.84,56.49 69.89,58.17C69.89,57.55 69.89,56.9 69.89,56.22Z\"\n            tools:ignore=\"VectorPath\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M38.98,48.81C38.98,51.54 41.18,53.71 43.94,53.71C46.71,53.71 48.91,51.45 48.91,48.81C48.91,46.07 46.71,43.9 43.94,43.9C41.18,43.9 38.98,46.07 38.98,48.81Z\" />\n\n    </group>\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/ic_notification_icon.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <group\n        android:scaleX=\"2.1\"\n        android:scaleY=\"2.1\"\n        android:translateX=\"-59\"\n        android:translateY=\"-59\">\n\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:fillType=\"evenOdd\"\n            android:pathData=\"M57.74,43.82V47.67C57.74,48.33 57.97,48.89 58.42,49.33C58.87,49.78 59.43,50 60.1,50H64C64.32,50 64.62,49.95 64.92,49.83C65.21,49.71 65.48,49.54 65.71,49.3L78,37.17C78.35,36.82 78.61,36.42 78.76,35.97C78.92,35.52 79,35.09 79,34.66C79,34.23 78.91,33.8 78.73,33.38C78.56,32.95 78.31,32.56 78,32.21L75.81,30.05C75.46,29.7 75.06,29.44 74.63,29.26C74.2,29.09 73.74,29 73.27,29C72.84,29 72.41,29.08 71.97,29.23C71.54,29.39 71.15,29.64 70.79,29.99L58.45,42.13C58.21,42.36 58.04,42.62 57.92,42.92C57.8,43.21 57.74,43.51 57.74,43.82ZM63.53,46.5H61.28V44.29L68.49,37.23L70.67,39.39L63.53,46.5Z\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M69.89,56.22C69.89,53.33 69.89,50.99 69.83,49.03L73.81,45.1C74.11,47.9 74.11,51.47 74.11,56.22C74.11,65.82 74.11,70.61 71.6,73.95C70.86,74.92 69.99,75.79 69,76.51C65.63,79 60.77,79 51.06,79C41.35,79 36.49,79 33.11,76.51C32.13,75.79 31.25,74.92 30.52,73.95C28,70.61 28,65.82 28,56.22C28,46.62 28,41.83 30.52,38.49C31.25,37.52 32.13,36.65 33.11,35.93C36.49,33.44 41.35,33.44 51.06,33.44C56.32,33.44 60.16,33.44 63.1,33.84L59.19,37.7C57.05,37.61 54.42,37.61 51.06,37.61C46.11,37.61 42.74,37.62 40.17,37.9C37.69,38.17 36.47,38.65 35.63,39.27C34.98,39.75 34.39,40.33 33.9,40.98C33.27,41.81 32.78,43.01 32.51,45.47C32.23,48 32.22,51.33 32.22,56.22C32.22,61.11 32.23,64.44 32.51,66.97C32.57,67.53 32.64,68.01 32.73,68.45L32.77,68.42C36.59,65.67 40.54,62.82 43.92,64.75L46.82,66.5C49.64,68.23 52.89,65.29 56.42,62.08C58.8,59.93 61.31,57.65 63.89,56.62C66.26,55.68 67.84,56.49 69.89,58.17C69.89,57.55 69.89,56.9 69.89,56.22Z\"\n            tools:ignore=\"VectorPath\" />\n        <path\n            android:fillColor=\"@color/onPrimary\"\n            android:pathData=\"M38.98,48.81C38.98,51.54 41.18,53.71 43.94,53.71C46.71,53.71 48.91,51.45 48.91,48.81C48.91,46.07 46.71,43.9 43.94,43.9C41.18,43.9 38.98,46.07 38.98,48.81Z\" />\n\n    </group>\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/image_to_text_outlined.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000000\"\n        android:pathData=\"M19.31,18.9L22.39,22L21,23.39L17.88,20.32C17.19,20.75 16.37,21 15.5,21C13,21 11,19 11,16.5C11,14 13,12 15.5,12C18,12 20,14 20,16.5C20,17.38 19.75,18.21 19.31,18.9M15.5,19C16.88,19 18,17.88 18,16.5C18,15.12 16.88,14 15.5,14C14.12,14 13,15.12 13,16.5C13,17.88 14.12,19 15.5,19M21,4V6H3V4H21M3,16V14H9V16H3M3,11V9H21V11H18.97C17.96,10.37 16.77,10 15.5,10C14.23,10 13.04,10.37 12.03,11H3Z\"\n        android:strokeColor=\"#00000000\" />\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/mobile_screenshot.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M19.725,6.65c-0.183,-0.25 -0.425,-0.433 -0.725,-0.55v-3.1c0,-0.55 -0.196,-1.021 -0.588,-1.412s-0.862,-0.588 -1.412,-0.588H7c-0.55,0 -1.021,0.196 -1.412,0.588s-0.588,0.862 -0.588,1.412v18c0,0.55 0.196,1.021 0.588,1.412s0.862,0.588 1.412,0.588h10c0.55,0 1.021,-0.196 1.412,-0.588s0.588,-0.862 0.588,-1.412v-10.1c0.3,-0.117 0.542,-0.3 0.725,-0.55 0.183,-0.25 0.275,-0.533 0.275,-0.85v-2c0,-0.317 -0.092,-0.6 -0.275,-0.85ZM17,21H7V3h10v18Z\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M7,21V3v18Z\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,20l4,0l0,-4l-1.5,0l0,2.5l-2.5,0l0,1.5z\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M8,8l1.5,0l0,-2.5l2.5,0l0,-1.5l-4,0l0,4z\" />\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/multiple_image_edit.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M6,6.5c0,-0.417 0.146,-0.771 0.438,-1.063 0.292,-0.292 0.646,-0.438 1.063,-0.438h9c0.417,0 0.771,0.146 1.063,0.438s0.438,0.646 0.438,1.063H6Z\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M7,3.5c0,-0.417 0.146,-0.771 0.438,-1.063s0.646,-0.438 1.063,-0.438h7c0.417,0 0.771,0.146 1.063,0.438s0.438,0.646 0.438,1.063H7Z\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M20.615,16.463c-0.062,-0.151 -0.148,-0.288 -0.257,-0.412l-0.762,-0.762c-0.124,-0.124 -0.261,-0.216 -0.412,-0.278s-0.309,-0.093 -0.474,-0.093c-0.151,0 -0.302,0.027 -0.453,0.082s-0.288,0.144 -0.412,0.268l-4.552,4.531v2.533h2.533l4.531,-4.531c0.124,-0.124 0.213,-0.264 0.268,-0.422 0.055,-0.158 0.082,-0.312 0.082,-0.463s-0.031,-0.302 -0.093,-0.453ZM15.311,21.097h-0.783v-0.783l2.513,-2.492 0.391,0.371 0.371,0.391 -2.492,2.513Z\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M18.412,8.588c-0.392,-0.392 -0.862,-0.588 -1.412,-0.588H7c-0.55,0 -1.021,0.196 -1.412,0.588s-0.588,0.862 -0.588,1.412v10c0,0.55 0.196,1.021 0.588,1.412s0.862,0.588 1.412,0.588h4.801v-2h-4.801v-10h10v3.642h2v-3.642c0,-0.55 -0.196,-1.021 -0.588,-1.412Z\" />\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M14.93,15.73l-1.387,-1.849l-1.875,2.5l-1.375,-1.825l-2.125,2.825l5.111,0l1.651,-1.651z\" />\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/outline_colorize_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:pathData=\"M19.35,11.72L17.22,13.85L15.81,12.43L8.1,20.14L3.5,22L2,20.5L3.86,15.9L11.57,8.19L10.15,6.78L12.28,4.65L19.35,11.72M16.76,3C17.93,1.83 19.83,1.83 21,3C22.17,4.17 22.17,6.07 21,7.24L19.08,9.16L14.84,4.92L16.76,3M5.56,17.03L4.5,19.5L6.97,18.44L14.4,11L13,9.6L5.56,17.03Z\" />\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/outline_drag_handle_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"960\"\n    android:viewportHeight=\"960\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M160,600L160,520L800,520L800,600L160,600ZM160,440L160,360L800,360L800,440L160,440Z\" />\n\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/palette_swatch_outlined.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000000\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M2.5,19.6L3.8,20.2V11.2L1.4,17C1,18.1 1.5,19.2 2.5,19.6M15.2,4.8L20.2,16.8L12.9,19.8L7.9,7.9V7.8L15.2,4.8M15.3,2.8C15,2.8 14.8,2.8 14.5,2.9L7.1,6C6.4,6.3 5.9,7 5.9,7.8C5.9,8 5.9,8.3 6,8.6L11,20.5C11.3,21.3 12,21.7 12.8,21.7C13.1,21.7 13.3,21.7 13.6,21.6L21,18.5C22,18.1 22.5,16.9 22.1,15.9L17.1,4C16.8,3.2 16,2.8 15.3,2.8M10.5,9.9C9.9,9.9 9.5,9.5 9.5,8.9S9.9,7.9 10.5,7.9C11.1,7.9 11.5,8.4 11.5,8.9S11.1,9.9 10.5,9.9M5.9,19.8C5.9,20.9 6.8,21.8 7.9,21.8H9.3L5.9,13.5V19.8Z\"\n        android:strokeWidth=\"0.0\"\n        android:strokeColor=\"#00000000\" />\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/rounded_document_scanner_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"960\"\n    android:viewportHeight=\"960\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M80,200L80,120Q80,87 103.5,63.5Q127,40 160,40L240,40Q257,40 268.5,51.5Q280,63 280,80Q280,97 268.5,108.5Q257,120 240,120L160,120Q160,120 160,120Q160,120 160,120L160,200Q160,217 148.5,228.5Q137,240 120,240Q103,240 91.5,228.5Q80,217 80,200ZM800,200L800,120Q800,120 800,120Q800,120 800,120L720,120Q703,120 691.5,108.5Q680,97 680,80Q680,63 691.5,51.5Q703,40 720,40L800,40Q833,40 856.5,63.5Q880,87 880,120L880,200Q880,217 868.5,228.5Q857,240 840,240Q823,240 811.5,228.5Q800,217 800,200ZM80,840L80,760Q80,743 91.5,731.5Q103,720 120,720Q137,720 148.5,731.5Q160,743 160,760L160,840Q160,840 160,840Q160,840 160,840L240,840Q257,840 268.5,851.5Q280,863 280,880Q280,897 268.5,908.5Q257,920 240,920L160,920Q127,920 103.5,896.5Q80,873 80,840ZM800,920L720,920Q703,920 691.5,908.5Q680,897 680,880Q680,863 691.5,851.5Q703,840 720,840L800,840Q800,840 800,840Q800,840 800,840L800,760Q800,743 811.5,731.5Q823,720 840,720Q857,720 868.5,731.5Q880,743 880,760L880,840Q880,873 856.5,896.5Q833,920 800,920ZM280,720Q280,720 280,720Q280,720 280,720L680,720Q680,720 680,720Q680,720 680,720L680,240Q680,240 680,240Q680,240 680,240L280,240Q280,240 280,240Q280,240 280,240L280,720ZM280,800Q247,800 223.5,776.5Q200,753 200,720L200,240Q200,207 223.5,183.5Q247,160 280,160L680,160Q713,160 736.5,183.5Q760,207 760,240L760,720Q760,753 736.5,776.5Q713,800 680,800L280,800ZM400,400L560,400Q577,400 588.5,388.5Q600,377 600,360Q600,343 588.5,331.5Q577,320 560,320L400,320Q383,320 371.5,331.5Q360,343 360,360Q360,377 371.5,388.5Q383,400 400,400ZM400,520L560,520Q577,520 588.5,508.5Q600,497 600,480Q600,463 588.5,451.5Q577,440 560,440L400,440Q383,440 371.5,451.5Q360,463 360,480Q360,497 371.5,508.5Q383,520 400,520ZM400,640L560,640Q577,640 588.5,628.5Q600,617 600,600Q600,583 588.5,571.5Q577,560 560,560L400,560Q383,560 371.5,571.5Q360,583 360,600Q360,617 371.5,628.5Q383,640 400,640ZM280,720L280,240Q280,240 280,240Q280,240 280,240L280,240Q280,240 280,240Q280,240 280,240L280,720Q280,720 280,720Q280,720 280,720L280,720Q280,720 280,720Q280,720 280,720Z\" />\n\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/rounded_qr_code_scanner_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"960\"\n    android:viewportHeight=\"960\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M120,280Q103,280 91.5,268.5Q80,257 80,240L80,120Q80,103 91.5,91.5Q103,80 120,80L240,80Q257,80 268.5,91.5Q280,103 280,120Q280,137 268.5,148.5Q257,160 240,160L160,160L160,240Q160,257 148.5,268.5Q137,280 120,280ZM120,880Q103,880 91.5,868.5Q80,857 80,840L80,720Q80,703 91.5,691.5Q103,680 120,680Q137,680 148.5,691.5Q160,703 160,720L160,800L240,800Q257,800 268.5,811.5Q280,823 280,840Q280,857 268.5,868.5Q257,880 240,880L120,880ZM720,880Q703,880 691.5,868.5Q680,857 680,840Q680,823 691.5,811.5Q703,800 720,800L800,800L800,720Q800,703 811.5,691.5Q823,680 840,680Q857,680 868.5,691.5Q880,703 880,720L880,840Q880,857 868.5,868.5Q857,880 840,880L720,880ZM840,280Q823,280 811.5,268.5Q800,257 800,240L800,160L720,160Q703,160 691.5,148.5Q680,137 680,120Q680,103 691.5,91.5Q703,80 720,80L840,80Q857,80 868.5,91.5Q880,103 880,120L880,240Q880,257 868.5,268.5Q857,280 840,280ZM700,760L700,700L760,700L760,760L700,760ZM700,640L700,580L760,580L760,640L700,640ZM640,700L640,640L700,640L700,700L640,700ZM580,760L580,700L640,700L640,760L580,760ZM520,700L520,640L580,640L580,700L520,700ZM640,580L640,520L700,520L700,580L640,580ZM580,640L580,580L640,580L640,640L580,640ZM520,580L520,520L580,520L580,580L520,580ZM560,440Q543,440 531.5,428.5Q520,417 520,400L520,240Q520,223 531.5,211.5Q543,200 560,200L720,200Q737,200 748.5,211.5Q760,223 760,240L760,400Q760,417 748.5,428.5Q737,440 720,440L560,440ZM240,760Q223,760 211.5,748.5Q200,737 200,720L200,560Q200,543 211.5,531.5Q223,520 240,520L400,520Q417,520 428.5,531.5Q440,543 440,560L440,720Q440,737 428.5,748.5Q417,760 400,760L240,760ZM240,440Q223,440 211.5,428.5Q200,417 200,400L200,240Q200,223 211.5,211.5Q223,200 240,200L400,200Q417,200 428.5,211.5Q440,223 440,240L440,400Q440,417 428.5,428.5Q417,440 400,440L240,440ZM260,700L380,700L380,580L260,580L260,700ZM260,380L380,380L380,260L260,260L260,380ZM580,380L700,380L700,260L580,260L580,380Z\" />\n\n</vector>\n"
  },
  {
    "path": "core/resources/src/main/res/drawable/shape_find_in_file.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <corners\n        android:bottomLeftRadius=\"0dp\"\n        android:bottomRightRadius=\"0dp\"\n        android:topLeftRadius=\"0dp\"\n        android:topRightRadius=\"0dp\" />\n    <padding\n        android:bottom=\"12dp\"\n        android:left=\"12dp\"\n        android:right=\"12dp\"\n        android:top=\"12dp\" />\n</shape>"
  },
  {
    "path": "core/resources/src/main/res/drawable-v31/ic_logo_animated.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animated-vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\">\n\n    <aapt:attr name=\"android:drawable\">\n        <vector\n            android:width=\"108dp\"\n            android:height=\"108dp\"\n            android:viewportWidth=\"108\"\n            android:viewportHeight=\"108\">\n\n            <group\n                android:name=\"root\"\n                android:scaleX=\"0.8\"\n                android:scaleY=\"0.8\"\n                android:translateX=\"12\"\n                android:translateY=\"11\">\n\n                <group\n                    android:name=\"pencil\"\n                    android:alpha=\"1\"\n                    android:pivotX=\"54\"\n                    android:pivotY=\"54\"\n                    android:scaleX=\"2.4\"\n                    android:scaleY=\"2.4\"\n                    android:translateX=\"-36\"\n                    android:translateY=\"36\">\n\n                    <path\n                        android:fillColor=\"@color/onPrimary\"\n                        android:fillType=\"evenOdd\"\n                        android:pathData=\"M57.74,43.82V47.67C57.74,48.33 57.97,48.89 58.42,49.33C58.87,49.78 59.43,50 60.1,50H64C64.32,50 64.62,49.95 64.92,49.83C65.21,49.71 65.48,49.54 65.71,49.3L78,37.17C78.35,36.82 78.61,36.42 78.76,35.97C78.92,35.52 79,35.09 79,34.66C79,34.23 78.91,33.8 78.73,33.38C78.56,32.95 78.31,32.56 78,32.21L75.81,30.05C75.46,29.7 75.06,29.44 74.63,29.26C74.2,29.09 73.74,29 73.27,29C72.84,29 72.41,29.08 71.97,29.23C71.54,29.39 71.15,29.64 70.79,29.99L58.45,42.13C58.21,42.36 58.04,42.62 57.92,42.92C57.8,43.21 57.74,43.51 57.74,43.82ZM63.53,46.5H61.28V44.29L68.49,37.23L70.67,39.39L63.53,46.5Z\" />\n                </group>\n\n                <group android:name=\"body\">\n\n                    <path\n                        android:name=\"body_path1\"\n                        android:alpha=\"0.0\"\n                        android:fillColor=\"@color/onPrimary\"\n                        android:pathData=\"M69.89,56.22C69.89,53.33 69.89,50.99 69.83,49.03L73.81,45.1C74.11,47.9 74.11,51.47 74.11,56.22C74.11,65.82 74.11,70.61 71.6,73.95C70.86,74.92 69.99,75.79 69,76.51C65.63,79 60.77,79 51.06,79C41.35,79 36.49,79 33.11,76.51C32.13,75.79 31.25,74.92 30.52,73.95C28,70.61 28,65.82 28,56.22C28,46.62 28,41.83 30.52,38.49C31.25,37.52 32.13,36.65 33.11,35.93C36.49,33.44 41.35,33.44 51.06,33.44C56.32,33.44 60.16,33.44 63.1,33.84L59.19,37.7C57.05,37.61 54.42,37.61 51.06,37.61C46.11,37.61 42.74,37.62 40.17,37.9C37.69,38.17 36.47,38.65 35.63,39.27C34.98,39.75 34.39,40.33 33.9,40.98C33.27,41.81 32.78,43.01 32.51,45.47C32.23,48 32.22,51.33 32.22,56.22C32.22,61.11 32.23,64.44 32.51,66.97C32.57,67.53 32.64,68.01 32.73,68.45L32.77,68.42C36.59,65.67 40.54,62.82 43.92,64.75L46.82,66.5C49.64,68.23 52.89,65.29 56.42,62.08C58.8,59.93 61.31,57.65 63.89,56.62C66.26,55.68 67.84,56.49 69.89,58.17C69.89,57.55 69.89,56.9 69.89,56.22Z\" />\n\n                    <path\n                        android:name=\"body_path2\"\n                        android:alpha=\"0.0\"\n                        android:fillColor=\"@color/onPrimary\"\n                        android:pathData=\"M38.98,48.81C38.98,51.54 41.18,53.71 43.94,53.71C46.71,53.71 48.91,51.45 48.91,48.81C48.91,46.07 46.71,43.9 43.94,43.9C41.18,43.9 38.98,46.07 38.98,48.81Z\" />\n                </group>\n\n            </group>\n        </vector>\n    </aapt:attr>\n\n    <target android:name=\"pencil\">\n        <aapt:attr name=\"android:animation\">\n            <set android:ordering=\"together\">\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"translateX\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"-36\"\n                    android:valueTo=\"0\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"translateY\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"36\"\n                    android:valueTo=\"0\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"scaleX\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"2.4\"\n                    android:valueTo=\"1\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/overshoot\"\n                    android:propertyName=\"scaleY\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"2.4\"\n                    android:valueTo=\"1\" />\n            </set>\n        </aapt:attr>\n    </target>\n\n    <target android:name=\"body_path1\">\n        <aapt:attr name=\"android:animation\">\n            <set android:ordering=\"together\">\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/decelerate_quad\"\n                    android:propertyName=\"fillAlpha\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"0.0\"\n                    android:valueTo=\"1.0\"\n                    android:valueType=\"floatType\" />\n            </set>\n        </aapt:attr>\n    </target>\n\n    <target android:name=\"body_path2\">\n        <aapt:attr name=\"android:animation\">\n            <set android:ordering=\"together\">\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/decelerate_quad\"\n                    android:propertyName=\"fillAlpha\"\n                    android:startOffset=\"150\"\n                    android:valueFrom=\"0.0\"\n                    android:valueTo=\"1.0\"\n                    android:valueType=\"floatType\" />\n            </set>\n        </aapt:attr>\n    </target>\n\n\n</animated-vector>"
  },
  {
    "path": "core/resources/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n    <monochrome android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "core/resources/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n    <monochrome android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "core/resources/src/main/res/raw/keep.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:keep=\"@raw/aboutlibraries\" />"
  },
  {
    "path": "core/resources/src/main/res/values/arrays.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <!--language keys mapped to tessertact training data -->\n    <string-array name=\"key_ocr_engine_language_value\">\n        <item>afr</item>\n        <item>amh</item>\n        <item>ara</item>\n        <item>asm</item>\n        <item>aze</item>\n        <item>bel</item>\n        <item>ben</item>\n        <item>bod</item>\n        <item>bos</item>\n        <item>bul</item>\n        <item>cat</item>\n        <item>ceb</item>\n        <item>ces</item>\n        <item>chi_sim</item>\n        <item>chi_tra</item>\n        <item>chr</item>\n        <item>cos</item>\n        <item>cym</item>\n        <item>dan</item>\n        <item>deu</item>\n        <item>div</item>\n        <item>dzo</item>\n        <item>ell</item>\n        <item>eng</item>\n        <item>enm</item>\n        <item>epo</item>\n        <item>eqo</item>\n        <item>est</item>\n        <item>eus</item>\n        <item>fao</item>\n        <item>fas</item>\n        <item>fil</item>\n        <item>fin</item>\n        <item>fra</item>\n        <item>frk</item>\n        <item>frm</item>\n        <item>fry</item>\n        <item>gla</item>\n        <item>gle</item>\n        <item>glg</item>\n        <item>grc</item>\n        <item>guj</item>\n        <item>hat</item>\n        <item>heb</item>\n        <item>hin</item>\n        <item>hrv</item>\n        <item>hun</item>\n        <item>hye</item>\n        <item>iku</item>\n        <item>ind</item>\n        <item>isl</item>\n        <item>ita</item>\n        <item>jav</item>\n        <item>jpn</item>\n        <item>kan</item>\n        <item>kat</item>\n        <item>kaz</item>\n        <item>khm</item>\n        <item>kir</item>\n        <item>kmr</item>\n        <item>kor</item>\n        <item>kur</item>\n        <item>lao</item>\n        <item>lat</item>\n        <item>lav</item>\n        <item>lit</item>\n        <item>ltz</item>\n        <item>mal</item>\n        <item>mar</item>\n        <item>mkd</item>\n        <item>mlt</item>\n        <item>mon</item>\n        <item>mri</item>\n        <item>msa</item>\n        <item>mya</item>\n        <item>nep</item>\n        <item>nld</item>\n        <item>nor</item>\n        <item>oci</item>\n        <item>ori</item>\n        <item>osd</item>\n        <item>pan</item>\n        <item>pol</item>\n        <item>por</item>\n        <item>pus</item>\n        <item>que</item>\n        <item>ron</item>\n        <item>rus</item>\n        <item>san</item>\n        <item>sin</item>\n        <item>slk</item>\n        <item>slv</item>\n        <item>snd</item>\n        <item>spa</item>\n        <item>sqi</item>\n        <item>srp</item>\n        <item>sun</item>\n        <item>swa</item>\n        <item>swe</item>\n        <item>syr</item>\n        <item>tam</item>\n        <item>tat</item>\n        <item>tel</item>\n        <item>tgk</item>\n        <item>tgl</item>\n        <item>tha</item>\n        <item>tir</item>\n        <item>ton</item>\n        <item>tur</item>\n        <item>uig</item>\n        <item>ukr</item>\n        <item>urd</item>\n        <item>uzb</item>\n        <item>vie</item>\n        <item>yid</item>\n        <item>yor</item>\n    </string-array>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values/bools.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <bool name=\"at_least_26\">false</bool>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">#ABE87C</color>\n    <color name=\"onPrimary\">#394F29</color>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"ic_launcher_background\">@color/primary</color>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  --><resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\" translatable=\"false\">Image Toolbox</string>\n    <string name=\"app_launcher_name\" translatable=\"false\">Image Toolbox</string>\n    <string name=\"file_provider\" translatable=\"false\">com.t8rin.imagetoolbox.fileprovider</string>\n    <string name=\"smth_went_wrong\">Something went wrong: %1$s</string>\n    <string name=\"size\">Size %1$s</string>\n    <string name=\"loading\">Loading…</string>\n    <string name=\"image_too_large_preview\">Image is too large to preview, but saving will be attempted anyway</string>\n    <string name=\"pick_image\">Pick image to start</string>\n    <string name=\"width\">Width %1$s</string>\n    <string name=\"height\">Height %1$s</string>\n    <string name=\"quality\">Quality</string>\n    <string name=\"extension\">Extension</string>\n    <string name=\"resize_type\">Resize type</string>\n    <string name=\"explicit\">Explicit</string>\n    <string name=\"flexible\">Flexible</string>\n    <string name=\"pick_image_alt\">Pick Image</string>\n    <string name=\"app_closing_sub\">Are you sure you want to close the app?</string>\n    <string name=\"app_closing\">App closing</string>\n    <string name=\"stay\">Stay</string>\n    <string name=\"close\">Close</string>\n    <string name=\"reset_image\">Reset image</string>\n    <string name=\"reset_image_sub\">Image changes will roll back to initial values</string>\n    <string name=\"values_reset\">Values properly reset</string>\n    <string name=\"reset\">Reset</string>\n    <string name=\"something_went_wrong\">Something went wrong</string>\n    <string name=\"restart_app\">Restart app</string>\n    <string name=\"copied\">Copied to clipboard</string>\n    <string name=\"exception\">Exception</string>\n    <string name=\"edit_exif\">Edit EXIF</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">No EXIF data found</string>\n    <string name=\"add_tag\">Add tag</string>\n    <string name=\"save\">Save</string>\n    <string name=\"clear\">Clear</string>\n    <string name=\"clear_exif\">Clear EXIF</string>\n    <string name=\"cancel\">Cancel</string>\n    <string name=\"clear_exif_sub\">All image EXIF data will be erased. This action cannot be undone!</string>\n    <string name=\"presets\">Presets</string>\n    <string name=\"crop\">Crop</string>\n    <string name=\"image_not_saved\">Saving</string>\n    <string name=\"image_not_saved_sub\">All unsaved changes will be lost, if you exit now</string>\n    <string name=\"check_source_code\">Source code</string>\n    <string name=\"check_source_code_sub\">Get the latest updates, discuss issues and more</string>\n    <string name=\"single_edit\">Single Edit</string>\n    <string name=\"single_edit_sub\">Modify, resize and edit one image</string>\n    <string name=\"pick_color\">Color Picker</string>\n    <string name=\"pick_color_sub\">Pick color from image, copy or share</string>\n    <string name=\"image\">Image</string>\n    <string name=\"color\">Color</string>\n    <string name=\"color_copied\">Color copied</string>\n    <string name=\"crop_sub\">Crop image to any bounds</string>\n    <string name=\"version\">Version</string>\n    <string name=\"keep_exif\">Keep EXIF</string>\n    <string name=\"images\">Images: %d</string>\n    <string name=\"change_preview\">Change preview</string>\n    <string name=\"remove\">Remove</string>\n    <string name=\"palette_sub\">Generate color palette swatch from given image</string>\n    <string name=\"generate_palette\">Generate Palette</string>\n    <string name=\"palette\">Palette</string>\n    <string name=\"update\">Update</string>\n    <string name=\"new_version\">New version %1$s</string>\n    <string name=\"unsupported_type\">Unsupported type: %1$s</string>\n    <string name=\"no_palette\">Cannot generate palette for given image</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Output folder</string>\n    <string name=\"default_folder\" translatable=\"false\">Documents/ImageToolbox</string>\n    <string name=\"def\">Default</string>\n    <string name=\"custom\">Custom</string>\n    <string name=\"unspecified\">Unspecified</string>\n    <string name=\"device_storage\">Device storage</string>\n    <string name=\"by_bytes_resize\">Resize by Weight</string>\n    <string name=\"max_bytes\">Max size in KB</string>\n    <string name=\"by_bytes_resize_sub\">Resize an image following given size in KB</string>\n    <string name=\"compare\">Compare</string>\n    <string name=\"compare_sub\">Compare two given images</string>\n    <string name=\"pick_two_images\">Pick two images to start</string>\n    <string name=\"pick_images\">Pick images</string>\n    <string name=\"settings\">Settings</string>\n    <string name=\"night_mode\">Night Mode</string>\n    <string name=\"dark\">Dark</string>\n    <string name=\"light\">Light</string>\n    <string name=\"system\">System</string>\n    <string name=\"dynamic_colors\">Dynamic colors</string>\n    <string name=\"customization\">Customization</string>\n    <string name=\"allow_image_monet\">Allow image monet</string>\n    <string name=\"allow_image_monet_sub\">If enabled, when you choose an image to edit, app colors will be adopted to this image</string>\n    <string name=\"language\">Language</string>\n    <string name=\"amoled_mode\">Amoled mode</string>\n    <string name=\"amoled_mode_sub\">If enabled surfaces color will be set to absolute dark in night mode</string>\n    <string name=\"color_scheme\">Color scheme</string>\n    <string name=\"color_red\">Red</string>\n    <string name=\"color_green\">Green</string>\n    <string name=\"color_blue\">Blue</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Paste a valid aRGB color code</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nothing to paste</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">The app\\'s color scheme cannot be changed while dynamic colors are turned on</string>\n    <string name=\"pick_accent_color\">App theme will be based on selected color</string>\n    <string name=\"about_app\">About app</string>\n    <string name=\"app_developer\" translatable=\"false\">Malik Mukhametzyanov</string>\n    <string name=\"app_developer_nick\" translatable=\"false\">T8RIN</string>\n    <string name=\"no_updates\">No updates found</string>\n    <string name=\"issue_tracker\">Issue tracker</string>\n    <string name=\"issue_tracker_sub\">Send bug reports and feature requests here</string>\n    <string name=\"help_translate\">Help translate</string>\n    <string name=\"help_translate_sub\">Correct translation mistakes or localize project to another languages</string>\n    <string name=\"nothing_found_by_search\">Nothing found by your query</string>\n    <string name=\"search_here\">Search here</string>\n    <string name=\"dynamic_colors_sub\">If enabled, then app colors will be adopted to wallpaper colors</string>\n    <string name=\"failed_to_save\">Failed to save %d image(s)</string>\n    <string name=\"telegram\" translatable=\"false\">Telegram</string>\n    <string name=\"email\">Email</string>\n    <string name=\"github\" translatable=\"false\">GitHub</string>\n    <string name=\"developer_email\" translatable=\"false\">t8rin@bk.ru</string>\n    <string name=\"primary\">Primary</string>\n    <string name=\"tertiary\">Tertiary</string>\n    <string name=\"secondary\">Secondary</string>\n    <string name=\"border_thickness\">Border thickness</string>\n    <string name=\"surface\">Surface</string>\n    <string name=\"values\">Values</string>\n    <string name=\"add\">Add</string>\n    <string name=\"permission\">Permission</string>\n    <string name=\"grant\">Grant</string>\n    <string name=\"permission_sub\">App needs access to your storage to save images to work, it is necessary. Please grant permission in the next dialog box.</string>\n    <string name=\"grant_permission_manual\">App needs this permission to work, please grant it manually</string>\n    <string name=\"external_storage\">External storage</string>\n    <string name=\"monet_colors\">Monet colors</string>\n    <string name=\"donation_sub\">This application is completely free, but if you want to support the project development, you can click here</string>\n    <string name=\"fab_alignment\">FAB alignment</string>\n    <string name=\"check_updates\">Check for updates</string>\n    <string name=\"check_updates_sub\">If enabled, update dialog will be shown to you on app startup</string>\n    <string name=\"zoom\">Image zoom</string>\n    <string name=\"share\">Share</string>\n    <string name=\"prefix\">Prefix</string>\n    <string name=\"filename\">Filename</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Select which emoji to display on the main screen</string>\n    <string name=\"add_file_size\">Add file size</string>\n    <string name=\"add_file_size_sub\">If enabled, adds width and height of saved image to the name of output file</string>\n    <string name=\"delete_exif\">Delete EXIF</string>\n    <string name=\"delete_exif_sub\">Delete EXIF metadata from any set of images</string>\n    <string name=\"image_preview\">Image Preview</string>\n    <string name=\"image_preview_sub\">Preview any type of images: GIF, SVG, and so on</string>\n    <string name=\"image_source\">Image source</string>\n    <string name=\"photo_picker\">Photo picker</string>\n    <string name=\"gallery_picker\">Gallery</string>\n    <string name=\"file_explorer_picker\">File explorer</string>\n    <string name=\"photo_picker_sub\">Android modern photo picker which appears at the bottom of the screen, may work only on android 12+. Has issues receiving EXIF metadata</string>\n    <string name=\"gallery_picker_sub\">Simple gallery image picker. It will work only if you have an app that provides media picking</string>\n    <string name=\"file_explorer_picker_sub\">Use GetContent intent to pick image. Works everywhere, but is known to have issues receiving picked images on some devices. That\\'s not my fault.</string>\n    <string name=\"options_arrangement\">Options arrangement</string>\n    <string name=\"edit\">Edit</string>\n    <string name=\"order\">Order</string>\n    <string name=\"order_sub\">Determines order of the tools on the main screen</string>\n    <string name=\"emojis_count\">Emojis count</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"add_original_filename\">Add original filename</string>\n    <string name=\"add_original_filename_sub\">If enabled adds original filename in the name of the output image</string>\n    <string name=\"replace_sequence_number\">Replace sequence number</string>\n    <string name=\"replace_sequence_number_sub\">If enabled replaces standard timestamp to the image sequence number if you use batch processing</string>\n    <string name=\"filename_not_work_with_photopicker\">Adding original filename doesn\\'t work if photo picker image source selected</string>\n    <string name=\"load_image_from_net\">Web Image Loading</string>\n    <string name=\"load_image_from_net_sub\">Load any image from the internet to preview, zoom, edit and save it if you want.</string>\n    <string name=\"no_image\">No image</string>\n    <string name=\"image_link\">Image link</string>\n    <string name=\"fill\">Fill</string>\n    <string name=\"fit\">Fit</string>\n    <string name=\"content_scale\">Content scale</string>\n    <string name=\"explicit_description\">Resizes images to the given height and width. The aspect ratio of the images may change.</string>\n    <string name=\"flexible_description\">Resizes images with a long side to the given height or width. All size calculations will be done after saving. The aspect ratio of the images will be preserved.</string>\n    <string name=\"brightness\">Brightness</string>\n    <string name=\"contrast\">Contrast</string>\n    <string name=\"hue\">Hue</string>\n    <string name=\"saturation\">Saturation</string>\n    <string name=\"add_filter\">Add filter</string>\n    <string name=\"filter\">Filter</string>\n    <string name=\"filter_sub\">Apply filter chains to images</string>\n    <string name=\"filters\">Filters</string>\n    <string name=\"light_aka_illumination\">Light</string>\n    <string name=\"color_filter\">Color filter</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"exposure\">Exposure</string>\n    <string name=\"white_balance\">White balance</string>\n    <string name=\"temperature\">Temperature</string>\n    <string name=\"tint\">Tint</string>\n    <string name=\"monochrome\">Monochrome</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Highlights and shadows</string>\n    <string name=\"highlights\">Highlights</string>\n    <string name=\"shadows\">Shadows</string>\n    <string name=\"haze\">Haze</string>\n    <string name=\"effect\">Effect</string>\n    <string name=\"distance\">Distance</string>\n    <string name=\"slope\">Slope</string>\n    <string name=\"sharpen\">Sharpen</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negative</string>\n    <string name=\"solarize\">Solarize</string>\n    <string name=\"vibrance\">Vibrance</string>\n    <string name=\"black_and_white\">Black and White</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">Spacing</string>\n    <string name=\"line_width\">Line width</string>\n    <string name=\"sobel_edge\">Sobel edge</string>\n    <string name=\"blur\">Blur</string>\n    <string name=\"halftone\">Halftone</string>\n    <string name=\"cga_colorspace\">CGA colorspace</string>\n    <string name=\"gaussian_blur\">Gaussian blur</string>\n    <string name=\"box_blur\">Box blur</string>\n    <string name=\"bilaterial_blur\">Bilaterial blur</string>\n    <string name=\"emboss\">Emboss</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Vignette</string>\n    <string name=\"start\">Start</string>\n    <string name=\"end\">End</string>\n    <string name=\"kuwahara\">Kuwahara smoothing</string>\n    <string name=\"stack_blur\">Stack blur</string>\n    <string name=\"radius\">Radius</string>\n    <string name=\"scale\">Scale</string>\n    <string name=\"distortion\">Distortion</string>\n    <string name=\"angle\">Angle</string>\n    <string name=\"swirl\">Swirl</string>\n    <string name=\"bulge\">Bulge</string>\n    <string name=\"dilation\">Dilation</string>\n    <string name=\"sphere_refraction\">Sphere refraction</string>\n    <string name=\"refractive_index\">Refractive index</string>\n    <string name=\"glass_sphere_refraction\">Glass sphere refraction</string>\n    <string name=\"color_matrix\">Color matrix</string>\n    <string name=\"float_array_of\" translatable=\"false\">floatArrayOf(f, f, f)</string>\n    <string name=\"opacity\">Opacity</string>\n    <string name=\"limits_resize\">Resize by Limits</string>\n    <string name=\"limits_resize_sub\">Resize images to the given height and width while keeping the aspect ratio</string>\n    <string name=\"sketch\">Sketch</string>\n    <string name=\"threshold\">Threshold</string>\n    <string name=\"quantizationLevels\">Quantization levels</string>\n    <string name=\"smooth_toon\">Smooth toon</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterize</string>\n    <string name=\"non_maximum_suppression\">Non maximum suppression</string>\n    <string name=\"weak_pixel_inclusion\">Weak pixel inclusion</string>\n    <string name=\"lookup\">Lookup</string>\n    <string name=\"convolution3x3\">Convolution 3x3</string>\n    <string name=\"rgb_filter\">RGB filter</string>\n    <string name=\"false_color\">False color</string>\n    <string name=\"first_color\">First color</string>\n    <string name=\"second_color\">Second color</string>\n    <string name=\"reorder\">Reorder</string>\n    <string name=\"fast_blur\">Fast blur</string>\n    <string name=\"blur_size\">Blur size</string>\n    <string name=\"blur_center_x\">Blur center x</string>\n    <string name=\"blur_center_y\">Blur center y</string>\n    <string name=\"zoom_blur\">Zoom blur</string>\n    <string name=\"color_balance\">Color balance</string>\n    <string name=\"luminance_threshold\">Luminance threshold</string>\n    <string name=\"activate_files\">You disabled Files app, activate it to use this feature</string>\n    <string name=\"draw\">Draw</string>\n    <string name=\"draw_sub\">Draw on image like in a sketchbook, or draw on the background itself</string>\n    <string name=\"paint_color\">Paint color</string>\n    <string name=\"paint_alpha\">Paint alpha</string>\n    <string name=\"draw_on_image\">Draw on image</string>\n    <string name=\"draw_on_image_sub\">Pick an image and draw something on it</string>\n    <string name=\"draw_on_background\">Draw on background</string>\n    <string name=\"draw_on_background_sub\">Pick background color and draw on top of it</string>\n    <string name=\"background_color\">Background color</string>\n    <string name=\"cipher\">Cipher</string>\n    <string name=\"cipher_sub\">Encrypt and Decrypt any file (not only the image) based on various available crypto algorithms</string>\n    <string name=\"pick_file\">Pick file</string>\n    <string name=\"encrypt\">Encrypt</string>\n    <string name=\"decrypt\">Decrypt</string>\n    <string name=\"pick_file_to_start\">Pick file to start</string>\n    <string name=\"open_markup_project\">Open project</string>\n    <string name=\"open_markup_project_sub\">Continue editing a previously saved Image Toolbox project</string>\n    <string name=\"markup_project_open_failed\">Unable to open Image Toolbox project</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox project is missing project data</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox project is corrupted</string>\n    <string name=\"unsupported_markup_project_version\">Unsupported Image Toolbox project version: %1$d</string>\n    <string name=\"decryption\">Decryption</string>\n    <string name=\"encryption\">Encryption</string>\n    <string name=\"key\">Key</string>\n    <string name=\"file_proceed\">File processed</string>\n    <string name=\"store_file_desc\">Store this file on your device or use share action to put it wherever you want</string>\n    <string name=\"features\">Features</string>\n    <string name=\"implementation\">Implementation</string>\n    <string name=\"compatibility\">Compatibility</string>\n    <string name=\"features_sub\">Password-based encryption of files. Proceeded files can be stored in the selected directory or shared. Decrypted files can also be opened directly.</string>\n    <string name=\"implementation_sub\">AES-256, GCM mode, no padding, 12 bytes random IVs by default. You can select the needed algorithm. Keys are used as 256-bit SHA-3 hashes</string>\n    <string name=\"file_size\">File size</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent.\n\\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">Please note that compatibility to other file encryption software or services is not guaranteed. A slightly different key treatment or cipher configuration may cause incompatibility.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Invalid password or chosen file is not encrypted</string>\n    <string name=\"image_size_warning\">Trying to save the image with the given width and height may cause an out of memory error. Do this at your own risk.</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Cache size</string>\n    <string name=\"found_s\">Found %1$s</string>\n    <string name=\"auto_cache_clearing\">Auto cache clearing</string>\n    <string name=\"auto_cache_clearing_sub\">If enabled app cache will be cleared on app startup</string>\n    <string name=\"create\">Create</string>\n    <string name=\"tools\">Tools</string>\n    <string name=\"group_options_by_type\">Group options by type</string>\n    <string name=\"group_options_by_type_sub\">Groups options on the main screen by their type instead of a custom list arrangement</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Cannot change arrangement while option grouping is enabled</string>\n    <string name=\"default_prefix\" translatable=\"false\">ResizedImage</string>\n    <string name=\"edit_screenshot\">Edit screenshot</string>\n    <string name=\"secondary_customization\">Secondary customization</string>\n    <string name=\"screenshot\">Screenshot</string>\n    <string name=\"fallback_option\">Fallback option</string>\n    <string name=\"skip\">Skip</string>\n    <string name=\"copy\">Copy</string>\n    <string name=\"warning_bytes\">Saving in %1$s mode can be unstable, because it is a lossless format</string>\n    <string name=\"presets_sub\" formatted=\"false\">If you have selected preset 125, image will be saved as 125% size of the original image. If you choose preset 50, then image will be saved with 50% size</string>\n    <string name=\"presets_sub_bytes\">Preset here determines % of output file, i.e. if you select preset 50 on 5 MB image then you will get a 2,5 MB image after saving</string>\n    <string name=\"randomize_filename\">Randomize filename</string>\n    <string name=\"randomize_filename_sub\">If enabled output filename will be fully random</string>\n    <string name=\"saved_to\">Saved to %1$s folder with name %2$s</string>\n    <string name=\"saved_to_without_filename\">Saved to %1$s folder</string>\n    <string name=\"tg_chat\">Telegram chat</string>\n    <string name=\"tg_chat_sub\">Discuss the app and get feedback from other users. You can also get beta updates and insights there.</string>\n    <string name=\"crop_mask\">Crop mask</string>\n    <string name=\"aspect_ratio\">Aspect ratio</string>\n    <string name=\"image_crop_mask_sub\">Use this mask type to create mask from given image, notice that it SHOULD have alpha channel</string>\n    <string name=\"backup_and_restore\">Backup and restore</string>\n    <string name=\"backup\">Backup</string>\n    <string name=\"restore\">Restore</string>\n    <string name=\"backup_sub\">Backup your app settings to a file</string>\n    <string name=\"restore_sub\">Restore app settings from previously generated file</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Corrupted file or not a backup</string>\n    <string name=\"settings_restored\">Settings restored successfully</string>\n    <string name=\"contact_me\">Contact me</string>\n    <string name=\"reset_settings_sub\">This will roll back your settings to the default values. Notice that this can\\'t be undone without a backup file mentioned above.</string>\n    <string name=\"delete\">Delete</string>\n    <string name=\"delete_color_scheme_warn\">You are about to delete selected color scheme. This operation cannot be undone</string>\n    <string name=\"delete_color_scheme_title\">Delete scheme</string>\n    <string name=\"font\">Font</string>\n    <string name=\"text\">Text</string>\n    <string name=\"font_scale\">Font scale</string>\n    <string name=\"defaultt\">Default</string>\n    <string name=\"using_large_fonts_warn\">Using large font scales may cause UI glitches and problems, which won\\'t be fixed. Use cautiously.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"emotions\">Emotions</string>\n    <string name=\"food_and_drink\">Food and Drink</string>\n    <string name=\"nature_and_animals\">Nature and Animals</string>\n    <string name=\"objects\">Objects</string>\n    <string name=\"symbols\">Symbols</string>\n    <string name=\"enable_emoji\">Enable emoji</string>\n    <string name=\"travels_and_places\">Travels and Places</string>\n    <string name=\"activities\">Activities</string>\n    <string name=\"background_remover\">Background Remover</string>\n    <string name=\"background_remover_sub\">Remove background from image by drawing or use Auto option</string>\n    <string name=\"trim_image\">Trim image</string>\n    <string name=\"keep_exif_sub\">Original image metadata will be kept</string>\n    <string name=\"trim_image_sub\">Trasparent spaces around image will be trimmed</string>\n    <string name=\"auto_erase_background\">Auto erase background</string>\n    <string name=\"restore_image\">Restore image</string>\n    <string name=\"erase_mode\">Erase mode</string>\n    <string name=\"erase_background\">Erase background</string>\n    <string name=\"restore_background\">Restore background</string>\n    <string name=\"blur_radius\">Blur radius</string>\n    <string name=\"pipette\">Pipette</string>\n    <string name=\"draw_mode\">Draw mode</string>\n    <string name=\"create_issue\">Create Issue</string>\n    <string name=\"something_went_wrong_emphasis\">Oops… Something went wrong. You can write to me using options below and I\\'ll try to find solution</string>\n    <string name=\"resize_and_convert\">Resize and Convert</string>\n    <string name=\"resize_and_convert_sub\">Change size of given images or convert them to other formats. EXIF metadata can also be edited here if picking a single image.</string>\n    <string name=\"max_colors_count\">Max color count</string>\n    <string name=\"firebase\" translatable=\"false\">Firebase</string>\n    <string name=\"crashlytics\" translatable=\"false\">Crashlytics</string>\n    <string name=\"crashlytics_sub\">This allows the app to collect crash reports automatically</string>\n    <string name=\"analytics\">Analytics</string>\n    <string name=\"analytics_sub\">Allow collecting anonymous app usage statistics</string>\n    <string name=\"image_exif_warning\">Currently, %1$s format only allows reading EXIF metadata on android. Output image won\\'t have metadata at all, when saved.</string>\n    <string name=\"effort\">Effort</string>\n    <string name=\"effort_sub\">A value of %1$s means a fast compression, resulting in a relatively large file size. %2$s means a slower compression, resulting in a smaller file.</string>\n    <string name=\"wait\">Wait</string>\n    <string name=\"saving_almost_complete\">Saving almost complete. Cancelling now will require saving again.</string>\n    <string name=\"updates\">Updates</string>\n    <string name=\"allow_betas\">Allow betas</string>\n    <string name=\"allow_betas_sub\">Update checking will include beta app versions if enabled</string>\n    <string name=\"draw_arrows\">Draw Arrows</string>\n    <string name=\"draw_arrows_sub\">If enabled drawing path will be represented as pointing arrow</string>\n    <string name=\"brush_softness\">Brush softness</string>\n    <string name=\"crop_description\">Pictures will be center cropped to entered size. Canvas will be expanded with given background color if image is smaller than entered dimensions.</string>\n    <string name=\"donation\">Donation</string>\n    <string name=\"bitcoin\" translatable=\"false\">Bitcoin</string>\n    <string name=\"usdt\" translatable=\"false\">USDT</string>\n    <string name=\"image_stitching\">Image Stitching</string>\n    <string name=\"image_stitching_sub\">Combine the given images to get one big one</string>\n    <string name=\"pick_at_least_two_images\">Pick at least 2 images</string>\n    <string name=\"output_image_scale\">Output image scale</string>\n    <string name=\"image_orientation\">Image Orientation</string>\n    <string name=\"horizontal\">Horizontal</string>\n    <string name=\"vertical\">Vertical</string>\n    <string name=\"scale_small_images_to_large\">Scale small images to large</string>\n    <string name=\"scale_small_images_to_large_sub\">Small images will be scaled to the largest one in the sequence if enabled</string>\n    <string name=\"images_order\">Images order</string>\n    <string name=\"regular\">Regular</string>\n    <string name=\"blur_edges\">Blur edges</string>\n    <string name=\"blur_edges_sub\">Draws blurred edges under original image to fill spaces around it instead of single color if enabled</string>\n    <string name=\"pixelation\">Pixelation</string>\n    <string name=\"enhanced_pixelation\">Enhanced Pixelation</string>\n    <string name=\"stroke_pixelation\">Stroke Pixelation</string>\n    <string name=\"enhanced_diamond_pixelation\">Enhanced Diamond Pixelation</string>\n    <string name=\"diamond_pixelation\">Diamond Pixelation</string>\n    <string name=\"circle_pixelation\">Circle Pixelation</string>\n    <string name=\"enhanced_circle_pixelation\">Enhanced Circle Pixelation</string>\n    <string name=\"replace_color\">Replace Color</string>\n    <string name=\"tolerance\">Tolerance</string>\n    <string name=\"color_to_replace\">Color to Replace</string>\n    <string name=\"target_color\">Target Color</string>\n    <string name=\"color_to_remove\">Color to Remove</string>\n    <string name=\"remove_color\">Remove Color</string>\n    <string name=\"recode\">Recode</string>\n    <string name=\"pixel_size\">Pixel Size</string>\n    <string name=\"lock_draw_orientation\">Lock draw orientation</string>\n    <string name=\"lock_draw_orientation_sub\">If enabled in drawing mode, screen won\\'t rotate</string>\n    <string name=\"check_for_updates\">Check for updates</string>\n    <string name=\"palette_style\">Palette style</string>\n    <string name=\"tonal_spot\">Tonal Spot</string>\n    <string name=\"neutral\">Neutral</string>\n    <string name=\"vibrant\">Vibrant</string>\n    <string name=\"expressive\">Expressive</string>\n    <string name=\"rainbow\">Rainbow</string>\n    <string name=\"fruit_salad\">Fruit Salad</string>\n    <string name=\"fidelity\">Fidelity</string>\n    <string name=\"content\">Content</string>\n    <string name=\"tonal_spot_sub\">Default palette style, it allows to customize all four colors, others allow you to set only the key color</string>\n    <string name=\"neutral_sub\">A style that\\'s slightly more chromatic than monochrome</string>\n    <string name=\"vibrant_sub\">A loud theme, colorfulness is maximum for Primary palette, increased for others</string>\n    <string name=\"playful_scheme\">A playful theme - the source color\\'s hue does not appear in the theme</string>\n    <string name=\"monochrome_sub\">A monochrome theme, colors are purely black / white / gray</string>\n    <string name=\"content_sub\">A scheme that places the source color in Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">A scheme that is very similar to the content scheme</string>\n    <string name=\"foss_update_checker_warning\">This update checker will connect to GitHub in reason of checking if there is a new update available</string>\n    <string name=\"attention\">Attention</string>\n    <string name=\"fading_edges\">Fading Edges</string>\n    <string name=\"disabled\">Disabled</string>\n    <string name=\"both\">Both</string>\n    <string name=\"invert_colors\">Invert Colors</string>\n    <string name=\"invert_colors_sub\">Replaces theme colors to negative ones if enabled</string>\n    <string name=\"search_option\">Search</string>\n    <string name=\"search_option_sub\">Enables ability to search through all available tools on the main screen</string>\n    <string name=\"pdf_tools\">PDF Tools</string>\n    <string name=\"pdf_tools_sub\">Operate with PDF files: Preview, Convert to batch of images or create one from given pictures</string>\n    <string name=\"preview_pdf\">Preview PDF</string>\n    <string name=\"pdf_to_images\">PDF to Images</string>\n    <string name=\"images_to_pdf\">Images to PDF</string>\n    <string name=\"preview_pdf_sub\">Simple PDF preview</string>\n    <string name=\"pdf_to_images_sub\">Convert PDF to Images in given output format</string>\n    <string name=\"images_to_pdf_sub\">Pack given Images into output PDF file</string>\n    <string name=\"mask_filter\">Mask Filter</string>\n    <string name=\"mask_filter_sub\">Apply filter chains on given masked areas, each mask area can determine its own set of filters</string>\n    <string name=\"masks\">Masks</string>\n    <string name=\"add_mask\">Add Mask</string>\n    <string name=\"mask_indexed\">Mask %d</string>\n    <string name=\"mask_color\">Mask Color</string>\n    <string name=\"ton_space\" translatable=\"false\">TON Space</string>\n    <string name=\"ton\" translatable=\"false\">TON</string>\n    <string name=\"boosty\" translatable=\"false\">Boosty</string>\n    <string name=\"mask_preview\">Mask preview</string>\n    <string name=\"mask_preview_sub\">Drawn filter mask will be rendered to show you the approximate result</string>\n    <string name=\"inverse_fill_type\">Inverse Fill Type</string>\n    <string name=\"inverse_fill_type_sub\">If enabled all of the non masked areas will be filtered instead of default behavior</string>\n    <string name=\"delete_mask_warn\">You are about to delete selected filter mask. This operation cannot be undone</string>\n    <string name=\"delete_mask\">Delete mask</string>\n    <string name=\"full_filter\">Full Filter</string>\n    <string name=\"full_filter_sub\">Apply any filter chains to given images or single image</string>\n    <string name=\"start_position\">Start</string>\n    <string name=\"center_position\">Center</string>\n    <string name=\"end_position\">End</string>\n    <string name=\"simple_variants\">Simple Variants</string>\n    <string name=\"highlighter\">Highlighter</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Pen</string>\n    <string name=\"privacy_blur\">Privacy Blur</string>\n    <string name=\"highlighter_sub\">Draw semi-transparent sharpened highlighter paths</string>\n    <string name=\"neon_sub\">Add some glowing effect to your drawings</string>\n    <string name=\"pen_sub\">Default one, simplest - just the color</string>\n    <string name=\"privacy_blur_sub\">Blurs image under the drawn path to secure anything you want to hide</string>\n    <string name=\"pixelation_sub\">Similar to privacy blur, but pixelates instead of bluring</string>\n    <string name=\"containers_shadow\">Containers</string>\n    <string name=\"containers_shadow_sub\">Draw a shadow behind containers</string>\n    <string name=\"sliders_shadow\">Sliders</string>\n    <string name=\"switches_shadow\">Switches</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">Buttons</string>\n    <string name=\"sliders_shadow_sub\">Draw a shadow behind sliders</string>\n    <string name=\"switches_shadow_sub\">Draw a shadow behind switches</string>\n    <string name=\"fabs_shadow_sub\">Draw a shadow behind floating action buttons</string>\n    <string name=\"buttons_shadow_sub\">Draw a shadow behind buttons</string>\n    <string name=\"app_bars_shadow\">App bars</string>\n    <string name=\"app_bars_shadow_sub\">Draw a shadow behind app bars</string>\n    <string name=\"value_in_range\">Value in range %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Auto Rotate</string>\n    <string name=\"auto_rotate_limits_sub\">Allows limit box to be adopted for image orientation</string>\n    <string name=\"draw_path_mode\">Draw Path Mode</string>\n    <string name=\"double_line_arrow\">Double Line Arrow</string>\n    <string name=\"free_drawing\">Free Drawing</string>\n    <string name=\"double_arrow\">Double Arrow</string>\n    <string name=\"line_arrow\">Line Arrow</string>\n    <string name=\"arrow\">Arrow</string>\n    <string name=\"line\">Line</string>\n    <string name=\"free_drawing_sub\">Draws path as input value</string>\n    <string name=\"line_sub\">Draws path from start point to end point as a line</string>\n    <string name=\"line_arrow_sub\">Draws pointing arrow from start point to end point as a line</string>\n    <string name=\"arrow_sub\">Draws a pointing arrow from a given path</string>\n    <string name=\"double_line_arrow_sub\">Draws double pointing arrow from start point to end point as a line</string>\n    <string name=\"double_arrow_sub\">Draws double pointing arrow from a given path</string>\n    <string name=\"outlined_oval\">Outlined Oval</string>\n    <string name=\"outlined_rect\">Outlined Rect</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Draws rect from start point to end point</string>\n    <string name=\"oval_sub\">Draws oval from start point to end point</string>\n    <string name=\"outlined_oval_sub\">Draws outlined oval from start point to end point</string>\n    <string name=\"outlined_rect_sub\">Draws outlined rect from start point to end point</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Draws closed filled path by given path</string>\n    <string name=\"free\">Free</string>\n    <string name=\"horizontal_grid\">Horizontal Grid</string>\n    <string name=\"vertical_grid\">Vertical Grid</string>\n    <string name=\"stitch_mode\">Stitch Mode</string>\n    <string name=\"rows_count\">Rows Count</string>\n    <string name=\"columns_count\">Columns Count</string>\n    <string name=\"no_such_directory\">No \\\"%1$s\\\" directory found, we switched it to default one, please save the file again</string>\n    <string name=\"clipboard\">Clipboard</string>\n    <string name=\"auto_pin\">Auto pin</string>\n    <string name=\"auto_pin_sub\">Automatically adds saved image to clipboard if enabled</string>\n    <string name=\"vibration\">Vibration</string>\n    <string name=\"vibration_strength\">Vibration Strength</string>\n    <string name=\"overwrite_file_requirements\">In order to overwrite files you need to use \\\"Explorer\\\" image source, try repick images, we\\'ve changed image source to the needed one</string>\n    <string name=\"overwrite_files\">Overwrite Files</string>\n    <string name=\"overwrite_files_sub\">Original file will be replaced with new one instead of saving in selected folder, this option need to image source be \\\"Explorer\\\" or GetContent, when toggling this, it will be set automatically</string>\n    <string name=\"empty\">Empty</string>\n    <string name=\"suffix\">Suffix</string>\n    <string name=\"scale_mode\">Scale mode</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Nearest</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Basic</string>\n    <string name=\"default_value\">Default Value</string>\n    <string name=\"bilinear_sub\">Linear (or bilinear, in two dimensions) interpolation is typically good for changing the size of an image, but causes some undesirable softening of details and can still be somewhat jagged</string>\n    <string name=\"bicubic_sub\">Better scaling methods include Lanczos resampling and Mitchell-Netravali filters</string>\n    <string name=\"nearest_sub\">One of the simpler ways of increasing the size, replacing every pixel with a number of pixels of the same color</string>\n    <string name=\"basic_sub\">Simplest android scaling mode that used in almost all apps</string>\n    <string name=\"catmull_sub\">Method for smoothly interpolating and resampling a set of control points, commonly used in computer graphics to create smooth curves</string>\n    <string name=\"hann_sub\">Windowing function often applied in signal processing to minimize spectral leakage and improve the accuracy of frequency analysis by tapering the edges of a signal</string>\n    <string name=\"hermite_sub\">Mathematical interpolation technique that uses the values and derivatives at the endpoints of a curve segment to generate a smooth and continuous curve</string>\n    <string name=\"lanczos_sub\">Resampling method that maintains high-quality interpolation by applying a weighted sinc function to the pixel values</string>\n    <string name=\"mitchell_sub\">Resampling method that use a convolution filter with adjustable parameters to achieve a balance between sharpness and anti-aliasing in the scaled image</string>\n    <string name=\"spline_sub\">Uses piecewise-defined polynomial functions to smoothly interpolate and approximate a curve or surface, providing flexible and continuous shape representation</string>\n    <string name=\"only_clip\">Only Clip</string>\n    <string name=\"only_clip_sub\">Saving to storage will not be performed, and image will be tried to put into the clipboard only</string>\n    <string name=\"restore_background_sub\">Brush will restore the background instead of erasing</string>\n    <string name=\"recognize_text\">OCR (recognize text)</string>\n    <string name=\"recognize_text_sub\">Recognize text from given image, 120+ languages supported</string>\n    <string name=\"picture_has_no_text\">Picture has no text, or app didn\\'t find it</string>\n    <string name=\"accuracy\">\"Accuracy: %1$s\"</string>\n    <string name=\"recognition_type\">Recognition Type</string>\n    <string name=\"fast\">Fast</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"best\">Best</string>\n    <string name=\"no_data\">No Data</string>\n    <string name=\"download_description\">For proper functioning of Tesseract OCR additional training data (%1$s) needs to be downloaded to your device.\\nDo you want to download %2$s data?</string>\n    <string name=\"download\">Download</string>\n    <string name=\"no_connection\">No connection, check it and try again in order to download train models</string>\n    <string name=\"downloaded_languages\">Downloaded Languages</string>\n    <string name=\"available_languages\">Available Languages</string>\n    <string name=\"segmentation_mode\">Segmentation Mode</string>\n    <string name=\"use_pixel_switch\">Use Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Uses a Google Pixel-like switch</string>\n    <string name=\"saved_to_original\">Overwritten file with name %1$s at original destination</string>\n    <string name=\"magnifier\">Magnifier</string>\n    <string name=\"magnifier_sub\">Enables magnifier at the top of finger in drawing modes for better accessibility</string>\n    <string name=\"force_exif_widget_initial_value\">Force initial value</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Forces exif widget to be checked initially</string>\n    <string name=\"exif\" translatable=\"false\">EXIF</string>\n    <string name=\"allow_multiple_languages\">Allow Multiple Languages</string>\n    <string name=\"slide\">Slide</string>\n    <string name=\"side_by_side\">Side By Side</string>\n    <string name=\"toggle_tap\">Toggle Tap</string>\n    <string name=\"transparency\">Transparency</string>\n    <string name=\"rate_app\">Rate App</string>\n    <string name=\"rate\">Rate</string>\n    <string name=\"rate_app_sub\">This app is completely free, if you want it to become bigger, please star the project on Github 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Orientation &amp; Script Detection only</string>\n    <string name=\"segmentation_mode_auto_osd\">Auto Orientation &amp; Script Detection</string>\n    <string name=\"segmentation_mode_auto_only\">Auto only</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Single Column</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Single block vertical text</string>\n    <string name=\"segmentation_mode_single_block\">Single block</string>\n    <string name=\"segmentation_mode_single_line\">Single line</string>\n    <string name=\"segmentation_mode_single_word\">Single word</string>\n    <string name=\"segmentation_mode_circle_word\">Circle word</string>\n    <string name=\"segmentation_mode_single_char\">Single char</string>\n    <string name=\"segmentation_mode_sparse_text\">Sparse text</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Sparse text Orientation &amp; Script Detection</string>\n    <string name=\"segmentation_mode_raw_line\">Raw line</string>\n    <string name=\"delete_language_sub\">Do you want to delete language \\\"%1$s\\\" OCR training data for all recognition types, or only for selected one (%2$s)?</string>\n    <string name=\"current\">Current</string>\n    <string name=\"all\">All</string>\n    <string name=\"gradient_maker\">Gradient Maker</string>\n    <string name=\"gradient_maker_sub\">Create gradient of given output size with customized colors and appearance type</string>\n    <string name=\"gradient_type_linear\">Linear</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Sweep</string>\n    <string name=\"gradient_type\">Gradient Type</string>\n    <string name=\"center_x\">Center X</string>\n    <string name=\"center_y\">Center Y</string>\n    <string name=\"tile_mode\">Tile Mode</string>\n    <string name=\"tile_mode_repeated\">Repeated</string>\n    <string name=\"tile_mode_mirror\">Mirror</string>\n    <string name=\"tile_mode_clamp\">Clamp</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"color_stops\">Color Stops</string>\n    <string name=\"add_color\">Add Color</string>\n    <string name=\"properties\">Properties</string>\n    <string name=\"brightness_enforcement\">Brightness Enforcement</string>\n    <string name=\"screen\">Screen</string>\n    <string name=\"gradient_maker_type_image\">Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_sub\">Compose any gradient of top of given images</string>\n    <string name=\"transformations\">Transformations</string>\n    <string name=\"camera\">Camera</string>\n    <string name=\"camera_sub\">Take a picture with a camera. Note that it is possible to get only one image from this image source</string>\n    <string name=\"watermarking\">Watermarking</string>\n    <string name=\"watermarking_sub\">Cover pictures with customizable text/image watermarks</string>\n    <string name=\"repeat_watermark\">Repeat watermark</string>\n    <string name=\"repeat_watermark_sub\">Repeats watermark over image instead of single at given position</string>\n    <string name=\"offset_x\">Offset X</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermark_type\">Watermark Type</string>\n    <string name=\"watermarking_image_sub\">This image will be used as pattern for watermarking</string>\n    <string name=\"text_color\">Text Color</string>\n    <string name=\"overlay_mode\">Overlay Mode</string>\n    <string name=\"gif_tools\">GIF Tools</string>\n    <string name=\"gif_tools_sub\">Convert images to GIF picture or extract frames from given GIF image</string>\n    <string name=\"gif_type_to_image\">GIF to images</string>\n    <string name=\"gif_type_to_image_sub\">Convert GIF file to batch of pictures</string>\n    <string name=\"gif_type_to_gif_sub\">Convert batch of images to GIF file</string>\n    <string name=\"gif_type_to_gif\">Images to GIF</string>\n    <string name=\"select_gif_image_to_start\">Pick GIF image to start</string>\n    <string name=\"use_size_of_first_frame\">Use size of First frame</string>\n    <string name=\"use_size_of_first_frame_sub\">Replace specified size with first frame dimensions</string>\n    <string name=\"repeat_count\">Repeat Count</string>\n    <string name=\"frame_delay\">Frame Delay</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Use Lasso</string>\n    <string name=\"use_lasso_sub\">Uses Lasso like in drawing mode to perform erasing</string>\n    <string name=\"original_image_preview_alpha\">Original Image Preview Alpha</string>\n    <string name=\"confetti\">Confetti</string>\n    <string name=\"confetti_sub\">Confetti will be shown on saving, sharing and other primary actions</string>\n    <string name=\"secure_mode\">Secure Mode</string>\n    <string name=\"secure_mode_sub\">Hides app content in recent apps. It cannot be captured or recorded.</string>\n    <string name=\"exit\">Exit</string>\n    <string name=\"preview_closing\">If you leave preview now, you\\'ll need to add the images again</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizier</string>\n    <string name=\"gray_scale\">Gray Scale</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Two Row Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">False Floyd Steinberg Dithering</string>\n    <string name=\"left_to_right_dithering\">Left To Right Dithering</string>\n    <string name=\"random_dithering\">Random Dithering</string>\n    <string name=\"simple_threshold_dithering\">Simple Threshold Dithering</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Spatial Sigma</string>\n    <string name=\"median_blur\">Median Blur</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Utilizes piecewise-defined bicubic polynomial functions to smoothly interpolate and approximate a curve or surface, flexible and continuous shape representation</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"glitch\">Glitch</string>\n    <string name=\"amount\">Amount</string>\n    <string name=\"seed\">Seed</string>\n    <string name=\"anaglyph\">Anaglyph</string>\n    <string name=\"noise\">Noise</string>\n    <string name=\"pixel_sort\">Pixel Sort</string>\n    <string name=\"shuffle\">Shuffle</string>\n    <string name=\"enhanced_glitch\">Enhanced Glitch</string>\n    <string name=\"channel_shift_x\">Channel Shift X</string>\n    <string name=\"channel_shift_y\">Channel Shift Y</string>\n    <string name=\"corruption_size\">Corruption Size</string>\n    <string name=\"corruption_shift_x\">Corruption Shift X</string>\n    <string name=\"corruption_shift_y\">Corruption Shift Y</string>\n    <string name=\"tent_blur\">Tent Blur</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">Side</string>\n    <string name=\"top\">Top</string>\n    <string name=\"bottom\">Bottom</string>\n    <string name=\"strength\">Strength</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anisotropic Diffusion</string>\n    <string name=\"diffusion\">Diffusion</string>\n    <string name=\"conduction\">Conduction</string>\n    <string name=\"horizontal_wind_stagger\">Horizontal Wind Stagger</string>\n    <string name=\"fast_bilaterial_blur\">Fast Bilaterial Blur</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">Logarithmic Tone Mapping</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"crystallize\">Crystallize</string>\n    <string name=\"stroke_color\">Stroke Color</string>\n    <string name=\"fractal_glass\">Fractal Glass</string>\n    <string name=\"amplitude\">Amplitude</string>\n    <string name=\"marble\">Marble</string>\n    <string name=\"turbulence\">Turbulence</string>\n    <string name=\"oil\">Oil</string>\n    <string name=\"water_effect\">Water Effect</string>\n    <string name=\"just_size\">Size</string>\n    <string name=\"frequency_x\">Frequency X</string>\n    <string name=\"frequency_y\">Frequency Y</string>\n    <string name=\"amplitude_x\">Amplitude X</string>\n    <string name=\"amplitude_y\">Amplitude Y</string>\n    <string name=\"perlin_distortion\">Perlin Distortion</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Tone mapping</string>\n    <string name=\"speed\">Speed</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Color Matrix 4x4</string>\n    <string name=\"color_matrix_3x3\">Color Matrix 3x3</string>\n    <string name=\"simple_effects\">Simple Effects</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomaly</string>\n    <string name=\"deutaromaly\">Deuteranomaly</string>\n    <string name=\"protonomaly\">Protanomaly</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Night Vision</string>\n    <string name=\"warm\">Warm</string>\n    <string name=\"cool\">Cool</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Achromatomaly</string>\n    <string name=\"achromatopsia\">Achromatopsia</string>\n    <string name=\"grain\">Grain</string>\n    <string name=\"unsharp\">Unsharp</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Orange Haze</string>\n    <string name=\"pink_dream\">Pink Dream</string>\n    <string name=\"golden_hour\">Golden Hour</string>\n    <string name=\"hot_summer\">Hot Summer</string>\n    <string name=\"purple_mist\">Purple Mist</string>\n    <string name=\"sunrise\">Sunrise</string>\n    <string name=\"colorful_swirl\">Colorful Swirl</string>\n    <string name=\"soft_spring_light\">Soft Spring Light</string>\n    <string name=\"autumn_tones\">Autumn Tones</string>\n    <string name=\"lavender_dream\">Lavender Dream</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Lemonade Light</string>\n    <string name=\"spectral_fire\">Spectral Fire</string>\n    <string name=\"night_magic\">Night Magic</string>\n    <string name=\"fantasy_landscape\">Fantasy Landscape</string>\n    <string name=\"color_explosion\">Color Explosion</string>\n    <string name=\"electric_gradient\">Electric Gradient</string>\n    <string name=\"caramel_darkness\">Caramel Darkness</string>\n    <string name=\"futuristic_gradient\">Futuristic Gradient</string>\n    <string name=\"green_sun\">Green Sun</string>\n    <string name=\"rainbow_world\">Rainbow World</string>\n    <string name=\"deep_purple\">Deep Purple</string>\n    <string name=\"space_portal\">Space Portal</string>\n    <string name=\"red_swirl\">Red Swirl</string>\n    <string name=\"digital_code\">Digital Code</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">The app bar emoji will change randomly</string>\n    <string name=\"random_emojis\">Random Emojis</string>\n    <string name=\"random_emojis_error\">You cannot use random emojis while emojis are disabled</string>\n    <string name=\"emoji_selection_error\">You cannot select an emoji while random emojis are enabled</string>\n    <string name=\"old_tv\">Old Tv</string>\n    <string name=\"shuffle_blur\">Shuffle Blur</string>\n    <string name=\"favorite\">Favorite</string>\n    <string name=\"no_favorite_filters\">No favorite filters added yet</string>\n    <string name=\"image_format\">Image Format</string>\n    <string name=\"icon_shape_sub\">Adds a container with the selected shape under the icons</string>\n    <string name=\"icon_shape\">Icon Shape</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Cutoff</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Transition</string>\n    <string name=\"peak\">Peak</string>\n    <string name=\"color_anomaly\">Color Anomaly</string>\n    <string name=\"images_overwritten\">Images overwritten at original destination</string>\n    <string name=\"cannot_change_image_format\">Cannot change image format while overwrite files option enabled</string>\n    <string name=\"emoji_as_color_scheme\">Emoji as Color Scheme</string>\n    <string name=\"emoji_as_color_scheme_sub\">Uses emoji primary color as app color scheme instead of manually defined one</string>\n    <string name=\"material_you\" translatable=\"false\">Material You</string>\n    <string name=\"material_you_sub\">Creates Material You palette from image</string>\n    <string name=\"dark_colors\">Dark Colors</string>\n    <string name=\"dark_colors_sub\">Uses night mode color scheme instead of light variant</string>\n    <string name=\"copy_as_compose_code\">Copy as Jetpack Compose code</string>\n    <string name=\"ring_blur\">Ring Blur</string>\n    <string name=\"cross_blur\">Cross Blur</string>\n    <string name=\"circle_blur\">Circle Blur</string>\n    <string name=\"star_blur\">Star Blur</string>\n    <string name=\"linear_tilt_shift\">Linear Tilt-Shift</string>\n    <string name=\"tags_to_remove\">Tags To Remove</string>\n    <string name=\"apng_tools\">APNG Tools</string>\n    <string name=\"apng_tools_sub\">Convert images to APNG picture or extract frames from given APNG image</string>\n    <string name=\"apng_type_to_image\">APNG to images</string>\n    <string name=\"apng_type_to_image_sub\">Convert APNG file to batch of pictures</string>\n    <string name=\"apng_type_to_apng_sub\">Convert batch of images to APNG file</string>\n    <string name=\"apng_type_to_apng\">Images to APNG</string>\n    <string name=\"select_apng_image_to_start\">Pick APNG image to start</string>\n    <string name=\"motion_blur\">Motion Blur</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Create Zip file from given files or images</string>\n    <string name=\"drag_handle_width\">Drag Handle Width</string>\n    <string name=\"confetti_type\">Confetti Type</string>\n    <string name=\"festive\">Festive</string>\n    <string name=\"explode\">Explode</string>\n    <string name=\"rain\">Rain</string>\n    <string name=\"corners\">Corners</string>\n    <string name=\"jxl_tools\">JXL Tools</string>\n    <string name=\"jxl_tools_sub\">Perform JXL ~ JPEG transcoding with no quality loss, or convert GIF/APNG to JXL animation</string>\n    <string name=\"jxl_type_to_jpeg\">JXL to JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Perform lossless transcoding from JXL to JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Perform lossless transcoding from  JPEG to JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG to JXL</string>\n    <string name=\"select_jxl_image_to_start\">Pick JXL image to start</string>\n    <string name=\"fast_gaussian_blur_2d\">Fast Gaussian Blur 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Fast Gaussian Blur 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Fast Gaussian Blur 4D</string>\n    <string name=\"auto_paste\">Auto Paste</string>\n    <string name=\"auto_paste_sub\">Allows app to auto paste clipboard data, so it will appear on main screen and you will be able to process it</string>\n    <string name=\"harmonization_color\">Harmonization Color</string>\n    <string name=\"harmonization_level\">Harmonization Level</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Resampling method that maintains high-quality interpolation by applying a Bessel (jinc) function to the pixel values</string>\n    <string name=\"gif_type_to_jxl\">GIF to JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Convert GIF images to JXL animated pictures</string>\n    <string name=\"apng_type_to_jxl\">APNG to JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Convert APNG images to JXL animated pictures</string>\n    <string name=\"jxl_type_to_images\">JXL to Images</string>\n    <string name=\"jxl_type_to_images_sub\">Convert JXL animation to batch of pictures</string>\n    <string name=\"jxl_type_to_jxl\">Images to JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Convert batch of pictures to JXL animation</string>\n    <string name=\"behavior\">Behavior</string>\n    <string name=\"skip_file_picking\">Skip File Picking</string>\n    <string name=\"skip_file_picking_sub\">File picker will be shown immediately if this possible on chosen screen</string>\n    <string name=\"generate_previews\">Generate Previews</string>\n    <string name=\"generate_previews_sub\">Enables preview generation, this may help to avoid crashes on some devices, this also disables some editing functionality within single edit option</string>\n    <string name=\"lossy_compression\">Lossy Compression</string>\n    <string name=\"lossy_compression_sub\">Uses lossy compression to reduce file size instead of lossless</string>\n    <string name=\"compression_type\">Compression Type</string>\n    <string name=\"speed_sub\">Controls resulting image decoding speed, this should help open resulting image faster, value of %1$s means slowest decoding, whereas %2$s - fastest, this setting may increase output image size</string>\n    <string name=\"sorting\">Sorting</string>\n    <string name=\"sort_by_date\">Date</string>\n    <string name=\"sort_by_date_reversed\">Date (Reversed)</string>\n    <string name=\"sort_by_name\">Name</string>\n    <string name=\"sort_by_name_reversed\">Name (Reversed)</string>\n    <string name=\"channels_configuration\">Channels Configuration</string>\n    <string name=\"header_today\">Today</string>\n    <string name=\"header_yesterday\">Yesterday</string>\n    <string name=\"embedded_picker\">Embedded Picker</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox\\'s image picker</string>\n    <string name=\"no_permissions\">No permissions</string>\n    <string name=\"request\">Request</string>\n    <string name=\"pick_multiple_media\">Pick Multiple Media</string>\n    <string name=\"pick_single_media\">Pick Single Media</string>\n    <string name=\"pick\">Pick</string>\n    <string name=\"try_again\">Try again</string>\n    <string name=\"show_settings_in_landscape\">Show Settings In Landscape</string>\n    <string name=\"show_settings_in_landscape_sub\">If this disabled then in landscape mode settings will be opened on the button in top app bar as always, instead of permanent visible option</string>\n    <string name=\"fullscreen_settings\">Fullscreen Settings</string>\n    <string name=\"fullscreen_settings_sub\">Enable it and settings page will be always opened as fullscreen instead of slideable drawer sheet</string>\n    <string name=\"switch_type\">Switch Type</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"compose_switch_sub\">A Jetpack Compose Material You switch</string>\n    <string name=\"material_you_switch_sub\">A Material You switch</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Resize Anchor</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">A switch based on the \\\"Fluent\\\" design system</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">A switch based on the \\\"Cupertino\\\" design system</string>\n    <string name=\"images_to_svg\">Images to SVG</string>\n    <string name=\"images_to_svg_sub\">Trace given images to SVG images</string>\n    <string name=\"use_sampled_palette\">Use Sampled Palette</string>\n    <string name=\"use_sampled_palette_sub\">Quantization palette will be sampled if this option enabled</string>\n    <string name=\"path_omit\">Path Omit</string>\n    <string name=\"svg_warning\">Usage of this tool for tracing large images without downscaling are not recommended, it can cause crash and increase processing time</string>\n    <string name=\"downscale_image\">Downscale image</string>\n    <string name=\"downscale_image_sub\">Image will be downscaled to lower dimensions before processing, this helps the tool to work faster and safer</string>\n    <string name=\"min_color_ratio\">Minimum Color Ratio</string>\n    <string name=\"lines_threshold\">Lines Threshold</string>\n    <string name=\"quadratic_threshold\">Quadratic Threshold</string>\n    <string name=\"coordinates_rounding_tolerance\">Coordinates Rounding Tolerance</string>\n    <string name=\"path_scale\">Path Scale</string>\n    <string name=\"reset_properties\">Reset properties</string>\n    <string name=\"reset_properties_sub\">All properties will be set to default values, notice that this action cannot be undone</string>\n    <string name=\"detailed\">Detailed</string>\n    <string name=\"default_line_width\">Default Line Width</string>\n    <string name=\"engine_mode\">Engine Mode</string>\n    <string name=\"legacy\">Legacy</string>\n    <string name=\"lstm_network\">LSTM network</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp; LSTM</string>\n    <string name=\"convert\">Convert</string>\n    <string name=\"convert_sub\">Convert image batches to given format</string>\n    <string name=\"add_new_folder\">Add New Folder</string>\n    <string name=\"tag_bits_per_sample\">Bits Per Sample</string>\n    <string name=\"tag_compression\">Compression</string>\n    <string name=\"tag_photometric_interpretation\">Photometric Interpretation</string>\n    <string name=\"tag_samples_per_pixel\">Samples Per Pixel</string>\n    <string name=\"tag_planar_configuration\">Planar Configuration</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sub Sampling</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Positioning</string>\n    <string name=\"tag_x_resolution\">X Resolution</string>\n    <string name=\"tag_y_resolution\">Y Resolution</string>\n    <string name=\"tag_resolution_unit\">Resolution Unit</string>\n    <string name=\"tag_strip_offsets\">Strip Offsets</string>\n    <string name=\"tag_rows_per_strip\">Rows Per Strip</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG Interchange Format</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG Interchange Format Length</string>\n    <string name=\"tag_transfer_function\">Transfer Function</string>\n    <string name=\"tag_white_point\">White Point</string>\n    <string name=\"tag_primary_chromaticities\">Primary Chromaticities</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Coefficients</string>\n    <string name=\"tag_reference_black_white\">Reference Black White</string>\n    <string name=\"tag_datetime\">Date Time</string>\n    <string name=\"tag_image_description\">Image Description</string>\n    <string name=\"tag_make\">Make</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_artist\">Artist</string>\n    <string name=\"tag_copyright\">Copyright</string>\n    <string name=\"tag_exif_version\">Exif Version</string>\n    <string name=\"tag_flashpix_version\">Flashpix Version</string>\n    <string name=\"tag_color_space\">Color Space</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y Dimension</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Compressed Bits Per Pixel</string>\n    <string name=\"tag_maker_note\">Maker Note</string>\n    <string name=\"tag_user_comment\">User Comment</string>\n    <string name=\"tag_related_sound_file\">Related Sound File</string>\n    <string name=\"tag_datetime_original\">Date Time Original</string>\n    <string name=\"tag_datetime_digitized\">Date Time Digitized</string>\n    <string name=\"tag_offset_time\">Offset Time</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Offset Time Digitized</string>\n    <string name=\"tag_subsec_time\">Sub Sec Time</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Time Original</string>\n    <string name=\"tag_subsec_time_digitized\">Sub Sec Time Digitized</string>\n    <string name=\"tag_exposure_time\">Exposure Time</string>\n    <string name=\"tag_f_number\">F Number</string>\n    <string name=\"tag_exposure_program\">Exposure Program</string>\n    <string name=\"tag_spectral_sensitivity\">Spectral Sensitivity</string>\n    <string name=\"tag_photographic_sensitivity\">Photographic Sensitivity</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Sensitivity Type</string>\n    <string name=\"tag_standard_output_sensitivity\">Standard Output Sensitivity</string>\n    <string name=\"tag_recommended_exposure_index\">Recommended Exposure Index</string>\n    <string name=\"tag_iso_speed\">ISO Speed</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Speed Latitude yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Speed Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Shutter Speed Value</string>\n    <string name=\"tag_aperture_value\">Aperture Value</string>\n    <string name=\"tag_brightness_value\">Brightness Value</string>\n    <string name=\"tag_exposure_bias_value\">Exposure Bias Value</string>\n    <string name=\"tag_max_aperture_value\">Max Aperture Value</string>\n    <string name=\"tag_subject_distance\">Subject Distance</string>\n    <string name=\"tag_metering_mode\">Metering Mode</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Subject Area</string>\n    <string name=\"tag_focal_length\">Focal Length</string>\n    <string name=\"tag_flash_energy\">Flash Energy</string>\n    <string name=\"tag_spatial_frequency_response\">Spatial Frequency Response</string>\n    <string name=\"tag_focal_plane_x_resolution\">Focal Plane X Resolution</string>\n    <string name=\"tag_focal_plane_y_resolution\">Focal Plane Y Resolution</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Focal Plane Resolution Unit</string>\n    <string name=\"tag_subject_location\">Subject Location</string>\n    <string name=\"tag_exposure_index\">Exposure Index</string>\n    <string name=\"tag_sensing_method\">Sensing Method</string>\n    <string name=\"tag_file_source\">File Source</string>\n    <string name=\"tag_cfa_pattern\">CFA Pattern</string>\n    <string name=\"tag_custom_rendered\">Custom Rendered</string>\n    <string name=\"tag_exposure_mode\">Exposure Mode</string>\n    <string name=\"tag_white_balance\">White Balance</string>\n    <string name=\"tag_digital_zoom_ratio\">Digital Zoom Ratio</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Focal Length In35mm Film</string>\n    <string name=\"tag_scene_capture_type\">Scene Capture Type</string>\n    <string name=\"tag_gain_control\">Gain Control</string>\n    <string name=\"tag_contrast\">Contrast</string>\n    <string name=\"tag_saturation\">Saturation</string>\n    <string name=\"tag_sharpness\">Sharpness</string>\n    <string name=\"tag_device_setting_description\">Device Setting Description</string>\n    <string name=\"tag_subject_distance_range\">Subject Distance Range</string>\n    <string name=\"tag_image_unique_id\">Image Unique ID</string>\n    <string name=\"tag_camera_owner_name\">Camera Owner Name</string>\n    <string name=\"tag_body_serial_number\">Body Serial Number</string>\n    <string name=\"tag_lens_specification\">Lens Specification</string>\n    <string name=\"tag_lens_make\">Lens Make</string>\n    <string name=\"tag_lens_model\">Lens Model</string>\n    <string name=\"tag_lens_serial_number\">Lens Serial Number</string>\n    <string name=\"tag_gps_version_id\">GPS Version ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitude</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Longitude Ref</string>\n    <string name=\"tag_gps_longitude\">GPS Longitude</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Altitude Ref</string>\n    <string name=\"tag_gps_altitude\">GPS Altitude</string>\n    <string name=\"tag_gps_timestamp\">GPS Time Stamp</string>\n    <string name=\"tag_gps_satellites\">GPS Satellites</string>\n    <string name=\"tag_gps_status\">GPS Status</string>\n    <string name=\"tag_gps_measure_mode\">GPS Measure Mode</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS Speed Ref</string>\n    <string name=\"tag_gps_speed\">GPS Speed</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS Track</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img Direction Ref</string>\n    <string name=\"tag_gps_img_direction\">GPS Img Direction</string>\n    <string name=\"tag_gps_map_datum\">GPS Map Datum</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitude Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Longitude</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS Dest Distance</string>\n    <string name=\"tag_gps_processing_method\">GPS Processing Method</string>\n    <string name=\"tag_gps_area_information\">GPS Area Information</string>\n    <string name=\"tag_gps_datestamp\">GPS Date Stamp</string>\n    <string name=\"tag_gps_differential\">GPS Differential</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H Positioning Error</string>\n    <string name=\"tag_interoperability_index\">Interoperability Index</string>\n    <string name=\"tag_dng_version\">DNG Version</string>\n    <string name=\"tag_default_crop_size\">Default Crop Size</string>\n    <string name=\"tag_orf_preview_image_start\">Preview Image Start</string>\n    <string name=\"tag_orf_preview_image_length\">Preview Image Length</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect Frame</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Sensor Bottom Border</string>\n    <string name=\"tag_rw2_sensor_left_border\">Sensor Left Border</string>\n    <string name=\"tag_rw2_sensor_right_border\">Sensor Right Border</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sensor Top Border</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Draw Text on path with given font and color</string>\n    <string name=\"font_size\">Font Size</string>\n    <string name=\"watermark_size\">Watermark Size</string>\n    <string name=\"repeat_text\">Repeat Text</string>\n    <string name=\"repeat_text_sub\">Current text will be repeated until the path end instead of one time drawing</string>\n    <string name=\"dash_size\">Dash Size</string>\n    <string name=\"draw_mode_image_sub\">Use selected image to draw it along given path</string>\n    <string name=\"draw_image_sub\">This image will be used as repetitive entry of drawn path</string>\n    <string name=\"outlined_triangle_sub\">Draws outlined triangle from start point to end point</string>\n    <string name=\"triangle_sub\">Draws outlined triangle from start point to end point</string>\n    <string name=\"outlined_triangle\">Outlined Triangle</string>\n    <string name=\"triangle\">Triangle</string>\n    <string name=\"polygon_sub\">Draws polygon from start point to end point</string>\n    <string name=\"polygon\">Polygon</string>\n    <string name=\"outlined_polygon\">Outlined Polygon</string>\n    <string name=\"outlined_polygon_sub\">Draws outlined polygon from start point to end point</string>\n    <string name=\"vertices\">Vertices</string>\n    <string name=\"draw_regular_polygon\">Draw Regular Polygon</string>\n    <string name=\"draw_regular_polygon_sub\">Draw polygon which will be regular instead of free form</string>\n    <string name=\"star_sub\">Draws star from start point to end point</string>\n    <string name=\"star\">Star</string>\n    <string name=\"outlined_star\">Outlined Star</string>\n    <string name=\"outlined_star_sub\">Draws outlined star from start point to end point</string>\n    <string name=\"inner_radius_ratio\">Inner Radius Ratio</string>\n    <string name=\"draw_regular_star\">Draw Regular Star</string>\n    <string name=\"draw_regular_star_sub\">Draw star which will be regular instead of free form</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Enables antialiasing to prevent sharp edges</string>\n    <string name=\"open_edit_instead_of_preview\">Open Edit Instead Of Preview</string>\n    <string name=\"open_edit_instead_of_preview_sub\">When you select image to open (preview) in ImageToolbox, edit selection sheet will be opened instead of previewing</string>\n    <string name=\"document_scanner\">Document Scanner</string>\n    <string name=\"document_scanner_sub\">Scan documents and create PDF or separate images from them</string>\n    <string name=\"click_to_start_scanning\">Click to start scanning</string>\n    <string name=\"start_scanning\">Start Scanning</string>\n    <string name=\"save_as_pdf\">Save As Pdf</string>\n    <string name=\"share_as_pdf\">Share as PDF</string>\n    <string name=\"options_below_is_for_images\">Options below is for saving images, not PDF</string>\n    <string name=\"equalize_histogram_hsv\">Equalize Histogram HSV</string>\n    <string name=\"equalize_histogram\">Equalize Histogram</string>\n    <string name=\"enter_percentage\">Enter Percentage</string>\n    <string name=\"allow_enter_by_text_field\">Allow enter by Text Field</string>\n    <string name=\"allow_enter_by_text_field_sub\">Enables Text Field behind presets selection, to enter them on the fly</string>\n    <string name=\"scale_color_space\">Scale Color Space</string>\n    <string name=\"linear\">Linear</string>\n    <string name=\"equalize_histogram_pixelation\">Equalize Histogram Pixelation</string>\n    <string name=\"grid_size_x\">Grid Size X</string>\n    <string name=\"grid_size_y\">Grid Size Y</string>\n    <string name=\"equalize_histogram_adaptive\">Equalize Histogram Adaptive</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Equalize Histogram Adaptive LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalize Histogram Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Crop to Content</string>\n    <string name=\"frame_color\">Frame Color</string>\n    <string name=\"color_to_ignore\">Color To Ignore</string>\n    <string name=\"template\">Template</string>\n    <string name=\"no_template_filters\">No template filters added</string>\n    <string name=\"create_new\">Create New</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">The scanned QR code is not a valid filter template</string>\n    <string name=\"scan_qr_code\">Scan QR code</string>\n    <string name=\"opened_file_have_no_filter_template\">Selected file have no filter template data</string>\n    <string name=\"create_template\">Create Template</string>\n    <string name=\"template_name\">Template Name</string>\n    <string name=\"select_template_preview\">This image will be used to preview this filter template</string>\n    <string name=\"template_filter\">Template Filter</string>\n    <string name=\"as_qr_code\">As QR code image</string>\n    <string name=\"as_file\">As file</string>\n    <string name=\"save_as_file\">Save as file</string>\n    <string name=\"save_markup_project\">Save project</string>\n    <string name=\"save_markup_project_sub\">Store layers, background and edit history in an editable project file</string>\n    <string name=\"save_as_qr_code_image\">Save as QR code image</string>\n    <string name=\"delete_template\">Delete Template</string>\n    <string name=\"delete_template_warn\">You are about to delete selected template filter. This operation cannot be undone</string>\n    <string name=\"added_filter_template\">Added filter template with name \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Filter Preview</string>\n    <string name=\"qr_code\">QR &amp; Barcode</string>\n    <string name=\"qr_code_sub\">Scan QR code and get its content or paste your string to generate new one</string>\n    <string name=\"code_content\">Code Content</string>\n    <string name=\"scan_qr_code_to_replace_content\">Scan any barcode to replace content in field, or type something to generate new barcode with selected type</string>\n    <string name=\"qr_description\">QR Description</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Grant camera permission in settings to scan QR code</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Grant camera permission in settings to scan Document Scanner</string>\n    <string name=\"cubic\">Cubic</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussian</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"box\">Box</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Cubic interpolation provides smoother scaling by considering the closest 16 pixels, giving better results than bilinear</string>\n    <string name=\"bspline_sub\">Utilizes piecewise-defined polynomial functions to smoothly interpolate and approximate a curve or surface, flexible and continuous shape representation</string>\n    <string name=\"hamming_sub\">A window function used to reduce spectral leakage by tapering the edges of a signal, useful in signal processing</string>\n    <string name=\"hanning_sub\">A variant of the Hann window, commonly used to reduce spectral leakage in signal processing applications</string>\n    <string name=\"blackman_sub\">A window function that provides good frequency resolution by minimizing spectral leakage, often used in signal processing</string>\n    <string name=\"welch_sub\">A window function designed to give good frequency resolution with reduced spectral leakage, often used in signal processing applications</string>\n    <string name=\"quadric_sub\">A method that uses a quadratic function for interpolation, providing smooth and continuous results</string>\n    <string name=\"gaussian_sub\">An interpolation method that applies a Gaussian function, useful for smoothing and reducing noise in images</string>\n    <string name=\"sphinx_sub\">An advanced resampling method providing high-quality interpolation with minimal artifacts</string>\n    <string name=\"bartlett_sub\">A triangular window function used in signal processing to reduce spectral leakage</string>\n    <string name=\"robidoux_sub\">A high-quality interpolation method optimized for natural image resizing, balancing sharpness and smoothness</string>\n    <string name=\"robidoux_sharp_sub\">A sharper variant of the Robidoux method, optimized for crisp image resizing</string>\n    <string name=\"spline16_sub\">A spline-based interpolation method that provides smooth results using a 16-tap filter</string>\n    <string name=\"spline36_sub\">A spline-based interpolation method that provides smooth results using a 36-tap filter</string>\n    <string name=\"spline64_sub\">A spline-based interpolation method that provides smooth results using a 64-tap filter</string>\n    <string name=\"kaiser_sub\">An interpolation method that uses the Kaiser window, providing good control over the trade-off between main-lobe width and side-lobe level</string>\n    <string name=\"bartlett_hann_sub\">A hybrid window function combining the Bartlett and Hann windows, used to reduce spectral leakage in signal processing</string>\n    <string name=\"box_sub\">A simple resampling method that uses the average of the nearest pixel values, often resulting in a blocky appearance</string>\n    <string name=\"bohman_sub\">A window function used to reduce spectral leakage, providing good frequency resolution in signal processing applications</string>\n    <string name=\"lanczos2_sub\">A resampling method that uses a 2-lobe Lanczos filter for high-quality interpolation with minimal artifacts</string>\n    <string name=\"lanczos3_sub\">A resampling method that uses a 3-lobe Lanczos filter for high-quality interpolation with minimal artifacts</string>\n    <string name=\"lanczos4_sub\">A resampling method that uses a 4-lobe Lanczos filter for high-quality interpolation with minimal artifacts</string>\n    <string name=\"lanczos2_jinc_sub\">A variant of the Lanczos 2 filter that uses the jinc function, providing high-quality interpolation with minimal artifacts</string>\n    <string name=\"lanczos3_jinc_sub\">A variant of the Lanczos 3 filter that uses the jinc function, providing high-quality interpolation with minimal artifacts</string>\n    <string name=\"lanczos4_jinc_sub\">A variant of the Lanczos 4 filter that uses the jinc function, providing high-quality interpolation with minimal artifacts</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Elliptical Weighted Average (EWA) variant of the Hanning filter for smooth interpolation and resampling</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elliptical Weighted Average (EWA) variant of the Robidoux filter for high-quality resampling</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_blackman_sub\">Elliptical Weighted Average (EWA) variant of the Blackman filter for minimizing ringing artifacts</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Elliptical Weighted Average (EWA) variant of the Quadric filter for smooth interpolation</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elliptical Weighted Average (EWA) variant of the Robidoux Sharp filter for sharper results</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Elliptical Weighted Average (EWA) variant of the Lanczos 3 Jinc filter for high-quality resampling with reduced aliasing</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">A resampling filter designed for high-quality image processing with a good balance of sharpness and smoothness</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Elliptical Weighted Average (EWA) variant of the Ginseng filter for enhanced image quality</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Elliptical Weighted Average (EWA) variant of the Lanczos Sharp filter for achieving sharp results with minimal artifacts</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Elliptical Weighted Average (EWA) variant of the Lanczos 4 Sharpest filter for extremely sharp image resampling</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptical Weighted Average (EWA) variant of the Lanczos Soft filter for smoother image resampling</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">A resampling filter designed by Haasn for smooth and artifact-free image scaling</string>\n    <string name=\"format_conversion\">Format Conversion</string>\n    <string name=\"format_conversion_sub\">Convert batch of images from one format to another</string>\n    <string name=\"dismiss_forever\">Dismiss Forever</string>\n    <string name=\"image_stacking\">Image Stacking</string>\n    <string name=\"image_stacking_sub\">Stack images on top of each other with chosen blend modes</string>\n    <string name=\"add_image\">Add Image</string>\n    <string name=\"bins_count\">Bins count</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Equalize Histogram Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Equalize Histogram Adaptive HSV</string>\n    <string name=\"edge_mode\">Edge Mode</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Wrap</string>\n    <string name=\"color_blind_scheme\">Color Blindness</string>\n    <string name=\"color_blind_scheme_sub\">Select mode to adapt theme colors for the selected color blindness variant</string>\n    <string name=\"protanomaly_sub\">Difficulty distinguishing between red and green hues</string>\n    <string name=\"deuteranomaly_sub\">Difficulty distinguishing between green and red hues</string>\n    <string name=\"tritanomaly_sub\">Difficulty distinguishing between blue and yellow hues</string>\n    <string name=\"protanopia_sub\">Inability to perceive red hues</string>\n    <string name=\"deuteranopia_sub\">Inability to perceive green hues</string>\n    <string name=\"tritanopia_sub\">Inability to perceive blue hues</string>\n    <string name=\"achromatomaly_sub\">Reduced sensitivity to all colors</string>\n    <string name=\"achromatopsia_sub\">Complete color blindness, seeing only shades of gray</string>\n    <string name=\"not_use_color_blind_scheme\">Do not use Color Blind scheme</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Colors will be exactly as set in the theme</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">A Lagrange interpolation filter of order 2, suitable for high-quality image scaling with smooth transitions</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">A Lagrange interpolation filter of order 3, offering better accuracy and smoother results for image scaling</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">A Lanczos resampling filter with a higher order of 6, providing sharper and more accurate image scaling</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">A variant of the Lanczos 6 filter using a Jinc function for improved image resampling quality</string>\n    <string name=\"linear_box_blur\">Linear Box Blur</string>\n    <string name=\"linear_tent_blur\">Linear Tent Blur</string>\n    <string name=\"linear_gaussian_box_blur\">Linear Gaussian Box Blur</string>\n    <string name=\"linear_stack_blur\">Linear Stack Blur</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linear Fast Gaussian Blur Next</string>\n    <string name=\"linear_fast_gaussian_blur\">Linear Fast Gaussian Blur</string>\n    <string name=\"linear_gaussian_blur\">Linear Gaussian Blur</string>\n    <string name=\"draw_filter_sub\">Choose one filter to use it as paint</string>\n    <string name=\"replace_filter\">Replace Filter</string>\n    <string name=\"pick_filter_info\">Pick filter below to use it as brush in your drawing</string>\n    <string name=\"tiff_compression_scheme\">TIFF compression scheme</string>\n    <string name=\"low_poly\">Low Poly</string>\n    <string name=\"sand_painting\">Sand Painting</string>\n    <string name=\"image_splitting\">Image Splitting</string>\n    <string name=\"image_splitting_sub\">Split single image by rows or columns</string>\n    <string name=\"fit_to_bounds\">Fit To Bounds</string>\n    <string name=\"fit_to_bounds_sub\">Combine crop resize mode with this parameter to achieve desired behavior (Crop/Fit to aspect ratio)</string>\n    <string name=\"languages_imported\">Languages imported successfully</string>\n    <string name=\"backup_ocr_models\">Backup OCR models</string>\n    <string name=\"import_word\">Import</string>\n    <string name=\"export\">Export</string>\n    <string name=\"position\">Position</string>\n    <string name=\"center\">Center</string>\n    <string name=\"top_left\">Top Left</string>\n    <string name=\"top_right\">Top Right</string>\n    <string name=\"bottom_left\">Bottom Left</string>\n    <string name=\"bottom_right\">Bottom Right</string>\n    <string name=\"top_center\">Top Center</string>\n    <string name=\"center_right\">Center Right</string>\n    <string name=\"bottom_center\">Bottom Center</string>\n    <string name=\"center_left\">Center Left</string>\n    <string name=\"target_image\">Target Image</string>\n    <string name=\"palette_transfer\">Palette Transfer</string>\n    <string name=\"enhanced_oil\">Enhanced Oil</string>\n    <string name=\"simple_old_tv\">Simple Old TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Simple Sketch</string>\n    <string name=\"soft_glow\">Soft Glow</string>\n    <string name=\"color_poster\">Color Poster</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Third color</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Clustered 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Clustered 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">Clustered 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">No favorite options selected, add them in tools page</string>\n    <string name=\"add_favorites\">Add Favorites</string>\n    <string name=\"harmony_complementary\">Complementary</string>\n    <string name=\"harmony_analogous\">Analogous</string>\n    <string name=\"harmony_triadic\">Triadic</string>\n    <string name=\"harmony_split_complementary\">Split Complementary</string>\n    <string name=\"harmony_tetradic\">Tetradic</string>\n    <string name=\"harmony_square\">Square</string>\n    <string name=\"harmony_analogous_complementary\">Analogous + Complementary</string>\n    <string name=\"color_tools\">Color Tools</string>\n    <string name=\"color_tools_sub\">Mix, make tones, generate shades and more</string>\n    <string name=\"color_harmonies\">Color Harmonies</string>\n    <string name=\"color_shading\">Color Shading</string>\n    <string name=\"variation\">Variation</string>\n    <string name=\"tints\">Tints</string>\n    <string name=\"tones\">Tones</string>\n    <string name=\"shades\">Shades</string>\n    <string name=\"color_mixing\">Color Mixing</string>\n    <string name=\"color_info\">Color Info</string>\n    <string name=\"selected_color\">Selected Color</string>\n    <string name=\"color_to_mix\">Color To Mix</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Cannot use monet while dynamic colors are turned on</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Target LUT image</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"soft_elegance\">Soft Elegance</string>\n    <string name=\"soft_elegance_variant\">Soft Elegance Variant</string>\n    <string name=\"palette_transfer_variant\">Palette Transfer Variant</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Target 3D LUT File (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Candlelight</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Edgy Amber</string>\n    <string name=\"fall_colors\">Fall Colors</string>\n    <string name=\"film_stock_50\">Film Stock 50</string>\n    <string name=\"foggy_night\">Foggy Night</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Get Neutral LUT image</string>\n    <string name=\"save_empty_lut_sub\">First, use your favourite photo editing application to apply a filter to neutral LUT which you can obtain here. For this to work properly each pixel color must not depend on other pixels (e.g. blur will not work). Once ready, use your new LUT image as input for 512*512 LUT filter</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"coffee\">Coffee</string>\n    <string name=\"golden_forest\">Golden Forest</string>\n    <string name=\"greenish\">Greenish</string>\n    <string name=\"retro_yellow\">Retro Yellow</string>\n    <string name=\"links_preview\">Links Preview</string>\n    <string name=\"links_preview_sub\">Enables link preview retrieving in places where you can obtain text (QRCode, OCR etc)</string>\n    <string name=\"links\">Links</string>\n    <string name=\"ico_size_warning\">ICO files can only be saved at the maximum size of 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF to WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Convert GIF images to WEBP animated pictures</string>\n    <string name=\"webp_tools\">WEBP Tools</string>\n    <string name=\"webp_tools_sub\">Convert images to WEBP animated picture or extract frames from given WEBP animation</string>\n    <string name=\"webp_type_to_image\">WEBP to images</string>\n    <string name=\"webp_type_to_image_sub\">Convert WEBP file to batch of pictures</string>\n    <string name=\"webp_type_to_webp_sub\">Convert batch of images to WEBP file</string>\n    <string name=\"webp_type_to_webp\">Images to WEBP</string>\n    <string name=\"select_webp_image_to_start\">Pick WEBP image to start</string>\n    <string name=\"manage_storage_extra_types\">No full access to files</string>\n    <string name=\"manage_storage_extra_types_sub\">Allow all files access to see JXL, QOI and other images that are not recognized as images on Android. Without the permission Image Toolbox is unable to show those images</string>\n    <string name=\"default_draw_color\">Default Draw Color</string>\n    <string name=\"default_draw_path_mode\">Default Draw Path Mode</string>\n    <string name=\"add_timestamp\">Add Timestamp</string>\n    <string name=\"add_timestamp_sub\">Enables Timestamp adding to the output filename</string>\n    <string name=\"formatted_timestamp\">Formatted Timestamp</string>\n    <string name=\"formatted_timestamp_sub\">Enable Timestamp formatting in output filename instead of basic millis</string>\n    <string name=\"enable_timestamps_to_format_them\">Enable Timestamps to select their format</string>\n    <string name=\"one_time_save_location\">One Time Save Location</string>\n    <string name=\"one_time_save_location_sub\">View and Edit one time save locations which you can use by long pressing the save button in mostly all options</string>\n    <string name=\"recently_used\">Recently Used</string>\n    <string name=\"ci_channel\">CI channel</string>\n    <string name=\"group\">Group</string>\n    <string name=\"ungroup\">Ungroup</string>\n    <string name=\"image_toolbox_in_telegram\">Image Toolbox in Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Join our chat where you can discuss anything you want and also look into the CI channel where I post betas and announcements</string>\n    <string name=\"ci_channel_sub\">Get notified about new versions of app, and read announcements</string>\n    <string name=\"fit_description\">Fit an image to given dimensions and apply blur or color to background</string>\n    <string name=\"tools_arrangement\">Tools Arrangement</string>\n    <string name=\"group_tools_by_type\">Group tools by type</string>\n    <string name=\"group_tools_by_type_sub\">Groups tools on the main screen by their type instead of a custom list arrangement</string>\n    <string name=\"default_values\">Default Values</string>\n    <string name=\"system_bars_visibility\">System Bars Visibility</string>\n    <string name=\"show_system_bars_by_swipe\">Show System Bars By Swipe</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Enables swiping to show system bars if they are hidden</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Hide All</string>\n    <string name=\"show_all\">Show All</string>\n    <string name=\"hide_nav_bar\">Hide Nav Bar</string>\n    <string name=\"hide_status_bar\">Hide Status Bar</string>\n    <string name=\"noise_generation\">Noise Generation</string>\n    <string name=\"noise_generation_sub\">Generate different noises like Perlin or other types</string>\n    <string name=\"frequency\">Frequency</string>\n    <string name=\"noise_type\">Noise Type</string>\n    <string name=\"rotation_type\">Rotation Type</string>\n    <string name=\"fractal_type\">Fractal Type</string>\n    <string name=\"octaves\">Octaves</string>\n    <string name=\"lacunarity\">Lacunarity</string>\n    <string name=\"gain\">Gain</string>\n    <string name=\"weighted_strength\">Weighted Strength</string>\n    <string name=\"ping_pong_strength\">Ping Pong Strength</string>\n    <string name=\"distance_function\">Distance Function</string>\n    <string name=\"return_type\">Return Type</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"alignment\">Alignment</string>\n    <string name=\"custom_filename\">Custom Filename</string>\n    <string name=\"custom_filename_sub\">Select location and filename which are will be used to save current image</string>\n    <string name=\"saved_to_custom\">Saved to folder with custom name</string>\n    <string name=\"collage_maker\">Collage Maker</string>\n    <string name=\"collage_maker_sub\">Make collages from up to 20 images</string>\n    <string name=\"collage_type\">Collage Type</string>\n    <string name=\"collages_info\">Hold image to swap, move and zoom to adjust position</string>\n    <string name=\"disable_rotation\">Disable rotation</string>\n    <string name=\"disable_rotation_sub\">Prevents rotating images with two-finger gestures</string>\n    <string name=\"enable_snapping_to_borders\">Enable snapping to borders</string>\n    <string name=\"enable_snapping_to_borders_sub\">After moving or zooming, images will snap to fill frame edges</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">RGB or Brightness image histogram to help you make adjustments</string>\n    <string name=\"image_for_histogram\">This image will be used to generate RGB and Brightness histograms</string>\n    <string name=\"tesseract_options\">Tesseract Options</string>\n    <string name=\"tesseract_options_sub\">Apply some input variables for tesseract engine</string>\n    <string name=\"custom_options\">Custom Options</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">Options should be entered following this pattern: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Auto Crop</string>\n    <string name=\"free_corners\">Free Corners</string>\n    <string name=\"free_corners_sub\">Crop image by polygon, this also corrects perspective</string>\n    <string name=\"coerce_points_to_image_bounds\">Coerce Points To Image Bounds</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Points will not be limited by image bounds, this useful for more precise perspective correcting</string>\n    <string name=\"mask\">Mask</string>\n    <string name=\"spot_heal_sub\">Content aware fill under drawn path</string>\n    <string name=\"spot_heal\">Heal Spot</string>\n    <string name=\"use_circle_kernel\">Use Circle Kernel</string>\n    <string name=\"opening\">Opening</string>\n    <string name=\"closing\">Closing</string>\n    <string name=\"morphological_gradient\">Morphological Gradient</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Black Hat</string>\n    <string name=\"tone_curves\">Tone Curves</string>\n    <string name=\"reset_curves\">Reset Curves</string>\n    <string name=\"reset_curves_sub\">Curves will be rolled back to default value</string>\n    <string name=\"line_style\">Line Style</string>\n    <string name=\"gap_size\">Gap Size</string>\n    <string name=\"dashed\">Dashed</string>\n    <string name=\"dot_dashed\">Dot Dashed</string>\n    <string name=\"stamped\">Stamped</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Draws dashed line along the drawn path with specified gap size</string>\n    <string name=\"dot_dashed_sub\">Draws dot and dashed line along given path</string>\n    <string name=\"defaultt_sub\">Just default straight lines</string>\n    <string name=\"stamped_sub\">Draws selected shapes along the path with specified spacing</string>\n    <string name=\"zigzag_sub\">Draws wavy zigzag along the path</string>\n    <string name=\"zigzag_ratio\">Zigzag ratio</string>\n    <string name=\"create_shortcut\">Create Shortcut</string>\n    <string name=\"create_shortcut_title\">Choose tool to pin</string>\n    <string name=\"create_shortcut_subtitle\">Tool will be added to home screen of your launcher as shortcut, use it combining with \\\"Skip file picking\\\" setting to achieve needed behavior</string>\n    <string name=\"dont_stack_frames\">Don\\'t stack frames</string>\n    <string name=\"dont_stack_frames_sub\">Enables disposing of previous frames, so they will not stack on each other</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Frames will be crossfaded into each other</string>\n    <string name=\"crossfade_count\">Crossfade frames count</string>\n    <string name=\"threshold_one\">Threshold One</string>\n    <string name=\"threshold_two\">Threshold Two</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Mirror 101</string>\n    <string name=\"enhanced_zoom_blur\">Enhanced Zoom Blur</string>\n    <string name=\"laplacian_simple\">Laplacian Simple</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Helper Grid</string>\n    <string name=\"helper_grid_sub\">Shows supporting grid above drawing area to help with precise manipulations</string>\n    <string name=\"grid_color\">Grid Color</string>\n    <string name=\"cell_width\">Cell Width</string>\n    <string name=\"cell_height\">Cell Height</string>\n    <string name=\"compact_selectors\">Compact Selectors</string>\n    <string name=\"compact_selectors_sub\">Some selection controls will use a compact layout to take less space</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Grant camera permission in settings to capture image</string>\n    <string name=\"layout\">Layout</string>\n    <string name=\"main_screen_title\">Main Screen Title</string>\n    <string name=\"constant_rate_factor\">Constant Rate Factor (CRF)</string>\n    <string name=\"crf_sub\">A value of %1$s means a slow compression, resulting in a relatively small file size. %2$s means a faster compression, resulting in a large file.</string>\n    <string name=\"lut_library\">Lut Library</string>\n    <string name=\"lut_library_sub\">Download collection of LUTs, which you can apply after downloading</string>\n    <string name=\"lut_library_update_sub\">Update collection of LUTs (only new ones will be queued), which you can apply after downloading</string>\n    <string name=\"filter_preview_image_sub\">Change default image preview for filters</string>\n    <string name=\"filter_preview_image\">Preview Image</string>\n    <string name=\"hide\">Hide</string>\n    <string name=\"show\">Show</string>\n    <string name=\"slider_type\">Slider Type</string>\n    <string name=\"fancy\">Fancy</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy_sub\">A fancy-looking slider. This is the default option</string>\n    <string name=\"material_2_sub\">A Material 2 slider</string>\n    <string name=\"material_you_slider_sub\">A Material You slider</string>\n    <string name=\"apply\">Apply</string>\n    <string name=\"center_align_dialog_buttons\">Center Dialog Buttons</string>\n    <string name=\"center_align_dialog_buttons_sub\">Buttons of dialogs will be positioned at center instead of left side if possible</string>\n    <string name=\"open_source_licenses\">Open Source Licenses</string>\n    <string name=\"open_source_licenses_sub\">View licenses of open source libraries used in this app</string>\n    <string name=\"area\">Area</string>\n    <string name=\"area_sub\">Resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire\\'-free results. But when the image is zoomed, it is similar to the \\\"Nearest\\\" method.</string>\n    <string name=\"enable_tonemapping\">Enable Tonemapping</string>\n    <string name=\"enter_percent\">Enter %</string>\n    <string name=\"unknown_host\">Cannot access the site, try using VPN or check if the url correct</string>\n    <string name=\"markup_layers\">Markup Layers</string>\n    <string name=\"markup_layers_sub\">Layers mode with ability to freely place images, text and more</string>\n    <string name=\"edit_layer\">Edit layer</string>\n    <string name=\"layers_on_image\">Layers on image</string>\n    <string name=\"layers_on_image_sub\">Use an image as a background and add different layers on top of it</string>\n    <string name=\"layers_on_background\">Layers on background</string>\n    <string name=\"layers_on_background_sub\">The same as first option but with color instead of image</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Fast Settings Side</string>\n    <string name=\"fast_settings_side_sub\">Add a floating strip at the selected side while editing images, which will open fast settings when clicked</string>\n    <string name=\"clear_selection\">Clear selection</string>\n    <string name=\"settings_group_visibility_hidden\">Setting group \\\"%1$s\\\" will be collapsed by default</string>\n    <string name=\"settings_group_visibility_visible\">Setting group \\\"%1$s\\\" will be expanded by default</string>\n    <string name=\"base_64_tools\">Base64 Tools</string>\n    <string name=\"base_64_tools_sub\">Decode Base64 string to image, or encode image to Base64 format</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">Provided value is not a valid Base64 string</string>\n    <string name=\"copy_not_a_valid_base_64\">Cannot copy empty or invalid Base64 string</string>\n    <string name=\"paste_base_64\">Paste Base64</string>\n    <string name=\"copy_base_64\">Copy Base64</string>\n    <string name=\"base_64_tips\">Load image to copy or save Base64 string. If you have the string itself, you can paste it above to obtain image</string>\n    <string name=\"save_base_64\">Save Base64</string>\n    <string name=\"share_base_64\">Share Base64</string>\n    <string name=\"options\">Options</string>\n    <string name=\"actions\">Actions</string>\n    <string name=\"import_base_64\">Import Base64</string>\n    <string name=\"base_64_actions\">Base64 Actions</string>\n    <string name=\"add_outline\">Add Outline</string>\n    <string name=\"add_outline_sub\">Add outline around text with specified color and width</string>\n    <string name=\"add_shadow\">Add Shadow</string>\n    <string name=\"add_shadow_sub\">Add blur shadow behind layer with configurable color and offsets</string>\n    <string name=\"outline_color\">Outline Color</string>\n    <string name=\"outline_size\">Outline Size</string>\n    <string name=\"shadow_color\">Shadow Color</string>\n    <string name=\"text_geometry\">Text Geometry</string>\n    <string name=\"text_geometry_sub\">Stretch or skew text for sharper stylization</string>\n    <string name=\"scale_x\">Scale X</string>\n    <string name=\"skew_x\">Skew X</string>\n    <string name=\"rotation\">Rotation</string>\n    <string name=\"checksum_as_filename\">Checksum as Filename</string>\n    <string name=\"checksum_as_filename_sub\">Output images will have name corresponding to their data checksum</string>\n    <string name=\"free_software_partner\">Free Software (Partner)</string>\n    <string name=\"free_software_partner_sub\">More useful software in the partner channel of Android applications</string>\n    <string name=\"algorithms\">Algorithm</string>\n    <string name=\"checksum_tools\">Checksum Tools</string>\n    <string name=\"checksum_tools_sub\">Compare checksums, calculate hashes or create hex strings from files using different hashing algorithms</string>\n    <string name=\"calculate\">Calculate</string>\n    <string name=\"text_hash\">Text Hash</string>\n    <string name=\"checksum\">Checksum</string>\n    <string name=\"pick_file_to_checksum\">Pick file to calculate its checksum based on selected algorithm</string>\n    <string name=\"enter_text_to_checksum\">Enter text to calculate its checksum based on selected algorithm</string>\n    <string name=\"source_checksum\">Source Checksum</string>\n    <string name=\"checksum_to_compare\">Checksum To Compare</string>\n    <string name=\"match\">Match!</string>\n    <string name=\"difference\">Difference</string>\n    <string name=\"match_sub\">Checksums are equal, it can be safe</string>\n    <string name=\"difference_sub\">Checksums are not equal, file can be unsafe!</string>\n    <string name=\"mesh_gradients\">Mesh Gradients</string>\n    <string name=\"collection_mesh_gradients_sub\">Look at online collection of Mesh Gradients</string>\n    <string name=\"wrong_font\">Only TTF and OTF fonts can be imported</string>\n    <string name=\"import_font\">Import font (TTF/OTF)</string>\n    <string name=\"export_fonts\">Export fonts</string>\n    <string name=\"imported_fonts\">Imported fonts</string>\n    <string name=\"error_while_saving\">Error while saving attempt, try to change output folder</string>\n    <string name=\"filename_is_not_set\">Filename is not set</string>\n    <string name=\"none\">None</string>\n    <string name=\"custom_pages\">Custom Pages</string>\n    <string name=\"pages_selection\">Pages Selection</string>\n    <string name=\"tool_exit_confirmation\">Tool Exit Confirmation</string>\n    <string name=\"tool_exit_confirmation_sub\">If you have unsaved changes while using particular tools and try to close it, then confirm dialog will be shown</string>\n    <string name=\"edit_exif_screen\">Edit EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Change metadata of single image without recompression</string>\n    <string name=\"edit_exif_tag\">Tap to edit available tags</string>\n    <string name=\"change_sticker\">Change Sticker</string>\n    <string name=\"fit_width\">Fit Width</string>\n    <string name=\"fit_height\">Fit Height</string>\n    <string name=\"batch_compare\">Batch Compare</string>\n    <string name=\"pick_files_to_checksum\">Pick file/files to calculate its checksum based on selected algorithm</string>\n    <string name=\"pick_files\">Pick Files</string>\n    <string name=\"pick_directory\">Pick Directory</string>\n    <string name=\"head_length_scale\">Head Length Scale</string>\n    <string name=\"stamp\">Stamp</string>\n    <string name=\"timestamp\">Timestamp</string>\n    <string name=\"format_pattern\">Format Pattern</string>\n    <string name=\"padding\">Padding</string>\n    <string name=\"image_cutting\">Image Cutting</string>\n    <string name=\"image_cutting_sub\">Cut image part and merge left ones (can be inverse) by vertical or horizontal lines</string>\n    <string name=\"vertical_pivot_line\">Vertical Pivot Line</string>\n    <string name=\"horizontal_pivot_line\">Horizontal Pivot Line</string>\n    <string name=\"inverse_selection\">Inverse Selection</string>\n    <string name=\"inverse_vertical_selection_sub\">Vertical cut part will be leaved, instead of merging parts around cut area</string>\n    <string name=\"inverse_horizontal_selection_sub\">Horizontal cut part will be leaved, instead of merging parts around cut area</string>\n    <string name=\"collection_mesh_gradients\">Collection of Mesh Gradients</string>\n    <string name=\"mesh_gradients_sub\">Create mesh gradient with custom amount of knots and resolution</string>\n    <string name=\"gradient_maker_type_image_mesh\">Mesh Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Compose mesh gradient of top of given images</string>\n    <string name=\"points_customization\">Points Customization</string>\n    <string name=\"grid_size\">Grid Size</string>\n    <string name=\"resolution_x\">Resolution X</string>\n    <string name=\"resolution_y\">Resolution Y</string>\n    <string name=\"resolution\">Resolution</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">Highlight Color</string>\n    <string name=\"pixel_comparison_type\">Pixel Comparison Type</string>\n    <string name=\"scan_barcode\">Scan barcode</string>\n    <string name=\"height_ratio\">Height Ratio</string>\n    <string name=\"barcode_type\">Barcode Type</string>\n    <string name=\"enforce_bw\">Enforce B/W</string>\n    <string name=\"enforce_bw_sub\">Barcode Image will be fully black and white and not colored by app\\'s theme</string>\n    <string name=\"barcodes_sub\">Scan any Barcode (QR, EAN, AZTEC, …) and get its content or paste your text to generate new one</string>\n    <string name=\"no_barcode_found\">No Barcode Found</string>\n    <string name=\"generated_barcode_will_be_here\">Generated Barcode Will Be Here</string>\n    <string name=\"audio_cover_extractor\">Audio Covers</string>\n    <string name=\"audio_cover_extractor_sub\">Extract album cover images from audio files, most common formats are supported</string>\n    <string name=\"pick_audio_to_start\">Pick audio to start</string>\n    <string name=\"pick_audio\">Pick Audio</string>\n    <string name=\"no_covers_found\">No Covers Found</string>\n    <string name=\"send_logs\">Send Logs</string>\n    <string name=\"send_logs_sub\">Click to share app logs file, this can help me to spot the problem and fix issues</string>\n    <string name=\"crash_title\">Oops… Something went wrong</string>\n    <string name=\"crash_subtitle\">You can contact me using options below and I will try to find solution.\\n(Do not forget to attach logs)</string>\n    <string name=\"ocr_write_to_file\">Write To File</string>\n    <string name=\"ocr_write_to_file_sub\">Extract text from batch of images and store it in the one text file</string>\n    <string name=\"ocr_write_to_metadata\">Write To Metadata</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extract text from each image and place it in EXIF info of relative photos</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Write To Searchable PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Recognize text from image batch and save searchable PDF with image and selectable text layer</string>\n    <string name=\"invisible_mode\">Invisible Mode</string>\n    <string name=\"invisible_mode_sub\">Use steganography to create eye invisible watermarks inside bytes of your images</string>\n    <string name=\"use_lsb\">Use LSB</string>\n    <string name=\"use_lsb_sub\">LSB (Less Significant Bit) steganography method will be used, FD (Frequency Domain) otherwise</string>\n    <string name=\"auto_remove_red_eyes\">Auto Remove Red Eyes</string>\n    <string name=\"password\">Password</string>\n    <string name=\"lock\">Lock</string>\n    <string name=\"unlock\">Unlock</string>\n    <string name=\"pdf_is_protected\">PDF is protected</string>\n    <string name=\"operation_almost_complete\">Operation almost complete. Cancelling now will require restarting it</string>\n    <string name=\"sort_by_date_modified\">Date Modified</string>\n    <string name=\"sort_by_date_modified_reversed\">Date Modified (Reversed)</string>\n    <string name=\"sort_by_size\">Size</string>\n    <string name=\"sort_by_size_reversed\">Size (Reversed)</string>\n    <string name=\"sort_by_mime_type\">MIME Type</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME Type (Reversed)</string>\n    <string name=\"sort_by_extension\">Extension</string>\n    <string name=\"sort_by_extension_reversed\">Extension (Reversed)</string>\n    <string name=\"sort_by_date_added\">Date Added</string>\n    <string name=\"sort_by_date_added_reversed\">Date Added (Reversed)</string>\n    <string name=\"left_to_right\">Left to Right</string>\n    <string name=\"right_to_left\">Right to Left</string>\n    <string name=\"top_to_bottom\">Top to Bottom</string>\n    <string name=\"bottom_to_top\">Bottom to Top</string>\n    <string name=\"liquid_glass\">Liquid Glass</string>\n    <string name=\"liquid_glass_sub\">A switch based on recently announced IOS 26 and it\\'s liquid glass design system</string>\n    <string name=\"pick_image_or_base64\">Pick image or paste/import Base64 data below</string>\n    <string name=\"type_image_link\">Type image link to start</string>\n    <string name=\"paste_link\">Paste link</string>\n    <string name=\"kaleidoscope\">Kaleidoscope</string>\n    <string name=\"secondary_angle\">Secondary angle</string>\n    <string name=\"sides\">Sides</string>\n    <string name=\"channel_mix\">Channel Mix</string>\n    <string name=\"blue_green\">Blue green</string>\n    <string name=\"red_blue\">Red blue</string>\n    <string name=\"green_red\">Green red</string>\n    <string name=\"into_red\">Into red</string>\n    <string name=\"into_green\">Into green</string>\n    <string name=\"into_blue\">Into blue</string>\n    <string name=\"cyan\">Cyan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Yellow</string>\n    <string name=\"color_halftone\">Color Halftone</string>\n    <string name=\"contour\">Contour</string>\n    <string name=\"levels\">Levels</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi Crystallize</string>\n    <string name=\"shape\">Shape</string>\n    <string name=\"stretch\">Stretch</string>\n    <string name=\"randomness\">Randomness</string>\n    <string name=\"despeckle\">Despeckle</string>\n    <string name=\"diffuse\">Diffuse</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Second radius</string>\n    <string name=\"equalize\">Equalize</string>\n    <string name=\"glow\">Glow</string>\n    <string name=\"whirl_and_pinch\">Whirl and Pinch</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">Border color</string>\n    <string name=\"polar_coordinates\">Polar Coordinates</string>\n    <string name=\"rect_to_polar\">Rect to polar</string>\n    <string name=\"polar_to_rect\">Polar to rect</string>\n    <string name=\"invert_in_circle\">Invert in circle</string>\n    <string name=\"reduce_noise\">Reduce Noise</string>\n    <string name=\"simple_solarize\">Simple Solarize</string>\n    <string name=\"weave\">Weave</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X Width</string>\n    <string name=\"y_wdth\">Y Width</string>\n    <string name=\"twirl\">Twirl</string>\n    <string name=\"rubber_stmp\">Rubber Stamp</string>\n    <string name=\"smear\">Smear</string>\n    <string name=\"density\">Density</string>\n    <string name=\"mix\">Mix</string>\n    <string name=\"sphere_lensh_distortion\">Sphere Lens Distortion</string>\n    <string name=\"refraction_index\">Refraction index</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Spread angle</string>\n    <string name=\"sparkle\">Sparkle</string>\n    <string name=\"rays\">Rays</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Moire</string>\n    <string name=\"autumn\">Autumn</string>\n    <string name=\"bone\">Bone</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Winter</string>\n    <string name=\"ocean\">Ocean</string>\n    <string name=\"summer\">Summer</string>\n    <string name=\"spring\">Spring</string>\n    <string name=\"cool_variant\">Cool Variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Pink</string>\n    <string name=\"hot\">Hot</string>\n    <string name=\"parula\">Parula</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Cividis</string>\n    <string name=\"twilight\">Twilight</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspective Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Allow crop</string>\n    <string name=\"crop_or_perspective\">Crop or Perspective</string>\n    <string name=\"absolute\">Absolute</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Deep Green</string>\n    <string name=\"lens_correction\">Lens Correction</string>\n    <string name=\"target_lens_profile\">Target lens profile file in JSON format</string>\n    <string name=\"download_ready_lens_profiles\">Download ready lens profiles</string>\n    <string name=\"part_percents\">Part percents</string>\n    <string name=\"export_as_json\">Export as JSON</string>\n    <string name=\"export_as_json_sub\">Copy string with a palette data as json representation</string>\n    <string name=\"seam_carving\">Seam Carving</string>\n    <string name=\"home_screen\">Home Screen</string>\n    <string name=\"lock_screen\">Lock Screen</string>\n    <string name=\"built_in\">Built-in</string>\n    <string name=\"wallpapers_export\">Wallpapers Export</string>\n    <string name=\"refresh\">Refresh</string>\n    <string name=\"wallpapers_export_sub\">Obtain current Home, Lock and Built-in wallpapers</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Allow access to all files, this is needed to retrieve wallpapers</string>\n    <string name=\"allow_read_media_images_for_wp\">Manage external storage permission is not enough, you need to allow access to your images, make sure to select \\\"Allow all\\\"</string>\n    <string name=\"add_preset_to_filename\">Add Preset To Filename</string>\n    <string name=\"add_preset_to_filename_sub\">Appends suffix with selected preset to image filename</string>\n    <string name=\"add_image_scale_mode_to_filename\">Add Image Scale Mode To Filename</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Appends suffix with selected image scale mode to image filename</string>\n    <string name=\"ascii_art\">ASCII Art</string>\n    <string name=\"ascii_art_sub\">Convert picture to ASCII text which will look like image</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Applies negative filter to image for better result in some cases</string>\n    <string name=\"processing_screenshot\">Processing screenshot</string>\n    <string name=\"screenshot_not_captured_try_again\">Screenshot not captured, try again</string>\n    <string name=\"skipped_saving\">Saving skipped</string>\n    <string name=\"skipped_saving_multiple\">%1$s files skipped</string>\n    <string name=\"allow_skip_if_larger\">Allow Skip If Larger</string>\n    <string name=\"allow_skip_if_larger_sub\">Some tools are will be allowed to skip saving images if the resulting file size would be larger than the original</string>\n    <string name=\"qr_type_calendar_event\">Calendar Event</string>\n    <string name=\"qr_type_contact_info\">Contact</string>\n    <string name=\"qr_type_email\">Email</string>\n    <string name=\"qr_type_geo_point\">Location</string>\n    <string name=\"qr_type_phone\">Phone</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Open network</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Phone</string>\n    <string name=\"message\">Message</string>\n    <string name=\"address\">Address</string>\n    <string name=\"subject\">Subject</string>\n    <string name=\"body\">Body</string>\n    <string name=\"name\">Name</string>\n    <string name=\"organization\">Organization</string>\n    <string name=\"title\">Title</string>\n    <string name=\"phones\">Phones</string>\n    <string name=\"emails\">Emails</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">Addresses</string>\n    <string name=\"summary\">Summary</string>\n    <string name=\"description\">Description</string>\n    <string name=\"location\">Location</string>\n    <string name=\"organizer\">Organizer</string>\n    <string name=\"start_date\">Start date</string>\n    <string name=\"end_date\">End date</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Latitude</string>\n    <string name=\"longitude\">Longitude</string>\n    <string name=\"create_barcode\">Create Barcode</string>\n    <string name=\"edit_barcode\">Edit Barcode</string>\n    <string name=\"wifi_configuration\">Wi-Fi configuration</string>\n    <string name=\"security\">Security</string>\n    <string name=\"pick_contact\">Pick contact</string>\n    <string name=\"grant_contact_permission\">Grant contacts permission in settings to autofill using selected contact</string>\n    <string name=\"contact_info\">Contact info</string>\n    <string name=\"first_name\">First name</string>\n    <string name=\"middle_name\">Middle name</string>\n    <string name=\"last_name\">Last name</string>\n    <string name=\"pronunciation\">Pronunciation</string>\n    <string name=\"add_phone\">Add phone</string>\n    <string name=\"add_email\">Add email</string>\n    <string name=\"add_address\">Add address</string>\n    <string name=\"website\">Website</string>\n    <string name=\"add_website\">Add website</string>\n    <string name=\"formatted_name\">Formatted name</string>\n    <string name=\"qr_code_top_image\">This image will be used to place above barcode</string>\n    <string name=\"code_customization\">Code customization</string>\n    <string name=\"qr_logo_image\">This image will be used as logo in the center of QR code</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo padding</string>\n    <string name=\"logo_size\">Logo size</string>\n    <string name=\"logo_corners\">Logo corners</string>\n    <string name=\"fourth_eye\">Fourth eye</string>\n    <string name=\"fourth_eye_description\">Adds eye symmetry to qr code by adding fourth eye at the bottom end corner</string>\n    <string name=\"pixel_shape\">Pixel shape</string>\n    <string name=\"frame_shape\">Frame shape</string>\n    <string name=\"ball_shape\">Ball shape</string>\n    <string name=\"error_correction_level\">Error correction level</string>\n    <string name=\"dark_color\">Dark color</string>\n    <string name=\"light_color\">Light color</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS like style</string>\n    <string name=\"mask_pattern\">Mask pattern</string>\n    <string name=\"code_may_be_not_scannable\">This code may be not scannable, change appearance params to make it readable with all devices</string>\n    <string name=\"not_scannable\">Not scannable</string>\n    <string name=\"launcher_mode_sub\">Tools will look like home screen app launcher to be more compact</string>\n    <string name=\"launcher_mode\">Launcher Mode</string>\n    <string name=\"flood_fill_sub\">Fills an area with selected brush and style</string>\n    <string name=\"flood_fill\">Flood Fill</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Draws graffity styled path</string>\n    <string name=\"square_particles\">Square Particles</string>\n    <string name=\"square_particles_sub\">Spray particles will be square shaped instead of circles</string>\n    <string name=\"palette_tools\">Palette Tools</string>\n    <string name=\"palette_tools_sub\">Generate basic/material you palette from image, or import/export across different palette formats</string>\n    <string name=\"edit_palette\">Edit Palette</string>\n    <string name=\"edit_palette_sub\">Export/import palette across various formats</string>\n    <string name=\"color_name\">Color name</string>\n    <string name=\"palette_name\">Palette name</string>\n    <string name=\"palette_format\">Palette Format</string>\n    <string name=\"export_palette_sub\">Export generated palette to different formats</string>\n    <string name=\"add_color_palette_sub\">Adds new color to current palette</string>\n    <string name=\"palette_name_not_supported\">%1$s format doesn\\'t support providing palette name</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Due to Play Store policies, this feature cannot be included in the current build. To access this functionality, please download ImageToolbox from an alternative source. You can find the available builds on GitHub below.</string>\n    <string name=\"open_github_page\">Open Github page</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s color</item>\n        <item quantity=\"few\">%1$s colors</item>\n        <item quantity=\"many\">%1$s colors</item>\n        <item quantity=\"other\">%1$s colors</item>\n    </plurals>\n    <string name=\"overwrite_files_sub_short\">Original file will be replaced with new one instead of saving in selected folder</string>\n    <string name=\"hidden_watermark_text_detected\">Detected hidden watermark text</string>\n    <string name=\"hidden_watermark_image_detected\">Detected hidden watermark image</string>\n    <string name=\"this_image_was_hidden\">This image was hidden</string>\n    <string name=\"generative_inpaint\">Generative Inpainting</string>\n    <string name=\"generative_inpaint_sub\">Allows you to remove objects in an image using an AI model, without relying on OpenCV. To use this feature, app will download the required model (~200 MB) from GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Allows you to remove objects in an image using an AI model, without relying on OpenCV. This could be a long running operation</string>\n    <string name=\"error_level_analysis\">Error Level Analysis</string>\n    <string name=\"luminance_gradient\">Luminance Gradient</string>\n    <string name=\"average_distance\">Average Distance</string>\n    <string name=\"copy_move_detection\">Copy Move Detection</string>\n    <string name=\"retain\">Retain</string>\n    <string name=\"coefficent\">Coefficent</string>\n    <string name=\"clipboard_data_is_too_large\">Clipboard data is too large</string>\n    <string name=\"data_is_too_large_to_copy\">Data is too large to copy</string>\n    <string name=\"simple_weave_pixelization\">Simple Weave Pixelization</string>\n    <string name=\"staggered_pixelization\">Staggered Pixelization</string>\n    <string name=\"cross_pixelization\">Cross Pixelization</string>\n    <string name=\"micro_macro_pixelization\">Micro Macro Pixelization</string>\n    <string name=\"orbital_pixelization\">Orbital Pixelization</string>\n    <string name=\"vortex_pixelization\">Vortex Pixelization</string>\n    <string name=\"pulse_grid_pixelization\">Pulse Grid Pixelization</string>\n    <string name=\"nucleus_pixelization\">Nucleus Pixelization</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave Pixelization</string>\n    <string name=\"cannot_open_uri\">Cannot open uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Snowfall Mode</string>\n    <string name=\"enabled\">Enabled</string>\n    <string name=\"border_frame\">Border Frame</string>\n    <string name=\"glitch_variant\">Glitch Variant</string>\n    <string name=\"channel_shift\">Channel Shift</string>\n    <string name=\"max_offset\">Max Offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Block Glitch</string>\n    <string name=\"block_size\">Block Size</string>\n    <string name=\"crt_curvature\">CRT curvature</string>\n    <string name=\"curvature\">Curvature</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">AI Tools</string>\n    <string name=\"ai_tools_sub\">Various tools to process images through ai models like artifact removing or denoising</string>\n    <string name=\"model_anime_undeint\">Compression, jagged lines</string>\n    <string name=\"model_broadcast\">Cartoons, broadcast compression</string>\n    <string name=\"model_rgb_max_denoise_fp16\">General compression, general noise</string>\n    <string name=\"model_wb_denoise\">Colorless cartoon noise</string>\n    <string name=\"model_span_anime_pretrain\">Fast, general compression, general noise, animation/comics/anime</string>\n    <string name=\"model_book_scan\">Book scanning</string>\n    <string name=\"model_overexposure\">Exposure correction</string>\n    <string name=\"model_fbcnn_color_fp16\">Best at general compression, color images</string>\n    <string name=\"model_fbcnn_gray_fp16\">Best at general compression, grayscale images</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">General compression, grayscale images, stronger</string>\n    <string name=\"model_scunet_color_gan_fp16\">General noise, color images</string>\n    <string name=\"model_scunet_color_psnr_fp16\">General noise, color images, better details</string>\n    <string name=\"model_scunet_gray_15_fp16\">General noise, grayscale images</string>\n    <string name=\"model_scunet_gray_25_fp16\">General noise, grayscale images, stronger</string>\n    <string name=\"model_scunet_gray_50_fp16\">General noise, grayscale images, strongest</string>\n    <string name=\"model_jpeg_destroyer\">General compression</string>\n    <string name=\"model_jaywreck\">General compression</string>\n    <string name=\"model_h264\">Texturization, h264 compression</string>\n    <string name=\"model_vhs\">VHS compression</string>\n    <string name=\"model_cinepak\">Non-standard compression (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink compression, better on geometry</string>\n    <string name=\"model_debink_v5\">Bink compression, stronger</string>\n    <string name=\"model_debink_v6\">Bink compression, soft, retains detail</string>\n    <string name=\"model_antialias\">Eliminating the stair-step effect, smoothing</string>\n    <string name=\"model_kdm_scans\">Scanned art/drawings, mild compression, moire</string>\n    <string name=\"model_bandage\">Color banding</string>\n    <string name=\"model_halftone\">Slow, removing halftones</string>\n    <string name=\"model_colorizer\">General colorizer for grayscale/bw images, for better results use DDColor</string>\n    <string name=\"model_deedge\">Edge removal</string>\n    <string name=\"model_desharpen\">Removes oversharpening</string>\n    <string name=\"model_dither\">Slow, dithering</string>\n    <string name=\"model_gainres\">Anti-aliasing, general artifacts, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 scans processing</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Lightweight image enhancement model</string>\n    <string name=\"model_bcgone_detailed_v2\">Compression artifact removal</string>\n    <string name=\"model_bcgone_smooth\">Compression artifact removal</string>\n    <string name=\"model_bandage_smooth\">Bandage removal with smooth results</string>\n    <string name=\"model_bendel_halftone\">Halftone pattern processing</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Dither pattern removal V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG artifact removal V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 texture enhancement</string>\n    <string name=\"model_vhs_sharpen\">VHS sharpening and enhancement</string>\n    <string name=\"merging\">Merging</string>\n    <string name=\"chunk_size\">Chunk Size</string>\n    <string name=\"overlap_size\">Overlap Size</string>\n    <string name=\"note_chunk_info\">Images over %1$s px will be sliced and processed in chunks, overlap blends these to prevent visible seams.</string>\n    <string name=\"large_chunk_warning\">Large sizes can cause instability with low-end devices</string>\n    <string name=\"select_one_to_start\">Select one to start</string>\n    <string name=\"delete_model_sub\">Do you want to delete %1$s model? You will need to download it again</string>\n    <string name=\"confirm\">Confirm</string>\n    <string name=\"models\">Models</string>\n    <string name=\"downloaded_models\">Downloaded Models</string>\n    <string name=\"available_models\">Available Models</string>\n    <string name=\"preparing\">Preparing</string>\n    <string name=\"active_model\">Active model</string>\n    <string name=\"failed_to_open_session\">Failed to open session</string>\n    <string name=\"only_onnx_models\">Only .onnx/.ort models can be imported</string>\n    <string name=\"import_model\">Import model</string>\n    <string name=\"import_model_sub\">Import custom onnx model to further use, only onnx/ort models are accepted, supports almost all esrgan like variants</string>\n    <string name=\"imported_models\">Imported Models</string>\n    <string name=\"model_scunet_color_15_fp16\">General noise, colored images</string>\n    <string name=\"model_scunet_color_25_fp16\">General noise, colored images, stronger</string>\n    <string name=\"model_scunet_color_50_fp16\">General noise, colored images, strongest</string>\n    <string name=\"model_artifacts_dithering_alsa\">Reduces dithering artifacts and color banding, improving smooth gradients and flat color areas.</string>\n    <string name=\"model_nmkd_brighten_redux\">Enhances image brightness and contrast with balanced highlights while preserving natural colors.</string>\n    <string name=\"model_nmkd_brighten\">Brightens dark images while keeping details and avoiding overexposure.</string>\n    <string name=\"model_nmkd_detoon\">Removes excessive color toning and restores a more neutral and natural color balance.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Applies Poisson-based noise toning with emphasis on preserving fine details and textures.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Applies soft Poisson noise toning for smoother and less aggressive visual results.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Uniform noise toning focused on detail preservation and image clarity.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Gentle uniform noise toning for subtle texture and smooth appearance.</string>\n    <string name=\"model_repainter\">Repairs damaged or uneven areas by repainting artifacts and improving image consistency.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Lightweight debanding model that removes color banding with minimal performance cost.</string>\n    <string name=\"model_jpeg_0_20\">Optimizes images with very high compression artifacts (0-20% quality) for improved clarity.</string>\n    <string name=\"model_jpeg_20_40\">Enhances images with high compression artifacts (20-40% quality), restoring details and reducing noise.</string>\n    <string name=\"model_jpeg_40_60\">Improves images with moderate compression (40-60% quality), balancing sharpness and smoothness.</string>\n    <string name=\"model_jpeg_60_80\">Refines images with light compression (60-80% quality) to enhance subtle details and textures.</string>\n    <string name=\"model_jpeg_80_100\">Slightly enhances near-lossless images (80-100% quality) while preserving natural look and details.</string>\n    <string name=\"model_spongecolor_lite\">Simple and fast colorization, cartoons, not ideal</string>\n    <string name=\"model_deblr\">Slightly reduces image blur, improving sharpness without introducing artifacts.</string>\n    <string name=\"processing_channel\">Long running operations</string>\n    <string name=\"processing_image\">Processing image</string>\n    <string name=\"processing\">Processing</string>\n    <string name=\"model_artifacts_jpg_0_20\">Removes heavy JPEG compression artifacts in very low quality images (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Reduces strong JPEG artifacts in highly compressed images (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Cleans up moderate JPEG artifacts while preserving image details (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Refines light JPEG artifacts in fairly high quality images (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Subtly reduces minor JPEG artifacts in near-lossless images (80-100%).</string>\n    <string name=\"model_redetail_v2\">Enhances fine details and textures, improving perceived sharpness without heavy artifacts.</string>\n    <string name=\"processing_finished\">Processing finished</string>\n    <string name=\"processing_failed\">Processing failed</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Enhances skin textures and details while keeping a natural look, optimized for speed.</string>\n    <string name=\"model_sbdv_dejpeg\">Removes JPEG compression artifacts and restores image quality for compressed photos.</string>\n    <string name=\"model_iso_denoise_v1\">Reduces ISO noise in photos taken in low-light conditions, preserving details.</string>\n    <string name=\"model_dejumbo\">Corrects overexposed or “jumbo” highlights and restores better tonal balance.</string>\n    <string name=\"model_ddcolor_tiny\">Lightweight and fast colorization model that adds natural colors to grayscale images.</string>\n    <string name=\"type_dejpeg\">DeJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Colorize</string>\n    <string name=\"type_artifacts\">Artifacts</string>\n    <string name=\"type_enhance\">Enhance</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Scans</string>\n    <string name=\"type_upscale\">Upscale</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler for general images; tiny model that uses less GPU and time, with moderate deblur and denoise.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler for general images, preserving textures and natural details.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 upscaler for general images with enhanced textures and realistic results.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler optimized for anime images; 6 RRDB blocks for sharper lines and details.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 upscaler with MSE loss, produces smoother results and reduced artifacts for general images.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimized for anime images; 4B32F variant with sharper details and smooth lines.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 model for general images; emphasizes sharpness and clarity.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; faster and smaller, preserves detail while using less GPU memory.</string>\n    <string name=\"model_rmbg_1_4\">Lightweight model for quick background removal. Balanced performance and accuracy. Works with portraits, objects, and scenes. Recommended for most use cases.</string>\n    <string name=\"type_removebg\">Remove BG</string>\n    <string name=\"horizontal_border_thickness\">Horizontal Border Thickness</string>\n    <string name=\"vertical_border_thickness\">Vertical Border Thickness</string>\n    <string name=\"current_model_not_chunkable\">Current model does not support chunking, image will be processed in original dimensions, this may cause high memory consumption and issues with low-end devices</string>\n    <string name=\"chunking_disabled\">Chunking disabled, image will be processed in original dimensions, this may cause high memory consumption and issues with low-end devices but may give better results on inference</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">High-accuracy image segmentation model for background removing</string>\n    <string name=\"model_u2netp\">Lightweight version of U2Net for faster background removing with smaller memory usage.</string>\n    <string name=\"model_ddcolor\">Full DDColor model delivers high-quality colorization for general images with minimal artifacts. Best choice of all colorization models.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Trained and private artistic datasets; produces diverse and artistic colorization results with fewer unrealistic color artifacts.</string>\n    <string name=\"model_birefnet\">Lightweight BiRefNet model based on Swin Transformer for accurate background removing.</string>\n    <string name=\"model_inspyrenet\">High-quality background removal with sharp edges and excellent detail preservation, especially on complex objects and tricky backgrounds.</string>\n    <string name=\"model_isnet\">Background removal model that produces accurate masks with smooth edges, suitable for general objects and moderate detail preservation.</string>\n    <string name=\"model_already_downloaded\">Model already downloaded</string>\n    <string name=\"model_successfully_imported\">Model successfully imported</string>\n    <string name=\"type\">Type</string>\n    <string name=\"keyword\">Keyword</string>\n    <string name=\"very_fast\">Very Fast</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Slow</string>\n    <string name=\"very_slow\">Very Slow</string>\n    <string name=\"compute_percents\">Compute Percents</string>\n    <string name=\"minimum_value_is\">Min value is %1$s</string>\n    <string name=\"warp_sub\">Distort image by drawing with fingers</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">Hardness</string>\n    <string name=\"warp_mode\">Warp Mode</string>\n    <string name=\"warp_mode_move\">Move</string>\n    <string name=\"warp_mode_grow\">Grow</string>\n    <string name=\"warp_mode_shrink\">Shrink</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Swirl CCW</string>\n    <string name=\"fade_strength\">Fade Strength</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Bottom Drop</string>\n    <string name=\"start_drop\">Start Drop</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">Downloading</string>\n    <string name=\"smooth_shapes\">Smooth Shapes</string>\n    <string name=\"smooth_shapes_sub\">Use superellipses instead of standard rounded rectangles for smoother, more natural shapes</string>\n    <string name=\"shape_type\">Shape Type</string>\n    <string name=\"cut\">Cut</string>\n    <string name=\"rounded\">Rounded</string>\n    <string name=\"smooth\">Smooth</string>\n    <string name=\"cut_shapes_sub\">Sharp edges without rounding</string>\n    <string name=\"rounded_shapes_sub\">Classic rounded corners</string>\n    <string name=\"shapes_type\">Shapes Type</string>\n    <string name=\"corners_size\">Corners Size</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elegant rounded UI elements</string>\n    <string name=\"filename_format\">Filename Format</string>\n    <string name=\"prefix_pattern_description\">Custom text placed at the very beginning of the filename, perfect for project names, brands, or personal tags.</string>\n    <string name=\"original_filename_pattern_description\">Uses the original file name without extension, helping you keep source identification intact.</string>\n    <string name=\"width_pattern_description\">The image width in pixels, useful for tracking resolution changes or scaling results.</string>\n    <string name=\"height_pattern_description\">The image height in pixels, helpful when working with aspect ratios or exports.</string>\n    <string name=\"formatted_timestamp_pattern_description\">A customizable timestamp that lets you define your own format by Java specification for perfect sorting.</string>\n    <string name=\"random_numbers_pattern_description\">Generates random digits to guarantee unique filenames; add more digits for extra safety against duplicates.</string>\n    <string name=\"sequence_number_pattern_description\">Auto-incrementing counter for batch exports, ideal when saving multiple images in one session.</string>\n    <string name=\"preset_info_pattern_description\">Inserts the applied preset name into the filename so you can easily remember how the image was processed.</string>\n    <string name=\"scale_mode_pattern_description\">Displays the image scaling mode used during processing, helping distinguish resized, cropped, or fitted images.</string>\n    <string name=\"suffix_pattern_description\">Custom text placed at the end of the filename, useful for versioning like _v2, _edited, or _final.</string>\n    <string name=\"extension_pattern_description\">The file extension (png, jpg, webp, etc.), automatically matching the actual saved format.</string>\n    <string name=\"fling_type\">Fling Type</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">iOS Style</string>\n    <string name=\"smooth_curve\">Smooth Curve</string>\n    <string name=\"quick_stop\">Quick Stop</string>\n    <string name=\"bouncy\">Bouncy</string>\n    <string name=\"floaty\">Floaty</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">Adaptive</string>\n    <string name=\"accessibility_aware\">Accessibility Aware</string>\n    <string name=\"reduced_motion\">Reduced Motion</string>\n    <string name=\"android_native_sub\">Native Android scroll physics</string>\n    <string name=\"smooth_sub\">Balanced, smooth scrolling for general use</string>\n    <string name=\"ios_style_sub\">Higher friction iOS-like scroll behavior</string>\n    <string name=\"smooth_curve_sub\">Unique spline curve for distinct scroll feel</string>\n    <string name=\"quick_stop_sub\">Precise scrolling with quick stopping</string>\n    <string name=\"bouncy_sub\">Playful, responsive bouncy scroll</string>\n    <string name=\"floaty_sub\">Long, gliding scrolls for content browsing</string>\n    <string name=\"snappy_sub\">Quick, responsive scrolling for interactive UIs</string>\n    <string name=\"ultra_smooth_sub\">Premium smooth scrolling with extended momentum</string>\n    <string name=\"adaptive_sub\">Adjusts physics based on fling velocity</string>\n    <string name=\"accessibility_aware_sub\">Respects system accessibility settings</string>\n    <string name=\"reduced_motion_sub\">Minimal motion for accessibility needs</string>\n    <string name=\"primary_lines\">Primary Lines</string>\n    <string name=\"primary_lines_sub\">Adds thicker line every fifth line</string>\n    <string name=\"fill_color\">Fill Color</string>\n    <string name=\"hidden_tools\">Hidden Tools</string>\n    <string name=\"hidden_for_share\">Tools Hidden For Share</string>\n    <string name=\"color_library\">Color Library</string>\n    <string name=\"color_library_sub\">Browse a vast collection of colors</string>\n    <string name=\"model_fatality_deblur\">Sharpens and removes blur from images while maintaining natural details, ideal for fixing out-of-focus photos.</string>\n    <string name=\"model_unresize_v3\">Intelligently restores images that have been previously resized, recovering lost details and textures.</string>\n    <string name=\"model_liveaction_v1_span\">Optimized for live-action content, reduces compression artifacts and enhances fine details in movie/TV show frames.</string>\n    <string name=\"model_vhs2hd_realplksr\">Converts VHS-quality footage to HD, removing tape noise and enhancing resolution while preserving vintage feel.</string>\n    <string name=\"model_text2hd_v1\">Specialized for text-heavy images and screenshots, sharpens characters and improves readability.</string>\n    <string name=\"model_frankendata_pretrainer\">Advanced upscaling trained on diverse datasets, excellent for general-purpose photo enhancement.</string>\n    <string name=\"model_realwebphoto_v2\">Optimized for web-compressed photos, removes JPEG artifacts and restores natural appearance.</string>\n    <string name=\"model_realwebphoto_v4\">Improved version for web photos with better texture preservation and artifact reduction.</string>\n    <string name=\"model_dat_2x\">2x upscaling with Dual Aggregation Transformer technology, maintains sharpness and natural details.</string>\n    <string name=\"model_dat_3x\">3x upscaling using advanced transformer architecture, ideal for moderate enlargement needs.</string>\n    <string name=\"model_dat_4x\">4x high-quality upscaling with state-of-the-art transformer network, preserves fine details at larger scales.</string>\n    <string name=\"model_nafnet_deblurring\">Removes blur/noise and shakes from photos. General purpose but best on photos.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Restores low-quality images using Swin2SR transformer, optimized for BSRGAN degradation. Great for fixing heavy compression artifacts and enhancing details at 4x scale.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x upscaling with SwinIR transformer trained on BSRGAN degradation. Uses GAN for sharper textures and more natural details in photos and complex scenes.</string>\n    <string name=\"path\">Path</string>\n    <string name=\"merge_pdf\">Merge PDF</string>\n    <string name=\"merge_pdf_sub\">Combine multiple PDF files into one document</string>\n    <string name=\"files_order\">Files Order</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Split PDF</string>\n    <string name=\"split_pdf_sub\">Extract specific pages from PDF document</string>\n    <string name=\"rotate_pdf\">Rotate PDF</string>\n    <string name=\"rotate_pdf_sub\">Fix page orientation permanently</string>\n    <string name=\"pages\">Pages</string>\n    <string name=\"rearrange_pdf\">Rearrange PDF</string>\n    <string name=\"rearrange_pdf_sub\">Drag and drop pages to reorder them</string>\n    <string name=\"hold_drag_drop\">Hold &amp; Drag pages</string>\n    <string name=\"page_numbers\">Page Numbers</string>\n    <string name=\"page_numbers_sub\">Add numbering to your documents automatically</string>\n    <string name=\"label_format\">Label Format</string>\n    <string name=\"pdf_to_text\">PDF to Text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extract plain text from your PDF documents</string>\n    <string name=\"watermark_pdf_sub\">Overlay custom text for branding or security</string>\n    <string name=\"signature\">Signature</string>\n    <string name=\"signature_sub\">Add your electronic signature to any document</string>\n    <string name=\"will_be_for_signature\">This will be used as signature</string>\n    <string name=\"unlock_pdf\">Unlock PDF</string>\n    <string name=\"unlock_pdf_sub\">Remove passwords from your protected files</string>\n    <string name=\"protect_pdf\">Protect PDF</string>\n    <string name=\"protect_pdf_sub\">Secure your documents with strong encryption</string>\n    <string name=\"success\">Success</string>\n    <string name=\"pdf_unlocked\">PDF unlocked, you can save or share it</string>\n    <string name=\"repair_pdf\">Repair PDF</string>\n    <string name=\"repair_pdf_sub\">Attempt to fix corrupted or unreadable documents</string>\n    <string name=\"grayscale\">Grayscale</string>\n    <string name=\"grayscale_pdf_sub\">Convert all document embedded images to grayscale</string>\n    <string name=\"compress_pdf\">Compress PDF</string>\n    <string name=\"compress_pdf_sub\">Optimize your document file size for easier sharing</string>\n    <string name=\"repair_info\">ImageToolbox rebuilds the internal cross-reference table and regenerates the file structure from scratch. This can restore access to many files that \\\"cannot be opened\\\"</string>\n    <string name=\"grayscale_info\">This tool converts all document images to grayscale. Best for printing and reducing file size</string>\n    <string name=\"metadata\">Metadata</string>\n    <string name=\"metadata_pdf_sub\">Edit document properties for better privacy</string>\n    <string name=\"tags\">Tags</string>\n    <string name=\"producer\">Producer</string>\n    <string name=\"author\">Author</string>\n    <string name=\"keywords\">Keywords</string>\n    <string name=\"creator\">Creator</string>\n    <string name=\"privacy_deep_clean\">Privacy Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Clear all available metadata for this document</string>\n    <string name=\"page\">Page</string>\n    <string name=\"deep_ocr\">Deep OCR</string>\n    <string name=\"deep_ocr_sub\">Extract text from document and store it in the one text file using Tesseract engine</string>\n    <string name=\"cant_remove_all\">Can\\'t remove all pages</string>\n    <string name=\"remove_pages_pdf\">Remove PDF pages</string>\n    <string name=\"remove_pages_pdf_sub\">Remove specific pages from PDF document</string>\n    <string name=\"tap_to_remove\">Tap To Remove</string>\n    <string name=\"manually\">Manually</string>\n    <string name=\"crop_pdf\">Crop PDF</string>\n    <string name=\"crop_pdf_sub\">Crop document pages to any bounds</string>\n    <string name=\"flatten_pdf\">Flatten PDF</string>\n    <string name=\"flatten_pdf_sub\">Make PDF unmodifiable by rastering document pages</string>\n    <string name=\"camera_failed_to_open\">Could not start the camera. Please check permissions and make sure it\\'s not being used by another app.</string>\n    <string name=\"extract_images\">Extract Images</string>\n    <string name=\"extract_images_sub\">Extract images embedded in PDFs at their original resolution</string>\n    <string name=\"pdf_no_embedded\">This PDF file doesn’t contain any embedded images</string>\n    <string name=\"extract_images_info\">This tool scans every page and recovers full-quality source images — perfect for saving originals from documents</string>\n    <string name=\"draw_signature\">Draw Signature</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">Use own signature as image to be placed on documents</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Split document with given interval and pack new docuements into zip archive</string>\n    <string name=\"interval\">Interval</string>\n    <string name=\"print_pdf\">Print PDF</string>\n    <string name=\"print_pdf_sub\">Prepare document for printing with custom page size</string>\n    <string name=\"pages_per_sheet\">Pages Per Sheet</string>\n    <string name=\"orientation\">Orientation</string>\n    <string name=\"page_size\">Page Size</string>\n    <string name=\"margin\">Margin</string>\n    <string name=\"bloom\">Bloom</string>\n    <string name=\"soft_knee\">Soft Knee</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimized for anime and cartoons. Fast upscaling with improved natural colors and fewer artifacts</string>\n    <string name=\"one_ui\" translatable=\"false\">One UI</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 like style</string>\n    <string name=\"calculate_hint\">Enter basic math symbols here to calculate the desired value (e.g. (5+5)*10)</string>\n    <string name=\"math_expression\">Math expression</string>\n    <string name=\"pick_up_to_n_collage_images\">Pick up to %1$s images</string>\n    <string name=\"keep_date_time\">Keep Date Time</string>\n    <string name=\"keep_date_time_sub\">Always preserve exif tags related to date and time, works independently of keep exif option</string>\n    <string name=\"background_color_for_alpha_formats\">Background Color For Alpha Formats</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Adds ability to set background color for every image format with alpha support, when disabled this available for non alpha ones only</string>\n    <string name=\"failed_to_open\">Failed to open</string>\n    <string name=\"layer_alpha\">Layer alpha</string>\n    <string name=\"horizontal_flip\">Horizontal Flip</string>\n    <string name=\"vertical_flip\">Vertical Flip</string>\n    <string name=\"remove_annotations\">Remove annotations</string>\n    <string name=\"remove_annotations_sub\">Remove selected annotation types such as links, comments, highlights, shapes, or form fields from the PDF pages</string>\n    <string name=\"annotation_link\">Hyperlinks</string>\n    <string name=\"annotation_file_attachment\">File Attachments</string>\n    <string name=\"annotation_line\">Lines</string>\n    <string name=\"annotation_popup\">Popups</string>\n    <string name=\"annotation_stamp\">Stamps</string>\n    <string name=\"annotation_shapes\">Shapes</string>\n    <string name=\"annotation_text\">Text Notes</string>\n    <string name=\"annotation_text_markup\">Text Markup</string>\n    <string name=\"annotation_widget\">Form Fields</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">Unknown</string>\n    <string name=\"annotations\">Annotations</string>\n</resources>\n"
  },
  {
    "path": "core/resources/src/main/res/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <style name=\"Theme.ImageToolbox\" parent=\"Theme.Material3.DayNight.NoActionBar\">\n        <item name=\"android:forceDarkAllowed\" tools:targetApi=\"q\">false</item>\n    </style>\n\n    <style name=\"Theme.ImageToolbox.Launcher\" parent=\"Theme.SplashScreen\">\n        <item name=\"windowSplashScreenBackground\">@color/ic_launcher_background</item>\n        <item name=\"windowSplashScreenAnimatedIcon\">@drawable/ic_logo_animated</item>\n        <item name=\"postSplashScreenTheme\">@style/Theme.ImageToolbox</item>\n    </style>\n\n    <style name=\"TransparentActivity\" parent=\"Theme.Material3.DayNight.NoActionBar\">\n        <item name=\"android:windowBackground\">@android:color/transparent</item>\n        <item name=\"android:colorBackgroundCacheHint\">@null</item>\n        <item name=\"android:windowIsTranslucent\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowIsFloating\">true</item>\n        <item name=\"android:backgroundDimEnabled\">false</item>\n    </style>\n\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ar/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"language\">اللغة</string>\n    <string name=\"amoled_mode\">وضع Amoled</string>\n    <string name=\"amoled_mode_sub\">إذا فُعّل لون الأسطح فسيتم ضبطه على الظلام المطلق في الوضع الليلي</string>\n    <string name=\"color_scheme\">نظام الألوان</string>\n    <string name=\"color_red\">أحمر</string>\n    <string name=\"color_green\">أخضر</string>\n    <string name=\"color_blue\">أزرق</string>\n    <string name=\"clipboard_paste_invalid_color_code\">ألصِق كود aRGB صالح</string>\n    <string name=\"clipboard_paste_invalid_empty\">لا شيئ للصقه</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">لا يمكن تغيير مخطط ألوان التطبيق أثناء تشغيل الألوان الديناميكية</string>\n    <string name=\"pick_accent_color\">سيعتمد سمة التطبيق على اللون الذي ستختاره</string>\n    <string name=\"smth_went_wrong\">حدث خطأ ما: %1$s</string>\n    <string name=\"size\">الحجم %1$s</string>\n    <string name=\"loading\">تحميل…</string>\n    <string name=\"image_too_large_preview\">الصورة أكبر من تُعايَن، ولكن ستُحفَظ بأي حال.</string>\n    <string name=\"pick_image\">اخنر صورة للبدء</string>\n    <string name=\"width\">العرض %1$s</string>\n    <string name=\"height\">الارتفاع %1$s</string>\n    <string name=\"quality\">الجودة</string>\n    <string name=\"extension\">الصيغة</string>\n    <string name=\"resize_type\">نوع إعادة التحجيم</string>\n    <string name=\"explicit\">واضح</string>\n    <string name=\"flexible\">مرن</string>\n    <string name=\"pick_image_alt\">اختر صورة</string>\n    <string name=\"app_closing_sub\">أمتأكد برغبتك بإغلاق التطبيق؟</string>\n    <string name=\"app_closing\">يُغلق التطبيق</string>\n    <string name=\"stay\">ابقِ</string>\n    <string name=\"close\">أغلِق</string>\n    <string name=\"reset_image\">صفّر الصورة</string>\n    <string name=\"reset_image_sub\">سيتم التراجع عن تغييرات الصورة لوضعها الاساسي</string>\n    <string name=\"values_reset\">صفّر القيم بشكل صحيح</string>\n    <string name=\"reset\">صفّر</string>\n    <string name=\"something_went_wrong\">حدث خطأ ما</string>\n    <string name=\"restart_app\">أعد تشغيل التطبيق</string>\n    <string name=\"copied\">نُسخ إلى الحافظة</string>\n    <string name=\"exception\">إستثناء</string>\n    <string name=\"edit_exif\">حرِّر البيانات الوصفية</string>\n    <string name=\"ok\">حسناً</string>\n    <string name=\"no_exif\">لم يتم العثور على بيانات وصفية</string>\n    <string name=\"add_tag\">أضف وسم</string>\n    <string name=\"save\">احفظ</string>\n    <string name=\"clear\">امحُ</string>\n    <string name=\"clear_exif\">امحُ البيانات الوصفية</string>\n    <string name=\"cancel\">ألغِ</string>\n    <string name=\"clear_exif_sub\">سيتم مسح جميع البيانات الوصفية للصورة. لا يمكن التراجع عن هذا الإجراء!</string>\n    <string name=\"presets\">الإعدادات المسبقة</string>\n    <string name=\"crop\">اقتصاص</string>\n    <string name=\"image_not_saved\">جارِ الحفظ..</string>\n    <string name=\"image_not_saved_sub\">ستفقد جميع التغييرات غير المحفوظة، إذا غادرت الآن.</string>\n    <string name=\"check_source_code\">شفرة المصدر</string>\n    <string name=\"check_source_code_sub\">احصل على آخر التحديثات وتناقش عن البرنامج من أعطال ومما يتعلق به</string>\n    <string name=\"single_edit\">تحرير واحد</string>\n    <string name=\"single_edit_sub\">تعديل وتحجيم وتحرير صورة واحدة</string>\n    <string name=\"pick_color\">منتقي الألوان</string>\n    <string name=\"pick_color_sub\">حدد لونًا من صورة، انسخ أو شارك</string>\n    <string name=\"image\">صورة</string>\n    <string name=\"color\">اللون</string>\n    <string name=\"color_copied\">نُسخ اللون</string>\n    <string name=\"crop_sub\">اقتصاص الصورة بأي حدود</string>\n    <string name=\"version\">النسخة</string>\n    <string name=\"keep_exif\">حافظ على البيانات الوصفية</string>\n    <string name=\"images\">الصور: %d</string>\n    <string name=\"change_preview\">غيّر المعاينة</string>\n    <string name=\"remove\">أزِل</string>\n    <string name=\"palette_sub\">ولّد لوحة ألوان من صورة معينة</string>\n    <string name=\"generate_palette\">ولّد لوحة ألوان</string>\n    <string name=\"palette\">لوحة ألوان</string>\n    <string name=\"update\">تحديث</string>\n    <string name=\"new_version\">نسخة جديدة %1$s</string>\n    <string name=\"unsupported_type\">نوع غير مدعوم: %1$s</string>\n    <string name=\"no_palette\">لا يمكن توليد لوحة ألوان للصورة المحدّدة</string>\n    <string name=\"original\">الاصلية</string>\n    <string name=\"folder\">مجلد الحفظ</string>\n    <string name=\"def\">الافتراضي</string>\n    <string name=\"custom\">مخصص</string>\n    <string name=\"unspecified\">غير محدد</string>\n    <string name=\"device_storage\">تخزين الجهاز</string>\n    <string name=\"by_bytes_resize\">تغيير حجم الصورة بناء على حجم الملف</string>\n    <string name=\"max_bytes\">الحجم الأقصى بالكيلو بايت</string>\n    <string name=\"by_bytes_resize_sub\">غيّر حجم الصورة باتباع الحجم المحدد بالكيلو بايت</string>\n    <string name=\"compare\">قارن</string>\n    <string name=\"compare_sub\">قارن بين صورتين معينتين</string>\n    <string name=\"pick_two_images\">اختر صورتين للبدء</string>\n    <string name=\"pick_images\">اختر الصور</string>\n    <string name=\"settings\">الاعدادات</string>\n    <string name=\"night_mode\">الوضع الليلي</string>\n    <string name=\"dark\">مظلم</string>\n    <string name=\"light\">مضيء</string>\n    <string name=\"system\">نظام</string>\n    <string name=\"dynamic_colors\">ألوان ديناميكية</string>\n    <string name=\"customization\">التخصيص</string>\n    <string name=\"allow_image_monet\">وفقا لالوان الصورة المختارة</string>\n    <string name=\"allow_image_monet_sub\">في حال التفعيل، عند اختيار صورة لتحريرها، سيتم تكييف ألوان التطبيق لتناسب هذه الصورة.</string>\n    <string name=\"about_app\">حول التطبيق</string>\n    <string name=\"issue_tracker\">متعقب المشاكل</string>\n    <string name=\"help_translate\">مساعدة في الترجمة</string>\n    <string name=\"no_updates\">لم يتم العثور على تحديثات</string>\n    <string name=\"issue_tracker_sub\">أرسل تقرير بمشكلتك وطلباتك من هنا</string>\n    <string name=\"search_here\">ابحث هنا</string>\n    <string name=\"help_translate_sub\">تصحيح أخطاء الترجمة أو ترجمة المشروع إلى لغات أخرى</string>\n    <string name=\"nothing_found_by_search\">لم يتم العثور على شيء من خلال الاستعلام الخاص بك</string>\n    <string name=\"dynamic_colors_sub\">إذا فعّلته، فسيتم تكييف ألوان التطبيق مع ألوان خلفية الشاشة</string>\n    <string name=\"failed_to_save\">فشل حفظ %d صورة (صور)</string>\n    <string name=\"surface\">سطح</string>\n    <string name=\"donation_sub\">هذا التطبيق مجاني تمامًا، ولكن إذا كنت ترغب في دعم تطوير المشروع، يمكنك النقر هنا</string>\n    <string name=\"fab_alignment\">محاذاة FAB</string>\n    <string name=\"check_updates\">تحقق من وجود تحديثات</string>\n    <string name=\"check_updates_sub\">في حال التفعيل، ستظهر لك نافذة التحديث عند تشغيل التطبيق</string>\n    <string name=\"values\">القيم</string>\n    <string name=\"add\">أضف</string>\n    <string name=\"primary\">أساسي</string>\n    <string name=\"tertiary\">ثالث</string>\n    <string name=\"secondary\">ثانوي</string>\n    <string name=\"permission\">إذن</string>\n    <string name=\"grant\">منح</string>\n    <string name=\"permission_sub\">يحتاج التطبيق إلى الوصول إلى وحدة التخزين الخاصة بك لحفظ الصور لكي يعمل، وهذا أمر ضروري. يُرجى منح الإذن في مربع الحوار التالي.</string>\n    <string name=\"grant_permission_manual\">يحتاج التطبيق إلى هذا الإذن للعمل، يُرجى منحه يدويًا</string>\n    <string name=\"border_thickness\">سمك الحدود</string>\n    <string name=\"external_storage\">تخزين خارجي</string>\n    <string name=\"monet_colors\">ألوان مونيه</string>\n    <string name=\"zoom\">تكبير الصورة</string>\n    <string name=\"prefix\">بادئة</string>\n    <string name=\"filename\">اسم الملف</string>\n    <string name=\"share\">شارك</string>\n    <string name=\"emoji\">تعبيري</string>\n    <string name=\"emoji_sub\">حدد الرموز التعبيرية التي سيتم عرضها على الشاشة الرئيسية</string>\n    <string name=\"add_file_size\">أضف حجم الملف</string>\n    <string name=\"add_file_size_sub\">إذا فُعّل، يضيف عرض وارتفاع الصورة المحفوظة إلى اسم الملف الناتج</string>\n    <string name=\"delete_exif\">احذف EXIF</string>\n    <string name=\"delete_exif_sub\">احذف البيانات الوصفية EXIF من أي مجموعة صور</string>\n    <string name=\"image_preview\">معاينة الصورة</string>\n    <string name=\"image_source\">مصدر الصورة</string>\n    <string name=\"file_explorer_picker_sub\">استخدم نية GetContent لاختيار صورة. تعمل في كل مكان، لكن من المعروف أن بها مشاكل في استقبال الصور المختارة على بعض الأجهزة. هذا ليس خطئي.</string>\n    <string name=\"options_arrangement\">ترتيب الخيارات</string>\n    <string name=\"order\">رتب</string>\n    <string name=\"emojis_count\">عدد الرموز التعبيرية</string>\n    <string name=\"sequence_num\">تسلسل</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"add_original_filename\">أضف اسم الملف الأصلي</string>\n    <string name=\"add_original_filename_sub\">إذا فُعّل، يضيف اسم الملف الأصلي في اسم صورة المخرجات</string>\n    <string name=\"image_preview_sub\">معاينة أي نوع من الصور: GIF و SVG وما إلى ذلك</string>\n    <string name=\"photo_picker\">منتقي الصور</string>\n    <string name=\"gallery_picker\">معرض الصور</string>\n    <string name=\"file_explorer_picker\">مستكشف الملفات</string>\n    <string name=\"photo_picker_sub\">قد يعمل منتقي الصور الحديث من Android الذي يظهر في الجزء السفلي من الشاشة فقط على adnroid 12+ ولديه أيضًا مشكلات في تلقي بيانات EXIF الوصفية</string>\n    <string name=\"gallery_picker_sub\">منتقي صور المعرض البسيط، لن تعمل إلا إذا كان لديك تطبيق يوفر خاصية إنتقاء الوسائط</string>\n    <string name=\"edit\">حرِّر</string>\n    <string name=\"order_sub\">يحدد ترتيب الأدوات على الشاشة الرئيسية</string>\n    <string name=\"filename_not_work_with_photopicker\">إضافة اسم الملف الأصلي لا تعمل إذا تم تحديد مصدر صورة منتقي الصور</string>\n    <string name=\"brightness\">سطوع</string>\n    <string name=\"contrast\">مقابلة</string>\n    <string name=\"hue\">مسحة</string>\n    <string name=\"sepia\">بني داكن</string>\n    <string name=\"negative\">سلبي</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"line_width\">عرض الخط</string>\n    <string name=\"sobel_edge\">حافة سوبل</string>\n    <string name=\"radius\">نصف القطر</string>\n    <string name=\"scale\">حجم</string>\n    <string name=\"stack_blur\">طمس بطيء</string>\n    <string name=\"sketch\">رسم</string>\n    <string name=\"threshold\">عتبة</string>\n    <string name=\"replace_sequence_number\">استبدل رقم التسلسل</string>\n    <string name=\"replace_sequence_number_sub\">إذا فُعّل، يستبدل الطابع الزمني القياسي برقم تسلسل الصورة عند استخدام المعالجة الدفعية</string>\n    <string name=\"load_image_from_net\">تحميل الصورة من الانترنت</string>\n    <string name=\"load_image_from_net_sub\">حمّل أي صورة من الإنترنت لمعاينتها وتقريبها/تبعيدها وتحريرها وحفظها إذا أردت.</string>\n    <string name=\"no_image\">لا توجد صورة</string>\n    <string name=\"image_link\">رابط الصورة</string>\n    <string name=\"fill\">يملأ</string>\n    <string name=\"fit\">ملائمة</string>\n    <string name=\"explicit_description\">تغيير حجم الصور إلى العرض واﻹرتفاع المٌعطى. قد تتغير نسبة العرض إلى الارتفاع للصور.</string>\n    <string name=\"flexible_description\">يغير حجم الصور ذات جانب طويل إلى العرض أو الارتفاع المٌعطى.سيتم إجراء جميع حسابات الحجم بعد الحفظ. سيتم الحفاظ على نسبة العرض إلى الارتفاع.</string>\n    <string name=\"saturation\">التشبع</string>\n    <string name=\"add_filter\">أضف تصفية</string>\n    <string name=\"filter\">التصفية</string>\n    <string name=\"filter_sub\">طبّق سلسلة تصفية على الصور</string>\n    <string name=\"filters\">التصفيات</string>\n    <string name=\"light_aka_illumination\">ضوء</string>\n    <string name=\"color_filter\">تصفية اللون</string>\n    <string name=\"alpha\">ألفا</string>\n    <string name=\"exposure\">التعرض</string>\n    <string name=\"white_balance\">توازن اللون الأبيض</string>\n    <string name=\"temperature\">درجة حرارة</string>\n    <string name=\"tint\">لون</string>\n    <string name=\"monochrome\">أحادي اللون</string>\n    <string name=\"gamma\">جاما</string>\n    <string name=\"highlights_shadows\">يسلط الضوء والظلال</string>\n    <string name=\"highlights\">يسلط الضوء</string>\n    <string name=\"shadows\">الظلال</string>\n    <string name=\"haze\">ضباب</string>\n    <string name=\"effect\">تأثير</string>\n    <string name=\"distance\">مسافة</string>\n    <string name=\"slope\">ميل</string>\n    <string name=\"sharpen\">شحذ</string>\n    <string name=\"solarize\">شمسي</string>\n    <string name=\"vibrance\">حيوية</string>\n    <string name=\"black_and_white\">اسود و ابيض</string>\n    <string name=\"spacing\">تباعد</string>\n    <string name=\"blur\">طمس</string>\n    <string name=\"halftone\">نصفية</string>\n    <string name=\"cga_colorspace\">مساحة ألوان GCA</string>\n    <string name=\"gaussian_blur\">التمويه الضبابي</string>\n    <string name=\"box_blur\">مربع طمس</string>\n    <string name=\"bilaterial_blur\">طمس ثنائي الجوهر</string>\n    <string name=\"emboss\">زخرف</string>\n    <string name=\"laplacian\">لابلاسيان</string>\n    <string name=\"vignette\">المقالة القصيرة</string>\n    <string name=\"start\">يبدأ</string>\n    <string name=\"end\">نهاية</string>\n    <string name=\"kuwahara\">تنعيم الكوهرة</string>\n    <string name=\"distortion\">تشوه</string>\n    <string name=\"angle\">زاوية</string>\n    <string name=\"swirl\">دوامة</string>\n    <string name=\"bulge\">انتفاخ</string>\n    <string name=\"dilation\">تمدد</string>\n    <string name=\"sphere_refraction\">انكسار الكرة</string>\n    <string name=\"refractive_index\">معامل الانكسار</string>\n    <string name=\"glass_sphere_refraction\">انكسار الكرة الزجاجية</string>\n    <string name=\"color_matrix\">مصفوفة الألوان</string>\n    <string name=\"opacity\">التعتيم</string>\n    <string name=\"limits_resize\">تغيير الحجم بحدود الصورة</string>\n    <string name=\"limits_resize_sub\">غيّر حجم الصور المحدّدة لتتبع حدود العرض والارتفاع المحددة مع حفظ نسبة العرض إلى الارتفاع</string>\n    <string name=\"quantizationLevels\">مستويات التكميم</string>\n    <string name=\"smooth_toon\">السلس تون</string>\n    <string name=\"toon\">تون</string>\n    <string name=\"posterize\">تتالي</string>\n    <string name=\"content_scale\">مقياس المحتوى</string>\n    <string name=\"convolution3x3\">التفاف 3x3</string>\n    <string name=\"rgb_filter\">تصفية RGB</string>\n    <string name=\"color_balance\">توازن الالوان</string>\n    <string name=\"non_maximum_suppression\">عدم الحد الأقصى للقمع</string>\n    <string name=\"weak_pixel_inclusion\">إدراج ضعيف للبكسل</string>\n    <string name=\"lookup\">ابحث عن</string>\n    <string name=\"false_color\">لون مزيف</string>\n    <string name=\"first_color\">اللون الأول</string>\n    <string name=\"second_color\">اللون الثاني</string>\n    <string name=\"reorder\">إعادة ترتيب</string>\n    <string name=\"fast_blur\">طمس سريع</string>\n    <string name=\"blur_size\">حجم التمويه</string>\n    <string name=\"blur_center_x\">مركز طمس x</string>\n    <string name=\"blur_center_y\">مركز طمس ذ</string>\n    <string name=\"zoom_blur\">زووم طمس</string>\n    <string name=\"luminance_threshold\">عتبة النصوع</string>\n    <string name=\"draw\">الرسم</string>\n    <string name=\"paint_color\">لون الطلاء</string>\n    <string name=\"activate_files\">لقد عطلت تطبيق الملفات، فعّله لاستخدام هذه الميزة</string>\n    <string name=\"draw_sub\">ارسم على صورة كما في دفتر الرسم، أو ارسم على الخلفية نفسها</string>\n    <string name=\"paint_alpha\">طلاء ألفا</string>\n    <string name=\"draw_on_image\">ارسم على صورة</string>\n    <string name=\"draw_on_image_sub\">اختيار صورة وارسم شيئًا عليها</string>\n    <string name=\"draw_on_background\">ارسم على خلفية</string>\n    <string name=\"draw_on_background_sub\">اختيار لون الخلفية وارسم فوقها</string>\n    <string name=\"background_color\">لون الخلفية</string>\n    <string name=\"cipher\">الشفرة</string>\n    <string name=\"cipher_sub\">تعمية وفك تعمية أي ملف (ليس فقط الصورة) بناءً على مختلف خوارزميات التعمية المتاحة</string>\n    <string name=\"pick_file\">اختر الملف</string>\n    <string name=\"encrypt\">تشفير</string>\n    <string name=\"decrypt\">فك تشفير</string>\n    <string name=\"pick_file_to_start\">اختر ملف للبدء</string>\n    <string name=\"decryption\">فك التشفير</string>\n    <string name=\"encryption\">التشفير</string>\n    <string name=\"key\">مفتاح</string>\n    <string name=\"file_proceed\">متابعة الملف</string>\n    <string name=\"store_file_desc\">خزّن هذا الملف على جهازك أو استخدم إجراء المشاركة لوضعه في أي مكان تريده</string>\n    <string name=\"features\">سمات</string>\n    <string name=\"compatibility_sub\">يرجى ملاحظة أن التوافق مع برامج أو خدمات تشفير الملفات الأخرى غير مضمون. قد يكون هناك اختلاف طفيف في معالجة المفتاح أو تكوين التشفير من أسباب عدم التوافق.</string>\n    <string name=\"implementation\">تطبيق</string>\n    <string name=\"compatibility\">التوافق</string>\n    <string name=\"features_sub\">تشفير الملفات على أساس كلمة المرور. يمكن تخزين الملفات التي تمت متابعتها في دليل Crypto أو مشاركتها. يمكن أيضًا فتح الملفات التي تم فك تشفيرها مباشرة.</string>\n    <string name=\"implementation_sub\">AES-256، وضع GCM، بدون حشو، 12 بايت من المتجهات الأولية العشوائية افتراضيًا. يمكنك اختيار الخوارزمية المطلوبة. تُستخدم المفاتيح كقيم تجزئة SHA-3 بطول 256 بت.</string>\n    <string name=\"file_size\">حجم الملف</string>\n    <string name=\"file_size_sub\">الحد الأقصى لحجم الملف مقيد بنظام التشغيل أندرويد والذاكرة المتاحة، والتي تعتمد بشكل واضح على جهازك. \\nيُرجى ملاحظة: الذاكرة ليست تخزين.</string>\n    <string name=\"group_options_by_type_sub\">خيارات المجموعات على الشاشة الرئيسية من نوعها بدلاً من ترتيب القائمة المخصص</string>\n    <string name=\"create\">أنشئ</string>\n    <string name=\"image_size_warning\">محاولة حفظ الصورة بالعرض والارتفاع المحددين قد تتسبب في حدوث خطأ في الذاكرة. قم بذلك على مسؤوليتك الخاصة.</string>\n    <string name=\"auto_cache_clearing_sub\">إذا فُعّل، سيتم مسح ذاكرة التخزين المؤقت للتطبيق عند بدء التشغيل</string>\n    <string name=\"tools\">أدوات</string>\n    <string name=\"screenshot\">لقطة شاشة</string>\n    <string name=\"group_options_by_type\">خيارات المجموعة حسب النوع</string>\n    <string name=\"cache_size\">حجم ذاكرة التخزين المؤقت</string>\n    <string name=\"found_s\">عُثر %1$s</string>\n    <string name=\"auto_cache_clearing\">مسح ذاكرة التخزين المؤقت التلقائي</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">لا يمكن تغيير الترتيب أثناء تمكين تجميع الخيارات</string>\n    <string name=\"edit_screenshot\">حرِّر لقطة الشاشة</string>\n    <string name=\"secondary_customization\">التخصيص الثانوي</string>\n    <string name=\"fallback_option\">الخيار الاحتياطي</string>\n    <string name=\"skip\">يتخطى</string>\n    <string name=\"copy\">ينسخ</string>\n    <string name=\"warning_bytes\">يمكن أن يكون الحفظ في وضع %1$s غير مستقر، لأنه تنسيق غير ضياع</string>\n    <string name=\"invalid_password_or_not_encrypted\">كلمة مرور غير صالحة أو الملف المختار غير مشفر</string>\n    <string name=\"cache\">مخبأ</string>\n    <string name=\"reset_settings_sub\">سيؤدي هذا إلى إعادة إعداداتك إلى القيم الافتراضية، لاحظ أنه لا يمكن التراجع عن هذا بدون ملف النسخ الاحتياطي من الخيار أعلاه</string>\n    <string name=\"tg_chat\">محادثة تيليجرام</string>\n    <string name=\"crop_mask\">قناع القص</string>\n    <string name=\"nature_and_animals\">الطبيعة والحيوان</string>\n    <string name=\"food_and_drink\">الغذاء والشرب</string>\n    <string name=\"contact_me\">اتصل بي</string>\n    <string name=\"backup_sub\">انسخ احتياطيًا إعدادات تطبيقك إلى الملف</string>\n    <string name=\"corrupted_file_or_not_a_backup\">ملف تالف أو ليس نسخة احتياطية</string>\n    <string name=\"presets_sub\" formatted=\"false\">إذا حدّدت الإعداد المسبق 125، فسيتم حفظ الصورة بنسبة 125% من حجم الصورة الأصلية. أما إذا اخترت الإعداد المسبق 50، فسيتم حفظ الصورة بنسبة 50% من حجمها.</string>\n    <string name=\"font_scale\">مقياس الخط</string>\n    <string name=\"restore\">استعادة</string>\n    <string name=\"tg_chat_sub\">ناقش حول التطبيق واحصل على تعليقات من المستخدمين الآخرين، ويمكنك هنا أيضًا الحصول على تحديثات تجريبية</string>\n    <string name=\"alphabet_and_numbers\">ا أ إ آ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي 0123456789 !؟</string>\n    <string name=\"delete\">احذف</string>\n    <string name=\"aspect_ratio\">نسبة الأبعاد</string>\n    <string name=\"delete_color_scheme_warn\">أنت على وشك حذف نظام الألوان المحدد، لا يمكن التراجع عن هذه العملية</string>\n    <string name=\"saved_to_without_filename\">حُفظ في المجلد %1$s</string>\n    <string name=\"settings_restored\">اُستعيدت الإعدادات بنجاح</string>\n    <string name=\"backup_and_restore\">النسخ الاحتياطي والاستعادة</string>\n    <string name=\"backup\">نسخ احتياطي</string>\n    <string name=\"emotions\">المشاعر</string>\n    <string name=\"saved_to\">حُفظ في المجلد %1$s بالاسم %2$s</string>\n    <string name=\"image_crop_mask_sub\">استخدم هذا النوع من القناع لإنشاء قناع من صورة معينة، لاحظ أنه يجب أن يحتوي على قناة ألفا</string>\n    <string name=\"randomize_filename\">اسم عشوائي للملف</string>\n    <string name=\"text\">النص</string>\n    <string name=\"defaultt\">الإفتراضي</string>\n    <string name=\"delete_color_scheme_title\">احذف المخطط</string>\n    <string name=\"font\">الخط</string>\n    <string name=\"using_large_fonts_warn\">قد يؤدي استخدام مقاييس الخطوط الكبيرة إلى حدوث خلل في واجهة المستخدم ولن يتم إصلاحه، استخدمه إذا كنت تريد ذلك فقط</string>\n    <string name=\"randomize_filename_sub\">إذا فُعّل اسم ملف الإخراج فسيكون عشوائيًا بشكل تام</string>\n    <string name=\"restore_sub\">استعادة إعدادات التطبيق من الملف الذي ولّد مسبقًا</string>\n    <string name=\"presets_sub_bytes\">يحدّد الإعداد المسبق هنا النسبة المئوية لملف الإخراج، أي إذا حددت 50 إعدادًا مسبقًا على صورة بحجم 5 ميجابايت، فستحصل على صورة بحجم 2.5 ميجابايت بعد الحفظ</string>\n    <string name=\"enhanced_pixelation\">تعزيز البكسل</string>\n    <string name=\"diamond_pixelation\">بكسل الماس</string>\n    <string name=\"draw_mode\">وضع الرسم</string>\n    <string name=\"trim_image_sub\">سيتم قطع المساحات الشفافة حول الصورة</string>\n    <string name=\"auto_erase_background\">مسح الخلفية تلقائيًا</string>\n    <string name=\"pipette\">ماصة</string>\n    <string name=\"restore_background\">استعادة الخلفية</string>\n    <string name=\"keep_exif_sub\">سيتم الاحتفاظ بالبيانات الوصفية للصورة الأصلية</string>\n    <string name=\"updates\">التحديثات</string>\n    <string name=\"allow_betas\">السماح بالإصدارات التجريبية</string>\n    <string name=\"segmentation_mode_osd_only\">الاتجاه &amp; اكتشاف البرنامج النصي فقط</string>\n    <string name=\"segmentation_mode_auto_osd\">التوجيه التلقائي &amp; اكتشاف البرنامج النصي</string>\n    <string name=\"segmentation_mode_auto_only\">السيارات فقط</string>\n    <string name=\"segmentation_mode_auto\">آلي</string>\n    <string name=\"segmentation_mode_single_block\">كتلة واحدة</string>\n    <string name=\"segmentation_mode_single_line\">سطر واحد</string>\n    <string name=\"segmentation_mode_single_word\">كلمة واحدة</string>\n    <string name=\"segmentation_mode_circle_word\">كلمة الدائرة</string>\n    <string name=\"segmentation_mode_single_char\">حرف واحد</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">اتجاه النص المتفرق &amp; اكتشاف البرنامج النصي</string>\n    <string name=\"segmentation_mode_raw_line\">خط خام</string>\n    <string name=\"glitch\">خلل</string>\n    <string name=\"amount\">كمية</string>\n    <string name=\"seed\">بذرة</string>\n    <string name=\"delete_mask_warn\">أنت على وشك حذف قناع التصفية المحددة. هذه العملية لا يمكن التراجع عنها</string>\n    <string name=\"delete_mask\">احذف القناع</string>\n    <string name=\"no_such_directory\">لم يُعثر على دليل \\\"%1$s\\\"، لقد قمنا بتحويله إلى الدليل الافتراضي، يُرجى حفظ الملف مرة أخرى</string>\n    <string name=\"clipboard\">الحافظة</string>\n    <string name=\"overwrite_file_requirements\">لاستبدال الملفات، تحتاج إلى استخدام مصدر الصورة \\\"Explorer\\\"، حاول إعادة اختيار الصور، لقد قمنا بتغيير مصدر الصورة إلى المصدر المطلوب</string>\n    <string name=\"empty\">فارغ</string>\n    <string name=\"search_option\">يبحث</string>\n    <string name=\"free\">حر</string>\n    <string name=\"images_overwritten\">كُتب فوق الصور في الوجهة الأصلية</string>\n    <string name=\"activities\">أنشطة</string>\n    <string name=\"draw_arrows_sub\">إذا فُعِّل مسار الرسم فسيتم تمثيله كسهم يشير</string>\n    <string name=\"crop_description\">سيتم اقتصاص الصور من المنتصف حسب الحجم الذي تم إدخاله. سيتم توسيع اللوحة القماشية بلون الخلفية المحدد إذا كانت الصورة أصغر من الأبعاد المدخلة.</string>\n    <string name=\"donation\">هبة</string>\n    <string name=\"horizontal\">أفقي</string>\n    <string name=\"vertical\">رَأسِيّ</string>\n    <string name=\"scale_small_images_to_large_sub\">سيتم تغيير حجم الصور الصغيرة إلى أكبر صورة في التسلسل إذا تم تمكينها</string>\n    <string name=\"blur_edges_sub\">رسم حواف غير واضحة أسفل الصورة الأصلية لملء الفراغات حولها بدلاً من لون واحد إذا تم تمكينه</string>\n    <string name=\"stroke_pixelation\">بكسل السكتة الدماغية</string>\n    <string name=\"enhanced_diamond_pixelation\">تعزيز بكسل الماس</string>\n    <string name=\"tolerance\">تسامح</string>\n    <string name=\"color_to_replace\">اللون للاستبدال</string>\n    <string name=\"target_color\">اللون المستهدف</string>\n    <string name=\"color_to_remove\">اللون المراد إزالته</string>\n    <string name=\"lock_draw_orientation_sub\">إذا فُعِّل في وضع الرسم، فلن تدور الشاشة</string>\n    <string name=\"palette_style\">نمط اللوحة</string>\n    <string name=\"tonal_spot\">بقعة نغمية</string>\n    <string name=\"neutral\">حيادي</string>\n    <string name=\"vibrant\">نابض بالحياة</string>\n    <string name=\"expressive\">معبرة</string>\n    <string name=\"rainbow\">قوس المطر</string>\n    <string name=\"fruit_salad\">سلطة فواكه</string>\n    <string name=\"fidelity\">الاخلاص</string>\n    <string name=\"content\">محتوى</string>\n    <string name=\"tonal_spot_sub\">نمط اللوحة الافتراضي، فهو يسمح بتخصيص جميع الألوان الأربعة، والبعض الآخر يسمح لك بتعيين اللون الرئيسي فقط</string>\n    <string name=\"neutral_sub\">نمط لوني أكثر قليلاً من اللون الأحادي</string>\n    <string name=\"vibrant_sub\">سمة عالية، والألوان هي الحد الأقصى للوحة الأساسية، وزيادة للآخرين</string>\n    <string name=\"playful_scheme\">سمة مرحة - لا يظهر تدرج اللون المصدر في السمة</string>\n    <string name=\"monochrome_sub\">سمة أحادية اللون، الألوان هي أسود / أبيض / رمادي بحت</string>\n    <string name=\"content_sub\">مخطط يضع اللون المصدر في Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">مخطط مشابه جدًا لنظام المحتوى</string>\n    <string name=\"disabled\">عاجز</string>\n    <string name=\"both\">كلاهما</string>\n    <string name=\"invert_colors_sub\">يستبدل ألوان السمة بالألوان السلبية إذا فُعّلت</string>\n    <string name=\"search_option_sub\">تمكن القدرة على البحث خلال جميع الأدوات المتاحة على الشاشة الرئيسية</string>\n    <string name=\"mask_preview_sub\">سيتم عرض قناع التصفية المرسوم ليظهر لك النتيجة التقريبية</string>\n    <string name=\"inverse_fill_type_sub\">إذا فُعّل، فسيتم تصفية كافة المناطق غير المقنعة بدلاً من السلوك الافتراضي</string>\n    <string name=\"simple_variants\">المتغيرات البسيطة</string>\n    <string name=\"highlighter\">قلم تمييز</string>\n    <string name=\"pen\">قلم</string>\n    <string name=\"privacy_blur\">طمس الخصوصية</string>\n    <string name=\"neon_sub\">أضف بعض التأثير المتوهج إلى رسوماتك</string>\n    <string name=\"pen_sub\">الافتراضي واحد، أبسط - فقط اللون</string>\n    <string name=\"pixelation_sub\">يشبه تمويه الخصوصية، ولكنه يتقطّع بدلاً من التعتيم</string>\n    <string name=\"switches_shadow\">مفاتيح</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">أزرار</string>\n    <string name=\"sliders_shadow_sub\">رسم ظل خلف أشرطة التمرير</string>\n    <string name=\"switches_shadow_sub\">رسم ظل خلف المفاتيح</string>\n    <string name=\"fabs_shadow_sub\">رسم ظل خلف أزرار الإجراءات العائمة</string>\n    <string name=\"buttons_shadow_sub\">رسم ظل خلف الأزرار</string>\n    <string name=\"app_bars_shadow\">أشرطة التطبيقات</string>\n    <string name=\"app_bars_shadow_sub\">رسم ظل خلف أشرطة التطبيقات</string>\n    <string name=\"auto_rotate_limits\">الدوران التلقائي</string>\n    <string name=\"auto_rotate_limits_sub\">يسمح باعتماد مربع الحد لتوجيه الصورة</string>\n    <string name=\"free_drawing\">الرسم الحر</string>\n    <string name=\"double_arrow\">سهم مزدوج</string>\n    <string name=\"double_line_arrow_sub\">رسم سهمًا مزدوجًا من نقطة البداية إلى نقطة النهاية كخط</string>\n    <string name=\"stitch_mode\">وضع الغرزة</string>\n    <string name=\"rows_count\">عدد الصفوف</string>\n    <string name=\"columns_count\">عدد الأعمدة</string>\n    <string name=\"auto_pin\">دبوس تلقائي</string>\n    <string name=\"auto_pin_sub\">يضيف الصورة المحفوظة تلقائيًا إلى الحافظة إذا حُفظت</string>\n    <string name=\"vibration\">اهتزاز</string>\n    <string name=\"vibration_strength\">قوة الاهتزاز</string>\n    <string name=\"overwrite_files\">الكتابة فوق الملفات</string>\n    <string name=\"overwrite_files_sub\">سيتم استبدال الملف الأصلي بملف جديد بدلاً من حفظه في المجلد المحدد، ويجب أن يكون هذا الخيار هو مصدر الصورة \\\"Explorer\\\" أو GetContent، وعند تبديل هذا، سيتم تعيينه تلقائيًا</string>\n    <string name=\"suffix\">لاحقة</string>\n    <string name=\"bicubic\">بيكوبيك</string>\n    <string name=\"spline\">خدد</string>\n    <string name=\"bilinear_sub\">عادةً ما يكون الاستيفاء الخطي (أو ثنائي الخط، في بعدين) جيدًا لتغيير حجم الصورة، ولكنه يسبب بعض التخفيف غير المرغوب فيه للتفاصيل ويمكن أن يظل متعرجًا إلى حد ما</string>\n    <string name=\"bicubic_sub\">تتضمن طرق القياس الأفضل إعادة أخذ العينات من Lanczos وتصفيات Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">إحدى أبسط الطرق لزيادة الحجم هي استبدال كل بكسل بعدد من البكسلات من نفس اللون</string>\n    <string name=\"basic_sub\">أبسط وضع للتحجيم على نظام Android يُستخدم في جميع التطبيقات تقريبًا</string>\n    <string name=\"catmull_sub\">طريقة لاستكمال وإعادة تشكيل مجموعة من نقاط التحكم بسلاسة، تُستخدم عادةً في رسوميات الحاسوب لإنشاء منحنيات ناعمة</string>\n    <string name=\"hann_sub\">غالبًا ما يتم تطبيق وظيفة النوافذ في معالجة الإشارات لتقليل التسرب الطيفي وتحسين دقة تحليل التردد عن طريق تضييق حواف الإشارة</string>\n    <string name=\"hermite_sub\">تقنية الاستيفاء الرياضي التي تستخدم القيم والمشتقات عند نقاط نهاية مقطع المنحنى لتوليد منحنى سلس ومستمر</string>\n    <string name=\"lanczos_sub\">طريقة إعادة التشكيل التي تحافظ على الاستيفاء عالي الجودة من خلال تطبيق دالة المزامنة الموزونة على قيم البكسل</string>\n    <string name=\"mitchell_sub\">طريقة إعادة التشكيل التي تستخدم تصفية التفاف مع معلمات قابلة للتضبيط لتحقيق التوازن بين الحدة والصقل في الصورة ذات الحجم الكبير</string>\n    <string name=\"spline_sub\">يستخدم الدوال متعددة الحدود المحددة لاستكمال وتقريب المنحنى أو السطح بسلاسة، وتمثيل الشكل المرن والمستمر</string>\n    <string name=\"only_clip_sub\">لن يتم إجراء الحفظ في وحدة التخزين، وستتم محاولة وضع الصورة في الحافظة فقط</string>\n    <string name=\"no_data\">لايوجد بيانات</string>\n    <string name=\"use_pixel_switch_sub\">يستخدم مفتاحًا يشبه Google Pixel</string>\n    <string name=\"saved_to_original\">كُتب فوق الملف بالاسم %1$s في الوجهة الأصلية</string>\n    <string name=\"magnifier_sub\">لتمكين المكبر الموجود أعلى الإصبع في أوضاع الرسم لتسهيل الوصول إليه</string>\n    <string name=\"force_exif_widget_initial_value\">قوة القيمة الأولية</string>\n    <string name=\"force_exif_widget_initial_value_sub\">يفرض فحص عنصر واجهة المستخدم exif في البداية</string>\n    <string name=\"allow_multiple_languages\">السماح بعدة لغات</string>\n    <string name=\"slide\">الانزلاق</string>\n    <string name=\"side_by_side\">جنباألى جنب</string>\n    <string name=\"segmentation_mode_single_column\">عمود فردي</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">نص عمودي كتلة واحدة</string>\n    <string name=\"segmentation_mode_sparse_text\">نص متفرق</string>\n    <string name=\"delete_language_sub\">هل تريد حذف بيانات تدريب التعرف الضوئي على الحروف \\\"%1$s\\\" اللغوية لجميع أنواع التعرف، أم للنوع المحدد فقط (%2$s)؟</string>\n    <string name=\"current\">حاضِر</string>\n    <string name=\"all\">الجميع</string>\n    <string name=\"gradient_maker_sub\">أنشئ تدرج لحجم الإخراج المحدد بألوان مخصّصة ونوع المظهر</string>\n    <string name=\"tile_mode_clamp\">المشبك</string>\n    <string name=\"tile_mode_decal\">صائق</string>\n    <string name=\"color_stops\">توقف اللون</string>\n    <string name=\"add_color\">أضف اللون</string>\n    <string name=\"properties\">ملكيات</string>\n    <string name=\"watermarking_sub\">قم بتغطية الصور بعلامات مائية نصية/صورة قابلة للتخصيص</string>\n    <string name=\"repeat_watermark_sub\">يكرر العلامة المائية على الصورة بدلاً من العلامة المائية في موضع معين</string>\n    <string name=\"offset_x\">الإزاحة X</string>\n    <string name=\"offset_y\">إزاحة Y</string>\n    <string name=\"watermark_type\">نوع العلامة المائية</string>\n    <string name=\"watermarking_image_sub\">سيتم استخدام هذه الصورة كنموذج للعلامة المائية</string>\n    <string name=\"text_color\">لون الخط</string>\n    <string name=\"gif_tools\">أدوات GIF</string>\n    <string name=\"gif_tools_sub\">تحويل الصور إلى صورة GIF أو استخراج الإطارات من صورة GIF معينة</string>\n    <string name=\"gif_type_to_image\">GIF للصور</string>\n    <string name=\"gif_type_to_image_sub\">تحويل ملف GIF إلى مجموعة من الصور</string>\n    <string name=\"gif_type_to_gif_sub\">تحويل مجموعة من الصور إلى ملف GIF</string>\n    <string name=\"gif_type_to_gif\">الصور إلى GIF</string>\n    <string name=\"select_gif_image_to_start\">اختر صورة GIF للبدء</string>\n    <string name=\"use_size_of_first_frame\">استخدم حجم الإطار الأول</string>\n    <string name=\"use_size_of_first_frame_sub\">استبدل الحجم المحدد بأبعاد الإطار الأول</string>\n    <string name=\"repeat_count\">تكرار العد</string>\n    <string name=\"frame_delay\">تأخير الإطار</string>\n    <string name=\"millis\">ملي</string>\n    <string name=\"fps\">إطارا في الثانية</string>\n    <string name=\"confetti\">قصاصات ورق ملون</string>\n    <string name=\"confetti_sub\">سيتم عرض قصاصات الورق عند الحفظ والمشاركة والإجراءات الأساسية الأخرى</string>\n    <string name=\"secure_mode\">وضع آمن</string>\n    <string name=\"secure_mode_sub\">يخفي المحتوى عند الخروج، كما لا يمكن التقاط الشاشة أو تسجيلها</string>\n    <string name=\"bayer_three_dithering\">باير ثلاثة بثلاثة التردد</string>\n    <string name=\"bayer_four_dithering\">باير أربعة بأربعة التردد</string>\n    <string name=\"two_row_sierra_dithering\">ثبات سييرا ذو صفين</string>\n    <string name=\"sierra_lite_dithering\">ثبات سييرا لايت</string>\n    <string name=\"atkinson_dithering\">أتكينسون تذبذب</string>\n    <string name=\"false_floyd_steinberg_dithering\">التردد الكاذب فلويد شتاينبرغ</string>\n    <string name=\"left_to_right_dithering\">التردد من اليسار إلى اليمين</string>\n    <string name=\"random_dithering\">ثبات عشوائي</string>\n    <string name=\"simple_threshold_dithering\">ثبات العتبة البسيطة</string>\n    <string name=\"b_spline_sub\">يستخدم وظائف متعددة الحدود ثنائية التكعيبية لاستكمال وتقريب المنحنى أو السطح بسلاسة، وتمثيل الشكل المرن والمستمر</string>\n    <string name=\"native_stack_blur\">طمس المكدس الأصلي</string>\n    <string name=\"anaglyph\">النقش</string>\n    <string name=\"noise\">ضوضاء</string>\n    <string name=\"pixel_sort\">فرز البكسل</string>\n    <string name=\"shuffle\">خلط</string>\n    <string name=\"enhanced_glitch\">خلل معزز</string>\n    <string name=\"channel_shift_x\">تحويل القناة X</string>\n    <string name=\"channel_shift_y\">تحويل القناة Y</string>\n    <string name=\"corruption_size\">حجم الفساد</string>\n    <string name=\"corruption_shift_x\">تحول الفساد X</string>\n    <string name=\"corruption_shift_y\">تحول الفساد Y</string>\n    <string name=\"tent_blur\">طمس الخيمة</string>\n    <string name=\"side_fade\">تتلاشى الجانب</string>\n    <string name=\"side\">جانب</string>\n    <string name=\"top\">قمة</string>\n    <string name=\"bottom\">قاع</string>\n    <string name=\"strength\">قوة</string>\n    <string name=\"amplitude\">السعة</string>\n    <string name=\"marble\">رخام</string>\n    <string name=\"simple_effects\">تأثيرات بسيطة</string>\n    <string name=\"polaroid\">بولارويد</string>\n    <string name=\"tritonomaly\">شلل تريتونومي</string>\n    <string name=\"deutaromaly\">شلل ثنائي</string>\n    <string name=\"protonomaly\">بروتونومالي</string>\n    <string name=\"vintage\">كلاسيكي</string>\n    <string name=\"night_vision\">الرؤية الليلية</string>\n    <string name=\"warm\">دافيء</string>\n    <string name=\"cool\">رائع</string>\n    <string name=\"tritanopia\">تريتانوبيا</string>\n    <string name=\"deutaronotopia\">ديوتارونوتوبيا</string>\n    <string name=\"achromatomaly\">شلل لوني</string>\n    <string name=\"achromatopsia\">الأكروماتوبسيا</string>\n    <string name=\"golden_hour\">الساعة الذهبية</string>\n    <string name=\"hot_summer\">صيف حار</string>\n    <string name=\"autumn_tones\">نغمات الخريف</string>\n    <string name=\"fantasy_landscape\">المناظر الطبيعية الخيالية</string>\n    <string name=\"color_explosion\">انفجار اللون</string>\n    <string name=\"electric_gradient\">التدرج الكهربائي</string>\n    <string name=\"caramel_darkness\">كراميل الظلام</string>\n    <string name=\"futuristic_gradient\">التدرج المستقبلي</string>\n    <string name=\"green_sun\">الشمس الخضراء</string>\n    <string name=\"digital_code\">الكود الرقمي</string>\n    <string name=\"icon_shape\">شكل الأيقونة</string>\n    <string name=\"drago\">دراجو</string>\n    <string name=\"aldridge\">الدريدج</string>\n    <string name=\"cutoff\">قطع</string>\n    <string name=\"uchimura\">اوتشيمورا</string>\n    <string name=\"mobius\">موبيوس</string>\n    <string name=\"transition\">انتقال</string>\n    <string name=\"peak\">قمة</string>\n    <string name=\"color_anomaly\">شذوذ اللون</string>\n    <string name=\"cannot_change_image_format\">لا يمكن تغيير تنسيق الصورة أثناء تمكين خيار الكتابة فوق الملفات</string>\n    <string name=\"emoji_as_color_scheme\">الرموز التعبيرية كنظام ألوان</string>\n    <string name=\"emoji_as_color_scheme_sub\">يستخدم اللون الأساسي للرموز التعبيرية كنظام ألوان للتطبيق بدلاً من اللون المحدد يدويًا</string>\n    <string name=\"background_remover\">مزيل الخلفية</string>\n    <string name=\"trim_image\">تقليم الصورة</string>\n    <string name=\"erase_mode\">وضع المسح</string>\n    <string name=\"circle_pixelation\">بكسل الدائرة</string>\n    <string name=\"enhanced_circle_pixelation\">تعزيز بكسل الدائرة</string>\n    <string name=\"replace_color\">استبدال اللون</string>\n    <string name=\"remove_color\">أزل اللون</string>\n    <string name=\"recode\">إعادة ترميز</string>\n    <string name=\"erode\">تقلص</string>\n    <string name=\"anisotropic_diffusion\">انتشار متباين الخواص</string>\n    <string name=\"diffusion\">انتشار</string>\n    <string name=\"conduction\">التوصيل</string>\n    <string name=\"horizontal_wind_stagger\">الرياح الأفقية ترنح</string>\n    <string name=\"aces_filmic_tone_mapping\">رسم خرائط النغمات السينمائية من ACES</string>\n    <string name=\"aces_hill_tone_mapping\">ACES هيل لهجة رسم الخرائط</string>\n    <string name=\"fast_bilaterial_blur\">طمس ثنائي سريع</string>\n    <string name=\"poisson_blur\">بواسون طمس</string>\n    <string name=\"logarithmic_tone_mapping\">رسم خرائط النغمة اللوغاريتمية</string>\n    <string name=\"crystallize\">تبلور</string>\n    <string name=\"stroke_color\">حلقه ملونه</string>\n    <string name=\"fractal_glass\">زجاج كسورية</string>\n    <string name=\"turbulence\">الاضطراب</string>\n    <string name=\"oil\">زيت</string>\n    <string name=\"water_effect\">تأثير الماء</string>\n    <string name=\"just_size\">مقاس</string>\n    <string name=\"frequency_x\">التردد X</string>\n    <string name=\"frequency_y\">التردد Y</string>\n    <string name=\"amplitude_x\">السعة X</string>\n    <string name=\"amplitude_y\">السعة Y</string>\n    <string name=\"perlin_distortion\">تشويه بيرلين</string>\n    <string name=\"hable_filmic_tone_mapping\">رسم خرائط النغمات السينمائية</string>\n    <string name=\"heji_burgess_tone_mapping\">رسم خرائط لهجة هيجل بورغيس</string>\n    <string name=\"full_filter\">تصفية كاملة</string>\n    <string name=\"start_position\">يبدأ</string>\n    <string name=\"center_position\">مركز</string>\n    <string name=\"end_position\">نهاية</string>\n    <string name=\"full_filter_sub\">طبّق أي سلاسل التصفية على الصور المُعطاة أو على صورة واحدة</string>\n    <string name=\"pdf_tools_sub\">العمل مع ملفات PDF: معاينة، تحويل إلى مجموعة من الصور أو إنشاء واحدة من صور معينة</string>\n    <string name=\"preview_pdf\">معاينة PDF</string>\n    <string name=\"pdf_to_images\">PDF إلى صور</string>\n    <string name=\"images_to_pdf\">صور إلى PDF</string>\n    <string name=\"preview_pdf_sub\">معاينة PDF بسيطة</string>\n    <string name=\"pdf_to_images_sub\">تحويل PDF إلى صور بتنسيق الإخراج المحدد</string>\n    <string name=\"images_to_pdf_sub\">حزم الصور المعطاة في ملف PDF الناتج</string>\n    <string name=\"gradient_maker\">صانع التدرج</string>\n    <string name=\"speed\">سرعة</string>\n    <string name=\"dehaze\">ديهيز</string>\n    <string name=\"omega\">أوميغا</string>\n    <string name=\"pdf_tools\">أدوات PDF</string>\n    <string name=\"rate_app\">قيّم التطبيق</string>\n    <string name=\"rate\">قيّم</string>\n    <string name=\"rate_app_sub\">هذا التطبيق مجاني تمامًا، إذا كنت تريد أن يصبح أكبر، يُرجى تمييز المشروع بنجمة على Github 😄</string>\n    <string name=\"color_matrix_4x4\">مصفوفة الألوان 4x4</string>\n    <string name=\"color_matrix_3x3\">مصفوفة الألوان 3x3</string>\n    <string name=\"browni\">براوني</string>\n    <string name=\"coda_chrome\">كودا كروم</string>\n    <string name=\"protanopia\">بروتانوبيا</string>\n    <string name=\"gradient_type_linear\">خطي</string>\n    <string name=\"gradient_type_radial\">شعاعي</string>\n    <string name=\"gradient_type_sweep\">مسح</string>\n    <string name=\"gradient_type\">نوع التدرج</string>\n    <string name=\"center_x\">المركز العاشر</string>\n    <string name=\"center_y\">مركز ي</string>\n    <string name=\"tile_mode\">وضع البلاط</string>\n    <string name=\"tile_mode_repeated\">معاد</string>\n    <string name=\"tile_mode_mirror\">مرآة</string>\n    <string name=\"draw_path_mode\">وضع رسم المسار</string>\n    <string name=\"double_line_arrow\">سهم خط مزدوج</string>\n    <string name=\"line_arrow\">سهم الخط</string>\n    <string name=\"line_sub\">رسم المسار من نقطة البداية إلى نقطة النهاية كخط</string>\n    <string name=\"arrow\">سهم</string>\n    <string name=\"line\">خط</string>\n    <string name=\"free_drawing_sub\">رسم المسار كقيمة إدخال</string>\n    <string name=\"line_arrow_sub\">رسم سهمًا يشير من نقطة البداية إلى نقطة النهاية كخط</string>\n    <string name=\"arrow_sub\">رسم سهم يشير من مسار معين</string>\n    <string name=\"double_arrow_sub\">رسم سهمًا مزدوجًا يشير من مسار معين</string>\n    <string name=\"outlined_oval\">البيضاوي المبين</string>\n    <string name=\"outlined_rect\">المستقيم المبين</string>\n    <string name=\"oval\">بيضاوي</string>\n    <string name=\"rect\">مستقيم</string>\n    <string name=\"rect_sub\">رسم بشكل مستقيم من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"oval_sub\">رسم شكلًا بيضاويًا من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"outlined_oval_sub\">رسم شكل بيضاوي محدد من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"outlined_rect_sub\">الرسم بشكل مستقيم من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"dithering\">التردد</string>\n    <string name=\"quantizier\">كمية</string>\n    <string name=\"gray_scale\">مقياس رمادي</string>\n    <string name=\"bayer_two_dithering\">باير اثنين من اثنين التردد</string>\n    <string name=\"bayer_eight_dithering\">باير ثمانية بثمانية التردد</string>\n    <string name=\"floyd_steinberg_dithering\">فلويد شتاينبرغ التردد</string>\n    <string name=\"jarvis_judice_ninke_dithering\">جارفيس جوديس نينكي التردد</string>\n    <string name=\"sierra_dithering\">سييرا التردد</string>\n    <string name=\"stucki_dithering\">ثبات ستوكي</string>\n    <string name=\"burkes_dithering\">تذبذب بيركس</string>\n    <string name=\"crashlytics_sub\">يتيح ذلك للتطبيق جمع تقارير الأعطال يدويًا</string>\n    <string name=\"analytics\">التحليلات</string>\n    <string name=\"analytics_sub\">السماح بجمع إحصائيات استخدام التطبيق بشكل مجهول</string>\n    <string name=\"mask_color\">لون القناع</string>\n    <string name=\"mask_preview\">معاينة القناع</string>\n    <string name=\"scale_mode\">وضع القياس</string>\n    <string name=\"bilinear\">خطين</string>\n    <string name=\"hann\">هان</string>\n    <string name=\"hermite\">هيرميت</string>\n    <string name=\"lanczos\">لانكزوس</string>\n    <string name=\"mitchell\">ميتشل</string>\n    <string name=\"nearest\">الأقرب</string>\n    <string name=\"basic\">أساسي</string>\n    <string name=\"default_value\">القيمة الافتراضية</string>\n    <string name=\"value_in_range\">القيمة في النطاق %1$s - %2$s</string>\n    <string name=\"sigma\">سيجما</string>\n    <string name=\"spatial_sigma\">سيجما المكانية</string>\n    <string name=\"median_blur\">طمس متوسط</string>\n    <string name=\"catmull\">كاتمول</string>\n    <string name=\"only_clip\">كليب فقط</string>\n    <string name=\"icon_shape_sub\">يضيف حاوية بالشكل المحدد أسفل الأيقونات</string>\n    <string name=\"image_stitching\">خياطة الصورة</string>\n    <string name=\"image_stitching_sub\">ادمج الصور المُعطاة للحصول على صورة واحدة كبيرة</string>\n    <string name=\"email\">بريد إلكتروني</string>\n    <string name=\"brightness_enforcement\">إنفاذ السطوع</string>\n    <string name=\"screen\">شاشة</string>\n    <string name=\"gradient_maker_type_image\">تغطية بالتدرج اللوني</string>\n    <string name=\"gradient_maker_type_image_sub\">إنشاء أي تدرج في أعلى الصورة المعطاة</string>\n    <string name=\"transformations\">التحولات</string>\n    <string name=\"camera\">آلة تصوير</string>\n    <string name=\"camera_sub\">يستخدم الكاميرا لالتقاط الصورة، لاحظ أنه من الممكن الحصول على صورة واحدة فقط من مصدر الصورة هذا</string>\n    <string name=\"pick_at_least_two_images\">اختر صورتين على الأقل</string>\n    <string name=\"output_image_scale\">مقياس صورة الإخراج</string>\n    <string name=\"image_orientation\">اتجاه الصورة</string>\n    <string name=\"scale_small_images_to_large\">تحجيم الصور الصغيرة إلى كبيرة</string>\n    <string name=\"images_order\">ترتيب الصور</string>\n    <string name=\"grain\">قمح</string>\n    <string name=\"orange_haze\">ضباب برتقالي</string>\n    <string name=\"unsharp\">غير حاد</string>\n    <string name=\"pastel\">باستيل</string>\n    <string name=\"pink_dream\">الحلم الوردي</string>\n    <string name=\"purple_mist\">الضباب الأرجواني</string>\n    <string name=\"sunrise\">شروق الشمس</string>\n    <string name=\"colorful_swirl\">دوامة ملونة</string>\n    <string name=\"soft_spring_light\">ضوء الربيع الناعم</string>\n    <string name=\"lavender_dream\">حلم الخزامى</string>\n    <string name=\"cyberpunk\">السايبربانك</string>\n    <string name=\"lemonade_light\">ضوء عصير الليمون</string>\n    <string name=\"spectral_fire\">النار الطيفية</string>\n    <string name=\"night_magic\">سحر الليل</string>\n    <string name=\"rainbow_world\">عالم قوس قزح</string>\n    <string name=\"deep_purple\">ديب بيربل</string>\n    <string name=\"space_portal\">بوابة الفضاء</string>\n    <string name=\"red_swirl\">دوامة حمراء</string>\n    <string name=\"watermarking\">العلامة المائية</string>\n    <string name=\"repeat_watermark\">كرر العلامة المائية</string>\n    <string name=\"overlay_mode\">وضع التراكب</string>\n    <string name=\"pixel_size\">حجم بكسل</string>\n    <string name=\"lock_draw_orientation\">قفل اتجاه الرسم</string>\n    <string name=\"effort_sub\">القيمة %1$s تعني ضغطًا سريعًا، مما يؤدي إلى حجم ملف كبير نسبيًا. %2$s يعني ضغطًا أبطأ، مما يؤدي إلى ملف أصغر.</string>\n    <string name=\"bokeh\">خوخه</string>\n    <string name=\"use_lasso\">استخدم لاسو</string>\n    <string name=\"use_lasso_sub\">يستخدم Lasso كما هو الحال في وضع الرسم لإجراء المسح</string>\n    <string name=\"original_image_preview_alpha\">معاينة الصورة الأصلية ألفا</string>\n    <string name=\"mask_filter\">تصفية القناع</string>\n    <string name=\"mask_filter_sub\">طبّق سلاسل التصفية على المناطق المقنعة المعطاة، حيث يمكن لكل منطقة قناع تحديد مجموعة التصفيات الخاصة بها.</string>\n    <string name=\"add_mask\">أضف قناع</string>\n    <string name=\"restore_image\">استعادة الصورة</string>\n    <string name=\"random_emojis_sub\">سيتم تغيير الرموز التعبيرية لشريط التطبيقات بشكل عشوائي بشكل مستمر بدلاً من استخدام الرمز المحدد</string>\n    <string name=\"random_emojis\">الرموز التعبيرية العشوائية</string>\n    <string name=\"random_emojis_error\">لا يمكن استخدام انتقاء عشوائي للرموز التعبيرية أثناء تعطيل الرموز التعبيرية</string>\n    <string name=\"emoji_selection_error\">لا يمكن تحديد رمز تعبيري أثناء تمكين اختيار رمز عشوائي</string>\n    <string name=\"check_for_updates\">تحقق من وجود تحديثات</string>\n    <string name=\"effort\">جهد</string>\n    <string name=\"wait\">انتظر</string>\n    <string name=\"objects\">أشياء</string>\n    <string name=\"symbols\">حرف او رمز</string>\n    <string name=\"enable_emoji\">فعِّل الرموز التعبيرية</string>\n    <string name=\"travels_and_places\">الرحلات والأماكن</string>\n    <string name=\"background_remover_sub\">أزِل الخلفية من الصورة عن طريق الرسم أو استخدام الخيار التلقائي</string>\n    <string name=\"erase_background\">محو الخلفية</string>\n    <string name=\"blur_radius\">طمس نصف قطرها</string>\n    <string name=\"create_issue\">أنشئ علة</string>\n    <string name=\"something_went_wrong_emphasis\">عفوًا… حدث خطأ ما. يمكنك الكتابة إليَّ باستخدام الخيارات أدناه وسأحاول إيجاد حل</string>\n    <string name=\"resize_and_convert\">تغيير الحجم والتحويل</string>\n    <string name=\"resize_and_convert_sub\">غيّر حجم الصور المعينة أو تحويلها إلى تنسيقات أخرى. يمكن أيضًا تحرير بيانات EXIF التعريفية هنا في حالة اختيار صورة واحدة.</string>\n    <string name=\"max_colors_count\">الحد الأقصى لعدد الألوان</string>\n    <string name=\"image_exif_warning\">حاليًا، يسمح تنسيق %1$s بقراءة بيانات EXIF التعريفية فقط على نظام Android. لن تحتوي الصورة الناتجة على بيانات وصفية على الإطلاق عند حفظها.</string>\n    <string name=\"saving_almost_complete\">اكتمل الحفظ تقريبًا. سيتطلب الإلغاء الآن الحفظ مرة أخرى.</string>\n    <string name=\"allow_betas_sub\">سيتضمن التحقق من التحديث إصدارات التطبيق التجريبية إذا فُعّلت</string>\n    <string name=\"old_tv\">تلفزيون قديم</string>\n    <string name=\"shuffle_blur\">خلط ورق اللعب طمس</string>\n    <string name=\"recognize_text\">التعرف الضوئي على الحروف (التعرف على النص)</string>\n    <string name=\"recognize_text_sub\">التعرف على النص من صورة معينة، دعم أكثر من 120 لغة</string>\n    <string name=\"picture_has_no_text\">الصورة لا تحتوي على نص، أو أن التطبيق لم يعثر عليها</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">نوع الاعتراف</string>\n    <string name=\"fast\">سريع</string>\n    <string name=\"standard\">معيار</string>\n    <string name=\"best\">أفضل</string>\n    <string name=\"download_description\">للحصول على أداء سليم لـ Tesseract OCR، يجب تنزيل بيانات التدريب الإضافية (%1$s) على جهازك. \\nأتريد تنزيل %2$s بيانات؟</string>\n    <string name=\"download\">نزّل</string>\n    <string name=\"no_connection\">لا يوجد اتصال، تحقق منه وحاول مرة أخرى لتنزيل نماذج القطارات</string>\n    <string name=\"downloaded_languages\">اللغات المُنزلة</string>\n    <string name=\"available_languages\">اللغات المتوفرة</string>\n    <string name=\"segmentation_mode\">وضع التجزئة</string>\n    <string name=\"restore_background_sub\">ستقوم الفرشاة باستعادة الخلفية بدلاً من مسحها</string>\n    <string name=\"horizontal_grid\">الشبكة الأفقية</string>\n    <string name=\"vertical_grid\">الشبكة العمودية</string>\n    <string name=\"use_pixel_switch\">استخدم مفتاح البكسل</string>\n    <string name=\"toggle_tap\">تبديل اضغط</string>\n    <string name=\"transparency\">الشفافية</string>\n    <string name=\"magnifier\">المكبر</string>\n    <string name=\"favorite\">مفضل</string>\n    <string name=\"no_favorite_filters\">لم تتم إضافة أي تصفيات مفضلة حتى الآن</string>\n    <string name=\"b_spline\">ب سبلين</string>\n    <string name=\"tilt_shift\">التحول الميل</string>\n    <string name=\"regular\">عادي</string>\n    <string name=\"blur_edges\">طمس الحواف</string>\n    <string name=\"pixelation\">البكسل</string>\n    <string name=\"inverse_fill_type\">نوع التعبئة العكسية</string>\n    <string name=\"draw_arrows\">ارسم السهام</string>\n    <string name=\"brush_softness\">نعومة الفرشاة</string>\n    <string name=\"masks\">أقنعة</string>\n    <string name=\"mask_indexed\">قناع %d</string>\n    <string name=\"neon\">نيون</string>\n    <string name=\"highlighter_sub\">ارسم مسارات تمييز حادة وشبه شفافة</string>\n    <string name=\"privacy_blur_sub\">يطمس الصورة أسفل المسار المرسوم لتأمين أي شيء تريد إخفاءه</string>\n    <string name=\"containers_shadow\">حاويات</string>\n    <string name=\"containers_shadow_sub\">رسم ظل خلف الحاويات</string>\n    <string name=\"sliders_shadow\">المتزلجون</string>\n    <string name=\"foss_update_checker_warning\">سيتصل مدقق التحديث هذا بـ GitHub للتحقق من توفر تحديث جديد</string>\n    <string name=\"attention\">انتباه</string>\n    <string name=\"fading_edges\">حواف باهتة</string>\n    <string name=\"invert_colors\">عكس الألوان</string>\n    <string name=\"exit\">غادر</string>\n    <string name=\"preview_closing\">إذا تركت المعاينة الآن، فسوف تحتاج إلى إضافة الصور مرة أخرى</string>\n    <string name=\"lasso\">لاسو</string>\n    <string name=\"lasso_sub\">رسم مسارًا مغلقًا ومملوءًا بمسار معين</string>\n    <string name=\"image_format\">تنسيق الصورة</string>\n    <string name=\"dark_colors\">الألوان الداكنة</string>\n    <string name=\"dark_colors_sub\">يستخدم نظام ألوان الوضع الليلي بدلا من متغير الضوء</string>\n    <string name=\"copy_as_compose_code\">نسخ كما جيتباك يؤلف التعليمات البرمجية</string>\n    <string name=\"material_you_sub\">ينشئ لوحة\\\"Materal You\\\" من الصورة</string>\n    <string name=\"ring_blur\">خاتم الضباب</string>\n    <string name=\"circle_blur\">دائرة الضباب</string>\n    <string name=\"star_blur\">نجمة الضباب</string>\n    <string name=\"cross_blur\">ضباب متقاطع</string>\n    <string name=\"linear_tilt_shift\">تحول الميل الخطي</string>\n    <string name=\"tags_to_remove\">وسوم للإزالة</string>\n    <string name=\"apng_tools\">ادوات APNG</string>\n    <string name=\"apng_type_to_image\">APNG إلى الصور</string>\n    <string name=\"apng_type_to_image_sub\">تحويل ملف APNG إلى مجموعة من الصور</string>\n    <string name=\"apng_type_to_apng\">الصور إلى APNG</string>\n    <string name=\"select_apng_image_to_start\">اختر صورة APNG للبدء</string>\n    <string name=\"motion_blur\">ضبابية الحركة</string>\n    <string name=\"zip_sub\">أنشئ ملف مضغوط من ملفات أو صور معينة</string>\n    <string name=\"apng_tools_sub\">تحويل الصور إلى صورة APNG أو استخراج الإطارات من صورة APNG معينة</string>\n    <string name=\"apng_type_to_apng_sub\">تحويل مجموعة من الصور إلى ملف APNG</string>\n    <string name=\"zip\">مضغوط</string>\n    <string name=\"drag_handle_width\">عرض مقبض السحب</string>\n    <string name=\"confetti_type\">نوع قصاصات الورق</string>\n    <string name=\"festive\">احتفالي</string>\n    <string name=\"explode\">الانفجار</string>\n    <string name=\"rain\">مطر</string>\n    <string name=\"corners\">الحواف</string>\n    <string name=\"jxl_tools_sub\">قم بإجراء تحويل ترميز JXL ~ JPEG دون فقدان الجودة، أو قم بتحويل GIF/APNG إلى رسوم متحركة JXL</string>\n    <string name=\"jxl_type_to_jpeg\">من JXL إلى JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">قم بإجراء تحويل بدون فقدان الترميز من JXL إلى JPEG</string>\n    <string name=\"jxl_tools\">أدوات جي إكس إل</string>\n    <string name=\"jpeg_type_to_jxl_sub\">قم بإجراء تحويل بدون فقدان الترميز من JPEG الى JXL</string>\n    <string name=\"fast_gaussian_blur_2d\">تمويه غاوسي سريع 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">طمس غاوسي سريع 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">تمويه غاوسي سريع 4D</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG إلى JXL</string>\n    <string name=\"select_jxl_image_to_start\">اختر صورة JXL للبدء</string>\n    <string name=\"auto_paste\">اللصق التلقائي</string>\n    <string name=\"auto_paste_sub\">يسمح للتطبيق بلصق بيانات الحافظة تلقائيًا، بحيث تظهر على الشاشة الرئيسية وستتمكن من معالجتها</string>\n    <string name=\"harmonization_color\">وحدة تنسيق</string>\n    <string name=\"harmonization_level\">مستوى المواءمة</string>\n    <string name=\"lanczos_bessel\">لانكزوس بيسل</string>\n    <string name=\"lanczos_bessel_sub\">طريقة إعادة التشكيل التي تحافظ على الاستيفاء عالي الجودة من خلال تطبيق دالة Bessel (jinc) على قيم البكسل</string>\n    <string name=\"gif_type_to_jxl\">GIF إلى JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">تحويل صور GIF إلى صور متحركة JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG الى JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">تحويل صور APNG إلى صور متحركة JXL</string>\n    <string name=\"jxl_type_to_images\">JXL إلى الصور</string>\n    <string name=\"jxl_type_to_images_sub\">تحويل الرسوم المتحركة JXL إلى مجموعة من الصور</string>\n    <string name=\"jxl_type_to_jxl\">الصور إلى JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">تحويل مجموعة من الصور إلى الرسوم المتحركة JXL</string>\n    <string name=\"behavior\">السلوك</string>\n    <string name=\"skip_file_picking\">تخطي انتقاء الملف</string>\n    <string name=\"generate_previews\">ولّد معاينات</string>\n    <string name=\"lossy_compression\">ضغط بيانات مع فقد (Lossy)</string>\n    <string name=\"lossy_compression_sub\">يستخدم الضغط مع فقدان البيانات لتقليل حجم الملف بدلاً من عدم فقدانه</string>\n    <string name=\"compression_type\">نوع الضغط</string>\n    <string name=\"skip_file_picking_sub\">سيتم عرض منتقي الملفات على الفور إذا كان ذلك ممكنًا على الشاشة المختارة</string>\n    <string name=\"generate_previews_sub\">يفعّل إنشاء المعاينة، وقد يساعد هذا في تجنب الأعطال على بعض الأجهزة، كما يؤدي هذا أيضًا إلى تعطيل بعض وظائف التحرير ضمن خيار تحرير واحد</string>\n    <string name=\"speed_sub\">يتحكم في سرعة فك تشفير الصورة الناتجة، وهذا من شأنه أن يساعد في فتح الصورة الناتجة بشكل أسرع، قيمة %1$s تعني أبطأ عملية فك تشفير، بينما %2$s - الأسرع، قد يؤدي هذا الإعداد إلى زيادة حجم الصورة الناتجة</string>\n    <string name=\"sorting\">الفرز</string>\n    <string name=\"sort_by_date\">رتب حسب التاريخ</string>\n    <string name=\"sort_by_date_reversed\">رتب حسب التاريخ(معكوس)</string>\n    <string name=\"sort_by_name\">فرز حسب الاسم</string>\n    <string name=\"sort_by_name_reversed\">فرز حسب الاسم (معكوس)</string>\n    <string name=\"channels_configuration\">إعداد القنوات</string>\n    <string name=\"header_today\">اليوم</string>\n    <string name=\"header_yesterday\">أمس</string>\n    <string name=\"embedded_picker\">المنتقى المضمن</string>\n    <string name=\"embedded_picker_sub\">يستخدم منتقي الصور الخاص بـ Image Toolbox بدلاً من الصور المحددة مسبقًا في النظام</string>\n    <string name=\"no_permissions\">لا أذونات</string>\n    <string name=\"request\">الطلب</string>\n    <string name=\"pick_multiple_media\">اختر صور متعددة</string>\n    <string name=\"pick\">اختر</string>\n    <string name=\"pick_single_media\">اختر صورة واحدة</string>\n    <string name=\"show_settings_in_landscape\">عرض الإعدادات في الوضع الأفقي</string>\n    <string name=\"try_again\">حاول مرة أخرى</string>\n    <string name=\"show_settings_in_landscape_sub\">إذا تم تعطيل هذا الخيار، فسيتم فتح إعدادات الوضع الأفقي على الزر الموجود في شريط التطبيقات العلوي كما هو الحال دائمًا، بدلاً من الخيار المرئي الدائم</string>\n    <string name=\"fullscreen_settings\">إعدادات ملء الشاشة</string>\n    <string name=\"fullscreen_settings_sub\">فعّله وسيتم فتح صفحة الإعدادات دائمًا بملء الشاشة بدلاً من ورقة الدرج القابلة للانزلاق</string>\n    <string name=\"switch_type\">تبديل النوع</string>\n    <string name=\"compose\">تركيب</string>\n    <string name=\"compose_switch_sub\">مفتاح Jetpack Compose Material You</string>\n    <string name=\"material_you_switch_sub\">مفتاح Material You</string>\n    <string name=\"resize_anchor\">تغيير حجم الارتساء</string>\n    <string name=\"fluent_switch\">طلِق</string>\n    <string name=\"max\">الأعلى</string>\n    <string name=\"pixel_switch\">بكسل</string>\n    <string name=\"fluent_switch_sub\">يستخدم مفتاح Windows 11 المصمم على أساس نظام التصميم \\\"الطلاقة\\\".</string>\n    <string name=\"cupertino_switch\">كوبرتينو</string>\n    <string name=\"cupertino_switch_sub\">مفتاح تبديل يعتمد على نظام التصميم \\\"كوبرتينو\\\"</string>\n    <string name=\"images_to_svg_sub\">تتبع الصور المعطاة إلى صور SVG</string>\n    <string name=\"use_sampled_palette\">استخدم لوحة العينات</string>\n    <string name=\"path_omit\">إهمال المسار</string>\n    <string name=\"downscale_image\">قلّص الصورة</string>\n    <string name=\"downscale_image_sub\">سيتم تقليص الصورة إلى أبعاد أقل قبل معالجتها، مما يساعد الأداة على العمل بشكل أسرع وأكثر أمانًا</string>\n    <string name=\"min_color_ratio\">الحد الأدنى لنسبة اللون</string>\n    <string name=\"lines_threshold\">عتبة الخطوط</string>\n    <string name=\"quadratic_threshold\">العتبة التربيعية</string>\n    <string name=\"coordinates_rounding_tolerance\">إحداثيات التقريب التسامح</string>\n    <string name=\"path_scale\">مقياس المسار</string>\n    <string name=\"reset_properties\">صفّر الخصائص</string>\n    <string name=\"images_to_svg\">الصور إلى Svg</string>\n    <string name=\"use_sampled_palette_sub\">سيتم أخذ عينات من لوحة القياس إذا فُعّل هذا الخيار</string>\n    <string name=\"svg_warning\">لا يُنصح باستخدام هذه الأداة لتتبع الصور الكبيرة دون تقليصها، حيث يمكن أن تتسبب في حدوث إنهيار وزيادة وقت المعالجة</string>\n    <string name=\"reset_properties_sub\">سيصفّر كافة الخصائص إلى القيم الافتراضية، لاحظ أنه لا يمكن التراجع عن هذا الإجراء</string>\n    <string name=\"detailed\">‬مفصلة</string>\n    <string name=\"default_line_width\">عرض الخط الافتراضي</string>\n    <string name=\"engine_mode\">وضع المحرك</string>\n    <string name=\"legacy\">قياسي</string>\n    <string name=\"lstm_network\">شبكة LSTM</string>\n    <string name=\"legacy_and_lstm\">قياسي &amp; LSTM</string>\n    <string name=\"convert\">تحويل</string>\n    <string name=\"convert_sub\">تحويل دفعات الصور إلى تنسيق معين</string>\n    <string name=\"add_new_folder\">أضف مجلد جديد</string>\n    <string name=\"tag_compression\">الضغط</string>\n    <string name=\"tag_photometric_interpretation\">التفسير الضوئي</string>\n    <string name=\"tag_samples_per_pixel\">عينات لكل بكسل</string>\n    <string name=\"tag_planar_configuration\">التكوين المستوي</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr أخذ العينات الفرعية</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr لتحديد المواقع</string>\n    <string name=\"tag_x_resolution\">القرار العاشر</string>\n    <string name=\"tag_y_resolution\">القرار ص</string>\n    <string name=\"tag_bits_per_sample\">بت لكل عينة</string>\n    <string name=\"tag_datetime\">التاريخ والوقت</string>\n    <string name=\"tag_make\">مصنّع</string>\n    <string name=\"tag_image_description\">وصف الصورة</string>\n    <string name=\"tag_model\">نموذج</string>\n    <string name=\"tag_software\">برمجية</string>\n    <string name=\"tag_copyright\">حقوق النشر</string>\n    <string name=\"tag_artist\">فنان</string>\n    <string name=\"tag_flashpix_version\">إصدار Flashpix</string>\n    <string name=\"tag_exif_version\">إصدار Exif</string>\n    <string name=\"draw_text_sub\">ارسم النص علي المسار بالخط المُعطى واللون</string>\n    <string name=\"tag_resolution_unit\">وحدة الدقة</string>\n    <string name=\"tag_white_point\">نقطة بيضاء</string>\n    <string name=\"tag_gamma\">جاما</string>\n    <string name=\"tag_user_comment\">تعليق المستخدم</string>\n    <string name=\"tag_related_sound_file\">ملف الصوت المرتبط</string>\n    <string name=\"tag_datetime_original\">الوقت والتاريخ الأصليين</string>\n    <string name=\"font_size\">حجم الخط</string>\n    <string name=\"watermark_size\">حجم العلامة المائية</string>\n    <string name=\"repeat_text\">تكرار النص</string>\n    <string name=\"tag_strip_offsets\">إزالة الإزاحات</string>\n    <string name=\"tag_rows_per_strip\">الصفوف لكل قطاع</string>\n    <string name=\"tag_strip_byte_counts\">تجريد عدد البايتات</string>\n    <string name=\"tag_jpeg_interchange_format\">تنسيق التبادل JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">طول تنسيق التبادل JPEG</string>\n    <string name=\"tag_transfer_function\">وظيفة النقل</string>\n    <string name=\"tag_primary_chromaticities\">اللونيات الأولية</string>\n    <string name=\"tag_y_cb_cr_coefficients\">معاملات Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">مرجعية الاسود الابيض</string>\n    <string name=\"tag_color_space\">نطاق الألوان</string>\n    <string name=\"tag_pixel_x_dimension\">بكسل × البعد</string>\n    <string name=\"tag_pixel_y_dimension\">بكسل بُعد ص</string>\n    <string name=\"tag_compressed_bits_per_pixel\">البت المضغوطة لكل بكسل</string>\n    <string name=\"tag_maker_note\">ملاحظة الصانع</string>\n    <string name=\"tag_datetime_digitized\">الوقت والتاريخ المرقم</string>\n    <string name=\"tag_offset_time\">وقت الإزاحة</string>\n    <string name=\"tag_offset_time_original\">وقت الإزاحة الأصلي</string>\n    <string name=\"tag_offset_time_digitized\">وقت الإزاحة المرقم</string>\n    <string name=\"tag_subsec_time\">الوقت الفرعي ثانية</string>\n    <string name=\"tag_subsec_time_original\">الوقت الفرعي للثانية الأصلي</string>\n    <string name=\"tag_subsec_time_digitized\">وقت فرعي رقمي</string>\n    <string name=\"tag_exposure_time\">وقت التعرض</string>\n    <string name=\"tag_f_number\">رقم ف</string>\n    <string name=\"tag_exposure_program\">برنامج التعرض</string>\n    <string name=\"tag_spectral_sensitivity\">الحساسية الطيفية</string>\n    <string name=\"tag_photographic_sensitivity\">حساسية التصوير الفوتوغرافي</string>\n    <string name=\"tag_oecf\">منظمة التعاون الاقتصادي</string>\n    <string name=\"tag_sensitivity_type\">نوع الحساسية</string>\n    <string name=\"tag_standard_output_sensitivity\">حساسية الإخراج القياسية</string>\n    <string name=\"tag_recommended_exposure_index\">مؤشر التعرض الموصى به</string>\n    <string name=\"tag_iso_speed\">سرعة الأيزو</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">خط عرض سرعة ISO yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">سرعة ISO خط العرض zzz</string>\n    <string name=\"tag_shutter_speed_value\">قيمة سرعة الغالق</string>\n    <string name=\"tag_aperture_value\">قيمة الفتحة</string>\n    <string name=\"tag_brightness_value\">قيمة السطوع</string>\n    <string name=\"tag_exposure_bias_value\">قيمة انحياز التعرض</string>\n    <string name=\"tag_max_aperture_value\">قيمة الفتحة القصوى</string>\n    <string name=\"tag_subject_distance\">مسافة الموضوع</string>\n    <string name=\"tag_metering_mode\">وضع القياس</string>\n    <string name=\"tag_flash\">فلاش</string>\n    <string name=\"tag_subject_area\">مجال الموضوع</string>\n    <string name=\"tag_focal_length\">البعد البؤري</string>\n    <string name=\"tag_flash_energy\">طاقة الفلاش</string>\n    <string name=\"tag_spatial_frequency_response\">استجابة التردد المكاني</string>\n    <string name=\"tag_focal_plane_x_resolution\">المستوى البؤري X القرار</string>\n    <string name=\"tag_focal_plane_y_resolution\">المستوى البؤري Y القرار</string>\n    <string name=\"tag_focal_plane_resolution_unit\">وحدة تحليل المستوى البؤري</string>\n    <string name=\"tag_subject_location\">موقع الموضوع</string>\n    <string name=\"tag_exposure_index\">مؤشر التعرض</string>\n    <string name=\"tag_sensing_method\">طريقة الاستشعار</string>\n    <string name=\"tag_file_source\">مصدر الملف</string>\n    <string name=\"tag_cfa_pattern\">نمط CFA</string>\n    <string name=\"tag_custom_rendered\">المقدمة المخصصة</string>\n    <string name=\"tag_exposure_mode\">وضع التعريض</string>\n    <string name=\"tag_white_balance\">توازن اللون الأبيض</string>\n    <string name=\"tag_digital_zoom_ratio\">نسبة التكبير الرقمي</string>\n    <string name=\"tag_focal_length_in_35mm_film\">البعد البؤري في فيلم 35 مم</string>\n    <string name=\"tag_scene_capture_type\">نوع التقاط المشهد</string>\n    <string name=\"tag_gain_control\">السيطرة على المكاسب</string>\n    <string name=\"tag_contrast\">مقابلة</string>\n    <string name=\"tag_saturation\">التشبع</string>\n    <string name=\"tag_sharpness\">حدة</string>\n    <string name=\"tag_device_setting_description\">وصف إعدادات الجهاز</string>\n    <string name=\"tag_subject_distance_range\">نطاق مسافة الموضوع</string>\n    <string name=\"tag_image_unique_id\">معرف الصورة الفريد</string>\n    <string name=\"tag_camera_owner_name\">اسم مالك الكاميرا</string>\n    <string name=\"tag_body_serial_number\">الرقم التسلسلي للجسم</string>\n    <string name=\"tag_lens_specification\">مواصفات العدسة</string>\n    <string name=\"tag_lens_make\">صنع العدسة</string>\n    <string name=\"tag_lens_model\">نموذج العدسة</string>\n    <string name=\"tag_lens_serial_number\">الرقم التسلسلي للعدسة</string>\n    <string name=\"tag_gps_version_id\">معرف إصدار نظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_latitude_ref\">مرجع خط العرض GPS</string>\n    <string name=\"tag_gps_latitude\">خط العرض GPS</string>\n    <string name=\"tag_gps_longitude_ref\">المرجع خط الطول لنظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_longitude\">خط الطول لنظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_altitude_ref\">مرجع ارتفاع نظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_altitude\">ارتفاع نظام تحديد المواقع</string>\n    <string name=\"tag_gps_timestamp\">الطابع الزمني لنظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_satellites\">الأقمار الصناعية لتحديد المواقع</string>\n    <string name=\"tag_gps_status\">حالة نظام تحديد المواقع</string>\n    <string name=\"tag_gps_measure_mode\">وضع قياس نظام تحديد المواقع</string>\n    <string name=\"tag_gps_dop\">نظام تحديد المواقع دوب</string>\n    <string name=\"tag_gps_speed_ref\">مرجع سرعة GPS</string>\n    <string name=\"tag_gps_speed\">سرعة نظام تحديد المواقع</string>\n    <string name=\"tag_gps_track_ref\">مرجع مسار نظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_track\">مسار نظام تحديد المواقع</string>\n    <string name=\"tag_gps_img_direction_ref\">المرجع اتجاه صورة GPS</string>\n    <string name=\"tag_gps_img_direction\">اتجاه صورة GPS</string>\n    <string name=\"tag_gps_map_datum\">مسند خريطة GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">المرجع لخط العرض الوجهة لنظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_dest_latitude\">GPS الوجهة العرض</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS الوجهة خط الطول المرجع</string>\n    <string name=\"tag_gps_dest_longitude\">GPS خط الطول الوجهة</string>\n    <string name=\"tag_gps_dest_bearing_ref\">المرجع المرجعي للوجهة بنظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_dest_bearing\">نظام تحديد المواقع العالمي (GPS) لتحديد الوجهة</string>\n    <string name=\"tag_gps_dest_distance_ref\">مرجع مسافة الوجهة GPS</string>\n    <string name=\"tag_gps_dest_distance\">مسافة الوجهة بنظام تحديد المواقع العالمي (GPS).</string>\n    <string name=\"tag_gps_processing_method\">طريقة معالجة نظام تحديد المواقع</string>\n    <string name=\"tag_gps_area_information\">معلومات منطقة GPS</string>\n    <string name=\"tag_gps_datestamp\">ختم تاريخ نظام تحديد المواقع</string>\n    <string name=\"tag_gps_differential\">نظام تحديد المواقع التفاضلي</string>\n    <string name=\"tag_gps_h_positioning_error\">خطأ في تحديد موضع GPS H</string>\n    <string name=\"tag_interoperability_index\">مؤشر التشغيل البيني</string>\n    <string name=\"tag_dng_version\">نسخة دي إن جي</string>\n    <string name=\"tag_default_crop_size\">حجم المحاصيل الافتراضي</string>\n    <string name=\"tag_orf_preview_image_start\">بداية معاينة الصورة</string>\n    <string name=\"tag_orf_preview_image_length\">معاينة طول الصورة</string>\n    <string name=\"tag_orf_aspect_frame\">إطار الجانب</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">الحد السفلي لجهاز الاستشعار</string>\n    <string name=\"tag_rw2_sensor_left_border\">استشعار الحدود اليسرى</string>\n    <string name=\"tag_rw2_sensor_right_border\">استشعار الحدود اليمنى</string>\n    <string name=\"tag_rw2_sensor_top_border\">الحد العلوي لجهاز الاستشعار</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"repeat_text_sub\">سيتم تكرار النص الحالي حتى نهاية المسار بدلاً من الرسم مرة واحدة</string>\n    <string name=\"dash_size\">حجم داش</string>\n    <string name=\"draw_mode_image_sub\">استخدم الصورة المحددة لرسمها على طول المسار المحدد</string>\n    <string name=\"draw_image_sub\">سيتم استخدام هذه الصورة كمدخل متكرر للمسار المرسوم</string>\n    <string name=\"outlined_triangle_sub\">رسم مثلث محدد من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"triangle_sub\">رسم مثلث محدد من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"outlined_triangle\">المثلث المبين</string>\n    <string name=\"triangle\">مثلث</string>\n    <string name=\"polygon_sub\">يرسم المضلع من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"polygon\">مضلع</string>\n    <string name=\"outlined_polygon\">المضلع المحدد</string>\n    <string name=\"outlined_polygon_sub\">يرسم المضلع المحدد من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"vertices\">القمم</string>\n    <string name=\"draw_regular_polygon\">ارسم مضلعًا منتظمًا</string>\n    <string name=\"draw_regular_polygon_sub\">ارسم المضلع الذي سيكون منتظمًا بدلًا من الشكل الحر</string>\n    <string name=\"star_sub\">يرسم النجمة من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"star\">نجم</string>\n    <string name=\"outlined_star\">النجمة المبينة</string>\n    <string name=\"outlined_star_sub\">رسم النجمة المحددة من نقطة البداية إلى نقطة النهاية</string>\n    <string name=\"inner_radius_ratio\">نسبة نصف القطر الداخلي</string>\n    <string name=\"draw_regular_star\">ارسم نجمة عادية</string>\n    <string name=\"draw_regular_star_sub\">ارسم النجمة التي ستكون منتظمة بدلاً من الشكل الحر</string>\n    <string name=\"antialias\">الحواف</string>\n    <string name=\"antialias_sub\">يفعّل الحواف لمنع الحواف الحادة</string>\n    <string name=\"open_edit_instead_of_preview\">افتح تحرير بدلاً من المعاينة</string>\n    <string name=\"open_edit_instead_of_preview_sub\">عند تحديد صورة لفتحها (معاينة) في ImageToolbox، سيتم فتح ورقة تحديد التحرير بدلاً من المعاينة</string>\n    <string name=\"document_scanner\">ماسح ضوئي للمستندات</string>\n    <string name=\"document_scanner_sub\">امسح المستندات ضوئيًا وإنشاء ملف PDF أو افصل الصور عنها</string>\n    <string name=\"click_to_start_scanning\">انقر لبدء المسح</string>\n    <string name=\"start_scanning\">ابدأ المسح</string>\n    <string name=\"save_as_pdf\">احفظ ك PDF</string>\n    <string name=\"share_as_pdf\">شارك ك PDF</string>\n    <string name=\"options_below_is_for_images\">الخيارات أدناه مخصصة لحفظ الصور، وليس PDF</string>\n    <string name=\"equalize_histogram_hsv\">معادلة الرسم البياني HSV</string>\n    <string name=\"equalize_histogram\">معادلة الرسم البياني</string>\n    <string name=\"enter_percentage\">أدخل النسبة المئوية</string>\n    <string name=\"allow_enter_by_text_field\">السماح بالدخول عن طريق حقل النص</string>\n    <string name=\"allow_enter_by_text_field_sub\">يفعّل حقل النص خلف تحديد الإعدادات المسبقة، لإدخالها بسرعة</string>\n    <string name=\"scale_color_space\">مقياس مساحة اللون</string>\n    <string name=\"linear\">خطي</string>\n    <string name=\"equalize_histogram_pixelation\">معادلة بكسل الرسم البياني</string>\n    <string name=\"grid_size_x\">حجم الشبكة X</string>\n    <string name=\"grid_size_y\">حجم الشبكة Y</string>\n    <string name=\"equalize_histogram_adaptive\">معادلة الرسم البياني التكيفي</string>\n    <string name=\"equalize_histogram_adaptive_luv\">معادلة الرسم البياني التكيفي LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">معادلة الرسم البياني التكيفي LAB</string>\n    <string name=\"clahe\">كلاهي</string>\n    <string name=\"clahe_lab\">مختبر كلاهي</string>\n    <string name=\"clahe_luv\">كلاهي لوف</string>\n    <string name=\"crop_to_content\">الاقتصاص إلى المحتوى</string>\n    <string name=\"frame_color\">لون الإطار</string>\n    <string name=\"color_to_ignore\">اللون الذي يجب تجاهله</string>\n    <string name=\"template\">نموذج</string>\n    <string name=\"no_template_filters\">لم تتم إضافة تصفيات القالب</string>\n    <string name=\"create_new\">أنشئ جديد</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">رمز QR الممسوح ضوئيًا ليس قالب تصفية صالحًا</string>\n    <string name=\"scan_qr_code\">امسح رمز QR</string>\n    <string name=\"opened_file_have_no_filter_template\">الملف المحدد لا يحتوي على بيانات قالب التصفية</string>\n    <string name=\"create_template\">أنشئ قالب</string>\n    <string name=\"template_name\">اسم القالب</string>\n    <string name=\"select_template_preview\">سيتم استخدام هذه الصورة لمعاينة قالب التصفية هذا</string>\n    <string name=\"template_filter\">تصفية القالب</string>\n    <string name=\"as_qr_code\">كصورة رمز الاستجابة السريعة</string>\n    <string name=\"as_file\">كملف</string>\n    <string name=\"save_as_file\">احفظ كملف</string>\n    <string name=\"save_as_qr_code_image\">احفظ كصورة رمز QR</string>\n    <string name=\"delete_template\">احذف القالب</string>\n    <string name=\"delete_template_warn\">أنت على وشك حذف عامل تصفية القالب المحدد. لا يمكن التراجع عن هذه العملية</string>\n    <string name=\"added_filter_template\">أُضيف قالب تصفية بالاسم \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">معاينة التصفية</string>\n    <string name=\"qr_code\">QR والرمز الشريطي</string>\n    <string name=\"qr_code_sub\">امسح رمز QR ضوئيًا واحصل على محتواه أو الصق سلسلتك لتوليد واحدة جديدة</string>\n    <string name=\"code_content\">محتوى الكود</string>\n    <string name=\"scan_qr_code_to_replace_content\">امسح أي رمز شريطي لاستبدال المحتوى الموجود في الحقل، أو اكتب شيئًا لتوليد رمز شريطي جديد بالنوع المحدد</string>\n    <string name=\"qr_description\">وصف QR</string>\n    <string name=\"min\">دقيقة</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">امنح إذن الكاميرا في الإعدادات لمسح رمز QR</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">امنح إذن الكاميرا في الإعدادات لمسح Document Scanner</string>\n    <string name=\"cubic\">مكعب</string>\n    <string name=\"bspline\">ب-الخط</string>\n    <string name=\"hamming\">هامينج</string>\n    <string name=\"hanning\">هانينج</string>\n    <string name=\"blackman\">بلاكمان</string>\n    <string name=\"welch\">ولش</string>\n    <string name=\"quadric\">رباعي</string>\n    <string name=\"gaussian\">غاوسي</string>\n    <string name=\"sphinx\">أبو الهول</string>\n    <string name=\"bartlett\">بارتليت</string>\n    <string name=\"robidoux\">روبيدوكس</string>\n    <string name=\"robidoux_sharp\">روبيدو شارب</string>\n    <string name=\"spline16\">الخط 16</string>\n    <string name=\"spline36\">الخط 36</string>\n    <string name=\"spline64\">الخط 64</string>\n    <string name=\"kaiser\">كايزر</string>\n    <string name=\"bartlett_hann\">بارتليت-هي</string>\n    <string name=\"box\">صندوق</string>\n    <string name=\"bohman\">بوهمان</string>\n    <string name=\"lanczos2\">لانكزوس 2</string>\n    <string name=\"lanczos3\">لانكزوس 3</string>\n    <string name=\"lanczos4\">لانكزوس 4</string>\n    <string name=\"lanczos2_jinc\">لانكزوس 2 جينك</string>\n    <string name=\"lanczos3_jinc\">لانكزوس 3 جينك</string>\n    <string name=\"lanczos4_jinc\">لانكزوس 4 جينك</string>\n    <string name=\"cubic_sub\">يوفر الاستيفاء المكعب تحجيمًا أكثر سلاسة من خلال النظر في أقرب 16 بكسل، مما يعطي نتائج أفضل من الخطين</string>\n    <string name=\"bspline_sub\">يستخدم الدوال متعددة الحدود المحددة لاستكمال وتقريب المنحنى أو السطح بسلاسة، وتمثيل الشكل المرن والمستمر</string>\n    <string name=\"hamming_sub\">وظيفة نافذة تستخدم لتقليل التسرب الطيفي عن طريق تضييق حواف الإشارة، وهي مفيدة في معالجة الإشارة</string>\n    <string name=\"hanning_sub\">أحد أشكال نافذة هان، يُستخدم عادةً لتقليل التسرب الطيفي في تطبيقات معالجة الإشارات</string>\n    <string name=\"blackman_sub\">وظيفة نافذة توفر دقة تردد جيدة عن طريق تقليل التسرب الطيفي، وغالبًا ما تستخدم في معالجة الإشارات</string>\n    <string name=\"welch_sub\">وظيفة نافذة مصممة لتوفير دقة تردد جيدة مع تقليل التسرب الطيفي، وغالبًا ما تستخدم في تطبيقات معالجة الإشارات</string>\n    <string name=\"quadric_sub\">طريقة تستخدم الدالة التربيعية للاستيفاء، مما يوفر نتائج سلسة ومستمرة</string>\n    <string name=\"gaussian_sub\">طريقة استيفاء تطبق دالة غاوسية، وهي مفيدة لتنعيم الصور وتقليل التشويش فيها</string>\n    <string name=\"sphinx_sub\">طريقة متقدمة لإعادة التشكيل توفر استيفاءً عالي الجودة مع الحد الأدنى من القطع الأثرية</string>\n    <string name=\"bartlett_sub\">وظيفة نافذة مثلثة تستخدم في معالجة الإشارات لتقليل التسرب الطيفي</string>\n    <string name=\"robidoux_sub\">طريقة استيفاء عالية الجودة مُحسّنة لتغيير الحجم الطبيعي للصورة، وموازنة الحدة والنعومة</string>\n    <string name=\"robidoux_sharp_sub\">نسخة أكثر وضوحًا من طريقة Robidoux، مُحسّنة لتغيير حجم الصورة بوضوح</string>\n    <string name=\"spline16_sub\">طريقة استيفاء قائمة على الشريحة توفر نتائج سلسة باستخدام تصفية ذو 16 نقرة</string>\n    <string name=\"spline36_sub\">طريقة استيفاء قائمة على الشريحة توفر نتائج سلسة باستخدام تصفية 36 نقرة</string>\n    <string name=\"spline64_sub\">طريقة استيفاء قائمة على الشريحة توفر نتائج سلسة باستخدام تصفية 64 نقرة</string>\n    <string name=\"kaiser_sub\">طريقة استيفاء تستخدم نافذة كايزر، مما يوفر تحكمًا جيدًا في المفاضلة بين عرض الفص الرئيسي ومستوى الفص الجانبي</string>\n    <string name=\"bartlett_hann_sub\">وظيفة نافذة هجينة تجمع بين نوافذ بارتليت وهان، تستخدم لتقليل التسرب الطيفي في معالجة الإشارات</string>\n    <string name=\"box_sub\">طريقة بسيطة لإعادة التشكيل تستخدم متوسط قيم أقرب بكسل، مما يؤدي غالبًا إلى ظهور ممتلئ</string>\n    <string name=\"bohman_sub\">وظيفة نافذة تستخدم لتقليل التسرب الطيفي، مما يوفر دقة تردد جيدة في تطبيقات معالجة الإشارات</string>\n    <string name=\"lanczos2_sub\">طريقة إعادة أخذ العينات تستخدم تصفية Lanczos ثنائي الفص للحصول على استيفاء عالي الجودة مع الحد الأدنى من الشوائب</string>\n    <string name=\"lanczos3_sub\">طريقة إعادة أخذ العينات تستخدم تصفية Lanczos ثلاثي الفصوص للحصول على استيفاء عالي الجودة مع الحد الأدنى من الشوائب</string>\n    <string name=\"lanczos4_sub\">طريقة إعادة أخذ العينات تستخدم تصفية Lanczos رباعي الفصوص للحصول على استيفاء عالي الجودة مع الحد الأدنى من الشوائب</string>\n    <string name=\"lanczos2_jinc_sub\">نوع مختلف من تصفية Lanczos 2 الذي يستخدم وظيفة jinc، مما يوفر استيفاءً عالي الجودة مع الحد الأدنى من الشوائب</string>\n    <string name=\"lanczos3_jinc_sub\">نوع مختلف من تصفية Lanczos 3 الذي يستخدم وظيفة jinc، مما يوفر استيفاءً عالي الجودة مع الحد الأدنى من الشوائب</string>\n    <string name=\"lanczos4_jinc_sub\">نوع مختلف من تصفية Lanczos 4 الذي يستخدم وظيفة jinc، مما يوفر استيفاءً عالي الجودة مع الحد الأدنى من الشوائب</string>\n    <string name=\"ewa_hanning\">هانينغ إيوا</string>\n    <string name=\"ewa_hanning_sub\">نوع المتوسط المرجح الإهليجي (EWA) من تصفية هانينغ للاستيفاء وإعادة التشكيل السلس</string>\n    <string name=\"ewa_robidoux\">روبيدو إيوا</string>\n    <string name=\"ewa_robidoux_sub\">نوع المتوسط المرجح الإهليجي (EWA) من تصفية Robidoux لإعادة التشكيل عالية الجودة</string>\n    <string name=\"ewa_blackman\">بلاكمان إيف</string>\n    <string name=\"ewa_blackman_sub\">نوع المتوسط المرجح البيضوي (EWA) من تصفية بلاكمان لتقليل التشويش الحلقي</string>\n    <string name=\"ewa_quadric\">رباعية EWA</string>\n    <string name=\"ewa_quadric_sub\">نوع المتوسط المرجح الإهليجي (EWA) من مرشح الرباعي للاستيفاء السلس</string>\n    <string name=\"ewa_robidoux_sharp\">روبيدو شارب إيوا</string>\n    <string name=\"ewa_robidoux_sharp_sub\">نوع المتوسط المرجح الإهليجي (EWA) من مرشح Robidoux Sharp للحصول على نتائج أكثر وضوحًا</string>\n    <string name=\"ewa_lanczos3_jinc\">لانكزوس 3 جينك إيوا</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">نوع المتوسط المرجح الإهليلجي (EWA) من مرشح جينك لانكوس 3 لإعادة التشكيل عالي الجودة مع تقليل التشويه الطيفي</string>\n    <string name=\"ginseng\">الجينسنغ</string>\n    <string name=\"ginseng_sub\">مرشح إعادة التشكيل مصمم لمعالجة الصور عالية الجودة مع توازن جيد بين الحدة والنعومة</string>\n    <string name=\"ewa_ginseng\">الجينسنغ إيوا</string>\n    <string name=\"ewa_ginseng_sub\">نظام التصفية Ginseng المحسّن باستخدام المتوسط المرجح الإهليجي (EWA) لتحسين جودة الصورة</string>\n    <string name=\"ewa_lanczos_sharp\">لانكزوس شارب إيوا</string>\n    <string name=\"ewa_lanczos_sharp_sub\">النسخة المتوسطة المرجحة الإهليلجية (EWA) من مرشح لانكزوس شارب لتحقيق نتائج حادة بأقل قدر من التشوهات</string>\n    <string name=\"ewa_lanczos_4_sharpest\">لانكزوس 4 شاربست إيوا</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">الإصدار EWA (المتوسط المرجح الإهليجي) من مرشح Lanczos 4 الأكثر حدة لإعادة تشكيل الصورة بدقة فائقة</string>\n    <string name=\"ewa_lanczos_soft\">لانكزوس سوفت إيوا</string>\n    <string name=\"ewa_lanczos_soft_sub\">نوع المتوسط المرجح الإهليلجي (EWA) من مرشح لانكزوس الناعم لإعادة تشكيل الصورة بشكل أكثر سلاسة</string>\n    <string name=\"haasn_soft\">حسن سوفت</string>\n    <string name=\"haasn_soft_sub\">مرشح إعادة تشكيل صممه Haasn لتحجيم الصورة بشكل سلس وخالي من الشوائب</string>\n    <string name=\"format_conversion\">تحويل التنسيق</string>\n    <string name=\"format_conversion_sub\">تحويل مجموعة من الصور من تنسيق إلى آخر</string>\n    <string name=\"dismiss_forever\">أهمِل إلى الأبد</string>\n    <string name=\"image_stacking\">تكديس الصور</string>\n    <string name=\"image_stacking_sub\">كدِّس الصور فوق بعضها البعض باستخدام أوضاع المزج المختارة</string>\n    <string name=\"add_image\">أضف صورة</string>\n    <string name=\"bins_count\">عدد الصناديق</string>\n    <string name=\"clahe_hsl\">كلاهي HSL</string>\n    <string name=\"clahe_hsv\">كلاش HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">معادلة الرسم البياني التكيفي HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">معادلة الرسم البياني التكيفي HSV</string>\n    <string name=\"edge_mode\">وضع الحافة</string>\n    <string name=\"clip\">مقطع</string>\n    <string name=\"wrap\">طَوّق</string>\n    <string name=\"color_blind_scheme\">عمى الألوان</string>\n    <string name=\"color_blind_scheme_sub\">حدّد السمة لتكييف ألوان السمة لمتغير عمى الألوان المحدّد</string>\n    <string name=\"protanomaly_sub\">صعوبة التمييز بين اللونين الأحمر والأخضر</string>\n    <string name=\"deuteranomaly_sub\">صعوبة التمييز بين اللونين الأخضر والأحمر</string>\n    <string name=\"tritanomaly_sub\">صعوبة التمييز بين اللونين الأزرق والأصفر</string>\n    <string name=\"protanopia_sub\">- عدم القدرة على إدراك الألوان الحمراء</string>\n    <string name=\"deuteranopia_sub\">- عدم القدرة على إدراك الألوان الخضراء</string>\n    <string name=\"tritanopia_sub\">- عدم القدرة على إدراك الألوان الزرقاء</string>\n    <string name=\"achromatomaly_sub\">انخفاض الحساسية لجميع الألوان</string>\n    <string name=\"achromatopsia_sub\">عمى الألوان الكامل، حيث لا يرى سوى درجات اللون الرمادي</string>\n    <string name=\"not_use_color_blind_scheme\">لا تستخدم نظام Color Blind</string>\n    <string name=\"not_use_color_blind_scheme_sub\">ستكون الألوان تمامًا كما هي محدّدة في السمة</string>\n    <string name=\"sigmoidal\">السيني</string>\n    <string name=\"lagrange_2\">لاغرانج 2</string>\n    <string name=\"lagrange_2_sub\">مرشح استيفاء لاغرانج من الرتبة 2، مناسب لقياس الصور عالي الجودة مع انتقالات سلسة</string>\n    <string name=\"lagrange_3\">لاغرانج 3</string>\n    <string name=\"lagrange_3_sub\">مرشح استيفاء لاغرانج من الدرجة 3، يوفر دقة أفضل ونتائج أكثر سلاسة لقياس الصورة</string>\n    <string name=\"lanczos_6\">لانكزوس 6</string>\n    <string name=\"lanczos_6_sub\">مرشح Lanczos لإعادة التشكيل بترتيب أعلى يبلغ 6، مما يوفر تحجيمًا أكثر وضوحًا ودقة للصورة</string>\n    <string name=\"lanczos_6_jinc\">لانكزوس 6 جينك</string>\n    <string name=\"lanczos_6_jinc_sub\">متغير من مرشح Lanczos 6 يستخدم وظيفة Jinc لتحسين جودة إعادة تشكيل الصورة</string>\n    <string name=\"linear_box_blur\">طمس المربع الخطي</string>\n    <string name=\"linear_tent_blur\">طمس الخيمة الخطية</string>\n    <string name=\"linear_gaussian_box_blur\">طمس مربع غاوسي الخطي</string>\n    <string name=\"linear_stack_blur\">طمس المكدس الخطي</string>\n    <string name=\"gaussian_box_blur\">طمس مربع غاوسي</string>\n    <string name=\"linear_fast_gaussian_blur_next\">تمويه غاوسي سريع خطي التالي</string>\n    <string name=\"linear_fast_gaussian_blur\">طمس غاوسي خطي سريع</string>\n    <string name=\"linear_gaussian_blur\">طمس غاوسي الخطي</string>\n    <string name=\"draw_filter_sub\">اختر مرشحًا واحدًا لاستخدامه كطلاء</string>\n    <string name=\"replace_filter\">استبدال الفلتر</string>\n    <string name=\"pick_filter_info\">اختر الفلتر أدناه لاستخدامه كفرشاة في الرسم</string>\n    <string name=\"tiff_compression_scheme\">نظام ضغط TIFF</string>\n    <string name=\"low_poly\">بولي منخفض</string>\n    <string name=\"sand_painting\">الرسم بالرمل</string>\n    <string name=\"image_splitting\">تقسيم الصورة</string>\n    <string name=\"image_splitting_sub\">تقسيم صورة واحدة حسب الصفوف أو الأعمدة</string>\n    <string name=\"fit_to_bounds\">صالح للحدود</string>\n    <string name=\"fit_to_bounds_sub\">ادمج وضع تغيير حجم الاقتصاص مع هذه المعلمة لتحقيق السلوك المطلوب (اقتصاص/ملاءمة نسبة العرض إلى الارتفاع)</string>\n    <string name=\"languages_imported\">استوردت اللغات بنجاح</string>\n    <string name=\"backup_ocr_models\">النسخ الاحتياطي لنماذج التعرف الضوئي على الحروف</string>\n    <string name=\"import_word\">استورد</string>\n    <string name=\"export\">صدِّر</string>\n    <string name=\"position\">موضع</string>\n    <string name=\"center\">مركز</string>\n    <string name=\"top_left\">أعلى اليسار</string>\n    <string name=\"top_right\">أعلى اليمين</string>\n    <string name=\"bottom_left\">أسفل اليسار</string>\n    <string name=\"bottom_right\">أسفل اليمين</string>\n    <string name=\"top_center\">أعلى المركز</string>\n    <string name=\"center_right\">مركز اليمين</string>\n    <string name=\"bottom_center\">مركز القاع</string>\n    <string name=\"center_left\">وسط اليسار</string>\n    <string name=\"target_image\">الصورة المستهدفة</string>\n    <string name=\"palette_transfer\">نقل لوحة</string>\n    <string name=\"enhanced_oil\">النفط المعزز</string>\n    <string name=\"simple_old_tv\">تلفزيون قديم بسيط</string>\n    <string name=\"hdr\">تقرير التنمية البشرية</string>\n    <string name=\"gotham\">جوثام</string>\n    <string name=\"simple_sketch\">رسم بسيط</string>\n    <string name=\"soft_glow\">توهج ناعم</string>\n    <string name=\"color_poster\">ملصق ملون</string>\n    <string name=\"tri_tone\">ثلاثي النغمة</string>\n    <string name=\"third_color\">اللون الثالث</string>\n    <string name=\"clahe_oklab\">كلاهي أوكلاب</string>\n    <string name=\"clahe_oklch\">كلارا أولش</string>\n    <string name=\"clahe_jzazbz\">كلاهي جازبز</string>\n    <string name=\"polka_dot\">المنقط</string>\n    <string name=\"clustered_2x2_dithering\">تذبذب متجمع 2x2</string>\n    <string name=\"clustered_4x4_dithering\">تذبذب سيارات الدفع الرباعي المتجمعة</string>\n    <string name=\"clustered_8x8_dithering\">تذبذب متجمع 8 × 8</string>\n    <string name=\"yililoma_dithering\">تذبذب ييليلوما</string>\n    <string name=\"no_favorite_options_selected\">لم يتم تحديد خيارات مفضلة، أضفهم في صفحة الأدوات</string>\n    <string name=\"add_favorites\">أضف التفضيلات</string>\n    <string name=\"harmony_complementary\">تكميلية</string>\n    <string name=\"harmony_analogous\">مماثل</string>\n    <string name=\"harmony_triadic\">ثلاثي</string>\n    <string name=\"harmony_split_complementary\">سبليت التكميلية</string>\n    <string name=\"harmony_tetradic\">رباعي</string>\n    <string name=\"harmony_square\">مربع</string>\n    <string name=\"harmony_analogous_complementary\">مماثل + مكمل</string>\n    <string name=\"color_tools\">أدوات اللون</string>\n    <string name=\"color_tools_sub\">يمكنك المزج وإنشاء النغمات وتوليد الظلال والمزيد</string>\n    <string name=\"color_harmonies\">تناغمات الألوان</string>\n    <string name=\"color_shading\">تظليل اللون</string>\n    <string name=\"variation\">تفاوت</string>\n    <string name=\"tints\">الصبغات</string>\n    <string name=\"tones\">نغمات</string>\n    <string name=\"shades\">ظلال</string>\n    <string name=\"color_mixing\">خلط الألوان</string>\n    <string name=\"color_info\">معلومات اللون</string>\n    <string name=\"selected_color\">اللون المحدد</string>\n    <string name=\"color_to_mix\">اللون للمزج</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">لا يمكن استخدام monet أثناء تشغيل الألوان الديناميكية</string>\n    <string name=\"lut512x512\">512 × 512 جدول ثنائي الأبعاد</string>\n    <string name=\"target_lut_image\">صورة الهدف LUT</string>\n    <string name=\"amatorka\">أحد الهواة</string>\n    <string name=\"miss_etikate\">ملكة جمال الآداب</string>\n    <string name=\"soft_elegance\">الأناقة الناعمة</string>\n    <string name=\"soft_elegance_variant\">البديل الناعم للأناقة</string>\n    <string name=\"palette_transfer_variant\">متغير نقل اللوحة</string>\n    <string name=\"cube_lut\">3D لوط</string>\n    <string name=\"target_cube_lut_file\">الهدف ملف LUT ثلاثي الأبعاد (.cube / .CUBE)</string>\n    <string name=\"lut\">طرفية المستعملين المحليين</string>\n    <string name=\"bleach_bypass\">تجاوز التبييض</string>\n    <string name=\"candlelight\">ضوء الشموع</string>\n    <string name=\"drop_blues\">إسقاط البلوز</string>\n    <string name=\"edgy_amber\">منفعل العنبر</string>\n    <string name=\"fall_colors\">ألوان الخريف</string>\n    <string name=\"film_stock_50\">مخزون الفيلم 50</string>\n    <string name=\"foggy_night\">ليلة ضبابية</string>\n    <string name=\"kodak\">كوداك</string>\n    <string name=\"save_empty_lut\">احصل على صورة LUT محايدة</string>\n    <string name=\"save_empty_lut_sub\">أولاً، استخدم تطبيق تحرير الصور المفضل لديك لتطبيق مرشح على LUT المحايد والذي يمكنك الحصول عليه هنا. لكي يعمل هذا بشكل صحيح، يجب ألا يعتمد كل لون بكسل على وحدات بكسل أخرى (على سبيل المثال، لن يعمل التمويه). بمجرد أن تصبح جاهزًا، استخدم صورة LUT الجديدة كمدخل لمرشح LUT 512*512</string>\n    <string name=\"pop_art\">فن البوب</string>\n    <string name=\"celluloid\">شريط سينمائي</string>\n    <string name=\"coffee\">قهوة</string>\n    <string name=\"golden_forest\">الغابة الذهبية</string>\n    <string name=\"greenish\">مخضر</string>\n    <string name=\"retro_yellow\">الرجعية الأصفر</string>\n    <string name=\"links_preview\">معاينة الروابط</string>\n    <string name=\"links_preview_sub\">تمكين استرداد معاينة الرابط في الأماكن التي يمكنك فيها الحصول على النص (QRCode، OCR، إلخ)</string>\n    <string name=\"links\">روابط</string>\n    <string name=\"ico_size_warning\">لا يمكن حفظ ملفات ICO إلا بالحجم الأقصى وهو 256 × 256</string>\n    <string name=\"gif_type_to_webp\">GIF إلى WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">تحويل صور GIF إلى صور متحركة WEBP</string>\n    <string name=\"webp_tools\">أدوات ويب</string>\n    <string name=\"webp_tools_sub\">تحويل الصور إلى صورة متحركة WEBP أو استخراج الإطارات من الرسوم المتحركة WEBP معينة</string>\n    <string name=\"webp_type_to_image\">WEBP للصور</string>\n    <string name=\"webp_type_to_image_sub\">تحويل ملف WEBP إلى مجموعة من الصور</string>\n    <string name=\"webp_type_to_webp_sub\">تحويل مجموعة من الصور إلى ملف WEBP</string>\n    <string name=\"webp_type_to_webp\">الصور إلى WEBP</string>\n    <string name=\"select_webp_image_to_start\">اختر صورة WEBP للبدء</string>\n    <string name=\"manage_storage_extra_types\">لا يوجد وصول كامل إلى الملفات</string>\n    <string name=\"manage_storage_extra_types_sub\">السماح لجميع الملفات بالوصول لرؤية JXL وQOI والصور الأخرى التي لم يتم التعرف عليها كصور على Android. بدون إذن، يتعذر على Image Toolbox عرض تلك الصور</string>\n    <string name=\"default_draw_color\">لون الرسم الافتراضي</string>\n    <string name=\"default_draw_path_mode\">وضع رسم المسار الافتراضي</string>\n    <string name=\"add_timestamp\">أضف الطابع الزمني</string>\n    <string name=\"add_timestamp_sub\">يفعّل إضافة الطابع الزمني إلى اسم ملف الإخراج</string>\n    <string name=\"formatted_timestamp\">الطابع الزمني المنسق</string>\n    <string name=\"formatted_timestamp_sub\">فعِّل تنسيق الطابع الزمني في اسم ملف الإخراج بدلاً من الميلي الأساسي</string>\n    <string name=\"enable_timestamps_to_format_them\">فعّل الطوابع الزمنية لتحديد تنسيقها</string>\n    <string name=\"one_time_save_location\">حفظ الموقع مرة واحدة</string>\n    <string name=\"one_time_save_location_sub\">اعرض وحرِّر مواقع الحفظ مرة واحدة والتي يمكنك استخدامها بالضغط لفترة طويلة على زر الحفظ في جميع الخيارات في الغالب</string>\n    <string name=\"recently_used\">المستخدمة مؤخرا</string>\n    <string name=\"ci_channel\">قناة سي.اي</string>\n    <string name=\"group\">مجموعة</string>\n    <string name=\"image_toolbox_in_telegram\">صندوق أدوات الصور في Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">انضم إلى محادثتنا حيث يمكنك مناقشة أي شيء تريده وكذلك الاطلاع على قناة CI حيث أنشر الإصدارات التجريبية والإعلانات</string>\n    <string name=\"ci_channel_sub\">احصل على إشعارات بشأن الإصدارات الجديدة من التطبيق، واقرأ الإعلانات</string>\n    <string name=\"fit_description\">لائم الصورة مع أبعاد معينة وطبّق التمويه أو اللون على الخلفية</string>\n    <string name=\"tools_arrangement\">ترتيب الأدوات</string>\n    <string name=\"group_tools_by_type\">أدوات المجموعة حسب النوع</string>\n    <string name=\"group_tools_by_type_sub\">تجميع الأدوات على الشاشة الرئيسية حسب نوعها بدلاً من ترتيب القائمة المخصصة</string>\n    <string name=\"default_values\">القيم الافتراضية</string>\n    <string name=\"system_bars_visibility\">رؤية أشرطة النظام</string>\n    <string name=\"show_system_bars_by_swipe\">إظهار أشرطة النظام عن طريق السحب</string>\n    <string name=\"show_system_bars_by_swipe_sub\">يفعّل الضرب لإظهار أشرطة النظام إذا كانت مخفية</string>\n    <string name=\"auto\">آلي</string>\n    <string name=\"hide_all\">إخفاء الكل</string>\n    <string name=\"show_all\">إظهار الكل</string>\n    <string name=\"hide_nav_bar\">إخفاء شريط التنقل</string>\n    <string name=\"hide_status_bar\">إخفاء شريط الحالة</string>\n    <string name=\"noise_generation\">توليد الضوضاء</string>\n    <string name=\"noise_generation_sub\">ولّد أصوات مختلفة مثل بيرلين أو أنواع أخرى</string>\n    <string name=\"frequency\">تكرار</string>\n    <string name=\"noise_type\">نوع الضوضاء</string>\n    <string name=\"rotation_type\">نوع التناوب</string>\n    <string name=\"fractal_type\">نوع كسورية</string>\n    <string name=\"octaves\">أوكتافات</string>\n    <string name=\"lacunarity\">نقص</string>\n    <string name=\"gain\">يكسب</string>\n    <string name=\"weighted_strength\">القوة المرجحة</string>\n    <string name=\"ping_pong_strength\">قوة بينج بونج</string>\n    <string name=\"distance_function\">وظيفة المسافة</string>\n    <string name=\"return_type\">نوع الإرجاع</string>\n    <string name=\"jitter\">غضب</string>\n    <string name=\"domain_warp\">تشوه المجال</string>\n    <string name=\"alignment\">تنسيق</string>\n    <string name=\"custom_filename\">اسم الملف المخصص</string>\n    <string name=\"custom_filename_sub\">حدد الموقع واسم الملف الذي سيتم استخدامه لحفظ الصورة الحالية</string>\n    <string name=\"saved_to_custom\">حُفظ في المجلد باسم مخصّص</string>\n    <string name=\"collage_maker\">صانع الكولاج</string>\n    <string name=\"collage_maker_sub\">اصنع صور مجمّعة من ما يصل إلى 20 صور</string>\n    <string name=\"collage_type\">نوع الكولاج</string>\n    <string name=\"collages_info\">امسك الصورة للتبديل والتحريك والتكبير لضبط الموضع</string>\n    <string name=\"disable_rotation\">تعطيل التدوير</string>\n    <string name=\"disable_rotation_sub\">يمنع تدوير الصور بإيماءات بإصبعين</string>\n    <string name=\"enable_snapping_to_borders\">فعّل الانطباق على الحدود</string>\n    <string name=\"enable_snapping_to_borders_sub\">بعد النقل أو التكبير/التصغير، سيتم التقاط الصور لملء حواف الإطار</string>\n    <string name=\"histogram\">الرسم البياني</string>\n    <string name=\"histogram_sub\">الرسم البياني للصورة RGB أو السطوع لمساعدتك في إجراء التضبيطات</string>\n    <string name=\"image_for_histogram\">سيتم استخدام هذه الصورة لتوليد رسوم بيانية RGB والسطوع</string>\n    <string name=\"tesseract_options\">خيارات تسراكت</string>\n    <string name=\"tesseract_options_sub\">تطبيق بعض متغيرات الإدخال لمحرك tesseract</string>\n    <string name=\"custom_options\">خيارات مخصصة</string>\n    <string name=\"custom_params_info\">يجب إدخال الخيارات باتباع هذا النمط: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">الاقتصاص التلقائي</string>\n    <string name=\"free_corners\">زوايا حرة</string>\n    <string name=\"free_corners_sub\">قص الصورة حسب المضلع، وهذا أيضًا يصحح المنظور</string>\n    <string name=\"coerce_points_to_image_bounds\">نقاط الإكراه إلى حدود الصورة</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">لن تكون النقاط محدودة بحدود الصورة، وهذا مفيد لتصحيح المنظور بشكل أكثر دقة</string>\n    <string name=\"mask\">قناع</string>\n    <string name=\"spot_heal_sub\">ملء علم المحتوى تحت المسار المرسوم</string>\n    <string name=\"spot_heal\">شفاء بقعة</string>\n    <string name=\"use_circle_kernel\">استخدم نواة الدائرة</string>\n    <string name=\"opening\">يفتح</string>\n    <string name=\"closing\">إغلاق</string>\n    <string name=\"morphological_gradient\">التدرج المورفولوجي</string>\n    <string name=\"top_hat\">القبعة العلوية</string>\n    <string name=\"black_hat\">القبعة السوداء</string>\n    <string name=\"tone_curves\">منحنيات النغمة</string>\n    <string name=\"reset_curves\">صفّر المنحنيات</string>\n    <string name=\"reset_curves_sub\">سيتم إرجاع المنحنيات إلى القيمة الافتراضية</string>\n    <string name=\"line_style\">نمط الخط</string>\n    <string name=\"gap_size\">حجم الفجوة</string>\n    <string name=\"dashed\">متقطع</string>\n    <string name=\"dot_dashed\">نقطة متقطعة</string>\n    <string name=\"stamped\">مختوم</string>\n    <string name=\"zigzag\">متعرج</string>\n    <string name=\"dashed_sub\">يرسم خطًا متقطعًا على طول المسار المرسوم بحجم فجوة محدد</string>\n    <string name=\"dot_dashed_sub\">رسم نقطة وخط متقطع على طول المسار المحدد</string>\n    <string name=\"defaultt_sub\">مجرد خطوط مستقيمة افتراضية</string>\n    <string name=\"stamped_sub\">يرسم الأشكال المحددة على طول المسار بمسافة محددة</string>\n    <string name=\"zigzag_sub\">يرسم خطًا متعرجًا متموجًا على طول المسار</string>\n    <string name=\"zigzag_ratio\">نسبة متعرجة</string>\n    <string name=\"create_shortcut\">أنشئ اختصار</string>\n    <string name=\"create_shortcut_title\">اختر أداة لتثبيتها</string>\n    <string name=\"create_shortcut_subtitle\">ستتم إضافة الأداة إلى الشاشة الرئيسية للمشغل الخاص بك كاختصار، استخدمها مع إعداد \\\"تخطي انتقاء الملفات\\\" لتحقيق السلوك المطلوب</string>\n    <string name=\"dont_stack_frames\">لا تكدس الإطارات</string>\n    <string name=\"dont_stack_frames_sub\">يتيح التخلص من الإطارات السابقة، بحيث لا تتكدس فوق بعضها البعض</string>\n    <string name=\"crossfade\">التلاشي المتقاطع</string>\n    <string name=\"crossfade_sub\">سيتم تداخل الإطارات مع بعضها البعض</string>\n    <string name=\"crossfade_count\">عدد الإطارات المتداخلة</string>\n    <string name=\"threshold_one\">العتبة الأولى</string>\n    <string name=\"threshold_two\">العتبة الثانية</string>\n    <string name=\"canny\">حكيم</string>\n    <string name=\"mirror_101\">مرآة 101</string>\n    <string name=\"enhanced_zoom_blur\">تعزيز طمس التكبير</string>\n    <string name=\"laplacian_simple\">لابلاس بسيط</string>\n    <string name=\"sobel_simple\">سوبيل بسيط</string>\n    <string name=\"helper_grid\">الشبكة المساعدة</string>\n    <string name=\"helper_grid_sub\">يُظهر الشبكة الداعمة أعلى منطقة الرسم للمساعدة في المعالجة الدقيقة</string>\n    <string name=\"grid_color\">لون الشبكة</string>\n    <string name=\"cell_width\">عرض الخلية</string>\n    <string name=\"cell_height\">ارتفاع الخلية</string>\n    <string name=\"compact_selectors\">محددات مدمجة</string>\n    <string name=\"compact_selectors_sub\">ستستخدم بعض عناصر التحكم في التحديد تخطيطًا مضغوطًا لشغل مساحة أقل</string>\n    <string name=\"grant_camera_permission_to_capture_image\">منح إذن الكاميرا في الإعدادات لالتقاط الصورة</string>\n    <string name=\"layout\">تَخطِيط</string>\n    <string name=\"main_screen_title\">عنوان الشاشة الرئيسية</string>\n    <string name=\"constant_rate_factor\">عامل المعدل الثابت (CRF)</string>\n    <string name=\"crf_sub\">القيمة %1$s تعني ضغطًا بطيئًا، مما يؤدي إلى حجم ملف صغير نسبيًا. %2$s يعني ضغطًا أسرع، مما يؤدي إلى ملف كبير.</string>\n    <string name=\"lut_library\">مكتبة لوط</string>\n    <string name=\"lut_library_sub\">نزّل مجموعة LUTs، والتي يمكنك تطبيقها بعد التنزيل</string>\n    <string name=\"lut_library_update_sub\">حدِّث مجموعة جداول البحث (سيتم وضع العناصر الجديدة فقط في قائمة الانتظار)، والتي يمكنك تطبيقها بعد التنزيل</string>\n    <string name=\"filter_preview_image_sub\">غيّر معاينة الصورة الافتراضية للتصفيات</string>\n    <string name=\"filter_preview_image\">معاينة الصورة</string>\n    <string name=\"hide\">يخفي</string>\n    <string name=\"show\">يعرض</string>\n    <string name=\"slider_type\">نوع المنزلق</string>\n    <string name=\"fancy\">باهِظ</string>\n    <string name=\"material_2\">المادة 2</string>\n    <string name=\"fancy_sub\">منزلق ذو مظهر فاخر. هذا هو الخيار الافتراضي</string>\n    <string name=\"material_2_sub\">شريط تمرير المادة 2</string>\n    <string name=\"material_you_slider_sub\">مادة أنت منزلق</string>\n    <string name=\"apply\">يتقدم</string>\n    <string name=\"center_align_dialog_buttons\">أزرار الحوار المركزية</string>\n    <string name=\"center_align_dialog_buttons_sub\">سيتم وضع أزرار الحوار في المنتصف بدلاً من الجانب الأيسر إن أمكن</string>\n    <string name=\"open_source_licenses\">تراخيص مفتوحة المصدر</string>\n    <string name=\"open_source_licenses_sub\">عرض تراخيص المكتبات مفتوحة المصدر المستخدمة في هذا التطبيق</string>\n    <string name=\"area\">منطقة</string>\n    <string name=\"area_sub\">إعادة التشكيل باستخدام علاقة منطقة البكسل. قد تكون هذه هي الطريقة المفضلة لتدمير الصورة، لأنها تعطي نتائج خالية من التموج في النسيج. ولكن عندما يتم تكبير الصورة، فهي تشبه طريقة \\\"الأقرب\\\".</string>\n    <string name=\"enable_tonemapping\">فعّل تعيين النغمات</string>\n    <string name=\"enter_percent\">يدخل ٪</string>\n    <string name=\"unknown_host\">لا يمكن الوصول إلى الموقع، حاول استخدام VPN أو تحقق مما إذا كان عنوان URL صحيحًا</string>\n    <string name=\"markup_layers\">طبقات العلامات</string>\n    <string name=\"markup_layers_sub\">وضع الطبقات مع القدرة على وضع الصور والنصوص والمزيد بحرية</string>\n    <string name=\"edit_layer\">حرِّر الطبقة</string>\n    <string name=\"layers_on_image\">طبقات على الصورة</string>\n    <string name=\"layers_on_image_sub\">استخدم صورة كخلفية وأضف طبقات مختلفة فوقها</string>\n    <string name=\"layers_on_background\">طبقات على الخلفية</string>\n    <string name=\"layers_on_background_sub\">نفس الخيار الأول ولكن مع اللون بدلاً من الصورة</string>\n    <string name=\"beta\">تجريبي</string>\n    <string name=\"fast_settings_side\">جانب الإعدادات السريعة</string>\n    <string name=\"fast_settings_side_sub\">أضف شريط عائم على الجانب المحدد أثناء تحرير الصور، مما سيؤدي إلى فتح الإعدادات السريعة عند النقر عليها</string>\n    <string name=\"clear_selection\">امحُ التحديد</string>\n    <string name=\"settings_group_visibility_hidden\">سيتم طي مجموعة الإعدادات \\\"%1$s\\\" بشكل افتراضي</string>\n    <string name=\"settings_group_visibility_visible\">سيتم توسيع مجموعة الإعدادات \\\"%1$s\\\" بشكل افتراضي</string>\n    <string name=\"base_64_tools\">أدوات Base64</string>\n    <string name=\"base_64_tools_sub\">فك ترميز سلسلة Base64 إلى صورة، أو رمّز الصورة إلى تنسيق Base64</string>\n    <string name=\"base_64\">قاعدة64</string>\n    <string name=\"not_a_valid_base_64\">القيمة المقدمة ليست سلسلة Base64 صالحة</string>\n    <string name=\"copy_not_a_valid_base_64\">لا يمكن نسخ سلسلة Base64 فارغة أو غير صالحة</string>\n    <string name=\"paste_base_64\">لصق Base64</string>\n    <string name=\"copy_base_64\">نسخ Base64</string>\n    <string name=\"base_64_tips\">حمّل الصورة لنسخ أو حفظ سلسلة Base64. إذا كان لديك السلسلة نفسها، يمكنك لصقها أعلاه للحصول على الصورة</string>\n    <string name=\"save_base_64\">احفظ Base64</string>\n    <string name=\"share_base_64\">شارك Base64</string>\n    <string name=\"options\">خيارات</string>\n    <string name=\"actions\">الإجراءات</string>\n    <string name=\"import_base_64\">استورد Base64</string>\n    <string name=\"base_64_actions\">إجراءات Base64</string>\n    <string name=\"add_outline\">أضف مخطط تفصيلي</string>\n    <string name=\"add_outline_sub\">أضف مخططًا تفصيليًا حول النص باللون والعرض المحددين</string>\n    <string name=\"outline_color\">لون المخطط التفصيلي</string>\n    <string name=\"outline_size\">حجم المخطط التفصيلي</string>\n    <string name=\"rotation\">تناوب</string>\n    <string name=\"checksum_as_filename\">المجموع الاختباري كاسم الملف</string>\n    <string name=\"checksum_as_filename_sub\">سيكون للصور الناتجة اسم يتوافق مع المجموع الاختباري لبياناتها</string>\n    <string name=\"free_software_partner\">البرمجيات الحرة (شريك)</string>\n    <string name=\"free_software_partner_sub\">المزيد من البرامج المفيدة في القناة الشريكة لتطبيقات Android</string>\n    <string name=\"algorithms\">خوارزمية</string>\n    <string name=\"checksum_tools\">أدوات المجموع الاختباري</string>\n    <string name=\"checksum_tools_sub\">قارن المجاميع الاختبارية أو احسب التجزئة أو أنشئ سلاسل سداسية عشرية من الملفات باستخدام خوارزميات تجزئة مختلفة</string>\n    <string name=\"calculate\">احسب</string>\n    <string name=\"text_hash\">تجزئة النص</string>\n    <string name=\"checksum\">المجموع الاختباري</string>\n    <string name=\"pick_file_to_checksum\">اختر الملف لحساب المجموع الاختباري الخاص به بناءً على الخوارزمية المحددة</string>\n    <string name=\"enter_text_to_checksum\">أدخل النص لحساب المجموع الاختباري الخاص به بناءً على الخوارزمية المحددة</string>\n    <string name=\"source_checksum\">المجموع الاختباري للمصدر</string>\n    <string name=\"checksum_to_compare\">المجموع الاختباري للمقارنة</string>\n    <string name=\"match\">مباراة!</string>\n    <string name=\"difference\">اختلاف</string>\n    <string name=\"match_sub\">المجاميع الاختبارية متساوية، ويمكن أن تكون آمنة</string>\n    <string name=\"difference_sub\">المجاميع الاختبارية ليست متساوية، يمكن أن يكون الملف غير آمن!</string>\n    <string name=\"mesh_gradients\">التدرجات شبكة</string>\n    <string name=\"collection_mesh_gradients_sub\">انظر إلى مجموعة Mesh Gradients عبر الإنترنت</string>\n    <string name=\"wrong_font\">يمكن استيراد خطوط TTF وOTF فقط</string>\n    <string name=\"import_font\">استورد خط (TTF/OTF)</string>\n    <string name=\"export_fonts\">صدِّر الخطوط</string>\n    <string name=\"imported_fonts\">الخطوط المستوردة</string>\n    <string name=\"error_while_saving\">حدث خطأ أثناء حفظ المحاولة، حاول تغيير مجلد الإخراج</string>\n    <string name=\"filename_is_not_set\">لم يتم تعيين اسم الملف</string>\n    <string name=\"none\">لا أحد</string>\n    <string name=\"custom_pages\">الصفحات المخصصة</string>\n    <string name=\"pages_selection\">اختيار الصفحات</string>\n    <string name=\"tool_exit_confirmation\">تأكيد خروج الأداة</string>\n    <string name=\"tool_exit_confirmation_sub\">إذا كانت لديك تغييرات غير محفوظة أثناء استخدام أدوات معينة وحاولت إغلاقها، فسيتم عرض مربع حوار التأكيد</string>\n    <string name=\"edit_exif_screen\">حرِّر EXIF</string>\n    <string name=\"edit_exif_screen_sub\">غيّر البيانات الوصفية لصورة واحدة دون إعادة الضغط</string>\n    <string name=\"edit_exif_tag\">انقر لتحرير العلامات المتاحة</string>\n    <string name=\"change_sticker\">غيّر الملصق</string>\n    <string name=\"fit_width\">عرض مناسب</string>\n    <string name=\"fit_height\">الارتفاع المناسب</string>\n    <string name=\"batch_compare\">دفعة مقارنة</string>\n    <string name=\"pick_files_to_checksum\">اختر الملف/الملفات لحساب المجموع الاختباري الخاص بها بناءً على الخوارزمية المحددة</string>\n    <string name=\"pick_files\">اختر الملفات</string>\n    <string name=\"pick_directory\">اختر الدليل</string>\n    <string name=\"head_length_scale\">مقياس طول الرأس</string>\n    <string name=\"stamp\">ختم</string>\n    <string name=\"timestamp\">الطابع الزمني</string>\n    <string name=\"format_pattern\">نمط التنسيق</string>\n    <string name=\"padding\">حشوة</string>\n    <string name=\"image_cutting\">قطع الصور</string>\n    <string name=\"image_cutting_sub\">قص جزء من الصورة ودمج الأجزاء اليسرى (يمكن أن تكون معكوسة) بخطوط رأسية أو أفقية</string>\n    <string name=\"vertical_pivot_line\">الخط المحوري العمودي</string>\n    <string name=\"horizontal_pivot_line\">الخط المحوري الأفقي</string>\n    <string name=\"inverse_selection\">الاختيار العكسي</string>\n    <string name=\"inverse_vertical_selection_sub\">سيتم ترك الجزء المقطوع عموديًا، بدلاً من دمج الأجزاء حول منطقة القطع</string>\n    <string name=\"inverse_horizontal_selection_sub\">سيتم ترك الجزء المقطوع أفقيًا، بدلاً من دمج الأجزاء حول منطقة القطع</string>\n    <string name=\"collection_mesh_gradients\">مجموعة من التدرجات شبكة</string>\n    <string name=\"mesh_gradients_sub\">أنشئ تدرجًا شبكيًا بكمية مخصصة من العقد والدقة</string>\n    <string name=\"gradient_maker_type_image_mesh\">شبكة تراكب التدرج</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">إنشاء تدرج شبكي أعلى الصور المعطاة</string>\n    <string name=\"points_customization\">تخصيص النقاط</string>\n    <string name=\"grid_size\">حجم الشبكة</string>\n    <string name=\"resolution_x\">القرار العاشر</string>\n    <string name=\"resolution_y\">القرار ص</string>\n    <string name=\"resolution\">دقة</string>\n    <string name=\"pixel_by_pixel\">بكسل بواسطة بكسل</string>\n    <string name=\"highlight_color\">تسليط الضوء على اللون</string>\n    <string name=\"pixel_comparison_type\">نوع مقارنة البكسل</string>\n    <string name=\"scan_barcode\">امسح الرمز الشريطي</string>\n    <string name=\"height_ratio\">نسبة الارتفاع</string>\n    <string name=\"barcode_type\">نوع الرمز الشريطي</string>\n    <string name=\"enforce_bw\">فرض B/W</string>\n    <string name=\"enforce_bw_sub\">ستكون صورة الرمز الشريطي باللونين الأبيض والأسود بالكامل ولن يتم تلوينها حسب سمة التطبيق</string>\n    <string name=\"barcodes_sub\">امسح أي رمز شريطي (QR، EAN، AZTEC، …) واحصل على محتواه أو الصق نصك لتوليد واحد جديد</string>\n    <string name=\"no_barcode_found\">لم يُعثر على رمز الشريطي</string>\n    <string name=\"generated_barcode_will_be_here\">سيكون الرمز الشريطي المولّد هنا</string>\n    <string name=\"audio_cover_extractor\">أغلفة الصوت</string>\n    <string name=\"audio_cover_extractor_sub\">استخرج صور غلاف الألبوم من الملفات الصوتية، ويدعم معظم التنسيقات الشائعة</string>\n    <string name=\"pick_audio_to_start\">اختر الصوت للبدء</string>\n    <string name=\"pick_audio\">اختر الصوت</string>\n    <string name=\"no_covers_found\">لم يتم العثور على أي أغطية</string>\n    <string name=\"send_logs\">إرسال السجلات</string>\n    <string name=\"send_logs_sub\">انقر لمشاركة ملف سجلات التطبيق، حيث يمكن أن يساعدني هذا في اكتشاف المشاكل وإصلاحها</string>\n    <string name=\"crash_title\">عفوًا… حدث خطأ ما</string>\n    <string name=\"crash_subtitle\">يمكنك الاتصال بي باستخدام الخيارات أدناه وسأحاول إيجاد حل.\\n(لا تنس إرفاق السجلات)</string>\n    <string name=\"ocr_write_to_file\">الكتابة إلى الملف</string>\n    <string name=\"ocr_write_to_file_sub\">استخرج النص من مجموعة الصور وخزنه في ملف نصي واحد</string>\n    <string name=\"ocr_write_to_metadata\">الكتابة إلى بيانات التعريف</string>\n    <string name=\"ocr_write_to_metadata_sub\">استخرج النص من كل صورة وضعه في معلومات EXIF للصور ذات الصلة</string>\n    <string name=\"invisible_mode\">الوضع غير المرئي</string>\n    <string name=\"invisible_mode_sub\">استخدم إخفاء المعلومات لإنشاء علامات مائية غير مرئية بالعين داخل وحدات البايت من صورك</string>\n    <string name=\"use_lsb\">استخدم إل إس بي</string>\n    <string name=\"use_lsb_sub\">سيتم استخدام طريقة إخفاء المعلومات LSB (بت أقل أهمية)، وإلا FD (مجال التردد)</string>\n    <string name=\"auto_remove_red_eyes\">أزل العيون الحمراء تلقائيًا</string>\n    <string name=\"password\">كلمة المرور</string>\n    <string name=\"unlock\">فتح</string>\n    <string name=\"pdf_is_protected\">PDF محمي</string>\n    <string name=\"operation_almost_complete\">اكتملت العملية تقريبًا. سيتطلب الإلغاء الآن إعادة تشغيله</string>\n    <string name=\"sort_by_date_modified\">تاريخ التعديل</string>\n    <string name=\"sort_by_date_modified_reversed\">تاريخ التعديل (معكوس)</string>\n    <string name=\"sort_by_size\">مقاس</string>\n    <string name=\"sort_by_size_reversed\">الحجم (معكوس)</string>\n    <string name=\"sort_by_mime_type\">نوع MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">نوع MIME (معكوس)</string>\n    <string name=\"sort_by_extension\">امتداد</string>\n    <string name=\"sort_by_extension_reversed\">تمديد (عكس)</string>\n    <string name=\"sort_by_date_added\">تاريخ الإضافة</string>\n    <string name=\"sort_by_date_added_reversed\">تاريخ الإضافة (معكوس)</string>\n    <string name=\"left_to_right\">من اليسار إلى اليمين</string>\n    <string name=\"right_to_left\">من اليمين إلى اليسار</string>\n    <string name=\"top_to_bottom\">من الأعلى إلى الأسفل</string>\n    <string name=\"bottom_to_top\">من الأسفل إلى الأعلى</string>\n    <string name=\"liquid_glass\">الزجاج السائل</string>\n    <string name=\"liquid_glass_sub\">مفتاح يعتمد على نظام التشغيل IOS 26 الذي تم الإعلان عنه مؤخرًا ونظام تصميم الزجاج السائل الخاص به</string>\n    <string name=\"pick_image_or_base64\">اختر صورة أو ألصِق/استورد بيانات Base64 أدناه</string>\n    <string name=\"type_image_link\">اكتب رابط الصورة للبدء</string>\n    <string name=\"paste_link\">لصق الرابط</string>\n    <string name=\"kaleidoscope\">المشكال</string>\n    <string name=\"secondary_angle\">زاوية ثانوية</string>\n    <string name=\"sides\">الجانبين</string>\n    <string name=\"channel_mix\">مزيج القناة</string>\n    <string name=\"blue_green\">أزرق أخضر</string>\n    <string name=\"red_blue\">أحمر أزرق</string>\n    <string name=\"green_red\">أحمر أخضر</string>\n    <string name=\"into_red\">إلى اللون الأحمر</string>\n    <string name=\"into_green\">إلى اللون الأخضر</string>\n    <string name=\"into_blue\">إلى اللون الأزرق</string>\n    <string name=\"cyan\">سماوي</string>\n    <string name=\"magenta\">أرجواني</string>\n    <string name=\"yellow\">أصفر</string>\n    <string name=\"color_halftone\">اللون النصفي</string>\n    <string name=\"contour\">كفاف</string>\n    <string name=\"levels\">المستويات</string>\n    <string name=\"offset\">إزاحة</string>\n    <string name=\"voronoi_crystallize\">تبلور فورونوي</string>\n    <string name=\"shape\">شكل</string>\n    <string name=\"stretch\">تمتد</string>\n    <string name=\"randomness\">العشوائية</string>\n    <string name=\"despeckle\">إزالة البقع</string>\n    <string name=\"diffuse\">منتشر</string>\n    <string name=\"dog\">كلب</string>\n    <string name=\"second_radius\">نصف القطر الثاني</string>\n    <string name=\"equalize\">معادلة</string>\n    <string name=\"glow\">يشع</string>\n    <string name=\"whirl_and_pinch\">دوامة وقرصة</string>\n    <string name=\"pointillize\">بوينتيليزي</string>\n    <string name=\"border_color\">لون الحدود</string>\n    <string name=\"polar_coordinates\">الإحداثيات القطبية</string>\n    <string name=\"rect_to_polar\">المستقيم إلى القطبية</string>\n    <string name=\"polar_to_rect\">القطبية لتصحيح</string>\n    <string name=\"invert_in_circle\">عكس في الدائرة</string>\n    <string name=\"reduce_noise\">تقليل الضوضاء</string>\n    <string name=\"simple_solarize\">سولاريز بسيط</string>\n    <string name=\"weave\">نسج</string>\n    <string name=\"x_gap\">X الفجوة</string>\n    <string name=\"y_gap\">Y الفجوة</string>\n    <string name=\"x_width\">عرض X</string>\n    <string name=\"y_wdth\">عرض ص</string>\n    <string name=\"twirl\">برم</string>\n    <string name=\"rubber_stmp\">ختم مطاطي</string>\n    <string name=\"smear\">تشويه</string>\n    <string name=\"density\">كثافة</string>\n    <string name=\"mix\">مزج</string>\n    <string name=\"sphere_lensh_distortion\">تشويه عدسة المجال</string>\n    <string name=\"refraction_index\">مؤشر الانكسار</string>\n    <string name=\"arc\">قوس</string>\n    <string name=\"spread_angle\">زاوية الانتشار</string>\n    <string name=\"sparkle\">التألق</string>\n    <string name=\"rays\">أشعة</string>\n    <string name=\"ascii\">أسكي</string>\n    <string name=\"gradient\">التدرج</string>\n    <string name=\"moire\">ماري</string>\n    <string name=\"autumn\">خريف</string>\n    <string name=\"bone\">عظم</string>\n    <string name=\"jet\">جيت</string>\n    <string name=\"winter\">شتاء</string>\n    <string name=\"ocean\">محيط</string>\n    <string name=\"summer\">صيف</string>\n    <string name=\"spring\">ربيع</string>\n    <string name=\"cool_variant\">البديل بارد</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">لون القرنفل</string>\n    <string name=\"hot\">حار</string>\n    <string name=\"parula\">كلمة</string>\n    <string name=\"magma\">الصهارة</string>\n    <string name=\"inferno\">جحيم</string>\n    <string name=\"plasma\">بلازما</string>\n    <string name=\"viridis\">فيريديس</string>\n    <string name=\"cividis\">المواطنين</string>\n    <string name=\"twilight\">الشفق</string>\n    <string name=\"twilight_shifted\">تحول الشفق</string>\n    <string name=\"auto_perspective\">منظور تلقائي</string>\n    <string name=\"deskew\">منحرف</string>\n    <string name=\"allow_crop\">السماح بالاقتصاص</string>\n    <string name=\"crop_or_perspective\">المحاصيل أو المنظور</string>\n    <string name=\"absolute\">مطلق</string>\n    <string name=\"turbo\">توربيني</string>\n    <string name=\"deep_green\">أخضر عميق</string>\n    <string name=\"lens_correction\">تصحيح العدسة</string>\n    <string name=\"target_lens_profile\">ملف تعريف العدسة المستهدفة بتنسيق JSON</string>\n    <string name=\"download_ready_lens_profiles\">نزّل ملفات تعريف العدسة الجاهزة</string>\n    <string name=\"part_percents\">النسب المئوية للجزء</string>\n    <string name=\"export_as_json\">صدِّر كـ JSON</string>\n    <string name=\"export_as_json_sub\">انسخ السلسلة باستخدام بيانات لوحة الألوان كتمثيل json</string>\n    <string name=\"seam_carving\">نحت التماس</string>\n    <string name=\"home_screen\">الشاشة الرئيسية</string>\n    <string name=\"lock_screen\">قفل الشاشة</string>\n    <string name=\"built_in\">مدمج</string>\n    <string name=\"wallpapers_export\">تصدير الخلفيات</string>\n    <string name=\"refresh\">أنعِش</string>\n    <string name=\"wallpapers_export_sub\">احصل على خلفيات الصفحة الرئيسية والقفل والخلفيات المدمجة الحالية</string>\n    <string name=\"allow_access_to_all_files_for_wp\">السماح بالوصول إلى جميع الملفات، وهذا ضروري لاسترداد الخلفيات</string>\n    <string name=\"allow_read_media_images_for_wp\">إدارة إذن التخزين الخارجي ليست كافية، فأنت بحاجة إلى السماح بالوصول إلى صورك، وتأكد من تحديد \\\"السماح للجميع\\\"</string>\n    <string name=\"add_preset_to_filename\">أضف الإعداد المسبق إلى اسم الملف</string>\n    <string name=\"add_preset_to_filename_sub\">إلحاق لاحقة بالإعداد المسبق المحدد لاسم ملف الصورة</string>\n    <string name=\"add_image_scale_mode_to_filename\">أضف وضع مقياس الصورة إلى اسم الملف</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">إلحاق لاحقة مع وضع مقياس الصورة المحدد لاسم ملف الصورة</string>\n    <string name=\"ascii_art\">فن أسكي (ASCII)</string>\n    <string name=\"ascii_art_sub\">تحويل الصورة إلى نص ASCII الذي سيبدو مثل الصورة</string>\n    <string name=\"params\">بارامس</string>\n    <string name=\"invert_colors_ascii_sub\">يتم تطبيق مرشح سلبي على الصورة للحصول على نتيجة أفضل في بعض الحالات</string>\n    <string name=\"processing_screenshot\">معالجة لقطة الشاشة</string>\n    <string name=\"screenshot_not_captured_try_again\">لم يتم التقاط لقطة الشاشة، حاول مرة أخرى</string>\n    <string name=\"skipped_saving\">تم تخطي الحفظ</string>\n    <string name=\"skipped_saving_multiple\">تم تخطي %1$s الملفات</string>\n    <string name=\"allow_skip_if_larger\">السماح بالتخطي إذا كان أكبر</string>\n    <string name=\"allow_skip_if_larger_sub\">سيتم السماح لبعض الأدوات بتخطي حفظ الصور إذا كان حجم الملف الناتج أكبر من الحجم الأصلي</string>\n    <string name=\"qr_type_calendar_event\">حدث التقويم</string>\n    <string name=\"qr_type_contact_info\">اتصال</string>\n    <string name=\"qr_type_email\">بريد إلكتروني</string>\n    <string name=\"qr_type_geo_point\">موقع</string>\n    <string name=\"qr_type_phone\">هاتف</string>\n    <string name=\"qr_type_plain\">نص</string>\n    <string name=\"qr_type_sms\">رسالة قصيرة</string>\n    <string name=\"qr_type_url\">عنوان URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">شبكة مفتوحة</string>\n    <string name=\"not_specified\">لا يوجد</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">هاتف</string>\n    <string name=\"message\">رسالة</string>\n    <string name=\"address\">عنوان</string>\n    <string name=\"subject\">موضوع</string>\n    <string name=\"body\">جسم</string>\n    <string name=\"name\">اسم</string>\n    <string name=\"organization\">منظمة</string>\n    <string name=\"title\">عنوان</string>\n    <string name=\"phones\">الهواتف</string>\n    <string name=\"emails\">رسائل البريد الإلكتروني</string>\n    <string name=\"urls\">عناوين URL</string>\n    <string name=\"addresses\">العناوين</string>\n    <string name=\"summary\">ملخص</string>\n    <string name=\"description\">وصف</string>\n    <string name=\"location\">موقع</string>\n    <string name=\"organizer\">منظم</string>\n    <string name=\"start_date\">تاريخ البدء</string>\n    <string name=\"end_date\">تاريخ الانتهاء</string>\n    <string name=\"status\">حالة</string>\n    <string name=\"latitude\">خط العرض</string>\n    <string name=\"longitude\">خط الطول</string>\n    <string name=\"create_barcode\">أنشئ رمز شريطي</string>\n    <string name=\"edit_barcode\">حرِّر الرمز شريطي</string>\n    <string name=\"wifi_configuration\">تكوين واي فاي</string>\n    <string name=\"security\">حماية</string>\n    <string name=\"pick_contact\">اختر جهة الاتصال</string>\n    <string name=\"grant_contact_permission\">منح جهات الاتصال الإذن في الإعدادات للملء التلقائي باستخدام جهة الاتصال المحددة</string>\n    <string name=\"contact_info\">معلومات الاتصال</string>\n    <string name=\"first_name\">الاسم الأول</string>\n    <string name=\"middle_name\">الاسم الأوسط</string>\n    <string name=\"last_name\">اسم العائلة</string>\n    <string name=\"pronunciation\">نطق</string>\n    <string name=\"add_phone\">أضف هاتف</string>\n    <string name=\"add_email\">أضف البريد الإلكتروني</string>\n    <string name=\"add_address\">أضف عنوانًا</string>\n    <string name=\"website\">موقع إلكتروني</string>\n    <string name=\"add_website\">أضف موقعًا إلكترونيًا</string>\n    <string name=\"formatted_name\">اسم منسق</string>\n    <string name=\"qr_code_top_image\">سيتم استخدام هذه الصورة لوضعها فوق الرمز شريطي</string>\n    <string name=\"code_customization\">تخصيص الكود</string>\n    <string name=\"qr_logo_image\">سيتم استخدام هذه الصورة كشعار في وسط رمز الاستجابة السريعة</string>\n    <string name=\"logo\">الشعار</string>\n    <string name=\"logo_padding\">حشوة الشعار</string>\n    <string name=\"logo_size\">حجم الشعار</string>\n    <string name=\"logo_corners\">زوايا الشعار</string>\n    <string name=\"fourth_eye\">العين الرابعة</string>\n    <string name=\"fourth_eye_description\">يضيف تماثل العين إلى رمز QR عن طريق إضافة العين الرابعة في الزاوية السفلية</string>\n    <string name=\"pixel_shape\">شكل بكسل</string>\n    <string name=\"frame_shape\">شكل الإطار</string>\n    <string name=\"ball_shape\">شكل الكرة</string>\n    <string name=\"error_correction_level\">مستوى تصحيح الخطأ</string>\n    <string name=\"dark_color\">اللون الداكن</string>\n    <string name=\"light_color\">لون فاتح</string>\n    <string name=\"hyper_os\">فرط نظام التشغيل</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS مثل الأسلوب</string>\n    <string name=\"mask_pattern\">نمط القناع</string>\n    <string name=\"code_may_be_not_scannable\">قد لا يكون هذا الرمز قابلاً للمسح الضوئي، غيّر معلمات المظهر لجعله قابلاً للقراءة على جميع الأجهزة</string>\n    <string name=\"not_scannable\">غير قابل للمسح الضوئي</string>\n    <string name=\"launcher_mode_sub\">ستبدو الأدوات مثل مشغل تطبيقات الشاشة الرئيسية لتكون أكثر إحكاما</string>\n    <string name=\"launcher_mode\">وضع المشغل</string>\n    <string name=\"flood_fill_sub\">يملأ المنطقة بالفرشاة والأسلوب المحددين</string>\n    <string name=\"flood_fill\">ملء الفيضان</string>\n    <string name=\"spray\">رذاذ</string>\n    <string name=\"spray_sub\">يرسم مسارًا على شكل جرافيتي</string>\n    <string name=\"square_particles\">الجسيمات المربعة</string>\n    <string name=\"square_particles_sub\">ستكون جزيئات الرش مربعة الشكل بدلاً من الدوائر</string>\n    <string name=\"palette_tools\">أدوات اللوحة</string>\n    <string name=\"palette_tools_sub\">ولّد لوحة أساسية/material you من الصورة، أو استورد/صدِّر عبر تنسيقات لوحة مختلفة</string>\n    <string name=\"edit_palette\">حرِّر اللوحة</string>\n    <string name=\"edit_palette_sub\">صدِّر/استورد لوحة عبر تنسيقات مختلفة</string>\n    <string name=\"color_name\">اسم اللون</string>\n    <string name=\"palette_name\">اسم اللوحة</string>\n    <string name=\"palette_format\">تنسيق اللوحة</string>\n    <string name=\"export_palette_sub\">صدِّر اللوحة التي المولّدة إلى تنسيقات مختلفة</string>\n    <string name=\"add_color_palette_sub\">يضيف لونًا جديدًا إلى اللوحة الحالية</string>\n    <string name=\"palette_name_not_supported\">تنسيق %1$s لا يدعم توفير اسم اللوحة</string>\n    <string name=\"wallpapers_export_not_avaialbe\">نظرًا لسياسات متجر Play، لا يمكن تضمين هذه الميزة في الإصدار الحالي. للوصول إلى هذه الوظيفة، يُرجى تنزيل ImageToolbox من مصدر بديل. يمكنك العثور على الإصدارات المتاحة على GitHub أدناه.</string>\n    <string name=\"open_github_page\">افتح صفحة Github</string>\n    <string name=\"overwrite_files_sub_short\">سيتم استبدال الملف الأصلي بملف جديد بدلاً من حفظه في المجلد المحدد</string>\n    <string name=\"hidden_watermark_text_detected\">تم اكتشاف نص العلامة المائية المخفية</string>\n    <string name=\"hidden_watermark_image_detected\">تم الكشف عن صورة العلامة المائية المخفية</string>\n    <string name=\"this_image_was_hidden\">أُخفت هذه الصورة</string>\n    <string name=\"generative_inpaint\">الرسم التوليدي</string>\n    <string name=\"generative_inpaint_sub\">يسمح لك بإزالة الكائنات في الصورة باستخدام نموذج الذكاء الاصطناعي، دون الاعتماد على OpenCV. لاستخدام هذه الميزة، سيقوم التطبيق بتنزيل النموذج المطلوب (حوالي 200 ميجابايت) من GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">يسمح لك بإزالة الكائنات في الصورة باستخدام نموذج الذكاء الاصطناعي، دون الاعتماد على OpenCV. قد تكون هذه عملية طويلة الأمد</string>\n    <string name=\"error_level_analysis\">تحليل مستوى الخطأ</string>\n    <string name=\"luminance_gradient\">التدرج النصوع</string>\n    <string name=\"average_distance\">متوسط المسافة</string>\n    <string name=\"copy_move_detection\">كشف نقل النسخ</string>\n    <string name=\"retain\">يحتفظ</string>\n    <string name=\"coefficent\">معامل</string>\n    <string name=\"clipboard_data_is_too_large\">بيانات الحافظة كبيرة جدًا</string>\n    <string name=\"data_is_too_large_to_copy\">البيانات كبيرة جدًا بحيث لا يمكن نسخها</string>\n    <string name=\"simple_weave_pixelization\">نسج بسيط Pixelization</string>\n    <string name=\"staggered_pixelization\">بكسل متداخلة</string>\n    <string name=\"cross_pixelization\">عبر البكسل</string>\n    <string name=\"micro_macro_pixelization\">بكسل مايكرو ماكرو</string>\n    <string name=\"orbital_pixelization\">البكسل المداري</string>\n    <string name=\"vortex_pixelization\">دوامة البكسل</string>\n    <string name=\"pulse_grid_pixelization\">نبض شبكة البكسل</string>\n    <string name=\"nucleus_pixelization\">بكسل النواة</string>\n    <string name=\"radial_weave_pixelization\">شعاعي نسج بكسل</string>\n    <string name=\"cannot_open_uri\">لا يمكن فتح عنوان uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">وضع تساقط الثلوج</string>\n    <string name=\"enabled\">ممكّن</string>\n    <string name=\"border_frame\">إطار الحدود</string>\n    <string name=\"glitch_variant\">البديل خلل</string>\n    <string name=\"channel_shift\">تحول القناة</string>\n    <string name=\"max_offset\">ماكس إزاحة</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">كتلة خلل</string>\n    <string name=\"block_size\">حجم الكتلة</string>\n    <string name=\"crt_curvature\">انحناء CRT</string>\n    <string name=\"curvature\">انحناء</string>\n    <string name=\"chroma\">صفاء</string>\n    <string name=\"pixel_melt\">بكسل تذوب</string>\n    <string name=\"max_drop\">ماكس قطرة</string>\n    <string name=\"ai_tools\">أدوات الذكاء الاصطناعي</string>\n    <string name=\"ai_tools_sub\">أدوات مختلفة لمعالجة الصور من خلال نماذج الذكاء الاصطناعي مثل إزالة القطع الأثرية أو تقليل الضوضاء</string>\n    <string name=\"model_anime_undeint\">ضغط، خطوط خشنة</string>\n    <string name=\"model_broadcast\">الرسوم المتحركة، ضغط البث</string>\n    <string name=\"model_rgb_max_denoise_fp16\">ضغط عام، ضوضاء عامة</string>\n    <string name=\"model_wb_denoise\">ضجيج الرسوم المتحركة عديم اللون</string>\n    <string name=\"model_span_anime_pretrain\">سريع، ضغط عام، ضوضاء عامة، رسوم متحركة/كاريكاتير/أنيمي</string>\n    <string name=\"model_book_scan\">مسح الكتاب</string>\n    <string name=\"model_overexposure\">تصحيح التعرض</string>\n    <string name=\"model_fbcnn_color_fp16\">الأفضل في الضغط العام والصور الملونة</string>\n    <string name=\"model_fbcnn_gray_fp16\">الأفضل في الضغط العام للصور ذات التدرج الرمادي</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">الضغط العام، الصور ذات التدرج الرمادي، أقوى</string>\n    <string name=\"model_scunet_color_gan_fp16\">الضوضاء العامة والصور الملونة</string>\n    <string name=\"model_scunet_color_psnr_fp16\">الضوضاء العامة والصور الملونة وتفاصيل أفضل</string>\n    <string name=\"model_scunet_gray_15_fp16\">الضوضاء العامة والصور ذات التدرج الرمادي</string>\n    <string name=\"model_scunet_gray_25_fp16\">الضوضاء العامة، الصور ذات التدرج الرمادي، أقوى</string>\n    <string name=\"model_scunet_gray_50_fp16\">الضوضاء العامة، الصور ذات التدرج الرمادي، الأقوى</string>\n    <string name=\"model_jpeg_destroyer\">ضغط عام</string>\n    <string name=\"model_jaywreck\">ضغط عام</string>\n    <string name=\"model_h264\">التركيب، ضغط h264</string>\n    <string name=\"model_vhs\">ضغط VHS</string>\n    <string name=\"model_cinepak\">الضغط غير القياسي (cinepak، msvideo1، roq)</string>\n    <string name=\"model_debink_v4\">ضغط بينك، أفضل في الهندسة</string>\n    <string name=\"model_debink_v5\">ضغط بينك، أقوى</string>\n    <string name=\"model_debink_v6\">ضغط بينك، ناعم، يحتفظ بالتفاصيل</string>\n    <string name=\"model_antialias\">القضاء على تأثير خطوة الدرج، والتنعيم</string>\n    <string name=\"model_kdm_scans\">الأعمال الفنية/الرسومات الممسوحة ضوئيًا، والضغط الخفيف، والتموج في النسيج</string>\n    <string name=\"model_bandage\">النطاقات اللونية</string>\n    <string name=\"model_halftone\">بطيئة، وإزالة الألوان النصفية</string>\n    <string name=\"model_colorizer\">أداة تلوين عامة للصور ذات التدرج الرمادي/الأبيض والأسود، للحصول على نتائج أفضل استخدم DDColor</string>\n    <string name=\"model_deedge\">إزالة الحافة</string>\n    <string name=\"model_desharpen\">يزيل الحدة الزائدة</string>\n    <string name=\"model_dither\">بطيء، متردد</string>\n    <string name=\"model_gainres\">تنعيم، التحف العامة، CGI</string>\n    <string name=\"model_kdm003_scans\">معالجة المسح الضوئي KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">نموذج تحسين الصورة خفيف الوزن</string>\n    <string name=\"model_bcgone_detailed_v2\">إزالة قطعة أثرية الضغط</string>\n    <string name=\"model_bcgone_smooth\">إزالة قطعة أثرية الضغط</string>\n    <string name=\"model_bandage_smooth\">إزالة الضمادات مع نتائج سلسة</string>\n    <string name=\"model_bendel_halftone\">معالجة نمط الألوان النصفية</string>\n    <string name=\"model_dither_deleter_v3_smooth\">إزالة نمط التردد V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">إزالة آثار JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">تحسين نسيج H.264</string>\n    <string name=\"model_vhs_sharpen\">شحذ وتعزيز VHS</string>\n    <string name=\"merging\">دمج</string>\n    <string name=\"chunk_size\">حجم القطعة</string>\n    <string name=\"overlap_size\">حجم التداخل</string>\n    <string name=\"note_chunk_info\">سيتم تقطيع الصور التي يزيد حجمها عن %1$s بكسل إلى شرائح ومعالجتها إلى أجزاء، ويتم مزجها بشكل متداخل لمنع ظهور طبقات مرئية.</string>\n    <string name=\"large_chunk_warning\">يمكن أن تؤدي الأحجام الكبيرة إلى عدم الاستقرار مع الأجهزة المنخفضة الجودة</string>\n    <string name=\"select_one_to_start\">اختر واحدة للبدء</string>\n    <string name=\"delete_model_sub\">هل تريد حذف نموذج %1$s؟ سوف تحتاج إلى تنزيله مرة أخرى</string>\n    <string name=\"confirm\">يتأكد</string>\n    <string name=\"models\">نماذج</string>\n    <string name=\"downloaded_models\">النماذج المُنزلة</string>\n    <string name=\"available_models\">النماذج المتاحة</string>\n    <string name=\"preparing\">تحضير</string>\n    <string name=\"active_model\">نموذج نشط</string>\n    <string name=\"failed_to_open_session\">فشل فتح الجلسة</string>\n    <string name=\"only_onnx_models\">يمكن استيراد نماذج .onnx/.ort فقط</string>\n    <string name=\"import_model\">استورد نموذج</string>\n    <string name=\"import_model_sub\">استورد نموذج onnx مخصص لمزيد من الاستخدام، يتم قبول نماذج onnx/ort فقط، ويدعم جميع المتغيرات المشابهة لـ esrgan تقريبًا</string>\n    <string name=\"imported_models\">نماذج مستوردة</string>\n    <string name=\"model_scunet_color_15_fp16\">الضوضاء العامة والصور الملونة</string>\n    <string name=\"model_scunet_color_25_fp16\">الضوضاء العامة، الصور الملونة، أقوى</string>\n    <string name=\"model_scunet_color_50_fp16\">الضوضاء العامة، الصور الملونة، الأقوى</string>\n    <string name=\"model_artifacts_dithering_alsa\">يقلل من ثبات الألوان ونطاقات الألوان، مما يحسن التدرجات الناعمة ومناطق الألوان المسطحة.</string>\n    <string name=\"model_nmkd_brighten_redux\">يعزز سطوع الصورة وتباينها من خلال الإبرازات المتوازنة مع الحفاظ على الألوان الطبيعية.</string>\n    <string name=\"model_nmkd_brighten\">يقوم بتفتيح الصور الداكنة مع الحفاظ على التفاصيل وتجنب التعرض المفرط.</string>\n    <string name=\"model_nmkd_detoon\">يزيل تنغيم اللون الزائد ويستعيد توازن اللون الأكثر حيادية وطبيعية.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">يطبق تنغيم الضوضاء المعتمد على Poisson مع التركيز على الحفاظ على التفاصيل الدقيقة والأنسجة.</string>\n    <string name=\"model_noise_toner_poisson_soft\">يطبق تنغيم ضوضاء Poisson الناعم للحصول على نتائج بصرية أكثر سلاسة وأقل عدوانية.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">يركز تنغيم الضوضاء الموحد على الحفاظ على التفاصيل ووضوح الصورة.</string>\n    <string name=\"model_noise_toner_uniform_soft\">نغمة ضوضاء موحدة لطيفة للحصول على ملمس رقيق ومظهر ناعم.</string>\n    <string name=\"model_repainter\">إصلاح المناطق التالفة أو غير المستوية عن طريق إعادة طلاء القطع الأثرية وتحسين تناسق الصورة.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">نموذج debanding خفيف الوزن يزيل نطاقات الألوان بأقل تكلفة للأداء.</string>\n    <string name=\"model_jpeg_0_20\">يعمل على تحسين الصور باستخدام عناصر ضغط عالية جدًا (جودة 0-20%) لتحسين الوضوح.</string>\n    <string name=\"model_jpeg_20_40\">تحسين الصور بتأثيرات ضغط عالية (جودة 20-40%)، واستعادة التفاصيل وتقليل التشويش.</string>\n    <string name=\"model_jpeg_40_60\">يعمل على تحسين الصور بالضغط المعتدل (جودة 40-60%)، وموازنة الحدة والنعومة.</string>\n    <string name=\"model_jpeg_60_80\">ينقي الصور بضغط خفيف (جودة 60-80%) لتحسين التفاصيل والأنسجة الدقيقة.</string>\n    <string name=\"model_jpeg_80_100\">يعمل على تحسين الصور التي لا يمكن فقدانها تقريبًا (جودة 80-100%) مع الحفاظ على المظهر والتفاصيل الطبيعية.</string>\n    <string name=\"model_spongecolor_lite\">تلوين بسيط وسريع، رسوم متحركة، ليست مثالية</string>\n    <string name=\"model_deblr\">يقلل من ضبابية الصورة قليلاً، ويحسن الحدة دون إدخال أي تشويش.</string>\n    <string name=\"processing_channel\">عمليات تشغيل طويلة</string>\n    <string name=\"processing_image\">معالجة الصورة</string>\n    <string name=\"processing\">يعالج</string>\n    <string name=\"model_artifacts_jpg_0_20\">يزيل آثار ضغط JPEG الثقيلة في الصور ذات الجودة المنخفضة جدًا (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">يقلل من آثار JPEG القوية في الصور المضغوطة للغاية (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">ينظف عناصر JPEG المعتدلة مع الحفاظ على تفاصيل الصورة (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">ينقي عناصر JPEG الخفيفة في صور ذات جودة عالية إلى حد ما (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">يقلل بمهارة من آثار JPEG البسيطة في الصور التي لا تفقد البيانات تقريبًا (80-100%).</string>\n    <string name=\"model_redetail_v2\">يعزز التفاصيل الدقيقة والأنسجة، مما يحسن الحدة الملموسة دون المؤثرات الثقيلة.</string>\n    <string name=\"processing_finished\">انتهت المعالجة</string>\n    <string name=\"processing_failed\">فشلت المعالجة</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">يعزز نسيج البشرة وتفاصيلها مع الحفاظ على المظهر الطبيعي، الأمثل للسرعة.</string>\n    <string name=\"model_sbdv_dejpeg\">يزيل آثار ضغط JPEG ويستعيد جودة الصورة للصور المضغوطة.</string>\n    <string name=\"model_iso_denoise_v1\">يقلل من ضوضاء ISO في الصور الملتقطة في ظروف الإضاءة المنخفضة، مع الحفاظ على التفاصيل.</string>\n    <string name=\"model_dejumbo\">يصحح التعريض الزائد أو التظليلات \\\"الضخمة\\\" ويستعيد توازنًا لونيًا أفضل.</string>\n    <string name=\"model_ddcolor_tiny\">نموذج تلوين خفيف الوزن وسريع يضيف ألوانًا طبيعية إلى الصور ذات التدرج الرمادي.</string>\n    <string name=\"type_dejpeg\">ديجبيج</string>\n    <string name=\"type_denoise\">دينواز</string>\n    <string name=\"type_colorize\">تلوين</string>\n    <string name=\"type_artifacts\">التحف</string>\n    <string name=\"type_enhance\">يحسن</string>\n    <string name=\"type_anime\">أنيمي</string>\n    <string name=\"type_scans\">المسح</string>\n    <string name=\"type_upscale\">الراقي</string>\n    <string name=\"model_realesrgan_x4v3\">جهاز ترقية X4 للصور العامة؛ نموذج صغير يستخدم معالج الرسوميات (GPU) ووقتًا أقل، مع تقليل التشويش وتقليل الضوضاء بشكل معتدل.</string>\n    <string name=\"model_realesrgan_x2plus\">جهاز ترقية X2 للصور العامة والحفاظ على الأنسجة والتفاصيل الطبيعية.</string>\n    <string name=\"model_realesrgan_x4plus\">أداة ترقية X4 للصور العامة مع مواد محسنة ونتائج واقعية.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">مُحسّن X4 لصور الأنيمي؛ 6 كتل RRDB لخطوط وتفاصيل أكثر وضوحًا.</string>\n    <string name=\"model_realesrnet_x4plus\">يؤدي جهاز ترقية X4 مع فقدان MSE إلى الحصول على نتائج أكثر سلاسة وتقليل الشوائب للصور العامة.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler مُحسّن لصور الأنيمي؛ متغير 4B32F بتفاصيل أكثر وضوحًا وخطوط ناعمة.</string>\n    <string name=\"model_ultrasharp_v2_x4\">طراز X4 UltraSharp V2 للصور العامة؛ يؤكد الحدة والوضوح.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 ألتراشارب V2 لايت؛ أسرع وأصغر، ويحافظ على التفاصيل مع استخدام ذاكرة GPU أقل.</string>\n    <string name=\"model_rmbg_1_4\">نموذج خفيف الوزن لإزالة الخلفية بسرعة. الأداء المتوازن والدقة. يعمل مع الصور والأشياء والمشاهد. يوصى به لمعظم حالات الاستخدام.</string>\n    <string name=\"type_removebg\">أزِل الخلفية</string>\n    <string name=\"horizontal_border_thickness\">سمك الحدود الأفقية</string>\n    <string name=\"vertical_border_thickness\">سمك الحدود العمودية</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"zero\">لا لون</item>\n        <item quantity=\"one\">لون</item>\n        <item quantity=\"two\">لونان</item>\n        <item quantity=\"few\">%1$s لون</item>\n        <item quantity=\"many\">%1$s لون</item>\n        <item quantity=\"other\">%1$s لون</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">النموذج الحالي لا يدعم التقطيع، ستتم معالجة الصورة بالأبعاد الأصلية، وقد يتسبب ذلك في استهلاك كبير للذاكرة ومشكلات مع الأجهزة المنخفضة الجودة</string>\n    <string name=\"chunking_disabled\">عُطّل التقطيع، ستتم معالجة الصورة بالأبعاد الأصلية، وقد يتسبب ذلك في استهلاك كبير للذاكرة ومشكلات مع الأجهزة المنخفضة الجودة ولكنه قد يعطي نتائج أفضل عند الاستدلال</string>\n    <string name=\"chunking\">التقطيع</string>\n    <string name=\"model_u2net\">نموذج تجزئة الصور عالي الدقة لإزالة الخلفية</string>\n    <string name=\"model_u2netp\">إصدار خفيف الوزن من U2Net لإزالة الخلفية بشكل أسرع مع استخدام ذاكرة أصغر.</string>\n    <string name=\"model_ddcolor\">يوفر نموذج DDColor الكامل تلوينًا عالي الجودة للصور العامة مع الحد الأدنى من الشوائب. أفضل خيار لجميع نماذج التلوين.</string>\n    <string name=\"model_ddcolor_artistic\">مجموعات البيانات الفنية الخاصة والمدربة على DDColor؛ ينتج نتائج تلوين متنوعة وفنية مع عدد أقل من التحف اللونية غير الواقعية.</string>\n    <string name=\"model_birefnet\">نموذج BiRefNet خفيف الوزن يعتمد على Swin Transformer لإزالة الخلفية بدقة.</string>\n    <string name=\"model_inspyrenet\">إزالة خلفية عالية الجودة بحواف حادة والحفاظ على التفاصيل بشكل ممتاز، خاصة على الكائنات المعقدة والخلفيات الصعبة.</string>\n    <string name=\"model_isnet\">نموذج إزالة الخلفية الذي ينتج أقنعة دقيقة ذات حواف ناعمة، مناسبة للأشياء العامة والحفاظ على التفاصيل بشكل معتدل.</string>\n    <string name=\"model_already_downloaded\">النموذج مُنزّل بالفعل</string>\n    <string name=\"model_successfully_imported\">استوردت النموذج بنجاح</string>\n    <string name=\"type\">يكتب</string>\n    <string name=\"keyword\">الكلمة الرئيسية</string>\n    <string name=\"very_fast\">سريع جدًا</string>\n    <string name=\"normal\">طبيعي</string>\n    <string name=\"slow\">بطيء</string>\n    <string name=\"very_slow\">بطيء جدًا</string>\n    <string name=\"compute_percents\">احسب النسب المئوية</string>\n    <string name=\"minimum_value_is\">القيمة الأدنى هي %1$s</string>\n    <string name=\"warp_sub\">شوّه الصورة بالرسم بالأصابع</string>\n    <string name=\"warp\">طي</string>\n    <string name=\"hardness\">الصلابة</string>\n    <string name=\"warp_mode\">وضع الطي</string>\n    <string name=\"warp_mode_move\">حرّك</string>\n    <string name=\"warp_mode_grow\">وسِّع</string>\n    <string name=\"warp_mode_shrink\">قلِّص</string>\n    <string name=\"warp_mode_swirl_cw\">تدور في اتجاه عقارب الساعة</string>\n    <string name=\"warp_mode_swirl_ccw\">تدور عكس عقارب الساعة</string>\n    <string name=\"fade_strength\">قوة التلاشي</string>\n    <string name=\"top_drop\">أعلى قطرة</string>\n    <string name=\"bottom_drop\">إسقاط القاع</string>\n    <string name=\"start_drop\">ابدأ بالاسقاط</string>\n    <string name=\"end_drop\">نهاية السقوط</string>\n    <string name=\"downloading\">يُنزّل</string>\n    <string name=\"smooth_shapes\">الأشكال السلسة</string>\n    <string name=\"smooth_shapes_sub\">استخدم القطع الناقص الفائق بدلاً من المستطيلات المستديرة القياسية للحصول على أشكال أكثر سلاسة وطبيعية</string>\n    <string name=\"shape_type\">نوع الشكل</string>\n    <string name=\"cut\">يقطع</string>\n    <string name=\"rounded\">مدور</string>\n    <string name=\"smooth\">سلس</string>\n    <string name=\"cut_shapes_sub\">حواف حادة بدون تقريب</string>\n    <string name=\"rounded_shapes_sub\">زوايا مستديرة كلاسيكية</string>\n    <string name=\"shapes_type\">نوع الأشكال</string>\n    <string name=\"corners_size\">حجم الزوايا</string>\n    <string name=\"squircle\">سكويركل</string>\n    <string name=\"squircle_shapes_sub\">عناصر واجهة المستخدم مدورة أنيقة</string>\n    <string name=\"filename_format\">تنسيق اسم الملف</string>\n    <string name=\"prefix_pattern_description\">نص مخصص يتم وضعه في بداية اسم الملف، وهو مثالي لأسماء المشاريع أو العلامات التجارية أو العلامات الشخصية.</string>\n    <string name=\"original_filename_pattern_description\">يستخدم اسم الملف الأصلي بدون امتداد، مما يساعدك على الحفاظ على تعريف المصدر سليمًا.</string>\n    <string name=\"width_pattern_description\">عرض الصورة بالبكسل، مفيد لتتبع تغييرات الدقة أو قياس النتائج.</string>\n    <string name=\"height_pattern_description\">ارتفاع الصورة بالبكسل، وهو أمر مفيد عند التعامل مع نسب العرض إلى الارتفاع أو عمليات التصدير.</string>\n    <string name=\"random_numbers_pattern_description\">يولّد أرقام عشوائية لضمان أسماء ملفات فريدة من نوعها؛ أضف المزيد من الأرقام لمزيد من الأمان ضد التكرارات.</string>\n    <string name=\"sequence_number_pattern_description\">عداد متزايد تلقائيًا لصادرات الدُفعات، وهو مثالي عند حفظ صور متعدّدة في جلسة واحدة.</string>\n    <string name=\"preset_info_pattern_description\">يقوم بإدراج اسم الإعداد المسبق المطبق في اسم الملف حتى تتمكن من تذكر كيفية معالجة الصورة بسهولة.</string>\n    <string name=\"scale_mode_pattern_description\">يعرض وضع تغيير حجم الصورة المستخدم أثناء المعالجة، مما يساعد على تمييز الصور التي تم تغيير حجمها أو اقتصاصها أو تركيبها.</string>\n    <string name=\"suffix_pattern_description\">نص مخصص يتم وضعه في نهاية اسم الملف، وهو مفيد لإصدارات مثل _v2، أو _edited، أو _final.</string>\n    <string name=\"extension_pattern_description\">امتداد الملف (png، jpg، webp، وما إلى ذلك)، يطابق تلقائيًا التنسيق الفعلي المحفوظ.</string>\n    <string name=\"formatted_timestamp_pattern_description\">طابع زمني قابل للتخصيص يتيح لك تحديد التنسيق الخاص بك من خلال مواصفات جافا للفرز المثالي.</string>\n    <string name=\"fling_type\">نوع القذف</string>\n    <string name=\"android_native\">الروبوت الأصلي</string>\n    <string name=\"ios_style\">نمط دائرة الرقابة الداخلية</string>\n    <string name=\"smooth_curve\">منحنى سلس</string>\n    <string name=\"quick_stop\">توقف سريع</string>\n    <string name=\"bouncy\">نطاط</string>\n    <string name=\"floaty\">عائم</string>\n    <string name=\"snappy\">لاذع</string>\n    <string name=\"ultra_smooth\">فائق النعومة</string>\n    <string name=\"adaptive\">التكيف</string>\n    <string name=\"accessibility_aware\">علم إمكانية الوصول</string>\n    <string name=\"reduced_motion\">انخفاض الحركة</string>\n    <string name=\"android_native_sub\">فيزياء التمرير الأصلية لنظام Android لمقارنة خط الأساس</string>\n    <string name=\"smooth_sub\">التمرير المتوازن والسلس للاستخدام العام</string>\n    <string name=\"ios_style_sub\">سلوك تمرير عالي الاحتكاك يشبه نظام iOS</string>\n    <string name=\"smooth_curve_sub\">منحنى فريد من نوعه لإحساس التمرير المميز</string>\n    <string name=\"quick_stop_sub\">التمرير الدقيق مع التوقف السريع</string>\n    <string name=\"bouncy_sub\">تمريرة نطاطة مرحة وسريعة الاستجابة</string>\n    <string name=\"floaty_sub\">مخطوطات طويلة ومزلقة لتصفح المحتوى</string>\n    <string name=\"snappy_sub\">تمرير سريع وسريع الاستجابة لواجهات المستخدم التفاعلية</string>\n    <string name=\"ultra_smooth_sub\">تمرير سلس ممتاز مع زخم ممتد</string>\n    <string name=\"adaptive_sub\">يضبط الفيزياء على أساس سرعة الدفع</string>\n    <string name=\"accessibility_aware_sub\">يحترم إعدادات إمكانية الوصول إلى النظام</string>\n    <string name=\"reduced_motion_sub\">الحد الأدنى من الحركة لتلبية احتياجات الوصول</string>\n    <string name=\"primary_lines\">الخطوط الأولية</string>\n    <string name=\"primary_lines_sub\">يضيف خطًا أكثر سمكًا في كل سطر خامس</string>\n    <string name=\"fill_color\">لون التعبئة</string>\n    <string name=\"hidden_tools\">الأدوات المخفية</string>\n    <string name=\"hidden_for_share\">أدوات مخفية للمشاركة</string>\n    <string name=\"color_library\">مكتبة الألوان</string>\n    <string name=\"color_library_sub\">تصفح مجموعة واسعة من الألوان</string>\n    <string name=\"model_fatality_deblur\">يعمل على زيادة حدة الصور وإزالة التشويش منها مع الحفاظ على التفاصيل الطبيعية، وهو مثالي لإصلاح الصور خارج نطاق التركيز.</string>\n    <string name=\"model_unresize_v3\">يستعيد الصور التي تم تغيير حجمها مسبقًا بذكاء، ويستعيد التفاصيل والأنسجة المفقودة.</string>\n    <string name=\"model_liveaction_v1_span\">تم تحسينه لمحتوى الحركة الحية، ويقلل من تأثيرات الضغط ويعزز التفاصيل الدقيقة في إطارات الأفلام/البرامج التلفزيونية.</string>\n    <string name=\"model_vhs2hd_realplksr\">يحول لقطات بجودة VHS إلى HD، مما يزيل ضوضاء الشريط ويعزز الدقة مع الحفاظ على المظهر القديم.</string>\n    <string name=\"model_text2hd_v1\">مخصص للصور ذات النصوص الثقيلة ولقطات الشاشة، ويزيد من حدة الأحرف ويحسن إمكانية القراءة.</string>\n    <string name=\"model_frankendata_pretrainer\">تم تدريب الترقية المتقدمة على مجموعات بيانات متنوعة، وهي ممتازة لتحسين الصور للأغراض العامة.</string>\n    <string name=\"model_realwebphoto_v2\">تم تحسينه للصور المضغوطة على الويب، ويزيل آثار JPEG ويستعيد المظهر الطبيعي.</string>\n    <string name=\"model_realwebphoto_v4\">نسخة محسنة لصور الويب مع الحفاظ بشكل أفضل على الملمس وتقليل الشوائب.</string>\n    <string name=\"model_dat_2x\">ترقية 2x باستخدام تقنية محول التجميع المزدوج، تحافظ على الوضوح والتفاصيل الطبيعية.</string>\n    <string name=\"model_dat_3x\">ترقية 3x باستخدام بنية المحولات المتقدمة، مثالية لاحتياجات التوسيع المعتدلة.</string>\n    <string name=\"model_dat_4x\">ترقية الجودة العالية 4x باستخدام شبكة محولات حديثة، تحافظ على التفاصيل الدقيقة بمقاييس أكبر.</string>\n    <string name=\"model_nafnet_deblurring\">يزيل الضبابية/الضوضاء والاهتزازات من الصور. للأغراض العامة ولكن الأفضل في الصور.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">يستعيد الصور ذات الجودة المنخفضة باستخدام محول Swin2SR، الأمثل لتدهور BSRGAN. رائعة لإصلاح التحف المضغوطة الثقيلة وتحسين التفاصيل بمقياس 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">ترقية 4x باستخدام محول SwinIR المدرب على تحلل BSRGAN. يستخدم GAN للحصول على مواد أكثر وضوحًا وتفاصيل أكثر طبيعية في الصور والمشاهد المعقدة.</string>\n    <string name=\"path\">طريق</string>\n    <string name=\"merge_pdf\">دمج PDF</string>\n    <string name=\"merge_pdf_sub\">دمج ملفات PDF متعدّدة في مستند واحد</string>\n    <string name=\"files_order\">ترتيب الملفات</string>\n    <string name=\"pages_short\">ص.</string>\n    <string name=\"split_pdf\">تقسيم PDF</string>\n    <string name=\"split_pdf_sub\">استخرج صفحات محدّدة من مستند PDF</string>\n    <string name=\"rotate_pdf\">تدوير PDF</string>\n    <string name=\"rotate_pdf_sub\">إصلاح اتجاه الصفحة بشكل دائم</string>\n    <string name=\"pages\">الصفحات</string>\n    <string name=\"rearrange_pdf\">إعادة ترتيب PDF</string>\n    <string name=\"rearrange_pdf_sub\">اسحب واسقط الصفحات لإعادة ترتيبها</string>\n    <string name=\"hold_drag_drop\">اضغط على الصفحات واسحبها</string>\n    <string name=\"page_numbers\">أرقام الصفحات</string>\n    <string name=\"page_numbers_sub\">أضف الترقيم إلى مستنداتك تلقائيًا</string>\n    <string name=\"label_format\">تنسيق التسمية</string>\n    <string name=\"pdf_to_text\">PDF إلى نص (OCR)</string>\n    <string name=\"pdf_to_text_sub\">استخرج نص عادي من مستندات PDF الخاصة بك</string>\n    <string name=\"watermark_pdf_sub\">تراكب نص مخصص للعلامة التجارية أو الأمان</string>\n    <string name=\"signature\">إمضاء</string>\n    <string name=\"signature_sub\">أضف توقيعك الإلكتروني إلى أي مستند</string>\n    <string name=\"will_be_for_signature\">سيتم استخدام هذا كتوقيع</string>\n    <string name=\"unlock_pdf\">فتح ملف PDF</string>\n    <string name=\"unlock_pdf_sub\">أزِل كلمات السر من ملفاتك المحمية</string>\n    <string name=\"protect_pdf\">حماية PDF</string>\n    <string name=\"protect_pdf_sub\">أمن مستنداتك بتعمية قوية</string>\n    <string name=\"success\">نجاح</string>\n    <string name=\"pdf_unlocked\">PDF مقفل، يمكنك حفظه أو مشاركته</string>\n    <string name=\"repair_pdf\">إصلاح PDF</string>\n    <string name=\"repair_pdf_sub\">محاولة إصلاح المستندات التالفة أو غير القابلة للقراءة</string>\n    <string name=\"grayscale\">تدرج الرمادي</string>\n    <string name=\"grayscale_pdf_sub\">تحويل كافة الصور المضمنة في الوثيقة إلى التدرج الرمادي</string>\n    <string name=\"compress_pdf\">اضغط PDF</string>\n    <string name=\"compress_pdf_sub\">حسّن حجم ملف مستندك لتسهيل المشاركة</string>\n    <string name=\"repair_info\">يقوم ImageToolbox بإعادة بناء جدول الإسناد الترافقي الداخلي ويعيد توليد بنية الملف من البداية. يمكن أن يؤدي هذا إلى استعادة الوصول إلى العديد من الملفات التي \\\"لا يمكن فتحها\\\"</string>\n    <string name=\"grayscale_info\">تقوم هذه الأداة بتحويل جميع صور المستندات إلى تدرج رمادي. الأفضل للطباعة وتقليل حجم الملف</string>\n    <string name=\"metadata\">البيانات الوصفية</string>\n    <string name=\"metadata_pdf_sub\">حرِّر خصائص الوثيقة لتحسين الخصوصية</string>\n    <string name=\"tags\">العلامات</string>\n    <string name=\"producer\">منتج</string>\n    <string name=\"author\">مؤلف</string>\n    <string name=\"keywords\">الكلمات الرئيسية</string>\n    <string name=\"creator\">الخالق</string>\n    <string name=\"privacy_deep_clean\">الخصوصية العميقة النظيفة</string>\n    <string name=\"privacy_deep_clean_sub\">امسح كافة البيانات التعريفية المتوفرة لهذا المستند</string>\n    <string name=\"page\">صفحة</string>\n    <string name=\"deep_ocr\">التعرف الضوئي على الحروف العميق</string>\n    <string name=\"deep_ocr_sub\">استخرج النص من المستند وخزنه في ملف نصي واحد باستخدام محرك Tesseract</string>\n    <string name=\"cant_remove_all\">لا يمكن إزالة كل الصفحات</string>\n    <string name=\"remove_pages_pdf\">أزِل صفحات PDF</string>\n    <string name=\"remove_pages_pdf_sub\">أزِل صفحات محدّدة من مستند PDF</string>\n    <string name=\"tap_to_remove\">انقر لإزالة</string>\n    <string name=\"manually\">يدويا</string>\n    <string name=\"crop_pdf\">قص ملف PDF</string>\n    <string name=\"crop_pdf_sub\">قص صفحات المستند إلى أي حدود</string>\n    <string name=\"flatten_pdf\">سطح PDF</string>\n    <string name=\"flatten_pdf_sub\">اجعل ملف PDF غير قابل للتعديل عن طريق تنقيط صفحات المستند</string>\n    <string name=\"camera_failed_to_open\">تعذر تشغيل الكاميرا. يرجى التحقق من الأذونات والتأكد من عدم استخدامها بواسطة تطبيق آخر.</string>\n    <string name=\"extract_images\">استخرج صور</string>\n    <string name=\"extract_images_sub\">استخرج الصور المضمّنة في ملفات PDF بدقتها الأصلية</string>\n    <string name=\"pdf_no_embedded\">لا يحتوي ملف PDF هذا على أي صور مضمنة</string>\n    <string name=\"extract_images_info\">تقوم هذه الأداة بمسح كل صفحة واستعادة الصور المصدرية ذات الجودة الكاملة، وهي مثالية لحفظ النسخ الأصلية من المستندات</string>\n    <string name=\"draw_signature\">رسم التوقيع</string>\n    <string name=\"pen_params\">معلمات القلم</string>\n    <string name=\"draw_signature_sub\">استخدم التوقيع الخاص كصورة لوضعها على المستندات</string>\n    <string name=\"zip_pdf\">الرمز البريدي PDF</string>\n    <string name=\"zip_pdf_sub\">قسّم المستند بفاصل زمني محدّد وحزم المستندات الجديدة في أرشيف مضغوط</string>\n    <string name=\"interval\">فاصلة</string>\n    <string name=\"print_pdf\">اطبع PDF</string>\n    <string name=\"print_pdf_sub\">جهّز مستند للطباعة بحجم صفحة مخصّص</string>\n    <string name=\"pages_per_sheet\">صفحات لكل ورقة</string>\n    <string name=\"orientation\">توجيه</string>\n    <string name=\"page_size\">حجم الصفحة</string>\n    <string name=\"margin\">هامِش</string>\n    <string name=\"bloom\">يزدهر</string>\n    <string name=\"soft_knee\">الركبة الناعمة</string>\n    <string name=\"model_realesr_animevideo_v3x4\">الأمثل للأنيمي والرسوم المتحركة. ترقية سريعة مع ألوان طبيعية محسنة وعدد أقل من القطع الأثرية</string>\n    <string name=\"one_ui_sub\">سامسونج One UI 7 مثل الاسلوب</string>\n    <string name=\"calculate_hint\">أدخل رموز الرياضيات الأساسية هنا لحساب القيمة المطلوبة (على سبيل المثال (5+5)*10)</string>\n    <string name=\"math_expression\">التعبير الرياضي</string>\n    <string name=\"pick_up_to_n_collage_images\">التقط ما يصل إلى %1$s من الصور</string>\n    <string name=\"keep_date_time\">احتفظ بالتاريخ والوقت</string>\n    <string name=\"keep_date_time_sub\">احتفظ دائمًا بعلامات exif المتعلقة بالتاريخ والوقت، ويعمل بشكل مستقل عن خيار keep exif</string>\n    <string name=\"background_color_for_alpha_formats\">لون الخلفية لتنسيقات ألفا</string>\n    <string name=\"background_color_for_alpha_formats_sub\">يضيف القدرة على تعيين لون الخلفية لكل تنسيق صورة مع دعم ألفا، عند تعطيله يكون هذا متاحًا للتنسيقات غير ألفا فقط</string>\n    <string name=\"open_markup_project\">مشروع مفتوح</string>\n    <string name=\"open_markup_project_sub\">استمر في تحرير مشروع Image Toolbox المحفوظ مسبقًا</string>\n    <string name=\"markup_project_open_failed\">غير قادر على فتح مشروع Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">يفتقد مشروع Image Toolbox بيانات المشروع</string>\n    <string name=\"markup_project_corrupted\">مشروع Image Toolbox تالف</string>\n    <string name=\"unsupported_markup_project_version\">إصدار مشروع Image Toolbox غير مدعوم: %1$d</string>\n    <string name=\"save_markup_project\">حفظ المشروع</string>\n    <string name=\"save_markup_project_sub\">قم بتخزين الطبقات والخلفية وسجل التحرير في ملف مشروع قابل للتحرير</string>\n    <string name=\"failed_to_open\">فشل في الفتح</string>\n    <string name=\"ocr_write_to_searchable_pdf\">الكتابة إلى ملف PDF قابل للبحث</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">تعرف على النص من مجموعة الصور واحفظ ملف PDF القابل للبحث مع الصورة وطبقة النص القابلة للتحديد</string>\n    <string name=\"layer_alpha\">طبقة ألفا</string>\n    <string name=\"horizontal_flip\">الوجه الأفقي</string>\n    <string name=\"vertical_flip\">الوجه العمودي</string>\n    <string name=\"lock\">قفل</string>\n    <string name=\"add_shadow\">أضف الظل</string>\n    <string name=\"shadow_color\">لون الظل</string>\n    <string name=\"text_geometry\">هندسة النص</string>\n    <string name=\"text_geometry_sub\">قم بتمديد النص أو تحريفه للحصول على أسلوب أكثر وضوحًا</string>\n    <string name=\"scale_x\">مقياس X</string>\n    <string name=\"skew_x\">انحراف X</string>\n    <string name=\"remove_annotations\">إزالة التعليقات التوضيحية</string>\n    <string name=\"remove_annotations_sub\">قم بإزالة أنواع التعليقات التوضيحية المحددة مثل الروابط أو التعليقات أو الإبرازات أو الأشكال أو حقول النموذج من صفحات PDF</string>\n    <string name=\"annotation_link\">الارتباطات التشعبية</string>\n    <string name=\"annotation_file_attachment\">مرفقات الملفات</string>\n    <string name=\"annotation_line\">خطوط</string>\n    <string name=\"annotation_popup\">النوافذ المنبثقة</string>\n    <string name=\"annotation_stamp\">الطوابع</string>\n    <string name=\"annotation_shapes\">الأشكال</string>\n    <string name=\"annotation_text\">ملاحظات نصية</string>\n    <string name=\"annotation_text_markup\">ترميز النص</string>\n    <string name=\"annotation_widget\">حقول النموذج</string>\n    <string name=\"annotation_markup\">العلامات</string>\n    <string name=\"annotation_unknown\">مجهول</string>\n    <string name=\"annotations\">الشروح</string>\n    <string name=\"ungroup\">فك التجميع</string>\n    <string name=\"add_shadow_sub\">أضف ظلًا ضبابيًا خلف الطبقة مع لون وإزاحات قابلة للتكوين</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-be/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"pick_image\">Выберыце малюнак для пачатку</string>\n    <string name=\"height\">Вышыня %1$s</string>\n    <string name=\"explicit\">Спецыфічны</string>\n    <string name=\"app_closing\">Закрыццё праграмы</string>\n    <string name=\"reset_image_sub\">Змены выявы вернуцца да пачатковых значэнняў</string>\n    <string name=\"reset\">Скід</string>\n    <string name=\"copied\">Скапіравана ў буфер абмену</string>\n    <string name=\"exception\">Выключэнне</string>\n    <string name=\"ok\">Ок</string>\n    <string name=\"no_exif\">Дадзеныя EXIF не знойдзены</string>\n    <string name=\"add_tag\">Дадаць тэг</string>\n    <string name=\"smth_went_wrong\">Нешта пайшло не так: %1$s</string>\n    <string name=\"size\">Памер %1$s</string>\n    <string name=\"loading\">Загрузка…</string>\n    <string name=\"image_too_large_preview\">Відарыс занадта вялікі для папярэдняга прагляду, але ўсё роўна будзе зроблена спроба захаваць</string>\n    <string name=\"width\">Шырыня %1$s</string>\n    <string name=\"resize_type\">Тып маштабавання</string>\n    <string name=\"quality\">Якасць</string>\n    <string name=\"extension\">Пашырэнне</string>\n    <string name=\"flexible\">Гнуткі</string>\n    <string name=\"pick_image_alt\">Выберыце малюнак</string>\n    <string name=\"app_closing_sub\">Вы ўпэўнены, што хочаце закрыць праграму?</string>\n    <string name=\"stay\">Заставайся</string>\n    <string name=\"close\">Закрыць</string>\n    <string name=\"reset_image\">Скінуць выяву</string>\n    <string name=\"values_reset\">Значэнне скінута правільна</string>\n    <string name=\"something_went_wrong\">Нешта пайшло не так</string>\n    <string name=\"restart_app\">Перазапусціць праграму</string>\n    <string name=\"edit_exif\">Рэдагаваць EXIF</string>\n    <string name=\"image_not_saved_sub\">Усе незахаваныя змены будуць страчаны, калі вы выйдзеце зараз</string>\n    <string name=\"save\">Захаваць</string>\n    <string name=\"image_exif_warning\">Ў цяперашні час фармат %1$s на Android дазваляе толькі чытаць exif, але не змяняць/захоўваць іх, гэта азначае, што выходная выява наогул не будзе мець метададзеных.</string>\n    <string name=\"clear\">Ачысціць</string>\n    <string name=\"clear_exif\">Ачысціць EXIF</string>\n    <string name=\"image_not_saved\">Захаванне</string>\n    <string name=\"pick_color\">Выберыце колер</string>\n    <string name=\"pick_color_sub\">Выберыце колер з малюнка, скапіруйце або падзяліцеся ім</string>\n    <string name=\"image\">Малюнак</string>\n    <string name=\"presets\">Прадустаноўкі</string>\n    <string name=\"check_source_code_sub\">Атрымлівайце апошнія абнаўленні, абмяркоўвайце праблемы і многае іншае</string>\n    <string name=\"clear_exif_sub\">Усе даныя EXIF выявы будуць выдалены. Гэта дзеянне нельга адмяніць!</string>\n    <string name=\"single_edit\">Адна праўка</string>\n    <string name=\"color_copied\">Колер скапіяваны</string>\n    <string name=\"check_source_code\">Зыходны код</string>\n    <string name=\"single_edit_sub\">Змяніць характарыстыкі аднаго дадзенага відарыса</string>\n    <string name=\"cancel\">Адмена</string>\n    <string name=\"crop\">Выразаць</string>\n    <string name=\"color\">Колер</string>\n    <string name=\"palette\">Палітра</string>\n    <string name=\"images\">Выявы: %d</string>\n    <string name=\"no_palette\">Немагчыма стварыць палітру для дадзенай выявы</string>\n    <string name=\"original\">Арыгінал</string>\n    <string name=\"remove\">Выключыць</string>\n    <string name=\"secondary_customization\">Другасная персаналізацыя</string>\n    <string name=\"font_scale\">Памер тэксту</string>\n    <string name=\"update\">Абнаўленне</string>\n    <string name=\"keep_exif\">Захаваць EXIF</string>\n    <string name=\"folder\">Тэчка вываду</string>\n    <string name=\"light\">Светлы</string>\n    <string name=\"version\">Версія</string>\n    <string name=\"customization\">Персаналізацыя</string>\n    <string name=\"palette_sub\">Стварыце ўзор каляровай палітры з дадзенага малюнка</string>\n    <string name=\"dark\">Цёмны</string>\n    <string name=\"crop_sub\">Абрэзаць выяву ў любых межах</string>\n    <string name=\"def\">Па змаўчанні</string>\n    <string name=\"generate_palette\">Стварыць палітру</string>\n    <string name=\"amoled_mode_sub\">Калі ўключана, то колер паверхняў будзе ўсталяваны на абсалютна цёмны ў начным рэжыме.</string>\n    <string name=\"font\">Шрыфт</string>\n    <string name=\"using_large_fonts_warn\">Выкарыстанне вялікага памеру шрыфтоў можа выклікаць збоі ў карыстальніцкім інтэрфейсе і праблемы, якія не будуць выпраўлены. Выкарыстоўвайце асцярожна.</string>\n    <string name=\"system\">Як у сістэме</string>\n    <string name=\"new_version\">Новая версія %1$s</string>\n    <string name=\"change_preview\">Змяніць папярэдні прагляд</string>\n    <string name=\"emoji_sub\">Выберыце, які эмодзі адлюстроўваць на галоўным экране</string>\n    <string name=\"color_balance\">Каляровы баланс</string>\n    <string name=\"background_color\">Колер фону</string>\n    <string name=\"enable_emoji\">Ўключыць эмодзі</string>\n    <string name=\"vibration_strength\">Сіла вібрацыі</string>\n    <string name=\"color_to_replace\">Колер для замены</string>\n    <string name=\"remove_color\">Выдаліць колер</string>\n    <string name=\"highlights_shadows\">Блікі і цені</string>\n    <string name=\"highlights\">Блікі</string>\n    <string name=\"group_options_by_type_sub\">Групуе параметры на галоўным экране па іх тыпу замест карыстальніцкага спісу</string>\n    <string name=\"tonal_spot_sub\">Стыль палітры па змаўчанні, ён дазваляе наладзіць усе чатыры колеры, іншыя дазваляюць усталяваць толькі асноўны колер</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Немагчыма змяніць каляровую схему праграмы, калі ўключаны дынамічныя колеры</string>\n    <string name=\"dynamic_colors_sub\">Калі гэта ўключана, то колеры праграмы будуць прымяняцца да колераў шпалер</string>\n    <string name=\"allow_image_monet_sub\">Калі ўключаны, то колеры праграмы будуць падладжвацца пад выбраны малюнак у рэжыме рэдагавання</string>\n    <string name=\"monet_colors\">Колеры Monet</string>\n    <string name=\"night_mode\">Начны рэжым</string>\n    <string name=\"dynamic_colors\">Дынамічныя колеры</string>\n    <string name=\"color_green\">Зялёны</string>\n    <string name=\"color_blue\">Сіні</string>\n    <string name=\"color_scheme\">Каляровая схема</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Ўстаўце правільны aRGB-код.</string>\n    <string name=\"color_red\">Чырвоны</string>\n    <string name=\"emoji\">Эмодзі</string>\n    <string name=\"filename\">Імя файла</string>\n    <string name=\"emojis_count\">Колькасць эмодзі</string>\n    <string name=\"cga_colorspace\">Колеравая прастора GCA</string>\n    <string name=\"color_matrix\">Каляровая матрыца</string>\n    <string name=\"false_color\">Фальшывы колер</string>\n    <string name=\"saved_to_without_filename\">Захавана ў тэчку %1$s</string>\n    <string name=\"delete_color_scheme_warn\">Вы збіраецеся выдаліць выбраную каляровую схему. Гэтую аперацыю нельга адмяніць</string>\n    <string name=\"delete_color_scheme_title\">Выдаліць схему</string>\n    <string name=\"text\">Тэкст</string>\n    <string name=\"picture_has_no_text\">На малюнку няма тэксту або праграма не знайшла яго</string>\n    <string name=\"vibration\">Вібрацыя</string>\n    <string name=\"activate_files\">Вы адключылі праграму \\\"Файлы\\\", актывуйце яе, каб выкарыстоўваць гэту функцыю</string>\n    <string name=\"clipboard\">Буфер абмену</string>\n    <string name=\"auto_pin_sub\">Аўтаматычна дадае захаваны малюнак у буфер абмену, калі ўключана</string>\n    <string name=\"add_original_filename\">Дадайце зыходнае імя файла</string>\n    <string name=\"only_clip\">Толькі націск</string>\n    <string name=\"only_clip_sub\">Захаванне ў сховішча не будзе выканана, а малюнак будзе спрабаваць змясціць толькі ў буфер абмену</string>\n    <string name=\"pick_accent_color\">Тэма праграмы будзе заснавана на абраным колеры</string>\n    <string name=\"randomize_filename_sub\">Калі ўключана, імя вываднага файла будзе цалкам выпадковым</string>\n    <string name=\"amoled_mode\">Рэжым Amoled</string>\n    <string name=\"clipboard_paste_invalid_empty\">Няма чаго ўставіць</string>\n    <string name=\"original_filename\">зыходнае імя файла</string>\n    <string name=\"light_aka_illumination\">Светлы</string>\n    <string name=\"color_filter\">Каляровы фільтр</string>\n    <string name=\"first_color\">Першы колер</string>\n    <string name=\"second_color\">Другі колер</string>\n    <string name=\"paint_color\">Колер фарбы</string>\n    <string name=\"randomize_filename\">Рандамізацыя імя файла</string>\n    <string name=\"max_colors_count\">Максімальная колькасць колераў</string>\n    <string name=\"recognize_text\">OCR (распазнаванне тэксту)</string>\n    <string name=\"recognize_text_sub\">Распазнаваць тэкст з дадзенай выявы, падтрымліваецца больш за 120 моў</string>\n    <string name=\"replace_color\">Замяніць колер</string>\n    <string name=\"color_to_remove\">Колер для выдалення</string>\n    <string name=\"disabled\">Адкл.</string>\n    <string name=\"stroke_pixelation\">Пікселяцыя абводкі</string>\n    <string name=\"diamond_pixelation\">Алмазная пікселізацыя</string>\n    <string name=\"allow_image_monet\">Ўключыць Monet</string>\n    <string name=\"language\">Мова</string>\n    <string name=\"help_translate_sub\">Выправіць памылкі перакладу або перакласці праект на іншыя мовы</string>\n    <string name=\"weak_pixel_inclusion\">Слабае ўключэнне пікселяў</string>\n    <string name=\"use_pixel_switch\">Выкарыстоўваць перамыкач Pixel</string>\n    <string name=\"use_pixel_switch_sub\">Будзе выкарыстоўвацца перамыкач, як на тэлефонах Pixel, замест стандартнага з Material You</string>\n    <string name=\"allow_multiple_languages\">Дазволіць некалькі моў</string>\n    <string name=\"enhanced_diamond_pixelation\">Палепшаная алмазная пікселізацыя</string>\n    <string name=\"available_languages\">Даступныя мовы</string>\n    <string name=\"downloaded_languages\">Спампаваныя мовы</string>\n    <string name=\"border_thickness\">Таўшчыня рамкі</string>\n    <string name=\"pixelation\">Пікселізацыя</string>\n    <string name=\"enhanced_pixelation\">Палепшаная пікселізацыя</string>\n    <string name=\"app_bars_shadow_sub\">Ўключыць адмалёўку ценяў пад панэллю дзеянняў</string>\n    <string name=\"app_bars_shadow\">Панэлі дзеянняў</string>\n    <string name=\"check_updates_sub\">Калі ўключана, дыялогавае акно абнаўлення будзе паказвацца пры запуску праграмы</string>\n    <string name=\"updates\">Абнаўленні</string>\n    <string name=\"delete_mask_warn\">Вы збіраецеся выдаліць выбраную маску фільтра. Гэтую аперацыю нельга адмяніць</string>\n    <string name=\"about_app\">Аб праграме</string>\n    <string name=\"no_updates\">Абнаўленні не знойдзены</string>\n    <string name=\"check_updates\">Праверка наяўнасці абнаўлення</string>\n    <string name=\"check_for_updates\">Праверыць абнаўлення</string>\n    <string name=\"allow_betas_sub\">Праверка абнаўленняў будзе ўключаць бэта-версіі праграмы, калі яна ўключана</string>\n    <string name=\"foss_update_checker_warning\">Гэта сродак праверкі абнаўленняў падключыцца да GitHub, каб праверыць наяўнасць новага абнаўлення</string>\n    <string name=\"enhanced_glitch\">Палепшаны глюк</string>\n    <string name=\"channel_shift_x\">Зрух канала X</string>\n    <string name=\"channel_shift_y\">Зрух канала Y</string>\n    <string name=\"corruption_size\">Памер карупцыі</string>\n    <string name=\"corruption_shift_x\">Карупцыя Shift X</string>\n    <string name=\"corruption_shift_y\">Карупцыйны зрух Y</string>\n    <string name=\"tent_blur\">Размыццё палаткі</string>\n    <string name=\"side_fade\">Бакавое выцвітанне</string>\n    <string name=\"side\">Збоку</string>\n    <string name=\"top\">Топ</string>\n    <string name=\"filters\">Фільтры</string>\n    <string name=\"draw_on_background\">Маляваць на фоне</string>\n    <string name=\"draw_on_background_sub\">Выберыце колер фону і малюйце па-над ім</string>\n    <string name=\"pick_file\">Выберыце файл</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Немагчыма змяніць размяшчэнне, пакуль уключана групаванне опцый</string>\n    <string name=\"screenshot\">Скрыншот</string>\n    <string name=\"contact_me\">Звяжыцеся са мной</string>\n    <string name=\"emotions\">Эмоцыі</string>\n    <string name=\"segmentation_mode_osd_only\">Арыентацыя &amp; Толькі выяўленне сцэнарыя</string>\n    <string name=\"segmentation_mode_auto_osd\">Аўтаматычная арыентацыя &amp; Выяўленне сцэнарыя</string>\n    <string name=\"segmentation_mode_single_column\">Адзін слупок</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Адзін блок вертыкальнага тэксту</string>\n    <string name=\"segmentation_mode_single_block\">Адзінкавы блок</string>\n    <string name=\"segmentation_mode_single_line\">Адзіны радок</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Разрэджаны тэкст Арыентацыя &amp; Выяўленне сцэнарыя</string>\n    <string name=\"segmentation_mode_raw_line\">Сырая лінія</string>\n    <string name=\"glitch\">Глюк</string>\n    <string name=\"amount\">Сума</string>\n    <string name=\"seed\">насенне</string>\n    <string name=\"delete_mask\">Выдаліць маску</string>\n    <string name=\"drago\">Драго</string>\n    <string name=\"aldridge\">Олдрыдж</string>\n    <string name=\"mobius\">Мёбіус</string>\n    <string name=\"transition\">Пераход</string>\n    <string name=\"peak\">Пікавая</string>\n    <string name=\"color_anomaly\">Каляровая анамалія</string>\n    <string name=\"no_such_directory\">Каталог \\\"%1$s\\\" не знойдзены, мы змянілі яго на стандартны, захавайце файл яшчэ раз</string>\n    <string name=\"auto_pin\">Аўтаматычны штыфт</string>\n    <string name=\"overwrite_files\">Перазапісаць файлы</string>\n    <string name=\"empty\">Пусты</string>\n    <string name=\"suffix\">Суфікс</string>\n    <string name=\"search_option\">Пошук</string>\n    <string name=\"free\">Бясплатна</string>\n    <string name=\"replace_sequence_number\">Замяніць парадкавы нумар</string>\n    <string name=\"donation_sub\">Гэта дадатак цалкам бясплатнае, але калі вы хочаце падтрымаць развіццё праекта, вы можаце націснуць тут</string>\n    <string name=\"gallery_picker_sub\">Просты выбар галерэі малюнкаў. Гэта будзе працаваць, толькі калі ў вас ёсць праграма, якая забяспечвае выбар мультымедыя</string>\n    <string name=\"file_explorer_picker_sub\">Выкарыстоўвайце намер GetContent для выбару выявы. Працуе ўсюды, але, як вядома, узнікаюць праблемы з атрыманнем выбраных відарысаў на некаторых прыладах. Гэта не мая віна.</string>\n    <string name=\"replace_sequence_number_sub\">Калі ўключана, стандартная пазнака часу замяняецца на парадкавы нумар выявы, калі вы выкарыстоўваеце пакетную апрацоўку</string>\n    <string name=\"filename_not_work_with_photopicker\">Даданне зыходнай назвы файла не працуе, калі выбрана крыніца выявы ў сродку выбару фота</string>\n    <string name=\"load_image_from_net\">Загрузіць малюнак з сеткі</string>\n    <string name=\"fill\">Запоўніць</string>\n    <string name=\"fit\">Прыстасаваны</string>\n    <string name=\"flexible_description\">Змяняе памер малюнкаў у відарысы з доўгім бокам, зададзеным параметрам Шырыня або Вышыня, усе разлікі памеру будуць зроблены пасля захавання - захоўвае суадносіны бакоў</string>\n    <string name=\"filter\">Фільтраваць</string>\n    <string name=\"filter_sub\">Прымяніце любую ланцужок фільтраў да зададзеных малюнкаў</string>\n    <string name=\"alpha\">Альфа</string>\n    <string name=\"exposure\">Экспазіцыя</string>\n    <string name=\"white_balance\">Баланс белага</string>\n    <string name=\"temperature\">тэмпература</string>\n    <string name=\"tint\">Таніроўка</string>\n    <string name=\"shadows\">Цені</string>\n    <string name=\"distance\">Дыстанцыя</string>\n    <string name=\"slope\">Схіл</string>\n    <string name=\"sharpen\">Вастрыць</string>\n    <string name=\"sepia\">Сэпія</string>\n    <string name=\"negative\">Адмоўны</string>\n    <string name=\"black_and_white\">Чорна-белы</string>\n    <string name=\"crosshatch\">Штрыхоўка</string>\n    <string name=\"spacing\">Інтэрвал</string>\n    <string name=\"line_width\">Шырыня лініі</string>\n    <string name=\"bilaterial_blur\">Двухбаковае размыццё</string>\n    <string name=\"emboss\">Выбіваць</string>\n    <string name=\"laplacian\">Лапласаўская</string>\n    <string name=\"start\">Пачаць</string>\n    <string name=\"end\">Канец</string>\n    <string name=\"kuwahara\">Згладжванне Кувахара</string>\n    <string name=\"stack_blur\">Размыццё стэка</string>\n    <string name=\"radius\">Радыус</string>\n    <string name=\"scale\">Маштаб</string>\n    <string name=\"distortion\">Скажэнне</string>\n    <string name=\"angle\">Вугал</string>\n    <string name=\"swirl\">Віхор</string>\n    <string name=\"bulge\">Выпукласць</string>\n    <string name=\"dilation\">Пашырэнне</string>\n    <string name=\"sphere_refraction\">Праламленне сферы</string>\n    <string name=\"refractive_index\">Паказчык праламлення</string>\n    <string name=\"glass_sphere_refraction\">Праламленне шкляной сферы</string>\n    <string name=\"limits_resize\">Абмяжоўвае змяненне памеру</string>\n    <string name=\"sketch\">Эскіз</string>\n    <string name=\"quantizationLevels\">Узроўні квантавання</string>\n    <string name=\"non_maximum_suppression\">Не максімальнае падаўленне</string>\n    <string name=\"reorder\">Змяніць парадак</string>\n    <string name=\"fast_blur\">Хуткае размыццё</string>\n    <string name=\"blur_size\">Памер размыцця</string>\n    <string name=\"blur_center_x\">Размыццё цэнтра x</string>\n    <string name=\"blur_center_y\">Цэнтр размыцця y</string>\n    <string name=\"zoom_blur\">Размыццё зуму</string>\n    <string name=\"luminance_threshold\">Парог яркасці</string>\n    <string name=\"cipher\">Шыфр</string>\n    <string name=\"cipher_sub\">Шыфраваць і дэшыфраваць любы файл (а не толькі малюнак) на аснове крыпта-алгарытму AES</string>\n    <string name=\"encrypt\">Зашыфраваць</string>\n    <string name=\"decrypt\">Расшыфраваць</string>\n    <string name=\"store_file_desc\">Захавайце гэты файл на сваёй прыладзе або выкарыстоўвайце дзеянне абагульвання, каб змясціць яго куды заўгодна</string>\n    <string name=\"features_sub\">Шыфраванне файлаў на аснове пароля. Атрыманыя файлы можна захоўваць у абраным каталогу або абагульваць. Расшыфраваныя файлы таксама можна адкрыць непасрэдна.</string>\n    <string name=\"implementation_sub\">AES-256, рэжым GCM, без запаўнення, 12 байтаў у выпадковым парадку IV. Ключы выкарыстоўваюцца як хэшы SHA-3 (256 біт).</string>\n    <string name=\"saved_to\">Захавана ў папку %1$s з назвай %2$s</string>\n    <string name=\"image_crop_mask_sub\">Выкарыстоўвайце гэты тып маскі для стварэння маскі з дадзенай выявы, заўважце, што яна ПАВІННА мець альфа-канал</string>\n    <string name=\"settings_restored\">Налады паспяхова адноўлены</string>\n    <string name=\"reset_settings_sub\">Гэта верне вашы налады да значэнняў па змаўчанні. Звярніце ўвагу, што гэта нельга адмяніць без файла рэзервовай копіі, згаданага вышэй.</string>\n    <string name=\"defaultt\">Па змаўчанні</string>\n    <string name=\"alphabet_and_numbers\">Аа Бб Вв Гг Дд Ее Ёё Жж Зз Іі Йй Кк Лл Мм Нн Оо Пп Рр Сс Тт Уу Ўў Фф Хх Цц Чч Шш Ыы Ьь Ээ Юю Яя 0123456789 !?</string>\n    <string name=\"nature_and_animals\">Прырода і жывёлы</string>\n    <string name=\"objects\">Аб\\'екты</string>\n    <string name=\"symbols\">Сімвалы</string>\n    <string name=\"crashlytics_sub\">Гэта дазваляе праграме збіраць справаздачы аб збоях уручную</string>\n    <string name=\"analytics_sub\">Дазволіць збор ананімнай статыстыкі выкарыстання праграмы</string>\n    <string name=\"analytics\">Аналітыка</string>\n    <string name=\"saving_almost_complete\">Захаванне амаль завершана. Пры адмене зараз спатрэбіцца захаванне зноў.</string>\n    <string name=\"draw_arrows\">Намалюйце стрэлкі</string>\n    <string name=\"scale_small_images_to_large_sub\">Маленькія выявы будуць маштабавацца да самых вялікіх у паслядоўнасці, калі гэта ўключана</string>\n    <string name=\"enhanced_circle_pixelation\">Палепшаная пікселізацыя кругоў</string>\n    <string name=\"palette_style\">Стыль палітры</string>\n    <string name=\"tonal_spot\">Танальная пляма</string>\n    <string name=\"neutral\">Нейтральны</string>\n    <string name=\"vibrant\">Жывы</string>\n    <string name=\"expressive\">Экспрэсіўны</string>\n    <string name=\"rainbow\">Вясёлка</string>\n    <string name=\"fruit_salad\">Фруктовы салата</string>\n    <string name=\"fidelity\">Вернасць</string>\n    <string name=\"content\">Змест</string>\n    <string name=\"playful_scheme\">Гуллівая тэма - адценне зыходнага колеру не адлюстроўваецца ў тэме</string>\n    <string name=\"monochrome_sub\">Манахромная тэма, колеры чыста чорны / белы / шэры</string>\n    <string name=\"content_sub\">Схема, якая змяшчае зыходны колер у Scheme.primaryContainer</string>\n    <string name=\"search_option_sub\">Дае магчымасць пошуку па ўсіх даступных опцыях на галоўным экране</string>\n    <string name=\"pdf_to_images_sub\">Пераўтварыце PDF у выявы ў зададзеным фармаце вываду</string>\n    <string name=\"images_to_pdf_sub\">Упакуйце дадзеныя выявы ў выходны файл PDF</string>\n    <string name=\"mask_filter\">Фільтр маскі</string>\n    <string name=\"mask_filter_sub\">Прымяніць ланцужкі фільтраў да зададзеных замаскіраваных абласцей, кожная вобласць маскі можа вызначыць свой уласны набор фільтраў</string>\n    <string name=\"masks\">Маскі</string>\n    <string name=\"add_mask\">Дадаць маску</string>\n    <string name=\"mask_indexed\">Маска %d</string>\n    <string name=\"mask_preview\">Папярэдні прагляд маскі</string>\n    <string name=\"mask_preview_sub\">Нарысаваная маска фільтра будзе візуалізавана, каб паказаць вам прыблізны вынік</string>\n    <string name=\"full_filter\">Поўны фільтр</string>\n    <string name=\"start_position\">Пачаць</string>\n    <string name=\"center_position\">Цэнтр</string>\n    <string name=\"end_position\">Канец</string>\n    <string name=\"simple_variants\">Простыя варыянты</string>\n    <string name=\"highlighter\">Хайлайтер</string>\n    <string name=\"neon\">Неон</string>\n    <string name=\"pen\">Пяро</string>\n    <string name=\"privacy_blur\">Размыццё прыватнасці</string>\n    <string name=\"neon_sub\">Дадайце эфект ззяння сваім малюнкам</string>\n    <string name=\"pen_sub\">Па змаўчанні адзін, самы просты - толькі колер</string>\n    <string name=\"pixelation_sub\">Падобна да размыцця прыватнасці, але пікселізуе замест размыцця</string>\n    <string name=\"auto_rotate_limits\">Аўтаматычны паварот</string>\n    <string name=\"auto_rotate_limits_sub\">Дазваляе выкарыстоўваць абмежавальнае поле для арыентацыі выявы</string>\n    <string name=\"free_drawing_sub\">Малюе шлях у якасці ўваходнага значэння</string>\n    <string name=\"line_sub\">Малюе шлях ад пачатковай да канчатковай кропкі ў выглядзе лініі</string>\n    <string name=\"line_arrow_sub\">Малюе стрэлку ад пачатковай да канчатковай кропкі ў выглядзе лініі</string>\n    <string name=\"arrow_sub\">Малюе паказальную стрэлку ад зададзенага шляху</string>\n    <string name=\"double_line_arrow_sub\">Малюе двайную стрэлку ад пачатковай да канчатковай кропкі ў выглядзе лініі</string>\n    <string name=\"double_arrow_sub\">Малюе двайную стрэлку ад зададзенага шляху</string>\n    <string name=\"outlined_oval\">Абведзены авал</string>\n    <string name=\"outlined_rect\">Акрэслены праст</string>\n    <string name=\"oval\">Авал</string>\n    <string name=\"rect\">Рэкт</string>\n    <string name=\"rect_sub\">Малюе прамавухі ад пачатковай да канчатковай кропкі</string>\n    <string name=\"oval_sub\">Малюе авал ад пачатковай да канчатковай кропкі</string>\n    <string name=\"outlined_oval_sub\">Малюе контурны авал ад пачатковай да канчатковай кропкі</string>\n    <string name=\"outlined_rect_sub\">Малюе акрэслены прастакут ад пачатковай да канчатковай кропкі</string>\n    <string name=\"overwrite_file_requirements\">Каб перазапісаць файлы, трэба выкарыстоўваць крыніцу відарысаў \\\"Правадыр\\\", паспрабуйце пераабраць відарысы, мы змянілі крыніцу відарысаў на патрэбны</string>\n    <string name=\"overwrite_files_sub\">Арыгінальны файл будзе заменены на новы замест захавання ў абранай тэчцы, крыніцай выявы для гэтага параметра павінна быць \\\"Правадыр\\\" або GetContent, пры пераключэнні гэтага параметра ён будзе ўсталяваны аўтаматычна</string>\n    <string name=\"nearest_sub\">Адзін з самых простых спосабаў павелічэння памеру, замена кожнага пікселя на колькасць пікселяў таго ж колеру</string>\n    <string name=\"catmull_sub\">Метад плыўнай інтэрпаляцыі і паўторнай выбаркі набору кантрольных кропак, звычайна выкарыстоўваецца ў камп\\'ютэрнай графіцы для стварэння гладкіх крывых</string>\n    <string name=\"basic_sub\">Самы просты рэжым маштабавання Android, які выкарыстоўваецца амаль ва ўсіх праграмах</string>\n    <string name=\"lanczos_sub\">Метад паўторнай выбаркі, які падтрымлівае высакаякасную інтэрпаляцыю шляхам прымянення ўзважанай функцыі sinc да значэнняў пікселяў</string>\n    <string name=\"hann_sub\">Функцыя вокнаў часта прымяняецца пры апрацоўцы сігналаў для мінімізацыі спектральнай уцечкі і павышэння дакладнасці частотнага аналізу шляхам звужэння краёў сігналу</string>\n    <string name=\"hermite_sub\">Тэхніка матэматычнай інтэрпаляцыі, якая выкарыстоўвае значэнні і вытворныя ў канчатковых кропках сегмента крывой для стварэння гладкай і бесперапыннай крывой</string>\n    <string name=\"download_description\">Для належнага функцыянавання Tesseract OCR дадатковыя навучальныя даныя (%1$s) неабходна загрузіць на вашу прыладу. \\nВы хочаце спампаваць даныя %2$s?</string>\n    <string name=\"mitchell_sub\">Метад паўторнай выбаркі, які выкарыстоўвае канвертацыйны фільтр з наладжвальнымі параметрамі для дасягнення балансу паміж рэзкасцю і згладжваннем у маштабаванай выяве</string>\n    <string name=\"spline_sub\">Выкарыстоўвае шматчленныя функцыі для плыўнай інтэрпаляцыі і апраксімацыі крывой або паверхні, гнуткае і бесперапыннае прадстаўленне формы</string>\n    <string name=\"no_data\">Даных няма</string>\n    <string name=\"download\">Спампаваць</string>\n    <string name=\"no_connection\">Няма падключэння, праверце і паўтарыце спробу, каб спампаваць мадэлі цягнікоў</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Прымушае першапачатковую праверку віджэта exif</string>\n    <string name=\"segmentation_mode_auto_only\">Толькі аўто</string>\n    <string name=\"segmentation_mode_auto\">Аўто</string>\n    <string name=\"segmentation_mode_single_word\">Адно слова</string>\n    <string name=\"segmentation_mode_circle_word\">Абвядзіце слова</string>\n    <string name=\"segmentation_mode_single_char\">Адзін сімвал</string>\n    <string name=\"segmentation_mode_sparse_text\">Разрэджаны тэкст</string>\n    <string name=\"delete_language_sub\">Вы хочаце выдаліць даныя навучання OCR для мовы \\\"%1$s\\\" для ўсіх тыпаў распазнання ці толькі для выбранага (%2$s)?</string>\n    <string name=\"add_color\">Дадаць колер</string>\n    <string name=\"properties\">Уласцівасці</string>\n    <string name=\"watermarking\">Вадзяныя знакі</string>\n    <string name=\"watermarking_sub\">Малюнкі вокладкі з наладжвальнымі тэкставымі/малюнкавымі вадзянымі знакамі</string>\n    <string name=\"repeat_watermark\">Паўтарыць вадзяны знак</string>\n    <string name=\"repeat_watermark_sub\">Паўтараецца вадзяны знак на малюнку замест аднаго ў дадзеным месцы</string>\n    <string name=\"offset_x\">Зрушэнне X</string>\n    <string name=\"offset_y\">Зрушэнне Y</string>\n    <string name=\"watermark_type\">Тып вадзянога знака</string>\n    <string name=\"quantizier\">Квантызатар</string>\n    <string name=\"gray_scale\">Шэрая шкала</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Флойд Штайнберг Дызерынг</string>\n    <string name=\"false_floyd_steinberg_dithering\">False Floyd Steinberg Dithering</string>\n    <string name=\"b_spline_sub\">Выкарыстоўвае кавалачна вызначаныя бікубічныя паліномныя функцыі для плыўнай інтэрпаляцыі і апраксімацыі крывой або паверхні, гнуткае і бесперапыннае прадстаўленне формы</string>\n    <string name=\"tilt_shift\">Зрух нахілу</string>\n    <string name=\"bottom\">Знізу</string>\n    <string name=\"strength\">Сіла</string>\n    <string name=\"fractal_glass\">Фрактальнае шкло</string>\n    <string name=\"just_size\">Памер</string>\n    <string name=\"amplitude_x\">Амплітуда X</string>\n    <string name=\"speed\">хуткасць</string>\n    <string name=\"simple_effects\">Простыя эфекты</string>\n    <string name=\"tritonomaly\">Трытаномалія</string>\n    <string name=\"deutaromaly\">Дэўтарамалія</string>\n    <string name=\"protonomaly\">Пратанамалія</string>\n    <string name=\"vintage\">Вінтаж</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Начное бачанне</string>\n    <string name=\"warm\">Цёплы</string>\n    <string name=\"cool\">Крута</string>\n    <string name=\"tritanopia\">Трытанопія</string>\n    <string name=\"achromatomaly\">Ахраматамалія</string>\n    <string name=\"achromatopsia\">Ахроматопсия</string>\n    <string name=\"unsharp\">Нярэзкі</string>\n    <string name=\"pastel\">Пастэльныя</string>\n    <string name=\"orange_haze\">Аранжавая дымка</string>\n    <string name=\"pink_dream\">Ружовая мара</string>\n    <string name=\"golden_hour\">Залатая гадзіна</string>\n    <string name=\"hot_summer\">Гарачае лета</string>\n    <string name=\"purple_mist\">Фіялетавы туман</string>\n    <string name=\"sunrise\">Усход сонца</string>\n    <string name=\"colorful_swirl\">Маляўнічы вір</string>\n    <string name=\"soft_spring_light\">Мяккае вясновае святло</string>\n    <string name=\"autumn_tones\">Тоны восені</string>\n    <string name=\"lavender_dream\">Лавандавая мара</string>\n    <string name=\"cyberpunk\">Кіберпанк</string>\n    <string name=\"lemonade_light\">Лёгкі ліманад</string>\n    <string name=\"spectral_fire\">Прывідны агонь</string>\n    <string name=\"night_magic\">Начная магія</string>\n    <string name=\"fantasy_landscape\">Фантастычны пейзаж</string>\n    <string name=\"color_explosion\">Каляровы выбух</string>\n    <string name=\"electric_gradient\">Электрычны градыент</string>\n    <string name=\"space_portal\">Касмічны партал</string>\n    <string name=\"red_swirl\">Чырвоны вір</string>\n    <string name=\"digital_code\">Лічбавы код</string>\n    <string name=\"icon_shape\">Форма значка</string>\n    <string name=\"cutoff\">Адрэзаць</string>\n    <string name=\"uchimura\">Учымура</string>\n    <string name=\"images_overwritten\">Выявы перазапісаны ў першапачатковым месцы прызначэння</string>\n    <string name=\"cannot_change_image_format\">Немагчыма змяніць фармат выявы, калі ўключана опцыя перазапісу файлаў</string>\n    <string name=\"emoji_as_color_scheme\">Эмодзі як каляровая схема</string>\n    <string name=\"emoji_as_color_scheme_sub\">Выкарыстоўвае асноўны колер эмодзі ў якасці каляровай схемы праграмы замест вызначанай уручную</string>\n    <string name=\"backup_and_restore\">Рэзервовае капіраванне і аднаўленне</string>\n    <string name=\"backup_sub\">Зрабіце рэзервовую копію налад праграмы ў файл</string>\n    <string name=\"restore_sub\">Аднавіць налады праграмы з раней створанага файла</string>\n    <string name=\"keep_exif_sub\">Зыходныя метаданыя выявы будуць захаваны</string>\n    <string name=\"images_order\">Парадак малюнкаў</string>\n    <string name=\"circle_pixelation\">Круговая пікселізацыя</string>\n    <string name=\"tolerance\">Талерантнасць</string>\n    <string name=\"target_color\">Колер мэты</string>\n    <string name=\"recode\">Перакадзіраваць</string>\n    <string name=\"erode\">Размываць</string>\n    <string name=\"anisotropic_diffusion\">Анізатропная дыфузія</string>\n    <string name=\"diffusion\">Дыфузія</string>\n    <string name=\"conduction\">Правядзенне</string>\n    <string name=\"horizontal_wind_stagger\">Гарызантальны вецер</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"fast_bilaterial_blur\">Хуткае двухбаковае размыццё</string>\n    <string name=\"poisson_blur\">Размыццё Пуасона</string>\n    <string name=\"logarithmic_tone_mapping\">Лагарыфмічнае танальнае адлюстраванне</string>\n    <string name=\"crystallize\">Крышталізаваць</string>\n    <string name=\"stroke_color\">Колер абводкі</string>\n    <string name=\"amplitude\">Амплітуда</string>\n    <string name=\"marble\">Мармуровы</string>\n    <string name=\"turbulence\">Турбулентнасць</string>\n    <string name=\"oil\">Алей</string>\n    <string name=\"water_effect\">Эфект вады</string>\n    <string name=\"frequency_x\">Частата X</string>\n    <string name=\"frequency_y\">Частата Y</string>\n    <string name=\"amplitude_y\">Амплітуда Y</string>\n    <string name=\"perlin_distortion\">Скажэнне Перліна</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"current\">Ток</string>\n    <string name=\"all\">Усе</string>\n    <string name=\"full_filter_sub\">Ужывайце любыя ланцужкі фільтраў да зададзеных відарысаў або аднаго відарыса</string>\n    <string name=\"pdf_to_images\">PDF ў выявы</string>\n    <string name=\"images_to_pdf\">Выявы ў pdf</string>\n    <string name=\"preview_pdf_sub\">Просты папярэдні прагляд PDF</string>\n    <string name=\"gradient_maker\">Стваральнік градыентаў</string>\n    <string name=\"gradient_maker_sub\">Стварыце градыент зададзенага выхаднога памеру з наладжанымі колерамі і тыпам выгляду</string>\n    <string name=\"dehaze\">Абезгазаваць</string>\n    <string name=\"omega\">Амега</string>\n    <string name=\"pdf_tools\">Інструменты PDF</string>\n    <string name=\"rate_app\">Ацаніць дадатак</string>\n    <string name=\"rate\">Стаўка</string>\n    <string name=\"rate_app_sub\">Гэта дадатак цалкам бясплатнае, калі вы хочаце, каб яно стала большым, пазначце праект зоркай на Github 😄</string>\n    <string name=\"color_matrix_4x4\">Каляровая матрыца 4х4</string>\n    <string name=\"color_matrix_3x3\">Каляровая матрыца 3х3</string>\n    <string name=\"polaroid\">Паляроід</string>\n    <string name=\"browni\">Браўні</string>\n    <string name=\"deutaronotopia\">Дэўтаронатапія</string>\n    <string name=\"protanopia\">Пратанопія</string>\n    <string name=\"gradient_type_linear\">Лінейны</string>\n    <string name=\"gradient_type_radial\">Радыяльны</string>\n    <string name=\"gradient_type_sweep\">Падмятаць</string>\n    <string name=\"gradient_type\">Тып градыенту</string>\n    <string name=\"center_x\">Цэнтр X</string>\n    <string name=\"center_y\">Цэнтр Ю</string>\n    <string name=\"tile_mode\">Рэжым пліткі</string>\n    <string name=\"tile_mode_repeated\">Паўтараецца</string>\n    <string name=\"tile_mode_mirror\">Люстэрка</string>\n    <string name=\"tile_mode_clamp\">Заціск</string>\n    <string name=\"tile_mode_decal\">Дэкаль</string>\n    <string name=\"color_stops\">Каляровыя прыпынкі</string>\n    <string name=\"email\">Электронная пошта</string>\n    <string name=\"draw_path_mode\">Рэжым малявання шляху</string>\n    <string name=\"double_line_arrow\">Падвойная стрэлка</string>\n    <string name=\"free_drawing\">Бясплатнае маляванне</string>\n    <string name=\"double_arrow\">Двайная стрэлка</string>\n    <string name=\"line_arrow\">Лінія Стрэлка</string>\n    <string name=\"arrow\">Стрэлка</string>\n    <string name=\"line\">лінія</string>\n    <string name=\"dithering\">Дызерінг</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Баер тры на тры дызерінг</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Джарвіс Джудіс Нінке Дытэрынг</string>\n    <string name=\"sierra_dithering\">Сьера-Дытэрынг</string>\n    <string name=\"two_row_sierra_dithering\">Two Row Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Аткінсан Дзітэрынг</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Беркс Дытэрынг</string>\n    <string name=\"left_to_right_dithering\">Размыванне злева направа</string>\n    <string name=\"random_dithering\">Выпадковае змяненне</string>\n    <string name=\"simple_threshold_dithering\">Простае парогавае ваганне</string>\n    <string name=\"unsupported_type\">Тып не падтрымліваецца: %1$s</string>\n    <string name=\"custom\">Прыстасаваныя</string>\n    <string name=\"unspecified\">Невызначаны</string>\n    <string name=\"device_storage\">Захоўванне прылады</string>\n    <string name=\"compare\">Параўнайце</string>\n    <string name=\"by_bytes_resize\">Змяніць памер па вазе</string>\n    <string name=\"max_bytes\">Максімальны памер у КБ</string>\n    <string name=\"by_bytes_resize_sub\">Змяніць памер выявы ў адпаведнасці з зададзеным памерам у КБ</string>\n    <string name=\"compare_sub\">Параўнайце два дадзеныя малюнкі</string>\n    <string name=\"pick_two_images\">Выберыце два відарысы для пачатку</string>\n    <string name=\"pick_images\">Падбярыце малюнкі</string>\n    <string name=\"settings\">Налады</string>\n    <string name=\"issue_tracker\">Адсочванне праблем</string>\n    <string name=\"issue_tracker_sub\">Дасылайце справаздачы аб памылках і запыты аб функцыях сюды</string>\n    <string name=\"help_translate\">Дапамажыце перакласці</string>\n    <string name=\"nothing_found_by_search\">Па вашым запыце нічога не знойдзена</string>\n    <string name=\"search_here\">Шукайце тут</string>\n    <string name=\"failed_to_save\">Не ўдалося захаваць %d відарыс(ы)</string>\n    <string name=\"secondary\">Другасны</string>\n    <string name=\"add\">Дадаць</string>\n    <string name=\"permission\">Дазвол</string>\n    <string name=\"grant\">Грант</string>\n    <string name=\"permission_sub\">Праграме неабходны доступ да вашага сховішча, каб захоўваць выявы для працы. Дайце дазвол у наступным дыялогавым акне.</string>\n    <string name=\"external_storage\">Знешняе сховішча</string>\n    <string name=\"fab_alignment\">Выраўноўванне FAB</string>\n    <string name=\"zoom\">Маштаб выявы</string>\n    <string name=\"share\">падзяліцца</string>\n    <string name=\"prefix\">Прэфікс</string>\n    <string name=\"add_file_size\">Дадайце памер файла</string>\n    <string name=\"add_file_size_sub\">Калі ўключана, дадае шырыню і вышыню захаванай выявы да назвы выходнага файла</string>\n    <string name=\"delete_exif\">Выдаліць EXIF</string>\n    <string name=\"delete_exif_sub\">Выдаліць метададзеныя EXIF з любога набору малюнкаў</string>\n    <string name=\"image_preview\">Папярэдні прагляд выявы</string>\n    <string name=\"image_preview_sub\">Папярэдні прагляд малюнкаў любога тыпу: GIF, SVG і гэтак далей</string>\n    <string name=\"image_source\">Крыніца выявы</string>\n    <string name=\"gallery_picker\">Галерэя</string>\n    <string name=\"file_explorer_picker\">Правадыр файлаў</string>\n    <string name=\"photo_picker_sub\">Сучасны інструмент выбару фатаграфій Android, які з\\'яўляецца ўнізе экрана, можа працаваць толькі на Android 12+. Ёсць праблемы з атрыманнем метаданых EXIF</string>\n    <string name=\"options_arrangement\">Размяшчэнне варыянтаў</string>\n    <string name=\"edit\">Рэдагаваць</string>\n    <string name=\"order\">Парадак</string>\n    <string name=\"order_sub\">Вызначае парадак параметраў на галоўным экране</string>\n    <string name=\"add_original_filename_sub\">Калі ўключана, дадае арыгінальнае імя файла ў назву выходнага відарыса</string>\n    <string name=\"content_scale\">Маштаб зместу</string>\n    <string name=\"explicit_description\">Прымушае ператвараць кожны малюнак у відарыс, зададзены параметрамі Шырыня і Вышыня - можа змяніць суадносіны бакоў</string>\n    <string name=\"brightness\">Яркасць</string>\n    <string name=\"contrast\">Кантраст</string>\n    <string name=\"hue\">Адценне</string>\n    <string name=\"saturation\">Насычанасць</string>\n    <string name=\"add_filter\">Дадаць фільтр</string>\n    <string name=\"monochrome\">Манахромны</string>\n    <string name=\"gamma\">Гама</string>\n    <string name=\"haze\">Дымка</string>\n    <string name=\"effect\">Эфект</string>\n    <string name=\"solarize\">Салярызаваць</string>\n    <string name=\"vibrance\">Жывасць</string>\n    <string name=\"sobel_edge\">Собельскі край</string>\n    <string name=\"blur\">Размыццё</string>\n    <string name=\"halftone\">Паўтоны</string>\n    <string name=\"gaussian_blur\">Гаўсава размыццё</string>\n    <string name=\"box_blur\">Размытасць скрынкі</string>\n    <string name=\"vignette\">Віньетка</string>\n    <string name=\"opacity\">Непразрыстасць</string>\n    <string name=\"threshold\">Парог</string>\n    <string name=\"smooth_toon\">Гладкі мульцік</string>\n    <string name=\"toon\">Мультфільм</string>\n    <string name=\"posterize\">Постэрызацыі</string>\n    <string name=\"lookup\">Шукаць</string>\n    <string name=\"convolution3x3\">Згортка 3х3</string>\n    <string name=\"rgb_filter\">Rgb фільтр</string>\n    <string name=\"draw\">Маляваць</string>\n    <string name=\"draw_sub\">Малюйце на малюнку, як у альбоме для малявання, або малюйце на самім фоне</string>\n    <string name=\"paint_alpha\">Фарба альфа</string>\n    <string name=\"draw_on_image\">Маляваць на малюнку</string>\n    <string name=\"draw_on_image_sub\">Выберыце малюнак і намалюйце што-небудзь на ім</string>\n    <string name=\"pick_file_to_start\">Выберыце файл для пачатку</string>\n    <string name=\"decryption\">Расшыфроўка</string>\n    <string name=\"encryption\">Шыфраванне</string>\n    <string name=\"key\">ключ</string>\n    <string name=\"file_proceed\">Файл апрацаваны</string>\n    <string name=\"features\">Асаблівасці</string>\n    <string name=\"implementation\">Рэалізацыя</string>\n    <string name=\"compatibility\">Сумяшчальнасць</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">Калі ласка, звярніце ўвагу, што сумяшчальнасць з іншымі праграмамі або службамі шыфравання файлаў не гарантуецца. Крыху іншая апрацоўка ключа або канфігурацыя шыфра могуць выклікаць несумяшчальнасць.</string>\n    <string name=\"cache\">Кэш</string>\n    <string name=\"image_size_warning\">Спроба захаваць малюнак з зададзенай шырынёй і вышынёй можа выклікаць памылку OOM. Рабіце гэта на свой страх і рызыку, і не кажыце, што я вас не папярэджваў!</string>\n    <string name=\"cache_size\">Памер кэша</string>\n    <string name=\"found_s\">Знойдзена %1$s</string>\n    <string name=\"auto_cache_clearing\">Аўтаматычная ачыстка кэша</string>\n    <string name=\"auto_cache_clearing_sub\">Калі ўключана, кэш праграмы будзе ачышчаны пры запуску праграмы</string>\n    <string name=\"create\">Ствараць</string>\n    <string name=\"tools\">інструменты</string>\n    <string name=\"edit_screenshot\">Рэдагаваць скрыншот</string>\n    <string name=\"skip\">Прапусціць</string>\n    <string name=\"copy\">Копія</string>\n    <string name=\"warning_bytes\">Захаванне ў рэжыме %1$s можа быць нестабільным, таму што гэта фармат без страт</string>\n    <string name=\"presets_sub\" formatted=\"false\">Калі вы абралі папярэднюю ўстаноўку 125, выява будзе захавана ў памеры 125% ад арыгінальнай выявы. Калі вы выбіраеце значэнне 50, то выява будзе захавана з памерам 50%</string>\n    <string name=\"presets_sub_bytes\">Прадусталяванне тут вызначае % выхаднога файла, г. зн., калі вы выбіраеце заданне 50 для выявы памерам 5 МБ, пасля захавання вы атрымаеце выяву памерам 2,5 МБ</string>\n    <string name=\"tg_chat\">Тэлеграм чат</string>\n    <string name=\"crop_mask\">Кроп-маска</string>\n    <string name=\"aspect_ratio\">Суадносіны бакоў</string>\n    <string name=\"backup\">Рэзервовае капіраванне</string>\n    <string name=\"delete\">Выдаліць</string>\n    <string name=\"food_and_drink\">Прадукты харчавання і напоі</string>\n    <string name=\"trim_image\">Абрэзаць малюнак</string>\n    <string name=\"background_remover_sub\">Выдаліце фон з выявы, намаляваўшы або скарыстаўшыся опцыяй Аўта.</string>\n    <string name=\"trim_image_sub\">Празрыстыя прасторы вакол выявы будуць абрэзаны</string>\n    <string name=\"draw_mode\">Рэжым малявання</string>\n    <string name=\"restore_background\">Аднавіць фон</string>\n    <string name=\"blur_radius\">Радыус размыцця</string>\n    <string name=\"pipette\">Піпетка</string>\n    <string name=\"mask_color\">Колер маскі</string>\n    <string name=\"scale_mode\">Рэжым маштабу</string>\n    <string name=\"bilinear\">Білінейны</string>\n    <string name=\"hann\">Ханн</string>\n    <string name=\"hermite\">Эрміт</string>\n    <string name=\"lanczos\">Ланцош</string>\n    <string name=\"mitchell\">Мітчэл</string>\n    <string name=\"nearest\">Бліжэйшы</string>\n    <string name=\"spline\">Сплайн</string>\n    <string name=\"basic\">Базавы</string>\n    <string name=\"default_value\">Значэнне па змаўчанні</string>\n    <string name=\"value_in_range\">Значэнне ў дыяпазоне %1$s - %2$s</string>\n    <string name=\"sigma\">Сігма</string>\n    <string name=\"spatial_sigma\">Прасторавая сігма</string>\n    <string name=\"median_blur\">Сярэдняе размыццё</string>\n    <string name=\"catmull\">Кэтмул</string>\n    <string name=\"bicubic\">Бікубічны</string>\n    <string name=\"bilinear_sub\">Лінейная (або білінейная, у двух вымярэннях) інтэрпаляцыя звычайна добрая для змены памеру выявы, але выклікае некаторае непажаданае змякчэнне дэталяў і ўсё яшчэ можа быць некалькі няроўнай</string>\n    <string name=\"bicubic_sub\">Лепшыя метады маштабавання ўключаюць паўторную выбарку Ланцоша і фільтры Мітчэла-Нетравалі</string>\n    <string name=\"icon_shape_sub\">Дадае кантэйнер з выбранай формай пад галоўнымі значкамі карт</string>\n    <string name=\"image_stitching\">Сшыванне малюнкаў</string>\n    <string name=\"image_stitching_sub\">Аб\\'яднайце дадзеныя малюнкі, каб атрымаць адзін вялікі</string>\n    <string name=\"brightness_enforcement\">Максімальная яркасць</string>\n    <string name=\"screen\">Экран</string>\n    <string name=\"gradient_maker_type_image\">Градыентнае накладанне</string>\n    <string name=\"gradient_maker_type_image_sub\">Складзіце любы градыент верхняй часткі дадзенага малюнка</string>\n    <string name=\"transformations\">Пераўтварэнні</string>\n    <string name=\"camera\">Камера</string>\n    <string name=\"camera_sub\">Выкарыстоўвае камеру для здымкі, звярніце ўвагу, што можна атрымаць толькі адну выяву з гэтай крыніцы выявы</string>\n    <string name=\"pick_at_least_two_images\">Выберыце як мінімум 2 выявы</string>\n    <string name=\"grain\">Збожжа</string>\n    <string name=\"caramel_darkness\">Карамельная цемра</string>\n    <string name=\"futuristic_gradient\">Футурыстычны градыент</string>\n    <string name=\"green_sun\">Зялёнае сонца</string>\n    <string name=\"rainbow_world\">Вясёлкавы свет</string>\n    <string name=\"deep_purple\">Deep Purple</string>\n    <string name=\"watermarking_image_sub\">Гэта выява будзе выкарыстоўвацца ў якасці шаблону для вадзяных знакаў</string>\n    <string name=\"text_color\">Колер тэксту</string>\n    <string name=\"overlay_mode\">Рэжым накладання</string>\n    <string name=\"lock_draw_orientation\">Заблакіраваць арыентацыю малюнка</string>\n    <string name=\"pixel_size\">Памер пікселя</string>\n    <string name=\"lock_draw_orientation_sub\">Калі ўключана ў рэжыме малявання, экран не будзе паварочвацца</string>\n    <string name=\"limits_resize_sub\">Змяняйце памер выбраных відарысаў у адпаведнасці з зададзенымі абмежаваннямі па шырыні і вышыні, захоўваючы суадносіны бакоў</string>\n    <string name=\"bokeh\">Боке</string>\n    <string name=\"gif_tools\">Інструменты GIF</string>\n    <string name=\"gif_tools_sub\">Пераўтварыце выявы ў малюнак GIF або вылучыце рамкі з дадзенага малюнка GIF</string>\n    <string name=\"gif_type_to_image\">GIF да малюнкаў</string>\n    <string name=\"gif_type_to_image_sub\">Пераўтварыце GIF-файл у пакет малюнкаў</string>\n    <string name=\"gif_type_to_gif_sub\">Пераўтварэнне пакета малюнкаў у файл GIF</string>\n    <string name=\"gif_type_to_gif\">Выявы ў GIF</string>\n    <string name=\"select_gif_image_to_start\">Каб пачаць, абярыце GIF-малюнак</string>\n    <string name=\"use_size_of_first_frame\">Выкарыстоўвайце памер першага кадра</string>\n    <string name=\"use_size_of_first_frame_sub\">Заменіце ўказаны памер першымі памерамі кадра</string>\n    <string name=\"repeat_count\">Паўтарыце падлік</string>\n    <string name=\"frame_delay\">Затрымка кадра</string>\n    <string name=\"millis\">міліс</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Выкарыстоўвайце ласо</string>\n    <string name=\"use_lasso_sub\">Для выканання сцірання выкарыстоўваецца ласо, як у рэжыме малявання</string>\n    <string name=\"original_image_preview_alpha\">Арыгінальны папярэдні прагляд выявы Альфа</string>\n    <string name=\"random_emojis_sub\">Эмодзі на панэлі прыкладанняў будуць пастаянна змяняцца выпадковым чынам замест выкарыстання выбранага</string>\n    <string name=\"random_emojis\">Выпадковыя эмодзі</string>\n    <string name=\"random_emojis_error\">Немагчыма выкарыстоўваць выпадковы выбар эмодзі, калі эмодзі адключаны</string>\n    <string name=\"emoji_selection_error\">Немагчыма выбраць эмодзі, калі ўключаны выпадковы выбар</string>\n    <string name=\"effort\">Высілак</string>\n    <string name=\"effort_sub\">Значэнне %1$s азначае хуткае сцісканне, што прыводзіць да адносна вялікага памеру файла. %2$s азначае больш павольнае сцісканне, што прыводзіць да меншага файла.</string>\n    <string name=\"wait\">Пачакай</string>\n    <string name=\"primary\">Першасны</string>\n    <string name=\"tertiary\">троесны</string>\n    <string name=\"surface\">Паверхня</string>\n    <string name=\"values\">Каштоўнасці</string>\n    <string name=\"grant_permission_manual\">Прыкладанню патрэбны гэты дазвол для працы, дайце яго ўручную</string>\n    <string name=\"photo_picker\">Выбар фота</string>\n    <string name=\"sequence_num\">паслядоўнасцьNum</string>\n    <string name=\"load_image_from_net_sub\">Загрузіце любую выяву з Інтэрнэту для папярэдняга прагляду, маштабавання, рэдагавання і захавання, калі хочаце.</string>\n    <string name=\"no_image\">Няма выявы</string>\n    <string name=\"image_link\">Спасылка на малюнак</string>\n    <string name=\"file_size\">Памер файла</string>\n    <string name=\"invalid_password_or_not_encrypted\">Няправільны пароль або выбраны файл не зашыфраваны</string>\n    <string name=\"group_options_by_type\">Згрупуйце параметры па тыпу</string>\n    <string name=\"fallback_option\">Запасны варыянт</string>\n    <string name=\"tg_chat_sub\">Абмяркуйце прыкладанне і атрымайце водгукі ад іншых карыстальнікаў. Вы таксама можаце атрымліваць абнаўленні бэта-версіі і інфармацыю тут.</string>\n    <string name=\"restore\">Аднавіць</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Пашкоджаны файл ці не рэзервовая копія</string>\n    <string name=\"travels_and_places\">Падарожжы і мясціны</string>\n    <string name=\"activities\">Мерапрыемствы</string>\n    <string name=\"background_remover\">Праграма для выдалення фону</string>\n    <string name=\"auto_erase_background\">Аўтаматычнае выдаленне фону</string>\n    <string name=\"restore_image\">Аднавіць малюнак</string>\n    <string name=\"erase_mode\">Рэжым сцірання</string>\n    <string name=\"allow_betas\">Дазволіць бэта-версіі</string>\n    <string name=\"erase_background\">Сцерці фон</string>\n    <string name=\"create_issue\">Стварыць выпуск</string>\n    <string name=\"something_went_wrong_emphasis\">Ой… Нешта пайшло не так. Вы можаце напісаць мне, выкарыстоўваючы параметры ніжэй, і я паспрабую знайсці рашэнне</string>\n    <string name=\"resize_and_convert\">Змяніць памер і канвертаваць</string>\n    <string name=\"resize_and_convert_sub\">Змяняйце памер дадзеных малюнкаў або канвертуйце іх у іншыя фарматы. Метададзеныя EXIF таксама можна рэдагаваць тут, выбраўшы адну выяву.</string>\n    <string name=\"draw_arrows_sub\">Калі ўключана, шлях малявання будзе паказаны ў выглядзе стрэлкі</string>\n    <string name=\"fidelity_sub\">Схема, якая вельмі падобная на схему кантэнту</string>\n    <string name=\"pdf_tools_sub\">Працуйце з PDF-файламі: папярэдні прагляд, пераўтварэнне ў групу малюнкаў або стварэнне аднаго з дадзеных малюнкаў</string>\n    <string name=\"old_tv\">Стары тэлевізар</string>\n    <string name=\"shuffle_blur\">Выпадковае размыццё</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Тып распазнавання</string>\n    <string name=\"fast\">Хуткі</string>\n    <string name=\"standard\">Стандартны</string>\n    <string name=\"best\">Лепшы</string>\n    <string name=\"segmentation_mode\">Рэжым сегментацыі</string>\n    <string name=\"restore_background_sub\">Пэндзаль адновіць фон замест сцірання</string>\n    <string name=\"horizontal_grid\">Гарызантальная сетка</string>\n    <string name=\"vertical_grid\">Вертыкальная сетка</string>\n    <string name=\"stitch_mode\">Рэжым вышыўкі</string>\n    <string name=\"rows_count\">Колькасць радкоў</string>\n    <string name=\"columns_count\">Граф слупкоў</string>\n    <string name=\"slide\">слайд</string>\n    <string name=\"side_by_side\">Побач</string>\n    <string name=\"toggle_tap\">Пераключыць кран</string>\n    <string name=\"transparency\">Празрыстасць</string>\n    <string name=\"saved_to_original\">Перазапісаны файл з назвай %1$s у першапачатковым месцы прызначэння</string>\n    <string name=\"magnifier\">Лупа</string>\n    <string name=\"magnifier_sub\">Ўключае лупу ў верхняй частцы пальца ў рэжымах малявання для лепшай даступнасці</string>\n    <string name=\"force_exif_widget_initial_value\">Прымусовае пачатковае значэнне</string>\n    <string name=\"favorite\">Любімая</string>\n    <string name=\"no_favorite_filters\">Яшчэ не дададзены любімыя фільтры</string>\n    <string name=\"b_spline\">Б Сплайн</string>\n    <string name=\"native_stack_blur\">Уласнае размыццё стэка</string>\n    <string name=\"regular\">Рэгулярны</string>\n    <string name=\"blur_edges\">Размыць краю</string>\n    <string name=\"blur_edges_sub\">Малюе размытыя краю пад зыходным відарысам, каб запоўніць прастору вакол яго замест аднаго колеру, калі ўключана</string>\n    <string name=\"inverse_fill_type\">Зваротны тып запаўнення</string>\n    <string name=\"inverse_fill_type_sub\">Калі ўключана, усе незамаскіраваныя вобласці будуць адфільтраваны замест паводзін па змаўчанні</string>\n    <string name=\"confetti\">Канфеці</string>\n    <string name=\"confetti_sub\">Канфеці будзе паказвацца пры захаванні, абагульванні і іншых асноўных дзеяннях</string>\n    <string name=\"secure_mode\">Бяспечны рэжым</string>\n    <string name=\"secure_mode_sub\">Хавае змесціва пры выхадзе, таксама немагчыма захапіць або запісаць экран</string>\n    <string name=\"brush_softness\">Мяккасць пэндзля</string>\n    <string name=\"crop_description\">Фотаздымкі будуць абрэзаны па цэнтры да ўведзенага памеру. Палатно будзе разгорнута з зададзеным колерам фону, калі малюнак меншы за ўведзеныя памеры.</string>\n    <string name=\"donation\">Ахвяраванне</string>\n    <string name=\"output_image_scale\">Выхадны маштаб малюнка</string>\n    <string name=\"image_orientation\">Арыентацыя выявы</string>\n    <string name=\"horizontal\">Гарызантальны</string>\n    <string name=\"vertical\">Вертыкальны</string>\n    <string name=\"scale_small_images_to_large\">Маштабуйце маленькія выявы да вялікіх</string>\n    <string name=\"neutral_sub\">Стыль крыху больш храматычны, чым манахромны</string>\n    <string name=\"vibrant_sub\">Гучная тэма, маляўнічасць максімальная для першаснай палітры, павышаная для іншых</string>\n    <string name=\"preview_pdf\">Папярэдні прагляд PDF</string>\n    <string name=\"highlighter_sub\">Намалюйце напаўпразрысты завостраны контур маркера</string>\n    <string name=\"privacy_blur_sub\">Размывае малюнак пад намаляваным шляхам, каб засцерагчы ўсё, што вы хочаце схаваць</string>\n    <string name=\"containers_shadow\">Кантэйнеры</string>\n    <string name=\"containers_shadow_sub\">Ўключае малюнак ценяў за кантэйнерамі</string>\n    <string name=\"sliders_shadow\">Паўзункі</string>\n    <string name=\"switches_shadow\">Выключальнікі</string>\n    <string name=\"fabs_shadow\">ФАБ</string>\n    <string name=\"buttons_shadow\">Гузікі</string>\n    <string name=\"sliders_shadow_sub\">Ўключае малюнак ценяў за паўзункамі</string>\n    <string name=\"switches_shadow_sub\">Ўключае малюнак ценяў за пераключальнікамі</string>\n    <string name=\"fabs_shadow_sub\">Ўключае малюнак ценяў за плаваючымі кнопкамі дзеянняў</string>\n    <string name=\"buttons_shadow_sub\">Ўключае малюнак ценяў за стандартнымі кнопкамі</string>\n    <string name=\"attention\">Увага</string>\n    <string name=\"fading_edges\">Выцвітаючыя краю</string>\n    <string name=\"both\">Абодва</string>\n    <string name=\"invert_colors\">Інвертаваць колеры</string>\n    <string name=\"invert_colors_sub\">Замяняе колеры тэмы на адмоўныя, калі ўключана</string>\n    <string name=\"exit\">Выхад</string>\n    <string name=\"preview_closing\">Калі вы выйдзеце з папярэдняга прагляду зараз, вам трэба будзе зноў дадаць выявы</string>\n    <string name=\"lasso\">Ласо</string>\n    <string name=\"lasso_sub\">Малюе замкнуты заліты шлях па зададзеным шляху</string>\n    <string name=\"image_format\">Фармат выявы</string>\n    <string name=\"anaglyph\">Анагліф</string>\n    <string name=\"noise\">Шум</string>\n    <string name=\"pixel_sort\">Сартаванне пікселяў</string>\n    <string name=\"shuffle\">Ператасаваць</string>\n    <string name=\"dark_colors\">Цёмныя колеру</string>\n    <string name=\"dark_colors_sub\">Выкарыстоўвае каляровую схему начнога рэжыму замест светлага варыянту</string>\n    <string name=\"material_you_sub\">Стварае палітру \\\"Material You\\\" з малюнка</string>\n    <string name=\"copy_as_compose_code\">Скапіруйце як код \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Размыццё кольцы</string>\n    <string name=\"cross_blur\">Перакрыжаванае размыццё</string>\n    <string name=\"circle_blur\">Размыццё круга</string>\n    <string name=\"star_blur\">Размыццё зоркамі</string>\n    <string name=\"linear_tilt_shift\">Лінейны зрух нахілу</string>\n    <string name=\"tags_to_remove\">Тэгі для выдалення</string>\n    <string name=\"apng_tools\">Інструменты APNG</string>\n    <string name=\"apng_tools_sub\">Пераўтварайце выявы ў малюнак APNG або выцягвайце кадры з дадзенага малюнка APNG</string>\n    <string name=\"apng_type_to_apng\">Выявы ў APNG</string>\n    <string name=\"select_apng_image_to_start\">Каб пачаць, абярыце выяву APNG</string>\n    <string name=\"motion_blur\">Размыццё ў руху</string>\n    <string name=\"apng_type_to_image\">APNG да малюнкаў</string>\n    <string name=\"apng_type_to_image_sub\">Пераўтварыце файл APNG у пакет малюнкаў</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Стварыце файл Zip з дадзеных файлаў або малюнкаў</string>\n    <string name=\"apng_type_to_apng_sub\">Пераўтварыце пакет малюнкаў у файл APNG</string>\n    <string name=\"drag_handle_width\">Шырыня маркера перацягвання</string>\n    <string name=\"confetti_type\">Тып канфеці</string>\n    <string name=\"auto_paste_sub\">Разрашыць праграме аўтаматычна ўставіць дадзеныя з буфера абмену, каб яны з\\'явіліся на галоўным экране, і вы змаглі іх апрацаваць</string>\n    <string name=\"harmonization_color\">Колер гарманізацыі</string>\n    <string name=\"harmonization_level\">Узровень гарманізацыі</string>\n    <string name=\"lossy_compression_sub\">Выкарыстоўваецца сціск са стратамі для памяншэння памеру файла замест сціску без страт</string>\n    <string name=\"festive\">Святочны</string>\n    <string name=\"explode\">Выбух</string>\n    <string name=\"rain\">Дождж</string>\n    <string name=\"corners\">Куткі</string>\n    <string name=\"jxl_tools\">Інструменты JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL ў JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Выканайце перакадзіраванне без страт з JXL ў JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Выканайце перакадзіраванне без страт з JPEG ў JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG ў JXL</string>\n    <string name=\"fast_gaussian_blur_2d\">Хуткае размыццё па Гаўсу 2D</string>\n    <string name=\"fast_gaussian_blur_4d\">Хуткае размыццё па Гаўсу 4D</string>\n    <string name=\"header_yesterday\">Ўчора</string>\n    <string name=\"embedded_picker_sub\">Выкарыстоўвае ўласны інструмент выбару малюнкаў замест наканаваных сістэмай</string>\n    <string name=\"request\">Запыт</string>\n    <string name=\"auto_paste\">Аўтаўстаўка</string>\n    <string name=\"jxl_tools_sub\">Выканайце перакадзіраванне JXL ~ JPEG без страты якасці або пераўтварыце анімацыю GIF/APNG ў JXL</string>\n    <string name=\"select_jxl_image_to_start\">Для пачатку абярыце відарыс JXL</string>\n    <string name=\"fast_gaussian_blur_3d\">Хуткае размыццё па Гаўсу 3D</string>\n    <string name=\"channels_configuration\">Канфігурацыя каналаў</string>\n    <string name=\"no_permissions\">Няма дазволаў</string>\n    <string name=\"header_today\">Сёння</string>\n    <string name=\"embedded_picker\">Убудаваны інструмент выбару</string>\n    <string name=\"lanczos_bessel\">Ланцош Бесэль</string>\n    <string name=\"lanczos_bessel_sub\">Метад паўторнай выбаркі, які падтрымлівае высакаякасную інтэрпаляцыю шляхам прымянення функцыі Беселя (jinc) да значэнняў пікселяў</string>\n    <string name=\"gif_type_to_jxl\">GIF ў JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Канвертуйце выявы GIF ў аніміраваныя выявы JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG ў JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Канвертуйце выявы APNG ў аніміраваныя выявы JXL</string>\n    <string name=\"jxl_type_to_images\">JXL ў Выявы</string>\n    <string name=\"jxl_type_to_images_sub\">Канвертуйце анімацыю JXL ў пакет малюнкаў</string>\n    <string name=\"jxl_type_to_jxl\">Выявы ў JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Канвертуйце партыю малюнкаў ў анімацыю JXL</string>\n    <string name=\"behavior\">Паводзіны</string>\n    <string name=\"skip_file_picking\">Прапусціць выбар файла</string>\n    <string name=\"skip_file_picking_sub\">Інструмент выбару файлаў будзе паказаны неадкладна, калі гэта магчыма, на выбраным экране</string>\n    <string name=\"generate_previews\">Стварыць прэв\\'ю</string>\n    <string name=\"generate_previews_sub\">Ўключае генерацыю папярэдняга прагляду, гэта можа дапамагчы пазбегнуць збояў на некаторых прыладах, гэта таксама адключае некаторыя функцыі рэдагавання ў рамках адной опцыі рэдагавання</string>\n    <string name=\"lossy_compression\">Сцісканне з стратамі</string>\n    <string name=\"compression_type\">Тып сціску</string>\n    <string name=\"speed_sub\">Кантралюе хуткасць дэкадавання выніковага відарыса, гэта павінна дапамагчы адкрыць выніковы відарыс хутчэй, значэнне %1$s азначае самае павольнае дэкадаванне, ў той час як %2$s - самае хуткае, гэты параметр можа павялічыць памер выходнага відарыса</string>\n    <string name=\"sorting\">Сартаванне</string>\n    <string name=\"sort_by_date\">Сартаваць па даце</string>\n    <string name=\"sort_by_date_reversed\">Сартаваць па даце (зваротна)</string>\n    <string name=\"sort_by_name_reversed\">Сартаваць па назве (зваротна)</string>\n    <string name=\"sort_by_name\">Сартаваць па назве</string>\n    <string name=\"show_settings_in_landscape_sub\">Калі гэта адключана, то ў ландшафтным рэжыме налады будуць адчыняцца па кнопцы ў верхняй панэлі прыкладання, як заўсёды, замест сталай бачнай опцыі</string>\n    <string name=\"fullscreen_settings_sub\">Ўключыце яго, і старонка настроек заўсёды будзе адкрывацца ў поўнаэкранным рэжыме, а не ў высоўнай скрыні</string>\n    <string name=\"try_again\">Паспрабаваць зноў</string>\n    <string name=\"show_settings_in_landscape\">Паказаць налады ў альбомнай арыентацыі</string>\n    <string name=\"pick\">Выбраць</string>\n    <string name=\"fullscreen_settings\">Поўнаэкранныя налады</string>\n    <string name=\"switch_type\">Тып пераключальніка</string>\n    <string name=\"pick_multiple_media\">Множны выбар медыя</string>\n    <string name=\"pick_single_media\">Выбар медыя</string>\n    <string name=\"downscale_image\">Памяншэнне выявы</string>\n    <string name=\"quadratic_threshold\">Квадратычны парог</string>\n    <string name=\"coordinates_rounding_tolerance\">Допуск акруглення каардынат</string>\n    <string name=\"add_new_folder\">Дадаць новую тэчку</string>\n    <string name=\"tag_bits_per_sample\">Бітоў на сэмпл</string>\n    <string name=\"tag_compression\">Кампрэсія</string>\n    <string name=\"tag_photometric_interpretation\">Фотаметрычная інтэрпрэтацыя</string>\n    <string name=\"tag_samples_per_pixel\">Сэмплаў на піксель</string>\n    <string name=\"tag_planar_configuration\">Планарная канфігурацыя</string>\n    <string name=\"compose\">Кампоз</string>\n    <string name=\"material_you_switch_sub\">Выкарыстоўвае перамыкач на аснове View, ён выглядае лепш за іншых і мае прыемную анімацыю</string>\n    <string name=\"compose_switch_sub\">Выкарыстоўвае перамыкач з Jetpack Compose, ён не так прыгожы, як на аснове View</string>\n    <string name=\"default_line_width\">Таўшчыня лініі па змаўчанні</string>\n    <string name=\"max\">Максімум</string>\n    <string name=\"resize_anchor\">Прывязка да памеру</string>\n    <string name=\"pixel_switch\">Піксель</string>\n    <string name=\"fluent_switch\">Флюент</string>\n    <string name=\"fluent_switch_sub\">Выкарыстоўвае перамыкач у стылі Windows 11 на аснове сістэмы дызайну Fluent</string>\n    <string name=\"cupertino_switch\">Куперціна</string>\n    <string name=\"cupertino_switch_sub\">Выкарыстоўвае iOS-падобны перамыкач на аснове сістэмы дызайну Куперціна</string>\n    <string name=\"engine_mode\">Рэжым рухавіка</string>\n    <string name=\"legacy\">Стары</string>\n    <string name=\"lstm_network\">Сетка LSTM</string>\n    <string name=\"legacy_and_lstm\">Стары &amp; LSTM</string>\n    <string name=\"convert\">Канвертаваць</string>\n    <string name=\"convert_sub\">Пераўтварэнне пакетаў выяваў у зададзены фармат</string>\n    <string name=\"images_to_svg\">Выявы ў SVG</string>\n    <string name=\"images_to_svg_sub\">Трасіроўка дадзеных малюнкаў у выявы SVG</string>\n    <string name=\"use_sampled_palette\">Выкарыстоўваць выбарачную палітру</string>\n    <string name=\"use_sampled_palette_sub\">Палітра квантавання будзе абрана, калі гэтая опцыя ўключана</string>\n    <string name=\"path_omit\">Пропуск шляху</string>\n    <string name=\"svg_warning\">Выкарыстанне гэтай прылады для адсочвання вялікіх малюнкаў без памяншэння маштабу не рэкамендуецца, гэта можа прывесці да збою і павелічэнню часу апрацоўкі</string>\n    <string name=\"downscale_image_sub\">Перад апрацоўкай малюнак будзе паменшаны да меншых памераў, гэта дапаможа прыладзе працаваць хутчэй і бяспечней.</string>\n    <string name=\"min_color_ratio\">Мінімальныя суадносіны колераў</string>\n    <string name=\"lines_threshold\">Парог ліній</string>\n    <string name=\"path_scale\">Маштаб шляху</string>\n    <string name=\"reset_properties\">Скінуць уласцівасці</string>\n    <string name=\"reset_properties_sub\">Для ўсіх уласцівасцей будуць устаноўлены значэнні па змаўчанні. Звярніце ўвагу, што гэта дзеянне немагчыма адмяніць</string>\n    <string name=\"detailed\">Падрабязны</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr субвыбарка</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr пазіцыянаванне</string>\n    <string name=\"tag_x_resolution\">Х Рэзалюцыя</string>\n    <string name=\"tag_y_resolution\">Дазвол Y</string>\n    <string name=\"tag_resolution_unit\">Адзінка дазволу</string>\n    <string name=\"tag_strip_offsets\">Зрушэнне паласы</string>\n    <string name=\"tag_rows_per_strip\">Радкоў на паласу</string>\n    <string name=\"tag_strip_byte_counts\">Паласа падліку байтаў</string>\n    <string name=\"tag_jpeg_interchange_format\">Фармат абмену JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Даўжыня фармату абмену JPEG</string>\n    <string name=\"tag_transfer_function\">Перадатная функцыя</string>\n    <string name=\"tag_white_point\">Уайт-Пойнт</string>\n    <string name=\"tag_primary_chromaticities\">Першасныя каляровасці</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Каэфіцыенты Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">Спасылка Чорны Белы</string>\n    <string name=\"tag_datetime\">Дата Час</string>\n    <string name=\"tag_image_description\">Апісанне выявы</string>\n    <string name=\"tag_make\">зрабіць</string>\n    <string name=\"tag_model\">мадэль</string>\n    <string name=\"tag_software\">праграмнае забеспячэнне</string>\n    <string name=\"tag_artist\">Мастак</string>\n    <string name=\"tag_copyright\">Аўтарскае права</string>\n    <string name=\"tag_exif_version\">Exif версія</string>\n    <string name=\"tag_flashpix_version\">Flashpix версія</string>\n    <string name=\"tag_color_space\">Каляровая прастора</string>\n    <string name=\"tag_gamma\">Гама</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y Dimension</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Сціснутыя біты на піксель</string>\n    <string name=\"tag_maker_note\">Заўвага вытворцы</string>\n    <string name=\"tag_user_comment\">Каментар карыстальніка</string>\n    <string name=\"tag_related_sound_file\">Звязаны гукавы файл</string>\n    <string name=\"tag_datetime_original\">Дата Час Арыгінал</string>\n    <string name=\"tag_datetime_digitized\">Дата Час Алічбаваны</string>\n    <string name=\"tag_offset_time\">Час зрушэння</string>\n    <string name=\"tag_offset_time_original\">Арыгінал часу зрушэння</string>\n    <string name=\"tag_offset_time_digitized\">Час зрушэння алічбаваны</string>\n    <string name=\"tag_subsec_time\">Субсекундны час</string>\n    <string name=\"tag_subsec_time_original\">Арыгінал субсекунднага часу</string>\n    <string name=\"tag_subsec_time_digitized\">Падсекундны час алічбаваны</string>\n    <string name=\"tag_exposure_time\">Час уздзеяння</string>\n    <string name=\"tag_f_number\">Нумар F</string>\n    <string name=\"tag_exposure_program\">Праграму экспазіцыі</string>\n    <string name=\"tag_spectral_sensitivity\">Спектральная адчувальнасць</string>\n    <string name=\"tag_photographic_sensitivity\">Фатаграфічная адчувальнасць</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Тып адчувальнасці</string>\n    <string name=\"tag_standard_output_sensitivity\">Стандартная выхадная адчувальнасць</string>\n    <string name=\"tag_recommended_exposure_index\">Рэкамендаваны індэкс экспазіцыі</string>\n    <string name=\"tag_iso_speed\">Хуткасць ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Шырата хуткасці ISO yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Шырата хуткасці ISO zzz</string>\n    <string name=\"tag_shutter_speed_value\">Значэнне вытрымкі</string>\n    <string name=\"tag_aperture_value\">Значэнне дыяфрагмы</string>\n    <string name=\"tag_brightness_value\">Значэнне яркасці</string>\n    <string name=\"tag_exposure_bias_value\">Значэнне зрушэння экспазіцыі</string>\n    <string name=\"tag_max_aperture_value\">Максімальнае значэнне дыяфрагмы</string>\n    <string name=\"tag_subject_distance\">Прадметная дыстанцыя</string>\n    <string name=\"tag_metering_mode\">Рэжым вымярэння</string>\n    <string name=\"tag_flash\">Успышка</string>\n    <string name=\"tag_subject_area\">Прадметная вобласць</string>\n    <string name=\"tag_focal_length\">Фокусная адлегласць</string>\n    <string name=\"tag_flash_energy\">Энергія ўспышкі</string>\n    <string name=\"tag_spatial_frequency_response\">Прасторавая частотная характарыстыка</string>\n    <string name=\"tag_focal_plane_x_resolution\">Разрозненне X у факальнай плоскасці</string>\n    <string name=\"tag_focal_plane_y_resolution\">Раздзяленне факальнай плоскасці Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Блок раздзялення ў факальнай плоскасці</string>\n    <string name=\"tag_subject_location\">Размяшчэнне прадмета</string>\n    <string name=\"tag_exposure_index\">Індэкс экспазіцыі</string>\n    <string name=\"tag_sensing_method\">Метад зандзіравання</string>\n    <string name=\"tag_file_source\">Крыніца файла</string>\n    <string name=\"tag_cfa_pattern\">Шаблон CFA</string>\n    <string name=\"tag_custom_rendered\">Атрымана на заказ</string>\n    <string name=\"tag_exposure_mode\">Рэжым экспазіцыі</string>\n    <string name=\"tag_white_balance\">Баланс белага</string>\n    <string name=\"tag_digital_zoom_ratio\">Каэфіцыент лічбавага маштабавання</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Фокусная адлегласць у плёнцы 35 мм</string>\n    <string name=\"tag_scene_capture_type\">Тып захопу сцэны</string>\n    <string name=\"tag_gain_control\">Кантроль узмацнення</string>\n    <string name=\"tag_contrast\">Кантраст</string>\n    <string name=\"tag_saturation\">Насычанасць</string>\n    <string name=\"tag_sharpness\">Рэзкасць</string>\n    <string name=\"tag_device_setting_description\">Апісанне налад прылады</string>\n    <string name=\"tag_subject_distance_range\">Дыяпазон адлегласці аб\\'екта</string>\n    <string name=\"tag_image_unique_id\">Унікальны ідэнтыфікатар выявы</string>\n    <string name=\"tag_camera_owner_name\">Імя ўладальніка камеры</string>\n    <string name=\"tag_body_serial_number\">Серыйны нумар корпуса</string>\n    <string name=\"tag_lens_specification\">Спецыфікацыя аб\\'ектыва</string>\n    <string name=\"tag_lens_make\">Марка аб\\'ектыва</string>\n    <string name=\"tag_lens_model\">Мадэль аб\\'ектыва</string>\n    <string name=\"tag_lens_serial_number\">Серыйны нумар аб\\'ектыва</string>\n    <string name=\"tag_gps_version_id\">Ідэнтыфікатар версіі GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Шырата GPS Ref</string>\n    <string name=\"tag_gps_latitude\">Шырата GPS</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Даўгата Ref</string>\n    <string name=\"tag_gps_longitude\">Даўгата GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Вышыня па GPS</string>\n    <string name=\"tag_gps_altitude\">GPS вышыня</string>\n    <string name=\"tag_gps_timestamp\">Пазнака часу GPS</string>\n    <string name=\"tag_gps_satellites\">Спадарожнікі GPS</string>\n    <string name=\"tag_gps_status\">Статус GPS</string>\n    <string name=\"tag_gps_measure_mode\">Рэжым вымярэння GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Спасылка на хуткасць GPS</string>\n    <string name=\"tag_gps_speed\">Хуткасць GPS</string>\n    <string name=\"tag_gps_track_ref\">GPS-трэк Ref</string>\n    <string name=\"tag_gps_track\">GPS-трэк</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img Напрамак Ref</string>\n    <string name=\"tag_gps_img_direction\">Напрамак малюнка GPS</string>\n    <string name=\"tag_gps_map_datum\">Дата карты GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">Шырата пункта прызначэння GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS - даўгата пункта прызначэння</string>\n    <string name=\"tag_gps_dest_longitude\">Даўгата пункта прызначэння GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Даз. пункт прызначэння GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Пеленг GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Спасылка на адлегласць да пункта прызначэння GPS</string>\n    <string name=\"tag_gps_dest_distance\">Пункт прызначэння GPS</string>\n    <string name=\"tag_gps_processing_method\">Метад апрацоўкі GPS</string>\n    <string name=\"tag_gps_area_information\">Інфармацыя пра вобласць GPS</string>\n    <string name=\"tag_gps_datestamp\">Штамп даты GPS</string>\n    <string name=\"tag_gps_differential\">Дыферэнцыял GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Памылка пазіцыянавання GPS H</string>\n    <string name=\"tag_interoperability_index\">Індэкс сумяшчальнасці</string>\n    <string name=\"tag_dng_version\">Dng версія</string>\n    <string name=\"tag_default_crop_size\">Памер кадравання па змаўчанні</string>\n    <string name=\"tag_orf_preview_image_start\">Пачатак папярэдняга прагляду выявы</string>\n    <string name=\"tag_orf_preview_image_length\">Даўжыня відарыса папярэдняга прагляду</string>\n    <string name=\"tag_orf_aspect_frame\">Рамка бакоў</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Ніжняя мяжа датчыка</string>\n    <string name=\"tag_rw2_sensor_left_border\">Левая мяжа датчыка</string>\n    <string name=\"tag_rw2_sensor_right_border\">Правая мяжа датчыка</string>\n    <string name=\"tag_rw2_sensor_top_border\">Верхняя мяжа датчыка</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Намалюйце тэкст на шляху зададзеным шрыфтам і колерам</string>\n    <string name=\"font_size\">Памер шрыфта</string>\n    <string name=\"watermark_size\">Памер вадзянога знака</string>\n    <string name=\"repeat_text\">Паўтарыць тэкст</string>\n    <string name=\"repeat_text_sub\">Бягучы тэкст будзе паўтарацца да канца шляху замест аднаразовага малявання</string>\n    <string name=\"dash_size\">Памер рыскі</string>\n    <string name=\"draw_mode_image_sub\">Выкарыстоўвайце абраны малюнак, каб намаляваць яго ўздоўж зададзенага шляху</string>\n    <string name=\"draw_image_sub\">Гэты відарыс будзе выкарыстоўвацца як паўтаральны запіс намаляванага шляху</string>\n    <string name=\"outlined_triangle_sub\">Малюе акрэслены трохвугольнік ад пачатковай да канчатковай кропкі</string>\n    <string name=\"triangle_sub\">Малюе акрэслены трохвугольнік ад пачатковай да канчатковай кропкі</string>\n    <string name=\"outlined_triangle\">Акрэслены трохкутнік</string>\n    <string name=\"triangle\">Трохвугольнік</string>\n    <string name=\"polygon_sub\">Малюе шматкутнік ад пачатковай да канчатковай кропкі</string>\n    <string name=\"polygon\">Шматкутнік</string>\n    <string name=\"outlined_polygon\">Акрэслены шматкутнік</string>\n    <string name=\"outlined_polygon_sub\">Малюе акрэслены шматкутнік ад пачатковай да канчатковай кропкі</string>\n    <string name=\"vertices\">Вершыні</string>\n    <string name=\"draw_regular_polygon\">Намалюйце правільны шматкутнік</string>\n    <string name=\"draw_regular_polygon_sub\">Намалюйце шматкутнік, які будзе правільнай, а не свабоднай формы</string>\n    <string name=\"star_sub\">Малюе зорку ад пачатковай да канчатковай кропкі</string>\n    <string name=\"star\">Зорка</string>\n    <string name=\"outlined_star\">Акрэсленая зорка</string>\n    <string name=\"outlined_star_sub\">Малюе акрэсленую зорку ад пачатковай да канчатковай кропкі</string>\n    <string name=\"inner_radius_ratio\">Суадносіны ўнутранага радыусу</string>\n    <string name=\"draw_regular_star\">Намалюйце звычайную зорку</string>\n    <string name=\"draw_regular_star_sub\">Намалюйце зорку, якая будзе правільнай, а не свабоднай формы</string>\n    <string name=\"antialias\">Антыаліас</string>\n    <string name=\"antialias_sub\">Уключае згладжванне для прадухілення вострых краёў</string>\n    <string name=\"open_edit_instead_of_preview\">Адкрыйце праўку замест папярэдняга прагляду</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Калі вы выбіраеце відарыс для адкрыцця (прагляду) у ImageToolbox, замест папярэдняга прагляду будзе адкрыты аркуш выбару рэдагавання</string>\n    <string name=\"document_scanner\">Сканер дакументаў</string>\n    <string name=\"document_scanner_sub\">Сканіруйце дакументы і стварайце PDF або асобныя выявы з іх</string>\n    <string name=\"click_to_start_scanning\">Націсніце, каб пачаць сканаванне</string>\n    <string name=\"start_scanning\">Пачаць сканаванне</string>\n    <string name=\"save_as_pdf\">Захаваць як pdf</string>\n    <string name=\"share_as_pdf\">Падзяліцца як pdf</string>\n    <string name=\"options_below_is_for_images\">Параметры ніжэй прызначаны для захавання малюнкаў, а не PDF</string>\n    <string name=\"equalize_histogram_hsv\">Выраўнаваць гістаграму HSV</string>\n    <string name=\"equalize_histogram\">Выраўнаваць гістаграму</string>\n    <string name=\"enter_percentage\">Увядзіце працэнт</string>\n    <string name=\"allow_enter_by_text_field\">Дазволіць увод праз тэкставае поле</string>\n    <string name=\"allow_enter_by_text_field_sub\">Уключае тэкставае поле за выбарам перадустановак, каб уводзіць іх на лета</string>\n    <string name=\"scale_color_space\">Шкала Каляровая прастора</string>\n    <string name=\"linear\">Лінейны</string>\n    <string name=\"equalize_histogram_pixelation\">Выраўноўванне пікселізацыі гістаграмы</string>\n    <string name=\"grid_size_x\">Памер сеткі X</string>\n    <string name=\"grid_size_y\">Памер сеткі Y</string>\n    <string name=\"equalize_histogram_adaptive\">Адаптыўная гістаграма выраўноўвання</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Адаптыўны LUV для выраўноўвання гістаграмы</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalize Histogram Adaptive LAB</string>\n    <string name=\"clahe\">КЛАЕ</string>\n    <string name=\"clahe_lab\">ЛАБАРАТЫЯ КЛАЭ</string>\n    <string name=\"clahe_luv\">КЛАЭ ЛУВ</string>\n    <string name=\"crop_to_content\">Абрэзаць да змесціва</string>\n    <string name=\"frame_color\">Колер рамкі</string>\n    <string name=\"color_to_ignore\">Колер, які трэба ігнараваць</string>\n    <string name=\"template\">Шаблон</string>\n    <string name=\"no_template_filters\">Ніякіх шаблонных фільтраў не дададзена</string>\n    <string name=\"create_new\">Стварыць новы</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Адсканаваны QR-код не з\\'яўляецца сапраўдным шаблонам фільтра</string>\n    <string name=\"scan_qr_code\">Адсканіраваць QR-код</string>\n    <string name=\"opened_file_have_no_filter_template\">Выбраны файл не мае даных шаблону фільтра</string>\n    <string name=\"create_template\">Стварыць шаблон</string>\n    <string name=\"template_name\">Імя шаблона</string>\n    <string name=\"select_template_preview\">Гэта выява будзе выкарыстоўвацца для папярэдняга прагляду гэтага шаблону фільтра</string>\n    <string name=\"template_filter\">Фільтр шаблонаў</string>\n    <string name=\"as_qr_code\">Як выява QR-кода</string>\n    <string name=\"as_file\">Як файл</string>\n    <string name=\"save_as_file\">Захаваць як файл</string>\n    <string name=\"save_as_qr_code_image\">Захаваць як відарыс QR-кода</string>\n    <string name=\"delete_template\">Выдаліць шаблон</string>\n    <string name=\"delete_template_warn\">Вы збіраецеся выдаліць выбраны фільтр шаблона. Гэтую аперацыю нельга адмяніць</string>\n    <string name=\"added_filter_template\">Дададзены шаблон фільтра з назвай \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Папярэдні прагляд фільтра</string>\n    <string name=\"qr_code\">QR і штрых-код</string>\n    <string name=\"qr_code_sub\">Адсканіруйце QR-код і атрымайце яго змесціва або ўстаўце свой радок, каб стварыць новы</string>\n    <string name=\"code_content\">Змест кода</string>\n    <string name=\"scan_qr_code_to_replace_content\">Адсканіруйце любы штрых-код, каб замяніць змесціва ў полі, або ўвядзіце што-небудзь, каб стварыць новы штрых-код выбранага тыпу</string>\n    <string name=\"qr_description\">QR-апісанне</string>\n    <string name=\"min\">Мін</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Дайце дазвол камеры ў наладах для сканіравання QR-кода</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Дайце дазвол камеры ў наладах, каб сканаваць сканер дакументаў</string>\n    <string name=\"cubic\">Кубічны</string>\n    <string name=\"bspline\">Б-сплайн</string>\n    <string name=\"hamming\">Хэмінг</string>\n    <string name=\"hanning\">Ханінг</string>\n    <string name=\"blackman\">Чорны чалавек</string>\n    <string name=\"welch\">Уэлч</string>\n    <string name=\"quadric\">Квадрычны</string>\n    <string name=\"gaussian\">Гаўсава</string>\n    <string name=\"sphinx\">Сфінкс</string>\n    <string name=\"bartlett\">Бартлет</string>\n    <string name=\"robidoux\">Рабіду</string>\n    <string name=\"robidoux_sharp\">Робіду Шарп</string>\n    <string name=\"spline16\">Сплайн 16</string>\n    <string name=\"spline36\">Сплайн 36</string>\n    <string name=\"spline64\">Сплайн 64</string>\n    <string name=\"kaiser\">Кайзер</string>\n    <string name=\"bartlett_hann\">Бартлетт-Ён</string>\n    <string name=\"box\">скрынка</string>\n    <string name=\"bohman\">Боман</string>\n    <string name=\"lanczos2\">Ланцош 2</string>\n    <string name=\"lanczos3\">Ланцош 3</string>\n    <string name=\"lanczos4\">Ланцош 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Кубічная інтэрпаляцыя забяспечвае больш плыўнае маштабаванне з улікам бліжэйшых 16 пікселяў, даючы лепшыя вынікі, чым білінейная</string>\n    <string name=\"bspline_sub\">Выкарыстоўвае шматчленныя функцыі для плыўнай інтэрпаляцыі і апраксімацыі крывой або паверхні, гнуткае і бесперапыннае прадстаўленне формы</string>\n    <string name=\"hamming_sub\">Аконная функцыя, якая выкарыстоўваецца для памяншэння спектральнай уцечкі шляхам звужэння краёў сігналу, карысная пры апрацоўцы сігналаў</string>\n    <string name=\"hanning_sub\">Варыянт акна Хана, які звычайна выкарыстоўваецца для памяншэння спектральнай уцечкі ў праграмах апрацоўкі сігналаў</string>\n    <string name=\"blackman_sub\">Аконная функцыя, якая забяспечвае добрае дазвол па частотах за кошт мінімізацыі спектральнай уцечкі, часта выкарыстоўваецца пры апрацоўцы сігналаў</string>\n    <string name=\"welch_sub\">Аконная функцыя, прызначаная для забеспячэння добрага частотнага раздзялення з паменшанай спектральнай уцечкай, часта выкарыстоўваецца ў праграмах апрацоўкі сігналаў</string>\n    <string name=\"quadric_sub\">Метад, які выкарыстоўвае квадратычную функцыю для інтэрпаляцыі, забяспечваючы гладкія і бесперапынныя вынікі</string>\n    <string name=\"gaussian_sub\">Метад інтэрпаляцыі, які прымяняе функцыю Гаўса, карысны для згладжвання і памяншэння шуму ў выявах</string>\n    <string name=\"sphinx_sub\">Удасканалены метад паўторнай выбаркі, які забяспечвае высакаякасную інтэрпаляцыю з мінімальнымі артэфактамі</string>\n    <string name=\"bartlett_sub\">Функцыя трохвугольнага акна, якая выкарыстоўваецца пры апрацоўцы сігналаў для памяншэння спектральнай уцечкі</string>\n    <string name=\"robidoux_sub\">Высакаякасны метад інтэрпаляцыі, аптымізаваны для натуральнага змены памеру выявы, балансу выразнасці і плыўнасці</string>\n    <string name=\"robidoux_sharp_sub\">Больш рэзкі варыянт метаду Робіду, аптымізаваны для выразнага змены памеру выявы</string>\n    <string name=\"spline16_sub\">Метад інтэрпаляцыі на аснове сплайнаў, які забяспечвае плыўныя вынікі з дапамогай фільтра з 16 націскамі</string>\n    <string name=\"spline36_sub\">Метад інтэрпаляцыі на аснове сплайнаў, які забяспечвае гладкія вынікі з выкарыстаннем фільтра з 36 націскамі</string>\n    <string name=\"spline64_sub\">Метад інтэрпаляцыі на аснове сплайнаў, які забяспечвае гладкія вынікі з выкарыстаннем фільтра з 64 націскамі</string>\n    <string name=\"kaiser_sub\">Метад інтэрпаляцыі, які выкарыстоўвае акно Кайзера, забяспечваючы добры кантроль над кампрамісам паміж шырынёй галоўнага пялёстка і ўзроўнем бакавых пялёсткаў</string>\n    <string name=\"bartlett_hann_sub\">Функцыя гібрыднага акна, якая аб\\'ядноўвае вокны Бартлета і Хана, выкарыстоўваецца для памяншэння спектральнай уцечкі пры апрацоўцы сігналаў</string>\n    <string name=\"box_sub\">Просты метад паўторнай выбаркі, які выкарыстоўвае сярэдняе значэнне бліжэйшых значэнняў пікселяў, што часта прыводзіць да з\\'яўлення блокаў</string>\n    <string name=\"bohman_sub\">Аконная функцыя, якая выкарыстоўваецца для памяншэння спектральнай уцечкі, забяспечваючы добрае дазвол частоты ў праграмах апрацоўкі сігналаў</string>\n    <string name=\"lanczos2_sub\">Метад паўторнай выбаркі, які выкарыстоўвае 2-лепестковы фільтр Ланцоша для высакаякаснай інтэрпаляцыі з мінімальнымі артэфактамі</string>\n    <string name=\"lanczos3_sub\">Метад паўторнай выбаркі, які выкарыстоўвае 3-лепестковы фільтр Lanczos для высакаякаснай інтэрпаляцыі з мінімальнымі артэфактамі</string>\n    <string name=\"lanczos4_sub\">Метад паўторнай выбаркі, які выкарыстоўвае 4-лепестковы фільтр Lanczos для высакаякаснай інтэрпаляцыі з мінімальнымі артэфактамі</string>\n    <string name=\"lanczos2_jinc_sub\">Варыянт фільтра Lanczos 2, які выкарыстоўвае функцыю jinc, забяспечваючы высакаякасную інтэрпаляцыю з мінімальнымі артэфактамі</string>\n    <string name=\"lanczos3_jinc_sub\">Варыянт фільтра Lanczos 3, які выкарыстоўвае функцыю jinc, забяспечваючы высакаякасную інтэрпаляцыю з мінімальнымі артэфактамі</string>\n    <string name=\"lanczos4_jinc_sub\">Варыянт фільтра Lanczos 4, які выкарыстоўвае функцыю jinc, забяспечваючы высакаякасную інтэрпаляцыю з мінімальнымі артэфактамі</string>\n    <string name=\"ewa_hanning\">Ханінг EWA</string>\n    <string name=\"ewa_hanning_sub\">Эліптычны сярэднеўзважаны (EWA) варыянт фільтра Ханінга для плыўнай інтэрпаляцыі і паўторнай выбаркі</string>\n    <string name=\"ewa_robidoux\">Рабіду ЭВА</string>\n    <string name=\"ewa_robidoux_sub\">Эліптычны сярэднеўзважаны (EWA) варыянт фільтра Robidoux для высакаякаснай паўторнай выбаркі</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Эліптычны сярэднеўзважаны (EWA) варыянт фільтра Блэкмана для мінімізацыі артэфактаў гуку</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Эліптычны сярэднеўзважаны варыянт (EWA) фільтра Quadric для гладкай інтэрпаляцыі</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Эліптычны сярэднеўзважаны (EWA) варыянт фільтра Robidoux Sharp для больш выразных вынікаў</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Варыянт фільтра Lanczos 3 Jinc з эліптычным сярэднеўзважаным значэннем (EWA) для высакаякаснай паўторнай дыскрэтызацыі з паменшаным згладжваннем</string>\n    <string name=\"ginseng\">Жэньшэнь</string>\n    <string name=\"ginseng_sub\">Фільтр паўторнай выбаркі, прызначаны для высакаякаснай апрацоўкі малюнкаў з добрым балансам рэзкасці і плыўнасці</string>\n    <string name=\"ewa_ginseng\">Жэньшэнь EWA</string>\n    <string name=\"ewa_ginseng_sub\">Эліптычны сярэднеўзважаны (EWA) варыянт фільтра Ginseng для паляпшэння якасці выявы</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Elliptical Weighted Average (EWA) варыянт фільтра Lanczos Sharp для дасягнення выразных вынікаў з мінімальнымі артэфактамі</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Варыянт Elliptical Weighted Average (EWA) фільтра Lanczos 4 Sharpest для надзвычай выразнай паўторнай выбаркі выявы</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Эліптычны сярэднеўзважаны (EWA) варыянт мяккага фільтра Lanczos для больш плыўнай паўторнай выбаркі выявы</string>\n    <string name=\"haasn_soft\">Мяккі Haasn</string>\n    <string name=\"haasn_soft_sub\">Фільтр паўторнай выбаркі, распрацаваны Haasn для плыўнага і без артэфактаў маштабавання выявы</string>\n    <string name=\"format_conversion\">Пераўтварэнне фарматаў</string>\n    <string name=\"format_conversion_sub\">Пераўтварыце партыю малюнкаў з аднаго фармату ў іншы</string>\n    <string name=\"dismiss_forever\">Звольніць назаўжды</string>\n    <string name=\"image_stacking\">Стэкінг малюнкаў</string>\n    <string name=\"image_stacking_sub\">Складайце выявы адзін на аднаго з выбранымі рэжымамі змешвання</string>\n    <string name=\"add_image\">Дадаць выяву</string>\n    <string name=\"bins_count\">Лічыць бункеры</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Адаптыўны HSL выраўноўвання гістаграмы</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Адаптыўная гістаграма Equalize HSV</string>\n    <string name=\"edge_mode\">Рэжым Edge</string>\n    <string name=\"clip\">Кліп</string>\n    <string name=\"wrap\">Абгарнуць</string>\n    <string name=\"color_blind_scheme\">Барваслепасць</string>\n    <string name=\"color_blind_scheme_sub\">Выберыце рэжым, каб адаптаваць колеры тэмы для абранага варыянту дальтанізму</string>\n    <string name=\"protanomaly_sub\">Цяжка адрозніць чырвоны і зялёны адценні</string>\n    <string name=\"deuteranomaly_sub\">Цяжка адрозніць зялёны і чырвоны адценні</string>\n    <string name=\"tritanomaly_sub\">Цяжка адрозніць сіні і жоўты адценні</string>\n    <string name=\"protanopia_sub\">Няздольнасць ўспрымаць чырвоныя адценні</string>\n    <string name=\"deuteranopia_sub\">Няздольнасць ўспрымаць зялёныя адценні</string>\n    <string name=\"tritanopia_sub\">Няздольнасць ўспрымаць блакітныя адценні</string>\n    <string name=\"achromatomaly_sub\">Зніжэнне адчувальнасці да ўсіх колераў</string>\n    <string name=\"achromatopsia_sub\">Поўная барваслепасць, бачыць толькі адценні шэрага</string>\n    <string name=\"not_use_color_blind_scheme\">Не выкарыстоўвайце схему дальтоніка</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Колеры будуць дакладна такімі, якія зададзены ў тэме</string>\n    <string name=\"sigmoidal\">Сігмападобная</string>\n    <string name=\"lagrange_2\">Лагранж 2</string>\n    <string name=\"lagrange_2_sub\">Інтэрпаляцыйны фільтр Лагранжа парадку 2, прыдатны для высакаякаснага маштабавання выявы з плыўнымі пераходамі</string>\n    <string name=\"lagrange_3\">Лагранж 3</string>\n    <string name=\"lagrange_3_sub\">Інтэрпаляцыйны фільтр Лагранжа парадку 3, які прапануе лепшую дакладнасць і больш плыўныя вынікі для маштабавання выявы</string>\n    <string name=\"lanczos_6\">Ланцош 6</string>\n    <string name=\"lanczos_6_sub\">Фільтр паўторнай выбаркі Lanczos з больш высокім парадкам 6, які забяспечвае больш выразнае і дакладнае маштабаванне выявы</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Варыянт фільтра Lanczos 6 з выкарыстаннем функцыі Jinc для паляпшэння якасці перадвыбаркі выявы</string>\n    <string name=\"linear_box_blur\">Лінейнае размыццё поля</string>\n    <string name=\"linear_tent_blur\">Лінейнае размыццё палаткі</string>\n    <string name=\"linear_gaussian_box_blur\">Лінейнае размыццё скрынкі Гаўса</string>\n    <string name=\"linear_stack_blur\">Лінейнае размыццё стэка</string>\n    <string name=\"gaussian_box_blur\">Размыццё скрынкі Гаўса</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Лінейнае хуткае размыццё па Гаўсу Далей</string>\n    <string name=\"linear_fast_gaussian_blur\">Хуткае лінейнае размыццё па Гаўсу</string>\n    <string name=\"linear_gaussian_blur\">Лінейнае размыццё па Гаўсу</string>\n    <string name=\"draw_filter_sub\">Выберыце адзін фільтр, каб выкарыстоўваць яго ў якасці фарбы</string>\n    <string name=\"replace_filter\">Замяніць фільтр</string>\n    <string name=\"pick_filter_info\">Выберыце ніжэй фільтр, каб выкарыстоўваць яго ў якасці пэндзля ў сваім малюнку</string>\n    <string name=\"tiff_compression_scheme\">Схема сціску TIFF</string>\n    <string name=\"low_poly\">Нізкая полі</string>\n    <string name=\"sand_painting\">Карціна пяском</string>\n    <string name=\"image_splitting\">Раздзяленне выявы</string>\n    <string name=\"image_splitting_sub\">Разбіце адзін малюнак на радкі або слупкі</string>\n    <string name=\"fit_to_bounds\">Адпавядаць межам</string>\n    <string name=\"fit_to_bounds_sub\">Аб\\'яднайце рэжым змены памеру абрэзкі з гэтым параметрам, каб дасягнуць жаданага паводзін (абрэзка/падгонка да суадносін бакоў)</string>\n    <string name=\"languages_imported\">Мовы паспяхова імпартаваны</string>\n    <string name=\"backup_ocr_models\">Рэзервовае капіраванне мадэляў OCR</string>\n    <string name=\"import_word\">Імпарт</string>\n    <string name=\"export\">Экспарт</string>\n    <string name=\"position\">Пазіцыя</string>\n    <string name=\"center\">Цэнтр</string>\n    <string name=\"top_left\">Уверсе злева</string>\n    <string name=\"top_right\">Уверсе справа</string>\n    <string name=\"bottom_left\">Унізе злева</string>\n    <string name=\"bottom_right\">Унізе справа</string>\n    <string name=\"top_center\">Верхні цэнтр</string>\n    <string name=\"center_right\">Правы цэнтр</string>\n    <string name=\"bottom_center\">Ніжні цэнтр</string>\n    <string name=\"center_left\">Левы цэнтр</string>\n    <string name=\"target_image\">Мэтавы малюнак</string>\n    <string name=\"palette_transfer\">Перанос палітры</string>\n    <string name=\"enhanced_oil\">Палепшанае алей</string>\n    <string name=\"simple_old_tv\">Просты стары тэлевізар</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Готэм</string>\n    <string name=\"simple_sketch\">Просты эскіз</string>\n    <string name=\"soft_glow\">Мяккае ззянне</string>\n    <string name=\"color_poster\">Каляровы плакат</string>\n    <string name=\"tri_tone\">Тры тоны</string>\n    <string name=\"third_color\">Трэці колер</string>\n    <string name=\"clahe_oklab\">Клахе Аклаб</string>\n    <string name=\"clahe_oklch\">Клара Олх</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Гарошак</string>\n    <string name=\"clustered_2x2_dithering\">Кластарны згладжванне 2x2</string>\n    <string name=\"clustered_4x4_dithering\">Кластарны 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">Кластарны дызерінг 8x8</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Любыя параметры не выбраны, дадайце іх на старонцы інструментаў</string>\n    <string name=\"add_favorites\">Дадаць абранае</string>\n    <string name=\"harmony_complementary\">Камплементарныя</string>\n    <string name=\"harmony_analogous\">Аналаг</string>\n    <string name=\"harmony_triadic\">Трыяда</string>\n    <string name=\"harmony_split_complementary\">Спліт дадатковы</string>\n    <string name=\"harmony_tetradic\">Тэтрадычны</string>\n    <string name=\"harmony_square\">квадратны</string>\n    <string name=\"harmony_analogous_complementary\">Аналагічны + Дапаўняльны</string>\n    <string name=\"color_tools\">Інструменты колеру</string>\n    <string name=\"color_tools_sub\">Змешвайце, стварайце тоны, стварайце адценні і многае іншае</string>\n    <string name=\"color_harmonies\">Каляровыя гармоніі</string>\n    <string name=\"color_shading\">Зацяненне колеру</string>\n    <string name=\"variation\">Варыяцыя</string>\n    <string name=\"tints\">Адценні</string>\n    <string name=\"tones\">Тоны</string>\n    <string name=\"shades\">Адценні</string>\n    <string name=\"color_mixing\">Змешванне колераў</string>\n    <string name=\"color_info\">Інфармацыя пра колер</string>\n    <string name=\"selected_color\">Абраны колер</string>\n    <string name=\"color_to_mix\">Колер для змешвання</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Немагчыма выкарыстоўваць Манэ, калі ўключаны дынамічныя колеры</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Мэтавая выява LUT</string>\n    <string name=\"amatorka\">Аматар</string>\n    <string name=\"miss_etikate\">Міс Этыкет</string>\n    <string name=\"soft_elegance\">Мяккая элегантнасць</string>\n    <string name=\"soft_elegance_variant\">Варыянт Soft Elegance</string>\n    <string name=\"palette_transfer_variant\">Варыянт перадачы палітры</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Мэтавы файл 3D LUT (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Абыход адбельвальніка</string>\n    <string name=\"candlelight\">Святло свечак</string>\n    <string name=\"drop_blues\">Блюз</string>\n    <string name=\"edgy_amber\">Вострая Эмбер</string>\n    <string name=\"fall_colors\">Колеры восені</string>\n    <string name=\"film_stock_50\">Фільм фонд 50</string>\n    <string name=\"foggy_night\">Туманная ноч</string>\n    <string name=\"kodak\">Кодак</string>\n    <string name=\"save_empty_lut\">Атрымаць выяву нейтральнага LUT</string>\n    <string name=\"save_empty_lut_sub\">Спачатку выкарыстайце сваё любімае прыкладанне для рэдагавання фатаграфій, каб прымяніць фільтр да нейтральнай LUT, які вы можаце атрымаць тут. Каб гэта працавала належным чынам, колер кожнага пікселя не павінен залежаць ад іншых пікселяў (напрыклад, размыццё не будзе працаваць). Пасля гатоўнасці выкарыстоўвайце свой новы малюнак LUT у якасці ўваходных дадзеных для фільтра LUT 512*512</string>\n    <string name=\"pop_art\">Поп-арт</string>\n    <string name=\"celluloid\">Цэлюлоід</string>\n    <string name=\"coffee\">Кава</string>\n    <string name=\"golden_forest\">Залаты лес</string>\n    <string name=\"greenish\">Зеленаватыя</string>\n    <string name=\"retro_yellow\">Рэтра жоўты</string>\n    <string name=\"links_preview\">Папярэдні прагляд спасылак</string>\n    <string name=\"links_preview_sub\">Уключае папярэдні прагляд спасылак у месцах, дзе можна атрымаць тэкст (QRCode, OCR і г.д.)</string>\n    <string name=\"links\">Спасылкі</string>\n    <string name=\"ico_size_warning\">Файлы ICO можна захоўваць толькі ў максімальным памеры 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF у WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Пераўтварыце выявы GIF у аніміраваныя выявы WEBP</string>\n    <string name=\"webp_tools\">Інструменты WEBP</string>\n    <string name=\"webp_tools_sub\">Пераўтварайце выявы ў аніміраваныя выявы WEBP або выцягвайце кадры з дадзенай анімацыі WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP да малюнкаў</string>\n    <string name=\"webp_type_to_image_sub\">Пераўтварыце файл WEBP у пакет малюнкаў</string>\n    <string name=\"webp_type_to_webp_sub\">Пераўтварэнне пакета малюнкаў у файл WEBP</string>\n    <string name=\"webp_type_to_webp\">Выявы ў WEBP</string>\n    <string name=\"select_webp_image_to_start\">Каб пачаць, абярыце малюнак WEBP</string>\n    <string name=\"manage_storage_extra_types\">Няма поўнага доступу да файлаў</string>\n    <string name=\"manage_storage_extra_types_sub\">Дазволіць доступ да ўсіх файлаў, каб бачыць JXL, QOI і іншыя выявы, якія не распазнаюцца як выявы на Android. Без дазволу Image Toolbox не можа паказаць гэтыя выявы</string>\n    <string name=\"default_draw_color\">Колер малявання па змаўчанні</string>\n    <string name=\"default_draw_path_mode\">Рэжым шляху малявання па змаўчанні</string>\n    <string name=\"add_timestamp\">Дадаць метку часу</string>\n    <string name=\"add_timestamp_sub\">Дазваляе дадаваць метку часу да імя выходнага файла</string>\n    <string name=\"formatted_timestamp\">Адфарматаваная метка часу</string>\n    <string name=\"formatted_timestamp_sub\">Уключыць фарматаванне меткі часу ў назве выходнага файла замест асноўных мілі</string>\n    <string name=\"enable_timestamps_to_format_them\">Уключыце меткі часу, каб выбраць іх фармат</string>\n    <string name=\"one_time_save_location\">Аднаразовае захаванне месцазнаходжання</string>\n    <string name=\"one_time_save_location_sub\">Праглядвайце і рэдагуйце месцы аднаразовага захавання, якімі вы можаце карыстацца, доўга націскаючы кнопку захавання ў большасці варыянтаў</string>\n    <string name=\"recently_used\">Нядаўна выкарыстаны</string>\n    <string name=\"ci_channel\">Канал CI</string>\n    <string name=\"group\">Група</string>\n    <string name=\"image_toolbox_in_telegram\">Панэль інструментаў малюнкаў у Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Далучайцеся да нашага чата, дзе вы можаце абмяркоўваць усё, што заўгодна, а таксама зазірніце ў канал CI, дзе я публікую бэта-версіі і аб\\'явы</string>\n    <string name=\"ci_channel_sub\">Атрымлівайце апавяшчэнні аб новых версіях праграмы і чытайце аб\\'явы</string>\n    <string name=\"fit_description\">Адагнайце малюнак да зададзеных памераў і прымяніце размыццё або колер фону</string>\n    <string name=\"tools_arrangement\">Размяшчэнне інструментаў</string>\n    <string name=\"group_tools_by_type\">Згрупуйце інструменты па тыпу</string>\n    <string name=\"group_tools_by_type_sub\">Групуе інструменты на галоўным экране па іх тыпу замест карыстацкага спісу</string>\n    <string name=\"default_values\">Значэнні па змаўчанні</string>\n    <string name=\"system_bars_visibility\">Бачнасць сістэмных палос</string>\n    <string name=\"show_system_bars_by_swipe\">Паказаць сістэмныя панэлі, правёўшы пальцам</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Уключае правядзенне пальцам, каб паказаць сістэмныя панэлі, калі яны схаваныя</string>\n    <string name=\"auto\">Аўто</string>\n    <string name=\"hide_all\">Схаваць усе</string>\n    <string name=\"show_all\">Паказаць усе</string>\n    <string name=\"hide_nav_bar\">Схаваць панэль навігацыі</string>\n    <string name=\"hide_status_bar\">Схаваць радок стану</string>\n    <string name=\"noise_generation\">Генерацыя шуму</string>\n    <string name=\"noise_generation_sub\">Стварайце розныя шумы, такія як Perlin або іншыя тыпы</string>\n    <string name=\"frequency\">Частата</string>\n    <string name=\"noise_type\">Тып шуму</string>\n    <string name=\"rotation_type\">Тып кручэння</string>\n    <string name=\"fractal_type\">Фрактальны тып</string>\n    <string name=\"octaves\">Актавы</string>\n    <string name=\"lacunarity\">Лакунарность</string>\n    <string name=\"gain\">Узмацненне</string>\n    <string name=\"weighted_strength\">Узважаная сіла</string>\n    <string name=\"ping_pong_strength\">Сіла пінг-понга</string>\n    <string name=\"distance_function\">Функцыя адлегласці</string>\n    <string name=\"return_type\">Тып вяртання</string>\n    <string name=\"jitter\">Дрыгаценне</string>\n    <string name=\"domain_warp\">Дэфармацыя дамена</string>\n    <string name=\"alignment\">Выраўноўванне</string>\n    <string name=\"custom_filename\">Карыстальніцкае імя файла</string>\n    <string name=\"custom_filename_sub\">Выберыце месцазнаходжанне і імя файла, якія будуць выкарыстоўвацца для захавання бягучага малюнка</string>\n    <string name=\"saved_to_custom\">Захавана ў тэчку з карыстальніцкай назвай</string>\n    <string name=\"collage_maker\">Стваральнік калажаў</string>\n    <string name=\"collage_maker_sub\">Стварайце калажы з максімум 20 малюнкаў</string>\n    <string name=\"collage_type\">Тып калажа</string>\n    <string name=\"collages_info\">Утрымлівайце малюнак, каб памяняць месцамі, перамяшчаць і маштабаваць, каб адрэгуляваць становішча</string>\n    <string name=\"disable_rotation\">Адключыць паварот</string>\n    <string name=\"disable_rotation_sub\">Прадухіляе паварот малюнкаў з дапамогай жэстаў двума пальцамі</string>\n    <string name=\"enable_snapping_to_borders\">Уключыць прывязку да межаў</string>\n    <string name=\"enable_snapping_to_borders_sub\">Пасля перамяшчэння або павелічэння маштабу відарысы запаўняюць краю кадра</string>\n    <string name=\"histogram\">Гістаграма</string>\n    <string name=\"histogram_sub\">Гістаграма выявы RGB або яркасці, якая дапаможа вам унесці карэктывы</string>\n    <string name=\"image_for_histogram\">Гэта выява будзе выкарыстоўвацца для стварэння гістаграм RGB і яркасці</string>\n    <string name=\"tesseract_options\">Параметры тэсеракта</string>\n    <string name=\"tesseract_options_sub\">Прымяніць некаторыя ўваходныя зменныя для рухавіка tesseract</string>\n    <string name=\"custom_options\">Карыстальніцкія параметры</string>\n    <string name=\"custom_params_info\">Варыянты трэба ўводзіць па наступным шаблоне: \\\"--{назва_опцыі} {значэнне}\\\"</string>\n    <string name=\"auto_crop\">Аўтаматычнае абрэзка</string>\n    <string name=\"free_corners\">Свабодныя куткі</string>\n    <string name=\"free_corners_sub\">Абрэзаць малюнак па шматкутніку, гэта таксама карэктуе ракурс</string>\n    <string name=\"coerce_points_to_image_bounds\">Coerce паказвае на межы выявы</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Ачкі не будуць абмежаваныя межамі выявы, гэта карысна для больш дакладнай карэкцыі перспектывы</string>\n    <string name=\"mask\">Маска</string>\n    <string name=\"spot_heal_sub\">Запаўненне з улікам змесціва пад намаляваным шляхам</string>\n    <string name=\"spot_heal\">Вылечыць пляму</string>\n    <string name=\"use_circle_kernel\">Выкарыстоўвайце Circle Kernel</string>\n    <string name=\"opening\">Адкрыццё</string>\n    <string name=\"closing\">Закрыццё</string>\n    <string name=\"morphological_gradient\">Марфалагічны градыент</string>\n    <string name=\"top_hat\">Цыліндр</string>\n    <string name=\"black_hat\">Чорны Капялюш</string>\n    <string name=\"tone_curves\">Крывыя тоны</string>\n    <string name=\"reset_curves\">Скінуць крывыя</string>\n    <string name=\"reset_curves_sub\">Крывыя будуць адкачаны да значэння па змаўчанні</string>\n    <string name=\"line_style\">Стыль лініі</string>\n    <string name=\"gap_size\">Памер зазору</string>\n    <string name=\"dashed\">Пункцірная</string>\n    <string name=\"dot_dashed\">Пункцірная кропка</string>\n    <string name=\"stamped\">Штампаваны</string>\n    <string name=\"zigzag\">Зігзаг</string>\n    <string name=\"dashed_sub\">Малюе пункцірную лінію ўздоўж намаляванага шляху з зададзеным памерам прабелу</string>\n    <string name=\"dot_dashed_sub\">Малюе кропкавую і пункцірную лініі ўздоўж зададзенага шляху</string>\n    <string name=\"defaultt_sub\">Проста прамыя лініі па змаўчанні</string>\n    <string name=\"stamped_sub\">Малюе выбраныя фігуры ўздоўж шляху з зададзеным інтэрвалам</string>\n    <string name=\"zigzag_sub\">Малюе па сцяжынцы хвалісты зігзаг</string>\n    <string name=\"zigzag_ratio\">Зігзагападобныя суадносіны</string>\n    <string name=\"create_shortcut\">Стварыць ярлык</string>\n    <string name=\"create_shortcut_title\">Выберыце інструмент для замацавання</string>\n    <string name=\"create_shortcut_subtitle\">Інструмент будзе дададзены на галоўны экран праграмы запуску ў якасці цэтліка, выкарыстоўвайце яго ў спалучэнні з наладай \\\"Прапусціць выбар файлаў\\\", каб дасягнуць неабходных паводзін</string>\n    <string name=\"dont_stack_frames\">Не складайце кадры</string>\n    <string name=\"dont_stack_frames_sub\">Дазваляе ўтылізаваць папярэднія кадры, каб яны не накладваліся адзін на аднаго</string>\n    <string name=\"crossfade\">Перакрыжаваны плынь</string>\n    <string name=\"crossfade_sub\">Кадры будуць пераходзіць адзін у аднаго</string>\n    <string name=\"crossfade_count\">Колькасць кадраў перакрыжаванага плыні</string>\n    <string name=\"threshold_one\">Парог адзін</string>\n    <string name=\"threshold_two\">Парог другі</string>\n    <string name=\"canny\">Кані</string>\n    <string name=\"mirror_101\">Люстэрка 101</string>\n    <string name=\"enhanced_zoom_blur\">Палепшанае размыццё зуму</string>\n    <string name=\"laplacian_simple\">Лапласа просты</string>\n    <string name=\"sobel_simple\">Собель Просты</string>\n    <string name=\"helper_grid\">Дапаможная сетка</string>\n    <string name=\"helper_grid_sub\">Паказвае апорную сетку над вобласцю малявання, каб дапамагчы з дакладнымі маніпуляцыямі</string>\n    <string name=\"grid_color\">Колер сеткі</string>\n    <string name=\"cell_width\">Шырыня клеткі</string>\n    <string name=\"cell_height\">Вышыня клеткі</string>\n    <string name=\"compact_selectors\">Кампактныя селектары</string>\n    <string name=\"compact_selectors_sub\">Некаторыя элементы кіравання выбарам будуць выкарыстоўваць кампактны макет, каб займаць менш месца</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Дайце камере дазвол у наладах, каб зрабіць відарыс</string>\n    <string name=\"layout\">Макет</string>\n    <string name=\"main_screen_title\">Назва галоўнага экрана</string>\n    <string name=\"constant_rate_factor\">Каэфіцыент пастаяннай хуткасці (CRF)</string>\n    <string name=\"crf_sub\">Значэнне %1$s азначае павольнае сцісканне, што прыводзіць да адносна невялікага памеру файла. %2$s азначае больш хуткае сцісканне, што прыводзіць да вялікага файла.</string>\n    <string name=\"lut_library\">Луцкая бібліятэка</string>\n    <string name=\"lut_library_sub\">Спампуйце калекцыю LUT, якую вы можаце прымяніць пасля загрузкі</string>\n    <string name=\"lut_library_update_sub\">Абнавіць калекцыю LUT (толькі новыя будуць пастаўлены ў чаргу), якую можна прымяніць пасля спампоўкі</string>\n    <string name=\"filter_preview_image_sub\">Змяніць папярэдні прагляд выявы па змаўчанні для фільтраў</string>\n    <string name=\"filter_preview_image\">Папярэдні прагляд выявы</string>\n    <string name=\"hide\">Схаваць</string>\n    <string name=\"show\">Паказаць</string>\n    <string name=\"slider_type\">Тып паўзунка</string>\n    <string name=\"fancy\">Вычварны</string>\n    <string name=\"material_2\">Матэрыял 2</string>\n    <string name=\"fancy_sub\">Прыгожы слайдэр. Гэта параметр па змаўчанні</string>\n    <string name=\"material_2_sub\">Слайдэр Material 2</string>\n    <string name=\"material_you_slider_sub\">Паўзунок A Material You</string>\n    <string name=\"apply\">Ужыць</string>\n    <string name=\"center_align_dialog_buttons\">Цэнтральныя кнопкі дыялогу</string>\n    <string name=\"center_align_dialog_buttons_sub\">Кнопкі дыялогавых вокнаў будуць размешчаны ў цэнтры, а не злева, калі гэта магчыма</string>\n    <string name=\"open_source_licenses\">Ліцэнзіі з адкрытым зыходным кодам</string>\n    <string name=\"open_source_licenses_sub\">Праглядзіце ліцэнзіі на бібліятэкі з адкрытым зыходным кодам, якія выкарыстоўваюцца ў гэтым дадатку</string>\n    <string name=\"area\">Плошча</string>\n    <string name=\"area_sub\">Паўторная выбарка з выкарыстаннем адносіны плошчы пікселяў. Гэта можа быць пераважным метадам для дэцымацыі выявы, паколькі ён дае вынікі без муара. Але калі выява павялічана, гэта падобна на метад \\\"Бліжэйшы\\\".</string>\n    <string name=\"enable_tonemapping\">Уключыць Tonemapping</string>\n    <string name=\"enter_percent\">Увядзіце %</string>\n    <string name=\"unknown_host\">Немагчыма атрымаць доступ да сайта, паспрабуйце выкарыстоўваць VPN або праверце, ці правільны URL</string>\n    <string name=\"markup_layers\">Пласты разметкі</string>\n    <string name=\"markup_layers_sub\">Рэжым слаёў з магчымасцю свабоднага размяшчэння малюнкаў, тэксту і іншага</string>\n    <string name=\"edit_layer\">Рэдагаваць пласт</string>\n    <string name=\"layers_on_image\">Пласты на малюнку</string>\n    <string name=\"layers_on_image_sub\">Выкарыстоўвайце малюнак у якасці фону і дадавайце па-над ім розныя пласты</string>\n    <string name=\"layers_on_background\">Пласты на фоне</string>\n    <string name=\"layers_on_background_sub\">Тое самае, што і першы варыянт, але з колерам замест малюнка</string>\n    <string name=\"beta\">Бэта-версія</string>\n    <string name=\"fast_settings_side\">Бок хуткіх налад</string>\n    <string name=\"fast_settings_side_sub\">Дадайце плаваючую паласу на абраным баку падчас рэдагавання малюнкаў, якая адкрые хуткія налады пры націску</string>\n    <string name=\"clear_selection\">Ачысціць выбар</string>\n    <string name=\"settings_group_visibility_hidden\">Група налад \\\"%1$s\\\" будзе згорнута па змаўчанні</string>\n    <string name=\"settings_group_visibility_visible\">Група налад \\\"%1$s\\\" будзе пашырана па змаўчанні</string>\n    <string name=\"base_64_tools\">Інструменты Base64</string>\n    <string name=\"base_64_tools_sub\">Дэкадзіраваць радок Base64 у відарыс або закадзіраваць відарыс у фармат Base64</string>\n    <string name=\"base_64\">База64</string>\n    <string name=\"not_a_valid_base_64\">Уведзенае значэнне не з\\'яўляецца сапраўдным радком Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">Немагчыма скапіяваць пусты або несапраўдны радок Base64</string>\n    <string name=\"paste_base_64\">Уставіць Base64</string>\n    <string name=\"copy_base_64\">Скапіруйце Base64</string>\n    <string name=\"base_64_tips\">Загрузіце малюнак, каб скапіяваць або захаваць радок Base64. Калі ў вас ёсць сам радок, вы можаце ўставіць яго вышэй, каб атрымаць малюнак</string>\n    <string name=\"save_base_64\">Захаваць Base64</string>\n    <string name=\"share_base_64\">Падзяліцеся Base64</string>\n    <string name=\"options\">Параметры</string>\n    <string name=\"actions\">Дзеянні</string>\n    <string name=\"import_base_64\">Імпарт Base64</string>\n    <string name=\"base_64_actions\">Дзеянні Base64</string>\n    <string name=\"add_outline\">Дадаць контур</string>\n    <string name=\"add_outline_sub\">Дадайце контур вакол тэксту вызначаным колерам і шырынёй</string>\n    <string name=\"outline_color\">Колер контуру</string>\n    <string name=\"outline_size\">Памер контуру</string>\n    <string name=\"rotation\">Кручэнне</string>\n    <string name=\"checksum_as_filename\">Кантрольная сума як імя файла</string>\n    <string name=\"checksum_as_filename_sub\">Выхадныя выявы будуць мець назву, якая адпавядае іх кантрольнай суме дадзеных</string>\n    <string name=\"free_software_partner\">Бясплатнае праграмнае забеспячэнне (партнёр)</string>\n    <string name=\"free_software_partner_sub\">Больш карыснага праграмнага забеспячэння ў партнёрскім канале прыкладанняў Android</string>\n    <string name=\"algorithms\">Алгарытм</string>\n    <string name=\"checksum_tools\">Інструменты кантрольнай сумы</string>\n    <string name=\"checksum_tools_sub\">Параўноўвайце кантрольныя сумы, вылічвайце хэшы або стварайце шаснаццатковыя радкі з файлаў, выкарыстоўваючы розныя алгарытмы хэшавання</string>\n    <string name=\"calculate\">Вылічыць</string>\n    <string name=\"text_hash\">Хэш тэксту</string>\n    <string name=\"checksum\">Кантрольная сума</string>\n    <string name=\"pick_file_to_checksum\">Выберыце файл, каб вылічыць яго кантрольную суму на аснове абранага алгарытму</string>\n    <string name=\"enter_text_to_checksum\">Увядзіце тэкст для разліку яго кантрольнай сумы на аснове абранага алгарытму</string>\n    <string name=\"source_checksum\">Зыходная кантрольная сума</string>\n    <string name=\"checksum_to_compare\">Кантрольная сума для параўнання</string>\n    <string name=\"match\">Матч!</string>\n    <string name=\"difference\">Розніца</string>\n    <string name=\"match_sub\">Кантрольныя сумы роўныя, гэта можа быць бяспечна</string>\n    <string name=\"difference_sub\">Кантрольныя сумы не роўныя, файл можа быць небяспечным!</string>\n    <string name=\"mesh_gradients\">Градыенты сеткі</string>\n    <string name=\"collection_mesh_gradients_sub\">Паглядзіце онлайн-калекцыю Mesh Gradients</string>\n    <string name=\"wrong_font\">Можна імпартаваць толькі шрыфты TTF і OTF</string>\n    <string name=\"import_font\">Імпартаваць шрыфт (TTF/OTF)</string>\n    <string name=\"export_fonts\">Экспарт шрыфтоў</string>\n    <string name=\"imported_fonts\">Імпартаваныя шрыфты</string>\n    <string name=\"error_while_saving\">Памылка падчас спробы захавання, паспрабуйце змяніць тэчку вываду</string>\n    <string name=\"filename_is_not_set\">Імя файла не зададзена</string>\n    <string name=\"none\">Няма</string>\n    <string name=\"custom_pages\">Карыстальніцкія старонкі</string>\n    <string name=\"pages_selection\">Выбар старонак</string>\n    <string name=\"tool_exit_confirmation\">Пацверджанне выхаду з інструмента</string>\n    <string name=\"tool_exit_confirmation_sub\">Калі ў вас ёсць незахаваныя змены падчас выкарыстання пэўных інструментаў і вы спрабуеце закрыць яго, то будзе паказана дыялогавае акно пацверджання</string>\n    <string name=\"edit_exif_screen\">Рэдагаваць EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Змяніць метаданыя аднаго малюнка без паўторнага сціску</string>\n    <string name=\"edit_exif_tag\">Націсніце, каб змяніць даступныя тэгі</string>\n    <string name=\"change_sticker\">Змяніць стыкер</string>\n    <string name=\"fit_width\">Адпавядаць шырыні</string>\n    <string name=\"fit_height\">Адпавядаць вышыні</string>\n    <string name=\"batch_compare\">Параўнанне партый</string>\n    <string name=\"pick_files_to_checksum\">Выберыце файл/файлы для разліку яго кантрольнай сумы на аснове абранага алгарытму</string>\n    <string name=\"pick_files\">Выберыце файлы</string>\n    <string name=\"pick_directory\">Выберыце каталог</string>\n    <string name=\"head_length_scale\">Шкала даўжыні галавы</string>\n    <string name=\"stamp\">Марка</string>\n    <string name=\"timestamp\">Метка часу</string>\n    <string name=\"format_pattern\">Шаблон фармату</string>\n    <string name=\"padding\">Падкладка</string>\n    <string name=\"image_cutting\">Нарэзка малюнкаў</string>\n    <string name=\"image_cutting_sub\">Выражыце частку малюнка і аб\\'яднайце левыя (можна наадварот) вертыкальнымі або гарызантальнымі лініямі</string>\n    <string name=\"vertical_pivot_line\">Вертыкальная разводная лінія</string>\n    <string name=\"horizontal_pivot_line\">Гарызантальная апорная лінія</string>\n    <string name=\"inverse_selection\">Адваротны выбар</string>\n    <string name=\"inverse_vertical_selection_sub\">Частка вертыкальнага разрэзу будзе пакінута, замест аб\\'яднання частак вакол вобласці разрэзу</string>\n    <string name=\"inverse_horizontal_selection_sub\">Гарызантальная выразаная частка будзе пакінута замест аб\\'яднання частак вакол выразанай вобласці</string>\n    <string name=\"collection_mesh_gradients\">Калекцыя сеткаватых градыентаў</string>\n    <string name=\"mesh_gradients_sub\">Стварыце градыент сеткі з індывідуальнай колькасцю вузлоў і дазволам</string>\n    <string name=\"gradient_maker_type_image_mesh\">Градыентнае накладанне сеткі</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Складзіце сеткаваты градыент верхняй частцы дадзеных відарысаў</string>\n    <string name=\"points_customization\">Настройка балаў</string>\n    <string name=\"grid_size\">Памер сеткі</string>\n    <string name=\"resolution_x\">Рэзалюцыя X</string>\n    <string name=\"resolution_y\">Рэзалюцыя Ю</string>\n    <string name=\"resolution\">дазвол</string>\n    <string name=\"pixel_by_pixel\">Піксель за пікселем</string>\n    <string name=\"highlight_color\">Колер вылучэння</string>\n    <string name=\"pixel_comparison_type\">Тып параўнання пікселяў</string>\n    <string name=\"scan_barcode\">Сканаваць штрых-код</string>\n    <string name=\"height_ratio\">Каэфіцыент вышыні</string>\n    <string name=\"barcode_type\">Тып штрых-кода</string>\n    <string name=\"enforce_bw\">Прымяніць Ч/Б</string>\n    <string name=\"enforce_bw_sub\">Відарыс штрых-кода будзе цалкам чорна-белым і не будзе афарбаваны тэмай праграмы</string>\n    <string name=\"barcodes_sub\">Адсканіруйце любы штрых-код (QR, EAN, AZTEC, …) і атрымайце яго змест або ўстаўце свой тэкст, каб стварыць новы</string>\n    <string name=\"no_barcode_found\">Штрых-код не знойдзены</string>\n    <string name=\"generated_barcode_will_be_here\">Згенераваны штрых-код будзе тут</string>\n    <string name=\"audio_cover_extractor\">Аўдыё вокладкі</string>\n    <string name=\"audio_cover_extractor_sub\">Выманне малюнкаў вокладкі альбома з аўдыяфайлаў, падтрымліваюцца найбольш распаўсюджаныя фарматы</string>\n    <string name=\"pick_audio_to_start\">Выберыце аўдыя для пачатку</string>\n    <string name=\"pick_audio\">Выберыце Аўдыё</string>\n    <string name=\"no_covers_found\">Вокладкі не знойдзены</string>\n    <string name=\"send_logs\">Адправіць часопісы</string>\n    <string name=\"send_logs_sub\">Націсніце, каб падзяліцца файлам журналаў праграмы, гэта можа дапамагчы мне выявіць праблему і выправіць праблемы</string>\n    <string name=\"crash_title\">На жаль… Нешта пайшло не так</string>\n    <string name=\"crash_subtitle\">Вы можаце звязацца са мной, выкарыстоўваючы варыянты ніжэй, і я паспрабую знайсці рашэнне.\\n(Не забудзьцеся далучыць журналы)</string>\n    <string name=\"ocr_write_to_file\">Запіс у файл</string>\n    <string name=\"ocr_write_to_file_sub\">Вылучыце тэкст з пакета малюнкаў і захавайце яго ў адным тэкставым файле</string>\n    <string name=\"ocr_write_to_metadata\">Запіс у метададзеныя</string>\n    <string name=\"ocr_write_to_metadata_sub\">Вылучыце тэкст з кожнай выявы і змесціце яго ў інфармацыю EXIF ​​адпаведных фатаграфій</string>\n    <string name=\"invisible_mode\">Нябачны рэжым</string>\n    <string name=\"invisible_mode_sub\">Выкарыстоўвайце стэганаграфію, каб ствараць нябачныя вадзяныя знакі ўнутры байтаў вашых малюнкаў</string>\n    <string name=\"use_lsb\">Выкарыстоўвайце LSB</string>\n    <string name=\"use_lsb_sub\">Будзе выкарыстоўвацца метад стэганаграфіі LSB (менш важны біт), у адваротным выпадку FD (частотны дамен)</string>\n    <string name=\"auto_remove_red_eyes\">Аўтаматычнае выдаленне чырвоных вачэй</string>\n    <string name=\"password\">Пароль</string>\n    <string name=\"unlock\">Разблакіраваць</string>\n    <string name=\"pdf_is_protected\">PDF абаронены</string>\n    <string name=\"operation_almost_complete\">Аперацыя амаль завершана. Каб скасаваць зараз, спатрэбіцца перазапусціць яго</string>\n    <string name=\"sort_by_date_modified\">Дата змены</string>\n    <string name=\"sort_by_date_modified_reversed\">Дата змены (адменена)</string>\n    <string name=\"sort_by_size\">Памер</string>\n    <string name=\"sort_by_size_reversed\">Памер (перавернуты)</string>\n    <string name=\"sort_by_mime_type\">Тып MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Тып MIME (перавернуты)</string>\n    <string name=\"sort_by_extension\">Пашырэнне</string>\n    <string name=\"sort_by_extension_reversed\">Пашырэнне (перавернута)</string>\n    <string name=\"sort_by_date_added\">Дата дадання</string>\n    <string name=\"sort_by_date_added_reversed\">Дата дадання (зваротная)</string>\n    <string name=\"left_to_right\">Злева направа</string>\n    <string name=\"right_to_left\">Справа налева</string>\n    <string name=\"top_to_bottom\">Зверху ўніз</string>\n    <string name=\"bottom_to_top\">Знізу ўверх</string>\n    <string name=\"liquid_glass\">Вадкае шкло</string>\n    <string name=\"liquid_glass_sub\">Пераключальнік, заснаваны на нядаўна абвешчанай IOS 26 і яго сістэме дызайну з вадкага шкла</string>\n    <string name=\"pick_image_or_base64\">Выберыце малюнак або ўстаўце/імпартуйце даныя Base64 ніжэй</string>\n    <string name=\"type_image_link\">Каб пачаць, увядзіце спасылку на выяву</string>\n    <string name=\"paste_link\">Уставіць спасылку</string>\n    <string name=\"kaleidoscope\">Калейдаскоп</string>\n    <string name=\"secondary_angle\">Другасны вугал</string>\n    <string name=\"sides\">Бакі</string>\n    <string name=\"channel_mix\">Мікс канала</string>\n    <string name=\"blue_green\">Сіне-зялёны</string>\n    <string name=\"red_blue\">Чырвоны сіні</string>\n    <string name=\"green_red\">Зялёны чырвоны</string>\n    <string name=\"into_red\">У чырвоны</string>\n    <string name=\"into_green\">У зялёны</string>\n    <string name=\"into_blue\">У блакіт</string>\n    <string name=\"cyan\">Блакітны</string>\n    <string name=\"magenta\">Пурпурны</string>\n    <string name=\"yellow\">Жоўты</string>\n    <string name=\"color_halftone\">Каляровы паўтон</string>\n    <string name=\"contour\">Контур</string>\n    <string name=\"levels\">Узроўні</string>\n    <string name=\"offset\">Зрушэнне</string>\n    <string name=\"voronoi_crystallize\">Вараной Крышталізуйся</string>\n    <string name=\"shape\">Форма</string>\n    <string name=\"stretch\">Расцяжка</string>\n    <string name=\"randomness\">Выпадковасць</string>\n    <string name=\"despeckle\">Ачысціць плямы</string>\n    <string name=\"diffuse\">Дыфузны</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Другі радыус</string>\n    <string name=\"equalize\">Зраўнаваць</string>\n    <string name=\"glow\">Свяціцца</string>\n    <string name=\"whirl_and_pinch\">Круціцца і шчыпаць</string>\n    <string name=\"pointillize\">Пуантылізаваць</string>\n    <string name=\"border_color\">Колер мяжы</string>\n    <string name=\"polar_coordinates\">Палярныя каардынаты</string>\n    <string name=\"rect_to_polar\">Прамая да палярнай</string>\n    <string name=\"polar_to_rect\">Палярны ў прамы</string>\n    <string name=\"invert_in_circle\">Перавярнуць у круг</string>\n    <string name=\"reduce_noise\">Паменшыць шум</string>\n    <string name=\"simple_solarize\">Простая салярызацыя</string>\n    <string name=\"weave\">Ткаць</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">Шырыня X</string>\n    <string name=\"y_wdth\">Шырыня Y</string>\n    <string name=\"twirl\">Круціцца</string>\n    <string name=\"rubber_stmp\">Гумовы штамп</string>\n    <string name=\"smear\">Мазок</string>\n    <string name=\"density\">Шчыльнасць</string>\n    <string name=\"mix\">Змяшаць</string>\n    <string name=\"sphere_lensh_distortion\">Скажэнне сферычнай лінзы</string>\n    <string name=\"refraction_index\">Паказчык праламлення</string>\n    <string name=\"arc\">Арк</string>\n    <string name=\"spread_angle\">Кут разгортвання</string>\n    <string name=\"sparkle\">Бліск</string>\n    <string name=\"rays\">Прамяні</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Градыент</string>\n    <string name=\"moire\">Мэры</string>\n    <string name=\"autumn\">Восень</string>\n    <string name=\"bone\">Костка</string>\n    <string name=\"jet\">Рэактыўны</string>\n    <string name=\"winter\">зіма</string>\n    <string name=\"ocean\">Акіян</string>\n    <string name=\"summer\">лета</string>\n    <string name=\"spring\">Вясна</string>\n    <string name=\"cool_variant\">Класны варыянт</string>\n    <string name=\"hsv\">ВПГ</string>\n    <string name=\"pink\">Ружовы</string>\n    <string name=\"hot\">Горача</string>\n    <string name=\"parula\">Слова</string>\n    <string name=\"magma\">Магма</string>\n    <string name=\"inferno\">Пекла</string>\n    <string name=\"plasma\">плазма</string>\n    <string name=\"viridis\">Вірыдзіс</string>\n    <string name=\"cividis\">Грамадзяне</string>\n    <string name=\"twilight\">Змрок</string>\n    <string name=\"twilight_shifted\">Змрок зрушаны</string>\n    <string name=\"auto_perspective\">Аўтаперспектыва</string>\n    <string name=\"deskew\">Выправіць перакос</string>\n    <string name=\"allow_crop\">Дазволіць абрэзку</string>\n    <string name=\"crop_or_perspective\">Абрэзка або перспектыва</string>\n    <string name=\"absolute\">Абсалютны</string>\n    <string name=\"turbo\">Турба</string>\n    <string name=\"deep_green\">Цёмна-зялёны</string>\n    <string name=\"lens_correction\">Карэкцыя аб\\'ектыва</string>\n    <string name=\"target_lens_profile\">Файл профілю мэтавай лінзы ў фармаце JSON</string>\n    <string name=\"download_ready_lens_profiles\">Спампаваць гатовыя профілі лінзаў</string>\n    <string name=\"part_percents\">Частка працэнтаў</string>\n    <string name=\"export_as_json\">Экспарт у фармаце JSON</string>\n    <string name=\"export_as_json_sub\">Скапіруйце радок з дадзенымі палітры ў выглядзе прадстаўлення json</string>\n    <string name=\"seam_carving\">Разьба швоў</string>\n    <string name=\"home_screen\">Галоўны экран</string>\n    <string name=\"lock_screen\">Экран блакіроўкі</string>\n    <string name=\"built_in\">Убудаваны</string>\n    <string name=\"wallpapers_export\">Экспарт шпалер</string>\n    <string name=\"refresh\">Абнавіць</string>\n    <string name=\"wallpapers_export_sub\">Атрымайце бягучыя шпалеры Home, Lock і Built-in</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Дазволіць доступ да ўсіх файлаў, гэта неабходна для атрымання шпалер</string>\n    <string name=\"allow_read_media_images_for_wp\">Дазволу на кіраванне знешнім сховішчам недастаткова, вам трэба дазволіць доступ да вашых малюнкаў, не забудзьцеся выбраць \\\"Дазволіць усё\\\"</string>\n    <string name=\"add_preset_to_filename\">Дадаць наладку да імя файла</string>\n    <string name=\"add_preset_to_filename_sub\">Дадае суфікс з выбранай перадусталёўкай да назвы файла выявы</string>\n    <string name=\"add_image_scale_mode_to_filename\">Дадайце рэжым маштабавання выявы ў імя файла</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Дадае суфікс з абраным рэжымам маштабу выявы да назвы файла выявы</string>\n    <string name=\"ascii_art\">Ascii арт</string>\n    <string name=\"ascii_art_sub\">Пераўтварыце малюнак у тэкст ASCII, які будзе выглядаць як малюнак</string>\n    <string name=\"params\">Параметры</string>\n    <string name=\"invert_colors_ascii_sub\">Прымяняе адмоўны фільтр да выявы для лепшага выніку ў некаторых выпадках</string>\n    <string name=\"processing_screenshot\">Апрацоўка скрыншота</string>\n    <string name=\"screenshot_not_captured_try_again\">Здымак экрана не зроблены, паўтарыце спробу</string>\n    <string name=\"skipped_saving\">Захаванне прапушчана</string>\n    <string name=\"skipped_saving_multiple\">%1$s файлаў прапушчана</string>\n    <string name=\"allow_skip_if_larger\">Дазволіць прапусціць, калі больш</string>\n    <string name=\"allow_skip_if_larger_sub\">Некаторым інструментам будзе дазволена прапускаць захаванне малюнкаў, калі выніковы памер файла будзе большы за арыгінальны</string>\n    <string name=\"qr_type_calendar_event\">Каляндар падзей</string>\n    <string name=\"qr_type_contact_info\">Кантакт</string>\n    <string name=\"qr_type_email\">Электронная пошта</string>\n    <string name=\"qr_type_geo_point\">Размяшчэнне</string>\n    <string name=\"qr_type_phone\">Тэлефон</string>\n    <string name=\"qr_type_plain\">Тэкст</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Адкрытая сетка</string>\n    <string name=\"not_specified\">Н/Д</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Тэлефон</string>\n    <string name=\"message\">паведамленне</string>\n    <string name=\"address\">Адрас</string>\n    <string name=\"subject\">Тэма</string>\n    <string name=\"body\">Цела</string>\n    <string name=\"name\">Імя</string>\n    <string name=\"organization\">Арганізацыя</string>\n    <string name=\"title\">Назва</string>\n    <string name=\"phones\">Тэлефоны</string>\n    <string name=\"emails\">Электронныя лісты</string>\n    <string name=\"urls\">URL-адрасы</string>\n    <string name=\"addresses\">Адрасы</string>\n    <string name=\"summary\">Рэзюмэ</string>\n    <string name=\"description\">Апісанне</string>\n    <string name=\"location\">Размяшчэнне</string>\n    <string name=\"organizer\">Арганізатар</string>\n    <string name=\"start_date\">Дата пачатку</string>\n    <string name=\"end_date\">Дата заканчэння</string>\n    <string name=\"status\">Статус</string>\n    <string name=\"latitude\">Шырата</string>\n    <string name=\"longitude\">Даўгата</string>\n    <string name=\"create_barcode\">Стварыць штрых-код</string>\n    <string name=\"edit_barcode\">Рэдагаваць штрых-код</string>\n    <string name=\"wifi_configuration\">Канфігурацыя Wi-Fi</string>\n    <string name=\"security\">Бяспека</string>\n    <string name=\"pick_contact\">Выберыце кантакт</string>\n    <string name=\"grant_contact_permission\">Дайце кантактам дазвол у наладах на аўтазапаўненне з дапамогай выбранага кантакту</string>\n    <string name=\"contact_info\">Кантактная інфармацыя</string>\n    <string name=\"first_name\">імя</string>\n    <string name=\"middle_name\">Імя па бацьку</string>\n    <string name=\"last_name\">Прозвішча</string>\n    <string name=\"pronunciation\">Вымаўленне</string>\n    <string name=\"add_phone\">Дадаць тэлефон</string>\n    <string name=\"add_email\">Дадаць адрас электроннай пошты</string>\n    <string name=\"add_address\">Дадайце адрас</string>\n    <string name=\"website\">Вэб-сайт</string>\n    <string name=\"add_website\">Дадаць сайт</string>\n    <string name=\"formatted_name\">Адфарматаванае імя</string>\n    <string name=\"qr_code_top_image\">Гэта выява будзе выкарыстоўвацца для размяшчэння над штрых-кодам</string>\n    <string name=\"code_customization\">Налада кода</string>\n    <string name=\"qr_logo_image\">Гэта выява будзе выкарыстоўвацца ў якасці лагатыпа ў цэнтры QR-кода</string>\n    <string name=\"logo\">Лагатып</string>\n    <string name=\"logo_padding\">Абіўка лагатыпа</string>\n    <string name=\"logo_size\">Памер лагатыпа</string>\n    <string name=\"logo_corners\">Куты лагатыпа</string>\n    <string name=\"fourth_eye\">Чацвёртае вока</string>\n    <string name=\"fourth_eye_description\">Дадае сіметрыю вачэй у qr-код, дадаючы чацвёртае вока ў ніжнім кантавым куце</string>\n    <string name=\"pixel_shape\">Форма пікселя</string>\n    <string name=\"frame_shape\">Форма каркаса</string>\n    <string name=\"ball_shape\">Форма шара</string>\n    <string name=\"error_correction_level\">Узровень выпраўлення памылак</string>\n    <string name=\"dark_color\">Цёмны колер</string>\n    <string name=\"light_color\">Светлы колер</string>\n    <string name=\"hyper_os\">Гіпер АС</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS, як стыль</string>\n    <string name=\"mask_pattern\">Выкрайка маскі</string>\n    <string name=\"code_may_be_not_scannable\">Гэты код можа быць не сканіраваны, змяніце параметры выгляду, каб зрабіць яго чытальным на ўсіх прыладах</string>\n    <string name=\"not_scannable\">Не сканіруецца</string>\n    <string name=\"launcher_mode_sub\">Інструменты будуць выглядаць як праграма запуску праграм на галоўным экране, каб быць больш кампактнымі</string>\n    <string name=\"launcher_mode\">Рэжым запуску</string>\n    <string name=\"flood_fill_sub\">Запаўняе вобласць абраным пэндзлем і стылем</string>\n    <string name=\"flood_fill\">Заліванне паводкай</string>\n    <string name=\"spray\">Спрэй</string>\n    <string name=\"spray_sub\">Малюе шлях у стылі графіці</string>\n    <string name=\"square_particles\">Квадратныя часціцы</string>\n    <string name=\"square_particles_sub\">Часціцы спрэю будуць мець квадратную форму, а не кругі</string>\n    <string name=\"palette_tools\">Інструменты палітры</string>\n    <string name=\"palette_tools_sub\">Стварыце асноўны/матэрыял, які вы палітруеце, з выявы або імпартуйце/экспартуйце ў розныя фарматы палітры</string>\n    <string name=\"edit_palette\">Рэдагаваць палітру</string>\n    <string name=\"edit_palette_sub\">Экспарт/імпарт палітры ў розных фарматах</string>\n    <string name=\"color_name\">Назва колеру</string>\n    <string name=\"palette_name\">Імя палітры</string>\n    <string name=\"palette_format\">Фармат палітры</string>\n    <string name=\"export_palette_sub\">Экспарт згенераванай палітры ў розныя фарматы</string>\n    <string name=\"add_color_palette_sub\">Дадае новы колер да бягучай палітры</string>\n    <string name=\"palette_name_not_supported\">Фармат %1$s не падтрымлівае назву палітры</string>\n    <string name=\"wallpapers_export_not_avaialbe\">З-за палітыкі Крамы Play гэтая функцыя не можа быць уключана ў бягучую зборку. Каб атрымаць доступ да гэтай функцыі, загрузіце ImageToolbox з альтэрнатыўнай крыніцы. Вы можаце знайсці даступныя зборкі на GitHub ніжэй.</string>\n    <string name=\"open_github_page\">Адкрыць старонку Github</string>\n    <string name=\"overwrite_files_sub_short\">Арыгінальны файл будзе заменены новым замест захавання ў выбранай папцы</string>\n    <string name=\"hidden_watermark_text_detected\">Выяўлены схаваны тэкст вадзянога знака</string>\n    <string name=\"hidden_watermark_image_detected\">Выяўлена схаваная выява вадзянога знака</string>\n    <string name=\"this_image_was_hidden\">Гэта выява была схаваная</string>\n    <string name=\"generative_inpaint\">Генератыўны жывапіс</string>\n    <string name=\"generative_inpaint_sub\">Дазваляе выдаляць аб\\'екты на малюнку з дапамогай мадэлі штучнага інтэлекту, не абапіраючыся на OpenCV. Каб выкарыстоўваць гэту функцыю, праграма загрузіць неабходную мадэль (~200 МБ) з GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Дазваляе выдаляць аб\\'екты на малюнку з дапамогай мадэлі штучнага інтэлекту, не абапіраючыся на OpenCV. Гэта можа быць працяглая аперацыя</string>\n    <string name=\"error_level_analysis\">Аналіз ўзроўню памылак</string>\n    <string name=\"luminance_gradient\">Градыент яркасці</string>\n    <string name=\"average_distance\">Сярэдняя адлегласць</string>\n    <string name=\"copy_move_detection\">Выяўленне перамяшчэння капіявання</string>\n    <string name=\"retain\">Захаваць</string>\n    <string name=\"coefficent\">Каэфіцыент</string>\n    <string name=\"clipboard_data_is_too_large\">Даныя буфера абмену занадта вялікія</string>\n    <string name=\"data_is_too_large_to_copy\">Дадзеныя занадта вялікія для капіравання</string>\n    <string name=\"simple_weave_pixelization\">Простая пікселізацыя Weave</string>\n    <string name=\"staggered_pixelization\">Паступовая пікселізацыя</string>\n    <string name=\"cross_pixelization\">Перакрыжаваная пікселізацыя</string>\n    <string name=\"micro_macro_pixelization\">Мікра Макра пікселізацыя</string>\n    <string name=\"orbital_pixelization\">Арбітальная пікселізацыя</string>\n    <string name=\"vortex_pixelization\">Віхравая пікселізацыя</string>\n    <string name=\"pulse_grid_pixelization\">Піксэлізацыя імпульснай сеткі</string>\n    <string name=\"nucleus_pixelization\">Пікселізацыю ядра</string>\n    <string name=\"radial_weave_pixelization\">Радыяльнае перапляценне пікселізацыі</string>\n    <string name=\"cannot_open_uri\">Немагчыма адкрыць uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Рэжым снегападу</string>\n    <string name=\"enabled\">Уключаны</string>\n    <string name=\"border_frame\">Бардзюрная рамка</string>\n    <string name=\"glitch_variant\">Варыянт глюка</string>\n    <string name=\"channel_shift\">Зрух канала</string>\n    <string name=\"max_offset\">Максімальнае зрушэнне</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Блок Глюк</string>\n    <string name=\"block_size\">Памер блока</string>\n    <string name=\"crt_curvature\">крывізна ЭПТ</string>\n    <string name=\"curvature\">Скрыўленне</string>\n    <string name=\"chroma\">каляровасць</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Макс Дроп</string>\n    <string name=\"ai_tools\">Інструменты штучнага інтэлекту</string>\n    <string name=\"ai_tools_sub\">Розныя інструменты для апрацоўкі відарысаў з дапамогай мадэляў штучнага інтэлекту, напрыклад, выдаленне артэфактаў або шумашумленне</string>\n    <string name=\"model_anime_undeint\">Сцісканне, няроўныя лініі</string>\n    <string name=\"model_broadcast\">Мультфільмы, сціск трансляцыі</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Агульная кампрэсія, агульны шум</string>\n    <string name=\"model_wb_denoise\">Бясколерны шум мультфільма</string>\n    <string name=\"model_span_anime_pretrain\">Хуткі, агульнае сцісканне, агульны шум, анімацыя/коміксы/анімэ</string>\n    <string name=\"model_book_scan\">Сканаванне кнігі</string>\n    <string name=\"model_overexposure\">Карэкцыя экспазіцыі</string>\n    <string name=\"model_fbcnn_color_fp16\">Найлепшыя пры агульным сціску, каляровыя выявы</string>\n    <string name=\"model_fbcnn_gray_fp16\">Лепш за ўсё пры агульным сціску, выявы ў адценнях шэрага</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Агульнае сцісканне, выявы ў адценнях шэрага мацней</string>\n    <string name=\"model_scunet_color_gan_fp16\">Агульны шум, каляровыя выявы</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Агульны шум, каляровыя малюнкі, лепшыя дэталі</string>\n    <string name=\"model_scunet_gray_15_fp16\">Агульны шум, выявы ў адценнях шэрага</string>\n    <string name=\"model_scunet_gray_25_fp16\">Агульны шум, малюнкі ў адценнях шэрага мацней</string>\n    <string name=\"model_scunet_gray_50_fp16\">Агульны шум, відарысы ў адценнях шэрага, самы моцны</string>\n    <string name=\"model_jpeg_destroyer\">Агульная кампрэсія</string>\n    <string name=\"model_jaywreck\">Агульная кампрэсія</string>\n    <string name=\"model_h264\">Тэкстурацыя, сціск h264</string>\n    <string name=\"model_vhs\">Кампрэсія VHS</string>\n    <string name=\"model_cinepak\">Нестандартнае сцісканне (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Сціск Bink, лепш па геаметрыі</string>\n    <string name=\"model_debink_v5\">Сціск Bink, мацней</string>\n    <string name=\"model_debink_v6\">Сціск Bink, мяккі, захоўвае дэталі</string>\n    <string name=\"model_antialias\">Ліквідацыю эфекту лесвіцы, згладжванне</string>\n    <string name=\"model_kdm_scans\">Адсканаваныя малюнкі/малюнкі, мяккае сцісканне, муар</string>\n    <string name=\"model_bandage\">Каляровая паласа</string>\n    <string name=\"model_halftone\">Павольна, выдаляючы паўтоны</string>\n    <string name=\"model_colorizer\">Агульны каларызатар для адценняў шэрага/ч.б. малюнкаў, для лепшых вынікаў выкарыстоўвайце DDColor</string>\n    <string name=\"model_deedge\">Выдаленне краю</string>\n    <string name=\"model_desharpen\">Выдаляе празмерную завострыванне</string>\n    <string name=\"model_dither\">Павольна, дрыготка</string>\n    <string name=\"model_gainres\">Згладжванне, агульныя артэфакты, CGI</string>\n    <string name=\"model_kdm003_scans\">Апрацоўка сканаў KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Лёгкая мадэль паляпшэння выявы</string>\n    <string name=\"model_bcgone_detailed_v2\">Выдаленне артэфактаў сціску</string>\n    <string name=\"model_bcgone_smooth\">Выдаленне артэфактаў сціску</string>\n    <string name=\"model_bandage_smooth\">Зняцце павязкі з гладкімі вынікамі</string>\n    <string name=\"model_bendel_halftone\">Апрацоўка паўтонавых малюнкаў</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Выдаленне шаблону дызерінга V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Выдаленне артэфактаў JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Паляпшэнне тэкстуры H.264</string>\n    <string name=\"model_vhs_sharpen\">VHS рэзкасць і паляпшэнне</string>\n    <string name=\"merging\">Зліццё</string>\n    <string name=\"chunk_size\">Памер кавалка</string>\n    <string name=\"overlap_size\">Памер перакрыцця</string>\n    <string name=\"note_chunk_info\">Выявы памерам больш за %1$s пікселяў будуць нарэзаны і апрацаваны на кавалкі. Перакрываючы іх змешвае, каб прадухіліць бачныя швы.</string>\n    <string name=\"large_chunk_warning\">Вялікія памеры могуць выклікаць нестабільнасць прылад нізкага ўзроўню</string>\n    <string name=\"select_one_to_start\">Выберыце адзін, каб пачаць</string>\n    <string name=\"delete_model_sub\">Вы хочаце выдаліць мадэль %1$s? Вам трэба будзе спампаваць яго зноў</string>\n    <string name=\"confirm\">Пацвердзіць</string>\n    <string name=\"models\">Мадэлі</string>\n    <string name=\"downloaded_models\">Спампаваныя мадэлі</string>\n    <string name=\"available_models\">Даступныя мадэлі</string>\n    <string name=\"preparing\">Рыхтуецца</string>\n    <string name=\"active_model\">Актыўная мадэль</string>\n    <string name=\"failed_to_open_session\">Не ўдалося адкрыць сеанс</string>\n    <string name=\"only_onnx_models\">Можна імпартаваць толькі мадэлі .onnx/.ort</string>\n    <string name=\"import_model\">Імпартная мадэль</string>\n    <string name=\"import_model_sub\">Імпартуйце карыстальніцкую мадэль onnx для далейшага выкарыстання, прымаюцца толькі мадэлі onnx/ort, падтрымлівае амаль усе варыянты, падобныя на esrgan</string>\n    <string name=\"imported_models\">Імпартныя мадэлі</string>\n    <string name=\"model_scunet_color_15_fp16\">Агульны шум, каляровыя выявы</string>\n    <string name=\"model_scunet_color_25_fp16\">Агульны шум, каляровыя малюнкі, мацней</string>\n    <string name=\"model_scunet_color_50_fp16\">Агульны шум, каляровыя выявы, наймацнейшыя</string>\n    <string name=\"model_artifacts_dithering_alsa\">Памяншае артэфакты размывання і каляровыя палосы, паляпшаючы плыўныя градыенты і плоскія каляровыя вобласці.</string>\n    <string name=\"model_nmkd_brighten_redux\">Павышае яркасць і кантраснасць выявы са збалансаванымі блікамі, захоўваючы натуральныя колеры.</string>\n    <string name=\"model_nmkd_brighten\">Асвятляе цёмныя выявы, захоўваючы дэталі і пазбягаючы пераэкспазіцыі.</string>\n    <string name=\"model_nmkd_detoon\">Выдаляе празмернае тоніраванне колеру і аднаўляе больш нейтральны і натуральны баланс колеру.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Прымяняе таніраванне шуму на аснове Пуасона з акцэнтам на захаванне дробных дэталяў і тэкстур.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Прымяняе мяккае таніраванне шуму Пуасона для больш гладкіх і менш агрэсіўных візуальных вынікаў.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Раўнамернае тоніраванне шуму, арыентаванае на захаванне дэталяў і выразнасць выявы.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Мяккае аднастайнае шумавое таніраванне для тонкай тэкстуры і гладкага выгляду.</string>\n    <string name=\"model_repainter\">Аднаўляе пашкоджаныя або няроўныя ўчасткі, перафарбоўваючы артэфакты і паляпшаючы кансістэнцыю выявы.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Лёгкая мадэль дэбандынгу, якая выдаляе каляровыя палосы з мінімальнымі выдаткамі.</string>\n    <string name=\"model_jpeg_0_20\">Аптымізуе выявы з вельмі высокімі артэфактамі сціску (якасць 0-20%) для павышэння выразнасці.</string>\n    <string name=\"model_jpeg_20_40\">Паляпшае выявы з высокімі артэфактамі сціску (якасць 20-40%), аднаўляючы дэталі і памяншаючы шум.</string>\n    <string name=\"model_jpeg_40_60\">Паляпшае выявы з умераным сцісканнем (якасць 40-60%), балансуючы рэзкасць і гладкасць.</string>\n    <string name=\"model_jpeg_60_80\">Удасканальвае выявы з лёгкім сцісканнем (якасць 60-80%) для паляпшэння тонкіх дэталяў і тэкстур.</string>\n    <string name=\"model_jpeg_80_100\">Нязначна паляпшае выявы амаль без страт (якасць 80-100%), захоўваючы натуральны выгляд і дэталі.</string>\n    <string name=\"model_spongecolor_lite\">Простая і хуткая размалёўка, мультфільмы, не ідэальна</string>\n    <string name=\"model_deblr\">Злёгку памяншае размытасць выявы, паляпшаючы рэзкасць без увядзення артэфактаў.</string>\n    <string name=\"processing_channel\">Працяглыя аперацыі</string>\n    <string name=\"processing_image\">Апрацоўка выявы</string>\n    <string name=\"processing\">Апрацоўка</string>\n    <string name=\"model_artifacts_jpg_0_20\">Выдаляе моцныя артэфакты сціску JPEG у малюнках вельмі нізкай якасці (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Памяншае моцныя артэфакты JPEG у моцна сціснутых выявах (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Ачышчае ўмераныя артэфакты JPEG, захоўваючы дэталі выявы (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Удасканальвае лёгкія артэфакты JPEG у малюнках даволі высокай якасці (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Тонка памяншае нязначныя артэфакты JPEG у выявах амаль без страт (80-100%).</string>\n    <string name=\"model_redetail_v2\">Паляпшае дробныя дэталі і тэкстуры, паляпшаючы адчувальную рэзкасць без моцных артэфактаў.</string>\n    <string name=\"processing_finished\">Апрацоўка скончана</string>\n    <string name=\"processing_failed\">Збой апрацоўкі</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Паляпшае тэкстуру скуры і дэталі, захоўваючы пры гэтым натуральны выгляд, аптымізаваны для хуткасці.</string>\n    <string name=\"model_sbdv_dejpeg\">Выдаляе артэфакты сціску JPEG і аднаўляе якасць выявы для сціснутых фатаграфій.</string>\n    <string name=\"model_iso_denoise_v1\">Памяншае шум ISO на фотаздымках, зробленых ва ўмовах нізкай асветленасці, захоўваючы дэталі.</string>\n    <string name=\"model_dejumbo\">Выпраўляе празмерна экспанаваныя або «гіганцкія» блікі і аднаўляе лепшы танальны баланс.</string>\n    <string name=\"model_ddcolor_tiny\">Лёгкая і хуткая мадэль афарбоўкі, якая дадае натуральныя колеры да малюнкаў у адценнях шэрага.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Знішчыць шум</string>\n    <string name=\"type_colorize\">Размаляваць</string>\n    <string name=\"type_artifacts\">Артэфакты</string>\n    <string name=\"type_enhance\">Палепшыць</string>\n    <string name=\"type_anime\">Анімэ</string>\n    <string name=\"type_scans\">Сканы</string>\n    <string name=\"type_upscale\">Высакакласны</string>\n    <string name=\"model_realesrgan_x4v3\">X4 Upscaler для агульных малюнкаў; малюсенькая мадэль, якая выкарыстоўвае менш GPU і часу, з умераным выдаленнем размытасці і шуму.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 Upscaler для агульных малюнкаў, захоўваючы тэкстуры і натуральныя дэталі.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 Upscaler для агульных малюнкаў з палепшанымі тэкстурамі і рэалістычнымі вынікамі.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 Upscaler аптымізаваны для малюнкаў анімэ; 6 блокаў RRDB для больш выразных ліній і дэталяў.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 Upscaler са стратамі MSE, дае больш плыўныя вынікі і зніжае колькасць дэфектаў для агульных малюнкаў.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler аптымізаваны для малюнкаў анімэ; Варыянт 4B32F з больш выразнымі дэталямі і плыўнымі лініямі.</string>\n    <string name=\"model_ultrasharp_v2_x4\">мадэль X4 UltraSharp V2 для агульных малюнкаў; падкрэслівае выразнасць і выразнасць.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; больш хуткі і меншы, захоўвае дэталі, выкарыстоўваючы менш памяці GPU.</string>\n    <string name=\"model_rmbg_1_4\">Лёгкая мадэль для хуткага выдалення фону. Збалансаваная прадукцыйнасць і дакладнасць. Працуе з партрэтамі, аб\\'ектамі і сцэнамі. Рэкамендуецца для большасці выпадкаў выкарыстання.</string>\n    <string name=\"type_removebg\">Выдаліць BG</string>\n    <string name=\"horizontal_border_thickness\">Таўшчыня гарызантальнай мяжы</string>\n    <string name=\"vertical_border_thickness\">Таўшчыня вертыкальнай мяжы</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s колер</item>\n        <item quantity=\"few\">%1$s колераў</item>\n        <item quantity=\"many\">%1$s колераў</item>\n        <item quantity=\"other\">%1$s колераў</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Бягучая мадэль не падтрымлівае разбіццё на кавалкі, выява будзе апрацоўвацца ў зыходных памерах, гэта можа выклікаць вялікае спажыванне памяці і праблемы з прыладамі нізкага ўзроўню</string>\n    <string name=\"chunking_disabled\">Раздзяленне на кавалкі адключана, відарыс будзе апрацоўвацца ў зыходных памерах, гэта можа выклікаць вялікае спажыванне памяці і праблемы з прыладамі нізкага класа, але можа даць лепшыя вынікі высновы</string>\n    <string name=\"chunking\">Чанкінг</string>\n    <string name=\"model_u2net\">Высокадакладная мадэль сегментацыі выявы для выдалення фону</string>\n    <string name=\"model_u2netp\">Палегчаная версія U2Net для больш хуткага выдалення фону з меншым выкарыстаннем памяці.</string>\n    <string name=\"model_ddcolor\">Поўная мадэль DDColor забяспечвае высакаякасную афарбоўку агульных малюнкаў з мінімальнымі артэфактамі. Лепшы выбар з усіх мадэляў афарбоўкі.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Навучаныя і прыватныя наборы мастацкіх дадзеных; стварае разнастайныя і мастацкія вынікі афарбоўвання з меншай колькасцю нерэальных каляровых артэфактаў.</string>\n    <string name=\"model_birefnet\">Лёгкая мадэль BiRefNet на аснове Swin Transformer для дакладнага выдалення фону.</string>\n    <string name=\"model_inspyrenet\">Высакаякаснае выдаленне фону з рэзкімі краямі і выдатным захаваннем дэталяў, асабліва на складаных аб\\'ектах і складаным фоне.</string>\n    <string name=\"model_isnet\">Мадэль выдалення фону, якая стварае дакладныя маскі з гладкімі краямі, прыдатныя для агульных аб\\'ектаў і ўмераным захаваннем дэталяў.</string>\n    <string name=\"model_already_downloaded\">Мадэль ужо спампавана</string>\n    <string name=\"model_successfully_imported\">Мадэль паспяхова імпартавана</string>\n    <string name=\"type\">Тып</string>\n    <string name=\"keyword\">Ключавое слова</string>\n    <string name=\"very_fast\">Вельмі хутка</string>\n    <string name=\"normal\">Нармальны</string>\n    <string name=\"slow\">павольна</string>\n    <string name=\"very_slow\">Вельмі павольна</string>\n    <string name=\"compute_percents\">Вылічыць працэнты</string>\n    <string name=\"minimum_value_is\">Мінімальнае значэнне %1$s</string>\n    <string name=\"warp_sub\">Скажайце малюнак, малюючы пальцамі</string>\n    <string name=\"warp\">Дэфармацыя</string>\n    <string name=\"hardness\">Цвёрдасць</string>\n    <string name=\"warp_mode\">Рэжым дэфармацыі</string>\n    <string name=\"warp_mode_move\">Рухайцеся</string>\n    <string name=\"warp_mode_grow\">Расці</string>\n    <string name=\"warp_mode_shrink\">Скарачацца</string>\n    <string name=\"warp_mode_swirl_cw\">Круціцца CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Круціце супраць супрацьлеглай рукі</string>\n    <string name=\"fade_strength\">Fade Strength</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Ніжняя кропля</string>\n    <string name=\"start_drop\">Пачаць Drop</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">Ідзе загрузка</string>\n    <string name=\"smooth_shapes\">Гладкія фігуры</string>\n    <string name=\"smooth_shapes_sub\">Выкарыстоўвайце суперэліпсы замест стандартных круглявых прамавугольнікаў для больш гладкіх і натуральных формаў</string>\n    <string name=\"shape_type\">Тып формы</string>\n    <string name=\"cut\">Выразаць</string>\n    <string name=\"rounded\">Закругленыя</string>\n    <string name=\"smooth\">Гладкая</string>\n    <string name=\"cut_shapes_sub\">Вострыя краю без закруглення</string>\n    <string name=\"rounded_shapes_sub\">Класічныя закругленыя куты</string>\n    <string name=\"shapes_type\">Формы Тып</string>\n    <string name=\"corners_size\">Памер кутоў</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Элегантныя закругленыя элементы інтэрфейсу</string>\n    <string name=\"filename_format\">Фармат імя файла</string>\n    <string name=\"prefix_pattern_description\">Нестандартны тэкст змяшчаецца ў самым пачатку назвы файла, ідэальна падыходзіць для назваў праектаў, брэндаў або асабістых тэгаў.</string>\n    <string name=\"original_filename_pattern_description\">Выкарыстоўвае зыходнае імя файла без пашырэння, што дапамагае захаваць ідэнтыфікацыю крыніцы.</string>\n    <string name=\"width_pattern_description\">Шырыня выявы ў пікселях, карысная для адсочвання змяненняў раздзялення або маштабавання вынікаў.</string>\n    <string name=\"height_pattern_description\">Вышыня выявы ў пікселях, карысная пры працы з суадносінамі бакоў або экспартам.</string>\n    <string name=\"random_numbers_pattern_description\">Генеруе выпадковыя лічбы, каб гарантаваць унікальныя імёны файлаў; дадаць больш лічбаў для дадатковай бяспекі ад дублікатаў.</string>\n    <string name=\"sequence_number_pattern_description\">Лічыльнік з аўтаматычным павелічэннем для пакетнага экспарту, ідэальны варыянт пры захаванні некалькіх малюнкаў за адзін сеанс.</string>\n    <string name=\"preset_info_pattern_description\">Устаўляе прымененае імя загадзя ў імя файла, каб вы маглі лёгка запомніць, як апрацоўваўся малюнак.</string>\n    <string name=\"scale_mode_pattern_description\">Адлюстроўвае рэжым маштабавання выявы, які выкарыстоўваецца падчас апрацоўкі, дапамагаючы адрозніваць выявы змененага памеру, абрэзаныя або падагнаныя.</string>\n    <string name=\"suffix_pattern_description\">Нестандартны тэкст, размешчаны ў канцы імя файла, карысны для кіравання версіямі, такімі як _v2, _edited або _final.</string>\n    <string name=\"extension_pattern_description\">Пашырэнне файла (png, jpg, webp і г.д.), якое аўтаматычна адпавядае фактычнаму захаванаму фармату.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Наладжвальная пазнака часу, якая дазваляе вам вызначаць уласны фармат па спецыфікацыі Java для ідэальнага сартавання.</string>\n    <string name=\"fling_type\">Тып кідка</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">Стыль iOS</string>\n    <string name=\"smooth_curve\">Плаўная крывая</string>\n    <string name=\"quick_stop\">Хуткая прыпынак</string>\n    <string name=\"bouncy\">Бадзёры</string>\n    <string name=\"floaty\">Плывучы</string>\n    <string name=\"snappy\">Імклівы</string>\n    <string name=\"ultra_smooth\">Ультрагладкая</string>\n    <string name=\"adaptive\">Адаптыўны</string>\n    <string name=\"accessibility_aware\">Даступнасць Aware</string>\n    <string name=\"reduced_motion\">Зніжэнне руху</string>\n    <string name=\"android_native_sub\">Родная фізіка пракруткі Android</string>\n    <string name=\"smooth_sub\">Збалансаваная плыўная пракрутка для агульнага карыстання</string>\n    <string name=\"ios_style_sub\">Паводзіны пракруткі, падобныя на iOS, з большым трэннем</string>\n    <string name=\"smooth_curve_sub\">Унікальная сплайн-крывая для выразнага адчування пракруткі</string>\n    <string name=\"quick_stop_sub\">Дакладная пракрутка з хуткай прыпынкам</string>\n    <string name=\"bouncy_sub\">Гуллівы, спагадны пругкі скрутак</string>\n    <string name=\"floaty_sub\">Доўгія слізгальныя скруткі для прагляду кантэнту</string>\n    <string name=\"snappy_sub\">Хуткая і адаптыўная пракрутка для інтэрактыўных інтэрфейсаў</string>\n    <string name=\"ultra_smooth_sub\">Прэміяльная плаўная пракрутка з пашыраным імпульсам</string>\n    <string name=\"adaptive_sub\">Рэгулюе фізіку ў залежнасці ад хуткасці кідка</string>\n    <string name=\"accessibility_aware_sub\">Паважае налады даступнасці сістэмы</string>\n    <string name=\"reduced_motion_sub\">Мінімальны рух для патрэб даступнасці</string>\n    <string name=\"primary_lines\">Першасныя лініі</string>\n    <string name=\"primary_lines_sub\">Дадае больш тоўстую лінію кожны пяты радок</string>\n    <string name=\"fill_color\">Колер залівання</string>\n    <string name=\"hidden_tools\">Схаваныя інструменты</string>\n    <string name=\"hidden_for_share\">Інструменты, схаваныя для абмену</string>\n    <string name=\"color_library\">Бібліятэка колераў</string>\n    <string name=\"color_library_sub\">Праглядзіце шырокую калекцыю колераў</string>\n    <string name=\"model_fatality_deblur\">Павялічвае рэзкасць і выдаляе размытасць малюнкаў, захоўваючы пры гэтым натуральныя дэталі, што ідэальна падыходзіць для выпраўлення расфакусаваных фатаграфій.</string>\n    <string name=\"model_unresize_v3\">Інтэлектуальна аднаўляе выявы, памер якіх раней быў зменены, аднаўляючы страчаныя дэталі і тэкстуры.</string>\n    <string name=\"model_liveaction_v1_span\">Аптымізаваны для жывога кантэнту, памяншае артэфакты сціску і паляпшае дробныя дэталі ў кадрах фільмаў/тэлешоу.</string>\n    <string name=\"model_vhs2hd_realplksr\">Пераўтварае відэаматэрыял VHS-якасці ў HD, выдаляючы шум стужкі і паляпшаючы разрозненне, захоўваючы старадаўняе адчуванне.</string>\n    <string name=\"model_text2hd_v1\">Спецыялізуецца на выявах і скрыншотах з вялікай колькасцю тэксту, узмацняе выразнасць сімвалаў і паляпшае чытальнасць.</string>\n    <string name=\"model_frankendata_pretrainer\">Пашыранае павышэнне маштабу, навучанае на розных наборах даных, выдатна падыходзіць для паляпшэння фатаграфій агульнага прызначэння.</string>\n    <string name=\"model_realwebphoto_v2\">Аптымізавана для фатаграфій, сціснутых у Інтэрнэце, выдаляе артэфакты JPEG і аднаўляе натуральны выгляд.</string>\n    <string name=\"model_realwebphoto_v4\">Палепшаная версія для вэб-фатаграфій з лепшым захаваннем тэкстуры і памяншэннем артэфактаў.</string>\n    <string name=\"model_dat_2x\">2-кратнае павелічэнне маштабу з дапамогай тэхналогіі Dual Aggregation Transformer, захоўвае рэзкасць і натуральныя дэталі.</string>\n    <string name=\"model_dat_3x\">3-кратнае павелічэнне з выкарыстаннем перадавой архітэктуры трансфарматара, ідэальнае для ўмераных патрэб пашырэння.</string>\n    <string name=\"model_dat_4x\">4-кратнае высакаякаснае павышэнне маштабу з сучаснай сеткай трансфарматараў, захоўвае дробныя дэталі ў вялікіх маштабах.</string>\n    <string name=\"model_nafnet_deblurring\">Выдаляе размытасць/шум і дрыгаценне фатаграфій. Агульнага прызначэння, але лепш за ўсё на фота.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Аднаўляе выявы нізкай якасці з дапамогай трансфарматара Swin2SR, аптымізаванага для дэградацыі BSRGAN. Выдатна падыходзіць для выпраўлення моцных артэфактаў сціску і паляпшэння дэталяў у 4-кратным маштабе.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4-кратнае павелічэнне маштабу з дапамогай трансфарматара SwinIR, навучанага дэградацыі BSRGAN. Выкарыстоўвае GAN для больш выразных тэкстур і больш натуральных дэталяў на фотаздымках і складаных сцэнах.</string>\n    <string name=\"path\">шлях</string>\n    <string name=\"merge_pdf\">Аб\\'яднаць PDF</string>\n    <string name=\"merge_pdf_sub\">Аб\\'яднайце некалькі файлаў PDF у адзін дакумент</string>\n    <string name=\"files_order\">Парадак файлаў</string>\n    <string name=\"pages_short\">с.</string>\n    <string name=\"split_pdf\">Разбіць PDF</string>\n    <string name=\"split_pdf_sub\">Выняць пэўныя старонкі з дакумента PDF</string>\n    <string name=\"rotate_pdf\">Павярнуць pdf</string>\n    <string name=\"rotate_pdf_sub\">Назаўжды выправіць арыентацыю старонкі</string>\n    <string name=\"pages\">старонкі</string>\n    <string name=\"rearrange_pdf\">Змяніць парадак pdf</string>\n    <string name=\"rearrange_pdf_sub\">Перацягніце старонкі, каб змяніць іх парадак</string>\n    <string name=\"hold_drag_drop\">Утрымлівайце і перацягвайце старонкі</string>\n    <string name=\"page_numbers\">Нумары старонак</string>\n    <string name=\"page_numbers_sub\">Аўтаматычна дадайце нумарацыю ў свае дакументы</string>\n    <string name=\"label_format\">Фармат этыкеткі</string>\n    <string name=\"pdf_to_text\">PDF у тэкст (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Вылучыце звычайны тэкст з дакументаў PDF</string>\n    <string name=\"watermark_pdf_sub\">Накладанне ўласнага тэксту для брэндынгу або бяспекі</string>\n    <string name=\"signature\">Подпіс</string>\n    <string name=\"signature_sub\">Дадайце свой электронны подпіс да любога дакумента</string>\n    <string name=\"will_be_for_signature\">Гэта будзе выкарыстоўвацца як подпіс</string>\n    <string name=\"unlock_pdf\">Разблакіраваць PDF</string>\n    <string name=\"unlock_pdf_sub\">Выдаліце ​​​​паролі з вашых абароненых файлаў</string>\n    <string name=\"protect_pdf\">Абараніць PDF</string>\n    <string name=\"protect_pdf_sub\">Абараніце свае дакументы з дапамогай моцнага шыфравання</string>\n    <string name=\"success\">Поспех</string>\n    <string name=\"pdf_unlocked\">PDF разблакіраваны, вы можаце захаваць ці падзяліцца ім</string>\n    <string name=\"repair_pdf\">Рамонт pdf</string>\n    <string name=\"repair_pdf_sub\">Спроба выправіць пашкоджаныя або нечытэльныя дакументы</string>\n    <string name=\"grayscale\">Адценні шэрага</string>\n    <string name=\"grayscale_pdf_sub\">Пераўтварыце ўсе выявы, убудаваныя ў дакумент, у адценні шэрага</string>\n    <string name=\"compress_pdf\">Сціснуць PDF</string>\n    <string name=\"compress_pdf_sub\">Аптымізуйце памер файла дакумента для палягчэння абмену</string>\n    <string name=\"repair_info\">ImageToolbox аднаўляе ўнутраную табліцу крыжаваных спасылак і аднаўляе структуру файла з нуля. Гэта можа аднавіць доступ да многіх файлаў, якія \\\\\"немагчыма адкрыць\\\\\"</string>\n    <string name=\"grayscale_info\">Гэты інструмент пераўтворыць усе выявы дакументаў у адценні шэрага. Лепшы для друку і памяншэння памеру файла</string>\n    <string name=\"metadata\">Метададзеныя</string>\n    <string name=\"metadata_pdf_sub\">Рэдагуйце ўласцівасці дакумента для лепшай прыватнасці</string>\n    <string name=\"tags\">Тэгі</string>\n    <string name=\"producer\">Прадзюсер</string>\n    <string name=\"author\">Аўтар</string>\n    <string name=\"keywords\">Ключавыя словы</string>\n    <string name=\"creator\">Творца</string>\n    <string name=\"privacy_deep_clean\">Прыватнасць Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Ачысціць усе даступныя метаданыя для гэтага дакумента</string>\n    <string name=\"page\">старонка</string>\n    <string name=\"deep_ocr\">Глыбокае OCR</string>\n    <string name=\"deep_ocr_sub\">Выняць тэкст з дакумента і захаваць яго ў адным тэкставым файле з дапамогай рухавіка Tesseract</string>\n    <string name=\"cant_remove_all\">Немагчыма выдаліць усе старонкі</string>\n    <string name=\"remove_pages_pdf\">Выдаліць старонкі PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Выдаліць пэўныя старонкі з дакумента PDF</string>\n    <string name=\"tap_to_remove\">Націсніце, каб выдаліць</string>\n    <string name=\"manually\">Ўручную</string>\n    <string name=\"crop_pdf\">Абрэзаць PDF</string>\n    <string name=\"crop_pdf_sub\">Абрэжце старонкі дакумента да любых межаў</string>\n    <string name=\"flatten_pdf\">Звесці PDF</string>\n    <string name=\"flatten_pdf_sub\">Зрабіце PDF-файл нязменным, растравіўшы старонкі дакумента</string>\n    <string name=\"camera_failed_to_open\">Не атрымалася запусціць камеру. Калі ласка, праверце дазволы і пераканайцеся, што ён не выкарыстоўваецца іншай праграмай.</string>\n    <string name=\"extract_images\">Выманне малюнкаў</string>\n    <string name=\"extract_images_sub\">Выманне малюнкаў, убудаваных у PDF-файлы, у іх зыходным раздзяленні</string>\n    <string name=\"pdf_no_embedded\">Гэты PDF-файл не змяшчае ўбудаваных малюнкаў</string>\n    <string name=\"extract_images_info\">Гэты інструмент скануе кожную старонку і аднаўляе паўнавартасныя зыходныя выявы — ідэальна падыходзіць для захавання арыгіналаў з дакументаў</string>\n    <string name=\"draw_signature\">Намалюйце подпіс</string>\n    <string name=\"pen_params\">Параметры ручкі</string>\n    <string name=\"draw_signature_sub\">Выкарыстоўвайце ўласны подпіс у якасці выявы для размяшчэння на дакументах</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Разбіце дакумент з зададзеным інтэрвалам і спакуйце новыя дакументы ў zip-архіў</string>\n    <string name=\"interval\">Інтэрвал</string>\n    <string name=\"print_pdf\">Раздрукаваць PDF</string>\n    <string name=\"print_pdf_sub\">Падрыхтуйце дакумент да друку з нестандартным памерам старонкі</string>\n    <string name=\"pages_per_sheet\">Старонкі на аркушы</string>\n    <string name=\"orientation\">Арыентацыя</string>\n    <string name=\"page_size\">Памер старонкі</string>\n    <string name=\"margin\">Маржа</string>\n    <string name=\"bloom\">красаваць</string>\n    <string name=\"soft_knee\">Мяккае калена</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Аптымізаваны для анімэ і мультфільмаў. Хуткае павелічэнне маштабу з паляпшэннем натуральных колераў і меншай колькасцю артэфактаў</string>\n    <string name=\"one_ui_sub\">Стыль, падобны на Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Увядзіце тут асноўныя матэматычныя сімвалы, каб вылічыць патрэбнае значэнне (напрыклад, (5+5)*10)</string>\n    <string name=\"math_expression\">Матэматычны выраз</string>\n    <string name=\"pick_up_to_n_collage_images\">Выберыце да %1$s малюнкаў</string>\n    <string name=\"keep_date_time\">Захоўвайце дату і час</string>\n    <string name=\"keep_date_time_sub\">Заўсёды захоўваць тэгі exif, звязаныя з датай і часам, працуе незалежна ад параметра keep exif</string>\n    <string name=\"background_color_for_alpha_formats\">Колер фону для альфа-фарматаў</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Дадае магчымасць усталёўваць колер фону для кожнага фармату выявы з падтрымкай альфа-версіі, калі адключана, гэта даступна толькі для неальфа-фармату</string>\n    <string name=\"open_markup_project\">Адкрыты праект</string>\n    <string name=\"open_markup_project_sub\">Працягнуць рэдагаванне раней захаванага праекта Image Toolbox</string>\n    <string name=\"markup_project_open_failed\">Немагчыма адкрыць праект Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">У праекце Image Toolbox адсутнічаюць даныя праекта</string>\n    <string name=\"markup_project_corrupted\">Праект Image Toolbox пашкоджаны</string>\n    <string name=\"unsupported_markup_project_version\">Непадтрымоўваная версія праекта Image Toolbox: %1$d</string>\n    <string name=\"save_markup_project\">Захаваць праект</string>\n    <string name=\"save_markup_project_sub\">Захоўвайце слаі, фон і гісторыю рэдагавання ў файле праекта, які можна рэдагаваць</string>\n    <string name=\"failed_to_open\">Не ўдалося адкрыць</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Запіс у PDF з магчымасцю пошуку</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Распазнавайце тэкст з пакета малюнкаў і захоўвайце PDF з магчымасцю пошуку з выявай і тэкставым пластом, які можна выбраць</string>\n    <string name=\"layer_alpha\">Пласт альфа</string>\n    <string name=\"horizontal_flip\">Гарызантальны фліп</string>\n    <string name=\"vertical_flip\">Вертыкальны фліп</string>\n    <string name=\"lock\">Замак</string>\n    <string name=\"add_shadow\">Дадайце цень</string>\n    <string name=\"shadow_color\">Колер цені</string>\n    <string name=\"text_geometry\">Геаметрыя тэксту</string>\n    <string name=\"text_geometry_sub\">Расцягніце або перакосіце тэкст для больш выразнай стылізацыі</string>\n    <string name=\"scale_x\">Маштаб X</string>\n    <string name=\"skew_x\">Перакос X</string>\n    <string name=\"remove_annotations\">Выдаліць анатацыі</string>\n    <string name=\"remove_annotations_sub\">Выдаліце ​​са старонак PDF выбраныя тыпы анатацый, такія як спасылкі, каментарыі, вылучэнні, фігуры або палі формы</string>\n    <string name=\"annotation_link\">Гіперспасылкі</string>\n    <string name=\"annotation_file_attachment\">Укладанні файлаў</string>\n    <string name=\"annotation_line\">Радкі</string>\n    <string name=\"annotation_popup\">Усплывальныя вокны</string>\n    <string name=\"annotation_stamp\">Маркі</string>\n    <string name=\"annotation_shapes\">Формы</string>\n    <string name=\"annotation_text\">Тэкставыя нататкі</string>\n    <string name=\"annotation_text_markup\">Разметка тэксту</string>\n    <string name=\"annotation_widget\">Палі формы</string>\n    <string name=\"annotation_markup\">Разметка</string>\n    <string name=\"annotation_unknown\">Невядомы</string>\n    <string name=\"annotations\">Анатацыі</string>\n    <string name=\"ungroup\">Разгрупаваць</string>\n    <string name=\"add_shadow_sub\">Дадайце цень размыцця за пласт з наладжвальнымі колерам і зрухамі</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-bn/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"loading\">লোড হচ্ছে…</string>\n    <string name=\"image_too_large_preview\">ছবিটি প্রিভিউ করার জন্য খুব বড়, তবে সেভ করার চেষ্টা করা হবে।</string>\n    <string name=\"pick_image\">শুরু করার জন্য ছবি বেছে নিন</string>\n    <string name=\"width\">প্রস্থ %1$s</string>\n    <string name=\"height\">উচ্চতা %1$s</string>\n    <string name=\"quality\">গুণমান</string>\n    <string name=\"resize_type\">আকার পরিবর্তনের ধরণ</string>\n    <string name=\"explicit\">স্পষ্ট</string>\n    <string name=\"flexible\">নমনীয়</string>\n    <string name=\"smth_went_wrong\">কিছু ভুল হয়েছে: %1$s</string>\n    <string name=\"size\">আকার %1$s</string>\n    <string name=\"pick_image_alt\">ছবি বেছে নিন</string>\n    <string name=\"app_closing\">অ্যাপ বন্ধ করা হচ্ছে</string>\n    <string name=\"stay\">থাকা</string>\n    <string name=\"close\">বন্ধ</string>\n    <string name=\"reset_image\">ছবি রিসেট করুন</string>\n    <string name=\"values_reset\">মানগুলি সঠিকভাবে রিসেট করা হয়েছে</string>\n    <string name=\"reset\">রিসেট</string>\n    <string name=\"something_went_wrong\">কিছু ভুল হয়েছে</string>\n    <string name=\"restart_app\">অ্যাপটি পুনরায় চালু করুন</string>\n    <string name=\"copied\">ক্লিপবোর্ডে কপি করা হয়েছে</string>\n    <string name=\"edit_exif\">EXIF সম্পাদনা করুন</string>\n    <string name=\"ok\">ঠিক আছে</string>\n    <string name=\"no_exif\">কোন EXIF তথ্য পাওয়া যায়নি</string>\n    <string name=\"save\">সংরক্ষণ করুন</string>\n    <string name=\"clear_exif\">EXIF সাফ করুন</string>\n    <string name=\"extension\">এক্সটেনশন</string>\n    <string name=\"clear\">পরিষ্কার</string>\n    <string name=\"app_closing_sub\">আপনি কি অ্যাপটি বন্ধ করার বিষয়ে নিশ্চিত?</string>\n    <string name=\"add_tag\">ট্যাগ যোগ করুন</string>\n    <string name=\"reset_image_sub\">ছবির পরিবর্তনগুলি প্রাথমিক মানগুলিতে ফিরে যাবে</string>\n    <string name=\"exception\">ব্যতিক্রম</string>\n    <string name=\"cancel\">বাতিল করুন</string>\n    <string name=\"clear_exif_sub\">সব ইমেজ EXIF ডেটা মুছে ফেলা হবে। এই কাজের পর আগের অবস্থায় ফিরে আসা যাবে না!</string>\n    <string name=\"presets\">পূর্বনির্ধারণ সমূহ</string>\n    <string name=\"crop\">কেটে ছোট করুন</string>\n    <string name=\"image_not_saved\">সংরক্ষণ করুন</string>\n    <string name=\"image_not_saved_sub\">সব অরক্ষিত পরিবর্তন হারিয়ে যাবে, যদি আপনি এখন বেরিয়ে যান</string>\n    <string name=\"check_source_code\">সৌর্স কোড</string>\n    <string name=\"check_source_code_sub\">সর্বশেষ আপডেট পান, সমস্যাগুলো এবং আরো কিছু নিয়ে আলোচনা করুন</string>\n    <string name=\"single_edit\">একটি পরিবর্তন</string>\n    <string name=\"pick_color\">রং নির্ণায়ক</string>\n    <string name=\"pick_color_sub\">ছবি থেকে রং নির্ণয়, কপি অথবা শেয়ার করুন</string>\n    <string name=\"image\">ছবি</string>\n    <string name=\"color\">রং</string>\n    <string name=\"color_copied\">রং কপি করা হয়েছে</string>\n    <string name=\"crop_sub\">যেকোনো সীমায় ছবি কাটুন</string>\n    <string name=\"version\">ভার্সন</string>\n    <string name=\"keep_exif\">EXIF রাখুন</string>\n    <string name=\"change_preview\">খসড়া পরিবর্তন করুন</string>\n    <string name=\"remove\">মুছে ফেলুন</string>\n    <string name=\"palette_sub\">প্রদত্ত ছবি থেকে কালার প্যালেট সোয়াচ তৈরি করুন</string>\n    <string name=\"generate_palette\">প্যালেট তৈরি করুন</string>\n    <string name=\"palette\">প্যালেট</string>\n    <string name=\"update\">আপডেট</string>\n    <string name=\"no_palette\">প্রদত্ত ছবি থেকে কালার প্যালেট তৈরি করা যাচ্ছে না</string>\n    <string name=\"original\">আসল</string>\n    <string name=\"folder\">আউটপুট ফোল্ডার</string>\n    <string name=\"def\">সাধারণ</string>\n    <string name=\"custom\">পছন্দমাফিক</string>\n    <string name=\"unspecified\">অনির্ধারিত</string>\n    <string name=\"device_storage\">ডিভাইস স্টোরেজ</string>\n    <string name=\"max_bytes\">KB তে সর্বোচ্চ সাইজ</string>\n    <string name=\"single_edit_sub\">একটি চিত্র পরিবর্তন, আকার পরিবর্তন এবং সম্পাদনা করুন</string>\n    <string name=\"images\">ছবি: %d</string>\n    <string name=\"new_version\">নতুন সংস্করণ %1$s</string>\n    <string name=\"unsupported_type\">অসমর্থিত প্রকার: %1$s</string>\n    <string name=\"by_bytes_resize\">ওজন দ্বারা মাপ</string>\n    <string name=\"by_bytes_resize_sub\">KB তে প্রদত্ত আকার অনুসরণ করে একটি চিত্রের আকার পরিবর্তন করুন</string>\n    <string name=\"compare\">তুলনা করুন</string>\n    <string name=\"compare_sub\">দুটি প্রদত্ত চিত্রের তুলনা করুন</string>\n    <string name=\"pick_two_images\">শুরু করতে দুটি ছবি বেছে নিন</string>\n    <string name=\"pick_images\">ছবি বাছাই করুন</string>\n    <string name=\"settings\">সেটিংস</string>\n    <string name=\"night_mode\">নাইট মোড</string>\n    <string name=\"dark\">অন্ধকার</string>\n    <string name=\"light\">আলো</string>\n    <string name=\"system\">সিস্টেম</string>\n    <string name=\"dynamic_colors\">গতিশীল রং</string>\n    <string name=\"customization\">কাস্টমাইজেশন</string>\n    <string name=\"allow_image_monet\">ইমেজ monet অনুমতি দিন</string>\n    <string name=\"allow_image_monet_sub\">যদি সক্ষম করা থাকে, আপনি যখন সম্পাদনা করার জন্য একটি ছবি চয়ন করেন, তখন অ্যাপের রঙগুলি এই ছবিতে গৃহীত হবে৷</string>\n    <string name=\"language\">ভাষা</string>\n    <string name=\"amoled_mode\">অ্যামোলেড মোড</string>\n    <string name=\"amoled_mode_sub\">সক্ষম হলে পৃষ্ঠের রঙ রাতের মোডে পরম অন্ধকারে সেট করা হবে</string>\n    <string name=\"color_scheme\">রঙের স্কিম</string>\n    <string name=\"color_red\">লাল</string>\n    <string name=\"color_green\">সবুজ</string>\n    <string name=\"color_blue\">নীল</string>\n    <string name=\"clipboard_paste_invalid_color_code\">একটি বৈধ aRGB কালার কোড পেস্ট করুন</string>\n    <string name=\"clipboard_paste_invalid_empty\">পেস্ট করার মতো কিছুই নেই</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">ডায়নামিক রং চালু থাকা অবস্থায় অ্যাপের রঙের স্কিম পরিবর্তন করা যাবে না</string>\n    <string name=\"pick_accent_color\">অ্যাপ থিম নির্বাচিত রঙের উপর ভিত্তি করে হবে</string>\n    <string name=\"about_app\">অ্যাপ সম্পর্কে</string>\n    <string name=\"no_updates\">কোন আপডেট পাওয়া যায়নি</string>\n    <string name=\"issue_tracker\">ইস্যু ট্র্যাকার</string>\n    <string name=\"issue_tracker_sub\">এখানে বাগ রিপোর্ট এবং বৈশিষ্ট্য অনুরোধ পাঠান</string>\n    <string name=\"help_translate\">অনুবাদে সাহায্য করুন</string>\n    <string name=\"help_translate_sub\">অনুবাদের ভুলগুলি সংশোধন করুন বা অন্য ভাষায় প্রকল্প স্থানীয়করণ করুন</string>\n    <string name=\"nothing_found_by_search\">আপনার প্রশ্নের দ্বারা কিছুই পাওয়া যায়নি</string>\n    <string name=\"search_here\">এখানে অনুসন্ধান করুন</string>\n    <string name=\"dynamic_colors_sub\">যদি সক্ষম করা থাকে, তাহলে অ্যাপের রং ওয়ালপেপারের রঙে গৃহীত হবে</string>\n    <string name=\"failed_to_save\">%d ছবি(গুলি) সংরক্ষণ করতে ব্যর্থ হয়েছে</string>\n    <string name=\"email\">ইমেইল</string>\n    <string name=\"primary\">প্রাথমিক</string>\n    <string name=\"tertiary\">টারশিয়ারি</string>\n    <string name=\"secondary\">মাধ্যমিক</string>\n    <string name=\"border_thickness\">সীমানা বেধ</string>\n    <string name=\"surface\">সারফেস</string>\n    <string name=\"values\">মূল্যবোধ</string>\n    <string name=\"add\">যোগ করুন</string>\n    <string name=\"permission\">অনুমতি</string>\n    <string name=\"grant\">অনুদান</string>\n    <string name=\"permission_sub\">অ্যাপ্লিকেশন কাজ করার জন্য ছবি সংরক্ষণ করতে আপনার স্টোরেজ অ্যাক্সেস প্রয়োজন, এটা প্রয়োজন. অনুগ্রহ করে পরবর্তী ডায়ালগ বক্সে অনুমতি দিন।</string>\n    <string name=\"grant_permission_manual\">অ্যাপটির কাজ করার জন্য এই অনুমতির প্রয়োজন, অনুগ্রহ করে এটি ম্যানুয়ালি মঞ্জুর করুন</string>\n    <string name=\"external_storage\">বাহ্যিক স্টোরেজ</string>\n    <string name=\"monet_colors\">Monet রং</string>\n    <string name=\"donation_sub\">এই অ্যাপ্লিকেশনটি সম্পূর্ণ বিনামূল্যে, তবে আপনি যদি প্রকল্পের উন্নয়নে সহায়তা করতে চান তবে আপনি এখানে ক্লিক করতে পারেন</string>\n    <string name=\"fab_alignment\">FAB প্রান্তিককরণ</string>\n    <string name=\"check_updates\">আপডেটের জন্য চেক করুন</string>\n    <string name=\"check_updates_sub\">সক্রিয় থাকলে, অ্যাপ স্টার্টআপে আপনাকে আপডেট ডায়ালগ দেখানো হবে</string>\n    <string name=\"zoom\">ছবি জুম</string>\n    <string name=\"share\">শেয়ার করুন</string>\n    <string name=\"prefix\">উপসর্গ</string>\n    <string name=\"filename\">ফাইলের নাম</string>\n    <string name=\"emoji\">ইমোজি</string>\n    <string name=\"emoji_sub\">প্রধান স্ক্রিনে কোন ইমোজি প্রদর্শন করতে হবে তা নির্বাচন করুন</string>\n    <string name=\"add_file_size\">ফাইলের আকার যোগ করুন</string>\n    <string name=\"add_file_size_sub\">যদি সক্রিয় থাকে, আউটপুট ফাইলের নামে সংরক্ষিত চিত্রের প্রস্থ এবং উচ্চতা যোগ করে</string>\n    <string name=\"delete_exif\">EXIF মুছুন</string>\n    <string name=\"delete_exif_sub\">যেকোন ছবির সেট থেকে EXIF ​​মেটাডেটা মুছুন</string>\n    <string name=\"image_preview\">ছবির পূর্বরূপ</string>\n    <string name=\"image_preview_sub\">যেকোন ধরনের ছবির পূর্বরূপ দেখুন: GIF, SVG, ইত্যাদি</string>\n    <string name=\"image_source\">ইমেজ সোর্স</string>\n    <string name=\"photo_picker\">ফটো পিকার</string>\n    <string name=\"gallery_picker\">গ্যালারি</string>\n    <string name=\"file_explorer_picker\">ফাইল এক্সপ্লোরার</string>\n    <string name=\"photo_picker_sub\">স্ক্রিনের নীচে প্রদর্শিত অ্যান্ড্রয়েড আধুনিক ফটো পিকার, শুধুমাত্র অ্যান্ড্রয়েড 12+ এ কাজ করতে পারে। EXIF মেটাডেটা প্রাপ্তিতে সমস্যা আছে</string>\n    <string name=\"gallery_picker_sub\">সহজ গ্যালারি ইমেজ পিকার। মিডিয়া পিকিং প্রদান করে এমন একটি অ্যাপ থাকলেই এটি কাজ করবে</string>\n    <string name=\"file_explorer_picker_sub\">ছবি বাছাই করতে GetContent উদ্দেশ্য ব্যবহার করুন। সব জায়গায় কাজ করে, কিন্তু কিছু ডিভাইসে বাছাই করা ছবি পেতে সমস্যা আছে বলে জানা যায়। এটা আমার দোষ না।</string>\n    <string name=\"options_arrangement\">বিকল্প ব্যবস্থা</string>\n    <string name=\"edit\">সম্পাদনা করুন</string>\n    <string name=\"order\">অর্ডার</string>\n    <string name=\"order_sub\">প্রধান স্ক্রিনে টুলের ক্রম নির্ধারণ করে</string>\n    <string name=\"emojis_count\">ইমোজি গণনা</string>\n    <string name=\"sequence_num\">ক্রমসংখ্যা</string>\n    <string name=\"original_filename\">মূল ফাইলের নাম</string>\n    <string name=\"add_original_filename\">মূল ফাইলের নাম যোগ করুন</string>\n    <string name=\"add_original_filename_sub\">সক্রিয় থাকলে আউটপুট চিত্রের নামে মূল ফাইলের নাম যোগ করে</string>\n    <string name=\"replace_sequence_number\">ক্রম নম্বর প্রতিস্থাপন করুন</string>\n    <string name=\"replace_sequence_number_sub\">আপনি ব্যাচ প্রসেসিং ব্যবহার করলে ইমেজ সিকোয়েন্স নম্বরে স্ট্যান্ডার্ড টাইমস্ট্যাম্প প্রতিস্থাপন করা হলে</string>\n    <string name=\"filename_not_work_with_photopicker\">ফটো পিকার ইমেজ সোর্স নির্বাচিত হলে আসল ফাইলের নাম যোগ করা কাজ করে না</string>\n    <string name=\"load_image_from_net\">ওয়েব ইমেজ লোড হচ্ছে</string>\n    <string name=\"load_image_from_net_sub\">ইন্টারনেট থেকে যেকোনো ছবি লোড করুন প্রিভিউ, জুম, এডিট এবং আপনি চাইলে সেভ করতে।</string>\n    <string name=\"no_image\">কোনো ছবি নেই</string>\n    <string name=\"image_link\">ছবির লিঙ্ক</string>\n    <string name=\"fill\">ভরাট</string>\n    <string name=\"fit\">ফিট</string>\n    <string name=\"content_scale\">বিষয়বস্তু স্কেল</string>\n    <string name=\"explicit_description\">প্রদত্ত উচ্চতা এবং প্রস্থে চিত্রগুলির আকার পরিবর্তন করে৷ চিত্রগুলির আকৃতির অনুপাত পরিবর্তিত হতে পারে।</string>\n    <string name=\"flexible_description\">প্রদত্ত উচ্চতা বা প্রস্থে লম্বা পাশ সহ চিত্রগুলির আকার পরিবর্তন করে৷ সংরক্ষণের পরে সমস্ত আকারের হিসাব করা হবে। ছবির আকৃতির অনুপাত সংরক্ষণ করা হবে।</string>\n    <string name=\"brightness\">উজ্জ্বলতা</string>\n    <string name=\"contrast\">বৈপরীত্য</string>\n    <string name=\"hue\">হিউ</string>\n    <string name=\"saturation\">স্যাচুরেশন</string>\n    <string name=\"add_filter\">ফিল্টার যোগ করুন</string>\n    <string name=\"filter\">ফিল্টার</string>\n    <string name=\"filter_sub\">ছবিতে ফিল্টার চেইন প্রয়োগ করুন</string>\n    <string name=\"filters\">ফিল্টার</string>\n    <string name=\"light_aka_illumination\">আলো</string>\n    <string name=\"color_filter\">রঙ ফিল্টার</string>\n    <string name=\"alpha\">আলফা</string>\n    <string name=\"exposure\">প্রকাশ</string>\n    <string name=\"white_balance\">সাদা ভারসাম্য</string>\n    <string name=\"temperature\">তাপমাত্রা</string>\n    <string name=\"tint\">আভা</string>\n    <string name=\"monochrome\">একরঙা</string>\n    <string name=\"gamma\">গামা</string>\n    <string name=\"highlights_shadows\">হাইলাইট এবং ছায়া</string>\n    <string name=\"highlights\">হাইলাইট</string>\n    <string name=\"shadows\">ছায়া</string>\n    <string name=\"haze\">কুয়াশা</string>\n    <string name=\"effect\">প্রভাব</string>\n    <string name=\"distance\">দূরত্ব</string>\n    <string name=\"slope\">ঢাল</string>\n    <string name=\"sharpen\">ধারালো</string>\n    <string name=\"sepia\">সেপিয়া</string>\n    <string name=\"negative\">নেতিবাচক</string>\n    <string name=\"solarize\">সোলারাইজ করুন</string>\n    <string name=\"vibrance\">ভাইব্রেন্স</string>\n    <string name=\"black_and_white\">কালো এবং সাদা</string>\n    <string name=\"crosshatch\">ক্রসশ্যাচ</string>\n    <string name=\"spacing\">ব্যবধান</string>\n    <string name=\"line_width\">লাইন প্রস্থ</string>\n    <string name=\"sobel_edge\">সোবেল প্রান্ত</string>\n    <string name=\"blur\">ঝাপসা</string>\n    <string name=\"halftone\">হাফটোন</string>\n    <string name=\"cga_colorspace\">CGA রঙের স্থান</string>\n    <string name=\"gaussian_blur\">গাউসিয়ান ব্লার</string>\n    <string name=\"box_blur\">বক্স ঝাপসা</string>\n    <string name=\"bilaterial_blur\">দ্বিপাক্ষিক অস্পষ্টতা</string>\n    <string name=\"emboss\">এমবস</string>\n    <string name=\"laplacian\">ল্যাপ্লাসিয়ান</string>\n    <string name=\"vignette\">ভিগনেট</string>\n    <string name=\"start\">শুরু করুন</string>\n    <string name=\"end\">শেষ</string>\n    <string name=\"kuwahara\">কুয়াহারা মসৃণ করা</string>\n    <string name=\"stack_blur\">স্ট্যাক ব্লার</string>\n    <string name=\"radius\">ব্যাসার্ধ</string>\n    <string name=\"scale\">স্কেল</string>\n    <string name=\"distortion\">বিকৃতি</string>\n    <string name=\"angle\">কোণ</string>\n    <string name=\"swirl\">ঘূর্ণি</string>\n    <string name=\"bulge\">স্ফীতি</string>\n    <string name=\"dilation\">প্রসারণ</string>\n    <string name=\"sphere_refraction\">গোলক প্রতিসরণ</string>\n    <string name=\"refractive_index\">প্রতিসরণকারী সূচক</string>\n    <string name=\"glass_sphere_refraction\">কাচের গোলকের প্রতিসরণ</string>\n    <string name=\"color_matrix\">কালার ম্যাট্রিক্স</string>\n    <string name=\"opacity\">অস্বচ্ছতা</string>\n    <string name=\"limits_resize\">সীমা অনুযায়ী আকার পরিবর্তন করুন</string>\n    <string name=\"limits_resize_sub\">আকৃতির অনুপাত বজায় রেখে প্রদত্ত উচ্চতা এবং প্রস্থে চিত্রগুলির আকার পরিবর্তন করুন</string>\n    <string name=\"sketch\">স্কেচ</string>\n    <string name=\"threshold\">থ্রেশহোল্ড</string>\n    <string name=\"quantizationLevels\">কোয়ান্টাইজেশন লেভেল</string>\n    <string name=\"smooth_toon\">মসৃণ টুন</string>\n    <string name=\"toon\">টুন</string>\n    <string name=\"posterize\">পোস্টারাইজ করুন</string>\n    <string name=\"non_maximum_suppression\">অ সর্বোচ্চ দমন</string>\n    <string name=\"weak_pixel_inclusion\">দুর্বল পিক্সেল অন্তর্ভুক্তি</string>\n    <string name=\"lookup\">লুকআপ</string>\n    <string name=\"convolution3x3\">আবর্তন 3x3</string>\n    <string name=\"rgb_filter\">আরজিবি ফিল্টার</string>\n    <string name=\"false_color\">মিথ্যা রং</string>\n    <string name=\"first_color\">প্রথম রঙ</string>\n    <string name=\"second_color\">দ্বিতীয় রঙ</string>\n    <string name=\"reorder\">পুনরায় সাজান</string>\n    <string name=\"fast_blur\">দ্রুত ঝাপসা</string>\n    <string name=\"blur_size\">ব্লার সাইজ</string>\n    <string name=\"blur_center_x\">অস্পষ্ট কেন্দ্র x</string>\n    <string name=\"blur_center_y\">অস্পষ্ট কেন্দ্র y</string>\n    <string name=\"zoom_blur\">জুম ব্লার</string>\n    <string name=\"color_balance\">রঙের ভারসাম্য</string>\n    <string name=\"luminance_threshold\">উজ্জ্বলতা থ্রেশহোল্ড</string>\n    <string name=\"activate_files\">আপনি ফাইল অ্যাপটি নিষ্ক্রিয় করেছেন, এই বৈশিষ্ট্যটি ব্যবহার করতে এটি সক্রিয় করুন৷</string>\n    <string name=\"draw\">আঁকা</string>\n    <string name=\"draw_sub\">একটি স্কেচবুকের মতো চিত্রে আঁকুন বা পটভূমিতে নিজেই আঁকুন</string>\n    <string name=\"paint_color\">পেইন্ট রং</string>\n    <string name=\"paint_alpha\">আলফা পেইন্ট করুন</string>\n    <string name=\"draw_on_image\">চিত্রে আঁকুন</string>\n    <string name=\"draw_on_image_sub\">একটি ছবি বাছুন এবং এটিতে কিছু আঁকুন</string>\n    <string name=\"draw_on_background\">পটভূমিতে আঁকা</string>\n    <string name=\"draw_on_background_sub\">পটভূমির রঙ চয়ন করুন এবং এটির উপরে আঁকুন</string>\n    <string name=\"background_color\">পটভূমির রঙ</string>\n    <string name=\"cipher\">সাইফার</string>\n    <string name=\"cipher_sub\">বিভিন্ন উপলব্ধ ক্রিপ্টো অ্যালগরিদমের উপর ভিত্তি করে যেকোনো ফাইল (শুধুমাত্র ছবি নয়) এনক্রিপ্ট এবং ডিক্রিপ্ট করুন</string>\n    <string name=\"pick_file\">ফাইল বাছাই করুন</string>\n    <string name=\"encrypt\">এনক্রিপ্ট করুন</string>\n    <string name=\"decrypt\">ডিক্রিপ্ট করুন</string>\n    <string name=\"pick_file_to_start\">শুরু করতে ফাইল বাছাই করুন</string>\n    <string name=\"decryption\">ডিক্রিপশন</string>\n    <string name=\"encryption\">এনক্রিপশন</string>\n    <string name=\"key\">চাবি</string>\n    <string name=\"file_proceed\">ফাইল প্রক্রিয়া করা হয়েছে</string>\n    <string name=\"store_file_desc\">এই ফাইলটি আপনার ডিভাইসে সঞ্চয় করুন অথবা আপনি যেখানে চান সেখানে রাখতে শেয়ার অ্যাকশন ব্যবহার করুন</string>\n    <string name=\"features\">বৈশিষ্ট্য</string>\n    <string name=\"implementation\">বাস্তবায়ন</string>\n    <string name=\"compatibility\">সামঞ্জস্য</string>\n    <string name=\"features_sub\">ফাইলগুলির পাসওয়ার্ড-ভিত্তিক এনক্রিপশন। অগ্রসর হওয়া ফাইলগুলি নির্বাচিত ডিরেক্টরিতে সংরক্ষণ করা বা ভাগ করা যেতে পারে। ডিক্রিপ্ট করা ফাইলগুলিও সরাসরি খোলা যায়।</string>\n    <string name=\"implementation_sub\">AES-256, GCM মোড, কোনো প্যাডিং নেই, ডিফল্টরূপে 12 বাইট র্যান্ডম IV। আপনি প্রয়োজনীয় অ্যালগরিদম নির্বাচন করতে পারেন। কীগুলি 256-বিট SHA-3 হ্যাশ হিসাবে ব্যবহৃত হয়</string>\n    <string name=\"file_size\">ফাইলের আকার</string>\n    <string name=\"file_size_sub\">সর্বাধিক ফাইলের আকার Android OS এবং উপলব্ধ মেমরি দ্বারা সীমাবদ্ধ, যা ডিভাইস নির্ভর। \\nঅনুগ্রহ করে মনে রাখবেন: মেমরি স্টোরেজ নয়।</string>\n    <string name=\"compatibility_sub\">অনুগ্রহ করে মনে রাখবেন যে অন্যান্য ফাইল এনক্রিপশন সফ্টওয়্যার বা পরিষেবাগুলির সাথে সামঞ্জস্যপূর্ণতা নিশ্চিত নয়৷ একটি সামান্য ভিন্ন কী চিকিত্সা বা সাইফার কনফিগারেশন অসঙ্গতি সৃষ্টি করতে পারে।</string>\n    <string name=\"invalid_password_or_not_encrypted\">অবৈধ পাসওয়ার্ড বা নির্বাচিত ফাইল এনক্রিপ্ট করা হয় না</string>\n    <string name=\"image_size_warning\">প্রদত্ত প্রস্থ এবং উচ্চতা দিয়ে ছবিটি সংরক্ষণ করার চেষ্টা করলে মেমরির বাইরে ত্রুটি হতে পারে। এটি আপনার নিজের ঝুঁকিতে করুন।</string>\n    <string name=\"cache\">ক্যাশে</string>\n    <string name=\"cache_size\">ক্যাশে আকার</string>\n    <string name=\"found_s\">%1$s পাওয়া গেছে</string>\n    <string name=\"auto_cache_clearing\">স্বয়ংক্রিয় ক্যাশে ক্লিয়ারিং</string>\n    <string name=\"auto_cache_clearing_sub\">সক্ষম হলে অ্যাপ ক্যাশে অ্যাপ স্টার্টআপে সাফ হয়ে যাবে</string>\n    <string name=\"create\">তৈরি করুন</string>\n    <string name=\"tools\">টুলস</string>\n    <string name=\"group_options_by_type\">টাইপ দ্বারা গ্রুপ বিকল্প</string>\n    <string name=\"group_options_by_type_sub\">একটি কাস্টম তালিকা বিন্যাসের পরিবর্তে মূল স্ক্রিনে গোষ্ঠীর বিকল্পগুলি তাদের প্রকার অনুসারে</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">বিকল্প গ্রুপিং সক্রিয় থাকা অবস্থায় বিন্যাস পরিবর্তন করা যাবে না</string>\n    <string name=\"edit_screenshot\">স্ক্রিনশট সম্পাদনা করুন</string>\n    <string name=\"secondary_customization\">সেকেন্ডারি কাস্টমাইজেশন</string>\n    <string name=\"screenshot\">স্ক্রিনশট</string>\n    <string name=\"fallback_option\">ফলব্যাক বিকল্প</string>\n    <string name=\"skip\">এড়িয়ে যান</string>\n    <string name=\"copy\">কপি</string>\n    <string name=\"warning_bytes\">%1$s মোডে সংরক্ষণ করা অস্থির হতে পারে, কারণ এটি একটি ক্ষতিহীন বিন্যাস</string>\n    <string name=\"presets_sub\">আপনি যদি প্রিসেট 125 নির্বাচন করে থাকেন, তাহলে ছবিটি মূল ছবির 125% আকার হিসাবে সংরক্ষণ করা হবে। আপনি যদি প্রিসেট 50 নির্বাচন করেন, তাহলে ছবি 50% আকারের সাথে সংরক্ষণ করা হবে</string>\n    <string name=\"presets_sub_bytes\">এখানে প্রিসেট আউটপুট ফাইলের % নির্ধারণ করে, অর্থাৎ আপনি যদি 5 এমবি ইমেজে প্রিসেট 50 নির্বাচন করেন তাহলে সেভ করার পর আপনি একটি 2,5 এমবি ইমেজ পাবেন।</string>\n    <string name=\"randomize_filename\">ফাইলের নাম র্যান্ডমাইজ করুন</string>\n    <string name=\"randomize_filename_sub\">যদি সক্রিয় আউটপুট ফাইলের নাম সম্পূর্ণরূপে র্যান্ডম হবে</string>\n    <string name=\"saved_to\">%2$s নামের সাথে %1$s ফোল্ডারে সংরক্ষিত</string>\n    <string name=\"saved_to_without_filename\">%1$s ফোল্ডারে সংরক্ষিত</string>\n    <string name=\"tg_chat\">টেলিগ্রাম চ্যাট</string>\n    <string name=\"tg_chat_sub\">অ্যাপটি নিয়ে আলোচনা করুন এবং অন্যান্য ব্যবহারকারীদের কাছ থেকে প্রতিক্রিয়া পান। আপনি সেখানে বিটা আপডেট এবং অন্তর্দৃষ্টিও পেতে পারেন।</string>\n    <string name=\"crop_mask\">ক্রপ মাস্ক</string>\n    <string name=\"aspect_ratio\">আকৃতির অনুপাত</string>\n    <string name=\"image_crop_mask_sub\">প্রদত্ত চিত্র থেকে মুখোশ তৈরি করতে এই মাস্ক টাইপটি ব্যবহার করুন, লক্ষ্য করুন যে এটিতে আলফা চ্যানেল থাকা উচিত</string>\n    <string name=\"backup_and_restore\">ব্যাকআপ এবং পুনরুদ্ধার</string>\n    <string name=\"backup\">ব্যাকআপ</string>\n    <string name=\"restore\">পুনরুদ্ধার করুন</string>\n    <string name=\"backup_sub\">একটি ফাইলে আপনার অ্যাপ সেটিংস ব্যাকআপ করুন</string>\n    <string name=\"restore_sub\">পূর্বে তৈরি করা ফাইল থেকে অ্যাপ সেটিংস পুনরুদ্ধার করুন</string>\n    <string name=\"corrupted_file_or_not_a_backup\">দূষিত ফাইল বা ব্যাকআপ নয়</string>\n    <string name=\"settings_restored\">সেটিংস সফলভাবে পুনরুদ্ধার করা হয়েছে৷</string>\n    <string name=\"contact_me\">আমার সাথে যোগাযোগ করুন</string>\n    <string name=\"reset_settings_sub\">এটি আপনার সেটিংসকে ডিফল্ট মানগুলিতে ফিরিয়ে আনবে। লক্ষ্য করুন যে উপরে উল্লিখিত একটি ব্যাকআপ ফাইল ছাড়া এটি পূর্বাবস্থায় ফেরানো যাবে না৷</string>\n    <string name=\"delete\">মুছুন</string>\n    <string name=\"delete_color_scheme_warn\">আপনি নির্বাচিত রঙের স্কিম মুছে ফেলতে চলেছেন৷ এই অপারেশন পূর্বাবস্থায় ফেরানো যাবে না</string>\n    <string name=\"delete_color_scheme_title\">স্কিম মুছুন</string>\n    <string name=\"font\">হরফ</string>\n    <string name=\"text\">পাঠ্য</string>\n    <string name=\"font_scale\">ফন্ট স্কেল</string>\n    <string name=\"defaultt\">ডিফল্ট</string>\n    <string name=\"using_large_fonts_warn\">বড় ফন্ট স্কেল ব্যবহার করলে UI সমস্যা এবং সমস্যা হতে পারে, যা ঠিক করা হবে না। সাবধানে ব্যবহার করুন।</string>\n    <string name=\"alphabet_and_numbers\">অ আ ই ঈ উ ঊ ঋ এ ঐ ও ঔ ক খ গ ঘ ঙ চ ছ জ ঝ ঞ ট ঠ ড ঢ ণ ত থ দ ধ ন প ফ ব ভ ম য র ল শ ষ স হ 0123456789 !?</string>\n    <string name=\"emotions\">আবেগ</string>\n    <string name=\"food_and_drink\">খাদ্য এবং পানীয়</string>\n    <string name=\"nature_and_animals\">প্রকৃতি এবং প্রাণী</string>\n    <string name=\"objects\">বস্তু</string>\n    <string name=\"symbols\">প্রতীক</string>\n    <string name=\"enable_emoji\">ইমোজি সক্ষম করুন</string>\n    <string name=\"travels_and_places\">ভ্রমণ এবং স্থান</string>\n    <string name=\"activities\">কার্যক্রম</string>\n    <string name=\"background_remover\">ব্যাকগ্রাউন্ড রিমুভার</string>\n    <string name=\"background_remover_sub\">অঙ্কন করে বা অটো বিকল্প ব্যবহার করে ছবি থেকে পটভূমি সরান</string>\n    <string name=\"trim_image\">ছবি ট্রিম করুন</string>\n    <string name=\"keep_exif_sub\">অরিজিনাল ইমেজ মেটাডেটা রাখা হবে</string>\n    <string name=\"trim_image_sub\">ছবির চারপাশে স্বচ্ছ স্থানগুলি ছাঁটাই করা হবে</string>\n    <string name=\"auto_erase_background\">স্বয়ংক্রিয়ভাবে পটভূমি মুছে ফেলা</string>\n    <string name=\"restore_image\">ছবি পুনরুদ্ধার করুন</string>\n    <string name=\"erase_mode\">মুছে ফেলার মোড</string>\n    <string name=\"erase_background\">পটভূমি মুছুন</string>\n    <string name=\"restore_background\">পটভূমি পুনরুদ্ধার করুন</string>\n    <string name=\"blur_radius\">ব্লার ব্যাসার্ধ</string>\n    <string name=\"pipette\">পিপেট</string>\n    <string name=\"draw_mode\">আঁকা মোড</string>\n    <string name=\"create_issue\">ইস্যু তৈরি করুন</string>\n    <string name=\"something_went_wrong_emphasis\">ওহো… কিছু ভুল হয়েছে। আপনি নীচের বিকল্পগুলি ব্যবহার করে আমাকে লিখতে পারেন এবং আমি সমাধান খোঁজার চেষ্টা করব৷</string>\n    <string name=\"resize_and_convert\">আকার পরিবর্তন করুন এবং রূপান্তর করুন</string>\n    <string name=\"resize_and_convert_sub\">প্রদত্ত চিত্রগুলির আকার পরিবর্তন করুন বা অন্য বিন্যাসে রূপান্তর করুন। EXIF মেটাডেটাও এখানে সম্পাদনা করা যেতে পারে যদি একটি একক ছবি বাছাই করা হয়।</string>\n    <string name=\"max_colors_count\">সর্বাধিক রঙ গণনা</string>\n    <string name=\"crashlytics_sub\">এটি অ্যাপটিকে স্বয়ংক্রিয়ভাবে ক্র্যাশ রিপোর্ট সংগ্রহ করতে দেয়</string>\n    <string name=\"analytics\">বিশ্লেষণ</string>\n    <string name=\"analytics_sub\">বেনামী অ্যাপ ব্যবহারের পরিসংখ্যান সংগ্রহ করার অনুমতি দিন</string>\n    <string name=\"image_exif_warning\">বর্তমানে, %1$s ফরম্যাট শুধুমাত্র Android এ EXIF ​​মেটাডেটা পড়ার অনুমতি দেয়। আউটপুট ইমেজে মেটাডেটা থাকবে না, যখন সেভ করা হবে।</string>\n    <string name=\"effort\">প্রচেষ্টা</string>\n    <string name=\"effort_sub\">%1$s এর মান মানে একটি দ্রুত কম্প্রেশন, যার ফলে ফাইলের আকার তুলনামূলকভাবে বড় হয়। %2$s মানে একটি ধীর সংকোচন, যার ফলে একটি ছোট ফাইল হয়।</string>\n    <string name=\"wait\">অপেক্ষা করুন</string>\n    <string name=\"saving_almost_complete\">সংরক্ষণ প্রায় সম্পূর্ণ। এখন বাতিল করার জন্য আবার সংরক্ষণের প্রয়োজন হবে।</string>\n    <string name=\"updates\">আপডেট</string>\n    <string name=\"allow_betas\">বেটাকে অনুমতি দিন</string>\n    <string name=\"allow_betas_sub\">সক্রিয় থাকলে আপডেট চেকিং বিটা অ্যাপ সংস্করণ অন্তর্ভুক্ত করবে</string>\n    <string name=\"draw_arrows\">তীর আঁকা</string>\n    <string name=\"draw_arrows_sub\">সক্ষম হলে অঙ্কন পথ নির্দেশক তীর হিসাবে উপস্থাপন করা হবে</string>\n    <string name=\"brush_softness\">ব্রাশের কোমলতা</string>\n    <string name=\"crop_description\">প্রবেশ করা আকারে ছবি কেন্দ্রে কাটা হবে। প্রদত্ত পটভূমির রঙ দিয়ে ক্যানভাস প্রসারিত করা হবে যদি চিত্রটি প্রবেশ করা মাত্রার চেয়ে ছোট হয়।</string>\n    <string name=\"donation\">দান</string>\n    <string name=\"image_stitching\">ছবি সেলাই</string>\n    <string name=\"image_stitching_sub\">একটি বড় একটি পেতে প্রদত্ত চিত্রগুলিকে একত্রিত করুন৷</string>\n    <string name=\"pick_at_least_two_images\">কমপক্ষে 2টি ছবি বেছে নিন</string>\n    <string name=\"output_image_scale\">আউটপুট ইমেজ স্কেল</string>\n    <string name=\"image_orientation\">ইমেজ ওরিয়েন্টেশন</string>\n    <string name=\"horizontal\">অনুভূমিক</string>\n    <string name=\"vertical\">উল্লম্ব</string>\n    <string name=\"scale_small_images_to_large\">ছোট ছবিকে বড় করে স্কেল করুন</string>\n    <string name=\"scale_small_images_to_large_sub\">সক্ষম করা থাকলে ছোট ছবিগুলিকে ক্রমানুসারে বৃহত্তম চিত্রে স্কেল করা হবে৷</string>\n    <string name=\"images_order\">ইমেজ অর্ডার</string>\n    <string name=\"regular\">নিয়মিত</string>\n    <string name=\"blur_edges\">ঝাপসা প্রান্ত</string>\n    <string name=\"blur_edges_sub\">সক্রিয় থাকলে একক রঙের পরিবর্তে এটির চারপাশের স্থানগুলি পূরণ করতে আসল চিত্রের নীচে ঝাপসা প্রান্তগুলি আঁকে</string>\n    <string name=\"pixelation\">পিক্সেলেশন</string>\n    <string name=\"enhanced_pixelation\">উন্নত Pixelation</string>\n    <string name=\"stroke_pixelation\">স্ট্রোক পিক্সেলেশন</string>\n    <string name=\"enhanced_diamond_pixelation\">উন্নত ডায়মন্ড পিক্সেলেশন</string>\n    <string name=\"diamond_pixelation\">ডায়মন্ড পিক্সেলেশন</string>\n    <string name=\"circle_pixelation\">সার্কেল পিক্সেলেশন</string>\n    <string name=\"enhanced_circle_pixelation\">উন্নত সার্কেল পিক্সেলেশন</string>\n    <string name=\"replace_color\">রঙ প্রতিস্থাপন করুন</string>\n    <string name=\"tolerance\">সহনশীলতা</string>\n    <string name=\"color_to_replace\">প্রতিস্থাপন করার জন্য রঙ</string>\n    <string name=\"target_color\">টার্গেট কালার</string>\n    <string name=\"color_to_remove\">অপসারণ করার জন্য রঙ</string>\n    <string name=\"remove_color\">রঙ সরান</string>\n    <string name=\"recode\">রিকোড</string>\n    <string name=\"pixel_size\">পিক্সেল সাইজ</string>\n    <string name=\"lock_draw_orientation\">লক ড্র ওরিয়েন্টেশন</string>\n    <string name=\"lock_draw_orientation_sub\">অঙ্কন মোডে সক্রিয় থাকলে, স্ক্রিন ঘোরবে না</string>\n    <string name=\"check_for_updates\">আপডেটের জন্য চেক করুন</string>\n    <string name=\"palette_style\">প্যালেট শৈলী</string>\n    <string name=\"tonal_spot\">টোনাল স্পট</string>\n    <string name=\"neutral\">নিরপেক্ষ</string>\n    <string name=\"vibrant\">প্রাণবন্ত</string>\n    <string name=\"expressive\">অভিব্যক্তিপূর্ণ</string>\n    <string name=\"rainbow\">রংধনু</string>\n    <string name=\"fruit_salad\">ফলের সালাদ</string>\n    <string name=\"fidelity\">বিশ্বস্ততা</string>\n    <string name=\"content\">বিষয়বস্তু</string>\n    <string name=\"tonal_spot_sub\">ডিফল্ট প্যালেট শৈলী, এটি সমস্ত চারটি রঙ কাস্টমাইজ করার অনুমতি দেয়, অন্যরা আপনাকে শুধুমাত্র কী রঙ সেট করতে দেয়</string>\n    <string name=\"neutral_sub\">একটি শৈলী যা একরঙা থেকে একটু বেশি বর্ণময়</string>\n    <string name=\"vibrant_sub\">একটি জোরে থিম, রঙিনতা প্রাথমিক প্যালেটের জন্য সর্বাধিক, অন্যদের জন্য বৃদ্ধি</string>\n    <string name=\"playful_scheme\">একটি কৌতুকপূর্ণ থিম - উত্স রঙের বর্ণ থিমে প্রদর্শিত হয় না৷</string>\n    <string name=\"monochrome_sub\">একটি একরঙা থিম, রঙগুলি সম্পূর্ণরূপে কালো/সাদা/ধূসর</string>\n    <string name=\"content_sub\">একটি স্কিম যা Scheme.primaryContainer-এ উৎসের রঙ রাখে</string>\n    <string name=\"fidelity_sub\">একটি স্কিম যা বিষয়বস্তু স্কিমের অনুরূপ</string>\n    <string name=\"foss_update_checker_warning\">এই আপডেট পরীক্ষক একটি নতুন আপডেট উপলব্ধ আছে কিনা তা পরীক্ষা করার কারণে GitHub এর সাথে সংযুক্ত হবে</string>\n    <string name=\"attention\">মনোযোগ</string>\n    <string name=\"fading_edges\">বিবর্ণ প্রান্ত</string>\n    <string name=\"disabled\">অক্ষম</string>\n    <string name=\"both\">উভয়</string>\n    <string name=\"invert_colors\">উল্টানো রং</string>\n    <string name=\"invert_colors_sub\">সক্রিয় থাকলে থিমের রঙকে নেতিবাচক রঙে প্রতিস্থাপন করে</string>\n    <string name=\"search_option\">অনুসন্ধান করুন</string>\n    <string name=\"search_option_sub\">মূল স্ক্রিনে সমস্ত উপলব্ধ সরঞ্জামগুলির মাধ্যমে অনুসন্ধান করার ক্ষমতা সক্ষম করে৷</string>\n    <string name=\"pdf_tools\">পিডিএফ টুলস</string>\n    <string name=\"pdf_tools_sub\">পিডিএফ ফাইলগুলির সাথে কাজ করুন: পূর্বরূপ, চিত্রের ব্যাচে রূপান্তর করুন বা প্রদত্ত ছবি থেকে একটি তৈরি করুন</string>\n    <string name=\"preview_pdf\">পিডিএফ প্রিভিউ করুন</string>\n    <string name=\"pdf_to_images\">পিডিএফ টু ইমেজ</string>\n    <string name=\"images_to_pdf\">পিডিএফে ছবি</string>\n    <string name=\"preview_pdf_sub\">সহজ পিডিএফ প্রিভিউ</string>\n    <string name=\"pdf_to_images_sub\">প্রদত্ত আউটপুট বিন্যাসে পিডিএফকে চিত্রগুলিতে রূপান্তর করুন</string>\n    <string name=\"images_to_pdf_sub\">প্রদত্ত চিত্রগুলিকে আউটপুট পিডিএফ ফাইলে প্যাক করুন</string>\n    <string name=\"mask_filter\">মাস্ক ফিল্টার</string>\n    <string name=\"mask_filter_sub\">প্রদত্ত মুখোশযুক্ত এলাকায় ফিল্টার চেইন প্রয়োগ করুন, প্রতিটি মুখোশ এলাকা তার নিজস্ব ফিল্টার সেট নির্ধারণ করতে পারে</string>\n    <string name=\"masks\">মুখোশ</string>\n    <string name=\"add_mask\">মাস্ক যোগ করুন</string>\n    <string name=\"mask_indexed\">মাস্ক %d</string>\n    <string name=\"mask_color\">মুখোশের রঙ</string>\n    <string name=\"mask_preview\">মাস্ক প্রিভিউ</string>\n    <string name=\"mask_preview_sub\">আপনাকে আনুমানিক ফলাফল দেখানোর জন্য আঁকা ফিল্টার মাস্ক রেন্ডার করা হবে</string>\n    <string name=\"inverse_fill_type\">ইনভার্স ফিল টাইপ</string>\n    <string name=\"inverse_fill_type_sub\">যদি সক্রিয় করা হয় তবে সমস্ত নন-মাস্কড এলাকাগুলি ডিফল্ট আচরণের পরিবর্তে ফিল্টার করা হবে</string>\n    <string name=\"delete_mask_warn\">আপনি নির্বাচিত ফিল্টার মাস্ক মুছে ফেলতে চলেছেন৷ এই অপারেশন পূর্বাবস্থায় ফেরানো যাবে না</string>\n    <string name=\"delete_mask\">মাস্ক মুছে দিন</string>\n    <string name=\"full_filter\">সম্পূর্ণ ফিল্টার</string>\n    <string name=\"full_filter_sub\">প্রদত্ত ইমেজ বা একক ছবিতে যেকোনো ফিল্টার চেইন প্রয়োগ করুন</string>\n    <string name=\"start_position\">শুরু করুন</string>\n    <string name=\"center_position\">কেন্দ্র</string>\n    <string name=\"end_position\">শেষ</string>\n    <string name=\"simple_variants\">সরল ভেরিয়েন্ট</string>\n    <string name=\"highlighter\">হাইলাইটার</string>\n    <string name=\"neon\">নিয়ন</string>\n    <string name=\"pen\">কলম</string>\n    <string name=\"privacy_blur\">গোপনীয়তা ঝাপসা</string>\n    <string name=\"highlighter_sub\">আধা-স্বচ্ছ ধারালো হাইলাইটার পাথ আঁকুন</string>\n    <string name=\"neon_sub\">আপনার আঁকা কিছু উজ্জ্বল প্রভাব যোগ করুন</string>\n    <string name=\"pen_sub\">ডিফল্ট এক, সহজতম - শুধু রঙ</string>\n    <string name=\"privacy_blur_sub\">আপনি যা কিছু লুকাতে চান তা সুরক্ষিত করতে আঁকা পথের নীচে ছবি ঝাপসা করে</string>\n    <string name=\"pixelation_sub\">প্রাইভেসি ব্লারের মতো, কিন্তু পিক্সেলেট ব্লার করার পরিবর্তে</string>\n    <string name=\"containers_shadow\">পাত্রে</string>\n    <string name=\"containers_shadow_sub\">পাত্রের পিছনে একটি ছায়া আঁকুন</string>\n    <string name=\"sliders_shadow\">স্লাইডার</string>\n    <string name=\"switches_shadow\">সুইচ</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">বোতাম</string>\n    <string name=\"sliders_shadow_sub\">স্লাইডারের পিছনে একটি ছায়া আঁকুন</string>\n    <string name=\"switches_shadow_sub\">সুইচের পিছনে একটি ছায়া আঁকুন</string>\n    <string name=\"fabs_shadow_sub\">ভাসমান অ্যাকশন বোতামের পিছনে একটি ছায়া আঁকুন</string>\n    <string name=\"buttons_shadow_sub\">বোতামের পিছনে একটি ছায়া আঁকুন</string>\n    <string name=\"app_bars_shadow\">অ্যাপ বার</string>\n    <string name=\"app_bars_shadow_sub\">অ্যাপ বারের পিছনে একটি ছায়া আঁকুন</string>\n    <string name=\"value_in_range\">পরিসরে মান %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">স্বয়ংক্রিয় ঘোরান</string>\n    <string name=\"auto_rotate_limits_sub\">ইমেজ ওরিয়েন্টেশনের জন্য সীমা বক্স গ্রহণ করার অনুমতি দেয়</string>\n    <string name=\"draw_path_mode\">পাথ মোড আঁকুন</string>\n    <string name=\"double_line_arrow\">ডাবল লাইন তীর</string>\n    <string name=\"free_drawing\">বিনামূল্যে অঙ্কন</string>\n    <string name=\"double_arrow\">ডাবল তীর</string>\n    <string name=\"line_arrow\">লাইন তীর</string>\n    <string name=\"arrow\">তীর</string>\n    <string name=\"line\">লাইন</string>\n    <string name=\"free_drawing_sub\">ইনপুট মান হিসাবে পাথ আঁকে</string>\n    <string name=\"line_sub\">একটি রেখা হিসাবে শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত পথ আঁকে</string>\n    <string name=\"line_arrow_sub\">একটি রেখা হিসাবে শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত নির্দেশক তীর আঁকে</string>\n    <string name=\"arrow_sub\">একটি প্রদত্ত পথ থেকে একটি নির্দেশক তীর আঁকে</string>\n    <string name=\"double_line_arrow_sub\">একটি লাইন হিসাবে শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত ডবল নির্দেশক তীর আঁকে</string>\n    <string name=\"double_arrow_sub\">একটি প্রদত্ত পথ থেকে দ্বিগুণ নির্দেশক তীর আঁকে</string>\n    <string name=\"outlined_oval\">রূপরেখা ওভাল</string>\n    <string name=\"outlined_rect\">আউটলাইন রেক্ট</string>\n    <string name=\"oval\">ওভাল</string>\n    <string name=\"rect\">রেক্ট</string>\n    <string name=\"rect_sub\">শুরুর বিন্দু থেকে শেষ বিন্দু পর্যন্ত আয়ত আঁকে</string>\n    <string name=\"oval_sub\">শুরু বিন্দু থেকে শেষ বিন্দু ডিম্বাকৃতি আঁকা</string>\n    <string name=\"outlined_oval_sub\">শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত রূপরেখা ডিম্বাকৃতি আঁকা</string>\n    <string name=\"outlined_rect_sub\">প্রারম্ভ বিন্দু থেকে শেষ বিন্দু পর্যন্ত আউটলাইন রেক্ট আঁকে</string>\n    <string name=\"lasso\">ল্যাসো</string>\n    <string name=\"lasso_sub\">প্রদত্ত পথ দ্বারা বদ্ধ ভরাট পথ আঁকে</string>\n    <string name=\"free\">বিনামূল্যে</string>\n    <string name=\"horizontal_grid\">অনুভূমিক গ্রিড</string>\n    <string name=\"vertical_grid\">উল্লম্ব গ্রিড</string>\n    <string name=\"stitch_mode\">স্টিচ মোড</string>\n    <string name=\"rows_count\">সারি গণনা</string>\n    <string name=\"columns_count\">কলাম সংখ্যা</string>\n    <string name=\"no_such_directory\">কোনো \\\"%1$s\\\" ডিরেক্টরি পাওয়া যায়নি, আমরা এটিকে ডিফল্টে স্যুইচ করেছি, অনুগ্রহ করে ফাইলটি আবার সংরক্ষণ করুন</string>\n    <string name=\"clipboard\">ক্লিপবোর্ড</string>\n    <string name=\"auto_pin\">অটো পিন</string>\n    <string name=\"auto_pin_sub\">সক্রিয় থাকলে স্বয়ংক্রিয়ভাবে ক্লিপবোর্ডে সংরক্ষিত ছবি যোগ করে</string>\n    <string name=\"vibration\">কম্পন</string>\n    <string name=\"vibration_strength\">কম্পন শক্তি</string>\n    <string name=\"overwrite_file_requirements\">ফাইলগুলিকে ওভাররাইট করার জন্য আপনাকে \\\"এক্সপ্লোরার\\\" ইমেজ সোর্স ব্যবহার করতে হবে, রিপিক ইমেজ চেষ্টা করুন, আমরা ইমেজ সোর্সকে প্রয়োজনীয় একটিতে পরিবর্তন করেছি</string>\n    <string name=\"overwrite_files\">ফাইল ওভাররাইট করুন</string>\n    <string name=\"overwrite_files_sub\">আসল ফাইলটি নির্বাচিত ফোল্ডারে সংরক্ষণ করার পরিবর্তে নতুন ফাইলের সাথে প্রতিস্থাপিত হবে, এই বিকল্পটিকে \\\"এক্সপ্লোরার\\\" বা GetContent হতে ইমেজ সোর্স করতে হবে, এটি টগল করার সময়, এটি স্বয়ংক্রিয়ভাবে সেট হয়ে যাবে</string>\n    <string name=\"empty\">খালি</string>\n    <string name=\"suffix\">প্রত্যয়</string>\n    <string name=\"scale_mode\">স্কেল মোড</string>\n    <string name=\"bilinear\">বিলিনিয়ার</string>\n    <string name=\"catmull\">ক্যাটমুল</string>\n    <string name=\"bicubic\">বিকিউবিক</string>\n    <string name=\"hann\">সে</string>\n    <string name=\"hermite\">সন্ন্যাসী</string>\n    <string name=\"lanczos\">ল্যাঙ্কজোস</string>\n    <string name=\"mitchell\">মিচেল</string>\n    <string name=\"nearest\">নিকটতম</string>\n    <string name=\"spline\">স্প্লাইন</string>\n    <string name=\"basic\">মৌলিক</string>\n    <string name=\"default_value\">ডিফল্ট মান</string>\n    <string name=\"bilinear_sub\">রৈখিক (বা বাইলিনিয়ার, দুই মাত্রায়) ইন্টারপোলেশন সাধারণত একটি চিত্রের আকার পরিবর্তনের জন্য ভাল, তবে বিশদ কিছু অবাঞ্ছিত নরম করে তোলে এবং এখনও কিছুটা জ্যাগড হতে পারে</string>\n    <string name=\"bicubic_sub\">ভালো স্কেলিং পদ্ধতির মধ্যে রয়েছে ল্যাঙ্কজোস রিস্যাম্পলিং এবং মিচেল-নেত্রাভালি ফিল্টার</string>\n    <string name=\"nearest_sub\">আকার বাড়ানোর সহজ উপায়গুলির মধ্যে একটি, প্রতিটি পিক্সেলকে একই রঙের একাধিক পিক্সেল দিয়ে প্রতিস্থাপন করা</string>\n    <string name=\"basic_sub\">সবচেয়ে সহজ অ্যান্ড্রয়েড স্কেলিং মোড যা প্রায় সব অ্যাপে ব্যবহৃত হয়</string>\n    <string name=\"catmull_sub\">মসৃণ বক্ররেখা তৈরি করতে সাধারণত কম্পিউটার গ্রাফিক্সে ব্যবহৃত নিয়ন্ত্রণ পয়েন্টগুলির একটি সেটকে মসৃণভাবে ইন্টারপোলেট করার এবং পুনরায় নমুনা করার পদ্ধতি</string>\n    <string name=\"hann_sub\">বর্ণালী ফুটো কমাতে এবং সংকেতের প্রান্তগুলিকে ছোট করে ফ্রিকোয়েন্সি বিশ্লেষণের নির্ভুলতা উন্নত করতে সিগন্যাল প্রসেসিং-এ প্রায়ই উইন্ডো করার ফাংশন প্রয়োগ করা হয়</string>\n    <string name=\"hermite_sub\">গাণিতিক ইন্টারপোলেশন কৌশল যা একটি মসৃণ এবং অবিচ্ছিন্ন বক্ররেখা তৈরি করতে একটি বক্র অংশের শেষ বিন্দুতে মান এবং ডেরিভেটিভ ব্যবহার করে</string>\n    <string name=\"lanczos_sub\">রিস্যাম্পলিং পদ্ধতি যা পিক্সেল মানগুলিতে একটি ওজনযুক্ত সিঙ্ক ফাংশন প্রয়োগ করে উচ্চ-মানের ইন্টারপোলেশন বজায় রাখে</string>\n    <string name=\"mitchell_sub\">রিস্যাম্পলিং পদ্ধতি যা স্কেল করা ছবিতে তীক্ষ্ণতা এবং অ্যান্টি-আলিয়াসিংয়ের মধ্যে ভারসাম্য অর্জন করতে সামঞ্জস্যযোগ্য প্যারামিটার সহ একটি কনভোলিউশন ফিল্টার ব্যবহার করে</string>\n    <string name=\"spline_sub\">নমনীয় এবং অবিচ্ছিন্ন আকৃতি উপস্থাপনা প্রদান করে, একটি বক্ররেখা বা পৃষ্ঠকে মসৃণভাবে প্রসারিত করতে এবং আনুমানিক করতে টুকরো টুকরো-সংজ্ঞায়িত বহুপদী ফাংশন ব্যবহার করে</string>\n    <string name=\"only_clip\">শুধুমাত্র ক্লিপ</string>\n    <string name=\"only_clip_sub\">সঞ্চয়স্থানে সংরক্ষণ করা হবে না, এবং ছবি শুধুমাত্র ক্লিপবোর্ডে রাখার চেষ্টা করা হবে</string>\n    <string name=\"restore_background_sub\">ব্রাশ মুছে ফেলার পরিবর্তে পটভূমি পুনরুদ্ধার করবে</string>\n    <string name=\"recognize_text\">ওসিআর (পাঠ্য সনাক্ত করুন)</string>\n    <string name=\"recognize_text_sub\">প্রদত্ত চিত্র থেকে পাঠ্য সনাক্ত করুন, 120+ ভাষা সমর্থিত</string>\n    <string name=\"picture_has_no_text\">ছবির কোন টেক্সট নেই, বা অ্যাপ এটি খুঁজে পায়নি</string>\n    <string name=\"accuracy\">\\\"নির্ভুলতা: %1$s\\\"</string>\n    <string name=\"recognition_type\">স্বীকৃতির ধরন</string>\n    <string name=\"fast\">দ্রুত</string>\n    <string name=\"standard\">স্ট্যান্ডার্ড</string>\n    <string name=\"best\">সেরা</string>\n    <string name=\"no_data\">কোন ডেটা নেই</string>\n    <string name=\"download_description\">Tesseract OCR অতিরিক্ত প্রশিক্ষণ ডেটা (%1$s) সঠিকভাবে কাজ করার জন্য আপনার ডিভাইসে ডাউনলোড করতে হবে৷\\nআপনি কি %2$s ডেটা ডাউনলোড করতে চান?</string>\n    <string name=\"download\">ডাউনলোড করুন</string>\n    <string name=\"no_connection\">কোনও সংযোগ নেই, এটি পরীক্ষা করুন এবং ট্রেনের মডেলগুলি ডাউনলোড করার জন্য আবার চেষ্টা করুন৷</string>\n    <string name=\"downloaded_languages\">ডাউনলোড করা ভাষা</string>\n    <string name=\"available_languages\">উপলব্ধ ভাষা</string>\n    <string name=\"segmentation_mode\">সেগমেন্টেশন মোড</string>\n    <string name=\"use_pixel_switch\">পিক্সেল সুইচ ব্যবহার করুন</string>\n    <string name=\"use_pixel_switch_sub\">একটি Google Pixel-এর মতো সুইচ ব্যবহার করে</string>\n    <string name=\"saved_to_original\">মূল গন্তব্যে %1$s নামের সাথে ওভাররাইট করা ফাইল</string>\n    <string name=\"magnifier\">ম্যাগনিফায়ার</string>\n    <string name=\"magnifier_sub\">আরও ভাল অ্যাক্সেসযোগ্যতার জন্য অঙ্কন মোডে আঙুলের শীর্ষে ম্যাগনিফায়ার সক্ষম করে৷</string>\n    <string name=\"force_exif_widget_initial_value\">প্রাথমিক মান জোর করুন</string>\n    <string name=\"force_exif_widget_initial_value_sub\">exif উইজেট প্রাথমিকভাবে চেক করতে বাধ্য করে</string>\n    <string name=\"allow_multiple_languages\">একাধিক ভাষার অনুমতি দিন</string>\n    <string name=\"slide\">স্লাইড</string>\n    <string name=\"side_by_side\">সাইড বাই সাইড</string>\n    <string name=\"toggle_tap\">টগল ট্যাপ করুন</string>\n    <string name=\"transparency\">স্বচ্ছতা</string>\n    <string name=\"rate_app\">অ্যাপকে রেট দিন</string>\n    <string name=\"rate\">হার</string>\n    <string name=\"rate_app_sub\">এই অ্যাপটি সম্পূর্ণ বিনামূল্যে, আপনি যদি এটিকে আরও বড় করতে চান, তাহলে অনুগ্রহ করে Github-এ প্রজেক্টটি স্টার করুন 😄</string>\n    <string name=\"segmentation_mode_osd_only\">শুধুমাত্র ওরিয়েন্টেশন ও স্ক্রিপ্ট ডিটেকশন</string>\n    <string name=\"segmentation_mode_auto_osd\">স্বয়ংক্রিয় অভিযোজন এবং স্ক্রিপ্ট সনাক্তকরণ</string>\n    <string name=\"segmentation_mode_auto_only\">শুধুমাত্র অটো</string>\n    <string name=\"segmentation_mode_auto\">অটো</string>\n    <string name=\"segmentation_mode_single_column\">একক কলাম</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">একক ব্লক উল্লম্ব পাঠ্য</string>\n    <string name=\"segmentation_mode_single_block\">একক ব্লক</string>\n    <string name=\"segmentation_mode_single_line\">একক লাইন</string>\n    <string name=\"segmentation_mode_single_word\">একক শব্দ</string>\n    <string name=\"segmentation_mode_circle_word\">বৃত্ত শব্দ</string>\n    <string name=\"segmentation_mode_single_char\">একক চর</string>\n    <string name=\"segmentation_mode_sparse_text\">স্পার্স টেক্সট</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">স্পার্স টেক্সট ওরিয়েন্টেশন এবং স্ক্রিপ্ট সনাক্তকরণ</string>\n    <string name=\"segmentation_mode_raw_line\">কাঁচা লাইন</string>\n    <string name=\"delete_language_sub\">আপনি কি সমস্ত স্বীকৃতি প্রকারের জন্য ভাষা \\\"%1$s\\\" OCR প্রশিক্ষণ ডেটা মুছতে চান, নাকি শুধুমাত্র নির্বাচিত একটি (%2$s) এর জন্য?</string>\n    <string name=\"current\">কারেন্ট</string>\n    <string name=\"all\">সব</string>\n    <string name=\"gradient_maker\">গ্রেডিয়েন্ট মেকার</string>\n    <string name=\"gradient_maker_sub\">কাস্টমাইজড রং এবং চেহারা টাইপ সহ প্রদত্ত আউটপুট আকারের গ্রেডিয়েন্ট তৈরি করুন</string>\n    <string name=\"gradient_type_linear\">রৈখিক</string>\n    <string name=\"gradient_type_radial\">রেডিয়াল</string>\n    <string name=\"gradient_type_sweep\">ঝাড়ু</string>\n    <string name=\"gradient_type\">গ্রেডিয়েন্ট টাইপ</string>\n    <string name=\"center_x\">কেন্দ্র এক্স</string>\n    <string name=\"center_y\">কেন্দ্র Y</string>\n    <string name=\"tile_mode\">টাইল মোড</string>\n    <string name=\"tile_mode_repeated\">বারবার</string>\n    <string name=\"tile_mode_mirror\">আয়না</string>\n    <string name=\"tile_mode_clamp\">বাতা</string>\n    <string name=\"tile_mode_decal\">ডেকাল</string>\n    <string name=\"color_stops\">রঙ স্টপ</string>\n    <string name=\"add_color\">রঙ যোগ করুন</string>\n    <string name=\"properties\">বৈশিষ্ট্য</string>\n    <string name=\"brightness_enforcement\">উজ্জ্বলতা প্রয়োগ</string>\n    <string name=\"screen\">পর্দা</string>\n    <string name=\"gradient_maker_type_image\">গ্রেডিয়েন্ট ওভারলে</string>\n    <string name=\"gradient_maker_type_image_sub\">প্রদত্ত চিত্রগুলির শীর্ষের যে কোনও গ্রেডিয়েন্ট রচনা করুন</string>\n    <string name=\"transformations\">রূপান্তর</string>\n    <string name=\"camera\">ক্যামেরা</string>\n    <string name=\"camera_sub\">ক্যামেরা দিয়ে ছবি তুলুন। উল্লেখ্য যে এই ইমেজ সোর্স থেকে শুধুমাত্র একটি ইমেজ পাওয়া সম্ভব</string>\n    <string name=\"watermarking\">ওয়াটারমার্কিং</string>\n    <string name=\"watermarking_sub\">কাস্টমাইজযোগ্য টেক্সট/ইমেজ ওয়াটারমার্ক দিয়ে ছবি কভার করুন</string>\n    <string name=\"repeat_watermark\">জলছাপ পুনরাবৃত্তি করুন</string>\n    <string name=\"repeat_watermark_sub\">প্রদত্ত অবস্থানে একক পরিবর্তে চিত্রের উপর জলছাপ পুনরাবৃত্তি করুন৷</string>\n    <string name=\"offset_x\">অফসেট এক্স</string>\n    <string name=\"offset_y\">অফসেট Y</string>\n    <string name=\"watermark_type\">ওয়াটারমার্ক টাইপ</string>\n    <string name=\"watermarking_image_sub\">এই ছবিটি ওয়াটারমার্কিং এর প্যাটার্ন হিসাবে ব্যবহার করা হবে</string>\n    <string name=\"text_color\">পাঠ্যের রঙ</string>\n    <string name=\"overlay_mode\">ওভারলে মোড</string>\n    <string name=\"gif_tools\">GIF টুলস</string>\n    <string name=\"gif_tools_sub\">ছবিগুলিকে GIF ছবিতে রূপান্তর করুন বা প্রদত্ত GIF ছবি থেকে ফ্রেমগুলি বের করুন৷</string>\n    <string name=\"gif_type_to_image\">ছবি থেকে GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF ফাইলকে ছবির ব্যাচে রূপান্তর করুন</string>\n    <string name=\"gif_type_to_gif_sub\">ছবির ব্যাচকে GIF ফাইলে রূপান্তর করুন</string>\n    <string name=\"gif_type_to_gif\">GIF-তে ছবি</string>\n    <string name=\"select_gif_image_to_start\">শুরু করতে GIF ছবি বাছুন</string>\n    <string name=\"use_size_of_first_frame\">প্রথম ফ্রেমের আকার ব্যবহার করুন</string>\n    <string name=\"use_size_of_first_frame_sub\">প্রথম ফ্রেমের মাত্রা দিয়ে নির্দিষ্ট আকার প্রতিস্থাপন করুন</string>\n    <string name=\"repeat_count\">পুনরাবৃত্তি গণনা</string>\n    <string name=\"frame_delay\">ফ্রেম বিলম্ব</string>\n    <string name=\"millis\">মিলি</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">ল্যাসো ব্যবহার করুন</string>\n    <string name=\"use_lasso_sub\">মুছে ফেলার জন্য অঙ্কন মোডের মতো ল্যাসো ব্যবহার করে</string>\n    <string name=\"original_image_preview_alpha\">আসল ছবি প্রিভিউ আলফা</string>\n    <string name=\"confetti\">কনফেটি</string>\n    <string name=\"confetti_sub\">কনফেটি সংরক্ষণ, ভাগ করে নেওয়া এবং অন্যান্য প্রাথমিক ক্রিয়াগুলিতে দেখানো হবে৷</string>\n    <string name=\"secure_mode\">নিরাপদ মোড</string>\n    <string name=\"secure_mode_sub\">সাম্প্রতিক অ্যাপে অ্যাপের বিষয়বস্তু লুকায়। এটা ক্যাপচার বা রেকর্ড করা যাবে না.</string>\n    <string name=\"exit\">প্রস্থান করুন</string>\n    <string name=\"preview_closing\">আপনি এখন পূর্বরূপ ছেড়ে গেলে, আপনাকে আবার ছবি যোগ করতে হবে</string>\n    <string name=\"dithering\">ডিথারিং</string>\n    <string name=\"quantizier\">কোয়ান্টাইজার</string>\n    <string name=\"gray_scale\">গ্রে স্কেল</string>\n    <string name=\"bayer_two_dithering\">বায়ার টু বাই টু ডিথারিং</string>\n    <string name=\"bayer_three_dithering\">বায়ার থ্রি বাই থ্রি ডিথারিং</string>\n    <string name=\"bayer_four_dithering\">বায়ার ফোর বাই ফোর ডিথারিং</string>\n    <string name=\"bayer_eight_dithering\">বায়ার এইট বাই এইট ডিথারিং</string>\n    <string name=\"floyd_steinberg_dithering\">ফ্লয়েড স্টেইনবার্গ ডিথারিং</string>\n    <string name=\"jarvis_judice_ninke_dithering\">জার্ভিস বিচারক নিঙ্কে ডিথারিং</string>\n    <string name=\"sierra_dithering\">সিয়েরা ডিথারিং</string>\n    <string name=\"two_row_sierra_dithering\">দুই সারি সিয়েরা ডিথারিং</string>\n    <string name=\"sierra_lite_dithering\">সিয়েরা লাইট ডিথারিং</string>\n    <string name=\"atkinson_dithering\">অ্যাটকিনসন ডিথারিং</string>\n    <string name=\"stucki_dithering\">স্টুকি ডিথারিং</string>\n    <string name=\"burkes_dithering\">বার্কস ডিথারিং</string>\n    <string name=\"false_floyd_steinberg_dithering\">মিথ্যা ফ্লয়েড স্টেইনবার্গ ডিথারিং</string>\n    <string name=\"left_to_right_dithering\">লেফট টু রাইট ডিথারিং</string>\n    <string name=\"random_dithering\">র‍্যান্ডম ডিথারিং</string>\n    <string name=\"simple_threshold_dithering\">সরল থ্রেশহোল্ড ডিথারিং</string>\n    <string name=\"sigma\">সিগমা</string>\n    <string name=\"spatial_sigma\">স্থানিক সিগমা</string>\n    <string name=\"median_blur\">মাঝারি ব্লার</string>\n    <string name=\"b_spline\">বি স্প্লাইন</string>\n    <string name=\"b_spline_sub\">একটি বক্ররেখা বা পৃষ্ঠ, নমনীয় এবং অবিচ্ছিন্ন আকৃতির উপস্থাপনাকে মসৃণভাবে প্রসারিত করতে এবং আনুমানিকভাবে আনুমানিকভাবে সংজ্ঞায়িত করতে পিসওয়াইজ-সংজ্ঞায়িত বাইকিউবিক বহুপদী ফাংশন ব্যবহার করে</string>\n    <string name=\"native_stack_blur\">নেটিভ স্ট্যাক ব্লার</string>\n    <string name=\"tilt_shift\">টিল্ট শিফট</string>\n    <string name=\"glitch\">গ্লিচ</string>\n    <string name=\"amount\">পরিমাণ</string>\n    <string name=\"seed\">বীজ</string>\n    <string name=\"anaglyph\">অ্যানাগ্লিফ</string>\n    <string name=\"noise\">গোলমাল</string>\n    <string name=\"pixel_sort\">পিক্সেল সাজান</string>\n    <string name=\"shuffle\">এলোমেলো</string>\n    <string name=\"enhanced_glitch\">বর্ধিত ত্রুটি</string>\n    <string name=\"channel_shift_x\">চ্যানেল শিফট এক্স</string>\n    <string name=\"channel_shift_y\">চ্যানেল শিফট ওয়াই</string>\n    <string name=\"corruption_size\">দুর্নীতির আকার</string>\n    <string name=\"corruption_shift_x\">দুর্নীতি শিফট এক্স</string>\n    <string name=\"corruption_shift_y\">দুর্নীতি শিফট Y</string>\n    <string name=\"tent_blur\">তাঁবুর অস্পষ্টতা</string>\n    <string name=\"side_fade\">সাইড ফেইড</string>\n    <string name=\"side\">পাশ</string>\n    <string name=\"top\">শীর্ষ</string>\n    <string name=\"bottom\">নীচে</string>\n    <string name=\"strength\">শক্তি</string>\n    <string name=\"erode\">ইরোড</string>\n    <string name=\"anisotropic_diffusion\">অ্যানিসোট্রপিক ডিফিউশন</string>\n    <string name=\"diffusion\">ডিফিউশন</string>\n    <string name=\"conduction\">সঞ্চালন</string>\n    <string name=\"horizontal_wind_stagger\">অনুভূমিক বায়ু স্তব্ধ</string>\n    <string name=\"fast_bilaterial_blur\">দ্রুত দ্বিপাক্ষিক ঝাপসা</string>\n    <string name=\"poisson_blur\">পয়সন ব্লার</string>\n    <string name=\"logarithmic_tone_mapping\">লগারিদমিক টোন ম্যাপিং</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES ফিল্মিক টোন ম্যাপিং</string>\n    <string name=\"crystallize\">স্ফটিক করা</string>\n    <string name=\"stroke_color\">স্ট্রোক রঙ</string>\n    <string name=\"fractal_glass\">ফ্র্যাক্টাল গ্লাস</string>\n    <string name=\"amplitude\">প্রশস্ততা</string>\n    <string name=\"marble\">মার্বেল</string>\n    <string name=\"turbulence\">অশান্তি</string>\n    <string name=\"oil\">তেল</string>\n    <string name=\"water_effect\">জলের প্রভাব</string>\n    <string name=\"just_size\">আকার</string>\n    <string name=\"frequency_x\">ফ্রিকোয়েন্সি এক্স</string>\n    <string name=\"frequency_y\">ফ্রিকোয়েন্সি Y</string>\n    <string name=\"amplitude_x\">প্রশস্ততা এক্স</string>\n    <string name=\"amplitude_y\">প্রশস্ততা Y</string>\n    <string name=\"perlin_distortion\">পার্লিন বিকৃতি</string>\n    <string name=\"aces_hill_tone_mapping\">ACES হিল টোন ম্যাপিং</string>\n    <string name=\"hable_filmic_tone_mapping\">হ্যাবল ফিল্মিক টোন ম্যাপিং</string>\n    <string name=\"heji_burgess_tone_mapping\">হেজি-বার্গেস টোন ম্যাপিং</string>\n    <string name=\"speed\">গতি</string>\n    <string name=\"dehaze\">দেহাজে</string>\n    <string name=\"omega\">ওমেগা</string>\n    <string name=\"color_matrix_4x4\">কালার ম্যাট্রিক্স 4x4</string>\n    <string name=\"color_matrix_3x3\">কালার ম্যাট্রিক্স 3x3</string>\n    <string name=\"simple_effects\">সহজ প্রভাব</string>\n    <string name=\"polaroid\">পোলারয়েড</string>\n    <string name=\"tritonomaly\">ট্রাইটানোমালি</string>\n    <string name=\"deutaromaly\">Deuteranomaly</string>\n    <string name=\"protonomaly\">প্রোটানোমালি</string>\n    <string name=\"vintage\">ভিনটেজ</string>\n    <string name=\"browni\">ব্রাউন এর</string>\n    <string name=\"coda_chrome\">কোডা ক্রোম</string>\n    <string name=\"night_vision\">নাইট ভিশন</string>\n    <string name=\"warm\">উষ্ণ</string>\n    <string name=\"cool\">কুল</string>\n    <string name=\"tritanopia\">ট্রাইটানোপিয়া</string>\n    <string name=\"deutaronotopia\">ডিউটারোনোটোপিয়া</string>\n    <string name=\"protanopia\">প্রোটানোপিয়া</string>\n    <string name=\"achromatomaly\">আক্রোমাটোমালি</string>\n    <string name=\"achromatopsia\">অ্যাক্রোমাটোপসিয়া</string>\n    <string name=\"grain\">শস্য</string>\n    <string name=\"unsharp\">আনশার্প</string>\n    <string name=\"pastel\">প্যাস্টেল</string>\n    <string name=\"orange_haze\">কমলা কুয়াশা</string>\n    <string name=\"pink_dream\">গোলাপী স্বপ্ন</string>\n    <string name=\"golden_hour\">গোল্ডেন আওয়ার</string>\n    <string name=\"hot_summer\">গরম গ্রীষ্ম</string>\n    <string name=\"purple_mist\">বেগুনি কুয়াশা</string>\n    <string name=\"sunrise\">সূর্যোদয়</string>\n    <string name=\"colorful_swirl\">রঙিন ঘূর্ণি</string>\n    <string name=\"soft_spring_light\">নরম বসন্তের আলো</string>\n    <string name=\"autumn_tones\">শরতের টোন</string>\n    <string name=\"lavender_dream\">ল্যাভেন্ডার স্বপ্ন</string>\n    <string name=\"cyberpunk\">সাইবারপাঙ্ক</string>\n    <string name=\"lemonade_light\">লেমনেড লাইট</string>\n    <string name=\"spectral_fire\">স্পেকট্রাল ফায়ার</string>\n    <string name=\"night_magic\">নাইট ম্যাজিক</string>\n    <string name=\"fantasy_landscape\">ফ্যান্টাসি ল্যান্ডস্কেপ</string>\n    <string name=\"color_explosion\">রঙের বিস্ফোরণ</string>\n    <string name=\"electric_gradient\">বৈদ্যুতিক গ্রেডিয়েন্ট</string>\n    <string name=\"caramel_darkness\">ক্যারামেল ডার্কনেস</string>\n    <string name=\"futuristic_gradient\">ফিউচারিস্টিক গ্রেডিয়েন্ট</string>\n    <string name=\"green_sun\">সবুজ সূর্য</string>\n    <string name=\"rainbow_world\">রংধনু বিশ্ব</string>\n    <string name=\"deep_purple\">গভীর বেগুনি</string>\n    <string name=\"space_portal\">স্পেস পোর্টাল</string>\n    <string name=\"red_swirl\">লাল ঘূর্ণি</string>\n    <string name=\"digital_code\">ডিজিটাল কোড</string>\n    <string name=\"bokeh\">বোকেহ</string>\n    <string name=\"random_emojis_sub\">অ্যাপ বার ইমোজি এলোমেলোভাবে পরিবর্তন হবে</string>\n    <string name=\"random_emojis\">এলোমেলো ইমোজিস</string>\n    <string name=\"random_emojis_error\">ইমোজি অক্ষম থাকা অবস্থায় আপনি র্যান্ডম ইমোজি ব্যবহার করতে পারবেন না</string>\n    <string name=\"emoji_selection_error\">র্যান্ডম ইমোজি সক্রিয় থাকা অবস্থায় আপনি একটি ইমোজি নির্বাচন করতে পারবেন না</string>\n    <string name=\"old_tv\">পুরাতন টিভি</string>\n    <string name=\"shuffle_blur\">এলোমেলো ঝাপসা</string>\n    <string name=\"favorite\">প্রিয়</string>\n    <string name=\"no_favorite_filters\">এখনও কোন প্রিয় ফিল্টার যোগ করা হয়নি</string>\n    <string name=\"image_format\">ইমেজ ফরম্যাট</string>\n    <string name=\"icon_shape_sub\">আইকনগুলির অধীনে নির্বাচিত আকৃতি সহ একটি ধারক যোগ করে</string>\n    <string name=\"icon_shape\">আইকন আকৃতি</string>\n    <string name=\"drago\">ড্রাগো</string>\n    <string name=\"aldridge\">অ্যালড্রিজ</string>\n    <string name=\"cutoff\">কাটঅফ</string>\n    <string name=\"uchimura\">আপনি জেগে উঠুন</string>\n    <string name=\"mobius\">মবিয়াস</string>\n    <string name=\"transition\">উত্তরণ</string>\n    <string name=\"peak\">পিক</string>\n    <string name=\"color_anomaly\">রঙের অসঙ্গতি</string>\n    <string name=\"images_overwritten\">মূল গন্তব্যে ছবিগুলি ওভাররাইট করা হয়েছে</string>\n    <string name=\"cannot_change_image_format\">ওভাররাইট ফাইল অপশন সক্রিয় থাকা অবস্থায় ইমেজ ফরম্যাট পরিবর্তন করা যাবে না</string>\n    <string name=\"emoji_as_color_scheme\">কালার স্কিম হিসেবে ইমোজি</string>\n    <string name=\"emoji_as_color_scheme_sub\">ম্যানুয়ালি সংজ্ঞায়িত একটির পরিবর্তে অ্যাপের রঙ স্কিম হিসাবে ইমোজি প্রাথমিক রঙ ব্যবহার করে</string>\n    <string name=\"material_you_sub\">ইমেজ থেকে ম্যাটেরিয়াল ইউ প্যালেট তৈরি করে</string>\n    <string name=\"dark_colors\">গাঢ় রং</string>\n    <string name=\"dark_colors_sub\">হালকা বৈকল্পিক পরিবর্তে নাইট মোড রঙের স্কিম ব্যবহার করে</string>\n    <string name=\"copy_as_compose_code\">জেটপ্যাক কম্পোজ কোড হিসাবে অনুলিপি করুন</string>\n    <string name=\"ring_blur\">রিং ব্লার</string>\n    <string name=\"cross_blur\">ক্রস ব্লার</string>\n    <string name=\"circle_blur\">বৃত্ত ঝাপসা</string>\n    <string name=\"star_blur\">স্টার ব্লার</string>\n    <string name=\"linear_tilt_shift\">লিনিয়ার টিল্ট-শিফট</string>\n    <string name=\"tags_to_remove\">ট্যাগ অপসারণ</string>\n    <string name=\"apng_tools\">APNG টুলস</string>\n    <string name=\"apng_tools_sub\">ছবিগুলিকে APNG ছবিতে রূপান্তর করুন বা প্রদত্ত APNG ছবি থেকে ফ্রেমগুলি বের করুন৷</string>\n    <string name=\"apng_type_to_image\">ছবি APNG</string>\n    <string name=\"apng_type_to_image_sub\">APNG ফাইলকে ছবির ব্যাচে রূপান্তর করুন</string>\n    <string name=\"apng_type_to_apng_sub\">ছবির ব্যাচকে APNG ফাইলে রূপান্তর করুন</string>\n    <string name=\"apng_type_to_apng\">APNG-তে ছবি</string>\n    <string name=\"select_apng_image_to_start\">শুরু করতে APNG ছবি বেছে নিন</string>\n    <string name=\"motion_blur\">মোশন ব্লার</string>\n    <string name=\"zip\">জিপ</string>\n    <string name=\"zip_sub\">প্রদত্ত ফাইল বা ছবি থেকে Zip ফাইল তৈরি করুন</string>\n    <string name=\"drag_handle_width\">হ্যান্ডেল প্রস্থ টেনে আনুন</string>\n    <string name=\"confetti_type\">কনফেটি টাইপ</string>\n    <string name=\"festive\">উৎসব</string>\n    <string name=\"explode\">বিস্ফোরণ</string>\n    <string name=\"rain\">বৃষ্টি</string>\n    <string name=\"corners\">কোণ</string>\n    <string name=\"jxl_tools\">JXL টুলস</string>\n    <string name=\"jxl_tools_sub\">কোন মানের ক্ষতি ছাড়াই JXL ~ JPEG ট্রান্সকোডিং সম্পাদন করুন, অথবা GIF/APNG কে JXL অ্যানিমেশনে রূপান্তর করুন</string>\n    <string name=\"jxl_type_to_jpeg\">JXL থেকে JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL থেকে JPEG তে ক্ষতিহীন ট্রান্সকোডিং করুন</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG থেকে JXL পর্যন্ত ক্ষতিহীন ট্রান্সকোডিং সম্পাদন করুন</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG থেকে JXL</string>\n    <string name=\"select_jxl_image_to_start\">শুরু করতে JXL ছবি বাছুন</string>\n    <string name=\"fast_gaussian_blur_2d\">দ্রুত গাউসিয়ান ব্লার 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">দ্রুত গাউসিয়ান ব্লার 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">দ্রুত গাউসিয়ান ব্লার 4D</string>\n    <string name=\"auto_paste\">গাড়ী ইস্টার</string>\n    <string name=\"auto_paste_sub\">অ্যাপটিকে ক্লিপবোর্ড ডেটা স্বয়ংক্রিয়ভাবে আটকানোর অনুমতি দেয়, তাই এটি প্রধান স্ক্রিনে প্রদর্শিত হবে এবং আপনি এটি প্রক্রিয়া করতে সক্ষম হবেন৷</string>\n    <string name=\"harmonization_color\">হারমোনাইজেশন রঙ</string>\n    <string name=\"harmonization_level\">হারমোনাইজেশন লেভেল</string>\n    <string name=\"lanczos_bessel\">ল্যাঙ্কজোস বেসেল</string>\n    <string name=\"lanczos_bessel_sub\">রিস্যাম্পলিং পদ্ধতি যা পিক্সেল মানগুলিতে বেসেল (জিঙ্ক) ফাংশন প্রয়োগ করে উচ্চ-মানের ইন্টারপোলেশন বজায় রাখে</string>\n    <string name=\"gif_type_to_jxl\">JXL থেকে GIF</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF ছবিগুলিকে JXL অ্যানিমেটেড ছবিতে রূপান্তর করুন</string>\n    <string name=\"apng_type_to_jxl\">APNG থেকে JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG ছবিকে JXL অ্যানিমেটেড ছবিতে রূপান্তর করুন</string>\n    <string name=\"jxl_type_to_images\">ইমেজ থেকে JXL</string>\n    <string name=\"jxl_type_to_images_sub\">JXL অ্যানিমেশনকে ছবির ব্যাচে রূপান্তর করুন</string>\n    <string name=\"jxl_type_to_jxl\">JXL-এ ছবি</string>\n    <string name=\"jxl_type_to_jxl_sub\">ছবির ব্যাচকে JXL অ্যানিমেশনে রূপান্তর করুন</string>\n    <string name=\"behavior\">আচরণ</string>\n    <string name=\"skip_file_picking\">ফাইল পিকিং এড়িয়ে যান</string>\n    <string name=\"skip_file_picking_sub\">নির্বাচিত স্ক্রিনে এটি সম্ভব হলে ফাইল পিকার অবিলম্বে দেখানো হবে</string>\n    <string name=\"generate_previews\">প্রিভিউ তৈরি করুন</string>\n    <string name=\"generate_previews_sub\">পূর্বরূপ জেনারেশন সক্ষম করে, এটি কিছু ডিভাইসে ক্র্যাশ এড়াতে সাহায্য করতে পারে, এটি একক সম্পাদনা বিকল্পের মধ্যে কিছু সম্পাদনা কার্যকারিতা অক্ষম করে</string>\n    <string name=\"lossy_compression\">ক্ষতিকারক কম্প্রেশন</string>\n    <string name=\"lossy_compression_sub\">লসলেস এর পরিবর্তে ফাইলের আকার কমাতে ক্ষতিকর কম্প্রেশন ব্যবহার করে</string>\n    <string name=\"compression_type\">কম্প্রেশন টাইপ</string>\n    <string name=\"speed_sub\">ফলস্বরূপ ইমেজ ডিকোডিং গতি নিয়ন্ত্রণ করে, এটি ফলস্বরূপ চিত্রটি দ্রুত খুলতে সাহায্য করবে, %1$s এর মান হল সবচেয়ে ধীরগতির ডিকোডিং, যেখানে %2$s - দ্রুততম, এই সেটিংটি আউটপুট চিত্রের আকার বাড়াতে পারে</string>\n    <string name=\"sorting\">বাছাই</string>\n    <string name=\"sort_by_date\">তারিখ</string>\n    <string name=\"sort_by_date_reversed\">তারিখ (বিপরীত)</string>\n    <string name=\"sort_by_name\">নাম</string>\n    <string name=\"sort_by_name_reversed\">নাম (বিপরীত)</string>\n    <string name=\"channels_configuration\">চ্যানেল কনফিগারেশন</string>\n    <string name=\"header_today\">আজ</string>\n    <string name=\"header_yesterday\">গতকাল</string>\n    <string name=\"embedded_picker\">এমবেডেড পিকার</string>\n    <string name=\"embedded_picker_sub\">ইমেজ টুলবক্সের ইমেজ পিকার</string>\n    <string name=\"no_permissions\">কোন অনুমতি নেই</string>\n    <string name=\"request\">অনুরোধ</string>\n    <string name=\"pick_multiple_media\">একাধিক মিডিয়া বাছুন</string>\n    <string name=\"pick_single_media\">একক মিডিয়া বাছুন</string>\n    <string name=\"pick\">বাছাই</string>\n    <string name=\"try_again\">আবার চেষ্টা করুন</string>\n    <string name=\"show_settings_in_landscape\">ল্যান্ডস্কেপে সেটিংস দেখান</string>\n    <string name=\"show_settings_in_landscape_sub\">যদি এটি অক্ষম করা হয় তবে স্থায়ী দৃশ্যমান বিকল্পের পরিবর্তে ল্যান্ডস্কেপ মোডে সেটিংস বরাবরের মতো উপরের অ্যাপ বারে বোতামে খোলা হবে</string>\n    <string name=\"fullscreen_settings\">ফুলস্ক্রিন সেটিংস</string>\n    <string name=\"fullscreen_settings_sub\">এটি সক্ষম করুন এবং সেটিংস পৃষ্ঠা সর্বদা স্লাইডযোগ্য ড্রয়ার শীটের পরিবর্তে ফুলস্ক্রিন হিসাবে খোলা হবে</string>\n    <string name=\"switch_type\">সুইচ টাইপ</string>\n    <string name=\"compose\">রচনা করুন</string>\n    <string name=\"compose_switch_sub\">একটি Jetpack রচনা উপাদান আপনি সুইচ</string>\n    <string name=\"material_you_switch_sub\">একটি উপাদান আপনি সুইচ</string>\n    <string name=\"max\">সর্বোচ্চ</string>\n    <string name=\"resize_anchor\">অ্যাঙ্করের আকার পরিবর্তন করুন</string>\n    <string name=\"pixel_switch\">পিক্সেল</string>\n    <string name=\"fluent_switch\">সাবলীল</string>\n    <string name=\"fluent_switch_sub\">\\\"ফ্লুয়েন্ট\\\" ডিজাইন সিস্টেমের উপর ভিত্তি করে একটি সুইচ</string>\n    <string name=\"cupertino_switch\">কুপারটিনো</string>\n    <string name=\"cupertino_switch_sub\">\\\"Cupertino\\\" ডিজাইন সিস্টেমের উপর ভিত্তি করে একটি সুইচ</string>\n    <string name=\"images_to_svg\">SVG-তে ছবি</string>\n    <string name=\"images_to_svg_sub\">SVG চিত্রগুলিতে প্রদত্ত চিত্রগুলি ট্রেস করুন৷</string>\n    <string name=\"use_sampled_palette\">নমুনা প্যালেট ব্যবহার করুন</string>\n    <string name=\"use_sampled_palette_sub\">এই বিকল্পটি সক্রিয় থাকলে কোয়ান্টাইজেশন প্যালেট নমুনা করা হবে</string>\n    <string name=\"path_omit\">পথ বাদ দাও</string>\n    <string name=\"svg_warning\">ডাউনস্কেলিং ছাড়াই বড় ছবি ট্রেস করার জন্য এই টুলের ব্যবহার বাঞ্ছনীয় নয়, এটি ক্র্যাশ হতে পারে এবং প্রক্রিয়াকরণের সময় বাড়াতে পারে</string>\n    <string name=\"downscale_image\">ডাউনস্কেল চিত্র</string>\n    <string name=\"downscale_image_sub\">প্রক্রিয়াকরণের আগে চিত্রটি নিম্ন মাত্রায় স্কেল করা হবে, এটি সরঞ্জামটিকে দ্রুত এবং নিরাপদে কাজ করতে সহায়তা করে</string>\n    <string name=\"min_color_ratio\">ন্যূনতম রঙের অনুপাত</string>\n    <string name=\"lines_threshold\">লাইন থ্রেশহোল্ড</string>\n    <string name=\"quadratic_threshold\">চতুর্মুখী থ্রেশহোল্ড</string>\n    <string name=\"coordinates_rounding_tolerance\">বৃত্তাকার সহনশীলতা স্থানাঙ্ক</string>\n    <string name=\"path_scale\">পাথ স্কেল</string>\n    <string name=\"reset_properties\">বৈশিষ্ট্য রিসেট করুন</string>\n    <string name=\"reset_properties_sub\">সমস্ত বৈশিষ্ট্য ডিফল্ট মানগুলিতে সেট করা হবে, লক্ষ্য করুন যে এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না৷</string>\n    <string name=\"detailed\">বিস্তারিত</string>\n    <string name=\"default_line_width\">ডিফল্ট লাইন প্রস্থ</string>\n    <string name=\"engine_mode\">ইঞ্জিন মোড</string>\n    <string name=\"legacy\">উত্তরাধিকার</string>\n    <string name=\"lstm_network\">LSTM নেটওয়ার্ক</string>\n    <string name=\"legacy_and_lstm\">উত্তরাধিকার এবং LSTM</string>\n    <string name=\"convert\">রূপান্তর করুন</string>\n    <string name=\"convert_sub\">প্রদত্ত বিন্যাসে ইমেজ ব্যাচ রূপান্তর করুন</string>\n    <string name=\"add_new_folder\">নতুন ফোল্ডার যোগ করুন</string>\n    <string name=\"tag_bits_per_sample\">নমুনা প্রতি বিট</string>\n    <string name=\"tag_compression\">কম্প্রেশন</string>\n    <string name=\"tag_photometric_interpretation\">ফটোমেট্রিক ব্যাখ্যা</string>\n    <string name=\"tag_samples_per_pixel\">পিক্সেল প্রতি নমুনা</string>\n    <string name=\"tag_planar_configuration\">প্ল্যানার কনফিগারেশন</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr সাব স্যাম্পলিং</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr পজিশনিং</string>\n    <string name=\"tag_x_resolution\">এক্স রেজোলিউশন</string>\n    <string name=\"tag_y_resolution\">Y রেজোলিউশন</string>\n    <string name=\"tag_resolution_unit\">রেজোলিউশন ইউনিট</string>\n    <string name=\"tag_strip_offsets\">স্ট্রিপ অফসেট</string>\n    <string name=\"tag_rows_per_strip\">স্ট্রিপ প্রতি সারি</string>\n    <string name=\"tag_strip_byte_counts\">স্ট্রিপ বাইট গণনা</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG ইন্টারচেঞ্জ ফরম্যাট</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG ইন্টারচেঞ্জ ফরম্যাটের দৈর্ঘ্য</string>\n    <string name=\"tag_transfer_function\">স্থানান্তর ফাংশন</string>\n    <string name=\"tag_white_point\">হোয়াইট পয়েন্ট</string>\n    <string name=\"tag_primary_chromaticities\">প্রাথমিক ক্রোমাটিসিটিস</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr সহগ</string>\n    <string name=\"tag_reference_black_white\">রেফারেন্স কালো সাদা</string>\n    <string name=\"tag_datetime\">তারিখ সময়</string>\n    <string name=\"tag_image_description\">ছবির বর্ণনা</string>\n    <string name=\"tag_make\">তৈরি করুন</string>\n    <string name=\"tag_model\">মডেল</string>\n    <string name=\"tag_software\">সফটওয়্যার</string>\n    <string name=\"tag_artist\">শিল্পী</string>\n    <string name=\"tag_copyright\">কপিরাইট</string>\n    <string name=\"tag_exif_version\">এক্সিফ সংস্করণ</string>\n    <string name=\"tag_flashpix_version\">ফ্ল্যাশপিক্স সংস্করণ</string>\n    <string name=\"tag_color_space\">রঙের স্থান</string>\n    <string name=\"tag_gamma\">গামা</string>\n    <string name=\"tag_pixel_x_dimension\">পিক্সেল এক্স ডাইমেনশন</string>\n    <string name=\"tag_pixel_y_dimension\">পিক্সেল ওয়াই ডাইমেনশন</string>\n    <string name=\"tag_compressed_bits_per_pixel\">পিক্সেল প্রতি সংকুচিত বিট</string>\n    <string name=\"tag_maker_note\">মেকার নোট</string>\n    <string name=\"tag_user_comment\">ব্যবহারকারী মন্তব্য</string>\n    <string name=\"tag_related_sound_file\">সম্পর্কিত শব্দ ফাইল</string>\n    <string name=\"tag_datetime_original\">তারিখ সময় মূল</string>\n    <string name=\"tag_datetime_digitized\">তারিখ সময় ডিজিটালাইজড</string>\n    <string name=\"tag_offset_time\">অফসেট সময়</string>\n    <string name=\"tag_offset_time_original\">অফসেট সময় আসল</string>\n    <string name=\"tag_offset_time_digitized\">অফসেট সময় ডিজিটালাইজড</string>\n    <string name=\"tag_subsec_time\">সাব সেকেন্ড সময়</string>\n    <string name=\"tag_subsec_time_original\">সাব সেকেন্ড সময় মূল</string>\n    <string name=\"tag_subsec_time_digitized\">সাব সেকেন্ড টাইম ডিজিটালাইজড</string>\n    <string name=\"tag_exposure_time\">প্রকাশের সময়</string>\n    <string name=\"tag_f_number\">F নম্বর</string>\n    <string name=\"tag_exposure_program\">এক্সপোজার প্রোগ্রাম</string>\n    <string name=\"tag_spectral_sensitivity\">বর্ণালী সংবেদনশীলতা</string>\n    <string name=\"tag_photographic_sensitivity\">ফটোগ্রাফিক সংবেদনশীলতা</string>\n    <string name=\"tag_oecf\">ওইসিএফ</string>\n    <string name=\"tag_sensitivity_type\">সংবেদনশীলতার ধরন</string>\n    <string name=\"tag_standard_output_sensitivity\">স্ট্যান্ডার্ড আউটপুট সংবেদনশীলতা</string>\n    <string name=\"tag_recommended_exposure_index\">প্রস্তাবিত এক্সপোজার সূচক</string>\n    <string name=\"tag_iso_speed\">আইএসও গতি</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO গতি অক্ষাংশ yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO গতি অক্ষাংশ zzz</string>\n    <string name=\"tag_shutter_speed_value\">শাটার গতির মান</string>\n    <string name=\"tag_aperture_value\">অ্যাপারচার মান</string>\n    <string name=\"tag_brightness_value\">উজ্জ্বলতার মান</string>\n    <string name=\"tag_exposure_bias_value\">এক্সপোজার বায়াস মান</string>\n    <string name=\"tag_max_aperture_value\">সর্বোচ্চ অ্যাপারচার মান</string>\n    <string name=\"tag_subject_distance\">বিষয় দূরত্ব</string>\n    <string name=\"tag_metering_mode\">মিটারিং মোড</string>\n    <string name=\"tag_flash\">ফ্ল্যাশ</string>\n    <string name=\"tag_subject_area\">বিষয় এলাকা</string>\n    <string name=\"tag_focal_length\">ফোকাল দৈর্ঘ্য</string>\n    <string name=\"tag_flash_energy\">ফ্ল্যাশ এনার্জি</string>\n    <string name=\"tag_spatial_frequency_response\">স্থানিক ফ্রিকোয়েন্সি প্রতিক্রিয়া</string>\n    <string name=\"tag_focal_plane_x_resolution\">ফোকাল প্লেন এক্স রেজোলিউশন</string>\n    <string name=\"tag_focal_plane_y_resolution\">ফোকাল প্লেন ওয়াই রেজোলিউশন</string>\n    <string name=\"tag_focal_plane_resolution_unit\">ফোকাল প্লেন রেজোলিউশন ইউনিট</string>\n    <string name=\"tag_subject_location\">বিষয় অবস্থান</string>\n    <string name=\"tag_exposure_index\">এক্সপোজার সূচক</string>\n    <string name=\"tag_sensing_method\">সেন্সিং পদ্ধতি</string>\n    <string name=\"tag_file_source\">ফাইল উৎস</string>\n    <string name=\"tag_cfa_pattern\">CFA প্যাটার্ন</string>\n    <string name=\"tag_custom_rendered\">কাস্টম রেন্ডার করা</string>\n    <string name=\"tag_exposure_mode\">এক্সপোজার মোড</string>\n    <string name=\"tag_white_balance\">হোয়াইট ব্যালেন্স</string>\n    <string name=\"tag_digital_zoom_ratio\">ডিজিটাল জুম অনুপাত</string>\n    <string name=\"tag_focal_length_in_35mm_film\">ফোকাল দৈর্ঘ্য ইন 35 মিমি ফিল্ম</string>\n    <string name=\"tag_scene_capture_type\">দৃশ্য ক্যাপচার টাইপ</string>\n    <string name=\"tag_gain_control\">নিয়ন্ত্রণ লাভ করুন</string>\n    <string name=\"tag_contrast\">বৈপরীত্য</string>\n    <string name=\"tag_saturation\">স্যাচুরেশন</string>\n    <string name=\"tag_sharpness\">তীক্ষ্ণতা</string>\n    <string name=\"tag_device_setting_description\">ডিভাইস সেটিং বর্ণনা</string>\n    <string name=\"tag_subject_distance_range\">বিষয় দূরত্ব পরিসীমা</string>\n    <string name=\"tag_image_unique_id\">ইমেজ ইউনিক আইডি</string>\n    <string name=\"tag_camera_owner_name\">ক্যামেরার মালিকের নাম</string>\n    <string name=\"tag_body_serial_number\">বডি সিরিয়াল নম্বর</string>\n    <string name=\"tag_lens_specification\">লেন্স স্পেসিফিকেশন</string>\n    <string name=\"tag_lens_make\">লেন্স তৈরি করুন</string>\n    <string name=\"tag_lens_model\">লেন্স মডেল</string>\n    <string name=\"tag_lens_serial_number\">লেন্স সিরিয়াল নম্বর</string>\n    <string name=\"tag_gps_version_id\">জিপিএস সংস্করণ আইডি</string>\n    <string name=\"tag_gps_latitude_ref\">GPS অক্ষাংশ রেফ</string>\n    <string name=\"tag_gps_latitude\">জিপিএস অক্ষাংশ</string>\n    <string name=\"tag_gps_longitude_ref\">GPS দ্রাঘিমাংশ রেফ</string>\n    <string name=\"tag_gps_longitude\">GPS দ্রাঘিমাংশ</string>\n    <string name=\"tag_gps_altitude_ref\">জিপিএস উচ্চতা রেফ</string>\n    <string name=\"tag_gps_altitude\">জিপিএস উচ্চতা</string>\n    <string name=\"tag_gps_timestamp\">জিপিএস টাইম স্ট্যাম্প</string>\n    <string name=\"tag_gps_satellites\">জিপিএস স্যাটেলাইট</string>\n    <string name=\"tag_gps_status\">জিপিএস স্ট্যাটাস</string>\n    <string name=\"tag_gps_measure_mode\">GPS পরিমাপ মোড</string>\n    <string name=\"tag_gps_dop\">জিপিএস ডিওপি</string>\n    <string name=\"tag_gps_speed_ref\">জিপিএস গতি রেফ</string>\n    <string name=\"tag_gps_speed\">জিপিএস গতি</string>\n    <string name=\"tag_gps_track_ref\">জিপিএস ট্র্যাক রেফ</string>\n    <string name=\"tag_gps_track\">জিপিএস ট্র্যাক</string>\n    <string name=\"tag_gps_img_direction_ref\">জিপিএস আইএমজি দিক নির্দেশনা</string>\n    <string name=\"tag_gps_img_direction\">জিপিএস আইএমজি দিকনির্দেশ</string>\n    <string name=\"tag_gps_map_datum\">GPS মানচিত্র তথ্য</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS গন্তব্য অক্ষাংশ</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS গন্তব্য দ্রাঘিমাংশ রেফ</string>\n    <string name=\"tag_gps_dest_longitude\">GPS গন্তব্য দ্রাঘিমাংশ</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS ডেস্ট বিয়ারিং রেফ</string>\n    <string name=\"tag_gps_dest_bearing\">জিপিএস ডেস্ট বিয়ারিং</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS গন্তব্য দূরত্ব রেফ</string>\n    <string name=\"tag_gps_dest_distance\">GPS গন্তব্য দূরত্ব</string>\n    <string name=\"tag_gps_processing_method\">জিপিএস প্রক্রিয়াকরণ পদ্ধতি</string>\n    <string name=\"tag_gps_area_information\">জিপিএস এলাকার তথ্য</string>\n    <string name=\"tag_gps_datestamp\">GPS তারিখ স্ট্যাম্প</string>\n    <string name=\"tag_gps_differential\">জিপিএস ডিফারেনশিয়াল</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H পজিশনিং ত্রুটি৷</string>\n    <string name=\"tag_interoperability_index\">ইন্টারঅপারেবিলিটি সূচক</string>\n    <string name=\"tag_dng_version\">DNG সংস্করণ</string>\n    <string name=\"tag_default_crop_size\">ডিফল্ট ক্রপ সাইজ</string>\n    <string name=\"tag_orf_preview_image_start\">পূর্বরূপ চিত্র শুরু</string>\n    <string name=\"tag_orf_preview_image_length\">পূর্বরূপ চিত্র দৈর্ঘ্য</string>\n    <string name=\"tag_orf_aspect_frame\">দৃষ্টিভঙ্গি ফ্রেম</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">সেন্সর নিচের সীমানা</string>\n    <string name=\"tag_rw2_sensor_left_border\">সেন্সর বাম সীমানা</string>\n    <string name=\"tag_rw2_sensor_right_border\">সেন্সর ডান বর্ডার</string>\n    <string name=\"tag_rw2_sensor_top_border\">সেন্সর টপ বর্ডার</string>\n    <string name=\"tag_rw2_iso\">আইএসও</string>\n    <string name=\"draw_text_sub\">প্রদত্ত ফন্ট এবং রঙ দিয়ে পাথে পাঠ্য আঁকুন</string>\n    <string name=\"font_size\">ফন্ট সাইজ</string>\n    <string name=\"watermark_size\">ওয়াটারমার্ক সাইজ</string>\n    <string name=\"repeat_text\">টেক্সট পুনরাবৃত্তি করুন</string>\n    <string name=\"repeat_text_sub\">এক সময় আঁকার পরিবর্তে পাথ শেষ না হওয়া পর্যন্ত বর্তমান পাঠ্য পুনরাবৃত্তি করা হবে</string>\n    <string name=\"dash_size\">ড্যাশ সাইজ</string>\n    <string name=\"draw_mode_image_sub\">প্রদত্ত পথ বরাবর এটি আঁকার জন্য নির্বাচিত ছবি ব্যবহার করুন</string>\n    <string name=\"draw_image_sub\">এই চিত্রটি আঁকা পথের পুনরাবৃত্তিমূলক এন্ট্রি হিসাবে ব্যবহার করা হবে</string>\n    <string name=\"outlined_triangle_sub\">শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত রূপরেখাযুক্ত ত্রিভুজ আঁকে</string>\n    <string name=\"triangle_sub\">শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত রূপরেখাযুক্ত ত্রিভুজ আঁকে</string>\n    <string name=\"outlined_triangle\">রূপরেখাযুক্ত ত্রিভুজ</string>\n    <string name=\"triangle\">ত্রিভুজ</string>\n    <string name=\"polygon_sub\">শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত বহুভুজ আঁকে</string>\n    <string name=\"polygon\">বহুভুজ</string>\n    <string name=\"outlined_polygon\">আউটলাইন করা বহুভুজ</string>\n    <string name=\"outlined_polygon_sub\">প্রারম্ভ বিন্দু থেকে শেষ বিন্দু পর্যন্ত রূপরেখা বহুভুজ আঁকে</string>\n    <string name=\"vertices\">শীর্ষবিন্দু</string>\n    <string name=\"draw_regular_polygon\">নিয়মিত বহুভুজ আঁকুন</string>\n    <string name=\"draw_regular_polygon_sub\">বহুভুজ আঁকুন যা ফ্রি ফর্মের পরিবর্তে নিয়মিত হবে</string>\n    <string name=\"star_sub\">শুরু বিন্দু থেকে শেষ বিন্দু পর্যন্ত তারকা আঁকা</string>\n    <string name=\"star\">তারা</string>\n    <string name=\"outlined_star\">আউটলাইন স্টার</string>\n    <string name=\"outlined_star_sub\">সূচনা বিন্দু থেকে শেষ বিন্দু পর্যন্ত রূপরেখাযুক্ত তারা আঁকে</string>\n    <string name=\"inner_radius_ratio\">অভ্যন্তরীণ ব্যাসার্ধ অনুপাত</string>\n    <string name=\"draw_regular_star\">নিয়মিত তারা আঁকুন</string>\n    <string name=\"draw_regular_star_sub\">স্টার আঁকুন যা ফ্রি ফর্মের পরিবর্তে নিয়মিত হবে</string>\n    <string name=\"antialias\">অ্যান্টিলিয়াস</string>\n    <string name=\"antialias_sub\">তীক্ষ্ণ প্রান্ত প্রতিরোধ করতে অ্যান্টিলিয়াসিং সক্ষম করে</string>\n    <string name=\"open_edit_instead_of_preview\">পূর্বরূপের পরিবর্তে সম্পাদনা খুলুন</string>\n    <string name=\"open_edit_instead_of_preview_sub\">আপনি যখন ইমেজটুলবক্সে খোলার জন্য (প্রিভিউ) ছবি নির্বাচন করেন, তখন পূর্বরূপ দেখার পরিবর্তে সম্পাদনা নির্বাচন শীট খোলা হবে</string>\n    <string name=\"document_scanner\">ডকুমেন্ট স্ক্যানার</string>\n    <string name=\"document_scanner_sub\">নথি স্ক্যান করুন এবং পিডিএফ তৈরি করুন বা তাদের থেকে আলাদা ছবি তৈরি করুন</string>\n    <string name=\"click_to_start_scanning\">স্ক্যানিং শুরু করতে ক্লিক করুন</string>\n    <string name=\"start_scanning\">স্ক্যান করা শুরু করুন</string>\n    <string name=\"save_as_pdf\">পিডিএফ হিসাবে সংরক্ষণ করুন</string>\n    <string name=\"share_as_pdf\">পিডিএফ হিসাবে শেয়ার করুন</string>\n    <string name=\"options_below_is_for_images\">নীচের বিকল্পগুলি ছবি সংরক্ষণের জন্য, PDF নয়</string>\n    <string name=\"equalize_histogram_hsv\">হিস্টোগ্রাম HSV সমান করুন</string>\n    <string name=\"equalize_histogram\">হিস্টোগ্রামকে সমান করুন</string>\n    <string name=\"enter_percentage\">শতাংশ লিখুন</string>\n    <string name=\"allow_enter_by_text_field\">পাঠ্য ক্ষেত্র দ্বারা প্রবেশের অনুমতি দিন</string>\n    <string name=\"allow_enter_by_text_field_sub\">প্রিসেট নির্বাচনের পিছনে পাঠ্য ক্ষেত্র সক্ষম করে, ফ্লাইতে সেগুলি প্রবেশ করতে</string>\n    <string name=\"scale_color_space\">স্কেল রঙের স্থান</string>\n    <string name=\"linear\">রৈখিক</string>\n    <string name=\"equalize_histogram_pixelation\">হিস্টোগ্রাম পিক্সেলেশন সমান করুন</string>\n    <string name=\"grid_size_x\">গ্রিড সাইজ এক্স</string>\n    <string name=\"grid_size_y\">গ্রিড সাইজ Y</string>\n    <string name=\"equalize_histogram_adaptive\">হিস্টোগ্রাম অভিযোজিত সমান করুন</string>\n    <string name=\"equalize_histogram_adaptive_luv\">হিস্টোগ্রাম অভিযোজিত LUV সমান করুন</string>\n    <string name=\"equalize_histogram_adaptive_lab\">হিস্টোগ্রাম অভিযোজিত LAB সমান করুন</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE ল্যাব</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">সামগ্রীতে ক্রপ করুন</string>\n    <string name=\"frame_color\">ফ্রেমের রঙ</string>\n    <string name=\"color_to_ignore\">উপেক্ষা করার জন্য রঙ</string>\n    <string name=\"template\">টেমপ্লেট</string>\n    <string name=\"no_template_filters\">কোন টেমপ্লেট ফিল্টার যোগ করা হয়নি</string>\n    <string name=\"create_new\">নতুন তৈরি করুন</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">স্ক্যান করা QR কোড একটি বৈধ ফিল্টার টেমপ্লেট নয়</string>\n    <string name=\"scan_qr_code\">QR কোড স্ক্যান করুন</string>\n    <string name=\"opened_file_have_no_filter_template\">নির্বাচিত ফাইলে কোনো ফিল্টার টেমপ্লেট ডেটা নেই</string>\n    <string name=\"create_template\">টেমপ্লেট তৈরি করুন</string>\n    <string name=\"template_name\">টেমপ্লেট নাম</string>\n    <string name=\"select_template_preview\">এই ছবিটি এই ফিল্টার টেমপ্লেটের পূর্বরূপ দেখতে ব্যবহার করা হবে</string>\n    <string name=\"template_filter\">টেমপ্লেট ফিল্টার</string>\n    <string name=\"as_qr_code\">QR কোড ইমেজ হিসাবে</string>\n    <string name=\"as_file\">ফাইল হিসাবে</string>\n    <string name=\"save_as_file\">ফাইল হিসাবে সংরক্ষণ করুন</string>\n    <string name=\"save_as_qr_code_image\">QR কোড ইমেজ হিসাবে সংরক্ষণ করুন</string>\n    <string name=\"delete_template\">টেমপ্লেট মুছুন</string>\n    <string name=\"delete_template_warn\">আপনি নির্বাচিত টেমপ্লেট ফিল্টার মুছে ফেলতে চলেছেন৷ এই অপারেশন পূর্বাবস্থায় ফেরানো যাবে না</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) নামের সাথে ফিল্টার টেমপ্লেট যোগ করা হয়েছে</string>\n    <string name=\"filter_preview\">ফিল্টার প্রিভিউ</string>\n    <string name=\"qr_code\">QR এবং বারকোড</string>\n    <string name=\"qr_code_sub\">QR কোড স্ক্যান করুন এবং এর বিষয়বস্তু পান বা নতুন একটি তৈরি করতে আপনার স্ট্রিং পেস্ট করুন</string>\n    <string name=\"code_content\">কোড বিষয়বস্তু</string>\n    <string name=\"scan_qr_code_to_replace_content\">ক্ষেত্রের বিষয়বস্তু প্রতিস্থাপন করতে যেকোনো বারকোড স্ক্যান করুন, বা নির্বাচিত প্রকারের সাথে নতুন বারকোড তৈরি করতে কিছু টাইপ করুন</string>\n    <string name=\"qr_description\">QR বর্ণনা</string>\n    <string name=\"min\">মিন</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR কোড স্ক্যান করার জন্য সেটিংসে ক্যামেরার অনুমতি দিন</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">ডকুমেন্ট স্ক্যানার স্ক্যান করতে সেটিংসে ক্যামেরার অনুমতি দিন</string>\n    <string name=\"cubic\">ঘন</string>\n    <string name=\"bspline\">বি-স্পলাইন</string>\n    <string name=\"hamming\">হ্যামিং</string>\n    <string name=\"hanning\">হ্যানিং</string>\n    <string name=\"blackman\">ব্ল্যাকম্যান</string>\n    <string name=\"welch\">ওয়েলচ</string>\n    <string name=\"quadric\">কোয়াড্রিক</string>\n    <string name=\"gaussian\">গাউসিয়ান</string>\n    <string name=\"sphinx\">স্ফিংক্স</string>\n    <string name=\"bartlett\">বার্টলেট</string>\n    <string name=\"robidoux\">রবিডক্স</string>\n    <string name=\"robidoux_sharp\">রবিডক্স শার্প</string>\n    <string name=\"spline16\">স্প্লাইন 16</string>\n    <string name=\"spline36\">স্প্লাইন 36</string>\n    <string name=\"spline64\">স্প্লাইন 64</string>\n    <string name=\"kaiser\">কায়সার</string>\n    <string name=\"bartlett_hann\">বার্টলেট-হি</string>\n    <string name=\"box\">বক্স</string>\n    <string name=\"bohman\">বোহমান</string>\n    <string name=\"lanczos2\">ল্যাঙ্কজোস 2</string>\n    <string name=\"lanczos3\">ল্যাঙ্কজোস ঘ</string>\n    <string name=\"lanczos4\">ল্যাঙ্কজোস 4</string>\n    <string name=\"lanczos2_jinc\">ল্যাঙ্কজোস 2 জিঙ্ক</string>\n    <string name=\"lanczos3_jinc\">ল্যাঙ্কজোস 3 জিঙ্ক</string>\n    <string name=\"lanczos4_jinc\">ল্যাঙ্কজোস 4 জিঙ্ক</string>\n    <string name=\"cubic_sub\">কিউবিক ইন্টারপোলেশন নিকটতম 16 পিক্সেল বিবেচনা করে মসৃণ স্কেলিং প্রদান করে, বাইলিনিয়ারের চেয়ে ভাল ফলাফল দেয়</string>\n    <string name=\"bspline_sub\">একটি বক্ররেখা বা পৃষ্ঠ, নমনীয় এবং অবিচ্ছিন্ন আকৃতির উপস্থাপনাকে মসৃণভাবে ইন্টারপোলেট এবং আনুমানিক করতে টুকরো টুকরো-সংজ্ঞায়িত বহুপদী ফাংশন ব্যবহার করে</string>\n    <string name=\"hamming_sub\">একটি উইন্ডো ফাংশন সিগন্যালের প্রান্তগুলিকে টেপার করে বর্ণালী ফুটো কমাতে ব্যবহৃত হয়, সিগন্যাল প্রক্রিয়াকরণে দরকারী</string>\n    <string name=\"hanning_sub\">হ্যান উইন্ডোর একটি রূপ, সাধারণত সিগন্যাল প্রসেসিং অ্যাপ্লিকেশনগুলিতে বর্ণালী ফুটো কমাতে ব্যবহৃত হয়</string>\n    <string name=\"blackman_sub\">একটি উইন্ডো ফাংশন যা বর্ণালী ফুটো কমিয়ে ভাল ফ্রিকোয়েন্সি রেজোলিউশন প্রদান করে, প্রায়শই সংকেত প্রক্রিয়াকরণে ব্যবহৃত হয়</string>\n    <string name=\"welch_sub\">কম বর্ণালী ফুটো সহ ভাল ফ্রিকোয়েন্সি রেজোলিউশন দেওয়ার জন্য ডিজাইন করা একটি উইন্ডো ফাংশন, প্রায়শই সংকেত প্রক্রিয়াকরণ অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়</string>\n    <string name=\"quadric_sub\">একটি পদ্ধতি যা ইন্টারপোলেশনের জন্য একটি দ্বিঘাত ফাংশন ব্যবহার করে, মসৃণ এবং অবিচ্ছিন্ন ফলাফল প্রদান করে</string>\n    <string name=\"gaussian_sub\">একটি ইন্টারপোলেশন পদ্ধতি যা একটি গাউসিয়ান ফাংশন প্রয়োগ করে, চিত্রগুলিকে মসৃণ এবং কমানোর জন্য দরকারী</string>\n    <string name=\"sphinx_sub\">একটি উন্নত রিস্যাম্পলিং পদ্ধতি যা ন্যূনতম আর্টিফ্যাক্ট সহ উচ্চ-মানের ইন্টারপোলেশন প্রদান করে</string>\n    <string name=\"bartlett_sub\">বর্ণালী ফুটো কমাতে সংকেত প্রক্রিয়াকরণে ব্যবহৃত একটি ত্রিভুজাকার উইন্ডো ফাংশন</string>\n    <string name=\"robidoux_sub\">প্রাকৃতিক চিত্রের আকার পরিবর্তন, তীক্ষ্ণতা এবং মসৃণতা ভারসাম্যের জন্য অপ্টিমাইজ করা একটি উচ্চ-মানের ইন্টারপোলেশন পদ্ধতি</string>\n    <string name=\"robidoux_sharp_sub\">রবিডক্স পদ্ধতির একটি তীক্ষ্ণ বৈকল্পিক, খাস্তা চিত্রের আকার পরিবর্তনের জন্য অপ্টিমাইজ করা হয়েছে</string>\n    <string name=\"spline16_sub\">একটি স্প্লাইন-ভিত্তিক ইন্টারপোলেশন পদ্ধতি যা একটি 16-ট্যাপ ফিল্টার ব্যবহার করে মসৃণ ফলাফল প্রদান করে</string>\n    <string name=\"spline36_sub\">একটি স্প্লাইন-ভিত্তিক ইন্টারপোলেশন পদ্ধতি যা একটি 36-ট্যাপ ফিল্টার ব্যবহার করে মসৃণ ফলাফল প্রদান করে</string>\n    <string name=\"spline64_sub\">একটি স্প্লাইন-ভিত্তিক ইন্টারপোলেশন পদ্ধতি যা একটি 64-ট্যাপ ফিল্টার ব্যবহার করে মসৃণ ফলাফল প্রদান করে</string>\n    <string name=\"kaiser_sub\">একটি ইন্টারপোলেশন পদ্ধতি যা কায়সার উইন্ডো ব্যবহার করে, প্রধান-লোব প্রস্থ এবং পার্শ্ব-লোব স্তরের মধ্যে ট্রেড-অফের উপর ভাল নিয়ন্ত্রণ প্রদান করে</string>\n    <string name=\"bartlett_hann_sub\">বার্টলেট এবং হ্যান উইন্ডোর সমন্বয়ে একটি হাইব্রিড উইন্ডো ফাংশন, সিগন্যাল প্রক্রিয়াকরণে বর্ণালী ফুটো কমাতে ব্যবহৃত</string>\n    <string name=\"box_sub\">একটি সাধারণ রিস্যাম্পলিং পদ্ধতি যা নিকটতম পিক্সেল মানগুলির গড় ব্যবহার করে, প্রায়শই একটি ব্লকি চেহারার ফলে</string>\n    <string name=\"bohman_sub\">বর্ণালী ফুটো কমাতে ব্যবহৃত একটি উইন্ডো ফাংশন, সিগন্যাল প্রসেসিং অ্যাপ্লিকেশনগুলিতে ভাল ফ্রিকোয়েন্সি রেজোলিউশন প্রদান করে</string>\n    <string name=\"lanczos2_sub\">একটি রিস্যাম্পলিং পদ্ধতি যা 2-লোব ল্যাঙ্কজোস ফিল্টার ব্যবহার করে ন্যূনতম আর্টিফ্যাক্ট সহ উচ্চ-মানের ইন্টারপোলেশনের জন্য</string>\n    <string name=\"lanczos3_sub\">একটি রিস্যাম্পলিং পদ্ধতি যা ন্যূনতম নিদর্শন সহ উচ্চ-মানের ইন্টারপোলেশনের জন্য একটি 3-লোব ল্যাঙ্কজোস ফিল্টার ব্যবহার করে</string>\n    <string name=\"lanczos4_sub\">একটি রিস্যাম্পলিং পদ্ধতি যা 4-লোব ল্যাঙ্কজোস ফিল্টার ব্যবহার করে ন্যূনতম আর্টিফ্যাক্ট সহ উচ্চ-মানের ইন্টারপোলেশনের জন্য</string>\n    <string name=\"lanczos2_jinc_sub\">ল্যাঙ্কজোস 2 ফিল্টারের একটি বৈকল্পিক যা জিঙ্ক ফাংশন ব্যবহার করে, ন্যূনতম শিল্পকর্মের সাথে উচ্চ-মানের ইন্টারপোলেশন প্রদান করে</string>\n    <string name=\"lanczos3_jinc_sub\">ল্যাঙ্কজোস 3 ফিল্টারের একটি বৈকল্পিক যা জিঙ্ক ফাংশন ব্যবহার করে, ন্যূনতম শিল্পকর্মের সাথে উচ্চ-মানের ইন্টারপোলেশন প্রদান করে</string>\n    <string name=\"lanczos4_jinc_sub\">ল্যাঙ্কজোস 4 ফিল্টারের একটি বৈকল্পিক যা জিঙ্ক ফাংশন ব্যবহার করে, ন্যূনতম শিল্পকর্মের সাথে উচ্চ-মানের ইন্টারপোলেশন প্রদান করে</string>\n    <string name=\"ewa_hanning\">হ্যানিং EWA</string>\n    <string name=\"ewa_hanning_sub\">মসৃণ ইন্টারপোলেশন এবং রিস্যাম্পলিং এর জন্য হ্যানিং ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">উচ্চ মানের পুনঃনমুনাকরণের জন্য রবিডক্স ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_blackman\">ব্ল্যাকম্যান ইভ</string>\n    <string name=\"ewa_blackman_sub\">রিংিং আর্টিফ্যাক্টগুলি কমানোর জন্য ব্ল্যাকম্যান ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_quadric\">কোয়াড্রিক EWA</string>\n    <string name=\"ewa_quadric_sub\">মসৃণ ইন্টারপোলেশনের জন্য কোয়াড্রিক ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux শার্প EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">তীক্ষ্ণ ফলাফলের জন্য রবিডক্স শার্প ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">ল্যাঙ্কজোস 3 জিঙ্ক ফিল্টারের উপবৃত্তাকার ওয়েটেড এভারেজ (EWA) ভেরিয়েন্ট কম অ্যালিয়াসিং সহ উচ্চ-মানের রিস্যাম্পলিং এর জন্য</string>\n    <string name=\"ginseng\">জিনসেং</string>\n    <string name=\"ginseng_sub\">তীক্ষ্ণতা এবং মসৃণতার একটি ভাল ভারসাম্য সহ উচ্চ-মানের চিত্র প্রক্রিয়াকরণের জন্য ডিজাইন করা একটি রিস্যাম্পলিং ফিল্টার</string>\n    <string name=\"ewa_ginseng\">জিনসেং ইডব্লিউএ</string>\n    <string name=\"ewa_ginseng_sub\">উন্নত চিত্রের গুণমানের জন্য জিনসেং ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos শার্প EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">ন্যূনতম শিল্পকর্মের সাথে তীক্ষ্ণ ফলাফল অর্জনের জন্য ল্যাঙ্কজোস শার্প ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 শার্পেস্ট EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">অত্যন্ত তীক্ষ্ণ চিত্র পুনরায় নমুনা করার জন্য ল্যাঙ্কজোস 4 শার্পেস্ট ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"ewa_lanczos_soft\">ল্যাঙ্কজোস সফট ইডব্লিউএ</string>\n    <string name=\"ewa_lanczos_soft_sub\">মসৃণ চিত্র পুনরায় নমুনা করার জন্য ল্যাঙ্কজোস সফট ফিল্টারের উপবৃত্তাকার ওজনযুক্ত গড় (EWA) রূপ</string>\n    <string name=\"haasn_soft\">হাসন নরম</string>\n    <string name=\"haasn_soft_sub\">মসৃণ এবং আর্টিফ্যাক্ট-মুক্ত ইমেজ স্কেলিং এর জন্য হাসান দ্বারা ডিজাইন করা একটি রিস্যাম্পলিং ফিল্টার</string>\n    <string name=\"format_conversion\">ফর্ম্যাট রূপান্তর</string>\n    <string name=\"format_conversion_sub\">এক বিন্যাস থেকে অন্য বিন্যাসে চিত্রের ব্যাচ রূপান্তর করুন</string>\n    <string name=\"dismiss_forever\">চিরতরে বরখাস্ত করুন</string>\n    <string name=\"image_stacking\">ইমেজ স্ট্যাকিং</string>\n    <string name=\"image_stacking_sub\">নির্বাচিত মিশ্রণ মোডগুলির সাথে একে অপরের উপরে ছবিগুলিকে স্ট্যাক করুন৷</string>\n    <string name=\"add_image\">ছবি যোগ করুন</string>\n    <string name=\"bins_count\">বিন গণনা</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">হিস্টোগ্রাম অভিযোজিত HSL সমান করুন</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">হিস্টোগ্রাম অভিযোজিত HSV সমান করুন</string>\n    <string name=\"edge_mode\">এজ মোড</string>\n    <string name=\"clip\">ক্লিপ</string>\n    <string name=\"wrap\">মোড়ানো</string>\n    <string name=\"color_blind_scheme\">বর্ণান্ধতা</string>\n    <string name=\"color_blind_scheme_sub\">নির্বাচিত রঙ অন্ধত্ব বৈকল্পিক জন্য থিম রং মানিয়ে মোড নির্বাচন করুন</string>\n    <string name=\"protanomaly_sub\">লাল এবং সবুজ রঙের মধ্যে পার্থক্য করতে অসুবিধা</string>\n    <string name=\"deuteranomaly_sub\">সবুজ এবং লাল রঙের মধ্যে পার্থক্য করতে অসুবিধা</string>\n    <string name=\"tritanomaly_sub\">নীল এবং হলুদ রঙের মধ্যে পার্থক্য করতে অসুবিধা</string>\n    <string name=\"protanopia_sub\">লাল রং বোঝার অক্ষমতা</string>\n    <string name=\"deuteranopia_sub\">সবুজ রং উপলব্ধি করতে অক্ষমতা</string>\n    <string name=\"tritanopia_sub\">নীল রং উপলব্ধি করতে অক্ষমতা</string>\n    <string name=\"achromatomaly_sub\">সমস্ত রং সংবেদনশীলতা হ্রাস</string>\n    <string name=\"achromatopsia_sub\">সম্পূর্ণ বর্ণান্ধতা, শুধুমাত্র ধূসর শেড দেখা</string>\n    <string name=\"not_use_color_blind_scheme\">কালার ব্লাইন্ড স্কিম ব্যবহার করবেন না</string>\n    <string name=\"not_use_color_blind_scheme_sub\">রঙ ঠিক থিমে সেট করা হবে</string>\n    <string name=\"sigmoidal\">সিগময়েডাল</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">অর্ডার 2 এর একটি Lagrange ইন্টারপোলেশন ফিল্টার, মসৃণ রূপান্তর সহ উচ্চ-মানের চিত্র স্কেলিং এর জন্য উপযুক্ত</string>\n    <string name=\"lagrange_3\">ল্যাগ্রেঞ্জ ঘ</string>\n    <string name=\"lagrange_3_sub\">অর্ডার 3 এর একটি ল্যাগ্রেঞ্জ ইন্টারপোলেশন ফিল্টার, ইমেজ স্কেলিং এর জন্য আরও ভাল নির্ভুলতা এবং মসৃণ ফলাফল প্রদান করে</string>\n    <string name=\"lanczos_6\">ল্যাঙ্কজোস 6</string>\n    <string name=\"lanczos_6_sub\">একটি ল্যাঙ্কজোস রিস্যাম্পলিং ফিল্টার 6 এর উচ্চ ক্রম সহ, তীক্ষ্ণ এবং আরও সঠিক চিত্র স্কেলিং প্রদান করে</string>\n    <string name=\"lanczos_6_jinc\">ল্যাঙ্কজোস 6 জিঙ্ক</string>\n    <string name=\"lanczos_6_jinc_sub\">উন্নত ইমেজ রিস্যাম্পলিং মানের জন্য জিঙ্ক ফাংশন ব্যবহার করে ল্যাঙ্কজোস 6 ফিল্টারের একটি বৈকল্পিক</string>\n    <string name=\"linear_box_blur\">লিনিয়ার বক্স ব্লার</string>\n    <string name=\"linear_tent_blur\">লিনিয়ার টেন্ট ব্লার</string>\n    <string name=\"linear_gaussian_box_blur\">লিনিয়ার গাউসিয়ান বক্স ব্লার</string>\n    <string name=\"linear_stack_blur\">লিনিয়ার স্ট্যাক ব্লার</string>\n    <string name=\"gaussian_box_blur\">গাউসিয়ান বক্স ব্লার</string>\n    <string name=\"linear_fast_gaussian_blur_next\">লিনিয়ার ফাস্ট গাউসিয়ান ব্লার নেক্সট</string>\n    <string name=\"linear_fast_gaussian_blur\">লিনিয়ার ফাস্ট গাউসিয়ান ব্লার</string>\n    <string name=\"linear_gaussian_blur\">লিনিয়ার গাউসিয়ান ব্লার</string>\n    <string name=\"draw_filter_sub\">পেইন্ট হিসাবে এটি ব্যবহার করার জন্য একটি ফিল্টার চয়ন করুন</string>\n    <string name=\"replace_filter\">ফিল্টার প্রতিস্থাপন করুন</string>\n    <string name=\"pick_filter_info\">আপনার অঙ্কনে ব্রাশ হিসাবে এটি ব্যবহার করতে নীচের ফিল্টারটি চয়ন করুন</string>\n    <string name=\"tiff_compression_scheme\">টিআইএফএফ কম্প্রেশন স্কিম</string>\n    <string name=\"low_poly\">নিম্ন পলি</string>\n    <string name=\"sand_painting\">বালি পেইন্টিং</string>\n    <string name=\"image_splitting\">ইমেজ স্প্লিটিং</string>\n    <string name=\"image_splitting_sub\">সারি বা কলাম দ্বারা একক ছবি বিভক্ত করুন</string>\n    <string name=\"fit_to_bounds\">ফিট টু বাউন্ডস</string>\n    <string name=\"fit_to_bounds_sub\">পছন্দসই আচরণ অর্জন করতে এই প্যারামিটারের সাথে ক্রপ রিসাইজ মোড একত্রিত করুন (আসপেক্ট রেশিওতে ক্রপ/ফিট করুন)</string>\n    <string name=\"languages_imported\">ভাষাগুলি সফলভাবে আমদানি করা হয়েছে৷</string>\n    <string name=\"backup_ocr_models\">OCR মডেলের ব্যাকআপ</string>\n    <string name=\"import_word\">আমদানি</string>\n    <string name=\"export\">রপ্তানি</string>\n    <string name=\"position\">অবস্থান</string>\n    <string name=\"center\">কেন্দ্র</string>\n    <string name=\"top_left\">উপরের বাম</string>\n    <string name=\"top_right\">উপরে ডান</string>\n    <string name=\"bottom_left\">নীচে বাম</string>\n    <string name=\"bottom_right\">নীচে ডান</string>\n    <string name=\"top_center\">শীর্ষ কেন্দ্র</string>\n    <string name=\"center_right\">কেন্দ্র ডান</string>\n    <string name=\"bottom_center\">নীচে কেন্দ্র</string>\n    <string name=\"center_left\">কেন্দ্র বাম</string>\n    <string name=\"target_image\">টার্গেট ইমেজ</string>\n    <string name=\"palette_transfer\">প্যালেট স্থানান্তর</string>\n    <string name=\"enhanced_oil\">উন্নত তেল</string>\n    <string name=\"simple_old_tv\">সাধারণ পুরানো টিভি</string>\n    <string name=\"hdr\">এইচডিআর</string>\n    <string name=\"gotham\">গোথাম</string>\n    <string name=\"simple_sketch\">সহজ স্কেচ</string>\n    <string name=\"soft_glow\">নরম আভা</string>\n    <string name=\"color_poster\">রঙিন পোস্টার</string>\n    <string name=\"tri_tone\">ট্রাই টোন</string>\n    <string name=\"third_color\">তৃতীয় রঙ</string>\n    <string name=\"clahe_oklab\">ক্লাহে ওকলাব</string>\n    <string name=\"clahe_oklch\">ক্লারা ওলচ</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">পোলকা ডট</string>\n    <string name=\"clustered_2x2_dithering\">ক্লাস্টারড 2x2 ডিথারিং</string>\n    <string name=\"clustered_4x4_dithering\">ক্লাস্টারড 4x4 ডিথারিং</string>\n    <string name=\"clustered_8x8_dithering\">ক্লাস্টারড 8x8 ডিথারিং</string>\n    <string name=\"yililoma_dithering\">ইলিলোমা ডিথারিং</string>\n    <string name=\"no_favorite_options_selected\">কোন পছন্দসই বিকল্প নির্বাচন করা হয়নি, সেগুলিকে টুল পৃষ্ঠায় যোগ করুন</string>\n    <string name=\"add_favorites\">ফেভারিট যোগ করুন</string>\n    <string name=\"harmony_complementary\">পরিপূরক</string>\n    <string name=\"harmony_analogous\">সাদৃশ্যপূর্ণ</string>\n    <string name=\"harmony_triadic\">ট্রায়াডিক</string>\n    <string name=\"harmony_split_complementary\">বিভক্ত পরিপূরক</string>\n    <string name=\"harmony_tetradic\">টেট্রাডিক</string>\n    <string name=\"harmony_square\">বর্গক্ষেত্র</string>\n    <string name=\"harmony_analogous_complementary\">সাদৃশ্য + পরিপূরক</string>\n    <string name=\"color_tools\">কালার টুলস</string>\n    <string name=\"color_tools_sub\">মিশ্রিত করুন, টোন তৈরি করুন, শেড তৈরি করুন এবং আরও অনেক কিছু</string>\n    <string name=\"color_harmonies\">কালার হারমোনিস</string>\n    <string name=\"color_shading\">কালার শেডিং</string>\n    <string name=\"variation\">প্রকরণ</string>\n    <string name=\"tints\">টিন্টস</string>\n    <string name=\"tones\">টোন</string>\n    <string name=\"shades\">শেডস</string>\n    <string name=\"color_mixing\">রঙের মিশ্রণ</string>\n    <string name=\"color_info\">রঙের তথ্য</string>\n    <string name=\"selected_color\">নির্বাচিত রঙ</string>\n    <string name=\"color_to_mix\">মিশ্রিত রং</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">গতিশীল রং চালু থাকা অবস্থায় monet ব্যবহার করা যাবে না</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">লক্ষ্য LUT চিত্র</string>\n    <string name=\"amatorka\">একজন অপেশাদার</string>\n    <string name=\"miss_etikate\">মিস শিষ্টাচার</string>\n    <string name=\"soft_elegance\">নরম কমনীয়তা</string>\n    <string name=\"soft_elegance_variant\">নরম কমনীয়তা বৈকল্পিক</string>\n    <string name=\"palette_transfer_variant\">প্যালেট স্থানান্তর বৈকল্পিক</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">টার্গেট 3D LUT ফাইল (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">ব্লিচ বাইপাস</string>\n    <string name=\"candlelight\">মোমবাতির আলো</string>\n    <string name=\"drop_blues\">ড্রপ ব্লুজ</string>\n    <string name=\"edgy_amber\">এজি অ্যাম্বার</string>\n    <string name=\"fall_colors\">পতন রং</string>\n    <string name=\"film_stock_50\">ফিল্ম স্টক 50</string>\n    <string name=\"foggy_night\">কুয়াশাচ্ছন্ন রাত</string>\n    <string name=\"kodak\">কোডাক</string>\n    <string name=\"save_empty_lut\">নিরপেক্ষ LUT ইমেজ পান</string>\n    <string name=\"save_empty_lut_sub\">প্রথমে, নিরপেক্ষ LUT এ একটি ফিল্টার প্রয়োগ করতে আপনার প্রিয় ফটো এডিটিং অ্যাপ্লিকেশনটি ব্যবহার করুন যা আপনি এখানে পেতে পারেন। এটি সঠিকভাবে কাজ করার জন্য প্রতিটি পিক্সেল রঙ অবশ্যই অন্যান্য পিক্সেলের উপর নির্ভর করবে না (যেমন ব্লার কাজ করবে না)। একবার প্রস্তুত হয়ে গেলে, 512*512 LUT ফিল্টারের জন্য ইনপুট হিসাবে আপনার নতুন LUT চিত্রটি ব্যবহার করুন</string>\n    <string name=\"pop_art\">পপ আর্ট</string>\n    <string name=\"celluloid\">সেলুলয়েড</string>\n    <string name=\"coffee\">কফি</string>\n    <string name=\"golden_forest\">গোল্ডেন ফরেস্ট</string>\n    <string name=\"greenish\">সবুজাভ</string>\n    <string name=\"retro_yellow\">রেট্রো হলুদ</string>\n    <string name=\"links_preview\">লিঙ্ক পূর্বরূপ</string>\n    <string name=\"links_preview_sub\">যেখানে আপনি পাঠ্য (QRCode, OCR ইত্যাদি) পেতে পারেন সেখানে লিঙ্কের পূর্বরূপ পুনরুদ্ধার সক্ষম করে</string>\n    <string name=\"links\">লিঙ্ক</string>\n    <string name=\"ico_size_warning\">ICO ফাইলগুলি শুধুমাত্র সর্বাধিক 256 x 256 আকারে সংরক্ষণ করা যেতে পারে</string>\n    <string name=\"gif_type_to_webp\">WEBP-এ GIF</string>\n    <string name=\"gif_type_to_webp_sub\">GIF ছবিগুলিকে WEBP অ্যানিমেটেড ছবিতে রূপান্তর করুন৷</string>\n    <string name=\"webp_tools\">WEBP টুলস</string>\n    <string name=\"webp_tools_sub\">ছবিগুলিকে WEBP অ্যানিমেটেড ছবিতে রূপান্তর করুন বা প্রদত্ত WEBP অ্যানিমেশন থেকে ফ্রেমগুলি বের করুন৷</string>\n    <string name=\"webp_type_to_image\">ছবি WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP ফাইলকে ছবির ব্যাচে রূপান্তর করুন</string>\n    <string name=\"webp_type_to_webp_sub\">WEBP ফাইলে চিত্রের ব্যাচ রূপান্তর করুন</string>\n    <string name=\"webp_type_to_webp\">WEBP-এ ছবি</string>\n    <string name=\"select_webp_image_to_start\">শুরু করতে WEBP ছবি বাছুন</string>\n    <string name=\"manage_storage_extra_types\">ফাইলগুলিতে সম্পূর্ণ অ্যাক্সেস নেই</string>\n    <string name=\"manage_storage_extra_types_sub\">সমস্ত ফাইলগুলিকে JXL, QOI এবং অন্যান্য ছবিগুলি দেখার অনুমতি দিন যেগুলি Android-এ ছবি হিসাবে স্বীকৃত নয়৷ অনুমতি ছাড়া ইমেজ টুলবক্স সেই ছবিগুলো দেখাতে অক্ষম</string>\n    <string name=\"default_draw_color\">ডিফল্ট আঁকা রঙ</string>\n    <string name=\"default_draw_path_mode\">ডিফল্ট ড্র পাথ মোড</string>\n    <string name=\"add_timestamp\">টাইমস্ট্যাম্প যোগ করুন</string>\n    <string name=\"add_timestamp_sub\">আউটপুট ফাইলনামে টাইমস্ট্যাম্প যোগ করা সক্ষম করে</string>\n    <string name=\"formatted_timestamp\">ফরম্যাট করা টাইমস্ট্যাম্প</string>\n    <string name=\"formatted_timestamp_sub\">মৌলিক মিলের পরিবর্তে আউটপুট ফাইলনামে টাইমস্ট্যাম্প বিন্যাস সক্ষম করুন</string>\n    <string name=\"enable_timestamps_to_format_them\">তাদের বিন্যাস নির্বাচন করতে টাইমস্ট্যাম্প সক্ষম করুন৷</string>\n    <string name=\"one_time_save_location\">ওয়ান টাইম সেভ লোকেশন</string>\n    <string name=\"one_time_save_location_sub\">একবার সংরক্ষণ করা অবস্থানগুলি দেখুন এবং সম্পাদনা করুন যা আপনি বেশিরভাগ বিকল্পে সংরক্ষণ বোতামটি দীর্ঘক্ষণ টিপে ব্যবহার করতে পারেন</string>\n    <string name=\"recently_used\">সম্প্রতি ব্যবহৃত</string>\n    <string name=\"ci_channel\">সিআই চ্যানেল</string>\n    <string name=\"group\">গ্রুপ</string>\n    <string name=\"image_toolbox_in_telegram\">টেলিগ্রামে ইমেজ টুলবক্স 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">আমাদের চ্যাটে যোগ দিন যেখানে আপনি যা চান তা নিয়ে আলোচনা করতে পারেন এবং CI চ্যানেলটিও দেখতে পারেন যেখানে আমি বেটা এবং ঘোষণা পোস্ট করি</string>\n    <string name=\"ci_channel_sub\">অ্যাপের নতুন সংস্করণ সম্পর্কে বিজ্ঞপ্তি পান এবং ঘোষণা পড়ুন</string>\n    <string name=\"fit_description\">প্রদত্ত মাত্রার সাথে একটি চিত্র ফিট করুন এবং পটভূমিতে অস্পষ্ট বা রঙ প্রয়োগ করুন</string>\n    <string name=\"tools_arrangement\">টুলস ব্যবস্থা</string>\n    <string name=\"group_tools_by_type\">টাইপ অনুসারে গ্রুপ টুল</string>\n    <string name=\"group_tools_by_type_sub\">একটি কাস্টম তালিকা বিন্যাসের পরিবর্তে প্রধান স্ক্রিনে সরঞ্জামগুলিকে তাদের প্রকার অনুসারে গোষ্ঠীবদ্ধ করে৷</string>\n    <string name=\"default_values\">ডিফল্ট মান</string>\n    <string name=\"system_bars_visibility\">সিস্টেম বার দৃশ্যমানতা</string>\n    <string name=\"show_system_bars_by_swipe\">সোয়াইপ করে সিস্টেম বার দেখান</string>\n    <string name=\"show_system_bars_by_swipe_sub\">সিস্টেম বারগুলি লুকানো থাকলে তা দেখানোর জন্য সোয়াইপ করা সক্ষম করে৷</string>\n    <string name=\"auto\">অটো</string>\n    <string name=\"hide_all\">সব লুকান</string>\n    <string name=\"show_all\">সব দেখান</string>\n    <string name=\"hide_nav_bar\">নেভি বার লুকান</string>\n    <string name=\"hide_status_bar\">স্ট্যাটাস বার লুকান</string>\n    <string name=\"noise_generation\">নয়েজ জেনারেশন</string>\n    <string name=\"noise_generation_sub\">পার্লিন বা অন্যান্য ধরনের মত বিভিন্ন শব্দ তৈরি করুন</string>\n    <string name=\"frequency\">ফ্রিকোয়েন্সি</string>\n    <string name=\"noise_type\">নয়েজ টাইপ</string>\n    <string name=\"rotation_type\">ঘূর্ণন প্রকার</string>\n    <string name=\"fractal_type\">ফ্র্যাক্টাল টাইপ</string>\n    <string name=\"octaves\">অষ্টক</string>\n    <string name=\"lacunarity\">স্বল্পতা</string>\n    <string name=\"gain\">লাভ</string>\n    <string name=\"weighted_strength\">ওজনযুক্ত শক্তি</string>\n    <string name=\"ping_pong_strength\">পিং পং শক্তি</string>\n    <string name=\"distance_function\">দূরত্ব ফাংশন</string>\n    <string name=\"return_type\">রিটার্ন টাইপ</string>\n    <string name=\"jitter\">জিটার</string>\n    <string name=\"domain_warp\">ডোমেন ওয়ার্প</string>\n    <string name=\"alignment\">প্রান্তিককরণ</string>\n    <string name=\"custom_filename\">কাস্টম ফাইলের নাম</string>\n    <string name=\"custom_filename_sub\">অবস্থান এবং ফাইলের নাম নির্বাচন করুন যা বর্তমান চিত্র সংরক্ষণ করতে ব্যবহার করা হবে</string>\n    <string name=\"saved_to_custom\">কাস্টম নামের সাথে ফোল্ডারে সংরক্ষিত</string>\n    <string name=\"collage_maker\">কোলাজ মেকার</string>\n    <string name=\"collage_maker_sub\">20টি পর্যন্ত ছবি থেকে কোলাজ তৈরি করুন৷</string>\n    <string name=\"collage_type\">কোলাজ প্রকার</string>\n    <string name=\"collages_info\">অবস্থান সামঞ্জস্য করতে ছবি অদলবদল করতে, সরাতে এবং জুম করতে ধরে রাখুন</string>\n    <string name=\"disable_rotation\">ঘূর্ণন অক্ষম করুন</string>\n    <string name=\"disable_rotation_sub\">দুই আঙুলের অঙ্গভঙ্গি দিয়ে ছবি ঘোরানো প্রতিরোধ করে</string>\n    <string name=\"enable_snapping_to_borders\">সীমানায় স্ন্যাপিং সক্ষম করুন</string>\n    <string name=\"enable_snapping_to_borders_sub\">সরানো বা জুম করার পরে, ছবিগুলি ফ্রেমের প্রান্তগুলি পূরণ করতে স্ন্যাপ করবে৷</string>\n    <string name=\"histogram\">হিস্টোগ্রাম</string>\n    <string name=\"histogram_sub\">আপনাকে সামঞ্জস্য করতে সাহায্য করার জন্য RGB বা উজ্জ্বলতা ইমেজ হিস্টোগ্রাম</string>\n    <string name=\"image_for_histogram\">এই চিত্রটি আরজিবি এবং উজ্জ্বলতা হিস্টোগ্রাম তৈরি করতে ব্যবহার করা হবে</string>\n    <string name=\"tesseract_options\">Tesseract অপশন</string>\n    <string name=\"tesseract_options_sub\">টেসার্যাক্ট ইঞ্জিনের জন্য কিছু ইনপুট ভেরিয়েবল প্রয়োগ করুন</string>\n    <string name=\"custom_options\">কাস্টম বিকল্প</string>\n    <string name=\"custom_params_info\">এই প্যাটার্ন অনুসরণ করে বিকল্পগুলি লিখতে হবে: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">অটো ক্রপ</string>\n    <string name=\"free_corners\">বিনামূল্যে কর্নার</string>\n    <string name=\"free_corners_sub\">বহুভুজ দ্বারা চিত্র ক্রপ করুন, এটি দৃষ্টিকোণকেও সংশোধন করে</string>\n    <string name=\"coerce_points_to_image_bounds\">ইমেজ বাউন্ডে জোর করে পয়েন্ট</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">পয়েন্টগুলি চিত্র সীমার দ্বারা সীমাবদ্ধ থাকবে না, এটি আরও সুনির্দিষ্ট দৃষ্টিকোণ সংশোধনের জন্য দরকারী</string>\n    <string name=\"mask\">মুখোশ</string>\n    <string name=\"spot_heal_sub\">টানা পথের অধীনে বিষয়বস্তু সচেতন পূরণ করুন</string>\n    <string name=\"spot_heal\">স্পট নিরাময়</string>\n    <string name=\"use_circle_kernel\">সার্কেল কার্নেল ব্যবহার করুন</string>\n    <string name=\"opening\">খোলা হচ্ছে</string>\n    <string name=\"closing\">বন্ধ হচ্ছে</string>\n    <string name=\"morphological_gradient\">রূপগত গ্রেডিয়েন্ট</string>\n    <string name=\"top_hat\">শীর্ষ টুপি</string>\n    <string name=\"black_hat\">কালো টুপি</string>\n    <string name=\"tone_curves\">টোন কার্ভস</string>\n    <string name=\"reset_curves\">কার্ভ রিসেট করুন</string>\n    <string name=\"reset_curves_sub\">বক্ররেখাগুলিকে ডিফল্ট মানে ফিরিয়ে আনা হবে</string>\n    <string name=\"line_style\">লাইন স্টাইল</string>\n    <string name=\"gap_size\">গ্যাপ সাইজ</string>\n    <string name=\"dashed\">ড্যাশড</string>\n    <string name=\"dot_dashed\">ডট ড্যাশড</string>\n    <string name=\"stamped\">মুদ্রাঙ্কিত</string>\n    <string name=\"zigzag\">জিগজ্যাগ</string>\n    <string name=\"dashed_sub\">নির্দিষ্ট ফাঁক আকারের সাথে আঁকা পথ বরাবর ড্যাশড রেখা আঁকে</string>\n    <string name=\"dot_dashed_sub\">প্রদত্ত পথ বরাবর ডট এবং ড্যাশড লাইন আঁকে</string>\n    <string name=\"defaultt_sub\">শুধু ডিফল্ট সোজা লাইন</string>\n    <string name=\"stamped_sub\">নির্দিষ্ট ব্যবধান সহ পথ বরাবর নির্বাচিত আকার আঁকে</string>\n    <string name=\"zigzag_sub\">পথ বরাবর তরঙ্গায়িত জিগজ্যাগ আঁকে</string>\n    <string name=\"zigzag_ratio\">জিগজ্যাগ অনুপাত</string>\n    <string name=\"create_shortcut\">শর্টকাট তৈরি করুন</string>\n    <string name=\"create_shortcut_title\">পিন করার জন্য টুল বেছে নিন</string>\n    <string name=\"create_shortcut_subtitle\">টুলটি আপনার লঞ্চারের হোম স্ক্রিনে শর্টকাট হিসাবে যোগ করা হবে, প্রয়োজনীয় আচরণ অর্জন করতে \\\"ফাইল পিকিং এড়িয়ে যান\\\" সেটিংসের সাথে এটি ব্যবহার করুন</string>\n    <string name=\"dont_stack_frames\">ফ্রেম স্ট্যাক করবেন না</string>\n    <string name=\"dont_stack_frames_sub\">পূর্ববর্তী ফ্রেম নিষ্পত্তি সক্ষম করে, তাই তারা একে অপরের উপর স্ট্যাক করবে না</string>\n    <string name=\"crossfade\">ক্রসফেড</string>\n    <string name=\"crossfade_sub\">ফ্রেম একে অপরের মধ্যে ক্রসফেড করা হবে</string>\n    <string name=\"crossfade_count\">ক্রসফেড ফ্রেম গণনা</string>\n    <string name=\"threshold_one\">থ্রেশহোল্ড ওয়ান</string>\n    <string name=\"threshold_two\">থ্রেশহোল্ড দুই</string>\n    <string name=\"canny\">ক্যানি</string>\n    <string name=\"mirror_101\">মিরর 101</string>\n    <string name=\"enhanced_zoom_blur\">বর্ধিত জুম ব্লার</string>\n    <string name=\"laplacian_simple\">ল্যাপ্লাসিয়ান সিম্পল</string>\n    <string name=\"sobel_simple\">সোবেল সিম্পল</string>\n    <string name=\"helper_grid\">হেল্পার গ্রিড</string>\n    <string name=\"helper_grid_sub\">সুনির্দিষ্ট ম্যানিপুলেশনে সাহায্য করার জন্য অঙ্কন এলাকার উপরে সমর্থনকারী গ্রিড দেখায়</string>\n    <string name=\"grid_color\">গ্রিড রঙ</string>\n    <string name=\"cell_width\">কক্ষের প্রস্থ</string>\n    <string name=\"cell_height\">কোষের উচ্চতা</string>\n    <string name=\"compact_selectors\">কমপ্যাক্ট নির্বাচক</string>\n    <string name=\"compact_selectors_sub\">কিছু নির্বাচন নিয়ন্ত্রণ কম জায়গা নিতে কমপ্যাক্ট লেআউট ব্যবহার করবে</string>\n    <string name=\"grant_camera_permission_to_capture_image\">ছবি তোলার জন্য সেটিংসে ক্যামেরার অনুমতি দিন</string>\n    <string name=\"layout\">লেআউট</string>\n    <string name=\"main_screen_title\">প্রধান পর্দা শিরোনাম</string>\n    <string name=\"constant_rate_factor\">ধ্রুবক হার ফ্যাক্টর (CRF)</string>\n    <string name=\"crf_sub\">%1$s এর মান মানে একটি ধীর সংকোচন, যার ফলে ফাইলের আকার অপেক্ষাকৃত ছোট হয়। %2$s মানে একটি দ্রুত কম্প্রেশন, যার ফলে একটি বড় ফাইল।</string>\n    <string name=\"lut_library\">লুট লাইব্রেরি</string>\n    <string name=\"lut_library_sub\">LUTs এর সংগ্রহ ডাউনলোড করুন, যা আপনি ডাউনলোড করার পরে আবেদন করতে পারেন</string>\n    <string name=\"lut_library_update_sub\">LUT-এর সংগ্রহ আপডেট করুন (শুধুমাত্র নতুনগুলি সারিবদ্ধ হবে), যা আপনি ডাউনলোড করার পরে আবেদন করতে পারেন</string>\n    <string name=\"filter_preview_image_sub\">ফিল্টারগুলির জন্য ডিফল্ট চিত্র পূর্বরূপ পরিবর্তন করুন</string>\n    <string name=\"filter_preview_image\">পূর্বরূপ চিত্র</string>\n    <string name=\"hide\">লুকান</string>\n    <string name=\"show\">দেখান</string>\n    <string name=\"slider_type\">স্লাইডার টাইপ</string>\n    <string name=\"fancy\">অভিনব</string>\n    <string name=\"material_2\">উপাদান 2</string>\n    <string name=\"fancy_sub\">একটি অভিনব-সুদর্শন স্লাইডার. এটি ডিফল্ট বিকল্প</string>\n    <string name=\"material_2_sub\">একটি উপাদান 2 স্লাইডার</string>\n    <string name=\"material_you_slider_sub\">একটি উপাদান আপনি স্লাইডার</string>\n    <string name=\"apply\">আবেদন করুন</string>\n    <string name=\"center_align_dialog_buttons\">কেন্দ্র ডায়ালগ বোতাম</string>\n    <string name=\"center_align_dialog_buttons_sub\">ডায়ালগের বোতামগুলি সম্ভব হলে বাম দিকের পরিবর্তে কেন্দ্রে স্থাপন করা হবে</string>\n    <string name=\"open_source_licenses\">ওপেন সোর্স লাইসেন্স</string>\n    <string name=\"open_source_licenses_sub\">এই অ্যাপে ব্যবহৃত ওপেন সোর্স লাইব্রেরির লাইসেন্স দেখুন</string>\n    <string name=\"area\">এলাকা</string>\n    <string name=\"area_sub\">পিক্সেল এরিয়া রিলেশন ব্যবহার করে রিস্যাম্পলিং। এটি ইমেজ ডিসিমেশনের জন্য একটি পছন্দের পদ্ধতি হতে পারে, কারণ এটি ময়ার\\'-মুক্ত ফলাফল দেয়। কিন্তু যখন ছবিটি জুম করা হয়, তখন এটি \\\"নিকটবর্তী\\\" পদ্ধতির অনুরূপ।</string>\n    <string name=\"enable_tonemapping\">টোনম্যাপিং সক্ষম করুন</string>\n    <string name=\"enter_percent\">% লিখুন</string>\n    <string name=\"unknown_host\">সাইটটি অ্যাক্সেস করতে পারবেন না, ভিপিএন ব্যবহার করার চেষ্টা করুন বা ইউআরএল সঠিক কিনা তা পরীক্ষা করুন</string>\n    <string name=\"markup_layers\">মার্কআপ স্তর</string>\n    <string name=\"markup_layers_sub\">অবাধে ছবি, টেক্সট এবং আরও অনেক কিছু রাখার ক্ষমতা সহ লেয়ার মোড</string>\n    <string name=\"edit_layer\">স্তর সম্পাদনা করুন</string>\n    <string name=\"layers_on_image\">ইমেজ উপর স্তর</string>\n    <string name=\"layers_on_image_sub\">একটি পটভূমি হিসাবে একটি চিত্র ব্যবহার করুন এবং এটির উপরে বিভিন্ন স্তর যুক্ত করুন</string>\n    <string name=\"layers_on_background\">পটভূমিতে স্তর</string>\n    <string name=\"layers_on_background_sub\">প্রথম বিকল্পের মতই কিন্তু ছবির পরিবর্তে রঙ সহ</string>\n    <string name=\"beta\">বেটা</string>\n    <string name=\"fast_settings_side\">দ্রুত সেটিংস সাইড</string>\n    <string name=\"fast_settings_side_sub\">ছবি সম্পাদনা করার সময় নির্বাচিত পাশে একটি ভাসমান স্ট্রিপ যোগ করুন, যা ক্লিক করলে দ্রুত সেটিংস খুলবে</string>\n    <string name=\"clear_selection\">নির্বাচন পরিষ্কার করুন</string>\n    <string name=\"settings_group_visibility_hidden\">সেট করা গোষ্ঠী \\\"%1$s\\\" ডিফল্টরূপে ভেঙে যাবে</string>\n    <string name=\"settings_group_visibility_visible\">সেট করা গ্রুপ \\\"%1$s\\\" ডিফল্টরূপে প্রসারিত হবে</string>\n    <string name=\"base_64_tools\">বেস64 টুলস</string>\n    <string name=\"base_64_tools_sub\">Base64 স্ট্রিংকে ইমেজ ডিকোড করুন, বা Base64 ফরম্যাটে ইমেজ এনকোড করুন</string>\n    <string name=\"base_64\">বেস64</string>\n    <string name=\"not_a_valid_base_64\">প্রদত্ত মান একটি বৈধ Base64 স্ট্রিং নয়৷</string>\n    <string name=\"copy_not_a_valid_base_64\">খালি বা অবৈধ Base64 স্ট্রিং কপি করা যাবে না</string>\n    <string name=\"paste_base_64\">পেস্ট বেস64</string>\n    <string name=\"copy_base_64\">কপি Base64</string>\n    <string name=\"base_64_tips\">Base64 স্ট্রিং কপি বা সংরক্ষণ করতে ছবি লোড করুন। আপনার যদি স্ট্রিংটি থাকে তবে আপনি ছবিটি পেতে উপরে পেস্ট করতে পারেন</string>\n    <string name=\"save_base_64\">বেস 64 সংরক্ষণ করুন</string>\n    <string name=\"share_base_64\">শেয়ার বেস64</string>\n    <string name=\"options\">অপশন</string>\n    <string name=\"actions\">কর্ম</string>\n    <string name=\"import_base_64\">আমদানি বেস64</string>\n    <string name=\"base_64_actions\">বেস64 অ্যাকশন</string>\n    <string name=\"add_outline\">আউটলাইন যোগ করুন</string>\n    <string name=\"add_outline_sub\">নির্দিষ্ট রঙ এবং প্রস্থ সহ পাঠ্যের চারপাশে রূপরেখা যুক্ত করুন</string>\n    <string name=\"outline_color\">রূপরেখার রঙ</string>\n    <string name=\"outline_size\">রূপরেখার আকার</string>\n    <string name=\"rotation\">ঘূর্ণন</string>\n    <string name=\"checksum_as_filename\">ফাইলের নাম হিসাবে চেকসাম</string>\n    <string name=\"checksum_as_filename_sub\">আউটপুট ইমেজ তাদের ডেটা চেকসামের সাথে সম্পর্কিত নাম থাকবে</string>\n    <string name=\"free_software_partner\">ফ্রি সফটওয়্যার (অংশীদার)</string>\n    <string name=\"free_software_partner_sub\">অ্যান্ড্রয়েড অ্যাপ্লিকেশনের অংশীদার চ্যানেলে আরও দরকারী সফ্টওয়্যার</string>\n    <string name=\"algorithms\">অ্যালগরিদম</string>\n    <string name=\"checksum_tools\">চেকসাম টুলস</string>\n    <string name=\"checksum_tools_sub\">চেকসাম তুলনা করুন, হ্যাশ গণনা করুন বা বিভিন্ন হ্যাশিং অ্যালগরিদম ব্যবহার করে ফাইল থেকে হেক্স স্ট্রিং তৈরি করুন</string>\n    <string name=\"calculate\">হিসাব করুন</string>\n    <string name=\"text_hash\">টেক্সট হ্যাশ</string>\n    <string name=\"checksum\">চেকসাম</string>\n    <string name=\"pick_file_to_checksum\">নির্বাচিত অ্যালগরিদমের উপর ভিত্তি করে এর চেকসাম গণনা করতে ফাইলটি বেছে নিন</string>\n    <string name=\"enter_text_to_checksum\">নির্বাচিত অ্যালগরিদমের উপর ভিত্তি করে এর চেকসাম গণনা করতে পাঠ্য লিখুন</string>\n    <string name=\"source_checksum\">উৎস চেকসাম</string>\n    <string name=\"checksum_to_compare\">তুলনা করার জন্য চেকসাম</string>\n    <string name=\"match\">মিল !</string>\n    <string name=\"difference\">পার্থক্য</string>\n    <string name=\"match_sub\">চেকসাম সমান, এটি নিরাপদ হতে পারে</string>\n    <string name=\"difference_sub\">চেকসাম সমান নয়, ফাইল অনিরাপদ হতে পারে!</string>\n    <string name=\"mesh_gradients\">মেশ গ্রেডিয়েন্ট</string>\n    <string name=\"collection_mesh_gradients_sub\">মেশ গ্রেডিয়েন্টের অনলাইন সংগ্রহ দেখুন</string>\n    <string name=\"wrong_font\">শুধুমাত্র TTF এবং OTF ফন্ট ইম্পোর্ট করা যাবে</string>\n    <string name=\"import_font\">হরফ আমদানি করুন (TTF/OTF)</string>\n    <string name=\"export_fonts\">ফন্ট রপ্তানি করুন</string>\n    <string name=\"imported_fonts\">আমদানিকৃত ফন্ট</string>\n    <string name=\"error_while_saving\">চেষ্টা সংরক্ষণ করার সময় ত্রুটি, আউটপুট ফোল্ডার পরিবর্তন করার চেষ্টা করুন</string>\n    <string name=\"filename_is_not_set\">ফাইলের নাম সেট করা নেই</string>\n    <string name=\"none\">কোনোটিই নয়</string>\n    <string name=\"custom_pages\">কাস্টম পেজ</string>\n    <string name=\"pages_selection\">পৃষ্ঠা নির্বাচন</string>\n    <string name=\"tool_exit_confirmation\">টুল প্রস্থান নিশ্চিতকরণ</string>\n    <string name=\"tool_exit_confirmation_sub\">নির্দিষ্ট টুল ব্যবহার করার সময় আপনার যদি অসংরক্ষিত পরিবর্তন থাকে এবং এটি বন্ধ করার চেষ্টা করে, তাহলে নিশ্চিত করুন ডায়ালগ দেখানো হবে</string>\n    <string name=\"edit_exif_screen\">EXIF সম্পাদনা করুন</string>\n    <string name=\"edit_exif_screen_sub\">রিকম্প্রেশন ছাড়াই একক ছবির মেটাডেটা পরিবর্তন করুন</string>\n    <string name=\"edit_exif_tag\">উপলব্ধ ট্যাগ সম্পাদনা করতে আলতো চাপুন</string>\n    <string name=\"change_sticker\">স্টিকার পরিবর্তন করুন</string>\n    <string name=\"fit_width\">ফিট প্রস্থ</string>\n    <string name=\"fit_height\">মানানসই উচ্চতা</string>\n    <string name=\"batch_compare\">ব্যাচ তুলনা</string>\n    <string name=\"pick_files_to_checksum\">নির্বাচিত অ্যালগরিদমের উপর ভিত্তি করে এর চেকসাম গণনা করতে ফাইল/ফাইলগুলি বেছে নিন</string>\n    <string name=\"pick_files\">ফাইল বাছাই করুন</string>\n    <string name=\"pick_directory\">ডিরেক্টরি বাছাই করুন</string>\n    <string name=\"head_length_scale\">মাথার দৈর্ঘ্য স্কেল</string>\n    <string name=\"stamp\">স্ট্যাম্প</string>\n    <string name=\"timestamp\">টাইমস্ট্যাম্প</string>\n    <string name=\"format_pattern\">বিন্যাস প্যাটার্ন</string>\n    <string name=\"padding\">প্যাডিং</string>\n    <string name=\"image_cutting\">ইমেজ কাটিং</string>\n    <string name=\"image_cutting_sub\">চিত্রের অংশটি কেটে নিন এবং উল্লম্ব বা অনুভূমিক রেখা দ্বারা বাম অংশগুলিকে একত্রিত করুন (বিপরীত হতে পারে)</string>\n    <string name=\"vertical_pivot_line\">উল্লম্ব পিভট লাইন</string>\n    <string name=\"horizontal_pivot_line\">অনুভূমিক পিভট লাইন</string>\n    <string name=\"inverse_selection\">বিপরীত নির্বাচন</string>\n    <string name=\"inverse_vertical_selection_sub\">কাটা এলাকার চারপাশে অংশ একত্রিত করার পরিবর্তে উল্লম্ব কাটা অংশ ছেড়ে দেওয়া হবে</string>\n    <string name=\"inverse_horizontal_selection_sub\">কাটা এলাকার চারপাশে অংশ একত্রিত করার পরিবর্তে অনুভূমিক কাটা অংশ ছেড়ে দেওয়া হবে</string>\n    <string name=\"collection_mesh_gradients\">মেশ গ্রেডিয়েন্টের সংগ্রহ</string>\n    <string name=\"mesh_gradients_sub\">কাস্টম পরিমাণ নট এবং রেজোলিউশন সহ জাল গ্রেডিয়েন্ট তৈরি করুন</string>\n    <string name=\"gradient_maker_type_image_mesh\">মেশ গ্রেডিয়েন্ট ওভারলে</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">প্রদত্ত চিত্রগুলির শীর্ষে জাল গ্রেডিয়েন্ট রচনা করুন</string>\n    <string name=\"points_customization\">পয়েন্ট কাস্টমাইজেশন</string>\n    <string name=\"grid_size\">গ্রিডের আকার</string>\n    <string name=\"resolution_x\">রেজোলিউশন এক্স</string>\n    <string name=\"resolution_y\">রেজোলিউশন Y</string>\n    <string name=\"resolution\">রেজোলিউশন</string>\n    <string name=\"pixel_by_pixel\">পিক্সেল বাই পিক্সেল</string>\n    <string name=\"highlight_color\">হাইলাইট রঙ</string>\n    <string name=\"pixel_comparison_type\">পিক্সেল তুলনা প্রকার</string>\n    <string name=\"scan_barcode\">বারকোড স্ক্যান করুন</string>\n    <string name=\"height_ratio\">উচ্চতা অনুপাত</string>\n    <string name=\"barcode_type\">বারকোড টাইপ</string>\n    <string name=\"enforce_bw\">B/W প্রয়োগ করুন</string>\n    <string name=\"enforce_bw_sub\">বারকোড ইমেজ সম্পূর্ণ কালো এবং সাদা হবে এবং অ্যাপের থিম দ্বারা রঙিন হবে না</string>\n    <string name=\"barcodes_sub\">যেকোনো বারকোড (QR, EAN, AZTEC, …) স্ক্যান করুন এবং এর বিষয়বস্তু পান বা নতুন তৈরি করতে আপনার পাঠ্য পেস্ট করুন</string>\n    <string name=\"no_barcode_found\">কোন বারকোড পাওয়া যায়নি</string>\n    <string name=\"generated_barcode_will_be_here\">জেনারেটেড বারকোড এখানে থাকবে</string>\n    <string name=\"audio_cover_extractor\">অডিও কভার</string>\n    <string name=\"audio_cover_extractor_sub\">অডিও ফাইল থেকে অ্যালবাম কভার ইমেজ নিষ্কাশন, সবচেয়ে সাধারণ বিন্যাস সমর্থিত হয়</string>\n    <string name=\"pick_audio_to_start\">শুরু করতে অডিও বেছে নিন</string>\n    <string name=\"pick_audio\">অডিও বাছাই করুন</string>\n    <string name=\"no_covers_found\">কোন কভার পাওয়া যায়নি</string>\n    <string name=\"send_logs\">লগ পাঠান</string>\n    <string name=\"send_logs_sub\">অ্যাপ লগ ফাইল শেয়ার করতে ক্লিক করুন, এটি আমাকে সমস্যা খুঁজে পেতে এবং সমস্যার সমাধান করতে সাহায্য করতে পারে</string>\n    <string name=\"crash_title\">ওহো… কিছু ভুল হয়েছে</string>\n    <string name=\"crash_subtitle\">আপনি নীচের বিকল্পগুলি ব্যবহার করে আমার সাথে যোগাযোগ করতে পারেন এবং আমি সমাধান খোঁজার চেষ্টা করব৷\\n(লগগুলি সংযুক্ত করতে ভুলবেন না)</string>\n    <string name=\"ocr_write_to_file\">ফাইলে লিখুন</string>\n    <string name=\"ocr_write_to_file_sub\">চিত্রের ব্যাচ থেকে পাঠ্য বের করুন এবং এটি একটি পাঠ্য ফাইলে সংরক্ষণ করুন</string>\n    <string name=\"ocr_write_to_metadata\">মেটাডেটা লিখুন</string>\n    <string name=\"ocr_write_to_metadata_sub\">প্রতিটি ছবি থেকে টেক্সট বের করুন এবং আপেক্ষিক ফটোর EXIF ​​তথ্যে রাখুন</string>\n    <string name=\"invisible_mode\">অদৃশ্য মোড</string>\n    <string name=\"invisible_mode_sub\">আপনার ছবির বাইটের ভিতরে চোখের অদৃশ্য ওয়াটারমার্ক তৈরি করতে স্টেগানোগ্রাফি ব্যবহার করুন</string>\n    <string name=\"use_lsb\">LSB ব্যবহার করুন</string>\n    <string name=\"use_lsb_sub\">LSB (কম উল্লেখযোগ্য বিট) স্টেগানোগ্রাফি পদ্ধতি ব্যবহার করা হবে, অন্যথায় FD (ফ্রিকোয়েন্সি ডোমেন)</string>\n    <string name=\"auto_remove_red_eyes\">স্বয়ং লাল চোখ সরান</string>\n    <string name=\"password\">পাসওয়ার্ড</string>\n    <string name=\"unlock\">আনলক</string>\n    <string name=\"pdf_is_protected\">পিডিএফ সুরক্ষিত</string>\n    <string name=\"operation_almost_complete\">অপারেশন প্রায় সম্পূর্ণ। এখন বাতিল করার জন্য এটি পুনরায় চালু করতে হবে</string>\n    <string name=\"sort_by_date_modified\">তারিখ পরিবর্তিত</string>\n    <string name=\"sort_by_date_modified_reversed\">তারিখ পরিবর্তিত (বিপরীত)</string>\n    <string name=\"sort_by_size\">আকার</string>\n    <string name=\"sort_by_size_reversed\">আকার (বিপরীত)</string>\n    <string name=\"sort_by_mime_type\">MIME প্রকার</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME প্রকার (বিপরীত)</string>\n    <string name=\"sort_by_extension\">এক্সটেনশন</string>\n    <string name=\"sort_by_extension_reversed\">এক্সটেনশন (বিপরীত)</string>\n    <string name=\"sort_by_date_added\">তারিখ যোগ করা হয়েছে</string>\n    <string name=\"sort_by_date_added_reversed\">যোগ করার তারিখ (বিপরীত)</string>\n    <string name=\"left_to_right\">বাম থেকে ডানে</string>\n    <string name=\"right_to_left\">ডান থেকে বাম</string>\n    <string name=\"top_to_bottom\">টপ টু বটম</string>\n    <string name=\"bottom_to_top\">নিচ থেকে উপরে</string>\n    <string name=\"liquid_glass\">তরল গ্লাস</string>\n    <string name=\"liquid_glass_sub\">সম্প্রতি ঘোষিত IOS 26 এবং এটির লিকুইড গ্লাস ডিজাইন সিস্টেমের উপর ভিত্তি করে একটি সুইচ</string>\n    <string name=\"pick_image_or_base64\">চিত্র বাছাই করুন বা নীচে বেস64 ডেটা পেস্ট/আমদানি করুন</string>\n    <string name=\"type_image_link\">শুরু করতে ছবির লিঙ্ক টাইপ করুন</string>\n    <string name=\"paste_link\">লিঙ্ক পেস্ট করুন</string>\n    <string name=\"kaleidoscope\">ক্যালিডোস্কোপ</string>\n    <string name=\"secondary_angle\">মাধ্যমিক কোণ</string>\n    <string name=\"sides\">পক্ষসমূহ</string>\n    <string name=\"channel_mix\">চ্যানেল মিক্স</string>\n    <string name=\"blue_green\">নীল সবুজ</string>\n    <string name=\"red_blue\">লাল নীল</string>\n    <string name=\"green_red\">সবুজ লাল</string>\n    <string name=\"into_red\">লাল হয়ে গেছে</string>\n    <string name=\"into_green\">সবুজে</string>\n    <string name=\"into_blue\">নীলে</string>\n    <string name=\"cyan\">সায়ান</string>\n    <string name=\"magenta\">ম্যাজেন্টা</string>\n    <string name=\"yellow\">হলুদ</string>\n    <string name=\"color_halftone\">কালার হাফটোন</string>\n    <string name=\"contour\">কনট্যুর</string>\n    <string name=\"levels\">স্তর</string>\n    <string name=\"offset\">অফসেট</string>\n    <string name=\"voronoi_crystallize\">Voronoi ক্রিস্টালাইজ</string>\n    <string name=\"shape\">আকৃতি</string>\n    <string name=\"stretch\">প্রসারিত</string>\n    <string name=\"randomness\">এলোমেলোতা</string>\n    <string name=\"despeckle\">Despeckle</string>\n    <string name=\"diffuse\">ছড়িয়ে পড়া</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">দ্বিতীয় ব্যাসার্ধ</string>\n    <string name=\"equalize\">সমান করা</string>\n    <string name=\"glow\">দীপ্তি</string>\n    <string name=\"whirl_and_pinch\">ঘূর্ণি এবং চিমটি</string>\n    <string name=\"pointillize\">পয়েন্টিলাইজ করুন</string>\n    <string name=\"border_color\">বর্ডার রঙ</string>\n    <string name=\"polar_coordinates\">পোলার স্থানাঙ্ক</string>\n    <string name=\"rect_to_polar\">মেরু থেকে রেক্ট</string>\n    <string name=\"polar_to_rect\">সংশোধন করতে পোলার</string>\n    <string name=\"invert_in_circle\">বৃত্তে উল্টানো</string>\n    <string name=\"reduce_noise\">শব্দ কম করুন</string>\n    <string name=\"simple_solarize\">সরল সোলারাইজ</string>\n    <string name=\"weave\">বিণ</string>\n    <string name=\"x_gap\">এক্স গ্যাপ</string>\n    <string name=\"y_gap\">ওয়াই গ্যাপ</string>\n    <string name=\"x_width\">এক্স প্রস্থ</string>\n    <string name=\"y_wdth\">Y প্রস্থ</string>\n    <string name=\"twirl\">ঘূর্ণায়মান</string>\n    <string name=\"rubber_stmp\">রাবার স্ট্যাম্প</string>\n    <string name=\"smear\">স্মিয়ার</string>\n    <string name=\"density\">ঘনত্ব</string>\n    <string name=\"mix\">মিক্স</string>\n    <string name=\"sphere_lensh_distortion\">গোলক লেন্স বিকৃতি</string>\n    <string name=\"refraction_index\">প্রতিসরণ সূচক</string>\n    <string name=\"arc\">অর্ক</string>\n    <string name=\"spread_angle\">স্প্রেড কোণ</string>\n    <string name=\"sparkle\">ঝকঝকে</string>\n    <string name=\"rays\">রশ্মি</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">গ্রেডিয়েন্ট</string>\n    <string name=\"moire\">মেরি</string>\n    <string name=\"autumn\">শরৎ</string>\n    <string name=\"bone\">হাড়</string>\n    <string name=\"jet\">জেট</string>\n    <string name=\"winter\">শীতকাল</string>\n    <string name=\"ocean\">মহাসাগর</string>\n    <string name=\"summer\">গ্রীষ্ম</string>\n    <string name=\"spring\">বসন্ত</string>\n    <string name=\"cool_variant\">শীতল বৈকল্পিক</string>\n    <string name=\"hsv\">এইচএসভি</string>\n    <string name=\"pink\">গোলাপী</string>\n    <string name=\"hot\">গরম</string>\n    <string name=\"parula\">শব্দ</string>\n    <string name=\"magma\">ম্যাগমা</string>\n    <string name=\"inferno\">ইনফার্নো</string>\n    <string name=\"plasma\">প্লাজমা</string>\n    <string name=\"viridis\">ভিরিডিস</string>\n    <string name=\"cividis\">নাগরিক</string>\n    <string name=\"twilight\">গোধূলি</string>\n    <string name=\"twilight_shifted\">গোধূলি স্থানান্তরিত</string>\n    <string name=\"auto_perspective\">দৃষ্টিকোণ অটো</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">ক্রপ করার অনুমতি দিন</string>\n    <string name=\"crop_or_perspective\">ক্রপ বা দৃষ্টিকোণ</string>\n    <string name=\"absolute\">পরম</string>\n    <string name=\"turbo\">টার্বো</string>\n    <string name=\"deep_green\">গভীর সবুজ</string>\n    <string name=\"lens_correction\">লেন্স সংশোধন</string>\n    <string name=\"target_lens_profile\">টার্গেট লেন্স প্রোফাইল ফাইল JSON ফর্ম্যাটে</string>\n    <string name=\"download_ready_lens_profiles\">প্রস্তুত লেন্স প্রোফাইল ডাউনলোড করুন</string>\n    <string name=\"part_percents\">অংশ শতাংশ</string>\n    <string name=\"export_as_json\">JSON হিসাবে রপ্তানি করুন</string>\n    <string name=\"export_as_json_sub\">json উপস্থাপনা হিসাবে একটি প্যালেট ডেটা সহ স্ট্রিং অনুলিপি করুন</string>\n    <string name=\"seam_carving\">সীম খোদাই</string>\n    <string name=\"home_screen\">হোম স্ক্রীন</string>\n    <string name=\"lock_screen\">লক স্ক্রীন</string>\n    <string name=\"built_in\">অন্তর্নির্মিত</string>\n    <string name=\"wallpapers_export\">ওয়ালপেপার রপ্তানি</string>\n    <string name=\"refresh\">রিফ্রেশ</string>\n    <string name=\"wallpapers_export_sub\">বর্তমান হোম, লক এবং অন্তর্নির্মিত ওয়ালপেপার পান</string>\n    <string name=\"allow_access_to_all_files_for_wp\">সমস্ত ফাইল অ্যাক্সেস করার অনুমতি দিন, ওয়ালপেপার পুনরুদ্ধার করার জন্য এটি প্রয়োজন</string>\n    <string name=\"allow_read_media_images_for_wp\">বাহ্যিক সঞ্চয়স্থানের অনুমতি পরিচালনা করা যথেষ্ট নয়, আপনাকে আপনার চিত্রগুলিতে অ্যাক্সেসের অনুমতি দিতে হবে, \\\"সমস্তকে অনুমতি দিন\\\" নির্বাচন করতে ভুলবেন না</string>\n    <string name=\"add_preset_to_filename\">ফাইলনামে প্রিসেট যোগ করুন</string>\n    <string name=\"add_preset_to_filename_sub\">ইমেজ ফাইলনামে নির্বাচিত প্রিসেটের সাথে প্রত্যয় যুক্ত করে</string>\n    <string name=\"add_image_scale_mode_to_filename\">ফাইলনামে ইমেজ স্কেল মোড যোগ করুন</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">ইমেজ ফাইলনামে নির্বাচিত ইমেজ স্কেল মোডের সাথে প্রত্যয় যুক্ত করে</string>\n    <string name=\"ascii_art\">Ascii আর্ট</string>\n    <string name=\"ascii_art_sub\">ছবিকে ascii টেক্সটে রূপান্তর করুন যা চিত্রের মতো দেখাবে</string>\n    <string name=\"params\">পরমস</string>\n    <string name=\"invert_colors_ascii_sub\">কিছু ক্ষেত্রে ভালো ফলাফলের জন্য ছবিতে নেতিবাচক ফিল্টার প্রয়োগ করে</string>\n    <string name=\"processing_screenshot\">স্ক্রিনশট প্রক্রিয়া করা হচ্ছে</string>\n    <string name=\"screenshot_not_captured_try_again\">স্ক্রিনশট ক্যাপচার করা হয়নি, আবার চেষ্টা করুন</string>\n    <string name=\"skipped_saving\">সেভ করা এড়িয়ে গেছে</string>\n    <string name=\"skipped_saving_multiple\">%1$s ফাইল এড়িয়ে গেছে</string>\n    <string name=\"allow_skip_if_larger\">বড় হলে এড়িয়ে যাওয়ার অনুমতি দিন</string>\n    <string name=\"allow_skip_if_larger_sub\">ফলস্বরূপ ফাইলের আকার আসলটির চেয়ে বড় হলে কিছু সরঞ্জামকে ছবি সংরক্ষণ করা এড়ানোর অনুমতি দেওয়া হবে</string>\n    <string name=\"qr_type_calendar_event\">ক্যালেন্ডার ইভেন্ট</string>\n    <string name=\"qr_type_contact_info\">যোগাযোগ</string>\n    <string name=\"qr_type_email\">ইমেইল</string>\n    <string name=\"qr_type_geo_point\">অবস্থান</string>\n    <string name=\"qr_type_phone\">ফোন</string>\n    <string name=\"qr_type_plain\">পাঠ্য</string>\n    <string name=\"qr_type_sms\">এসএমএস</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">ওয়াই-ফাই</string>\n    <string name=\"open_network\">নেটওয়ার্ক খুলুন</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">ফোন</string>\n    <string name=\"message\">বার্তা</string>\n    <string name=\"address\">ঠিকানা</string>\n    <string name=\"subject\">বিষয়</string>\n    <string name=\"body\">শরীর</string>\n    <string name=\"name\">নাম</string>\n    <string name=\"organization\">সংগঠন</string>\n    <string name=\"title\">শিরোনাম</string>\n    <string name=\"phones\">ফোন</string>\n    <string name=\"emails\">ইমেইল</string>\n    <string name=\"urls\">ইউআরএল</string>\n    <string name=\"addresses\">ঠিকানা</string>\n    <string name=\"summary\">সারাংশ</string>\n    <string name=\"description\">বর্ণনা</string>\n    <string name=\"location\">অবস্থান</string>\n    <string name=\"organizer\">সংগঠক</string>\n    <string name=\"start_date\">শুরুর তারিখ</string>\n    <string name=\"end_date\">শেষ তারিখ</string>\n    <string name=\"status\">স্ট্যাটাস</string>\n    <string name=\"latitude\">অক্ষাংশ</string>\n    <string name=\"longitude\">দ্রাঘিমাংশ</string>\n    <string name=\"create_barcode\">বারকোড তৈরি করুন</string>\n    <string name=\"edit_barcode\">বারকোড সম্পাদনা করুন</string>\n    <string name=\"wifi_configuration\">Wi-Fi কনফিগারেশন</string>\n    <string name=\"security\">নিরাপত্তা</string>\n    <string name=\"pick_contact\">পরিচিতি বাছুন</string>\n    <string name=\"grant_contact_permission\">নির্বাচিত পরিচিতি ব্যবহার করে অটোফিল করার জন্য সেটিংসে পরিচিতিদের অনুমতি দিন</string>\n    <string name=\"contact_info\">যোগাযোগের তথ্য</string>\n    <string name=\"first_name\">প্রথম নাম</string>\n    <string name=\"middle_name\">মধ্য নাম</string>\n    <string name=\"last_name\">পদবি</string>\n    <string name=\"pronunciation\">উচ্চারণ</string>\n    <string name=\"add_phone\">ফোন যোগ করুন</string>\n    <string name=\"add_email\">ইমেল যোগ করুন</string>\n    <string name=\"add_address\">ঠিকানা যোগ করুন</string>\n    <string name=\"website\">ওয়েবসাইট</string>\n    <string name=\"add_website\">ওয়েবসাইট যোগ করুন</string>\n    <string name=\"formatted_name\">ফরম্যাট করা নাম</string>\n    <string name=\"qr_code_top_image\">এই ছবিটি বারকোডের উপরে রাখতে ব্যবহার করা হবে</string>\n    <string name=\"code_customization\">কোড কাস্টমাইজেশন</string>\n    <string name=\"qr_logo_image\">এই ছবিটি QR কোডের কেন্দ্রে লোগো হিসাবে ব্যবহার করা হবে</string>\n    <string name=\"logo\">লোগো</string>\n    <string name=\"logo_padding\">লোগো প্যাডিং</string>\n    <string name=\"logo_size\">লোগো আকার</string>\n    <string name=\"logo_corners\">লোগো কোণ</string>\n    <string name=\"fourth_eye\">চতুর্থ চোখ</string>\n    <string name=\"fourth_eye_description\">নিচের প্রান্তের কোণায় চতুর্থ চোখ যোগ করে qr কোডে চোখের প্রতিসাম্য যোগ করে</string>\n    <string name=\"pixel_shape\">পিক্সেল আকৃতি</string>\n    <string name=\"frame_shape\">ফ্রেমের আকৃতি</string>\n    <string name=\"ball_shape\">বলের আকৃতি</string>\n    <string name=\"error_correction_level\">ত্রুটি সংশোধন স্তর</string>\n    <string name=\"dark_color\">গাঢ় রং</string>\n    <string name=\"light_color\">হালকা রঙ</string>\n    <string name=\"hyper_os\">হাইপার ওএস</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS এর মতো স্টাইল</string>\n    <string name=\"mask_pattern\">মাস্ক প্যাটার্ন</string>\n    <string name=\"code_may_be_not_scannable\">এই কোডটি স্ক্যানযোগ্য নাও হতে পারে, এটিকে সমস্ত ডিভাইসের সাথে পঠনযোগ্য করতে চেহারা প্যারামগুলি পরিবর্তন করুন৷</string>\n    <string name=\"not_scannable\">স্ক্যানযোগ্য নয়</string>\n    <string name=\"launcher_mode_sub\">সরঞ্জামগুলি আরও কমপ্যাক্ট হতে হোম স্ক্রীন অ্যাপ লঞ্চারের মতো দেখাবে</string>\n    <string name=\"launcher_mode\">লঞ্চার মোড</string>\n    <string name=\"flood_fill_sub\">নির্বাচিত ব্রাশ এবং শৈলী দিয়ে একটি এলাকা পূরণ করে</string>\n    <string name=\"flood_fill\">বন্যা ভরাট</string>\n    <string name=\"spray\">স্প্রে</string>\n    <string name=\"spray_sub\">গ্রাফিটি স্টাইলযুক্ত পথ আঁকে</string>\n    <string name=\"square_particles\">বর্গাকার কণা</string>\n    <string name=\"square_particles_sub\">স্প্রে কণা বৃত্তের পরিবর্তে বর্গাকার আকৃতির হবে</string>\n    <string name=\"palette_tools\">প্যালেট সরঞ্জাম</string>\n    <string name=\"palette_tools_sub\">ইমেজ থেকে আপনার প্যালেটের মৌলিক/উপাদান তৈরি করুন বা বিভিন্ন প্যালেট ফরম্যাট জুড়ে আমদানি/রপ্তানি করুন</string>\n    <string name=\"edit_palette\">প্যালেট সম্পাদনা করুন</string>\n    <string name=\"edit_palette_sub\">বিভিন্ন ফরম্যাটে রপ্তানি/আমদানি প্যালেট</string>\n    <string name=\"color_name\">রঙের নাম</string>\n    <string name=\"palette_name\">প্যালেট নাম</string>\n    <string name=\"palette_format\">প্যালেট বিন্যাস</string>\n    <string name=\"export_palette_sub\">বিভিন্ন ফরম্যাটে জেনারেট করা প্যালেট রপ্তানি করুন</string>\n    <string name=\"add_color_palette_sub\">বর্তমান প্যালেটে নতুন রঙ যোগ করে</string>\n    <string name=\"palette_name_not_supported\">%1$s বিন্যাস প্যালেট নাম প্রদান সমর্থন করে না</string>\n    <string name=\"wallpapers_export_not_avaialbe\">প্লে স্টোর নীতির কারণে, এই বৈশিষ্ট্যটি বর্তমান বিল্ডে অন্তর্ভুক্ত করা যাবে না। এই কার্যকারিতা অ্যাক্সেস করতে, একটি বিকল্প উৎস থেকে ImageToolbox ডাউনলোড করুন। আপনি নীচে গিটহাবে উপলব্ধ বিল্ডগুলি খুঁজে পেতে পারেন।</string>\n    <string name=\"open_github_page\">Github পৃষ্ঠা খুলুন</string>\n    <string name=\"overwrite_files_sub_short\">আসল ফাইলটি নির্বাচিত ফোল্ডারে সংরক্ষণ করার পরিবর্তে নতুন একটি দিয়ে প্রতিস্থাপিত হবে</string>\n    <string name=\"hidden_watermark_text_detected\">লুকানো ওয়াটারমার্ক টেক্সট সনাক্ত করা হয়েছে</string>\n    <string name=\"hidden_watermark_image_detected\">লুকানো জলছাপ চিত্র সনাক্ত করা হয়েছে</string>\n    <string name=\"this_image_was_hidden\">এই ছবি লুকানো ছিল</string>\n    <string name=\"generative_inpaint\">জেনারেটিভ ইনপেইন্টিং</string>\n    <string name=\"generative_inpaint_sub\">OpenCV-এর উপর নির্ভর না করেই আপনাকে AI মডেল ব্যবহার করে একটি ইমেজে অবজেক্ট অপসারণ করতে দেয়। এই বৈশিষ্ট্যটি ব্যবহার করতে, অ্যাপটি গিটহাব থেকে প্রয়োজনীয় মডেল (~200 MB) ডাউনলোড করবে</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV-এর উপর নির্ভর না করেই আপনাকে AI মডেল ব্যবহার করে একটি ইমেজে অবজেক্ট অপসারণ করতে দেয়। এটি একটি দীর্ঘ চলমান অপারেশন হতে পারে</string>\n    <string name=\"error_level_analysis\">ত্রুটি স্তর বিশ্লেষণ</string>\n    <string name=\"luminance_gradient\">লুমিনেন্স গ্রেডিয়েন্ট</string>\n    <string name=\"average_distance\">গড় দূরত্ব</string>\n    <string name=\"copy_move_detection\">কপি মুভ ডিটেকশন</string>\n    <string name=\"retain\">ধরে রাখা</string>\n    <string name=\"coefficent\">সহগ</string>\n    <string name=\"clipboard_data_is_too_large\">ক্লিপবোর্ড ডেটা খুব বড়৷</string>\n    <string name=\"data_is_too_large_to_copy\">কপি করার জন্য ডেটা খুব বড়</string>\n    <string name=\"simple_weave_pixelization\">সহজ বুনা Pixelization</string>\n    <string name=\"staggered_pixelization\">স্তব্ধ Pixelization</string>\n    <string name=\"cross_pixelization\">ক্রস পিক্সেলাইজেশন</string>\n    <string name=\"micro_macro_pixelization\">মাইক্রো ম্যাক্রো পিক্সেলাইজেশন</string>\n    <string name=\"orbital_pixelization\">অরবিটাল পিক্সেলাইজেশন</string>\n    <string name=\"vortex_pixelization\">ঘূর্ণি পিক্সেলাইজেশন</string>\n    <string name=\"pulse_grid_pixelization\">পালস গ্রিড পিক্সেলাইজেশন</string>\n    <string name=\"nucleus_pixelization\">নিউক্লিয়াস পিক্সেলাইজেশন</string>\n    <string name=\"radial_weave_pixelization\">রেডিয়াল ওয়েভ পিক্সেলাইজেশন</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\" খুলতে পারে না</string>\n    <string name=\"snowfall_mode\">তুষারপাত মোড</string>\n    <string name=\"enabled\">সক্রিয়</string>\n    <string name=\"border_frame\">বর্ডার ফ্রেম</string>\n    <string name=\"glitch_variant\">গ্লিচ বৈকল্পিক</string>\n    <string name=\"channel_shift\">চ্যানেল শিফট</string>\n    <string name=\"max_offset\">সর্বোচ্চ অফসেট</string>\n    <string name=\"vhs\">ভিএইচএস</string>\n    <string name=\"block_glitch\">ব্লক গ্লিচ</string>\n    <string name=\"block_size\">ব্লক সাইজ</string>\n    <string name=\"crt_curvature\">CRT বক্রতা</string>\n    <string name=\"curvature\">বক্রতা</string>\n    <string name=\"chroma\">ক্রোমা</string>\n    <string name=\"pixel_melt\">পিক্সেল মেল্ট</string>\n    <string name=\"max_drop\">সর্বোচ্চ ড্রপ</string>\n    <string name=\"ai_tools\">এআই টুলস</string>\n    <string name=\"ai_tools_sub\">এআই মডেলের মাধ্যমে ছবি প্রসেস করার জন্য বিভিন্ন টুল যেমন আর্টিফ্যাক্ট রিমুভিং বা ডিনোইসিং</string>\n    <string name=\"model_anime_undeint\">কম্প্রেশন, জ্যাগড লাইন</string>\n    <string name=\"model_broadcast\">কার্টুন, সম্প্রচার কম্প্রেশন</string>\n    <string name=\"model_rgb_max_denoise_fp16\">সাধারণ সংকোচন, সাধারণ শব্দ</string>\n    <string name=\"model_wb_denoise\">বর্ণহীন কার্টুনের আওয়াজ</string>\n    <string name=\"model_span_anime_pretrain\">দ্রুত, সাধারণ কম্প্রেশন, সাধারণ গোলমাল, অ্যানিমেশন/কমিক্স/অ্যানিম</string>\n    <string name=\"model_book_scan\">বই স্ক্যানিং</string>\n    <string name=\"model_overexposure\">এক্সপোজার সংশোধন</string>\n    <string name=\"model_fbcnn_color_fp16\">সাধারণ কম্প্রেশনে সেরা, রঙিন ছবি</string>\n    <string name=\"model_fbcnn_gray_fp16\">সাধারণ কম্প্রেশনে সেরা, গ্রেস্কেল ছবি</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">সাধারণ কম্প্রেশন, গ্রেস্কেল ইমেজ, শক্তিশালী</string>\n    <string name=\"model_scunet_color_gan_fp16\">সাধারণ গোলমাল, রঙিন ছবি</string>\n    <string name=\"model_scunet_color_psnr_fp16\">সাধারণ গোলমাল, রঙিন ছবি, আরও ভালো বিবরণ</string>\n    <string name=\"model_scunet_gray_15_fp16\">সাধারণ গোলমাল, গ্রেস্কেল ছবি</string>\n    <string name=\"model_scunet_gray_25_fp16\">সাধারণ গোলমাল, গ্রেস্কেল ছবি, শক্তিশালী</string>\n    <string name=\"model_scunet_gray_50_fp16\">সাধারণ গোলমাল, গ্রেস্কেল ছবি, শক্তিশালী</string>\n    <string name=\"model_jpeg_destroyer\">সাধারণ কম্প্রেশন</string>\n    <string name=\"model_jaywreck\">সাধারণ কম্প্রেশন</string>\n    <string name=\"model_h264\">টেক্সচারাইজেশন, h264 কম্প্রেশন</string>\n    <string name=\"model_vhs\">ভিএইচএস কম্প্রেশন</string>\n    <string name=\"model_cinepak\">অ-মানক কম্প্রেশন (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">বিঙ্ক কম্প্রেশন, জ্যামিতিতে ভাল</string>\n    <string name=\"model_debink_v5\">বিঙ্ক কম্প্রেশন, শক্তিশালী</string>\n    <string name=\"model_debink_v6\">বিঙ্ক কম্প্রেশন, নরম, বিস্তারিত ধরে রাখে</string>\n    <string name=\"model_antialias\">সিঁড়ি-পদক্ষেপের প্রভাব দূর করা, মসৃণ করা</string>\n    <string name=\"model_kdm_scans\">স্ক্যান করা আর্ট/ড্রয়িং, হালকা কম্প্রেশন, মোয়ার</string>\n    <string name=\"model_bandage\">কালার ব্যান্ডিং</string>\n    <string name=\"model_halftone\">ধীর, হাফটোন অপসারণ</string>\n    <string name=\"model_colorizer\">গ্রেস্কেল/বিডব্লিউ ইমেজের জন্য সাধারণ কালারাইজার, ভালো ফলাফলের জন্য DDColor ব্যবহার করুন</string>\n    <string name=\"model_deedge\">প্রান্ত অপসারণ</string>\n    <string name=\"model_desharpen\">ওভারশার্পেনিং দূর করে</string>\n    <string name=\"model_dither\">ধীর, বিভ্রান্তি</string>\n    <string name=\"model_gainres\">অ্যান্টি-আলিয়াসিং, সাধারণ শিল্পকর্ম, সিজিআই</string>\n    <string name=\"model_kdm003_scans\">KDM003 স্ক্যান প্রক্রিয়াকরণ</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">লাইটওয়েট ইমেজ বর্ধিতকরণ মডেল</string>\n    <string name=\"model_bcgone_detailed_v2\">কম্প্রেশন আর্টিফ্যাক্ট অপসারণ</string>\n    <string name=\"model_bcgone_smooth\">কম্প্রেশন আর্টিফ্যাক্ট অপসারণ</string>\n    <string name=\"model_bandage_smooth\">মসৃণ ফলাফল সঙ্গে ব্যান্ডেজ অপসারণ</string>\n    <string name=\"model_bendel_halftone\">হাফটোন প্যাটার্ন প্রক্রিয়াকরণ</string>\n    <string name=\"model_dither_deleter_v3_smooth\">ডিথার প্যাটার্ন অপসারণ V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG আর্টিফ্যাক্ট অপসারণ V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 টেক্সচার বর্ধন</string>\n    <string name=\"model_vhs_sharpen\">VHS শার্পনিং এবং বর্ধিতকরণ</string>\n    <string name=\"merging\">মার্জিং</string>\n    <string name=\"chunk_size\">খণ্ডের আকার</string>\n    <string name=\"overlap_size\">ওভারল্যাপ সাইজ</string>\n    <string name=\"note_chunk_info\">%1$s px-এর বেশি চিত্রগুলিকে টুকরো টুকরো করে কেটে প্রক্রিয়াজাত করা হবে, দৃশ্যমান সীমগুলি প্রতিরোধ করতে ওভারল্যাপ এগুলিকে মিশ্রিত করে৷</string>\n    <string name=\"large_chunk_warning\">লো-এন্ড ডিভাইসের সাথে বড় আকার অস্থিরতা সৃষ্টি করতে পারে</string>\n    <string name=\"select_one_to_start\">শুরু করতে একটি নির্বাচন করুন</string>\n    <string name=\"delete_model_sub\">আপনি কি %1$s মডেল মুছতে চান? আপনাকে আবার এটি ডাউনলোড করতে হবে</string>\n    <string name=\"confirm\">নিশ্চিত করুন</string>\n    <string name=\"models\">মডেল</string>\n    <string name=\"downloaded_models\">ডাউনলোড করা মডেল</string>\n    <string name=\"available_models\">উপলব্ধ মডেল</string>\n    <string name=\"preparing\">প্রস্তুতি নিচ্ছে</string>\n    <string name=\"active_model\">সক্রিয় মডেল</string>\n    <string name=\"failed_to_open_session\">সেশন খুলতে ব্যর্থ হয়েছে৷</string>\n    <string name=\"only_onnx_models\">শুধুমাত্র .onnx/.ort মডেল ইম্পোর্ট করা যাবে</string>\n    <string name=\"import_model\">আমদানি মডেল</string>\n    <string name=\"import_model_sub\">আরও ব্যবহার করার জন্য কাস্টম onnx মডেল আমদানি করুন, শুধুমাত্র onnx/ort মডেলগুলি গ্রহণ করা হয়, প্রায় সমস্ত esrgan যেমন বৈকল্পিক সমর্থন করে</string>\n    <string name=\"imported_models\">আমদানিকৃত মডেল</string>\n    <string name=\"model_scunet_color_15_fp16\">সাধারণ গোলমাল, রঙিন ছবি</string>\n    <string name=\"model_scunet_color_25_fp16\">সাধারণ গোলমাল, রঙিন ছবি, শক্তিশালী</string>\n    <string name=\"model_scunet_color_50_fp16\">সাধারণ গোলমাল, রঙিন ছবি, শক্তিশালী</string>\n    <string name=\"model_artifacts_dithering_alsa\">মসৃণ গ্রেডিয়েন্ট এবং সমতল রঙের ক্ষেত্রগুলিকে উন্নত করে, বিক্ষিপ্ত শিল্পকর্ম এবং রঙের ব্যান্ডিং হ্রাস করে।</string>\n    <string name=\"model_nmkd_brighten_redux\">প্রাকৃতিক রং সংরক্ষণ করার সময় সুষম হাইলাইটের সাথে ছবির উজ্জ্বলতা এবং বৈসাদৃশ্য বাড়ায়।</string>\n    <string name=\"model_nmkd_brighten\">বিস্তারিত রাখা এবং অতিরিক্ত এক্সপোজার এড়ানোর সময় অন্ধকার ছবি উজ্জ্বল করে।</string>\n    <string name=\"model_nmkd_detoon\">অত্যধিক রঙের টোনিং দূর করে এবং আরও নিরপেক্ষ এবং প্রাকৃতিক রঙের ভারসাম্য পুনরুদ্ধার করে।</string>\n    <string name=\"model_noise_toner_poisson_detailed\">সূক্ষ্ম বিবরণ এবং টেক্সচার সংরক্ষণের উপর জোর দিয়ে পয়সন-ভিত্তিক নয়েজ টোনিং প্রয়োগ করে।</string>\n    <string name=\"model_noise_toner_poisson_soft\">মসৃণ এবং কম আক্রমনাত্মক ভিজ্যুয়াল ফলাফলের জন্য নরম পয়সন নয়েজ টোনিং প্রয়োগ করে।</string>\n    <string name=\"model_noise_toner_uniform_detailed\">ইউনিফর্ম নয়েজ টোনিং বিস্তারিত সংরক্ষণ এবং চিত্রের স্বচ্ছতার উপর দৃষ্টি নিবদ্ধ করে।</string>\n    <string name=\"model_noise_toner_uniform_soft\">সূক্ষ্ম টেক্সচার এবং মসৃণ চেহারা জন্য মৃদু অভিন্ন শব্দ টোনিং।</string>\n    <string name=\"model_repainter\">আর্টিফ্যাক্ট পুনরায় রং করে এবং চিত্রের সামঞ্জস্য উন্নত করে ক্ষতিগ্রস্ত বা অসম এলাকা মেরামত করে।</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">লাইটওয়েট ডিব্যান্ডিং মডেল যা ন্যূনতম পারফরম্যান্স খরচের সাথে রঙের ব্যান্ডিং সরিয়ে দেয়।</string>\n    <string name=\"model_jpeg_0_20\">উন্নত স্বচ্ছতার জন্য খুব উচ্চ কম্প্রেশন আর্টিফ্যাক্ট (0-20% গুণমান) সহ ছবিগুলিকে অপ্টিমাইজ করে৷</string>\n    <string name=\"model_jpeg_20_40\">উচ্চ কম্প্রেশন আর্টিফ্যাক্ট (20-40% গুণমান) সহ চিত্রগুলিকে উন্নত করে, বিবরণ পুনরুদ্ধার করে এবং শব্দ কমায়।</string>\n    <string name=\"model_jpeg_40_60\">মাঝারি কম্প্রেশন (40-60% গুণমান), তীক্ষ্ণতা এবং মসৃণতা ভারসাম্য সহ চিত্রগুলিকে উন্নত করে।</string>\n    <string name=\"model_jpeg_60_80\">সূক্ষ্ম বিবরণ এবং টেক্সচার উন্নত করতে হালকা কম্প্রেশন (60-80% গুণমান) সহ চিত্রগুলিকে পরিমার্জিত করে।</string>\n    <string name=\"model_jpeg_80_100\">প্রাকৃতিক চেহারা এবং বিশদ বিবরণ সংরক্ষণ করার সময় কাছাকাছি-ক্ষতিহীন চিত্রগুলিকে (80-100% গুণমান) সামান্য উন্নত করে।</string>\n    <string name=\"model_spongecolor_lite\">সহজ এবং দ্রুত কালারাইজেশন, কার্টুন, আদর্শ নয়</string>\n    <string name=\"model_deblr\">চিত্রের অস্পষ্টতাকে সামান্য কমিয়ে দেয়, শিল্পকর্মের পরিচয় না দিয়ে তীক্ষ্ণতা উন্নত করে।</string>\n    <string name=\"processing_channel\">দীর্ঘ চলমান অপারেশন</string>\n    <string name=\"processing_image\">চিত্র প্রক্রিয়াকরণ</string>\n    <string name=\"processing\">প্রক্রিয়াকরণ</string>\n    <string name=\"model_artifacts_jpg_0_20\">খুব কম মানের ছবিতে (0-20%) ভারী JPEG কম্প্রেশন আর্টিফ্যাক্টগুলি সরিয়ে দেয়।</string>\n    <string name=\"model_artifacts_jpg_20_40\">অত্যন্ত সংকুচিত চিত্রগুলিতে শক্তিশালী JPEG আর্টিফ্যাক্টগুলি হ্রাস করে (20-40%)।</string>\n    <string name=\"model_artifacts_jpg_40_60\">ছবির বিশদ (40-60%) সংরক্ষণ করার সময় মাঝারি JPEG আর্টিফ্যাক্টগুলি পরিষ্কার করে।</string>\n    <string name=\"model_artifacts_jpg_60_80\">মোটামুটি উচ্চ মানের ছবিতে হালকা JPEG আর্টিফ্যাক্টগুলিকে পরিমার্জন করে (60-80%)।</string>\n    <string name=\"model_artifacts_jpg_80_100\">সূক্ষ্মভাবে প্রায় ক্ষতিহীন চিত্রগুলিতে (80-100%) ছোট JPEG শিল্পকর্মগুলিকে হ্রাস করে৷</string>\n    <string name=\"model_redetail_v2\">সূক্ষ্ম বিবরণ এবং টেক্সচার উন্নত করে, ভারী শিল্পকর্ম ছাড়াই অনুভূত তীক্ষ্ণতা উন্নত করে।</string>\n    <string name=\"processing_finished\">প্রক্রিয়াকরণ সমাপ্ত</string>\n    <string name=\"processing_failed\">প্রক্রিয়াকরণ ব্যর্থ হয়েছে৷</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">গতির জন্য অপ্টিমাইজ করা একটি প্রাকৃতিক চেহারা রাখার সময় ত্বকের টেক্সচার এবং বিবরণ উন্নত করে।</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG কম্প্রেশন আর্টিফ্যাক্টগুলি সরিয়ে দেয় এবং সংকুচিত ফটোগুলির জন্য ছবির গুণমান পুনরুদ্ধার করে।</string>\n    <string name=\"model_iso_denoise_v1\">কম-আলোতে তোলা ফটোতে ISO নয়েজ কমায়, বিশদ সংরক্ষণ করে।</string>\n    <string name=\"model_dejumbo\">ওভার এক্সপোজড বা \\\"জাম্বো\\\" হাইলাইটগুলিকে সংশোধন করে এবং আরও ভাল টোনাল ভারসাম্য পুনরুদ্ধার করে।</string>\n    <string name=\"model_ddcolor_tiny\">লাইটওয়েট এবং দ্রুত কালারাইজেশন মডেল যা গ্রেস্কেল ছবিতে প্রাকৃতিক রং যোগ করে।</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">রঙ করা</string>\n    <string name=\"type_artifacts\">শিল্পকর্ম</string>\n    <string name=\"type_enhance\">উন্নত করুন</string>\n    <string name=\"type_anime\">এনিমে</string>\n    <string name=\"type_scans\">স্ক্যান</string>\n    <string name=\"type_upscale\">আপস্কেল</string>\n    <string name=\"model_realesrgan_x4v3\">সাধারণ ছবির জন্য X4 আপস্কেলার; ছোট মডেল যা কম GPU এবং সময় ব্যবহার করে, মাঝারি deblur এবং denoise সহ।</string>\n    <string name=\"model_realesrgan_x2plus\">সাধারণ ছবি, টেক্সচার এবং প্রাকৃতিক বিবরণ সংরক্ষণের জন্য X2 আপস্কেলার।</string>\n    <string name=\"model_realesrgan_x4plus\">উন্নত টেক্সচার এবং বাস্তবসম্মত ফলাফল সহ সাধারণ চিত্রগুলির জন্য X4 আপস্কেলার।</string>\n    <string name=\"model_realesrgan_x4plus_anime\">অ্যানিমে ছবিগুলির জন্য অপ্টিমাইজ করা X4 আপস্কেলার; ধারালো লাইন এবং বিশদ বিবরণের জন্য 6টি RRDB ব্লক।</string>\n    <string name=\"model_realesrnet_x4plus\">MSE ক্ষতি সহ X4 আপস্কেলার, সাধারণ চিত্রগুলির জন্য মসৃণ ফলাফল এবং কম শিল্পকর্ম তৈরি করে।</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">অ্যানিমে ছবিগুলির জন্য অপ্টিমাইজ করা X4 আপস্ক্যালার; তীক্ষ্ণ বিবরণ এবং মসৃণ লাইন সহ 4B32F ভেরিয়েন্ট।</string>\n    <string name=\"model_ultrasharp_v2_x4\">সাধারণ ছবির জন্য X4 UltraSharp V2 মডেল; তীক্ষ্ণতা এবং স্বচ্ছতার উপর জোর দেয়।</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; দ্রুত এবং ছোট, কম GPU মেমরি ব্যবহার করার সময় বিস্তারিত সংরক্ষণ করে।</string>\n    <string name=\"model_rmbg_1_4\">দ্রুত পটভূমি অপসারণের জন্য লাইটওয়েট মডেল। সুষম কর্মক্ষমতা এবং নির্ভুলতা। প্রতিকৃতি, বস্তু এবং দৃশ্য নিয়ে কাজ করে। বেশিরভাগ ব্যবহারের ক্ষেত্রে প্রস্তাবিত।</string>\n    <string name=\"type_removebg\">বিজি সরান</string>\n    <string name=\"horizontal_border_thickness\">অনুভূমিক সীমানা পুরুত্ব</string>\n    <string name=\"vertical_border_thickness\">উল্লম্ব সীমানা বেধ</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s রঙ</item>\n        <item quantity=\"other\">%1$s রং</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">বর্তমান মডেল চঙ্কিং সমর্থন করে না, ছবিটি মূল মাত্রায় প্রসেস করা হবে, এর ফলে উচ্চ মেমরি খরচ হতে পারে এবং লো-এন্ড ডিভাইসে সমস্যা হতে পারে</string>\n    <string name=\"chunking_disabled\">চঙ্কিং অক্ষম, ছবি মূল মাত্রায় প্রক্রিয়া করা হবে, এর ফলে উচ্চ মেমরি খরচ হতে পারে এবং লো-এন্ড ডিভাইসে সমস্যা হতে পারে তবে অনুমানে আরও ভাল ফলাফল দিতে পারে</string>\n    <string name=\"chunking\">চঙ্কিং</string>\n    <string name=\"model_u2net\">পটভূমি অপসারণের জন্য উচ্চ-নির্ভুলতা চিত্র বিভাজন মডেল</string>\n    <string name=\"model_u2netp\">ছোট মেমরি ব্যবহারের সাথে দ্রুত পটভূমি অপসারণের জন্য U2Net-এর হালকা সংস্করণ।</string>\n    <string name=\"model_ddcolor\">সম্পূর্ণ DDCcolor মডেল ন্যূনতম শিল্পকর্ম সহ সাধারণ চিত্রগুলির জন্য উচ্চ-মানের রঙিনকরণ সরবরাহ করে। সমস্ত রঙিন মডেলের সেরা পছন্দ।</string>\n    <string name=\"model_ddcolor_artistic\">DDColor প্রশিক্ষিত এবং ব্যক্তিগত শৈল্পিক ডেটাসেট; কম অবাস্তব রঙের শিল্পকর্মের সাথে বৈচিত্র্যময় এবং শৈল্পিক রঙিন ফলাফল তৈরি করে।</string>\n    <string name=\"model_birefnet\">সঠিক পটভূমি অপসারণের জন্য সুইন ট্রান্সফরমারের উপর ভিত্তি করে হালকা ওজনের BiRefNet মডেল।</string>\n    <string name=\"model_inspyrenet\">ধারালো প্রান্ত এবং চমৎকার বিশদ সংরক্ষণের সাথে উচ্চ-মানের পটভূমি অপসারণ, বিশেষ করে জটিল বস্তু এবং জটিল পটভূমিতে।</string>\n    <string name=\"model_isnet\">পটভূমি অপসারণ মডেল যা মসৃণ প্রান্ত সহ সঠিক মুখোশ তৈরি করে, সাধারণ বস্তুর জন্য উপযুক্ত এবং মাঝারি বিস্তারিত সংরক্ষণ।</string>\n    <string name=\"model_already_downloaded\">মডেল ইতিমধ্যে ডাউনলোড করা হয়েছে</string>\n    <string name=\"model_successfully_imported\">মডেল সফলভাবে আমদানি করা হয়েছে৷</string>\n    <string name=\"type\">টাইপ</string>\n    <string name=\"keyword\">কীওয়ার্ড</string>\n    <string name=\"very_fast\">খুব দ্রুত</string>\n    <string name=\"normal\">স্বাভাবিক</string>\n    <string name=\"slow\">ধীর</string>\n    <string name=\"very_slow\">খুব ধীর</string>\n    <string name=\"compute_percents\">শতাংশ গণনা করুন</string>\n    <string name=\"minimum_value_is\">সর্বনিম্ন মান হল %1$s</string>\n    <string name=\"warp_sub\">আঙ্গুল দিয়ে আঁকা ছবি বিকৃত</string>\n    <string name=\"warp\">ওয়ার্প</string>\n    <string name=\"hardness\">কঠোরতা</string>\n    <string name=\"warp_mode\">ওয়ার্প মোড</string>\n    <string name=\"warp_mode_move\">সরান</string>\n    <string name=\"warp_mode_grow\">বৃদ্ধি</string>\n    <string name=\"warp_mode_shrink\">সঙ্কুচিত</string>\n    <string name=\"warp_mode_swirl_cw\">ঘূর্ণি CW</string>\n    <string name=\"warp_mode_swirl_ccw\">ঘূর্ণায়মান CCW</string>\n    <string name=\"fade_strength\">বিবর্ণ শক্তি</string>\n    <string name=\"top_drop\">শীর্ষ ড্রপ</string>\n    <string name=\"bottom_drop\">বটম ড্রপ</string>\n    <string name=\"start_drop\">স্টার্ট ড্রপ</string>\n    <string name=\"end_drop\">শেষ ড্রপ</string>\n    <string name=\"downloading\">ডাউনলোড হচ্ছে</string>\n    <string name=\"smooth_shapes\">মসৃণ আকার</string>\n    <string name=\"smooth_shapes_sub\">মসৃণ, আরও প্রাকৃতিক আকৃতির জন্য আদর্শ গোলাকার আয়তক্ষেত্রের পরিবর্তে সুপারেলিপ্স ব্যবহার করুন</string>\n    <string name=\"shape_type\">আকৃতির ধরন</string>\n    <string name=\"cut\">কাটা</string>\n    <string name=\"rounded\">গোলাকার</string>\n    <string name=\"smooth\">মসৃণ</string>\n    <string name=\"cut_shapes_sub\">বৃত্তাকার ছাড়াই ধারালো প্রান্ত</string>\n    <string name=\"rounded_shapes_sub\">ক্লাসিক গোলাকার কোণ</string>\n    <string name=\"shapes_type\">আকারের ধরন</string>\n    <string name=\"corners_size\">কোণার আকার</string>\n    <string name=\"squircle\">কাঠবিড়ালি</string>\n    <string name=\"squircle_shapes_sub\">মার্জিত গোলাকার UI উপাদান</string>\n    <string name=\"filename_format\">ফাইলের নাম বিন্যাস</string>\n    <string name=\"prefix_pattern_description\">কাস্টম টেক্সট ফাইলের নামের একেবারে শুরুতে, প্রকল্পের নাম, ব্র্যান্ড বা ব্যক্তিগত ট্যাগের জন্য উপযুক্ত।</string>\n    <string name=\"original_filename_pattern_description\">এক্সটেনশন ছাড়াই মূল ফাইলের নাম ব্যবহার করে, আপনাকে উৎস সনাক্তকরণ অক্ষত রাখতে সাহায্য করে।</string>\n    <string name=\"width_pattern_description\">ছবির প্রস্থ পিক্সেলে, রেজোলিউশন পরিবর্তন বা স্কেলিং ফলাফল ট্র্যাক করার জন্য দরকারী।</string>\n    <string name=\"height_pattern_description\">চিত্রের উচ্চতা পিক্সেলে, আকৃতির অনুপাত বা রপ্তানির সাথে কাজ করার সময় সহায়ক।</string>\n    <string name=\"random_numbers_pattern_description\">অনন্য ফাইলের নাম নিশ্চিত করতে র্যান্ডম সংখ্যা তৈরি করে; ডুপ্লিকেটের বিরুদ্ধে অতিরিক্ত নিরাপত্তার জন্য আরও সংখ্যা যোগ করুন।</string>\n    <string name=\"sequence_number_pattern_description\">ব্যাচ রপ্তানির জন্য স্বয়ংক্রিয়-বর্ধিত কাউন্টার, এক সেশনে একাধিক ছবি সংরক্ষণ করার সময় আদর্শ।</string>\n    <string name=\"preset_info_pattern_description\">ফাইলের নামের মধ্যে প্রয়োগকৃত প্রিসেট নাম সন্নিবেশ করান যাতে আপনি সহজেই মনে রাখতে পারেন কিভাবে চিত্রটি প্রক্রিয়া করা হয়েছিল।</string>\n    <string name=\"scale_mode_pattern_description\">প্রসেসিং এর সময় ব্যবহৃত ইমেজ স্কেলিং মোড প্রদর্শন করে, রিসাইজ করা, ক্রপ করা বা ফিট করা ছবিগুলিকে আলাদা করতে সাহায্য করে।</string>\n    <string name=\"suffix_pattern_description\">ফাইলের নামের শেষে কাস্টম টেক্সট রাখা, _v2, _edited বা _final-এর মত সংস্করণের জন্য উপযোগী।</string>\n    <string name=\"extension_pattern_description\">ফাইল এক্সটেনশন (png, jpg, webp, ইত্যাদি), স্বয়ংক্রিয়ভাবে প্রকৃত সংরক্ষিত বিন্যাসের সাথে মিলে যায়।</string>\n    <string name=\"formatted_timestamp_pattern_description\">একটি কাস্টমাইজযোগ্য টাইমস্ট্যাম্প যা আপনাকে নিখুঁত সাজানোর জন্য জাভা স্পেসিফিকেশন দ্বারা আপনার নিজস্ব বিন্যাস সংজ্ঞায়িত করতে দেয়।</string>\n    <string name=\"fling_type\">ফ্লিং টাইপ</string>\n    <string name=\"android_native\">অ্যান্ড্রয়েড নেটিভ</string>\n    <string name=\"ios_style\">iOS স্টাইল</string>\n    <string name=\"smooth_curve\">মসৃণ বক্ররেখা</string>\n    <string name=\"quick_stop\">কুইক স্টপ</string>\n    <string name=\"bouncy\">বাউন্সি</string>\n    <string name=\"floaty\">ভাসমান</string>\n    <string name=\"snappy\">চটপটি</string>\n    <string name=\"ultra_smooth\">আল্ট্রা মসৃণ</string>\n    <string name=\"adaptive\">অভিযোজিত</string>\n    <string name=\"accessibility_aware\">অ্যাক্সেসিবিলিটি সচেতন</string>\n    <string name=\"reduced_motion\">গতি কমানো</string>\n    <string name=\"android_native_sub\">বেসলাইন তুলনার জন্য নেটিভ অ্যান্ড্রয়েড স্ক্রোল ফিজিক্স</string>\n    <string name=\"smooth_sub\">সাধারণ ব্যবহারের জন্য সুষম, মসৃণ স্ক্রলিং</string>\n    <string name=\"ios_style_sub\">উচ্চ ঘর্ষণ iOS-এর মতো স্ক্রোল আচরণ</string>\n    <string name=\"smooth_curve_sub\">স্বতন্ত্র স্ক্রোল অনুভূতির জন্য অনন্য স্প্লাইন বক্ররেখা</string>\n    <string name=\"quick_stop_sub\">দ্রুত স্টপিংয়ের সাথে সুনির্দিষ্ট স্ক্রলিং</string>\n    <string name=\"bouncy_sub\">কৌতুকপূর্ণ, প্রতিক্রিয়াশীল বাউন্সি স্ক্রোল</string>\n    <string name=\"floaty_sub\">কন্টেন্ট ব্রাউজিং এর জন্য লম্বা, গ্লাইডিং স্ক্রল</string>\n    <string name=\"snappy_sub\">ইন্টারেক্টিভ UI এর জন্য দ্রুত, প্রতিক্রিয়াশীল স্ক্রলিং</string>\n    <string name=\"ultra_smooth_sub\">বর্ধিত ভরবেগ সহ প্রিমিয়াম মসৃণ স্ক্রলিং</string>\n    <string name=\"adaptive_sub\">ফ্লিং বেগের উপর ভিত্তি করে পদার্থবিদ্যা সামঞ্জস্য করে</string>\n    <string name=\"accessibility_aware_sub\">সিস্টেম অ্যাক্সেসিবিলিটি সেটিংসকে সম্মান করে</string>\n    <string name=\"reduced_motion_sub\">অ্যাক্সেসযোগ্যতার প্রয়োজনের জন্য ন্যূনতম গতি</string>\n    <string name=\"primary_lines\">প্রাথমিক লাইন</string>\n    <string name=\"primary_lines_sub\">প্রতি পঞ্চম লাইনে মোটা লাইন যোগ করে</string>\n    <string name=\"fill_color\">রঙ পূরণ করুন</string>\n    <string name=\"hidden_tools\">লুকানো টুলস</string>\n    <string name=\"hidden_for_share\">শেয়ারের জন্য লুকানো টুল</string>\n    <string name=\"color_library\">রঙিন গ্রন্থাগার</string>\n    <string name=\"color_library_sub\">রঙের একটি বিশাল সংগ্রহ ব্রাউজ করুন</string>\n    <string name=\"model_fatality_deblur\">প্রাকৃতিক বিশদগুলি বজায় রেখে ছবিগুলিকে তীক্ষ্ণ করে এবং অস্পষ্টতা সরিয়ে দেয়, ফোকাসের বাইরের ফটোগুলি ঠিক করার জন্য আদর্শ৷</string>\n    <string name=\"model_unresize_v3\">বুদ্ধিমত্তার সাথে ইমেজগুলি পুনরুদ্ধার করে যা পূর্বে পুনরায় আকার দেওয়া হয়েছে, হারানো বিবরণ এবং টেক্সচার পুনরুদ্ধার করে।</string>\n    <string name=\"model_liveaction_v1_span\">লাইভ-অ্যাকশন কন্টেন্টের জন্য অপ্টিমাইজ করা, কম্প্রেশন আর্টিফ্যাক্ট কমায় এবং মুভি/টিভি শো ফ্রেমে সূক্ষ্ম বিবরণ বাড়ায়।</string>\n    <string name=\"model_vhs2hd_realplksr\">ভিএইচএস-গুণমানের ফুটেজকে HD তে রূপান্তর করে, টেপের শব্দ অপসারণ করে এবং ভিনটেজ অনুভূতি সংরক্ষণ করার সময় রেজোলিউশন বাড়ায়।</string>\n    <string name=\"model_text2hd_v1\">টেক্সট-ভারী ছবি এবং স্ক্রিনশটগুলির জন্য বিশেষ, অক্ষরগুলিকে তীক্ষ্ণ করে এবং পঠনযোগ্যতা উন্নত করে।</string>\n    <string name=\"model_frankendata_pretrainer\">বিভিন্ন ডেটাসেটে প্রশিক্ষিত উন্নত আপস্কেলিং, সাধারণ-উদ্দেশ্যের ফটো বর্ধনের জন্য চমৎকার।</string>\n    <string name=\"model_realwebphoto_v2\">ওয়েব-সংকুচিত ফটোগুলির জন্য অপ্টিমাইজ করা, JPEG আর্টিফ্যাক্টগুলি সরিয়ে দেয় এবং প্রাকৃতিক চেহারা পুনরুদ্ধার করে।</string>\n    <string name=\"model_realwebphoto_v4\">উন্নত টেক্সচার সংরক্ষণ এবং আর্টিফ্যাক্ট হ্রাস সহ ওয়েব ফটোগুলির জন্য উন্নত সংস্করণ।</string>\n    <string name=\"model_dat_2x\">ডুয়াল অ্যাগ্রিগেশন ট্রান্সফরমার প্রযুক্তির সাথে 2x আপস্কেলিং, তীক্ষ্ণতা এবং প্রাকৃতিক বিবরণ বজায় রাখে।</string>\n    <string name=\"model_dat_3x\">উন্নত ট্রান্সফরমার আর্কিটেকচার ব্যবহার করে 3x আপস্কেলিং, মাঝারি বৃদ্ধির প্রয়োজনের জন্য আদর্শ।</string>\n    <string name=\"model_dat_4x\">অত্যাধুনিক ট্রান্সফরমার নেটওয়ার্কের সাথে 4x উচ্চ-মানের আপস্কেলিং, বড় স্কেলে সূক্ষ্ম বিবরণ সংরক্ষণ করে।</string>\n    <string name=\"model_nafnet_deblurring\">ফটো থেকে ঝাপসা/গোলমাল এবং ঝাঁকুনি সরিয়ে দেয়। সাধারণ উদ্দেশ্য কিন্তু ফটোতে সেরা।</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Swin2SR ট্রান্সফরমার ব্যবহার করে নিম্ন-মানের ছবি পুনরুদ্ধার করে, BSRGAN অবক্ষয়ের জন্য অপ্টিমাইজ করা হয়েছে। ভারী কম্প্রেশন আর্টিফ্যাক্ট ঠিক করার জন্য এবং 4x স্কেলে বিশদ উন্নত করার জন্য দুর্দান্ত।</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN অবক্ষয়ের উপর প্রশিক্ষিত SwinIR ট্রান্সফরমার সহ 4x upscaling। ফটো এবং জটিল দৃশ্যগুলিতে তীক্ষ্ণ টেক্সচার এবং আরও প্রাকৃতিক বিবরণের জন্য GAN ব্যবহার করে।</string>\n    <string name=\"path\">পথ</string>\n    <string name=\"merge_pdf\">পিডিএফ মার্জ করুন</string>\n    <string name=\"merge_pdf_sub\">একটি নথিতে একাধিক পিডিএফ ফাইল একত্রিত করুন</string>\n    <string name=\"files_order\">ফাইল অর্ডার</string>\n    <string name=\"pages_short\">পিপি</string>\n    <string name=\"split_pdf\">পিডিএফ বিভক্ত করুন</string>\n    <string name=\"split_pdf_sub\">পিডিএফ ডকুমেন্ট থেকে নির্দিষ্ট পৃষ্ঠাগুলি বের করুন</string>\n    <string name=\"rotate_pdf\">পিডিএফ ঘোরান</string>\n    <string name=\"rotate_pdf_sub\">স্থায়ীভাবে পৃষ্ঠা অভিযোজন ঠিক করুন</string>\n    <string name=\"pages\">পাতা</string>\n    <string name=\"rearrange_pdf\">পিডিএফ পুনরায় সাজান</string>\n    <string name=\"rearrange_pdf_sub\">পৃষ্ঠাগুলিকে পুনরায় সাজাতে টেনে আনুন এবং ড্রপ করুন৷</string>\n    <string name=\"hold_drag_drop\">পৃষ্ঠাগুলি ধরে রাখুন এবং টেনে আনুন</string>\n    <string name=\"page_numbers\">পৃষ্ঠা নম্বর</string>\n    <string name=\"page_numbers_sub\">স্বয়ংক্রিয়ভাবে আপনার নথিতে নম্বর যোগ করুন</string>\n    <string name=\"label_format\">লেবেল বিন্যাস</string>\n    <string name=\"pdf_to_text\">PDF থেকে পাঠ্য (OCR)</string>\n    <string name=\"pdf_to_text_sub\">আপনার পিডিএফ ডকুমেন্ট থেকে প্লেইন টেক্সট বের করুন</string>\n    <string name=\"watermark_pdf_sub\">ব্র্যান্ডিং বা নিরাপত্তার জন্য কাস্টম টেক্সট ওভারলে</string>\n    <string name=\"signature\">স্বাক্ষর</string>\n    <string name=\"signature_sub\">যেকোনো নথিতে আপনার ইলেকট্রনিক স্বাক্ষর যোগ করুন</string>\n    <string name=\"will_be_for_signature\">এটি স্বাক্ষর হিসাবে ব্যবহার করা হবে</string>\n    <string name=\"unlock_pdf\">পিডিএফ আনলক করুন</string>\n    <string name=\"unlock_pdf_sub\">আপনার সুরক্ষিত ফাইল থেকে পাসওয়ার্ড সরান</string>\n    <string name=\"protect_pdf\">পিডিএফ রক্ষা করুন</string>\n    <string name=\"protect_pdf_sub\">শক্তিশালী এনক্রিপশন সহ আপনার নথিগুলি সুরক্ষিত করুন</string>\n    <string name=\"success\">সফলতা</string>\n    <string name=\"pdf_unlocked\">PDF আনলক করা হয়েছে, আপনি এটি সংরক্ষণ বা ভাগ করতে পারেন</string>\n    <string name=\"repair_pdf\">পিডিএফ মেরামত করুন</string>\n    <string name=\"repair_pdf_sub\">দূষিত বা অপঠনযোগ্য নথি ঠিক করার চেষ্টা করুন</string>\n    <string name=\"grayscale\">গ্রেস্কেল</string>\n    <string name=\"grayscale_pdf_sub\">সমস্ত নথি এমবেড করা ছবিকে গ্রেস্কেলে রূপান্তর করুন</string>\n    <string name=\"compress_pdf\">পিডিএফ কম্প্রেস করুন</string>\n    <string name=\"compress_pdf_sub\">সহজে ভাগ করার জন্য আপনার নথি ফাইলের আকার অপ্টিমাইজ করুন</string>\n    <string name=\"repair_info\">ImageToolbox অভ্যন্তরীণ ক্রস-রেফারেন্স টেবিল পুনর্নির্মাণ করে এবং স্ক্র্যাচ থেকে ফাইল গঠন পুনরুত্পাদন করে। এটি অনেক ফাইলের অ্যাক্সেস পুনরুদ্ধার করতে পারে যা \\\\\"খোলা যাবে না\\\\\"</string>\n    <string name=\"grayscale_info\">এই টুলটি সমস্ত নথির ছবিকে গ্রেস্কেলে রূপান্তর করে। ফাইলের আকার মুদ্রণ এবং হ্রাস করার জন্য সেরা</string>\n    <string name=\"metadata\">মেটাডেটা</string>\n    <string name=\"metadata_pdf_sub\">ভাল গোপনীয়তার জন্য নথি বৈশিষ্ট্য সম্পাদনা করুন</string>\n    <string name=\"tags\">ট্যাগ</string>\n    <string name=\"producer\">প্রযোজক</string>\n    <string name=\"author\">লেখক</string>\n    <string name=\"keywords\">কীওয়ার্ড</string>\n    <string name=\"creator\">সৃষ্টিকর্তা</string>\n    <string name=\"privacy_deep_clean\">গোপনীয়তা গভীর পরিষ্কার</string>\n    <string name=\"privacy_deep_clean_sub\">এই নথির জন্য সমস্ত উপলব্ধ মেটাডেটা সাফ করুন</string>\n    <string name=\"page\">পাতা</string>\n    <string name=\"deep_ocr\">গভীর ওসিআর</string>\n    <string name=\"deep_ocr_sub\">ডকুমেন্ট থেকে টেক্সট বের করুন এবং Tesseract ইঞ্জিন ব্যবহার করে একটি টেক্সট ফাইলে সংরক্ষণ করুন</string>\n    <string name=\"cant_remove_all\">সব পৃষ্ঠা মুছে ফেলা যাবে না</string>\n    <string name=\"remove_pages_pdf\">পিডিএফ পৃষ্ঠাগুলি সরান</string>\n    <string name=\"remove_pages_pdf_sub\">পিডিএফ ডকুমেন্ট থেকে নির্দিষ্ট পৃষ্ঠাগুলি সরান</string>\n    <string name=\"tap_to_remove\">সরাতে আলতো চাপুন</string>\n    <string name=\"manually\">ম্যানুয়ালি</string>\n    <string name=\"crop_pdf\">পিডিএফ ক্রপ করুন</string>\n    <string name=\"crop_pdf_sub\">দস্তাবেজ পৃষ্ঠাগুলিকে যে কোনও সীমা পর্যন্ত কাটুন</string>\n    <string name=\"flatten_pdf\">পিডিএফ সমতল করুন</string>\n    <string name=\"flatten_pdf_sub\">ডকুমেন্ট পেজ রাস্টার করে পিডিএফকে পরিবর্তনযোগ্য করুন</string>\n    <string name=\"camera_failed_to_open\">ক্যামেরা চালু করা যায়নি। অনুগ্রহ করে অনুমতি পরীক্ষা করুন এবং নিশ্চিত করুন যে এটি অন্য অ্যাপ ব্যবহার করছে না।</string>\n    <string name=\"extract_images\">ইমেজ এক্সট্র্যাক্ট</string>\n    <string name=\"extract_images_sub\">পিডিএফ-এ এমবেড করা ছবিগুলো তাদের আসল রেজোলিউশনে বের করুন</string>\n    <string name=\"pdf_no_embedded\">এই পিডিএফ ফাইলটিতে কোনো এমবেড করা ছবি নেই</string>\n    <string name=\"extract_images_info\">এই টুলটি প্রতিটি পৃষ্ঠা স্ক্যান করে এবং পূর্ণ মানের সোর্স ছবি পুনরুদ্ধার করে — নথি থেকে আসলগুলি সংরক্ষণ করার জন্য উপযুক্ত</string>\n    <string name=\"draw_signature\">স্বাক্ষর আঁকুন</string>\n    <string name=\"pen_params\">কলম পরম</string>\n    <string name=\"draw_signature_sub\">নথিতে স্থাপন করার জন্য ছবি হিসাবে নিজের স্বাক্ষর ব্যবহার করুন</string>\n    <string name=\"zip_pdf\">জিপ পিডিএফ</string>\n    <string name=\"zip_pdf_sub\">প্রদত্ত ব্যবধানে নথি ভাগ করুন এবং জিপ সংরক্ষণাগারে নতুন নথি প্যাক করুন</string>\n    <string name=\"interval\">ব্যবধান</string>\n    <string name=\"print_pdf\">পিডিএফ প্রিন্ট করুন</string>\n    <string name=\"print_pdf_sub\">কাস্টম পৃষ্ঠা আকার সহ মুদ্রণের জন্য নথি প্রস্তুত করুন</string>\n    <string name=\"pages_per_sheet\">পত্র প্রতি পাতা</string>\n    <string name=\"orientation\">ওরিয়েন্টেশন</string>\n    <string name=\"page_size\">পৃষ্ঠার আকার</string>\n    <string name=\"margin\">মার্জিন</string>\n    <string name=\"bloom\">পুষ্প</string>\n    <string name=\"soft_knee\">নরম হাঁটু</string>\n    <string name=\"model_realesr_animevideo_v3x4\">এনিমে এবং কার্টুন জন্য অপ্টিমাইজ করা. উন্নত প্রাকৃতিক রং এবং কম নিদর্শন সহ দ্রুত আপস্কেলিং</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 এর মতো স্টাইল</string>\n    <string name=\"calculate_hint\">পছন্দসই মান গণনা করতে এখানে মৌলিক গণিত প্রতীক লিখুন (যেমন (5+5)*10)</string>\n    <string name=\"math_expression\">গণিত অভিব্যক্তি</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s পর্যন্ত ছবি তুলে নিন</string>\n    <string name=\"keep_date_time\">তারিখ সময় রাখুন</string>\n    <string name=\"background_color_for_alpha_formats\">আলফা ফরম্যাটের জন্য পটভূমির রঙ</string>\n    <string name=\"background_color_for_alpha_formats_sub\">আলফা সমর্থন সহ প্রতিটি ইমেজ ফরম্যাটের জন্য পটভূমির রঙ সেট করার ক্ষমতা যোগ করে, যখন এটি নিষ্ক্রিয় করা হয় শুধুমাত্র অ-আলফাগুলির জন্য উপলব্ধ</string>\n    <string name=\"keep_date_time_sub\">সর্বদা তারিখ এবং সময়ের সাথে সম্পর্কিত exif ট্যাগ সংরক্ষণ করুন, exif বিকল্পটি স্বাধীনভাবে কাজ করে</string>\n    <string name=\"open_markup_project\">প্রকল্প খুলুন</string>\n    <string name=\"open_markup_project_sub\">একটি পূর্বে সংরক্ষিত চিত্র টুলবক্স প্রকল্প সম্পাদনা চালিয়ে যান</string>\n    <string name=\"markup_project_open_failed\">ইমেজ টুলবক্স প্রকল্প খুলতে অক্ষম</string>\n    <string name=\"markup_project_missing_data\">ইমেজ টুলবক্স প্রোজেক্টে প্রোজেক্ট ডেটা নেই</string>\n    <string name=\"markup_project_corrupted\">ইমেজ টুলবক্স প্রকল্প দূষিত হয়েছে</string>\n    <string name=\"unsupported_markup_project_version\">অসমর্থিত চিত্র টুলবক্স প্রকল্প সংস্করণ: %1$d</string>\n    <string name=\"save_markup_project\">প্রকল্প সংরক্ষণ করুন</string>\n    <string name=\"save_markup_project_sub\">একটি সম্পাদনাযোগ্য প্রকল্প ফাইলে স্তর, পটভূমি এবং সম্পাদনা ইতিহাস সংরক্ষণ করুন</string>\n    <string name=\"failed_to_open\">খুলতে ব্যর্থ হয়েছে</string>\n    <string name=\"ocr_write_to_searchable_pdf\">অনুসন্ধানযোগ্য পিডিএফ-এ লিখুন</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">চিত্র ব্যাচ থেকে পাঠ্য সনাক্ত করুন এবং চিত্র এবং নির্বাচনযোগ্য পাঠ্য স্তর সহ অনুসন্ধানযোগ্য PDF সংরক্ষণ করুন</string>\n    <string name=\"layer_alpha\">লেয়ার আলফা</string>\n    <string name=\"horizontal_flip\">অনুভূমিক উল্টানো</string>\n    <string name=\"vertical_flip\">উল্লম্ব উল্টানো</string>\n    <string name=\"lock\">তালা</string>\n    <string name=\"add_shadow\">ছায়া যোগ করুন</string>\n    <string name=\"shadow_color\">ছায়া রঙ</string>\n    <string name=\"text_geometry\">পাঠ্য জ্যামিতি</string>\n    <string name=\"text_geometry_sub\">তীক্ষ্ণ স্টাইলাইজেশনের জন্য টেক্সট প্রসারিত বা তির্যক করুন</string>\n    <string name=\"scale_x\">স্কেল এক্স</string>\n    <string name=\"skew_x\">স্কু এক্স</string>\n    <string name=\"remove_annotations\">টীকাগুলি সরান৷</string>\n    <string name=\"remove_annotations_sub\">পিডিএফ পৃষ্ঠাগুলি থেকে লিঙ্ক, মন্তব্য, হাইলাইট, আকার বা ফর্ম ক্ষেত্রগুলির মতো নির্বাচিত টীকা প্রকারগুলি সরান</string>\n    <string name=\"annotation_link\">হাইপারলিঙ্ক</string>\n    <string name=\"annotation_file_attachment\">ফাইল সংযুক্তি</string>\n    <string name=\"annotation_line\">লাইন</string>\n    <string name=\"annotation_popup\">পপআপ</string>\n    <string name=\"annotation_stamp\">স্ট্যাম্প</string>\n    <string name=\"annotation_shapes\">আকৃতি</string>\n    <string name=\"annotation_text\">টেক্সট নোট</string>\n    <string name=\"annotation_text_markup\">টেক্সট মার্কআপ</string>\n    <string name=\"annotation_widget\">ফর্ম ক্ষেত্র</string>\n    <string name=\"annotation_markup\">মার্কআপ</string>\n    <string name=\"annotation_unknown\">অজানা</string>\n    <string name=\"annotations\">টীকা</string>\n    <string name=\"ungroup\">আনগ্রুপ করুন</string>\n    <string name=\"add_shadow_sub\">কনফিগারযোগ্য রঙ এবং অফসেট সহ স্তরের পিছনে অস্পষ্ট ছায়া যোগ করুন</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ca/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">Alguna cosa ha anat malament: %1$s</string>\n    <string name=\"size\">Mida %1$s</string>\n    <string name=\"pick_image\">Trieu la imatge per començar</string>\n    <string name=\"width\">Amplada %1$s</string>\n    <string name=\"height\">Alçada %1$s</string>\n    <string name=\"quality\">Qualitat</string>\n    <string name=\"extension\">Extensió</string>\n    <string name=\"resize_type\">Tipus de redimensionat</string>\n    <string name=\"explicit\">Explícit</string>\n    <string name=\"pick_image_alt\">Trieu una imatge</string>\n    <string name=\"app_closing_sub\">Esteu segur que voleu tancar l\\'aplicació?</string>\n    <string name=\"app_closing\">S\\'està tancant l\\'aplicació</string>\n    <string name=\"flexible\">Flexible</string>\n    <string name=\"values_reset\">Valors reiniciats correctament</string>\n    <string name=\"stay\">Queda\\'t</string>\n    <string name=\"reset_image\">Restableix la imatge</string>\n    <string name=\"reset\">Restableix</string>\n    <string name=\"restart_app\">Reinicia l\\'aplicació</string>\n    <string name=\"copied\">S\\'ha copiat al porta-retalls</string>\n    <string name=\"exception\">Excepció</string>\n    <string name=\"edit_exif\">Edita l\\'EXIF</string>\n    <string name=\"something_went_wrong\">Alguna cosa ha anat malament</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">D\\'acord</string>\n    <string name=\"clear_exif_sub\">S\\'esborraran totes les dades EXIF de la imatge. Aquesta acció no es pot desfer!</string>\n    <string name=\"presets\">Valors predefinits</string>\n    <string name=\"image_not_saved\">Desant</string>\n    <string name=\"no_exif\">No s\\'han trobat dades EXIF</string>\n    <string name=\"add_tag\">Afegeix etiqueta</string>\n    <string name=\"single_edit_sub\">Canvia les especificacions d\\'una image</string>\n    <string name=\"check_source_code_sub\">Obteniu les últimes actualitzacions, discutiu temes i més</string>\n    <string name=\"pick_color_sub\">Tria el color de la imatge, copia o comparteix</string>\n    <string name=\"image\">Imatge</string>\n    <string name=\"color\">Color</string>\n    <string name=\"color_copied\">Color copiat</string>\n    <string name=\"keep_exif\">Manté l\\'EXIF</string>\n    <string name=\"images\">Imatges: %d</string>\n    <string name=\"change_preview\">Canvia la previsualització</string>\n    <string name=\"palette_sub\">Genera una mostra de la paleta de colors a partir de la imatge donada</string>\n    <string name=\"unsupported_type\">Tipus no admès: %1$s</string>\n    <string name=\"custom\">Personalitzat</string>\n    <string name=\"folder\">Carpeta de sortida</string>\n    <string name=\"by_bytes_resize_sub\">Canvia la mida d\\'una imatge a partir de la mida indicada en KB</string>\n    <string name=\"compare_sub\">Compara dues imatges donades</string>\n    <string name=\"unspecified\">Sense especificar</string>\n    <string name=\"device_storage\">Emmagatzematge del dispositiu</string>\n    <string name=\"pick_two_images\">Trieu dues imatges per a començar</string>\n    <string name=\"pick_images\">Tria imatges</string>\n    <string name=\"settings\">Configuració</string>\n    <string name=\"language\">Idioma</string>\n    <string name=\"allow_image_monet\">Permet Monet d\\'imatge</string>\n    <string name=\"dynamic_colors\">Colors dinàmics</string>\n    <string name=\"customization\">Personalització</string>\n    <string name=\"color_green\">Verd</string>\n    <string name=\"color_blue\">Blau</string>\n    <string name=\"color_scheme\">Esquema de color</string>\n    <string name=\"color_red\">Vermell</string>\n    <string name=\"issue_tracker\">Seguiment de problemes</string>\n    <string name=\"clipboard_paste_invalid_empty\">No hi ha res a enganxar</string>\n    <string name=\"about_app\">Quant a l\\'aplicació</string>\n    <string name=\"no_updates\">No s\\'ha trobat cap actualització</string>\n    <string name=\"pick_accent_color\">El tema de l\\'aplicació es basarà en el color seleccionat</string>\n    <string name=\"nothing_found_by_search\">No s\\'ha trobat res amb aquesta la consulta</string>\n    <string name=\"dynamic_colors_sub\">Si s\\'habilita, els colors de l\\'aplicació s\\'adaptaran als colors del fons de pantalla</string>\n    <string name=\"failed_to_save\">No s\\'ha pogut desar %d imatges</string>\n    <string name=\"search_here\">Cerca aquí</string>\n    <string name=\"email\">Correu electrònic</string>\n    <string name=\"secondary\">Secundari</string>\n    <string name=\"tertiary\">Terciari</string>\n    <string name=\"border_thickness\">Gruix de la vora</string>\n    <string name=\"grant_permission_manual\">L\\'aplicació necessita aquest permís per funcionar, concediu-lo manualment</string>\n    <string name=\"monet_colors\">Colors de Monet</string>\n    <string name=\"values\">Valors</string>\n    <string name=\"add\">Afegeix</string>\n    <string name=\"external_storage\">Emmagatzematge extern</string>\n    <string name=\"permission\">Permís</string>\n    <string name=\"fab_alignment\">Alineació FAB</string>\n    <string name=\"check_updates\">Comprova si hi ha actualitzacions</string>\n    <string name=\"zoom\">Ampliació de la imatge</string>\n    <string name=\"prefix\">Prefix</string>\n    <string name=\"filename\">Nom del fitxer</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Seleccioneu quin emoji es mostrarà a la pantalla principal</string>\n    <string name=\"add_file_size\">Afegeix la mida del fitxer</string>\n    <string name=\"add_file_size_sub\">Si està habilitat, afegeix l\\'amplada i l\\'alçada de la imatge al nom del fitxer de sortida</string>\n    <string name=\"delete_exif\">Suprimeix l\\'EXIF</string>\n    <string name=\"check_updates_sub\">Si està habilitat, es mostrarà el diàleg d\\'actualització en iniciar l\\'aplicació</string>\n    <string name=\"share\">Comparteix</string>\n    <string name=\"delete_exif_sub\">Suprimeix les metadades EXIF de qualsevol conjunt d\\'imatges</string>\n    <string name=\"image_preview\">Previsualització de la imatge</string>\n    <string name=\"image_preview_sub\">Previsualitza qualsevol tipus d\\'imatges: GIF, SVG, etc.</string>\n    <string name=\"image_source\">Font de la imatge</string>\n    <string name=\"photo_picker\">Selector de fotos</string>\n    <string name=\"gallery_picker\">Galeria</string>\n    <string name=\"file_explorer_picker\">Explorador de fitxers</string>\n    <string name=\"photo_picker_sub\">El selector de fotos modern d\\'Android que apareix a la part inferior de la pantalla, pot funcionar només en Android 12 o superior. Té problemes en rebre les metadades EXIF</string>\n    <string name=\"gallery_picker_sub\">Selector simple d\\'imatges de galeria. Només funcionarà si teniu una aplicació que proporciona la selecció de fotos</string>\n    <string name=\"file_explorer_picker_sub\">Utilitza GetContent per triar una imatge. Funciona a tot arreu, però se sap que té problemes per rebre imatges seleccionades en alguns dispositius.</string>\n    <string name=\"options_arrangement\">Arranjament de les opcions</string>\n    <string name=\"add_original_filename\">Afegeix el nom del fitxer original</string>\n    <string name=\"order\">Ordre</string>\n    <string name=\"emojis_count\">Nombre d\\'emojis</string>\n    <string name=\"replace_sequence_number\">Reemplaça el nombre de seqüència</string>\n    <string name=\"filename_not_work_with_photopicker\">L\\'addició del nom del fitxer original no funciona si s\\'ha seleccionat la font d\\'imatge del selector de fotos</string>\n    <string name=\"load_image_from_net_sub\">Carregueu qualsevol imatge des d\\'Internet per a previsualitzar-la, ampliar-la, editar-la i desar-la.</string>\n    <string name=\"image_link\">Enllaç de la imatge</string>\n    <string name=\"replace_sequence_number_sub\">Si està habilitat, substituirà la marca horària estàndard al número de seqüència de la imatge si utilitzeu el processament per lots</string>\n    <string name=\"load_image_from_net\">Carrega la imatge des de la xarxa</string>\n    <string name=\"no_image\">Sense imatge</string>\n    <string name=\"content_scale\">Escala del contingut</string>\n    <string name=\"hue\">To</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"exposure\">Exposició</string>\n    <string name=\"temperature\">Temperatura</string>\n    <string name=\"vibrance\">Vivacitat</string>\n    <string name=\"crosshatch\">Ombreig</string>\n    <string name=\"emboss\">Relleu</string>\n    <string name=\"start\">Inicia</string>\n    <string name=\"sketch\">Esbós</string>\n    <string name=\"posterize\">Posteritza</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"fast_blur\">Difuminat ràpid</string>\n    <string name=\"blur_center_y\">Centre del difuminat y</string>\n    <string name=\"color_balance\">Equilibri de color</string>\n    <string name=\"file_proceed\">Fitxer processat</string>\n    <string name=\"store_file_desc\">Emmagatzema aquest fitxer al dispositiu o utilitza l\\'acció de compartició per posar-lo allà on vulgueu</string>\n    <string name=\"compatibility\">Compatibilitat</string>\n    <string name=\"implementation_sub\">AES-256, mode GCM, sense farciment, 12 bytes IVs aleatoris. Les claus s\\'utilitzen com a sumes de verificació SHA-3 (256 bits).</string>\n    <string name=\"file_size\">Mida del fitxer</string>\n    <string name=\"fill\">Omple</string>\n    <string name=\"fit\">Ajusta</string>\n    <string name=\"flexible_description\">Canvia la mida de les imatges a les imatges amb un costat llarg donat pel paràmetre d\\'amplada o alçada, tots els càlculs de la mida es faran després de desar - això manté la relació d\\'aspecte</string>\n    <string name=\"brightness\">Brillantor</string>\n    <string name=\"add_filter\">Afegeix un filtre</string>\n    <string name=\"filter_sub\">Aplica qualsevol cadena de filtres a les imatges indicades</string>\n    <string name=\"filters\">Filtres</string>\n    <string name=\"light_aka_illumination\">Llum</string>\n    <string name=\"white_balance\">Balanç de blancs</string>\n    <string name=\"monochrome\">Monocrom</string>\n    <string name=\"saturation\">Saturació</string>\n    <string name=\"filter\">Filtre</string>\n    <string name=\"color_filter\">Filtre de color</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Ressaltats i ombres</string>\n    <string name=\"sepia\">Sèpia</string>\n    <string name=\"negative\">Negatiu</string>\n    <string name=\"highlights\">Ressaltats</string>\n    <string name=\"shadows\">Ombres</string>\n    <string name=\"haze\">Boira</string>\n    <string name=\"distance\">Distància</string>\n    <string name=\"slope\">Pendent</string>\n    <string name=\"sharpen\">Aguditza</string>\n    <string name=\"effect\">Efecte</string>\n    <string name=\"solarize\">Solaritza</string>\n    <string name=\"spacing\">Espaiat</string>\n    <string name=\"sobel_edge\">Vora Sobel</string>\n    <string name=\"black_and_white\">Blanc i negre</string>\n    <string name=\"line_width\">Amplada de la línia</string>\n    <string name=\"blur\">Difuminat</string>\n    <string name=\"halftone\">Semi to</string>\n    <string name=\"box_blur\">Caixa de difuminat</string>\n    <string name=\"vignette\">Vinyeta</string>\n    <string name=\"cga_colorspace\">Espai de color CGA</string>\n    <string name=\"gaussian_blur\">Difuminat gaussià</string>\n    <string name=\"end\">Fi</string>\n    <string name=\"bilaterial_blur\">Difuminat bilateral</string>\n    <string name=\"laplacian\">Laplacià</string>\n    <string name=\"kuwahara\">Suavització Kuwahara</string>\n    <string name=\"stack_blur\">Difuminat de pila</string>\n    <string name=\"radius\">Radi</string>\n    <string name=\"scale\">Escala</string>\n    <string name=\"blur_size\">Mida del difuminat</string>\n    <string name=\"distortion\">Distorsió</string>\n    <string name=\"angle\">Angle</string>\n    <string name=\"swirl\">Remolí</string>\n    <string name=\"bulge\">Protuberància</string>\n    <string name=\"refractive_index\">Índex de refracció</string>\n    <string name=\"dilation\">Dilatació</string>\n    <string name=\"sphere_refraction\">Refracció de l\\'esfera</string>\n    <string name=\"opacity\">Opacitat</string>\n    <string name=\"glass_sphere_refraction\">Refracció de l\\'esfera de vidre</string>\n    <string name=\"color_matrix\">Matriu de color</string>\n    <string name=\"limits_resize\">Límits del redimensionat</string>\n    <string name=\"threshold\">Llindar</string>\n    <string name=\"smooth_toon\">Toon suau</string>\n    <string name=\"non_maximum_suppression\">Supressió no màxima</string>\n    <string name=\"lookup\">Cerca</string>\n    <string name=\"blur_center_x\">Centre del difuminat x</string>\n    <string name=\"zoom_blur\">Difuminat d\\'ampliació</string>\n    <string name=\"convolution3x3\">Convolució 3x3</string>\n    <string name=\"rgb_filter\">Filtre RGB</string>\n    <string name=\"first_color\">Primer color</string>\n    <string name=\"second_color\">Segon color</string>\n    <string name=\"reorder\">Reordena</string>\n    <string name=\"luminance_threshold\">Llindar de luminància</string>\n    <string name=\"limits_resize_sub\">Redimensiona les imatges seleccionades per a seguir els límits d\\'amplada i alçada indicats mentre es desa la relació d\\'aspecte</string>\n    <string name=\"quantizationLevels\">Nivells de quantificació</string>\n    <string name=\"weak_pixel_inclusion\">Inclusió de píxels febles</string>\n    <string name=\"false_color\">Color fals</string>\n    <string name=\"activate_files\">Heu desactivat l\\'aplicació Fitxers, activeu-la per utilitzar aquesta característica</string>\n    <string name=\"draw\">Dibuixa</string>\n    <string name=\"draw_sub\">Dibuixa sobre la imatge com en un quadern de dibuix, o dibuixa sobre el fons mateix</string>\n    <string name=\"paint_color\">Color de pintura</string>\n    <string name=\"paint_alpha\">Pintura alfa</string>\n    <string name=\"draw_on_image_sub\">Trieu una imatge i dibuixeu-hi alguna cosa</string>\n    <string name=\"draw_on_image\">Dibuixa a la imatge</string>\n    <string name=\"draw_on_background\">Dibuixa sobre el fons</string>\n    <string name=\"draw_on_background_sub\">Tria el color de fons i dibuixeu sobre seu</string>\n    <string name=\"pick_file\">Tria un fitxer</string>\n    <string name=\"encrypt\">Xifra</string>\n    <string name=\"background_color\">Color de fons</string>\n    <string name=\"cipher\">Xifra</string>\n    <string name=\"cipher_sub\">Xifra i desxifra qualsevol fitxer (no només la imatge) basat en l\\'algorisme criptogràfic AES</string>\n    <string name=\"features\">Característiques</string>\n    <string name=\"decryption\">Desxifratge</string>\n    <string name=\"encryption\">Xifratge</string>\n    <string name=\"implementation\">Implementació</string>\n    <string name=\"decrypt\">Desxifra</string>\n    <string name=\"pick_file_to_start\">Trieu el fitxer per iniciar</string>\n    <string name=\"key\">Clau</string>\n    <string name=\"features_sub\">Xifratge de fitxers basat en contrasenya. Els fitxers processats es poden emmagatzemar al directori seleccionat o compartit. Els fitxers desxifrats també es poden obrir directament.</string>\n    <string name=\"reset_image_sub\">e</string>\n    <string name=\"close\">Tanca</string>\n    <string name=\"save\">Desa</string>\n    <string name=\"cancel\">Cancel·la</string>\n    <string name=\"crop\">Escapça</string>\n    <string name=\"single_edit\">Edició única</string>\n    <string name=\"pick_color\">Tria el color</string>\n    <string name=\"update\">Actualitza</string>\n    <string name=\"def\">Per defecte</string>\n    <string name=\"crop_sub\">Escapça la imatge a qualsevol límit</string>\n    <string name=\"remove\">Suprimeix</string>\n    <string name=\"max_bytes\">Mida màxima en KB</string>\n    <string name=\"generate_palette\">Genera la paleta</string>\n    <string name=\"no_palette\">No s\\'ha pogut generar la paleta per a la imatge donada</string>\n    <string name=\"by_bytes_resize\">Redimensiona per pes</string>\n    <string name=\"dark\">Fosc</string>\n    <string name=\"night_mode\">Mode nocturn</string>\n    <string name=\"system\">Sistema</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Enganxa un codi aRGB vàlid.</string>\n    <string name=\"donation_sub\">Aquesta aplicació és totalment gratuïta, però si voleu donar suport al desenvolupament del projecte feu clic aquí</string>\n    <string name=\"edit\">Edita</string>\n    <string name=\"order_sub\">Determina l\\'ordre de les opcions a la pantalla principal</string>\n    <string name=\"add_original_filename_sub\">Si està habilitat, afegeix el nom del fitxer original al nom de la imatge de sortida</string>\n    <string name=\"clear_exif\">Esborra l\\'EXIF</string>\n    <string name=\"clear\">Esborra</string>\n    <string name=\"image_not_saved_sub\">Si sortiu ara es perdran tots els canvis no desats</string>\n    <string name=\"check_source_code\">Codi font</string>\n    <string name=\"version\">Versió</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"original\">Original</string>\n    <string name=\"compare\">Compara</string>\n    <string name=\"light\">Clar</string>\n    <string name=\"new_version\">Nova versió %1$s</string>\n    <string name=\"allow_image_monet_sub\">Si està habilitat, quan trieu una imatge per editar-la, els colors de l\\'aplicació s\\'adaptaran a ella</string>\n    <string name=\"amoled_mode\">Mode AMOLED</string>\n    <string name=\"amoled_mode_sub\">Si està activat, en el mode nocturn el color de les superfícies s\\'establirà a la foscor absoluta</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">No es pot canviar l\\'esquema de color de l\\'aplicació mentre els colors dinàmics estan activats</string>\n    <string name=\"issue_tracker_sub\">Envieu aquí els informes d\\'error i les sol·licituds de funcionalitats</string>\n    <string name=\"help_translate\">Ajudeu a traduir</string>\n    <string name=\"help_translate_sub\">Corregiu errors de traducció o localitzeu el projecte a altres idiomes</string>\n    <string name=\"primary\">Primari</string>\n    <string name=\"surface\">Superfície</string>\n    <string name=\"grant\">Atorga</string>\n    <string name=\"permission_sub\">L\\'aplicació necessita accés al vostre emmagatzematge per tal que es pugui desar imatges. Si us plau, concediu el permís en el quadre de diàleg que s\\'obrirà ara.</string>\n    <string name=\"sequence_num\">númSeqüència</string>\n    <string name=\"original_filename\">nomFitxerOriginal</string>\n    <string name=\"explicit_description\">Força cada imatge pels paràmetres d\\'amplada i alçada - pot canviar la relació d\\'aspecte</string>\n    <string name=\"contrast\">Contrast</string>\n    <string name=\"tint\">Tint</string>\n    <string name=\"loading\">S\\'està carregant…</string>\n    <string name=\"image_too_large_preview\">La imatge és massa grossa per a previsualitzar-la, però es provarà de desar igualment</string>\n    <string name=\"secondary_customization\">Personalització secundària</string>\n    <string name=\"screenshot\">Captura de pantalla</string>\n    <string name=\"fallback_option\">Opció de reserva</string>\n    <string name=\"background_remover\">Eliminador de fons</string>\n    <string name=\"restore_image\">Restaura la imatge</string>\n    <string name=\"blur_radius\">Radi difuminat</string>\n    <string name=\"analytics\">Analítica</string>\n    <string name=\"analytics_sub\">Permet recopilar estadístiques anònimes d\\'ús d\\'aplicacions</string>\n    <string name=\"effort\">Esforç</string>\n    <string name=\"wait\">Espera</string>\n    <string name=\"saving_almost_complete\">S\\'ha desat gairebé completament. Si ho cancel·leu ara, caldrà tornar-ho a desar.</string>\n    <string name=\"updates\">Actualitzacions</string>\n    <string name=\"draw_arrows\">Dibuixa fletxes</string>\n    <string name=\"draw_arrows_sub\">Si està activat, el camí de dibuix es representarà com a fletxa apuntant</string>\n    <string name=\"images_order\">Ordre d\\'imatges</string>\n    <string name=\"enhanced_circle_pixelation\">Pixelació del cercle millorada</string>\n    <string name=\"check_for_updates\">Buscar actualitzacions</string>\n    <string name=\"rainbow\">Arc de Sant Martí</string>\n    <string name=\"neutral_sub\">Un estil lleugerament més cromàtic que monocromàtic</string>\n    <string name=\"attention\">Atenció</string>\n    <string name=\"images_to_pdf\">Imatges a PDF</string>\n    <string name=\"add_mask\">Afegeix una màscara</string>\n    <string name=\"end_position\">Final</string>\n    <string name=\"simple_variants\">Variants simples</string>\n    <string name=\"highlighter\">Ressaltador</string>\n    <string name=\"containers_shadow\">Contenidors</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"app_bars_shadow\">Barres d\\'aplicacions</string>\n    <string name=\"app_bars_shadow_sub\">Habilita el dibuix d\\'ombres darrere de les barres d\\'aplicacions</string>\n    <string name=\"value_in_range\">Valor en l\\'interval %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Rotació automàtica</string>\n    <string name=\"double_line_arrow\">Fletxa de doble línia</string>\n    <string name=\"double_arrow\">Doble fletxa</string>\n    <string name=\"stitch_mode\">Mode de puntada</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Més proper</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Bàsic</string>\n    <string name=\"nearest_sub\">Una de les maneres més senzilles d\\'augmentar la mida, substituint cada píxel per un nombre de píxels del mateix color</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"downloaded_languages\">Idiomes descarregats</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Text vertical d\\'un sol bloc</string>\n    <string name=\"segmentation_mode_single_char\">Caràcter únic</string>\n    <string name=\"segmentation_mode_sparse_text\">Text escàs</string>\n    <string name=\"segmentation_mode_raw_line\">Línia crua</string>\n    <string name=\"transformations\">Transformacions</string>\n    <string name=\"repeat_watermark\">Repetiu la marca d\\'aigua</string>\n    <string name=\"offset_x\">Desplaçament X</string>\n    <string name=\"gif_type_to_image\">GIF a imatges</string>\n    <string name=\"use_lasso_sub\">Utilitza Lasso com en el mode de dibuix per esborrar</string>\n    <string name=\"preview_closing\">Si deixeu la vista prèvia ara, haureu d\\'afegir les imatges de nou</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"glitch\">Glitch</string>\n    <string name=\"enhanced_glitch\">Glitch millorat</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"turbulence\">Turbulència</string>\n    <string name=\"oil\">Oli</string>\n    <string name=\"amplitude_y\">Amplitud Y</string>\n    <string name=\"perlin_distortion\">Distorsió Perlin</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"dehaze\">Desembolica</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Color Matrix 4x4</string>\n    <string name=\"simple_effects\">Efectes simples</string>\n    <string name=\"protonomaly\">Protanomalia</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"autumn_tones\">Tons de tardor</string>\n    <string name=\"old_tv\">Televisió antiga</string>\n    <string name=\"shuffle_blur\">Difuminat aleatori</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">Tingueu en compte que la compatibilitat amb altres programes o serveis de xifratge de fitxers no està garantida. Un tractament de clau o una configuració de xifratge lleugerament diferent pot provocar incompatibilitats.</string>\n    <string name=\"invalid_password_or_not_encrypted\">La contrasenya no vàlida o el fitxer escollit no està xifrat</string>\n    <string name=\"image_size_warning\">Intentar desar la imatge amb una amplada i una alçada determinades pot provocar un error de MOO. Fes-ho sota el teu propi risc i no diguis que no t\\'he advertit!</string>\n    <string name=\"cache\">Memòria cau</string>\n    <string name=\"cache_size\">Mida de la memòria cau</string>\n    <string name=\"found_s\">S\\'ha trobat %1$s</string>\n    <string name=\"auto_cache_clearing\">Esborrada automàtica de la memòria cau</string>\n    <string name=\"auto_cache_clearing_sub\">Si està activada, la memòria cau de l\\'aplicació s\\'esborrarà a l\\'inici de l\\'aplicació</string>\n    <string name=\"create\">Crear</string>\n    <string name=\"tools\">Eines</string>\n    <string name=\"group_options_by_type\">Agrupa les opcions per tipus</string>\n    <string name=\"edit_screenshot\">Edita la captura de pantalla</string>\n    <string name=\"group_options_by_type_sub\">Agrupa les opcions de la pantalla principal pel seu tipus en lloc d\\'una disposició de llista personalitzada</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">No es pot canviar la disposició mentre l\\'agrupació d\\'opcions està activada</string>\n    <string name=\"skip\">Omet</string>\n    <string name=\"copy\">Copia</string>\n    <string name=\"warning_bytes\">Desar en mode %1$s pot ser inestable, perquè és un format sense pèrdues</string>\n    <string name=\"presets_sub\" formatted=\"false\">Si heu seleccionat el valor predefinit 125, la imatge es desarà com a mida del 125% de la imatge original amb una qualitat del 100%. Si trieu el valor predefinit 50, la imatge es desarà amb un 50% de mida i un 50% de qualitat.</string>\n    <string name=\"presets_sub_bytes\">El valor predefinit aquí determina el percentatge del fitxer de sortida, és a dir, si seleccioneu el valor predefinit 50 en una imatge de 5 MB, obtindreu una imatge de 2,5 MB després de desar-lo.</string>\n    <string name=\"randomize_filename\">Aleatoritzar el nom del fitxer</string>\n    <string name=\"randomize_filename_sub\">Si està activat, el nom del fitxer de sortida serà totalment aleatori</string>\n    <string name=\"saved_to\">S\\'ha desat a la carpeta %1$s amb el nom %2$s</string>\n    <string name=\"saved_to_without_filename\">S\\'ha desat a la carpeta %1$s</string>\n    <string name=\"tg_chat\">Xat de Telegram</string>\n    <string name=\"tg_chat_sub\">Parleu de l\\'aplicació i obteniu comentaris d\\'altres usuaris. També podeu obtenir actualitzacions beta i estadístiques aquí.</string>\n    <string name=\"crop_mask\">Màscara de cultiu</string>\n    <string name=\"aspect_ratio\">Relació d\\'aspecte</string>\n    <string name=\"image_crop_mask_sub\">Utilitzeu aquest tipus de màscara per crear una màscara a partir d\\'una imatge donada, tingueu en compte que HA de tenir un canal alfa</string>\n    <string name=\"backup_and_restore\">Còpia de seguretat i restauració</string>\n    <string name=\"backup\">Còpia de seguretat</string>\n    <string name=\"restore\">Restaurar</string>\n    <string name=\"backup_sub\">Feu una còpia de seguretat de la configuració de l\\'aplicació en un fitxer</string>\n    <string name=\"restore_sub\">Restaura la configuració de l\\'aplicació des del fitxer generat anteriorment</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Fitxer danyat o no és una còpia de seguretat</string>\n    <string name=\"settings_restored\">La configuració s\\'ha restaurat correctament</string>\n    <string name=\"contact_me\">Contacta amb mi</string>\n    <string name=\"reset_settings_sub\">Això tornarà a la vostra configuració als valors predeterminats. Tingueu en compte que això no es pot desfer sense un fitxer de còpia de seguretat esmentat anteriorment.</string>\n    <string name=\"delete\">Suprimeix</string>\n    <string name=\"delete_color_scheme_warn\">Esteu a punt d\\'eliminar l\\'esquema de colors seleccionat. Aquesta operació no es pot desfer</string>\n    <string name=\"delete_color_scheme_title\">Suprimeix l\\'esquema</string>\n    <string name=\"font\">Font</string>\n    <string name=\"text\">Text</string>\n    <string name=\"font_scale\">Escala de lletra</string>\n    <string name=\"defaultt\">Per defecte</string>\n    <string name=\"using_large_fonts_warn\">L\\'ús de lletres grosses pot provocar errors i problemes a la interfície d\\'usuari, i no se solucionaran. Feu-ho servir amb precaució.</string>\n    <string name=\"alphabet_and_numbers\">Aa Àà Bb Cc Çç Dd Ee Èè Éé Ff Gg Hh Ii Íí Ll L·l Mm Nn Oo Òò Óó Pp Qq Rr Ss Tt Uu Úú Vv Xx Yy Zz 0123456789 !?</string>\n    <string name=\"emotions\">Emocions</string>\n    <string name=\"food_and_drink\">Menjar i beguda</string>\n    <string name=\"nature_and_animals\">Natura i Animals</string>\n    <string name=\"objects\">Objectes</string>\n    <string name=\"symbols\">Símbols</string>\n    <string name=\"enable_emoji\">Activa els emoji</string>\n    <string name=\"travels_and_places\">Viatges i Llocs</string>\n    <string name=\"activities\">Activitats</string>\n    <string name=\"trim_image\">Retalla la imatge</string>\n    <string name=\"background_remover_sub\">Elimina el fons de la imatge dibuixant o utilitza l\\'opció Automàtica</string>\n    <string name=\"keep_exif_sub\">Es conservaran les metadades de la imatge original</string>\n    <string name=\"trim_image_sub\">Els espais transparents al voltant de la imatge es retallaran</string>\n    <string name=\"auto_erase_background\">Esborra automàticament el fons</string>\n    <string name=\"erase_mode\">Mode d\\'esborrar</string>\n    <string name=\"erase_background\">Esborra el fons</string>\n    <string name=\"restore_background\">Restaura el fons</string>\n    <string name=\"pipette\">Pipeta</string>\n    <string name=\"draw_mode\">Mode dibuix</string>\n    <string name=\"create_issue\">Crea un problema</string>\n    <string name=\"something_went_wrong_emphasis\">Vaja… S\\'ha produït un error. Podeu escriure\\'m mitjançant les opcions següents i intentaré trobar una solució</string>\n    <string name=\"resize_and_convert\">Canviar la mida i convertir</string>\n    <string name=\"resize_and_convert_sub\">Canvia la mida de les imatges donades o converteix-les a altres formats. Les metadades EXIF també es poden editar aquí si trieu una sola imatge.</string>\n    <string name=\"max_colors_count\">Recompte màxim de colors</string>\n    <string name=\"crashlytics_sub\">Això permet que l\\'aplicació reculli informes d\\'error manualment</string>\n    <string name=\"image_exif_warning\">Actualment, el format %1$s només permet llegir metadades EXIF a Android. La imatge de sortida no tindrà metadades en absolut quan es desi.</string>\n    <string name=\"effort_sub\">Un valor de %1$s significa una compressió ràpida, que resulta en una mida de fitxer relativament gran. %2$s significa una compressió més lenta, donant lloc a un fitxer més petit.</string>\n    <string name=\"allow_betas\">Permet betas</string>\n    <string name=\"allow_betas_sub\">La comprovació d\\'actualitzacions inclourà les versions beta de l\\'aplicació si està activada</string>\n    <string name=\"brush_softness\">suavitat del pinzell</string>\n    <string name=\"crop_description\">Les imatges es retallaran al centre a la mida introduïda. El llenç s\\'ampliarà amb el color de fons donat si la imatge és més petita que les dimensions introduïdes.</string>\n    <string name=\"donation\">Donació</string>\n    <string name=\"image_stitching\">Costura de la imatge</string>\n    <string name=\"pick_at_least_two_images\">Trieu almenys 2 imatges</string>\n    <string name=\"image_stitching_sub\">Combina les imatges donades per obtenir-ne una de gran</string>\n    <string name=\"output_image_scale\">Escala d\\'imatge de sortida</string>\n    <string name=\"image_orientation\">Orientació de la imatge</string>\n    <string name=\"horizontal\">Horitzontal</string>\n    <string name=\"vertical\">Vertical</string>\n    <string name=\"scale_small_images_to_large\">Escala imatges petites a grans</string>\n    <string name=\"scale_small_images_to_large_sub\">Les imatges petites s\\'escalaran a la més gran de la seqüència si està activada</string>\n    <string name=\"regular\">Regular</string>\n    <string name=\"blur_edges\">Difumina les vores</string>\n    <string name=\"blur_edges_sub\">Dibuixa vores borroses sota la imatge original per omplir espais al seu voltant en lloc d\\'un sol color si està activat</string>\n    <string name=\"pixelation\">Pixelació</string>\n    <string name=\"enhanced_pixelation\">Pixelació millorada</string>\n    <string name=\"stroke_pixelation\">Pixelació del traç</string>\n    <string name=\"enhanced_diamond_pixelation\">Pixelació del diamant millorada</string>\n    <string name=\"diamond_pixelation\">Pixelació del diamant</string>\n    <string name=\"circle_pixelation\">Pixelació del cercle</string>\n    <string name=\"replace_color\">Substitueix el color</string>\n    <string name=\"tolerance\">Tolerància</string>\n    <string name=\"color_to_replace\">Color per substituir</string>\n    <string name=\"target_color\">Color objectiu</string>\n    <string name=\"color_to_remove\">Color per eliminar</string>\n    <string name=\"remove_color\">Elimina el color</string>\n    <string name=\"recode\">Recodificar</string>\n    <string name=\"pixel_size\">Mida de píxels</string>\n    <string name=\"lock_draw_orientation\">Bloqueja l\\'orientació del dibuix</string>\n    <string name=\"lock_draw_orientation_sub\">Si està activat en mode de dibuix, la pantalla no girarà</string>\n    <string name=\"palette_style\">Estil de paleta</string>\n    <string name=\"tonal_spot\">Taca tonal</string>\n    <string name=\"neutral\">Neutre</string>\n    <string name=\"vibrant\">Vibrant</string>\n    <string name=\"expressive\">Expressiu</string>\n    <string name=\"fruit_salad\">Amanida de fruita</string>\n    <string name=\"fidelity\">Fidelitat</string>\n    <string name=\"content\">Contingut</string>\n    <string name=\"tonal_spot_sub\">Estil de paleta predeterminat, permet personalitzar els quatre colors, d\\'altres permeten establir només el color clau</string>\n    <string name=\"vibrant_sub\">Un tema fort, el colorit és màxim per a la paleta primària, augmentat per als altres</string>\n    <string name=\"playful_scheme\">Un tema lúdic: la tonalitat del color d\\'origen no apareix al tema</string>\n    <string name=\"monochrome_sub\">Un tema monocrom, els colors són purament negre / blanc / gris</string>\n    <string name=\"content_sub\">Un esquema que col·loca el color d\\'origen a Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Un esquema molt semblant a l\\'esquema de contingut</string>\n    <string name=\"foss_update_checker_warning\">Aquest verificador d\\'actualitzacions es connectarà a GitHub per comprovar si hi ha una nova actualització disponible</string>\n    <string name=\"fading_edges\">Vores esvaïdes</string>\n    <string name=\"disabled\">Inhabilitat</string>\n    <string name=\"both\">Tots dos</string>\n    <string name=\"invert_colors\">Invertir colors</string>\n    <string name=\"invert_colors_sub\">Substitueix els colors del tema per negatius si està activat</string>\n    <string name=\"search_option\">Cerca</string>\n    <string name=\"search_option_sub\">Permet la possibilitat de cercar a través de totes les opcions disponibles a la pantalla principal</string>\n    <string name=\"pdf_tools\">Eines PDF</string>\n    <string name=\"pdf_tools_sub\">Opera amb fitxers PDF: previsualitza, converteix en lots d\\'imatges o crea\\'n una a partir d\\'imatges donades</string>\n    <string name=\"preview_pdf\">Vista prèvia del PDF</string>\n    <string name=\"pdf_to_images\">PDF a Imatges</string>\n    <string name=\"preview_pdf_sub\">Vista prèvia senzilla de PDF</string>\n    <string name=\"pdf_to_images_sub\">Converteix PDF a imatges en un format de sortida determinat</string>\n    <string name=\"images_to_pdf_sub\">Empaqueta les imatges donades al fitxer PDF de sortida</string>\n    <string name=\"mask_filter\">Filtre de màscara</string>\n    <string name=\"mask_filter_sub\">Apliqueu cadenes de filtres a àrees emmascarades determinades, cada àrea de màscara pot determinar el seu propi conjunt de filtres</string>\n    <string name=\"masks\">Màscares</string>\n    <string name=\"mask_indexed\">Màscara %d</string>\n    <string name=\"mask_color\">Color de la màscara</string>\n    <string name=\"mask_preview\">Vista prèvia de la màscara</string>\n    <string name=\"mask_preview_sub\">Es representarà la màscara de filtre dibuixada per mostrar-vos el resultat aproximat</string>\n    <string name=\"inverse_fill_type\">Tipus de farciment invers</string>\n    <string name=\"inverse_fill_type_sub\">Si està activat, es filtraran totes les àrees no emmascarades en lloc del comportament predeterminat</string>\n    <string name=\"delete_mask_warn\">Esteu a punt d\\'eliminar la màscara de filtre seleccionada. Aquesta operació no es pot desfer</string>\n    <string name=\"delete_mask\">Suprimeix la màscara</string>\n    <string name=\"full_filter\">Filtre complet</string>\n    <string name=\"neon\">Neó</string>\n    <string name=\"full_filter_sub\">Apliqueu qualsevol cadena de filtres a imatges donades o imatge única</string>\n    <string name=\"pen\">Bolígraf</string>\n    <string name=\"start_position\">Començar</string>\n    <string name=\"center_position\">Centre</string>\n    <string name=\"privacy_blur\">Difuminat de privadesa</string>\n    <string name=\"highlighter_sub\">Dibuixa camins de ressaltat nítids semitransparents</string>\n    <string name=\"neon_sub\">Afegeix un efecte brillant als teus dibuixos</string>\n    <string name=\"privacy_blur_sub\">Difumina la imatge sota el camí dibuixat per protegir tot el que vulgueu amagar</string>\n    <string name=\"pen_sub\">Un per defecte, el més senzill: només el color</string>\n    <string name=\"pixelation_sub\">Similar al difuminat de privadesa, però es pixela en lloc de desenfocar</string>\n    <string name=\"containers_shadow_sub\">Habilita el dibuix d\\'ombres darrere dels contenidors</string>\n    <string name=\"sliders_shadow\">Lliscants</string>\n    <string name=\"switches_shadow\">Interruptors</string>\n    <string name=\"buttons_shadow\">Botons</string>\n    <string name=\"sliders_shadow_sub\">Activa el dibuix d\\'ombres darrere dels controls lliscants</string>\n    <string name=\"switches_shadow_sub\">Habilita el dibuix d\\'ombres darrere dels interruptors</string>\n    <string name=\"fabs_shadow_sub\">Habilita el dibuix d\\'ombres darrere dels botons d\\'acció flotants</string>\n    <string name=\"buttons_shadow_sub\">Habilita el dibuix d\\'ombres darrere dels botons predeterminats</string>\n    <string name=\"auto_rotate_limits_sub\">Permet adoptar un quadre de límit per a l\\'orientació de la imatge</string>\n    <string name=\"draw_path_mode\">Mode de dibuix del camí</string>\n    <string name=\"free_drawing\">Dibuix lliure</string>\n    <string name=\"line_arrow\">Fletxa de línia</string>\n    <string name=\"arrow\">Fletxa</string>\n    <string name=\"line\">Línia</string>\n    <string name=\"free_drawing_sub\">Dibuixa el camí com a valor d\\'entrada</string>\n    <string name=\"line_sub\">Dibuixa el camí des del punt inicial fins al punt final com una línia</string>\n    <string name=\"line_arrow_sub\">Dibuixa la fletxa apuntant des del punt inicial fins al punt final com una línia</string>\n    <string name=\"arrow_sub\">Dibuixa una fletxa apuntant des d\\'un camí determinat</string>\n    <string name=\"double_line_arrow_sub\">Dibuixa una fletxa apuntant doble des del punt inicial fins al punt final com una línia</string>\n    <string name=\"double_arrow_sub\">Dibuixa una fletxa apuntant doble des d\\'un camí determinat</string>\n    <string name=\"outlined_oval\">Oval perfilat</string>\n    <string name=\"outlined_rect\">Esbossat Rect</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Dibuixa recte des del punt inicial fins al punt final</string>\n    <string name=\"oval_sub\">Dibuixa un oval des del punt inicial fins al punt final</string>\n    <string name=\"outlined_oval_sub\">Dibuixa un oval delineat des del punt inicial fins al punt final</string>\n    <string name=\"outlined_rect_sub\">Dibuixa el recte delineat des del punt inicial fins al punt final</string>\n    <string name=\"lasso\">Lazo</string>\n    <string name=\"lasso_sub\">Dibuixa un camí ple tancat per un camí donat</string>\n    <string name=\"free\">Gratuït</string>\n    <string name=\"horizontal_grid\">Quadrícula horitzontal</string>\n    <string name=\"vertical_grid\">Quadrícula vertical</string>\n    <string name=\"rows_count\">Recompte de files</string>\n    <string name=\"columns_count\">Recompte de columnes</string>\n    <string name=\"no_such_directory\">No s\\'ha trobat cap directori \\\"%1$s\\\", l\\'hem canviat a un per defecte. Torneu a desar el fitxer</string>\n    <string name=\"clipboard\">Porta-retalls</string>\n    <string name=\"auto_pin\">Pin automàtic</string>\n    <string name=\"auto_pin_sub\">Afegeix automàticament la imatge desada al porta-retalls si està activat</string>\n    <string name=\"vibration\">Vibració</string>\n    <string name=\"vibration_strength\">Força de vibració</string>\n    <string name=\"overwrite_file_requirements\">Per sobreescriure els fitxers, heu d\\'utilitzar la font d\\'imatge \\\"Explorer\\\", proveu de tornar a seleccionar les imatges, hem canviat la font de la imatge a la necessària.</string>\n    <string name=\"overwrite_files\">Sobreescriu els fitxers</string>\n    <string name=\"overwrite_files_sub\">El fitxer original es substituirà per un de nou en comptes de desar-lo a la carpeta seleccionada, aquesta opció necessita que l\\'origen de la imatge sigui \\\"Explorador\\\" o GetContent, en canviar-ho, s\\'establirà automàticament</string>\n    <string name=\"empty\">Buit</string>\n    <string name=\"suffix\">Sufix</string>\n    <string name=\"scale_mode\">Mode d\\'escala</string>\n    <string name=\"bilinear\">Bilineal</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicúbic</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Ermita</string>\n    <string name=\"default_value\">Valor per defecte</string>\n    <string name=\"bilinear_sub\">La interpolació lineal (o bilineal, en dues dimensions) sol ser bona per canviar la mida d\\'una imatge, però provoca una suavització indesitjable dels detalls i encara pot ser una mica irregular.</string>\n    <string name=\"bicubic_sub\">Els millors mètodes d\\'escalat inclouen el remostreig de Lanczos i els filtres Mitchell-Netravali.</string>\n    <string name=\"basic_sub\">El mode d\\'escalat d\\'Android més senzill que s\\'utilitza en gairebé totes les aplicacions</string>\n    <string name=\"catmull_sub\">Mètode per interpolar i tornar a mostrejar sense problemes un conjunt de punts de control, utilitzat habitualment en gràfics per ordinador per crear corbes suaus</string>\n    <string name=\"hann_sub\">La funció de finestra s\\'aplica sovint en el processament del senyal per minimitzar les fuites espectrals i millorar la precisió de l\\'anàlisi de freqüència reduint les vores d\\'un senyal.</string>\n    <string name=\"hermite_sub\">Tècnica d\\'interpolació matemàtica que utilitza els valors i les derivades als extrems d\\'un segment de corba per generar una corba suau i contínua</string>\n    <string name=\"lanczos_sub\">Mètode de mostreig que manté una interpolació d\\'alta qualitat aplicant una funció de sincronització ponderada als valors de píxels</string>\n    <string name=\"mitchell_sub\">Mètode de remostreig que utilitza un filtre de convolució amb paràmetres ajustables per aconseguir un equilibri entre la nitidesa i l\\'antialiàsing a la imatge escalada</string>\n    <string name=\"spline_sub\">Utilitza funcions polinomials definides per trossos per interpolar i aproximar suaument una corba o una representació de forma flexible i contínua.</string>\n    <string name=\"only_clip\">Només Clip</string>\n    <string name=\"only_clip_sub\">No es realitzarà l\\'emmagatzematge i només s\\'intentarà posar la imatge al porta-retalls</string>\n    <string name=\"restore_background_sub\">El pinzell restaurarà el fons en lloc d\\'esborrar-lo</string>\n    <string name=\"recognize_text\">OCR (reconeix el text)</string>\n    <string name=\"recognize_text_sub\">Reconeix el text d\\'una imatge donada, més de 120 idiomes compatibles</string>\n    <string name=\"picture_has_no_text\">La imatge no té text o l\\'aplicació no l\\'ha trobat</string>\n    <string name=\"recognition_type\">Tipus de reconeixement</string>\n    <string name=\"fast\">Ràpid</string>\n    <string name=\"standard\">Estàndard</string>\n    <string name=\"download\">descarregar</string>\n    <string name=\"best\">El millor</string>\n    <string name=\"no_data\">No hi ha dades</string>\n    <string name=\"download_description\">Per al bon funcionament de Tesseract OCR, les dades d\\'entrenament addicionals (%1$s) s\\'han de baixar al vostre dispositiu. \\nVoleu baixar %2$s dades?</string>\n    <string name=\"no_connection\">No hi ha connexió, comproveu-ho i torneu-ho a provar per descarregar models de tren</string>\n    <string name=\"available_languages\">Idiomes disponibles</string>\n    <string name=\"segmentation_mode\">Mode de segmentació</string>\n    <string name=\"use_pixel_switch\">Utilitza Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">S\\'utilitzarà un commutador semblant a un píxel en lloc del material de Google que has basat</string>\n    <string name=\"saved_to_original\">Fitxer sobreescrit amb el nom %1$s a la destinació original</string>\n    <string name=\"magnifier\">Lupa</string>\n    <string name=\"magnifier_sub\">Activa la lupa a la part superior del dit en els modes de dibuix per a una millor accessibilitat</string>\n    <string name=\"force_exif_widget_initial_value\">Força el valor inicial</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Força el giny exif a comprovar inicialment</string>\n    <string name=\"allow_multiple_languages\">Permet diversos idiomes</string>\n    <string name=\"slide\">Diapositiva</string>\n    <string name=\"side_by_side\">Al costat de l\\'altre</string>\n    <string name=\"toggle_tap\">Canvia Toc</string>\n    <string name=\"transparency\">Transparència</string>\n    <string name=\"rate_app\">Valora l\\'aplicació</string>\n    <string name=\"rate\">Taxa</string>\n    <string name=\"rate_app_sub\">Aquesta aplicació és completament gratuïta, si voleu que sigui més gran, destaca el projecte a Github 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Orientació &amp; Només detecció d\\'scripts</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientació automàtica &amp; Detecció de guió</string>\n    <string name=\"segmentation_mode_auto_only\">Només automàtic</string>\n    <string name=\"segmentation_mode_auto\">Automàtic</string>\n    <string name=\"segmentation_mode_single_column\">Columna única</string>\n    <string name=\"segmentation_mode_single_block\">Bloc únic</string>\n    <string name=\"segmentation_mode_single_line\">Línia única</string>\n    <string name=\"segmentation_mode_single_word\">Paraula única</string>\n    <string name=\"segmentation_mode_circle_word\">Encercla paraula</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Orientació de text escàs &amp; Detecció d\\'scripts</string>\n    <string name=\"delete_language_sub\">Voleu suprimir les dades d\\'entrenament OCR de l\\'idioma \\\"%1$s\\\" per a tots els tipus de reconeixement o només per a un seleccionat (%2$s)?</string>\n    <string name=\"current\">Actual</string>\n    <string name=\"all\">Tots</string>\n    <string name=\"gradient_maker\">Creador de degradats</string>\n    <string name=\"gradient_maker_sub\">Creeu un degradat d\\'una mida de sortida determinada amb colors i tipus d\\'aparença personalitzats</string>\n    <string name=\"gradient_type_linear\">Lineal</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Escombra</string>\n    <string name=\"gradient_type\">Tipus de degradat</string>\n    <string name=\"center_x\">Centre X</string>\n    <string name=\"center_y\">Centre Y</string>\n    <string name=\"tile_mode\">Mode de mosaic</string>\n    <string name=\"tile_mode_repeated\">Es repeteix</string>\n    <string name=\"tile_mode_mirror\">Mirall</string>\n    <string name=\"tile_mode_clamp\">Pinça</string>\n    <string name=\"tile_mode_decal\">Adhesiu</string>\n    <string name=\"color_stops\">Color Stops</string>\n    <string name=\"add_color\">Afegeix color</string>\n    <string name=\"properties\">Propietats</string>\n    <string name=\"brightness_enforcement\">Aplicació de la brillantor</string>\n    <string name=\"screen\">Pantalla</string>\n    <string name=\"gradient_maker_type_image\">Superposició de degradat</string>\n    <string name=\"gradient_maker_type_image_sub\">Compon qualsevol degradat de la part superior de la imatge donada</string>\n    <string name=\"camera\">Càmera</string>\n    <string name=\"camera_sub\">Utilitza la càmera per fer fotos, tingueu en compte que només és possible obtenir una imatge d\\'aquesta font d\\'imatge</string>\n    <string name=\"watermarking\">Marca d\\'aigua</string>\n    <string name=\"watermarking_sub\">Cobrir imatges amb marques d\\'aigua de text/imatge personalitzables</string>\n    <string name=\"repeat_watermark_sub\">Repeteix la marca d\\'aigua sobre la imatge en lloc d\\'una sola en una posició determinada</string>\n    <string name=\"offset_y\">Desplaçament Y</string>\n    <string name=\"watermark_type\">Tipus de filigrana</string>\n    <string name=\"watermarking_image_sub\">Aquesta imatge s\\'utilitzarà com a patró per a la marca d\\'aigua</string>\n    <string name=\"text_color\">Color del text</string>\n    <string name=\"overlay_mode\">Mode de superposició</string>\n    <string name=\"gif_tools\">Eines GIF</string>\n    <string name=\"gif_tools_sub\">Converteix imatges a imatge GIF o extreu marcs d\\'una imatge GIF determinada</string>\n    <string name=\"gif_type_to_image_sub\">Converteix el fitxer GIF en un lot d\\'imatges</string>\n    <string name=\"gif_type_to_gif_sub\">Converteix un lot d\\'imatges a un fitxer GIF</string>\n    <string name=\"gif_type_to_gif\">Imatges a GIF</string>\n    <string name=\"select_gif_image_to_start\">Trieu la imatge GIF per començar</string>\n    <string name=\"use_size_of_first_frame\">Utilitzeu la mida del primer fotograma</string>\n    <string name=\"use_size_of_first_frame_sub\">Substituïu la mida especificada per les dimensions del primer marc</string>\n    <string name=\"repeat_count\">Repetiu el recompte</string>\n    <string name=\"frame_delay\">Retard de fotograma</string>\n    <string name=\"millis\">milis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Utilitzeu Lasso</string>\n    <string name=\"original_image_preview_alpha\">Vista prèvia de la imatge original Alpha</string>\n    <string name=\"confetti\">Confetti</string>\n    <string name=\"confetti_sub\">Es mostrarà confeti en desar, compartir i altres accions principals</string>\n    <string name=\"secure_mode\">Mode segur</string>\n    <string name=\"secure_mode_sub\">Amaga el contingut en sortir, a més la pantalla no es pot capturar ni gravar</string>\n    <string name=\"exit\">Sortida</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantificador</string>\n    <string name=\"gray_scale\">Escala de grisos</string>\n    <string name=\"bayer_two_dithering\">Bayer Dos Per Dos Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Tres Per Tres Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Dues fileres Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Dithering Sierra Lite</string>\n    <string name=\"atkinson_dithering\">Dithering d\\'Atkinson</string>\n    <string name=\"false_floyd_steinberg_dithering\">Fals dithering de Floyd Steinberg</string>\n    <string name=\"left_to_right_dithering\">Trama d\\'esquerra a dreta</string>\n    <string name=\"random_dithering\">Dithering aleatori</string>\n    <string name=\"simple_threshold_dithering\">Trama de llindar simple</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma espacial</string>\n    <string name=\"median_blur\">Difuminat mitjà</string>\n    <string name=\"b_spline_sub\">Utilitza funcions polinomials bicúbiques definides a trossos per interpolar i aproximar suaument una corba o una representació de forma flexible i contínua</string>\n    <string name=\"native_stack_blur\">Difuminat de pila natiu</string>\n    <string name=\"tilt_shift\">Canvi de inclinació</string>\n    <string name=\"amount\">Import</string>\n    <string name=\"seed\">Llavor</string>\n    <string name=\"anaglyph\">Anaglif</string>\n    <string name=\"noise\">Soroll</string>\n    <string name=\"pixel_sort\">Ordenació de píxels</string>\n    <string name=\"shuffle\">Barrejar</string>\n    <string name=\"channel_shift_x\">Canvi de canal X</string>\n    <string name=\"channel_shift_y\">Canvi de canal Y</string>\n    <string name=\"corruption_size\">Mida de la corrupció</string>\n    <string name=\"corruption_shift_x\">Canvi de corrupció X</string>\n    <string name=\"corruption_shift_y\">Canvi de corrupció Y</string>\n    <string name=\"tent_blur\">Difuminat de tenda</string>\n    <string name=\"side_fade\">Esvaïment lateral</string>\n    <string name=\"side\">lateral</string>\n    <string name=\"top\">Superior</string>\n    <string name=\"bottom\">A baix</string>\n    <string name=\"strength\">Força</string>\n    <string name=\"erode\">Erosionar</string>\n    <string name=\"anisotropic_diffusion\">Difusió anisotròpica</string>\n    <string name=\"diffusion\">Difusió</string>\n    <string name=\"conduction\">Conducció</string>\n    <string name=\"horizontal_wind_stagger\">Escalador de vent horitzontal</string>\n    <string name=\"fast_bilaterial_blur\">Difuminat bilateral ràpid</string>\n    <string name=\"poisson_blur\">Difuminat verinós</string>\n    <string name=\"logarithmic_tone_mapping\">Mapeig de to logarítmic</string>\n    <string name=\"crystallize\">Cristal·litza</string>\n    <string name=\"stroke_color\">Color del traç</string>\n    <string name=\"fractal_glass\">Vidre fractal</string>\n    <string name=\"amplitude\">Amplitud</string>\n    <string name=\"marble\">Marbre</string>\n    <string name=\"water_effect\">Efecte Aigua</string>\n    <string name=\"just_size\">Mida</string>\n    <string name=\"frequency_x\">Freqüència X</string>\n    <string name=\"frequency_y\">Freqüència Y</string>\n    <string name=\"amplitude_x\">Amplitud X</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Mapes de tons Hejl Burgess</string>\n    <string name=\"speed\">Velocitat</string>\n    <string name=\"color_matrix_3x3\">Matriu de colors 3x3</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomia</string>\n    <string name=\"deutaromaly\">Deuteranomalia</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Visió nocturna</string>\n    <string name=\"warm\">càlid</string>\n    <string name=\"cool\">Collonut</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Acromatomalia</string>\n    <string name=\"achromatopsia\">Acromatòpsia</string>\n    <string name=\"grain\">Gra</string>\n    <string name=\"unsharp\">Poc nítid</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Orange Haze</string>\n    <string name=\"pink_dream\">Somni rosa</string>\n    <string name=\"golden_hour\">Hora daurada</string>\n    <string name=\"hot_summer\">Estiu calorós</string>\n    <string name=\"purple_mist\">Boira Porpra</string>\n    <string name=\"sunrise\">Sortida del sol</string>\n    <string name=\"colorful_swirl\">Remolino de colors</string>\n    <string name=\"soft_spring_light\">Llum suau de primavera</string>\n    <string name=\"lavender_dream\">Somni de lavanda</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Llimonada Llum</string>\n    <string name=\"spectral_fire\">Foc Espectral</string>\n    <string name=\"night_magic\">Màgia nocturna</string>\n    <string name=\"fantasy_landscape\">Paisatge de fantasia</string>\n    <string name=\"color_explosion\">Explosió de colors</string>\n    <string name=\"electric_gradient\">Degradat elèctric</string>\n    <string name=\"caramel_darkness\">Caramel foscor</string>\n    <string name=\"futuristic_gradient\">Degradat futurista</string>\n    <string name=\"green_sun\">Sol Verd</string>\n    <string name=\"rainbow_world\">El món de l\\'arc de Sant Martí</string>\n    <string name=\"deep_purple\">Lila fosc</string>\n    <string name=\"space_portal\">Portal Espacial</string>\n    <string name=\"red_swirl\">Remolí vermell</string>\n    <string name=\"digital_code\">Codi digital</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">L\\'emoji de la barra d\\'aplicacions es canviarà contínuament de manera aleatòria en lloc d\\'utilitzar-ne un seleccionat</string>\n    <string name=\"random_emojis\">Emojis aleatoris</string>\n    <string name=\"random_emojis_error\">No es pot utilitzar la selecció aleatòria d\\'emojis mentre els emojis estan desactivats</string>\n    <string name=\"emoji_selection_error\">No es pot seleccionar un emoji mentre n\\'escolliu un a l\\'atzar activat</string>\n    <string name=\"favorite\">Favorit</string>\n    <string name=\"no_favorite_filters\">Encara no s\\'ha afegit cap filtre preferit</string>\n    <string name=\"image_format\">Format d\\'imatge</string>\n    <string name=\"icon_shape_sub\">Afegeix un contenidor amb la forma seleccionada sota les icones principals de les targetes</string>\n    <string name=\"icon_shape\">Forma d\\'icona</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Tallar</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Transició</string>\n    <string name=\"peak\">Cim</string>\n    <string name=\"color_anomaly\">Anomalia del color</string>\n    <string name=\"images_overwritten\">Imatges sobreescrites a la destinació original</string>\n    <string name=\"cannot_change_image_format\">No es pot canviar el format de la imatge mentre l\\'opció de sobreescriure fitxers està activada</string>\n    <string name=\"emoji_as_color_scheme\">Emoji com a esquema de colors</string>\n    <string name=\"emoji_as_color_scheme_sub\">Utilitza el color primari dels emoji com a esquema de colors de l\\'aplicació en lloc d\\'un de definit manualment</string>\n    <string name=\"material_you_sub\">Crea la paleta \\\"Material You\\\" a partir de la imatge</string>\n    <string name=\"dark_colors\">Colors Foscos</string>\n    <string name=\"dark_colors_sub\">Utilitza el mode nocturn esquema de colors en lloc de la variant de llum</string>\n    <string name=\"copy_as_compose_code\">Copia com a codi \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Difuminat d\\'anell</string>\n    <string name=\"cross_blur\">Difuminat creuat</string>\n    <string name=\"circle_blur\">Difuminat de cercle</string>\n    <string name=\"star_blur\">Difuminat d\\'estrelles</string>\n    <string name=\"linear_tilt_shift\">Canvi d\\'inclinació lineal</string>\n    <string name=\"tags_to_remove\">Etiquetes A Eliminar</string>\n    <string name=\"apng_tools\">Eines APNG</string>\n    <string name=\"apng_tools_sub\">Converteix imatges a imatge APNG o extreu marcs de la imatge APNG donada</string>\n    <string name=\"apng_type_to_image\">APNG a les imatges</string>\n    <string name=\"apng_type_to_image_sub\">Converteix el fitxer APNG en un lot d\\'imatges</string>\n    <string name=\"apng_type_to_apng_sub\">Converteix un lot d\\'imatges a fitxer APNG</string>\n    <string name=\"apng_type_to_apng\">Imatges a APNG</string>\n    <string name=\"select_apng_image_to_start\">Trieu la imatge APNG per començar</string>\n    <string name=\"motion_blur\">Difuminat de moviment</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Creeu un fitxer Zip a partir de fitxers o imatges donats</string>\n    <string name=\"drag_handle_width\">Arrossegueu l\\'amplada del mànec</string>\n    <string name=\"fast_gaussian_blur_2d\">Difuminat gaussià ràpid en 2D</string>\n    <string name=\"fast_gaussian_blur_4d\">Difuminat gaussià ràpid en 4D</string>\n    <string name=\"fast_gaussian_blur_3d\">Difuminat gaussià ràpid en 3D</string>\n    <string name=\"lanczos_bessel_sub\">Mètode de remostreig que manté la interpolació d\\'alta qualitat aplicant una funció de Bessel (jinc) als valors dels píxels</string>\n    <string name=\"confetti_type\">Tipus de confeti</string>\n    <string name=\"festive\">Festiu</string>\n    <string name=\"explode\">Explotar</string>\n    <string name=\"rain\">Pluja</string>\n    <string name=\"corners\">Cantonades</string>\n    <string name=\"jxl_tools\">Eines JXL</string>\n    <string name=\"jxl_tools_sub\">Realitzeu una transcodificació JXL ~ JPEG sense pèrdua de qualitat o convertiu GIF/APNG a animació JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL a JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Realitzeu una transcodificació sense pèrdues de JXL a JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Realitzeu una transcodificació sense pèrdues de JPEG a JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG a JXL</string>\n    <string name=\"select_jxl_image_to_start\">Trieu la imatge JXL per començar</string>\n    <string name=\"auto_paste\">Cotxe de Pasqua</string>\n    <string name=\"auto_paste_sub\">Permet que l\\'aplicació enganxi automàticament les dades del porta-retalls, de manera que apareixeran a la pantalla principal i les podreu processar</string>\n    <string name=\"harmonization_color\">Color d\\'harmonització</string>\n    <string name=\"harmonization_level\">Nivell d\\'harmonització</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"gif_type_to_jxl\">GIF a JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Converteix imatges GIF en imatges animades JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG a JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Converteix imatges APNG en imatges animades JXL</string>\n    <string name=\"jxl_type_to_images\">JXL a Imatges</string>\n    <string name=\"jxl_type_to_images_sub\">Converteix l\\'animació JXL en un lot d\\'imatges</string>\n    <string name=\"jxl_type_to_jxl\">Imatges a JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Converteix el lot d\\'imatges a animació JXL</string>\n    <string name=\"behavior\">Comportament</string>\n    <string name=\"skip_file_picking\">Omet la selecció de fitxers</string>\n    <string name=\"skip_file_picking_sub\">El selector de fitxers es mostrarà immediatament si això és possible a la pantalla escollida</string>\n    <string name=\"generate_previews\">Genera visualitzacions prèvies</string>\n    <string name=\"generate_previews_sub\">Habilita la generació de visualitzacions prèvies, això pot ajudar a evitar bloquejos en alguns dispositius, això també desactiva algunes funcionalitats d\\'edició dins de l\\'opció d\\'edició única</string>\n    <string name=\"lossy_compression\">Compressió amb pèrdues</string>\n    <string name=\"lossy_compression_sub\">Utilitza la compressió amb pèrdues per reduir la mida del fitxer en lloc de la compressió sense pèrdues</string>\n    <string name=\"compression_type\">Tipus de compressió</string>\n    <string name=\"speed_sub\">Controla la velocitat de descodificació de la imatge resultant, això hauria d\\'ajudar a obrir la imatge resultant més ràpidament, el valor de %1$s significa la descodificació més lenta, mentre que %2$s - la més ràpida, aquesta configuració pot augmentar la mida de la imatge de sortida.</string>\n    <string name=\"sorting\">Classificació</string>\n    <string name=\"sort_by_date\">Data</string>\n    <string name=\"sort_by_date_reversed\">Data (invertida)</string>\n    <string name=\"sort_by_name\">Nom</string>\n    <string name=\"sort_by_name_reversed\">Nom (invertit)</string>\n    <string name=\"channels_configuration\">Configuració de canals</string>\n    <string name=\"header_today\">Avui</string>\n    <string name=\"header_yesterday\">Ahir</string>\n    <string name=\"embedded_picker\">Selector incrustat</string>\n    <string name=\"embedded_picker_sub\">Selector d\\'imatges de Image Toolbox</string>\n    <string name=\"no_permissions\">Sense permisos</string>\n    <string name=\"request\">Sol·licitud</string>\n    <string name=\"pick_multiple_media\">Trieu diversos mitjans</string>\n    <string name=\"pick_single_media\">Trieu un mitjà únic</string>\n    <string name=\"pick\">Tria</string>\n    <string name=\"try_again\">Torna-ho a provar</string>\n    <string name=\"show_settings_in_landscape\">Mostra la configuració en paisatge</string>\n    <string name=\"show_settings_in_landscape_sub\">Si està desactivat, la configuració del mode horitzontal s\\'obrirà al botó de la barra superior d\\'aplicacions com sempre, en lloc de l\\'opció visible permanent.</string>\n    <string name=\"fullscreen_settings\">Configuració de pantalla completa</string>\n    <string name=\"fullscreen_settings_sub\">Activeu-lo i la pàgina de configuració s\\'obrirà sempre com a pantalla completa en lloc de full de calaix lliscant</string>\n    <string name=\"switch_type\">Tipus de canvi</string>\n    <string name=\"compose\">Composar</string>\n    <string name=\"compose_switch_sub\">Un Jetpack Compose Material que canvieu</string>\n    <string name=\"material_you_switch_sub\">Un material que canvies</string>\n    <string name=\"max\">Màx</string>\n    <string name=\"resize_anchor\">Canvia la mida de l\\'àncora</string>\n    <string name=\"pixel_switch\">Píxel</string>\n    <string name=\"fluent_switch\">Fluït</string>\n    <string name=\"fluent_switch_sub\">Un interruptor basat en el sistema de disseny \\\"Fluent\\\".</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Un interruptor basat en el sistema de disseny \\\"Cupertino\\\".</string>\n    <string name=\"images_to_svg\">Imatges a SVG</string>\n    <string name=\"images_to_svg_sub\">Traça imatges donades a imatges SVG</string>\n    <string name=\"use_sampled_palette\">Utilitzeu la paleta mostrada</string>\n    <string name=\"use_sampled_palette_sub\">La paleta de quantització es mostrarà si aquesta opció està activada</string>\n    <string name=\"path_omit\">Omet el camí</string>\n    <string name=\"svg_warning\">No es recomana l\\'ús d\\'aquesta eina per rastrejar imatges grans sense reduir l\\'escala, pot provocar un bloqueig i augmentar el temps de processament</string>\n    <string name=\"downscale_image\">Reducció de la imatge</string>\n    <string name=\"downscale_image_sub\">La imatge es reduirà a dimensions inferiors abans de processar-la, això ajuda a que l\\'eina funcioni de manera més ràpida i segura</string>\n    <string name=\"min_color_ratio\">Relació de color mínima</string>\n    <string name=\"lines_threshold\">Línies Llindar</string>\n    <string name=\"quadratic_threshold\">Llindar quadràtic</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolerància a l\\'arrodoniment de les coordenades</string>\n    <string name=\"path_scale\">Escala del camí</string>\n    <string name=\"reset_properties\">Restableix les propietats</string>\n    <string name=\"reset_properties_sub\">Totes les propietats s\\'establiran als valors predeterminats, tingueu en compte que aquesta acció no es pot desfer</string>\n    <string name=\"detailed\">Detallada</string>\n    <string name=\"default_line_width\">Amplada de línia per defecte</string>\n    <string name=\"engine_mode\">Mode motor</string>\n    <string name=\"legacy\">Llegat</string>\n    <string name=\"lstm_network\">Xarxa LSTM</string>\n    <string name=\"legacy_and_lstm\">Llegat i LSTM</string>\n    <string name=\"convert\">Converteix</string>\n    <string name=\"convert_sub\">Converteix lots d\\'imatges al format donat</string>\n    <string name=\"add_new_folder\">Afegeix una carpeta nova</string>\n    <string name=\"tag_bits_per_sample\">Bits per mostra</string>\n    <string name=\"tag_compression\">Compressió</string>\n    <string name=\"tag_photometric_interpretation\">Interpretació fotomètrica</string>\n    <string name=\"tag_samples_per_pixel\">Mostres per píxel</string>\n    <string name=\"tag_planar_configuration\">Configuració plana</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Submostreig</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Posicionament</string>\n    <string name=\"tag_x_resolution\">X Resolució</string>\n    <string name=\"tag_y_resolution\">Resolució Y</string>\n    <string name=\"tag_resolution_unit\">Unitat de Resolució</string>\n    <string name=\"tag_strip_offsets\">Desplaçaments de franges</string>\n    <string name=\"tag_rows_per_strip\">Files per tira</string>\n    <string name=\"tag_strip_byte_counts\">Recompte de bytes de banda</string>\n    <string name=\"tag_jpeg_interchange_format\">Format d\\'intercanvi JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Longitud del format d\\'intercanvi JPEG</string>\n    <string name=\"tag_transfer_function\">Funció de transferència</string>\n    <string name=\"tag_white_point\">Punt Blanc</string>\n    <string name=\"tag_primary_chromaticities\">Cromaticitats primàries</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Coeficients</string>\n    <string name=\"tag_reference_black_white\">Referència Negre Blanc</string>\n    <string name=\"tag_datetime\">Data Hora</string>\n    <string name=\"tag_image_description\">Descripció de la imatge</string>\n    <string name=\"tag_make\">Fer</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Programari</string>\n    <string name=\"tag_artist\">Artista</string>\n    <string name=\"tag_copyright\">Copyright</string>\n    <string name=\"tag_exif_version\">Versió Exif</string>\n    <string name=\"tag_flashpix_version\">Versió Flashpix</string>\n    <string name=\"tag_color_space\">Espai de color</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Dimensió Pixel X</string>\n    <string name=\"tag_pixel_y_dimension\">Dimensió Y de píxels</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Bits comprimits per píxel</string>\n    <string name=\"tag_maker_note\">Nota del fabricant</string>\n    <string name=\"tag_user_comment\">Comentari de l\\'usuari</string>\n    <string name=\"tag_related_sound_file\">Fitxer de so relacionat</string>\n    <string name=\"tag_datetime_original\">Data Hora Original</string>\n    <string name=\"tag_datetime_digitized\">Data Hora Digitalitzat</string>\n    <string name=\"tag_offset_time\">Temps de compensació</string>\n    <string name=\"tag_offset_time_original\">Temps de compensació original</string>\n    <string name=\"tag_offset_time_digitized\">Temps de compensació digitalitzat</string>\n    <string name=\"tag_subsec_time\">Temps de subsec</string>\n    <string name=\"tag_subsec_time_original\">Subsec Temps Original</string>\n    <string name=\"tag_subsec_time_digitized\">Temps subsec digitalitzat</string>\n    <string name=\"tag_exposure_time\">Temps d\\'exposició</string>\n    <string name=\"tag_f_number\">Número F</string>\n    <string name=\"tag_exposure_program\">Programa d\\'exposició</string>\n    <string name=\"tag_spectral_sensitivity\">Sensibilitat espectral</string>\n    <string name=\"tag_photographic_sensitivity\">Sensibilitat fotogràfica</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Tipus de sensibilitat</string>\n    <string name=\"tag_standard_output_sensitivity\">Sensibilitat de sortida estàndard</string>\n    <string name=\"tag_recommended_exposure_index\">Índex d\\'exposició recomanat</string>\n    <string name=\"tag_iso_speed\">Velocitat ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Velocitat ISO Latitud yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Velocitat ISO Latitud zzz</string>\n    <string name=\"tag_shutter_speed_value\">Valor de velocitat d\\'obturació</string>\n    <string name=\"tag_aperture_value\">Valor d\\'obertura</string>\n    <string name=\"tag_brightness_value\">Valor de brillantor</string>\n    <string name=\"tag_exposure_bias_value\">Valor de biaix d\\'exposició</string>\n    <string name=\"tag_max_aperture_value\">Valor màxim d\\'obertura</string>\n    <string name=\"tag_subject_distance\">Distància del subjecte</string>\n    <string name=\"tag_metering_mode\">Mode de mesura</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Àrea temàtica</string>\n    <string name=\"tag_focal_length\">Distància focal</string>\n    <string name=\"tag_flash_energy\">Energia Flash</string>\n    <string name=\"tag_spatial_frequency_response\">Resposta de freqüència espacial</string>\n    <string name=\"tag_focal_plane_x_resolution\">Resolució del pla focal X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Resolució del pla focal Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Unitat de resolució del pla focal</string>\n    <string name=\"tag_subject_location\">Ubicació de l\\'assignatura</string>\n    <string name=\"tag_exposure_index\">Índex d\\'exposició</string>\n    <string name=\"tag_sensing_method\">Mètode de detecció</string>\n    <string name=\"tag_file_source\">Font del fitxer</string>\n    <string name=\"tag_cfa_pattern\">Patró CFA</string>\n    <string name=\"tag_custom_rendered\">Representació personalitzada</string>\n    <string name=\"tag_exposure_mode\">Mode d\\'exposició</string>\n    <string name=\"tag_white_balance\">Balanç de blancs</string>\n    <string name=\"tag_digital_zoom_ratio\">Relació de zoom digital</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Distància focal en pel·lícula de 35 mm</string>\n    <string name=\"tag_scene_capture_type\">Tipus de captura d\\'escena</string>\n    <string name=\"tag_gain_control\">Obteniu el control</string>\n    <string name=\"tag_contrast\">Contrast</string>\n    <string name=\"tag_saturation\">Saturació</string>\n    <string name=\"tag_sharpness\">Nitidez</string>\n    <string name=\"tag_device_setting_description\">Descripció de la configuració del dispositiu</string>\n    <string name=\"tag_subject_distance_range\">Interval de distància del subjecte</string>\n    <string name=\"tag_image_unique_id\">Identificador únic de la imatge</string>\n    <string name=\"tag_camera_owner_name\">Nom del propietari de la càmera</string>\n    <string name=\"tag_body_serial_number\">Número de sèrie del cos</string>\n    <string name=\"tag_lens_specification\">Especificació de la lent</string>\n    <string name=\"tag_lens_make\">Marca de lents</string>\n    <string name=\"tag_lens_model\">Model de lent</string>\n    <string name=\"tag_lens_serial_number\">Número de sèrie de la lent</string>\n    <string name=\"tag_gps_version_id\">ID de versió del GPS</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitud Ref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitud</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Longitud Ref</string>\n    <string name=\"tag_gps_longitude\">Longitud GPS</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Altitud Ref</string>\n    <string name=\"tag_gps_altitude\">Altitud GPS</string>\n    <string name=\"tag_gps_timestamp\">Marca de temps GPS</string>\n    <string name=\"tag_gps_satellites\">Satèl·lits GPS</string>\n    <string name=\"tag_gps_status\">Estat GPS</string>\n    <string name=\"tag_gps_measure_mode\">Mode de mesura GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Velocitat GPS Ref</string>\n    <string name=\"tag_gps_speed\">Velocitat GPS</string>\n    <string name=\"tag_gps_track_ref\">Track GPS Ref</string>\n    <string name=\"tag_gps_track\">Track GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Direcció Img GPS Ref</string>\n    <string name=\"tag_gps_img_direction\">Direcció d\\'imatge GPS</string>\n    <string name=\"tag_gps_map_datum\">Dades del mapa GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitud Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitud Ref</string>\n    <string name=\"tag_gps_dest_longitude\">Longitud destí GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">Distància GPS Ref</string>\n    <string name=\"tag_gps_dest_distance\">Distància de destí GPS</string>\n    <string name=\"tag_gps_processing_method\">Mètode de processament GPS</string>\n    <string name=\"tag_gps_area_information\">Informació de l\\'àrea GPS</string>\n    <string name=\"tag_gps_datestamp\">Segell de data GPS</string>\n    <string name=\"tag_gps_differential\">Diferencial GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Error de posicionament GPS H</string>\n    <string name=\"tag_interoperability_index\">Índex d\\'interoperabilitat</string>\n    <string name=\"tag_dng_version\">Versió DNG</string>\n    <string name=\"tag_default_crop_size\">Mida de retall per defecte</string>\n    <string name=\"tag_orf_preview_image_start\">Inici de la previsualització de la imatge</string>\n    <string name=\"tag_orf_preview_image_length\">Previsualitza la longitud de la imatge</string>\n    <string name=\"tag_orf_aspect_frame\">Marc d\\'aspecte</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Bord inferior del sensor</string>\n    <string name=\"tag_rw2_sensor_left_border\">Vora esquerra del sensor</string>\n    <string name=\"tag_rw2_sensor_right_border\">Bord dret del sensor</string>\n    <string name=\"tag_rw2_sensor_top_border\">Bord superior del sensor</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Dibuixa el text al camí amb el tipus de lletra i el color donats</string>\n    <string name=\"font_size\">Mida de la lletra</string>\n    <string name=\"watermark_size\">Mida de la filigrana</string>\n    <string name=\"repeat_text\">Repetiu el text</string>\n    <string name=\"repeat_text_sub\">El text actual es repetirà fins al final del camí en lloc de dibuixar una vegada</string>\n    <string name=\"dash_size\">Mida del guió</string>\n    <string name=\"draw_mode_image_sub\">Utilitzeu la imatge seleccionada per dibuixar-la al llarg del camí donat</string>\n    <string name=\"draw_image_sub\">Aquesta imatge s\\'utilitzarà com a entrada repetitiva del camí dibuixat</string>\n    <string name=\"outlined_triangle_sub\">Dibuixa un triangle delineat des del punt inicial fins al punt final</string>\n    <string name=\"triangle_sub\">Dibuixa un triangle delineat des del punt inicial fins al punt final</string>\n    <string name=\"outlined_triangle\">Triangle esquematitzat</string>\n    <string name=\"triangle\">Triangle</string>\n    <string name=\"polygon_sub\">Dibuixa polígon des del punt inicial fins al punt final</string>\n    <string name=\"polygon\">Polígon</string>\n    <string name=\"outlined_polygon\">Polígon esquematitzat</string>\n    <string name=\"outlined_polygon_sub\">Dibuixa un polígon delineat des del punt inicial fins al punt final</string>\n    <string name=\"vertices\">Vèrtexs</string>\n    <string name=\"draw_regular_polygon\">Dibuixa un polígon regular</string>\n    <string name=\"draw_regular_polygon_sub\">Dibuixa un polígon que serà regular en lloc de forma lliure</string>\n    <string name=\"star_sub\">Dibuixa estrella des del punt inicial fins al punt final</string>\n    <string name=\"star\">Estrella</string>\n    <string name=\"outlined_star\">Estrella perfilada</string>\n    <string name=\"outlined_star_sub\">Dibuixa l\\'estrella delineada des del punt inicial fins al punt final</string>\n    <string name=\"inner_radius_ratio\">Relació de radi interior</string>\n    <string name=\"draw_regular_star\">Dibuixa una estrella regular</string>\n    <string name=\"draw_regular_star_sub\">Dibuixa una estrella que serà regular en lloc de lliure</string>\n    <string name=\"antialias\">Antiàlies</string>\n    <string name=\"antialias_sub\">Habilita l\\'antialiasing per evitar vores afilades</string>\n    <string name=\"open_edit_instead_of_preview\">Obriu Edita en lloc de previsualitzar</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Quan seleccioneu la imatge per obrir (visualització prèvia) a ImageToolbox, s\\'obrirà el full de selecció d\\'edició en lloc de previsualitzar</string>\n    <string name=\"document_scanner\">Escàner de documents</string>\n    <string name=\"document_scanner_sub\">Escaneja documents i crea PDF o separa imatges d\\'ells</string>\n    <string name=\"click_to_start_scanning\">Feu clic per començar a escanejar</string>\n    <string name=\"start_scanning\">Inicieu l\\'escaneig</string>\n    <string name=\"save_as_pdf\">Desa com a PDF</string>\n    <string name=\"share_as_pdf\">Comparteix com a PDF</string>\n    <string name=\"options_below_is_for_images\">Les opcions següents són per desar imatges, no PDF</string>\n    <string name=\"equalize_histogram_hsv\">Igualar l\\'histograma HSV</string>\n    <string name=\"equalize_histogram\">Equalitzar l\\'histograma</string>\n    <string name=\"enter_percentage\">Introduïu un percentatge</string>\n    <string name=\"allow_enter_by_text_field\">Permet l\\'entrada per camp de text</string>\n    <string name=\"allow_enter_by_text_field_sub\">Activa el camp de text darrere de la selecció de valors predefinits per introduir-los sobre la marxa</string>\n    <string name=\"scale_color_space\">Escala l\\'espai de color</string>\n    <string name=\"linear\">Lineal</string>\n    <string name=\"equalize_histogram_pixelation\">Igualar la pixelació de l\\'histograma</string>\n    <string name=\"grid_size_x\">Mida de la quadrícula X</string>\n    <string name=\"grid_size_y\">Mida de la quadrícula Y</string>\n    <string name=\"equalize_histogram_adaptive\">Equalitzar histograma adaptatiu</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Equalitzar histograma LUV adaptatiu</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalize Histogram Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Retalla al contingut</string>\n    <string name=\"frame_color\">Color del marc</string>\n    <string name=\"color_to_ignore\">Color per ignorar</string>\n    <string name=\"template\">Plantilla</string>\n    <string name=\"no_template_filters\">No s\\'han afegit filtres de plantilla</string>\n    <string name=\"create_new\">Crea nou</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">El codi QR escanejat no és una plantilla de filtre vàlida</string>\n    <string name=\"scan_qr_code\">Escaneja el codi QR</string>\n    <string name=\"opened_file_have_no_filter_template\">El fitxer seleccionat no té dades de plantilla de filtre</string>\n    <string name=\"create_template\">Crea plantilla</string>\n    <string name=\"template_name\">Nom de la plantilla</string>\n    <string name=\"select_template_preview\">Aquesta imatge s\\'utilitzarà per previsualitzar aquesta plantilla de filtre</string>\n    <string name=\"template_filter\">Filtre de plantilla</string>\n    <string name=\"as_qr_code\">Com a imatge de codi QR</string>\n    <string name=\"as_file\">Com a fitxer</string>\n    <string name=\"save_as_file\">Desa com a fitxer</string>\n    <string name=\"save_as_qr_code_image\">Desa com a imatge de codi QR</string>\n    <string name=\"delete_template\">Suprimeix la plantilla</string>\n    <string name=\"delete_template_warn\">Esteu a punt d\\'eliminar el filtre de plantilla seleccionat. Aquesta operació no es pot desfer</string>\n    <string name=\"added_filter_template\">S\\'ha afegit una plantilla de filtre amb el nom \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Vista prèvia del filtre</string>\n    <string name=\"qr_code\">QR i codi de barres</string>\n    <string name=\"qr_code_sub\">Escaneja el codi QR i obtén el seu contingut o enganxa la cadena per generar-ne una de nova</string>\n    <string name=\"code_content\">Contingut del codi</string>\n    <string name=\"scan_qr_code_to_replace_content\">Escaneja qualsevol codi de barres per substituir el contingut del camp o escriviu alguna cosa per generar un codi de barres nou amb el tipus seleccionat</string>\n    <string name=\"qr_description\">Descripció QR</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Doneu permís a la càmera a la configuració per escanejar el codi QR</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Doneu permís a la càmera a la configuració per escanejar Document Scanner</string>\n    <string name=\"cubic\">Cúbic</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussià</string>\n    <string name=\"sphinx\">Esfinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Caixa</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanços 2</string>\n    <string name=\"lanczos3\">Lanços 3</string>\n    <string name=\"lanczos4\">Lanços 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">La interpolació cúbica proporciona una escala més suau tenint en compte els 16 píxels més propers, donant millors resultats que els bilineals</string>\n    <string name=\"bspline_sub\">Utilitza funcions polinomials definides per trossos per interpolar i aproximar suaument una corba o una representació de forma flexible i contínua.</string>\n    <string name=\"hamming_sub\">Una funció de finestra que s\\'utilitza per reduir les fuites espectrals reduint les vores d\\'un senyal, útil en el processament del senyal</string>\n    <string name=\"hanning_sub\">Una variant de la finestra de Hann, que s\\'utilitza habitualment per reduir les fuites espectrals en aplicacions de processament de senyal</string>\n    <string name=\"blackman_sub\">Una funció de finestra que proporciona una bona resolució de freqüència minimitzant les fuites espectrals, que s\\'utilitza sovint en el processament del senyal</string>\n    <string name=\"welch_sub\">Una funció de finestra dissenyada per oferir una bona resolució de freqüència amb una fuga espectral reduïda, que s\\'utilitza sovint en aplicacions de processament de senyal</string>\n    <string name=\"quadric_sub\">Un mètode que utilitza una funció quadràtica per a la interpolació, proporcionant resultats suaus i continus</string>\n    <string name=\"gaussian_sub\">Un mètode d\\'interpolació que aplica una funció gaussiana, útil per suavitzar i reduir el soroll a les imatges</string>\n    <string name=\"sphinx_sub\">Un mètode avançat de mostreig que proporciona una interpolació d\\'alta qualitat amb un mínim d\\'artefactes</string>\n    <string name=\"bartlett_sub\">Una funció de finestra triangular que s\\'utilitza en el processament del senyal per reduir les fuites espectrals</string>\n    <string name=\"robidoux_sub\">Un mètode d\\'interpolació d\\'alta qualitat optimitzat per redimensionar la imatge natural, equilibrant la nitidesa i la suavitat</string>\n    <string name=\"robidoux_sharp_sub\">Una variant més nítida del mètode Robidoux, optimitzada per canviar la mida de la imatge nítida</string>\n    <string name=\"spline16_sub\">Un mètode d\\'interpolació basat en spline que proporciona resultats suaus mitjançant un filtre de 16 tocs</string>\n    <string name=\"spline36_sub\">Un mètode d\\'interpolació basat en spline que proporciona resultats suaus mitjançant un filtre de 36 tocs</string>\n    <string name=\"spline64_sub\">Un mètode d\\'interpolació basat en spline que proporciona resultats suaus mitjançant un filtre de 64 tocs</string>\n    <string name=\"kaiser_sub\">Un mètode d\\'interpolació que utilitza la finestra Kaiser, proporcionant un bon control sobre la compensació entre l\\'amplada del lòbul principal i el nivell del lòbul lateral</string>\n    <string name=\"bartlett_hann_sub\">Una funció de finestra híbrida que combina les finestres de Bartlett i Hann, utilitzada per reduir les fuites espectrals en el processament del senyal</string>\n    <string name=\"box_sub\">Un mètode de remuestreig senzill que utilitza la mitjana dels valors de píxels més propers, sovint donant lloc a una aparença de blocs</string>\n    <string name=\"bohman_sub\">Una funció de finestra utilitzada per reduir les fuites espectrals, proporcionant una bona resolució de freqüència en aplicacions de processament de senyal</string>\n    <string name=\"lanczos2_sub\">Un mètode de mostreig que utilitza un filtre Lanczos de 2 lòbuls per a una interpolació d\\'alta qualitat amb artefactes mínims</string>\n    <string name=\"lanczos3_sub\">Un mètode de remuestreig que utilitza un filtre Lanczos de 3 lòbuls per a una interpolació d\\'alta qualitat amb artefactes mínims</string>\n    <string name=\"lanczos4_sub\">Un mètode de mostreig que utilitza un filtre Lanczos de 4 lòbuls per a una interpolació d\\'alta qualitat amb artefactes mínims</string>\n    <string name=\"lanczos2_jinc_sub\">Una variant del filtre Lanczos 2 que utilitza la funció jinc, proporcionant una interpolació d\\'alta qualitat amb artefactes mínims</string>\n    <string name=\"lanczos3_jinc_sub\">Una variant del filtre Lanczos 3 que utilitza la funció jinc, proporcionant una interpolació d\\'alta qualitat amb artefactes mínims</string>\n    <string name=\"lanczos4_jinc_sub\">Una variant del filtre Lanczos 4 que utilitza la funció jinc, proporcionant una interpolació d\\'alta qualitat amb artefactes mínims</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Hanning per a una interpolació i un remuestreig suaus</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Robidoux per a un remuestreig d\\'alta qualitat</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Blackman per minimitzar els artefactes de timbre</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre quàdric per a una interpolació suau</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Robidoux Sharp per obtenir resultats més nítids</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Lanczos 3 Jinc per a un remuestreig d\\'alta qualitat amb àlies reduïts</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Un filtre de mostreig dissenyat per processar imatges d\\'alta qualitat amb un bon equilibri de nitidesa i suavitat</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Mitjana ponderada el·líptica (EWA) variant del filtre Ginseng per millorar la qualitat d\\'imatge</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Lanczos Sharp per aconseguir resultats nítids amb artefactes mínims</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA més nítid</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Lanczos 4 Sharpest per a un remuestreig d\\'imatges extremadament nítid</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Variant de mitjana ponderada el·líptica (EWA) del filtre Lanczos Soft per a un remuestreig més suau de la imatge</string>\n    <string name=\"haasn_soft\">Haasn suau</string>\n    <string name=\"haasn_soft_sub\">Un filtre de mostreig dissenyat per Haasn per a una escala d\\'imatges suau i sense artefactes</string>\n    <string name=\"format_conversion\">Conversió de format</string>\n    <string name=\"format_conversion_sub\">Converteix lots d\\'imatges d\\'un format a un altre</string>\n    <string name=\"dismiss_forever\">Descartar per sempre</string>\n    <string name=\"image_stacking\">Apilament d\\'imatges</string>\n    <string name=\"image_stacking_sub\">Apila imatges unes sobre les altres amb els modes de combinació escollits</string>\n    <string name=\"add_image\">Afegeix una imatge</string>\n    <string name=\"bins_count\">Els contenidors compten</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Equalitzar histograma HSL adaptatiu</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Equalitzar histograma HSV adaptatiu</string>\n    <string name=\"edge_mode\">Mode Edge</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Embolicar</string>\n    <string name=\"color_blind_scheme\">Daltonisme</string>\n    <string name=\"color_blind_scheme_sub\">Seleccioneu el mode per adaptar els colors del tema per a la variant de daltonisme seleccionada</string>\n    <string name=\"protanomaly_sub\">Dificultat per distingir entre tons vermells i verds</string>\n    <string name=\"deuteranomaly_sub\">Dificultat per distingir entre tons verds i vermells</string>\n    <string name=\"tritanomaly_sub\">Dificultat per distingir els tons blaus i grocs</string>\n    <string name=\"protanopia_sub\">Incapacitat per percebre tonalitats vermelles</string>\n    <string name=\"deuteranopia_sub\">Incapacitat per percebre els tons verds</string>\n    <string name=\"tritanopia_sub\">Incapacitat per percebre tons blaus</string>\n    <string name=\"achromatomaly_sub\">Sensibilitat reduïda a tots els colors</string>\n    <string name=\"achromatopsia_sub\">Daltonisme total, veient només tons de gris</string>\n    <string name=\"not_use_color_blind_scheme\">No utilitzeu l\\'esquema de daltònic</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Els colors seran exactament els establerts al tema</string>\n    <string name=\"sigmoidal\">Sigmoïdal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Un filtre d\\'interpolació de Lagrange d\\'ordre 2, adequat per a l\\'escala d\\'imatges d\\'alta qualitat amb transicions suaus</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Un filtre d\\'interpolació de Lagrange d\\'ordre 3, que ofereix una millor precisió i resultats més suaus per a l\\'escala de la imatge</string>\n    <string name=\"lanczos_6\">Lanços 6</string>\n    <string name=\"lanczos_6_sub\">Un filtre de remuestreig de Lanczos amb un ordre superior de 6, que proporciona una escala d\\'imatges més nítida i precisa</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Una variant del filtre Lanczos 6 que utilitza una funció Jinc per millorar la qualitat de mostreig de la imatge</string>\n    <string name=\"linear_box_blur\">Desenfocament de caixa lineal</string>\n    <string name=\"linear_tent_blur\">Desenfocament de tenda lineal</string>\n    <string name=\"linear_gaussian_box_blur\">Desenfocament de caixa gaussiana lineal</string>\n    <string name=\"linear_stack_blur\">Desenfocament de pila lineal</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Desenfocament gaussià ràpid lineal A continuació</string>\n    <string name=\"linear_fast_gaussian_blur\">Desenfocament gaussià ràpid lineal</string>\n    <string name=\"linear_gaussian_blur\">Desenfocament gaussià lineal</string>\n    <string name=\"draw_filter_sub\">Trieu un filtre per utilitzar-lo com a pintura</string>\n    <string name=\"replace_filter\">Substituïu el filtre</string>\n    <string name=\"pick_filter_info\">Trieu el filtre següent per utilitzar-lo com a pinzell al vostre dibuix</string>\n    <string name=\"tiff_compression_scheme\">Esquema de compressió TIFF</string>\n    <string name=\"low_poly\">Low Poly</string>\n    <string name=\"sand_painting\">Pintura de sorra</string>\n    <string name=\"image_splitting\">Divisió d\\'imatges</string>\n    <string name=\"image_splitting_sub\">Dividiu una imatge única per files o columnes</string>\n    <string name=\"fit_to_bounds\">Ajust als límits</string>\n    <string name=\"fit_to_bounds_sub\">Combina el mode de canvi de mida retallat amb aquest paràmetre per aconseguir el comportament desitjat (retalla/ajust a la relació d\\'aspecte)</string>\n    <string name=\"languages_imported\">Idiomes importats correctament</string>\n    <string name=\"backup_ocr_models\">Còpia de seguretat dels models OCR</string>\n    <string name=\"import_word\">Importar</string>\n    <string name=\"export\">Exporta</string>\n    <string name=\"position\">Posició</string>\n    <string name=\"center\">Centre</string>\n    <string name=\"top_left\">Superior esquerra</string>\n    <string name=\"top_right\">A dalt a la dreta</string>\n    <string name=\"bottom_left\">A baix a l\\'esquerra</string>\n    <string name=\"bottom_right\">A baix a la dreta</string>\n    <string name=\"top_center\">Centre superior</string>\n    <string name=\"center_right\">Centre Dret</string>\n    <string name=\"bottom_center\">Centre inferior</string>\n    <string name=\"center_left\">Centre Esquerra</string>\n    <string name=\"target_image\">Imatge objectiu</string>\n    <string name=\"palette_transfer\">Transferència de paleta</string>\n    <string name=\"enhanced_oil\">Oli millorat</string>\n    <string name=\"simple_old_tv\">Televisió antiga senzilla</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Esbós simple</string>\n    <string name=\"soft_glow\">Lluentor suau</string>\n    <string name=\"color_poster\">Cartell de colors</string>\n    <string name=\"tri_tone\">Tri Ton</string>\n    <string name=\"third_color\">Tercer color</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Punt de polca</string>\n    <string name=\"clustered_2x2_dithering\">Dithering 2x2 agrupat</string>\n    <string name=\"clustered_4x4_dithering\">Dithering 4x4 agrupat</string>\n    <string name=\"clustered_8x8_dithering\">Dithering de 8 x 8 en clúster</string>\n    <string name=\"yililoma_dithering\">Dithering de Yililoma</string>\n    <string name=\"no_favorite_options_selected\">No s\\'ha seleccionat cap opció preferida, afegiu-les a la pàgina d\\'eines</string>\n    <string name=\"add_favorites\">Afegeix Preferits</string>\n    <string name=\"harmony_complementary\">Complementari</string>\n    <string name=\"harmony_analogous\">Anàleg</string>\n    <string name=\"harmony_triadic\">Triadic</string>\n    <string name=\"harmony_split_complementary\">Complementària dividida</string>\n    <string name=\"harmony_tetradic\">Tetràdic</string>\n    <string name=\"harmony_square\">Plaçada</string>\n    <string name=\"harmony_analogous_complementary\">Anàleg + Complementari</string>\n    <string name=\"color_tools\">Eines de color</string>\n    <string name=\"color_tools_sub\">Barrejar, crear tons, generar matisos i molt més</string>\n    <string name=\"color_harmonies\">Harmonies de colors</string>\n    <string name=\"color_shading\">Sombreat de colors</string>\n    <string name=\"variation\">Variació</string>\n    <string name=\"tints\">Tints</string>\n    <string name=\"tones\">Tons</string>\n    <string name=\"shades\">Ombres</string>\n    <string name=\"color_mixing\">Barreja de colors</string>\n    <string name=\"color_info\">Informació de color</string>\n    <string name=\"selected_color\">Color seleccionat</string>\n    <string name=\"color_to_mix\">Color per barrejar</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">No es pot utilitzar monet mentre els colors dinàmics estan activats</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Imatge LUT objectiu</string>\n    <string name=\"amatorka\">Un aficionat</string>\n    <string name=\"miss_etikate\">Senyoreta Etiqueta</string>\n    <string name=\"soft_elegance\">Elegància suau</string>\n    <string name=\"soft_elegance_variant\">Variant suau elegància</string>\n    <string name=\"palette_transfer_variant\">Variant de transferència de paleta</string>\n    <string name=\"cube_lut\">LUT 3D</string>\n    <string name=\"target_cube_lut_file\">Fitxer LUT 3D de destinació (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bypass de lleixiu</string>\n    <string name=\"candlelight\">Llum de les espelmes</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Amber nervioso</string>\n    <string name=\"fall_colors\">Colors de tardor</string>\n    <string name=\"film_stock_50\">Film Stock 50</string>\n    <string name=\"foggy_night\">Nit de boira</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Obteniu una imatge LUT neutral</string>\n    <string name=\"save_empty_lut_sub\">Primer, utilitzeu la vostra aplicació d\\'edició de fotos preferida per aplicar un filtre a LUT neutral que podeu obtenir aquí. Perquè això funcioni correctament, cada color de píxel no ha de dependre d\\'altres píxels (per exemple, el desenfocament no funcionarà). Un cop estigui llest, utilitzeu la vostra nova imatge LUT com a entrada per al filtre 512*512 LUT</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Cel·luloide</string>\n    <string name=\"coffee\">Cafè</string>\n    <string name=\"golden_forest\">Bosc daurat</string>\n    <string name=\"greenish\">Verdós</string>\n    <string name=\"retro_yellow\">Groc retro</string>\n    <string name=\"links_preview\">Vista prèvia d\\'enllaços</string>\n    <string name=\"links_preview_sub\">Permet la recuperació de la vista prèvia d\\'enllaços en llocs on podeu obtenir text (QRCode, OCR, etc.)</string>\n    <string name=\"links\">Enllaços</string>\n    <string name=\"ico_size_warning\">Els fitxers ICO només es poden desar amb una mida màxima de 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF a WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Converteix imatges GIF en imatges animades WEBP</string>\n    <string name=\"webp_tools\">Eines WEB</string>\n    <string name=\"webp_tools_sub\">Converteix imatges a imatges animades WEBP o extreu fotogrames d\\'una animació WEBP determinada</string>\n    <string name=\"webp_type_to_image\">WEBP a imatges</string>\n    <string name=\"webp_type_to_image_sub\">Converteix el fitxer WEBP en un lot d\\'imatges</string>\n    <string name=\"webp_type_to_webp_sub\">Converteix un lot d\\'imatges a un fitxer WEBP</string>\n    <string name=\"webp_type_to_webp\">Imatges al WEBP</string>\n    <string name=\"select_webp_image_to_start\">Trieu la imatge WEBP per començar</string>\n    <string name=\"manage_storage_extra_types\">No hi ha accés complet als fitxers</string>\n    <string name=\"manage_storage_extra_types_sub\">Permet l\\'accés a tots els fitxers per veure JXL, QOI i altres imatges que no es reconeixen com a imatges a Android. Sense el permís Image Toolbox no pot mostrar aquestes imatges</string>\n    <string name=\"default_draw_color\">Color de dibuix per defecte</string>\n    <string name=\"default_draw_path_mode\">Mode de camí de dibuix predeterminat</string>\n    <string name=\"add_timestamp\">Afegeix marca de temps</string>\n    <string name=\"add_timestamp_sub\">Activa l\\'addició de marca de temps al nom del fitxer de sortida</string>\n    <string name=\"formatted_timestamp\">Marca de temps amb format</string>\n    <string name=\"formatted_timestamp_sub\">Activeu el format de marca de temps al nom del fitxer de sortida en comptes de mil·lisos bàsics</string>\n    <string name=\"enable_timestamps_to_format_them\">Activeu les marques de temps per seleccionar-ne el format</string>\n    <string name=\"one_time_save_location\">Ubicació d\\'estalvi d\\'una vegada</string>\n    <string name=\"one_time_save_location_sub\">Visualitzeu i editeu les ubicacions d\\'emmagatzematge d\\'una vegada que podeu utilitzar prement el botó desa en la majoria de les opcions</string>\n    <string name=\"recently_used\">Usat recentment</string>\n    <string name=\"ci_channel\">Canal CI</string>\n    <string name=\"group\">Grup</string>\n    <string name=\"image_toolbox_in_telegram\">Caixa d\\'eines d\\'imatge a Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Uneix-te al nostre xat on podràs parlar del que vulguis i també mirar al canal CI on publico betas i anuncis</string>\n    <string name=\"ci_channel_sub\">Rebeu notificacions sobre les noves versions de l\\'aplicació i llegiu els anuncis</string>\n    <string name=\"fit_description\">Ajusteu una imatge a les dimensions donades i apliqueu el desenfocament o el color al fons</string>\n    <string name=\"tools_arrangement\">Disposició d\\'eines</string>\n    <string name=\"group_tools_by_type\">Agrupa les eines per tipus</string>\n    <string name=\"group_tools_by_type_sub\">Agrupa les eines de la pantalla principal pel seu tipus en lloc d\\'una disposició de llista personalitzada</string>\n    <string name=\"default_values\">Valors per defecte</string>\n    <string name=\"system_bars_visibility\">Visibilitat de les barres del sistema</string>\n    <string name=\"show_system_bars_by_swipe\">Mostra les barres del sistema fent lliscar el dit</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Permet lliscar per mostrar les barres del sistema si estan amagades</string>\n    <string name=\"auto\">Automàtic</string>\n    <string name=\"hide_all\">Amaga-ho tot</string>\n    <string name=\"show_all\">Mostra-ho tot</string>\n    <string name=\"hide_nav_bar\">Amaga la barra de navegació</string>\n    <string name=\"hide_status_bar\">Amaga la barra d\\'estat</string>\n    <string name=\"noise_generation\">Generació de soroll</string>\n    <string name=\"noise_generation_sub\">Genera diferents sorolls com Perlin o altres tipus</string>\n    <string name=\"frequency\">Freqüència</string>\n    <string name=\"noise_type\">Tipus de soroll</string>\n    <string name=\"rotation_type\">Tipus de rotació</string>\n    <string name=\"fractal_type\">Tipus fractal</string>\n    <string name=\"octaves\">Octaves</string>\n    <string name=\"lacunarity\">Lacunaritat</string>\n    <string name=\"gain\">Guanyar</string>\n    <string name=\"weighted_strength\">Força ponderada</string>\n    <string name=\"ping_pong_strength\">Ping Pong Força</string>\n    <string name=\"distance_function\">Funció de distància</string>\n    <string name=\"return_type\">Tipus de retorn</string>\n    <string name=\"jitter\">Trastorn</string>\n    <string name=\"domain_warp\">Deformació del domini</string>\n    <string name=\"alignment\">Alineació</string>\n    <string name=\"custom_filename\">Nom de fitxer personalitzat</string>\n    <string name=\"custom_filename_sub\">Seleccioneu la ubicació i el nom del fitxer que s\\'utilitzaran per desar la imatge actual</string>\n    <string name=\"saved_to_custom\">Desat a la carpeta amb un nom personalitzat</string>\n    <string name=\"collage_maker\">Creador de collages</string>\n    <string name=\"collage_maker_sub\">Feu collages de fins a 20 imatges</string>\n    <string name=\"collage_type\">Tipus de collage</string>\n    <string name=\"collages_info\">Mantingueu premut la imatge per intercanviar, moure i fer zoom per ajustar la posició</string>\n    <string name=\"disable_rotation\">Desactiva la rotació</string>\n    <string name=\"disable_rotation_sub\">Impedeix la rotació de les imatges amb gestos amb dos dits</string>\n    <string name=\"enable_snapping_to_borders\">Activa l\\'ajustament a les vores</string>\n    <string name=\"enable_snapping_to_borders_sub\">Després de moure\\'s o fer zoom, les imatges s\\'ajustaran per omplir les vores del marc</string>\n    <string name=\"histogram\">Histograma</string>\n    <string name=\"histogram_sub\">Histograma d\\'imatge RGB o brillantor per ajudar-vos a fer ajustaments</string>\n    <string name=\"image_for_histogram\">Aquesta imatge s\\'utilitzarà per generar histogrames RGB i Brillantor</string>\n    <string name=\"tesseract_options\">Opcions de Tesseract</string>\n    <string name=\"tesseract_options_sub\">Apliqueu algunes variables d\\'entrada per al motor tesseract</string>\n    <string name=\"custom_options\">Opcions personalitzades</string>\n    <string name=\"custom_params_info\">Les opcions s\\'han d\\'introduir seguint aquest patró: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Retall automàtic</string>\n    <string name=\"free_corners\">Racons lliures</string>\n    <string name=\"free_corners_sub\">Retalla la imatge per polígon, això també corregeix la perspectiva</string>\n    <string name=\"coerce_points_to_image_bounds\">Coaccionar els punts als límits de la imatge</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Els punts no estaran limitats pels límits de la imatge, això és útil per a una correcció de perspectiva més precisa</string>\n    <string name=\"mask\">Màscara</string>\n    <string name=\"spot_heal_sub\">Emplenament conscient del contingut sota el camí dibuixat</string>\n    <string name=\"spot_heal\">Punt de curació</string>\n    <string name=\"use_circle_kernel\">Utilitzeu Circle Kernel</string>\n    <string name=\"opening\">Obertura</string>\n    <string name=\"closing\">Tancament</string>\n    <string name=\"morphological_gradient\">Gradient Morfològic</string>\n    <string name=\"top_hat\">Barret de copa</string>\n    <string name=\"black_hat\">Barret negre</string>\n    <string name=\"tone_curves\">Corbes de to</string>\n    <string name=\"reset_curves\">Restableix les corbes</string>\n    <string name=\"reset_curves_sub\">Les corbes es tornaran al valor predeterminat</string>\n    <string name=\"line_style\">Estil de línia</string>\n    <string name=\"gap_size\">Mida de la bretxa</string>\n    <string name=\"dashed\">De punt</string>\n    <string name=\"dot_dashed\">Punt puntejat</string>\n    <string name=\"stamped\">Estampat</string>\n    <string name=\"zigzag\">Ziga-zaga</string>\n    <string name=\"dashed_sub\">Dibuixa una línia discontínua al llarg del camí dibuixat amb la mida de buit especificada</string>\n    <string name=\"dot_dashed_sub\">Dibuixa punts i línies discontínues al llarg del camí donat</string>\n    <string name=\"defaultt_sub\">Només línies rectes per defecte</string>\n    <string name=\"stamped_sub\">Dibuixa les formes seleccionades al llarg del camí amb l\\'espaiat especificat</string>\n    <string name=\"zigzag_sub\">Dibuixa una ziga-zaga ondulada al llarg del camí</string>\n    <string name=\"zigzag_ratio\">Relació en zig-zag</string>\n    <string name=\"create_shortcut\">Crea una drecera</string>\n    <string name=\"create_shortcut_title\">Trieu l\\'eina per fixar</string>\n    <string name=\"create_shortcut_subtitle\">L\\'eina s\\'afegirà a la pantalla d\\'inici del llançador com a drecera, utilitzeu-la combinant-la amb la configuració \\\"Omet la selecció de fitxers\\\" per aconseguir el comportament necessari</string>\n    <string name=\"dont_stack_frames\">No apileu marcs</string>\n    <string name=\"dont_stack_frames_sub\">Permet eliminar els fotogrames anteriors, de manera que no s\\'apilen els uns als altres</string>\n    <string name=\"crossfade\">Fundició creuada</string>\n    <string name=\"crossfade_sub\">Els fotogrames s\\'encreuaran entre si</string>\n    <string name=\"crossfade_count\">Els fotogrames de fundició creuada compten</string>\n    <string name=\"threshold_one\">Llindar 1</string>\n    <string name=\"threshold_two\">Llindar dos</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Mirall 101</string>\n    <string name=\"enhanced_zoom_blur\">Desenfocament del zoom millorat</string>\n    <string name=\"laplacian_simple\">Laplacià simple</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Graella d\\'ajuda</string>\n    <string name=\"helper_grid_sub\">Mostra la quadrícula de suport a sobre de l\\'àrea de dibuix per ajudar amb manipulacions precises</string>\n    <string name=\"grid_color\">Color de la quadrícula</string>\n    <string name=\"cell_width\">Amplada de la cel·la</string>\n    <string name=\"cell_height\">Alçada cel·lular</string>\n    <string name=\"compact_selectors\">Selectors compactes</string>\n    <string name=\"compact_selectors_sub\">Alguns controls de selecció utilitzaran un disseny compacte per ocupar menys espai</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Doneu permís a la càmera a la configuració per capturar la imatge</string>\n    <string name=\"layout\">Disseny</string>\n    <string name=\"main_screen_title\">Títol de la pantalla principal</string>\n    <string name=\"constant_rate_factor\">Factor de taxa constant (CRF)</string>\n    <string name=\"crf_sub\">Un valor de %1$s significa una compressió lenta, que resulta en una mida de fitxer relativament petita. %2$s significa una compressió més ràpida, donant lloc a un fitxer gran.</string>\n    <string name=\"lut_library\">Biblioteca Lut</string>\n    <string name=\"lut_library_sub\">Baixeu la col·lecció de LUT, que podeu aplicar després de descarregar</string>\n    <string name=\"lut_library_update_sub\">Actualitzeu la col·lecció de LUT (només es posaran a la cua les noves), que podeu aplicar després de descarregar</string>\n    <string name=\"filter_preview_image_sub\">Canvia la vista prèvia de la imatge per defecte per als filtres</string>\n    <string name=\"filter_preview_image\">Imatge de previsualització</string>\n    <string name=\"hide\">Amaga</string>\n    <string name=\"show\">Mostra</string>\n    <string name=\"slider_type\">Tipus de control lliscant</string>\n    <string name=\"fancy\">Fantasia</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy_sub\">Un control lliscant d\\'aspecte elegant. Aquesta és l\\'opció predeterminada</string>\n    <string name=\"material_2_sub\">Un control lliscant Material 2</string>\n    <string name=\"material_you_slider_sub\">Un control lliscant Material You</string>\n    <string name=\"apply\">Aplicar</string>\n    <string name=\"center_align_dialog_buttons\">Botons de diàleg central</string>\n    <string name=\"center_align_dialog_buttons_sub\">Els botons dels diàlegs es col·locaran al centre en lloc del costat esquerre si és possible</string>\n    <string name=\"open_source_licenses\">Llicències de codi obert</string>\n    <string name=\"open_source_licenses_sub\">Consulta les llicències de les biblioteques de codi obert utilitzades en aquesta aplicació</string>\n    <string name=\"area\">Àrea</string>\n    <string name=\"area_sub\">Re-mostreig utilitzant la relació d\\'àrea de píxels. Pot ser un mètode preferit per a la destrucció d\\'imatges, ja que dóna resultats lliures de moiré. Però quan s\\'amplia la imatge, és similar al mètode \\\"Més propera\\\".</string>\n    <string name=\"enable_tonemapping\">Activa el mapa de tons</string>\n    <string name=\"enter_percent\">Introduïu %</string>\n    <string name=\"unknown_host\">No es pot accedir al lloc, proveu d\\'utilitzar VPN o comproveu si l\\'URL és correcte</string>\n    <string name=\"markup_layers\">Capes de marcatge</string>\n    <string name=\"markup_layers_sub\">Mode de capes amb la possibilitat de col·locar lliurement imatges, text i molt més</string>\n    <string name=\"edit_layer\">Edita la capa</string>\n    <string name=\"layers_on_image\">Capes a la imatge</string>\n    <string name=\"layers_on_image_sub\">Utilitzeu una imatge com a fons i afegiu-hi diferents capes a sobre</string>\n    <string name=\"layers_on_background\">Capes al fons</string>\n    <string name=\"layers_on_background_sub\">Igual que la primera opció però amb color en comptes d\\'imatge</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Configuració ràpida lateral</string>\n    <string name=\"fast_settings_side_sub\">Afegiu una franja flotant al costat seleccionat mentre editeu les imatges, que obrirà la configuració ràpida quan feu clic</string>\n    <string name=\"clear_selection\">Esborra la selecció</string>\n    <string name=\"settings_group_visibility_hidden\">El grup de configuració \\\"%1$s\\\" es replegarà de manera predeterminada</string>\n    <string name=\"settings_group_visibility_visible\">El grup de configuració \\\"%1$s\\\" s\\'ampliarà de manera predeterminada</string>\n    <string name=\"base_64_tools\">Eines Base64</string>\n    <string name=\"base_64_tools_sub\">Descodifiqueu la cadena Base64 a la imatge o codifiqueu la imatge al format Base64</string>\n    <string name=\"base_64\">Base 64</string>\n    <string name=\"not_a_valid_base_64\">El valor proporcionat no és una cadena Base64 vàlida</string>\n    <string name=\"copy_not_a_valid_base_64\">No es pot copiar la cadena Base64 buida o no vàlida</string>\n    <string name=\"paste_base_64\">Enganxa la base 64</string>\n    <string name=\"copy_base_64\">Copia Base64</string>\n    <string name=\"base_64_tips\">Carregueu la imatge per copiar o desar la cadena Base64. Si teniu la cadena en si, podeu enganxar-la a dalt per obtenir la imatge</string>\n    <string name=\"save_base_64\">Desa Base64</string>\n    <string name=\"share_base_64\">Comparteix Base64</string>\n    <string name=\"options\">Opcions</string>\n    <string name=\"actions\">Accions</string>\n    <string name=\"import_base_64\">Importa Base64</string>\n    <string name=\"base_64_actions\">Accions Base64</string>\n    <string name=\"add_outline\">Afegeix un esquema</string>\n    <string name=\"add_outline_sub\">Afegiu un esquema al voltant del text amb el color i l\\'amplada especificats</string>\n    <string name=\"outline_color\">Color del contorn</string>\n    <string name=\"outline_size\">Mida del contorn</string>\n    <string name=\"rotation\">Rotació</string>\n    <string name=\"checksum_as_filename\">Suma de comprovació com a nom de fitxer</string>\n    <string name=\"checksum_as_filename_sub\">Les imatges de sortida tindran un nom corresponent a la seva suma de comprovació de dades</string>\n    <string name=\"free_software_partner\">Programari lliure (partner)</string>\n    <string name=\"free_software_partner_sub\">Programari més útil al canal de socis d\\'aplicacions d\\'Android</string>\n    <string name=\"algorithms\">Algorisme</string>\n    <string name=\"checksum_tools\">Eines de suma de comprovació</string>\n    <string name=\"checksum_tools_sub\">Compareu sumes de comprovació, calculeu hash o creeu cadenes hexadecimales a partir de fitxers utilitzant diferents algorismes de hash</string>\n    <string name=\"calculate\">Calcula</string>\n    <string name=\"text_hash\">Text Hash</string>\n    <string name=\"checksum\">Suma de control</string>\n    <string name=\"pick_file_to_checksum\">Trieu el fitxer per calcular la seva suma de comprovació en funció de l\\'algorisme seleccionat</string>\n    <string name=\"enter_text_to_checksum\">Introduïu text per calcular la seva suma de comprovació en funció de l\\'algorisme seleccionat</string>\n    <string name=\"source_checksum\">Suma de comprovació de la font</string>\n    <string name=\"checksum_to_compare\">Suma de comprovació per comparar</string>\n    <string name=\"match\">Partit!</string>\n    <string name=\"difference\">Diferència</string>\n    <string name=\"match_sub\">Les sumes de control són iguals, pot ser segur</string>\n    <string name=\"difference_sub\">Les sumes de control no són iguals, el fitxer pot ser perillós!</string>\n    <string name=\"mesh_gradients\">Gradients de malla</string>\n    <string name=\"collection_mesh_gradients_sub\">Mireu la col·lecció en línia de Mesh Gradients</string>\n    <string name=\"wrong_font\">Només es poden importar tipus de lletra TTF i OTF</string>\n    <string name=\"import_font\">Importa el tipus de lletra (TTF/OTF)</string>\n    <string name=\"export_fonts\">Exportar tipus de lletra</string>\n    <string name=\"imported_fonts\">Tipus de lletra importats</string>\n    <string name=\"error_while_saving\">S\\'ha produït un error en desar l\\'intent, prova de canviar la carpeta de sortida</string>\n    <string name=\"filename_is_not_set\">El nom del fitxer no està definit</string>\n    <string name=\"none\">Cap</string>\n    <string name=\"custom_pages\">Pàgines personalitzades</string>\n    <string name=\"pages_selection\">Selecció de pàgines</string>\n    <string name=\"tool_exit_confirmation\">Confirmació de sortida de l\\'eina</string>\n    <string name=\"tool_exit_confirmation_sub\">Si teniu canvis no desats mentre feu servir eines concretes i intenteu tancar-los, es mostrarà el diàleg de confirmació</string>\n    <string name=\"edit_exif_screen\">Edita EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Canvieu les metadades d\\'una imatge única sense recompressió</string>\n    <string name=\"edit_exif_tag\">Toqueu per editar les etiquetes disponibles</string>\n    <string name=\"change_sticker\">Canvia l\\'adhesiu</string>\n    <string name=\"fit_width\">Amplada d\\'ajust</string>\n    <string name=\"fit_height\">Alçada d\\'ajust</string>\n    <string name=\"batch_compare\">Comparació per lots</string>\n    <string name=\"pick_files_to_checksum\">Trieu fitxers/fitxers per calcular la seva suma de comprovació en funció de l\\'algorisme seleccionat</string>\n    <string name=\"pick_files\">Trieu fitxers</string>\n    <string name=\"pick_directory\">Trieu Directori</string>\n    <string name=\"head_length_scale\">Escala de longitud del cap</string>\n    <string name=\"stamp\">Segell</string>\n    <string name=\"timestamp\">Marca de temps</string>\n    <string name=\"format_pattern\">Patró de format</string>\n    <string name=\"padding\">Encoixinat</string>\n    <string name=\"image_cutting\">Tall d\\'imatges</string>\n    <string name=\"image_cutting_sub\">Retalla la part de la imatge i fusiona les de l\\'esquerra (pot ser inversa) per línies verticals o horitzontals</string>\n    <string name=\"vertical_pivot_line\">Línia de pivot vertical</string>\n    <string name=\"horizontal_pivot_line\">Línia de pivot horitzontal</string>\n    <string name=\"inverse_selection\">Selecció inversa</string>\n    <string name=\"inverse_vertical_selection_sub\">Es deixarà la part tallada verticalment, en lloc de fusionar les parts al voltant de l\\'àrea de tall</string>\n    <string name=\"inverse_horizontal_selection_sub\">Es deixarà la part tallada horitzontal, en lloc de fusionar les parts al voltant de l\\'àrea de tall</string>\n    <string name=\"collection_mesh_gradients\">Col·lecció de degradats de malla</string>\n    <string name=\"mesh_gradients_sub\">Creeu un degradat de malla amb una quantitat personalitzada de nusos i resolució</string>\n    <string name=\"gradient_maker_type_image_mesh\">Superposició de degradat de malla</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Composa el degradat de malla de la part superior de les imatges donades</string>\n    <string name=\"points_customization\">Personalització de punts</string>\n    <string name=\"grid_size\">Mida de la graella</string>\n    <string name=\"resolution_x\">Resolució X</string>\n    <string name=\"resolution_y\">Resolució Y</string>\n    <string name=\"resolution\">Resolució</string>\n    <string name=\"pixel_by_pixel\">Píxel a Píxel</string>\n    <string name=\"highlight_color\">Ressaltar el color</string>\n    <string name=\"pixel_comparison_type\">Tipus de comparació de píxels</string>\n    <string name=\"scan_barcode\">Escaneja el codi de barres</string>\n    <string name=\"height_ratio\">Relació d\\'altura</string>\n    <string name=\"barcode_type\">Tipus de codi de barres</string>\n    <string name=\"enforce_bw\">Aplicar en B/N</string>\n    <string name=\"enforce_bw_sub\">La imatge del codi de barres serà completament en blanc i negre i no tindran color pel tema de l\\'aplicació</string>\n    <string name=\"barcodes_sub\">Escaneja qualsevol codi de barres (QR, EAN, AZTEC, …) i obtén el seu contingut o enganxa el teu text per generar-ne un de nou</string>\n    <string name=\"no_barcode_found\">No s\\'ha trobat cap codi de barres</string>\n    <string name=\"generated_barcode_will_be_here\">El codi de barres generat estarà aquí</string>\n    <string name=\"audio_cover_extractor\">Portades d\\'àudio</string>\n    <string name=\"audio_cover_extractor_sub\">Extraieu imatges de la portada d\\'àlbum dels fitxers d\\'àudio, els formats més habituals són compatibles</string>\n    <string name=\"pick_audio_to_start\">Trieu l\\'àudio per començar</string>\n    <string name=\"pick_audio\">Trieu l\\'àudio</string>\n    <string name=\"no_covers_found\">No s\\'han trobat cobertes</string>\n    <string name=\"send_logs\">Envia registres</string>\n    <string name=\"send_logs_sub\">Feu clic per compartir el fitxer de registres de l\\'aplicació, això em pot ajudar a detectar el problema i solucionar-los</string>\n    <string name=\"crash_title\">Vaja… S\\'ha produït un error</string>\n    <string name=\"crash_subtitle\">Podeu contactar amb mi mitjançant les opcions següents i intentaré trobar una solució.\\n(No oblideu adjuntar els registres)</string>\n    <string name=\"ocr_write_to_file\">Escriure al fitxer</string>\n    <string name=\"ocr_write_to_file_sub\">Extraieu text del lot d\\'imatges i emmagatzemeu-lo en un fitxer de text</string>\n    <string name=\"ocr_write_to_metadata\">Escriure a les metadades</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extraieu el text de cada imatge i col·loqueu-lo a la informació EXIF ​​de les fotos relatives</string>\n    <string name=\"invisible_mode\">Mode invisible</string>\n    <string name=\"invisible_mode_sub\">Utilitzeu l\\'esteganografia per crear filigranes invisibles als ulls dins dels bytes de les vostres imatges</string>\n    <string name=\"use_lsb\">Utilitzeu LSB</string>\n    <string name=\"use_lsb_sub\">S\\'utilitzarà el mètode d\\'esteganografia LSB (Less Significant Bit), en cas contrari FD (Domini de freqüència).</string>\n    <string name=\"auto_remove_red_eyes\">Elimina automàticament els ulls vermells</string>\n    <string name=\"password\">Contrasenya</string>\n    <string name=\"unlock\">Desbloqueja</string>\n    <string name=\"pdf_is_protected\">PDF està protegit</string>\n    <string name=\"operation_almost_complete\">Operació gairebé acabada. Si cancel·les ara caldrà reiniciar-lo</string>\n    <string name=\"sort_by_date_modified\">Data de modificació</string>\n    <string name=\"sort_by_date_modified_reversed\">Data de modificació (invertida)</string>\n    <string name=\"sort_by_size\">Mida</string>\n    <string name=\"sort_by_size_reversed\">Mida (invertida)</string>\n    <string name=\"sort_by_mime_type\">Tipus MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Tipus MIME (invertit)</string>\n    <string name=\"sort_by_extension\">Extensió</string>\n    <string name=\"sort_by_extension_reversed\">Extensió (invertida)</string>\n    <string name=\"sort_by_date_added\">Data d\\'afegit</string>\n    <string name=\"sort_by_date_added_reversed\">Data afegida (invertida)</string>\n    <string name=\"left_to_right\">D\\'esquerra a dreta</string>\n    <string name=\"right_to_left\">De dreta a esquerra</string>\n    <string name=\"top_to_bottom\">De dalt a baix</string>\n    <string name=\"bottom_to_top\">De baix a dalt</string>\n    <string name=\"liquid_glass\">Vidre líquid</string>\n    <string name=\"liquid_glass_sub\">Un interruptor basat en IOS 26 anunciat recentment i el seu sistema de disseny de vidre líquid</string>\n    <string name=\"pick_image_or_base64\">Trieu la imatge o enganxeu/importeu dades de Base64 a continuació</string>\n    <string name=\"type_image_link\">Escriviu l\\'enllaç de la imatge per començar</string>\n    <string name=\"paste_link\">Enganxa l\\'enllaç</string>\n    <string name=\"kaleidoscope\">Calidoscopi</string>\n    <string name=\"secondary_angle\">Angle secundari</string>\n    <string name=\"sides\">Els costats</string>\n    <string name=\"channel_mix\">Mescla de canals</string>\n    <string name=\"blue_green\">Verd blau</string>\n    <string name=\"red_blue\">Blau vermell</string>\n    <string name=\"green_red\">Verd vermell</string>\n    <string name=\"into_red\">En vermell</string>\n    <string name=\"into_green\">Al verd</string>\n    <string name=\"into_blue\">Al blau</string>\n    <string name=\"cyan\">Cian</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Groc</string>\n    <string name=\"color_halftone\">Color de mitges tintes</string>\n    <string name=\"contour\">Contorn</string>\n    <string name=\"levels\">Nivells</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi cristal·litza</string>\n    <string name=\"shape\">Forma</string>\n    <string name=\"stretch\">Estirar</string>\n    <string name=\"randomness\">Aleatorietat</string>\n    <string name=\"despeckle\">Destaquejar</string>\n    <string name=\"diffuse\">Difús</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Segon radi</string>\n    <string name=\"equalize\">Igualar</string>\n    <string name=\"glow\">resplendor</string>\n    <string name=\"whirl_and_pinch\">Girar i pessigar</string>\n    <string name=\"pointillize\">Puntilitzar</string>\n    <string name=\"border_color\">Color de la vora</string>\n    <string name=\"polar_coordinates\">Coordenades polars</string>\n    <string name=\"rect_to_polar\">Recta a polar</string>\n    <string name=\"polar_to_rect\">Polar a recte</string>\n    <string name=\"invert_in_circle\">Inverteix en cercle</string>\n    <string name=\"reduce_noise\">Reduir el soroll</string>\n    <string name=\"simple_solarize\">Solarització senzilla</string>\n    <string name=\"weave\">Teixir</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X Amplada</string>\n    <string name=\"y_wdth\">Y Amplada</string>\n    <string name=\"twirl\">Girar</string>\n    <string name=\"rubber_stmp\">Segell de goma</string>\n    <string name=\"smear\">Untar</string>\n    <string name=\"density\">Densitat</string>\n    <string name=\"mix\">Barrejar</string>\n    <string name=\"sphere_lensh_distortion\">Distorsió de la lent esfèrica</string>\n    <string name=\"refraction_index\">Índex de refracció</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Angle de propagació</string>\n    <string name=\"sparkle\">Espurneig</string>\n    <string name=\"rays\">Raigs</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Maria</string>\n    <string name=\"autumn\">Tardor</string>\n    <string name=\"bone\">Os</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Hivern</string>\n    <string name=\"ocean\">Oceà</string>\n    <string name=\"summer\">Estiu</string>\n    <string name=\"spring\">Primavera</string>\n    <string name=\"cool_variant\">Variant genial</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rosa</string>\n    <string name=\"hot\">Calent</string>\n    <string name=\"parula\">Paraula</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Infern</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Ciutadans</string>\n    <string name=\"twilight\">Crepuscle</string>\n    <string name=\"twilight_shifted\">Crepuscle canviat</string>\n    <string name=\"auto_perspective\">Perspectiva Automàtica</string>\n    <string name=\"deskew\">Desviació</string>\n    <string name=\"allow_crop\">Permetre retallar</string>\n    <string name=\"crop_or_perspective\">Retall o perspectiva</string>\n    <string name=\"absolute\">Absoluta</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Verd profund</string>\n    <string name=\"lens_correction\">Correcció de la lent</string>\n    <string name=\"target_lens_profile\">Fitxer de perfil de la lent objectiu en format JSON</string>\n    <string name=\"download_ready_lens_profiles\">Baixeu perfils de lents preparats</string>\n    <string name=\"part_percents\">Percentatges de part</string>\n    <string name=\"export_as_json\">Exporta com a JSON</string>\n    <string name=\"export_as_json_sub\">Copieu la cadena amb dades de paleta com a representació JSON</string>\n    <string name=\"seam_carving\">Talla de costures</string>\n    <string name=\"home_screen\">Pantalla d\\'inici</string>\n    <string name=\"lock_screen\">Pantalla de bloqueig</string>\n    <string name=\"built_in\">Integrat</string>\n    <string name=\"wallpapers_export\">Exportació de fons de pantalla</string>\n    <string name=\"refresh\">Actualitza</string>\n    <string name=\"wallpapers_export_sub\">Obteniu fons de pantalla actuals de la llar, de bloqueig i integrats</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Permet l\\'accés a tots els fitxers, això és necessari per recuperar fons de pantalla</string>\n    <string name=\"allow_read_media_images_for_wp\">El permís de gestió d\\'emmagatzematge extern no és suficient, heu de permetre l\\'accés a les vostres imatges, assegureu-vos de seleccionar \\\"Permet-ho tot\\\"</string>\n    <string name=\"add_preset_to_filename\">Afegeix un valor predefinit al nom del fitxer</string>\n    <string name=\"add_preset_to_filename_sub\">Afegeix el sufix amb el valor predefinit seleccionat al nom del fitxer d\\'imatge</string>\n    <string name=\"add_image_scale_mode_to_filename\">Afegeix el mode d\\'escala d\\'imatge al nom del fitxer</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Afegeix el sufix amb el mode d\\'escala d\\'imatge seleccionat al nom del fitxer de la imatge</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Converteix la imatge en text ascii que semblarà una imatge</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Aplica un filtre negatiu a la imatge per obtenir un millor resultat en alguns casos</string>\n    <string name=\"processing_screenshot\">S\\'està processant la captura de pantalla</string>\n    <string name=\"screenshot_not_captured_try_again\">La captura de pantalla no s\\'ha capturat, torna-ho a provar</string>\n    <string name=\"skipped_saving\">S\\'ha omès l\\'estalvi</string>\n    <string name=\"skipped_saving_multiple\">S\\'han omès %1$s fitxers</string>\n    <string name=\"allow_skip_if_larger\">Permet ometre si és més gran</string>\n    <string name=\"allow_skip_if_larger_sub\">Algunes eines podran saltar-se desar imatges si la mida del fitxer resultant és més gran que l\\'original</string>\n    <string name=\"qr_type_calendar_event\">Esdeveniment del calendari</string>\n    <string name=\"qr_type_contact_info\">Contacte</string>\n    <string name=\"qr_type_email\">Correu electrònic</string>\n    <string name=\"qr_type_geo_point\">Ubicació</string>\n    <string name=\"qr_type_phone\">Telèfon</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Xarxa oberta</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telèfon</string>\n    <string name=\"message\">Missatge</string>\n    <string name=\"address\">Adreça</string>\n    <string name=\"subject\">Assumpte</string>\n    <string name=\"body\">Cos</string>\n    <string name=\"name\">Nom</string>\n    <string name=\"organization\">Organització</string>\n    <string name=\"title\">Títol</string>\n    <string name=\"phones\">Telèfons</string>\n    <string name=\"emails\">Correus electrònics</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Adreces</string>\n    <string name=\"summary\">Resum</string>\n    <string name=\"description\">Descripció</string>\n    <string name=\"location\">Ubicació</string>\n    <string name=\"organizer\">Organitzador</string>\n    <string name=\"start_date\">Data d\\'inici</string>\n    <string name=\"end_date\">Data de finalització</string>\n    <string name=\"status\">Estat</string>\n    <string name=\"latitude\">Latitud</string>\n    <string name=\"longitude\">Longitud</string>\n    <string name=\"create_barcode\">Crea codi de barres</string>\n    <string name=\"edit_barcode\">Edita el codi de barres</string>\n    <string name=\"wifi_configuration\">Configuració Wi-Fi</string>\n    <string name=\"security\">Seguretat</string>\n    <string name=\"pick_contact\">Tria el contacte</string>\n    <string name=\"grant_contact_permission\">Concedeix permís als contactes a la configuració per emplenar automàticament amb el contacte seleccionat</string>\n    <string name=\"contact_info\">Informació de contacte</string>\n    <string name=\"first_name\">Nom de pila</string>\n    <string name=\"middle_name\">segon nom</string>\n    <string name=\"last_name\">Cognom</string>\n    <string name=\"pronunciation\">Pronunciació</string>\n    <string name=\"add_phone\">Afegeix el telèfon</string>\n    <string name=\"add_email\">Afegeix un correu electrònic</string>\n    <string name=\"add_address\">Afegeix una adreça</string>\n    <string name=\"website\">Lloc web</string>\n    <string name=\"add_website\">Afegeix un lloc web</string>\n    <string name=\"formatted_name\">Nom amb format</string>\n    <string name=\"qr_code_top_image\">Aquesta imatge s\\'utilitzarà per col·locar-la a sobre del codi de barres</string>\n    <string name=\"code_customization\">Personalització del codi</string>\n    <string name=\"qr_logo_image\">Aquesta imatge s\\'utilitzarà com a logotip al centre del codi QR</string>\n    <string name=\"logo\">Logotip</string>\n    <string name=\"logo_padding\">Encoixinat de logotip</string>\n    <string name=\"logo_size\">Mida del logotip</string>\n    <string name=\"logo_corners\">Cantonades del logotip</string>\n    <string name=\"fourth_eye\">Quart ull</string>\n    <string name=\"fourth_eye_description\">Afegeix simetria ocular al codi qr afegint un quart ull a l\\'extrem inferior</string>\n    <string name=\"pixel_shape\">Forma de píxel</string>\n    <string name=\"frame_shape\">Forma de marc</string>\n    <string name=\"ball_shape\">Forma de bola</string>\n    <string name=\"error_correction_level\">Nivell de correcció d\\'errors</string>\n    <string name=\"dark_color\">Color fosc</string>\n    <string name=\"light_color\">Color clar</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Estil semblant a Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Patró de màscara</string>\n    <string name=\"code_may_be_not_scannable\">És possible que aquest codi no es pugui escanejar, canvieu els paràmetres d\\'aparença per fer-lo llegible amb tots els dispositius</string>\n    <string name=\"not_scannable\">No escanejable</string>\n    <string name=\"launcher_mode_sub\">Les eines semblaran el llançador d\\'aplicacions de la pantalla d\\'inici per ser més compactes</string>\n    <string name=\"launcher_mode\">Mode d\\'inici</string>\n    <string name=\"flood_fill_sub\">Omple una àrea amb el pinzell i l\\'estil seleccionats</string>\n    <string name=\"flood_fill\">Farciment d\\'inundació</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Dibuixa un camí amb estil grafit</string>\n    <string name=\"square_particles\">Partícules quadrades</string>\n    <string name=\"square_particles_sub\">Les partícules de polvorització tindran forma quadrada en lloc de cercles</string>\n    <string name=\"palette_tools\">Eines de paleta</string>\n    <string name=\"palette_tools_sub\">Genereu material bàsic/de la paleta a partir d\\'imatge, o importeu/exporteu a diferents formats de paleta</string>\n    <string name=\"edit_palette\">Edita la paleta</string>\n    <string name=\"edit_palette_sub\">Exporta/importa la paleta en diversos formats</string>\n    <string name=\"color_name\">Nom del color</string>\n    <string name=\"palette_name\">Nom de la paleta</string>\n    <string name=\"palette_format\">Format de paleta</string>\n    <string name=\"export_palette_sub\">Exporta la paleta generada a diferents formats</string>\n    <string name=\"add_color_palette_sub\">Afegeix un color nou a la paleta actual</string>\n    <string name=\"palette_name_not_supported\">El format %1$s no admet proporcionar el nom de la paleta</string>\n    <string name=\"wallpapers_export_not_avaialbe\">A causa de les polítiques de Play Store, aquesta funció no es pot incloure a la versió actual. Per accedir a aquesta funcionalitat, descarregueu ImageToolbox des d\\'una font alternativa. Podeu trobar les versions disponibles a GitHub a continuació.</string>\n    <string name=\"open_github_page\">Obriu la pàgina de Github</string>\n    <string name=\"overwrite_files_sub_short\">El fitxer original es substituirà per un de nou en lloc de desar-lo a la carpeta seleccionada</string>\n    <string name=\"hidden_watermark_text_detected\">S\\'ha detectat un text de marca d\\'aigua amagat</string>\n    <string name=\"hidden_watermark_image_detected\">S\\'ha detectat una imatge de marca d\\'aigua oculta</string>\n    <string name=\"this_image_was_hidden\">Aquesta imatge estava amagada</string>\n    <string name=\"generative_inpaint\">Inpainting generatiu</string>\n    <string name=\"generative_inpaint_sub\">Us permet eliminar objectes d\\'una imatge mitjançant un model d\\'IA, sense dependre d\\'OpenCV. Per utilitzar aquesta funció, l\\'aplicació baixarà el model necessari (~200 MB) de GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Us permet eliminar objectes d\\'una imatge mitjançant un model d\\'IA, sense dependre d\\'OpenCV. Aquesta pot ser una operació de llarga durada</string>\n    <string name=\"error_level_analysis\">Anàlisi del nivell d\\'error</string>\n    <string name=\"luminance_gradient\">Gradient de lluminància</string>\n    <string name=\"average_distance\">Distància mitjana</string>\n    <string name=\"copy_move_detection\">Detecció de moviment de còpia</string>\n    <string name=\"retain\">Retenir</string>\n    <string name=\"coefficent\">Coeficient</string>\n    <string name=\"clipboard_data_is_too_large\">Les dades del porta-retalls són massa grans</string>\n    <string name=\"data_is_too_large_to_copy\">Les dades són massa grans per copiar-les</string>\n    <string name=\"simple_weave_pixelization\">Pixelització de teixit simple</string>\n    <string name=\"staggered_pixelization\">Pixelització esglaonada</string>\n    <string name=\"cross_pixelization\">Pixelització creuada</string>\n    <string name=\"micro_macro_pixelization\">Micro Macro Pixelització</string>\n    <string name=\"orbital_pixelization\">Pixelització orbital</string>\n    <string name=\"vortex_pixelization\">Pixelització de vòrtex</string>\n    <string name=\"pulse_grid_pixelization\">Pixelització de quadrícula de pols</string>\n    <string name=\"nucleus_pixelization\">Pixelització del nucli</string>\n    <string name=\"radial_weave_pixelization\">Pixelització de teixit radial</string>\n    <string name=\"cannot_open_uri\">No es pot obrir l\\'uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Mode de nevada</string>\n    <string name=\"enabled\">Habilitat</string>\n    <string name=\"border_frame\">Marc de vora</string>\n    <string name=\"glitch_variant\">Variant de Glitch</string>\n    <string name=\"channel_shift\">Canvi de canal</string>\n    <string name=\"max_offset\">Desplaçament màxim</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Block Glitch</string>\n    <string name=\"block_size\">Mida del bloc</string>\n    <string name=\"crt_curvature\">curvatura CRT</string>\n    <string name=\"curvature\">Curvatura</string>\n    <string name=\"chroma\">Croma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Caiguda màxima</string>\n    <string name=\"ai_tools\">Eines d\\'IA</string>\n    <string name=\"ai_tools_sub\">Diverses eines per processar imatges mitjançant models d\\'IA, com l\\'eliminació d\\'artefactes o la eliminació de sorolls</string>\n    <string name=\"model_anime_undeint\">Compressió, línies irregulars</string>\n    <string name=\"model_broadcast\">Dibuixos animats, compressió d\\'emissió</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Compressió general, soroll general</string>\n    <string name=\"model_wb_denoise\">Soroll de dibuixos animats incolors</string>\n    <string name=\"model_span_anime_pretrain\">Ràpid, compressió general, soroll general, animació/cómics/anime</string>\n    <string name=\"model_book_scan\">Escaneig de llibres</string>\n    <string name=\"model_overexposure\">Correcció de l\\'exposició</string>\n    <string name=\"model_fbcnn_color_fp16\">Millor en compressió general, imatges en color</string>\n    <string name=\"model_fbcnn_gray_fp16\">Millor en compressió general, imatges en escala de grisos</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Compressió general, imatges en escala de grisos, més forta</string>\n    <string name=\"model_scunet_color_gan_fp16\">Soroll general, imatges en color</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Soroll general, imatges en color, millors detalls</string>\n    <string name=\"model_scunet_gray_15_fp16\">Soroll general, imatges en escala de grisos</string>\n    <string name=\"model_scunet_gray_25_fp16\">Soroll general, imatges en escala de grisos, més fort</string>\n    <string name=\"model_scunet_gray_50_fp16\">Soroll general, imatges en escala de grisos, més fort</string>\n    <string name=\"model_jpeg_destroyer\">Compressió general</string>\n    <string name=\"model_jaywreck\">Compressió general</string>\n    <string name=\"model_h264\">Texturització, compressió h264</string>\n    <string name=\"model_vhs\">Compressió VHS</string>\n    <string name=\"model_cinepak\">Compressió no estàndard (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Compressió Bink, millor en geometria</string>\n    <string name=\"model_debink_v5\">Compressió Bink, més forta</string>\n    <string name=\"model_debink_v6\">Compressió Bink, suau, conserva el detall</string>\n    <string name=\"model_antialias\">Eliminació de l\\'efecte de l\\'escala, suavització</string>\n    <string name=\"model_kdm_scans\">Art/dibuixos escanejats, compressió suau, moiré</string>\n    <string name=\"model_bandage\">Bandes de color</string>\n    <string name=\"model_halftone\">Lenta, eliminant mitges tintes</string>\n    <string name=\"model_colorizer\">Coloritzador general per a imatges en escala de grisos/bw, per obtenir millors resultats utilitzeu DDColor</string>\n    <string name=\"model_deedge\">Eliminació de vora</string>\n    <string name=\"model_desharpen\">Elimina el sobreafilat</string>\n    <string name=\"model_dither\">Lenta, distorsionada</string>\n    <string name=\"model_gainres\">Anti-aliasing, artefactes generals, CGI</string>\n    <string name=\"model_kdm003_scans\">Processament d\\'exploracions KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Model lleuger de millora de la imatge</string>\n    <string name=\"model_bcgone_detailed_v2\">Eliminació d\\'artefactes de compressió</string>\n    <string name=\"model_bcgone_smooth\">Eliminació d\\'artefactes de compressió</string>\n    <string name=\"model_bandage_smooth\">Eliminació de l\\'embenat amb resultats suaus</string>\n    <string name=\"model_bendel_halftone\">Processament de patrons de mitges tintes</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Eliminació del patró de tramado V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Eliminació d\\'artefactes JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Millora de la textura H.264</string>\n    <string name=\"model_vhs_sharpen\">Afilat i millora de VHS</string>\n    <string name=\"merging\">Fusió</string>\n    <string name=\"chunk_size\">Mida del tros</string>\n    <string name=\"overlap_size\">Mida de superposició</string>\n    <string name=\"note_chunk_info\">Les imatges de més de %1$s px es tallaran i es processaran en trossos, la superposició les combina per evitar costures visibles.</string>\n    <string name=\"large_chunk_warning\">Les mides grans poden causar inestabilitat amb dispositius de gamma baixa</string>\n    <string name=\"select_one_to_start\">Seleccioneu-ne un per començar</string>\n    <string name=\"delete_model_sub\">Voleu suprimir el model %1$s? Haureu de descarregar-lo de nou</string>\n    <string name=\"confirm\">Confirmeu</string>\n    <string name=\"models\">Models</string>\n    <string name=\"downloaded_models\">Models descarregats</string>\n    <string name=\"available_models\">Models disponibles</string>\n    <string name=\"preparing\">Preparant</string>\n    <string name=\"active_model\">Model actiu</string>\n    <string name=\"failed_to_open_session\">No s\\'ha pogut obrir la sessió</string>\n    <string name=\"only_onnx_models\">Només es poden importar models .onnx/.ort</string>\n    <string name=\"import_model\">Model d\\'importació</string>\n    <string name=\"import_model_sub\">Importeu el model onnx personalitzat per a un ús posterior, només s\\'accepten models onnx/ort, admet gairebé totes les variants semblants a esrgan</string>\n    <string name=\"imported_models\">Models importats</string>\n    <string name=\"model_scunet_color_15_fp16\">Soroll general, imatges de colors</string>\n    <string name=\"model_scunet_color_25_fp16\">Soroll general, imatges de colors, més fort</string>\n    <string name=\"model_scunet_color_50_fp16\">Soroll general, imatges de colors, més fort</string>\n    <string name=\"model_artifacts_dithering_alsa\">Redueix els artefactes de tramado i les bandes de color, millorant els degradats suaus i les zones de color planes.</string>\n    <string name=\"model_nmkd_brighten_redux\">Millora la brillantor i el contrast de la imatge amb reflexos equilibrats alhora que preserva els colors naturals.</string>\n    <string name=\"model_nmkd_brighten\">Il·lumina les imatges fosques mantenint els detalls i evitant la sobreexposició.</string>\n    <string name=\"model_nmkd_detoon\">Elimina el to de color excessiu i restableix un equilibri de color més neutre i natural.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Aplica tons de soroll basats en Poisson amb èmfasi en preservar els detalls i les textures.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Aplica un suau to de soroll de Poisson per obtenir resultats visuals més suaus i menys agressius.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Tonificació de soroll uniforme centrada en la preservació dels detalls i la claredat de la imatge.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Tonificació de soroll uniforme suau per a una textura subtil i un aspecte suau.</string>\n    <string name=\"model_repainter\">Repara les zones danyades o irregulars tornant a pintar els artefactes i millorar la consistència de la imatge.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Model de desbandada lleuger que elimina les bandes de color amb un cost de rendiment mínim.</string>\n    <string name=\"model_jpeg_0_20\">Optimitza les imatges amb artefactes de compressió molt alts (0-20% de qualitat) per millorar la claredat.</string>\n    <string name=\"model_jpeg_20_40\">Millora les imatges amb artefactes de compressió alta (20-40% de qualitat), restaurant els detalls i reduint el soroll.</string>\n    <string name=\"model_jpeg_40_60\">Millora les imatges amb una compressió moderada (40-60% de qualitat), equilibrant la nitidesa i la suavitat.</string>\n    <string name=\"model_jpeg_60_80\">Perfecciona les imatges amb una compressió lleugera (60-80% de qualitat) per millorar els detalls i les textures subtils.</string>\n    <string name=\"model_jpeg_80_100\">Millora lleugerament les imatges gairebé sense pèrdues (qualitat del 80-100%) alhora que conserva l\\'aspecte i els detalls naturals.</string>\n    <string name=\"model_spongecolor_lite\">Colorització senzilla i ràpida, dibuixos animats, no ideals</string>\n    <string name=\"model_deblr\">Redueix lleugerament el desenfocament de la imatge, millorant la nitidesa sense introduir artefactes.</string>\n    <string name=\"processing_channel\">Operacions de llarga durada</string>\n    <string name=\"processing_image\">Tractament de la imatge</string>\n    <string name=\"processing\">Tramitació</string>\n    <string name=\"model_artifacts_jpg_0_20\">Elimina els grans artefactes de compressió JPEG en imatges de molt baixa qualitat (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Redueix els forts artefactes JPEG en imatges altament comprimides (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Neteja els artefactes JPEG moderats alhora que conserva els detalls de la imatge (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Refina els artefactes JPEG lleugers en imatges d\\'alta qualitat (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Redueix subtilment els artefactes JPEG menors en imatges gairebé sense pèrdues (80-100%).</string>\n    <string name=\"model_redetail_v2\">Millora els detalls i les textures fins, millorant la nitidesa percebuda sense artefactes pesats.</string>\n    <string name=\"processing_finished\">Processament acabat</string>\n    <string name=\"processing_failed\">Ha fallat el processament</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Millora les textures i els detalls de la pell mantenint un aspecte natural, optimitzat per a la velocitat.</string>\n    <string name=\"model_sbdv_dejpeg\">Elimina els artefactes de compressió JPEG i restaura la qualitat de la imatge de les fotos comprimides.</string>\n    <string name=\"model_iso_denoise_v1\">Redueix el soroll ISO a les fotos fetes en condicions de poca llum, conservant els detalls.</string>\n    <string name=\"model_dejumbo\">Corregeix els reflexos sobreexposats o \\\"jumbo\\\" i restableix un millor equilibri tonal.</string>\n    <string name=\"model_ddcolor_tiny\">Model de coloració lleuger i ràpid que afegeix colors naturals a les imatges en escala de grisos.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Acoloreix</string>\n    <string name=\"type_artifacts\">Artefactes</string>\n    <string name=\"type_enhance\">Millora</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Escaneigs</string>\n    <string name=\"type_upscale\">De luxe</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler per a imatges generals; model petit que utilitza menys GPU i menys temps, amb un desenfocament i un soroll moderats.</string>\n    <string name=\"model_realesrgan_x2plus\">Escalador X2 per a imatges generals, conservant textures i detalls naturals.</string>\n    <string name=\"model_realesrgan_x4plus\">Escalador X4 per a imatges generals amb textures millorades i resultats realistes.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler optimitzat per a imatges d\\'anime; 6 blocs RRDB per a línies i detalls més nítids.</string>\n    <string name=\"model_realesrnet_x4plus\">L\\'escalador X4 amb pèrdua de MSE, produeix resultats més suaus i artefactes reduïts per a imatges generals.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimitzat per a imatges d\\'anime; Variant 4B32F amb detalls més nítids i línies suaus.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Model X4 UltraSharp V2 per a imatges generals; emfatitza la nitidesa i la claredat.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; més ràpid i petit, conserva els detalls mentre utilitza menys memòria GPU.</string>\n    <string name=\"model_rmbg_1_4\">Model lleuger per eliminar ràpidament el fons. Rendiment i precisió equilibrats. Treballa amb retrats, objectes i escenes. Recomanat per a la majoria dels casos d\\'ús.</string>\n    <string name=\"type_removebg\">Eliminar BG</string>\n    <string name=\"horizontal_border_thickness\">Gruix de la vora horitzontal</string>\n    <string name=\"vertical_border_thickness\">Gruix de la vora vertical</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s color</item>\n        <item quantity=\"other\">%1$s colors</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">El model actual no admet la fragmentació, la imatge es processarà a les dimensions originals, això pot provocar un gran consum de memòria i problemes amb els dispositius de gamma baixa</string>\n    <string name=\"chunking_disabled\">La fragmentació està desactivada, la imatge es processarà a les dimensions originals; això pot provocar un gran consum de memòria i problemes amb els dispositius de gamma baixa, però pot donar millors resultats en la inferència.</string>\n    <string name=\"chunking\">En trossos</string>\n    <string name=\"model_u2net\">Model de segmentació d\\'imatges d\\'alta precisió per eliminar fons</string>\n    <string name=\"model_u2netp\">Versió lleugera d\\'U2Net per a una eliminació més ràpida de fons amb un ús de memòria més petit.</string>\n    <string name=\"model_ddcolor\">El model DDColor complet ofereix una coloració d\\'alta qualitat per a imatges generals amb un mínim d\\'artefactes. La millor opció de tots els models de coloració.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Conjunts de dades artístics entrenats i privats; produeix resultats de coloració diversos i artístics amb menys artefactes de color poc realistes.</string>\n    <string name=\"model_birefnet\">Model lleuger BiRefNet basat en Swin Transformer per eliminar amb precisió el fons.</string>\n    <string name=\"model_inspyrenet\">Eliminació de fons d\\'alta qualitat amb vores nítides i excel·lent preservació dels detalls, especialment en objectes complexos i fons complicats.</string>\n    <string name=\"model_isnet\">Model d\\'eliminació de fons que produeix màscares precises amb vores llises, aptes per a objectes generals i conservació moderada dels detalls.</string>\n    <string name=\"model_already_downloaded\">Model ja descarregat</string>\n    <string name=\"model_successfully_imported\">El model s\\'ha importat correctament</string>\n    <string name=\"type\">Tipus</string>\n    <string name=\"keyword\">Paraula clau</string>\n    <string name=\"very_fast\">Molt ràpid</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Lenta</string>\n    <string name=\"very_slow\">Molt Lent</string>\n    <string name=\"compute_percents\">Calcular percentatges</string>\n    <string name=\"minimum_value_is\">El valor mínim és %1$s</string>\n    <string name=\"warp_sub\">Distorsiona la imatge dibuixant amb els dits</string>\n    <string name=\"warp\">Deformació</string>\n    <string name=\"hardness\">Duresa</string>\n    <string name=\"warp_mode\">Mode Warp</string>\n    <string name=\"warp_mode_move\">Mou-te</string>\n    <string name=\"warp_mode_grow\">Créixer</string>\n    <string name=\"warp_mode_shrink\">Encongir-se</string>\n    <string name=\"warp_mode_swirl_cw\">Remolí CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Remolí cap a la dreta</string>\n    <string name=\"fade_strength\">Força d\\'esvaïment</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Gota inferior</string>\n    <string name=\"start_drop\">Inicia Drop</string>\n    <string name=\"end_drop\">Finalitza la caiguda</string>\n    <string name=\"downloading\">Descàrrega</string>\n    <string name=\"smooth_shapes\">Formes llises</string>\n    <string name=\"smooth_shapes_sub\">Utilitzeu superel·lipses en lloc de rectangles arrodonits estàndard per obtenir formes més suaus i naturals</string>\n    <string name=\"shape_type\">Tipus de forma</string>\n    <string name=\"cut\">Tallar</string>\n    <string name=\"rounded\">Arrodonit</string>\n    <string name=\"smooth\">suau</string>\n    <string name=\"cut_shapes_sub\">Vores afilades sense arrodoniments</string>\n    <string name=\"rounded_shapes_sub\">Clàssiques cantonades arrodonides</string>\n    <string name=\"shapes_type\">Tipus de formes</string>\n    <string name=\"corners_size\">Mida de les cantonades</string>\n    <string name=\"squircle\">Esquirol</string>\n    <string name=\"squircle_shapes_sub\">Elements d\\'IU arrodonits elegants</string>\n    <string name=\"filename_format\">Format de nom de fitxer</string>\n    <string name=\"prefix_pattern_description\">Text personalitzat situat al principi del nom del fitxer, perfecte per a noms de projectes, marques o etiquetes personals.</string>\n    <string name=\"original_filename_pattern_description\">Utilitza el nom del fitxer original sense extensió, ajudant-vos a mantenir intacta la identificació de la font.</string>\n    <string name=\"width_pattern_description\">L\\'amplada de la imatge en píxels, útil per fer un seguiment dels canvis de resolució o per escalar els resultats.</string>\n    <string name=\"height_pattern_description\">L\\'alçada de la imatge en píxels, útil quan es treballa amb relacions d\\'aspecte o exportacions.</string>\n    <string name=\"random_numbers_pattern_description\">Genera dígits aleatoris per garantir noms de fitxer únics; afegir més dígits per a més seguretat contra duplicats.</string>\n    <string name=\"sequence_number_pattern_description\">Comptador d\\'increment automàtic per a exportacions per lots, ideal per desar diverses imatges en una sessió.</string>\n    <string name=\"preset_info_pattern_description\">Insereix el nom predefinit aplicat al nom del fitxer perquè pugueu recordar fàcilment com es va processar la imatge.</string>\n    <string name=\"scale_mode_pattern_description\">Mostra el mode d\\'escala de la imatge utilitzat durant el processament, ajudant a distingir les imatges redimensionades, retallades o ajustades.</string>\n    <string name=\"suffix_pattern_description\">Text personalitzat situat al final del nom del fitxer, útil per a versions com _v2, _edited o _final.</string>\n    <string name=\"extension_pattern_description\">L\\'extensió del fitxer (png, jpg, webp, etc.), que coincideix automàticament amb el format desat real.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Una marca de temps personalitzable que us permet definir el vostre propi format mitjançant l\\'especificació de Java per a una ordenació perfecta.</string>\n    <string name=\"fling_type\">Tipus Fling</string>\n    <string name=\"android_native\">Natiu d\\'Android</string>\n    <string name=\"ios_style\">Estil iOS</string>\n    <string name=\"smooth_curve\">Corba suau</string>\n    <string name=\"quick_stop\">Parada ràpida</string>\n    <string name=\"bouncy\">Rebot</string>\n    <string name=\"floaty\">Flotant</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Ultra suau</string>\n    <string name=\"adaptive\">Adaptatiu</string>\n    <string name=\"accessibility_aware\">Conscient de l\\'accessibilitat</string>\n    <string name=\"reduced_motion\">Moviment reduït</string>\n    <string name=\"android_native_sub\">Física de desplaçament nativa d\\'Android</string>\n    <string name=\"smooth_sub\">Desplaçament suau i equilibrat per a ús general</string>\n    <string name=\"ios_style_sub\">Comportament de desplaçament semblant a iOS de major fricció</string>\n    <string name=\"smooth_curve_sub\">Corba spline única per a una sensació de desplaçament diferent</string>\n    <string name=\"quick_stop_sub\">Desplaçament precís amb parada ràpida</string>\n    <string name=\"bouncy_sub\">Desplaçament inflable lúdic i sensible</string>\n    <string name=\"floaty_sub\">Desplaçaments llargs i lliscants per a la navegació de contingut</string>\n    <string name=\"snappy_sub\">Desplaçament ràpid i sensible per a interfícies d\\'usuari interactives</string>\n    <string name=\"ultra_smooth_sub\">Desplaçament suau premium amb impuls estès</string>\n    <string name=\"adaptive_sub\">Ajusta la física en funció de la velocitat de llançament</string>\n    <string name=\"accessibility_aware_sub\">Respecta la configuració d\\'accessibilitat del sistema</string>\n    <string name=\"reduced_motion_sub\">Moviment mínim per a necessitats d\\'accessibilitat</string>\n    <string name=\"primary_lines\">Línies primàries</string>\n    <string name=\"primary_lines_sub\">Afegeix una línia més gruixuda cada cinquena línia</string>\n    <string name=\"fill_color\">Color de farciment</string>\n    <string name=\"hidden_tools\">Eines ocultes</string>\n    <string name=\"hidden_for_share\">Eines amagades per compartir</string>\n    <string name=\"color_library\">Biblioteca de colors</string>\n    <string name=\"color_library_sub\">Exploreu una àmplia col·lecció de colors</string>\n    <string name=\"model_fatality_deblur\">Augmenta i elimina el desenfocament de les imatges mantenint els detalls naturals, ideal per arreglar fotos desenfocades.</string>\n    <string name=\"model_unresize_v3\">Restaura de manera intel·ligent les imatges que s\\'han redimensionat prèviament, recuperant els detalls i les textures perduts.</string>\n    <string name=\"model_liveaction_v1_span\">Optimitzat per a contingut d\\'acció en directe, redueix els artefactes de compressió i millora els detalls detallats en fotogrames de pel·lícules o programes de televisió.</string>\n    <string name=\"model_vhs2hd_realplksr\">Converteix metratges de qualitat VHS a HD, eliminant el soroll de la cinta i millorant la resolució alhora que conserva la sensació vintage.</string>\n    <string name=\"model_text2hd_v1\">Especialitzat per a imatges i captures de pantalla amb un gran nombre de text, aguditza els caràcters i millora la llegibilitat.</string>\n    <string name=\"model_frankendata_pretrainer\">Escala avançada entrenada en diversos conjunts de dades, excel·lent per a la millora de fotografies d\\'ús general.</string>\n    <string name=\"model_realwebphoto_v2\">Optimitzat per a fotos comprimides a la web, elimina els artefactes JPEG i restaura l\\'aspecte natural.</string>\n    <string name=\"model_realwebphoto_v4\">Versió millorada per a fotos web amb una millor preservació de la textura i reducció d\\'artefactes.</string>\n    <string name=\"model_dat_2x\">Ampliació 2x amb tecnologia Dual Aggregation Transformer, manté la nitidesa i els detalls naturals.</string>\n    <string name=\"model_dat_3x\">Ampliació 3x utilitzant una arquitectura de transformador avançada, ideal per a necessitats d\\'ampliació moderades.</string>\n    <string name=\"model_dat_4x\">L\\'augment d\\'alta qualitat 4x amb una xarxa de transformadors d\\'última generació, conserva els detalls fins a escala més gran.</string>\n    <string name=\"model_nafnet_deblurring\">Elimina el borrós/soroll i els tremolors de les fotos. Propòsit general però millor en fotos.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Restaura imatges de baixa qualitat mitjançant el transformador Swin2SR, optimitzat per a la degradació de BSRGAN. Ideal per arreglar artefactes de compressió pesats i millorar els detalls a escala 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Ampliació 4x amb transformador SwinIR entrenat en degradació BSRGAN. Utilitza GAN per obtenir textures més nítides i detalls més naturals en fotos i escenes complexes.</string>\n    <string name=\"path\">Camí</string>\n    <string name=\"merge_pdf\">Combina PDF</string>\n    <string name=\"merge_pdf_sub\">Combina diversos fitxers PDF en un sol document</string>\n    <string name=\"files_order\">Ordre de fitxers</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">PDF dividit</string>\n    <string name=\"split_pdf_sub\">Extreu pàgines específiques del document PDF</string>\n    <string name=\"rotate_pdf\">Gira PDF</string>\n    <string name=\"rotate_pdf_sub\">Corregiu l\\'orientació de la pàgina de manera permanent</string>\n    <string name=\"pages\">Pàgines</string>\n    <string name=\"rearrange_pdf\">Reorganitza el PDF</string>\n    <string name=\"rearrange_pdf_sub\">Arrossegueu i deixeu anar les pàgines per reordenar-les</string>\n    <string name=\"hold_drag_drop\">Mantén premuda i arrossega les pàgines</string>\n    <string name=\"page_numbers\">Números de pàgina</string>\n    <string name=\"page_numbers_sub\">Afegiu numeració als vostres documents automàticament</string>\n    <string name=\"label_format\">Format de l\\'etiqueta</string>\n    <string name=\"pdf_to_text\">PDF a text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extraieu text sense format dels vostres documents PDF</string>\n    <string name=\"watermark_pdf_sub\">Superposeu text personalitzat per a la marca o la seguretat</string>\n    <string name=\"signature\">Signatura</string>\n    <string name=\"signature_sub\">Afegiu la vostra signatura electrònica a qualsevol document</string>\n    <string name=\"will_be_for_signature\">S\\'utilitzarà com a signatura</string>\n    <string name=\"unlock_pdf\">Desbloqueja PDF</string>\n    <string name=\"unlock_pdf_sub\">Elimineu les contrasenyes dels vostres fitxers protegits</string>\n    <string name=\"protect_pdf\">Protegeix PDF</string>\n    <string name=\"protect_pdf_sub\">Protegiu els vostres documents amb un xifratge fort</string>\n    <string name=\"success\">Èxit</string>\n    <string name=\"pdf_unlocked\">PDF desbloquejat, podeu desar-lo o compartir-lo</string>\n    <string name=\"repair_pdf\">Reparar PDF</string>\n    <string name=\"repair_pdf_sub\">Intenteu arreglar documents danyats o il·legibles</string>\n    <string name=\"grayscale\">Escala de grisos</string>\n    <string name=\"grayscale_pdf_sub\">Converteix totes les imatges incrustades del document a escala de grisos</string>\n    <string name=\"compress_pdf\">Comprimir PDF</string>\n    <string name=\"compress_pdf_sub\">Optimitzeu la mida del fitxer del document per compartir-lo més fàcilment</string>\n    <string name=\"repair_info\">ImageToolbox reconstrueix la taula interna de referències creuades i regenera l\\'estructura de fitxers des de zero. Això pot restaurar l\\'accés a molts fitxers que \\\\\"no es poden obrir\\\\\"</string>\n    <string name=\"grayscale_info\">Aquesta eina converteix totes les imatges del document a escala de grisos. El millor per imprimir i reduir la mida del fitxer</string>\n    <string name=\"metadata\">Metadades</string>\n    <string name=\"metadata_pdf_sub\">Editeu les propietats del document per a una millor privadesa</string>\n    <string name=\"tags\">Etiquetes</string>\n    <string name=\"producer\">Productor</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Paraules clau</string>\n    <string name=\"creator\">Creador</string>\n    <string name=\"privacy_deep_clean\">Neteja profunda de privadesa</string>\n    <string name=\"privacy_deep_clean_sub\">Esborra totes les metadades disponibles per a aquest document</string>\n    <string name=\"page\">Pàgina</string>\n    <string name=\"deep_ocr\">OCR profund</string>\n    <string name=\"deep_ocr_sub\">Extraieu text del document i emmagatzemeu-lo en un fitxer de text mitjançant el motor Tesseract</string>\n    <string name=\"cant_remove_all\">No es poden eliminar totes les pàgines</string>\n    <string name=\"remove_pages_pdf\">Elimina les pàgines PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Elimina pàgines específiques del document PDF</string>\n    <string name=\"tap_to_remove\">Toqueu Per eliminar</string>\n    <string name=\"manually\">Manualment</string>\n    <string name=\"crop_pdf\">Retalla PDF</string>\n    <string name=\"crop_pdf_sub\">Retalla les pàgines del document fins a qualsevol límit</string>\n    <string name=\"flatten_pdf\">Aplanar PDF</string>\n    <string name=\"flatten_pdf_sub\">Feu que els PDF no siguin modificables rasteritzant les pàgines del document</string>\n    <string name=\"camera_failed_to_open\">No s\\'ha pogut iniciar la càmera. Comproveu els permisos i assegureu-vos que no l\\'utilitzi una altra aplicació.</string>\n    <string name=\"extract_images\">Extreu Imatges</string>\n    <string name=\"extract_images_sub\">Extraieu imatges incrustades en PDF amb la seva resolució original</string>\n    <string name=\"pdf_no_embedded\">Aquest fitxer PDF no conté cap imatge incrustada</string>\n    <string name=\"extract_images_info\">Aquesta eina escaneja totes les pàgines i recupera imatges d\\'origen de qualitat completa, perfecte per desar originals dels documents</string>\n    <string name=\"draw_signature\">Dibuixa la signatura</string>\n    <string name=\"pen_params\">Params de ploma</string>\n    <string name=\"draw_signature_sub\">Utilitzeu la pròpia signatura com a imatge per col·locar als documents</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Dividiu el document amb un interval donat i empaqueteu nous documents a l\\'arxiu zip</string>\n    <string name=\"interval\">Interval</string>\n    <string name=\"print_pdf\">Imprimeix PDF</string>\n    <string name=\"print_pdf_sub\">Prepareu el document per imprimir amb una mida de pàgina personalitzada</string>\n    <string name=\"pages_per_sheet\">Pàgines per full</string>\n    <string name=\"orientation\">Orientació</string>\n    <string name=\"page_size\">Mida de la pàgina</string>\n    <string name=\"margin\">Marge</string>\n    <string name=\"bloom\">Floreix</string>\n    <string name=\"soft_knee\">Genoll suau</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimitzat per a anime i dibuixos animats. Ampliació ràpida amb colors naturals millorats i menys artefactes</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 estil semblant</string>\n    <string name=\"calculate_hint\">Introduïu aquí símbols matemàtics bàsics per calcular el valor desitjat (p. ex. (5+5)*10)</string>\n    <string name=\"math_expression\">Expressió matemàtica</string>\n    <string name=\"pick_up_to_n_collage_images\">Recolliu fins a %1$s imatges</string>\n    <string name=\"keep_date_time\">Manteniu la data i l\\'hora</string>\n    <string name=\"keep_date_time_sub\">Preserveu sempre les etiquetes exif relacionades amb la data i l\\'hora, funciona independentment de l\\'opció de mantenir l\\'exif</string>\n    <string name=\"background_color_for_alpha_formats\">Color de fons per a formats alfa</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Afegeix la possibilitat d\\'establir el color de fons per a cada format d\\'imatge amb suport alfa, quan està desactivat, només està disponible per als que no són alfa</string>\n    <string name=\"open_markup_project\">Projecte obert</string>\n    <string name=\"open_markup_project_sub\">Continueu editant un projecte de Image Toolbox desat anteriorment</string>\n    <string name=\"markup_project_open_failed\">No es pot obrir el projecte Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Falten dades del projecte al projecte Image Toolbox</string>\n    <string name=\"markup_project_corrupted\">El projecte Image Toolbox està malmès</string>\n    <string name=\"unsupported_markup_project_version\">Versió del projecte Image Toolbox no compatible: %1$d</string>\n    <string name=\"save_markup_project\">Guarda el projecte</string>\n    <string name=\"save_markup_project_sub\">Emmagatzema capes, fons i historial d\\'edició en un fitxer de projecte editable</string>\n    <string name=\"failed_to_open\">No s\\'ha pogut obrir</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Escriu en PDF cercable</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Reconeix el text del lot d\\'imatges i desa PDF cercable amb imatge i capa de text seleccionable</string>\n    <string name=\"layer_alpha\">Capa alfa</string>\n    <string name=\"horizontal_flip\">Flip horitzontal</string>\n    <string name=\"vertical_flip\">Flip vertical</string>\n    <string name=\"lock\">Bloqueig</string>\n    <string name=\"add_shadow\">Afegeix ombra</string>\n    <string name=\"shadow_color\">Color de l\\'ombra</string>\n    <string name=\"text_geometry\">Geometria del text</string>\n    <string name=\"text_geometry_sub\">Estira o inclina el text per a una estilització més nítida</string>\n    <string name=\"scale_x\">Escala X</string>\n    <string name=\"skew_x\">Esbiaix X</string>\n    <string name=\"remove_annotations\">Elimina les anotacions</string>\n    <string name=\"remove_annotations_sub\">Elimina els tipus d\\'anotacions seleccionats, com ara enllaços, comentaris, ressaltats, formes o camps de formulari de les pàgines PDF</string>\n    <string name=\"annotation_link\">Hiperenllaços</string>\n    <string name=\"annotation_file_attachment\">Fitxers adjunts</string>\n    <string name=\"annotation_line\">Línies</string>\n    <string name=\"annotation_popup\">Popups</string>\n    <string name=\"annotation_stamp\">Segells</string>\n    <string name=\"annotation_shapes\">Formes</string>\n    <string name=\"annotation_text\">Notes de text</string>\n    <string name=\"annotation_text_markup\">Marcatge de text</string>\n    <string name=\"annotation_widget\">Camps de formulari</string>\n    <string name=\"annotation_markup\">Marcatge</string>\n    <string name=\"annotation_unknown\">Desconegut</string>\n    <string name=\"annotations\">Anotacions</string>\n    <string name=\"ungroup\">Desagrupar</string>\n    <string name=\"add_shadow_sub\">Afegeix ombra borrosa darrere de la capa amb color i desplaçaments configurables</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-cs/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"prefix\">Předpona</string>\n    <string name=\"smth_went_wrong\">Něco se pokazilo: %1$s</string>\n    <string name=\"size\">Velikost %1$s</string>\n    <string name=\"loading\">Načítání…</string>\n    <string name=\"image_too_large_preview\">Obrázek je pro náhled příliš velký, ale přesto se ho pokusíme uložit.</string>\n    <string name=\"pick_image\">Začněte výběrem obrázku</string>\n    <string name=\"width\">Šířka %1$s</string>\n    <string name=\"height\">Výška %1$s</string>\n    <string name=\"quality\">Kvalita</string>\n    <string name=\"extension\">Rozšíření</string>\n    <string name=\"resize_type\">Způsob změny velikosti</string>\n    <string name=\"explicit\">Explicitní</string>\n    <string name=\"flexible\">Flexibilní</string>\n    <string name=\"pick_image_alt\">Vybrat obrázek</string>\n    <string name=\"app_closing_sub\">Opravdu chcete aplikaci zavřít?</string>\n    <string name=\"app_closing\">Zavření aplikace</string>\n    <string name=\"stay\">Zůstat</string>\n    <string name=\"close\">Zavřít</string>\n    <string name=\"reset_image\">Vrátit změny v obrázku</string>\n    <string name=\"reset_image_sub\">Úpravy obrázku budou vráceny na počáteční hodnoty</string>\n    <string name=\"values_reset\">Hodnoty úspěšně obnoveny</string>\n    <string name=\"reset\">Vrátit změny</string>\n    <string name=\"something_went_wrong\">Něco se pokazilo</string>\n    <string name=\"restart_app\">Restart aplikace</string>\n    <string name=\"copied\">Zkopírováno do schránky</string>\n    <string name=\"exception\">Výjimka</string>\n    <string name=\"edit_exif\">Upravit EXIF</string>\n    <string name=\"ok\">Ok</string>\n    <string name=\"no_exif\">Nebyla nalezena žádná EXIF data</string>\n    <string name=\"add_tag\">Přidat štítek</string>\n    <string name=\"save\">Uložit</string>\n    <string name=\"clear\">Vymazat</string>\n    <string name=\"clear_exif\">Vymazat EXIF data</string>\n    <string name=\"cancel\">Zrušit</string>\n    <string name=\"clear_exif_sub\">Všechna EXIF data obrázku budou vymazána, tuto akci nelze vrátit zpět!</string>\n    <string name=\"presets\">Předvolby</string>\n    <string name=\"crop\">Ořezat</string>\n    <string name=\"image_not_saved\">Ukládání</string>\n    <string name=\"image_not_saved_sub\">Pokud nyní odejdete, všechny neuložené změny budou ztraceny.</string>\n    <string name=\"check_source_code\">Zdrojový kód</string>\n    <string name=\"check_source_code_sub\">Získejte nejnovější aktualizace, diskutujte o problémech a další informace</string>\n    <string name=\"single_edit\">Jednotlivá změna velikosti</string>\n    <string name=\"single_edit_sub\">Změna specifikací jednoho zadaného obrázku</string>\n    <string name=\"pick_color\">Vyberte barvu</string>\n    <string name=\"pick_color_sub\">Výběr barvy z obrázku, kopírování nebo sdílení</string>\n    <string name=\"image\">Obrázek</string>\n    <string name=\"color\">Barva</string>\n    <string name=\"color_copied\">Barva zkopírována</string>\n    <string name=\"crop_sub\">Oříznutí obrázku do libovolných mezí</string>\n    <string name=\"version\">Verze</string>\n    <string name=\"keep_exif\">Ponechat EXIF data</string>\n    <string name=\"images\">Obrázky: %d</string>\n    <string name=\"change_preview\">Náhled úprav</string>\n    <string name=\"remove\">Odebrat</string>\n    <string name=\"palette_sub\">Vytvořit paletu barev ze zadaného obrázku</string>\n    <string name=\"generate_palette\">Vytvoření palety</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"update\">Obnovit</string>\n    <string name=\"new_version\">Nová verze %1$s</string>\n    <string name=\"unsupported_type\">Nepodporovaný typ: %1$s</string>\n    <string name=\"no_palette\">Nelze vytvořit paletu pro daný obrázek</string>\n    <string name=\"original\">Originál</string>\n    <string name=\"folder\">Výstupní složka</string>\n    <string name=\"def\">Výchozí</string>\n    <string name=\"custom\">Vlastní</string>\n    <string name=\"unspecified\">Nespecifikováno</string>\n    <string name=\"device_storage\">Úložiště zařízení</string>\n    <string name=\"by_bytes_resize\">Upravit velikost</string>\n    <string name=\"max_bytes\">Maximální velikost v KB</string>\n    <string name=\"by_bytes_resize_sub\">Upravit velikost obrázku podle zadané velikosti v KB</string>\n    <string name=\"compare\">Porovnat</string>\n    <string name=\"compare_sub\">Porovnání dvou zadaných obrázků</string>\n    <string name=\"pick_two_images\">Začněte výběrem dvou obrázků</string>\n    <string name=\"pick_images\">Vyberte obrázky</string>\n    <string name=\"settings\">Nastavení</string>\n    <string name=\"night_mode\">Noční režim</string>\n    <string name=\"dark\">Tmavý</string>\n    <string name=\"light\">Světlý</string>\n    <string name=\"system\">Systém</string>\n    <string name=\"dynamic_colors\">Dynamické barvy</string>\n    <string name=\"customization\">Přizpůsobení</string>\n    <string name=\"allow_image_monet\">Povolit zpeněžení obrázku</string>\n    <string name=\"allow_image_monet_sub\">Pokud je tato možnost povolena, při výběru obrázku k úpravě se barvy aplikace přizpůsobí tomuto obrázku.</string>\n    <string name=\"language\">Jazyk</string>\n    <string name=\"amoled_mode\">Režim Amoled</string>\n    <string name=\"amoled_mode_sub\">Pokud je povoleno, barva povrchů bude v nočním režimu nastavena na absolutně tmavou.</string>\n    <string name=\"color_scheme\">Barevné schéma</string>\n    <string name=\"color_red\">Červená</string>\n    <string name=\"color_green\">Zelená</string>\n    <string name=\"color_blue\">Modrá</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Vložte platný kód aRGB.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nic k vložení</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Nelze změnit barevné schéma aplikace, když jsou zapnuté dynamické barvy</string>\n    <string name=\"pick_accent_color\">Motiv aplikace bude založen na barvě, kterou si vyberete.</string>\n    <string name=\"about_app\">O aplikaci</string>\n    <string name=\"no_updates\">Nebyly nalezeny žádné aktualizace</string>\n    <string name=\"issue_tracker\">Sledování problémů</string>\n    <string name=\"issue_tracker_sub\">Pošlete sem hlášení o chybách a požadavky na funkce</string>\n    <string name=\"help_translate\">Nápověda k překladu</string>\n    <string name=\"help_translate_sub\">Oprava chyb v překladu nebo lokalizace projektu do jiných jazyků</string>\n    <string name=\"nothing_found_by_search\">Na základě vašeho dotazu nebylo nic nalezeno</string>\n    <string name=\"search_here\">Hledejte zde</string>\n    <string name=\"dynamic_colors_sub\">Pokud je tato možnost povolena, barvy aplikace se přizpůsobí barvám tapety.</string>\n    <string name=\"failed_to_save\">Nepodařilo se uložit obrázek (obrázky) %d</string>\n    <string name=\"primary\">Primární</string>\n    <string name=\"tertiary\">Terciární</string>\n    <string name=\"secondary\">Sekundární</string>\n    <string name=\"border_thickness\">Tloušťka hranic</string>\n    <string name=\"surface\">Povrch</string>\n    <string name=\"values\">Hodnoty</string>\n    <string name=\"add\">Přidat</string>\n    <string name=\"permission\">Povolení</string>\n    <string name=\"grant\">Grant</string>\n    <string name=\"permission_sub\">Aplikace potřebuje přístup k vašemu úložišti, aby mohla ukládat obrázky, je to nezbytné, bez toho nemůže fungovat, takže prosím udělte povolení v dalším dialogu.</string>\n    <string name=\"grant_permission_manual\">Aplikace potřebuje toto oprávnění ke své činnosti, udělte ji prosím ručně.</string>\n    <string name=\"external_storage\">Externí úložiště</string>\n    <string name=\"monet_colors\">Monetovy barvy</string>\n    <string name=\"donation_sub\">Tato aplikace je zcela zdarma, ale pokud chcete podpořit vývoj projektu, můžete kliknout zde.</string>\n    <string name=\"fab_alignment\">Vyrovnání FAB</string>\n    <string name=\"check_updates\">Zkontrolujte aktualizace</string>\n    <string name=\"check_updates_sub\">Pokud je povoleno, zobrazí se po spuštění aplikace dialogové okno pro aktualizaci.</string>\n    <string name=\"zoom\">Zvětšení obrazu</string>\n    <string name=\"share\">Sdílet</string>\n    <string name=\"filename\">Název souboru</string>\n    <string name=\"brightness\">Jas</string>\n    <string name=\"slope\">Sklon</string>\n    <string name=\"sharpen\">Ostřete</string>\n    <string name=\"sepia\">Sépie</string>\n    <string name=\"black_and_white\">Černý a bílý</string>\n    <string name=\"spacing\">Vzdálenost</string>\n    <string name=\"line_width\">Šířka čáry</string>\n    <string name=\"sobel_edge\">Hrana Sobel</string>\n    <string name=\"end\">Konec</string>\n    <string name=\"scale\">Měřítko</string>\n    <string name=\"radius\">Poloměr</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"add_file_size\">Přidejte velikost souboru</string>\n    <string name=\"load_image_from_net\">Načíst obrázek z internetu</string>\n    <string name=\"fit\">Vejít se</string>\n    <string name=\"filters\">Filtry</string>\n    <string name=\"exposure\">Vystavení</string>\n    <string name=\"white_balance\">Vyvážení bílé</string>\n    <string name=\"limits_resize\">Změna velikosti limitů</string>\n    <string name=\"sketch\">Skica</string>\n    <string name=\"threshold\">Práh</string>\n    <string name=\"quantizationLevels\">Kvantizační úrovně</string>\n    <string name=\"smooth_toon\">Hladký toon</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"non_maximum_suppression\">Ne maximální potlačení</string>\n    <string name=\"weak_pixel_inclusion\">Slabé zahrnutí pixelů</string>\n    <string name=\"lookup\">Vzhlédnout</string>\n    <string name=\"luminance_threshold\">Práh svítivosti</string>\n    <string name=\"emoji_sub\">Vyberte, které emotikony se zobrazí na hlavní obrazovce</string>\n    <string name=\"add_file_size_sub\">Pokud je povoleno, přidá šířku a výšku uloženého obrázku k názvu výstupního souboru</string>\n    <string name=\"delete_exif_sub\">Odstraňte metadata EXIF z libovolného páru obrázků</string>\n    <string name=\"image_preview\">Náhled obrázku</string>\n    <string name=\"file_explorer_picker\">Průzkumník souborů</string>\n    <string name=\"photo_picker_sub\">Moderní nástroj pro výběr fotografií Android, který se zobrazuje ve spodní části obrazovky, může fungovat pouze na Androidu 12+ a má také problémy s přijímáním metadat EXIF</string>\n    <string name=\"gallery_picker_sub\">Jednoduchý výběr obrázků galerie, bude fungovat, pouze pokud máte tuto aplikaci</string>\n    <string name=\"file_explorer_picker_sub\">Použijte záměr GetContent k výběru obrázku, funguje všude, ale také může mít problémy s přijímáním vybraných obrázků na některých zařízeních, to není moje chyba</string>\n    <string name=\"options_arrangement\">Uspořádání možností</string>\n    <string name=\"edit\">Upravit</string>\n    <string name=\"order\">Pořadí</string>\n    <string name=\"order_sub\">Určuje pořadí nástrojů na hlavní obrazovce</string>\n    <string name=\"replace_sequence_number\">Nahraďte pořadové číslo</string>\n    <string name=\"replace_sequence_number_sub\">Pokud je povoleno, nahradí standardní časové razítko pořadovým číslem obrázku, pokud používáte dávkové zpracování</string>\n    <string name=\"load_image_from_net_sub\">Načtěte jakýkoli obrázek z internetu, zobrazte jeho náhled, přibližujte jej a také jej uložte nebo upravte, pokud chcete</string>\n    <string name=\"no_image\">Bez obrázku</string>\n    <string name=\"image_link\">Odkaz na obrázek</string>\n    <string name=\"fill\">Vyplnit</string>\n    <string name=\"explicit_description\">Změní velikost obrázků na danou výšku a šířku. Poměr stran obrázků se může změnit.</string>\n    <string name=\"flexible_description\">Změní velikost obrázků na obrázky s dlouhou stranou danou parametrem Width nebo Height, všechny výpočty velikosti budou provedeny po uložení - zachová poměr stran</string>\n    <string name=\"contrast\">Kontrast</string>\n    <string name=\"hue\">Odstín</string>\n    <string name=\"saturation\">Nasycení</string>\n    <string name=\"add_filter\">Přidat filtr</string>\n    <string name=\"filter\">Filtr</string>\n    <string name=\"filter_sub\">Na dané obrázky použijte libovolný řetězec filtrů</string>\n    <string name=\"light_aka_illumination\">Světlo</string>\n    <string name=\"color_filter\">Barevný filtr</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"temperature\">Teplota</string>\n    <string name=\"tint\">Nádech</string>\n    <string name=\"monochrome\">Černobílý</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Světla a stíny</string>\n    <string name=\"highlights\">Zvýraznění</string>\n    <string name=\"shadows\">Stíny</string>\n    <string name=\"haze\">Opar</string>\n    <string name=\"effect\">Účinek</string>\n    <string name=\"distance\">Vzdálenost</string>\n    <string name=\"negative\">Negativní</string>\n    <string name=\"solarize\">Solarizovat</string>\n    <string name=\"vibrance\">Vibrace</string>\n    <string name=\"crosshatch\">Křížový šraf</string>\n    <string name=\"blur\">Rozmazat</string>\n    <string name=\"halftone\">Půltón</string>\n    <string name=\"cga_colorspace\">barevný prostor GCA</string>\n    <string name=\"gaussian_blur\">Gaussovské rozostření</string>\n    <string name=\"box_blur\">Box rozostření</string>\n    <string name=\"bilaterial_blur\">Dvoustranné rozostření</string>\n    <string name=\"emboss\">Vytepat</string>\n    <string name=\"laplacian\">laplacký</string>\n    <string name=\"vignette\">Viněta</string>\n    <string name=\"start\">Start</string>\n    <string name=\"kuwahara\">Kuwahara vyhlazování</string>\n    <string name=\"distortion\">Zkreslení</string>\n    <string name=\"angle\">Úhel</string>\n    <string name=\"swirl\">Vířit se</string>\n    <string name=\"bulge\">Boule</string>\n    <string name=\"dilation\">Dilatace</string>\n    <string name=\"sphere_refraction\">Lom koule</string>\n    <string name=\"refractive_index\">Index lomu</string>\n    <string name=\"glass_sphere_refraction\">Lom skleněné koule</string>\n    <string name=\"color_matrix\">Barevná matrice</string>\n    <string name=\"opacity\">Neprůhlednost</string>\n    <string name=\"limits_resize_sub\">Změňte velikost daných obrázků tak, aby odpovídaly daným limitům šířky a výšky s uložením poměru stran</string>\n    <string name=\"posterize\">Posterizovat</string>\n    <string name=\"stack_blur\">Rozostření zásobníku</string>\n    <string name=\"convolution3x3\">Konvoluce 3x3</string>\n    <string name=\"rgb_filter\">RGB filtr</string>\n    <string name=\"false_color\">Falešná barva</string>\n    <string name=\"first_color\">První barva</string>\n    <string name=\"second_color\">Druhá barva</string>\n    <string name=\"reorder\">Seřadit</string>\n    <string name=\"fast_blur\">Rychlé rozmazání</string>\n    <string name=\"blur_size\">Velikost rozostření</string>\n    <string name=\"blur_center_x\">Rozmazat střed x</string>\n    <string name=\"blur_center_y\">Rozostření středu y</string>\n    <string name=\"zoom_blur\">Zoom rozostření</string>\n    <string name=\"color_balance\">Vyvážení barev</string>\n    <string name=\"delete_exif\">Smazat EXIF</string>\n    <string name=\"image_preview_sub\">Náhled libovolného typu obrázků: GIF, SVG a tak dále</string>\n    <string name=\"image_source\">Zdroj obrázku</string>\n    <string name=\"photo_picker\">Výběr fotografií</string>\n    <string name=\"gallery_picker\">Galerie</string>\n    <string name=\"content_scale\">Obsahové měřítko</string>\n    <string name=\"emojis_count\">Počet emodži</string>\n    <string name=\"add_original_filename_sub\">Pokud je povoleno, přidá původní název souboru do názvu výstupního obrazu</string>\n    <string name=\"sequence_num\">sekvenceNum</string>\n    <string name=\"original_filename\">původní název souboru</string>\n    <string name=\"add_original_filename\">Přidejte původní název souboru</string>\n    <string name=\"filename_not_work_with_photopicker\">Přidání původního názvu souboru nefunguje, pokud je vybrán zdroj obrázku pro výběr fotografií</string>\n    <string name=\"activate_files\">Zakázali jste aplikaci Soubory, aktivujte ji, abyste mohli tuto funkci používat</string>\n    <string name=\"paint_alpha\">Malování alfa</string>\n    <string name=\"draw_on_image\">Nakreslete na obrázek</string>\n    <string name=\"draw\">Kreslit</string>\n    <string name=\"draw_sub\">Nakreslete na obrázek jako ve skicáku nebo nakreslete na samotné pozadí</string>\n    <string name=\"draw_on_image_sub\">Vyberte si obrázek a něco na něj nakreslete</string>\n    <string name=\"draw_on_background\">Kreslit na pozadí</string>\n    <string name=\"encryption\">Šifrování</string>\n    <string name=\"key\">Klíč</string>\n    <string name=\"store_file_desc\">Uložte tento soubor ve svém zařízení nebo jej pomocí akce sdílení umístěte kamkoli chcete</string>\n    <string name=\"implementation\">Implementace</string>\n    <string name=\"compatibility\">Kompatibilita</string>\n    <string name=\"features_sub\">Šifrování souborů na základě hesla. Provedené soubory mohou být uloženy ve vybraném adresáři nebo sdíleny. Dešifrované soubory lze také otevřít přímo.</string>\n    <string name=\"file_size_sub\">Maximální velikost souboru je omezena operačním systémem Android a dostupnou pamětí, což samozřejmě závisí na vašem zařízení. \\nPoznámka: paměť není úložiště.</string>\n    <string name=\"create\">Vytvořit</string>\n    <string name=\"edit_screenshot\">Upravit snímek obrazovky</string>\n    <string name=\"secondary_customization\">Sekundární přizpůsobení</string>\n    <string name=\"file_proceed\">Soubor zpracován</string>\n    <string name=\"invalid_password_or_not_encrypted\">Neplatné heslo nebo vybraný soubor není zašifrován</string>\n    <string name=\"compatibility_sub\">Upozorňujeme, že kompatibilita s jiným softwarem nebo službami pro šifrování souborů není zaručena. Důvodem nekompatibility může být mírně odlišné zpracování klíče nebo konfigurace šifry.</string>\n    <string name=\"screenshot\">Snímek obrazovky</string>\n    <string name=\"fallback_option\">Záložní možnost</string>\n    <string name=\"skip\">Přeskočit</string>\n    <string name=\"decryption\">Dešifrování</string>\n    <string name=\"copy\">kopírovat</string>\n    <string name=\"draw_on_background_sub\">Vyberte barvu pozadí a nakreslete na ni</string>\n    <string name=\"background_color\">Barva pozadí</string>\n    <string name=\"pick_file_to_start\">Začněte výběrem souboru</string>\n    <string name=\"features\">Funkce</string>\n    <string name=\"warning_bytes\">Ukládání v režimu %1$s může být nestabilní, protože se jedná o bezztrátový formát</string>\n    <string name=\"paint_color\">Barva laku</string>\n    <string name=\"cipher\">Šifra</string>\n    <string name=\"cipher_sub\">Šifrujte a dešifrujte jakýkoli soubor (nejen obrázek) na základě šifrovacího algoritmu AES</string>\n    <string name=\"pick_file\">Vybrat soubor</string>\n    <string name=\"encrypt\">Šifrovat</string>\n    <string name=\"decrypt\">Dešifrovat</string>\n    <string name=\"implementation_sub\">AES-256, režim GCM, bez výplně, 12 bajtů náhodných IV. Klíče se používají jako hash SHA-3 (256 bitů).</string>\n    <string name=\"file_size\">Velikost souboru</string>\n    <string name=\"image_size_warning\">Pokus o uložení obrázku s danou šířkou a výškou může způsobit chybu OOM, dělejte to na vlastní riziko a neříkejte, že jsem vás nevaroval!</string>\n    <string name=\"cache\">Mezipaměti</string>\n    <string name=\"cache_size\">Velikost mezipaměti</string>\n    <string name=\"found_s\">Nalezeno %1$s</string>\n    <string name=\"auto_cache_clearing\">Automatické vymazání mezipaměti</string>\n    <string name=\"auto_cache_clearing_sub\">Pokud je povoleno, mezipaměť aplikace se vymaže při spuštění aplikace</string>\n    <string name=\"tools\">Nástroje</string>\n    <string name=\"group_options_by_type\">Seskupit možnosti podle typu</string>\n    <string name=\"group_options_by_type_sub\">Seskupí možnosti na hlavní obrazovce svého typu namísto vlastního uspořádání seznamu</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Nelze změnit uspořádání, když je povoleno seskupování možností</string>\n    <string name=\"saved_to_without_filename\">Uloženo do složky %1$s</string>\n    <string name=\"saved_to\">Uloženo do složky %1$s pod názvem %2$s</string>\n    <string name=\"enhanced_pixelation\">Vylepšená pixelace</string>\n    <string name=\"crop_mask\">Plodinová maska</string>\n    <string name=\"enhanced_glitch\">Vylepšený Glitch</string>\n    <string name=\"channel_shift_x\">Posun kanálu X</string>\n    <string name=\"channel_shift_y\">Posun kanálu Y</string>\n    <string name=\"corruption_size\">Velikost korupce</string>\n    <string name=\"corruption_shift_x\">Korupce Shift X</string>\n    <string name=\"corruption_shift_y\">Korupční posun Y</string>\n    <string name=\"tent_blur\">Rozostření stanu</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">Boční</string>\n    <string name=\"top\">Horní</string>\n    <string name=\"bottom\">Dno</string>\n    <string name=\"auto_erase_background\">Automatické vymazání pozadí</string>\n    <string name=\"randomize_filename\">Randomizujte název souboru</string>\n    <string name=\"travels_and_places\">Cesty a místa</string>\n    <string name=\"allow_betas\">Povolit beta verze</string>\n    <string name=\"segmentation_mode_osd_only\">Orientace &amp; Pouze detekce skriptu</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatická orientace &amp; Detekce skriptu</string>\n    <string name=\"segmentation_mode_auto_only\">Pouze auto</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_word\">Jediné slovo</string>\n    <string name=\"segmentation_mode_circle_word\">Zakroužkujte slovo</string>\n    <string name=\"glitch\">Závada</string>\n    <string name=\"amount\">Množství</string>\n    <string name=\"seed\">Semínko</string>\n    <string name=\"delete_mask_warn\">Chystáte se smazat vybranou masku filtru. Tuto operaci nelze vrátit zpět</string>\n    <string name=\"delete_mask\">Smazat masku</string>\n    <string name=\"no_such_directory\">Nebyl nalezen žádný adresář \\\"%1$s\\\", přepnuli jsme jej na výchozí, uložte prosím soubor znovu</string>\n    <string name=\"clipboard\">Schránka</string>\n    <string name=\"auto_pin\">Automatický pin</string>\n    <string name=\"auto_pin_sub\">Automaticky přidá uložený obrázek do schránky, pokud je povoleno</string>\n    <string name=\"vibration\">Vibrace</string>\n    <string name=\"vibration_strength\">Síla vibrací</string>\n    <string name=\"overwrite_files\">Přepsat soubory</string>\n    <string name=\"empty\">Prázdný</string>\n    <string name=\"suffix\">Přípona</string>\n    <string name=\"search_option\">Vyhledávání</string>\n    <string name=\"free\">Volný, uvolnit</string>\n    <string name=\"images_overwritten\">Obrázky byly přepsány v původním umístění</string>\n    <string name=\"randomize_filename_sub\">Pokud je povoleno, výstupní název souboru bude zcela náhodný</string>\n    <string name=\"image_crop_mask_sub\">Tento typ masky použijte k vytvoření masky z daného obrázku, všimněte si, že BY MĚL mít alfa kanál</string>\n    <string name=\"restore\">Obnovit</string>\n    <string name=\"restore_sub\">Obnovte nastavení aplikace z dříve vygenerovaného souboru</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Poškozený soubor nebo není záloha</string>\n    <string name=\"contact_me\">Kontaktujte mě</string>\n    <string name=\"reset_settings_sub\">Tím se vrátí vaše nastavení na výchozí hodnoty. Všimněte si, že to nelze vrátit zpět bez výše uvedeného záložního souboru.</string>\n    <string name=\"delete\">Vymazat</string>\n    <string name=\"delete_color_scheme_warn\">Chystáte se smazat vybrané barevné schéma. Tuto operaci nelze vrátit zpět</string>\n    <string name=\"delete_color_scheme_title\">Smazat schéma</string>\n    <string name=\"font\">Písmo</string>\n    <string name=\"text\">Text</string>\n    <string name=\"font_scale\">Měřítko písma</string>\n    <string name=\"defaultt\">Výchozí</string>\n    <string name=\"using_large_fonts_warn\">Použití velkých měřítek písem může způsobit závady a problémy uživatelského rozhraní, které nebudou opraveny. Používejte opatrně.</string>\n    <string name=\"alphabet_and_numbers\">Aa Áá Bb Cc Čč Dd Ďď Ee Éé Ěě Ff Gg Hh Ii Íí Jj Kk Ll Mm Nn Ňň Oo Óó Pp Qq Rr Řř Ss Šš Tt Ťť Uu Úú Ůů Vv Ww Xx Yy Zz Žž 0123456789 !?</string>\n    <string name=\"emotions\">Emoce</string>\n    <string name=\"food_and_drink\">Jídlo a pití</string>\n    <string name=\"nature_and_animals\">Příroda a zvířata</string>\n    <string name=\"objects\">Objekty</string>\n    <string name=\"symbols\">Symboly</string>\n    <string name=\"enable_emoji\">Povolit emotikony</string>\n    <string name=\"activities\">Činnosti</string>\n    <string name=\"background_remover\">Odstraňovač pozadí</string>\n    <string name=\"background_remover_sub\">Odstraňte pozadí z obrázku kreslením nebo použijte možnost Auto</string>\n    <string name=\"trim_image\">Oříznout obrázek</string>\n    <string name=\"keep_exif_sub\">Původní metadata obrázku budou zachována</string>\n    <string name=\"restore_background\">Obnovit pozadí</string>\n    <string name=\"something_went_wrong_emphasis\">Jejda… Něco se pokazilo. Můžete mi napsat pomocí níže uvedených možností a já se pokusím najít řešení</string>\n    <string name=\"resize_and_convert_sub\">Změňte velikost daných obrázků nebo je převeďte do jiných formátů. Metadata EXIF lze zde také upravit, pokud vyberete jeden obrázek.</string>\n    <string name=\"crop_description\">Obrázky budou oříznuty na střed na zadanou velikost. Pokud je obrázek menší než zadané rozměry, plátno se roztáhne o danou barvu pozadí.</string>\n    <string name=\"stroke_pixelation\">Pixelace tahu</string>\n    <string name=\"color_to_remove\">Barva k odstranění</string>\n    <string name=\"remove_color\">Odebrat barvu</string>\n    <string name=\"palette_style\">Paletový styl</string>\n    <string name=\"tonal_spot\">Tonální skvrna</string>\n    <string name=\"neutral\">Neutrální</string>\n    <string name=\"vibrant\">Vibrující</string>\n    <string name=\"expressive\">Expresivní</string>\n    <string name=\"rainbow\">Duha</string>\n    <string name=\"fruit_salad\">Ovocný salát</string>\n    <string name=\"fidelity\">Věrnost</string>\n    <string name=\"content\">Obsah</string>\n    <string name=\"tonal_spot_sub\">Výchozí styl palety, umožňuje přizpůsobit všechny čtyři barvy, ostatní umožňují nastavit pouze klíčovou barvu</string>\n    <string name=\"neutral_sub\">Styl, který je o něco více chromatičtější než monochromatický</string>\n    <string name=\"vibrant_sub\">Hlasité téma, barevnost je maximální pro primární paletu, zvýšená pro ostatní</string>\n    <string name=\"playful_scheme\">Hravý motiv – v motivu se neobjevuje zdrojový barevný odstín</string>\n    <string name=\"monochrome_sub\">Jednobarevné téma, barvy jsou čistě černá / bílá / šedá</string>\n    <string name=\"content_sub\">Schéma, které umístí zdrojovou barvu do Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Schéma, které je velmi podobné schématu obsahu</string>\n    <string name=\"search_option_sub\">Umožňuje prohledávat všechny dostupné možnosti na hlavní obrazovce</string>\n    <string name=\"preview_pdf\">Náhled PDF</string>\n    <string name=\"preview_pdf_sub\">Jednoduchý náhled PDF</string>\n    <string name=\"pdf_to_images_sub\">Převeďte PDF na obrázky v daném výstupním formátu</string>\n    <string name=\"images_to_pdf_sub\">Zabalte dané obrázky do výstupního souboru PDF</string>\n    <string name=\"masks\">Masky</string>\n    <string name=\"add_mask\">Přidejte masku</string>\n    <string name=\"mask_indexed\">Maska %d</string>\n    <string name=\"mask_color\">Barva masky</string>\n    <string name=\"mask_preview\">Náhled masky</string>\n    <string name=\"simple_variants\">Jednoduché varianty</string>\n    <string name=\"highlighter\">Zvýrazňovač</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Pero</string>\n    <string name=\"privacy_blur\">Rozmazání soukromí</string>\n    <string name=\"neon_sub\">Přidejte do svých kreseb nějaký zářící efekt</string>\n    <string name=\"pen_sub\">Výchozí, nejjednodušší - jen barva</string>\n    <string name=\"pixelation_sub\">Podobné rozostření soukromí, ale místo rozmazání pixeluje</string>\n    <string name=\"auto_rotate_limits\">Automatické otáčení</string>\n    <string name=\"auto_rotate_limits_sub\">Umožňuje použití limitního rámečku pro orientaci obrázku</string>\n    <string name=\"line_sub\">Nakreslí cestu z počátečního bodu do koncového bodu jako čáru</string>\n    <string name=\"line\">Čára</string>\n    <string name=\"free_drawing_sub\">Nakreslí cestu jako vstupní hodnotu</string>\n    <string name=\"line_arrow_sub\">Nakreslí směřující šipku z počátečního bodu do koncového bodu jako čáru</string>\n    <string name=\"arrow_sub\">Nakreslí ukazující šipku z dané cesty</string>\n    <string name=\"double_line_arrow_sub\">Nakreslí dvojitou šipku z počátečního bodu do koncového bodu jako čáru</string>\n    <string name=\"double_arrow_sub\">Nakreslí dvojitou šipku z dané cesty</string>\n    <string name=\"outlined_oval\">Nastínil Ovál</string>\n    <string name=\"outlined_rect\">Obrys Rect</string>\n    <string name=\"outlined_rect_sub\">Nakreslí obrysový obdélník od počátečního bodu do koncového bodu</string>\n    <string name=\"overwrite_file_requirements\">Chcete-li přepsat soubory, musíte použít zdroj obrázků \\\"Explorer\\\", zkuste obrázky znovu vybrat, zdroj obrázků jsme změnili na potřebný</string>\n    <string name=\"overwrite_files_sub\">Původní soubor bude nahrazen novým souborem namísto uložení do vybrané složky, tato možnost musí být zdrojem obrázku \\\"Explorer\\\" nebo GetContent, při přepnutí se nastaví automaticky</string>\n    <string name=\"hann_sub\">Funkce okna se často používá při zpracování signálu, aby se minimalizoval spektrální únik a zlepšila přesnost frekvenční analýzy zúžením okrajů signálu</string>\n    <string name=\"hermite_sub\">Technika matematické interpolace, která využívá hodnoty a derivace na koncových bodech segmentu křivky k vytvoření hladké a spojité křivky</string>\n    <string name=\"lanczos_sub\">Metoda převzorkování, která zachovává vysoce kvalitní interpolaci aplikací vážené funkce sinc na hodnoty pixelů</string>\n    <string name=\"mitchell_sub\">Metoda převzorkování, která využívá konvoluční filtr s nastavitelnými parametry pro dosažení rovnováhy mezi ostrostí a vyhlazováním v zmenšeném obrázku</string>\n    <string name=\"spline_sub\">Využívá po částech definované polynomiální funkce k hladké interpolaci a aproximaci křivky nebo povrchu, flexibilní a spojité reprezentace tvaru</string>\n    <string name=\"recognize_text\">OCR (rozpoznat text)</string>\n    <string name=\"recognize_text_sub\">Rozpoznejte text z daného obrázku, podporováno více než 120 jazyků</string>\n    <string name=\"picture_has_no_text\">Obrázek neobsahuje žádný text nebo jej aplikace nenašla</string>\n    <string name=\"accuracy\">Přesnost: %1$s</string>\n    <string name=\"recognition_type\">Typ rozpoznávání</string>\n    <string name=\"fast\">Rychle</string>\n    <string name=\"available_languages\">Dostupné jazyky</string>\n    <string name=\"rate_app_sub\">Tato aplikace je zcela zdarma, pokud ji chcete zvětšit, označte prosím projekt hvězdičkou na Github 😄</string>\n    <string name=\"segmentation_mode_single_column\">Jeden sloupec</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Jednoblokový svislý text</string>\n    <string name=\"segmentation_mode_single_block\">Jediný blok</string>\n    <string name=\"segmentation_mode_single_line\">Jediný řádek</string>\n    <string name=\"segmentation_mode_single_char\">Jediný znak</string>\n    <string name=\"segmentation_mode_sparse_text\">Řídký text</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Orientace řídkého textu &amp; Detekce skriptu</string>\n    <string name=\"segmentation_mode_raw_line\">Syrová čára</string>\n    <string name=\"current\">Aktuální</string>\n    <string name=\"all\">Všechno</string>\n    <string name=\"gradient_maker_sub\">Vytvořte přechod dané výstupní velikosti s přizpůsobenými barvami a typem vzhledu</string>\n    <string name=\"add_color\">Přidat barvu</string>\n    <string name=\"properties\">Vlastnosti</string>\n    <string name=\"repeat_watermark_sub\">Opakuje vodoznak přes obrázek místo jednoho na dané pozici</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermark_type\">Typ vodoznaku</string>\n    <string name=\"watermarking_image_sub\">Tento obrázek bude použit jako vzor pro vodoznak</string>\n    <string name=\"text_color\">Barva textu</string>\n    <string name=\"frame_delay\">Frame Delay</string>\n    <string name=\"millis\">milis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"native_stack_blur\">Nativní rozostření zásobníku</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"left_to_right_dithering\">Dithering zleva doprava</string>\n    <string name=\"random_dithering\">Náhodné dithering</string>\n    <string name=\"simple_threshold_dithering\">Jednoduché prahové dithering</string>\n    <string name=\"tilt_shift\">Změna sklonu</string>\n    <string name=\"strength\">Síla</string>\n    <string name=\"fast_bilaterial_blur\">Rychlé dvoustranné rozmazání</string>\n    <string name=\"oil\">Olej</string>\n    <string name=\"frequency_x\">Frekvence X</string>\n    <string name=\"frequency_y\">Frekvence Y</string>\n    <string name=\"amplitude_x\">Amplituda X</string>\n    <string name=\"color_matrix_3x3\">Color Matrix 3x3</string>\n    <string name=\"simple_effects\">Jednoduché efekty</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomálie</string>\n    <string name=\"deutaromaly\">Deutaromálie</string>\n    <string name=\"protonomaly\">Protonomálie</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"deutaronotopia\">Deutaronotopie</string>\n    <string name=\"protanopia\">Protanopie</string>\n    <string name=\"achromatomaly\">Achromatomálie</string>\n    <string name=\"achromatopsia\">Achromatopsie</string>\n    <string name=\"colorful_swirl\">Barevná spirála</string>\n    <string name=\"soft_spring_light\">Měkké jarní světlo</string>\n    <string name=\"autumn_tones\">Podzimní tóny</string>\n    <string name=\"lavender_dream\">Levandulový sen</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Limonádové světlo</string>\n    <string name=\"space_portal\">Vesmírný portál</string>\n    <string name=\"spectral_fire\">Spektrální oheň</string>\n    <string name=\"caramel_darkness\">Karamelová tma</string>\n    <string name=\"futuristic_gradient\">Futuristický přechod</string>\n    <string name=\"deep_purple\">Deep Purple</string>\n    <string name=\"red_swirl\">Červená spirála</string>\n    <string name=\"digital_code\">Digitální kód</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Odříznout</string>\n    <string name=\"uchimura\">Učimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Přechod</string>\n    <string name=\"peak\">Vrchol</string>\n    <string name=\"color_anomaly\">Barevná anomálie</string>\n    <string name=\"cannot_change_image_format\">Nelze změnit formát obrázku, pokud je povolena možnost přepisování souborů</string>\n    <string name=\"emoji_as_color_scheme\">Emoji jako barevné schéma</string>\n    <string name=\"emoji_as_color_scheme_sub\">Používá primární barvu emodži jako barevné schéma aplikace namísto ručně definovaného</string>\n    <string name=\"tg_chat\">Telegramový chat</string>\n    <string name=\"tg_chat_sub\">Diskutujte o aplikaci a získejte zpětnou vazbu od ostatních uživatelů. Můžete zde také získat aktualizace beta verze a statistiky.</string>\n    <string name=\"backup_and_restore\">Zálohování a obnovení</string>\n    <string name=\"settings_restored\">Nastavení byla úspěšně obnovena</string>\n    <string name=\"blur_radius\">Poloměr rozostření</string>\n    <string name=\"draw_mode\">Režim kreslení</string>\n    <string name=\"draw_arrows\">Kreslit šipky</string>\n    <string name=\"enhanced_diamond_pixelation\">Vylepšená diamantová pixelace</string>\n    <string name=\"tolerance\">Tolerance</string>\n    <string name=\"recode\">Překódovat</string>\n    <string name=\"erode\">Erodovat</string>\n    <string name=\"anisotropic_diffusion\">Anizotropní difúze</string>\n    <string name=\"diffusion\">Difúze</string>\n    <string name=\"conduction\">Vedení</string>\n    <string name=\"horizontal_wind_stagger\">Horizontální Wind Stagger</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"aces_hill_tone_mapping\">Mapování horských tónů ACES</string>\n    <string name=\"poisson_blur\">Poissonovo rozostření</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmické mapování tónů</string>\n    <string name=\"crystallize\">Krystalizovat</string>\n    <string name=\"stroke_color\">Barva tahu</string>\n    <string name=\"fractal_glass\">Fraktální sklo</string>\n    <string name=\"amplitude\">Amplituda</string>\n    <string name=\"marble\">Mramor</string>\n    <string name=\"turbulence\">Turbulence</string>\n    <string name=\"water_effect\">Vodní efekt</string>\n    <string name=\"just_size\">Velikost</string>\n    <string name=\"amplitude_y\">Amplituda Y</string>\n    <string name=\"perlin_distortion\">Perlinovo zkreslení</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable filmové mapování tónů</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"delete_language_sub\">Chcete smazat jazyková \\\"%1$s\\\" trénovací data OCR pro všechny typy rozpoznávání, nebo pouze pro vybraný (%2$s)?</string>\n    <string name=\"full_filter\">Plný filtr</string>\n    <string name=\"end_position\">Konec</string>\n    <string name=\"center_position\">Centrum</string>\n    <string name=\"full_filter_sub\">Aplikujte libovolné řetězy filtrů na dané obrázky nebo jeden obrázek</string>\n    <string name=\"pdf_tools_sub\">Práce se soubory PDF: Náhled, převod na dávku obrázků nebo vytvoření jednoho z daných obrázků</string>\n    <string name=\"pdf_to_images\">PDF do obrázků</string>\n    <string name=\"images_to_pdf\">Obrázky do PDF</string>\n    <string name=\"gradient_maker\">Tvůrce přechodů</string>\n    <string name=\"speed\">Rychlost</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"pdf_tools\">Nástroje PDF</string>\n    <string name=\"rate_app\">Ohodnoťte aplikaci</string>\n    <string name=\"rate\">Hodnotit</string>\n    <string name=\"color_matrix_4x4\">Color Matrix 4x4</string>\n    <string name=\"vintage\">Vinobraní</string>\n    <string name=\"night_vision\">Noční vidění</string>\n    <string name=\"warm\">Teplý</string>\n    <string name=\"cool\">Chladný</string>\n    <string name=\"tritanopia\">Tritanopie</string>\n    <string name=\"gradient_type_linear\">Lineární</string>\n    <string name=\"gradient_type_radial\">Radiální</string>\n    <string name=\"gradient_type_sweep\">Zametat</string>\n    <string name=\"gradient_type\">Typ přechodu</string>\n    <string name=\"center_x\">Střed X</string>\n    <string name=\"center_y\">Střed Y</string>\n    <string name=\"tile_mode\">Režim dlaždic</string>\n    <string name=\"tile_mode_repeated\">Opakované</string>\n    <string name=\"tile_mode_mirror\">Zrcadlo</string>\n    <string name=\"tile_mode_clamp\">Svorka</string>\n    <string name=\"tile_mode_decal\">Obtisk</string>\n    <string name=\"color_stops\">Barva se zastaví</string>\n    <string name=\"email\">E-mailem</string>\n    <string name=\"draw_path_mode\">Režim kreslení cesty</string>\n    <string name=\"double_line_arrow\">Šipka dvojité čáry</string>\n    <string name=\"free_drawing\">Kreslení zdarma</string>\n    <string name=\"double_arrow\">Dvojitá šipka</string>\n    <string name=\"line_arrow\">Šipka čáry</string>\n    <string name=\"arrow\">Šipka</string>\n    <string name=\"oval\">Ovál</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Kreslí obdélník od počátečního bodu do koncového bodu</string>\n    <string name=\"oval_sub\">Kreslí ovál od počátečního bodu ke koncovému bodu</string>\n    <string name=\"outlined_oval_sub\">Nakreslí obrysový ovál od počátečního bodu ke koncovému bodu</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizier</string>\n    <string name=\"gray_scale\">Stupnice šedé</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Dvě řady Sierra Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinsonův rozklad</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falešný Floyd Steinberg Dithering</string>\n    <string name=\"max_colors_count\">Maximální počet barev</string>\n    <string name=\"crashlytics_sub\">To aplikaci umožňuje ručně shromažďovat zprávy o selhání</string>\n    <string name=\"mask_preview_sub\">Nakreslená maska filtru bude vykreslena, aby vám ukázala přibližný výsledek</string>\n    <string name=\"scale_mode\">Režim měřítka</string>\n    <string name=\"bilinear\">Bilineární</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Nejbližší</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Základní</string>\n    <string name=\"default_value\">Výchozí hodnota</string>\n    <string name=\"value_in_range\">Hodnota v rozsahu %1$s – %2$s</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Prostorová Sigma</string>\n    <string name=\"median_blur\">Střední rozostření</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bikubický</string>\n    <string name=\"bilinear_sub\">Lineární (nebo bilineární, ve dvou rozměrech) interpolace je obvykle dobrá pro změnu velikosti obrázku, ale způsobuje určité nežádoucí změkčení detailů a může být stále poněkud zubatá.</string>\n    <string name=\"bicubic_sub\">Mezi lepší metody škálování patří Lanczosovo převzorkování a Mitchell-Netravaliho filtry</string>\n    <string name=\"nearest_sub\">Jeden z jednodušších způsobů zvětšení velikosti, nahrazení každého pixelu určitým počtem pixelů stejné barvy</string>\n    <string name=\"basic_sub\">Nejjednodušší režim škálování pro Android, který se používá téměř ve všech aplikacích</string>\n    <string name=\"catmull_sub\">Metoda pro hladkou interpolaci a převzorkování sady řídicích bodů, běžně používaná v počítačové grafice k vytvoření hladkých křivek</string>\n    <string name=\"only_clip\">Pouze klip</string>\n    <string name=\"only_clip_sub\">Ukládání do úložiště se neprovede a obrázek se pokusí vložit pouze do schránky</string>\n    <string name=\"icon_shape_sub\">Přidá kontejner s vybraným tvarem pod úvodní ikony karet</string>\n    <string name=\"icon_shape\">Tvar ikony</string>\n    <string name=\"image_stitching\">Sešívání obrázku</string>\n    <string name=\"image_stitching_sub\">Spojením uvedených obrázků získáte jeden velký</string>\n    <string name=\"brightness_enforcement\">Vynucení jasu</string>\n    <string name=\"screen\">Obrazovka</string>\n    <string name=\"gradient_maker_type_image\">Překrytí přechodem</string>\n    <string name=\"gradient_maker_type_image_sub\">Vytvořte libovolný přechod horní části daného obrázku</string>\n    <string name=\"transformations\">Proměny</string>\n    <string name=\"camera\">Fotoaparát</string>\n    <string name=\"camera_sub\">K pořízení snímku používá fotoaparát, všimněte si, že z tohoto zdroje obrázků je možné získat pouze jeden snímek</string>\n    <string name=\"pick_at_least_two_images\">Vyberte alespoň 2 obrázky</string>\n    <string name=\"output_image_scale\">Výstupní měřítko obrazu</string>\n    <string name=\"image_orientation\">Orientace obrazu</string>\n    <string name=\"horizontal\">Horizontální</string>\n    <string name=\"vertical\">Vertikální</string>\n    <string name=\"scale_small_images_to_large\">Měřítko malých obrázků na velké</string>\n    <string name=\"scale_small_images_to_large_sub\">Pokud je tato možnost povolena, malé obrázky budou zmenšeny na největší v sekvenci</string>\n    <string name=\"images_order\">Pořadí obrázků</string>\n    <string name=\"grain\">Obilí</string>\n    <string name=\"unsharp\">Neostrý</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Orange Haze</string>\n    <string name=\"pink_dream\">Růžový sen</string>\n    <string name=\"golden_hour\">Zlatá hodina</string>\n    <string name=\"hot_summer\">Horké léto</string>\n    <string name=\"purple_mist\">Fialová mlha</string>\n    <string name=\"sunrise\">svítání</string>\n    <string name=\"night_magic\">Noční magie</string>\n    <string name=\"fantasy_landscape\">Fantasy Krajina</string>\n    <string name=\"color_explosion\">Barevná exploze</string>\n    <string name=\"electric_gradient\">Elektrický gradient</string>\n    <string name=\"green_sun\">Zelené slunce</string>\n    <string name=\"rainbow_world\">Duhový svět</string>\n    <string name=\"watermarking\">Vodoznak</string>\n    <string name=\"watermarking_sub\">Zakryjte obrázky přizpůsobitelnými textovými/obrázkovými vodoznaky</string>\n    <string name=\"repeat_watermark\">Opakujte vodoznak</string>\n    <string name=\"offset_x\">Odsazení X</string>\n    <string name=\"overlay_mode\">Režim překrytí</string>\n    <string name=\"pixel_size\">Velikost pixelů</string>\n    <string name=\"lock_draw_orientation\">Zamknout orientaci kreslení</string>\n    <string name=\"lock_draw_orientation_sub\">Pokud je povoleno v režimu kreslení, obrazovka se neotáčí</string>\n    <string name=\"bokeh\">bokeh</string>\n    <string name=\"gif_tools\">Nástroje GIF</string>\n    <string name=\"gif_tools_sub\">Převeďte obrázky na obrázek GIF nebo extrahujte snímky z daného obrázku GIF</string>\n    <string name=\"gif_type_to_image\">GIF k obrázkům</string>\n    <string name=\"gif_type_to_image_sub\">Převeďte soubor GIF na dávku obrázků</string>\n    <string name=\"gif_type_to_gif_sub\">Převeďte dávku obrázků do souboru GIF</string>\n    <string name=\"gif_type_to_gif\">Obrázky do GIF</string>\n    <string name=\"select_gif_image_to_start\">Začněte výběrem obrázku GIF</string>\n    <string name=\"use_size_of_first_frame\">Použijte velikost prvního snímku</string>\n    <string name=\"use_size_of_first_frame_sub\">Nahraďte určenou velikost rozměry prvního rámu</string>\n    <string name=\"repeat_count\">Počet opakování</string>\n    <string name=\"use_lasso\">Použijte laso</string>\n    <string name=\"use_lasso_sub\">K mazání používá laso jako v režimu kreslení</string>\n    <string name=\"original_image_preview_alpha\">Náhled původního obrázku Alpha</string>\n    <string name=\"mask_filter\">Filtr masky</string>\n    <string name=\"mask_filter_sub\">Aplikujte řetězce filtrů na dané maskované oblasti, každá oblast masky si může určit vlastní sadu filtrů</string>\n    <string name=\"random_emojis_sub\">Emoji lišty aplikací se budou průběžně měnit náhodně namísto použití vybraného</string>\n    <string name=\"random_emojis\">Náhodné emotikony</string>\n    <string name=\"random_emojis_error\">Nelze použít náhodný výběr emodži, když jsou emodži vypnuté</string>\n    <string name=\"emoji_selection_error\">Nelze vybrat emotikon, když je aktivován náhodný výběr</string>\n    <string name=\"check_for_updates\">Kontrola aktualizací</string>\n    <string name=\"wait\">Počkejte</string>\n    <string name=\"effort\">Snaha</string>\n    <string name=\"effort_sub\">Hodnota %1$s znamená rychlou kompresi, která má za následek relativně velkou velikost souboru. %2$s znamená pomalejší kompresi, výsledkem je menší soubor.</string>\n    <string name=\"saving_almost_complete\">Ukládání téměř dokončeno. Zrušení nyní bude vyžadovat opětovné uložení.</string>\n    <string name=\"presets_sub_bytes\">Předvolba zde určuje % výstupního souboru, tj. pokud zvolíte předvolbu 50 na 5mb obrázku, získáte po uložení obrázek 2,5mb</string>\n    <string name=\"presets_sub\" formatted=\"false\">Pokud jste vybrali předvolbu 125, obrázek se uloží jako velikost 125 % původního obrázku se 100% kvalitou. Pokud zvolíte předvolbu 50, obrázek se uloží s 50% velikostí a 50% kvalitou.</string>\n    <string name=\"aspect_ratio\">Poměr stran</string>\n    <string name=\"backup\">Záloha</string>\n    <string name=\"backup_sub\">Zálohujte nastavení aplikace do souboru</string>\n    <string name=\"trim_image_sub\">Průhledné prostory kolem obrázku budou oříznuty</string>\n    <string name=\"restore_image\">Obnovit obrázek</string>\n    <string name=\"erase_mode\">Režim mazání</string>\n    <string name=\"erase_background\">Vymazat pozadí</string>\n    <string name=\"pipette\">Pipeta</string>\n    <string name=\"create_issue\">Vytvořit vydání</string>\n    <string name=\"resize_and_convert\">Změnit velikost a převést</string>\n    <string name=\"analytics\">Analytics</string>\n    <string name=\"analytics_sub\">Povolit shromažďování anonymních statistik používání aplikací</string>\n    <string name=\"image_exif_warning\">V současné době formát %1$s umožňuje pouze čtení metadat EXIF v systému Android. Výstupní obrázek po uložení nebude mít vůbec metadata.</string>\n    <string name=\"updates\">Aktualizace</string>\n    <string name=\"allow_betas_sub\">Kontrola aktualizací bude zahrnovat beta verze aplikace, pokud je povolena</string>\n    <string name=\"draw_arrows_sub\">Pokud je povoleno, cesta výkresu bude znázorněna jako ukazující šipka</string>\n    <string name=\"brush_softness\">Měkkost štětce</string>\n    <string name=\"start_position\">Start</string>\n    <string name=\"old_tv\">Stará televize</string>\n    <string name=\"shuffle_blur\">Náhodné rozmazání</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"best\">Nejlepší</string>\n    <string name=\"no_data\">Žádná data</string>\n    <string name=\"download_description\">Pro správné fungování Tesseract OCR je třeba do vašeho zařízení stáhnout další tréninková data (%1$s). \\nChcete stáhnout %2$s data?</string>\n    <string name=\"download\">Stažení</string>\n    <string name=\"no_connection\">Žádné připojení, zkontrolujte jej a zkuste to znovu, abyste si mohli stáhnout modely vlaků</string>\n    <string name=\"downloaded_languages\">Stažené jazyky</string>\n    <string name=\"segmentation_mode\">Režim segmentace</string>\n    <string name=\"restore_background_sub\">Štětec místo mazání obnoví pozadí</string>\n    <string name=\"horizontal_grid\">Horizontální mřížka</string>\n    <string name=\"vertical_grid\">Vertikální mřížka</string>\n    <string name=\"stitch_mode\">Stitch Mode</string>\n    <string name=\"rows_count\">Počet řádků</string>\n    <string name=\"columns_count\">Počet sloupců</string>\n    <string name=\"use_pixel_switch\">Použijte Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Pixel-like switch bude použit místo google materiálu, který jste založili</string>\n    <string name=\"slide\">Skluzavka</string>\n    <string name=\"side_by_side\">Bok po boku</string>\n    <string name=\"toggle_tap\">Přepnout klepnutím</string>\n    <string name=\"transparency\">Průhlednost</string>\n    <string name=\"saved_to_original\">Přepsaný soubor s názvem %1$s v původním umístění</string>\n    <string name=\"magnifier\">Lupa</string>\n    <string name=\"magnifier_sub\">Povolí lupu v horní části prstu v režimech kreslení pro lepší přístupnost</string>\n    <string name=\"force_exif_widget_initial_value\">Vynutit počáteční hodnotu</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Vynutí počáteční kontrolu widgetu exif</string>\n    <string name=\"allow_multiple_languages\">Povolit více jazyků</string>\n    <string name=\"favorite\">Oblíbený</string>\n    <string name=\"no_favorite_filters\">Zatím nebyly přidány žádné oblíbené filtry</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Využívá po částech definované bikubické polynomické funkce k hladké interpolaci a aproximaci křivky nebo povrchu, flexibilní a spojité reprezentace tvaru</string>\n    <string name=\"regular\">Pravidelný</string>\n    <string name=\"blur_edges\">Rozostření okrajů</string>\n    <string name=\"blur_edges_sub\">Nakreslí rozmazané okraje pod původní obrázek, aby se vyplnily mezery kolem něj místo jedné barvy, pokud je povoleno</string>\n    <string name=\"pixelation\">Pixelace</string>\n    <string name=\"inverse_fill_type\">Inverzní typ výplně</string>\n    <string name=\"inverse_fill_type_sub\">Je-li povoleno, budou namísto výchozího chování filtrovány všechny nemaskované oblasti</string>\n    <string name=\"confetti\">Konfety</string>\n    <string name=\"confetti_sub\">Konfety se zobrazí při ukládání, sdílení a dalších primárních akcích</string>\n    <string name=\"secure_mode\">Zabezpečený režim</string>\n    <string name=\"secure_mode_sub\">Skryje obsah při ukončení, obrazovku také nelze zachytit nebo zaznamenat</string>\n    <string name=\"donation\">Dar</string>\n    <string name=\"diamond_pixelation\">Diamantová pixelace</string>\n    <string name=\"circle_pixelation\">Kruhová pixelace</string>\n    <string name=\"enhanced_circle_pixelation\">Vylepšená kruhová pixelace</string>\n    <string name=\"replace_color\">Vyměnit barvu</string>\n    <string name=\"color_to_replace\">Barva k výměně</string>\n    <string name=\"target_color\">Cílová barva</string>\n    <string name=\"highlighter_sub\">Nakreslete poloprůhledné zaostřené dráhy zvýrazňovače</string>\n    <string name=\"privacy_blur_sub\">Rozmaže obraz pod nakreslenou cestou, aby zajistil vše, co chcete skrýt</string>\n    <string name=\"containers_shadow\">Kontejnery</string>\n    <string name=\"containers_shadow_sub\">Umožňuje kreslení stínů za kontejnery</string>\n    <string name=\"sliders_shadow\">Posuvníky</string>\n    <string name=\"switches_shadow\">Přepínače</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">Tlačítka</string>\n    <string name=\"sliders_shadow_sub\">Umožňuje kreslení stínů za posuvníky</string>\n    <string name=\"switches_shadow_sub\">Umožňuje kreslení stínů za přepínači</string>\n    <string name=\"fabs_shadow_sub\">Umožňuje kreslení stínů za plovoucími akčními tlačítky</string>\n    <string name=\"buttons_shadow_sub\">Povolí kreslení stínů za výchozími tlačítky</string>\n    <string name=\"app_bars_shadow\">Lišty aplikací</string>\n    <string name=\"app_bars_shadow_sub\">Umožňuje kreslení stínů za lištami aplikace</string>\n    <string name=\"foss_update_checker_warning\">Tato kontrola aktualizací se připojí ke GitHubu z důvodu kontroly, zda je k dispozici nová aktualizace</string>\n    <string name=\"attention\">Pozornost</string>\n    <string name=\"fading_edges\">Slábnoucí hrany</string>\n    <string name=\"disabled\">Zakázáno</string>\n    <string name=\"both\">Oba</string>\n    <string name=\"invert_colors\">Invertovat barvy</string>\n    <string name=\"invert_colors_sub\">Nahradí barvy motivu negativními, pokud je povoleno</string>\n    <string name=\"exit\">Odejít</string>\n    <string name=\"preview_closing\">Pokud nyní náhled opustíte, budete muset obrázky přidat znovu</string>\n    <string name=\"lasso\">Laso</string>\n    <string name=\"lasso_sub\">Nakreslí uzavřenou vyplněnou cestu danou cestou</string>\n    <string name=\"image_format\">Formát obrázku</string>\n    <string name=\"anaglyph\">Anaglyf</string>\n    <string name=\"noise\">Hluk</string>\n    <string name=\"pixel_sort\">Pixel Sort</string>\n    <string name=\"shuffle\">Zamíchat</string>\n    <string name=\"material_you_sub\">Vytvoří paletu\\\" Material You \\\" z obrázku</string>\n    <string name=\"dark_colors\">Tmavé Barvy</string>\n    <string name=\"dark_colors_sub\">Používá barevné schéma nočního režimu místo světelné varianty</string>\n    <string name=\"copy_as_compose_code\">Kopírovat jako Jetpack Compose code</string>\n    <string name=\"circle_blur\">Rozostření Kruhu</string>\n    <string name=\"star_blur\">Hvězdné Rozostření</string>\n    <string name=\"linear_tilt_shift\">Lineární Posun Náklonu</string>\n    <string name=\"ring_blur\">Rozostření Prstenu</string>\n    <string name=\"cross_blur\">Křížové Rozostření</string>\n    <string name=\"tags_to_remove\">削除するタグ</string>\n    <string name=\"apng_tools\">Nástroje APNG</string>\n    <string name=\"apng_tools_sub\">Převeďte obrázky na obrázek APNG nebo extrahujte snímky z daného obrázku APNG</string>\n    <string name=\"apng_type_to_image\">APNG k obrázkům</string>\n    <string name=\"apng_type_to_image_sub\">Převeďte soubor APNG na dávku obrázků</string>\n    <string name=\"apng_type_to_apng_sub\">Převeďte dávku obrázků do souboru APNG</string>\n    <string name=\"apng_type_to_apng\">Obrázky do APNG</string>\n    <string name=\"select_apng_image_to_start\">Začněte výběrem obrázku APNG</string>\n    <string name=\"motion_blur\">Rozostření pohybu</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Vytvořte soubor Zip z daných souborů nebo obrázků</string>\n    <string name=\"drag_handle_width\">Šířka táhla</string>\n    <string name=\"rain\">Déšť</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Bezztrátový převod z formátu JXL do JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Proveď bezztrátový převod z formátu JPEG do JXL</string>\n    <string name=\"select_jxl_image_to_start\">Začněte výběrem souboru JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL na JPEG</string>\n    <string name=\"jxl_tools\">Nástroje JXL</string>\n    <string name=\"corners\">Rohy</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG na JXL</string>\n    <string name=\"jxl_type_to_jxl\">Obrázky na JXL</string>\n    <string name=\"jxl_tools_sub\">Převod formátu obrázku JXL ~ JPEG bez ztráty kvality nebo převod obrázku GIF/APNG na animaci JXL</string>\n    <string name=\"compression_type\">Druh komprese</string>\n    <string name=\"sorting\">Řazení</string>\n    <string name=\"sort_by_date_reversed\">Řadit podle data (pozpátku)</string>\n    <string name=\"header_today\">Dnes</string>\n    <string name=\"header_yesterday\">Včera</string>\n    <string name=\"auto_paste\">Automatické vložení</string>\n    <string name=\"auto_paste_sub\">Dovolí aplikaci automaticky vložit data, takže se zobrazí na hlavní obrazovce a bude je možno zpracovat</string>\n    <string name=\"gif_type_to_jxl\">GIF na JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Převod obrázků GIF na animované obrázky JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG na JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Převod obrázků APNG na animované obrázky JXL</string>\n    <string name=\"jxl_type_to_images\">JXL na obrázky</string>\n    <string name=\"jxl_type_to_images_sub\">Převod animace JXL na sadu obrázků</string>\n    <string name=\"jxl_type_to_jxl_sub\">Převod sady obrázků na animaci JXL</string>\n    <string name=\"behavior\">Chování</string>\n    <string name=\"skip_file_picking\">Přeskočit výběr obrázku</string>\n    <string name=\"skip_file_picking_sub\">Výběr souborů bude zobrazen okamžitě, pokud je to na vybrané obrazovce možné</string>\n    <string name=\"generate_previews\">Vytvářet náhledy</string>\n    <string name=\"generate_previews_sub\">Povolí vytváření náhledů, toto může na některých zařízeních pomoci předejít pádům a také zakáže některé funkce úprav v rámci jednotlivé možnosti editace.</string>\n    <string name=\"lossy_compression\">Ztrátová komprese</string>\n    <string name=\"lossy_compression_sub\">Používat ztrátovou kompresi ke snížení velikosti místo bezztrátové</string>\n    <string name=\"sort_by_date\">Řadit podle data</string>\n    <string name=\"sort_by_name\">Řadit podle názvu</string>\n    <string name=\"sort_by_name_reversed\">Řadit podle názvu (obráceně)</string>\n    <string name=\"no_permissions\">Žádná oprávnění</string>\n    <string name=\"request\">Požadavek</string>\n    <string name=\"pick_multiple_media\">Vybrat více médií</string>\n    <string name=\"pick\">Vybrat</string>\n    <string name=\"try_again\">Zkusit znovu</string>\n    <string name=\"show_settings_in_landscape\">Zobrazit nastavení na šířku</string>\n    <string name=\"show_settings_in_landscape_sub\">Pokud je toto vypnuto, pak budou v režimu na šířku nastavení jako obvykle otevíraná v tlačítku na horní liště aplikace místo trvale zobrazené volby</string>\n    <string name=\"images_to_svg_sub\">Vykreslení vybraných obrázků do SVG</string>\n    <string name=\"svg_warning\">Použití tohoto nástroje pro vykreslování velkých obrázku bez snížení velikosti není doporučeno, může způsobit pád a prodloužit čas zpracovávání</string>\n    <string name=\"fullscreen_settings\">Možnosti zobrazení na celou obrazovku</string>\n    <string name=\"max\">Max</string>\n    <string name=\"images_to_svg\">Obrázky do SVG</string>\n    <string name=\"path_omit\">Vynechat cestu</string>\n    <string name=\"downscale_image\">Snížit velikost obrázku</string>\n    <string name=\"pick_single_media\">Vybrat jeden mediální soubor</string>\n    <string name=\"tag_compression\">Komprese</string>\n    <string name=\"tag_artist\">Autor</string>\n    <string name=\"add_new_folder\">Vytvořit novou složku</string>\n    <string name=\"tag_x_resolution\">Rozlišení X</string>\n    <string name=\"tag_y_resolution\">Rozlišení Y</string>\n    <string name=\"tag_resolution_unit\">Jednotka rozlišení</string>\n    <string name=\"tag_white_point\">Bílý bod</string>\n    <string name=\"tag_image_description\">Popis obrázku</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_copyright\">Autorská práva</string>\n    <string name=\"tag_exif_version\">Verze Exif</string>\n    <string name=\"tag_flashpix_version\">Verze Flashpix</string>\n    <string name=\"tag_user_comment\">Uživatelský komentář</string>\n    <string name=\"tag_related_sound_file\">Související zvukový soubor</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"channels_configuration\">Konfigurace kanálů</string>\n    <string name=\"embedded_picker\">Vestavěný výběr</string>\n    <string name=\"embedded_picker_sub\">Využívá vlastní výběr z aplikace Image Toolbox namísto předefinovaného ze systému.</string>\n    <string name=\"legacy\">Starší</string>\n    <string name=\"lstm_network\">Síť LSTM</string>\n    <string name=\"legacy_and_lstm\">Starší a LSTM</string>\n    <string name=\"harmonization_color\">Harmonizační barva</string>\n    <string name=\"harmonization_level\">Úroveň harmonizace</string>\n    <string name=\"convert\">Konvertovat</string>\n    <string name=\"speed_sub\">Určuje výslednou rychlost dekódování obrázku, tato funkce může napomoci k rychlejšímu otevření obrázku, hodnota %1$s znamená pomalejší dekódování, kdežto %2$s rychlejší, zároveň může zvětšit velikost výstupního obrázku.</string>\n    <string name=\"reset_properties\">Obnovit výchozí hodnoty nastavení</string>\n    <string name=\"reset_properties_sub\">Všechna nastavení budou obnovena na výchozí hodnoty, uvědomte si, že tato akce nemůže být vrácena zpět</string>\n    <string name=\"fit_to_bounds\">Přizpůsobit hranicím</string>\n    <string name=\"backup_ocr_models\">Zálohovat OCR modely</string>\n    <string name=\"import_word\">Importovat</string>\n    <string name=\"export\">Exportovat</string>\n    <string name=\"position\">Pozice</string>\n    <string name=\"center\">Uprostřed</string>\n    <string name=\"top_left\">Nahoře vlevo</string>\n    <string name=\"top_right\">Nahoře vpravo</string>\n    <string name=\"bottom_left\">Dole vlevo</string>\n    <string name=\"bottom_right\">Dole vpravo</string>\n    <string name=\"top_center\">Nahoře uprostřed</string>\n    <string name=\"center_right\">Uprostřed vpravo</string>\n    <string name=\"bottom_center\">Dole uprostřed</string>\n    <string name=\"target_image\">Cílový obrázek</string>\n    <string name=\"color_tools\">Nástroje barev</string>\n    <string name=\"color_tools_sub\">Míchejte, vytvářejte tóny, generujte odstíny a další</string>\n    <string name=\"color_harmonies\">Barevné harmonie</string>\n    <string name=\"manage_storage_extra_types\">Není dostupný plný přístup k souborům</string>\n    <string name=\"add_timestamp\">Přidat časové razítko</string>\n    <string name=\"add_timestamp_sub\">Povolí vložení časového razítka do názvu výstupního souboru</string>\n    <string name=\"default_draw_color\">Výchozí barva kreslení</string>\n    <string name=\"default_draw_path_mode\">Výchozí mód vykreslení cesty</string>\n    <string name=\"formatted_timestamp\">Formátované časové razítko</string>\n    <string name=\"formatted_timestamp_sub\">Povolit časové razítko v názvu výrobního souboru místo základních milisekund</string>\n    <string name=\"tag_bits_per_sample\">Bitů na vzorek</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrická interpretace</string>\n    <string name=\"tag_samples_per_pixel\">Vzorků na pixel</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr pozicování</string>\n    <string name=\"recently_used\">Posledně použité</string>\n    <string name=\"group\">Skupina</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"collage_maker_sub\">Vytvořte různé koláže ze 20 obrázků</string>\n    <string name=\"collages_info\">Podržením obrázku jej můžete vyměnit, posunem a zvětšením upravit polohu</string>\n    <string name=\"as_file\">Jako soubor</string>\n    <string name=\"save_as_file\">Uložit jako soubor</string>\n    <string name=\"webp_tools_sub\">Převézt obrázky na animovaný obrázek WEBP nebo extrahovat snímky z dané animace WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP na obrázky</string>\n    <string name=\"variation\">Varianty</string>\n    <string name=\"tones\">Tóny</string>\n    <string name=\"tints\">Nádech</string>\n    <string name=\"document_scanner\">Skener dokumentů</string>\n    <string name=\"click_to_start_scanning\">Klikněte pro spuštění skenování</string>\n    <string name=\"start_scanning\">Skenovat</string>\n    <string name=\"save_as_pdf\">Uložit jako PDF</string>\n    <string name=\"share_as_pdf\">Sdílet jako PDF</string>\n    <string name=\"options_below_is_for_images\">Volby níže jsou pro ukládání obrázků, nikoliv pro PDF</string>\n    <string name=\"document_scanner_sub\">Skenovat dokumenty a vytvořit PDF soubor nebo je rozdělit do obrázků</string>\n    <string name=\"switch_type\">Druh prepínače</string>\n    <string name=\"default_line_width\">Výchozí šířka čáry</string>\n    <string name=\"image_splitting\">Rozdělení obrázku</string>\n    <string name=\"image_splitting_sub\">Rozdělit jeden obrázek na části podle řádků nebo sloupců</string>\n    <string name=\"fast_gaussian_blur_2d\">Rychlé 2D gaussovské rozostření</string>\n    <string name=\"fast_gaussian_blur_3d\">Rychlé 3D gaussovské rozostření</string>\n    <string name=\"fast_gaussian_blur_4d\">Rychlé 4D gaussovské rozostření</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">Využívá přepínač ve stylu Windows 11 založený na systémovém vzhledu \\\"Fluent\\\"</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"links_preview\">Náhled odkazů</string>\n    <string name=\"links_preview_sub\">Povolit náhled odkazů na místech, kde můžete získat text ( QR kód, OCR apod.)</string>\n    <string name=\"format_conversion\">Převod formátu</string>\n    <string name=\"format_conversion_sub\">Dávkový převod obrázků z jednoho formátu do jiného</string>\n    <string name=\"resize_anchor\">Změna velikosti ukotvení</string>\n    <string name=\"cupertino_switch_sub\">Využívá přepínač ve stylu iOS založený na systémovém vzhledu Cupertino.</string>\n    <string name=\"downscale_image_sub\">Před spuštěním úprav bude sníženo rozlišení obrázku, aby nástroj mohl pracovat rychleji a bezpečněji.</string>\n    <string name=\"detailed\">Podrobný</string>\n    <string name=\"convert_sub\">Převod dávek obrázků do daného formátu</string>\n    <string name=\"tools_arrangement\">Uspořádání nástrojů</string>\n    <string name=\"group_tools_by_type\">Seskupit nástroje podle typu</string>\n    <string name=\"group_tools_by_type_sub\">Seskupit nástroje na hlavní obrazovce podle jejich typu namísto vlastního uspořádání seznamu</string>\n    <string name=\"default_values\">Výchozí hodnoty</string>\n    <string name=\"system_bars_visibility\">Viditelnost systémových panelů</string>\n    <string name=\"show_system_bars_by_swipe\">Zobrazit systémové panely potažením</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Povolit potažení pro zobrazení systémových panelů, pokud jsou právě skryté.</string>\n    <string name=\"auto\">Automaticky</string>\n    <string name=\"hide_all\">Skrýt všechny</string>\n    <string name=\"show_all\">Zobrazit všechny</string>\n    <string name=\"hide_nav_bar\">Skrýt navigační panel</string>\n    <string name=\"hide_status_bar\">Skrýt stavový panel</string>\n    <string name=\"noise_generation\">Generování šumu</string>\n    <string name=\"noise_generation_sub\">Generovat různé šumy jako Perlinův šum a jiné</string>\n    <string name=\"frequency\">Frekvence</string>\n    <string name=\"noise_type\">Typ šumu</string>\n    <string name=\"rotation_type\">Typ rotace</string>\n    <string name=\"fractal_type\">Typ fraktálu</string>\n    <string name=\"octaves\">Oktávy</string>\n    <string name=\"lacunarity\">Lakunarita</string>\n    <string name=\"custom_filename\">Vlastní název souboru</string>\n    <string name=\"custom_filename_sub\">Vyberte umístění a název pro uložení současného obrázku</string>\n    <string name=\"saved_to_custom\">Uložena složka s vlastním názvem</string>\n    <string name=\"collage_type\">Druh koláže</string>\n    <string name=\"color_shading\">Stínování barev</string>\n    <string name=\"shades\">Odstíny</string>\n    <string name=\"color_mixing\">Míchání barev</string>\n    <string name=\"color_info\">Informace o barvě</string>\n    <string name=\"selected_color\">Vybraná barva</string>\n    <string name=\"color_to_mix\">Barva k míchání</string>\n    <string name=\"manage_storage_extra_types_sub\">Povolte plný přístup k souborům pro zobrazení JXL, QOI a dalších souborů, které nejsou na Androidu rozpoznány jako obrázkové soubory, bez povolení oprávnění nebude možné tyto obrázky zobrazit.</string>\n    <string name=\"center_left\">Uprostřed vlevo</string>\n    <string name=\"min_color_ratio\">Minimální poměr barev</string>\n    <string name=\"lines_threshold\">Práh čar</string>\n    <string name=\"quadratic_threshold\">Kvadratický práh</string>\n    <string name=\"path_scale\">Měřítko cesty</string>\n    <string name=\"webp_tools\">Nástroje pro WEBP</string>\n    <string name=\"webp_type_to_webp\">Obrázky na WEBP</string>\n    <string name=\"select_webp_image_to_start\">Začněte výběrem WEBP obrázku</string>\n    <string name=\"webp_type_to_image_sub\">Převést soubor WEBP na dávku obrázků</string>\n    <string name=\"webp_type_to_webp_sub\">Převést dávku obrázků na WEBP soubor</string>\n    <string name=\"save_as_qr_code_image\">Uložit jako obrázek s QR kódem</string>\n    <string name=\"delete_template\">Smazat šablonu</string>\n    <string name=\"filter_preview\">Náhled filtru</string>\n    <string name=\"qr_code\">QR kód</string>\n    <string name=\"qr_code_sub\">Načíst QR kód a získat jeho obsah nebo vložit vlastní řetězec pro generování nového kódu</string>\n    <string name=\"code_content\">Obsah kódu</string>\n    <string name=\"collage_maker\">Tvorba koláží</string>\n    <string name=\"confetti_type\">Typ konfety</string>\n    <string name=\"festive\">Slavnostní</string>\n    <string name=\"explode\">Explodovat</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Metoda převzorkování, která zachovává vysoce kvalitní interpolaci aplikací Besselovy (jinc) funkce na hodnoty pixelů</string>\n    <string name=\"fullscreen_settings_sub\">Povolte ji a stránka nastavení se vždy otevře jako celá obrazovka, nikoli jako posuvná zásuvka</string>\n    <string name=\"compose\">Komponovat</string>\n    <string name=\"compose_switch_sub\">Materiál pro složení Jetpacku, který přepnete</string>\n    <string name=\"material_you_switch_sub\">Materiál, který vyměníte</string>\n    <string name=\"use_sampled_palette\">Použít paletu vzorků</string>\n    <string name=\"use_sampled_palette_sub\">Pokud je tato možnost povolena, bude vzorkována paleta kvantifikace</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolerance zaokrouhlení souřadnic</string>\n    <string name=\"engine_mode\">Režim motoru</string>\n    <string name=\"tag_planar_configuration\">Planární konfigurace</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Dílčí vzorkování</string>\n    <string name=\"tag_strip_offsets\">Odsazení pásů</string>\n    <string name=\"tag_rows_per_strip\">Řádky na proužek</string>\n    <string name=\"tag_strip_byte_counts\">Počty bajtů stripu</string>\n    <string name=\"tag_jpeg_interchange_format\">Výměnný formát JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Délka výměnného formátu JPEG</string>\n    <string name=\"tag_transfer_function\">Přenosová funkce</string>\n    <string name=\"tag_primary_chromaticities\">Primární barevnost</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr koeficienty</string>\n    <string name=\"tag_reference_black_white\">Referenční černá bílá</string>\n    <string name=\"tag_datetime\">Datum Čas</string>\n    <string name=\"tag_make\">Make</string>\n    <string name=\"tag_color_space\">Barevný prostor</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X rozměr</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel rozměr Y</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Komprimované bity na pixel</string>\n    <string name=\"tag_maker_note\">Poznámka výrobce</string>\n    <string name=\"tag_datetime_original\">Datum Čas Originál</string>\n    <string name=\"tag_datetime_digitized\">Datum Čas Digitalizace</string>\n    <string name=\"tag_offset_time\">Čas offsetu</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Čas posunu Digitalizováno</string>\n    <string name=\"tag_subsec_time\">Čas pod sekundu</string>\n    <string name=\"tag_subsec_time_original\">Čas pod sekundu Originál</string>\n    <string name=\"tag_subsec_time_digitized\">Čas pod sekundu Digitalizováno</string>\n    <string name=\"tag_exposure_time\">Doba vystavení</string>\n    <string name=\"tag_f_number\">Číslo F</string>\n    <string name=\"tag_exposure_program\">Program expozice</string>\n    <string name=\"tag_spectral_sensitivity\">Spektrální citlivost</string>\n    <string name=\"tag_photographic_sensitivity\">Fotografická citlivost</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Typ citlivosti</string>\n    <string name=\"tag_standard_output_sensitivity\">Standardní výstupní citlivost</string>\n    <string name=\"tag_recommended_exposure_index\">Doporučený index expozice</string>\n    <string name=\"tag_iso_speed\">Rychlost ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Rychlost ISO Latitude yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Citlivost ISO Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Hodnota rychlosti závěrky</string>\n    <string name=\"tag_aperture_value\">Hodnota clony</string>\n    <string name=\"tag_brightness_value\">Hodnota jasu</string>\n    <string name=\"tag_exposure_bias_value\">Hodnota zkreslení expozice</string>\n    <string name=\"tag_max_aperture_value\">Maximální hodnota clony</string>\n    <string name=\"tag_subject_distance\">Vzdálenost předmětu</string>\n    <string name=\"tag_metering_mode\">Režim měření</string>\n    <string name=\"tag_flash\">Blikat</string>\n    <string name=\"tag_subject_area\">Předmětová oblast</string>\n    <string name=\"tag_focal_length\">Ohnisková vzdálenost</string>\n    <string name=\"tag_flash_energy\">Energie blesku</string>\n    <string name=\"tag_spatial_frequency_response\">Prostorová frekvenční odezva</string>\n    <string name=\"tag_focal_plane_x_resolution\">Rozlišení ohniskové roviny X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Rozlišení ohniskové roviny Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Jednotka rozlišení ohniskové roviny</string>\n    <string name=\"tag_subject_location\">Umístění předmětu</string>\n    <string name=\"tag_exposure_index\">Index expozice</string>\n    <string name=\"tag_sensing_method\">Metoda snímání</string>\n    <string name=\"tag_file_source\">Zdroj souboru</string>\n    <string name=\"tag_cfa_pattern\">Vzor CFA</string>\n    <string name=\"tag_custom_rendered\">Vlastní vykreslení</string>\n    <string name=\"tag_exposure_mode\">Expoziční režim</string>\n    <string name=\"tag_white_balance\">Vyvážení bílé</string>\n    <string name=\"tag_digital_zoom_ratio\">Poměr digitálního zoomu</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Ohnisková vzdálenost v 35mm filmu</string>\n    <string name=\"tag_scene_capture_type\">Typ zachycení scény</string>\n    <string name=\"tag_gain_control\">Gain Control</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"tag_saturation\">Nasycení</string>\n    <string name=\"tag_sharpness\">Ostrost</string>\n    <string name=\"tag_device_setting_description\">Popis nastavení zařízení</string>\n    <string name=\"tag_subject_distance_range\">Rozsah vzdálenosti předmětu</string>\n    <string name=\"tag_image_unique_id\">Jedinečné ID obrázku</string>\n    <string name=\"tag_camera_owner_name\">Jméno vlastníka fotoaparátu</string>\n    <string name=\"tag_body_serial_number\">Sériové číslo těla</string>\n    <string name=\"tag_lens_specification\">Specifikace objektivu</string>\n    <string name=\"tag_lens_make\">Značka objektivu</string>\n    <string name=\"tag_lens_model\">Model objektivu</string>\n    <string name=\"tag_lens_serial_number\">Sériové číslo objektivu</string>\n    <string name=\"tag_gps_version_id\">ID verze GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Ref. zeměpisná šířka GPS</string>\n    <string name=\"tag_gps_latitude\">Zeměpisná šířka GPS</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Zeměpisná délka Ref</string>\n    <string name=\"tag_gps_longitude\">Zeměpisná délka GPS</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Nadmořská výška Ref</string>\n    <string name=\"tag_gps_altitude\">GPS nadmořská výška</string>\n    <string name=\"tag_gps_timestamp\">GPS časové razítko</string>\n    <string name=\"tag_gps_satellites\">GPS satelity</string>\n    <string name=\"tag_gps_status\">Stav GPS</string>\n    <string name=\"tag_gps_measure_mode\">Režim měření GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Rychlost GPS Ref</string>\n    <string name=\"tag_gps_speed\">Rychlost GPS</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS stopa</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Směr obr. Ref</string>\n    <string name=\"tag_gps_img_direction\">Směr obrazu GPS</string>\n    <string name=\"tag_gps_map_datum\">Datum mapy GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Ref. zeměpisná šířka cíle GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Cílová zeměpisná šířka GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Ref. zeměpisná délka cíle GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Zeměpisná délka cíle GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Cílové ložisko GPS Ref</string>\n    <string name=\"tag_gps_dest_bearing\">Cílové ložisko GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Cílová vzdálenost GPS Ref</string>\n    <string name=\"tag_gps_dest_distance\">Cílová vzdálenost GPS</string>\n    <string name=\"tag_gps_processing_method\">Metoda zpracování GPS</string>\n    <string name=\"tag_gps_area_information\">Informace o oblasti GPS</string>\n    <string name=\"tag_gps_datestamp\">GPS datumovka</string>\n    <string name=\"tag_gps_differential\">Diferenciál GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H Positioning Error</string>\n    <string name=\"tag_interoperability_index\">Index interoperability</string>\n    <string name=\"tag_dng_version\">Verze DNG</string>\n    <string name=\"tag_default_crop_size\">Výchozí velikost oříznutí</string>\n    <string name=\"tag_orf_preview_image_start\">Náhled obrázku Start</string>\n    <string name=\"tag_orf_preview_image_length\">Délka náhledového obrázku</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect Frame</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Spodní okraj snímače</string>\n    <string name=\"tag_rw2_sensor_left_border\">Levý okraj snímače</string>\n    <string name=\"tag_rw2_sensor_right_border\">Pravý okraj snímače</string>\n    <string name=\"tag_rw2_sensor_top_border\">Horní okraj snímače</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Nakreslete text na cestu s daným písmem a barvou</string>\n    <string name=\"font_size\">Velikost písma</string>\n    <string name=\"watermark_size\">Velikost vodoznaku</string>\n    <string name=\"repeat_text\">Opakujte text</string>\n    <string name=\"repeat_text_sub\">Aktuální text se bude místo jednorázového kreslení opakovat až do konce cesty</string>\n    <string name=\"dash_size\">Velikost Dash</string>\n    <string name=\"draw_mode_image_sub\">Použijte vybraný obrázek k jeho nakreslení podél dané cesty</string>\n    <string name=\"draw_image_sub\">Tento obrázek bude použit jako opakující se zadání nakreslené cesty</string>\n    <string name=\"outlined_triangle_sub\">Nakreslí obrysový trojúhelník od počátečního bodu do koncového bodu</string>\n    <string name=\"triangle_sub\">Nakreslí obrysový trojúhelník od počátečního bodu do koncového bodu</string>\n    <string name=\"outlined_triangle\">Nastíněný trojúhelník</string>\n    <string name=\"triangle\">Trojúhelník</string>\n    <string name=\"polygon_sub\">Kreslí mnohoúhelník z počátečního bodu do koncového bodu</string>\n    <string name=\"polygon\">Polygon</string>\n    <string name=\"outlined_polygon\">Obrysový mnohoúhelník</string>\n    <string name=\"outlined_polygon_sub\">Nakreslí obrysový mnohoúhelník od počátečního bodu ke koncovému bodu</string>\n    <string name=\"vertices\">Vrcholy</string>\n    <string name=\"draw_regular_polygon\">Nakreslete pravidelný mnohoúhelník</string>\n    <string name=\"draw_regular_polygon_sub\">Nakreslete mnohoúhelník, který bude pravidelný místo volného tvaru</string>\n    <string name=\"star_sub\">Kreslí hvězdu z počátečního bodu do koncového bodu</string>\n    <string name=\"star\">Hvězda</string>\n    <string name=\"outlined_star\">Nastíněná hvězda</string>\n    <string name=\"outlined_star_sub\">Kreslí obrysovou hvězdu od počátečního bodu do koncového bodu</string>\n    <string name=\"inner_radius_ratio\">Poměr vnitřního poloměru</string>\n    <string name=\"draw_regular_star\">Nakreslete pravidelnou hvězdu</string>\n    <string name=\"draw_regular_star_sub\">Nakreslete hvězdu, která bude pravidelná místo volné formy</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Umožňuje vyhlazování, aby se zabránilo ostrým hranám</string>\n    <string name=\"open_edit_instead_of_preview\">Otevřete Upravit místo náhledu</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Když v ImageToolbox vyberete obrázek k otevření (náhled), otevře se místo náhledu list výběru</string>\n    <string name=\"equalize_histogram_hsv\">Vyrovnat histogram HSV</string>\n    <string name=\"equalize_histogram\">Vyrovnat histogram</string>\n    <string name=\"enter_percentage\">Zadejte procento</string>\n    <string name=\"allow_enter_by_text_field\">Povolit zadávání textovým polem</string>\n    <string name=\"allow_enter_by_text_field_sub\">Povolí textové pole za výběrem předvoleb, abyste je mohli zadávat za běhu</string>\n    <string name=\"scale_color_space\">Měřítko barevného prostoru</string>\n    <string name=\"linear\">Lineární</string>\n    <string name=\"equalize_histogram_pixelation\">Vyrovnat pixelaci histogramu</string>\n    <string name=\"grid_size_x\">Velikost mřížky X</string>\n    <string name=\"grid_size_y\">Velikost mřížky Y</string>\n    <string name=\"equalize_histogram_adaptive\">Equalize Histogram Adaptive</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Vyrovnat histogram Adaptivní LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalize Histogram Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Oříznout na obsah</string>\n    <string name=\"frame_color\">Barva rámu</string>\n    <string name=\"color_to_ignore\">Barva k ignorování</string>\n    <string name=\"template\">Šablona</string>\n    <string name=\"no_template_filters\">Nebyly přidány žádné filtry šablon</string>\n    <string name=\"create_new\">Vytvořit nový</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Naskenovaný QR kód není platnou šablonou filtru</string>\n    <string name=\"scan_qr_code\">Naskenujte QR kód</string>\n    <string name=\"opened_file_have_no_filter_template\">Vybraný soubor neobsahuje žádná data šablony filtru</string>\n    <string name=\"create_template\">Vytvořit šablonu</string>\n    <string name=\"template_name\">Název šablony</string>\n    <string name=\"select_template_preview\">Tento obrázek bude použit k náhledu této šablony filtru</string>\n    <string name=\"template_filter\">Filtr šablony</string>\n    <string name=\"as_qr_code\">Jako obrázek s QR kódem</string>\n    <string name=\"delete_template_warn\">Chystáte se smazat vybraný filtr šablony. Tuto operaci nelze vrátit zpět</string>\n    <string name=\"added_filter_template\">Byla přidána šablona filtru s názvem  \\\"%1$s \\\" (%2$s)</string>\n    <string name=\"scan_qr_code_to_replace_content\">Naskenujte libovolný čárový kód, abyste nahradili obsah v poli, nebo něco napište a vygenerujte nový čárový kód s vybraným typem</string>\n    <string name=\"qr_description\">Popis QR</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">V nastavení udělte fotoaparátu oprávnění ke skenování QR kódu</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">V nastavení udělte fotoaparátu oprávnění ke skenování skeneru dokumentů</string>\n    <string name=\"cubic\">Krychlový</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussův</string>\n    <string name=\"sphinx\">Sfinga</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Krabice</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kubická interpolace poskytuje plynulejší škálování tím, že bere v úvahu nejbližších 16 pixelů, což poskytuje lepší výsledky než bilineární</string>\n    <string name=\"bspline_sub\">Využívá po částech definované polynomiální funkce k hladké interpolaci a aproximaci křivky nebo povrchu, flexibilní a spojité reprezentace tvaru</string>\n    <string name=\"hamming_sub\">Funkce okna používaná ke snížení spektrálního úniku zúžením hran signálu, užitečná při zpracování signálu</string>\n    <string name=\"hanning_sub\">Varianta Hannova okna, běžně používaná ke snížení spektrálního úniku v aplikacích zpracování signálu</string>\n    <string name=\"blackman_sub\">Funkce okna, která poskytuje dobré frekvenční rozlišení minimalizací spektrálního úniku, často používaná při zpracování signálu</string>\n    <string name=\"welch_sub\">Funkce okna navržená tak, aby poskytovala dobré frekvenční rozlišení se sníženým spektrálním únikem, často používaná v aplikacích zpracování signálu</string>\n    <string name=\"quadric_sub\">Metoda, která využívá kvadratickou funkci pro interpolaci a poskytuje hladké a spojité výsledky</string>\n    <string name=\"gaussian_sub\">Interpolační metoda, která aplikuje Gaussovu funkci, užitečnou pro vyhlazení a redukci šumu v obrazech</string>\n    <string name=\"sphinx_sub\">Pokročilá metoda převzorkování poskytující vysoce kvalitní interpolaci s minimem artefaktů</string>\n    <string name=\"bartlett_sub\">Funkce trojúhelníkového okna používaná při zpracování signálu ke snížení spektrálního úniku</string>\n    <string name=\"robidoux_sub\">Vysoce kvalitní metoda interpolace optimalizovaná pro přirozenou změnu velikosti obrazu, vyvážení ostrosti a plynulosti</string>\n    <string name=\"robidoux_sharp_sub\">Ostřejší varianta metody Robidoux, optimalizovaná pro ostré změny velikosti obrazu</string>\n    <string name=\"spline16_sub\">Metoda interpolace založená na spline, která poskytuje hladké výsledky pomocí filtru s 16 klepnutími</string>\n    <string name=\"spline36_sub\">Metoda interpolace založená na spline, která poskytuje hladké výsledky pomocí filtru s 36 klepnutími</string>\n    <string name=\"spline64_sub\">Metoda interpolace založená na spline, která poskytuje hladké výsledky pomocí filtru s 64 klepnutími</string>\n    <string name=\"kaiser_sub\">Interpolační metoda, která využívá okno Kaiser, poskytuje dobrou kontrolu nad kompromisem mezi šířkou hlavního laloku a úrovní postranního laloku</string>\n    <string name=\"bartlett_hann_sub\">Hybridní funkce okna kombinující okna Bartlett a Hann, která se používá ke snížení spektrálního úniku při zpracování signálu</string>\n    <string name=\"box_sub\">Jednoduchá metoda převzorkování, která používá průměr nejbližších hodnot pixelů, což často vede k hranatému vzhledu</string>\n    <string name=\"bohman_sub\">Funkce okna používaná ke snížení spektrálního úniku, poskytující dobré frekvenční rozlišení v aplikacích zpracování signálu</string>\n    <string name=\"lanczos2_sub\">Metoda převzorkování, která využívá 2-lalokový Lanczosův filtr pro vysoce kvalitní interpolaci s minimem artefaktů</string>\n    <string name=\"lanczos3_sub\">Metoda převzorkování, která využívá 3-lalokový Lanczosův filtr pro vysoce kvalitní interpolaci s minimem artefaktů</string>\n    <string name=\"lanczos4_sub\">Metoda převzorkování, která využívá 4-lalokový Lanczosův filtr pro vysoce kvalitní interpolaci s minimem artefaktů</string>\n    <string name=\"lanczos2_jinc_sub\">Varianta filtru Lanczos 2, která využívá funkci jinc a poskytuje vysoce kvalitní interpolaci s minimálními artefakty</string>\n    <string name=\"lanczos3_jinc_sub\">Varianta filtru Lanczos 3, která využívá funkci jinc a poskytuje vysoce kvalitní interpolaci s minimálními artefakty</string>\n    <string name=\"lanczos4_jinc_sub\">Varianta filtru Lanczos 4, která využívá funkci jinc a poskytuje vysoce kvalitní interpolaci s minimálními artefakty</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Varianta eliptického váženého průměru (EWA) Hanningova filtru pro hladkou interpolaci a převzorkování</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Varianta eliptického váženého průměru (EWA) filtru Robidoux pro vysoce kvalitní převzorkování</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Varianta eliptického váženého průměru (EWA) filtru Blackman pro minimalizaci artefaktů zvonění</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Varianta eliptického váženého průměru (EWA) filtru Quadric pro hladkou interpolaci</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Varianta eliptického váženého průměru (EWA) filtru Robidoux Sharp pro ostřejší výsledky</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Varianta eliptického váženého průměru (EWA) filtru Lanczos 3 Jinc pro vysoce kvalitní převzorkování s redukovaným aliasingem</string>\n    <string name=\"ginseng\">Ženšen</string>\n    <string name=\"ginseng_sub\">Převzorkovací filtr určený pro vysoce kvalitní zpracování obrazu s dobrým vyvážením ostrosti a plynulosti</string>\n    <string name=\"ewa_ginseng\">Ženšen EWA</string>\n    <string name=\"ewa_ginseng_sub\">Varianta eliptického váženého průměru (EWA) ženšenového filtru pro lepší kvalitu obrazu</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Varianta eliptického váženého průměru (EWA) Lanczos Sharp filtru pro dosažení ostrých výsledků s minimem artefaktů</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 nejostřejší EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Varianta eliptického váženého průměru (EWA) filtru Lanczos 4 Sharpest pro extrémně ostré převzorkování obrazu</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptical Weighted Average (EWA) varianta Lanczos Soft filtru pro plynulejší převzorkování obrazu</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Převzorkovací filtr navržený Haasnem pro plynulé škálování obrazu bez artefaktů</string>\n    <string name=\"dismiss_forever\">Odmítnout navždy</string>\n    <string name=\"image_stacking\">Stohování obrázků</string>\n    <string name=\"image_stacking_sub\">Skládejte obrázky na sebe s vybranými režimy prolnutí</string>\n    <string name=\"add_image\">Přidat obrázek</string>\n    <string name=\"bins_count\">Koše se počítají</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Equalize Histogram Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Equalize Histogram Adaptive HSV</string>\n    <string name=\"edge_mode\">Režim okraje</string>\n    <string name=\"clip\">Klip</string>\n    <string name=\"wrap\">Zabalit</string>\n    <string name=\"color_blind_scheme\">Barevná slepota</string>\n    <string name=\"color_blind_scheme_sub\">Vyberte režim pro přizpůsobení barev motivu pro vybranou variantu barvosleposti</string>\n    <string name=\"protanomaly_sub\">Obtížné rozlišení mezi červenými a zelenými odstíny</string>\n    <string name=\"deuteranomaly_sub\">Obtížné rozlišení mezi zeleným a červeným odstínem</string>\n    <string name=\"tritanomaly_sub\">Obtížné rozlišení mezi modrými a žlutými odstíny</string>\n    <string name=\"protanopia_sub\">Neschopnost vnímat červené odstíny</string>\n    <string name=\"deuteranopia_sub\">Neschopnost vnímat zelené odstíny</string>\n    <string name=\"tritanopia_sub\">Neschopnost vnímat modré odstíny</string>\n    <string name=\"achromatomaly_sub\">Snížená citlivost na všechny barvy</string>\n    <string name=\"achromatopsia_sub\">Úplná barvoslepost, vidět pouze odstíny šedi</string>\n    <string name=\"not_use_color_blind_scheme\">Nepoužívejte schéma Color Blind</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Barvy budou přesně takové, jaké jsou nastaveny v motivu</string>\n    <string name=\"sigmoidal\">Sigmoidální</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Lagrangeův interpolační filtr řádu 2, vhodný pro vysoce kvalitní škálování obrazu s plynulými přechody</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Lagrangeův interpolační filtr řádu 3, který nabízí lepší přesnost a hladší výsledky pro změnu měřítka obrazu</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Lanczosův převzorkovací filtr s vyšším řádem 6, který poskytuje ostřejší a přesnější měřítko obrazu</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Varianta filtru Lanczos 6 využívající funkci Jinc pro lepší kvalitu převzorkování obrazu</string>\n    <string name=\"linear_box_blur\">Lineární rámeček rozostření</string>\n    <string name=\"linear_tent_blur\">Lineární rozostření stanu</string>\n    <string name=\"linear_gaussian_box_blur\">Lineární Gaussův Box Blur</string>\n    <string name=\"linear_stack_blur\">Lineární rozostření zásobníku</string>\n    <string name=\"gaussian_box_blur\">Rozostření Gaussova pole</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lineární rychlé Gaussovské rozostření Další</string>\n    <string name=\"linear_fast_gaussian_blur\">Lineární rychlé Gaussovské rozostření</string>\n    <string name=\"linear_gaussian_blur\">Lineární gaussovské rozostření</string>\n    <string name=\"draw_filter_sub\">Vyberte jeden filtr, který chcete použít jako barvu</string>\n    <string name=\"replace_filter\">Vyměňte filtr</string>\n    <string name=\"pick_filter_info\">Vyberte filtr níže a použijte jej jako štětec ve výkresu</string>\n    <string name=\"tiff_compression_scheme\">Schéma komprese TIFF</string>\n    <string name=\"low_poly\">Low Poly</string>\n    <string name=\"sand_painting\">Pískové malování</string>\n    <string name=\"fit_to_bounds_sub\">Zkombinujte režim změny velikosti oříznutí s tímto parametrem, abyste dosáhli požadovaného chování (oříznutí/přizpůsobení poměru stran)</string>\n    <string name=\"languages_imported\">Jazyky byly úspěšně importovány</string>\n    <string name=\"palette_transfer\">Přenos palety</string>\n    <string name=\"enhanced_oil\">Vylepšený olej</string>\n    <string name=\"simple_old_tv\">Jednoduchá stará televize</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Jednoduchá skica</string>\n    <string name=\"soft_glow\">Měkká záře</string>\n    <string name=\"color_poster\">Barevný plakát</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Třetí barva</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Klára Olchová</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Clustered 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Clustered 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">Clustered 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Nejsou vybrány žádné oblíbené možnosti, přidejte je na stránce nástrojů</string>\n    <string name=\"add_favorites\">Přidat oblíbené</string>\n    <string name=\"harmony_complementary\">Komplementární</string>\n    <string name=\"harmony_analogous\">Analogický</string>\n    <string name=\"harmony_triadic\">Triadický</string>\n    <string name=\"harmony_split_complementary\">Rozdělení komplementární</string>\n    <string name=\"harmony_tetradic\">Tetradický</string>\n    <string name=\"harmony_square\">Náměstí</string>\n    <string name=\"harmony_analogous_complementary\">Analogové + doplňkové</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Při zapnutých dynamických barvách nelze použít monet</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Cílový obrázek LUT</string>\n    <string name=\"amatorka\">Amatér</string>\n    <string name=\"miss_etikate\">Slečno Etiketa</string>\n    <string name=\"soft_elegance\">Měkká elegance</string>\n    <string name=\"soft_elegance_variant\">Varianta Soft Elegance</string>\n    <string name=\"palette_transfer_variant\">Paletová přenosová varianta</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Cílový soubor 3D LUT (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Světlo svíček</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Nervózní Amber</string>\n    <string name=\"fall_colors\">Podzimní barvy</string>\n    <string name=\"film_stock_50\">Filmový sklad 50</string>\n    <string name=\"foggy_night\">Mlhavá noc</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Získejte neutrální obrázek LUT</string>\n    <string name=\"save_empty_lut_sub\">Nejprve pomocí své oblíbené aplikace pro úpravu fotografií aplikujte filtr na neutrální LUT, který můžete získat zde. Aby to fungovalo správně, barva každého pixelu nesmí záviset na jiných pixelech (např. nebude fungovat rozostření). Jakmile budete připraveni, použijte svůj nový obrázek LUT jako vstup pro filtr 512*512 LUT</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celuloid</string>\n    <string name=\"coffee\">Káva</string>\n    <string name=\"golden_forest\">Zlatý les</string>\n    <string name=\"greenish\">Nazelenalý</string>\n    <string name=\"retro_yellow\">Retro žlutá</string>\n    <string name=\"links\">Odkazy</string>\n    <string name=\"ico_size_warning\">Soubory ICO lze uložit pouze v maximální velikosti 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF na WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Převeďte obrázky GIF na animované obrázky WEBP</string>\n    <string name=\"enable_timestamps_to_format_them\">Povolením časových razítek vyberte jejich formát</string>\n    <string name=\"one_time_save_location\">Místo pro jednorázové uložení</string>\n    <string name=\"one_time_save_location_sub\">Zobrazit a upravit umístění jednorázového uložení, které můžete použít dlouhým stisknutím tlačítka uložit ve většině možností</string>\n    <string name=\"ci_channel\">CI kanál</string>\n    <string name=\"image_toolbox_in_telegram\">Image Toolbox v Telegramu 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Připojte se k našemu chatu, kde můžete diskutovat o čemkoli, co chcete, a také se podívat na kanál CI, kde zveřejňuji beta verze a oznámení</string>\n    <string name=\"ci_channel_sub\">Získejte upozornění na nové verze aplikace a přečtěte si oznámení</string>\n    <string name=\"fit_description\">Přizpůsobte obrázek daným rozměrům a použijte rozostření nebo barvu na pozadí</string>\n    <string name=\"gain\">Získat</string>\n    <string name=\"weighted_strength\">Vážená síla</string>\n    <string name=\"ping_pong_strength\">Síla ping pongu</string>\n    <string name=\"distance_function\">Funkce vzdálenosti</string>\n    <string name=\"return_type\">Typ návratu</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Pokřivení domény</string>\n    <string name=\"alignment\">Zarovnání</string>\n    <string name=\"disable_rotation\">Zakázat otáčení</string>\n    <string name=\"disable_rotation_sub\">Zabraňuje otáčení obrázků pomocí gest dvěma prsty</string>\n    <string name=\"enable_snapping_to_borders\">Povolit přichycení k okrajům</string>\n    <string name=\"enable_snapping_to_borders_sub\">Po přesunutí nebo přiblížení se obrázky přichytí k vyplnění okrajů rámečku</string>\n    <string name=\"histogram_sub\">Histogram obrazu RGB nebo jasu, který vám pomůže provést úpravy</string>\n    <string name=\"image_for_histogram\">Tento obrázek bude použit ke generování histogramů RGB a jasu</string>\n    <string name=\"tesseract_options\">Možnosti Tesseractu</string>\n    <string name=\"tesseract_options_sub\">Použijte některé vstupní proměnné pro engine tesseract</string>\n    <string name=\"custom_options\">Vlastní možnosti</string>\n    <string name=\"custom_params_info\">Možnosti je třeba zadat podle tohoto vzoru:  \\\"--{název_možnosti} {hodnota} \\\"</string>\n    <string name=\"auto_crop\">Automatické oříznutí</string>\n    <string name=\"free_corners\">Volné rohy</string>\n    <string name=\"free_corners_sub\">Oříznout obrázek podle mnohoúhelníku, to také opraví perspektivu</string>\n    <string name=\"coerce_points_to_image_bounds\">Vynucené body na hranice obrázku</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Body nebudou omezeny hranicemi obrazu, což je užitečné pro přesnější korekci perspektivy</string>\n    <string name=\"mask\">Maska</string>\n    <string name=\"spot_heal_sub\">Výplň pod nakreslenou cestou podle obsahu</string>\n    <string name=\"spot_heal\">Heal Spot</string>\n    <string name=\"use_circle_kernel\">Použijte kruhové jádro</string>\n    <string name=\"opening\">Otevírací</string>\n    <string name=\"closing\">Zavírání</string>\n    <string name=\"morphological_gradient\">Morfologický gradient</string>\n    <string name=\"top_hat\">Cylindr</string>\n    <string name=\"black_hat\">Černý klobouk</string>\n    <string name=\"tone_curves\">Tónové křivky</string>\n    <string name=\"reset_curves\">Resetovat křivky</string>\n    <string name=\"reset_curves_sub\">Křivky budou vráceny zpět na výchozí hodnotu</string>\n    <string name=\"line_style\">Styl čáry</string>\n    <string name=\"gap_size\">Velikost mezery</string>\n    <string name=\"dashed\">čárkovaná</string>\n    <string name=\"dot_dashed\">Přerušovaná tečka</string>\n    <string name=\"stamped\">Vyraženo</string>\n    <string name=\"zigzag\">Cikcak</string>\n    <string name=\"dashed_sub\">Nakreslí přerušovanou čáru podél nakreslené cesty se zadanou velikostí mezery</string>\n    <string name=\"dot_dashed_sub\">Nakreslí tečku a přerušovanou čáru podél dané cesty</string>\n    <string name=\"defaultt_sub\">Pouze výchozí rovné čáry</string>\n    <string name=\"stamped_sub\">Nakreslí vybrané tvary podél cesty se zadaným rozestupem</string>\n    <string name=\"zigzag_sub\">Kreslí vlnitá klikatá podél cesty</string>\n    <string name=\"zigzag_ratio\">Cikcak poměr</string>\n    <string name=\"create_shortcut\">Vytvořit zástupce</string>\n    <string name=\"create_shortcut_title\">Vyberte nástroj, který chcete připnout</string>\n    <string name=\"create_shortcut_subtitle\">Nástroj bude přidán na domovskou obrazovku vašeho spouštěče jako zkratka, použijte jej v kombinaci s nastavením  \\\"Přeskočit výběr souboru \\\", abyste dosáhli potřebného chování</string>\n    <string name=\"dont_stack_frames\">Neskládejte rámečky</string>\n    <string name=\"dont_stack_frames_sub\">Umožňuje likvidaci předchozích snímků, takže se nebudou skládat na sebe</string>\n    <string name=\"crossfade\">Prolínání</string>\n    <string name=\"crossfade_sub\">Rámy budou vzájemně prolínány</string>\n    <string name=\"crossfade_count\">Počet snímků prolínání</string>\n    <string name=\"threshold_one\">Práh jedna</string>\n    <string name=\"threshold_two\">Práh dva</string>\n    <string name=\"canny\">Mazaný</string>\n    <string name=\"mirror_101\">Zrcadlo 101</string>\n    <string name=\"enhanced_zoom_blur\">Vylepšené rozostření přiblížením</string>\n    <string name=\"laplacian_simple\">Laplacký jednoduchý</string>\n    <string name=\"sobel_simple\">Sobel Jednoduché</string>\n    <string name=\"helper_grid\">Pomocná mřížka</string>\n    <string name=\"helper_grid_sub\">Zobrazuje podpůrnou mřížku nad oblastí kreslení, která pomáhá s přesnými manipulacemi</string>\n    <string name=\"grid_color\">Barva mřížky</string>\n    <string name=\"cell_width\">Šířka buňky</string>\n    <string name=\"cell_height\">Výška buňky</string>\n    <string name=\"compact_selectors\">Kompaktní selektory</string>\n    <string name=\"compact_selectors_sub\">Některé ovládací prvky výběru budou používat kompaktní rozvržení, aby zabraly méně místa</string>\n    <string name=\"grant_camera_permission_to_capture_image\">V nastavení udělte fotoaparátu oprávnění k pořízení snímku</string>\n    <string name=\"layout\">Rozložení</string>\n    <string name=\"main_screen_title\">Titulek hlavní obrazovky</string>\n    <string name=\"constant_rate_factor\">Konstantní rychlostní faktor (CRF)</string>\n    <string name=\"crf_sub\">Hodnota %1$s znamená pomalou kompresi, což má za následek relativně malou velikost souboru. %2$s znamená rychlejší kompresi, výsledkem je velký soubor.</string>\n    <string name=\"lut_library\">Knihovna Lut</string>\n    <string name=\"lut_library_sub\">Stáhněte si kolekci LUT, kterou můžete použít po stažení</string>\n    <string name=\"lut_library_update_sub\">Aktualizujte kolekci LUT (pouze nové budou zařazeny do fronty), kterou můžete použít po stažení</string>\n    <string name=\"filter_preview_image_sub\">Změnit výchozí náhled obrázku pro filtry</string>\n    <string name=\"filter_preview_image\">Náhledový obrázek</string>\n    <string name=\"hide\">Skrýt</string>\n    <string name=\"show\">Show</string>\n    <string name=\"slider_type\">Typ posuvníku</string>\n    <string name=\"fancy\">Fantazie</string>\n    <string name=\"material_2\">Materiál 2</string>\n    <string name=\"fancy_sub\">Efektně vypadající slider. Toto je výchozí možnost</string>\n    <string name=\"material_2_sub\">Posuvník Materiál 2</string>\n    <string name=\"material_you_slider_sub\">Posuvník Material You</string>\n    <string name=\"apply\">Použít</string>\n    <string name=\"center_align_dialog_buttons\">Středová tlačítka dialogu</string>\n    <string name=\"center_align_dialog_buttons_sub\">Tlačítka dialogů budou pokud možno umístěna uprostřed místo na levé straně</string>\n    <string name=\"open_source_licenses\">Open Source licence</string>\n    <string name=\"open_source_licenses_sub\">Zobrazit licence knihoven s otevřeným zdrojovým kódem používaných v této aplikaci</string>\n    <string name=\"area\">Plocha</string>\n    <string name=\"area_sub\">Převzorkování pomocí vztahu plochy pixelů. Může to být preferovaná metoda pro decimaci obrazu, protože poskytuje výsledky bez moaré. Ale když je obrázek přiblížený, je to podobné jako u metody  \\\"Nejbližší \\\".</string>\n    <string name=\"enable_tonemapping\">Povolit mapování tónů</string>\n    <string name=\"enter_percent\">Zadejte %</string>\n    <string name=\"unknown_host\">Nelze získat přístup k webu, zkuste použít VPN nebo zkontrolujte, zda je adresa URL správná</string>\n    <string name=\"markup_layers\">Značkovací vrstvy</string>\n    <string name=\"markup_layers_sub\">Režim vrstev s možností libovolně umísťovat obrázky, text a další</string>\n    <string name=\"edit_layer\">Upravit vrstvu</string>\n    <string name=\"layers_on_image\">Vrstvy na obrázku</string>\n    <string name=\"layers_on_image_sub\">Použijte obrázek jako pozadí a přidejte na něj různé vrstvy</string>\n    <string name=\"layers_on_background\">Vrstvy na pozadí</string>\n    <string name=\"layers_on_background_sub\">Stejné jako u první možnosti, ale s barvou místo obrázku</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Strana rychlého nastavení</string>\n    <string name=\"fast_settings_side_sub\">Při úpravě obrázků přidejte na vybranou stranu plovoucí pruh, který po kliknutí otevře rychlé nastavení</string>\n    <string name=\"clear_selection\">Jasný výběr</string>\n    <string name=\"settings_group_visibility_hidden\">Skupina nastavení  \\\"%1$s \\\" bude ve výchozím nastavení sbalená</string>\n    <string name=\"settings_group_visibility_visible\">Skupina nastavení  \\\"%1$s \\\" bude ve výchozím nastavení rozbalena</string>\n    <string name=\"base_64_tools\">Nástroje Base64</string>\n    <string name=\"base_64_tools_sub\">Dekódujte řetězec Base64 na obrázek nebo zakódujte obrázek do formátu Base64</string>\n    <string name=\"base_64\">Základní 64</string>\n    <string name=\"not_a_valid_base_64\">Zadaná hodnota není platný řetězec Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">Nelze zkopírovat prázdný nebo neplatný řetězec Base64</string>\n    <string name=\"paste_base_64\">Vložit Base64</string>\n    <string name=\"copy_base_64\">Kopírovat Base64</string>\n    <string name=\"base_64_tips\">Načtěte obrázek pro zkopírování nebo uložení řetězce Base64. Pokud máte samotný řetězec, můžete jej vložit výše a získat obrázek</string>\n    <string name=\"save_base_64\">Uložit Base64</string>\n    <string name=\"share_base_64\">Share Base64</string>\n    <string name=\"options\">Možnosti</string>\n    <string name=\"actions\">Akce</string>\n    <string name=\"import_base_64\">Import Base64</string>\n    <string name=\"base_64_actions\">Akce Base64</string>\n    <string name=\"add_outline\">Přidat obrys</string>\n    <string name=\"add_outline_sub\">Přidejte obrys kolem textu se zadanou barvou a šířkou</string>\n    <string name=\"outline_color\">Barva obrysu</string>\n    <string name=\"outline_size\">Velikost obrysu</string>\n    <string name=\"rotation\">Otáčení</string>\n    <string name=\"checksum_as_filename\">Kontrolní součet jako název souboru</string>\n    <string name=\"checksum_as_filename_sub\">Výstupní obrázky budou mít název odpovídající jejich datovému kontrolnímu součtu</string>\n    <string name=\"free_software_partner\">Svobodný software (partner)</string>\n    <string name=\"free_software_partner_sub\">Užitečnější software v partnerském kanálu aplikací pro Android</string>\n    <string name=\"algorithms\">Algoritmus</string>\n    <string name=\"checksum_tools\">Nástroje kontrolního součtu</string>\n    <string name=\"checksum_tools_sub\">Porovnejte kontrolní součty, vypočítejte hash nebo vytvořte hex řetězce ze souborů pomocí různých hashovacích algoritmů</string>\n    <string name=\"calculate\">Vypočítat</string>\n    <string name=\"text_hash\">Textový hash</string>\n    <string name=\"checksum\">Kontrolní součet</string>\n    <string name=\"pick_file_to_checksum\">Vyberte soubor pro výpočet jeho kontrolního součtu na základě zvoleného algoritmu</string>\n    <string name=\"enter_text_to_checksum\">Zadejte text pro výpočet jeho kontrolního součtu na základě vybraného algoritmu</string>\n    <string name=\"source_checksum\">Kontrolní součet zdroje</string>\n    <string name=\"checksum_to_compare\">Kontrolní součet k porovnání</string>\n    <string name=\"match\">Zápas!</string>\n    <string name=\"difference\">Rozdíl</string>\n    <string name=\"match_sub\">Kontrolní součty jsou stejné, může to být bezpečné</string>\n    <string name=\"difference_sub\">Kontrolní součty nejsou stejné, soubor může být nebezpečný!</string>\n    <string name=\"mesh_gradients\">Síťové přechody</string>\n    <string name=\"collection_mesh_gradients_sub\">Podívejte se na online kolekci síťových přechodů</string>\n    <string name=\"wrong_font\">Importovat lze pouze písma TTF a OTF</string>\n    <string name=\"import_font\">Importovat písmo (TTF/OTF)</string>\n    <string name=\"export_fonts\">Exportujte písma</string>\n    <string name=\"imported_fonts\">Importovaná písma</string>\n    <string name=\"error_while_saving\">Chyba při pokusu o uložení, zkuste změnit výstupní složku</string>\n    <string name=\"filename_is_not_set\">Název souboru není nastaven</string>\n    <string name=\"none\">Žádný</string>\n    <string name=\"custom_pages\">Vlastní stránky</string>\n    <string name=\"pages_selection\">Výběr stránek</string>\n    <string name=\"tool_exit_confirmation\">Potvrzení ukončení nástroje</string>\n    <string name=\"tool_exit_confirmation_sub\">Pokud máte při používání určitých nástrojů neuložené změny a pokusíte se je zavřít, zobrazí se dialog pro potvrzení</string>\n    <string name=\"edit_exif_screen\">Upravit EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Změňte metadata jednoho obrázku bez rekomprese</string>\n    <string name=\"edit_exif_tag\">Klepnutím upravíte dostupné značky</string>\n    <string name=\"change_sticker\">Změnit nálepku</string>\n    <string name=\"fit_width\">Přizpůsobit šířku</string>\n    <string name=\"fit_height\">Přizpůsobit výšku</string>\n    <string name=\"batch_compare\">Dávkové porovnání</string>\n    <string name=\"pick_files_to_checksum\">Vyberte soubor/soubory pro výpočet jejich kontrolního součtu na základě zvoleného algoritmu</string>\n    <string name=\"pick_files\">Vyberte Soubory</string>\n    <string name=\"pick_directory\">Vyberte adresář</string>\n    <string name=\"head_length_scale\">Měřítko délky hlavy</string>\n    <string name=\"stamp\">Razítko</string>\n    <string name=\"timestamp\">Časové razítko</string>\n    <string name=\"format_pattern\">Formát vzor</string>\n    <string name=\"padding\">Vycpávka</string>\n    <string name=\"image_cutting\">Řezání obrazu</string>\n    <string name=\"image_cutting_sub\">Vyřízněte část obrázku a slučte levé (může být inverzní) svislými nebo vodorovnými čarami</string>\n    <string name=\"vertical_pivot_line\">Vertikální otočná čára</string>\n    <string name=\"horizontal_pivot_line\">Horizontální otočná čára</string>\n    <string name=\"inverse_selection\">Inverzní výběr</string>\n    <string name=\"inverse_vertical_selection_sub\">Svislá část řezu bude ponechána, místo sloučení částí kolem oblasti řezu</string>\n    <string name=\"inverse_horizontal_selection_sub\">Vodorovná část řezu bude ponechána namísto sloučení částí kolem oblasti řezu</string>\n    <string name=\"collection_mesh_gradients\">Kolekce síťových přechodů</string>\n    <string name=\"mesh_gradients_sub\">Vytvořte síťový gradient s vlastním množstvím uzlů a rozlišením</string>\n    <string name=\"gradient_maker_type_image_mesh\">Překrytí síťovým přechodem</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Vytvořte síťový gradient horní části daných obrázků</string>\n    <string name=\"points_customization\">Přizpůsobení bodů</string>\n    <string name=\"grid_size\">Velikost mřížky</string>\n    <string name=\"resolution_x\">Rozlišení X</string>\n    <string name=\"resolution_y\">Rozlišení Y</string>\n    <string name=\"resolution\">Rezoluce</string>\n    <string name=\"pixel_by_pixel\">Pixel za pixelem</string>\n    <string name=\"highlight_color\">Barva zvýraznění</string>\n    <string name=\"pixel_comparison_type\">Typ porovnání pixelů</string>\n    <string name=\"scan_barcode\">Naskenujte čárový kód</string>\n    <string name=\"height_ratio\">Výškový poměr</string>\n    <string name=\"barcode_type\">Typ čárového kódu</string>\n    <string name=\"enforce_bw\">Vynutit B/W</string>\n    <string name=\"enforce_bw_sub\">Obrázek čárového kódu bude plně černobílý a nebude zbarven podle motivu aplikace</string>\n    <string name=\"barcodes_sub\">Naskenujte libovolný čárový kód (QR, EAN, AZTEC, …) a získejte jeho obsah nebo vložte svůj text a vygenerujte nový</string>\n    <string name=\"no_barcode_found\">Nebyl nalezen žádný čárový kód</string>\n    <string name=\"generated_barcode_will_be_here\">Generovaný čárový kód zde bude</string>\n    <string name=\"audio_cover_extractor\">Audio kryty</string>\n    <string name=\"audio_cover_extractor_sub\">Extrahujte obrázky obalu alba ze zvukových souborů, většina běžných formátů je podporována</string>\n    <string name=\"pick_audio_to_start\">Začněte výběrem zvuku</string>\n    <string name=\"pick_audio\">Vyberte Zvuk</string>\n    <string name=\"no_covers_found\">Nebyly nalezeny žádné kryty</string>\n    <string name=\"send_logs\">Odeslat protokoly</string>\n    <string name=\"send_logs_sub\">Kliknutím sdílejte soubor protokolů aplikace, může mi to pomoci odhalit problém a vyřešit problémy</string>\n    <string name=\"crash_title\">Jejda… Něco se pokazilo</string>\n    <string name=\"crash_subtitle\">Můžete mě kontaktovat pomocí níže uvedených možností a já se pokusím najít řešení.\\n(Nezapomeňte připojit protokoly)</string>\n    <string name=\"ocr_write_to_file\">Zápis do souboru</string>\n    <string name=\"ocr_write_to_file_sub\">Extrahujte text z dávky obrázků a uložte jej do jednoho textového souboru</string>\n    <string name=\"ocr_write_to_metadata\">Zápis do metadat</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extrahujte text z každého obrázku a umístěte jej do EXIF ​​informací o relativních fotografiích</string>\n    <string name=\"invisible_mode\">Neviditelný režim</string>\n    <string name=\"invisible_mode_sub\">Použijte steganografii k vytvoření okem neviditelných vodoznaků uvnitř bajtů vašich obrázků</string>\n    <string name=\"use_lsb\">Použijte LSB</string>\n    <string name=\"use_lsb_sub\">Bude použita steganografická metoda LSB (Less Significant Bit), jinak FD (Frequency Domain).</string>\n    <string name=\"auto_remove_red_eyes\">Automatické odstranění červených očí</string>\n    <string name=\"password\">Heslo</string>\n    <string name=\"unlock\">Odemknout</string>\n    <string name=\"pdf_is_protected\">PDF je chráněno</string>\n    <string name=\"operation_almost_complete\">Operace téměř dokončena. Zrušení nyní bude vyžadovat restartování</string>\n    <string name=\"sort_by_date_modified\">Datum změny</string>\n    <string name=\"sort_by_date_modified_reversed\">Datum změny (obráceno)</string>\n    <string name=\"sort_by_size\">Velikost</string>\n    <string name=\"sort_by_size_reversed\">Velikost (obrácená)</string>\n    <string name=\"sort_by_mime_type\">Typ MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Typ MIME (obrácený)</string>\n    <string name=\"sort_by_extension\">Rozšíření</string>\n    <string name=\"sort_by_extension_reversed\">Rozšíření (obráceno)</string>\n    <string name=\"sort_by_date_added\">Datum přidání</string>\n    <string name=\"sort_by_date_added_reversed\">Datum přidání (obráceno)</string>\n    <string name=\"left_to_right\">Zleva doprava</string>\n    <string name=\"right_to_left\">Zprava doleva</string>\n    <string name=\"top_to_bottom\">Shora dolů</string>\n    <string name=\"bottom_to_top\">Zespodu nahoru</string>\n    <string name=\"liquid_glass\">Tekuté sklo</string>\n    <string name=\"liquid_glass_sub\">Přepínač založený na nedávno oznámeném IOS 26 a jeho designovém systému tekutého skla</string>\n    <string name=\"pick_image_or_base64\">Níže vyberte obrázek nebo vložte/importujte data Base64</string>\n    <string name=\"type_image_link\">Začněte zadáním odkazu na obrázek</string>\n    <string name=\"paste_link\">Vložit odkaz</string>\n    <string name=\"kaleidoscope\">Kaleidoskop</string>\n    <string name=\"secondary_angle\">Sekundární úhel</string>\n    <string name=\"sides\">Strany</string>\n    <string name=\"channel_mix\">Mix kanálů</string>\n    <string name=\"blue_green\">Modrá zelená</string>\n    <string name=\"red_blue\">Červená modrá</string>\n    <string name=\"green_red\">Zelená červená</string>\n    <string name=\"into_red\">Do červena</string>\n    <string name=\"into_green\">Do zelena</string>\n    <string name=\"into_blue\">Do modra</string>\n    <string name=\"cyan\">azurová</string>\n    <string name=\"magenta\">purpurová</string>\n    <string name=\"yellow\">Žluť</string>\n    <string name=\"color_halftone\">Barva Polotón</string>\n    <string name=\"contour\">Obrys</string>\n    <string name=\"levels\">úrovně</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi krystalizuje</string>\n    <string name=\"shape\">Tvar</string>\n    <string name=\"stretch\">Úsek</string>\n    <string name=\"randomness\">Nahodilost</string>\n    <string name=\"despeckle\">Despeckle</string>\n    <string name=\"diffuse\">Šířit</string>\n    <string name=\"dog\">Pes</string>\n    <string name=\"second_radius\">Druhý poloměr</string>\n    <string name=\"equalize\">Vyrovnat</string>\n    <string name=\"glow\">Záře</string>\n    <string name=\"whirl_and_pinch\">Vířit a štípnout</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">Barva ohraničení</string>\n    <string name=\"polar_coordinates\">Polární souřadnice</string>\n    <string name=\"rect_to_polar\">Rect to polar</string>\n    <string name=\"polar_to_rect\">Polární až obdélníkový</string>\n    <string name=\"invert_in_circle\">Invertovat v kruhu</string>\n    <string name=\"reduce_noise\">Snížit hluk</string>\n    <string name=\"simple_solarize\">Jednoduchá Solarizace</string>\n    <string name=\"weave\">Vazba</string>\n    <string name=\"x_gap\">X mezera</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X šířka</string>\n    <string name=\"y_wdth\">Y šířka</string>\n    <string name=\"twirl\">Točit</string>\n    <string name=\"rubber_stmp\">Razítko</string>\n    <string name=\"smear\">Namazat</string>\n    <string name=\"density\">Hustota</string>\n    <string name=\"mix\">Směs</string>\n    <string name=\"sphere_lensh_distortion\">Sphere Lens Distortion</string>\n    <string name=\"refraction_index\">Index lomu</string>\n    <string name=\"arc\">Oblouk</string>\n    <string name=\"spread_angle\">Úhel rozpětí</string>\n    <string name=\"sparkle\">Jiskra</string>\n    <string name=\"rays\">Paprsky</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Marie</string>\n    <string name=\"autumn\">Podzim</string>\n    <string name=\"bone\">Kost</string>\n    <string name=\"jet\">Proud</string>\n    <string name=\"winter\">Zima</string>\n    <string name=\"ocean\">Oceán</string>\n    <string name=\"summer\">Letní</string>\n    <string name=\"spring\">Jaro</string>\n    <string name=\"cool_variant\">Cool Varianta</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Růžový</string>\n    <string name=\"hot\">Horký</string>\n    <string name=\"parula\">Slovo</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Peklo</string>\n    <string name=\"plasma\">Plazma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Občané</string>\n    <string name=\"twilight\">Soumrak</string>\n    <string name=\"twilight_shifted\">Soumrak se posunul</string>\n    <string name=\"auto_perspective\">Perspektiva Auto</string>\n    <string name=\"deskew\">Zkosení</string>\n    <string name=\"allow_crop\">Povolit oříznutí</string>\n    <string name=\"crop_or_perspective\">Oříznutí nebo perspektiva</string>\n    <string name=\"absolute\">Absolutní</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Tmavě zelená</string>\n    <string name=\"lens_correction\">Korekce objektivu</string>\n    <string name=\"target_lens_profile\">Soubor profilu cílového objektivu ve formátu JSON</string>\n    <string name=\"download_ready_lens_profiles\">Stáhněte si hotové profily objektivů</string>\n    <string name=\"part_percents\">Část procent</string>\n    <string name=\"export_as_json\">Exportovat jako JSON</string>\n    <string name=\"export_as_json_sub\">Zkopírujte řetězec s daty palety jako reprezentaci json</string>\n    <string name=\"seam_carving\">Vyřezávání švů</string>\n    <string name=\"home_screen\">Domovská obrazovka</string>\n    <string name=\"lock_screen\">Uzamknout obrazovku</string>\n    <string name=\"built_in\">Vestavěný</string>\n    <string name=\"wallpapers_export\">Export tapet</string>\n    <string name=\"refresh\">Obnovit</string>\n    <string name=\"wallpapers_export_sub\">Získejte aktuální tapety Home, Lock a Built-in</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Povolit přístup ke všem souborům, to je potřeba k načtení tapet</string>\n    <string name=\"allow_read_media_images_for_wp\">Oprávnění ke správě externího úložiště nestačí, musíte povolit přístup ke svým obrázkům, nezapomeňte vybrat možnost  \\\"Povolit vše \\\"</string>\n    <string name=\"add_preset_to_filename\">Přidat předvolbu k názvu souboru</string>\n    <string name=\"add_preset_to_filename_sub\">Připojí příponu s vybranou předvolbou k názvu souboru obrázku</string>\n    <string name=\"add_image_scale_mode_to_filename\">Přidat režim měřítka obrázku k názvu souboru</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Připojí příponu s vybraným režimem měřítka obrázku k souboru obrázku</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Převeďte obrázek na text ASCII, který bude vypadat jako obrázek</string>\n    <string name=\"params\">Parametry</string>\n    <string name=\"invert_colors_ascii_sub\">Aplikuje negativní filtr na obrázek pro lepší výsledek v některých případech</string>\n    <string name=\"processing_screenshot\">Zpracování snímku obrazovky</string>\n    <string name=\"screenshot_not_captured_try_again\">Snímek obrazovky nebyl zachycen, zkuste to znovu</string>\n    <string name=\"skipped_saving\">Ukládání bylo přeskočeno</string>\n    <string name=\"skipped_saving_multiple\">%1$s souborů přeskočeno</string>\n    <string name=\"allow_skip_if_larger\">Povolit přeskočení, pokud je větší</string>\n    <string name=\"allow_skip_if_larger_sub\">Některé nástroje budou moci přeskočit ukládání obrázků, pokud by výsledná velikost souboru byla větší než původní</string>\n    <string name=\"qr_type_calendar_event\">Kalendář událostí</string>\n    <string name=\"qr_type_contact_info\">Kontakt</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Umístění</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Otevřená síť</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Zpráva</string>\n    <string name=\"address\">Adresa</string>\n    <string name=\"subject\">Podrobit</string>\n    <string name=\"body\">Tělo</string>\n    <string name=\"name\">Jméno</string>\n    <string name=\"organization\">Organizace</string>\n    <string name=\"title\">Titul</string>\n    <string name=\"phones\">Telefony</string>\n    <string name=\"emails\">e-maily</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Adresy</string>\n    <string name=\"summary\">Shrnutí</string>\n    <string name=\"description\">Popis</string>\n    <string name=\"location\">Umístění</string>\n    <string name=\"organizer\">Organizátor</string>\n    <string name=\"start_date\">Datum zahájení</string>\n    <string name=\"end_date\">Datum ukončení</string>\n    <string name=\"status\">Postavení</string>\n    <string name=\"latitude\">Zeměpisná šířka</string>\n    <string name=\"longitude\">Zeměpisná délka</string>\n    <string name=\"create_barcode\">Vytvořte čárový kód</string>\n    <string name=\"edit_barcode\">Upravit čárový kód</string>\n    <string name=\"wifi_configuration\">Konfigurace Wi-Fi</string>\n    <string name=\"security\">Zabezpečení</string>\n    <string name=\"pick_contact\">Vyberte kontakt</string>\n    <string name=\"grant_contact_permission\">Udělte kontaktům v nastavení oprávnění k automatickému vyplňování pomocí vybraného kontaktu</string>\n    <string name=\"contact_info\">Kontaktní údaje</string>\n    <string name=\"first_name\">Křestní jméno</string>\n    <string name=\"middle_name\">Druhé jméno</string>\n    <string name=\"last_name\">Příjmení</string>\n    <string name=\"pronunciation\">Výslovnost</string>\n    <string name=\"add_phone\">Přidat telefon</string>\n    <string name=\"add_email\">Přidat e-mail</string>\n    <string name=\"add_address\">Přidat adresu</string>\n    <string name=\"website\">webové stránky</string>\n    <string name=\"add_website\">Přidat web</string>\n    <string name=\"formatted_name\">Formátovaný název</string>\n    <string name=\"qr_code_top_image\">Tento obrázek bude použit k umístění nad čárový kód</string>\n    <string name=\"code_customization\">Přizpůsobení kódu</string>\n    <string name=\"qr_logo_image\">Tento obrázek bude použit jako logo uprostřed QR kódu</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Polstrování logem</string>\n    <string name=\"logo_size\">Velikost loga</string>\n    <string name=\"logo_corners\">Rohy loga</string>\n    <string name=\"fourth_eye\">Čtvrté oko</string>\n    <string name=\"fourth_eye_description\">Přidá do qr kódu symetrii oka přidáním čtvrtého oka do spodního rohu</string>\n    <string name=\"pixel_shape\">Tvar pixelu</string>\n    <string name=\"frame_shape\">Tvar rámu</string>\n    <string name=\"ball_shape\">Tvar koule</string>\n    <string name=\"error_correction_level\">Úroveň opravy chyb</string>\n    <string name=\"dark_color\">Tmavá barva</string>\n    <string name=\"light_color\">Světlá barva</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Styl podobný Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Vzor masky</string>\n    <string name=\"code_may_be_not_scannable\">Tento kód nemusí být skenovatelný, změňte parametry vzhledu, aby byl čitelný na všech zařízeních</string>\n    <string name=\"not_scannable\">Nelze skenovat</string>\n    <string name=\"launcher_mode_sub\">Nástroje budou vypadat jako spouštěč aplikací na domovské obrazovce, aby byly kompaktnější</string>\n    <string name=\"launcher_mode\">Režim spouštěče</string>\n    <string name=\"flood_fill_sub\">Vyplní oblast vybraným štětcem a stylem</string>\n    <string name=\"flood_fill\">Povodňová výplň</string>\n    <string name=\"spray\">Sprej</string>\n    <string name=\"spray_sub\">Kreslí cestu ve stylu graffity</string>\n    <string name=\"square_particles\">Čtvercové částice</string>\n    <string name=\"square_particles_sub\">Částice spreje budou mít čtvercový tvar namísto kruhů</string>\n    <string name=\"palette_tools\">Nástroje palety</string>\n    <string name=\"palette_tools_sub\">Vygenerujte základní/materiál z palety z obrázku nebo importujte/exportujte přes různé formáty palet</string>\n    <string name=\"edit_palette\">Upravit paletu</string>\n    <string name=\"edit_palette_sub\">Export/import palety v různých formátech</string>\n    <string name=\"color_name\">Název barvy</string>\n    <string name=\"palette_name\">Název palety</string>\n    <string name=\"palette_format\">Formát palety</string>\n    <string name=\"export_palette_sub\">Export vygenerované palety do různých formátů</string>\n    <string name=\"add_color_palette_sub\">Přidá novou barvu do aktuální palety</string>\n    <string name=\"palette_name_not_supported\">Formát %1$s nepodporuje zadání názvu palety</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Kvůli zásadám Obchodu Play nelze tuto funkci zahrnout do aktuálního sestavení. Chcete-li získat přístup k této funkci, stáhněte si ImageToolbox z alternativního zdroje. Dostupné sestavení na GitHubu najdete níže.</string>\n    <string name=\"open_github_page\">Otevřete stránku Github</string>\n    <string name=\"overwrite_files_sub_short\">Původní soubor bude nahrazen novým souborem namísto uložení do vybrané složky</string>\n    <string name=\"hidden_watermark_text_detected\">Zjištěn skrytý text vodoznaku</string>\n    <string name=\"hidden_watermark_image_detected\">Byl zjištěn skrytý obrázek vodoznaku</string>\n    <string name=\"this_image_was_hidden\">Tento obrázek byl skrytý</string>\n    <string name=\"generative_inpaint\">Generativní malba</string>\n    <string name=\"generative_inpaint_sub\">Umožňuje odstranit objekty z obrázku pomocí modelu AI, aniž byste se spoléhali na OpenCV. K použití této funkce si aplikace stáhne požadovaný model (~200 MB) z GitHubu</string>\n    <string name=\"generative_inpaint_ready_sub\">Umožňuje odstranit objekty z obrázku pomocí modelu AI, aniž byste se spoléhali na OpenCV. Může se jednat o dlouhodobou operaci</string>\n    <string name=\"error_level_analysis\">Analýza úrovně chyb</string>\n    <string name=\"luminance_gradient\">Gradient jasu</string>\n    <string name=\"average_distance\">Průměrná vzdálenost</string>\n    <string name=\"copy_move_detection\">Kopírovat Detekce přesunu</string>\n    <string name=\"retain\">Zachovat</string>\n    <string name=\"coefficent\">Koeficient</string>\n    <string name=\"clipboard_data_is_too_large\">Data schránky jsou příliš velká</string>\n    <string name=\"data_is_too_large_to_copy\">Data jsou příliš velká na kopírování</string>\n    <string name=\"simple_weave_pixelization\">Jednoduchá Weave Pixelizace</string>\n    <string name=\"staggered_pixelization\">Postupná pixelizace</string>\n    <string name=\"cross_pixelization\">Křížová pixelizace</string>\n    <string name=\"micro_macro_pixelization\">Mikro makro pixelizace</string>\n    <string name=\"orbital_pixelization\">Orbitální pixelizace</string>\n    <string name=\"vortex_pixelization\">Vortexová pixelizace</string>\n    <string name=\"pulse_grid_pixelization\">Pixelizace pulzní mřížky</string>\n    <string name=\"nucleus_pixelization\">Pixelizace jádra</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave Pixelization</string>\n    <string name=\"cannot_open_uri\">Nelze otevřít uri  \\\"%1$s \\\"</string>\n    <string name=\"snowfall_mode\">Režim sněžení</string>\n    <string name=\"enabled\">Povoleno</string>\n    <string name=\"border_frame\">Hraniční rám</string>\n    <string name=\"glitch_variant\">Závadová varianta</string>\n    <string name=\"channel_shift\">Posun kanálu</string>\n    <string name=\"max_offset\">Maximální offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blokovat závadu</string>\n    <string name=\"block_size\">Velikost bloku</string>\n    <string name=\"crt_curvature\">CRT zakřivení</string>\n    <string name=\"curvature\">Zakřivení</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">Nástroje AI</string>\n    <string name=\"ai_tools_sub\">Různé nástroje pro zpracování obrázků prostřednictvím modelů AI, jako je odstraňování artefaktů nebo odšumování</string>\n    <string name=\"model_anime_undeint\">Komprese, zubaté linie</string>\n    <string name=\"model_broadcast\">Karikatury, vysílací komprese</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Obecná komprese, obecný šum</string>\n    <string name=\"model_wb_denoise\">Bezbarvý kreslený hluk</string>\n    <string name=\"model_span_anime_pretrain\">Rychlá, obecná komprese, obecný šum, animace/komiks/anime</string>\n    <string name=\"model_book_scan\">Skenování knih</string>\n    <string name=\"model_overexposure\">Korekce expozice</string>\n    <string name=\"model_fbcnn_color_fp16\">Nejlepší při obecné kompresi, barevné obrázky</string>\n    <string name=\"model_fbcnn_gray_fp16\">Nejlepší při obecné kompresi, obrázky ve stupních šedi</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Obecná komprese, obrázky ve stupních šedi, silnější</string>\n    <string name=\"model_scunet_color_gan_fp16\">Obecný šum, barevné obrázky</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Obecný šum, barevné obrázky, lepší detaily</string>\n    <string name=\"model_scunet_gray_15_fp16\">Obecný šum, obrázky ve stupních šedi</string>\n    <string name=\"model_scunet_gray_25_fp16\">Obecný šum, obrázky ve stupních šedi, silnější</string>\n    <string name=\"model_scunet_gray_50_fp16\">Obecný šum, obrázky ve stupních šedi, nejsilnější</string>\n    <string name=\"model_jpeg_destroyer\">Obecná komprese</string>\n    <string name=\"model_jaywreck\">Obecná komprese</string>\n    <string name=\"model_h264\">Texturizace, komprese h264</string>\n    <string name=\"model_vhs\">Komprese VHS</string>\n    <string name=\"model_cinepak\">Nestandardní komprese (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink komprese, lepší na geometrii</string>\n    <string name=\"model_debink_v5\">Bink komprese, silnější</string>\n    <string name=\"model_debink_v6\">Komprese Bink, měkká, zachovává detaily</string>\n    <string name=\"model_antialias\">Eliminace schodišťového efektu, vyhlazování</string>\n    <string name=\"model_kdm_scans\">Naskenované umění/kresby, mírná komprese, moaré</string>\n    <string name=\"model_bandage\">Barevné pruhování</string>\n    <string name=\"model_halftone\">Pomalé, odstranění polotónů</string>\n    <string name=\"model_colorizer\">Obecný kolorizér pro obrázky ve stupních šedi/černobíle, pro lepší výsledky použijte DDColor</string>\n    <string name=\"model_deedge\">Odstraňování okrajů</string>\n    <string name=\"model_desharpen\">Odstraňuje nadměrné ostření</string>\n    <string name=\"model_dither\">Pomalé, váhavé</string>\n    <string name=\"model_gainres\">Anti-aliasing, obecné artefakty, CGI</string>\n    <string name=\"model_kdm003_scans\">Zpracování skenů KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Lehký model vylepšení obrazu</string>\n    <string name=\"model_bcgone_detailed_v2\">Odstranění kompresního artefaktu</string>\n    <string name=\"model_bcgone_smooth\">Odstranění kompresního artefaktu</string>\n    <string name=\"model_bandage_smooth\">Odstranění obvazu s hladkým výsledkem</string>\n    <string name=\"model_bendel_halftone\">Zpracování polotónového vzoru</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Odstranění vzoru rozkladu V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Odstranění artefaktů JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Vylepšení textury H.264</string>\n    <string name=\"model_vhs_sharpen\">Ostření a vylepšení VHS</string>\n    <string name=\"merging\">Sloučení</string>\n    <string name=\"chunk_size\">Velikost kousku</string>\n    <string name=\"overlap_size\">Velikost překrytí</string>\n    <string name=\"note_chunk_info\">Obrázky větší než %1$s pixelů budou nakrájeny a zpracovány na kousky, které se překrývají, aby se zabránilo viditelným švům.</string>\n    <string name=\"large_chunk_warning\">Velké velikosti mohou způsobit nestabilitu u zařízení nižší třídy</string>\n    <string name=\"select_one_to_start\">Začněte výběrem jednoho</string>\n    <string name=\"delete_model_sub\">Chcete smazat %1$s model? Budete si jej muset stáhnout znovu</string>\n    <string name=\"confirm\">Potvrdit</string>\n    <string name=\"models\">Modelky</string>\n    <string name=\"downloaded_models\">Stažené modely</string>\n    <string name=\"available_models\">Dostupné modely</string>\n    <string name=\"preparing\">Příprava</string>\n    <string name=\"active_model\">Aktivní model</string>\n    <string name=\"failed_to_open_session\">Otevření relace se nezdařilo</string>\n    <string name=\"only_onnx_models\">Importovat lze pouze modely .onnx/.ort</string>\n    <string name=\"import_model\">Importovat model</string>\n    <string name=\"import_model_sub\">Importujte vlastní model onnx pro další použití, jsou přijímány pouze modely onnx/ort, podporuje téměř všechny varianty podobné esrgan</string>\n    <string name=\"imported_models\">Importované modely</string>\n    <string name=\"model_scunet_color_15_fp16\">Obecný šum, barevné obrázky</string>\n    <string name=\"model_scunet_color_25_fp16\">Obecný šum, barevné obrázky, silnější</string>\n    <string name=\"model_scunet_color_50_fp16\">Obecný šum, barevné obrázky, nejsilnější</string>\n    <string name=\"model_artifacts_dithering_alsa\">Snižuje artefakty rozkladu a barevné pruhy, zlepšuje hladké přechody a ploché barevné oblasti.</string>\n    <string name=\"model_nmkd_brighten_redux\">Vylepšuje jas a kontrast obrazu s vyváženými světly při zachování přirozených barev.</string>\n    <string name=\"model_nmkd_brighten\">Zesvětluje tmavé snímky a zároveň zachovává detaily a zabraňuje přeexponování.</string>\n    <string name=\"model_nmkd_detoon\">Odstraňuje nadměrné barevné tónování a obnovuje neutrálnější a přirozenější vyvážení barev.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Aplikuje tónování šumu na základě Poisson s důrazem na zachování jemných detailů a textur.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Aplikuje jemné tónování Poissonova šumu pro hladší a méně agresivní vizuální výsledky.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Jednotné tónování šumu zaměřené na zachování detailů a čistotu obrazu.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Jemné jednotné tónování šumu pro jemnou texturu a hladký vzhled.</string>\n    <string name=\"model_repainter\">Opravuje poškozené nebo nerovné oblasti překreslením artefaktů a zlepšením konzistence obrazu.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Lehký model pro odstraňování pásů, který odstraňuje barevné pruhy s minimálními náklady na výkon.</string>\n    <string name=\"model_jpeg_0_20\">Optimalizuje obrazy s velmi vysokou kompresí artefaktů (0-20% kvalita) pro lepší jasnost.</string>\n    <string name=\"model_jpeg_20_40\">Vylepšuje obrázky pomocí artefaktů s vysokou kompresí (20-40% kvalita), obnovuje detaily a snižuje šum.</string>\n    <string name=\"model_jpeg_40_60\">Zlepšuje snímky s mírnou kompresí (40-60% kvalita), vyvážením ostrosti a plynulosti.</string>\n    <string name=\"model_jpeg_60_80\">Upřesňuje obrázky pomocí lehké komprese (60-80% kvalita) pro vylepšení jemných detailů a textur.</string>\n    <string name=\"model_jpeg_80_100\">Mírně vylepšuje téměř bezeztrátový obraz (80-100% kvalita) při zachování přirozeného vzhledu a detailů.</string>\n    <string name=\"model_spongecolor_lite\">Jednoduché a rychlé kolorování, kreslené, není ideální</string>\n    <string name=\"model_deblr\">Mírně snižuje rozmazání obrazu a zlepšuje ostrost bez vnášení artefaktů.</string>\n    <string name=\"processing_channel\">Dlouho běžící operace</string>\n    <string name=\"processing_image\">Zpracování obrázku</string>\n    <string name=\"processing\">Zpracování</string>\n    <string name=\"model_artifacts_jpg_0_20\">Odstraňuje těžké artefakty komprese JPEG v obrazech velmi nízké kvality (0-20 %).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Snižuje silné JPEG artefakty ve vysoce komprimovaných obrázcích (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Vyčistí mírné JPEG artefakty při zachování detailů obrazu (40-60 %).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Zjemňuje světlé JPEG artefakty v poměrně vysoké kvalitě obrázků (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Jemně redukuje drobné JPEG artefakty v téměř bezeztrátových obrázcích (80-100 %).</string>\n    <string name=\"model_redetail_v2\">Vylepšuje jemné detaily a textury a zlepšuje vnímanou ostrost bez těžkých artefaktů.</string>\n    <string name=\"processing_finished\">Zpracování dokončeno</string>\n    <string name=\"processing_failed\">Zpracování se nezdařilo</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Zlepšuje textury a detaily pleti a zároveň zachovává přirozený vzhled, optimalizovaný pro rychlost.</string>\n    <string name=\"model_sbdv_dejpeg\">Odstraňuje artefakty komprese JPEG a obnovuje kvalitu obrazu komprimovaných fotografií.</string>\n    <string name=\"model_iso_denoise_v1\">Snižuje šum ISO na fotografiích pořízených za špatných světelných podmínek a zachovává detaily.</string>\n    <string name=\"model_dejumbo\">Opravuje přeexponované nebo „jumbo“ zvýraznění a obnovuje lepší vyvážení tónů.</string>\n    <string name=\"model_ddcolor_tiny\">Lehký a rychlý kolorizační model, který dodává obrázkům ve stupních šedi přirozené barvy.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Odhlučnit</string>\n    <string name=\"type_colorize\">Vybarvit</string>\n    <string name=\"type_artifacts\">Artefakty</string>\n    <string name=\"type_enhance\">Zvýšit</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Skenuje</string>\n    <string name=\"type_upscale\">Upscale</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler pro obecné obrázky; malý model, který využívá méně GPU a času, s mírným rozmazáním a odšumováním.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler pro obecné obrázky, zachování textur a přirozených detailů.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 upscaler pro obecné obrázky s vylepšenými texturami a realistickými výsledky.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler optimalizovaný pro obrázky anime; 6 bloků RRDB pro ostřejší linie a detaily.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 upscaler se ztrátou MSE poskytuje hladší výsledky a snížené artefakty pro obecné obrázky.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimalizovaný pro obrázky anime; Varianta 4B32F s ostřejšími detaily a hladkými liniemi.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Model X4 UltraSharp V2 pro obecné obrázky; zdůrazňuje ostrost a jasnost.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; rychlejší a menší, zachovává detaily při použití menší paměti GPU.</string>\n    <string name=\"model_rmbg_1_4\">Lehký model pro rychlé odstranění pozadí. Vyvážený výkon a přesnost. Pracuje s portréty, objekty a scénami. Doporučeno pro většinu případů použití.</string>\n    <string name=\"type_removebg\">Odebrat BG</string>\n    <string name=\"horizontal_border_thickness\">Tloušťka horizontálního okraje</string>\n    <string name=\"vertical_border_thickness\">Tloušťka vertikálního okraje</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"many\">%1$s barev</item>\n        <item quantity=\"one\">%1$s barva</item>\n        <item quantity=\"few\">%1$s barev</item>\n        <item quantity=\"other\">%1$s barev</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Aktuální model nepodporuje chunking, obraz bude zpracován v původních rozměrech, což může způsobit vysokou spotřebu paměti a problémy se zařízeními nižší třídy</string>\n    <string name=\"chunking_disabled\">Chunking zakázáno, obraz bude zpracován v původních rozměrech, což může způsobit vysokou spotřebu paměti a problémy se zařízeními nižší třídy, ale může poskytnout lepší výsledky při odvození</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">Vysoce přesný model segmentace obrazu pro odstranění pozadí</string>\n    <string name=\"model_u2netp\">Odlehčená verze U2Net pro rychlejší odstraňování pozadí s menší spotřebou paměti.</string>\n    <string name=\"model_ddcolor\">Plný model DDColor poskytuje vysoce kvalitní vybarvení pro obecné obrázky s minimálními artefakty. Nejlepší výběr ze všech barevných modelů.</string>\n    <string name=\"model_ddcolor_artistic\">DDDColor Vyškolené a soukromé umělecké datové sady; vytváří rozmanité a umělecké výsledky zbarvení s menším počtem nerealistických barevných artefaktů.</string>\n    <string name=\"model_birefnet\">Lehký model BiRefNet založený na Swin Transformer pro přesné odstranění pozadí.</string>\n    <string name=\"model_inspyrenet\">Vysoce kvalitní odstranění pozadí s ostrými hranami a vynikajícím zachováním detailů, zejména na složitých objektech a složitých pozadích.</string>\n    <string name=\"model_isnet\">Model odstranění pozadí, který vytváří přesné masky s hladkými okraji, vhodný pro běžné objekty a zachování mírného detailu.</string>\n    <string name=\"model_already_downloaded\">Model je již stažen</string>\n    <string name=\"model_successfully_imported\">Model byl úspěšně importován</string>\n    <string name=\"type\">Typ</string>\n    <string name=\"keyword\">Klíčové slovo</string>\n    <string name=\"very_fast\">Velmi rychlé</string>\n    <string name=\"normal\">Normální</string>\n    <string name=\"slow\">Pomalý</string>\n    <string name=\"very_slow\">Velmi pomalé</string>\n    <string name=\"compute_percents\">Vypočítat procenta</string>\n    <string name=\"minimum_value_is\">Minimální hodnota je %1$s</string>\n    <string name=\"warp_sub\">Zkreslení obrazu kresbou prsty</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">Tvrdost</string>\n    <string name=\"warp_mode\">Režim Warp</string>\n    <string name=\"warp_mode_move\">Pohyb</string>\n    <string name=\"warp_mode_grow\">Růst</string>\n    <string name=\"warp_mode_shrink\">Zmenšit</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Krouživým pohybem CCW</string>\n    <string name=\"fade_strength\">Síla blednutí</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Dolní Drop</string>\n    <string name=\"start_drop\">Spusťte aplikaci Drop</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">Stahování</string>\n    <string name=\"smooth_shapes\">Hladké tvary</string>\n    <string name=\"smooth_shapes_sub\">Použijte superelipsy místo standardních zaoblených obdélníků pro hladší a přirozenější tvary</string>\n    <string name=\"shape_type\">Typ tvaru</string>\n    <string name=\"cut\">Střih</string>\n    <string name=\"rounded\">Zaoblený</string>\n    <string name=\"smooth\">Hladký</string>\n    <string name=\"cut_shapes_sub\">Ostré hrany bez zaoblení</string>\n    <string name=\"rounded_shapes_sub\">Klasické zaoblené rohy</string>\n    <string name=\"shapes_type\">Tvary Typ</string>\n    <string name=\"corners_size\">Velikost rohů</string>\n    <string name=\"squircle\">Veverka</string>\n    <string name=\"squircle_shapes_sub\">Elegantní zaoblené prvky uživatelského rozhraní</string>\n    <string name=\"filename_format\">Formát názvu souboru</string>\n    <string name=\"prefix_pattern_description\">Vlastní text umístěný na samém začátku názvu souboru, ideální pro názvy projektů, značky nebo osobní značky.</string>\n    <string name=\"original_filename_pattern_description\">Používá původní název souboru bez přípony, což vám pomáhá zachovat identifikaci zdroje nedotčenou.</string>\n    <string name=\"width_pattern_description\">Šířka obrázku v pixelech, užitečné pro sledování změn rozlišení nebo změny měřítka výsledků.</string>\n    <string name=\"height_pattern_description\">Výška obrázku v pixelech, užitečná při práci s poměry stran nebo exportu.</string>\n    <string name=\"random_numbers_pattern_description\">Generuje náhodné číslice pro zaručení jedinečných názvů souborů; přidejte další číslice pro větší bezpečnost proti duplikátům.</string>\n    <string name=\"sequence_number_pattern_description\">Automatické počítadlo pro dávkové exporty, ideální při ukládání více obrázků v jedné relaci.</string>\n    <string name=\"preset_info_pattern_description\">Vloží použitý název předvolby do názvu souboru, abyste si snadno zapamatovali, jak byl obrázek zpracován.</string>\n    <string name=\"scale_mode_pattern_description\">Zobrazuje režim změny velikosti obrazu použitý během zpracování a pomáhá rozlišovat obrazy se změněnou velikostí, oříznuté nebo přizpůsobené obrazy.</string>\n    <string name=\"suffix_pattern_description\">Vlastní text umístěný na konci názvu souboru, užitečný pro verzování jako _v2, _edited nebo _final.</string>\n    <string name=\"extension_pattern_description\">Přípona souboru (png, jpg, webp atd.), automaticky odpovídající skutečně uloženému formátu.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Přizpůsobitelné časové razítko, které vám umožní definovat svůj vlastní formát pomocí specifikace Java pro dokonalé třídění.</string>\n    <string name=\"fling_type\">Typ Fling</string>\n    <string name=\"android_native\">Android Nativní</string>\n    <string name=\"ios_style\">Styl iOS</string>\n    <string name=\"smooth_curve\">Hladká křivka</string>\n    <string name=\"quick_stop\">Rychlé zastavení</string>\n    <string name=\"bouncy\">Skákající</string>\n    <string name=\"floaty\">Plovoucí</string>\n    <string name=\"snappy\">Elegantní</string>\n    <string name=\"ultra_smooth\">Ultra hladký</string>\n    <string name=\"adaptive\">Adaptivní</string>\n    <string name=\"accessibility_aware\">Přístupnost Aware</string>\n    <string name=\"reduced_motion\">Snížený pohyb</string>\n    <string name=\"android_native_sub\">Nativní fyzika rolování pro Android</string>\n    <string name=\"smooth_sub\">Vyvážené, plynulé rolování pro všeobecné použití</string>\n    <string name=\"ios_style_sub\">Chování posouvání jako u iOS s vyšším třením</string>\n    <string name=\"smooth_curve_sub\">Unikátní spline křivka pro zřetelný pocit rolování</string>\n    <string name=\"quick_stop_sub\">Přesné rolování s rychlým zastavením</string>\n    <string name=\"bouncy_sub\">Hravý, citlivý skákací svitek</string>\n    <string name=\"floaty_sub\">Dlouhé, klouzavé svitky pro procházení obsahu</string>\n    <string name=\"snappy_sub\">Rychlé a citlivé posouvání pro interaktivní uživatelská rozhraní</string>\n    <string name=\"ultra_smooth_sub\">Prémiové plynulé rolování s prodlouženou hybností</string>\n    <string name=\"adaptive_sub\">Upravuje fyziku na základě rychlosti letu</string>\n    <string name=\"accessibility_aware_sub\">Respektuje nastavení přístupnosti systému</string>\n    <string name=\"reduced_motion_sub\">Minimální pohyb pro potřeby dostupnosti</string>\n    <string name=\"primary_lines\">Primární linky</string>\n    <string name=\"primary_lines_sub\">Přidá silnější čáru každý pátý řádek</string>\n    <string name=\"fill_color\">Barva výplně</string>\n    <string name=\"hidden_tools\">Skryté nástroje</string>\n    <string name=\"hidden_for_share\">Nástroje skryté pro sdílení</string>\n    <string name=\"color_library\">Knihovna barev</string>\n    <string name=\"color_library_sub\">Prohlédněte si rozsáhlou sbírku barev</string>\n    <string name=\"model_fatality_deblur\">Zaostří a odstraní rozmazání snímků při zachování přirozených detailů, což je ideální pro opravu rozostřených fotografií.</string>\n    <string name=\"model_unresize_v3\">Inteligentně obnovuje obrázky, jejichž velikost byla dříve změněna, a obnovuje ztracené detaily a textury.</string>\n    <string name=\"model_liveaction_v1_span\">Optimalizováno pro živě akční obsah, snižuje kompresní artefakty a vylepšuje jemné detaily ve snímcích filmu/TV pořadu.</string>\n    <string name=\"model_vhs2hd_realplksr\">Převádí záznam v kvalitě VHS do HD, odstraňuje šum na pásce a zvyšuje rozlišení při zachování vintage stylu.</string>\n    <string name=\"model_text2hd_v1\">Specializuje se na obrázky a snímky obrazovky s velkým množstvím textu, zaostřuje znaky a zlepšuje čitelnost.</string>\n    <string name=\"model_frankendata_pretrainer\">Pokročilé upscaling trénované na různých souborech dat, vynikající pro všeobecné vylepšení fotografií.</string>\n    <string name=\"model_realwebphoto_v2\">Optimalizováno pro webově komprimované fotografie, odstraňuje JPEG artefakty a obnovuje přirozený vzhled.</string>\n    <string name=\"model_realwebphoto_v4\">Vylepšená verze pro webové fotografie s lepším zachováním textury a redukcí artefaktů.</string>\n    <string name=\"model_dat_2x\">2x upscaling s technologií Dual Aggregation Transformer, zachovává ostrost a přirozené detaily.</string>\n    <string name=\"model_dat_3x\">3x upscaling pomocí pokročilé architektury transformátoru, ideální pro potřeby mírného zvětšení.</string>\n    <string name=\"model_dat_4x\">4x vysoce kvalitní upscaling s nejmodernější sítí transformátorů, zachovává jemné detaily ve větším měřítku.</string>\n    <string name=\"model_nafnet_deblurring\">Odstraňuje rozmazání/šum a chvění z fotografií. Všeobecný účel, ale nejlépe na fotografiích.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Obnovuje obrazy nízké kvality pomocí transformátoru Swin2SR, optimalizovaného pro degradaci BSRGAN. Skvělé pro opravu těžkých kompresních artefaktů a vylepšení detailů ve 4násobném měřítku.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x upscaling s transformátorem SwinIR trénovaným na degradaci BSRGAN. Využívá GAN pro ostřejší textury a přirozenější detaily na fotografiích a složitých scénách.</string>\n    <string name=\"path\">Cesta</string>\n    <string name=\"merge_pdf\">Sloučit PDF</string>\n    <string name=\"merge_pdf_sub\">Spojte více souborů PDF do jednoho dokumentu</string>\n    <string name=\"files_order\">Pořadí souborů</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Rozdělit PDF</string>\n    <string name=\"split_pdf_sub\">Extrahujte konkrétní stránky z dokumentu PDF</string>\n    <string name=\"rotate_pdf\">Otočit PDF</string>\n    <string name=\"rotate_pdf_sub\">Opravte orientaci stránky trvale</string>\n    <string name=\"pages\">Stránky</string>\n    <string name=\"rearrange_pdf\">Přeuspořádat PDF</string>\n    <string name=\"rearrange_pdf_sub\">Přetažením stránek změníte jejich pořadí</string>\n    <string name=\"hold_drag_drop\">Podržte a přetáhněte stránky</string>\n    <string name=\"page_numbers\">Čísla stránek</string>\n    <string name=\"page_numbers_sub\">Automaticky přidejte číslování do dokumentů</string>\n    <string name=\"label_format\">Formát štítku</string>\n    <string name=\"pdf_to_text\">PDF na text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extrahujte prostý text z dokumentů PDF</string>\n    <string name=\"watermark_pdf_sub\">Překryvný vlastní text pro branding nebo zabezpečení</string>\n    <string name=\"signature\">Podpis</string>\n    <string name=\"signature_sub\">Přidejte svůj elektronický podpis do jakéhokoli dokumentu</string>\n    <string name=\"will_be_for_signature\">Toto bude použito jako podpis</string>\n    <string name=\"unlock_pdf\">Odemknout PDF</string>\n    <string name=\"unlock_pdf_sub\">Odstraňte hesla z chráněných souborů</string>\n    <string name=\"protect_pdf\">Chránit PDF</string>\n    <string name=\"protect_pdf_sub\">Zabezpečte své dokumenty pomocí silného šifrování</string>\n    <string name=\"success\">Úspěch</string>\n    <string name=\"pdf_unlocked\">PDF odemčené, můžete jej uložit nebo sdílet</string>\n    <string name=\"repair_pdf\">Oprava PDF</string>\n    <string name=\"repair_pdf_sub\">Pokuste se opravit poškozené nebo nečitelné dokumenty</string>\n    <string name=\"grayscale\">Stupně šedi</string>\n    <string name=\"grayscale_pdf_sub\">Převeďte všechny vložené obrázky dokumentu do stupňů šedi</string>\n    <string name=\"compress_pdf\">Komprimovat PDF</string>\n    <string name=\"compress_pdf_sub\">Optimalizujte velikost souboru dokumentu pro snazší sdílení</string>\n    <string name=\"repair_info\">ImageToolbox znovu sestaví vnitřní tabulku křížových odkazů a regeneruje strukturu souborů od začátku. To může obnovit přístup k mnoha souborům, které \\\\\"nelze otevřít\\\\\"</string>\n    <string name=\"grayscale_info\">Tento nástroj převede všechny obrázky dokumentů do stupňů šedi. Nejlepší pro tisk a zmenšení velikosti souboru</string>\n    <string name=\"metadata\">Metadata</string>\n    <string name=\"metadata_pdf_sub\">Upravte vlastnosti dokumentu pro lepší soukromí</string>\n    <string name=\"tags\">Tagy</string>\n    <string name=\"producer\">Výrobce</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Klíčová slova</string>\n    <string name=\"creator\">Tvůrce</string>\n    <string name=\"privacy_deep_clean\">Soukromí Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Vymažte všechna dostupná metadata pro tento dokument</string>\n    <string name=\"page\">Strana</string>\n    <string name=\"deep_ocr\">Hluboké OCR</string>\n    <string name=\"deep_ocr_sub\">Extrahujte text z dokumentu a uložte jej do jednoho textového souboru pomocí enginu Tesseract</string>\n    <string name=\"cant_remove_all\">Nelze odstranit všechny stránky</string>\n    <string name=\"remove_pages_pdf\">Odstraňte stránky PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Odstraňte konkrétní stránky z dokumentu PDF</string>\n    <string name=\"tap_to_remove\">Klepněte na Odebrat</string>\n    <string name=\"manually\">Ručně</string>\n    <string name=\"crop_pdf\">Oříznout PDF</string>\n    <string name=\"crop_pdf_sub\">Ořízněte stránky dokumentu na libovolné hranice</string>\n    <string name=\"flatten_pdf\">Vyrovnat PDF</string>\n    <string name=\"flatten_pdf_sub\">Udělejte PDF nemodifikovatelné rastrováním stránek dokumentu</string>\n    <string name=\"camera_failed_to_open\">Fotoaparát nelze spustit. Zkontrolujte prosím oprávnění a ujistěte se, že je nepoužívá jiná aplikace.</string>\n    <string name=\"extract_images\">Extrahovat obrázky</string>\n    <string name=\"extract_images_sub\">Extrahujte obrázky vložené do souborů PDF v původním rozlišení</string>\n    <string name=\"pdf_no_embedded\">Tento soubor PDF neobsahuje žádné vložené obrázky</string>\n    <string name=\"extract_images_info\">Tento nástroj naskenuje každou stránku a obnoví zdrojové obrázky v plné kvalitě – ideální pro ukládání originálů z dokumentů</string>\n    <string name=\"draw_signature\">Nakreslit podpis</string>\n    <string name=\"pen_params\">Parametry pera</string>\n    <string name=\"draw_signature_sub\">Použijte vlastní podpis jako obrázek pro umístění na dokumenty</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Rozdělte dokument s daným intervalem a zabalte nové dokumenty do zip archivu</string>\n    <string name=\"interval\">Interval</string>\n    <string name=\"print_pdf\">Tisk PDF</string>\n    <string name=\"print_pdf_sub\">Připravte dokument pro tisk s vlastní velikostí stránky</string>\n    <string name=\"pages_per_sheet\">Stránky na list</string>\n    <string name=\"orientation\">Orientace</string>\n    <string name=\"page_size\">Velikost stránky</string>\n    <string name=\"margin\">Okraj</string>\n    <string name=\"bloom\">Květ</string>\n    <string name=\"soft_knee\">Měkké koleno</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimalizováno pro anime a kreslené filmy. Rychlé převzorkování s vylepšenými přirozenými barvami a menším počtem artefaktů</string>\n    <string name=\"one_ui_sub\">Styl jako Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Zde zadejte základní matematické symboly pro výpočet požadované hodnoty (např. (5+5)*10)</string>\n    <string name=\"math_expression\">Matematický výraz</string>\n    <string name=\"pick_up_to_n_collage_images\">Vyzvedněte až %1$s obrázků</string>\n    <string name=\"keep_date_time\">Udržujte datum a čas</string>\n    <string name=\"keep_date_time_sub\">Vždy zachovejte exif značky související s datem a časem, funguje nezávisle na možnosti zachovat exif</string>\n    <string name=\"background_color_for_alpha_formats\">Barva Pozadí Pro Formáty Alfa</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Přidává možnost nastavit barvu pozadí pro každý formát obrázku s podporou alfa, pokud je tato možnost zakázána, je k dispozici pouze pro ty, které nejsou alfa</string>\n    <string name=\"open_markup_project\">Otevřete projekt</string>\n    <string name=\"open_markup_project_sub\">Pokračujte v úpravách dříve uloženého projektu Image Toolbox</string>\n    <string name=\"markup_project_open_failed\">Nelze otevřít projekt Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">V projektu Image Toolbox chybí data projektu</string>\n    <string name=\"markup_project_corrupted\">Projekt Image Toolbox je poškozen</string>\n    <string name=\"unsupported_markup_project_version\">Nepodporovaná verze projektu Image Toolbox: %1$d</string>\n    <string name=\"save_markup_project\">Uložit projekt</string>\n    <string name=\"save_markup_project_sub\">Ukládejte vrstvy, pozadí a historii úprav do upravitelného souboru projektu</string>\n    <string name=\"failed_to_open\">Otevření se nezdařilo</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Zápis do prohledávatelného PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Rozpoznejte text z obrázkové dávky a uložte prohledávatelné PDF s obrázkem a volitelnou textovou vrstvou</string>\n    <string name=\"layer_alpha\">Vrstva alfa</string>\n    <string name=\"horizontal_flip\">Horizontální překlopení</string>\n    <string name=\"vertical_flip\">Vertikální překlopení</string>\n    <string name=\"lock\">Zámek</string>\n    <string name=\"add_shadow\">Přidat stín</string>\n    <string name=\"shadow_color\">Barva stínu</string>\n    <string name=\"text_geometry\">Geometrie textu</string>\n    <string name=\"text_geometry_sub\">Roztažením nebo zkosením textu získáte ostřejší stylizaci</string>\n    <string name=\"scale_x\">Měřítko X</string>\n    <string name=\"skew_x\">Zkosit X</string>\n    <string name=\"remove_annotations\">Odebrat anotace</string>\n    <string name=\"remove_annotations_sub\">Odstraňte vybrané typy poznámek, jako jsou odkazy, komentáře, zvýraznění, tvary nebo pole formulářů ze stránek PDF</string>\n    <string name=\"annotation_link\">Hypertextové odkazy</string>\n    <string name=\"annotation_file_attachment\">Přílohy souborů</string>\n    <string name=\"annotation_line\">Čáry</string>\n    <string name=\"annotation_popup\">Vyskakovací okna</string>\n    <string name=\"annotation_stamp\">Známky</string>\n    <string name=\"annotation_shapes\">Tvary</string>\n    <string name=\"annotation_text\">Textové poznámky</string>\n    <string name=\"annotation_text_markup\">Označení textu</string>\n    <string name=\"annotation_widget\">Pole formuláře</string>\n    <string name=\"annotation_markup\">Označení</string>\n    <string name=\"annotation_unknown\">Neznámý</string>\n    <string name=\"annotations\">Anotace</string>\n    <string name=\"ungroup\">Zrušit seskupení</string>\n    <string name=\"add_shadow_sub\">Přidejte stín rozostření za vrstvu s konfigurovatelnou barvou a posuny</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-da/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"flexible\">Fleksibel</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"crop\">Beskær</string>\n    <string name=\"check_source_code\">Kildekode</string>\n    <string name=\"smth_went_wrong\">Noget gik galt: %1$s</string>\n    <string name=\"size\">Størrelse %1$s</string>\n    <string name=\"loading\">Indlæser…</string>\n    <string name=\"image_too_large_preview\">Billedet er for stort til at blive vist, men vil blive forsøgt gemt alligevel</string>\n    <string name=\"pick_image\">Vælg billede til at starte</string>\n    <string name=\"width\">Bredde %1$s</string>\n    <string name=\"height\">Højde %1$s</string>\n    <string name=\"quality\">Kvalitet</string>\n    <string name=\"extension\">Udvidelse</string>\n    <string name=\"resize_type\">Ændring af størrelse</string>\n    <string name=\"explicit\">Eksplicit</string>\n    <string name=\"pick_image_alt\">Vælg billede</string>\n    <string name=\"app_closing_sub\">Er di sikker på, at du vil slukke appen?</string>\n    <string name=\"app_closing\">Lukning af app</string>\n    <string name=\"stay\">Bliv på</string>\n    <string name=\"close\">Luk</string>\n    <string name=\"reset_image\">Nulstil billede</string>\n    <string name=\"reset_image_sub\">Billedændringer vil blive rullet tilbage til startværdierne</string>\n    <string name=\"values_reset\">Værdierne nulstilles korrekt</string>\n    <string name=\"reset\">Nulstil</string>\n    <string name=\"something_went_wrong\">Noget gik galt</string>\n    <string name=\"restart_app\">Genstart appen</string>\n    <string name=\"copied\">Kopieret til udklipsholderen</string>\n    <string name=\"exception\">Undtagelse</string>\n    <string name=\"edit_exif\">Rediger EXIF</string>\n    <string name=\"no_exif\">Ingen EXIF-data fundet</string>\n    <string name=\"add_tag\">Tilføj tag</string>\n    <string name=\"save\">Gem</string>\n    <string name=\"clear\">Klar</string>\n    <string name=\"clear_exif\">Ryd EXIF</string>\n    <string name=\"cancel\">Annuller</string>\n    <string name=\"clear_exif_sub\">Alle EXIF-data for billedet bliver slettet, og denne handling kan ikke fortrydes!</string>\n    <string name=\"presets\">Forudindstillinger</string>\n    <string name=\"image_not_saved\">Gemmer</string>\n    <string name=\"image_not_saved_sub\">Alle ikke gemte ændringer vil gå tabt, hvis du forlader stedet nu</string>\n    <string name=\"check_source_code_sub\">Få de seneste opdateringer, diskutere spørgsmål og meget mere</string>\n    <string name=\"single_edit\">Enkelt ændring</string>\n    <string name=\"single_edit_sub\">Ændre et enkelt billede</string>\n    <string name=\"pick_color\">Farvevælger</string>\n    <string name=\"pick_color_sub\">Vælg farve fra billede, kopier eller del den</string>\n    <string name=\"image\">Billede</string>\n    <string name=\"color\">Farve</string>\n    <string name=\"color_copied\">Farve kopieret</string>\n    <string name=\"crop_sub\">Beskær billedet</string>\n    <string name=\"version\">Version</string>\n    <string name=\"keep_exif\">Behold EXIF</string>\n    <string name=\"images\">Billeder: %d</string>\n    <string name=\"change_preview\">Visning af ændringer</string>\n    <string name=\"remove\">Fjern</string>\n    <string name=\"palette_sub\">Generer en farvepalet fra et givet billede</string>\n    <string name=\"generate_palette\">Generere palette</string>\n    <string name=\"palette\">Palet</string>\n    <string name=\"update\">Opdatering</string>\n    <string name=\"new_version\">Ny version %1$s</string>\n    <string name=\"unsupported_type\">Ikke understøttet type: %1$s</string>\n    <string name=\"no_palette\">Kan ikke generere en palet for det givne billede</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Output-mappe</string>\n    <string name=\"def\">Standard</string>\n    <string name=\"custom\">Tilpasset</string>\n    <string name=\"unspecified\">Uspecificeret</string>\n    <string name=\"device_storage\">Opbevaring af enheder</string>\n    <string name=\"by_bytes_resize\">Beskær i forhold til filstørrelse</string>\n    <string name=\"max_bytes\">Maksimal størrelse i KB</string>\n    <string name=\"by_bytes_resize_sub\">Ændre størrelsen på et billede efter en given størrelse i KB</string>\n    <string name=\"compare\">Sammenlign</string>\n    <string name=\"compare_sub\">Sammenligne to givne billeder</string>\n    <string name=\"pick_two_images\">Vælg to billeder til at starte med</string>\n    <string name=\"pick_images\">Vælg billeder</string>\n    <string name=\"settings\">Indstillinger</string>\n    <string name=\"night_mode\">Nattilstand</string>\n    <string name=\"dark\">Mørk</string>\n    <string name=\"light\">Lys</string>\n    <string name=\"system\">System</string>\n    <string name=\"dynamic_colors\">Dynamiske farver</string>\n    <string name=\"customization\">Tilpasning</string>\n    <string name=\"allow_image_monet\">Tillad billedmonetering</string>\n    <string name=\"allow_image_monet_sub\">Hvis den er aktiveret, vil app-farverne blive overtaget til dette billede, når du vælger et billede til redigering</string>\n    <string name=\"language\">Sprog</string>\n    <string name=\"amoled_mode\">Amoled-tilstand</string>\n    <string name=\"amoled_mode_sub\">Hvis den er aktiveret, indstilles overfladenes farve til absolut mørk i nattilstand</string>\n    <string name=\"color_scheme\">Farveskema</string>\n    <string name=\"color_red\">Rød</string>\n    <string name=\"color_green\">Grøn</string>\n    <string name=\"color_blue\">Blå</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Indsæt gyldig aRGB-kode.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Intet at indsætte</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Kan ikke ændre appens farvepalette, mens dynamiske farver er slået til</string>\n    <string name=\"pick_accent_color\">App-temaet vil være baseret på den farve, som du skal vælge</string>\n    <string name=\"about_app\">Om appen</string>\n    <string name=\"no_updates\">Ingen opdateringer fundet</string>\n    <string name=\"issue_tracker\">Problemløser</string>\n    <string name=\"issue_tracker_sub\">Send fejlrapporter og anmodninger om funktioner her</string>\n    <string name=\"help_translate\">Hjælp til at oversætte</string>\n    <string name=\"help_translate_sub\">Korriger oversættelsesfejl eller lokalisere projektet til andre sprog</string>\n    <string name=\"nothing_found_by_search\">Intet fundet ved din forespørgsel</string>\n    <string name=\"search_here\">Søg her</string>\n    <string name=\"dynamic_colors_sub\">Hvis den er aktiveret, vil appens farver blive tilpasset tapetets farver</string>\n    <string name=\"failed_to_save\">Det lykkedes ikke at gemme %d billede(r)</string>\n    <string name=\"primary\">Primært</string>\n    <string name=\"tertiary\">Tertiær</string>\n    <string name=\"secondary\">Sekundær</string>\n    <string name=\"border_thickness\">Tykkelse af kant</string>\n    <string name=\"surface\">Overflade</string>\n    <string name=\"values\">Værdier</string>\n    <string name=\"add\">Tilføj</string>\n    <string name=\"permission\">Tilladelse</string>\n    <string name=\"grant\">Tilskud</string>\n    <string name=\"permission_sub\">Appen skal have adgang til dit lager for at gemme billeder, det er nødvendigt, uden det kan den ikke fungere, så giv venligst tilladelse i den næste dialogboks</string>\n    <string name=\"grant_permission_manual\">Appen har brug for denne tilladelse for at fungere, giv den venligst manuelt</string>\n    <string name=\"external_storage\">Ekstern lagring</string>\n    <string name=\"monet_colors\">Monet farver</string>\n    <string name=\"donation_sub\">Denne applikation er helt gratis, men hvis du vil støtte udviklingen af projektet, kan du klikke her</string>\n    <string name=\"fab_alignment\">FAB-tilpasning</string>\n    <string name=\"check_updates\">Tjek for opdateringer</string>\n    <string name=\"check_updates_sub\">Hvis den er aktiveret, vises opdateringsdialogboksen efter opstart af appen</string>\n    <string name=\"zoom\">Billede zoom</string>\n    <string name=\"share\">Del</string>\n    <string name=\"prefix\">Præfiks</string>\n    <string name=\"filename\">Filenavn</string>\n    <string name=\"filter_sub\">Anvend enhver filterkæde på givne billeder</string>\n    <string name=\"filters\">Filtre</string>\n    <string name=\"light_aka_illumination\">Lys</string>\n    <string name=\"color_filter\">Farvefilter</string>\n    <string name=\"exposure\">Eksponering</string>\n    <string name=\"shadows\">Skygger</string>\n    <string name=\"haze\">Dis</string>\n    <string name=\"effect\">Effekt</string>\n    <string name=\"distance\">Afstand</string>\n    <string name=\"sharpen\">Skærpe</string>\n    <string name=\"black_and_white\">Sort og hvid</string>\n    <string name=\"crosshatch\">Krydsskravering</string>\n    <string name=\"spacing\">Mellemrum</string>\n    <string name=\"halftone\">Halvtone</string>\n    <string name=\"box_blur\">Boks sløring</string>\n    <string name=\"bilaterial_blur\">Bilateral sløring</string>\n    <string name=\"vignette\">Vignette</string>\n    <string name=\"start\">Start</string>\n    <string name=\"radius\">Radius</string>\n    <string name=\"bulge\">Bule</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"file_explorer_picker\">Filudforsker</string>\n    <string name=\"no_image\">Intet billede</string>\n    <string name=\"tint\">Farve</string>\n    <string name=\"limits_resize\">Ændre størrelse ud fra øvre grænser</string>\n    <string name=\"limits_resize_sub\">Tilpas størrelsen for at følge givne bredde- og højdemål. Billedforhold bevares</string>\n    <string name=\"quantizationLevels\">Kvantiseringsniveauer</string>\n    <string name=\"non_maximum_suppression\">Ikke maksimal undertrykkelse</string>\n    <string name=\"weak_pixel_inclusion\">Svag pixel inklusion</string>\n    <string name=\"stack_blur\">stak sløring</string>\n    <string name=\"reorder\">Genbestil</string>\n    <string name=\"luminance_threshold\">Luminanstærskel</string>\n    <string name=\"flexible_description\">Ændrer størrelsen på billeder til billeder med en lang side givet af parameteren Width eller Height, alle størrelsesberegninger vil blive udført efter lagring - bevarer billedformat</string>\n    <string name=\"emoji_sub\">Vælg hvilken emoji der skal vises på hovedskærmen</string>\n    <string name=\"add_file_size\">Tilføj filstørrelse</string>\n    <string name=\"add_file_size_sub\">Hvis det er aktiveret, tilføjes bredden og højden af det gemte billede til navnet på outputfilen</string>\n    <string name=\"delete_exif\">Slet EXIF</string>\n    <string name=\"delete_exif_sub\">Slet EXIF-metadata fra et par billeder</string>\n    <string name=\"image_preview_sub\">Forhåndsvis enhver type billeder: GIF, SVG og så videre</string>\n    <string name=\"image_source\">Billedkilde</string>\n    <string name=\"photo_picker\">Fotovælger</string>\n    <string name=\"gallery_picker\">Galleri</string>\n    <string name=\"photo_picker_sub\">Android moderne fotovælger, som vises nederst på skærmen, fungerer muligvis kun på Android 12+ og har også problemer med at modtage EXIF-metadata</string>\n    <string name=\"gallery_picker_sub\">Simpel galleribilledvælger, den fungerer kun, hvis du har den app</string>\n    <string name=\"file_explorer_picker_sub\">Brug GetContent hensigt til at vælge billede, virker overalt, men kan også have problemer med at modtage udvalgte billeder på nogle enheder, det er ikke min skyld</string>\n    <string name=\"options_arrangement\">Options arrangement</string>\n    <string name=\"edit\">Redigere</string>\n    <string name=\"order\">Bestille</string>\n    <string name=\"order_sub\">Skift rækkefølgen af værktøjer på hovedskærmen</string>\n    <string name=\"image_link\">Billed link</string>\n    <string name=\"fill\">Fylde</string>\n    <string name=\"fit\">Passe</string>\n    <string name=\"explicit_description\">Ændre billedstørrelse i forhold til brede og højde. Kan ændre proportioner</string>\n    <string name=\"brightness\">Lysstyrke</string>\n    <string name=\"contrast\">Kontrast</string>\n    <string name=\"hue\">Hue</string>\n    <string name=\"saturation\">Mætning</string>\n    <string name=\"add_filter\">Tilføj filter</string>\n    <string name=\"filter\">Filter</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"white_balance\">hvidbalance</string>\n    <string name=\"temperature\">Temperatur</string>\n    <string name=\"monochrome\">Monokrom</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Højdepunkter og skygger</string>\n    <string name=\"highlights\">Højdepunkter</string>\n    <string name=\"slope\">Hældning</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negativ</string>\n    <string name=\"solarize\">Solariser</string>\n    <string name=\"vibrance\">Livskraft</string>\n    <string name=\"line_width\">Linjebredde</string>\n    <string name=\"sobel_edge\">Sobel kant</string>\n    <string name=\"blur\">Slør</string>\n    <string name=\"cga_colorspace\">GCA farverum</string>\n    <string name=\"gaussian_blur\">Gaussisk sløring</string>\n    <string name=\"emboss\">Præg</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"end\">Ende</string>\n    <string name=\"kuwahara\">Kuwahara udjævning</string>\n    <string name=\"scale\">vægt</string>\n    <string name=\"distortion\">Forvrængning</string>\n    <string name=\"angle\">Vinkel</string>\n    <string name=\"swirl\">Hvirvel</string>\n    <string name=\"dilation\">Dilatation</string>\n    <string name=\"sphere_refraction\">Kuglebrydning</string>\n    <string name=\"refractive_index\">Brydningsindeks</string>\n    <string name=\"glass_sphere_refraction\">Glaskuglebrydning</string>\n    <string name=\"color_matrix\">Farve matrix</string>\n    <string name=\"opacity\">Gennemsigtighed</string>\n    <string name=\"sketch\">Skitse</string>\n    <string name=\"threshold\">Grænseværdi</string>\n    <string name=\"smooth_toon\">Glat tone</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterize</string>\n    <string name=\"lookup\">Kig op</string>\n    <string name=\"convolution3x3\">Convolution 3x3</string>\n    <string name=\"rgb_filter\">RGB filter</string>\n    <string name=\"false_color\">Falsk farve</string>\n    <string name=\"first_color\">Første farve</string>\n    <string name=\"second_color\">Anden farve</string>\n    <string name=\"fast_blur\">Hurtig sløring</string>\n    <string name=\"blur_size\">Sløringsstørrelse</string>\n    <string name=\"blur_center_x\">Sløring i midten x</string>\n    <string name=\"blur_center_y\">Sløring i midten y</string>\n    <string name=\"zoom_blur\">Zoom sløring</string>\n    <string name=\"color_balance\">Farvebalance</string>\n    <string name=\"image_preview\">Forhåndsvisning af billede</string>\n    <string name=\"load_image_from_net\">Indlæs billede fra nettet</string>\n    <string name=\"load_image_from_net_sub\">Indlæs et hvilket som helst billede fra internettet, se et eksempel på det, zoom og gem eller rediger det, hvis du vil</string>\n    <string name=\"content_scale\">Indholdsskala</string>\n    <string name=\"emojis_count\">Emojis tæller</string>\n    <string name=\"sequence_num\">sekvensNum</string>\n    <string name=\"original_filename\">originalt filnavn</string>\n    <string name=\"add_original_filename\">Tilføj originalt filnavn</string>\n    <string name=\"add_original_filename_sub\">Hvis det er aktiveret, tilføjes det originale filnavn i navnet på outputbilledet</string>\n    <string name=\"filename_not_work_with_photopicker\">Tilføjelse af originalt filnavn virker ikke, hvis billedkilden til billedvælgeren er valgt</string>\n    <string name=\"replace_sequence_number\">Udskift sekvensnummer</string>\n    <string name=\"replace_sequence_number_sub\">Hvis aktiveret, erstatter standardtidsstemplet til billedsekvensnummeret, hvis du bruger batchbehandling</string>\n    <string name=\"cache_size\">Cache størrelse</string>\n    <string name=\"activate_files\">Du deaktiverede Filer-appen, aktiver den for at bruge denne funktion</string>\n    <string name=\"draw\">Tegne</string>\n    <string name=\"draw_sub\">Tegn på billede som i en skitsebog, eller tegn på selve baggrunden</string>\n    <string name=\"paint_color\">Maling farve</string>\n    <string name=\"secondary_customization\">Sekundær tilpasning</string>\n    <string name=\"draw_on_image_sub\">Vælg et billede og tegn noget på det</string>\n    <string name=\"cipher_sub\">Krypter og dekrypter enhver fil (ikke kun billedet) baseret på forskellige algoritmer</string>\n    <string name=\"pick_file\">Vælg fil</string>\n    <string name=\"encrypt\">Krypter</string>\n    <string name=\"decryption\">Dekryptering</string>\n    <string name=\"implementation_sub\">AES-256, GCM-tilstand, ingen polstring, 12 bytes tilfældige IV\\'er. Nøgler bruges som SHA-3 hashes (256 bit).</string>\n    <string name=\"image_size_warning\">Hvis du forsøger at gemme billedet med de aktuelle højde/bredde-parametre, risikerer du at appen crasher og du taber dit arbejder. Du fortsætter derfor på EGEN RISIKO!</string>\n    <string name=\"tools\">Værktøjer</string>\n    <string name=\"group_options_by_type\">Gruppér muligheder efter type</string>\n    <string name=\"edit_screenshot\">Rediger skærmbillede</string>\n    <string name=\"fallback_option\">Fallback mulighed</string>\n    <string name=\"skip\">Springe</string>\n    <string name=\"copy\">Kopi</string>\n    <string name=\"warning_bytes\">Lagring i tilstanden %1$s kan være ustabil, fordi det er et tabsfrit format</string>\n    <string name=\"invalid_password_or_not_encrypted\">Ugyldig adgangskode eller valgt fil er ikke krypteret</string>\n    <string name=\"features\">Funktioner</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"found_s\">Fundet %1$s</string>\n    <string name=\"screenshot\">Skærmbillede</string>\n    <string name=\"paint_alpha\">Male alfa</string>\n    <string name=\"draw_on_image\">Tegn på billede</string>\n    <string name=\"draw_on_background\">Tegn på baggrund</string>\n    <string name=\"draw_on_background_sub\">Vælg baggrundsfarve og tegn oven på den</string>\n    <string name=\"background_color\">Baggrundsfarve</string>\n    <string name=\"cipher\">Chiffer</string>\n    <string name=\"auto_cache_clearing_sub\">Hvis aktiveret, vil app-cachen blive ryddet ved app-start</string>\n    <string name=\"create\">skab</string>\n    <string name=\"group_options_by_type_sub\">Grupper muligheder på hovedskærmen af deres type i stedet for tilpasset listearrangement</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Kan ikke ændre arrangement, mens valgmulighedsgruppering er aktiveret</string>\n    <string name=\"features_sub\">Password-baseret kryptering af filer. Fortsatte filer kan gemmes i den valgte mappe eller deles. Dekrypterede filer kan også åbnes direkte.</string>\n    <string name=\"auto_cache_clearing\">Automatisk cacherydning</string>\n    <string name=\"decrypt\">Dekrypter</string>\n    <string name=\"pick_file_to_start\">Vælg fil for at starte</string>\n    <string name=\"encryption\">Kryptering</string>\n    <string name=\"key\">Nøgle</string>\n    <string name=\"store_file_desc\">Gem denne fil på din enhed, eller brug delehandlingen til at placere den, hvor du vil</string>\n    <string name=\"implementation\">Implementering</string>\n    <string name=\"compatibility\">Kompatibilitet</string>\n    <string name=\"file_size\">Filstørrelse</string>\n    <string name=\"file_size_sub\">Den maksimale filstørrelse er begrænset af Android OS og den tilgængelige hukommelse, hvilket naturligvis afhænger af din enhed. \\nBemærk venligst: Hukommelsen er ikke lager.</string>\n    <string name=\"compatibility_sub\">Bemærk venligst, at kompatibilitet med anden filkrypteringssoftware eller -tjenester ikke er garanteret. En lidt anderledes nøglebehandling eller chifferkonfiguration kan være årsager til inkompatibilitet.</string>\n    <string name=\"file_proceed\">Filen er behandlet</string>\n    <string name=\"enhanced_pixelation\">Forbedret pixelering</string>\n    <string name=\"stroke_pixelation\">Slagpixelering</string>\n    <string name=\"side\">Side</string>\n    <string name=\"strength\">Styrke</string>\n    <string name=\"contact_me\">Kontakt mig</string>\n    <string name=\"font_scale\">Skrift skala</string>\n    <string name=\"trim_image_sub\">Gennemsigtige mellemrum omkring billedet vil blive beskåret</string>\n    <string name=\"erase_background\">Slet baggrund</string>\n    <string name=\"delete\">Slet</string>\n    <string name=\"aspect_ratio\">Størrelsesforhold</string>\n    <string name=\"saved_to_without_filename\">Gemt i mappen %1$s</string>\n    <string name=\"symbols\">Symboler</string>\n    <string name=\"image_crop_mask_sub\">Brug denne masketype til at oprette maske fra et givet billede, bemærk at billedet SKAL have alfakanal (gennemsigtig baggrund)</string>\n    <string name=\"enable_emoji\">Aktiver emoji</string>\n    <string name=\"randomize_filename\">Tilfældig filnavn</string>\n    <string name=\"restore_background\">Gendan baggrund</string>\n    <string name=\"restore_sub\">Gendan appindstillinger fra tidligere genereret fil</string>\n    <string name=\"effort_sub\">En værdi på %1$s betyder en hurtig komprimering, hvilket resulterer i en relativt stor filstørrelse. %2$s betyder en langsommere komprimering, hvilket resulterer i en mindre fil.</string>\n    <string name=\"segmentation_mode_single_column\">Enkelt kolonne</string>\n    <string name=\"glitch\">Fejl</string>\n    <string name=\"amount\">Beløb</string>\n    <string name=\"seed\">Frø</string>\n    <string name=\"delete_mask_warn\">Du er ved at slette den valgte filtermaske. Denne handling kan ikke fortrydes</string>\n    <string name=\"color_anomaly\">Farveanomali</string>\n    <string name=\"no_such_directory\">Der blev ikke fundet nogen \\\"%1$s\\\"-mappe. Vi har ændret den til standard, gem venligst filen igen</string>\n    <string name=\"clipboard\">Udklipsholder</string>\n    <string name=\"auto_pin\">Automatisk pin</string>\n    <string name=\"overwrite_files\">Overskriv filer</string>\n    <string name=\"empty\">Tom</string>\n    <string name=\"suffix\">Suffiks</string>\n    <string name=\"free\">Gratis</string>\n    <string name=\"presets_sub\" formatted=\"false\">Hvis du har valgt forudindstilling 125, vil billedet blive gemt som 125 % størrelse af det originale billede. Hvis du vælger forudindstilling 50, vil billedet blive gemt med 50 % størrelse</string>\n    <string name=\"presets_sub_bytes\">Forudindstilling her bestemmer % af filstørrelsen. Hvis du vælger 50% på 5mb billede, vil du få 2,5mb billede efter lagring</string>\n    <string name=\"randomize_filename_sub\">Hvis det er aktiveret, vil outputfilnavnet være helt tilfældigt</string>\n    <string name=\"tg_chat_sub\">Diskuter appen og få feedback fra andre brugere. Du kan også få betaopdateringer og indsigt her.</string>\n    <string name=\"restore\">Gendan</string>\n    <string name=\"backup_sub\">Sikkerhedskopier dine appindstillinger til en fil</string>\n    <string name=\"settings_restored\">Indstillinger blev gendannet</string>\n    <string name=\"delete_color_scheme_warn\">Du er ved at slette det valgte farveskema. Denne handling kan ikke fortrydes</string>\n    <string name=\"delete_color_scheme_title\">Slet palette</string>\n    <string name=\"text\">Tekst</string>\n    <string name=\"defaultt\">Standard</string>\n    <string name=\"emotions\">Følelser</string>\n    <string name=\"food_and_drink\">Mad og drikke</string>\n    <string name=\"nature_and_animals\">Natur og Dyr</string>\n    <string name=\"objects\">Objekter</string>\n    <string name=\"travels_and_places\">Rejser og steder</string>\n    <string name=\"activities\">Aktiviteter</string>\n    <string name=\"background_remover\">Baggrundsfjerner</string>\n    <string name=\"background_remover_sub\">Fjern baggrunden fra billedet ved at tegne eller brug indstillingen Auto</string>\n    <string name=\"trim_image\">Trim billede</string>\n    <string name=\"keep_exif_sub\">Originale billedmetadata vil blive bevaret</string>\n    <string name=\"auto_erase_background\">Slet automatisk baggrund</string>\n    <string name=\"restore_image\">Gendan billede</string>\n    <string name=\"erase_mode\">Slet tilstand</string>\n    <string name=\"blur_radius\">Sløringsradius</string>\n    <string name=\"pipette\">Pipette</string>\n    <string name=\"draw_mode\">Tegnetilstand</string>\n    <string name=\"create_issue\">Opret problem</string>\n    <string name=\"something_went_wrong_emphasis\">Ups… Noget gik galt. Du kan skrive til mig ved at bruge mulighederne nedenfor, og jeg vil prøve at finde en løsning</string>\n    <string name=\"resize_and_convert\">Tilpas størrelse og konverter</string>\n    <string name=\"resize_and_convert_sub\">Skift størrelse på givne billeder eller konverter dem til andre formater. EXIF-metadata kan også redigeres her, hvis du vælger et enkelt billede.</string>\n    <string name=\"analytics\">Analytics</string>\n    <string name=\"analytics_sub\">Tillad indsamling af anonym appbrugsstatistik</string>\n    <string name=\"image_exif_warning\">I øjeblikket tillader formatet %1$s kun læsning af EXIF-metadata på Android. Outputbilledet vil slet ikke have metadata, når det er gemt.</string>\n    <string name=\"wait\">Vente</string>\n    <string name=\"updates\">Opdateringer</string>\n    <string name=\"allow_betas\">Tillad betaversioner</string>\n    <string name=\"allow_betas_sub\">Opdateringskontrol inkluderer beta-appversioner, hvis den er aktiveret</string>\n    <string name=\"draw_arrows\">Tegn pile</string>\n    <string name=\"draw_arrows_sub\">Hvis aktiveret, vil tegnestien blive repræsenteret som en pegepil</string>\n    <string name=\"horizontal\">Vandret</string>\n    <string name=\"scale_small_images_to_large\">Skaler små billeder til store</string>\n    <string name=\"vertical\">Lodret</string>\n    <string name=\"scale_small_images_to_large_sub\">Små billeder vil blive skaleret til det største i sekvensen, hvis det er aktiveret</string>\n    <string name=\"images_order\">Billedrækkefølge</string>\n    <string name=\"pixelation\">Pixelering</string>\n    <string name=\"enhanced_diamond_pixelation\">Forbedret diamantpixelering</string>\n    <string name=\"diamond_pixelation\">Diamantpixelering</string>\n    <string name=\"circle_pixelation\">Cirkelpixelering</string>\n    <string name=\"enhanced_circle_pixelation\">Forbedret cirkelpixelering</string>\n    <string name=\"replace_color\">Udskift farve</string>\n    <string name=\"color_to_replace\">Farve der skal udskiftes</string>\n    <string name=\"target_color\">Målfarve</string>\n    <string name=\"color_to_remove\">Farve der skal fjernes</string>\n    <string name=\"remove_color\">Fjern farve</string>\n    <string name=\"fading_edges\">Faldende kanter</string>\n    <string name=\"disabled\">handicappet</string>\n    <string name=\"both\">Begge</string>\n    <string name=\"search_option\">Søg</string>\n    <string name=\"search_option_sub\">Gør det muligt at søge gennem alle tilgængelige værktøjer på hovedskærmen</string>\n    <string name=\"pdf_tools_sub\">Betjen med PDF-filer: Forhåndsvisning, Konverter til batch af billeder eller opret et fra givne billeder</string>\n    <string name=\"preview_pdf\">Forhåndsvisning af PDF</string>\n    <string name=\"pdf_to_images\">PDF til billeder</string>\n    <string name=\"images_to_pdf\">Billeder til PDF</string>\n    <string name=\"preview_pdf_sub\">Enkel PDF-forhåndsvisning</string>\n    <string name=\"pdf_to_images_sub\">Konverter PDF til billeder i givet outputformat</string>\n    <string name=\"images_to_pdf_sub\">Pak givne billeder ind i output PDF-fil</string>\n    <string name=\"add_mask\">Tilføj maske</string>\n    <string name=\"mask_indexed\">Maske %d</string>\n    <string name=\"mask_preview_sub\">Tegnet filtermaske vil blive gengivet for at vise dig det omtrentlige resultat</string>\n    <string name=\"delete_mask\">Slet maske</string>\n    <string name=\"simple_variants\">Simple varianter</string>\n    <string name=\"highlighter\">Highlighter</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Pen</string>\n    <string name=\"privacy_blur\">Sløring af privatliv</string>\n    <string name=\"highlighter_sub\">Tegn semi-transparente, skærpede highlighter-baner</string>\n    <string name=\"neon_sub\">Tilføj en glødende effekt til dine tegninger</string>\n    <string name=\"pen_sub\">Standard en, enklest - kun farven</string>\n    <string name=\"privacy_blur_sub\">Slører billedet under den tegnede sti for at sikre alt, hvad du vil skjule</string>\n    <string name=\"pixelation_sub\">Svarende til sløring af privatlivets fred, men pixelerer i stedet for sløring</string>\n    <string name=\"auto_rotate_limits\">Automatisk rotation</string>\n    <string name=\"auto_rotate_limits_sub\">Tillader, at begrænsningsboksen anvendes til billedorientering</string>\n    <string name=\"draw_path_mode\">Tegnestitilstand</string>\n    <string name=\"double_line_arrow\">Dobbelt linje pil</string>\n    <string name=\"free_drawing\">Gratis tegning</string>\n    <string name=\"double_arrow\">Dobbelt pil</string>\n    <string name=\"line_arrow\">Linje pil</string>\n    <string name=\"double_line_arrow_sub\">Tegner en dobbeltpegende pil fra startpunkt til slutpunkt som en linje</string>\n    <string name=\"double_arrow_sub\">Tegner en dobbeltpegende pil fra en given sti</string>\n    <string name=\"outlined_oval\">Skitseret Oval</string>\n    <string name=\"outlined_rect\">Skitseret Rect</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"auto_pin_sub\">Tilføjer automatisk gemt billede til udklipsholder, hvis det er aktiveret</string>\n    <string name=\"vibration\">Vibration</string>\n    <string name=\"vibration_strength\">Vibrationsstyrke</string>\n    <string name=\"overwrite_file_requirements\">For at overskrive filer skal du bruge \\\"Explorer\\\" billedkilde, prøv gentag billeder, vi har ændret billedkilde til den nødvendige</string>\n    <string name=\"overwrite_files_sub\">Den originale fil vil blive erstattet med en ny i stedet for at gemme i den valgte mappe, denne mulighed skal være billedkilden \\\"Explorer\\\" eller GetContent, når du skifter dette, indstilles den automatisk</string>\n    <string name=\"catmull\">Kattemuld</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Grundlæggende</string>\n    <string name=\"bicubic_sub\">Bedre skaleringsmetoder omfatter Lanczos-resampling og Mitchell-Netravali-filtre</string>\n    <string name=\"nearest_sub\">En af de nemmere måder at øge størrelsen på ved at erstatte hver pixel med et antal pixels af samme farve</string>\n    <string name=\"basic_sub\">Den enkleste android-skaleringstilstand, der bruges i næsten alle apps</string>\n    <string name=\"catmull_sub\">Metode til jævn interpolering og resampling af et sæt kontrolpunkter, der almindeligvis bruges i computergrafik til at skabe jævne kurver</string>\n    <string name=\"hann_sub\">Vinduesfunktion anvendes ofte i signalbehandling for at minimere spektral lækage og forbedre nøjagtigheden af frekvensanalyse ved at tilspidse kanterne af et signal</string>\n    <string name=\"hermite_sub\">Matematisk interpolationsteknik, der bruger værdierne og afledte ved endepunkterne af et kurvesegment til at generere en jævn og kontinuerlig kurve</string>\n    <string name=\"lanczos_sub\">Resampling-metode, der opretholder interpolation af høj kvalitet ved at anvende en vægtet sinc-funktion på pixelværdierne</string>\n    <string name=\"mitchell_sub\">Resampling-metode, der bruger et foldningsfilter med justerbare parametre for at opnå en balance mellem skarphed og anti-aliasing i det skalerede billede</string>\n    <string name=\"download\">Hent</string>\n    <string name=\"no_connection\">Ingen forbindelse, tjek det og prøv igen for at downloade togmodeller</string>\n    <string name=\"downloaded_languages\">Downloadede sprog</string>\n    <string name=\"segmentation_mode\">Segmenteringstilstand</string>\n    <string name=\"rate_app\">Bedøm app</string>\n    <string name=\"segmentation_mode_osd_only\">Kun scriptregistrering &amp;</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatisk orientering &amp; Scriptgenkendelse</string>\n    <string name=\"segmentation_mode_auto_only\">Kun auto</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Enkelt blok lodret tekst</string>\n    <string name=\"segmentation_mode_single_block\">Enkelt blok</string>\n    <string name=\"segmentation_mode_single_line\">Enkelt linje</string>\n    <string name=\"segmentation_mode_single_word\">Enkelt ord</string>\n    <string name=\"segmentation_mode_circle_word\">Cirkel ord</string>\n    <string name=\"segmentation_mode_single_char\">Enkelt forkullet</string>\n    <string name=\"segmentation_mode_sparse_text\">Sparsom tekst</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Sparsom tekstorientering &amp; Scriptdetektion</string>\n    <string name=\"segmentation_mode_raw_line\">Rå linje</string>\n    <string name=\"delete_language_sub\">Vil du slette sprog \\\"%1$s\\\" OCR-træningsdata for alle genkendelsestyper, eller kun for den valgte (%2$s)?</string>\n    <string name=\"current\">Nuværende</string>\n    <string name=\"all\">Alle</string>\n    <string name=\"gradient_type_linear\">Lineær</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Feje</string>\n    <string name=\"gradient_type\">Gradient type</string>\n    <string name=\"center_x\">Center X</string>\n    <string name=\"center_y\">Center Y</string>\n    <string name=\"tile_mode\">Flisetilstand</string>\n    <string name=\"brightness_enforcement\">Håndhævelse af lysstyrke</string>\n    <string name=\"screen\">Skærm</string>\n    <string name=\"gradient_maker_type_image\">Gradient Overlay</string>\n    <string name=\"watermarking\">Vandmærke</string>\n    <string name=\"watermarking_sub\">Dæk billeder med brugerdefinerbare tekst/billede vandmærker</string>\n    <string name=\"repeat_watermark\">Gentag vandmærke</string>\n    <string name=\"repeat_watermark_sub\">Gentager vandmærke over billede i stedet for enkelt på en given position</string>\n    <string name=\"offset_x\">Offset X</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermarking_image_sub\">Dette billede vil blive brugt som mønster til vandmærkning</string>\n    <string name=\"text_color\">Tekst farve</string>\n    <string name=\"gif_tools\">GIF værktøjer</string>\n    <string name=\"gif_tools_sub\">Konverter billeder til GIF-billede eller udtræk rammer fra givet GIF-billede</string>\n    <string name=\"gif_type_to_image\">GIF til billeder</string>\n    <string name=\"gif_type_to_image_sub\">Konverter GIF-fil til batch af billeder</string>\n    <string name=\"gif_type_to_gif_sub\">Konverter batch af billeder til GIF-fil</string>\n    <string name=\"gif_type_to_gif\">Billeder til GIF</string>\n    <string name=\"select_gif_image_to_start\">Vælg GIF-billede for at starte</string>\n    <string name=\"use_size_of_first_frame\">Brug størrelsen af den første ramme</string>\n    <string name=\"use_size_of_first_frame_sub\">Udskift den angivne størrelse med de første rammemål</string>\n    <string name=\"repeat_count\">Gentag optælling</string>\n    <string name=\"frame_delay\">Frame Delay</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizier</string>\n    <string name=\"gray_scale\">Gråskala</string>\n    <string name=\"bayer_two_dithering\">Bayer to og to dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer tre af tre dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer fire af fire dithering</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Anvender stykkevis definerede bikubiske polynomielle funktioner til jævnt at interpolere og tilnærme en kurve eller overflade, fleksibel og kontinuert formrepræsentation</string>\n    <string name=\"native_stack_blur\">Indbygget stak sløring</string>\n    <string name=\"enhanced_glitch\">Forbedret fejl</string>\n    <string name=\"channel_shift_x\">Kanalskift X</string>\n    <string name=\"channel_shift_y\">Kanalskift Y</string>\n    <string name=\"corruption_size\">Korruptionsstørrelse</string>\n    <string name=\"corruption_shift_x\">Korruption Shift X</string>\n    <string name=\"corruption_shift_y\">Korruptionsskift Y</string>\n    <string name=\"tent_blur\">Telt sløring</string>\n    <string name=\"side_fade\">Side fade</string>\n    <string name=\"top\">Top</string>\n    <string name=\"bottom\">Bund</string>\n    <string name=\"anisotropic_diffusion\">Anisotropisk diffusion</string>\n    <string name=\"diffusion\">Diffusion</string>\n    <string name=\"conduction\">Ledning</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmisk tonekortlægning</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"color_matrix_4x4\">Farve Matrix 4x4</string>\n    <string name=\"color_matrix_3x3\">Farvematrix 3x3</string>\n    <string name=\"simple_effects\">Simple effekter</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomali</string>\n    <string name=\"deutaromaly\">Deutaromali</string>\n    <string name=\"protonomaly\">Protonomali</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Nattesyn</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Akromatomali</string>\n    <string name=\"achromatopsia\">Achromatopsi</string>\n    <string name=\"grain\">Korn</string>\n    <string name=\"unsharp\">Uskarp</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Orange dis</string>\n    <string name=\"pink_dream\">Lyserød drøm</string>\n    <string name=\"golden_hour\">Gyldne time</string>\n    <string name=\"hot_summer\">Varm sommer</string>\n    <string name=\"purple_mist\">Lilla tåge</string>\n    <string name=\"sunrise\">Solopgang</string>\n    <string name=\"lemonade_light\">Lemonade lys</string>\n    <string name=\"spectral_fire\">Spektral ild</string>\n    <string name=\"fantasy_landscape\">Fantasy Landskab</string>\n    <string name=\"electric_gradient\">Elektrisk gradient</string>\n    <string name=\"caramel_darkness\">Karamelmørke</string>\n    <string name=\"space_portal\">Rumportal</string>\n    <string name=\"red_swirl\">Rød hvirvel</string>\n    <string name=\"digital_code\">Digital kode</string>\n    <string name=\"icon_shape\">Ikon form</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Skære af</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Overgang</string>\n    <string name=\"peak\">Spids</string>\n    <string name=\"images_overwritten\">Billeder overskrevet ved den oprindelige destination</string>\n    <string name=\"cannot_change_image_format\">Kan ikke ændre billedformat, mens indstillingen for overskrivning af filer er aktiveret</string>\n    <string name=\"emoji_as_color_scheme\">Emoji som farveskema</string>\n    <string name=\"emoji_as_color_scheme_sub\">Bruger emoji primærfarve som app-farveskema i stedet for manuelt defineret</string>\n    <string name=\"tg_chat\">Telegram chat</string>\n    <string name=\"crop_mask\">Beskær maske</string>\n    <string name=\"using_large_fonts_warn\">Brug af store skriftstørrelser kan forårsage fejl i brugergrænsefladen og problemer, som ikke bliver rettet. Brug forsigtigt.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz Ææ Øø Åå 0123456789 !?</string>\n    <string name=\"crop_description\">Billeder vil blive beskåret fra midten til den indtastede størrelse. Lærredet vil blive udvidet med en given baggrundsfarve, hvis billedet er mindre end de indtastede dimensioner.</string>\n    <string name=\"tolerance\">Tolerance</string>\n    <string name=\"recode\">Omkode</string>\n    <string name=\"erode\">Erodere</string>\n    <string name=\"horizontal_wind_stagger\">Vandret vindsvingning</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"fast_bilaterial_blur\">Hurtig bilateral sløring</string>\n    <string name=\"poisson_blur\">Poisson sløring</string>\n    <string name=\"crystallize\">Krystalliser</string>\n    <string name=\"stroke_color\">Slagfarve</string>\n    <string name=\"fractal_glass\">Fraktal glas</string>\n    <string name=\"amplitude\">Amplitude</string>\n    <string name=\"marble\">Marmor</string>\n    <string name=\"turbulence\">Turbulens</string>\n    <string name=\"oil\">Olie</string>\n    <string name=\"water_effect\">Vand effekt</string>\n    <string name=\"just_size\">Størrelse</string>\n    <string name=\"frequency_x\">Frekvens X</string>\n    <string name=\"frequency_y\">Frekvens Y</string>\n    <string name=\"amplitude_x\">Amplitude X</string>\n    <string name=\"amplitude_y\">Amplitude Y</string>\n    <string name=\"perlin_distortion\">Perlin forvrængning</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"full_filter\">Fuldt filter</string>\n    <string name=\"start_position\">Start</string>\n    <string name=\"center_position\">Centrum</string>\n    <string name=\"end_position\">Ende</string>\n    <string name=\"full_filter_sub\">Anvend eventuelle filterkæder på givne billeder eller enkeltbilleder</string>\n    <string name=\"gradient_maker\">Gradient Maker</string>\n    <string name=\"gradient_maker_sub\">Opret gradient af given outputstørrelse med tilpassede farver og udseendetype</string>\n    <string name=\"speed\">Fart</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"pdf_tools\">PDF-værktøjer</string>\n    <string name=\"rate\">Sats</string>\n    <string name=\"rate_app_sub\">Denne app er helt gratis, hvis du vil have den til at blive større, så stjerne projektet på Github 😄</string>\n    <string name=\"vintage\">Årgang</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"warm\">Varm</string>\n    <string name=\"cool\">Fedt nok</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"tile_mode_repeated\">Gentaget</string>\n    <string name=\"tile_mode_mirror\">Spejl</string>\n    <string name=\"tile_mode_clamp\">Klemme</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"color_stops\">Farve stopper</string>\n    <string name=\"add_color\">Tilføj farve</string>\n    <string name=\"properties\">Ejendomme</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"arrow\">Pil</string>\n    <string name=\"line\">Linje</string>\n    <string name=\"free_drawing_sub\">Tegner sti som inputværdi</string>\n    <string name=\"line_sub\">Tegner stien fra startpunkt til slutpunkt som en linje</string>\n    <string name=\"line_arrow_sub\">Tegner en pil fra startpunkt til slutpunkt som en linje</string>\n    <string name=\"arrow_sub\">Tegner en pil fra en given sti</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"oval_sub\">Tegner oval fra startpunkt til slutpunkt</string>\n    <string name=\"rect_sub\">Tegner ret fra startpunkt til slutpunkt</string>\n    <string name=\"outlined_oval_sub\">Tegner ovalt skitseret fra startpunkt til slutpunkt</string>\n    <string name=\"outlined_rect_sub\">Tegner skitseret rekt fra startpunkt til slutpunkt</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">To Rækker Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falsk Floyd Steinberg Dithering</string>\n    <string name=\"left_to_right_dithering\">Venstre til højre dithering</string>\n    <string name=\"random_dithering\">Tilfældig dithering</string>\n    <string name=\"simple_threshold_dithering\">Simpel Threshold Dithering</string>\n    <string name=\"max_colors_count\">Max farveantal</string>\n    <string name=\"crashlytics_sub\">Dette gør det muligt for appen at indsamle nedbrudsrapporter automatisk</string>\n    <string name=\"mask_color\">Maske farve</string>\n    <string name=\"mask_preview\">Forhåndsvisning af maske</string>\n    <string name=\"scale_mode\">Skaleringstilstand</string>\n    <string name=\"bilinear\">Bilineær</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Nærmeste</string>\n    <string name=\"default_value\">Standard værdi</string>\n    <string name=\"value_in_range\">Værdi i området %1$s - %2$s</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Rumlig Sigma</string>\n    <string name=\"median_blur\">Median sløring</string>\n    <string name=\"bicubic\">Bikubisk</string>\n    <string name=\"bilinear_sub\">Lineær (eller bilineær, i to dimensioner) interpolation er typisk god til at ændre størrelsen på et billede, men forårsager en uønsket blødgøring af detaljer og kan stadig være noget takket</string>\n    <string name=\"spline_sub\">Anvender stykkevis definerede polynomielle funktioner til jævnt at interpolere og tilnærme en kurve eller overflade, fleksibel og kontinuerlig formrepræsentation</string>\n    <string name=\"only_clip\">Kun klip</string>\n    <string name=\"only_clip_sub\">Gem til lager vil ikke blive udført, og billedet vil kun blive forsøgt at lægge i udklipsholderen</string>\n    <string name=\"icon_shape_sub\">Tilføjer beholder med valgt form under de førende ikoner for kort</string>\n    <string name=\"image_stitching\">Billedsøm</string>\n    <string name=\"image_stitching_sub\">Kombiner de givne billeder for at få et stort</string>\n    <string name=\"saved_to\">Gemt i mappen %1$s med navnet %2$s</string>\n    <string name=\"gradient_maker_type_image_sub\">Komponer en hvilken som helst gradient af toppen af et givet billede</string>\n    <string name=\"transformations\">Transformationer</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Bruger kamera til at tage billede, bemærk at det kun er muligt at få ét billede fra denne billedkilde</string>\n    <string name=\"pick_at_least_two_images\">Vælg mindst 2 billeder</string>\n    <string name=\"output_image_scale\">Output billedskala</string>\n    <string name=\"image_orientation\">Billedorientering</string>\n    <string name=\"colorful_swirl\">Farverig hvirvel</string>\n    <string name=\"soft_spring_light\">Blødt forårslys</string>\n    <string name=\"autumn_tones\">Efterårs toner</string>\n    <string name=\"lavender_dream\">Lavendel drøm</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"night_magic\">Nattemagi</string>\n    <string name=\"color_explosion\">Farveeksplosion</string>\n    <string name=\"futuristic_gradient\">Futuristisk gradient</string>\n    <string name=\"green_sun\">Grøn Sol</string>\n    <string name=\"rainbow_world\">Rainbow World</string>\n    <string name=\"deep_purple\">Mørke lilla</string>\n    <string name=\"watermark_type\">Vandmærke Type</string>\n    <string name=\"overlay_mode\">Overlejringstilstand</string>\n    <string name=\"pixel_size\">Pixel størrelse</string>\n    <string name=\"lock_draw_orientation\">Lås tegneretningen</string>\n    <string name=\"reset_settings_sub\">Dette vil rulle dine indstillinger tilbage til standardværdierne. Bemærk, at dette ikke kan fortrydes uden en sikkerhedskopifil nævnt ovenfor.</string>\n    <string name=\"lock_draw_orientation_sub\">Hvis det er aktiveret i tegnetilstand, vil skærmen ikke rotere</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"use_lasso\">Brug Lasso</string>\n    <string name=\"use_lasso_sub\">Bruger Lasso som i tegnetilstand til at udføre sletning</string>\n    <string name=\"original_image_preview_alpha\">Forhåndsvisning af originalt billede Alpha</string>\n    <string name=\"mask_filter\">Maskefilter</string>\n    <string name=\"mask_filter_sub\">Anvend filterkæder på givne maskerede områder, hvert maskeområde kan have sit eget sæt af filtre</string>\n    <string name=\"masks\">Masker</string>\n    <string name=\"random_emojis_sub\">Appbar-emoji vil løbende blive ændret tilfældigt i stedet for at bruge den valgte</string>\n    <string name=\"random_emojis\">Tilfældige emojis</string>\n    <string name=\"random_emojis_error\">Kan ikke bruge tilfældig emojivalg, mens emojis er deaktiveret</string>\n    <string name=\"emoji_selection_error\">Kan ikke vælge en emoji, mens du vælger en tilfældig aktiveret</string>\n    <string name=\"check_for_updates\">Søg efter opdateringer</string>\n    <string name=\"effort\">Indsats</string>\n    <string name=\"backup_and_restore\">Backup og genskab</string>\n    <string name=\"backup\">Backup</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Ødelagt fil eller ikke en sikkerhedskopi</string>\n    <string name=\"font\">Skrifttype</string>\n    <string name=\"saving_almost_complete\">Lagring næsten fuldført. Hvis du annullerer nu, skal du gemme igen.</string>\n    <string name=\"brush_softness\">Børstes blødhed</string>\n    <string name=\"donation\">Donation</string>\n    <string name=\"old_tv\">Gammelt tv</string>\n    <string name=\"shuffle_blur\">Bland sløring</string>\n    <string name=\"recognize_text\">OCR (genkend tekst)</string>\n    <string name=\"recognize_text_sub\">Genkend tekst fra et givet billede, 120+ sprog understøttet</string>\n    <string name=\"picture_has_no_text\">Billedet har ingen tekst, eller appen fandt det ikke</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Genkendelsestype</string>\n    <string name=\"fast\">Hurtig</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"best\">Bedst</string>\n    <string name=\"no_data\">Ingen data</string>\n    <string name=\"download_description\">For at Tesseract OCR fungerer korrekt, skal yderligere træningsdata (%1$s) downloades til din enhed. \\nVil du downloade %2$s-data?</string>\n    <string name=\"available_languages\">Tilgængelige sprog</string>\n    <string name=\"restore_background_sub\">Pensel vil gendanne baggrunden i stedet for at slette</string>\n    <string name=\"horizontal_grid\">Vandret gitter</string>\n    <string name=\"vertical_grid\">Lodret gitter</string>\n    <string name=\"stitch_mode\">Sømtilstand</string>\n    <string name=\"rows_count\">Rækker tæller</string>\n    <string name=\"columns_count\">Antal kolonner</string>\n    <string name=\"use_pixel_switch\">Brug Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Pixel-lignende switch vil blive brugt i stedet for Googles materiale, du baserede en</string>\n    <string name=\"slide\">Glide</string>\n    <string name=\"side_by_side\">Side om side</string>\n    <string name=\"toggle_tap\">Skift Tryk</string>\n    <string name=\"transparency\">Gennemsigtighed</string>\n    <string name=\"saved_to_original\">Overskrevet fil med navn %1$s på den oprindelige destination</string>\n    <string name=\"magnifier\">Forstørrelsesglas</string>\n    <string name=\"magnifier_sub\">Aktiverer forstørrelsesglas øverst på fingeren i tegnetilstande for bedre tilgængelighed</string>\n    <string name=\"force_exif_widget_initial_value\">Tving startværdi</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Tvinger exif-widget til at blive tjekket indledningsvis</string>\n    <string name=\"allow_multiple_languages\">Tillad flere sprog</string>\n    <string name=\"favorite\">Favorit</string>\n    <string name=\"no_favorite_filters\">Ingen favoritfiltre tilføjet endnu</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"regular\">Fast</string>\n    <string name=\"blur_edges\">Slørede kanter</string>\n    <string name=\"blur_edges_sub\">Tegner slørede kanter under originalbilledet for at udfylde mellemrum omkring det i stedet for en enkelt farve, hvis det er aktiveret</string>\n    <string name=\"inverse_fill_type\">Omvendt fyldtype</string>\n    <string name=\"inverse_fill_type_sub\">Hvis aktiveret, vil alle ikke-maskerede områder blive filtreret i stedet for standardadfærd</string>\n    <string name=\"confetti\">Konfetti</string>\n    <string name=\"confetti_sub\">Konfetti vil blive vist ved lagring, deling og andre primære handlinger</string>\n    <string name=\"secure_mode\">Sikker tilstand</string>\n    <string name=\"secure_mode_sub\">Skjuler indhold ved afslutning, og skærmen kan heller ikke optages eller optages</string>\n    <string name=\"palette_style\">Palette stil</string>\n    <string name=\"tonal_spot\">Tonalt sted</string>\n    <string name=\"neutral\">Neutral</string>\n    <string name=\"vibrant\">Levende</string>\n    <string name=\"expressive\">Udtryksfuldt</string>\n    <string name=\"rainbow\">Regnbue</string>\n    <string name=\"fruit_salad\">Frugtsalat</string>\n    <string name=\"fidelity\">Troskab</string>\n    <string name=\"content\">Indhold</string>\n    <string name=\"tonal_spot_sub\">Standard paletstil, det giver mulighed for at tilpasse alle fire farver, andre tillader dig kun at indstille nøglefarven</string>\n    <string name=\"neutral_sub\">En stil, der er lidt mere kromatisk end monokrom</string>\n    <string name=\"vibrant_sub\">Et højt tema, farverighed er maksimal for Primær palet, øget for andre</string>\n    <string name=\"playful_scheme\">Et legende tema - kildefarvens nuance vises ikke i temaet</string>\n    <string name=\"monochrome_sub\">Et monokromt tema, farverne er rent sort / hvid / grå</string>\n    <string name=\"content_sub\">Et skema, der placerer kildefarven i Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">En ordning, der minder meget om indholdsordningen</string>\n    <string name=\"containers_shadow\">Containere</string>\n    <string name=\"containers_shadow_sub\">Tegn skygger bag beholdere</string>\n    <string name=\"sliders_shadow\">Skydere</string>\n    <string name=\"switches_shadow\">Afbrydere</string>\n    <string name=\"fabs_shadow\">FAB\\'er</string>\n    <string name=\"buttons_shadow\">Knapper</string>\n    <string name=\"sliders_shadow_sub\">Tegn skygge bag skydere</string>\n    <string name=\"switches_shadow_sub\">Tegn skygge bag kontakter</string>\n    <string name=\"fabs_shadow_sub\">Aktiverer skyggetegning bag flydende handlingsknapper</string>\n    <string name=\"buttons_shadow_sub\">Aktiverer skyggetegning bag standardknapper</string>\n    <string name=\"app_bars_shadow\">App barer</string>\n    <string name=\"app_bars_shadow_sub\">Aktiverer skyggetegning bag appbjælker</string>\n    <string name=\"foss_update_checker_warning\">Denne opdateringskontrol vil oprette forbindelse til GitHub for at kontrollere, om der er en ny opdatering tilgængelig</string>\n    <string name=\"attention\">Opmærksomhed</string>\n    <string name=\"invert_colors\">Inverter farver</string>\n    <string name=\"invert_colors_sub\">Erstatter temafarver til negative, hvis aktiveret</string>\n    <string name=\"exit\">Afslut</string>\n    <string name=\"preview_closing\">Hvis du forlader forhåndsvisningen nu, bliver du nødt til at tilføje billederne igen</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Tegner lukket udfyldt sti efter given sti</string>\n    <string name=\"image_format\">Billedformat</string>\n    <string name=\"anaglyph\">Anaglyph</string>\n    <string name=\"noise\">Støj</string>\n    <string name=\"pixel_sort\">Pixel Sort</string>\n    <string name=\"shuffle\">Bland</string>\n    <string name=\"material_you_sub\">Opretter \\\"Material You\\\" palette fra billede</string>\n    <string name=\"dark_colors\">Mørke Farver</string>\n    <string name=\"dark_colors_sub\">Bruger nattilstand farveskema i stedet for lys variant</string>\n    <string name=\"copy_as_compose_code\">Kopier som\\\" Jetpack Compose \\\" kode</string>\n    <string name=\"ring_blur\">Ringsløring</string>\n    <string name=\"cross_blur\">Kryds sløring</string>\n    <string name=\"circle_blur\">Cirkel sløring</string>\n    <string name=\"star_blur\">Stjernesløring</string>\n    <string name=\"linear_tilt_shift\">Lineær Tilt Shift</string>\n    <string name=\"tags_to_remove\">Tags At Fjerne</string>\n    <string name=\"apng_type_to_apng_sub\">Konverter batch af billeder til APNG-fil</string>\n    <string name=\"motion_blur\">Bevægelsessløring</string>\n    <string name=\"apng_tools\">APNG-værktøjer</string>\n    <string name=\"apng_tools_sub\">Konverter billeder til APNG-billede eller udtræk rammer fra givet APNG-billede</string>\n    <string name=\"apng_type_to_image_sub\">Konverter APNG-fil til batch af billeder</string>\n    <string name=\"apng_type_to_apng\">Billeder til APNG</string>\n    <string name=\"select_apng_image_to_start\">Vælg APNG-billede for at starte</string>\n    <string name=\"apng_type_to_image\">APNG til billeder</string>\n    <string name=\"zip\">Lynlås</string>\n    <string name=\"zip_sub\">Opret zip-fil fra givne filer eller billeder</string>\n    <string name=\"drag_handle_width\">Trækhåndtagsbredde</string>\n    <string name=\"tag_default_crop_size\">Standard beskæring</string>\n    <string name=\"crop_to_content\">Beskær til indhold af billedet</string>\n    <string name=\"confetti_type\">Konfetti type</string>\n    <string name=\"festive\">Festligt</string>\n    <string name=\"explode\">Eksplodere</string>\n    <string name=\"rain\">Regn</string>\n    <string name=\"corners\">Hjørner</string>\n    <string name=\"jxl_tools\">JXL værktøj</string>\n    <string name=\"jxl_tools_sub\">Udfør JXL ~ JPEG-omkodning uden kvalitetstab, eller konverter GIF/APNG til JXL-animation</string>\n    <string name=\"jxl_type_to_jpeg\">JXL til JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Udfør tabsfri omkodning fra JXL til JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Udfør tabsfri omkodning fra JPEG til JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG til JXL</string>\n    <string name=\"select_jxl_image_to_start\">Vælg JXL-billede for at starte</string>\n    <string name=\"fast_gaussian_blur_2d\">Hurtig Gaussisk sløring 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Hurtig Gaussisk sløring 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Hurtig Gaussisk sløring 4D</string>\n    <string name=\"auto_paste\">Bil påske</string>\n    <string name=\"auto_paste_sub\">Tillader, at appen automatisk indsætter data fra udklipsholderen, så de vises på hovedskærmen, og du vil være i stand til at behandle dem</string>\n    <string name=\"harmonization_color\">Harmoniseringsfarve</string>\n    <string name=\"harmonization_level\">Harmoniseringsniveau</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Resampling-metode, der opretholder interpolation af høj kvalitet ved at anvende en Bessel-funktion (jinc) på pixelværdierne</string>\n    <string name=\"gif_type_to_jxl\">GIF til JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Konverter GIF-billeder til JXL-animerede billeder</string>\n    <string name=\"apng_type_to_jxl\">APNG til JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Konverter APNG-billeder til JXL-animerede billeder</string>\n    <string name=\"jxl_type_to_images\">JXL til billeder</string>\n    <string name=\"jxl_type_to_images_sub\">Konverter JXL-animation til batch af billeder</string>\n    <string name=\"jxl_type_to_jxl\">Billeder til JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Konverter batch af billeder til JXL-animation</string>\n    <string name=\"behavior\">Opførsel</string>\n    <string name=\"skip_file_picking\">Spring over filvalg</string>\n    <string name=\"skip_file_picking_sub\">Filvælger vil blive vist med det samme, hvis dette er muligt på den valgte skærm</string>\n    <string name=\"generate_previews\">Generer forhåndsvisninger</string>\n    <string name=\"generate_previews_sub\">Aktiverer forhåndsvisning, dette kan hjælpe med at undgå nedbrud på nogle enheder, dette deaktiverer også nogle redigeringsfunktioner inden for en enkelt redigeringsmulighed</string>\n    <string name=\"lossy_compression\">Lossy kompression</string>\n    <string name=\"lossy_compression_sub\">Bruger komprimering med tab til at reducere filstørrelsen i stedet for tabsfri</string>\n    <string name=\"compression_type\">Kompressionstype</string>\n    <string name=\"speed_sub\">Styrer den resulterende billedafkodningshastighed, dette skulle hjælpe med at åbne det resulterende billede hurtigere, værdien %1$s betyder langsomste afkodning, hvorimod %2$s - hurtigst, denne indstilling kan øge outputbilledets størrelse</string>\n    <string name=\"sorting\">Sortering</string>\n    <string name=\"sort_by_date\">Dato</string>\n    <string name=\"sort_by_date_reversed\">Dato (omvendt)</string>\n    <string name=\"sort_by_name\">Navn</string>\n    <string name=\"sort_by_name_reversed\">Navn (omvendt)</string>\n    <string name=\"channels_configuration\">Kanalkonfiguration</string>\n    <string name=\"header_today\">I dag</string>\n    <string name=\"header_yesterday\">I går</string>\n    <string name=\"embedded_picker\">Embedded Picker</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox\\'s billedvælger</string>\n    <string name=\"no_permissions\">Ingen tilladelser</string>\n    <string name=\"request\">Anmodning</string>\n    <string name=\"pick_multiple_media\">Vælg flere medier</string>\n    <string name=\"pick_single_media\">Vælg Single Media</string>\n    <string name=\"pick\">Plukke</string>\n    <string name=\"try_again\">Prøv igen</string>\n    <string name=\"show_settings_in_landscape\">Vis indstillinger i liggende</string>\n    <string name=\"show_settings_in_landscape_sub\">Hvis dette er deaktiveret, åbnes indstillingerne i landskabstilstand på knappen i den øverste applinje som altid, i stedet for permanent synlig mulighed</string>\n    <string name=\"fullscreen_settings\">Indstillinger for fuld skærm</string>\n    <string name=\"fullscreen_settings_sub\">Aktiver det, og indstillingssiden vil altid blive åbnet som fuldskærm i stedet for forskydeligt skuffeark</string>\n    <string name=\"switch_type\">Switch Type</string>\n    <string name=\"compose\">Skriv</string>\n    <string name=\"compose_switch_sub\">En Jetpack Compose Materiale Du skifter</string>\n    <string name=\"material_you_switch_sub\">Et materiale, du skifter</string>\n    <string name=\"max\">Maks</string>\n    <string name=\"resize_anchor\">Ændr størrelse på anker</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Flydende</string>\n    <string name=\"fluent_switch_sub\">En switch baseret på \\\"Fluent\\\" designsystemet</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">En switch baseret på \\\"Cupertino\\\" designsystemet</string>\n    <string name=\"images_to_svg\">Billeder til SVG</string>\n    <string name=\"images_to_svg_sub\">Spor givne billeder til SVG-billeder</string>\n    <string name=\"use_sampled_palette\">Brug Sampled Palette</string>\n    <string name=\"use_sampled_palette_sub\">Kvantiseringspaletten vil blive samplet, hvis denne indstilling er aktiveret</string>\n    <string name=\"path_omit\">Udelad sti</string>\n    <string name=\"svg_warning\">Brug af dette værktøj til sporing af store billeder uden nedskalering anbefales ikke, det kan forårsage nedbrud og øge behandlingstiden</string>\n    <string name=\"downscale_image\">Nedskaleret billede</string>\n    <string name=\"downscale_image_sub\">Billedet vil blive nedskaleret til lavere dimensioner før behandling, dette hjælper værktøjet til at arbejde hurtigere og mere sikkert</string>\n    <string name=\"min_color_ratio\">Minimum farveforhold</string>\n    <string name=\"lines_threshold\">Linjer Tærskel</string>\n    <string name=\"quadratic_threshold\">Kvadratisk tærskel</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordinater afrundingstolerance</string>\n    <string name=\"path_scale\">Sti Skala</string>\n    <string name=\"reset_properties\">Nulstil egenskaber</string>\n    <string name=\"reset_properties_sub\">Alle egenskaber vil blive sat til standardværdier, bemærk at denne handling ikke kan fortrydes</string>\n    <string name=\"detailed\">Detaljeret</string>\n    <string name=\"default_line_width\">Standard linjebredde</string>\n    <string name=\"engine_mode\">Motortilstand</string>\n    <string name=\"legacy\">Arv</string>\n    <string name=\"lstm_network\">LSTM netværk</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp; LSTM</string>\n    <string name=\"convert\">Konvertere</string>\n    <string name=\"convert_sub\">Konverter billedbatches til givet format</string>\n    <string name=\"add_new_folder\">Tilføj ny mappe</string>\n    <string name=\"tag_bits_per_sample\">Bits pr. prøve</string>\n    <string name=\"tag_compression\">Kompression</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrisk fortolkning</string>\n    <string name=\"tag_samples_per_pixel\">Prøver pr. pixel</string>\n    <string name=\"tag_planar_configuration\">Plan konfiguration</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sub Sampling</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Positionering</string>\n    <string name=\"tag_x_resolution\">X opløsning</string>\n    <string name=\"tag_y_resolution\">Y Opløsning</string>\n    <string name=\"tag_resolution_unit\">Opløsningsenhed</string>\n    <string name=\"tag_strip_offsets\">Strip offsets</string>\n    <string name=\"tag_rows_per_strip\">Rækker pr. strimmel</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG-udvekslingsformat</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG Interchange Format Længde</string>\n    <string name=\"tag_transfer_function\">Overførselsfunktion</string>\n    <string name=\"tag_white_point\">Hvidt punkt</string>\n    <string name=\"tag_primary_chromaticities\">Primære kromaticiteter</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr-koefficienter</string>\n    <string name=\"tag_reference_black_white\">Reference Sort Hvid</string>\n    <string name=\"tag_datetime\">Dato Tid</string>\n    <string name=\"tag_image_description\">Billedbeskrivelse</string>\n    <string name=\"tag_make\">Lave</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_artist\">Kunstner</string>\n    <string name=\"tag_copyright\">Copyright</string>\n    <string name=\"tag_exif_version\">Exif version</string>\n    <string name=\"tag_flashpix_version\">Flashpix version</string>\n    <string name=\"tag_color_space\">Farverum</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y-dimension</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Komprimerede bits pr. pixel</string>\n    <string name=\"tag_maker_note\">Maker Note</string>\n    <string name=\"tag_user_comment\">Brugerkommentar</string>\n    <string name=\"tag_related_sound_file\">Relateret lydfil</string>\n    <string name=\"tag_datetime_original\">Dato Tid Original</string>\n    <string name=\"tag_datetime_digitized\">Dato Tid Digitaliseret</string>\n    <string name=\"tag_offset_time\">Offset tid</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Offset Tid Digitaliseret</string>\n    <string name=\"tag_subsec_time\">Undersek. tid</string>\n    <string name=\"tag_subsec_time_original\">Undersek. Tid Original</string>\n    <string name=\"tag_subsec_time_digitized\">Undersek. Tid digitaliseret</string>\n    <string name=\"tag_exposure_time\">Eksponeringstid</string>\n    <string name=\"tag_f_number\">F nummer</string>\n    <string name=\"tag_exposure_program\">Eksponeringsprogram</string>\n    <string name=\"tag_spectral_sensitivity\">Spektral følsomhed</string>\n    <string name=\"tag_photographic_sensitivity\">Fotografisk følsomhed</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Følsomhedstype</string>\n    <string name=\"tag_standard_output_sensitivity\">Standard udgangsfølsomhed</string>\n    <string name=\"tag_recommended_exposure_index\">Anbefalet eksponeringsindeks</string>\n    <string name=\"tag_iso_speed\">ISO hastighed</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Speed ​​Latitude yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Speed ​​Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Lukkerhastighedsværdi</string>\n    <string name=\"tag_aperture_value\">Blændeværdi</string>\n    <string name=\"tag_brightness_value\">Lysstyrkeværdi</string>\n    <string name=\"tag_exposure_bias_value\">Værdi for eksponeringsbias</string>\n    <string name=\"tag_max_aperture_value\">Max blændeværdi</string>\n    <string name=\"tag_subject_distance\">Emne afstand</string>\n    <string name=\"tag_metering_mode\">Måletilstand</string>\n    <string name=\"tag_flash\">Blitz</string>\n    <string name=\"tag_subject_area\">Fagområde</string>\n    <string name=\"tag_focal_length\">Brændvidde</string>\n    <string name=\"tag_flash_energy\">Flash energi</string>\n    <string name=\"tag_spatial_frequency_response\">Rumlig frekvensrespons</string>\n    <string name=\"tag_focal_plane_x_resolution\">Focal Plane X-opløsning</string>\n    <string name=\"tag_focal_plane_y_resolution\">Brændplan Y-opløsning</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Focal Plane Resolution Unit</string>\n    <string name=\"tag_subject_location\">Emnets placering</string>\n    <string name=\"tag_exposure_index\">Eksponeringsindeks</string>\n    <string name=\"tag_sensing_method\">Sensing metode</string>\n    <string name=\"tag_file_source\">Filkilde</string>\n    <string name=\"tag_cfa_pattern\">CFA mønster</string>\n    <string name=\"tag_custom_rendered\">Brugerdefineret gengivet</string>\n    <string name=\"tag_exposure_mode\">Eksponeringstilstand</string>\n    <string name=\"tag_white_balance\">Hvidbalance</string>\n    <string name=\"tag_digital_zoom_ratio\">Digitalt zoomforhold</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Brændvidde i 35 mm film</string>\n    <string name=\"tag_scene_capture_type\">Sceneoptagelsestype</string>\n    <string name=\"tag_gain_control\">Få kontrol</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"tag_saturation\">Mætning</string>\n    <string name=\"tag_sharpness\">Skarphed</string>\n    <string name=\"tag_device_setting_description\">Beskrivelse af enhedsindstilling</string>\n    <string name=\"tag_subject_distance_range\">Emneafstand</string>\n    <string name=\"tag_image_unique_id\">Billede unikt ID</string>\n    <string name=\"tag_camera_owner_name\">Navn på kameraejer</string>\n    <string name=\"tag_body_serial_number\">Kroppens serienummer</string>\n    <string name=\"tag_lens_specification\">Objektivspecifikation</string>\n    <string name=\"tag_lens_make\">Lens Make</string>\n    <string name=\"tag_lens_model\">Objektiv model</string>\n    <string name=\"tag_lens_serial_number\">Objektivets serienummer</string>\n    <string name=\"tag_gps_version_id\">GPS-versions-id</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS-breddegrad</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Længdegrad Ref</string>\n    <string name=\"tag_gps_longitude\">GPS Længdegrad</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Højde Ref</string>\n    <string name=\"tag_gps_altitude\">GPS højde</string>\n    <string name=\"tag_gps_timestamp\">GPS tidsstempel</string>\n    <string name=\"tag_gps_satellites\">GPS satellitter</string>\n    <string name=\"tag_gps_status\">GPS-status</string>\n    <string name=\"tag_gps_measure_mode\">GPS måletilstand</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS-hastighed Ref</string>\n    <string name=\"tag_gps_speed\">GPS hastighed</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS spor</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS billede Ref</string>\n    <string name=\"tag_gps_img_direction\">GPS billedretning</string>\n    <string name=\"tag_gps_map_datum\">GPS-kort dato</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Længdegrad Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Længdegrad</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Leje Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS-destinationsafstand</string>\n    <string name=\"tag_gps_processing_method\">GPS-behandlingsmetode</string>\n    <string name=\"tag_gps_area_information\">GPS-områdeinformation</string>\n    <string name=\"tag_gps_datestamp\">GPS-datostempel</string>\n    <string name=\"tag_gps_differential\">GPS differentiale</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H-positioneringsfejl</string>\n    <string name=\"tag_interoperability_index\">Interoperabilitetsindeks</string>\n    <string name=\"tag_dng_version\">DNG-version</string>\n    <string name=\"tag_orf_preview_image_start\">Preview Image Start</string>\n    <string name=\"tag_orf_preview_image_length\">Forhåndsvisning af billedlængde</string>\n    <string name=\"tag_orf_aspect_frame\">Aspektramme</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Sensor nederste kant</string>\n    <string name=\"tag_rw2_sensor_left_border\">Sensor venstre kant</string>\n    <string name=\"tag_rw2_sensor_right_border\">Sensor højre kant</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sensor øverste kant</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Tegn tekst på stien med givet skrifttype og farve</string>\n    <string name=\"font_size\">Skriftstørrelse</string>\n    <string name=\"watermark_size\">Vandmærke størrelse</string>\n    <string name=\"repeat_text\">Gentag tekst</string>\n    <string name=\"repeat_text_sub\">Den aktuelle tekst vil blive gentaget, indtil stien slutter i stedet for at tegne én gang</string>\n    <string name=\"dash_size\">Dash størrelse</string>\n    <string name=\"draw_mode_image_sub\">Brug det valgte billede til at tegne det langs en given sti</string>\n    <string name=\"draw_image_sub\">Dette billede vil blive brugt som gentagen indtastning af tegnet sti</string>\n    <string name=\"outlined_triangle_sub\">Tegner en skitseret trekant fra startpunkt til slutpunkt</string>\n    <string name=\"triangle_sub\">Tegner en skitseret trekant fra startpunkt til slutpunkt</string>\n    <string name=\"outlined_triangle\">Skitseret trekant</string>\n    <string name=\"triangle\">Trekant</string>\n    <string name=\"polygon_sub\">Tegner polygon fra startpunkt til slutpunkt</string>\n    <string name=\"polygon\">Polygon</string>\n    <string name=\"outlined_polygon\">Skitseret polygon</string>\n    <string name=\"outlined_polygon_sub\">Tegner en polygon med skitsering fra startpunkt til slutpunkt</string>\n    <string name=\"vertices\">Toppunkter</string>\n    <string name=\"draw_regular_polygon\">Tegn almindelig polygon</string>\n    <string name=\"draw_regular_polygon_sub\">Tegn polygon, som vil være regulær i stedet for fri form</string>\n    <string name=\"star_sub\">Tegner stjerne fra startpunkt til slutpunkt</string>\n    <string name=\"star\">Stjerne</string>\n    <string name=\"outlined_star\">Skitseret Stjerne</string>\n    <string name=\"outlined_star_sub\">Tegner skitseret stjerne fra startpunkt til slutpunkt</string>\n    <string name=\"inner_radius_ratio\">Indre radiusforhold</string>\n    <string name=\"draw_regular_star\">Tegn almindelig stjerne</string>\n    <string name=\"draw_regular_star_sub\">Tegn stjerne, som vil være almindelig i stedet for fri form</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Aktiverer antialiasing for at forhindre skarpe kanter</string>\n    <string name=\"open_edit_instead_of_preview\">Åbn Rediger i stedet for forhåndsvisning</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Når du vælger billede, der skal åbnes (forhåndsvisning) i ImageToolbox, åbnes redigeringsarket i stedet for forhåndsvisning</string>\n    <string name=\"document_scanner\">Dokument scanner</string>\n    <string name=\"document_scanner_sub\">Scan dokumenter og opret PDF eller adskil billeder fra dem</string>\n    <string name=\"click_to_start_scanning\">Klik for at starte scanningen</string>\n    <string name=\"start_scanning\">Start scanning</string>\n    <string name=\"save_as_pdf\">Gem som pdf</string>\n    <string name=\"share_as_pdf\">Del som pdf</string>\n    <string name=\"options_below_is_for_images\">Nedenstående muligheder er til at gemme billeder, ikke PDF</string>\n    <string name=\"equalize_histogram_hsv\">Udlign Histogram HSV</string>\n    <string name=\"equalize_histogram\">Udlign histogram</string>\n    <string name=\"enter_percentage\">Indtast procent</string>\n    <string name=\"allow_enter_by_text_field\">Tillad indtastning efter tekstfelt</string>\n    <string name=\"allow_enter_by_text_field_sub\">Aktiverer tekstfelt bag forudindstillinger, for at indtaste dem med det samme</string>\n    <string name=\"scale_color_space\">Skala farverum</string>\n    <string name=\"linear\">Lineær</string>\n    <string name=\"equalize_histogram_pixelation\">Udlign histogrampixelering</string>\n    <string name=\"grid_size_x\">Gitterstørrelse X</string>\n    <string name=\"grid_size_y\">Gitterstørrelse Y</string>\n    <string name=\"equalize_histogram_adaptive\">Udlign Histogram Adaptive</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Udlign Histogram Adaptive LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Udlign Histogram Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"frame_color\">Ramme farve</string>\n    <string name=\"color_to_ignore\">Farve at ignorere</string>\n    <string name=\"template\">Skabelon</string>\n    <string name=\"no_template_filters\">Ingen skabelonfiltre tilføjet</string>\n    <string name=\"create_new\">Opret ny</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Den scannede QR-kode er ikke en gyldig filterskabelon</string>\n    <string name=\"scan_qr_code\">Scan QR-kode</string>\n    <string name=\"opened_file_have_no_filter_template\">Den valgte fil har ingen filterskabelondata</string>\n    <string name=\"create_template\">Opret skabelon</string>\n    <string name=\"template_name\">Skabelonnavn</string>\n    <string name=\"select_template_preview\">Dette billede vil blive brugt til at få vist denne filterskabelon</string>\n    <string name=\"template_filter\">Skabelonfilter</string>\n    <string name=\"as_qr_code\">Som QR-kode billede</string>\n    <string name=\"as_file\">Som fil</string>\n    <string name=\"save_as_file\">Gem som fil</string>\n    <string name=\"save_as_qr_code_image\">Gem som QR-kodebillede</string>\n    <string name=\"delete_template\">Slet skabelon</string>\n    <string name=\"delete_template_warn\">Du er ved at slette det valgte skabelonfilter. Denne handling kan ikke fortrydes</string>\n    <string name=\"added_filter_template\">Tilføjet filterskabelon med navnet \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Forhåndsvisning af filter</string>\n    <string name=\"qr_code\">QR &amp; stregkode</string>\n    <string name=\"qr_code_sub\">Scan QR-koden og få dens indhold, eller indsæt din streng for at generere en ny</string>\n    <string name=\"code_content\">Kodeindhold</string>\n    <string name=\"scan_qr_code_to_replace_content\">Scan en hvilken som helst stregkode for at erstatte indhold i feltet, eller skriv noget for at generere ny stregkode med den valgte type</string>\n    <string name=\"qr_description\">QR beskrivelse</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Giv kameratilladelse i indstillingerne til at scanne QR-kode</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Giv kameratilladelse i indstillingerne til at scanne dokumentscanner</string>\n    <string name=\"cubic\">Kubik</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussisk</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Boks</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kubisk interpolation giver jævnere skalering ved at overveje de nærmeste 16 pixels, hvilket giver bedre resultater end bilineær</string>\n    <string name=\"bspline_sub\">Anvender stykkevis definerede polynomielle funktioner til jævnt at interpolere og tilnærme en kurve eller overflade, fleksibel og kontinuerlig formrepræsentation</string>\n    <string name=\"hamming_sub\">En vinduesfunktion, der bruges til at reducere spektral lækage ved at tilspidse kanterne på et signal, hvilket er nyttigt i signalbehandling</string>\n    <string name=\"hanning_sub\">En variant af Hann-vinduet, der almindeligvis bruges til at reducere spektral lækage i signalbehandlingsapplikationer</string>\n    <string name=\"blackman_sub\">En vinduesfunktion, der giver god frekvensopløsning ved at minimere spektral lækage, ofte brugt i signalbehandling</string>\n    <string name=\"welch_sub\">En vinduesfunktion designet til at give god frekvensopløsning med reduceret spektral lækage, der ofte bruges i signalbehandlingsapplikationer</string>\n    <string name=\"quadric_sub\">En metode, der bruger en kvadratisk funktion til interpolation, hvilket giver jævne og kontinuerlige resultater</string>\n    <string name=\"gaussian_sub\">En interpolationsmetode, der anvender en Gauss-funktion, nyttig til at udjævne og reducere støj i billeder</string>\n    <string name=\"sphinx_sub\">En avanceret resamplingmetode, der giver interpolation af høj kvalitet med minimale artefakter</string>\n    <string name=\"bartlett_sub\">En trekantet vinduesfunktion, der bruges i signalbehandling for at reducere spektral lækage</string>\n    <string name=\"robidoux_sub\">En interpolationsmetode af høj kvalitet, der er optimeret til naturlig billedstørrelse, balancering af skarphed og glathed</string>\n    <string name=\"robidoux_sharp_sub\">En skarpere variant af Robidoux-metoden, optimeret til skarp billedstørrelse</string>\n    <string name=\"spline16_sub\">En spline-baseret interpolationsmetode, der giver jævne resultater ved hjælp af et 16-taps filter</string>\n    <string name=\"spline36_sub\">En spline-baseret interpolationsmetode, der giver jævne resultater ved hjælp af et 36-taps filter</string>\n    <string name=\"spline64_sub\">En spline-baseret interpolationsmetode, der giver jævne resultater ved hjælp af et 64-taps filter</string>\n    <string name=\"kaiser_sub\">En interpolationsmetode, der bruger Kaiser-vinduet, der giver god kontrol over afvejningen mellem hovedlobens bredde og sidelobens niveau</string>\n    <string name=\"bartlett_hann_sub\">En hybrid vinduesfunktion, der kombinerer Bartlett og Hann vinduerne, bruges til at reducere spektral lækage i signalbehandling</string>\n    <string name=\"box_sub\">En simpel resamplingmetode, der bruger gennemsnittet af de nærmeste pixelværdier, hvilket ofte resulterer i et blokeret udseende</string>\n    <string name=\"bohman_sub\">En vinduesfunktion, der bruges til at reducere spektral lækage, hvilket giver god frekvensopløsning i signalbehandlingsapplikationer</string>\n    <string name=\"lanczos2_sub\">En resamplingmetode, der bruger et 2-lobs Lanczos-filter til interpolation af høj kvalitet med minimale artefakter</string>\n    <string name=\"lanczos3_sub\">En resamplingmetode, der bruger et 3-lobs Lanczos-filter til interpolation af høj kvalitet med minimale artefakter</string>\n    <string name=\"lanczos4_sub\">En resamplingmetode, der bruger et 4-lobs Lanczos-filter til interpolation af høj kvalitet med minimale artefakter</string>\n    <string name=\"lanczos2_jinc_sub\">En variant af Lanczos 2-filteret, der bruger jinc-funktionen, der giver interpolation af høj kvalitet med minimale artefakter</string>\n    <string name=\"lanczos3_jinc_sub\">En variant af Lanczos 3-filteret, der bruger jinc-funktionen, der giver interpolation af høj kvalitet med minimale artefakter</string>\n    <string name=\"lanczos4_jinc_sub\">En variant af Lanczos 4-filteret, der bruger jinc-funktionen, der giver interpolation af høj kvalitet med minimale artefakter</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Elliptical Weighted Average (EWA) variant af Hanning-filteret til jævn interpolation og resampling</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elliptical Weighted Average (EWA) variant af Robidoux-filteret til resampling af høj kvalitet</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Elliptical Weighted Average (EWA) variant af Blackman-filteret for at minimere ringeartefakter</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Elliptical Weighted Average (EWA) variant af Quadric-filteret for jævn interpolation</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elliptical Weighted Average (EWA) variant af Robidoux Sharp-filteret for skarpere resultater</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Elliptical Weighted Average (EWA) variant af Lanczos 3 Jinc-filteret til resampling af høj kvalitet med reduceret aliasing</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Et resamplingfilter designet til billedbehandling af høj kvalitet med en god balance mellem skarphed og glathed</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Elliptical Weighted Average (EWA) variant af Ginseng-filteret for forbedret billedkvalitet</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Elliptical Weighted Average (EWA) variant af Lanczos Sharp-filteret for at opnå skarpe resultater med minimale artefakter</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Skarpeste EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Elliptical Weighted Average (EWA)-variant af Lanczos 4 Sharpest-filteret til ekstremt skarp billedresampling</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptical Weighted Average (EWA) variant af Lanczos Soft-filteret for jævnere billedresampling</string>\n    <string name=\"haasn_soft\">Haasn blød</string>\n    <string name=\"haasn_soft_sub\">Et resampling-filter designet af Haasn til jævn og artefaktfri billedskalering</string>\n    <string name=\"format_conversion\">Formatkonvertering</string>\n    <string name=\"format_conversion_sub\">Konverter batch af billeder fra et format til et andet</string>\n    <string name=\"dismiss_forever\">Afskedig for evigt</string>\n    <string name=\"image_stacking\">Billedstabling</string>\n    <string name=\"image_stacking_sub\">Stak billeder oven på hinanden med de valgte blandingstilstande</string>\n    <string name=\"add_image\">Tilføj billede</string>\n    <string name=\"bins_count\">Beholdere tæller</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Udlign Histogram Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Udlign Histogram Adaptive HSV</string>\n    <string name=\"edge_mode\">Edge Mode</string>\n    <string name=\"clip\">Klip</string>\n    <string name=\"wrap\">Indpakning</string>\n    <string name=\"color_blind_scheme\">Farveblindhed</string>\n    <string name=\"color_blind_scheme_sub\">Vælg tilstand for at tilpasse temafarver til den valgte farveblindhedsvariant</string>\n    <string name=\"protanomaly_sub\">Svært ved at skelne mellem røde og grønne nuancer</string>\n    <string name=\"deuteranomaly_sub\">Svært ved at skelne mellem grønne og røde nuancer</string>\n    <string name=\"tritanomaly_sub\">Svært ved at skelne mellem blå og gule nuancer</string>\n    <string name=\"protanopia_sub\">Manglende evne til at opfatte røde nuancer</string>\n    <string name=\"deuteranopia_sub\">Manglende evne til at opfatte grønne nuancer</string>\n    <string name=\"tritanopia_sub\">Manglende evne til at opfatte blå nuancer</string>\n    <string name=\"achromatomaly_sub\">Reduceret følsomhed over for alle farver</string>\n    <string name=\"achromatopsia_sub\">Fuldstændig farveblindhed, ser kun gråtoner</string>\n    <string name=\"not_use_color_blind_scheme\">Brug ikke farveblind-skemaet</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Farverne vil være nøjagtigt som angivet i temaet</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Et Lagrange-interpolationsfilter af størrelsesorden 2, velegnet til billedskalering af høj kvalitet med jævne overgange</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Et Lagrange-interpolationsfilter af størrelsesorden 3, der giver bedre nøjagtighed og jævnere resultater til billedskalering</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Et Lanczos resampling-filter med en højere orden på 6, hvilket giver skarpere og mere nøjagtig billedskalering</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">En variant af Lanczos 6-filteret, der bruger en Jinc-funktion for forbedret billedresampling-kvalitet</string>\n    <string name=\"linear_box_blur\">Sløring af lineær boks</string>\n    <string name=\"linear_tent_blur\">Lineær teltsløring</string>\n    <string name=\"linear_gaussian_box_blur\">Lineær Gaussisk bokssløring</string>\n    <string name=\"linear_stack_blur\">Lineær stak sløring</string>\n    <string name=\"gaussian_box_blur\">Gaussisk boks sløring</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lineær Hurtig Gaussisk sløring Næste</string>\n    <string name=\"linear_fast_gaussian_blur\">Lineær hurtig Gaussisk sløring</string>\n    <string name=\"linear_gaussian_blur\">Lineær Gaussisk sløring</string>\n    <string name=\"draw_filter_sub\">Vælg et filter for at bruge det som maling</string>\n    <string name=\"replace_filter\">Udskift filter</string>\n    <string name=\"pick_filter_info\">Vælg filter nedenfor for at bruge det som pensel i din tegning</string>\n    <string name=\"tiff_compression_scheme\">TIFF-komprimeringsskema</string>\n    <string name=\"low_poly\">Lav poly</string>\n    <string name=\"sand_painting\">Sandmaleri</string>\n    <string name=\"image_splitting\">Billedopdeling</string>\n    <string name=\"image_splitting_sub\">Opdel enkelt billede efter rækker eller kolonner</string>\n    <string name=\"fit_to_bounds\">Fit To Bounds</string>\n    <string name=\"fit_to_bounds_sub\">Kombiner beskæringsændringstilstand med denne parameter for at opnå den ønskede adfærd (Beskær/tilpas til billedformat)</string>\n    <string name=\"languages_imported\">Sprog blev importeret</string>\n    <string name=\"backup_ocr_models\">Backup OCR-modeller</string>\n    <string name=\"import_word\">Importere</string>\n    <string name=\"export\">Eksportere</string>\n    <string name=\"position\">Position</string>\n    <string name=\"center\">Centrum</string>\n    <string name=\"top_left\">Øverst til venstre</string>\n    <string name=\"top_right\">Øverst til højre</string>\n    <string name=\"bottom_left\">Nederst til venstre</string>\n    <string name=\"bottom_right\">Nederst til højre</string>\n    <string name=\"top_center\">Top Center</string>\n    <string name=\"center_right\">Center højre</string>\n    <string name=\"bottom_center\">Nederst i midten</string>\n    <string name=\"center_left\">Midt til venstre</string>\n    <string name=\"target_image\">Målbillede</string>\n    <string name=\"palette_transfer\">Palette overførsel</string>\n    <string name=\"enhanced_oil\">Forbedret olie</string>\n    <string name=\"simple_old_tv\">Simpelt gammelt TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Simpel skitse</string>\n    <string name=\"soft_glow\">Blød glød</string>\n    <string name=\"color_poster\">Farve plakat</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Tredje farve</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Clustered 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Clustered 4x4 dithering</string>\n    <string name=\"clustered_8x8_dithering\">Clustered 8x8 dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma dithering</string>\n    <string name=\"no_favorite_options_selected\">Ingen foretrukne valgmuligheder valgt, tilføj dem på siden med værktøjer</string>\n    <string name=\"add_favorites\">Tilføj favoritter</string>\n    <string name=\"harmony_complementary\">Komplementær</string>\n    <string name=\"harmony_analogous\">Analog</string>\n    <string name=\"harmony_triadic\">Triadisk</string>\n    <string name=\"harmony_split_complementary\">Split komplementær</string>\n    <string name=\"harmony_tetradic\">tetradisk</string>\n    <string name=\"harmony_square\">Firkant</string>\n    <string name=\"harmony_analogous_complementary\">Analog + Komplementær</string>\n    <string name=\"color_tools\">Farveværktøjer</string>\n    <string name=\"color_tools_sub\">Mix, lav toner, generer nuancer og mere</string>\n    <string name=\"color_harmonies\">Farveharmonier</string>\n    <string name=\"color_shading\">Farveskygge</string>\n    <string name=\"variation\">Variation</string>\n    <string name=\"tints\">Farver</string>\n    <string name=\"tones\">Toner</string>\n    <string name=\"shades\">Nuancer</string>\n    <string name=\"color_mixing\">Farveblanding</string>\n    <string name=\"color_info\">Farve info</string>\n    <string name=\"selected_color\">Valgt farve</string>\n    <string name=\"color_to_mix\">Farve at blande</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Kan ikke bruge monet, mens dynamiske farver er slået til</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Mål LUT-billede</string>\n    <string name=\"amatorka\">En amatør</string>\n    <string name=\"miss_etikate\">Frøken Etikette</string>\n    <string name=\"soft_elegance\">Blød elegance</string>\n    <string name=\"soft_elegance_variant\">Soft Elegance Variant</string>\n    <string name=\"palette_transfer_variant\">Palette Transfer Variant</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Mål 3D LUT-fil (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Stearinlys</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Edgy Amber</string>\n    <string name=\"fall_colors\">Efterårsfarver</string>\n    <string name=\"film_stock_50\">Filmlager 50</string>\n    <string name=\"foggy_night\">Tåget nat</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Få et neutralt LUT-billede</string>\n    <string name=\"save_empty_lut_sub\">Brug først dit foretrukne fotoredigeringsprogram til at anvende et filter på neutral LUT, som du kan få her. For at dette skal fungere korrekt, må hver pixelfarve ikke afhænge af andre pixels (f.eks. virker sløring ikke). Når du er klar, skal du bruge dit nye LUT-billede som input til 512*512 LUT-filter</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"coffee\">Kaffe</string>\n    <string name=\"golden_forest\">Gyldne Skov</string>\n    <string name=\"greenish\">Grønlig</string>\n    <string name=\"retro_yellow\">Retro gul</string>\n    <string name=\"links_preview\">Forhåndsvisning af links</string>\n    <string name=\"links_preview_sub\">Aktiverer hentning af linkforhåndsvisning på steder, hvor du kan hente tekst (QRCode, OCR osv.)</string>\n    <string name=\"links\">Links</string>\n    <string name=\"ico_size_warning\">ICO-filer kan kun gemmes i den maksimale størrelse på 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF til WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Konverter GIF-billeder til WEBP-animerede billeder</string>\n    <string name=\"webp_tools\">WEBP-værktøjer</string>\n    <string name=\"webp_tools_sub\">Konverter billeder til WEBP-animerede billeder eller udtræk rammer fra en given WEBP-animation</string>\n    <string name=\"webp_type_to_image\">WEBP til billeder</string>\n    <string name=\"webp_type_to_image_sub\">Konverter WEBP-fil til batch af billeder</string>\n    <string name=\"webp_type_to_webp_sub\">Konverter batch af billeder til WEBP-fil</string>\n    <string name=\"webp_type_to_webp\">Billeder til WEBP</string>\n    <string name=\"select_webp_image_to_start\">Vælg WEBP-billede for at starte</string>\n    <string name=\"manage_storage_extra_types\">Ingen fuld adgang til filer</string>\n    <string name=\"manage_storage_extra_types_sub\">Tillad alle filer adgang til at se JXL, QOI og andre billeder, der ikke genkendes som billeder på Android. Uden tilladelsen er Image Toolbox ikke i stand til at vise disse billeder</string>\n    <string name=\"default_draw_color\">Standard tegnefarve</string>\n    <string name=\"default_draw_path_mode\">Standard tegnestitilstand</string>\n    <string name=\"add_timestamp\">Tilføj tidsstempel</string>\n    <string name=\"add_timestamp_sub\">Aktiverer tilføjelse af tidsstempel til outputfilnavnet</string>\n    <string name=\"formatted_timestamp\">Formateret tidsstempel</string>\n    <string name=\"formatted_timestamp_sub\">Aktiver tidsstempelformatering i outputfilnavn i stedet for grundlæggende millis</string>\n    <string name=\"enable_timestamps_to_format_them\">Aktiver tidsstempler for at vælge deres format</string>\n    <string name=\"one_time_save_location\">En gang gem placering</string>\n    <string name=\"one_time_save_location_sub\">Se og rediger en gang gemte placeringer, som du kan bruge ved at trykke længe på gem-knappen i stort set alle muligheder</string>\n    <string name=\"recently_used\">Nyligt brugt</string>\n    <string name=\"ci_channel\">CI kanal</string>\n    <string name=\"group\">Gruppe</string>\n    <string name=\"image_toolbox_in_telegram\">Billedværktøjskasse i Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Deltag i vores chat, hvor du kan diskutere alt, hvad du vil, og se også ind på CI-kanalen, hvor jeg poster betaer og annonceringer</string>\n    <string name=\"ci_channel_sub\">Få besked om nye versioner af appen, og læs meddelelser</string>\n    <string name=\"fit_description\">Tilpas et billede til givne dimensioner og anvend sløring eller farve på baggrunden</string>\n    <string name=\"tools_arrangement\">Værktøjsarrangement</string>\n    <string name=\"group_tools_by_type\">Gruppér værktøjer efter type</string>\n    <string name=\"group_tools_by_type_sub\">Grupperer værktøjer på hovedskærmen efter deres type i stedet for et brugerdefineret listearrangement</string>\n    <string name=\"default_values\">Standardværdier</string>\n    <string name=\"system_bars_visibility\">Systembars synlighed</string>\n    <string name=\"show_system_bars_by_swipe\">Vis systembjælker ved at stryge</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Aktiverer strygning for at vise systembjælker, hvis de er skjulte</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Skjul alle</string>\n    <string name=\"show_all\">Vis alle</string>\n    <string name=\"hide_nav_bar\">Skjul Nav Bar</string>\n    <string name=\"hide_status_bar\">Skjul statuslinje</string>\n    <string name=\"noise_generation\">Støjgenerering</string>\n    <string name=\"noise_generation_sub\">Generer forskellige lyde som Perlin eller andre typer</string>\n    <string name=\"frequency\">Frekvens</string>\n    <string name=\"noise_type\">Støjtype</string>\n    <string name=\"rotation_type\">Rotationstype</string>\n    <string name=\"fractal_type\">Fraktal type</string>\n    <string name=\"octaves\">Oktaver</string>\n    <string name=\"lacunarity\">Lakunaritet</string>\n    <string name=\"gain\">Gevinst</string>\n    <string name=\"weighted_strength\">Vægtet styrke</string>\n    <string name=\"ping_pong_strength\">Ping Pong Styrke</string>\n    <string name=\"distance_function\">Afstandsfunktion</string>\n    <string name=\"return_type\">Returtype</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"alignment\">Justering</string>\n    <string name=\"custom_filename\">Brugerdefineret filnavn</string>\n    <string name=\"custom_filename_sub\">Vælg placering og filnavn, som skal bruges til at gemme det aktuelle billede</string>\n    <string name=\"saved_to_custom\">Gemt i mappe med brugerdefineret navn</string>\n    <string name=\"collage_maker\">Collage maker</string>\n    <string name=\"collage_maker_sub\">Lav collager af op til 20 billeder</string>\n    <string name=\"collage_type\">Collage type</string>\n    <string name=\"collages_info\">Hold billedet for at bytte, flytte og zoome for at justere positionen</string>\n    <string name=\"disable_rotation\">Deaktiver rotation</string>\n    <string name=\"disable_rotation_sub\">Forhindrer roterende billeder med to-fingerbevægelser</string>\n    <string name=\"enable_snapping_to_borders\">Aktiver snapping til grænser</string>\n    <string name=\"enable_snapping_to_borders_sub\">Efter at have flyttet eller zoomet vil billederne snappes for at udfylde rammens kanter</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">RGB- eller Brightness-billedhistogram for at hjælpe dig med at foretage justeringer</string>\n    <string name=\"image_for_histogram\">Dette billede vil blive brugt til at generere RGB- og lysstyrkehistogrammer</string>\n    <string name=\"tesseract_options\">Tesseract muligheder</string>\n    <string name=\"tesseract_options_sub\">Anvend nogle inputvariabler til tesseract-motoren</string>\n    <string name=\"custom_options\">Brugerdefinerede indstillinger</string>\n    <string name=\"custom_params_info\">Indstillinger skal indtastes efter dette mønster: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Automatisk beskæring</string>\n    <string name=\"free_corners\">Frie hjørner</string>\n    <string name=\"free_corners_sub\">Beskær billede efter polygon, dette korrigerer også perspektivet</string>\n    <string name=\"coerce_points_to_image_bounds\">Tvang peger på billedgrænser</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Points vil ikke være begrænset af billedgrænser, dette er nyttigt til mere præcis perspektivkorrektion</string>\n    <string name=\"mask\">Maske</string>\n    <string name=\"spot_heal_sub\">Indholdsbevidst fyld under tegnet sti</string>\n    <string name=\"spot_heal\">Heal Spot</string>\n    <string name=\"use_circle_kernel\">Brug Circle Kernel</string>\n    <string name=\"opening\">Åbning</string>\n    <string name=\"closing\">Lukning</string>\n    <string name=\"morphological_gradient\">Morfologisk gradient</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Sort Hat</string>\n    <string name=\"tone_curves\">Tonekurver</string>\n    <string name=\"reset_curves\">Nulstil kurver</string>\n    <string name=\"reset_curves_sub\">Kurver vil blive rullet tilbage til standardværdien</string>\n    <string name=\"line_style\">Linje stil</string>\n    <string name=\"gap_size\">Gab størrelse</string>\n    <string name=\"dashed\">Stiplet</string>\n    <string name=\"dot_dashed\">Punkt stiplet</string>\n    <string name=\"stamped\">Stemplet</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Tegner stiplet linje langs den tegnede sti med specificeret mellemrumsstørrelse</string>\n    <string name=\"dot_dashed_sub\">Tegner prik og stiplet linje langs den givne sti</string>\n    <string name=\"defaultt_sub\">Bare standard lige linjer</string>\n    <string name=\"stamped_sub\">Tegner valgte figurer langs stien med specificeret mellemrum</string>\n    <string name=\"zigzag_sub\">Tegner bølget zigzag langs stien</string>\n    <string name=\"zigzag_ratio\">Zigzag-forhold</string>\n    <string name=\"create_shortcut\">Opret genvej</string>\n    <string name=\"create_shortcut_title\">Vælg værktøj til at fastgøre</string>\n    <string name=\"create_shortcut_subtitle\">Værktøjet vil blive tilføjet til startskærmen på din launcher som genvej, brug det i kombination med indstillingen \\\"Spring filvalg over\\\" for at opnå den nødvendige adfærd</string>\n    <string name=\"dont_stack_frames\">Stable ikke rammer</string>\n    <string name=\"dont_stack_frames_sub\">Gør det muligt at bortskaffe tidligere rammer, så de ikke stables på hinanden</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Rammer vil blive krydstonet ind i hinanden</string>\n    <string name=\"crossfade_count\">Crossfade-rammer tæller</string>\n    <string name=\"threshold_one\">Tærskel 1</string>\n    <string name=\"threshold_two\">Tærskel to</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Spejl 101</string>\n    <string name=\"enhanced_zoom_blur\">Forbedret zoomsløring</string>\n    <string name=\"laplacian_simple\">Laplacian Simple</string>\n    <string name=\"sobel_simple\">Sobel Simpel</string>\n    <string name=\"helper_grid\">Hjælpergitter</string>\n    <string name=\"helper_grid_sub\">Viser understøttende gitter over tegneområdet for at hjælpe med præcise manipulationer</string>\n    <string name=\"grid_color\">Gitter farve</string>\n    <string name=\"cell_width\">Cellebredde</string>\n    <string name=\"cell_height\">Cellehøjde</string>\n    <string name=\"compact_selectors\">Kompakte vælgere</string>\n    <string name=\"compact_selectors_sub\">Nogle valgknapper vil bruge et kompakt layout for at tage mindre plads</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Giv kameratilladelse i indstillingerne til at tage billeder</string>\n    <string name=\"layout\">Layout</string>\n    <string name=\"main_screen_title\">Hovedskærmens titel</string>\n    <string name=\"constant_rate_factor\">Konstant Rate Factor (CRF)</string>\n    <string name=\"crf_sub\">En værdi på %1$s betyder en langsom komprimering, hvilket resulterer i en relativt lille filstørrelse. %2$s betyder en hurtigere komprimering, hvilket resulterer i en stor fil.</string>\n    <string name=\"lut_library\">Lut Bibliotek</string>\n    <string name=\"lut_library_sub\">Download samling af LUT\\'er, som du kan anvende efter download</string>\n    <string name=\"lut_library_update_sub\">Opdater samling af LUT\\'er (kun nye vil stå i kø), som du kan anvende efter download</string>\n    <string name=\"filter_preview_image_sub\">Skift standard billedeksempel for filtre</string>\n    <string name=\"filter_preview_image\">Eksempelbillede</string>\n    <string name=\"hide\">Skjule</string>\n    <string name=\"show\">Vise</string>\n    <string name=\"slider_type\">Slider Type</string>\n    <string name=\"fancy\">Fancy</string>\n    <string name=\"material_2\">Materiale 2</string>\n    <string name=\"fancy_sub\">En fancy skyder. Dette er standardindstillingen</string>\n    <string name=\"material_2_sub\">En Materiale 2-skyder</string>\n    <string name=\"material_you_slider_sub\">Et materiale du skyder</string>\n    <string name=\"apply\">Anvende</string>\n    <string name=\"center_align_dialog_buttons\">Midterdialogknapper</string>\n    <string name=\"center_align_dialog_buttons_sub\">Knapper af dialogbokse vil blive placeret i midten i stedet for venstre side, hvis det er muligt</string>\n    <string name=\"open_source_licenses\">Open Source-licenser</string>\n    <string name=\"open_source_licenses_sub\">Se licenser til open source-biblioteker, der bruges i denne app</string>\n    <string name=\"area\">Areal</string>\n    <string name=\"area_sub\">Resampling ved hjælp af pixelarealrelation. Det kan være en foretrukken metode til billeddecimering, da det giver moire\\'-fri resultater. Men når billedet er zoomet ind, ligner det \\\"Nærmeste\\\"-metoden.</string>\n    <string name=\"enable_tonemapping\">Aktiver tonemapping</string>\n    <string name=\"enter_percent\">Indtast %</string>\n    <string name=\"unknown_host\">Kan ikke få adgang til webstedet, prøv at bruge VPN eller tjek om url\\'en er korrekt</string>\n    <string name=\"markup_layers\">Markup-lag</string>\n    <string name=\"markup_layers_sub\">Lagtilstand med mulighed for frit at placere billeder, tekst og mere</string>\n    <string name=\"edit_layer\">Rediger lag</string>\n    <string name=\"layers_on_image\">Lag på billedet</string>\n    <string name=\"layers_on_image_sub\">Brug et billede som baggrund og tilføj forskellige lag oven på det</string>\n    <string name=\"layers_on_background\">Lag på baggrund</string>\n    <string name=\"layers_on_background_sub\">Det samme som første mulighed, men med farve i stedet for billede</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Hurtige indstillinger side</string>\n    <string name=\"fast_settings_side_sub\">Tilføj en flydende strimmel på den valgte side, mens du redigerer billeder, som åbner hurtige indstillinger, når der klikkes på</string>\n    <string name=\"clear_selection\">Ryd markering</string>\n    <string name=\"settings_group_visibility_hidden\">Indstillingsgruppen \\\"%1$s\\\" vil blive skjult som standard</string>\n    <string name=\"settings_group_visibility_visible\">Indstillingsgruppen \\\"%1$s\\\" udvides som standard</string>\n    <string name=\"base_64_tools\">Base64 værktøjer</string>\n    <string name=\"base_64_tools_sub\">Afkod Base64-streng til billede, eller indkod billede til Base64-format</string>\n    <string name=\"base_64\">Base 64</string>\n    <string name=\"not_a_valid_base_64\">Den angivne værdi er ikke en gyldig Base64-streng</string>\n    <string name=\"copy_not_a_valid_base_64\">Kan ikke kopiere tom eller ugyldig Base64-streng</string>\n    <string name=\"paste_base_64\">Indsæt Base64</string>\n    <string name=\"copy_base_64\">Kopiér Base64</string>\n    <string name=\"base_64_tips\">Indlæs billede for at kopiere eller gemme Base64-streng. Hvis du har selve strengen, kan du indsætte den ovenfor for at få et billede</string>\n    <string name=\"save_base_64\">Gem Base64</string>\n    <string name=\"share_base_64\">Aktiebase64</string>\n    <string name=\"options\">Valgmuligheder</string>\n    <string name=\"actions\">Handlinger</string>\n    <string name=\"import_base_64\">Import Base64</string>\n    <string name=\"base_64_actions\">Base64-handlinger</string>\n    <string name=\"add_outline\">Tilføj disposition</string>\n    <string name=\"add_outline_sub\">Tilføj omrids omkring tekst med specificeret farve og bredde</string>\n    <string name=\"outline_color\">Konturfarve</string>\n    <string name=\"outline_size\">Omridsstørrelse</string>\n    <string name=\"rotation\">Rotation</string>\n    <string name=\"checksum_as_filename\">Kontrolsum som filnavn</string>\n    <string name=\"checksum_as_filename_sub\">Outputbilleder vil have et navn, der svarer til deres datakontrolsum</string>\n    <string name=\"free_software_partner\">Gratis software (partner)</string>\n    <string name=\"free_software_partner_sub\">Mere nyttig software i partnerkanalen for Android-applikationer</string>\n    <string name=\"algorithms\">Algoritme</string>\n    <string name=\"checksum_tools\">Kontrolsum værktøjer</string>\n    <string name=\"checksum_tools_sub\">Sammenlign kontrolsummer, beregn hashes eller opret hex-strenge fra filer ved hjælp af forskellige hashing-algoritmer</string>\n    <string name=\"calculate\">Beregne</string>\n    <string name=\"text_hash\">Tekst Hash</string>\n    <string name=\"checksum\">Kontrolsum</string>\n    <string name=\"pick_file_to_checksum\">Vælg fil for at beregne dens kontrolsum baseret på valgt algoritme</string>\n    <string name=\"enter_text_to_checksum\">Indtast tekst for at beregne dens kontrolsum baseret på den valgte algoritme</string>\n    <string name=\"source_checksum\">Kildekontrolsum</string>\n    <string name=\"checksum_to_compare\">Kontrolsum til sammenligning</string>\n    <string name=\"match\">Kamp!</string>\n    <string name=\"difference\">Forskel</string>\n    <string name=\"match_sub\">Kontrolsummer er lige store, det kan være sikkert</string>\n    <string name=\"difference_sub\">Kontrolsummer er ikke ens, filen kan være usikker!</string>\n    <string name=\"mesh_gradients\">Mesh gradienter</string>\n    <string name=\"collection_mesh_gradients_sub\">Se på online samling af Mesh Gradienter</string>\n    <string name=\"wrong_font\">Kun TTF- og OTF-skrifttyper kan importeres</string>\n    <string name=\"import_font\">Importer skrifttype (TTF/OTF)</string>\n    <string name=\"export_fonts\">Eksporter skrifttyper</string>\n    <string name=\"imported_fonts\">Importerede skrifttyper</string>\n    <string name=\"error_while_saving\">Fejl under lagring af forsøg. Prøv at ændre outputmappe</string>\n    <string name=\"filename_is_not_set\">Filnavn er ikke angivet</string>\n    <string name=\"none\">Ingen</string>\n    <string name=\"custom_pages\">Brugerdefinerede sider</string>\n    <string name=\"pages_selection\">Udvalg af sider</string>\n    <string name=\"tool_exit_confirmation\">Bekræftelse af værktøjsafslutning</string>\n    <string name=\"tool_exit_confirmation_sub\">Hvis du har ændringer, som ikke er gemt, mens du bruger bestemte værktøjer og prøver at lukke dem, vil bekræftelsesdialogen blive vist</string>\n    <string name=\"edit_exif_screen\">Rediger EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Skift metadata af enkelt billede uden rekomprimering</string>\n    <string name=\"edit_exif_tag\">Tryk for at redigere tilgængelige tags</string>\n    <string name=\"change_sticker\">Skift klistermærke</string>\n    <string name=\"fit_width\">Tilpas bredde</string>\n    <string name=\"fit_height\">Tilpas højde</string>\n    <string name=\"batch_compare\">Batch Sammenlign</string>\n    <string name=\"pick_files_to_checksum\">Vælg fil/filer for at beregne dens kontrolsum baseret på valgt algoritme</string>\n    <string name=\"pick_files\">Vælg filer</string>\n    <string name=\"pick_directory\">Vælg bibliotek</string>\n    <string name=\"head_length_scale\">Skala for hovedlængde</string>\n    <string name=\"stamp\">Stempel</string>\n    <string name=\"timestamp\">Tidsstempel</string>\n    <string name=\"format_pattern\">Formater mønster</string>\n    <string name=\"padding\">Polstring</string>\n    <string name=\"image_cutting\">Billedskæring</string>\n    <string name=\"image_cutting_sub\">Klip billeddelen og flet dem til venstre (kan være omvendt) med lodrette eller vandrette linjer</string>\n    <string name=\"vertical_pivot_line\">Lodret drejelinje</string>\n    <string name=\"horizontal_pivot_line\">Vandret drejelinje</string>\n    <string name=\"inverse_selection\">Omvendt valg</string>\n    <string name=\"inverse_vertical_selection_sub\">Lodret afskåret del vil blive forladt, i stedet for at flette dele rundt om det udskårne område</string>\n    <string name=\"inverse_horizontal_selection_sub\">Den vandrette afskårne del vil blive forladt, i stedet for at flette dele rundt om det udskårne område</string>\n    <string name=\"collection_mesh_gradients\">Samling af mesh gradienter</string>\n    <string name=\"mesh_gradients_sub\">Opret mesh-gradient med tilpasset mængde knob og opløsning</string>\n    <string name=\"gradient_maker_type_image_mesh\">Mesh Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Komponer mesh-gradient af toppen af ​​givne billeder</string>\n    <string name=\"points_customization\">Pointtilpasning</string>\n    <string name=\"grid_size\">Gitterstørrelse</string>\n    <string name=\"resolution_x\">Opløsning X</string>\n    <string name=\"resolution_y\">Opløsning Y</string>\n    <string name=\"resolution\">Opløsning</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">Fremhæv farve</string>\n    <string name=\"pixel_comparison_type\">Pixel sammenligningstype</string>\n    <string name=\"scan_barcode\">Scan stregkoden</string>\n    <string name=\"height_ratio\">Højdeforhold</string>\n    <string name=\"barcode_type\">Stregkode type</string>\n    <string name=\"enforce_bw\">Håndhæve S/H</string>\n    <string name=\"enforce_bw_sub\">Stregkodebilledet vil være helt sort og hvidt og ikke farvet af appens tema</string>\n    <string name=\"barcodes_sub\">Scan enhver stregkode (QR, EAN, AZTEC, …) og få dens indhold eller indsæt din tekst for at generere en ny</string>\n    <string name=\"no_barcode_found\">Ingen stregkode fundet</string>\n    <string name=\"generated_barcode_will_be_here\">Genereret stregkode vil være her</string>\n    <string name=\"audio_cover_extractor\">Audio Covers</string>\n    <string name=\"audio_cover_extractor_sub\">Udpak albumcoverbilleder fra lydfiler, de mest almindelige formater understøttes</string>\n    <string name=\"pick_audio_to_start\">Vælg lyd for at starte</string>\n    <string name=\"pick_audio\">Vælg lyd</string>\n    <string name=\"no_covers_found\">Ingen omslag fundet</string>\n    <string name=\"send_logs\">Send logs</string>\n    <string name=\"send_logs_sub\">Klik for at dele app-logfil, dette kan hjælpe mig med at finde problemet og løse problemer</string>\n    <string name=\"crash_title\">Ups… Noget gik galt</string>\n    <string name=\"crash_subtitle\">Du kan kontakte mig ved at bruge mulighederne nedenfor, og jeg vil prøve at finde en løsning.\\n(Glem ikke at vedhæfte logfiler)</string>\n    <string name=\"ocr_write_to_file\">Skriv til fil</string>\n    <string name=\"ocr_write_to_file_sub\">Udpak tekst fra en batch af billeder og gem den i den ene tekstfil</string>\n    <string name=\"ocr_write_to_metadata\">Skriv til metadata</string>\n    <string name=\"ocr_write_to_metadata_sub\">Udtræk tekst fra hvert billede, og placer det i EXIF-info af relative billeder</string>\n    <string name=\"invisible_mode\">Usynlig tilstand</string>\n    <string name=\"invisible_mode_sub\">Brug steganografi til at skabe øjensynlige vandmærker inde i bytes på dine billeder</string>\n    <string name=\"use_lsb\">Brug LSB</string>\n    <string name=\"use_lsb_sub\">LSB (Less Significant Bit) steganografimetode vil blive brugt, ellers FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Fjern automatisk røde øjne</string>\n    <string name=\"password\">Adgangskode</string>\n    <string name=\"unlock\">Lås op</string>\n    <string name=\"pdf_is_protected\">PDF er beskyttet</string>\n    <string name=\"operation_almost_complete\">Operation næsten afsluttet. Hvis du annullerer nu, skal du genstarte den</string>\n    <string name=\"sort_by_date_modified\">Ændret dato</string>\n    <string name=\"sort_by_date_modified_reversed\">Ændret dato (omvendt)</string>\n    <string name=\"sort_by_size\">Størrelse</string>\n    <string name=\"sort_by_size_reversed\">Størrelse (omvendt)</string>\n    <string name=\"sort_by_mime_type\">MIME-type</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME-type (omvendt)</string>\n    <string name=\"sort_by_extension\">Forlængelse</string>\n    <string name=\"sort_by_extension_reversed\">Udvidelse (omvendt)</string>\n    <string name=\"sort_by_date_added\">Dato tilføjet</string>\n    <string name=\"sort_by_date_added_reversed\">Dato tilføjet (omvendt)</string>\n    <string name=\"left_to_right\">Venstre mod højre</string>\n    <string name=\"right_to_left\">Højre til venstre</string>\n    <string name=\"top_to_bottom\">Top til bund</string>\n    <string name=\"bottom_to_top\">Bund til top</string>\n    <string name=\"liquid_glass\">Flydende glas</string>\n    <string name=\"liquid_glass_sub\">En switch baseret på nyligt annonceret IOS 26 og dets flydende glasdesignsystem</string>\n    <string name=\"pick_image_or_base64\">Vælg billede eller indsæt/importér Base64-data nedenfor</string>\n    <string name=\"type_image_link\">Indtast billedlink for at starte</string>\n    <string name=\"paste_link\">Indsæt link</string>\n    <string name=\"kaleidoscope\">Kalejdoskop</string>\n    <string name=\"secondary_angle\">Sekundær vinkel</string>\n    <string name=\"sides\">Sider</string>\n    <string name=\"channel_mix\">Kanalmix</string>\n    <string name=\"blue_green\">Blå grøn</string>\n    <string name=\"red_blue\">Rød blå</string>\n    <string name=\"green_red\">Grøn rød</string>\n    <string name=\"into_red\">Til rødt</string>\n    <string name=\"into_green\">Ind i grønt</string>\n    <string name=\"into_blue\">Til blå</string>\n    <string name=\"cyan\">Cyan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Gul</string>\n    <string name=\"color_halftone\">Farve Halvtone</string>\n    <string name=\"contour\">Kontur</string>\n    <string name=\"levels\">Niveauer</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi krystallisere</string>\n    <string name=\"shape\">Form</string>\n    <string name=\"stretch\">Strække</string>\n    <string name=\"randomness\">Tilfældighed</string>\n    <string name=\"despeckle\">Afpletter</string>\n    <string name=\"diffuse\">Diffus</string>\n    <string name=\"dog\">Hund</string>\n    <string name=\"second_radius\">Anden radius</string>\n    <string name=\"equalize\">Udlign</string>\n    <string name=\"glow\">Glød</string>\n    <string name=\"whirl_and_pinch\">Hvirvel og knib</string>\n    <string name=\"pointillize\">Pointilliser</string>\n    <string name=\"border_color\">Kantfarve</string>\n    <string name=\"polar_coordinates\">Polære koordinater</string>\n    <string name=\"rect_to_polar\">Ret til polar</string>\n    <string name=\"polar_to_rect\">Polar til rekt</string>\n    <string name=\"invert_in_circle\">Vend i cirkel</string>\n    <string name=\"reduce_noise\">Reducer støj</string>\n    <string name=\"simple_solarize\">Simpel solarisering</string>\n    <string name=\"weave\">Væve</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X bredde</string>\n    <string name=\"y_wdth\">Y Bredde</string>\n    <string name=\"twirl\">Twirl</string>\n    <string name=\"rubber_stmp\">Gummistempel</string>\n    <string name=\"smear\">Smøre</string>\n    <string name=\"density\">Tæthed</string>\n    <string name=\"mix\">Blande</string>\n    <string name=\"sphere_lensh_distortion\">Sphere Lens Distortion</string>\n    <string name=\"refraction_index\">Brydningsindeks</string>\n    <string name=\"arc\">Bue</string>\n    <string name=\"spread_angle\">Spredningsvinkel</string>\n    <string name=\"sparkle\">Glitrende</string>\n    <string name=\"rays\">Stråler</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Mary</string>\n    <string name=\"autumn\">Efterår</string>\n    <string name=\"bone\">Knogle</string>\n    <string name=\"jet\">Stråle</string>\n    <string name=\"winter\">Vinter</string>\n    <string name=\"ocean\">Ocean</string>\n    <string name=\"summer\">Sommer</string>\n    <string name=\"spring\">Forår</string>\n    <string name=\"cool_variant\">Fed variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Lyserød</string>\n    <string name=\"hot\">Varmt</string>\n    <string name=\"parula\">Ord</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Borgere</string>\n    <string name=\"twilight\">Tusmørke</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspektiv Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Tillad beskæring</string>\n    <string name=\"crop_or_perspective\">Beskær eller perspektiv</string>\n    <string name=\"absolute\">Absolut</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Dyb Grøn</string>\n    <string name=\"lens_correction\">Linsekorrektion</string>\n    <string name=\"target_lens_profile\">Målobjektivprofilfil i JSON-format</string>\n    <string name=\"download_ready_lens_profiles\">Download klar linseprofiler</string>\n    <string name=\"part_percents\">Del procenter</string>\n    <string name=\"export_as_json\">Eksporter som JSON</string>\n    <string name=\"export_as_json_sub\">Kopier streng med en paletdata som json-repræsentation</string>\n    <string name=\"seam_carving\">Sømskæring</string>\n    <string name=\"home_screen\">Startskærm</string>\n    <string name=\"lock_screen\">Lås skærm</string>\n    <string name=\"built_in\">Indbygget</string>\n    <string name=\"wallpapers_export\">Tapet eksport</string>\n    <string name=\"refresh\">Opfriske</string>\n    <string name=\"wallpapers_export_sub\">Få aktuelle hjem, lås og indbyggede tapeter</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Tillad adgang til alle filer, dette er nødvendigt for at hente wallpapers</string>\n    <string name=\"allow_read_media_images_for_wp\">Administrer ekstern lagringstilladelse er ikke nok, du skal give adgang til dine billeder, sørg for at vælge \\\"Tillad alle\\\"</string>\n    <string name=\"add_preset_to_filename\">Tilføj forudindstilling til filnavn</string>\n    <string name=\"add_preset_to_filename_sub\">Tilføjer suffiks med valgt forudindstilling til billedfilnavn</string>\n    <string name=\"add_image_scale_mode_to_filename\">Tilføj billedskalatilstand til filnavn</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Tilføjer suffiks med valgt billedskaleringstilstand til billedfilnavnet</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Konverter billede til ascii-tekst, som vil ligne billede</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Anvender negativt filter på billedet for bedre resultat i nogle tilfælde</string>\n    <string name=\"processing_screenshot\">Behandler skærmbillede</string>\n    <string name=\"screenshot_not_captured_try_again\">Skærmbilledet blev ikke taget, prøv igen</string>\n    <string name=\"skipped_saving\">Lagring sprunget over</string>\n    <string name=\"skipped_saving_multiple\">%1$s filer sprunget over</string>\n    <string name=\"allow_skip_if_larger\">Tillad Spring over hvis større</string>\n    <string name=\"allow_skip_if_larger_sub\">Nogle værktøjer får lov til at springe over at gemme billeder, hvis den resulterende filstørrelse ville være større end originalen</string>\n    <string name=\"qr_type_calendar_event\">Kalenderbegivenhed</string>\n    <string name=\"qr_type_contact_info\">Kontakte</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Beliggenhed</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Tekst</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Åbent netværk</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Besked</string>\n    <string name=\"address\">Adresse</string>\n    <string name=\"subject\">Emne</string>\n    <string name=\"body\">Legeme</string>\n    <string name=\"name\">Navn</string>\n    <string name=\"organization\">Organisation</string>\n    <string name=\"title\">Titel</string>\n    <string name=\"phones\">Telefoner</string>\n    <string name=\"emails\">E-mails</string>\n    <string name=\"urls\">URL\\'er</string>\n    <string name=\"addresses\">adresser</string>\n    <string name=\"summary\">Oversigt</string>\n    <string name=\"description\">Beskrivelse</string>\n    <string name=\"location\">Beliggenhed</string>\n    <string name=\"organizer\">Arrangør</string>\n    <string name=\"start_date\">Startdato</string>\n    <string name=\"end_date\">Slutdato</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Breddegrad</string>\n    <string name=\"longitude\">Længde</string>\n    <string name=\"create_barcode\">Opret stregkode</string>\n    <string name=\"edit_barcode\">Rediger stregkode</string>\n    <string name=\"wifi_configuration\">Wi-Fi konfiguration</string>\n    <string name=\"security\">Sikkerhed</string>\n    <string name=\"pick_contact\">Vælg kontakt</string>\n    <string name=\"grant_contact_permission\">Giv kontaktpersoner tilladelse i indstillingerne til at autofylde ved hjælp af den valgte kontakt</string>\n    <string name=\"contact_info\">Kontakt info</string>\n    <string name=\"first_name\">Fornavn</string>\n    <string name=\"middle_name\">Mellemnavn</string>\n    <string name=\"last_name\">Efternavn</string>\n    <string name=\"pronunciation\">Udtale</string>\n    <string name=\"add_phone\">Tilføj telefon</string>\n    <string name=\"add_email\">Tilføj e-mail</string>\n    <string name=\"add_address\">Tilføj adresse</string>\n    <string name=\"website\">Hjemmeside</string>\n    <string name=\"add_website\">Tilføj hjemmeside</string>\n    <string name=\"formatted_name\">Formateret navn</string>\n    <string name=\"qr_code_top_image\">Dette billede vil blive brugt til at placere over stregkoden</string>\n    <string name=\"code_customization\">Kodetilpasning</string>\n    <string name=\"qr_logo_image\">Dette billede vil blive brugt som logo i midten af ​​QR-koden</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo polstring</string>\n    <string name=\"logo_size\">Logo størrelse</string>\n    <string name=\"logo_corners\">Logo hjørner</string>\n    <string name=\"fourth_eye\">Fjerde øje</string>\n    <string name=\"fourth_eye_description\">Tilføjer øjensymmetri til qr-koden ved at tilføje det fjerde øje i det nederste endehjørne</string>\n    <string name=\"pixel_shape\">Pixel form</string>\n    <string name=\"frame_shape\">Rammeform</string>\n    <string name=\"ball_shape\">Kugleform</string>\n    <string name=\"error_correction_level\">Fejlkorrektionsniveau</string>\n    <string name=\"dark_color\">Mørk farve</string>\n    <string name=\"light_color\">Lys farve</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS-lignende stil</string>\n    <string name=\"mask_pattern\">Maske mønster</string>\n    <string name=\"code_may_be_not_scannable\">Denne kode kan muligvis ikke scannes, skift udseendeparametre for at gøre den læsbar med alle enheder</string>\n    <string name=\"not_scannable\">Kan ikke scannes</string>\n    <string name=\"launcher_mode_sub\">Værktøjer vil ligne startskærmens appstarter for at være mere kompakt</string>\n    <string name=\"launcher_mode\">Launcher-tilstand</string>\n    <string name=\"flood_fill_sub\">Fylder et område med udvalgt pensel og stil</string>\n    <string name=\"flood_fill\">Flood Fyld</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Tegner graffity-stilet sti</string>\n    <string name=\"square_particles\">Firkantede partikler</string>\n    <string name=\"square_particles_sub\">Spraypartikler vil være firkantede i stedet for cirkler</string>\n    <string name=\"palette_tools\">Paletværktøjer</string>\n    <string name=\"palette_tools_sub\">Generer basis-/materiale, du paletter fra billede, eller importer/eksportér på tværs af forskellige paletformater</string>\n    <string name=\"edit_palette\">Rediger palet</string>\n    <string name=\"edit_palette_sub\">Eksporter/importer palet på tværs af forskellige formater</string>\n    <string name=\"color_name\">Farvenavn</string>\n    <string name=\"palette_name\">Palette navn</string>\n    <string name=\"palette_format\">Palette format</string>\n    <string name=\"export_palette_sub\">Eksporter genereret palet til forskellige formater</string>\n    <string name=\"add_color_palette_sub\">Tilføjer ny farve til den nuværende palet</string>\n    <string name=\"palette_name_not_supported\">Formatet %1$s understøtter ikke at angive paletnavn</string>\n    <string name=\"wallpapers_export_not_avaialbe\">På grund af Play Butiks politikker kan denne funktion ikke inkluderes i den aktuelle build. For at få adgang til denne funktionalitet skal du downloade ImageToolbox fra en alternativ kilde. Du kan finde de tilgængelige builds på GitHub nedenfor.</string>\n    <string name=\"open_github_page\">Åbn Github-siden</string>\n    <string name=\"overwrite_files_sub_short\">Den originale fil vil blive erstattet med en ny i stedet for at gemme den i den valgte mappe</string>\n    <string name=\"hidden_watermark_text_detected\">Registreret skjult vandmærketekst</string>\n    <string name=\"hidden_watermark_image_detected\">Registreret skjult vandmærkebillede</string>\n    <string name=\"this_image_was_hidden\">Dette billede blev skjult</string>\n    <string name=\"generative_inpaint\">Generativ indmaling</string>\n    <string name=\"generative_inpaint_sub\">Giver dig mulighed for at fjerne objekter i et billede ved hjælp af en AI-model uden at være afhængig af OpenCV. For at bruge denne funktion vil appen downloade den påkrævede model (~200 MB) fra GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Giver dig mulighed for at fjerne objekter i et billede ved hjælp af en AI-model uden at være afhængig af OpenCV. Dette kan være en langvarig operation</string>\n    <string name=\"error_level_analysis\">Analyse af fejlniveau</string>\n    <string name=\"luminance_gradient\">Luminansgradient</string>\n    <string name=\"average_distance\">Gennemsnitlig afstand</string>\n    <string name=\"copy_move_detection\">Detektion af kopibevægelse</string>\n    <string name=\"retain\">Beholde</string>\n    <string name=\"coefficent\">Koefficient</string>\n    <string name=\"clipboard_data_is_too_large\">Udklipsholderdata er for store</string>\n    <string name=\"data_is_too_large_to_copy\">Data er for store til at kopiere</string>\n    <string name=\"simple_weave_pixelization\">Simpel vævningspixelisering</string>\n    <string name=\"staggered_pixelization\">Forskudt pixelisering</string>\n    <string name=\"cross_pixelization\">Krydspixelisering</string>\n    <string name=\"micro_macro_pixelization\">Mikromakropixelisering</string>\n    <string name=\"orbital_pixelization\">Orbital pixelisering</string>\n    <string name=\"vortex_pixelization\">Vortex pixelisering</string>\n    <string name=\"pulse_grid_pixelization\">Puls Grid Pixelization</string>\n    <string name=\"nucleus_pixelization\">Nucleus Pixelization</string>\n    <string name=\"radial_weave_pixelization\">Radial vævningspixelisering</string>\n    <string name=\"cannot_open_uri\">Kan ikke åbne uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Snefaldstilstand</string>\n    <string name=\"enabled\">Aktiveret</string>\n    <string name=\"border_frame\">Kantramme</string>\n    <string name=\"glitch_variant\">Glitch-variant</string>\n    <string name=\"channel_shift\">Kanalskift</string>\n    <string name=\"max_offset\">Max offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Bloker fejl</string>\n    <string name=\"block_size\">Blokstørrelse</string>\n    <string name=\"crt_curvature\">CRT-krumning</string>\n    <string name=\"curvature\">Krumning</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">AI værktøjer</string>\n    <string name=\"ai_tools_sub\">Forskellige værktøjer til at behandle billeder gennem ai-modeller som f.eks. fjernelse af artefakter eller denoising</string>\n    <string name=\"model_anime_undeint\">Kompression, takkede linjer</string>\n    <string name=\"model_broadcast\">Tegnefilm, udsendelseskomprimering</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Generel kompression, generel støj</string>\n    <string name=\"model_wb_denoise\">Farveløs tegneseriestøj</string>\n    <string name=\"model_span_anime_pretrain\">Hurtig, generel komprimering, generel støj, animation/tegneserier/anime</string>\n    <string name=\"model_book_scan\">Bogscanning</string>\n    <string name=\"model_overexposure\">Eksponeringskorrektion</string>\n    <string name=\"model_fbcnn_color_fp16\">Bedst til generel komprimering, farvebilleder</string>\n    <string name=\"model_fbcnn_gray_fp16\">Bedst til generel komprimering, gråtonebilleder</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Generel komprimering, gråtonebilleder, stærkere</string>\n    <string name=\"model_scunet_color_gan_fp16\">Generel støj, farvebilleder</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Generel støj, farvebilleder, bedre detaljer</string>\n    <string name=\"model_scunet_gray_15_fp16\">Generel støj, gråtonebilleder</string>\n    <string name=\"model_scunet_gray_25_fp16\">Generel støj, gråtonebilleder, stærkere</string>\n    <string name=\"model_scunet_gray_50_fp16\">Generel støj, gråtonebilleder, stærkest</string>\n    <string name=\"model_jpeg_destroyer\">Generel kompression</string>\n    <string name=\"model_jaywreck\">Generel kompression</string>\n    <string name=\"model_h264\">Teksturering, h264 komprimering</string>\n    <string name=\"model_vhs\">VHS-komprimering</string>\n    <string name=\"model_cinepak\">Ikke-standard komprimering (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink kompression, bedre på geometri</string>\n    <string name=\"model_debink_v5\">Bink kompression, stærkere</string>\n    <string name=\"model_debink_v6\">Bink kompression, blød, bevarer detaljer</string>\n    <string name=\"model_antialias\">Eliminerer trappetrinseffekten, udjævner</string>\n    <string name=\"model_kdm_scans\">Scannet kunst/tegninger, mild kompression, moire</string>\n    <string name=\"model_bandage\">Farvebånd</string>\n    <string name=\"model_halftone\">Langsom, fjernende halvtoner</string>\n    <string name=\"model_colorizer\">Generel farvestof til gråtone-/bw-billeder, for bedre resultater brug DDColor</string>\n    <string name=\"model_deedge\">Kantfjernelse</string>\n    <string name=\"model_desharpen\">Fjerner overslibning</string>\n    <string name=\"model_dither\">Langsomt, rystende</string>\n    <string name=\"model_gainres\">Anti-aliasing, generelle artefakter, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 scanner behandling</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Letvægts billedforbedringsmodel</string>\n    <string name=\"model_bcgone_detailed_v2\">Fjernelse af kompressionsartefakter</string>\n    <string name=\"model_bcgone_smooth\">Fjernelse af kompressionsartefakter</string>\n    <string name=\"model_bandage_smooth\">Bandagefjernelse med glatte resultater</string>\n    <string name=\"model_bendel_halftone\">Halvtonemønsterbehandling</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Dither mønster fjernelse V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Fjernelse af JPEG-artefakter V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 teksturforbedring</string>\n    <string name=\"model_vhs_sharpen\">VHS skarphed og forbedring</string>\n    <string name=\"merging\">Sammenlægning</string>\n    <string name=\"chunk_size\">Chunk størrelse</string>\n    <string name=\"overlap_size\">Overlap størrelse</string>\n    <string name=\"note_chunk_info\">Billeder over %1$s px vil blive skåret i skiver og behandlet i bidder, overlappende blander disse for at forhindre synlige sømme.</string>\n    <string name=\"large_chunk_warning\">Store størrelser kan forårsage ustabilitet med low-end enheder</string>\n    <string name=\"select_one_to_start\">Vælg en for at starte</string>\n    <string name=\"delete_model_sub\">Vil du slette %1$s model? Du skal downloade den igen</string>\n    <string name=\"confirm\">Bekræfte</string>\n    <string name=\"models\">Modeller</string>\n    <string name=\"downloaded_models\">Downloadede modeller</string>\n    <string name=\"available_models\">Tilgængelige modeller</string>\n    <string name=\"preparing\">Forbereder</string>\n    <string name=\"active_model\">Aktiv model</string>\n    <string name=\"failed_to_open_session\">Sessionen kunne ikke åbnes</string>\n    <string name=\"only_onnx_models\">Kun .onnx/.ort-modeller kan importeres</string>\n    <string name=\"import_model\">Import model</string>\n    <string name=\"import_model_sub\">Importer tilpasset onnx-model til videre brug, kun onnx/ort-modeller accepteres, understøtter næsten alle esrgan-lignende varianter</string>\n    <string name=\"imported_models\">Importerede modeller</string>\n    <string name=\"model_scunet_color_15_fp16\">Generel støj, farvede billeder</string>\n    <string name=\"model_scunet_color_25_fp16\">Generel støj, farvede billeder, stærkere</string>\n    <string name=\"model_scunet_color_50_fp16\">Generel støj, farvede billeder, stærkest</string>\n    <string name=\"model_artifacts_dithering_alsa\">Reducerer dithering-artefakter og farvestriber, hvilket forbedrer jævne gradienter og flade farveområder.</string>\n    <string name=\"model_nmkd_brighten_redux\">Forbedrer billedets lysstyrke og kontrast med afbalancerede højlys, mens naturlige farver bevares.</string>\n    <string name=\"model_nmkd_brighten\">Gør mørke billeder lysere, samtidig med at detaljer bevares og overeksponering undgås.</string>\n    <string name=\"model_nmkd_detoon\">Fjerner overdreven farvetoning og genopretter en mere neutral og naturlig farvebalance.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Anvender Poisson-baseret støjtoning med vægt på at bevare fine detaljer og teksturer.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Anvender blød Poisson-støjtoning for jævnere og mindre aggressive visuelle resultater.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Ensartet støjtoning med fokus på detaljebevarelse og billedklarhed.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Blid ensartet støjtoning for subtil tekstur og glat udseende.</string>\n    <string name=\"model_repainter\">Reparerer beskadigede eller ujævne områder ved at male artefakter igen og forbedre billedkonsistensen.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Letvægts debanding-model, der fjerner farvestriber med minimal ydeevne.</string>\n    <string name=\"model_jpeg_0_20\">Optimerer billeder med meget høje kompressionsartefakter (0-20 % kvalitet) for forbedret klarhed.</string>\n    <string name=\"model_jpeg_20_40\">Forbedrer billeder med høje kompressionsartefakter (20-40 % kvalitet), genskaber detaljer og reducerer støj.</string>\n    <string name=\"model_jpeg_40_60\">Forbedrer billeder med moderat komprimering (40-60% kvalitet), balancerer skarphed og glathed.</string>\n    <string name=\"model_jpeg_60_80\">Forfiner billeder med let komprimering (60-80 % kvalitet) for at forbedre subtile detaljer og teksturer.</string>\n    <string name=\"model_jpeg_80_100\">Forbedrer næsten tabsfrie billeder en smule (80-100 % kvalitet), samtidig med at det naturlige udseende og detaljer bevares.</string>\n    <string name=\"model_spongecolor_lite\">Enkel og hurtig farvelægning, tegnefilm, ikke ideelt</string>\n    <string name=\"model_deblr\">Reducerer billedsløring en smule og forbedrer skarpheden uden at introducere artefakter.</string>\n    <string name=\"processing_channel\">Langvarige operationer</string>\n    <string name=\"processing_image\">Behandler billede</string>\n    <string name=\"processing\">Forarbejdning</string>\n    <string name=\"model_artifacts_jpg_0_20\">Fjerner tunge JPEG-komprimeringsartefakter i billeder af meget lav kvalitet (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Reducerer stærke JPEG-artefakter i stærkt komprimerede billeder (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Rydder op i moderate JPEG-artefakter, mens billeddetaljerne bevares (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Forfiner lette JPEG-artefakter i billeder af ret høj kvalitet (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Reducerer subtilt mindre JPEG-artefakter i næsten tabsfri billeder (80-100%).</string>\n    <string name=\"model_redetail_v2\">Forbedrer fine detaljer og teksturer, forbedrer den opfattede skarphed uden tunge artefakter.</string>\n    <string name=\"processing_finished\">Behandling afsluttet</string>\n    <string name=\"processing_failed\">Behandlingen mislykkedes</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Forbedrer hudens teksturer og detaljer, mens den bevarer et naturligt udseende, optimeret til hastighed.</string>\n    <string name=\"model_sbdv_dejpeg\">Fjerner JPEG-komprimeringsartefakter og gendanner billedkvaliteten for komprimerede fotos.</string>\n    <string name=\"model_iso_denoise_v1\">Reducerer ISO-støj i billeder taget under svagt lys, og bevarer detaljer.</string>\n    <string name=\"model_dejumbo\">Korrigerer overeksponerede eller \\\"jumbo\\\" highlights og genopretter en bedre tonal balance.</string>\n    <string name=\"model_ddcolor_tiny\">Let og hurtig farvelægningsmodel, der tilføjer naturlige farver til gråtonebilleder.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Farvelæg</string>\n    <string name=\"type_artifacts\">Artefakter</string>\n    <string name=\"type_enhance\">Forbedre</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Scanninger</string>\n    <string name=\"type_upscale\">Fornemme</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler til generelle billeder; lille model, der bruger mindre GPU og tid, med moderat sløring og denoise.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler til generelle billeder, bevarer teksturer og naturlige detaljer.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 upscaler til generelle billeder med forbedrede teksturer og realistiske resultater.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler optimeret til anime billeder; 6 RRDB blokke for skarpere linjer og detaljer.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 opskalerer med MSE-tab, producerer jævnere resultater og reducerede artefakter til generelle billeder.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimeret til anime-billeder; 4B32F variant med skarpere detaljer og glatte linjer.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2-model til generelle billeder; understreger skarphed og klarhed.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; hurtigere og mindre, bevarer detaljer, mens du bruger mindre GPU-hukommelse.</string>\n    <string name=\"model_rmbg_1_4\">Letvægtsmodel til hurtig fjernelse af baggrunden. Afbalanceret ydeevne og nøjagtighed. Arbejder med portrætter, objekter og scener. Anbefales til de fleste anvendelsestilfælde.</string>\n    <string name=\"type_removebg\">Fjern BG</string>\n    <string name=\"horizontal_border_thickness\">Vandret kanttykkelse</string>\n    <string name=\"vertical_border_thickness\">Lodret kanttykkelse</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s farve</item>\n        <item quantity=\"other\">%1$s farver</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Den nuværende model understøtter ikke chunking, billedet vil blive behandlet i originale dimensioner, dette kan forårsage højt hukommelsesforbrug og problemer med low-end enheder</string>\n    <string name=\"chunking_disabled\">Chunking deaktiveret, billede vil blive behandlet i originale dimensioner, dette kan forårsage højt hukommelsesforbrug og problemer med low-end enheder, men kan give bedre resultater ved slutninger</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">Høj nøjagtig billedsegmenteringsmodel til fjernelse af baggrund</string>\n    <string name=\"model_u2netp\">Letvægtsversion af U2Net til hurtigere fjernelse af baggrund med mindre hukommelsesforbrug.</string>\n    <string name=\"model_ddcolor\">Fuld DDColor-model leverer farvelægning af høj kvalitet til generelle billeder med minimale artefakter. Bedste valg af alle farvelægningsmodeller.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Trænede og private kunstneriske datasæt; producerer forskellige og kunstneriske farvelægningsresultater med færre urealistiske farveartefakter.</string>\n    <string name=\"model_birefnet\">Letvægts BiRefNet-model baseret på Swin Transformer til nøjagtig baggrundsfjernelse.</string>\n    <string name=\"model_inspyrenet\">Baggrundsfjernelse i høj kvalitet med skarpe kanter og fremragende detaljebevarelse, især på komplekse genstande og vanskelige baggrunde.</string>\n    <string name=\"model_isnet\">Baggrundsfjernelsesmodel, der producerer nøjagtige masker med glatte kanter, velegnet til generelle genstande og moderat detaljebevarelse.</string>\n    <string name=\"model_already_downloaded\">Modellen er allerede downloadet</string>\n    <string name=\"model_successfully_imported\">Modellen blev importeret</string>\n    <string name=\"type\">Type</string>\n    <string name=\"keyword\">Søgeord</string>\n    <string name=\"very_fast\">Meget hurtig</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Langsom</string>\n    <string name=\"very_slow\">Meget langsom</string>\n    <string name=\"compute_percents\">Beregn procenter</string>\n    <string name=\"minimum_value_is\">Min. værdi er %1$s</string>\n    <string name=\"warp_sub\">Forvrænget billedet ved at tegne med fingrene</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">Hårdhed</string>\n    <string name=\"warp_mode\">Warp-tilstand</string>\n    <string name=\"warp_mode_move\">Flytte</string>\n    <string name=\"warp_mode_grow\">Dyrke</string>\n    <string name=\"warp_mode_shrink\">Krympe</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Hvirvel mod venstre</string>\n    <string name=\"fade_strength\">Fade Styrke</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Nederste fald</string>\n    <string name=\"start_drop\">Start Drop</string>\n    <string name=\"end_drop\">Slut Drop</string>\n    <string name=\"downloading\">Downloader</string>\n    <string name=\"smooth_shapes\">Glatte former</string>\n    <string name=\"smooth_shapes_sub\">Brug superellipser i stedet for standard afrundede rektangler for glattere, mere naturlige former</string>\n    <string name=\"shape_type\">Form Type</string>\n    <string name=\"cut\">Skære</string>\n    <string name=\"rounded\">Afrundet</string>\n    <string name=\"smooth\">Glat</string>\n    <string name=\"cut_shapes_sub\">Skarpe kanter uden afrunding</string>\n    <string name=\"rounded_shapes_sub\">Klassiske afrundede hjørner</string>\n    <string name=\"shapes_type\">Former Type</string>\n    <string name=\"corners_size\">Hjørner Størrelse</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elegante afrundede UI-elementer</string>\n    <string name=\"filename_format\">Filnavn format</string>\n    <string name=\"prefix_pattern_description\">Brugerdefineret tekst placeret helt i begyndelsen af ​​filnavnet, perfekt til projektnavne, mærker eller personlige tags.</string>\n    <string name=\"original_filename_pattern_description\">Bruger det originale filnavn uden filtypenavn, hvilket hjælper dig med at holde kildeidentifikationen intakt.</string>\n    <string name=\"width_pattern_description\">Billedbredden i pixels, nyttig til sporing af opløsningsændringer eller skalering af resultater.</string>\n    <string name=\"height_pattern_description\">Billedhøjden i pixels, nyttigt, når du arbejder med billedformater eller eksporter.</string>\n    <string name=\"random_numbers_pattern_description\">Genererer tilfældige cifre for at garantere unikke filnavne; tilføje flere cifre for ekstra sikkerhed mod dubletter.</string>\n    <string name=\"sequence_number_pattern_description\">Auto-inkrementerende tæller til batch-eksport, ideel, når du gemmer flere billeder i én session.</string>\n    <string name=\"preset_info_pattern_description\">Indsætter det anvendte forudindstillede navn i filnavnet, så du nemt kan huske, hvordan billedet blev behandlet.</string>\n    <string name=\"scale_mode_pattern_description\">Viser billedskaleringstilstanden, der bruges under behandling, og hjælper med at skelne mellem ændrede, beskårne eller tilpassede billeder.</string>\n    <string name=\"suffix_pattern_description\">Brugerdefineret tekst placeret i slutningen af ​​filnavnet, nyttig til versionering som _v2, _edited eller _final.</string>\n    <string name=\"extension_pattern_description\">Filtypenavnet (png, jpg, webp osv.), der automatisk matcher det faktiske gemte format.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Et tilpasseligt tidsstempel, der lader dig definere dit eget format efter java-specifikation for perfekt sortering.</string>\n    <string name=\"fling_type\">Fling Type</string>\n    <string name=\"android_native\">Indbygget Android</string>\n    <string name=\"ios_style\">iOS stil</string>\n    <string name=\"smooth_curve\">Glat kurve</string>\n    <string name=\"quick_stop\">Hurtigt stop</string>\n    <string name=\"bouncy\">hoppende</string>\n    <string name=\"floaty\">Flydende</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Ultra Glat</string>\n    <string name=\"adaptive\">Adaptiv</string>\n    <string name=\"accessibility_aware\">Tilgængelighedsbevidst</string>\n    <string name=\"reduced_motion\">Reduceret bevægelse</string>\n    <string name=\"android_native_sub\">Indbygget Android rullefysik</string>\n    <string name=\"smooth_sub\">Balanceret, jævn rulning til generel brug</string>\n    <string name=\"ios_style_sub\">Højere friktion iOS-lignende rulleadfærd</string>\n    <string name=\"smooth_curve_sub\">Unik splinekurve for tydelig rullefølelse</string>\n    <string name=\"quick_stop_sub\">Præcis rulning med hurtig stop</string>\n    <string name=\"bouncy_sub\">Legesyg, responsiv hoppende rulle</string>\n    <string name=\"floaty_sub\">Lange, glidende ruller til gennemsyn af indhold</string>\n    <string name=\"snappy_sub\">Hurtig, responsiv rulning til interaktive brugergrænseflader</string>\n    <string name=\"ultra_smooth_sub\">Premium jævn rulning med udvidet momentum</string>\n    <string name=\"adaptive_sub\">Justerer fysik baseret på slyngehastighed</string>\n    <string name=\"accessibility_aware_sub\">Respekterer systemtilgængelighedsindstillinger</string>\n    <string name=\"reduced_motion_sub\">Minimal bevægelse for tilgængelighedsbehov</string>\n    <string name=\"primary_lines\">Primære Linjer</string>\n    <string name=\"primary_lines_sub\">Tilføjer tykkere linje hver femte linje</string>\n    <string name=\"fill_color\">Fyld farve</string>\n    <string name=\"hidden_tools\">Skjulte værktøjer</string>\n    <string name=\"hidden_for_share\">Værktøjer skjult til deling</string>\n    <string name=\"color_library\">Farvebibliotek</string>\n    <string name=\"color_library_sub\">Gennemse en stor samling af farver</string>\n    <string name=\"model_fatality_deblur\">Gør skarpere og fjerner sløring fra billeder, samtidig med at de naturlige detaljer bevares, ideel til at rette ufokuserede billeder.</string>\n    <string name=\"model_unresize_v3\">Intelligent gendanner billeder, der tidligere er blevet ændret, og genskaber mistede detaljer og teksturer.</string>\n    <string name=\"model_liveaction_v1_span\">Optimeret til live-action-indhold, reducerer kompressionsartefakter og forbedrer fine detaljer i film-/tv-showrammer.</string>\n    <string name=\"model_vhs2hd_realplksr\">Konverterer optagelser i VHS-kvalitet til HD, fjerner båndstøj og forbedrer opløsningen, samtidig med at vintage-følelsen bevares.</string>\n    <string name=\"model_text2hd_v1\">Specialiseret til teksttunge billeder og skærmbilleder, skærper tegn og forbedrer læsbarheden.</string>\n    <string name=\"model_frankendata_pretrainer\">Avanceret opskalering trænet på forskellige datasæt, fremragende til generelle fotoforbedring.</string>\n    <string name=\"model_realwebphoto_v2\">Optimeret til webkomprimerede billeder, fjerner JPEG-artefakter og genopretter det naturlige udseende.</string>\n    <string name=\"model_realwebphoto_v4\">Forbedret version til webfotos med bedre teksturbevarelse og reduktion af artefakter.</string>\n    <string name=\"model_dat_2x\">2x opskalering med Dual Aggregation Transformer-teknologi, bevarer skarphed og naturlige detaljer.</string>\n    <string name=\"model_dat_3x\">3x opskalering ved hjælp af avanceret transformerarkitektur, ideel til moderate forstørrelsesbehov.</string>\n    <string name=\"model_dat_4x\">4x højkvalitets opskalering med state-of-the-art transformer netværk, bevarer fine detaljer i større skalaer.</string>\n    <string name=\"model_nafnet_deblurring\">Fjerner sløring/støj og rystelser fra fotos. Generelt formål, men bedst på billeder.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Gendanner billeder i lav kvalitet ved hjælp af Swin2SR-transformer, optimeret til BSRGAN-nedbrydning. Fantastisk til at fikse tunge kompressionsartefakter og forbedre detaljer i 4x skala.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x opskalering med SwinIR-transformer trænet på BSRGAN-nedbrydning. Bruger GAN til skarpere teksturer og mere naturlige detaljer i fotos og komplekse scener.</string>\n    <string name=\"path\">Sti</string>\n    <string name=\"merge_pdf\">Flet PDF</string>\n    <string name=\"merge_pdf_sub\">Kombiner flere PDF-filer til ét dokument</string>\n    <string name=\"files_order\">Filer rækkefølge</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Opdel PDF</string>\n    <string name=\"split_pdf_sub\">Uddrag bestemte sider fra PDF-dokument</string>\n    <string name=\"rotate_pdf\">Roter PDF</string>\n    <string name=\"rotate_pdf_sub\">Ret sideretning permanent</string>\n    <string name=\"pages\">Sider</string>\n    <string name=\"rearrange_pdf\">Omarranger PDF</string>\n    <string name=\"rearrange_pdf_sub\">Træk og slip sider for at omarrangere dem</string>\n    <string name=\"hold_drag_drop\">Hold og træk sider</string>\n    <string name=\"page_numbers\">Sidetal</string>\n    <string name=\"page_numbers_sub\">Tilføj automatisk nummerering til dine dokumenter</string>\n    <string name=\"label_format\">Etiketformat</string>\n    <string name=\"pdf_to_text\">PDF til tekst (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Uddrag almindelig tekst fra dine PDF-dokumenter</string>\n    <string name=\"watermark_pdf_sub\">Overlay tilpasset tekst til branding eller sikkerhed</string>\n    <string name=\"signature\">Signatur</string>\n    <string name=\"signature_sub\">Tilføj din elektroniske signatur til ethvert dokument</string>\n    <string name=\"will_be_for_signature\">Dette vil blive brugt som signatur</string>\n    <string name=\"unlock_pdf\">Lås PDF op</string>\n    <string name=\"unlock_pdf_sub\">Fjern adgangskoder fra dine beskyttede filer</string>\n    <string name=\"protect_pdf\">Beskyt PDF</string>\n    <string name=\"protect_pdf_sub\">Beskyt dine dokumenter med stærk kryptering</string>\n    <string name=\"success\">Succes</string>\n    <string name=\"pdf_unlocked\">PDF ulåst, du kan gemme eller dele det</string>\n    <string name=\"repair_pdf\">Reparation af pdf</string>\n    <string name=\"repair_pdf_sub\">Forsøg på at rette beskadigede eller ulæselige dokumenter</string>\n    <string name=\"grayscale\">Gråtoner</string>\n    <string name=\"grayscale_pdf_sub\">Konverter alle dokumentindlejrede billeder til gråtoner</string>\n    <string name=\"compress_pdf\">Komprimer PDF</string>\n    <string name=\"compress_pdf_sub\">Optimer din dokumentfilstørrelse for nemmere deling</string>\n    <string name=\"repair_info\">ImageToolbox genopbygger den interne krydsreferencetabel og regenererer filstrukturen fra bunden. Dette kan gendanne adgangen til mange filer, der \\\\\"ikke kan åbnes\\\\\"</string>\n    <string name=\"grayscale_info\">Dette værktøj konverterer alle dokumentbilleder til gråtoner. Bedst til udskrivning og reduktion af filstørrelse</string>\n    <string name=\"metadata\">Metadata</string>\n    <string name=\"metadata_pdf_sub\">Rediger dokumentegenskaber for bedre privatliv</string>\n    <string name=\"tags\">Tags</string>\n    <string name=\"producer\">Producent</string>\n    <string name=\"author\">Forfatter</string>\n    <string name=\"keywords\">Nøgleord</string>\n    <string name=\"creator\">Skaber</string>\n    <string name=\"privacy_deep_clean\">Privatliv Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Ryd alle tilgængelige metadata for dette dokument</string>\n    <string name=\"page\">Side</string>\n    <string name=\"deep_ocr\">Dyb OCR</string>\n    <string name=\"deep_ocr_sub\">Uddrag tekst fra dokument og gem den i den ene tekstfil ved hjælp af Tesseract-motoren</string>\n    <string name=\"cant_remove_all\">Kan ikke fjerne alle sider</string>\n    <string name=\"remove_pages_pdf\">Fjern PDF-sider</string>\n    <string name=\"remove_pages_pdf_sub\">Fjern bestemte sider fra PDF-dokument</string>\n    <string name=\"tap_to_remove\">Tryk for at fjerne</string>\n    <string name=\"manually\">Manuelt</string>\n    <string name=\"crop_pdf\">Beskær PDF</string>\n    <string name=\"crop_pdf_sub\">Beskær dokumentsider til enhver grænse</string>\n    <string name=\"flatten_pdf\">Udglat PDF</string>\n    <string name=\"flatten_pdf_sub\">Gør PDF uændret ved at rastere dokumentsider</string>\n    <string name=\"camera_failed_to_open\">Kunne ikke starte kameraet. Tjek venligst tilladelser og sørg for, at den ikke bliver brugt af en anden app.</string>\n    <string name=\"extract_images\">Uddrag billeder</string>\n    <string name=\"extract_images_sub\">Uddrag billeder indlejret i PDF-filer i deres originale opløsning</string>\n    <string name=\"pdf_no_embedded\">Denne PDF-fil indeholder ingen indlejrede billeder</string>\n    <string name=\"extract_images_info\">Dette værktøj scanner hver side og gendanner kildebilleder i fuld kvalitet - perfekt til at gemme originaler fra dokumenter</string>\n    <string name=\"draw_signature\">Tegn signatur</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">Brug egen signatur som billede, der skal placeres på dokumenter</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Opdel dokument med givet interval og pak nye dokumenter i zip-arkiv</string>\n    <string name=\"interval\">Interval</string>\n    <string name=\"print_pdf\">Udskriv PDF</string>\n    <string name=\"print_pdf_sub\">Forbered dokumentet til udskrivning med brugerdefineret sidestørrelse</string>\n    <string name=\"pages_per_sheet\">Sider pr. ark</string>\n    <string name=\"orientation\">Orientering</string>\n    <string name=\"page_size\">Sidestørrelse</string>\n    <string name=\"margin\">Margin</string>\n    <string name=\"bloom\">Bloom</string>\n    <string name=\"soft_knee\">Blødt knæ</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimeret til anime og tegnefilm. Hurtig opskalering med forbedrede naturlige farver og færre artefakter</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7-lignende stil</string>\n    <string name=\"calculate_hint\">Indtast grundlæggende matematiske symboler her for at beregne den ønskede værdi (f.eks. (5+5)*10)</string>\n    <string name=\"math_expression\">Matematisk udtryk</string>\n    <string name=\"pick_up_to_n_collage_images\">Saml op til %1$s billeder</string>\n    <string name=\"keep_date_time\">Hold Dato Tid</string>\n    <string name=\"keep_date_time_sub\">Bevar altid exif-tags relateret til dato og klokkeslæt, fungerer uafhængigt af keep exif-indstillingen</string>\n    <string name=\"background_color_for_alpha_formats\">Baggrundsfarve til alfaformater</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Tilføjer mulighed for at indstille baggrundsfarve for hvert billedformat med alfa-understøttelse, når den er deaktiveret, er dette kun tilgængeligt for ikke-alfa-one</string>\n    <string name=\"open_markup_project\">Åbent projekt</string>\n    <string name=\"open_markup_project_sub\">Fortsæt med at redigere et tidligere gemt Image Toolbox-projekt</string>\n    <string name=\"markup_project_open_failed\">Kan ikke åbne Image Toolbox-projektet</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox-projektet mangler projektdata</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox-projektet er beskadiget</string>\n    <string name=\"unsupported_markup_project_version\">Ikke-understøttet Image Toolbox-projektversion: %1$d</string>\n    <string name=\"save_markup_project\">Gem projekt</string>\n    <string name=\"save_markup_project_sub\">Gem lag, baggrund og redigeringshistorik i en redigerbar projektfil</string>\n    <string name=\"failed_to_open\">Kunne ikke åbne</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Skriv til søgbar PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Genkend tekst fra billedbatch og gem søgbar PDF med billede og valgbart tekstlag</string>\n    <string name=\"layer_alpha\">Alfa lag</string>\n    <string name=\"horizontal_flip\">Vandret vending</string>\n    <string name=\"vertical_flip\">Lodret flip</string>\n    <string name=\"lock\">Låse</string>\n    <string name=\"add_shadow\">Tilføj skygge</string>\n    <string name=\"shadow_color\">Skygge farve</string>\n    <string name=\"text_geometry\">Tekstgeometri</string>\n    <string name=\"text_geometry_sub\">Stræk eller skæv tekst for skarpere stilisering</string>\n    <string name=\"scale_x\">Skala X</string>\n    <string name=\"skew_x\">Skæv X</string>\n    <string name=\"remove_annotations\">Fjern annoteringer</string>\n    <string name=\"remove_annotations_sub\">Fjern valgte annoteringstyper såsom links, kommentarer, fremhævninger, former eller formularfelter fra PDF-siderne</string>\n    <string name=\"annotation_link\">Hyperlinks</string>\n    <string name=\"annotation_file_attachment\">Vedhæftede filer</string>\n    <string name=\"annotation_line\">Linjer</string>\n    <string name=\"annotation_popup\">Popups</string>\n    <string name=\"annotation_stamp\">Frimærker</string>\n    <string name=\"annotation_shapes\">Former</string>\n    <string name=\"annotation_text\">Tekstnoter</string>\n    <string name=\"annotation_text_markup\">Tekstmarkering</string>\n    <string name=\"annotation_widget\">Formularfelter</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">Ukendt</string>\n    <string name=\"annotations\">Anmærkninger</string>\n    <string name=\"ungroup\">Ophæv grupperingen</string>\n    <string name=\"add_shadow_sub\">Tilføj sløret skygge bag lag med konfigurerbar farve og offsets</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-de/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"size\">Größe %1$s</string>\n    <string name=\"height\">Höhe %1$s</string>\n    <string name=\"quality\">Qualität</string>\n    <string name=\"resize_type\">Methode</string>\n    <string name=\"explicit\">Explizit</string>\n    <string name=\"no_palette\">Kann Farbpalette aus gewähltem Bild nicht erzeugen</string>\n    <string name=\"folder\">Ausgabeverzeichnis</string>\n    <string name=\"def\">Standardeinstellung</string>\n    <string name=\"custom\">Benutzerdefiniert</string>\n    <string name=\"by_bytes_resize_sub\">Ändern der Größe eines Bildes entsprechend der angegebenen Größe in KB</string>\n    <string name=\"settings\">Einstellungen</string>\n    <string name=\"system\">Nach Systemvorgabe</string>\n    <string name=\"night_mode\">Nachtmodus</string>\n    <string name=\"dark\">Dunkles Design</string>\n    <string name=\"light\">Helles Design</string>\n    <string name=\"customization\">Personalisierung</string>\n    <string name=\"allow_image_monet\">Farbschema von Bild</string>\n    <string name=\"amoled_mode\">AMOLED Modus</string>\n    <string name=\"amoled_mode_sub\">Alle dunklen Farben der Benutzeroberfläche werden im dunklen Design schwarz dargestellt</string>\n    <string name=\"color_scheme\">Farbschema</string>\n    <string name=\"extension\">Dateityp</string>\n    <string name=\"clipboard_paste_invalid_empty\">Die Zwischenablage ist leer</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Das App Farbschema kann nicht geändert werden, wenn dynamische Farben aktiviert sind</string>\n    <string name=\"pick_accent_color\">App-Farbschema basierend auf einer wählbaren Farbe ändern</string>\n    <string name=\"about_app\">Über die App</string>\n    <string name=\"no_updates\">Kein Update gefunden</string>\n    <string name=\"issue_tracker\">Fehlermeldungen</string>\n    <string name=\"issue_tracker_sub\">Sende Fehlermeldungen und Änderungswünsche hierhin</string>\n    <string name=\"help_translate\">Hilf beim Übersetzen</string>\n    <string name=\"smth_went_wrong\">Etwas ging schief: %1$s</string>\n    <string name=\"image_too_large_preview\">Bild ist zu groß für die Vorschau, es wird aber trotzdem versucht es zu speichern</string>\n    <string name=\"loading\">Lade…</string>\n    <string name=\"pick_image\">Zum Starten Bild wählen</string>\n    <string name=\"width\">Breite %1$s</string>\n    <string name=\"reset_image\">Bild zurücksetzen</string>\n    <string name=\"something_went_wrong\">Irgendetwas ging schief</string>\n    <string name=\"restart_app\">App neustarten</string>\n    <string name=\"copied\">In die Zwischenablage kopiert</string>\n    <string name=\"stay\">Bleiben</string>\n    <string name=\"add_tag\">Tag hinzufügen</string>\n    <string name=\"flexible\">Flexibel</string>\n    <string name=\"pick_image_alt\">Bild auswählen</string>\n    <string name=\"app_closing\">Schließe App</string>\n    <string name=\"reset\">Zurücksetzen</string>\n    <string name=\"app_closing_sub\">Bist du sicher, dass du die App schließen willst?</string>\n    <string name=\"close\">Schließen</string>\n    <string name=\"reset_image_sub\">Änderungen am Bild werden zu den Ursprungswerten zurückgesetzt</string>\n    <string name=\"values_reset\">Werte erfolgreich zurückgesetzt</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"crop\">Zuschneiden</string>\n    <string name=\"single_edit_sub\">Modifiziere, skaliere und bearbeite ein Bild</string>\n    <string name=\"exception\">Ausnahme</string>\n    <string name=\"edit_exif\">EXIF bearbeiten</string>\n    <string name=\"no_exif\">Keine EXIF Daten gefunden</string>\n    <string name=\"cancel\">Abbrechen</string>\n    <string name=\"presets\">Voreinstellungen</string>\n    <string name=\"image_not_saved\">Speichern</string>\n    <string name=\"clear\">Leeren</string>\n    <string name=\"clear_exif_sub\">Alle EXIF-Daten des Bildes werden gelöscht. Dies kann nicht rückgängig gemacht werden!</string>\n    <string name=\"save\">Speichern</string>\n    <string name=\"clear_exif\">EXIF leeren</string>\n    <string name=\"single_edit\">Einzelne Bearbeitung</string>\n    <string name=\"image_not_saved_sub\">Alle ungespeicherten Änderungen gehen verloren, wenn Du den Dialog jetzt schließt</string>\n    <string name=\"pick_color\">Farbwähler</string>\n    <string name=\"update\">Aktualisierung</string>\n    <string name=\"check_source_code\">Quellcode</string>\n    <string name=\"image\">Bild</string>\n    <string name=\"keep_exif\">EXIF behalten</string>\n    <string name=\"check_source_code_sub\">Aktuelle Meldungen, Problemmeldungen und mehr</string>\n    <string name=\"pick_color_sub\">Farbe aus einem Bild wählen und diese kopieren oder teilen</string>\n    <string name=\"color\">Farbe</string>\n    <string name=\"color_copied\">Farbe kopiert</string>\n    <string name=\"crop_sub\">Bild beliebig zuschneiden</string>\n    <string name=\"version\">Version</string>\n    <string name=\"images\">Bilder: %d</string>\n    <string name=\"change_preview\">Vorschaubild ändern</string>\n    <string name=\"remove\">Entfernen</string>\n    <string name=\"palette_sub\">Farbpalette aus einem angegebenen Bild erzeugen</string>\n    <string name=\"palette\">Farbpalette</string>\n    <string name=\"new_version\">Neue Version %1$s</string>\n    <string name=\"unsupported_type\">Dateityp wird nicht unterstützt: %1$s</string>\n    <string name=\"original\">Original</string>\n    <string name=\"generate_palette\">Palette erzeugen</string>\n    <string name=\"unspecified\">Nicht spezifiziert</string>\n    <string name=\"device_storage\">Gerätespeicher</string>\n    <string name=\"max_bytes\">Maximale Größe in KB</string>\n    <string name=\"by_bytes_resize\">Größe nach Gewicht ändern</string>\n    <string name=\"compare\">Vergleichen</string>\n    <string name=\"pick_two_images\">Wähle zwei Bilder zum Starten</string>\n    <string name=\"pick_images\">Wähle Bilder</string>\n    <string name=\"compare_sub\">Vergleiche zwei Bilder</string>\n    <string name=\"dynamic_colors\">Dynamisches Farbschema</string>\n    <string name=\"allow_image_monet_sub\">Ändert das Farbschema der App automatisch zum gewählten Bild</string>\n    <string name=\"language\">Sprache</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Füge einen gültigen aRGB Farb Code ein</string>\n    <string name=\"color_red\">Rot</string>\n    <string name=\"color_green\">Grün</string>\n    <string name=\"color_blue\">Blau</string>\n    <string name=\"search_here\">Hier suchen</string>\n    <string name=\"help_translate_sub\">Verbessere Übersetzungsfehler oder übersetze die App in andere Sprachen</string>\n    <string name=\"nothing_found_by_search\">Deine Suchanfrage hat nichts gefunden</string>\n    <string name=\"dynamic_colors_sub\">Wenn aktiviert, werden die Farben der Anwendung an die Farben des Hintergrundbildes angepasst.</string>\n    <string name=\"failed_to_save\">Fehler beim Speichern von %d-Bildern</string>\n    <string name=\"surface\">Oberfläche</string>\n    <string name=\"values\">Werte</string>\n    <string name=\"add\">Hinzufügen</string>\n    <string name=\"tertiary\">Tertiär</string>\n    <string name=\"secondary\">Sekundär</string>\n    <string name=\"primary\">Primär</string>\n    <string name=\"permission\">Berechtigung</string>\n    <string name=\"grant\">Gewähren</string>\n    <string name=\"permission_sub\">App benötigt Zugriff auf deinen Speicher, um Bilder zu speichern, es ist notwendig. Bitte erlaube deshalb im nächsten Dialog die Berechtigung.</string>\n    <string name=\"border_thickness\">Rahmenstärke</string>\n    <string name=\"grant_permission_manual\">Die App benötigt diese Berechtigung, um zu funktionieren, bitte erteile diese manuell</string>\n    <string name=\"external_storage\">Externer Speicher</string>\n    <string name=\"monet_colors\">„Monet“-Farben</string>\n    <string name=\"donation_sub\">Diese Anwendung ist völlig kostenlos, aber wenn du die Projektentwicklung unterstützen möchtest, klicke hier.</string>\n    <string name=\"check_updates\">Auf Aktualisierungen prüfen</string>\n    <string name=\"check_updates_sub\">Wenn aktiviert, wird der Aktualisierungsdialog nach dem Start der App angezeigt</string>\n    <string name=\"zoom\">Bild-Zoom</string>\n    <string name=\"fab_alignment\">FAB-Ausrichtung</string>\n    <string name=\"share\">Teilen</string>\n    <string name=\"prefix\">Präfix</string>\n    <string name=\"filename\">Dateiname</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Wähle, welches Emoji auf der Hauptseite angezeigt wird</string>\n    <string name=\"add_file_size\">Dateigröße hinzufügen</string>\n    <string name=\"add_file_size_sub\">Wenn aktiviert, werden Breite und Höhe des gespeicherten Bildes zum Namen der Ausgabedatei hinzugefügt</string>\n    <string name=\"delete_exif\">EXIF löschen</string>\n    <string name=\"delete_exif_sub\">EXIF-Metadaten von einem beliebigen Bilderpaar löschen</string>\n    <string name=\"image_preview\">Bildvorschau</string>\n    <string name=\"image_preview_sub\">Sieh dir jegliches Bildformat an: GIF, SVG usw.</string>\n    <string name=\"image_source\">Bildquelle</string>\n    <string name=\"gallery_picker\">Galerie</string>\n    <string name=\"photo_picker\">Bildauswahl</string>\n    <string name=\"gallery_picker_sub\">Einfache Bildauswahl mittels einer Galerie-App. Funktioniert nur, wenn du eine solche App installiert hast.</string>\n    <string name=\"order\">Reihenfolge</string>\n    <string name=\"order_sub\">Legt die Reihenfolge der Tools im Hauptfenster fest</string>\n    <string name=\"file_explorer_picker_sub\">Nutzt GetContent-Intent für die Bildauswahl. Funktioniert überall, kann aber auf manchen Geräten Probleme mit dem Empfangen der Bildauswahl haben (nicht meine Schuld)</string>\n    <string name=\"edit\">Bearbeiten</string>\n    <string name=\"options_arrangement\">Anordnung der Optionen</string>\n    <string name=\"add_original_filename\">Ursprünglichen Namen hinzufügen</string>\n    <string name=\"add_original_filename_sub\">Wenn aktiviert, fügt dies den ursprünglichen Dateinamen zum Namen des ausgegebenen Bildes hinzu</string>\n    <string name=\"original_filename\">UrsprName</string>\n    <string name=\"file_explorer_picker\">Dateimanager</string>\n    <string name=\"photo_picker_sub\">Androids aktuelle Fotoauswahl, die am unteren Rand des Bildschirms erscheint. Funktioniert möglicherweise nur auf Android 12+ und hat zudem Probleme mit dem Empfang von EXIF-Metadaten</string>\n    <string name=\"image_link\">Bild-Link</string>\n    <string name=\"load_image_from_net\">Laden von Web Bildern</string>\n    <string name=\"load_image_from_net_sub\">Lade jegliches Bild aus dem Internet, betrachte, zoome, bearbeite und speichere es wenn du willst</string>\n    <string name=\"no_image\">Kein Bild</string>\n    <string name=\"emojis_count\">Anzahl der Emojis</string>\n    <string name=\"filename_not_work_with_photopicker\">Funktioniert nicht, wenn »Bildauswahl« als Bildquelle gewählt wurde</string>\n    <string name=\"replace_sequence_number\">Bildfolgenummer ersetzen</string>\n    <string name=\"replace_sequence_number_sub\">Wenn aktiviert, ersetzt dies bei der Stapelverarbeitung den Zeitstempel durch die Bildfolgenummer</string>\n    <string name=\"fit\">Einpassen</string>\n    <string name=\"sequence_num\">FolgeNum</string>\n    <string name=\"fill\">Füllen</string>\n    <string name=\"content_scale\">Inhaltsskalierung</string>\n    <string name=\"flexible_description\">Ändert die Größe von Bildern mit einer langen Seite auf die angegebene Höhe oder Breite. Alle Größenberechnungen werden nach dem Speichern durchgeführt. Das Seitenverhältnis der Bilder wird beibehalten.</string>\n    <string name=\"explicit_description\">Ändert die Größe von Bildern auf die angegebene Höhe und Breite. Das Seitenverhältnis der Bilder kann sich ändern.</string>\n    <string name=\"brightness\">Helligkeit</string>\n    <string name=\"contrast\">Kontrast</string>\n    <string name=\"hue\">Farbton</string>\n    <string name=\"saturation\">Farbsättigung</string>\n    <string name=\"filter\">Filtern</string>\n    <string name=\"filter_sub\">Filterketten auf Bilder anwenden</string>\n    <string name=\"filters\">Filter</string>\n    <string name=\"light_aka_illumination\">Licht</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"add_filter\">Filter hinzufügen</string>\n    <string name=\"color_filter\">Farbfilter</string>\n    <string name=\"white_balance\">Weißabgleich</string>\n    <string name=\"temperature\">Farbtemperatur</string>\n    <string name=\"tint\">Tönung</string>\n    <string name=\"highlights\">Lichter</string>\n    <string name=\"haze\">Nebel</string>\n    <string name=\"effect\">Effekt</string>\n    <string name=\"monochrome\">Monochrom</string>\n    <string name=\"highlights_shadows\">Lichter und Schatten</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"shadows\">Schatten</string>\n    <string name=\"exposure\">Belichtung</string>\n    <string name=\"slope\">Steilheit</string>\n    <string name=\"distance\">Abstand</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negativ</string>\n    <string name=\"solarize\">Solarisieren</string>\n    <string name=\"vibrance\">Lebendigkeit</string>\n    <string name=\"black_and_white\">Schwarzweiß</string>\n    <string name=\"blur\">Weichzeichner</string>\n    <string name=\"sobel_edge\">Sobel-Kanten</string>\n    <string name=\"bilaterial_blur\">Bilateraler Weichzeichner</string>\n    <string name=\"sharpen\">Schärfen</string>\n    <string name=\"crosshatch\">Schraffieren</string>\n    <string name=\"line_width\">Linienstärke</string>\n    <string name=\"gaussian_blur\">Gaussscher Weichzeichner</string>\n    <string name=\"halftone\">Halbton</string>\n    <string name=\"cga_colorspace\">CGA-Farbraum</string>\n    <string name=\"box_blur\">Box-Weichzeichner</string>\n    <string name=\"emboss\">Prägen</string>\n    <string name=\"laplacian\">Laplace-Kanten</string>\n    <string name=\"vignette\">Vignettierung</string>\n    <string name=\"start\">Anfang</string>\n    <string name=\"end\">Ende</string>\n    <string name=\"spacing\">Abstand der Linien</string>\n    <string name=\"stack_blur\">Verwischen (langsam)</string>\n    <string name=\"angle\">Winkel</string>\n    <string name=\"swirl\">Wirbel</string>\n    <string name=\"bulge\">Schwellung</string>\n    <string name=\"dilation\">Streckung</string>\n    <string name=\"sphere_refraction\">Kugel-Brechung</string>\n    <string name=\"scale\">Intensität</string>\n    <string name=\"color_matrix\">Farbmatrix</string>\n    <string name=\"opacity\">Deckkraft</string>\n    <string name=\"posterize\">Tonwerttrennung</string>\n    <string name=\"toon\">Cartoon</string>\n    <string name=\"kuwahara\">Kuwahara-Glättung</string>\n    <string name=\"radius\">Radius</string>\n    <string name=\"distortion\">Verzerrung</string>\n    <string name=\"refractive_index\">Brechungsindex</string>\n    <string name=\"glass_sphere_refraction\">Glaskugel-Brechung</string>\n    <string name=\"sketch\">Skizze</string>\n    <string name=\"threshold\">Schwellenwert</string>\n    <string name=\"quantizationLevels\">Stärke des Effekts</string>\n    <string name=\"limits_resize_sub\">Ändern der Größe von Bildern auf die angegebene Höhe und Breite unter Beibehaltung des Seitenverhältnisses</string>\n    <string name=\"smooth_toon\">Geglätteter Cartoon</string>\n    <string name=\"limits_resize\">Größe nach Grenzen ändern</string>\n    <string name=\"lookup\">Lookup</string>\n    <string name=\"non_maximum_suppression\">Nicht maximale Unterdrückung</string>\n    <string name=\"weak_pixel_inclusion\">Helle Pixel heller</string>\n    <string name=\"convolution3x3\">sog. Faltungsmatrix 3x3</string>\n    <string name=\"rgb_filter\">RGB-Filter</string>\n    <string name=\"false_color\">Falschfarben</string>\n    <string name=\"first_color\">Erste Farbe</string>\n    <string name=\"second_color\">Zweite Farbe</string>\n    <string name=\"reorder\">Umsortieren</string>\n    <string name=\"fast_blur\">Schnelle Unschärfe</string>\n    <string name=\"blur_size\">Größe der Unschärfe</string>\n    <string name=\"blur_center_x\">Bewegungsursprung x-Achse</string>\n    <string name=\"color_balance\">Farbbalance</string>\n    <string name=\"blur_center_y\">Bewegungsursprung y-Achse</string>\n    <string name=\"zoom_blur\">Bewegungsunschärfe</string>\n    <string name=\"luminance_threshold\">Luminanzschwelle</string>\n    <string name=\"draw\">Zeichnen</string>\n    <string name=\"draw_sub\">Zeichne auf einem Bild wie in einem Skizzenbuch oder zeichne auf dem Hintergrund selbst</string>\n    <string name=\"activate_files\">Deine Dateien-App ist deaktiviert. Aktiviere sie, um diese Funktion zu nutzen.</string>\n    <string name=\"paint_alpha\">Deckkraft</string>\n    <string name=\"draw_on_image\">Auf Bild zeichnen</string>\n    <string name=\"draw_on_image_sub\">Wähle ein Bild und zeichne etwas darauf</string>\n    <string name=\"draw_on_background\">Zeichne auf Hintergrund</string>\n    <string name=\"background_color\">Hintergrundfarbe</string>\n    <string name=\"paint_color\">Zeichenfarbe</string>\n    <string name=\"draw_on_background_sub\">Wähle eine Hintergrundfarbe und zeichne darauf</string>\n    <string name=\"pick_file\">Datei auswählen</string>\n    <string name=\"features\">Eigenschaften</string>\n    <string name=\"compatibility\">Kompatibilität</string>\n    <string name=\"cipher\">Chiffrieren</string>\n    <string name=\"cipher_sub\">Ver- und Entschlüsselung beliebiger Dateien (nicht nur des Bildes) auf der Grundlage verschiedenen Verschlüsselungsalgorithmen</string>\n    <string name=\"decrypt\">Entschlüsseln</string>\n    <string name=\"implementation\">Implementierung</string>\n    <string name=\"encrypt\">Verschlüsseln</string>\n    <string name=\"pick_file_to_start\">Datei zum Starten auswählen</string>\n    <string name=\"encryption\">Verschlüsselung</string>\n    <string name=\"decryption\">Entschlüsselung</string>\n    <string name=\"key\">Schlüssel</string>\n    <string name=\"file_size\">Dateigröße</string>\n    <string name=\"group_options_by_type\">Optionen nach Typ gruppieren</string>\n    <string name=\"invalid_password_or_not_encrypted\">Ungültiges Passwort oder ausgewählte Datei ist nicht verschlüsselt</string>\n    <string name=\"found_s\">%1$s gefunden</string>\n    <string name=\"tools\">Tools</string>\n    <string name=\"group_options_by_type_sub\">Gruppierung der Optionen auf dem Hauptbildschirm nach ihrem Typ anstelle einer benutzerdefinierten Listenanordnung</string>\n    <string name=\"create\">Erstellen</string>\n    <string name=\"store_file_desc\">Speichere die Datei auf deinem Gerät oder benutze Teilen, um es wo immer du möchtest abzulegen</string>\n    <string name=\"implementation_sub\">AES-256, GCM-Modus, kein Padding, standardmäßig 12 Byte zufällige IVs. Du kannst den gewünschten Algorithmus auswählen. Schlüssel werden als 256-Bit SHA-3-Hashes benutzt</string>\n    <string name=\"file_size_sub\">Die maximale Dateigröße wird durch das Android-Betriebssystem und den verfügbaren Speicher begrenzt, was natürlich von Ihrem Gerät abhängt. \\nBitte beachten Sie: Speicher ist nicht gleich Speicherplatz.</string>\n    <string name=\"compatibility_sub\">Bitte beachte, dass die Kompatibilität zu anderen Dateiverschlüsselungsprogrammen oder -diensten nicht gewährleistet ist. Eine leicht abweichende Behandlung des Schlüssels oder eine andere Chiffrierkonfiguration können Gründe für eine Inkompatibilität sein.</string>\n    <string name=\"file_proceed\">Datei bearbeitet</string>\n    <string name=\"features_sub\">Passwortbasierte Verschlüsselung von Dateien. Die verschlüsselten Dateien können im ausgewählten Verzeichnis gespeichert oder freigegeben werden. Entschlüsselte Dateien können auch unmittelbar geöffnet werden.</string>\n    <string name=\"image_size_warning\">Das Versuchen, das Bild mit der angegebenen Breite und Höhe zu speichern, kann zu einem Fehler führen, wenn der Speicher voll ist. Dies geschieht auf eigene Gefahr.</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Cache-Größe</string>\n    <string name=\"auto_cache_clearing_sub\">Wenn aktiviert, wird der App-Cache beim Start der App geleert</string>\n    <string name=\"auto_cache_clearing\">Automatische Cache-Leerung</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Die Anordnung kann nicht geändert werden, wenn die Optionen gruppiert sind</string>\n    <string name=\"edit_screenshot\">Screenshot bearbeiten</string>\n    <string name=\"screenshot\">Screenshot</string>\n    <string name=\"secondary_customization\">Sekundäre Personalisierung</string>\n    <string name=\"warning_bytes\">Das Speichern im Modus %1$s kann instabil sein, da es sich um ein verlustfreies Format handelt</string>\n    <string name=\"fallback_option\">Fallback-Option</string>\n    <string name=\"skip\">Überspringen</string>\n    <string name=\"copy\">Kopieren</string>\n    <string name=\"presets_sub\" formatted=\"false\">Wenn du die Voreinstellung 125 gewählt hast, wird das Bild in einer Größe von 125% des Originalbildes gespeichert. Wenn du Voreinstellung 50 wählst, wird das Bild mit 50 % Größe gespeichert</string>\n    <string name=\"presets_sub_bytes\">Die Voreinstellung legt hier den % der Ausgabedatei fest, d. h. wenn du die Voreinstellung 50 für ein 5 MB Bild wählst, erhältst du nach dem Speichern ein 2,5 MB Bild.</string>\n    <string name=\"randomize_filename\">Zufälligen Dateinamen erzeugen</string>\n    <string name=\"randomize_filename_sub\">Wenn aktiviert, wird der Dateiname völlig zufällig gewählt.</string>\n    <string name=\"saved_to\">Gespeichert im Ordner „%1$s“ als „%2$s“</string>\n    <string name=\"tg_chat\">Telegram-Chat</string>\n    <string name=\"saved_to_without_filename\">Gespeichert im Ordner „%1$s“</string>\n    <string name=\"tg_chat_sub\">Diskutiere über die App und erhalte Feedback von anderen Nutzern. Außerdem kannst du dort Beta-Updates und Einblicke erhalten.</string>\n    <string name=\"image_crop_mask_sub\">Verwende diesen Maskentyp, um eine Maskierung aus einem Bild zu erzeugen. Beachte, dass es einen Alphakanal haben sollte.</string>\n    <string name=\"backup_and_restore\">Datensicherung und Wiederherstellung</string>\n    <string name=\"backup\">Datensicherung</string>\n    <string name=\"restore\">Wiederherstellung</string>\n    <string name=\"backup_sub\">App-Einstellungen in Datei sichern</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Beschädigte Datei oder keine Backup-Datei</string>\n    <string name=\"contact_me\">Kontaktiere mich</string>\n    <string name=\"crop_mask\">Beschnittmaske</string>\n    <string name=\"aspect_ratio\">Seitenverhältnis</string>\n    <string name=\"restore_sub\">Wiederherstellen von App-Einstellungen aus zuvor erstellter Datei</string>\n    <string name=\"settings_restored\">Einstellungen wiederhergestellt</string>\n    <string name=\"reset_settings_sub\">Dadurch werden Deine Einstellungen auf die Standardwerte zurückgesetzt. Bitte beachte, dass dies nicht ohne die Sicherungsdatei der obigen Option rückgängig gemacht werden kann.</string>\n    <string name=\"delete\">Löschen</string>\n    <string name=\"delete_color_scheme_warn\">Du bist dabei, das ausgewählte Farbschema zu löschen. Dieser Vorgang kann nicht rückgängig gemacht werden.</string>\n    <string name=\"delete_color_scheme_title\">Schema löschen</string>\n    <string name=\"font_scale\">Schriftgröße</string>\n    <string name=\"font\">Schriftart</string>\n    <string name=\"text\">Text</string>\n    <string name=\"defaultt\">Standardeinstellung</string>\n    <string name=\"using_large_fonts_warn\">Die Verwendung großer Schriftgrößen führt möglicherweise zu unschönen Nebeneffekten.</string>\n    <string name=\"erase_mode\">Lösch-Modus</string>\n    <string name=\"erase_background\">Hintergrund löschen</string>\n    <string name=\"emotions\">Emotionen</string>\n    <string name=\"nature_and_animals\">Natur und Tiere</string>\n    <string name=\"food_and_drink\">Essen und Trinken</string>\n    <string name=\"restore_background\">Hintergrund wiederherstellen</string>\n    <string name=\"objects\">Objekte</string>\n    <string name=\"symbols\">Symbole</string>\n    <string name=\"enable_emoji\">Emoji aktivieren</string>\n    <string name=\"travels_and_places\">Reisen und Orte</string>\n    <string name=\"activities\">Aktivitäten</string>\n    <string name=\"blur_radius\">Unschärfe-Radius</string>\n    <string name=\"pipette\">Pipette</string>\n    <string name=\"draw_mode\">Zeichenmodus</string>\n    <string name=\"alphabet_and_numbers\">Aa Ää Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Öö Pp Qq Rr Ss ß Tt Uu Üü Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"keep_exif_sub\">Die Metadaten des Originalbilds bleiben erhalten</string>\n    <string name=\"background_remover\">Hintergrund entfernen</string>\n    <string name=\"background_remover_sub\">Entferne den Hintergrund eines Bildes durch zeichnen oder verwende die Automatikfunktion</string>\n    <string name=\"trim_image\">Bildüberstand entfernen</string>\n    <string name=\"trim_image_sub\">Reduziert die Bildmaße durch Entfernen transparenter Pixelbereiche</string>\n    <string name=\"auto_erase_background\">Hintergrund automatisch löschen</string>\n    <string name=\"restore_image\">Bild wiederherstellen</string>\n    <string name=\"create_issue\">Fehlermeldung anlegen</string>\n    <string name=\"resize_and_convert_sub\">Ändere die Größe bestimmter Bilder oder konvertiere sie in andere Formate, außerdem kannst Du bei Auswahl eines einzelnen Bildes EXIF-Metadaten bearbeiten</string>\n    <string name=\"something_went_wrong_emphasis\">­Ups… Irgendetwas ist schiefgelaufen. Du kannst mir mittels der nachfolgenden Optionen schreiben und ich werde versuchen, eine Lösung zu finden</string>\n    <string name=\"resize_and_convert\">Größe ändern und konvertieren</string>\n    <string name=\"max_colors_count\">Höchstzahl an Farben</string>\n    <string name=\"crashlytics_sub\">Erlaubt der App, Absturzberichte automatisch zu sammeln</string>\n    <string name=\"analytics\">Analyse</string>\n    <string name=\"analytics_sub\">Erlaube anonymisierte App-Nutzungsstatitiken zu erfassen</string>\n    <string name=\"image_exif_warning\">Derzeit erlaubt das %1$s-Format auf Android nur das Lesen von Exif-Daten und nicht das Ändern/Speichern, d.h. das ausgegebene Bild wird keine Metadaten haben</string>\n    <string name=\"updates\">Aktualisierungen</string>\n    <string name=\"wait\">Warten</string>\n    <string name=\"effort_sub\">Ein Wert von %1$s bedeutet, dass die Komprimierung schnell erfolgt, was zu einer relativ großen Datei führt. %2$s bedeutet, dass die Komprimierung mehr Zeit in Anspruch nimmt, was zu einer kleineren Datei führt</string>\n    <string name=\"allow_betas\">Betas zulassen</string>\n    <string name=\"saving_almost_complete\">Speichervorgang ist fast abgeschlossen. Wenn du abbrichst, musst du es nochmal speichern.</string>\n    <string name=\"effort\">Aufwand</string>\n    <string name=\"allow_betas_sub\">Die Aktualisierungsprüfung schließt Beta-App-Versionen ein, wenn sie aktiviert ist</string>\n    <string name=\"brush_softness\">Pinselweichheit</string>\n    <string name=\"draw_arrows\">Pfeile zeichnen</string>\n    <string name=\"donation\">Spende</string>\n    <string name=\"draw_arrows_sub\">Falls aktiviert, wird der Zeichenpfad als Pfeil dargestellt</string>\n    <string name=\"crop_description\">Bilder werden mittig auf diese Größe zugeschnitten, wenn sie größer sind als die eingegebenen Maße. In anderen Fällen wird die Leinwand mit der angegebenen Hintergrundfarbe erweitert.</string>\n    <string name=\"image_stitching\">Bild zusammenfügen</string>\n    <string name=\"image_stitching_sub\">Kombiniere bestimmte Bilder zu einem großen</string>\n    <string name=\"horizontal\">Horizontal</string>\n    <string name=\"images_order\">Reihenfolge der Bilder</string>\n    <string name=\"pick_at_least_two_images\">Wähle min. zwei Bilder</string>\n    <string name=\"scale_small_images_to_large_sub\">Wenn aktiviert, werden kleine Bilder maßstäblich dem Größten angepasst</string>\n    <string name=\"image_orientation\">Bildausrichtung</string>\n    <string name=\"vertical\">Vertikal</string>\n    <string name=\"output_image_scale\">Maßstab der ausgegebenen Bilder</string>\n    <string name=\"scale_small_images_to_large\">Kleine Bilder hochskalieren</string>\n    <string name=\"blur_edges\">Ränder unscharf machen</string>\n    <string name=\"pixelation\">Verpixelung</string>\n    <string name=\"blur_edges_sub\">Wenn aktiviert, werden unscharfe Ränder unter das Originalbild gezeichnet, um den Raum um das Bild herum auszufüllen, anstatt nur eine Farbe zu verwenden</string>\n    <string name=\"regular\">Regulär</string>\n    <string name=\"recode\">Recodieren</string>\n    <string name=\"tolerance\">Toleranz</string>\n    <string name=\"both\">Beide</string>\n    <string name=\"invert_colors_sub\">Ersetzt die Themenfarben durch negative, sofern aktiviert</string>\n    <string name=\"rainbow\">Regenbogen</string>\n    <string name=\"playful_scheme\">Ein verspieltes Thema – der Farbton der Quellfarbe erscheint nicht im Thema</string>\n    <string name=\"fading_edges\">Verblassende Kanten</string>\n    <string name=\"vibrant_sub\">Ein lautes Thema, die Farbigkeit ist für die primäre Palette maximal, für andere erhöht</string>\n    <string name=\"pdf_tools\">PDF Tools</string>\n    <string name=\"neutral_sub\">Ein Stil, der etwas chromatischer als monochrom ist</string>\n    <string name=\"enhanced_pixelation\">Verbesserte Pixelierung</string>\n    <string name=\"target_color\">Ziel-Farbe</string>\n    <string name=\"foss_update_checker_warning\">This update checker will connect to GitHub in reason of checking if there is a new update available</string>\n    <string name=\"pixel_size\">Pixelgröße</string>\n    <string name=\"content_sub\">Ein Schema, das die Quellfarbe in Scheme.primaryContainer platziert</string>\n    <string name=\"tonal_spot\">Tonfleck</string>\n    <string name=\"search_option\">Suchen</string>\n    <string name=\"replace_color\">Farbe ersetzen</string>\n    <string name=\"diamond_pixelation\">Diamand Pixelierung</string>\n    <string name=\"remove_color\">Farbe entfernen</string>\n    <string name=\"images_to_pdf\">Bilder zu PDF</string>\n    <string name=\"monochrome_sub\">Ein monochromes Thema, die Farben sind rein schwarz/weiß/grau</string>\n    <string name=\"fruit_salad\">Fruchtsalat</string>\n    <string name=\"enhanced_diamond_pixelation\">Verbesserte Diamand Pixelierung</string>\n    <string name=\"circle_pixelation\">Kreis Pixelierung</string>\n    <string name=\"preview_pdf\">PDF Vorschau</string>\n    <string name=\"fidelity_sub\">Ein Schema, das dem Inhaltsschema sehr ähnlich ist</string>\n    <string name=\"check_for_updates\">Nach Updates suchen</string>\n    <string name=\"search_option_sub\">Ermöglicht die Suche durch alle verfügbaren Tools auf dem Hauptbildschirm</string>\n    <string name=\"content\">Inhalt</string>\n    <string name=\"disabled\">Deaktiviert</string>\n    <string name=\"pdf_to_images\">PDF zu Bildern</string>\n    <string name=\"neutral\">Neutral</string>\n    <string name=\"color_to_remove\">Zu entfernende Farbe</string>\n    <string name=\"tonal_spot_sub\">Standard-Palettenstil, mit dem du alle vier Farben anpassen kannst, bei anderen kannst du nur die Schlüsselfarbe festlegen</string>\n    <string name=\"color_to_replace\">Zu ersetzende Farbe</string>\n    <string name=\"images_to_pdf_sub\">Führt Bilder in einem PDF zusammen</string>\n    <string name=\"preview_pdf_sub\">Einfache PDF Vorschau</string>\n    <string name=\"lock_draw_orientation_sub\">Aktivieren um Bildschirmdrehung beim Zeichnen zu sperren.</string>\n    <string name=\"palette_style\">Paletten-Stil</string>\n    <string name=\"invert_colors\">Farben invertieren</string>\n    <string name=\"vibrant\">Lebendig</string>\n    <string name=\"stroke_pixelation\">Pinsel Pixelierung</string>\n    <string name=\"pdf_tools_sub\">PDF-Dateien verarbeiten: Vorschau, Konvertieren in einen Stapel von Bildern oder Erstellen eines neuen PDFs aus ausgewählten Bildern</string>\n    <string name=\"enhanced_circle_pixelation\">Verbesserte Kreis Pixelierung</string>\n    <string name=\"attention\">Achtung</string>\n    <string name=\"pdf_to_images_sub\">Konvrtiert PDF zu Bildern in angegebenem Format</string>\n    <string name=\"delete_mask_warn\">Du bist dabei, die ausgewählte Filtermaske zu löschen. Dieser Vorgang kann nicht rückgängig gemacht werden</string>\n    <string name=\"delete_mask\">Maske löschen</string>\n    <string name=\"free\">Freihand</string>\n    <string name=\"center_position\">Mitte</string>\n    <string name=\"end_position\">Ende</string>\n    <string name=\"start_position\">Anfang</string>\n    <string name=\"free_drawing_sub\">Zeichnet den Pfad als Eingabewert</string>\n    <string name=\"line_arrow_sub\">Zeichnet einen Pfeil vom Anfangs- zum Endpunkt als Linie</string>\n    <string name=\"arrow_sub\">Malt einen gepunkteten Pfeil aus einem vorgegebenen Pfad</string>\n    <string name=\"double_arrow_sub\">Zeichnet einen Doppelpfeil aus einem vorgegebenen Pfad</string>\n    <string name=\"outlined_oval\">Konturiertes Oval</string>\n    <string name=\"outlined_rect\">Konturiertes Rechteck</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Rechteck</string>\n    <string name=\"rect_sub\">Zeichnet ein Rechteck vom Anfangs- zum Endpunkt</string>\n    <string name=\"oval_sub\">Zeichnet ein Oval vom Anfangs- zum Endpunkt</string>\n    <string name=\"outlined_oval_sub\">Zeichnet ein konturiertes Oval vom Anfangs- zum Endpunkt</string>\n    <string name=\"mask_color\">Maskenfarbe</string>\n    <string name=\"mask_preview_sub\">Die gezeichnete Filtermaske wird berechnet, um Ihnen das ungefähre Ergebnis zu zeigen</string>\n    <string name=\"mask_preview\">Masken Vorschau</string>\n    <string name=\"lock_draw_orientation\">Zeichenrichtung sperren</string>\n    <string name=\"mask_filter\">Maskierungsfilter</string>\n    <string name=\"masks\">Masken</string>\n    <string name=\"add_mask\">Maske hinzufügen</string>\n    <string name=\"mask_indexed\">Maske %d</string>\n    <string name=\"mask_filter_sub\">Wende Filterketten auf vorgegebene maskierte Bereiche an, jeder Maskenbereich kann seinen eigenen Satz von Filtern bestimmen</string>\n    <string name=\"free_drawing\">Freihand-Zeichnung</string>\n    <string name=\"line_sub\">Zeichnet einen Pfad vom Anfangs- zum Endpunkt als Linie</string>\n    <string name=\"double_line_arrow_sub\">Zeichnet einen Doppelpfeil vom Anfangs- zum Endpunkt als Linie</string>\n    <string name=\"outlined_rect_sub\">Zeichnet ein konturiertes Rechteck vom Anfangs- zum Endpunkt</string>\n    <string name=\"expressive\">Expressiv</string>\n    <string name=\"inverse_fill_type_sub\">Wenn diese Option aktiviert ist, werden alle nicht maskierten Bereiche gefiltert, anstatt des Standardverfahrens</string>\n    <string name=\"inverse_fill_type\">Invertierter Fülltyp</string>\n    <string name=\"fidelity\">Genauigkeit</string>\n    <string name=\"lasso_sub\">Zeichnet einen geschlossenen, gefüllten Pfad anhand des vorgegebenen Pfades</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"fast\">Schnell</string>\n    <string name=\"best\">Beste</string>\n    <string name=\"download\">Herunterladen</string>\n    <string name=\"available_languages\">Verfügbare Sprachen</string>\n    <string name=\"sliders_shadow_sub\">Malt einen Schatten hinter Schiebereglern</string>\n    <string name=\"switches_shadow_sub\">Malt einen Schatten hinter Schaltern</string>\n    <string name=\"value_in_range\">Wert im Bereich %1$s - %2$s</string>\n    <string name=\"recognition_type\">Erkennungstyp</string>\n    <string name=\"no_data\">Keine Daten</string>\n    <string name=\"containers_shadow_sub\">Malt einen Schatten hinter Containern</string>\n    <string name=\"downloaded_languages\">Heruntergeladene Sprachen</string>\n    <string name=\"segmentation_mode\">Segmentierungsmodus</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"simple_variants\">Einfache Varianten</string>\n    <string name=\"highlighter\">Textmarker</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Stift</string>\n    <string name=\"privacy_blur\">Datenschutzunschärfe</string>\n    <string name=\"highlighter_sub\">Zeichne halbtransparente, geschärfte Textmarkerpfade</string>\n    <string name=\"neon_sub\">Leuchteffekte zu Ihren Zeichnungen hinzufügen</string>\n    <string name=\"pen_sub\">Standardeinstellung, am einfachsten - nur die Farbe</string>\n    <string name=\"auto_rotate_limits\">Automatisch drehen</string>\n    <string name=\"containers_shadow\">Container</string>\n    <string name=\"buttons_shadow\">Schaltflächen</string>\n    <string name=\"sliders_shadow\">Schieberegler</string>\n    <string name=\"switches_shadow\">Schalter</string>\n    <string name=\"buttons_shadow_sub\">Malt einen Schatten hinter Schaltflächen</string>\n    <string name=\"app_bars_shadow\">App Leisten</string>\n    <string name=\"app_bars_shadow_sub\">Malt einen Schatten hinter App-Leisten</string>\n    <string name=\"enhanced_glitch\">Verbesserter Glitch</string>\n    <string name=\"tent_blur\">Zeltunschärfe</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatische Ausrichtung &amp; Skripterkennung</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Vertikaler Einzelblocktext</string>\n    <string name=\"segmentation_mode_single_block\">Einzelner Block</string>\n    <string name=\"segmentation_mode_circle_word\">Kreiswort</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Ausrichtung von spärlichem Text &amp; Skripterkennung</string>\n    <string name=\"segmentation_mode_raw_line\">Rohe Linie</string>\n    <string name=\"email\">Email</string>\n    <string name=\"glitch\">Panne</string>\n    <string name=\"amount\">Menge</string>\n    <string name=\"no_such_directory\">Kein \\\"%1$s\\\"-Verzeichnis gefunden, wir haben es auf das Standardverzeichnis umgestellt, bitte speichere die Datei erneut</string>\n    <string name=\"clipboard\">Zwischenablage</string>\n    <string name=\"auto_pin\">Auto-Pin</string>\n    <string name=\"auto_pin_sub\">Fügt das gespeicherte Bild automatisch zur Zwischenablage hinzu, sofern aktiviert</string>\n    <string name=\"vibration\">Vibration</string>\n    <string name=\"overwrite_files\">Dateien überschreiben</string>\n    <string name=\"overwrite_files_sub\">Originaldatei wird durch eine neue ersetzt, anstatt sie im ausgewählten Ordner zu speichern. Diese Option muss als Bildquelle „Explorer“ oder „GetContent“ angegeben werden. Wenn du diese Option umschaltest, wird es automatisch festgelegt</string>\n    <string name=\"empty\">Leer</string>\n    <string name=\"suffix\">Suffix</string>\n    <string name=\"columns_count\">Anzahl der Spalten</string>\n    <string name=\"vibration_strength\">Vibrationsstärke</string>\n    <string name=\"overwrite_file_requirements\">Um Dateien zu überschreiben, musst du die Bildquelle „Explorer“ verwenden. Versuche, die Bilder erneut auszuwählen. Wir haben die Bildquelle auf die benötigte geändert</string>\n    <string name=\"bilinear_sub\">Die lineare (oder bilineare, in zwei Dimensionen) Interpolation eignet sich normalerweise gut zum Ändern der Größe eines Bildes, führt jedoch zu einer unerwünschten Weichzeichnung der Details und kann dennoch etwas gezackt wirken</string>\n    <string name=\"bicubic_sub\">Zu besseren Skalierungsmethoden gehören Lanczos-Resampling und Mitchell-Netravali-Filter</string>\n    <string name=\"nearest_sub\">Eine der einfacheren Möglichkeiten, die Größe zu erhöhen, besteht darin, jedes Pixel durch eine Anzahl Pixel derselben Farbe zu ersetzen</string>\n    <string name=\"basic_sub\">Einfachster Android-Skalierungsmodus, der in fast allen Apps verwendet wird</string>\n    <string name=\"catmull_sub\">Methode zum reibungslosen Interpolieren und Resampling einer Reihe von Kontrollpunkten, die häufig in der Computergrafik zum Erstellen glatter Kurven verwendet wird</string>\n    <string name=\"hann_sub\">Fensterfunktion, die häufig in der Signalverarbeitung eingesetzt wird, um spektrale Verluste zu minimieren und die Genauigkeit der Frequenzanalyse durch Verjüngung der Signalflanken zu verbessern</string>\n    <string name=\"hermite_sub\">Mathematische Interpolationstechnik, die Werte und Ableitungen an den Endpunkten eines Kurvensegments verwendet, um eine glatte und kontinuierliche Kurve zu erzeugen</string>\n    <string name=\"lanczos_sub\">Resampling-Methode, die eine qualitativ hochwertige Interpolation aufrechterhält, indem eine gewichtete Sinusfunktion auf die Pixelwerte angewendet wird</string>\n    <string name=\"mitchell_sub\">Resampling-Methode, die einen Faltungsfilter mit einstellbaren Parametern verwendet, um ein Gleichgewicht zwischen Schärfe und Anti-Aliasing im skalierten Bild zu erreichen</string>\n    <string name=\"spline_sub\">Verwendet stückweise definierte Polynomfunktionen zur sanften Interpolation und Annäherung an eine Kurve oder Fläche und bietet so eine flexible und kontinuierliche Formdarstellung</string>\n    <string name=\"recognize_text_sub\">Erkenne Text aus einem bestimmten Bild. Über 120 Sprachen werden unterstützt</string>\n    <string name=\"picture_has_no_text\">Das Bild enthält keinen Text oder die App hat ihn nicht gefunden</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"transparency\">Transparenz</string>\n    <string name=\"rate\">Rate</string>\n    <string name=\"rate_app_sub\">Diese App ist völlig kostenlos. Wenn du möchtest, dass sie größer wird, dann gibt dem Projekt bitte einen Stern auf Github 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Ausrichtung &amp; Nur Skripterkennung</string>\n    <string name=\"segmentation_mode_auto_only\">Nur Auto</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Einzelne Spalte</string>\n    <string name=\"segmentation_mode_single_line\">Einzelne Zeile</string>\n    <string name=\"segmentation_mode_single_word\">Einzelnes Wort</string>\n    <string name=\"segmentation_mode_single_char\">Einzelnes Zeichen</string>\n    <string name=\"segmentation_mode_sparse_text\">Spärlicher Text</string>\n    <string name=\"delete_language_sub\">Möchtest du die Sprach-OCR-Trainingsdaten „%1$s“ für alle Erkennungstypen oder nur für den ausgewählten Typ (%2$s) löschen?</string>\n    <string name=\"gradient_type_linear\">Linear</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Fegen</string>\n    <string name=\"gradient_type\">Farbverlaufstyp</string>\n    <string name=\"center_x\">Mitte X</string>\n    <string name=\"center_y\">Zentrum Y</string>\n    <string name=\"tile_mode\">Kachelmodus</string>\n    <string name=\"tile_mode_repeated\">Wiederholt</string>\n    <string name=\"tile_mode_mirror\">Spiegel</string>\n    <string name=\"tile_mode_clamp\">Klemme</string>\n    <string name=\"tile_mode_decal\">Abziehbild</string>\n    <string name=\"color_stops\">Farbstopps</string>\n    <string name=\"add_color\">Farbe hinzufügen</string>\n    <string name=\"properties\">Eigenschaften</string>\n    <string name=\"watermarking\">Wasserzeichen</string>\n    <string name=\"watermarking_sub\">Decke Bilder mit anpassbaren Text-/Bildwasserzeichen ab</string>\n    <string name=\"repeat_watermark_sub\">Wiederholt das Wasserzeichen über dem Bild statt einzeln an der angegebenen Position</string>\n    <string name=\"offset_x\">Versatz X</string>\n    <string name=\"offset_y\">Y-Versatz</string>\n    <string name=\"watermark_type\">Wasserzeichentyp</string>\n    <string name=\"watermarking_image_sub\">Dieses Bild wird als Muster für das Wasserzeichen verwendet</string>\n    <string name=\"text_color\">Textfarbe</string>\n    <string name=\"gif_tools_sub\">Konvertiere Bilder in GIF-Bilder oder extrahiere Rahmen aus einem bestimmten GIF-Bild</string>\n    <string name=\"gif_type_to_image\">GIF zu Bildern</string>\n    <string name=\"gif_type_to_image_sub\">Konvertiere eine GIF-Datei in einen Bilderstapel</string>\n    <string name=\"gif_type_to_gif_sub\">Konvertiere einen Stapel Bilder in eine GIF-Datei</string>\n    <string name=\"select_gif_image_to_start\">Wähle zum Starten ein GIF-Bild aus</string>\n    <string name=\"use_size_of_first_frame\">Verwende die Größe des ersten Rahmens</string>\n    <string name=\"use_size_of_first_frame_sub\">Ersetze die angegebene Größe durch die ersten Rahmenabmessungen</string>\n    <string name=\"repeat_count\">Zählen wiederholen</string>\n    <string name=\"frame_delay\">Frame-Verzögerung</string>\n    <string name=\"millis\">Millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"secure_mode_sub\">Blendet den Inhalt der letzten Apps aus. Es kann nicht erfasst oder aufgezeichnet werden.</string>\n    <string name=\"bayer_four_dithering\">Bayer Vier-gegen-Vier-Zögern</string>\n    <string name=\"bayer_eight_dithering\">Bayer-Acht-gegen-Acht-Zögern</string>\n    <string name=\"two_row_sierra_dithering\">Zweireihiges Sierra-Dithering</string>\n    <string name=\"simple_threshold_dithering\">Einfaches Schwellenwert-Dithering</string>\n    <string name=\"b_spline_sub\">Verwendet stückweise definierte bikubische Polynomfunktionen zur reibungslosen Interpolation und Approximation einer Kurve oder Oberfläche sowie einer flexiblen und kontinuierlichen Formdarstellung</string>\n    <string name=\"tilt_shift\">Tilt-Shift</string>\n    <string name=\"seed\">Samen</string>\n    <string name=\"channel_shift_x\">Kanalverschiebung X</string>\n    <string name=\"channel_shift_y\">Kanalverschiebung Y</string>\n    <string name=\"corruption_size\">Korruptionsgröße</string>\n    <string name=\"corruption_shift_x\">Korruptionsverschiebung X</string>\n    <string name=\"corruption_shift_y\">Korruptionsverschiebung Y</string>\n    <string name=\"side_fade\">Seitliches Ausblenden</string>\n    <string name=\"side\">Seite</string>\n    <string name=\"top\">Spitze</string>\n    <string name=\"bottom\">Unten</string>\n    <string name=\"strength\">Stärke</string>\n    <string name=\"amplitude\">Amplitude</string>\n    <string name=\"marble\">Marmor</string>\n    <string name=\"water_effect\">Wassereffekt</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Tone Mapping</string>\n    <string name=\"speed\">Geschwindigkeit</string>\n    <string name=\"simple_effects\">Einfache Effekte</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomalie</string>\n    <string name=\"deutaromaly\">Deuteranomalie</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"cool\">Cool</string>\n    <string name=\"tritanopia\">Tritanopie</string>\n    <string name=\"deutaronotopia\">Deuteranopie</string>\n    <string name=\"protanopia\">Protanopie</string>\n    <string name=\"achromatomaly\">Achromatomalie</string>\n    <string name=\"achromatopsia\">Achromatopsie</string>\n    <string name=\"orange_haze\">Orangefarbener Dunst</string>\n    <string name=\"pink_dream\">Rosa Traum</string>\n    <string name=\"golden_hour\">Goldene Stunde</string>\n    <string name=\"soft_spring_light\">Sanftes Frühlingslicht</string>\n    <string name=\"autumn_tones\">Herbsttöne</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Limonade leicht</string>\n    <string name=\"spectral_fire\">Spektrales Feuer</string>\n    <string name=\"night_magic\">Nachtzauber</string>\n    <string name=\"fantasy_landscape\">Fantasielandschaft</string>\n    <string name=\"color_explosion\">Farbexplosion</string>\n    <string name=\"electric_gradient\">Elektrischer Gradient</string>\n    <string name=\"caramel_darkness\">Karamell-Dunkelheit</string>\n    <string name=\"futuristic_gradient\">Futuristischer Farbverlauf</string>\n    <string name=\"rainbow_world\">Regenbogenwelt</string>\n    <string name=\"deep_purple\">Dunkellila</string>\n    <string name=\"space_portal\">Weltraumportal</string>\n    <string name=\"digital_code\">Digitaler Code</string>\n    <string name=\"no_favorite_filters\">Noch keine Lieblingsfilter hinzugefügt</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Abgeschnitten</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Möbius</string>\n    <string name=\"transition\">Übergang</string>\n    <string name=\"peak\">Gipfel</string>\n    <string name=\"color_anomaly\">Farbanomalie</string>\n    <string name=\"images_overwritten\">Bilder werden am ursprünglichen Zielort überschrieben</string>\n    <string name=\"cannot_change_image_format\">Das Bildformat kann nicht geändert werden, während die Option zum Überschreiben von Dateien aktiviert ist</string>\n    <string name=\"emoji_as_color_scheme\">Emoji als Farbschema</string>\n    <string name=\"emoji_as_color_scheme_sub\">Verwendet die Emoji-Primärfarbe als App-Farbschema anstelle einer manuell definierten</string>\n    <string name=\"erode\">Erodieren</string>\n    <string name=\"anisotropic_diffusion\">Anisotrope Diffusion</string>\n    <string name=\"diffusion\">Diffusion</string>\n    <string name=\"conduction\">Leitung</string>\n    <string name=\"horizontal_wind_stagger\">Horizontaler Windstaffel</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"fast_bilaterial_blur\">Schnelle bilaterale Unschärfe</string>\n    <string name=\"poisson_blur\">Poisson Unschärfe</string>\n    <string name=\"logarithmic_tone_mapping\">Logarithmische Tonzuordnung</string>\n    <string name=\"crystallize\">Kristallisieren</string>\n    <string name=\"stroke_color\">Strichfarbe</string>\n    <string name=\"fractal_glass\">Fraktales Glas</string>\n    <string name=\"turbulence\">Turbulenz</string>\n    <string name=\"oil\">Öl</string>\n    <string name=\"just_size\">Größe</string>\n    <string name=\"frequency_x\">Frequenz X</string>\n    <string name=\"frequency_y\">Frequenz Y</string>\n    <string name=\"amplitude_x\">Amplitude X</string>\n    <string name=\"perlin_distortion\">Perlin-Verzerrung</string>\n    <string name=\"amplitude_y\">Amplitude Y</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"current\">Aktuell</string>\n    <string name=\"all\">Alle</string>\n    <string name=\"full_filter\">Voller Filter</string>\n    <string name=\"full_filter_sub\">Wende beliebige Filterketten auf bestimmte Bilder oder einzelne Bilder an</string>\n    <string name=\"gradient_maker\">Verlaufsgenerator</string>\n    <string name=\"gradient_maker_sub\">Erstelle einen Farbverlauf in einer bestimmten Ausgabegröße mit benutzerdefinierten Farben und Darstellungstypen</string>\n    <string name=\"dehaze\">Entnebeln</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"rate_app\">Bewertungs App</string>\n    <string name=\"color_matrix_4x4\">Farbmatrix 4x4</string>\n    <string name=\"color_matrix_3x3\">Farbmatrix 3x3</string>\n    <string name=\"protonomaly\">Protanomalie</string>\n    <string name=\"vintage\">Jahrgang</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Nachtsicht</string>\n    <string name=\"warm\">Warm</string>\n    <string name=\"draw_path_mode\">Modus „Pfad zeichnen“.</string>\n    <string name=\"double_line_arrow\">Doppellinienpfeil</string>\n    <string name=\"double_arrow\">Doppelpfeil</string>\n    <string name=\"line_arrow\">Linienpfeil</string>\n    <string name=\"arrow\">Pfeil</string>\n    <string name=\"line\">Linie</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantisierer</string>\n    <string name=\"gray_scale\">Graustufen</string>\n    <string name=\"bayer_two_dithering\">Bayer Two by Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer-Drei-mal-Drei-Zögern</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg zittert</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite-Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falsches Floyd-Steinberg-Dithering</string>\n    <string name=\"left_to_right_dithering\">Dithering von links nach rechts</string>\n    <string name=\"random_dithering\">Zufälliges Dithering</string>\n    <string name=\"scale_mode\">Skalierungsmodus</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Einsiedler</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Nächste</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Basic</string>\n    <string name=\"default_value\">Standardwert</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Räumliches Sigma</string>\n    <string name=\"median_blur\">Mediane Unschärfe</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bikubisch</string>\n    <string name=\"only_clip\">Nur Clip</string>\n    <string name=\"only_clip_sub\">Das Speichern im Speicher wird nicht durchgeführt und es wird versucht, das Bild nur in die Zwischenablage zu legen</string>\n    <string name=\"icon_shape_sub\">Fügt einen Container mit der ausgewählten Form unter den Symbolen hinzu</string>\n    <string name=\"icon_shape\">Symbolform</string>\n    <string name=\"brightness_enforcement\">Durchsetzung der Helligkeit</string>\n    <string name=\"screen\">Bildschirm</string>\n    <string name=\"gradient_maker_type_image\">Verlaufsüberlagerung</string>\n    <string name=\"gradient_maker_type_image_sub\">Erstelle einen beliebigen Farbverlauf am oberen Rand der angegebenen Bilder</string>\n    <string name=\"transformations\">Transformationen</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Nimm ein Bild mit der Kamera auf. Beachte, dass es möglich ist, nur ein Bild aus dieser Bildquelle zu erhalten</string>\n    <string name=\"grain\">Getreide</string>\n    <string name=\"unsharp\">Unscharf</string>\n    <string name=\"pastel\">Pastell</string>\n    <string name=\"hot_summer\">Heißer Sommer</string>\n    <string name=\"purple_mist\">Lila Nebel</string>\n    <string name=\"sunrise\">Sonnenaufgang</string>\n    <string name=\"colorful_swirl\">Bunter Wirbel</string>\n    <string name=\"lavender_dream\">Lavendeltraum</string>\n    <string name=\"green_sun\">Grüne Sonne</string>\n    <string name=\"red_swirl\">Roter Wirbel</string>\n    <string name=\"repeat_watermark\">Wasserzeichen wiederholen</string>\n    <string name=\"overlay_mode\">Overlay-Modus</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">GIF Tools</string>\n    <string name=\"gif_type_to_gif\">Bilder zu GIF</string>\n    <string name=\"use_lasso\">Benutze Lasso</string>\n    <string name=\"use_lasso_sub\">Verwendet Lasso wie im Zeichenmodus zum Löschen</string>\n    <string name=\"original_image_preview_alpha\">Originalbildvorschau Alpha</string>\n    <string name=\"random_emojis_sub\">Das Emoji der App Leiste ändert sich zufällig</string>\n    <string name=\"random_emojis\">Zufällige Emojis</string>\n    <string name=\"random_emojis_error\">Du kannst keine zufälligen Emojis verwenden, wenn Emojis deaktiviert sind</string>\n    <string name=\"emoji_selection_error\">Du kannst kein Emoji auswählen, wenn zufällige Emojis aktiviert sind</string>\n    <string name=\"old_tv\">Alter Fernseher</string>\n    <string name=\"shuffle_blur\">Mischunschärfe</string>\n    <string name=\"recognize_text\">OCR (Text erkennen)</string>\n    <string name=\"download_description\">Damit Tesseract OCR ordnungsgemäß funktioniert, müssen zusätzliche Trainingsdaten (%1$s) auf dein Gerät heruntergeladen werden. \\nMöchtest du %2$s Daten herunterladen?</string>\n    <string name=\"no_connection\">Keine Verbindung. Überprüfen die Verbindung und versuche es erneut, um Eisenbahnmodelle herunterzuladen</string>\n    <string name=\"restore_background_sub\">Der Pinsel stellt den Hintergrund wieder her, anstatt ihn auszuradieren</string>\n    <string name=\"horizontal_grid\">Horizontales Gitter</string>\n    <string name=\"vertical_grid\">Vertikales Gitter</string>\n    <string name=\"stitch_mode\">Stichmodus</string>\n    <string name=\"rows_count\">Anzahl der Zeilen</string>\n    <string name=\"use_pixel_switch\">Verwende Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Verwendet einen Google Pixel-ähnlichen Schalter</string>\n    <string name=\"slide\">Gleiten</string>\n    <string name=\"side_by_side\">Seite an Seite</string>\n    <string name=\"toggle_tap\">Tippen umschalten</string>\n    <string name=\"saved_to_original\">Überschriebene Datei mit dem Namen %1$s am ursprünglichen Ziel</string>\n    <string name=\"magnifier\">Lupe</string>\n    <string name=\"magnifier_sub\">Aktiviert die Lupe im Zeichenmodus für bessere Zugänglichkeit oben am Finger</string>\n    <string name=\"force_exif_widget_initial_value\">Anfangswert erzwingen</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Erzwingt die anfängliche Überprüfung des Exif-Widgets</string>\n    <string name=\"allow_multiple_languages\">Mehrere Sprachen zulassen</string>\n    <string name=\"favorite\">Favorit</string>\n    <string name=\"b_spline\">B-Spline</string>\n    <string name=\"native_stack_blur\">Native Stapelunschärfe</string>\n    <string name=\"confetti\">Konfetti</string>\n    <string name=\"confetti_sub\">Konfetti wird beim Speichern, Teilen und anderen primären Aktionen angezeigt</string>\n    <string name=\"secure_mode\">Sicherer Modus</string>\n    <string name=\"pixelation_sub\">Ähnlich wie Datenschutzunschärfe, aber pixelig statt unscharf</string>\n    <string name=\"auto_rotate_limits_sub\">Ermöglicht die Übernahme eines Begrenzungsrahmens für die Bildausrichtung</string>\n    <string name=\"privacy_blur_sub\">Verwischt das Bild unter dem gezeichneten Pfad, um alles zu sichern, was du verbergen möchtest</string>\n    <string name=\"fabs_shadow\">Fabs</string>\n    <string name=\"fabs_shadow_sub\">Malt einen Schatten hinter schwebenden Aktionsschaltflächen</string>\n    <string name=\"exit\">Verlassen</string>\n    <string name=\"preview_closing\">Wenn du die Vorschau jetzt verlässt, musst du die Bilder erneut hinzufügen</string>\n    <string name=\"image_format\">Bildformat</string>\n    <string name=\"noise\">Lärm</string>\n    <string name=\"pixel_sort\">Pixelsortierung</string>\n    <string name=\"shuffle\">Mischen</string>\n    <string name=\"anaglyph\">Anaglyphe</string>\n    <string name=\"material_you_sub\">Erstellt die Palette \\\"Material You\\\" aus dem Bild</string>\n    <string name=\"dark_colors\">Dunkle Farben</string>\n    <string name=\"dark_colors_sub\">Verwendet das Nachtmodus-Farbschema anstelle der Lichtvariante</string>\n    <string name=\"copy_as_compose_code\">Als \\\"Jetpack Compose\\\" -Code kopieren</string>\n    <string name=\"ring_blur\">Ringunschärfe</string>\n    <string name=\"cross_blur\">Kreuzunschärfe</string>\n    <string name=\"circle_blur\">Kreisunschärfe</string>\n    <string name=\"star_blur\">Sternenunschärfe</string>\n    <string name=\"linear_tilt_shift\">Lineare Neigungsverschiebung</string>\n    <string name=\"tags_to_remove\">Zu entfernende Tags</string>\n    <string name=\"apng_type_to_apng\">Bilder zu APNG</string>\n    <string name=\"apng_tools\">APNG Tools</string>\n    <string name=\"apng_tools_sub\">Konvertiere Bilder in APNG-Bilder oder extrahiere Rahmen aus einem bestimmten APNG-Bild</string>\n    <string name=\"apng_type_to_image\">APNG zu Bildern</string>\n    <string name=\"select_apng_image_to_start\">Wähle zum Starten das APNG-Bild aus</string>\n    <string name=\"motion_blur\">Bewegungsunschärfe</string>\n    <string name=\"apng_type_to_image_sub\">Konvertiere die APNG-Datei in einen Bilderstapel</string>\n    <string name=\"apng_type_to_apng_sub\">Konvertiere einen Stapel Bilder in eine APNG-Datei</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Erstelle eine Zip-Datei aus bestimmten Dateien oder Bildern</string>\n    <string name=\"drag_handle_width\">Griffbreite ziehen</string>\n    <string name=\"rain\">Regen</string>\n    <string name=\"festive\">Festlich</string>\n    <string name=\"explode\">Explodieren</string>\n    <string name=\"corners\">Ecken</string>\n    <string name=\"jxl_tools\">JXL Tools</string>\n    <string name=\"jxl_tools_sub\">Führe eine JXL ~ JPEG Konvertierung ohne Qualitätsverlust durch, oder wandle GIF/APNG in JXL Animation um</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Verlustfreie Konvertierung von JXL zu JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Verlustfreie Konvertierung von JPEG zu JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG zu JXL</string>\n    <string name=\"fast_gaussian_blur_3d\">Fast Gaussian Blur 3D</string>\n    <string name=\"auto_paste\">Automatisches Einfügen</string>\n    <string name=\"auto_paste_sub\">Erlaubt der App automatisches Einfügen von der Zwischenablage, damit es auf dem Bildschirm erscheint und bearbeitet werden kann.</string>\n    <string name=\"harmonization_color\">Farben Vereinheitlichung</string>\n    <string name=\"harmonization_level\">Ebenen Vereinheitlichung</string>\n    <string name=\"jxl_type_to_jpeg\">JXL zu JPEG</string>\n    <string name=\"select_jxl_image_to_start\">Wähle JXL Bild zum Starten</string>\n    <string name=\"fast_gaussian_blur_2d\">Fast Gaussian Blur 2D</string>\n    <string name=\"fast_gaussian_blur_4d\">Fast Gaussian Blur 4D</string>\n    <string name=\"confetti_type\">Konfetti Typ</string>\n    <string name=\"gif_type_to_jxl\">GIF zu JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Konvertiere GIF Bilder zu JXL animierte Bilder</string>\n    <string name=\"apng_type_to_jxl\">APNG zu JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Konvertiere APNG Bilder zu JXL animierten Bilder</string>\n    <string name=\"jxl_type_to_images\">JXL zu Bild</string>\n    <string name=\"jxl_type_to_jxl\">BIlder zu JXL</string>\n    <string name=\"generate_previews\">Vorschau generieren</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"behavior\">Verhalten</string>\n    <string name=\"skip_file_picking\">Dateiauswahl überspringen</string>\n    <string name=\"generate_previews_sub\">Aktiviert die Vorschauerstellung, was helfen könnte, Abstürze auf manchen Geräten zu verhindern, aber dadurch werden auch einige Funktionen der Einzelbildbearbeitung deaktiviert</string>\n    <string name=\"jxl_type_to_images_sub\">Wandelt eine JXL Animation in einen Bilderstapel um</string>\n    <string name=\"jxl_type_to_jxl_sub\">Wandelt einen Bilderstapel in eine JXL Animation um</string>\n    <string name=\"skip_file_picking_sub\">Wenn möglich wird die Dateiauswahl automatisch geöffnet</string>\n    <string name=\"lossy_compression\">Verlustbehaftete Kompression</string>\n    <string name=\"lossy_compression_sub\">Verwendet verlustbehaftete Kompression (anstelle von verlustfreier) um die Dateigröße zu verringern</string>\n    <string name=\"lanczos_bessel_sub\">Resampling-Methode, die durch Anwendung einer Bessel Funktion auf die Pixel-Werte eine hochqualitative Interpolation gewährleistet</string>\n    <string name=\"compression_type\">Komprimierungstyp</string>\n    <string name=\"speed_sub\">Einstellungen für die Geschwindigkeit der Bild-Dekodierung, dies sollte helfen, das entsprechende Bild schneller zu öffnen, ein Wert von %1$s entspricht dem langsamsten Dekodieren, ein Wert von %2$s dem schnellsten, diese Einstellung kann die Größe der Bilddatei erhöhen</string>\n    <string name=\"pick_multiple_media\">Wähle mehrere Medien</string>\n    <string name=\"pick_single_media\">Wähle einzelnes Medium</string>\n    <string name=\"pick\">Wählen</string>\n    <string name=\"header_today\">Heute</string>\n    <string name=\"header_yesterday\">Gestern</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox\\'s Bildauswahl</string>\n    <string name=\"no_permissions\">Keine Berechtigungen</string>\n    <string name=\"channels_configuration\">Kanal-Konfiguration</string>\n    <string name=\"embedded_picker\">Integrierte Auswahl</string>\n    <string name=\"request\">Anfrage</string>\n    <string name=\"sorting\">Sortierung</string>\n    <string name=\"sort_by_date\">Datum</string>\n    <string name=\"sort_by_date_reversed\">Datum (umgekehrt)</string>\n    <string name=\"sort_by_name\">Name</string>\n    <string name=\"sort_by_name_reversed\">Name (umgekehrt)</string>\n    <string name=\"try_again\">Nochmal versuchen</string>\n    <string name=\"show_settings_in_landscape\">Zeige die Einstellungen im Querformat</string>\n    <string name=\"show_settings_in_landscape_sub\">Wenn deaktiviert, werden die Einstellungen im Querformat über die Taste in der oberen App-Leiste aufgerufen, anstatt immer sichtbar zu sein</string>\n    <string name=\"fullscreen_settings\">Vollbild-Einstellungen</string>\n    <string name=\"switch_type\">Schalter Typ</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"material_you_switch_sub\">Ein Material You Schalter</string>\n    <string name=\"compose_switch_sub\">Ein Jetpack Compose Material You Schalter</string>\n    <string name=\"fluent_switch_sub\">Ein Schalter basierend auf dem \\\"Fluent\\\" Design</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Ein Schalter basiert auf dem \\\"Cupertino\\\" Design</string>\n    <string name=\"fullscreen_settings_sub\">Wenn aktiviert, werden die Einstellungen immer im Vollbild angezeigt, anstatt einer ausfahrbaren Seitenleiste</string>\n    <string name=\"max\">Max</string>\n    <string name=\"detailed\">Detailliert</string>\n    <string name=\"images_to_svg\">Bilder zu SVG</string>\n    <string name=\"path_omit\">Pfad auslassen</string>\n    <string name=\"svg_warning\">Die Verwendung dieses Tools für die Umwandlung großer Bilder ohne Herunterskalierung wird nicht empfohlen, da dies zu Abstürzen führen und die Verarbeitungszeit verlängern kann.</string>\n    <string name=\"downscale_image\">Bild herunterskalieren</string>\n    <string name=\"default_line_width\">Standardlinienbreite</string>\n    <string name=\"resize_anchor\">Ankergröße ändern</string>\n    <string name=\"images_to_svg_sub\">Vorgegebene Bilder in SVG-Bilder umwandeln</string>\n    <string name=\"use_sampled_palette\">Gesampelte Palette verwenden</string>\n    <string name=\"use_sampled_palette_sub\">Die Quantisierungspalette wird gesampelt., wenn diese Option aktiviert ist.</string>\n    <string name=\"downscale_image_sub\">Das Bild wird vor der Verarbeitung auf eine geringere Größe herunterskaliert, damit das Tool schneller und sicherer arbeiten kann</string>\n    <string name=\"min_color_ratio\">Minimales Farbverhältnis</string>\n    <string name=\"lines_threshold\">Schwellenwert für Linien</string>\n    <string name=\"coordinates_rounding_tolerance\">Rundungstoleranz für Koordinaten</string>\n    <string name=\"path_scale\">Pfadskalierung</string>\n    <string name=\"reset_properties\">Eigenschaften zurücksetzen</string>\n    <string name=\"reset_properties_sub\">Alle Eigenschaften werden auf deine Standardwerte zurückgesetzt. Beachte, dass dies nicht rückgängig gemacht werden kann.</string>\n    <string name=\"lstm_network\">LSTM-Netzwerk</string>\n    <string name=\"convert\">Konvertieren</string>\n    <string name=\"tag_compression\">Kompression</string>\n    <string name=\"tag_x_resolution\">X-Auflösung</string>\n    <string name=\"tag_y_resolution\">Y-Auflösung</string>\n    <string name=\"tag_resolution_unit\">Auflösungseinheit</string>\n    <string name=\"tag_image_description\">Bildbeschreibung</string>\n    <string name=\"tag_model\">Modell</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_artist\">Künstler</string>\n    <string name=\"tag_copyright\">Urheberrecht</string>\n    <string name=\"tag_exposure_mode\">Belichtungsmodus</string>\n    <string name=\"tag_white_balance\">Weißabgleich</string>\n    <string name=\"tag_digital_zoom_ratio\">Digitalzoom-Verhältnis</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"tag_gps_processing_method\">GPS-Verarbeitungsmethode</string>\n    <string name=\"tag_gps_area_information\">GPS-Gebietsinformationen</string>\n    <string name=\"tag_gps_datestamp\">GPS-Datumsstempel</string>\n    <string name=\"tag_gps_differential\">GPS-Differenzial</string>\n    <string name=\"tag_interoperability_index\">Interoperabilitätsindex</string>\n    <string name=\"tag_dng_version\">DNG-Version</string>\n    <string name=\"repeat_text\">Text wiederholen</string>\n    <string name=\"repeat_text_sub\">Der aktuelle Text wird bis zum Ende des Pfades wiederholt, anstatt einmalig zu zeichnen</string>\n    <string name=\"dash_size\">Strichgröße</string>\n    <string name=\"draw_mode_image_sub\">Ausgewähltes Bild verwenden, um es entlang eines vorgegebenen Pfades zu zeichnen</string>\n    <string name=\"share_as_pdf\">Als PDF teilen</string>\n    <string name=\"options_below_is_for_images\">Die folgenden Optionen dienen zum Speichern von Bildern, nicht von PDF-Dateien</string>\n    <string name=\"cubic\">Kubisch</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"gaussian\">Gaußisch</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"box\">Box</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"min\">Min.</string>\n    <string name=\"triangle_sub\">Zeichnet ein umrandetes Dreieck vom Startpunkt zum Endpunkt</string>\n    <string name=\"outlined_triangle\">Umrandetes Dreieck</string>\n    <string name=\"outlined_triangle_sub\">Zeichnet ein umrandetes Dreieck vom Startpunkt zum Endpunkt</string>\n    <string name=\"triangle\">Dreieck</string>\n    <string name=\"polygon_sub\">Zeichnet ein Polygon vom Startpunkt zum Endpunkt</string>\n    <string name=\"polygon\">Polygon</string>\n    <string name=\"outlined_polygon\">Umrandetes Polygon</string>\n    <string name=\"outlined_polygon_sub\">Zeichnet ein umrandetes Polygon vom Startpunkt zum Endpunkt</string>\n    <string name=\"star\">Stern</string>\n    <string name=\"outlined_star\">Umrandeter Stern</string>\n    <string name=\"outlined_star_sub\">Zeichnet einen umrandeten Stern vom Startpunkt zum Endpunkt</string>\n    <string name=\"inner_radius_ratio\">Innenradius Verhältnis</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Komprimierte Bits pro Pixel</string>\n    <string name=\"add_new_folder\">Neuen Ordner hinzufügen</string>\n    <string name=\"tag_transfer_function\">Übertragungsfunktion</string>\n    <string name=\"tag_white_point\">Weißer Punkt</string>\n    <string name=\"tag_exposure_time\">Belichtungszeit</string>\n    <string name=\"tag_primary_chromaticities\">Primäre Chromatizitäten</string>\n    <string name=\"tag_exif_version\">Exif-Version</string>\n    <string name=\"tag_flashpix_version\">Flashpix-Version</string>\n    <string name=\"tag_color_space\">Farbraum</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_related_sound_file\">Zugehörige Tondatei</string>\n    <string name=\"tag_offset_time\">Zeitverschiebung</string>\n    <string name=\"tag_brightness_value\">Helligkeitswert</string>\n    <string name=\"tag_cfa_pattern\">CFA-Muster</string>\n    <string name=\"tag_user_comment\">Benutzer-Kommentar</string>\n    <string name=\"tag_photographic_sensitivity\">Fotografische Empfindlichkeit</string>\n    <string name=\"tag_sensitivity_type\">Empfindlichkeitstyp</string>\n    <string name=\"tag_iso_speed\">ISO-Geschwindigkeit</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO-Geschwindigkeit Breitengrad zzz</string>\n    <string name=\"tag_spectral_sensitivity\">Farbempfindlichkeit</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO-Geschwindigkeit Breitengrad yyy</string>\n    <string name=\"tag_shutter_speed_value\">Verschlusszeitwert</string>\n    <string name=\"tag_max_aperture_value\">Max. Blendenwert</string>\n    <string name=\"tag_metering_mode\">Messmodus</string>\n    <string name=\"tag_aperture_value\">Blendenwert</string>\n    <string name=\"tag_focal_length\">Brennweite</string>\n    <string name=\"tag_flash\">Blitzlicht</string>\n    <string name=\"tag_flash_energy\">Blitzlicht-Energie</string>\n    <string name=\"tag_exposure_index\">Belichtungsindex</string>\n    <string name=\"tag_file_source\">Dateiquelle</string>\n    <string name=\"tag_camera_owner_name\">Name des Kamerabesitzers</string>\n    <string name=\"tag_gps_latitude\">GPS-Breitengrad</string>\n    <string name=\"tag_gps_measure_mode\">GPS-Messmodus</string>\n    <string name=\"tag_saturation\">Sättigung</string>\n    <string name=\"tag_sharpness\">Schärfe</string>\n    <string name=\"tag_device_setting_description\">Geräteeinstellung-Beschreibung</string>\n    <string name=\"tag_body_serial_number\">Seriennummer des Gehäuses</string>\n    <string name=\"tag_lens_specification\">Spezifikation des Objektivs</string>\n    <string name=\"tag_lens_model\">Objektiv-Modell</string>\n    <string name=\"tag_lens_serial_number\">Seriennummer des Objektivs</string>\n    <string name=\"tag_gps_timestamp\">GPS-Zeitstempel</string>\n    <string name=\"tag_gps_longitude\">GPS-Längengrad</string>\n    <string name=\"tag_gps_altitude\">GPS-Höhe</string>\n    <string name=\"tag_gps_satellites\">GPS-Satelliten</string>\n    <string name=\"tag_gps_status\">GPS-Status</string>\n    <string name=\"tag_gps_img_direction\">GPS-Bildrichtung</string>\n    <string name=\"tag_gps_map_datum\">GPS-Kartendatum</string>\n    <string name=\"tag_gps_speed\">GPS-Geschwindigkeit</string>\n    <string name=\"font_size\">Schriftgröße</string>\n    <string name=\"watermark_size\">Wasserzeichengröße</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Text auf Pfad mit gegebener Schriftart und Farbe zeichnen</string>\n    <string name=\"draw_image_sub\">Dieses Bild wird als wiederholter Eintrag des gezeichneten Pfades verwendet</string>\n    <string name=\"save_as_pdf\">Als PDF speichern</string>\n    <string name=\"draw_regular_star\">Regelmäßigen Stern zeichnen</string>\n    <string name=\"allow_enter_by_text_field\">Eingabe per Textfeld zulassen</string>\n    <string name=\"no_template_filters\">Keine Vorlagenfilter hinzugefügt</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Der gescannte QR Code ist keine gültige Filtervorlage</string>\n    <string name=\"scan_qr_code\">QR Code scannen</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Erlaube Kamera Berechtigung in den Einstellungen, um den QR-Code zu scannen</string>\n    <string name=\"opened_file_have_no_filter_template\">Ausgewählte Datei hat keine Filtervorlagedaten</string>\n    <string name=\"create_template\">Vorlage erstellen</string>\n    <string name=\"quadric\">Quadratisch</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"linear\">Linear</string>\n    <string name=\"grid_size_x\">Rastergröße X</string>\n    <string name=\"grid_size_y\">Rastergröße Y</string>\n    <string name=\"antialias\">Kantenglättung</string>\n    <string name=\"antialias_sub\">Aktiviert die Kantenglättung, um scharfe Kanten zu vermeiden</string>\n    <string name=\"crop_to_content\">Zum Inhalt zuschneiden</string>\n    <string name=\"frame_color\">Rahmenfarbe</string>\n    <string name=\"color_to_ignore\">Zu ignorierende Farbe</string>\n    <string name=\"open_edit_instead_of_preview\">Bearbeiten statt Vorschau öffnen</string>\n    <string name=\"template\">Vorlage</string>\n    <string name=\"create_new\">Neu erstellen</string>\n    <string name=\"select_template_preview\">Dieses Bild wird für die Vorschau dieser Filtervorlage verwendet</string>\n    <string name=\"template_filter\">Vorlagenfilter</string>\n    <string name=\"template_name\">Vorlagenname</string>\n    <string name=\"as_qr_code\">Als QR-Code-Bild</string>\n    <string name=\"as_file\">Als Datei</string>\n    <string name=\"save_as_file\">Als Datei speichern</string>\n    <string name=\"save_as_qr_code_image\">Als QR-Code-Bild speichern</string>\n    <string name=\"delete_template\">Vorlage löschen</string>\n    <string name=\"delete_template_warn\">Du bist dabei, den ausgewählten Vorlagenfilter zu löschen. Dieser Vorgang kann nicht rückgängig gemacht werden</string>\n    <string name=\"filter_preview\">Filtervorschau</string>\n    <string name=\"qr_code\">QR &amp; Barcode</string>\n    <string name=\"code_content\">Code-Inhalt</string>\n    <string name=\"qr_description\">QR-Beschreibung</string>\n    <string name=\"convert_sub\">Konvertieren von mehrere Bildern in ein bestimmtes Format</string>\n    <string name=\"draw_filter_sub\">Wähle einen Filter, um ihn als Farbe zu nutzen</string>\n    <string name=\"tag_bits_per_sample\">Bits pro Probe</string>\n    <string name=\"tag_photometric_interpretation\">Photometrische Auswertung</string>\n    <string name=\"tag_samples_per_pixel\">Abtastungen pro Pixel</string>\n    <string name=\"tag_planar_configuration\">Planare Konfiguration</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Unterprobenahme</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Positionierung</string>\n    <string name=\"tag_strip_offsets\">Streifenverschiebungen</string>\n    <string name=\"tag_rows_per_strip\">Zeilen pro Streifen</string>\n    <string name=\"image_splitting\">Bild aufteilen</string>\n    <string name=\"image_splitting_sub\">Teile ein einzelnes Bild nach Zeilen oder Spalten auf</string>\n    <string name=\"format_conversion_sub\">Konvertieren von Bildstapeln von einem Format in ein anderes</string>\n    <string name=\"format_conversion\">Stapelverarbeitung</string>\n    <string name=\"engine_mode\">Motor Modus</string>\n    <string name=\"legacy\">Legacy</string>\n    <string name=\"image_stacking\">Bild stapeln</string>\n    <string name=\"image_stacking_sub\">Stapel Bilder mit ausgewählten Mischmodi übereinander</string>\n    <string name=\"legacy_and_lstm\">Altbestand &amp; LSTM</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte-Zahlen</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG Interchange Format</string>\n    <string name=\"quadratic_threshold\">Quadratischer Schwellenwert</string>\n    <string name=\"document_scanner_sub\">Scanne Dokumente und erstelle PDFs oder separate Bilder daraus</string>\n    <string name=\"document_scanner\">Dokumentenscanner</string>\n    <string name=\"add_favorites\">Favoriten hinzufügen</string>\n    <string name=\"no_favorite_options_selected\">Keine bevorzugten Optionen ausgewählt, füge sie auf der Seite Tools hinzu</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Wenn du ein Bild auswählst, um es in ImageToolbox zu öffnen (Vorschau), wird anstatt der Vorschau das Auswahlblatt \\\"Bearbeiten\\\" geöffnet</string>\n    <string name=\"qr_code_sub\">Scanne den QR-Code und rufe seinen Inhalt ab oder füge deine Zeichenfolge ein, um einen neuen zu erstellen</string>\n    <string name=\"scan_qr_code_to_replace_content\">Scanne einen beliebigen Barcode, um den Inhalt des Feldes zu ersetzen, oder schreib etwas, um einen neuen Barcode mit dem ausgewählten Typ zu erzeugen</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG Austauschformat Länge</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Koeffizienten</string>\n    <string name=\"tag_make\">Machen</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y Dimension</string>\n    <string name=\"tag_maker_note\">Anmerkung des Herstellers</string>\n    <string name=\"tag_datetime_digitized\">Datum Uhrzeit Digitalisiert</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_recommended_exposure_index\">Empfohlener Belichtungsindex</string>\n    <string name=\"tag_exposure_bias_value\">Belichtung Verzerrungswert</string>\n    <string name=\"tag_subject_distance\">Thema Entfernung</string>\n    <string name=\"tag_spatial_frequency_response\">Räumlicher Frequenzgang</string>\n    <string name=\"tag_focal_plane_x_resolution\">Brennebene X Auflösung</string>\n    <string name=\"tag_focal_plane_y_resolution\">Brennebene Y Auflösung</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Einheit für die Auflösung der Brennebene</string>\n    <string name=\"tag_subject_location\">Thema Standort</string>\n    <string name=\"tag_sensing_method\">Sensorik Methode</string>\n    <string name=\"tag_custom_rendered\">Benutzerdefiniert gerendert</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Brennweite bei 35-mm-Film</string>\n    <string name=\"tag_scene_capture_type\">Szenenerfassungstyp</string>\n    <string name=\"tag_gain_control\">Verstärkungsregelung</string>\n    <string name=\"tag_image_unique_id\">Einzigartige Bild-ID</string>\n    <string name=\"tag_subject_distance_range\">Thema Entfernungsbereich</string>\n    <string name=\"tag_lens_make\">Objektiv Marke</string>\n    <string name=\"tag_gps_version_id\">GPS-Version ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Breitengrad Referenz</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Längengrad Referenz</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Höhenangabe Referenz</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS-Geschwindigkeitsreferenz</string>\n    <string name=\"tag_gps_track_ref\">GPS-Track-Referenz</string>\n    <string name=\"tag_gps_track\">GPS Track</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS-Bild Richtungsreferenz</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Ziel Breitengrad Referenz</string>\n    <string name=\"tag_gps_dest_latitude\">GPS-Ziel Breitengrad</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Ziel Längengrad Ref</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Ziel Peilung Referenz</string>\n    <string name=\"tag_gps_dest_bearing\">GPS-Zielpeilung</string>\n    <string name=\"tag_gps_dest_distance\">GPS-Zielentfernung</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H-Ortungsfehler</string>\n    <string name=\"tag_default_crop_size\">Standardausschnittgröße</string>\n    <string name=\"tag_orf_preview_image_start\">Bildvorschau Start</string>\n    <string name=\"tag_orf_preview_image_length\">Vorschaubild Länge</string>\n    <string name=\"tag_orf_aspect_frame\">Aspekt Rahmen</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Sensor unterer Rand</string>\n    <string name=\"tag_rw2_sensor_left_border\">Sensor Linker Rand</string>\n    <string name=\"tag_rw2_sensor_right_border\">Sensor Rechter Rand</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sensor Oberer Rand</string>\n    <string name=\"click_to_start_scanning\">Klicken, um das Scannen zu starten</string>\n    <string name=\"start_scanning\">Scannen starten</string>\n    <string name=\"bspline_sub\">Verwendet stückweise definierte Polynomfunktionen, um eine Kurve oder Fläche sanft zu interpolieren und anzunähern, flexible und kontinuierliche Formdarstellung</string>\n    <string name=\"hanning_sub\">‘Eine Variante des Hann-Fensters, die häufig zur Verringerung spektraler Leckagen bei der Signalverarbeitung verwendet wird</string>\n    <string name=\"blackman_sub\">Eine Fensterfunktion, die eine gute Frequenzauflösung bietet, indem sie spektrale Leckagen minimiert, und die häufig in der Signalverarbeitung verwendet wird</string>\n    <string name=\"bartlett_hann_sub\">Eine hybride Fensterfunktion, die das Bartlett- und das Hann-Fenster kombiniert und zur Verringerung spektraler Leckagen bei der Signalverarbeitung verwendet wird</string>\n    <string name=\"lanczos4_jinc_sub\">Eine Variante des Lanczos-4-Filters, welche die jinc-Funktion verwendet und eine hochwertige Interpolation mit minimalen Artefakten ermöglicht</string>\n    <string name=\"draw_regular_polygon\">Regelmäßiges Polygon zeichnen</string>\n    <string name=\"draw_regular_polygon_sub\">Zeichne ein regelmäßiges Polygon anstelle einer freien Form</string>\n    <string name=\"star_sub\">Zeichnet den Stern vom Startpunkt zum Endpunkt</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Elliptical Weighted Average (EWA)-Variante des Lanczos-3-Jinc-Filters für qualitativ hochwertiges Resampling mit reduziertem Aliasing</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Elliptische gewichtete Mittelwertbildung (EWA) als Variante des Lanczos-Sharp-Filters zur Erzielung scharfer Ergebnisse mit minimalen Artefakten</string>\n    <string name=\"draw_regular_star_sub\">Zeichne einen Stern, der regelmäßig statt frei geformt sein wird</string>\n    <string name=\"tag_reference_black_white\">Referenz Schwarz Weiß</string>\n    <string name=\"tag_datetime_original\">Datum Uhrzeit Original</string>\n    <string name=\"kaiser_sub\">Eine Interpolationsmethode, die das Kaiser-Fenster verwendet und eine gute Kontrolle über den Kompromiss zwischen Hauptkeulenbreite und Nebenkeulenpegel bietet</string>\n    <string name=\"welch_sub\">Eine Fensterfunktion, die für eine gute Frequenzauflösung mit reduziertem spektralen Leck entwickelt wurde und häufig in der Signalverarbeitung verwendet wird</string>\n    <string name=\"box_sub\">Eine einfache Resampling-Methode, bei welcher der Durchschnitt der nächstgelegenen Pixelwerte verwendet wird, was oft zu einem blockigen Aussehen führt</string>\n    <string name=\"lanczos2_jinc_sub\">Eine Variante des Lanczos-2-Filters, welche die jinc-Funktion verwendet und eine hochwertige Interpolation mit minimalen Artefakten ermöglicht</string>\n    <string name=\"tag_datetime\">Datum Uhrzeit</string>\n    <string name=\"hamming_sub\">Eine Fensterfunktion, die dazu dient, spektrale Leckagen zu reduzieren, indem die Ränder eines Signals verjüngt werden; nützlich bei der Signalverarbeitung</string>\n    <string name=\"lanczos_6_sub\">Ein Lanczos-Resampling-Filter mit einer höheren Ordnung von 6, der eine schärfere und genauere Bildskalierung ermöglicht</string>\n    <string name=\"tag_offset_time_original\">Versetzte Zeit Original</string>\n    <string name=\"tag_subsec_time\">Sub Sec Zeit</string>\n    <string name=\"tag_exposure_program\">Belichtungsprogramm</string>\n    <string name=\"tag_gps_dest_longitude\">GPS-Ziel Längengrad</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Ziel Entfernung Referenz</string>\n    <string name=\"lanczos3_jinc_sub\">Eine Variante des Lanczos-3-Filters, welche die jinc-Funktion verwendet und eine hochwertige Interpolation mit minimalen Artefakten ermöglicht</string>\n    <string name=\"cubic_sub\">Die kubische Interpolation sorgt für eine glattere Skalierung, indem sie die nächstgelegenen 16 Pixel berücksichtigt und bessere Ergebnisse als die bilineare Interpolation liefert.</string>\n    <string name=\"gaussian_sub\">Eine Interpolationsmethode, die eine Gauß-Funktion anwendet und zur Glättung und Rauschunterdrückung in Bildern dient</string>\n    <string name=\"tag_offset_time_digitized\">Versetzte Zeit Digitalisiert</string>\n    <string name=\"tag_standard_output_sensitivity\">Standard-Ausgangs-Empfindlichkeit</string>\n    <string name=\"tag_subject_area\">Themenbereich</string>\n    <string name=\"vertices\">Scheitelpunkte</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Zeit Original</string>\n    <string name=\"tag_subsec_time_digitized\">Sub Sec Zeit Digitalisiert</string>\n    <string name=\"tag_f_number\">F Nummer</string>\n    <string name=\"simple_old_tv\">Einfacher alter Fernseher</string>\n    <string name=\"target_image\">Zielbild</string>\n    <string name=\"palette_transfer\">Palette übertragen</string>\n    <string name=\"enhanced_oil\">Verbessertes Öl</string>\n    <string name=\"simple_sketch\">Einfache Skizze</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"color_poster\">Farbiges Poster</string>\n    <string name=\"edge_mode\">Kantenmodus</string>\n    <string name=\"linear_box_blur\">Lineare Boxunschärfe</string>\n    <string name=\"linear_tent_blur\">Lineare Zelt Unschärfe</string>\n    <string name=\"linear_gaussian_box_blur\">Linearer Gaußscher Box Unschärfe</string>\n    <string name=\"color_blind_scheme\">Farbenblindheit</string>\n    <string name=\"color_blind_scheme_sub\">Wähle den Modus, um die Themenfarben für die gewählte Variante der Farbenblindheit anzupassen</string>\n    <string name=\"protanomaly_sub\">Schwierigkeiten bei der Unterscheidung zwischen roten und grünen Farbtönen</string>\n    <string name=\"deuteranomaly_sub\">Schwierigkeiten bei der Unterscheidung zwischen grünen und roten Farbtönen</string>\n    <string name=\"tritanomaly_sub\">Schwierigkeiten bei der Unterscheidung zwischen blauen und gelben Farbtönen</string>\n    <string name=\"protanopia_sub\">Unfähigkeit, rote Farbtöne wahrzunehmen</string>\n    <string name=\"deuteranopia_sub\">Unfähigkeit, grüne Farbtöne wahrzunehmen</string>\n    <string name=\"tritanopia_sub\">Unfähigkeit, blaue Farbtöne wahrzunehmen</string>\n    <string name=\"achromatomaly_sub\">Verminderte Empfindlichkeit für alle Farben</string>\n    <string name=\"achromatopsia_sub\">Vollständige Farbenblindheit, sieht nur Grautöne</string>\n    <string name=\"not_use_color_blind_scheme\">Kein Farbenblindheitschema verwenden</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Farben werden genau so sein, wie sie im Thema festgelegt sind</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Ein Lagrange-Interpolationsfilter der Ordnung 2, geeignet für hochwertige Bildskalierung mit glatten Übergängen</string>\n    <string name=\"lagrange_3_sub\">Ein Lagrange-Interpolationsfilter der Ordnung 3, der eine bessere Genauigkeit und glattere Ergebnisse bei der Bildskalierung bietet</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linearer schneller Gaußscher Unschärfe Next</string>\n    <string name=\"linear_gaussian_blur\">Linearer Gaußscher Unschärfe</string>\n    <string name=\"replace_filter\">Filter ersetzen</string>\n    <string name=\"linear_fast_gaussian_blur\">Linearer schneller Gaußscher Unschärfe</string>\n    <string name=\"pick_filter_info\">Wählen den Filter unten, um ihn als Pinsel in deiner Zeichnung zu nutzen</string>\n    <string name=\"equalize_histogram_hsv\">Histogramm ausgleichen HSV</string>\n    <string name=\"equalize_histogram\">Histogramm ausgleichen</string>\n    <string name=\"robidoux_sharp\">Robidoux Scharf</string>\n    <string name=\"quadric_sub\">Eine Methode, bei der eine quadratische Funktion zur Interpolation verwendet wird, die glatte und kontinuierliche Ergebnisse liefert</string>\n    <string name=\"sphinx_sub\">Eine fortschrittliche Resampling-Methode, die eine hochwertige Interpolation mit minimalen Artefakten ermöglicht</string>\n    <string name=\"robidoux_sharp_sub\">Eine schärfere Variante der Robidoux-Methode, optimiert für eine scharfe Bildgrößenänderung</string>\n    <string name=\"spline16_sub\">Eine splinebasierte Interpolationsmethode, die mit einem 16-Tap-Filter glatte Ergebnisse liefert</string>\n    <string name=\"spline36_sub\">Eine splinebasierte Interpolationsmethode, die mit einem 36-Tap-Filter glatte Ergebnisse liefert</string>\n    <string name=\"spline64_sub\">Eine splinebasierte Interpolationsmethode, die mit einem 64-Tap-Filter glatte Ergebnisse liefert</string>\n    <string name=\"bohman_sub\">Eine Fensterfunktion, die zur Verringerung spektraler Leckagen verwendet wird und eine gute Frequenzauflösung bei Signalverarbeitungsanwendungen ermöglicht</string>\n    <string name=\"lanczos2_sub\">Eine Resampling-Methode, die einen 2-lobe Lanczos-Filter für hochwertige Interpolation mit minimalen Artefakten verwendet</string>\n    <string name=\"lanczos4_sub\">Eine Resampling-Methode, die einen 4-lobe Lanczos-Filter für hochwertige Interpolation mit minimalen Artefakten verwendet</string>\n    <string name=\"enter_percentage\">Prozentsatz eingeben</string>\n    <string name=\"allow_enter_by_text_field_sub\">Ermöglicht ein Textfeld hinter der Auswahl der Voreinstellungen, um sie spontan einzugeben</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Wickeln</string>\n    <string name=\"tiff_compression_scheme\">TIFF Komprimierungsschema</string>\n    <string name=\"low_poly\">Niedrig Poly</string>\n    <string name=\"sand_painting\">Sandmalerei</string>\n    <string name=\"tri_tone\">Dreifarbig</string>\n    <string name=\"third_color\">Dritte Farbe</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Elliptische gewichteter Durchschnitt (EWA) als Variante des Hanning-Filters für glatte Interpolation und Resampling</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elliptische gewichteter Durchschnitt (EWA) als Variante des Robidoux-Filters für hochwertiges Resampling</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_quadric\">Quadrische EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elliptische gewichteter Durchschnitt (EWA) als Variante des Robidoux Scharf-Filters für schärfere Ergebnisse</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Ein Resampling-Filter für hochwertige Bildverarbeitung mit einem ausgewogenen Verhältnis von Schärfe und Glätte</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Elliptische gewichteter Durchschnitt (EWA) als Variante des Ginseng-Filters zur Verbesserung der Bildqualität</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Scharf EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Schärfste EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Elliptische gewichteter Durchschnitt (EWA) Variante des Lanczos 4 schärfste Filters für extrem scharfes Bild-Resampling</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Weich EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptische gewichteter Durchschnitt (EWA) als Variante des Lanczos-Weich-Filters für eine glattere Bildumwandlung</string>\n    <string name=\"haasn_soft\">Haasn Weich</string>\n    <string name=\"haasn_soft_sub\">Ein von Haasn entwickelter Resampling-Filter für eine glatte und artefaktfreie Bildskalierung</string>\n    <string name=\"dismiss_forever\">Für immer verwerfen</string>\n    <string name=\"scale_color_space\">Skala Farbraum</string>\n    <string name=\"equalize_histogram_pixelation\">Histogramm-Pixelung ausgleichen</string>\n    <string name=\"equalize_histogram_adaptive\">Histogramm ausgleichen Adaptiv</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Histogramm ausgleichen Adaptive LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Histogramm ausgleichen Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"add_image\">Bild hinzufügen</string>\n    <string name=\"clustered_2x2_dithering\">Geclustertes 2x2 Dithering</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_4x4_dithering\">Geclustertes 4x4 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"bins_count\">Anzahl der Behälter</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Histogramm ausgleichen Adaptive HSV</string>\n    <string name=\"color_tools_sub\">Mischen, Töne erzeugen, Schattierungen erzeugen und mehr</string>\n    <string name=\"harmony_analogous_complementary\">Analog + Komplementär</string>\n    <string name=\"harmony_complementary\">Komplementär</string>\n    <string name=\"harmony_analogous\">Analog</string>\n    <string name=\"harmony_triadic\">Triadisch</string>\n    <string name=\"harmony_split_complementary\">Geteilt Komplementär</string>\n    <string name=\"harmony_tetradic\">Tetradisch</string>\n    <string name=\"harmony_square\">Viereckig</string>\n    <string name=\"color_tools\">Farb Tools</string>\n    <string name=\"color_harmonies\">Farbharmonien</string>\n    <string name=\"color_shading\">Farbschattierung</string>\n    <string name=\"tints\">Farbtöne</string>\n    <string name=\"shades\">Schattierungen</string>\n    <string name=\"color_mixing\">Farbmischung</string>\n    <string name=\"color_info\">Farbe Info</string>\n    <string name=\"selected_color\">Ausgewählte Farbe</string>\n    <string name=\"tones\">Tönep</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Monet kann nicht verwendet werden, wenn die dynamischen Farben aktiviert sind</string>\n    <string name=\"target_lut_image\">LUT-Zielbild</string>\n    <string name=\"soft_elegance_variant\">Weiche Eleganz Variante</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"soft_elegance\">Weiche Eleganz</string>\n    <string name=\"ewa_blackman_sub\">Elliptische gewichteter Durchschnitt (EWA) Variante des Blackman-Filters zur Minimierung von Ringing-Artefakten</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Scharf EWA</string>\n    <string name=\"ewa_quadric_sub\">Elliptische gewichteter Durchschnitt (EWA) als Variante des Quadric-Filters für glatte Interpolation</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Histogramm ausgleichen Adaptive HSL</string>\n    <string name=\"bartlett_sub\">Eine dreieckige Fensterfunktion, die in der Signalverarbeitung zur Verringerung spektraler Leckagen verwendet wird</string>\n    <string name=\"robidoux_sub\">Ein hochwertiges Interpolationsverfahren, das für die natürliche Größenanpassung von Bildern optimiert ist und ein Gleichgewicht zwischen Schärfe und Glätte schafft</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lanczos_6_jinc_sub\">Eine Variante des Lanczos-6-Filters unter Verwendung einer Jinc-Funktion zur Verbesserung der Qualität des Bild-Resamplings</string>\n    <string name=\"lanczos3_sub\">Eine Resampling-Methode, die einen 3-lobe Lanczos-Filter für hochwertige Interpolation mit minimalen Artefakten verwendet</string>\n    <string name=\"linear_stack_blur\">Lineare Stapelunschärfe</string>\n    <string name=\"gaussian_box_blur\">Gaußscher Box Unschärfe</string>\n    <string name=\"languages_imported\">Sprachen erfolgreich importiert</string>\n    <string name=\"backup_ocr_models\">OCR Modelle sichern</string>\n    <string name=\"clustered_8x8_dithering\">Geclustertes 8x8 Dithering</string>\n    <string name=\"color_to_mix\">Farbe zum Mischen</string>\n    <string name=\"fit_to_bounds\">An Grenze halten</string>\n    <string name=\"soft_glow\">Sanftes Glühen</string>\n    <string name=\"fit_to_bounds_sub\">Kombiniere den Zuschneidemodus mit diesem Parameter, um das gewünschte Verhalten zu erreichen (Zuschneiden/Anpassen an das Seitenverhältnis)</string>\n    <string name=\"variation\">Variation</string>\n    <string name=\"top_left\">Oben links</string>\n    <string name=\"top_right\">Oben rechts</string>\n    <string name=\"bottom_left\">Unten links</string>\n    <string name=\"bottom_right\">Unten rechts</string>\n    <string name=\"top_center\">Oben Mitte</string>\n    <string name=\"center_right\">Mitte rechts</string>\n    <string name=\"bottom_center\">Unten Mitte</string>\n    <string name=\"center_left\">Mitte links</string>\n    <string name=\"import_word\">Importieren</string>\n    <string name=\"export\">Exportieren</string>\n    <string name=\"position\">Position</string>\n    <string name=\"center\">Mitte</string>\n    <string name=\"added_filter_template\">Filtervorlage mit Namen \\\"%1$s\\\" (%2$s) hinzugefügt</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleich Bypass</string>\n    <string name=\"candlelight\">Kerzenlicht</string>\n    <string name=\"drop_blues\">Tropfen Blues</string>\n    <string name=\"edgy_amber\">Edgy Amber</string>\n    <string name=\"fall_colors\">Herbstfarben</string>\n    <string name=\"film_stock_50\">Filmstock 50</string>\n    <string name=\"foggy_night\">Neblige Nacht</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">­Neutrales LUT Bild</string>\n    <string name=\"palette_transfer_variant\">Palette Transfer Variante</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Target 3D LUT File (.cube / .CUBE)</string>\n    <string name=\"save_empty_lut_sub\">Verwenden zunächst deine bevorzugte Fotobearbeitungsanwendung, um einen Filter auf die neutrale LUT anzuwenden, die du hier erhalten kannst. Damit dies richtig funktioniert, darf die Farbe jedes Pixels nicht von anderen Pixeln abhängen (z. B. funktioniert der Weichzeichner nicht). Sobald du fertig bist, verwendest du dein neues LUT-Bild als Eingabe für den 512*512 LUT-Filter</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Erteile Kamera Erlaubnis in den Einstellungen, um den Dokumentenscanner zu scannen</string>\n    <string name=\"golden_forest\">Goldener Wald</string>\n    <string name=\"greenish\">Grünlich</string>\n    <string name=\"retro_yellow\">Retrogelb</string>\n    <string name=\"coffee\">Kaffee</string>\n    <string name=\"celluloid\">Zelluloid</string>\n    <string name=\"links_preview\">Links Vorschau</string>\n    <string name=\"links_preview_sub\">Aktiviert das Abrufen der Linkvorschau an Stellen, an denen du Text erhalten kannst (QR-Code, OCR usw.)</string>\n    <string name=\"links\">Links</string>\n    <string name=\"ico_size_warning\">ICO-Dateien können nur mit einer maximalen Größe von 256 x 256 gespeichert werden</string>\n    <string name=\"default_draw_color\">Standardfarbe zum Zeichnen</string>\n    <string name=\"default_draw_path_mode\">Standard-Zeichenpfadmodus</string>\n    <string name=\"add_timestamp\">Zeitstempel hinzufügen</string>\n    <string name=\"add_timestamp_sub\">Aktiviert das Hinzufügen eines Zeitstempels zum Dateinamen der Ausgabe</string>\n    <string name=\"formatted_timestamp\">Formatierter Zeitstempel</string>\n    <string name=\"formatted_timestamp_sub\">Zeitstempelformatierung im Ausgabedateinamen anstelle von einfachen Millisekunden aktivieren</string>\n    <string name=\"enable_timestamps_to_format_them\">Zeitstempel aktivieren, um ihr Format auszuwählen</string>\n    <string name=\"recently_used\">Kürzlich verwendet</string>\n    <string name=\"ci_channel\">CI-Kanal</string>\n    <string name=\"group\">Gruppe</string>\n    <string name=\"ci_channel_sub\">Lass dich über neue Versionen der App benachrichtigen und lies Ankündigungen</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Tritt unserem Chat bei, in dem du alles besprechen kannst, was du willst, und schau auch in den CI-Kanal, wo ich Betas und Ankündigungen poste</string>\n    <string name=\"manage_storage_extra_types\">Kein vollständiger Zugriff auf Dateien</string>\n    <string name=\"manage_storage_extra_types_sub\">Erlaube allen Dateien den Zugriff, um JXL, QOI und andere Bilder zu sehen, die unter Android nicht als Bilder erkannt werden. Ohne diese Berechtigung kann Image Toolbox diese Bilder nicht anzeigen</string>\n    <string name=\"one_time_save_location\">Einmaliger Speicherort</string>\n    <string name=\"one_time_save_location_sub\">Einmalige Speicherorte anzeigen und bearbeiten, die du durch langes Drücken der Speichertaste in fast allen Optionen verwenden kannst</string>\n    <string name=\"gif_type_to_webp\">GIF zu WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">GIF-Bilder in animierte WEBP-Bilder umwandeln</string>\n    <string name=\"webp_type_to_image\">WEBP zu Bildern</string>\n    <string name=\"webp_tools\">­­WEBP Tools</string>\n    <string name=\"webp_tools_sub\">Bilder in animierte WEBP-Bilder umwandeln oder Einzelbilder aus einer gegebenen WEBP-Animation extrahieren</string>\n    <string name=\"webp_type_to_image_sub\">WEBP-Datei in einen Stapel an Bildern umwandeln</string>\n    <string name=\"webp_type_to_webp_sub\">Stapel an Bildern in eine WEBP-Datei umwandeln</string>\n    <string name=\"webp_type_to_webp\">Bilder zu WEBP</string>\n    <string name=\"select_webp_image_to_start\">WEBP-Bild zum Starten auswählen</string>\n    <string name=\"image_toolbox_in_telegram\">Image Toolbox in Telegram 🎉</string>\n    <string name=\"custom_options\">Eigene Optionen</string>\n    <string name=\"custom_params_info\">Optionen sollten nach folgendem Muster eingegeben werden: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"free_corners\">Freie Ecken</string>\n    <string name=\"mask\">Maske</string>\n    <string name=\"spot_heal\">Stelle heilen</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Punkte werden nicht durch Bildgrenzen gebunden, nützlich für genauere perspektivische Korrektur</string>\n    <string name=\"spot_heal_sub\">Inhaltsbewusste Füllung unter Zeichenpfad</string>\n    <string name=\"histogram_sub\">RGB- oder Helligkeits-Histogramm, um dir zu helfen, Anpassungen vorzunehmen</string>\n    <string name=\"tesseract_options\">Tesseract-Optionen</string>\n    <string name=\"tesseract_options_sub\">Eingabevariablen für die Tesseract Engine anwenden</string>\n    <string name=\"auto_crop\">Autom. Beschnitt</string>\n    <string name=\"free_corners_sub\">Bild per Vieleck beschneiden. (Korrigiert auch die Perspektive.)</string>\n    <string name=\"coerce_points_to_image_bounds\">Punkte in Bildgrenzen zwingen</string>\n    <string name=\"fit_description\">Passe ein Bild an vorgegebene Abmessungen an und wende Weichzeichner oder Farbe auf den Hintergrund an</string>\n    <string name=\"tools_arrangement\">Anordnung der Tools</string>\n    <string name=\"group_tools_by_type\">Tools nach Typ gruppieren</string>\n    <string name=\"group_tools_by_type_sub\">Tools im Hauptfenster nach Typ gruppieren anstatt untereinander als Liste</string>\n    <string name=\"default_values\">Standardwerte</string>\n    <string name=\"system_bars_visibility\">Systemleisten Sichtbarkeit</string>\n    <string name=\"show_system_bars_by_swipe\">Systemleisten durch Wischen anzeigen</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Zeigt Systemleisten durch Wischen an, falls sie versteckt sind</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Alle verbergen</string>\n    <string name=\"show_all\">Alle anzeigen</string>\n    <string name=\"hide_nav_bar\">Navi-Leiste verbergen</string>\n    <string name=\"hide_status_bar\">Statusleiste verbergen</string>\n    <string name=\"noise_generation\">Rauscherzeugung</string>\n    <string name=\"noise_generation_sub\">Verschiedenes Rauschen erzeugen wie Perlin oder andere</string>\n    <string name=\"frequency\">Frequenz</string>\n    <string name=\"noise_type\">Rauschtyp</string>\n    <string name=\"rotation_type\">Rotationsart</string>\n    <string name=\"fractal_type\">Fraktaltyp</string>\n    <string name=\"octaves\">Oktaven</string>\n    <string name=\"lacunarity\">Lückenhaftigkeit</string>\n    <string name=\"gain\">Zuwachs</string>\n    <string name=\"weighted_strength\">Gewichtete Stärke</string>\n    <string name=\"jitter\">Flimmern</string>\n    <string name=\"ping_pong_strength\">Ping Pong Stärke</string>\n    <string name=\"distance_function\">Abstandsfunktion</string>\n    <string name=\"return_type\">Wiedergabetyp</string>\n    <string name=\"alignment\">Ausrichtung</string>\n    <string name=\"custom_filename\">Eigener Dateiname</string>\n    <string name=\"custom_filename_sub\">Wähle Speicherort und Dateiname für das aktuelles Bild</string>\n    <string name=\"saved_to_custom\">In Ordner mit eigenem Namen gespeichert</string>\n    <string name=\"collage_maker\">Collagen erstellen</string>\n    <string name=\"collage_type\">Collagen-Art</string>\n    <string name=\"collages_info\">Bild halten zum Wechseln, bewegen und zoomen um Position anzupassen</string>\n    <string name=\"histogram\">Histogramm</string>\n    <string name=\"image_for_histogram\">Dieses Bild wird verwendet, um RGB und Helligkeits-Histogramme zu erzeugen</string>\n    <string name=\"opening\">Wird geöffnet</string>\n    <string name=\"closing\">Wird geschlossen</string>\n    <string name=\"morphological_gradient\">Morphologischer Farbverlauf</string>\n    <string name=\"black_hat\">Schwarzer Hut</string>\n    <string name=\"stamped\">Gestempelt</string>\n    <string name=\"reset_curves\">Kurven zurücksetzen</string>\n    <string name=\"line_style\">Linienstil</string>\n    <string name=\"gap_size\">Lückengröße</string>\n    <string name=\"dashed\">Gestrichelt</string>\n    <string name=\"dot_dashed\">Strichpunktiert</string>\n    <string name=\"zigzag\">Zickzack</string>\n    <string name=\"dot_dashed_sub\">Zeichnet eine gepunktete und gestrichelte Linie entlang eines angegebenen Pfades</string>\n    <string name=\"zigzag_sub\">Zeichnet ein wellenförmiges Zickzack entlang des Pfades</string>\n    <string name=\"zigzag_ratio\">Zickzack-Verhältnis</string>\n    <string name=\"threshold_one\">Schwellenwert Eins</string>\n    <string name=\"threshold_two\">Schwellenwert Zwei</string>\n    <string name=\"dashed_sub\">Zeichnet eine gestrichelte Linie entlang des gezeichneten Pfades mit der angegebenen Lückengröße</string>\n    <string name=\"defaultt_sub\">Nur standardmäßige gerade Linien</string>\n    <string name=\"stamped_sub\">Zeichnet ausgewählte Formen entlang des Pfades mit dem angegebenen Abstand</string>\n    <string name=\"crossfade\">Überblendung</string>\n    <string name=\"top_hat\">Zylinderhut</string>\n    <string name=\"tone_curves\">Tonkurven</string>\n    <string name=\"reset_curves_sub\">Die Kurven werden auf den Standardwert zurückgesetzt</string>\n    <string name=\"create_shortcut\">Verknüpfung erstellen</string>\n    <string name=\"create_shortcut_title\">Tool zum Anheften auswählen</string>\n    <string name=\"create_shortcut_subtitle\">Das Tool wird dem Startbildschirm deines Starters als Verknüpfung hinzugefügt, verwende es in Kombination mit der Einstellung „Dateiauswahl überspringen“, um das gewünschte Verhalten zu erreichen</string>\n    <string name=\"collage_maker_sub\">Erstelle Collagen aus bis zu 20 Bildern</string>\n    <string name=\"mirror_101\">Spiegel 101</string>\n    <string name=\"enhanced_zoom_blur\">Verbesserte Zoom Unschärfe</string>\n    <string name=\"grid_color\">Rasterfarbe</string>\n    <string name=\"helper_grid\">Hilfsraster</string>\n    <string name=\"helper_grid_sub\">Zeigt ein Hilfsraster über der Zeichenfläche an, um präzise Manipulationen zu ermöglichen</string>\n    <string name=\"cell_width\">Zellenbreite</string>\n    <string name=\"cell_height\">Zellenhöhe</string>\n    <string name=\"compact_selectors\">Kompakte Selektoren</string>\n    <string name=\"compact_selectors_sub\">Einige Auswahlkontrollen verwenden ein kompaktes Layout, um weniger Platz zu benötigen</string>\n    <string name=\"layout\">Layout</string>\n    <string name=\"main_screen_title\">Titel des Hauptbildschirms</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Gewähre der Kamera in den Einstellungen die Berechtigung, ein Bild aufzunehmen</string>\n    <string name=\"constant_rate_factor\">Konstanter Ratenfaktor (KRF)</string>\n    <string name=\"crf_sub\">Ein Wert von %1$s bedeutet eine langsame Komprimierung, was zu einer relativ kleinen Dateigröße führt. %2$s bedeutet eine schnellere Komprimierung, was zu einer großen Datei führt.</string>\n    <string name=\"lut_library\">Lut Bücherei</string>\n    <string name=\"lut_library_sub\">Download einer Sammlung von LUTs, die du nach dem Herunterladen anwenden kannst</string>\n    <string name=\"use_circle_kernel\">Circle Kernel verwenden</string>\n    <string name=\"lut_library_update_sub\">Aktualisiere LUT-Sammlung (nur neue werden in die Warteschlange gestellt), die du nach dem Herunterladen anwenden kannst</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"dont_stack_frames\">Keine Rahmen stapeln</string>\n    <string name=\"dont_stack_frames_sub\">Ermöglicht die Beseitigung vorheriger Einzelbilder, so dass sie nicht übereinander gestapelt werden</string>\n    <string name=\"crossfade_sub\">Frames werden ineinander überblendet</string>\n    <string name=\"crossfade_count\">Anzahl der Überblendungsbilder</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"laplacian_simple\">Laplacian Einfach</string>\n    <string name=\"sobel_simple\">Sobel Einfach</string>\n    <string name=\"filter_preview_image\">Vorschaubild</string>\n    <string name=\"filter_preview_image_sub\">Standardbildvorschau für Filter ändern</string>\n    <string name=\"hide\">Ausblenden</string>\n    <string name=\"show\">Anzeigen</string>\n    <string name=\"slider_type\">Schieberegler-Typ</string>\n    <string name=\"material_you_slider_sub\">Ein Material You Schieberegler</string>\n    <string name=\"fancy_sub\">Ein schick aussehender Schieberegler. Das ist die Standardoption</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy\">Schick</string>\n    <string name=\"material_2_sub\">Ein Material 2 Schieberegler</string>\n    <string name=\"apply\">Anwenden</string>\n    <string name=\"center_align_dialog_buttons_sub\">Schaltflächen der Dialoge werden nach Möglichkeit in der Mitte anstatt links positioniert</string>\n    <string name=\"markup_layers\">Markierungsebenen</string>\n    <string name=\"markup_layers_sub\">Ebenenmodus mit der Möglichkeit, Bilder, Text und mehr frei zu platzieren</string>\n    <string name=\"layers_on_image_sub\">Benutze ein Bild als Hintergrund und füge verschiedene Ebenen darüber hinzu</string>\n    <string name=\"layers_on_image\">Ebenen auf dem Bild</string>\n    <string name=\"center_align_dialog_buttons\">Dialogschaltflächen zentrieren</string>\n    <string name=\"open_source_licenses\">Open Source Lizenzen</string>\n    <string name=\"open_source_licenses_sub\">Lizenzen der in dieser App verwendeten Open Source Bibliotheken anzeigen</string>\n    <string name=\"enter_percent\">Eingabe %</string>\n    <string name=\"unknown_host\">Auf Website kann nicht zugegriffen werden, versuche es mit VPN oder überprüfe, ob die URL korrekt ist</string>\n    <string name=\"edit_layer\">Ebene bearbeiten</string>\n    <string name=\"layers_on_background\">Ebenen auf dem Hintergrund</string>\n    <string name=\"layers_on_background_sub\">Das selbe wie bei der ersten Option, aber mit Farbe statt Bild</string>\n    <string name=\"area\">Bereich</string>\n    <string name=\"area_sub\">Resampling unter Verwendung des Pixelflächenverhältnisses. Diese Methode kann bei der Bilddezimierung bevorzugt werden, da sie moirefreie Ergebnisse liefert. Wenn das Bild jedoch gezoomt wird, ähnelt sie der „Nähesten“-Methode.</string>\n    <string name=\"enable_tonemapping\">Tonemapping einschalten</string>\n    <string name=\"fast_settings_side\">Schnelleinstellungen Seite</string>\n    <string name=\"fast_settings_side_sub\">Hinzufügen eines schwebenden Streifens an der ausgewählten Seite während der Bildbearbeitung, der beim Anklicken die Schnelleinstellungen öffnet</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"clear_selection\">Auswahl löschen</string>\n    <string name=\"base_64_tools\">Base64 Tools</string>\n    <string name=\"base_64_tools_sub\">Base64-String in Bild dekodieren, oder Bild in Base64-Format kodieren</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">Bereitgestellter Wert ist keine gültige Base64-Zeichenkette</string>\n    <string name=\"copy_not_a_valid_base_64\">Leere oder ungültige Base64-Zeichenfolge kann nicht kopiert werden</string>\n    <string name=\"paste_base_64\">Base64 einfügen</string>\n    <string name=\"copy_base_64\">Base64 kopieren</string>\n    <string name=\"save_base_64\">Base64 speichern</string>\n    <string name=\"share_base_64\">Base64 teilen</string>\n    <string name=\"options\">Optionen</string>\n    <string name=\"actions\">Aktionen</string>\n    <string name=\"import_base_64\">Base64 importieren</string>\n    <string name=\"settings_group_visibility_hidden\">Einstellungsgruppe \\\"%1$s\\\" wird standardmäßig eingeklappt</string>\n    <string name=\"settings_group_visibility_visible\">Einstellungsgruppe \\\"%1$s\\\" wird standardmäßig erweitert</string>\n    <string name=\"base_64_tips\">Bild laden, um Base64-Zeichenfolge zu kopieren oder zu speichern. Wenn du die Zeichenfolge selbst hast, kannst du sie oben einfügen, um das Bild zu erhalten</string>\n    <string name=\"base_64_actions\">Base64 Aktionen</string>\n    <string name=\"add_outline_sub\">Hinzufügen eines Umrisses um den Text mit bestimmter Farbe und Breite</string>\n    <string name=\"outline_color\">Umrissfarbe</string>\n    <string name=\"add_outline\">Umriss hinzufügen</string>\n    <string name=\"outline_size\">Umrissgröße</string>\n    <string name=\"checksum\">Prüfsumme</string>\n    <string name=\"match\">Übereinstimmung!</string>\n    <string name=\"match_sub\">Prüfsummen sind gleich, es kann sicher sein</string>\n    <string name=\"checksum_as_filename_sub\">Die Namen der ausgegebenen Bilder entsprechen den Prüfsummen der Daten</string>\n    <string name=\"checksum_tools_sub\">Prüfsummen vergleichen, Hashwerte berechnen, oder Hex Zeichenketten aus Dateien mit verschiedenen Hash-Algorithmen erstellen</string>\n    <string name=\"calculate\">Berechnen</string>\n    <string name=\"checksum_to_compare\">Prüfsumme zum Vergleichen</string>\n    <string name=\"difference\">Unterschied</string>\n    <string name=\"difference_sub\">Prüfsummen sind nicht gleich, Datei kann unsicher sein!</string>\n    <string name=\"algorithms\">Algorithmus</string>\n    <string name=\"checksum_tools\">Prüfsummen Tools</string>\n    <string name=\"checksum_as_filename\">Prüfsumme als Dateiname</string>\n    <string name=\"rotation\">Drehung</string>\n    <string name=\"free_software_partner\">Freie Software (Partner)</string>\n    <string name=\"free_software_partner_sub\">Mehr nützliche Software im Partnerkanal der Android-Anwendungen</string>\n    <string name=\"text_hash\">Text Hash</string>\n    <string name=\"source_checksum\">Quelle Prüfsumme</string>\n    <string name=\"mesh_gradients\">Meshverläufe</string>\n    <string name=\"enter_text_to_checksum\">Text eingeben, um seine Prüfsumme des gewählten Algorithmus zu berechnen</string>\n    <string name=\"pick_file_to_checksum\">Wählen die Datei aus, um ihre Prüfsumme des gewählten Algorithmus zu berechnen</string>\n    <string name=\"collection_mesh_gradients_sub\">Online-Sammlung von Meshverläufen ansehen</string>\n    <string name=\"imported_fonts\">Importierte Schriftarten</string>\n    <string name=\"export_fonts\">Schriftarten exportieren</string>\n    <string name=\"wrong_font\">Nur TTF und OTF Schriften können importiert werden</string>\n    <string name=\"import_font\">Schriftart importieren (TTF/OTF)</string>\n    <string name=\"custom_pages\">Benutzerdefinierte Seiten</string>\n    <string name=\"tool_exit_confirmation_sub\">Wenn du bei der Verwendung bestimmter Tools nicht gespeicherte Änderungen vorgenommen hast und versuchst, sie zu schließen, wird ein Bestätigungsdialog angezeigt</string>\n    <string name=\"tool_exit_confirmation\">Bestätigung der Beendigung des Tools</string>\n    <string name=\"none\">Keine</string>\n    <string name=\"error_while_saving\">Fehler beim Speichern, versuche den Ausgabeordner zu ändern</string>\n    <string name=\"filename_is_not_set\">Dateiname ist nicht festgelegt</string>\n    <string name=\"pages_selection\">Seitenauswahl</string>\n    <string name=\"edit_exif_screen\">EXIF bearbeiten</string>\n    <string name=\"batch_compare\">Stapelvergleich</string>\n    <string name=\"pick_files_to_checksum\">Wähle Datei(en) aus, deren Prüfsumme auf der Grundlage des gewählten Algorithmus berechnet werden soll</string>\n    <string name=\"pick_directory\">Verzeichnis auswählen</string>\n    <string name=\"edit_exif_screen_sub\">Metadaten eines einzelnen Bildes ohne erneute Komprimierung ändern</string>\n    <string name=\"edit_exif_tag\">Tippen, um die verfügbaren Tags zu bearbeiten</string>\n    <string name=\"change_sticker\">Sticker ändern</string>\n    <string name=\"fit_width\">Breite anpassen</string>\n    <string name=\"fit_height\">Höhe anpassen</string>\n    <string name=\"pick_files\">Dateien auswählen</string>\n    <string name=\"head_length_scale\">Kopf Länge Skala</string>\n    <string name=\"padding\">Polsterung</string>\n    <string name=\"horizontal_pivot_line\">Horizontale Pivotlinie</string>\n    <string name=\"inverse_selection\">Umgekehrte Auswahl</string>\n    <string name=\"inverse_horizontal_selection_sub\">Horizontal geschnittene Teile werden ausgelassen, anstatt die Teile um den Schnittbereich herum zusammenzuführen.</string>\n    <string name=\"mesh_gradients_sub\">Erstellen eines Maschenverlaufs mit benutzerdefinierter Anzahl von Knoten und Auflösung</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Zusammensetzen des Maschenverlaufs des oberen Teils der gegebenen Bilder</string>\n    <string name=\"resolution_x\">Auflösung X</string>\n    <string name=\"resolution_y\">Auflösung Y</string>\n    <string name=\"resolution\">Auflösung</string>\n    <string name=\"gradient_maker_type_image_mesh\">Maschenverlaufsüberlagerung</string>\n    <string name=\"points_customization\">Punkteanpassung</string>\n    <string name=\"timestamp\">Zeitstempel</string>\n    <string name=\"inverse_vertical_selection_sub\">Vertikaler Schnittteil wird ausgelassen, anstatt Teile um den Schnittbereich herum zusammenzuführen</string>\n    <string name=\"grid_size\">Rastergröße</string>\n    <string name=\"stamp\">Stempel</string>\n    <string name=\"format_pattern\">Formatmuster</string>\n    <string name=\"image_cutting\">Bild schneiden</string>\n    <string name=\"collection_mesh_gradients\">Sammlung von Maschenverläufen</string>\n    <string name=\"image_cutting_sub\">Schneide einen Teil des Bildes aus und füge den linken Teil (kann auch umgekehrt sein) mit vertikalen oder horizontalen Linien zusammen</string>\n    <string name=\"vertical_pivot_line\">Vertikale Pivotlinie</string>\n    <string name=\"pixel_by_pixel\">Pixel für Pixel</string>\n    <string name=\"highlight_color\">Hervorhebungsfarbe</string>\n    <string name=\"pixel_comparison_type\">Pixel-Vergleichstyp</string>\n    <string name=\"ocr_write_to_file\">In Datei schreiben</string>\n    <string name=\"scan_barcode\">Barcode scannen</string>\n    <string name=\"height_ratio\">Höhenverhältnis</string>\n    <string name=\"barcode_type\">Barcode-Typ</string>\n    <string name=\"enforce_bw\">Erzwinge Schwarz/Weiß</string>\n    <string name=\"enforce_bw_sub\">Barcode-Bild wird vollständig schwarz-weiß und nicht durch das App-Thema eingefärbt</string>\n    <string name=\"barcodes_sub\">Jeden Barcode (QR, EAN, AZTEC, …) scannen und seinen Inhalt abrufen oder Ihren Text einfügen, um einen neuen zu erstellen</string>\n    <string name=\"no_barcode_found\">Kein Barcode gefunden</string>\n    <string name=\"generated_barcode_will_be_here\">Generierter Barcode wird hier sein</string>\n    <string name=\"right_to_left\">Rechts nach links</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME Typ (umgekehrt)</string>\n    <string name=\"audio_cover_extractor_sub\">Extrahiere Albumcoverbilder aus Audiodateien, die meisten gängigen Formate werden unterstützt</string>\n    <string name=\"audio_cover_extractor\">Audio Covers</string>\n    <string name=\"pick_audio_to_start\">Audio zum Starten auswählen</string>\n    <string name=\"pick_audio\">Audio auswählen</string>\n    <string name=\"no_covers_found\">Keine Cover gefunden</string>\n    <string name=\"send_logs\">Protokolle senden</string>\n    <string name=\"crash_subtitle\">Du kannst mich über die unten stehenden Optionen kontaktieren und ich werde versuchen, eine Lösung zu finden.\\n(Vergiss nicht, Protokolle anzuhängen)</string>\n    <string name=\"ocr_write_to_file_sub\">Text aus einem Stapel von Bildern extrahieren und in einer Textdatei speichern</string>\n    <string name=\"ocr_write_to_metadata\">In Metadaten schreiben</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extrahiere Text aus jedem Bild und füge ihn in die EXIF Informationen der entsprechenden Fotos ein</string>\n    <string name=\"use_lsb\">LSB benutzen</string>\n    <string name=\"use_lsb_sub\">Die LSB (Less Significant Bit) Steganographie Methode wird verwendet, ansonsten FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Rote Augen automatisch entfernen</string>\n    <string name=\"password\">Passwort</string>\n    <string name=\"unlock\">Entsperren</string>\n    <string name=\"pdf_is_protected\">PDF ist geschützt</string>\n    <string name=\"operation_almost_complete\">Vorgang fast abgeschlossen. Wenn jetzt abgebrochen wird, muss neugestartet werden</string>\n    <string name=\"sort_by_date_modified_reversed\">Datum geändert (umgekehrt)</string>\n    <string name=\"sort_by_mime_type\">MIME Typ</string>\n    <string name=\"sort_by_extension\">Erweiterung</string>\n    <string name=\"sort_by_extension_reversed\">Erweiterung (umgekehrt)</string>\n    <string name=\"sort_by_date_added\">Datum hinzugefügt</string>\n    <string name=\"sort_by_date_added_reversed\">Datum hinzugefügt (umgekehrt)</string>\n    <string name=\"left_to_right\">Links nach rechts</string>\n    <string name=\"top_to_bottom\">Oben nach unten</string>\n    <string name=\"invisible_mode\">Unsichtbarer Modus</string>\n    <string name=\"sort_by_date_modified\">Datum geändert</string>\n    <string name=\"crash_title\">Ups… da ist etwas schief gelaufen</string>\n    <string name=\"bottom_to_top\">Unten nach oben</string>\n    <string name=\"send_logs_sub\">Klicken, um die Protokolldatei der App zu teilen. Dies kann mir helfen, das Problem zu erkennen und zu beheben.</string>\n    <string name=\"invisible_mode_sub\">Verwende Steganografie, um unsichtbare Wasserzeichen in Bytes deiner Bilder zu erstellen</string>\n    <string name=\"sort_by_size_reversed\">Größe (umgekehrt)</string>\n    <string name=\"sort_by_size\">Größe</string>\n    <string name=\"liquid_glass\">Flüssiges Glas</string>\n    <string name=\"liquid_glass_sub\">Ein Schalter, der auf dem kürzlich angekündigten IOS 26 und seinem Flüssigglas-Designsystem basiert</string>\n    <string name=\"paste_link\">Link einfügen</string>\n    <string name=\"pick_image_or_base64\">Bild auswählen oder Base64-Daten einfügen/importieren</string>\n    <string name=\"type_image_link\">Bildlink zum Starten eingeben</string>\n    <string name=\"kaleidoscope\">Kaleidoskop</string>\n    <string name=\"secondary_angle\">Sekundärer Winkel</string>\n    <string name=\"sides\">Seiten</string>\n    <string name=\"channel_mix\">Kanal Mix</string>\n    <string name=\"blue_green\">Blau grün</string>\n    <string name=\"red_blue\">Rot blau</string>\n    <string name=\"green_red\">Grün rot</string>\n    <string name=\"into_red\">Ins Rote</string>\n    <string name=\"into_green\">Ins Grüne</string>\n    <string name=\"into_blue\">Ins Blaue</string>\n    <string name=\"cyan\">Türkis</string>\n    <string name=\"magenta\">Purpurrot</string>\n    <string name=\"yellow\">Gelb</string>\n    <string name=\"color_halftone\">Farbe Halbton</string>\n    <string name=\"contour\">Kontur</string>\n    <string name=\"levels\">Ebenen</string>\n    <string name=\"offset\">Versetzt</string>\n    <string name=\"voronoi_crystallize\">Voronoi kristallisieren</string>\n    <string name=\"shape\">Form</string>\n    <string name=\"stretch\">Dehnen</string>\n    <string name=\"randomness\">Zufälligkeit</string>\n    <string name=\"despeckle\">Despeckle</string>\n    <string name=\"diffuse\">Diffus</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Zweiter Radius</string>\n    <string name=\"equalize\">Ausgleichen</string>\n    <string name=\"glow\">Glühen</string>\n    <string name=\"whirl_and_pinch\">Wirbeln und Zwicken</string>\n    <string name=\"pointillize\">Punktuell</string>\n    <string name=\"border_color\">Randfarbe</string>\n    <string name=\"polar_coordinates\">Polarkoordinaten</string>\n    <string name=\"rect_to_polar\">Rechteckig zu polar</string>\n    <string name=\"polar_to_rect\">Polar zu rechteckig</string>\n    <string name=\"invert_in_circle\">Im Kreis umkehren</string>\n    <string name=\"reduce_noise\">Geräuschreduzierung</string>\n    <string name=\"simple_solarize\">Einfaches Solarisieren</string>\n    <string name=\"weave\">Weben</string>\n    <string name=\"x_gap\">X Lücke</string>\n    <string name=\"y_gap\">Y Lücke</string>\n    <string name=\"x_width\">X Breite</string>\n    <string name=\"y_wdth\">Y Breite</string>\n    <string name=\"twirl\">Wirbeln</string>\n    <string name=\"rubber_stmp\">Gummistempel</string>\n    <string name=\"smear\">Verschmieren</string>\n    <string name=\"density\">Dichte</string>\n    <string name=\"mix\">Mix</string>\n    <string name=\"sphere_lensh_distortion\">Kugel Objektiv Verzerrung</string>\n    <string name=\"refraction_index\">Lichtbrechungsindex</string>\n    <string name=\"arc\">Bogen</string>\n    <string name=\"spread_angle\">Verschmierungswinkel</string>\n    <string name=\"sparkle\">Glitzern</string>\n    <string name=\"rays\">Strahlen</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Farbverlauf</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"moire\">Moire</string>\n    <string name=\"autumn\">Herbst</string>\n    <string name=\"bone\">Knochen</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Winter</string>\n    <string name=\"ocean\">Ozean</string>\n    <string name=\"summer\">Sommer</string>\n    <string name=\"spring\">Frühling</string>\n    <string name=\"cool_variant\">Coole Variante</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Pink</string>\n    <string name=\"hot\">Heiß</string>\n    <string name=\"parula\">Parula</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Cividis</string>\n    <string name=\"twilight\">Dämmerung</string>\n    <string name=\"twilight_shifted\">Verschobene Dämmerung</string>\n    <string name=\"auto_perspective\">Auto Perspektive</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Zuschnitt zulassen</string>\n    <string name=\"crop_or_perspective\">Zuschnitt oder Perspektive</string>\n    <string name=\"absolute\">Absolut</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Tiefgrün</string>\n    <string name=\"lens_correction\">Linsenkorrektur</string>\n    <string name=\"target_lens_profile\">Ziellinsenprofildatei im JSON-Format</string>\n    <string name=\"download_ready_lens_profiles\">fertige Objektivprofile herunterladen</string>\n    <string name=\"part_percents\">Teilprozent</string>\n    <string name=\"disable_rotation\">Drehen deaktivieren</string>\n    <string name=\"disable_rotation_sub\">Verhindert das Drehen von Bildern mit Zwei-Finger-Gesten</string>\n    <string name=\"enable_snapping_to_borders\">Einrasten an Kanten aktivieren</string>\n    <string name=\"enable_snapping_to_borders_sub\">Nach dem Verschieben oder Zoomen werden Bilder so eingerastet, dass sie die Rahmenkanten ausfüllen</string>\n    <string name=\"export_as_json\">Als JSON exportieren</string>\n    <string name=\"export_as_json_sub\">Zeichenfolge mit Palettendaten als JSON-Darstellung kopieren</string>\n    <string name=\"wallpapers_export\">Hintergrundbilder Export</string>\n    <string name=\"refresh\">Aktualisieren</string>\n    <string name=\"wallpapers_export_sub\">Rufe die aktuellen Hintergrundbilder für Start, Sperr und Built-in ab</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Zugriff auf alle Dateien zulassen, dies wird zum Abrufen von Hintergrundbildern benötigt</string>\n    <string name=\"allow_read_media_images_for_wp\">Die Verwaltung externer Speicherberechtigungen reicht nicht aus. Du musst den Zugriff auf deine Bilder zulassen. Wähle unbedingt „Alle zulassen“ aus</string>\n    <string name=\"seam_carving\">Nahtschnitzen</string>\n    <string name=\"home_screen\">Startbildschirm</string>\n    <string name=\"lock_screen\">Sperrbildschirm</string>\n    <string name=\"built_in\">Eingebaut</string>\n    <string name=\"add_preset_to_filename\">Voreinstellung zum Dateinamen hinzufügen</string>\n    <string name=\"add_preset_to_filename_sub\">Hängt Suffix mit ausgewählter Voreinstellung an den Bilddateinamen an</string>\n    <string name=\"add_image_scale_mode_to_filename\">Bildskalierungsmodus zum Dateinamen hinzufügen</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Hängt Suffix mit ausgewähltem Bildskalierungsmodus an den Bilddateinamen an</string>\n    <string name=\"ascii_art\">Ascii Kunst</string>\n    <string name=\"ascii_art_sub\">Konvertiere das Bild in ASCII-Text, der wie ein Bild aussieht</string>\n    <string name=\"invert_colors_ascii_sub\">Wendet in einigen Fällen einen negativen Filter auf das Bild an, um ein besseres Ergebnis zu erzielen</string>\n    <string name=\"params\">Parameter</string>\n    <string name=\"processing_screenshot\">Verarbeite Screenshot</string>\n    <string name=\"screenshot_not_captured_try_again\">Screenshot wurde nicht erfasst, erneut versuchen</string>\n    <string name=\"skipped_saving\">Speichern übersprungen</string>\n    <string name=\"skipped_saving_multiple\">%1$s Dateien übersprungen</string>\n    <string name=\"allow_skip_if_larger\">Überspringen zulassen, wenn größer</string>\n    <string name=\"allow_skip_if_larger_sub\">Einige Tools erlauben es, das Speichern von Bildern zu überspringen, wenn die resultierende Dateigröße größer als das Original wäre.</string>\n    <string name=\"qr_type_calendar_event\">Kalenderevent</string>\n    <string name=\"qr_type_contact_info\">Kontakt</string>\n    <string name=\"qr_type_email\">Email</string>\n    <string name=\"qr_type_geo_point\">Standort</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">WLAN</string>\n    <string name=\"open_network\">Offenes Netzwerk</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Nachricht</string>\n    <string name=\"address\">Adresse</string>\n    <string name=\"subject\">Thema</string>\n    <string name=\"body\">Körper</string>\n    <string name=\"name\">Name</string>\n    <string name=\"organization\">Organisation</string>\n    <string name=\"title\">Titel</string>\n    <string name=\"phones\">Telefone</string>\n    <string name=\"emails\">Emails</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">Adressen</string>\n    <string name=\"summary\">Zusammenfassung</string>\n    <string name=\"description\">Beschreibung</string>\n    <string name=\"location\">Standort</string>\n    <string name=\"organizer\">Organisierer</string>\n    <string name=\"start_date\">Startdatum</string>\n    <string name=\"end_date\">Enddatum</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Breitengrad</string>\n    <string name=\"longitude\">Längengrad</string>\n    <string name=\"create_barcode\">Barcode erstellen</string>\n    <string name=\"edit_barcode\">Barcode bearbeiten</string>\n    <string name=\"wifi_configuration\">WLAN Konfiguration</string>\n    <string name=\"security\">Sicherheit</string>\n    <string name=\"pick_contact\">Kontakt auswählen</string>\n    <string name=\"grant_contact_permission\">Kontakte Berechtigung in den Einstellungn erteilen, um mit ausgewählten Kontakt automatisch Auszufüllen.</string>\n    <string name=\"middle_name\">zweiter Vorname</string>\n    <string name=\"last_name\">Nachname</string>\n    <string name=\"pronunciation\">Betonung</string>\n    <string name=\"add_phone\">Telefon hinzufügen</string>\n    <string name=\"add_email\">Email hinzufügen</string>\n    <string name=\"add_address\">Adresse hinzufügen</string>\n    <string name=\"website\">Webseite</string>\n    <string name=\"add_website\">Webseite hinzufügen</string>\n    <string name=\"formatted_name\">Formatierter Name</string>\n    <string name=\"contact_info\">Kontaktinformationen</string>\n    <string name=\"first_name\">Vorname</string>\n    <string name=\"qr_code_top_image\">Dieses Bild wird über dem Barcode platziert.</string>\n    <string name=\"code_customization\">Code-Anpassung</string>\n    <string name=\"qr_logo_image\">Dieses Bild wird als Logo in der Mitte des QR-Codes verwendet</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo-Ausgleich</string>\n    <string name=\"logo_size\">Logo-Größe</string>\n    <string name=\"logo_corners\">Logo-Ecken</string>\n    <string name=\"fourth_eye\">Viertes Auge</string>\n    <string name=\"fourth_eye_description\">Fügt dem QR-Code Augensymmetrie hinzu, indem ein viertes Auge an der unteren Ecke hinzugefügt wird.</string>\n    <string name=\"pixel_shape\">Pixelform</string>\n    <string name=\"snowfall_mode\">Schneefallmodus</string>\n    <string name=\"enabled\">Aktiviert</string>\n    <string name=\"border_frame\">Rahmen</string>\n    <string name=\"frame_shape\">Rahmenform</string>\n    <string name=\"ball_shape\">Kugelform</string>\n    <string name=\"error_correction_level\">Fehlerkorrekturstufe</string>\n    <string name=\"dark_color\">Dunkle Farbe</string>\n    <string name=\"light_color\">Helle Farbe</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Im Stil von Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Maskenmuster</string>\n    <string name=\"code_may_be_not_scannable\">Dieser Code ist möglicherweise nicht scanbar. Ändern Sie die Darstellungsparameter, damit er mit allen Geräten lesbar ist.</string>\n    <string name=\"not_scannable\">Nicht scanbar</string>\n    <string name=\"launcher_mode_sub\">Die Tools werden wie der App-Launcher auf dem Startbildschirm aussehen, um kompakter zu sein.</string>\n    <string name=\"launcher_mode\">Launcher Modus</string>\n    <string name=\"flood_fill_sub\">Füllt einen Bereich mit ausgewähltem Pinsel und Stil</string>\n    <string name=\"overlap_size\">Überlappungsgröße</string>\n    <string name=\"model_antialias\">Kantenglättung</string>\n    <string name=\"model_bandage\">Farbstreifenbildung</string>\n    <string name=\"model_deedge\">Kantenentfernung</string>\n    <string name=\"model_gainres\">Kantenglättung, allgemeine Artefakte, CGI</string>\n    <string name=\"model_bcgone_detailed_v2\">Entfernung von Kompressionsartefakten</string>\n    <string name=\"model_bcgone_smooth\">Entfernung von Kompressionsartefakten</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG-Artefaktentfernung V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264-Texturverbesserung</string>\n    <string name=\"model_vhs_sharpen\">VHS-Schärfung und -Verbesserung</string>\n    <string name=\"merging\">Zusammenführung</string>\n    <string name=\"flood_fill\">Hochwasserfüllung</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Zeichnet einen Pfad im Graffiti-Stil</string>\n    <string name=\"square_particles\">Quadratische Teilchen</string>\n    <string name=\"square_particles_sub\">Die Sprühpartikel haben eine quadratische statt kreisförmige Form</string>\n    <string name=\"palette_tools\">Palettenwerkzeuge</string>\n    <string name=\"palette_tools_sub\">Generieren Sie Basismaterial/Palettenmaterial aus einem Bild oder importieren/exportieren Sie es über verschiedene Palettenformate hinweg</string>\n    <string name=\"edit_palette\">Palette bearbeiten</string>\n    <string name=\"edit_palette_sub\">Export-/Importpalette für verschiedene Formate</string>\n    <string name=\"color_name\">Farbname</string>\n    <string name=\"palette_name\">Palettenname</string>\n    <string name=\"palette_format\">Palettenformat</string>\n    <string name=\"export_palette_sub\">Exportieren Sie die generierte Palette in verschiedene Formate</string>\n    <string name=\"add_color_palette_sub\">Fügt der aktuellen Palette eine neue Farbe hinzu</string>\n    <string name=\"palette_name_not_supported\">Das Format %1$s unterstützt die Angabe des Palettennamens nicht</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Aufgrund der Play Store-Richtlinien kann diese Funktion nicht in den aktuellen Build aufgenommen werden. Um auf diese Funktionalität zuzugreifen, laden Sie ImageToolbox bitte von einer alternativen Quelle herunter. Die verfügbaren Builds finden Sie unten auf GitHub.</string>\n    <string name=\"open_github_page\">Öffnen Sie die Github-Seite</string>\n    <string name=\"overwrite_files_sub_short\">Die Originaldatei wird durch eine neue ersetzt, anstatt sie im ausgewählten Ordner zu speichern</string>\n    <string name=\"hidden_watermark_text_detected\">Versteckter Wasserzeichentext erkannt</string>\n    <string name=\"hidden_watermark_image_detected\">Verstecktes Wasserzeichenbild erkannt</string>\n    <string name=\"this_image_was_hidden\">Dieses Bild wurde ausgeblendet</string>\n    <string name=\"generative_inpaint\">Generatives Inpainting</string>\n    <string name=\"generative_inpaint_sub\">Ermöglicht das Entfernen von Objekten in einem Bild mithilfe eines KI-Modells, ohne auf OpenCV angewiesen zu sein. Um diese Funktion zu nutzen, lädt die App das erforderliche Modell (~200 MB) von GitHub herunter</string>\n    <string name=\"generative_inpaint_ready_sub\">Ermöglicht das Entfernen von Objekten in einem Bild mithilfe eines KI-Modells, ohne auf OpenCV angewiesen zu sein. Dies könnte ein langwieriger Vorgang sein</string>\n    <string name=\"error_level_analysis\">Fehlerebenenanalyse</string>\n    <string name=\"luminance_gradient\">Luminanzgradient</string>\n    <string name=\"average_distance\">Durchschnittliche Entfernung</string>\n    <string name=\"copy_move_detection\">Kopierbewegungserkennung</string>\n    <string name=\"retain\">Zurückbehalten</string>\n    <string name=\"coefficent\">Koeffizient</string>\n    <string name=\"clipboard_data_is_too_large\">Die Daten in der Zwischenablage sind zu groß</string>\n    <string name=\"data_is_too_large_to_copy\">Die Daten sind zu groß zum Kopieren</string>\n    <string name=\"simple_weave_pixelization\">Einfache Webpixelisierung</string>\n    <string name=\"staggered_pixelization\">Gestaffelte Pixelisierung</string>\n    <string name=\"cross_pixelization\">Kreuzpixelisierung</string>\n    <string name=\"micro_macro_pixelization\">Mikro-Makro-Pixelisierung</string>\n    <string name=\"orbital_pixelization\">Orbitale Pixelisierung</string>\n    <string name=\"vortex_pixelization\">Vortex-Pixelisierung</string>\n    <string name=\"pulse_grid_pixelization\">Pulsgitterpixelisierung</string>\n    <string name=\"nucleus_pixelization\">Kernpixelisierung</string>\n    <string name=\"radial_weave_pixelization\">Radiale Webpixelisierung</string>\n    <string name=\"cannot_open_uri\">URI „%1$s“ kann nicht geöffnet werden</string>\n    <string name=\"glitch_variant\">Glitch-Variante</string>\n    <string name=\"channel_shift\">Kanalverschiebung</string>\n    <string name=\"max_offset\">Maximaler Versatz</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Glitch blockieren</string>\n    <string name=\"block_size\">Blockgröße</string>\n    <string name=\"crt_curvature\">CRT-Krümmung</string>\n    <string name=\"curvature\">Krümmung</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixelschmelze</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">KI-Tools</string>\n    <string name=\"ai_tools_sub\">Verschiedene Tools zur Verarbeitung von Bildern durch KI-Modelle wie Artefaktentfernung oder Rauschunterdrückung</string>\n    <string name=\"model_anime_undeint\">Komprimierung, gezackte Linien</string>\n    <string name=\"model_broadcast\">Cartoons, Broadcast-Komprimierung</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Allgemeine Komprimierung, allgemeines Rauschen</string>\n    <string name=\"model_wb_denoise\">Farbloses Cartoon-Geräusch</string>\n    <string name=\"model_span_anime_pretrain\">Schnell, allgemeine Komprimierung, allgemeines Rauschen, Animation/Comics/Anime</string>\n    <string name=\"model_book_scan\">Scannen von Büchern</string>\n    <string name=\"model_overexposure\">Belichtungskorrektur</string>\n    <string name=\"model_fbcnn_color_fp16\">Am besten bei allgemeiner Komprimierung und Farbbildern</string>\n    <string name=\"model_fbcnn_gray_fp16\">Am besten bei allgemeiner Komprimierung und Graustufenbildern</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Allgemeine Komprimierung, Graustufenbilder, stärker</string>\n    <string name=\"model_scunet_color_gan_fp16\">Allgemeines Rauschen, Farbbilder</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Allgemeines Rauschen, Farbbilder, bessere Details</string>\n    <string name=\"model_scunet_gray_15_fp16\">Allgemeines Rauschen, Graustufenbilder</string>\n    <string name=\"model_scunet_gray_25_fp16\">Allgemeines Rauschen, Graustufenbilder, stärker</string>\n    <string name=\"model_scunet_gray_50_fp16\">Allgemeines Rauschen, Graustufenbilder, am stärksten</string>\n    <string name=\"model_jpeg_destroyer\">Allgemeine Komprimierung</string>\n    <string name=\"model_jaywreck\">Allgemeine Komprimierung</string>\n    <string name=\"model_h264\">Texturierung, h264-Komprimierung</string>\n    <string name=\"model_vhs\">VHS-Komprimierung</string>\n    <string name=\"model_cinepak\">Nicht standardmäßige Komprimierung (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink-Komprimierung, bessere Geometrie</string>\n    <string name=\"model_debink_v5\">Bink-Kompression, stärker</string>\n    <string name=\"model_debink_v6\">Bink-Kompression, weich, behält Details bei</string>\n    <string name=\"model_kdm_scans\">Gescannte Kunstwerke/Zeichnungen, leichte Komprimierung, Moiré</string>\n    <string name=\"model_halftone\">Langsam, Halbtöne entfernen</string>\n    <string name=\"model_colorizer\">Allgemeiner Kolorierer für Graustufen-/Schwarzweißbilder. Für bessere Ergebnisse verwenden Sie DDColor</string>\n    <string name=\"model_desharpen\">Entfernt Überschärfung</string>\n    <string name=\"model_dither\">Langsam, zögerlich</string>\n    <string name=\"model_kdm003_scans\">KDM003 scannt die Verarbeitung</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Leichtes Bildverbesserungsmodell</string>\n    <string name=\"model_bandage_smooth\">Verbandentfernung mit reibungslosem Ergebnis</string>\n    <string name=\"model_bendel_halftone\">Verarbeitung von Halbtonmustern</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Entfernung von Dither-Mustern V3</string>\n    <string name=\"chunk_size\">Stückgröße</string>\n    <string name=\"note_chunk_info\">Bilder über %1$s px werden in Stücke geschnitten und verarbeitet. Durch Überlappung werden diese zusammengefügt, um sichtbare Nähte zu vermeiden.</string>\n    <string name=\"large_chunk_warning\">Große Größen können bei Low-End-Geräten zu Instabilität führen</string>\n    <string name=\"select_one_to_start\">Wählen Sie eine aus, um zu beginnen</string>\n    <string name=\"delete_model_sub\">Möchten Sie das Modell %1$s löschen? Sie müssen es erneut herunterladen</string>\n    <string name=\"confirm\">Bestätigen</string>\n    <string name=\"models\">Modelle</string>\n    <string name=\"downloaded_models\">Heruntergeladene Modelle</string>\n    <string name=\"available_models\">Verfügbare Modelle</string>\n    <string name=\"preparing\">Vorbereiten</string>\n    <string name=\"active_model\">Aktives Modell</string>\n    <string name=\"failed_to_open_session\">Sitzung konnte nicht geöffnet werden</string>\n    <string name=\"only_onnx_models\">Es können nur .onnx/.ort-Modelle importiert werden</string>\n    <string name=\"import_model\">Modell importieren</string>\n    <string name=\"import_model_sub\">Importieren Sie ein benutzerdefiniertes ONNX-Modell zur weiteren Verwendung. Es werden nur ONNX-/Ort-Modelle akzeptiert. Unterstützt fast alle Esrgan-ähnlichen Varianten</string>\n    <string name=\"imported_models\">Importierte Modelle</string>\n    <string name=\"model_scunet_color_15_fp16\">Allgemeines Rauschen, farbige Bilder</string>\n    <string name=\"model_scunet_color_25_fp16\">Allgemeines Rauschen, farbige Bilder, stärker</string>\n    <string name=\"model_scunet_color_50_fp16\">Allgemeines Rauschen, farbige Bilder, am stärksten</string>\n    <string name=\"model_artifacts_dithering_alsa\">Reduziert Dithering-Artefakte und Farbstreifen und verbessert so sanfte Farbverläufe und flache Farbbereiche.</string>\n    <string name=\"model_nmkd_brighten_redux\">Verbessert die Bildhelligkeit und den Kontrast mit ausgewogenen Glanzlichtern und behält gleichzeitig natürliche Farben bei.</string>\n    <string name=\"model_nmkd_brighten\">Hellt dunkle Bilder auf, behält dabei aber Details bei und vermeidet Überbelichtung.</string>\n    <string name=\"model_nmkd_detoon\">Entfernt übermäßige Farbtöne und stellt eine neutralere und natürlichere Farbbalance wieder her.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Wendet eine Poisson-basierte Rauschtönung an, wobei der Schwerpunkt auf der Erhaltung feiner Details und Texturen liegt.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Wendet eine sanfte Poisson-Rauschen-Tönung an, um weichere und weniger aggressive visuelle Ergebnisse zu erzielen.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Die gleichmäßige Rauschtönung konzentrierte sich auf die Erhaltung von Details und Bildklarheit.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Sanfte, gleichmäßige Rauschtönung für eine subtile Textur und ein glattes Erscheinungsbild.</string>\n    <string name=\"model_repainter\">Repariert beschädigte oder unebene Bereiche durch Neulackierung von Artefakten und verbessert die Bildkonsistenz.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Leichtes Debanding-Modell, das Farbstreifen mit minimalen Leistungseinbußen entfernt.</string>\n    <string name=\"model_jpeg_0_20\">Optimiert Bilder mit sehr hohen Komprimierungsartefakten (0–20 % Qualität) für verbesserte Klarheit.</string>\n    <string name=\"model_jpeg_20_40\">Verbessert Bilder mit hohen Komprimierungsartefakten (20–40 % Qualität), stellt Details wieder her und reduziert Rauschen.</string>\n    <string name=\"model_jpeg_40_60\">Verbessert Bilder mit mäßiger Komprimierung (40-60 % Qualität) und gleicht Schärfe und Glätte aus.</string>\n    <string name=\"model_jpeg_60_80\">Verfeinert Bilder mit leichter Komprimierung (60–80 % Qualität), um subtile Details und Texturen hervorzuheben.</string>\n    <string name=\"model_jpeg_80_100\">Verbessert nahezu verlustfreie Bilder leicht (80–100 % Qualität) und behält gleichzeitig das natürliche Aussehen und die Details bei.</string>\n    <string name=\"model_spongecolor_lite\">Einfache und schnelle Kolorierung, Cartoons, nicht ideal</string>\n    <string name=\"model_deblr\">Reduziert die Bildunschärfe leicht und verbessert die Schärfe, ohne dass Artefakte entstehen.</string>\n    <string name=\"processing_channel\">Lang andauernde Vorgänge</string>\n    <string name=\"processing_image\">Bild wird verarbeitet</string>\n    <string name=\"processing\">Verarbeitung</string>\n    <string name=\"model_artifacts_jpg_0_20\">Entfernt starke JPEG-Komprimierungsartefakte in Bildern mit sehr geringer Qualität (0–20 %).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Reduziert starke JPEG-Artefakte in stark komprimierten Bildern (20–40 %).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Bereinigt mäßige JPEG-Artefakte unter Beibehaltung der Bilddetails (40–60 %).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Verfeinert leichte JPEG-Artefakte in Bildern mit relativ hoher Qualität (60–80 %).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Reduziert geringfügige JPEG-Artefakte in nahezu verlustfreien Bildern (80–100 %).</string>\n    <string name=\"model_redetail_v2\">Verstärkt feine Details und Texturen und verbessert die wahrgenommene Schärfe ohne starke Artefakte.</string>\n    <string name=\"processing_finished\">Verarbeitung abgeschlossen</string>\n    <string name=\"processing_failed\">Die Verarbeitung ist fehlgeschlagen</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Verbessert Hauttexturen und -details und behält gleichzeitig ein natürliches Aussehen bei, optimiert für Geschwindigkeit.</string>\n    <string name=\"model_sbdv_dejpeg\">Entfernt JPEG-Komprimierungsartefakte und stellt die Bildqualität für komprimierte Fotos wieder her.</string>\n    <string name=\"model_iso_denoise_v1\">Reduziert das ISO-Rauschen bei Fotos, die bei schlechten Lichtverhältnissen aufgenommen wurden, und bewahrt so Details.</string>\n    <string name=\"model_dejumbo\">Korrigiert überbelichtete oder „riesige“ Glanzlichter und stellt eine bessere Tonbalance wieder her.</string>\n    <string name=\"model_ddcolor_tiny\">Leichtes und schnelles Kolorierungsmodell, das Graustufenbildern natürliche Farben hinzufügt.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Kolorieren</string>\n    <string name=\"type_artifacts\">Artefakte</string>\n    <string name=\"type_enhance\">Erweitern</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Scannt</string>\n    <string name=\"type_upscale\">Gehoben</string>\n    <string name=\"model_realesrgan_x4v3\">X4-Upscaler für allgemeine Bilder; Winziges Modell, das weniger GPU und Zeit verbraucht, mit mäßiger Entunschärfe und Rauschunterdrückung.</string>\n    <string name=\"model_realesrgan_x2plus\">X2-Upscaler für allgemeine Bilder unter Beibehaltung von Texturen und natürlichen Details.</string>\n    <string name=\"model_realesrgan_x4plus\">X4-Upscaler für allgemeine Bilder mit verbesserten Texturen und realistischen Ergebnissen.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4-Upscaler, optimiert für Anime-Bilder; 6 RRDB-Blöcke für schärfere Linien und Details.</string>\n    <string name=\"model_realesrnet_x4plus\">X4-Upscaler mit MSE-Verlust sorgt für glattere Ergebnisse und weniger Artefakte für allgemeine Bilder.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimiert für Anime-Bilder; 4B32F-Variante mit schärferen Details und glatten Linien.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2-Modell für allgemeine Bilder; betont Schärfe und Klarheit.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; schneller und kleiner, behält Details bei und verbraucht weniger GPU-Speicher.</string>\n    <string name=\"model_rmbg_1_4\">Leichtes Modell zur schnellen Hintergrundentfernung. Ausgewogene Leistung und Genauigkeit. Arbeitet mit Porträts, Objekten und Szenen. Empfohlen für die meisten Anwendungsfälle.</string>\n    <string name=\"type_removebg\">BG entfernen</string>\n    <string name=\"horizontal_border_thickness\">Horizontale Randstärke</string>\n    <string name=\"vertical_border_thickness\">Vertikale Randstärke</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s Farbe</item>\n        <item quantity=\"other\">%1$s Farben</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Das aktuelle Modell unterstützt kein Chunking. Das Bild wird in den Originalabmessungen verarbeitet. Dies kann zu hohem Speicherverbrauch und Problemen mit Low-End-Geräten führen</string>\n    <string name=\"chunking_disabled\">Chunking ist deaktiviert, das Bild wird in den Originalabmessungen verarbeitet. Dies kann zu einem hohen Speicherverbrauch und Problemen mit Low-End-Geräten führen, kann jedoch zu besseren Ergebnissen bei der Inferenz führen</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">Hochpräzises Bildsegmentierungsmodell zur Hintergrundentfernung</string>\n    <string name=\"model_u2netp\">Leichte Version von U2Net für schnellere Hintergrundentfernung bei geringerer Speichernutzung.</string>\n    <string name=\"model_ddcolor\">Das vollständige DDColor-Modell liefert eine hochwertige Kolorierung für allgemeine Bilder mit minimalen Artefakten. Beste Wahl aller Kolorierungsmodelle.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor geschulte und private künstlerische Datensätze; Erzeugt vielfältige und künstlerische Kolorierungsergebnisse mit weniger unrealistischen Farbartefakten.</string>\n    <string name=\"model_birefnet\">Leichtes BiRefNet-Modell basierend auf Swin Transformer für präzise Hintergrundentfernung.</string>\n    <string name=\"model_inspyrenet\">Hochwertige Hintergrundentfernung mit scharfen Kanten und hervorragender Detailerhaltung, insbesondere bei komplexen Objekten und schwierigen Hintergründen.</string>\n    <string name=\"model_isnet\">Hintergrundentfernungsmodell, das genaue Masken mit glatten Kanten erzeugt, geeignet für allgemeine Objekte und mäßige Detailerhaltung.</string>\n    <string name=\"model_already_downloaded\">Modell bereits heruntergeladen</string>\n    <string name=\"model_successfully_imported\">Modell erfolgreich importiert</string>\n    <string name=\"type\">Typ</string>\n    <string name=\"keyword\">Stichwort</string>\n    <string name=\"very_fast\">Sehr schnell</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Langsam</string>\n    <string name=\"very_slow\">Sehr langsam</string>\n    <string name=\"compute_percents\">Berechnen Sie Prozente</string>\n    <string name=\"minimum_value_is\">Der Mindestwert ist %1$s</string>\n    <string name=\"warp_sub\">Verzerren Sie das Bild, indem Sie mit den Fingern zeichnen</string>\n    <string name=\"warp\">Kette</string>\n    <string name=\"hardness\">Härte</string>\n    <string name=\"warp_mode\">Warp-Modus</string>\n    <string name=\"warp_mode_move\">Bewegen</string>\n    <string name=\"warp_mode_grow\">Wachsen</string>\n    <string name=\"warp_mode_shrink\">Schrumpfen</string>\n    <string name=\"warp_mode_swirl_cw\">Wirbel im Uhrzeigersinn</string>\n    <string name=\"warp_mode_swirl_ccw\">Gegen den Uhrzeigersinn wirbeln</string>\n    <string name=\"fade_strength\">Stärke verblassen</string>\n    <string name=\"top_drop\">Top-Drop</string>\n    <string name=\"bottom_drop\">Bottom Drop</string>\n    <string name=\"start_drop\">Starten Sie Drop</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">Herunterladen</string>\n    <string name=\"smooth_shapes\">Glatte Formen</string>\n    <string name=\"smooth_shapes_sub\">Verwenden Sie Superellipsen anstelle der standardmäßigen abgerundeten Rechtecke für glattere, natürlichere Formen</string>\n    <string name=\"shape_type\">Formtyp</string>\n    <string name=\"cut\">Schneiden</string>\n    <string name=\"rounded\">Gerundet</string>\n    <string name=\"smooth\">Glatt</string>\n    <string name=\"cut_shapes_sub\">Scharfe Kanten ohne Rundung</string>\n    <string name=\"rounded_shapes_sub\">Klassische abgerundete Ecken</string>\n    <string name=\"shapes_type\">Formentyp</string>\n    <string name=\"corners_size\">Eckengröße</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elegante abgerundete UI-Elemente</string>\n    <string name=\"filename_format\">Dateinamenformat</string>\n    <string name=\"prefix_pattern_description\">Benutzerdefinierter Text wird ganz am Anfang des Dateinamens platziert, ideal für Projektnamen, Marken oder persönliche Tags.</string>\n    <string name=\"original_filename_pattern_description\">Verwendet den ursprünglichen Dateinamen ohne Erweiterung, sodass die Quellenidentifizierung erhalten bleibt.</string>\n    <string name=\"width_pattern_description\">Die Bildbreite in Pixel, nützlich zum Verfolgen von Auflösungsänderungen oder zum Skalieren von Ergebnissen.</string>\n    <string name=\"height_pattern_description\">Die Bildhöhe in Pixel, hilfreich beim Arbeiten mit Seitenverhältnissen oder Exporten.</string>\n    <string name=\"random_numbers_pattern_description\">Erzeugt zufällige Ziffern, um eindeutige Dateinamen zu gewährleisten; Fügen Sie weitere Ziffern hinzu, um die Sicherheit vor Duplikaten zu erhöhen.</string>\n    <string name=\"sequence_number_pattern_description\">Automatisch inkrementierender Zähler für Batch-Exporte, ideal beim Speichern mehrerer Bilder in einer Sitzung.</string>\n    <string name=\"preset_info_pattern_description\">Fügt den Namen der angewendeten Voreinstellung in den Dateinamen ein, damit Sie sich leicht daran erinnern können, wie das Bild verarbeitet wurde.</string>\n    <string name=\"scale_mode_pattern_description\">Zeigt den Bildskalierungsmodus an, der während der Verarbeitung verwendet wird, und hilft dabei, in der Größe veränderte, zugeschnittene oder angepasste Bilder zu unterscheiden.</string>\n    <string name=\"suffix_pattern_description\">Benutzerdefinierter Text am Ende des Dateinamens, nützlich für die Versionierung, z. B. _v2, _edited oder _final.</string>\n    <string name=\"extension_pattern_description\">Die Dateierweiterung (png, jpg, webp usw.) passt automatisch zum tatsächlich gespeicherten Format.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Ein anpassbarer Zeitstempel, mit dem Sie Ihr eigenes Format nach Java-Spezifikation für eine perfekte Sortierung definieren können.</string>\n    <string name=\"fling_type\">Fling-Typ</string>\n    <string name=\"android_native\">Android nativ</string>\n    <string name=\"ios_style\">iOS-Stil</string>\n    <string name=\"smooth_curve\">Glatte Kurve</string>\n    <string name=\"quick_stop\">Schneller Stopp</string>\n    <string name=\"bouncy\">Federnd</string>\n    <string name=\"floaty\">Schwebend</string>\n    <string name=\"snappy\">Bissig</string>\n    <string name=\"ultra_smooth\">Ultra glatt</string>\n    <string name=\"adaptive\">Adaptiv</string>\n    <string name=\"accessibility_aware\">Barrierefreiheit bewusst</string>\n    <string name=\"reduced_motion\">Reduzierte Bewegung</string>\n    <string name=\"android_native_sub\">Native Android-Scroll-Physik zum Basisvergleich</string>\n    <string name=\"smooth_sub\">Ausgewogenes, flüssiges Scrollen für den allgemeinen Gebrauch</string>\n    <string name=\"ios_style_sub\">Höheres Reibungsverhalten beim iOS-ähnlichen Scrollverhalten</string>\n    <string name=\"smooth_curve_sub\">Einzigartige Spline-Kurve für ein ausgeprägtes Scroll-Gefühl</string>\n    <string name=\"quick_stop_sub\">Präzises Scrollen mit schnellem Stoppen</string>\n    <string name=\"bouncy_sub\">Verspielte, reaktionsschnelle, federnde Schriftrolle</string>\n    <string name=\"floaty_sub\">Lange, gleitende Scrolls zum Durchsuchen von Inhalten</string>\n    <string name=\"snappy_sub\">Schnelles, reaktionsschnelles Scrollen für interaktive Benutzeroberflächen</string>\n    <string name=\"ultra_smooth_sub\">Erstklassiges flüssiges Scrollen mit längerem Schwung</string>\n    <string name=\"adaptive_sub\">Passt die Physik basierend auf der Wurfgeschwindigkeit an</string>\n    <string name=\"accessibility_aware_sub\">Berücksichtigt die Barrierefreiheitseinstellungen des Systems</string>\n    <string name=\"reduced_motion_sub\">Minimale Bewegung für Zugänglichkeitsanforderungen</string>\n    <string name=\"primary_lines\">Primäre Linien</string>\n    <string name=\"primary_lines_sub\">Fügt jede fünfte Zeile eine dickere Linie hinzu</string>\n    <string name=\"fill_color\">Füllfarbe</string>\n    <string name=\"hidden_tools\">Versteckte Werkzeuge</string>\n    <string name=\"hidden_for_share\">Zum Teilen ausgeblendete Tools</string>\n    <string name=\"color_library\">Farbbibliothek</string>\n    <string name=\"color_library_sub\">Stöbern Sie in einer riesigen Farbkollektion</string>\n    <string name=\"model_fatality_deblur\">Schärft und entfernt Unschärfen aus Bildern und behält gleichzeitig natürliche Details bei, ideal zum Korrigieren unscharfer Fotos.</string>\n    <string name=\"model_unresize_v3\">Stellt Bilder, deren Größe zuvor geändert wurde, intelligent wieder her und stellt verlorene Details und Texturen wieder her.</string>\n    <string name=\"model_liveaction_v1_span\">Optimiert für Live-Action-Inhalte, reduziert Komprimierungsartefakte und verbessert feine Details in Film-/TV-Show-Frames.</string>\n    <string name=\"model_vhs2hd_realplksr\">Konvertiert Filmmaterial in VHS-Qualität in HD, entfernt Bandrauschen und verbessert die Auflösung, während das Vintage-Feeling erhalten bleibt.</string>\n    <string name=\"model_text2hd_v1\">Spezialisiert auf textlastige Bilder und Screenshots, schärft Zeichen und verbessert die Lesbarkeit.</string>\n    <string name=\"model_frankendata_pretrainer\">Erweitertes Upscaling, trainiert auf verschiedenen Datensätzen, hervorragend für die allgemeine Fotoverbesserung.</string>\n    <string name=\"model_realwebphoto_v2\">Optimiert für webkomprimierte Fotos, entfernt JPEG-Artefakte und stellt das natürliche Erscheinungsbild wieder her.</string>\n    <string name=\"model_realwebphoto_v4\">Verbesserte Version für Webfotos mit besserer Texturerhaltung und Artefaktreduzierung.</string>\n    <string name=\"model_dat_2x\">2-fache Hochskalierung mit Dual Aggregation Transformer-Technologie, behält Schärfe und natürliche Details bei.</string>\n    <string name=\"model_dat_3x\">3-fache Hochskalierung mit fortschrittlicher Transformatorarchitektur, ideal für moderate Vergrößerungsanforderungen.</string>\n    <string name=\"model_dat_4x\">4-fache hochwertige Hochskalierung mit modernstem Transformatornetzwerk, bewahrt feine Details in größeren Maßstäben.</string>\n    <string name=\"model_nafnet_deblurring\">Entfernt Unschärfe/Rauschen und Verwacklungen aus Fotos. Universell einsetzbar, aber am besten für Fotos geeignet.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Stellt Bilder mit geringer Qualität mithilfe des Swin2SR-Transformators wieder her, der für die BSRGAN-Verschlechterung optimiert ist. Ideal zum Beheben starker Komprimierungsartefakte und zur Verbesserung von Details im 4-fachen Maßstab.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4-fache Hochskalierung mit SwinIR-Transformator, trainiert auf BSRGAN-Degradation. Verwendet GAN für schärfere Texturen und natürlichere Details in Fotos und komplexen Szenen.</string>\n    <string name=\"path\">Weg</string>\n    <string name=\"merge_pdf\">PDF zusammenführen</string>\n    <string name=\"merge_pdf_sub\">Kombinieren Sie mehrere PDF-Dateien in einem Dokument</string>\n    <string name=\"files_order\">Dateireihenfolge</string>\n    <string name=\"pages_short\">S.</string>\n    <string name=\"split_pdf\">PDF teilen</string>\n    <string name=\"split_pdf_sub\">Extrahieren Sie bestimmte Seiten aus einem PDF-Dokument</string>\n    <string name=\"rotate_pdf\">PDF drehen</string>\n    <string name=\"rotate_pdf_sub\">Seitenausrichtung dauerhaft korrigieren</string>\n    <string name=\"pages\">Seiten</string>\n    <string name=\"rearrange_pdf\">PDF neu anordnen</string>\n    <string name=\"rearrange_pdf_sub\">Ziehen Sie Seiten per Drag-and-Drop, um sie neu anzuordnen</string>\n    <string name=\"hold_drag_drop\">Halten und ziehen Sie Seiten</string>\n    <string name=\"page_numbers\">Seitenzahlen</string>\n    <string name=\"page_numbers_sub\">Fügen Sie Ihren Dokumenten automatisch eine Nummerierung hinzu</string>\n    <string name=\"label_format\">Etikettenformat</string>\n    <string name=\"pdf_to_text\">PDF zu Text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extrahieren Sie einfachen Text aus Ihren PDF-Dokumenten</string>\n    <string name=\"watermark_pdf_sub\">Überlagern Sie benutzerdefinierten Text für Branding oder Sicherheit</string>\n    <string name=\"signature\">Unterschrift</string>\n    <string name=\"signature_sub\">Fügen Sie Ihre elektronische Signatur zu jedem Dokument hinzu</string>\n    <string name=\"will_be_for_signature\">Dies wird als Signatur verwendet</string>\n    <string name=\"unlock_pdf\">PDF entsperren</string>\n    <string name=\"unlock_pdf_sub\">Entfernen Sie Passwörter aus Ihren geschützten Dateien</string>\n    <string name=\"protect_pdf\">PDF schützen</string>\n    <string name=\"protect_pdf_sub\">Sichern Sie Ihre Dokumente mit starker Verschlüsselung</string>\n    <string name=\"success\">Erfolg</string>\n    <string name=\"pdf_unlocked\">PDF entsperrt, Sie können es speichern oder teilen</string>\n    <string name=\"repair_pdf\">PDF reparieren</string>\n    <string name=\"repair_pdf_sub\">Versuchen Sie, beschädigte oder unleserliche Dokumente zu reparieren</string>\n    <string name=\"grayscale\">Graustufen</string>\n    <string name=\"grayscale_pdf_sub\">Konvertieren Sie alle in Dokumente eingebetteten Bilder in Graustufen</string>\n    <string name=\"compress_pdf\">PDF komprimieren</string>\n    <string name=\"compress_pdf_sub\">Optimieren Sie die Dateigröße Ihres Dokuments für eine einfachere Weitergabe</string>\n    <string name=\"repair_info\">ImageToolbox erstellt die interne Querverweistabelle neu und generiert die Dateistruktur von Grund auf neu. Dadurch kann der Zugriff auf viele Dateien wiederhergestellt werden, die „nicht geöffnet werden können“.</string>\n    <string name=\"grayscale_info\">Dieses Tool konvertiert alle Dokumentbilder in Graustufen. Am besten zum Drucken und Reduzieren der Dateigröße geeignet</string>\n    <string name=\"metadata\">Metadaten</string>\n    <string name=\"metadata_pdf_sub\">Bearbeiten Sie die Dokumenteigenschaften, um den Datenschutz zu verbessern</string>\n    <string name=\"tags\">Schlagworte</string>\n    <string name=\"producer\">Produzent</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Schlüsselwörter</string>\n    <string name=\"creator\">Schöpfer</string>\n    <string name=\"privacy_deep_clean\">Privatsphäre tief reinigen</string>\n    <string name=\"privacy_deep_clean_sub\">Löschen Sie alle verfügbaren Metadaten für dieses Dokument</string>\n    <string name=\"page\">Seite</string>\n    <string name=\"deep_ocr\">Tiefe OCR</string>\n    <string name=\"deep_ocr_sub\">Extrahieren Sie Text aus dem Dokument und speichern Sie ihn mithilfe der Tesseract-Engine in einer Textdatei</string>\n    <string name=\"cant_remove_all\">Es können nicht alle Seiten entfernt werden</string>\n    <string name=\"remove_pages_pdf\">PDF-Seiten entfernen</string>\n    <string name=\"remove_pages_pdf_sub\">Entfernen Sie bestimmte Seiten aus dem PDF-Dokument</string>\n    <string name=\"tap_to_remove\">Tippen Sie auf „Entfernen“.</string>\n    <string name=\"manually\">Manuell</string>\n    <string name=\"crop_pdf\">PDF zuschneiden</string>\n    <string name=\"crop_pdf_sub\">Beschneiden Sie Dokumentseiten auf beliebige Grenzen</string>\n    <string name=\"flatten_pdf\">PDF reduzieren</string>\n    <string name=\"flatten_pdf_sub\">Machen Sie PDFs durch Rastern von Dokumentseiten unveränderbar</string>\n    <string name=\"camera_failed_to_open\">Die Kamera konnte nicht gestartet werden. Bitte überprüfen Sie die Berechtigungen und stellen Sie sicher, dass sie nicht von einer anderen App verwendet wird.</string>\n    <string name=\"extract_images\">Bilder extrahieren</string>\n    <string name=\"extract_images_sub\">Extrahieren Sie in PDFs eingebettete Bilder in ihrer Originalauflösung</string>\n    <string name=\"pdf_no_embedded\">Diese PDF-Datei enthält keine eingebetteten Bilder</string>\n    <string name=\"extract_images_info\">Dieses Tool scannt jede Seite und stellt Quellbilder in voller Qualität wieder her – perfekt zum Speichern von Originalen aus Dokumenten</string>\n    <string name=\"draw_signature\">Unterschrift zeichnen</string>\n    <string name=\"pen_params\">Stiftparameter</string>\n    <string name=\"draw_signature_sub\">Verwenden Sie Ihre eigene Signatur als Bild, das auf Dokumenten platziert werden soll</string>\n    <string name=\"zip_pdf\">PDF komprimieren</string>\n    <string name=\"zip_pdf_sub\">Teilen Sie das Dokument in einem bestimmten Intervall auf und packen Sie neue Dokumente in ein ZIP-Archiv</string>\n    <string name=\"interval\">Intervall</string>\n    <string name=\"print_pdf\">PDF drucken</string>\n    <string name=\"print_pdf_sub\">Bereiten Sie das Dokument zum Drucken mit benutzerdefinierter Seitengröße vor</string>\n    <string name=\"pages_per_sheet\">Seiten pro Blatt</string>\n    <string name=\"orientation\">Orientierung</string>\n    <string name=\"page_size\">Seitengröße</string>\n    <string name=\"margin\">Marge</string>\n    <string name=\"bloom\">Blühen</string>\n    <string name=\"soft_knee\">Weiches Knie</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimiert für Anime und Cartoons. Schnelles Hochskalieren mit verbesserten natürlichen Farben und weniger Artefakten</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7-ähnlicher Stil</string>\n    <string name=\"calculate_hint\">Geben Sie hier grundlegende mathematische Symbole ein, um den gewünschten Wert zu berechnen (z. B. (5+5)*10).</string>\n    <string name=\"math_expression\">Mathematischer Ausdruck</string>\n    <string name=\"pick_up_to_n_collage_images\">Bis zu %1$s Bilder aufnehmen</string>\n    <string name=\"keep_date_time\">Datum und Uhrzeit beibehalten</string>\n    <string name=\"keep_date_time_sub\">Behalten Sie immer Exif-Tags in Bezug auf Datum und Uhrzeit bei, funktioniert unabhängig von der Option „Exif behalten“.</string>\n    <string name=\"background_color_for_alpha_formats\">Hintergrundfarbe für Alpha-Formate</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Fügt die Möglichkeit hinzu, die Hintergrundfarbe für jedes Bildformat mit Alpha-Unterstützung festzulegen. Wenn diese Option deaktiviert ist, ist sie nur für Nicht-Alpha-Formate verfügbar</string>\n    <string name=\"open_markup_project\">Projekt öffnen</string>\n    <string name=\"open_markup_project_sub\">Bearbeiten Sie weiterhin ein zuvor gespeichertes Image Toolbox-Projekt</string>\n    <string name=\"markup_project_open_failed\">Das Image Toolbox-Projekt kann nicht geöffnet werden</string>\n    <string name=\"markup_project_missing_data\">Im Image Toolbox-Projekt fehlen Projektdaten</string>\n    <string name=\"markup_project_corrupted\">Das Image Toolbox-Projekt ist beschädigt</string>\n    <string name=\"unsupported_markup_project_version\">Nicht unterstützte Image Toolbox-Projektversion: %1$d</string>\n    <string name=\"save_markup_project\">Projekt speichern</string>\n    <string name=\"save_markup_project_sub\">Speichern Sie Ebenen, Hintergrund und Bearbeitungsverlauf in einer bearbeitbaren Projektdatei</string>\n    <string name=\"failed_to_open\">Öffnen fehlgeschlagen</string>\n    <string name=\"ocr_write_to_searchable_pdf\">In durchsuchbares PDF schreiben</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Erkennen Sie Text aus dem Bildstapel und speichern Sie durchsuchbare PDFs mit Bild und auswählbarer Textebene</string>\n    <string name=\"layer_alpha\">Ebene Alpha</string>\n    <string name=\"horizontal_flip\">Horizontaler Flip</string>\n    <string name=\"vertical_flip\">Vertikaler Flip</string>\n    <string name=\"lock\">Sperren</string>\n    <string name=\"add_shadow\">Schatten hinzufügen</string>\n    <string name=\"shadow_color\">Schattenfarbe</string>\n    <string name=\"text_geometry\">Textgeometrie</string>\n    <string name=\"text_geometry_sub\">Dehnen oder neigen Sie Text für eine schärfere Stilisierung</string>\n    <string name=\"scale_x\">Maßstab X</string>\n    <string name=\"skew_x\">Skew X</string>\n    <string name=\"remove_annotations\">Anmerkungen entfernen</string>\n    <string name=\"remove_annotations_sub\">Entfernen Sie ausgewählte Anmerkungstypen wie Links, Kommentare, Hervorhebungen, Formen oder Formularfelder von den PDF-Seiten</string>\n    <string name=\"annotation_link\">Hyperlinks</string>\n    <string name=\"annotation_file_attachment\">Dateianhänge</string>\n    <string name=\"annotation_line\">Linien</string>\n    <string name=\"annotation_popup\">Popups</string>\n    <string name=\"annotation_stamp\">Briefmarken</string>\n    <string name=\"annotation_shapes\">Formen</string>\n    <string name=\"annotation_text\">Textnotizen</string>\n    <string name=\"annotation_text_markup\">Textmarkierung</string>\n    <string name=\"annotation_widget\">Formularfelder</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">Unbekannt</string>\n    <string name=\"annotations\">Anmerkungen</string>\n    <string name=\"ungroup\">Gruppierung aufheben</string>\n    <string name=\"add_shadow_sub\">Fügen Sie Unschärfeschatten hinter der Ebene mit konfigurierbaren Farben und Offsets hinzu</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-es/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">Algo salió mal: %1$s</string>\n    <string name=\"size\">Tamaño %1$s</string>\n    <string name=\"loading\">Cargando…</string>\n    <string name=\"image_too_large_preview\">La imagen es demasiado grande para previsualizarla, pero se intentará guardar de todas formas.</string>\n    <string name=\"pick_image\">Selecciona una imagen para iniciar</string>\n    <string name=\"search_here\">Busca aquí</string>\n    <string name=\"width\">Anchura %1$s</string>\n    <string name=\"resize_type\">Tipo de redimensión</string>\n    <string name=\"explicit\">Explícito</string>\n    <string name=\"flexible\">Flexible</string>\n    <string name=\"pick_image_alt\">Elegir imagen</string>\n    <string name=\"app_closing\">Aplicación cerrándose</string>\n    <string name=\"stay\">Quedarse</string>\n    <string name=\"close\">Cerrar</string>\n    <string name=\"reset_image\">Restablecer imagen</string>\n    <string name=\"reset_image_sub\">Los cambios en la imagen se revertirán a los valores iniciales</string>\n    <string name=\"values_reset\">Valores restablecidos correctamente</string>\n    <string name=\"reset\">Restablecer</string>\n    <string name=\"something_went_wrong\">Algo salió mal</string>\n    <string name=\"restart_app\">Reiniciar la aplicación</string>\n    <string name=\"copied\">Copiado al portapapeles</string>\n    <string name=\"exception\">Excepción</string>\n    <string name=\"edit_exif\">Editar EXIF</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">No se han encontrado datos EXIF</string>\n    <string name=\"add_tag\">Añadir etiqueta</string>\n    <string name=\"save\">Guardar</string>\n    <string name=\"clear\">Borrar</string>\n    <string name=\"clear_exif\">Borrar EXIF</string>\n    <string name=\"cancel\">Cancelar</string>\n    <string name=\"clear_exif_sub\">Se borrarán todos los datos EXIF de la imagen, ¡esta acción no se puede deshacer!</string>\n    <string name=\"presets\">Preajustes</string>\n    <string name=\"crop\">Recortar</string>\n    <string name=\"image_not_saved\">Guardar</string>\n    <string name=\"image_not_saved_sub\">Todos los cambios no guardados se perderán si sales ahora</string>\n    <string name=\"check_source_code\">Código fuente</string>\n    <string name=\"check_source_code_sub\">Recibe las últimas actualizaciones, discute acerca de los problemas y más</string>\n    <string name=\"single_edit\">Edición única</string>\n    <string name=\"single_edit_sub\">Modificar, redimensionar y editar una imagen</string>\n    <string name=\"pick_color\">Selector de color</string>\n    <string name=\"pick_color_sub\">Elige el color de la imagen, cópiala o compártela</string>\n    <string name=\"image\">Imagen</string>\n    <string name=\"color\">Color</string>\n    <string name=\"color_copied\">Color copiado</string>\n    <string name=\"crop_sub\">Recorta la imagen a cualquier límite</string>\n    <string name=\"version\">Versión</string>\n    <string name=\"keep_exif\">Conservar EXIF</string>\n    <string name=\"images\">Imágenes: %d</string>\n    <string name=\"change_preview\">Cambiar vista previa</string>\n    <string name=\"remove\">Eliminar</string>\n    <string name=\"palette_sub\">Generar una muestra de paleta de colores a partir de una imagen dada</string>\n    <string name=\"generate_palette\">Generar Paleta</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"update\">Actualizar</string>\n    <string name=\"new_version\">Nueva versión %1$s</string>\n    <string name=\"unsupported_type\">Tipo no admitido: %1$s</string>\n    <string name=\"no_palette\">No se puede generar la paleta para la imagen dada</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Carpeta de salida</string>\n    <string name=\"def\">Por defecto</string>\n    <string name=\"custom\">Personalizado</string>\n    <string name=\"unspecified\">Sin especificar</string>\n    <string name=\"device_storage\">Almacenamiento del dispositivo</string>\n    <string name=\"by_bytes_resize\">Redimensionar por Peso</string>\n    <string name=\"max_bytes\">Tamaño máximo en KB</string>\n    <string name=\"by_bytes_resize_sub\">Redimensionar una imagen siguiendo un tamaño dado en KB</string>\n    <string name=\"compare\">Comparar</string>\n    <string name=\"settings\">Ajustes</string>\n    <string name=\"night_mode\">Modo nocturno</string>\n    <string name=\"dark\">Oscuro</string>\n    <string name=\"light\">Claro</string>\n    <string name=\"system\">Sistema</string>\n    <string name=\"dynamic_colors\">Colores dinámicos</string>\n    <string name=\"customization\">Personalización</string>\n    <string name=\"allow_image_monet\">Permitir monet de imagen</string>\n    <string name=\"allow_image_monet_sub\">Si está activado, cuando elijas una imagen para editar, los colores de la aplicación se adaptarán a esta imagen</string>\n    <string name=\"language\">Idioma</string>\n    <string name=\"amoled_mode\">Modo Amoled</string>\n    <string name=\"amoled_mode_sub\">Si se activa, el color de las superficies se establecerá como oscuro absoluto en modo nocturno</string>\n    <string name=\"color_scheme\">Esquema de colores</string>\n    <string name=\"color_red\">Rojo</string>\n    <string name=\"color_green\">Verde</string>\n    <string name=\"color_blue\">Azul</string>\n    <string name=\"clipboard_paste_invalid_color_code\">El código de color aRGB no es válido.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nada que pegar</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">El esquema de colores de la app no se puede cambiar mientras los colores dinámicos están activados</string>\n    <string name=\"pick_accent_color\">El tema de la aplicación se basará en el color que elijas</string>\n    <string name=\"about_app\">Acerca de la aplicación</string>\n    <string name=\"no_updates\">No se han encontrado actualizaciones</string>\n    <string name=\"issue_tracker\">Seguimiento de problemas</string>\n    <string name=\"issue_tracker_sub\">Envía aquí informes de errores y solicitudes de funciones</string>\n    <string name=\"help_translate\">Ayuda a traducir</string>\n    <string name=\"help_translate_sub\">Corrige errores de traducción o localiza el proyecto a otros idiomas</string>\n    <string name=\"height\">Altura %1$s</string>\n    <string name=\"quality\">Calidad</string>\n    <string name=\"extension\">Extensión</string>\n    <string name=\"app_closing_sub\">¿Estás seguro de querer cerrar la aplicación?</string>\n    <string name=\"compare_sub\">Compara dos imágenes dadas</string>\n    <string name=\"pick_two_images\">Elige dos imágenes para empezar</string>\n    <string name=\"pick_images\">Elegir imágenes</string>\n    <string name=\"nothing_found_by_search\">No se ha encontrado nada con tu consulta</string>\n    <string name=\"dynamic_colors_sub\">Si está habilitado, los colores de la aplicación se adaptarán a los colores del fondo de pantalla</string>\n    <string name=\"failed_to_save\">Error al guardar %d imagen(es)</string>\n    <string name=\"primary\">Primario</string>\n    <string name=\"tertiary\">Terciario</string>\n    <string name=\"secondary\">Secundario</string>\n    <string name=\"border_thickness\">Grosor del borde</string>\n    <string name=\"surface\">Superficie</string>\n    <string name=\"values\">Valores</string>\n    <string name=\"add\">Añadir</string>\n    <string name=\"permission\">Permiso</string>\n    <string name=\"grant\">Otorgar</string>\n    <string name=\"permission_sub\">La app necesita acceso a tu almacenamiento para guardar imágenes, es necesario pues sin ello no funciona, así que por favor otorga el permiso en el siguiente diálogo.</string>\n    <string name=\"grant_permission_manual\">La aplicación necesita este permiso para funcionar, por favor, otorgalo manualmente</string>\n    <string name=\"donation_sub\">Esta aplicación es totalmente gratuita, pero si quieres apoyar el desarrollo del proyecto, puedes hacer clic aquí</string>\n    <string name=\"fab_alignment\">Alineación FAB</string>\n    <string name=\"check_updates\">Buscar actualizaciones</string>\n    <string name=\"check_updates_sub\">Si está activado, se mostrará un cuadro de diálogo de actualización al iniciar la aplicación</string>\n    <string name=\"zoom\">Zoom de la imagen</string>\n    <string name=\"prefix\">Prefijo</string>\n    <string name=\"filename\">Nombre de archivo</string>\n    <string name=\"share\">Compartir</string>\n    <string name=\"external_storage\">Almacenamiento externo</string>\n    <string name=\"monet_colors\">Colores Monet</string>\n    <string name=\"explicit_description\">Redimensiona las imágenes a la altura y anchura dadas. La relación de aspecto puede cambiar.</string>\n    <string name=\"brightness\">Brillo</string>\n    <string name=\"contrast\">Contraste</string>\n    <string name=\"saturation\">Saturación</string>\n    <string name=\"add_filter\">Añadir filtro</string>\n    <string name=\"filter_sub\">Aplica la selección de filtros a las imágenes</string>\n    <string name=\"filters\">Filtros</string>\n    <string name=\"light_aka_illumination\">Luz</string>\n    <string name=\"exposure\">Exposición</string>\n    <string name=\"white_balance\">Balance de blancos</string>\n    <string name=\"temperature\">Temperatura</string>\n    <string name=\"slope\">Pendiente</string>\n    <string name=\"negative\">Negativo</string>\n    <string name=\"sharpen\">Afilar</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"crosshatch\">Sombreado</string>\n    <string name=\"spacing\">Espaciado</string>\n    <string name=\"cga_colorspace\">espacio de color GCA</string>\n    <string name=\"kuwahara\">Suavizado Kuwahara</string>\n    <string name=\"image_preview_sub\">Visualiza cualquier tipo de imagen: GIF, SVG, etc</string>\n    <string name=\"order\">Orden</string>\n    <string name=\"no_image\">Sin imagen</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"tint\">Tinte</string>\n    <string name=\"black_and_white\">En blanco y negro</string>\n    <string name=\"opacity\">Opacidad</string>\n    <string name=\"limits_resize\">Redimensionar por Límites</string>\n    <string name=\"sketch\">Bosquejo</string>\n    <string name=\"threshold\">Límite</string>\n    <string name=\"quantizationLevels\">Niveles de cuantificación</string>\n    <string name=\"smooth_toon\">Toon suave</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"non_maximum_suppression\">Supresión no máxima</string>\n    <string name=\"weak_pixel_inclusion\">Inclusión de píxeles débiles</string>\n    <string name=\"lookup\">Buscar</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"stack_blur\">Desenfoque de pila</string>\n    <string name=\"convolution3x3\">Convolución 3x3</string>\n    <string name=\"rgb_filter\">filtro RGB</string>\n    <string name=\"false_color\">Color falso</string>\n    <string name=\"blur_size\">Tamaño de desenfoque</string>\n    <string name=\"blur_center_x\">Centro de desenfoque x</string>\n    <string name=\"blur_center_y\">Centro de desenfoque y</string>\n    <string name=\"zoom_blur\">Desenfoque de zoom</string>\n    <string name=\"color_balance\">Balance de color</string>\n    <string name=\"luminance_threshold\">Umbral de luminancia</string>\n    <string name=\"add_file_size\">Agregar tamaño de archivo</string>\n    <string name=\"add_file_size_sub\">Si está habilitado, agrega la anchura y altura de la imagen guardada al nombre del archivo resultante</string>\n    <string name=\"image_preview\">Vista previa de la imagen</string>\n    <string name=\"image_source\">Fuente de la imagen</string>\n    <string name=\"photo_picker\">Selector de fotos</string>\n    <string name=\"gallery_picker\">Galería</string>\n    <string name=\"file_explorer_picker\">Explorador de archivos</string>\n    <string name=\"photo_picker_sub\">El selector de fotos moderno de Android que aparece en la parte inferior de la pantalla, puede que funcione solo en Android 12+ y además tiene problemas para recibir metadatos EXIF</string>\n    <string name=\"gallery_picker_sub\">Selector simple de imágenes de la galería, solo funcionará si tienes alguna app que provea selección de fotos</string>\n    <string name=\"order_sub\">Determina el orden de las herramientas en la pantalla principal</string>\n    <string name=\"replace_sequence_number_sub\">Si está habilitado, reemplaza la marca de tiempo estándar por el número de secuencia de imágenes si usas el procesamiento por lotes</string>\n    <string name=\"load_image_from_net_sub\">Carga cualquier imagen de Internet, obtén una vista previa, haz zoom y también guárdala o edítala si lo deseas.</string>\n    <string name=\"image_link\">Enlace de imagen</string>\n    <string name=\"fill\">Llenar</string>\n    <string name=\"fit\">Adaptar</string>\n    <string name=\"flexible_description\">Redimensiona las imágenes que no sean cuadradas a la altura o anchura introducida. Todos los cálculos de tamaño se realizarán después de guardar. Se mantendrá la relación de aspecto.</string>\n    <string name=\"hue\">Matiz</string>\n    <string name=\"filter\">Filtrar</string>\n    <string name=\"color_filter\">Filtro de color</string>\n    <string name=\"monochrome\">Monocromo</string>\n    <string name=\"gamma\">Gama</string>\n    <string name=\"highlights_shadows\">Luces y sombras</string>\n    <string name=\"highlights\">Reflejos</string>\n    <string name=\"shadows\">Sombras</string>\n    <string name=\"haze\">Bruma</string>\n    <string name=\"effect\">Efecto</string>\n    <string name=\"distance\">Distancia</string>\n    <string name=\"solarize\">Solarizar</string>\n    <string name=\"vibrance\">Intensidad</string>\n    <string name=\"line_width\">Ancho de línea</string>\n    <string name=\"sobel_edge\">Borde sobel</string>\n    <string name=\"blur\">Desenfocar</string>\n    <string name=\"halftone\">Semitono</string>\n    <string name=\"gaussian_blur\">Desenfoque gaussiano</string>\n    <string name=\"box_blur\">Caja de desenfoque</string>\n    <string name=\"bilaterial_blur\">Desenfoque bilateral</string>\n    <string name=\"emboss\">Realzar</string>\n    <string name=\"laplacian\">Laplaciano</string>\n    <string name=\"vignette\">Viñeta</string>\n    <string name=\"start\">Comenzar</string>\n    <string name=\"end\">Fin</string>\n    <string name=\"radius\">Radio</string>\n    <string name=\"scale\">Escala</string>\n    <string name=\"distortion\">Distorsión</string>\n    <string name=\"angle\">Ángulo</string>\n    <string name=\"swirl\">Remolino</string>\n    <string name=\"bulge\">Bulto</string>\n    <string name=\"dilation\">Dilatación</string>\n    <string name=\"sphere_refraction\">Refracción de esfera</string>\n    <string name=\"refractive_index\">Índice de refracción</string>\n    <string name=\"glass_sphere_refraction\">Refracción de esfera de vidrio</string>\n    <string name=\"color_matrix\">Matriz de color</string>\n    <string name=\"limits_resize_sub\">Redimensionar imágenes a una altura y anchura dadas manteniendo la relación de aspecto.</string>\n    <string name=\"posterize\">Posterizar</string>\n    <string name=\"emoji_sub\">Selecciona qué emoji se mostrará en la pantalla principal</string>\n    <string name=\"first_color\">Primer color</string>\n    <string name=\"second_color\">Segundo color</string>\n    <string name=\"reorder\">Reordenar</string>\n    <string name=\"fast_blur\">Desenfoque rápido</string>\n    <string name=\"delete_exif\">Eliminar EXIF</string>\n    <string name=\"delete_exif_sub\">Eliminar metadatos EXIF de cualquier par de imágenes</string>\n    <string name=\"load_image_from_net\">Cargar imagen en línea</string>\n    <string name=\"options_arrangement\">Acomodo de opciones</string>\n    <string name=\"edit\">Editar</string>\n    <string name=\"content_scale\">Escala de contenido</string>\n    <string name=\"emojis_count\">Número de emojis</string>\n    <string name=\"sequence_num\">número de secuencia</string>\n    <string name=\"original_filename\">Nombre de archivo original</string>\n    <string name=\"add_original_filename\">Agregar el nombre del archivo original</string>\n    <string name=\"add_original_filename_sub\">Si está habilitado, agrega el nombre del archivo original en el nombre de la imagen resultante</string>\n    <string name=\"filename_not_work_with_photopicker\">Agregar el nombre del archivo original no funciona si se seleccionó la fuente de imagen del selector de fotos</string>\n    <string name=\"file_explorer_picker_sub\">Usa la intención GetContent para elegir una imagen, funciona en todas partes, pero también puede tener problemas para recibir imágenes seleccionadas en algunos dispositivos, eso no es mi culpa.</string>\n    <string name=\"replace_sequence_number\">Reemplazar número de secuencia</string>\n    <string name=\"paint_color\">Color de pintura</string>\n    <string name=\"background_color\">Color de fondo</string>\n    <string name=\"cipher_sub\">Encriptar y desencriptar archivos (no solo imágenes) en base a diferentes algoritmos de encriptación disponibles.</string>\n    <string name=\"pick_file\">Escoger archivo</string>\n    <string name=\"encrypt\">Encriptar</string>\n    <string name=\"pick_file_to_start\">Escoge el archivo para empezar</string>\n    <string name=\"decryption\">Descripción</string>\n    <string name=\"encryption\">Cifrado</string>\n    <string name=\"key\">Clave</string>\n    <string name=\"compatibility\">Compatibilidad</string>\n    <string name=\"file_size\">Tamaño del archivo</string>\n    <string name=\"draw_on_image\">Dibujar en imagen</string>\n    <string name=\"decrypt\">Desencriptar</string>\n    <string name=\"invalid_password_or_not_encrypted\">Contraseña incorrecta o el archivo escogido no está encriptado</string>\n    <string name=\"image_size_warning\">Intentar guardar la imagen con esas dimensiones puede provocar un error de falta de memoria. Hazlo bajo tu responsabilidad.</string>\n    <string name=\"cache\">Caché</string>\n    <string name=\"cache_size\">Tamaño del caché</string>\n    <string name=\"auto_cache_clearing\">Limpieza del caché automática</string>\n    <string name=\"tools\">Herramientas</string>\n    <string name=\"implementation\">Implementación</string>\n    <string name=\"draw_on_image_sub\">Escoge una imagen y dibuja algo en ella</string>\n    <string name=\"store_file_desc\">Guarda este archivo en tu dispositivo o usa la acción de compartir para colocarlo donde desees</string>\n    <string name=\"features\">Características</string>\n    <string name=\"file_size_sub\">El tamaño máximo del archivo está restringido por el SO Android y la memoria disponible, lo cual obviamente dependerá de tu dispositivo. \\nImportante: memoria no es almacenamiento.</string>\n    <string name=\"edit_screenshot\">Editar captura de pantalla</string>\n    <string name=\"draw\">Dibujar</string>\n    <string name=\"group_options_by_type\">Opciones de grupo por tipo</string>\n    <string name=\"group_options_by_type_sub\">Opciones de grupos en la pantalla principal de su tipo en lugar de disposición de lista personalizada</string>\n    <string name=\"create\">Crear</string>\n    <string name=\"secondary_customization\">Personalización secundaria</string>\n    <string name=\"screenshot\">Captura de pantalla</string>\n    <string name=\"fallback_option\">Opción alternativa</string>\n    <string name=\"draw_on_background\">Dibujar en el fondo</string>\n    <string name=\"activate_files\">Desactivó la aplicación Archivos, actívela para usar esta función</string>\n    <string name=\"draw_sub\">Dibujar en la imagen como en un cuaderno de bocetos, o dibujar en el fondo mismo</string>\n    <string name=\"compatibility_sub\">Tenga en cuenta que no se garantiza la compatibilidad con otros servicios o software de cifrado de archivos. Un tratamiento de claves o una configuración de cifrado ligeramente diferentes pueden ser motivos de incompatibilidad.</string>\n    <string name=\"auto_cache_clearing_sub\">Si la caché de la aplicación está habilitada, se borrará al iniciar la aplicación</string>\n    <string name=\"copy\">Copiar</string>\n    <string name=\"warning_bytes\">Guardar en modo %1$s puede ser inestable, porque es un formato sin pérdidas</string>\n    <string name=\"found_s\">Encontrado %1$s</string>\n    <string name=\"draw_on_background_sub\">Elija el color de fondo y dibuje encima</string>\n    <string name=\"features_sub\">Cifrado de archivos basado en contraseña. Los archivos procedidos pueden almacenarse en el directorio seleccionado o compartirse. Los archivos descifrados también se pueden abrir directamente.</string>\n    <string name=\"implementation_sub\">\"AES-256, modo GCM, sin relleno, vector de Inicialización (IV) aleatorio de 12 bytes por defecto. Se puede seleccionar el algoritmo necesario. Las claves se utilizan como hashes SHA-3  de 256 bits.\"</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">No se puede cambiar el arreglo mientras la agrupación de opciones está habilitada</string>\n    <string name=\"skip\">Saltar</string>\n    <string name=\"paint_alpha\">Pintura alfa</string>\n    <string name=\"cipher\">Cifrar</string>\n    <string name=\"file_proceed\">Archivo procesado</string>\n    <string name=\"reset_settings_sub\">Esto restablecerá la configuración a los valores predeterminados. Ten en cuenta que esto no se puede deshacer sin un archivo de respaldo mencionado anteriormente.</string>\n    <string name=\"updates\">Actualizaciones</string>\n    <string name=\"something_went_wrong_emphasis\">Ups… Algo salió mal, escríbeme utilizando las opciones debajo e intentaré encontrar una solución</string>\n    <string name=\"tg_chat\">Chat de Telegram</string>\n    <string name=\"crop_mask\">Recortar máscara</string>\n    <string name=\"nature_and_animals\">Naturaleza y Animales</string>\n    <string name=\"max_colors_count\">Número de colores máximos</string>\n    <string name=\"activities\">Actividades</string>\n    <string name=\"wait\">Espera</string>\n    <string name=\"image_exif_warning\">Actualmente el formato %1$s en android solamente permite leer el EXIF y no cambiarlo/guardarlo, lo que significa que la imagen resultante no tendrá metadatos en absoluto.</string>\n    <string name=\"food_and_drink\">Comida y Bebida</string>\n    <string name=\"brush_softness\">Suavidad de la brocha</string>\n    <string name=\"contact_me\">Contáctame</string>\n    <string name=\"effort_sub\">Un valor de %1$s significa comprimir rápidamente, resultando en un peso de archivo relativamente grande. %2$s significa tomar más tiempo comprimiendo, resultando en un peso de archivo más pequeño.</string>\n    <string name=\"backup_sub\">Respalda tus configuraciones en la app a un archivo</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Archivo corrompido o no es un respaldo</string>\n    <string name=\"presets_sub\" formatted=\"false\">Si has seleccionado el preajuste 125, la imagen se guardará al 125% del tamaño de la imagen original. Si eliges el preajuste 50, entonces la imagen se guardará al 50% del tamaño original</string>\n    <string name=\"analytics_sub\">Permitir la recolección de estadísticas anónimas de uso de la app</string>\n    <string name=\"font_scale\">Tamaño de fuente</string>\n    <string name=\"allow_betas\">Permitir betas</string>\n    <string name=\"draw_arrows\">Dibujar Flechas</string>\n    <string name=\"draw_mode\">Modo de dibujo</string>\n    <string name=\"restore\">Restaurar</string>\n    <string name=\"trim_image_sub\">Los espacios transparentes alrededor de la imagen serán recortados</string>\n    <string name=\"tg_chat_sub\">Habla sobre la aplicación y recibe comentarios de otros usuarios. Además, allí puedes conseguir actualizaciones en beta e información.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Ññ Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"erase_background\">Borrar fondo</string>\n    <string name=\"restore_image\">Restaurar imagen</string>\n    <string name=\"draw_arrows_sub\">Si está habilitado, la dirección de dibujo será representada como una flecha apuntando</string>\n    <string name=\"delete\">Borrar</string>\n    <string name=\"aspect_ratio\">Relación de aspecto</string>\n    <string name=\"blur_radius\">Radio de desenfoque</string>\n    <string name=\"background_remover\">Eliminador de fondos</string>\n    <string name=\"trim_image\">Ajustar imagen</string>\n    <string name=\"background_remover_sub\">Remueve el fondo de una imagen mediante el pincel o utiliza la opción automática</string>\n    <string name=\"delete_color_scheme_warn\">Estás a punto de borrar el esquema de color seleccionado, esta acción no puede deshacerse</string>\n    <string name=\"saved_to_without_filename\">Guardado en el folder %1$s</string>\n    <string name=\"settings_restored\">Configuraciones restauradas con éxito</string>\n    <string name=\"backup_and_restore\">Respaldar y restaurar</string>\n    <string name=\"backup\">Respaldar</string>\n    <string name=\"auto_erase_background\">Remover fondo de manera automática</string>\n    <string name=\"emotions\">Emociones</string>\n    <string name=\"crashlytics_sub\">Esto permite a la aplicación recolectar reportes de fallo automáticamente</string>\n    <string name=\"saving_almost_complete\">Guardado casi completado, si cancelas ahora entonces tendrás que empezar a guardar de nuevo.</string>\n    <string name=\"create_issue\">Crear Reporte de Problema</string>\n    <string name=\"pipette\">Pipeta</string>\n    <string name=\"saved_to\">Guardado en el folder %1$s con nombre %2$s</string>\n    <string name=\"symbols\">Símbolos</string>\n    <string name=\"analytics\">Analíticos</string>\n    <string name=\"image_crop_mask_sub\">Usa este tipo de máscara para crear una máscara a partir de una imagen dada. Tenga en cuenta que DEBERÁ tener canal alfa</string>\n    <string name=\"enable_emoji\">Habilitar emoji</string>\n    <string name=\"effort\">Esfuerzo</string>\n    <string name=\"resize_and_convert\">Reajustar Tamaño y Convertir</string>\n    <string name=\"objects\">Objetos</string>\n    <string name=\"randomize_filename\">Aleatorizar nombre del archivo</string>\n    <string name=\"text\">Texto</string>\n    <string name=\"defaultt\">Predeterminado</string>\n    <string name=\"delete_color_scheme_title\">Borrar Esquema</string>\n    <string name=\"restore_background\">Restaurar fondo</string>\n    <string name=\"font\">Fuente</string>\n    <string name=\"crop_description\">Las imágenes serán recortadas centralmente a este tamaño si es un tamaño más grande que las dimensiones establecidas, y el canvas será expandido con el color de fondo dado en otros casos.</string>\n    <string name=\"resize_and_convert_sub\">Cambia el tamaño de imágenes dadas o conviértelas a otros formatos, además puedes editar los metadatos EXIF si seleccionas una sola imagen.</string>\n    <string name=\"using_large_fonts_warn\">Usar tamaños de fuente grandes puede causar errores en la IU que no serán arreglados, úsalos solamente si lo deseas.</string>\n    <string name=\"randomize_filename_sub\">Si se activa, el nombre del archivo resultante será completamente aleatorio</string>\n    <string name=\"donation\">Donación</string>\n    <string name=\"keep_exif_sub\">Se conservarán los metadatos de la imagen original</string>\n    <string name=\"restore_sub\">Restaura las configuraciones de la app desde un archivo previamente generado</string>\n    <string name=\"presets_sub_bytes\">El ajuste predeterminado aquí define el % de tamaño del archivo resultante. Es decir, seleccionando \\\"50\\\" para una imagen de 5 MB se guardará una imagen de 2.5 MB.</string>\n    <string name=\"erase_mode\">Modo de borrado</string>\n    <string name=\"allow_betas_sub\">La búsqueda de actualizaciones incluirá versiones beta de la app si está habilitado</string>\n    <string name=\"travels_and_places\">Viajes y Lugares</string>\n    <string name=\"email\">Correo electrónico</string>\n    <string name=\"enhanced_glitch\">Fallo mejorado</string>\n    <string name=\"channel_shift_x\">Cambio de canal X</string>\n    <string name=\"channel_shift_y\">Cambio de canal Y</string>\n    <string name=\"corruption_size\">Tamaño de la corrupción</string>\n    <string name=\"corruption_shift_x\">Cambio de corrupción X</string>\n    <string name=\"segmentation_mode_osd_only\">Orientación &amp; Solo detección de secuencias de comandos</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientación automática &amp; Detección de secuencias de comandos</string>\n    <string name=\"segmentation_mode_auto_only\">Sólo automático</string>\n    <string name=\"segmentation_mode_single_block\">Bloque único</string>\n    <string name=\"segmentation_mode_single_line\">Línea sola</string>\n    <string name=\"glitch\">Falla</string>\n    <string name=\"amount\">Cantidad</string>\n    <string name=\"seed\">Semilla</string>\n    <string name=\"shuffle\">Barajar</string>\n    <string name=\"delete_mask_warn\">Estás a punto de eliminar la máscara de filtro seleccionada. Esta operación no se puede deshacer</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Cortar</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Móbius</string>\n    <string name=\"no_such_directory\">No se encontró el directorio \\\"%1$s\\\", lo cambiamos al predeterminado, guarde el archivo nuevamente</string>\n    <string name=\"clipboard\">Portapapeles</string>\n    <string name=\"auto_pin\">Fijación automática</string>\n    <string name=\"vibration\">Vibración</string>\n    <string name=\"overwrite_file_requirements\">Para sobrescribir archivos, necesita usar la fuente de imagen \\\"Explorer\\\", intente volver a seleccionar imágenes, hemos cambiado la fuente de imagen a la necesaria</string>\n    <string name=\"overwrite_files\">Sobrescribir archivos</string>\n    <string name=\"overwrite_files_sub\">El archivo original se reemplazará por uno nuevo en lugar de guardarlo en la carpeta seleccionada. Esta opción debe tener como fuente de imagen \\\"Explorer\\\" o GetContent; al alternar esto, se configurará automáticamente</string>\n    <string name=\"empty\">Vacío</string>\n    <string name=\"suffix\">Sufijo</string>\n    <string name=\"search_option\">Buscar</string>\n    <string name=\"search_option_sub\">Permite buscar entre todas las herramientas disponibles en la pantalla principal.</string>\n    <string name=\"free\">Gratis</string>\n    <string name=\"images_overwritten\">Imágenes sobrescritas en el destino original</string>\n    <string name=\"blur_edges\">Bordes borrosos</string>\n    <string name=\"blur_edges_sub\">Dibuja bordes borrosos debajo de la imagen original para llenar los espacios a su alrededor en lugar de un solo color si está habilitado</string>\n    <string name=\"pixelation\">Pixelación</string>\n    <string name=\"enhanced_pixelation\">Pixelación mejorada</string>\n    <string name=\"stroke_pixelation\">Pixelación de trazo</string>\n    <string name=\"diamond_pixelation\">Pixelación de diamantes</string>\n    <string name=\"color_to_replace\">Color para reemplazar</string>\n    <string name=\"target_color\">Color objetivo</string>\n    <string name=\"color_to_remove\">Color para quitar</string>\n    <string name=\"remove_color\">Quitar color</string>\n    <string name=\"recode\">Recodificar</string>\n    <string name=\"fruit_salad\">Ensalada de frutas</string>\n    <string name=\"fidelity\">Fidelidad</string>\n    <string name=\"content\">Contenido</string>\n    <string name=\"tonal_spot_sub\">Estilo de paleta predeterminado, permite personalizar los cuatro colores, otros le permiten configurar solo el color clave</string>\n    <string name=\"neutral_sub\">Un estilo ligeramente más cromático que monocromático</string>\n    <string name=\"vibrant_sub\">Un tema ruidoso, el colorido es máximo para la paleta principal, aumentado para otras</string>\n    <string name=\"playful_scheme\">Un tema divertido: el tono del color de origen no aparece en el tema</string>\n    <string name=\"monochrome_sub\">Un tema monocromático, los colores son puramente negro/blanco/gris</string>\n    <string name=\"content_sub\">Un esquema que coloca el color de origen en Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Un esquema que es muy similar al esquema de contenido</string>\n    <string name=\"disabled\">Desactivado</string>\n    <string name=\"preview_pdf\">Vista previa de PDF</string>\n    <string name=\"pdf_to_images\">PDF a imágenes</string>\n    <string name=\"images_to_pdf\">Imágenes a PDF</string>\n    <string name=\"preview_pdf_sub\">Vista previa sencilla de PDF</string>\n    <string name=\"pdf_to_images_sub\">Convertir PDF a imágenes en un formato de salida determinado</string>\n    <string name=\"masks\">Máscaras</string>\n    <string name=\"add_mask\">Agregar máscara</string>\n    <string name=\"mask_indexed\">Máscara %d</string>\n    <string name=\"mask_preview\">Vista previa de máscara</string>\n    <string name=\"mask_preview_sub\">La máscara de filtro dibujada se representará para mostrarle el resultado aproximado</string>\n    <string name=\"delete_mask\">Eliminar máscara</string>\n    <string name=\"simple_variants\">Variantes simples</string>\n    <string name=\"highlighter\">Resaltador</string>\n    <string name=\"neon\">Neón</string>\n    <string name=\"pen\">Bolígrafo</string>\n    <string name=\"privacy_blur\">Desenfoque de privacidad</string>\n    <string name=\"neon_sub\">Añade un efecto brillante a tus dibujos</string>\n    <string name=\"pen_sub\">El predeterminado, el más simple: solo el color</string>\n    <string name=\"pixelation_sub\">Similar al desenfoque de privacidad, pero pixelado en lugar de desenfocado</string>\n    <string name=\"buttons_shadow\">Botones</string>\n    <string name=\"sliders_shadow_sub\">Dibuja una sombra detrás de los controles deslizantes</string>\n    <string name=\"switches_shadow_sub\">Dibuja una sombra detrás de los interruptores</string>\n    <string name=\"fabs_shadow_sub\">Dibuja una sombra detrás de los botones de acción flotantes</string>\n    <string name=\"buttons_shadow_sub\">Dibuja una sombra detrás de los botones</string>\n    <string name=\"app_bars_shadow\">Barras de aplicaciones</string>\n    <string name=\"app_bars_shadow_sub\">Dibuja una sombra detrás de las barras de la aplicación</string>\n    <string name=\"value_in_range\">Valor en el rango %1$s - %2$s</string>\n    <string name=\"double_line_arrow_sub\">Dibuja una flecha de doble punta desde el punto inicial hasta el punto final como una línea</string>\n    <string name=\"double_arrow_sub\">Dibuja una flecha de doble punta desde un camino determinado.</string>\n    <string name=\"outlined_rect\">Rectángulo delineado</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Recto</string>\n    <string name=\"outlined_oval_sub\">Dibuja un óvalo delineado desde el punto inicial hasta el punto final</string>\n    <string name=\"outlined_rect_sub\">Dibuja el rectángulo delineado desde el punto inicial hasta el punto final</string>\n    <string name=\"auto_pin_sub\">Agrega automáticamente la imagen guardada al portapapeles si está habilitado</string>\n    <string name=\"vibration_strength\">Fuerza de vibración</string>\n    <string name=\"nearest\">Más cercano</string>\n    <string name=\"spline\">Ranura</string>\n    <string name=\"catmull_sub\">Método para interpolar y remuestrear suavemente un conjunto de puntos de control, comúnmente utilizado en gráficos por computadora para crear curvas suaves</string>\n    <string name=\"hann_sub\">La función de ventana se aplica a menudo en el procesamiento de señales para minimizar la fuga espectral y mejorar la precisión del análisis de frecuencia al reducir los bordes de una señal</string>\n    <string name=\"hermite_sub\">Técnica de interpolación matemática que utiliza los valores y derivadas en los puntos finales de un segmento de curva para generar una curva suave y continua</string>\n    <string name=\"lanczos_sub\">Método de remuestreo que mantiene una interpolación de alta calidad aplicando una función de sincronización ponderada a los valores de los píxeles</string>\n    <string name=\"mitchell_sub\">Método de remuestreo que utiliza un filtro de convolución con parámetros ajustables para lograr un equilibrio entre nitidez y suavizado en la imagen escalada</string>\n    <string name=\"spline_sub\">Usa funciones polinomiales definidas por partes para interpolar y aproximar suavemente una curva o superficie, proporcionando una representación de forma flexible y continua</string>\n    <string name=\"recognize_text_sub\">Reconoce texto de una imagen determinada, admite más de 120 idiomas</string>\n    <string name=\"picture_has_no_text\">La imagen no tiene texto o la aplicación no la encontró</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Tipo de reconocimiento</string>\n    <string name=\"segmentation_mode\">Modo de segmentación</string>\n    <string name=\"saved_to_original\">Archivo sobrescrito con nombre %1$s en el destino original</string>\n    <string name=\"magnifier_sub\">Habilita la lupa en la parte superior del dedo en los modos de dibujo para una mejor accesibilidad</string>\n    <string name=\"force_exif_widget_initial_value\">Forzar valor inicial</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Obliga a que el widget exif se compruebe inicialmente</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Una sola columna</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Texto vertical de un solo bloque</string>\n    <string name=\"segmentation_mode_single_word\">Una sola palabra</string>\n    <string name=\"segmentation_mode_circle_word\">Palabra circular</string>\n    <string name=\"segmentation_mode_single_char\">Carácter único</string>\n    <string name=\"segmentation_mode_sparse_text\">Texto escaso</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Orientación de texto disperso &amp; Detección de secuencias de comandos</string>\n    <string name=\"segmentation_mode_raw_line\">Línea cruda</string>\n    <string name=\"delete_language_sub\">¿Desea eliminar los datos de entrenamiento de OCR de idioma \\\"%1$s\\\" para todos los tipos de reconocimiento o solo para uno seleccionado (%2$s)?</string>\n    <string name=\"properties\">Propiedades</string>\n    <string name=\"camera_sub\">Utiliza la cámara para tomar fotografías; tenga en cuenta que solo es posible obtener una imagen de esta fuente de imágenes</string>\n    <string name=\"repeat_watermark\">Repetir marca de agua</string>\n    <string name=\"repeat_watermark_sub\">Repite la marca de agua sobre la imagen en lugar de una sola en una posición determinada</string>\n    <string name=\"offset_x\">Desplazamiento X</string>\n    <string name=\"offset_y\">Compensación Y</string>\n    <string name=\"watermark_type\">Tipo de marca de agua</string>\n    <string name=\"watermarking_image_sub\">Esta imagen se utilizará como patrón para la marca de agua</string>\n    <string name=\"text_color\">Color de texto</string>\n    <string name=\"frame_delay\">Retraso de fotograma</string>\n    <string name=\"millis\">milis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"secure_mode_sub\">Oculta el contenido al salir, además la pantalla no se puede capturar ni grabar</string>\n    <string name=\"bayer_three_dithering\">Bayer tres por tres tramado</string>\n    <string name=\"sierra_lite_dithering\">Tramado de Sierra Lite</string>\n    <string name=\"atkinson_dithering\">Atkinson vacilante</string>\n    <string name=\"stucki_dithering\">Stucki vacilante</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falso Floyd Steinberg vacilante</string>\n    <string name=\"left_to_right_dithering\">Tramado de izquierda a derecha</string>\n    <string name=\"random_dithering\">Tramado aleatorio</string>\n    <string name=\"simple_threshold_dithering\">Tramado de umbral simple</string>\n    <string name=\"b_spline_sub\">Utiliza funciones polinómicas bicúbicas definidas por partes para interpolar y aproximar suavemente una curva o superficie, representación de forma flexible y continua</string>\n    <string name=\"corruption_shift_y\">Cambio de corrupción Y</string>\n    <string name=\"tent_blur\">Desenfoque de tienda</string>\n    <string name=\"side_fade\">Desvanecimiento lateral</string>\n    <string name=\"side\">Lado</string>\n    <string name=\"top\">Arriba</string>\n    <string name=\"bottom\">Abajo</string>\n    <string name=\"strength\">Fortaleza</string>\n    <string name=\"stroke_color\">Color del trazo</string>\n    <string name=\"amplitude\">Amplitud</string>\n    <string name=\"turbulence\">Turbulencia</string>\n    <string name=\"water_effect\">Efecto agua</string>\n    <string name=\"just_size\">Tamaño</string>\n    <string name=\"frequency_y\">Frecuencia Y</string>\n    <string name=\"simple_effects\">Efectos simples</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomalía</string>\n    <string name=\"deutaromaly\">Deuteranomalía</string>\n    <string name=\"protonomaly\">Protanomalía</string>\n    <string name=\"vintage\">Antiguo</string>\n    <string name=\"browni\">Brownie</string>\n    <string name=\"coda_chrome\">Coda Cromo</string>\n    <string name=\"night_vision\">Visión nocturna</string>\n    <string name=\"warm\">Cálido</string>\n    <string name=\"cool\">Fresco</string>\n    <string name=\"tritanopia\">Tritanopía</string>\n    <string name=\"deutaronotopia\">Deuteranopía</string>\n    <string name=\"protanopia\">Protanopía</string>\n    <string name=\"achromatomaly\">Acromatomalia</string>\n    <string name=\"achromatopsia\">Acromatopsia</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Neblina naranja</string>\n    <string name=\"autumn_tones\">Tonos de Otoño</string>\n    <string name=\"lavender_dream\">Sueño de lavanda</string>\n    <string name=\"cyberpunk\">Ciberpunk</string>\n    <string name=\"spectral_fire\">Fuego espectral</string>\n    <string name=\"night_magic\">Magia Nocturna</string>\n    <string name=\"fantasy_landscape\">Paisaje de fantasía</string>\n    <string name=\"color_explosion\">Explosión de color</string>\n    <string name=\"electric_gradient\">Gradiente eléctrico</string>\n    <string name=\"green_sun\">Sol verde</string>\n    <string name=\"rainbow_world\">Mundo arcoíris</string>\n    <string name=\"deep_purple\">Morado oscuro</string>\n    <string name=\"space_portal\">Portal espacial</string>\n    <string name=\"red_swirl\">Remolino rojo</string>\n    <string name=\"icon_shape\">Forma del icono</string>\n    <string name=\"transition\">Transición</string>\n    <string name=\"peak\">Cima</string>\n    <string name=\"color_anomaly\">Anomalía de color</string>\n    <string name=\"cannot_change_image_format\">No se puede cambiar el formato de imagen mientras la opción de sobrescribir archivos está habilitada</string>\n    <string name=\"emoji_as_color_scheme\">Emoji como combinación de colores</string>\n    <string name=\"emoji_as_color_scheme_sub\">Utiliza el color primario de emoji como combinación de colores de la aplicación en lugar de uno definido manualmente</string>\n    <string name=\"vertical\">Vertical</string>\n    <string name=\"images_order\">Orden de imágenes</string>\n    <string name=\"enhanced_diamond_pixelation\">Pixelación de diamantes mejorada</string>\n    <string name=\"erode\">Erosionar</string>\n    <string name=\"anisotropic_diffusion\">Difusión anisotrópica</string>\n    <string name=\"diffusion\">Difusión</string>\n    <string name=\"conduction\">Conducción</string>\n    <string name=\"horizontal_wind_stagger\">Escalonamiento del viento horizontal</string>\n    <string name=\"fractal_glass\">Vidrio fractal</string>\n    <string name=\"marble\">Mármol</string>\n    <string name=\"oil\">Aceite</string>\n    <string name=\"frequency_x\">Frecuencia X</string>\n    <string name=\"amplitude_x\">Amplitud X</string>\n    <string name=\"amplitude_y\">Amplitud Y</string>\n    <string name=\"perlin_distortion\">Distorsión Perlin</string>\n    <string name=\"hable_filmic_tone_mapping\">Mapeo de tonos fílmicos Hable</string>\n    <string name=\"heji_burgess_tone_mapping\">Mapeo de tonos de Hejl Burgess</string>\n    <string name=\"aces_filmic_tone_mapping\">Mapeo de tonos fílmicos de ACES</string>\n    <string name=\"aces_hill_tone_mapping\">Mapeo de tonos de colinas de ACES</string>\n    <string name=\"fast_bilaterial_blur\">Desenfoque bilateral rápido</string>\n    <string name=\"poisson_blur\">Desenfoque venenoso</string>\n    <string name=\"logarithmic_tone_mapping\">Mapeo de tonos logarítmicos</string>\n    <string name=\"crystallize\">Cristalizar</string>\n    <string name=\"current\">Actual</string>\n    <string name=\"all\">Todo</string>\n    <string name=\"full_filter\">Filtro completo</string>\n    <string name=\"start_position\">Comenzar</string>\n    <string name=\"center_position\">Centro</string>\n    <string name=\"end_position\">Fin</string>\n    <string name=\"full_filter_sub\">Aplique cualquier cadena de filtros a imágenes determinadas o a una sola imagen</string>\n    <string name=\"pdf_tools\">Herramientas PDF</string>\n    <string name=\"pdf_tools_sub\">Opere con archivos PDF: vista previa, convierta a un lote de imágenes o cree una a partir de imágenes determinadas</string>\n    <string name=\"images_to_pdf_sub\">Empaquetar las imágenes dadas en un archivo PDF de salida</string>\n    <string name=\"gradient_maker\">Creador de degradados</string>\n    <string name=\"gradient_maker_sub\">Cree un degradado de un tamaño de salida determinado con colores y tipos de apariencia personalizados</string>\n    <string name=\"speed\">Velocidad</string>\n    <string name=\"dehaze\">Desempañar</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"rate_app\">Calificar aplicacion</string>\n    <string name=\"rate\">Tasa</string>\n    <string name=\"rate_app_sub\">Esta aplicación es completamente gratuita, si quieres que crezca, estrella el proyecto en Github 😄</string>\n    <string name=\"color_matrix_4x4\">Matriz de colores 4x4</string>\n    <string name=\"color_matrix_3x3\">Matriz de colores 3x3</string>\n    <string name=\"gradient_type_linear\">Lineal</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Barrer</string>\n    <string name=\"gradient_type\">Tipo de gradiente</string>\n    <string name=\"center_x\">Centro X</string>\n    <string name=\"center_y\">Centro Y</string>\n    <string name=\"tile_mode\">Modo mosaico</string>\n    <string name=\"tile_mode_repeated\">Repetido</string>\n    <string name=\"tile_mode_mirror\">Espejo</string>\n    <string name=\"tile_mode_clamp\">Abrazadera</string>\n    <string name=\"tile_mode_decal\">Calcomanía</string>\n    <string name=\"color_stops\">Paradas de color</string>\n    <string name=\"add_color\">Agregar color</string>\n    <string name=\"double_line_arrow\">Flecha de doble línea</string>\n    <string name=\"draw_path_mode\">Modo dibujar ruta</string>\n    <string name=\"free_drawing\">Dibujo Gratis</string>\n    <string name=\"double_arrow\">Doble flecha</string>\n    <string name=\"line_arrow\">Flecha de línea</string>\n    <string name=\"arrow\">Flecha</string>\n    <string name=\"line\">Línea</string>\n    <string name=\"free_drawing_sub\">Dibuja la ruta como valor de entrada</string>\n    <string name=\"line_sub\">Dibuja la ruta desde el punto inicial hasta el punto final como una línea</string>\n    <string name=\"line_arrow_sub\">Dibuja una flecha que apunta desde el punto inicial al punto final como una línea</string>\n    <string name=\"arrow_sub\">Dibuja una flecha que apunta desde una ruta determinada.</string>\n    <string name=\"outlined_oval\">Ovalado delineado</string>\n    <string name=\"rect_sub\">Dibuja un rectángulo desde el punto inicial hasta el punto final</string>\n    <string name=\"oval_sub\">Dibuja un óvalo desde el punto inicial hasta el punto final</string>\n    <string name=\"dithering\">Tramado</string>\n    <string name=\"quantizier\">Cuantificador</string>\n    <string name=\"gray_scale\">Escala de grises</string>\n    <string name=\"bayer_two_dithering\">Bayer dos por dos tramado</string>\n    <string name=\"bayer_four_dithering\">Bayer cuatro por cuatro tramado</string>\n    <string name=\"bayer_eight_dithering\">Bayer ocho por ocho tramado</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg vacilante</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke vacilante</string>\n    <string name=\"sierra_dithering\">Sierra vacilante</string>\n    <string name=\"two_row_sierra_dithering\">Tramado Sierra de dos filas</string>\n    <string name=\"burkes_dithering\">Burkes vacilante</string>\n    <string name=\"mask_color\">Color de máscara</string>\n    <string name=\"scale_mode\">Modo de escala</string>\n    <string name=\"bilinear\">Bilineal</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Ermita</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"basic\">Básico</string>\n    <string name=\"default_value\">Valor por defecto</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma espacial</string>\n    <string name=\"median_blur\">Desenfoque mediano</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicúbico</string>\n    <string name=\"bilinear_sub\">La interpolación lineal (o bilineal, en dos dimensiones) suele ser buena para cambiar el tamaño de una imagen, pero causa cierto suavizado no deseado de los detalles y aún puede ser algo irregular</string>\n    <string name=\"bicubic_sub\">Los mejores métodos de escalado incluyen el remuestreo de Lanczos y los filtros Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Una de las formas más sencillas de aumentar el tamaño, sustituyendo cada píxel por varios píxeles del mismo color</string>\n    <string name=\"basic_sub\">El modo de escalado de Android más simple que se usa en casi todas las aplicaciones</string>\n    <string name=\"only_clip\">Sólo vídeo</string>\n    <string name=\"only_clip_sub\">No se guardará en el almacenamiento y se intentará colocar la imagen únicamente en el portapapeles</string>\n    <string name=\"icon_shape_sub\">Agrega un contenedor con la forma seleccionada debajo de los íconos principales de las tarjetas</string>\n    <string name=\"image_stitching\">Unión de imágenes</string>\n    <string name=\"image_stitching_sub\">Combina las imágenes dadas para obtener una grande</string>\n    <string name=\"brightness_enforcement\">Aplicación del brillo</string>\n    <string name=\"screen\">Pantalla</string>\n    <string name=\"gradient_maker_type_image\">Gradiente de superposición</string>\n    <string name=\"gradient_maker_type_image_sub\">Componga cualquier degradado en la parte superior de una imagen determinada</string>\n    <string name=\"transformations\">Transformaciones</string>\n    <string name=\"camera\">Cámara</string>\n    <string name=\"grain\">Grano</string>\n    <string name=\"unsharp\">Desenfocar</string>\n    <string name=\"pink_dream\">Sueño rosa</string>\n    <string name=\"golden_hour\">Hora dorada</string>\n    <string name=\"hot_summer\">Verano caluroso</string>\n    <string name=\"purple_mist\">Niebla Púrpura</string>\n    <string name=\"sunrise\">Amanecer</string>\n    <string name=\"colorful_swirl\">Remolino colorido</string>\n    <string name=\"soft_spring_light\">Luz suave de primavera</string>\n    <string name=\"lemonade_light\">Luz de limonada</string>\n    <string name=\"caramel_darkness\">Oscuridad del caramelo</string>\n    <string name=\"futuristic_gradient\">Degradado futurista</string>\n    <string name=\"digital_code\">Código digital</string>\n    <string name=\"watermarking\">Marca de agua</string>\n    <string name=\"watermarking_sub\">Cubra imágenes con marcas de agua de texto/imagen personalizables</string>\n    <string name=\"overlay_mode\">Modo de superposición</string>\n    <string name=\"pixel_size\">Tamaño de píxel</string>\n    <string name=\"lock_draw_orientation\">Bloquear la orientación del dibujo</string>\n    <string name=\"lock_draw_orientation_sub\">Si está habilitado en el modo de dibujo, la pantalla no rotará</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">Herramientas GIF</string>\n    <string name=\"gif_tools_sub\">Convierta imágenes a imágenes GIF o extraiga fotogramas de una imagen GIF determinada</string>\n    <string name=\"gif_type_to_image\">GIF a imágenes</string>\n    <string name=\"gif_type_to_image_sub\">Convertir un archivo GIF en un lote de imágenes</string>\n    <string name=\"gif_type_to_gif_sub\">Convertir lotes de imágenes a archivos GIF</string>\n    <string name=\"gif_type_to_gif\">Imágenes a GIF</string>\n    <string name=\"select_gif_image_to_start\">Elija una imagen GIF para comenzar</string>\n    <string name=\"use_size_of_first_frame\">Usar el tamaño del primer fotograma</string>\n    <string name=\"use_size_of_first_frame_sub\">Reemplace el tamaño especificado con las dimensiones del primer marco</string>\n    <string name=\"repeat_count\">Repetir recuento</string>\n    <string name=\"use_lasso\">Usar lazo</string>\n    <string name=\"use_lasso_sub\">Utiliza Lasso como en el modo de dibujo para realizar el borrado</string>\n    <string name=\"original_image_preview_alpha\">Vista previa de imagen original Alfa</string>\n    <string name=\"mask_filter\">Filtro de máscara</string>\n    <string name=\"mask_filter_sub\">Aplique cadenas de filtros en áreas enmascaradas determinadas, cada área de máscara puede determinar su propio conjunto de filtros</string>\n    <string name=\"random_emojis_sub\">El emoji de la barra de aplicaciones se cambiará continuamente de forma aleatoria en lugar de usar uno seleccionado</string>\n    <string name=\"random_emojis\">Emojis aleatorios</string>\n    <string name=\"random_emojis_error\">No se puede utilizar la selección aleatoria de emojis mientras los emojis estén desactivados</string>\n    <string name=\"emoji_selection_error\">No puedo seleccionar un emoji mientras se selecciona uno aleatorio habilitado</string>\n    <string name=\"check_for_updates\">Buscar actualizaciones</string>\n    <string name=\"old_tv\">Televisor viejo</string>\n    <string name=\"shuffle_blur\">Desenfoque aleatorio</string>\n    <string name=\"recognize_text\">OCR (reconocer texto)</string>\n    <string name=\"fast\">Rápido</string>\n    <string name=\"standard\">Estándar</string>\n    <string name=\"best\">Mejor</string>\n    <string name=\"no_data\">Sin datos</string>\n    <string name=\"download_description\">Para que Tesseract OCR funcione correctamente, es necesario descargar datos de entrenamiento adicionales (%1$s) en su dispositivo. \\n¿Desea descargar %2$s datos?</string>\n    <string name=\"download\">Descargar</string>\n    <string name=\"no_connection\">No hay conexión, compruébalo y vuelve a intentarlo para descargar los modelos de trenes</string>\n    <string name=\"downloaded_languages\">Idiomas descargados</string>\n    <string name=\"available_languages\">Idiomas Disponibles</string>\n    <string name=\"restore_background_sub\">El pincel restaurará el fondo en lugar de borrarlo</string>\n    <string name=\"horizontal_grid\">Cuadrícula horizontal</string>\n    <string name=\"vertical_grid\">Cuadrícula vertical</string>\n    <string name=\"stitch_mode\">Modo de puntada</string>\n    <string name=\"rows_count\">Recuento de filas</string>\n    <string name=\"columns_count\">Recuento de columnas</string>\n    <string name=\"use_pixel_switch\">Usar interruptor de píxeles</string>\n    <string name=\"use_pixel_switch_sub\">Utiliza un interruptor similar al de Google Pixel</string>\n    <string name=\"slide\">Deslizar</string>\n    <string name=\"side_by_side\">Lado a lado</string>\n    <string name=\"toggle_tap\">Alternar toque</string>\n    <string name=\"transparency\">Transparencia</string>\n    <string name=\"magnifier\">Lupa</string>\n    <string name=\"allow_multiple_languages\">Permitir varios idiomas</string>\n    <string name=\"favorite\">Favorito</string>\n    <string name=\"no_favorite_filters\">Aún no se han agregado filtros favoritos</string>\n    <string name=\"b_spline\">Estría B</string>\n    <string name=\"native_stack_blur\">Desenfoque de pila nativo</string>\n    <string name=\"tilt_shift\">Cambio de inclinación</string>\n    <string name=\"inverse_fill_type\">Tipo de relleno inverso</string>\n    <string name=\"inverse_fill_type_sub\">Si está habilitado, todas las áreas no enmascaradas se filtrarán en lugar del comportamiento predeterminado</string>\n    <string name=\"confetti\">Confeti</string>\n    <string name=\"confetti_sub\">Se mostrará confeti al guardar, compartir y otras acciones principales</string>\n    <string name=\"secure_mode\">Modo seguro</string>\n    <string name=\"pick_at_least_two_images\">Elige al menos 2 imágenes</string>\n    <string name=\"output_image_scale\">Escala de imagen de salida</string>\n    <string name=\"image_orientation\">Orientación de la imagen</string>\n    <string name=\"horizontal\">Horizontal</string>\n    <string name=\"scale_small_images_to_large\">Escalar imágenes pequeñas a grandes</string>\n    <string name=\"scale_small_images_to_large_sub\">Las imágenes pequeñas se escalarán a la más grande de la secuencia si está habilitada</string>\n    <string name=\"regular\">Regular</string>\n    <string name=\"circle_pixelation\">Pixelación de círculos</string>\n    <string name=\"enhanced_circle_pixelation\">Pixelación de círculos mejorada</string>\n    <string name=\"replace_color\">Reemplazar color</string>\n    <string name=\"tolerance\">Tolerancia</string>\n    <string name=\"auto_rotate_limits\">Auto rotar</string>\n    <string name=\"auto_rotate_limits_sub\">Permite adoptar un cuadro de límite para la orientación de la imagen</string>\n    <string name=\"palette_style\">Estilo de paleta</string>\n    <string name=\"tonal_spot\">Mancha tonal</string>\n    <string name=\"neutral\">Neutral</string>\n    <string name=\"vibrant\">Vibrante</string>\n    <string name=\"expressive\">Expresivo</string>\n    <string name=\"rainbow\">Arcoíris</string>\n    <string name=\"highlighter_sub\">Dibuja trazados de resaltado afilados y semitransparentes</string>\n    <string name=\"privacy_blur_sub\">Difumina la imagen debajo del camino dibujado para asegurar todo lo que quieras ocultar</string>\n    <string name=\"containers_shadow\">Contenedores</string>\n    <string name=\"containers_shadow_sub\">Dibuja una sombra detrás de los contenedores</string>\n    <string name=\"sliders_shadow\">Controles Deslizantes</string>\n    <string name=\"switches_shadow\">Interruptores</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"foss_update_checker_warning\">Este verificador de actualizaciones se conectará a GitHub para verificar si hay una nueva actualización disponible</string>\n    <string name=\"attention\">Atención</string>\n    <string name=\"fading_edges\">Bordes desvanecidos</string>\n    <string name=\"both\">Ambos</string>\n    <string name=\"invert_colors\">Colores invertidos</string>\n    <string name=\"invert_colors_sub\">Reemplaza los colores del tema por negativos si está habilitado</string>\n    <string name=\"exit\">Salir</string>\n    <string name=\"preview_closing\">Si sales de la vista previa ahora, tendrás que agregar las imágenes nuevamente</string>\n    <string name=\"lasso\">Lazo</string>\n    <string name=\"lasso_sub\">Dibuja un camino cerrado y lleno por un camino dado</string>\n    <string name=\"image_format\">Formato de imagen</string>\n    <string name=\"noise\">Ruido</string>\n    <string name=\"pixel_sort\">Ordenar píxeles</string>\n    <string name=\"anaglyph\">Anáglifo</string>\n    <string name=\"material_you_sub\">Crea la paleta \\\"Material You\\\" a partir de la imagen</string>\n    <string name=\"dark_colors\">Colores Oscuros</string>\n    <string name=\"dark_colors_sub\">Utiliza el esquema de color del modo nocturno en lugar de la variante de luz</string>\n    <string name=\"copy_as_compose_code\">Copiar como código \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Desenfoque de anillo</string>\n    <string name=\"cross_blur\">Desenfoque cruzado</string>\n    <string name=\"circle_blur\">Desenfoque de círculo</string>\n    <string name=\"star_blur\">Desenfoque de estrella</string>\n    <string name=\"linear_tilt_shift\">Cambio de inclinación lineal</string>\n    <string name=\"tags_to_remove\">Etiquetas Para Eliminar</string>\n    <string name=\"apng_type_to_apng\">Imágenes a APNG</string>\n    <string name=\"motion_blur\">Desenfoque de movimiento</string>\n    <string name=\"apng_tools\">Herramientas APNG</string>\n    <string name=\"apng_tools_sub\">Convierta imágenes a imágenes APNG o extraiga fotogramas de una imagen APNG determinada</string>\n    <string name=\"apng_type_to_image\">APNG a imágenes</string>\n    <string name=\"apng_type_to_image_sub\">Convierta un archivo APNG en un lote de imágenes</string>\n    <string name=\"apng_type_to_apng_sub\">Convertir lotes de imágenes a archivos APNG</string>\n    <string name=\"select_apng_image_to_start\">Elija la imagen APNG para comenzar</string>\n    <string name=\"zip\">Comprimir</string>\n    <string name=\"zip_sub\">Cree un archivo Zip a partir de archivos o imágenes determinados</string>\n    <string name=\"drag_handle_width\">Ancho del mango de arrastre</string>\n    <string name=\"festive\">Festivo</string>\n    <string name=\"rain\">Lluvia</string>\n    <string name=\"corners\">Esquinas</string>\n    <string name=\"jxl_tools\">Herramientas JXL</string>\n    <string name=\"jxl_tools_sub\">Realizar transcodificaciones JXL ~ JPEG sin pérdidas de calidad, o convertir animaciones GIF/APNG a JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL a JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Realizar transcodificaciones sin pérdida de JXL a JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Realizar transcodificaciones sin pérdida de JPEG a JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG a JXL</string>\n    <string name=\"select_jxl_image_to_start\">Elegir la imagen JXL para empezar</string>\n    <string name=\"format_conversion\">Convertir a formato</string>\n    <string name=\"fit_to_bounds\">Ajustar a márgenes</string>\n    <string name=\"languages_imported\">Idiomas importados con éxito</string>\n    <string name=\"backup_ocr_models\">Hacer copia de seguridad de los modelos OCR</string>\n    <string name=\"export\">Exportar</string>\n    <string name=\"position\">Position</string>\n    <string name=\"center\">Centro</string>\n    <string name=\"top_left\">Superior izquierda</string>\n    <string name=\"center_left\">Centro izquierda</string>\n    <string name=\"harmony_complementary\">Complementario</string>\n    <string name=\"color_shading\">Sombreado de color</string>\n    <string name=\"tones\">Tonos</string>\n    <string name=\"shades\">Tonos</string>\n    <string name=\"color_mixing\">Mezcla de color</string>\n    <string name=\"color_info\">Información de color</string>\n    <string name=\"selected_color\">Color seleccionado</string>\n    <string name=\"color_to_mix\">Color para mezclar</string>\n    <string name=\"celluloid\">Celuloide</string>\n    <string name=\"coffee\">Café</string>\n    <string name=\"greenish\">Verdoso</string>\n    <string name=\"confetti_type\">Tipo confeti</string>\n    <string name=\"manage_storage_extra_types\">Sin acceso completo a los archivos</string>\n    <string name=\"add_timestamp\">Añadir marca de tiempo</string>\n    <string name=\"color_blind_scheme\">Esquema daltónico</string>\n    <string name=\"draw_filter_sub\">Elige un filtro para usarlo como pintura</string>\n    <string name=\"replace_filter\">Reemplazar filtro</string>\n    <string name=\"try_again\">Intentar de nuevo</string>\n    <string name=\"add_new_folder\">Añadir nueva carpeta</string>\n    <string name=\"tag_bits_per_sample\">Bits por muestra</string>\n    <string name=\"tag_samples_per_pixel\">Muestras por píxel</string>\n    <string name=\"tag_datetime\">Fecha y hora</string>\n    <string name=\"tag_image_description\">Descripción de imagen</string>\n    <string name=\"tag_exif_version\">Versión EXIF</string>\n    <string name=\"tag_artist\">Artista</string>\n    <string name=\"tag_copyright\">Derecho de autor</string>\n    <string name=\"tag_color_space\">Espacio de color</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_user_comment\">Comentario de usuario</string>\n    <string name=\"tag_exposure_time\">Tiempo de exposición</string>\n    <string name=\"tag_shutter_speed_value\">Valor de velocidad de obturación</string>\n    <string name=\"tag_aperture_value\">Valor de apertura</string>\n    <string name=\"tag_brightness_value\">Valor de brillo</string>\n    <string name=\"tag_max_aperture_value\">Valor de apertura máximo</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_focal_length\">Distancia focal</string>\n    <string name=\"tag_file_source\">Archivo de origen</string>\n    <string name=\"tag_custom_rendered\">Renderizado personalizado</string>\n    <string name=\"tag_exposure_mode\">Modo de exposición</string>\n    <string name=\"tag_white_balance\">Balance de blancos</string>\n    <string name=\"tag_lens_model\">Modelo de lente</string>\n    <string name=\"tag_lens_specification\">Especificaciónd e lente</string>\n    <string name=\"tag_gps_altitude\">Altitud GPS</string>\n    <string name=\"tag_gps_status\">Estado GPS</string>\n    <string name=\"tag_lens_serial_number\">Número de serie de lente</string>\n    <string name=\"tag_gps_latitude\">Latitud GPS</string>\n    <string name=\"tag_gps_longitude\">Longitud GPS</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"recently_used\">Usados recientemente</string>\n    <string name=\"ci_channel\">Canal CI</string>\n    <string name=\"group\">Grupo</string>\n    <string name=\"image_toolbox_in_telegram\">ImageToolbox en Telegram 🎉</string>\n    <string name=\"font_size\">Tamaño de fuente</string>\n    <string name=\"watermark_size\">Tamaño de marca de agua</string>\n    <string name=\"custom_options\">Opciones personalizadas</string>\n    <string name=\"repeat_text\">Repetir texto</string>\n    <string name=\"document_scanner\">Escanear documento</string>\n    <string name=\"click_to_start_scanning\">Haz clic para empezar a escanear</string>\n    <string name=\"start_scanning\">Empezar a escanear</string>\n    <string name=\"cubic\">Cúbico</string>\n    <string name=\"mask\">Máscara</string>\n    <string name=\"enter_percentage\">Introducir porcentaje</string>\n    <string name=\"pick\">Elegir</string>\n    <string name=\"fullscreen_settings\">Ajustes de pantalla completa</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"pick_multiple_media\">Elegir múltiples archivos multimedia</string>\n    <string name=\"pick_single_media\">Elegir un único archivo multimedia</string>\n    <string name=\"triangle\">Triángulo</string>\n    <string name=\"polygon\">Polígono</string>\n    <string name=\"draw_regular_polygon\">Dibujar polígono regular</string>\n    <string name=\"star\">Estrella</string>\n    <string name=\"pixel_switch\">Píxel</string>\n    <string name=\"links_preview\">Vista previa de enlaces</string>\n    <string name=\"links\">Enlaces</string>\n    <string name=\"dismiss_forever\">Descartar para siempre</string>\n    <string name=\"linear\">Lineal</string>\n    <string name=\"header_today\">Hoy</string>\n    <string name=\"tools_arrangement\">Organización de herramientas</string>\n    <string name=\"group_tools_by_type\">Agrupar herramientas por tipo</string>\n    <string name=\"default_values\">Valores predeterminados</string>\n    <string name=\"hide_all\">Ocultar todos</string>\n    <string name=\"alignment\">Alineación</string>\n    <string name=\"channels_configuration\">Configuración de canales</string>\n    <string name=\"header_yesterday\">Ayer</string>\n    <string name=\"convert_sub\">Convertir lotes de imágenes a un formato dado</string>\n    <string name=\"tag_contrast\">Contraste</string>\n    <string name=\"tag_saturation\">Saturación</string>\n    <string name=\"vertices\">Vértices</string>\n    <string name=\"save_as_pdf\">Guardar como PDF</string>\n    <string name=\"share_as_pdf\">Compartir como PDF</string>\n    <string name=\"template_name\">Nombre de plantilla</string>\n    <string name=\"template_filter\">Filtro de plantilla</string>\n    <string name=\"as_qr_code\">Como imagen de código QR</string>\n    <string name=\"as_file\">Como archivo</string>\n    <string name=\"save_as_file\">Guardar como archivo</string>\n    <string name=\"save_as_qr_code_image\">Guardar como imagen de código QR</string>\n    <string name=\"delete_template\">Eliminar plantilla</string>\n    <string name=\"filter_preview\">Vista previa de filtro</string>\n    <string name=\"qr_code\">Código QR</string>\n    <string name=\"qr_description\">Descripción QR</string>\n    <string name=\"not_use_color_blind_scheme\">No utilices el esquema daltónico</string>\n    <string name=\"import_word\">Importar</string>\n    <string name=\"top_right\">Superior derecha</string>\n    <string name=\"bottom_left\">Inferior izquierda</string>\n    <string name=\"bottom_right\">Inferior derecha</string>\n    <string name=\"top_center\">Centro superior</string>\n    <string name=\"center_right\">Centro derecha</string>\n    <string name=\"bottom_center\">Centro inferior</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"add_favorites\">Añadir favoritos</string>\n    <string name=\"harmony_square\">Cuadrado</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Únete a nuestra conversación donde charlamos de todo lo que quieras y también échale un vistazo al canal CI donde publico versiones betas y comunicados</string>\n    <string name=\"ci_channel_sub\">Recibe notificaciones sobre nuevas versiones de la aplicación, y leer los comunicados</string>\n    <string name=\"show_all\">Mostrar todos</string>\n    <string name=\"hide_nav_bar\">Ocultar barra de navegación</string>\n    <string name=\"hide_status_bar\">Ocultar barra de estado</string>\n    <string name=\"frequency\">Frecuencia</string>\n    <string name=\"custom_filename\">Nombre de archivo personalizado</string>\n    <string name=\"custom_filename_sub\">Elige la ubicación y nombre de archivo que se usarán para guardar la imagen actual</string>\n    <string name=\"saved_to_custom\">Guardar en una carpeta con un nombre personalizado</string>\n    <string name=\"add_image\">Añadir imagen</string>\n    <string name=\"convert\">Convertir</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"gif_type_to_jxl\">GIF a JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG a JXL</string>\n    <string name=\"jxl_type_to_images\">JXL a Imágenes</string>\n    <string name=\"jxl_type_to_jxl\">Imágenes a JXL</string>\n    <string name=\"generate_previews\">Generar vistas previas</string>\n    <string name=\"lossy_compression\">Compresión sin pérdidas</string>\n    <string name=\"sorting\">Ordenar</string>\n    <string name=\"sort_by_date\">Ordenar por fecha</string>\n    <string name=\"sort_by_date_reversed\">Ordenar por fecha (Inversa)</string>\n    <string name=\"sort_by_name\">Ordenar por nombre</string>\n    <string name=\"sort_by_name_reversed\">Nombre (Inverso)</string>\n    <string name=\"reset_properties\">Restablecer propiedades</string>\n    <string name=\"detailed\">Detallado</string>\n    <string name=\"gif_type_to_webp\">GIF WEBP</string>\n    <string name=\"webp_tools\">Herramientas WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP a imágenes</string>\n    <string name=\"webp_type_to_webp_sub\">Convertir lote de imágenes a archivo WEBP</string>\n    <string name=\"webp_type_to_webp\">Imágenes a WEBP</string>\n    <string name=\"template\">Plantilla</string>\n    <string name=\"no_template_filters\">No se han añadido filtros de plantilla</string>\n    <string name=\"create_new\">Crear nuevo</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">El código QR escaneado no es una plantilla de filtro válida</string>\n    <string name=\"scan_qr_code\">Escanear código QR</string>\n    <string name=\"create_template\">Crear plantilla</string>\n    <string name=\"pop_art\">Arte pop</string>\n    <string name=\"add_timestamp_sub\">Permite añadir una marca de tiempo al nombre del archivo de salida</string>\n    <string name=\"tag_default_crop_size\">Tamaño de recorte predeterminado</string>\n    <string name=\"tag_orf_preview_image_length\">Longitud de previsualización de imagen</string>\n    <string name=\"tag_orf_aspect_frame\">Marco de aspecto</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Borde inferior de sensor</string>\n    <string name=\"tag_rw2_sensor_left_border\">Borde izquierdo de sensor</string>\n    <string name=\"tag_rw2_sensor_right_border\">Borde derecho de sensor</string>\n    <string name=\"tag_rw2_sensor_top_border\">Borde superior de sensor</string>\n    <string name=\"repeat_text_sub\">El texto actual se repetirá hasta el final de la ruta en lugar de una única vez</string>\n    <string name=\"dash_size\">Tamaño de guion</string>\n    <string name=\"document_scanner_sub\">Escanear documentos y crear PDF or separar las imágenes de ellos</string>\n    <string name=\"cubic_sub\">La interpolación cúbica proporciona un escalado más suave teniendo en cuenta los 16 píxeles más cercanos, otrogando mejores resultados que la interpolación bilinear</string>\n    <string name=\"quadric_sub\">Un método que utiliza una función cuadrática para la interpolación, proporcionando unos resultados más fluidos y continuos</string>\n    <string name=\"outlined_triangle\">Triángulo delineado</string>\n    <string name=\"triangle_sub\">Dibuja un triángulo delineado desde el punto inicial al punto final</string>\n    <string name=\"outlined_triangle_sub\">Dibuja un triángulo delineado desde el punto inicial al punto final</string>\n    <string name=\"outlined_polygon\">Polígono delineado</string>\n    <string name=\"star_sub\">Dibuja una estrella desde el punto inicial al punto final</string>\n    <string name=\"outlined_star_sub\">Dibuja una estrella delineada desde el punto inicial al punto final</string>\n    <string name=\"options_below_is_for_images\">Las siguientes opciones son para guardar imágenes, no PDF</string>\n    <string name=\"allow_enter_by_text_field\">Permitir Intro en el campo de texto</string>\n    <string name=\"opened_file_have_no_filter_template\">El archivo seleccionado no tiene datos de plantilla de filtro</string>\n    <string name=\"select_template_preview\">Se utilizará esta imagen para la vista previo de esta plantilla de filtro</string>\n    <string name=\"qr_code_sub\">Escanear código QR y obtén su contenido o pega tu cadena de texto para generar uno nuevo</string>\n    <string name=\"min\">Mín.</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Conceder el permiso de cámara desde ajustes para escanear el código QR</string>\n    <string name=\"gaussian_sub\">Un método de interpolación que aplica una función gaussiana, útil para la fluidez y reducción de ruido en las imágenes</string>\n    <string name=\"robidoux_sub\">Un método de interpolación de alta calidad optimizado para la redimensión natural de la imagen, con un equilibrio entre nitidez y suavidad</string>\n    <string name=\"antialias_sub\">Activa el antialiasing para evitar los bordes nítidos</string>\n    <string name=\"no_favorite_options_selected\">No se han seleccionado opciones favoritas, añádelas en la página de herramientas</string>\n    <string name=\"draw_mode_image_sub\">Utilizar la imagen seleccionada para dibujarla a lo largo de una ruta determinada</string>\n    <string name=\"polygon_sub\">Dibuja un polígono desde el punto inicial al punto final</string>\n    <string name=\"outlined_polygon_sub\">Dubija un polígono delineado desde el punto inicial al punto final</string>\n    <string name=\"draw_regular_polygon_sub\">Dibujar polígono que sea regular en lugar de forma libre</string>\n    <string name=\"outlined_star\">Estrella delineada</string>\n    <string name=\"inner_radius_ratio\">Proporción de radio interior</string>\n    <string name=\"draw_regular_star\">Dibujar estrella regular</string>\n    <string name=\"draw_regular_star_sub\">Dibujar estrella que sea regular en lugar de forma libre</string>\n    <string name=\"scale_color_space\">Escala de espacio de color</string>\n    <string name=\"grid_size_x\">Tamaño de parrilla en eje X</string>\n    <string name=\"grid_size_y\">Tamaño de parrilla en eje Y</string>\n    <string name=\"crop_to_content\">Recortar a contenido</string>\n    <string name=\"frame_color\">Color de marco</string>\n    <string name=\"color_to_ignore\">Color a ignorar</string>\n    <string name=\"open_edit_instead_of_preview\">Abrir Edición en lugar de Vista previa</string>\n    <string name=\"delete_template_warn\">Estás a punto de eliminar la plantilla de filtro seleccionada. Esta operación no se puede deshacer</string>\n    <string name=\"added_filter_template\">Añadir plantilla de filtro con nombre \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"scan_qr_code_to_replace_content\">Escanear código QR para reemplazar el contenido del campo, o escribe algo para generar un nuevo código QR</string>\n    <string name=\"tag_compression\">Compresión</string>\n    <string name=\"tag_resolution_unit\">Unidad de resolución</string>\n    <string name=\"tag_x_resolution\">Resolución X</string>\n    <string name=\"tag_y_resolution\">Resolución Y</string>\n    <string name=\"tag_transfer_function\">Función de transferencia</string>\n    <string name=\"default_line_width\">Anchura de línea predeterminada</string>\n    <string name=\"show_settings_in_landscape\">Mostrar ajustes en vista horizontal</string>\n    <string name=\"embedded_picker\">Selector integrado</string>\n    <string name=\"embedded_picker_sub\">Selector de imágenes de Image Toolbox</string>\n    <string name=\"no_permissions\">Sin permisos</string>\n    <string name=\"request\">Solicitar</string>\n    <string name=\"auto_paste\">Pegado automático</string>\n    <string name=\"auto_paste_sub\">Permite que la aplicación pegue automáticamente los datos del portapapeles, para que aparezcan en la pantalla principal y puedas procesarlos</string>\n    <string name=\"gif_type_to_jxl_sub\">Convertir imágenes GIF a fotografías animadas JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Convertir imágenes APNG a fotografías animadas JXL</string>\n    <string name=\"jxl_type_to_images_sub\">Convertir animación JXL a un lote de fotografías</string>\n    <string name=\"jxl_type_to_jxl_sub\">Convertir lote de fotografías a animación JXL</string>\n    <string name=\"skip_file_picking_sub\">El selector de archivos aparecerá inmediatamente, si es posible, en la pantalla elegida</string>\n    <string name=\"skip_file_picking\">Omitir selección de archivos</string>\n    <string name=\"compression_type\">Tipo de compresión</string>\n    <string name=\"images_to_svg\">Imágenes a SVG</string>\n    <string name=\"images_to_svg_sub\">Trazar imágenes dadas a imágenes SVG</string>\n    <string name=\"path_omit\">Omitir ruta</string>\n    <string name=\"downscale_image\">Reducir imagen</string>\n    <string name=\"downscale_image_sub\">Se reducirán las dimensiones de la imagen antes de procesarla, para permitir que la herramienta funcione de forma más rápida y segura</string>\n    <string name=\"min_color_ratio\">Relación de color mínima</string>\n    <string name=\"lines_threshold\">Umbral de líneas</string>\n    <string name=\"quadratic_threshold\">Umbral cuadrático</string>\n    <string name=\"reset_properties_sub\">Se restablecerán los valores predeterminados para todas las propiedades. Ten en cuenta que esta acción no se puede deshacer</string>\n    <string name=\"haasn_soft_sub\">Un filtro de remuestreo diseñado por Haasn para un escalado de imagen suave y sin artefactos</string>\n    <string name=\"enhanced_oil\">Aceite mejorado</string>\n    <string name=\"simple_old_tv\">Televisor viejo simple</string>\n    <string name=\"simple_sketch\">Boceto simple</string>\n    <string name=\"harmony_split_complementary\">Complemento de división</string>\n    <string name=\"color_tools\">Herramientas de color</string>\n    <string name=\"color_tools_sub\">Mezclar, hacer tonos, generar tonos y más</string>\n    <string name=\"color_harmonies\">Armonías de color</string>\n    <string name=\"variation\">Variación</string>\n    <string name=\"target_lut_image\">Imagen LUT objetivo</string>\n    <string name=\"soft_elegance\">Elegancia suave</string>\n    <string name=\"fall_colors\">Colores de otoño</string>\n    <string name=\"foggy_night\">Noche con niebla</string>\n    <string name=\"save_empty_lut\">Obtener imagen LUT neutral</string>\n    <string name=\"retro_yellow\">Amarillo retro</string>\n    <string name=\"target_image\">Imagen objetivo</string>\n    <string name=\"palette_transfer\">Transferencia de paleta</string>\n    <string name=\"edge_mode\">Modo de borde</string>\n    <string name=\"linear_box_blur\">Desenfoque linear de caja</string>\n    <string name=\"protanomaly_sub\">Dificultad para distinguir entre tonos rojos y verdes</string>\n    <string name=\"deuteranomaly_sub\">Dificultad para distinguir entre tonos verdes y rojos</string>\n    <string name=\"one_time_save_location\">Ubicación de un solo guardado</string>\n    <string name=\"tag_exposure_index\">Índice de exposición</string>\n    <string name=\"engine_mode\">Modo del motor</string>\n    <string name=\"tag_metering_mode\">Modo de medición</string>\n    <string name=\"tag_subject_distance_range\">Rango de distancia de sujeto</string>\n    <string name=\"format_conversion_sub\">Convertir lote de imágenes de un formato a otro</string>\n    <string name=\"image_stacking\">Apilamiento de imágenes</string>\n    <string name=\"tag_y_cb_cr_positioning\">Posicionamiento Y Cb Cr</string>\n    <string name=\"tag_make\">Hacer</string>\n    <string name=\"tag_spectral_sensitivity\">Sensibilidad espectral</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Longitud del formato de intercambio JPEG</string>\n    <string name=\"generate_previews_sub\">Permite la generación de vistas previas, lo que puede ayudar a evitar bloqueos en algunos dispositivos; sin embargo, esto también desactiva algunas funcionalidades de edición dentro de la opción de edición única.</string>\n    <string name=\"tag_digital_zoom_ratio\">Relación de zoom digital</string>\n    <string name=\"lossy_compression_sub\">Usa compresión con pérdida para reducir el tamaño del archivo en lugar de comprensión sin pérdida.</string>\n    <string name=\"tag_gps_measure_mode\">Modo de medición GPS</string>\n    <string name=\"tag_subject_distance\">Distancia de sujeto</string>\n    <string name=\"fluent_switch_sub\">Un interruptor basado en el sistema de diseño \\\"Fluent\\\"</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Bits comprimidos por pixel</string>\n    <string name=\"tag_spatial_frequency_response\">Respuesta de frecuencia espacial</string>\n    <string name=\"gap_size\">Tamaño de Espacio</string>\n    <string name=\"harmonization_color\">Armonización de Color</string>\n    <string name=\"use_sampled_palette_sub\">Paleta de cuantización será muestreada si está opción es activada</string>\n    <string name=\"tag_photographic_sensitivity\">Sensibilidad fotográfica</string>\n    <string name=\"fast_gaussian_blur_2d\">Desenfoque Gaussiano Rápido 2D</string>\n    <string name=\"default_draw_path_mode\">Modo predeterminado de ruta de dibujado</string>\n    <string name=\"tag_cfa_pattern\">Patrón CFA</string>\n    <string name=\"select_webp_image_to_start\">Selecciona imagen WEBP para comenzar</string>\n    <string name=\"image_stacking_sub\">Apilar imágenes una encima de otra con modos de fusión seleccionados</string>\n    <string name=\"tag_jpeg_interchange_format\">Formato de intercambio JPEG</string>\n    <string name=\"tag_datetime_original\">Hora y fecha original</string>\n    <string name=\"image_splitting\">División de imagen</string>\n    <string name=\"image_splitting_sub\">Dividir imagen única en filas y columnas</string>\n    <string name=\"cupertino_switch_sub\">Un interruptor basado en el sistema de diseño de \\\"Cupertino\\\"</string>\n    <string name=\"show_settings_in_landscape_sub\">Si se desactiva, en modo horizontal los ajustes serán abiertos en el botón en la barra de aplicaciones de arriba como siempre, en lugar de la opción permanentemente visible.</string>\n    <string name=\"tag_iso_speed\">Velocidad de ISO</string>\n    <string name=\"tag_gain_control\">Control de ganancia</string>\n    <string name=\"max\">Máximo</string>\n    <string name=\"resize_anchor\">Ancla de redimensionamiento</string>\n    <string name=\"tag_scene_capture_type\">Tipo de captura de escena</string>\n    <string name=\"black_hat\">Sombrero negro</string>\n    <string name=\"show_system_bars_by_swipe\">Muestra barras del sistema al deslizar</string>\n    <string name=\"tesseract_options_sub\">Aplica algunas variables de entrada para motor tesseract</string>\n    <string name=\"achromatopsia_sub\">Daltonismo completo, viendo solo tonos de gris</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Los colores serán exactos a los establecidos en el tema</string>\n    <string name=\"lanczos_6_sub\">Un filtro de remuestreo Lanczos con un orden más alto de 6, resultante en un escalado de imagen más preciso y nítido</string>\n    <string name=\"lanczos_6_jinc_sub\">Una variante del filtro Lanczos 6 usando una función Jinc para una mejor calidad de remuestreo de imagen</string>\n    <string name=\"linear_stack_blur\">Desenfoque apilado linear</string>\n    <string name=\"linear_fast_gaussian_blur\">Desenfoque Gaussiano linear rápido</string>\n    <string name=\"pick_filter_info\">Elige filtro de abajo para usarlos como pincel en tu dibujo</string>\n    <string name=\"third_color\">Tercer color</string>\n    <string name=\"tints\">Tintes</string>\n    <string name=\"soft_elegance_variant\">Variante de elegancia suave</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Permitir permiso de cámara en ajustes para escanear Escaneador de documentos</string>\n    <string name=\"gif_type_to_webp_sub\">Convertir imágenes GIF a imágenes animadas WEBP</string>\n    <string name=\"default_draw_color\">Color de dibujado predeterminado</string>\n    <string name=\"one_time_save_location_sub\">Ver y editar ubicaciones de un solo guardado que puedes usar al mantener presionado el botón de guardado en la mayoría de las opciones</string>\n    <string name=\"group_tools_by_type_sub\">Agrupar herramientas en la pantalla principal por su tipo en lugar de una lista de personalizada de orden</string>\n    <string name=\"system_bars_visibility\">Visibilidad de barras del sistema</string>\n    <string name=\"noise_generation\">Generación de ruido</string>\n    <string name=\"gain\">Ganancia</string>\n    <string name=\"weighted_strength\">Fuerza medida</string>\n    <string name=\"distance_function\">Función de distancia</string>\n    <string name=\"return_type\">Tipo de retorno</string>\n    <string name=\"collage_maker_sub\">Crea collages de hasta 20 imágenes</string>\n    <string name=\"collage_type\">Tipo de collage</string>\n    <string name=\"collages_info\">Mantiene presionada la imagen para intercambiar, mover y hacer zoom para ajustar posición</string>\n    <string name=\"histogram_sub\">Histograma de RGB o brillo de imagen para ayudarte a hacer ajustes</string>\n    <string name=\"auto_crop\">Recorte automático</string>\n    <string name=\"morphological_gradient\">Gradiente morfológica</string>\n    <string name=\"explode\">Explotar</string>\n    <string name=\"fast_gaussian_blur_3d\">Desenfoque Gaussiano Rápido 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Desenfoque Gaussiano Rápido 4D</string>\n    <string name=\"harmonization_level\">Armonización de Nivel</string>\n    <string name=\"lanczos_bessel_sub\">Método de remuestreo que mantiene una interpolación de alta calidad al aplicar una función de Bessel (jinc) a los valores de los pixeles</string>\n    <string name=\"fullscreen_settings_sub\">Al activar la página de ajustes será siempre abierta en pantalla completa en lugar de un panel deslizante.</string>\n    <string name=\"switch_type\">Tipo de interruptor</string>\n    <string name=\"material_you_switch_sub\">Un interruptor basado en Material You</string>\n    <string name=\"use_sampled_palette\">Usa paleta de muestreo</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolerancia en el redondeo de las coordenadas</string>\n    <string name=\"legacy\">Legado</string>\n    <string name=\"lstm_network\">Red de LSTM</string>\n    <string name=\"legacy_and_lstm\">Legado y LSTM</string>\n    <string name=\"tag_photometric_interpretation\">Interpretación fotométrica</string>\n    <string name=\"tag_planar_configuration\">Configuración planar</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Submuestreo Y Cb Cr</string>\n    <string name=\"tag_related_sound_file\">Archivo de audio relacionado</string>\n    <string name=\"tag_sensitivity_type\">Tipo de sensibilidad</string>\n    <string name=\"tag_recommended_exposure_index\">Índice de exposiciones recomendadas</string>\n    <string name=\"tag_subject_area\">Área de sujeto</string>\n    <string name=\"tag_flash_energy\">Energía de flash</string>\n    <string name=\"tag_focal_plane_x_resolution\">Resolución de plano focal X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Resolución de plano focal Y</string>\n    <string name=\"tag_sensing_method\">Método de detección</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Plano focal en película de 35mm</string>\n    <string name=\"tag_sharpness\">Nitidez</string>\n    <string name=\"tag_image_unique_id\">ID único de imagen</string>\n    <string name=\"tag_camera_owner_name\">Nombre del propietario de cámara</string>\n    <string name=\"tag_gps_speed\">Velocidad de GPS</string>\n    <string name=\"noise_generation_sub\">Generar diferentes tipos de ruidos como Perlin u otros tipos</string>\n    <string name=\"noise_type\">Tipo de ruido</string>\n    <string name=\"rotation_type\">Tipo de rotación</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Unidad de resolución de plano focal</string>\n    <string name=\"tiff_compression_scheme\">Esquema de comprensión TIFF</string>\n    <string name=\"links_preview_sub\">Activa la recuperación de vista previa de enlaces en lugares donde puedes obtener texto (QRCode, OCR, etc)</string>\n    <string name=\"image_for_histogram\">Esta imagen será utilizada para generar histogramas de RGB y brillo</string>\n    <string name=\"tone_curves\">Curvas de tono</string>\n    <string name=\"reset_curves\">Restablecer curvas</string>\n    <string name=\"tag_body_serial_number\">Número serial de cuerpo</string>\n    <string name=\"ginseng_sub\">Un filtro de remuestreo diseñado para procesamiento de imagen de alta calidad con un buen balance de nitidez y suavidad</string>\n    <string name=\"color_blind_scheme_sub\">Selecciona modo para adaptar colores de tema según la variante de daltonismo dada</string>\n    <string name=\"achromatomaly_sub\">Sensibilidad reducida a todos los colores</string>\n    <string name=\"wrap\">Envolver</string>\n    <string name=\"tritanomaly_sub\">Dificultad para distinguir entre tonos azules y amarillos</string>\n    <string name=\"protanopia_sub\">Incapacidad para percibir tonos rojos</string>\n    <string name=\"tritanopia_sub\">Incapacidad para percibir tonos azules</string>\n    <string name=\"soft_glow\">Brillo suave</string>\n    <string name=\"sand_painting\">Pintura de arena</string>\n    <string name=\"fit_to_bounds_sub\">Combina modo de redimensionamiento de recorte con este parámetro para obtener el comportamiento deseado(Recortar/Ajustar a la relación de aspecto)</string>\n    <string name=\"candlelight\">Luz de vela</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Habilita deslizar para mostrar barras de sistema si están ocultas</string>\n    <string name=\"fractal_type\">Tipo de fractal</string>\n    <string name=\"histogram\">Histograma</string>\n    <string name=\"free_corners\">Esquinas libres</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">Las opciones deben ser ingresadas siguiendo este patrón: \\\"--{option_name} {valor}\\\"</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Los puntos no estarán limitados por los límites de imagen, es útil para correcciones más precisas de perspectivas</string>\n    <string name=\"free_corners_sub\">Recorta imagen por polígono, esto también corrige la perspectiva</string>\n    <string name=\"spot_heal_sub\">Relleno según contenido bajo dibujado de ruta</string>\n    <string name=\"stamped\">Estampado</string>\n    <string name=\"opening\">Abriendo</string>\n    <string name=\"line_style\">Estilo de línea</string>\n    <string name=\"palette_transfer_variant\">Variante de transferencia de paleta</string>\n    <string name=\"tag_white_point\">Punto Blanco</string>\n    <string name=\"tag_model\">Modelo</string>\n    <string name=\"behavior\">Comportamiento</string>\n    <string name=\"deuteranopia_sub\">Incapacidad para percibir tonos verdes</string>\n    <string name=\"speed_sub\">Controla la velocidad de decodificación de la imagen resultante, esto debería ayudar a abrir la imagen resultante más rápido, un valor de %1$s significa en la decodificación mas lenta, mientras %2$s es la más rápida, esta configuración puede aumentar el tamaño de la imagen de salida.</string>\n    <string name=\"save_empty_lut_sub\">Primero, usa tu aplicación de edición de imágenes favorita para aplicar un filtro al LUT neutral el cual puedes obtener aquí. Para que esto funcione cada color de pixel no debe depender de otros pixeles (por ejemplo, el desenfoque no funcionará). Una vez listo, usa tu nueva imagen LUT como entrada para tu filtro LUT 512*512.</string>\n    <string name=\"path_scale\">Escala de ruta</string>\n    <string name=\"linear_gaussian_blur\">Desenfoque Gaussiano linear</string>\n    <string name=\"tag_subject_location\">Ubicación de sujeto</string>\n    <string name=\"svg_warning\">El uso de esta herramienta para trazar imágenes grandes sin reducir su escala no es recomendable, puede causar bloqueos y aumentar tiempo de procesamiento.</string>\n    <string name=\"fit_description\">Ajustar una imagen a las dimensiones dadas y aplicar desenfoque o colorear fondo</string>\n    <string name=\"fluent_switch\">Fluido</string>\n    <string name=\"tag_device_setting_description\">Descripción de ajustes de dispositivo</string>\n    <string name=\"reset_curves_sub\">Las curvas serán reestablecidas al valor predeterminado</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Cuando seleccionas una imagen para abrir (vista previa) en ImageToolbox, la hoja de selección de edición se abrirá en vez de mostrar la vista previa</string>\n    <string name=\"barcodes_sub\">Escanea cualquier código de barras (QR, EAN, AZTEC, …) y obtén su contenido o pega tu texto para generar uno nuevo</string>\n    <string name=\"lanczos2_jinc_sub\">Una variante del filtro Lanczos 2 que usa la función jinc, proveyendo interpolación de alta calidad con distorsiones mínimas</string>\n    <string name=\"compose_switch_sub\">Un interruptor Jetpack Compose Material You</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"liquid_glass\">Liquid Glass</string>\n    <string name=\"liquid_glass_sub\">Un interruptor basado en el recientemente anunciado IOS 26 y su sistema de diseño \\\"liquid glass\\\"</string>\n    <string name=\"pick_image_or_base64\">Selecciona una imagen o pega/importa datos Base64 debajo</string>\n    <string name=\"paste_link\">Pegar link</string>\n    <string name=\"kaleidoscope\">Caleidoscopio</string>\n    <string name=\"type_image_link\">Escribe en enlace de la imagen para comenzar</string>\n    <string name=\"secondary_angle\">Ángulo secundario</string>\n    <string name=\"sides\">Lados</string>\n    <string name=\"bottom_to_top\">Abajo a Arriba</string>\n    <string name=\"top_to_bottom\">Arriba a Abajo</string>\n    <string name=\"right_to_left\">Derecha a Izquierda</string>\n    <string name=\"left_to_right\">Izquierda a Derecha</string>\n    <string name=\"sort_by_size\">Tamaño</string>\n    <string name=\"sort_by_size_reversed\">Tamaño (Inverso)</string>\n    <string name=\"sort_by_mime_type\">Tipo MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Tipo MIME (Inverso)</string>\n    <string name=\"sort_by_extension\">Extensión</string>\n    <string name=\"sort_by_extension_reversed\">Extensión (Inverso)</string>\n    <string name=\"layout\">Diseño</string>\n    <string name=\"sort_by_date_added\">Fecha de Adición</string>\n    <string name=\"sort_by_date_added_reversed\">Fecha de Adición (Inverso)</string>\n    <string name=\"blue_green\">Azul Verdoso</string>\n    <string name=\"red_blue\">Rojo Azul</string>\n    <string name=\"green_red\">Verde Rojo</string>\n    <string name=\"into_red\">En rojo</string>\n    <string name=\"cyan\">Cian</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Amarillo</string>\n    <string name=\"color_halftone\">Color Semitono</string>\n    <string name=\"contour\">Contorno</string>\n    <string name=\"levels\">Niveles</string>\n    <string name=\"shape\">Forma</string>\n    <string name=\"stretch\">Estirar</string>\n    <string name=\"randomness\">Aleatoriedad</string>\n    <string name=\"despeckle\">Destramar</string>\n    <string name=\"diffuse\">Difuminar</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_maker_note\">Nota del creador</string>\n    <string name=\"second_radius\">Segundo radio</string>\n    <string name=\"equalize\">Igualar</string>\n    <string name=\"whirl_and_pinch\">Girar y Pellizcar</string>\n    <string name=\"pointillize\">Puntillizar</string>\n    <string name=\"border_color\">Color del borde</string>\n    <string name=\"polar_coordinates\">Coordenadas Polares</string>\n    <string name=\"rect_to_polar\">Rect a Polar</string>\n    <string name=\"polar_to_rect\">Polar a Rect</string>\n    <string name=\"reduce_noise\">Reducir Ruido</string>\n    <string name=\"simple_solarize\">Solarizar Simple</string>\n    <string name=\"x_width\">Ancho X</string>\n    <string name=\"y_wdth\">Ancho Y</string>\n    <string name=\"twirl\">Molinete</string>\n    <string name=\"smear\">Emborronar</string>\n    <string name=\"density\">Densidad</string>\n    <string name=\"mix\">Mix</string>\n    <string name=\"sphere_lensh_distortion\">Distorsión de Lentes en esfera</string>\n    <string name=\"refraction_index\">Índice de refracción</string>\n    <string name=\"spread_angle\">Ángulo de dispersión</string>\n    <string name=\"rays\">Rayos</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradiente</string>\n    <string name=\"crash_title\">Oops… Algo salió mal</string>\n    <string name=\"crash_subtitle\">Me puedes contactar usando las opciones de debajo e intentaré encontrar una solución.\\n(No te olvides de adjuntar logs/registros)</string>\n    <string name=\"ocr_write_to_file\">Escribir a archivo</string>\n    <string name=\"password\">Contraseña</string>\n    <string name=\"unlock\">Desbloquear</string>\n    <string name=\"pdf_is_protected\">El PDF está protegido</string>\n    <string name=\"operation_almost_complete\">Operación casi completada. Si cancelas ahora, será necesario reiniciarla</string>\n    <string name=\"sort_by_date_modified\">Fecha de Modificación</string>\n    <string name=\"sort_by_date_modified_reversed\">Fecha de Modificación (Inversa)</string>\n    <string name=\"bspline_sub\">Utiliza funciones polinómicas definidas por tramos para interpolar suavemente y aproximar una curva o superficie, lo que permite una representación flexible y continua de la forma</string>\n    <string name=\"hamming_sub\">Una función de ventana usada para reducir el manchado espectral mediante el estrechamiento de los bordes de una señal, útil en procesamiento de señales</string>\n    <string name=\"hanning_sub\">Una variante de la ventana de Hann, usada comúnmente para reducir el manchado espectral en aplicaciones de procesamiento de señales</string>\n    <string name=\"blackman_sub\">Una función ventana que provee buena resolución de frecuencia buena al minimizar el manchado espectral, utilizada a menudo en procesamiento de señales</string>\n    <string name=\"welch_sub\">Una función ventana diseñada para dar buena resolución de frecuencia con un manchado espectral reducido, generalmente usada en aplicaciones de procesamiento de señales</string>\n    <string name=\"sphinx_sub\">Un método avanzado de remuestreo que ofrece una interpolación de alta calidad con artefactos mínimos</string>\n    <string name=\"bartlett_sub\">Una función triangular usada en procesamiento de señales para reducir el manchado espectral</string>\n    <string name=\"robidoux_sharp_sub\">Una variante más nítida del método Robidoux, optimizada para el redimensionamiento de imágenes nítidas.</string>\n    <string name=\"spline16_sub\">Un método de interpolación basado en splines que proporciona resultados suaves utilizando un filtro 16-tap</string>\n    <string name=\"spline36_sub\">Un método de interpolación basado en splines que proporciona resultados suaves utilizando un filtro 36-tap</string>\n    <string name=\"spline64_sub\">Un método de interpolación basado en splines que proporciona resultados suaves utilizando un filtro 64-tap</string>\n    <string name=\"kaiser_sub\">Un método de interpolación que utiliza la ventana (función) de Kaiser, proporcionando un buen control sobre la compensación entre la anchura del lóbulo principal y el nivel del lóbulo lateral</string>\n    <string name=\"bartlett_hann_sub\">Una función de ventana híbrida que combina las ventanas de Barlett y Hann, utilizada para reducir el manchado espectral en procesamiento de señales</string>\n    <string name=\"box_sub\">Un método simple de remuestreo que usa el promedio de los valores de los píxeles más cercanos, a menudo resulta en una apariencia pixelada</string>\n    <string name=\"enable_timestamps_to_format_them\">Habilita las marcas de tiempo para seleccionar su formato</string>\n    <string name=\"webp_type_to_image_sub\">Convierte un archivo WEBP a lotes de imágenes</string>\n    <string name=\"golden_forest\">Bosque Dorado</string>\n    <string name=\"webp_tools_sub\">Convierte imágenes a imágenes WEBP animadas o extrae frames de un archivo WEBP animado dado</string>\n    <string name=\"ico_size_warning\">Los archivos ICO sólo pueden ser guardados con tamaño máximo de 256 x 256</string>\n    <string name=\"manage_storage_extra_types_sub\">Permite acceso a todos los archivos para ver JXL, QOI y otras imágenes que no son reconocidas como imágenes en Android. Sin los permisos, Image Toolbox no podrá mostrar esas imágenes</string>\n    <string name=\"formatted_timestamp\">Marca de tiempo con formato</string>\n    <string name=\"formatted_timestamp_sub\">Habilita el formateo de marcas de tiempo (Timestamps) en el nombre del archivo de salida, en lugar de milisegundos básicos</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"octaves\">Octavas</string>\n    <string name=\"lacunarity\">Lacunaridad</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"collage_maker\">Creador de Collage</string>\n    <string name=\"tesseract_options\">Opciones de Tesseract</string>\n    <string name=\"domain_warp\">Warp de Dominio</string>\n    <string name=\"coerce_points_to_image_bounds\">Limitar Puntos a Bordes de Imagen</string>\n    <string name=\"closing\">Cerrando</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Dibuja una línea discontinua a lo largo de la ruta trazada, con el tamaño de separación especificado</string>\n    <string name=\"dashed\">Rayado</string>\n    <string name=\"dot_dashed\">Punteado</string>\n    <string name=\"dot_dashed_sub\">Dibuja una línea discontinua con puntos y rayas, a lo largo de una trayectoria dada</string>\n    <string name=\"defaultt_sub\">Las líneas rectas por defecto</string>\n    <string name=\"stamped_sub\">Dibuja las formas seleccionadas a lo largo de la ruta, con un espaciado especificado</string>\n    <string name=\"zigzag_sub\">Dibuja un zigzag ondulado a lo largo del recorrido</string>\n    <string name=\"zigzag_ratio\">Ratio del Zigzag</string>\n    <string name=\"create_shortcut\">Crear Atajo</string>\n    <string name=\"create_shortcut_title\">Elige que herramienta fijar</string>\n    <string name=\"create_shortcut_subtitle\">La herramienta será añadida a la pantalla de inicio de tu launcher como un atajo. Utilízala junto con la configuración \\\"Omitir selección de archivos\\\" para conseguir el comportamiento deseado</string>\n    <string name=\"dont_stack_frames\">No apilar frames</string>\n    <string name=\"dont_stack_frames_sub\">Habilita deshacerse de frames previos, de modo que no se amontonen unos sobre otros</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Los frames se fundirán entre sí</string>\n    <string name=\"crossfade_count\">Recuento de frames fundidos/sobrepuestos</string>\n    <string name=\"threshold_one\">Umbral Uno</string>\n    <string name=\"threshold_two\">Umbral Dos</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Espejo 101</string>\n    <string name=\"enhanced_zoom_blur\">Desenfoque de Zoom Mejorado</string>\n    <string name=\"laplacian_simple\">Laplaciano Simple</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Cuadrícula de Ayuda</string>\n    <string name=\"helper_grid_sub\">Muestra una cuadrícula de apoyo sobre el área de dibujo para facilitar manipulaciones precisas</string>\n    <string name=\"grid_color\">Color de la Cuadrícula</string>\n    <string name=\"cell_width\">Ancho de Celda</string>\n    <string name=\"cell_height\">Altura de Celda</string>\n    <string name=\"compact_selectors\">Selectores Compactos</string>\n    <string name=\"compact_selectors_sub\">Algunos controles de selección usarán un diseño compacto para tomar menos espacio</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Conceda permiso a la cámara en ajustes para capturar la imagen</string>\n    <string name=\"main_screen_title\">Título de la Pantalla Principal</string>\n    <string name=\"constant_rate_factor\">Constant Rate Factor (CRF)</string>\n    <string name=\"crf_sub\">Un valor de %1$s significa una compresión lenta, resultando en un tamaño de archivo relativamente pequeño. %2$s significa una compresión más rápida, resultando en un archivo grande/más pesado.</string>\n    <string name=\"lut_library\">Biblioteca LUT</string>\n    <string name=\"lut_library_sub\">Descarga una colección de LUTs, que puedes aplicar tras la descarga</string>\n    <string name=\"lut_library_update_sub\">Actualizar colección de LUTs (sólo los nuevos serán puestos en la cola), los cuales puedes aplicar tras la descarga</string>\n    <string name=\"filter_preview_image_sub\">Cambia la imagen de vista previa por defecto para filtros</string>\n    <string name=\"filter_preview_image\">Imagen de Vista Previa</string>\n    <string name=\"hide\">Ocultar</string>\n    <string name=\"show\">Mostrar</string>\n    <string name=\"slider_type\">Tipo de Slider</string>\n    <string name=\"fancy\">Fancy</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy_sub\">Un slider con aspecto elegante. Esta es la opción predeterminada</string>\n    <string name=\"material_2_sub\">Un slider Material 2</string>\n    <string name=\"material_you_slider_sub\">Un slider Material You</string>\n    <string name=\"apply\">Aplicar</string>\n    <string name=\"center_align_dialog_buttons\">Centrar Botones de Diálogo</string>\n    <string name=\"center_align_dialog_buttons_sub\">Los botones de los cuadros de diálogo serán posicionados en el centro, en lugar de a la izquierda, si es posible</string>\n    <string name=\"open_source_licenses\">Licencias Open Source</string>\n    <string name=\"open_source_licenses_sub\">Ver licencias de librerías open source usadas en esta app</string>\n    <string name=\"area\">Área</string>\n    <string name=\"area_sub\">Remuestreo utilizando la relación del área de píxeles. Puede ser un método preferido para la reducción de imágenes, ya que ofrece resultados sin moiré. Sin embargo, cuando se amplía la imagen, es similar al método \\\"Más cercano\\\"</string>\n    <string name=\"enable_tonemapping\">Habilitar Mapeo de Tonos</string>\n    <string name=\"enter_percent\">Introduzca %</string>\n    <string name=\"unknown_host\">No se puede acceder al sitio, intenta usar una VPN o comprueba si la url es correcta</string>\n    <string name=\"markup_layers\">Capas de Marcado</string>\n    <string name=\"markup_layers_sub\">Modo de capas con la habilidad de colocar libremente imágenes, texto y más</string>\n    <string name=\"edit_layer\">Editar capa</string>\n    <string name=\"layers_on_image\">Capas en Imagen</string>\n    <string name=\"layers_on_image_sub\">Usa una imagen como fondo y añade diferentes capas sobre ella</string>\n    <string name=\"layers_on_background\">Capas en el fondo</string>\n    <string name=\"layers_on_background_sub\">Lo mismo que la primera opción pero con color en lugar de una imagen</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Acceso a Configuración Lateral</string>\n    <string name=\"fast_settings_side_sub\">Añade una barra flotante en el lado seleccionado mientras editas imágenes, la cual abrirá los ajustes rápidos al clickear en ella</string>\n    <string name=\"clear_selection\">Borrar selección</string>\n    <string name=\"checksum_as_filename\">Checksum como nombre de archivo</string>\n    <string name=\"checksum_as_filename_sub\">El nombre de las imágenes de salida se corresponderá al checksum de datos de la imagen</string>\n    <string name=\"checksum_tools\">Herramientas de Checksum</string>\n    <string name=\"checksum_tools_sub\">Compara checksums, calcular hashes o crear cadenas hexadecimales de archivos, usando diferentes algoritmos de hashing</string>\n    <string name=\"checksum\">Checksum</string>\n    <string name=\"pick_file_to_checksum\">Elige el archivo para calcular su checksum basado en el algoritmo seleccionado</string>\n    <string name=\"enter_text_to_checksum\">Introduce un texto para calcular su checksum, basado en el algoritmo seleccionado</string>\n    <string name=\"source_checksum\">Checksum de Origen</string>\n    <string name=\"checksum_to_compare\">Checksum a Comparar</string>\n    <string name=\"match_sub\">Los checksums son iguales, es seguro</string>\n    <string name=\"difference_sub\">Los Checksums no son iguales, el archivo puede no ser seguro!</string>\n    <string name=\"pick_files_to_checksum\">Selecciona el/los archivo(s) para calcular su checksum basado en el algoritmo seleccionado</string>\n    <string name=\"tag_strip_offsets\">Desplazamientos de tiras</string>\n    <string name=\"tag_rows_per_strip\">Filas por tira</string>\n    <string name=\"tag_strip_byte_counts\">Recuentos de bytes de eliminación</string>\n    <string name=\"tag_primary_chromaticities\">Cromaticidades primarias</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Coeficientes Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">Referencia Negro Blanco</string>\n    <string name=\"tag_flashpix_version\">Versión Flashpix</string>\n    <string name=\"tag_pixel_x_dimension\">Dimensión del píxel X</string>\n    <string name=\"tag_pixel_y_dimension\">Dimensión Y del píxel</string>\n    <string name=\"tag_datetime_digitized\">Fecha Hora Digitalizada</string>\n    <string name=\"tag_offset_time\">Tiempo de compensación</string>\n    <string name=\"tag_offset_time_original\">Hora de compensación original</string>\n    <string name=\"tag_offset_time_digitized\">Hora de compensación digitalizada</string>\n    <string name=\"tag_subsec_time\">Tiempo subseg.</string>\n    <string name=\"tag_subsec_time_original\">Tiempo subseg. Original</string>\n    <string name=\"tag_subsec_time_digitized\">Hora subseg. digitalizada</string>\n    <string name=\"tag_f_number\">Número F</string>\n    <string name=\"tag_exposure_program\">Programa de exposición</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_standard_output_sensitivity\">Sensibilidad de salida estándar</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Velocidad ISO Latitud yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Velocidad ISO Latitud zzz</string>\n    <string name=\"tag_exposure_bias_value\">Valor de sesgo de exposición</string>\n    <string name=\"tag_lens_make\">Marca de lente</string>\n    <string name=\"tag_gps_version_id\">ID de versión de GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Referencia de latitud GPS</string>\n    <string name=\"tag_gps_longitude_ref\">Referencia de longitud GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Referencia de altitud GPS</string>\n    <string name=\"tag_gps_timestamp\">Marca de tiempo GPS</string>\n    <string name=\"tag_gps_satellites\">Satélites GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Referencia de velocidad GPS</string>\n    <string name=\"tag_gps_track_ref\">Referencia de seguimiento GPS</string>\n    <string name=\"tag_gps_track\">Seguimiento GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Referencia de dirección de imagen GPS</string>\n    <string name=\"tag_gps_img_direction\">Dirección de imagen GPS</string>\n    <string name=\"tag_gps_map_datum\">Dato del mapa GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitud Ref</string>\n    <string name=\"tag_gps_dest_latitude\">Latitud del destino del GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitud Ref</string>\n    <string name=\"tag_gps_dest_longitude\">Longitud del destino del GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Referencia de rumbo de destino GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Rumbo de destino GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Referencia de distancia de destino GPS</string>\n    <string name=\"tag_gps_dest_distance\">Distancia de destino GPS</string>\n    <string name=\"tag_gps_processing_method\">Método de procesamiento GPS</string>\n    <string name=\"tag_gps_area_information\">Información del área GPS</string>\n    <string name=\"tag_gps_datestamp\">Sello de fecha GPS</string>\n    <string name=\"tag_gps_differential\">Diferencial GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Error de posicionamiento GPS H</string>\n    <string name=\"tag_interoperability_index\">Índice de interoperabilidad</string>\n    <string name=\"tag_dng_version\">Versión DNG</string>\n    <string name=\"tag_orf_preview_image_start\">Vista previa de imagen Inicio</string>\n    <string name=\"draw_text_sub\">Dibuja texto en el camino con la fuente y el color dados</string>\n    <string name=\"draw_image_sub\">Esta imagen se utilizará como entrada repetitiva del camino dibujado.</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"equalize_histogram_hsv\">Ecualizar histograma HSV</string>\n    <string name=\"equalize_histogram\">Ecualizar histograma</string>\n    <string name=\"allow_enter_by_text_field_sub\">Habilita el campo de texto detrás de la selección de ajustes preestablecidos, para ingresarlos sobre la marcha</string>\n    <string name=\"equalize_histogram_pixelation\">Ecualizar pixelación de histograma</string>\n    <string name=\"equalize_histogram_adaptive\">Ecualizar histograma adaptativo</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Ecualizar histograma LUV adaptativo</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Ecualizar histograma adaptativo LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">LABORATORIO CLAHE</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"code_content\">Contenido del código</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">hammam</string>\n    <string name=\"hanning\">hanning</string>\n    <string name=\"blackman\">hombre negro</string>\n    <string name=\"welch\">galés</string>\n    <string name=\"quadric\">cuadrico</string>\n    <string name=\"gaussian\">gaussiano</string>\n    <string name=\"sphinx\">Esfinge</string>\n    <string name=\"bartlett\">bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux afilado</string>\n    <string name=\"spline16\">Línea 16</string>\n    <string name=\"spline36\">Estría 36</string>\n    <string name=\"spline64\">Estría 64</string>\n    <string name=\"kaiser\">Emperador</string>\n    <string name=\"bartlett_hann\">Bartlett-Él</string>\n    <string name=\"box\">Caja</string>\n    <string name=\"bohman\">bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"bohman_sub\">Una función de ventana utilizada para reducir la fuga espectral, proporcionando una buena resolución de frecuencia en aplicaciones de procesamiento de señales.</string>\n    <string name=\"lanczos2_sub\">Un método de remuestreo que utiliza un filtro Lanczos de 2 lóbulos para una interpolación de alta calidad con artefactos mínimos</string>\n    <string name=\"lanczos3_sub\">Un método de remuestreo que utiliza un filtro Lanczos de 3 lóbulos para una interpolación de alta calidad con artefactos mínimos</string>\n    <string name=\"lanczos4_sub\">Un método de remuestreo que utiliza un filtro Lanczos de 4 lóbulos para una interpolación de alta calidad con artefactos mínimos</string>\n    <string name=\"lanczos3_jinc_sub\">Una variante del filtro Lanczos 3 que utiliza la función jinc, lo que proporciona una interpolación de alta calidad con artefactos mínimos.</string>\n    <string name=\"lanczos4_jinc_sub\">Una variante del filtro Lanczos 4 que utiliza la función jinc, lo que proporciona una interpolación de alta calidad con artefactos mínimos.</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Variante de media ponderada elíptica (EWA) del filtro Hanning para una interpolación y un remuestreo suaves</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Variante de media ponderada elíptica (EWA) del filtro Robidoux para remuestreo de alta calidad</string>\n    <string name=\"ewa_blackman\">Eva negra</string>\n    <string name=\"ewa_blackman_sub\">Variante de promedio ponderado elíptico (EWA) del filtro Blackman para minimizar los artefactos de timbre</string>\n    <string name=\"ewa_quadric\">EWA cuádrico</string>\n    <string name=\"ewa_quadric_sub\">Variante de promedio ponderado elíptico (EWA) del filtro cuádrico para una interpolación suave</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Variante de promedio ponderado elíptico (EWA) del filtro Robidoux Sharp para obtener resultados más nítidos</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Variante de media ponderada elíptica (EWA) del filtro Lanczos 3 Jinc para remuestreo de alta calidad con alias reducido</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Variante de media ponderada elíptica (EWA) del filtro Ginseng para mejorar la calidad de imagen</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Variante de promedio ponderado elíptico (EWA) del filtro Lanczos Sharp para lograr resultados nítidos con artefactos mínimos</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA más nítidos</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Variante de promedio ponderado elíptico (EWA) del filtro Lanczos 4 Sharpest para un remuestreo de imágenes extremadamente nítido</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Suave EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Variante de media ponderada elíptica (EWA) del filtro Lanczos Soft para un remuestreo de imágenes más fluido</string>\n    <string name=\"haasn_soft\">Haasn suave</string>\n    <string name=\"bins_count\">Recuento de contenedores</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Ecualizar histograma HSL adaptativo</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Ecualizar histograma HSV adaptativo</string>\n    <string name=\"clip\">Acortar</string>\n    <string name=\"sigmoidal\">sigmoideo</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Un filtro de interpolación de Lagrange de orden 2, adecuado para escalado de imágenes de alta calidad con transiciones suaves</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Un filtro de interpolación de Lagrange de orden 3, que ofrece mayor precisión y resultados más fluidos para el escalado de imágenes.</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"linear_tent_blur\">Desenfoque de tienda lineal</string>\n    <string name=\"linear_gaussian_box_blur\">Desenfoque de caja gaussiana lineal</string>\n    <string name=\"gaussian_box_blur\">Desenfoque de caja gaussiano</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Desenfoque gaussiano rápido lineal Siguiente</string>\n    <string name=\"low_poly\">Poli baja</string>\n    <string name=\"gotham\">ciudad gótica</string>\n    <string name=\"color_poster\">Color Póster</string>\n    <string name=\"tri_tone\">Tritono</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Lunares</string>\n    <string name=\"clustered_2x2_dithering\">Tramado 2x2 agrupado</string>\n    <string name=\"clustered_4x4_dithering\">Tramado 4x4 agrupado</string>\n    <string name=\"clustered_8x8_dithering\">Tramado agrupado de 8x8</string>\n    <string name=\"yililoma_dithering\">Yililoma vacilante</string>\n    <string name=\"harmony_analogous\">Análogo</string>\n    <string name=\"harmony_triadic\">triádico</string>\n    <string name=\"harmony_tetradic\">Tetrádica</string>\n    <string name=\"harmony_analogous_complementary\">Análogo + Complementario</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">No se puede usar Monet mientras los colores dinámicos están activados</string>\n    <string name=\"amatorka\">un aficionado</string>\n    <string name=\"miss_etikate\">Señorita etiqueta</string>\n    <string name=\"target_cube_lut_file\">Archivo LUT 3D de destino (.cube / .CUBE)</string>\n    <string name=\"bleach_bypass\">Bypass de blanqueador</string>\n    <string name=\"drop_blues\">soltar blues</string>\n    <string name=\"edgy_amber\">Ámbar nervioso</string>\n    <string name=\"film_stock_50\">Material de película 50</string>\n    <string name=\"ping_pong_strength\">Fuerza del ping pong</string>\n    <string name=\"disable_rotation\">Desactivar rotación</string>\n    <string name=\"disable_rotation_sub\">Evita la rotación de imágenes con gestos con dos dedos.</string>\n    <string name=\"enable_snapping_to_borders\">Habilitar el ajuste a los bordes</string>\n    <string name=\"enable_snapping_to_borders_sub\">Después de moverlas o hacer zoom, las imágenes se ajustarán para llenar los bordes del marco.</string>\n    <string name=\"spot_heal\">Punto de curación</string>\n    <string name=\"use_circle_kernel\">Usar núcleo circular</string>\n    <string name=\"top_hat\">Sombrero de copa</string>\n    <string name=\"settings_group_visibility_hidden\">El grupo de configuración \\\"%1$s\\\" se contraerá de forma predeterminada</string>\n    <string name=\"settings_group_visibility_visible\">El grupo de configuración \\\"%1$s\\\" se expandirá de forma predeterminada</string>\n    <string name=\"base_64_tools\">Herramientas Base64</string>\n    <string name=\"base_64_tools_sub\">Decodificar cadena Base64 en imagen o codificar imagen en formato Base64</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">El valor proporcionado no es una cadena Base64 válida</string>\n    <string name=\"copy_not_a_valid_base_64\">No se puede copiar una cadena Base64 vacía o no válida</string>\n    <string name=\"paste_base_64\">Pegar Base64</string>\n    <string name=\"copy_base_64\">Copiar Base64</string>\n    <string name=\"base_64_tips\">Cargue la imagen para copiar o guardar la cadena Base64. Si tiene la cadena en sí, puede pegarla arriba para obtener la imagen.</string>\n    <string name=\"save_base_64\">Guardar Base64</string>\n    <string name=\"share_base_64\">Compartir Base64</string>\n    <string name=\"options\">Opciones</string>\n    <string name=\"actions\">Comportamiento</string>\n    <string name=\"import_base_64\">Importar Base64</string>\n    <string name=\"base_64_actions\">Acciones Base64</string>\n    <string name=\"add_outline\">Agregar esquema</string>\n    <string name=\"add_outline_sub\">Agregar contorno alrededor del texto con color y ancho especificados</string>\n    <string name=\"outline_color\">Color del contorno</string>\n    <string name=\"outline_size\">Tamaño del contorno</string>\n    <string name=\"rotation\">Rotación</string>\n    <string name=\"free_software_partner\">Software gratuito (socio)</string>\n    <string name=\"free_software_partner_sub\">Más software útil en el canal de socios de aplicaciones de Android</string>\n    <string name=\"algorithms\">Algoritmo</string>\n    <string name=\"calculate\">Calcular</string>\n    <string name=\"text_hash\">Hash de texto</string>\n    <string name=\"match\">¡Fósforo!</string>\n    <string name=\"difference\">Diferencia</string>\n    <string name=\"mesh_gradients\">Degradados de malla</string>\n    <string name=\"collection_mesh_gradients_sub\">Mire la colección en línea de degradados de malla</string>\n    <string name=\"wrong_font\">Sólo se pueden importar fuentes TTF y OTF</string>\n    <string name=\"import_font\">Importar fuente (TTF/OTF)</string>\n    <string name=\"export_fonts\">Exportar fuentes</string>\n    <string name=\"imported_fonts\">Fuentes importadas</string>\n    <string name=\"error_while_saving\">Error al guardar el intento, intente cambiar la carpeta de salida</string>\n    <string name=\"filename_is_not_set\">El nombre del archivo no está configurado</string>\n    <string name=\"none\">Ninguno</string>\n    <string name=\"custom_pages\">Páginas personalizadas</string>\n    <string name=\"pages_selection\">Selección de páginas</string>\n    <string name=\"tool_exit_confirmation\">Confirmación de salida de herramienta</string>\n    <string name=\"tool_exit_confirmation_sub\">Si tiene cambios no guardados mientras usa herramientas particulares e intenta cerrarlas, se mostrará el cuadro de diálogo de confirmación.</string>\n    <string name=\"edit_exif_screen\">Editar EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Cambiar metadatos de una sola imagen sin recomprimir</string>\n    <string name=\"edit_exif_tag\">Toque para editar las etiquetas disponibles</string>\n    <string name=\"change_sticker\">Cambiar pegatina</string>\n    <string name=\"fit_width\">Ancho de ajuste</string>\n    <string name=\"fit_height\">Altura de ajuste</string>\n    <string name=\"batch_compare\">Comparación por lotes</string>\n    <string name=\"pick_files\">Seleccionar archivos</string>\n    <string name=\"pick_directory\">Seleccionar directorio</string>\n    <string name=\"head_length_scale\">Escala de longitud de la cabeza</string>\n    <string name=\"stamp\">Estampilla</string>\n    <string name=\"timestamp\">Marca de tiempo</string>\n    <string name=\"format_pattern\">Patrón de formato</string>\n    <string name=\"padding\">Relleno</string>\n    <string name=\"image_cutting\">Corte de imagen</string>\n    <string name=\"image_cutting_sub\">Corte la parte de la imagen y combine las de la izquierda (puede ser al revés) mediante líneas verticales u horizontales.</string>\n    <string name=\"vertical_pivot_line\">Línea de pivote vertical</string>\n    <string name=\"horizontal_pivot_line\">Línea de pivote horizontal</string>\n    <string name=\"inverse_selection\">Selección inversa</string>\n    <string name=\"inverse_vertical_selection_sub\">La parte cortada vertical se dejará, en lugar de fusionar partes alrededor del área cortada.</string>\n    <string name=\"inverse_horizontal_selection_sub\">La parte cortada horizontal se dejará, en lugar de fusionar partes alrededor del área cortada.</string>\n    <string name=\"collection_mesh_gradients\">Colección de degradados de malla</string>\n    <string name=\"mesh_gradients_sub\">Cree un degradado de malla con una cantidad personalizada de nudos y resolución</string>\n    <string name=\"gradient_maker_type_image_mesh\">Superposición de degradado de malla</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Componer gradiente de malla de la parte superior de las imágenes dadas</string>\n    <string name=\"points_customization\">Personalización de puntos</string>\n    <string name=\"grid_size\">Tamaño de cuadrícula</string>\n    <string name=\"resolution_x\">Resolución X</string>\n    <string name=\"resolution_y\">Resolución Y</string>\n    <string name=\"resolution\">Resolución</string>\n    <string name=\"pixel_by_pixel\">Píxel por píxel</string>\n    <string name=\"highlight_color\">Color de resaltado</string>\n    <string name=\"pixel_comparison_type\">Tipo de comparación de píxeles</string>\n    <string name=\"scan_barcode\">escanear código de barras</string>\n    <string name=\"height_ratio\">Relación de altura</string>\n    <string name=\"barcode_type\">Tipo de código de barras</string>\n    <string name=\"enforce_bw\">Aplicar B/N</string>\n    <string name=\"enforce_bw_sub\">La imagen del código de barras será completamente en blanco y negro y no estará coloreada por el tema de la aplicación.</string>\n    <string name=\"no_barcode_found\">No se encontró ningún código de barras</string>\n    <string name=\"generated_barcode_will_be_here\">El código de barras generado estará aquí</string>\n    <string name=\"audio_cover_extractor\">Cubiertas de audio</string>\n    <string name=\"audio_cover_extractor_sub\">Extraiga imágenes de portadas de álbumes de archivos de audio; se admiten los formatos más comunes</string>\n    <string name=\"pick_audio_to_start\">Elige audio para comenzar</string>\n    <string name=\"pick_audio\">Elige audio</string>\n    <string name=\"no_covers_found\">No se encontraron portadas</string>\n    <string name=\"send_logs\">Enviar registros</string>\n    <string name=\"send_logs_sub\">Haga clic para compartir el archivo de registros de la aplicación. Esto puede ayudarme a detectar el problema y solucionarlo.</string>\n    <string name=\"ocr_write_to_file_sub\">Extraiga texto de un lote de imágenes y guárdelo en un archivo de texto</string>\n    <string name=\"ocr_write_to_metadata\">Escribir en metadatos</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extraer texto de cada imagen y añadirlo a sus datos EXIF</string>\n    <string name=\"invisible_mode\">Modo invisible</string>\n    <string name=\"invisible_mode_sub\">Utilice la esteganografía para crear marcas de agua invisibles a los ojos dentro de bytes de sus imágenes</string>\n    <string name=\"use_lsb\">Usar LSB</string>\n    <string name=\"use_lsb_sub\">Se utilizará el método de esteganografía LSB (bit menos significativo); en caso contrario, FD (dominio de frecuencia).</string>\n    <string name=\"auto_remove_red_eyes\">Eliminación automática de ojos rojos</string>\n    <string name=\"channel_mix\">Mezcla de canales</string>\n    <string name=\"into_green\">En verde</string>\n    <string name=\"into_blue\">En azul</string>\n    <string name=\"offset\">Compensar</string>\n    <string name=\"voronoi_crystallize\">Voronoi cristalizar</string>\n    <string name=\"dog\">Perro</string>\n    <string name=\"glow\">Brillo</string>\n    <string name=\"invert_in_circle\">invertir en círculo</string>\n    <string name=\"weave\">Tejer</string>\n    <string name=\"x_gap\">X brecha</string>\n    <string name=\"y_gap\">Brecha Y</string>\n    <string name=\"rubber_stmp\">Sello de goma</string>\n    <string name=\"arc\">Arco</string>\n    <string name=\"sparkle\">Brillar</string>\n    <string name=\"moire\">María</string>\n    <string name=\"autumn\">Otoño</string>\n    <string name=\"bone\">Hueso</string>\n    <string name=\"jet\">Chorro</string>\n    <string name=\"winter\">Invierno</string>\n    <string name=\"ocean\">Océano</string>\n    <string name=\"summer\">Verano</string>\n    <string name=\"spring\">Primavera</string>\n    <string name=\"cool_variant\">Variante genial</string>\n    <string name=\"hsv\">VHS</string>\n    <string name=\"pink\">Rosa</string>\n    <string name=\"hot\">Caliente</string>\n    <string name=\"parula\">Palabra</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Infierno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Ciudadanos</string>\n    <string name=\"twilight\">Crepúsculo</string>\n    <string name=\"twilight_shifted\">Crepúsculo cambiado</string>\n    <string name=\"auto_perspective\">Perspectiva automática</string>\n    <string name=\"deskew\">alinear</string>\n    <string name=\"allow_crop\">Permitir recorte</string>\n    <string name=\"crop_or_perspective\">Cultivo o perspectiva</string>\n    <string name=\"absolute\">Absoluto</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">verde intenso</string>\n    <string name=\"lens_correction\">Corrección de lentes</string>\n    <string name=\"target_lens_profile\">Archivo de perfil de lente de destino en formato JSON</string>\n    <string name=\"download_ready_lens_profiles\">Descargar perfiles de lentes listos</string>\n    <string name=\"part_percents\">Porcentajes parciales</string>\n    <string name=\"export_as_json\">Exportar como JSON</string>\n    <string name=\"export_as_json_sub\">Copie la cadena con datos de una paleta como representación json</string>\n    <string name=\"seam_carving\">Tallado de costura</string>\n    <string name=\"home_screen\">Pantalla de inicio</string>\n    <string name=\"lock_screen\">Pantalla de bloqueo</string>\n    <string name=\"built_in\">Incorporado</string>\n    <string name=\"wallpapers_export\">Exportación de fondos de pantalla</string>\n    <string name=\"refresh\">Refrescar</string>\n    <string name=\"wallpapers_export_sub\">Obtenga fondos de pantalla actuales de Inicio, Bloqueo e Integrados</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Permitir el acceso a todos los archivos, esto es necesario para recuperar fondos de pantalla</string>\n    <string name=\"allow_read_media_images_for_wp\">Administrar el permiso de almacenamiento externo no es suficiente, debe permitir el acceso a sus imágenes, asegúrese de seleccionar \\\"Permitir todo\\\"</string>\n    <string name=\"add_preset_to_filename\">Agregar preset al nombre de archivo</string>\n    <string name=\"add_preset_to_filename_sub\">Agrega el sufijo con el ajuste preestablecido seleccionado al nombre del archivo de imagen</string>\n    <string name=\"add_image_scale_mode_to_filename\">Agregar modo de escala de imagen al nombre de archivo</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Agrega el sufijo con el modo de escala de imagen seleccionado al nombre del archivo de imagen</string>\n    <string name=\"ascii_art\">Arte Ascii</string>\n    <string name=\"ascii_art_sub\">Convierta una imagen a texto ascii que se verá como una imagen</string>\n    <string name=\"params\">parámetros</string>\n    <string name=\"invert_colors_ascii_sub\">Aplica un filtro negativo a la imagen para obtener mejores resultados en algunos casos.</string>\n    <string name=\"processing_screenshot\">Procesando captura de pantalla</string>\n    <string name=\"screenshot_not_captured_try_again\">Captura de pantalla no capturada, inténtalo de nuevo</string>\n    <string name=\"skipped_saving\">Guardado omitido</string>\n    <string name=\"skipped_saving_multiple\">%1$s archivos omitidos</string>\n    <string name=\"allow_skip_if_larger\">Permitir omitir si es más grande</string>\n    <string name=\"allow_skip_if_larger_sub\">Algunas herramientas podrán omitir el guardado de imágenes si el tamaño del archivo resultante fuera mayor que el original.</string>\n    <string name=\"qr_type_calendar_event\">Evento del calendario</string>\n    <string name=\"qr_type_contact_info\">Contacto</string>\n    <string name=\"qr_type_email\">Correo electrónico</string>\n    <string name=\"qr_type_geo_point\">Ubicación</string>\n    <string name=\"qr_type_phone\">Teléfono</string>\n    <string name=\"qr_type_plain\">Texto</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wifi</string>\n    <string name=\"open_network\">Red abierta</string>\n    <string name=\"not_specified\">N / A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Teléfono</string>\n    <string name=\"message\">Mensaje</string>\n    <string name=\"address\">DIRECCIÓN</string>\n    <string name=\"subject\">Sujeto</string>\n    <string name=\"body\">Cuerpo</string>\n    <string name=\"name\">Nombre</string>\n    <string name=\"organization\">Organización</string>\n    <string name=\"title\">Título</string>\n    <string name=\"phones\">Teléfonos</string>\n    <string name=\"emails\">Correos electrónicos</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Direcciones</string>\n    <string name=\"summary\">Resumen</string>\n    <string name=\"description\">Descripción</string>\n    <string name=\"location\">Ubicación</string>\n    <string name=\"organizer\">Organizador</string>\n    <string name=\"start_date\">Fecha de inicio</string>\n    <string name=\"end_date\">Fecha de finalización</string>\n    <string name=\"status\">Estado</string>\n    <string name=\"latitude\">Latitud</string>\n    <string name=\"longitude\">Longitud</string>\n    <string name=\"create_barcode\">Crear código de barras</string>\n    <string name=\"edit_barcode\">Editar código de barras</string>\n    <string name=\"wifi_configuration\">configuración wifi</string>\n    <string name=\"security\">Seguridad</string>\n    <string name=\"pick_contact\">Escoger contacto</string>\n    <string name=\"grant_contact_permission\">Otorgar permiso a los contactos en la configuración para que se completen automáticamente usando el contacto seleccionado</string>\n    <string name=\"contact_info\">Información de contacto</string>\n    <string name=\"first_name\">Nombre de pila</string>\n    <string name=\"middle_name\">Segundo nombre</string>\n    <string name=\"last_name\">Apellido</string>\n    <string name=\"pronunciation\">Pronunciación</string>\n    <string name=\"add_phone\">Agregar teléfono</string>\n    <string name=\"add_email\">Agregar correo electrónico</string>\n    <string name=\"add_address\">Agregar dirección</string>\n    <string name=\"website\">Sitio web</string>\n    <string name=\"add_website\">Agregar sitio web</string>\n    <string name=\"formatted_name\">Nombre formateado</string>\n    <string name=\"qr_code_top_image\">Esta imagen se utilizará para colocar encima del código de barras.</string>\n    <string name=\"code_customization\">Personalización del código</string>\n    <string name=\"qr_logo_image\">Esta imagen se utilizará como logotipo en el centro del código QR.</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Acolchado con logotipo</string>\n    <string name=\"logo_size\">Tamaño del logotipo</string>\n    <string name=\"logo_corners\">Esquinas del logotipo</string>\n    <string name=\"fourth_eye\">Cuarto ojo</string>\n    <string name=\"fourth_eye_description\">Agrega simetría de ojo al código qr agregando un cuarto ojo en la esquina inferior</string>\n    <string name=\"pixel_shape\">Forma de píxel</string>\n    <string name=\"frame_shape\">Forma del marco</string>\n    <string name=\"ball_shape\">forma de bola</string>\n    <string name=\"error_correction_level\">Nivel de corrección de errores</string>\n    <string name=\"dark_color\">color oscuro</string>\n    <string name=\"light_color\">color claro</string>\n    <string name=\"hyper_os\">Hipersistema operativo</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS le gusta el estilo</string>\n    <string name=\"mask_pattern\">Patrón de máscara</string>\n    <string name=\"code_may_be_not_scannable\">Es posible que este código no se pueda escanear. Cambie los parámetros de apariencia para que sea legible en todos los dispositivos.</string>\n    <string name=\"not_scannable\">No escaneable</string>\n    <string name=\"launcher_mode_sub\">Las herramientas se parecerán al iniciador de aplicaciones de la pantalla de inicio y serán más compactos</string>\n    <string name=\"launcher_mode\">Modo lanzador</string>\n    <string name=\"flood_fill_sub\">Rellena un área con el pincel y el estilo seleccionados</string>\n    <string name=\"flood_fill\">Relleno de inundación</string>\n    <string name=\"spray\">Pulverización</string>\n    <string name=\"spray_sub\">Dibuja un camino con estilo graffiti.</string>\n    <string name=\"square_particles\">Partículas cuadradas</string>\n    <string name=\"square_particles_sub\">Las partículas de pulverización tendrán forma cuadrada en lugar de círculos.</string>\n    <string name=\"palette_tools\">Herramientas de paleta</string>\n    <string name=\"palette_tools_sub\">Genere su paleta básica/material a partir de una imagen, o importe/exporte a través de diferentes formatos de paleta</string>\n    <string name=\"edit_palette\">Editar paleta</string>\n    <string name=\"edit_palette_sub\">Exportar/importar paleta en varios formatos</string>\n    <string name=\"color_name\">Nombre del color</string>\n    <string name=\"palette_name\">Nombre de la paleta</string>\n    <string name=\"palette_format\">Formato de paleta</string>\n    <string name=\"export_palette_sub\">Exportar paleta generada a diferentes formatos.</string>\n    <string name=\"add_color_palette_sub\">Agrega un nuevo color a la paleta actual</string>\n    <string name=\"palette_name_not_supported\">El formato %1$s no admite proporcionar el nombre de la paleta</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Debido a las políticas de Play Store, esta función no se puede incluir en la versión actual. Para acceder a esta funcionalidad, descargue ImageToolbox desde una fuente alternativa. Puede encontrar las compilaciones disponibles en GitHub a continuación.</string>\n    <string name=\"open_github_page\">Abrir página de Github</string>\n    <string name=\"overwrite_files_sub_short\">El archivo original será reemplazado por uno nuevo en lugar de guardarse en la carpeta seleccionada.</string>\n    <string name=\"hidden_watermark_text_detected\">Texto de marca de agua oculto detectado</string>\n    <string name=\"hidden_watermark_image_detected\">Imagen de marca de agua oculta detectada</string>\n    <string name=\"this_image_was_hidden\">Esta imagen estaba oculta</string>\n    <string name=\"generative_inpaint\">Pintura generativa</string>\n    <string name=\"generative_inpaint_sub\">Le permite eliminar objetos en una imagen utilizando un modelo de IA, sin depender de OpenCV. Para usar esta función, la aplicación descargará el modelo requerido (~200 MB) de GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Le permite eliminar objetos en una imagen utilizando un modelo de IA, sin depender de OpenCV. Esta podría ser una operación de larga duración.</string>\n    <string name=\"error_level_analysis\">Análisis de nivel de error</string>\n    <string name=\"luminance_gradient\">gradiente de luminancia</string>\n    <string name=\"average_distance\">Distancia promedio</string>\n    <string name=\"copy_move_detection\">Detección de movimiento de copia</string>\n    <string name=\"retain\">Retener</string>\n    <string name=\"coefficent\">coeficiente</string>\n    <string name=\"clipboard_data_is_too_large\">Los datos del portapapeles son demasiado grandes</string>\n    <string name=\"data_is_too_large_to_copy\">Los datos son demasiado grandes para copiarlos.</string>\n    <string name=\"simple_weave_pixelization\">Pixelización de tejido simple</string>\n    <string name=\"staggered_pixelization\">Pixelización escalonada</string>\n    <string name=\"cross_pixelization\">Pixelización cruzada</string>\n    <string name=\"micro_macro_pixelization\">Micropixelización macro</string>\n    <string name=\"orbital_pixelization\">Pixelización orbital</string>\n    <string name=\"vortex_pixelization\">Pixelización de vórtice</string>\n    <string name=\"pulse_grid_pixelization\">Pixelización de cuadrícula de pulso</string>\n    <string name=\"nucleus_pixelization\">Pixelización del núcleo</string>\n    <string name=\"radial_weave_pixelization\">Pixelización de tejido radial</string>\n    <string name=\"cannot_open_uri\">No se puede abrir la uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Modo nevadas</string>\n    <string name=\"enabled\">Activado</string>\n    <string name=\"border_frame\">Marco de borde</string>\n    <string name=\"glitch_variant\">Variante de falla</string>\n    <string name=\"channel_shift\">Cambio de canal</string>\n    <string name=\"max_offset\">Compensación máxima</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Bloqueo de fallo</string>\n    <string name=\"block_size\">Tamaño del bloque</string>\n    <string name=\"crt_curvature\">Curvatura CRT</string>\n    <string name=\"curvature\">Curvatura</string>\n    <string name=\"chroma\">croma</string>\n    <string name=\"pixel_melt\">Derretimiento de píxeles</string>\n    <string name=\"max_drop\">Caída máxima</string>\n    <string name=\"ai_tools\">Herramientas de IA</string>\n    <string name=\"ai_tools_sub\">Varias herramientas para procesar imágenes a través de modelos de inteligencia artificial, como eliminación de artefactos o eliminación de ruido</string>\n    <string name=\"model_anime_undeint\">Compresión, líneas irregulares.</string>\n    <string name=\"model_broadcast\">Dibujos animados, compresión de transmisión.</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Compresión general, ruido general.</string>\n    <string name=\"model_wb_denoise\">Ruido de dibujos animados incoloro</string>\n    <string name=\"model_span_anime_pretrain\">Rápido, compresión general, ruido general, animación/cómics/anime</string>\n    <string name=\"model_book_scan\">Escaneo de libros</string>\n    <string name=\"model_overexposure\">Corrección de exposición</string>\n    <string name=\"model_fbcnn_color_fp16\">Lo mejor en compresión general e imágenes en color.</string>\n    <string name=\"model_fbcnn_gray_fp16\">Lo mejor en compresión general, imágenes en escala de grises</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Compresión general, imágenes en escala de grises, más fuertes.</string>\n    <string name=\"model_scunet_color_gan_fp16\">Ruido general, imágenes en color.</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Ruido general, imágenes en color, mejores detalles.</string>\n    <string name=\"model_scunet_gray_15_fp16\">Ruido general, imágenes en escala de grises.</string>\n    <string name=\"model_scunet_gray_25_fp16\">Ruido general, imágenes en escala de grises, más fuertes.</string>\n    <string name=\"model_scunet_gray_50_fp16\">Ruido general, imágenes en escala de grises, más fuertes.</string>\n    <string name=\"model_jpeg_destroyer\">Compresión general</string>\n    <string name=\"model_jaywreck\">Compresión general</string>\n    <string name=\"model_h264\">Texturización, compresión h264.</string>\n    <string name=\"model_vhs\">compresión VHS</string>\n    <string name=\"model_cinepak\">Compresión no estándar (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Compresión bink, mejor en geometría</string>\n    <string name=\"model_debink_v5\">Compresión Bink, más fuerte.</string>\n    <string name=\"model_debink_v6\">Compresión Bink, suave, conserva los detalles.</string>\n    <string name=\"model_antialias\">Eliminando el efecto escalón, alisando</string>\n    <string name=\"model_kdm_scans\">Arte/dibujos escaneados, compresión suave, muaré</string>\n    <string name=\"model_bandage\">bandas de color</string>\n    <string name=\"model_halftone\">Lento, eliminando medios tonos.</string>\n    <string name=\"model_colorizer\">Colorizador general para imágenes en escala de grises/blanco y negro; para obtener mejores resultados utilice DDColor</string>\n    <string name=\"model_deedge\">Eliminación de bordes</string>\n    <string name=\"model_desharpen\">Elimina el exceso de nitidez</string>\n    <string name=\"model_dither\">Lento, vacilante</string>\n    <string name=\"model_gainres\">Antialiasing, artefactos generales, CGI</string>\n    <string name=\"model_kdm003_scans\">Procesamiento de escaneos KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Modelo ligero de mejora de imagen.</string>\n    <string name=\"model_bcgone_detailed_v2\">Eliminación de artefactos de compresión</string>\n    <string name=\"model_bcgone_smooth\">Eliminación de artefactos de compresión</string>\n    <string name=\"model_bandage_smooth\">Retiro del vendaje con resultados suaves.</string>\n    <string name=\"model_bendel_halftone\">Procesamiento de patrones de semitonos</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Eliminación de patrones de tramado V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Eliminación de artefactos JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Mejora de textura H.264</string>\n    <string name=\"model_vhs_sharpen\">Mejora y nitidez de VHS</string>\n    <string name=\"merging\">Fusionando</string>\n    <string name=\"chunk_size\">Tamaño del fragmento</string>\n    <string name=\"overlap_size\">Tamaño de superposición</string>\n    <string name=\"note_chunk_info\">Las imágenes de más de %1$s px se cortarán y procesarán en trozos; la superposición las mezcla para evitar uniones visibles.</string>\n    <string name=\"large_chunk_warning\">Los tamaños grandes pueden causar inestabilidad con dispositivos de gama baja</string>\n    <string name=\"select_one_to_start\">Seleccione uno para comenzar</string>\n    <string name=\"delete_model_sub\">¿Quieres eliminar el modelo %1$s? Tendrás que descargarlo nuevamente.</string>\n    <string name=\"confirm\">Confirmar</string>\n    <string name=\"models\">Modelos</string>\n    <string name=\"downloaded_models\">Modelos descargados</string>\n    <string name=\"available_models\">Modelos disponibles</string>\n    <string name=\"preparing\">Preparante</string>\n    <string name=\"active_model\">modelo activo</string>\n    <string name=\"failed_to_open_session\">No se pudo abrir la sesión</string>\n    <string name=\"only_onnx_models\">Sólo se pueden importar modelos .onnx/.ort</string>\n    <string name=\"import_model\">Importar modelo</string>\n    <string name=\"import_model_sub\">Importe el modelo onnx personalizado para su uso posterior, solo se aceptan modelos onnx/ort, admite casi todas las variantes similares a esrgan</string>\n    <string name=\"imported_models\">Modelos importados</string>\n    <string name=\"model_scunet_color_15_fp16\">Ruido general, imágenes en color.</string>\n    <string name=\"model_scunet_color_25_fp16\">Ruido general, imágenes en color, más fuertes.</string>\n    <string name=\"model_scunet_color_50_fp16\">Ruido general, imágenes en color, más fuerte.</string>\n    <string name=\"model_artifacts_dithering_alsa\">Reduce los artefactos de tramado y las bandas de color, mejorando los degradados suaves y las áreas de color planas.</string>\n    <string name=\"model_nmkd_brighten_redux\">Mejora el brillo y el contraste de la imagen con reflejos equilibrados y al mismo tiempo conserva los colores naturales.</string>\n    <string name=\"model_nmkd_brighten\">Ilumina las imágenes oscuras manteniendo los detalles y evitando la sobreexposición.</string>\n    <string name=\"model_nmkd_detoon\">Elimina el tono excesivo del color y restaura un equilibrio de color más neutro y natural.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Aplica tonificación de ruido basada en Poisson con énfasis en preservar texturas y detalles finos.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Aplica una tonificación suave del ruido Poisson para obtener resultados visuales más suaves y menos agresivos.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Tono de ruido uniforme centrado en la preservación de los detalles y la claridad de la imagen.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Tono de ruido suave y uniforme para una textura sutil y una apariencia suave.</string>\n    <string name=\"model_repainter\">Repara áreas dañadas o irregulares repintando artefactos y mejorando la consistencia de la imagen.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Modelo de eliminación de bandas liviano que elimina las bandas de color con un costo de rendimiento mínimo.</string>\n    <string name=\"model_jpeg_0_20\">Optimiza imágenes con artefactos de compresión muy alta (calidad del 0 al 20 %) para mejorar la claridad.</string>\n    <string name=\"model_jpeg_20_40\">Mejora las imágenes con artefactos de alta compresión (20-40% de calidad), restaurando detalles y reduciendo el ruido.</string>\n    <string name=\"model_jpeg_40_60\">Mejora las imágenes con una compresión moderada (40-60% de calidad), equilibrando la nitidez y la suavidad.</string>\n    <string name=\"model_jpeg_60_80\">Refina las imágenes con una ligera compresión (60-80 % de calidad) para mejorar los detalles y texturas sutiles.</string>\n    <string name=\"model_jpeg_80_100\">Mejora ligeramente las imágenes casi sin pérdidas (80-100 % de calidad) y al mismo tiempo conserva el aspecto y los detalles naturales.</string>\n    <string name=\"model_spongecolor_lite\">Colorización simple y rápida, dibujos animados, no es ideal.</string>\n    <string name=\"model_deblr\">Reduce ligeramente el desenfoque de la imagen, mejorando la nitidez sin introducir artefactos.</string>\n    <string name=\"processing_channel\">Operaciones de larga duración</string>\n    <string name=\"processing_image\">Procesando imagen</string>\n    <string name=\"processing\">Tratamiento</string>\n    <string name=\"model_artifacts_jpg_0_20\">Elimina fuertes artefactos de compresión JPEG en imágenes de muy baja calidad (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Reduce fuertes artefactos JPEG en imágenes muy comprimidas (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Limpia artefactos JPEG moderados conservando los detalles de la imagen (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Refina los artefactos JPEG ligeros en imágenes de calidad bastante alta (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Reduce sutilmente pequeños artefactos JPEG en imágenes casi sin pérdidas (80-100%).</string>\n    <string name=\"model_redetail_v2\">Mejora los detalles finos y las texturas, mejorando la nitidez percibida sin artefactos pesados.</string>\n    <string name=\"processing_finished\">Procesamiento terminado</string>\n    <string name=\"processing_failed\">Error de procesamiento</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Mejora las texturas y los detalles de la piel mientras mantiene una apariencia natural, optimizada para la velocidad.</string>\n    <string name=\"model_sbdv_dejpeg\">Elimina los artefactos de compresión JPEG y restaura la calidad de la imagen de las fotografías comprimidas.</string>\n    <string name=\"model_iso_denoise_v1\">Reduce el ruido ISO en fotografías tomadas en condiciones de poca luz, preservando los detalles.</string>\n    <string name=\"model_dejumbo\">Corrige las luces sobreexpuestas o “jumbo” y restaura un mejor equilibrio tonal.</string>\n    <string name=\"model_ddcolor_tiny\">Modelo de coloración ligero y rápido que agrega colores naturales a imágenes en escala de grises.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">eliminar ruido</string>\n    <string name=\"type_colorize\">colorear</string>\n    <string name=\"type_artifacts\">Artefactos</string>\n    <string name=\"type_enhance\">Mejorar</string>\n    <string name=\"type_anime\">animado</string>\n    <string name=\"type_scans\">Escaneos</string>\n    <string name=\"type_upscale\">Exclusivo</string>\n    <string name=\"model_realesrgan_x4v3\">escalador X4 para imágenes generales; Modelo pequeño que utiliza menos GPU y tiempo, con desenfoque y ruido moderados.</string>\n    <string name=\"model_realesrgan_x2plus\">Escalador X2 para imágenes generales, preservando texturas y detalles naturales.</string>\n    <string name=\"model_realesrgan_x4plus\">Escalador X4 para imágenes generales con texturas mejoradas y resultados realistas.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Escalador X4 optimizado para imágenes de anime; 6 bloques RRDB para líneas y detalles más nítidos.</string>\n    <string name=\"model_realesrnet_x4plus\">El escalador X4 con pérdida de MSE produce resultados más fluidos y artefactos reducidos para imágenes generales.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimizado para imágenes de anime; Variante 4B32F con detalles más nítidos y líneas suaves.</string>\n    <string name=\"model_ultrasharp_v2_x4\">modelo X4 UltraSharp V2 para imágenes generales; enfatiza la nitidez y la claridad.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; Más rápido y más pequeño, conserva los detalles mientras utiliza menos memoria GPU.</string>\n    <string name=\"model_rmbg_1_4\">Modelo liviano para una rápida eliminación del fondo. Rendimiento y precisión equilibrados. Trabaja con retratos, objetos y escenas. Recomendado para la mayoría de los casos de uso.</string>\n    <string name=\"type_removebg\">Eliminar glucemia</string>\n    <string name=\"horizontal_border_thickness\">Grosor del borde horizontal</string>\n    <string name=\"vertical_border_thickness\">Grosor del borde vertical</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s color</item>\n        <item quantity=\"other\">%1$s colores</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">El modelo actual no admite fragmentación, la imagen se procesará en las dimensiones originales, lo que puede causar un alto consumo de memoria y problemas con dispositivos de gama baja.</string>\n    <string name=\"chunking_disabled\">La fragmentación está deshabilitada, la imagen se procesará en las dimensiones originales, esto puede causar un alto consumo de memoria y problemas con dispositivos de gama baja, pero puede dar mejores resultados en la inferencia.</string>\n    <string name=\"chunking\">fragmentación</string>\n    <string name=\"model_u2net\">Modelo de segmentación de imágenes de alta precisión para eliminar el fondo</string>\n    <string name=\"model_u2netp\">Versión liviana de U2Net para una eliminación de fondo más rápida con un menor uso de memoria.</string>\n    <string name=\"model_ddcolor\">El modelo DDColor completo ofrece coloración de alta calidad para imágenes generales con artefactos mínimos. La mejor elección de todos los modelos de coloración.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Conjuntos de datos artísticos privados y capacitados; produce resultados de coloración diversos y artísticos con menos artefactos de color poco realistas.</string>\n    <string name=\"model_birefnet\">Modelo ligero BiRefNet basado en Swin Transformer para una eliminación precisa del fondo.</string>\n    <string name=\"model_inspyrenet\">Eliminación de fondos de alta calidad con bordes nítidos y excelente conservación de detalles, especialmente en objetos complejos y fondos complicados.</string>\n    <string name=\"model_isnet\">Modelo de eliminación de fondo que produce máscaras precisas con bordes suaves, adecuado para objetos generales y preservación moderada de detalles.</string>\n    <string name=\"model_already_downloaded\">Modelo ya descargado</string>\n    <string name=\"model_successfully_imported\">Modelo importado exitosamente</string>\n    <string name=\"type\">Tipo</string>\n    <string name=\"keyword\">Palabra clave</string>\n    <string name=\"very_fast\">muy rápido</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Lento</string>\n    <string name=\"very_slow\">muy lento</string>\n    <string name=\"compute_percents\">Calcular porcentajes</string>\n    <string name=\"minimum_value_is\">El valor mínimo es %1$s</string>\n    <string name=\"warp_sub\">Distorsionar la imagen dibujando con los dedos.</string>\n    <string name=\"warp\">Urdimbre</string>\n    <string name=\"hardness\">Dureza</string>\n    <string name=\"warp_mode\">Modo de deformación</string>\n    <string name=\"warp_mode_move\">Mover</string>\n    <string name=\"warp_mode_grow\">Crecer</string>\n    <string name=\"warp_mode_shrink\">Encoger</string>\n    <string name=\"warp_mode_swirl_cw\">Remolino CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Remolino CCW</string>\n    <string name=\"fade_strength\">Fuerza de desvanecimiento</string>\n    <string name=\"top_drop\">Caída superior</string>\n    <string name=\"bottom_drop\">Caída inferior</string>\n    <string name=\"start_drop\">Iniciar caída</string>\n    <string name=\"end_drop\">Caída final</string>\n    <string name=\"downloading\">Descargando</string>\n    <string name=\"smooth_shapes\">Formas suaves</string>\n    <string name=\"smooth_shapes_sub\">Utilice superelipses en lugar de rectángulos redondeados estándar para obtener formas más suaves y naturales</string>\n    <string name=\"shape_type\">Tipo de forma</string>\n    <string name=\"cut\">Cortar</string>\n    <string name=\"rounded\">Redondeado</string>\n    <string name=\"smooth\">Liso</string>\n    <string name=\"cut_shapes_sub\">Bordes afilados sin redondear</string>\n    <string name=\"rounded_shapes_sub\">Esquinas redondeadas clásicas</string>\n    <string name=\"shapes_type\">Tipo de formas</string>\n    <string name=\"corners_size\">Tamaño de las esquinas</string>\n    <string name=\"squircle\">ardilla</string>\n    <string name=\"squircle_shapes_sub\">Elementos de interfaz de usuario redondeados y elegantes</string>\n    <string name=\"filename_format\">Formato de nombre de archivo</string>\n    <string name=\"prefix_pattern_description\">Texto personalizado colocado al principio del nombre del archivo, perfecto para nombres de proyectos, marcas o etiquetas personales.</string>\n    <string name=\"original_filename_pattern_description\">Utiliza el nombre del archivo original sin extensión, lo que le ayuda a mantener intacta la identificación de la fuente.</string>\n    <string name=\"width_pattern_description\">El ancho de la imagen en píxeles, útil para rastrear cambios de resolución o escalar resultados.</string>\n    <string name=\"height_pattern_description\">La altura de la imagen en píxeles, útil cuando se trabaja con relaciones de aspecto o exportaciones.</string>\n    <string name=\"random_numbers_pattern_description\">Genera dígitos aleatorios para garantizar nombres de archivos únicos; agregue más dígitos para mayor seguridad contra duplicados.</string>\n    <string name=\"sequence_number_pattern_description\">Contador de incremento automático para exportaciones por lotes, ideal para guardar varias imágenes en una sesión.</string>\n    <string name=\"preset_info_pattern_description\">Inserta el nombre preestablecido aplicado en el nombre del archivo para que pueda recordar fácilmente cómo se procesó la imagen.</string>\n    <string name=\"scale_mode_pattern_description\">Muestra el modo de escala de imagen utilizado durante el procesamiento, lo que ayuda a distinguir imágenes redimensionadas, recortadas o ajustadas.</string>\n    <string name=\"suffix_pattern_description\">Texto personalizado colocado al final del nombre del archivo, útil para versiones como _v2, _edited o _final.</string>\n    <string name=\"extension_pattern_description\">La extensión del archivo (png, jpg, webp, etc.), que coincide automáticamente con el formato guardado real.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Una marca de tiempo personalizable que le permite definir su propio formato según la especificación de Java para una clasificación perfecta.</string>\n    <string name=\"fling_type\">Tipo de aventura</string>\n    <string name=\"android_native\">Nativo de Android</string>\n    <string name=\"ios_style\">Estilo iOS</string>\n    <string name=\"smooth_curve\">Curva suave</string>\n    <string name=\"quick_stop\">Parada rápida</string>\n    <string name=\"bouncy\">Activo</string>\n    <string name=\"floaty\">flotante</string>\n    <string name=\"snappy\">Rápido</string>\n    <string name=\"ultra_smooth\">Ultrasuave</string>\n    <string name=\"adaptive\">Adaptado</string>\n    <string name=\"accessibility_aware\">Accesibilidad consciente</string>\n    <string name=\"reduced_motion\">Movimiento reducido</string>\n    <string name=\"android_native_sub\">Física de desplazamiento nativa de Android para comparación de referencia</string>\n    <string name=\"smooth_sub\">Desplazamiento equilibrado y fluido para uso general</string>\n    <string name=\"ios_style_sub\">Comportamiento de desplazamiento similar al de iOS de mayor fricción</string>\n    <string name=\"smooth_curve_sub\">Curva spline única para una sensación de desplazamiento distinta</string>\n    <string name=\"quick_stop_sub\">Desplazamiento preciso con parada rápida</string>\n    <string name=\"bouncy_sub\">Desplazamiento lúdico y responsivo</string>\n    <string name=\"floaty_sub\">Desplazamientos largos y deslizantes para explorar contenidos</string>\n    <string name=\"snappy_sub\">Desplazamiento rápido y responsivo para interfaces de usuario interactivas</string>\n    <string name=\"ultra_smooth_sub\">Desplazamiento suave premium con impulso extendido</string>\n    <string name=\"adaptive_sub\">Ajusta la física según la velocidad de lanzamiento.</string>\n    <string name=\"accessibility_aware_sub\">Respeta la configuración de accesibilidad del sistema</string>\n    <string name=\"reduced_motion_sub\">Movimiento mínimo para necesidades de accesibilidad.</string>\n    <string name=\"primary_lines\">Líneas primarias</string>\n    <string name=\"primary_lines_sub\">Agrega una línea más gruesa cada quinta línea</string>\n    <string name=\"fill_color\">Color de relleno</string>\n    <string name=\"hidden_tools\">Herramientas ocultas</string>\n    <string name=\"hidden_for_share\">Herramientas ocultas para compartir</string>\n    <string name=\"color_library\">Biblioteca de colores</string>\n    <string name=\"color_library_sub\">Explora una amplia colección de colores</string>\n    <string name=\"model_fatality_deblur\">Mejora la nitidez y elimina las imágenes borrosas manteniendo los detalles naturales, ideal para corregir fotografías desenfocadas.</string>\n    <string name=\"model_unresize_v3\">Restaura de forma inteligente imágenes cuyo tamaño ha sido redimensionado previamente, recuperando detalles y texturas perdidas.</string>\n    <string name=\"model_liveaction_v1_span\">Optimizado para contenido de acción en vivo, reduce los artefactos de compresión y mejora los detalles finos en fotogramas de películas o programas de televisión.</string>\n    <string name=\"model_vhs2hd_realplksr\">Convierte metraje con calidad VHS a HD, eliminando el ruido de la cinta y mejorando la resolución al mismo tiempo que conserva la sensación vintage.</string>\n    <string name=\"model_text2hd_v1\">Especializado para imágenes y capturas de pantalla con mucho texto, afina los caracteres y mejora la legibilidad.</string>\n    <string name=\"model_frankendata_pretrainer\">Ampliación avanzada entrenada en diversos conjuntos de datos, excelente para mejorar fotografías de uso general.</string>\n    <string name=\"model_realwebphoto_v2\">Optimizado para fotografías comprimidas web, elimina artefactos JPEG y restaura la apariencia natural.</string>\n    <string name=\"model_realwebphoto_v4\">Versión mejorada para fotografías web con mejor conservación de texturas y reducción de artefactos.</string>\n    <string name=\"model_dat_2x\">La mejora 2x con la tecnología Dual Aggregation Transformer mantiene la nitidez y los detalles naturales.</string>\n    <string name=\"model_dat_3x\">Ampliación 3x utilizando arquitectura de transformador avanzada, ideal para necesidades de ampliación moderadas.</string>\n    <string name=\"model_dat_4x\">La ampliación de alta calidad 4x con una red de transformadores de última generación conserva los detalles finos a escalas más grandes.</string>\n    <string name=\"model_nafnet_deblurring\">Elimina el desenfoque/ruido y las sacudidas de las fotos. Propósito general pero mejor en fotografías.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Restaura imágenes de baja calidad utilizando el transformador Swin2SR, optimizado para la degradación de BSRGAN. Excelente para corregir artefactos de compresión intensa y mejorar detalles a escala 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Ampliación 4x con transformador SwinIR entrenado en degradación de BSRGAN. Utiliza GAN para obtener texturas más nítidas y detalles más naturales en fotografías y escenas complejas.</string>\n    <string name=\"path\">Camino</string>\n    <string name=\"merge_pdf\">Fusionar PDF</string>\n    <string name=\"merge_pdf_sub\">Combine varios archivos PDF en un solo documento</string>\n    <string name=\"files_order\">Orden de archivos</string>\n    <string name=\"pages_short\">páginas.</string>\n    <string name=\"split_pdf\">Dividir PDF</string>\n    <string name=\"split_pdf_sub\">Extraiga páginas específicas de un documento PDF</string>\n    <string name=\"rotate_pdf\">Girar PDF</string>\n    <string name=\"rotate_pdf_sub\">Corregir la orientación de la página permanentemente</string>\n    <string name=\"pages\">paginas</string>\n    <string name=\"rearrange_pdf\">Reorganizar PDF</string>\n    <string name=\"rearrange_pdf_sub\">Arrastra y suelta páginas para reordenarlas</string>\n    <string name=\"hold_drag_drop\">Sostener y arrastrar páginas</string>\n    <string name=\"page_numbers\">Números de página</string>\n    <string name=\"page_numbers_sub\">Añade numeración a tus documentos automáticamente</string>\n    <string name=\"label_format\">Formato de etiqueta</string>\n    <string name=\"pdf_to_text\">PDF a texto (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extraiga texto sin formato de sus documentos PDF</string>\n    <string name=\"watermark_pdf_sub\">Superponer texto personalizado para marca o seguridad</string>\n    <string name=\"signature\">Firma</string>\n    <string name=\"signature_sub\">Añade tu firma electrónica a cualquier documento</string>\n    <string name=\"will_be_for_signature\">Esto se utilizará como firma.</string>\n    <string name=\"unlock_pdf\">Desbloquear PDF</string>\n    <string name=\"unlock_pdf_sub\">Elimina contraseñas de tus archivos protegidos</string>\n    <string name=\"protect_pdf\">Proteger PDF</string>\n    <string name=\"protect_pdf_sub\">Proteja sus documentos con un cifrado seguro</string>\n    <string name=\"success\">Éxito</string>\n    <string name=\"pdf_unlocked\">PDF desbloqueado, puedes guardarlo o compartirlo</string>\n    <string name=\"repair_pdf\">Reparar PDF</string>\n    <string name=\"repair_pdf_sub\">Intente reparar documentos corruptos o ilegibles</string>\n    <string name=\"grayscale\">Escala de grises</string>\n    <string name=\"grayscale_pdf_sub\">Convierta todas las imágenes incrustadas en documentos a escala de grises</string>\n    <string name=\"compress_pdf\">Comprimir PDF</string>\n    <string name=\"compress_pdf_sub\">Optimice el tamaño del archivo de su documento para compartirlo más fácilmente</string>\n    <string name=\"repair_info\">ImageToolbox reconstruye la tabla de referencias cruzadas interna y regenera la estructura del archivo desde cero. Esto puede restaurar el acceso a muchos archivos que \\\\\"no se pueden abrir\\\\\"</string>\n    <string name=\"grayscale_info\">Esta herramienta convierte todas las imágenes de documentos a escala de grises. Lo mejor para imprimir y reducir el tamaño del archivo</string>\n    <string name=\"metadata\">Metadatos</string>\n    <string name=\"metadata_pdf_sub\">Edite las propiedades del documento para una mayor privacidad</string>\n    <string name=\"tags\">Etiquetas</string>\n    <string name=\"producer\">Productor</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Palabras clave</string>\n    <string name=\"creator\">Creador</string>\n    <string name=\"privacy_deep_clean\">Limpieza profunda de privacidad</string>\n    <string name=\"privacy_deep_clean_sub\">Borrar todos los metadatos disponibles para este documento</string>\n    <string name=\"page\">Página</string>\n    <string name=\"deep_ocr\">OCR profundo</string>\n    <string name=\"deep_ocr_sub\">Extraiga texto del documento y guárdelo en un archivo de texto utilizando el motor Tesseract</string>\n    <string name=\"cant_remove_all\">No se pueden eliminar todas las páginas</string>\n    <string name=\"remove_pages_pdf\">Eliminar páginas PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Eliminar páginas específicas del documento PDF</string>\n    <string name=\"tap_to_remove\">Toque para eliminar</string>\n    <string name=\"manually\">A mano</string>\n    <string name=\"crop_pdf\">Recortar PDF</string>\n    <string name=\"crop_pdf_sub\">Recortar páginas de documentos hasta cualquier límite</string>\n    <string name=\"flatten_pdf\">Aplanar PDF</string>\n    <string name=\"flatten_pdf_sub\">Haga que el PDF no se pueda modificar rasterizando las páginas del documento</string>\n    <string name=\"camera_failed_to_open\">No se pudo iniciar la cámara. Verifique los permisos y asegúrese de que otra aplicación no los esté utilizando.</string>\n    <string name=\"extract_images\">Extraer imágenes</string>\n    <string name=\"extract_images_sub\">Extraiga imágenes incrustadas en archivos PDF en su resolución original</string>\n    <string name=\"pdf_no_embedded\">Este archivo PDF no contiene ninguna imagen incrustada.</string>\n    <string name=\"extract_images_info\">Esta herramienta escanea cada página y recupera imágenes originales de alta calidad, perfecta para guardar originales de documentos.</string>\n    <string name=\"draw_signature\">Dibujar firma</string>\n    <string name=\"pen_params\">Parámetros de pluma</string>\n    <string name=\"draw_signature_sub\">Utilice su propia firma como imagen para colocar en los documentos.</string>\n    <string name=\"zip_pdf\">Comprimir PDF</string>\n    <string name=\"zip_pdf_sub\">Divida el documento con el intervalo determinado y empaquete documentos nuevos en un archivo zip</string>\n    <string name=\"interval\">Intervalo</string>\n    <string name=\"print_pdf\">Imprimir PDF</string>\n    <string name=\"print_pdf_sub\">Prepare el documento para imprimir con un tamaño de página personalizado</string>\n    <string name=\"pages_per_sheet\">Páginas por hoja</string>\n    <string name=\"orientation\">Orientación</string>\n    <string name=\"page_size\">Tamaño de página</string>\n    <string name=\"margin\">Margen</string>\n    <string name=\"bloom\">Floración</string>\n    <string name=\"soft_knee\">Rodilla suave</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimizado para anime y dibujos animados. Ampliación rápida con colores naturales mejorados y menos artefactos</string>\n    <string name=\"one_ui_sub\">Estilo Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Ingrese aquí símbolos matemáticos básicos para calcular el valor deseado (por ejemplo, (5+5)*10)</string>\n    <string name=\"math_expression\">expresión matemática</string>\n    <string name=\"pick_up_to_n_collage_images\">Recoge hasta %1$s imágenes</string>\n    <string name=\"keep_date_time\">Mantener fecha y hora</string>\n    <string name=\"keep_date_time_sub\">Conserve siempre las etiquetas exif relacionadas con la fecha y la hora, funciona independientemente de la opción mantener exif</string>\n    <string name=\"background_color_for_alpha_formats\">Color de fondo para formatos alfa</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Agrega la capacidad de establecer el color de fondo para cada formato de imagen con soporte alfa; cuando está deshabilitado, está disponible solo para los que no son alfa.</string>\n    <string name=\"open_markup_project\">Abrir proyecto</string>\n    <string name=\"open_markup_project_sub\">Continuar editando un proyecto de Image Toolbox previamente guardado</string>\n    <string name=\"markup_project_open_failed\">No se puede abrir el proyecto de Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Al proyecto Image Toolbox le faltan datos del proyecto</string>\n    <string name=\"markup_project_corrupted\">El proyecto Image Toolbox está dañado</string>\n    <string name=\"unsupported_markup_project_version\">Versión del proyecto Image Toolbox no compatible: %1$d</string>\n    <string name=\"save_markup_project\">Guardar proyecto</string>\n    <string name=\"save_markup_project_sub\">Almacene capas, fondos y edite el historial en un archivo de proyecto editable</string>\n    <string name=\"failed_to_open\">No se pudo abrir</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Escribir en PDF con capacidad de búsqueda</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Reconozca texto de un lote de imágenes y guarde PDF con capacidad de búsqueda con imagen y capa de texto seleccionable</string>\n    <string name=\"layer_alpha\">Capa alfa</string>\n    <string name=\"horizontal_flip\">Voltear horizontalmente</string>\n    <string name=\"vertical_flip\">Voltear verticalmente</string>\n    <string name=\"lock\">Cerrar</string>\n    <string name=\"add_shadow\">Agregar sombra</string>\n    <string name=\"shadow_color\">Color de sombra</string>\n    <string name=\"text_geometry\">Geometría del texto</string>\n    <string name=\"text_geometry_sub\">Estire o sesgue el texto para lograr un estilo más nítido</string>\n    <string name=\"scale_x\">Escala X</string>\n    <string name=\"skew_x\">Sesgar X</string>\n    <string name=\"remove_annotations\">Eliminar anotaciones</string>\n    <string name=\"remove_annotations_sub\">Elimine los tipos de anotaciones seleccionados, como enlaces, comentarios, resaltados, formas o campos de formulario de las páginas PDF</string>\n    <string name=\"annotation_link\">Hipervínculos</string>\n    <string name=\"annotation_file_attachment\">Archivos adjuntos</string>\n    <string name=\"annotation_line\">Pauta</string>\n    <string name=\"annotation_popup\">Ventanas emergentes</string>\n    <string name=\"annotation_stamp\">Sellos</string>\n    <string name=\"annotation_shapes\">formas</string>\n    <string name=\"annotation_text\">Notas de texto</string>\n    <string name=\"annotation_text_markup\">Marcado de texto</string>\n    <string name=\"annotation_widget\">Campos de formulario</string>\n    <string name=\"annotation_markup\">Margen</string>\n    <string name=\"annotation_unknown\">Desconocido</string>\n    <string name=\"annotations\">Anotaciones</string>\n    <string name=\"ungroup\">Desagrupar</string>\n    <string name=\"add_shadow_sub\">Agregue sombra borrosa detrás de la capa con colores y compensaciones configurables</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-et/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"smth_went_wrong\">Midagi läks valesti: %1$s</string>\n    <string name=\"size\">Suurus %1$s</string>\n    <string name=\"loading\">Laadin…</string>\n    <string name=\"image_too_large_preview\">Pilt on eelvaate jaoks liiga suur, kuid üritame ikkagi salvestada</string>\n    <string name=\"pick_image\">Alustamiseks vali pilt</string>\n    <string name=\"width\">Laius %1$s</string>\n    <string name=\"height\">Kõrgus %1$s</string>\n    <string name=\"quality\">Kvaliteet</string>\n    <string name=\"something_went_wrong\">Midagi läks valesti</string>\n    <string name=\"restart_app\">Käivita rakendus uuesti</string>\n    <string name=\"copied\">Kopeeritud lõikelauale</string>\n    <string name=\"exception\">Erandlik olukord</string>\n    <string name=\"edit_exif\">Muuda EXIF-andmeid</string>\n    <string name=\"ok\">Sobib</string>\n    <string name=\"no_exif\">EXIF-andmeid ei leidunud</string>\n    <string name=\"add_tag\">Lisa silt</string>\n    <string name=\"save\">Salvesta</string>\n    <string name=\"clear\">Eemalda</string>\n    <string name=\"clear_exif\">Eemalda EXIF-andmed</string>\n    <string name=\"cancel\">Katkesta</string>\n    <string name=\"clear_exif_sub\">Kõik EXIF-andmed kustutatakse. Seda tegevust ei saa tagasi pöörata!</string>\n    <string name=\"presets\">Eelseadistused</string>\n    <string name=\"crop\">Kadreeri</string>\n    <string name=\"image_not_saved\">Salvestan</string>\n    <string name=\"image_not_saved_sub\">Kui väljud, siis kõik salvestamata muudatused lähevad kaotsi</string>\n    <string name=\"check_source_code\">Lähtekood</string>\n    <string name=\"extension\">Lisamoodul</string>\n    <string name=\"resize_type\">Suuruse muutmise tüüp</string>\n    <string name=\"single_edit\">Ühe pildi muutmine</string>\n    <string name=\"single_edit_sub\">Muuda ühe pildi suurust ja muid parameetreid</string>\n    <string name=\"pick_image_alt\">Vali pilt</string>\n    <string name=\"app_closing_sub\">Kas oled kindel, et soovid selle rakenduse sulgeda?</string>\n    <string name=\"app_closing\">Rakendus on sulgemisel</string>\n    <string name=\"stay\">Jää siia</string>\n    <string name=\"close\">Sulge</string>\n    <string name=\"image\">Pilt</string>\n    <string name=\"color\">Värv</string>\n    <string name=\"color_copied\">Värv on kopeeritud</string>\n    <string name=\"crop_sub\">Kadreeri pilti soovitud viisil</string>\n    <string name=\"version\">Versioon</string>\n    <string name=\"keep_exif\">Säilita EXIF-andmed</string>\n    <string name=\"images\">Pildid: %d</string>\n    <string name=\"change_preview\">Muuda eelvaadet</string>\n    <string name=\"remove\">Eemalda</string>\n    <string name=\"palette_sub\">Koosta antud pildi alusel värvipalett</string>\n    <string name=\"generate_palette\">Paleti koostamine</string>\n    <string name=\"palette\">Värvipalett</string>\n    <string name=\"check_source_code_sub\">Siit leiad viimased uudised, saad osaleda arendusega seotud aruteludes ja palju muud</string>\n    <string name=\"pick_color\">Värvivalija</string>\n    <string name=\"pick_color_sub\">Vali pildilt värv ning kopeeri või jaga seda</string>\n    <string name=\"update\">Uuendus</string>\n    <string name=\"new_version\">Uus versioon %1$s</string>\n    <string name=\"unsupported_type\">Mittetoetatud tüüp: %1$s</string>\n    <string name=\"no_palette\">Antud pildist ei saa paletti luua</string>\n    <string name=\"explicit\">Konkreetne</string>\n    <string name=\"flexible\">Paindlik</string>\n    <string name=\"reset_image\">Lähtesta pilt</string>\n    <string name=\"reset_image_sub\">Pildi muudatused tühistuvad ja asenduvad vaikimisi väärtustega</string>\n    <string name=\"values_reset\">Väärtused on korrektselt lähtestatud</string>\n    <string name=\"reset\">Lähtesta</string>\n    <string name=\"original\">Algne</string>\n    <string name=\"folder\">Väljundkaust</string>\n    <string name=\"def\">Vaikimisi</string>\n    <string name=\"custom\">Kohandatud</string>\n    <string name=\"unspecified\">Määratlemata</string>\n    <string name=\"device_storage\">Seadme andmeruum</string>\n    <string name=\"color_scheme\">Värvikombinatsioon</string>\n    <string name=\"color_red\">Punane</string>\n    <string name=\"color_green\">Roheline</string>\n    <string name=\"color_blue\">Sinine</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Aseta korrektne aRGB värvikood</string>\n    <string name=\"clipboard_paste_invalid_empty\">Pole mitte midagi asetada</string>\n    <string name=\"failed_to_save\">%d pildi salvestamine ei õnnestunud</string>\n    <string name=\"email\">E-post</string>\n    <string name=\"compare\">Võrdle</string>\n    <string name=\"settings\">Seadistused</string>\n    <string name=\"dark\">Tume kujundus</string>\n    <string name=\"light\">Hele kujundus</string>\n    <string name=\"system\">Süsteemi kujundus</string>\n    <string name=\"customization\">Kohandamine</string>\n    <string name=\"language\">Keel</string>\n    <string name=\"primary\">Esmane</string>\n    <string name=\"surface\">Tasapind</string>\n    <string name=\"values\">Väärtused</string>\n    <string name=\"add\">Lisa</string>\n    <string name=\"permission\">Õigused</string>\n    <string name=\"grant\">Anna õigused</string>\n    <string name=\"share\">Jaga</string>\n    <string name=\"prefix\">Eesliide</string>\n    <string name=\"filename\">Failinimi</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"gallery_picker\">Galerii</string>\n    <string name=\"edit\">Muuda</string>\n    <string name=\"order\">Järjestus</string>\n    <string name=\"fill\">Täida</string>\n    <string name=\"fit\">Sobita</string>\n    <string name=\"brightness\">Eredus</string>\n    <string name=\"contrast\">Kontrastsus</string>\n    <string name=\"hue\">Värvitoon</string>\n    <string name=\"saturation\">Värviküllastus</string>\n    <string name=\"filter\">Filter</string>\n    <string name=\"filters\">Filtrid</string>\n    <string name=\"by_bytes_resize\">Suuruse muutmine kaalu järgi</string>\n    <string name=\"max_bytes\">Maksimaalne suurus KB-des</string>\n    <string name=\"by_bytes_resize_sub\">Muutke pildi suurust vastavalt etteantud suurusele KB-des</string>\n    <string name=\"compare_sub\">Võrrelge kahte antud pilti</string>\n    <string name=\"pick_two_images\">Valige alustamiseks kaks pilti</string>\n    <string name=\"pick_images\">Valige pildid</string>\n    <string name=\"night_mode\">Öörežiim</string>\n    <string name=\"dynamic_colors\">Dünaamilised värvid</string>\n    <string name=\"allow_image_monet\">Luba pilt rahaks</string>\n    <string name=\"allow_image_monet_sub\">Kui see on lubatud, võetakse redigeeritava pildi valimisel sellele pildile rakenduse värvid</string>\n    <string name=\"amoled_mode\">Amoled režiim</string>\n    <string name=\"amoled_mode_sub\">Kui see on lubatud, seatakse pindade värv öörežiimis absoluutselt tumedaks</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Kui dünaamilised värvid on sisse lülitatud, ei saa rakenduse värviskeemi muuta</string>\n    <string name=\"pick_accent_color\">Rakenduse teema põhineb valitud värvil</string>\n    <string name=\"about_app\">Teave rakenduse kohta</string>\n    <string name=\"no_updates\">Värskendusi ei leitud</string>\n    <string name=\"issue_tracker\">Probleemi jälgija</string>\n    <string name=\"issue_tracker_sub\">Saatke siin veaaruandeid ja funktsioonitaotlusi</string>\n    <string name=\"help_translate\">Aidake tõlkida</string>\n    <string name=\"help_translate_sub\">Parandage tõlkevead või lokaliseerige projekt teistesse keeltesse</string>\n    <string name=\"nothing_found_by_search\">Teie päringuga ei leitud midagi</string>\n    <string name=\"search_here\">Otsi siit</string>\n    <string name=\"dynamic_colors_sub\">Kui see on lubatud, võetakse rakenduse värvid taustapildi värvideks</string>\n    <string name=\"tertiary\">Tertsiaarne</string>\n    <string name=\"secondary\">Sekundaarne</string>\n    <string name=\"border_thickness\">Piiri paksus</string>\n    <string name=\"permission_sub\">Rakendus vajab piltide tööks salvestamiseks juurdepääsu teie salvestusruumile, see on vajalik. Palun andke luba järgmises dialoogiboksis.</string>\n    <string name=\"grant_permission_manual\">Rakendus vajab töötamiseks seda luba, andke see käsitsi</string>\n    <string name=\"external_storage\">Väline salvestusruum</string>\n    <string name=\"monet_colors\">Monet värvid</string>\n    <string name=\"donation_sub\">See rakendus on täiesti tasuta, kuid kui soovite projekti arendamist toetada, klõpsake siin</string>\n    <string name=\"fab_alignment\">FAB joondus</string>\n    <string name=\"check_updates\">Kontrollige värskendusi</string>\n    <string name=\"check_updates_sub\">Kui see on lubatud, kuvatakse teile rakenduse käivitamisel värskendamise dialoog</string>\n    <string name=\"zoom\">Pildi suum</string>\n    <string name=\"emoji_sub\">Valige, millist emotikonit põhiekraanil kuvada</string>\n    <string name=\"add_file_size\">Lisa faili suurus</string>\n    <string name=\"add_file_size_sub\">Kui see on lubatud, lisab salvestatud pildi laiuse ja kõrguse väljundfaili nimele</string>\n    <string name=\"delete_exif\">Kustuta EXIF</string>\n    <string name=\"delete_exif_sub\">Kustutage EXIF-i metaandmed mis tahes pildikomplektist</string>\n    <string name=\"image_preview\">Pildi eelvaade</string>\n    <string name=\"image_preview_sub\">Saate vaadata mis tahes tüüpi kujutiste eelvaateid: GIF, SVG ja nii edasi</string>\n    <string name=\"image_source\">Pildi allikas</string>\n    <string name=\"photo_picker\">Fotovalija</string>\n    <string name=\"file_explorer_picker\">Failiuurija</string>\n    <string name=\"photo_picker_sub\">Androidi kaasaegne fotovalija, mis kuvatakse ekraani allservas, võib töötada ainult Android 12+ puhul. EXIF-i metaandmete saamisel on probleeme</string>\n    <string name=\"gallery_picker_sub\">Lihtne galerii pildivalija. See töötab ainult siis, kui teil on rakendus, mis pakub meediumivalikut</string>\n    <string name=\"file_explorer_picker_sub\">Kasutage pildi valimiseks GetContenti kavatsust. Töötab kõikjal, kuid on teada, et mõnes seadmes on probleeme valitud piltide vastuvõtmisega. See pole minu süü.</string>\n    <string name=\"options_arrangement\">Optsioonide paigutus</string>\n    <string name=\"order_sub\">Määrab põhiekraanil olevate tööriistade järjestuse</string>\n    <string name=\"emojis_count\">Emotikonid loevad</string>\n    <string name=\"sequence_num\">järjestusNum</string>\n    <string name=\"original_filename\">originaalfailinimi</string>\n    <string name=\"add_original_filename\">Lisa algne failinimi</string>\n    <string name=\"add_original_filename_sub\">Kui see on lubatud, lisab väljundpildi nimele algse failinime</string>\n    <string name=\"replace_sequence_number\">Asenda järjekorranumber</string>\n    <string name=\"replace_sequence_number_sub\">Kui see on lubatud, asendab standardse ajatempli pildi järjekorranumbriga, kui kasutate paketttöötlust</string>\n    <string name=\"filename_not_work_with_photopicker\">Algse failinime lisamine ei tööta, kui valitud on fotovalija pildiallikas</string>\n    <string name=\"load_image_from_net\">Veebipildi laadimine</string>\n    <string name=\"load_image_from_net_sub\">Laadige Internetist mis tahes pilt, et seda soovi korral eelvaateks, suumida, redigeerida ja salvestada.</string>\n    <string name=\"no_image\">Pilt puudub</string>\n    <string name=\"image_link\">Pildi link</string>\n    <string name=\"content_scale\">Sisu skaala</string>\n    <string name=\"explicit_description\">Muudab piltide suurust etteantud kõrgusele ja laiusele. Piltide kuvasuhe võib muutuda.</string>\n    <string name=\"flexible_description\">Muudab pika küljega piltide suurust etteantud kõrgusele või laiusele. Kõik suuruse arvutused tehakse pärast salvestamist. Piltide kuvasuhe säilib.</string>\n    <string name=\"add_filter\">Lisa filter</string>\n    <string name=\"filter_sub\">Kasutage piltidele filtrikette</string>\n    <string name=\"light_aka_illumination\">Valgus</string>\n    <string name=\"color_filter\">Värvifilter</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"exposure\">Kokkupuude</string>\n    <string name=\"white_balance\">Valge tasakaal</string>\n    <string name=\"temperature\">Temperatuur</string>\n    <string name=\"tint\">Toon</string>\n    <string name=\"monochrome\">Ühevärviline</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Esiletõstetud ja varjud</string>\n    <string name=\"highlights\">Esiletõstmised</string>\n    <string name=\"shadows\">Varjud</string>\n    <string name=\"haze\">Hägusus</string>\n    <string name=\"effect\">Mõju</string>\n    <string name=\"distance\">Kaugus</string>\n    <string name=\"slope\">Kalle</string>\n    <string name=\"sharpen\">Teritama</string>\n    <string name=\"sepia\">Seepia</string>\n    <string name=\"negative\">Negatiivne</string>\n    <string name=\"solarize\">Solariseeruda</string>\n    <string name=\"vibrance\">Vibrance</string>\n    <string name=\"black_and_white\">Must ja valge</string>\n    <string name=\"crosshatch\">Ristviilu</string>\n    <string name=\"spacing\">Vahekaugus</string>\n    <string name=\"line_width\">Joone laius</string>\n    <string name=\"sobel_edge\">Sobel serv</string>\n    <string name=\"blur\">Hägusus</string>\n    <string name=\"halftone\">Pooltoonid</string>\n    <string name=\"cga_colorspace\">CGA värviruum</string>\n    <string name=\"gaussian_blur\">Gaussi hägusus</string>\n    <string name=\"box_blur\">Kasti hägusus</string>\n    <string name=\"bilaterial_blur\">Kahepoolne hägusus</string>\n    <string name=\"emboss\">Reljeef</string>\n    <string name=\"laplacian\">laplane</string>\n    <string name=\"vignette\">Vinjett</string>\n    <string name=\"start\">Alusta</string>\n    <string name=\"end\">Lõpp</string>\n    <string name=\"kuwahara\">Kuwahara silumine</string>\n    <string name=\"stack_blur\">Virna hägusus</string>\n    <string name=\"radius\">Raadius</string>\n    <string name=\"scale\">Skaala</string>\n    <string name=\"distortion\">Moonutused</string>\n    <string name=\"angle\">Nurk</string>\n    <string name=\"swirl\">Keeris</string>\n    <string name=\"bulge\">Mõhk</string>\n    <string name=\"dilation\">Laienemine</string>\n    <string name=\"sphere_refraction\">Sfääri murdumine</string>\n    <string name=\"refractive_index\">Murdumisnäitaja</string>\n    <string name=\"glass_sphere_refraction\">Klaassfääri murdumine</string>\n    <string name=\"color_matrix\">Värvimaatriks</string>\n    <string name=\"opacity\">Läbipaistmatus</string>\n    <string name=\"limits_resize\">Suuruse muutmine piirangutega</string>\n    <string name=\"limits_resize_sub\">Muutke piltide suurust etteantud kõrgusele ja laiusele, säilitades samal ajal kuvasuhte</string>\n    <string name=\"sketch\">Sketš</string>\n    <string name=\"threshold\">Lävi</string>\n    <string name=\"quantizationLevels\">Kvantimistasemed</string>\n    <string name=\"smooth_toon\">Sujuv toon</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Plakati</string>\n    <string name=\"non_maximum_suppression\">Mitte maksimaalne summutus</string>\n    <string name=\"weak_pixel_inclusion\">Nõrk pikslite kaasamine</string>\n    <string name=\"lookup\">Otsimine</string>\n    <string name=\"convolution3x3\">Konvolutsioon 3x3</string>\n    <string name=\"rgb_filter\">RGB filter</string>\n    <string name=\"false_color\">Vale värv</string>\n    <string name=\"first_color\">Esimene värv</string>\n    <string name=\"second_color\">Teine värv</string>\n    <string name=\"reorder\">Järjesta ümber</string>\n    <string name=\"fast_blur\">Kiire hägustumine</string>\n    <string name=\"blur_size\">Hägususe suurus</string>\n    <string name=\"blur_center_x\">Keskelt hägustamine x</string>\n    <string name=\"blur_center_y\">Hägusus keskel y</string>\n    <string name=\"zoom_blur\">Suumi hägusus</string>\n    <string name=\"color_balance\">Värvitasakaalu</string>\n    <string name=\"luminance_threshold\">Heleduse lävi</string>\n    <string name=\"activate_files\">Keelasite rakenduse Failid, aktiveerige see selle funktsiooni kasutamiseks</string>\n    <string name=\"draw\">Joonista</string>\n    <string name=\"draw_sub\">Joonistage pildile nagu visandivihikule või joonistage taustale endale</string>\n    <string name=\"paint_color\">Värvi värv</string>\n    <string name=\"paint_alpha\">Alfa värvimine</string>\n    <string name=\"draw_on_image\">Joonista pildile</string>\n    <string name=\"draw_on_image_sub\">Valige pilt ja joonistage sellele midagi</string>\n    <string name=\"draw_on_background\">Joonista taustale</string>\n    <string name=\"draw_on_background_sub\">Valige taustavärv ja joonistage selle peale</string>\n    <string name=\"background_color\">Taustavärv</string>\n    <string name=\"cipher\">Šifr</string>\n    <string name=\"cipher_sub\">Krüptige ja dekrüptige kõik failid (mitte ainult pildid), mis põhinevad erinevatel saadaolevatel krüptoalgoritmidel</string>\n    <string name=\"pick_file\">Vali fail</string>\n    <string name=\"encrypt\">Krüptida</string>\n    <string name=\"decrypt\">Dekrüpteerida</string>\n    <string name=\"pick_file_to_start\">Valige alustamiseks fail</string>\n    <string name=\"decryption\">Dekrüpteerimine</string>\n    <string name=\"encryption\">Krüpteerimine</string>\n    <string name=\"key\">Võti</string>\n    <string name=\"file_proceed\">Fail töödeldud</string>\n    <string name=\"store_file_desc\">Salvestage see fail oma seadmesse või kasutage jagamistoimingut, et panna see kuhu iganes soovite</string>\n    <string name=\"features\">Omadused</string>\n    <string name=\"implementation\">Rakendamine</string>\n    <string name=\"compatibility\">Ühilduvus</string>\n    <string name=\"features_sub\">Paroolipõhine failide krüptimine. Jätkatud faile saab salvestada valitud kataloogi või jagada. Dekrüpteeritud faile saab avada ka otse.</string>\n    <string name=\"implementation_sub\">AES-256, GCM-režiim, polsterduseta, vaikimisi 12-baidised juhuslikud IV-d. Saate valida vajaliku algoritmi. Võtmeid kasutatakse 256-bitiste SHA-3 räsidena</string>\n    <string name=\"file_size\">Faili suurus</string>\n    <string name=\"file_size_sub\">Maksimaalset failisuurust piiravad Android OS ja saadaolev mälu, mis sõltub seadmest. \\nPange tähele: mälu ei ole salvestusruum.</string>\n    <string name=\"compatibility_sub\">Pange tähele, et ühilduvus muude failide krüpteerimistarkvara või -teenustega ei ole garanteeritud. Veidi erinev võtmetöötlus või šifri konfiguratsioon võib põhjustada ühildumatust.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Vale parool või valitud fail pole krüptitud</string>\n    <string name=\"image_size_warning\">Etteantud laiuse ja kõrgusega kujutise salvestamine võib põhjustada mälutõrke. Tehke seda omal riisikol.</string>\n    <string name=\"cache\">Vahemälu</string>\n    <string name=\"cache_size\">Vahemälu suurus</string>\n    <string name=\"found_s\">Leitud %1$s</string>\n    <string name=\"auto_cache_clearing\">Automaatne vahemälu tühjendamine</string>\n    <string name=\"auto_cache_clearing_sub\">Kui see on lubatud, tühjendatakse rakenduse käivitamisel rakenduse vahemälu</string>\n    <string name=\"create\">Loo</string>\n    <string name=\"tools\">Tööriistad</string>\n    <string name=\"group_options_by_type\">Rühmitage valikud tüübi järgi</string>\n    <string name=\"group_options_by_type_sub\">Rühmitab põhiekraanil olevad valikud kohandatud loendi paigutuse asemel nende tüübi järgi</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Paigutust ei saa muuta, kui valikute rühmitamine on lubatud</string>\n    <string name=\"edit_screenshot\">Redigeeri ekraanipilti</string>\n    <string name=\"secondary_customization\">Sekundaarne kohandamine</string>\n    <string name=\"screenshot\">Ekraanipilt</string>\n    <string name=\"fallback_option\">Varuvõimalus</string>\n    <string name=\"skip\">Jäta vahele</string>\n    <string name=\"copy\">Kopeeri</string>\n    <string name=\"warning_bytes\">Režiimis %1$s salvestamine võib olla ebastabiilne, kuna tegemist on kadudeta vorminguga</string>\n    <string name=\"presets_sub\">Kui olete valinud eelseadistuse 125, salvestatakse pilt 125% suurusena originaalpildist. Kui valite eelseadistuse 50, salvestatakse pilt 50% suuruses</string>\n    <string name=\"presets_sub_bytes\">Siinne eelseadistus määrab väljundfaili %, st kui valite 5 MB pildil eelseadistuse 50, saate pärast salvestamist 2,5 MB pildi</string>\n    <string name=\"randomize_filename\">Muutke failinimi juhuslikult</string>\n    <string name=\"randomize_filename_sub\">Kui see on lubatud, on väljundfaili nimi täiesti juhuslik</string>\n    <string name=\"saved_to\">Salvestatud %1$s kausta nimega %2$s</string>\n    <string name=\"saved_to_without_filename\">Salvestatud kausta %1$s</string>\n    <string name=\"tg_chat\">Telegrami vestlus</string>\n    <string name=\"tg_chat_sub\">Arutage rakendust ja saage teistelt kasutajatelt tagasisidet. Sealt saate ka beetavärskendusi ja statistikat.</string>\n    <string name=\"crop_mask\">Põllukultuuri mask</string>\n    <string name=\"aspect_ratio\">Kuvasuhe</string>\n    <string name=\"image_crop_mask_sub\">Kasutage seda maski tüüpi maski loomiseks antud pildist, pange tähele, et sellel PEAKS olema alfakanal</string>\n    <string name=\"backup_and_restore\">Varundamine ja taastamine</string>\n    <string name=\"backup\">Varundamine</string>\n    <string name=\"restore\">Taasta</string>\n    <string name=\"backup_sub\">Varundage oma rakenduse seaded faili</string>\n    <string name=\"restore_sub\">Rakenduse seadete taastamine varem loodud failist</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Rikutud fail või mitte varukoopia</string>\n    <string name=\"settings_restored\">Seadete taastamine õnnestus</string>\n    <string name=\"contact_me\">Võta minuga ühendust</string>\n    <string name=\"reset_settings_sub\">See taastab teie seaded vaikeväärtustele. Pange tähele, et seda ei saa tagasi võtta ilma ülalmainitud varukoopiafailita.</string>\n    <string name=\"delete\">Kustuta</string>\n    <string name=\"delete_color_scheme_warn\">Olete kustutamas valitud värviskeemi. Seda toimingut ei saa tagasi võtta</string>\n    <string name=\"delete_color_scheme_title\">Kustuta skeem</string>\n    <string name=\"font\">Font</string>\n    <string name=\"text\">Tekst</string>\n    <string name=\"font_scale\">Fondi skaala</string>\n    <string name=\"defaultt\">Vaikimisi</string>\n    <string name=\"using_large_fonts_warn\">Suurte fontide kasutamine võib põhjustada kasutajaliidese tõrkeid ja probleeme, mida ei saa parandada. Kasutage ettevaatlikult.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Šš Zz Žž Tt Uu Vv Ww Õõ Ää Öö Üü Xx Yy 0123456789 !?</string>\n    <string name=\"emotions\">Emotsioonid</string>\n    <string name=\"food_and_drink\">Söök ja jook</string>\n    <string name=\"nature_and_animals\">Loodus ja loomad</string>\n    <string name=\"objects\">Objektid</string>\n    <string name=\"symbols\">Sümbolid</string>\n    <string name=\"enable_emoji\">Luba emotikonid</string>\n    <string name=\"travels_and_places\">Reisid ja kohad</string>\n    <string name=\"activities\">Tegevused</string>\n    <string name=\"background_remover\">Tausta eemaldaja</string>\n    <string name=\"background_remover_sub\">Eemaldage pildilt taust joonistades või kasutage valikut Automaatne</string>\n    <string name=\"trim_image\">Kärbi pilti</string>\n    <string name=\"keep_exif_sub\">Kujutise algsed metaandmed säilitatakse</string>\n    <string name=\"trim_image_sub\">Läbipaistvad ruumid pildi ümber kärbitakse</string>\n    <string name=\"auto_erase_background\">Tausta automaatne kustutamine</string>\n    <string name=\"restore_image\">Taasta pilt</string>\n    <string name=\"erase_mode\">Kustutusrežiim</string>\n    <string name=\"erase_background\">Kustuta taust</string>\n    <string name=\"restore_background\">Tausta taastamine</string>\n    <string name=\"blur_radius\">Hägususe raadius</string>\n    <string name=\"pipette\">Pipetti</string>\n    <string name=\"draw_mode\">Joonistamisrežiim</string>\n    <string name=\"create_issue\">Loo probleem</string>\n    <string name=\"something_went_wrong_emphasis\">Oih… Midagi läks valesti. Võite mulle kirjutada, kasutades allolevaid valikuid ja ma püüan leida lahenduse</string>\n    <string name=\"resize_and_convert\">Suuruse muutmine ja teisendamine</string>\n    <string name=\"resize_and_convert_sub\">Muutke antud piltide suurust või teisendage need muudesse vormingutesse. EXIF-i metaandmeid saab siin redigeerida ka ühe pildi valimisel.</string>\n    <string name=\"max_colors_count\">Maksimaalne värvide arv</string>\n    <string name=\"crashlytics_sub\">See võimaldab rakendusel krahhiaruandeid automaatselt koguda</string>\n    <string name=\"analytics\">Analüütika</string>\n    <string name=\"analytics_sub\">Lubage koguda anonüümset rakenduste kasutusstatistikat</string>\n    <string name=\"image_exif_warning\">Praegu võimaldab %1$s-vorming Androidis lugeda ainult EXIF-i metaandmeid. Väljundpildil pole salvestamisel metaandmeid.</string>\n    <string name=\"effort\">Pingutus</string>\n    <string name=\"effort_sub\">Väärtus %1$s tähendab kiiret tihendamist, mille tulemuseks on suhteliselt suur failimaht. %2$s tähendab aeglasemat tihendamist, mille tulemuseks on väiksem fail.</string>\n    <string name=\"wait\">Oota</string>\n    <string name=\"saving_almost_complete\">Salvestamine on peaaegu lõppenud. Praeguse tühistamise korral tuleb uuesti salvestada.</string>\n    <string name=\"updates\">Värskendused</string>\n    <string name=\"allow_betas\">Luba beetaversioonid</string>\n    <string name=\"allow_betas_sub\">Värskenduste kontrollimine hõlmab rakenduse beetaversioone, kui see on lubatud</string>\n    <string name=\"draw_arrows\">Joonista nooled</string>\n    <string name=\"draw_arrows_sub\">Kui see on lubatud, kujutatakse joonistamise teed osutava noolena</string>\n    <string name=\"brush_softness\">Pintsli pehmus</string>\n    <string name=\"crop_description\">Pildid kärbitakse keskelt sisestatud suuruseni. Lõuendit laiendatakse antud taustavärviga, kui pilt on sisestatud mõõtmetest väiksem.</string>\n    <string name=\"donation\">Annetus</string>\n    <string name=\"image_stitching\">Piltide õmblemine</string>\n    <string name=\"image_stitching_sub\">Kombineerige antud pildid, et saada üks suur</string>\n    <string name=\"pick_at_least_two_images\">Valige vähemalt 2 pilti</string>\n    <string name=\"output_image_scale\">Väljundpildi skaala</string>\n    <string name=\"image_orientation\">Pildi suund</string>\n    <string name=\"horizontal\">Horisontaalne</string>\n    <string name=\"vertical\">Vertikaalne</string>\n    <string name=\"scale_small_images_to_large\">Skaalake väikesed pildid suureks</string>\n    <string name=\"scale_small_images_to_large_sub\">Kui see on lubatud, skaleeritakse väikesed pildid järjestuse suurimaks</string>\n    <string name=\"images_order\">Piltide järjekord</string>\n    <string name=\"regular\">Regulaarne</string>\n    <string name=\"blur_edges\">Hägusad servad</string>\n    <string name=\"blur_edges_sub\">Kui see on lubatud, joonistab algkujutise alla udused servad, et täita selle ümber olevad ruumid ühe värvi asemel</string>\n    <string name=\"pixelation\">Pikselatsioon</string>\n    <string name=\"enhanced_pixelation\">Täiustatud pikslistamine</string>\n    <string name=\"stroke_pixelation\">Stroke Pixelation</string>\n    <string name=\"enhanced_diamond_pixelation\">Täiustatud teemantpikselatsioon</string>\n    <string name=\"diamond_pixelation\">Teemantpikselatsioon</string>\n    <string name=\"circle_pixelation\">Ringi pikselatsioon</string>\n    <string name=\"enhanced_circle_pixelation\">Täiustatud ringikujuline pikselatsioon</string>\n    <string name=\"replace_color\">Asenda Värv</string>\n    <string name=\"tolerance\">Tolerantsus</string>\n    <string name=\"color_to_replace\">Asendatav värv</string>\n    <string name=\"target_color\">Sihtvärv</string>\n    <string name=\"color_to_remove\">Eemaldatav värv</string>\n    <string name=\"remove_color\">Eemalda värv</string>\n    <string name=\"recode\">Ümberkodeerida</string>\n    <string name=\"pixel_size\">Piksli suurus</string>\n    <string name=\"lock_draw_orientation\">Lukusta joonistussuund</string>\n    <string name=\"lock_draw_orientation_sub\">Kui see on joonistusrežiimis lubatud, siis ekraan ei pöörle</string>\n    <string name=\"check_for_updates\">Kontrollige värskendusi</string>\n    <string name=\"palette_style\">Paleti stiil</string>\n    <string name=\"tonal_spot\">Tonaalne koht</string>\n    <string name=\"neutral\">Neutraalne</string>\n    <string name=\"vibrant\">Elav</string>\n    <string name=\"expressive\">Ekspressiivne</string>\n    <string name=\"rainbow\">Vikerkaar</string>\n    <string name=\"fruit_salad\">Puuvilja salat</string>\n    <string name=\"fidelity\">Truudus</string>\n    <string name=\"content\">Sisu</string>\n    <string name=\"tonal_spot_sub\">Vaikimisi paleti stiil, see võimaldab kohandada kõiki nelja värvi, teised võimaldavad teil määrata ainult võtmevärvi</string>\n    <string name=\"neutral_sub\">Stiil, mis on pisut kromaatilisem kui ühevärviline</string>\n    <string name=\"vibrant_sub\">Kõva teema, esmase paleti jaoks on värvilisus maksimaalne, teiste jaoks suurenenud</string>\n    <string name=\"playful_scheme\">Mänguline teema – lähtevärvi toon ei ilmu teemasse</string>\n    <string name=\"monochrome_sub\">Monokroomne teema, värvid on puhtalt must / valge / hall</string>\n    <string name=\"content_sub\">Skeem, mis asetab lähtevärvi kausta Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Skeem, mis on sisuskeemiga väga sarnane</string>\n    <string name=\"foss_update_checker_warning\">See värskenduste kontrollija loob ühenduse GitHubiga, et kontrollida, kas uus värskendus on saadaval</string>\n    <string name=\"attention\">Tähelepanu</string>\n    <string name=\"fading_edges\">Häälevad servad</string>\n    <string name=\"disabled\">Keelatud</string>\n    <string name=\"both\">Mõlemad</string>\n    <string name=\"invert_colors\">Inverteeri värvid</string>\n    <string name=\"invert_colors_sub\">Kui see on lubatud, asendab teema värvid negatiivsetega</string>\n    <string name=\"search_option\">Otsi</string>\n    <string name=\"search_option_sub\">Võimaldab otsida põhiekraanil kõiki saadaolevaid tööriistu</string>\n    <string name=\"pdf_tools\">PDF-tööriistad</string>\n    <string name=\"pdf_tools_sub\">Töötage PDF-failidega: eelvaade, teisendage piltide partiiks või looge see antud piltidest</string>\n    <string name=\"preview_pdf\">PDF-i eelvaade</string>\n    <string name=\"pdf_to_images\">PDF pildiks</string>\n    <string name=\"images_to_pdf\">Pildid PDF-i</string>\n    <string name=\"preview_pdf_sub\">Lihtne PDF-i eelvaade</string>\n    <string name=\"pdf_to_images_sub\">Teisendage PDF piltideks antud väljundvormingus</string>\n    <string name=\"images_to_pdf_sub\">Pakkige antud pildid väljundisse PDF-faili</string>\n    <string name=\"mask_filter\">Maski filter</string>\n    <string name=\"mask_filter_sub\">Kasutage antud maskeeritud aladele filtrikette, iga maski piirkond saab määrata oma filtrite komplekti</string>\n    <string name=\"masks\">Maskid</string>\n    <string name=\"add_mask\">Lisa mask</string>\n    <string name=\"mask_indexed\">Mask %d</string>\n    <string name=\"mask_color\">Maski värv</string>\n    <string name=\"mask_preview\">Maski eelvaade</string>\n    <string name=\"mask_preview_sub\">Joonistatud filtrimask renderdatakse, et näidata teile ligikaudset tulemust</string>\n    <string name=\"inverse_fill_type\">Pöördtäidise tüüp</string>\n    <string name=\"inverse_fill_type_sub\">Kui see on lubatud, filtreeritakse vaikekäitumise asemel kõik maskeerimata alad</string>\n    <string name=\"delete_mask_warn\">Olete kustutamas valitud filtrimaski. Seda toimingut ei saa tagasi võtta</string>\n    <string name=\"delete_mask\">Kustuta mask</string>\n    <string name=\"full_filter\">Täielik filter</string>\n    <string name=\"full_filter_sub\">Kasutage antud piltidele või üksikule pildile mis tahes filtrikette</string>\n    <string name=\"start_position\">Alusta</string>\n    <string name=\"center_position\">Keskus</string>\n    <string name=\"end_position\">Lõpp</string>\n    <string name=\"simple_variants\">Lihtsad variandid</string>\n    <string name=\"highlighter\">Esiletõstja</string>\n    <string name=\"neon\">Neoon</string>\n    <string name=\"pen\">Pliiats</string>\n    <string name=\"privacy_blur\">Privaatsuse hägu</string>\n    <string name=\"highlighter_sub\">Joonistage poolläbipaistvad teritatud markeriteed</string>\n    <string name=\"neon_sub\">Lisage oma joonistele mõni helendav efekt</string>\n    <string name=\"pen_sub\">Vaikimisi, kõige lihtsam – ainult värv</string>\n    <string name=\"privacy_blur_sub\">Hägustab pildi joonistatud tee all, et kaitsta kõike, mida soovite peita</string>\n    <string name=\"pixelation_sub\">Sarnaselt privaatsuse hägustamisele, kuid hägustamise asemel pikslib</string>\n    <string name=\"containers_shadow\">Konteinerid</string>\n    <string name=\"containers_shadow_sub\">Joonista konteinerite taha vari</string>\n    <string name=\"sliders_shadow\">Liugurid</string>\n    <string name=\"switches_shadow\">Lülitid</string>\n    <string name=\"fabs_shadow\">FAB-id</string>\n    <string name=\"buttons_shadow\">Nupud</string>\n    <string name=\"sliders_shadow_sub\">Joonistage liugurite taha vari</string>\n    <string name=\"switches_shadow_sub\">Joonista lülitite taha vari</string>\n    <string name=\"fabs_shadow_sub\">Joonistage hõljuvate tegevusnuppude taha vari</string>\n    <string name=\"buttons_shadow_sub\">Joonistage nuppude taha vari</string>\n    <string name=\"app_bars_shadow\">Rakenduste ribad</string>\n    <string name=\"app_bars_shadow_sub\">Joonistage vari rakenduse ribade taha</string>\n    <string name=\"value_in_range\">Väärtus vahemikus %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Automaatne pööramine</string>\n    <string name=\"auto_rotate_limits_sub\">Võimaldab pildi orientatsiooni jaoks kasutada piirkasti</string>\n    <string name=\"draw_path_mode\">Teekonna joonistamise režiim</string>\n    <string name=\"double_line_arrow\">Topeltjooneline nool</string>\n    <string name=\"free_drawing\">Tasuta joonistamine</string>\n    <string name=\"double_arrow\">Topeltnool</string>\n    <string name=\"line_arrow\">Joone nool</string>\n    <string name=\"arrow\">Nool</string>\n    <string name=\"line\">Liin</string>\n    <string name=\"free_drawing_sub\">Joonistab sisendväärtusena tee</string>\n    <string name=\"line_sub\">Joonistab tee alguspunktist lõpp-punktini joonena</string>\n    <string name=\"line_arrow_sub\">Joonistab joonena osutava noole alguspunktist lõpp-punkti</string>\n    <string name=\"arrow_sub\">Joonistab etteantud rajalt osutava noole</string>\n    <string name=\"double_line_arrow_sub\">Joonistab topeltnoole alguspunktist lõpp-punkti joonena</string>\n    <string name=\"double_arrow_sub\">Joonistab etteantud rajalt topeltnoole</string>\n    <string name=\"outlined_oval\">Kontuuriga ovaalne</string>\n    <string name=\"outlined_rect\">Välja toodud õp</string>\n    <string name=\"oval\">Ovaalne</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Joonistab otse alguspunktist lõpp-punkti</string>\n    <string name=\"oval_sub\">Joonistab ovaali alguspunktist lõpp-punktini</string>\n    <string name=\"outlined_oval_sub\">Joonistab ovaalse kontuuri alguspunktist lõpp-punktini</string>\n    <string name=\"outlined_rect_sub\">Joonistab sirgjooneliselt alguspunktist lõpp-punktini</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Joonistab suletud täidetud tee antud tee järgi</string>\n    <string name=\"free\">Tasuta</string>\n    <string name=\"horizontal_grid\">Horisontaalne võrk</string>\n    <string name=\"vertical_grid\">Vertikaalne võrk</string>\n    <string name=\"stitch_mode\">Õmblusrežiim</string>\n    <string name=\"rows_count\">Ridade arv</string>\n    <string name=\"columns_count\">Veergude arv</string>\n    <string name=\"no_such_directory\">Kataloogi \\\"%1$s\\\" ei leitud, vahetasime selle vaikekataloogi, palun salvestage fail uuesti</string>\n    <string name=\"clipboard\">Lõikelaud</string>\n    <string name=\"auto_pin\">Automaatne pin</string>\n    <string name=\"auto_pin_sub\">Kui see on lubatud, lisab salvestatud pildi automaatselt lõikelauale</string>\n    <string name=\"vibration\">Vibratsioon</string>\n    <string name=\"vibration_strength\">Vibratsiooni tugevus</string>\n    <string name=\"overwrite_file_requirements\">Failide ülekirjutamiseks peate kasutama \\\"Exploreri\\\" pildiallikat, proovige pilte uuesti valida, oleme muutnud pildiallika vajalikuks</string>\n    <string name=\"overwrite_files\">Failide ülekirjutamine</string>\n    <string name=\"overwrite_files_sub\">Algne fail asendatakse uuega, selle asemel, et salvestada valitud kausta</string>\n    <string name=\"empty\">Tühi</string>\n    <string name=\"suffix\">Sufiks</string>\n    <string name=\"scale_mode\">Skaalarežiim</string>\n    <string name=\"bilinear\">Bilineaarne</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"hann\">Tema</string>\n    <string name=\"hermite\">Erak</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Lähim</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Põhiline</string>\n    <string name=\"default_value\">Vaikeväärtus</string>\n    <string name=\"bilinear_sub\">Lineaarne (või bilineaarne, kahemõõtmeline) interpolatsioon on tavaliselt hea pildi suuruse muutmiseks, kuid põhjustab detailide ebasoovitavat pehmenemist ja võib siiski olla mõnevõrra sakiline</string>\n    <string name=\"bicubic_sub\">Paremate skaleerimismeetodite hulka kuuluvad Lanczose resampling ja Mitchell-Netravali filtrid</string>\n    <string name=\"nearest_sub\">Üks lihtsamaid viise suuruse suurendamiseks, iga piksli asendamine sama värvi pikslitega</string>\n    <string name=\"basic_sub\">Lihtsaim Androidi skaleerimisrežiim, mida kasutatakse peaaegu kõigis rakendustes</string>\n    <string name=\"catmull_sub\">Meetod kontrollpunktide komplekti sujuvaks interpoleerimiseks ja uuesti valimiseks, mida tavaliselt kasutatakse arvutigraafikas sujuvate kõverate loomiseks</string>\n    <string name=\"hann_sub\">Akende funktsioon, mida sageli kasutatakse signaalitöötluses, et minimeerida spektraalset leket ja parandada sagedusanalüüsi täpsust, ahendades signaali servi</string>\n    <string name=\"hermite_sub\">Matemaatiline interpolatsioonitehnika, mis kasutab sujuva ja pideva kõvera loomiseks väärtusi ja tuletisi kõvera segmendi lõpp-punktides</string>\n    <string name=\"lanczos_sub\">Resampling meetod, mis säilitab kvaliteetse interpolatsiooni, rakendades piksliväärtustele kaalutud funktsiooni sinc</string>\n    <string name=\"mitchell_sub\">Resampling meetod, mis kasutab reguleeritavate parameetritega konvolutsioonifiltrit, et saavutada tasakaal skaleeritud pildi teravuse ja antialiasi vahel</string>\n    <string name=\"spline_sub\">Kasutab kõvera või pinna sujuvaks interpoleerimiseks ja lähendamiseks tükkhaaval määratletud polünoomifunktsioone, pakkudes kuju paindlikku ja pidevat esitust</string>\n    <string name=\"only_clip\">Ainult klipp</string>\n    <string name=\"only_clip_sub\">Salvestusruumi ei salvestata ja pilti proovitakse sisestada ainult lõikepuhvrisse</string>\n    <string name=\"restore_background_sub\">Pintsel taastab kustutamise asemel tausta</string>\n    <string name=\"recognize_text\">OCR (teksti tuvastamine)</string>\n    <string name=\"recognize_text_sub\">Tuvastage antud pildilt tekst, toetatud on üle 120 keele</string>\n    <string name=\"picture_has_no_text\">Pildil pole teksti või rakendus ei leidnud seda</string>\n    <string name=\"accuracy\">\\\"Täpsus: %1$s\\\"</string>\n    <string name=\"recognition_type\">Tunnustamise tüüp</string>\n    <string name=\"fast\">Kiire</string>\n    <string name=\"standard\">Standardne</string>\n    <string name=\"best\">Parim</string>\n    <string name=\"no_data\">Andmeid pole</string>\n    <string name=\"download_description\">Tesseracti OCR-i nõuetekohaseks toimimiseks tuleb teie seadmesse alla laadida täiendavad treeningandmed (%1$s).\\nKas soovite %2$s andmeid alla laadida?</string>\n    <string name=\"download\">Laadi alla</string>\n    <string name=\"no_connection\">Ühendust pole, kontrollige seda ja proovige uuesti rongimudelite allalaadimiseks</string>\n    <string name=\"downloaded_languages\">Allalaaditud keeled</string>\n    <string name=\"available_languages\">Saadaolevad keeled</string>\n    <string name=\"segmentation_mode\">Segmenteerimisrežiim</string>\n    <string name=\"use_pixel_switch\">Kasutage Pixel Switchi</string>\n    <string name=\"use_pixel_switch_sub\">Kasutab Google Pixeli sarnast lülitit</string>\n    <string name=\"saved_to_original\">Algses sihtkohas on üle kirjutatud fail nimega %1$s</string>\n    <string name=\"magnifier\">Luup</string>\n    <string name=\"magnifier_sub\">Lubab parema ligipääsetavuse tagamiseks joonistusrežiimides sõrme ülaosas oleva suurendi</string>\n    <string name=\"force_exif_widget_initial_value\">Jõu algväärtus</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Sunnib exif vidina esmalt kontrollima</string>\n    <string name=\"allow_multiple_languages\">Luba mitu keelt</string>\n    <string name=\"slide\">Libistage</string>\n    <string name=\"side_by_side\">Kõrvuti</string>\n    <string name=\"toggle_tap\">Lülita puudutage</string>\n    <string name=\"transparency\">Läbipaistvus</string>\n    <string name=\"rate_app\">Hinda rakendust</string>\n    <string name=\"rate\">Hinda</string>\n    <string name=\"rate_app_sub\">See rakendus on täiesti tasuta, kui soovite, et see muutuks suuremaks, tähistage projekti Githubis 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Ainult orientatsioon ja skripti tuvastamine</string>\n    <string name=\"segmentation_mode_auto_osd\">Automaatne orientatsioon ja skripti tuvastamine</string>\n    <string name=\"segmentation_mode_auto_only\">Ainult auto</string>\n    <string name=\"segmentation_mode_auto\">Automaatne</string>\n    <string name=\"segmentation_mode_single_column\">Üks veerg</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Ühe ploki vertikaalne tekst</string>\n    <string name=\"segmentation_mode_single_block\">Üksik plokk</string>\n    <string name=\"segmentation_mode_single_line\">Üksik rida</string>\n    <string name=\"segmentation_mode_single_word\">Üksik sõna</string>\n    <string name=\"segmentation_mode_circle_word\">Sõna ringiga</string>\n    <string name=\"segmentation_mode_single_char\">Üksik tähemärk</string>\n    <string name=\"segmentation_mode_sparse_text\">Vähene tekst</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Hõreda teksti suund ja skripti tuvastamine</string>\n    <string name=\"segmentation_mode_raw_line\">Toores joon</string>\n    <string name=\"delete_language_sub\">Kas soovite kustutada keele \\\"%1$s\\\" OCR treeningu andmed kõigi tuvastustüüpide või ainult valitud ühe (%2$s) jaoks?</string>\n    <string name=\"current\">Praegune</string>\n    <string name=\"all\">Kõik</string>\n    <string name=\"gradient_maker\">Gradiendi tegija</string>\n    <string name=\"gradient_maker_sub\">Looge etteantud väljundsuurusega gradient kohandatud värvide ja välimuse tüübiga</string>\n    <string name=\"gradient_type_linear\">Lineaarne</string>\n    <string name=\"gradient_type_radial\">Radiaalne</string>\n    <string name=\"gradient_type_sweep\">Pühkima</string>\n    <string name=\"gradient_type\">Gradiendi tüüp</string>\n    <string name=\"center_x\">Keskus X</string>\n    <string name=\"center_y\">Keskus Y</string>\n    <string name=\"tile_mode\">Plaatide režiim</string>\n    <string name=\"tile_mode_repeated\">Korduv</string>\n    <string name=\"tile_mode_mirror\">Peegel</string>\n    <string name=\"tile_mode_clamp\">Klamber</string>\n    <string name=\"tile_mode_decal\">Kleebis</string>\n    <string name=\"color_stops\">Värv peatub</string>\n    <string name=\"add_color\">Lisa värv</string>\n    <string name=\"properties\">Omadused</string>\n    <string name=\"brightness_enforcement\">Heleduse jõustamine</string>\n    <string name=\"screen\">Ekraan</string>\n    <string name=\"gradient_maker_type_image\">Gradiendi ülekate</string>\n    <string name=\"gradient_maker_type_image_sub\">Koostage antud piltide ülaosast mis tahes gradient</string>\n    <string name=\"transformations\">Transformatsioonid</string>\n    <string name=\"camera\">Kaamera</string>\n    <string name=\"camera_sub\">Tehke kaameraga pilti. Pange tähele, et sellest pildiallikast on võimalik hankida ainult üks pilt</string>\n    <string name=\"watermarking\">Vesimärgid</string>\n    <string name=\"watermarking_sub\">Katke pildid kohandatavate teksti/pildi vesimärkidega</string>\n    <string name=\"repeat_watermark\">Korda vesimärki</string>\n    <string name=\"repeat_watermark_sub\">Korrab vesimärki antud asukohas üksiku asemel pildi kohal</string>\n    <string name=\"offset_x\">Nihe X</string>\n    <string name=\"offset_y\">Nihe Y</string>\n    <string name=\"watermark_type\">Vesimärgi tüüp</string>\n    <string name=\"watermarking_image_sub\">Seda pilti kasutatakse vesimärgi mustrina</string>\n    <string name=\"text_color\">Teksti värv</string>\n    <string name=\"overlay_mode\">Ülekatterežiim</string>\n    <string name=\"gif_tools\">GIF-tööriistad</string>\n    <string name=\"gif_tools_sub\">Teisendage pildid GIF-pildiks või eraldage antud GIF-pildist raamid</string>\n    <string name=\"gif_type_to_image\">GIF piltidele</string>\n    <string name=\"gif_type_to_image_sub\">Teisendage GIF-fail piltide komplektiks</string>\n    <string name=\"gif_type_to_gif_sub\">Teisendage piltide partii GIF-failiks</string>\n    <string name=\"gif_type_to_gif\">Pildid GIF-i</string>\n    <string name=\"select_gif_image_to_start\">Alustamiseks valige GIF-pilt</string>\n    <string name=\"use_size_of_first_frame\">Kasutage esimese kaadri suurust</string>\n    <string name=\"use_size_of_first_frame_sub\">Asendage määratud suurus esimese raami mõõtmetega</string>\n    <string name=\"repeat_count\">Korda loendust</string>\n    <string name=\"frame_delay\">Kaadri viivitus</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Kasutage Lassot</string>\n    <string name=\"use_lasso_sub\">Kasutab kustutamiseks Lassot nagu joonistusrežiimis</string>\n    <string name=\"original_image_preview_alpha\">Algse pildi eelvaade Alpha</string>\n    <string name=\"confetti\">Konfettid</string>\n    <string name=\"confetti_sub\">Konfetti näidatakse salvestamise, jagamise ja muude esmaste toimingute puhul</string>\n    <string name=\"secure_mode\">Turvarežiim</string>\n    <string name=\"secure_mode_sub\">Peidab viimaste rakenduste sisu. Seda ei saa jäädvustada ega salvestada.</string>\n    <string name=\"exit\">Välju</string>\n    <string name=\"preview_closing\">Kui lahkute praegu eelvaatest, peate pildid uuesti lisama</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Kvantiseerija</string>\n    <string name=\"gray_scale\">Hall skaala</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinbergi segadus</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvise kohtunik Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra dithering</string>\n    <string name=\"two_row_sierra_dithering\">Kaherealine Sierra dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinsoni segadus</string>\n    <string name=\"stucki_dithering\">Stucki dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Vale Floyd Steinbergi segadus</string>\n    <string name=\"left_to_right_dithering\">Vasakult paremale segamine</string>\n    <string name=\"random_dithering\">Juhuslik dithering</string>\n    <string name=\"simple_threshold_dithering\">Lihtne läve närimine</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Ruumiline sigma</string>\n    <string name=\"median_blur\">Keskmine hägu</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Kasutab kõvera või pinna sujuvaks interpoleerimiseks ja ligikaudseks, paindlikuks ja pidevaks kujundi esituseks tükkhaaval määratletud kahekuubilised polünoomifunktsioonid</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Kallutamise vahetus</string>\n    <string name=\"glitch\">Glitch</string>\n    <string name=\"amount\">Summa</string>\n    <string name=\"seed\">Seeme</string>\n    <string name=\"anaglyph\">Anaglüüf</string>\n    <string name=\"noise\">Müra</string>\n    <string name=\"pixel_sort\">Pikslite sortimine</string>\n    <string name=\"shuffle\">Segamine</string>\n    <string name=\"enhanced_glitch\">Täiustatud tõrge</string>\n    <string name=\"channel_shift_x\">Kanali nihe X</string>\n    <string name=\"channel_shift_y\">Kanalivahetus Y</string>\n    <string name=\"corruption_size\">Korruptsiooni suurus</string>\n    <string name=\"corruption_shift_x\">Korruptsioonivahetus X</string>\n    <string name=\"corruption_shift_y\">Korruptsioonivahetus Y</string>\n    <string name=\"tent_blur\">Telgi hägu</string>\n    <string name=\"side_fade\">Külgmine tuhmumine</string>\n    <string name=\"side\">Külg</string>\n    <string name=\"top\">Üles</string>\n    <string name=\"bottom\">Altpoolt</string>\n    <string name=\"strength\">Tugevus</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anisotroopne difusioon</string>\n    <string name=\"diffusion\">Difusioon</string>\n    <string name=\"conduction\">Juhtimine</string>\n    <string name=\"horizontal_wind_stagger\">Horisontaalne tuule astmeline</string>\n    <string name=\"fast_bilaterial_blur\">Kiire kahepoolne hägu</string>\n    <string name=\"poisson_blur\">Poissoni hägu</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmiline toonide kaardistamine</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"crystallize\">Kristalliseerida</string>\n    <string name=\"stroke_color\">Löögi värv</string>\n    <string name=\"fractal_glass\">Fraktalklaas</string>\n    <string name=\"amplitude\">Amplituud</string>\n    <string name=\"marble\">Marmor</string>\n    <string name=\"turbulence\">Turbulents</string>\n    <string name=\"oil\">Õli</string>\n    <string name=\"water_effect\">Veeefekt</string>\n    <string name=\"just_size\">Suurus</string>\n    <string name=\"frequency_x\">Sagedus X</string>\n    <string name=\"frequency_y\">Sagedus Y</string>\n    <string name=\"amplitude_x\">Amplituud X</string>\n    <string name=\"amplitude_y\">Amplituud Y</string>\n    <string name=\"perlin_distortion\">Perlini moonutus</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgessi toonide kaardistamine</string>\n    <string name=\"speed\">Kiirus</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Värvimaatriks 4x4</string>\n    <string name=\"color_matrix_3x3\">Värvimaatriks 3x3</string>\n    <string name=\"simple_effects\">Lihtsad efektid</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomaalia</string>\n    <string name=\"deutaromaly\">Deuteranomaalia</string>\n    <string name=\"protonomaly\">Protanomaalia</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Öine nägemine</string>\n    <string name=\"warm\">Soe</string>\n    <string name=\"cool\">Lahe</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotoopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Akromatoomia</string>\n    <string name=\"achromatopsia\">Akromatopsia</string>\n    <string name=\"grain\">Teravili</string>\n    <string name=\"unsharp\">Ebaterav</string>\n    <string name=\"pastel\">Pastelne</string>\n    <string name=\"orange_haze\">Oranž udu</string>\n    <string name=\"pink_dream\">Roosa unistus</string>\n    <string name=\"golden_hour\">Kuldne tund</string>\n    <string name=\"hot_summer\">Kuum suvi</string>\n    <string name=\"purple_mist\">Lilla udu</string>\n    <string name=\"sunrise\">Päikesetõus</string>\n    <string name=\"colorful_swirl\">Värviline keeris</string>\n    <string name=\"soft_spring_light\">Pehme kevadvalgusti</string>\n    <string name=\"autumn_tones\">Sügistoonid</string>\n    <string name=\"lavender_dream\">Lavendli unistus</string>\n    <string name=\"cyberpunk\">Küberpunk</string>\n    <string name=\"lemonade_light\">Limonaadi valgus</string>\n    <string name=\"spectral_fire\">Spektraalne tuli</string>\n    <string name=\"night_magic\">Öine maagia</string>\n    <string name=\"fantasy_landscape\">Fantaasia maastik</string>\n    <string name=\"color_explosion\">Värviplahvatus</string>\n    <string name=\"electric_gradient\">Elektriline gradient</string>\n    <string name=\"caramel_darkness\">Karamelli tumedus</string>\n    <string name=\"futuristic_gradient\">Futuristlik gradient</string>\n    <string name=\"green_sun\">Roheline päike</string>\n    <string name=\"rainbow_world\">Vikerkaare maailm</string>\n    <string name=\"deep_purple\">Sügavlilla</string>\n    <string name=\"space_portal\">Kosmoseportaal</string>\n    <string name=\"red_swirl\">Punane keeris</string>\n    <string name=\"digital_code\">Digitaalne kood</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">Rakenduse riba emotikon muutub juhuslikult</string>\n    <string name=\"random_emojis\">Juhuslikud emotikonid</string>\n    <string name=\"random_emojis_error\">Kui emotikonid on keelatud, ei saa te kasutada juhuslikke emotikone</string>\n    <string name=\"emoji_selection_error\">Kui juhuslikud emotikonid on lubatud, ei saa te emotikone valida</string>\n    <string name=\"old_tv\">Vana TV</string>\n    <string name=\"shuffle_blur\">Juhusesine hägu</string>\n    <string name=\"favorite\">Lemmik</string>\n    <string name=\"no_favorite_filters\">Lemmikfiltreid pole veel lisatud</string>\n    <string name=\"image_format\">Pildi formaat</string>\n    <string name=\"icon_shape_sub\">Lisab ikoonide alla konteineri valitud kujuga</string>\n    <string name=\"icon_shape\">Ikooni kuju</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Katkestus</string>\n    <string name=\"uchimura\">Sa ärkad üles</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Üleminek</string>\n    <string name=\"peak\">Tipp</string>\n    <string name=\"color_anomaly\">Värvi anomaalia</string>\n    <string name=\"images_overwritten\">Pildid on algses sihtkohas üle kirjutatud</string>\n    <string name=\"cannot_change_image_format\">Pildivormingut ei saa muuta, kui failide ülekirjutamise valik on lubatud</string>\n    <string name=\"emoji_as_color_scheme\">Emotikonid värviskeemina</string>\n    <string name=\"emoji_as_color_scheme_sub\">Kasutab rakenduse värviskeemina emotikonide põhivärvi, mitte käsitsi määratletud värvi</string>\n    <string name=\"material_you_sub\">Loob pildist Material You paleti</string>\n    <string name=\"dark_colors\">Tumedad Värvid</string>\n    <string name=\"dark_colors_sub\">Kasutab valgusvariandi asemel öörežiimi värviskeemi</string>\n    <string name=\"copy_as_compose_code\">Kopeerige Jetpack Compose koodina</string>\n    <string name=\"ring_blur\">Rõngane hägu</string>\n    <string name=\"cross_blur\">Risti hägu</string>\n    <string name=\"circle_blur\">Ringi hägusus</string>\n    <string name=\"star_blur\">Tähehägu</string>\n    <string name=\"linear_tilt_shift\">Lineaarne Tilt-Shift</string>\n    <string name=\"tags_to_remove\">Eemaldatavad sildid</string>\n    <string name=\"apng_tools\">APNG tööriistad</string>\n    <string name=\"apng_tools_sub\">Teisendage pildid APNG-pildiks või eraldage antud APNG-pildist kaadreid</string>\n    <string name=\"apng_type_to_image\">APNG piltidele</string>\n    <string name=\"apng_type_to_image_sub\">Teisendage APNG-fail piltide partiiks</string>\n    <string name=\"apng_type_to_apng_sub\">Teisendage piltide partii APNG-failiks</string>\n    <string name=\"apng_type_to_apng\">Pildid APNG-sse</string>\n    <string name=\"select_apng_image_to_start\">Alustamiseks valige APNG-pilt</string>\n    <string name=\"motion_blur\">Liikumishägu</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Looge antud failidest või piltidest ZIP-fail</string>\n    <string name=\"drag_handle_width\">Lohista käepideme laius</string>\n    <string name=\"confetti_type\">Konfeti tüüp</string>\n    <string name=\"festive\">Pidulik</string>\n    <string name=\"explode\">Plahvata</string>\n    <string name=\"rain\">Vihma</string>\n    <string name=\"corners\">Nurgad</string>\n    <string name=\"jxl_tools\">JXL tööriistad</string>\n    <string name=\"jxl_tools_sub\">Tehke JXL ~ JPEG ümberkodeerimine ilma kvaliteedi kadumiseta või teisendage GIF/APNG JXL-animatsiooniks</string>\n    <string name=\"jxl_type_to_jpeg\">JXL kuni JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Tehke kadudeta ümberkodeerimine JXL-st JPEG-vormingusse</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Tehke kadudeta ümberkodeerimine JPEG-st JXL-i</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG kuni JXL</string>\n    <string name=\"select_jxl_image_to_start\">Alustamiseks valige JXL-pilt</string>\n    <string name=\"fast_gaussian_blur_2d\">Kiire Gaussi hägu 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Kiire Gaussi hägu 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Kiire Gaussi hägu 4D</string>\n    <string name=\"auto_paste\">Auto lihavõtted</string>\n    <string name=\"auto_paste_sub\">Võimaldab rakendusel lõikelaua andmeid automaatselt kleepida, nii et need ilmuvad põhiekraanile ja saate neid töödelda</string>\n    <string name=\"harmonization_color\">Ühtlustamise värv</string>\n    <string name=\"harmonization_level\">Ühtlustamise tase</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Resampling meetod, mis säilitab kvaliteetse interpolatsiooni, rakendades piksliväärtustele Besseli (jinc) funktsiooni</string>\n    <string name=\"gif_type_to_jxl\">GIF JXL-i</string>\n    <string name=\"gif_type_to_jxl_sub\">Teisendage GIF-pildid JXL-i animeeritud piltideks</string>\n    <string name=\"apng_type_to_jxl\">APNG kuni JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Teisendage APNG-pildid JXL-animeeritud piltideks</string>\n    <string name=\"jxl_type_to_images\">JXL piltidele</string>\n    <string name=\"jxl_type_to_images_sub\">Teisendage JXL-animatsioon piltide partiiks</string>\n    <string name=\"jxl_type_to_jxl\">Pildid JXL-i</string>\n    <string name=\"jxl_type_to_jxl_sub\">Teisendage piltide partii JXL-animatsiooniks</string>\n    <string name=\"behavior\">Käitumine</string>\n    <string name=\"skip_file_picking\">Jätke faili valimine vahele</string>\n    <string name=\"skip_file_picking_sub\">Failivalija kuvatakse valitud ekraanil kohe, kui see on võimalik</string>\n    <string name=\"generate_previews\">Loo eelvaateid</string>\n    <string name=\"generate_previews_sub\">Lubab eelvaate genereerimise, see võib aidata vältida mõne seadme kokkujooksmisi, samuti keelab see mõne redigeerimisfunktsiooni ühe redigeerimisvaliku raames</string>\n    <string name=\"lossy_compression\">Kadunud kompressioon</string>\n    <string name=\"lossy_compression_sub\">Kasutab kadudeta pakkimist, et vähendada faili suurust, mitte kadudeta</string>\n    <string name=\"compression_type\">Kompressiooni tüüp</string>\n    <string name=\"speed_sub\">Reguleerib saadud kujutise dekodeerimise kiirust, see peaks aitama tulemuseks oleva pildi kiiremini avada, väärtus %1$s tähendab kõige aeglasemat dekodeerimist, samas kui %2$s - kiireim, see säte võib suurendada väljundpildi suurust</string>\n    <string name=\"sorting\">Sorteerimine</string>\n    <string name=\"sort_by_date\">Kuupäev</string>\n    <string name=\"sort_by_date_reversed\">Kuupäev (ümberpööratud)</string>\n    <string name=\"sort_by_name\">Nimi</string>\n    <string name=\"sort_by_name_reversed\">Nimi (tagurpidi)</string>\n    <string name=\"channels_configuration\">Kanalite konfiguratsioon</string>\n    <string name=\"header_today\">Täna</string>\n    <string name=\"header_yesterday\">eile</string>\n    <string name=\"embedded_picker\">Manustatud valija</string>\n    <string name=\"embedded_picker_sub\">Image Toolboxi pildivalija</string>\n    <string name=\"no_permissions\">Lubasid pole</string>\n    <string name=\"request\">Taotlus</string>\n    <string name=\"pick_multiple_media\">Valige mitu meediat</string>\n    <string name=\"pick_single_media\">Valige üks meedium</string>\n    <string name=\"pick\">Vali</string>\n    <string name=\"try_again\">Proovi uuesti</string>\n    <string name=\"show_settings_in_landscape\">Kuva seaded maastikul</string>\n    <string name=\"show_settings_in_landscape_sub\">Kui see on keelatud, avatakse rõhtrežiimis sätted ülemise rakenduse riba nupul nagu alati, mitte püsiva nähtava valiku asemel</string>\n    <string name=\"fullscreen_settings\">Täisekraani seaded</string>\n    <string name=\"fullscreen_settings_sub\">Lubage see ja seadete leht avatakse alati täisekraanina, mitte libistatava sahtlilehena</string>\n    <string name=\"switch_type\">Lüliti tüüp</string>\n    <string name=\"compose\">Koosta</string>\n    <string name=\"compose_switch_sub\">Jetpack Compose materjal, mille vahetate</string>\n    <string name=\"material_you_switch_sub\">Materjal, mille vahetate</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Ankru suuruse muutmine</string>\n    <string name=\"pixel_switch\">piksel</string>\n    <string name=\"fluent_switch\">Ladus</string>\n    <string name=\"fluent_switch_sub\">Lüliti, mis põhineb disainisüsteemil \\\"Fluent\\\".</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">\\\"Cupertino\\\" disainisüsteemil põhinev lüliti</string>\n    <string name=\"images_to_svg\">Pildid SVG-sse</string>\n    <string name=\"images_to_svg_sub\">Jälgige antud kujutised SVG-kujutisteks</string>\n    <string name=\"use_sampled_palette\">Kasutage proovide paletti</string>\n    <string name=\"use_sampled_palette_sub\">Kui see suvand on lubatud, valitakse kvantimispalett</string>\n    <string name=\"path_omit\">Tee ära jätta</string>\n    <string name=\"svg_warning\">Selle tööriista kasutamine suurte piltide jälgimiseks ilma skaleerimata ei ole soovitatav, see võib põhjustada krahhi ja pikendada töötlemisaega</string>\n    <string name=\"downscale_image\">Madalam pilt</string>\n    <string name=\"downscale_image_sub\">Enne töötlemist vähendatakse kujutise mõõtmeid madalamaks, mis aitab tööriistal kiiremini ja ohutumalt töötada</string>\n    <string name=\"min_color_ratio\">Minimaalne värvisuhe</string>\n    <string name=\"lines_threshold\">Liinide lävi</string>\n    <string name=\"quadratic_threshold\">Ruutkünnis</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordineerib ümardamise tolerantsi</string>\n    <string name=\"path_scale\">Tee skaala</string>\n    <string name=\"reset_properties\">Lähtesta atribuudid</string>\n    <string name=\"reset_properties_sub\">Kõik atribuudid seatakse vaikeväärtustele, pange tähele, et seda toimingut ei saa tagasi võtta</string>\n    <string name=\"detailed\">Üksikasjalik</string>\n    <string name=\"default_line_width\">Vaikimisi rea laius</string>\n    <string name=\"engine_mode\">Mootori režiim</string>\n    <string name=\"legacy\">Pärand</string>\n    <string name=\"lstm_network\">LSTM võrk</string>\n    <string name=\"legacy_and_lstm\">Pärand ja LSTM</string>\n    <string name=\"convert\">Teisenda</string>\n    <string name=\"convert_sub\">Teisendage pildipartiid antud vormingusse</string>\n    <string name=\"add_new_folder\">Lisa uus kaust</string>\n    <string name=\"tag_bits_per_sample\">Bitti proovi kohta</string>\n    <string name=\"tag_compression\">Kokkusurumine</string>\n    <string name=\"tag_photometric_interpretation\">Fotomeetriline tõlgendamine</string>\n    <string name=\"tag_samples_per_pixel\">Näidised piksli kohta</string>\n    <string name=\"tag_planar_configuration\">Tasapinnaline konfiguratsioon</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Subproovide võtmine</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr positsioneerimine</string>\n    <string name=\"tag_x_resolution\">X resolutsioon</string>\n    <string name=\"tag_y_resolution\">Y Resolutsioon</string>\n    <string name=\"tag_resolution_unit\">Lahutusvõime üksus</string>\n    <string name=\"tag_strip_offsets\">Ribade nihked</string>\n    <string name=\"tag_rows_per_strip\">Rida riba kohta</string>\n    <string name=\"tag_strip_byte_counts\">Riba baitide arv</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG vahetusvorming</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG vahetusvormingu pikkus</string>\n    <string name=\"tag_transfer_function\">Ülekandmise funktsioon</string>\n    <string name=\"tag_white_point\">Valge punkt</string>\n    <string name=\"tag_primary_chromaticities\">Primaarsed kromaatsused</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr koefitsiendid</string>\n    <string name=\"tag_reference_black_white\">Viide Must Valge</string>\n    <string name=\"tag_datetime\">Kuupäev Kellaaeg</string>\n    <string name=\"tag_image_description\">Pildi kirjeldus</string>\n    <string name=\"tag_make\">Tee</string>\n    <string name=\"tag_model\">Mudel</string>\n    <string name=\"tag_software\">Tarkvara</string>\n    <string name=\"tag_artist\">Kunstnik</string>\n    <string name=\"tag_copyright\">Autoriõigus</string>\n    <string name=\"tag_exif_version\">Exif versioon</string>\n    <string name=\"tag_flashpix_version\">Flashpix versioon</string>\n    <string name=\"tag_color_space\">Värviruum</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X dimensioon</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y mõõde</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Tihendatud bitti piksli kohta</string>\n    <string name=\"tag_maker_note\">Tootja märkus</string>\n    <string name=\"tag_user_comment\">Kasutaja kommentaar</string>\n    <string name=\"tag_related_sound_file\">Seotud helifail</string>\n    <string name=\"tag_datetime_original\">Kuupäev Kell Originaal</string>\n    <string name=\"tag_datetime_digitized\">Kuupäev Kell digiteeritud</string>\n    <string name=\"tag_offset_time\">Offset Time</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Offset Time Digitaliseeritud</string>\n    <string name=\"tag_subsec_time\">Alamsekundi aeg</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Time Original</string>\n    <string name=\"tag_subsec_time_digitized\">Alamsekundi aeg digiteeritud</string>\n    <string name=\"tag_exposure_time\">Kokkupuute aeg</string>\n    <string name=\"tag_f_number\">F Number</string>\n    <string name=\"tag_exposure_program\">Kokkupuute programm</string>\n    <string name=\"tag_spectral_sensitivity\">Spektri tundlikkus</string>\n    <string name=\"tag_photographic_sensitivity\">Fotograafiline tundlikkus</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Tundlikkuse tüüp</string>\n    <string name=\"tag_standard_output_sensitivity\">Standardne väljundtundlikkus</string>\n    <string name=\"tag_recommended_exposure_index\">Soovitatav kokkupuuteindeks</string>\n    <string name=\"tag_iso_speed\">ISO kiirus</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO kiirus Latitude yyyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO kiirus Laiuskraad zzz</string>\n    <string name=\"tag_shutter_speed_value\">Säriaja väärtus</string>\n    <string name=\"tag_aperture_value\">Ava väärtus</string>\n    <string name=\"tag_brightness_value\">Heleduse väärtus</string>\n    <string name=\"tag_exposure_bias_value\">Särituse kallutatuse väärtus</string>\n    <string name=\"tag_max_aperture_value\">Maksimaalne ava väärtus</string>\n    <string name=\"tag_subject_distance\">Teema kaugus</string>\n    <string name=\"tag_metering_mode\">Mõõtmisrežiim</string>\n    <string name=\"tag_flash\">Välklamp</string>\n    <string name=\"tag_subject_area\">Teemavaldkond</string>\n    <string name=\"tag_focal_length\">Fookuskaugus</string>\n    <string name=\"tag_flash_energy\">Välgu energia</string>\n    <string name=\"tag_spatial_frequency_response\">Ruumiline sagedusreaktsioon</string>\n    <string name=\"tag_focal_plane_x_resolution\">Fokaaltasandi X eraldusvõime</string>\n    <string name=\"tag_focal_plane_y_resolution\">Fokaaltasandi Y eraldusvõime</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Fokaaltasandi eraldusvõime üksus</string>\n    <string name=\"tag_subject_location\">Teema asukoht</string>\n    <string name=\"tag_exposure_index\">Kokkupuute indeks</string>\n    <string name=\"tag_sensing_method\">Sensatsioonimeetod</string>\n    <string name=\"tag_file_source\">Faili allikas</string>\n    <string name=\"tag_cfa_pattern\">CFA muster</string>\n    <string name=\"tag_custom_rendered\">Kohandatud renderdatud</string>\n    <string name=\"tag_exposure_mode\">Särirežiim</string>\n    <string name=\"tag_white_balance\">Valge tasakaal</string>\n    <string name=\"tag_digital_zoom_ratio\">Digitaalne suumisuhe</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Fookuskaugus In35mm film</string>\n    <string name=\"tag_scene_capture_type\">Stseeni jäädvustamise tüüp</string>\n    <string name=\"tag_gain_control\">Saavuta kontroll</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"tag_saturation\">Küllastus</string>\n    <string name=\"tag_sharpness\">Teravus</string>\n    <string name=\"tag_device_setting_description\">Seadme seadistuse kirjeldus</string>\n    <string name=\"tag_subject_distance_range\">Teema kauguse vahemik</string>\n    <string name=\"tag_image_unique_id\">Pildi kordumatu ID</string>\n    <string name=\"tag_camera_owner_name\">Kaamera omaniku nimi</string>\n    <string name=\"tag_body_serial_number\">Kere seerianumber</string>\n    <string name=\"tag_lens_specification\">Objektiivi spetsifikatsioon</string>\n    <string name=\"tag_lens_make\">Objektiivi valmistamine</string>\n    <string name=\"tag_lens_model\">Objektiivi mudel</string>\n    <string name=\"tag_lens_serial_number\">Objektiivi seerianumber</string>\n    <string name=\"tag_gps_version_id\">GPS-i versiooni ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitude</string>\n    <string name=\"tag_gps_longitude_ref\">GPS pikkuskraad Ref</string>\n    <string name=\"tag_gps_longitude\">GPS pikkuskraad</string>\n    <string name=\"tag_gps_altitude_ref\">GPS-i kõrguse viide</string>\n    <string name=\"tag_gps_altitude\">GPS kõrgus merepinnast</string>\n    <string name=\"tag_gps_timestamp\">GPS-i ajatempel</string>\n    <string name=\"tag_gps_satellites\">GPS-satelliidid</string>\n    <string name=\"tag_gps_status\">GPS-i olek</string>\n    <string name=\"tag_gps_measure_mode\">GPS mõõtmise režiim</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS kiiruse viide</string>\n    <string name=\"tag_gps_speed\">GPS kiirus</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS jälg</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img suuna viide</string>\n    <string name=\"tag_gps_img_direction\">GPS Img suund</string>\n    <string name=\"tag_gps_map_datum\">GPS kaardi kuupäev</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS-i sihtlaiuskraadi viide</string>\n    <string name=\"tag_gps_dest_latitude\">GPS-i sihtlaiuskraad</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS sihtkoha pikkuskraad Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS-i sihtpikkuskraad</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS-i sihtkauguse viide</string>\n    <string name=\"tag_gps_dest_distance\">GPS-i sihtkaugus</string>\n    <string name=\"tag_gps_processing_method\">GPS-i töötlemismeetod</string>\n    <string name=\"tag_gps_area_information\">GPS-piirkonna teave</string>\n    <string name=\"tag_gps_datestamp\">GPS-i kuupäevatempel</string>\n    <string name=\"tag_gps_differential\">GPS diferentsiaal</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H positsioneerimise viga</string>\n    <string name=\"tag_interoperability_index\">Koostalitlusvõime indeks</string>\n    <string name=\"tag_dng_version\">DNG versioon</string>\n    <string name=\"tag_default_crop_size\">Kärpimise vaikesuurus</string>\n    <string name=\"tag_orf_preview_image_start\">Pildi eelvaate algus</string>\n    <string name=\"tag_orf_preview_image_length\">Pildi eelvaate pikkus</string>\n    <string name=\"tag_orf_aspect_frame\">Aspekti raam</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Anduri alumine piir</string>\n    <string name=\"tag_rw2_sensor_left_border\">Anduri vasak ääris</string>\n    <string name=\"tag_rw2_sensor_right_border\">Anduri parem ääris</string>\n    <string name=\"tag_rw2_sensor_top_border\">Anduri ülemine ääris</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Joonistage tekst teele antud fondi ja värviga</string>\n    <string name=\"font_size\">Fondi suurus</string>\n    <string name=\"watermark_size\">Vesimärgi suurus</string>\n    <string name=\"repeat_text\">Korda teksti</string>\n    <string name=\"repeat_text_sub\">Praegust teksti korratakse ühekordse joonistamise asemel kuni tee lõpuni</string>\n    <string name=\"dash_size\">Kriipsu suurus</string>\n    <string name=\"draw_mode_image_sub\">Kasutage valitud pilti, et joonistada see mööda etteantud teed</string>\n    <string name=\"draw_image_sub\">Seda pilti kasutatakse joonistatud tee korduva sisestusena</string>\n    <string name=\"outlined_triangle_sub\">Joonistab kontuuriga kolmnurga alguspunktist lõpp-punkti</string>\n    <string name=\"triangle_sub\">Joonistab kontuuriga kolmnurga alguspunktist lõpp-punkti</string>\n    <string name=\"outlined_triangle\">Kontuuriga kolmnurk</string>\n    <string name=\"triangle\">Kolmnurk</string>\n    <string name=\"polygon_sub\">Joonistab hulknurga alguspunktist lõpp-punkti</string>\n    <string name=\"polygon\">Hulknurk</string>\n    <string name=\"outlined_polygon\">Piiratud hulknurk</string>\n    <string name=\"outlined_polygon_sub\">Joonistab piiritletud hulknurga alguspunktist lõpp-punktini</string>\n    <string name=\"vertices\">Tipud</string>\n    <string name=\"draw_regular_polygon\">Joonistage korrapärane hulknurk</string>\n    <string name=\"draw_regular_polygon_sub\">Joonistage hulknurk, mis on vaba vormi asemel korrapärane</string>\n    <string name=\"star_sub\">Joonistab tähe alguspunktist lõpp-punkti</string>\n    <string name=\"star\">Täht</string>\n    <string name=\"outlined_star\">Kontuuriga täht</string>\n    <string name=\"outlined_star_sub\">Joonistab kontuuriga tähe alguspunktist lõpp-punktini</string>\n    <string name=\"inner_radius_ratio\">Sisemise raadiuse suhe</string>\n    <string name=\"draw_regular_star\">Joonistage tavaline täht</string>\n    <string name=\"draw_regular_star_sub\">Joonistage täht, mis on vaba vormi asemel tavaline</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Võimaldab antialiasi, et vältida teravaid servi</string>\n    <string name=\"open_edit_instead_of_preview\">Ava eelvaate asemel Redigeerimine</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Kui valite ImageToolboxis avatava (eelvaate) pildi, avatakse eelvaate asemel redigeerimise valikuleht</string>\n    <string name=\"document_scanner\">Dokumendi skanner</string>\n    <string name=\"document_scanner_sub\">Skannige dokumente ja looge PDF-faile või eraldage neist pilte</string>\n    <string name=\"click_to_start_scanning\">Klõpsake skannimise alustamiseks</string>\n    <string name=\"start_scanning\">Alustage skannimist</string>\n    <string name=\"save_as_pdf\">Salvesta pdf-ina</string>\n    <string name=\"share_as_pdf\">Jaga pdf-ina</string>\n    <string name=\"options_below_is_for_images\">Allolevad valikud on mõeldud piltide, mitte PDF-i salvestamiseks</string>\n    <string name=\"equalize_histogram_hsv\">HSV histogrammi võrdsustamine</string>\n    <string name=\"equalize_histogram\">Histogrammi võrdsustamine</string>\n    <string name=\"enter_percentage\">Sisestage protsent</string>\n    <string name=\"allow_enter_by_text_field\">Luba sisestada tekstivälja kaudu</string>\n    <string name=\"allow_enter_by_text_field_sub\">Lubab eelseadistuste valiku taga oleva tekstivälja, et need käigupealt sisestada</string>\n    <string name=\"scale_color_space\">Skaala värviruum</string>\n    <string name=\"linear\">Lineaarne</string>\n    <string name=\"equalize_histogram_pixelation\">Histogrammi pikslituse võrdsustamine</string>\n    <string name=\"grid_size_x\">Võre suurus X</string>\n    <string name=\"grid_size_y\">Võre suurus Y</string>\n    <string name=\"equalize_histogram_adaptive\">Histogrammi võrdsustamine adaptiivne</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Histogrammi kohanduva LUV-i võrdsustamine</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Ühtlustada histogrammi adaptiivne LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Kärbi sisu</string>\n    <string name=\"frame_color\">Raami värv</string>\n    <string name=\"color_to_ignore\">Värv, mida ignoreerida</string>\n    <string name=\"template\">Mall</string>\n    <string name=\"no_template_filters\">Mallfiltreid pole lisatud</string>\n    <string name=\"create_new\">Loo uus</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Skannitud QR-kood ei ole kehtiv filtrimall</string>\n    <string name=\"scan_qr_code\">Skaneeri QR-kood</string>\n    <string name=\"opened_file_have_no_filter_template\">Valitud failil puuduvad filtrimalli andmed</string>\n    <string name=\"create_template\">Loo mall</string>\n    <string name=\"template_name\">Malli nimi</string>\n    <string name=\"select_template_preview\">Seda pilti kasutatakse selle filtrimalli eelvaateks</string>\n    <string name=\"template_filter\">Malli filter</string>\n    <string name=\"as_qr_code\">QR-koodi pildina</string>\n    <string name=\"as_file\">Failina</string>\n    <string name=\"save_as_file\">Salvesta failina</string>\n    <string name=\"save_as_qr_code_image\">Salvesta QR-koodi kujutisena</string>\n    <string name=\"delete_template\">Kustuta mall</string>\n    <string name=\"delete_template_warn\">Olete kustutamas valitud mallifiltrit. Seda toimingut ei saa tagasi võtta</string>\n    <string name=\"added_filter_template\">Lisatud filtrimall nimega \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Filtri eelvaade</string>\n    <string name=\"qr_code\">QR ja vöötkood</string>\n    <string name=\"qr_code_sub\">Skannige QR-kood ja hankige selle sisu või kleepige oma string uue koodi loomiseks</string>\n    <string name=\"code_content\">Koodi sisu</string>\n    <string name=\"scan_qr_code_to_replace_content\">Skannige mis tahes vöötkoodi, et väljal sisu asendada, või sisestage midagi, et luua valitud tüüpi uus vöötkood</string>\n    <string name=\"qr_description\">QR-kirjeldus</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Andke seadetes kaamera luba QR-koodi skannimiseks</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Andke seadetes kaamerale luba dokumendiskanneri skannimiseks</string>\n    <string name=\"cubic\">Kuubik</string>\n    <string name=\"bspline\">B-spliin</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadriric</string>\n    <string name=\"gaussian\">Gaussi</string>\n    <string name=\"sphinx\">Sfinks</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spliin 16</string>\n    <string name=\"spline36\">Spliin 36</string>\n    <string name=\"spline64\">Spliin 64</string>\n    <string name=\"kaiser\">Keiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Kast</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kuupinterpolatsioon tagab sujuvama skaleerimise, võttes arvesse lähimat 16 pikslit, andes paremaid tulemusi kui bilineaarne</string>\n    <string name=\"bspline_sub\">Kasutab kõvera või pinna sujuvaks interpoleerimiseks ja lähendamiseks tükikaupa määratletud polünoomifunktsioone, paindlikku ja pidevat kujundit</string>\n    <string name=\"hamming_sub\">Aknafunktsioon, mida kasutatakse spektraalse lekke vähendamiseks signaali servade kitsendamise teel, mis on kasulik signaalitöötluses</string>\n    <string name=\"hanning_sub\">Hanni akna variant, mida tavaliselt kasutatakse signaalitöötlusrakendustes spektraallekke vähendamiseks</string>\n    <string name=\"blackman_sub\">Aknafunktsioon, mis tagab hea sageduseraldusvõime, minimeerides spektraalset leket ja mida kasutatakse sageli signaalitöötluses</string>\n    <string name=\"welch_sub\">Aknafunktsioon, mis on loodud hea sageduseraldusvõime tagamiseks koos vähendatud spektraallekkega, mida kasutatakse sageli signaalitöötlusrakendustes</string>\n    <string name=\"quadric_sub\">Meetod, mis kasutab interpoleerimiseks ruutfunktsiooni, pakkudes sujuvaid ja pidevaid tulemusi</string>\n    <string name=\"gaussian_sub\">Interpolatsioonimeetod, mis rakendab Gaussi funktsiooni, mis on kasulik piltide müra tasandamiseks ja vähendamiseks</string>\n    <string name=\"sphinx_sub\">Täiustatud resamplimise meetod, mis pakub kvaliteetset interpolatsiooni minimaalsete artefaktidega</string>\n    <string name=\"bartlett_sub\">Kolmnurkse akna funktsioon, mida kasutatakse signaalitöötluses spektraalse lekke vähendamiseks</string>\n    <string name=\"robidoux_sub\">Kvaliteetne interpolatsioonimeetod, mis on optimeeritud loomuliku pildi suuruse muutmiseks, tasakaalustades teravust ja sujuvust</string>\n    <string name=\"robidoux_sharp_sub\">Robidouxi meetodi teravam variant, optimeeritud terava pildi suuruse muutmiseks</string>\n    <string name=\"spline16_sub\">Splainipõhine interpolatsioonimeetod, mis tagab sujuva tulemuse, kasutades 16-puudutusega filtrit</string>\n    <string name=\"spline36_sub\">Splainipõhine interpolatsioonimeetod, mis tagab sujuva tulemuse, kasutades 36-puudutusega filtrit</string>\n    <string name=\"spline64_sub\">Splainipõhine interpolatsioonimeetod, mis tagab sujuva tulemuse, kasutades 64-puudutusega filtrit</string>\n    <string name=\"kaiser_sub\">Interpolatsioonimeetod, mis kasutab Kaiseri akent, pakkudes head kontrolli põhisagara laiuse ja külgsagara taseme vahelise kompromissi üle</string>\n    <string name=\"bartlett_hann_sub\">Hübriidakna funktsioon, mis ühendab Bartletti ja Hanni aknad, mida kasutatakse signaalitöötluse spektraallekke vähendamiseks</string>\n    <string name=\"box_sub\">Lihtne uuesti diskreetimismeetod, mis kasutab lähimate piksliväärtuste keskmist, mille tulemuseks on sageli blokeeritud välimus</string>\n    <string name=\"bohman_sub\">Aknafunktsioon, mida kasutatakse spektraalse lekke vähendamiseks, pakkudes signaalitöötlusrakendustes head sageduseraldusvõimet</string>\n    <string name=\"lanczos2_sub\">Resampling meetod, mis kasutab 2-sagaralist Lanczose filtrit kvaliteetse interpolatsiooni jaoks minimaalsete artefaktidega</string>\n    <string name=\"lanczos3_sub\">Resampling meetod, mis kasutab 3-sagaralist Lanczose filtrit kvaliteetse interpolatsiooni jaoks minimaalsete artefaktidega</string>\n    <string name=\"lanczos4_sub\">Resampling meetod, mis kasutab 4-sagaralist Lanczose filtrit kvaliteetse interpolatsiooni jaoks minimaalsete artefaktidega</string>\n    <string name=\"lanczos2_jinc_sub\">Lanczos 2 filtri variant, mis kasutab jinc-funktsiooni, pakkudes kvaliteetset interpolatsiooni minimaalsete artefaktidega</string>\n    <string name=\"lanczos3_jinc_sub\">Lanczos 3 filtri variant, mis kasutab jinc-funktsiooni, pakkudes kvaliteetset interpolatsiooni minimaalsete artefaktidega</string>\n    <string name=\"lanczos4_jinc_sub\">Lanczos 4 filtri variant, mis kasutab jinc-funktsiooni, pakkudes kvaliteetset interpolatsiooni minimaalsete artefaktidega</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Hanningi filtri elliptiline kaalutud keskmine (EWA) variant sujuvaks interpoleerimiseks ja uuesti diskreetimiseks</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Robidouxi filtri elliptiline kaalutud keskmine (EWA) variant kvaliteetseks uuesti proovivõtuks</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Blackmani filtri elliptiline kaalutud keskmine (EWA) variant helisevate artefaktide minimeerimiseks</string>\n    <string name=\"ewa_quadric\">Kvadriline EWA</string>\n    <string name=\"ewa_quadric_sub\">Quadric filtri elliptiline kaalutud keskmine (EWA) variant sujuvaks interpoleerimiseks</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Robidoux Sharpi filtri elliptiline kaalutud keskmine (EWA) variant teravamate tulemuste saamiseks</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Lanczos 3 Jinci filtri elliptiline kaalutud keskmine (EWA) variant kvaliteetseks uuesti proovivõtuks vähendatud aliasidega</string>\n    <string name=\"ginseng\">Ženšenn</string>\n    <string name=\"ginseng_sub\">Resampling filter, mis on loodud kvaliteetseks pilditöötluseks koos hea teravuse ja sujuvuse tasakaaluga</string>\n    <string name=\"ewa_ginseng\">Ženšenn EWA</string>\n    <string name=\"ewa_ginseng_sub\">Ženšenni filtri elliptiline kaalutud keskmine (EWA) variant parema pildikvaliteedi saavutamiseks</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Lanczos Sharpi filtri elliptiline kaalutud keskmine (EWA) variant teravate tulemuste saavutamiseks minimaalsete artefaktidega</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 teravaim EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Lanczos 4 Sharpest filtri elliptiline kaalutud keskmine (EWA) variant üliterava pildi uuesti proovivõtmiseks</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Lanczose pehme filtri elliptiline kaalutud keskmine (EWA) variant sujuvamaks kujutiste uuesti valimiseks</string>\n    <string name=\"haasn_soft\">Haasn Pehme</string>\n    <string name=\"haasn_soft_sub\">Haasni loodud resamplimisfilter sujuvaks ja artefaktivabaks pildi skaleerimiseks</string>\n    <string name=\"format_conversion\">Vormingu teisendamine</string>\n    <string name=\"format_conversion_sub\">Teisendage piltide partii ühest vormingust teise</string>\n    <string name=\"dismiss_forever\">Loobu igaveseks</string>\n    <string name=\"image_stacking\">Piltide virnastamine</string>\n    <string name=\"image_stacking_sub\">Virnastada pilte valitud segamisrežiimidega üksteise peale</string>\n    <string name=\"add_image\">Lisa pilt</string>\n    <string name=\"bins_count\">Prügikastid loevad</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Ühtlustada histogrammi adaptiivne HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Ühtlustada histogrammi adaptiivne HSV</string>\n    <string name=\"edge_mode\">Edge režiim</string>\n    <string name=\"clip\">Klipp</string>\n    <string name=\"wrap\">Mähi</string>\n    <string name=\"color_blind_scheme\">Värvipimedus</string>\n    <string name=\"color_blind_scheme_sub\">Valige režiim, et kohandada teemavärve valitud värvipimeduse variandiga</string>\n    <string name=\"protanomaly_sub\">Raskused eristada punaseid ja rohelisi toone</string>\n    <string name=\"deuteranomaly_sub\">Raskused roheliste ja punaste toonide eristamisel</string>\n    <string name=\"tritanomaly_sub\">Raskused eristada sinist ja kollast tooni</string>\n    <string name=\"protanopia_sub\">Võimetus tajuda punaseid toone</string>\n    <string name=\"deuteranopia_sub\">Suutmatus tajuda rohelisi toone</string>\n    <string name=\"tritanopia_sub\">Suutmatus tajuda siniseid toone</string>\n    <string name=\"achromatomaly_sub\">Vähendatud tundlikkus kõikide värvide suhtes</string>\n    <string name=\"achromatopsia_sub\">Täielik värvipimedus, ainult halli varjundite nägemine</string>\n    <string name=\"not_use_color_blind_scheme\">Ärge kasutage värvipimeduse skeemi</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Värvid on täpselt sellised, nagu teemas määratud</string>\n    <string name=\"sigmoidal\">Sigmoidne</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Lagrange\\'i interpolatsioonifilter järgus 2, mis sobib sujuvate üleminekutega kvaliteetseks kujutise skaleerimiseks</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Lagrange\\'i interpolatsioonifilter järgus 3, mis pakub paremat täpsust ja sujuvamaid tulemusi pildi skaleerimisel</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Lanczose resampling filter kõrgema astmega 6, mis tagab teravama ja täpsema pildi skaleerimise</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Lanczos 6 filtri variant, mis kasutab Jinc-funktsiooni, et parandada kujutise uuesti proovivõtu kvaliteeti</string>\n    <string name=\"linear_box_blur\">Lineaarne kasti hägu</string>\n    <string name=\"linear_tent_blur\">Lineaarne telgi hägu</string>\n    <string name=\"linear_gaussian_box_blur\">Lineaarne Gaussi kasti hägu</string>\n    <string name=\"linear_stack_blur\">Lineaarne virna hägu</string>\n    <string name=\"gaussian_box_blur\">Gaussi kasti hägu</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lineaarne kiire Gaussi hägusus Järgmine</string>\n    <string name=\"linear_fast_gaussian_blur\">Lineaarne kiire Gaussi hägu</string>\n    <string name=\"linear_gaussian_blur\">Lineaarne Gaussi hägu</string>\n    <string name=\"draw_filter_sub\">Valige üks filter, et seda värvina kasutada</string>\n    <string name=\"replace_filter\">Vahetage filter</string>\n    <string name=\"pick_filter_info\">Valige allpool filter, et kasutada seda oma joonisel pintslina</string>\n    <string name=\"tiff_compression_scheme\">TIFF-i tihendamise skeem</string>\n    <string name=\"low_poly\">Madal polü</string>\n    <string name=\"sand_painting\">Liivamaaling</string>\n    <string name=\"image_splitting\">Pildi jagamine</string>\n    <string name=\"image_splitting_sub\">Jagage üks pilt ridade või veergude kaupa</string>\n    <string name=\"fit_to_bounds\">Sobib piiridesse</string>\n    <string name=\"fit_to_bounds_sub\">Kombineerige kärpimise suuruse muutmise režiim selle parameetriga, et saavutada soovitud käitumine (kärpimine/sobita kuvasuhe)</string>\n    <string name=\"languages_imported\">Keelte importimine õnnestus</string>\n    <string name=\"backup_ocr_models\">OCR-mudelite varundamine</string>\n    <string name=\"import_word\">Import</string>\n    <string name=\"export\">Ekspordi</string>\n    <string name=\"position\">positsioon</string>\n    <string name=\"center\">Keskus</string>\n    <string name=\"top_left\">Üleval vasakul</string>\n    <string name=\"top_right\">Üleval paremal</string>\n    <string name=\"bottom_left\">All vasakul</string>\n    <string name=\"bottom_right\">All paremal</string>\n    <string name=\"top_center\">Ülemine keskus</string>\n    <string name=\"center_right\">Keskel paremal</string>\n    <string name=\"bottom_center\">Alumine keskus</string>\n    <string name=\"center_left\">Keskel vasakul</string>\n    <string name=\"target_image\">Sihtpilt</string>\n    <string name=\"palette_transfer\">Paleti ülekanne</string>\n    <string name=\"enhanced_oil\">Täiustatud õli</string>\n    <string name=\"simple_old_tv\">Lihtne vana teler</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Lihtne sketš</string>\n    <string name=\"soft_glow\">Pehme sära</string>\n    <string name=\"color_poster\">Värviline plakat</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Kolmas värv</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Kobaras 2x2 dithering</string>\n    <string name=\"clustered_4x4_dithering\">Kobaras 4x4 dithering</string>\n    <string name=\"clustered_8x8_dithering\">Kobaras 8x8 dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma dithering</string>\n    <string name=\"no_favorite_options_selected\">Lemmikvalikuid pole valitud, lisage need tööriistade lehele</string>\n    <string name=\"add_favorites\">Lisa lemmikud</string>\n    <string name=\"harmony_complementary\">Täiendav</string>\n    <string name=\"harmony_analogous\">Analoogne</string>\n    <string name=\"harmony_triadic\">kolmik</string>\n    <string name=\"harmony_split_complementary\">Tükeldatud Täiendav</string>\n    <string name=\"harmony_tetradic\">Tetradic</string>\n    <string name=\"harmony_square\">Ruut</string>\n    <string name=\"harmony_analogous_complementary\">Analoogne + täiendav</string>\n    <string name=\"color_tools\">Värvitööriistad</string>\n    <string name=\"color_tools_sub\">Segage, looge toone, genereerige toone ja palju muud</string>\n    <string name=\"color_harmonies\">Värvide harmooniad</string>\n    <string name=\"color_shading\">Värvi varjutamine</string>\n    <string name=\"variation\">Variatsioon</string>\n    <string name=\"tints\">Tints</string>\n    <string name=\"tones\">Toonid</string>\n    <string name=\"shades\">Varjud</string>\n    <string name=\"color_mixing\">Värvide segamine</string>\n    <string name=\"color_info\">Värviinfo</string>\n    <string name=\"selected_color\">Valitud värv</string>\n    <string name=\"color_to_mix\">Värv segamiseks</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Kui dünaamilised värvid on sisse lülitatud, ei saa raha kasutada</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Siht-LUT-pilt</string>\n    <string name=\"amatorka\">Amatöör</string>\n    <string name=\"miss_etikate\">Preili etikett</string>\n    <string name=\"soft_elegance\">Pehme elegants</string>\n    <string name=\"soft_elegance_variant\">Pehme elegantsi variant</string>\n    <string name=\"palette_transfer_variant\">Paleti ülekande variant</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Siht-3D LUT-fail (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Küünlavalgus</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Äge Amber</string>\n    <string name=\"fall_colors\">Sügisvärvid</string>\n    <string name=\"film_stock_50\">Filmivaru 50</string>\n    <string name=\"foggy_night\">Udune öö</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Hankige neutraalne LUT-pilt</string>\n    <string name=\"save_empty_lut_sub\">Esmalt kasutage oma lemmikfototöötlusrakendust, et rakendada neutraalsele LUT-ile filter, mille saate siit. Selle korrektseks toimimiseks ei tohi ükski pikslivärv sõltuda teistest pikslitest (nt hägusus ei tööta). Kui olete valmis, kasutage uut LUT-pilti 512*512 LUT-filtri sisendina</string>\n    <string name=\"pop_art\">Popkunst</string>\n    <string name=\"celluloid\">Tselluloid</string>\n    <string name=\"coffee\">Kohv</string>\n    <string name=\"golden_forest\">Kuldne mets</string>\n    <string name=\"greenish\">Rohekas</string>\n    <string name=\"retro_yellow\">Retrokollane</string>\n    <string name=\"links_preview\">Linkide eelvaade</string>\n    <string name=\"links_preview_sub\">Võimaldab linkide eelvaate allalaadimist kohtades, kust saate teksti (QRCode, OCR jne)</string>\n    <string name=\"links\">Lingid</string>\n    <string name=\"ico_size_warning\">ICO-faile saab salvestada ainult maksimaalses suuruses 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF-i WEBP-sse</string>\n    <string name=\"gif_type_to_webp_sub\">Teisendage GIF-pildid WEBP-animeeritud piltideks</string>\n    <string name=\"webp_tools\">WEBP tööriistad</string>\n    <string name=\"webp_tools_sub\">Teisendage pildid WEBP-animeeritud pildiks või eraldage antud WEBP-animatsioonist kaadreid</string>\n    <string name=\"webp_type_to_image\">WEBP piltidele</string>\n    <string name=\"webp_type_to_image_sub\">Teisendage WEBP-fail piltide komplektiks</string>\n    <string name=\"webp_type_to_webp_sub\">Teisendage piltide partii WEBP-failiks</string>\n    <string name=\"webp_type_to_webp\">Pildid WEBP-sse</string>\n    <string name=\"select_webp_image_to_start\">Alustamiseks valige WEBP-pilt</string>\n    <string name=\"manage_storage_extra_types\">Puudub täielik juurdepääs failidele</string>\n    <string name=\"manage_storage_extra_types_sub\">Lubage kõigile failidele juurdepääs, et näha JXL-i, QOI-d ja muid pilte, mida Androidis piltidena ei tuvastata. Ilma loata ei saa Image Toolbox neid pilte näidata</string>\n    <string name=\"default_draw_color\">Joonistuse vaikevärv</string>\n    <string name=\"default_draw_path_mode\">Vaikimisi joonistamise tee režiim</string>\n    <string name=\"add_timestamp\">Lisa ajatempel</string>\n    <string name=\"add_timestamp_sub\">Lubab ajatempli lisamise väljundfaili nimele</string>\n    <string name=\"formatted_timestamp\">Vormindatud ajatempel</string>\n    <string name=\"formatted_timestamp_sub\">Lubage ajatempli vormindamine väljundfaili nimes lihtsate millide asemel</string>\n    <string name=\"enable_timestamps_to_format_them\">Lubage ajatemplid, et valida nende vorming</string>\n    <string name=\"one_time_save_location\">Ühekordne salvestamiskoht</string>\n    <string name=\"one_time_save_location_sub\">Saate vaadata ja redigeerida ühekordseid salvestuskohti, mida saate kasutada, vajutades pikalt salvestamisnuppu enamasti kõigis valikutes</string>\n    <string name=\"recently_used\">Hiljuti kasutatud</string>\n    <string name=\"ci_channel\">CI kanal</string>\n    <string name=\"group\">Grupp</string>\n    <string name=\"image_toolbox_in_telegram\">Pildi tööriistakast Telegramis 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Liituge meie vestlusega, kus saate arutada kõike, mida soovite, ja vaadata ka CI kanalit, kuhu postitan beetaversioone ja teadaandeid</string>\n    <string name=\"ci_channel_sub\">Hankige märguandeid rakenduse uute versioonide kohta ja lugege teadaandeid</string>\n    <string name=\"fit_description\">Sobitage pilt etteantud mõõtmetega ja rakendage taustale hägusust või värvi</string>\n    <string name=\"tools_arrangement\">Tööriistade paigutus</string>\n    <string name=\"group_tools_by_type\">Grupeeri tööriistad tüübi järgi</string>\n    <string name=\"group_tools_by_type_sub\">Rühmitab põhiekraanil olevad tööriistad kohandatud loendi paigutuse asemel nende tüübi järgi</string>\n    <string name=\"default_values\">Vaikeväärtused</string>\n    <string name=\"system_bars_visibility\">Süsteemi ribade nähtavus</string>\n    <string name=\"show_system_bars_by_swipe\">Süsteemiribade kuvamine pühkides</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Lubab pühkimise, et kuvada süsteemiribad, kui need on peidetud</string>\n    <string name=\"auto\">Automaatne</string>\n    <string name=\"hide_all\">Peida kõik</string>\n    <string name=\"show_all\">Näita kõiki</string>\n    <string name=\"hide_nav_bar\">Peida navigeerimisriba</string>\n    <string name=\"hide_status_bar\">Peida olekuriba</string>\n    <string name=\"noise_generation\">Müra tekitamine</string>\n    <string name=\"noise_generation_sub\">Looge erinevaid helisid, nagu Perlin või muud tüüpi helid</string>\n    <string name=\"frequency\">Sagedus</string>\n    <string name=\"noise_type\">Müra tüüp</string>\n    <string name=\"rotation_type\">Pöörlemise tüüp</string>\n    <string name=\"fractal_type\">Fraktaali tüüp</string>\n    <string name=\"octaves\">oktaavid</string>\n    <string name=\"lacunarity\">Lakuuarsus</string>\n    <string name=\"gain\">Kasu</string>\n    <string name=\"weighted_strength\">Kaalutud tugevus</string>\n    <string name=\"ping_pong_strength\">Pingpongi tugevus</string>\n    <string name=\"distance_function\">Kauguse funktsioon</string>\n    <string name=\"return_type\">Tagastamise tüüp</string>\n    <string name=\"jitter\">Värisemine</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"alignment\">Joondamine</string>\n    <string name=\"custom_filename\">Kohandatud failinimi</string>\n    <string name=\"custom_filename_sub\">Valige asukoht ja failinimi, mida kasutatakse praeguse pildi salvestamiseks</string>\n    <string name=\"saved_to_custom\">Salvestatud kohandatud nimega kausta</string>\n    <string name=\"collage_maker\">Kollaažide tegija</string>\n    <string name=\"collage_maker_sub\">Tehke kollaaže kuni 20 pildist</string>\n    <string name=\"collage_type\">Kollaaži tüüp</string>\n    <string name=\"collages_info\">Hoidke pilti, et vahetada, liigutada ja asendi reguleerimiseks suumida</string>\n    <string name=\"disable_rotation\">Keela pööramine</string>\n    <string name=\"disable_rotation_sub\">Takistab piltide pööramist kahe sõrme liigutustega</string>\n    <string name=\"enable_snapping_to_borders\">Luba ääriste külge kinnitamine</string>\n    <string name=\"enable_snapping_to_borders_sub\">Pärast liigutamist või suumimist klõpsavad pildid, et täita raami servad</string>\n    <string name=\"histogram\">Histogramm</string>\n    <string name=\"histogram_sub\">RGB või Brightness kujutise histogramm, mis aitab teil kohandada</string>\n    <string name=\"image_for_histogram\">Seda pilti kasutatakse RGB ja heleduse histogrammide loomiseks</string>\n    <string name=\"tesseract_options\">Tesseracti valikud</string>\n    <string name=\"tesseract_options_sub\">Rakendage tesseract-mootori jaoks mõned sisendmuutujad</string>\n    <string name=\"custom_options\">Kohandatud valikud</string>\n    <string name=\"custom_params_info\">Valikud tuleb sisestada järgmise skeemi järgi: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Automaatne kärpimine</string>\n    <string name=\"free_corners\">Vabad nurgad</string>\n    <string name=\"free_corners_sub\">Kärbi pilti hulknurga kaupa, see parandab ka perspektiivi</string>\n    <string name=\"coerce_points_to_image_bounds\">Sundige punktid kujutise piiridele</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Punkte ei piira pildipiirid, see on kasulik perspektiivi täpsemaks korrigeerimiseks</string>\n    <string name=\"mask\">Mask</string>\n    <string name=\"spot_heal_sub\">Sisu teadlik täitmine joonistatud tee all</string>\n    <string name=\"spot_heal\">Tervenemiskoht</string>\n    <string name=\"use_circle_kernel\">Kasutage Circle Kerneli</string>\n    <string name=\"opening\">Avamine</string>\n    <string name=\"closing\">Sulgemine</string>\n    <string name=\"morphological_gradient\">Morfoloogiline gradient</string>\n    <string name=\"top_hat\">Top Müts</string>\n    <string name=\"black_hat\">Must müts</string>\n    <string name=\"tone_curves\">Toonikõverad</string>\n    <string name=\"reset_curves\">Lähtestage kõverad</string>\n    <string name=\"reset_curves_sub\">Kõverad veeretatakse tagasi vaikeväärtusele</string>\n    <string name=\"line_style\">Joone stiil</string>\n    <string name=\"gap_size\">Vahe suurus</string>\n    <string name=\"dashed\">Katkendlik</string>\n    <string name=\"dot_dashed\">Punkt katkendlik</string>\n    <string name=\"stamped\">Tempel</string>\n    <string name=\"zigzag\">Siksak</string>\n    <string name=\"dashed_sub\">Joonistab määratud vahe suurusega katkendjoone piki tõmmatud rada</string>\n    <string name=\"dot_dashed_sub\">Joonistab punkti ja katkendjoone mööda etteantud teed</string>\n    <string name=\"defaultt_sub\">Lihtsalt vaikimisi sirgjooned</string>\n    <string name=\"stamped_sub\">Joonistab valitud kujundid mööda rada määratud vahedega</string>\n    <string name=\"zigzag_sub\">Joonistab lainelise siksaki mööda teed</string>\n    <string name=\"zigzag_ratio\">Siksak-suhe</string>\n    <string name=\"create_shortcut\">Loo otsetee</string>\n    <string name=\"create_shortcut_title\">Valige kinnitamiseks tööriist</string>\n    <string name=\"create_shortcut_subtitle\">Tööriist lisatakse teie käivitusprogrammi avakuvale otseteena. Vajaliku käitumise saavutamiseks kasutage seda koos sättega \\\"Jäta faili valimine vahele\\\".</string>\n    <string name=\"dont_stack_frames\">Ärge virna raame</string>\n    <string name=\"dont_stack_frames_sub\">Võimaldab eelmiste raamide utiliseerimist, nii et need ei virna üksteise peale</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Raamid liimitakse üksteise sisse</string>\n    <string name=\"crossfade_count\">Crossfade kaadrid loevad</string>\n    <string name=\"threshold_one\">Lävi üks</string>\n    <string name=\"threshold_two\">Lävi kaks</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Peegel 101</string>\n    <string name=\"enhanced_zoom_blur\">Täiustatud suumi hägusus</string>\n    <string name=\"laplacian_simple\">Laplacian Lihtne</string>\n    <string name=\"sobel_simple\">Sobel Lihtne</string>\n    <string name=\"helper_grid\">Abistav võrk</string>\n    <string name=\"helper_grid_sub\">Täpse manipuleerimise hõlbustamiseks kuvatakse joonistusala kohal tugivõrk</string>\n    <string name=\"grid_color\">Võre värv</string>\n    <string name=\"cell_width\">Lahtri laius</string>\n    <string name=\"cell_height\">Lahtri kõrgus</string>\n    <string name=\"compact_selectors\">Kompaktsed valijad</string>\n    <string name=\"compact_selectors_sub\">Mõned valiku juhtelemendid kasutavad vähem ruumi võtmiseks kompaktset paigutust</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Andke seadetes kaamera luba pildi jäädvustamiseks</string>\n    <string name=\"layout\">Paigutus</string>\n    <string name=\"main_screen_title\">Põhiekraani pealkiri</string>\n    <string name=\"constant_rate_factor\">Constant Rate Factor (CRF)</string>\n    <string name=\"crf_sub\">Väärtus %1$s tähendab aeglast tihendamist, mille tulemuseks on suhteliselt väike failimaht. %2$s tähendab kiiremat tihendamist, mille tulemuseks on suur fail.</string>\n    <string name=\"lut_library\">Lut raamatukogu</string>\n    <string name=\"lut_library_sub\">Laadige alla LUT-de kogu, mida saate pärast allalaadimist rakendada</string>\n    <string name=\"lut_library_update_sub\">Värskendage LUT-de kogu (järjekorda pannakse ainult uued), mida saate pärast allalaadimist rakendada</string>\n    <string name=\"filter_preview_image_sub\">Muutke filtrite vaikepildi eelvaadet</string>\n    <string name=\"filter_preview_image\">Pildi eelvaade</string>\n    <string name=\"hide\">Peida</string>\n    <string name=\"show\">Näita</string>\n    <string name=\"slider_type\">Liuguri tüüp</string>\n    <string name=\"fancy\">Uhke</string>\n    <string name=\"material_2\">Materjal 2</string>\n    <string name=\"fancy_sub\">Väljamõeldud liugur. See on vaikevalik</string>\n    <string name=\"material_2_sub\">Materjali 2 liugur</string>\n    <string name=\"material_you_slider_sub\">Liugur Material You</string>\n    <string name=\"apply\">Rakenda</string>\n    <string name=\"center_align_dialog_buttons\">Keskmised dialooginupud</string>\n    <string name=\"center_align_dialog_buttons_sub\">Dialoogide nupud paigutatakse võimaluse korral keskele, mitte vasakule küljele</string>\n    <string name=\"open_source_licenses\">Avatud lähtekoodiga litsentsid</string>\n    <string name=\"open_source_licenses_sub\">Vaadake selles rakenduses kasutatavate avatud lähtekoodiga teekide litsentse</string>\n    <string name=\"area\">Piirkond</string>\n    <string name=\"area_sub\">Resampling kasutades piksli pindala seost. See võib olla eelistatud meetod kujutiste detsimeerimiseks, kuna see annab muare-vabad tulemused. Kui aga pilti suumida, sarnaneb see \\\"Lähima\\\" meetodiga.</string>\n    <string name=\"enable_tonemapping\">Luba Tonemapping</string>\n    <string name=\"enter_percent\">Sisesta %</string>\n    <string name=\"unknown_host\">Saidile ei pääse juurde, proovige kasutada VPN-i või kontrollige, kas URL on õige</string>\n    <string name=\"markup_layers\">Märgistuskihid</string>\n    <string name=\"markup_layers_sub\">Kihtide režiim, mis võimaldab vabalt paigutada pilte, teksti ja muud</string>\n    <string name=\"edit_layer\">Redigeeri kihti</string>\n    <string name=\"layers_on_image\">Kihid pildil</string>\n    <string name=\"layers_on_image_sub\">Kasutage pilti taustana ja lisage sellele erinevad kihid</string>\n    <string name=\"layers_on_background\">Kihid taustal</string>\n    <string name=\"layers_on_background_sub\">Sama mis esimene valik, kuid pildi asemel on värv</string>\n    <string name=\"beta\">Beeta</string>\n    <string name=\"fast_settings_side\">Kiirseadete külg</string>\n    <string name=\"fast_settings_side_sub\">Lisage piltide redigeerimise ajal valitud küljele ujuv riba, millel klõpsamisel avanevad kiired sätted</string>\n    <string name=\"clear_selection\">Tühjenda valik</string>\n    <string name=\"settings_group_visibility_hidden\">Seadete rühm \\\"%1$s\\\" ahendatakse vaikimisi</string>\n    <string name=\"settings_group_visibility_visible\">Seadete gruppi \\\"%1$s\\\" laiendatakse vaikimisi</string>\n    <string name=\"base_64_tools\">Base64 tööriistad</string>\n    <string name=\"base_64_tools_sub\">Dekodeerige Base64 string pildiks või kodeerige pilt Base64 vormingusse</string>\n    <string name=\"base_64\">Alus64</string>\n    <string name=\"not_a_valid_base_64\">Esitatud väärtus ei ole kehtiv Base64 string</string>\n    <string name=\"copy_not_a_valid_base_64\">Tühja või kehtetut Base64 stringi ei saa kopeerida</string>\n    <string name=\"paste_base_64\">Kleebi alus64</string>\n    <string name=\"copy_base_64\">Kopeeri Base64</string>\n    <string name=\"base_64_tips\">Laadige pilt Base64 stringi kopeerimiseks või salvestamiseks. Kui teil on string ise, saate selle pildi saamiseks ülal kleepida</string>\n    <string name=\"save_base_64\">Salvesta Base64</string>\n    <string name=\"share_base_64\">Share Base64</string>\n    <string name=\"options\">Valikud</string>\n    <string name=\"actions\">Tegevused</string>\n    <string name=\"import_base_64\">Impordibaas64</string>\n    <string name=\"base_64_actions\">Base64 toimingud</string>\n    <string name=\"add_outline\">Lisa kontuur</string>\n    <string name=\"add_outline_sub\">Lisage määratud värvi ja laiusega teksti ümber kontuur</string>\n    <string name=\"outline_color\">Kontuuri värv</string>\n    <string name=\"outline_size\">Kontuuri suurus</string>\n    <string name=\"rotation\">Pöörlemine</string>\n    <string name=\"checksum_as_filename\">Kontrollsumma failinimena</string>\n    <string name=\"checksum_as_filename_sub\">Väljundpiltidel on nende andmete kontrollsummale vastav nimi</string>\n    <string name=\"free_software_partner\">Tasuta tarkvara (partner)</string>\n    <string name=\"free_software_partner_sub\">Rohkem kasulikku tarkvara Androidi rakenduste partnerkanalis</string>\n    <string name=\"algorithms\">Algoritm</string>\n    <string name=\"checksum_tools\">Kontrollsumma tööriistad</string>\n    <string name=\"checksum_tools_sub\">Võrrelge kontrollsummasid, arvutage räsi või looge failidest kuueteistkümnendstringe, kasutades erinevaid räsimisalgoritme</string>\n    <string name=\"calculate\">Arvutage</string>\n    <string name=\"text_hash\">Tekst Hash</string>\n    <string name=\"checksum\">Kontrollsumma</string>\n    <string name=\"pick_file_to_checksum\">Valige fail, et arvutada selle kontrollsumma valitud algoritmi alusel</string>\n    <string name=\"enter_text_to_checksum\">Sisestage tekst, et arvutada selle kontrollsumma valitud algoritmi alusel</string>\n    <string name=\"source_checksum\">Allika kontrollsumma</string>\n    <string name=\"checksum_to_compare\">Kontrollsumma võrdluseks</string>\n    <string name=\"match\">Matš!</string>\n    <string name=\"difference\">Erinevus</string>\n    <string name=\"match_sub\">Kontrollsummad on võrdsed, see võib olla ohutu</string>\n    <string name=\"difference_sub\">Kontrollsummad ei ole võrdsed, fail võib olla ohtlik!</string>\n    <string name=\"mesh_gradients\">Võrgusilma gradiendid</string>\n    <string name=\"collection_mesh_gradients_sub\">Vaadake võrgusilma gradientide kogumit</string>\n    <string name=\"wrong_font\">Importida saab ainult TTF- ja OTF-fonte</string>\n    <string name=\"import_font\">Importi font (TTF/OTF)</string>\n    <string name=\"export_fonts\">Ekspordi fonte</string>\n    <string name=\"imported_fonts\">Imporditud fondid</string>\n    <string name=\"error_while_saving\">Viga katse salvestamisel, proovige muuta väljundkausta</string>\n    <string name=\"filename_is_not_set\">Failinimi pole määratud</string>\n    <string name=\"none\">Mitte ühtegi</string>\n    <string name=\"custom_pages\">Kohandatud lehed</string>\n    <string name=\"pages_selection\">Lehtede valik</string>\n    <string name=\"tool_exit_confirmation\">Tööriistast väljumise kinnitus</string>\n    <string name=\"tool_exit_confirmation_sub\">Kui teil on teatud tööriistade kasutamise ajal salvestamata muudatusi ja proovite seda sulgeda, kuvatakse kinnitusdialoog</string>\n    <string name=\"edit_exif_screen\">Redigeerige EXIF-i</string>\n    <string name=\"edit_exif_screen_sub\">Muutke ühe pildi metaandmeid ilma uuesti tihendamiseta</string>\n    <string name=\"edit_exif_tag\">Puudutage saadaolevate siltide muutmiseks</string>\n    <string name=\"change_sticker\">Muuda kleebist</string>\n    <string name=\"fit_width\">Sobiv laius</string>\n    <string name=\"fit_height\">Sobiv kõrgus</string>\n    <string name=\"batch_compare\">Partii võrdlemine</string>\n    <string name=\"pick_files_to_checksum\">Valige fail/failid, et arvutada selle kontrollsumma valitud algoritmi alusel</string>\n    <string name=\"pick_files\">Valige failid</string>\n    <string name=\"pick_directory\">Valige kataloog</string>\n    <string name=\"head_length_scale\">Pea pikkuse skaala</string>\n    <string name=\"stamp\">Tempel</string>\n    <string name=\"timestamp\">Ajatempel</string>\n    <string name=\"format_pattern\">Vorming muster</string>\n    <string name=\"padding\">Polsterdus</string>\n    <string name=\"image_cutting\">Pildi lõikamine</string>\n    <string name=\"image_cutting_sub\">Lõika pildi osa ja ühenda vasakpoolsed (võib olla pöördvõrdeline) vertikaalsete või horisontaalsete joontega</string>\n    <string name=\"vertical_pivot_line\">Vertikaalne pöördejoon</string>\n    <string name=\"horizontal_pivot_line\">Horisontaalne pöördejoon</string>\n    <string name=\"inverse_selection\">Pöördvalik</string>\n    <string name=\"inverse_vertical_selection_sub\">Vertikaalne lõigatud osa jäetakse maha, selle asemel, et lõikeala ümber osi liita</string>\n    <string name=\"inverse_horizontal_selection_sub\">Horisontaalne lõigatud osa jäetakse maha, selle asemel, et lõikeala ümber osi liita</string>\n    <string name=\"collection_mesh_gradients\">Võrgusilma gradientide kogu</string>\n    <string name=\"mesh_gradients_sub\">Looge võrgusilma gradient kohandatud sõlmede arvu ja eraldusvõimega</string>\n    <string name=\"gradient_maker_type_image_mesh\">Võrgusilma gradiendi ülekate</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Koostage etteantud piltide ülaosa võrgusilma gradient</string>\n    <string name=\"points_customization\">Punktide kohandamine</string>\n    <string name=\"grid_size\">Võre suurus</string>\n    <string name=\"resolution_x\">Resolutsioon X</string>\n    <string name=\"resolution_y\">Resolutsioon Y</string>\n    <string name=\"resolution\">Resolutsioon</string>\n    <string name=\"pixel_by_pixel\">Pikslite kaupa</string>\n    <string name=\"highlight_color\">Tõstke esile Värv</string>\n    <string name=\"pixel_comparison_type\">Pikslite võrdluse tüüp</string>\n    <string name=\"scan_barcode\">Skanni vöötkoodi</string>\n    <string name=\"height_ratio\">Kõrguse suhe</string>\n    <string name=\"barcode_type\">Vöötkoodi tüüp</string>\n    <string name=\"enforce_bw\">Jõustada mustvalge</string>\n    <string name=\"enforce_bw_sub\">Vöötkoodipilt on täielikult mustvalge ja seda ei värvita rakenduse teema järgi</string>\n    <string name=\"barcodes_sub\">Skannige mis tahes vöötkoodi (QR, EAN, AZTEC jne) ja hankige selle sisu või kleepige oma tekst uue loomiseks</string>\n    <string name=\"no_barcode_found\">Vöötkoodi ei leitud</string>\n    <string name=\"generated_barcode_will_be_here\">Loodud vöötkood on siin</string>\n    <string name=\"audio_cover_extractor\">Helikaaned</string>\n    <string name=\"audio_cover_extractor_sub\">Ekstraktige helifailidest albumi kaanepildid, toetatakse enamikke levinumaid vorminguid</string>\n    <string name=\"pick_audio_to_start\">Valige alustamiseks heli</string>\n    <string name=\"pick_audio\">Valige heli</string>\n    <string name=\"no_covers_found\">Kaaneid ei leitud</string>\n    <string name=\"send_logs\">Logid saatmine</string>\n    <string name=\"send_logs_sub\">Klõpsake rakenduse logifaili jagamiseks. See aitab mul probleemi tuvastada ja probleeme lahendada</string>\n    <string name=\"crash_title\">Oih… Midagi läks valesti</string>\n    <string name=\"crash_subtitle\">Võite minuga ühendust võtta, kasutades allolevaid valikuid ja ma püüan leida lahenduse.\\n(Ärge unustage logisid lisada)</string>\n    <string name=\"ocr_write_to_file\">Kirjuta faili</string>\n    <string name=\"ocr_write_to_file_sub\">Ekstraktige piltide partiist tekst ja salvestage see ühte tekstifaili</string>\n    <string name=\"ocr_write_to_metadata\">Kirjuta metaandmetesse</string>\n    <string name=\"ocr_write_to_metadata_sub\">Ekstraheerige igast pildist tekst ja asetage see suhteliste fotode EXIF-teabesse</string>\n    <string name=\"invisible_mode\">Nähtamatu režiim</string>\n    <string name=\"invisible_mode_sub\">Kasutage steganograafiat, et luua oma piltide baitide sees silmale nähtamatud vesimärgid</string>\n    <string name=\"use_lsb\">Kasutage LSB-d</string>\n    <string name=\"use_lsb_sub\">Kasutatakse LSB (Less Significant Bit) steganograafia meetodit, muul juhul FD (Frequency Domain) meetodit</string>\n    <string name=\"auto_remove_red_eyes\">Punasilmsuse automaatne eemaldamine</string>\n    <string name=\"password\">Parool</string>\n    <string name=\"unlock\">Avage lukustus</string>\n    <string name=\"pdf_is_protected\">PDF on kaitstud</string>\n    <string name=\"operation_almost_complete\">Operatsioon peaaegu lõpetatud. Nüüd tühistamine nõuab selle taaskäivitamist</string>\n    <string name=\"sort_by_date_modified\">Muutmise kuupäev</string>\n    <string name=\"sort_by_date_modified_reversed\">Muutmise kuupäev (ümberpööratud)</string>\n    <string name=\"sort_by_size\">Suurus</string>\n    <string name=\"sort_by_size_reversed\">Suurus (tagurpidi)</string>\n    <string name=\"sort_by_mime_type\">MIME tüüp</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME tüüp (ümberpööratud)</string>\n    <string name=\"sort_by_extension\">Laiendus</string>\n    <string name=\"sort_by_extension_reversed\">Laiendus (tagurpidi)</string>\n    <string name=\"sort_by_date_added\">Lisamise kuupäev</string>\n    <string name=\"sort_by_date_added_reversed\">Lisamise kuupäev (ümberpööratud)</string>\n    <string name=\"left_to_right\">Vasakult paremale</string>\n    <string name=\"right_to_left\">Paremalt vasakule</string>\n    <string name=\"top_to_bottom\">Ülevalt alla</string>\n    <string name=\"bottom_to_top\">Alt üles</string>\n    <string name=\"liquid_glass\">Vedel klaas</string>\n    <string name=\"liquid_glass_sub\">Lüliti, mis põhineb hiljuti välja kuulutatud IOS 26-l ja selle vedelklaasi disainisüsteemil</string>\n    <string name=\"pick_image_or_base64\">Valige allpool pilt või kleepige/importige Base64 andmed</string>\n    <string name=\"type_image_link\">Alustamiseks tippige pildi link</string>\n    <string name=\"paste_link\">Kleebi link</string>\n    <string name=\"kaleidoscope\">Kaleidoskoop</string>\n    <string name=\"secondary_angle\">Sekundaarne nurk</string>\n    <string name=\"sides\">Küljed</string>\n    <string name=\"channel_mix\">Kanalite segu</string>\n    <string name=\"blue_green\">Sinine roheline</string>\n    <string name=\"red_blue\">Punane sinine</string>\n    <string name=\"green_red\">Roheline punane</string>\n    <string name=\"into_red\">Punaseks</string>\n    <string name=\"into_green\">Roheliseks</string>\n    <string name=\"into_blue\">Sinise sisse</string>\n    <string name=\"cyan\">Tsüaan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Kollane</string>\n    <string name=\"color_halftone\">Värv Pooltoon</string>\n    <string name=\"contour\">Kontuur</string>\n    <string name=\"levels\">Tasemed</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi kristalliseerumine</string>\n    <string name=\"shape\">Kuju</string>\n    <string name=\"stretch\">Venitada</string>\n    <string name=\"randomness\">Juhuslikkus</string>\n    <string name=\"despeckle\">Eemaldage täpid</string>\n    <string name=\"diffuse\">Hajus</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Teine raadius</string>\n    <string name=\"equalize\">võrdsustada</string>\n    <string name=\"glow\">Sära</string>\n    <string name=\"whirl_and_pinch\">Keerake ja näpistage</string>\n    <string name=\"pointillize\">Pointilliseerida</string>\n    <string name=\"border_color\">Äärise värv</string>\n    <string name=\"polar_coordinates\">Polaarkoordinaadid</string>\n    <string name=\"rect_to_polar\">Otse polaarseks</string>\n    <string name=\"polar_to_rect\">Polaarne otse</string>\n    <string name=\"invert_in_circle\">Pöörake ringis ümber</string>\n    <string name=\"reduce_noise\">Vähenda müra</string>\n    <string name=\"simple_solarize\">Lihtne solariseerimine</string>\n    <string name=\"weave\">Kuduma</string>\n    <string name=\"x_gap\">X vahe</string>\n    <string name=\"y_gap\">Y vahe</string>\n    <string name=\"x_width\">X Laius</string>\n    <string name=\"y_wdth\">Y Laius</string>\n    <string name=\"twirl\">Keerake</string>\n    <string name=\"rubber_stmp\">Kummitempel</string>\n    <string name=\"smear\">Määri</string>\n    <string name=\"density\">Tihedus</string>\n    <string name=\"mix\">Sega</string>\n    <string name=\"sphere_lensh_distortion\">Keraobjektiivi moonutused</string>\n    <string name=\"refraction_index\">Murdumisnäitaja</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Levitamise nurk</string>\n    <string name=\"sparkle\">Säde</string>\n    <string name=\"rays\">Kiired</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Maarja</string>\n    <string name=\"autumn\">Sügis</string>\n    <string name=\"bone\">Luu</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Talv</string>\n    <string name=\"ocean\">Ookean</string>\n    <string name=\"summer\">Suvi</string>\n    <string name=\"spring\">Kevad</string>\n    <string name=\"cool_variant\">Lahe variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Roosa</string>\n    <string name=\"hot\">Kuum</string>\n    <string name=\"parula\">Sõna</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Kodanikud</string>\n    <string name=\"twilight\">Hämar</string>\n    <string name=\"twilight_shifted\">Hämarik nihkunud</string>\n    <string name=\"auto_perspective\">Perspektiiv Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Luba kärpida</string>\n    <string name=\"crop_or_perspective\">Põllukultuur või perspektiiv</string>\n    <string name=\"absolute\">Absoluutne</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Sügavroheline</string>\n    <string name=\"lens_correction\">Objektiivi korrigeerimine</string>\n    <string name=\"target_lens_profile\">Sihtobjektiivi profiilifail JSON-vormingus</string>\n    <string name=\"download_ready_lens_profiles\">Laadige alla valmis objektiiviprofiilid</string>\n    <string name=\"part_percents\">Osa protsendid</string>\n    <string name=\"export_as_json\">Ekspordi JSON-ina</string>\n    <string name=\"export_as_json_sub\">Kopeerige palettandmetega string JSON-esitusena</string>\n    <string name=\"seam_carving\">Õmbluste nikerdamine</string>\n    <string name=\"home_screen\">Avakuva</string>\n    <string name=\"lock_screen\">Lukustusekraan</string>\n    <string name=\"built_in\">Sisseehitatud</string>\n    <string name=\"wallpapers_export\">Taustapiltide eksport</string>\n    <string name=\"refresh\">Värskenda</string>\n    <string name=\"wallpapers_export_sub\">Hankige praegused kodu-, luku- ja sisseehitatud taustapildid</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Luba juurdepääs kõikidele failidele, seda on vaja taustapiltide toomiseks</string>\n    <string name=\"allow_read_media_images_for_wp\">Välise salvestusruumi haldamise loast ei piisa, peate lubama juurdepääsu oma piltidele, tehke kindlasti valik \\\"Luba kõik\\\".</string>\n    <string name=\"add_preset_to_filename\">Lisa failinimele eelseade</string>\n    <string name=\"add_preset_to_filename_sub\">Lisab pildifaili nimele sufiks koos valitud eelseadistuse</string>\n    <string name=\"add_image_scale_mode_to_filename\">Lisage failinimele pildiskaala režiim</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Lisab pildifaili nimele sufiks valitud kujutise mõõtkava režiimiga</string>\n    <string name=\"ascii_art\">Ascii art</string>\n    <string name=\"ascii_art_sub\">Teisendage pilt ascii tekstiks, mis näeb välja nagu pilt</string>\n    <string name=\"params\">Parameetrid</string>\n    <string name=\"invert_colors_ascii_sub\">Mõnel juhul rakendab parema tulemuse saavutamiseks pildile negatiivse filtri</string>\n    <string name=\"processing_screenshot\">Ekraanipildi töötlemine</string>\n    <string name=\"screenshot_not_captured_try_again\">Ekraanipilti ei tehtud, proovige uuesti</string>\n    <string name=\"skipped_saving\">Salvestamine jäeti vahele</string>\n    <string name=\"skipped_saving_multiple\">%1$s faili jäeti vahele</string>\n    <string name=\"allow_skip_if_larger\">Luba vahelejätmine, kui suurem</string>\n    <string name=\"allow_skip_if_larger_sub\">Mõnel tööriistal on lubatud piltide salvestamine vahele jätta, kui tulemuseks olev faili suurus on originaalist suurem</string>\n    <string name=\"qr_type_calendar_event\">Kalendri sündmus</string>\n    <string name=\"qr_type_contact_info\">Võtke ühendust</string>\n    <string name=\"qr_type_email\">Meil</string>\n    <string name=\"qr_type_geo_point\">Asukoht</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Tekst</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Avatud võrk</string>\n    <string name=\"not_specified\">Ei kehti</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Sõnum</string>\n    <string name=\"address\">Aadress</string>\n    <string name=\"subject\">Teema</string>\n    <string name=\"body\">Keha</string>\n    <string name=\"name\">Nimi</string>\n    <string name=\"organization\">Organisatsioon</string>\n    <string name=\"title\">Pealkiri</string>\n    <string name=\"phones\">Telefonid</string>\n    <string name=\"emails\">Meilid</string>\n    <string name=\"urls\">URL-id</string>\n    <string name=\"addresses\">Aadressid</string>\n    <string name=\"summary\">Kokkuvõte</string>\n    <string name=\"description\">Kirjeldus</string>\n    <string name=\"location\">Asukoht</string>\n    <string name=\"organizer\">Korraldaja</string>\n    <string name=\"start_date\">Alguskuupäev</string>\n    <string name=\"end_date\">Lõppkuupäev</string>\n    <string name=\"status\">Olek</string>\n    <string name=\"latitude\">Laiuskraad</string>\n    <string name=\"longitude\">Pikkuskraad</string>\n    <string name=\"create_barcode\">Loo vöötkood</string>\n    <string name=\"edit_barcode\">Redigeeri vöötkoodi</string>\n    <string name=\"wifi_configuration\">Wi-Fi konfiguratsioon</string>\n    <string name=\"security\">Turvalisus</string>\n    <string name=\"pick_contact\">Valige kontakt</string>\n    <string name=\"grant_contact_permission\">Andke seadetes kontaktidele luba valitud kontakti kasutades automaatseks täitmiseks</string>\n    <string name=\"contact_info\">Kontaktandmed</string>\n    <string name=\"first_name\">Eesnimi</string>\n    <string name=\"middle_name\">Keskmine nimi</string>\n    <string name=\"last_name\">Perekonnanimi</string>\n    <string name=\"pronunciation\">Hääldus</string>\n    <string name=\"add_phone\">Lisa telefon</string>\n    <string name=\"add_email\">Lisa email</string>\n    <string name=\"add_address\">Lisa aadress</string>\n    <string name=\"website\">Veebisait</string>\n    <string name=\"add_website\">Lisa veebisait</string>\n    <string name=\"formatted_name\">Vormindatud nimi</string>\n    <string name=\"qr_code_top_image\">Seda pilti kasutatakse vöötkoodi kohale paigutamiseks</string>\n    <string name=\"code_customization\">Koodi kohandamine</string>\n    <string name=\"qr_logo_image\">Seda pilti kasutatakse QR-koodi keskel logona</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo polsterdus</string>\n    <string name=\"logo_size\">Logo suurus</string>\n    <string name=\"logo_corners\">Logo nurgad</string>\n    <string name=\"fourth_eye\">Neljas silm</string>\n    <string name=\"fourth_eye_description\">Lisab qr-koodile silmade sümmeetria, lisades alumisse otsanurka neljanda silma</string>\n    <string name=\"pixel_shape\">Piksli kuju</string>\n    <string name=\"frame_shape\">Raami kuju</string>\n    <string name=\"ball_shape\">Palli kuju</string>\n    <string name=\"error_correction_level\">Veaparanduse tase</string>\n    <string name=\"dark_color\">Tume värv</string>\n    <string name=\"light_color\">Hele värv</string>\n    <string name=\"hyper_os\">Hüper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS-ile sarnane stiil</string>\n    <string name=\"mask_pattern\">Maski muster</string>\n    <string name=\"code_may_be_not_scannable\">See kood ei pruugi olla skannitav. Muutke välimuse parameetreid, et see oleks kõigi seadmetega loetav</string>\n    <string name=\"not_scannable\">Pole skannitav</string>\n    <string name=\"launcher_mode_sub\">Tööriistad näevad välja nagu avaekraani rakenduste käivitaja, et need oleksid kompaktsemad</string>\n    <string name=\"launcher_mode\">Käivitusrežiim</string>\n    <string name=\"flood_fill_sub\">Täidab ala valitud pintsli ja stiiliga</string>\n    <string name=\"flood_fill\">Üleujutuse täitmine</string>\n    <string name=\"spray\">Pihusta</string>\n    <string name=\"spray_sub\">Joonistab graffity stiilis tee</string>\n    <string name=\"square_particles\">Ruudukujulised osakesed</string>\n    <string name=\"square_particles_sub\">Pihustusosakesed on ringide asemel ruudukujulised</string>\n    <string name=\"palette_tools\">Paleti tööriistad</string>\n    <string name=\"palette_tools_sub\">Looge pildilt palett põhi-/materjal või importige/eksportige erinevatesse paletivormingutesse</string>\n    <string name=\"edit_palette\">Redigeeri paletti</string>\n    <string name=\"edit_palette_sub\">Ekspordi/impordi palett erinevates vormingutes</string>\n    <string name=\"color_name\">Värvi nimi</string>\n    <string name=\"palette_name\">Paleti nimi</string>\n    <string name=\"palette_format\">Paleti formaat</string>\n    <string name=\"export_palette_sub\">Ekspordi loodud palett erinevatesse vormingutesse</string>\n    <string name=\"add_color_palette_sub\">Lisab praegusele paletile uue värvi</string>\n    <string name=\"palette_name_not_supported\">%1$s vorming ei toeta paleti nime esitamist</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play poe eeskirjade tõttu ei saa seda funktsiooni praegusesse järgmisse kaasata. Sellele funktsioonile juurdepääsemiseks laadige ImageToolbox alla alternatiivsest allikast. GitHubi saadaolevad versioonid leiate allpool.</string>\n    <string name=\"open_github_page\">Avage Githubi leht</string>\n    <string name=\"overwrite_files_sub_short\">Algne fail asendatakse valitud kausta salvestamise asemel uuega</string>\n    <string name=\"hidden_watermark_text_detected\">Tuvastati peidetud vesimärgi tekst</string>\n    <string name=\"hidden_watermark_image_detected\">Tuvastati peidetud vesimärgi kujutis</string>\n    <string name=\"this_image_was_hidden\">See pilt oli peidetud</string>\n    <string name=\"generative_inpaint\">Generatiivne maalimine</string>\n    <string name=\"generative_inpaint_sub\">Võimaldab eemaldada pildilt objekte AI-mudeli abil, ilma OpenCV-le tuginemata. Selle funktsiooni kasutamiseks laadib rakendus GitHubist alla vajaliku mudeli (~200 MB).</string>\n    <string name=\"generative_inpaint_ready_sub\">Võimaldab eemaldada pildilt objekte AI-mudeli abil, ilma OpenCV-le tuginemata. See võib olla pikaajaline operatsioon</string>\n    <string name=\"error_level_analysis\">Veataseme analüüs</string>\n    <string name=\"luminance_gradient\">Heleduse gradient</string>\n    <string name=\"average_distance\">Keskmine vahemaa</string>\n    <string name=\"copy_move_detection\">Kopeeri liikumise tuvastamine</string>\n    <string name=\"retain\">Säilitada</string>\n    <string name=\"coefficent\">Koefitsient</string>\n    <string name=\"clipboard_data_is_too_large\">Lõikelaua andmed on liiga suured</string>\n    <string name=\"data_is_too_large_to_copy\">Andmed on kopeerimiseks liiga suured</string>\n    <string name=\"simple_weave_pixelization\">Lihtne kudumise pikseliseerimine</string>\n    <string name=\"staggered_pixelization\">Ajastatud pikseliseerimine</string>\n    <string name=\"cross_pixelization\">Ristpiksliseerimine</string>\n    <string name=\"micro_macro_pixelization\">Mikro-makropikseliseerimine</string>\n    <string name=\"orbital_pixelization\">Orbitaalne pikseliseerimine</string>\n    <string name=\"vortex_pixelization\">Vorteksi pikseliseerimine</string>\n    <string name=\"pulse_grid_pixelization\">Impulssvõrgu pikseliseerimine</string>\n    <string name=\"nucleus_pixelization\">Tuuma pikseliseerimine</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave Pixelization</string>\n    <string name=\"cannot_open_uri\">Ei saa avada uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Lumesaju režiim</string>\n    <string name=\"enabled\">Lubatud</string>\n    <string name=\"border_frame\">Piiriraam</string>\n    <string name=\"glitch_variant\">Glitchi variant</string>\n    <string name=\"channel_shift\">Kanali nihe</string>\n    <string name=\"max_offset\">Maksimaalne nihe</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blokeeri tõrge</string>\n    <string name=\"block_size\">Ploki suurus</string>\n    <string name=\"crt_curvature\">CRT kõverus</string>\n    <string name=\"curvature\">Kumerus</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Piksli sulamine</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">AI tööriistad</string>\n    <string name=\"ai_tools_sub\">Erinevad tööriistad piltide töötlemiseks AI-mudelite kaudu, näiteks artefaktide eemaldamine või müra summutamine</string>\n    <string name=\"model_anime_undeint\">Kompressioon, sakilised jooned</string>\n    <string name=\"model_broadcast\">Multikad, saate tihendus</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Üldine kompressioon, üldine müra</string>\n    <string name=\"model_wb_denoise\">Värvitu koomiksimüra</string>\n    <string name=\"model_span_anime_pretrain\">Kiire, üldine pakkimine, üldine müra, animatsioon/koomiksid/anime</string>\n    <string name=\"model_book_scan\">Raamatu skaneerimine</string>\n    <string name=\"model_overexposure\">Särituse korrigeerimine</string>\n    <string name=\"model_fbcnn_color_fp16\">Parim üldise tihendamise, värviliste piltide osas</string>\n    <string name=\"model_fbcnn_gray_fp16\">Parimad üldise tihendamise, halltoonides kujutiste puhul</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Üldine tihendus, halltoonides pildid, tugevam</string>\n    <string name=\"model_scunet_color_gan_fp16\">Üldmüra, värvilised pildid</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Üldine müra, värvilised pildid, paremad detailid</string>\n    <string name=\"model_scunet_gray_15_fp16\">Üldine müra, halltoonides pildid</string>\n    <string name=\"model_scunet_gray_25_fp16\">Üldine müra, halltoonides pildid, tugevamad</string>\n    <string name=\"model_scunet_gray_50_fp16\">Üldine müra, halltoonides pildid, tugevaim</string>\n    <string name=\"model_jpeg_destroyer\">Üldine kokkusurumine</string>\n    <string name=\"model_jaywreck\">Üldine kokkusurumine</string>\n    <string name=\"model_h264\">Tekstuurimine, h264 tihendamine</string>\n    <string name=\"model_vhs\">VHS tihendus</string>\n    <string name=\"model_cinepak\">Mittestandardne tihendus (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink kokkusurumine, parem geomeetria</string>\n    <string name=\"model_debink_v5\">Bink kompressioon, tugevam</string>\n    <string name=\"model_debink_v6\">Bink-kompressioon, pehme, säilitab detailid</string>\n    <string name=\"model_antialias\">Trepiastme efekti kõrvaldamine, silumine</string>\n    <string name=\"model_kdm_scans\">Skaneeritud kunst/joonised, kerge kokkusurumine, muaare</string>\n    <string name=\"model_bandage\">Värviriba</string>\n    <string name=\"model_halftone\">Aeglane, pooltoone eemaldav</string>\n    <string name=\"model_colorizer\">Üldine värvimisseade halltoonide/bw piltide jaoks, paremate tulemuste saamiseks kasutage DDColori</string>\n    <string name=\"model_deedge\">Serva eemaldamine</string>\n    <string name=\"model_desharpen\">Eemaldab ületeritamise</string>\n    <string name=\"model_dither\">Aeglane, segane</string>\n    <string name=\"model_gainres\">Antialiasing, üldised artefaktid, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 skannib töötlemist</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Kerge pildiparandusmudel</string>\n    <string name=\"model_bcgone_detailed_v2\">Kompressiooniartefaktide eemaldamine</string>\n    <string name=\"model_bcgone_smooth\">Kompressiooniartefaktide eemaldamine</string>\n    <string name=\"model_bandage_smooth\">Sideme eemaldamine sujuvate tulemustega</string>\n    <string name=\"model_bendel_halftone\">Pooltoonmustri töötlemine</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Mustri eemaldamine V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG artefaktide eemaldamine V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 tekstuuri täiustamine</string>\n    <string name=\"model_vhs_sharpen\">VHS-i teravustamine ja täiustamine</string>\n    <string name=\"merging\">Ühinemine</string>\n    <string name=\"chunk_size\">Tüki suurus</string>\n    <string name=\"overlap_size\">Ülekatte suurus</string>\n    <string name=\"note_chunk_info\">Üle %1$s piksli suurused pildid lõigatakse viiludeks ja töödeldakse tükkidena. Need kattuvad, et vältida nähtavaid õmblusi.</string>\n    <string name=\"large_chunk_warning\">Suured suurused võivad odavate seadmete puhul põhjustada ebastabiilsust</string>\n    <string name=\"select_one_to_start\">Alustamiseks valige üks</string>\n    <string name=\"delete_model_sub\">Kas soovite %1$s mudeli kustutada? Peate selle uuesti alla laadima</string>\n    <string name=\"confirm\">Kinnita</string>\n    <string name=\"models\">Mudelid</string>\n    <string name=\"downloaded_models\">Allalaaditud mudelid</string>\n    <string name=\"available_models\">Saadaolevad mudelid</string>\n    <string name=\"preparing\">Ettevalmistus</string>\n    <string name=\"active_model\">Aktiivne mudel</string>\n    <string name=\"failed_to_open_session\">Seansi avamine ebaõnnestus</string>\n    <string name=\"only_onnx_models\">Importida saab ainult .onnx/.ort mudeleid</string>\n    <string name=\"import_model\">Impordi mudel</string>\n    <string name=\"import_model_sub\">Importige kohandatud onnxi mudel edasiseks kasutamiseks, aktsepteeritakse ainult onnx/ort mudeleid, toetab peaaegu kõiki esrgani sarnaseid variante</string>\n    <string name=\"imported_models\">Imporditud mudelid</string>\n    <string name=\"model_scunet_color_15_fp16\">Üldine müra, värvilised pildid</string>\n    <string name=\"model_scunet_color_25_fp16\">Üldine müra, värvilised pildid, tugevam</string>\n    <string name=\"model_scunet_color_50_fp16\">Üldmüra, värvilised pildid, tugevaim</string>\n    <string name=\"model_artifacts_dithering_alsa\">Vähendab moonutavaid artefakte ja värviribasid, parandades sujuvaid gradiente ja tasaseid värvialasid.</string>\n    <string name=\"model_nmkd_brighten_redux\">Suurendab pildi heledust ja kontrasti tasakaalustatud esiletõstetega, säilitades samal ajal loomulikud värvid.</string>\n    <string name=\"model_nmkd_brighten\">Muudab tumedaid pilte heledamaks, säilitades samal ajal üksikasjad ja vältides ülesäritust.</string>\n    <string name=\"model_nmkd_detoon\">Eemaldab liigse värvitoonuse ning taastab neutraalsema ja loomulikuma värvitasakaalu.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Rakendab Poissoni-põhist müra toonimist, keskendudes peente detailide ja tekstuuride säilitamisele.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Rakendab pehmet Poissoni müra toonimist sujuvamaks ja vähem agressiivseks visuaalseks tulemuseks.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Ühtlane müra toonimine, mis keskendub detailide säilitamisele ja pildi selgusele.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Õrn ühtlane müra toniseerimine peene tekstuuri ja sileda välimuse jaoks.</string>\n    <string name=\"model_repainter\">Parandab kahjustatud või ebatasased alad, värvides uuesti esemeid ja parandades kujutise ühtlust.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Kerge eraldusmudel, mis eemaldab värviribad minimaalse jõudluskuluga.</string>\n    <string name=\"model_jpeg_0_20\">Optimeerib väga suure tihendusartefaktidega pilte (0–20% kvaliteet), et parandada selgust.</string>\n    <string name=\"model_jpeg_20_40\">Täiustab pilte suure tihendusartefaktidega (20–40% kvaliteet), taastades detailid ja vähendades müra.</string>\n    <string name=\"model_jpeg_40_60\">Parandab mõõduka tihendusega pilte (40-60% kvaliteet), tasakaalustades teravust ja sujuvust.</string>\n    <string name=\"model_jpeg_60_80\">Täiustab pilte kerge tihendusega (60–80% kvaliteet), et täiustada peeneid detaile ja tekstuure.</string>\n    <string name=\"model_jpeg_80_100\">Parandab veidi peaaegu kadudeta pilte (80-100% kvaliteet), säilitades samal ajal loomuliku välimuse ja detailid.</string>\n    <string name=\"model_spongecolor_lite\">Lihtne ja kiire värvimine, multikad, pole ideaalne</string>\n    <string name=\"model_deblr\">Vähendab veidi pildi hägusust, parandades teravust ilma artefakte lisamata.</string>\n    <string name=\"processing_channel\">Pikaajalised operatsioonid</string>\n    <string name=\"processing_image\">Pildi töötlemine</string>\n    <string name=\"processing\">Töötlemine</string>\n    <string name=\"model_artifacts_jpg_0_20\">Eemaldab rasked JPEG-tihendusartefaktid väga madala kvaliteediga piltidelt (0–20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Vähendab tugevaid JPEG-artefakte tugevalt tihendatud piltidel (20–40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Puhastab mõõdukad JPEG-artefaktid, säilitades samal ajal pildi üksikasjad (40–60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Viimistleb heledaid JPEG-artefakte üsna kõrge kvaliteediga piltides (60–80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Vähendab peenelt väiksemaid JPEG-artefakte peaaegu kadudeta piltidel (80–100%).</string>\n    <string name=\"model_redetail_v2\">Täiustab peeneid detaile ja tekstuure, parandades tajutavat teravust ilma raskete artefaktideta.</string>\n    <string name=\"processing_finished\">Töötlemine lõpetatud</string>\n    <string name=\"processing_failed\">Töötlemine ebaõnnestus</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Parandab naha tekstuure ja detaile, säilitades samal ajal loomuliku välimuse, optimeeritud kiiruse jaoks.</string>\n    <string name=\"model_sbdv_dejpeg\">Eemaldab JPEG-tihendusartefaktid ja taastab tihendatud fotode pildikvaliteedi.</string>\n    <string name=\"model_iso_denoise_v1\">Vähendab ISO-müra vähese valgusega fotodel, säilitades üksikasjad.</string>\n    <string name=\"model_dejumbo\">Parandab ülevalgustatud või \\\"jumbo\\\" esiletõstmised ja taastab parema toonitasakaalu.</string>\n    <string name=\"model_ddcolor_tiny\">Kerge ja kiire värvimismudel, mis lisab halltoonides piltidele loomulikke värve.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Värvige</string>\n    <string name=\"type_artifacts\">Artefaktid</string>\n    <string name=\"type_enhance\">Täiustage</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Skaneerib</string>\n    <string name=\"type_upscale\">Kallis</string>\n    <string name=\"model_realesrgan_x4v3\">X4 suurendaja üldiste piltide jaoks; väike mudel, mis kasutab vähem GPU-d ja aega, mõõduka hägususe ja müraga.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 suurendaja üldiste piltide jaoks, säilitades tekstuurid ja loomulikud detailid.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 suurendaja üldiste piltide jaoks täiustatud tekstuuride ja realistlike tulemustega.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Animepiltide jaoks optimeeritud X4 suurendaja; 6 RRDB plokki teravamate joonte ja detailide jaoks.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE kadudega X4 suurendaja annab sujuvamad tulemused ja vähendab üldiste piltide artefakte.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">Animepiltide jaoks optimeeritud X4 Upscaler; Teravamate detailide ja sujuvate joontega variant 4B32F.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 mudel üldiste piltide jaoks; rõhutab teravust ja selgust.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; kiirem ja väiksem, säilitab üksikasjad, kasutades vähem GPU mälu.</string>\n    <string name=\"model_rmbg_1_4\">Kerge mudel tausta kiireks eemaldamiseks. Tasakaalustatud jõudlus ja täpsus. Töötab portreede, objektide ja stseenidega. Soovitatav enamiku kasutusjuhtude jaoks.</string>\n    <string name=\"type_removebg\">Eemalda BG</string>\n    <string name=\"horizontal_border_thickness\">Horisontaalne piiri paksus</string>\n    <string name=\"vertical_border_thickness\">Vertikaalse piiri paksus</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s värvi</item>\n        <item quantity=\"other\">%1$s värvid</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Praegune mudel ei toeta tükeldamist, pilti töödeldakse originaalmõõtmetes, see võib põhjustada suurt mälutarbimist ja probleeme madala kvaliteediga seadmetega</string>\n    <string name=\"chunking_disabled\">Tükeldamine on keelatud, pilti töödeldakse esialgsetes mõõtmetes, see võib põhjustada suurt mälutarbimist ja probleeme madala kvaliteediga seadmetega, kuid võib anda paremaid järeldusi</string>\n    <string name=\"chunking\">Tükeldamine</string>\n    <string name=\"model_u2net\">Suure täpsusega piltide segmenteerimise mudel tausta eemaldamiseks</string>\n    <string name=\"model_u2netp\">U2Neti kerge versioon tausta kiiremaks eemaldamiseks väiksema mälukasutusega.</string>\n    <string name=\"model_ddcolor\">Full DDColor mudel pakub kvaliteetset värvimist üldiste piltide jaoks minimaalsete artefaktidega. Kõigi värvimismudelite parim valik.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Koolitatud ja privaatsed kunstiandmed; annab mitmekesiseid ja kunstipäraseid värvimistulemusi vähemate ebarealistlike värviartefaktidega.</string>\n    <string name=\"model_birefnet\">Kerge BiRefNet mudel, mis põhineb Swin Transformeril tausta täpseks eemaldamiseks.</string>\n    <string name=\"model_inspyrenet\">Kvaliteetne teravate servade ja suurepärase detaili säilivusega taustaeemaldus, eriti keerukate objektide ja keerulise taustaga.</string>\n    <string name=\"model_isnet\">Tausta eemaldamise mudel, mis toodab täpseid siledate servadega maske, mis sobivad üldistele objektidele ja mõõduka detaili säilitamiseks.</string>\n    <string name=\"model_already_downloaded\">Mudel on juba alla laaditud</string>\n    <string name=\"model_successfully_imported\">Mudel edukalt imporditud</string>\n    <string name=\"type\">Tüüp</string>\n    <string name=\"keyword\">Märksõna</string>\n    <string name=\"very_fast\">Väga kiire</string>\n    <string name=\"normal\">Tavaline</string>\n    <string name=\"slow\">Aeglane</string>\n    <string name=\"very_slow\">Väga aeglane</string>\n    <string name=\"compute_percents\">Arvuta protsentuaalsed osakaalud</string>\n    <string name=\"minimum_value_is\">Minimaalne väärtus on %1$s</string>\n    <string name=\"warp_sub\">Pildi moonutamine sõrmedega joonistades</string>\n    <string name=\"warp\">lõime</string>\n    <string name=\"hardness\">Kõvadus</string>\n    <string name=\"warp_mode\">Warp režiim</string>\n    <string name=\"warp_mode_move\">Liiguta</string>\n    <string name=\"warp_mode_grow\">Kasvama</string>\n    <string name=\"warp_mode_shrink\">Kahanema</string>\n    <string name=\"warp_mode_swirl_cw\">Keerake CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Pöörake CCW</string>\n    <string name=\"fade_strength\">tuhmumistugevus</string>\n    <string name=\"top_drop\">Ülemine tilk</string>\n    <string name=\"bottom_drop\">Alumine tilk</string>\n    <string name=\"start_drop\">Käivitage Drop</string>\n    <string name=\"end_drop\">Lõpeta kukkumine</string>\n    <string name=\"downloading\">Allalaadimine</string>\n    <string name=\"smooth_shapes\">Siledad kujundid</string>\n    <string name=\"smooth_shapes_sub\">Kasutage tavaliste ümarate ristkülikute asemel superellipsi, et saada sujuvamaid ja loomulikumaid kujundeid</string>\n    <string name=\"shape_type\">Kuju tüüp</string>\n    <string name=\"cut\">Lõika</string>\n    <string name=\"rounded\">Ümardatud</string>\n    <string name=\"smooth\">Sujuv</string>\n    <string name=\"cut_shapes_sub\">Teravad servad ilma ümardamiseta</string>\n    <string name=\"rounded_shapes_sub\">Klassikalised ümarad nurgad</string>\n    <string name=\"shapes_type\">Kujundite tüüp</string>\n    <string name=\"corners_size\">Nurkade suurus</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elegantsed ümarad kasutajaliidese elemendid</string>\n    <string name=\"filename_format\">Failinime vorming</string>\n    <string name=\"prefix_pattern_description\">Kohandatud tekst, mis asetatakse failinime algusesse, sobib ideaalselt projektinimede, kaubamärkide või isiklike siltide jaoks.</string>\n    <string name=\"original_filename_pattern_description\">Kasutab algset failinime ilma laiendita, mis aitab teil hoida allika identifitseerimist puutumata.</string>\n    <string name=\"width_pattern_description\">Pildi laius pikslites, kasulik eraldusvõime muutuste jälgimiseks või tulemuste skaleerimiseks.</string>\n    <string name=\"height_pattern_description\">Pildi kõrgus pikslites, abiks kuvasuhtega töötamisel või eksportimisel.</string>\n    <string name=\"random_numbers_pattern_description\">Genereerib juhuslikud numbrid, et tagada unikaalsed failinimed; lisage rohkem numbreid, et kaitsta end duplikaatide eest.</string>\n    <string name=\"sequence_number_pattern_description\">Automaatselt suurenev loendur partiide eksportimiseks, ideaalne mitme pildi salvestamiseks ühe seansi jooksul.</string>\n    <string name=\"preset_info_pattern_description\">Lisab rakendatud eelseadistuse nime failinimesse, et saaksite hõlpsasti meeles pidada, kuidas pilti töödeldakse.</string>\n    <string name=\"scale_mode_pattern_description\">Kuvab töötlemise ajal kasutatava pildi skaleerimise režiimi, aidates eristada muudetud suurusega, kärbitud või kohandatud pilte.</string>\n    <string name=\"suffix_pattern_description\">Failinime lõppu paigutatud kohandatud tekst, mis on kasulik versioonide loomiseks, nagu _v2, _edited või _final.</string>\n    <string name=\"extension_pattern_description\">Faililaiend (png, jpg, webp jne), mis vastab automaatselt tegelikule salvestatud vormingule.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Kohandatav ajatempel, mis võimaldab teil täiusliku sortimise jaoks määratleda oma vormingu Java spetsifikatsioonide järgi.</string>\n    <string name=\"fling_type\">Paiskamise tüüp</string>\n    <string name=\"android_native\">Androidi algseade</string>\n    <string name=\"ios_style\">iOS-i stiil</string>\n    <string name=\"smooth_curve\">Sujuv kõver</string>\n    <string name=\"quick_stop\">Kiire peatus</string>\n    <string name=\"bouncy\">Kopsakas</string>\n    <string name=\"floaty\">Ujuv</string>\n    <string name=\"snappy\">Kihvt</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">Kohanduv</string>\n    <string name=\"accessibility_aware\">Juurdepääsetavus teadlik</string>\n    <string name=\"reduced_motion\">Vähendatud liikumine</string>\n    <string name=\"android_native_sub\">Androidi algse kerimisfüüsika võrdluseks</string>\n    <string name=\"smooth_sub\">Tasakaalustatud, sujuv kerimine üldiseks kasutamiseks</string>\n    <string name=\"ios_style_sub\">Suurem hõõrdumine iOS-i sarnane kerimiskäitumine</string>\n    <string name=\"smooth_curve_sub\">Ainulaadne splainikõver erilise kerimistunde jaoks</string>\n    <string name=\"quick_stop_sub\">Täpne kerimine koos kiire peatamisega</string>\n    <string name=\"bouncy_sub\">Mänguline, tundlik hüppeline kerimisrull</string>\n    <string name=\"floaty_sub\">Pikad libisevad rullid sisu sirvimiseks</string>\n    <string name=\"snappy_sub\">Kiire ja tundlik kerimine interaktiivsete kasutajaliideste jaoks</string>\n    <string name=\"ultra_smooth_sub\">Esmaklassiline sujuv kerimine pikendatud hooga</string>\n    <string name=\"adaptive_sub\">Reguleerib füüsikat paiskamiskiiruse alusel</string>\n    <string name=\"accessibility_aware_sub\">Austab süsteemi juurdepääsetavuse sätteid</string>\n    <string name=\"reduced_motion_sub\">Minimaalne liikumine juurdepääsetavuse vajadustele</string>\n    <string name=\"primary_lines\">Põhiliinid</string>\n    <string name=\"primary_lines_sub\">Lisab paksema joone igal viiendal real</string>\n    <string name=\"fill_color\">Täitevärv</string>\n    <string name=\"hidden_tools\">Peidetud tööriistad</string>\n    <string name=\"hidden_for_share\">Jagamiseks peidetud tööriistad</string>\n    <string name=\"color_library\">Värviteek</string>\n    <string name=\"color_library_sub\">Sirvige suurt värvikogu</string>\n    <string name=\"model_fatality_deblur\">Teravustab ja eemaldab piltidelt hägususe, säilitades samal ajal loomulikud detailid, mis on ideaalne fookusest väljas olevate fotode parandamiseks.</string>\n    <string name=\"model_unresize_v3\">Taastab nutikalt pildid, mille suurust on varem muudetud, taastades kadunud detailid ja tekstuurid.</string>\n    <string name=\"model_liveaction_v1_span\">Optimeeritud reaalajas toimuva sisu jaoks, vähendab tihendusartefakte ja täiustab filmi/telesaadete kaadrite peeneid detaile.</string>\n    <string name=\"model_vhs2hd_realplksr\">Teisendab VHS-kvaliteediga video HD-vormingusse, eemaldades lindimüra ja parandades eraldusvõimet, säilitades samas vanaaegse tunde.</string>\n    <string name=\"model_text2hd_v1\">Spetsialiseerunud tekstirohkete piltide ja ekraanipiltide jaoks, teravdab tähemärke ja parandab loetavust.</string>\n    <string name=\"model_frankendata_pretrainer\">Täiustatud ülesskaleerimine, mis on koolitatud erinevatele andmekogumitele, sobib suurepäraselt üldotstarbeliseks fotode täiustamiseks.</string>\n    <string name=\"model_realwebphoto_v2\">Optimeeritud veebis kokkusurutud fotode jaoks, eemaldab JPEG-artefaktid ja taastab loomuliku välimuse.</string>\n    <string name=\"model_realwebphoto_v4\">Täiustatud versioon veebifotode jaoks parema tekstuuri säilitamise ja artefaktide vähendamisega.</string>\n    <string name=\"model_dat_2x\">2x ülesskaleerimine Dual Aggregation Transformer tehnoloogiaga, säilitab teravuse ja loomulikud detailid.</string>\n    <string name=\"model_dat_3x\">3x ülesskaleerimine täiustatud trafoarhitektuuri abil, sobib ideaalselt mõõdukate laiendusvajaduste jaoks.</string>\n    <string name=\"model_dat_4x\">4x kvaliteetne ülesskaleerimine tipptasemel trafovõrguga, säilitab peened detailid suuremates mõõtkavades.</string>\n    <string name=\"model_nafnet_deblurring\">Eemaldab fotodelt hägususe/müra ja värinad. Üldotstarbeline, kuid parim fotodel.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Taastab madala kvaliteediga pildid, kasutades Swin2SR-i trafot, mis on optimeeritud BSRGAN-i halvenemise jaoks. Suurepärane raskete kokkusurutud artefaktide kinnitamiseks ja detailide täiustamiseks 4x skaalal.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x ülesskaleerimine SwinIR-trafoga, mis on koolitatud BSRGANi halvenemise kohta. Kasutab GAN-i teravamate tekstuuride ja loomulikumate detailide saamiseks fotodel ja keerulistes stseenides.</string>\n    <string name=\"path\">Tee</string>\n    <string name=\"merge_pdf\">Ühendage PDF</string>\n    <string name=\"merge_pdf_sub\">Ühendage mitu PDF-faili üheks dokumendiks</string>\n    <string name=\"files_order\">Failide järjestus</string>\n    <string name=\"pages_short\">lk.</string>\n    <string name=\"split_pdf\">Poolita PDF</string>\n    <string name=\"split_pdf_sub\">Ekstraktige PDF-dokumendist konkreetsed lehed</string>\n    <string name=\"rotate_pdf\">Pöörake PDF-i</string>\n    <string name=\"rotate_pdf_sub\">Parandage lehe orientatsioon jäädavalt</string>\n    <string name=\"pages\">Leheküljed</string>\n    <string name=\"rearrange_pdf\">PDF-i ümberkorraldamine</string>\n    <string name=\"rearrange_pdf_sub\">Lehtede järjestuse muutmiseks pukseerige</string>\n    <string name=\"hold_drag_drop\">Hoia ja lohista lehti</string>\n    <string name=\"page_numbers\">Lehekülje numbrid</string>\n    <string name=\"page_numbers_sub\">Lisage oma dokumentidele automaatselt nummerdamine</string>\n    <string name=\"label_format\">Sildi vorming</string>\n    <string name=\"pdf_to_text\">PDF tekstiks (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Ekstraktige oma PDF-dokumentidest lihttekst</string>\n    <string name=\"watermark_pdf_sub\">Ülekate kohandatud tekst kaubamärgi või turvalisuse jaoks</string>\n    <string name=\"signature\">Allkiri</string>\n    <string name=\"signature_sub\">Lisage oma elektrooniline allkiri mis tahes dokumendile</string>\n    <string name=\"will_be_for_signature\">Seda kasutatakse allkirjana</string>\n    <string name=\"unlock_pdf\">Avage PDF</string>\n    <string name=\"unlock_pdf_sub\">Eemaldage kaitstud failidest paroolid</string>\n    <string name=\"protect_pdf\">Kaitske PDF-i</string>\n    <string name=\"protect_pdf_sub\">Kaitske oma dokumente tugeva krüptimisega</string>\n    <string name=\"success\">Edu</string>\n    <string name=\"pdf_unlocked\">PDF on lukustamata, saate seda salvestada või jagada</string>\n    <string name=\"repair_pdf\">Parandage PDF</string>\n    <string name=\"repair_pdf_sub\">Proovige parandada rikutud või loetamatud dokumente</string>\n    <string name=\"grayscale\">Halltoonid</string>\n    <string name=\"grayscale_pdf_sub\">Teisendage kõik dokumendi manustatud pildid halltoonides</string>\n    <string name=\"compress_pdf\">Tihendage PDF</string>\n    <string name=\"compress_pdf_sub\">Lihtsamaks jagamiseks optimeerige oma dokumendi faili suurust</string>\n    <string name=\"repair_info\">ImageToolbox taastab sisemise ristviidetabeli ja taastab failistruktuuri nullist. See võib taastada juurdepääsu paljudele failidele, mida \\\\\"ei saa avada\\\\\"</string>\n    <string name=\"grayscale_info\">See tööriist teisendab kõik dokumendipildid halltoonides. Parim printimiseks ja faili suuruse vähendamiseks</string>\n    <string name=\"metadata\">Metaandmed</string>\n    <string name=\"metadata_pdf_sub\">Parema privaatsuse tagamiseks muutke dokumendi atribuute</string>\n    <string name=\"tags\">Sildid</string>\n    <string name=\"producer\">Tootja</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Märksõnad</string>\n    <string name=\"creator\">Looja</string>\n    <string name=\"privacy_deep_clean\">Privaatsus sügavpuhastus</string>\n    <string name=\"privacy_deep_clean_sub\">Kustutage kõik selle dokumendi saadaolevad metaandmed</string>\n    <string name=\"page\">Lehekülg</string>\n    <string name=\"deep_ocr\">Sügav OCR</string>\n    <string name=\"deep_ocr_sub\">Ekstraktige dokumendist tekst ja salvestage see Tesseracti mootori abil ühte tekstifaili</string>\n    <string name=\"cant_remove_all\">Kõiki lehti ei saa eemaldada</string>\n    <string name=\"remove_pages_pdf\">Eemaldage PDF-lehed</string>\n    <string name=\"remove_pages_pdf_sub\">Eemaldage PDF-dokumendist konkreetsed lehed</string>\n    <string name=\"tap_to_remove\">Puudutage Eemaldamiseks</string>\n    <string name=\"manually\">Käsitsi</string>\n    <string name=\"crop_pdf\">Kärbi PDF-i</string>\n    <string name=\"crop_pdf_sub\">Kärbi dokumendi lehti suvaliste piirideni</string>\n    <string name=\"flatten_pdf\">Lamendada PDF</string>\n    <string name=\"flatten_pdf_sub\">Muutke PDF-i muutmatuks, rasterdades dokumendi lehekülgi</string>\n    <string name=\"camera_failed_to_open\">Kaamerat ei saanud käivitada. Kontrollige õigusi ja veenduge, et seda ei kasutaks mõni teine ​​rakendus.</string>\n    <string name=\"extract_images\">Ekstrakti pildid</string>\n    <string name=\"extract_images_sub\">Eraldage PDF-failidesse manustatud pildid nende algse eraldusvõimega</string>\n    <string name=\"pdf_no_embedded\">See PDF-fail ei sisalda manustatud pilte</string>\n    <string name=\"extract_images_info\">See tööriist skannib iga lehekülge ja taastab täiskvaliteediga lähtepildid – ideaalne originaalide salvestamiseks dokumentidest</string>\n    <string name=\"draw_signature\">Joonista allkiri</string>\n    <string name=\"pen_params\">Pliiatsi parameetrid</string>\n    <string name=\"draw_signature_sub\">Kasutage dokumentidele lisatava pildina enda allkirja</string>\n    <string name=\"zip_pdf\">ZIP PDF</string>\n    <string name=\"zip_pdf_sub\">Tükeldage dokument etteantud intervalliga ja pakkige uued dokumendid ZIP-arhiivi</string>\n    <string name=\"interval\">Intervall</string>\n    <string name=\"print_pdf\">Printige PDF</string>\n    <string name=\"print_pdf_sub\">Valmistage dokument ette kohandatud leheformaadiga printimiseks</string>\n    <string name=\"pages_per_sheet\">Lehekülgi lehel</string>\n    <string name=\"orientation\">Orienteerumine</string>\n    <string name=\"page_size\">Lehekülje suurus</string>\n    <string name=\"margin\">Marginaali</string>\n    <string name=\"bloom\">Õitsema</string>\n    <string name=\"soft_knee\">Pehme põlv</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimeeritud anime ja koomiksite jaoks. Kiire skaleerimine täiustatud loomulike värvide ja vähemate esemetega</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 sarnane stiil</string>\n    <string name=\"calculate_hint\">Soovitud väärtuse arvutamiseks sisestage siia põhilised matemaatilised sümbolid (nt (5+5)*10)</string>\n    <string name=\"math_expression\">Matemaatiline väljend</string>\n    <string name=\"pick_up_to_n_collage_images\">Valige kuni %1$s pilti</string>\n    <string name=\"keep_date_time\">Hoidke kuupäev ja kellaaeg</string>\n    <string name=\"keep_date_time_sub\">Säilitage alati kuupäeva ja kellaajaga seotud exif-sildid, töötab sõltumatult exif-i säilitamise võimalusest</string>\n    <string name=\"background_color_for_alpha_formats\">Taustavärv Alfa-vormingute jaoks</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Lisab võimaluse määrata taustavärvi igale alfatoega pildivormingule, kui see on keelatud, on see saadaval ainult mittealfavormingute jaoks</string>\n    <string name=\"open_markup_project\">Avatud projekt</string>\n    <string name=\"open_markup_project_sub\">Jätkake varem salvestatud Image Toolboxi projekti redigeerimist</string>\n    <string name=\"markup_project_open_failed\">Image Toolboxi projekti ei saa avada</string>\n    <string name=\"markup_project_missing_data\">Pildi tööriistakasti projektil puuduvad projekti andmed</string>\n    <string name=\"markup_project_corrupted\">Pildi tööriistakasti projekt on rikutud</string>\n    <string name=\"unsupported_markup_project_version\">Toetamata pilditööriista projekti versioon: %1$d</string>\n    <string name=\"save_markup_project\">Salvesta projekt</string>\n    <string name=\"save_markup_project_sub\">Salvestage kihid, taust ja redigeerimisajalugu redigeeritavas projektifailis</string>\n    <string name=\"failed_to_open\">Avamine ebaõnnestus</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Kirjutage otsitavasse PDF-i</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Tuvastage pildikomplektist tekst ja salvestage otsitav PDF koos pildi ja valitava tekstikihiga</string>\n    <string name=\"layer_alpha\">Alfa kiht</string>\n    <string name=\"horizontal_flip\">Horisontaalne klapp</string>\n    <string name=\"vertical_flip\">Vertikaalne ümberpööramine</string>\n    <string name=\"lock\">Lukk</string>\n    <string name=\"add_shadow\">Lisa varju</string>\n    <string name=\"shadow_color\">Varju värv</string>\n    <string name=\"text_geometry\">Teksti geomeetria</string>\n    <string name=\"text_geometry_sub\">Teravama stiliseerimise jaoks venitage või kallutage teksti</string>\n    <string name=\"scale_x\">Skaala X</string>\n    <string name=\"skew_x\">Viltus X</string>\n    <string name=\"remove_annotations\">Eemalda märkused</string>\n    <string name=\"remove_annotations_sub\">Eemaldage PDF-lehtedelt valitud märkuste tüübid, nagu lingid, kommentaarid, esiletõstmised, kujundid või vormiväljad</string>\n    <string name=\"annotation_link\">Hüperlingid</string>\n    <string name=\"annotation_file_attachment\">Failide manused</string>\n    <string name=\"annotation_line\">Jooned</string>\n    <string name=\"annotation_popup\">Hüpikaknad</string>\n    <string name=\"annotation_stamp\">Margid</string>\n    <string name=\"annotation_shapes\">Kujundid</string>\n    <string name=\"annotation_text\">Tekst Märkused</string>\n    <string name=\"annotation_text_markup\">Teksti märgistus</string>\n    <string name=\"annotation_widget\">Vormi väljad</string>\n    <string name=\"annotation_markup\">Märgistus</string>\n    <string name=\"annotation_unknown\">Tundmatu</string>\n    <string name=\"annotations\">Märkused</string>\n    <string name=\"ungroup\">Lahutage rühmitamine</string>\n    <string name=\"add_shadow_sub\">Lisage konfigureeritava värvi ja nihkega kihi taha hägune vari</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-eu/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"size\">Tamaina %1$s</string>\n    <string name=\"smth_went_wrong\">Zerbait gaizki atera da: %1$s</string>\n    <string name=\"loading\">Kargatzen…</string>\n    <string name=\"image_too_large_preview\">Irudia handiegia da aurreikusteko, hala ere, gordetzen saiatuko da</string>\n    <string name=\"pick_image\">Aukeratu irudia hasteko</string>\n    <string name=\"width\">Zabalera %1$s</string>\n    <string name=\"height\">Altuera %1$s</string>\n    <string name=\"quality\">Kalitatea</string>\n    <string name=\"extension\">Luzapena</string>\n    <string name=\"resize_type\">Tamaina-aldaketaren mota</string>\n    <string name=\"flexible\">Malgua</string>\n    <string name=\"explicit\">Esplizitua</string>\n    <string name=\"pick_image_alt\">Aukeratu Irudia</string>\n    <string name=\"app_closing\">Aplikazioa ixten</string>\n    <string name=\"stay\">Geratu</string>\n    <string name=\"app_closing_sub\">Ziur aplikazioa itxi nahi duzula?</string>\n    <string name=\"close\">Itxi</string>\n    <string name=\"reset_image\">Berrezarri irudia</string>\n    <string name=\"reset\">Berrezarri</string>\n    <string name=\"copied\">Arbelera kopiatuta</string>\n    <string name=\"exception\">Salbuespena</string>\n    <string name=\"values_reset\">Balioak ongi berrezarri dira</string>\n    <string name=\"reset_image_sub\">Irudiaren aldaketak hasierako balioetara itzuliko dira</string>\n    <string name=\"something_went_wrong\">Zerbait gaizki atera da</string>\n    <string name=\"restart_app\">Berrabiarazi aplikazioa</string>\n    <string name=\"ok\">Ados</string>\n    <string name=\"edit_exif\">Editatu EXIF</string>\n    <string name=\"no_exif\">EXIF daturik ez da aurkitu</string>\n    <string name=\"add_tag\">Gehitu etiketa</string>\n    <string name=\"save\">Gorde</string>\n    <string name=\"clear_exif\">Ezabatu EXIF</string>\n    <string name=\"cancel\">Utzi</string>\n    <string name=\"clear_exif_sub\">Irudiaren EXIF datu guztiak ezabatuko dira, ekintza hau ezin da leheneratu!</string>\n    <string name=\"clear\">Garbitu</string>\n    <string name=\"image_not_saved\">Gordetzen</string>\n    <string name=\"image_not_saved_sub\">Gorde ez diren aldaketa guztiak galduko dira orain irteten bazara</string>\n    <string name=\"check_source_code_sub\">Jaso azken eguneraketak, eztabaidatu arazoak eta gehiago</string>\n    <string name=\"single_edit\">Tamaina-aldaketa bakarra</string>\n    <string name=\"presets\">Aurredoikuntzak</string>\n    <string name=\"check_source_code\">Iturburu-kodea</string>\n    <string name=\"crop\">Moztu</string>\n    <string name=\"single_edit_sub\">Aldatu emandako irudi bakarraren zehaztapenak</string>\n    <string name=\"pick_color\">Aukeratu kolorea</string>\n    <string name=\"pick_color_sub\">Aukeratu kolorea iruditik, kopiatu edo partekatu</string>\n    <string name=\"image\">Irudia</string>\n    <string name=\"color\">Kolore</string>\n    <string name=\"color_copied\">Kolorea kopiatu da</string>\n    <string name=\"crop_sub\">Moztu irudia edozein mugatara</string>\n    <string name=\"version\">Bertsioa</string>\n    <string name=\"change_preview\">Aldatu aurrebista</string>\n    <string name=\"update\">Eguneratu</string>\n    <string name=\"no_palette\">Ezin da paleta sortu emandako irudiarentzat</string>\n    <string name=\"def\">Lehenetsia</string>\n    <string name=\"custom\">Pertsonalizatua</string>\n    <string name=\"unspecified\">Zehaztu gabe</string>\n    <string name=\"max_bytes\">Gehienezko tamaina KBtan</string>\n    <string name=\"by_bytes_resize_sub\">Aldatu irudi bat KB-tan emandako tamainari jarraituz</string>\n    <string name=\"compare\">Konparatu</string>\n    <string name=\"compare_sub\">Konparatu emandako bi irudi</string>\n    <string name=\"pick_two_images\">Aukeratu bi irudi hasteko</string>\n    <string name=\"pick_images\">Aukeratu irudiak</string>\n    <string name=\"settings\">Ezarpenak</string>\n    <string name=\"night_mode\">Gaueko modua</string>\n    <string name=\"dark\">Iluna</string>\n    <string name=\"light\">Argia</string>\n    <string name=\"amoled_mode\">Amoled modua</string>\n    <string name=\"color_red\">Gorria</string>\n    <string name=\"clipboard_paste_invalid_empty\">Ezer itsatsi beharrik</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Ezin da aldatu aplikazioaren kolore-eskema kolore dinamikoak aktibatuta dauden bitartean</string>\n    <string name=\"pick_accent_color\">Aplikazioaren gaia aukeratuko duzun kolorean oinarrituta egongo da</string>\n    <string name=\"about_app\">Aplikazioari buruz</string>\n    <string name=\"no_updates\">Ez da eguneratzerik aurkitu</string>\n    <string name=\"issue_tracker\">Arazoen jarraipena</string>\n    <string name=\"issue_tracker_sub\">Bidali hona akatsen txostenak eta eginbide eskaerak</string>\n    <string name=\"help_translate\">Lagundu itzultzen</string>\n    <string name=\"help_translate_sub\">Zuzendu itzulpen-akatsak edo lokalizatu proiektua beste hizkuntza batera</string>\n    <string name=\"tertiary\">Hirugarren mailakoa</string>\n    <string name=\"secondary\">Bigarren mailakoa</string>\n    <string name=\"surface\">Azalera</string>\n    <string name=\"values\">Balioak</string>\n    <string name=\"add\">Gehitu</string>\n    <string name=\"permission\">Baimena</string>\n    <string name=\"grant\">Baimena eman</string>\n    <string name=\"keep_exif\">Mantendu EXIF</string>\n    <string name=\"images\">Irudiak: %d</string>\n    <string name=\"remove\">Kendu</string>\n    <string name=\"palette_sub\">Sortu kolore-paleta lagina emandako iruditik</string>\n    <string name=\"generate_palette\">Sortu paleta</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"new_version\">Bertsio berria %1$s</string>\n    <string name=\"unsupported_type\">Onartu gabeko mota: %1$s</string>\n    <string name=\"original\">Jatorrizkoa</string>\n    <string name=\"folder\">Irteera karpeta</string>\n    <string name=\"device_storage\">Gailuaren biltegiratzea</string>\n    <string name=\"by_bytes_resize\">Tamaina aldatu pisuaren arabera</string>\n    <string name=\"system\">Sistema</string>\n    <string name=\"dynamic_colors\">Kolore dinamikoak</string>\n    <string name=\"customization\">Pertsonalizazioa</string>\n    <string name=\"allow_image_monet\">Baimendu irudien dirua</string>\n    <string name=\"allow_image_monet_sub\">Gaituta badago, editatzeko irudi bat aukeratzen duzunean, aplikazioaren koloreak hartuko dira irudi honetan</string>\n    <string name=\"language\">Hizkuntza</string>\n    <string name=\"amoled_mode_sub\">Gainazalen kolorea erabat ilunean ezarriko da gaueko moduan</string>\n    <string name=\"color_scheme\">Kolore eskema</string>\n    <string name=\"color_green\">Berdea</string>\n    <string name=\"color_blue\">Urdina</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Itsatsi baliozko aRGB-kode.</string>\n    <string name=\"nothing_found_by_search\">Zure kontsultan ez da ezer aurkitu</string>\n    <string name=\"search_here\">Bilatu hemen</string>\n    <string name=\"dynamic_colors_sub\">Gaituta badago, aplikazioaren koloreak hartuko dira horma-paperen koloreetarako</string>\n    <string name=\"failed_to_save\">Ezin izan dira gorde %d irudiak</string>\n    <string name=\"primary\">Lehen mailakoa</string>\n    <string name=\"border_thickness\">Ertzaren lodiera</string>\n    <string name=\"permission_sub\">Aplikazioak zure biltegiratze sarbidea behar du irudiak gordetzeko, beharrezkoa da, hori gabe ezin du funtzionatu, beraz, eman baimena hurrengo elkarrizketa-koadroan</string>\n    <string name=\"grant_permission_manual\">Aplikazioak funtziona dezan baimen hau behar du, mesedez, baimendu eskuz</string>\n    <string name=\"donation_sub\">Aplikazio hau guztiz doakoa da, baina proiektuaren garapenean lagundu nahi baduzu, hemen klik egin dezakezu</string>\n    <string name=\"fab_alignment\">FAB lerrokatzea</string>\n    <string name=\"check_updates\">Egiaztatu eguneratzeak</string>\n    <string name=\"check_updates_sub\">Gaituta badago, eguneratzeko elkarrizketa-koadroa erakutsiko zaizu aplikazioa abiarazi ondoren</string>\n    <string name=\"zoom\">Irudia zooma</string>\n    <string name=\"prefix\">Aurrizkia</string>\n    <string name=\"filename\">Fitxategi izena</string>\n    <string name=\"share\">Partekatu</string>\n    <string name=\"external_storage\">Kanpoko biltegia</string>\n    <string name=\"monet_colors\">Moneten koloreak</string>\n    <string name=\"exposure\">Esposizio</string>\n    <string name=\"monochrome\">Monokromoa</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">Tartea</string>\n    <string name=\"line_width\">Lerroaren zabalera</string>\n    <string name=\"laplacian\">Laplazianoa</string>\n    <string name=\"vignette\">Viñeta</string>\n    <string name=\"radius\">Erradioa</string>\n    <string name=\"scale\">Eskala</string>\n    <string name=\"order_sub\">Pantaila nagusiko aukeren ordena zehazten du</string>\n    <string name=\"add_filter\">Gehitu iragazkia</string>\n    <string name=\"filter\">Iragazkia</string>\n    <string name=\"white_balance\">Zurien balantzea</string>\n    <string name=\"tint\">Tinta</string>\n    <string name=\"opacity\">Opakotasuna</string>\n    <string name=\"limits_resize\">Tamaina aldatzeko mugak</string>\n    <string name=\"sketch\">Zirriborroa</string>\n    <string name=\"threshold\">Atalasea</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"non_maximum_suppression\">Gehienezko ezabaketa</string>\n    <string name=\"lookup\">Bilatu</string>\n    <string name=\"emoji\">Emojia</string>\n    <string name=\"stack_blur\">Pila lausotzea</string>\n    <string name=\"blur_size\">Lausoaren tamaina</string>\n    <string name=\"blur_center_x\">Lausotu zentroa x</string>\n    <string name=\"luminance_threshold\">Luminantza atalasea</string>\n    <string name=\"emoji_sub\">Hautatu zein emoji bistaratuko den pantaila nagusian</string>\n    <string name=\"add_file_size\">Gehitu fitxategiaren tamaina</string>\n    <string name=\"add_file_size_sub\">Gaituta badago, gordetako irudiaren zabalera eta altuera gehitzen zaizkio irteera-fitxategiaren izenari</string>\n    <string name=\"delete_exif_sub\">Ezabatu EXIF metadatuak edozein iruditatik</string>\n    <string name=\"image_preview\">Irudiaren aurrebista</string>\n    <string name=\"gallery_picker_sub\">Galeriako irudi-hautatzaile sinplea, aplikazio hori baduzu bakarrik funtzionatuko du</string>\n    <string name=\"file_explorer_picker_sub\">Erabili GetContent-en asmoa irudia hautatzeko, nonahi funtzionatzen du, baina gailu batzuetan aukeratutako irudiak jasotzeko arazoak ere izan ditzake, hori ez da nire errua</string>\n    <string name=\"options_arrangement\">Aukerak antolatzea</string>\n    <string name=\"edit\">Editatu</string>\n    <string name=\"order\">Agindu</string>\n    <string name=\"replace_sequence_number\">Ordeztu sekuentzia-zenbakia</string>\n    <string name=\"replace_sequence_number_sub\">Gaituta badago, denbora-zigilu estandarra irudiaren sekuentzia-zenbakiarekin ordezkatzen du sorta prozesatzea erabiltzen baduzu</string>\n    <string name=\"load_image_from_net\">Kargatu irudia saretik</string>\n    <string name=\"load_image_from_net_sub\">Kargatu edozein irudi internetetik, ikusi aurrebista, zoomatu eta, halaber, gorde edo editatu nahi baduzu</string>\n    <string name=\"no_image\">Ez dago irudirik</string>\n    <string name=\"image_link\">Irudiaren esteka</string>\n    <string name=\"fill\">Bete</string>\n    <string name=\"fit\">Egokitu</string>\n    <string name=\"explicit_description\">Irudi bakoitza Zabalera eta Altuera parametroak emandako irudi batera behartzen du; baliteke aspektu-erlazioa aldatzea</string>\n    <string name=\"flexible_description\">Irudiak tamaina aldatzen du Zabalera edo Altuera parametroak emandako alde luzea duten irudietara, tamaina kalkulu guztiak gorde ondoren egingo dira - aspektu-erlazioa mantentzen du</string>\n    <string name=\"brightness\">Distira</string>\n    <string name=\"contrast\">Kontrastatu</string>\n    <string name=\"hue\">Hue</string>\n    <string name=\"saturation\">Saturazioa</string>\n    <string name=\"filter_sub\">Aplikatu edozein iragazki-katea emandako irudiei</string>\n    <string name=\"filters\">Iragazkiak</string>\n    <string name=\"light_aka_illumination\">Argia</string>\n    <string name=\"color_filter\">Kolore-iragazkia</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"temperature\">Tenperatura</string>\n    <string name=\"highlights_shadows\">Nabarmenak eta itzalak</string>\n    <string name=\"highlights\">Nabarmenak</string>\n    <string name=\"shadows\">Itzalak</string>\n    <string name=\"haze\">Lainoa</string>\n    <string name=\"effect\">Eragina</string>\n    <string name=\"distance\">Distantzia</string>\n    <string name=\"slope\">Aldapa</string>\n    <string name=\"sharpen\">Zorroztu</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negatiboa</string>\n    <string name=\"solarize\">Eguzkiratu</string>\n    <string name=\"vibrance\">Bizitasuna</string>\n    <string name=\"black_and_white\">Beltza eta zuria</string>\n    <string name=\"sobel_edge\">Sobel ertza</string>\n    <string name=\"blur\">Lausotzea</string>\n    <string name=\"halftone\">Tonu erdia</string>\n    <string name=\"cga_colorspace\">GCA kolore-espazioa</string>\n    <string name=\"gaussian_blur\">Gauss lausotzea</string>\n    <string name=\"box_blur\">Kutxa lausotzea</string>\n    <string name=\"bilaterial_blur\">Aldebiko lausotzea</string>\n    <string name=\"emboss\">Erliebea</string>\n    <string name=\"start\">Hasi</string>\n    <string name=\"end\">Amaiera</string>\n    <string name=\"kuwahara\">Kuwahara leuntzea</string>\n    <string name=\"distortion\">Distortsioa</string>\n    <string name=\"angle\">Angelua</string>\n    <string name=\"swirl\">Zurrunbiloa</string>\n    <string name=\"bulge\">Bultza</string>\n    <string name=\"dilation\">Dilatazioa</string>\n    <string name=\"sphere_refraction\">Esferaren errefrakzioa</string>\n    <string name=\"refractive_index\">Errefrakzio-indizea</string>\n    <string name=\"glass_sphere_refraction\">Beirazko esferaren errefrakzioa</string>\n    <string name=\"color_matrix\">Kolore-matrizea</string>\n    <string name=\"limits_resize_sub\">Aldatu tamaina emandako irudiak emandako zabalera eta altuera mugak aspektu-erlazioa gordetzeko</string>\n    <string name=\"quantizationLevels\">Kuantizazio-mailak</string>\n    <string name=\"smooth_toon\">Toon leuna</string>\n    <string name=\"posterize\">Posterizatu</string>\n    <string name=\"weak_pixel_inclusion\">Pixelen inklusio ahula</string>\n    <string name=\"convolution3x3\">Bilaketa 3x3</string>\n    <string name=\"rgb_filter\">RGB iragazkia</string>\n    <string name=\"false_color\">Kolore faltsua</string>\n    <string name=\"first_color\">Lehenengo kolorea</string>\n    <string name=\"second_color\">Bigarren kolorea</string>\n    <string name=\"reorder\">Berrantolatu</string>\n    <string name=\"fast_blur\">Lausotze azkarra</string>\n    <string name=\"blur_center_y\">Lausotu zentroa y</string>\n    <string name=\"zoom_blur\">Zooma lausotzea</string>\n    <string name=\"color_balance\">Koloreen oreka</string>\n    <string name=\"delete_exif\">Ezabatu EXIF</string>\n    <string name=\"image_preview_sub\">Aurreikusi edozein motatako irudiak: GIF, SVG eta abar</string>\n    <string name=\"image_source\">Irudiaren iturria</string>\n    <string name=\"photo_picker\">Argazki-hautatzailea</string>\n    <string name=\"gallery_picker\">Galeria</string>\n    <string name=\"file_explorer_picker\">Fitxategien esploratzailea</string>\n    <string name=\"photo_picker_sub\">Pantailaren behealdean agertzen den Android argazki-hautatzaile modernoa, baliteke Android 12+etan bakarrik funtzionatzea eta arazoak ditu EXIF metadatuak jasotzeko.</string>\n    <string name=\"content_scale\">Edukien eskala</string>\n    <string name=\"emojis_count\">Emoji kopurua</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"add_original_filename\">Gehitu jatorrizko fitxategi-izena</string>\n    <string name=\"add_original_filename_sub\">Gaituta badago, jatorrizko fitxategi-izena gehitzen du irteerako irudiaren izenean</string>\n    <string name=\"filename_not_work_with_photopicker\">Jatorrizko fitxategi-izena gehitzeak ez du funtzionatuko argazki-hautatzailearen irudi-iturria hautatuta badago</string>\n    <string name=\"activate_files\">Fitxategiak aplikazioa desgaitu duzu, aktibatu eginbide hau erabiltzeko</string>\n    <string name=\"draw\">Marraztu</string>\n    <string name=\"paint_color\">Margotu kolorea</string>\n    <string name=\"paint_alpha\">Margotu alfa</string>\n    <string name=\"draw_on_image\">Marraztu irudian</string>\n    <string name=\"draw_on_image_sub\">Aukeratu irudi bat eta marraztu zerbait gainean</string>\n    <string name=\"draw_on_background\">Marraztu atzeko planoan</string>\n    <string name=\"key\">Gakoa</string>\n    <string name=\"implementation_sub\">AES-256, GCM modua, betegarririk gabe, 12 byte ausazko IV. Gakoak SHA-3 hash gisa erabiltzen dira (256 bit).</string>\n    <string name=\"file_proceed\">Fitxategiak aurrera egin du</string>\n    <string name=\"invalid_password_or_not_encrypted\">Pasahitz baliogabea edo aukeratutako fitxategia ez dago enkriptatuta</string>\n    <string name=\"image_size_warning\">Emandako zabalera eta altuera duen irudia gordetzen saiatzeak OOM errore bat sor dezake, egin hau zure ardurapean, eta ez esan abisatu ez dudala!</string>\n    <string name=\"cache\">Cachea</string>\n    <string name=\"cache_size\">Cachearen tamaina</string>\n    <string name=\"found_s\">Aurkitu %1$s</string>\n    <string name=\"auto_cache_clearing\">Cache garbiketa automatikoa</string>\n    <string name=\"auto_cache_clearing_sub\">Gaituta badago, aplikazioaren cachea garbituko da aplikazioa abiaraztean</string>\n    <string name=\"tools\">Tresnak</string>\n    <string name=\"group_options_by_type\">Talde aukerak motaren arabera</string>\n    <string name=\"group_options_by_type_sub\">Taldeko aukerak bere motako pantaila nagusiko zerrenda pertsonalizatuaren ordez</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Ezin da antolamendua aldatu aukerak taldekatzea gaituta dagoen bitartean</string>\n    <string name=\"create\">Sortu</string>\n    <string name=\"draw_sub\">Marraztu irudian zirriborro batean bezala, edo marraztu hondoan bertan</string>\n    <string name=\"draw_on_background_sub\">Aukeratu hondoko kolorea eta marraztu haren gainean</string>\n    <string name=\"background_color\">Atzeko planoaren kolorea</string>\n    <string name=\"cipher\">Zifratzea</string>\n    <string name=\"cipher_sub\">Zifratu eta deszifratu edozein fitxategi (ez soilik irudia) AES kripto algoritmoan oinarrituta</string>\n    <string name=\"pick_file\">Aukeratu fitxategia</string>\n    <string name=\"encrypt\">Enkriptatzea</string>\n    <string name=\"decrypt\">Deszifratu</string>\n    <string name=\"pick_file_to_start\">Hautatu fitxategia hasteko</string>\n    <string name=\"decryption\">Deszifratzea</string>\n    <string name=\"encryption\">Enkriptatzea</string>\n    <string name=\"store_file_desc\">Gorde fitxategi hau zure gailuan edo erabili partekatzeko ekintza nahi duzun lekuan jartzeko</string>\n    <string name=\"features\">Ezaugarriak</string>\n    <string name=\"implementation\">Ezarpena</string>\n    <string name=\"compatibility\">Bateragarritasuna</string>\n    <string name=\"file_size\">Fitxategiaren tamaina</string>\n    <string name=\"file_size_sub\">Fitxategien gehienezko tamaina Android sistema eragileak eta eskuragarri dagoen memoriak mugatzen du, hau da, jakina, zure gailuaren araberakoa. \\nKontuan izan: memoria ez da biltegiratzea.</string>\n    <string name=\"compatibility_sub\">Kontuan izan fitxategiak enkriptatzeko beste software edo zerbitzu batzuekin bateragarritasuna ez dagoela bermatuta. Gako-tratamendu edo zifratze-konfigurazio apur bat desberdina bateraezintasunaren arrazoia izan daiteke.</string>\n    <string name=\"features_sub\">Fitxategien pasahitzetan oinarritutako enkriptatzea. Jarraitutako fitxategiak hautatutako direktorioan gorde edo partekatu daitezke. Deszifratutako fitxategiak ere zuzenean ireki daitezke.</string>\n    <string name=\"fallback_option\">Atzerako aukera</string>\n    <string name=\"secondary_customization\">Bigarren mailako pertsonalizazioa</string>\n    <string name=\"warning_bytes\">%1$s moduan gordetzea ezegonkorra izan daiteke, galerarik gabeko formatua delako</string>\n    <string name=\"screenshot\">Pantaila-argazkia</string>\n    <string name=\"skip\">Saltatu</string>\n    <string name=\"copy\">Kopiatu</string>\n    <string name=\"edit_screenshot\">Editatu pantaila-argazkia</string>\n    <string name=\"trim_image\">Moztu irudia</string>\n    <string name=\"resize_and_convert\">Tamaina aldatu eta Bihurtu</string>\n    <string name=\"corruption_size\">Ustelkeriaren Tamaina</string>\n    <string name=\"strength\">Indarra</string>\n    <string name=\"brush_softness\">Eskuila leuntasuna</string>\n    <string name=\"draw_mode\">Marrazketa modua</string>\n    <string name=\"restore\">Berreskuratu</string>\n    <string name=\"segmentation_mode_osd_only\">Orientazioa &amp; Script-en hautematea soilik</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientazio automatikoa &amp; Script-en hautematea</string>\n    <string name=\"segmentation_mode_auto_only\">Autoa soilik</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Bloke bakarreko testu bertikala</string>\n    <string name=\"segmentation_mode_single_block\">Bloke bakarra</string>\n    <string name=\"segmentation_mode_single_line\">Lerro bakarra</string>\n    <string name=\"segmentation_mode_single_char\">Char bakarra</string>\n    <string name=\"segmentation_mode_sparse_text\">Testu urria</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Testu eskasa Orientazioa &amp; Gidoien detekzioa</string>\n    <string name=\"segmentation_mode_raw_line\">Lerro gordina</string>\n    <string name=\"glitch\">Akatsa</string>\n    <string name=\"amount\">Zenbatekoa</string>\n    <string name=\"seed\">Hazia</string>\n    <string name=\"anaglyph\">Anaglifoa</string>\n    <string name=\"noise\">Zarata</string>\n    <string name=\"pixel_sort\">Pixel sorta</string>\n    <string name=\"shuffle\">Nahastu</string>\n    <string name=\"peak\">Gailurra</string>\n    <string name=\"color_anomaly\">Kolore Anomalia</string>\n    <string name=\"no_such_directory\">Ez da aurkitu \\\"%1$s\\\" direktoriorik, lehenetsitako batera aldatu dugu, mesedez gorde fitxategia berriro</string>\n    <string name=\"clipboard\">Arbela</string>\n    <string name=\"auto_pin\">Pin automatikoa</string>\n    <string name=\"vibration\">Dardara</string>\n    <string name=\"vibration_strength\">Bibrazio-indarra</string>\n    <string name=\"overwrite_files\">Gainidatzi fitxategiak</string>\n    <string name=\"overwrite_files_sub\">Jatorrizko fitxategia beste batekin ordezkatuko da hautatutako karpetan gorde beharrean, aukera honek irudiaren iturburua \\\"Explorer\\\" edo GetContent izan behar du, hau aldatzean, automatikoki ezarriko da.</string>\n    <string name=\"empty\">Hutsik</string>\n    <string name=\"suffix\">Atzizkia</string>\n    <string name=\"free\">Doan</string>\n    <string name=\"email\">Posta elektronikoa</string>\n    <string name=\"presets_sub_bytes\">Hemen aurrez ezarritakoak irteerako fitxategiaren % zehazten du, hau da, 5 MBko irudian 50 aurrez ezarritakoa hautatzen baduzu, 2,5 MBko irudia lortuko duzu gorde ondoren.</string>\n    <string name=\"randomize_filename\">Ausazko fitxategi-izena</string>\n    <string name=\"randomize_filename_sub\">Gaituta badago irteerako fitxategi-izena guztiz ausazkoa izango da</string>\n    <string name=\"saved_to\">%1$s karpetan gorde da %2$s izenarekin</string>\n    <string name=\"saved_to_without_filename\">%1$s karpetan gorde da</string>\n    <string name=\"tg_chat\">Telegram txata</string>\n    <string name=\"tg_chat_sub\">Eztabaidatu aplikazioa eta jaso beste erabiltzaileen iritzia. Hemen ere lor ditzakezu beta eguneraketak eta estatistikak.</string>\n    <string name=\"crop_mask\">Moztu maskara</string>\n    <string name=\"aspect_ratio\">Aspektu-erlazioa</string>\n    <string name=\"image_crop_mask_sub\">Erabili maskara mota hau emandako iruditik maskara sortzeko, ohartu alfa kanala izan BEHAR DUela</string>\n    <string name=\"backup_and_restore\">Babeskopia egin eta leheneratu</string>\n    <string name=\"backup\">Babeskopia</string>\n    <string name=\"settings_restored\">Ezarpenak behar bezala leheneratu dira</string>\n    <string name=\"restore_sub\">Berrezarri aplikazioaren ezarpenak aurrez sortutako fitxategitik</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Fitxategi hondatua edo babeskopia ez</string>\n    <string name=\"contact_me\">Jarri nirekin harremanetan</string>\n    <string name=\"reset_settings_sub\">Honek zure ezarpenak balio lehenetsietara itzuliko ditu. Kontuan izan hau ezin dela desegin goian aipatutako babeskopia fitxategirik gabe.</string>\n    <string name=\"delete\">Ezabatu</string>\n    <string name=\"delete_color_scheme_warn\">Hautatutako kolore-eskema ezabatzera zoaz. Eragiketa hau ezin da desegin</string>\n    <string name=\"delete_color_scheme_title\">Ezabatu eskema</string>\n    <string name=\"font\">Letra-tipoa</string>\n    <string name=\"text\">Testua</string>\n    <string name=\"font_scale\">Letra-tipoen eskala</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Ññ Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"defaultt\">Lehenetsia</string>\n    <string name=\"emotions\">Emozioak</string>\n    <string name=\"using_large_fonts_warn\">Letra-tipo-eskala handiak erabiltzeak UI akatsak eta arazoak sor ditzake, eta horiek ez dira konponduko. Erabili kontu handiz.</string>\n    <string name=\"food_and_drink\">Janaria eta edaria</string>\n    <string name=\"nature_and_animals\">Natura eta Animaliak</string>\n    <string name=\"activities\">Jarduerak</string>\n    <string name=\"background_remover\">Atzeko planoa kentzeko</string>\n    <string name=\"background_remover_sub\">Kendu atzeko planoa iruditik marraztuz edo erabili Auto aukera</string>\n    <string name=\"objects\">Objektuak</string>\n    <string name=\"symbols\">Sinboloak</string>\n    <string name=\"enable_emoji\">Gaitu emojiak</string>\n    <string name=\"travels_and_places\">Bidaiak eta Lekuak</string>\n    <string name=\"trim_image_sub\">Irudiaren inguruko espazio gardenak moztuko dira</string>\n    <string name=\"auto_erase_background\">Ezabatu automatikoki atzeko planoa</string>\n    <string name=\"restore_image\">Berreskuratu irudia</string>\n    <string name=\"erase_mode\">Ezabatu modua</string>\n    <string name=\"erase_background\">Ezabatu atzeko planoa</string>\n    <string name=\"restore_background\">Leheneratu atzeko planoa</string>\n    <string name=\"blur_radius\">Lausotze erradioa</string>\n    <string name=\"pipette\">Pipeta</string>\n    <string name=\"create_issue\">Sortu alea</string>\n    <string name=\"something_went_wrong_emphasis\">Aupa… Arazoren bat izan da. Beheko aukerak erabiliz idatz diezadazu eta irtenbidea bilatzen saiatuko naiz</string>\n    <string name=\"resize_and_convert_sub\">Emandako irudien tamaina aldatu edo beste formatu batzuetara bihurtu. EXIF metadatuak hemen ere edita daitezke irudi bakarra hautatuz gero.</string>\n    <string name=\"crashlytics_sub\">Horri esker, aplikazioak hutsegiteen txostenak eskuz bil ditzake</string>\n    <string name=\"analytics\">Analitika</string>\n    <string name=\"analytics_sub\">Baimendu aplikazioen erabilera-estatistika anonimoak biltzea</string>\n    <string name=\"image_exif_warning\">Une honetan, %1$s formatuak EXIF metadatuak irakurtzeko aukera ematen du Android-en. Irteerako irudiak ez du metadaturik izango gordetzean.</string>\n    <string name=\"effort_sub\">%1$s balioak konpresio azkarra esan nahi du, eta horren ondorioz fitxategiaren tamaina handi samarra da. %2$s-k konpresio motelagoa dela esan nahi du, eta horren ondorioz fitxategi txikiagoa izango da.</string>\n    <string name=\"wait\">Itxaron</string>\n    <string name=\"saving_almost_complete\">Gorde ia amaituta. Orain bertan behera uzteko, berriro gorde beharko da.</string>\n    <string name=\"updates\">Eguneraketak</string>\n    <string name=\"allow_betas\">Baimendu beta-ak</string>\n    <string name=\"allow_betas_sub\">Eguneratze-egiaztapenak aplikazioaren beta bertsioak barne hartuko ditu gaituta badago</string>\n    <string name=\"draw_arrows_sub\">Gaituta badago marrazteko bidea gezi adierazgarri gisa irudikatuko da</string>\n    <string name=\"crop_description\">Irudiak erdian moztuko dira sartutako tamainara. Mihisea atzeko planoko kolorearekin zabalduko da irudia sartutako neurriak baino txikiagoa bada.</string>\n    <string name=\"image_orientation\">Irudien Orientazioa</string>\n    <string name=\"horizontal\">Horizontala</string>\n    <string name=\"vertical\">Bertikala</string>\n    <string name=\"scale_small_images_to_large\">Eskalatu irudi txikiak handietara</string>\n    <string name=\"scale_small_images_to_large_sub\">Irudi txikiak sekuentziako handienera eskalatuko dira gaituta badago</string>\n    <string name=\"images_order\">Irudien ordena</string>\n    <string name=\"regular\">Erregularra</string>\n    <string name=\"blur_edges\">Lausotu ertzak</string>\n    <string name=\"blur_edges_sub\">Gaituta badago, jatorrizko irudiaren azpian ertz lausoak marrazten ditu bere inguruko espazioak betetzeko, kolore bakarreko ordez</string>\n    <string name=\"pixelation\">Pixelazioa</string>\n    <string name=\"enhanced_pixelation\">Pixelazio hobetua</string>\n    <string name=\"stroke_pixelation\">Trazuaren pixelazioa</string>\n    <string name=\"enhanced_diamond_pixelation\">Diamante pixelazio hobetua</string>\n    <string name=\"diamond_pixelation\">Diamante pixelazioa</string>\n    <string name=\"circle_pixelation\">Zirkuluaren pixelazioa</string>\n    <string name=\"enhanced_circle_pixelation\">Zirkuluen pixelazio hobetua</string>\n    <string name=\"replace_color\">Ordeztu Kolorea</string>\n    <string name=\"color_to_remove\">Kendu beharreko kolorea</string>\n    <string name=\"remove_color\">Kendu kolorea</string>\n    <string name=\"recode\">Birkodetzea</string>\n    <string name=\"palette_style\">Paleta estiloa</string>\n    <string name=\"tonal_spot\">Tonal Spot</string>\n    <string name=\"neutral\">Neutroa</string>\n    <string name=\"vibrant\">Bizia</string>\n    <string name=\"expressive\">Adierazkorra</string>\n    <string name=\"rainbow\">Ortzadarra</string>\n    <string name=\"fruit_salad\">Fruitu entsalada</string>\n    <string name=\"fidelity\">Fideltasuna</string>\n    <string name=\"content\">Edukia</string>\n    <string name=\"tonal_spot_sub\">Paleta estilo lehenetsia, lau koloreak pertsonalizatzeko aukera ematen du, beste batzuek gako kolorea soilik ezartzeko aukera ematen dute</string>\n    <string name=\"neutral_sub\">Monokromoa baino apur bat kromatikoagoa den estiloa</string>\n    <string name=\"vibrant_sub\">Gai ozena, koloretsutasuna maximoa da Lehen mailako paletarentzat, besteentzat areagotua</string>\n    <string name=\"playful_scheme\">Gai dibertigarria - iturriko kolorearen ñabardura ez da gaian agertzen</string>\n    <string name=\"monochrome_sub\">Gai monokromoa, koloreak beltza / zuria / grisa dira</string>\n    <string name=\"content_sub\">Iturburu-kolorea Scheme.primaryContainer-en jartzen duen eskema</string>\n    <string name=\"fidelity_sub\">Edukien eskemaren oso antzekoa den eskema</string>\n    <string name=\"foss_update_checker_warning\">Eguneratze-zuzentzaile hau GitHub-era konektatuko da eguneratze berririk eskuragarri dagoen egiaztatzeko</string>\n    <string name=\"both\">Biak</string>\n    <string name=\"search_option\">Bilatu</string>\n    <string name=\"search_option_sub\">Pantaila nagusian eskuragarri dauden aukera guztiak bilatzeko gaitasuna ematen du</string>\n    <string name=\"preview_pdf\">Aurreikusi PDFa</string>\n    <string name=\"pdf_to_images\">PDF irudietara</string>\n    <string name=\"images_to_pdf\">Irudiak PDFra</string>\n    <string name=\"pdf_to_images_sub\">Bihurtu PDF irudietara irteerako formatuan</string>\n    <string name=\"images_to_pdf_sub\">Pakeatu emandako irudiak irteerako PDF fitxategian</string>\n    <string name=\"mask_filter\">Maskara-iragazkia</string>\n    <string name=\"mask_filter_sub\">Aplikatu iragazki-kateak estalitako eremu jakin batzuetan, maskara-eremu bakoitzak bere iragazki-multzoa zehaztu dezake</string>\n    <string name=\"masks\">Maskarak</string>\n    <string name=\"add_mask\">Gehitu maskara</string>\n    <string name=\"mask_indexed\">Maskara %d</string>\n    <string name=\"mask_color\">Maskararen kolorea</string>\n    <string name=\"mask_preview\">Maskararen aurrebista</string>\n    <string name=\"mask_preview_sub\">Marraztutako iragazki-maskara errendatuko da gutxi gorabeherako emaitza erakusteko</string>\n    <string name=\"delete_mask_warn\">Hautatutako iragazki-maskara ezabatzera zoaz. Eragiketa hau ezin da desegin</string>\n    <string name=\"delete_mask\">Ezabatu maskara</string>\n    <string name=\"center_position\">Zentroa</string>\n    <string name=\"end_position\">Amaiera</string>\n    <string name=\"simple_variants\">Aldaera sinpleak</string>\n    <string name=\"highlighter\">Nabarmendutzailea</string>\n    <string name=\"neon\">Neoia</string>\n    <string name=\"pen\">Boligrafoa</string>\n    <string name=\"privacy_blur\">Pribatutasuna lausotzea</string>\n    <string name=\"neon_sub\">Gehitu efektu distiratsu batzuk zure marrazkiei</string>\n    <string name=\"pen_sub\">Lehenetsia, sinpleena - kolorea besterik ez</string>\n    <string name=\"pixelation_sub\">Pribatutasun-lausotzearen antzekoa, baina pixelatu egiten da lausotu beharrean</string>\n    <string name=\"buttons_shadow\">Botoiak</string>\n    <string name=\"value_in_range\">%1$s - %2$s barrutiko balioa</string>\n    <string name=\"auto_rotate_limits\">Biratu automatikoa</string>\n    <string name=\"auto_rotate_limits_sub\">Irudiaren orientaziorako muga-koadroa hartzeko aukera ematen du</string>\n    <string name=\"double_arrow_sub\">Bide jakin batetik gezi bikoitza marrazten du</string>\n    <string name=\"outlined_rect\">Azaldutako Rect</string>\n    <string name=\"oval\">Obalatua</string>\n    <string name=\"rect\">Zuzen</string>\n    <string name=\"rect_sub\">Zuzena marrazten du hasierako puntutik amaierako puntura</string>\n    <string name=\"auto_pin_sub\">Automatikoki gehitzen du gordetako irudia arbelean gaituta badago</string>\n    <string name=\"overwrite_file_requirements\">Fitxategiak gainidazteko \\\"Explorer\\\" irudi-iturburua erabili behar duzu, saiatu irudiak berrikusten, irudi-iturburua behar den batera aldatu dugu.</string>\n    <string name=\"nearest\">Hurbilena</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Oinarrizkoa</string>\n    <string name=\"catmull_sub\">Kontrol-puntu multzo bat leunki interpolatzeko eta berriro lagintzeko metodoa, ordenagailu grafikoetan erabili ohi den kurba leunak sortzeko</string>\n    <string name=\"hann_sub\">Leiho-funtzioa sarritan erabiltzen da seinaleen prozesamenduan, ihes espektrala minimizatzeko eta maiztasun-analisiaren zehaztasuna hobetzeko seinale baten ertzak txikituz.</string>\n    <string name=\"available_languages\">Eskuragarri dauden hizkuntzak</string>\n    <string name=\"segmentation_mode\">Segmentazio modua</string>\n    <string name=\"saved_to_original\">Gainidatzitako fitxategia %1$s izena duen jatorrizko helmugan</string>\n    <string name=\"magnifier\">Lupa</string>\n    <string name=\"magnifier_sub\">Irisgarritasun hobea lortzeko, hatzaren goiko aldean lupa gaitzen du marrazketa moduetan</string>\n    <string name=\"force_exif_widget_initial_value\">Indartu hasierako balioa</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Exif widget-a hasiera batean egiaztatzea behartzen du</string>\n    <string name=\"toggle_tap\">Aktibatu/Sakatu</string>\n    <string name=\"rate_app_sub\">Aplikazio hau guztiz doakoa da, handiagoa izan nahi baduzu, izarra ezazu proiektua Github-en 😄</string>\n    <string name=\"segmentation_mode_auto\">Autoa</string>\n    <string name=\"segmentation_mode_single_column\">Zutabe bakarra</string>\n    <string name=\"segmentation_mode_single_word\">Hitz bakarra</string>\n    <string name=\"segmentation_mode_circle_word\">Hitz biribila</string>\n    <string name=\"delete_language_sub\">Hizkuntza \\\"%1$s\\\" OCR prestakuntza-datuak ezabatu nahi dituzu aintzatespen-mota guztietarako, edo hautatutako (%2$s) soilik?</string>\n    <string name=\"current\">Oraingoa</string>\n    <string name=\"add_color\">Gehitu kolorea</string>\n    <string name=\"properties\">Propietateak</string>\n    <string name=\"watermarking\">Ur-marka</string>\n    <string name=\"watermarking_sub\">Estali argazkiak testu/irudi pertsonalizagarriekin</string>\n    <string name=\"repeat_watermark\">Errepikatu ur-marka</string>\n    <string name=\"repeat_watermark_sub\">Ur-marka errepikatzen du irudiaren gainean, bakarren ordez, emandako posizioan</string>\n    <string name=\"use_size_of_first_frame\">Erabili Lehen fotogramaren tamaina</string>\n    <string name=\"use_size_of_first_frame_sub\">Ordeztu zehaztutako tamaina lehen markoaren neurriekin</string>\n    <string name=\"repeat_count\">Errepikatu zenbaketa</string>\n    <string name=\"frame_delay\">Fotograma atzerapena</string>\n    <string name=\"millis\">milis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"bayer_four_dithering\">Lau Bider Lau Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Bi ilaratako Sierra dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">False Floyd Steinberg dithering</string>\n    <string name=\"median_blur\">Lausotze mediana</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Zatika definitutako polinomio bikubiko funtzioak erabiltzen ditu kurba edo gainazal bat, formaren irudikapen malgua eta jarraitua leunki interpolatzeko eta hurbiltzeko.</string>\n    <string name=\"enhanced_glitch\">Glitch hobetua</string>\n    <string name=\"channel_shift_x\">Channel Shift X</string>\n    <string name=\"corruption_shift_x\">Ustelkeria txanda X</string>\n    <string name=\"corruption_shift_y\">Ustelkeria txanda Y</string>\n    <string name=\"channel_shift_y\">Channel Shift Y</string>\n    <string name=\"tent_blur\">Karpa Blur</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">Aldea</string>\n    <string name=\"top\">Goiena</string>\n    <string name=\"bottom\">Behean</string>\n    <string name=\"fractal_glass\">Beira fraktala</string>\n    <string name=\"amplitude_x\">X anplitudea</string>\n    <string name=\"amplitude_y\">Y anplitudea</string>\n    <string name=\"perlin_distortion\">Perlin Distortsioa</string>\n    <string name=\"color_matrix_4x4\">Kolore Matrizea 4x4</string>\n    <string name=\"color_matrix_3x3\">Kolore Matrizea 3x3</string>\n    <string name=\"simple_effects\">Efektu sinpleak</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomalia</string>\n    <string name=\"deutaromaly\">Deutaromalia</string>\n    <string name=\"protonomaly\">Protonomalia</string>\n    <string name=\"vintage\">Vintagea</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Gaueko Ikusmena</string>\n    <string name=\"warm\">Epela</string>\n    <string name=\"cool\">Cool</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"grain\">Alea</string>\n    <string name=\"unsharp\">Zorrotzgabea</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Laranja Lainoa</string>\n    <string name=\"pink_dream\">Amets Arrosa</string>\n    <string name=\"golden_hour\">Urrezko Ordua</string>\n    <string name=\"hot_summer\">Uda beroa</string>\n    <string name=\"purple_mist\">Laino morea</string>\n    <string name=\"sunrise\">Egunsentia</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Limonada Argia</string>\n    <string name=\"spectral_fire\">Su espektrala</string>\n    <string name=\"night_magic\">Gau Magia</string>\n    <string name=\"green_sun\">Eguzki Berdea</string>\n    <string name=\"rainbow_world\">Ortzadarraren Mundua</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Moztu</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Trantsizioa</string>\n    <string name=\"images_overwritten\">Jatorrizko helmugan gainidatzitako irudiak</string>\n    <string name=\"cannot_change_image_format\">Ezin da irudi formatua aldatu fitxategiak gainidatzi aukera gaituta dagoen bitartean</string>\n    <string name=\"emoji_as_color_scheme\">Emoji kolore eskema gisa</string>\n    <string name=\"emoji_as_color_scheme_sub\">Emoji kolore nagusia erabiltzen du aplikazioaren kolore-eskema gisa, eskuz definitutako baten ordez</string>\n    <string name=\"backup_sub\">Egin zure aplikazioaren ezarpenen babeskopia fitxategi batean</string>\n    <string name=\"effort\">Esfortzua</string>\n    <string name=\"draw_arrows\">Marraztu Geziak</string>\n    <string name=\"pick_at_least_two_images\">Aukeratu gutxienez 2 irudi</string>\n    <string name=\"tolerance\">Tolerantzia</string>\n    <string name=\"color_to_replace\">Ordezkatzeko kolorea</string>\n    <string name=\"target_color\">Helburu-kolorea</string>\n    <string name=\"erode\">Higatu</string>\n    <string name=\"anisotropic_diffusion\">Difusio anisotropikoa</string>\n    <string name=\"diffusion\">Zabalkundea</string>\n    <string name=\"conduction\">Eroapena</string>\n    <string name=\"horizontal_wind_stagger\">Haizearen mailakatu horizontala</string>\n    <string name=\"fast_bilaterial_blur\">Aldebiko lausotze azkarra</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">Tonu logaritmikoak mapatzea</string>\n    <string name=\"crystallize\">Kristalizatu</string>\n    <string name=\"stroke_color\">Trazuaren kolorea</string>\n    <string name=\"amplitude\">Anplitudea</string>\n    <string name=\"marble\">Marmola</string>\n    <string name=\"turbulence\">Turbulentzia</string>\n    <string name=\"oil\">Olioa</string>\n    <string name=\"water_effect\">Ur Efektua</string>\n    <string name=\"just_size\">Tamaina</string>\n    <string name=\"frequency_x\">X maiztasuna</string>\n    <string name=\"frequency_y\">Y maiztasuna</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES tonu filmikoaren mapak</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"all\">Denak</string>\n    <string name=\"full_filter\">Iragazki osoa</string>\n    <string name=\"start_position\">Hasi</string>\n    <string name=\"full_filter_sub\">Aplikatu edozein iragazki-kateak emandako irudiei edo irudi bakarrei</string>\n    <string name=\"pdf_tools\">PDF tresnak</string>\n    <string name=\"pdf_tools_sub\">Funtzionatu PDF fitxategiekin: Aurreikusi, Bihurtu irudi sorta batean edo sortu argazkien bat</string>\n    <string name=\"preview_pdf_sub\">PDF aurrebista sinplea</string>\n    <string name=\"gradient_maker\">Gradient Maker</string>\n    <string name=\"gradient_maker_sub\">Sortu irteera-tamainaren gradientea kolore eta itxura mota pertsonalizatuekin</string>\n    <string name=\"speed\">Abiadura</string>\n    <string name=\"dehaze\">Lainoa kendu</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"rate_app\">Tarifa aplikazioa</string>\n    <string name=\"rate\">Tarifa</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Akromatomalia</string>\n    <string name=\"achromatopsia\">Akromatopsia</string>\n    <string name=\"gradient_type_linear\">Lineala</string>\n    <string name=\"gradient_type_radial\">Erradiala</string>\n    <string name=\"gradient_type_sweep\">Ekorketa</string>\n    <string name=\"gradient_type\">Gradiente mota</string>\n    <string name=\"center_x\">X zentroa</string>\n    <string name=\"center_y\">Y zentroa</string>\n    <string name=\"tile_mode\">Fitxa modua</string>\n    <string name=\"tile_mode_repeated\">Errepikatua</string>\n    <string name=\"tile_mode_mirror\">Ispilua</string>\n    <string name=\"tile_mode_clamp\">Pintza</string>\n    <string name=\"tile_mode_decal\">Decala</string>\n    <string name=\"color_stops\">Kolore Geldialdiak</string>\n    <string name=\"draw_path_mode\">Marraztu bidea modua</string>\n    <string name=\"double_line_arrow\">Lerro bikoitzeko gezia</string>\n    <string name=\"free_drawing\">Marrazki Librea</string>\n    <string name=\"double_arrow\">Gezi bikoitza</string>\n    <string name=\"line_arrow\">Line Arrow</string>\n    <string name=\"arrow\">Gezia</string>\n    <string name=\"line\">Lerroa</string>\n    <string name=\"free_drawing_sub\">Bidea marrazten du sarrerako balio gisa</string>\n    <string name=\"line_sub\">Hasierako puntutik amaierarako bidea marrazten du lerro gisa</string>\n    <string name=\"line_arrow_sub\">Hasierako puntutik amaierako puntura marrazten duen gezia zuzena marrazten du</string>\n    <string name=\"arrow_sub\">Bide jakin batetik gezi zorrotzak marrazten ditu</string>\n    <string name=\"double_line_arrow_sub\">Hasierako puntutik amaierarako gezi bikoitza marrazten du lerro gisa</string>\n    <string name=\"outlined_oval\">Delineatutako Obalatua</string>\n    <string name=\"oval_sub\">Hasiera-puntutik amaiera-puntura obalatua marrazten du</string>\n    <string name=\"outlined_oval_sub\">Obalatua marrazten du hasierako puntutik amaieraraino</string>\n    <string name=\"outlined_rect_sub\">Zuzen marrazten du hasierako puntutik amaierako puntura</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizier</string>\n    <string name=\"gray_scale\">Grisen Eskala</string>\n    <string name=\"bayer_two_dithering\">Bayer bi teo Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Hiruz Hiru Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"left_to_right_dithering\">Ezker-eskuin dithering</string>\n    <string name=\"random_dithering\">Ausazko dithering</string>\n    <string name=\"simple_threshold_dithering\">Atalasearen dithering sinplea</string>\n    <string name=\"scale_mode\">Eskala modua</string>\n    <string name=\"bilinear\">Bilineala</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Ermita</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"default_value\">Balio lehenetsia</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma espaziala</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bikubikoa</string>\n    <string name=\"bilinear_sub\">Interpolazio lineala (edo bilineala, bi dimentsiotan) normalean ona da irudi baten tamaina aldatzeko, baina xehetasunak nahiko ez diren leuntzea eragiten du eta, hala ere, apur bat apur bat izan daiteke.</string>\n    <string name=\"bicubic_sub\">Eskalatze-metodo hobeak Lanczos birlaginketa eta Mitchell-Netravali iragazkiak dira</string>\n    <string name=\"nearest_sub\">Tamaina handitzeko modu errazenetako bat, pixel bakoitza kolore bereko pixel batzuekin ordezkatuz</string>\n    <string name=\"basic_sub\">Ia aplikazio guztietan erabiltzen den Android eskalatze modurik sinpleena</string>\n    <string name=\"hermite_sub\">Kurba-segmentu baten amaierako puntuetan balioak eta deribatuak erabiltzen dituen interpolazio matematikoko teknika kurba leun eta jarraitua sortzeko</string>\n    <string name=\"lanczos_sub\">Pixel balioei sinc funtzio haztatua aplikatuz kalitate handiko interpolazioa mantentzen duen birlaginketa metodoa</string>\n    <string name=\"mitchell_sub\">Parametro doigarriekin konboluzio-iragazkia erabiltzen duen birlaginketa metodoa, eskalatutako irudian zorroztasunaren eta antialiasing-aren arteko oreka lortzeko.</string>\n    <string name=\"spline_sub\">Zatika definitutako polinomio-funtzioak erabiltzen ditu kurba edo gainazal bat, forma-errepresentazio malgua eta jarraitua leunki interpolatzeko eta hurbiltzeko.</string>\n    <string name=\"only_clip\">Clip bakarrik</string>\n    <string name=\"only_clip_sub\">Ez da biltegian gordeko, eta irudia arbelean bakarrik jartzen saiatuko da</string>\n    <string name=\"icon_shape_sub\">Hautatutako forma duen edukiontzia gehitzen du txartelen ikono nagusien azpian</string>\n    <string name=\"icon_shape\">Ikonoaren forma</string>\n    <string name=\"image_stitching\">Irudien jostura</string>\n    <string name=\"image_stitching_sub\">Konbinatu emandako irudiak handi bat lortzeko</string>\n    <string name=\"brightness_enforcement\">Distira betearaztea</string>\n    <string name=\"screen\">Pantaila</string>\n    <string name=\"gradient_maker_type_image\">Gradientearen gainjartzea</string>\n    <string name=\"gradient_maker_type_image_sub\">Konposatu emandako irudiaren goialdeko edozein gradiente</string>\n    <string name=\"transformations\">Eraldaketak</string>\n    <string name=\"keep_exif_sub\">Jatorrizko irudiaren metadatuak gordeko dira</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Kamera erabiltzen du argazkiak ateratzeko. Kontuan izan irudi-iturburu honetatik irudi bakarra atera daitekeela</string>\n    <string name=\"colorful_swirl\">Zurrunbilo koloretsua</string>\n    <string name=\"soft_spring_light\">Udaberriko Argia</string>\n    <string name=\"autumn_tones\">Udazkeneko Tonuak</string>\n    <string name=\"lavender_dream\">Izpiliku Ametsa</string>\n    <string name=\"fantasy_landscape\">Fantasiazko Paisaia</string>\n    <string name=\"color_explosion\">Kolore leherketa</string>\n    <string name=\"electric_gradient\">Gradiente elektrikoa</string>\n    <string name=\"caramel_darkness\">Caramel Iluntasuna</string>\n    <string name=\"futuristic_gradient\">Gradiente futurista</string>\n    <string name=\"deep_purple\">More iluna</string>\n    <string name=\"space_portal\">Espazio Ataria</string>\n    <string name=\"red_swirl\">Zurrunbilo Gorria</string>\n    <string name=\"digital_code\">Kode Digitala</string>\n    <string name=\"offset_x\">Desplazamendua X</string>\n    <string name=\"offset_y\">Desplazamendua Y</string>\n    <string name=\"watermark_type\">Ur-marka mota</string>\n    <string name=\"watermarking_image_sub\">Irudi hau ur-markak egiteko eredu gisa erabiliko da</string>\n    <string name=\"text_color\">Testuaren kolorea</string>\n    <string name=\"overlay_mode\">Gainjartze modua</string>\n    <string name=\"pixel_size\">Pixel Tamaina</string>\n    <string name=\"lock_draw_orientation\">Blokeatu marrazkiaren orientazioa</string>\n    <string name=\"max_colors_count\">Kolore kopurua gehienez</string>\n    <string name=\"lock_draw_orientation_sub\">Marrazketa moduan gaituta badago, pantaila ez da biratuko</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">GIF tresnak</string>\n    <string name=\"gif_tools_sub\">Bihurtu irudiak GIF irudira edo atera fotogramak emandako GIF iruditik</string>\n    <string name=\"gif_type_to_image\">GIF irudietara</string>\n    <string name=\"gif_type_to_image_sub\">Bihurtu GIF fitxategia argazki sorta batean</string>\n    <string name=\"gif_type_to_gif_sub\">Bihurtu irudi sorta GIF fitxategira</string>\n    <string name=\"gif_type_to_gif\">Irudiak GIF-era</string>\n    <string name=\"select_gif_image_to_start\">Hautatu GIF irudia hasteko</string>\n    <string name=\"use_lasso\">Erabili Lazoa</string>\n    <string name=\"use_lasso_sub\">Lassoa erabiltzen du marrazketa moduan bezala ezabatzeko</string>\n    <string name=\"original_image_preview_alpha\">Jatorrizko irudiaren aurrebista Alpha</string>\n    <string name=\"random_emojis_sub\">Aplikazio-barrako emojiak ausaz aldatuko dira etengabe hautatutakoa erabili beharrean</string>\n    <string name=\"random_emojis\">Ausazko emojiak</string>\n    <string name=\"random_emojis_error\">Ezin da erabili ausazko emojiak hautatzea emojiak desgaituta dauden bitartean</string>\n    <string name=\"emoji_selection_error\">Ezin da emojirik hautatu ausazko bat gaituta dagoen bitartean</string>\n    <string name=\"check_for_updates\">Egiaztatu eguneratzeak</string>\n    <string name=\"presets_sub\" formatted=\"false\">Aurrez ezarritako 125a aukeratu baduzu, irudia jatorrizko irudiaren % 125eko tamainan gordeko da, % 100eko kalitatearekin. Aurrez ezarritako 50 aukeratzen baduzu, irudia% 50eko tamainarekin eta% 50eko kalitatearekin gordeko da.</string>\n    <string name=\"old_tv\">Telebista Zaharra</string>\n    <string name=\"shuffle_blur\">Nahastu Lausotzea</string>\n    <string name=\"recognize_text\">OCR (testua ezagutu)</string>\n    <string name=\"recognize_text_sub\">Emandako irudiaren testua ezagutu, 120 hizkuntza baino gehiago onartzen dira</string>\n    <string name=\"picture_has_no_text\">Irudiak ez du testurik edo aplikazioak ez du aurkitu</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Aitorpen Mota</string>\n    <string name=\"fast\">Azkar</string>\n    <string name=\"standard\">Estandarra</string>\n    <string name=\"best\">Onena</string>\n    <string name=\"no_data\">Ez dago daturik</string>\n    <string name=\"download_description\">Tesseract OCR prestakuntza-datu osagarriak (%1$s) behar bezala funtzionatzeko zure gailura deskargatu behar dira. \\n%2$s datuak deskargatu nahi dituzu?</string>\n    <string name=\"download\">Deskargatu</string>\n    <string name=\"no_connection\">Ez dago konexiorik, egiaztatu eta saiatu berriro tren-ereduak deskargatzeko</string>\n    <string name=\"downloaded_languages\">Deskargatutako hizkuntzak</string>\n    <string name=\"restore_background_sub\">Pintzelak atzeko planoa berreskuratuko du ezabatu beharrean</string>\n    <string name=\"horizontal_grid\">Sare horizontala</string>\n    <string name=\"vertical_grid\">Sare bertikala</string>\n    <string name=\"stitch_mode\">Puntu modua</string>\n    <string name=\"rows_count\">Errenkadak zenbatzen</string>\n    <string name=\"columns_count\">Zutabeen zenbaketa</string>\n    <string name=\"use_pixel_switch\">Erabili Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Pixel-itxurako etengailua erabiliko da zuk oinarritutako Google-ren materialaren ordez</string>\n    <string name=\"slide\">Diapositiba</string>\n    <string name=\"side_by_side\">Alboz Albo</string>\n    <string name=\"transparency\">Gardentasuna</string>\n    <string name=\"allow_multiple_languages\">Onartu hainbat hizkuntza</string>\n    <string name=\"favorite\">Gogokoena</string>\n    <string name=\"no_favorite_filters\">Ez dago gogoko iragazkirik gehitu oraindik</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"inverse_fill_type\">Alderantzizko betetze mota</string>\n    <string name=\"inverse_fill_type_sub\">Gaituta badago, maskaratuta ez dauden eremu guztiak iragaziko dira portaera lehenetsiaren ordez</string>\n    <string name=\"confetti\">Konfetiak</string>\n    <string name=\"confetti_sub\">Konfetiak gordetzeko, partekatzeko eta beste lehen ekintzetan erakutsiko dira</string>\n    <string name=\"secure_mode\">Modu segurua</string>\n    <string name=\"secure_mode_sub\">Irteeran edukia ezkutatzen du; gainera, pantaila ezin da harrapatu edo grabatu</string>\n    <string name=\"donation\">Dohaintza</string>\n    <string name=\"output_image_scale\">Irteerako irudien eskala</string>\n    <string name=\"fading_edges\">Desagertzen diren ertzak</string>\n    <string name=\"disabled\">Desgaituta</string>\n    <string name=\"highlighter_sub\">Marraztu erdi-gardenak zorroztutako argitzaile-bideak</string>\n    <string name=\"privacy_blur_sub\">Marraztutako bidearen azpian irudia lausotzen du ezkutatu nahi duzun guztia ziurtatzeko</string>\n    <string name=\"containers_shadow\">Ontziak</string>\n    <string name=\"containers_shadow_sub\">Edukiontzien atzean itzalen marrazketa gaitzen du</string>\n    <string name=\"sliders_shadow\">Graduatzaileak</string>\n    <string name=\"switches_shadow\">Etengailuak</string>\n    <string name=\"fabs_shadow\">FABak</string>\n    <string name=\"sliders_shadow_sub\">Irristagailuen atzean itzalen marrazketa gaitzen du</string>\n    <string name=\"switches_shadow_sub\">Etengailuen atzean itzalen marrazketa gaitzen du</string>\n    <string name=\"fabs_shadow_sub\">Itzalen marrazketa gaitzen du ekintza-botoien atzean</string>\n    <string name=\"buttons_shadow_sub\">Itzalen marrazketa gaitzen du lehenetsitako botoien atzean</string>\n    <string name=\"app_bars_shadow\">Aplikazioen barrak</string>\n    <string name=\"app_bars_shadow_sub\">Aplikazioen barren atzean itzalen marrazketa gaitzen du</string>\n    <string name=\"attention\">Arreta</string>\n    <string name=\"invert_colors\">Alderantzikatu Koloreak</string>\n    <string name=\"invert_colors_sub\">Gaiaren koloreak negatiboekin ordezkatzen ditu gaituta badago</string>\n    <string name=\"exit\">Irten</string>\n    <string name=\"preview_closing\">Aurrebista orain uzten baduzu, irudiak berriro gehitu beharko dituzu</string>\n    <string name=\"lasso\">Lazoa</string>\n    <string name=\"lasso_sub\">Bide itxia marrazten du emandako bidearen arabera</string>\n    <string name=\"image_format\">Irudi formatua</string>\n    <string name=\"dark_colors\">Kolore Ilunak</string>\n    <string name=\"dark_colors_sub\">Gaueko moduaren kolore eskema erabiltzen du argiaren aldaeraren ordez</string>\n    <string name=\"copy_as_compose_code\">Kopiatu Jetpack Compose kodea</string>\n    <string name=\"material_you_sub\">Material You paleta sortzen du iruditik</string>\n    <string name=\"ring_blur\">Eraztunaren Lausotzea</string>\n    <string name=\"cross_blur\">Gurutze Lausoa</string>\n    <string name=\"circle_blur\">Zirkuluaren Lausotzea</string>\n    <string name=\"star_blur\">Izar Lausoa</string>\n    <string name=\"linear_tilt_shift\">Aldaketa Lineala</string>\n    <string name=\"tags_to_remove\">Etiketak Kentzeko</string>\n    <string name=\"apng_tools\">APNG tresnak</string>\n    <string name=\"apng_type_to_image\">Irudiei APNG</string>\n    <string name=\"motion_blur\">Mugimendu lausotzea</string>\n    <string name=\"apng_tools_sub\">Bihurtu irudiak APNG irudira edo atera fotogramak emandako APNG iruditik</string>\n    <string name=\"apng_type_to_image_sub\">Bihurtu APNG fitxategia argazki sorta batean</string>\n    <string name=\"apng_type_to_apng_sub\">Bihurtu irudi sorta APNG fitxategira</string>\n    <string name=\"apng_type_to_apng\">Irudiak APNGra</string>\n    <string name=\"select_apng_image_to_start\">Hautatu APNG irudia hasteko</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Sortu Zip fitxategia emandako fitxategi edo irudietatik</string>\n    <string name=\"drag_handle_width\">Arrastatu heldulekuaren zabalera</string>\n    <string name=\"confetti_type\">Konfeti mota</string>\n    <string name=\"festive\">Jaia</string>\n    <string name=\"explode\">Lehertu</string>\n    <string name=\"rain\">Euria</string>\n    <string name=\"corners\">Txokoak</string>\n    <string name=\"jxl_tools\">JXL tresnak</string>\n    <string name=\"jxl_tools_sub\">Egin JXL ~ JPEG transkodeketa kalitate-galerarik gabe edo bihurtu GIF/APNG JXL animaziora</string>\n    <string name=\"jxl_type_to_jpeg\">JXLtik JPEGra</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Egin galerarik gabeko transkodeketa JXLtik JPEGra</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Egin galerarik gabeko transkodeketa JPEGtik JXLra</string>\n    <string name=\"jpeg_type_to_jxl\">JPEGtik JXLra</string>\n    <string name=\"select_jxl_image_to_start\">Hautatu JXL irudia hasteko</string>\n    <string name=\"fast_gaussian_blur_2d\">Gauss lausotze azkarra 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Gaussian Blur azkarra 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Gaussian Blur azkarra 4D</string>\n    <string name=\"auto_paste\">Autoa Aste Santua</string>\n    <string name=\"auto_paste_sub\">Arbeleko datuak automatikoki itsatsi ditzake aplikazioak, beraz, pantaila nagusian agertuko da eta prozesatu ahal izango dituzu</string>\n    <string name=\"harmonization_color\">Harmonizazio Kolorea</string>\n    <string name=\"harmonization_level\">Harmonizazio Maila</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Pixel balioei Bessel (jinc) funtzioa aplikatuz kalitate handiko interpolazioa mantentzen duen birlaginketa metodoa</string>\n    <string name=\"gif_type_to_jxl\">GIFetik JXLra</string>\n    <string name=\"gif_type_to_jxl_sub\">Bihurtu GIF irudiak JXL irudi animatuetara</string>\n    <string name=\"apng_type_to_jxl\">APNGtik JXLra</string>\n    <string name=\"apng_type_to_jxl_sub\">Bihurtu APNG irudiak JXL irudi animatuetara</string>\n    <string name=\"jxl_type_to_images\">JXL Irudietara</string>\n    <string name=\"jxl_type_to_images_sub\">Bihurtu JXL animazioa argazki sorta batean</string>\n    <string name=\"jxl_type_to_jxl\">Irudiak JXLra</string>\n    <string name=\"jxl_type_to_jxl_sub\">Bihurtu argazki sorta JXL animaziora</string>\n    <string name=\"behavior\">Portaera</string>\n    <string name=\"skip_file_picking\">Saltatu fitxategien hautaketa</string>\n    <string name=\"skip_file_picking_sub\">Fitxategi-hautatzailea berehala erakutsiko da aukeratutako pantailan</string>\n    <string name=\"generate_previews\">Sortu Aurrebistak</string>\n    <string name=\"generate_previews_sub\">Aurrebista sortzea gaitzen du; honek gailu batzuetan hutsegiterik ez izateko lagungarria izan daiteke; honek edizio-funtzio batzuk ere desgaitzen ditu edizio bakarreko aukeraren barruan.</string>\n    <string name=\"lossy_compression\">Konpresio galdua</string>\n    <string name=\"lossy_compression_sub\">Konpresio galera erabiltzen du fitxategiaren tamaina murrizteko, galerarik gabekoa izan beharrean</string>\n    <string name=\"compression_type\">Konpresio Mota</string>\n    <string name=\"speed_sub\">Ondorioz irudiak deskodetzeko abiadura kontrolatzen du. Honek ondoriozko irudia azkarrago irekitzen lagundu beharko luke, %1$s balioak deskodetze motelena esan nahi du, eta %2$s - azkarrena, ezarpen honek irteerako irudiaren tamaina handitu dezake.</string>\n    <string name=\"sorting\">Sailkatzea</string>\n    <string name=\"sort_by_date\">Data</string>\n    <string name=\"sort_by_date_reversed\">Data (alderantziztuta)</string>\n    <string name=\"sort_by_name\">Izena</string>\n    <string name=\"sort_by_name_reversed\">Izena (alderantziztuta)</string>\n    <string name=\"channels_configuration\">Kanalen konfigurazioa</string>\n    <string name=\"header_today\">Gaur</string>\n    <string name=\"header_yesterday\">Atzo</string>\n    <string name=\"embedded_picker\">Kapsulatutako hautatzailea</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox-en irudi-hautatzailea</string>\n    <string name=\"no_permissions\">Ez dago baimenik</string>\n    <string name=\"request\">Eskaera</string>\n    <string name=\"pick_multiple_media\">Aukeratu hainbat euskarri</string>\n    <string name=\"pick_single_media\">Aukeratu euskarri bakarra</string>\n    <string name=\"pick\">Aukeratu</string>\n    <string name=\"try_again\">Saiatu berriro</string>\n    <string name=\"show_settings_in_landscape\">Erakutsi ezarpenak Paisaian</string>\n    <string name=\"show_settings_in_landscape_sub\">Hau desgaituta badago, paisaia moduan ezarpenak beti bezala aplikazioaren goiko barrako botoian irekiko dira, betirako ikusgai dagoen aukeraren ordez.</string>\n    <string name=\"fullscreen_settings\">Pantaila osoko ezarpenak</string>\n    <string name=\"fullscreen_settings_sub\">Gaitu eta ezarpenen orria pantaila osoko moduan irekiko da beti, tiradera-orri irristagarriaren ordez</string>\n    <string name=\"switch_type\">Aldatu mota</string>\n    <string name=\"compose\">Konposatu</string>\n    <string name=\"compose_switch_sub\">Jetpack Konposatzen duzun materiala</string>\n    <string name=\"material_you_switch_sub\">Aldatzen duzun materiala</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Aingura tamaina aldatu</string>\n    <string name=\"pixel_switch\">Pixela</string>\n    <string name=\"fluent_switch\">Arina</string>\n    <string name=\"fluent_switch_sub\"> \\\"Fluent \\\" diseinu sisteman oinarritutako etengailua</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\"> \\\"Cupertino \\\" diseinu sisteman oinarritutako etengailua</string>\n    <string name=\"images_to_svg\">Irudiak SVGra</string>\n    <string name=\"images_to_svg_sub\">Jarraitu emandako irudiak SVG irudietara</string>\n    <string name=\"use_sampled_palette\">Erabili Sampled Paleta</string>\n    <string name=\"use_sampled_palette_sub\">Kuantizazio-paleta lagintuko da aukera hau gaituta badago</string>\n    <string name=\"path_omit\">Bidea Utzi</string>\n    <string name=\"svg_warning\">Ez da gomendagarria irudi handiak trazatzeko tresna hau txikiagotu gabe erabiltzea, huts egin dezake eta prozesatzeko denbora handitu dezake.</string>\n    <string name=\"downscale_image\">Irudia txikiagotu</string>\n    <string name=\"downscale_image_sub\">Irudia dimentsio txikiagoetara murriztuko da prozesatu aurretik, honek tresna azkarrago eta seguruago lan egiten laguntzen du</string>\n    <string name=\"min_color_ratio\">Gutxieneko kolore-erlazioa</string>\n    <string name=\"lines_threshold\">Lerroen Atalasea</string>\n    <string name=\"quadratic_threshold\">Atalase koadratikoa</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordenatuak biribiltzeko tolerantzia</string>\n    <string name=\"path_scale\">Bide Eskala</string>\n    <string name=\"reset_properties\">Berrezarri propietateak</string>\n    <string name=\"reset_properties_sub\">Propietate guztiak balio lehenetsiekin ezarriko dira, konturatu ekintza hau ezin dela desegin</string>\n    <string name=\"detailed\">Xehetasuna</string>\n    <string name=\"default_line_width\">Lerro-zabalera lehenetsia</string>\n    <string name=\"engine_mode\">Motor modua</string>\n    <string name=\"legacy\">Ondarea</string>\n    <string name=\"lstm_network\">LSTM sarea</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp; LSTM</string>\n    <string name=\"convert\">Bihurtu</string>\n    <string name=\"convert_sub\">Bihurtu irudi sortak emandako formatura</string>\n    <string name=\"add_new_folder\">Gehitu Karpeta Berria</string>\n    <string name=\"tag_bits_per_sample\">Lagin bakoitzeko bits</string>\n    <string name=\"tag_compression\">Konpresioa</string>\n    <string name=\"tag_photometric_interpretation\">Interpretazio fotometrikoa</string>\n    <string name=\"tag_samples_per_pixel\">Pixel bakoitzeko laginak</string>\n    <string name=\"tag_planar_configuration\">Konfigurazio planoa</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Azpi-laginketa</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Posizionamendua</string>\n    <string name=\"tag_x_resolution\">X Ebazpena</string>\n    <string name=\"tag_y_resolution\">Y Ebazpena</string>\n    <string name=\"tag_resolution_unit\">Ebazpen Unitatea</string>\n    <string name=\"tag_strip_offsets\">Strip Offsets</string>\n    <string name=\"tag_rows_per_strip\">Tira bakoitzeko errenkadak</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte-kopuruak</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG truke formatua</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG Truke formatuaren luzera</string>\n    <string name=\"tag_transfer_function\">Transferentzia Funtzioa</string>\n    <string name=\"tag_white_point\">Puntu Zuria</string>\n    <string name=\"tag_primary_chromaticities\">Lehen mailako kromatikoak</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Koefizienteak</string>\n    <string name=\"tag_reference_black_white\">Erreferentzia Zuri Beltza</string>\n    <string name=\"tag_datetime\">Data Ordua</string>\n    <string name=\"tag_image_description\">Irudiaren deskribapena</string>\n    <string name=\"tag_make\">Egin</string>\n    <string name=\"tag_model\">Eredua</string>\n    <string name=\"tag_software\">Softwarea</string>\n    <string name=\"tag_artist\">Artista</string>\n    <string name=\"tag_copyright\">Copyright</string>\n    <string name=\"tag_exif_version\">Exif bertsioa</string>\n    <string name=\"tag_flashpix_version\">Flashpix bertsioa</string>\n    <string name=\"tag_color_space\">Kolore-espazioa</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimentsioa</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y Dimentsioa</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Pixel bakoitzeko bit konprimituak</string>\n    <string name=\"tag_maker_note\">Maker Oharra</string>\n    <string name=\"tag_user_comment\">Erabiltzaileen iruzkina</string>\n    <string name=\"tag_related_sound_file\">Erlazionatutako Soinu Fitxategia</string>\n    <string name=\"tag_datetime_original\">Data Ordua Jatorrizkoa</string>\n    <string name=\"tag_datetime_digitized\">Data Ordua Digitalizatuta</string>\n    <string name=\"tag_offset_time\">Desplazamendu-denbora</string>\n    <string name=\"tag_offset_time_original\">Desplazamendu-denbora jatorrizkoa</string>\n    <string name=\"tag_offset_time_digitized\">Desplazamendu-denbora digitalizatua</string>\n    <string name=\"tag_subsec_time\">Azpi Seg Denbora</string>\n    <string name=\"tag_subsec_time_original\">Sub Seg Denbora Jatorrizkoa</string>\n    <string name=\"tag_subsec_time_digitized\">Sub Seg Denbora digitalizatua</string>\n    <string name=\"tag_exposure_time\">Esposizio-denbora</string>\n    <string name=\"tag_f_number\">F Zenbakia</string>\n    <string name=\"tag_exposure_program\">Esposizio Programa</string>\n    <string name=\"tag_spectral_sensitivity\">Sentsibilitate Espektrala</string>\n    <string name=\"tag_photographic_sensitivity\">Argazki-sentsibilitatea</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Sentikortasun mota</string>\n    <string name=\"tag_standard_output_sensitivity\">Irteera estandarraren sentikortasuna</string>\n    <string name=\"tag_recommended_exposure_index\">Gomendatutako Esposizio Indizea</string>\n    <string name=\"tag_iso_speed\">ISO abiadura</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Abiadura Latitudea yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Abiadura Latitudea zzz</string>\n    <string name=\"tag_shutter_speed_value\">Obturadorearen abiaduraren balioa</string>\n    <string name=\"tag_aperture_value\">Irekiduraren balioa</string>\n    <string name=\"tag_brightness_value\">Distira-balioa</string>\n    <string name=\"tag_exposure_bias_value\">Esposizio-alborapenaren balioa</string>\n    <string name=\"tag_max_aperture_value\">Gehienezko irekiera-balioa</string>\n    <string name=\"tag_subject_distance\">Gaiaren distantzia</string>\n    <string name=\"tag_metering_mode\">Neurketa modua</string>\n    <string name=\"tag_flash\">Flasha</string>\n    <string name=\"tag_subject_area\">Gai Arloa</string>\n    <string name=\"tag_focal_length\">Fokua</string>\n    <string name=\"tag_flash_energy\">Flash Energia</string>\n    <string name=\"tag_spatial_frequency_response\">Maiztasun Erantzun Espaziala</string>\n    <string name=\"tag_focal_plane_x_resolution\">Foku Plano X Ebazpena</string>\n    <string name=\"tag_focal_plane_y_resolution\">Foku Plano Y Ebazpena</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Foku Plano Ebazpen Unitatea</string>\n    <string name=\"tag_subject_location\">Gaiaren kokapena</string>\n    <string name=\"tag_exposure_index\">Esposizio-indizea</string>\n    <string name=\"tag_sensing_method\">Sentsazio metodoa</string>\n    <string name=\"tag_file_source\">Fitxategiaren iturria</string>\n    <string name=\"tag_cfa_pattern\">CFA eredua</string>\n    <string name=\"tag_custom_rendered\">Pertsonalizatutako errendazioa</string>\n    <string name=\"tag_exposure_mode\">Esposizio modua</string>\n    <string name=\"tag_white_balance\">Zurien Balantzea</string>\n    <string name=\"tag_digital_zoom_ratio\">Zoom digitalaren ratioa</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Foku-luzera 35 mm-ko pelikulan</string>\n    <string name=\"tag_scene_capture_type\">Eszena Harrapaketa Mota</string>\n    <string name=\"tag_gain_control\">Irabazi Kontrola</string>\n    <string name=\"tag_contrast\">Kontrastea</string>\n    <string name=\"tag_saturation\">Saturazioa</string>\n    <string name=\"tag_sharpness\">Zorroztasuna</string>\n    <string name=\"tag_device_setting_description\">Gailuaren ezarpenaren deskribapena</string>\n    <string name=\"tag_subject_distance_range\">Gaiaren Distantzia Barrutia</string>\n    <string name=\"tag_image_unique_id\">Irudia ID bakarra</string>\n    <string name=\"tag_camera_owner_name\">Kameraren jabearen izena</string>\n    <string name=\"tag_body_serial_number\">Gorputzaren serie zenbakia</string>\n    <string name=\"tag_lens_specification\">Lentearen zehaztapena</string>\n    <string name=\"tag_lens_make\">Lens Make</string>\n    <string name=\"tag_lens_model\">Lente eredua</string>\n    <string name=\"tag_lens_serial_number\">Lentearen serie zenbakia</string>\n    <string name=\"tag_gps_version_id\">GPS bertsioaren IDa</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Erref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitudea</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Luzera Erref</string>\n    <string name=\"tag_gps_longitude\">GPSaren luzera</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Altuera Erref</string>\n    <string name=\"tag_gps_altitude\">GPS Altuera</string>\n    <string name=\"tag_gps_timestamp\">GPS denbora-zigilua</string>\n    <string name=\"tag_gps_satellites\">GPS sateliteak</string>\n    <string name=\"tag_gps_status\">GPS egoera</string>\n    <string name=\"tag_gps_measure_mode\">GPS neurketa modua</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS Abiadura Erref</string>\n    <string name=\"tag_gps_speed\">GPS Abiadura</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Erref</string>\n    <string name=\"tag_gps_track\">GPS Track</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS irudiaren norabidea Erref</string>\n    <string name=\"tag_gps_img_direction\">GPS irudiaren norabidea</string>\n    <string name=\"tag_gps_map_datum\">GPS maparen datuak</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Erref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Luzera Erref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Luzera</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Erref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest distantzia Erref</string>\n    <string name=\"tag_gps_dest_distance\">GPS Dest Distantzia</string>\n    <string name=\"tag_gps_processing_method\">GPS prozesatzeko metodoa</string>\n    <string name=\"tag_gps_area_information\">GPS eremuaren informazioa</string>\n    <string name=\"tag_gps_datestamp\">GPS data zigilua</string>\n    <string name=\"tag_gps_differential\">GPS diferentziala</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H kokapen-errorea</string>\n    <string name=\"tag_interoperability_index\">Elkarreragingarritasun Indizea</string>\n    <string name=\"tag_dng_version\">DNG bertsioa</string>\n    <string name=\"tag_default_crop_size\">Mozketaren tamaina lehenetsia</string>\n    <string name=\"tag_orf_preview_image_start\">Aurrebista Irudia Hasi</string>\n    <string name=\"tag_orf_preview_image_length\">Aurrebista irudiaren luzera</string>\n    <string name=\"tag_orf_aspect_frame\">Aspektu Markoa</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Sentsorearen beheko ertza</string>\n    <string name=\"tag_rw2_sensor_left_border\">Sentsorearen ezkerreko ertza</string>\n    <string name=\"tag_rw2_sensor_right_border\">Sentsorearen eskuineko ertza</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sentsorearen goiko ertza</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Marraztu testua bideko letra-tipoarekin eta kolorearekin</string>\n    <string name=\"font_size\">Letra-tamaina</string>\n    <string name=\"watermark_size\">Ur-markaren tamaina</string>\n    <string name=\"repeat_text\">Errepikatu testua</string>\n    <string name=\"repeat_text_sub\">Uneko testua errepikatuko da bidea amaitu arte, behin marraztu beharrean</string>\n    <string name=\"dash_size\">Marratxoaren tamaina</string>\n    <string name=\"draw_mode_image_sub\">Erabili hautatutako irudia emandako bidetik marrazteko</string>\n    <string name=\"draw_image_sub\">Irudi hau marraztutako bidearen sarrera errepikakor gisa erabiliko da</string>\n    <string name=\"outlined_triangle_sub\">Triangelu eskematua marrazten du hasierako puntutik amaierako puntura</string>\n    <string name=\"triangle_sub\">Triangelu eskematua marrazten du hasierako puntutik amaierako puntura</string>\n    <string name=\"outlined_triangle\">Triangelu eskematua</string>\n    <string name=\"triangle\">Triangelua</string>\n    <string name=\"polygon_sub\">Hasierako puntutik amaierako poligonoa marrazten du</string>\n    <string name=\"polygon\">Poligonoa</string>\n    <string name=\"outlined_polygon\">Deskribatutako poligonoa</string>\n    <string name=\"outlined_polygon_sub\">Aztertutako poligonoa marrazten du hasierako puntutik amaieraraino</string>\n    <string name=\"vertices\">Erpinak</string>\n    <string name=\"draw_regular_polygon\">Marraztu poligono erregularra</string>\n    <string name=\"draw_regular_polygon_sub\">Marraztu poligonoa forma askearen ordez erregularra izango dena</string>\n    <string name=\"star_sub\">Izarra hasierako puntutik amaierara marrazten du</string>\n    <string name=\"star\">Izarra</string>\n    <string name=\"outlined_star\">Izarra deskribatua</string>\n    <string name=\"outlined_star_sub\">Marraztutako izarra hasierako puntutik amaierako puntura marrazten du</string>\n    <string name=\"inner_radius_ratio\">Barne Erradio Erlazioa</string>\n    <string name=\"draw_regular_star\">Marraztu izar erregularra</string>\n    <string name=\"draw_regular_star_sub\">Marraztu forma askearen ordez erregularra izango den izarra</string>\n    <string name=\"antialias\">Antialiak</string>\n    <string name=\"antialias_sub\">Antialiasing gaitzen du ertz zorrotzak saihesteko</string>\n    <string name=\"open_edit_instead_of_preview\">Ireki Editatu Aurrebistaren ordez</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Irudia irekitzeko (aurrebista) hautatzen duzunean ImageToolbox-en, editatu hautapen orria irekiko da aurrebistaren ordez</string>\n    <string name=\"document_scanner\">Dokumentuen eskanerra</string>\n    <string name=\"document_scanner_sub\">Eskaneatu dokumentuak eta sortu PDF edo bereizi irudiak haietatik</string>\n    <string name=\"click_to_start_scanning\">Egin klik eskaneatzen hasteko</string>\n    <string name=\"start_scanning\">Hasi eskaneatzen</string>\n    <string name=\"save_as_pdf\">Gorde Pdf gisa</string>\n    <string name=\"share_as_pdf\">Partekatu PDF gisa</string>\n    <string name=\"options_below_is_for_images\">Beheko aukerak irudiak gordetzeko dira, ez PDF</string>\n    <string name=\"equalize_histogram_hsv\">Berdindu histograma HSV</string>\n    <string name=\"equalize_histogram\">Histograma berdindu</string>\n    <string name=\"enter_percentage\">Sartu ehunekoa</string>\n    <string name=\"allow_enter_by_text_field\">Baimendu testu-eremuaren bidez sartzeko</string>\n    <string name=\"allow_enter_by_text_field_sub\">Aurrez ezarritako hautapenaren atzean dagoen Testu-eremua gaitzen du, berehala sartzeko</string>\n    <string name=\"scale_color_space\">Eskala kolore-espazioa</string>\n    <string name=\"linear\">Lineala</string>\n    <string name=\"equalize_histogram_pixelation\">Berdindu histograma pixelazioa</string>\n    <string name=\"grid_size_x\">Sarearen tamaina X</string>\n    <string name=\"grid_size_y\">Sarearen tamaina Y</string>\n    <string name=\"equalize_histogram_adaptive\">Histograma Egokigarria berdindu</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Histograma Egokitzeko LUV berdindu</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Histograma berdindu LAB moldatzailea</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Moztu edukira</string>\n    <string name=\"frame_color\">Markoaren Kolorea</string>\n    <string name=\"color_to_ignore\">Ez ikusi egin beharreko kolorea</string>\n    <string name=\"template\">Txantiloia</string>\n    <string name=\"no_template_filters\">Ez da txantiloi-iragazkirik gehitu</string>\n    <string name=\"create_new\">Sortu Berria</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Eskaneatutako QR kodea ez da baliozko iragazki txantiloia</string>\n    <string name=\"scan_qr_code\">Eskaneatu QR kodea</string>\n    <string name=\"opened_file_have_no_filter_template\">Hautatutako fitxategiak ez du iragazki txantiloiaren daturik</string>\n    <string name=\"create_template\">Sortu txantiloia</string>\n    <string name=\"template_name\">Txantiloiaren izena</string>\n    <string name=\"select_template_preview\">Irudi hau iragazki txantiloi honen aurrebista egiteko erabiliko da</string>\n    <string name=\"template_filter\">Txantiloi-iragazkia</string>\n    <string name=\"as_qr_code\">QR kodearen irudi gisa</string>\n    <string name=\"as_file\">Fitxategi gisa</string>\n    <string name=\"save_as_file\">Gorde fitxategi gisa</string>\n    <string name=\"save_as_qr_code_image\">Gorde QR kodearen irudi gisa</string>\n    <string name=\"delete_template\">Ezabatu txantiloia</string>\n    <string name=\"delete_template_warn\">Hautatutako txantiloi-iragazkia ezabatzera zoaz. Eragiketa hau ezin da desegin</string>\n    <string name=\"added_filter_template\"> \\\"%1$s \\\" izena duen iragazki txantiloia gehitu da (%2$s)</string>\n    <string name=\"filter_preview\">Iragaziaren aurrebista</string>\n    <string name=\"qr_code\">QR eta barra-kodea</string>\n    <string name=\"qr_code_sub\">Eskaneatu QR kodea eta lortu bere edukia edo itsatsi zure katea berria sortzeko</string>\n    <string name=\"code_content\">Kode Edukia</string>\n    <string name=\"scan_qr_code_to_replace_content\">Eskaneatu edozein barra-kode eremuko edukia ordezkatzeko, edo idatzi zerbait barra-kode berria sortzeko hautatutako motarekin</string>\n    <string name=\"qr_description\">QR deskribapena</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Eman kamerari baimena ezarpenetan QR kodea eskaneatzeko</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Eman kamerari baimena dokumentuen eskanerra eskaneatzeko ezarpenetan</string>\n    <string name=\"cubic\">Kubikoa</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Kuadrikoa</string>\n    <string name=\"gaussian\">Gauss</string>\n    <string name=\"sphinx\">Esfingea</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Kutxa</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lantxoak 2</string>\n    <string name=\"lanczos3\">Lantxoak 3</string>\n    <string name=\"lanczos4\">Lantxoak 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Interpolazio kubikoak eskala leunagoa eskaintzen du hurbilen dauden 16 pixelak kontuan hartuta, bilineala baino emaitza hobeak emanez.</string>\n    <string name=\"bspline_sub\">Zatika definitutako polinomio-funtzioak erabiltzen ditu kurba edo gainazal bat, forma-errepresentazio malgua eta jarraitua leunki interpolatzeko eta hurbiltzeko.</string>\n    <string name=\"hamming_sub\">Seinale baten ertzak txikituz ihes espektrala murrizteko erabiltzen den leiho-funtzioa, seinalea prozesatzeko erabilgarria.</string>\n    <string name=\"hanning_sub\">Hann leihoaren aldaera bat, seinaleak prozesatzeko aplikazioetan ihes espektrala murrizteko erabili ohi dena</string>\n    <string name=\"blackman_sub\">Maiztasun-bereizmen ona eskaintzen duen leiho-funtzioa, ihes espektrala gutxituz, sarritan seinalea prozesatzeko erabiltzen dena</string>\n    <string name=\"welch_sub\">Maiztasun-bereizmen ona emateko diseinatutako leiho-funtzioa, ihes espektral murriztuarekin, sarritan seinalea prozesatzeko aplikazioetan erabilia</string>\n    <string name=\"quadric_sub\">Interpolaziorako funtzio koadratikoa erabiltzen duen metodoa, emaitza leun eta jarraituak ematen dituena</string>\n    <string name=\"gaussian_sub\">Gauss funtzio bat aplikatzen duen interpolazio-metodoa, irudietan zarata leuntzeko eta murrizteko erabilgarria</string>\n    <string name=\"sphinx_sub\">Birlaginketa metodo aurreratua kalitate handiko interpolazioa eskaintzen duen artefaktu minimoekin</string>\n    <string name=\"bartlett_sub\">Seinalearen prozesamenduan erabiltzen den leiho triangeluar funtzioa ihes espektrala murrizteko</string>\n    <string name=\"robidoux_sub\">Irudi naturalaren tamaina aldatzeko optimizatutako kalitate handiko interpolazio metodoa, zorroztasuna eta leuntasuna orekatuz</string>\n    <string name=\"robidoux_sharp_sub\">Robidoux metodoaren aldaera zorrotzagoa, irudi kurruskaria aldatzeko optimizatua</string>\n    <string name=\"spline16_sub\">Splinen oinarritutako interpolazio-metodoa, 16 sakatze-iragazkia erabiliz emaitza leunak ematen dituena</string>\n    <string name=\"spline36_sub\">Splinen oinarritutako interpolazio-metodoa, 36 sakatze-iragazkia erabiliz emaitza leunak ematen dituena</string>\n    <string name=\"spline64_sub\">Splinen oinarritutako interpolazio-metodoa, 64 sakatze-iragazkia erabiliz emaitza leunak ematen dituena</string>\n    <string name=\"kaiser_sub\">Kaiser leihoa erabiltzen duen interpolazio-metodoa, lobulu nagusiaren zabaleraren eta alboko lobuluen mailaren arteko trukearen kontrol ona eskaintzen duena.</string>\n    <string name=\"bartlett_hann_sub\">Bartlett eta Hann leihoak konbinatzen dituen leiho-funtzio hibridoa, seinaleen prozesamenduan ihes espektralak murrizteko erabiltzen dena.</string>\n    <string name=\"box_sub\">Hurbilen dauden pixelen balioen batez bestekoa erabiltzen duen birlaginketa-metodo sinplea, askotan bloke-itxura sortzen duena</string>\n    <string name=\"bohman_sub\">Ihes espektralak murrizteko erabiltzen den leiho-funtzioa, seinalea prozesatzeko aplikazioetan maiztasun-bereizmen ona eskaintzen duena</string>\n    <string name=\"lanczos2_sub\">2 lobuludun Lanczos iragazkia erabiltzen duen birlaginketa metodoa kalitate handiko interpolaziorako artefaktu minimoekin</string>\n    <string name=\"lanczos3_sub\">3 lobuludun Lanczos iragazkia erabiltzen duen birlaginketa metodoa kalitate handiko interpolaziorako artefaktu minimoekin</string>\n    <string name=\"lanczos4_sub\">Lanczos 4 lobuluko iragazkia erabiltzen duen birlaginketa metodoa kalitate handiko interpolaziorako artefaktu minimoekin</string>\n    <string name=\"lanczos2_jinc_sub\">Jinc funtzioa erabiltzen duen Lanczos 2 iragazkiaren aldaera bat, kalitate handiko interpolazioa eskaintzen du artefaktu minimoekin</string>\n    <string name=\"lanczos3_jinc_sub\">Jinc funtzioa erabiltzen duen Lanczos 3 iragazkiaren aldaera, kalitate handiko interpolazioa eskaintzen du artefaktu minimoekin</string>\n    <string name=\"lanczos4_jinc_sub\">Jinc funtzioa erabiltzen duen Lanczos 4 iragazkiaren aldaera, kalitate handiko interpolazioa eskaintzen du artefaktu minimoekin</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Hanning iragazkiaren EWA (Eliptical Weighted Average) aldaera, interpolazio leun eta birlaginketa egiteko</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Eliptical Weighted Average (EWA) Robidoux iragazkiaren aldaera kalitate handiko birlaginketa egiteko</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Eliptical Weighted Average (EWA) Blackman iragazkiaren aldaera, dei artefaktuak gutxitzeko</string>\n    <string name=\"ewa_quadric\">EWA kuadrikoa</string>\n    <string name=\"ewa_quadric_sub\">Eliptical Weighted Average (EWA) iragazki kuadrikoaren aldaera interpolazio leunerako</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Robidoux Sharp iragazkiaren batez besteko haztatutako eliptikoa (EWA) aldaera emaitza zorrotzagoak lortzeko</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Eliptical Weighted Average (EWA) Lanczos 3 Jinc iragazkiaren aldaera kalitate handiko birlaginketa aliasing murriztuarekin</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Kalitate handiko irudiak prozesatzeko diseinatutako birlaginketa-iragazkia, zorroztasun eta leuntasun oreka onarekin</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Eliptical Weighted Average (EWA) Ginseng iragazkiaren aldaera irudiaren kalitatea hobetzeko</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Eliptical Weighted Average (EWA) Lanczos Sharp iragazkiaren aldaera, artefaktu minimoekin emaitza zorrotzak lortzeko</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA zorrotzena</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Eliptical Weighted Average (EWA) Lanczos 4 Sharpest iragazkiaren aldaera, irudiak oso zorrotzak birlagintzeko</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Eliptical Weighted Average (EWA) Lanczos Soft iragazkiaren aldaera, irudien birlaginketa leunagoa izateko</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Haasn-ek diseinatutako birlaginketa-iragazkia irudiak leun eta artefakturik gabeko eskalatzeko</string>\n    <string name=\"format_conversion\">Formatu Bihurketa</string>\n    <string name=\"format_conversion_sub\">Bihurtu irudi sorta formatu batetik bestera</string>\n    <string name=\"dismiss_forever\">Baztertu Betiko</string>\n    <string name=\"image_stacking\">Irudien pilaketa</string>\n    <string name=\"image_stacking_sub\">Bildu irudiak bata bestearen gainean aukeratutako nahasketa moduekin</string>\n    <string name=\"add_image\">Gehitu irudia</string>\n    <string name=\"bins_count\">Binak zenbatzen dira</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Histograma HSL egokitzailea berdindu</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Berdindu histograma Adaptive HSV</string>\n    <string name=\"edge_mode\">Ertz modua</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Itzulbiratu</string>\n    <string name=\"color_blind_scheme\">Daltonismoa</string>\n    <string name=\"color_blind_scheme_sub\">Hautatu modua gaiaren koloreak egokitzeko hautatutako daltonismoaren aldaerarako</string>\n    <string name=\"protanomaly_sub\">Tonu gorria eta berdea bereizteko zailtasuna</string>\n    <string name=\"deuteranomaly_sub\">Tonu berdea eta gorria bereizteko zailtasuna</string>\n    <string name=\"tritanomaly_sub\">Tonu urdina eta horia bereizteko zailtasuna</string>\n    <string name=\"protanopia_sub\">Tonu gorriak hautemateko ezintasuna</string>\n    <string name=\"deuteranopia_sub\">Tonu berdeak hautemateko ezintasuna</string>\n    <string name=\"tritanopia_sub\">Tonu urdinak hautemateko ezintasuna</string>\n    <string name=\"achromatomaly_sub\">Kolore guztietarako sentikortasuna murriztu da</string>\n    <string name=\"achromatopsia_sub\">Daltonismo osoa, gris tonuak bakarrik ikusiz</string>\n    <string name=\"not_use_color_blind_scheme\">Ez erabili daltonismoaren eskema</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Koloreak gaian ezarritakoaren araberakoak izango dira</string>\n    <string name=\"sigmoidal\">Sigmoidea</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">2. ordenako Lagrange interpolazio-iragazkia, trantsizio leunekin kalitate handiko irudiak eskalatzeko egokia</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">3. ordenako Lagrange interpolazio-iragazkia, zehaztasun hobea eta emaitza leunagoak eskaintzen ditu irudiak eskalatzeko</string>\n    <string name=\"lanczos_6\">Lantxoak 6</string>\n    <string name=\"lanczos_6_sub\">Lanczos-en birlaginketa-iragazkia 6 ordena handiagoarekin, irudien eskalatze zorrotzagoa eta zehatzagoa eskaintzen duena</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Lanczos 6 iragazkiaren aldaera Jinc funtzioa erabiliz irudien birlaginketa kalitatea hobetzeko</string>\n    <string name=\"linear_box_blur\">Kutxa lineala lausotzea</string>\n    <string name=\"linear_tent_blur\">Karpa lausotu lineala</string>\n    <string name=\"linear_gaussian_box_blur\">Gauss Lineala Kutxa Lausotzea</string>\n    <string name=\"linear_stack_blur\">Pila lineala lausotzea</string>\n    <string name=\"gaussian_box_blur\">Gaussiar Kutxa Lausotzea</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lausotze Gaussiar Azkarra Lineala Hurrengoa</string>\n    <string name=\"linear_fast_gaussian_blur\">Gaussiar Lausotasun Azkarra Lineala</string>\n    <string name=\"linear_gaussian_blur\">Gauss lausotze lineala</string>\n    <string name=\"draw_filter_sub\">Aukeratu iragazki bat pintura gisa erabiltzeko</string>\n    <string name=\"replace_filter\">Ordeztu iragazkia</string>\n    <string name=\"pick_filter_info\">Hautatu beheko iragazkia zure marrazkian pintzel gisa erabiltzeko</string>\n    <string name=\"tiff_compression_scheme\">TIFF konpresio eskema</string>\n    <string name=\"low_poly\">Low Poly</string>\n    <string name=\"sand_painting\">Harea Pintura</string>\n    <string name=\"image_splitting\">Irudien zatiketa</string>\n    <string name=\"image_splitting_sub\">Zatitu irudi bakarra errenkada edo zutabeen arabera</string>\n    <string name=\"fit_to_bounds\">Mugetara egokitu</string>\n    <string name=\"fit_to_bounds_sub\">Konbinatu mozketaren tamaina aldatzeko modua parametro honekin nahi duzun portaera lortzeko (Moztu/Doitu aspektu-erlaziora)</string>\n    <string name=\"languages_imported\">Inportatu dira hizkuntzak</string>\n    <string name=\"backup_ocr_models\">Egin babeskopiak OCR ereduak</string>\n    <string name=\"import_word\">Inportatu</string>\n    <string name=\"export\">Esportatu</string>\n    <string name=\"position\">Posizioa</string>\n    <string name=\"center\">Zentroa</string>\n    <string name=\"top_left\">Goiko Ezkerrean</string>\n    <string name=\"top_right\">Goian Eskuinekoa</string>\n    <string name=\"bottom_left\">Beheko Ezkerrean</string>\n    <string name=\"bottom_right\">Behean Eskuinean</string>\n    <string name=\"top_center\">Goiko erdigunea</string>\n    <string name=\"center_right\">Erdian Eskuin</string>\n    <string name=\"bottom_center\">Beheko Erdian</string>\n    <string name=\"center_left\">Erdiko Ezkerra</string>\n    <string name=\"target_image\">Helburuko irudia</string>\n    <string name=\"palette_transfer\">Paleta transferentzia</string>\n    <string name=\"enhanced_oil\">Olio hobetua</string>\n    <string name=\"simple_old_tv\">Telebista zaharra sinplea</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Krokis sinplea</string>\n    <string name=\"soft_glow\">Distira leuna</string>\n    <string name=\"color_poster\">Koloretako kartela</string>\n    <string name=\"tri_tone\">Hiru Tonua</string>\n    <string name=\"third_color\">Hirugarren kolorea</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">2x2 dithering multzokatua</string>\n    <string name=\"clustered_4x4_dithering\">4x4 dithering multzokatua</string>\n    <string name=\"clustered_8x8_dithering\">8x8 dithering multzokatua</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Ez dago gogoko aukerarik hautatu, gehitu tresnak orrian</string>\n    <string name=\"add_favorites\">Gehitu gogokoak</string>\n    <string name=\"harmony_complementary\">Osagarria</string>\n    <string name=\"harmony_analogous\">Analogoa</string>\n    <string name=\"harmony_triadic\">Triadikoa</string>\n    <string name=\"harmony_split_complementary\">Zatiketa osagarria</string>\n    <string name=\"harmony_tetradic\">Tetradikoa</string>\n    <string name=\"harmony_square\">Plaza</string>\n    <string name=\"harmony_analogous_complementary\">Analogikoa + Osagarria</string>\n    <string name=\"color_tools\">Kolore Tresnak</string>\n    <string name=\"color_tools_sub\">Nahastu, egin tonuak, sortu tonu eta gehiago</string>\n    <string name=\"color_harmonies\">Kolore Harmoniak</string>\n    <string name=\"color_shading\">Kolore Itzaltzea</string>\n    <string name=\"variation\">Aldakuntza</string>\n    <string name=\"tints\">Tinduak</string>\n    <string name=\"tones\">Tonuak</string>\n    <string name=\"shades\">Itzalak</string>\n    <string name=\"color_mixing\">Kolore Nahasketa</string>\n    <string name=\"color_info\">Koloreen informazioa</string>\n    <string name=\"selected_color\">Hautatutako kolorea</string>\n    <string name=\"color_to_mix\">Kolorea Nahasteko</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Ezin da dirua erabili kolore dinamikoak aktibatuta dauden bitartean</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Helburuko LUT irudia</string>\n    <string name=\"amatorka\">Afizionatua</string>\n    <string name=\"miss_etikate\">Etiketa andereñoa</string>\n    <string name=\"soft_elegance\">Dotorezia leuna</string>\n    <string name=\"soft_elegance_variant\">Soft Elegance Aldaera</string>\n    <string name=\"palette_transfer_variant\">Paleta transferentzia aldaera</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Helburuko 3D LUT fitxategia (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Lixiba Saihesbidea</string>\n    <string name=\"candlelight\">Kandelaren argia</string>\n    <string name=\"drop_blues\">Jaregin Blues</string>\n    <string name=\"edgy_amber\">Amber zirraragarria</string>\n    <string name=\"fall_colors\">Udazkeneko Koloreak</string>\n    <string name=\"film_stock_50\">Film Stock 50</string>\n    <string name=\"foggy_night\">Gau lainotsua</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Lortu LUT irudi neutroa</string>\n    <string name=\"save_empty_lut_sub\">Lehenik eta behin, erabili zure gogoko argazkiak editatzeko aplikazioa hemen lor dezakezun LUT neutralari iragazki bat aplikatzeko. Honek behar bezala funtziona dezan, pixel kolore bakoitzak ez du beste pixel batzuen menpe egon behar (adibidez, lausotzeak ez du funtzionatuko). Prest dagoenean, erabili zure LUT irudi berria 512*512 LUT iragazkirako sarrera gisa</string>\n    <string name=\"pop_art\">Pop Artea</string>\n    <string name=\"celluloid\">Zeluloidea</string>\n    <string name=\"coffee\">Kafea</string>\n    <string name=\"golden_forest\">Urrezko Basoa</string>\n    <string name=\"greenish\">Berdexka</string>\n    <string name=\"retro_yellow\">Retro horia</string>\n    <string name=\"links_preview\">Estekak aurrebista</string>\n    <string name=\"links_preview_sub\">Testua lor dezakezun lekuetan (QRCode, OCR eta abar) esteken aurrebista berreskuratzea gaitzen du.</string>\n    <string name=\"links\">Estekak</string>\n    <string name=\"ico_size_warning\">ICO fitxategiak 256 x 256 gehienezko tamainan soilik gorde daitezke</string>\n    <string name=\"gif_type_to_webp\">GIF WEBPra</string>\n    <string name=\"gif_type_to_webp_sub\">Bihurtu GIF irudiak WEBP irudi animatuetara</string>\n    <string name=\"webp_tools\">WEBP tresnak</string>\n    <string name=\"webp_tools_sub\">Bihurtu irudiak WEBP animaziozko irudietara edo atera fotogramak emandako WEBP animaziotik</string>\n    <string name=\"webp_type_to_image\">WEBP irudietara</string>\n    <string name=\"webp_type_to_image_sub\">Bihurtu WEBP fitxategia argazki sorta batean</string>\n    <string name=\"webp_type_to_webp_sub\">Bihurtu irudi sorta WEBP fitxategira</string>\n    <string name=\"webp_type_to_webp\">Irudiak WEBPra</string>\n    <string name=\"select_webp_image_to_start\">Hautatu WEBP irudia hasteko</string>\n    <string name=\"manage_storage_extra_types\">Ez dago fitxategietarako sarbide osorik</string>\n    <string name=\"manage_storage_extra_types_sub\">Baimendu fitxategi guztiak sartzeko JXL, QOI eta Android-en irudi gisa ezagutzen ez diren beste irudi batzuk ikusteko. Baimenik gabe Image Toolbox ezin ditu irudi horiek erakutsi</string>\n    <string name=\"default_draw_color\">Marraztu kolore lehenetsia</string>\n    <string name=\"default_draw_path_mode\">Marrazte-bide modu lehenetsia</string>\n    <string name=\"add_timestamp\">Gehitu denbora-zigilua</string>\n    <string name=\"add_timestamp_sub\">Denbora-zigilua irteerako fitxategi-izenari gehitzea gaitzen du</string>\n    <string name=\"formatted_timestamp\">Formateatutako denbora-zigilua</string>\n    <string name=\"formatted_timestamp_sub\">Gaitu Denbora-zigiluaren formatua irteerako fitxategi-izenean oinarrizko milis-en ordez</string>\n    <string name=\"enable_timestamps_to_format_them\">Gaitu Denbora-zigiluak haien formatua hautatzeko</string>\n    <string name=\"one_time_save_location\">Behin gordeko kokapena</string>\n    <string name=\"one_time_save_location_sub\">Ikusi eta editatu behin betiko gordetzeko kokapenak, gehienetan aukera guztietan gordetzeko botoia luze sakatuz erabil ditzakezun</string>\n    <string name=\"recently_used\">Duela gutxi erabilia</string>\n    <string name=\"ci_channel\">CI kanala</string>\n    <string name=\"group\">Taldea</string>\n    <string name=\"image_toolbox_in_telegram\">Irudi-tresnak Telegram-en 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Sartu gure txatean, nahi duzun guztia eztabaidatu ahal izateko eta beta eta iragarkiak argitaratzen ditudan CI kanalean ere begiratu</string>\n    <string name=\"ci_channel_sub\">Jaso jakinarazpenak aplikazioaren bertsio berriei buruz eta irakurri iragarkiak</string>\n    <string name=\"fit_description\">Egokitu irudi bat emandako neurrietara eta aplikatu lausotasuna edo kolorea atzeko planoari</string>\n    <string name=\"tools_arrangement\">Tresnen Antolaketa</string>\n    <string name=\"group_tools_by_type\">Motaren arabera taldekatu tresnak</string>\n    <string name=\"group_tools_by_type_sub\">Pantaila nagusiko tresnak beren motaren arabera taldekatzen ditu, zerrenda pertsonalizatu baten ordez</string>\n    <string name=\"default_values\">Balio lehenetsiak</string>\n    <string name=\"system_bars_visibility\">Sistema Barren Ikusgarritasuna</string>\n    <string name=\"show_system_bars_by_swipe\">Erakutsi sistema-barrak irristatuz</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Sistema-barrak ezkutatuta badaude erakusteko hatza egitea gaitzen du</string>\n    <string name=\"auto\">Autoa</string>\n    <string name=\"hide_all\">Ezkutatu guztiak</string>\n    <string name=\"show_all\">Erakutsi guztiak</string>\n    <string name=\"hide_nav_bar\">Ezkutatu nabigazio-barra</string>\n    <string name=\"hide_status_bar\">Ezkutatu egoera barra</string>\n    <string name=\"noise_generation\">Zarata Sortzea</string>\n    <string name=\"noise_generation_sub\">Sortu Perlin edo beste mota batzuetako zarata desberdinak</string>\n    <string name=\"frequency\">Maiztasuna</string>\n    <string name=\"noise_type\">Zarata Mota</string>\n    <string name=\"rotation_type\">Errotazio Mota</string>\n    <string name=\"fractal_type\">Fraktal Mota</string>\n    <string name=\"octaves\">Oktabak</string>\n    <string name=\"lacunarity\">Lakunartasuna</string>\n    <string name=\"gain\">Irabazi</string>\n    <string name=\"weighted_strength\">Indar haztatua</string>\n    <string name=\"ping_pong_strength\">Ping Pong Indarra</string>\n    <string name=\"distance_function\">Distantzia Funtzioa</string>\n    <string name=\"return_type\">Itzuli mota</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domeinuaren deformazioa</string>\n    <string name=\"alignment\">Lerrokatzea</string>\n    <string name=\"custom_filename\">Fitxategi-izen pertsonalizatua</string>\n    <string name=\"custom_filename_sub\">Hautatu uneko irudia gordetzeko erabiliko diren kokapena eta fitxategi-izena</string>\n    <string name=\"saved_to_custom\">Izen pertsonalizatuarekin karpetan gorde da</string>\n    <string name=\"collage_maker\">Collage Maker</string>\n    <string name=\"collage_maker_sub\">Egin collageak gehienez 20 iruditatik</string>\n    <string name=\"collage_type\">Collage mota</string>\n    <string name=\"collages_info\">Eduki sakatuta irudia trukatzeko, mugitzeko eta zooma posizioa doitzeko</string>\n    <string name=\"disable_rotation\">Desgaitu biraketa</string>\n    <string name=\"disable_rotation_sub\">Bi hatzekin egindako keinuekin irudiak biratzea eragozten du</string>\n    <string name=\"enable_snapping_to_borders\">Gaitu ertzetara atxikitzea</string>\n    <string name=\"enable_snapping_to_borders_sub\">Mugitu edo zooma egin ondoren, irudiak koadroaren ertzak beteko dira</string>\n    <string name=\"histogram\">Histograma</string>\n    <string name=\"histogram_sub\">RGB edo Distira irudiaren histograma doikuntzak egiten laguntzeko</string>\n    <string name=\"image_for_histogram\">Irudi hau RGB eta Distira histogramak sortzeko erabiliko da</string>\n    <string name=\"tesseract_options\">Tesseract Aukerak</string>\n    <string name=\"tesseract_options_sub\">Aplikatu sarrerako aldagai batzuk tesseract motorrako</string>\n    <string name=\"custom_options\">Aukera pertsonalizatuak</string>\n    <string name=\"custom_params_info\">Aukerak eredu hau jarraituz sartu behar dira:  \\\"--{option_name} {value} \\\"</string>\n    <string name=\"auto_crop\">Mozketa automatikoa</string>\n    <string name=\"free_corners\">Doako Txokoak</string>\n    <string name=\"free_corners_sub\">Moztu irudia poligonoz, honek perspektiba ere zuzentzen du</string>\n    <string name=\"coerce_points_to_image_bounds\">Bortxatu Irudien Mugetara</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Puntuak ez dira irudien mugek mugatuko, hau da, perspektiba zehatzago zuzentzeko erabilgarria</string>\n    <string name=\"mask\">Maskara</string>\n    <string name=\"spot_heal_sub\">Edukia kontzienteki bete marraztutako bidearen azpian</string>\n    <string name=\"spot_heal\">Sendatu Lekua</string>\n    <string name=\"use_circle_kernel\">Erabili Circle Kernel</string>\n    <string name=\"opening\">Irekiera</string>\n    <string name=\"closing\">Itxiera</string>\n    <string name=\"morphological_gradient\">Gradiente morfologikoa</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Kapela Beltza</string>\n    <string name=\"tone_curves\">Tonu Kurbak</string>\n    <string name=\"reset_curves\">Berrezarri Kurbak</string>\n    <string name=\"reset_curves_sub\">Kurbak balio lehenetsira itzuliko dira</string>\n    <string name=\"line_style\">Lerro-estiloa</string>\n    <string name=\"gap_size\">Hutsunearen Tamaina</string>\n    <string name=\"dashed\">Marrakatua</string>\n    <string name=\"dot_dashed\">Dot Marrakatua</string>\n    <string name=\"stamped\">Zigilua</string>\n    <string name=\"zigzag\">Sigi-saga</string>\n    <string name=\"dashed_sub\">Lerro eten bat marrazten du marraztutako bidetik zehaztutako hutsunearen tamainarekin</string>\n    <string name=\"dot_dashed_sub\">Emandako bidetik puntua eta marra etena marrazten ditu</string>\n    <string name=\"defaultt_sub\">Lerro zuzen lehenetsiak besterik ez</string>\n    <string name=\"stamped_sub\">Aukeratutako formak marrazten ditu bidearen zehar zehaztutako tartearekin</string>\n    <string name=\"zigzag_sub\">Bidean zehar sigi-saga uhintsuak marrazten ditu</string>\n    <string name=\"zigzag_ratio\">Sigi-saga-erlazioa</string>\n    <string name=\"create_shortcut\">Sortu lasterbidea</string>\n    <string name=\"create_shortcut_title\">Aukeratu ainguratzeko tresna</string>\n    <string name=\"create_shortcut_subtitle\">Tresna abiarazlearen hasierako pantailan gehituko da lasterbide gisa, erabili  \\\"Saltatu fitxategiak hautatzea \\\" ezarpenarekin konbinatuz, beharrezko portaera lortzeko.</string>\n    <string name=\"dont_stack_frames\">Ez pilatu markoak</string>\n    <string name=\"dont_stack_frames_sub\">Aurreko fotogramak botatzeko aukera ematen du, beraz, ez dira elkarren gainean pilatuko</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Fotogramak elkarren artean gurutzatuta egongo dira</string>\n    <string name=\"crossfade_count\">Crossfade fotogramak zenbatzen dira</string>\n    <string name=\"threshold_one\">Atalase bat</string>\n    <string name=\"threshold_two\">Bigarren atalasea</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Ispilua 101</string>\n    <string name=\"enhanced_zoom_blur\">Zoom Lausodura hobetua</string>\n    <string name=\"laplacian_simple\">Laplaziar sinplea</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Laguntzailea Sarea</string>\n    <string name=\"helper_grid_sub\">Marrazki-eremuaren gainean euskarria erakusten du manipulazio zehatzak egiteko</string>\n    <string name=\"grid_color\">Sarearen kolorea</string>\n    <string name=\"cell_width\">Zelula-zabalera</string>\n    <string name=\"cell_height\">Zelula-Altuera</string>\n    <string name=\"compact_selectors\">Hautatzaile trinkoak</string>\n    <string name=\"compact_selectors_sub\">Hautaketa-kontrol batzuek diseinu trinkoa erabiliko dute leku gutxiago hartzeko</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Eman argazkia ateratzeko kameraren baimena ezarpenetan</string>\n    <string name=\"layout\">Diseinua</string>\n    <string name=\"main_screen_title\">Pantaila nagusiaren izenburua</string>\n    <string name=\"constant_rate_factor\">Tasa Konstanteko Faktorea (CRF)</string>\n    <string name=\"crf_sub\">%1$s balio batek konpresio motela esan nahi du, eta horren ondorioz fitxategiaren tamaina txiki samarra da. %2$s-k konpresio azkarragoa esan nahi du, fitxategi handi bat sortuz.</string>\n    <string name=\"lut_library\">Lut Liburutegia</string>\n    <string name=\"lut_library_sub\">Deskargatu LUT bilduma, deskargatu ondoren aplika dezakezuna</string>\n    <string name=\"lut_library_update_sub\">Eguneratu LUT bilduma (berriak bakarrik jarriko dira ilaran), deskargatu ondoren aplika dezakezuna</string>\n    <string name=\"filter_preview_image_sub\">Aldatu iragazkien irudien aurrebista lehenetsia</string>\n    <string name=\"filter_preview_image\">Aurrebista irudia</string>\n    <string name=\"hide\">Ezkutatu</string>\n    <string name=\"show\">Erakutsi</string>\n    <string name=\"slider_type\">Graduatzaile mota</string>\n    <string name=\"fancy\">Fantasia</string>\n    <string name=\"material_2\">Materiala 2</string>\n    <string name=\"fancy_sub\">Itxura dotoreko graduatzailea. Hau da aukera lehenetsia</string>\n    <string name=\"material_2_sub\">Material 2 graduatzailea</string>\n    <string name=\"material_you_slider_sub\">A Material You graduatzailea</string>\n    <string name=\"apply\">Aplikatu</string>\n    <string name=\"center_align_dialog_buttons\">Erdiko elkarrizketa-botoiak</string>\n    <string name=\"center_align_dialog_buttons_sub\">Elkarrizketa-botoiak erdian kokatuko dira ezkerreko aldean beharrean</string>\n    <string name=\"open_source_licenses\">Kode irekiko lizentziak</string>\n    <string name=\"open_source_licenses_sub\">Ikusi aplikazio honetan erabiltzen diren kode irekiko liburutegien lizentziak</string>\n    <string name=\"area\">Eremua</string>\n    <string name=\"area_sub\">Birlaginketa pixelaren eremuaren erlazioa erabiliz. Irudiak dezimatzeko metodo hobetsia izan daiteke, moirerik gabeko emaitzak ematen baititu. Baina irudia handitzen denean,  \\\"Gertuena \\\" metodoaren antzekoa da.</string>\n    <string name=\"enable_tonemapping\">Gaitu Tonemapping</string>\n    <string name=\"enter_percent\">Sartu %</string>\n    <string name=\"unknown_host\">Ezin da webgunera sartu, saiatu VPN erabiltzen edo egiaztatu url-a zuzena den</string>\n    <string name=\"markup_layers\">Markatze geruzak</string>\n    <string name=\"markup_layers_sub\">Geruzak modua irudiak, testuak eta beste modu askean jartzeko gaitasunarekin</string>\n    <string name=\"edit_layer\">Editatu geruza</string>\n    <string name=\"layers_on_image\">Geruzak irudian</string>\n    <string name=\"layers_on_image_sub\">Erabili irudi bat atzeko plano gisa eta gehitu geruza desberdinak gainean</string>\n    <string name=\"layers_on_background\">Geruzak atzeko planoan</string>\n    <string name=\"layers_on_background_sub\">Lehen aukeraren berdina baina irudiaren ordez kolorearekin</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Ezarpen azkarrak aldean</string>\n    <string name=\"fast_settings_side_sub\">Gehitu zerrenda mugikor bat hautatutako aldean irudiak editatzen dituzun bitartean, eta horrek ezarpen azkarrak irekiko ditu klik egiten duzunean</string>\n    <string name=\"clear_selection\">Garbitu hautaketa</string>\n    <string name=\"settings_group_visibility_hidden\"> \\\"%1$s \\\" ezarpen taldea lehenespenez tolestuta egongo da</string>\n    <string name=\"settings_group_visibility_visible\"> \\\"%1$s \\\" ezarpen taldea lehenespenez zabalduko da</string>\n    <string name=\"base_64_tools\">Base64 tresnak</string>\n    <string name=\"base_64_tools_sub\">Deskodetu Base64 katea irudira, edo kodetu irudia Base64 formatuan</string>\n    <string name=\"base_64\">Oinarria64</string>\n    <string name=\"not_a_valid_base_64\">Emandako balioa ez da baliozko Base64 kate bat</string>\n    <string name=\"copy_not_a_valid_base_64\">Ezin da kopiatu Base64 kate hutsa edo baliogabea</string>\n    <string name=\"paste_base_64\">Itsatsi Oinarria64</string>\n    <string name=\"copy_base_64\">Kopiatu Base64</string>\n    <string name=\"base_64_tips\">Kargatu irudia Base64 katea kopiatzeko edo gordetzeko. Katea bera baduzu, goiko itsatsi dezakezu irudia lortzeko</string>\n    <string name=\"save_base_64\">Gorde Base64</string>\n    <string name=\"share_base_64\">Partekatu Base64</string>\n    <string name=\"options\">Aukerak</string>\n    <string name=\"actions\">Ekintzak</string>\n    <string name=\"import_base_64\">Inportatu Base64</string>\n    <string name=\"base_64_actions\">Base64 Ekintzak</string>\n    <string name=\"add_outline\">Gehitu eskema</string>\n    <string name=\"add_outline_sub\">Gehitu eskema kolore eta zabalera zehaztutako testuaren inguruan</string>\n    <string name=\"outline_color\">Eskema Kolorea</string>\n    <string name=\"outline_size\">Eskema Tamaina</string>\n    <string name=\"rotation\">Errotazioa</string>\n    <string name=\"checksum_as_filename\">Checksum fitxategi-izen gisa</string>\n    <string name=\"checksum_as_filename_sub\">Irteerako irudiek beren datuen kontrol-sumari dagokion izena izango dute</string>\n    <string name=\"free_software_partner\">Software librea (bazkidea)</string>\n    <string name=\"free_software_partner_sub\">Software erabilgarriagoa Android aplikazioen bazkide kanalean</string>\n    <string name=\"algorithms\">Algoritmoa</string>\n    <string name=\"checksum_tools\">Checksum tresnak</string>\n    <string name=\"checksum_tools_sub\">Konparatu kontrol batuketak, kalkulatu hashak edo sortu hashing-algoritmo desberdinak erabiliz fitxategietatik hex kateak</string>\n    <string name=\"calculate\">Kalkulatu</string>\n    <string name=\"text_hash\">Testu Hash</string>\n    <string name=\"checksum\">Checksum</string>\n    <string name=\"pick_file_to_checksum\">Aukeratu fitxategia hautatutako algoritmoan oinarrituta bere kontrol-sumoa kalkulatzeko</string>\n    <string name=\"enter_text_to_checksum\">Idatzi testua hautatutako algoritmoan oinarrituta kalkulatzeko</string>\n    <string name=\"source_checksum\">Iturburua egiaztatzeko batura</string>\n    <string name=\"checksum_to_compare\">Konparatzeko checksum</string>\n    <string name=\"match\">Partidu!</string>\n    <string name=\"difference\">Aldea</string>\n    <string name=\"match_sub\">Checksumak berdinak dira, segurua izan daiteke</string>\n    <string name=\"difference_sub\">Checksumak ez dira berdinak, fitxategia segurua izan daiteke!</string>\n    <string name=\"mesh_gradients\">Sarearen gradienteak</string>\n    <string name=\"collection_mesh_gradients_sub\">Begiratu sareko Gradienteen sareko bilduma</string>\n    <string name=\"wrong_font\">TTF eta OTF letra-tipoak soilik inporta daitezke</string>\n    <string name=\"import_font\">Inportatu letra-tipoa (TTF/OTF)</string>\n    <string name=\"export_fonts\">Esportatu letra-tipoak</string>\n    <string name=\"imported_fonts\">Inportatutako letra-tipoak</string>\n    <string name=\"error_while_saving\">Errore bat gertatu da saiakera gordetzean, saiatu irteera karpeta aldatzen</string>\n    <string name=\"filename_is_not_set\">Fitxategiaren izena ez dago ezarrita</string>\n    <string name=\"none\">Bat ere ez</string>\n    <string name=\"custom_pages\">Orriak pertsonalizatuak</string>\n    <string name=\"pages_selection\">Orrialdeak hautatzea</string>\n    <string name=\"tool_exit_confirmation\">Erremintaren irteeraren berrespena</string>\n    <string name=\"tool_exit_confirmation_sub\">Tresna jakinak erabiltzen dituzun bitartean gorde gabeko aldaketak badituzu eta ixten saiatzen bazara, berretsi elkarrizketa-koadroa agertuko da</string>\n    <string name=\"edit_exif_screen\">Editatu EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Aldatu irudi bakarreko metadatuak birkonpresiorik gabe</string>\n    <string name=\"edit_exif_tag\">Sakatu erabilgarri dauden etiketak editatzeko</string>\n    <string name=\"change_sticker\">Aldatu eranskailua</string>\n    <string name=\"fit_width\">Egokitzeko Zabalera</string>\n    <string name=\"fit_height\">Fit Altuera</string>\n    <string name=\"batch_compare\">Batch Konparazioa</string>\n    <string name=\"pick_files_to_checksum\">Aukeratu fitxategiak/fitxategiak hautatutako algoritmoan oinarrituta bere kontrol-bagadura kalkulatzeko</string>\n    <string name=\"pick_files\">Aukeratu Fitxategiak</string>\n    <string name=\"pick_directory\">Aukeratu direktorioa</string>\n    <string name=\"head_length_scale\">Buruaren Luzera Eskala</string>\n    <string name=\"stamp\">Zigilua</string>\n    <string name=\"timestamp\">Denbora-zigilua</string>\n    <string name=\"format_pattern\">Formatu eredua</string>\n    <string name=\"padding\">Betegarria</string>\n    <string name=\"image_cutting\">Irudiaren mozketa</string>\n    <string name=\"image_cutting_sub\">Moztu irudiaren zatia eta batu ezkerrekoak (alderantzizkoa izan daiteke) lerro bertikal edo horizontalen bidez</string>\n    <string name=\"vertical_pivot_line\">Pibot-lerro bertikala</string>\n    <string name=\"horizontal_pivot_line\">Pibot-lerro horizontala</string>\n    <string name=\"inverse_selection\">Alderantzizko hautaketa</string>\n    <string name=\"inverse_vertical_selection_sub\">Ebakitako zati bertikala utziko da, moztutako eremuaren inguruan zatiak batu beharrean</string>\n    <string name=\"inverse_horizontal_selection_sub\">Moztutako zati horizontala utziko da, moztutako eremuaren inguruan zatiak batu beharrean</string>\n    <string name=\"collection_mesh_gradients\">Sare-gradienteen bilduma</string>\n    <string name=\"mesh_gradients_sub\">Sortu sare-gradientea korapilo eta bereizmen kopuru pertsonalizatuarekin</string>\n    <string name=\"gradient_maker_type_image_mesh\">Sarearen gradientearen gainjartzea</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Konposatu emandako irudien goiko sareko gradientea</string>\n    <string name=\"points_customization\">Puntuen Pertsonalizazioa</string>\n    <string name=\"grid_size\">Sarearen tamaina</string>\n    <string name=\"resolution_x\">X Ebazpena</string>\n    <string name=\"resolution_y\">Y ebazpena</string>\n    <string name=\"resolution\">Ebazpena</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">Nabarmendu Kolorea</string>\n    <string name=\"pixel_comparison_type\">Pixel konparazio mota</string>\n    <string name=\"scan_barcode\">Eskaneatu barra-kodea</string>\n    <string name=\"height_ratio\">Altuera ratioa</string>\n    <string name=\"barcode_type\">Barra-kode mota</string>\n    <string name=\"enforce_bw\">B/N betearazi</string>\n    <string name=\"enforce_bw_sub\">Barra-kodearen irudia zuri-beltzean izango da eta ez da aplikazioaren gaiaren arabera koloreztatu</string>\n    <string name=\"barcodes_sub\">Eskaneatu edozein barra-kode (QR, EAN, AZTEC, …) eta lortu bere edukia edo itsatsi zure testua berri bat sortzeko</string>\n    <string name=\"no_barcode_found\">Ez da barra-koderik aurkitu</string>\n    <string name=\"generated_barcode_will_be_here\">Sortutako barra-kodea hemen egongo da</string>\n    <string name=\"audio_cover_extractor\">Audio Azalak</string>\n    <string name=\"audio_cover_extractor_sub\">Atera albumen azaleko irudiak audio fitxategietatik, formatu ohikoenak onartzen dira</string>\n    <string name=\"pick_audio_to_start\">Hautatu audioa hasteko</string>\n    <string name=\"pick_audio\">Aukeratu Audioa</string>\n    <string name=\"no_covers_found\">Ez da azala aurkitu</string>\n    <string name=\"send_logs\">Bidali erregistroak</string>\n    <string name=\"send_logs_sub\">Egin klik aplikazioaren erregistro-fitxategia partekatzeko, honek arazoa antzematen eta arazoak konpontzen lagunduko dit</string>\n    <string name=\"crash_title\">Aupa… Arazoren bat izan da</string>\n    <string name=\"crash_subtitle\">Nirekin harremanetan jar zaitezke beheko aukeren bidez eta irtenbidea bilatzen saiatuko naiz.\\n(Ez ahaztu erregistroak eranstea)</string>\n    <string name=\"ocr_write_to_file\">Idatzi fitxategira</string>\n    <string name=\"ocr_write_to_file_sub\">Atera testua irudi sortatik eta gorde testu fitxategi bakarrean</string>\n    <string name=\"ocr_write_to_metadata\">Idatzi metadatuetara</string>\n    <string name=\"ocr_write_to_metadata_sub\">Atera testua irudi bakoitzetik eta jarri argazki erlatiboen EXIF ​​informazioan</string>\n    <string name=\"invisible_mode\">Modu Ikusezina</string>\n    <string name=\"invisible_mode_sub\">Erabili esteganografia begi-markak ikusezinak sortzeko zure irudien byteen barruan</string>\n    <string name=\"use_lsb\">Erabili LSB</string>\n    <string name=\"use_lsb_sub\">LSB (Less Significant Bit) esteganografia metodoa erabiliko da, FD (Frequency Domain) bestela</string>\n    <string name=\"auto_remove_red_eyes\">Kendu begi gorriak automatikoki</string>\n    <string name=\"password\">Pasahitza</string>\n    <string name=\"unlock\">Desblokeatu</string>\n    <string name=\"pdf_is_protected\">PDF babestuta dago</string>\n    <string name=\"operation_almost_complete\">Eragiketa ia amaituta. Orain bertan behera uzteko, berrabiarazi beharko da</string>\n    <string name=\"sort_by_date_modified\">Aldaketa data</string>\n    <string name=\"sort_by_date_modified_reversed\">Aldaketa data (alderantziztua)</string>\n    <string name=\"sort_by_size\">Tamaina</string>\n    <string name=\"sort_by_size_reversed\">Tamaina (alderantzizkatua)</string>\n    <string name=\"sort_by_mime_type\">MIME mota</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME mota (alderantzikatua)</string>\n    <string name=\"sort_by_extension\">Luzapena</string>\n    <string name=\"sort_by_extension_reversed\">Luzapena (alderantzikatua)</string>\n    <string name=\"sort_by_date_added\">Gehitutako data</string>\n    <string name=\"sort_by_date_added_reversed\">Gehitutako data (alderantzikatua)</string>\n    <string name=\"left_to_right\">Ezkerretik Eskuinera</string>\n    <string name=\"right_to_left\">Eskuinetik Ezkerrera</string>\n    <string name=\"top_to_bottom\">Goitik Behetik</string>\n    <string name=\"bottom_to_top\">Behetik gora</string>\n    <string name=\"liquid_glass\">Beira likidoa</string>\n    <string name=\"liquid_glass_sub\">Duela gutxi iragarritako IOS 26an eta haren beira likidoaren diseinu sisteman oinarritutako etengailua</string>\n    <string name=\"pick_image_or_base64\">Aukeratu irudia edo itsatsi/inportatu Base64 datuak behean</string>\n    <string name=\"type_image_link\">Idatzi irudiaren esteka hasteko</string>\n    <string name=\"paste_link\">Itsatsi esteka</string>\n    <string name=\"kaleidoscope\">Kaleidoskopioa</string>\n    <string name=\"secondary_angle\">Bigarren mailako angelua</string>\n    <string name=\"sides\">Aldeak</string>\n    <string name=\"channel_mix\">Channel Mix</string>\n    <string name=\"blue_green\">Berde urdina</string>\n    <string name=\"red_blue\">Gorria urdina</string>\n    <string name=\"green_red\">Berde gorria</string>\n    <string name=\"into_red\">Gorri sartu</string>\n    <string name=\"into_green\">Berdean sartu</string>\n    <string name=\"into_blue\">Urdinera</string>\n    <string name=\"cyan\">Zian</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Horia</string>\n    <string name=\"color_halftone\">Kolore-tonu erdia</string>\n    <string name=\"contour\">Ingerada</string>\n    <string name=\"levels\">Mailak</string>\n    <string name=\"offset\">Desplazamendua</string>\n    <string name=\"voronoi_crystallize\">Voronoi Kristalizatu</string>\n    <string name=\"shape\">Forma</string>\n    <string name=\"stretch\">Luzatu</string>\n    <string name=\"randomness\">Ausazkotasuna</string>\n    <string name=\"despeckle\">Desitxuratu</string>\n    <string name=\"diffuse\">Zabaldua</string>\n    <string name=\"dog\">Txakurra</string>\n    <string name=\"second_radius\">Bigarren erradioa</string>\n    <string name=\"equalize\">Berdindu</string>\n    <string name=\"glow\">Distira</string>\n    <string name=\"whirl_and_pinch\">Zurrunbiloa eta Pintxa</string>\n    <string name=\"pointillize\">Puntillatu</string>\n    <string name=\"border_color\">Ertzaren kolorea</string>\n    <string name=\"polar_coordinates\">Koordenatu polarrak</string>\n    <string name=\"rect_to_polar\">Zuzena polarrera</string>\n    <string name=\"polar_to_rect\">Polarra zuzenera</string>\n    <string name=\"invert_in_circle\">Inbertitu zirkuluan</string>\n    <string name=\"reduce_noise\">Murriztu Zarata</string>\n    <string name=\"simple_solarize\">Solarize sinplea</string>\n    <string name=\"weave\">Ehundu</string>\n    <string name=\"x_gap\">X Hutsunea</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X Zabalera</string>\n    <string name=\"y_wdth\">Y Zabalera</string>\n    <string name=\"twirl\">Biraka</string>\n    <string name=\"rubber_stmp\">Gomazko zigilua</string>\n    <string name=\"smear\">Lohitu</string>\n    <string name=\"density\">Dentsitatea</string>\n    <string name=\"mix\">Nahastu</string>\n    <string name=\"sphere_lensh_distortion\">Esfera lentearen distortsioa</string>\n    <string name=\"refraction_index\">Errefrakzio-indizea</string>\n    <string name=\"arc\">Arkua</string>\n    <string name=\"spread_angle\">Zabaltzeko angelua</string>\n    <string name=\"sparkle\">Distira</string>\n    <string name=\"rays\">Izpiak</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradientea</string>\n    <string name=\"moire\">Maria</string>\n    <string name=\"autumn\">Udazkena</string>\n    <string name=\"bone\">Hezurra</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Negua</string>\n    <string name=\"ocean\">Ozeanoa</string>\n    <string name=\"summer\">Uda</string>\n    <string name=\"spring\">Udaberria</string>\n    <string name=\"cool_variant\">Cool Aldaera</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Arrosa</string>\n    <string name=\"hot\">Beroa</string>\n    <string name=\"parula\">Hitza</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Infernua</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Herritarrak</string>\n    <string name=\"twilight\">Ilunabarra</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspektiba Auto</string>\n    <string name=\"deskew\">Okertu</string>\n    <string name=\"allow_crop\">Moztu baimendu</string>\n    <string name=\"crop_or_perspective\">Mozketa edo Perspektiba</string>\n    <string name=\"absolute\">Absolutua</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Berde sakona</string>\n    <string name=\"lens_correction\">Lenteen zuzenketa</string>\n    <string name=\"target_lens_profile\">Helburuko lentearen profil fitxategia JSON formatuan</string>\n    <string name=\"download_ready_lens_profiles\">Deskargatu prest dauden lenteen profilak</string>\n    <string name=\"part_percents\">Zatiaren ehunekoak</string>\n    <string name=\"export_as_json\">Esportatu JSON gisa</string>\n    <string name=\"export_as_json_sub\">Kopiatu katea paleta-datu batekin json irudikapen gisa</string>\n    <string name=\"seam_carving\">Jostura Taila</string>\n    <string name=\"home_screen\">Hasierako pantaila</string>\n    <string name=\"lock_screen\">Blokeatu pantaila</string>\n    <string name=\"built_in\">Eraikituta</string>\n    <string name=\"wallpapers_export\">Horma-irudiak esportatu</string>\n    <string name=\"refresh\">Freskatu</string>\n    <string name=\"wallpapers_export_sub\">Lortu uneko hasierako, blokeoa eta horma-irudi integratuak</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Baimendu fitxategi guztietarako sarbidea, hau beharrezkoa da horma-paperak berreskuratzeko</string>\n    <string name=\"allow_read_media_images_for_wp\">Kudeatu kanpoko biltegiratze-baimena ez da nahikoa, zure irudietarako sarbidea baimendu behar duzu, ziurtatu  \\\"Baimendu guztiak \\\" hautatu duzula</string>\n    <string name=\"add_preset_to_filename\">Gehitu aurrezarpena fitxategi-izenari</string>\n    <string name=\"add_preset_to_filename_sub\">Hautatutako aurrezartutako atzizkia eransten dio irudi-fitxategiaren izenari</string>\n    <string name=\"add_image_scale_mode_to_filename\">Gehitu irudien eskala modua fitxategi-izenari</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Hautatutako irudien eskala moduarekin atzizkia eransten dio irudi-fitxategiaren izenari</string>\n    <string name=\"ascii_art\">Ascii art</string>\n    <string name=\"ascii_art_sub\">Bihurtu irudia irudiaren itxura izango duen ascii testura</string>\n    <string name=\"params\">Parametroak</string>\n    <string name=\"invert_colors_ascii_sub\">Irudiari iragazki negatiboa aplikatzen dio emaitza hobeak lortzeko, kasu batzuetan</string>\n    <string name=\"processing_screenshot\">Pantaila-argazkia prozesatzen</string>\n    <string name=\"screenshot_not_captured_try_again\">Ez da pantaila-argazkia atera, saiatu berriro</string>\n    <string name=\"skipped_saving\">Saltatu da gordetzea</string>\n    <string name=\"skipped_saving_multiple\">%1$s fitxategi saltatu dira</string>\n    <string name=\"allow_skip_if_larger\">Baimendu Saltatu handiagoa bada</string>\n    <string name=\"allow_skip_if_larger_sub\">Tresna batzuek irudiak gordetzeari uzteko baimena izango dute, ondoriozko fitxategiaren tamaina jatorrizkoa baino handiagoa bada</string>\n    <string name=\"qr_type_calendar_event\">Egutegiko Gertaera</string>\n    <string name=\"qr_type_contact_info\">Harremanetan jarri</string>\n    <string name=\"qr_type_email\">Posta elektronikoa</string>\n    <string name=\"qr_type_geo_point\">Kokapena</string>\n    <string name=\"qr_type_phone\">Telefonoa</string>\n    <string name=\"qr_type_plain\">Testua</string>\n    <string name=\"qr_type_sms\">SMSak</string>\n    <string name=\"qr_type_url\">URLa</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Sare irekia</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefonoa</string>\n    <string name=\"message\">Mezua</string>\n    <string name=\"address\">Helbidea</string>\n    <string name=\"subject\">Gaia</string>\n    <string name=\"body\">Gorputza</string>\n    <string name=\"name\">Izena</string>\n    <string name=\"organization\">Antolaketa</string>\n    <string name=\"title\">Izenburua</string>\n    <string name=\"phones\">Telefonoak</string>\n    <string name=\"emails\">Posta elektronikoak</string>\n    <string name=\"urls\">URLak</string>\n    <string name=\"addresses\">Helbideak</string>\n    <string name=\"summary\">Laburpena</string>\n    <string name=\"description\">Deskribapena</string>\n    <string name=\"location\">Kokapena</string>\n    <string name=\"organizer\">Antolatzailea</string>\n    <string name=\"start_date\">Hasiera data</string>\n    <string name=\"end_date\">Amaiera data</string>\n    <string name=\"status\">Egoera</string>\n    <string name=\"latitude\">Latitudea</string>\n    <string name=\"longitude\">Luzera</string>\n    <string name=\"create_barcode\">Sortu barra-kodea</string>\n    <string name=\"edit_barcode\">Editatu barra-kodea</string>\n    <string name=\"wifi_configuration\">Wi-Fi konfigurazioa</string>\n    <string name=\"security\">Segurtasuna</string>\n    <string name=\"pick_contact\">Aukeratu kontaktua</string>\n    <string name=\"grant_contact_permission\">Eman kontaktuei ezarpenetan aukeratutako kontaktua erabiliz automatikoki betetzeko baimena</string>\n    <string name=\"contact_info\">Harremanetarako informazioa</string>\n    <string name=\"first_name\">Izena</string>\n    <string name=\"middle_name\">Erdiko izena</string>\n    <string name=\"last_name\">Abizena</string>\n    <string name=\"pronunciation\">Ahoskera</string>\n    <string name=\"add_phone\">Gehitu telefonoa</string>\n    <string name=\"add_email\">Gehitu posta elektronikoa</string>\n    <string name=\"add_address\">Gehitu helbidea</string>\n    <string name=\"website\">Webgunea</string>\n    <string name=\"add_website\">Gehitu webgunea</string>\n    <string name=\"formatted_name\">Formateatutako izena</string>\n    <string name=\"qr_code_top_image\">Irudi hau barra-kodearen gainean jartzeko erabiliko da</string>\n    <string name=\"code_customization\">Kodeen pertsonalizazioa</string>\n    <string name=\"qr_logo_image\">Irudi hau QR kodearen erdian logotipo gisa erabiliko da</string>\n    <string name=\"logo\">Logotipoa</string>\n    <string name=\"logo_padding\">Logo betegarria</string>\n    <string name=\"logo_size\">Logotipoaren tamaina</string>\n    <string name=\"logo_corners\">Logoaren txokoak</string>\n    <string name=\"fourth_eye\">Laugarren begia</string>\n    <string name=\"fourth_eye_description\">Begiaren simetria gehitzen dio qr kodeari laugarren begia gehituz beheko muturrean</string>\n    <string name=\"pixel_shape\">Pixel forma</string>\n    <string name=\"frame_shape\">Markoaren forma</string>\n    <string name=\"ball_shape\">Pilota forma</string>\n    <string name=\"error_correction_level\">Erroreak zuzentzeko maila</string>\n    <string name=\"dark_color\">Kolore iluna</string>\n    <string name=\"light_color\">Kolore argia</string>\n    <string name=\"hyper_os\">Hiper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS bezalako estiloa</string>\n    <string name=\"mask_pattern\">Maskararen eredua</string>\n    <string name=\"code_may_be_not_scannable\">Baliteke kode hau eskaneatu ezin izatea, aldatu itxura-parametroak gailu guztiekin irakurtzeko</string>\n    <string name=\"not_scannable\">Ezin da eskaneatu</string>\n    <string name=\"launcher_mode_sub\">Tresnek hasierako pantailako aplikazioen abiarazlearen itxura izango dute trinkoagoa izateko</string>\n    <string name=\"launcher_mode\">Abiarazle modua</string>\n    <string name=\"flood_fill_sub\">Aukeratutako pintzelarekin eta estiloarekin eremu bat betetzen du</string>\n    <string name=\"flood_fill\">Uholde betetzea</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Graffity estiloko bidea marrazten du</string>\n    <string name=\"square_particles\">Partikula karratuak</string>\n    <string name=\"square_particles_sub\">Spray partikulak zirkuluen ordez karratu formakoak izango dira</string>\n    <string name=\"palette_tools\">Paleta tresnak</string>\n    <string name=\"palette_tools_sub\">Sortu paleta duzun oinarrizko/materiala iruditik, edo inportatu/esportatu paleta formatu ezberdinetan</string>\n    <string name=\"edit_palette\">Editatu paleta</string>\n    <string name=\"edit_palette_sub\">Esportatu/inportatu paleta hainbat formatutan</string>\n    <string name=\"color_name\">Kolorearen izena</string>\n    <string name=\"palette_name\">Paletaren izena</string>\n    <string name=\"palette_format\">Paleta formatua</string>\n    <string name=\"export_palette_sub\">Esportatu sortutako paleta formatu desberdinetara</string>\n    <string name=\"add_color_palette_sub\">Kolore berria gehitzen dio uneko paletari</string>\n    <string name=\"palette_name_not_supported\">%1$s formatuak ez du onartzen paleta izena ematea</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store-ren gidalerroak direla eta, eginbide hau ezin da uneko bertsioan sartu. Funtzionalitate honetara sartzeko, deskargatu ImageToolbox iturri alternatibo batetik. GitHub-en dauden eraikuntzak aurki ditzakezu behean.</string>\n    <string name=\"open_github_page\">Ireki Github orria</string>\n    <string name=\"overwrite_files_sub_short\">Jatorrizko fitxategia beste batekin ordezkatuko da hautatutako karpetan gorde beharrean</string>\n    <string name=\"hidden_watermark_text_detected\">Ezkutuko ur-markaren testua detektatu da</string>\n    <string name=\"hidden_watermark_image_detected\">Ezkutuko ur-markaren irudia detektatu da</string>\n    <string name=\"this_image_was_hidden\">Irudi hau ezkutatuta zegoen</string>\n    <string name=\"generative_inpaint\">Inpainting generatiboa</string>\n    <string name=\"generative_inpaint_sub\">Irudi bateko objektuak AI eredu bat erabiliz kentzeko aukera ematen du, OpenCV-n fidatu gabe. Eginbide hau erabiltzeko, aplikazioak behar den eredua (~200 MB) deskargatuko du GitHub-etik</string>\n    <string name=\"generative_inpaint_ready_sub\">Irudi bateko objektuak AI eredu bat erabiliz kentzeko aukera ematen du, OpenCV-n fidatu gabe. Eragiketa luzea izan daiteke</string>\n    <string name=\"error_level_analysis\">Errore-mailaren analisia</string>\n    <string name=\"luminance_gradient\">Luminantza Gradientea</string>\n    <string name=\"average_distance\">Batez besteko Distantzia</string>\n    <string name=\"copy_move_detection\">Kopiatu Mugimendu detekzioa</string>\n    <string name=\"retain\">Atxiki</string>\n    <string name=\"coefficent\">Koefizientea</string>\n    <string name=\"clipboard_data_is_too_large\">Arbeleko datuak handiegiak dira</string>\n    <string name=\"data_is_too_large_to_copy\">Datuak handiegiak dira kopiatzeko</string>\n    <string name=\"simple_weave_pixelization\">Ehundura sinplearen pixelizazioa</string>\n    <string name=\"staggered_pixelization\">Pixelizazio mailakatua</string>\n    <string name=\"cross_pixelization\">Pixelizazio gurutzatua</string>\n    <string name=\"micro_macro_pixelization\">Mikro makro pixelizazioa</string>\n    <string name=\"orbital_pixelization\">Pixelizazio orbitala</string>\n    <string name=\"vortex_pixelization\">Zurrunbiloen pixelizazioa</string>\n    <string name=\"pulse_grid_pixelization\">Pultsu-sarearen pixelizazioa</string>\n    <string name=\"nucleus_pixelization\">Nukleoaren pixelizazioa</string>\n    <string name=\"radial_weave_pixelization\">Ehun erradiala pixelizazioa</string>\n    <string name=\"cannot_open_uri\">Ezin da ireki uri  \\\"%1$s \\\"</string>\n    <string name=\"snowfall_mode\">Elurra modua</string>\n    <string name=\"enabled\">Gaituta</string>\n    <string name=\"border_frame\">Ertzaren markoa</string>\n    <string name=\"glitch_variant\">Glitch aldaera</string>\n    <string name=\"channel_shift\">Kanal-aldaketa</string>\n    <string name=\"max_offset\">Desplazamendu maximoa</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blokeatu Glitch</string>\n    <string name=\"block_size\">Blokearen tamaina</string>\n    <string name=\"crt_curvature\">CRT kurbadura</string>\n    <string name=\"curvature\">Kurbadura</string>\n    <string name=\"chroma\">Kroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Gehienezko tantoa</string>\n    <string name=\"ai_tools\">AI tresnak</string>\n    <string name=\"ai_tools_sub\">Hainbat tresna irudiak prozesatzeko ai ereduen bidez, hala nola artefaktuak kentzea edo denoising</string>\n    <string name=\"model_anime_undeint\">Konpresioa, lerro bitxiak</string>\n    <string name=\"model_broadcast\">Marrazki bizidunak, emisio-konpresioa</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Konpresio orokorra, zarata orokorra</string>\n    <string name=\"model_wb_denoise\">Kolorerik gabeko marrazki bizidunen zarata</string>\n    <string name=\"model_span_anime_pretrain\">Azkar, konpresio orokorra, zarata orokorra, animazioa/komikiak/anime</string>\n    <string name=\"model_book_scan\">Liburuen eskaneatzea</string>\n    <string name=\"model_overexposure\">Esposizioaren zuzenketa</string>\n    <string name=\"model_fbcnn_color_fp16\">Konpresio orokorrean onena, koloretako irudietan</string>\n    <string name=\"model_fbcnn_gray_fp16\">Onena konpresio orokorrean, gris-eskalako irudietan</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Konpresio orokorra, gris-eskalako irudiak, indartsuagoak</string>\n    <string name=\"model_scunet_color_gan_fp16\">Zarata orokorra, koloretako irudiak</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Zarata orokorra, koloretako irudiak, xehetasun hobeak</string>\n    <string name=\"model_scunet_gray_15_fp16\">Zarata orokorra, gris-eskalako irudiak</string>\n    <string name=\"model_scunet_gray_25_fp16\">Zarata orokorra, gris-eskalako irudiak, indartsuagoak</string>\n    <string name=\"model_scunet_gray_50_fp16\">Zarata orokorra, gris-eskalako irudiak, indartsuena</string>\n    <string name=\"model_jpeg_destroyer\">Konpresio orokorra</string>\n    <string name=\"model_jaywreck\">Konpresio orokorra</string>\n    <string name=\"model_h264\">Testurizazioa, h264 konpresioa</string>\n    <string name=\"model_vhs\">VHS konpresioa</string>\n    <string name=\"model_cinepak\">Konpresio ez estandarra (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink konpresioa, geometrian hobea</string>\n    <string name=\"model_debink_v5\">Bink konpresioa, indartsuagoa</string>\n    <string name=\"model_debink_v6\">Bink konpresioa, biguna, xehetasunak mantentzen ditu</string>\n    <string name=\"model_antialias\">Eskailera-urrats efektua kentzea, leuntzea</string>\n    <string name=\"model_kdm_scans\">Eskaneatutako artea/marrazkiak, konpresio leuna, moire</string>\n    <string name=\"model_bandage\">Kolore-bandak</string>\n    <string name=\"model_halftone\">Astiro, tonu erdiak kenduz</string>\n    <string name=\"model_colorizer\">Grisen eskala/bw irudietarako koloreztatzaile orokorra, emaitza hobeak lortzeko erabili DDColor</string>\n    <string name=\"model_deedge\">Ertzak kentzea</string>\n    <string name=\"model_desharpen\">Gehiegizko zorroztasuna kentzen du</string>\n    <string name=\"model_dither\">Astiro, dithering</string>\n    <string name=\"model_gainres\">Aliasaren aurkakoa, artefaktu orokorrak, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003-k aztertzen du prozesatzea</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Irudia hobetzeko eredu arina</string>\n    <string name=\"model_bcgone_detailed_v2\">Konpresioaren artefaktuak kentzea</string>\n    <string name=\"model_bcgone_smooth\">Konpresioaren artefaktuak kentzea</string>\n    <string name=\"model_bandage_smooth\">Benda kentzea emaitza leunekin</string>\n    <string name=\"model_bendel_halftone\">Tonu erdiko ereduen prozesamendua</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Dither eredua kentzea V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG artefaktuak kentzea V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 ehundura hobetzea</string>\n    <string name=\"model_vhs_sharpen\">VHS zorroztu eta hobetzea</string>\n    <string name=\"merging\">Batzea</string>\n    <string name=\"chunk_size\">Zatiaren tamaina</string>\n    <string name=\"overlap_size\">Gainjartze Tamaina</string>\n    <string name=\"note_chunk_info\">%1$s px-tik gorako irudiak zatika zatikatu eta prozesatu egingo dira, gainjarriz nahasten dira josturak ikus daitezkeen saihesteko.</string>\n    <string name=\"large_chunk_warning\">Tamaina handiek ezegonkortasuna sor dezakete gama baxuko gailuekin</string>\n    <string name=\"select_one_to_start\">Hautatu bat hasteko</string>\n    <string name=\"delete_model_sub\">%1$s eredua ezabatu nahi duzu? Berriro deskargatu beharko duzu</string>\n    <string name=\"confirm\">Berretsi</string>\n    <string name=\"models\">Ereduak</string>\n    <string name=\"downloaded_models\">Deskargatutako ereduak</string>\n    <string name=\"available_models\">Eskuragarri dauden ereduak</string>\n    <string name=\"preparing\">Prestatzen</string>\n    <string name=\"active_model\">Eredu aktiboa</string>\n    <string name=\"failed_to_open_session\">Ezin izan da saioa ireki</string>\n    <string name=\"only_onnx_models\">.onnx/.ort ereduak soilik inporta daitezke</string>\n    <string name=\"import_model\">Inportazio eredua</string>\n    <string name=\"import_model_sub\">Inportatu onnx eredu pertsonalizatua gehiago erabiltzeko, onnx/ort ereduak bakarrik onartzen dira, esrgan bezalako aldaera ia guztiak onartzen ditu</string>\n    <string name=\"imported_models\">Inportatutako ereduak</string>\n    <string name=\"model_scunet_color_15_fp16\">Zarata orokorra, koloretako irudiak</string>\n    <string name=\"model_scunet_color_25_fp16\">Zarata orokorra, koloretako irudiak, indartsuagoak</string>\n    <string name=\"model_scunet_color_50_fp16\">Zarata orokorra, koloretako irudiak, indartsuena</string>\n    <string name=\"model_artifacts_dithering_alsa\">Dithering artefaktuak eta kolore-bandak murrizten ditu, gradiente leunak eta kolore-eremu lauak hobetuz.</string>\n    <string name=\"model_nmkd_brighten_redux\">Irudiaren distira eta kontrastea hobetzen ditu distira orekatuekin, kolore naturalak mantenduz.</string>\n    <string name=\"model_nmkd_brighten\">Irudi ilunak argitzen ditu xehetasunak mantenduz eta gehiegizko esposizioa saihestuz.</string>\n    <string name=\"model_nmkd_detoon\">Gehiegizko kolore-tonua kentzen du eta kolore oreka neutralagoa eta naturalagoa berreskuratzen du.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Poisson-en oinarritutako zarata-tonua aplikatzen du, xehetasun eta ehundura finak zaintzean arreta jarriz.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Poisson zarata-tonu leuna aplikatzen du, ikusmen emaitza leunagoak eta ez hain oldarkorrak lortzeko.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Zarata-tonu uniformea ​​xehetasunen kontserbazioan eta irudiaren argitasunean zentratua.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Zarata tonu uniforme leuna, ehundura sotila eta itxura leuna lortzeko.</string>\n    <string name=\"model_repainter\">Kaltetutako edo irregularrak diren eremuak konpontzen ditu artefaktuak berriro margotuz eta irudiaren koherentzia hobetuz.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Debanding eredu arina, kolore-bandak kentzen dituena, errendimendu kostu minimoarekin.</string>\n    <string name=\"model_jpeg_0_20\">Konpresio artefaktu oso altuak dituzten irudiak optimizatzen ditu (% 0-20ko kalitatea) argitasuna hobetzeko.</string>\n    <string name=\"model_jpeg_20_40\">Irudiak hobetzen ditu konpresio handiko artefaktuekin (% 20-40ko kalitatea), xehetasunak leheneratzen eta zarata murriztuz.</string>\n    <string name=\"model_jpeg_40_60\">Irudiak hobetzen ditu konpresio moderatua (% 40-60 kalitatea), zorroztasuna eta leuntasuna orekatuz.</string>\n    <string name=\"model_jpeg_60_80\">Irudiak konpresio argiarekin (% 60-80 kalitatea) hobetzen ditu xehetasun eta ehundura sotilak hobetzeko.</string>\n    <string name=\"model_jpeg_80_100\">Ia galerarik gabeko irudiak apur bat hobetzen ditu (% 80-100eko kalitatea), itxura eta xehetasun naturalak mantenduz.</string>\n    <string name=\"model_spongecolor_lite\">Kolorizazio sinple eta azkarra, marrazki bizidunak, ez da ideala</string>\n    <string name=\"model_deblr\">Irudiaren lausotasuna apur bat murrizten du, zorroztasuna hobetuz artefaktuak sartu gabe.</string>\n    <string name=\"processing_channel\">Ibilbide luzeko eragiketak</string>\n    <string name=\"processing_image\">Irudia prozesatzea</string>\n    <string name=\"processing\">Tramitazioa</string>\n    <string name=\"model_artifacts_jpg_0_20\">JPEG konpresio-artefaktu handiak kentzen ditu kalitate baxuko irudietan (% 0-20).</string>\n    <string name=\"model_artifacts_jpg_20_40\">JPEG artefaktu indartsuak murrizten ditu oso konprimitutako irudietan (% 20-40).</string>\n    <string name=\"model_artifacts_jpg_40_60\">JPEG artefaktu moderatuak garbitzen ditu, irudiaren xehetasunak (% 40-60) gordetzen dituen bitartean.</string>\n    <string name=\"model_artifacts_jpg_60_80\">JPEG artefaktu argiak hobetzen ditu kalitate handiko irudietan (% 60-80).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Ia galerarik gabeko irudietan JPEG artefaktu txikiak murrizten ditu (% 80-100).</string>\n    <string name=\"model_redetail_v2\">Xehetasun eta ehundura finak hobetzen ditu, artefaktu astunik gabe hautemandako zorroztasuna hobetuz.</string>\n    <string name=\"processing_finished\">Prozesatzea amaitu da</string>\n    <string name=\"processing_failed\">Ezin izan da prozesatu</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Azalaren ehundura eta xehetasunak hobetzen ditu, itxura naturala mantenduz, abiadurarako optimizatuta.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG konpresioaren artefaktuak kentzen ditu eta konprimitutako argazkien irudiaren kalitatea berrezartzen du.</string>\n    <string name=\"model_iso_denoise_v1\">ISO zarata murrizten du argi gutxiko baldintzetan ateratako argazkietan, xehetasunak gordez.</string>\n    <string name=\"model_dejumbo\">Gehiegizko esposizioak edo \\\"jumbo\\\" nabarmenak zuzentzen ditu eta tonu-oreka hobea berreskuratzen du.</string>\n    <string name=\"model_ddcolor_tiny\">Kolore-eredu arina eta azkarra gris-eskalako irudiei kolore naturalak gehitzen dizkiena.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Koloreztatu</string>\n    <string name=\"type_artifacts\">Artefaktuak</string>\n    <string name=\"type_enhance\">Hobetu</string>\n    <string name=\"type_anime\">Animea</string>\n    <string name=\"type_scans\">Eskaneatzea</string>\n    <string name=\"type_upscale\">Goi mailakoa</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler irudi orokorretarako; GPU eta denbora gutxiago erabiltzen dituen modelo txiki-txikia, lausotze eta desnoise moderatuak dituena.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler irudi orokorretarako, testurak eta xehetasun naturalak gordez.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 upscaler irudi orokorretarako testura hobetuekin eta emaitza errealistekin.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler anime irudietarako optimizatua; 6 RRDB bloke lerro eta xehetasun zorrotzagoetarako.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 upscaler MSE galerarekin, emaitza leunagoak eta artefaktu murriztuak sortzen ditu irudi orokorretarako.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler anime irudietarako optimizatua; 4B32F aldaera xehetasun zorrotzagoekin eta lerro leunekin.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 eredua irudi orokorretarako; zorroztasuna eta argitasuna azpimarratzen ditu.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; azkarrago eta txikiagoa, xehetasunak gordetzen ditu GPU memoria gutxiago erabiliz.</string>\n    <string name=\"model_rmbg_1_4\">Eredu arina atzeko planoa azkar kentzeko. Errendimendu orekatua eta zehaztasuna. Erretratu, objektu eta eszenekin lan egiten du. Erabilera gehienetarako gomendatua.</string>\n    <string name=\"type_removebg\">Kendu BG</string>\n    <string name=\"horizontal_border_thickness\">Ertzaren lodiera horizontala</string>\n    <string name=\"vertical_border_thickness\">Ertz Bertikala Lodiera</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s kolorea</item>\n        <item quantity=\"other\">%1$s koloreak</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Oraingo ereduak ez du zatiketa onartzen, irudia jatorrizko dimentsioetan prozesatu egingo da; horrek memoria-kontsumo handia eta maila baxuko gailuekin arazoak sor ditzake.</string>\n    <string name=\"chunking_disabled\">Zatiketa desgaituta dago, irudia jatorrizko dimentsioetan prozesatuko da; horrek memoria-kontsumo handia eta arazoak sor ditzake gama baxuko gailuekin, baina emaitza hobeak eman ditzake ondorioetan.</string>\n    <string name=\"chunking\">Zatiketa</string>\n    <string name=\"model_u2net\">Zehaztasun handiko irudiak segmentatzeko eredua atzeko planoa kentzeko</string>\n    <string name=\"model_u2netp\">U2Net-en bertsio arina atzeko planoa bizkorrago kentzeko memoria-erabilera txikiagoarekin.</string>\n    <string name=\"model_ddcolor\">DDColor eredu osoak kalitate handiko koloreztatzea eskaintzen du artefaktu minimoekin irudi orokorretarako. Kolorizazio eredu guztien aukerarik onena.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Prestatutako eta datu artistiko pribatuak; Kolore-emaitzak anitz eta artistikoak sortzen ditu, kolore-artefaktu irrealista gutxiagorekin.</string>\n    <string name=\"model_birefnet\">Swin Transformer-en oinarritutako BiRefNet eredu arina atzeko planoa zehatz kentzeko.</string>\n    <string name=\"model_inspyrenet\">Kalitate handiko atzeko planoa kentzea ertz zorrotzekin eta xehetasunen kontserbazio bikainarekin, batez ere objektu konplexuetan eta atzeko plano delikatuenetan.</string>\n    <string name=\"model_isnet\">Atzeko planoa kentzeko eredua, ertz leunekin maskara zehatzak sortzen dituena, objektu orokorretarako egokia eta xehetasun moderatua zaintzeko.</string>\n    <string name=\"model_already_downloaded\">Dagoeneko deskargatu da eredua</string>\n    <string name=\"model_successfully_imported\">Eredua behar bezala inportatu da</string>\n    <string name=\"type\">Mota</string>\n    <string name=\"keyword\">Gakoa</string>\n    <string name=\"very_fast\">Oso azkarra</string>\n    <string name=\"normal\">Normala</string>\n    <string name=\"slow\">Astiro</string>\n    <string name=\"very_slow\">Oso motela</string>\n    <string name=\"compute_percents\">Ehuneko kalkulatu</string>\n    <string name=\"minimum_value_is\">Gutxieneko balioa %1$s da</string>\n    <string name=\"warp_sub\">Desitxuratu irudia hatzekin marraztuz</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">Gogortasuna</string>\n    <string name=\"warp_mode\">Warp modua</string>\n    <string name=\"warp_mode_move\">Mugitu</string>\n    <string name=\"warp_mode_grow\">Hazi</string>\n    <string name=\"warp_mode_shrink\">Txikitu</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Zurrunbiloa CCW</string>\n    <string name=\"fade_strength\">Desagertzeko indarra</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Beheko Tanta</string>\n    <string name=\"start_drop\">Hasi Drop</string>\n    <string name=\"end_drop\">Amaitu Drop</string>\n    <string name=\"downloading\">Deskargatzen</string>\n    <string name=\"smooth_shapes\">Forma leunak</string>\n    <string name=\"smooth_shapes_sub\">Erabili superelipseak laukizuzen biribilduen ordez forma leunagoak eta naturalagoak lortzeko</string>\n    <string name=\"shape_type\">Forma mota</string>\n    <string name=\"cut\">Moztu</string>\n    <string name=\"rounded\">Biribildua</string>\n    <string name=\"smooth\">Leuna</string>\n    <string name=\"cut_shapes_sub\">Ertz zorrotzak biribildu gabe</string>\n    <string name=\"rounded_shapes_sub\">Ertz biribildu klasikoak</string>\n    <string name=\"shapes_type\">Formak Mota</string>\n    <string name=\"corners_size\">Txokoak Tamaina</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">UI elementu biribildu dotoreak</string>\n    <string name=\"filename_format\">Fitxategi-izenen formatua</string>\n    <string name=\"prefix_pattern_description\">Fitxategi-izenaren hasieran jarritako testu pertsonalizatua, ezin hobea proiektuen izenetarako, marketarako edo etiketa pertsonaletarako.</string>\n    <string name=\"original_filename_pattern_description\">Jatorrizko fitxategi-izena luzapenik gabe erabiltzen du, iturriaren identifikazioa osorik mantentzen lagunduko dizu.</string>\n    <string name=\"width_pattern_description\">Irudiaren zabalera pixeletan, erabilgarria bereizmen-aldaketen jarraipena egiteko edo emaitzak eskalatzeko.</string>\n    <string name=\"height_pattern_description\">Irudiaren altuera pixeletan, lagungarria aspektu-erlazioekin edo esportazioekin lan egiteko.</string>\n    <string name=\"random_numbers_pattern_description\">Ausazko zifrak sortzen ditu fitxategi-izen bakarrak bermatzeko; Gehitu zifra gehiago bikoiztuen aurkako segurtasun gehigarrirako.</string>\n    <string name=\"sequence_number_pattern_description\">Loteen esportazioetarako automatikoki gehitzen den kontagailua, saio batean hainbat irudi gordetzeko aproposa.</string>\n    <string name=\"preset_info_pattern_description\">Aplikatutako aurrez ezarritako izena fitxategi-izenean txertatzen du, irudia nola prozesatu zen erraz gogoratu ahal izateko.</string>\n    <string name=\"scale_mode_pattern_description\">Prozesatzean erabilitako irudien eskalatze modua bistaratzen du, tamaina aldatu, moztutako edo egokitutako irudiak bereizten laguntzen du.</string>\n    <string name=\"suffix_pattern_description\">Testu pertsonalizatua fitxategi-izenaren amaieran jartzen da, _v2, _edited edo _final bezalako bertsioak egiteko erabilgarria.</string>\n    <string name=\"extension_pattern_description\">Fitxategiaren luzapena (png, jpg, webp, etab.), automatikoki gordetako benetako formatuarekin bat datorrena.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Denbora-zigilu pertsonalizagarria, zure formatua java zehaztapenen arabera definitzeko aukera ematen dizuna ordenatzeko.</string>\n    <string name=\"fling_type\">Fling mota</string>\n    <string name=\"android_native\">Android natiboa</string>\n    <string name=\"ios_style\">iOS estiloa</string>\n    <string name=\"smooth_curve\">Kurba leuna</string>\n    <string name=\"quick_stop\">Geldialdi azkarra</string>\n    <string name=\"bouncy\">Errebotea</string>\n    <string name=\"floaty\">Flotagarria</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Ultra leuna</string>\n    <string name=\"adaptive\">Egokigarria</string>\n    <string name=\"accessibility_aware\">Irisgarritasuna jakitun</string>\n    <string name=\"reduced_motion\">Mugimendu murriztua</string>\n    <string name=\"android_native_sub\">Native Android korritze fisika oinarrizko alderaketa egiteko</string>\n    <string name=\"smooth_sub\">Erabilera orokorrerako korritze orekatua eta leuna</string>\n    <string name=\"ios_style_sub\">Marruskadura handiagoa iOS-en antzeko korritze portaera</string>\n    <string name=\"smooth_curve_sub\">Spline kurba berezia korritze sentsazio desberdina lortzeko</string>\n    <string name=\"quick_stop_sub\">Mugimendu zehatza geldialdi bizkorrekin</string>\n    <string name=\"bouncy_sub\">Sroll errebote dibertigarria eta sentikorra</string>\n    <string name=\"floaty_sub\">Edukiak arakatzeko korritu luze eta irristagarriak</string>\n    <string name=\"snappy_sub\">Mugimendu azkarra eta sentikorra interfaze interaktiboetarako</string>\n    <string name=\"ultra_smooth_sub\">Premium mugitze leuna, momentu hedatuarekin</string>\n    <string name=\"adaptive_sub\">Fling abiaduran oinarritutako fisika doitzen du</string>\n    <string name=\"accessibility_aware_sub\">Sistemaren irisgarritasun-ezarpenak errespetatzen ditu</string>\n    <string name=\"reduced_motion_sub\">Irisgarritasun-beharretarako mugimendu minimoa</string>\n    <string name=\"primary_lines\">Lehen lerroak</string>\n    <string name=\"primary_lines_sub\">Lerro lodiagoa gehitzen du bosgarren lerroan behin</string>\n    <string name=\"fill_color\">Bete kolorea</string>\n    <string name=\"hidden_tools\">Ezkutuko Tresnak</string>\n    <string name=\"hidden_for_share\">Partekatzeko ezkutatuta dauden tresnak</string>\n    <string name=\"color_library\">Kolore Liburutegia</string>\n    <string name=\"color_library_sub\">Arakatu kolore bilduma zabala</string>\n    <string name=\"model_fatality_deblur\">Irudiak zorrozten eta kentzen ditu xehetasun naturalak mantenduz, fokurik gabeko argazkiak konpontzeko aproposa.</string>\n    <string name=\"model_unresize_v3\">Aurrez tamaina aldatutako irudiak modu adimentsuan leheneratzen ditu, galdutako xehetasunak eta ehundurak berreskuratuz.</string>\n    <string name=\"model_liveaction_v1_span\">Zuzeneko ekintzako edukietarako optimizatuta, konpresio-artefaktuak murrizten ditu eta xehetasun finak hobetzen ditu pelikula/telebistako saioen fotogrametan.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS kalitateko metrajeak HD bihurtzen ditu, zintaren zarata kenduz eta bereizmena hobetuz, vintage kutsua mantenduz.</string>\n    <string name=\"model_text2hd_v1\">Testu handiko irudi eta pantaila-argazkietarako espezializatua, karaktereak zorrozten ditu eta irakurgarritasuna hobetzen du.</string>\n    <string name=\"model_frankendata_pretrainer\">Datu-multzo ezberdinetan trebatutako igoera aurreratua, helburu orokorreko argazkiak hobetzeko bikaina.</string>\n    <string name=\"model_realwebphoto_v2\">Web-konprimitutako argazkietarako optimizatua, JPEG artefaktuak kentzen ditu eta itxura naturala berreskuratzen du.</string>\n    <string name=\"model_realwebphoto_v4\">Web-argazkietarako bertsio hobetua, testura hobeto kontserbatzeko eta artefaktuak murrizteko.</string>\n    <string name=\"model_dat_2x\">Dual Aggregation Transformer teknologiarekin 2 aldiz eskalatzea, zorroztasuna eta xehetasun naturalak mantentzen ditu.</string>\n    <string name=\"model_dat_3x\">3 aldiz eskalatzea transformadoreen arkitektura aurreratua erabiliz, handitze neurrizko beharretarako aproposa.</string>\n    <string name=\"model_dat_4x\">Kalitate handiko 4 aldiz eskalatzea punta-puntako transformadore-sarearekin, xehetasun finak gordetzen ditu eskala handiagoetan.</string>\n    <string name=\"model_nafnet_deblurring\">Argazkietatik lausotasuna/zarata eta dardarak kentzen ditu. Helburu orokorra baina onena argazkietan.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Kalitate baxuko irudiak leheneratzen ditu Swin2SR transformagailua erabiliz, BSRGAN degradaziorako optimizatuta. Konpresio-artefaktu astunak konpontzeko eta xehetasunak 4x eskalan hobetzeko bikaina.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x igoera BSRGAN degradazioan trebatutako SwinIR transformadorearekin. GAN erabiltzen du testura zorrotzagoak eta xehetasun naturalagoak lortzeko argazkietan eta eszena konplexuetan.</string>\n    <string name=\"path\">Bidea</string>\n    <string name=\"merge_pdf\">Batu PDFa</string>\n    <string name=\"merge_pdf_sub\">Konbinatu hainbat PDF fitxategi dokumentu batean</string>\n    <string name=\"files_order\">Fitxategien ordena</string>\n    <string name=\"pages_short\">orr.</string>\n    <string name=\"split_pdf\">Zatitu PDFa</string>\n    <string name=\"split_pdf_sub\">Atera orri zehatzak PDF dokumentutik</string>\n    <string name=\"rotate_pdf\">Biratu PDFa</string>\n    <string name=\"rotate_pdf_sub\">Konpondu orriaren orientazioa betirako</string>\n    <string name=\"pages\">Orriak</string>\n    <string name=\"rearrange_pdf\">Berrantolatu PDFa</string>\n    <string name=\"rearrange_pdf_sub\">Arrastatu eta jaregin orriak ordenatzeko</string>\n    <string name=\"hold_drag_drop\">Eutsi eta arrastatu orriak</string>\n    <string name=\"page_numbers\">Orrialde Zenbakiak</string>\n    <string name=\"page_numbers_sub\">Gehitu zenbakiak zure dokumentuei automatikoki</string>\n    <string name=\"label_format\">Etiketa formatua</string>\n    <string name=\"pdf_to_text\">PDF testura (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Atera testu arrunta zure PDF dokumentuetatik</string>\n    <string name=\"watermark_pdf_sub\">Testu pertsonalizatua gainjarri marka edo segurtasunerako</string>\n    <string name=\"signature\">Sinadura</string>\n    <string name=\"signature_sub\">Gehitu zure sinadura elektronikoa edozein dokumentutan</string>\n    <string name=\"will_be_for_signature\">Hau sinadura gisa erabiliko da</string>\n    <string name=\"unlock_pdf\">Desblokeatu PDFa</string>\n    <string name=\"unlock_pdf_sub\">Kendu pasahitzak babestutako fitxategietatik</string>\n    <string name=\"protect_pdf\">Babestu PDFa</string>\n    <string name=\"protect_pdf_sub\">Babestu zure dokumentuak enkriptazio sendoarekin</string>\n    <string name=\"success\">Arrakasta</string>\n    <string name=\"pdf_unlocked\">PDF desblokeatua, gorde edo parteka dezakezu</string>\n    <string name=\"repair_pdf\">PDFa konpondu</string>\n    <string name=\"repair_pdf_sub\">Saiatu hondatuta dauden edo irakurezinak diren dokumentuak konpontzen</string>\n    <string name=\"grayscale\">Grisen eskala</string>\n    <string name=\"grayscale_pdf_sub\">Bihurtu dokumentu txertatutako irudi guztiak gris-eskalara</string>\n    <string name=\"compress_pdf\">Konprimitu PDFa</string>\n    <string name=\"compress_pdf_sub\">Optimizatu zure dokumentu-fitxategiaren tamaina errazago partekatzeko</string>\n    <string name=\"repair_info\">ImageToolbox-ek barne-erreferentzia gurutzatuen taula berreraikitzen du eta fitxategi-egitura hutsetik birsortzen du. Honek \\\\\"ireki ezin diren\\\\\" fitxategi askotarako sarbidea berrezarri dezake</string>\n    <string name=\"grayscale_info\">Tresna honek dokumentuen irudi guztiak gris-eskala bihurtzen ditu. Fitxategien tamaina murrizteko eta inprimatzeko onena</string>\n    <string name=\"metadata\">Metadatuak</string>\n    <string name=\"metadata_pdf_sub\">Editatu dokumentuaren propietateak pribatutasun hobea izateko</string>\n    <string name=\"tags\">Etiketak</string>\n    <string name=\"producer\">Ekoizlea</string>\n    <string name=\"author\">Egilea</string>\n    <string name=\"keywords\">Gako-hitzak</string>\n    <string name=\"creator\">Sortzailea</string>\n    <string name=\"privacy_deep_clean\">Pribatutasuna Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Garbitu dokumentu honetarako erabilgarri dauden metadatu guztiak</string>\n    <string name=\"page\">Orria</string>\n    <string name=\"deep_ocr\">OCR sakona</string>\n    <string name=\"deep_ocr_sub\">Atera testua dokumentutik eta gorde testu fitxategi bakarrean Tesseract motorra erabiliz</string>\n    <string name=\"cant_remove_all\">Ezin dira orri guztiak kendu</string>\n    <string name=\"remove_pages_pdf\">Kendu PDF orriak</string>\n    <string name=\"remove_pages_pdf_sub\">Kendu orri zehatzak PDF dokumentutik</string>\n    <string name=\"tap_to_remove\">Sakatu Kendu</string>\n    <string name=\"manually\">Eskuz</string>\n    <string name=\"crop_pdf\">Moztu PDFa</string>\n    <string name=\"crop_pdf_sub\">Moztu dokumentuaren orriak edozein mugatara</string>\n    <string name=\"flatten_pdf\">Laundu PDFa</string>\n    <string name=\"flatten_pdf_sub\">Egin PDF aldaezina dokumentu-orriak rasterizatuz</string>\n    <string name=\"camera_failed_to_open\">Ezin izan da kamera abiarazi. Mesedez, egiaztatu baimenak eta ziurtatu beste aplikazio batek ez duela erabiltzen.</string>\n    <string name=\"extract_images\">Irudiak atera</string>\n    <string name=\"extract_images_sub\">Atera PDFetan txertatutako irudiak jatorrizko bereizmenarekin</string>\n    <string name=\"pdf_no_embedded\">PDF fitxategi honek ez du kapsulatutako irudirik</string>\n    <string name=\"extract_images_info\">Tresna honek orrialde guztiak eskaneatzen ditu eta kalitate osoko iturburu-irudiak berreskuratzen ditu - ezin hobea dokumentuetatik jatorrizkoak gordetzeko</string>\n    <string name=\"draw_signature\">Marraztu Sinadura</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">Erabili sinadura propioa dokumentuetan jartzeko irudi gisa</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Zatitu dokumentua emandako tartearekin eta paketatu dokumentu berriak zip artxiboan</string>\n    <string name=\"interval\">Tartea</string>\n    <string name=\"print_pdf\">PDF inprimatu</string>\n    <string name=\"print_pdf_sub\">Prestatu dokumentua orri-tamaina pertsonalizatuarekin inprimatzeko</string>\n    <string name=\"pages_per_sheet\">Orrialde bakoitzeko orrialdeak</string>\n    <string name=\"orientation\">Orientazioa</string>\n    <string name=\"page_size\">Orrialdearen Tamaina</string>\n    <string name=\"margin\">Marjina</string>\n    <string name=\"bloom\">Loraldia</string>\n    <string name=\"soft_knee\">Belauna biguna</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Anime eta marrazki bizidunetarako optimizatua. Azkar igotzea kolore natural hobetuekin eta artefaktu gutxiagorekin</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 bezalako estiloa</string>\n    <string name=\"calculate_hint\">Sartu hemen oinarrizko matematika-sinboloak nahi duzun balioa kalkulatzeko (adibidez, (5+5)*10)</string>\n    <string name=\"math_expression\">Matematikako adierazpena</string>\n    <string name=\"pick_up_to_n_collage_images\">Jaso %1$s irudi</string>\n    <string name=\"background_color_for_alpha_formats\">Atzeko planoko kolorea Alfa formatuetarako</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Alfa laguntzarekin atzeko planoko kolorea ezartzeko gaitasuna gehitzen du, desgaituta dagoenean, alfa ez direnentzat bakarrik eskuragarri.</string>\n    <string name=\"keep_date_time\">Mantendu Data Ordua</string>\n    <string name=\"keep_date_time_sub\">Gorde beti data eta orduarekin lotutako exif etiketak, mantendu exif aukeratik independenteki funtzionatzen du</string>\n    <string name=\"open_markup_project\">Proiektu irekia</string>\n    <string name=\"open_markup_project_sub\">Jarraitu aurrez gordetako Image Toolbox proiektu bat editatzen</string>\n    <string name=\"markup_project_open_failed\">Ezin da Image Toolbox proiektua ireki</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox proiektuari proiektuaren datuak falta zaizkio</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox proiektua hondatuta dago</string>\n    <string name=\"unsupported_markup_project_version\">Onartzen ez den Image Toolbox proiektuaren bertsioa: %1$d</string>\n    <string name=\"save_markup_project\">Gorde proiektua</string>\n    <string name=\"save_markup_project_sub\">Gorde geruzak, atzeko planoa eta editatu historia proiektu editagarri batean</string>\n    <string name=\"failed_to_open\">Ezin izan da ireki</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Idatzi bila daitekeen PDF batean</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Ezagutu irudi sortako testua eta gorde PDF bilagarria irudiarekin eta hauta daitekeen testu geruzarekin</string>\n    <string name=\"layer_alpha\">Geruza alfa</string>\n    <string name=\"horizontal_flip\">Flip horizontala</string>\n    <string name=\"vertical_flip\">Flip bertikala</string>\n    <string name=\"lock\">Blokea</string>\n    <string name=\"add_shadow\">Gehitu Itzala</string>\n    <string name=\"shadow_color\">Itzalen Kolorea</string>\n    <string name=\"text_geometry\">Testuaren Geometria</string>\n    <string name=\"text_geometry_sub\">Luzatu edo okertu testua estilizazio zorrotzagoa lortzeko</string>\n    <string name=\"scale_x\">X eskala</string>\n    <string name=\"skew_x\">Okertu X</string>\n    <string name=\"remove_annotations\">Kendu oharrak</string>\n    <string name=\"remove_annotations_sub\">Kendu hautatutako ohar motak, hala nola estekak, iruzkinak, nabarmenduak, formak edo inprimaki-eremuak PDF orrietatik</string>\n    <string name=\"annotation_link\">Hiperestekak</string>\n    <string name=\"annotation_file_attachment\">Fitxategi eranskinak</string>\n    <string name=\"annotation_line\">Lerroak</string>\n    <string name=\"annotation_popup\">Popup-ak</string>\n    <string name=\"annotation_stamp\">Zigiluak</string>\n    <string name=\"annotation_shapes\">Formak</string>\n    <string name=\"annotation_text\">Testu-oharrak</string>\n    <string name=\"annotation_text_markup\">Testuaren markaketa</string>\n    <string name=\"annotation_widget\">Inprimaki-eremuak</string>\n    <string name=\"annotation_markup\">Markatzea</string>\n    <string name=\"annotation_unknown\">Ezezaguna</string>\n    <string name=\"annotations\">Oharpenak</string>\n    <string name=\"ungroup\">Destaldekatu</string>\n    <string name=\"add_shadow_sub\">Gehitu lausotutako itzala geruzaren atzean, kolore eta desplazamendu konfiguragarriekin</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-fa/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"size\">اندازه</string>\n    <string name=\"pick_image\">تصویری برای شروع انتخاب کنید</string>\n    <string name=\"smth_went_wrong\">مشکلی رخ داد: %1$s</string>\n    <string name=\"loading\">در حال بارگذاری…</string>\n    <string name=\"image_too_large_preview\">تصویر برای پیش نمایش بسیار بزرگ است، اما به هر حال ذخیره خواهد شد</string>\n    <string name=\"width\">عرض %1$s</string>\n    <string name=\"height\">ارتفاع %1$s</string>\n    <string name=\"primary\">اصلی</string>\n    <string name=\"cache\">حافظه نهان</string>\n    <string name=\"background_remover\">برداشتن پس‌زمینه</string>\n    <string name=\"fidelity\">وفاداری</string>\n    <string name=\"recognize_text\">OCR (تشخیص متن)</string>\n    <string name=\"best\">بهترین</string>\n    <string name=\"rate\">امتیاز</string>\n    <string name=\"color_stops\">توقف‌های رنگ</string>\n    <string name=\"add_color\">افزودن رنگ</string>\n    <string name=\"millis\">میلی‌ثانیه</string>\n    <string name=\"fps\">فریم در ثانیه</string>\n    <string name=\"use_lasso\">استفاده از طناب</string>\n    <string name=\"secure_mode\">حالت امن</string>\n    <string name=\"median_blur\">محو میانه</string>\n    <string name=\"amplitude\">دامنه</string>\n    <string name=\"marble\">مرمر</string>\n    <string name=\"color_matrix_3x3\">ماتریس رنگ ۳×۳</string>\n    <string name=\"simple_effects\">جلوه‌های ساده</string>\n    <string name=\"quality\">کیفیت</string>\n    <string name=\"extension\">پسوند</string>\n    <string name=\"resize_type\">نوع تغییر اندازه</string>\n    <string name=\"explicit\">صریح</string>\n    <string name=\"flexible\">انعطاف‌پذیر</string>\n    <string name=\"pick_image_alt\">تصویر را انتخاب کنید</string>\n    <string name=\"app_closing_sub\">آیا مطمئن هستید که می خواهید برنامه را ببندید؟</string>\n    <string name=\"app_closing\">در حال بستن برنامه</string>\n    <string name=\"stay\">ماندن</string>\n    <string name=\"close\">بستن</string>\n    <string name=\"reset_image\">بازنشانی تصویر</string>\n    <string name=\"reset_image_sub\">تغییرات تصویر به مقادیر اولیه بازخواهد گشت</string>\n    <string name=\"values_reset\">مقادیر به درستی بازنشانی شدند</string>\n    <string name=\"reset\">بازنشانی</string>\n    <string name=\"something_went_wrong\">مشکلی پیش آمد</string>\n    <string name=\"restart_app\">باز راه‌اندازی برنامه</string>\n    <string name=\"copied\">در تخته‌گیره رونوشت شد</string>\n    <string name=\"exception\">استثنا</string>\n    <string name=\"edit_exif\">ویرایش EXIF</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">تأیید</string>\n    <string name=\"no_exif\">هیچ داده EXIF یافت نشد</string>\n    <string name=\"add_tag\">افزودن برچسب</string>\n    <string name=\"save\">ذخیره</string>\n    <string name=\"clear\">پاک کردن</string>\n    <string name=\"clear_exif\">پاک کردن EXIF</string>\n    <string name=\"cancel\">رد کردن</string>\n    <string name=\"clear_exif_sub\">تمام داده‌های EXIF تصویر پاک خواهند شد. این عمل قابل لغو نیست!</string>\n    <string name=\"presets\">پیش‌تنظیم‌ها</string>\n    <string name=\"crop\">برش</string>\n    <string name=\"image_not_saved\">در حال ذخیره</string>\n    <string name=\"image_not_saved_sub\">اگر اکنون خارج شوید، همه تغییرات ذخیره نشده از بین خواهند رفت</string>\n    <string name=\"check_source_code\">کد منبع</string>\n    <string name=\"check_source_code_sub\">آخرین به‌روز رسانی‌ها را دریافت کنید، درباره مسائل و موارد دیگر بحث کنید</string>\n    <string name=\"single_edit\">ویرایش تکی</string>\n    <string name=\"single_edit_sub\">تغییر اندازه و ویرایش یک تصویر</string>\n    <string name=\"pick_color\">انتخابگر رنگ</string>\n    <string name=\"pick_color_sub\">رنگ را از تصویر انتخاب کنید، کپی کنید یا به اشتراک بگذارید</string>\n    <string name=\"image\">تصویر</string>\n    <string name=\"color\">رنگ</string>\n    <string name=\"color_copied\">رنگ رونوشت شد</string>\n    <string name=\"crop_sub\">تصویر را به هر حدی برش دهید</string>\n    <string name=\"version\">نگارش</string>\n    <string name=\"keep_exif\">نگه‌داری EXIF</string>\n    <string name=\"images\">Images: %d</string>\n    <string name=\"change_preview\">تغییر پیش‌نمایش</string>\n    <string name=\"remove\">پاک کردن</string>\n    <string name=\"palette_sub\">نمونه پالت رنگی را از تصویر داده شده ایجاد کنید</string>\n    <string name=\"generate_palette\">تولید تخته‌رنگ رنگی از تصویر داده‌شده</string>\n    <string name=\"palette\">تخته‌رنگ</string>\n    <string name=\"update\">به‌روزرسانی</string>\n    <string name=\"new_version\">نگارش جدید %1$s</string>\n    <string name=\"unsupported_type\">نوع پشتیبانی‌نشده: %1$s</string>\n    <string name=\"no_palette\">نمی توان پالت برای تصویر داده شده ایجاد کرد</string>\n    <string name=\"original\">اصلی</string>\n    <string name=\"folder\">پوشه خروجی</string>\n    <string name=\"def\">پیش فرض</string>\n    <string name=\"custom\">سفارشی</string>\n    <string name=\"unspecified\">نامشخص</string>\n    <string name=\"device_storage\">حافظه دستگاه</string>\n    <string name=\"by_bytes_resize\">تغییر اندازه بر اساس وزن</string>\n    <string name=\"max_bytes\">حداکثر اندازه در کیلوبایت</string>\n    <string name=\"by_bytes_resize_sub\">اندازه یک تصویر را با توجه به اندازه داده شده در کیلوبایت تغییر دهید</string>\n    <string name=\"compare\">مقایسه</string>\n    <string name=\"compare_sub\">دو تصویر داده شده را مقایسه کنید</string>\n    <string name=\"pick_two_images\">دو تصویر برای شروع انتخاب کنید</string>\n    <string name=\"pick_images\">انتخاب تصاویر</string>\n    <string name=\"settings\">تنظیمات</string>\n    <string name=\"night_mode\">حالت شب</string>\n    <string name=\"dark\">تیره</string>\n    <string name=\"light\">روشن</string>\n    <string name=\"system\">سیستم</string>\n    <string name=\"dynamic_colors\">رنگ‌های پویا</string>\n    <string name=\"customization\">سفارشی‌سازی</string>\n    <string name=\"allow_image_monet\">اجازه هماهنگی رنگ تصویر</string>\n    <string name=\"allow_image_monet_sub\">اگر فعال باشد، وقتی تصویری را برای ویرایش انتخاب می‌کنید، رنگ‌های برنامه برای این تصویر انتخاب می‌شوند</string>\n    <string name=\"language\">زبان</string>\n    <string name=\"amoled_mode\">حالت کاملا تیره</string>\n    <string name=\"amoled_mode_sub\">در صورت فعال بودن رنگ سطوح در حالت شب روی تاریکی مطلق تنظیم می شود</string>\n    <string name=\"color_scheme\">طرح رنگی</string>\n    <string name=\"color_red\">قرمز</string>\n    <string name=\"color_green\">سبز</string>\n    <string name=\"color_blue\">آبی</string>\n    <string name=\"clipboard_paste_invalid_color_code\">یک کد رنگ aRGB معتبر را جایگذاری کنید</string>\n    <string name=\"clipboard_paste_invalid_empty\">چیزی برای چسباندن نیست</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">در حالی که رنگ‌های پویا روشن هستند، نمی‌توان طرح رنگ برنامه را تغییر داد</string>\n    <string name=\"pick_accent_color\">طرح زمینه برنامه بر اساس رنگ انتخاب شده خواهد بود</string>\n    <string name=\"about_app\">درباره برنامه</string>\n    <string name=\"no_updates\">هیچ به روز رسانی پیدا نشد</string>\n    <string name=\"issue_tracker\">ردیاب مشکلات</string>\n    <string name=\"issue_tracker_sub\">گزارش اشکال و درخواست ویژگی را اینجا ارسال کنید</string>\n    <string name=\"help_translate\">کمک به ترجمه</string>\n    <string name=\"help_translate_sub\">اشتباهات ترجمه را تصحیح کنید یا پروژه را به زبان های دیگر بومی سازی کنید</string>\n    <string name=\"nothing_found_by_search\">با درخواست شما چیزی پیدا نشد</string>\n    <string name=\"search_here\">اینجا جستجو کنید</string>\n    <string name=\"dynamic_colors_sub\">اگر فعال باشد، رنگ‌های برنامه برای رنگ‌های کاغذدیواری استفاده می‌شوند</string>\n    <string name=\"failed_to_save\">ذخیره %d تصویر(ها) ناموفق بود</string>\n    <string name=\"email\">رایانامه</string>\n    <string name=\"tertiary\">سومین</string>\n    <string name=\"secondary\">فرعی</string>\n    <string name=\"border_thickness\">ضخامت حاشیه</string>\n    <string name=\"surface\">سطح</string>\n    <string name=\"values\">مقادیر</string>\n    <string name=\"add\">افزودن</string>\n    <string name=\"permission\">دسترسی</string>\n    <string name=\"grant\">دادن</string>\n    <string name=\"permission_sub\">برنامه نیاز به دسترسی به فضای ذخیره سازی شما برای ذخیره تصاویر برای کار دارد، لازم است. لطفاً در کادر محاوره ای بعدی مجوز بدهید.</string>\n    <string name=\"grant_permission_manual\">برنامه برای کار به این مجوز نیاز دارد، لطفاً آن را به صورت دستی اعطا کنید</string>\n    <string name=\"external_storage\">حافظه خارجی</string>\n    <string name=\"monet_colors\">رنگ‌های پویا</string>\n    <string name=\"donation_sub\">این برنامه کاملا رایگان است، اما اگر می خواهید از توسعه پروژه پشتیبانی کنید، می توانید اینجا کلیک کنید</string>\n    <string name=\"fab_alignment\">تراز دکمه شناور</string>\n    <string name=\"check_updates\">به روز رسانی را بررسی کنید</string>\n    <string name=\"check_updates_sub\">در صورت فعال بودن، گفتگوی به‌روزرسانی هنگام راه‌اندازی برنامه به شما نشان داده می‌شود</string>\n    <string name=\"zoom\">بزرگنمایی تصویر</string>\n    <string name=\"share\">هم‌رسانی</string>\n    <string name=\"prefix\">پیشوند</string>\n    <string name=\"filename\">نام پرونده</string>\n    <string name=\"emoji\">شکلک</string>\n    <string name=\"emoji_sub\">انتخاب کنید کدام ایموجی در صفحه اصلی نمایش داده شود</string>\n    <string name=\"add_file_size\">افزودن اندازه پرونده</string>\n    <string name=\"add_file_size_sub\">در صورت فعال بودن، عرض و ارتفاع تصویر ذخیره شده را به نام فایل خروجی اضافه می کند</string>\n    <string name=\"delete_exif\">برداشتن EXIF</string>\n    <string name=\"delete_exif_sub\">ابرداده EXIF را از هر مجموعه ای از تصاویر حذف کنید</string>\n    <string name=\"image_preview\">پیش‌نمایش تصویر</string>\n    <string name=\"image_preview_sub\">پیش نمایش هر نوع تصویر: GIF، SVG، و غیره</string>\n    <string name=\"image_source\">منبع تصویر</string>\n    <string name=\"photo_picker\">انتخاب‌گر عکس</string>\n    <string name=\"gallery_picker\">آلبوم عکس</string>\n    <string name=\"file_explorer_picker\">جستجوگر فایل</string>\n    <string name=\"photo_picker_sub\">انتخابگر عکس مدرن اندروید که در پایین صفحه ظاهر می شود، ممکن است فقط در اندروید 12+ کار کند. در دریافت فراداده EXIF مشکل دارد</string>\n    <string name=\"gallery_picker_sub\">انتخابگر تصویر گالری ساده. فقط در صورتی کار می کند که برنامه ای داشته باشید که انتخاب رسانه را ارائه دهد</string>\n    <string name=\"file_explorer_picker_sub\">از قصد GetContent برای انتخاب تصویر استفاده کنید. در همه جا کار می کند، اما مشخص است که در دریافت تصاویر انتخابی در برخی از دستگاه ها مشکلاتی دارد. این تقصیر من نیست</string>\n    <string name=\"options_arrangement\">چیدمان گزینه‌ها</string>\n    <string name=\"edit\">ویرایش</string>\n    <string name=\"order\">ترتیب</string>\n    <string name=\"order_sub\">ترتیب ابزار ها را در صفحه اصلی تعیین می کند</string>\n    <string name=\"emojis_count\">تعداد شکلک‌ها</string>\n    <string name=\"sequence_num\">شماره ترتیب</string>\n    <string name=\"original_filename\">نام پرونده اصلی</string>\n    <string name=\"add_original_filename\">افزودن نام پرونده اصلی</string>\n    <string name=\"add_original_filename_sub\">اگر فعال باشد، نام فایل اصلی را به نام تصویر خروجی اضافه می کند</string>\n    <string name=\"replace_sequence_number\">جایگزینی شماره ترتیب</string>\n    <string name=\"replace_sequence_number_sub\">اگر فعال باشد، اگر از پردازش دسته‌ای استفاده می‌کنید، مهر زمانی استاندارد را به شماره توالی تصویر جایگزین می‌کند</string>\n    <string name=\"filename_not_work_with_photopicker\">اگر منبع تصویر انتخابگر عکس انتخاب شود، افزودن نام فایل اصلی کار نمی‌کند</string>\n    <string name=\"load_image_from_net\">بارگذاری تصویر از وب</string>\n    <string name=\"load_image_from_net_sub\">هر تصویری را از اینترنت برای پیش نمایش، زوم، ویرایش و ذخیره آن در صورت تمایل بارگیری کنید.</string>\n    <string name=\"no_image\">بدون تصویر</string>\n    <string name=\"image_link\">پیوند تصویر</string>\n    <string name=\"fill\">پر کردن</string>\n    <string name=\"fit\">تناسب</string>\n    <string name=\"content_scale\">مقیاس محتوا</string>\n    <string name=\"explicit_description\">اندازه تصاویر را به ارتفاع و عرض داده شده تغییر دهید. نسبت ابعاد تصاویر ممکن است تغییر کند.</string>\n    <string name=\"flexible_description\">تصاویر را با ضلع بلند به ارتفاع یا عرض داده شده تغییر اندازه می‌دهد. تمام محاسبات اندازه پس از ذخیره انجام می‌شود. نسبت ابعاد تصاویر حفظ خواهد شد.</string>\n    <string name=\"brightness\">روشنایی</string>\n    <string name=\"contrast\">تضاد</string>\n    <string name=\"hue\">رنگ‌مایه</string>\n    <string name=\"saturation\">اشباع</string>\n    <string name=\"add_filter\">افزودن پالایه</string>\n    <string name=\"filter\">پالایه</string>\n    <string name=\"filter_sub\">هر زنجیره فیلتر را روی تصاویر داده شده اعمال کنید</string>\n    <string name=\"filters\">پالایه‌ها</string>\n    <string name=\"light_aka_illumination\">سبک</string>\n    <string name=\"color_filter\">پالایه رنگ</string>\n    <string name=\"alpha\">آلفا</string>\n    <string name=\"exposure\">نوردهی</string>\n    <string name=\"white_balance\">تراز سفیدی</string>\n    <string name=\"temperature\">دما</string>\n    <string name=\"tint\">ته‌رنگ</string>\n    <string name=\"monochrome\">تک‌رنگ</string>\n    <string name=\"gamma\">گاما</string>\n    <string name=\"highlights_shadows\">هایلایت و سایه ها</string>\n    <string name=\"highlights\">هایلایت‌ها</string>\n    <string name=\"shadows\">سایه‌ها</string>\n    <string name=\"haze\">مه</string>\n    <string name=\"effect\">جلوه</string>\n    <string name=\"distance\">فاصله</string>\n    <string name=\"slope\">شیب</string>\n    <string name=\"sharpen\">تیز کردن</string>\n    <string name=\"sepia\">سپیا</string>\n    <string name=\"negative\">نفی</string>\n    <string name=\"solarize\">خورشیدی‌سازی</string>\n    <string name=\"vibrance\">سرزندگی</string>\n    <string name=\"black_and_white\">سیاه و سفید</string>\n    <string name=\"crosshatch\">هاشور متقاطع</string>\n    <string name=\"spacing\">فاصله‌گذاری</string>\n    <string name=\"line_width\">عرض خط</string>\n    <string name=\"sobel_edge\">لبه سوبل</string>\n    <string name=\"blur\">محو</string>\n    <string name=\"halftone\">نیم‌تون</string>\n    <string name=\"cga_colorspace\">فضای رنگی CGA</string>\n    <string name=\"gaussian_blur\">محو گاوسی</string>\n    <string name=\"box_blur\">محو جعبه‌ای</string>\n    <string name=\"bilaterial_blur\">تاری دو طرفه</string>\n    <string name=\"emboss\">برجسته‌سازی</string>\n    <string name=\"laplacian\">لاپلاسین</string>\n    <string name=\"vignette\">وینیت</string>\n    <string name=\"start\">آغاز</string>\n    <string name=\"end\">پایان</string>\n    <string name=\"kuwahara\">کووهرا صاف کردن</string>\n    <string name=\"stack_blur\">محو پشته‌ای</string>\n    <string name=\"radius\">شعاع</string>\n    <string name=\"scale\">مقیاس</string>\n    <string name=\"distortion\">اعوجاج</string>\n    <string name=\"angle\">زاویه</string>\n    <string name=\"swirl\">چرخش</string>\n    <string name=\"bulge\">برآمدگی</string>\n    <string name=\"dilation\">گشادسازی</string>\n    <string name=\"sphere_refraction\">شکست کره‌ای</string>\n    <string name=\"refractive_index\">شاخص شکست</string>\n    <string name=\"glass_sphere_refraction\">شکست کره شیشه‌ای</string>\n    <string name=\"color_matrix\">ماتریس رنگ</string>\n    <string name=\"opacity\">شفافیت</string>\n    <string name=\"limits_resize\">تغییر اندازه با محدودیت</string>\n    <string name=\"limits_resize_sub\">اندازه تصاویر انتخاب شده را تغییر دهید تا از محدودیت های عرض و ارتفاع پیروی کنید و در عین حال نسبت ابعاد را ذخیره کنید</string>\n    <string name=\"sketch\">طرح</string>\n    <string name=\"threshold\">آستانه</string>\n    <string name=\"quantizationLevels\">سطوح کوانتیزاسیون</string>\n    <string name=\"smooth_toon\">کارتونی نرم</string>\n    <string name=\"toon\">کارتونی</string>\n    <string name=\"posterize\">پوسترسازی</string>\n    <string name=\"non_maximum_suppression\">برداشتن غیرحداکثر</string>\n    <string name=\"weak_pixel_inclusion\">گنجایش پیکسل ضعیف</string>\n    <string name=\"lookup\">جستجو</string>\n    <string name=\"convolution3x3\">پیچیدگی 3x3</string>\n    <string name=\"rgb_filter\">پالایه RGB</string>\n    <string name=\"false_color\">رنگ کاذب</string>\n    <string name=\"first_color\">رنگ اول</string>\n    <string name=\"second_color\">رنگ دوم</string>\n    <string name=\"reorder\">بازچینش</string>\n    <string name=\"fast_blur\">محو سریع</string>\n    <string name=\"blur_size\">اندازه محو</string>\n    <string name=\"blur_center_x\">مرکز محو X</string>\n    <string name=\"blur_center_y\">مرکز محو Y</string>\n    <string name=\"zoom_blur\">محو بزرگ‌نمایی</string>\n    <string name=\"color_balance\">تعادل رنگ</string>\n    <string name=\"luminance_threshold\">آستانه درخشندگی</string>\n    <string name=\"activate_files\">برنامه Files را غیرفعال کردید، برای استفاده از این ویژگی آن را فعال کنید</string>\n    <string name=\"draw\">نقاشی</string>\n    <string name=\"draw_sub\">مانند یک کتاب طراحی روی تصویر بکشید یا روی خود پس زمینه بکشید</string>\n    <string name=\"paint_color\">رنگ قلم</string>\n    <string name=\"paint_alpha\">آلفای قلم</string>\n    <string name=\"draw_on_image\">نقاشی روی تصویر</string>\n    <string name=\"draw_on_image_sub\">یک تصویر را انتخاب کنید و چیزی روی آن بکشید</string>\n    <string name=\"draw_on_background\">نقاشی روی پس‌زمینه</string>\n    <string name=\"draw_on_background_sub\">رنگ پس زمینه را انتخاب کنید و بالای آن بکشید</string>\n    <string name=\"background_color\">رنگ پس‌زمینه</string>\n    <string name=\"cipher\">رمزنگاری</string>\n    <string name=\"cipher_sub\">هر فایل (نه تنها تصویر) را بر اساس الگوریتم‌های مختلف رمزنگاری موجود، رمزگذاری و رمزگشایی کنید</string>\n    <string name=\"pick_file\">انتخاب پرونده</string>\n    <string name=\"encrypt\">رمزنگاری</string>\n    <string name=\"decrypt\">رمزگشایی</string>\n    <string name=\"pick_file_to_start\">پرونده‌ای برای شروع انتخاب کنید</string>\n    <string name=\"decryption\">رمزگشایی</string>\n    <string name=\"encryption\">رمزنگاری</string>\n    <string name=\"key\">کلید</string>\n    <string name=\"file_proceed\">فایل پردازش شد</string>\n    <string name=\"store_file_desc\">این فایل را در دستگاه خود ذخیره کنید یا از اقدام اشتراک گذاری برای قرار دادن آن در هر کجا که می خواهید استفاده کنید</string>\n    <string name=\"features\">ویژگی‌ها</string>\n    <string name=\"implementation\">پیاده‌سازی</string>\n    <string name=\"compatibility\">سازگاری</string>\n    <string name=\"features_sub\">رمزگذاری فایل ها بر اساس رمز عبور فایل های ادامه یافته را می توان در فهرست انتخابی ذخیره کرد یا به اشتراک گذاشت. فایل های رمزگشایی شده نیز می توانند مستقیما باز شوند.</string>\n    <string name=\"implementation_sub\">AES-256 با حالت GCM، بدون padding، IV تصادفی ۱۲ بایتی (به صورت پیش‌فرض، اما می‌توانید الگوریتم مورد نظر را انتخاب کنید). کلیدها به صورت هش SHA-3 با طول ۲۵۶ بیت استفاده می‌شوند.</string>\n    <string name=\"file_size\">اندازه پرونده</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">لطفاً توجه داشته باشید که سازگاری با سایر نرم افزارها یا خدمات رمزگذاری فایل تضمین نمی شود. یک درمان کلیدی یا پیکربندی رمز کمی متفاوت ممکن است باعث ناسازگاری شود.</string>\n    <string name=\"invalid_password_or_not_encrypted\">رمز عبور نامعتبر یا فایل انتخابی رمزگذاری نشده است</string>\n    <string name=\"image_size_warning\">تلاش برای ذخیره تصویر با عرض و ارتفاع معین ممکن است باعث خطای OOM شود. این کار را با مسئولیت خود انجام دهید و نگویید من به شما هشدار ندادم!</string>\n    <string name=\"cache_size\">اندازه حافظه نهان</string>\n    <string name=\"found_s\">پیدا شد %1$s</string>\n    <string name=\"auto_cache_clearing\">پاک‌سازی خودکار حافظه نهان</string>\n    <string name=\"auto_cache_clearing_sub\">در صورت فعال بودن حافظه پنهان برنامه هنگام راه اندازی برنامه پاک می شود</string>\n    <string name=\"create\">ساختن</string>\n    <string name=\"tools\">ابزارها</string>\n    <string name=\"group_options_by_type\">گروه‌بندی گزینه‌ها بر پایه نوع</string>\n    <string name=\"group_options_by_type_sub\">به جای ترتیب فهرست سفارشی، گزینه‌ها را بر اساس نوعشان در صفحه اصلی گروه‌بندی می‌کند</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">وقتی گروه بندی گزینه ها فعال است، نمی توان ترتیب را تغییر داد</string>\n    <string name=\"edit_screenshot\">ویرایش عکس از صفحه</string>\n    <string name=\"secondary_customization\">سفارشی‌سازی فرعی</string>\n    <string name=\"screenshot\">عکس از صفحه</string>\n    <string name=\"fallback_option\">گزینه جایگزین</string>\n    <string name=\"skip\">رد کردن</string>\n    <string name=\"copy\">رونوشت</string>\n    <string name=\"warning_bytes\">ذخیره در حالت %1$s می تواند ناپایدار باشد، زیرا یک قالب بدون ضرر است</string>\n    <string name=\"presets_sub\" formatted=\"false\">اگر 125 از پیش تعیین شده را انتخاب کرده باشید، تصویر به اندازه 125% اندازه تصویر اصلی ذخیره می شود. اگر 50 از پیش تعیین شده را انتخاب کنید، تصویر با اندازه 50٪ ذخیره می شود</string>\n    <string name=\"presets_sub_bytes\">پیش‌تنظیم در اینجا درصد فایل خروجی را تعیین می‌کند، یعنی اگر 50 از پیش تعیین شده را روی تصویر 5 مگابایتی انتخاب کنید، پس از ذخیره کردن تصویر 2.5 مگابایتی دریافت خواهید کرد.</string>\n    <string name=\"randomize_filename\">تصادفی‌سازی نام پرونده</string>\n    <string name=\"randomize_filename_sub\">اگر فعال باشد نام فایل خروجی کاملا تصادفی خواهد بود</string>\n    <string name=\"saved_to\">در پوشه %1$s با نام %2$s ذخیره شد</string>\n    <string name=\"saved_to_without_filename\">در پوشه %1$s ذخیره شد</string>\n    <string name=\"tg_chat\">چت تلگرام</string>\n    <string name=\"tg_chat_sub\">در مورد برنامه بحث کنید و از سایر کاربران بازخورد دریافت کنید. همچنین می‌توانید به‌روزرسانی‌ها و اطلاعات آماری بتا را در اینجا دریافت کنید.</string>\n    <string name=\"crop_mask\">ماسک برش</string>\n    <string name=\"aspect_ratio\">نسبت ابعاد</string>\n    <string name=\"image_crop_mask_sub\">از این نوع ماسک برای ایجاد ماسک از تصویر داده شده استفاده کنید، توجه کنید که باید کانال آلفا داشته باشد</string>\n    <string name=\"backup_and_restore\">پشتیبان‌گیری و بازیابی</string>\n    <string name=\"backup\">پشتیبان‌گیری</string>\n    <string name=\"restore\">بازیابی</string>\n    <string name=\"backup_sub\">از تنظیمات برنامه خود در یک فایل نسخه پشتیبان تهیه کنید</string>\n    <string name=\"restore_sub\">تنظیمات برنامه را از فایلی که قبلا ایجاد شده است بازیابی کنید</string>\n    <string name=\"corrupted_file_or_not_a_backup\">فایل خراب است یا نسخه پشتیبان ندارد</string>\n    <string name=\"settings_restored\">تنظیمات با موفقیت بازیابی شدند</string>\n    <string name=\"contact_me\">تماس با من</string>\n    <string name=\"reset_settings_sub\">با این کار تنظیمات شما به مقادیر پیش فرض برمی گردد. توجه داشته باشید که این کار بدون فایل پشتیبان ذکر شده در بالا قابل واگرد نیست.</string>\n    <string name=\"delete\">پاک کردن</string>\n    <string name=\"delete_color_scheme_warn\">شما در حال حذف طرح رنگ انتخابی هستید. این عملیات قابل برگشت نیست</string>\n    <string name=\"delete_color_scheme_title\">حذف طرح</string>\n    <string name=\"font\">قلم</string>\n    <string name=\"text\">متن</string>\n    <string name=\"font_scale\">مقیاس قلم</string>\n    <string name=\"defaultt\">پیش فرض</string>\n    <string name=\"using_large_fonts_warn\">استفاده از مقیاس‌های فونت بزرگ ممکن است باعث اشکالات و مشکلات رابط کاربری شود که رفع نمی‌شوند. با احتیاط استفاده کنید.</string>\n    <string name=\"alphabet_and_numbers\">ا ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ی 0123456789 !؟</string>\n    <string name=\"emotions\">احساسات</string>\n    <string name=\"food_and_drink\">غذا و نوشیدنی</string>\n    <string name=\"nature_and_animals\">طبیعت و حیوانات</string>\n    <string name=\"objects\">اشیاء</string>\n    <string name=\"symbols\">نمادها</string>\n    <string name=\"enable_emoji\">فعال‌سازی شکلک</string>\n    <string name=\"travels_and_places\">سفرها و مکان‌ها</string>\n    <string name=\"activities\">فعالیت‌ها</string>\n    <string name=\"background_remover_sub\">با کشیدن پس زمینه از تصویر حذف کنید یا از گزینه Auto استفاده کنید</string>\n    <string name=\"trim_image\">کوتاه کردن تصویر</string>\n    <string name=\"keep_exif_sub\">ابرداده تصویر اصلی حفظ خواهد شد</string>\n    <string name=\"trim_image_sub\">فضاهای شفاف اطراف تصویر کوتاه خواهند شد</string>\n    <string name=\"auto_erase_background\">برداشتن خودکار پس‌زمینه</string>\n    <string name=\"restore_image\">بازیابی تصویر</string>\n    <string name=\"erase_mode\">حالت پاک کردن</string>\n    <string name=\"erase_background\">پاک کردن پس‌زمینه</string>\n    <string name=\"restore_background\">بازیابی پس‌زمینه</string>\n    <string name=\"blur_radius\">شعاع محو</string>\n    <string name=\"pipette\">پیپت</string>\n    <string name=\"draw_mode\">حالت نقاشی</string>\n    <string name=\"create_issue\">ایجاد مسئله</string>\n    <string name=\"something_went_wrong_emphasis\">اوه… مشکلی پیش آمد. می توانید با استفاده از گزینه های زیر برای من بنویسید و من سعی خواهم کرد راه حلی پیدا کنم</string>\n    <string name=\"resize_and_convert\">تغییر اندازه و تبدیل</string>\n    <string name=\"resize_and_convert_sub\">اندازه تصاویر داده شده را تغییر دهید یا آنها را به فرمت های دیگر تبدیل کنید. در صورت انتخاب یک تصویر واحد، ابرداده EXIF را نیز می توان در اینجا ویرایش کرد.</string>\n    <string name=\"max_colors_count\">حداکثر تعداد رنگ</string>\n    <string name=\"crashlytics_sub\">این به برنامه اجازه می دهد تا گزارش های خرابی را به صورت دستی جمع آوری کند</string>\n    <string name=\"analytics\">تحلیل</string>\n    <string name=\"analytics_sub\">جمع آوری آمار استفاده از برنامه ناشناس را مجاز کنید</string>\n    <string name=\"image_exif_warning\">در حال حاضر، قالب %1$s فقط اجازه خواندن فراداده EXIF را در اندروید می دهد. تصویر خروجی در صورت ذخیره به هیچ وجه متادیتا نخواهد داشت.</string>\n    <string name=\"effort\">تلاش</string>\n    <string name=\"effort_sub\">مقدار %1$s به معنای فشرده سازی سریع است که در نتیجه اندازه فایل نسبتاً بزرگی ایجاد می شود. %2$s به معنای فشرده سازی کندتر است که در نتیجه فایل کوچکتری ایجاد می شود.</string>\n    <string name=\"wait\">صبر کنید</string>\n    <string name=\"saving_almost_complete\">ذخیره تقریباً کامل شده است. لغو اکنون نیازمند ذخیره دوباره است.</string>\n    <string name=\"updates\">به‌روزرسانی‌ها</string>\n    <string name=\"allow_betas\">اجازه نسخه‌های بتا</string>\n    <string name=\"allow_betas_sub\">در صورت فعال بودن، بررسی به‌روزرسانی شامل نسخه‌های برنامه بتا می‌شود</string>\n    <string name=\"draw_arrows\">نقاشی پیکان‌ها</string>\n    <string name=\"draw_arrows_sub\">اگر فعال باشد مسیر ترسیم به صورت فلش اشاره گر نشان داده می شود</string>\n    <string name=\"brush_softness\">نرمی قلم</string>\n    <string name=\"crop_description\">تصاویر به اندازه وارد شده در مرکز برش داده می شوند. اگر تصویر کوچکتر از ابعاد وارد شده باشد، بوم با رنگ پس زمینه داده شده بزرگ می شود.</string>\n    <string name=\"donation\">کمک مالی</string>\n    <string name=\"image_stitching\">ترکیب تصاویر</string>\n    <string name=\"image_stitching_sub\">تصاویر داده شده را با هم ترکیب کنید تا یک تصویر بزرگ بدست آورید</string>\n    <string name=\"pick_at_least_two_images\">حداقل ۲ تصویر انتخاب کنید</string>\n    <string name=\"output_image_scale\">مقیاس تصویر خروجی</string>\n    <string name=\"image_orientation\">جهت‌گیری تصویر</string>\n    <string name=\"horizontal\">افقی</string>\n    <string name=\"vertical\">عمودی</string>\n    <string name=\"scale_small_images_to_large\">تصاویر کوچک را به بزرگ تبدیل کنید</string>\n    <string name=\"scale_small_images_to_large_sub\">در صورت فعال بودن، تصاویر کوچک به بزرگ‌ترین آن‌ها در توالی مقیاس می‌شوند</string>\n    <string name=\"images_order\">ترتیب تصاویر</string>\n    <string name=\"regular\">عادی</string>\n    <string name=\"blur_edges\">محو کردن لبه‌ها</string>\n    <string name=\"blur_edges_sub\">لبه های تار را زیر تصویر اصلی می کشد تا در صورت فعال بودن، به جای تک رنگ، فضاهای اطراف آن را پر کند</string>\n    <string name=\"pixelation\">پیکسل‌سازی</string>\n    <string name=\"enhanced_pixelation\">پیکسل‌سازی پیشرفته</string>\n    <string name=\"stroke_pixelation\">پیکسل‌سازی خطی</string>\n    <string name=\"enhanced_diamond_pixelation\">پیکسل‌سازی الماسی پیشرفته</string>\n    <string name=\"diamond_pixelation\">پیکسل‌سازی الماسی</string>\n    <string name=\"circle_pixelation\">پیکسل‌سازی دایره‌ای</string>\n    <string name=\"enhanced_circle_pixelation\">پیکسل‌سازی دایره‌ای پیشرفته</string>\n    <string name=\"replace_color\">جایگزینی رنگ</string>\n    <string name=\"tolerance\">تحمل</string>\n    <string name=\"color_to_replace\">رنگ برای جایگزینی</string>\n    <string name=\"target_color\">رنگ هدف</string>\n    <string name=\"color_to_remove\">رنگ برای برداشتن</string>\n    <string name=\"remove_color\">برداشتن رنگ</string>\n    <string name=\"recode\">رمزنگاری مجدد</string>\n    <string name=\"pixel_size\">اندازه پیکسل</string>\n    <string name=\"lock_draw_orientation\">قفل جهت‌گیری نقاشی</string>\n    <string name=\"lock_draw_orientation_sub\">اگر در حالت طراحی فعال باشد، صفحه نمی‌چرخد</string>\n    <string name=\"check_for_updates\">بررسی به‌روزرسانی‌ها</string>\n    <string name=\"palette_style\">سبک تخته‌رنگ</string>\n    <string name=\"tonal_spot\">نقطه تونال</string>\n    <string name=\"neutral\">خنثی</string>\n    <string name=\"vibrant\">پرجنب‌وجوش</string>\n    <string name=\"expressive\">بیانگر</string>\n    <string name=\"rainbow\">رنگین‌کمان</string>\n    <string name=\"fruit_salad\">سالاد میوه</string>\n    <string name=\"content\">محتوا</string>\n    <string name=\"tonal_spot_sub\">سبک پالت پیش‌فرض، امکان سفارشی کردن هر چهار رنگ را فراهم می‌کند، بقیه به شما اجازه می‌دهند فقط رنگ کلید را تنظیم کنید</string>\n    <string name=\"neutral_sub\">سبکی که کمی رنگی تر از تک رنگ است</string>\n    <string name=\"vibrant_sub\">تم بلند، رنگارنگی برای پالت اصلی حداکثر است، برای سایرین افزایش یافته است</string>\n    <string name=\"playful_scheme\">یک تم بازی - رنگ منبع رنگ در طرح زمینه ظاهر نمی شود</string>\n    <string name=\"monochrome_sub\">یک تم تک ، رنگ ها کاملا سیاه / سفید / خاکستری هستند</string>\n    <string name=\"content_sub\">طرحی که رنگ منبع را در Scheme.primaryContainer قرار می دهد</string>\n    <string name=\"fidelity_sub\">طرحی که شباهت زیادی به طرح محتوا دارد</string>\n    <string name=\"foss_update_checker_warning\">این بررسی کننده به روز رسانی به GitHub متصل می شود تا بررسی کند آیا به روز رسانی جدیدی در دسترس است یا خیر</string>\n    <string name=\"attention\">توجه</string>\n    <string name=\"fading_edges\">لبه‌های محو</string>\n    <string name=\"both\">هر دو</string>\n    <string name=\"disabled\">غیرفعال</string>\n    <string name=\"invert_colors\">معکوس کردن رنگ‌ها</string>\n    <string name=\"invert_colors_sub\">در صورت فعال بودن، رنگ های طرح زمینه را با رنگ های منفی جایگزین می کند</string>\n    <string name=\"search_option\">جستجو کردن</string>\n    <string name=\"search_option_sub\">امکان جستجو در تمام ابزار های موجود در صفحه اصلی را فعال می کند</string>\n    <string name=\"pdf_tools\">ابزارهای PDF</string>\n    <string name=\"pdf_tools_sub\">کار با فایل های PDF: پیش نمایش، تبدیل به دسته ای از تصاویر یا ایجاد یکی از تصاویر داده شده</string>\n    <string name=\"preview_pdf\">پیش‌نمایش PDF</string>\n    <string name=\"pdf_to_images\">PDF به تصاویر</string>\n    <string name=\"images_to_pdf\">تصاویر به PDF</string>\n    <string name=\"preview_pdf_sub\">پیش نمایش PDF ساده</string>\n    <string name=\"pdf_to_images_sub\">تبدیل PDF به تصاویر در فرمت خروجی داده شده</string>\n    <string name=\"images_to_pdf_sub\">تصاویر داده شده را در فایل PDF خروجی بسته بندی کنید</string>\n    <string name=\"mask_filter\">پالایه ماسک</string>\n    <string name=\"mask_filter_sub\">زنجیر فیلتر را روی نواحی پوشانده شده اعمال کنید، هر ناحیه ماسک می تواند مجموعه فیلترهای خود را تعیین کند</string>\n    <string name=\"masks\">ماسک‌ها</string>\n    <string name=\"add_mask\">افزودن ماسک</string>\n    <string name=\"mask_indexed\">ماسک %d</string>\n    <string name=\"mask_color\">رنگ ماسک</string>\n    <string name=\"mask_preview\">پیش‌نمایش ماسک</string>\n    <string name=\"mask_preview_sub\">ماسک فیلتر کشیده شده برای نشان دادن نتیجه تقریبی به شما ارائه می شود</string>\n    <string name=\"inverse_fill_type\">نوع پر کردن معکوس</string>\n    <string name=\"inverse_fill_type_sub\">اگر فعال باشد، به جای رفتار پیش‌فرض، تمام مناطق بدون ماسک فیلتر می‌شوند</string>\n    <string name=\"delete_mask_warn\">شما در حال حذف ماسک فیلتر انتخابی هستید. این عملیات قابل برگشت نیست</string>\n    <string name=\"delete_mask\">حذف ماسک</string>\n    <string name=\"full_filter\">پالایه کامل</string>\n    <string name=\"full_filter_sub\">هر زنجیره فیلتر را روی تصاویر داده شده یا تک تصویر اعمال کنید</string>\n    <string name=\"start_position\">شروع کنید</string>\n    <string name=\"center_position\">مرکز</string>\n    <string name=\"end_position\">پایان</string>\n    <string name=\"simple_variants\">انواع ساده</string>\n    <string name=\"highlighter\">هایلایتر</string>\n    <string name=\"neon\">نئون</string>\n    <string name=\"pen\">قلم</string>\n    <string name=\"privacy_blur\">محو حریم خصوصی</string>\n    <string name=\"highlighter_sub\">مسیرهای هایلایتر تیز شده نیمه شفاف را رسم کنید</string>\n    <string name=\"neon_sub\">جلوه ای درخشان به نقاشی های خود اضافه کنید</string>\n    <string name=\"pen_sub\">پیش‌فرض، ساده‌ترین - فقط رنگ</string>\n    <string name=\"privacy_blur_sub\">تصویر زیر مسیر ترسیم شده را محو می کند تا هر چیزی را که می خواهید پنهان کنید ایمن کنید</string>\n    <string name=\"pixelation_sub\">شبیه محو کردن حریم خصوصی است، اما به جای محو کردن، پیکسل می‌شود</string>\n    <string name=\"containers_shadow\">ظروف</string>\n    <string name=\"containers_shadow_sub\">طراحی سایه پشت کانتینرها را فعال می کند</string>\n    <string name=\"sliders_shadow\">لغزنده</string>\n    <string name=\"switches_shadow\">سوئیچ ها</string>\n    <string name=\"fabs_shadow\">FAB ها</string>\n    <string name=\"buttons_shadow\">دکمه ها</string>\n    <string name=\"sliders_shadow_sub\">طراحی سایه پشت لغزنده را فعال می کند</string>\n    <string name=\"switches_shadow_sub\">طراحی سایه پشت سوئیچ ها را فعال می کند</string>\n    <string name=\"fabs_shadow_sub\">طراحی سایه پشت دکمه‌های عمل شناور را فعال می‌کند</string>\n    <string name=\"buttons_shadow_sub\">طراحی سایه پشت دکمه های پیش فرض را فعال می کند</string>\n    <string name=\"app_bars_shadow\">نوارهای برنامه</string>\n    <string name=\"app_bars_shadow_sub\">طراحی سایه در پشت نوارهای برنامه را فعال می کند</string>\n    <string name=\"value_in_range\">مقدار در محدوده %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">چرخش خودکار</string>\n    <string name=\"auto_rotate_limits_sub\">اجازه می دهد تا جعبه محدودیت برای جهت گیری تصویر اتخاذ شود</string>\n    <string name=\"draw_path_mode\">حالت مسیر نقاشی</string>\n    <string name=\"double_line_arrow\">پیکان خط دو سویه</string>\n    <string name=\"free_drawing\">نقاشی آزاد</string>\n    <string name=\"double_arrow\">پیکان دو سویه</string>\n    <string name=\"line_arrow\">پیکان خطی</string>\n    <string name=\"arrow\">پیکان</string>\n    <string name=\"line\">خط</string>\n    <string name=\"free_drawing_sub\">مسیر را به عنوان مقدار ورودی ترسیم می کند</string>\n    <string name=\"line_sub\">مسیر را از نقطه شروع به نقطه پایان به عنوان یک خط رسم می کند</string>\n    <string name=\"line_arrow_sub\">فلش اشاره گر را از نقطه شروع به نقطه پایان به عنوان یک خط رسم می کند</string>\n    <string name=\"arrow_sub\">فلش اشاره گر را از یک مسیر مشخص می کشد</string>\n    <string name=\"double_line_arrow_sub\">فلش های دوگانه را از نقطه شروع به نقطه پایان به عنوان یک خط رسم می کند</string>\n    <string name=\"double_arrow_sub\">فلش های دو نشان دهنده را از یک مسیر مشخص می کشد</string>\n    <string name=\"outlined_oval\">بیضی خطی</string>\n    <string name=\"outlined_rect\">مستطیل خطی</string>\n    <string name=\"oval\">بیضی</string>\n    <string name=\"rect\">مستطیل</string>\n    <string name=\"rect_sub\">راست را از نقطه شروع به نقطه پایان رسم می کند</string>\n    <string name=\"oval_sub\">بیضی شکل را از نقطه شروع تا نقطه پایان ترسیم می کند</string>\n    <string name=\"outlined_oval_sub\">بیضی شکل را از نقطه شروع تا نقطه پایان ترسیم می کند</string>\n    <string name=\"outlined_rect_sub\">رئوس مطالب را از نقطه شروع تا پایان رسم می کند</string>\n    <string name=\"lasso\">طناب</string>\n    <string name=\"lasso_sub\">مسیر پر بسته را بر اساس مسیر داده شده ترسیم می کند</string>\n    <string name=\"free\">آزاد</string>\n    <string name=\"horizontal_grid\">شبکه افقی</string>\n    <string name=\"vertical_grid\">شبکه عمودی</string>\n    <string name=\"stitch_mode\">حالت ترکیب</string>\n    <string name=\"rows_count\">تعداد ردیف‌ها</string>\n    <string name=\"columns_count\">تعداد ستون‌ها</string>\n    <string name=\"no_such_directory\">دایرکتوری \\\"%1$s\\\" یافت نشد، ما آن را به یک فهرست پیش فرض تغییر دادیم، لطفاً فایل را دوباره ذخیره کنید</string>\n    <string name=\"clipboard\">بریده‌دان</string>\n    <string name=\"auto_pin\">سنجاق خودکار</string>\n    <string name=\"auto_pin_sub\">در صورت فعال بودن، به طور خودکار تصویر ذخیره شده را به کلیپ بورد اضافه می کند</string>\n    <string name=\"vibration\">لرزش</string>\n    <string name=\"vibration_strength\">قدرت لرزش</string>\n    <string name=\"overwrite_file_requirements\">برای بازنویسی فایل‌ها باید از منبع تصویر \\\"Explorer\\\" استفاده کنید، تصاویر را دوباره انتخاب کنید، ما منبع تصویر را به منبع مورد نیاز تغییر داده‌ایم</string>\n    <string name=\"overwrite_files\">بازنویسی پرونده‌ها</string>\n    <string name=\"overwrite_files_sub\">فایل اصلی به جای ذخیره در پوشه انتخابی با فایل جدید جایگزین می شود، این گزینه باید منبع تصویر \\\"Explorer\\\" یا GetContent باشد، در صورت تغییر دادن این، به طور خودکار تنظیم می شود.</string>\n    <string name=\"empty\">خالی</string>\n    <string name=\"suffix\">پسوند</string>\n    <string name=\"scale_mode\">حالت مقیاس</string>\n    <string name=\"bilinear\">دوخطی</string>\n    <string name=\"catmull\">کت‌مال</string>\n    <string name=\"bicubic\">دومکعبی</string>\n    <string name=\"hann\">هان</string>\n    <string name=\"hermite\">هرمیت</string>\n    <string name=\"lanczos\">لانکزوس</string>\n    <string name=\"mitchell\">میچل</string>\n    <string name=\"nearest\">نزدیک‌ترین</string>\n    <string name=\"spline\">منحنی</string>\n    <string name=\"basic\">پایه</string>\n    <string name=\"default_value\">مقدار پیش‌فرض</string>\n    <string name=\"bilinear_sub\">درون یابی خطی (یا دو خطی، در دو بعدی) معمولاً برای تغییر اندازه یک تصویر خوب است، اما باعث نرم شدن نامطلوب جزئیات می شود و هنوز هم می تواند تا حدودی ناهموار باشد.</string>\n    <string name=\"bicubic_sub\">روش‌های مقیاس‌بندی بهتر شامل نمونه‌برداری مجدد Lanczos و فیلترهای Mitchell-Netravali است</string>\n    <string name=\"nearest_sub\">یکی از راه‌های ساده‌تر افزایش اندازه، جایگزینی هر پیکسل با تعدادی پیکسل همرنگ</string>\n    <string name=\"basic_sub\">ساده‌ترین حالت مقیاس‌بندی اندروید که تقریباً در همه برنامه‌ها استفاده می‌شود</string>\n    <string name=\"catmull_sub\">روشی برای درونیابی هموار و نمونه برداری مجدد مجموعه ای از نقاط کنترل که معمولاً در گرافیک کامپیوتری برای ایجاد منحنی های صاف استفاده می شود.</string>\n    <string name=\"hann_sub\">تابع پنجره اغلب در پردازش سیگنال برای به حداقل رساندن نشت طیفی و بهبود دقت تجزیه و تحلیل فرکانس با باریک کردن لبه‌های سیگنال استفاده می‌شود.</string>\n    <string name=\"hermite_sub\">تکنیک درون یابی ریاضی که از مقادیر و مشتقات در نقاط انتهایی یک بخش منحنی برای ایجاد یک منحنی صاف و پیوسته استفاده می کند.</string>\n    <string name=\"lanczos_sub\">روش نمونه گیری مجدد که درون یابی با کیفیت بالا را با اعمال تابع sinc وزنی به مقادیر پیکسل حفظ می کند.</string>\n    <string name=\"mitchell_sub\">روش نمونه برداری مجدد که از فیلتر پیچشی با پارامترهای قابل تنظیم برای دستیابی به تعادل بین وضوح و ضد aliasing در تصویر مقیاس شده استفاده می کند.</string>\n    <string name=\"spline_sub\">از توابع چند جمله ای تعریف شده تکه ای برای درون یابی و تقریب هموار یک منحنی یا سطح، نمایش شکل انعطاف پذیر و پیوسته استفاده می کند.</string>\n    <string name=\"only_clip\">فقط برش</string>\n    <string name=\"only_clip_sub\">ذخیره در فضای ذخیره سازی انجام نمی شود و سعی می شود تصویر فقط در کلیپ بورد قرار داده شود</string>\n    <string name=\"restore_background_sub\">براش به جای پاک کردن پس زمینه را بازیابی می کند</string>\n    <string name=\"recognize_text_sub\">تشخیص متن از تصویر داده شده، بیش از 120 زبان پشتیبانی می شود</string>\n    <string name=\"picture_has_no_text\">تصویر متنی ندارد یا برنامه آن را پیدا نکرده است</string>\n    <string name=\"accuracy\">دقت: %1$s</string>\n    <string name=\"recognition_type\">نوع تشخیص</string>\n    <string name=\"fast\">سریع</string>\n    <string name=\"standard\">استاندارد</string>\n    <string name=\"no_data\">بدون داده</string>\n    <string name=\"download_description\">برای عملکرد صحیح Tesseract OCR باید داده های آموزشی اضافی (%1$s) در دستگاه شما دانلود شود. \\nآیا می خواهید داده های %2$s را دانلود کنید؟</string>\n    <string name=\"download\">بارگیری</string>\n    <string name=\"no_connection\">بدون اتصال، آن را بررسی کنید و دوباره برای بارگیری مدل‌های آموزشی تلاش کنید</string>\n    <string name=\"downloaded_languages\">زبان‌های بارگیری‌شده</string>\n    <string name=\"available_languages\">زبان‌های در دسترس</string>\n    <string name=\"segmentation_mode\">حالت تقسیم‌بندی</string>\n    <string name=\"use_pixel_switch\">استفاده از کلید شبیه پیکسل گوگل</string>\n    <string name=\"use_pixel_switch_sub\">از یک سوئیچ شبیه به گوگل پیکسل استفاده می‌کند</string>\n    <string name=\"saved_to_original\">فایل بازنویسی شده با نام %1$s در مقصد اصلی</string>\n    <string name=\"magnifier\">ذره‌بین</string>\n    <string name=\"magnifier_sub\">برای دسترسی بهتر، ذره بین را در بالای انگشت در حالت های طراحی فعال می کند</string>\n    <string name=\"force_exif_widget_initial_value\">اجباری مقدار اولیه</string>\n    <string name=\"force_exif_widget_initial_value_sub\">ویجت exif را وادار می کند که در ابتدا بررسی شود</string>\n    <string name=\"allow_multiple_languages\">اجازه چندین زبان</string>\n    <string name=\"slide\">لغزش</string>\n    <string name=\"side_by_side\">کنار هم</string>\n    <string name=\"toggle_tap\">ضربه برای تغییر</string>\n    <string name=\"transparency\">شفافیت</string>\n    <string name=\"rate_app\">امتیاز دادن به برنامه</string>\n    <string name=\"rate_app_sub\">این برنامه کاملا رایگان است، اگر می خواهید بزرگتر شود، لطفا پروژه را در Github ستاره دار کنید 😄</string>\n    <string name=\"segmentation_mode_osd_only\">جهت &amp; فقط تشخیص اسکریپت</string>\n    <string name=\"segmentation_mode_auto_osd\">جهت گیری خودکار &amp; تشخیص اسکریپت</string>\n    <string name=\"segmentation_mode_auto_only\">فقط خودکار</string>\n    <string name=\"segmentation_mode_auto\">خودکار</string>\n    <string name=\"segmentation_mode_single_column\">تک ستونی</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">متن عمودی تک بلوکی</string>\n    <string name=\"segmentation_mode_single_block\">تک بلوک</string>\n    <string name=\"segmentation_mode_single_line\">تک خط</string>\n    <string name=\"segmentation_mode_single_word\">تک کلمه</string>\n    <string name=\"segmentation_mode_circle_word\">دور کلمه</string>\n    <string name=\"segmentation_mode_single_char\">کاراکتر تک</string>\n    <string name=\"segmentation_mode_sparse_text\">متن پراکنده</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">جهت متن پراکنده &amp; تشخیص اسکریپت</string>\n    <string name=\"segmentation_mode_raw_line\">خط خام</string>\n    <string name=\"delete_language_sub\">آیا می‌خواهید داده‌های آموزش OCR زبان \\\"%1$s\\\" را برای همه انواع تشخیص حذف کنید یا فقط برای یک انتخاب شده (%2$s)؟</string>\n    <string name=\"current\">جاری</string>\n    <string name=\"all\">همه</string>\n    <string name=\"gradient_maker\">سازنده شیب</string>\n    <string name=\"gradient_maker_sub\">شیب اندازه خروجی داده شده را با رنگ های سفارشی و نوع ظاهر ایجاد کنید</string>\n    <string name=\"gradient_type_linear\">خطی</string>\n    <string name=\"gradient_type_radial\">شعاعی</string>\n    <string name=\"gradient_type_sweep\">جارو کردن</string>\n    <string name=\"gradient_type\">نوع شیب</string>\n    <string name=\"center_x\">مرکز X</string>\n    <string name=\"center_y\">مرکز Y</string>\n    <string name=\"tile_mode\">حالت کاشی</string>\n    <string name=\"tile_mode_repeated\">تکرار شد</string>\n    <string name=\"tile_mode_mirror\">آینه</string>\n    <string name=\"tile_mode_clamp\">گیره</string>\n    <string name=\"tile_mode_decal\">برگردان</string>\n    <string name=\"properties\">ویژگی‌ها</string>\n    <string name=\"brightness_enforcement\">اجرای روشنایی</string>\n    <string name=\"screen\">صفحه</string>\n    <string name=\"gradient_maker_type_image\">همپوشانی گرادیان</string>\n    <string name=\"gradient_maker_type_image_sub\">هر شیب بالای تصاویر داده شده را بنویسید</string>\n    <string name=\"transformations\">تبدیل‌ها</string>\n    <string name=\"camera\">دوربین</string>\n    <string name=\"camera_sub\">گرفتن یک عکس با استفاده از دوربین، توجه داشته باشید که دریافت تنها یک تصویر از این منبع تصویر امکان پذیر است</string>\n    <string name=\"watermarking\">علامت‌گذاری</string>\n    <string name=\"watermarking_sub\">تصاویر را با واترمارک های متنی/تصویر قابل تنظیم بپوشانید</string>\n    <string name=\"repeat_watermark\">تکرار علامت</string>\n    <string name=\"repeat_watermark_sub\">واترمارک را روی تصویر به جای تک در موقعیت مشخص تکرار می کند</string>\n    <string name=\"offset_x\">اختلاف X</string>\n    <string name=\"offset_y\">اختلاف Y</string>\n    <string name=\"watermark_type\">نوع علامت</string>\n    <string name=\"watermarking_image_sub\">این تصویر به عنوان الگو برای واترمارک استفاده خواهد شد</string>\n    <string name=\"text_color\">رنگ متن</string>\n    <string name=\"overlay_mode\">حالت پوشش</string>\n    <string name=\"gif_tools\">ابزارهای GIF</string>\n    <string name=\"gif_tools_sub\">تصاویر را به تصویر GIF تبدیل کنید یا فریم هایی را از تصویر GIF داده شده استخراج کنید</string>\n    <string name=\"gif_type_to_image\">GIF به تصاویر</string>\n    <string name=\"gif_type_to_image_sub\">تبدیل فایل GIF به دسته ای از تصاویر</string>\n    <string name=\"gif_type_to_gif_sub\">تبدیل دسته ای از تصاویر به فایل GIF</string>\n    <string name=\"gif_type_to_gif\">تصاویر به GIF</string>\n    <string name=\"select_gif_image_to_start\">برای شروع تصویر GIF را انتخاب کنید</string>\n    <string name=\"use_size_of_first_frame\">از اندازه فریم اول استفاده کنید</string>\n    <string name=\"use_size_of_first_frame_sub\">اندازه مشخص شده را با ابعاد قاب اول جایگزین کنید</string>\n    <string name=\"repeat_count\">تعداد تکرار</string>\n    <string name=\"frame_delay\">تاخیر فریم</string>\n    <string name=\"use_lasso_sub\">از Lasso مانند در حالت ترسیم برای انجام پاک کردن استفاده می کند</string>\n    <string name=\"original_image_preview_alpha\">آلفای پیش‌نمایش تصویر اصلی</string>\n    <string name=\"confetti\">کاغذ رنگی</string>\n    <string name=\"confetti_sub\">Confetti در ذخیره، اشتراک گذاری و سایر اقدامات اولیه نشان داده می شود</string>\n    <string name=\"secure_mode_sub\">محتوای برنامه را در برنامه‌های اخیر پنهان می‌کند. نمی‌توان آن را ضبط یا ثبت کرد.</string>\n    <string name=\"exit\">خروج</string>\n    <string name=\"preview_closing\">اگر اکنون پیش‌نمایش را ترک کنید، باید دوباره تصاویر را اضافه کنید</string>\n    <string name=\"dithering\">دیترینگ</string>\n    <string name=\"quantizier\">کوانتیزر</string>\n    <string name=\"gray_scale\">مقیاس خاکستری</string>\n    <string name=\"bayer_two_dithering\">بایر دو در دو دیترینگ</string>\n    <string name=\"bayer_three_dithering\">بایر سه در سه دیترینگ</string>\n    <string name=\"bayer_four_dithering\">بایر چهار با چهار دیترینگ</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">دیترینگ فلویید-اشتاینبرگ</string>\n    <string name=\"jarvis_judice_ninke_dithering\">دیترینگ جارویس-جودیس-نینکه</string>\n    <string name=\"sierra_dithering\">دیترینگ سیرا</string>\n    <string name=\"two_row_sierra_dithering\">دیترینگ سیرا دو ردیفه</string>\n    <string name=\"sierra_lite_dithering\">دیترینگ سیرا لایت</string>\n    <string name=\"atkinson_dithering\">دیترینگ اتکینسون</string>\n    <string name=\"stucki_dithering\">دیترینگ استوکی</string>\n    <string name=\"burkes_dithering\">دیترینگ بورکس</string>\n    <string name=\"false_floyd_steinberg_dithering\">دیترینگ فلویید-اشتاینبرگ کاذب</string>\n    <string name=\"left_to_right_dithering\">دیترینگ چپ به راست</string>\n    <string name=\"random_dithering\">دیترینگ تصادفی</string>\n    <string name=\"simple_threshold_dithering\">دیترینگ آستانه ساده</string>\n    <string name=\"sigma\">سیگما</string>\n    <string name=\"spatial_sigma\">سیگمای فضایی</string>\n    <string name=\"b_spline\">منحنی-ب</string>\n    <string name=\"b_spline_sub\">از توابع چند جمله ای دو مکعبی تعریف شده تکه ای برای درون یابی و تقریب هموار یک منحنی یا سطح، نمایش شکل انعطاف پذیر و پیوسته استفاده می کند.</string>\n    <string name=\"native_stack_blur\">محو پشته‌ای بومی</string>\n    <string name=\"tilt_shift\">تغییر شیب</string>\n    <string name=\"glitch\">گلیچ</string>\n    <string name=\"amount\">مقدار</string>\n    <string name=\"seed\">دانه</string>\n    <string name=\"anaglyph\">آناگلیف</string>\n    <string name=\"noise\">نویز</string>\n    <string name=\"pixel_sort\">مرتب‌سازی پیکسل</string>\n    <string name=\"shuffle\">مخلوط کردن</string>\n    <string name=\"enhanced_glitch\">گلیچ پیشرفته</string>\n    <string name=\"channel_shift_x\">جابه‌جایی کانال X</string>\n    <string name=\"channel_shift_y\">جابه‌جایی کانال Y</string>\n    <string name=\"corruption_size\">اندازه خرابی</string>\n    <string name=\"corruption_shift_x\">جابه‌جایی خرابی X</string>\n    <string name=\"corruption_shift_y\">جابه‌جایی خرابی Y</string>\n    <string name=\"tent_blur\">محو چادری</string>\n    <string name=\"side_fade\">محو کناری</string>\n    <string name=\"side\">کنار</string>\n    <string name=\"top\">بالا</string>\n    <string name=\"bottom\">پایین</string>\n    <string name=\"strength\">قدرت</string>\n    <string name=\"erode\">فرسایش</string>\n    <string name=\"anisotropic_diffusion\">انتشار ناهمسان</string>\n    <string name=\"diffusion\">انتشار</string>\n    <string name=\"conduction\">هدایت</string>\n    <string name=\"horizontal_wind_stagger\">لرزش باد افقی</string>\n    <string name=\"fast_bilaterial_blur\">تاری دوطرفه سریع</string>\n    <string name=\"poisson_blur\">محو پواسون</string>\n    <string name=\"logarithmic_tone_mapping\">نقشه‌برداری تون لگاریتمی</string>\n    <string name=\"aces_filmic_tone_mapping\">نقشه‌برداری تون فیلمک ACES</string>\n    <string name=\"crystallize\">متبلور کردن</string>\n    <string name=\"stroke_color\">رنگ خط</string>\n    <string name=\"fractal_glass\">شیشه ناصاف</string>\n    <string name=\"turbulence\">آشوب</string>\n    <string name=\"oil\">روغن</string>\n    <string name=\"water_effect\">جلوه آب</string>\n    <string name=\"just_size\">اندازه</string>\n    <string name=\"frequency_x\">فرکانس X</string>\n    <string name=\"frequency_y\">فرکانس Y</string>\n    <string name=\"amplitude_x\">دامنه X</string>\n    <string name=\"amplitude_y\">دامنه Y</string>\n    <string name=\"perlin_distortion\">اعوجاج پرلین</string>\n    <string name=\"aces_hill_tone_mapping\">نقشه‌برداری تون هیل ACES</string>\n    <string name=\"hable_filmic_tone_mapping\">نقشه‌برداری تون فیلمک هابل</string>\n    <string name=\"heji_burgess_tone_mapping\">نقشه‌برداری تون هجی-بورگس</string>\n    <string name=\"speed\">سرعت</string>\n    <string name=\"dehaze\">مه‌زدایی</string>\n    <string name=\"omega\">امگا</string>\n    <string name=\"color_matrix_4x4\">ماتریس رنگ ۴×۴</string>\n    <string name=\"polaroid\">عکس فوری</string>\n    <string name=\"tritonomaly\">آبی‌دشواربینی</string>\n    <string name=\"deutaromaly\">سبزدشواربینی</string>\n    <string name=\"protonomaly\">قرمز دشواربینی</string>\n    <string name=\"vintage\">قدیمی</string>\n    <string name=\"browni\">شکلاتی</string>\n    <string name=\"coda_chrome\">کودا کروم</string>\n    <string name=\"night_vision\">دید در شب</string>\n    <string name=\"warm\">گرم</string>\n    <string name=\"cool\">خنک</string>\n    <string name=\"tritanopia\">آبی‌ کوری</string>\n    <string name=\"deutaronotopia\">سبزکوری</string>\n    <string name=\"protanopia\">سرخ کوری</string>\n    <string name=\"achromatomaly\">شبه کور رنگی</string>\n    <string name=\"achromatopsia\">کور رنگی</string>\n    <string name=\"grain\">دانه</string>\n    <string name=\"unsharp\">نا تیز</string>\n    <string name=\"pastel\">پاستل</string>\n    <string name=\"orange_haze\">مه نارنجی</string>\n    <string name=\"pink_dream\">رؤیای صورتی</string>\n    <string name=\"golden_hour\">ساعت طلایی</string>\n    <string name=\"hot_summer\">تابستان گرم</string>\n    <string name=\"purple_mist\">مه بنفش</string>\n    <string name=\"sunrise\">طلوع آفتاب</string>\n    <string name=\"colorful_swirl\">چرخش رنگارنگ</string>\n    <string name=\"soft_spring_light\">نور بهاری نرم</string>\n    <string name=\"autumn_tones\">تون‌های پاییزی</string>\n    <string name=\"lavender_dream\">رؤیای اسطوخودوس</string>\n    <string name=\"cyberpunk\">سایبرپانک</string>\n    <string name=\"lemonade_light\">نور لیموناد</string>\n    <string name=\"spectral_fire\">آتش طیفی</string>\n    <string name=\"night_magic\">جادوی شب</string>\n    <string name=\"fantasy_landscape\">چشم‌انداز فانتزی</string>\n    <string name=\"color_explosion\">انفجار رنگ</string>\n    <string name=\"electric_gradient\">شیب الکتریکی</string>\n    <string name=\"caramel_darkness\">تاریکی کارامل</string>\n    <string name=\"futuristic_gradient\">شیب آینده‌نگر</string>\n    <string name=\"green_sun\">خورشید سبز</string>\n    <string name=\"rainbow_world\">جهان رنگین‌کمان</string>\n    <string name=\"deep_purple\">بنفش عمیق</string>\n    <string name=\"space_portal\">پورتال فضایی</string>\n    <string name=\"red_swirl\">چرخش قرمز</string>\n    <string name=\"digital_code\">کد دیجیتال</string>\n    <string name=\"bokeh\">بوکه</string>\n    <string name=\"random_emojis_sub\">ایموجی نوار برنامه به صورت تصادفی تغییر خواهد کرد</string>\n    <string name=\"random_emojis\">شکلک‌های تصادفی</string>\n    <string name=\"random_emojis_error\">در حالی که ایموجی‌ها غیرفعال هستند، نمی‌توانید از ایموجی‌های تصادفی استفاده کنید</string>\n    <string name=\"emoji_selection_error\">نمیتوانید شکلک را انتخاب کنید در حالی که شکلک‌های تصادفی فعال هستند</string>\n    <string name=\"old_tv\">تلویزیون قدیمی</string>\n    <string name=\"shuffle_blur\">محو شافل</string>\n    <string name=\"favorite\">برگزیدن</string>\n    <string name=\"no_favorite_filters\">هنوز هیچ پالایه برگزیده‌ای اضافه نشده است</string>\n    <string name=\"image_format\">قالب تصویر</string>\n    <string name=\"icon_shape_sub\">یک ظرف با شکل انتخاب شده در زیر آیکون‌ها اضافه می‌کند</string>\n    <string name=\"icon_shape\">شکل نماد</string>\n    <string name=\"drago\">دراگو</string>\n    <string name=\"aldridge\">آلدریج</string>\n    <string name=\"cutoff\">کات‌آف</string>\n    <string name=\"uchimura\">اوچیمورا</string>\n    <string name=\"mobius\">موبیوس</string>\n    <string name=\"transition\">انتقال</string>\n    <string name=\"peak\">پیک</string>\n    <string name=\"color_anomaly\">ناهنجاری رنگ</string>\n    <string name=\"images_overwritten\">تصاویر در مقصد اصلی بازنویسی شدند</string>\n    <string name=\"cannot_change_image_format\">وقتی گزینه بازنویسی فایل ها فعال است، قالب تصویر را نمی توان تغییر داد</string>\n    <string name=\"emoji_as_color_scheme\">شکلک به‌عنوان طرح رنگی</string>\n    <string name=\"emoji_as_color_scheme_sub\">از رنگ اصلی ایموجی به‌عنوان طرح رنگ برنامه به‌جای تعریف دستی استفاده می‌کند</string>\n    <string name=\"material_you_sub\">پالت \\\"Material You\\\" را از تصویر ایجاد می کند</string>\n    <string name=\"dark_colors\">رنگ‌های تیره</string>\n    <string name=\"dark_colors_sub\">از طرح رنگ حالت شب به جای نوع نور استفاده می کند</string>\n    <string name=\"copy_as_compose_code\">کپی به عنوان\\\" Jetpack Compose \\\" کد</string>\n    <string name=\"ring_blur\">محو حلقه‌ای</string>\n    <string name=\"cross_blur\">محو صلیبی</string>\n    <string name=\"circle_blur\">محو دایره‌ای</string>\n    <string name=\"star_blur\">محو ستاره‌ای</string>\n    <string name=\"linear_tilt_shift\">تغییر شیب خطی</string>\n    <string name=\"tags_to_remove\">برچسب‌های برای حذف</string>\n    <string name=\"apng_tools_sub\">تصاویر را به تصویر APNG تبدیل کنید یا فریم هایی را از تصویر APNG داده شده استخراج کنید</string>\n    <string name=\"apng_tools\">ابزارهای APNG</string>\n    <string name=\"apng_type_to_image\">APNG به تصاویر</string>\n    <string name=\"apng_type_to_image_sub\">تبدیل فایل APNG به دسته ای از تصاویر</string>\n    <string name=\"apng_type_to_apng_sub\">تبدیل دسته ای از تصاویر به APNG</string>\n    <string name=\"apng_type_to_apng\">تصاویر به APNG</string>\n    <string name=\"select_apng_image_to_start\">برای شروع تصاویر APNG را انتخاب کنید</string>\n    <string name=\"motion_blur\">محو حرکتی</string>\n    <string name=\"zip\">زیپ</string>\n    <string name=\"zip_sub\">ساخت فایل Zip از تصاویر یا فایل داده شده</string>\n    <string name=\"confetti_type\">نوع کنفتی</string>\n    <string name=\"festive\">جشنواره‌ای</string>\n    <string name=\"explode\">انفجار</string>\n    <string name=\"rain\">باران</string>\n    <string name=\"try_again\">دوباره تلاش کنید</string>\n    <string name=\"show_settings_in_landscape\">نمایش تنظیمات در حالت افقی</string>\n    <string name=\"show_settings_in_landscape_sub\">اگر این غیرفعال باشد، تنظیمات حالت افقی مانند همیشه به جای گزینه قابل مشاهده دائم، روی دکمه در نوار بالای برنامه باز می شود.</string>\n    <string name=\"jxl_tools\">ابزارهای JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL به JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">رمزگذاری بدون اتلاف از JXL به JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">رمزگذاری بدون اتلاف از JPEG به JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG به JXL</string>\n    <string name=\"select_jxl_image_to_start\">برای شروع تصاویر JXL را انتخاب کنید</string>\n    <string name=\"reset_properties_sub\">همه ویژگی ها روی مقادیر پیش فرض تنظیم می شوند، توجه داشته باشید که این عمل قابل واگرد نیست</string>\n    <string name=\"pick\">انتخاب</string>\n    <string name=\"fullscreen_settings\">تنظیمات تمام‌صفحه</string>\n    <string name=\"fullscreen_settings_sub\">آن را فعال کنید و صفحه تنظیمات همیشه به‌جای برگه کشویی به‌صورت تمام‌صفحه باز می‌شود</string>\n    <string name=\"switch_type\">نوع کلید</string>\n    <string name=\"compose\">کامپوز</string>\n    <string name=\"pick_multiple_media\">انتخاب چند رسانه</string>\n    <string name=\"pick_single_media\">انتخاب رسانه تکی</string>\n    <string name=\"corners\">گوشه‌ها</string>\n    <string name=\"jxl_tools_sub\">رمزگذاری JXL ~ JPEG را بدون افت کیفیت انجام دهید یا انیمیشن GIF/APNG را به JXL تبدیل کنید</string>\n    <string name=\"fast_gaussian_blur_3d\">محو گاوسی سریع سه‌بعدی</string>\n    <string name=\"harmonization_level\">سطح هماهنگ‌سازی</string>\n    <string name=\"jxl_type_to_jxl\">تصاویر به JXL</string>\n    <string name=\"skip_file_picking\">رد کردن انتخاب پرونده</string>\n    <string name=\"skip_file_picking_sub\">در صورت امکان، انتخابگر فایل بلافاصله در صفحه انتخاب شده نشان داده می شود</string>\n    <string name=\"fast_gaussian_blur_4d\">محو گاوسی سریع چهاربعدی</string>\n    <string name=\"generate_previews_sub\">تولید پیش‌نمایش را فعال می‌کند، ممکن است به جلوگیری از خرابی در برخی دستگاه‌ها کمک کند، همچنین برخی از قابلیت‌های ویرایش را در گزینه ویرایش واحد غیرفعال می‌کند.</string>\n    <string name=\"lossy_compression\">فشرده‌سازی با افت</string>\n    <string name=\"lossy_compression_sub\">از فشرده سازی با اتلاف برای کاهش حجم فایل به جای فشرده سازی بدون اتلاف استفاده می کند</string>\n    <string name=\"speed_sub\">نوع فشرده‌سازی سرعت رمزگشایی تصویر حاصل را کنترل می‌کند، این باید به باز کردن سریع‌تر تصویر حاصل کمک کند، مقدار %1$s به معنای کندترین رمزگشایی است، در حالی که %2$s - سریع‌ترین، این تنظیم ممکن است اندازه تصویر خروجی را افزایش دهد.</string>\n    <string name=\"compression_type\">نوع فشرده‌سازی</string>\n    <string name=\"header_today\">امروز</string>\n    <string name=\"header_yesterday\">دیروز</string>\n    <string name=\"sort_by_date_reversed\">تاریخ (معکوس)</string>\n    <string name=\"no_permissions\">بدون دسترسی</string>\n    <string name=\"request\">درخواست</string>\n    <string name=\"images_to_svg_sub\">تبدیل تصاویر داده شده به تصاویر SVG</string>\n    <string name=\"use_sampled_palette\">استفاده از تخته‌رنگ نمونه‌برداری‌شده</string>\n    <string name=\"svg_warning\">استفاده از این ابزار برای ردیابی تصاویر بزرگ بدون کاهش مقیاس توصیه نمی شود، می تواند باعث کرش و افزایش زمان پردازش شود.</string>\n    <string name=\"material_you_switch_sub\">کلید Material You</string>\n    <string name=\"fast_gaussian_blur_2d\">محو گاوسی سریع دوبعدی</string>\n    <string name=\"max\">حداکثر</string>\n    <string name=\"resize_anchor\">لنگر تغییر اندازه</string>\n    <string name=\"pixel_switch\">پیکسل</string>\n    <string name=\"fluent_switch\">روان</string>\n    <string name=\"fluent_switch_sub\">از سوییچ سبک ویندوز 11 بر اساس سیستم طراحی \\\"Fluent\\\" استفاده می کند</string>\n    <string name=\"cupertino_switch_sub\">از سوئیچ مانند iOS بر اساس سیستم طراحی کوپرتینو استفاده می کند</string>\n    <string name=\"channels_configuration\">پیکربندی کانال‌ها</string>\n    <string name=\"embedded_picker\">انتخاب‌گر تصویر جعبه‌ابزار تصویر</string>\n    <string name=\"embedded_picker_sub\">انتخابگر تصویر در Image Toolbox</string>\n    <string name=\"auto_paste\">جای‌گذاری خودکار</string>\n    <string name=\"auto_paste_sub\">به برنامه اجازه می‌دهد تا داده‌های کلیپ‌بورد را به‌طور خودکار جای‌گذاری کند، بنابراین در صفحه اصلی ظاهر می‌شود و می‌توانید آن‌ها را پردازش کنید.</string>\n    <string name=\"harmonization_color\">رنگ هماهنگ‌سازی</string>\n    <string name=\"lanczos_bessel_sub\">روش نمونه‌گیری مجدد که درون یابی با کیفیت بالا را با اعمال تابع Bessel (jinc) به مقادیر پیکسل حفظ می‌کند.</string>\n    <string name=\"gif_type_to_jxl\">GIF به JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">تبدیل تصاویر GIF به تصاویر متحرک JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG به JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">تبدیل تصاویر APNG به تصاویر متحرک JXL</string>\n    <string name=\"jxl_type_to_images\">JXL به تصاویر</string>\n    <string name=\"jxl_type_to_images_sub\">تبدیل انمیشن JXL به دسته ای از تصاویر</string>\n    <string name=\"jxl_type_to_jxl_sub\">تبدیل دسته ای از تصاویر به انیمیشن JXL</string>\n    <string name=\"behavior\">رفتار</string>\n    <string name=\"generate_previews\">تولید پیش‌نمایش‌ها</string>\n    <string name=\"sorting\">مرتب‌سازی</string>\n    <string name=\"sort_by_date\">تاریخ</string>\n    <string name=\"sort_by_name\">نام</string>\n    <string name=\"sort_by_name_reversed\">نام (معکوس)</string>\n    <string name=\"images_to_svg\">تصاویر به SVG</string>\n    <string name=\"use_sampled_palette_sub\">اگر این گزینه فعال باشد از پالت Quantization نمونه برداری می شود</string>\n    <string name=\"path_omit\">برداشتن مسیر</string>\n    <string name=\"downscale_image\">کاهش مقیاس تصویر</string>\n    <string name=\"downscale_image_sub\">تصویر قبل از پردازش به ابعاد پایین‌تر کاهش می‌یابد، این به ابزار کمک می‌کند تا سریع‌تر و ایمن‌تر کار کند</string>\n    <string name=\"min_color_ratio\">حداقل نسبت رنگ</string>\n    <string name=\"lines_threshold\">آستانه خطوط</string>\n    <string name=\"quadratic_threshold\">آستانه درجه دوم</string>\n    <string name=\"coordinates_rounding_tolerance\">تحمل گرد کردن مختصات</string>\n    <string name=\"path_scale\">مقیاس مسیر</string>\n    <string name=\"reset_properties\">بازنشانی ویژگی‌ها</string>\n    <string name=\"add_new_folder\">افزودن پوشه جدید</string>\n    <string name=\"tag_bits_per_sample\">بیت ها در نمونه</string>\n    <string name=\"tag_compression\">فشرده سازی</string>\n    <string name=\"tag_samples_per_pixel\">نمونه ها در پیکسل</string>\n    <string name=\"default_line_width\">عرض خط پیش‌فرض</string>\n    <string name=\"engine_mode\">حالت موتور</string>\n    <string name=\"lstm_network\">شبکه LSTM</string>\n    <string name=\"legacy\">میراث</string>\n    <string name=\"legacy_and_lstm\">میراث و LSTM</string>\n    <string name=\"convert\">تبدیل</string>\n    <string name=\"min\">کمترین</string>\n    <string name=\"qr_description\">توضیحات QR</string>\n    <string name=\"convert_sub\">تبدیل تصاویر به فرمت داده شده</string>\n    <string name=\"tag_photometric_interpretation\">تفسیر فتومتریک</string>\n    <string name=\"tag_x_resolution\">رزولوشن X</string>\n    <string name=\"tag_y_resolution\">رزولوشن Y</string>\n    <string name=\"tag_resolution_unit\">واحد رزولوشن</string>\n    <string name=\"tag_jpeg_interchange_format\">تغییر فرمت JPEG</string>\n    <string name=\"tag_transfer_function\">تابع انتقال</string>\n    <string name=\"tag_white_point\">نقطه سفید</string>\n    <string name=\"tag_reference_black_white\">مرجع سیاه سفید</string>\n    <string name=\"tag_image_description\">توضیحات تصویر</string>\n    <string name=\"tag_make\">ساختن</string>\n    <string name=\"tag_model\">مدل</string>\n    <string name=\"tag_software\">نرم افزار</string>\n    <string name=\"tag_artist\">هنرمند</string>\n    <string name=\"tag_exif_version\">نسخه Exif</string>\n    <string name=\"tag_flashpix_version\">نسخه Flashpix</string>\n    <string name=\"tag_gamma\">گاما</string>\n    <string name=\"tag_color_space\">فضای رنگی</string>\n    <string name=\"tag_pixel_x_dimension\">ابعاد پیکسل X</string>\n    <string name=\"tag_compressed_bits_per_pixel\">بیت های فشرده در هر پیکسل</string>\n    <string name=\"tag_maker_note\">یادداشت ساز</string>\n    <string name=\"tag_pixel_y_dimension\">ابعاد پیکسل Y</string>\n    <string name=\"tag_related_sound_file\">فایل صوتی مرتبط</string>\n    <string name=\"tag_datetime_original\">تاریخ زمان اصلی</string>\n    <string name=\"tag_datetime_digitized\">تاریخ زمان دیجیتالی شدن</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">در تنظیمات برای اسکن کد QR به دوربین اجازه دهید</string>\n    <string name=\"links_preview\">پیش نمایش لینک ها</string>\n    <string name=\"links_preview_sub\">بازیابی پیش‌نمایش پیوند را در مکان‌هایی که می‌توانید متن دریافت کنید (کد QR، OCR و غیره) را فعال می‌کند.</string>\n    <string name=\"format_conversion_sub\">تبدیل دسته ای از تصاویر از یک فرمت به فرمت دیگر</string>\n    <string name=\"format_conversion\">تبدیل فرمت</string>\n    <string name=\"scale_color_space\">مقیاس فضای رنگ</string>\n    <string name=\"gif_type_to_webp\">GIF به WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">تبدیل تصاویر GIF به تصاویر متحرک WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP به تصاویر</string>\n    <string name=\"webp_type_to_image_sub\">تبدیل فایل WEBP به دسته ای از تصاویر</string>\n    <string name=\"webp_type_to_webp_sub\">دسته ای از تصاویر را به فایل WEBP تبدیل کنید</string>\n    <string name=\"webp_type_to_webp\">تصاویر به WEBP</string>\n    <string name=\"select_webp_image_to_start\">تصویر WEBP را برای شروع انتخاب کنید</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">کد QR اسکن شده یک الگوی فیلتر معتبر نیست</string>\n    <string name=\"scan_qr_code\">اسکن QR کد</string>\n    <string name=\"as_qr_code\">QR کد به عنوان تصویر</string>\n    <string name=\"qr_code\">QR کد</string>\n    <string name=\"scan_qr_code_to_replace_content\">کد QR را برای جایگزینی محتوا در فیلد اسکن کنید، یا چیزی را برای تولید کد QR جدید تایپ کنید</string>\n    <string name=\"no_favorite_options_selected\">هیچ گزینه دلخواه انتخاب نشده است، آنها را در صفحه ابزار اضافه کنید</string>\n    <string name=\"webp_tools\">ابزارهای WEBP</string>\n    <string name=\"color_tools\">ابزار رنگ</string>\n    <string name=\"color_tools_sub\">مخلوط کنید، رنگ بسازید، سایه ها ایجاد کنید و موارد دیگر</string>\n    <string name=\"webp_tools_sub\">تصاویر را به تصویر متحرک WEBP تبدیل کنید یا فریم هایی را از انیمیشن WEBP داده شده استخراج کنید</string>\n    <string name=\"save_as_qr_code_image\">ذخیره QR کد به عنوان تصویر</string>\n    <string name=\"qr_code_sub\">کد QR را اسکن کنید و محتوای آن را دریافت کنید یا رشته خود را برای ایجاد کد جدید جایگذاری کنید</string>\n    <string name=\"gaussian_sub\">یک روش درون یابی که یک تابع گاوسی را اعمال می کند و برای صاف کردن و کاهش نویز در تصاویر مفید است.</string>\n    <string name=\"tag_user_comment\">نظر کاربر</string>\n    <string name=\"tag_subsec_time\">زمان زیر ثانیه</string>\n    <string name=\"tag_iso_speed\">سرعت ISO</string>\n    <string name=\"tag_shutter_speed_value\">مقدار سرعت شاتر</string>\n    <string name=\"tag_flash\">فلش</string>\n    <string name=\"tag_flash_energy\">انرژی فلش</string>\n    <string name=\"image_toolbox_in_telegram\">ImageToolbox در تلگرام 🎉</string>\n    <string name=\"noise_generation\">تولید نویز</string>\n    <string name=\"noise_generation_sub\">نویز های مختلفی مانند پرلین یا انواع دیگر تولید کنید</string>\n    <string name=\"noise_type\">نوع نویز</string>\n    <string name=\"auto\">خودکار</string>\n    <string name=\"hide_all\">پنهان کردن همه</string>\n    <string name=\"show_all\">نمایش همه</string>\n    <string name=\"hide_status_bar\">پنهان کردن نوار وضعیت</string>\n    <string name=\"alignment\">تراز</string>\n    <string name=\"tag_f_number\">عدد F</string>\n    <string name=\"tag_white_balance\">وایت بالانس</string>\n    <string name=\"tag_sharpness\">وضوح</string>\n    <string name=\"tag_camera_owner_name\">نام مالک دوربین</string>\n    <string name=\"tag_gps_version_id\">شناسه نسخه GPS</string>\n    <string name=\"tag_gps_satellites\">ماهواره های GPS</string>\n    <string name=\"tag_gps_status\">وضعیت GPS</string>\n    <string name=\"tag_gps_measure_mode\">حالت اندازه گیری GPS</string>\n    <string name=\"tag_gps_speed\">سرعت GPS</string>\n    <string name=\"tag_datetime\">داده زمان</string>\n    <string name=\"tag_copyright\">حق چاپ</string>\n    <string name=\"tag_offset_time\">زمان افست</string>\n    <string name=\"tag_offset_time_original\">افست زمان اصلی</string>\n    <string name=\"tag_offset_time_digitized\">زمان دیجیتالی افست</string>\n    <string name=\"tag_sensitivity_type\">نوع حساسیت</string>\n    <string name=\"tag_subject_distance\">فاصله موضوع</string>\n    <string name=\"tag_metering_mode\">حالت اندازه گیری</string>\n    <string name=\"filter_preview_image\">پیش نمایش تصویر</string>\n    <string name=\"lut_library_sub\">مجموعه LUT ها را دانلود کنید که پس از دانلود می توانید آن را اعمال کنید</string>\n    <string name=\"filter_preview_image_sub\">پیش نمایش تصویر پیش فرض را برای فیلترها تغییر دهید</string>\n    <string name=\"dont_stack_frames\">فریم ها را روی هم قرار ندهید</string>\n    <string name=\"create_shortcut_subtitle\">ابزار به عنوان میانبر به صفحه اصلی راه‌انداز شما اضافه می‌شود، از ترکیب آن با تنظیمات «پرش از انتخاب فایل» برای دستیابی به رفتار مورد نیاز استفاده کنید.</string>\n    <string name=\"create_shortcut\">ایجاد میانبر</string>\n    <string name=\"main_screen_title\">عنوان صفحه اصلی</string>\n    <string name=\"compact_selectors\">انتخابگرهای فشرده</string>\n    <string name=\"tag_subject_location\">محل موضوع</string>\n    <string name=\"hanning\">هانینگ</string>\n    <string name=\"audio_cover_extractor\">استخراج کننده کاور صدا</string>\n    <string name=\"pick_audio_to_start\">برای شروع صدا را انتخاب کنید</string>\n    <string name=\"allow_enter_by_text_field\">اجازه ورود از طریق فیلد متنی را بدهید</string>\n    <string name=\"create_template\">ایجاد قالب</string>\n    <string name=\"equalize_histogram_pixelation\">یکسان سازی هیستوگرام پیکسلی</string>\n    <string name=\"template_name\">نام قالب</string>\n    <string name=\"color_harmonies\">هارمونی رنگ</string>\n    <string name=\"hamming\">همینگ</string>\n    <string name=\"barcode_type\">نوع بارکد</string>\n    <string name=\"generated_barcode_will_be_here\">بارکد تولید شده اینجا خواهد بود</string>\n    <string name=\"no_barcode_found\">بارکدی پیدا نشد</string>\n    <string name=\"no_covers_found\">هیچ جلدی یافت نشد</string>\n    <string name=\"pick_audio\">انتخاب صدا</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"font_size\">اندازه فونت</string>\n    <string name=\"watermark_size\">اندازه واترمارک</string>\n    <string name=\"repeat_text\">تکرار متن</string>\n    <string name=\"dash_size\">اندازه خط تیره</string>\n    <string name=\"linear\">خطی</string>\n    <string name=\"template_filter\">فیلتر قالب</string>\n    <string name=\"color_shading\">سایه رنگ</string>\n    <string name=\"variation\">تنوع</string>\n    <string name=\"tints\">رنگ ها</string>\n    <string name=\"fall_colors\">رنگ های پاییزی</string>\n    <string name=\"resolution\">رزولیشن</string>\n    <string name=\"resolution_y\">رزولیشن Y</string>\n    <string name=\"resolution_x\">رزولیشن X</string>\n    <string name=\"crash_title\">اوه… مشکلی پیش آمد</string>\n    <string name=\"send_logs_sub\">روی اشتراک‌گذاری فایل گزارش برنامه کلیک کنید، این می‌تواند به من کمک کند تا مشکل را پیدا کنم و مشکلات را برطرف کنم</string>\n    <string name=\"send_logs\">ارسال گزارش</string>\n    <string name=\"pixel_by_pixel\">پیکسل به پیکسل</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"candlelight\">نور شمع</string>\n    <string name=\"robidoux_sub\">یک روش درونیابی با کیفیت بالا که برای تغییر اندازه طبیعی تصاویر بهینه شده و بین وضوح و روانی تعادل برقرار می‌کند</string>\n    <string name=\"hamming_sub\">تابع پنجره‌ای برای کاهش نشت طیفی با کاهش دامنه لبه‌های سیگنال، کاربردی در پردازش سیگنال</string>\n    <string name=\"spline36_sub\">یک روش درونیابی مبتنی بر اسپلاین که با استفاده از فیلتر 36 تپی نتایج روانی ارائه می‌دهد</string>\n    <string name=\"bartlett_hann_sub\">یک تابع پنجره ترکیبی که پنجره‌های بارتلت و هان را ترکیب می‌کند و برای کاهش نشتی طیفی در پردازش سیگنال استفاده می‌شود</string>\n    <string name=\"bohman_sub\">یک تابع پنجره که برای کاهش نشتی طیفی استفاده می‌شود و وضوح فرکانس خوبی در برنامه‌های پردازش سیگنال ارائه می‌دهد</string>\n    <string name=\"tag_gps_longitude_ref\">مرجع طول جغرافیایی GPS</string>\n    <string name=\"spline16_sub\">یک روش درونیابی مبتنی بر اسپلاین که با استفاده از فیلتر 16 تپی نتایج روانی ارائه می‌دهد</string>\n    <string name=\"hanning_sub\">یک گونه از پنجره هان که معمولاً برای کاهش نشت طیفی در کاربردهای پردازش سیگنال استفاده می‌شود</string>\n    <string name=\"tag_gps_altitude_ref\">مرجع ارتفاع GPS</string>\n    <string name=\"bspline_sub\">از توابع چندجمله‌ای تعریف‌شده تکه‌ای برای درون‌یابی و تقریب هموار یک منحنی یا سطح استفاده می‌کند، نمایش شکل انعطاف‌پذیر و پیوسته</string>\n    <string name=\"spline64_sub\">یک روش درونیابی مبتنی بر اسپلاین که با استفاده از فیلتر 64 تپی نتایج روانی ارائه می‌دهد</string>\n    <string name=\"welch_sub\">یک تابع پنجره طراحی‌شده برای ارائه وضوح فرکانس بالا با کاهش نشتی طیفی، که اغلب در برنامه‌های پردازش سیگنال استفاده می‌شود</string>\n    <string name=\"bleach_bypass\">بایپس بلیچ</string>\n    <string name=\"image_for_histogram\">این تصویر برای تولید هیستوگرام‌های RGB و روشنایی استفاده خواهد شد</string>\n    <string name=\"drag_handle_width\">عرض دستگیره کشیدن</string>\n    <string name=\"checksum_tools_sub\">مقایسه چکسام‌ها، محاسبه هش‌ها و ایجاد رشته‌های هگز از فایل‌ها با استفاده از الگوریتم‌های مختلف هشینگ</string>\n    <string name=\"tag_jpeg_interchange_format_length\">طول فرمت تبادل JPEG</string>\n    <string name=\"tag_file_source\">منبع فایل</string>\n    <string name=\"image_splitting\">تقسیم تصویر</string>\n    <string name=\"lanczos_bessel\">لانکزوس بسل</string>\n    <string name=\"cupertino_switch\">کاپرتینو</string>\n    <string name=\"detailed\">جزئی</string>\n    <string name=\"tag_planar_configuration\">پیکربندی صفحه‌ای</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">نمونه‌برداری فرعی Y Cb Cr</string>\n    <string name=\"tag_y_cb_cr_positioning\">موقعیت Y Cb Cr</string>\n    <string name=\"tag_strip_offsets\">آفست‌های نواری</string>\n    <string name=\"tag_rows_per_strip\">سطرها در هر نوار</string>\n    <string name=\"tag_strip_byte_counts\">تعداد بایت‌های نوار</string>\n    <string name=\"tag_primary_chromaticities\">کروماتیسیته‌های اولیه</string>\n    <string name=\"tag_y_cb_cr_coefficients\">ضرایب Y Cb Cr</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_recommended_exposure_index\">ایندکس توصیه شده نوردهی</string>\n    <string name=\"tag_subsec_time_original\">زمان اصلی زیر ثانیه</string>\n    <string name=\"tag_subsec_time_digitized\">زمان دیجیتالی زیر ثانیه</string>\n    <string name=\"tag_exposure_time\">زمان نوردهی</string>\n    <string name=\"tag_exposure_program\">برنامه نوردهی</string>\n    <string name=\"tag_spectral_sensitivity\">حساسیت طیفی</string>\n    <string name=\"tag_photographic_sensitivity\">حساسیت عکاسی</string>\n    <string name=\"tag_standard_output_sensitivity\">حساسیت خروجی استاندارد</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">عرض سرعت ایزو yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">عرض سرعت ایزو zzz</string>\n    <string name=\"tag_aperture_value\">مقدار دیافراگم</string>\n    <string name=\"tag_brightness_value\">مقدار روشنایی</string>\n    <string name=\"tag_exposure_bias_value\">مقدار تعصب نوردهی</string>\n    <string name=\"tag_max_aperture_value\">مقدار حداکثر دیافراگم</string>\n    <string name=\"tag_subject_area\">منطقه موضوعی</string>\n    <string name=\"tag_focal_length\">طول کانونی</string>\n    <string name=\"tag_spatial_frequency_response\">پاسخ فرکانس مکانی</string>\n    <string name=\"tag_focal_plane_x_resolution\">وضوح صفحه کانونی X</string>\n    <string name=\"tag_gps_longitude\">طول جغرافیایی GPS</string>\n    <string name=\"tag_gps_altitude\">ارتفاع GPS</string>\n    <string name=\"tag_gps_timestamp\">مهر زمان GPS</string>\n    <string name=\"tag_gps_map_datum\">داده‌های نقشه GPS</string>\n    <string name=\"tag_gps_latitude_ref\">مرجع عرض جغرافیایی GPS</string>\n    <string name=\"tag_gps_latitude\">عرض جغرافیایی GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">مرجع عرض جغرافیایی مقصد GPS</string>\n    <string name=\"tag_gps_processing_method\">روش پردازش GPS</string>\n    <string name=\"tag_gps_area_information\">اطلاعات منطقه GPS</string>\n    <string name=\"blackman_sub\">یک تابع پنجره‌ای که با به حداقل رساندن نشت طیفی، وضوح فرکانسی خوبی ارائه می‌دهد و اغلب در پردازش سیگنال استفاده می‌شود</string>\n    <string name=\"quadric_sub\">یک روش که از یک تابع درجه دوم برای درونیابی استفاده می‌کند و نتایج روان و پیوسته‌ای ارائه می‌دهد</string>\n    <string name=\"sphinx_sub\">یک روش پیشرفته نمونه‌برداری مجدد که درونیابی با کیفیت بالا و حداقل مصنوع ارائه می‌دهد</string>\n    <string name=\"bartlett_sub\">یک تابع پنجره مثلثی که در پردازش سیگنال برای کاهش نشتی طیفی استفاده می‌شود</string>\n    <string name=\"robidoux_sharp_sub\">یک نوع تیزتر از روش روبیدوکس که برای تغییر اندازه واضح تصاویر بهینه شده است</string>\n    <string name=\"kaiser_sub\">یک روش درونیابی که از پنجره کایزر استفاده می‌کند و کنترل خوبی بر توازن بین پهنای لوب اصلی و سطح لوب جانبی فراهم می‌کند</string>\n    <string name=\"simple_sketch\">طرح ساده</string>\n    <string name=\"color_poster\">پوستر رنگی</string>\n    <string name=\"tri_tone\">سه رنگه</string>\n    <string name=\"third_color\">رنگ سوم</string>\n    <string name=\"target_cube_lut_file\">فایل هدف 3D LUT (.cube / .CUBE)</string>\n    <string name=\"system_bars_visibility\">قابلیت مشاهده نوارهای سیستم</string>\n    <string name=\"show_system_bars_by_swipe\">نمایش نوارهای سیستم با کشیدن</string>\n    <string name=\"soft_glow\">نور ملایم</string>\n    <string name=\"tag_image_unique_id\">شناسه یکتای تصویر</string>\n    <string name=\"tag_focal_plane_y_resolution\">وضوح محور Y در صفحه کانونی</string>\n    <string name=\"tag_focal_plane_resolution_unit\">واحد وضوح صفحه کانونی</string>\n    <string name=\"tag_exposure_index\">شاخص نوردهی</string>\n    <string name=\"tag_sensing_method\">روش حسگر</string>\n    <string name=\"tag_cfa_pattern\">الگو CFA</string>\n    <string name=\"tag_custom_rendered\">پردازش سفارشی شده</string>\n    <string name=\"tag_exposure_mode\">حالت نوردهی</string>\n    <string name=\"tag_digital_zoom_ratio\">نسبت بزرگ‌نمایی دیجیتال</string>\n    <string name=\"tag_focal_length_in_35mm_film\">فاصله کانونی در فیلم ۳۵ میلی‌متری</string>\n    <string name=\"tag_scene_capture_type\">نوع ثبت صحنه</string>\n    <string name=\"tag_contrast\">کنتراست</string>\n    <string name=\"tag_saturation\">اشباع</string>\n    <string name=\"tag_device_setting_description\">دستگاه تنظیم توضیحات</string>\n    <string name=\"tag_subject_distance_range\">محدوده فاصله سوژه</string>\n    <string name=\"tag_body_serial_number\">شماره سریال بدنه</string>\n    <string name=\"tag_lens_specification\">مشخصات لنز</string>\n    <string name=\"tag_lens_make\">سازنده لنز</string>\n    <string name=\"tag_lens_model\">مدل لنز</string>\n    <string name=\"tag_lens_serial_number\">شماره سریال لنز</string>\n    <string name=\"tag_gps_dop\">دقت موقعیت مکانی</string>\n    <string name=\"tag_gps_speed_ref\">مرجع سرعت موقعیت مکانی</string>\n    <string name=\"center\">مرکز</string>\n    <string name=\"tag_gps_datestamp\">مهر تاریخ GPS</string>\n    <string name=\"tag_gps_differential\">دیفرانسیل GPS</string>\n    <string name=\"paste_link\">وارد کردن لینک</string>\n    <string name=\"star\">ستاره</string>\n    <string name=\"outlined_star\">ستاره طرح دار</string>\n    <string name=\"antialias\">آنتی‌آلیاس‌ها</string>\n    <string name=\"document_scanner\">اسکنر اسناد</string>\n    <string name=\"click_to_start_scanning\">برای شروع اسکن کلیک کنید</string>\n    <string name=\"start_scanning\">شروع اسکن</string>\n    <string name=\"save_as_pdf\">ذخیره به صورت pdf</string>\n    <string name=\"share_as_pdf\">اشتراک گذاری به صورت pdf</string>\n    <string name=\"grid_size_x\">اندازه شبکه X</string>\n    <string name=\"grid_size_y\">اندازه شبکه Y</string>\n    <string name=\"image_cutting\">برش تصویر</string>\n    <string name=\"edit_exif_screen\">ویرایش EXIF</string>\n    <string name=\"edit_exif_screen_sub\">تغییر متادیتای یک تصویر بدون فشرده‌سازی مجدد</string>\n    <string name=\"edit_exif_tag\">برای ویرایش برچسب‌های موجود، ضربه بزنید</string>\n    <string name=\"compose_switch_sub\">یک Jetpack Compose Material که شما جابجا می کنید</string>\n    <string name=\"tag_gain_control\">کنترل را به دست آورید</string>\n    <string name=\"tag_gps_track_ref\">کد مسیر GPS</string>\n    <string name=\"tag_gps_track\">مسیر GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Ref. GPS img Direction</string>\n    <string name=\"tag_gps_img_direction\">GPS img جهت</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitude Ref</string>\n    <string name=\"tag_gps_dest_longitude\">طول جغرافیایی مقصد GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">کد بلبرینگ مقصد GPS</string>\n    <string name=\"tag_gps_dest_bearing\">بلبرینگ مقصد GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">مرجع فاصله مقصد GPS</string>\n    <string name=\"tag_gps_dest_distance\">فاصله مقصد GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">خطای موقعیت یابی GPS H</string>\n    <string name=\"tag_interoperability_index\">شاخص قابلیت همکاری</string>\n    <string name=\"tag_dng_version\">نسخه DNG</string>\n    <string name=\"tag_default_crop_size\">اندازه پیش‌فرض برش</string>\n    <string name=\"tag_orf_preview_image_start\">پیش نمایش شروع تصویر</string>\n    <string name=\"tag_orf_preview_image_length\">طول تصویر پیش نمایش</string>\n    <string name=\"tag_orf_aspect_frame\">قاب جنبه</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">حاشیه پایین سنسور</string>\n    <string name=\"tag_rw2_sensor_left_border\">حاشیه سمت چپ سنسور</string>\n    <string name=\"tag_rw2_sensor_right_border\">حاشیه سمت راست سنسور</string>\n    <string name=\"tag_rw2_sensor_top_border\">حاشیه بالای سنسور</string>\n    <string name=\"draw_text_sub\">با فونت و رنگ داده شده متن را روی مسیر بکشید</string>\n    <string name=\"repeat_text_sub\">متن فعلی به جای یک بار کشیدن تا پایان مسیر تکرار می شود</string>\n    <string name=\"draw_mode_image_sub\">از تصویر انتخاب شده برای کشیدن آن در مسیر مشخص شده استفاده کنید</string>\n    <string name=\"draw_image_sub\">این تصویر به عنوان ورودی تکراری مسیر ترسیم شده استفاده خواهد شد</string>\n    <string name=\"outlined_triangle_sub\">مثلث مشخص شده را از نقطه شروع تا نقطه پایان رسم می کند</string>\n    <string name=\"triangle_sub\">مثلث مشخص شده را از نقطه شروع تا نقطه پایان رسم می کند</string>\n    <string name=\"outlined_triangle\">مثلث مشخص شده</string>\n    <string name=\"triangle\">مثلث</string>\n    <string name=\"polygon_sub\">چند ضلعی را از نقطه شروع به نقطه پایان رسم می کند</string>\n    <string name=\"polygon\">چند ضلعی</string>\n    <string name=\"outlined_polygon\">چند ضلعی مشخص شده</string>\n    <string name=\"outlined_polygon_sub\">چند ضلعی مشخص شده را از نقطه شروع تا نقطه پایان ترسیم می کند</string>\n    <string name=\"vertices\">رئوس</string>\n    <string name=\"draw_regular_polygon\">رسم چند ضلعی منتظم</string>\n    <string name=\"draw_regular_polygon_sub\">چند ضلعی رسم کنید که به جای فرم آزاد، منظم باشد</string>\n    <string name=\"star_sub\">ستاره را از نقطه شروع به نقطه پایان می کشد</string>\n    <string name=\"outlined_star_sub\">ستاره مشخص شده را از نقطه شروع تا نقطه پایان ترسیم می کند</string>\n    <string name=\"inner_radius_ratio\">نسبت شعاع داخلی</string>\n    <string name=\"draw_regular_star\">رسم ستاره منظم</string>\n    <string name=\"draw_regular_star_sub\">ستاره ای را بکشید که به جای شکل آزاد، منظم خواهد بود</string>\n    <string name=\"antialias_sub\">برای جلوگیری از لبه‌های تیز، آنتی‌الیاسینگ را فعال می‌کند</string>\n    <string name=\"open_edit_instead_of_preview\">ویرایش را به جای پیش نمایش باز کنید</string>\n    <string name=\"open_edit_instead_of_preview_sub\">هنگامی که تصویر را برای باز کردن (پیش نمایش) در ImageToolbox انتخاب می کنید، برگه انتخاب ویرایش به جای پیش نمایش باز می شود</string>\n    <string name=\"document_scanner_sub\">اسناد را اسکن کنید و PDF یا تصاویر جدا از آنها ایجاد کنید</string>\n    <string name=\"options_below_is_for_images\">گزینه های زیر برای ذخیره تصاویر است نه PDF</string>\n    <string name=\"equalize_histogram_hsv\">هیستوگرام HSV را یکسان کنید</string>\n    <string name=\"equalize_histogram\">یکسان سازی هیستوگرام</string>\n    <string name=\"enter_percentage\">درصد را وارد کنید</string>\n    <string name=\"allow_enter_by_text_field_sub\">فیلد متن را در پشت انتخاب از پیش تنظیم‌ها فعال می‌کند تا آن‌ها را در لحظه وارد کنید</string>\n    <string name=\"equalize_histogram_adaptive\">هیستوگرام تطبیقی ​​را برابر کنید</string>\n    <string name=\"equalize_histogram_adaptive_luv\">LUV تطبیقی ​​هیستوگرام را یکسان کنید</string>\n    <string name=\"equalize_histogram_adaptive_lab\">LAB تطبیقی ​​هیستوگرام را برابر کنید</string>\n    <string name=\"clahe\">کلاه</string>\n    <string name=\"clahe_lab\">آزمایشگاه کلاه</string>\n    <string name=\"clahe_luv\">کلاه لوو</string>\n    <string name=\"crop_to_content\">برش به محتوا</string>\n    <string name=\"frame_color\">رنگ قاب</string>\n    <string name=\"color_to_ignore\">رنگ برای نادیده گرفتن</string>\n    <string name=\"template\">الگو</string>\n    <string name=\"no_template_filters\">هیچ فیلتر قالب اضافه نشده است</string>\n    <string name=\"create_new\">ایجاد جدید</string>\n    <string name=\"opened_file_have_no_filter_template\">فایل انتخابی داده‌های قالب فیلتر ندارد</string>\n    <string name=\"select_template_preview\">این تصویر برای پیش نمایش این الگوی فیلتر استفاده خواهد شد</string>\n    <string name=\"as_file\">به عنوان فایل</string>\n    <string name=\"save_as_file\">ذخیره به عنوان فایل</string>\n    <string name=\"delete_template\">حذف قالب</string>\n    <string name=\"delete_template_warn\">شما در حال حذف فیلتر قالب انتخابی هستید. این عملیات قابل برگشت نیست</string>\n    <string name=\"added_filter_template\">الگوی فیلتر با نام \\\"%1$s\\\" (%2$s) اضافه شد</string>\n    <string name=\"filter_preview\">پیش نمایش فیلتر</string>\n    <string name=\"code_content\">محتوای کد</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">اعطای مجوز دوربین در تنظیمات برای اسکن اسکنر اسناد</string>\n    <string name=\"cubic\">مکعبی</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"blackman\">بلکمن</string>\n    <string name=\"welch\">ولش</string>\n    <string name=\"quadric\">چهارگانه</string>\n    <string name=\"gaussian\">گاوسی</string>\n    <string name=\"sphinx\">ابوالهول</string>\n    <string name=\"bartlett\">بارتلت</string>\n    <string name=\"robidoux\">روبیدوکس</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">اسپلاین 16</string>\n    <string name=\"spline36\">اسپلاین 36</string>\n    <string name=\"spline64\">اسپلاین 64</string>\n    <string name=\"kaiser\">قیصر</string>\n    <string name=\"bartlett_hann\">بارتلت-هی</string>\n    <string name=\"box\">جعبه</string>\n    <string name=\"bohman\">بومن</string>\n    <string name=\"lanczos2\">لانچوس 2</string>\n    <string name=\"lanczos3\">لانچوس 3</string>\n    <string name=\"lanczos4\">لانچوس 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">درون یابی مکعبی با در نظر گرفتن نزدیکترین 16 پیکسل، مقیاس بندی نرم تری را فراهم می کند و نتایج بهتری نسبت به دوخطی دارد.</string>\n    <string name=\"box_sub\">یک روش نمونه‌گیری مجدد ساده که از میانگین نزدیک‌ترین مقادیر پیکسل استفاده می‌کند، که اغلب منجر به ظاهر بلوکی می‌شود.</string>\n    <string name=\"lanczos2_sub\">یک روش نمونه‌گیری مجدد که از فیلتر 2 لوب Lanczos برای درونیابی با کیفیت بالا با حداقل مصنوعات استفاده می‌کند.</string>\n    <string name=\"lanczos3_sub\">یک روش نمونه برداری مجدد که از یک فیلتر 3 لوب Lanczos برای درونیابی با کیفیت بالا با حداقل مصنوعات استفاده می کند.</string>\n    <string name=\"lanczos4_sub\">یک روش نمونه‌گیری مجدد که از فیلتر 4 لوب Lanczos برای درونیابی با کیفیت بالا با حداقل مصنوعات استفاده می‌کند.</string>\n    <string name=\"lanczos2_jinc_sub\">نوعی از فیلتر Lanczos 2 که از عملکرد jinc استفاده می کند و درون یابی با کیفیت بالا با حداقل مصنوعات را ارائه می دهد.</string>\n    <string name=\"lanczos3_jinc_sub\">نوعی از فیلتر Lanczos 3 که از عملکرد jinc استفاده می کند و درون یابی با کیفیت بالا با حداقل مصنوعات را ارائه می دهد.</string>\n    <string name=\"lanczos4_jinc_sub\">نوعی از فیلتر Lanczos 4 که از عملکرد jinc استفاده می کند و درون یابی با کیفیت بالا با حداقل مصنوعات را ارائه می دهد.</string>\n    <string name=\"ewa_hanning\">هانینگ EWA</string>\n    <string name=\"ewa_hanning_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر هانینگ برای درونیابی صاف و نمونه برداری مجدد</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر Robidoux برای نمونه برداری مجدد با کیفیت بالا</string>\n    <string name=\"ewa_blackman\">بلکمن حوا</string>\n    <string name=\"ewa_blackman_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر Blackman برای به حداقل رساندن آرتیفکت های زنگ</string>\n    <string name=\"ewa_quadric\">EWA چهارگانه</string>\n    <string name=\"ewa_quadric_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر Quadric برای درونیابی صاف</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر Robidoux Sharp برای نتایج واضح تر</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر Lanczos 3 Jinc برای نمونه برداری مجدد با کیفیت بالا با کمترین الایاسینگ</string>\n    <string name=\"ginseng\">جینسینگ</string>\n    <string name=\"ginseng_sub\">یک فیلتر نمونه برداری مجدد که برای پردازش تصویر با کیفیت بالا با تعادل خوبی از وضوح و صافی طراحی شده است</string>\n    <string name=\"ewa_ginseng\">جینسینگ EWA</string>\n    <string name=\"ewa_ginseng_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر جینسنگ برای بهبود کیفیت تصویر</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر Lanczos Sharp برای دستیابی به نتایج واضح با حداقل مصنوعات</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر Lanczos 4 Sharpest برای نمونه برداری مجدد تصویر بسیار واضح</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">نوع میانگین وزنی بیضوی (EWA) فیلتر نرم Lanczos برای نمونه برداری مجدد صاف تر</string>\n    <string name=\"haasn_soft\">هاسن سافت</string>\n    <string name=\"haasn_soft_sub\">یک فیلتر نمونه‌برداری مجدد که توسط Haasn برای مقیاس‌گذاری صاف و بدون مصنوعات تصویر طراحی شده است</string>\n    <string name=\"dismiss_forever\">برای همیشه اخراج کنید</string>\n    <string name=\"image_stacking\">انباشتن تصویر</string>\n    <string name=\"image_stacking_sub\">با حالت های ترکیبی انتخابی، تصاویر را روی هم قرار دهید</string>\n    <string name=\"add_image\">اضافه کردن تصویر</string>\n    <string name=\"bins_count\">سطل ها به حساب می آیند</string>\n    <string name=\"clahe_hsl\">کلاه HSL</string>\n    <string name=\"clahe_hsv\">کلاه HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">HSL تطبیقی ​​هیستوگرام را برابر کنید</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">یکسان سازی هیستوگرام تطبیقی ​​HSV</string>\n    <string name=\"edge_mode\">حالت لبه</string>\n    <string name=\"clip\">کلیپ</string>\n    <string name=\"wrap\">بسته بندی کنید</string>\n    <string name=\"color_blind_scheme\">کوررنگی</string>\n    <string name=\"color_blind_scheme_sub\">حالت را برای تطبیق رنگ های تم برای نوع کوررنگی انتخاب شده انتخاب کنید</string>\n    <string name=\"protanomaly_sub\">مشکل در تشخیص رنگ قرمز و سبز</string>\n    <string name=\"deuteranomaly_sub\">مشکل در تشخیص رنگ سبز و قرمز</string>\n    <string name=\"tritanomaly_sub\">مشکل در تشخیص رنگ آبی و زرد</string>\n    <string name=\"protanopia_sub\">ناتوانی در درک رنگ قرمز</string>\n    <string name=\"deuteranopia_sub\">ناتوانی در درک رنگ سبز</string>\n    <string name=\"tritanopia_sub\">ناتوانی در درک رنگ آبی</string>\n    <string name=\"achromatomaly_sub\">کاهش حساسیت به تمام رنگ ها</string>\n    <string name=\"achromatopsia_sub\">کوررنگی کامل، دیدن فقط سایه های خاکستری</string>\n    <string name=\"not_use_color_blind_scheme\">از طرح کور رنگی استفاده نکنید</string>\n    <string name=\"not_use_color_blind_scheme_sub\">رنگ ها دقیقاً همانطور که در موضوع تنظیم شده است خواهند بود</string>\n    <string name=\"sigmoidal\">سیگموئیدی</string>\n    <string name=\"lagrange_2\">لاگرانژ 2</string>\n    <string name=\"lagrange_2_sub\">فیلتر درون یابی لاگرانژ درجه 2، مناسب برای مقیاس بندی تصویر با کیفیت بالا با انتقال صاف</string>\n    <string name=\"lagrange_3\">لاگرانژ 3</string>\n    <string name=\"lagrange_3_sub\">یک فیلتر درون یابی لاگرانژ درجه 3 که دقت بهتر و نتایج نرم تری را برای مقیاس بندی تصویر ارائه می دهد.</string>\n    <string name=\"lanczos_6\">لانچوس 6</string>\n    <string name=\"lanczos_6_sub\">فیلتر نمونه برداری مجدد Lanczos با مرتبه بالاتر از 6 که مقیاس تصویر واضح تر و دقیق تر را ارائه می دهد.</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">نوعی از فیلتر Lanczos 6 با استفاده از عملکرد Jinc برای بهبود کیفیت نمونه‌برداری مجدد تصویر</string>\n    <string name=\"linear_box_blur\">تاری جعبه خطی</string>\n    <string name=\"linear_tent_blur\">تاری چادر خطی</string>\n    <string name=\"linear_gaussian_box_blur\">تاری جعبه گاوسی خطی</string>\n    <string name=\"linear_stack_blur\">تاری پشته خطی</string>\n    <string name=\"gaussian_box_blur\">تاری جعبه گاوسی</string>\n    <string name=\"linear_fast_gaussian_blur_next\">تاری گاوسی سریع خطی بعدی</string>\n    <string name=\"linear_fast_gaussian_blur\">تاری گاوسی سریع خطی</string>\n    <string name=\"linear_gaussian_blur\">تاری گاوسی خطی</string>\n    <string name=\"draw_filter_sub\">یک فیلتر را برای استفاده از آن به عنوان رنگ انتخاب کنید</string>\n    <string name=\"replace_filter\">فیلتر را تعویض کنید</string>\n    <string name=\"pick_filter_info\">فیلتر زیر را انتخاب کنید تا از آن به عنوان قلم مو در طراحی خود استفاده کنید</string>\n    <string name=\"tiff_compression_scheme\">طرح فشرده سازی TIFF</string>\n    <string name=\"low_poly\">کم پلی</string>\n    <string name=\"sand_painting\">نقاشی شن و ماسه</string>\n    <string name=\"image_splitting_sub\">تک تصویر را بر اساس ردیف یا ستون تقسیم کنید</string>\n    <string name=\"fit_to_bounds\">متناسب با محدوده</string>\n    <string name=\"fit_to_bounds_sub\">برای دستیابی به رفتار دلخواه، حالت تغییر اندازه برش را با این پارامتر ترکیب کنید (نسبت Crop/Fit to aspect)</string>\n    <string name=\"languages_imported\">زبان ها با موفقیت وارد شدند</string>\n    <string name=\"backup_ocr_models\">پشتیبان گیری از مدل های OCR</string>\n    <string name=\"import_word\">واردات</string>\n    <string name=\"export\">صادرات</string>\n    <string name=\"position\">موقعیت</string>\n    <string name=\"top_left\">بالا سمت چپ</string>\n    <string name=\"top_right\">بالا سمت راست</string>\n    <string name=\"bottom_left\">پایین سمت چپ</string>\n    <string name=\"bottom_right\">پایین سمت راست</string>\n    <string name=\"top_center\">مرکز برتر</string>\n    <string name=\"center_right\">مرکز راست</string>\n    <string name=\"bottom_center\">مرکز پایین</string>\n    <string name=\"center_left\">مرکز چپ</string>\n    <string name=\"target_image\">تصویر هدف</string>\n    <string name=\"palette_transfer\">انتقال پالت</string>\n    <string name=\"enhanced_oil\">روغن تقویت شده</string>\n    <string name=\"simple_old_tv\">تلویزیون قدیمی ساده</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">گاتهام</string>\n    <string name=\"clahe_oklab\">کلاه اوکلاب</string>\n    <string name=\"clahe_oklch\">کلارا اولچ</string>\n    <string name=\"clahe_jzazbz\">کلاه جزبز</string>\n    <string name=\"polka_dot\">نقطه پولکا</string>\n    <string name=\"clustered_2x2_dithering\">Dithering 2x2 خوشه ای</string>\n    <string name=\"clustered_4x4_dithering\">Dithering 4x4 خوشه ای</string>\n    <string name=\"clustered_8x8_dithering\">Dithering 8x8 خوشه ای</string>\n    <string name=\"yililoma_dithering\">ییلیلوما دیترینگ</string>\n    <string name=\"add_favorites\">موارد دلخواه را اضافه کنید</string>\n    <string name=\"harmony_complementary\">مکمل</string>\n    <string name=\"harmony_analogous\">مشابه</string>\n    <string name=\"harmony_triadic\">سه گانه</string>\n    <string name=\"harmony_split_complementary\">تقسیم مکمل</string>\n    <string name=\"harmony_tetradic\">تترادیک</string>\n    <string name=\"harmony_square\">مربع</string>\n    <string name=\"harmony_analogous_complementary\">مشابه + مکمل</string>\n    <string name=\"tones\">تن</string>\n    <string name=\"shades\">سایه ها</string>\n    <string name=\"color_mixing\">اختلاط رنگ</string>\n    <string name=\"color_info\">اطلاعات رنگ</string>\n    <string name=\"selected_color\">رنگ انتخاب شده</string>\n    <string name=\"color_to_mix\">رنگ برای مخلوط کردن</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">وقتی رنگ‌های پویا روشن هستند، نمی‌توان از monet استفاده کرد</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">تصویر LUT را هدف بگیرید</string>\n    <string name=\"amatorka\">یک آماتور</string>\n    <string name=\"miss_etikate\">خانم آداب معاشرت</string>\n    <string name=\"soft_elegance\">ظرافت نرم</string>\n    <string name=\"soft_elegance_variant\">نوع Soft Elegance</string>\n    <string name=\"palette_transfer_variant\">نوع انتقال پالت</string>\n    <string name=\"cube_lut\">LUT سه بعدی</string>\n    <string name=\"drop_blues\">بلوز را رها کنید</string>\n    <string name=\"edgy_amber\">عنبر</string>\n    <string name=\"film_stock_50\">استوک فیلم 50</string>\n    <string name=\"foggy_night\">شب مه آلود</string>\n    <string name=\"kodak\">کداک</string>\n    <string name=\"save_empty_lut\">تصویر LUT خنثی را دریافت کنید</string>\n    <string name=\"save_empty_lut_sub\">ابتدا، از برنامه ویرایش عکس مورد علاقه خود برای اعمال فیلتر روی LUT خنثی استفاده کنید که می توانید از اینجا دریافت کنید. برای اینکه این کار به درستی کار کند، هر رنگ پیکسل نباید به پیکسل های دیگر بستگی داشته باشد (به عنوان مثال، تاری کار نخواهد کرد). پس از آماده شدن، از تصویر LUT جدید خود به عنوان ورودی فیلتر LUT 512*512 استفاده کنید</string>\n    <string name=\"pop_art\">هنر پاپ</string>\n    <string name=\"celluloid\">سلولوئید</string>\n    <string name=\"coffee\">قهوه</string>\n    <string name=\"golden_forest\">جنگل طلایی</string>\n    <string name=\"greenish\">مایل به سبز</string>\n    <string name=\"retro_yellow\">یکپارچهسازی با سیستمعامل زرد</string>\n    <string name=\"links\">پیوندها</string>\n    <string name=\"ico_size_warning\">فایل‌های ICO را فقط می‌توان در حداکثر اندازه ۲۵۶×۲۵۶ ذخیره کرد</string>\n    <string name=\"manage_storage_extra_types\">عدم دسترسی کامل به فایل ها</string>\n    <string name=\"manage_storage_extra_types_sub\">برای دیدن JXL، QOI و سایر تصاویری که در Android به‌عنوان تصویر شناخته نمی‌شوند، به همه فایل‌ها اجازه دسترسی دهید. بدون مجوز Image Toolbox قادر به نمایش آن تصاویر نیست</string>\n    <string name=\"default_draw_color\">رنگ ترسیم پیش فرض</string>\n    <string name=\"default_draw_path_mode\">حالت پیش‌فرض ترسیم مسیر</string>\n    <string name=\"add_timestamp\">اضافه کردن زمان</string>\n    <string name=\"add_timestamp_sub\">افزودن مهر زمانی به نام فایل خروجی را فعال می کند</string>\n    <string name=\"formatted_timestamp\">مُهر زمانی قالب بندی شده</string>\n    <string name=\"formatted_timestamp_sub\">قالب‌بندی مهر زمانی را در نام فایل خروجی به جای میلی‌سی‌های اصلی فعال کنید</string>\n    <string name=\"enable_timestamps_to_format_them\">Timestamps را برای انتخاب قالب خود فعال کنید</string>\n    <string name=\"one_time_save_location\">یک بار ذخیره مکان</string>\n    <string name=\"one_time_save_location_sub\">مکان‌های ذخیره یک‌باره را مشاهده و ویرایش کنید که می‌توانید با فشار طولانی دکمه ذخیره در اکثر گزینه‌ها استفاده کنید</string>\n    <string name=\"recently_used\">اخیرا استفاده شده است</string>\n    <string name=\"ci_channel\">کانال CI</string>\n    <string name=\"group\">گروه</string>\n    <string name=\"image_toolbox_in_telegram_sub\">به چت ما بپیوندید، جایی که می توانید در مورد هر چیزی که می خواهید بحث کنید و همچنین به کانال CI که در آن نسخه های بتا و اطلاعیه ها را پست می کنم نگاه کنید.</string>\n    <string name=\"ci_channel_sub\">در مورد نسخه های جدید برنامه مطلع شوید و اطلاعیه ها را بخوانید</string>\n    <string name=\"fit_description\">یک تصویر را در ابعاد داده شده قرار دهید و تاری یا رنگ را در پس زمینه اعمال کنید</string>\n    <string name=\"tools_arrangement\">چیدمان ابزار</string>\n    <string name=\"group_tools_by_type\">ابزارها را بر اساس نوع گروه بندی کنید</string>\n    <string name=\"group_tools_by_type_sub\">ابزارها را بر اساس نوع آنها در صفحه اصلی به جای ترتیب فهرست سفارشی گروه بندی می کند</string>\n    <string name=\"default_values\">مقادیر پیش فرض</string>\n    <string name=\"show_system_bars_by_swipe_sub\">کشیدن انگشت را برای نمایش نوارهای سیستم در صورت پنهان بودن فعال می کند</string>\n    <string name=\"hide_nav_bar\">نوار Nav را پنهان کنید</string>\n    <string name=\"frequency\">فرکانس</string>\n    <string name=\"rotation_type\">نوع چرخش</string>\n    <string name=\"fractal_type\">نوع فراکتال</string>\n    <string name=\"octaves\">اکتاو</string>\n    <string name=\"lacunarity\">پوچی</string>\n    <string name=\"gain\">به دست آوردن</string>\n    <string name=\"weighted_strength\">قدرت وزنی</string>\n    <string name=\"ping_pong_strength\">قدرت پینگ پنگ</string>\n    <string name=\"distance_function\">تابع فاصله</string>\n    <string name=\"return_type\">نوع برگشت</string>\n    <string name=\"jitter\">عصبانیت</string>\n    <string name=\"domain_warp\">Warp دامنه</string>\n    <string name=\"custom_filename\">نام فایل سفارشی</string>\n    <string name=\"custom_filename_sub\">مکان و نام فایل را انتخاب کنید که برای ذخیره تصویر فعلی استفاده می شود</string>\n    <string name=\"saved_to_custom\">در پوشه ای با نام سفارشی ذخیره شد</string>\n    <string name=\"collage_maker\">کلاژ ساز</string>\n    <string name=\"collage_maker_sub\">از حداکثر 20 تصویر کلاژ بسازید</string>\n    <string name=\"collage_type\">نوع کلاژ</string>\n    <string name=\"collages_info\">تصویر را برای جابجایی، حرکت و بزرگنمایی برای تنظیم موقعیت نگه دارید</string>\n    <string name=\"disable_rotation\">چرخش را غیرفعال کنید</string>\n    <string name=\"disable_rotation_sub\">با حرکات دو انگشتی از چرخش تصاویر جلوگیری می کند</string>\n    <string name=\"enable_snapping_to_borders\">اتصال به مرزها را فعال کنید</string>\n    <string name=\"enable_snapping_to_borders_sub\">پس از جابجایی یا بزرگ‌نمایی، عکس‌ها می‌چپند تا لبه‌های قاب را پر کنند</string>\n    <string name=\"histogram\">هیستوگرام</string>\n    <string name=\"histogram_sub\">هیستوگرام تصویر RGB یا Brightness برای کمک به شما در انجام تنظیمات</string>\n    <string name=\"tesseract_options\">گزینه های Tesseract</string>\n    <string name=\"tesseract_options_sub\">برخی از متغیرهای ورودی را برای موتور تسراکت اعمال کنید</string>\n    <string name=\"custom_options\">گزینه های سفارشی</string>\n    <string name=\"custom_params_info\">گزینه‌ها باید با این الگو وارد شوند: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">برش خودکار</string>\n    <string name=\"free_corners\">گوشه های رایگان</string>\n    <string name=\"free_corners_sub\">برش تصویر با چند ضلعی، این نیز پرسپکتیو را تصحیح می کند</string>\n    <string name=\"coerce_points_to_image_bounds\">اجبار به مرزهای تصویر اشاره می کند</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">نقاط با محدودیت های تصویر محدود نمی شوند، این برای تصحیح پرسپکتیو دقیق تر مفید است</string>\n    <string name=\"mask\">ماسک</string>\n    <string name=\"spot_heal_sub\">محتوای آگاه در مسیر ترسیم شده پر می شود</string>\n    <string name=\"spot_heal\">Heal Spot</string>\n    <string name=\"use_circle_kernel\">از Circle Kernel استفاده کنید</string>\n    <string name=\"opening\">باز شدن</string>\n    <string name=\"closing\">بسته شدن</string>\n    <string name=\"morphological_gradient\">گرادیان مورفولوژیکی</string>\n    <string name=\"top_hat\">کلاه بالا</string>\n    <string name=\"black_hat\">کلاه سیاه</string>\n    <string name=\"tone_curves\">منحنی های تن</string>\n    <string name=\"reset_curves\">بازنشانی منحنی ها</string>\n    <string name=\"reset_curves_sub\">منحنی ها به مقدار پیش فرض برمی گردند</string>\n    <string name=\"line_style\">سبک خط</string>\n    <string name=\"gap_size\">اندازه شکاف</string>\n    <string name=\"dashed\">بریده بریده</string>\n    <string name=\"dot_dashed\">نقطه چین</string>\n    <string name=\"stamped\">مهر شده</string>\n    <string name=\"zigzag\">زیگزاگ</string>\n    <string name=\"dashed_sub\">خط چین را در طول مسیر ترسیم شده با اندازه شکاف مشخص می‌کشد</string>\n    <string name=\"dot_dashed_sub\">نقطه و خط چین را در مسیر داده شده رسم می کند</string>\n    <string name=\"defaultt_sub\">فقط خطوط مستقیم پیش فرض</string>\n    <string name=\"stamped_sub\">اشکال انتخاب شده را در طول مسیر با فاصله مشخص ترسیم می کند</string>\n    <string name=\"zigzag_sub\">زیگزاگ مواج را در طول مسیر ترسیم می کند</string>\n    <string name=\"zigzag_ratio\">نسبت زیگزاگ</string>\n    <string name=\"create_shortcut_title\">ابزاری را برای پین کردن انتخاب کنید</string>\n    <string name=\"dont_stack_frames_sub\">حذف فریم‌های قبلی را فعال می‌کند، بنابراین آنها روی یکدیگر قرار نمی‌گیرند</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">فریم ها به یکدیگر متقاطع می شوند</string>\n    <string name=\"crossfade_count\">تعداد فریم های متقاطع</string>\n    <string name=\"threshold_one\">آستانه یک</string>\n    <string name=\"threshold_two\">آستانه دو</string>\n    <string name=\"canny\">کانی</string>\n    <string name=\"mirror_101\">آینه 101</string>\n    <string name=\"enhanced_zoom_blur\">تاری زوم پیشرفته</string>\n    <string name=\"laplacian_simple\">لاپلاسی ساده</string>\n    <string name=\"sobel_simple\">سوبل ساده</string>\n    <string name=\"helper_grid\">شبکه کمکی</string>\n    <string name=\"helper_grid_sub\">شبکه پشتیبان را در بالای منطقه طراحی نشان می دهد تا به دستکاری های دقیق کمک کند</string>\n    <string name=\"grid_color\">رنگ شبکه</string>\n    <string name=\"cell_width\">عرض سلول</string>\n    <string name=\"cell_height\">ارتفاع سلول</string>\n    <string name=\"compact_selectors_sub\">برخی از کنترل‌های انتخاب از یک چیدمان فشرده برای اشغال فضای کمتر استفاده می‌کنند</string>\n    <string name=\"grant_camera_permission_to_capture_image\">اجازه دوربین را در تنظیمات برای گرفتن تصویر بدهید</string>\n    <string name=\"layout\">طرح بندی</string>\n    <string name=\"constant_rate_factor\">ضریب نرخ ثابت (CRF)</string>\n    <string name=\"crf_sub\">مقدار %1$s به معنای فشرده سازی آهسته است که در نتیجه حجم فایل نسبتاً کم است. %2$s به معنای فشرده‌سازی سریع‌تر است که منجر به ایجاد یک فایل بزرگ می‌شود.</string>\n    <string name=\"lut_library\">کتابخانه لوت</string>\n    <string name=\"lut_library_update_sub\">مجموعه LUT ها را به روز کنید (فقط موارد جدید در صف قرار می گیرند) که می توانید پس از دانلود آن را اعمال کنید</string>\n    <string name=\"hide\">پنهان کردن</string>\n    <string name=\"show\">نمایش دهید</string>\n    <string name=\"slider_type\">نوع لغزنده</string>\n    <string name=\"fancy\">فانتزی</string>\n    <string name=\"material_2\">مواد 2</string>\n    <string name=\"fancy_sub\">یک نوار لغزنده با ظاهر فانتزی. این گزینه پیش فرض است</string>\n    <string name=\"material_2_sub\">یک نوار لغزنده Material 2</string>\n    <string name=\"material_you_slider_sub\">نوار لغزنده مواد شما</string>\n    <string name=\"apply\">درخواست کنید</string>\n    <string name=\"center_align_dialog_buttons\">دکمه های گفتگوی مرکزی</string>\n    <string name=\"center_align_dialog_buttons_sub\">دکمه های دیالوگ ها در صورت امکان به جای سمت چپ در مرکز قرار می گیرند</string>\n    <string name=\"open_source_licenses\">مجوزهای منبع باز</string>\n    <string name=\"open_source_licenses_sub\">مجوزهای کتابخانه های منبع باز مورد استفاده در این برنامه را مشاهده کنید</string>\n    <string name=\"area\">منطقه</string>\n    <string name=\"area_sub\">نمونه برداری مجدد با استفاده از رابطه مساحت پیکسل. ممکن است روشی ارجح برای از بین بردن تصویر باشد، زیرا نتایج بدون مویر می دهد. اما وقتی تصویر بزرگ‌نمایی می‌شود، شبیه به روش \\\"نزدیک‌ترین\\\" است.</string>\n    <string name=\"enable_tonemapping\">Tonemapping را فعال کنید</string>\n    <string name=\"enter_percent\">% را وارد کنید</string>\n    <string name=\"unknown_host\">نمی توانید به سایت دسترسی پیدا کنید، سعی کنید از VPN استفاده کنید یا بررسی کنید که آیا URL درست است</string>\n    <string name=\"markup_layers\">لایه های نشانه گذاری</string>\n    <string name=\"markup_layers_sub\">حالت لایه ها با قابلیت قرار دادن آزادانه تصاویر، متن و موارد دیگر</string>\n    <string name=\"edit_layer\">ویرایش لایه</string>\n    <string name=\"layers_on_image\">لایه ها روی تصویر</string>\n    <string name=\"layers_on_image_sub\">از یک تصویر به عنوان پس زمینه استفاده کنید و لایه های مختلف را در بالای آن اضافه کنید</string>\n    <string name=\"layers_on_background\">لایه ها روی پس زمینه</string>\n    <string name=\"layers_on_background_sub\">همان گزینه اول اما با رنگ به جای تصویر</string>\n    <string name=\"beta\">بتا</string>\n    <string name=\"fast_settings_side\">سمت تنظیمات سریع</string>\n    <string name=\"fast_settings_side_sub\">هنگام ویرایش تصاویر، یک نوار شناور در سمت انتخاب شده اضافه کنید، که با کلیک کردن، تنظیمات سریع باز می شود</string>\n    <string name=\"clear_selection\">پاک کردن انتخاب</string>\n    <string name=\"settings_group_visibility_hidden\">گروه تنظیم \\\"%1$s\\\" به طور پیش‌فرض جمع می‌شود</string>\n    <string name=\"settings_group_visibility_visible\">گروه تنظیم \\\"%1$s\\\" به طور پیش فرض گسترش می یابد</string>\n    <string name=\"base_64_tools\">ابزارهای Base64</string>\n    <string name=\"base_64_tools_sub\">رشته Base64 را به تصویر رمزگشایی کنید یا تصویر را به فرمت Base64 رمزگذاری کنید</string>\n    <string name=\"base_64\">پایه 64</string>\n    <string name=\"not_a_valid_base_64\">مقدار ارائه شده یک رشته Base64 معتبر نیست</string>\n    <string name=\"copy_not_a_valid_base_64\">نمی توان رشته Base64 خالی یا نامعتبر را کپی کرد</string>\n    <string name=\"paste_base_64\">Paste Base64</string>\n    <string name=\"copy_base_64\">Copy Base64</string>\n    <string name=\"base_64_tips\">تصویر را برای کپی یا ذخیره رشته Base64 بارگیری کنید. اگر خود رشته را دارید، می توانید آن را در بالا بچسبانید تا تصویر را به دست آورید</string>\n    <string name=\"save_base_64\">ذخیره Base64</string>\n    <string name=\"share_base_64\">Base64 را به اشتراک بگذارید</string>\n    <string name=\"options\">گزینه ها</string>\n    <string name=\"actions\">اقدامات</string>\n    <string name=\"import_base_64\">Import Base64</string>\n    <string name=\"base_64_actions\">Base64 Actions</string>\n    <string name=\"add_outline\">طرح کلی را اضافه کنید</string>\n    <string name=\"add_outline_sub\">طرح کلی اطراف متن را با رنگ و عرض مشخص اضافه کنید</string>\n    <string name=\"outline_color\">رنگ طرح کلی</string>\n    <string name=\"outline_size\">اندازه طرح کلی</string>\n    <string name=\"rotation\">چرخش</string>\n    <string name=\"checksum_as_filename\">Checksum به عنوان نام فایل</string>\n    <string name=\"checksum_as_filename_sub\">تصاویر خروجی دارای نامی هستند که با جمع کنترلی داده هایشان مطابقت دارد</string>\n    <string name=\"free_software_partner\">نرم افزار رایگان (شریک)</string>\n    <string name=\"free_software_partner_sub\">نرم افزارهای مفیدتر در کانال همکار اپلیکیشن های اندروید</string>\n    <string name=\"algorithms\">الگوریتم</string>\n    <string name=\"checksum_tools\">ابزارهای Checksum</string>\n    <string name=\"calculate\">محاسبه کنید</string>\n    <string name=\"text_hash\">هش متن</string>\n    <string name=\"checksum\">چک جمع</string>\n    <string name=\"pick_file_to_checksum\">فایلی را انتخاب کنید تا جمع چک آن بر اساس الگوریتم انتخاب شده محاسبه شود</string>\n    <string name=\"enter_text_to_checksum\">متنی را وارد کنید تا بر اساس الگوریتم انتخابی، جمع چک آن محاسبه شود</string>\n    <string name=\"source_checksum\">منبع Checksum</string>\n    <string name=\"checksum_to_compare\">چک جمع برای مقایسه</string>\n    <string name=\"match\">مسابقه!</string>\n    <string name=\"difference\">تفاوت</string>\n    <string name=\"match_sub\">مبلغ چک برابر است، می تواند ایمن باشد</string>\n    <string name=\"difference_sub\">جمع های چک برابر نیستند، فایل می تواند ناامن باشد!</string>\n    <string name=\"mesh_gradients\">گرادیان های مش</string>\n    <string name=\"collection_mesh_gradients_sub\">به مجموعه آنلاین Mesh Gradients نگاه کنید</string>\n    <string name=\"wrong_font\">فقط فونت های TTF و OTF را می توان وارد کرد</string>\n    <string name=\"import_font\">وارد کردن فونت (TTF/OTF)</string>\n    <string name=\"export_fonts\">صادرات فونت</string>\n    <string name=\"imported_fonts\">فونت های وارداتی</string>\n    <string name=\"error_while_saving\">خطا هنگام ذخیره تلاش، سعی کنید پوشه خروجی را تغییر دهید</string>\n    <string name=\"filename_is_not_set\">نام فایل تنظیم نشده است</string>\n    <string name=\"none\">هیچ کدام</string>\n    <string name=\"custom_pages\">صفحات سفارشی</string>\n    <string name=\"pages_selection\">انتخاب صفحات</string>\n    <string name=\"tool_exit_confirmation\">تأیید خروج از ابزار</string>\n    <string name=\"tool_exit_confirmation_sub\">اگر هنگام استفاده از ابزار خاصی تغییرات ذخیره نشده ای داشته باشید و سعی کنید آن را ببندید، گفتگوی تایید نمایش داده می شود</string>\n    <string name=\"change_sticker\">تغییر استیکر</string>\n    <string name=\"fit_width\">متناسب با عرض</string>\n    <string name=\"fit_height\">ارتفاع مناسب</string>\n    <string name=\"batch_compare\">مقایسه دسته ای</string>\n    <string name=\"pick_files_to_checksum\">فایل/فایل ها را انتخاب کنید تا جمع چک آن بر اساس الگوریتم انتخاب شده محاسبه شود</string>\n    <string name=\"pick_files\">فایل ها را انتخاب کنید</string>\n    <string name=\"pick_directory\">دایرکتوری را انتخاب کنید</string>\n    <string name=\"head_length_scale\">ترازوی طول سر</string>\n    <string name=\"stamp\">تمبر</string>\n    <string name=\"timestamp\">مهر زمان</string>\n    <string name=\"format_pattern\">الگوی قالب</string>\n    <string name=\"padding\">بالشتک</string>\n    <string name=\"image_cutting_sub\">قسمت تصویر را برش دهید و قسمت های چپ (می تواند معکوس باشد) را با خطوط عمودی یا افقی ادغام کنید</string>\n    <string name=\"vertical_pivot_line\">خط محوری عمودی</string>\n    <string name=\"horizontal_pivot_line\">خط محوری افقی</string>\n    <string name=\"inverse_selection\">انتخاب معکوس</string>\n    <string name=\"inverse_vertical_selection_sub\">قسمت برش عمودی به جای ادغام قطعات در اطراف منطقه برش، برگ خواهد شد</string>\n    <string name=\"inverse_horizontal_selection_sub\">قسمت برش افقی به جای ادغام قطعات در اطراف منطقه برش، برگ خواهد شد</string>\n    <string name=\"collection_mesh_gradients\">مجموعه ای از گرادیان های مش</string>\n    <string name=\"mesh_gradients_sub\">شیب مش را با مقدار سفارشی گره و وضوح ایجاد کنید</string>\n    <string name=\"gradient_maker_type_image_mesh\">پوشش گرادیان مش</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">شیب مش را از بالای تصاویر داده شده بنویسید</string>\n    <string name=\"points_customization\">سفارشی سازی امتیاز</string>\n    <string name=\"grid_size\">اندازه شبکه</string>\n    <string name=\"highlight_color\">رنگ را برجسته کنید</string>\n    <string name=\"pixel_comparison_type\">نوع مقایسه پیکسل</string>\n    <string name=\"scan_barcode\">اسکن بارکد</string>\n    <string name=\"height_ratio\">نسبت ارتفاع</string>\n    <string name=\"enforce_bw\">اعمال B/W</string>\n    <string name=\"enforce_bw_sub\">تصویر بارکد کاملا سیاه و سفید خواهد بود و با تم برنامه رنگی نمی شود</string>\n    <string name=\"barcodes_sub\">هر بارکدی (QR، EAN، AZTEC، …) را اسکن کنید و محتوای آن را دریافت کنید یا متن خود را برای ایجاد بارکد جدید جایگذاری کنید.</string>\n    <string name=\"audio_cover_extractor_sub\">استخراج تصاویر جلد آلبوم از فایل های صوتی، رایج ترین فرمت ها پشتیبانی می شوند</string>\n    <string name=\"crash_subtitle\">می‌توانید با استفاده از گزینه‌های زیر با من تماس بگیرید و من سعی می‌کنم راه‌حلی پیدا کنم.\\n(فراموش نکنید که گزارش‌ها را پیوست کنید)</string>\n    <string name=\"ocr_write_to_file\">نوشتن در فایل</string>\n    <string name=\"ocr_write_to_file_sub\">متن را از دسته ای از تصاویر استخراج کرده و در یک فایل متنی ذخیره کنید</string>\n    <string name=\"ocr_write_to_metadata\">نوشتن در فراداده</string>\n    <string name=\"ocr_write_to_metadata_sub\">متن را از هر تصویر استخراج کنید و آن را در اطلاعات EXIF ​​عکس های نسبی قرار دهید</string>\n    <string name=\"invisible_mode\">حالت نامرئی</string>\n    <string name=\"invisible_mode_sub\">از استگانوگرافی برای ایجاد واترمارک های نامرئی در داخل بایت های تصاویر خود استفاده کنید</string>\n    <string name=\"use_lsb\">از LSB استفاده کنید</string>\n    <string name=\"use_lsb_sub\">از روش استگانوگرافی LSB (بیت کمتر با اهمیت) استفاده می شود، در غیر این صورت از FD (دامنه فرکانس) استفاده می شود.</string>\n    <string name=\"auto_remove_red_eyes\">حذف خودکار قرمزی چشم</string>\n    <string name=\"password\">رمز عبور</string>\n    <string name=\"unlock\">باز کردن قفل</string>\n    <string name=\"pdf_is_protected\">PDF محافظت می شود</string>\n    <string name=\"operation_almost_complete\">عملیات تقریباً کامل شده است. لغو اکنون مستلزم راه اندازی مجدد آن است</string>\n    <string name=\"sort_by_date_modified\">تاریخ اصلاح شد</string>\n    <string name=\"sort_by_date_modified_reversed\">تاریخ اصلاح (معکوس)</string>\n    <string name=\"sort_by_size\">اندازه</string>\n    <string name=\"sort_by_size_reversed\">اندازه (معکوس)</string>\n    <string name=\"sort_by_mime_type\">نوع MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">نوع MIME (معکوس)</string>\n    <string name=\"sort_by_extension\">پسوند</string>\n    <string name=\"sort_by_extension_reversed\">پسوند (معکوس)</string>\n    <string name=\"sort_by_date_added\">تاریخ اضافه شدن</string>\n    <string name=\"sort_by_date_added_reversed\">تاریخ اضافه شدن (معکوس)</string>\n    <string name=\"left_to_right\">از چپ به راست</string>\n    <string name=\"right_to_left\">از راست به چپ</string>\n    <string name=\"top_to_bottom\">از بالا به پایین</string>\n    <string name=\"bottom_to_top\">از پایین به بالا</string>\n    <string name=\"liquid_glass\">شیشه مایع</string>\n    <string name=\"liquid_glass_sub\">سوئیچ مبتنی بر IOS 26 که اخیراً معرفی شده و سیستم طراحی شیشه مایع آن است</string>\n    <string name=\"pick_image_or_base64\">تصویر را انتخاب کنید یا داده‌های Base64 را در زیر جای‌گذاری/وارد کنید</string>\n    <string name=\"type_image_link\">برای شروع پیوند تصویر را تایپ کنید</string>\n    <string name=\"kaleidoscope\">کلیدوسکوپ</string>\n    <string name=\"secondary_angle\">زاویه ثانویه</string>\n    <string name=\"sides\">طرفین</string>\n    <string name=\"channel_mix\">میکس کانال</string>\n    <string name=\"blue_green\">سبز آبی</string>\n    <string name=\"red_blue\">قرمز آبی</string>\n    <string name=\"green_red\">سبز قرمز</string>\n    <string name=\"into_red\">به رنگ قرمز</string>\n    <string name=\"into_green\">به رنگ سبز</string>\n    <string name=\"into_blue\">به رنگ آبی</string>\n    <string name=\"cyan\">فیروزه ای</string>\n    <string name=\"magenta\">سرخابی</string>\n    <string name=\"yellow\">زرد</string>\n    <string name=\"color_halftone\">رنگ نیم تنه</string>\n    <string name=\"contour\">کانتور</string>\n    <string name=\"levels\">سطوح</string>\n    <string name=\"offset\">افست</string>\n    <string name=\"voronoi_crystallize\">کریستالیز ورونوی</string>\n    <string name=\"shape\">شکل</string>\n    <string name=\"stretch\">کشش</string>\n    <string name=\"randomness\">تصادفی بودن</string>\n    <string name=\"despeckle\">دسپکل</string>\n    <string name=\"diffuse\">پراکنده</string>\n    <string name=\"dog\">سگ</string>\n    <string name=\"second_radius\">شعاع دوم</string>\n    <string name=\"equalize\">برابر کردن</string>\n    <string name=\"glow\">درخشش</string>\n    <string name=\"whirl_and_pinch\">چرخش و خرج کردن</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">رنگ حاشیه</string>\n    <string name=\"polar_coordinates\">مختصات قطبی</string>\n    <string name=\"rect_to_polar\">راست به قطبی</string>\n    <string name=\"polar_to_rect\">قطبی به راست</string>\n    <string name=\"invert_in_circle\">در دایره معکوس کنید</string>\n    <string name=\"reduce_noise\">کاهش نویز</string>\n    <string name=\"simple_solarize\">خورشیدی ساده</string>\n    <string name=\"weave\">ببافید</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">شکاف Y</string>\n    <string name=\"x_width\">عرض X</string>\n    <string name=\"y_wdth\">عرض Y</string>\n    <string name=\"twirl\">چرخش</string>\n    <string name=\"rubber_stmp\">مهر لاستیکی</string>\n    <string name=\"smear\">اسمیر</string>\n    <string name=\"density\">تراکم</string>\n    <string name=\"mix\">مخلوط کنید</string>\n    <string name=\"sphere_lensh_distortion\">اعوجاج لنز کره</string>\n    <string name=\"refraction_index\">ضریب شکست</string>\n    <string name=\"arc\">قوس</string>\n    <string name=\"spread_angle\">زاویه گسترش</string>\n    <string name=\"sparkle\">درخشش</string>\n    <string name=\"rays\">اشعه ها</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">گرادیان</string>\n    <string name=\"moire\">مریم</string>\n    <string name=\"autumn\">پاییز</string>\n    <string name=\"bone\">استخوان</string>\n    <string name=\"jet\">جت</string>\n    <string name=\"winter\">زمستان</string>\n    <string name=\"ocean\">اقیانوس</string>\n    <string name=\"summer\">تابستان</string>\n    <string name=\"spring\">بهار</string>\n    <string name=\"cool_variant\">نوع باحال</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">صورتی</string>\n    <string name=\"hot\">داغ</string>\n    <string name=\"parula\">کلمه</string>\n    <string name=\"magma\">ماگما</string>\n    <string name=\"inferno\">دوزخ</string>\n    <string name=\"plasma\">پلاسما</string>\n    <string name=\"viridis\">ویریدیس</string>\n    <string name=\"cividis\">شهروندان</string>\n    <string name=\"twilight\">گرگ و میش</string>\n    <string name=\"twilight_shifted\">گرگ و میش تغییر کرد</string>\n    <string name=\"auto_perspective\">پرسپکتیو خودکار</string>\n    <string name=\"deskew\">رومیزی</string>\n    <string name=\"allow_crop\">اجازه برش</string>\n    <string name=\"crop_or_perspective\">برش یا پرسپکتیو</string>\n    <string name=\"absolute\">مطلق</string>\n    <string name=\"turbo\">توربو</string>\n    <string name=\"deep_green\">سبز عمیق</string>\n    <string name=\"lens_correction\">تصحیح لنز</string>\n    <string name=\"target_lens_profile\">فایل پروفایل لنز هدف را با فرمت JSON</string>\n    <string name=\"download_ready_lens_profiles\">دانلود پروفایل لنز آماده</string>\n    <string name=\"part_percents\">درصد درصد</string>\n    <string name=\"export_as_json\">صادرات به عنوان JSON</string>\n    <string name=\"export_as_json_sub\">رشته را با داده های پالت به عنوان نمایش json کپی کنید</string>\n    <string name=\"seam_carving\">کنده کاری درز</string>\n    <string name=\"home_screen\">صفحه اصلی</string>\n    <string name=\"lock_screen\">صفحه قفل</string>\n    <string name=\"built_in\">ساخته شده در</string>\n    <string name=\"wallpapers_export\">صادرات تصاویر پس زمینه</string>\n    <string name=\"refresh\">تازه کردن</string>\n    <string name=\"wallpapers_export_sub\">والپیپرهای خانه، قفل و داخلی فعلی را دریافت کنید</string>\n    <string name=\"allow_access_to_all_files_for_wp\">اجازه دسترسی به همه فایل‌ها را بدهید، این برای بازیابی تصاویر پس زمینه لازم است</string>\n    <string name=\"allow_read_media_images_for_wp\">مجوز مدیریت حافظه خارجی کافی نیست، شما باید اجازه دسترسی به تصاویر خود را بدهید، مطمئن شوید که \\\"Allow all\\\" را انتخاب کنید</string>\n    <string name=\"add_preset_to_filename\">از پیش تنظیم به نام فایل اضافه کنید</string>\n    <string name=\"add_preset_to_filename_sub\">پسوندی را با از پیش تعیین شده انتخاب شده به نام فایل تصویر اضافه می کند</string>\n    <string name=\"add_image_scale_mode_to_filename\">حالت مقیاس تصویر را به نام فایل اضافه کنید</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">پسوندی را با حالت مقیاس تصویر انتخاب شده به نام فایل تصویر اضافه می کند</string>\n    <string name=\"ascii_art\">هنر آسکی</string>\n    <string name=\"ascii_art_sub\">تبدیل تصویر به متن ascii که شبیه تصویر است</string>\n    <string name=\"params\">پارامترها</string>\n    <string name=\"invert_colors_ascii_sub\">فیلتر منفی را برای نتیجه بهتر در برخی موارد روی تصویر اعمال می کند</string>\n    <string name=\"processing_screenshot\">در حال پردازش اسکرین شات</string>\n    <string name=\"screenshot_not_captured_try_again\">اسکرین شات گرفته نشد، دوباره امتحان کنید</string>\n    <string name=\"skipped_saving\">ذخیره رد شد</string>\n    <string name=\"skipped_saving_multiple\">%1$s فایل رد شد</string>\n    <string name=\"allow_skip_if_larger\">Allow Skip If Larter</string>\n    <string name=\"allow_skip_if_larger_sub\">اگر اندازه فایل حاصل بزرگتر از نسخه اصلی باشد، به برخی از ابزارها اجازه داده می شود از ذخیره تصاویر صرفنظر کنند.</string>\n    <string name=\"qr_type_calendar_event\">رویداد تقویم</string>\n    <string name=\"qr_type_contact_info\">تماس بگیرید</string>\n    <string name=\"qr_type_email\">ایمیل</string>\n    <string name=\"qr_type_geo_point\">مکان</string>\n    <string name=\"qr_type_phone\">تلفن</string>\n    <string name=\"qr_type_plain\">متن</string>\n    <string name=\"qr_type_sms\">اس ام اس</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">وای فای</string>\n    <string name=\"open_network\">شبکه را باز کنید</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">تلفن</string>\n    <string name=\"message\">پیام</string>\n    <string name=\"address\">آدرس</string>\n    <string name=\"subject\">موضوع</string>\n    <string name=\"body\">بدن</string>\n    <string name=\"name\">نام</string>\n    <string name=\"organization\">سازمان</string>\n    <string name=\"title\">عنوان</string>\n    <string name=\"phones\">تلفن ها</string>\n    <string name=\"emails\">ایمیل ها</string>\n    <string name=\"urls\">URL ها</string>\n    <string name=\"addresses\">آدرس ها</string>\n    <string name=\"summary\">خلاصه</string>\n    <string name=\"description\">توضیحات</string>\n    <string name=\"location\">مکان</string>\n    <string name=\"organizer\">سازمان دهنده</string>\n    <string name=\"start_date\">تاریخ شروع</string>\n    <string name=\"end_date\">تاریخ پایان</string>\n    <string name=\"status\">وضعیت</string>\n    <string name=\"latitude\">عرض جغرافیایی</string>\n    <string name=\"longitude\">طول جغرافیایی</string>\n    <string name=\"create_barcode\">ایجاد بارکد</string>\n    <string name=\"edit_barcode\">ویرایش بارکد</string>\n    <string name=\"wifi_configuration\">پیکربندی Wi-Fi</string>\n    <string name=\"security\">امنیت</string>\n    <string name=\"pick_contact\">مخاطب را انتخاب کنید</string>\n    <string name=\"grant_contact_permission\">به مخاطبین در تنظیمات اجازه دهید تا با استفاده از مخاطب انتخابی، به صورت خودکار تکمیل شوند</string>\n    <string name=\"contact_info\">اطلاعات تماس</string>\n    <string name=\"first_name\">نام کوچک</string>\n    <string name=\"middle_name\">نام میانی</string>\n    <string name=\"last_name\">نام خانوادگی</string>\n    <string name=\"pronunciation\">تلفظ</string>\n    <string name=\"add_phone\">تلفن را اضافه کنید</string>\n    <string name=\"add_email\">ایمیل اضافه کنید</string>\n    <string name=\"add_address\">آدرس اضافه کنید</string>\n    <string name=\"website\">وب سایت</string>\n    <string name=\"add_website\">اضافه کردن وب سایت</string>\n    <string name=\"formatted_name\">نام قالب بندی شده</string>\n    <string name=\"qr_code_top_image\">این تصویر برای قرار دادن بالای بارکد استفاده خواهد شد</string>\n    <string name=\"code_customization\">سفارشی سازی کد</string>\n    <string name=\"qr_logo_image\">این تصویر به عنوان لوگو در مرکز کد QR استفاده خواهد شد</string>\n    <string name=\"logo\">لوگو</string>\n    <string name=\"logo_padding\">بالشتک آرم</string>\n    <string name=\"logo_size\">اندازه لوگو</string>\n    <string name=\"logo_corners\">گوشه های لوگو</string>\n    <string name=\"fourth_eye\">چشم چهارم</string>\n    <string name=\"fourth_eye_description\">با افزودن چشم چهارم در گوشه انتهایی پایین، تقارن چشم را به کد qr اضافه می کند</string>\n    <string name=\"pixel_shape\">شکل پیکسل</string>\n    <string name=\"frame_shape\">شکل قاب</string>\n    <string name=\"ball_shape\">شکل توپ</string>\n    <string name=\"error_correction_level\">سطح تصحیح خطا</string>\n    <string name=\"dark_color\">رنگ تیره</string>\n    <string name=\"light_color\">رنگ روشن</string>\n    <string name=\"hyper_os\">سیستم عامل هایپر</string>\n    <string name=\"hyper_os_sub\">شیائومی HyperOS سبک است</string>\n    <string name=\"mask_pattern\">الگوی ماسک</string>\n    <string name=\"code_may_be_not_scannable\">ممکن است این کد قابل اسکن نباشد، پارامترهای ظاهری را تغییر دهید تا با همه دستگاه ها قابل خواندن باشد</string>\n    <string name=\"not_scannable\">قابل اسکن نیست</string>\n    <string name=\"launcher_mode_sub\">ابزارها مانند راه‌انداز برنامه صفحه اصلی به نظر می‌رسند تا فشرده‌تر باشند</string>\n    <string name=\"launcher_mode\">حالت لانچر</string>\n    <string name=\"flood_fill_sub\">یک منطقه را با قلم مو و سبک انتخاب شده پر می کند</string>\n    <string name=\"flood_fill\">پر سیل</string>\n    <string name=\"spray\">اسپری کنید</string>\n    <string name=\"spray_sub\">مسیر به سبک گرافیتی را ترسیم می کند</string>\n    <string name=\"square_particles\">ذرات مربع</string>\n    <string name=\"square_particles_sub\">ذرات اسپری به جای دایره مربع شکل خواهند بود</string>\n    <string name=\"palette_tools\">ابزار پالت</string>\n    <string name=\"palette_tools_sub\">پایه/مواد اولیه را که پالت می‌کنید از تصویر ایجاد کنید، یا در قالب‌های پالت مختلف وارد/صادرات کنید</string>\n    <string name=\"edit_palette\">ویرایش پالت</string>\n    <string name=\"edit_palette_sub\">صادرات/وارد کردن پالت در قالب‌های مختلف</string>\n    <string name=\"color_name\">نام رنگ</string>\n    <string name=\"palette_name\">نام پالت</string>\n    <string name=\"palette_format\">قالب پالت</string>\n    <string name=\"export_palette_sub\">پالت تولید شده را به فرمت های مختلف صادر کنید</string>\n    <string name=\"add_color_palette_sub\">رنگ جدیدی را به پالت فعلی اضافه می کند</string>\n    <string name=\"palette_name_not_supported\">قالب %1$s از ارائه نام پالت پشتیبانی نمی کند</string>\n    <string name=\"wallpapers_export_not_avaialbe\">به دلیل خط‌مشی‌های فروشگاه Play، این ویژگی نمی‌تواند در ساخت فعلی گنجانده شود. برای دسترسی به این قابلیت، لطفا ImageToolbox را از یک منبع جایگزین دانلود کنید. می توانید بیلدهای موجود در GitHub را در زیر بیابید.</string>\n    <string name=\"open_github_page\">صفحه Github را باز کنید</string>\n    <string name=\"overwrite_files_sub_short\">فایل اصلی به جای ذخیره در پوشه انتخابی با فایل جدید جایگزین می شود</string>\n    <string name=\"hidden_watermark_text_detected\">متن واترمارک پنهان شناسایی شد</string>\n    <string name=\"hidden_watermark_image_detected\">تصویر واترمارک مخفی شناسایی شد</string>\n    <string name=\"this_image_was_hidden\">این تصویر مخفی بود</string>\n    <string name=\"generative_inpaint\">رنگ آمیزی مولد</string>\n    <string name=\"generative_inpaint_sub\">به شما امکان می دهد اشیاء موجود در یک تصویر را با استفاده از مدل هوش مصنوعی، بدون تکیه بر OpenCV حذف کنید. برای استفاده از این ویژگی، برنامه مدل مورد نیاز (~200 مگابایت) را از GitHub دانلود می کند</string>\n    <string name=\"generative_inpaint_ready_sub\">به شما امکان می دهد اشیاء موجود در یک تصویر را با استفاده از مدل هوش مصنوعی، بدون تکیه بر OpenCV حذف کنید. این می تواند یک عملیات طولانی مدت باشد</string>\n    <string name=\"error_level_analysis\">تجزیه و تحلیل سطح خطا</string>\n    <string name=\"luminance_gradient\">گرادیان درخشندگی</string>\n    <string name=\"average_distance\">فاصله متوسط</string>\n    <string name=\"copy_move_detection\">تشخیص حرکت کپی</string>\n    <string name=\"retain\">حفظ کنید</string>\n    <string name=\"coefficent\">ضریب</string>\n    <string name=\"clipboard_data_is_too_large\">داده های کلیپ بورد خیلی بزرگ است</string>\n    <string name=\"data_is_too_large_to_copy\">داده ها برای کپی خیلی بزرگ هستند</string>\n    <string name=\"simple_weave_pixelization\">پیکسل سازی بافت ساده</string>\n    <string name=\"staggered_pixelization\">پیکسل‌سازی پلکانی</string>\n    <string name=\"cross_pixelization\">Cross Pixelization</string>\n    <string name=\"micro_macro_pixelization\">پیکسل‌سازی میکرو ماکرو</string>\n    <string name=\"orbital_pixelization\">پیکسل سازی مداری</string>\n    <string name=\"vortex_pixelization\">پیکسل‌سازی گرداب</string>\n    <string name=\"pulse_grid_pixelization\">Pixelization شبکه پالس</string>\n    <string name=\"nucleus_pixelization\">پیکسل سازی هسته</string>\n    <string name=\"radial_weave_pixelization\">پیکسل سازی بافت شعاعی</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\" باز نمی شود</string>\n    <string name=\"snowfall_mode\">حالت بارش برف</string>\n    <string name=\"enabled\">فعال شد</string>\n    <string name=\"border_frame\">قاب حاشیه</string>\n    <string name=\"glitch_variant\">نوع اشکال</string>\n    <string name=\"channel_shift\">کانال شیفت</string>\n    <string name=\"max_offset\">حداکثر افست</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">بلوک اشکال</string>\n    <string name=\"block_size\">اندازه بلوک</string>\n    <string name=\"crt_curvature\">انحنای CRT</string>\n    <string name=\"curvature\">انحنا</string>\n    <string name=\"chroma\">کروما</string>\n    <string name=\"pixel_melt\">پیکسل ذوب</string>\n    <string name=\"max_drop\">ماکس دراپ</string>\n    <string name=\"ai_tools\">ابزارهای هوش مصنوعی</string>\n    <string name=\"ai_tools_sub\">ابزارهای مختلف برای پردازش تصاویر از طریق مدل های ai مانند حذف مصنوع یا حذف نویز</string>\n    <string name=\"model_anime_undeint\">فشرده سازی، خطوط ناهموار</string>\n    <string name=\"model_broadcast\">کارتون، فشرده سازی پخش</string>\n    <string name=\"model_rgb_max_denoise_fp16\">فشرده سازی عمومی، نویز عمومی</string>\n    <string name=\"model_wb_denoise\">صدای کارتونی بی رنگ</string>\n    <string name=\"model_span_anime_pretrain\">سریع، فشرده سازی عمومی، نویز عمومی، انیمیشن/کمیک/انیمه</string>\n    <string name=\"model_book_scan\">اسکن کتاب</string>\n    <string name=\"model_overexposure\">تصحیح نوردهی</string>\n    <string name=\"model_fbcnn_color_fp16\">بهترین در فشرده سازی عمومی، تصاویر رنگی</string>\n    <string name=\"model_fbcnn_gray_fp16\">بهترین در فشرده سازی عمومی، تصاویر در مقیاس خاکستری</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">فشرده سازی عمومی، تصاویر خاکستری، قوی تر</string>\n    <string name=\"model_scunet_color_gan_fp16\">نویز عمومی، تصاویر رنگی</string>\n    <string name=\"model_scunet_color_psnr_fp16\">نویز عمومی، تصاویر رنگی، جزئیات بهتر</string>\n    <string name=\"model_scunet_gray_15_fp16\">نویز عمومی، تصاویر خاکستری</string>\n    <string name=\"model_scunet_gray_25_fp16\">نویز عمومی، تصاویر خاکستری، قوی تر</string>\n    <string name=\"model_scunet_gray_50_fp16\">نویز عمومی، تصاویر خاکستری، قوی ترین</string>\n    <string name=\"model_jpeg_destroyer\">فشرده سازی عمومی</string>\n    <string name=\"model_jaywreck\">فشرده سازی عمومی</string>\n    <string name=\"model_h264\">بافت سازی، فشرده سازی h264</string>\n    <string name=\"model_vhs\">فشرده سازی VHS</string>\n    <string name=\"model_cinepak\">فشرده سازی غیر استاندارد (cinepak، msvideo1، roq)</string>\n    <string name=\"model_debink_v4\">فشرده سازی مخزن، بهتر در هندسه</string>\n    <string name=\"model_debink_v5\">فشرده سازی مخزن، قوی تر</string>\n    <string name=\"model_debink_v6\">فشرده سازی مخزن، نرم، جزئیات را حفظ می کند</string>\n    <string name=\"model_antialias\">از بین بردن اثر پله پله، صاف کردن</string>\n    <string name=\"model_kdm_scans\">هنر/طراحی های اسکن شده، فشرده سازی ملایم، مویر</string>\n    <string name=\"model_bandage\">نواربندی رنگی</string>\n    <string name=\"model_halftone\">آهسته، حذف نیم تن</string>\n    <string name=\"model_colorizer\">رنگ‌کننده عمومی برای تصاویر خاکستری/bw، برای نتایج بهتر از DDColor استفاده کنید</string>\n    <string name=\"model_deedge\">حذف لبه</string>\n    <string name=\"model_desharpen\">تیز شدن بیش از حد را از بین می برد</string>\n    <string name=\"model_dither\">آهسته، پریشان</string>\n    <string name=\"model_gainres\">Anti-aliasing، مصنوعات عمومی، CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 پردازش را اسکن می کند</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">مدل بهبود تصویر سبک</string>\n    <string name=\"model_bcgone_detailed_v2\">حذف مصنوعات فشرده سازی</string>\n    <string name=\"model_bcgone_smooth\">حذف مصنوعات فشرده سازی</string>\n    <string name=\"model_bandage_smooth\">برداشتن باند با نتایج صاف</string>\n    <string name=\"model_bendel_halftone\">پردازش الگوی نیم‌تنی</string>\n    <string name=\"model_dither_deleter_v3_smooth\">حذف الگوی Dither V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">حذف مصنوعات JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">بهبود بافت H.264</string>\n    <string name=\"model_vhs_sharpen\">تیز کردن و تقویت VHS</string>\n    <string name=\"merging\">ادغام</string>\n    <string name=\"chunk_size\">اندازه تکه</string>\n    <string name=\"overlap_size\">اندازه همپوشانی</string>\n    <string name=\"note_chunk_info\">تصاویر بیش از %1$s پیکسل برش داده می‌شوند و به صورت تکه‌ای پردازش می‌شوند، همپوشانی اینها را با هم ترکیب می‌کند تا از درزهای قابل مشاهده جلوگیری کند.</string>\n    <string name=\"large_chunk_warning\">اندازه های بزرگ می تواند باعث ناپایداری دستگاه های ارزان قیمت شود</string>\n    <string name=\"select_one_to_start\">برای شروع یکی را انتخاب کنید</string>\n    <string name=\"delete_model_sub\">آیا می خواهید مدل %1$s را حذف کنید؟ باید دوباره آن را دانلود کنید</string>\n    <string name=\"confirm\">تایید کنید</string>\n    <string name=\"models\">مدل ها</string>\n    <string name=\"downloaded_models\">مدل های دانلود شده</string>\n    <string name=\"available_models\">مدل های موجود</string>\n    <string name=\"preparing\">آماده سازی</string>\n    <string name=\"active_model\">مدل فعال</string>\n    <string name=\"failed_to_open_session\">جلسه باز نشد</string>\n    <string name=\"only_onnx_models\">فقط مدل‌های .onnx/.ort می‌توانند وارد شوند</string>\n    <string name=\"import_model\">مدل وارداتی</string>\n    <string name=\"import_model_sub\">مدل سفارشی onnx را برای استفاده بیشتر وارد کنید، فقط مدل‌های onnx/ort پذیرفته می‌شوند، تقریباً از همه گونه‌های مشابه esrgan پشتیبانی می‌کند</string>\n    <string name=\"imported_models\">مدل های وارداتی</string>\n    <string name=\"model_scunet_color_15_fp16\">نویز عمومی، تصاویر رنگی</string>\n    <string name=\"model_scunet_color_25_fp16\">نویز عمومی، تصاویر رنگی، قوی تر</string>\n    <string name=\"model_scunet_color_50_fp16\">نویز عمومی، تصاویر رنگی، قوی ترین</string>\n    <string name=\"model_artifacts_dithering_alsa\">مصنوعات متمایز و نوارهای رنگی را کاهش می دهد، شیب های صاف و مناطق رنگی صاف را بهبود می بخشد.</string>\n    <string name=\"model_nmkd_brighten_redux\">روشنایی و کنتراست تصویر را با هایلایت های متعادل و در عین حال حفظ رنگ های طبیعی افزایش می دهد.</string>\n    <string name=\"model_nmkd_brighten\">تصاویر تاریک را با حفظ جزئیات و اجتناب از نوردهی بیش از حد روشن می کند.</string>\n    <string name=\"model_nmkd_detoon\">توناژ بیش از حد رنگ را از بین می برد و تعادل رنگ خنثی و طبیعی را بازیابی می کند.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">تونینگ نویز مبتنی بر پواسون را با تاکید بر حفظ جزئیات و بافت های ظریف اعمال می کند.</string>\n    <string name=\"model_noise_toner_poisson_soft\">از تونینگ نرم پواسون برای نتایج بصری نرمتر و کم تهاجمی استفاده می کند.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">نویز یکنواخت با تمرکز بر حفظ جزئیات و وضوح تصویر.</string>\n    <string name=\"model_noise_toner_uniform_soft\">نویز یکنواخت ملایم برای بافت ظریف و ظاهری صاف.</string>\n    <string name=\"model_repainter\">نواحی آسیب دیده یا ناهموار را با رنگ آمیزی مجدد مصنوعات و بهبود ثبات تصویر ترمیم می کند.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">مدل بندکشی سبک که باندهای رنگی را با حداقل هزینه عملکرد حذف می کند.</string>\n    <string name=\"model_jpeg_0_20\">تصاویر را با فشرده سازی بسیار بالا (کیفیت 0-20٪) برای وضوح بهتر بهینه می کند.</string>\n    <string name=\"model_jpeg_20_40\">تصاویر را با آرتیفکت های فشرده سازی بالا (کیفیت 20-40٪)، بازیابی جزئیات و کاهش نویز بهبود می بخشد.</string>\n    <string name=\"model_jpeg_40_60\">تصاویر را با فشرده سازی متوسط ​​(کیفیت 40-60٪)، متعادل کردن وضوح و صافی بهبود می بخشد.</string>\n    <string name=\"model_jpeg_60_80\">تصاویر را با فشرده سازی نور (کیفیت 60-80٪) برای بهبود جزئیات و بافت های ظریف اصلاح می کند.</string>\n    <string name=\"model_jpeg_80_100\">تصاویر تقریباً بدون اتلاف (کیفیت 80 تا 100٪) را کمی بهبود می بخشد و در عین حال ظاهر و جزئیات طبیعی را حفظ می کند.</string>\n    <string name=\"model_spongecolor_lite\">رنگ آمیزی ساده و سریع، کارتون، ایده آل نیست</string>\n    <string name=\"model_deblr\">کمی تاری تصویر را کاهش می دهد و وضوح را بدون معرفی مصنوعات بهبود می بخشد.</string>\n    <string name=\"processing_channel\">عملیات طولانی مدت</string>\n    <string name=\"processing_image\">پردازش تصویر</string>\n    <string name=\"processing\">پردازش</string>\n    <string name=\"model_artifacts_jpg_0_20\">آرتیفکت های فشرده فشرده سازی JPEG را در تصاویر با کیفیت بسیار پایین (0-20٪) حذف می کند.</string>\n    <string name=\"model_artifacts_jpg_20_40\">آرتیفکت های JPEG قوی را در تصاویر بسیار فشرده (20-40٪) کاهش می دهد.</string>\n    <string name=\"model_artifacts_jpg_40_60\">مصنوعات JPEG متوسط ​​را با حفظ جزئیات تصویر (40-60٪) پاک می کند.</string>\n    <string name=\"model_artifacts_jpg_60_80\">مصنوعات سبک JPEG را در تصاویر با کیفیت نسبتاً بالا (60-80٪) اصلاح می کند.</string>\n    <string name=\"model_artifacts_jpg_80_100\">به طور نامحسوس مصنوعات JPEG جزئی را در تصاویر تقریباً بدون اتلاف (80-100٪) کاهش می دهد.</string>\n    <string name=\"model_redetail_v2\">جزئیات و بافت های ظریف را بهبود می بخشد و وضوح درک شده را بدون آثار سنگین بهبود می بخشد.</string>\n    <string name=\"processing_finished\">پردازش به پایان رسید</string>\n    <string name=\"processing_failed\">پردازش انجام نشد</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">بافت ها و جزئیات پوست را بهبود می بخشد و در عین حال ظاهری طبیعی را حفظ می کند و برای سرعت بهینه شده است.</string>\n    <string name=\"model_sbdv_dejpeg\">آرتیفکت های فشرده سازی JPEG را حذف می کند و کیفیت تصویر را برای عکس های فشرده بازیابی می کند.</string>\n    <string name=\"model_iso_denoise_v1\">نویز ISO را در عکس های گرفته شده در شرایط کم نور کاهش می دهد و جزئیات را حفظ می کند.</string>\n    <string name=\"model_dejumbo\">هایلایت های بیش از حد نوردهی شده یا \\\"جامبو\\\" را تصحیح می کند و تعادل تونال بهتری را بازیابی می کند.</string>\n    <string name=\"model_ddcolor_tiny\">مدل رنگی سبک و سریع که رنگ های طبیعی را به تصاویر خاکستری اضافه می کند.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">حذف نویز</string>\n    <string name=\"type_colorize\">رنگ آمیزی کنید</string>\n    <string name=\"type_artifacts\">مصنوعات</string>\n    <string name=\"type_enhance\">افزایش دهید</string>\n    <string name=\"type_anime\">انیمه</string>\n    <string name=\"type_scans\">اسکن می کند</string>\n    <string name=\"type_upscale\">سطح بالا</string>\n    <string name=\"model_realesrgan_x4v3\">ارتقاء دهنده X4 برای تصاویر عمومی. مدل کوچکی که از GPU و زمان کمتری استفاده می‌کند، با تاری و حذف نویز متوسط.</string>\n    <string name=\"model_realesrgan_x2plus\">ارتقاء دهنده X2 برای تصاویر عمومی، حفظ بافت ها و جزئیات طبیعی.</string>\n    <string name=\"model_realesrgan_x4plus\">ارتقاء دهنده X4 برای تصاویر عمومی با بافت های پیشرفته و نتایج واقعی.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">ارتقاء دهنده X4 برای تصاویر انیمه بهینه شده است. 6 بلوک RRDB برای خطوط و جزئیات واضح تر.</string>\n    <string name=\"model_realesrnet_x4plus\">ارتقاء دهنده X4 با از دست دادن MSE، نتایج نرم تری ایجاد می کند و مصنوعات را برای تصاویر عمومی کاهش می دهد.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler بهینه شده برای تصاویر انیمه. نوع 4B32F با جزئیات واضح تر و خطوط صاف.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp مدل V2 برای تصاویر عمومی; بر وضوح و وضوح تأکید می کند.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; سریعتر و کوچکتر، جزئیات را حفظ می کند و در عین حال از حافظه GPU کمتری استفاده می کند.</string>\n    <string name=\"model_rmbg_1_4\">مدل سبک وزن برای حذف سریع پس زمینه. عملکرد و دقت متعادل. با پرتره ها، اشیا و صحنه ها کار می کند. برای بیشتر موارد استفاده توصیه می شود.</string>\n    <string name=\"type_removebg\">BG را حذف کنید</string>\n    <string name=\"horizontal_border_thickness\">ضخامت مرز افقی</string>\n    <string name=\"vertical_border_thickness\">ضخامت حاشیه عمودی</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s رنگ</item>\n        <item quantity=\"other\">%1$s رنگ</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">مدل فعلی از تکه‌شدن پشتیبانی نمی‌کند، تصویر در ابعاد اصلی پردازش می‌شود، این ممکن است باعث مصرف زیاد حافظه و مشکلات دستگاه‌های رده پایین شود.</string>\n    <string name=\"chunking_disabled\">قطعه قطعه کردن غیرفعال است، تصویر در ابعاد اصلی پردازش می‌شود، این ممکن است باعث مصرف زیاد حافظه و مشکلات دستگاه‌های ارزان‌قیمت شود، اما ممکن است نتایج بهتری در استنتاج داشته باشد.</string>\n    <string name=\"chunking\">تکه تکه شدن</string>\n    <string name=\"model_u2net\">مدل تقسیم‌بندی تصویر با دقت بالا برای حذف پس‌زمینه</string>\n    <string name=\"model_u2netp\">نسخه سبک U2Net برای حذف سریع پس زمینه با استفاده از حافظه کمتر.</string>\n    <string name=\"model_ddcolor\">مدل Full DDColor رنگ‌بندی با کیفیت بالا را برای تصاویر عمومی با حداقل مصنوعات ارائه می‌کند. بهترین انتخاب از همه مدل های رنگ بندی.</string>\n    <string name=\"model_ddcolor_artistic\">مجموعه داده های هنری آموزش دیده و خصوصی DDColor. نتایج رنگ آمیزی متنوع و هنری را با مصنوعات رنگی غیر واقعی کمتر ایجاد می کند.</string>\n    <string name=\"model_birefnet\">مدل سبک BiRefNet بر اساس ترانسفورماتور Swin برای حذف دقیق پس زمینه.</string>\n    <string name=\"model_inspyrenet\">حذف پس‌زمینه با کیفیت بالا با لبه‌های تیز و حفظ جزئیات عالی، به‌ویژه در اشیاء پیچیده و پس‌زمینه‌های پیچیده.</string>\n    <string name=\"model_isnet\">مدل حذف پس‌زمینه که ماسک‌هایی دقیق با لبه‌های صاف، مناسب برای اشیاء عمومی و حفظ جزئیات متوسط ​​تولید می‌کند.</string>\n    <string name=\"model_already_downloaded\">مدل قبلا دانلود شده است</string>\n    <string name=\"model_successfully_imported\">مدل با موفقیت وارد شد</string>\n    <string name=\"type\">تایپ کنید</string>\n    <string name=\"keyword\">کلمه کلیدی</string>\n    <string name=\"very_fast\">خیلی سریع</string>\n    <string name=\"normal\">عادی</string>\n    <string name=\"slow\">کند</string>\n    <string name=\"very_slow\">خیلی آهسته</string>\n    <string name=\"compute_percents\">محاسبه درصد</string>\n    <string name=\"minimum_value_is\">حداقل مقدار %1$s است</string>\n    <string name=\"warp_sub\">با کشیدن انگشت، تصویر را تحریف کنید</string>\n    <string name=\"warp\">پیچ و تاب</string>\n    <string name=\"hardness\">سختی</string>\n    <string name=\"warp_mode\">حالت Warp</string>\n    <string name=\"warp_mode_move\">حرکت کنید</string>\n    <string name=\"warp_mode_grow\">رشد کنید</string>\n    <string name=\"warp_mode_shrink\">کوچک شدن</string>\n    <string name=\"warp_mode_swirl_cw\">چرخش CW</string>\n    <string name=\"warp_mode_swirl_ccw\">چرخش CCW</string>\n    <string name=\"fade_strength\">محو کردن قدرت</string>\n    <string name=\"top_drop\">رها کردن بالا</string>\n    <string name=\"bottom_drop\">افت پایین</string>\n    <string name=\"start_drop\">شروع رها کردن</string>\n    <string name=\"end_drop\">پایان رها کردن</string>\n    <string name=\"downloading\">در حال دانلود</string>\n    <string name=\"smooth_shapes\">اشکال صاف</string>\n    <string name=\"smooth_shapes_sub\">به جای مستطیل های گرد استاندارد از ابربیضی ها استفاده کنید تا شکل های صاف تر و طبیعی تر داشته باشید</string>\n    <string name=\"shape_type\">نوع شکل</string>\n    <string name=\"cut\">برش دهید</string>\n    <string name=\"rounded\">گرد شده</string>\n    <string name=\"smooth\">صاف</string>\n    <string name=\"cut_shapes_sub\">لبه های تیز بدون گرد</string>\n    <string name=\"rounded_shapes_sub\">گوشه های گرد کلاسیک</string>\n    <string name=\"shapes_type\">نوع اشکال</string>\n    <string name=\"corners_size\">اندازه گوشه ها</string>\n    <string name=\"squircle\">سنجاب</string>\n    <string name=\"squircle_shapes_sub\">عناصر رابط کاربری گرد و زیبا</string>\n    <string name=\"filename_format\">فرمت نام فایل</string>\n    <string name=\"prefix_pattern_description\">متن سفارشی قرار داده شده در همان ابتدای نام فایل، مناسب برای نام پروژه، مارک ها، یا برچسب های شخصی.</string>\n    <string name=\"original_filename_pattern_description\">از نام فایل اصلی بدون پسوند استفاده می کند و به شما کمک می کند تا شناسایی منبع را دست نخورده نگه دارید.</string>\n    <string name=\"width_pattern_description\">عرض تصویر بر حسب پیکسل، برای ردیابی تغییرات وضوح یا مقیاس بندی نتایج مفید است.</string>\n    <string name=\"height_pattern_description\">ارتفاع تصویر بر حسب پیکسل، هنگام کار با نسبت ابعاد یا صادرات مفید است.</string>\n    <string name=\"random_numbers_pattern_description\">ارقام تصادفی را برای تضمین نام فایل های منحصر به فرد تولید می کند. برای ایمنی بیشتر در برابر موارد تکراری، ارقام بیشتری اضافه کنید.</string>\n    <string name=\"sequence_number_pattern_description\">شمارنده افزایش خودکار برای صادرات دسته ای، ایده آل برای ذخیره چندین تصویر در یک جلسه.</string>\n    <string name=\"preset_info_pattern_description\">نام از پیش تعیین شده اعمال شده را در نام فایل درج می کند تا بتوانید به راحتی نحوه پردازش تصویر را به خاطر بسپارید.</string>\n    <string name=\"scale_mode_pattern_description\">حالت مقیاس‌بندی تصویر را که در حین پردازش استفاده می‌شود، نمایش می‌دهد و به تشخیص تصاویر تغییر اندازه، برش‌خورده یا متناسب کمک می‌کند.</string>\n    <string name=\"suffix_pattern_description\">متن سفارشی قرار داده شده در انتهای نام فایل، مفید برای نسخه سازی مانند _v2، _edited، یا _final.</string>\n    <string name=\"extension_pattern_description\">پسوند فایل (png، jpg، webp، و غیره)، به طور خودکار با فرمت ذخیره شده واقعی مطابقت دارد.</string>\n    <string name=\"formatted_timestamp_pattern_description\">یک مهر زمانی قابل تنظیم که به شما امکان می دهد قالب خود را با مشخصات جاوا برای مرتب سازی کامل تعریف کنید.</string>\n    <string name=\"fling_type\">نوع پرت کردن</string>\n    <string name=\"android_native\">اندروید بومی</string>\n    <string name=\"ios_style\">سبک iOS</string>\n    <string name=\"smooth_curve\">منحنی صاف</string>\n    <string name=\"quick_stop\">توقف سریع</string>\n    <string name=\"bouncy\">فنری</string>\n    <string name=\"floaty\">شناور</string>\n    <string name=\"snappy\">اسنپی</string>\n    <string name=\"ultra_smooth\">فوق العاده صاف</string>\n    <string name=\"adaptive\">تطبیقی</string>\n    <string name=\"accessibility_aware\">آگاهی از دسترسی</string>\n    <string name=\"reduced_motion\">حرکت کاهش یافته</string>\n    <string name=\"android_native_sub\">فیزیک اسکرول اندروید بومی برای مقایسه پایه</string>\n    <string name=\"smooth_sub\">پیمایش متعادل و روان برای استفاده عمومی</string>\n    <string name=\"ios_style_sub\">رفتار پیمایش مانند iOS با اصطکاک بالاتر</string>\n    <string name=\"smooth_curve_sub\">منحنی اسپلاین منحصر به فرد برای حس اسکرول متمایز</string>\n    <string name=\"quick_stop_sub\">پیمایش دقیق با توقف سریع</string>\n    <string name=\"bouncy_sub\">اسکرول فنری بازیگوش و پاسخگو</string>\n    <string name=\"floaty_sub\">طومارهای بلند و سرخورده برای مرور محتوا</string>\n    <string name=\"snappy_sub\">پیمایش سریع و پاسخگو برای رابط های کاربری تعاملی</string>\n    <string name=\"ultra_smooth_sub\">پیمایش صاف ممتاز با حرکت گسترده</string>\n    <string name=\"adaptive_sub\">فیزیک را بر اساس سرعت پرتاب تنظیم می کند</string>\n    <string name=\"accessibility_aware_sub\">به تنظیمات دسترسی سیستم احترام می گذارد</string>\n    <string name=\"reduced_motion_sub\">حداقل حرکت برای نیازهای دسترسی</string>\n    <string name=\"primary_lines\">خطوط اولیه</string>\n    <string name=\"primary_lines_sub\">هر خط پنجم خط ضخیم‌تری اضافه می‌کند</string>\n    <string name=\"fill_color\">رنگ را پر کنید</string>\n    <string name=\"hidden_tools\">ابزارهای پنهان</string>\n    <string name=\"hidden_for_share\">ابزارهای پنهان برای اشتراک گذاری</string>\n    <string name=\"color_library\">کتابخانه رنگ</string>\n    <string name=\"color_library_sub\">مجموعه گسترده ای از رنگ ها را مرور کنید</string>\n    <string name=\"model_fatality_deblur\">با حفظ جزئیات طبیعی، تاری تصاویر را واضح می کند و از بین می برد که برای رفع عکس های خارج از فوکوس ایده آل است.</string>\n    <string name=\"model_unresize_v3\">به طور هوشمند تصاویری را که قبلاً تغییر اندازه داده اند، بازیابی می کند و جزئیات و بافت های از دست رفته را بازیابی می کند.</string>\n    <string name=\"model_liveaction_v1_span\">برای محتوای لایو اکشن بهینه شده است، آثار فشرده سازی را کاهش می دهد و جزئیات دقیق را در قاب های فیلم/نمایش تلویزیونی بهبود می بخشد.</string>\n    <string name=\"model_vhs2hd_realplksr\">فیلم‌های با کیفیت VHS را به HD تبدیل می‌کند، نویز نوار را حذف می‌کند و وضوح را افزایش می‌دهد و در عین حال احساس قدیمی را حفظ می‌کند.</string>\n    <string name=\"model_text2hd_v1\">مخصوص تصاویر و اسکرین شات های سنگین متن، کاراکترها را واضح می کند و خوانایی را بهبود می بخشد.</string>\n    <string name=\"model_frankendata_pretrainer\">ارتقاء مقیاس پیشرفته آموزش دیده بر روی مجموعه داده های متنوع، عالی برای بهبود عکس های همه منظوره.</string>\n    <string name=\"model_realwebphoto_v2\">برای عکس های فشرده شده تحت وب بهینه شده است، مصنوعات JPEG را حذف می کند و ظاهر طبیعی را بازیابی می کند.</string>\n    <string name=\"model_realwebphoto_v4\">نسخه بهبود یافته برای عکس های وب با حفظ بافت بهتر و کاهش مصنوعات.</string>\n    <string name=\"model_dat_2x\">ارتقاء 2 برابری با فناوری Dual Aggregation Transformer، وضوح و جزئیات طبیعی را حفظ می کند.</string>\n    <string name=\"model_dat_3x\">ارتقاء 3 برابری با استفاده از معماری پیشرفته ترانسفورماتور، ایده آل برای نیازهای بزرگنمایی متوسط.</string>\n    <string name=\"model_dat_4x\">ارتقاء 4 برابری با کیفیت بالا با شبکه ترانسفورماتور پیشرفته، جزئیات دقیق را در مقیاس های بزرگتر حفظ می کند.</string>\n    <string name=\"model_nafnet_deblurring\">تاری/نویز و لرزش را از عکس ها حذف می کند. هدف کلی اما بهترین در عکس.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">تصاویر با کیفیت پایین را با استفاده از ترانسفورماتور Swin2SR که برای تخریب BSRGAN بهینه شده است، بازیابی می کند. برای تثبیت مصنوعات فشرده سازی سنگین و بهبود جزئیات در مقیاس 4 برابر عالی است.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">ارتقاء 4 برابری با ترانسفورماتور SwinIR آموزش دیده در مورد تخریب BSRGAN. از GAN برای بافت های واضح تر و جزئیات طبیعی تر در عکس ها و صحنه های پیچیده استفاده می کند.</string>\n    <string name=\"path\">مسیر</string>\n    <string name=\"merge_pdf\">PDF را ادغام کنید</string>\n    <string name=\"merge_pdf_sub\">چندین فایل PDF را در یک سند ترکیب کنید</string>\n    <string name=\"files_order\">ترتیب فایل ها</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">تقسیم PDF</string>\n    <string name=\"split_pdf_sub\">صفحات خاصی را از سند PDF استخراج کنید</string>\n    <string name=\"rotate_pdf\">PDF را بچرخانید</string>\n    <string name=\"rotate_pdf_sub\">جهت گیری صفحه را به طور دائم رفع کنید</string>\n    <string name=\"pages\">صفحات</string>\n    <string name=\"rearrange_pdf\">پی دی اف را دوباره تنظیم کنید</string>\n    <string name=\"rearrange_pdf_sub\">صفحات را بکشید و رها کنید تا آنها را دوباره مرتب کنید</string>\n    <string name=\"hold_drag_drop\">صفحات را نگه و بکشید</string>\n    <string name=\"page_numbers\">شماره صفحه</string>\n    <string name=\"page_numbers_sub\">شماره گذاری را به صورت خودکار به اسناد خود اضافه کنید</string>\n    <string name=\"label_format\">قالب برچسب</string>\n    <string name=\"pdf_to_text\">PDF به متن (OCR)</string>\n    <string name=\"pdf_to_text_sub\">متن ساده را از اسناد PDF خود استخراج کنید</string>\n    <string name=\"watermark_pdf_sub\">متن سفارشی را برای نام تجاری یا امنیت پوشش دهید</string>\n    <string name=\"signature\">امضا</string>\n    <string name=\"signature_sub\">امضای الکترونیکی خود را به هر سندی اضافه کنید</string>\n    <string name=\"will_be_for_signature\">این به عنوان امضا استفاده خواهد شد</string>\n    <string name=\"unlock_pdf\">قفل PDF را باز کنید</string>\n    <string name=\"unlock_pdf_sub\">رمزهای عبور را از فایل های محافظت شده خود حذف کنید</string>\n    <string name=\"protect_pdf\">محافظت از PDF</string>\n    <string name=\"protect_pdf_sub\">اسناد خود را با رمزگذاری قوی ایمن کنید</string>\n    <string name=\"success\">موفقیت</string>\n    <string name=\"pdf_unlocked\">PDF باز شد، می توانید آن را ذخیره یا به اشتراک بگذارید</string>\n    <string name=\"repair_pdf\">PDF را تعمیر کنید</string>\n    <string name=\"repair_pdf_sub\">تلاش برای تعمیر اسناد خراب یا ناخوانا</string>\n    <string name=\"grayscale\">مقیاس خاکستری</string>\n    <string name=\"grayscale_pdf_sub\">همه تصاویر جاسازی شده سند را به مقیاس خاکستری تبدیل کنید</string>\n    <string name=\"compress_pdf\">فشرده سازی PDF</string>\n    <string name=\"compress_pdf_sub\">اندازه فایل سند خود را برای اشتراک گذاری آسان تر بهینه کنید</string>\n    <string name=\"repair_info\">ImageToolbox جدول مرجع متقابل داخلی را بازسازی می کند و ساختار فایل را از ابتدا بازسازی می کند. این می‌تواند دسترسی به بسیاری از فایل‌هایی را که \\\\\"باز نمی‌شوند\\\\\" بازیابی کند.</string>\n    <string name=\"grayscale_info\">این ابزار تمام تصاویر سند را به مقیاس خاکستری تبدیل می کند. بهترین برای چاپ و کاهش حجم فایل</string>\n    <string name=\"metadata\">فراداده</string>\n    <string name=\"metadata_pdf_sub\">ویژگی های سند را برای حفظ حریم خصوصی بهتر ویرایش کنید</string>\n    <string name=\"tags\">برچسب ها</string>\n    <string name=\"producer\">تولید کننده</string>\n    <string name=\"author\">نویسنده</string>\n    <string name=\"keywords\">کلمات کلیدی</string>\n    <string name=\"creator\">خالق</string>\n    <string name=\"privacy_deep_clean\">حفظ حریم خصوصی Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">تمام ابرداده های موجود برای این سند را پاک کنید</string>\n    <string name=\"page\">صفحه</string>\n    <string name=\"deep_ocr\">OCR عمیق</string>\n    <string name=\"deep_ocr_sub\">متن را از سند استخراج کرده و با استفاده از موتور Tesseract در یک فایل متنی ذخیره کنید</string>\n    <string name=\"cant_remove_all\">نمی توان همه صفحات را حذف کرد</string>\n    <string name=\"remove_pages_pdf\">صفحات PDF را حذف کنید</string>\n    <string name=\"remove_pages_pdf_sub\">صفحات خاصی را از سند PDF حذف کنید</string>\n    <string name=\"tap_to_remove\">برای حذف ضربه بزنید</string>\n    <string name=\"manually\">به صورت دستی</string>\n    <string name=\"crop_pdf\">برش PDF</string>\n    <string name=\"crop_pdf_sub\">صفحات سند را به هر حدی برش دهید</string>\n    <string name=\"flatten_pdf\">PDF را صاف کنید</string>\n    <string name=\"flatten_pdf_sub\">PDF را با شطرنجی کردن صفحات سند غیرقابل تغییر کنید</string>\n    <string name=\"camera_failed_to_open\">نمی توان دوربین را راه اندازی کرد. لطفاً مجوزها را بررسی کنید و مطمئن شوید که توسط برنامه دیگری استفاده نمی‌شود.</string>\n    <string name=\"extract_images\">استخراج تصاویر</string>\n    <string name=\"extract_images_sub\">تصاویر جاسازی شده در PDF را با وضوح اصلی خود استخراج کنید</string>\n    <string name=\"pdf_no_embedded\">این فایل PDF حاوی هیچ تصویر تعبیه شده نیست</string>\n    <string name=\"extract_images_info\">این ابزار هر صفحه را اسکن می کند و تصاویر منبع با کیفیت کامل را بازیابی می کند - برای ذخیره نسخه های اصلی از اسناد عالی است</string>\n    <string name=\"draw_signature\">رسم امضا</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">از امضای خود به عنوان تصویر برای قرار دادن روی اسناد استفاده کنید</string>\n    <string name=\"zip_pdf\">زیپ PDF</string>\n    <string name=\"zip_pdf_sub\">سند را با فاصله زمانی مشخص تقسیم کنید و اسناد جدید را در بایگانی فشرده قرار دهید</string>\n    <string name=\"interval\">فاصله</string>\n    <string name=\"print_pdf\">PDF چاپ کنید</string>\n    <string name=\"print_pdf_sub\">سند را برای چاپ با اندازه صفحه سفارشی آماده کنید</string>\n    <string name=\"pages_per_sheet\">صفحات در هر برگه</string>\n    <string name=\"orientation\">جهت گیری</string>\n    <string name=\"page_size\">اندازه صفحه</string>\n    <string name=\"margin\">حاشیه</string>\n    <string name=\"bloom\">شکوفه دادن</string>\n    <string name=\"soft_knee\">زانو نرم</string>\n    <string name=\"model_realesr_animevideo_v3x4\">بهینه شده برای انیمیشن و کارتون. ارتقاء سریع با رنگ های طبیعی بهبود یافته و مصنوعات کمتر</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 دارای سبکی است</string>\n    <string name=\"calculate_hint\">برای محاسبه مقدار مورد نظر، نمادهای ریاضی پایه را در اینجا وارد کنید (به عنوان مثال (5+5)*10)</string>\n    <string name=\"math_expression\">بیان ریاضی</string>\n    <string name=\"pick_up_to_n_collage_images\">حداکثر %1$s عکس را انتخاب کنید</string>\n    <string name=\"keep_date_time\">زمان تاریخ را حفظ کنید</string>\n    <string name=\"keep_date_time_sub\">همیشه برچسب های exif مربوط به تاریخ و زمان را حفظ کنید، مستقل از گزینه keep exif کار می کند</string>\n    <string name=\"background_color_for_alpha_formats\">رنگ پس زمینه برای فرمت های آلفا</string>\n    <string name=\"background_color_for_alpha_formats_sub\">قابلیت تنظیم رنگ پس‌زمینه برای هر فرمت تصویر با پشتیبانی آلفا را اضافه می‌کند، در صورت غیرفعال بودن این امکان فقط برای قالب‌های غیر آلفا در دسترس است.</string>\n    <string name=\"open_markup_project\">پروژه را باز کنید</string>\n    <string name=\"open_markup_project_sub\">به ویرایش پروژه جعبه ابزار تصویر ذخیره شده قبلی ادامه دهید</string>\n    <string name=\"markup_project_open_failed\">پروژه جعبه ابزار تصویر باز نمی شود</string>\n    <string name=\"markup_project_missing_data\">پروژه جعبه ابزار تصویر فاقد داده های پروژه است</string>\n    <string name=\"markup_project_corrupted\">پروژه جعبه ابزار تصویر خراب است</string>\n    <string name=\"unsupported_markup_project_version\">نسخه پروژه جعبه ابزار تصویر پشتیبانی نشده: %1$d</string>\n    <string name=\"save_markup_project\">ذخیره پروژه</string>\n    <string name=\"save_markup_project_sub\">لایه ها، پس زمینه و تاریخچه ویرایش را در یک فایل پروژه قابل ویرایش ذخیره کنید</string>\n    <string name=\"failed_to_open\">باز نشد</string>\n    <string name=\"ocr_write_to_searchable_pdf\">نوشتن در PDF قابل جستجو</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">متن را از دسته تصویر تشخیص دهید و PDF قابل جستجو را با تصویر و لایه متن قابل انتخاب ذخیره کنید</string>\n    <string name=\"layer_alpha\">لایه آلفا</string>\n    <string name=\"horizontal_flip\">تلنگر افقی</string>\n    <string name=\"vertical_flip\">چرخش عمودی</string>\n    <string name=\"lock\">قفل</string>\n    <string name=\"add_shadow\">سایه اضافه کنید</string>\n    <string name=\"shadow_color\">رنگ سایه</string>\n    <string name=\"text_geometry\">هندسه متن</string>\n    <string name=\"text_geometry_sub\">برای سبک‌سازی واضح‌تر، متن را کشیده یا کج کنید</string>\n    <string name=\"scale_x\">مقیاس X</string>\n    <string name=\"skew_x\">کج X</string>\n    <string name=\"remove_annotations\">حاشیه نویسی ها را حذف کنید</string>\n    <string name=\"remove_annotations_sub\">انواع حاشیه نویسی انتخاب شده مانند پیوندها، نظرات، هایلایت ها، اشکال یا فیلدهای فرم را از صفحات PDF حذف کنید.</string>\n    <string name=\"annotation_link\">هایپرلینک ها</string>\n    <string name=\"annotation_file_attachment\">فایل های پیوست</string>\n    <string name=\"annotation_line\">خطوط</string>\n    <string name=\"annotation_popup\">پنجره های بازشو</string>\n    <string name=\"annotation_stamp\">تمبر</string>\n    <string name=\"annotation_shapes\">اشکال</string>\n    <string name=\"annotation_text\">یادداشت های متنی</string>\n    <string name=\"annotation_text_markup\">نشانه گذاری متن</string>\n    <string name=\"annotation_widget\">فیلدهای فرم</string>\n    <string name=\"annotation_markup\">نشانه گذاری</string>\n    <string name=\"annotation_unknown\">ناشناس</string>\n    <string name=\"annotations\">حاشیه نویسی ها</string>\n    <string name=\"ungroup\">لغو گروه کردن</string>\n    <string name=\"add_shadow_sub\">سایه تاری پشت لایه را با رنگ قابل تنظیم و افست اضافه کنید</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-fi/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"width\">Leveys %1$s</string>\n    <string name=\"height\">Korkeus %1$s</string>\n    <string name=\"quality\">Laatu</string>\n    <string name=\"extension\">Lisäosa</string>\n    <string name=\"resize_type\">Koon muunto tyyppi</string>\n    <string name=\"explicit\">Selkeää</string>\n    <string name=\"pick_image_alt\">Valitse kuva</string>\n    <string name=\"stay\">Pysy</string>\n    <string name=\"smth_went_wrong\">Jokin meni väärin: %1$s</string>\n    <string name=\"size\">Koko %1$s</string>\n    <string name=\"image_too_large_preview\">\"Kuva on liian iso esikatseltavaksi, mutta tallennusta yritetään  joka tapauksessa\"</string>\n    <string name=\"pick_image\">Valitse kuva aloittaaksesi</string>\n    <string name=\"flexible\">Joustava</string>\n    <string name=\"reset_image\">Palauta kuva</string>\n    <string name=\"app_closing_sub\">Oletko todella varma että haluat sulkea sovelluksen?</string>\n    <string name=\"app_closing\">Ohjelma sulkeutuu</string>\n    <string name=\"close\">Sulje</string>\n    <string name=\"reset_image_sub\">Kuvanmuutokset palautuvat alku tilanteeseen</string>\n    <string name=\"values_reset\">Arvot asianmukaisesti asetettu</string>\n    <string name=\"reset\">Nollaa</string>\n    <string name=\"copied\">Kopioitu leikepöydälle</string>\n    <string name=\"no_exif\">EXIF tietoja ei löytynyt</string>\n    <string name=\"something_went_wrong\">Jotakin meni väärin</string>\n    <string name=\"restart_app\">Käynnistä sovellus uudelleen</string>\n    <string name=\"edit_exif\">Muokkaa EXIF</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">Ok</string>\n    <string name=\"exception\">Poikkeus</string>\n    <string name=\"loading\">Ladataan…</string>\n    <string name=\"add_tag\">Lisää tagi</string>\n    <string name=\"save\">Tallenna</string>\n    <string name=\"clear\">Selvä</string>\n    <string name=\"clear_exif\">Puhdas EXIF</string>\n    <string name=\"cancel\">Peruuta</string>\n    <string name=\"clear_exif_sub\">Kaikki kuvan EXIF tiedot tullaan pyyhkimään. Tätä toimintoa ei voi perua!</string>\n    <string name=\"presets\">Esiasetukset</string>\n    <string name=\"crop\">Leikkaa</string>\n    <string name=\"image_not_saved\">Tallennus</string>\n    <string name=\"image_not_saved_sub\">Kaikki tallentamattomat muutokset katoavat, jos poistut nyt</string>\n    <string name=\"check_source_code\">Lähdekoodi</string>\n    <string name=\"check_source_code_sub\">Saa tuoreimmat uutiset, keskustele ongelmista ja paljon muuta</string>\n    <string name=\"single_edit\">Yksittäinen muokkaus</string>\n    <string name=\"single_edit_sub\">Muunna, muuta kokoa ja muokkaa kuvaa</string>\n    <string name=\"pick_color\">Värin valitsin</string>\n    <string name=\"pick_color_sub\">Ota väri kuvasta, kopioi tai jaa</string>\n    <string name=\"image\">Kuva</string>\n    <string name=\"color\">Väri</string>\n    <string name=\"color_copied\">Väri kopioitu</string>\n    <string name=\"crop_sub\">Rajaa kuvaa miten vain</string>\n    <string name=\"version\">Versio</string>\n    <string name=\"keep_exif\">Pidä EXIF</string>\n    <string name=\"images\">Kuvat: %d</string>\n    <string name=\"change_preview\">Muuta esikatselua</string>\n    <string name=\"remove\">Poista</string>\n    <string name=\"palette_sub\">Luo väri paletti näyte annetusta kuvasta</string>\n    <string name=\"generate_palette\">Luo paletti</string>\n    <string name=\"palette\">Paletti</string>\n    <string name=\"update\">Päivitys</string>\n    <string name=\"new_version\">Uusi versio %1$s</string>\n    <string name=\"unsupported_type\">Tukematon tyypi: %1$s</string>\n    <string name=\"no_palette\">Palettia ei voida luoda valitulle kuvalle</string>\n    <string name=\"original\">Alkuperäinen</string>\n    <string name=\"folder\">Tulostekansio</string>\n    <string name=\"def\">Oletus</string>\n    <string name=\"custom\">Muokattu</string>\n    <string name=\"unspecified\">Määrittelemätön</string>\n    <string name=\"device_storage\">Laitteen tallennustila</string>\n    <string name=\"by_bytes_resize\">Muuta kokoa korkeuden mukaan</string>\n    <string name=\"max_bytes\">Suurin koko KB</string>\n    <string name=\"by_bytes_resize_sub\">Muuta kuvan kokoa seuraamalla annettua kokoa kilobiteissä</string>\n    <string name=\"compare\">Vertaa</string>\n    <string name=\"compare_sub\">Vertaa kahta määritettyä kuvaa</string>\n    <string name=\"pick_two_images\">Valitse kaksi kuvaa aloitaaksesi</string>\n    <string name=\"pick_images\">Valitse kuvat</string>\n    <string name=\"settings\">Asetukset</string>\n    <string name=\"night_mode\">Yötila</string>\n    <string name=\"dark\">Pimeä</string>\n    <string name=\"light\">Valoisa</string>\n    <string name=\"system\">Järjestelmä</string>\n    <string name=\"dynamic_colors\">Dynaamiset värit</string>\n    <string name=\"customization\">Mukauttaminen</string>\n    <string name=\"allow_image_monet\">Salli kuvan moneetti</string>\n    <string name=\"allow_image_monet_sub\">Jos käytössä, kun valitset kuvan muokkausta varten sovelluksen värit muuttuvat kuvaan sopiviksi</string>\n    <string name=\"language\">Kieli</string>\n    <string name=\"amoled_mode\">AMOLED tila</string>\n    <string name=\"amoled_mode_sub\">Jos käytössä liittymien värit asetetaan absoluuttisen pimeään yötilassa</string>\n    <string name=\"color_scheme\">Värisuunnitelma</string>\n    <string name=\"color_red\">Punainen</string>\n    <string name=\"color_green\">Vihreä</string>\n    <string name=\"color_blue\">Sininen</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Liitä sopiva aRGB värikoodi</string>\n    <string name=\"clipboard_paste_invalid_empty\">Ei mitään liitettävää</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Sovelluksen värisuunitelmaa ei voida muuttaa kun dynaamisen värit ovat käytössä</string>\n    <string name=\"pick_accent_color\">Sovelluksen teema pohjautuu valittuun väriin</string>\n    <string name=\"about_app\">Lisätietoja sovelluksesta</string>\n    <string name=\"no_updates\">Päivityksiä ei löytynyt</string>\n    <string name=\"issue_tracker\">Ongelman jäljitin</string>\n    <string name=\"issue_tracker_sub\">Lähetä virhe raportteja ja ominaisuus ehdotuksia tänne</string>\n    <string name=\"help_translate\">Auta kääntämään</string>\n    <string name=\"help_translate_sub\">Korjaa käännös virheitä tai lokalisoi projekteja muille kielille</string>\n    <string name=\"nothing_found_by_search\">Kyselysi ei tuottanut tulosta</string>\n    <string name=\"search_here\">Etsi täältä</string>\n    <string name=\"dynamic_colors_sub\">Jos käytössä, sovelluksen värit mukautuvat taustakuvan väriin</string>\n    <string name=\"failed_to_save\">%d tallentaminen epäonnistui</string>\n    <string name=\"email\">Sähköpostiosoite</string>\n    <string name=\"primary\">Ensisijainen</string>\n    <string name=\"tertiary\">Kolmannen asteen</string>\n    <string name=\"secondary\">Toissijainen</string>\n    <string name=\"border_thickness\">Kulmien paksuus</string>\n    <string name=\"surface\">Taso</string>\n    <string name=\"values\">Arvot</string>\n    <string name=\"add\">Lisää</string>\n    <string name=\"permission\">Käyttöoikeus</string>\n    <string name=\"grant\">Anna</string>\n    <string name=\"permission_sub\">Sovellus tarvitsee käyttöoikeuden tallennustilaasi kuvien tallennusta varten, se on välttämätöntä. Anna oikeus seuraavaassa dialogi laatikossa</string>\n    <string name=\"grant_permission_manual\">Sovellus tarvitsee käyttöoikeuden toimiakseen, hyväksy se manuaalisesti</string>\n    <string name=\"external_storage\">Ulkoinen tallennustila</string>\n    <string name=\"monet_colors\">Moneetti väri</string>\n    <string name=\"donation_sub\">Tämä sovellus on täysin ilmainen, mutta jos haluat voit tukea sen kehitystä, voit painaa tästä</string>\n    <string name=\"fab_alignment\">FAB kohdistus</string>\n    <string name=\"check_updates\">Tarkista päivitykset</string>\n    <string name=\"check_updates_sub\">Jos käytössä, päivitys dialogi näytetään sinulle kun sovellus käynnistyy</string>\n    <string name=\"zoom\">Kuvan zoomaus</string>\n    <string name=\"share\">Jaa</string>\n    <string name=\"prefix\">Etuliite</string>\n    <string name=\"filename\">Tiedostonimi</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Valitse mikä emoji näytetään päänäytössä</string>\n    <string name=\"add_file_size\">Lisää tiedosto koko</string>\n    <string name=\"add_file_size_sub\">Jos käytössä, lisää leveyden ja pituuden tallennettuihin kuviin tulostiedoston nimeen</string>\n    <string name=\"delete_exif\">Poista EXIF</string>\n    <string name=\"delete_exif_sub\">Poistaa EXIF metatiedot mistä vain kuvasetistä</string>\n    <string name=\"image_preview\">Kuvan esikatselu</string>\n    <string name=\"image_preview_sub\">Esikatsele minkä vain tyyppisiä kuvia: GIF, SVG, ja niin edelleen</string>\n    <string name=\"image_source\">Kuvan lähde</string>\n    <string name=\"photo_picker\">Kuvan valitsin</string>\n    <string name=\"gallery_picker\">Galleria</string>\n    <string name=\"file_explorer_picker\">Tiedosto etsijä</string>\n    <string name=\"photo_picker_sub\">Androidin moderni kuvan valitsin mikä ilmestyy näytön alareunaan, voi toimia vain Android 12+ . Siinä on ongelmia EXIF metadatan vastaanottamisessa</string>\n    <string name=\"gallery_picker_sub\">Yksinkertainen galleria kuvan valitsin. Toimii vain jos sinulla on sovellus mikä tarjoaa median valintaa</string>\n    <string name=\"file_explorer_picker_sub\">Käytä GetContent tarkoituksena valita kuva. Toimii missä vain, mutta siinä tiedetään olevan ongelmia kuvien valinnassa joillakin laitteilla. Se ei ole minun vikani.</string>\n    <string name=\"options_arrangement\">Vaihtoehtojen järjestely</string>\n    <string name=\"edit\">Muokkaa</string>\n    <string name=\"order\">Järjestys</string>\n    <string name=\"order_sub\">Päättää työkalujen järjestyksen päänäytöllä</string>\n    <string name=\"emojis_count\">Emojien lukumäärä</string>\n    <string name=\"sequence_num\">SekvenssiNum</string>\n    <string name=\"original_filename\">AlkuperäinenTiedostonimi</string>\n    <string name=\"add_original_filename\">Lisää alkuperäinen tiedostonimi</string>\n    <string name=\"add_original_filename_sub\">Jos käytössä, lisää alkuperäisen tiedostonimen tuloskuvan nimeen</string>\n    <string name=\"replace_sequence_number\">Korvaa sekvenssi numero</string>\n    <string name=\"replace_sequence_number_sub\">Jos käytössä, korvaa standardin aikaleiman kuvan sekvenssi numerolla, jos käytät eräkäsittelyä</string>\n    <string name=\"filename_not_work_with_photopicker\">Alkuperäisen tiedostonimen lisääminen ei toimi, jos kuvan valitsin lähde on valittuna</string>\n    <string name=\"load_image_from_net\">Verkko Kuva Lataus</string>\n    <string name=\"load_image_from_net_sub\">Lataa joku kuva verkosta esikatseluun, zoomaa, editoi ja tallenna se jos haluat.</string>\n    <string name=\"no_image\">Ei kuvaa</string>\n    <string name=\"image_link\">Kuvan linkki</string>\n    <string name=\"fill\">Täytä</string>\n    <string name=\"fit\">Sovita</string>\n    <string name=\"content_scale\">Sisällön skaalaus</string>\n    <string name=\"explicit_description\">Muuta kuvan kokoa annettuun leveyteen ja pituuteen. Kuvan kuvasuhde voi muuttua.</string>\n    <string name=\"flexible_description\">Muokkaa leveiden kuvien kokoa annettuun leveyteen tai pituuteen. Kaikki koon laskennat tehdään tallennuksen jälkeen. Kuvien kuvasuhde säilytetään</string>\n    <string name=\"brightness\">Kirkkaus</string>\n    <string name=\"contrast\">Kontrasti</string>\n    <string name=\"hue\">Sävy</string>\n    <string name=\"saturation\">Saturaatio</string>\n    <string name=\"add_filter\">Lisää suodatin</string>\n    <string name=\"filter\">Suodatin</string>\n    <string name=\"filter_sub\">Lisää suodatin ketjuja kuviin</string>\n    <string name=\"filters\">Suodattimet</string>\n    <string name=\"light_aka_illumination\">Valoisa</string>\n    <string name=\"color_filter\">Väri suodatin</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"exposure\">Valotus</string>\n    <string name=\"white_balance\">Valkotasapaino</string>\n    <string name=\"temperature\">Lämpötila</string>\n    <string name=\"tint\">Sävy</string>\n    <string name=\"monochrome\">Monokroominen</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Kohokohdat ja varjot</string>\n    <string name=\"highlights\">Kohokohdat</string>\n    <string name=\"shadows\">Varjot</string>\n    <string name=\"haze\">Usva</string>\n    <string name=\"effect\">Tehoste</string>\n    <string name=\"distance\">Etäisyys</string>\n    <string name=\"slope\">Kaltevuus</string>\n    <string name=\"sharpen\">Terävöitys</string>\n    <string name=\"sepia\">Seepia</string>\n    <string name=\"negative\">Negatiivinen</string>\n    <string name=\"solarize\">Solaarisointi</string>\n    <string name=\"vibrance\">Elävyys</string>\n    <string name=\"black_and_white\">Musta Ja Valkoinen</string>\n    <string name=\"crosshatch\">Ristiviivoitus</string>\n    <string name=\"spacing\">Välistys</string>\n    <string name=\"line_width\">Viivan paksuus</string>\n    <string name=\"sobel_edge\">Sobelin terä</string>\n    <string name=\"blur\">Sumennus</string>\n    <string name=\"halftone\">Puolisävy</string>\n    <string name=\"cga_colorspace\">CGA väriavaruus</string>\n    <string name=\"gaussian_blur\">Gaussian sumennus</string>\n    <string name=\"box_blur\">Laatikkosumennus</string>\n    <string name=\"bilaterial_blur\">Kahdenvälinen sumennus</string>\n    <string name=\"emboss\">Kohokuvio</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Vignetti</string>\n    <string name=\"start\">Aloitus</string>\n    <string name=\"end\">Loppu</string>\n    <string name=\"kuwahara\">Kuwahara pehmennys</string>\n    <string name=\"stack_blur\">Päällekäis-sumennus</string>\n    <string name=\"radius\">Säde</string>\n    <string name=\"scale\">Skaalaus</string>\n    <string name=\"distortion\">Vääristymä</string>\n    <string name=\"angle\">Kulma</string>\n    <string name=\"swirl\">Pyöre</string>\n    <string name=\"bulge\">Pullistuma</string>\n    <string name=\"dilation\">Laajennus</string>\n    <string name=\"sphere_refraction\">Ympyrätaittuminen</string>\n    <string name=\"refractive_index\">taitekerroin</string>\n    <string name=\"glass_sphere_refraction\">Lasiympyrän taittuminen</string>\n    <string name=\"color_matrix\">Värimatrix</string>\n    <string name=\"opacity\">Läpinäkymättömyys</string>\n    <string name=\"limits_resize\">Muokkaa rajoissa</string>\n    <string name=\"limits_resize_sub\">Muokkaa kuvia annettuun leveyteen ja pituuteen säilyttäen silti kuvasuhteen</string>\n    <string name=\"sketch\">Luonnos</string>\n    <string name=\"threshold\">Kynnys</string>\n    <string name=\"quantizationLevels\">Kvantisointi tasot</string>\n    <string name=\"smooth_toon\">Sileä piirretty</string>\n    <string name=\"toon\">Piirrety</string>\n    <string name=\"posterize\">Posteroi</string>\n    <string name=\"non_maximum_suppression\">Ei maksimaalinen vaimennus</string>\n    <string name=\"weak_pixel_inclusion\">Heikko pikselien säilytys</string>\n    <string name=\"lookup\">Haku</string>\n    <string name=\"convolution3x3\">Konvoluutio 3x3</string>\n    <string name=\"rgb_filter\">RGB filtteri</string>\n    <string name=\"false_color\">Feikkiväri</string>\n    <string name=\"first_color\">Ensimmäinen väri</string>\n    <string name=\"second_color\">Toinen väri</string>\n    <string name=\"reorder\">Uudelleenjärjestely</string>\n    <string name=\"fast_blur\">Nopea sumennus</string>\n    <string name=\"blur_size\">Sumennuksen koko</string>\n    <string name=\"blur_center_x\">Sumennus keskus x</string>\n    <string name=\"blur_center_y\">Summenus keskus y</string>\n    <string name=\"zoom_blur\">Zoomaus sumennus</string>\n    <string name=\"color_balance\">Väri tasapaino</string>\n    <string name=\"luminance_threshold\">luminanssikynnys</string>\n    <string name=\"activate_files\">Poistut käytöstä Tiedostot sovelluksen, aktivoi se käyttääksesi tätä ominaisuutta</string>\n    <string name=\"draw\">Piirrä</string>\n    <string name=\"draw_sub\">Piirrä kuvaan, ihan kuin luonnoskirjaan, tai piirrä itse taustaan</string>\n    <string name=\"paint_color\">Maalin väri</string>\n    <string name=\"paint_alpha\">Alfamaali</string>\n    <string name=\"draw_on_image\">Piirrä kuvaan</string>\n    <string name=\"draw_on_image_sub\">Valitse kuva ja piirrä siihen jotakin</string>\n    <string name=\"draw_on_background\">Piirrä taustaan</string>\n    <string name=\"draw_on_background_sub\">Valitse taustan väri ja piirrä sen päälle</string>\n    <string name=\"background_color\">Taustan väri</string>\n    <string name=\"cipher\">Salainen</string>\n    <string name=\"cipher_sub\">Salaa ja pura minkä vain tiedoston (ei vain kuvien) salaus pohjattuna moniin olemassa oleviin salaus algoritmeihin</string>\n    <string name=\"pick_file\">Valitse tiedosto</string>\n    <string name=\"encrypt\">Salaa</string>\n    <string name=\"decrypt\">Pura salaus</string>\n    <string name=\"pick_file_to_start\">Valitse kansio aloitaaksesi</string>\n    <string name=\"decryption\">Salauksen purku</string>\n    <string name=\"encryption\">Salataan</string>\n    <string name=\"key\">Avain</string>\n    <string name=\"file_proceed\">Tiedosto käsitelty</string>\n    <string name=\"store_file_desc\">Tallenna tämä tiedosto laitteeseesi tai käytä jakotoimintoa laitaaksesi sen minne ikinä haluat</string>\n    <string name=\"features\">Ominaisuudet</string>\n    <string name=\"implementation\">Toteutus</string>\n    <string name=\"compatibility\">Yhteensopivuus</string>\n    <string name=\"features_sub\">Salasana pohjainen tiedostojen salaus. Valitut kansiot voidaan säilyttää valitussa hakemistossa tai jaettuna. Salaamattomat tiedostot voidaan avata suoraan</string>\n    <string name=\"implementation_sub\">AE-256, GCM tila, ei täytettä, 12 bittinen satunnainen IVs oletuksena. Voit valita vaaditun algoritmin. Avaimia käytetään 256-bit SHA-3 hasheina</string>\n    <string name=\"file_size\">Tiedosto koko</string>\n    <string name=\"file_size_sub\">Suurin tiedosto koko on rajoitettu Android OS:än ja saatavilla olevan muistin mukaan, minkä laite on päättänyt\\nHuomioi: Muisti ei ole tallennustila</string>\n    <string name=\"compatibility_sub\">Huomioi, että yhteensopivuus muiden tiedoston salaus sovellusten tai palvelujen kanssa ei ole taattu. Hieman erilainen avaimen käsittely tai salaus voi johtaa yhteensopimattomuuteen</string>\n    <string name=\"invalid_password_or_not_encrypted\">Väärä salasana, tai valittu kansio ei ole salattu</string>\n    <string name=\"image_size_warning\">Yritys tallentaa kuva annetulla leveydellä ja korkeudella voi johtaa muisti virheeseen. Teet tämän omalla vastuullasi.</string>\n    <string name=\"cache\">Välimuisti</string>\n    <string name=\"cache_size\">Välimuistin koko</string>\n    <string name=\"found_s\">Löydetty %1$s</string>\n    <string name=\"auto_cache_clearing\">Automaattinen välimuistin tyhjennys</string>\n    <string name=\"auto_cache_clearing_sub\">Jos käytössä, välimuisti tyhjennetään kun sovellus käynnistetään</string>\n    <string name=\"create\">Luo</string>\n    <string name=\"tools\">Työkalut</string>\n    <string name=\"group_options_by_type\">Ryhmitä vaihtoehdot tyypin mukaan</string>\n    <string name=\"group_options_by_type_sub\">Ryhmittää vaihtoehdot päänäytöllä niiden tyypin mukaan, muokatun lista järjestelyn sijaan</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Listausta ei voida muuttaa kun ryhmitys vaihtoehto on käytössä</string>\n    <string name=\"edit_screenshot\">Muokkaa kuvankaapausta</string>\n    <string name=\"secondary_customization\">Toissijainen muokkaus</string>\n    <string name=\"screenshot\">Kuvankaappaus</string>\n    <string name=\"fallback_option\">Varavaihtoehto</string>\n    <string name=\"skip\">Ohita</string>\n    <string name=\"copy\">Kopioi</string>\n    <string name=\"warning_bytes\">Tallennetaan %1$s sisällä. Tila voi olla epävakaa, koska se on häviötön formaatti</string>\n    <string name=\"presets_sub\" formatted=\"false\">Jos olet valinnut esiasetuksen 125, kuva tallennetaan 125% koossa alkuperäisestä kuvasta. Jos valitset esiasetuksen 50, sitten kuva tallentuu 50% kossa</string>\n    <string name=\"presets_sub_bytes\">Esiasetus täällä päättää tulostiedoston %, esim. jos valitset 50 5 megabitin kuvaan sitten siihen tulee 2,5 megabittiä lisää tallennuksen jälkeen</string>\n    <string name=\"randomize_filename\">Satunnaista tiedostonimi</string>\n    <string name=\"randomize_filename_sub\">Jos käytössä tulostiedoston tiedostonimi tulee olemaan täysin satunnainen</string>\n    <string name=\"saved_to\">Tallennettu %1$s kansioon nimellä %2$s</string>\n    <string name=\"saved_to_without_filename\">Tallennettu %1$s kansioon</string>\n    <string name=\"tg_chat\">Telegram chat</string>\n    <string name=\"tg_chat_sub\">Keskustele sovelluksesta ja saa palautetta muilta käyttäjiltä. Voit myös saada beetapäivityksiä ja esikatseluita.</string>\n    <string name=\"crop_mask\">Rajausmaski</string>\n    <string name=\"aspect_ratio\">Kuvasuhde</string>\n    <string name=\"image_crop_mask_sub\">Käytä tätä maskityyppiä luodaksesi maskin annetusta kuvasta, huomioi että sen PITÄISI sisältää alfakanavan</string>\n    <string name=\"backup_and_restore\">Varmuuskopioi ja palauta</string>\n    <string name=\"backup\">Varmuuskopioi</string>\n    <string name=\"restore\">Palauta</string>\n    <string name=\"backup_sub\">Varmuuskopioi sovelluksesi asetukset tiedostoon</string>\n    <string name=\"restore_sub\">Palauta sovelluksen asetukset aikaisemmin luodusta kansiosta</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Vaurioitunut tiedosto tai ei varmuuskopiota</string>\n    <string name=\"settings_restored\">Asetukset palautettu onnistuneesti</string>\n    <string name=\"contact_me\">Ole yhteydessä</string>\n    <string name=\"reset_settings_sub\">Tämä palauttaa kaikki asetukset oletus arvoihin. Huomioi että tätä ei voi peruuttaa ilman varmuuskopio kansiota, kuten mainittu aikaisemmin</string>\n    <string name=\"delete\">Peruuta</string>\n    <string name=\"delete_color_scheme_warn\">Aiot poistaa valitun värisuunnitelman. Tätä operaatiota ei voi peruuttaa</string>\n    <string name=\"delete_color_scheme_title\">Poista suunnittelma</string>\n    <string name=\"font\">Fontti</string>\n    <string name=\"text\">Teksti</string>\n    <string name=\"font_scale\">Fontin koko</string>\n    <string name=\"defaultt\">Oletus</string>\n    <string name=\"using_large_fonts_warn\">Suurten fontti kokojen käyttö voi aiheuttaa UI virheitä ja ongelmia, mitä ei voi korjata. Käytä varovaisuudella.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz Åå Ää Öö 0123456789 !?</string>\n    <string name=\"emotions\">Tunteet</string>\n    <string name=\"food_and_drink\">Ruoka Ja Juoma</string>\n    <string name=\"nature_and_animals\">Luonto Ja Eläimet</string>\n    <string name=\"objects\">Kohteet</string>\n    <string name=\"symbols\">Symboolit</string>\n    <string name=\"enable_emoji\">Käytä emojia</string>\n    <string name=\"travels_and_places\">Matkat Ja Paikat</string>\n    <string name=\"activities\">Aktiviteetit</string>\n    <string name=\"background_remover\">Taustan Poistaja</string>\n    <string name=\"background_remover_sub\">Poista tausta kuvasta piirtämällä tai käytä Auto vaihtoehtoa</string>\n    <string name=\"trim_image\">Leikkaa kuva</string>\n    <string name=\"keep_exif_sub\">Alkuperäisen kuvan metatiedot pidetään</string>\n    <string name=\"trim_image_sub\">Läpinäkyvät alueet kuvan ympärillä leikataan</string>\n    <string name=\"auto_erase_background\">Pyyhi automaattisesti tausta</string>\n    <string name=\"restore_image\">Palauta kuva</string>\n    <string name=\"erase_mode\">Pyyhin tila</string>\n    <string name=\"erase_background\">Pyyhi tausta</string>\n    <string name=\"restore_background\">Palauta tausta</string>\n    <string name=\"blur_radius\">Sumennuksen säde</string>\n    <string name=\"pipette\">Pipetti</string>\n    <string name=\"draw_mode\">Piirostila</string>\n    <string name=\"create_issue\">Luo julkaisu</string>\n    <string name=\"something_went_wrong_emphasis\">Hupsis… Jotain meni pieleen. Voit kirjoittaa minulle käyttäen vaihtoehtoja alhaalla ja yritän löytää ratkaisun</string>\n    <string name=\"resize_and_convert\">Muokkaa Ja Muunna</string>\n    <string name=\"resize_and_convert_sub\">Muokkaa annettujen kuvien kokoa tai muunna ne muihin formaateihin. EXIF metatietoa voidaan myös muokata täällä jos valitaan yksittäinen kuva.</string>\n    <string name=\"max_colors_count\">Suurin väri määrä</string>\n    <string name=\"crashlytics_sub\">Tämä sallii sovelluksen kerätä kastumisraporteja automaattisesti</string>\n    <string name=\"analytics\">Analytiikat</string>\n    <string name=\"analytics_sub\">Salli anonyymisen sovelluksen käyttötilastojen keräämiseen</string>\n    <string name=\"image_exif_warning\">Tällä hetkellä, %1$s formaatti salli vain EXIF metatietojen luvun Androidilla. Tuloskuvassa ei tule olemaan yhtään tallennettua metatietoa, kun tallennettu.</string>\n    <string name=\"effort\">Ponnistus</string>\n    <string name=\"effort_sub\">%1$s :n arvo tarkoittaa nopeaa tiivistystä, johtaen erittäin suureen tiedosto kokoon. %2$s tarkoittaa hitaampaa tiivistystä, johtaen pienempään tiedostoon.</string>\n    <string name=\"wait\">Odota</string>\n    <string name=\"saving_almost_complete\">Tallennus melkein valmis. Peruuttaminen nyt vaatii uudelleen tallennusta.</string>\n    <string name=\"updates\">Päivitykset</string>\n    <string name=\"allow_betas\">Salli beetat</string>\n    <string name=\"allow_betas_sub\">Päivitysten tarkastus tulee sisältämään beetaversiot, jos kytketty päälle</string>\n    <string name=\"draw_arrows\">Piirrä nuolia</string>\n    <string name=\"draw_arrows_sub\">Jos käytössä, polkujen piirtäminen tullaan näyttämään osoittavina nuolina</string>\n    <string name=\"brush_softness\">Pensselin pehmeys</string>\n    <string name=\"crop_description\">Kuvat tulevat olemaan keskitettyjä määritettyyn kokoon. Kankaat laajennetaan annetulla taustavärillä jos kuva on pienempi kun annetut mitat.</string>\n    <string name=\"donation\">Lahjoitus</string>\n    <string name=\"image_stitching\">Kuvan ompelu</string>\n    <string name=\"image_stitching_sub\">Yhdistä annetut kuvat saadaksesi yhden ison kuvan</string>\n    <string name=\"pick_at_least_two_images\">Valitse ainakin 2 kuvaa</string>\n    <string name=\"output_image_scale\">Tuloskuvan skaalaus</string>\n    <string name=\"image_orientation\">Kuvan suunta</string>\n    <string name=\"horizontal\">Horisontaalinen</string>\n    <string name=\"vertical\">Vertikaalinen</string>\n    <string name=\"scale_small_images_to_large\">Skaalaa pienet kuvat suuriksi</string>\n    <string name=\"scale_small_images_to_large_sub\">Pienet kuvat skaalataan isoimmaksi kuvaksi sekvenssissä, jos päällä</string>\n    <string name=\"images_order\">Kuvien järjestys</string>\n    <string name=\"regular\">Normaali</string>\n    <string name=\"blur_edges\">Sumennetut reunat</string>\n    <string name=\"blur_edges_sub\">Pittää sumennetut reunat alkuperäisen kuvan alapuolelle täyttääkseen tilaa sen ympärillä yhden värin sijaan, jos kytketty päälle</string>\n    <string name=\"pixelation\">Pikselöinti</string>\n    <string name=\"enhanced_pixelation\">Paranneltu pikselöinti</string>\n    <string name=\"stroke_pixelation\">Iskevä pikselöinti</string>\n    <string name=\"enhanced_diamond_pixelation\">Paranneltu Timantti Pikselöinti</string>\n    <string name=\"diamond_pixelation\">Timantti Pikselöinti</string>\n    <string name=\"circle_pixelation\">Ympyrä Pikselöinti</string>\n    <string name=\"enhanced_circle_pixelation\">Paranneltu Ympyrä Pikselöinti</string>\n    <string name=\"replace_color\">Korvaa Väri</string>\n    <string name=\"tolerance\">Toleranssi</string>\n    <string name=\"color_to_replace\">Väri Korvaukseen</string>\n    <string name=\"target_color\">Kohdeväri</string>\n    <string name=\"color_to_remove\">Väri Poistoon</string>\n    <string name=\"remove_color\">Poista Väri</string>\n    <string name=\"recode\">Uudelleen Koodaa</string>\n    <string name=\"pixel_size\">Pikseli Koko</string>\n    <string name=\"lock_draw_orientation\">Lukitse piirin kulma</string>\n    <string name=\"lock_draw_orientation_sub\">Jos päällä piirostilassa, näyttö ei käänny</string>\n    <string name=\"check_for_updates\">Tarkista päivitykset</string>\n    <string name=\"palette_style\">Paletti tyyli</string>\n    <string name=\"tonal_spot\">Tonaalinen Piste</string>\n    <string name=\"neutral\">Neutraali</string>\n    <string name=\"vibrant\">Eloisa</string>\n    <string name=\"expressive\">Ilmeikäs</string>\n    <string name=\"rainbow\">Sateenkaari</string>\n    <string name=\"fruit_salad\">Hedelmä Salaatti</string>\n    <string name=\"fidelity\">Uskollisuus</string>\n    <string name=\"content\">Kontentti</string>\n    <string name=\"tonal_spot_sub\">Oletusarvoinen palettityyli, se salli kaikkien neljän värin muokkauksen, muut sallivat sinun vain asettaa avain värin</string>\n    <string name=\"neutral_sub\">Tyyli, mikä on hieman enemmän kromaattinen kuin monokroominen</string>\n    <string name=\"vibrant_sub\">Äänekäs teema, värikkyys on täysillä Ensisijaiselle paketille, tehostettu muille</string>\n    <string name=\"playful_scheme\">Leikkisä teema, lähde värin sävy ei ilmesty teemassa</string>\n    <string name=\"monochrome_sub\">Monokroominen teema, värit ovat täysin mustia/valkoisia/harmaita</string>\n    <string name=\"content_sub\">Suunnitelma, mikä asettaa lähde värin Scheme primaryContainer :ssa</string>\n    <string name=\"fidelity_sub\">Suunnitelma, joka on samanlainen kontentti suunnitelman kanssa</string>\n    <string name=\"foss_update_checker_warning\">Tämä päivitystarkastus yhdistää GitHubiin tarkistaaksen onko siellä uusia päivityksiä saatavilla</string>\n    <string name=\"attention\">Huomio</string>\n    <string name=\"fading_edges\">Katoavat Reunat</string>\n    <string name=\"disabled\">Ei päällä</string>\n    <string name=\"both\">Molemmat</string>\n    <string name=\"invert_colors\">Käänteisvärit</string>\n    <string name=\"invert_colors_sub\">Korvaa teeman värit negatiivisilla, jos päällä</string>\n    <string name=\"search_option\">Etsi</string>\n    <string name=\"search_option_sub\">Kytkee päälle kyvyn etsiä kaikkien päänäytöllä olevien työkalujen avulla</string>\n    <string name=\"pdf_tools\">PDF työkalut</string>\n    <string name=\"pdf_tools_sub\">Operoi PDF tiedostojen kanssa: Esikatsele, Purista erä kuvia tai luo yksi annetuista kuvista</string>\n    <string name=\"preview_pdf\">Esikatsele PDF</string>\n    <string name=\"pdf_to_images\">PDF:stä kuvaan</string>\n    <string name=\"images_to_pdf\">Kuvista PDF:ään</string>\n    <string name=\"preview_pdf_sub\">Yksinkertainen PDF esikatselu</string>\n    <string name=\"pdf_to_images_sub\">Purista PDF annetun ulostulo formaatin kuviksi</string>\n    <string name=\"images_to_pdf_sub\">Pakkaa annetut kuvat ulostulo PDF tiedostoksi</string>\n    <string name=\"mask_filter\">Maski Suodatin</string>\n    <string name=\"mask_filter_sub\">Lisää suodatin ketjuja annettulle maskialuelle, jokainen maskialue voi päättää itse sen oman sarjan suodattimia</string>\n    <string name=\"masks\">Maskit</string>\n    <string name=\"add_mask\">Lisää Maski</string>\n    <string name=\"mask_indexed\">Maski %d</string>\n    <string name=\"mask_color\">Maskin Väri</string>\n    <string name=\"mask_preview\">Maskin Esikatselu</string>\n    <string name=\"mask_preview_sub\">Piiretty suodatinmaski rendeöidään näyttääkseen sinulle summittaisen tuloksen</string>\n    <string name=\"inverse_fill_type\">Käänteinen täyttötyyppi</string>\n    <string name=\"inverse_fill_type_sub\">Jos päällä jokainen ai maskeerattu alue tullaan suodattamaan, oletusarvoisen käyttäytymisen sijaan</string>\n    <string name=\"delete_mask_warn\">Olet poistamassa valittua suodatinmaskia. Tätä operaatiota ei voi peruuttaa</string>\n    <string name=\"delete_mask\">Poista maski</string>\n    <string name=\"full_filter\">Täysi Suodatin</string>\n    <string name=\"full_filter_sub\">Lisää minä vain suodatin ketju annettuihin kuviin tai yksittäiseen kuvaan</string>\n    <string name=\"start_position\">Aloita</string>\n    <string name=\"center_position\">Keskus</string>\n    <string name=\"end_position\">Loppu</string>\n    <string name=\"simple_variants\">Simppelit Variantit</string>\n    <string name=\"highlighter\">Kohokohdistaja</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Kynä</string>\n    <string name=\"privacy_blur\">Yksityis Summenus</string>\n    <string name=\"highlighter_sub\">Piirrä semi-läpinäkyviä tervöittetyjä kohokohdistaja polkuja</string>\n    <string name=\"neon_sub\">Lisää hieman hohto tehostetta piirokseesi</string>\n    <string name=\"pen_sub\">Oletusarvoinen, yksinkertainen - Vain väri</string>\n    <string name=\"privacy_blur_sub\">Summena kuva piirrospolun alapuolelta turvataksesi mitä vain mitä haluat piilottaa</string>\n    <string name=\"pixelation_sub\">Samanlainen Yksityis Sumennuksen kanssa, mutta pikselöi sumennuksen sijaan</string>\n    <string name=\"containers_shadow\">Säiliöt</string>\n    <string name=\"containers_shadow_sub\">Piirrä varjo säiliöiden taakse</string>\n    <string name=\"sliders_shadow\">Liukusäätimet</string>\n    <string name=\"switches_shadow\">Kytkimet</string>\n    <string name=\"fabs_shadow\">FAB:t</string>\n    <string name=\"buttons_shadow\">Painikkeet</string>\n    <string name=\"sliders_shadow_sub\">Piirrä varjo liukusäätimien taakse</string>\n    <string name=\"switches_shadow_sub\">Piirrä varjo kytkimien taakse</string>\n    <string name=\"fabs_shadow_sub\">Piirrä varjo kelluvien toimintapainikkeiden taakse</string>\n    <string name=\"buttons_shadow_sub\">Piirrä varjo painikkeiden taakse</string>\n    <string name=\"app_bars_shadow\">Sovelluspalkit</string>\n    <string name=\"app_bars_shadow_sub\">Piirrä varjo sovelluspalkkien taakse</string>\n    <string name=\"value_in_range\">Arvo välillä %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Automaattinen kierto</string>\n    <string name=\"auto_rotate_limits_sub\">Mahdollistaa rajaruudun käyttöönoton kuvan suunnassa</string>\n    <string name=\"draw_path_mode\">Piirrä polkutila</string>\n    <string name=\"double_line_arrow\">Kaksoisviivanuoli</string>\n    <string name=\"free_drawing\">Ilmainen piirustus</string>\n    <string name=\"double_arrow\">Kaksoisnuoli</string>\n    <string name=\"line_arrow\">Viivanuoli</string>\n    <string name=\"arrow\">Nuoli</string>\n    <string name=\"line\">Linja</string>\n    <string name=\"free_drawing_sub\">Piirtää polun syöttöarvona</string>\n    <string name=\"line_sub\">Piirtää polun aloituspisteestä loppupisteeseen suorana</string>\n    <string name=\"line_arrow_sub\">Piirtää osoittavan nuolen aloituspisteestä loppupisteeseen viivana</string>\n    <string name=\"arrow_sub\">Piirtää osoittavan nuolen tietystä polusta</string>\n    <string name=\"double_line_arrow_sub\">Piirtää kaksoisnuolen aloituspisteestä loppupisteeseen viivana</string>\n    <string name=\"double_arrow_sub\">Piirtää kaksoisnuolen annetulta polulta</string>\n    <string name=\"outlined_oval\">Piirretty soikea</string>\n    <string name=\"outlined_rect\">Outlined Rect</string>\n    <string name=\"oval\">Soikea</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Piirtää suoran aloituspisteestä loppupisteeseen</string>\n    <string name=\"oval_sub\">Piirtää soikean aloituspisteestä loppupisteeseen</string>\n    <string name=\"outlined_oval_sub\">Piirtää soikean ääriviivat aloituspisteestä loppupisteeseen</string>\n    <string name=\"outlined_rect_sub\">Piirtää ääriviivat suoraan aloituspisteestä loppupisteeseen</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Piirtää suljetun täytetyn polun annetun polun mukaan</string>\n    <string name=\"free\">Ilmainen</string>\n    <string name=\"horizontal_grid\">Vaakasuora verkko</string>\n    <string name=\"vertical_grid\">Pystysuora verkko</string>\n    <string name=\"stitch_mode\">Ommeltila</string>\n    <string name=\"rows_count\">Rivien määrä</string>\n    <string name=\"columns_count\">Sarakkeiden määrä</string>\n    <string name=\"no_such_directory\">Ei löytynyt \\\"%1$s\\\" hakemistoa, vaihdoimme sen oletushakemistoon, tallenna tiedosto uudelleen</string>\n    <string name=\"clipboard\">Leikepöytä</string>\n    <string name=\"auto_pin\">Automaattinen pin</string>\n    <string name=\"auto_pin_sub\">Lisää tallennetun kuvan automaattisesti leikepöydälle, jos se on käytössä</string>\n    <string name=\"vibration\">Tärinä</string>\n    <string name=\"vibration_strength\">Värähtelyn voimakkuus</string>\n    <string name=\"overwrite_file_requirements\">Tiedostojen korvaamiseksi sinun on käytettävä \\\"Explorer\\\"-kuvalähdettä, kokeile kuvien uudelleenpoimimista, olemme vaihtaneet kuvalähteen tarvittavaan</string>\n    <string name=\"overwrite_files\">Korvaa tiedostot</string>\n    <string name=\"overwrite_files_sub\">Alkuperäinen tiedosto korvataan uudella sen sijaan, että tallennettaisiin valittuun kansioon. Tämän vaihtoehdon kuvan lähteen on oltava \\\"Explorer\\\" tai GetContent, kun tätä vaihdetaan, se asetetaan automaattisesti</string>\n    <string name=\"empty\">Tyhjä</string>\n    <string name=\"suffix\">Suffiksi</string>\n    <string name=\"scale_mode\">Skaalaustila</string>\n    <string name=\"bilinear\">Bilineaarinen</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"hann\">Hän</string>\n    <string name=\"hermite\">Erakko</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Lähin</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Perus</string>\n    <string name=\"default_value\">Oletusarvo</string>\n    <string name=\"bilinear_sub\">Lineaarinen (tai bilineaarinen, kahdessa ulottuvuudessa) interpolointi on tyypillisesti hyvä kuvan koon muuttamiseen, mutta aiheuttaa ei-toivottua yksityiskohtien pehmenemistä ja voi silti olla hieman rosoinen.</string>\n    <string name=\"bicubic_sub\">Parempia skaalausmenetelmiä ovat Lanczos-resampling ja Mitchell-Netravali-suodattimet</string>\n    <string name=\"nearest_sub\">Yksi yksinkertaisimmista tavoista suurentaa kokoa, korvaa jokainen pikseli useilla samanvärisillä pikseleillä</string>\n    <string name=\"basic_sub\">Yksinkertaisin Android-skaalaustila, jota käytetään melkein kaikissa sovelluksissa</string>\n    <string name=\"catmull_sub\">Menetelmä ohjauspisteiden joukon sujuvaan interpoloimiseen ja uudelleennäytteenottoon, jota käytetään yleisesti tietokonegrafiikassa tasaisten käyrien luomiseen</string>\n    <string name=\"hann_sub\">Ikkunatoiminto, jota käytetään usein signaalinkäsittelyssä spektrivuodon minimoimiseksi ja taajuusanalyysin tarkkuuden parantamiseksi kapenemalla signaalin reunoja</string>\n    <string name=\"hermite_sub\">Matemaattinen interpolointitekniikka, joka käyttää arvoja ja johdannaisia ​​käyräsegmentin päätepisteissä luomaan tasaisen ja jatkuvan käyrän</string>\n    <string name=\"lanczos_sub\">Uudelleennäytteistysmenetelmä, joka ylläpitää korkealaatuista interpolaatiota käyttämällä painotettua sinc-funktiota pikseliarvoihin</string>\n    <string name=\"mitchell_sub\">Uudelleennäytteenottomenetelmä, joka käyttää konvoluutiosuodatinta säädettävillä parametreilla saavuttaakseen tasapainon terävyyden ja anti-aliasoinnin välillä skaalatussa kuvassa</string>\n    <string name=\"spline_sub\">Käyttää paloittain määriteltyjä polynomifunktioita käyrän tai pinnan sujuvaan interpoloimiseen ja approksimoimiseen, mikä tarjoaa joustavan ja jatkuvan muodon esityksen</string>\n    <string name=\"only_clip\">Vain klippi</string>\n    <string name=\"only_clip_sub\">Tallennusta tallennustilaan ei suoriteta, vaan kuvaa yritetään laittaa vain leikepöydälle</string>\n    <string name=\"restore_background_sub\">Sivellin palauttaa taustan poistamisen sijaan</string>\n    <string name=\"recognize_text\">OCR (tunnista teksti)</string>\n    <string name=\"recognize_text_sub\">Tunnista teksti annetusta kuvasta, tuettu yli 120 kieltä</string>\n    <string name=\"picture_has_no_text\">Kuvassa ei ole tekstiä tai sovellus ei löytänyt sitä</string>\n    <string name=\"accuracy\">\\\"Tarkkuus: %1$s\\\"</string>\n    <string name=\"recognition_type\">Tunnistustyyppi</string>\n    <string name=\"fast\">Nopeasti</string>\n    <string name=\"standard\">Vakio</string>\n    <string name=\"best\">Parhaat</string>\n    <string name=\"no_data\">Ei dataa</string>\n    <string name=\"download_description\">Jotta Tesseract OCR toimisi oikein, laitteellesi on ladattava lisää harjoitustietoja (%1$s).\\nHaluatko ladata %2$s-tiedot?</string>\n    <string name=\"download\">Lataa</string>\n    <string name=\"no_connection\">Ei yhteyttä, tarkista se ja yritä uudelleen ladataksesi junamallit</string>\n    <string name=\"downloaded_languages\">Ladatut kielet</string>\n    <string name=\"available_languages\">Saatavilla olevat kielet</string>\n    <string name=\"segmentation_mode\">Segmentointitila</string>\n    <string name=\"use_pixel_switch\">Käytä Pixel Switchiä</string>\n    <string name=\"use_pixel_switch_sub\">Käyttää Google Pixelin kaltaista kytkintä</string>\n    <string name=\"saved_to_original\">Ylikirjoitettu tiedosto nimellä %1$s alkuperäisessä kohteessa</string>\n    <string name=\"magnifier\">Suurennuslasi</string>\n    <string name=\"magnifier_sub\">Ottaa käyttöön suurennuslasin sormen yläosassa piirustustiloissa parantaakseen käytettävyyttä</string>\n    <string name=\"force_exif_widget_initial_value\">Pakota alkuarvo</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Pakottaa exif-widgetin tarkistettavaksi aluksi</string>\n    <string name=\"allow_multiple_languages\">Salli useita kieliä</string>\n    <string name=\"slide\">Liuku</string>\n    <string name=\"side_by_side\">Rinnakkain</string>\n    <string name=\"toggle_tap\">Toggle Tap</string>\n    <string name=\"transparency\">Läpinäkyvyys</string>\n    <string name=\"rate_app\">Arvioi sovellus</string>\n    <string name=\"rate\">Rate</string>\n    <string name=\"rate_app_sub\">Tämä sovellus on täysin ilmainen, jos haluat sen kasvavan, tähdä projekti Githubissa 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Vain suunta ja komentosarjan tunnistus</string>\n    <string name=\"segmentation_mode_auto_osd\">Automaattinen suuntaus ja komentosarjan tunnistus</string>\n    <string name=\"segmentation_mode_auto_only\">Vain auto</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Yksi sarake</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Yhden lohkon pystysuuntainen teksti</string>\n    <string name=\"segmentation_mode_single_block\">Yksi lohko</string>\n    <string name=\"segmentation_mode_single_line\">Yksi rivi</string>\n    <string name=\"segmentation_mode_single_word\">Yksi sana</string>\n    <string name=\"segmentation_mode_circle_word\">Ympyrä sana</string>\n    <string name=\"segmentation_mode_single_char\">Yksittäinen merkki</string>\n    <string name=\"segmentation_mode_sparse_text\">Vähän tekstiä</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Harva tekstin suuntaus ja komentosarjan tunnistus</string>\n    <string name=\"segmentation_mode_raw_line\">Raaka linja</string>\n    <string name=\"delete_language_sub\">Haluatko poistaa kielen \\\"%1$s\\\" OCR-harjoitustiedot kaikille tunnistustyypeille vai vain valitulle (%2$s)?</string>\n    <string name=\"current\">Nykyinen</string>\n    <string name=\"all\">Kaikki</string>\n    <string name=\"gradient_maker\">Gradientin tekijä</string>\n    <string name=\"gradient_maker_sub\">Luo tietyn tulostuskoon gradientti mukautetuilla väreillä ja ulkoasutyypillä</string>\n    <string name=\"gradient_type_linear\">Lineaarinen</string>\n    <string name=\"gradient_type_radial\">Säteittäinen</string>\n    <string name=\"gradient_type_sweep\">Lakaista</string>\n    <string name=\"gradient_type\">Gradientin tyyppi</string>\n    <string name=\"center_x\">Keskusta X</string>\n    <string name=\"center_y\">Keskusta Y</string>\n    <string name=\"tile_mode\">Laattatila</string>\n    <string name=\"tile_mode_repeated\">Toistettu</string>\n    <string name=\"tile_mode_mirror\">Peili</string>\n    <string name=\"tile_mode_clamp\">Puristin</string>\n    <string name=\"tile_mode_decal\">Tarra</string>\n    <string name=\"color_stops\">Väri pysähtyy</string>\n    <string name=\"add_color\">Lisää väriä</string>\n    <string name=\"properties\">Ominaisuudet</string>\n    <string name=\"brightness_enforcement\">Kirkkauden tehostaminen</string>\n    <string name=\"screen\">Näyttö</string>\n    <string name=\"gradient_maker_type_image\">Gradienttipeitto</string>\n    <string name=\"gradient_maker_type_image_sub\">Luo mikä tahansa kaltevuus annettujen kuvien yläreunasta</string>\n    <string name=\"transformations\">Muutokset</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Ota kuva kameralla. Huomaa, että tästä kuvalähteestä on mahdollista saada vain yksi kuva</string>\n    <string name=\"watermarking\">Vesileima</string>\n    <string name=\"watermarking_sub\">Peitä kuvat muokattavissa olevilla teksti-/kuvavesileimoilla</string>\n    <string name=\"repeat_watermark\">Toista vesileima</string>\n    <string name=\"repeat_watermark_sub\">Toistaa vesileiman kuvan päällä yksittäisen sijasta tietyssä kohdassa</string>\n    <string name=\"offset_x\">Offset X</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermark_type\">Vesileiman tyyppi</string>\n    <string name=\"watermarking_image_sub\">Tätä kuvaa käytetään vesileiman mallina</string>\n    <string name=\"text_color\">Tekstin väri</string>\n    <string name=\"overlay_mode\">Peittokuvatila</string>\n    <string name=\"gif_tools\">GIF-työkalut</string>\n    <string name=\"gif_tools_sub\">Muunna kuvat GIF-kuvaksi tai poimi kehyksiä annetusta GIF-kuvasta</string>\n    <string name=\"gif_type_to_image\">GIF kuviin</string>\n    <string name=\"gif_type_to_image_sub\">Muunna GIF-tiedosto kuvasarjaksi</string>\n    <string name=\"gif_type_to_gif_sub\">Muunna kuvaerä GIF-tiedostoksi</string>\n    <string name=\"gif_type_to_gif\">Kuvat GIF-muotoon</string>\n    <string name=\"select_gif_image_to_start\">Aloita valitsemalla GIF-kuva</string>\n    <string name=\"use_size_of_first_frame\">Käytä ensimmäisen kehyksen kokoa</string>\n    <string name=\"use_size_of_first_frame_sub\">Korvaa määritetty koko ensimmäisen kehyksen mitoilla</string>\n    <string name=\"repeat_count\">Toista Count</string>\n    <string name=\"frame_delay\">Kehyksen viive</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Käytä Lassoa</string>\n    <string name=\"use_lasso_sub\">Käyttää Lassoa kuten piirustustilassa pyyhkimiseen</string>\n    <string name=\"original_image_preview_alpha\">Alkuperäisen kuvan esikatselu Alpha</string>\n    <string name=\"confetti\">Konfetti</string>\n    <string name=\"confetti_sub\">Konfettia näytetään tallennuksen, jakamisen ja muiden ensisijaisten toimien yhteydessä</string>\n    <string name=\"secure_mode\">Suojattu tila</string>\n    <string name=\"secure_mode_sub\">Piilottaa sovelluksen sisällön viimeaikaisissa sovelluksissa. Sitä ei voi tallentaa tai tallentaa.</string>\n    <string name=\"exit\">Poistu</string>\n    <string name=\"preview_closing\">Jos poistut esikatselusta nyt, sinun on lisättävä kuvat uudelleen</string>\n    <string name=\"dithering\">Dathering</string>\n    <string name=\"quantizier\">Kvantisoija</string>\n    <string name=\"gray_scale\">Harmaa asteikko</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dathering</string>\n    <string name=\"bayer_eight_dithering\">Bayerin kahdeksaan kahdeksaan sekoitus</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis-tuomari Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Kaksirivinen Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Väärä Floyd Steinbergin närästys</string>\n    <string name=\"left_to_right_dithering\">Vasemmalta oikealle Dathering</string>\n    <string name=\"random_dithering\">Random Dithering</string>\n    <string name=\"simple_threshold_dithering\">Yksinkertainen kynnysvärähtely</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Spatiaalinen Sigma</string>\n    <string name=\"median_blur\">Mediaani sumeus</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Käyttää paloittain määriteltyjä bikuutiopolynomifunktioita käyrän tai pinnan sujuvaan interpoloimiseen ja approksimoimiseen, joustavaan ja jatkuvaan muodon esitykseen</string>\n    <string name=\"native_stack_blur\">Alkuperäinen pinon sumennus</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"glitch\">Virhe</string>\n    <string name=\"amount\">Määrä</string>\n    <string name=\"seed\">Siemen</string>\n    <string name=\"anaglyph\">Anaglyfi</string>\n    <string name=\"noise\">Melu</string>\n    <string name=\"pixel_sort\">Pikselilajittelu</string>\n    <string name=\"shuffle\">Sekoita</string>\n    <string name=\"enhanced_glitch\">Parannettu Glitch</string>\n    <string name=\"channel_shift_x\">Kanavanvaihto X</string>\n    <string name=\"channel_shift_y\">Kanavanvaihto Y</string>\n    <string name=\"corruption_size\">Korruption koko</string>\n    <string name=\"corruption_shift_x\">Korruption vaihto X</string>\n    <string name=\"corruption_shift_y\">Korruptiovuoro Y</string>\n    <string name=\"tent_blur\">Teltan hämärtyminen</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">Sivu</string>\n    <string name=\"top\">Yläosa</string>\n    <string name=\"bottom\">Pohja</string>\n    <string name=\"strength\">Vahvuus</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anisotrooppinen diffuusio</string>\n    <string name=\"diffusion\">Diffuusio</string>\n    <string name=\"conduction\">Johtuminen</string>\n    <string name=\"horizontal_wind_stagger\">Vaakasuuntainen tuuliporras</string>\n    <string name=\"fast_bilaterial_blur\">Nopea kaksipuolinen sumennus</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritminen sävykartoitus</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"crystallize\">Kiteytyä</string>\n    <string name=\"stroke_color\">Viivan väri</string>\n    <string name=\"fractal_glass\">Fraktaalilasi</string>\n    <string name=\"amplitude\">Amplitudi</string>\n    <string name=\"marble\">Marmori</string>\n    <string name=\"turbulence\">Turbulenssi</string>\n    <string name=\"oil\">Öljy</string>\n    <string name=\"water_effect\">Vesi vaikutus</string>\n    <string name=\"just_size\">Koko</string>\n    <string name=\"frequency_x\">Taajuus X</string>\n    <string name=\"frequency_y\">Taajuus Y</string>\n    <string name=\"amplitude_x\">Amplitudi X</string>\n    <string name=\"amplitude_y\">Amplitudi Y</string>\n    <string name=\"perlin_distortion\">Perlin vääristymä</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Tone -kartoitus</string>\n    <string name=\"speed\">Nopeus</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Värimatriisi 4x4</string>\n    <string name=\"color_matrix_3x3\">Värimatriisi 3x3</string>\n    <string name=\"simple_effects\">Yksinkertaiset tehosteet</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomaly</string>\n    <string name=\"deutaromaly\">Deuteranomaalia</string>\n    <string name=\"protonomaly\">Protanomaalia</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Brownin</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Night Vision</string>\n    <string name=\"warm\">Lämmin</string>\n    <string name=\"cool\">Viileä</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Akromatomia</string>\n    <string name=\"achromatopsia\">Achromatopsia</string>\n    <string name=\"grain\">Vilja</string>\n    <string name=\"unsharp\">Epäterävä</string>\n    <string name=\"pastel\">Pastelli</string>\n    <string name=\"orange_haze\">Oranssi Haze</string>\n    <string name=\"pink_dream\">Vaaleanpunainen unelma</string>\n    <string name=\"golden_hour\">Kultainen tunti</string>\n    <string name=\"hot_summer\">Kuuma kesä</string>\n    <string name=\"purple_mist\">Purppura sumu</string>\n    <string name=\"sunrise\">Auringonnousu</string>\n    <string name=\"colorful_swirl\">Värikäs pyörre</string>\n    <string name=\"soft_spring_light\">Pehmeä kevätvalo</string>\n    <string name=\"autumn_tones\">Syksyn sävyt</string>\n    <string name=\"lavender_dream\">Laventelin unelma</string>\n    <string name=\"cyberpunk\">Kyberpunk</string>\n    <string name=\"lemonade_light\">Limonadin valo</string>\n    <string name=\"spectral_fire\">Spektraalinen tuli</string>\n    <string name=\"night_magic\">Night Magic</string>\n    <string name=\"fantasy_landscape\">Fantasia maisema</string>\n    <string name=\"color_explosion\">Väriräjähdys</string>\n    <string name=\"electric_gradient\">Sähköinen gradientti</string>\n    <string name=\"caramel_darkness\">Karamellipimeys</string>\n    <string name=\"futuristic_gradient\">Futuristinen gradientti</string>\n    <string name=\"green_sun\">Vihreä aurinko</string>\n    <string name=\"rainbow_world\">Sateenkaaren maailma</string>\n    <string name=\"deep_purple\">Syvä violetti</string>\n    <string name=\"space_portal\">Avaruusportaali</string>\n    <string name=\"red_swirl\">Punainen Pyörre</string>\n    <string name=\"digital_code\">Digitaalinen koodi</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">Sovelluspalkin emoji muuttuu satunnaisesti</string>\n    <string name=\"random_emojis\">Satunnaiset emojit</string>\n    <string name=\"random_emojis_error\">Et voi käyttää satunnaisia ​​hymiöitä, kun emojit on poistettu käytöstä</string>\n    <string name=\"emoji_selection_error\">Et voi valita emojia, kun satunnaiset emojit ovat käytössä</string>\n    <string name=\"old_tv\">Vanha tv</string>\n    <string name=\"shuffle_blur\">Sekoita sumennus</string>\n    <string name=\"favorite\">Suosikki</string>\n    <string name=\"no_favorite_filters\">Suosikkisuodattimia ei ole vielä lisätty</string>\n    <string name=\"image_format\">Kuvan muoto</string>\n    <string name=\"icon_shape_sub\">Lisää valitun muodon sisältävän säilön kuvakkeiden alle</string>\n    <string name=\"icon_shape\">Ikonin muoto</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Katkaisu</string>\n    <string name=\"uchimura\">Heräät</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Siirtyminen</string>\n    <string name=\"peak\">Huippu</string>\n    <string name=\"color_anomaly\">Värien anomalia</string>\n    <string name=\"images_overwritten\">Kuvat on kirjoitettu alkuperäiseen kohteeseen</string>\n    <string name=\"cannot_change_image_format\">Kuvamuotoa ei voi muuttaa, kun tiedostojen korvaaminen on käytössä</string>\n    <string name=\"emoji_as_color_scheme\">Emoji värimaailmana</string>\n    <string name=\"emoji_as_color_scheme_sub\">Käyttää emojin pääväriä sovelluksen väriteemana manuaalisesti määritetyn väriteeman sijaan</string>\n    <string name=\"material_you_sub\">Luo Material You -paletin kuvasta</string>\n    <string name=\"dark_colors\">Tummat Värit</string>\n    <string name=\"dark_colors_sub\">Käyttää yötilan värimaailmaa vaalean version sijaan</string>\n    <string name=\"copy_as_compose_code\">Kopioi Jetpack Compose -koodina</string>\n    <string name=\"ring_blur\">Renkaan sumennus</string>\n    <string name=\"cross_blur\">Cross Blur</string>\n    <string name=\"circle_blur\">Ympyrän sumennus</string>\n    <string name=\"star_blur\">Tähtien sumennus</string>\n    <string name=\"linear_tilt_shift\">Lineaarinen Tilt-Shift</string>\n    <string name=\"tags_to_remove\">Poistettavat tunnisteet</string>\n    <string name=\"apng_tools\">APNG-työkalut</string>\n    <string name=\"apng_tools_sub\">Muunna kuvat APNG-kuvaksi tai poimi kehyksiä annetusta APNG-kuvasta</string>\n    <string name=\"apng_type_to_image\">APNG kuviin</string>\n    <string name=\"apng_type_to_image_sub\">Muunna APNG-tiedosto kuvasarjaksi</string>\n    <string name=\"apng_type_to_apng_sub\">Muunna kuvaerä APNG-tiedostoksi</string>\n    <string name=\"apng_type_to_apng\">Kuvat APNG:hen</string>\n    <string name=\"select_apng_image_to_start\">Aloita valitsemalla APNG-kuva</string>\n    <string name=\"motion_blur\">Liikesumennus</string>\n    <string name=\"zip\">Postinumero</string>\n    <string name=\"zip_sub\">Luo Zip-tiedosto annetuista tiedostoista tai kuvista</string>\n    <string name=\"drag_handle_width\">Vedä kahvan leveys</string>\n    <string name=\"confetti_type\">Konfetti tyyppi</string>\n    <string name=\"festive\">Juhlava</string>\n    <string name=\"explode\">Räjähtää</string>\n    <string name=\"rain\">Sade</string>\n    <string name=\"corners\">Kulmat</string>\n    <string name=\"jxl_tools\">JXL työkalut</string>\n    <string name=\"jxl_tools_sub\">Suorita JXL ~ JPEG-transkoodaus ilman laadun heikkenemistä tai muunna GIF/APNG JXL-animaatioksi</string>\n    <string name=\"jxl_type_to_jpeg\">JXL - JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Suorita häviötön transkoodaus JXL:stä JPEG:ksi</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Suorita häviötön transkoodaus JPEG:stä JXL:ksi</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG - JXL</string>\n    <string name=\"select_jxl_image_to_start\">Aloita valitsemalla JXL-kuva</string>\n    <string name=\"fast_gaussian_blur_2d\">Nopea Gaussian Blur 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Nopea Gaussian Blur 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Nopea Gaussian Blur 4D</string>\n    <string name=\"auto_paste\">Auton pääsiäinen</string>\n    <string name=\"auto_paste_sub\">Sallii sovelluksen liittää leikepöydän tiedot automaattisesti, joten ne näkyvät päänäytössä ja voit käsitellä niitä</string>\n    <string name=\"harmonization_color\">Harmonisointiväri</string>\n    <string name=\"harmonization_level\">Harmonisointitaso</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Uudelleennäytteenottomenetelmä, joka ylläpitää korkealaatuista interpolointia käyttämällä Bessel-funktiota (jinc) pikseliarvoihin</string>\n    <string name=\"gif_type_to_jxl\">GIF JXL:ään</string>\n    <string name=\"gif_type_to_jxl_sub\">Muunna GIF-kuvat JXL-animoiduiksi kuviksi</string>\n    <string name=\"apng_type_to_jxl\">APNG - JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Muunna APNG-kuvat JXL-animoiduiksi kuviksi</string>\n    <string name=\"jxl_type_to_images\">JXL kuviin</string>\n    <string name=\"jxl_type_to_images_sub\">Muunna JXL-animaatio kuvasarjaksi</string>\n    <string name=\"jxl_type_to_jxl\">Kuvat JXL:ään</string>\n    <string name=\"jxl_type_to_jxl_sub\">Muunna kuvasarja JXL-animaatioksi</string>\n    <string name=\"behavior\">Käyttäytyminen</string>\n    <string name=\"skip_file_picking\">Ohita tiedostojen poiminta</string>\n    <string name=\"skip_file_picking_sub\">Tiedostovalitsin näytetään välittömästi valitulla näytöllä, jos tämä on mahdollista</string>\n    <string name=\"generate_previews\">Luo esikatselut</string>\n    <string name=\"generate_previews_sub\">Mahdollistaa esikatselun luomisen, tämä voi auttaa välttämään kaatumisia joissakin laitteissa, tämä myös poistaa käytöstä jotkin muokkaustoiminnot yksittäisessä muokkausvaihtoehdossa</string>\n    <string name=\"lossy_compression\">Häviöinen pakkaus</string>\n    <string name=\"lossy_compression_sub\">Käyttää häviöllistä pakkausta pienentääkseen tiedostokokoa häviöttömän sijaan</string>\n    <string name=\"compression_type\">Pakkaustyyppi</string>\n    <string name=\"speed_sub\">Säätää tuloksena olevan kuvan dekoodausnopeutta, tämän pitäisi auttaa avaamaan tuloksena olevaa kuvaa nopeammin, arvo %1$s tarkoittaa hitainta dekoodausta, kun taas %2$s - nopein, tämä asetus voi suurentaa ulostulokuvan kokoa</string>\n    <string name=\"sorting\">Lajittelu</string>\n    <string name=\"sort_by_date\">Päivämäärä</string>\n    <string name=\"sort_by_date_reversed\">Päivämäärä (käännetty)</string>\n    <string name=\"sort_by_name\">Nimi</string>\n    <string name=\"sort_by_name_reversed\">Nimi (käänteinen)</string>\n    <string name=\"channels_configuration\">Kanavien asetukset</string>\n    <string name=\"header_today\">Tänään</string>\n    <string name=\"header_yesterday\">Eilen</string>\n    <string name=\"embedded_picker\">Embedded Picker</string>\n    <string name=\"embedded_picker_sub\">Image Toolboxin kuvanvalitsin</string>\n    <string name=\"no_permissions\">Ei käyttöoikeuksia</string>\n    <string name=\"request\">Pyytää</string>\n    <string name=\"pick_multiple_media\">Valitse useita mediatiedostoja</string>\n    <string name=\"pick_single_media\">Valitse yksittäinen media</string>\n    <string name=\"pick\">Valita</string>\n    <string name=\"try_again\">Yritä uudelleen</string>\n    <string name=\"show_settings_in_landscape\">Näytä asetukset vaaka-asennossa</string>\n    <string name=\"show_settings_in_landscape_sub\">Jos tämä ei ole käytössä, vaakatilassa asetukset avautuvat yläsovelluspalkin painikkeeseen kuten aina, pysyvän näkyvän vaihtoehdon sijaan</string>\n    <string name=\"fullscreen_settings\">Koko näytön asetukset</string>\n    <string name=\"fullscreen_settings_sub\">Ota se käyttöön, niin asetussivu avautuu aina koko näytön kokoisena liukuvan vetolaatikon sijaan</string>\n    <string name=\"switch_type\">Kytkimen tyyppi</string>\n    <string name=\"compose\">Säveltää</string>\n    <string name=\"compose_switch_sub\">Vaihdettava Jetpack Compose -materiaali</string>\n    <string name=\"material_you_switch_sub\">Vaihdettava materiaali</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Muuta ankkurin kokoa</string>\n    <string name=\"pixel_switch\">Pikseli</string>\n    <string name=\"fluent_switch\">Sujuva</string>\n    <string name=\"fluent_switch_sub\">Kytkin, joka perustuu \\\"Fluent\\\"-suunnittelujärjestelmään</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Kytkin perustuu \\\"Cupertino\\\"-suunnittelujärjestelmään</string>\n    <string name=\"images_to_svg\">Kuvat SVG:hen</string>\n    <string name=\"images_to_svg_sub\">Jäljitä annetut kuvat SVG-kuviin</string>\n    <string name=\"use_sampled_palette\">Käytä näytepalettia</string>\n    <string name=\"use_sampled_palette_sub\">Kvantisointipaletista otetaan näyte, jos tämä vaihtoehto on käytössä</string>\n    <string name=\"path_omit\">Polku jätetään pois</string>\n    <string name=\"svg_warning\">Tämän työkalun käyttöä suurten kuvien jäljittämiseen ilman skaalausta ei suositella, se voi aiheuttaa kaatumisen ja pidentää käsittelyaikaa</string>\n    <string name=\"downscale_image\">Alennettu kuva</string>\n    <string name=\"downscale_image_sub\">Kuva skaalataan pienempiin mittoihin ennen käsittelyä, mikä auttaa työkalua toimimaan nopeammin ja turvallisemmin</string>\n    <string name=\"min_color_ratio\">Vähimmäisvärisuhde</string>\n    <string name=\"lines_threshold\">Linjojen kynnys</string>\n    <string name=\"quadratic_threshold\">Neliöllinen kynnys</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordinaattien pyöristystoleranssi</string>\n    <string name=\"path_scale\">Polun asteikko</string>\n    <string name=\"reset_properties\">Palauta ominaisuudet</string>\n    <string name=\"reset_properties_sub\">Kaikki ominaisuudet asetetaan oletusarvoihin. Huomaa, että tätä toimintoa ei voi kumota</string>\n    <string name=\"detailed\">Yksityiskohtainen</string>\n    <string name=\"default_line_width\">Oletusviivan leveys</string>\n    <string name=\"engine_mode\">Moottoritila</string>\n    <string name=\"legacy\">Legacy</string>\n    <string name=\"lstm_network\">LSTM verkko</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp;amp; LSTM</string>\n    <string name=\"convert\">Muuntaa</string>\n    <string name=\"convert_sub\">Muunna kuvaerät annettuun muotoon</string>\n    <string name=\"add_new_folder\">Lisää uusi kansio</string>\n    <string name=\"tag_bits_per_sample\">Bittiä näytettä kohti</string>\n    <string name=\"tag_compression\">Puristus</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrinen tulkinta</string>\n    <string name=\"tag_samples_per_pixel\">Näytteitä pikseliä kohden</string>\n    <string name=\"tag_planar_configuration\">Tasokokoonpano</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Subnäytteenotto</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr -paikannus</string>\n    <string name=\"tag_x_resolution\">X Resoluutio</string>\n    <string name=\"tag_y_resolution\">Y Resoluutio</string>\n    <string name=\"tag_resolution_unit\">Resoluutioyksikkö</string>\n    <string name=\"tag_strip_offsets\">Strip Offsets</string>\n    <string name=\"tag_rows_per_strip\">Rivit per nauha</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG-vaihtomuoto</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG-vaihtomuodon pituus</string>\n    <string name=\"tag_transfer_function\">Siirtotoiminto</string>\n    <string name=\"tag_white_point\">Valkoinen piste</string>\n    <string name=\"tag_primary_chromaticities\">Ensisijaiset kromaattisuudet</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr kertoimet</string>\n    <string name=\"tag_reference_black_white\">Viite musta valkoinen</string>\n    <string name=\"tag_datetime\">Päivämäärä Aika</string>\n    <string name=\"tag_image_description\">Kuvan kuvaus</string>\n    <string name=\"tag_make\">Tehdä</string>\n    <string name=\"tag_model\">Malli</string>\n    <string name=\"tag_software\">Ohjelmisto</string>\n    <string name=\"tag_artist\">Taiteilija</string>\n    <string name=\"tag_copyright\">Tekijänoikeus</string>\n    <string name=\"tag_exif_version\">Exif versio</string>\n    <string name=\"tag_flashpix_version\">Flashpix versio</string>\n    <string name=\"tag_color_space\">Väriavaruus</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y -mitta</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Pakattu bittiä pikseliä kohden</string>\n    <string name=\"tag_maker_note\">Tekijän huomautus</string>\n    <string name=\"tag_user_comment\">Käyttäjän kommentti</string>\n    <string name=\"tag_related_sound_file\">Aiheeseen liittyvä äänitiedosto</string>\n    <string name=\"tag_datetime_original\">Päivämäärä Aika Alkuperäinen</string>\n    <string name=\"tag_datetime_digitized\">Päivämäärä Aika digitoitu</string>\n    <string name=\"tag_offset_time\">Siirtymäaika</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Siirtymäaika digitoitu</string>\n    <string name=\"tag_subsec_time\">Sub Sec Time</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Time Alkuperäinen</string>\n    <string name=\"tag_subsec_time_digitized\">Sub Sec Time digitoitu</string>\n    <string name=\"tag_exposure_time\">Altistumisaika</string>\n    <string name=\"tag_f_number\">F Numero</string>\n    <string name=\"tag_exposure_program\">Altistusohjelma</string>\n    <string name=\"tag_spectral_sensitivity\">Spektriherkkyys</string>\n    <string name=\"tag_photographic_sensitivity\">Valokuvaherkkyys</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Herkkyystyyppi</string>\n    <string name=\"tag_standard_output_sensitivity\">Normaali lähtöherkkyys</string>\n    <string name=\"tag_recommended_exposure_index\">Suositeltu altistusindeksi</string>\n    <string name=\"tag_iso_speed\">ISO-nopeus</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO-nopeus Latitude vyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO-nopeus Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Suljinnopeuden arvo</string>\n    <string name=\"tag_aperture_value\">Aukon arvo</string>\n    <string name=\"tag_brightness_value\">Kirkkauden arvo</string>\n    <string name=\"tag_exposure_bias_value\">Exposure Bias Value</string>\n    <string name=\"tag_max_aperture_value\">Suurin aukkoarvo</string>\n    <string name=\"tag_subject_distance\">Aiheetäisyys</string>\n    <string name=\"tag_metering_mode\">Mittaustila</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Aihealue</string>\n    <string name=\"tag_focal_length\">Polttoväli</string>\n    <string name=\"tag_flash_energy\">Flash Energy</string>\n    <string name=\"tag_spatial_frequency_response\">Spatial Frequency Response</string>\n    <string name=\"tag_focal_plane_x_resolution\">Polttotason X resoluutio</string>\n    <string name=\"tag_focal_plane_y_resolution\">Polttotason Y resoluutio</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Polttotason resoluutioyksikkö</string>\n    <string name=\"tag_subject_location\">Aiheen sijainti</string>\n    <string name=\"tag_exposure_index\">Altistusindeksi</string>\n    <string name=\"tag_sensing_method\">Tunnistusmenetelmä</string>\n    <string name=\"tag_file_source\">Tiedoston lähde</string>\n    <string name=\"tag_cfa_pattern\">CFA-kuvio</string>\n    <string name=\"tag_custom_rendered\">Mukautettu renderöity</string>\n    <string name=\"tag_exposure_mode\">Valotustila</string>\n    <string name=\"tag_white_balance\">Valkotasapaino</string>\n    <string name=\"tag_digital_zoom_ratio\">Digitaalinen zoomaussuhde</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Polttoväli 35 mm filmi</string>\n    <string name=\"tag_scene_capture_type\">Scene Capture Type</string>\n    <string name=\"tag_gain_control\">Hanki hallinta</string>\n    <string name=\"tag_contrast\">Kontrasti</string>\n    <string name=\"tag_saturation\">Kylläisyys</string>\n    <string name=\"tag_sharpness\">Terävyys</string>\n    <string name=\"tag_device_setting_description\">Laiteasetusten kuvaus</string>\n    <string name=\"tag_subject_distance_range\">Aiheen etäisyysalue</string>\n    <string name=\"tag_image_unique_id\">Kuvan yksilöllinen tunnus</string>\n    <string name=\"tag_camera_owner_name\">Kameran omistajan nimi</string>\n    <string name=\"tag_body_serial_number\">Rungon sarjanumero</string>\n    <string name=\"tag_lens_specification\">Objektiivin tekniset tiedot</string>\n    <string name=\"tag_lens_make\">Linssin merkki</string>\n    <string name=\"tag_lens_model\">Linssin malli</string>\n    <string name=\"tag_lens_serial_number\">Objektiivin sarjanumero</string>\n    <string name=\"tag_gps_version_id\">GPS-version tunnus</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitude</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Pituusaste Ref</string>\n    <string name=\"tag_gps_longitude\">GPS pituusaste</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Korkeus Ref</string>\n    <string name=\"tag_gps_altitude\">GPS korkeus</string>\n    <string name=\"tag_gps_timestamp\">GPS-aikaleima</string>\n    <string name=\"tag_gps_satellites\">GPS-satelliitit</string>\n    <string name=\"tag_gps_status\">GPS-tila</string>\n    <string name=\"tag_gps_measure_mode\">GPS-mittaustila</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS Speed ​​Ref</string>\n    <string name=\"tag_gps_speed\">GPS nopeus</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS-jälki</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img Suuntaviite</string>\n    <string name=\"tag_gps_img_direction\">GPS Img suunta</string>\n    <string name=\"tag_gps_map_datum\">GPS-kartan päivämäärä</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS-kohteen leveysaste Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS-kohteen pituusaste Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS-kohteen pituusaste</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS-kohdeetäisyys</string>\n    <string name=\"tag_gps_processing_method\">GPS-käsittelymenetelmä</string>\n    <string name=\"tag_gps_area_information\">GPS-alueen tiedot</string>\n    <string name=\"tag_gps_datestamp\">GPS-päivämääräleima</string>\n    <string name=\"tag_gps_differential\">GPS-differentiaali</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H -paikannusvirhe</string>\n    <string name=\"tag_interoperability_index\">Yhteentoimivuusindeksi</string>\n    <string name=\"tag_dng_version\">DNG versio</string>\n    <string name=\"tag_default_crop_size\">Oletusrajauskoko</string>\n    <string name=\"tag_orf_preview_image_start\">Esikatselukuva Aloita</string>\n    <string name=\"tag_orf_preview_image_length\">Esikatselukuvan pituus</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect Frame</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Anturin alareuna</string>\n    <string name=\"tag_rw2_sensor_left_border\">Anturin vasen reuna</string>\n    <string name=\"tag_rw2_sensor_right_border\">Anturin oikea reuna</string>\n    <string name=\"tag_rw2_sensor_top_border\">Anturin yläreuna</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Piirrä tekstiä polulle annetulla fontilla ja värillä</string>\n    <string name=\"font_size\">Fontin koko</string>\n    <string name=\"watermark_size\">Vesileiman koko</string>\n    <string name=\"repeat_text\">Toista teksti</string>\n    <string name=\"repeat_text_sub\">Nykyistä tekstiä toistetaan polun loppuun asti yhden kerran piirtämisen sijaan</string>\n    <string name=\"dash_size\">Viivan koko</string>\n    <string name=\"draw_mode_image_sub\">Käytä valittua kuvaa piirtämään se annettua polkua pitkin</string>\n    <string name=\"draw_image_sub\">Tätä kuvaa käytetään piirretyn polun toistuvana syötönä</string>\n    <string name=\"outlined_triangle_sub\">Piirtää ääriviivat kolmion aloituspisteestä loppupisteeseen</string>\n    <string name=\"triangle_sub\">Piirtää ääriviivat kolmion aloituspisteestä loppupisteeseen</string>\n    <string name=\"outlined_triangle\">Piirretty kolmio</string>\n    <string name=\"triangle\">Kolmio</string>\n    <string name=\"polygon_sub\">Piirtää monikulmion aloituspisteestä loppupisteeseen</string>\n    <string name=\"polygon\">Monikulmio</string>\n    <string name=\"outlined_polygon\">Piirretty monikulmio</string>\n    <string name=\"outlined_polygon_sub\">Piirtää ääriviivat monikulmion aloituspisteestä loppupisteeseen</string>\n    <string name=\"vertices\">Vertices</string>\n    <string name=\"draw_regular_polygon\">Piirrä säännöllinen monikulmio</string>\n    <string name=\"draw_regular_polygon_sub\">Piirrä monikulmio, joka on säännöllinen vapaan muodon sijaan</string>\n    <string name=\"star_sub\">Piirtää tähden aloituspisteestä loppupisteeseen</string>\n    <string name=\"star\">Tähti</string>\n    <string name=\"outlined_star\">Piirretty tähti</string>\n    <string name=\"outlined_star_sub\">Piirtää rajatun tähden aloituspisteestä loppupisteeseen</string>\n    <string name=\"inner_radius_ratio\">Sisäinen sädesuhde</string>\n    <string name=\"draw_regular_star\">Piirrä tavallinen tähti</string>\n    <string name=\"draw_regular_star_sub\">Piirrä tähti, joka on tavallinen vapaamuotoisen sijaan</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Mahdollistaa antialiasoinnin terävien reunojen estämiseksi</string>\n    <string name=\"open_edit_instead_of_preview\">Avaa Muokkaa esikatselun sijaan</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Kun valitset avattavan (esikatselun) kuvan ImageToolboxissa, muokkausvalintasivu avautuu esikatselun sijaan</string>\n    <string name=\"document_scanner\">Asiakirjan skanneri</string>\n    <string name=\"document_scanner_sub\">Skannaa asiakirjoja ja luo PDF-tiedostoja tai erota niistä kuvia</string>\n    <string name=\"click_to_start_scanning\">Aloita skannaus napsauttamalla</string>\n    <string name=\"start_scanning\">Aloita skannaus</string>\n    <string name=\"save_as_pdf\">Tallenna pdf-muodossa</string>\n    <string name=\"share_as_pdf\">Jaa pdf-muodossa</string>\n    <string name=\"options_below_is_for_images\">Alla olevat vaihtoehdot ovat kuvien tallentamiseen, eivät PDF-tiedostoihin</string>\n    <string name=\"equalize_histogram_hsv\">Tasaa histogrammi HSV</string>\n    <string name=\"equalize_histogram\">Tasaa histogrammi</string>\n    <string name=\"enter_percentage\">Anna prosentti</string>\n    <string name=\"allow_enter_by_text_field\">Salli kirjoittaminen tekstikenttään</string>\n    <string name=\"allow_enter_by_text_field_sub\">Ottaa käyttöön tekstikentän esiasetusten valinnan takana, jotta ne syötetään lennossa</string>\n    <string name=\"scale_color_space\">Skaalaa väriavaruutta</string>\n    <string name=\"linear\">Lineaarinen</string>\n    <string name=\"equalize_histogram_pixelation\">Tasaa histogrammin pikselaus</string>\n    <string name=\"grid_size_x\">Ruudukon koko X</string>\n    <string name=\"grid_size_y\">Ruudukon koko Y</string>\n    <string name=\"equalize_histogram_adaptive\">Tasaa histogrammin mukautuva</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Tasaa histogrammin mukautuva LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Tasaa histogrammin mukautuva LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Rajaa sisältöön</string>\n    <string name=\"frame_color\">Kehyksen väri</string>\n    <string name=\"color_to_ignore\">Väri ohitettava</string>\n    <string name=\"template\">Malli</string>\n    <string name=\"no_template_filters\">Mallisuodattimia ei ole lisätty</string>\n    <string name=\"create_new\">Luo uusi</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Skannattu QR-koodi ei ole kelvollinen suodatinmalli</string>\n    <string name=\"scan_qr_code\">Skannaa QR-koodi</string>\n    <string name=\"opened_file_have_no_filter_template\">Valitussa tiedostossa ei ole suodatinmallitietoja</string>\n    <string name=\"create_template\">Luo malli</string>\n    <string name=\"template_name\">Mallin nimi</string>\n    <string name=\"select_template_preview\">Tätä kuvaa käytetään tämän suodatinmallin esikatseluun</string>\n    <string name=\"template_filter\">Mallin suodatin</string>\n    <string name=\"as_qr_code\">QR-koodikuvana</string>\n    <string name=\"as_file\">Tiedostona</string>\n    <string name=\"save_as_file\">Tallenna tiedostona</string>\n    <string name=\"save_as_qr_code_image\">Tallenna QR-koodikuvana</string>\n    <string name=\"delete_template\">Poista malli</string>\n    <string name=\"delete_template_warn\">Olet poistamassa valitun mallisuodattimen. Tätä toimintoa ei voi kumota</string>\n    <string name=\"added_filter_template\">Lisätty suodatinmalli, jonka nimi on \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Suodattimen esikatselu</string>\n    <string name=\"qr_code\">QR &amp;amp; Viivakoodi</string>\n    <string name=\"qr_code_sub\">Skannaa QR-koodi ja hae sen sisältö tai liitä merkkijonosi luodaksesi uuden koodin</string>\n    <string name=\"code_content\">Koodin sisältö</string>\n    <string name=\"scan_qr_code_to_replace_content\">Skannaa mikä tahansa viivakoodi korvataksesi kentän sisällön tai kirjoita jotain luodaksesi uuden viivakoodin valitulla tyypillä</string>\n    <string name=\"qr_description\">QR Kuvaus</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Myönnä kameralle lupa skannata QR-koodi</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Myönnä kameralle lupa skannata asiakirjaskanneria</string>\n    <string name=\"cubic\">Kuutio</string>\n    <string name=\"bspline\">B-spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussin</string>\n    <string name=\"sphinx\">Sfinksi</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spliini 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Laatikko</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kuutiointerpolointi mahdollistaa tasaisemman skaalan ottamalla huomioon lähimmät 16 pikseliä, mikä antaa parempia tuloksia kuin bilineaarinen</string>\n    <string name=\"bspline_sub\">Käyttää paloittain määriteltyjä polynomifunktioita käyrän tai pinnan sujuvaan interpoloimiseen ja approksimoimiseen, joustavaan ja jatkuvaan muodon esitykseen</string>\n    <string name=\"hamming_sub\">Ikkunatoiminto, jota käytetään vähentämään spektrivuotoa kapenemalla signaalin reunoja, hyödyllinen signaalinkäsittelyssä</string>\n    <string name=\"hanning_sub\">Hann-ikkunan muunnos, jota käytetään yleisesti vähentämään spektrivuotoa signaalinkäsittelysovelluksissa</string>\n    <string name=\"blackman_sub\">Ikkunatoiminto, joka tarjoaa hyvän taajuusresoluution minimoimalla spektrivuodon, jota käytetään usein signaalinkäsittelyssä</string>\n    <string name=\"welch_sub\">Ikkunatoiminto, joka on suunniteltu antamaan hyvä taajuusresoluutio pienemmällä spektrivuodolla, jota käytetään usein signaalinkäsittelysovelluksissa</string>\n    <string name=\"quadric_sub\">Menetelmä, joka käyttää toisen asteen funktiota interpoloinnissa ja tarjoaa tasaisia ​​ja jatkuvia tuloksia</string>\n    <string name=\"gaussian_sub\">Gaussin funktiota käyttävä interpolointimenetelmä, joka on hyödyllinen kuvien tasoittamiseen ja kohinan vähentämiseen</string>\n    <string name=\"sphinx_sub\">Kehittynyt uudelleennäytteenottomenetelmä, joka tarjoaa korkealaatuisen interpoloinnin minimaalisilla artefakteilla</string>\n    <string name=\"bartlett_sub\">Kolmioikkunatoiminto, jota käytetään signaalinkäsittelyssä spektrivuodon vähentämiseksi</string>\n    <string name=\"robidoux_sub\">Laadukas interpolointimenetelmä, joka on optimoitu luonnollisen kuvan koon muuttamiseen, terävyyden ja sileyden tasapainottamiseen</string>\n    <string name=\"robidoux_sharp_sub\">Robidoux-menetelmän terävämpi versio, joka on optimoitu terävän kuvan koon muuttamiseen</string>\n    <string name=\"spline16_sub\">Spline-pohjainen interpolointimenetelmä, joka tarjoaa tasaiset tulokset 16-napaisen suodattimen avulla</string>\n    <string name=\"spline36_sub\">Spline-pohjainen interpolointimenetelmä, joka tarjoaa tasaiset tulokset käyttämällä 36-napauksen suodatinta</string>\n    <string name=\"spline64_sub\">Spline-pohjainen interpolointimenetelmä, joka tarjoaa tasaiset tulokset käyttämällä 64-napauksen suodatinta</string>\n    <string name=\"kaiser_sub\">Interpolointimenetelmä, joka käyttää Kaiser-ikkunaa ja tarjoaa hyvän hallinnan pääkeilan leveyden ja sivukeilan tason väliseen kompromissiin</string>\n    <string name=\"bartlett_hann_sub\">Bartlett- ja Hann-ikkunat yhdistävä hybridi-ikkunatoiminto, jota käytetään vähentämään spektrivuotoja signaalinkäsittelyssä</string>\n    <string name=\"box_sub\">Yksinkertainen uudelleennäytteenottomenetelmä, joka käyttää lähimpien pikseliarvojen keskiarvoa, mikä usein johtaa lohkoiseen ulkonäköön</string>\n    <string name=\"bohman_sub\">Ikkunatoiminto, jota käytetään vähentämään spektrivuotoa ja tarjoaa hyvän taajuusresoluution signaalinkäsittelysovelluksissa</string>\n    <string name=\"lanczos2_sub\">Uudelleennäytteenottomenetelmä, joka käyttää 2-keilaa Lanczos-suodatinta korkealaatuiseen interpolointiin minimaalisella artefaktilla</string>\n    <string name=\"lanczos3_sub\">Uudelleennäytteenottomenetelmä, joka käyttää 3-keilaa Lanczos-suodatinta korkealaatuiseen interpolointiin minimaalisella artefaktilla</string>\n    <string name=\"lanczos4_sub\">Uudelleennäytteenottomenetelmä, joka käyttää 4-keilaa Lanczos-suodatinta korkealaatuiseen interpolointiin minimaalisella artefaktilla</string>\n    <string name=\"lanczos2_jinc_sub\">Lanczos 2 -suodattimen muunnos, joka käyttää jinc-toimintoa ja tarjoaa korkealaatuisen interpoloinnin minimaalisilla artefakteilla</string>\n    <string name=\"lanczos3_jinc_sub\">Lanczos 3 -suodattimen muunnos, joka käyttää jinc-toimintoa ja tarjoaa korkealaatuisen interpoloinnin minimaalisilla artefakteilla</string>\n    <string name=\"lanczos4_jinc_sub\">Lanczos 4 -suodattimen muunnos, joka käyttää jinc-toimintoa ja tarjoaa korkealaatuisen interpoloinnin minimaalisilla artefakteilla</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Hanning-suodattimen elliptinen painotettu keskiarvo (EWA) mahdollistaa sujuvan interpoloinnin ja uudelleennäytteenoton</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Robidoux-suodattimen elliptinen painotettu keskiarvo (EWA) -versio korkealaatuiseen uudelleennäytteenottoon</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Blackman-suodattimen elliptinen painotettu keskiarvo (EWA) -muunnelma soivien artefaktien minimoimiseksi</string>\n    <string name=\"ewa_quadric\">Neliöinen EWA</string>\n    <string name=\"ewa_quadric_sub\">Quadric-suodattimen elliptinen painotettu keskiarvo (EWA) -versio tasaiseen interpolointiin</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elliptinen painotettu keskiarvo (EWA) -versio Robidoux Sharp -suodattimesta terävämpiin tuloksiin</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Lanczos 3 Jinc -suodattimen elliptinen painotettu keskiarvo (EWA) -versio korkealaatuiseen uudelleennäytteenottoon pienemmällä aliasuksella</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Uudelleennäytteenottosuodatin, joka on suunniteltu korkealaatuiseen kuvankäsittelyyn, jossa on hyvä tasapaino terävyyden ja sileyden välillä</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Ginseng-suodattimen elliptinen painotettu keskiarvo (EWA) -versio parantaa kuvanlaatua</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Lanczos Sharp -suodattimen elliptinen painotettu keskiarvo (EWA) -muunnelma terävien tulosten saavuttamiseksi minimaalisilla artefakteilla</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 terävin EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Lanczos 4 Sharpest -suodattimen elliptinen painotettu keskiarvo (EWA) -versio erittäin terävän kuvan uudelleennäytteenottoa varten</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Lanczos Soft -suodattimen elliptinen painotettu keskiarvo (EWA) -versio tasaisempaan kuvan uudelleennäytteenottoon</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Haasnin suunnittelema uudelleennäytteenottosuodatin tasaista ja artefaktitonta kuvan skaalausta varten</string>\n    <string name=\"format_conversion\">Muodin muuntaminen</string>\n    <string name=\"format_conversion_sub\">Muunna kuvaerän muodosta toiseen</string>\n    <string name=\"dismiss_forever\">Hylkää ikuisesti</string>\n    <string name=\"image_stacking\">Kuvan pinoaminen</string>\n    <string name=\"image_stacking_sub\">Pinoa kuvat päällekkäin valituilla sekoitustiloilla</string>\n    <string name=\"add_image\">Lisää kuva</string>\n    <string name=\"bins_count\">Säiliöt laskevat</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Tasaa histogrammin mukautuva HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Tasaa histogrammin mukautuva HSV</string>\n    <string name=\"edge_mode\">Reunatila</string>\n    <string name=\"clip\">Leike</string>\n    <string name=\"wrap\">Kääri</string>\n    <string name=\"color_blind_scheme\">Värisokeus</string>\n    <string name=\"color_blind_scheme_sub\">Valitse tila mukauttaaksesi teemavärit valitun värisokeuden muunnelman mukaan</string>\n    <string name=\"protanomaly_sub\">Punaisen ja vihreän sävyn erottaminen on vaikeaa</string>\n    <string name=\"deuteranomaly_sub\">Vihreän ja punaisen sävyn erottaminen on vaikeaa</string>\n    <string name=\"tritanomaly_sub\">Vaikeus erottaa siniset ja keltaiset sävyt</string>\n    <string name=\"protanopia_sub\">Kyvyttömyys havaita punaisia ​​sävyjä</string>\n    <string name=\"deuteranopia_sub\">Kyvyttömyys havaita vihreitä sävyjä</string>\n    <string name=\"tritanopia_sub\">Kyvyttömyys havaita sinisiä sävyjä</string>\n    <string name=\"achromatomaly_sub\">Vähentynyt herkkyys kaikille väreille</string>\n    <string name=\"achromatopsia_sub\">Täydellinen värisokeus, näkee vain harmaan sävyjä</string>\n    <string name=\"not_use_color_blind_scheme\">Älä käytä Color Blind -mallia</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Värit ovat täsmälleen samat kuin teemassa</string>\n    <string name=\"sigmoidal\">Sigmoidinen</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Luokan 2 Lagrange-interpolaatiosuodatin, joka soveltuu korkealaatuiseen kuvan skaalaukseen tasaisilla siirtymillä</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Lagrange-interpolaatiosuodatin, luokka 3, joka tarjoaa paremman tarkkuuden ja tasaisemmat tulokset kuvan skaalautuksessa</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Lanczosin uudelleennäytteenottosuodatin korkeammalla 6:n asteikolla, joka tarjoaa terävämmän ja tarkemman kuvan skaalaus</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Lanczos 6 -suodattimen muunnelma, jossa käytetään Jinc-toimintoa kuvan uudelleennäytteenoton laadun parantamiseksi</string>\n    <string name=\"linear_box_blur\">Lineaarinen laatikon sumennus</string>\n    <string name=\"linear_tent_blur\">Lineaarinen teltan hämärtyminen</string>\n    <string name=\"linear_gaussian_box_blur\">Lineaarinen Gaussian Box Blur</string>\n    <string name=\"linear_stack_blur\">Lineaarinen pinon sumennus</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lineaarinen nopea Gaussin sumeus Seuraava</string>\n    <string name=\"linear_fast_gaussian_blur\">Lineaarinen nopea Gaussin sumennus</string>\n    <string name=\"linear_gaussian_blur\">Lineaarinen Gaussin sumennus</string>\n    <string name=\"draw_filter_sub\">Valitse yksi suodatin käyttääksesi sitä maalina</string>\n    <string name=\"replace_filter\">Vaihda suodatin</string>\n    <string name=\"pick_filter_info\">Valitse alta suodatin käyttääksesi sitä siveltimenä piirustuksessasi</string>\n    <string name=\"tiff_compression_scheme\">TIFF-pakkausmalli</string>\n    <string name=\"low_poly\">Matala poly</string>\n    <string name=\"sand_painting\">Hiekkamaalaus</string>\n    <string name=\"image_splitting\">Kuvan jakaminen</string>\n    <string name=\"image_splitting_sub\">Jaa yksittäinen kuva riveillä tai sarakkeilla</string>\n    <string name=\"fit_to_bounds\">Sovita rajoihin</string>\n    <string name=\"fit_to_bounds_sub\">Yhdistä rajauksen koonmuutostila tähän parametriin halutun toiminnan saavuttamiseksi (Rajaa/Sovita kuvasuhteeseen)</string>\n    <string name=\"languages_imported\">Kielten tuonti onnistui</string>\n    <string name=\"backup_ocr_models\">Varmuuskopioi OCR-malleja</string>\n    <string name=\"import_word\">Tuoda</string>\n    <string name=\"export\">Viedä</string>\n    <string name=\"position\">asema</string>\n    <string name=\"center\">Keskusta</string>\n    <string name=\"top_left\">Ylävasen</string>\n    <string name=\"top_right\">Ylhäällä oikea</string>\n    <string name=\"bottom_left\">Vasemmalla alhaalla</string>\n    <string name=\"bottom_right\">Alhaalla oikealla</string>\n    <string name=\"top_center\">Yläkeskus</string>\n    <string name=\"center_right\">Keski oikealla</string>\n    <string name=\"bottom_center\">Alakeskus</string>\n    <string name=\"center_left\">Keskellä vasen</string>\n    <string name=\"target_image\">Kohdekuva</string>\n    <string name=\"palette_transfer\">Paletin siirto</string>\n    <string name=\"enhanced_oil\">Tehostettu öljy</string>\n    <string name=\"simple_old_tv\">Yksinkertainen vanha TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Yksinkertainen Sketch</string>\n    <string name=\"soft_glow\">Pehmeä hehku</string>\n    <string name=\"color_poster\">Värillinen juliste</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Kolmas väri</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Pilkku</string>\n    <string name=\"clustered_2x2_dithering\">Klusteri 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Klusteroitu 4x4 dithering</string>\n    <string name=\"clustered_8x8_dithering\">Klusteroitu 8x8 dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Suosikkivaihtoehtoja ei ole valittu, lisää ne työkalusivulle</string>\n    <string name=\"add_favorites\">Lisää suosikkeja</string>\n    <string name=\"harmony_complementary\">Täydentävä</string>\n    <string name=\"harmony_analogous\">Analoginen</string>\n    <string name=\"harmony_triadic\">Triadinen</string>\n    <string name=\"harmony_split_complementary\">Jaettu täydentävä</string>\n    <string name=\"harmony_tetradic\">Tetradic</string>\n    <string name=\"harmony_square\">Neliö</string>\n    <string name=\"harmony_analogous_complementary\">Analoginen + täydentävä</string>\n    <string name=\"color_tools\">Värityökalut</string>\n    <string name=\"color_tools_sub\">Sekoita, luo sävyjä, luo sävyjä ja paljon muuta</string>\n    <string name=\"color_harmonies\">Väriharmoniat</string>\n    <string name=\"color_shading\">Värivarjostus</string>\n    <string name=\"variation\">Variaatio</string>\n    <string name=\"tints\">Sävyt</string>\n    <string name=\"tones\">Äänet</string>\n    <string name=\"shades\">Varjostimet</string>\n    <string name=\"color_mixing\">Värien sekoitus</string>\n    <string name=\"color_info\">Väritiedot</string>\n    <string name=\"selected_color\">Valittu väri</string>\n    <string name=\"color_to_mix\">Väri Sekoita</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Rahaa ei voi käyttää, kun dynaamiset värit ovat käytössä</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Kohde LUT-kuva</string>\n    <string name=\"amatorka\">Amatööri</string>\n    <string name=\"miss_etikate\">Neiti Etiketti</string>\n    <string name=\"soft_elegance\">Pehmeä eleganssi</string>\n    <string name=\"soft_elegance_variant\">Soft Elegance Variant</string>\n    <string name=\"palette_transfer_variant\">Paletin siirtovaihtoehto</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Kohde 3D LUT -tiedosto (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Kynttilänvalo</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Herkkä Amber</string>\n    <string name=\"fall_colors\">Syksyn värit</string>\n    <string name=\"film_stock_50\">Filmivarasto 50</string>\n    <string name=\"foggy_night\">Sumuinen yö</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Hanki neutraali LUT-kuva</string>\n    <string name=\"save_empty_lut_sub\">Käytä ensin suosikkikuvankäsittelyohjelmaasi suodattimen lisäämiseen neutraaliin LUT:iin, jonka saat täältä. Jotta tämä toimisi oikein, jokainen pikselin väri ei saa olla riippuvainen muista pikseleistä (esim. sumeus ei toimi). Kun olet valmis, käytä uutta LUT-kuvaasi tulona 512*512 LUT-suodattimelle</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Selluloidi</string>\n    <string name=\"coffee\">Kahvia</string>\n    <string name=\"golden_forest\">Kultainen metsä</string>\n    <string name=\"greenish\">Vihertävä</string>\n    <string name=\"retro_yellow\">Retro keltainen</string>\n    <string name=\"links_preview\">Linkkien esikatselu</string>\n    <string name=\"links_preview_sub\">Mahdollistaa linkin esikatselun noutamisen paikoista, joista voit saada tekstiä (QRCode, OCR jne.)</string>\n    <string name=\"links\">Linkit</string>\n    <string name=\"ico_size_warning\">ICO-tiedostoja voidaan tallentaa vain enintään 256 x 256 kokoisina</string>\n    <string name=\"gif_type_to_webp\">GIF WEBP:hen</string>\n    <string name=\"gif_type_to_webp_sub\">Muunna GIF-kuvat WEBP-animoiduiksi kuviksi</string>\n    <string name=\"webp_tools\">WEBP-työkalut</string>\n    <string name=\"webp_tools_sub\">Muunna kuvat WEBP-animoiduiksi kuviksi tai poimi kehyksiä annetusta WEBP-animaatiosta</string>\n    <string name=\"webp_type_to_image\">WEBP kuviin</string>\n    <string name=\"webp_type_to_image_sub\">Muunna WEBP-tiedosto kuvasarjaksi</string>\n    <string name=\"webp_type_to_webp_sub\">Muunna kuvaerä WEBP-tiedostoksi</string>\n    <string name=\"webp_type_to_webp\">Kuvat WEBP:hen</string>\n    <string name=\"select_webp_image_to_start\">Aloita valitsemalla WEBP-kuva</string>\n    <string name=\"manage_storage_extra_types\">Ei täydellistä pääsyä tiedostoihin</string>\n    <string name=\"manage_storage_extra_types_sub\">Salli kaikkien tiedostojen käyttöoikeus nähdä JXL, QOI ja muut kuvat, joita ei tunnisteta kuviksi Androidissa. Ilman lupaa Image Toolbox ei voi näyttää näitä kuvia</string>\n    <string name=\"default_draw_color\">Piirustuksen oletusväri</string>\n    <string name=\"default_draw_path_mode\">Oletuspiirtopolkutila</string>\n    <string name=\"add_timestamp\">Lisää aikaleima</string>\n    <string name=\"add_timestamp_sub\">Mahdollistaa aikaleiman lisäämisen tulosteen tiedostonimeen</string>\n    <string name=\"formatted_timestamp\">Muotoiltu aikaleima</string>\n    <string name=\"formatted_timestamp_sub\">Ota aikaleiman muotoilu käyttöön tulostiedoston nimessä perusmilliksen sijaan</string>\n    <string name=\"enable_timestamps_to_format_them\">Ota aikaleimat käyttöön valitaksesi niiden muodon</string>\n    <string name=\"one_time_save_location\">Kerran tallennettava sijainti</string>\n    <string name=\"one_time_save_location_sub\">Tarkastele ja muokkaa kertatallennuspaikkoja, joita voit käyttää painamalla pitkään tallennuspainiketta useimmissa vaihtoehdoissa</string>\n    <string name=\"recently_used\">Äskettäin käytetty</string>\n    <string name=\"ci_channel\">CI-kanava</string>\n    <string name=\"group\">ryhmä</string>\n    <string name=\"image_toolbox_in_telegram\">Kuvatyökalut Telegramissa 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Liity chattiin, jossa voit keskustella mistä haluat ja katsoa myös CI-kanavaa, jonne julkaisen betaversioita ja ilmoituksia</string>\n    <string name=\"ci_channel_sub\">Saat ilmoituksia sovelluksen uusista versioista ja lue ilmoituksia</string>\n    <string name=\"fit_description\">Sovita kuva annettuihin mittoihin ja lisää taustaan ​​sumennus tai väri</string>\n    <string name=\"tools_arrangement\">Työkalujen järjestely</string>\n    <string name=\"group_tools_by_type\">Ryhmittele työkalut tyypin mukaan</string>\n    <string name=\"group_tools_by_type_sub\">Ryhmittelee päänäytön työkalut niiden tyypin mukaan mukautetun luettelojärjestelyn sijaan</string>\n    <string name=\"default_values\">Oletusarvot</string>\n    <string name=\"system_bars_visibility\">Järjestelmäpalkkien näkyvyys</string>\n    <string name=\"show_system_bars_by_swipe\">Näytä järjestelmäpalkit pyyhkäisemällä</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Ottaa käyttöön pyyhkäisemisen näyttääksesi järjestelmäpalkit, jos ne ovat piilossa</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Piilota kaikki</string>\n    <string name=\"show_all\">Näytä kaikki</string>\n    <string name=\"hide_nav_bar\">Piilota navigointipalkki</string>\n    <string name=\"hide_status_bar\">Piilota tilapalkki</string>\n    <string name=\"noise_generation\">Melun tuottaminen</string>\n    <string name=\"noise_generation_sub\">Luo erilaisia ​​ääniä, kuten Perlin tai muita ääniä</string>\n    <string name=\"frequency\">Taajuus</string>\n    <string name=\"noise_type\">Melun tyyppi</string>\n    <string name=\"rotation_type\">Kiertotyyppi</string>\n    <string name=\"fractal_type\">Fraktaalityyppi</string>\n    <string name=\"octaves\">Oktaavia</string>\n    <string name=\"lacunarity\">Tyhjyys</string>\n    <string name=\"gain\">Saada</string>\n    <string name=\"weighted_strength\">Painotettu vahvuus</string>\n    <string name=\"ping_pong_strength\">Ping pong vahvuus</string>\n    <string name=\"distance_function\">Etäisyystoiminto</string>\n    <string name=\"return_type\">Palautustyyppi</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"alignment\">Tasaus</string>\n    <string name=\"custom_filename\">Mukautettu tiedostonimi</string>\n    <string name=\"custom_filename_sub\">Valitse sijainti ja tiedostonimi, joita käytetään nykyisen kuvan tallentamiseen</string>\n    <string name=\"saved_to_custom\">Tallennettu kansioon mukautetulla nimellä</string>\n    <string name=\"collage_maker\">Collage Maker</string>\n    <string name=\"collage_maker_sub\">Tee kollaaseja jopa 20 kuvasta</string>\n    <string name=\"collage_type\">Kollaasin tyyppi</string>\n    <string name=\"collages_info\">Pidä kuvaa painettuna vaihtaaksesi, siirrä ja zoomaa säätääksesi sijaintia</string>\n    <string name=\"disable_rotation\">Poista kierto käytöstä</string>\n    <string name=\"disable_rotation_sub\">Estää kuvien kiertämisen kahden sormen eleillä</string>\n    <string name=\"enable_snapping_to_borders\">Ota reunuksiin kiinnitys käyttöön</string>\n    <string name=\"enable_snapping_to_borders_sub\">Siirron tai zoomauksen jälkeen kuvat napsahtavat täyttämään kehyksen reunat</string>\n    <string name=\"histogram\">Histogrammi</string>\n    <string name=\"histogram_sub\">RGB- tai Brightness-kuvan histogrammi, joka auttaa sinua tekemään säätöjä</string>\n    <string name=\"image_for_histogram\">Tätä kuvaa käytetään RGB- ja Brightness-histogrammien luomiseen</string>\n    <string name=\"tesseract_options\">Tesseact-asetukset</string>\n    <string name=\"tesseract_options_sub\">Käytä joitain syöttömuuttujia tesseract-moottorille</string>\n    <string name=\"custom_options\">Mukautetut asetukset</string>\n    <string name=\"custom_params_info\">Vaihtoehdot tulee syöttää seuraavan mallin mukaisesti: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Automaattinen rajaus</string>\n    <string name=\"free_corners\">Vapaat kulmat</string>\n    <string name=\"free_corners_sub\">Rajaa kuvaa polygonin mukaan, tämä myös korjaa perspektiiviä</string>\n    <string name=\"coerce_points_to_image_bounds\">Pakottaa pisteitä kuvan rajoihin</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Kuvan rajat eivät rajoita pisteitä, mikä on hyödyllistä tarkemman perspektiivin korjauksessa</string>\n    <string name=\"mask\">Naamio</string>\n    <string name=\"spot_heal_sub\">Sisältötietoinen täyttö piirretyn polun alla</string>\n    <string name=\"spot_heal\">Parantumispiste</string>\n    <string name=\"use_circle_kernel\">Käytä Circle-ydintä</string>\n    <string name=\"opening\">Avaaminen</string>\n    <string name=\"closing\">Sulkeminen</string>\n    <string name=\"morphological_gradient\">Morfologinen gradientti</string>\n    <string name=\"top_hat\">Silinteri</string>\n    <string name=\"black_hat\">Musta hattu</string>\n    <string name=\"tone_curves\">Sävykäyrät</string>\n    <string name=\"reset_curves\">Nollaa käyrät</string>\n    <string name=\"reset_curves_sub\">Käyrät palautetaan oletusarvoihin</string>\n    <string name=\"line_style\">Viivan tyyli</string>\n    <string name=\"gap_size\">Välin koko</string>\n    <string name=\"dashed\">Katkotettu</string>\n    <string name=\"dot_dashed\">Piste katkoviiva</string>\n    <string name=\"stamped\">Leimattu</string>\n    <string name=\"zigzag\">Siksak</string>\n    <string name=\"dashed_sub\">Piirtää katkoviivan piirrettyä polkua pitkin määritetyllä aukon koolla</string>\n    <string name=\"dot_dashed_sub\">Piirtää pisteen ja katkoviivan annettua polkua pitkin</string>\n    <string name=\"defaultt_sub\">Vain oletussuorat viivat</string>\n    <string name=\"stamped_sub\">Piirtää valitut muodot polulle määritetyin välimatkoin</string>\n    <string name=\"zigzag_sub\">Piirtää polkua pitkin aaltoilevaa siksakia</string>\n    <string name=\"zigzag_ratio\">Siksak-suhde</string>\n    <string name=\"create_shortcut\">Luo pikakuvake</string>\n    <string name=\"create_shortcut_title\">Valitse kiinnitettävä työkalu</string>\n    <string name=\"create_shortcut_subtitle\">Työkalu lisätään käynnistysohjelman aloitusnäyttöön pikakuvakkeena. Käytä sitä yhdessä \\\"Ohita tiedostojen poiminta\\\" -asetuksen kanssa saavuttaaksesi tarvittavan toiminnan</string>\n    <string name=\"dont_stack_frames\">Älä pinoa kehyksiä</string>\n    <string name=\"dont_stack_frames_sub\">Mahdollistaa aikaisempien kehysten hävittämisen, joten ne eivät pinoudu päällekkäin</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Kehykset liitetään toisiinsa ristiin</string>\n    <string name=\"crossfade_count\">Crossfade-kehykset lasketaan</string>\n    <string name=\"threshold_one\">Kynnys yksi</string>\n    <string name=\"threshold_two\">Kynnys kaksi</string>\n    <string name=\"canny\">Ovela</string>\n    <string name=\"mirror_101\">Peili 101</string>\n    <string name=\"enhanced_zoom_blur\">Parannettu zoomaussumennus</string>\n    <string name=\"laplacian_simple\">Laplalainen yksinkertainen</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Helper Grid</string>\n    <string name=\"helper_grid_sub\">Näyttää tukiruudukon piirtoalueen yläpuolella, mikä helpottaa tarkkoja käsittelyjä</string>\n    <string name=\"grid_color\">Ruudukon väri</string>\n    <string name=\"cell_width\">Solun leveys</string>\n    <string name=\"cell_height\">Solun korkeus</string>\n    <string name=\"compact_selectors\">Kompaktit valitsimet</string>\n    <string name=\"compact_selectors_sub\">Jotkut valintaohjaimet käyttävät kompaktia asettelua, joka vie vähemmän tilaa</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Myönnä kameralle lupa asetuksista ottaa kuvia</string>\n    <string name=\"layout\">Layout</string>\n    <string name=\"main_screen_title\">Päänäytön otsikko</string>\n    <string name=\"constant_rate_factor\">Vakionopeustekijä (CRF)</string>\n    <string name=\"crf_sub\">Arvo %1$s tarkoittaa hidasta pakkausta, joka johtaa suhteellisen pieneen tiedostokokoon. %2$s tarkoittaa nopeampaa pakkausta, joka johtaa suureen tiedostoon.</string>\n    <string name=\"lut_library\">Lut kirjasto</string>\n    <string name=\"lut_library_sub\">Lataa LUT-kokoelma, jota voit käyttää lataamisen jälkeen</string>\n    <string name=\"lut_library_update_sub\">Päivitä LUT-kokoelma (vain uudet ovat jonossa), joita voit käyttää lataamisen jälkeen</string>\n    <string name=\"filter_preview_image_sub\">Muuta suodattimien oletuskuvan esikatselua</string>\n    <string name=\"filter_preview_image\">Esikatselukuva</string>\n    <string name=\"hide\">Piilottaa</string>\n    <string name=\"show\">Show</string>\n    <string name=\"slider_type\">Liukusäätimen tyyppi</string>\n    <string name=\"fancy\">Hieno</string>\n    <string name=\"material_2\">Materiaali 2</string>\n    <string name=\"fancy_sub\">Tyylikäs liukusäädin. Tämä on oletusasetus</string>\n    <string name=\"material_2_sub\">Materiaali 2 liukusäädin</string>\n    <string name=\"material_you_slider_sub\">Material You -liukusäädin</string>\n    <string name=\"apply\">Käytä</string>\n    <string name=\"center_align_dialog_buttons\">Keskusvalintapainikkeet</string>\n    <string name=\"center_align_dialog_buttons_sub\">Valintaikkunoiden painikkeet sijoitetaan keskelle vasemman reunan sijaan, jos mahdollista</string>\n    <string name=\"open_source_licenses\">Avoimen lähdekoodin lisenssit</string>\n    <string name=\"open_source_licenses_sub\">Tarkastele tässä sovelluksessa käytettyjen avoimen lähdekoodin kirjastojen lisenssejä</string>\n    <string name=\"area\">Alue</string>\n    <string name=\"area_sub\">Uudelleennäytteenotto pikselialuerelaation avulla. Se voi olla suositeltava menetelmä kuvan desimointiin, koska se antaa moire-vapaat tulokset. Mutta kun kuvaa zoomataan, se on samanlainen kuin \\\"Lähin\\\"-menetelmä.</string>\n    <string name=\"enable_tonemapping\">Ota Tonemapping käyttöön</string>\n    <string name=\"enter_percent\">Anna %</string>\n    <string name=\"unknown_host\">Sivustolle ei pääse, yritä käyttää VPN:ää tai tarkista, onko URL-osoite oikein</string>\n    <string name=\"markup_layers\">Merkintätasot</string>\n    <string name=\"markup_layers_sub\">Tasot-tila, jossa on mahdollisuus sijoittaa vapaasti kuvia, tekstiä ja muuta</string>\n    <string name=\"edit_layer\">Muokkaa tasoa</string>\n    <string name=\"layers_on_image\">Kerrokset kuvassa</string>\n    <string name=\"layers_on_image_sub\">Käytä kuvaa taustana ja lisää sen päälle erilaisia ​​kerroksia</string>\n    <string name=\"layers_on_background\">Tasot taustalla</string>\n    <string name=\"layers_on_background_sub\">Sama kuin ensimmäinen vaihtoehto, mutta värillä kuvan sijaan</string>\n    <string name=\"beta\">Beeta</string>\n    <string name=\"fast_settings_side\">Pika-asetukset-puoli</string>\n    <string name=\"fast_settings_side_sub\">Lisää kelluva nauha valitulle puolelle kuvien muokkauksen aikana, joka avaa nopeat asetukset, kun sitä napsautetaan</string>\n    <string name=\"clear_selection\">Tyhjennä valinta</string>\n    <string name=\"settings_group_visibility_hidden\">Asetusryhmä \\\"%1$s\\\" tiivistetään oletuksena</string>\n    <string name=\"settings_group_visibility_visible\">Asetusryhmä \\\"%1$s\\\" laajennetaan oletuksena</string>\n    <string name=\"base_64_tools\">Base64 työkalut</string>\n    <string name=\"base_64_tools_sub\">Pura Base64-merkkijono kuvaksi tai koodaa kuva Base64-muotoon</string>\n    <string name=\"base_64\">Perus64</string>\n    <string name=\"not_a_valid_base_64\">Annettu arvo ei ole kelvollinen Base64-merkkijono</string>\n    <string name=\"copy_not_a_valid_base_64\">Tyhjää tai virheellistä Base64-merkkijonoa ei voi kopioida</string>\n    <string name=\"paste_base_64\">Liitä pohja64</string>\n    <string name=\"copy_base_64\">Kopioi Base64</string>\n    <string name=\"base_64_tips\">Lataa kuva kopioidaksesi tai tallentaaksesi Base64-merkkijonon. Jos sinulla on itse merkkijono, voit liittää sen yllä saadaksesi kuvan</string>\n    <string name=\"save_base_64\">Tallenna Base64</string>\n    <string name=\"share_base_64\">Share Base64</string>\n    <string name=\"options\">Vaihtoehdot</string>\n    <string name=\"actions\">Toiminnot</string>\n    <string name=\"import_base_64\">Tuo Base64</string>\n    <string name=\"base_64_actions\">Base64-toiminnot</string>\n    <string name=\"add_outline\">Lisää ääriviivat</string>\n    <string name=\"add_outline_sub\">Lisää tekstin ympärille ääriviiva määritetyllä värillä ja leveydellä</string>\n    <string name=\"outline_color\">Ääriviivan väri</string>\n    <string name=\"outline_size\">Ääriviivan koko</string>\n    <string name=\"rotation\">Kierto</string>\n    <string name=\"checksum_as_filename\">Tarkistussumma tiedostonimenä</string>\n    <string name=\"checksum_as_filename_sub\">Tulostetuilla kuvilla on niiden tietojen tarkistussummaa vastaava nimi</string>\n    <string name=\"free_software_partner\">Vapaa ohjelmisto (kumppani)</string>\n    <string name=\"free_software_partner_sub\">Lisää hyödyllisiä ohjelmistoja Android-sovellusten kumppanikanavassa</string>\n    <string name=\"algorithms\">Algoritmi</string>\n    <string name=\"checksum_tools\">Tarkistussummatyökalut</string>\n    <string name=\"checksum_tools_sub\">Vertaile tarkistussummia, laske tiivisteitä tai luo heksadesimaattisia merkkijonoja tiedostoista käyttämällä erilaisia ​​hajautusalgoritmeja</string>\n    <string name=\"calculate\">Laskea</string>\n    <string name=\"text_hash\">Teksti Hash</string>\n    <string name=\"checksum\">Tarkistussumma</string>\n    <string name=\"pick_file_to_checksum\">Valitse tiedosto laskeaksesi sen tarkistussumma valitun algoritmin perusteella</string>\n    <string name=\"enter_text_to_checksum\">Syötä tekstiä sen tarkistussumman laskemiseksi valitun algoritmin perusteella</string>\n    <string name=\"source_checksum\">Lähteen tarkistussumma</string>\n    <string name=\"checksum_to_compare\">Vertailun tarkistussumma</string>\n    <string name=\"match\">Ottelu!</string>\n    <string name=\"difference\">Ero</string>\n    <string name=\"match_sub\">Tarkistussummat ovat yhtä suuret, se voi olla turvallista</string>\n    <string name=\"difference_sub\">Tarkistussummat eivät ole samat, tiedosto voi olla vaarallinen!</string>\n    <string name=\"mesh_gradients\">Mesh gradientit</string>\n    <string name=\"collection_mesh_gradients_sub\">Katso verkkogradienttikokoelmaa</string>\n    <string name=\"wrong_font\">Vain TTF- ja OTF-fontteja voidaan tuoda</string>\n    <string name=\"import_font\">Tuo fontti (TTF/OTF)</string>\n    <string name=\"export_fonts\">Vie fontit</string>\n    <string name=\"imported_fonts\">Tuodut fontit</string>\n    <string name=\"error_while_saving\">Virhe tallennettaessa yritystä, yritä vaihtaa tulostuskansiota</string>\n    <string name=\"filename_is_not_set\">Tiedostonimeä ei ole asetettu</string>\n    <string name=\"none\">Ei mitään</string>\n    <string name=\"custom_pages\">Mukautetut sivut</string>\n    <string name=\"pages_selection\">Sivujen valinta</string>\n    <string name=\"tool_exit_confirmation\">Työkalun poistumisen vahvistus</string>\n    <string name=\"tool_exit_confirmation_sub\">Jos sinulla on tallentamattomia muutoksia käyttäessäsi tiettyjä työkaluja ja yrität sulkea sen, vahvistusikkuna tulee näkyviin</string>\n    <string name=\"edit_exif_screen\">Muokkaa EXIF-tiedostoa</string>\n    <string name=\"edit_exif_screen_sub\">Muuta yksittäisen kuvan metatietoja ilman uudelleenpakkausta</string>\n    <string name=\"edit_exif_tag\">Napauta muokataksesi käytettävissä olevia tunnisteita</string>\n    <string name=\"change_sticker\">Vaihda tarra</string>\n    <string name=\"fit_width\">Sovita leveys</string>\n    <string name=\"fit_height\">Sopiva korkeus</string>\n    <string name=\"batch_compare\">Erävertailu</string>\n    <string name=\"pick_files_to_checksum\">Valitse tiedosto/tiedostot laskeaksesi sen tarkistussumman valitun algoritmin perusteella</string>\n    <string name=\"pick_files\">Valitse tiedostot</string>\n    <string name=\"pick_directory\">Valitse hakemisto</string>\n    <string name=\"head_length_scale\">Pään pituusasteikko</string>\n    <string name=\"stamp\">Leima</string>\n    <string name=\"timestamp\">Aikaleima</string>\n    <string name=\"format_pattern\">Muotoile kuvio</string>\n    <string name=\"padding\">Pehmuste</string>\n    <string name=\"image_cutting\">Kuvan leikkaaminen</string>\n    <string name=\"image_cutting_sub\">Leikkaa kuvan osa ja yhdistä vasemmanpuoleiset (voi olla käänteinen) pysty- tai vaakaviivoilla</string>\n    <string name=\"vertical_pivot_line\">Pysty Pivot Line</string>\n    <string name=\"horizontal_pivot_line\">Vaakasuuntainen kääntöviiva</string>\n    <string name=\"inverse_selection\">Käänteinen valinta</string>\n    <string name=\"inverse_vertical_selection_sub\">Pystysuora leikkausosa jätetään sen sijaan, että osia yhdistettäisiin leikatun alueen ympärillä</string>\n    <string name=\"inverse_horizontal_selection_sub\">Vaakasuora leikkausosa jätetään sen sijaan, että osia yhdistettäisiin leikatun alueen ympärillä</string>\n    <string name=\"collection_mesh_gradients\">Kokoelma verkkogradientteja</string>\n    <string name=\"mesh_gradients_sub\">Luo mesh-gradientti mukautetulla määrällä solmuja ja resoluutiota</string>\n    <string name=\"gradient_maker_type_image_mesh\">Mesh-gradienttipeitto</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Luo mesh-gradientti annettujen kuvien yläreunasta</string>\n    <string name=\"points_customization\">Pisteiden räätälöinti</string>\n    <string name=\"grid_size\">Ruudukon koko</string>\n    <string name=\"resolution_x\">Päätös X</string>\n    <string name=\"resolution_y\">Päätös Y</string>\n    <string name=\"resolution\">Resoluutio</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">Korosta Väri</string>\n    <string name=\"pixel_comparison_type\">Pikselivertailutyyppi</string>\n    <string name=\"scan_barcode\">Skannaa viivakoodi</string>\n    <string name=\"height_ratio\">Korkeussuhde</string>\n    <string name=\"barcode_type\">Viivakoodin tyyppi</string>\n    <string name=\"enforce_bw\">Täytä mustavalkoinen</string>\n    <string name=\"enforce_bw_sub\">Viivakoodikuva on täysin mustavalkoinen, eikä sitä väritä sovelluksen teema</string>\n    <string name=\"barcodes_sub\">Skannaa mikä tahansa viivakoodi (QR, EAN, AZTEC,…) ja hanki sen sisältö tai liitä tekstisi luodaksesi uuden</string>\n    <string name=\"no_barcode_found\">Viivakoodia ei löydy</string>\n    <string name=\"generated_barcode_will_be_here\">Luotu viivakoodi on täällä</string>\n    <string name=\"audio_cover_extractor\">Äänikotelot</string>\n    <string name=\"audio_cover_extractor_sub\">Pura albumin kansikuvat äänitiedostoista, yleisimpiä muotoja tuetaan</string>\n    <string name=\"pick_audio_to_start\">Aloita valitsemalla ääni</string>\n    <string name=\"pick_audio\">Valitse Ääni</string>\n    <string name=\"no_covers_found\">Kansia ei löytynyt</string>\n    <string name=\"send_logs\">Lähetä lokit</string>\n    <string name=\"send_logs_sub\">Napsauta jakaaksesi sovelluksen lokitiedoston. Tämä voi auttaa minua havaitsemaan ongelman ja korjaamaan ongelmat</string>\n    <string name=\"crash_title\">Hups… Jotain meni pieleen</string>\n    <string name=\"crash_subtitle\">Voit ottaa minuun yhteyttä alla olevilla vaihtoehdoilla, niin yritän löytää ratkaisun.\\n(Älä unohda liittää lokit)</string>\n    <string name=\"ocr_write_to_file\">Kirjoita tiedostoon</string>\n    <string name=\"ocr_write_to_file_sub\">Pura teksti kuvaerästä ja tallenna se yhteen tekstitiedostoon</string>\n    <string name=\"ocr_write_to_metadata\">Kirjoita metatietoihin</string>\n    <string name=\"ocr_write_to_metadata_sub\">Poimi teksti jokaisesta kuvasta ja sijoita se suhteellisten valokuvien EXIF-tietoihin</string>\n    <string name=\"invisible_mode\">Näkymätön tila</string>\n    <string name=\"invisible_mode_sub\">Käytä steganografiaa luodaksesi silmille näkymättömiä vesileimoja kuviesi tavujen sisään</string>\n    <string name=\"use_lsb\">Käytä LSB:tä</string>\n    <string name=\"use_lsb_sub\">LSB (Less Significant Bit) steganografiamenetelmää käytetään, muuten FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Automaattinen punasilmäisyyden poisto</string>\n    <string name=\"password\">Salasana</string>\n    <string name=\"unlock\">Avata</string>\n    <string name=\"pdf_is_protected\">PDF on suojattu</string>\n    <string name=\"operation_almost_complete\">Toiminta melkein valmis. Peruuttaminen nyt vaatii sen uudelleenkäynnistyksen</string>\n    <string name=\"sort_by_date_modified\">Muutospäivämäärä</string>\n    <string name=\"sort_by_date_modified_reversed\">Muokkauspäivä (käännetty)</string>\n    <string name=\"sort_by_size\">Koko</string>\n    <string name=\"sort_by_size_reversed\">Koko (käänteinen)</string>\n    <string name=\"sort_by_mime_type\">MIME-tyyppi</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME-tyyppi (käänteinen)</string>\n    <string name=\"sort_by_extension\">Laajennus</string>\n    <string name=\"sort_by_extension_reversed\">Laajennus (käänteinen)</string>\n    <string name=\"sort_by_date_added\">Lisäyspäivä</string>\n    <string name=\"sort_by_date_added_reversed\">Lisäyspäivä (käännetty)</string>\n    <string name=\"left_to_right\">Vasemmalta oikealle</string>\n    <string name=\"right_to_left\">Oikealta vasemmalle</string>\n    <string name=\"top_to_bottom\">Ylhäältä alas</string>\n    <string name=\"bottom_to_top\">Alhaalta ylös</string>\n    <string name=\"liquid_glass\">Nestemäinen lasi</string>\n    <string name=\"liquid_glass_sub\">Kytkin perustuu äskettäin julkistettuun IOS 26:een ja sen nestemäisen lasin suunnittelujärjestelmään</string>\n    <string name=\"pick_image_or_base64\">Valitse kuva tai liitä/tuo Base64-tiedot alta</string>\n    <string name=\"type_image_link\">Aloita kirjoittamalla kuvalinkki</string>\n    <string name=\"paste_link\">Liitä linkki</string>\n    <string name=\"kaleidoscope\">Kaleidoskooppi</string>\n    <string name=\"secondary_angle\">Toissijainen kulma</string>\n    <string name=\"sides\">Sivut</string>\n    <string name=\"channel_mix\">Kanavasekoitus</string>\n    <string name=\"blue_green\">Sinivihreä</string>\n    <string name=\"red_blue\">Punainen sininen</string>\n    <string name=\"green_red\">Vihreä punainen</string>\n    <string name=\"into_red\">Punaiseksi</string>\n    <string name=\"into_green\">Vihreään</string>\n    <string name=\"into_blue\">Siniseen</string>\n    <string name=\"cyan\">Syaani</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Keltainen</string>\n    <string name=\"color_halftone\">Väri puolisävy</string>\n    <string name=\"contour\">Contour</string>\n    <string name=\"levels\">Tasot</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi kiteytyy</string>\n    <string name=\"shape\">Muoto</string>\n    <string name=\"stretch\">Venyttää</string>\n    <string name=\"randomness\">Satunnaisuus</string>\n    <string name=\"despeckle\">Poistaa täplät</string>\n    <string name=\"diffuse\">Hajanainen</string>\n    <string name=\"dog\">Koira</string>\n    <string name=\"second_radius\">Toinen säde</string>\n    <string name=\"equalize\">Tasaa</string>\n    <string name=\"glow\">Hehku</string>\n    <string name=\"whirl_and_pinch\">Pyöritä ja purista</string>\n    <string name=\"pointillize\">Pointillisoida</string>\n    <string name=\"border_color\">Reunuksen väri</string>\n    <string name=\"polar_coordinates\">Napakoordinaatit</string>\n    <string name=\"rect_to_polar\">Suoraan napaiseen</string>\n    <string name=\"polar_to_rect\">Polaarinen suoraan</string>\n    <string name=\"invert_in_circle\">Käännä ympyrässä</string>\n    <string name=\"reduce_noise\">Vähennä melua</string>\n    <string name=\"simple_solarize\">Yksinkertainen solarisointi</string>\n    <string name=\"weave\">Kutoa</string>\n    <string name=\"x_gap\">X aukko</string>\n    <string name=\"y_gap\">Y väli</string>\n    <string name=\"x_width\">X Leveys</string>\n    <string name=\"y_wdth\">Y Leveys</string>\n    <string name=\"twirl\">Pyöritä</string>\n    <string name=\"rubber_stmp\">Kumileimasin</string>\n    <string name=\"smear\">Smear</string>\n    <string name=\"density\">Tiheys</string>\n    <string name=\"mix\">Sekoita</string>\n    <string name=\"sphere_lensh_distortion\">Pallolinssin vääristymä</string>\n    <string name=\"refraction_index\">Taitekerroin</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Levityskulma</string>\n    <string name=\"sparkle\">Kimallus</string>\n    <string name=\"rays\">Säteet</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Kaltevuus</string>\n    <string name=\"moire\">Mary</string>\n    <string name=\"autumn\">Syksy</string>\n    <string name=\"bone\">Luu</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Talvi</string>\n    <string name=\"ocean\">Valtameri</string>\n    <string name=\"summer\">Kesä</string>\n    <string name=\"spring\">Kevät</string>\n    <string name=\"cool_variant\">Cool Variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Vaaleanpunainen</string>\n    <string name=\"hot\">Kuuma</string>\n    <string name=\"parula\">Sana</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Kansalaiset</string>\n    <string name=\"twilight\">Iltahämärä</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspective Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Salli rajaus</string>\n    <string name=\"crop_or_perspective\">Raja tai perspektiivi</string>\n    <string name=\"absolute\">Ehdoton</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Syvän vihreä</string>\n    <string name=\"lens_correction\">Linssin korjaus</string>\n    <string name=\"target_lens_profile\">Kohdeobjektiivin profiilitiedosto JSON-muodossa</string>\n    <string name=\"download_ready_lens_profiles\">Lataa valmiit linssiprofiilit</string>\n    <string name=\"part_percents\">Osaprosentit</string>\n    <string name=\"export_as_json\">Vie JSON-muodossa</string>\n    <string name=\"export_as_json_sub\">Kopioi merkkijono, jossa on palettitiedot json-muodossa</string>\n    <string name=\"seam_carving\">Sauman veistäminen</string>\n    <string name=\"home_screen\">Kotinäyttö</string>\n    <string name=\"lock_screen\">Lukitusnäyttö</string>\n    <string name=\"built_in\">Sisäänrakennettu</string>\n    <string name=\"wallpapers_export\">Taustakuvien vienti</string>\n    <string name=\"refresh\">Päivitä</string>\n    <string name=\"wallpapers_export_sub\">Hanki nykyiset koti-, lukko- ja sisäänrakennetut taustakuvat</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Salli pääsy kaikkiin tiedostoihin, tätä tarvitaan taustakuvien hakemiseen</string>\n    <string name=\"allow_read_media_images_for_wp\">Hallinnoi ulkoista tallennustilaa ei riitä, sinun on sallittava kuviesi käyttö. Muista valita \\\"Salli kaikki\\\".</string>\n    <string name=\"add_preset_to_filename\">Lisää esiasetus tiedostonimeen</string>\n    <string name=\"add_preset_to_filename_sub\">Lisää valitun esiasetuksen mukaisen päätteen kuvatiedoston nimeen</string>\n    <string name=\"add_image_scale_mode_to_filename\">Lisää kuvan skaalaustila tiedostonimeen</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Lisää valitun kuvan mittakaavatilan päätteen kuvatiedoston nimeen</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Muunna kuva ascii-tekstiksi, joka näyttää kuvalta</string>\n    <string name=\"params\">Parametrit</string>\n    <string name=\"invert_colors_ascii_sub\">Käytä negatiivista suodatinta kuvaan paremman tuloksen saavuttamiseksi joissakin tapauksissa</string>\n    <string name=\"processing_screenshot\">Käsitellään kuvakaappausta</string>\n    <string name=\"screenshot_not_captured_try_again\">Kuvakaappausta ei otettu, yritä uudelleen</string>\n    <string name=\"skipped_saving\">Tallennus ohitettu</string>\n    <string name=\"skipped_saving_multiple\">%1$s tiedostoa ohitettiin</string>\n    <string name=\"allow_skip_if_larger\">Salli Ohita, jos suurempi</string>\n    <string name=\"allow_skip_if_larger_sub\">Jotkut työkalut voivat ohittaa kuvien tallentamisen, jos tuloksena oleva tiedostokoko on suurempi kuin alkuperäinen</string>\n    <string name=\"qr_type_calendar_event\">Kalenteri Tapahtuma</string>\n    <string name=\"qr_type_contact_info\">Ota yhteyttä</string>\n    <string name=\"qr_type_email\">Sähköposti</string>\n    <string name=\"qr_type_geo_point\">Sijainti</string>\n    <string name=\"qr_type_phone\">Puhelin</string>\n    <string name=\"qr_type_plain\">Teksti</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL-osoite</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Avoin verkko</string>\n    <string name=\"not_specified\">Ei käytössä</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Puhelin</string>\n    <string name=\"message\">Viesti</string>\n    <string name=\"address\">Osoite</string>\n    <string name=\"subject\">Aihe</string>\n    <string name=\"body\">Runko</string>\n    <string name=\"name\">Nimi</string>\n    <string name=\"organization\">Organisaatio</string>\n    <string name=\"title\">Otsikko</string>\n    <string name=\"phones\">Puhelimet</string>\n    <string name=\"emails\">Sähköpostit</string>\n    <string name=\"urls\">URL-osoitteet</string>\n    <string name=\"addresses\">Osoitteet</string>\n    <string name=\"summary\">Yhteenveto</string>\n    <string name=\"description\">Kuvaus</string>\n    <string name=\"location\">Sijainti</string>\n    <string name=\"organizer\">Järjestäjä</string>\n    <string name=\"start_date\">Aloituspäivämäärä</string>\n    <string name=\"end_date\">Päättymispäivä</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Leveysaste</string>\n    <string name=\"longitude\">Pituusaste</string>\n    <string name=\"create_barcode\">Luo viivakoodi</string>\n    <string name=\"edit_barcode\">Muokkaa viivakoodia</string>\n    <string name=\"wifi_configuration\">Wi-Fi-määritys</string>\n    <string name=\"security\">Turvallisuus</string>\n    <string name=\"pick_contact\">Valitse yhteystieto</string>\n    <string name=\"grant_contact_permission\">Myönnä kontakteille asetuksissa lupa täyttää automaattisesti valitun yhteystiedon avulla</string>\n    <string name=\"contact_info\">Yhteystiedot</string>\n    <string name=\"first_name\">Etunimi</string>\n    <string name=\"middle_name\">Toinen nimi</string>\n    <string name=\"last_name\">Sukunimi</string>\n    <string name=\"pronunciation\">Ääntäminen</string>\n    <string name=\"add_phone\">Lisää puhelin</string>\n    <string name=\"add_email\">Lisää sähköpostiosoite</string>\n    <string name=\"add_address\">Lisää osoite</string>\n    <string name=\"website\">Verkkosivusto</string>\n    <string name=\"add_website\">Lisää verkkosivusto</string>\n    <string name=\"formatted_name\">Muotoiltu nimi</string>\n    <string name=\"qr_code_top_image\">Tätä kuvaa käytetään viivakoodin yläpuolelle sijoittamiseen</string>\n    <string name=\"code_customization\">Koodin mukauttaminen</string>\n    <string name=\"qr_logo_image\">Tätä kuvaa käytetään logona QR-koodin keskellä</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo pehmuste</string>\n    <string name=\"logo_size\">Logon koko</string>\n    <string name=\"logo_corners\">Logon kulmat</string>\n    <string name=\"fourth_eye\">Neljäs silmä</string>\n    <string name=\"fourth_eye_description\">Lisää silmäsymmetriaa qr-koodiin lisäämällä neljännen silmän alareunaan</string>\n    <string name=\"pixel_shape\">Pikselin muoto</string>\n    <string name=\"frame_shape\">Kehyksen muoto</string>\n    <string name=\"ball_shape\">Pallon muoto</string>\n    <string name=\"error_correction_level\">Virheenkorjaustaso</string>\n    <string name=\"dark_color\">Tumma väri</string>\n    <string name=\"light_color\">Vaalea väri</string>\n    <string name=\"hyper_os\">Hyper käyttöjärjestelmä</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS:n kaltainen tyyli</string>\n    <string name=\"mask_pattern\">Maski kuvio</string>\n    <string name=\"code_may_be_not_scannable\">Tätä koodia ei ehkä voi skannata. Muuta ulkoasuparametreja, jotta se on luettavissa kaikilla laitteilla</string>\n    <string name=\"not_scannable\">Ei skannattavissa</string>\n    <string name=\"launcher_mode_sub\">Työkalut näyttävät aloitusnäytön sovellusten käynnistysohjelmalta, jotta ne olisivat kompaktimpia</string>\n    <string name=\"launcher_mode\">Käynnistystila</string>\n    <string name=\"flood_fill_sub\">Täyttää alueen valitulla siveltimellä ja tyylillä</string>\n    <string name=\"flood_fill\">Tulva täyttö</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Piirtää graffitityylisen polun</string>\n    <string name=\"square_particles\">Neliömäiset hiukkaset</string>\n    <string name=\"square_particles_sub\">Suihkehiukkaset ovat neliön muotoisia ympyröiden sijaan</string>\n    <string name=\"palette_tools\">Palettityökalut</string>\n    <string name=\"palette_tools_sub\">Luo perus-/materiaali paletti kuvasta tai tuo/vie eri palettimuodoissa</string>\n    <string name=\"edit_palette\">Muokkaa palettia</string>\n    <string name=\"edit_palette_sub\">Vie/tuo paletti eri muodoissa</string>\n    <string name=\"color_name\">Värin nimi</string>\n    <string name=\"palette_name\">Paletin nimi</string>\n    <string name=\"palette_format\">Paletin muoto</string>\n    <string name=\"export_palette_sub\">Vie luotu paletti eri muotoihin</string>\n    <string name=\"add_color_palette_sub\">Lisää uutta väriä nykyiseen palettiin</string>\n    <string name=\"palette_name_not_supported\">%1$s-muoto ei tue paletin nimen antamista</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Kaupan käytäntöjen vuoksi tätä ominaisuutta ei voi sisällyttää nykyiseen koontiversioon. Voit käyttää tätä toimintoa lataamalla ImageToolboxin vaihtoehtoisesta lähteestä. Löydät saatavilla olevat versiot GitHubista alta.</string>\n    <string name=\"open_github_page\">Avaa Github-sivu</string>\n    <string name=\"overwrite_files_sub_short\">Alkuperäinen tiedosto korvataan uudella sen sijaan, että se tallennettaisiin valittuun kansioon</string>\n    <string name=\"hidden_watermark_text_detected\">Havaittiin piilotettu vesileimateksti</string>\n    <string name=\"hidden_watermark_image_detected\">Havaittiin piilotettu vesileimakuva</string>\n    <string name=\"this_image_was_hidden\">Tämä kuva oli piilotettu</string>\n    <string name=\"generative_inpaint\">Generatiivinen maalaus</string>\n    <string name=\"generative_inpaint_sub\">Mahdollistaa objektien poistamisen kuvasta tekoälymallin avulla turvautumatta OpenCV:hen. Tämän ominaisuuden käyttämiseksi sovellus lataa vaaditun mallin (~200 Mt) GitHubista</string>\n    <string name=\"generative_inpaint_ready_sub\">Mahdollistaa objektien poistamisen kuvasta tekoälymallin avulla turvautumatta OpenCV:hen. Tämä voi olla pitkäkestoinen operaatio</string>\n    <string name=\"error_level_analysis\">Virhetason analyysi</string>\n    <string name=\"luminance_gradient\">Luminanssigradientti</string>\n    <string name=\"average_distance\">Keskimääräinen etäisyys</string>\n    <string name=\"copy_move_detection\">Kopioi siirtotunnistus</string>\n    <string name=\"retain\">Säilyttää</string>\n    <string name=\"coefficent\">Kerroin</string>\n    <string name=\"clipboard_data_is_too_large\">Leikepöydän tiedot ovat liian suuria</string>\n    <string name=\"data_is_too_large_to_copy\">Data on liian suuri kopioitavaksi</string>\n    <string name=\"simple_weave_pixelization\">Yksinkertainen Weave-pikselointi</string>\n    <string name=\"staggered_pixelization\">Porrastettu pikselisointi</string>\n    <string name=\"cross_pixelization\">Ristipikselointi</string>\n    <string name=\"micro_macro_pixelization\">Mikro-makropikselointi</string>\n    <string name=\"orbital_pixelization\">Orbitaalinen pikselisointi</string>\n    <string name=\"vortex_pixelization\">Vortex-pikselointi</string>\n    <string name=\"pulse_grid_pixelization\">Pulssiruudukon pikselointi</string>\n    <string name=\"nucleus_pixelization\">Ytimen pikselisaatio</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave -pikselointi</string>\n    <string name=\"cannot_open_uri\">Ei voi avata uria \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Lumisadetila</string>\n    <string name=\"enabled\">Käytössä</string>\n    <string name=\"border_frame\">Reunuskehys</string>\n    <string name=\"glitch_variant\">Glitch Variant</string>\n    <string name=\"channel_shift\">Kanavan vaihto</string>\n    <string name=\"max_offset\">Max Offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Estä Glitch</string>\n    <string name=\"block_size\">Lohkon koko</string>\n    <string name=\"crt_curvature\">CRT-kaarevuus</string>\n    <string name=\"curvature\">Kaarevuus</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pikselin sulaminen</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">AI-työkalut</string>\n    <string name=\"ai_tools_sub\">Erilaisia ​​työkaluja kuvien käsittelyyn AI-mallien avulla, kuten artefaktien poistaminen tai kohinan poistaminen</string>\n    <string name=\"model_anime_undeint\">Puristus, rosoiset linjat</string>\n    <string name=\"model_broadcast\">Sarjakuvat, lähetyspakkaus</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Yleinen puristus, yleinen melu</string>\n    <string name=\"model_wb_denoise\">Väritön sarjakuva melu</string>\n    <string name=\"model_span_anime_pretrain\">Nopea, yleinen pakkaus, yleinen kohina, animaatio/sarjakuva/anime</string>\n    <string name=\"model_book_scan\">Kirjan skannaus</string>\n    <string name=\"model_overexposure\">Altistuksen korjaus</string>\n    <string name=\"model_fbcnn_color_fp16\">Paras yleisessä pakkauksessa, värikuvissa</string>\n    <string name=\"model_fbcnn_gray_fp16\">Paras yleisessä pakkauksessa, harmaasävykuvissa</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Yleinen pakkaus, harmaasävykuvat, vahvempi</string>\n    <string name=\"model_scunet_color_gan_fp16\">Yleinen kohina, värikuvat</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Yleinen kohina, värikuvat, paremmat yksityiskohdat</string>\n    <string name=\"model_scunet_gray_15_fp16\">Yleinen kohina, harmaasävykuvat</string>\n    <string name=\"model_scunet_gray_25_fp16\">Yleinen kohina, harmaasävykuvat, vahvempi</string>\n    <string name=\"model_scunet_gray_50_fp16\">Yleinen kohina, harmaasävykuvat, voimakkain</string>\n    <string name=\"model_jpeg_destroyer\">Yleinen pakkaus</string>\n    <string name=\"model_jaywreck\">Yleinen pakkaus</string>\n    <string name=\"model_h264\">Teksturointi, h264-pakkaus</string>\n    <string name=\"model_vhs\">VHS-pakkaus</string>\n    <string name=\"model_cinepak\">Epätyypillinen pakkaus (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink-pakkaus, parempi geometriassa</string>\n    <string name=\"model_debink_v5\">Bink-puristus, vahvempi</string>\n    <string name=\"model_debink_v6\">Bink-pakkaus, pehmeä, säilyttää yksityiskohdat</string>\n    <string name=\"model_antialias\">Poistaa portaikkovaikutuksen, tasoittaa</string>\n    <string name=\"model_kdm_scans\">Skannattu taide/piirustukset, lievä pakkaus, moire</string>\n    <string name=\"model_bandage\">Värinauha</string>\n    <string name=\"model_halftone\">Hidasta, puolisävyjä poistavaa</string>\n    <string name=\"model_colorizer\">Yleisväriaine harmaasävy-/bw-kuville, parempien tulosten saamiseksi käytä DDColoria</string>\n    <string name=\"model_deedge\">Reunojen poisto</string>\n    <string name=\"model_desharpen\">Poistaa yliteroittumisen</string>\n    <string name=\"model_dither\">Hidasta, hämmentävää</string>\n    <string name=\"model_gainres\">Anti-aliasing, yleiset artefaktit, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 skannaa käsittelyä</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Kevyt kuvanparannusmalli</string>\n    <string name=\"model_bcgone_detailed_v2\">Puristusartefaktien poisto</string>\n    <string name=\"model_bcgone_smooth\">Puristusartefaktien poisto</string>\n    <string name=\"model_bandage_smooth\">Siteen poisto tasaisin tuloksin</string>\n    <string name=\"model_bendel_halftone\">Rasterikuvioiden käsittely</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Dther-kuvion poisto V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG-artefaktin poisto V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 tekstuurin parannus</string>\n    <string name=\"model_vhs_sharpen\">VHS-terästys ja parannus</string>\n    <string name=\"merging\">Yhdistäminen</string>\n    <string name=\"chunk_size\">Palan koko</string>\n    <string name=\"overlap_size\">Päällekkäisyyden koko</string>\n    <string name=\"note_chunk_info\">Kuvat, joiden koko on yli %1$s px, leikataan ja käsitellään paloina, ja ne sekoitetaan päällekkäin, jotta vältetään näkyviä saumoja.</string>\n    <string name=\"large_chunk_warning\">Suuret koot voivat aiheuttaa epävakautta halvempien laitteiden kanssa</string>\n    <string name=\"select_one_to_start\">Aloita valitsemalla yksi</string>\n    <string name=\"delete_model_sub\">Haluatko poistaa mallin %1$s? Sinun on ladattava se uudelleen</string>\n    <string name=\"confirm\">Vahvistaa</string>\n    <string name=\"models\">Mallit</string>\n    <string name=\"downloaded_models\">Ladatut mallit</string>\n    <string name=\"available_models\">Saatavilla olevat mallit</string>\n    <string name=\"preparing\">Valmistellaan</string>\n    <string name=\"active_model\">Aktiivinen malli</string>\n    <string name=\"failed_to_open_session\">Istunnon avaaminen epäonnistui</string>\n    <string name=\"only_onnx_models\">Vain .onnx/.ort-malleja voidaan tuoda</string>\n    <string name=\"import_model\">Tuo malli</string>\n    <string name=\"import_model_sub\">Tuo mukautettu onnx-malli myöhempää käyttöä varten, vain onnx/ort-mallit hyväksytään, tukee melkein kaikkia esrgan-tyyppisiä variantteja</string>\n    <string name=\"imported_models\">Tuodut mallit</string>\n    <string name=\"model_scunet_color_15_fp16\">Yleinen kohina, värilliset kuvat</string>\n    <string name=\"model_scunet_color_25_fp16\">Yleinen kohina, värilliset kuvat, vahvempi</string>\n    <string name=\"model_scunet_color_50_fp16\">Yleinen kohina, värilliset kuvat, voimakkain</string>\n    <string name=\"model_artifacts_dithering_alsa\">Vähentää haalistuvia artefakteja ja värijuovia parantaen tasaisia ​​liukuvärejä ja tasaisia ​​värialueita.</string>\n    <string name=\"model_nmkd_brighten_redux\">Parantaa kuvan kirkkautta ja kontrastia tasapainoisilla kohokohdilla säilyttäen samalla luonnolliset värit.</string>\n    <string name=\"model_nmkd_brighten\">Kirkastaa tummia kuvia säilyttäen samalla yksityiskohdat ja välttäen ylivalotusta.</string>\n    <string name=\"model_nmkd_detoon\">Poistaa liiallisen värisävytyksen ja palauttaa neutraalimman ja luonnollisemman väritasapainon.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Käyttää Poisson-pohjaista kohinan sävytystä painottaen hienojen yksityiskohtien ja tekstuurien säilyttämistä.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Käyttää pehmeää Poisson-kohinavärjäystä tasaisempien ja vähemmän aggressiivisten visuaalisten tulosten saamiseksi.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Tasainen kohinan sävytys keskittyy yksityiskohtien säilyttämiseen ja kuvan selkeyteen.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Hellävarainen tasainen kohinan sävytys hienovaraisen koostumuksen ja sileän ulkonäön saavuttamiseksi.</string>\n    <string name=\"model_repainter\">Korjaa vaurioituneet tai epätasaiset alueet maalaamalla esineitä uudelleen ja parantamalla kuvan yhtenäisyyttä.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Kevyt kaistanpoistomalli, joka poistaa värijuovat minimaalisilla suorituskustannuksilla.</string>\n    <string name=\"model_jpeg_0_20\">Optimoi kuvat, joissa on erittäin korkea pakkausvirhe (0-20 % laatu) selkeyden parantamiseksi.</string>\n    <string name=\"model_jpeg_20_40\">Parantaa kuvia korkean pakkauksen artefakteilla (20-40 % laatu), palauttaa yksityiskohtia ja vähentää kohinaa.</string>\n    <string name=\"model_jpeg_40_60\">Parantaa kuvia kohtuullisella pakkauksella (laatu 40-60 %) ja tasapainottaa terävyyttä ja tasaisuutta.</string>\n    <string name=\"model_jpeg_60_80\">Tarkoittaa kuvia kevyellä pakkauksella (60-80 % laatu) parantaakseen hienovaraisia ​​yksityiskohtia ja tekstuureja.</string>\n    <string name=\"model_jpeg_80_100\">Parantaa hieman lähes häviöttömiä kuvia (80-100 % laatu) säilyttäen samalla luonnollisen ilmeen ja yksityiskohdat.</string>\n    <string name=\"model_spongecolor_lite\">Yksinkertainen ja nopea väritys, sarjakuvia, ei ihanteellinen</string>\n    <string name=\"model_deblr\">Vähentää hieman kuvan epäterävyyttä ja parantaa terävyyttä ilman artefakteja.</string>\n    <string name=\"processing_channel\">Pitkät toiminnot</string>\n    <string name=\"processing_image\">Käsitellään kuvaa</string>\n    <string name=\"processing\">Käsittely</string>\n    <string name=\"model_artifacts_jpg_0_20\">Poistaa raskaat JPEG-pakkausartefaktit erittäin huonolaatuisista kuvista (0-20 %).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Vähentää vahvoja JPEG-artefakteja erittäin pakatuissa kuvissa (20-40 %).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Puhdistaa kohtalaiset JPEG-artefaktit säilyttäen samalla kuvan yksityiskohdat (40-60 %).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Tarkoittaa kevyitä JPEG-artefakteja melko korkealaatuisissa kuvissa (60-80 %).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Vähentää hienovaraisesti pieniä JPEG-virheitä lähes häviöttömissä kuvissa (80-100 %).</string>\n    <string name=\"model_redetail_v2\">Korostaa hienoja yksityiskohtia ja tekstuureja parantaen havaittua terävyyttä ilman raskaita esineitä.</string>\n    <string name=\"processing_finished\">Käsittely valmis</string>\n    <string name=\"processing_failed\">Käsittely epäonnistui</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Parantaa ihon tekstuuria ja yksityiskohtia säilyttäen luonnollisen ulkonäön, optimoituna nopeuteen.</string>\n    <string name=\"model_sbdv_dejpeg\">Poistaa JPEG-pakkausartefaktit ja palauttaa kuvanlaadun pakatuista valokuvista.</string>\n    <string name=\"model_iso_denoise_v1\">Vähentää ISO-kohinaa valokuvissa, jotka on otettu heikossa valaistuksessa ja säilyttää yksityiskohdat.</string>\n    <string name=\"model_dejumbo\">Korjaa ylivalottuneet tai \\\"jumbo\\\" kohokohdat ja palauttaa paremman sävytasapainon.</string>\n    <string name=\"model_ddcolor_tiny\">Kevyt ja nopea väritysmalli, joka lisää luonnollisia värejä harmaasävykuviin.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Väritä</string>\n    <string name=\"type_artifacts\">Artefaktit</string>\n    <string name=\"type_enhance\">Parantaa</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Skannaukset</string>\n    <string name=\"type_upscale\">Hyväpalkkainen</string>\n    <string name=\"model_realesrgan_x4v3\">X4-skaalaus yleiskuville; pieni malli, joka käyttää vähemmän GPU:ta ja aikaa, kohtuullisella epätarkkuudella ja kohinalla.</string>\n    <string name=\"model_realesrgan_x2plus\">X2-skaalaus yleiskuviin, pintakuvioiden ja luonnollisten yksityiskohtien säilyttämiseen.</string>\n    <string name=\"model_realesrgan_x4plus\">X4-skaalaus yleisiin kuviin parannetuilla tekstuureilla ja realistisilla tuloksilla.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4-skaalaus optimoitu animekuville; 6 RRDB-lohkoa terävämpiin linjoihin ja yksityiskohtiin.</string>\n    <string name=\"model_realesrnet_x4plus\">X4-skaalaus, jossa on MSE-häviö, tuottaa tasaisempia tuloksia ja vähentää artefakteja yleisissä kuvissa.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimoitu animekuville; 4B32F-versio, jossa on terävämmät yksityiskohdat ja sileät linjat.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 -malli yleiskuviin; korostaa terävyyttä ja selkeyttä.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; nopeampi ja pienempi, säilyttää yksityiskohdat ja käyttää vähemmän GPU-muistia.</string>\n    <string name=\"model_rmbg_1_4\">Kevyt malli nopeaan taustan poistoon. Tasapainoinen suorituskyky ja tarkkuus. Toimii muotokuvien, esineiden ja kohtausten kanssa. Suositellaan useimpiin käyttötapauksiin.</string>\n    <string name=\"type_removebg\">Poista BG</string>\n    <string name=\"horizontal_border_thickness\">Vaakasuora reunan paksuus</string>\n    <string name=\"vertical_border_thickness\">Pystysuuntaisen reunan paksuus</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s väri</item>\n        <item quantity=\"other\">%1$s väriä</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Nykyinen malli ei tue paloittelua, kuva käsitellään alkuperäisissä mitoissa, mikä voi aiheuttaa suurta muistinkulutusta ja ongelmia halvempien laitteiden kanssa</string>\n    <string name=\"chunking_disabled\">Sirpalointi poistettu käytöstä, kuva käsitellään alkuperäisissä mitoissa. Tämä voi aiheuttaa suurta muistinkulutusta ja ongelmia halvempien laitteiden kanssa, mutta voi antaa parempia tuloksia pääteltäessä</string>\n    <string name=\"chunking\">Murskaavaa</string>\n    <string name=\"model_u2net\">Erittäin tarkka kuvan segmentointimalli taustan poistamiseen</string>\n    <string name=\"model_u2netp\">U2Netin kevyt versio nopeampaan taustan poistamiseen pienemmällä muistinkäytöllä.</string>\n    <string name=\"model_ddcolor\">Full DDColor -malli tarjoaa korkealaatuisen värityksen yleisille kuville minimaalisilla artefakteilla. Paras valinta kaikista väritysmalleista.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Koulutetut ja yksityiset taiteelliset tietojoukot; tuottaa monipuolisia ja taiteellisia väritystuloksia harvemmilla epärealistisilla väriartefakteilla.</string>\n    <string name=\"model_birefnet\">Kevyt BiRefNet-malli, joka perustuu Swin Transformeriin tarkan taustan poistamiseen.</string>\n    <string name=\"model_inspyrenet\">Laadukas taustan poisto terävillä reunoilla ja erinomaisella yksityiskohdilla, erityisesti monimutkaisissa kohteissa ja hankalassa taustassa.</string>\n    <string name=\"model_isnet\">Taustanpoistomalli, joka tuottaa tarkat maskit sileillä reunoilla, sopii yleisiin esineisiin ja kohtuulliseen yksityiskohtien säilytykseen.</string>\n    <string name=\"model_already_downloaded\">Malli on jo ladattu</string>\n    <string name=\"model_successfully_imported\">Mallin tuonti onnistui</string>\n    <string name=\"type\">Tyyppi</string>\n    <string name=\"keyword\">avainsana</string>\n    <string name=\"very_fast\">Erittäin nopea</string>\n    <string name=\"normal\">Normaali</string>\n    <string name=\"slow\">Hidas</string>\n    <string name=\"very_slow\">Erittäin hidas</string>\n    <string name=\"compute_percents\">Laske prosentit</string>\n    <string name=\"minimum_value_is\">Minimiarvo on %1$s</string>\n    <string name=\"warp_sub\">Vääristä kuvaa piirtämällä sormilla</string>\n    <string name=\"warp\">Loimi</string>\n    <string name=\"hardness\">Kovuus</string>\n    <string name=\"warp_mode\">Warp-tila</string>\n    <string name=\"warp_mode_move\">Liikkua</string>\n    <string name=\"warp_mode_grow\">Kasvaa</string>\n    <string name=\"warp_mode_shrink\">Kutistua</string>\n    <string name=\"warp_mode_swirl_cw\">Pyöritä CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Pyöritä CCW</string>\n    <string name=\"fade_strength\">Häivytysvoima</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Pohjapudotus</string>\n    <string name=\"start_drop\">Käynnistä pudotus</string>\n    <string name=\"end_drop\">Lopeta pudotus</string>\n    <string name=\"downloading\">Ladataan</string>\n    <string name=\"smooth_shapes\">Sileät muodot</string>\n    <string name=\"smooth_shapes_sub\">Käytä superellipsiä tavallisten pyöristetyn suorakulmion sijaan saadaksesi pehmeämpiä ja luonnollisempia muotoja</string>\n    <string name=\"shape_type\">Muototyyppi</string>\n    <string name=\"cut\">Leikata</string>\n    <string name=\"rounded\">Pyöristetty</string>\n    <string name=\"smooth\">Sileä</string>\n    <string name=\"cut_shapes_sub\">Terävät reunat ilman pyöristystä</string>\n    <string name=\"rounded_shapes_sub\">Klassiset pyöristetyt kulmat</string>\n    <string name=\"shapes_type\">Muodot Tyyppi</string>\n    <string name=\"corners_size\">Kulmien koko</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Tyylikkäät pyöristetyt käyttöliittymäelementit</string>\n    <string name=\"filename_format\">Tiedostonimen muoto</string>\n    <string name=\"prefix_pattern_description\">Muokattu teksti sijoitetaan aivan tiedostonimen alkuun, täydellinen projektinimille, tuotemerkeille tai henkilökohtaisille tunnisteille.</string>\n    <string name=\"original_filename_pattern_description\">Käyttää alkuperäistä tiedostonimeä ilman päätettä, mikä auttaa sinua pitämään lähteen tunnisteen ennallaan.</string>\n    <string name=\"width_pattern_description\">Kuvan leveys pikseleinä, hyödyllinen tarkkuuden muutosten seurannassa tai tulosten skaalaus.</string>\n    <string name=\"height_pattern_description\">Kuvan korkeus pikseleinä, hyödyllinen kuvasuhteita tai vientiä käytettäessä.</string>\n    <string name=\"random_numbers_pattern_description\">Luo satunnaisia ​​numeroita ainutlaatuisten tiedostonimien takaamiseksi; lisää numeroita lisäturvaaksesi kaksoiskappaleita vastaan.</string>\n    <string name=\"sequence_number_pattern_description\">Automaattisesti kasvava laskuri erävientiä varten, ihanteellinen, kun tallennetaan useita kuvia yhdessä istunnossa.</string>\n    <string name=\"preset_info_pattern_description\">Lisää käytetyn esiasetuksen nimen tiedostonimeen, jotta voit helposti muistaa, kuinka kuvaa käsiteltiin.</string>\n    <string name=\"scale_mode_pattern_description\">Näyttää käsittelyn aikana käytetyn kuvan skaalaustilan, mikä auttaa erottamaan muutetut, rajatut tai sovitetut kuvat.</string>\n    <string name=\"suffix_pattern_description\">Muokattu teksti, joka on sijoitettu tiedostonimen loppuun, hyödyllinen versioinnissa, kuten _v2, _edited tai _final.</string>\n    <string name=\"extension_pattern_description\">Tiedostotunniste (png, jpg, webp jne.), joka vastaa automaattisesti todellista tallennettua muotoa.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Muokattava aikaleima, jonka avulla voit määrittää oman muotosi java-määrityksen avulla täydellisen lajittelun saavuttamiseksi.</string>\n    <string name=\"fling_type\">Fling tyyppi</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">iOS-tyyli</string>\n    <string name=\"smooth_curve\">Tasainen käyrä</string>\n    <string name=\"quick_stop\">Pikapysäytys</string>\n    <string name=\"bouncy\">Pirteä</string>\n    <string name=\"floaty\">Kelluva</string>\n    <string name=\"snappy\">Reipas</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">Mukautuva</string>\n    <string name=\"accessibility_aware\">Esteettömyystietoinen</string>\n    <string name=\"reduced_motion\">Alennettu liike</string>\n    <string name=\"android_native_sub\">Alkuperäinen Android-vieritysfysiikka vertailua varten</string>\n    <string name=\"smooth_sub\">Tasapainoinen, tasainen vieritys yleiseen käyttöön</string>\n    <string name=\"ios_style_sub\">Suurempi kitka iOS:n kaltainen vierityskäyttäytyminen</string>\n    <string name=\"smooth_curve_sub\">Ainutlaatuinen spline-käyrä antaa selkeän vieritystuntuman</string>\n    <string name=\"quick_stop_sub\">Tarkka vieritys nopealla pysäytyksellä</string>\n    <string name=\"bouncy_sub\">Leikkisä, reagoiva pomppiva rulla</string>\n    <string name=\"floaty_sub\">Pitkät, liukuvat rullat sisällön selaamiseen</string>\n    <string name=\"snappy_sub\">Nopea, reagoiva vieritys interaktiivisille käyttöliittymille</string>\n    <string name=\"ultra_smooth_sub\">Ensiluokkainen sujuva vieritys pidennetyllä vauhdilla</string>\n    <string name=\"adaptive_sub\">Säätää fysiikkaa heittonopeuden perusteella</string>\n    <string name=\"accessibility_aware_sub\">Kunnioita järjestelmän esteettömyysasetuksia</string>\n    <string name=\"reduced_motion_sub\">Minimaalinen liike esteettömyystarpeisiin</string>\n    <string name=\"primary_lines\">Ensisijaiset linjat</string>\n    <string name=\"primary_lines_sub\">Lisää paksumman viivan joka viides rivi</string>\n    <string name=\"fill_color\">Täyttöväri</string>\n    <string name=\"hidden_tools\">Piilotetut työkalut</string>\n    <string name=\"hidden_for_share\">Työkalut Piilotettu jakaa varten</string>\n    <string name=\"color_library\">Värikirjasto</string>\n    <string name=\"color_library_sub\">Selaa laajaa värivalikoimaa</string>\n    <string name=\"model_fatality_deblur\">Terävöittää ja poistaa kuvista epäterävyyden säilyttäen luonnolliset yksityiskohdat, mikä sopii erinomaisesti epätarkkojen kuvien korjaamiseen.</string>\n    <string name=\"model_unresize_v3\">Palauttaa älykkäästi kuvat, joiden kokoa on muutettu, ja palauttaa kadonneet yksityiskohdat ja tekstuurit.</string>\n    <string name=\"model_liveaction_v1_span\">Optimoitu live-action-sisällölle, vähentää pakkausartefakteja ja parantaa elokuvien/TV-ohjelmien kehysten hienoja yksityiskohtia.</string>\n    <string name=\"model_vhs2hd_realplksr\">Muuntaa VHS-laatuisen materiaalin HD:ksi, poistaa nauhakohinaa ja parantaa resoluutiota säilyttäen samalla vintage-tunnelman.</string>\n    <string name=\"model_text2hd_v1\">Erikoistunut paljon tekstiä sisältäviin kuviin ja kuvakaappauksiin, terävöittää merkkejä ja parantaa luettavuutta.</string>\n    <string name=\"model_frankendata_pretrainer\">Edistynyt skaalaus, joka on koulutettu erilaisiin tietokokonaisuuksiin, sopii erinomaisesti yleiskäyttöiseen valokuvien parantamiseen.</string>\n    <string name=\"model_realwebphoto_v2\">Optimoitu web-pakattuille valokuville, poistaa JPEG-artefaktit ja palauttaa luonnollisen ulkonäön.</string>\n    <string name=\"model_realwebphoto_v4\">Paranneltu versio verkkovalokuville paremmalla tekstuurin säilyttämisellä ja artefaktien vähentämisellä.</string>\n    <string name=\"model_dat_2x\">Kaksinkertainen skaalaus Dual Aggregation Transformer -teknologialla, säilyttää terävyyden ja luonnolliset yksityiskohdat.</string>\n    <string name=\"model_dat_3x\">3x skaalaus edistyneellä muuntajaarkkitehtuurilla, ihanteellinen kohtalaisiin laajennustarpeisiin.</string>\n    <string name=\"model_dat_4x\">4x korkealaatuinen skaalaus huippuluokan muuntajaverkolla, säilyttää hienot yksityiskohdat suuremmissa mittakaavaissa.</string>\n    <string name=\"model_nafnet_deblurring\">Poistaa kuvista epäterävyyttä/kohinaa ja tärinää. Yleiskäyttöinen, mutta paras kuvissa.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Palauttaa huonolaatuiset kuvat käyttämällä Swin2SR-muuntajaa, joka on optimoitu BSRGANin heikkenemistä varten. Erinomainen raskaiden puristusartefaktien korjaamiseen ja yksityiskohtien parantamiseen 4x mittakaavassa.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4-kertainen skaalaus SwinIR-muuntajalla, joka on koulutettu BSRGANin heikkenemiseen. Käyttää GAN-tekniikkaa terävämpiin tekstuuriin ja luonnollisempiin yksityiskohtiin valokuvissa ja monimutkaisissa kohtauksissa.</string>\n    <string name=\"path\">Polku</string>\n    <string name=\"merge_pdf\">Yhdistä PDF</string>\n    <string name=\"merge_pdf_sub\">Yhdistä useita PDF-tiedostoja yhdeksi asiakirjaksi</string>\n    <string name=\"files_order\">Tiedostojen järjestys</string>\n    <string name=\"pages_short\">s.</string>\n    <string name=\"split_pdf\">Jaa PDF</string>\n    <string name=\"split_pdf_sub\">Pura tietyt sivut PDF-dokumentista</string>\n    <string name=\"rotate_pdf\">Kierrä PDF</string>\n    <string name=\"rotate_pdf_sub\">Korjaa sivun suunta pysyvästi</string>\n    <string name=\"pages\">Sivut</string>\n    <string name=\"rearrange_pdf\">Järjestä PDF uudelleen</string>\n    <string name=\"rearrange_pdf_sub\">Järjestä sivut uudelleen vetämällä ja pudottamalla</string>\n    <string name=\"hold_drag_drop\">Pidä ja vedä sivuja</string>\n    <string name=\"page_numbers\">Sivunumerot</string>\n    <string name=\"page_numbers_sub\">Lisää numerointi asiakirjoihin automaattisesti</string>\n    <string name=\"label_format\">Label Format</string>\n    <string name=\"pdf_to_text\">PDF tekstiksi (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Pura pelkkää tekstiä PDF-dokumenteistasi</string>\n    <string name=\"watermark_pdf_sub\">Peittoteksti brändäystä tai turvallisuutta varten</string>\n    <string name=\"signature\">Allekirjoitus</string>\n    <string name=\"signature_sub\">Lisää sähköinen allekirjoituksesi mihin tahansa asiakirjaan</string>\n    <string name=\"will_be_for_signature\">Tätä käytetään allekirjoituksena</string>\n    <string name=\"unlock_pdf\">Avaa PDF</string>\n    <string name=\"unlock_pdf_sub\">Poista salasanat suojatuista tiedostoistasi</string>\n    <string name=\"protect_pdf\">Suojaa PDF</string>\n    <string name=\"protect_pdf_sub\">Suojaa asiakirjasi vahvalla salauksella</string>\n    <string name=\"success\">Menestys</string>\n    <string name=\"pdf_unlocked\">PDF avattu, voit tallentaa tai jakaa sen</string>\n    <string name=\"repair_pdf\">Korjaa PDF</string>\n    <string name=\"repair_pdf_sub\">Yritä korjata vioittuneet tai lukukelvottomat asiakirjat</string>\n    <string name=\"grayscale\">Harmaasävy</string>\n    <string name=\"grayscale_pdf_sub\">Muunna kaikki asiakirjan upotetut kuvat harmaasävyiksi</string>\n    <string name=\"compress_pdf\">Pakkaa PDF</string>\n    <string name=\"compress_pdf_sub\">Optimoi asiakirjatiedoston koko helpottamaan jakamista</string>\n    <string name=\"repair_info\">ImageToolbox rakentaa sisäisen ristiviittaustaulukon uudelleen ja luo tiedostorakenteen uudelleen tyhjästä. Tämä voi palauttaa pääsyn moniin tiedostoihin, joita \\\\\"ei voi avata\\\\\"</string>\n    <string name=\"grayscale_info\">Tämä työkalu muuntaa kaikki asiakirjan kuvat harmaasävyiksi. Paras tulostukseen ja tiedostokoon pienentämiseen</string>\n    <string name=\"metadata\">Metatiedot</string>\n    <string name=\"metadata_pdf_sub\">Muokkaa asiakirjan ominaisuuksia parantaaksesi yksityisyyttä</string>\n    <string name=\"tags\">Tunnisteet</string>\n    <string name=\"producer\">Tuottaja</string>\n    <string name=\"author\">Tekijä</string>\n    <string name=\"keywords\">Avainsanat</string>\n    <string name=\"creator\">Luoja</string>\n    <string name=\"privacy_deep_clean\">Yksityisyys syväpuhdistus</string>\n    <string name=\"privacy_deep_clean_sub\">Tyhjennä kaikki tämän asiakirjan saatavilla olevat metatiedot</string>\n    <string name=\"page\">Sivu</string>\n    <string name=\"deep_ocr\">Syvä OCR</string>\n    <string name=\"deep_ocr_sub\">Pura teksti asiakirjasta ja tallenna se yhteen tekstitiedostoon Tesseract-moottorilla</string>\n    <string name=\"cant_remove_all\">Kaikkia sivuja ei voi poistaa</string>\n    <string name=\"remove_pages_pdf\">Poista PDF-sivut</string>\n    <string name=\"remove_pages_pdf_sub\">Poista tietyt sivut PDF-dokumentista</string>\n    <string name=\"tap_to_remove\">Poista napauttamalla</string>\n    <string name=\"manually\">Käsin</string>\n    <string name=\"crop_pdf\">Rajaa PDF</string>\n    <string name=\"crop_pdf_sub\">Rajaa asiakirjan sivut mihin tahansa reunaan</string>\n    <string name=\"flatten_pdf\">Litistä PDF</string>\n    <string name=\"flatten_pdf_sub\">Tee PDF-tiedostosta muokkaamaton rasteroimalla asiakirjan sivut</string>\n    <string name=\"camera_failed_to_open\">Kameraa ei voitu käynnistää. Tarkista käyttöoikeudet ja varmista, että toinen sovellus ei käytä sitä.</string>\n    <string name=\"extract_images\">Pura kuvat</string>\n    <string name=\"extract_images_sub\">Pura PDF-tiedostoihin upotetut kuvat alkuperäisellä tarkkuudellaan</string>\n    <string name=\"pdf_no_embedded\">Tämä PDF-tiedosto ei sisällä upotettuja kuvia</string>\n    <string name=\"extract_images_info\">Tämä työkalu skannaa jokaisen sivun ja palauttaa täysilaatuiset lähdekuvat – täydellinen alkuperäisten tallentamiseen asiakirjoista</string>\n    <string name=\"draw_signature\">Piirrä allekirjoitus</string>\n    <string name=\"pen_params\">Kynäparametrit</string>\n    <string name=\"draw_signature_sub\">Käytä omaa allekirjoitusta kuvana lisättäväksi asiakirjoihin</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Jaa asiakirja tietyllä aikavälillä ja pakkaa uudet asiakirjat zip-arkistoon</string>\n    <string name=\"interval\">Intervalli</string>\n    <string name=\"print_pdf\">Tulosta PDF</string>\n    <string name=\"print_pdf_sub\">Valmistele asiakirja tulostusta varten mukautetulla sivukoolla</string>\n    <string name=\"pages_per_sheet\">Sivuja per arkki</string>\n    <string name=\"orientation\">Suuntautuminen</string>\n    <string name=\"page_size\">Sivun koko</string>\n    <string name=\"margin\">Marginaali</string>\n    <string name=\"bloom\">Kukinta</string>\n    <string name=\"soft_knee\">Pehmeä polvi</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimoitu animeille ja sarjakuville. Nopea skaalaus parannetuilla luonnollisilla väreillä ja vähemmillä esineillä</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7:n kaltainen tyyli</string>\n    <string name=\"calculate_hint\">Syötä tähän matemaattiset perussymbolit halutun arvon laskemiseksi (esim. (5+5)*10)</string>\n    <string name=\"math_expression\">Matemaattinen ilmaus</string>\n    <string name=\"pick_up_to_n_collage_images\">Poimi jopa %1$s kuvaa</string>\n    <string name=\"keep_date_time\">Pidä päivämäärä ja aika</string>\n    <string name=\"keep_date_time_sub\">Säilytä aina päivämäärään ja kellonaikaan liittyvät exif-tunnisteet, toimii riippumatta Keep exif -vaihtoehdosta</string>\n    <string name=\"background_color_for_alpha_formats\">Taustaväri Alfa-formaateille</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Lisää mahdollisuuden asettaa taustavärin jokaiselle kuvamuodolle alfa-tuella, kun tämä ei ole käytössä, tämä on käytettävissä vain muille kuin alfa-muodoille</string>\n    <string name=\"open_markup_project\">Avoin projekti</string>\n    <string name=\"open_markup_project_sub\">Jatka aiemmin tallennetun Image Toolbox -projektin muokkaamista</string>\n    <string name=\"markup_project_open_failed\">Image Toolbox -projektia ei voi avata</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox -projektista puuttuu projektitiedot</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox -projekti on vioittunut</string>\n    <string name=\"unsupported_markup_project_version\">Ei tuettu Image Toolbox -projektin versio: %1$d</string>\n    <string name=\"save_markup_project\">Tallenna projekti</string>\n    <string name=\"save_markup_project_sub\">Tallenna tasot, tausta ja muokkaushistoria muokattavaan projektitiedostoon</string>\n    <string name=\"failed_to_open\">Avaaminen epäonnistui</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Kirjoita haettavaan PDF-tiedostoon</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Tunnista teksti kuvaerästä ja tallenna haettavissa oleva PDF kuvan ja valittavan tekstikerroksen kanssa</string>\n    <string name=\"layer_alpha\">Kerros alfa</string>\n    <string name=\"horizontal_flip\">Vaakasuora kääntö</string>\n    <string name=\"vertical_flip\">Pystysuora kääntö</string>\n    <string name=\"lock\">Lukko</string>\n    <string name=\"add_shadow\">Lisää varjo</string>\n    <string name=\"shadow_color\">Varjon väri</string>\n    <string name=\"text_geometry\">Tekstin geometria</string>\n    <string name=\"text_geometry_sub\">Venytä tai vino tekstiä terävämmän tyylin saamiseksi</string>\n    <string name=\"scale_x\">Mittakaava X</string>\n    <string name=\"skew_x\">Vino X</string>\n    <string name=\"remove_annotations\">Poista merkinnät</string>\n    <string name=\"remove_annotations_sub\">Poista valitut merkintätyypit, kuten linkit, kommentit, korostukset, muodot tai lomakekentät PDF-sivuilta</string>\n    <string name=\"annotation_link\">Hyperlinkit</string>\n    <string name=\"annotation_file_attachment\">Tiedoston liitteet</string>\n    <string name=\"annotation_line\">Linjat</string>\n    <string name=\"annotation_popup\">Ponnahdusikkunat</string>\n    <string name=\"annotation_stamp\">Postimerkit</string>\n    <string name=\"annotation_shapes\">Muodot</string>\n    <string name=\"annotation_text\">Teksti Huomautuksia</string>\n    <string name=\"annotation_text_markup\">Tekstin merkintä</string>\n    <string name=\"annotation_widget\">Lomakekentät</string>\n    <string name=\"annotation_markup\">Merkintä</string>\n    <string name=\"annotation_unknown\">Tuntematon</string>\n    <string name=\"annotations\">Huomautukset</string>\n    <string name=\"ungroup\">Pura ryhmittely</string>\n    <string name=\"add_shadow_sub\">Lisää sumea varjo tason taakse konfiguroitavilla väreillä ja poikkeamilla</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-fil/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"size\">Laki %1$s</string>\n    <string name=\"loading\">Ikinakarga…</string>\n    <string name=\"pick_image\">Pumili ng larawan para magsimula</string>\n    <string name=\"width\">Lapad %1$s</string>\n    <string name=\"height\">Taas %1$s</string>\n    <string name=\"quality\">Kalidad</string>\n    <string name=\"extension\">Ekstensyon</string>\n    <string name=\"resize_type\">Uri ng pag-resize</string>\n    <string name=\"explicit\">Tahasan</string>\n    <string name=\"flexible\">Flexible</string>\n    <string name=\"pick_image_alt\">Pumili ng Larawan</string>\n    <string name=\"stay\">Manatili</string>\n    <string name=\"app_closing\">Pag-alis sa app</string>\n    <string name=\"close\">Umalis</string>\n    <string name=\"reset_image\">I-reset ang larawan</string>\n    <string name=\"reset_image_sub\">Ibabalik sa dati ang larawan at mawawala lahat ng mga pagbabago</string>\n    <string name=\"values_reset\">Matagumpay na na-reset ang mga value</string>\n    <string name=\"reset\">I-reset</string>\n    <string name=\"something_went_wrong\">Nagkaproblema</string>\n    <string name=\"restart_app\">I-restart ang app</string>\n    <string name=\"copied\">Nakopya sa clipboard</string>\n    <string name=\"exception\">Pagbubukod</string>\n    <string name=\"edit_exif\">Baguhin ang EXIF</string>\n    <string name=\"ok\">Sige</string>\n    <string name=\"add_tag\">Magdagdag ng tag</string>\n    <string name=\"smth_went_wrong\">Nagkaproblema: %1$s</string>\n    <string name=\"image_too_large_preview\">Masyadong malaki ang larawan para maipasilip, pero susubukan pa rin itong i-save</string>\n    <string name=\"app_closing_sub\">Sigurado ka bang gusto mong umalis sa app?</string>\n    <string name=\"no_exif\">Walang nakitang EXIF na datos</string>\n    <string name=\"save\">I-save</string>\n    <string name=\"cancel\">Kanselahin</string>\n    <string name=\"clear\">Burahin</string>\n    <string name=\"clear_exif\">Burahin ang EXIF</string>\n    <string name=\"clear_exif_sub\">Mawawala ang lahat ng EXIF na datos sa larawan, wala nang bawian!</string>\n    <string name=\"presets\">Mga Preset</string>\n    <string name=\"crop\">Putulan</string>\n    <string name=\"image_not_saved\">Pagse-save</string>\n    <string name=\"image_not_saved_sub\">Mawawala ang lahat ng mga pagbabagong hindi pa nase-save kung aalis ka</string>\n    <string name=\"check_source_code\">Source code</string>\n    <string name=\"check_source_code_sub\">Kunin ang pinakabagong update, pag-usapan ang mga isyu, atbp.</string>\n    <string name=\"single_edit\">Isahang pag-resize</string>\n    <string name=\"single_edit_sub\">Baguhin ang laki ng isang larawan</string>\n    <string name=\"pick_color\">Pumili ng kulay</string>\n    <string name=\"pick_color_sub\">Pumili ng kulay mula sa larawan, kopyahin o ibahagi</string>\n    <string name=\"image\">Larawan</string>\n    <string name=\"color\">Kulay</string>\n    <string name=\"color_copied\">Kinopya ang kulay</string>\n    <string name=\"crop_sub\">Putulan ang larawan sa anumang laki</string>\n    <string name=\"version\">Bersyon</string>\n    <string name=\"keep_exif\">Panatilihin ang EXIF</string>\n    <string name=\"images\">Mga larawan: %d</string>\n    <string name=\"change_preview\">Baguhin ang pasilip</string>\n    <string name=\"remove\">Tanggalin</string>\n    <string name=\"palette_sub\">Gumawa ng palette ng kulay mula sa napiling larawan</string>\n    <string name=\"generate_palette\">Gumawa ng palette</string>\n    <string name=\"palette\">Palette</string>\n    <string name=\"update\">Update</string>\n    <string name=\"new_version\">Bagong bersyon %1$s</string>\n    <string name=\"unsupported_type\">\\'Di-suportadong uri: %1$s</string>\n    <string name=\"no_palette\">Hindi makagawa ng palette mula sa napiling larawan</string>\n    <string name=\"original\">Orihinal</string>\n    <string name=\"folder\">Folder para sa mga output</string>\n    <string name=\"def\">Default</string>\n    <string name=\"custom\">Pasadya</string>\n    <string name=\"unspecified\">Hindi naitakda</string>\n    <string name=\"device_storage\">Storage ng device</string>\n    <string name=\"by_bytes_resize\">I-resize ayon sa bigat</string>\n    <string name=\"max_bytes\">Pinakamabigat sa KB</string>\n    <string name=\"by_bytes_resize_sub\">Mag-resize ng larawan ayon sa ibinigay na bigat sa KB</string>\n    <string name=\"compare\">Magkumpara</string>\n    <string name=\"pick_images\">Pumili ng mga larawan</string>\n    <string name=\"compare_sub\">Magkumpara ng dalawang larawan</string>\n    <string name=\"pick_two_images\">Pumili ng dalawang larawan para magsimula</string>\n    <string name=\"settings\">Mga Setting</string>\n    <string name=\"night_mode\">Mode panggabi</string>\n    <string name=\"dark\">Madilim</string>\n    <string name=\"light\">Maliwanag</string>\n    <string name=\"system\">Sistema</string>\n    <string name=\"allow_image_monet\">Payagan ang monet sa larawan</string>\n    <string name=\"language\">Wika</string>\n    <string name=\"customization\">Pagpapasadya</string>\n    <string name=\"dynamic_colors\">Dynamikong kulay</string>\n    <string name=\"allow_image_monet_sub\">Kung bubuksan, aangkop ang mga kulay ng app sa larawang nakabukas</string>\n    <string name=\"amoled_mode\">Amoled mode</string>\n    <string name=\"amoled_mode_sub\">Kung bubuksan, magiging napakadilim ang kulay ng mga surface sa mode panggabi</string>\n    <string name=\"color_red\">Pula</string>\n    <string name=\"color_green\">Berde</string>\n    <string name=\"color_blue\">Asul</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Mag-paste ng wastong aRGB-Code.</string>\n    <string name=\"color_scheme\">Eskema ng kulay</string>\n    <string name=\"clipboard_paste_invalid_empty\">Walang maipe-paste</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Hindi mababago ang eskema ng kulay ng app habang gumagamit ng dynamikong kulay</string>\n    <string name=\"pick_accent_color\">Ibabatay sa kulay na pipiliin mo ang tema ng app</string>\n    <string name=\"about_app\">Tungkol sa app</string>\n    <string name=\"no_updates\">Walang nakitang update</string>\n    <string name=\"issue_tracker\">Tagasubaybay sa mga problema</string>\n    <string name=\"issue_tracker_sub\">Magpadala rito ng mga ulat sa problema at kahilingan para sa mga feature</string>\n    <string name=\"help_translate\">Tumulong sa pagsasalin</string>\n    <string name=\"search_here\">Maghanap dito</string>\n    <string name=\"help_translate_sub\">Ayusin ang mga pagkakamali sa pagsasalin o isalin ang proyekto sa iba pang wika</string>\n    <string name=\"nothing_found_by_search\">Walang nakitang tugma sa query mo</string>\n    <string name=\"dynamic_colors_sub\">Kung nakabukas, aangkop ang kulay ng app sa kulay ng wallpaper</string>\n    <string name=\"failed_to_save\">Nagkaproblema sa pag-save ng %d larawan</string>\n    <string name=\"primary\">Pangunahin</string>\n    <string name=\"tertiary\">Tersiyaryo</string>\n    <string name=\"secondary\">Sekondaryo</string>\n    <string name=\"border_thickness\">Kapal ng gilid</string>\n    <string name=\"surface\">Ibabaw</string>\n    <string name=\"donation_sub\">Libre ang app na ito, pero pindutin ito kung gusto mong suportahan ang development ng proyekto</string>\n    <string name=\"permission_sub\">Kailangan ng app ng access sa storage mo para mag-save ng mga larawan, kaya mangyaring ibigay ang pahintulot sa ipapakitang diyalogo</string>\n    <string name=\"fab_alignment\">Pagpapantay ng FAB</string>\n    <string name=\"check_updates\">Tingnan kung may update</string>\n    <string name=\"check_updates_sub\">Kung nakabukas, magpapakita ng diyalogo sa update pagkabukas ng app</string>\n    <string name=\"values\">Mga halaga</string>\n    <string name=\"add\">Idagdag</string>\n    <string name=\"permission\">Pahintulot</string>\n    <string name=\"grant\">Grant</string>\n    <string name=\"zoom\">Pag-zoom ng larawan</string>\n    <string name=\"prefix\">Unlapi</string>\n    <string name=\"filename\">Pangalan ng file</string>\n    <string name=\"grant_permission_manual\">Kailangan ng app ang pahintulot na ito para gumana, kaya mangyaring manu-manong ibigay ang pahintulot na ito</string>\n    <string name=\"share\">Ibahagi</string>\n    <string name=\"external_storage\">Eksternal na storage</string>\n    <string name=\"monet_colors\">Mga kulay ng monet</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Piliin kung aling emoji ang ipapakita sa pangunahing screen</string>\n    <string name=\"add_file_size\">Ilagay ang laki ng file</string>\n    <string name=\"add_file_size_sub\">Kung nakabukas, ilalagay sa pangalan ng output file ang lapad at taas ng na-save na larawan</string>\n    <string name=\"delete_exif\">Magtanggal ng EXIF</string>\n    <string name=\"delete_exif_sub\">Magtanggal ng EXIF metadata sa anumang pares ng larawan</string>\n    <string name=\"image_preview\">Pasilip sa larawan</string>\n    <string name=\"image_preview_sub\">I-preview ang anumang uri ng mga larawana: GIF, SVG, at iba pa</string>\n    <string name=\"image_source\">Pinagmulan ng larawan</string>\n    <string name=\"photo_picker\">Tagapili ng larawan</string>\n    <string name=\"gallery_picker\">Gallery</string>\n    <string name=\"gallery_picker_sub\">Simpleng tagapili ng larawan ng gallery, gagana lamang ito kung mayroon kang app na iyon</string>\n    <string name=\"file_explorer_picker_sub\">Gamitin ang layunin ng GetContent upang pumili ng larawan, gumagana sa lahat ng dako, ngunit maaari ding magkaroon ng mga isyu sa pagtanggap ng mga pciked na larawan sa ilang device, hindi ko iyon kasalanan</string>\n    <string name=\"options_arrangement\">Pag-aayos ng mga pagpipilian</string>\n    <string name=\"edit\">I-edit</string>\n    <string name=\"order\">Umorder</string>\n    <string name=\"emojis_count\">Bilang ng mga emoji</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">orihinal na pangalan ng file</string>\n    <string name=\"add_original_filename\">Magdagdag ng orihinal na filename</string>\n    <string name=\"add_original_filename_sub\">Kung pinagana ay nagdaragdag ng orihinal na filename sa pangalan ng output na imahe</string>\n    <string name=\"file_explorer_picker\">File explorer</string>\n    <string name=\"photo_picker_sub\">Android modernong photo picker na lumalabas sa ibaba ng screen, ay maaaring gumana lamang sa adnroid 12+ at mayroon ding mga isyu sa pagtanggap ng EXIF metadata</string>\n    <string name=\"order_sub\">Tinutukoy ang pagkakasunud-sunod ng mga opsyon sa pangunahing screen</string>\n    <string name=\"filename_not_work_with_photopicker\">Hindi gagana ang pagdaragdag ng orihinal na filename kung napili ang source ng larawan ng photopicker</string>\n    <string name=\"flexible_description\">Binabago ang laki ng mga larawan sa mga larawang may mahabang gilid na ibinigay ng Width o Height na parameter, lahat ng laki ng pagkalkula ay gagawin pagkatapos i-save - pinapanatili ang aspect ratio</string>\n    <string name=\"haze\">Ulap</string>\n    <string name=\"effect\">Epekto</string>\n    <string name=\"distance\">Distansya</string>\n    <string name=\"slope\">Slope</string>\n    <string name=\"solarize\">Mag-solarize</string>\n    <string name=\"vibrance\">Vibrance</string>\n    <string name=\"blur\">Malabo</string>\n    <string name=\"halftone\">Halftone</string>\n    <string name=\"scale\">Iskala</string>\n    <string name=\"radius\">Radius</string>\n    <string name=\"swirl\">Umikot</string>\n    <string name=\"replace_sequence_number\">Palitan ang sequence number</string>\n    <string name=\"brightness\">Liwanag</string>\n    <string name=\"hue\">Hue</string>\n    <string name=\"start\">Magsimula</string>\n    <string name=\"limits_resize\">Mga limitasyon sa pagbabago ng laki</string>\n    <string name=\"limits_resize_sub\">Baguhin ang laki ng mga ibinigay na larawan upang sundin ang ibinigay na mga limitasyon sa lapad at taas na may pag-save ng aspect ratio</string>\n    <string name=\"sketch\">Sketch</string>\n    <string name=\"threshold\">Threshold</string>\n    <string name=\"non_maximum_suppression\">Hindi maximum na pagsugpo</string>\n    <string name=\"stack_blur\">Stack blur</string>\n    <string name=\"convolution3x3\">Convolution 3x3</string>\n    <string name=\"rgb_filter\">RGB filter</string>\n    <string name=\"false_color\">Maling kulay</string>\n    <string name=\"first_color\">Unang kulay</string>\n    <string name=\"luminance_threshold\">Luminance threshold</string>\n    <string name=\"replace_sequence_number_sub\">Kung pinagana, papalitan ang strandard timestamp sa numero ng pagkakasunud-sunod ng imahe kung gumagamit ka ng batch processing</string>\n    <string name=\"load_image_from_net\">Mag-load ng larawan mula sa net</string>\n    <string name=\"image_link\">Link ng larawan</string>\n    <string name=\"fill\">Punan</string>\n    <string name=\"explicit_description\">Pinipilit ang bawat larawan sa isang imahe na ibinigay ng parameter na Lapad at Taas - maaaring magbago ng aspect ratio</string>\n    <string name=\"contrast\">Contrast</string>\n    <string name=\"saturation\">Saturation</string>\n    <string name=\"add_filter\">Magdagdag ng filter</string>\n    <string name=\"filter\">Salain</string>\n    <string name=\"filter_sub\">Ilapat ang anumang chain ng filter sa mga ibinigay na larawan</string>\n    <string name=\"filters\">Mga filter</string>\n    <string name=\"light_aka_illumination\">Maliwanag</string>\n    <string name=\"color_filter\">Filter ng kulay</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"exposure\">Pagkalantad</string>\n    <string name=\"white_balance\">puting balanse</string>\n    <string name=\"temperature\">Temperatura</string>\n    <string name=\"tint\">Tint</string>\n    <string name=\"monochrome\">Monochrome</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Mga highlight at anino</string>\n    <string name=\"highlights\">Mga highlight</string>\n    <string name=\"shadows\">Mga anino</string>\n    <string name=\"sharpen\">Patalasin</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negatibo</string>\n    <string name=\"black_and_white\">Itim at puti</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">Spacing</string>\n    <string name=\"line_width\">Lapad ng linya</string>\n    <string name=\"sobel_edge\">Sobel gilid</string>\n    <string name=\"cga_colorspace\">colorspace ng GCA</string>\n    <string name=\"gaussian_blur\">Gaussian blur</string>\n    <string name=\"box_blur\">Malabo ang kahon</string>\n    <string name=\"bilaterial_blur\">Bilateral blur</string>\n    <string name=\"emboss\">Emboss</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Vignette</string>\n    <string name=\"end\">Tapusin</string>\n    <string name=\"kuwahara\">Kuwahara smoothing</string>\n    <string name=\"distortion\">pagbaluktot</string>\n    <string name=\"angle\">anggulo</string>\n    <string name=\"bulge\">Umbok</string>\n    <string name=\"dilation\">Pagluwang</string>\n    <string name=\"sphere_refraction\">Sphere repraksyon</string>\n    <string name=\"refractive_index\">Repraktibo index</string>\n    <string name=\"glass_sphere_refraction\">Glass sphere repraksyon</string>\n    <string name=\"color_matrix\">Kulay matrix</string>\n    <string name=\"opacity\">Opacity</string>\n    <string name=\"quantizationLevels\">Mga antas ng quantization</string>\n    <string name=\"smooth_toon\">Smooth toon</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterize</string>\n    <string name=\"weak_pixel_inclusion\">Mahinang pagsasama ng pixel</string>\n    <string name=\"lookup\">Paghahanap</string>\n    <string name=\"second_color\">Pangalawang kulay</string>\n    <string name=\"reorder\">Muling ayusin</string>\n    <string name=\"fast_blur\">Mabilis na lumabo</string>\n    <string name=\"blur_size\">Laki ng blur</string>\n    <string name=\"blur_center_x\">Palabuin ang gitna x</string>\n    <string name=\"blur_center_y\">Palabuin ang gitna y</string>\n    <string name=\"zoom_blur\">Mag-zoom blur</string>\n    <string name=\"color_balance\">Balanse ng kulay</string>\n    <string name=\"load_image_from_net_sub\">Mag-load ng anumang larawan sa internet, i-preview ito, i-zoom, at i-save o i-edit din ito kung gusto mo</string>\n    <string name=\"no_image\">Walang larawan</string>\n    <string name=\"fit\">Angkop</string>\n    <string name=\"content_scale\">Sukat ng nilalaman</string>\n    <string name=\"skip\">Laktawan</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Laki ng cache</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Hindi maaaring baguhin ang kaayusan habang naka-enable ang pagpapangkat ng opsyon</string>\n    <string name=\"create\">Lumikha</string>\n    <string name=\"edit_screenshot\">I-edit ang screenshot</string>\n    <string name=\"fallback_option\">Fallback na opsyon</string>\n    <string name=\"activate_files\">Hindi mo pinagana ang Files app, i-activate ito para magamit ang feature na ito</string>\n    <string name=\"draw_sub\">Gumuhit sa larawan tulad ng sa isang sketchbook, o gumuhit sa background mismo</string>\n    <string name=\"paint_color\">Kulay ng pintura</string>\n    <string name=\"draw_on_image\">Gumuhit sa larawan</string>\n    <string name=\"draw_on_image_sub\">Pumili ng isang imahe at gumuhit ng isang bagay dito</string>\n    <string name=\"background_color\">Kulay ng background</string>\n    <string name=\"store_file_desc\">I-store ang file na ito sa iyong device o gumamit ng share action para ilagay ito kahit saan mo gusto</string>\n    <string name=\"features\">Mga tampok</string>\n    <string name=\"compatibility_sub\">Pakitandaan na ang pagiging tugma sa ibang file encryption software o mga serbisyo ay hindi ginagarantiyahan. Ang bahagyang naiibang key treatment o cipher configuration ay maaaring mga dahilan ng hindi pagkakatugma.</string>\n    <string name=\"warning_bytes\">Ang pag-save sa %1$s mode ay maaaring hindi matatag, dahil ito ay lossless na format</string>\n    <string name=\"paint_alpha\">Kulayan ang alpha</string>\n    <string name=\"secondary_customization\">Pangalawang pagpapasadya</string>\n    <string name=\"compatibility\">Pagkakatugma</string>\n    <string name=\"screenshot\">Screenshot</string>\n    <string name=\"copy\">Kopya</string>\n    <string name=\"tools\">Mga gamit</string>\n    <string name=\"implementation\">Pagpapatupad</string>\n    <string name=\"draw\">Gumuhit</string>\n    <string name=\"found_s\">Natagpuan %1$s</string>\n    <string name=\"auto_cache_clearing\">Auto cache clearing</string>\n    <string name=\"auto_cache_clearing_sub\">Kung pinagana ang cache ng app ay iki-clear sa pagsisimula ng app</string>\n    <string name=\"group_options_by_type\">Mga opsyon sa pangkat ayon sa uri</string>\n    <string name=\"group_options_by_type_sub\">Mga opsyon sa pangkat sa pangunahing screen ng kanilang uri sa halip na pasadyang pag-aayos ng listahan</string>\n    <string name=\"draw_on_background\">Gumuhit sa background</string>\n    <string name=\"draw_on_background_sub\">Pumili ng kulay ng background at gumuhit sa ibabaw nito</string>\n    <string name=\"pick_file\">Pumili ng file</string>\n    <string name=\"encrypt\">I-encrypt</string>\n    <string name=\"decrypt\">I-decrypt</string>\n    <string name=\"key\">Susi</string>\n    <string name=\"file_size_sub\">Ang maximum na laki ng file ay pinaghihigpitan ng Android OS at ang memorya na magagamit, na halatang nakadepende sa iyong device. \\nMangyaring tandaan: ang memorya ay hindi imbakan.</string>\n    <string name=\"cipher\">Cipher</string>\n    <string name=\"cipher_sub\">I-encrypt at I-decrypt ang anumang file (hindi lamang ang imahe) batay sa AES crypto algorithm</string>\n    <string name=\"pick_file_to_start\">Pumili ng file upang magsimula</string>\n    <string name=\"decryption\">Pag-decryption</string>\n    <string name=\"encryption\">Pag-encrypt</string>\n    <string name=\"implementation_sub\">AES-256, GCM mode, walang padding, 12 bytes na random na IVs. Ang mga susi ay ginagamit bilang SHA-3 hash (256 bits).</string>\n    <string name=\"file_size\">Laki ng file</string>\n    <string name=\"features_sub\">Nakabatay sa password ang pag-encrypt ng mga file. Ang mga naituloy na file ay maaaring iimbak sa napiling direktoryo o ibinahagi. Ang mga decrypted na file ay maaari ding direktang mabuksan.</string>\n    <string name=\"image_size_warning\">Ang pagsisikap na i-save ang imahe na may ibinigay na lapad at taas ay maaaring magdulot ng isang error sa OOM, gawin ito sa iyong sariling peligro, at huwag sabihing hindi kita binalaan!</string>\n    <string name=\"file_proceed\">Naproseso ang file</string>\n    <string name=\"invalid_password_or_not_encrypted\">Ang di-wastong password o napiling file ay hindi naka-encrypt</string>\n    <string name=\"circle_pixelation\">Circle Pixelation</string>\n    <string name=\"enhanced_circle_pixelation\">Pinahusay na Circle Pixelation</string>\n    <string name=\"replace_color\">Palitan ang Kulay</string>\n    <string name=\"tolerance\">Pagpaparaya</string>\n    <string name=\"email\">Email</string>\n    <string name=\"tg_chat\">Telegram chat</string>\n    <string name=\"enhanced_glitch\">Pinahusay na Glitch</string>\n    <string name=\"channel_shift_x\">Channel Shift X</string>\n    <string name=\"top\">Nangunguna</string>\n    <string name=\"bottom\">Ibaba</string>\n    <string name=\"strength\">Lakas</string>\n    <string name=\"restore\">Ibalik</string>\n    <string name=\"tg_chat_sub\">Talakayin ang app at makakuha ng feedback mula sa ibang mga user. Maaari ka ring makakuha ng mga beta update at insight dito.</string>\n    <string name=\"erase_background\">Burahin ang background</string>\n    <string name=\"saved_to_without_filename\">Nai-save sa %1$s folder</string>\n    <string name=\"backup_and_restore\">I-backup at i-restore</string>\n    <string name=\"auto_erase_background\">Awtomatikong burahin ang background</string>\n    <string name=\"emotions\">Mga emosyon</string>\n    <string name=\"saved_to\">Nai-save sa %1$s folder na may pangalang %2$s</string>\n    <string name=\"defaultt\">Default</string>\n    <string name=\"keep_exif_sub\">Pananatilihin ang orihinal na metadata ng larawan</string>\n    <string name=\"donation\">Donasyon</string>\n    <string name=\"restore_sub\">Ibalik ang mga setting ng app mula sa dati nang nabuong file</string>\n    <string name=\"segmentation_mode_osd_only\">Oryentasyon &amp; Script Detection lamang</string>\n    <string name=\"segmentation_mode_single_line\">Isang linya</string>\n    <string name=\"segmentation_mode_raw_line\">Hilaw na linya</string>\n    <string name=\"glitch\">Glitch</string>\n    <string name=\"amount\">Halaga</string>\n    <string name=\"seed\">Binhi</string>\n    <string name=\"anaglyph\">Anaglyph</string>\n    <string name=\"noise\">ingay</string>\n    <string name=\"pixel_sort\">Pag-uuri ng Pixel</string>\n    <string name=\"delete_mask_warn\">Ide-delete mo na ang napiling filter mask. Hindi maa-undo ang operasyong ito</string>\n    <string name=\"delete_mask\">Tanggalin ang Mask</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Putulin</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Transisyon</string>\n    <string name=\"peak\">Tuktok</string>\n    <string name=\"color_anomaly\">Anomalya ng Kulay</string>\n    <string name=\"no_such_directory\">Walang nakitang direktoryo ng \\\"%1$s\\\", inilipat namin ito sa default, paki-save muli ang file</string>\n    <string name=\"clipboard\">Clipboard</string>\n    <string name=\"auto_pin\">Auto pin</string>\n    <string name=\"auto_pin_sub\">Awtomatikong nagdaragdag ng naka-save na larawan sa clipboard kung pinagana</string>\n    <string name=\"vibration\">Panginginig ng boses</string>\n    <string name=\"vibration_strength\">Lakas ng Vibration</string>\n    <string name=\"overwrite_files\">I-overwrite ang mga File</string>\n    <string name=\"empty\">Walang laman</string>\n    <string name=\"suffix\">Suffix</string>\n    <string name=\"free\">Libre</string>\n    <string name=\"images_overwritten\">Mga larawang na-overwrite sa orihinal na destinasyon</string>\n    <string name=\"emoji_as_color_scheme_sub\">Gumagamit ng pangunahing kulay ng emoji bilang scheme ng kulay ng app sa halip na manu-manong tinukoy</string>\n    <string name=\"presets_sub\" formatted=\"false\">Kung pinili mo ang preset na 125, ang imahe ay ise-save bilang 125% na laki ng orihinal na imahe na may 100% na kalidad. Kung pipiliin mo ang preset na 50, mase-save ang larawan na may 50% na laki at 50% na kalidad.</string>\n    <string name=\"presets_sub_bytes\">Tinutukoy ng preset dito ang % ng output file, ibig sabihin, kung pipiliin mo ang preset na 50 sa 5mb na imahe pagkatapos ay makakakuha ka ng 2.5mb na imahe pagkatapos i-save</string>\n    <string name=\"image_crop_mask_sub\">Gamitin ang uri ng mask na ito upang lumikha ng mask mula sa ibinigay na larawan, pansinin na DAPAT itong magkaroon ng alpha channel</string>\n    <string name=\"backup\">Backup</string>\n    <string name=\"backup_sub\">I-backup ang iyong mga setting ng app sa isang file</string>\n    <string name=\"settings_restored\">Matagumpay na naibalik ang mga setting</string>\n    <string name=\"contact_me\">Tawagan mo ako</string>\n    <string name=\"delete_color_scheme_title\">Tanggalin ang Scheme</string>\n    <string name=\"font\">Font</string>\n    <string name=\"text\">Text</string>\n    <string name=\"font_scale\">Sukat ng font</string>\n    <string name=\"using_large_fonts_warn\">Ang paggamit ng malalaking font scale ay maaaring magdulot ng mga aberya at problema sa UI, na hindi maaayos. Gamitin nang maingat.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Ññ Ngng Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"food_and_drink\">Pagkain at Inumin</string>\n    <string name=\"nature_and_animals\">Kalikasan at Hayop</string>\n    <string name=\"objects\">Mga bagay</string>\n    <string name=\"symbols\">Mga simbolo</string>\n    <string name=\"enable_emoji\">Paganahin ang emoji</string>\n    <string name=\"travels_and_places\">Mga Paglalakbay at Lugar</string>\n    <string name=\"activities\">Mga aktibidad</string>\n    <string name=\"background_remover\">Pantanggal ng background</string>\n    <string name=\"background_remover_sub\">Alisin ang background mula sa larawan sa pamamagitan ng pagguhit o paggamit ng Auto na opsyon</string>\n    <string name=\"trim_image\">I-trim ang larawan</string>\n    <string name=\"trim_image_sub\">Ang mga trasparent na puwang sa paligid ng larawan ay pupugutan</string>\n    <string name=\"restore_image\">Ibalik ang imahe</string>\n    <string name=\"erase_mode\">Erase mode</string>\n    <string name=\"restore_background\">Ibalik ang background</string>\n    <string name=\"blur_radius\">Blur radius</string>\n    <string name=\"draw_mode\">Draw mode</string>\n    <string name=\"create_issue\">Gumawa ng Isyu</string>\n    <string name=\"something_went_wrong_emphasis\">Ooops… Nagkaproblema. Maaari kang sumulat sa akin gamit ang mga opsyon sa ibaba at susubukan kong maghanap ng solusyon</string>\n    <string name=\"resize_and_convert\">Baguhin ang laki at I-convert</string>\n    <string name=\"resize_and_convert_sub\">Baguhin ang laki ng mga ibinigay na larawan o i-convert ang mga ito sa iba pang mga format. Ang EXIF metadata ay maaari ding i-edit dito kung pumipili ng isang larawan.</string>\n    <string name=\"analytics_sub\">Payagan ang pagkolekta ng hindi kilalang istatistika ng paggamit ng app</string>\n    <string name=\"image_exif_warning\">Sa kasalukuyan, pinapayagan lamang ng format na %1$s ang pagbabasa ng EXIF metadata sa android. Ang output na larawan ay hindi magkakaroon ng metadata, kapag na-save.</string>\n    <string name=\"allow_betas\">Payagan ang mga beta</string>\n    <string name=\"allow_betas_sub\">Kasama sa pagsusuri sa update ang mga bersyon ng beta app kung naka-enable</string>\n    <string name=\"draw_arrows\">Gumuhit ng mga Arrow</string>\n    <string name=\"crop_description\">Ang mga larawan ay i-center crop sa inilagay na laki. Papalawakin ang canvas gamit ang ibinigay na kulay ng background kung mas maliit ang larawan kaysa sa mga inilagay na dimensyon.</string>\n    <string name=\"image_stitching_sub\">Pagsamahin ang mga ibinigay na larawan upang makakuha ng isang malaki</string>\n    <string name=\"output_image_scale\">Iskala ng imahe ng output</string>\n    <string name=\"image_orientation\">Oryentasyon ng Larawan</string>\n    <string name=\"vertical\">Patayo</string>\n    <string name=\"scale_small_images_to_large\">I-scale ang maliliit na larawan sa malaki</string>\n    <string name=\"scale_small_images_to_large_sub\">Ang maliliit na larawan ay i-scale sa pinakamalaki sa pagkakasunud-sunod kung pinagana</string>\n    <string name=\"images_order\">Pagkakasunod-sunod ng mga larawan</string>\n    <string name=\"regular\">Regular</string>\n    <string name=\"pixelation\">Pixelation</string>\n    <string name=\"enhanced_pixelation\">Pinahusay na Pixelation</string>\n    <string name=\"stroke_pixelation\">Stroke Pixelation</string>\n    <string name=\"color_to_replace\">Kulay na Papalitan</string>\n    <string name=\"target_color\">Kulay ng Target</string>\n    <string name=\"color_to_remove\">Kulay na Aalisin</string>\n    <string name=\"remove_color\">Alisin ang Kulay</string>\n    <string name=\"lock_draw_orientation_sub\">Kung naka-enable sa drawing mode, hindi iikot ang screen</string>\n    <string name=\"check_for_updates\">Tingnan ang mga update</string>\n    <string name=\"neutral_sub\">Isang istilong medyo mas chromatic kaysa sa monochrome</string>\n    <string name=\"playful_scheme\">Isang mapaglarong tema - hindi lumalabas sa tema ang kulay ng pinagmulang kulay</string>\n    <string name=\"monochrome_sub\">Isang monochrome na tema, ang mga kulay ay puro itim / puti / kulay abo</string>\n    <string name=\"content_sub\">Isang scheme na naglalagay ng kulay ng pinagmulan sa Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Isang scheme na halos kapareho sa scheme ng nilalaman</string>\n    <string name=\"search_option\">Maghanap</string>\n    <string name=\"search_option_sub\">Pinapagana ang kakayahang maghanap sa lahat ng magagamit na opsyon sa pangunahing screen</string>\n    <string name=\"images_to_pdf_sub\">I-pack ang ibinigay na Mga Larawan sa output na PDF file</string>\n    <string name=\"mask_preview_sub\">Ire-render ang iginuhit na filter mask upang ipakita sa iyo ang tinatayang resulta</string>\n    <string name=\"full_filter\">Buong Filter</string>\n    <string name=\"full_filter_sub\">Ilapat ang anumang mga chain ng filter sa mga ibinigay na larawan o isang larawan</string>\n    <string name=\"start_position\">Magsimula</string>\n    <string name=\"center_position\">Gitna</string>\n    <string name=\"end_position\">Tapusin</string>\n    <string name=\"simple_variants\">Mga Simpleng Variant</string>\n    <string name=\"highlighter\">Highlighter</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"privacy_blur\">Privacy Blur</string>\n    <string name=\"highlighter_sub\">Gumuhit ng mga semi-transparent na sharpened highlighter path</string>\n    <string name=\"neon_sub\">Magdagdag ng ilang kumikinang na epekto sa iyong mga guhit</string>\n    <string name=\"pen_sub\">Default na isa, pinakasimple - ang kulay lang</string>\n    <string name=\"pixelation_sub\">Katulad ng privacy blur, ngunit pixelates sa halip na malabo</string>\n    <string name=\"fabs_shadow_sub\">Pinapagana ang shadow drawing sa likod ng mga floating action button</string>\n    <string name=\"buttons_shadow_sub\">Pinapagana ang shadow drawing sa likod ng mga default na button</string>\n    <string name=\"app_bars_shadow\">Mga App Bar</string>\n    <string name=\"app_bars_shadow_sub\">Pinapagana ang shadow drawing sa likod ng mga app bar</string>\n    <string name=\"auto_rotate_limits\">Kusang pag-ikot</string>\n    <string name=\"double_line_arrow_sub\">Gumuhit ng double pointing arrow mula sa simula hanggang sa dulo bilang isang linya</string>\n    <string name=\"auto_rotate_limits_sub\">Nagbibigay-daan sa limit box na gamitin para sa oryentasyon ng imahe</string>\n    <string name=\"double_arrow_sub\">Gumuhit ng double pointing arrow mula sa isang ibinigay na landas</string>\n    <string name=\"outlined_oval\">Nakabalangkas na Oval</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Gumuhit nang patuwid mula sa simula hanggang sa wakas</string>\n    <string name=\"oval_sub\">Gumuhit ng hugis-itlog mula sa simula hanggang sa wakas</string>\n    <string name=\"outlined_oval_sub\">Gumuguhit ng nakabalangkas na hugis-itlog mula sa simula hanggang sa wakas</string>\n    <string name=\"outlined_rect_sub\">Gumuhit ng nakabalangkas nang patuwid mula sa simula hanggang sa wakas</string>\n    <string name=\"overwrite_file_requirements\">Upang ma-overwrite ang mga file kailangan mong gumamit ng \\\"Explorer\\\" na pinagmumulan ng imahe, subukang muling pumili ng mga larawan, binago namin ang pinagmulan ng larawan sa kinakailangan.</string>\n    <string name=\"overwrite_files_sub\">Ang orihinal na file ay papalitan ng bago sa halip na i-save sa napiling folder, ang pagpipiliang ito ay kailangang source ng larawan ay \\\"Explorer\\\" o GetContent, kapag ito ay i-toggling, ito ay awtomatikong itatakda</string>\n    <string name=\"hann_sub\">Ang function ng windowing ay madalas na ginagamit sa pagpoproseso ng signal upang mabawasan ang spectral leakage at pagbutihin ang katumpakan ng frequency analysis sa pamamagitan ng pag-taping sa mga gilid ng isang signal</string>\n    <string name=\"hermite_sub\">Mathematical interpolation technique na gumagamit ng mga value at derivatives sa mga endpoint ng isang curve segment upang makabuo ng maayos at tuluy-tuloy na curve</string>\n    <string name=\"lanczos_sub\">Paraan ng resampling na nagpapanatili ng mataas na kalidad na interpolation sa pamamagitan ng paglalapat ng weighted sinc function sa mga pixel value</string>\n    <string name=\"mitchell_sub\">Paraan ng resampling na gumagamit ng convolution filter na may mga adjustable na parameter para magkaroon ng balanse sa pagitan ng sharpness at anti-aliasing sa naka-scale na imahe</string>\n    <string name=\"spline_sub\">Gumagamit ng piecewise-defined polynomial functions upang maayos na i-interpolate at tantiyahin ang isang curve o surface, flexible at tuluy-tuloy na representasyon ng hugis</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Pinipilit ang exif widget na masuri sa simula</string>\n    <string name=\"allow_multiple_languages\">Payagan ang Maramihang Wika</string>\n    <string name=\"segmentation_mode_auto_osd\">Auto Orientation &amp; Script Detection</string>\n    <string name=\"segmentation_mode_auto_only\">Auto lang</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Isang Hanay</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Single block vertical text</string>\n    <string name=\"segmentation_mode_single_block\">Isang bloke</string>\n    <string name=\"segmentation_mode_single_word\">Isang salita</string>\n    <string name=\"segmentation_mode_circle_word\">Bilugan ang salita</string>\n    <string name=\"segmentation_mode_single_char\">Single char</string>\n    <string name=\"segmentation_mode_sparse_text\">Kalat-kalat na text</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Kalat-kalat na Oryentasyon ng teksto &amp; Script Detection</string>\n    <string name=\"tile_mode_mirror\">Salamin</string>\n    <string name=\"tile_mode_clamp\">Clamp</string>\n    <string name=\"camera_sub\">Gumagamit ng camera para kumuha ng larawan, tandaan na posibleng makakuha lamang ng isang larawan mula sa pinagmulan ng larawang ito</string>\n    <string name=\"repeat_watermark\">Ulitin ang watermark</string>\n    <string name=\"repeat_watermark_sub\">Inuulit ang watermark sa larawan sa halip na solong sa ibinigay na posisyon</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermark_type\">Uri ng Watermark</string>\n    <string name=\"watermarking_image_sub\">Gagamitin ang larawang ito bilang pattern para sa watermarking</string>\n    <string name=\"text_color\">Kulay ng teksto</string>\n    <string name=\"use_size_of_first_frame_sub\">Palitan ang tinukoy na laki ng mga unang sukat ng frame</string>\n    <string name=\"repeat_count\">Ulitin ang Bilang</string>\n    <string name=\"frame_delay\">Pagkaantala ng Frame</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Two Row Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Maling Floyd Steinberg Dithering</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Ikiling Shift</string>\n    <string name=\"shuffle\">Balasahin</string>\n    <string name=\"channel_shift_y\">Paglipat ng Channel Y</string>\n    <string name=\"corruption_size\">Sukat ng Korapsyon</string>\n    <string name=\"corruption_shift_x\">Paglipat ng Korapsyon X</string>\n    <string name=\"corruption_shift_y\">Paglipat ng Korapsyon Y</string>\n    <string name=\"tent_blur\">Tent Blur</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">Gilid</string>\n    <string name=\"amplitude\">Malawak</string>\n    <string name=\"vintage\">Antigo</string>\n    <string name=\"marble\">Marmol</string>\n    <string name=\"just_size\">Sukat</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomaly</string>\n    <string name=\"deutaromaly\">Deutaromaly</string>\n    <string name=\"protonomaly\">Protonomaly</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Night Vision</string>\n    <string name=\"warm\">Mainit</string>\n    <string name=\"cool\">Malamig</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Orange Haze</string>\n    <string name=\"pink_dream\">Rosas na Panaginip</string>\n    <string name=\"golden_hour\">Gintong Oras</string>\n    <string name=\"hot_summer\">Mainit na Tag-init</string>\n    <string name=\"purple_mist\">Purple Mist</string>\n    <string name=\"sunrise\">pagsikat ng araw</string>\n    <string name=\"colorful_swirl\">Makukulay na Swirl</string>\n    <string name=\"soft_spring_light\">Malambot Spring Light</string>\n    <string name=\"autumn_tones\">Mga Tono ng Taglagas</string>\n    <string name=\"lavender_dream\">Pangarap ng Lavender</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Liwanag ng limonada</string>\n    <string name=\"spectral_fire\">Spectral Fire</string>\n    <string name=\"night_magic\">Night Magic</string>\n    <string name=\"cannot_change_image_format\">Hindi maaaring baguhin ang format ng imahe habang pinagana ang opsyon sa pag-overwrite ng mga file</string>\n    <string name=\"emoji_as_color_scheme\">Emoji bilang Color Scheme</string>\n    <string name=\"aspect_ratio\">Aspect ratio</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Sirang file o hindi isang backup</string>\n    <string name=\"reset_settings_sub\">Ibabalik nito ang iyong mga setting sa mga default na halaga. Pansinin na hindi ito maa-undo nang walang backup na file na binanggit sa itaas.</string>\n    <string name=\"crashlytics_sub\">Nagbibigay-daan ito sa app na manu-manong mangolekta ng mga ulat ng pag-crash</string>\n    <string name=\"analytics\">Analytics</string>\n    <string name=\"updates\">Mga update</string>\n    <string name=\"value_in_range\">Halaga sa hanay na %1$s - %2$s</string>\n    <string name=\"blur_edges\">Palabuin ang mga gilid</string>\n    <string name=\"blur_edges_sub\">Gumuhit ng mga blur na gilid sa ilalim ng orihinal na larawan upang punan ang mga puwang sa paligid nito sa halip na isang kulay kung pinagana</string>\n    <string name=\"enhanced_diamond_pixelation\">Pinahusay na Diamond Pixelation</string>\n    <string name=\"diamond_pixelation\">Diamond Pixelation</string>\n    <string name=\"recode\">I-recode</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anisotropic Diffusion</string>\n    <string name=\"diffusion\">Pagsasabog</string>\n    <string name=\"conduction\">pagpapadaloy</string>\n    <string name=\"horizontal_wind_stagger\">Pahalang na Wind Stagger</string>\n    <string name=\"fast_bilaterial_blur\">Mabilis na Bilateral Blur</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">Logarithmic Tone Mapping</string>\n    <string name=\"crystallize\">Mag-kristal</string>\n    <string name=\"stroke_color\">Kulay ng Stroke</string>\n    <string name=\"fractal_glass\">Fractal Glass</string>\n    <string name=\"turbulence\">Kaguluhan</string>\n    <string name=\"oil\">Langis</string>\n    <string name=\"water_effect\">Epekto ng Tubig</string>\n    <string name=\"amplitude_x\">Amplitude X</string>\n    <string name=\"frequency_x\">Dalas X</string>\n    <string name=\"frequency_y\">Dalas Y</string>\n    <string name=\"amplitude_y\">Amplitude Y</string>\n    <string name=\"perlin_distortion\">Perlin Distortion</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"delete_language_sub\">Gusto mo bang tanggalin ang data ng pagsasanay ng wikang \\\"%1$s\\\" OCR para sa lahat ng uri ng pagkilala, o para lamang sa napiling isa (%2$s)?</string>\n    <string name=\"current\">Kasalukuyan</string>\n    <string name=\"all\">Lahat</string>\n    <string name=\"pdf_tools_sub\">Gumana gamit ang mga PDF file: I-preview, I-convert sa batch ng mga larawan o lumikha ng isa mula sa mga ibinigay na larawan</string>\n    <string name=\"preview_pdf\">I-preview ang PDF</string>\n    <string name=\"pdf_to_images\">PDF sa Mga Larawan</string>\n    <string name=\"images_to_pdf\">Mga larawan sa PDF</string>\n    <string name=\"preview_pdf_sub\">Simpleng PDF preview</string>\n    <string name=\"pdf_to_images_sub\">I-convert ang PDF sa Mga Larawan sa ibinigay na format ng output</string>\n    <string name=\"gradient_maker\">Gradient Maker</string>\n    <string name=\"gradient_maker_sub\">Lumikha ng gradient ng ibinigay na laki ng output na may naka-customize na mga kulay at uri ng hitsura</string>\n    <string name=\"speed\">Bilis</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"pdf_tools\">Mga Tool sa PDF</string>\n    <string name=\"rate_app\">I-rate ang App</string>\n    <string name=\"rate\">Rate</string>\n    <string name=\"rate_app_sub\">Ang app na ito ay libre, kung gusto mo itong lumaki, pakilagyan ng star ang proyekto sa Github 😄</string>\n    <string name=\"color_matrix_4x4\">Color Matrix 4x4</string>\n    <string name=\"color_matrix_3x3\">Color Matrix 3x3</string>\n    <string name=\"simple_effects\">Mga Simple Effect</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Achromatomaly</string>\n    <string name=\"achromatopsia\">Achromatopsia</string>\n    <string name=\"gradient_type_linear\">Linear</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Magwalis</string>\n    <string name=\"gradient_type\">Uri ng Gradient</string>\n    <string name=\"center_x\">Gitna X</string>\n    <string name=\"center_y\">Sentro Y</string>\n    <string name=\"tile_mode\">Tile Mode</string>\n    <string name=\"tile_mode_repeated\">Paulit-ulit</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"color_stops\">Color Stops</string>\n    <string name=\"add_color\">Magdagdag ng Kulay</string>\n    <string name=\"properties\">Ari-arian</string>\n    <string name=\"draw_path_mode\">Gumuhit ng Path Mode</string>\n    <string name=\"double_line_arrow\">Dobleng Linya na Arrow</string>\n    <string name=\"free_drawing\">Libreng Pagguhit</string>\n    <string name=\"double_arrow\">Dobleng Palaso</string>\n    <string name=\"line_arrow\">Line Arrow</string>\n    <string name=\"arrow\">Palaso</string>\n    <string name=\"line\">Linya</string>\n    <string name=\"free_drawing_sub\">Gumuhit ng landas bilang halaga ng input</string>\n    <string name=\"line_sub\">Gumuhit ng landas mula sa simula hanggang sa dulo bilang isang linya</string>\n    <string name=\"line_arrow_sub\">Gumuguhit ng nakaturo na arrow mula sa simula hanggang sa dulo bilang isang linya</string>\n    <string name=\"arrow_sub\">Gumuguhit ng nakaturo na arrow mula sa isang ibinigay na landas</string>\n    <string name=\"outlined_rect\">Binalangkas Rect</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">quantizier</string>\n    <string name=\"gray_scale\">Gray na Scale</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"left_to_right_dithering\">Kaliwa Pakanan Dithering</string>\n    <string name=\"random_dithering\">Random Dithering</string>\n    <string name=\"simple_threshold_dithering\">Simple Threshold Dithering</string>\n    <string name=\"pipette\">Pipette</string>\n    <string name=\"effort\">Pagsisikap</string>\n    <string name=\"wait\">Teka</string>\n    <string name=\"effort_sub\">Ang halaga ng %1$s ay nangangahulugang isang mabilis na pag-compress, na nagreresulta sa medyo malaking laki ng file. Ang %2$s ay nangangahulugang isang mas mabagal na compression, na nagreresulta sa isang mas maliit na file.</string>\n    <string name=\"saving_almost_complete\">Halos kumpleto ang pag-save. Ang pagkansela ngayon ay mangangailangan ng pag-save muli.</string>\n    <string name=\"mask_color\">Kulay ng Maskara</string>\n    <string name=\"mask_preview\">Preview ng Mask</string>\n    <string name=\"delete\">Tanggalin</string>\n    <string name=\"delete_color_scheme_warn\">Ide-delete mo na ang napiling color scheme. Hindi maa-undo ang operasyong ito</string>\n    <string name=\"scale_mode\">Scale mode</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Pinakamalapit</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Basic</string>\n    <string name=\"default_value\">Default na Halaga</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Spatial Sigma</string>\n    <string name=\"median_blur\">Median Blur</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"bilinear_sub\">Ang linear (o bilinear, sa dalawang dimensyon) na interpolation ay karaniwang mabuti para sa pagbabago ng laki ng isang imahe, ngunit nagiging sanhi ng ilang hindi kanais-nais na paglambot ng mga detalye at maaari pa ring maging medyo tulis-tulis.</string>\n    <string name=\"bicubic_sub\">Kasama sa mas mahuhusay na paraan ng pag-scale ang Lanczos resampling at mga filter ng Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Isa sa mga mas simpleng paraan ng pagpapalaki ng laki, pinapalitan ang bawat pixel ng bilang ng mga pixel ng parehong kulay</string>\n    <string name=\"basic_sub\">Pinakasimpleng android scaling mode na ginagamit sa halos lahat ng app</string>\n    <string name=\"catmull_sub\">Paraan para sa maayos na interpolating at resampling ng isang set ng mga control point, na karaniwang ginagamit sa computer graphics upang lumikha ng mga makinis na curve</string>\n    <string name=\"only_clip\">Clip lang</string>\n    <string name=\"only_clip_sub\">Ang pag-save sa storage ay hindi isasagawa, at ang larawan ay susubukan na ilagay sa clipboard lamang</string>\n    <string name=\"icon_shape_sub\">Nagdaragdag ng lalagyan na may napiling hugis sa ilalim ng mga nangungunang icon ng mga card</string>\n    <string name=\"icon_shape\">Hugis ng Icon</string>\n    <string name=\"randomize_filename_sub\">Kung pinagana ang output filename ay magiging ganap na random</string>\n    <string name=\"randomize_filename\">I-randomize ang filename</string>\n    <string name=\"brightness_enforcement\">Pagpapatupad ng Liwanag</string>\n    <string name=\"screen\">Screen</string>\n    <string name=\"gradient_maker_type_image\">Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_sub\">Bumuo ng anumang gradient ng tuktok ng ibinigay na larawan</string>\n    <string name=\"transformations\">Mga pagbabago</string>\n    <string name=\"camera\">Camera</string>\n    <string name=\"pick_at_least_two_images\">Pumili ng hindi bababa sa 2 larawan</string>\n    <string name=\"horizontal\">Pahalang</string>\n    <string name=\"grain\">butil</string>\n    <string name=\"unsharp\">Unsharp</string>\n    <string name=\"fantasy_landscape\">Fantasy Landscape</string>\n    <string name=\"color_explosion\">Pagsabog ng Kulay</string>\n    <string name=\"electric_gradient\">Electric Gradient</string>\n    <string name=\"caramel_darkness\">Karamelo Kadiliman</string>\n    <string name=\"futuristic_gradient\">Futuristic Gradient</string>\n    <string name=\"green_sun\">Berdeng Araw</string>\n    <string name=\"rainbow_world\">Rainbow World</string>\n    <string name=\"deep_purple\">Malalim na lila</string>\n    <string name=\"space_portal\">Space Portal</string>\n    <string name=\"red_swirl\">Red Swirl</string>\n    <string name=\"digital_code\">Digital Code</string>\n    <string name=\"watermarking\">Watermarking</string>\n    <string name=\"watermarking_sub\">Takpan ang mga larawan gamit ang nako-customize na text/image na mga watermark</string>\n    <string name=\"offset_x\">Offset X</string>\n    <string name=\"overlay_mode\">Overlay Mode</string>\n    <string name=\"pixel_size\">Laki ng Pixel</string>\n    <string name=\"lock_draw_orientation\">Lock draw orientation</string>\n    <string name=\"max_colors_count\">Max na bilang ng kulay</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">GIF Tools</string>\n    <string name=\"gif_tools_sub\">I-convert ang mga larawan sa GIF na larawan o i-extract ang mga frame mula sa ibinigay na GIF na larawan</string>\n    <string name=\"gif_type_to_image\">GIF sa mga larawan</string>\n    <string name=\"gif_type_to_image_sub\">I-convert ang GIF file sa batch ng mga larawan</string>\n    <string name=\"gif_type_to_gif_sub\">I-convert ang batch ng mga larawan sa GIF file</string>\n    <string name=\"gif_type_to_gif\">Mga larawan sa GIF</string>\n    <string name=\"select_gif_image_to_start\">Pumili ng GIF na imahe upang magsimula</string>\n    <string name=\"use_size_of_first_frame\">Gamitin ang laki ng Unang frame</string>\n    <string name=\"use_lasso\">Gamitin ang Lasso</string>\n    <string name=\"use_lasso_sub\">Gumagamit ng Lasso tulad ng sa drawing mode para magsagawa ng pagbubura</string>\n    <string name=\"original_image_preview_alpha\">Orihinal na Preview ng Larawan Alpha</string>\n    <string name=\"mask_filter\">Mask Filter</string>\n    <string name=\"mask_filter_sub\">Ilapat ang mga chain ng filter sa mga partikular na lugar na may maskara, maaaring matukoy ng bawat lugar ng maskara ang sarili nitong hanay ng mga filter</string>\n    <string name=\"masks\">Mga maskara</string>\n    <string name=\"add_mask\">Magdagdag ng Mask</string>\n    <string name=\"mask_indexed\">Mask %d</string>\n    <string name=\"random_emojis_sub\">Ang emoji ng app bar ay patuloy na babaguhin nang random sa halip na gumamit ng napili</string>\n    <string name=\"random_emojis\">Mga Random na Emoji</string>\n    <string name=\"random_emojis_error\">Hindi maaaring gumamit ng random na pagpili ng emoji habang naka-disable ang mga emoji</string>\n    <string name=\"emoji_selection_error\">Hindi makapili ng emoji habang naka-enable ang pagpili ng random</string>\n    <string name=\"crop_mask\">crop mask</string>\n    <string name=\"vibrant_sub\">Ang isang malakas na tema, ang pagiging makulay ay pinakamataas para sa Pangunahing palette, na nadagdagan para sa iba</string>\n    <string name=\"old_tv\">Lumang Tv</string>\n    <string name=\"shuffle_blur\">Balasahin ang Blur</string>\n    <string name=\"recognize_text\">OCR (Kilalanin ang Teksto)</string>\n    <string name=\"recognize_text_sub\">Kilalanin ang teksto mula sa ibinigay na larawan, suportado ng 120+ wika</string>\n    <string name=\"picture_has_no_text\">Walang text ang larawan, o hindi ito nakita ng app</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Uri ng Pagkilala</string>\n    <string name=\"fast\">Mabilis</string>\n    <string name=\"standard\">Pamantayan</string>\n    <string name=\"best\">Pinakamahusay</string>\n    <string name=\"no_data\">Walang Data</string>\n    <string name=\"download_description\">Para sa wastong paggana ng Tesseract OCR, kailangang ma-download ang karagdagang data ng pagsasanay (%1$s) sa iyong device. \\nGusto mo bang mag-download ng %2$s data?</string>\n    <string name=\"download\">I-download</string>\n    <string name=\"no_connection\">Walang koneksyon, suriin ito at subukang muli upang mag-download ng mga modelo ng tren</string>\n    <string name=\"downloaded_languages\">Mga Na-download na Wika</string>\n    <string name=\"available_languages\">Mga Magagamit na Wika</string>\n    <string name=\"segmentation_mode\">Mode ng Segmentation</string>\n    <string name=\"restore_background_sub\">Ibabalik ng brush ang background sa halip na burahin</string>\n    <string name=\"horizontal_grid\">Pahalang na Grid</string>\n    <string name=\"vertical_grid\">Vertical Grid</string>\n    <string name=\"stitch_mode\">Stitch Mode</string>\n    <string name=\"rows_count\">Bilang ng mga hilera</string>\n    <string name=\"columns_count\">Bilang ng Mga Hanay</string>\n    <string name=\"use_pixel_switch\">Gamitin ang Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Pixel-like switch ang gagamitin sa halip na ang materyal ng google na pinagbatayan mo</string>\n    <string name=\"slide\">Slide</string>\n    <string name=\"side_by_side\">Magkatabi</string>\n    <string name=\"toggle_tap\">I-toggle ang Tapikin</string>\n    <string name=\"transparency\">Aninaw</string>\n    <string name=\"saved_to_original\">Na-overwrite na file na may pangalang %1$s sa orihinal na destinasyon</string>\n    <string name=\"magnifier\">Magnifier</string>\n    <string name=\"magnifier_sub\">Pinapagana ang magnifier sa tuktok ng daliri sa mga mode ng pagguhit para sa mas mahusay na accessibility</string>\n    <string name=\"force_exif_widget_initial_value\">Pilitin ang paunang halaga</string>\n    <string name=\"favorite\">Paborito</string>\n    <string name=\"no_favorite_filters\">Wala pang naidagdag na mga paboritong filter</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Gumagamit ng piecewise-defined bicubic polynomial function upang maayos na i-interpolate at tantiyahin ang isang curve o surface, flexible at tuluy-tuloy na representasyon ng hugis</string>\n    <string name=\"inverse_fill_type\">Baliktad na Uri ng Punan</string>\n    <string name=\"inverse_fill_type_sub\">Kung pinagana ang lahat ng hindi naka-mask na lugar ay sasalain sa halip na default na gawi</string>\n    <string name=\"confetti\">Confetti</string>\n    <string name=\"confetti_sub\">Ipapakita ang confetti sa pag-save, pagbabahagi at iba pang pangunahing aksyon</string>\n    <string name=\"secure_mode\">Secure Mode</string>\n    <string name=\"secure_mode_sub\">Itinatago ang nilalaman sa paglabas, pati na rin ang screen ay hindi maaaring makuha o i-record</string>\n    <string name=\"draw_arrows_sub\">Kung pinagana ang landas sa pagguhit ay kakatawanin bilang nakaturo na arrow</string>\n    <string name=\"brush_softness\">Ang lambot ng brush</string>\n    <string name=\"image_stitching\">Pagtahi ng Larawan</string>\n    <string name=\"pen\">Panulat</string>\n    <string name=\"palette_style\">Estilo ng palette</string>\n    <string name=\"tonal_spot\">Tonal Spot</string>\n    <string name=\"neutral\">Neutral</string>\n    <string name=\"vibrant\">Masigla</string>\n    <string name=\"expressive\">Nagpapahayag</string>\n    <string name=\"rainbow\">bahaghari</string>\n    <string name=\"fruit_salad\">Fruit salad</string>\n    <string name=\"fidelity\">Katapatan</string>\n    <string name=\"content\">Nilalaman</string>\n    <string name=\"tonal_spot_sub\">Default na istilo ng palette, pinapayagan nitong i-customize ang lahat ng apat na kulay, pinapayagan ka ng iba na itakda lamang ang pangunahing kulay</string>\n    <string name=\"privacy_blur_sub\">I-blurs ang larawan sa ilalim ng iginuhit na landas upang ma-secure ang anumang nais mong itago</string>\n    <string name=\"containers_shadow\">Mga lalagyan</string>\n    <string name=\"containers_shadow_sub\">Pinapagana ang pagguhit ng anino sa likod ng mga lalagyan</string>\n    <string name=\"sliders_shadow\">Mga slider</string>\n    <string name=\"switches_shadow\">Mga switch</string>\n    <string name=\"fabs_shadow\">Mga FAB</string>\n    <string name=\"buttons_shadow\">Mga Pindutan</string>\n    <string name=\"sliders_shadow_sub\">Pinapagana ang shadow drawing sa likod ng mga slider</string>\n    <string name=\"switches_shadow_sub\">Pinapagana ang pagguhit ng anino sa likod ng mga switch</string>\n    <string name=\"attention\">Pansin</string>\n    <string name=\"foss_update_checker_warning\">Ang update checker na ito ay kumonekta sa GitHub sa dahilan ng pag-check kung may bagong update na available</string>\n    <string name=\"fading_edges\">Pagkupas Mga Gilid</string>\n    <string name=\"disabled\">Hindi pinagana</string>\n    <string name=\"both\">pareho</string>\n    <string name=\"invert_colors\">Baliktarin ang mga Kulay</string>\n    <string name=\"invert_colors_sub\">Pinapalitan ang mga kulay ng tema sa mga negatibo kung pinagana</string>\n    <string name=\"exit\">Lumabas</string>\n    <string name=\"preview_closing\">Kung aalis ka sa preview ngayon, kakailanganin mong idagdag muli ang mga larawan</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Gumuguhit ng closed filled path ayon sa ibinigay na path</string>\n    <string name=\"image_format\">Format ng Larawan</string>\n    <string name=\"material_you_sub\">Lumilikha ng \\\"Material You\\\" palette mula sa larawan</string>\n    <string name=\"dark_colors\">Madidilim na kulay</string>\n    <string name=\"dark_colors_sub\">Gumagamit ng night mode color scheme sa halip na light variant</string>\n    <string name=\"copy_as_compose_code\">Kopyahin bilang Jetpack Compose code</string>\n    <string name=\"ring_blur\">Ring Blur</string>\n    <string name=\"cross_blur\">Cross Blur</string>\n    <string name=\"circle_blur\">Circle Blur</string>\n    <string name=\"star_blur\">Star Blur</string>\n    <string name=\"linear_tilt_shift\">Linear Tilt Shift</string>\n    <string name=\"tags_to_remove\">Mga Tag Upang Alisin</string>\n    <string name=\"apng_tools\">Mga Tool ng APNG</string>\n    <string name=\"apng_tools_sub\">I-convert ang mga larawan sa APNG na larawan o kunin ang mga frame mula sa ibinigay na APNG na larawan</string>\n    <string name=\"apng_type_to_image\">APNG sa mga larawan</string>\n    <string name=\"apng_type_to_image_sub\">I-convert ang APNG file sa batch ng mga larawan</string>\n    <string name=\"apng_type_to_apng_sub\">I-convert ang batch ng mga larawan sa APNG file</string>\n    <string name=\"apng_type_to_apng\">Mga larawan sa APNG</string>\n    <string name=\"select_apng_image_to_start\">Pumili ng APNG na larawan upang magsimula</string>\n    <string name=\"motion_blur\">Galaw Malabo</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Lumikha ng Zip file mula sa mga ibinigay na file o larawan</string>\n    <string name=\"drag_handle_width\">I-drag ang Lapad ng Handle</string>\n    <string name=\"confetti_type\">Uri ng Confetti</string>\n    <string name=\"festive\">Masigasig</string>\n    <string name=\"explode\">Pasabog</string>\n    <string name=\"rain\">Ulan</string>\n    <string name=\"corners\">Kanto</string>\n    <string name=\"jxl_tools\">Mga Kagamitan para sa JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL papuntang JPEG</string>\n    <string name=\"jxl_tools_sub\">Mag-transcode sa pagitan ng JXL at JPEG nang walang pagkabawas sa kalidad, o i-convert ang GIF/APNG papunta sa animasyong JXL</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Magsagawa ng lossless transcoding mula JXL hanggang JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Magsagawa ng lossless transcoding mula JPEG hanggang JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG hanggang JXL</string>\n    <string name=\"select_jxl_image_to_start\">Pumili ng JXL image para magsimula</string>\n    <string name=\"fast_gaussian_blur_2d\">Mabilis na Gaussian Blur 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Mabilis na Gaussian Blur 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Mabilis na Gaussian Blur 4D</string>\n    <string name=\"auto_paste\">Pasko ng Pagkabuhay ng Kotse</string>\n    <string name=\"auto_paste_sub\">Binibigyang-daan ang app na awtomatikong i-paste ang data ng clipboard, kaya lilitaw ito sa pangunahing screen at maproseso mo ito</string>\n    <string name=\"harmonization_color\">Kulay ng Harmonization</string>\n    <string name=\"harmonization_level\">Antas ng Harmonisasyon</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Paraan ng resampling na nagpapanatili ng mataas na kalidad na interpolation sa pamamagitan ng paglalapat ng Bessel (jinc) function sa mga pixel value</string>\n    <string name=\"gif_type_to_jxl\">GIF sa JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">I-convert ang mga GIF na imahe sa JXL animated na mga larawan</string>\n    <string name=\"apng_type_to_jxl\">APNG hanggang JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">I-convert ang mga larawan ng APNG sa JXL animated na mga larawan</string>\n    <string name=\"jxl_type_to_images\">JXL sa Mga Larawan</string>\n    <string name=\"jxl_type_to_images_sub\">I-convert ang JXL animation sa batch ng mga larawan</string>\n    <string name=\"jxl_type_to_jxl\">Mga larawan sa JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">I-convert ang batch ng mga larawan sa JXL animation</string>\n    <string name=\"behavior\">Pag-uugali</string>\n    <string name=\"skip_file_picking\">Laktawan ang Pagpili ng File</string>\n    <string name=\"skip_file_picking_sub\">Ang tagapili ng file ay ipapakita kaagad kung posible ito sa napiling screen</string>\n    <string name=\"generate_previews\">Bumuo ng mga Preview</string>\n    <string name=\"generate_previews_sub\">Pinapagana ang pagbuo ng preview, maaaring makatulong ito upang maiwasan ang mga pag-crash sa ilang device, hindi rin nito pinapagana ang ilang functionality sa pag-edit sa loob ng iisang opsyon sa pag-edit</string>\n    <string name=\"lossy_compression\">Lossy Compression</string>\n    <string name=\"lossy_compression_sub\">Gumagamit ng lossy compression upang bawasan ang laki ng file sa halip na lossless</string>\n    <string name=\"compression_type\">Uri ng Compression</string>\n    <string name=\"speed_sub\">Kinokontrol ang nagreresultang bilis ng pag-decode ng imahe, makakatulong ito sa pagbukas ng nagreresultang larawan nang mas mabilis, ang halaga ng %1$s ay nangangahulugang pinakamabagal na pag-decode, samantalang %2$s - pinakamabilis, maaaring pataasin ng setting na ito ang laki ng output ng imahe.</string>\n    <string name=\"sorting\">Pag-uuri</string>\n    <string name=\"sort_by_date\">Petsa</string>\n    <string name=\"sort_by_date_reversed\">Petsa (Baliktad)</string>\n    <string name=\"sort_by_name\">Pangalan</string>\n    <string name=\"sort_by_name_reversed\">Pangalan (Baliktad)</string>\n    <string name=\"channels_configuration\">Configuration ng Mga Channel</string>\n    <string name=\"header_today\">Ngayong araw</string>\n    <string name=\"header_yesterday\">Kahapon</string>\n    <string name=\"embedded_picker\">Naka-embed na Picker</string>\n    <string name=\"embedded_picker_sub\">Tagapili ng imahe ng Image Toolbox</string>\n    <string name=\"no_permissions\">Walang pahintulot</string>\n    <string name=\"request\">Kahilingan</string>\n    <string name=\"pick_multiple_media\">Pumili ng Maramihang Media</string>\n    <string name=\"pick_single_media\">Pumili ng Single Media</string>\n    <string name=\"pick\">Pumili</string>\n    <string name=\"try_again\">Subukan muli</string>\n    <string name=\"show_settings_in_landscape\">Ipakita ang Mga Setting Sa Landscape</string>\n    <string name=\"show_settings_in_landscape_sub\">Kung ito ay hindi pinagana, sa mga setting ng landscape mode ay bubuksan sa button sa itaas na app bar gaya ng dati, sa halip na permanenteng nakikitang opsyon</string>\n    <string name=\"fullscreen_settings\">Mga Setting ng Fullscreen</string>\n    <string name=\"fullscreen_settings_sub\">I-enable ito at palaging bubuksan ang page ng mga setting bilang fullscreen sa halip na slideable drawer sheet</string>\n    <string name=\"switch_type\">Uri ng Switch</string>\n    <string name=\"compose\">Mag-compose</string>\n    <string name=\"compose_switch_sub\">Isang Jetpack Compose Material Lilipat ka</string>\n    <string name=\"material_you_switch_sub\">Isang Materyal na Papalitan mo</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Baguhin ang laki ng Anchor</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Matatas</string>\n    <string name=\"fluent_switch_sub\">Isang switch batay sa \\\"Fluent\\\" na sistema ng disenyo</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Isang switch batay sa sistema ng disenyo ng \\\"Cupertino\\\".</string>\n    <string name=\"images_to_svg\">Mga larawan sa SVG</string>\n    <string name=\"images_to_svg_sub\">I-trace ang mga ibinigay na larawan sa mga SVG na larawan</string>\n    <string name=\"use_sampled_palette\">Gumamit ng Sampled Palette</string>\n    <string name=\"use_sampled_palette_sub\">Ang quantization palette ay isa-sample kung ang opsyong ito ay pinagana</string>\n    <string name=\"path_omit\">Path Omit</string>\n    <string name=\"svg_warning\">Ang paggamit ng tool na ito para sa pagsubaybay sa malalaking larawan nang walang downscaling ay hindi inirerekomenda, maaari itong magdulot ng pag-crash at dagdagan ang oras ng pagproseso</string>\n    <string name=\"downscale_image\">Downscale na larawan</string>\n    <string name=\"downscale_image_sub\">Ang imahe ay ibababa sa mas mababang mga dimensyon bago iproseso, nakakatulong ito sa tool na gumana nang mas mabilis at mas ligtas</string>\n    <string name=\"min_color_ratio\">Minimum na Ratio ng Kulay</string>\n    <string name=\"lines_threshold\">Threshold ng mga Linya</string>\n    <string name=\"quadratic_threshold\">Quadratic Threshold</string>\n    <string name=\"coordinates_rounding_tolerance\">Coordinates Rounding Tolerance</string>\n    <string name=\"path_scale\">Scale ng Path</string>\n    <string name=\"reset_properties\">I-reset ang mga katangian</string>\n    <string name=\"reset_properties_sub\">Itatakda ang lahat ng property sa mga default na value, pansinin na hindi na mababawi ang pagkilos na ito</string>\n    <string name=\"detailed\">Detalyadong</string>\n    <string name=\"default_line_width\">Default na Lapad ng Linya</string>\n    <string name=\"engine_mode\">Mode ng Engine</string>\n    <string name=\"legacy\">Legacy</string>\n    <string name=\"lstm_network\">LSTM network</string>\n    <string name=\"legacy_and_lstm\">Legacy at LSTM</string>\n    <string name=\"convert\">Magbalik-loob</string>\n    <string name=\"convert_sub\">I-convert ang mga batch ng larawan sa ibinigay na format</string>\n    <string name=\"add_new_folder\">Magdagdag ng Bagong Folder</string>\n    <string name=\"tag_bits_per_sample\">Bits Bawat Sample</string>\n    <string name=\"tag_compression\">Compression</string>\n    <string name=\"tag_photometric_interpretation\">Photometric Interpretasyon</string>\n    <string name=\"tag_samples_per_pixel\">Mga Sample Bawat Pixel</string>\n    <string name=\"tag_planar_configuration\">Planar Configuration</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sub Sampling</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Positioning</string>\n    <string name=\"tag_x_resolution\">X Resolution</string>\n    <string name=\"tag_y_resolution\">Y Resolusyon</string>\n    <string name=\"tag_resolution_unit\">Yunit ng Resolusyon</string>\n    <string name=\"tag_strip_offsets\">Mga Strip Offset</string>\n    <string name=\"tag_rows_per_strip\">Mga Hanay sa Bawat Strip</string>\n    <string name=\"tag_strip_byte_counts\">Mga Bilang ng Strip Byte</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG Interchange Format</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Haba ng JPEG Interchange Format</string>\n    <string name=\"tag_transfer_function\">Paglipat ng Function</string>\n    <string name=\"tag_white_point\">Puting Punto</string>\n    <string name=\"tag_primary_chromaticities\">Pangunahing Chromaticities</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Coefficients</string>\n    <string name=\"tag_reference_black_white\">Sanggunian Black White</string>\n    <string name=\"tag_datetime\">Petsa Oras</string>\n    <string name=\"tag_image_description\">Paglalarawan ng Larawan</string>\n    <string name=\"tag_make\">Gawin</string>\n    <string name=\"tag_model\">Modelo</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_artist\">Artista</string>\n    <string name=\"tag_copyright\">Copyright</string>\n    <string name=\"tag_exif_version\">Bersyon ng Exif</string>\n    <string name=\"tag_flashpix_version\">Bersyon ng Flashpix</string>\n    <string name=\"tag_color_space\">Color Space</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Dimensyon ng Pixel X</string>\n    <string name=\"tag_pixel_y_dimension\">Dimensyon ng Pixel Y</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Mga Compressed Bits Bawat Pixel</string>\n    <string name=\"tag_maker_note\">Tala ng Gumawa</string>\n    <string name=\"tag_user_comment\">Komento ng User</string>\n    <string name=\"tag_related_sound_file\">Kaugnay na Sound File</string>\n    <string name=\"tag_datetime_original\">Orihinal na Petsa ng Oras</string>\n    <string name=\"tag_datetime_digitized\">Petsa Oras na Digitize</string>\n    <string name=\"tag_offset_time\">Oras ng Offset</string>\n    <string name=\"tag_offset_time_original\">Orihinal na Oras ng Offset</string>\n    <string name=\"tag_offset_time_digitized\">Offset Time Digitized</string>\n    <string name=\"tag_subsec_time\">Oras ng Sub Sec</string>\n    <string name=\"tag_subsec_time_original\">Orihinal na Oras ng Sub Sec</string>\n    <string name=\"tag_subsec_time_digitized\">Na-digitize ang Oras ng Sub Sec</string>\n    <string name=\"tag_exposure_time\">Tagal ng pagkalantad</string>\n    <string name=\"tag_f_number\">F Numero</string>\n    <string name=\"tag_exposure_program\">Exposure Program</string>\n    <string name=\"tag_spectral_sensitivity\">Spectral Sensitivity</string>\n    <string name=\"tag_photographic_sensitivity\">Photographic Sensitivity</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Uri ng Sensitivity</string>\n    <string name=\"tag_standard_output_sensitivity\">Standard Output Sensitivity</string>\n    <string name=\"tag_recommended_exposure_index\">Inirerekomendang Exposure Index</string>\n    <string name=\"tag_iso_speed\">Bilis ng ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Speed ​​Latitude yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Bilis ng ISO Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Halaga ng Bilis ng Shutter</string>\n    <string name=\"tag_aperture_value\">Halaga ng Aperture</string>\n    <string name=\"tag_brightness_value\">Halaga ng Liwanag</string>\n    <string name=\"tag_exposure_bias_value\">Halaga ng Exposure Bias</string>\n    <string name=\"tag_max_aperture_value\">Halaga ng Max Aperture</string>\n    <string name=\"tag_subject_distance\">Distansya ng Paksa</string>\n    <string name=\"tag_metering_mode\">Mode ng Pagsukat</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Lugar ng Paksa</string>\n    <string name=\"tag_focal_length\">Haba ng Focal</string>\n    <string name=\"tag_flash_energy\">Flash Energy</string>\n    <string name=\"tag_spatial_frequency_response\">Spatial Frequency Response</string>\n    <string name=\"tag_focal_plane_x_resolution\">Focal Plane X Resolution</string>\n    <string name=\"tag_focal_plane_y_resolution\">Focal Plane Y Resolution</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Focal Plane Resolution Unit</string>\n    <string name=\"tag_subject_location\">Lokasyon ng Paksa</string>\n    <string name=\"tag_exposure_index\">Index ng Exposure</string>\n    <string name=\"tag_sensing_method\">Paraan ng Sensing</string>\n    <string name=\"tag_file_source\">Pinagmulan ng File</string>\n    <string name=\"tag_cfa_pattern\">Pattern ng CFA</string>\n    <string name=\"tag_custom_rendered\">Custom na Na-render</string>\n    <string name=\"tag_exposure_mode\">Exposure Mode</string>\n    <string name=\"tag_white_balance\">White Balance</string>\n    <string name=\"tag_digital_zoom_ratio\">Digital Zoom Ratio</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Focal Length Sa35mm Film</string>\n    <string name=\"tag_scene_capture_type\">Uri ng Pagkuha ng Eksena</string>\n    <string name=\"tag_gain_control\">Makakuha ng Kontrol</string>\n    <string name=\"tag_contrast\">Contrast</string>\n    <string name=\"tag_saturation\">Saturation</string>\n    <string name=\"tag_sharpness\">Ang talas</string>\n    <string name=\"tag_device_setting_description\">Paglalarawan ng Setting ng Device</string>\n    <string name=\"tag_subject_distance_range\">Saklaw ng Distansya ng Paksa</string>\n    <string name=\"tag_image_unique_id\">Natatanging ID ng Larawan</string>\n    <string name=\"tag_camera_owner_name\">Pangalan ng May-ari ng Camera</string>\n    <string name=\"tag_body_serial_number\">Serial Number ng Katawan</string>\n    <string name=\"tag_lens_specification\">Pagtutukoy ng Lens</string>\n    <string name=\"tag_lens_make\">Gumawa ng Lens</string>\n    <string name=\"tag_lens_model\">Modelo ng Lens</string>\n    <string name=\"tag_lens_serial_number\">Serial Number ng Lens</string>\n    <string name=\"tag_gps_version_id\">ID ng Bersyon ng GPS</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitude</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Longitude Ref</string>\n    <string name=\"tag_gps_longitude\">GPS Longitude</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Altitude Ref</string>\n    <string name=\"tag_gps_altitude\">Altitude ng GPS</string>\n    <string name=\"tag_gps_timestamp\">GPS Time Stamp</string>\n    <string name=\"tag_gps_satellites\">Mga GPS Satellite</string>\n    <string name=\"tag_gps_status\">Katayuan ng GPS</string>\n    <string name=\"tag_gps_measure_mode\">Mode ng Pagsukat ng GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Bilis ng GPS Ref</string>\n    <string name=\"tag_gps_speed\">Bilis ng GPS</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS Track</string>\n    <string name=\"tag_gps_img_direction_ref\">Direksyon ng GPS Img Ref</string>\n    <string name=\"tag_gps_img_direction\">Direksyon ng GPS Img</string>\n    <string name=\"tag_gps_map_datum\">Datum ng Mapa ng GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitude Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Longitude</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS Dest Distansya</string>\n    <string name=\"tag_gps_processing_method\">Paraan ng Pagproseso ng GPS</string>\n    <string name=\"tag_gps_area_information\">Impormasyon sa Lugar ng GPS</string>\n    <string name=\"tag_gps_datestamp\">Stamp ng Petsa ng GPS</string>\n    <string name=\"tag_gps_differential\">GPS Differential</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H Positioning Error</string>\n    <string name=\"tag_interoperability_index\">Interoperability Index</string>\n    <string name=\"tag_dng_version\">Bersyon ng DNG</string>\n    <string name=\"tag_default_crop_size\">Default na Laki ng Pag-crop</string>\n    <string name=\"tag_orf_preview_image_start\">I-preview ang Simula ng Larawan</string>\n    <string name=\"tag_orf_preview_image_length\">I-preview ang Haba ng Imahe</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect Frame</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Border sa Ibaba ng Sensor</string>\n    <string name=\"tag_rw2_sensor_left_border\">Kaliwang Border ng Sensor</string>\n    <string name=\"tag_rw2_sensor_right_border\">Kanang Border ng Sensor</string>\n    <string name=\"tag_rw2_sensor_top_border\">Nangungunang Border ng Sensor</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Gumuhit ng Teksto sa landas na may ibinigay na font at kulay</string>\n    <string name=\"font_size\">Laki ng Font</string>\n    <string name=\"watermark_size\">Laki ng Watermark</string>\n    <string name=\"repeat_text\">Ulitin ang Teksto</string>\n    <string name=\"repeat_text_sub\">Ang kasalukuyang text ay uulitin hanggang sa matapos ang path sa halip na isang beses na pagguhit</string>\n    <string name=\"dash_size\">Laki ng Dash</string>\n    <string name=\"draw_mode_image_sub\">Gamitin ang napiling larawan upang iguhit ito sa ibinigay na landas</string>\n    <string name=\"draw_image_sub\">Gagamitin ang larawang ito bilang paulit-ulit na pagpasok ng iginuhit na landas</string>\n    <string name=\"outlined_triangle_sub\">Gumuguhit ng nakabalangkas na tatsulok mula sa simula hanggang sa wakas</string>\n    <string name=\"triangle_sub\">Gumuguhit ng nakabalangkas na tatsulok mula sa simula hanggang sa wakas</string>\n    <string name=\"outlined_triangle\">Nakabalangkas na Triangle</string>\n    <string name=\"triangle\">Tatsulok</string>\n    <string name=\"polygon_sub\">Gumuhit ng polygon mula sa simula hanggang sa wakas</string>\n    <string name=\"polygon\">Polygon</string>\n    <string name=\"outlined_polygon\">Nakabalangkas na Polygon</string>\n    <string name=\"outlined_polygon_sub\">Gumuguhit ng nakabalangkas na polygon mula sa simula hanggang sa wakas</string>\n    <string name=\"vertices\">Vertices</string>\n    <string name=\"draw_regular_polygon\">Gumuhit ng Regular na Polygon</string>\n    <string name=\"draw_regular_polygon_sub\">Gumuhit ng polygon na magiging regular sa halip na libreng anyo</string>\n    <string name=\"star_sub\">Gumuhit ng bituin mula sa simula hanggang sa wakas</string>\n    <string name=\"star\">Bituin</string>\n    <string name=\"outlined_star\">Nakabalangkas na Bituin</string>\n    <string name=\"outlined_star_sub\">Gumuhit ng nakabalangkas na bituin mula sa simula hanggang sa dulong punto</string>\n    <string name=\"inner_radius_ratio\">Inner Radius Ratio</string>\n    <string name=\"draw_regular_star\">Gumuhit ng Regular na Bituin</string>\n    <string name=\"draw_regular_star_sub\">Gumuhit ng bituin na magiging regular sa halip na libreng form</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Pinapagana ang antialiasing upang maiwasan ang matutulis na mga gilid</string>\n    <string name=\"open_edit_instead_of_preview\">Buksan ang Edit sa halip na Preview</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Kapag pinili mo ang larawan na bubuksan (preview) sa ImageToolbox, ang pag-edit ng selection sheet ay bubuksan sa halip na mag-preview</string>\n    <string name=\"document_scanner\">Scanner ng Dokumento</string>\n    <string name=\"document_scanner_sub\">I-scan ang mga dokumento at gumawa ng PDF o hiwalay na mga larawan mula sa kanila</string>\n    <string name=\"click_to_start_scanning\">I-click upang simulan ang pag-scan</string>\n    <string name=\"start_scanning\">Simulan ang Pag-scan</string>\n    <string name=\"save_as_pdf\">I-save Bilang PDF</string>\n    <string name=\"share_as_pdf\">Ibahagi Bilang PDF</string>\n    <string name=\"options_below_is_for_images\">Ang mga opsyon sa ibaba ay para sa pag-save ng mga larawan, hindi PDF</string>\n    <string name=\"equalize_histogram_hsv\">I-equalize ang Histogram HSV</string>\n    <string name=\"equalize_histogram\">I-equalize ang Histogram</string>\n    <string name=\"enter_percentage\">Ilagay ang Porsyento</string>\n    <string name=\"allow_enter_by_text_field\">Payagan ang pagpasok sa pamamagitan ng Text Field</string>\n    <string name=\"allow_enter_by_text_field_sub\">Pinapagana ang Text Field sa likod ng pagpili ng mga preset, upang maipasok ang mga ito sa mabilisang</string>\n    <string name=\"scale_color_space\">Scale Color Space</string>\n    <string name=\"linear\">Linear</string>\n    <string name=\"equalize_histogram_pixelation\">I-equalize ang Histogram Pixelation</string>\n    <string name=\"grid_size_x\">Sukat ng Grid X</string>\n    <string name=\"grid_size_y\">Laki ng Grid Y</string>\n    <string name=\"equalize_histogram_adaptive\">I-equalize ang Histogram Adaptive</string>\n    <string name=\"equalize_histogram_adaptive_luv\">I-equalize ang Histogram Adaptive LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">I-equalize ang Histogram Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">I-crop sa Nilalaman</string>\n    <string name=\"frame_color\">Kulay ng Frame</string>\n    <string name=\"color_to_ignore\">Kulay Upang Huwag pansinin</string>\n    <string name=\"template\">Template</string>\n    <string name=\"no_template_filters\">Walang naidagdag na mga filter ng template</string>\n    <string name=\"create_new\">Lumikha ng Bago</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Ang na-scan na QR code ay hindi isang wastong template ng filter</string>\n    <string name=\"scan_qr_code\">I-scan ang QR code</string>\n    <string name=\"opened_file_have_no_filter_template\">Ang napiling file ay walang data ng template ng filter</string>\n    <string name=\"create_template\">Lumikha ng Template</string>\n    <string name=\"template_name\">Pangalan ng Template</string>\n    <string name=\"select_template_preview\">Gagamitin ang larawang ito upang i-preview ang template ng filter na ito</string>\n    <string name=\"template_filter\">Filter ng Template</string>\n    <string name=\"as_qr_code\">Bilang imahe ng QR code</string>\n    <string name=\"as_file\">Bilang file</string>\n    <string name=\"save_as_file\">I-save bilang file</string>\n    <string name=\"save_as_qr_code_image\">I-save bilang imahe ng QR code</string>\n    <string name=\"delete_template\">Tanggalin ang Template</string>\n    <string name=\"delete_template_warn\">Ide-delete mo na ang napiling template filter. Hindi na maa-undo ang operasyong ito</string>\n    <string name=\"added_filter_template\">Idinagdag ang template ng filter na may pangalang \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">I-filter ang Preview</string>\n    <string name=\"qr_code\">QR at Barcode</string>\n    <string name=\"qr_code_sub\">I-scan ang QR code at kunin ang nilalaman nito o i-paste ang iyong string upang makabuo ng bago</string>\n    <string name=\"code_content\">Nilalaman ng Code</string>\n    <string name=\"scan_qr_code_to_replace_content\">I-scan ang anumang barcode upang palitan ang nilalaman sa field, o mag-type ng isang bagay upang makabuo ng bagong barcode na may napiling uri</string>\n    <string name=\"qr_description\">Paglalarawan ng QR</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Magbigay ng pahintulot sa camera sa mga setting para i-scan ang QR code</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Magbigay ng pahintulot sa camera sa mga setting para i-scan ang Document Scanner</string>\n    <string name=\"cubic\">Kubiko</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussian</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-Siya</string>\n    <string name=\"box\">Kahon</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Nagbibigay ang cubic interpolation ng mas maayos na scaling sa pamamagitan ng pagsasaalang-alang sa pinakamalapit na 16 pixels, na nagbibigay ng mas magandang resulta kaysa bilinear</string>\n    <string name=\"bspline_sub\">Gumagamit ng piecewise-defined polynomial functions upang maayos na i-interpolate at tantiyahin ang isang curve o surface, flexible at tuluy-tuloy na representasyon ng hugis</string>\n    <string name=\"hamming_sub\">Isang window function na ginagamit upang bawasan ang spectral leakage sa pamamagitan ng pag-taping sa mga gilid ng isang signal, na kapaki-pakinabang sa pagpoproseso ng signal</string>\n    <string name=\"hanning_sub\">Isang variant ng Hann window, na karaniwang ginagamit upang mabawasan ang spectral leakage sa mga application sa pagpoproseso ng signal</string>\n    <string name=\"blackman_sub\">Isang window function na nagbibigay ng magandang frequency resolution sa pamamagitan ng pagliit ng spectral leakage, na kadalasang ginagamit sa pagpoproseso ng signal</string>\n    <string name=\"welch_sub\">Isang window function na idinisenyo upang magbigay ng magandang frequency resolution na may pinababang spectral leakage, kadalasang ginagamit sa mga application sa pagpoproseso ng signal</string>\n    <string name=\"quadric_sub\">Isang paraan na gumagamit ng quadratic function para sa interpolation, na nagbibigay ng maayos at tuluy-tuloy na mga resulta</string>\n    <string name=\"gaussian_sub\">Isang paraan ng interpolation na naglalapat ng Gaussian function, na kapaki-pakinabang para sa pagpapakinis at pagbabawas ng ingay sa mga larawan</string>\n    <string name=\"sphinx_sub\">Isang advanced na paraan ng resampling na nagbibigay ng mataas na kalidad na interpolation na may kaunting artifact</string>\n    <string name=\"bartlett_sub\">Isang triangular na window function na ginagamit sa pagpoproseso ng signal para mabawasan ang spectral leakage</string>\n    <string name=\"robidoux_sub\">Isang mataas na kalidad na paraan ng interpolation na na-optimize para sa natural na pagbabago ng laki ng imahe, pagbabalanse ng sharpness at smoothness</string>\n    <string name=\"robidoux_sharp_sub\">Isang mas matalas na variant ng Robidoux method, na na-optimize para sa malulutong na pagbabago ng laki ng larawan</string>\n    <string name=\"spline16_sub\">Isang spline-based na interpolation na paraan na nagbibigay ng maayos na resulta gamit ang 16-tap na filter</string>\n    <string name=\"spline36_sub\">Isang spline-based na interpolation na paraan na nagbibigay ng maayos na resulta gamit ang 36-tap na filter</string>\n    <string name=\"spline64_sub\">Isang spline-based na interpolation na paraan na nagbibigay ng maayos na resulta gamit ang 64-tap na filter</string>\n    <string name=\"kaiser_sub\">Isang paraan ng interpolation na gumagamit ng Kaiser window, na nagbibigay ng mahusay na kontrol sa trade-off sa pagitan ng lapad ng main-lobe at side-lobe level</string>\n    <string name=\"bartlett_hann_sub\">Isang hybrid na function ng window na pinagsasama ang mga bintana ng Bartlett at Hann, na ginagamit upang bawasan ang spectral leakage sa pagpoproseso ng signal</string>\n    <string name=\"box_sub\">Isang simpleng paraan ng resampling na gumagamit ng average ng pinakamalapit na mga halaga ng pixel, na kadalasang nagreresulta sa isang blocky na hitsura</string>\n    <string name=\"bohman_sub\">Isang window function na ginagamit upang bawasan ang spectral leakage, na nagbibigay ng magandang frequency resolution sa mga application sa pagpoproseso ng signal</string>\n    <string name=\"lanczos2_sub\">Isang paraan ng resampling na gumagamit ng 2-lobe na Lanczos na filter para sa de-kalidad na interpolation na may kaunting artifact</string>\n    <string name=\"lanczos3_sub\">Isang paraan ng resampling na gumagamit ng 3-lobe na Lanczos na filter para sa mataas na kalidad na interpolation na may kaunting artifact</string>\n    <string name=\"lanczos4_sub\">Isang paraan ng resampling na gumagamit ng 4-lobe Lanczos na filter para sa mataas na kalidad na interpolation na may kaunting artifact</string>\n    <string name=\"lanczos2_jinc_sub\">Isang variant ng filter ng Lanczos 2 na gumagamit ng jinc function, na nagbibigay ng de-kalidad na interpolation na may kaunting artifact.</string>\n    <string name=\"lanczos3_jinc_sub\">Isang variant ng filter ng Lanczos 3 na gumagamit ng jinc function, na nagbibigay ng de-kalidad na interpolation na may kaunting artifact.</string>\n    <string name=\"lanczos4_jinc_sub\">Isang variant ng filter ng Lanczos 4 na gumagamit ng jinc function, na nagbibigay ng de-kalidad na interpolation na may kaunting artifact.</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Elliptical Weighted Average (EWA) na variant ng Hanning filter para sa maayos na interpolation at resampling</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elliptical Weighted Average (EWA) na variant ng Robidoux filter para sa mataas na kalidad na resampling</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Elliptical Weighted Average (EWA) na variant ng Blackman filter para sa pagliit ng mga artifact ng ring</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Elliptical Weighted Average (EWA) na variant ng Quadric na filter para sa maayos na interpolation</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elliptical Weighted Average (EWA) na variant ng Robidoux Sharp filter para sa mas matalas na resulta</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Elliptical Weighted Average (EWA) na variant ng Lanczos 3 Jinc filter para sa mataas na kalidad na resampling na may pinababang aliasing</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Isang resampling filter na idinisenyo para sa mataas na kalidad na pagpoproseso ng imahe na may magandang balanse ng sharpness at smoothness</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Elliptical Weighted Average (EWA) na variant ng Ginseng filter para sa pinahusay na kalidad ng larawan</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Elliptical Weighted Average (EWA) na variant ng Lanczos Sharp filter para sa pagkamit ng matalim na resulta na may kaunting artifact</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Pinakamatalim na EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Elliptical Weighted Average (EWA) na variant ng Lanczos 4 Sharpest na filter para sa sobrang matalas na resampling ng imahe</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptical Weighted Average (EWA) na variant ng Lanczos Soft filter para sa mas maayos na resampling ng imahe</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Isang resampling filter na idinisenyo ni Haasn para sa makinis at walang artifact na pag-scale ng imahe</string>\n    <string name=\"format_conversion\">Conversion ng Format</string>\n    <string name=\"format_conversion_sub\">I-convert ang batch ng mga larawan mula sa isang format patungo sa isa pa</string>\n    <string name=\"dismiss_forever\">Iwaksi ang Magpakailanman</string>\n    <string name=\"image_stacking\">Imahe Stacking</string>\n    <string name=\"image_stacking_sub\">I-stack ang mga larawan sa ibabaw ng bawat isa gamit ang mga piniling blend mode</string>\n    <string name=\"add_image\">Magdagdag ng Larawan</string>\n    <string name=\"bins_count\">Bilang ng mga bin</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">I-equalize ang Histogram Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">I-equalize ang Histogram Adaptive HSV</string>\n    <string name=\"edge_mode\">Edge Mode</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Balutin</string>\n    <string name=\"color_blind_scheme\">Pagkabulag ng kulay</string>\n    <string name=\"color_blind_scheme_sub\">Pumili ng mode para iakma ang mga kulay ng tema para sa napiling variant ng color blindness</string>\n    <string name=\"protanomaly_sub\">Kahirapan sa pagkilala sa pagitan ng pula at berdeng kulay</string>\n    <string name=\"deuteranomaly_sub\">Kahirapan sa pagkilala sa pagitan ng berde at pula na kulay</string>\n    <string name=\"tritanomaly_sub\">Kahirapan sa pagkilala sa pagitan ng asul at dilaw na kulay</string>\n    <string name=\"protanopia_sub\">Kawalan ng kakayahang makita ang mga pulang kulay</string>\n    <string name=\"deuteranopia_sub\">Kawalan ng kakayahang makita ang mga berdeng kulay</string>\n    <string name=\"tritanopia_sub\">Kawalan ng kakayahang makita ang mga asul na kulay</string>\n    <string name=\"achromatomaly_sub\">Nabawasan ang sensitivity sa lahat ng kulay</string>\n    <string name=\"achromatopsia_sub\">Kumpletong color blindness, kulay abo lang ang nakikita</string>\n    <string name=\"not_use_color_blind_scheme\">Huwag gumamit ng Color Blind scheme</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Ang mga kulay ay magiging eksakto sa itinakda sa tema</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Isang Lagrange interpolation filter ng order 2, na angkop para sa de-kalidad na pag-scale ng larawan na may maayos na mga transition</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Isang Lagrange interpolation filter ng order 3, na nag-aalok ng mas mahusay na katumpakan at mas malinaw na mga resulta para sa pag-scale ng imahe</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Isang Lanczos resampling filter na may mas mataas na pagkakasunud-sunod na 6, na nagbibigay ng mas matalas at mas tumpak na pag-scale ng imahe</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Isang variant ng filter ng Lanczos 6 gamit ang Jinc function para sa pinahusay na kalidad ng resampling ng imahe</string>\n    <string name=\"linear_box_blur\">Linear Box Blur</string>\n    <string name=\"linear_tent_blur\">Linear Tent Blur</string>\n    <string name=\"linear_gaussian_box_blur\">Linear Gaussian Box Blur</string>\n    <string name=\"linear_stack_blur\">Linear Stack Blur</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linear Fast Gaussian Blur Susunod</string>\n    <string name=\"linear_fast_gaussian_blur\">Linear Fast Gaussian Blur</string>\n    <string name=\"linear_gaussian_blur\">Linear Gaussian Blur</string>\n    <string name=\"draw_filter_sub\">Pumili ng isang filter upang gamitin ito bilang pintura</string>\n    <string name=\"replace_filter\">Palitan ang Filter</string>\n    <string name=\"pick_filter_info\">Pumili ng filter sa ibaba para gamitin ito bilang brush sa iyong drawing</string>\n    <string name=\"tiff_compression_scheme\">TIFF compression scheme</string>\n    <string name=\"low_poly\">Mababang Poly</string>\n    <string name=\"sand_painting\">Pagpipinta ng Buhangin</string>\n    <string name=\"image_splitting\">Paghahati ng Larawan</string>\n    <string name=\"image_splitting_sub\">Hatiin ang iisang larawan ayon sa mga row o column</string>\n    <string name=\"fit_to_bounds\">Akma sa Hangganan</string>\n    <string name=\"fit_to_bounds_sub\">Pagsamahin ang crop resize mode sa parameter na ito para makamit ang ninanais na gawi (Crop/Fit to aspect ratio)</string>\n    <string name=\"languages_imported\">Matagumpay na na-import ang mga wika</string>\n    <string name=\"backup_ocr_models\">I-backup ang mga modelo ng OCR</string>\n    <string name=\"import_word\">Mag-import</string>\n    <string name=\"export\">I-export</string>\n    <string name=\"position\">Posisyon</string>\n    <string name=\"center\">Gitna</string>\n    <string name=\"top_left\">Kaliwa sa itaas</string>\n    <string name=\"top_right\">Kanan sa itaas</string>\n    <string name=\"bottom_left\">Kaliwa sa ibaba</string>\n    <string name=\"bottom_right\">Kanan sa ibaba</string>\n    <string name=\"top_center\">Nangungunang Center</string>\n    <string name=\"center_right\">Gitnang Kanan</string>\n    <string name=\"bottom_center\">Ibaba Gitna</string>\n    <string name=\"center_left\">Gitnang Kaliwa</string>\n    <string name=\"target_image\">Target na Larawan</string>\n    <string name=\"palette_transfer\">Palette Transfer</string>\n    <string name=\"enhanced_oil\">Pinahusay na Langis</string>\n    <string name=\"simple_old_tv\">Simpleng Lumang TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Simple Sketch</string>\n    <string name=\"soft_glow\">Malambot na Glow</string>\n    <string name=\"color_poster\">Kulay ng Poster</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Pangatlong kulay</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olks</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Clustered 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Clustered 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">Clustered 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Walang napiling mga paboritong opsyon, idagdag ang mga ito sa pahina ng mga tool</string>\n    <string name=\"add_favorites\">Magdagdag ng Mga Paborito</string>\n    <string name=\"harmony_complementary\">Komplementaryo</string>\n    <string name=\"harmony_analogous\">Katulad</string>\n    <string name=\"harmony_triadic\">Triadic</string>\n    <string name=\"harmony_split_complementary\">Split Complementary</string>\n    <string name=\"harmony_tetradic\">Tetradic</string>\n    <string name=\"harmony_square\">parisukat</string>\n    <string name=\"harmony_analogous_complementary\">Analogous + Complementary</string>\n    <string name=\"color_tools\">Mga Tool sa Kulay</string>\n    <string name=\"color_tools_sub\">Paghaluin, gumawa ng mga tono, bumuo ng mga shade at higit pa</string>\n    <string name=\"color_harmonies\">Mga Harmoni ng Kulay</string>\n    <string name=\"color_shading\">Color Shading</string>\n    <string name=\"variation\">pagkakaiba-iba</string>\n    <string name=\"tints\">Tints</string>\n    <string name=\"tones\">Mga tono</string>\n    <string name=\"shades\">Mga shade</string>\n    <string name=\"color_mixing\">Paghahalo ng Kulay</string>\n    <string name=\"color_info\">Impormasyon ng Kulay</string>\n    <string name=\"selected_color\">Napiling Kulay</string>\n    <string name=\"color_to_mix\">Kulay Upang Paghaluin</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Hindi magagamit ang monet habang naka-on ang mga dynamic na kulay</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">I-target ang LUT na imahe</string>\n    <string name=\"amatorka\">Isang baguhan</string>\n    <string name=\"miss_etikate\">Miss Etiquette</string>\n    <string name=\"soft_elegance\">Malambot Elegance</string>\n    <string name=\"soft_elegance_variant\">Soft Elegance na Variant</string>\n    <string name=\"palette_transfer_variant\">Palette Transfer Variant</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Target na 3D LUT File (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Sindi ng kandila</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Nakakabaliw si Amber</string>\n    <string name=\"fall_colors\">Mga Kulay ng Taglagas</string>\n    <string name=\"film_stock_50\">Stock ng Pelikula 50</string>\n    <string name=\"foggy_night\">Mahamog na Gabi</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Kumuha ng Neutral na LUT na imahe</string>\n    <string name=\"save_empty_lut_sub\">Una, gamitin ang iyong paboritong application sa pag-edit ng larawan upang maglapat ng filter sa neutral na LUT na maaari mong makuha dito. Para gumana ito ng maayos, hindi dapat nakadepende ang bawat kulay ng pixel sa iba pang mga pixel (hal. hindi gagana ang blur). Kapag handa na, gamitin ang iyong bagong LUT na imahe bilang input para sa 512*512 LUT filter</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"coffee\">kape</string>\n    <string name=\"golden_forest\">Gintong Kagubatan</string>\n    <string name=\"greenish\">Maberde</string>\n    <string name=\"retro_yellow\">Retro Yellow</string>\n    <string name=\"links_preview\">Preview ng Mga Link</string>\n    <string name=\"links_preview_sub\">Pinapagana ang pagbawi ng preview ng link sa mga lugar kung saan makakakuha ka ng text (QRCode, OCR atbp)</string>\n    <string name=\"links\">Mga link</string>\n    <string name=\"ico_size_warning\">Ang mga ICO file ay maaari lamang i-save sa maximum na laki na 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF sa WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">I-convert ang mga larawang GIF sa mga animated na larawan ng WEBP</string>\n    <string name=\"webp_tools\">Mga Tool sa WEBP</string>\n    <string name=\"webp_tools_sub\">I-convert ang mga larawan sa WEBP animated na larawan o kunin ang mga frame mula sa ibinigay na WEBP animation</string>\n    <string name=\"webp_type_to_image\">WEBP sa mga larawan</string>\n    <string name=\"webp_type_to_image_sub\">I-convert ang WEBP file sa batch ng mga larawan</string>\n    <string name=\"webp_type_to_webp_sub\">I-convert ang batch ng mga larawan sa WEBP file</string>\n    <string name=\"webp_type_to_webp\">Mga larawan sa WEBP</string>\n    <string name=\"select_webp_image_to_start\">Pumili ng WEBP image para magsimula</string>\n    <string name=\"manage_storage_extra_types\">Walang ganap na access sa mga file</string>\n    <string name=\"manage_storage_extra_types_sub\">Payagan ang lahat ng mga file na ma-access upang makita ang JXL, QOI at iba pang mga larawan na hindi kinikilala bilang mga larawan sa Android. Kung walang pahintulot ang Image Toolbox ay hindi maipakita ang mga larawang iyon</string>\n    <string name=\"default_draw_color\">Default na Kulay ng Draw</string>\n    <string name=\"default_draw_path_mode\">Default na Draw Path Mode</string>\n    <string name=\"add_timestamp\">Magdagdag ng Timestamp</string>\n    <string name=\"add_timestamp_sub\">Pinapagana ang pagdaragdag ng Timestamp sa output filename</string>\n    <string name=\"formatted_timestamp\">Naka-format na Timestamp</string>\n    <string name=\"formatted_timestamp_sub\">Paganahin ang pag-format ng Timestamp sa output filename sa halip na mga pangunahing millis</string>\n    <string name=\"enable_timestamps_to_format_them\">Paganahin ang mga Timestamp upang piliin ang kanilang format</string>\n    <string name=\"one_time_save_location\">Isang Oras na I-save ang Lokasyon</string>\n    <string name=\"one_time_save_location_sub\">Tingnan at I-edit ang isang beses na i-save ang mga lokasyon na maaari mong gamitin sa pamamagitan ng mahabang pagpindot sa save button sa halos lahat ng mga opsyon</string>\n    <string name=\"recently_used\">Kamakailang Ginamit</string>\n    <string name=\"ci_channel\">CI channel</string>\n    <string name=\"group\">Grupo</string>\n    <string name=\"image_toolbox_in_telegram\">Toolbox ng Larawan sa Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Sumali sa aming chat kung saan maaari mong pag-usapan ang anumang gusto mo at tingnan din ang CI channel kung saan ako nagpo-post ng mga beta at anunsyo</string>\n    <string name=\"ci_channel_sub\">Maabisuhan tungkol sa mga bagong bersyon ng app, at magbasa ng mga anunsyo</string>\n    <string name=\"fit_description\">Pagkasyahin ang isang larawan sa mga ibinigay na dimensyon at ilapat ang blur o kulay sa background</string>\n    <string name=\"tools_arrangement\">Pag-aayos ng mga Tool</string>\n    <string name=\"group_tools_by_type\">Pangkatin ang mga tool ayon sa uri</string>\n    <string name=\"group_tools_by_type_sub\">Mga tool sa pangkat sa pangunahing screen ayon sa kanilang uri sa halip na isang pasadyang pag-aayos ng listahan</string>\n    <string name=\"default_values\">Mga Default na Halaga</string>\n    <string name=\"system_bars_visibility\">Visibility ng System Bar</string>\n    <string name=\"show_system_bars_by_swipe\">Ipakita ang System Bars Sa pamamagitan ng Swipe</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Pinapagana ang pag-swipe para ipakita ang mga system bar kung nakatago ang mga ito</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Itago Lahat</string>\n    <string name=\"show_all\">Ipakita ang Lahat</string>\n    <string name=\"hide_nav_bar\">Itago ang Nav Bar</string>\n    <string name=\"hide_status_bar\">Itago ang Status Bar</string>\n    <string name=\"noise_generation\">Pagbuo ng Ingay</string>\n    <string name=\"noise_generation_sub\">Bumuo ng iba\\'t ibang ingay tulad ng Perlin o iba pang uri</string>\n    <string name=\"frequency\">Dalas</string>\n    <string name=\"noise_type\">Uri ng Ingay</string>\n    <string name=\"rotation_type\">Uri ng Pag-ikot</string>\n    <string name=\"fractal_type\">Uri ng Fractal</string>\n    <string name=\"octaves\">Mga oktaba</string>\n    <string name=\"lacunarity\">Kakulangan</string>\n    <string name=\"gain\">Makakuha</string>\n    <string name=\"weighted_strength\">Timbang Lakas</string>\n    <string name=\"ping_pong_strength\">Lakas ng Ping Pong</string>\n    <string name=\"distance_function\">Distansya Function</string>\n    <string name=\"return_type\">Uri ng Pagbabalik</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"alignment\">Pag-align</string>\n    <string name=\"custom_filename\">Custom na Filename</string>\n    <string name=\"custom_filename_sub\">Piliin ang lokasyon at filename na gagamitin para i-save ang kasalukuyang larawan</string>\n    <string name=\"saved_to_custom\">Na-save sa folder na may custom na pangalan</string>\n    <string name=\"collage_maker\">Collage Maker</string>\n    <string name=\"collage_maker_sub\">Gumawa ng mga collage mula sa hanggang 20 larawan</string>\n    <string name=\"collage_type\">Uri ng Collage</string>\n    <string name=\"collages_info\">I-hold ang imahe upang magpalit, ilipat at mag-zoom upang ayusin ang posisyon</string>\n    <string name=\"disable_rotation\">Huwag paganahin ang pag-ikot</string>\n    <string name=\"disable_rotation_sub\">Pinipigilan ang pag-ikot ng mga larawan gamit ang dalawang daliri na mga galaw</string>\n    <string name=\"enable_snapping_to_borders\">Paganahin ang pag-snap sa mga hangganan</string>\n    <string name=\"enable_snapping_to_borders_sub\">Pagkatapos gumalaw o mag-zoom, kukunin ang mga larawan upang punan ang mga gilid ng frame</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">RGB o Brightness image histogram upang matulungan kang gumawa ng mga pagsasaayos</string>\n    <string name=\"image_for_histogram\">Gagamitin ang larawang ito upang makabuo ng mga histogram ng RGB at Brightness</string>\n    <string name=\"tesseract_options\">Mga Pagpipilian sa Tesseract</string>\n    <string name=\"tesseract_options_sub\">Ilapat ang ilang input variable para sa tesseract engine</string>\n    <string name=\"custom_options\">Mga Pasadyang Opsyon</string>\n    <string name=\"custom_params_info\">Dapat ipasok ang mga opsyon ayon sa pattern na ito: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Auto I-crop</string>\n    <string name=\"free_corners\">Libreng Corners</string>\n    <string name=\"free_corners_sub\">I-crop ang imahe sa pamamagitan ng polygon, itinutuwid din nito ang pananaw</string>\n    <string name=\"coerce_points_to_image_bounds\">Pilitin ang mga Punto Sa Mga Hangganan ng Imahe</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Ang mga puntos ay hindi lilimitahan ng mga hangganan ng larawan, ito ay kapaki-pakinabang para sa mas tumpak na pagwawasto ng pananaw</string>\n    <string name=\"mask\">maskara</string>\n    <string name=\"spot_heal_sub\">Punan ng kaalaman sa nilalaman sa ilalim ng iginuhit na landas</string>\n    <string name=\"spot_heal\">Pagalingin ang Spot</string>\n    <string name=\"use_circle_kernel\">Gamitin ang Circle Kernel</string>\n    <string name=\"opening\">Pagbubukas</string>\n    <string name=\"closing\">Pagsasara</string>\n    <string name=\"morphological_gradient\">Morphological Gradient</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Itim na Sombrero</string>\n    <string name=\"tone_curves\">Mga Kurba ng Tono</string>\n    <string name=\"reset_curves\">I-reset ang Curves</string>\n    <string name=\"reset_curves_sub\">Ang mga curve ay ibabalik sa default na halaga</string>\n    <string name=\"line_style\">Estilo ng Linya</string>\n    <string name=\"gap_size\">Laki ng Gap</string>\n    <string name=\"dashed\">Dashed</string>\n    <string name=\"dot_dashed\">Dot Dashed</string>\n    <string name=\"stamped\">Nakatatak</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Gumuhit ng dashed line sa kahabaan ng iginuhit na landas na may tinukoy na laki ng gap</string>\n    <string name=\"dot_dashed_sub\">Gumuguhit ng tuldok at putol-putol na linya sa ibinigay na landas</string>\n    <string name=\"defaultt_sub\">Mga tuwid na linya lang ang default</string>\n    <string name=\"stamped_sub\">Gumuguhit ng mga napiling hugis sa landas na may tinukoy na espasyo</string>\n    <string name=\"zigzag_sub\">Gumuguhit ng kulot na zigzag sa daan</string>\n    <string name=\"zigzag_ratio\">Zigzag ratio</string>\n    <string name=\"create_shortcut\">Lumikha ng Shortcut</string>\n    <string name=\"create_shortcut_title\">Pumili ng tool upang i-pin</string>\n    <string name=\"create_shortcut_subtitle\">Idaragdag ang tool sa home screen ng iyong launcher bilang shortcut, gamitin ito kasama ng setting na \\\"Laktawan ang pagpili ng file\\\" upang makamit ang kinakailangang gawi</string>\n    <string name=\"dont_stack_frames\">Huwag mag-stack ng mga frame</string>\n    <string name=\"dont_stack_frames_sub\">Ine-enable ang pagtatapon ng mga nakaraang frame, para hindi mag-stack ang mga ito sa isa\\'t isa</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Ang mga frame ay magiging crossfaded sa isa\\'t isa</string>\n    <string name=\"crossfade_count\">Bilang ng mga crossfade na frame</string>\n    <string name=\"threshold_one\">Unang Threshold</string>\n    <string name=\"threshold_two\">Ikalawang Threshold</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Salamin 101</string>\n    <string name=\"enhanced_zoom_blur\">Pinahusay na Zoom Blur</string>\n    <string name=\"laplacian_simple\">Laplacian Simple</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Helper Grid</string>\n    <string name=\"helper_grid_sub\">Nagpapakita ng pagsuporta sa grid sa itaas ng drawing area upang makatulong sa mga tumpak na manipulasyon</string>\n    <string name=\"grid_color\">Kulay ng Grid</string>\n    <string name=\"cell_width\">Lapad ng Cell</string>\n    <string name=\"cell_height\">Taas ng Cell</string>\n    <string name=\"compact_selectors\">Mga Compact Selector</string>\n    <string name=\"compact_selectors_sub\">Ang ilang mga kontrol sa pagpili ay gagamit ng isang compact na layout upang kumuha ng mas kaunting espasyo</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Magbigay ng pahintulot sa camera sa mga setting para kumuha ng larawan</string>\n    <string name=\"layout\">Layout</string>\n    <string name=\"main_screen_title\">Pangunahing Pamagat ng Screen</string>\n    <string name=\"constant_rate_factor\">Constant Rate Factor (CRF)</string>\n    <string name=\"crf_sub\">Ang halaga ng %1$s ay nangangahulugang isang mabagal na pag-compress, na nagreresulta sa isang medyo maliit na laki ng file. Ang ibig sabihin ng %2$s ay isang mas mabilis na compression, na nagreresulta sa isang malaking file.</string>\n    <string name=\"lut_library\">Lut Library</string>\n    <string name=\"lut_library_sub\">I-download ang koleksyon ng mga LUT, na maaari mong ilapat pagkatapos mag-download</string>\n    <string name=\"lut_library_update_sub\">I-update ang koleksyon ng mga LUT (mga bago lang ang ipi-queue), na maaari mong ilapat pagkatapos mag-download</string>\n    <string name=\"filter_preview_image_sub\">Baguhin ang default na preview ng larawan para sa mga filter</string>\n    <string name=\"filter_preview_image\">I-preview ang Larawan</string>\n    <string name=\"hide\">Magtago</string>\n    <string name=\"show\">Ipakita</string>\n    <string name=\"slider_type\">Uri ng Slider</string>\n    <string name=\"fancy\">Fancy</string>\n    <string name=\"material_2\">Materyal 2</string>\n    <string name=\"fancy_sub\">Isang magarbong slider. Ito ang default na opsyon</string>\n    <string name=\"material_2_sub\">Isang Materyal 2 slider</string>\n    <string name=\"material_you_slider_sub\">Isang Materyal Iyong slider</string>\n    <string name=\"apply\">Mag-apply</string>\n    <string name=\"center_align_dialog_buttons\">Mga Pindutan ng Dialog sa Gitnang</string>\n    <string name=\"center_align_dialog_buttons_sub\">Ang mga pindutan ng mga dialog ay ipoposisyon sa gitna sa halip na sa kaliwang bahagi kung maaari</string>\n    <string name=\"open_source_licenses\">Mga Lisensya sa Open Source</string>\n    <string name=\"open_source_licenses_sub\">Tingnan ang mga lisensya ng mga open source na library na ginagamit sa app na ito</string>\n    <string name=\"area\">Lugar</string>\n    <string name=\"area_sub\">Resampling gamit ang pixel area relation. Ito ay maaaring isang ginustong paraan para sa pag-decimation ng imahe, dahil nagbibigay ito ng moire\\'-free na mga resulta. Ngunit kapag ang imahe ay naka-zoom, ito ay katulad ng \\\"Nearest\\\" na paraan.</string>\n    <string name=\"enable_tonemapping\">Paganahin ang Tonemapping</string>\n    <string name=\"enter_percent\">Ipasok ang %</string>\n    <string name=\"unknown_host\">Hindi ma-access ang site, subukang gumamit ng VPN o tingnan kung tama ang url</string>\n    <string name=\"markup_layers\">Mga Markup Layer</string>\n    <string name=\"markup_layers_sub\">Layers mode na may kakayahang malayang maglagay ng mga larawan, teksto at higit pa</string>\n    <string name=\"edit_layer\">I-edit ang layer</string>\n    <string name=\"layers_on_image\">Mga layer sa larawan</string>\n    <string name=\"layers_on_image_sub\">Gumamit ng isang imahe bilang isang background at magdagdag ng iba\\'t ibang mga layer sa ibabaw nito</string>\n    <string name=\"layers_on_background\">Mga layer sa background</string>\n    <string name=\"layers_on_background_sub\">Pareho sa unang opsyon ngunit may kulay sa halip na larawan</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Gilid ng Mabilis na Mga Setting</string>\n    <string name=\"fast_settings_side_sub\">Magdagdag ng lumulutang na strip sa napiling gilid habang nag-e-edit ng mga larawan, na magbubukas ng mabilis na mga setting kapag na-click</string>\n    <string name=\"clear_selection\">I-clear ang pagpili</string>\n    <string name=\"settings_group_visibility_hidden\">Ang pagtatakda ng pangkat na \\\"%1$s\\\" ay iko-collapse bilang default</string>\n    <string name=\"settings_group_visibility_visible\">Ang pagtatakda ng pangkat na \\\"%1$s\\\" ay palalawakin bilang default</string>\n    <string name=\"base_64_tools\">Mga Tool sa Base64</string>\n    <string name=\"base_64_tools_sub\">I-decode ang Base64 string sa imahe, o i-encode ang imahe sa Base64 na format</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">Ang ibinigay na halaga ay hindi wastong Base64 string</string>\n    <string name=\"copy_not_a_valid_base_64\">Hindi makopya ang walang laman o di-wastong Base64 string</string>\n    <string name=\"paste_base_64\">Idikit ang Base64</string>\n    <string name=\"copy_base_64\">Copy Base64</string>\n    <string name=\"base_64_tips\">Mag-load ng larawan para kopyahin o i-save ang Base64 string. Kung mayroon kang mismong string, maaari mo itong i-paste sa itaas upang makakuha ng larawan</string>\n    <string name=\"save_base_64\">I-save ang Base64</string>\n    <string name=\"share_base_64\">Ibahagi ang Base64</string>\n    <string name=\"options\">Mga pagpipilian</string>\n    <string name=\"actions\">Mga aksyon</string>\n    <string name=\"import_base_64\">Import Base64</string>\n    <string name=\"base_64_actions\">Base64 na Mga Aksyon</string>\n    <string name=\"add_outline\">Magdagdag ng Balangkas</string>\n    <string name=\"add_outline_sub\">Magdagdag ng outline sa paligid ng teksto na may tinukoy na kulay at lapad</string>\n    <string name=\"outline_color\">Kulay ng Balangkas</string>\n    <string name=\"outline_size\">Laki ng Balangkas</string>\n    <string name=\"rotation\">Pag-ikot</string>\n    <string name=\"checksum_as_filename\">Checksum bilang Filename</string>\n    <string name=\"checksum_as_filename_sub\">Ang mga imahe ng output ay magkakaroon ng pangalang naaayon sa kanilang data checksum</string>\n    <string name=\"free_software_partner\">Libreng Software (Kasosyo)</string>\n    <string name=\"free_software_partner_sub\">Mas kapaki-pakinabang na software sa partner channel ng mga Android application</string>\n    <string name=\"algorithms\">Algorithm</string>\n    <string name=\"checksum_tools\">Mga Tool sa Checksum</string>\n    <string name=\"checksum_tools_sub\">Paghambingin ang mga checksum, kalkulahin ang mga hash o gumawa ng mga hex string mula sa mga file gamit ang iba\\'t ibang algorithm ng hashing</string>\n    <string name=\"calculate\">Kalkulahin</string>\n    <string name=\"text_hash\">I-text ang Hash</string>\n    <string name=\"checksum\">Checksum</string>\n    <string name=\"pick_file_to_checksum\">Pumili ng file para kalkulahin ang checksum nito batay sa napiling algorithm</string>\n    <string name=\"enter_text_to_checksum\">Maglagay ng text para kalkulahin ang checksum nito batay sa napiling algorithm</string>\n    <string name=\"source_checksum\">Pinagmulan Checksum</string>\n    <string name=\"checksum_to_compare\">Checksum Upang Paghambingin</string>\n    <string name=\"match\">Match!</string>\n    <string name=\"difference\">Pagkakaiba</string>\n    <string name=\"match_sub\">Ang mga checksum ay pantay, maaari itong maging ligtas</string>\n    <string name=\"difference_sub\">Ang mga checksum ay hindi pantay, ang file ay maaaring hindi ligtas!</string>\n    <string name=\"mesh_gradients\">Mesh Gradients</string>\n    <string name=\"collection_mesh_gradients_sub\">Tumingin sa online na koleksyon ng Mesh Gradients</string>\n    <string name=\"wrong_font\">Tanging mga TTF at OTF na font ang maaaring ma-import</string>\n    <string name=\"import_font\">Mag-import ng font (TTF/OTF)</string>\n    <string name=\"export_fonts\">I-export ang mga font</string>\n    <string name=\"imported_fonts\">Mga na-import na font</string>\n    <string name=\"error_while_saving\">Error habang nagse-save ng pagtatangka, subukang baguhin ang folder ng output</string>\n    <string name=\"filename_is_not_set\">Hindi nakatakda ang filename</string>\n    <string name=\"none\">wala</string>\n    <string name=\"custom_pages\">Mga Custom na Pahina</string>\n    <string name=\"pages_selection\">Pagpili ng Mga Pahina</string>\n    <string name=\"tool_exit_confirmation\">Kumpirmasyon sa Paglabas ng Tool</string>\n    <string name=\"tool_exit_confirmation_sub\">Kung mayroon kang mga hindi na-save na pagbabago habang gumagamit ng mga partikular na tool at subukang isara ito, pagkatapos ay ipapakita ang dialog na kumpirmahin</string>\n    <string name=\"edit_exif_screen\">I-edit ang EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Baguhin ang metadata ng isang larawan nang walang recompression</string>\n    <string name=\"edit_exif_tag\">I-tap para i-edit ang mga available na tag</string>\n    <string name=\"change_sticker\">Palitan ang Sticker</string>\n    <string name=\"fit_width\">Pagkasyahin ang Lapad</string>\n    <string name=\"fit_height\">Tamang-tama sa Taas</string>\n    <string name=\"batch_compare\">Batch Compare</string>\n    <string name=\"pick_files_to_checksum\">Pumili ng file/file para kalkulahin ang checksum nito batay sa napiling algorithm</string>\n    <string name=\"pick_files\">Pumili ng Mga File</string>\n    <string name=\"pick_directory\">Pumili ng Direktoryo</string>\n    <string name=\"head_length_scale\">Scale ng Haba ng Ulo</string>\n    <string name=\"stamp\">selyo</string>\n    <string name=\"timestamp\">Timestamp</string>\n    <string name=\"format_pattern\">Pattern ng Format</string>\n    <string name=\"padding\">Padding</string>\n    <string name=\"image_cutting\">Pagputol ng Larawan</string>\n    <string name=\"image_cutting_sub\">Gupitin ang bahagi ng larawan at pagsamahin ang mga kaliwa (maaaring baligtad) sa pamamagitan ng patayo o pahalang na mga linya</string>\n    <string name=\"vertical_pivot_line\">Vertical Pivot Line</string>\n    <string name=\"horizontal_pivot_line\">Pahalang na Pivot Line</string>\n    <string name=\"inverse_selection\">Baliktad na Pagpili</string>\n    <string name=\"inverse_vertical_selection_sub\">Ang bahaging patayong hiwa ay iiwanan, sa halip na pagsamahin ang mga bahagi sa paligid ng lugar ng hiwa</string>\n    <string name=\"inverse_horizontal_selection_sub\">Iiwan ang pahalang na bahagi ng hiwa, sa halip na pagsamahin ang mga bahagi sa paligid ng hiwa</string>\n    <string name=\"collection_mesh_gradients\">Koleksyon ng Mesh Gradients</string>\n    <string name=\"mesh_gradients_sub\">Gumawa ng mesh gradient na may custom na dami ng mga buhol at resolution</string>\n    <string name=\"gradient_maker_type_image_mesh\">Mesh Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Gumawa ng mesh gradient ng tuktok ng mga ibinigay na larawan</string>\n    <string name=\"points_customization\">Pag-customize ng mga puntos</string>\n    <string name=\"grid_size\">Sukat ng Grid</string>\n    <string name=\"resolution_x\">Resolusyon X</string>\n    <string name=\"resolution_y\">Resolusyon Y</string>\n    <string name=\"resolution\">Resolusyon</string>\n    <string name=\"pixel_by_pixel\">Pixel Sa Pixel</string>\n    <string name=\"highlight_color\">Kulay ng Highlight</string>\n    <string name=\"pixel_comparison_type\">Uri ng Paghahambing ng Pixel</string>\n    <string name=\"scan_barcode\">I-scan ang barcode</string>\n    <string name=\"height_ratio\">Ratio ng Taas</string>\n    <string name=\"barcode_type\">Uri ng Barcode</string>\n    <string name=\"enforce_bw\">Ipatupad ang B/W</string>\n    <string name=\"enforce_bw_sub\">Ang Larawan ng Barcode ay magiging ganap na itim at puti at hindi makulayan ng tema ng app</string>\n    <string name=\"barcodes_sub\">I-scan ang anumang Barcode (QR, EAN, AZTEC, …) at kunin ang nilalaman nito o i-paste ang iyong teksto upang makabuo ng bago</string>\n    <string name=\"no_barcode_found\">Walang Nakitang Barcode</string>\n    <string name=\"generated_barcode_will_be_here\">Naririto ang Binuo na Barcode</string>\n    <string name=\"audio_cover_extractor\">Mga Audio Cover</string>\n    <string name=\"audio_cover_extractor_sub\">I-extract ang mga larawan sa pabalat ng album mula sa mga audio file, karamihan sa mga karaniwang format ay sinusuportahan</string>\n    <string name=\"pick_audio_to_start\">Pumili ng audio para magsimula</string>\n    <string name=\"pick_audio\">Pumili ng Audio</string>\n    <string name=\"no_covers_found\">Walang Nahanap na Cover</string>\n    <string name=\"send_logs\">Magpadala ng mga Log</string>\n    <string name=\"send_logs_sub\">I-click upang ibahagi ang file ng mga log ng app, makakatulong ito sa akin na makita ang problema at ayusin ang mga isyu</string>\n    <string name=\"crash_title\">Oops… Nagkaproblema</string>\n    <string name=\"crash_subtitle\">Maaari kang makipag-ugnayan sa akin gamit ang mga opsyon sa ibaba at susubukan kong maghanap ng solusyon.\\n(Huwag kalimutang mag-attach ng mga log)</string>\n    <string name=\"ocr_write_to_file\">Sumulat sa File</string>\n    <string name=\"ocr_write_to_file_sub\">I-extract ang text mula sa batch ng mga imahe at iimbak ito sa isang text file</string>\n    <string name=\"ocr_write_to_metadata\">Sumulat sa Metadata</string>\n    <string name=\"ocr_write_to_metadata_sub\">I-extract ang text mula sa bawat larawan at ilagay ito sa EXIF ​​na impormasyon ng mga kamag-anak na larawan</string>\n    <string name=\"invisible_mode\">Invisible Mode</string>\n    <string name=\"invisible_mode_sub\">Gumamit ng steganography upang lumikha ng mga hindi nakikitang watermark ng mata sa loob ng mga byte ng iyong mga larawan</string>\n    <string name=\"use_lsb\">Gumamit ng LSB</string>\n    <string name=\"use_lsb_sub\">LSB (Less Significant Bit) steganography method ang gagamitin, FD (Frequency Domain) kung hindi.</string>\n    <string name=\"auto_remove_red_eyes\">Awtomatikong Alisin ang Mga Pulang Mata</string>\n    <string name=\"password\">Password</string>\n    <string name=\"unlock\">I-unlock</string>\n    <string name=\"pdf_is_protected\">Pinoprotektahan ang PDF</string>\n    <string name=\"operation_almost_complete\">Halos kumpleto ang operasyon. Ang pagkansela ngayon ay mangangailangan ng pag-restart nito</string>\n    <string name=\"sort_by_date_modified\">Petsa ng Binago</string>\n    <string name=\"sort_by_date_modified_reversed\">Petsa ng Binago (Binaliktad)</string>\n    <string name=\"sort_by_size\">Sukat</string>\n    <string name=\"sort_by_size_reversed\">Sukat (Baliktad)</string>\n    <string name=\"sort_by_mime_type\">Uri ng MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Uri ng MIME (Baliktad)</string>\n    <string name=\"sort_by_extension\">Extension</string>\n    <string name=\"sort_by_extension_reversed\">Extension (Baliktad)</string>\n    <string name=\"sort_by_date_added\">Petsa ng Idinagdag</string>\n    <string name=\"sort_by_date_added_reversed\">Petsa ng Pagdagdag (Binaliktad)</string>\n    <string name=\"left_to_right\">Kaliwa hanggang Kanan</string>\n    <string name=\"right_to_left\">Kanan papuntang Kaliwa</string>\n    <string name=\"top_to_bottom\">Itaas hanggang Ibaba</string>\n    <string name=\"bottom_to_top\">Ibaba hanggang Itaas</string>\n    <string name=\"liquid_glass\">Liquid na Salamin</string>\n    <string name=\"liquid_glass_sub\">Isang switch batay sa kamakailang inihayag na IOS 26 at ang sistema ng disenyo ng likidong salamin nito</string>\n    <string name=\"pick_image_or_base64\">Pumili ng larawan o i-paste/i-import ang Base64 data sa ibaba</string>\n    <string name=\"type_image_link\">I-type ang link ng larawan upang magsimula</string>\n    <string name=\"paste_link\">Idikit ang link</string>\n    <string name=\"kaleidoscope\">Kaleidoscope</string>\n    <string name=\"secondary_angle\">Pangalawang anggulo</string>\n    <string name=\"sides\">Mga gilid</string>\n    <string name=\"channel_mix\">Channel Mix</string>\n    <string name=\"blue_green\">Asul na berde</string>\n    <string name=\"red_blue\">Pulang asul</string>\n    <string name=\"green_red\">Berdeng pula</string>\n    <string name=\"into_red\">Sa pula</string>\n    <string name=\"into_green\">Sa berde</string>\n    <string name=\"into_blue\">Sa asul</string>\n    <string name=\"cyan\">Cyan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Dilaw</string>\n    <string name=\"color_halftone\">Kulay Halftone</string>\n    <string name=\"contour\">Contour</string>\n    <string name=\"levels\">Mga antas</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Nag-kristal ang Voronoi</string>\n    <string name=\"shape\">Hugis</string>\n    <string name=\"stretch\">Mag-stretch</string>\n    <string name=\"randomness\">pagiging random</string>\n    <string name=\"despeckle\">Despeckle</string>\n    <string name=\"diffuse\">Nagkakalat</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Pangalawang radius</string>\n    <string name=\"equalize\">Magpantay</string>\n    <string name=\"glow\">kumikinang</string>\n    <string name=\"whirl_and_pinch\">Whirl and Pinch</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">Kulay ng hangganan</string>\n    <string name=\"polar_coordinates\">Mga Polar Coordinate</string>\n    <string name=\"rect_to_polar\">Rect sa polar</string>\n    <string name=\"polar_to_rect\">Polar sa rect</string>\n    <string name=\"invert_in_circle\">Baliktarin sa bilog</string>\n    <string name=\"reduce_noise\">Bawasan ang Ingay</string>\n    <string name=\"simple_solarize\">Simpleng Solarize</string>\n    <string name=\"weave\">Paghahabi</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X Lapad</string>\n    <string name=\"y_wdth\">Y Lapad</string>\n    <string name=\"twirl\">Umikot</string>\n    <string name=\"rubber_stmp\">Rubber Stamp</string>\n    <string name=\"smear\">Pahid</string>\n    <string name=\"density\">Densidad</string>\n    <string name=\"mix\">Paghaluin</string>\n    <string name=\"sphere_lensh_distortion\">Distortion ng Sphere Lens</string>\n    <string name=\"refraction_index\">Index ng repraksyon</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Spread anggulo</string>\n    <string name=\"sparkle\">Kislap</string>\n    <string name=\"rays\">Sinag</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Mary</string>\n    <string name=\"autumn\">taglagas</string>\n    <string name=\"bone\">buto</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Taglamig</string>\n    <string name=\"ocean\">Karagatan</string>\n    <string name=\"summer\">Tag-init</string>\n    <string name=\"spring\">tagsibol</string>\n    <string name=\"cool_variant\">Cool na Variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rosas</string>\n    <string name=\"hot\">Mainit</string>\n    <string name=\"parula\">salita</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Mga mamamayan</string>\n    <string name=\"twilight\">takipsilim</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Pananaw Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Payagan ang pag-crop</string>\n    <string name=\"crop_or_perspective\">I-crop o Pananaw</string>\n    <string name=\"absolute\">Ganap</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Deep Green</string>\n    <string name=\"lens_correction\">Pagwawasto ng Lens</string>\n    <string name=\"target_lens_profile\">Target na file ng profile ng lens sa JSON format</string>\n    <string name=\"download_ready_lens_profiles\">Mag-download ng mga ready lens profile</string>\n    <string name=\"part_percents\">Mga porsyento ng bahagi</string>\n    <string name=\"export_as_json\">I-export bilang JSON</string>\n    <string name=\"export_as_json_sub\">Kopyahin ang string na may data ng palette bilang representasyon ng json</string>\n    <string name=\"seam_carving\">Pag-ukit ng tahi</string>\n    <string name=\"home_screen\">Home Screen</string>\n    <string name=\"lock_screen\">Lock Screen</string>\n    <string name=\"built_in\">Naka-built-in</string>\n    <string name=\"wallpapers_export\">Mga Wallpaper Export</string>\n    <string name=\"refresh\">I-refresh</string>\n    <string name=\"wallpapers_export_sub\">Kumuha ng kasalukuyang Home, Lock at Built-in na wallpaper</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Payagan ang pag-access sa lahat ng mga file, ito ay kinakailangan upang makuha ang mga wallpaper</string>\n    <string name=\"allow_read_media_images_for_wp\">Hindi sapat ang pahintulot na pamahalaan ang panlabas na storage, kailangan mong payagan ang pag-access sa iyong mga larawan, tiyaking piliin ang \\\"Pahintulutan ang lahat\\\"</string>\n    <string name=\"add_preset_to_filename\">Magdagdag ng Preset Sa Filename</string>\n    <string name=\"add_preset_to_filename_sub\">Nagdaragdag ng suffix na may napiling preset sa image filename</string>\n    <string name=\"add_image_scale_mode_to_filename\">Magdagdag ng Image Scale Mode Sa Filename</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Nagdaragdag ng suffix na may napiling mode ng scale ng imahe sa filename ng imahe</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">I-convert ang larawan sa ascii text na magmumukhang larawan</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Naglalapat ng negatibong filter sa larawan para sa mas magandang resulta sa ilang sitwasyon</string>\n    <string name=\"processing_screenshot\">Pinoproseso ang screenshot</string>\n    <string name=\"screenshot_not_captured_try_again\">Hindi nakuha ang screenshot, subukang muli</string>\n    <string name=\"skipped_saving\">Nilaktawan ang pag-save</string>\n    <string name=\"skipped_saving_multiple\">Nilaktawan ang %1$s file</string>\n    <string name=\"allow_skip_if_larger\">Payagan ang Laktawan Kung Mas Malaki</string>\n    <string name=\"allow_skip_if_larger_sub\">Ang ilang mga tool ay papayagan na laktawan ang pag-save ng mga imahe kung ang resultang laki ng file ay mas malaki kaysa sa orihinal</string>\n    <string name=\"qr_type_calendar_event\">Kaganapan sa Kalendaryo</string>\n    <string name=\"qr_type_contact_info\">Makipag-ugnayan</string>\n    <string name=\"qr_type_email\">Email</string>\n    <string name=\"qr_type_geo_point\">Lokasyon</string>\n    <string name=\"qr_type_phone\">Telepono</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Buksan ang network</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telepono</string>\n    <string name=\"message\">Mensahe</string>\n    <string name=\"address\">Address</string>\n    <string name=\"subject\">Paksa</string>\n    <string name=\"body\">Katawan</string>\n    <string name=\"name\">Pangalan</string>\n    <string name=\"organization\">Organisasyon</string>\n    <string name=\"title\">Pamagat</string>\n    <string name=\"phones\">Mga telepono</string>\n    <string name=\"emails\">Mga email</string>\n    <string name=\"urls\">Mga URL</string>\n    <string name=\"addresses\">Mga address</string>\n    <string name=\"summary\">Buod</string>\n    <string name=\"description\">Paglalarawan</string>\n    <string name=\"location\">Lokasyon</string>\n    <string name=\"organizer\">Organizer</string>\n    <string name=\"start_date\">Petsa ng pagsisimula</string>\n    <string name=\"end_date\">Petsa ng pagtatapos</string>\n    <string name=\"status\">Katayuan</string>\n    <string name=\"latitude\">Latitude</string>\n    <string name=\"longitude\">Longitude</string>\n    <string name=\"create_barcode\">Lumikha ng Barcode</string>\n    <string name=\"edit_barcode\">I-edit ang Barcode</string>\n    <string name=\"wifi_configuration\">configuration ng Wi-Fi</string>\n    <string name=\"security\">Seguridad</string>\n    <string name=\"pick_contact\">Pumili ng contact</string>\n    <string name=\"grant_contact_permission\">Bigyan ang mga contact ng pahintulot sa mga setting na mag-autofill gamit ang napiling contact</string>\n    <string name=\"contact_info\">Impormasyon sa pakikipag-ugnayan</string>\n    <string name=\"first_name\">Pangalan</string>\n    <string name=\"middle_name\">Gitnang pangalan</string>\n    <string name=\"last_name\">apelyido</string>\n    <string name=\"pronunciation\">Pagbigkas</string>\n    <string name=\"add_phone\">Magdagdag ng telepono</string>\n    <string name=\"add_email\">Magdagdag ng email</string>\n    <string name=\"add_address\">Magdagdag ng address</string>\n    <string name=\"website\">Website</string>\n    <string name=\"add_website\">Magdagdag ng website</string>\n    <string name=\"formatted_name\">Naka-format na pangalan</string>\n    <string name=\"qr_code_top_image\">Ang larawang ito ay gagamitin upang ilagay sa itaas ng barcode</string>\n    <string name=\"code_customization\">Pag-customize ng code</string>\n    <string name=\"qr_logo_image\">Gagamitin ang larawang ito bilang logo sa gitna ng QR code</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo padding</string>\n    <string name=\"logo_size\">Laki ng logo</string>\n    <string name=\"logo_corners\">Mga sulok ng logo</string>\n    <string name=\"fourth_eye\">Pang-apat na mata</string>\n    <string name=\"fourth_eye_description\">Nagdaragdag ng simetrya ng mata sa qr code sa pamamagitan ng pagdaragdag ng pang-apat na mata sa dulong sulok sa ibaba</string>\n    <string name=\"pixel_shape\">Hugis ng pixel</string>\n    <string name=\"frame_shape\">Hugis ng frame</string>\n    <string name=\"ball_shape\">Hugis ng bola</string>\n    <string name=\"error_correction_level\">Antas ng pagwawasto ng error</string>\n    <string name=\"dark_color\">Madilim na kulay</string>\n    <string name=\"light_color\">Banayad na kulay</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Tulad ng estilo ng Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Pattern ng maskara</string>\n    <string name=\"code_may_be_not_scannable\">Maaaring hindi ma-scan ang code na ito, baguhin ang mga param ng hitsura upang gawin itong nababasa sa lahat ng device</string>\n    <string name=\"not_scannable\">Hindi na-scan</string>\n    <string name=\"launcher_mode_sub\">Ang mga tool ay magmumukhang home screen app launcher upang maging mas compact</string>\n    <string name=\"launcher_mode\">Launcher Mode</string>\n    <string name=\"flood_fill_sub\">Pinuno ang isang lugar na may napiling brush at istilo</string>\n    <string name=\"flood_fill\">Punan ng Baha</string>\n    <string name=\"spray\">Mag-spray</string>\n    <string name=\"spray_sub\">Gumuguhit ng graffyy styled path</string>\n    <string name=\"square_particles\">Square Particle</string>\n    <string name=\"square_particles_sub\">Ang mga spray particle ay magiging parisukat sa halip na mga bilog</string>\n    <string name=\"palette_tools\">Mga Tool sa Palette</string>\n    <string name=\"palette_tools_sub\">Bumuo ng pangunahing/materyal na iyong palette mula sa larawan, o mag-import/mag-export sa iba\\'t ibang mga format ng palette</string>\n    <string name=\"edit_palette\">I-edit ang Palette</string>\n    <string name=\"edit_palette_sub\">I-export/import ang palette sa iba\\'t ibang mga format</string>\n    <string name=\"color_name\">Pangalan ng kulay</string>\n    <string name=\"palette_name\">Pangalan ng palette</string>\n    <string name=\"palette_format\">Format ng Palette</string>\n    <string name=\"export_palette_sub\">I-export ang nabuong palette sa iba\\'t ibang mga format</string>\n    <string name=\"add_color_palette_sub\">Nagdaragdag ng bagong kulay sa kasalukuyang palette</string>\n    <string name=\"palette_name_not_supported\">Hindi sinusuportahan ng %1$s na format ang pagbibigay ng pangalan ng palette</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Dahil sa mga patakaran ng Play Store, hindi maaaring isama ang feature na ito sa kasalukuyang build. Upang ma-access ang functionality na ito, mangyaring i-download ang ImageToolbox mula sa isang alternatibong pinagmulan. Mahahanap mo ang mga available na build sa GitHub sa ibaba.</string>\n    <string name=\"open_github_page\">Buksan ang pahina ng Github</string>\n    <string name=\"overwrite_files_sub_short\">Ang orihinal na file ay papalitan ng bago sa halip na i-save sa napiling folder</string>\n    <string name=\"hidden_watermark_text_detected\">Nakakita ng nakatagong watermark na text</string>\n    <string name=\"hidden_watermark_image_detected\">Nakita ang nakatagong larawan ng watermark</string>\n    <string name=\"this_image_was_hidden\">Nakatago ang larawang ito</string>\n    <string name=\"generative_inpaint\">Generative Inpainting</string>\n    <string name=\"generative_inpaint_sub\">Binibigyang-daan kang mag-alis ng mga bagay sa isang imahe gamit ang isang modelo ng AI, nang hindi umaasa sa OpenCV. Para magamit ang feature na ito, ida-download ng app ang kinakailangang modelo (~200 MB) mula sa GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Binibigyang-daan kang mag-alis ng mga bagay sa isang imahe gamit ang isang modelo ng AI, nang hindi umaasa sa OpenCV. Ito ay maaaring isang matagal na operasyon</string>\n    <string name=\"error_level_analysis\">Pagsusuri sa Antas ng Error</string>\n    <string name=\"luminance_gradient\">Luminance Gradient</string>\n    <string name=\"average_distance\">Average na Distansya</string>\n    <string name=\"copy_move_detection\">Kopyahin ang Move Detection</string>\n    <string name=\"retain\">Panatilihin</string>\n    <string name=\"coefficent\">Coefficient</string>\n    <string name=\"clipboard_data_is_too_large\">Masyadong malaki ang data ng clipboard</string>\n    <string name=\"data_is_too_large_to_copy\">Masyadong malaki ang data para makopya</string>\n    <string name=\"simple_weave_pixelization\">Simple Weave Pixelization</string>\n    <string name=\"staggered_pixelization\">Staggered Pixelization</string>\n    <string name=\"cross_pixelization\">Cross Pixelization</string>\n    <string name=\"micro_macro_pixelization\">Micro Macro Pixelization</string>\n    <string name=\"orbital_pixelization\">Orbital Pixelization</string>\n    <string name=\"vortex_pixelization\">Vortex Pixelization</string>\n    <string name=\"pulse_grid_pixelization\">Pixelization ng Pulse Grid</string>\n    <string name=\"nucleus_pixelization\">Pixelization ng Nucleus</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave Pixelization</string>\n    <string name=\"cannot_open_uri\">Hindi mabuksan ang uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Mode ng Snowfall</string>\n    <string name=\"enabled\">Pinagana</string>\n    <string name=\"border_frame\">Border Frame</string>\n    <string name=\"glitch_variant\">Variant ng Glitch</string>\n    <string name=\"channel_shift\">Paglipat ng Channel</string>\n    <string name=\"max_offset\">Max Offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">I-block ang Glitch</string>\n    <string name=\"block_size\">Laki ng Block</string>\n    <string name=\"crt_curvature\">CRT curvature</string>\n    <string name=\"curvature\">Curvature</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">Mga Tool ng AI</string>\n    <string name=\"ai_tools_sub\">Iba\\'t ibang mga tool upang iproseso ang mga larawan sa pamamagitan ng mga modelo tulad ng pag-alis o pag-denoise ng artifact</string>\n    <string name=\"model_anime_undeint\">Compression, tulis-tulis na linya</string>\n    <string name=\"model_broadcast\">Cartoons, broadcast compression</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Pangkalahatang compression, pangkalahatang ingay</string>\n    <string name=\"model_wb_denoise\">Walang kulay na ingay ng cartoon</string>\n    <string name=\"model_span_anime_pretrain\">Mabilis, pangkalahatang compression, pangkalahatang ingay, animation/komiks/anime</string>\n    <string name=\"model_book_scan\">Pag-scan ng libro</string>\n    <string name=\"model_overexposure\">Pagwawasto ng exposure</string>\n    <string name=\"model_fbcnn_color_fp16\">Pinakamahusay sa pangkalahatang compression, mga larawang may kulay</string>\n    <string name=\"model_fbcnn_gray_fp16\">Pinakamahusay sa pangkalahatang compression, grayscale na mga larawan</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Pangkalahatang compression, grayscale na mga imahe, mas malakas</string>\n    <string name=\"model_scunet_color_gan_fp16\">Pangkalahatang ingay, mga larawang may kulay</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Pangkalahatang ingay, mga larawang may kulay, mas magagandang detalye</string>\n    <string name=\"model_scunet_gray_15_fp16\">Pangkalahatang ingay, grayscale na mga larawan</string>\n    <string name=\"model_scunet_gray_25_fp16\">Pangkalahatang ingay, grayscale na mga imahe, mas malakas</string>\n    <string name=\"model_scunet_gray_50_fp16\">Pangkalahatang ingay, grayscale na mga imahe, pinakamalakas</string>\n    <string name=\"model_jpeg_destroyer\">Pangkalahatang compression</string>\n    <string name=\"model_jaywreck\">Pangkalahatang compression</string>\n    <string name=\"model_h264\">Texturization, h264 compression</string>\n    <string name=\"model_vhs\">VHS compression</string>\n    <string name=\"model_cinepak\">Hindi karaniwang compression (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink compression, mas mahusay sa geometry</string>\n    <string name=\"model_debink_v5\">Bink compression, mas malakas</string>\n    <string name=\"model_debink_v6\">Bink compression, malambot, pinapanatili ang detalye</string>\n    <string name=\"model_antialias\">Inaalis ang epekto ng hagdan-hakbang, pagpapakinis</string>\n    <string name=\"model_kdm_scans\">Scanned art/drawings, mild compression, moire</string>\n    <string name=\"model_bandage\">Banding ng kulay</string>\n    <string name=\"model_halftone\">Mabagal, inaalis ang mga halftone</string>\n    <string name=\"model_colorizer\">Pangkalahatang colorizer para sa grayscale/bw na mga imahe, para sa mas magandang resulta gumamit ng DDColor</string>\n    <string name=\"model_deedge\">Pag-alis ng gilid</string>\n    <string name=\"model_desharpen\">Nag-aalis ng labis na pagpapatalas</string>\n    <string name=\"model_dither\">Mabagal, nalilito</string>\n    <string name=\"model_gainres\">Anti-aliasing, pangkalahatang artifact, CGI</string>\n    <string name=\"model_kdm003_scans\">Pinoproseso ng KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Magaan na modelo ng pagpapahusay ng imahe</string>\n    <string name=\"model_bcgone_detailed_v2\">Pag-alis ng compression artifact</string>\n    <string name=\"model_bcgone_smooth\">Pag-alis ng compression artifact</string>\n    <string name=\"model_bandage_smooth\">Pag-alis ng benda na may makinis na resulta</string>\n    <string name=\"model_bendel_halftone\">Pagproseso ng pattern ng halftone</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Pag-alis ng pattern ng dither V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG artifact removal V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 pagpapahusay ng texture</string>\n    <string name=\"model_vhs_sharpen\">VHS hasa at pagpapahusay</string>\n    <string name=\"merging\">Pinagsasama</string>\n    <string name=\"chunk_size\">Laki ng Tipak</string>\n    <string name=\"overlap_size\">Laki ng Overlap</string>\n    <string name=\"note_chunk_info\">Ang mga larawang higit sa %1$s px ay hihiwain at ipoproseso sa mga tipak, magkakapatong-patong ang mga ito upang maiwasan ang mga nakikitang tahi.</string>\n    <string name=\"large_chunk_warning\">Ang malalaking sukat ay maaaring magdulot ng kawalang-tatag sa mga low-end na device</string>\n    <string name=\"select_one_to_start\">Pumili ng isa para magsimula</string>\n    <string name=\"delete_model_sub\">Gusto mo bang tanggalin ang %1$s na modelo? Kakailanganin mong i-download itong muli</string>\n    <string name=\"confirm\">Kumpirmahin</string>\n    <string name=\"models\">Mga modelo</string>\n    <string name=\"downloaded_models\">Mga Na-download na Modelo</string>\n    <string name=\"available_models\">Mga Magagamit na Modelo</string>\n    <string name=\"preparing\">Naghahanda</string>\n    <string name=\"active_model\">Aktibong modelo</string>\n    <string name=\"failed_to_open_session\">Nabigong buksan ang session</string>\n    <string name=\"only_onnx_models\">Tanging mga .onnx/.ort na modelo ang maaaring ma-import</string>\n    <string name=\"import_model\">Mag-import ng modelo</string>\n    <string name=\"import_model_sub\">Mag-import ng custom na onnx na modelo para magamit pa, mga onnx/ort model lang ang tinatanggap, sinusuportahan ang halos lahat ng esrgan na mga variant</string>\n    <string name=\"imported_models\">Mga na-import na Modelo</string>\n    <string name=\"model_scunet_color_15_fp16\">Pangkalahatang ingay, mga larawang may kulay</string>\n    <string name=\"model_scunet_color_25_fp16\">Pangkalahatang ingay, may kulay na mga imahe, mas malakas</string>\n    <string name=\"model_scunet_color_50_fp16\">Pangkalahatang ingay, may kulay na mga imahe, pinakamalakas</string>\n    <string name=\"model_artifacts_dithering_alsa\">Binabawasan ang dithering artifact at color banding, pagpapabuti ng mga makinis na gradient at flat color na lugar.</string>\n    <string name=\"model_nmkd_brighten_redux\">Pinapaganda ang liwanag at contrast ng imahe gamit ang mga balanseng highlight habang pinapanatili ang mga natural na kulay.</string>\n    <string name=\"model_nmkd_brighten\">Nagpapaliwanag ng mga madilim na larawan habang pinapanatili ang mga detalye at iniiwasan ang labis na pagkakalantad.</string>\n    <string name=\"model_nmkd_detoon\">Nag-aalis ng labis na kulay na toning at nagpapanumbalik ng mas neutral at natural na balanse ng kulay.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Inilalapat ang Poisson-based na noise toning na may diin sa pagpapanatili ng mga magagandang detalye at texture.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Naglalapat ng malambot na Poisson noise toning para sa mas makinis at hindi gaanong agresibong visual na mga resulta.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Uniform noise toning na nakatuon sa pangangalaga ng detalye at kalinawan ng imahe.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Magiliw na pare-parehong ingay toning para sa banayad na texture at makinis na hitsura.</string>\n    <string name=\"model_repainter\">Nag-aayos ng mga nasira o hindi pantay na lugar sa pamamagitan ng muling pagpipinta ng mga artifact at pagpapabuti ng pagkakapare-pareho ng imahe.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Lightweight debanding model na nag-aalis ng color banding na may kaunting gastos sa performance.</string>\n    <string name=\"model_jpeg_0_20\">Ino-optimize ang mga larawang may napakataas na compression artifact (0-20% na kalidad) para sa pinahusay na kalinawan.</string>\n    <string name=\"model_jpeg_20_40\">Pinapahusay ang mga larawang may mataas na compression artifact (20-40% na kalidad), pagpapanumbalik ng mga detalye at pagbabawas ng ingay.</string>\n    <string name=\"model_jpeg_40_60\">Pinapabuti ang mga larawang may katamtamang compression (40-60% na kalidad), binabalanse ang sharpness at smoothness.</string>\n    <string name=\"model_jpeg_60_80\">Pinipino ang mga larawan na may magaan na compression (60-80% na kalidad) para mapahusay ang mga banayad na detalye at texture.</string>\n    <string name=\"model_jpeg_80_100\">Bahagyang pinapaganda ang halos walang pagkawalang mga larawan (80-100% kalidad) habang pinapanatili ang natural na hitsura at mga detalye.</string>\n    <string name=\"model_spongecolor_lite\">Simple at mabilis na colorization, cartoons, hindi perpekto</string>\n    <string name=\"model_deblr\">Bahagyang binabawasan ang blur ng imahe, pinapabuti ang sharpness nang hindi nagpapakilala ng mga artifact.</string>\n    <string name=\"processing_channel\">Mahabang tumatakbong operasyon</string>\n    <string name=\"processing_image\">Pinoproseso ang imahe</string>\n    <string name=\"processing\">Pinoproseso</string>\n    <string name=\"model_artifacts_jpg_0_20\">Nag-aalis ng mabibigat na JPEG compression artifact sa napakababang kalidad ng mga larawan (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Binabawasan ang malalakas na JPEG artifact sa mataas na naka-compress na mga larawan (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Nililinis ang mga katamtamang JPEG artifact habang pinapanatili ang mga detalye ng larawan (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Pinipino ang mga magaan na JPEG artifact sa medyo mataas na kalidad na mga larawan (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Bahagyang binabawasan ang mga menor de edad na JPEG artifact sa halos walang pagkawala na mga larawan (80-100%).</string>\n    <string name=\"model_redetail_v2\">Pinapahusay ang mga pinong detalye at texture, pinapabuti ang nakikitang sharpness nang walang mabibigat na artifact.</string>\n    <string name=\"processing_finished\">Tapos na ang pagproseso</string>\n    <string name=\"processing_failed\">Nabigo ang pagproseso</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Pinapaganda ang mga texture at detalye ng balat habang pinapanatili ang natural na hitsura, na na-optimize para sa bilis.</string>\n    <string name=\"model_sbdv_dejpeg\">Inaalis ang mga artifact ng compression ng JPEG at ibinabalik ang kalidad ng imahe para sa mga naka-compress na larawan.</string>\n    <string name=\"model_iso_denoise_v1\">Binabawasan ang ingay ng ISO sa mga larawang kinunan sa mga kondisyong mababa ang liwanag, na pinapanatili ang mga detalye.</string>\n    <string name=\"model_dejumbo\">Itinatama ang overexposed o \\\"jumbo\\\" na mga highlight at ibinabalik ang mas magandang tonal balance.</string>\n    <string name=\"model_ddcolor_tiny\">Magaan at mabilis na modelo ng colorization na nagdaragdag ng mga natural na kulay sa mga grayscale na larawan.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Magkulay</string>\n    <string name=\"type_artifacts\">Mga artifact</string>\n    <string name=\"type_enhance\">Pagandahin</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Mga scan</string>\n    <string name=\"type_upscale\">Upscale</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler para sa mga pangkalahatang larawan; maliit na modelo na gumagamit ng mas kaunting GPU at oras, na may katamtamang deblur at denoise.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler para sa mga pangkalahatang larawan, pinapanatili ang mga texture at natural na mga detalye.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 upscaler para sa mga pangkalahatang larawan na may pinahusay na mga texture at makatotohanang mga resulta.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler na-optimize para sa mga imahe ng anime; 6 RRDB block para sa mas matalas na linya at detalye.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 upscaler na may pagkawala ng MSE, gumagawa ng mas malinaw na mga resulta at pinababang artifact para sa mga pangkalahatang larawan.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler na-optimize para sa mga imahe ng anime; 4B32F variant na may mas matalas na detalye at makinis na linya.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 na modelo para sa mga pangkalahatang larawan; binibigyang-diin ang talas at kalinawan.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; mas mabilis at mas maliit, pinapanatili ang detalye habang gumagamit ng mas kaunting memorya ng GPU.</string>\n    <string name=\"model_rmbg_1_4\">Magaang modelo para sa mabilis na pag-alis ng background. Balanseng pagganap at katumpakan. Gumagana sa mga portrait, bagay, at eksena. Inirerekomenda para sa karamihan ng mga kaso ng paggamit.</string>\n    <string name=\"type_removebg\">Alisin ang BG</string>\n    <string name=\"horizontal_border_thickness\">Pahalang na Kapal ng Border</string>\n    <string name=\"vertical_border_thickness\">Vertical Border Thickness</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s kulay</item>\n        <item quantity=\"other\">%1$s kulay</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Hindi sinusuportahan ng kasalukuyang modelo ang chunking, ipoproseso ang imahe sa mga orihinal na dimensyon, maaari itong magdulot ng mataas na pagkonsumo ng memorya at mga isyu sa mga low-end na device</string>\n    <string name=\"chunking_disabled\">Hindi pinagana ang pag-chun, ipoproseso ang larawan sa mga orihinal na dimensyon, maaari itong magdulot ng mataas na pagkonsumo ng memorya at mga isyu sa mga low-end na device ngunit maaaring magbigay ng mas magandang resulta sa hinuha</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">Modelo ng pagse-segment ng larawan na may mataas na katumpakan para sa pag-alis ng background</string>\n    <string name=\"model_u2netp\">Magaan na bersyon ng U2Net para sa mas mabilis na pag-alis ng background na may mas maliit na paggamit ng memory.</string>\n    <string name=\"model_ddcolor\">Ang buong modelo ng DDColor ay naghahatid ng mataas na kalidad na colorization para sa mga pangkalahatang larawan na may kaunting artifact. Pinakamahusay na pagpipilian ng lahat ng mga modelo ng colorization.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Sinanay at pribadong artistikong dataset; gumagawa ng magkakaibang at masining na mga resulta ng colorization na may mas kaunting hindi makatotohanang mga artifact ng kulay.</string>\n    <string name=\"model_birefnet\">Magaang modelo ng BiRefNet batay sa Swin Transformer para sa tumpak na pag-alis ng background.</string>\n    <string name=\"model_inspyrenet\">De-kalidad na pag-alis ng background na may matatalim na gilid at mahusay na pangangalaga sa detalye, lalo na sa mga kumplikadong bagay at nakakalito na background.</string>\n    <string name=\"model_isnet\">Modelo sa pag-alis ng background na gumagawa ng mga tumpak na maskara na may makinis na mga gilid, na angkop para sa mga pangkalahatang bagay at katamtamang pangangalaga sa detalye.</string>\n    <string name=\"model_already_downloaded\">Na-download na ang modelo</string>\n    <string name=\"model_successfully_imported\">Matagumpay na na-import ang modelo</string>\n    <string name=\"type\">Uri</string>\n    <string name=\"keyword\">Keyword</string>\n    <string name=\"very_fast\">Napakabilis</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Mabagal</string>\n    <string name=\"very_slow\">Napakabagal</string>\n    <string name=\"compute_percents\">Compute ng mga Porsyento</string>\n    <string name=\"minimum_value_is\">Ang min value ay %1$s</string>\n    <string name=\"warp_sub\">I-distort ang imahe sa pamamagitan ng pagguhit gamit ang mga daliri</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">Katigasan</string>\n    <string name=\"warp_mode\">Warp Mode</string>\n    <string name=\"warp_mode_move\">Ilipat</string>\n    <string name=\"warp_mode_grow\">Lumaki</string>\n    <string name=\"warp_mode_shrink\">Paliitin</string>\n    <string name=\"warp_mode_swirl_cw\">Umikot CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Iikot ang CCW</string>\n    <string name=\"fade_strength\">Lakas ng Fade</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Bottom Drop</string>\n    <string name=\"start_drop\">Simulan ang Drop</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">Nagda-download</string>\n    <string name=\"smooth_shapes\">Makinis na Hugis</string>\n    <string name=\"smooth_shapes_sub\">Gumamit ng mga superellipse sa halip na mga karaniwang bilugan na parihaba para sa mas makinis, mas natural na mga hugis</string>\n    <string name=\"shape_type\">Uri ng Hugis</string>\n    <string name=\"cut\">Putulin</string>\n    <string name=\"rounded\">Bilugan</string>\n    <string name=\"smooth\">Makinis</string>\n    <string name=\"cut_shapes_sub\">Matalim ang mga gilid nang walang pagbilog</string>\n    <string name=\"rounded_shapes_sub\">Mga klasikong bilugan na sulok</string>\n    <string name=\"shapes_type\">Uri ng Hugis</string>\n    <string name=\"corners_size\">Sukat ng mga Sulok</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Mga eleganteng bilugan na elemento ng UI</string>\n    <string name=\"filename_format\">Format ng Filename</string>\n    <string name=\"prefix_pattern_description\">Custom na text na inilagay sa pinakadulo simula ng filename, perpekto para sa mga pangalan ng proyekto, brand, o personal na tag.</string>\n    <string name=\"original_filename_pattern_description\">Gumagamit ng orihinal na pangalan ng file nang walang extension, na tumutulong sa iyong panatilihing buo ang pagkakakilanlan ng pinagmulan.</string>\n    <string name=\"width_pattern_description\">Ang lapad ng imahe sa mga pixel, kapaki-pakinabang para sa pagsubaybay sa mga pagbabago sa resolution o pag-scale ng mga resulta.</string>\n    <string name=\"height_pattern_description\">Ang taas ng larawan sa mga pixel, nakakatulong kapag nagtatrabaho sa mga aspect ratio o pag-export.</string>\n    <string name=\"random_numbers_pattern_description\">Bumubuo ng mga random na digit upang magarantiya ang mga natatanging filename; magdagdag ng higit pang mga digit para sa karagdagang kaligtasan laban sa mga duplicate.</string>\n    <string name=\"sequence_number_pattern_description\">Auto-incrementing counter para sa mga batch export, perpekto kapag nagse-save ng maraming larawan sa isang session.</string>\n    <string name=\"preset_info_pattern_description\">Inilalagay ang inilapat na preset na pangalan sa filename upang madali mong matandaan kung paano naproseso ang larawan.</string>\n    <string name=\"scale_mode_pattern_description\">Ipinapakita ang mode ng pag-scale ng imahe na ginagamit sa pagpoproseso, na tumutulong na makilala ang binago, na-crop, o nilagyan ng mga larawan.</string>\n    <string name=\"suffix_pattern_description\">Custom na text na inilagay sa dulo ng filename, kapaki-pakinabang para sa pag-bersyon tulad ng _v2, _edit, o _final.</string>\n    <string name=\"extension_pattern_description\">Ang extension ng file (png, jpg, webp, atbp.), ay awtomatikong tumutugma sa aktwal na naka-save na format.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Isang nako-customize na timestamp na nagbibigay-daan sa iyong tukuyin ang sarili mong format ayon sa java specification para sa perpektong pag-uuri.</string>\n    <string name=\"fling_type\">Uri ng Fling</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">Istilo ng iOS</string>\n    <string name=\"smooth_curve\">Makinis na Kurba</string>\n    <string name=\"quick_stop\">Mabilis na Huminto</string>\n    <string name=\"bouncy\">Bouncy</string>\n    <string name=\"floaty\">Lutang</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Napakakinis</string>\n    <string name=\"adaptive\">Adaptive</string>\n    <string name=\"accessibility_aware\">Accessibility Aware</string>\n    <string name=\"reduced_motion\">Nabawasang Paggalaw</string>\n    <string name=\"android_native_sub\">Native Android scroll physics</string>\n    <string name=\"smooth_sub\">Balanse, makinis na pag-scroll para sa pangkalahatang paggamit</string>\n    <string name=\"ios_style_sub\">Mas mataas na friction iOS-like scroll behavior</string>\n    <string name=\"smooth_curve_sub\">Natatanging spline curve para sa kakaibang scroll feel</string>\n    <string name=\"quick_stop_sub\">Tumpak na pag-scroll na may mabilis na paghinto</string>\n    <string name=\"bouncy_sub\">Mapaglaro, tumutugon bouncy scroll</string>\n    <string name=\"floaty_sub\">Mahahaba, gliding scroll para sa pag-browse ng content</string>\n    <string name=\"snappy_sub\">Mabilis, tumutugon na pag-scroll para sa mga interactive na UI</string>\n    <string name=\"ultra_smooth_sub\">Premium na makinis na pag-scroll na may pinahabang momentum</string>\n    <string name=\"adaptive_sub\">Inaayos ang physics batay sa bilis ng fling</string>\n    <string name=\"accessibility_aware_sub\">Iginagalang ang mga setting ng accessibility ng system</string>\n    <string name=\"reduced_motion_sub\">Minimal na paggalaw para sa mga pangangailangan sa accessibility</string>\n    <string name=\"primary_lines\">Mga Pangunahing Linya</string>\n    <string name=\"primary_lines_sub\">Nagdaragdag ng mas makapal na linya sa bawat ikalimang linya</string>\n    <string name=\"fill_color\">Kulay ng Punan</string>\n    <string name=\"hidden_tools\">Mga Nakatagong Tool</string>\n    <string name=\"hidden_for_share\">Mga Tool na Nakatago Para Ibahagi</string>\n    <string name=\"color_library\">Library ng Kulay</string>\n    <string name=\"color_library_sub\">Mag-browse ng malawak na koleksyon ng mga kulay</string>\n    <string name=\"model_fatality_deblur\">Pinatalas at inaalis ang blur sa mga larawan habang pinapanatili ang mga natural na detalye, perpekto para sa pag-aayos ng mga hindi naka-focus na larawan.</string>\n    <string name=\"model_unresize_v3\">Matalinong nire-restore ang mga larawang dati nang na-resize, binabawi ang mga nawawalang detalye at texture.</string>\n    <string name=\"model_liveaction_v1_span\">Na-optimize para sa live-action na content, binabawasan ang mga artifact ng compression at pinapahusay ang magagandang detalye sa mga frame ng pelikula/palabas sa TV.</string>\n    <string name=\"model_vhs2hd_realplksr\">Kino-convert ang VHS-kalidad na footage sa HD, inaalis ang ingay ng tape at pinapahusay ang resolution habang pinapanatili ang vintage na pakiramdam.</string>\n    <string name=\"model_text2hd_v1\">Espesyalista para sa mga larawan at screenshot na mabigat sa teksto, nagpapatalas ng mga character at pinapahusay ang pagiging madaling mabasa.</string>\n    <string name=\"model_frankendata_pretrainer\">Advanced na upscaling na sinanay sa magkakaibang mga dataset, mahusay para sa pangkalahatang layunin na pagpapahusay ng larawan.</string>\n    <string name=\"model_realwebphoto_v2\">Na-optimize para sa mga larawang naka-compress sa web, nag-aalis ng mga JPEG artifact at nagpapanumbalik ng natural na hitsura.</string>\n    <string name=\"model_realwebphoto_v4\">Pinahusay na bersyon para sa mga larawan sa web na may mas mahusay na pangangalaga sa texture at pagbabawas ng artifact.</string>\n    <string name=\"model_dat_2x\">2x upscaling gamit ang Dual Aggregation Transformer na teknolohiya, nagpapanatili ng sharpness at natural na mga detalye.</string>\n    <string name=\"model_dat_3x\">3x upscaling gamit ang advanced na transformer architecture, perpekto para sa katamtamang mga pangangailangan sa pagpapalaki.</string>\n    <string name=\"model_dat_4x\">4x na mataas na kalidad na upscaling na may makabagong network ng transformer, pinapanatili ang magagandang detalye sa mas malalaking sukat.</string>\n    <string name=\"model_nafnet_deblurring\">Nag-aalis ng blur/ingay at nanginginig sa mga larawan. Pangkalahatang layunin ngunit pinakamahusay sa mga larawan.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Ibinabalik ang mababang kalidad na mga larawan gamit ang Swin2SR transformer, na na-optimize para sa BSRGAN degradation. Mahusay para sa pag-aayos ng mga heavy compression artifact at pagpapahusay ng mga detalye sa 4x scale.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x na upscaling gamit ang SwinIR transformer na sinanay sa BSRGAN degradation. Gumagamit ng GAN para sa mas matalas na mga texture at mas natural na mga detalye sa mga larawan at kumplikadong mga eksena.</string>\n    <string name=\"path\">Daan</string>\n    <string name=\"merge_pdf\">Pagsamahin ang PDF</string>\n    <string name=\"merge_pdf_sub\">Pagsamahin ang maramihang mga PDF file sa isang dokumento</string>\n    <string name=\"files_order\">Pagkakasunud-sunod ng mga File</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Hatiin ang PDF</string>\n    <string name=\"split_pdf_sub\">I-extract ang mga partikular na pahina mula sa PDF na dokumento</string>\n    <string name=\"rotate_pdf\">I-rotate ang PDF</string>\n    <string name=\"rotate_pdf_sub\">Permanenteng ayusin ang oryentasyon ng page</string>\n    <string name=\"pages\">Mga pahina</string>\n    <string name=\"rearrange_pdf\">Ayusin muli ang PDF</string>\n    <string name=\"rearrange_pdf_sub\">I-drag at i-drop ang mga pahina upang muling ayusin ang mga ito</string>\n    <string name=\"hold_drag_drop\">Hawakan at I-drag ang mga pahina</string>\n    <string name=\"page_numbers\">Mga Numero ng Pahina</string>\n    <string name=\"page_numbers_sub\">Awtomatikong magdagdag ng pagnunumero sa iyong mga dokumento</string>\n    <string name=\"label_format\">Format ng Label</string>\n    <string name=\"pdf_to_text\">PDF to Text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">I-extract ang plain text mula sa iyong mga PDF na dokumento</string>\n    <string name=\"watermark_pdf_sub\">I-overlay ang custom na text para sa pagba-brand o seguridad</string>\n    <string name=\"signature\">Lagda</string>\n    <string name=\"signature_sub\">Idagdag ang iyong electronic signature sa anumang dokumento</string>\n    <string name=\"will_be_for_signature\">Ito ay gagamitin bilang lagda</string>\n    <string name=\"unlock_pdf\">I-unlock ang PDF</string>\n    <string name=\"unlock_pdf_sub\">Alisin ang mga password mula sa iyong mga protektadong file</string>\n    <string name=\"protect_pdf\">Protektahan ang PDF</string>\n    <string name=\"protect_pdf_sub\">I-secure ang iyong mga dokumento gamit ang malakas na pag-encrypt</string>\n    <string name=\"success\">Tagumpay</string>\n    <string name=\"pdf_unlocked\">Na-unlock ang PDF, maaari mong i-save o ibahagi ito</string>\n    <string name=\"repair_pdf\">Ayusin ang PDF</string>\n    <string name=\"repair_pdf_sub\">Subukang ayusin ang mga sira o hindi nababasang mga dokumento</string>\n    <string name=\"grayscale\">Grayscale</string>\n    <string name=\"grayscale_pdf_sub\">I-convert ang lahat ng mga larawang naka-embed na dokumento sa grayscale</string>\n    <string name=\"compress_pdf\">I-compress ang PDF</string>\n    <string name=\"compress_pdf_sub\">I-optimize ang laki ng iyong file ng dokumento para sa mas madaling pagbabahagi</string>\n    <string name=\"repair_info\">Ang ImageToolbox ay muling itinatayo ang panloob na cross-reference na talahanayan at muling nabuo ang istraktura ng file mula sa simula. Maaari nitong ibalik ang access sa maraming file na \\\\\"hindi mabubuksan\\\\\"</string>\n    <string name=\"grayscale_info\">Kino-convert ng tool na ito ang lahat ng mga imahe ng dokumento sa grayscale. Pinakamahusay para sa pag-print at pagbabawas ng laki ng file</string>\n    <string name=\"metadata\">Metadata</string>\n    <string name=\"metadata_pdf_sub\">I-edit ang mga katangian ng dokumento para sa mas mahusay na privacy</string>\n    <string name=\"tags\">Mga tag</string>\n    <string name=\"producer\">Producer</string>\n    <string name=\"author\">May-akda</string>\n    <string name=\"keywords\">Mga keyword</string>\n    <string name=\"creator\">Tagapaglikha</string>\n    <string name=\"privacy_deep_clean\">Privacy Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">I-clear ang lahat ng available na metadata para sa dokumentong ito</string>\n    <string name=\"page\">Pahina</string>\n    <string name=\"deep_ocr\">Malalim na OCR</string>\n    <string name=\"deep_ocr_sub\">I-extract ang text mula sa dokumento at iimbak ito sa isang text file gamit ang Tesseract engine</string>\n    <string name=\"cant_remove_all\">Hindi maalis ang lahat ng pahina</string>\n    <string name=\"remove_pages_pdf\">Alisin ang mga pahinang PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Alisin ang mga partikular na pahina mula sa dokumentong PDF</string>\n    <string name=\"tap_to_remove\">I-tap ang Upang Alisin</string>\n    <string name=\"manually\">Manu-manong</string>\n    <string name=\"crop_pdf\">I-crop ang PDF</string>\n    <string name=\"crop_pdf_sub\">I-crop ang mga pahina ng dokumento sa anumang mga hangganan</string>\n    <string name=\"flatten_pdf\">I-flatte ang PDF</string>\n    <string name=\"flatten_pdf_sub\">Gawing hindi nababago ang PDF sa pamamagitan ng pag-raster ng mga pahina ng dokumento</string>\n    <string name=\"camera_failed_to_open\">Hindi masimulan ang camera. Pakisuri ang mga pahintulot at tiyaking hindi ito ginagamit ng ibang app.</string>\n    <string name=\"extract_images\">I-extract ang mga Larawan</string>\n    <string name=\"extract_images_sub\">I-extract ang mga larawang naka-embed sa mga PDF sa orihinal na resolution ng mga ito</string>\n    <string name=\"pdf_no_embedded\">Ang PDF file na ito ay hindi naglalaman ng anumang mga naka-embed na larawan</string>\n    <string name=\"extract_images_info\">Ini-scan ng tool na ito ang bawat pahina at binabawi ang buong kalidad na mga larawan ng pinagmulan — perpekto para sa pag-save ng mga orihinal mula sa mga dokumento</string>\n    <string name=\"draw_signature\">Gumuhit ng Lagda</string>\n    <string name=\"pen_params\">Panulat Params</string>\n    <string name=\"draw_signature_sub\">Gumamit ng sariling pirma bilang imahe na ilalagay sa mga dokumento</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Hatiin ang dokumento sa ibinigay na pagitan at mag-pack ng mga bagong dokumento sa zip archive</string>\n    <string name=\"interval\">Pagitan</string>\n    <string name=\"print_pdf\">Mag-print ng PDF</string>\n    <string name=\"print_pdf_sub\">Maghanda ng dokumento para sa pag-print na may custom na laki ng pahina</string>\n    <string name=\"pages_per_sheet\">Mga Pahina Bawat Sheet</string>\n    <string name=\"orientation\">Oryentasyon</string>\n    <string name=\"page_size\">Laki ng Pahina</string>\n    <string name=\"margin\">Margin</string>\n    <string name=\"bloom\">Bloom</string>\n    <string name=\"soft_knee\">Malambot na Tuhod</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Na-optimize para sa anime at cartoons. Mabilis na pag-upscale gamit ang pinahusay na natural na mga kulay at mas kaunting artifact</string>\n    <string name=\"one_ui_sub\">Gaya ng istilo ng Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Maglagay ng mga pangunahing simbolo ng matematika dito upang kalkulahin ang nais na halaga (hal. (5+5)*10)</string>\n    <string name=\"math_expression\">Math expression</string>\n    <string name=\"pick_up_to_n_collage_images\">Pumili ng hanggang %1$s na mga larawan</string>\n    <string name=\"keep_date_time\">Panatilihin ang Oras ng Petsa</string>\n    <string name=\"keep_date_time_sub\">Palaging panatilihin ang mga exif tag na nauugnay sa petsa at oras, gumagana nang hiwalay sa opsyon na panatilihin ang exif</string>\n    <string name=\"background_color_for_alpha_formats\">Kulay ng Background Para sa Mga Alpha Format</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Nagdaragdag ng kakayahang magtakda ng kulay ng background para sa bawat format ng larawan na may suporta sa alpha, kapag hindi pinagana ito ay magagamit lamang para sa mga hindi alpha</string>\n    <string name=\"open_markup_project\">Buksan ang proyekto</string>\n    <string name=\"open_markup_project_sub\">Ipagpatuloy ang pag-edit ng naunang na-save na proyekto ng Image Toolbox</string>\n    <string name=\"markup_project_open_failed\">Hindi mabuksan ang proyekto ng Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Ang proyekto ng Image Toolbox ay walang data ng proyekto</string>\n    <string name=\"markup_project_corrupted\">Ang proyekto ng Image Toolbox ay sira</string>\n    <string name=\"unsupported_markup_project_version\">Hindi sinusuportahang bersyon ng proyekto ng Image Toolbox: %1$d</string>\n    <string name=\"save_markup_project\">I-save ang proyekto</string>\n    <string name=\"save_markup_project_sub\">Mag-imbak ng mga layer, background at kasaysayan ng pag-edit sa isang nae-edit na file ng proyekto</string>\n    <string name=\"failed_to_open\">Nabigong buksan</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Sumulat Sa Mahahanap na PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Kilalanin ang teksto mula sa batch ng imahe at i-save ang nahahanap na PDF na may larawan at maaaring piliin na layer ng teksto</string>\n    <string name=\"layer_alpha\">Layer alpha</string>\n    <string name=\"horizontal_flip\">Pahalang na Baligtad</string>\n    <string name=\"vertical_flip\">Vertical Flip</string>\n    <string name=\"lock\">Lock</string>\n    <string name=\"add_shadow\">Magdagdag ng Shadow</string>\n    <string name=\"shadow_color\">Kulay ng Anino</string>\n    <string name=\"text_geometry\">Text Geometry</string>\n    <string name=\"text_geometry_sub\">I-stretch o i-skew ang text para sa mas matalas na stylization</string>\n    <string name=\"scale_x\">Scale X</string>\n    <string name=\"skew_x\">I-skew X</string>\n    <string name=\"remove_annotations\">Alisin ang mga anotasyon</string>\n    <string name=\"remove_annotations_sub\">Alisin ang mga napiling uri ng anotasyon gaya ng mga link, komento, highlight, hugis, o mga field ng form mula sa mga pahinang PDF</string>\n    <string name=\"annotation_link\">Mga hyperlink</string>\n    <string name=\"annotation_file_attachment\">Mga Attachment ng File</string>\n    <string name=\"annotation_line\">Mga linya</string>\n    <string name=\"annotation_popup\">Mga popup</string>\n    <string name=\"annotation_stamp\">Mga selyo</string>\n    <string name=\"annotation_shapes\">Mga hugis</string>\n    <string name=\"annotation_text\">Mga Tala sa Teksto</string>\n    <string name=\"annotation_text_markup\">Markup ng Teksto</string>\n    <string name=\"annotation_widget\">Mga Patlang ng Form</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">Hindi alam</string>\n    <string name=\"annotations\">Mga anotasyon</string>\n    <string name=\"ungroup\">Alisin sa pangkat</string>\n    <string name=\"add_shadow_sub\">Magdagdag ng blur shadow sa likod ng layer na may nako-configure na kulay at mga offset</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-fr/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"smth_went_wrong\">Quelque chose s\\'est mal passé: %1$s</string>\n    <string name=\"size\">Dimension %1$s</string>\n    <string name=\"loading\">Chargement…</string>\n    <string name=\"image_too_large_preview\">L\\'image est trop grande pour être prévisualisée, mais la sauvegarde sera tentée de toute façon</string>\n    <string name=\"pick_image\">Pour commencer, sélectionnez une image</string>\n    <string name=\"width\">Largeur %1$s</string>\n    <string name=\"height\">Hauteur %1$s</string>\n    <string name=\"quality\">Qualité</string>\n    <string name=\"extension\">Extension</string>\n    <string name=\"resize_type\">Type de redimensionnement</string>\n    <string name=\"explicit\">Spécifique</string>\n    <string name=\"flexible\">Flexible</string>\n    <string name=\"pick_image_alt\">Choisir une image</string>\n    <string name=\"app_closing_sub\">Êtes-vous sûr de vouloir fermer l\\'application ?</string>\n    <string name=\"app_closing\">Fermeture de l\\'application</string>\n    <string name=\"stay\">Rester</string>\n    <string name=\"close\">Fermer</string>\n    <string name=\"reset_image\">Réinitialiser l\\'image</string>\n    <string name=\"reset_image_sub\">Les valeurs de l\\'image seront restaurées aux valeurs initiales</string>\n    <string name=\"values_reset\">Les valeurs ont été correctement réinitialisées</string>\n    <string name=\"reset\">Réinitialiser</string>\n    <string name=\"something_went_wrong\">Une erreur s\\'est produite</string>\n    <string name=\"restart_app\">Redémarrer l\\'application</string>\n    <string name=\"copied\">Copié dans le presse-papier</string>\n    <string name=\"exception\">Exception</string>\n    <string name=\"edit_exif\">Modifier les données EXIFs</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">Aucune donnée EXIF trouvée</string>\n    <string name=\"add_tag\">Ajouter une balise</string>\n    <string name=\"save\">Sauvegarder</string>\n    <string name=\"clear\">Effacer</string>\n    <string name=\"clear_exif\">Effacer les EXIF</string>\n    <string name=\"cancel\">Annuler</string>\n    <string name=\"clear_exif_sub\">Toutes les données EXIF de l\\'image seront effacées. Cette action ne peut pas être annulée !</string>\n    <string name=\"presets\">Préconfigurations</string>\n    <string name=\"crop\">Rogner</string>\n    <string name=\"image_not_saved\">Enregistrement</string>\n    <string name=\"image_not_saved_sub\">Toutes les modifications non enregistrées seront perdues si vous quittez maintenant</string>\n    <string name=\"check_source_code\">Code source</string>\n    <string name=\"check_source_code_sub\">Recevez les dernières mises à jour, discutez des problèmes et plus encore</string>\n    <string name=\"single_edit\">Édition Unique</string>\n    <string name=\"single_edit_sub\">Modifier, redimensionner et éditer une image</string>\n    <string name=\"pick_color\">Sélecteur de couleurs</string>\n    <string name=\"pick_color_sub\">Sélectionnez une couleur dans une image, la copiez ou partagez</string>\n    <string name=\"image\">Image</string>\n    <string name=\"color\">Couleur</string>\n    <string name=\"color_copied\">Couleur copiée</string>\n    <string name=\"crop_sub\">Rogner l\\'image aux dimensions voulues</string>\n    <string name=\"version\">Version</string>\n    <string name=\"keep_exif\">Conserver EXIF</string>\n    <string name=\"images\">Images : %d</string>\n    <string name=\"change_preview\">Modifier l\\'aperçu</string>\n    <string name=\"remove\">Retirer</string>\n    <string name=\"palette_sub\">Générer un échantillon de palette de couleurs à partir d\\'une image donnée</string>\n    <string name=\"generate_palette\">Générer des Palettes</string>\n    <string name=\"palette\">Palette</string>\n    <string name=\"new_version\">Nouvelle version %1$s</string>\n    <string name=\"update\">Mise à jour</string>\n    <string name=\"unsupported_type\">Type non pris en charge: %1$s</string>\n    <string name=\"no_palette\">Impossible de générer une palette pour l\\'image donnée</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Dossier de sortie</string>\n    <string name=\"def\">Defaut</string>\n    <string name=\"custom\">Personnalisé</string>\n    <string name=\"unspecified\">Non précisé</string>\n    <string name=\"device_storage\">Stockage de l\\'appareil</string>\n    <string name=\"by_bytes_resize\">Redimensionner en fonction du Poids</string>\n    <string name=\"max_bytes\">Taille maximale en ko</string>\n    <string name=\"by_bytes_resize_sub\">Redimensionner une image suivant une taille donnée en KB</string>\n    <string name=\"compare\">Comparer</string>\n    <string name=\"compare_sub\">Comparer deux images données</string>\n    <string name=\"pick_two_images\">Choisissez deux images pour commencer</string>\n    <string name=\"pick_images\">Choisir des images</string>\n    <string name=\"settings\">Paramètres</string>\n    <string name=\"night_mode\">Mode nuit</string>\n    <string name=\"dark\">Sombre</string>\n    <string name=\"system\">Système</string>\n    <string name=\"dynamic_colors\">Couleurs dynamiques</string>\n    <string name=\"customization\">Personnalisation</string>\n    <string name=\"language\">Langue</string>\n    <string name=\"allow_image_monet\">Permettre la monétisation des images</string>\n    <string name=\"light\">Lumière</string>\n    <string name=\"allow_image_monet_sub\">Si cette option est activée, lorsque vous choisissez une image à modifier, les couleurs de l\\'application seront adoptées pour cette image.</string>\n    <string name=\"amoled_mode\">Mode sombre</string>\n    <string name=\"amoled_mode_sub\">Si la couleur des surfaces est activée, la couleur sera définie sur l’obscurité absolue en mode nuit</string>\n    <string name=\"color_red\">Rouge</string>\n    <string name=\"color_green\">Vert</string>\n    <string name=\"color_blue\">Bleu</string>\n    <string name=\"color_scheme\">Couleurs</string>\n    <string name=\"clipboard_paste_invalid_empty\">Rien à coller</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Collez un code couleur aRGB valide</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Le jeu de couleurs de l\\'application ne peut pas être modifié lorsque les couleurs dynamiques sont activées</string>\n    <string name=\"pick_accent_color\">Le thème de l’application sera basé sur la couleur sélectionnée</string>\n    <string name=\"about_app\">À propos de l\\'application</string>\n    <string name=\"no_updates\">Aucune mise à jour trouvée</string>\n    <string name=\"issue_tracker\">Traqueur d\\'incidents</string>\n    <string name=\"issue_tracker_sub\">Envoyez les rapports de bugs et les demandes de fonctionnalités ici</string>\n    <string name=\"help_translate\">Aider à traduire</string>\n    <string name=\"search_here\">Rechercher ici</string>\n    <string name=\"help_translate_sub\">Corriger les erreurs de traduction ou localiser le projet dans une autre langue</string>\n    <string name=\"nothing_found_by_search\">Rien n\\'a été trouvé lors de votre recherche</string>\n    <string name=\"dynamic_colors_sub\">Si cette option est activée, les couleurs de l’application seront adoptées pour les couleurs du fond d’écran.</string>\n    <string name=\"failed_to_save\">Echec de l’enregistrement des images %d</string>\n    <string name=\"surface\">Surface</string>\n    <string name=\"donation_sub\">Cette application est entièrement gratuite, mais si vous souhaitez soutenir le développement du projet, vous pouvez cliquer ici</string>\n    <string name=\"primary\">Primaire</string>\n    <string name=\"permission_sub\">L\\'application a besoin d\\'accéder à votre espace de stockage pour enregistrer des images, cela est nécessaire. Veuillez accorder l\\'autorisation dans la boîte de dialogue suivante.</string>\n    <string name=\"external_storage\">Stockage externe</string>\n    <string name=\"fab_alignment\">Alignement du bouton d\\'action flottant</string>\n    <string name=\"check_updates\">Vérifier les mises à jour</string>\n    <string name=\"check_updates_sub\">Si activé, la boîte de dialogue de mise à jour vous sera affichée au démarrage de l\\'application</string>\n    <string name=\"values\">Valeurs</string>\n    <string name=\"add\">Ajouter</string>\n    <string name=\"tertiary\">Tertiaire</string>\n    <string name=\"secondary\">Secondaire</string>\n    <string name=\"permission\">Autorisation</string>\n    <string name=\"grant\">Accorder</string>\n    <string name=\"zoom\">Zoom sur les images</string>\n    <string name=\"grant_permission_manual\">L\\'application a besoin de cette autorisation pour fonctionner, veuillez l\\'accorder manuellement</string>\n    <string name=\"border_thickness\">Épaisseur de la bordure</string>\n    <string name=\"share\">Partager</string>\n    <string name=\"monet_colors\">Couleurs de Monet</string>\n    <string name=\"prefix\">Préfixe</string>\n    <string name=\"filename\">Nom du fichier</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Sélectionnez les émojis à afficher sur l\\'écran principal</string>\n    <string name=\"add_file_size\">Ajouter la taille du fichier</string>\n    <string name=\"add_file_size_sub\">Si activé, ajoute la largeur et la hauteur de l\\'image enregistrée au nom du fichier de sortie</string>\n    <string name=\"delete_exif\">Supprimer EXIF</string>\n    <string name=\"delete_exif_sub\">Supprimer les métadonnées EXIF de tout ensemble d\\'images</string>\n    <string name=\"image_preview\">Aperçu de l\\'Image</string>\n    <string name=\"image_preview_sub\">Aperçu de tout type d’images : GIF, SVG, et ainsi de suite</string>\n    <string name=\"photo_picker_sub\">Sélecteur moderne de photos Android apparaissant en bas de l\\'écran, ne fonctionne que sur Android 12+.A des problèmes de réception des métadonnées EXIF</string>\n    <string name=\"file_explorer_picker_sub\">Utiliser l\\'intent GetContent pour sélectionner l\\'image. Fonctionne partout, mais celui-ci est connu pour avoir des difficultés à recevoir les images sélectionnées sur certains appareils. Cela n\\'est pas de ma faute.</string>\n    <string name=\"image_source\">Source de l\\'image</string>\n    <string name=\"photo_picker\">Sélecteur de photos</string>\n    <string name=\"gallery_picker\">Galerie</string>\n    <string name=\"file_explorer_picker\">Explorateur de fichiers</string>\n    <string name=\"gallery_picker_sub\">Simple sélecteur d’image de galerie. Il ne fonctionnera que si vous avez une application qui permet la sélection d\\'image</string>\n    <string name=\"edit\">Modifier</string>\n    <string name=\"order\">Commander</string>\n    <string name=\"options_arrangement\">Disposition des options</string>\n    <string name=\"order_sub\">Détermine l’ordre des outils sur l’écran principal</string>\n    <string name=\"emojis_count\">Nombre d’émojis</string>\n    <string name=\"add_original_filename\">Ajouter le nom de fichier original</string>\n    <string name=\"add_original_filename_sub\">Si activé, ajoute le nom de fichier d\\'origine au nom de l\\'image de sortie</string>\n    <string name=\"replace_sequence_number_sub\">Si cette option est activée, l’horodatage de Standard remplace le numéro de séquence d’image si vous utilisez le traitement par lots</string>\n    <string name=\"sequence_num\">Numéro de séquence</string>\n    <string name=\"original_filename\">Fichier original</string>\n    <string name=\"replace_sequence_number\">Ajouter un numéro de séquence</string>\n    <string name=\"filename_not_work_with_photopicker\">Ajouter le nom de fichier d\\'origine ne fonctionne pas si la source d\\'image du sélecteur de photo est sélectionnée.</string>\n    <string name=\"load_image_from_net\">Charger une Image depuis Internet</string>\n    <string name=\"load_image_from_net_sub\">Charger n\\'importe quelle image de l\\'Internet pour la prévisualiser, zoomer, la modifier ou la sauvegarder si vous le souhaitez.</string>\n    <string name=\"no_image\">Aucune image</string>\n    <string name=\"image_link\">Lien de l\\'image</string>\n    <string name=\"fit\">Ajuster</string>\n    <string name=\"fill\">Remplissage</string>\n    <string name=\"content_scale\">Échelle de contenu</string>\n    <string name=\"explicit_description\">Redimensionne les images à la hauteur et à la largeur données. Le rapport hauteur/largeur des images peut changer.</string>\n    <string name=\"flexible_description\">Redimensionne les images avec un côté long à la hauteur ou à la largeur donnée. Tous les calculs de taille seront effectués après l\\'enregistrement. Le rapport hauteur/largeur des images sera préservé.</string>\n    <string name=\"contrast\">Contraste</string>\n    <string name=\"hue\">Teinte</string>\n    <string name=\"add_filter\">Ajouter un filtre</string>\n    <string name=\"filter\">Filtre</string>\n    <string name=\"filters\">Filtres</string>\n    <string name=\"light_aka_illumination\">Lumière</string>\n    <string name=\"color_filter\">Filtre de couleur</string>\n    <string name=\"brightness\">Luminosité</string>\n    <string name=\"saturation\">Saturation</string>\n    <string name=\"filter_sub\">Appliquer des filtres aux images</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"white_balance\">Balance des blancs</string>\n    <string name=\"temperature\">Température</string>\n    <string name=\"tint\">Teinte</string>\n    <string name=\"monochrome\">Monochrome</string>\n    <string name=\"highlights_shadows\">Points saillants et ombres</string>\n    <string name=\"exposure\">Exposition</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"shadows\">Ombres</string>\n    <string name=\"haze\">Flou</string>\n    <string name=\"effect\">Effet</string>\n    <string name=\"distance\">Distance</string>\n    <string name=\"sharpen\">Affiner</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negative</string>\n    <string name=\"solarize\">Solariser</string>\n    <string name=\"vibrance\">Vibe</string>\n    <string name=\"highlights\">Points Saillants</string>\n    <string name=\"slope\">Pente</string>\n    <string name=\"black_and_white\">Noir et Blanc</string>\n    <string name=\"spacing\">Espacement</string>\n    <string name=\"line_width\">Largeur de ligne</string>\n    <string name=\"sobel_edge\">Bord de sobel</string>\n    <string name=\"blur\">Flou</string>\n    <string name=\"crosshatch\">Hachure</string>\n    <string name=\"halftone\">Demi-teinte</string>\n    <string name=\"emboss\">En relief</string>\n    <string name=\"laplacian\">Laplacien</string>\n    <string name=\"vignette\">Vignette</string>\n    <string name=\"start\">Commencer</string>\n    <string name=\"end\">Fin</string>\n    <string name=\"cga_colorspace\">Espace colorimétrique CGA</string>\n    <string name=\"gaussian_blur\">Flou Gaussien</string>\n    <string name=\"box_blur\">Flou encadré</string>\n    <string name=\"bilaterial_blur\">Flou bilatéral</string>\n    <string name=\"kuwahara\">Lissage de Kuwahara</string>\n    <string name=\"radius\">Rayon</string>\n    <string name=\"scale\">Échelle</string>\n    <string name=\"stack_blur\">Flou lent</string>\n    <string name=\"angle\">Angle</string>\n    <string name=\"swirl\">Tourbillon</string>\n    <string name=\"distortion\">Distorsion</string>\n    <string name=\"dilation\">Dilatation</string>\n    <string name=\"sphere_refraction\">Réfraction de la sphère</string>\n    <string name=\"glass_sphere_refraction\">Réfraction de la sphère en verre</string>\n    <string name=\"color_matrix\">Matrice de couleur</string>\n    <string name=\"bulge\">Bosse</string>\n    <string name=\"refractive_index\">indice de réfraction</string>\n    <string name=\"opacity\">Opacité</string>\n    <string name=\"limits_resize\">Redimensionner avec des limites</string>\n    <string name=\"limits_resize_sub\">Redimensionner les images à la hauteur et à la largeur données tout en conservant le rapport hauteur/largeur</string>\n    <string name=\"sketch\">Esquisse</string>\n    <string name=\"threshold\">Seuil</string>\n    <string name=\"quantizationLevels\">Niveaux de quantification</string>\n    <string name=\"smooth_toon\">Lisse cartoon</string>\n    <string name=\"toon\">Dessin animé</string>\n    <string name=\"posterize\">Postériser</string>\n    <string name=\"lookup\">Consultation</string>\n    <string name=\"weak_pixel_inclusion\">Inclusion de pixels faibles</string>\n    <string name=\"non_maximum_suppression\">Suppression de non maximum</string>\n    <string name=\"convolution3x3\">Convolution 3x3</string>\n    <string name=\"false_color\">Couleur fausse</string>\n    <string name=\"second_color\">Seconde couleur</string>\n    <string name=\"rgb_filter\">Filtre RGB</string>\n    <string name=\"first_color\">Première couleur</string>\n    <string name=\"reorder\">Réorganiser</string>\n    <string name=\"fast_blur\">Flou rapide</string>\n    <string name=\"blur_size\">Taille floue</string>\n    <string name=\"blur_center_y\">Centre flou y</string>\n    <string name=\"zoom_blur\">Zoom flou</string>\n    <string name=\"color_balance\">Balance de couleur</string>\n    <string name=\"luminance_threshold\">Seuil de luminance</string>\n    <string name=\"blur_center_x\">Flou centre x</string>\n    <string name=\"draw\">Dessiner</string>\n    <string name=\"activate_files\">Vous avez désactivé l\\'application Fichiers, activez-la pour utiliser cette fonctionnalité</string>\n    <string name=\"draw_sub\">Dessinez sur l\\'image comme dans un carnet de croquis, ou dessinez sur l\\'arrière-plan lui-même</string>\n    <string name=\"paint_alpha\">Peinture alpha</string>\n    <string name=\"draw_on_image\">Dessiner sur l’image</string>\n    <string name=\"draw_on_background\">Dessiner sur fond uni</string>\n    <string name=\"draw_on_background_sub\">Choisissez la couleur de fond et dessinez dessus</string>\n    <string name=\"background_color\">Couleur d\\'arrière-plan</string>\n    <string name=\"paint_color\">Couleur de peinture</string>\n    <string name=\"draw_on_image_sub\">Choisissez une image et dessinez quelque chose dessus</string>\n    <string name=\"encrypt\">Crypter</string>\n    <string name=\"decrypt\">Décrypter</string>\n    <string name=\"pick_file_to_start\">Choisir le fichier pour commencer</string>\n    <string name=\"decryption\">Décryptage</string>\n    <string name=\"encryption\">Cryptage</string>\n    <string name=\"key\">Clé</string>\n    <string name=\"file_proceed\">Le dossier a été traité</string>\n    <string name=\"features\">Fonctionnalités</string>\n    <string name=\"implementation\">Exécution</string>\n    <string name=\"compatibility\">Compatibilité</string>\n    <string name=\"implementation_sub\">AES-256, mode GCM, pas de rembourrage, IV aléatoires de 12 octets par défaut. Vous pouvez sélectionner l\\'algorithme nécessaire. Les clés sont utilisées comme hachages SHA-3 de 256 bits.</string>\n    <string name=\"file_size\">Taille du fichier</string>\n    <string name=\"pick_file\">Choisir un dossier</string>\n    <string name=\"cipher\">Chiffrement</string>\n    <string name=\"store_file_desc\">Stockez ce fichier sur votre appareil ou utilisez l’action partage pour le mettre où vous voulez</string>\n    <string name=\"cipher_sub\">Chiffrer et déchiffrer n\\'importe quel fichier (pas seulement l\\'image) en fonction de divers algorithmes de chiffrement disponibles</string>\n    <string name=\"features_sub\">Chiffrement par mot de passe des fichiers. Les fichiers traités peuvent être stockés dans le répertoire sélectionné ou partagés. Les fichiers déchiffrés peuvent également être ouverts directement.</string>\n    <string name=\"compatibility_sub\">Veuillez noter que la compatibilité avec d’autres logiciels ou services de chiffrement de fichiers n’est pas garantie. Un traitement de clé ou une configuration de chiffrement légèrement différente peuvent causer une incompatibilité.</string>\n    <string name=\"file_size_sub\">La taille maximale du fichier est limitée par le système d\\'exploitation Android et la mémoire disponible, qui dépendent de votre appareil. \\nAttention : la mémoire n\\'est pas du stockage.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Mot de passe invalide ou fichier choisi non chiffré</string>\n    <string name=\"image_size_warning\">Essayer d’enregistrer une image avec ces largeur et hauteur peut provoquer une erreur de mémoire insuffisante. Faites ceci à vos propres risques.</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Taille du cache</string>\n    <string name=\"found_s\">Trouvé %1$s</string>\n    <string name=\"auto_cache_clearing\">Effacement automatique du cache</string>\n    <string name=\"auto_cache_clearing_sub\">Si activé, le cache de l\\'application sera effacé au démarrage de l’application</string>\n    <string name=\"create\">Créer</string>\n    <string name=\"tools\">Outils</string>\n    <string name=\"group_options_by_type\">Grouper les options par type</string>\n    <string name=\"group_options_by_type_sub\">Regroupe les options sur l\\'écran principal par type au lieu d\\'une disposition de liste personnalisée</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Impossible de modifier la disposition lorsque le groupement d\\'options est activé</string>\n    <string name=\"edit_screenshot\">Éditer capture d\\'écran</string>\n    <string name=\"screenshot\">Capture d\\'écran</string>\n    <string name=\"secondary_customization\">Personnalisation secondaire</string>\n    <string name=\"fallback_option\">Option de secours</string>\n    <string name=\"copy\">Copier</string>\n    <string name=\"skip\">Passer</string>\n    <string name=\"warning_bytes\">L’enregistrement en mode %1$s peut être instable, car c\\'est un format sans perte</string>\n    <string name=\"presets_sub\" formatted=\"false\">Si vous avez sélectionné le préréglage 125, l\\'image sera enregistrée avec une taille de 125% de l\\'image originale. Si vous sélectionnez le préréglage 50, l\\'image sera enregistrée avec une taille de 50%</string>\n    <string name=\"presets_sub_bytes\">Le préréglage ici détermine le % du fichier de sortie, c\\'est-à-dire que si vous sélectionnez le préréglage 50 sur une image de 5 Mo, vous obtiendrez une image de 2,5 Mo après l\\'enregistrement</string>\n    <string name=\"saved_to\">Enregistré dans le dossier %1$s avec le nom %2$s</string>\n    <string name=\"randomize_filename\">Nom de fichier aléatoire</string>\n    <string name=\"randomize_filename_sub\">Si activé, le nom du fichier de sortie sera entièrement aléatoire</string>\n    <string name=\"saved_to_without_filename\">Enregistré dans le dossier %1$s</string>\n    <string name=\"tg_chat\">Discussion Telegram</string>\n    <string name=\"tg_chat_sub\">Discutez de l\\'application et obtenez les commentaires des autres utilisateurs. Vous pouvez également y obtenir des mises à jour bêta et des informations.</string>\n    <string name=\"aspect_ratio\">Ratio d\\'aspect</string>\n    <string name=\"backup_and_restore\">Sauvegarde et restauration</string>\n    <string name=\"backup\">Sauvegarde</string>\n    <string name=\"restore_sub\">Restaurer les paramètres de l\\'application à partir du fichier généré précédemment</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Fichier corrompu ou pas de sauvegarde</string>\n    <string name=\"settings_restored\">Paramètres restaurés avec succès</string>\n    <string name=\"contact_me\">Contactez moi</string>\n    <string name=\"crop_mask\">Masque de recadrage</string>\n    <string name=\"image_crop_mask_sub\">Utilisez ce type de masque pour créer un masque à partir d’une image donnée, notez qu’il DEVRAIT avoir un canal alpha</string>\n    <string name=\"restore\">Restaurer</string>\n    <string name=\"backup_sub\">Sauvegardez vos paramètres d\\'application dans un fichier</string>\n    <string name=\"reset_settings_sub\">Cela ramènera vos paramètres aux valeurs par défaut. Notez que cela ne peut pas être annulé sans un fichier de sauvegarde mentionné ci-dessus.</string>\n    <string name=\"delete\">Supprimer</string>\n    <string name=\"delete_color_scheme_warn\">Vous êtes sur le point de supprimer le jeu de couleurs sélectionné. Cette opération ne peut pas être annulée</string>\n    <string name=\"delete_color_scheme_title\">Supprimer le schéma</string>\n    <string name=\"font\">Police</string>\n    <string name=\"text\">Texte</string>\n    <string name=\"font_scale\">Taille de la Police</string>\n    <string name=\"defaultt\">Défaut</string>\n    <string name=\"using_large_fonts_warn\">L’utilisation de grandes échelles de police peut provoquer des erreurs d’interface utilisateur ainsi que d\\'autres problèmes qui ne seront pas corrigés. A utiliser avec précaution.</string>\n    <string name=\"alphabet_and_numbers\">Aa Àà Ââ Ææ Bb Cc Çç Dd Ee Éé Èè Êê Ëë Ff Gg Hh Ii Îî Ïï Jj Kk Ll Mm Nn Oo Ôô Œœ Pp Qq Rr Ss Tt Uu Ùù Ûû Üü Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"emotions\">Emotions</string>\n    <string name=\"food_and_drink\">Nourriture et Boisson</string>\n    <string name=\"nature_and_animals\">Nature et animaux</string>\n    <string name=\"objects\">Objets</string>\n    <string name=\"symbols\">Symboles</string>\n    <string name=\"enable_emoji\">Activer les emoji</string>\n    <string name=\"travels_and_places\">Voyages et lieux</string>\n    <string name=\"activities\">Activités</string>\n    <string name=\"background_remover\">Suppresseur d\\'arrière-plan</string>\n    <string name=\"background_remover_sub\">Supprimer l’arrière-plan de l’image par dessin ou utiliser l’option Auto</string>\n    <string name=\"trim_image\">Couper l’image</string>\n    <string name=\"keep_exif_sub\">Les métadonnées de l\\'image originale seront conservées</string>\n    <string name=\"trim_image_sub\">L\\'espace transparent autour de l\\'image sera coupé</string>\n    <string name=\"auto_erase_background\">Effacement automatique de l\\'arrière-plan</string>\n    <string name=\"restore_image\">Restaurer l\\'image</string>\n    <string name=\"erase_mode\">Mode Effacer</string>\n    <string name=\"erase_background\">Effacer l\\'arrière-plan</string>\n    <string name=\"blur_radius\">Rayon de flou</string>\n    <string name=\"pipette\">Pipette</string>\n    <string name=\"restore_background\">Restaurer l\\'arrière-plan</string>\n    <string name=\"draw_mode\">Mode Dessin</string>\n    <string name=\"something_went_wrong_emphasis\">Oups… Quelque chose s\\'est mal passé. Vous pouvez m\\'écrire en utilisant les options ci-dessous et j\\'essaierai de trouver une solution</string>\n    <string name=\"resize_and_convert_sub\">Modifiez la taille des images données ou convertissez-les dans d\\'autres formats. Les métadonnées EXIF peuvent également être modifiées ici si une seule image est sélectionnée.</string>\n    <string name=\"resize_and_convert\">Redimensionner et Convertir</string>\n    <string name=\"create_issue\">Créer un problème</string>\n    <string name=\"max_colors_count\">Nombre maximal de couleurs</string>\n    <string name=\"crashlytics_sub\">Permet à l\\'application de collecter les rapports d\\'erreur automatiquement</string>\n    <string name=\"analytics\">Analyse</string>\n    <string name=\"analytics_sub\">Autoriser la collecte de données statistiques anonymes sur l\\'utilisation de l\\'application</string>\n    <string name=\"image_exif_warning\">Actuellement, le format %1$s permet uniquement de lire les métadonnées EXIF sur Android. L\\'image de sortie n\\'aura aucune métadonnée, lorsque sauvegardée.</string>\n    <string name=\"wait\">Patientez</string>\n    <string name=\"effort_sub\">Une valeur de %1$s signifie une compression rapide, ce qui entraîne une taille de fichier relativement importante. %2$s signifie une compression plus lente, ce qui donne un fichier plus petit.</string>\n    <string name=\"saving_almost_complete\">La sauvegarde est presque terminée. Annuler maintenant nécessitera de sauvegarder à nouveau.</string>\n    <string name=\"effort\">Travail</string>\n    <string name=\"updates\">Mises à jour</string>\n    <string name=\"allow_betas\">Autoriser les versions bêta</string>\n    <string name=\"allow_betas_sub\">La vérification des mises à jour inclura les versions bêta de l\\'application si activé</string>\n    <string name=\"brush_softness\">Douceur du pinceau</string>\n    <string name=\"draw_arrows\">Dessiner des flèches</string>\n    <string name=\"draw_arrows_sub\">Si activé, le chemin de dessin sera représenté par une flèche pointante</string>\n    <string name=\"crop_description\">Les images seront recadrées de façon centrée d\\'après la taille saisie. Les bordures seront agrandies avec la couleur d\\'arrière-plan choisie si l\\'image est plus petite que les dimensions saisies.</string>\n    <string name=\"donation\">Don</string>\n    <string name=\"image_stitching\">Assemblage d\\'images</string>\n    <string name=\"image_stitching_sub\">Combinez les images choisies pour en obtenir une grande</string>\n    <string name=\"horizontal\">horizontale</string>\n    <string name=\"images_order\">Ordre des images</string>\n    <string name=\"pick_at_least_two_images\">Choisissez au moins 2 images</string>\n    <string name=\"scale_small_images_to_large_sub\">Les petites images seront mises à l\\'échelle à la plus grande de la séquence si cette option est activée.</string>\n    <string name=\"image_orientation\">Orientation des images</string>\n    <string name=\"vertical\">Verticale</string>\n    <string name=\"output_image_scale\">Échelle de l\\'image de sortie</string>\n    <string name=\"scale_small_images_to_large\">Agrandir les petites images</string>\n    <string name=\"blur_edges\">Bords flous</string>\n    <string name=\"pixelation\">Pixelisation</string>\n    <string name=\"blur_edges_sub\">Dessine des bords flous sous l\\'image d\\'origine pour remplir les espaces autour d\\'elle au lieu d\\'une seule couleur si cette option est activée</string>\n    <string name=\"regular\">Regulié</string>\n    <string name=\"tolerance\">Tolérance</string>\n    <string name=\"enhanced_pixelation\">Pixelation améliorée</string>\n    <string name=\"target_color\">Couleur cible</string>\n    <string name=\"replace_color\">Remplacer la couleur</string>\n    <string name=\"diamond_pixelation\">Pixelation au diamant</string>\n    <string name=\"remove_color\">Supprimer la couleur</string>\n    <string name=\"enhanced_diamond_pixelation\">Pixelation Diamond améliorée</string>\n    <string name=\"circle_pixelation\">Pixelisation du cercle</string>\n    <string name=\"color_to_remove\">Couleur à supprimer</string>\n    <string name=\"color_to_replace\">Couleur à remplacer</string>\n    <string name=\"stroke_pixelation\">Pixellisation de la course</string>\n    <string name=\"enhanced_circle_pixelation\">Pixelisation de cercle améliorée</string>\n    <string name=\"recode\">Recoder</string>\n    <string name=\"pixel_size\">Dimensions de Pixel</string>\n    <string name=\"lock_draw_orientation\">Verrouiller l\\'orientation du dessin</string>\n    <string name=\"check_for_updates\">Vérifier les mises à jour</string>\n    <string name=\"lock_draw_orientation_sub\">Si activé en mode dessin, l\\'écran ne rotationnera pas</string>\n    <string name=\"fidelity\">Fidélité</string>\n    <string name=\"rainbow\">Arc-en-ciel</string>\n    <string name=\"playful_scheme\">Un thème ludique - la teinte de la couleur source n\\'apparaît pas dans le thème</string>\n    <string name=\"vibrant_sub\">Un thème fort, la couleur est maximale pour la palette primaire, augmentée pour les autres</string>\n    <string name=\"neutral_sub\">Un style légèrement plus chromatique que monochrome</string>\n    <string name=\"content_sub\">Un schéma qui place la couleur source dans Scheme.primaryContainer</string>\n    <string name=\"tonal_spot\">Accent tonique</string>\n    <string name=\"monochrome_sub\">Un thème monochrome, les couleurs sont purement noir/blanc/gris</string>\n    <string name=\"fruit_salad\">Salade de fruits</string>\n    <string name=\"fidelity_sub\">Un schéma très similaire au schéma de contenu</string>\n    <string name=\"content\">Contenu</string>\n    <string name=\"expressive\">Expression</string>\n    <string name=\"neutral\">Neutre</string>\n    <string name=\"tonal_spot_sub\">Style de palette par défaut, il permet de personnaliser les quatre couleurs, d\\'autres vous permettent de définir uniquement la couleur clé</string>\n    <string name=\"palette_style\">Style de palette</string>\n    <string name=\"vibrant\">Vive</string>\n    <string name=\"both\">Les deux</string>\n    <string name=\"invert_colors_sub\">Remplace les couleurs du thème par des couleurs négatives si elles sont activées</string>\n    <string name=\"fading_edges\">Bords décolorés</string>\n    <string name=\"pdf_tools\">Outils PDF</string>\n    <string name=\"foss_update_checker_warning\">Ce vérificateur de mise à jour se connectera à GitHub pour vérifier si une nouvelle mise à jour est disponible</string>\n    <string name=\"search_option\">Chercher</string>\n    <string name=\"images_to_pdf\">Images en PDF</string>\n    <string name=\"preview_pdf\">Aperçu du PDF</string>\n    <string name=\"search_option_sub\">Permet de rechercher parmi toutes les outils disponibles sur l\\'écran principal</string>\n    <string name=\"disabled\">Désactiver</string>\n    <string name=\"pdf_to_images\">PDF en images</string>\n    <string name=\"images_to_pdf_sub\">Emballer les images données dans le fichier PDF de sortie</string>\n    <string name=\"preview_pdf_sub\">Aperçu PDF simple</string>\n    <string name=\"invert_colors\">Inverser les couleurs</string>\n    <string name=\"pdf_tools_sub\">Fonctionner avec des fichiers PDF : prévisualiser, convertir en lot d\\'images ou en créer une à partir d\\'images données</string>\n    <string name=\"attention\">Precison</string>\n    <string name=\"pdf_to_images_sub\">Convertir un PDF en images dans un format de sortie donné</string>\n    <string name=\"mask_filter\">Filtre de masque</string>\n    <string name=\"mask_filter_sub\">Appliquez des chaînes de filtres sur des zones masquées données, chaque zone de masque peut déterminer son propre ensemble de filtres</string>\n    <string name=\"mask_preview\">Aperçu du Masque</string>\n    <string name=\"masks\">Masques</string>\n    <string name=\"mask_color\">Couleur du masque</string>\n    <string name=\"add_mask\">Ajouter un masque</string>\n    <string name=\"mask_preview_sub\">Le masque de filtre dessiné sera rendu pour vous montrer le résultat approximatif</string>\n    <string name=\"mask_indexed\">Masque %d</string>\n    <string name=\"neon\">Néon</string>\n    <string name=\"delete_mask\">Supprimer le masque</string>\n    <string name=\"inverse_fill_type\">Type de Remplissage Inverse</string>\n    <string name=\"delete_mask_warn\">Vous êtes sur le point de supprimer le masque filtre sélectionné. Cette opération est irréversible</string>\n    <string name=\"full_filter_sub\">Application de toute chaîne de filtres aux images sélectionnées ou individuellement</string>\n    <string name=\"inverse_fill_type_sub\">Si activé toutes les zones non-masquées seront filtrées au lieu du comportement par défaut</string>\n    <string name=\"start_position\">Début</string>\n    <string name=\"highlighter\">Surligneur</string>\n    <string name=\"simple_variants\">Variantes Simples</string>\n    <string name=\"full_filter\">Filtre Complet</string>\n    <string name=\"end_position\">Fin</string>\n    <string name=\"center_position\">Centre</string>\n    <string name=\"rows_count\">Nombre de lignes</string>\n    <string name=\"double_line_arrow\">Flèche à double ligne</string>\n    <string name=\"neon_sub\">Ajoutez un effet lumineux à vos dessins</string>\n    <string name=\"stitch_mode\">Mode point</string>\n    <string name=\"switches_shadow_sub\">Dessiner une ombres derrière les commutateurs</string>\n    <string name=\"double_line_arrow_sub\">Dessine une flèche à double pointage du point de départ au point final sous forme de ligne</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"arrow_sub\">Dessine une flèche pointant à partir d\\'un chemin donné</string>\n    <string name=\"auto_rotate_limits\">Rotation automatique</string>\n    <string name=\"free_drawing\">Dessin gratuit</string>\n    <string name=\"vibration\">Vibration</string>\n    <string name=\"horizontal_grid\">Grille horizontale</string>\n    <string name=\"outlined_oval\">Ovale décrit</string>\n    <string name=\"overwrite_file_requirements\">Afin d\\'écraser les fichiers, vous devez utiliser la source d\\'image \\\"Explorateur\\\", essayez de re-sélectionner les images, nous avons remplacé la source d\\'image par celle nécessaire</string>\n    <string name=\"pen\">Stylo</string>\n    <string name=\"line\">Doubler</string>\n    <string name=\"auto_pin_sub\">Ajoute automatiquement l\\'image enregistrée au presse-papiers si activé</string>\n    <string name=\"no_such_directory\">Aucun répertoire \\\"%1$s\\\" trouvé, nous l\\'avons remplacé par celui par défaut, veuillez enregistrer à nouveau le fichier</string>\n    <string name=\"vertical_grid\">Grille verticale</string>\n    <string name=\"sliders_shadow\">Curseurs</string>\n    <string name=\"containers_shadow_sub\">Dessiner une ombre derrière les conteneurs</string>\n    <string name=\"oval\">ovale</string>\n    <string name=\"rect\">Rectifier</string>\n    <string name=\"columns_count\">Nombre de colonnes</string>\n    <string name=\"clipboard\">Presse-papiers</string>\n    <string name=\"outlined_rect_sub\">Dessine le rectangle décrit du point de départ au point final</string>\n    <string name=\"auto_rotate_limits_sub\">Permet d\\'adopter une boîte de limite pour l\\'orientation de l\\'image</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"privacy_blur_sub\">L\\'image est floue sous le chemin tracé pour sécuriser tout ce que vous souhaitez cacher</string>\n    <string name=\"pen_sub\">Celui par défaut, le plus simple : juste la couleur</string>\n    <string name=\"line_arrow\">Flèche de ligne</string>\n    <string name=\"containers_shadow\">Conteneurs</string>\n    <string name=\"line_sub\">Dessine le chemin du point de départ au point final sous forme de ligne</string>\n    <string name=\"overwrite_files_sub\">Le fichier original sera remplacé par un nouveau au lieu d\\'être enregistré dans le dossier sélectionné. Cette option doit être la source de l\\'image \\\"Explorer\\\" ou GetContent. Lorsque vous activez cette option, elle sera définie automatiquement</string>\n    <string name=\"vibration_strength\">Résistance aux vibrations</string>\n    <string name=\"outlined_oval_sub\">Dessine un ovale délimité du point de départ au point final</string>\n    <string name=\"app_bars_shadow\">Barres d\\'Applications</string>\n    <string name=\"highlighter_sub\">Dessinez des chemins de surligneur aiguisés semi-transparents</string>\n    <string name=\"lasso_sub\">Dessine un chemin rempli fermé par chemin donné</string>\n    <string name=\"free\">Gratuite</string>\n    <string name=\"double_arrow\">Double flèche</string>\n    <string name=\"arrow\">Flèche</string>\n    <string name=\"free_drawing_sub\">Dessine le chemin comme valeur d\\'entrée</string>\n    <string name=\"buttons_shadow\">Boutons</string>\n    <string name=\"overwrite_files\">Écraser les fichiers</string>\n    <string name=\"rect_sub\">Dessine le rectangle du point de départ au point final</string>\n    <string name=\"sliders_shadow_sub\">Dessiner une ombre derrière les curseurs</string>\n    <string name=\"switches_shadow\">Commutateurs</string>\n    <string name=\"empty\">Vide</string>\n    <string name=\"app_bars_shadow_sub\">Dessiner une ombre derrière les barres d\\'application</string>\n    <string name=\"value_in_range\">Valeur comprise dans la plage %1$s - %2$s</string>\n    <string name=\"line_arrow_sub\">Dessine une flèche pointant du point de départ au point final sous forme de ligne</string>\n    <string name=\"pixelation_sub\">Semblable au flou de confidentialité, mais pixelisé au lieu de flou</string>\n    <string name=\"suffix\">Suffixe</string>\n    <string name=\"double_arrow_sub\">Dessine une double flèche pointée à partir d\\'un chemin donné</string>\n    <string name=\"outlined_rect\">Rect décrit</string>\n    <string name=\"privacy_blur\">Flou de confidentialité</string>\n    <string name=\"fabs_shadow_sub\">Dessiner une ombre derrière les boutons d\\'action flottants</string>\n    <string name=\"oval_sub\">Dessine un ovale du point de départ au point final</string>\n    <string name=\"buttons_shadow_sub\">Dessiner une ombre derrière les boutons</string>\n    <string name=\"auto_pin\">Épingle automatique</string>\n    <string name=\"draw_path_mode\">Mode Dessiner un chemin</string>\n    <string name=\"tent_blur\">Flou de tente</string>\n    <string name=\"side_fade\">Fondu latéral</string>\n    <string name=\"side\">Côté</string>\n    <string name=\"top\">Haut</string>\n    <string name=\"bottom\">Bas</string>\n    <string name=\"strength\">Force</string>\n    <string name=\"segmentation_mode_single_column\">Seule colonne</string>\n    <string name=\"segmentation_mode_sparse_text\">Texte clairsemé</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Texte clairsemé Orientation &amp; Détection de script</string>\n    <string name=\"segmentation_mode_raw_line\">Ligne brute</string>\n    <string name=\"glitch\">Problème</string>\n    <string name=\"amount\">Montant</string>\n    <string name=\"seed\">Graine</string>\n    <string name=\"anaglyph\">Anaglyphe</string>\n    <string name=\"noise\">Bruit</string>\n    <string name=\"pixel_sort\">Tri des pixels</string>\n    <string name=\"shuffle\">Mélanger</string>\n    <string name=\"peak\">Culminer</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubique</string>\n    <string name=\"bilinear_sub\">L\\'interpolation linéaire (ou bilinéaire, en deux dimensions) est généralement efficace pour modifier la taille d\\'une image, mais provoque un adoucissement indésirable des détails et peut encore être quelque peu irrégulière.</string>\n    <string name=\"lanczos_sub\">Méthode de rééchantillonnage qui maintient une interpolation de haute qualité en appliquant une fonction sinc pondérée aux valeurs des pixels</string>\n    <string name=\"mitchell_sub\">Méthode de rééchantillonnage utilisant un filtre de convolution avec des paramètres réglables pour obtenir un équilibre entre netteté et anticrénelage dans l\\'image mise à l\\'échelle</string>\n    <string name=\"spline_sub\">Utilise des fonctions polynomiales définies par morceaux pour interpoler et approximer en douceur une courbe ou une surface, donnant une représentation de forme flexible et continue</string>\n    <string name=\"use_pixel_switch_sub\">Utilise un bouton de type Google Pixel</string>\n    <string name=\"magnifier\">Loupe</string>\n    <string name=\"magnifier_sub\">Active la loupe sur le dessus du doigt dans les modes de dessin pour une meilleure accessibilité</string>\n    <string name=\"force_exif_widget_initial_value\">Forcer la valeur initiale</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Force la vérification initiale du widget exif</string>\n    <string name=\"allow_multiple_languages\">Autoriser plusieurs langues</string>\n    <string name=\"toggle_tap\">Appuyez sur</string>\n    <string name=\"transparency\">Transparence</string>\n    <string name=\"segmentation_mode_osd_only\">Orientation &amp; Détection de script uniquement</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientation automatique &amp; Détection de script</string>\n    <string name=\"segmentation_mode_auto_only\">Automatique uniquement</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Texte vertical à un seul bloc</string>\n    <string name=\"segmentation_mode_single_block\">Bloc unique</string>\n    <string name=\"segmentation_mode_single_line\">Une seule ligne</string>\n    <string name=\"segmentation_mode_single_word\">Un seul mot</string>\n    <string name=\"segmentation_mode_circle_word\">Mot de cercle</string>\n    <string name=\"segmentation_mode_single_char\">Caractère unique</string>\n    <string name=\"delete_language_sub\">Souhaitez-vous supprimer les données de formation OCR de langue \\\"%1$s\\\" pour tous les types de reconnaissance, ou uniquement pour celui sélectionné (%2$s) ?</string>\n    <string name=\"current\">Actuel</string>\n    <string name=\"all\">Tous</string>\n    <string name=\"camera_sub\">Prendre une photo avec l\\'appareil photo. Notez qu\\'il est possible d\\'obtenir une seule image à partir de cette source d\\'image.</string>\n    <string name=\"watermarking\">Filigrane</string>\n    <string name=\"watermarking_sub\">Couvrir les images avec des filigranes de texte/image personnalisables</string>\n    <string name=\"repeat_watermark\">Répéter le filigrane</string>\n    <string name=\"repeat_watermark_sub\">Répète le filigrane sur l\\'image au lieu d\\'un seul à une position donnée</string>\n    <string name=\"watermark_type\">Type de filigrane</string>\n    <string name=\"watermarking_image_sub\">Cette image sera utilisée comme modèle pour le filigrane</string>\n    <string name=\"use_size_of_first_frame_sub\">Remplacer la taille spécifiée par les premières dimensions du cadre</string>\n    <string name=\"frame_delay\">Retard de trame</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"secure_mode\">Mode sécurisé</string>\n    <string name=\"secure_mode_sub\">Masque le contenu de l\\'application dans les applications récentes. L\\'écran ne peut pas non plus être capturé ou enregistré</string>\n    <string name=\"bayer_four_dithering\">Bayer, quatre par quatre, tramage</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Tramage</string>\n    <string name=\"atkinson_dithering\">Tramage Atkinson</string>\n    <string name=\"two_row_sierra_dithering\">Tramage Sierra à deux rangées</string>\n    <string name=\"false_floyd_steinberg_dithering\">Faux Floyd Steinberg Dithering</string>\n    <string name=\"left_to_right_dithering\">Tramage de gauche à droite</string>\n    <string name=\"random_dithering\">Tramage aléatoire</string>\n    <string name=\"b_spline_sub\">Utilise des fonctions polynomiales bicubiques définies par morceaux pour interpoler et approximer en douceur une courbe ou une surface, une représentation de forme flexible et continue</string>\n    <string name=\"native_stack_blur\">Flou de pile natif</string>\n    <string name=\"enhanced_glitch\">Problème amélioré</string>\n    <string name=\"channel_shift_x\">Changement de chaîne X</string>\n    <string name=\"channel_shift_y\">Décalage de canal Y</string>\n    <string name=\"corruption_size\">Taille de la corruption</string>\n    <string name=\"corruption_shift_x\">Changement de corruption X</string>\n    <string name=\"corruption_shift_y\">Changement de corruption Y</string>\n    <string name=\"anisotropic_diffusion\">Diffusion anisotrope</string>\n    <string name=\"diffusion\">La diffusion</string>\n    <string name=\"conduction\">Conduction</string>\n    <string name=\"crystallize\">Cristalliser</string>\n    <string name=\"stroke_color\">Couleur du trait</string>\n    <string name=\"fractal_glass\">Verre fractal</string>\n    <string name=\"amplitude\">Amplitude</string>\n    <string name=\"marble\">Marbre</string>\n    <string name=\"frequency_y\">Fréquence Y</string>\n    <string name=\"amplitude_x\">AmplitudeX</string>\n    <string name=\"color_matrix_3x3\">Matrice de couleurs 3x3</string>\n    <string name=\"polaroid\">Polaroïd</string>\n    <string name=\"tritonomaly\">Tritanomalie</string>\n    <string name=\"coda_chrome\">Code Chrome</string>\n    <string name=\"night_vision\">Vision nocturne</string>\n    <string name=\"warm\">Chaud</string>\n    <string name=\"cool\">Cool</string>\n    <string name=\"achromatomaly\">Achromatomie</string>\n    <string name=\"achromatopsia\">Achromatopsie</string>\n    <string name=\"golden_hour\">Heure d\\'or</string>\n    <string name=\"hot_summer\">Été chaud</string>\n    <string name=\"purple_mist\">Brume violette</string>\n    <string name=\"electric_gradient\">Dégradé électrique</string>\n    <string name=\"caramel_darkness\">Caramel Ténèbres</string>\n    <string name=\"futuristic_gradient\">Dégradé futuriste</string>\n    <string name=\"deep_purple\">Violet foncé</string>\n    <string name=\"space_portal\">Portail spatial</string>\n    <string name=\"red_swirl\">Tourbillon rouge</string>\n    <string name=\"digital_code\">Code numérique</string>\n    <string name=\"icon_shape\">Forme d\\'icône</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Couper</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Transition</string>\n    <string name=\"color_anomaly\">Anomalie de couleur</string>\n    <string name=\"images_overwritten\">Images écrasées à la destination d\\'origine</string>\n    <string name=\"cannot_change_image_format\">Impossible de modifier le format de l\\'image lorsque l\\'option d\\'écrasement des fichiers est activée</string>\n    <string name=\"emoji_as_color_scheme\">Emoji comme palette de couleurs</string>\n    <string name=\"emoji_as_color_scheme_sub\">Utilise la couleur primaire des emoji comme jeu de couleurs de l\\'application au lieu d\\'un jeu de couleurs défini manuellement</string>\n    <string name=\"erode\">Éroder</string>\n    <string name=\"horizontal_wind_stagger\">Décalage horizontal du vent</string>\n    <string name=\"fast_bilaterial_blur\">Flou bilatéral rapide</string>\n    <string name=\"poisson_blur\">Flou de Poisson</string>\n    <string name=\"logarithmic_tone_mapping\">Cartographie des tons logarithmique</string>\n    <string name=\"turbulence\">Turbulence</string>\n    <string name=\"oil\">Huile</string>\n    <string name=\"water_effect\">Effet de l\\'eau</string>\n    <string name=\"just_size\">Taille</string>\n    <string name=\"frequency_x\">Fréquence X</string>\n    <string name=\"amplitude_y\">Amplitude Y</string>\n    <string name=\"perlin_distortion\">Distorsion Perlin</string>\n    <string name=\"hable_filmic_tone_mapping\">Cartographie des tons filmiques Hable</string>\n    <string name=\"heji_burgess_tone_mapping\">Cartographie des tons Heji-Burgess</string>\n    <string name=\"aces_filmic_tone_mapping\">Cartographie des tons filmiques ACES</string>\n    <string name=\"aces_hill_tone_mapping\">Cartographie des tons ACES Hill</string>\n    <string name=\"gradient_maker\">Créateur de dégradés</string>\n    <string name=\"gradient_maker_sub\">Créez un dégradé d\\'une taille de sortie donnée avec des couleurs et un type d\\'apparence personnalisés</string>\n    <string name=\"speed\">Vitesse</string>\n    <string name=\"dehaze\">Déhaze</string>\n    <string name=\"omega\">Oméga</string>\n    <string name=\"rate_app\">Noter l\\'App</string>\n    <string name=\"rate\">Noter</string>\n    <string name=\"rate_app_sub\">Cette application est entièrement gratuite, si vous souhaitez qu\\'elle devienne plus grande, veuillez mettre le projet en vedette sur Github 😄</string>\n    <string name=\"color_matrix_4x4\">Matrice de couleurs 4x4</string>\n    <string name=\"simple_effects\">Effets simples</string>\n    <string name=\"deutaromaly\">Deuteranomalie</string>\n    <string name=\"protonomaly\">Protanomalie</string>\n    <string name=\"vintage\">Ancien</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"tritanopia\">Tritanopie</string>\n    <string name=\"deutaronotopia\">Deuteranotopie</string>\n    <string name=\"protanopia\">Protanopie</string>\n    <string name=\"gradient_type_linear\">Linéaire</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Balayer</string>\n    <string name=\"gradient_type\">Type de dégradé</string>\n    <string name=\"center_x\">Centre X</string>\n    <string name=\"center_y\">Centre Y</string>\n    <string name=\"tile_mode\">Mode mosaïque</string>\n    <string name=\"tile_mode_repeated\">Répété</string>\n    <string name=\"tile_mode_mirror\">Miroir</string>\n    <string name=\"tile_mode_clamp\">Serrer</string>\n    <string name=\"tile_mode_decal\">Décalcomanie</string>\n    <string name=\"color_stops\">Arrêts de couleur</string>\n    <string name=\"add_color\">Ajouter de la couleur</string>\n    <string name=\"properties\">Propriétés</string>\n    <string name=\"dithering\">Tramage</string>\n    <string name=\"quantizier\">Quantificateur</string>\n    <string name=\"gray_scale\">Échelle de gris</string>\n    <string name=\"bayer_two_dithering\">Bayer, tramage deux par deux</string>\n    <string name=\"bayer_three_dithering\">Bayer, tramage trois par trois</string>\n    <string name=\"bayer_eight_dithering\">Bayer huit par huit tramage</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Tramage Sierra</string>\n    <string name=\"sierra_lite_dithering\">Tramage Sierra Lite</string>\n    <string name=\"stucki_dithering\">Tramage bloqué</string>\n    <string name=\"burkes_dithering\">Burkes tramage</string>\n    <string name=\"simple_threshold_dithering\">Dithering à seuil simple</string>\n    <string name=\"scale_mode\">Mode échelle</string>\n    <string name=\"bilinear\">Bilinéaire</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">La plus proche</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Basique</string>\n    <string name=\"default_value\">Valeur par défaut</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma spatial</string>\n    <string name=\"median_blur\">Flou médian</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"bicubic_sub\">Les meilleures méthodes de mise à l\\'échelle incluent le rééchantillonnage de Lanczos et les filtres Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">L\\'un des moyens les plus simples d\\'augmenter la taille, en remplaçant chaque pixel par un certain nombre de pixels de la même couleur.</string>\n    <string name=\"basic_sub\">Mode de mise à l\\'échelle Android le plus simple utilisé dans presque toutes les applications</string>\n    <string name=\"catmull_sub\">Méthode d\\'interpolation et de rééchantillonnage en douceur d\\'un ensemble de points de contrôle, couramment utilisée en infographie pour créer des courbes douces</string>\n    <string name=\"hann_sub\">Fonction de fenêtrage souvent appliquée dans le traitement du signal pour minimiser les fuites spectrales et améliorer la précision de l\\'analyse de fréquence en effilant les bords d\\'un signal</string>\n    <string name=\"hermite_sub\">Technique d\\'interpolation mathématique qui utilise les valeurs et les dérivées aux extrémités d\\'un segment de courbe pour générer une courbe lisse et continue</string>\n    <string name=\"only_clip\">Seulement le clip</string>\n    <string name=\"only_clip_sub\">L\\'enregistrement dans le stockage ne sera pas effectué et l\\'image sera tentée de être placée uniquement dans le presse-papiers.</string>\n    <string name=\"icon_shape_sub\">Ajoute un conteneur avec la forme sélectionnée sous les icônes</string>\n    <string name=\"brightness_enforcement\">Application de la luminosité</string>\n    <string name=\"screen\">Écran</string>\n    <string name=\"gradient_maker_type_image\">Incrustation en dégradé</string>\n    <string name=\"gradient_maker_type_image_sub\">Composez n\\'importe quel dégradé du haut des images données</string>\n    <string name=\"transformations\">Transformations</string>\n    <string name=\"camera\">Caméra</string>\n    <string name=\"grain\">Grain</string>\n    <string name=\"unsharp\">Flou</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Brume orange</string>\n    <string name=\"pink_dream\">Rêve rose</string>\n    <string name=\"sunrise\">Lever du soleil</string>\n    <string name=\"colorful_swirl\">Tourbillon coloré</string>\n    <string name=\"soft_spring_light\">Lumière de printemps douce</string>\n    <string name=\"autumn_tones\">Tons d\\'automne</string>\n    <string name=\"lavender_dream\">Rêve de lavande</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Limonade légère</string>\n    <string name=\"spectral_fire\">Feu spectral</string>\n    <string name=\"night_magic\">Magie nocturne</string>\n    <string name=\"fantasy_landscape\">Paysage fantastique</string>\n    <string name=\"color_explosion\">Explosion de couleurs</string>\n    <string name=\"green_sun\">Soleil vert</string>\n    <string name=\"rainbow_world\">Monde arc-en-ciel</string>\n    <string name=\"offset_x\">Décalage X</string>\n    <string name=\"offset_y\">Décalage Y</string>\n    <string name=\"text_color\">Couleur du texte</string>\n    <string name=\"overlay_mode\">Mode superposition</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">Outils GIF</string>\n    <string name=\"gif_tools_sub\">Convertir des images en image GIF ou extraire des images d\\'une image GIF donnée</string>\n    <string name=\"gif_type_to_image\">GIF en images</string>\n    <string name=\"gif_type_to_image_sub\">Convertir le fichier GIF en lot d\\'images</string>\n    <string name=\"gif_type_to_gif_sub\">Convertir un lot d\\'images en fichier GIF</string>\n    <string name=\"gif_type_to_gif\">Images en GIF</string>\n    <string name=\"select_gif_image_to_start\">Choisissez une image GIF pour commencer</string>\n    <string name=\"use_size_of_first_frame\">Utiliser la taille de la première image</string>\n    <string name=\"repeat_count\">Nombre de répétitions</string>\n    <string name=\"use_lasso\">Utiliser le lasso</string>\n    <string name=\"use_lasso_sub\">Utilise le Lasso comme en mode dessin pour effectuer l\\'effacement</string>\n    <string name=\"original_image_preview_alpha\">Aperçu de l\\'image originale Alpha</string>\n    <string name=\"random_emojis_sub\">Les emojis de la barre d\\'application changent aléatoirement</string>\n    <string name=\"random_emojis\">Émojis aléatoires</string>\n    <string name=\"random_emojis_error\">Impossible d\\'utiliser la sélection aléatoire d\\'emojis lorsque les emojis sont désactivés</string>\n    <string name=\"emoji_selection_error\">Impossible de sélectionner un emoji lorsque les emojis aléatoires sont activés</string>\n    <string name=\"old_tv\">Vieille télé</string>\n    <string name=\"shuffle_blur\">Mélanger le flou</string>\n    <string name=\"recognize_text\">OCR (reconnaître le texte)</string>\n    <string name=\"recognize_text_sub\">Reconnaître le texte d\\'une image donnée, plus de 120 langues prises en charge</string>\n    <string name=\"picture_has_no_text\">L\\'image ne contient pas de texte ou l\\'application ne l\\'a pas trouvé</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Type de reconnaissance</string>\n    <string name=\"fast\">Rapide</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"best\">Meilleur</string>\n    <string name=\"no_data\">Pas de données</string>\n    <string name=\"download_description\">Pour que Tesseract OCR fonctionne correctement, des données d\\'entraînement supplémentaires (%1$s) doivent être téléchargées sur votre appareil. \\nVoulez-vous télécharger des données %2$s ?</string>\n    <string name=\"download\">Télécharger</string>\n    <string name=\"no_connection\">Pas de connexion, vérifiez et réessayez afin de télécharger des modèles de train</string>\n    <string name=\"downloaded_languages\">Langues téléchargées</string>\n    <string name=\"available_languages\">Langues disponibles</string>\n    <string name=\"segmentation_mode\">Mode de segmentation</string>\n    <string name=\"restore_background_sub\">Le pinceau restaurera l\\'arrière-plan au lieu de l\\'effacer</string>\n    <string name=\"use_pixel_switch\">Utiliser le commutateur Pixel</string>\n    <string name=\"slide\">Glisser</string>\n    <string name=\"side_by_side\">Cote à cote</string>\n    <string name=\"saved_to_original\">Fichier écrasé portant le nom %1$s à la destination d\\'origine</string>\n    <string name=\"favorite\">Préféré</string>\n    <string name=\"no_favorite_filters\">Aucun filtre favori ajouté pour l\\'instant</string>\n    <string name=\"b_spline\">Cannelure B</string>\n    <string name=\"tilt_shift\">Inclinaison</string>\n    <string name=\"confetti\">Confettis</string>\n    <string name=\"confetti_sub\">Les confettis seront affichés lors de la sauvegarde, du partage et d\\'autres actions principales</string>\n    <string name=\"exit\">Sortie</string>\n    <string name=\"preview_closing\">Si vous quittez l\\'aperçu maintenant, vous devrez à nouveau ajouter les images</string>\n    <string name=\"image_format\">Format d\\'image</string>\n    <string name=\"material_you_sub\">Crée la palette \\\"Material You\\\" à partir de l\\'image</string>\n    <string name=\"dark_colors\">Couleurs Sombres</string>\n    <string name=\"dark_colors_sub\">Utilise la palette de couleurs du mode nuit au lieu de la variante lumineuse</string>\n    <string name=\"copy_as_compose_code\">Copier en tant que code \\\" Jetpack Compose”</string>\n    <string name=\"ring_blur\">Flou d\\'anneau</string>\n    <string name=\"cross_blur\">Flou Croisé</string>\n    <string name=\"circle_blur\">Flou Circulaire</string>\n    <string name=\"star_blur\">Flou d\\'Étoile</string>\n    <string name=\"linear_tilt_shift\">Tilt-Shift linéaire</string>\n    <string name=\"tags_to_remove\">Tags à supprimer</string>\n    <string name=\"apng_type_to_apng_sub\">Convertir un lot d\\'images en fichier APNG</string>\n    <string name=\"apng_type_to_apng\">Images en APNG</string>\n    <string name=\"apng_tools\">Outils APNG</string>\n    <string name=\"apng_tools_sub\">Convertir des images en image APNG ou extraire des images d\\'une image APNG donnée</string>\n    <string name=\"apng_type_to_image\">APNG en images</string>\n    <string name=\"apng_type_to_image_sub\">Convertir le fichier APNG en lot d\\'images</string>\n    <string name=\"motion_blur\">Flou de mouvement</string>\n    <string name=\"select_apng_image_to_start\">Choisissez l\\'image APNG pour commencer</string>\n    <string name=\"zip_sub\">Créer un fichier Zip à partir de fichiers ou d\\'images donnés</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"drag_handle_width\">Largeur de la poignée de déplacement</string>\n    <string name=\"confetti_type\">Type de confetti</string>\n    <string name=\"festive\">Célébration</string>\n    <string name=\"explode\">Exploser</string>\n    <string name=\"rain\">Pluie</string>\n    <string name=\"corners\">Coins</string>\n    <string name=\"jxl_tools\">Outils JXL</string>\n    <string name=\"jxl_tools_sub\">Effectuer le transcodage JXL ~ JPEG sans perte de qualité, ou convertir des GIF/APNG en animation JXL</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Effectuez un transcodage sans perte de JXL vers JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Effectuez un transcodage sans perte de JPEG vers JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG en JXL</string>\n    <string name=\"select_jxl_image_to_start\">Choisissez l\\'image JXL pour commencer</string>\n    <string name=\"fast_gaussian_blur_2d\">Flou gaussien rapide 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Flou gaussien rapide modèle 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Flou gaussien rapide 4D</string>\n    <string name=\"jxl_type_to_jpeg\">JXL en JPEG</string>\n    <string name=\"lanczos_bessel_sub\">Méthode de ré-échantillonnage qui conserve une haute qualité d\\'interpolation en appliquant une fontion Bessel (jinc) aux valeurs de pixels</string>\n    <string name=\"gif_type_to_jxl\">GIF en JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Converti les images APNG en images animées JXL</string>\n    <string name=\"jxl_type_to_images_sub\">Converti une animation JXL en un lot d\\'images</string>\n    <string name=\"jxl_type_to_jxl_sub\">Converti un lot d\\'images en animation JXL</string>\n    <string name=\"behavior\">Comportement</string>\n    <string name=\"skip_file_picking_sub\">Si possible, le sélecteur de fichiers sera affiché immédiatement sur l\\'écran choisi</string>\n    <string name=\"generate_previews\">Générer les Aperçus</string>\n    <string name=\"sorting\">Classement</string>\n    <string name=\"default_line_width\">Largeur de ligne par défaut</string>\n    <string name=\"header_today\">Aujourd\\'hui</string>\n    <string name=\"header_yesterday\">Hier</string>\n    <string name=\"gif_type_to_jxl_sub\">Converti les images GIF en images JXL animées</string>\n    <string name=\"apng_type_to_jxl\">APNG vers JXL</string>\n    <string name=\"jxl_type_to_images\">JXL en Images</string>\n    <string name=\"jxl_type_to_jxl\">Images en JXL</string>\n    <string name=\"generate_previews_sub\">Activer la génération d\\'aperçu, ce qui peut permettre d\\'éviter des crashs sur certains appareils. Cela désactive quelques fonctions d\\'édition dans la fonction d\\'édition simple</string>\n    <string name=\"compression_type\">Type de compression</string>\n    <string name=\"sort_by_date\">Date</string>\n    <string name=\"sort_by_date_reversed\">Date (inversé)</string>\n    <string name=\"sort_by_name\">Nom</string>\n    <string name=\"sort_by_name_reversed\">Nom (inversé)</string>\n    <string name=\"harmonization_color\">Harmonisation de la Couleur</string>\n    <string name=\"channels_configuration\">Configuration des Canaux</string>\n    <string name=\"embedded_picker_sub\">Utilisez le sélecteur d\\'Image Toolbox</string>\n    <string name=\"pick_multiple_media\">Sélectionner plusieurs médias</string>\n    <string name=\"try_again\">Réessayer</string>\n    <string name=\"show_settings_in_landscape\">Afficher les Paramètres en Mode Paysage</string>\n    <string name=\"fullscreen_settings\">Paramètres du plein écran</string>\n    <string name=\"pick_single_media\">Sélectionner un média</string>\n    <string name=\"pick\">Sélectionner</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Ancre de redimensionnement</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"embedded_picker\">Sélecteur intégré</string>\n    <string name=\"no_permissions\">Pas de permissions</string>\n    <string name=\"request\">Requête</string>\n    <string name=\"lstm_network\">Réseau LSTM</string>\n    <string name=\"auto_paste\">Collage automatique</string>\n    <string name=\"auto_paste_sub\">Permettez à l\\'application de coller automatiquement les données depuis le presse-papiers, elles vont apparaître sur l\\'écran principal et vous pourrez les éditer.</string>\n    <string name=\"skip_file_picking\">Passer la Sélection du Fichier</string>\n    <string name=\"lossy_compression\">Compression avec Pertes</string>\n    <string name=\"lossy_compression_sub\">Utilise la compression avec perte pour réduire la taille du fichier au lieu de la compression sans perte</string>\n    <string name=\"images_to_svg\">Images en SVG</string>\n    <string name=\"images_to_svg_sub\">Trace les images fournies en images SVG</string>\n    <string name=\"min_color_ratio\">Ratio colorimétrique minimum</string>\n    <string name=\"path_scale\">Échelle du chemin</string>\n    <string name=\"reset_properties\">Réinitialiser les propriétés</string>\n    <string name=\"reset_properties_sub\">Toutes les propriétés vont être réinitialisés aux valeurs par défaut, notez que cette action est irréversible</string>\n    <string name=\"detailed\">Détaillé.e</string>\n    <string name=\"svg_warning\">L’utilisation de cet outil pour tracer de grandes images sans réduction d’échelle n’est pas recommandée, il peut provoquer un crash et augmenter le temps de traitement</string>\n    <string name=\"use_sampled_palette\">Utiliser la palette échantillonnée</string>\n    <string name=\"fullscreen_settings_sub\">Activez-le et la page de paramètres sera toujours ouverte en plein écran au lieu de la fenêtre coulissante</string>\n    <string name=\"switch_type\">Type de bouton à bascule</string>\n    <string name=\"compose\">Composer</string>\n    <string name=\"harmonization_level\">Niveau d\\'harmonisation</string>\n    <string name=\"convert\">Convertir</string>\n    <string name=\"downscale_image_sub\">L’image sera réduite à des dimensions inférieures avant le traitement, ce qui aide l’outil à travailler plus rapidement et en toute sécurité</string>\n    <string name=\"downscale_image\">Image réduite</string>\n    <string name=\"lines_threshold\">Seuil des lignes</string>\n    <string name=\"quadratic_threshold\">Seuil quadratique</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolérance d’arrondissement des coordonnées</string>\n    <string name=\"add_new_folder\">Ajouter un Nouveau Dossier</string>\n    <string name=\"tag_compression\">Compression</string>\n    <string name=\"tag_datetime\">Date Heure</string>\n    <string name=\"tag_image_description\">Description de l\\'Image</string>\n    <string name=\"tag_artist\">Artiste</string>\n    <string name=\"tag_copyright\">Droit d\\'auteur</string>\n    <string name=\"speed_sub\">Contrôle la vitesse de décodage de l’image résultante, cela devrait aider à ouvrir l’image résultante plus rapidement, la valeur de %1$s signifie le décodage le plus lent, tandis que %2$s - le plus rapide, ce paramètre peut augmenter la taille de l’image de sortie</string>\n    <string name=\"use_sampled_palette_sub\">La palette de quantification sera échantillonnée si cette option est activée.</string>\n    <string name=\"convert_sub\">Conversion de lots d\\'images au format donné</string>\n    <string name=\"tag_subsec_time_original\">Temps Sub Sec original</string>\n    <string name=\"tag_spatial_frequency_response\">Réponse en fréquence spatiale</string>\n    <string name=\"show_settings_in_landscape_sub\">Si cette option est désactivée, en mode paysage, les paramètres s\\'ouvriront comme toujours sur le bouton de la barre d\\'applications supérieure, au lieu de l\\'option visible permanente.</string>\n    <string name=\"tag_bits_per_sample\">Bits par échantillon</string>\n    <string name=\"tag_photometric_interpretation\">Interprétation photométrique</string>\n    <string name=\"tag_samples_per_pixel\">Échantillons par pixel</string>\n    <string name=\"tag_planar_configuration\">Configuration planaire</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sous-échantillonage</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Positionnement</string>\n    <string name=\"tag_x_resolution\">Résolution X</string>\n    <string name=\"tag_y_resolution\">Résolution Y</string>\n    <string name=\"tag_resolution_unit\">Unité de résolution</string>\n    <string name=\"tag_strip_offsets\">Décalages de bande</string>\n    <string name=\"tag_rows_per_strip\">Lignes par bande</string>\n    <string name=\"tag_strip_byte_counts\">Nombre d\\'octets de la bande</string>\n    <string name=\"tag_jpeg_interchange_format\">Format d\\'échange JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Longueur du format d\\'échange JPEG</string>\n    <string name=\"tag_transfer_function\">Fonction de transfert</string>\n    <string name=\"tag_white_point\">Point blanc</string>\n    <string name=\"tag_primary_chromaticities\">Chromatismes primaires</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Coefficients</string>\n    <string name=\"tag_reference_black_white\">Référence Noir Blanc</string>\n    <string name=\"tag_make\">Créer</string>\n    <string name=\"tag_model\">Modèle</string>\n    <string name=\"tag_software\">Logiciel</string>\n    <string name=\"tag_exif_version\">Version Exif</string>\n    <string name=\"tag_flashpix_version\">Version Flashpix</string>\n    <string name=\"tag_color_space\">Espace couleur</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y Dimension</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Bits compressés par pixel</string>\n    <string name=\"tag_maker_note\">Note du fabricant</string>\n    <string name=\"tag_user_comment\">Commentaire de l\\'utilisateur</string>\n    <string name=\"tag_related_sound_file\">Fichier son associé</string>\n    <string name=\"tag_datetime_original\">Date Heure Original</string>\n    <string name=\"tag_datetime_digitized\">Date Heure Numérisée</string>\n    <string name=\"tag_offset_time\">Temps de décalage</string>\n    <string name=\"tag_offset_time_original\">Temps de décalage Original</string>\n    <string name=\"tag_offset_time_digitized\">Temps de décalage numérisé</string>\n    <string name=\"tag_subsec_time\">Temps Sub Sec</string>\n    <string name=\"tag_subsec_time_digitized\">Temps Sub Sec numérisé</string>\n    <string name=\"tag_exposure_time\">Temps d\\'exposition</string>\n    <string name=\"tag_f_number\">Nombre F</string>\n    <string name=\"tag_exposure_program\">Programme d\\'exposition</string>\n    <string name=\"tag_spectral_sensitivity\">Sensibilité spectrale</string>\n    <string name=\"tag_photographic_sensitivity\">Sensibilité photographique</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Type de sensibilité</string>\n    <string name=\"tag_standard_output_sensitivity\">Sensibilité de sortie standard</string>\n    <string name=\"tag_recommended_exposure_index\">Indice d\\'exposition recommandé</string>\n    <string name=\"tag_iso_speed\">Vitesse ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Vitesse ISO Latitude yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Vitesse ISO Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Vitesse d\\'obturation</string>\n    <string name=\"tag_aperture_value\">Valeur d\\'ouverture</string>\n    <string name=\"tag_brightness_value\">Valeur de luminosité</string>\n    <string name=\"tag_exposure_bias_value\">Valeur du biais d\\'exposition</string>\n    <string name=\"tag_max_aperture_value\">Valeur d\\'ouverture maximale</string>\n    <string name=\"tag_subject_distance\">Distance du sujet</string>\n    <string name=\"tag_metering_mode\">Mode de mesure</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Aire du sujet</string>\n    <string name=\"tag_focal_length\">Longueur focale</string>\n    <string name=\"tag_flash_energy\">Énergie flash</string>\n    <string name=\"tag_focal_plane_x_resolution\">Plan focal X Résolution</string>\n    <string name=\"tag_focal_plane_y_resolution\">Plan focal Y Résolution</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Unité de résolution du plan focal</string>\n    <string name=\"tag_subject_location\">Localisation du sujet</string>\n    <string name=\"tag_exposure_index\">Indice d\\'exposition</string>\n    <string name=\"tag_sensing_method\">Méthode de détection</string>\n    <string name=\"tag_file_source\">Source du fichier</string>\n    <string name=\"tag_cfa_pattern\">Motif CFA</string>\n    <string name=\"tag_custom_rendered\">Rendu personnalisé</string>\n    <string name=\"tag_exposure_mode\">Mode d\\'exposition</string>\n    <string name=\"tag_white_balance\">Balance Blanche</string>\n    <string name=\"tag_digital_zoom_ratio\">Digital Zoom Ratio</string>\n    <string name=\"material_you_switch_sub\">Un Material que vous utilisez</string>\n    <string name=\"compose_switch_sub\">Le Jetpack Compose Material que vous utilisez</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"fluent_switch_sub\">Utilise le systeme de design \\\"Fluent\\\"</string>\n    <string name=\"cupertino_switch_sub\">Utilise le système de design dit de \\\"Cupertino\\\"</string>\n    <string name=\"legacy\">Légende</string>\n    <string name=\"engine_mode\">Mode moteur</string>\n    <string name=\"legacy_and_lstm\">Légende &amp; LSTM</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"path_omit\">Chemin d\\'accès Omit</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Longueur focale en équivalent 35 mm</string>\n    <string name=\"tag_scene_capture_type\">Type de capture de scène</string>\n    <string name=\"tag_gain_control\">Contrôle de gain</string>\n    <string name=\"tag_contrast\">Contraste</string>\n    <string name=\"tag_saturation\">Saturation</string>\n    <string name=\"tag_sharpness\">Netteté</string>\n    <string name=\"tag_device_setting_description\">Description des paramètres de l\\'appareil</string>\n    <string name=\"tag_subject_distance_range\">Plage de distance du sujet</string>\n    <string name=\"helper_grid_sub\">Affiche une grille de soutien au-dessus de la zone de dessin pour aider à des manipulations précises</string>\n    <string name=\"enhanced_zoom_blur\">Flou de zoom amélioré</string>\n    <string name=\"laplacian_simple\">Laplacien simple</string>\n    <string name=\"sobel_simple\">Sobel simple</string>\n    <string name=\"helper_grid\">Grille d\\'aide</string>\n    <string name=\"grid_color\">Couleur de la grille</string>\n    <string name=\"cell_width\">Largeur de cellule</string>\n    <string name=\"cell_height\">Hauteur de cellule</string>\n    <string name=\"main_screen_title\">Titre de l\\'écran principal</string>\n    <string name=\"compact_selectors\">Sélecteurs compacts</string>\n    <string name=\"compact_selectors_sub\">Certains contrôles de sélection utiliseront un agencement compact pour prendre moins de place</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Accordez la permission d\\'accès à la caméra dans les paramètres pour capturer une image</string>\n    <string name=\"layout\">Mise en page</string>\n    <string name=\"lut_library\">Bibliothèque LUT</string>\n    <string name=\"lut_library_sub\">Téléchargez une collection de LUTs que vous pouvez appliquer après le téléchargement</string>\n    <string name=\"lut_library_update_sub\">Mettez à jour la collection de LUTs (seules les nouvelles seront mises en file d\\'attente), que vous pouvez appliquer après le téléchargement</string>\n    <string name=\"tag_image_unique_id\">Identifiant unique d\\'image</string>\n    <string name=\"tag_camera_owner_name\">Nom du propriétaire de caméra</string>\n    <string name=\"tag_lens_specification\">Spécification de lentils</string>\n    <string name=\"tag_body_serial_number\">Numéro de Série du Corps</string>\n    <string name=\"tag_lens_model\">Modèle de lentille</string>\n    <string name=\"tag_lens_make\">Créer un objectif</string>\n    <string name=\"harmony_complementary\">Complémentaire</string>\n    <string name=\"triangle\">Triangle</string>\n    <string name=\"tones\">Tons</string>\n    <string name=\"shades\">Ombrages</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"links\">Liens</string>\n    <string name=\"star\">Étoile</string>\n    <string name=\"linear\">Linéaire</string>\n    <string name=\"template\">Modèle</string>\n    <string name=\"center\">Milieu</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"coffee\">Café</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"octaves\">Octaves</string>\n    <string name=\"gain\">Gain</string>\n    <string name=\"histogram\">Histogramme</string>\n    <string name=\"mask\">Masque</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"cubic\">Cubique</string>\n    <string name=\"frequency\">Fréquence</string>\n    <string name=\"polygon\">Polygone</string>\n    <string name=\"import_word\">Importer</string>\n    <string name=\"export\">Exporter</string>\n    <string name=\"position\">Position</string>\n    <string name=\"tag_lens_serial_number\">Numéro de Série de l\\'Objectif</string>\n    <string name=\"tag_gps_version_id\">ID de la version du GPS</string>\n    <string name=\"tag_gps_latitude\">Latitude du GPS</string>\n    <string name=\"image_cutting\">Découpage d\\'images</string>\n    <string name=\"image_cutting_sub\">Découper une partie de l\\'image et fusionner les parties restantes (peut être inversé) par des lignes verticales ou horizontales</string>\n    <string name=\"tag_rw2_sensor_top_border\">Bordure supérieure du capteur</string>\n    <string name=\"tag_rw2_sensor_left_border\">Bordure gauche du capteur</string>\n    <string name=\"tag_gps_altitude_ref\">Altitude GPS de référence</string>\n    <string name=\"tag_gps_altitude\">Altitude GPS</string>\n    <string name=\"tag_gps_speed_ref\">Vitesse GPS de référence</string>\n    <string name=\"tag_gps_longitude\">Longitude GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Latitude GPS de référence</string>\n    <string name=\"tag_gps_longitude_ref\">Longitude GPS de référence</string>\n    <string name=\"tag_gps_timestamp\">Horodatage GPS</string>\n    <string name=\"tag_gps_satellites\">Satellites GPS</string>\n    <string name=\"tag_gps_status\">Statut GPS</string>\n    <string name=\"tag_gps_measure_mode\">Mode de mesure GPS</string>\n    <string name=\"tag_gps_speed\">Vitesse GPS</string>\n    <string name=\"tag_interoperability_index\">Index d\\'interopérabilité</string>\n    <string name=\"tag_dng_version\">Version DNG</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Bordure inférieure du capteur</string>\n    <string name=\"tag_rw2_sensor_right_border\">Bordure droite du capteur</string>\n    <string name=\"draw_text_sub\">Dessiner le texte sur le chemin avec la police et la couleur sélectionnés</string>\n    <string name=\"font_size\">Taille de la police</string>\n    <string name=\"watermark_size\">Taille du filigrane</string>\n    <string name=\"tag_default_crop_size\">Taille de rognage par défaut</string>\n    <string name=\"tag_orf_preview_image_length\">Longueur de l\\'image de prévisualisation</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS Track</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Image Direction Reference</string>\n    <string name=\"tag_gps_img_direction\">GPS Image direction</string>\n    <string name=\"tag_gps_map_datum\">GPS date de la carte</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Référence</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitude Référence</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Longitude</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Référence</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Référence</string>\n    <string name=\"tag_gps_dest_distance\">GPS Dest Distance</string>\n    <string name=\"tag_gps_processing_method\">GPS Processing Methode</string>\n    <string name=\"tag_gps_area_information\">GPS information de la zone</string>\n    <string name=\"tag_gps_datestamp\">Date du GPS</string>\n    <string name=\"tag_gps_differential\">Différentiel GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS erreur de positionnement H</string>\n    <string name=\"tag_orf_preview_image_start\">Démarrage de la prévisualisation de l\\'image</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect du cadre</string>\n    <string name=\"repeat_text\">Répétez le texte</string>\n    <string name=\"repeat_text_sub\">Le texte actuel sera répété jusqu\\'à la fin du chemin au lieu d\\'être dessiné une seule fois</string>\n    <string name=\"open_edit_instead_of_preview\">Ouvrir l\\'édition au lieu de la prévisualisation</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Quand vous ouvrez une image avec ImageToolbox, le panneau d\\'édition sera visible au lieu de celui de prévisualisation</string>\n    <string name=\"document_scanner\">Numériseur de document</string>\n    <string name=\"document_scanner_sub\">Numérisez des documents et enregistrez-les en fichiers PDF ou en images</string>\n    <string name=\"click_to_start_scanning\">Cliquez pour commencer la numérisation</string>\n    <string name=\"start_scanning\">Commencer la numérisation</string>\n    <string name=\"save_as_pdf\">Enregistrer en PDF</string>\n    <string name=\"share_as_pdf\">Partager en PDF</string>\n    <string name=\"options_below_is_for_images\">Les options ci-dessous sont utilisées lors d\\'un enregistrement en image et non en PDF</string>\n    <string name=\"color_to_ignore\">Couleur à ignorer</string>\n    <string name=\"create_new\">Créer un nouveau</string>\n    <string name=\"create_template\">Créer un modèle</string>\n    <string name=\"template_name\">Nom du modèle</string>\n    <string name=\"as_file\">En tant que fichier</string>\n    <string name=\"save_as_file\">Enregistrer en tant que fichier</string>\n    <string name=\"save_as_qr_code_image\">Enregistrer en tant qu\\'image QR code</string>\n    <string name=\"delete_template\">Supprimer le modèle</string>\n    <string name=\"add_image\">Ajouter une image</string>\n    <string name=\"image_stacking\">Empilement d\\'images</string>\n    <string name=\"image_stacking_sub\">Empiler les images les unes au dessus des autres avec le fondu sélectionné</string>\n    <string name=\"top_left\">En haut à gauche</string>\n    <string name=\"top_right\">En haut à droite</string>\n    <string name=\"bottom_left\">En bas à gauche</string>\n    <string name=\"bottom_right\">En bas à droite</string>\n    <string name=\"top_center\">En haut au milieu</string>\n    <string name=\"center_right\">Au centre à droite</string>\n    <string name=\"bottom_center\">En bas au centre</string>\n    <string name=\"center_left\">Au centre à gauche</string>\n    <string name=\"target_image\">Image cible</string>\n    <string name=\"no_favorite_options_selected\">Aucune option favorite sélectionnée, ajoutez-les dans la page d\\'outils</string>\n    <string name=\"add_favorites\">Ajouter des favoris</string>\n    <string name=\"harmony_analogous\">Analogue</string>\n    <string name=\"tints\">Tintes</string>\n    <string name=\"color_mixing\">Mélange des couleurs</string>\n    <string name=\"color_info\">Information sur les couleurs</string>\n    <string name=\"dash_size\">Taille du tiret</string>\n    <string name=\"draw_mode_image_sub\">Utiliser l\\'image sélectionnée pour la dessiner le long du chemin donné</string>\n    <string name=\"draw_image_sub\">Cette image sera utilisée comme entrée répétitive du chemin tracé</string>\n    <string name=\"outlined_triangle_sub\">Dessine le triangle décrit du point de départ au point final</string>\n    <string name=\"triangle_sub\">Dessine le triangle décrit du point de départ au point final</string>\n    <string name=\"outlined_triangle\">Triangle décrit</string>\n    <string name=\"polygon_sub\">Dessine un polygone du point de départ au point final</string>\n    <string name=\"outlined_polygon\">Polygone décrit</string>\n    <string name=\"outlined_polygon_sub\">Dessine le polygone décrit du point de départ au point final</string>\n    <string name=\"vertices\">Sommets</string>\n    <string name=\"draw_regular_polygon\">Dessiner un polygone régulier</string>\n    <string name=\"draw_regular_polygon_sub\">Dessinez un polygone qui sera régulier au lieu de forme libre</string>\n    <string name=\"star_sub\">Dessine l\\'étoile du point de départ au point final</string>\n    <string name=\"outlined_star\">Étoile décrite</string>\n    <string name=\"outlined_star_sub\">Dessine l\\'étoile décrite du point de départ au point final</string>\n    <string name=\"inner_radius_ratio\">Rapport de rayon intérieur</string>\n    <string name=\"draw_regular_star\">Dessiner une étoile régulière</string>\n    <string name=\"draw_regular_star_sub\">Dessinez une étoile qui sera régulière au lieu de forme libre</string>\n    <string name=\"antialias\">Anticrénelage</string>\n    <string name=\"antialias_sub\">Permet l\\'anticrénelage pour éviter les bords tranchants</string>\n    <string name=\"equalize_histogram_hsv\">Égaliser l\\'histogramme HSV</string>\n    <string name=\"equalize_histogram\">Égaliser l\\'histogramme</string>\n    <string name=\"enter_percentage\">Entrez le pourcentage</string>\n    <string name=\"allow_enter_by_text_field\">Autoriser la saisie par champ de texte</string>\n    <string name=\"allow_enter_by_text_field_sub\">Active le champ de texte derrière la sélection des préréglages, pour les saisir à la volée</string>\n    <string name=\"scale_color_space\">Espace colorimétrique à l\\'échelle</string>\n    <string name=\"equalize_histogram_pixelation\">Égaliser la pixellisation de l\\'histogramme</string>\n    <string name=\"grid_size_x\">Taille de la grille X</string>\n    <string name=\"grid_size_y\">Taille de grille Y</string>\n    <string name=\"equalize_histogram_adaptive\">Égaliser l\\'histogramme adaptatif</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Égaliser le LUV adaptatif de l\\'histogramme</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Égaliser l\\'histogramme LAB adaptatif</string>\n    <string name=\"clahe\">CLAHÉ</string>\n    <string name=\"clahe_lab\">LABORATOIRE CLAHE</string>\n    <string name=\"clahe_luv\">CLAHÉ LUV</string>\n    <string name=\"crop_to_content\">Recadrer au contenu</string>\n    <string name=\"frame_color\">Couleur du cadre</string>\n    <string name=\"no_template_filters\">Aucun filtre de modèle ajouté</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Le code QR scanné n\\'est pas un modèle de filtre valide</string>\n    <string name=\"scan_qr_code\">Scanner le code QR</string>\n    <string name=\"opened_file_have_no_filter_template\">Le fichier sélectionné ne contient aucune donnée de modèle de filtre</string>\n    <string name=\"select_template_preview\">Cette image sera utilisée pour prévisualiser ce modèle de filtre</string>\n    <string name=\"template_filter\">Filtre de modèle</string>\n    <string name=\"as_qr_code\">Comme image de code QR</string>\n    <string name=\"delete_template_warn\">Vous êtes sur le point de supprimer le filtre de modèle sélectionné. Cette opération est irréversible</string>\n    <string name=\"added_filter_template\">Modèle de filtre ajouté avec le nom \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Aperçu du filtre</string>\n    <string name=\"qr_code\">QR et code-barres</string>\n    <string name=\"qr_code_sub\">Scannez le code QR et obtenez son contenu ou collez votre chaîne pour en générer une nouvelle</string>\n    <string name=\"code_content\">Contenu du code</string>\n    <string name=\"scan_qr_code_to_replace_content\">Scannez n\\'importe quel code-barres pour remplacer le contenu dans le champ, ou tapez quelque chose pour générer un nouveau code-barres avec le type sélectionné</string>\n    <string name=\"qr_description\">QR descriptif</string>\n    <string name=\"min\">Min.</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Accorder l\\'autorisation à la caméra dans les paramètres pour scanner le code QR</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Accorder l\\'autorisation à l\\'appareil photo dans les paramètres pour numériser le scanner de documents</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Homme noir</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadrique</string>\n    <string name=\"gaussian\">Gaussien</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Cannelure 16</string>\n    <string name=\"spline36\">Cannelure 36</string>\n    <string name=\"spline64\">Cannelure 64</string>\n    <string name=\"kaiser\">kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-Il</string>\n    <string name=\"box\">Boîte</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">L\\'interpolation cubique permet une mise à l\\'échelle plus fluide en prenant en compte les 16 pixels les plus proches, ce qui donne de meilleurs résultats que l\\'interpolation bilinéaire.</string>\n    <string name=\"bspline_sub\">Utilise des fonctions polynomiales définies par morceaux pour interpoler et approximer en douceur une courbe ou une surface, une représentation de forme flexible et continue</string>\n    <string name=\"hamming_sub\">Une fonction de fenêtre utilisée pour réduire les fuites spectrales en effilant les bords d\\'un signal, utile dans le traitement du signal</string>\n    <string name=\"hanning_sub\">Une variante de la fenêtre de Hann, couramment utilisée pour réduire les fuites spectrales dans les applications de traitement du signal</string>\n    <string name=\"blackman_sub\">Une fonction de fenêtre qui offre une bonne résolution en fréquence en minimisant les fuites spectrales, souvent utilisée dans le traitement du signal</string>\n    <string name=\"welch_sub\">Une fonction de fenêtre conçue pour offrir une bonne résolution en fréquence avec une fuite spectrale réduite, souvent utilisée dans les applications de traitement du signal</string>\n    <string name=\"quadric_sub\">Une méthode qui utilise une fonction quadratique pour l\\'interpolation, fournissant des résultats fluides et continus</string>\n    <string name=\"gaussian_sub\">Une méthode d\\'interpolation qui applique une fonction gaussienne, utile pour lisser et réduire le bruit dans les images</string>\n    <string name=\"sphinx_sub\">Une méthode de rééchantillonnage avancée offrant une interpolation de haute qualité avec un minimum d\\'artefacts</string>\n    <string name=\"bartlett_sub\">Une fonction de fenêtre triangulaire utilisée dans le traitement du signal pour réduire les fuites spectrales</string>\n    <string name=\"robidoux_sub\">Une méthode d\\'interpolation de haute qualité optimisée pour le redimensionnement naturel de l\\'image, équilibrant la netteté et la douceur</string>\n    <string name=\"robidoux_sharp_sub\">Une variante plus nette de la méthode Robidoux, optimisée pour un redimensionnement d\\'image net</string>\n    <string name=\"spline16_sub\">Une méthode d\\'interpolation basée sur les splines qui fournit des résultats fluides à l\\'aide d\\'un filtre à 16 clics</string>\n    <string name=\"spline36_sub\">Une méthode d\\'interpolation basée sur les splines qui fournit des résultats fluides à l\\'aide d\\'un filtre à 36 clics</string>\n    <string name=\"spline64_sub\">Une méthode d\\'interpolation basée sur les splines qui fournit des résultats fluides à l\\'aide d\\'un filtre à 64 clics</string>\n    <string name=\"kaiser_sub\">Une méthode d\\'interpolation qui utilise la fenêtre Kaiser, offrant un bon contrôle sur le compromis entre la largeur du lobe principal et le niveau des lobes latéraux</string>\n    <string name=\"bartlett_hann_sub\">Une fonction de fenêtre hybride combinant les fenêtres Bartlett et Hann, utilisée pour réduire les fuites spectrales dans le traitement du signal</string>\n    <string name=\"box_sub\">Une méthode de rééchantillonnage simple qui utilise la moyenne des valeurs de pixels les plus proches, ce qui donne souvent une apparence en bloc</string>\n    <string name=\"bohman_sub\">Une fonction de fenêtre utilisée pour réduire les fuites spectrales, offrant une bonne résolution de fréquence dans les applications de traitement du signal</string>\n    <string name=\"lanczos2_sub\">Une méthode de rééchantillonnage qui utilise un filtre Lanczos à 2 lobes pour une interpolation de haute qualité avec un minimum d\\'artefacts</string>\n    <string name=\"lanczos3_sub\">Une méthode de rééchantillonnage qui utilise un filtre Lanczos à 3 lobes pour une interpolation de haute qualité avec un minimum d\\'artefacts</string>\n    <string name=\"lanczos4_sub\">Une méthode de rééchantillonnage qui utilise un filtre Lanczos à 4 lobes pour une interpolation de haute qualité avec un minimum d\\'artefacts</string>\n    <string name=\"lanczos2_jinc_sub\">Une variante du filtre Lanczos 2 qui utilise la fonction jinc, offrant une interpolation de haute qualité avec un minimum d\\'artefacts</string>\n    <string name=\"lanczos3_jinc_sub\">Une variante du filtre Lanczos 3 qui utilise la fonction jinc, offrant une interpolation de haute qualité avec un minimum d\\'artefacts</string>\n    <string name=\"lanczos4_jinc_sub\">Une variante du filtre Lanczos 4 qui utilise la fonction jinc, offrant une interpolation de haute qualité avec un minimum d\\'artefacts</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Variante de moyenne pondérée elliptique (EWA) du filtre Hanning pour une interpolation et un rééchantillonnage en douceur</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Variante Elliptical Weighted Average (EWA) du filtre Robidoux pour un rééchantillonnage de haute qualité</string>\n    <string name=\"ewa_blackman\">Homme noir EVE</string>\n    <string name=\"ewa_blackman_sub\">Variante Elliptical Weighted Average (EWA) du filtre Blackman pour minimiser les artefacts de sonnerie</string>\n    <string name=\"ewa_quadric\">EWA quadrique</string>\n    <string name=\"ewa_quadric_sub\">Variante Elliptical Weighted Average (EWA) du filtre Quadric pour une interpolation fluide</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Variante Elliptical Weighted Average (EWA) du filtre Robidoux Sharp pour des résultats plus nets</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Variante Elliptical Weighted Average (EWA) du filtre Lanczos 3 Jinc pour un rééchantillonnage de haute qualité avec un alias réduit</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Un filtre de rééchantillonnage conçu pour un traitement d\\'image de haute qualité avec un bon équilibre entre netteté et douceur</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Variante elliptique pondérée moyenne (EWA) du filtre Ginseng pour une qualité d\\'image améliorée</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Variante Elliptical Weighted Average (EWA) du filtre Lanczos Sharp pour obtenir des résultats nets avec un minimum d\\'artefacts</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA le plus pointu</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Variante Elliptical Weighted Average (EWA) du filtre Lanczos 4 Sharpest pour un rééchantillonnage d\\'image extrêmement net</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Variante Elliptical Weighted Average (EWA) du filtre Lanczos Soft pour un rééchantillonnage d\\'image plus fluide</string>\n    <string name=\"haasn_soft\">Haasn Doux</string>\n    <string name=\"haasn_soft_sub\">Un filtre de rééchantillonnage conçu par Haasn pour une mise à l\\'échelle de l\\'image fluide et sans artefacts</string>\n    <string name=\"format_conversion\">Conversion de formats</string>\n    <string name=\"format_conversion_sub\">Convertir un lot d\\'images d\\'un format à un autre</string>\n    <string name=\"dismiss_forever\">Rejeter pour toujours</string>\n    <string name=\"bins_count\">Nombre de bacs</string>\n    <string name=\"clahe_hsl\">LGV Clahé</string>\n    <string name=\"clahe_hsv\">Clahé HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Égaliser l\\'histogramme HSL adaptatif</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Égaliser l\\'histogramme HSV adaptatif</string>\n    <string name=\"edge_mode\">Mode bord</string>\n    <string name=\"clip\">Agrafe</string>\n    <string name=\"wrap\">Envelopper</string>\n    <string name=\"color_blind_scheme\">Daltonisme</string>\n    <string name=\"color_blind_scheme_sub\">Sélectionnez le mode pour adapter les couleurs du thème à la variante de daltonisme sélectionnée</string>\n    <string name=\"protanomaly_sub\">Difficulté à distinguer les teintes rouges et vertes</string>\n    <string name=\"deuteranomaly_sub\">Difficulté à distinguer les teintes vertes et rouges</string>\n    <string name=\"tritanomaly_sub\">Difficulté à distinguer les teintes bleues et jaunes</string>\n    <string name=\"protanopia_sub\">Incapacité à percevoir les teintes rouges</string>\n    <string name=\"deuteranopia_sub\">Incapacité à percevoir les teintes vertes</string>\n    <string name=\"tritanopia_sub\">Incapacité à percevoir les teintes bleues</string>\n    <string name=\"achromatomaly_sub\">Sensibilité réduite à toutes les couleurs</string>\n    <string name=\"achromatopsia_sub\">Daltonisme complet, ne voyant que des nuances de gris</string>\n    <string name=\"not_use_color_blind_scheme\">N\\'utilisez pas le système daltonien</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Les couleurs seront exactement telles que définies dans le thème</string>\n    <string name=\"sigmoidal\">Sigmoïde</string>\n    <string name=\"lagrange_2\">Lagrange2</string>\n    <string name=\"lagrange_2_sub\">Un filtre d\\'interpolation Lagrange d\\'ordre 2, adapté à une mise à l\\'échelle d\\'images de haute qualité avec des transitions douces</string>\n    <string name=\"lagrange_3\">Lagrange3</string>\n    <string name=\"lagrange_3_sub\">Un filtre d\\'interpolation Lagrange d\\'ordre 3, offrant une meilleure précision et des résultats plus fluides pour la mise à l\\'échelle des images</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Un filtre de rééchantillonnage Lanczos avec un ordre supérieur de 6, offrant une mise à l\\'échelle de l\\'image plus nette et plus précise</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Une variante du filtre Lanczos 6 utilisant une fonction Jinc pour une qualité de rééchantillonnage d\\'image améliorée</string>\n    <string name=\"linear_box_blur\">Flou de boîte linéaire</string>\n    <string name=\"linear_tent_blur\">Flou de tente linéaire</string>\n    <string name=\"linear_gaussian_box_blur\">Flou de boîte gaussien linéaire</string>\n    <string name=\"linear_stack_blur\">Flou de pile linéaire</string>\n    <string name=\"gaussian_box_blur\">Flou de boîte gaussien</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Flou gaussien rapide linéaire Suivant</string>\n    <string name=\"linear_fast_gaussian_blur\">Flou gaussien rapide linéaire</string>\n    <string name=\"linear_gaussian_blur\">Flou gaussien linéaire</string>\n    <string name=\"draw_filter_sub\">Choisissez un filtre pour l\\'utiliser comme peinture</string>\n    <string name=\"replace_filter\">Remplacer le filtre</string>\n    <string name=\"pick_filter_info\">Choisissez le filtre ci-dessous pour l\\'utiliser comme pinceau dans votre dessin</string>\n    <string name=\"tiff_compression_scheme\">Schéma de compression TIFF</string>\n    <string name=\"low_poly\">Faible poly</string>\n    <string name=\"sand_painting\">Peinture sur sable</string>\n    <string name=\"image_splitting\">Fractionnement d\\'image</string>\n    <string name=\"image_splitting_sub\">Diviser une seule image en lignes ou en colonnes</string>\n    <string name=\"fit_to_bounds\">Ajuster aux limites</string>\n    <string name=\"fit_to_bounds_sub\">Combinez le mode de redimensionnement du recadrage avec ce paramètre pour obtenir le comportement souhaité (Recadrage/Ajustement au rapport hauteur/largeur)</string>\n    <string name=\"languages_imported\">Langues importées avec succès</string>\n    <string name=\"backup_ocr_models\">Modèles OCR de sauvegarde</string>\n    <string name=\"palette_transfer\">Transfert de palettes</string>\n    <string name=\"enhanced_oil\">Huile améliorée</string>\n    <string name=\"simple_old_tv\">Vieille télé simple</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Croquis simple</string>\n    <string name=\"soft_glow\">Lueur douce</string>\n    <string name=\"color_poster\">Affiche couleur</string>\n    <string name=\"tri_tone\">Triton</string>\n    <string name=\"third_color\">Troisième couleur</string>\n    <string name=\"clahe_oklab\">Clahé Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahé Jzazbz</string>\n    <string name=\"polka_dot\">Pois</string>\n    <string name=\"clustered_2x2_dithering\">Dithering 2x2 en cluster</string>\n    <string name=\"clustered_4x4_dithering\">Dithering 4x4 en cluster</string>\n    <string name=\"clustered_8x8_dithering\">Dithering 8x8 en cluster</string>\n    <string name=\"yililoma_dithering\">Yililoma Tramage</string>\n    <string name=\"harmony_triadic\">Triadique</string>\n    <string name=\"harmony_split_complementary\">Split complémentaire</string>\n    <string name=\"harmony_tetradic\">Tétradique</string>\n    <string name=\"harmony_square\">Carré</string>\n    <string name=\"harmony_analogous_complementary\">Analogue + Complémentaire</string>\n    <string name=\"color_tools\">Outils de couleur</string>\n    <string name=\"color_tools_sub\">Mélangez, créez des tons, générez des nuances et bien plus encore</string>\n    <string name=\"color_harmonies\">Harmonies de couleurs</string>\n    <string name=\"color_shading\">Ombrage des couleurs</string>\n    <string name=\"variation\">Variation</string>\n    <string name=\"selected_color\">Couleur sélectionnée</string>\n    <string name=\"color_to_mix\">Couleur à mélanger</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Impossible d\\'utiliser Monet lorsque les couleurs dynamiques sont activées</string>\n    <string name=\"lut512x512\">512x512 LUT 2D</string>\n    <string name=\"target_lut_image\">Image LUT cible</string>\n    <string name=\"amatorka\">Un amateur</string>\n    <string name=\"miss_etikate\">Miss Étiquette</string>\n    <string name=\"soft_elegance\">Élégance douce</string>\n    <string name=\"soft_elegance_variant\">Variante élégance douce</string>\n    <string name=\"palette_transfer_variant\">Variante de transfert de palette</string>\n    <string name=\"cube_lut\">LUT 3D</string>\n    <string name=\"target_cube_lut_file\">Fichier LUT 3D cible (.cube / .CUBE)</string>\n    <string name=\"bleach_bypass\">Contournement de l\\'eau de Javel</string>\n    <string name=\"candlelight\">Aux chandelles</string>\n    <string name=\"drop_blues\">Laisser tomber le blues</string>\n    <string name=\"edgy_amber\">Ambre énervé</string>\n    <string name=\"fall_colors\">Couleurs d\\'automne</string>\n    <string name=\"film_stock_50\">Pellicule 50</string>\n    <string name=\"foggy_night\">Nuit brumeuse</string>\n    <string name=\"save_empty_lut\">Obtenir une image LUT neutre</string>\n    <string name=\"save_empty_lut_sub\">Tout d’abord, utilisez votre application de retouche photo préférée pour appliquer un filtre à la LUT neutre que vous pouvez obtenir ici. Pour que cela fonctionne correctement, la couleur de chaque pixel ne doit pas dépendre des autres pixels (par exemple, le flou ne fonctionnera pas). Une fois prêt, utilisez votre nouvelle image LUT comme entrée pour le filtre LUT 512*512</string>\n    <string name=\"pop_art\">Pop-Art</string>\n    <string name=\"celluloid\">Celluloïd</string>\n    <string name=\"golden_forest\">Forêt dorée</string>\n    <string name=\"greenish\">Verdâtre</string>\n    <string name=\"retro_yellow\">Jaune rétro</string>\n    <string name=\"links_preview\">Aperçu des liens</string>\n    <string name=\"links_preview_sub\">Permet la récupération de l\\'aperçu des liens aux endroits où vous pouvez obtenir du texte (QRCode, OCR, etc.)</string>\n    <string name=\"ico_size_warning\">Les fichiers ICO ne peuvent être enregistrés qu\\'à la taille maximale de 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF en WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Convertir des images GIF en images animées WEBP</string>\n    <string name=\"webp_tools\">Outils WEBP</string>\n    <string name=\"webp_tools_sub\">Convertir des images en image animée WEBP ou extraire des images d\\'une animation WEBP donnée</string>\n    <string name=\"webp_type_to_image\">WEBP en images</string>\n    <string name=\"webp_type_to_image_sub\">Convertir le fichier WEBP en lot d\\'images</string>\n    <string name=\"webp_type_to_webp_sub\">Convertir un lot d\\'images en fichier WEBP</string>\n    <string name=\"webp_type_to_webp\">Images vers WEBP</string>\n    <string name=\"select_webp_image_to_start\">Choisissez l\\'image WEBP pour commencer</string>\n    <string name=\"manage_storage_extra_types\">Pas d\\'accès complet aux fichiers</string>\n    <string name=\"manage_storage_extra_types_sub\">Autorisez l\\'accès à tous les fichiers pour voir JXL, QOI et autres images qui ne sont pas reconnues comme images sur Android. Sans l\\'autorisation, Image Toolbox ne peut pas afficher ces images</string>\n    <string name=\"default_draw_color\">Couleur de dessin par défaut</string>\n    <string name=\"default_draw_path_mode\">Mode de tracé par défaut</string>\n    <string name=\"add_timestamp\">Ajouter un horodatage</string>\n    <string name=\"add_timestamp_sub\">Active l\\'ajout d\\'horodatage au nom du fichier de sortie</string>\n    <string name=\"formatted_timestamp\">Horodatage formaté</string>\n    <string name=\"formatted_timestamp_sub\">Activer le formatage de l\\'horodatage dans le nom du fichier de sortie au lieu des millis de base</string>\n    <string name=\"enable_timestamps_to_format_them\">Activez les horodatages pour sélectionner leur format</string>\n    <string name=\"one_time_save_location\">Emplacement unique</string>\n    <string name=\"one_time_save_location_sub\">Afficher et modifier les emplacements de sauvegarde uniques que vous pouvez utiliser en appuyant longuement sur le bouton Enregistrer dans la plupart des options</string>\n    <string name=\"recently_used\">Récemment utilisé</string>\n    <string name=\"ci_channel\">canal CI</string>\n    <string name=\"group\">Groupe</string>\n    <string name=\"image_toolbox_in_telegram\">Boîte à outils d\\'images dans Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Rejoignez notre chat où vous pourrez discuter de tout ce que vous voulez et également consulter la chaîne CI où je publie des versions bêta et des annonces.</string>\n    <string name=\"ci_channel_sub\">Soyez informé des nouvelles versions de l\\'application et lisez les annonces</string>\n    <string name=\"fit_description\">Ajuster une image aux dimensions données et appliquer un flou ou une couleur à l\\'arrière-plan</string>\n    <string name=\"tools_arrangement\">Disposition des outils</string>\n    <string name=\"group_tools_by_type\">Regrouper les outils par type</string>\n    <string name=\"group_tools_by_type_sub\">Regroupe les outils sur l\\'écran principal par leur type au lieu d\\'une disposition de liste personnalisée</string>\n    <string name=\"default_values\">Valeurs par défaut</string>\n    <string name=\"system_bars_visibility\">Visibilité des barres système</string>\n    <string name=\"show_system_bars_by_swipe\">Afficher les barres système par balayage</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Permet de faire glisser pour afficher les barres système si elles sont masquées</string>\n    <string name=\"hide_all\">Masquer tout</string>\n    <string name=\"show_all\">Afficher tout</string>\n    <string name=\"hide_nav_bar\">Masquer la barre de navigation</string>\n    <string name=\"hide_status_bar\">Masquer la barre d\\'état</string>\n    <string name=\"noise_generation\">Génération de bruit</string>\n    <string name=\"noise_generation_sub\">Générez différents bruits comme Perlin ou d\\'autres types</string>\n    <string name=\"noise_type\">Type de bruit</string>\n    <string name=\"rotation_type\">Type de rotation</string>\n    <string name=\"fractal_type\">Type fractal</string>\n    <string name=\"lacunarity\">Lacunarité</string>\n    <string name=\"weighted_strength\">Force pondérée</string>\n    <string name=\"ping_pong_strength\">Force du ping-pong</string>\n    <string name=\"distance_function\">Fonction de distance</string>\n    <string name=\"return_type\">Type de retour</string>\n    <string name=\"jitter\">Gigue</string>\n    <string name=\"domain_warp\">Déformation de domaine</string>\n    <string name=\"alignment\">Alignement</string>\n    <string name=\"custom_filename\">Nom de fichier personnalisé</string>\n    <string name=\"custom_filename_sub\">Sélectionnez l\\'emplacement et le nom de fichier qui seront utilisés pour enregistrer l\\'image actuelle</string>\n    <string name=\"saved_to_custom\">Enregistré dans un dossier avec un nom personnalisé</string>\n    <string name=\"collage_maker\">Créateur de collages</string>\n    <string name=\"collage_maker_sub\">Créez des collages à partir de 20 images maximum</string>\n    <string name=\"collage_type\">Type de collage</string>\n    <string name=\"collages_info\">Maintenez l\\'image pour échanger, déplacer et zoomer pour ajuster la position</string>\n    <string name=\"disable_rotation\">Désactiver la rotation</string>\n    <string name=\"disable_rotation_sub\">Empêche la rotation des images avec des gestes à deux doigts</string>\n    <string name=\"enable_snapping_to_borders\">Activer l\\'alignement sur les bordures</string>\n    <string name=\"enable_snapping_to_borders_sub\">Après un déplacement ou un zoom, les images s\\'aligneront pour remplir les bords du cadre</string>\n    <string name=\"histogram_sub\">Histogramme d\\'image RVB ou luminosité pour vous aider à effectuer des ajustements</string>\n    <string name=\"image_for_histogram\">Cette image sera utilisée pour générer des histogrammes RVB et Luminosité</string>\n    <string name=\"tesseract_options\">Options de tesseract</string>\n    <string name=\"tesseract_options_sub\">Appliquer quelques variables d\\'entrée pour le moteur tesseract</string>\n    <string name=\"custom_options\">Options personnalisées</string>\n    <string name=\"custom_params_info\">Les options doivent être saisies en suivant ce modèle : \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Recadrage automatique</string>\n    <string name=\"free_corners\">Coins Libres</string>\n    <string name=\"free_corners_sub\">Recadrer l\\'image par polygone, cela corrige également la perspective</string>\n    <string name=\"coerce_points_to_image_bounds\">Contraindre les points aux limites de l\\'image</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Les points ne seront pas limités par les limites de l\\'image, ce qui est utile pour une correction de perspective plus précise</string>\n    <string name=\"spot_heal_sub\">Remplissage sensible au contenu sous le chemin tracé</string>\n    <string name=\"spot_heal\">Point de guérison</string>\n    <string name=\"use_circle_kernel\">Utiliser le noyau circulaire</string>\n    <string name=\"opening\">Ouverture</string>\n    <string name=\"closing\">Clôture</string>\n    <string name=\"morphological_gradient\">Dégradé Morphologique</string>\n    <string name=\"top_hat\">Chapeau haut de forme</string>\n    <string name=\"black_hat\">Chapeau noir</string>\n    <string name=\"tone_curves\">Courbes de tonalité</string>\n    <string name=\"reset_curves\">Réinitialiser les courbes</string>\n    <string name=\"reset_curves_sub\">Les courbes seront rétablies à leur valeur par défaut</string>\n    <string name=\"line_style\">Style de ligne</string>\n    <string name=\"gap_size\">Taille de l\\'écart</string>\n    <string name=\"dashed\">En pointillés</string>\n    <string name=\"dot_dashed\">Pointillé</string>\n    <string name=\"stamped\">Timbré</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Dessine une ligne pointillée le long du chemin tracé avec la taille d\\'espace spécifiée</string>\n    <string name=\"dot_dashed_sub\">Dessine des points et des lignes pointillées le long d\\'un chemin donné</string>\n    <string name=\"defaultt_sub\">Juste des lignes droites par défaut</string>\n    <string name=\"stamped_sub\">Dessine les formes sélectionnées le long du chemin avec un espacement spécifié</string>\n    <string name=\"zigzag_sub\">Dessine un zigzag ondulé le long du chemin</string>\n    <string name=\"zigzag_ratio\">Rapport de zigzag</string>\n    <string name=\"create_shortcut\">Créer un raccourci</string>\n    <string name=\"create_shortcut_title\">Choisissez l\\'outil à épingler</string>\n    <string name=\"create_shortcut_subtitle\">L\\'outil sera ajouté à l\\'écran d\\'accueil de votre lanceur en tant que raccourci, utilisez-le en combinaison avec le paramètre « Ignorer la sélection de fichiers » pour obtenir le comportement souhaité.</string>\n    <string name=\"dont_stack_frames\">N\\'empilez pas les cadres</string>\n    <string name=\"dont_stack_frames_sub\">Permet de supprimer les images précédentes, afin qu\\'elles ne s\\'empilent pas les unes sur les autres</string>\n    <string name=\"crossfade\">Fondu enchaîné</string>\n    <string name=\"crossfade_sub\">Les images seront fondues les unes dans les autres</string>\n    <string name=\"crossfade_count\">Nombre d’images de fondu enchaîné</string>\n    <string name=\"threshold_one\">Seuil un</string>\n    <string name=\"threshold_two\">Seuil deux</string>\n    <string name=\"canny\">Prudent</string>\n    <string name=\"mirror_101\">Miroir 101</string>\n    <string name=\"constant_rate_factor\">Facteur de taux constant (CRF)</string>\n    <string name=\"crf_sub\">Une valeur de %1$s signifie une compression lente, ce qui entraîne une taille de fichier relativement petite. %2$s signifie une compression plus rapide, ce qui donne un fichier volumineux.</string>\n    <string name=\"filter_preview_image_sub\">Modifier l\\'aperçu de l\\'image par défaut pour les filtres</string>\n    <string name=\"filter_preview_image\">Image d\\'aperçu</string>\n    <string name=\"hide\">Cacher</string>\n    <string name=\"show\">Montrer</string>\n    <string name=\"slider_type\">Type de curseur</string>\n    <string name=\"fancy\">Fantaisie</string>\n    <string name=\"material_2\">Matériel 2</string>\n    <string name=\"fancy_sub\">Un curseur au look sophistiqué. C\\'est l\\'option par défaut</string>\n    <string name=\"material_2_sub\">Un curseur Matériau 2</string>\n    <string name=\"material_you_slider_sub\">Un curseur Matériau Vous</string>\n    <string name=\"apply\">Appliquer</string>\n    <string name=\"center_align_dialog_buttons\">Boutons de la boîte de dialogue centrale</string>\n    <string name=\"center_align_dialog_buttons_sub\">Les boutons des boîtes de dialogue seront positionnés au centre plutôt qu\\'à gauche si possible</string>\n    <string name=\"open_source_licenses\">Licences Open Source</string>\n    <string name=\"open_source_licenses_sub\">Afficher les licences des bibliothèques open source utilisées dans cette application</string>\n    <string name=\"area\">Zone</string>\n    <string name=\"area_sub\">Rééchantillonnage en utilisant la relation entre les zones de pixels. Il s\\'agit peut-être d\\'une méthode privilégiée pour la décimation d\\'images, car elle donne des résultats sans moiré. Mais lorsque l\\'image est agrandie, cela ressemble à la méthode \\\"Nearest\\\".</string>\n    <string name=\"enable_tonemapping\">Activer le mappage de tons</string>\n    <string name=\"enter_percent\">Entrer %</string>\n    <string name=\"unknown_host\">Impossible d\\'accéder au site, essayez d\\'utiliser un VPN ou vérifiez si l\\'URL est correcte</string>\n    <string name=\"markup_layers\">Calques</string>\n    <string name=\"markup_layers_sub\">Mode Calques avec possibilité de placer librement des images, du texte et plus encore</string>\n    <string name=\"edit_layer\">Modifier le calque</string>\n    <string name=\"layers_on_image\">Calques sur l\\'image</string>\n    <string name=\"layers_on_image_sub\">Utilisez une image comme arrière-plan et ajoutez différents calques par-dessus</string>\n    <string name=\"layers_on_background\">Calques en arrière-plan</string>\n    <string name=\"layers_on_background_sub\">Identique à la première option mais avec de la couleur au lieu de l\\'image</string>\n    <string name=\"beta\">Bêta</string>\n    <string name=\"fast_settings_side\">Côté réglages rapides</string>\n    <string name=\"fast_settings_side_sub\">Ajoutez une bande flottante sur le côté sélectionné lors de l\\'édition des images, qui ouvrira les paramètres rapides lorsque vous cliquerez dessus</string>\n    <string name=\"clear_selection\">Effacer la sélection</string>\n    <string name=\"settings_group_visibility_hidden\">Le groupe de paramètres \\\"%1$s\\\" sera réduit par défaut</string>\n    <string name=\"settings_group_visibility_visible\">Le groupe de paramètres \\\"%1$s\\\" sera étendu par défaut</string>\n    <string name=\"base_64_tools\">Outils Base64</string>\n    <string name=\"base_64_tools_sub\">Décoder la chaîne Base64 en image ou encoder l\\'image au format Base64</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">La valeur fournie n\\'est pas une chaîne Base64 valide</string>\n    <string name=\"copy_not_a_valid_base_64\">Impossible de copier une chaîne Base64 vide ou invalide</string>\n    <string name=\"paste_base_64\">Coller Base64</string>\n    <string name=\"copy_base_64\">Copier Base64</string>\n    <string name=\"base_64_tips\">Chargez l\\'image pour copier ou enregistrer la chaîne Base64. Si vous avez la chaîne elle-même, vous pouvez la coller ci-dessus pour obtenir l\\'image</string>\n    <string name=\"save_base_64\">Enregistrer Base64</string>\n    <string name=\"share_base_64\">Partager Base64</string>\n    <string name=\"options\">Possibilités</string>\n    <string name=\"actions\">Actes</string>\n    <string name=\"import_base_64\">Importer Base64</string>\n    <string name=\"base_64_actions\">Actions Base64</string>\n    <string name=\"add_outline\">Ajouter un contour</string>\n    <string name=\"add_outline_sub\">Ajouter un contour autour du texte avec une couleur et une largeur spécifiées</string>\n    <string name=\"outline_color\">Couleur du contour</string>\n    <string name=\"outline_size\">Taille du contour</string>\n    <string name=\"rotation\">Rotation</string>\n    <string name=\"checksum_as_filename\">Somme de contrôle comme nom de fichier</string>\n    <string name=\"checksum_as_filename_sub\">Les images de sortie auront un nom correspondant à leur somme de contrôle de données</string>\n    <string name=\"free_software_partner\">Logiciel Libre (Partenaire)</string>\n    <string name=\"free_software_partner_sub\">Logiciels plus utiles dans le canal partenaire des applications Android</string>\n    <string name=\"algorithms\">Algorithme</string>\n    <string name=\"checksum_tools\">Outils de somme de contrôle</string>\n    <string name=\"checksum_tools_sub\">Comparez les sommes de contrôle, calculez les hachages ou créez des chaînes hexadécimales à partir de fichiers en utilisant différents algorithmes de hachage</string>\n    <string name=\"calculate\">Calculer</string>\n    <string name=\"text_hash\">Hachage de texte</string>\n    <string name=\"checksum\">Somme de contrôle</string>\n    <string name=\"pick_file_to_checksum\">Choisissez le fichier pour calculer sa somme de contrôle en fonction de l\\'algorithme sélectionné</string>\n    <string name=\"enter_text_to_checksum\">Entrez du texte pour calculer sa somme de contrôle en fonction de l\\'algorithme sélectionné</string>\n    <string name=\"source_checksum\">Somme de contrôle source</string>\n    <string name=\"checksum_to_compare\">Somme de contrôle à comparer</string>\n    <string name=\"match\">Correspondre!</string>\n    <string name=\"difference\">Différence</string>\n    <string name=\"match_sub\">Les sommes de contrôle sont égales, cela peut être sûr</string>\n    <string name=\"difference_sub\">Les sommes de contrôle ne sont pas égales, le fichier peut être dangereux !</string>\n    <string name=\"mesh_gradients\">Dégradés de maillage</string>\n    <string name=\"collection_mesh_gradients_sub\">Regardez la collection en ligne de dégradés de maillage</string>\n    <string name=\"wrong_font\">Seules les polices TTF et OTF peuvent être importées</string>\n    <string name=\"import_font\">Importer la police (TTF/OTF)</string>\n    <string name=\"export_fonts\">Exporter des polices</string>\n    <string name=\"imported_fonts\">Polices importées</string>\n    <string name=\"error_while_saving\">Erreur lors de la tentative d\\'enregistrement, essayez de modifier le dossier de sortie</string>\n    <string name=\"filename_is_not_set\">Le nom du fichier n\\'est pas défini</string>\n    <string name=\"none\">Aucun</string>\n    <string name=\"custom_pages\">Pages personnalisées</string>\n    <string name=\"pages_selection\">Sélection des pages</string>\n    <string name=\"tool_exit_confirmation\">Confirmation de sortie d\\'outil</string>\n    <string name=\"tool_exit_confirmation_sub\">Si vous avez des modifications non enregistrées lors de l\\'utilisation d\\'outils particuliers et essayez de le fermer, une boîte de dialogue de confirmation s\\'affichera.</string>\n    <string name=\"edit_exif_screen\">Modifier EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Modifier les métadonnées d\\'une seule image sans recompression</string>\n    <string name=\"edit_exif_tag\">Appuyez pour modifier les balises disponibles</string>\n    <string name=\"change_sticker\">Changer l\\'autocollant</string>\n    <string name=\"fit_width\">Ajuster la largeur</string>\n    <string name=\"fit_height\">Hauteur d\\'ajustement</string>\n    <string name=\"batch_compare\">Comparaison par lots</string>\n    <string name=\"pick_files_to_checksum\">Choisissez un ou plusieurs fichiers pour calculer sa somme de contrôle en fonction de l\\'algorithme sélectionné</string>\n    <string name=\"pick_files\">Choisir des fichiers</string>\n    <string name=\"pick_directory\">Choisir un répertoire</string>\n    <string name=\"head_length_scale\">Échelle de longueur de tête</string>\n    <string name=\"stamp\">Timbre</string>\n    <string name=\"timestamp\">Horodatage</string>\n    <string name=\"format_pattern\">Modèle de formatage</string>\n    <string name=\"padding\">Rembourrage</string>\n    <string name=\"vertical_pivot_line\">Ligne de pivotement vertical</string>\n    <string name=\"horizontal_pivot_line\">Ligne pivot horizontale</string>\n    <string name=\"inverse_selection\">Sélection inverse</string>\n    <string name=\"inverse_vertical_selection_sub\">La partie coupée verticalement sera conservée au lieu de fusionner les pièces autour de la zone coupée.</string>\n    <string name=\"inverse_horizontal_selection_sub\">La partie coupée horizontalement sera conservée au lieu de fusionner les pièces autour de la zone coupée.</string>\n    <string name=\"collection_mesh_gradients\">Collection de dégradés de maillage</string>\n    <string name=\"mesh_gradients_sub\">Créez un dégradé de maillage avec une quantité de nœuds et une résolution personnalisées</string>\n    <string name=\"gradient_maker_type_image_mesh\">Superposition de dégradé de maillage</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Composer un dégradé de maillage du haut des images données</string>\n    <string name=\"points_customization\">Personnalisation des points</string>\n    <string name=\"grid_size\">Taille de la grille</string>\n    <string name=\"resolution_x\">Résolution X</string>\n    <string name=\"resolution_y\">Résolution Y</string>\n    <string name=\"resolution\">Résolution</string>\n    <string name=\"pixel_by_pixel\">Pixel par pixel</string>\n    <string name=\"highlight_color\">Couleur de surbrillance</string>\n    <string name=\"pixel_comparison_type\">Type de comparaison de pixels</string>\n    <string name=\"scan_barcode\">Scanner le code-barres</string>\n    <string name=\"height_ratio\">Rapport de hauteur</string>\n    <string name=\"barcode_type\">Type de code-barres</string>\n    <string name=\"enforce_bw\">Appliquer le N/B</string>\n    <string name=\"enforce_bw_sub\">L\\'image du code-barres sera entièrement en noir et blanc et ne sera pas colorée par le thème de l\\'application.</string>\n    <string name=\"barcodes_sub\">Scannez n\\'importe quel code-barres (QR, EAN, AZTEC, …) et récupérez son contenu ou collez votre texte pour en générer un nouveau</string>\n    <string name=\"no_barcode_found\">Aucun code-barres trouvé</string>\n    <string name=\"generated_barcode_will_be_here\">Le code-barres généré sera ici</string>\n    <string name=\"audio_cover_extractor\">Couvertures audio</string>\n    <string name=\"audio_cover_extractor_sub\">Extrayez les images de couverture d\\'album à partir de fichiers audio, les formats les plus courants sont pris en charge</string>\n    <string name=\"pick_audio_to_start\">Choisissez l\\'audio pour commencer</string>\n    <string name=\"pick_audio\">Choisissez l\\'audio</string>\n    <string name=\"no_covers_found\">Aucune couverture trouvée</string>\n    <string name=\"send_logs\">Envoyer des journaux</string>\n    <string name=\"send_logs_sub\">Cliquez pour partager le fichier des journaux d\\'application, cela peut m\\'aider à repérer le problème et à le résoudre</string>\n    <string name=\"crash_title\">Oups… Quelque chose s\\'est mal passé</string>\n    <string name=\"crash_subtitle\">Vous pouvez me contacter en utilisant les options ci-dessous et j\\'essaierai de trouver une solution.\\n(N\\'oubliez pas de joindre les journaux)</string>\n    <string name=\"ocr_write_to_file\">Écrire dans un fichier</string>\n    <string name=\"ocr_write_to_file_sub\">Extrayez le texte d\\'un lot d\\'images et stockez-le dans un seul fichier texte</string>\n    <string name=\"ocr_write_to_metadata\">Écrire dans les métadonnées</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extrayez le texte de chaque image et placez-le dans les informations EXIF des photos relatives</string>\n    <string name=\"invisible_mode\">Mode invisible</string>\n    <string name=\"invisible_mode_sub\">Utilisez la stéganographie pour créer des filigranes invisibles à l\\'œil nu dans les octets de vos images</string>\n    <string name=\"use_lsb\">Utiliser LSB</string>\n    <string name=\"use_lsb_sub\">La méthode de stéganographie LSB (Less Significant Bit) sera utilisée, FD (Frequency Domain) sinon</string>\n    <string name=\"auto_remove_red_eyes\">Supprimer automatiquement les yeux rouges</string>\n    <string name=\"password\">Mot de passe</string>\n    <string name=\"unlock\">Ouvrir</string>\n    <string name=\"pdf_is_protected\">Le PDF est protégé</string>\n    <string name=\"operation_almost_complete\">Opération presque terminée. Annuler maintenant nécessitera de le redémarrer</string>\n    <string name=\"sort_by_date_modified\">Date de modification</string>\n    <string name=\"sort_by_date_modified_reversed\">Date de modification (inversée)</string>\n    <string name=\"sort_by_size\">Taille</string>\n    <string name=\"sort_by_size_reversed\">Taille (inversée)</string>\n    <string name=\"sort_by_mime_type\">Type MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Type MIME (inversé)</string>\n    <string name=\"sort_by_extension\">Extension</string>\n    <string name=\"sort_by_extension_reversed\">Extension (inversée)</string>\n    <string name=\"sort_by_date_added\">Date d\\'ajout</string>\n    <string name=\"sort_by_date_added_reversed\">Date d\\'ajout (inversée)</string>\n    <string name=\"left_to_right\">De gauche à droite</string>\n    <string name=\"right_to_left\">De droite à gauche</string>\n    <string name=\"top_to_bottom\">De haut en bas</string>\n    <string name=\"bottom_to_top\">De bas en haut</string>\n    <string name=\"liquid_glass\">Verre liquide</string>\n    <string name=\"liquid_glass_sub\">Un commutateur basé sur IOS 26 récemment annoncé et son système de conception en verre liquide</string>\n    <string name=\"pick_image_or_base64\">Choisissez une image ou collez/importez des données Base64 ci-dessous</string>\n    <string name=\"type_image_link\">Tapez le lien de l\\'image pour commencer</string>\n    <string name=\"paste_link\">Coller le lien</string>\n    <string name=\"kaleidoscope\">Kaléidoscope</string>\n    <string name=\"secondary_angle\">Angle secondaire</string>\n    <string name=\"sides\">Côtés</string>\n    <string name=\"channel_mix\">Mixage des chaînes</string>\n    <string name=\"blue_green\">Bleu vert</string>\n    <string name=\"red_blue\">Bleu rouge</string>\n    <string name=\"green_red\">Vert rouge</string>\n    <string name=\"into_red\">En rouge</string>\n    <string name=\"into_green\">En vert</string>\n    <string name=\"into_blue\">En bleu</string>\n    <string name=\"cyan\">Cyan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Jaune</string>\n    <string name=\"color_halftone\">Couleur Demi-teinte</string>\n    <string name=\"contour\">Contour</string>\n    <string name=\"levels\">Niveaux</string>\n    <string name=\"offset\">Compenser</string>\n    <string name=\"voronoi_crystallize\">Voronoï cristallise</string>\n    <string name=\"shape\">Forme</string>\n    <string name=\"stretch\">Extensible</string>\n    <string name=\"randomness\">Le hasard</string>\n    <string name=\"despeckle\">Détacher</string>\n    <string name=\"diffuse\">Diffuser</string>\n    <string name=\"dog\">Chien</string>\n    <string name=\"second_radius\">Deuxième rayon</string>\n    <string name=\"equalize\">Égaliser</string>\n    <string name=\"glow\">Briller</string>\n    <string name=\"whirl_and_pinch\">Tourbillonner et pincer</string>\n    <string name=\"pointillize\">Pointilliser</string>\n    <string name=\"border_color\">Couleur de la bordure</string>\n    <string name=\"polar_coordinates\">Coordonnées polaires</string>\n    <string name=\"rect_to_polar\">Rectifier vers polaire</string>\n    <string name=\"polar_to_rect\">Polaire à rectifier</string>\n    <string name=\"invert_in_circle\">Inverser en cercle</string>\n    <string name=\"reduce_noise\">Réduire le bruit</string>\n    <string name=\"simple_solarize\">Solarisation simple</string>\n    <string name=\"weave\">Tisser</string>\n    <string name=\"x_gap\">Écart X</string>\n    <string name=\"y_gap\">Écart en Y</string>\n    <string name=\"x_width\">Largeur X</string>\n    <string name=\"y_wdth\">Largeur Y</string>\n    <string name=\"twirl\">Tournoiement</string>\n    <string name=\"rubber_stmp\">Timbre en caoutchouc</string>\n    <string name=\"smear\">Frottis</string>\n    <string name=\"density\">Densité</string>\n    <string name=\"mix\">Mélanger</string>\n    <string name=\"sphere_lensh_distortion\">Distorsion de la lentille sphérique</string>\n    <string name=\"refraction_index\">Indice de réfraction</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Angle de propagation</string>\n    <string name=\"sparkle\">Éclat</string>\n    <string name=\"rays\">Rayons</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Pente</string>\n    <string name=\"moire\">Marie</string>\n    <string name=\"autumn\">Automne</string>\n    <string name=\"bone\">Os</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Hiver</string>\n    <string name=\"ocean\">Océan</string>\n    <string name=\"summer\">Été</string>\n    <string name=\"spring\">Printemps</string>\n    <string name=\"cool_variant\">Variante cool</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rose</string>\n    <string name=\"hot\">Chaud</string>\n    <string name=\"parula\">Mot</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Enfer</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Citoyens</string>\n    <string name=\"twilight\">Crépuscule</string>\n    <string name=\"twilight_shifted\">Crépuscule décalé</string>\n    <string name=\"auto_perspective\">Perspective automatique</string>\n    <string name=\"deskew\">Redressement</string>\n    <string name=\"allow_crop\">Autoriser le recadrage</string>\n    <string name=\"crop_or_perspective\">Recadrage ou perspective</string>\n    <string name=\"absolute\">Absolu</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Vert profond</string>\n    <string name=\"lens_correction\">Correction de l\\'objectif</string>\n    <string name=\"target_lens_profile\">Fichier de profil d\\'objectif cible au format JSON</string>\n    <string name=\"download_ready_lens_profiles\">Téléchargez les profils d\\'objectifs prêts à l\\'emploi</string>\n    <string name=\"part_percents\">Pourcentages partiels</string>\n    <string name=\"export_as_json\">Exporter au format JSON</string>\n    <string name=\"export_as_json_sub\">Copier la chaîne avec les données d\\'une palette sous forme de représentation json</string>\n    <string name=\"seam_carving\">Sculpture de couture</string>\n    <string name=\"home_screen\">Écran d\\'accueil</string>\n    <string name=\"lock_screen\">Écran de verrouillage</string>\n    <string name=\"built_in\">Intégré</string>\n    <string name=\"wallpapers_export\">Exportation de fonds d’écran</string>\n    <string name=\"refresh\">Rafraîchir</string>\n    <string name=\"wallpapers_export_sub\">Obtenez les fonds d\\'écran d\\'accueil, de verrouillage et intégrés actuels</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Autoriser l\\'accès à tous les fichiers, cela est nécessaire pour récupérer les fonds d\\'écran</string>\n    <string name=\"allow_read_media_images_for_wp\">Gérer l\\'autorisation de stockage externe ne suffit pas, vous devez autoriser l\\'accès à vos images, assurez-vous de sélectionner \\\"Autoriser tout\\\"</string>\n    <string name=\"add_preset_to_filename\">Ajouter un préréglage au nom de fichier</string>\n    <string name=\"add_preset_to_filename_sub\">Ajoute le suffixe avec le préréglage sélectionné au nom du fichier image</string>\n    <string name=\"add_image_scale_mode_to_filename\">Ajouter le mode d\\'échelle d\\'image au nom de fichier</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Ajoute le suffixe avec le mode d\\'échelle d\\'image sélectionné au nom du fichier image</string>\n    <string name=\"ascii_art\">Art Ascii</string>\n    <string name=\"ascii_art_sub\">Convertir l\\'image en texte ascii qui ressemblera à une image</string>\n    <string name=\"params\">Paramètres</string>\n    <string name=\"invert_colors_ascii_sub\">Applique un filtre négatif à l\\'image pour un meilleur résultat dans certains cas</string>\n    <string name=\"processing_screenshot\">Capture d\\'écran du traitement</string>\n    <string name=\"screenshot_not_captured_try_again\">Capture d\\'écran non capturée, réessayez</string>\n    <string name=\"skipped_saving\">Enregistrement ignoré</string>\n    <string name=\"skipped_saving_multiple\">%1$s fichiers ignorés</string>\n    <string name=\"allow_skip_if_larger\">Autoriser le saut si la taille est plus grande</string>\n    <string name=\"allow_skip_if_larger_sub\">Certains outils seront autorisés à ignorer l\\'enregistrement des images si la taille du fichier résultant est plus grande que l\\'original.</string>\n    <string name=\"qr_type_calendar_event\">Événement du calendrier</string>\n    <string name=\"qr_type_contact_info\">Contact</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Emplacement</string>\n    <string name=\"qr_type_phone\">Téléphone</string>\n    <string name=\"qr_type_plain\">Texte</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Réseau ouvert</string>\n    <string name=\"not_specified\">N / A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Téléphone</string>\n    <string name=\"message\">Message</string>\n    <string name=\"address\">Adresse</string>\n    <string name=\"subject\">Sujet</string>\n    <string name=\"body\">Corps</string>\n    <string name=\"name\">Nom</string>\n    <string name=\"organization\">Organisation</string>\n    <string name=\"title\">Titre</string>\n    <string name=\"phones\">Téléphones</string>\n    <string name=\"emails\">E-mails</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Adresses</string>\n    <string name=\"summary\">Résumé</string>\n    <string name=\"description\">Description</string>\n    <string name=\"location\">Emplacement</string>\n    <string name=\"organizer\">Organisateur</string>\n    <string name=\"start_date\">Date de début</string>\n    <string name=\"end_date\">Date de fin</string>\n    <string name=\"status\">Statut</string>\n    <string name=\"latitude\">Latitude</string>\n    <string name=\"longitude\">Longitude</string>\n    <string name=\"create_barcode\">Créer un code-barres</string>\n    <string name=\"edit_barcode\">Edit Barcode</string>\n    <string name=\"wifi_configuration\">Configuration Wi-Fi</string>\n    <string name=\"security\">Sécurité</string>\n    <string name=\"pick_contact\">Choisir un contact</string>\n    <string name=\"grant_contact_permission\">Accorder aux contacts l\\'autorisation dans les paramètres de remplir automatiquement à l\\'aide du contact sélectionné</string>\n    <string name=\"contact_info\">Coordonnées</string>\n    <string name=\"first_name\">Prénom</string>\n    <string name=\"middle_name\">Deuxième prénom</string>\n    <string name=\"last_name\">Nom de famille</string>\n    <string name=\"pronunciation\">Prononciation</string>\n    <string name=\"add_phone\">Ajouter un téléphone</string>\n    <string name=\"add_email\">Ajouter un e-mail</string>\n    <string name=\"add_address\">Ajouter une adresse</string>\n    <string name=\"website\">Site web</string>\n    <string name=\"add_website\">Ajouter un site Web</string>\n    <string name=\"formatted_name\">Nom formaté</string>\n    <string name=\"qr_code_top_image\">Cette image sera utilisée pour être placée au-dessus du code-barres</string>\n    <string name=\"code_customization\">Personnalisation des codes</string>\n    <string name=\"qr_logo_image\">Cette image sera utilisée comme logo au centre du code QR</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Rembourrage du logo</string>\n    <string name=\"logo_size\">Taille du logo</string>\n    <string name=\"logo_corners\">Coins logotés</string>\n    <string name=\"fourth_eye\">Quatrième œil</string>\n    <string name=\"fourth_eye_description\">Ajoute une symétrie oculaire au code QR en ajoutant un quatrième œil dans le coin inférieur</string>\n    <string name=\"pixel_shape\">Forme des pixels</string>\n    <string name=\"frame_shape\">Forme du cadre</string>\n    <string name=\"ball_shape\">Forme de boule</string>\n    <string name=\"error_correction_level\">Niveau de correction des erreurs</string>\n    <string name=\"dark_color\">Couleur foncée</string>\n    <string name=\"light_color\">Couleur claire</string>\n    <string name=\"hyper_os\">HyperOS</string>\n    <string name=\"hyper_os_sub\">Style similaire à Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Modèle de masque</string>\n    <string name=\"code_may_be_not_scannable\">Ce code peut ne pas être scannable, modifiez les paramètres d\\'apparence pour le rendre lisible sur tous les appareils</string>\n    <string name=\"not_scannable\">Non numérisable</string>\n    <string name=\"launcher_mode_sub\">Les outils ressembleront au lanceur d\\'applications sur l\\'écran d\\'accueil pour être plus compacts</string>\n    <string name=\"launcher_mode\">Mode lanceur</string>\n    <string name=\"flood_fill_sub\">Remplit une zone avec le pinceau et le style sélectionnés</string>\n    <string name=\"flood_fill\">Remplissage d\\'inondation</string>\n    <string name=\"spray\">Pulvérisation</string>\n    <string name=\"spray_sub\">Dessine un chemin de style graffiti</string>\n    <string name=\"square_particles\">Particules carrées</string>\n    <string name=\"square_particles_sub\">Les particules pulvérisées auront une forme carrée au lieu de cercles</string>\n    <string name=\"palette_tools\">Outils de palettes</string>\n    <string name=\"palette_tools_sub\">Générez le matériau de base de votre palette à partir de l\\'image, ou importez/exportez dans différents formats de palette</string>\n    <string name=\"edit_palette\">Modifier la palette</string>\n    <string name=\"edit_palette_sub\">Palette d\\'exportation/importation dans différents formats</string>\n    <string name=\"color_name\">Nom de la couleur</string>\n    <string name=\"palette_name\">Nom de la palette</string>\n    <string name=\"palette_format\">Format des palettes</string>\n    <string name=\"export_palette_sub\">Exporter la palette générée vers différents formats</string>\n    <string name=\"add_color_palette_sub\">Ajoute une nouvelle couleur à la palette actuelle</string>\n    <string name=\"palette_name_not_supported\">Le format %1$s ne prend pas en charge la fourniture du nom de la palette</string>\n    <string name=\"wallpapers_export_not_avaialbe\">En raison des politiques du Play Store, cette fonctionnalité ne peut pas être incluse dans la version actuelle. Pour accéder à cette fonctionnalité, veuillez télécharger ImageToolbox à partir d\\'une source alternative. Vous pouvez trouver les versions disponibles sur GitHub ci-dessous.</string>\n    <string name=\"open_github_page\">Ouvrir la page Github</string>\n    <string name=\"overwrite_files_sub_short\">Le fichier original sera remplacé par un nouveau au lieu d\\'être enregistré dans le dossier sélectionné</string>\n    <string name=\"hidden_watermark_text_detected\">Texte de filigrane caché détecté</string>\n    <string name=\"hidden_watermark_image_detected\">Image de filigrane cachée détectée</string>\n    <string name=\"this_image_was_hidden\">Cette image était cachée</string>\n    <string name=\"generative_inpaint\">Inpainting génératif</string>\n    <string name=\"generative_inpaint_sub\">Vous permet de supprimer des objets dans une image à l\\'aide d\\'un modèle d\\'IA, sans recourir à OpenCV. Pour utiliser cette fonctionnalité, l\\'application téléchargera le modèle requis (~ 200 Mo) depuis GitHub.</string>\n    <string name=\"generative_inpaint_ready_sub\">Vous permet de supprimer des objets dans une image à l\\'aide d\\'un modèle d\\'IA, sans recourir à OpenCV. Cela pourrait être une opération de longue durée</string>\n    <string name=\"error_level_analysis\">Analyse du niveau d\\'erreur</string>\n    <string name=\"luminance_gradient\">Dégradé de luminance</string>\n    <string name=\"average_distance\">Distance moyenne</string>\n    <string name=\"copy_move_detection\">Détection de déplacement de copie</string>\n    <string name=\"retain\">Retenir</string>\n    <string name=\"coefficent\">Coefficient</string>\n    <string name=\"clipboard_data_is_too_large\">Les données du Presse-papiers sont trop volumineuses</string>\n    <string name=\"data_is_too_large_to_copy\">Les données sont trop volumineuses pour être copiées</string>\n    <string name=\"simple_weave_pixelization\">Pixelisation de tissage simple</string>\n    <string name=\"staggered_pixelization\">Pixelisation échelonnée</string>\n    <string name=\"cross_pixelization\">Pixelisation croisée</string>\n    <string name=\"micro_macro_pixelization\">Pixelisation micro-macro</string>\n    <string name=\"orbital_pixelization\">Pixelisation orbitale</string>\n    <string name=\"vortex_pixelization\">Pixelisation Vortex</string>\n    <string name=\"pulse_grid_pixelization\">Pixelisation de la grille d\\'impulsions</string>\n    <string name=\"nucleus_pixelization\">Pixelisation du noyau</string>\n    <string name=\"radial_weave_pixelization\">Pixelisation à tissage radial</string>\n    <string name=\"cannot_open_uri\">Impossible d\\'ouvrir l\\'uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Mode chute de neige</string>\n    <string name=\"enabled\">Activé</string>\n    <string name=\"border_frame\">Cadre de bordure</string>\n    <string name=\"glitch_variant\">Variante de pépin</string>\n    <string name=\"channel_shift\">Changement de chaîne</string>\n    <string name=\"max_offset\">Décalage maximum</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Bloquer le problème</string>\n    <string name=\"block_size\">Taille du bloc</string>\n    <string name=\"crt_curvature\">Courbure du tube cathodique</string>\n    <string name=\"curvature\">Courbure</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Fusion de pixels</string>\n    <string name=\"max_drop\">Chute maximale</string>\n    <string name=\"ai_tools\">Outils IA</string>\n    <string name=\"ai_tools_sub\">Divers outils pour traiter les images via des modèles IA comme la suppression ou le débruitage d\\'artefacts</string>\n    <string name=\"model_anime_undeint\">Compression, lignes irrégulières</string>\n    <string name=\"model_broadcast\">Dessins animés, compression de diffusion</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Compression générale, bruit général</string>\n    <string name=\"model_wb_denoise\">Bruit de dessin animé incolore</string>\n    <string name=\"model_span_anime_pretrain\">Rapide, compression générale, bruit général, animation/bande dessinée/anime</string>\n    <string name=\"model_book_scan\">Numérisation de livres</string>\n    <string name=\"model_overexposure\">Correction d\\'exposition</string>\n    <string name=\"model_fbcnn_color_fp16\">Meilleur en compression générale, images couleur</string>\n    <string name=\"model_fbcnn_gray_fp16\">Meilleur en compression générale, images en niveaux de gris</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Compression générale, images en niveaux de gris, plus forte</string>\n    <string name=\"model_scunet_color_gan_fp16\">Bruit général, images couleur</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Bruit général, images couleur, meilleurs détails</string>\n    <string name=\"model_scunet_gray_15_fp16\">Bruit général, images en niveaux de gris</string>\n    <string name=\"model_scunet_gray_25_fp16\">Bruit général, images en niveaux de gris, plus fort</string>\n    <string name=\"model_scunet_gray_50_fp16\">Bruit général, images en niveaux de gris, le plus fort</string>\n    <string name=\"model_jpeg_destroyer\">Compression générale</string>\n    <string name=\"model_jaywreck\">Compression générale</string>\n    <string name=\"model_h264\">Texturation, compression h264</string>\n    <string name=\"model_vhs\">Compression VHS</string>\n    <string name=\"model_cinepak\">Compression non standard (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Compression Bink, meilleure sur la géométrie</string>\n    <string name=\"model_debink_v5\">Compression Bink, plus forte</string>\n    <string name=\"model_debink_v6\">Compression Bink, douce, conserve les détails</string>\n    <string name=\"model_antialias\">Suppression de l\\'effet marche d\\'escalier, lissage</string>\n    <string name=\"model_kdm_scans\">Art/dessins numérisés, compression légère, moiré</string>\n    <string name=\"model_bandage\">Bandes de couleur</string>\n    <string name=\"model_halftone\">Lent, suppression des demi-teintes</string>\n    <string name=\"model_colorizer\">Coloriseur général pour les images en niveaux de gris/bw, pour de meilleurs résultats, utilisez DDColor</string>\n    <string name=\"model_deedge\">Suppression des bords</string>\n    <string name=\"model_desharpen\">Supprime le suraffûtage</string>\n    <string name=\"model_dither\">Lent, tramage</string>\n    <string name=\"model_gainres\">Anti-aliasing, artefacts généraux, CGI</string>\n    <string name=\"model_kdm003_scans\">Traitement des analyses KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Modèle léger d\\'amélioration d\\'image</string>\n    <string name=\"model_bcgone_detailed_v2\">Suppression des artefacts de compression</string>\n    <string name=\"model_bcgone_smooth\">Suppression des artefacts de compression</string>\n    <string name=\"model_bandage_smooth\">Retrait du pansement avec des résultats fluides</string>\n    <string name=\"model_bendel_halftone\">Traitement des motifs en demi-teintes</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Suppression du motif de tramage V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Suppression des artefacts JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Amélioration de la texture H.264</string>\n    <string name=\"model_vhs_sharpen\">Affûtage et amélioration VHS</string>\n    <string name=\"merging\">Fusion</string>\n    <string name=\"chunk_size\">Taille du morceau</string>\n    <string name=\"overlap_size\">Taille de chevauchement</string>\n    <string name=\"note_chunk_info\">Les images de plus de %1$s px seront découpées et traitées en morceaux, superposés pour éviter les coutures visibles.</string>\n    <string name=\"large_chunk_warning\">Les grandes tailles peuvent provoquer une instabilité avec les appareils bas de gamme</string>\n    <string name=\"select_one_to_start\">Sélectionnez-en un pour commencer</string>\n    <string name=\"delete_model_sub\">Voulez-vous supprimer le modèle %1$s ? Vous devrez le télécharger à nouveau</string>\n    <string name=\"confirm\">Confirmer</string>\n    <string name=\"models\">Modèles</string>\n    <string name=\"downloaded_models\">Modèles téléchargés</string>\n    <string name=\"available_models\">Modèles disponibles</string>\n    <string name=\"preparing\">Préparation</string>\n    <string name=\"active_model\">Modèle actif</string>\n    <string name=\"failed_to_open_session\">Échec de l\\'ouverture de la session</string>\n    <string name=\"only_onnx_models\">Seuls les modèles .onnx/.ort peuvent être importés</string>\n    <string name=\"import_model\">Modèle d\\'importation</string>\n    <string name=\"import_model_sub\">Importez un modèle onnx personnalisé pour une utilisation ultérieure, seuls les modèles onnx/ort sont acceptés, prend en charge presque toutes les variantes de type esrgan</string>\n    <string name=\"imported_models\">Modèles importés</string>\n    <string name=\"model_scunet_color_15_fp16\">Bruit général, images colorées</string>\n    <string name=\"model_scunet_color_25_fp16\">Bruit général, images colorées, plus fort</string>\n    <string name=\"model_scunet_color_50_fp16\">Bruit général, images colorées, le plus fort</string>\n    <string name=\"model_artifacts_dithering_alsa\">Réduit les artefacts de tramage et les bandes de couleurs, améliorant ainsi les dégradés lisses et les zones de couleurs plates.</string>\n    <string name=\"model_nmkd_brighten_redux\">Améliore la luminosité et le contraste de l\\'image avec des reflets équilibrés tout en préservant les couleurs naturelles.</string>\n    <string name=\"model_nmkd_brighten\">Éclaircit les images sombres tout en conservant les détails et en évitant la surexposition.</string>\n    <string name=\"model_nmkd_detoon\">Élimine les tons excessifs de couleur et rétablit un équilibre des couleurs plus neutre et naturel.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Applique une tonalité de bruit basée sur Poisson en mettant l\\'accent sur la préservation des détails et des textures fins.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Applique une tonalité douce du bruit de Poisson pour des résultats visuels plus fluides et moins agressifs.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Tonalité de bruit uniforme axée sur la préservation des détails et la clarté de l’image.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Tonification sonore douce et uniforme pour une texture subtile et un aspect lisse.</string>\n    <string name=\"model_repainter\">Répare les zones endommagées ou inégales en repeignant les artefacts et en améliorant la cohérence de l\\'image.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Modèle de débandage léger qui supprime les bandes de couleur avec un coût de performance minimal.</string>\n    <string name=\"model_jpeg_0_20\">Optimise les images avec des artefacts de compression très élevés (qualité 0-20 %) pour une clarté améliorée.</string>\n    <string name=\"model_jpeg_20_40\">Améliore les images avec des artefacts de compression élevés (qualité de 20 à 40 %), en restaurant les détails et en réduisant le bruit.</string>\n    <string name=\"model_jpeg_40_60\">Améliore les images avec une compression modérée (qualité de 40 à 60 %), en équilibrant la netteté et la douceur.</string>\n    <string name=\"model_jpeg_60_80\">Affine les images avec une légère compression (qualité de 60 à 80 %) pour améliorer les détails et les textures subtiles.</string>\n    <string name=\"model_jpeg_80_100\">Améliore légèrement les images presque sans perte (qualité de 80 à 100 %) tout en préservant l\\'aspect et les détails naturels.</string>\n    <string name=\"model_spongecolor_lite\">Colorisation simple et rapide, dessins animés, pas idéal</string>\n    <string name=\"model_deblr\">Réduit légèrement le flou de l\\'image, améliorant ainsi la netteté sans introduire d\\'artefacts.</string>\n    <string name=\"processing_channel\">Opérations de longue durée</string>\n    <string name=\"processing_image\">Traitement de l\\'image</string>\n    <string name=\"processing\">Traitement</string>\n    <string name=\"model_artifacts_jpg_0_20\">Supprime les artefacts de compression JPEG importants dans les images de très faible qualité (0-20 %).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Réduit les forts artefacts JPEG dans les images hautement compressées (20 à 40 %).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Nettoie les artefacts JPEG modérés tout en préservant les détails de l\\'image (40 à 60 %).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Affine les artefacts JPEG légers dans des images d\\'assez haute qualité (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Réduit subtilement les artefacts JPEG mineurs dans les images presque sans perte (80 à 100 %).</string>\n    <string name=\"model_redetail_v2\">Améliore les détails et les textures fins, améliorant ainsi la netteté perçue sans artefacts lourds.</string>\n    <string name=\"processing_finished\">Traitement terminé</string>\n    <string name=\"processing_failed\">Échec du traitement</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Améliore les textures et les détails de la peau tout en gardant un aspect naturel, optimisé pour la vitesse.</string>\n    <string name=\"model_sbdv_dejpeg\">Supprime les artefacts de compression JPEG et restaure la qualité d\\'image des photos compressées.</string>\n    <string name=\"model_iso_denoise_v1\">Réduit le bruit ISO sur les photos prises dans des conditions de faible luminosité, préservant ainsi les détails.</string>\n    <string name=\"model_dejumbo\">Corrige les reflets surexposés ou « jumbo » et rétablit un meilleur équilibre tonal.</string>\n    <string name=\"model_ddcolor_tiny\">Modèle de colorisation léger et rapide qui ajoute des couleurs naturelles aux images en niveaux de gris.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Débruit</string>\n    <string name=\"type_colorize\">Coloriser</string>\n    <string name=\"type_artifacts\">Artefacts</string>\n    <string name=\"type_enhance\">Améliorer</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Analyses</string>\n    <string name=\"type_upscale\">Haut de gamme</string>\n    <string name=\"model_realesrgan_x4v3\">Upscaler X4 pour les images générales ; petit modèle qui utilise moins de GPU et de temps, avec un flou et un débruit modérés.</string>\n    <string name=\"model_realesrgan_x2plus\">Upscaler X2 pour les images générales, préservant les textures et les détails naturels.</string>\n    <string name=\"model_realesrgan_x4plus\">Upscaler X4 pour des images générales avec des textures améliorées et des résultats réalistes.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Upscaler X4 optimisé pour les images animées ; 6 blocs RRDB pour des lignes et des détails plus nets.</string>\n    <string name=\"model_realesrnet_x4plus\">L\\'upscaler X4 avec perte MSE produit des résultats plus fluides et des artefacts réduits pour les images générales.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimisé pour les images animées ; Variante 4B32F avec des détails plus nets et des lignes douces.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Modèle X4 UltraSharp V2 pour les images générales ; met l\\'accent sur la netteté et la clarté.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite ; plus rapide et plus petit, préserve les détails tout en utilisant moins de mémoire GPU.</string>\n    <string name=\"model_rmbg_1_4\">Modèle léger pour une suppression rapide de l’arrière-plan. Performances et précision équilibrées. Fonctionne avec des portraits, des objets et des scènes. Recommandé pour la plupart des cas d\\'utilisation.</string>\n    <string name=\"type_removebg\">Supprimer la glycémie</string>\n    <string name=\"horizontal_border_thickness\">Épaisseur de la bordure horizontale</string>\n    <string name=\"vertical_border_thickness\">Épaisseur de la bordure verticale</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s couleur</item>\n        <item quantity=\"other\">%1$s couleurs</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Le modèle actuel ne prend pas en charge le chunking, l\\'image sera traitée dans ses dimensions d\\'origine, cela peut entraîner une consommation de mémoire élevée et des problèmes avec les appareils bas de gamme.</string>\n    <string name=\"chunking_disabled\">Blocage désactivé, l\\'image sera traitée dans ses dimensions d\\'origine, cela peut entraîner une consommation de mémoire élevée et des problèmes avec les appareils bas de gamme, mais peut donner de meilleurs résultats d\\'inférence</string>\n    <string name=\"chunking\">Morceau</string>\n    <string name=\"model_u2net\">Modèle de segmentation d\\'image de haute précision pour la suppression de l\\'arrière-plan</string>\n    <string name=\"model_u2netp\">Version allégée de U2Net pour une suppression plus rapide de l\\'arrière-plan avec une utilisation moindre de la mémoire.</string>\n    <string name=\"model_ddcolor\">Le modèle complet DDColor offre une colorisation de haute qualité pour les images générales avec un minimum d\\'artefacts. Meilleur choix de tous les modèles de colorisation.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Ensembles de données artistiques formés et privés ; produit des résultats de colorisation diversifiés et artistiques avec moins d’artefacts de couleur irréalistes.</string>\n    <string name=\"model_birefnet\">Modèle BiRefNet léger basé sur Swin Transformer pour une suppression précise de l\\'arrière-plan.</string>\n    <string name=\"model_inspyrenet\">Suppression d’arrière-plan de haute qualité avec des bords nets et une excellente préservation des détails, en particulier sur les objets complexes et les arrière-plans délicats.</string>\n    <string name=\"model_isnet\">Modèle de suppression d\\'arrière-plan qui produit des masques précis avec des bords lisses, adaptés aux objets généraux et à une préservation modérée des détails.</string>\n    <string name=\"model_already_downloaded\">Modèle déjà téléchargé</string>\n    <string name=\"model_successfully_imported\">Modèle importé avec succès</string>\n    <string name=\"type\">Taper</string>\n    <string name=\"keyword\">Mot clé</string>\n    <string name=\"very_fast\">Très rapide</string>\n    <string name=\"normal\">Normale</string>\n    <string name=\"slow\">Lent</string>\n    <string name=\"very_slow\">Très lent</string>\n    <string name=\"compute_percents\">Calculer les pourcentages</string>\n    <string name=\"minimum_value_is\">La valeur minimale est %1$s</string>\n    <string name=\"warp_sub\">Déformer l\\'image en dessinant avec les doigts</string>\n    <string name=\"warp\">Chaîne</string>\n    <string name=\"hardness\">Dureté</string>\n    <string name=\"warp_mode\">Mode déformation</string>\n    <string name=\"warp_mode_move\">Se déplacer</string>\n    <string name=\"warp_mode_grow\">Grandir</string>\n    <string name=\"warp_mode_shrink\">Rétrécir</string>\n    <string name=\"warp_mode_swirl_cw\">Tourbillon CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Tourbillon CCW</string>\n    <string name=\"fade_strength\">Force de fondu</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Chute inférieure</string>\n    <string name=\"start_drop\">Démarrer le dépôt</string>\n    <string name=\"end_drop\">Fin du dépôt</string>\n    <string name=\"downloading\">Téléchargement</string>\n    <string name=\"smooth_shapes\">Formes lisses</string>\n    <string name=\"smooth_shapes_sub\">Utilisez des superellipses au lieu des rectangles arrondis standard pour des formes plus douces et plus naturelles</string>\n    <string name=\"shape_type\">Type de forme</string>\n    <string name=\"cut\">Couper</string>\n    <string name=\"rounded\">Arrondi</string>\n    <string name=\"smooth\">Lisse</string>\n    <string name=\"cut_shapes_sub\">Arêtes vives sans arrondi</string>\n    <string name=\"rounded_shapes_sub\">Coins arrondis classiques</string>\n    <string name=\"shapes_type\">Type de formes</string>\n    <string name=\"corners_size\">Taille des coins</string>\n    <string name=\"squircle\">Cercle</string>\n    <string name=\"squircle_shapes_sub\">Éléments d\\'interface utilisateur arrondis et élégants</string>\n    <string name=\"filename_format\">Format du nom de fichier</string>\n    <string name=\"prefix_pattern_description\">Texte personnalisé placé au tout début du nom de fichier, parfait pour les noms de projets, les marques ou les balises personnelles.</string>\n    <string name=\"original_filename_pattern_description\">Utilise le nom de fichier d\\'origine sans extension, vous aidant ainsi à conserver l\\'identification de la source intacte.</string>\n    <string name=\"width_pattern_description\">La largeur de l\\'image en pixels, utile pour suivre les changements de résolution ou la mise à l\\'échelle des résultats.</string>\n    <string name=\"height_pattern_description\">La hauteur de l\\'image en pixels, utile lorsque vous travaillez avec des proportions ou des exportations.</string>\n    <string name=\"random_numbers_pattern_description\">Génère des chiffres aléatoires pour garantir des noms de fichiers uniques ; ajoutez plus de chiffres pour plus de sécurité contre les doublons.</string>\n    <string name=\"sequence_number_pattern_description\">Compteur à incrémentation automatique pour les exportations par lots, idéal lors de l\\'enregistrement de plusieurs images en une seule session.</string>\n    <string name=\"preset_info_pattern_description\">Insère le nom du préréglage appliqué dans le nom de fichier afin que vous puissiez facilement vous rappeler comment l\\'image a été traitée.</string>\n    <string name=\"scale_mode_pattern_description\">Affiche le mode de mise à l\\'échelle de l\\'image utilisé pendant le traitement, permettant de distinguer les images redimensionnées, recadrées ou ajustées.</string>\n    <string name=\"suffix_pattern_description\">Texte personnalisé placé à la fin du nom de fichier, utile pour le versioning comme _v2, _edited ou _final.</string>\n    <string name=\"extension_pattern_description\">L\\'extension du fichier (png, jpg, webp, etc.), correspondant automatiquement au format réellement enregistré.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Un horodatage personnalisable qui vous permet de définir votre propre format par spécification Java pour un tri parfait.</string>\n    <string name=\"fling_type\">Type d\\'aventure</string>\n    <string name=\"android_native\">Android natif</string>\n    <string name=\"ios_style\">Style iOS</string>\n    <string name=\"smooth_curve\">Courbe douce</string>\n    <string name=\"quick_stop\">Arrêt rapide</string>\n    <string name=\"bouncy\">Gonflable</string>\n    <string name=\"floaty\">Flottant</string>\n    <string name=\"snappy\">Vif</string>\n    <string name=\"ultra_smooth\">Ultra lisse</string>\n    <string name=\"adaptive\">Adaptatif</string>\n    <string name=\"accessibility_aware\">Conscient de l\\'accessibilité</string>\n    <string name=\"reduced_motion\">Mouvement réduit</string>\n    <string name=\"android_native_sub\">Physique de défilement Android native pour une comparaison de base</string>\n    <string name=\"smooth_sub\">Défilement équilibré et fluide pour un usage général</string>\n    <string name=\"ios_style_sub\">Comportement de défilement de type iOS à friction plus élevée</string>\n    <string name=\"smooth_curve_sub\">Courbe cannelée unique pour une sensation de défilement distincte</string>\n    <string name=\"quick_stop_sub\">Défilement précis avec arrêt rapide</string>\n    <string name=\"bouncy_sub\">Défilement rebondissant ludique et réactif</string>\n    <string name=\"floaty_sub\">Défilements longs et glissants pour la navigation dans le contenu</string>\n    <string name=\"snappy_sub\">Défilement rapide et réactif pour les interfaces utilisateur interactives</string>\n    <string name=\"ultra_smooth_sub\">Défilement fluide de qualité supérieure avec un élan prolongé</string>\n    <string name=\"adaptive_sub\">Ajuste la physique en fonction de la vitesse de lancement</string>\n    <string name=\"accessibility_aware_sub\">Respecte les paramètres d\\'accessibilité du système</string>\n    <string name=\"reduced_motion_sub\">Mouvement minimal pour les besoins d’accessibilité</string>\n    <string name=\"primary_lines\">Lignes primaires</string>\n    <string name=\"primary_lines_sub\">Ajoute une ligne plus épaisse toutes les cinq lignes</string>\n    <string name=\"fill_color\">Couleur de remplissage</string>\n    <string name=\"hidden_tools\">Outils cachés</string>\n    <string name=\"hidden_for_share\">Outils masqués pour le partage</string>\n    <string name=\"color_library\">Bibliothèque de couleurs</string>\n    <string name=\"color_library_sub\">Parcourez une vaste collection de couleurs</string>\n    <string name=\"model_fatality_deblur\">Affine et supprime le flou des images tout en conservant les détails naturels, idéal pour corriger les photos floues.</string>\n    <string name=\"model_unresize_v3\">Restaure intelligemment les images précédemment redimensionnées, en récupérant les détails et les textures perdus.</string>\n    <string name=\"model_liveaction_v1_span\">Optimisé pour le contenu d\\'action en direct, réduit les artefacts de compression et améliore les détails fins des images de films/émissions de télévision.</string>\n    <string name=\"model_vhs2hd_realplksr\">Convertit les séquences de qualité VHS en HD, supprimant le bruit de la bande et améliorant la résolution tout en préservant l\\'aspect vintage.</string>\n    <string name=\"model_text2hd_v1\">Spécialisé pour les images et captures d\\'écran contenant beaucoup de texte, il affine les caractères et améliore la lisibilité.</string>\n    <string name=\"model_frankendata_pretrainer\">Mise à l\\'échelle avancée formée sur divers ensembles de données, excellente pour l\\'amélioration de photos à usage général.</string>\n    <string name=\"model_realwebphoto_v2\">Optimisé pour les photos compressées sur le Web, supprime les artefacts JPEG et restaure l\\'apparence naturelle.</string>\n    <string name=\"model_realwebphoto_v4\">Version améliorée pour les photos Web avec une meilleure préservation de la texture et une réduction des artefacts.</string>\n    <string name=\"model_dat_2x\">La mise à l\\'échelle 2x avec la technologie Dual Aggregation Transformer maintient la netteté et les détails naturels.</string>\n    <string name=\"model_dat_3x\">Mise à l\\'échelle 3x grâce à une architecture de transformateur avancée, idéale pour les besoins d\\'agrandissement modérés.</string>\n    <string name=\"model_dat_4x\">Mise à l\\'échelle 4x de haute qualité avec un réseau de transformateurs de pointe, préserve les détails fins à plus grande échelle.</string>\n    <string name=\"model_nafnet_deblurring\">Supprime le flou/bruit et les secousses des photos. Usage général mais meilleur sur les photos.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Restaure les images de faible qualité à l\\'aide du transformateur Swin2SR, optimisé pour la dégradation BSRGAN. Idéal pour corriger les artefacts de compression importants et améliorer les détails à une échelle 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Mise à l\\'échelle 4x avec le transformateur SwinIR formé à la dégradation BSRGAN. Utilise GAN pour des textures plus nettes et des détails plus naturels dans les photos et les scènes complexes.</string>\n    <string name=\"path\">Chemin</string>\n    <string name=\"merge_pdf\">Fusionner un PDF</string>\n    <string name=\"merge_pdf_sub\">Combinez plusieurs fichiers PDF en un seul document</string>\n    <string name=\"files_order\">Ordre des fichiers</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Fractionner un PDF</string>\n    <string name=\"split_pdf_sub\">Extraire des pages spécifiques d\\'un document PDF</string>\n    <string name=\"rotate_pdf\">Faire pivoter le PDF</string>\n    <string name=\"rotate_pdf_sub\">Corriger l\\'orientation de la page de manière permanente</string>\n    <string name=\"pages\">Pages</string>\n    <string name=\"rearrange_pdf\">Réorganiser le PDF</string>\n    <string name=\"rearrange_pdf_sub\">Glissez et déposez les pages pour les réorganiser</string>\n    <string name=\"hold_drag_drop\">Maintenir et faire glisser les pages</string>\n    <string name=\"page_numbers\">Numéros de pages</string>\n    <string name=\"page_numbers_sub\">Ajoutez automatiquement une numérotation à vos documents</string>\n    <string name=\"label_format\">Format d\\'étiquette</string>\n    <string name=\"pdf_to_text\">PDF en texte (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extrayez le texte brut de vos documents PDF</string>\n    <string name=\"watermark_pdf_sub\">Superposer du texte personnalisé pour la marque ou la sécurité</string>\n    <string name=\"signature\">Signature</string>\n    <string name=\"signature_sub\">Ajoutez votre signature électronique à n\\'importe quel document</string>\n    <string name=\"will_be_for_signature\">Ceci servira de signature</string>\n    <string name=\"unlock_pdf\">Déverrouiller le PDF</string>\n    <string name=\"unlock_pdf_sub\">Supprimez les mots de passe de vos fichiers protégés</string>\n    <string name=\"protect_pdf\">Protéger le PDF</string>\n    <string name=\"protect_pdf_sub\">Sécurisez vos documents avec un cryptage fort</string>\n    <string name=\"success\">Succès</string>\n    <string name=\"pdf_unlocked\">PDF déverrouillé, vous pouvez l\\'enregistrer ou le partager</string>\n    <string name=\"repair_pdf\">Réparer le PDF</string>\n    <string name=\"repair_pdf_sub\">Tentative de réparation de documents corrompus ou illisibles</string>\n    <string name=\"grayscale\">Niveaux de gris</string>\n    <string name=\"grayscale_pdf_sub\">Convertir toutes les images intégrées au document en niveaux de gris</string>\n    <string name=\"compress_pdf\">Compresser un PDF</string>\n    <string name=\"compress_pdf_sub\">Optimisez la taille de votre fichier de document pour un partage plus facile</string>\n    <string name=\"repair_info\">ImageToolbox reconstruit la table de références croisées interne et régénère la structure des fichiers à partir de zéro. Cela peut restaurer l\\'accès à de nombreux fichiers qui \\\\\"ne peuvent pas être ouverts\\\\\"</string>\n    <string name=\"grayscale_info\">Cet outil convertit toutes les images du document en niveaux de gris. Idéal pour imprimer et réduire la taille des fichiers</string>\n    <string name=\"metadata\">Métadonnées</string>\n    <string name=\"metadata_pdf_sub\">Modifier les propriétés du document pour une meilleure confidentialité</string>\n    <string name=\"tags\">Balises</string>\n    <string name=\"producer\">Producteur</string>\n    <string name=\"author\">Auteur</string>\n    <string name=\"keywords\">Mots-clés</string>\n    <string name=\"creator\">Créateur</string>\n    <string name=\"privacy_deep_clean\">Nettoyage en profondeur de la confidentialité</string>\n    <string name=\"privacy_deep_clean_sub\">Effacer toutes les métadonnées disponibles pour ce document</string>\n    <string name=\"page\">Page</string>\n    <string name=\"deep_ocr\">ROC profonde</string>\n    <string name=\"deep_ocr_sub\">Extrayez le texte du document et stockez-le dans un fichier texte à l\\'aide du moteur Tesseract</string>\n    <string name=\"cant_remove_all\">Impossible de supprimer toutes les pages</string>\n    <string name=\"remove_pages_pdf\">Supprimer des pages PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Supprimer des pages spécifiques du document PDF</string>\n    <string name=\"tap_to_remove\">Appuyez pour supprimer</string>\n    <string name=\"manually\">Manuellement</string>\n    <string name=\"crop_pdf\">Recadrer le PDF</string>\n    <string name=\"crop_pdf_sub\">Recadrer les pages du document à n\\'importe quelle limite</string>\n    <string name=\"flatten_pdf\">Aplatir le PDF</string>\n    <string name=\"flatten_pdf_sub\">Rendre le PDF non modifiable en pixellisant les pages du document</string>\n    <string name=\"camera_failed_to_open\">Impossible de démarrer la caméra. Veuillez vérifier les autorisations et vous assurer qu\\'elle n\\'est pas utilisée par une autre application.</string>\n    <string name=\"extract_images\">Extraire des images</string>\n    <string name=\"extract_images_sub\">Extrayez les images intégrées dans des PDF à leur résolution d\\'origine</string>\n    <string name=\"pdf_no_embedded\">Ce fichier PDF ne contient aucune image intégrée</string>\n    <string name=\"extract_images_info\">Cet outil numérise chaque page et récupère les images source en pleine qualité – parfait pour enregistrer les originaux des documents</string>\n    <string name=\"draw_signature\">Dessiner une signature</string>\n    <string name=\"pen_params\">Paramètres du stylo</string>\n    <string name=\"draw_signature_sub\">Utiliser votre propre signature comme image à placer sur les documents</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Divisez le document avec un intervalle donné et regroupez les nouveaux documents dans une archive zip</string>\n    <string name=\"interval\">Intervalle</string>\n    <string name=\"print_pdf\">Imprimer le PDF</string>\n    <string name=\"print_pdf_sub\">Préparer le document pour l\\'impression avec un format de page personnalisé</string>\n    <string name=\"pages_per_sheet\">Pages par feuille</string>\n    <string name=\"orientation\">Orientation</string>\n    <string name=\"page_size\">Taille des pages</string>\n    <string name=\"margin\">Marge</string>\n    <string name=\"bloom\">Floraison</string>\n    <string name=\"soft_knee\">Genou doux</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimisé pour les anime et les dessins animés. Mise à l\\'échelle rapide avec des couleurs naturelles améliorées et moins d\\'artefacts</string>\n    <string name=\"one_ui_sub\">Style similaire à Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Entrez ici les symboles mathématiques de base pour calculer la valeur souhaitée (par exemple (5+5)*10)</string>\n    <string name=\"math_expression\">Expression mathématique</string>\n    <string name=\"pick_up_to_n_collage_images\">Ramassez jusqu\\'à %1$s images</string>\n    <string name=\"keep_date_time\">Conserver la date et l\\'heure</string>\n    <string name=\"keep_date_time_sub\">Conservez toujours les balises exif liées à la date et à l\\'heure, fonctionne indépendamment de l\\'option conserver exif</string>\n    <string name=\"background_color_for_alpha_formats\">Couleur d\\'arrière-plan pour les formats alpha</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Ajoute la possibilité de définir la couleur d\\'arrière-plan pour chaque format d\\'image avec prise en charge alpha. Lorsqu\\'elle est désactivée, cette option est disponible uniquement pour les formats non alpha.</string>\n    <string name=\"open_markup_project\">Projet ouvert</string>\n    <string name=\"open_markup_project_sub\">Continuer à modifier un projet Image Toolbox précédemment enregistré</string>\n    <string name=\"markup_project_open_failed\">Impossible d\\'ouvrir le projet Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Le projet Image Toolbox ne contient pas de données de projet</string>\n    <string name=\"markup_project_corrupted\">Le projet Image Toolbox est corrompu</string>\n    <string name=\"unsupported_markup_project_version\">Version du projet Image Toolbox non prise en charge : %1$d</string>\n    <string name=\"save_markup_project\">Enregistrer le projet</string>\n    <string name=\"save_markup_project_sub\">Stockez les calques, l\\'arrière-plan et l\\'historique des modifications dans un fichier de projet modifiable</string>\n    <string name=\"failed_to_open\">Échec de l\\'ouverture</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Écrire dans un PDF consultable</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Reconnaissez le texte d\\'un lot d\\'images et enregistrez un PDF consultable avec une image et un calque de texte sélectionnable</string>\n    <string name=\"layer_alpha\">Couche alpha</string>\n    <string name=\"horizontal_flip\">Retournement horizontal</string>\n    <string name=\"vertical_flip\">Retournement vertical</string>\n    <string name=\"lock\">Verrouillage</string>\n    <string name=\"add_shadow\">Ajouter une ombre</string>\n    <string name=\"shadow_color\">Couleur de l\\'ombre</string>\n    <string name=\"text_geometry\">Géométrie du texte</string>\n    <string name=\"text_geometry_sub\">Étirez ou inclinez le texte pour une stylisation plus nette</string>\n    <string name=\"scale_x\">Échelle X</string>\n    <string name=\"skew_x\">Inclinaison X</string>\n    <string name=\"remove_annotations\">Supprimer les annotations</string>\n    <string name=\"remove_annotations_sub\">Supprimez les types d\\'annotations sélectionnés tels que les liens, les commentaires, les surlignages, les formes ou les champs de formulaire des pages PDF.</string>\n    <string name=\"annotation_link\">Liens hypertextes</string>\n    <string name=\"annotation_file_attachment\">Fichiers joints</string>\n    <string name=\"annotation_line\">Lignes</string>\n    <string name=\"annotation_popup\">Fenêtres contextuelles</string>\n    <string name=\"annotation_stamp\">Timbres</string>\n    <string name=\"annotation_shapes\">Formes</string>\n    <string name=\"annotation_text\">Notes de texte</string>\n    <string name=\"annotation_text_markup\">Balisage de texte</string>\n    <string name=\"annotation_widget\">Champs de formulaire</string>\n    <string name=\"annotation_markup\">Balisage</string>\n    <string name=\"annotation_unknown\">Inconnu</string>\n    <string name=\"annotations\">Annotations</string>\n    <string name=\"ungroup\">Dissocier</string>\n    <string name=\"add_shadow_sub\">Ajoutez une ombre floue derrière le calque avec des couleurs et des décalages configurables</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-hi/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"stay\">ठहरें</string>\n    <string name=\"close\">बंद करें</string>\n    <string name=\"reset_image\">छवि रीसेट करें</string>\n    <string name=\"reset_image_sub\">छवि परिवर्तन प्रारंभिक मानों पर वापस आ जाएंगे</string>\n    <string name=\"values_reset\">मान ठीक से रीसेट हो गए</string>\n    <string name=\"reset\">रीसेट</string>\n    <string name=\"compare_sub\">दी गई दो छवियों की तुलना करें</string>\n    <string name=\"pick_two_images\">आरंभ करने के लिए दो छवियां चुनें</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">गतिशील रंग चालू होने पर ऐप रंग योजना नहीं बदली जा सकती</string>\n    <string name=\"pick_accent_color\">ऐप थीम चयनित रंग पर आधारित होगी</string>\n    <string name=\"about_app\">ऐप के बारे में</string>\n    <string name=\"smth_went_wrong\">कुछ ग़लत हुआ: %1$s</string>\n    <string name=\"size\">आकार %1$s</string>\n    <string name=\"loading\">लोड हो रहा है…</string>\n    <string name=\"image_too_large_preview\">पूर्वावलोकन के लिए छवि बहुत बड़ी है, लेकिन फिर भी सहेजने का प्रयास किया जाएगा</string>\n    <string name=\"pick_image\">आरंभ करने के लिए छवि चुनें</string>\n    <string name=\"width\">चौड़ाई %1$s</string>\n    <string name=\"height\">ऊंचाई %1$s</string>\n    <string name=\"quality\">गुणवत्ता</string>\n    <string name=\"extension\">विस्तार</string>\n    <string name=\"resize_type\">पुनर्कार प्रकार</string>\n    <string name=\"explicit\">सुस्पष्ट</string>\n    <string name=\"flexible\">लचीला</string>\n    <string name=\"pick_image_alt\">छवि चुनें</string>\n    <string name=\"app_closing_sub\">क्या आप वाकई ऐप बंद करना चाहते हैं?</string>\n    <string name=\"app_closing\">ऐप बंद हो रहा है</string>\n    <string name=\"something_went_wrong\">कुछ गलत हुआ</string>\n    <string name=\"restart_app\">ऐप पुनः प्रारंभ करें</string>\n    <string name=\"copied\">क्लिपबोर्ड पर कॉपी किया गया</string>\n    <string name=\"exception\">अपवाद</string>\n    <string name=\"edit_exif\">EXIF बदलें</string>\n    <string name=\"ok\">ठीक है</string>\n    <string name=\"no_exif\">कोई EXIF डाटा नहीं मिला</string>\n    <string name=\"add_tag\">टैग जोड़ें</string>\n    <string name=\"save\">सहेजें</string>\n    <string name=\"clear\">साफ करें</string>\n    <string name=\"clear_exif\">EXIF साफ करें</string>\n    <string name=\"cancel\">रद्द करें</string>\n    <string name=\"clear_exif_sub\">छवि का सारा EXIF डेटा मिटा दिया जाएगा। इस कार्रवाई को पूर्ववत नहीं किया जा सकता!</string>\n    <string name=\"presets\">प्रीसेट</string>\n    <string name=\"crop\">क्रॉप</string>\n    <string name=\"image_not_saved\">सहेजा जा रहा है</string>\n    <string name=\"image_not_saved_sub\">यदि आप अभी बाहर निकलेंगे तो सभी सहेजे न गए परिवर्तन खो जाएंगे</string>\n    <string name=\"check_source_code\">स्रोत कोड</string>\n    <string name=\"check_source_code_sub\">नवीनतम अपडेट्स प्राप्त करें,मुद्दों पर चर्चा करें और अधिक</string>\n    <string name=\"single_edit\">एकल संपादन</string>\n    <string name=\"single_edit_sub\">एकल दी गई छवि का विवरण बदलें</string>\n    <string name=\"pick_color\">रंग चुनें</string>\n    <string name=\"pick_color_sub\">छवि से रंग चुनें, कॉपी करें या साझा करें</string>\n    <string name=\"image\">छवि</string>\n    <string name=\"color\">रंग</string>\n    <string name=\"color_copied\">रंग कॉपी किया गया</string>\n    <string name=\"crop_sub\">छवि को किसी भी सीमा तक क्रॉप करें</string>\n    <string name=\"version\">संस्करण</string>\n    <string name=\"keep_exif\">EXIF रखें</string>\n    <string name=\"images\">छवियां: %d</string>\n    <string name=\"change_preview\">पूर्वावलोकन बदलें</string>\n    <string name=\"remove\">हटाएं</string>\n    <string name=\"palette_sub\">दी गई छवि से रंग पैलेट नमूना बनाएं</string>\n    <string name=\"generate_palette\">पैलेट उत्पन्न करें</string>\n    <string name=\"palette\">पैलेट</string>\n    <string name=\"update\">अपडेट</string>\n    <string name=\"new_version\">नया संस्करण %1$s</string>\n    <string name=\"unsupported_type\">असमर्थित प्रकार: %1$s</string>\n    <string name=\"no_palette\">दी गई छवि के लिए पैलेट उत्पन्न नहीं किया जा सकता</string>\n    <string name=\"original\">मूल</string>\n    <string name=\"folder\">आउटपुट फोल्डर</string>\n    <string name=\"def\">तयशुदा</string>\n    <string name=\"custom\">तदनुकूल</string>\n    <string name=\"unspecified\">अनिर्दिष्ट</string>\n    <string name=\"device_storage\">डिवाइस स्टोरेज</string>\n    <string name=\"by_bytes_resize\">वजन के आधार पर आकार बदलें</string>\n    <string name=\"max_bytes\">अधिकतम आकार KB में</string>\n    <string name=\"by_bytes_resize_sub\">KB में दिए गए आकार के अनुसार छवि का आकार बदलें</string>\n    <string name=\"compare\">तुलना करें</string>\n    <string name=\"pick_images\">छवियां चुनें</string>\n    <string name=\"settings\">सेटिंग्स</string>\n    <string name=\"night_mode\">रात्रि मोड</string>\n    <string name=\"dark\">गहरा</string>\n    <string name=\"light\">हल्का</string>\n    <string name=\"system\">सिस्टम</string>\n    <string name=\"dynamic_colors\">गतिशील रंग</string>\n    <string name=\"customization\">अनुकूलीकरण</string>\n    <string name=\"allow_image_monet\">छवि मोनेट की अनुमति दें</string>\n    <string name=\"allow_image_monet_sub\">यदि सक्षम है, तो जब आप संपादित करने के लिए एक छवि चुनते हैं, तो इस छवि के लिए ऐप रंग अपनाए जाएंगे</string>\n    <string name=\"language\">भाषा</string>\n    <string name=\"amoled_mode\">Amoled मोड</string>\n    <string name=\"amoled_mode_sub\">यदि सक्षम किया गया है तो रात्रि मोड में सतहों का रंग पूर्णतः गहरे रंग पर निर्धारित हो जाएगा</string>\n    <string name=\"color_scheme\">रंग योजना</string>\n    <string name=\"color_red\">लाल</string>\n    <string name=\"color_green\">हरा</string>\n    <string name=\"color_blue\">नीला</string>\n    <string name=\"clipboard_paste_invalid_color_code\">वैध aRGB-कोड पेस्ट करें।</string>\n    <string name=\"clipboard_paste_invalid_empty\">पेस्ट करने के लिए कुछ नहीं है</string>\n    <string name=\"no_updates\">कोई अपडेट नहीं मिला</string>\n    <string name=\"issue_tracker\">मुद्दा ट्रैकर</string>\n    <string name=\"issue_tracker_sub\">बग रिपोर्ट और फीचर अनुरोध यहां भेजें</string>\n    <string name=\"help_translate\">अनुवाद करने में मदद करें</string>\n    <string name=\"help_translate_sub\">अनुवाद संबंधी गलतियों को सुधारें या परियोजना को अन्य भाषाओं में स्थानीयकृत करें</string>\n    <string name=\"nothing_found_by_search\">आपकी क्वेरी से कुछ नहीं मिला</string>\n    <string name=\"search_here\">यहां खोजें</string>\n    <string name=\"dynamic_colors_sub\">यदि सक्षम किया गया है, तो ऐप रंग वॉलपेपर रंगों के अनुरूप हो जाएंगे</string>\n    <string name=\"failed_to_save\">%d छवि(यों) को सहेजने में विफल</string>\n    <string name=\"surface\">सतह</string>\n    <string name=\"check_updates\">अपडेट के लिए जांचें</string>\n    <string name=\"check_updates_sub\">यदि सक्षम है, तो ऐप स्टार्टअप के बाद आपको अपडेट डायलॉग दिखाया जाएगा</string>\n    <string name=\"permission_sub\">छवियों को सहेजने के लिए ऐप को आपके स्टोरेज तक पहुंच की आवश्यकता है, काम करने के लिए यह आवश्यक है। कृपया अगले संवाद बॉक्स में अनुमति प्रदान करें।</string>\n    <string name=\"donation_sub\">यह एप्लिकेशन पूरी तरह से निःशुल्क है, लेकिन यदि आप परियोजना के विकास में सहायता करना चाहते हैं, तो आप यहां क्लिक कर सकते हैं</string>\n    <string name=\"fab_alignment\">FAB संरेखण</string>\n    <string name=\"values\">मान</string>\n    <string name=\"add\">जोड़ें</string>\n    <string name=\"primary\">प्राथमिक</string>\n    <string name=\"tertiary\">तृतीयक</string>\n    <string name=\"secondary\">माध्यमिक</string>\n    <string name=\"permission\">अनुमति</string>\n    <string name=\"grant\">अनुदान</string>\n    <string name=\"grant_permission_manual\">ऐप को काम करने के लिए इस अनुमति की आवश्यकता है, कृपया इसे मैन्युअल रूप से प्रदान करें</string>\n    <string name=\"border_thickness\">बॉर्डर की मोटाई</string>\n    <string name=\"external_storage\">बाहरी स्टोरेज</string>\n    <string name=\"monet_colors\">मोनेट रंग</string>\n    <string name=\"zoom\">छवि जूम</string>\n    <string name=\"prefix\">उपसर्ग</string>\n    <string name=\"filename\">फाइल का नाम</string>\n    <string name=\"share\">साझा करें</string>\n    <string name=\"emoji\">इमोजी</string>\n    <string name=\"emoji_sub\">मुख्य स्क्रीन पर प्रदर्शित होने वाले इमोजी का चयन करें</string>\n    <string name=\"add_file_size\">फाइल आकार जोड़ें</string>\n    <string name=\"add_file_size_sub\">यदि सक्षम किया गया है, तो आउटपुट फाइल के नाम पर सहेजी गई छवि की चौड़ाई और ऊंचाई जोड़ता है</string>\n    <string name=\"delete_exif\">EXIF मिटाएं</string>\n    <string name=\"image_preview\">छवि पूर्वावलोकन</string>\n    <string name=\"image_source\">छवि स्रोत</string>\n    <string name=\"photo_picker\">फोटो चयनकर्ता</string>\n    <string name=\"gallery_picker\">गेलरी</string>\n    <string name=\"file_explorer_picker\">फाइल अन्वेषक</string>\n    <string name=\"gallery_picker_sub\">सरल गैलरी छवि चयनकर्ता, यह तभी काम करेगा जब आपके पास वह ऐप होगा</string>\n    <string name=\"options_arrangement\">विकल्प व्यवस्था</string>\n    <string name=\"edit\">संपादित करें</string>\n    <string name=\"emojis_count\">इमोजी की गिनती</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"delete_exif_sub\">छवियों के किसी भी समूह से EXIF मेटाडेटा मिटाएं</string>\n    <string name=\"image_preview_sub\">किसी भी प्रकार की छवियों का पूर्वावलोकन करें: GIF, SVG, इत्यादि</string>\n    <string name=\"photo_picker_sub\">Android आधुनिक फोटो चयनकर्ता जो स्क्रीन के नीचे दिखाई देता है, केवल Android 12+ पर काम कर सकता हैै। इसमें EXIF मेटाडेटा प्राप्त करने में भी समस्याएं हैं</string>\n    <string name=\"file_explorer_picker_sub\">छवि चुनने के लिए GetContent आशय का उपयोग करें। हर जगह काम करता है, लेकिन कुछ डिवाइसों पर चुनी गई छवियां प्राप्त करने में समस्याएं आती हैं। वह मेरी गलती नहीं है।</string>\n    <string name=\"order\">क्रम</string>\n    <string name=\"order_sub\">मुख्य स्क्रीन पर विकल्पों का क्रम निर्धारित करता है</string>\n    <string name=\"add_original_filename\">मूल फाइल नाम जोड़ें</string>\n    <string name=\"add_original_filename_sub\">सक्षम होने पर आउटपुट छवि के नाम पर मूल फाइल नाम जोड़ता है</string>\n    <string name=\"replace_sequence_number\">अनुक्रम संख्या जोड़ें</string>\n    <string name=\"replace_sequence_number_sub\">यदि आप प्रचय संसाधन का उपयोग करते हैं तो सक्षम होने पर मानक समय-चिह्न को छवि अनुक्रम संख्या में बदल दिया जाता है</string>\n    <string name=\"filename_not_work_with_photopicker\">यदि फोटो चयनकर्ता छवि स्रोत चयनित है तो मूल फाइल नाम जोड़ना काम नहीं करता है</string>\n    <string name=\"brightness\">चमक</string>\n    <string name=\"sharpen\">पैना करें</string>\n    <string name=\"crosshatch\">क्रॉसहैच</string>\n    <string name=\"spacing\">अंतर</string>\n    <string name=\"line_width\">रेखा की चौडाई</string>\n    <string name=\"cga_colorspace\">CGA कलरस्पेस</string>\n    <string name=\"radius\">त्रिज्या</string>\n    <string name=\"scale\">पैमाना</string>\n    <string name=\"distortion\">विरूपण</string>\n    <string name=\"angle\">कोण</string>\n    <string name=\"bulge\">उभाड़ना</string>\n    <string name=\"load_image_from_net\">नेट से छवि लोड करें</string>\n    <string name=\"limits_resize\">सीमाओं का आकार बदलना</string>\n    <string name=\"stack_blur\">स्टैक ब्लर</string>\n    <string name=\"load_image_from_net_sub\">किसी भी छवि को इंटरनेट से लोड करें, उसका पूर्वावलोकन करें, जूम करें, और यदि आप चाहें तो उसे सहेज या संपादित भी कर सकते हैं</string>\n    <string name=\"no_image\">कोई छवि नहीं</string>\n    <string name=\"fit\">समुचित</string>\n    <string name=\"contrast\">वैषम्य</string>\n    <string name=\"hue\">रंगत</string>\n    <string name=\"saturation\">संतृप्ति</string>\n    <string name=\"add_filter\">फिल्टर जोड़ें</string>\n    <string name=\"filter\">फिल्टर</string>\n    <string name=\"filter_sub\">दी गई छवियों पर कोई फिल्टर श्रृंखला लागू करें</string>\n    <string name=\"filters\">फिल्टर</string>\n    <string name=\"light_aka_illumination\">रोशनी</string>\n    <string name=\"color_filter\">रंग फिल्टर</string>\n    <string name=\"alpha\">अल्फा</string>\n    <string name=\"exposure\">एक्सपोज़र</string>\n    <string name=\"white_balance\">श्वेत संतुलन</string>\n    <string name=\"temperature\">तापमान</string>\n    <string name=\"tint\">टिंट</string>\n    <string name=\"monochrome\">मोनोक्रोम</string>\n    <string name=\"gamma\">गामा</string>\n    <string name=\"highlights_shadows\">हाइलाइट्स और छायाएं</string>\n    <string name=\"highlights\">हाइलाइट</string>\n    <string name=\"haze\">धुंध</string>\n    <string name=\"effect\">प्रभाव</string>\n    <string name=\"distance\">दूरी</string>\n    <string name=\"slope\">ढलान</string>\n    <string name=\"sepia\">सीपिया</string>\n    <string name=\"negative\">नकारात्मक</string>\n    <string name=\"solarize\">सौर्यकृत</string>\n    <string name=\"vibrance\">जीवंतता</string>\n    <string name=\"black_and_white\">काला और सफेद</string>\n    <string name=\"sobel_edge\">सोबेल एज</string>\n    <string name=\"blur\">ब्लर</string>\n    <string name=\"halftone\">हाफ़टोन</string>\n    <string name=\"gaussian_blur\">गॉसियन ब्लर</string>\n    <string name=\"box_blur\">बॉक्स ब्लर</string>\n    <string name=\"bilaterial_blur\">द्विपक्षीय ब्लर</string>\n    <string name=\"emboss\">उभार</string>\n    <string name=\"laplacian\">लैप्लासियन</string>\n    <string name=\"vignette\">विनेट</string>\n    <string name=\"start\">शुरू</string>\n    <string name=\"end\">अंत</string>\n    <string name=\"kuwahara\">कुवहारा चौरसाई</string>\n    <string name=\"swirl\">भँवर</string>\n    <string name=\"dilation\">फैलाव</string>\n    <string name=\"sphere_refraction\">गोले का अपवर्तन</string>\n    <string name=\"refractive_index\">अपवर्तक सूचकांक</string>\n    <string name=\"glass_sphere_refraction\">कांच के गोले का अपवर्तन</string>\n    <string name=\"color_matrix\">रंग मैट्रिक्स</string>\n    <string name=\"opacity\">अपारदर्शिता</string>\n    <string name=\"limits_resize_sub\">पक्षानुपात को सहेजते समय दी गई चौड़ाई और ऊंचाई की सीमाओं का पालन करने के लिए चयनित छवियों का आकार बदलें</string>\n    <string name=\"sketch\">रेखाचित्र</string>\n    <string name=\"threshold\">सीमा</string>\n    <string name=\"quantizationLevels\">परिमाणीकरण स्तर</string>\n    <string name=\"smooth_toon\">चिकना तून</string>\n    <string name=\"toon\">तून</string>\n    <string name=\"posterize\">पोस्टरीकरण</string>\n    <string name=\"flexible_description\">चौड़ाई या ऊंचाई पैरामीटर द्वारा दिए गए लंबे पक्ष के साथ छवियों का आकार बदलता है, सहेजने के बाद सभी आकार की गणना की जाएगी - पहलू अनुपात रखता है</string>\n    <string name=\"shadows\">छायाएं</string>\n    <string name=\"image_link\">छवि लिंक</string>\n    <string name=\"fill\">भरें</string>\n    <string name=\"explicit_description\">चौड़ाई और ऊंचाई पैरामीटर द्वारा दी गई छवि में हर तस्वीर को बल देता है - पहलू अनुपात बदल सकता है</string>\n    <string name=\"content_scale\">सामग्री का पैमाना</string>\n    <string name=\"non_maximum_suppression\">गैर अधिकतम दमन</string>\n    <string name=\"weak_pixel_inclusion\">कमजोर पिक्सल समावेशन</string>\n    <string name=\"convolution3x3\">कनवल्शन 3x3</string>\n    <string name=\"blur_size\">ब्लर आकार</string>\n    <string name=\"blur_center_x\">ब्लर केंद्र x</string>\n    <string name=\"blur_center_y\">ब्लर केंद्र y</string>\n    <string name=\"zoom_blur\">जूम ब्लर</string>\n    <string name=\"color_balance\">रंग संतुलन</string>\n    <string name=\"luminance_threshold\">चमक दहलीज</string>\n    <string name=\"lookup\">ऊपर देखो</string>\n    <string name=\"rgb_filter\">RGB फिल्टर</string>\n    <string name=\"false_color\">मिथ्या रंग</string>\n    <string name=\"first_color\">पहला रंग</string>\n    <string name=\"second_color\">दूसरा रंग</string>\n    <string name=\"reorder\">पुन: व्यवस्थित करें</string>\n    <string name=\"fast_blur\">तेज़ ब्लर</string>\n    <string name=\"activate_files\">आपने फाइलें ऐप अक्षम कर दिया है, इस सुविधा का उपयोग करने के लिए इसे सक्रिय करें</string>\n    <string name=\"draw\">चित्र बनाएं</string>\n    <string name=\"draw_sub\">स्केचबुक की तरह छवि बनाएं, या पृष्ठभूमि पर ही चित्र बनाएं</string>\n    <string name=\"draw_on_background_sub\">पृष्ठभूमि रंग चुनें और उसके ऊपर चित्र बनाएं</string>\n    <string name=\"background_color\">पृष्ठभूमि का रंग</string>\n    <string name=\"pick_file\">फाइल चुनें</string>\n    <string name=\"encrypt\">कूटलेख</string>\n    <string name=\"pick_file_to_start\">आरंभ करने के लिए फाइल चुनें</string>\n    <string name=\"encryption\">कूटलेखन</string>\n    <string name=\"key\">कुंजी</string>\n    <string name=\"store_file_desc\">इस फाइल को अपने डिवाइस पर संग्रहीत करें या जहाँ चाहें इसे रखने के लिए साझा क्रिया का उपयोग करें</string>\n    <string name=\"features\">विशेषताएं</string>\n    <string name=\"file_proceed\">फाइल संसाधित</string>\n    <string name=\"implementation_sub\">AES-256, GCM मोड, कोई पैडिंग नहीं, 12 bytes यादृच्छिक IVs। कुंजियां SHA-3 हैश (256 bits) के रूप में उपयोग की जाती हैं।</string>\n    <string name=\"file_size_sub\">अधिकतम फाइल आकार Android OS और उपलब्ध मेमोरी द्वारा प्रतिबंधित है, जो स्पष्ट रूप से आपके डिवाइस पर निर्भर करता है। \\nकृपया ध्यान दें: मेमोरी स्टोरेज नहीं है।</string>\n    <string name=\"compatibility_sub\">कृपया ध्यान दें कि अन्य फाइल कूटलेखन सॉफ़्टवेयर या सेवाओं के साथ अनुकूलता की गारंटी नहीं है। थोड़ा अलग कुंजी उपचार या सिफर विन्यास असंगतता का कारण हो सकता है।</string>\n    <string name=\"features_sub\">फाइलों का पासवर्ड-आधारित कूटलेखन। आगे बढ़ी गई फाइलें चयनित निर्देशिका में संग्रहीत या साझा की जा सकती हैं। विकोडित फाइलें सीधे भी खोली जा सकती हैं।</string>\n    <string name=\"image_size_warning\">दी गई चौड़ाई और ऊंचाई के साथ छवि को सहेजने का प्रयास करने से OOM त्रुटि हो सकती है, इसे अपने जोखिम पर करें, और यह न कहें कि मैंने आपको चेतावनी नहीं दी थी!</string>\n    <string name=\"cache_size\">कैशे आकार</string>\n    <string name=\"found_s\">%1$s मिला</string>\n    <string name=\"auto_cache_clearing\">स्वचालित कैशे समाशोधन</string>\n    <string name=\"auto_cache_clearing_sub\">यदि सक्षम किया गया है तो ऐप स्टार्टअप पर ऐप कैशे साफ हो जाएगा</string>\n    <string name=\"tools\">औजार</string>\n    <string name=\"group_options_by_type\">प्रकार के अनुसार विकल्पों को समूहित करें</string>\n    <string name=\"group_options_by_type_sub\">तदनुकूल सूची व्यवस्था के बजाय अपने प्रकार की मुख्य स्क्रीन पर समूह विकल्प</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">विकल्प समूहन सक्षम होने पर व्यवस्था नहीं बदली जा सकती</string>\n    <string name=\"paint_color\">पेंट का रंग</string>\n    <string name=\"paint_alpha\">पेंट अल्फा</string>\n    <string name=\"draw_on_image\">छवि पर चित्र बनाएं</string>\n    <string name=\"draw_on_image_sub\">एक छवि चुनें और उस पर कुछ बनाएं</string>\n    <string name=\"draw_on_background\">पृष्ठभूमि पर चित्र बनाएं</string>\n    <string name=\"cipher\">सिफ़र</string>\n    <string name=\"cipher_sub\">AES क्रिप्टो एल्गोरिथम के आधार पर किसी भी फाइल (न केवल छवि) को कूटलेख और विकोड करें</string>\n    <string name=\"decrypt\">विकोड</string>\n    <string name=\"decryption\">विकोडन</string>\n    <string name=\"implementation\">कार्यान्वयन</string>\n    <string name=\"compatibility\">अनुकूलता</string>\n    <string name=\"file_size\">फाइल का साइज़</string>\n    <string name=\"invalid_password_or_not_encrypted\">अमान्य पासवर्ड या चुनी गई फाइल कूटलेखित नहीं है</string>\n    <string name=\"cache\">कैशे</string>\n    <string name=\"create\">बनाएं</string>\n    <string name=\"edit_screenshot\">स्क्रीनशॉट संपादित करें</string>\n    <string name=\"screenshot\">स्क्रीनशॉट</string>\n    <string name=\"fallback_option\">फ़ॉलबैक विकल्प</string>\n    <string name=\"skip\">छोड़ें</string>\n    <string name=\"copy\">प्रतिलिपि</string>\n    <string name=\"secondary_customization\">द्वितीयक अनुकूलन</string>\n    <string name=\"warning_bytes\">%1$s मोड में सहेजना अस्थिर हो सकता है, क्योंकि यह दोषरहित प्रारूप है</string>\n    <string name=\"reset_settings_sub\">यह आपकी सेटिंग्स को तयशुदा मानों पर वापस ले आएगा। ध्यान दें कि इसे ऊपर उल्लिखित बैकअप फाइल के बिना पूर्ववत नहीं किया जा सकता है।</string>\n    <string name=\"updates\">अपडेट</string>\n    <string name=\"something_went_wrong_emphasis\">उफ़… कुछ ग़लत हो गया। आप नीचे दिए गए विकल्पों का उपयोग करके मुझे लिख सकते हैं और मैं समाधान खोजने का प्रयास करूंगा</string>\n    <string name=\"tg_chat\">Telegram चैट</string>\n    <string name=\"crop_mask\">मास्क क्रॉप करे</string>\n    <string name=\"nature_and_animals\">प्रकृति और जानवर</string>\n    <string name=\"max_colors_count\">अधिकतम रंग गिनती</string>\n    <string name=\"activities\">गतिविधियां</string>\n    <string name=\"wait\">इंतजार करे</string>\n    <string name=\"image_exif_warning\">वर्तमान में, %1$s प्रारूप केवल Android पर EXIF मेटाडेटा पढ़ने की अनुमति देता है। सहेजे जाने पर आउटपुट छवि में बिल्कुल भी मेटाडेटा नहीं होगा।</string>\n    <string name=\"food_and_drink\">खाद्य और पेय</string>\n    <string name=\"contact_me\">मुझसे बात करें</string>\n    <string name=\"effort_sub\">%1$s के मान का अर्थ है तेज़ संपीड़न, जिसके परिणामस्वरूप फाइल का आकार अपेक्षाकृत बड़ा हो जाता है। %2$s का अर्थ है धीमा संपीड़न, जिसके परिणामस्वरूप छोटी फाइल बनती है।</string>\n    <string name=\"backup_sub\">फाइल में अपनी ऐप सेटिंग का बैकअप लें</string>\n    <string name=\"corrupted_file_or_not_a_backup\">दूषित फाइल या बैकअप नहीं</string>\n    <string name=\"presets_sub\" formatted=\"false\">यदि आपने प्रीसेट 125 चुना है, तो छवि मूल छवि के 125% आकार में सहेजी जाएगी। यदि आप प्रीसेट 50 चुनते हैं, तो छवि 50% आकार के साथ सहेजी जाएगी</string>\n    <string name=\"analytics_sub\">अनाम ऐप उपयोग आँकड़े एकत्र करने की अनुमति दें</string>\n    <string name=\"font_scale\">फ़ॉन्ट पैमाना</string>\n    <string name=\"allow_betas\">बीटा को अनुमति दें</string>\n    <string name=\"draw_mode\">ड्रॉ मोड</string>\n    <string name=\"restore\">पुनर्स्थापना</string>\n    <string name=\"trim_image_sub\">छवि के चारों ओर पारदर्शी स्थान को ट्रिम कर दिया जाएगा</string>\n    <string name=\"tg_chat_sub\">ऐप पर चर्चा करें और अन्य उपयोगकर्ताओं से प्रतिक्रिया प्राप्त करें। आप यहां बीटा अपडेट और अंतर्दृष्टि भी प्राप्त कर सकते हैं।</string>\n    <string name=\"alphabet_and_numbers\">अ आ इ ई उ ऊ ऋ ए ऐ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण त थ द ध न प फ ब भ म य र ल व श ष स ह 0123456789 !?</string>\n    <string name=\"erase_background\">पृष्ठभूमि मिटाएं</string>\n    <string name=\"restore_image\">छवि पुनर्स्थापित करें</string>\n    <string name=\"delete\">मिटाएं</string>\n    <string name=\"aspect_ratio\">पहलू अनुपात</string>\n    <string name=\"blur_radius\">ब्लर त्रिज्या</string>\n    <string name=\"background_remover\">पृष्ठभूमि हटानेवाला</string>\n    <string name=\"trim_image\">छवि ट्रिम करें</string>\n    <string name=\"background_remover_sub\">आरेखण या स्वतः विकल्प का उपयोग करके छवि से पृष्ठभूमि हटाएं</string>\n    <string name=\"delete_color_scheme_warn\">आप चयनित रंग योजना को मिटने वाले हैं। यह कार्रवाई पूर्ववत नहीं की जा सकती</string>\n    <string name=\"saved_to_without_filename\">%1$s फोल्डर में सहेजा गया</string>\n    <string name=\"settings_restored\">सेटिंग्स सफलतापूर्वक बहाल हो गई</string>\n    <string name=\"backup_and_restore\">बैकअप और पुनर्स्थापना</string>\n    <string name=\"backup\">बैकअप</string>\n    <string name=\"auto_erase_background\">स्वतः बैकग्राउंड मिटाएं</string>\n    <string name=\"emotions\">भावनाएं</string>\n    <string name=\"crashlytics_sub\">यह ऐप को मैन्युअल रूप से क्रैश रिपोर्ट एकत्र करने की अनुमति देता है</string>\n    <string name=\"saving_almost_complete\">लगभग सहेजा गया। अब रद्द करने पर फिर से सहेजने की आवश्यकता होगी।</string>\n    <string name=\"create_issue\">मुद्दा बनाएं</string>\n    <string name=\"pipette\">विंदुक</string>\n    <string name=\"saved_to\">%2$s नाम से %1$s फोल्डर में सहेजा गया</string>\n    <string name=\"symbols\">प्रतीक</string>\n    <string name=\"analytics\">विश्लेषिकी</string>\n    <string name=\"image_crop_mask_sub\">दी गई छवि से मास्क बनाने के लिए इस मास्क प्रकार का उपयोग करें, ध्यान दें कि इसमें अल्फा चैनल होना चाहिए</string>\n    <string name=\"enable_emoji\">इमोजी सक्षम करें</string>\n    <string name=\"effort\">कोशिश</string>\n    <string name=\"resize_and_convert\">पुनर्कार और परिवर्तित करें</string>\n    <string name=\"objects\">वस्तुएं</string>\n    <string name=\"randomize_filename\">फाइलनाम को यादृच्छिक करें</string>\n    <string name=\"text\">पाठ</string>\n    <string name=\"defaultt\">तयशुदा</string>\n    <string name=\"delete_color_scheme_title\">योजना मिटाएं</string>\n    <string name=\"restore_background\">पृष्ठभूमि पुनर्स्थापित करें</string>\n    <string name=\"font\">फॉन्ट</string>\n    <string name=\"resize_and_convert_sub\">दी गई छवियों का आकार बदलें या उन्हें अन्य प्रारूपों में परिवर्तित करें, यदि आप एकल छवि चुनते हैं तो आप EXIF मेटाडेटा को भी संपादित कर सकते हैं</string>\n    <string name=\"using_large_fonts_warn\">बड़े फ़ॉन्ट पैमाने का उपयोग करने से UI गड़बड़ियां और समस्याएं हो सकती हैं, जिन्हें ठीक नहीं किया जा सकेगा। सावधानी से प्रयोग करें।</string>\n    <string name=\"randomize_filename_sub\">सक्षम होने पर आउटपुट फाइल नाम पूरी तरह से यादृच्छिक होगा</string>\n    <string name=\"keep_exif_sub\">मूल छवि का मेटाडेटा रखा जाएगा</string>\n    <string name=\"restore_sub\">पहले से बनाई गई फाइल से ऐप सेटिंग पुनर्स्थापित करें</string>\n    <string name=\"presets_sub_bytes\">प्रीसेट यहाँ प्राप्त होने वाली फोटो का % निर्धारित करता है,जैसे कि अगर आपने प्रीसेट में 50 चुना हैं तो आपको 5mb की फोटो सेव होने के बाद 2.5mb की प्राप्त होगी</string>\n    <string name=\"erase_mode\">मिटाएं मोड</string>\n    <string name=\"allow_betas_sub\">सक्षम होने पर अपडेट जाँच में बीटा ऐप संस्करण शामिल होंगे</string>\n    <string name=\"travels_and_places\">यात्राएं और स्थान</string>\n    <string name=\"brush_softness\">ब्रश की कोमलता</string>\n    <string name=\"draw_arrows\">तीर खींचें</string>\n    <string name=\"draw_arrows_sub\">यदि सक्षम किया गया है तो आरेखण पथ को इंगित तीर के रूप में दर्शाया जाएगा</string>\n    <string name=\"crop_description\">यदि चित्रों का आकार इनपुट आयामों से बड़ा है तो उन्हें बीच में इस आकार में क्रॉप किया जाएगा और अन्य मामलों में कैनवास को दिए गए पृष्ठभूमि रंग के साथ विस्तारित किया जाएगा</string>\n    <string name=\"donation\">दान</string>\n    <string name=\"horizontal\">क्षैतिज</string>\n    <string name=\"images_order\">छवियों का क्रम</string>\n    <string name=\"image_stitching\">छवि सिलाई</string>\n    <string name=\"pick_at_least_two_images\">कम से कम 2 छवियां चुनें</string>\n    <string name=\"scale_small_images_to_large_sub\">सक्षम होने पर छोटी छवियों को अनुक्रम में सबसे बड़ी छवि में बदला जायेगा</string>\n    <string name=\"image_stitching_sub\">एक बड़ी छवि पाने के लिए दी गई छवियों को मिलाएं</string>\n    <string name=\"image_orientation\">छवि अभिविन्यास</string>\n    <string name=\"vertical\">लंबवत</string>\n    <string name=\"output_image_scale\">आउटपुट छवि पैमाना</string>\n    <string name=\"scale_small_images_to_large\">छोटी छवियों को बड़े आकार में बदलें</string>\n    <string name=\"regular\">नियमित</string>\n    <string name=\"email\">ईमेल</string>\n    <string name=\"pixelation\">पिक्सलेशन</string>\n    <string name=\"blur_edges_sub\">सक्षम होने पर एक रंग की बजाय इसके चारों ओर स्थान भरने के लिए छवि के नीचे धुंधले किनारों को भरता है</string>\n    <string name=\"blur_edges\">किनारों को धुंधला करें</string>\n    <string name=\"enhanced_pixelation\">उन्नत पिक्सलेशन</string>\n    <string name=\"replace_color\">रंग बदलें</string>\n    <string name=\"tolerance\">सहिष्णुता</string>\n    <string name=\"color_to_replace\">बदलने लायक रंग</string>\n    <string name=\"target_color\">लक्षित रंग</string>\n    <string name=\"color_to_remove\">हटाने के लिए रंग</string>\n    <string name=\"remove_color\">रंग हटाए</string>\n    <string name=\"bokeh\">बोकेह</string>\n    <string name=\"random_emojis\">रैंडम इमोजी</string>\n    <string name=\"emoji_selection_error\">रैंडम इमोजी ऑन होने पे इमोजी चुन नहीं सकते</string>\n    <string name=\"random_emojis_error\">इमोजी ऑफ होने पे रैंडम इमोजी इस्तेमाल नहीं कर सकते</string>\n    <string name=\"random_emojis_sub\">ऐप बार का इमोजी रैंडम इमोजी से लगातार बदला जाएगा</string>\n    <string name=\"old_tv\">पुराना टीवी</string>\n    <string name=\"digital_code\">डिजिटल कोड</string>\n    <string name=\"deep_purple\">डीप पर्पल</string>\n    <string name=\"red_swirl\">रेड स्वर्ल</string>\n    <string name=\"space_portal\">स्पेस पोर्टल</string>\n    <string name=\"enhanced_diamond_pixelation\">उन्नत डायमंड पिक्सलेशन</string>\n    <string name=\"diamond_pixelation\">डायमंड पिक्सलेशन</string>\n    <string name=\"circle_pixelation\">वृत्त पिक्सलेशन</string>\n    <string name=\"enhanced_circle_pixelation\">उन्नत वृत्त पिक्सलेशन</string>\n    <string name=\"night_magic\">रात्रि जादू</string>\n    <string name=\"green_sun\">हरा सूर्य</string>\n    <string name=\"pixel_size\">पिक्सल साइज</string>\n    <string name=\"lock_draw_orientation\">ड्रा अभिविन्यास लॉक करे</string>\n    <string name=\"tonal_spot_sub\">तयशुदा पैलेट शैली, यह सभी चार रंगों को अनुकूलित करने की अनुमति देती है। अन्य आपको केवल मुख्य रंग तय करने की अनुमति देते हैं</string>\n    <string name=\"color_explosion\">रंग विस्फोट</string>\n    <string name=\"neutral_sub\">एक शैली जो मोनोक्रोम की तुलना में थोड़ी अधिक रंगीन है</string>\n    <string name=\"rainbow_world\">सतरंगी दुनिया</string>\n    <string name=\"recode\">पुन:कोड</string>\n    <string name=\"lock_draw_orientation_sub\">अगर आरेखण मोड़ में सक्रिय रहा तो स्क्रीन नही घूमेगी</string>\n    <string name=\"check_for_updates\">अपडेट के लिये जांचें</string>\n    <string name=\"neutral\">तटस्थ</string>\n    <string name=\"vibrant\">चमकीला</string>\n    <string name=\"expressive\">अभिव्यंजक</string>\n    <string name=\"rainbow\">मेघधनुष</string>\n    <string name=\"fruit_salad\">फल सलाड</string>\n    <string name=\"content\">सामग्री</string>\n    <string name=\"stroke_pixelation\">स्ट्रोक पिक्सलेशन</string>\n    <string name=\"icon_shape_sub\">कार्ड के प्रमुख आइकन के तहत चयनित आकार के साथ कंटेनर जोड़ता है</string>\n    <string name=\"playful_scheme\">एक चंचल थीम - स्रोत रंग का रंग थीम में प्रकट नहीं होता है</string>\n    <string name=\"content_sub\">एक योजना जो स्रोत रंग को Scheme.primaryContainer में रखती है</string>\n    <string name=\"pdf_to_images_sub\">PDF को छवियों में दिए गए आउटपुट प्रारूप में बदलें</string>\n    <string name=\"images_to_pdf_sub\">आउटपुट PDF फाइल में दी गई छवियों को पैक करें</string>\n    <string name=\"search_option_sub\">मुख्य स्क्रीन पर सभी उपलब्ध विकल्पों के माध्यम से खोज करने की क्षमता सक्षम करता है</string>\n    <string name=\"pdf_tools\">PDF उपकरण</string>\n    <string name=\"pdf_tools_sub\">PDF फाइलों के साथ काम करें: पूर्वावलोकन करें, छवियों के बैच में परिवर्तित करें या दिए गए चित्रों में से एक बनाएं</string>\n    <string name=\"mask_filter_sub\">फिल्टर श्रृंखला दिए गए नकाबपोश क्षेत्रों पर लागू करें, प्रत्येक मास्क क्षेत्र फिल्टर का अपना समूह निर्धारित कर सकता है</string>\n    <string name=\"inverse_fill_type\">उलटा भरण प्रकार</string>\n    <string name=\"inverse_fill_type_sub\">यदि सक्षम सभी गैर-नकाबपोश क्षेत्रों को तयशुदा व्यवहार के बजाय फिल्टर किया जाएगा</string>\n    <string name=\"pen\">पेन</string>\n    <string name=\"privacy_blur\">गोपनीयता ब्लर</string>\n    <string name=\"privacy_blur_sub\">आप जो कुछ भी छिपाना चाहते हैं उसे सुरक्षित करने के लिए खींचे गए पथ के नीचे की छवि को ब्लर करता है</string>\n    <string name=\"containers_shadow_sub\">कंटेनरों के पीछे छाया आरेखण सक्षम करता है</string>\n    <string name=\"fabs_shadow_sub\">फ़्लोटिंग एक्शन बटन के पीछे छाया आरेखण सक्षम करता है</string>\n    <string name=\"auto_rotate_limits_sub\">छवि अभिविन्यास के लिए सीमा बॉक्स को अपनाने की अनुमति देता है</string>\n    <string name=\"delete_mask_warn\">आप चयनित फिल्टर मास्क को हटाने वाले हैं । यह कार्रवाई पूर्ववत नहीं की जा सकती</string>\n    <string name=\"delete_mask\">मास्क मिटायें</string>\n    <string name=\"search_option\">खोजें</string>\n    <string name=\"full_filter\">पूर्ण फिल्टर</string>\n    <string name=\"start_position\">प्रारंभ</string>\n    <string name=\"center_position\">मध्य</string>\n    <string name=\"end_position\">अंत</string>\n    <string name=\"full_filter_sub\">किसी भी फिल्टर श्रृंखला को दी गई छवियों या एकल छवि पर लागू करें</string>\n    <string name=\"preview_pdf\">PDF पूर्वावलोकन</string>\n    <string name=\"pdf_to_images\">PDF से छवियां</string>\n    <string name=\"images_to_pdf\">छवियां से PDF</string>\n    <string name=\"preview_pdf_sub\">सरल PDF पूर्वावलोकन</string>\n    <string name=\"draw_path_mode\">पथ मोड ड्रा करें</string>\n    <string name=\"double_line_arrow\">डबल लाइन तीर</string>\n    <string name=\"free_drawing\">मुक्त आरेखण</string>\n    <string name=\"double_arrow\">डबल तीर</string>\n    <string name=\"line_arrow\">रेखा तीर</string>\n    <string name=\"arrow\">तीर</string>\n    <string name=\"line\">रेखा</string>\n    <string name=\"free_drawing_sub\">इनपुट मूल्य के रूप में पथ खींचता है</string>\n    <string name=\"line_sub\">एक रेखा के रूप में प्रारंभ बिंदु से अंत बिंदु तक पथ खींचता है</string>\n    <string name=\"line_arrow_sub\">एक रेखा के रूप में प्रारंभ बिंदु से अंत बिंदु तक इंगित तीर खींचता है</string>\n    <string name=\"arrow_sub\">किसी दिए गए पथ से तीर इंगित करता है</string>\n    <string name=\"double_line_arrow_sub\">एक पंक्ति के रूप में प्रारंभ बिंदु से अंत बिंदु तक डबल पॉइंटिंग तीर खींचता है</string>\n    <string name=\"double_arrow_sub\">किसी दिए गए पथ से डबल पॉइंटिंग तीर खींचता है</string>\n    <string name=\"outlined_oval\">उल्लिखित अंडाकार</string>\n    <string name=\"outlined_rect\">उल्लिखित रेक्ट</string>\n    <string name=\"oval\">अंडाकार</string>\n    <string name=\"rect\">रेक्ट</string>\n    <string name=\"rect_sub\">प्रारंभ बिंदु से अंत बिंदु तक रेक्ट खींचता है</string>\n    <string name=\"oval_sub\">प्रारंभ बिंदु से अंत बिंदु तक अंडाकार खींचता है</string>\n    <string name=\"outlined_oval_sub\">प्रारंभ बिंदु से अंत बिंदु तक उल्लिखित अंडाकार खींचता है</string>\n    <string name=\"outlined_rect_sub\">प्रारंभ बिंदु से अंत बिंदु तक उल्लिखित रेक्ट खींचता है</string>\n    <string name=\"mask_color\">मास्क रंग</string>\n    <string name=\"mask_preview\">मास्क पूर्वावलोकन</string>\n    <string name=\"value_in_range\">मान %1$s - %2$s श्रेणी में है</string>\n    <string name=\"icon_shape\">चिह्न आकार</string>\n    <string name=\"vibrant_sub\">एक ज़ोरदार थीम, रंगीनता प्राथमिक पैलेट के लिए अधिकतम है, दूसरों के लिए बढ़ी हुई है</string>\n    <string name=\"monochrome_sub\">एक मोनोक्रोम थीम, रंग पूरी तरह से काले / सफेद / ग्रे हैं</string>\n    <string name=\"fidelity_sub\">एक योजना जो सामग्री योजना के समान है</string>\n    <string name=\"invert_colors_sub\">सक्षम होने पर थीम रंगों को नकारात्मक रंगों में बदल देता है</string>\n    <string name=\"mask_filter\">मास्क फिल्टर</string>\n    <string name=\"masks\">मास्क</string>\n    <string name=\"add_mask\">मास्क जोड़ें</string>\n    <string name=\"mask_indexed\">मास्क %d</string>\n    <string name=\"mask_preview_sub\">आपको अनुमानित परिणाम दिखाने के लिए खींचा गया फिल्टर मास्क प्रस्तुत किया जाएगा</string>\n    <string name=\"simple_variants\">सरल प्रकार</string>\n    <string name=\"highlighter\">हाइलाइटर</string>\n    <string name=\"neon\">नियोन</string>\n    <string name=\"highlighter_sub\">अर्ध-पारदर्शी तेज हाइलाइटर पथ बनाएं</string>\n    <string name=\"neon_sub\">अपने चित्र के लिए कुछ चमक प्रभाव जोड़ें</string>\n    <string name=\"pen_sub\">तयशुदा एक, सबसे सरल - केवल रंग</string>\n    <string name=\"pixelation_sub\">गोपनीयता ब्लर के समान, लेकिन धुंधला होने के बजाय पिक्सलेट हो जाता है</string>\n    <string name=\"auto_rotate_limits\">स्वतः घुमाएं</string>\n    <string name=\"palette_style\">पैलेट शैली</string>\n    <string name=\"tonal_spot\">टोनल स्पॉट</string>\n    <string name=\"fidelity\">फिडेलिटी</string>\n    <string name=\"containers_shadow\">कंटेनर</string>\n    <string name=\"sliders_shadow\">स्लाइडर्स</string>\n    <string name=\"switches_shadow\">स्विचेस</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">बटन</string>\n    <string name=\"sliders_shadow_sub\">स्लाइडर्स के पीछे छाया आरेखण सक्षम करता है</string>\n    <string name=\"switches_shadow_sub\">स्विचों के पीछे छाया आरेखण सक्षम करता है</string>\n    <string name=\"buttons_shadow_sub\">तयशुदा बटनों के पीछे छाया आरेखण सक्षम करता है</string>\n    <string name=\"app_bars_shadow\">ऐप बार</string>\n    <string name=\"app_bars_shadow_sub\">ऐप बार के पीछे छाया आरेखण सक्षम करता है</string>\n    <string name=\"foss_update_checker_warning\">यदि कोई नया अपडेट उपलब्ध है तो यह जांचने के लिए यह अपडेट चेकर GitHub से जुड़ेगा</string>\n    <string name=\"attention\">ध्यान दें</string>\n    <string name=\"fading_edges\">मिटते किनारे</string>\n    <string name=\"disabled\">अक्षम</string>\n    <string name=\"both\">दोनों</string>\n    <string name=\"invert_colors\">रंगों को पलटें</string>\n    <string name=\"lasso\">लैस्सो</string>\n    <string name=\"channel_shift_x\">चैनल शिफ्ट X</string>\n    <string name=\"channel_shift_y\">चैनल शिफ्ट Y</string>\n    <string name=\"corruption_shift_x\">भ्रष्टाचार शिफ्ट X</string>\n    <string name=\"corruption_shift_y\">भ्रष्टाचार शिफ्ट Y</string>\n    <string name=\"segmentation_mode_auto_only\">केवल ऑटो</string>\n    <string name=\"segmentation_mode_auto\">ऑटो</string>\n    <string name=\"segmentation_mode_single_column\">एकल स्तंभ</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">सिंगल ब्लॉक वर्टिकल टेक्स्ट</string>\n    <string name=\"segmentation_mode_single_block\">एकल ब्लॉक</string>\n    <string name=\"segmentation_mode_single_line\">सिंगल लाइन</string>\n    <string name=\"segmentation_mode_single_word\">एकल शब्द</string>\n    <string name=\"segmentation_mode_circle_word\">वृत्त शब्द</string>\n    <string name=\"segmentation_mode_single_char\">एकल वर्ण</string>\n    <string name=\"segmentation_mode_sparse_text\">विरल पाठ</string>\n    <string name=\"segmentation_mode_raw_line\">कच्ची लाइन</string>\n    <string name=\"glitch\">गड़बड़</string>\n    <string name=\"amount\">राशि</string>\n    <string name=\"seed\">बीज</string>\n    <string name=\"noise\">शोर</string>\n    <string name=\"peak\">चोटी</string>\n    <string name=\"transition\">संक्रमण</string>\n    <string name=\"clipboard\">क्लिपबोर्ड</string>\n    <string name=\"auto_pin\">स्वतः पिन</string>\n    <string name=\"auto_pin_sub\">सक्षम होने पर स्वचालित रूप से सहेजी गई छवि को क्लिपबोर्ड पर जोड़ता है</string>\n    <string name=\"vibration\">कंपन</string>\n    <string name=\"vibration_strength\">कंपन शक्ति</string>\n    <string name=\"overwrite_file_requirements\">फाइलों को अधिलेखित करने के लिए आपको \\\"अन्वेषक\\\" छवि स्रोत का उपयोग करने की आवश्यकता है, छवियों को दोबारा चुनने का प्रयास करें, हमने छवि स्रोत को आवश्यक स्रोत में बदल दिया है</string>\n    <string name=\"overwrite_files\">फाइलें अधिलेखित करें</string>\n    <string name=\"empty\">खाली</string>\n    <string name=\"suffix\">प्रत्यय</string>\n    <string name=\"no_such_directory\">कोई \\\"%1$s\\\" निर्देशिका नहीं मिली, हमने इसे तयशुदा निर्देशिका में बदल दिया है, कृपया फाइल को फिर से सहेजें</string>\n    <string name=\"overwrite_files_sub\">मूल फाइल को चयनित फोल्डर में सहेजने के बजाय एक नई फाइल से बदल दिया जाएगा, इस विकल्प के लिए छवि स्रोत \\\"अन्वेषक\\\" या GetContent होना चाहिए, इसे टॉगल करने पर, यह स्वचालित रूप से निर्धारित हो जाएगा</string>\n    <string name=\"bicubic\">बाइक्यूबिक</string>\n    <string name=\"bilinear_sub\">रैखिक (या द्विरेखीय, दो आयामों में) प्रक्षेप आम तौर पर छवि के आकार को बदलने के लिए अच्छा होता है, लेकिन विवरणों में कुछ अवांछनीय नरमी का कारण बनता है और फिर भी कुछ हद तक अनियमित हो सकता है</string>\n    <string name=\"nearest_sub\">आकार बढ़ाने के सरल तरीकों में से एक, प्रत्येक पिक्सल को एक ही रंग के कई पिक्सल के साथ बदलना</string>\n    <string name=\"catmull_sub\">सुचारू रूप से प्रक्षेप करने और नियंत्रण बिंदुओं के एक समूह को फिर से तैयार करने की विधि, आमतौर पर कंप्यूटर ग्राफिक्स में चिकनी वक्र बनाने के लिए उपयोग की जाती है</string>\n    <string name=\"hann_sub\">वर्णक्रमीय रिसाव को कम करने और सिग्नल के किनारों को टैप करके आवृत्ति विश्लेषण की सटीकता में सुधार करने के लिए अक्सर सिग्नल प्रोसेसिंग में विंडोिंग फ़ंक्शन लागू किया जाता है</string>\n    <string name=\"mitchell_sub\">स्केल की गई छवि में तीखेपन और एंटी-अलियासिंग के बीच संतुलन प्राप्त करने के लिए समायोज्य मापदंडों के साथ एक कनवल्शन फिल्टर का उपयोग करने वाली पुन: नमूनाकरण विधि</string>\n    <string name=\"spline_sub\">एक वक्र या सतह, लचीले और निरंतर आकार प्रतिनिधित्व को सुचारू रूप से प्रक्षेपित और अनुमानित करने के लिए टुकड़े-टुकड़े परिभाषित बहुपद कार्यों का उपयोग करता है</string>\n    <string name=\"color_anomaly\">रंग विसंगति</string>\n    <string name=\"saved_to_original\">मूल गंतव्य पर %1$s नाम से अधिलेखित फाइल</string>\n    <string name=\"use_pixel_switch\">पिक्सल स्विच का प्रयोग करें</string>\n    <string name=\"use_pixel_switch_sub\">गूगल के Material You आधारित स्विच की जगह पिक्सल जैसे स्विच का इस्तेमाल किया जाएगा</string>\n    <string name=\"allow_multiple_languages\">कई भाषाओं की अनुमति दें</string>\n    <string name=\"side_by_side\">अगल-बगल</string>\n    <string name=\"toggle_tap\">टैप टॉगल करें</string>\n    <string name=\"slide\">स्लाइड</string>\n    <string name=\"rate_app_sub\">यह ऐप पूरी तरह से मुफ़्त है, यदि आप चाहते हैं कि यह बड़ा हो जाए, तो कृपया प्रोजेक्ट को Github 😄 पर तारांकित करें</string>\n    <string name=\"segmentation_mode_osd_only\">केवल अभिविन्यास और स्क्रिप्ट डिटेक्शन</string>\n    <string name=\"segmentation_mode_auto_osd\">ऑटो अभिविन्यास और स्क्रिप्ट डिटेक्शन</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">विरल पाठ अभिविन्यास और स्क्रिप्ट का पता लगाने</string>\n    <string name=\"current\">वर्तमान</string>\n    <string name=\"gradient_maker_sub\">अनुकूलित रंगों और उपस्थिति प्रकार के साथ दिए गए आउटपुट आकार का अनुपात बनाएं</string>\n    <string name=\"gradient_maker_type_image_sub\">दी गई छवि के शीर्ष का कोई भी अनुपात बनाएं</string>\n    <string name=\"camera_sub\">तस्वीर लेने के लिए कैमरे का उपयोग करता है, ध्यान दें कि इस छवि स्रोत से केवल एक छवि प्राप्त करना संभव है</string>\n    <string name=\"gif_tools\">GIF उपकरण</string>\n    <string name=\"gif_tools_sub\">छवियों को GIF चित्र में बदलें या दिए गए GIF छवि से फ्रेम निकालें</string>\n    <string name=\"delete_language_sub\">क्या आप सभी पहचान प्रकारों के लिए भाषा \\\"%1$s\\\" OCR प्रशिक्षण डेटा हटाना चाहते हैं, या केवल चयनित एक (%2$s) के लिए?</string>\n    <string name=\"gif_type_to_gif_sub\">छवियों के बैच को GIF फाइल में बदलें</string>\n    <string name=\"use_size_of_first_frame\">पहले फ्रेम के आकार का उपयोग करें</string>\n    <string name=\"confetti_sub\">कन्फ़ेटी को सहेजने, साझा करने और अन्य प्राथमिक कार्यों पर दिखाया जाएगा</string>\n    <string name=\"secure_mode_sub\">बाहर निकलने पर सामग्री छुपाता है, साथ ही स्क्रीन को कैप्चर या रिकॉर्ड नहीं किया जा सकता है</string>\n    <string name=\"bayer_three_dithering\">बायर थ्री बाय थ्री डिथरिंग</string>\n    <string name=\"bayer_four_dithering\">बायर फोर बाय फोर डिथरिंग</string>\n    <string name=\"floyd_steinberg_dithering\">फ्लोयड स्टाइनबर्ग डिथरिंग</string>\n    <string name=\"two_row_sierra_dithering\">दो पंक्ति सिएरा डिथरिंग</string>\n    <string name=\"false_floyd_steinberg_dithering\">झूठी फ्लोयड स्टाइनबर्ग डिथरिंग</string>\n    <string name=\"b_spline_sub\">एक वक्र या सतह, लचीले और निरंतर आकार के प्रतिनिधित्व को सुचारू रूप से प्रक्षेपित और अनुमानित करने के लिए टुकड़े-टुकड़े परिभाषित बाइबिक बहुपद कार्यों का उपयोग करता है</string>\n    <string name=\"anaglyph\">एनाग्लिफ</string>\n    <string name=\"pixel_sort\">पिक्सल सॉर्ट</string>\n    <string name=\"shuffle\">शफल</string>\n    <string name=\"enhanced_glitch\">उन्नत गड़बड़ी</string>\n    <string name=\"corruption_size\">भ्रष्टाचार आकार</string>\n    <string name=\"free\">मुक्त</string>\n    <string name=\"all\">सब कुछ</string>\n    <string name=\"gradient_maker\">अनुपात निर्माता</string>\n    <string name=\"rate_app\">ऐप को रेट करें</string>\n    <string name=\"rate\">रेट</string>\n    <string name=\"gradient_type_linear\">रैखिक</string>\n    <string name=\"gradient_type_radial\">रेडियल</string>\n    <string name=\"gradient_type_sweep\">स्वीप</string>\n    <string name=\"gradient_type\">अनुपात प्रकार</string>\n    <string name=\"center_x\">केंद्र X</string>\n    <string name=\"center_y\">केंद्र Y</string>\n    <string name=\"tile_mode\">टाइल मोड</string>\n    <string name=\"tile_mode_repeated\">दोहराया</string>\n    <string name=\"tile_mode_mirror\">दर्पण</string>\n    <string name=\"tile_mode_clamp\">क्लैंप</string>\n    <string name=\"tile_mode_decal\">डिकल</string>\n    <string name=\"color_stops\">रंग बंद हो जाता है</string>\n    <string name=\"add_color\">रंग जोड़ें</string>\n    <string name=\"properties\">गुण</string>\n    <string name=\"lasso_sub\">दिए गए पथ से बंद भरा पथ खींचता है</string>\n    <string name=\"dithering\">डिथरिंग</string>\n    <string name=\"quantizier\">क्वांटिज़ियर</string>\n    <string name=\"gray_scale\">ग्रे स्केल</string>\n    <string name=\"bayer_two_dithering\">बायर टू बाय टू डिथरिंग</string>\n    <string name=\"bayer_eight_dithering\">बायर आठ से आठ डिथरिंग</string>\n    <string name=\"jarvis_judice_ninke_dithering\">जार्विस जुडिस निन्के डिथरिंग</string>\n    <string name=\"sierra_dithering\">सिएरा डिथरिंग</string>\n    <string name=\"sierra_lite_dithering\">सिएरा लाइट डिथरिंग</string>\n    <string name=\"atkinson_dithering\">एटकिंसन डिथरिंग</string>\n    <string name=\"stucki_dithering\">स्टकी डिथरिंग</string>\n    <string name=\"burkes_dithering\">बर्क्स डिथरिंग</string>\n    <string name=\"left_to_right_dithering\">बाएं से दाएं डिथरिंग</string>\n    <string name=\"random_dithering\">यादृच्छिक डिथरिंग</string>\n    <string name=\"simple_threshold_dithering\">सरल थ्रेसहोल्ड डिथरिंग</string>\n    <string name=\"hermite\">हर्माइट</string>\n    <string name=\"lanczos\">लैंक्ज़ोस</string>\n    <string name=\"scale_mode\">स्केल मोड</string>\n    <string name=\"bilinear\">द्विरेखीय</string>\n    <string name=\"hann\">हन्न</string>\n    <string name=\"mitchell\">मिशेल</string>\n    <string name=\"nearest\">निकटतम</string>\n    <string name=\"spline\">स्प्लाइन</string>\n    <string name=\"basic\">बेसिक</string>\n    <string name=\"default_value\">तयशुदा मान</string>\n    <string name=\"sigma\">सिग्मा</string>\n    <string name=\"spatial_sigma\">स्थानिक सिग्मा</string>\n    <string name=\"median_blur\">मेडियन ब्लर</string>\n    <string name=\"catmull\">कैटमुल</string>\n    <string name=\"bicubic_sub\">बेहतर स्केलिंग विधियों में लैंक्ज़ोस रीसम्पलिंग और मिशेल-नेत्रावली फिल्टर शामिल हैं</string>\n    <string name=\"basic_sub\">सरलतम Android स्केलिंग मोड जो लगभग सभी ऐप्स में उपयोग किया जाता है</string>\n    <string name=\"hermite_sub\">गणितीय प्रक्षेप तकनीक जो एक चिकनी और निरंतर वक्र उत्पन्न करने के लिए एक वक्र खंड के समापन बिंदुओं पर मूल्यों और डेरिवेटिव का उपयोग करती है</string>\n    <string name=\"lanczos_sub\">पुन: नमूनाकरण विधि जो पिक्सल मानों के लिए भारित सिंक फ़ंक्शन को लागू करके उच्च गुणवत्ता वाले प्रक्षेप को बनाए रखती है</string>\n    <string name=\"only_clip\">केवल क्लिप</string>\n    <string name=\"only_clip_sub\">स्टोरेज में सहेजा नहीं जाएगा, और छवि को केवल क्लिपबोर्ड में डालने का प्रयास किया जाएगा</string>\n    <string name=\"brightness_enforcement\">चमक प्रवर्तन</string>\n    <string name=\"screen\">स्क्रीन</string>\n    <string name=\"gradient_maker_type_image\">अनुपात उपरिशायी</string>\n    <string name=\"transformations\">परिवर्तन</string>\n    <string name=\"camera\">कैमरा</string>\n    <string name=\"watermarking\">वॉटरमार्किंग</string>\n    <string name=\"watermarking_sub\">अनुकूलन पाठ / छवि वॉटरमार्क के साथ चित्रों को कवर करें</string>\n    <string name=\"repeat_watermark\">वॉटरमार्क दोहराएं</string>\n    <string name=\"repeat_watermark_sub\">दिए गए स्थान पर एकल के बजाय छवि पर वॉटरमार्क दोहराता है</string>\n    <string name=\"offset_x\">ऑफसेट X</string>\n    <string name=\"offset_y\">ऑफसेट Y</string>\n    <string name=\"watermark_type\">वॉटरमार्क प्रकार</string>\n    <string name=\"watermarking_image_sub\">इस छवि का उपयोग वॉटरमार्किंग के लिए पैटर्न के रूप में किया जाएगा</string>\n    <string name=\"text_color\">पाठ का रंग</string>\n    <string name=\"overlay_mode\">ओवरले मोड</string>\n    <string name=\"gif_type_to_image\">GIF से छवियां</string>\n    <string name=\"gif_type_to_image_sub\">GIF फाइल को चित्रों के बैच में बदलें</string>\n    <string name=\"gif_type_to_gif\">छवियां से GIF</string>\n    <string name=\"select_gif_image_to_start\">आरंभ करने के लिए GIF छवि चुनें</string>\n    <string name=\"use_size_of_first_frame_sub\">निर्दिष्ट आकार को पहले फ्रेम आयामों से बदलें</string>\n    <string name=\"repeat_count\">गिनती दोहराएं</string>\n    <string name=\"frame_delay\">फ्रेम देरी</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">लैस्सो का प्रयोग करें</string>\n    <string name=\"use_lasso_sub\">मिटाने के लिए आरेखण मोड में लैस्सो का उपयोग करता है</string>\n    <string name=\"original_image_preview_alpha\">मूल छवि पूर्वावलोकन अल्फा</string>\n    <string name=\"recognize_text\">OCR (पाठ पहचानें)</string>\n    <string name=\"recognize_text_sub\">दी गई छवि से पाठ को पहचानें, 120 + भाषाओं का समर्थन किया</string>\n    <string name=\"picture_has_no_text\">चित्र में कोई पाठ नहीं है, या ऐप को यह नहीं मिला</string>\n    <string name=\"accuracy\">सटीकता: %1$s</string>\n    <string name=\"recognition_type\">मान्यता प्रकार</string>\n    <string name=\"fast\">तेज</string>\n    <string name=\"standard\">मानक</string>\n    <string name=\"best\">सबसे अच्छा</string>\n    <string name=\"no_data\">कोई डेटा नहीं</string>\n    <string name=\"download_description\">Tesseract OCR के समुचित कार्य के लिए अतिरिक्त प्रशिक्षण डेटा (%1$s) को आपके डिवाइस पर डाउनलोड करने की आवश्यकता है । \\nक्या आप %2$s डेटा डाउनलोड करना चाहते हैं?</string>\n    <string name=\"download\">डाउनलोड</string>\n    <string name=\"no_connection\">कोई कनेक्शन नहीं, इसे जांचें और ट्रेन मॉडल डाउनलोड करने के लिए फिर से प्रयास करें</string>\n    <string name=\"downloaded_languages\">डाउनलोड की गई भाषाएं</string>\n    <string name=\"available_languages\">उपलब्ध भाषाएं</string>\n    <string name=\"segmentation_mode\">विभाजन मोड</string>\n    <string name=\"restore_background_sub\">ब्रश मिटाने के बजाय पृष्ठभूमि को पुनर्स्थापित करेगा</string>\n    <string name=\"horizontal_grid\">क्षैतिज ग्रिड</string>\n    <string name=\"vertical_grid\">ऊर्ध्वाधर ग्रिड</string>\n    <string name=\"stitch_mode\">सिलाई मोड</string>\n    <string name=\"rows_count\">पंक्तियों की गिनती</string>\n    <string name=\"columns_count\">कॉलम गिनती</string>\n    <string name=\"transparency\">पारदर्शिता</string>\n    <string name=\"magnifier\">आवर्धक</string>\n    <string name=\"magnifier_sub\">बेहतर पहुंच के लिए आरेखण मोड में उंगली के शीर्ष पर आवर्धक सक्षम करता है</string>\n    <string name=\"force_exif_widget_initial_value\">आरंभिक मान को बाध्य करें</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Exif विजेट को प्रारंभ में जाँचने के लिए बाध्य करता है</string>\n    <string name=\"b_spline\">B स्प्लाइन</string>\n    <string name=\"native_stack_blur\">मूल स्टैक ब्लर</string>\n    <string name=\"tilt_shift\">झुकाव शिफ्ट</string>\n    <string name=\"confetti\">कन्फ़ेटी</string>\n    <string name=\"secure_mode\">सुरक्षित मोड</string>\n    <string name=\"exit\">बाहर निकलें</string>\n    <string name=\"preview_closing\">यदि आप अभी पूर्वावलोकन छोड़ते हैं, तो आपको छवियों को फिर से जोड़ना होगा</string>\n    <string name=\"tent_blur\">टेंट ब्लर</string>\n    <string name=\"side_fade\">पार्श्व फीका</string>\n    <string name=\"side\">पार्श्व</string>\n    <string name=\"top\">शीर्ष</string>\n    <string name=\"bottom\">नीचे</string>\n    <string name=\"strength\">ताकत</string>\n    <string name=\"aldridge\">एल्ड्रिज</string>\n    <string name=\"cutoff\">कटऑफ</string>\n    <string name=\"uchimura\">उचिमुरा</string>\n    <string name=\"mobius\">मोबियस</string>\n    <string name=\"pink_dream\">गुलाबी सपना</string>\n    <string name=\"colorful_swirl\">रंगीन भंवर</string>\n    <string name=\"lemonade_light\">नींबू पानी प्रकाश</string>\n    <string name=\"lavender_dream\">लैवेंडर सपना</string>\n    <string name=\"cyberpunk\">साइबरपंक</string>\n    <string name=\"fantasy_landscape\">काल्पनिक परिदृश्य</string>\n    <string name=\"caramel_darkness\">कारमेल अंधेरे</string>\n    <string name=\"drago\">ड्रैगो</string>\n    <string name=\"color_matrix_4x4\">रंग मैट्रिक्स 4x4</string>\n    <string name=\"color_matrix_3x3\">रंग मैट्रिक्स 3x3</string>\n    <string name=\"protonomaly\">प्रोटोनोमाली</string>\n    <string name=\"coda_chrome\">कोडा क्रोम</string>\n    <string name=\"vintage\">विंटेज</string>\n    <string name=\"night_vision\">रात्रि दृष्टि</string>\n    <string name=\"achromatomaly\">अक्रोमैटोमाली</string>\n    <string name=\"erode\">इरोड</string>\n    <string name=\"anisotropic_diffusion\">अनिसोट्रोपिक प्रसार</string>\n    <string name=\"diffusion\">प्रसार</string>\n    <string name=\"conduction\">चालन</string>\n    <string name=\"horizontal_wind_stagger\">क्षैतिज हवा डगमगाती</string>\n    <string name=\"fast_bilaterial_blur\">तेज़ द्विपक्षीय ब्लर</string>\n    <string name=\"poisson_blur\">पॉइसन ब्लर</string>\n    <string name=\"logarithmic_tone_mapping\">लॉगरिदमिक टोन मैपिंग</string>\n    <string name=\"crystallize\">क्रिस्टलाइज</string>\n    <string name=\"stroke_color\">स्ट्रोक रंग</string>\n    <string name=\"fractal_glass\">भग्न ग्लास</string>\n    <string name=\"amplitude\">आयाम</string>\n    <string name=\"marble\">संगमरमर</string>\n    <string name=\"turbulence\">अशांति</string>\n    <string name=\"oil\">तेल</string>\n    <string name=\"water_effect\">जल प्रभाव</string>\n    <string name=\"just_size\">आकार</string>\n    <string name=\"frequency_x\">आवृत्ति X</string>\n    <string name=\"frequency_y\">आवृत्ति Y</string>\n    <string name=\"amplitude_x\">आयाम X</string>\n    <string name=\"amplitude_y\">आयाम Y</string>\n    <string name=\"perlin_distortion\">पर्लिन विरूपण</string>\n    <string name=\"hable_filmic_tone_mapping\">हैबल फिल्मी टोन मैपिंग</string>\n    <string name=\"heji_burgess_tone_mapping\">हेजल बर्गेस टोन मैपिंग</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES फिल्मी टोन मैपिंग</string>\n    <string name=\"aces_hill_tone_mapping\">ACES हिल टोन मैपिंग</string>\n    <string name=\"speed\">गति</string>\n    <string name=\"dehaze\">डेहेज़</string>\n    <string name=\"omega\">ओमेगा</string>\n    <string name=\"simple_effects\">सरल प्रभाव</string>\n    <string name=\"polaroid\">पोलरॉइड</string>\n    <string name=\"tritonomaly\">ट्रिटोनोमाली</string>\n    <string name=\"deutaromaly\">ड्यूटारोमाली</string>\n    <string name=\"browni\">ब्राउनी</string>\n    <string name=\"warm\">गर्म</string>\n    <string name=\"cool\">कूल</string>\n    <string name=\"tritanopia\">ट्रिटानोपिया</string>\n    <string name=\"deutaronotopia\">ड्यूटारोनोटोपिया</string>\n    <string name=\"protanopia\">प्रोटानोपिया</string>\n    <string name=\"achromatopsia\">अक्रोमैटोप्सिया</string>\n    <string name=\"grain\">अनाज</string>\n    <string name=\"unsharp\">अनशर्प</string>\n    <string name=\"pastel\">पेस्टल</string>\n    <string name=\"orange_haze\">नारंगी धुंध</string>\n    <string name=\"golden_hour\">सुनहरा घंटा</string>\n    <string name=\"hot_summer\">गर्म गर्मी</string>\n    <string name=\"purple_mist\">बैंगनी धुंध</string>\n    <string name=\"sunrise\">सूर्योदय</string>\n    <string name=\"soft_spring_light\">शीतल वसंत प्रकाश</string>\n    <string name=\"autumn_tones\">शरद ऋतु टन</string>\n    <string name=\"spectral_fire\">वर्णक्रमीय आग</string>\n    <string name=\"electric_gradient\">विद्युत अनुपात</string>\n    <string name=\"futuristic_gradient\">भविष्यवादी अनुपात</string>\n    <string name=\"shuffle_blur\">शफल ब्लर</string>\n    <string name=\"favorite\">पसंदीदा</string>\n    <string name=\"no_favorite_filters\">अभी तक कोई पसंदीदा फिल्टर नहीं जोड़ा गया है</string>\n    <string name=\"image_format\">छवि प्रारूप</string>\n    <string name=\"cannot_change_image_format\">फाइलों को अधिलेखित करते समय छवि प्रारूप नहीं बदल सकता विकल्प सक्षम</string>\n    <string name=\"emoji_as_color_scheme\">रंग योजना के रूप में इमोजी</string>\n    <string name=\"emoji_as_color_scheme_sub\">मैन्युअल रूप से परिभाषित एक के बजाय ऐप रंग योजना के रूप में इमोजी प्राथमिक रंग का उपयोग करता है</string>\n    <string name=\"images_overwritten\">मूल गंतव्य पर ओवरराइट की गई छवियां</string>\n    <string name=\"material_you_sub\">छवि से Material You पैलेट बनाता है</string>\n    <string name=\"dark_colors\">गहरे रंग</string>\n    <string name=\"dark_colors_sub\">हल्के संस्करण के बजाय रात्रि मोड रंग योजना का उपयोग करता है</string>\n    <string name=\"copy_as_compose_code\">Jetpack Compose कोड के रूप में कॉपी करें</string>\n    <string name=\"circle_blur\">वृत्त ब्लर</string>\n    <string name=\"star_blur\">स्टार ब्लर</string>\n    <string name=\"ring_blur\">रिंग ब्लर</string>\n    <string name=\"cross_blur\">क्रॉस ब्लर</string>\n    <string name=\"linear_tilt_shift\">रैखिक झुकाव शिफ्ट</string>\n    <string name=\"tags_to_remove\">हटाने के लिए टैग</string>\n    <string name=\"apng_tools_sub\">छवियों को APNG चित्र में बदलें या दी गई APNG छवि से फ़्रेम निकालें</string>\n    <string name=\"apng_type_to_image_sub\">APNG फाइल को चित्रों के बैच में बदलें</string>\n    <string name=\"apng_type_to_apng_sub\">छवियों के बैच को APNG फाइल में बदलें</string>\n    <string name=\"apng_type_to_apng\">छवियां से APNG</string>\n    <string name=\"select_apng_image_to_start\">आरंभ करने के लिए APNG छवि चुनें</string>\n    <string name=\"apng_type_to_image\">APNG से छवियां</string>\n    <string name=\"apng_tools\">APNG टूल्स</string>\n    <string name=\"motion_blur\">मोशन ब्लर</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">दी गई फाइलों या छवियों से Zip फाइल बनाएं</string>\n    <string name=\"drag_handle_width\">खींचें हैंडल की चौड़ाई</string>\n    <string name=\"explode\">विस्फोट</string>\n    <string name=\"rain\">बारिश</string>\n    <string name=\"confetti_type\">कन्फ़ेटी प्रकार</string>\n    <string name=\"festive\">उत्सवपूर्ण</string>\n    <string name=\"corners\">कोने</string>\n    <string name=\"jxl_tools\">JXL टूल्स</string>\n    <string name=\"jxl_tools_sub\">बिना गुणवत्ता हानि के JXL ~ JPEG ट्रांसकोडिंग करें, या GIF/APNG को JXL एनीमेशन में बदलें</string>\n    <string name=\"jxl_type_to_jpeg\">JXL से JPEG</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG से JXL</string>\n    <string name=\"select_jxl_image_to_start\">आरंभ करने के लिए JXL छवि चुनें</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG से JXL तक दोषरहित ट्रांसकोडिंग करें</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL से JPEG तक दोषरहित ट्रांसकोडिंग करें</string>\n    <string name=\"fast_gaussian_blur_3d\">तेज गॉसियन ब्लर 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">तेज गॉसियन ब्लर 4D</string>\n    <string name=\"fast_gaussian_blur_2d\">तेज गॉसियन ब्लर 2D</string>\n    <string name=\"auto_paste\">ऑटो पेस्ट</string>\n    <string name=\"auto_paste_sub\">ऐप को क्लिपबोर्ड डेटा को ऑटो पेस्ट करने की अनुमति देता है, जिससे यह मुख्य स्क्रीन पर दिखाई देगा और आप इसे संसाधित करने में सक्षम होंगे</string>\n    <string name=\"harmonization_color\">सामंजस्य रंग</string>\n    <string name=\"harmonization_level\">सामंजस्य स्तर</string>\n    <string name=\"lanczos_bessel\">लैंक्ज़ोस बेसेल</string>\n    <string name=\"gif_type_to_jxl\">GIF से JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF छवियों को JXL एनिमेटेड चित्रों में बदलें</string>\n    <string name=\"apng_type_to_jxl\">APNG से JXL</string>\n    <string name=\"jxl_type_to_images_sub\">JXL एनिमेशन को चित्रों के बैच में बदलें</string>\n    <string name=\"jxl_type_to_images\">JXL से छवियां</string>\n    <string name=\"jxl_type_to_jxl\">छवियों से JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">चित्रों के बैच को JXL एनीमेशन में बदलें</string>\n    <string name=\"behavior\">व्यवहार</string>\n    <string name=\"skip_file_picking\">फाइल चयन छोड़ें</string>\n    <string name=\"skip_file_picking_sub\">यदि संभव हो तो चयनित स्क्रीन पर फाइल चयनकर्ता तुरंत दिखाया जाएगा</string>\n    <string name=\"generate_previews\">पूर्वावलोकन उत्पन्न करें</string>\n    <string name=\"generate_previews_sub\">पूर्वावलोकन जनरेशन सक्षम करता है, इससे कुछ उपकरणों पर क्रैश से बचने में मदद मिल सकती है, यह एकल संपादन विकल्प के भीतर कुछ संपादन कार्यक्षमता को भी अक्षम कर देता है</string>\n    <string name=\"lossy_compression\">हानिपूर्ण संपीड़न</string>\n    <string name=\"lossy_compression_sub\">फाइल आकार को दोषरहित के बजाय कम करने के लिए हानिपूर्ण संपीड़न का उपयोग करता है</string>\n    <string name=\"lanczos_bessel_sub\">पुन: नमूनाकरण विधि जो पिक्सल मानों पर बेसेल (jinc) फ़ंक्शन लागू करके उच्च गुणवत्ता वाले इंटरपोलेशन को बनाए रखती है</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG छवियों को JXL एनिमेटेड चित्रों में बदलें</string>\n    <string name=\"compression_type\">संपीड़न प्रकार</string>\n    <string name=\"speed_sub\">परिणामी छवि डिकोडिंग गति को नियंत्रित करता है, इससे परिणामी छवि को तेजी से खोलने में मदद मिलेगी, %1$s का मतलब सबसे धीमी डिकोडिंग, जबकि %2$s - सबसे तेज़, यह सेटिंग आउटपुट छवि आकार को बढ़ा सकती है</string>\n    <string name=\"sort_by_name\">नाम से छांटें</string>\n    <string name=\"sort_by_name_reversed\">नाम से छांटें (उलटा)</string>\n    <string name=\"sorting\">छंटाई</string>\n    <string name=\"sort_by_date_reversed\">तिथि से छांटें (उलटा)</string>\n    <string name=\"sort_by_date\">तिथि से छांटें</string>\n    <string name=\"channels_configuration\">चैनल विन्यास</string>\n    <string name=\"header_today\">आज</string>\n    <string name=\"embedded_picker\">अंतर्निहित चयनकर्ता</string>\n    <string name=\"header_yesterday\">कल</string>\n    <string name=\"embedded_picker_sub\">सिस्टम द्वारा पूर्वनिर्धारित छवि चयनकर्ता के बजाय इमेज टूलबॉक्स के स्वयं के छवि चयनकर्ता का उपयोग करता है</string>\n    <string name=\"request\">अनुरोध</string>\n    <string name=\"pick_multiple_media\">एकाधिक मीडिया चुनें</string>\n    <string name=\"pick_single_media\">एकल मीडिया चुनें</string>\n    <string name=\"pick\">चुनें</string>\n    <string name=\"no_permissions\">कोई अनुमतियां नहीं</string>\n    <string name=\"try_again\">पुनः प्रयास करें</string>\n    <string name=\"show_settings_in_landscape\">लैंडस्केप में सेटिंग्स दिखाएं</string>\n    <string name=\"show_settings_in_landscape_sub\">अक्षम होने पर लैंडस्केप मोड में स्थायी दृश्यमान विकल्प के बजाय सेटिंग्स हमेशा की तरह शीर्ष ऐप बार में बटन पर खोली जाएंगी</string>\n    <string name=\"switch_type\">स्विच प्रकार</string>\n    <string name=\"compose\">लिखें</string>\n    <string name=\"fullscreen_settings\">फ़ुलस्क्रीन सेटिंग्स</string>\n    <string name=\"fullscreen_settings_sub\">इसे सक्षम करें और सेटिंग पेज हमेशा स्लाइड करने योग्य ड्रॉअर शीट के बजाय फ़ुलस्क्रीन के रूप में खोला जाएगा</string>\n    <string name=\"compose_switch_sub\">Jetpack Compose Material You स्विच का उपयोग करें, यह दृश्य आधारित जितना सुंदर नहीं है</string>\n    <string name=\"material_you_switch_sub\">दृश्य आधारित Material You स्विच का उपयोग करता है, यह दूसरों की तुलना में बेहतर दिखता है और इसमें अच्छे एनिमेशन हैं</string>\n    <string name=\"pixel_switch\">पिक्सल</string>\n    <string name=\"cupertino_switch_sub\">Cupertino डिज़ाइन प्रणाली पर आधारित iOS जैसे स्विच का उपयोग करता है</string>\n    <string name=\"max\">अधि</string>\n    <string name=\"resize_anchor\">एंकर का आकार बदलें</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">\\\"Fluent\\\" डिज़ाइन प्रणाली पर आधारित Windows 11 स्टाइल स्विच का उपयोग करता है</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"use_sampled_palette\">नमूनाकृत पैलेट का प्रयोग करें</string>\n    <string name=\"path_omit\">पथ छोड़ें</string>\n    <string name=\"downscale_image\">छवि आकार घटाये</string>\n    <string name=\"downscale_image_sub\">प्रसंस्करण से पहले छवि को छोटे आयामों तक छोटा कर दिया जाएगा, इससे औजार को तेजी से और सुरक्षित रूप से काम करने में मदद मिलती है</string>\n    <string name=\"min_color_ratio\">न्यूनतम रंग अनुपात</string>\n    <string name=\"lines_threshold\">रेखाएं दहलीज</string>\n    <string name=\"coordinates_rounding_tolerance\">निर्देशांक गोलाई सहिष्णुता</string>\n    <string name=\"path_scale\">पथ पैमाना</string>\n    <string name=\"reset_properties\">गुण रीसेट करें</string>\n    <string name=\"images_to_svg\">छवियां को SVG में</string>\n    <string name=\"images_to_svg_sub\">दी गई छवियों को SVG छवियों में ट्रेस करें</string>\n    <string name=\"use_sampled_palette_sub\">यदि यह विकल्प सक्षम है तो परिमाणीकरण पैलेट का नमूना लिया जाएगा</string>\n    <string name=\"svg_warning\">इस औजार का उपयोग बड़ी छवियों का अनुरेखण बिना आकार घटाये करने के लिए अनुशंसित नहीं है, इससे क्रैश हो सकता है और प्रसंस्करण समय बढ़ सकता है</string>\n    <string name=\"quadratic_threshold\">द्विघात दहलीज</string>\n    <string name=\"reset_properties_sub\">सभी गुण को तयशुदा मानों पर सेट किया जाएगा, ध्यान दें कि इस क्रिया को पूर्ववत नहीं किया जा सकता है</string>\n    <string name=\"detailed\">विस्तृत</string>\n    <string name=\"default_line_width\">तयशुदा रेखा चौड़ाई</string>\n    <string name=\"engine_mode\">इंजन मोड</string>\n    <string name=\"lstm_network\">LSTM नेटवर्क</string>\n    <string name=\"legacy\">विरासत</string>\n    <string name=\"legacy_and_lstm\">विरासत और LSTM</string>\n    <string name=\"convert\">बदलें</string>\n    <string name=\"convert_sub\">छवि बैचों को दिए गए प्रारूप में बदलें</string>\n    <string name=\"add_new_folder\">नया फोल्डर जोड़ें</string>\n    <string name=\"tag_bits_per_sample\">प्रति नमूना बिट्स</string>\n    <string name=\"tag_compression\">संपीड़न</string>\n    <string name=\"tag_photometric_interpretation\">फोटोमीट्रिक व्याख्या</string>\n    <string name=\"tag_samples_per_pixel\">प्रति पिक्सल नमूने</string>\n    <string name=\"tag_planar_configuration\">तलीय विन्यास</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr उप नमूनाकरण</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr पोजिशनिंग</string>\n    <string name=\"tag_x_resolution\">X रेजोल्यूशन</string>\n    <string name=\"tag_y_resolution\">Y रेजोल्यूशन</string>\n    <string name=\"tag_resolution_unit\">रेजोल्यूशन इकाई</string>\n    <string name=\"tag_strip_offsets\">स्ट्रिप ऑफसेट</string>\n    <string name=\"tag_rows_per_strip\">पंक्तियां प्रति पट्टी</string>\n    <string name=\"tag_strip_byte_counts\">स्ट्रिप बाइट गणना</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG इंटरचेंज प्रारूप</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG इंटरचेंज प्रारूप की लंबाई</string>\n    <string name=\"tag_transfer_function\">स्थानांतरण प्रकार्य</string>\n    <string name=\"tag_white_point\">सफेद बिन्दु</string>\n    <string name=\"tag_primary_chromaticities\">प्राथमिक वर्णिकताएं</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr गुणांक</string>\n    <string name=\"tag_make\">निर्माता</string>\n    <string name=\"tag_reference_black_white\">संदर्भ काला सफ़ेद</string>\n    <string name=\"tag_datetime\">तिथि समय</string>\n    <string name=\"tag_image_description\">छवि विवरण</string>\n    <string name=\"tag_model\">मॉडल</string>\n    <string name=\"tag_software\">सॉफ्टवेयर</string>\n    <string name=\"tag_artist\">कलाकार</string>\n    <string name=\"tag_copyright\">कॉपीराइट</string>\n    <string name=\"tag_exif_version\">EXIF संस्करण</string>\n    <string name=\"tag_flashpix_version\">Flashpix संस्करण</string>\n    <string name=\"tag_color_space\">रंग स्थान</string>\n    <string name=\"tag_gamma\">गामा</string>\n    <string name=\"tag_pixel_x_dimension\">पिक्सल X आयाम</string>\n    <string name=\"tag_pixel_y_dimension\">पिक्सल Y आयाम</string>\n    <string name=\"tag_compressed_bits_per_pixel\">प्रति पिक्सल संपीड़ित बिट्स</string>\n    <string name=\"tag_maker_note\">निर्माता टिप्पणी</string>\n    <string name=\"tag_user_comment\">उपयोक्ता टिप्पणी</string>\n    <string name=\"tag_related_sound_file\">संबंधित ध्वनि फाइल</string>\n    <string name=\"tag_datetime_original\">दिनांक समय मूल</string>\n    <string name=\"tag_datetime_digitized\">दिनांक समय डिजिटलीकृत</string>\n    <string name=\"tag_offset_time\">ऑफसेट समय</string>\n    <string name=\"tag_offset_time_original\">ऑफसेट समय मूल</string>\n    <string name=\"tag_offset_time_digitized\">ऑफसेट समय डिजिटलीकृत</string>\n    <string name=\"tag_subsec_time\">उप-सेकंड समय</string>\n    <string name=\"tag_subsec_time_original\">उप-सेकंड समय मूल</string>\n    <string name=\"tag_subsec_time_digitized\">उप-सेकंड समय डिजिटलीकृत</string>\n    <string name=\"tag_exposure_time\">एक्सपोज़र समय</string>\n    <string name=\"tag_f_number\">F संख्या</string>\n    <string name=\"tag_exposure_program\">एक्सपोज़र प्रोग्राम</string>\n    <string name=\"tag_spectral_sensitivity\">वर्णक्रमीय संवेदनशीलता</string>\n    <string name=\"tag_photographic_sensitivity\">फोटोग्राफिक संवेदनशीलता</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">संवेदनशीलता प्रकार</string>\n    <string name=\"tag_standard_output_sensitivity\">मानक आउटपुट संवेदनशीलता</string>\n    <string name=\"tag_recommended_exposure_index\">अनुशंसित एक्सपोज़र इंडेक्स</string>\n    <string name=\"tag_iso_speed\">ISO गति</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO गति अक्षांश yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO गति अक्षांश zzz</string>\n    <string name=\"tag_shutter_speed_value\">शटर गति मान</string>\n    <string name=\"tag_aperture_value\">एपर्चर मान</string>\n    <string name=\"tag_brightness_value\">चमक मान</string>\n    <string name=\"tag_exposure_bias_value\">एक्सपोजर पूर्वाग्रह मान</string>\n    <string name=\"tag_max_aperture_value\">अधि एपर्चर मान</string>\n    <string name=\"tag_subject_distance\">विषय दूरी</string>\n    <string name=\"tag_metering_mode\">पैमाइश प्रणाली</string>\n    <string name=\"tag_flash\">फ़्लैश</string>\n    <string name=\"tag_subject_area\">विषय क्षेत्र</string>\n    <string name=\"tag_focal_length\">फोकल लंबाई</string>\n    <string name=\"tag_focal_plane_y_resolution\">फोकल प्लेन Y रेजोल्यूशन</string>\n    <string name=\"tag_flash_energy\">फ़्लैश ऊर्जा</string>\n    <string name=\"tag_spatial_frequency_response\">स्थानिक आवृत्ति प्रतिक्रिया</string>\n    <string name=\"tag_focal_plane_x_resolution\">फोकल प्लेन X रेजोल्यूशन</string>\n    <string name=\"tag_focal_plane_resolution_unit\">फोकल प्लेन रेजोल्यूशन यूनिट</string>\n    <string name=\"tag_subject_location\">विषय स्थान</string>\n    <string name=\"tag_exposure_index\">एक्सपोजर सूचकांक</string>\n    <string name=\"tag_sensing_method\">संवेदन विधि</string>\n    <string name=\"tag_file_source\">फाइल स्रोत</string>\n    <string name=\"tag_cfa_pattern\">CFA पैटर्न</string>\n    <string name=\"tag_custom_rendered\">तदनुकूल प्रतिपादित</string>\n    <string name=\"tag_exposure_mode\">एक्सपोज़र मोड</string>\n    <string name=\"tag_white_balance\">श्वेत संतुलन</string>\n    <string name=\"tag_digital_zoom_ratio\">डिजिटल जूम अनुपात</string>\n    <string name=\"tag_focal_length_in_35mm_film\">फोकल लंबाई In35mm फिल्म</string>\n    <string name=\"tag_scene_capture_type\">दृश्य कैप्चर प्रकार</string>\n    <string name=\"tag_gain_control\">गेन नियंत्रण</string>\n    <string name=\"tag_contrast\">वैषम्य</string>\n    <string name=\"tag_saturation\">संतृप्ति</string>\n    <string name=\"tag_sharpness\">पैनापन</string>\n    <string name=\"tag_device_setting_description\">डिवाइस सेटिंग विवरण</string>\n    <string name=\"tag_subject_distance_range\">विषय की दूरी सीमा</string>\n    <string name=\"tag_image_unique_id\">छवि विशिष्ट ID</string>\n    <string name=\"tag_camera_owner_name\">कैमरा मालिक का नाम</string>\n    <string name=\"tag_body_serial_number\">बॉडी क्रमांक</string>\n    <string name=\"tag_lens_specification\">लेंस विशिष्टता</string>\n    <string name=\"tag_lens_make\">लेंस निर्माता</string>\n    <string name=\"tag_lens_model\">लेंस मॉडल</string>\n    <string name=\"tag_lens_serial_number\">लेंस क्रमांक</string>\n    <string name=\"tag_gps_version_id\">GPS संस्करण ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS अक्षांश संदर्भ</string>\n    <string name=\"tag_gps_latitude\">GPS अक्षांश</string>\n    <string name=\"tag_gps_longitude_ref\">GPS देशांतर संदर्भ</string>\n    <string name=\"tag_gps_longitude\">GPS देशांतर</string>\n    <string name=\"tag_gps_altitude_ref\">GPS ऊंचाई संदर्भ</string>\n    <string name=\"tag_gps_altitude\">GPS ऊंचाई</string>\n    <string name=\"tag_gps_timestamp\">GPS समय-चिह्न</string>\n    <string name=\"tag_gps_satellites\">GPS उपग्रह</string>\n    <string name=\"tag_gps_status\">GPS स्थिति</string>\n    <string name=\"tag_gps_measure_mode\">GPS माप मोड</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS गति संदर्भ</string>\n    <string name=\"tag_gps_speed\">GPS गति</string>\n    <string name=\"tag_gps_track_ref\">GPS ट्रैक संदर्भ</string>\n    <string name=\"tag_gps_track\">GPS ट्रैक</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS छवि दिशा संदर्भ</string>\n    <string name=\"tag_gps_img_direction\">GPS छवि दिशा</string>\n    <string name=\"tag_gps_map_datum\">GPS मानचित्र आधार</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS गंतव्य अक्षांश संदर्भ</string>\n    <string name=\"tag_gps_dest_latitude\">GPS गंतव्य अक्षांश</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS गंतव्य देशांतर संदर्भ</string>\n    <string name=\"tag_gps_dest_longitude\">GPS गंतव्य देशांतर</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS गंतव्य बियरिंग संदर्भ</string>\n    <string name=\"tag_gps_dest_bearing\">GPS गंतव्य दिक्कोण</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS गंतव्य दूरी संदर्भ</string>\n    <string name=\"tag_gps_dest_distance\">GPS गंतव्य दूरी</string>\n    <string name=\"tag_gps_processing_method\">GPS प्रसंस्करण विधि</string>\n    <string name=\"tag_gps_area_information\">GPS क्षेत्र सूचना</string>\n    <string name=\"tag_gps_datestamp\">GPS दिनांक मोहर</string>\n    <string name=\"tag_gps_differential\">GPS विभेदक</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H पोजिशनिंग त्रुटि</string>\n    <string name=\"tag_interoperability_index\">अंतरसंचालनीयता सूचकांक</string>\n    <string name=\"tag_dng_version\">DNG संस्करण</string>\n    <string name=\"tag_default_crop_size\">तयशुदा क्रॉप आकार</string>\n    <string name=\"tag_orf_preview_image_start\">पूर्वावलोकन छवि प्रारंभ करें</string>\n    <string name=\"tag_orf_preview_image_length\">छवि लंबाई का पूर्वावलोकन करें</string>\n    <string name=\"tag_orf_aspect_frame\">पहलू ढांचा</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">सेंसर निचला बॉर्डर</string>\n    <string name=\"tag_rw2_sensor_left_border\">सेंसर बायां बॉर्डर</string>\n    <string name=\"tag_rw2_sensor_right_border\">सेंसर दायां बॉर्डर</string>\n    <string name=\"tag_rw2_sensor_top_border\">सेंसर शीर्ष बॉर्डर</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">दिए गए फ़ॉन्ट और रंग के साथ पथ पर पाठ बनाएं</string>\n    <string name=\"font_size\">फॉन्ट आकार</string>\n    <string name=\"watermark_size\">वॉटरमार्क आकार</string>\n    <string name=\"draw_mode_image_sub\">चयनित छवि को दिए गए पथ पर खींचने के लिए उसका उपयोग करें</string>\n    <string name=\"repeat_text\">पाठ दोहराएँ</string>\n    <string name=\"repeat_text_sub\">वर्तमान पाठ को एक बार की आरेखण के बजाय पथ समाप्त होने तक दोहराया जाएगा</string>\n    <string name=\"dash_size\">डैश का आकार</string>\n    <string name=\"draw_image_sub\">इस छवि का उपयोग खींचे गए पथ की दोहरावदार प्रविष्टि के रूप में किया जाएगा</string>\n    <string name=\"outlined_triangle_sub\">आरंभ बिंदु से अंत बिंदु तक रेखांकित त्रिभुज बनाता है</string>\n    <string name=\"triangle_sub\">आरंभ बिंदु से अंत बिंदु तक रेखांकित त्रिभुज बनाता है</string>\n    <string name=\"outlined_triangle\">रेखांकित त्रिभुज</string>\n    <string name=\"triangle\">त्रिभुज</string>\n    <string name=\"vertices\">शिखर</string>\n    <string name=\"polygon\">बहुभुज</string>\n    <string name=\"polygon_sub\">प्रारंभ बिंदु से अंतिम बिंदु तक बहुभुज बनाता है</string>\n    <string name=\"outlined_polygon\">रेखांकित बहुभुज</string>\n    <string name=\"outlined_polygon_sub\">प्रारंभ बिंदु से अंत बिंदु तक रेखांकित बहुभुज बनाता है</string>\n    <string name=\"draw_regular_polygon_sub\">बहुभुज बनाएं जो मुक्त रूप के बजाय नियमित होगा</string>\n    <string name=\"star_sub\">प्रारंभ बिंदु से अंतिम बिंदु तक तारा खींचता है</string>\n    <string name=\"star\">तारा</string>\n    <string name=\"draw_regular_polygon\">नियमित बहुभुज बनाएं</string>\n    <string name=\"outlined_star\">रेखांकित तारा</string>\n    <string name=\"inner_radius_ratio\">आंतरिक त्रिज्या अनुपात</string>\n    <string name=\"outlined_star_sub\">प्रारंभ बिंदु से अंतिम बिंदु तक रेखांकित तारा बनाता है</string>\n    <string name=\"draw_regular_star\">नियमित तारा बनाएं</string>\n    <string name=\"draw_regular_star_sub\">तारा बनाएं जो मुक्त रूप के बजाय नियमित होगा</string>\n    <string name=\"antialias\">एंटीएलियास</string>\n    <string name=\"antialias_sub\">तेज किनारों को रोकने के लिए एंटीएलियासिंग सक्षम करता है</string>\n    <string name=\"open_edit_instead_of_preview\">पूर्वावलोकन के बजाय संपादन खोलें</string>\n    <string name=\"open_edit_instead_of_preview_sub\">जब आप ImageToolbox में खोलने (पूर्वावलोकन) के लिए छवि का चयन करते हैं, तो पूर्वावलोकन के बजाय संपादन चयन पत्रक खोला जायेगा</string>\n    <string name=\"document_scanner\">दस्तावेज़ स्कैनर</string>\n    <string name=\"save_as_pdf\">PDF के रूप में सहेजें</string>\n    <string name=\"document_scanner_sub\">दस्तावेज़ों को स्कैन करें और उनसे PDF बनाएं या चित्र अलग करें</string>\n    <string name=\"click_to_start_scanning\">स्कैनिंग शुरू करने के लिए क्लिक करें</string>\n    <string name=\"start_scanning\">स्कैनिंग शुरू करें</string>\n    <string name=\"share_as_pdf\">PDF के रूप में साझा करें</string>\n    <string name=\"options_below_is_for_images\">नीचे दिया गया विकल्प छवियों को सहेजने के लिए है, PDF के लिए नहीं</string>\n    <string name=\"equalize_histogram_hsv\">हिस्टोग्राम को समान करें HSV</string>\n    <string name=\"equalize_histogram\">हिस्टोग्राम को समान करें</string>\n    <string name=\"enter_percentage\">प्रतिशत दर्ज करें</string>\n    <string name=\"allow_enter_by_text_field\">पाठ क्षेत्र द्वारा प्रवेश की अनुमति दें</string>\n    <string name=\"allow_enter_by_text_field_sub\">पूर्व निर्धारित चयन के पीछे पाठ क्षेत्र को तुरंत दर्ज करने के लिए सक्षम करता है</string>\n    <string name=\"scale_color_space\">कलर स्पेस को स्केल करें</string>\n    <string name=\"linear\">रेखीय</string>\n    <string name=\"equalize_histogram_pixelation\">हिस्टोग्राम पिक्सलेशन को समान करें</string>\n    <string name=\"grid_size_x\">ग्रिड आकार X</string>\n    <string name=\"grid_size_y\">ग्रिड आकार Y</string>\n    <string name=\"equalize_histogram_adaptive\">हिस्टोग्राम अनुकूली को समान करें</string>\n    <string name=\"equalize_histogram_adaptive_luv\">हिस्टोग्राम अनुकूली को समान करें LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">हिस्टोग्राम अनुकूली को समान करें LAB</string>\n    <string name=\"clahe\">क्लैहे</string>\n    <string name=\"clahe_lab\">क्लैहे LAB</string>\n    <string name=\"clahe_luv\">क्लैहे LUV</string>\n    <string name=\"crop_to_content\">सामग्री के अनुसार काटें</string>\n    <string name=\"frame_color\">फ्रेम का रंग</string>\n    <string name=\"color_to_ignore\">नज़रअंदाज़ करने के लिए रंग</string>\n    <string name=\"scan_qr_code\">QR कोड स्कैन करें</string>\n    <string name=\"opened_file_have_no_filter_template\">चयनित फाइल में कोई फिल्टर खाका डेटा नहीं है</string>\n    <string name=\"create_template\">खाका बनाएं</string>\n    <string name=\"template_name\">खाका नाम</string>\n    <string name=\"select_template_preview\">इस फिल्टर खाके का पूर्वावलोकन करने के लिए इस छवि का उपयोग किया जाएगा</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">स्कैन किया गया QR कोड मान्य फिल्टर खाका नहीं है</string>\n    <string name=\"template_filter\">खाका फिल्टर</string>\n    <string name=\"as_qr_code\">QR कोड छवि के रूप में</string>\n    <string name=\"as_file\">फाइल के रूप में</string>\n    <string name=\"save_as_file\">फाइल के रूप में सहेजें</string>\n    <string name=\"save_as_qr_code_image\">QR कोड छवि के रूप में सहेजें</string>\n    <string name=\"delete_template\">टेम्प्लेट मिटाएं</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" नाम के साथ फिल्टर खाका जोड़ा गया (%2$s)</string>\n    <string name=\"filter_preview\">फिल्टर पूर्वावलोकन</string>\n    <string name=\"qr_code\">QR कोड</string>\n    <string name=\"qr_code_sub\">QR कोड को स्कैन करें और उसकी सामग्री प्राप्त करें या नया कोड बनाने के लिए अपनी स्ट्रिंग पेस्ट करें</string>\n    <string name=\"code_content\">कोड सामग्री</string>\n    <string name=\"scan_qr_code_to_replace_content\">क्षेत्र में सामग्री को बदलने के लिए QR कोड को स्कैन करें, या नया QR कोड उत्पन्न करने के लिए कुछ टाइप करें</string>\n    <string name=\"qr_description\">QR विवरण</string>\n    <string name=\"template\">खाका</string>\n    <string name=\"no_template_filters\">कोई खाका फिल्टर नहीं जोड़ा गया</string>\n    <string name=\"create_new\">नया बनाएं</string>\n    <string name=\"delete_template_warn\">आप चयनित खाका फिल्टर को मिटाने वाले हैं। यह कार्रवाई पूर्ववत नहीं की जा सकती</string>\n    <string name=\"min\">न्यून</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR कोड स्कैन करने के लिए सेटिंग्स में कैमरे की अनुमति दें</string>\n    <string name=\"color_blind_scheme\">कलर ब्लाइंड योजना</string>\n    <string name=\"color_blind_scheme_sub\">दिए गए रंग अंधापन प्रकार के लिए थीम रंगों को अनुकूलित करने के लिए मोड का चयन करें</string>\n    <string name=\"protanomaly_sub\">लाल और हरे रंग के बीच अंतर करने में कठिनाई</string>\n    <string name=\"deuteranomaly_sub\">हरे और लाल रंग के बीच अंतर करने में कठिनाई</string>\n    <string name=\"deuteranopia_sub\">हरे रंग को समझने में असमर्थता</string>\n    <string name=\"tritanopia_sub\">नीले रंग को समझने में असमर्थता</string>\n    <string name=\"not_use_color_blind_scheme_sub\">रंग बिल्कुल वैसे ही होंगे जैसे थीम में सेट किए गए हैं</string>\n    <string name=\"sigmoidal\">सिग्मोयडल</string>\n    <string name=\"lagrange_2\">लैग्रेंज 2</string>\n    <string name=\"lagrange_2_sub\">क्रम 2 का एक लैग्रेंज इंटरपोलेशन फ़िल्टर, जो सुचारू संक्रमण के साथ उच्च-गुणवत्ता वाली छवि स्केलिंग के लिए उपयुक्त है</string>\n    <string name=\"lagrange_3\">लैग्रेंज 3</string>\n    <string name=\"lanczos_6\">लांक्ज़ोस 6</string>\n    <string name=\"lanczos_6_jinc\">लांक्ज़ोस 6 जिंक</string>\n    <string name=\"cubic\">घन</string>\n    <string name=\"bspline\">बी-स्पलाइन</string>\n    <string name=\"ewa_hanning\">हैंनिंग EWA</string>\n    <string name=\"ewa_robidoux_sub\">उच्च गुणवत्ता वाले पुनः नमूनाकरण के लिए रॉबिडौक्स फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_blackman\">ब्लैकमैन EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">कम एलियासिंग के साथ उच्च गुणवत्ता वाले रीसैंपलिंग के लिए लैंक्ज़ोस 3 जिंक फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ginseng\">जिनसेंग</string>\n    <string name=\"ewa_ginseng\">जिनसेंग EWA</string>\n    <string name=\"ewa_lanczos_sharp\">लैंक्ज़ोस शार्प EWA</string>\n    <string name=\"haasn_soft\">हसन सॉफ्ट</string>\n    <string name=\"dismiss_forever\">हमेशा के लिए खारिज करें</string>\n    <string name=\"hamming\">हैमिंग</string>\n    <string name=\"hanning\">हैनिंग</string>\n    <string name=\"blackman\">ब्लैकमैन</string>\n    <string name=\"welch\">वेल्च</string>\n    <string name=\"quadric\">द्विघात</string>\n    <string name=\"gaussian\">गॉसियन</string>\n    <string name=\"sphinx\">स्फिंक्स</string>\n    <string name=\"bartlett\">बार्टलेट</string>\n    <string name=\"robidoux\">रॉबिडौक्स</string>\n    <string name=\"robidoux_sharp\">रॉबिडौक्स शार्प</string>\n    <string name=\"spline16\">स्प्लाइन 16</string>\n    <string name=\"spline36\">स्प्लाइन 36</string>\n    <string name=\"spline64\">स्प्लाइन 64</string>\n    <string name=\"kaiser\">केईसर</string>\n    <string name=\"bartlett_hann\">बार्टलेट-हैन</string>\n    <string name=\"box\">बॉक्स</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">लांक्ज़ोस 2</string>\n    <string name=\"lanczos3\">लांक्ज़ोस 3</string>\n    <string name=\"lanczos4\">लांक्ज़ोस 4</string>\n    <string name=\"lanczos2_jinc\">लांक्ज़ोस 2 जिंक</string>\n    <string name=\"lanczos3_jinc\">लांक्ज़ोस 3 जिंक</string>\n    <string name=\"lanczos4_jinc\">लांक्ज़ोस 4 जिंक</string>\n    <string name=\"bspline_sub\">Utilizes piecewise-defined polynomial functions to smoothly interpolate and approximate a curve or surface, flexible and continuous shape representation</string>\n    <string name=\"cubic_sub\">क्यूबिक इंटरपोलेशन निकटतम 16 पिक्सल पर विचार करके चिकनी स्केलिंग प्रदान करता है, जो द्विरेखीय इंटरपोलेशन की तुलना में बेहतर परिणाम देता है।</string>\n    <string name=\"hanning_sub\">हैन विंडो का एक प्रकार, जिसका उपयोग आमतौर पर सिग्नल प्रोसेसिंग अनुप्रयोगों में स्पेक्ट्रल लीकेज को कम करने के लिए किया जाता है</string>\n    <string name=\"hamming_sub\">सिग्नल के किनारों को पतला करके स्पेक्ट्रल लीकेज को कम करने के लिए उपयोग किया जाने वाला एक विंडो फ़ंक्शन, सिग्नल प्रोसेसिंग में उपयोगी</string>\n    <string name=\"blackman_sub\">एक विंडो फ़ंक्शन जो स्पेक्ट्रल रिसाव को न्यूनतम करके अच्छा आवृत्ति रिज़ॉल्यूशन प्रदान करता है, अक्सर सिग्नल प्रोसेसिंग में उपयोग किया जाता है</string>\n    <string name=\"quadric_sub\">एक विधि जो प्रक्षेप के लिए द्विघात फ़ंक्शन का उपयोग करती है, जो सुचारू और निरंतर परिणाम प्रदान करती है</string>\n    <string name=\"gaussian_sub\">एक इंटरपोलेशन विधि जो गॉसियन फ़ंक्शन को लागू करती है, जो छवियों में शोर को कम करने और कम करने के लिए उपयोगी है</string>\n    <string name=\"welch_sub\">एक विंडो फ़ंक्शन जिसे कम स्पेक्ट्रल रिसाव के साथ अच्छा आवृत्ति रिज़ॉल्यूशन देने के लिए डिज़ाइन किया गया है, अक्सर सिग्नल प्रोसेसिंग अनुप्रयोगों में उपयोग किया जाता है</string>\n    <string name=\"sphinx_sub\">एक उन्नत रीसैंपलिंग विधि जो न्यूनतम कलाकृतियों के साथ उच्च गुणवत्ता वाला इंटरपोलेशन प्रदान करती है</string>\n    <string name=\"bartlett_sub\">स्पेक्ट्रल रिसाव को कम करने के लिए सिग्नल प्रोसेसिंग में प्रयुक्त त्रिकोणीय विंडो फ़ंक्शन</string>\n    <string name=\"robidoux_sub\">एक उच्च गुणवत्ता वाली इंटरपोलेशन विधि जो प्राकृतिक छवि आकार बदलने, तीक्ष्णता और चिकनाई को संतुलित करने के लिए अनुकूलित है</string>\n    <string name=\"spline64_sub\">एक स्प्लाइन-आधारित इंटरपोलेशन विधि जो 64-टैप फ़िल्टर का उपयोग करके सुचारू परिणाम प्रदान करती है</string>\n    <string name=\"kaiser_sub\">एक इंटरपोलेशन विधि जो कैसर विंडो का उपयोग करती है, मुख्य-लोब चौड़ाई और साइड-लोब स्तर के बीच व्यापार-बंद पर अच्छा नियंत्रण प्रदान करती है</string>\n    <string name=\"robidoux_sharp_sub\">रॉबिडौक्स विधि का एक अधिक स्पष्ट संस्करण, जो स्पष्ट छवि आकार परिवर्तन के लिए अनुकूलित है</string>\n    <string name=\"spline16_sub\">एक स्प्लाइन-आधारित इंटरपोलेशन विधि जो 16-टैप फ़िल्टर का उपयोग करके सुचारू परिणाम प्रदान करती है</string>\n    <string name=\"spline36_sub\">एक स्प्लाइन-आधारित इंटरपोलेशन विधि जो 36-टैप फ़िल्टर का उपयोग करके सुचारू परिणाम प्रदान करती है</string>\n    <string name=\"bartlett_hann_sub\">बार्टलेट और हन विंडो को मिलाकर एक हाइब्रिड विंडो फ़ंक्शन, जिसका उपयोग सिग्नल प्रोसेसिंग में स्पेक्ट्रल लीकेज को कम करने के लिए किया जाता है</string>\n    <string name=\"box_sub\">एक सरल पुनः नमूनाकरण विधि जो निकटतम पिक्सल मानों के औसत का उपयोग करती है, जिसके परिणामस्वरूप अक्सर एक ब्लॉकनुमा उपस्थिति प्राप्त होती है</string>\n    <string name=\"bohman_sub\">एक विंडो फ़ंक्शन जिसका उपयोग स्पेक्ट्रल रिसाव को कम करने के लिए किया जाता है, जो सिग्नल प्रोसेसिंग अनुप्रयोगों में अच्छा आवृत्ति रिज़ॉल्यूशन प्रदान करता है</string>\n    <string name=\"lanczos2_sub\">एक पुनः नमूनाकरण विधि जो न्यूनतम कलाकृतियों के साथ उच्च गुणवत्ता वाले प्रक्षेप के लिए 2-लोब लैंक्ज़ोस फ़िल्टर का उपयोग करती है</string>\n    <string name=\"lanczos3_sub\">एक पुनः नमूनाकरण विधि जो न्यूनतम कलाकृतियों के साथ उच्च गुणवत्ता वाले प्रक्षेप के लिए 3-लोब लैंक्ज़ोस फ़िल्टर का उपयोग करती है</string>\n    <string name=\"lanczos4_sub\">एक पुनः नमूनाकरण विधि जो न्यूनतम कलाकृतियों के साथ उच्च गुणवत्ता वाले प्रक्षेप के लिए 4-लोब लैंक्ज़ोस फ़िल्टर का उपयोग करती है</string>\n    <string name=\"lanczos3_jinc_sub\">लैंक्ज़ोस 3 फ़िल्टर का एक प्रकार जो जिंक फ़ंक्शन का उपयोग करता है, न्यूनतम कलाकृतियों के साथ उच्च गुणवत्ता वाला इंटरपोलेशन प्रदान करता है</string>\n    <string name=\"lanczos2_jinc_sub\">लैंक्ज़ोस 2 फ़िल्टर का एक प्रकार जो जिंक फ़ंक्शन का उपयोग करता है, न्यूनतम कलाकृतियों के साथ उच्च गुणवत्ता वाला इंटरपोलेशन प्रदान करता है</string>\n    <string name=\"lanczos4_jinc_sub\">लैंक्ज़ोस 4 फ़िल्टर का एक प्रकार जो जिंक फ़ंक्शन का उपयोग करता है, न्यूनतम कलाकृतियों के साथ उच्च गुणवत्ता वाला इंटरपोलेशन प्रदान करता है</string>\n    <string name=\"ewa_robidoux\">रॉबिडौक्स EWA</string>\n    <string name=\"ewa_hanning_sub\">सुचारू अंतर्वेशन और पुनः नमूनाकरण के लिए हैनिंग फिल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_quadric\">क्वाड्रिक EWA</string>\n    <string name=\"ewa_quadric_sub\">सुचारू अंतर्वेशन के लिए क्वाड्रिक फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_blackman_sub\">रिंगिंग आर्टिफैक्ट्स को न्यूनतम करने के लिए ब्लैकमैन फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_robidoux_sharp\">रॉबिडौक्स शार्प EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">अधिक स्पष्ट परिणामों के लिए रॉबिडौक्स शार्प फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_lanczos3_jinc\">लांक्ज़ोस 3 जिंक EWA</string>\n    <string name=\"ginseng_sub\">तीक्ष्णता और सहजता के अच्छे संतुलन के साथ उच्च गुणवत्ता वाली छवि प्रसंस्करण के लिए डिज़ाइन किया गया एक रीसैंपलिंग फ़िल्टर</string>\n    <string name=\"ewa_ginseng_sub\">बेहतर छवि गुणवत्ता के लिए जिनसेंग फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_lanczos_sharp_sub\">न्यूनतम कलाकृतियों के साथ तीक्ष्ण परिणाम प्राप्त करने के लिए लैंक्ज़ोस शार्प फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">अत्यंत तीक्ष्ण छवि पुनः नमूनाकरण के लिए लैंक्ज़ोस 4 शार्पेस्ट फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_lanczos_soft\">लैंक्ज़ोस सॉफ्ट EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">चिकनी छवि पुनः नमूनाकरण के लिए लैंक्ज़ोस सॉफ्ट फ़िल्टर का दीर्घवृत्तीय भारित औसत (EWA) संस्करण</string>\n    <string name=\"ewa_lanczos_4_sharpest\">लांक्ज़ोस 4 शार्पेस्ट EWA</string>\n    <string name=\"haasn_soft_sub\">हासन द्वारा डिजाइन किया गया एक रीसैंपलिंग फिल्टर, जो सहज और आर्टिफैक्ट-मुक्त छवि स्केलिंग के लिए है</string>\n    <string name=\"format_conversion\">प्रारूप रूपांतरण</string>\n    <string name=\"format_conversion_sub\">छवियों के बैच को एक प्रारूप से दूसरे प्रारूप में परिवर्तित करें</string>\n    <string name=\"image_stacking\">छवि स्टैकिंग</string>\n    <string name=\"image_stacking_sub\">चुने हुए मिश्रण मोड के साथ छवियों को एक दूसरे के ऊपर रखें</string>\n    <string name=\"add_image\">छवि जोड़ें</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">इक्वलाइज़ हिस्टोग्राम एडेप्टिव HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">समान हिस्टोग्राम अनुकूली HSV</string>\n    <string name=\"edge_mode\">एज मोड</string>\n    <string name=\"clip\">क्लिप</string>\n    <string name=\"wrap\">लपेटें</string>\n    <string name=\"tritanomaly_sub\">नीले और पीले रंग के बीच अंतर करने में कठिनाई</string>\n    <string name=\"protanopia_sub\">लाल रंग को समझने में असमर्थता</string>\n    <string name=\"achromatomaly_sub\">सभी रंगों के प्रति संवेदनशीलता कम हो गई</string>\n    <string name=\"achromatopsia_sub\">पूर्ण रंग अंधापन, केवल ग्रे रंग ही देख पाना</string>\n    <string name=\"not_use_color_blind_scheme\">कलर ब्लाइंड योजना का उपयोग न करें</string>\n    <string name=\"lanczos_6_sub\">6 के उच्च क्रम वाला लैंक्ज़ोस रीसैंपलिंग फ़िल्टर, जो अधिक स्पष्ट और अधिक सटीक छवि स्केलिंग प्रदान करता है</string>\n    <string name=\"lanczos_6_jinc_sub\">लैंक्ज़ोस 6 फ़िल्टर का एक प्रकार जो बेहतर छवि रीसैंपलिंग गुणवत्ता के लिए जिंक फ़ंक्शन का उपयोग करता है</string>\n    <string name=\"lagrange_3_sub\">ऑर्डर 3 का एक लैग्रेंज इंटरपोलेशन फ़िल्टर, जो छवि स्केलिंग के लिए बेहतर सटीकता और सुचारू परिणाम प्रदान करता है</string>\n    <string name=\"bins_count\">डिब्बों की संख्या</string>\n    <string name=\"clahe_hsl\">क्लेहे HSL</string>\n    <string name=\"clahe_hsv\">क्लेहे HSV</string>\n    <string name=\"linear_box_blur\">रैखिक बॉक्स धुंधलापन</string>\n    <string name=\"linear_tent_blur\">रैखिक तम्बू धुंधलापन</string>\n    <string name=\"linear_gaussian_box_blur\">रैखिक गाऊसी बॉक्स धुंधलापन</string>\n    <string name=\"linear_stack_blur\">रैखिक स्टैक धुंधलापन</string>\n    <string name=\"gaussian_box_blur\">गॉसियन बॉक्स धुंधलापन</string>\n    <string name=\"pick_filter_info\">अपने ड्राइंग में ब्रश के रूप में उपयोग करने के लिए नीचे फ़िल्टर चुनें</string>\n    <string name=\"linear_fast_gaussian_blur_next\">रैखिक तेज़ गाऊसी धुंधलापन अगला</string>\n    <string name=\"linear_fast_gaussian_blur\">रैखिक तेज़ गाऊसी धुंधलापन</string>\n    <string name=\"linear_gaussian_blur\">रैखिक गाऊसी धुंधलापन</string>\n    <string name=\"draw_filter_sub\">पेंट के रूप में उपयोग करने के लिए एक फ़िल्टर चुनें</string>\n    <string name=\"replace_filter\">फ़िल्टर बदलें</string>\n    <string name=\"tiff_compression_scheme\">TIFF संपीड़न योजना</string>\n    <string name=\"low_poly\">निम्न पाली</string>\n    <string name=\"sand_painting\">रेत चित्रकारी</string>\n    <string name=\"image_splitting\">छवि विभाजन</string>\n    <string name=\"image_splitting_sub\">एकल छवि को पंक्तियों या स्तंभों द्वारा विभाजित करें</string>\n    <string name=\"fit_to_bounds_sub\">वांछित व्यवहार (पहलू अनुपात के अनुसार क्रॉप/समुचित) प्राप्त करने के लिए इस पैरामीटर के साथ क्रॉप आकार मोड को संयोजित करें</string>\n    <string name=\"export\">निर्यात</string>\n    <string name=\"position\">स्थान</string>\n    <string name=\"center\">मध्य</string>\n    <string name=\"top_left\">शीर्ष बाएं</string>\n    <string name=\"top_right\">शीर्ष दाएं</string>\n    <string name=\"bottom_left\">नीचे बाएं</string>\n    <string name=\"bottom_right\">नीचे दाएं</string>\n    <string name=\"center_right\">मध्य दायां</string>\n    <string name=\"bottom_center\">निचला केंद्र</string>\n    <string name=\"center_left\">मध्य बायां</string>\n    <string name=\"fit_to_bounds\">सीमा के समुचित</string>\n    <string name=\"languages_imported\">भाषाएं सफलतापूर्वक आयात की गई</string>\n    <string name=\"backup_ocr_models\">OCR मॉडल का बैकअप लें</string>\n    <string name=\"import_word\">आयात</string>\n    <string name=\"top_center\">शीर्ष केंद्र</string>\n    <string name=\"color_poster\">रंगीन पोस्टर</string>\n    <string name=\"target_image\">लक्ष्य छवि</string>\n    <string name=\"palette_transfer\">पैलेट स्थानांतरण</string>\n    <string name=\"enhanced_oil\">उन्नत तेल</string>\n    <string name=\"simple_old_tv\">सरल पुराना टीवी</string>\n    <string name=\"hdr\">एचडीआर</string>\n    <string name=\"gotham\">गोथम</string>\n    <string name=\"simple_sketch\">सरल रेखाचित्र</string>\n    <string name=\"soft_glow\">हल्की चमक</string>\n    <string name=\"tri_tone\">ट्राई टोन</string>\n    <string name=\"third_color\">तीसरा रंग</string>\n    <string name=\"clahe_oklab\">क्लाहे ओकलैब</string>\n    <string name=\"clahe_oklch\">क्लाहे ओकल्छ</string>\n    <string name=\"clahe_jzazbz\">क्लाहे जज्बज़</string>\n    <string name=\"clustered_4x4_dithering\">क्लस्टर्ड 4x4 डिथरिंग</string>\n    <string name=\"clustered_8x8_dithering\">क्लस्टर्ड 8x8 डिथरिंग</string>\n    <string name=\"polka_dot\">पोल्का डॉट</string>\n    <string name=\"clustered_2x2_dithering\">क्लस्टर्ड 2x2 डिथरिंग</string>\n    <string name=\"yililoma_dithering\">यिलिलोमा डिथरिंग</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">डायनामिक रंग चालू होने पर मोनेट का उपयोग नहीं किया जा सकता</string>\n    <string name=\"lut512x512\">512x512 2D एलयूटी</string>\n    <string name=\"target_lut_image\">लक्ष्य एलयूटी छवि</string>\n    <string name=\"amatorka\">अमाटोरका</string>\n    <string name=\"miss_etikate\">मिस एटिकेट</string>\n    <string name=\"soft_elegance\">नरम लालित्य</string>\n    <string name=\"soft_elegance_variant\">नरम लालित्य संस्करण</string>\n    <string name=\"add_favorites\">पसंदीदा जोड़ें</string>\n    <string name=\"no_favorite_options_selected\">कोई पसंदीदा विकल्प चयनित नहीं है, उन्हें टूल पृष्ठ में जोड़ें</string>\n    <string name=\"harmony_complementary\">पूरक</string>\n    <string name=\"harmony_analogous\">अनुरूप</string>\n    <string name=\"harmony_triadic\">त्रियादिक</string>\n    <string name=\"harmony_split_complementary\">विभाजित पूरक</string>\n    <string name=\"harmony_tetradic\">टेट्राडिक</string>\n    <string name=\"harmony_square\">चौकोर</string>\n    <string name=\"harmony_analogous_complementary\">अनुरूप + पूरक</string>\n    <string name=\"color_tools\">रंग उपकरण</string>\n    <string name=\"color_tools_sub\">मिश्रण करें, टोन बनाएं, शेड्स बनाएं और बहुत कुछ</string>\n    <string name=\"color_harmonies\">रंग सामंजस्य</string>\n    <string name=\"color_shading\">रंग छायांकन</string>\n    <string name=\"variation\">भिन्नता</string>\n    <string name=\"tints\">टिंट</string>\n    <string name=\"tones\">टोन</string>\n    <string name=\"shades\">छाया</string>\n    <string name=\"color_mixing\">रंग मिश्रण</string>\n    <string name=\"color_info\">रंग जानकारी</string>\n    <string name=\"selected_color\">चयनित रंग</string>\n    <string name=\"color_to_mix\">मिश्रण करने के लिए रंग</string>\n    <string name=\"candlelight\">मोमबत्ती की रौशनी</string>\n    <string name=\"drop_blues\">ड्रॉप ब्लूज़</string>\n    <string name=\"palette_transfer_variant\">पैलेट ट्रांसफर वैरिएंट</string>\n    <string name=\"target_cube_lut_file\">लक्ष्य 3D एलयूटी फाइल (.cube / .CUBE)</string>\n    <string name=\"cube_lut\">3डी एलयूटी</string>\n    <string name=\"lut\">एलयूटी</string>\n    <string name=\"bleach_bypass\">ब्लीच बाईपास</string>\n    <string name=\"edgy_amber\">एजी एम्बर</string>\n    <string name=\"fall_colors\">पतझड़ के रंग</string>\n    <string name=\"film_stock_50\">फिल्म स्टॉक 50</string>\n    <string name=\"foggy_night\">धूमिल रात</string>\n    <string name=\"kodak\">कोडैक</string>\n    <string name=\"save_empty_lut\">न्यूट्रल LUT छवि प्राप्त करें</string>\n    <string name=\"pop_art\">पॉप आर्ट</string>\n    <string name=\"celluloid\">सेल्यूलाइड</string>\n    <string name=\"coffee\">कॉफी</string>\n    <string name=\"greenish\">हरापन</string>\n    <string name=\"save_empty_lut_sub\">सबसे पहले, न्यूट्रल LUT पर फिल्टर लगाने के लिए अपने पसंदीदा फोटो संपादन एप्लिकेशन का उपयोग करें जिसे आप यहां प्राप्त कर सकते हैं। इसके ठीक से काम करने के लिए प्रत्येक पिक्सल का रंग अन्य पिक्सल पर निर्भर नहीं होना चाहिए (उदाहरण के लिए धुंधलापन काम नहीं करेगा)। एक बार तैयार हो जाने पर, अपनी नई LUT छवि को 512*512 LUT फिल्टर के लिए इनपुट के रूप में उपयोग करें</string>\n    <string name=\"golden_forest\">सुनहरा जंगल</string>\n    <string name=\"retro_yellow\">रेट्रो पीला</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">दस्तावेज़ स्कैनर को स्कैन करने के लिए सेटिंग में कैमरे की अनुमति प्रदान करें</string>\n    <string name=\"links\">लिंक</string>\n    <string name=\"links_preview_sub\">उन स्थानों पर लिंक पूर्वावलोकन पुनर्प्राप्ति सक्षम करता है जहां आप पाठ प्राप्त कर सकते हैं (क्यूआर कोड, ओसीआर आदि)</string>\n    <string name=\"links_preview\">लिंक पूर्वावलोकन</string>\n    <string name=\"ico_size_warning\">ICO फ़ाइलें केवल 256 x 256 के अधिकतम आकार में ही सहेजी जा सकती हैं</string>\n    <string name=\"gif_type_to_webp\">GIF से WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">GIF छवियों को WEBP एनिमेटेड चित्रों में बदलें</string>\n    <string name=\"webp_tools\">वेबपी उपकरण</string>\n    <string name=\"webp_tools_sub\">छवियों को WEBP एनिमेटेड चित्र में बदलें या दिए गए WEBP एनीमेशन से फ़्रेम निकालें</string>\n    <string name=\"webp_type_to_image\">छवियों के लिए WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP फ़ाइल को चित्रों के बैच में कनवर्ट करें</string>\n    <string name=\"webp_type_to_webp_sub\">छवियों के बैच को WEBP फ़ाइल में बदलें</string>\n    <string name=\"webp_type_to_webp\">WEBP के लिए छवियाँ</string>\n    <string name=\"select_webp_image_to_start\">आरंभ करने के लिए WEBP छवि चुनें</string>\n    <string name=\"manage_storage_extra_types\">फ़ाइलों तक पूर्ण पहुंच नहीं</string>\n    <string name=\"manage_storage_extra_types_sub\">JXL, QOI और अन्य छवियों को देखने के लिए सभी फ़ाइलों तक पहुंच की अनुमति दें जिन्हें Android पर छवियों के रूप में मान्यता नहीं दी गई है। अनुमति के बिना इमेज टूलबॉक्स उन छवियों को दिखाने में असमर्थ है</string>\n    <string name=\"default_draw_color\">डिफ़ॉल्ट ड्रा रंग</string>\n    <string name=\"default_draw_path_mode\">डिफ़ॉल्ट ड्रा पथ मोड</string>\n    <string name=\"add_timestamp\">टाइमस्टैम्प जोड़ें</string>\n    <string name=\"add_timestamp_sub\">टाइमस्टैम्प को आउटपुट फ़ाइल नाम में जोड़ने में सक्षम बनाता है</string>\n    <string name=\"formatted_timestamp\">स्वरूपित टाइमस्टैम्प</string>\n    <string name=\"formatted_timestamp_sub\">मूल मिलिस के बजाय आउटपुट फ़ाइल नाम में टाइमस्टैम्प फ़ॉर्मेटिंग सक्षम करें</string>\n    <string name=\"enable_timestamps_to_format_them\">टाइमस्टैम्प को उनके प्रारूप का चयन करने के लिए सक्षम करें</string>\n    <string name=\"one_time_save_location\">वन टाइम सेव लोकेशन</string>\n    <string name=\"one_time_save_location_sub\">एक बार सहेजे गए स्थानों को देखें और संपादित करें जिनका उपयोग आप अधिकतर सभी विकल्पों में सेव बटन को लंबे समय तक दबाकर कर सकते हैं</string>\n    <string name=\"recently_used\">हाल ही में प्रयुक्त</string>\n    <string name=\"ci_channel\">सीआई चैनल</string>\n    <string name=\"group\">समूह</string>\n    <string name=\"image_toolbox_in_telegram\">टेलीग्राम में इमेज टूलबॉक्स 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">हमारी चैट में शामिल हों जहां आप अपनी इच्छानुसार किसी भी चीज़ पर चर्चा कर सकते हैं और सीआई चैनल भी देख सकते हैं जहां मैं बीटा और घोषणाएं पोस्ट करता हूं</string>\n    <string name=\"ci_channel_sub\">ऐप के नए संस्करणों के बारे में सूचना प्राप्त करें और घोषणाएँ पढ़ें</string>\n    <string name=\"fit_description\">किसी छवि को दिए गए आयामों में फ़िट करें और पृष्ठभूमि पर धुंधलापन या रंग लागू करें</string>\n    <string name=\"tools_arrangement\">उपकरण व्यवस्था</string>\n    <string name=\"group_tools_by_type\">प्रकार के आधार पर उपकरण समूहित करें</string>\n    <string name=\"group_tools_by_type_sub\">कस्टम सूची व्यवस्था के बजाय मुख्य स्क्रीन पर टूल को उनके प्रकार के आधार पर समूहित करें</string>\n    <string name=\"default_values\">डिफॉल्ट मान</string>\n    <string name=\"system_bars_visibility\">सिस्टम बार्स दृश्यता</string>\n    <string name=\"show_system_bars_by_swipe\">स्वाइप द्वारा सिस्टम बार दिखाएँ</string>\n    <string name=\"show_system_bars_by_swipe_sub\">यदि सिस्टम बार छिपे हुए हैं तो उन्हें दिखाने के लिए स्वाइप करने में सक्षम बनाता है</string>\n    <string name=\"auto\">ऑटो</string>\n    <string name=\"hide_all\">सभी को छिपाएं</string>\n    <string name=\"show_all\">सब दिखाएं</string>\n    <string name=\"hide_nav_bar\">नेव बार छिपाएँ</string>\n    <string name=\"hide_status_bar\">स्थिति पट्टी छुपाएँ</string>\n    <string name=\"noise_generation\">शोर उत्पन्न करना</string>\n    <string name=\"noise_generation_sub\">पेर्लिन या अन्य प्रकार जैसे विभिन्न शोर उत्पन्न करें</string>\n    <string name=\"frequency\">आवृत्ति</string>\n    <string name=\"noise_type\">शोर का प्रकार</string>\n    <string name=\"rotation_type\">घूर्णन प्रकार</string>\n    <string name=\"fractal_type\">भग्न प्रकार</string>\n    <string name=\"octaves\">अष्टक</string>\n    <string name=\"lacunarity\">कमी</string>\n    <string name=\"gain\">पाना</string>\n    <string name=\"weighted_strength\">भारित ताकत</string>\n    <string name=\"ping_pong_strength\">पिंग पोंग ताकत</string>\n    <string name=\"distance_function\">दूरी समारोह</string>\n    <string name=\"return_type\">वापसी प्रकार</string>\n    <string name=\"jitter\">घबराना</string>\n    <string name=\"domain_warp\">डोमेन ताना</string>\n    <string name=\"alignment\">संरेखण</string>\n    <string name=\"custom_filename\">कस्टम फ़ाइल नाम</string>\n    <string name=\"custom_filename_sub\">स्थान और फ़ाइल नाम का चयन करें जिसका उपयोग वर्तमान छवि को सहेजने के लिए किया जाएगा</string>\n    <string name=\"saved_to_custom\">कस्टम नाम वाले फ़ोल्डर में सहेजा गया</string>\n    <string name=\"collage_maker\">समुच्चित चित्रकला का निर्माता</string>\n    <string name=\"collage_maker_sub\">अधिकतम 20 छवियों से कोलाज बनाएं</string>\n    <string name=\"collage_type\">कोलाज प्रकार</string>\n    <string name=\"collages_info\">स्थिति को समायोजित करने के लिए छवि को स्वैप करने, स्थानांतरित करने और ज़ूम करने के लिए दबाए रखें</string>\n    <string name=\"disable_rotation\">रोटेशन अक्षम करें</string>\n    <string name=\"disable_rotation_sub\">दो-उंगली के इशारों से छवियों को घूमने से रोकता है</string>\n    <string name=\"enable_snapping_to_borders\">सीमाओं पर स्नैपिंग सक्षम करें</string>\n    <string name=\"enable_snapping_to_borders_sub\">मूव करने या ज़ूम करने के बाद, छवियाँ फ़्रेम के किनारों को भरने के लिए स्नैप हो जाएंगी</string>\n    <string name=\"histogram\">हिस्टोग्राम</string>\n    <string name=\"histogram_sub\">समायोजन करने में आपकी सहायता के लिए आरजीबी या चमक छवि हिस्टोग्राम</string>\n    <string name=\"image_for_histogram\">इस छवि का उपयोग आरजीबी और ब्राइटनेस हिस्टोग्राम उत्पन्न करने के लिए किया जाएगा</string>\n    <string name=\"tesseract_options\">टेसेरैक्ट विकल्प</string>\n    <string name=\"tesseract_options_sub\">टेसेरैक्ट इंजन के लिए कुछ इनपुट वेरिएबल लागू करें</string>\n    <string name=\"custom_options\">कस्टम विकल्प</string>\n    <string name=\"custom_params_info\">विकल्प इस पैटर्न का अनुसरण करते हुए दर्ज किए जाने चाहिए: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">ऑटो क्रॉप</string>\n    <string name=\"free_corners\">निःशुल्क कोने</string>\n    <string name=\"free_corners_sub\">छवि को बहुभुज द्वारा काटें, इससे परिप्रेक्ष्य भी सही हो जाता है</string>\n    <string name=\"coerce_points_to_image_bounds\">ज़बरदस्ती छवि सीमा की ओर इशारा करती है</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">अंक छवि सीमाओं द्वारा सीमित नहीं होंगे, यह अधिक सटीक परिप्रेक्ष्य सुधार के लिए उपयोगी है</string>\n    <string name=\"mask\">नकाब</string>\n    <string name=\"spot_heal_sub\">सामग्री जागरूक तैयार पथ के अंतर्गत भरें</string>\n    <string name=\"spot_heal\">ठीक स्थान</string>\n    <string name=\"use_circle_kernel\">सर्किल कर्नेल का प्रयोग करें</string>\n    <string name=\"opening\">प्रारंभिक</string>\n    <string name=\"closing\">समापन</string>\n    <string name=\"morphological_gradient\">रूपात्मक ढाल</string>\n    <string name=\"top_hat\">लंबा टोप</string>\n    <string name=\"black_hat\">बुरा व्यक्ति</string>\n    <string name=\"tone_curves\">स्वर वक्र</string>\n    <string name=\"reset_curves\">वक्र रीसेट करें</string>\n    <string name=\"reset_curves_sub\">कर्व्स को डिफ़ॉल्ट मान पर वापस ले जाया जाएगा</string>\n    <string name=\"line_style\">रेखा शैली</string>\n    <string name=\"gap_size\">अंतराल का आकार</string>\n    <string name=\"dashed\">धराशायी</string>\n    <string name=\"dot_dashed\">डॉट धराशायी</string>\n    <string name=\"stamped\">स्टाम्प</string>\n    <string name=\"zigzag\">वक्र</string>\n    <string name=\"dashed_sub\">निर्दिष्ट अंतराल आकार के साथ खींचे गए पथ पर धराशायी रेखा खींचता है</string>\n    <string name=\"dot_dashed_sub\">दिए गए पथ पर बिंदु और धराशायी रेखा खींचता है</string>\n    <string name=\"defaultt_sub\">बस डिफ़ॉल्ट सीधी रेखाएँ</string>\n    <string name=\"stamped_sub\">निर्दिष्ट रिक्त स्थान के साथ पथ के साथ चयनित आकृतियाँ बनाता है</string>\n    <string name=\"zigzag_sub\">पथ पर लहरदार टेढ़े-मेढ़े निशान बनाता है</string>\n    <string name=\"zigzag_ratio\">ज़िगज़ैग अनुपात</string>\n    <string name=\"create_shortcut\">शॉर्टकट बनाएं</string>\n    <string name=\"create_shortcut_title\">पिन करने के लिए टूल चुनें</string>\n    <string name=\"create_shortcut_subtitle\">टूल आपके लॉन्चर की होम स्क्रीन पर शॉर्टकट के रूप में जोड़ा जाएगा, आवश्यक व्यवहार प्राप्त करने के लिए इसे \\\"फ़ाइल चुनना छोड़ें\\\" सेटिंग के साथ संयोजन करके उपयोग करें</string>\n    <string name=\"dont_stack_frames\">फ़्रेमों का ढेर न लगाएं</string>\n    <string name=\"dont_stack_frames_sub\">पिछले फ़्रेमों का निपटान सक्षम बनाता है, ताकि वे एक-दूसरे पर ढेर न हों</string>\n    <string name=\"crossfade\">क्रॉसफ़ेड</string>\n    <string name=\"crossfade_sub\">फ़्रेम एक-दूसरे में क्रॉसफ़ेड किए जाएंगे</string>\n    <string name=\"crossfade_count\">क्रॉसफ़ेड फ़्रेम गिनती</string>\n    <string name=\"threshold_one\">दहलीज एक</string>\n    <string name=\"threshold_two\">दहलीज दो</string>\n    <string name=\"canny\">चालाक</string>\n    <string name=\"mirror_101\">दर्पण 101</string>\n    <string name=\"enhanced_zoom_blur\">उन्नत ज़ूम ब्लर</string>\n    <string name=\"laplacian_simple\">लाप्लासियन सरल</string>\n    <string name=\"sobel_simple\">सोबेल सिंपल</string>\n    <string name=\"helper_grid\">सहायक ग्रिड</string>\n    <string name=\"helper_grid_sub\">सटीक जोड़-तोड़ में मदद के लिए ड्राइंग क्षेत्र के ऊपर सहायक ग्रिड दिखाता है</string>\n    <string name=\"grid_color\">ग्रिड का रंग</string>\n    <string name=\"cell_width\">सेल चौड़ाई</string>\n    <string name=\"cell_height\">सेल की ऊंचाई</string>\n    <string name=\"compact_selectors\">कॉम्पैक्ट चयनकर्ता</string>\n    <string name=\"compact_selectors_sub\">कुछ चयन नियंत्रण कम जगह लेने के लिए कॉम्पैक्ट लेआउट का उपयोग करेंगे</string>\n    <string name=\"grant_camera_permission_to_capture_image\">छवि कैप्चर करने के लिए सेटिंग्स में कैमरे की अनुमति दें</string>\n    <string name=\"layout\">लेआउट</string>\n    <string name=\"main_screen_title\">मुख्य स्क्रीन शीर्षक</string>\n    <string name=\"constant_rate_factor\">स्थिर दर कारक (सीआरएफ)</string>\n    <string name=\"crf_sub\">%1$s का मान धीमी गति से संपीड़न का मतलब है, जिसके परिणामस्वरूप फ़ाइल का आकार अपेक्षाकृत छोटा होता है। %2$s का अर्थ है तेज़ संपीड़न, जिसके परिणामस्वरूप एक बड़ी फ़ाइल बनती है।</string>\n    <string name=\"lut_library\">लुट लाइब्रेरी</string>\n    <string name=\"lut_library_sub\">LUTs का संग्रह डाउनलोड करें, जिसे डाउनलोड करने के बाद आप आवेदन कर सकते हैं</string>\n    <string name=\"lut_library_update_sub\">LUTs का अद्यतन संग्रह (केवल नए कतारबद्ध होंगे), जिसे आप डाउनलोड करने के बाद लागू कर सकते हैं</string>\n    <string name=\"filter_preview_image_sub\">फ़िल्टर के लिए डिफ़ॉल्ट छवि पूर्वावलोकन बदलें</string>\n    <string name=\"filter_preview_image\">छवि का पूर्वावलोकन करें</string>\n    <string name=\"hide\">छिपाना</string>\n    <string name=\"show\">दिखाओ</string>\n    <string name=\"slider_type\">स्लाइडर प्रकार</string>\n    <string name=\"fancy\">कल्पना</string>\n    <string name=\"material_2\">सामग्री 2</string>\n    <string name=\"fancy_sub\">एक आकर्षक दिखने वाला स्लाइडर. यह डिफॉल्ट विकल्प है</string>\n    <string name=\"material_2_sub\">एक सामग्री 2 स्लाइडर</string>\n    <string name=\"material_you_slider_sub\">एक मटेरियल यू स्लाइडर</string>\n    <string name=\"apply\">आवेदन करना</string>\n    <string name=\"center_align_dialog_buttons\">केंद्र संवाद बटन</string>\n    <string name=\"center_align_dialog_buttons_sub\">यदि संभव हो तो संवादों के बटन बाईं ओर के बजाय केंद्र में स्थित होंगे</string>\n    <string name=\"open_source_licenses\">ओपन सोर्स लाइसेंस</string>\n    <string name=\"open_source_licenses_sub\">इस ऐप में प्रयुक्त ओपन सोर्स लाइब्रेरीज़ के लाइसेंस देखें</string>\n    <string name=\"area\">क्षेत्र</string>\n    <string name=\"area_sub\">पिक्सेल क्षेत्र संबंध का उपयोग करके पुन: नमूनाकरण। यह छवि विच्छेदन के लिए एक पसंदीदा तरीका हो सकता है, क्योंकि यह मौयर-मुक्त परिणाम देता है। लेकिन जब छवि ज़ूम की जाती है, तो यह \\\"निकटतम\\\" विधि के समान होती है।</string>\n    <string name=\"enable_tonemapping\">टोनमैपिंग सक्षम करें</string>\n    <string name=\"enter_percent\">प्रवेश करना %</string>\n    <string name=\"unknown_host\">साइट तक नहीं पहुंच सकते, वीपीएन का उपयोग करने का प्रयास करें या जांचें कि यूआरएल सही है या नहीं</string>\n    <string name=\"markup_layers\">मार्कअप परतें</string>\n    <string name=\"markup_layers_sub\">छवियों, पाठ और बहुत कुछ को स्वतंत्र रूप से रखने की क्षमता के साथ परत मोड</string>\n    <string name=\"edit_layer\">परत संपादित करें</string>\n    <string name=\"layers_on_image\">छवि पर परतें</string>\n    <string name=\"layers_on_image_sub\">पृष्ठभूमि के रूप में एक छवि का उपयोग करें और उसके ऊपर विभिन्न परतें जोड़ें</string>\n    <string name=\"layers_on_background\">पृष्ठभूमि पर परतें</string>\n    <string name=\"layers_on_background_sub\">पहले विकल्प के समान लेकिन छवि के बजाय रंग के साथ</string>\n    <string name=\"beta\">बीटा</string>\n    <string name=\"fast_settings_side\">फास्ट सेटिंग्स साइड</string>\n    <string name=\"fast_settings_side_sub\">छवियों को संपादित करते समय चयनित पक्ष में एक फ्लोटिंग स्ट्रिप जोड़ें, जिस पर क्लिक करने पर तेज़ सेटिंग्स खुल जाएंगी</string>\n    <string name=\"clear_selection\">स्पष्ट चयन</string>\n    <string name=\"settings_group_visibility_hidden\">सेटिंग समूह \\\"%1$s\\\" डिफ़ॉल्ट रूप से संक्षिप्त हो जाएगा</string>\n    <string name=\"settings_group_visibility_visible\">सेटिंग समूह \\\"%1$s\\\" को डिफ़ॉल्ट रूप से विस्तारित किया जाएगा</string>\n    <string name=\"base_64_tools\">बेस64 उपकरण</string>\n    <string name=\"base_64_tools_sub\">बेस64 स्ट्रिंग को छवि में डीकोड करें, या छवि को बेस64 प्रारूप में एनकोड करें</string>\n    <string name=\"base_64\">बेस 64</string>\n    <string name=\"not_a_valid_base_64\">प्रदत्त मान वैध बेस64 स्ट्रिंग नहीं है</string>\n    <string name=\"copy_not_a_valid_base_64\">खाली या अमान्य बेस64 स्ट्रिंग की प्रतिलिपि नहीं बनाई जा सकती</string>\n    <string name=\"paste_base_64\">बेस64 चिपकाएँ</string>\n    <string name=\"copy_base_64\">बेस64 कॉपी करें</string>\n    <string name=\"base_64_tips\">बेस64 स्ट्रिंग को कॉपी या सहेजने के लिए छवि लोड करें। यदि आपके पास स्ट्रिंग ही है, तो आप छवि प्राप्त करने के लिए इसे ऊपर चिपका सकते हैं</string>\n    <string name=\"save_base_64\">बेस64 सहेजें</string>\n    <string name=\"share_base_64\">बेस64 साझा करें</string>\n    <string name=\"options\">विकल्प</string>\n    <string name=\"actions\">कार्रवाई</string>\n    <string name=\"import_base_64\">बेस64 आयात करें</string>\n    <string name=\"base_64_actions\">बेस64 क्रियाएँ</string>\n    <string name=\"add_outline\">रूपरेखा जोड़ें</string>\n    <string name=\"add_outline_sub\">निर्दिष्ट रंग और चौड़ाई के साथ पाठ के चारों ओर रूपरेखा जोड़ें</string>\n    <string name=\"outline_color\">रूपरेखा रंग</string>\n    <string name=\"outline_size\">रूपरेखा का आकार</string>\n    <string name=\"rotation\">ROTATION</string>\n    <string name=\"checksum_as_filename\">फ़ाइलनाम के रूप में चेकसम</string>\n    <string name=\"checksum_as_filename_sub\">आउटपुट छवियों का नाम उनके डेटा चेकसम के अनुरूप होगा</string>\n    <string name=\"free_software_partner\">मुफ़्त सॉफ़्टवेयर (साझेदार)</string>\n    <string name=\"free_software_partner_sub\">एंड्रॉइड एप्लिकेशन के पार्टनर चैनल में अधिक उपयोगी सॉफ़्टवेयर</string>\n    <string name=\"algorithms\">एल्गोरिदम</string>\n    <string name=\"checksum_tools\">चेकसम उपकरण</string>\n    <string name=\"checksum_tools_sub\">चेकसम की तुलना करें, हैश की गणना करें या विभिन्न हैशिंग एल्गोरिदम का उपयोग करके फ़ाइलों से हेक्स स्ट्रिंग बनाएं</string>\n    <string name=\"calculate\">गणना</string>\n    <string name=\"text_hash\">टेक्स्ट हैश</string>\n    <string name=\"checksum\">अंततः,</string>\n    <string name=\"pick_file_to_checksum\">चयनित एल्गोरिदम के आधार पर इसके चेकसम की गणना करने के लिए फ़ाइल चुनें</string>\n    <string name=\"enter_text_to_checksum\">चयनित एल्गोरिदम के आधार पर इसके चेकसम की गणना करने के लिए टेक्स्ट दर्ज करें</string>\n    <string name=\"source_checksum\">स्रोत चेकसम</string>\n    <string name=\"checksum_to_compare\">तुलना करने के लिए चेकसम</string>\n    <string name=\"match\">मिलान!</string>\n    <string name=\"difference\">अंतर</string>\n    <string name=\"match_sub\">चेकसम बराबर हैं, यह सुरक्षित हो सकता है</string>\n    <string name=\"difference_sub\">चेकसम बराबर नहीं हैं, फ़ाइल असुरक्षित हो सकती है!</string>\n    <string name=\"mesh_gradients\">मेष ग्रेडिएंट्स</string>\n    <string name=\"collection_mesh_gradients_sub\">मेश ग्रेजुएट्स का ऑनलाइन संग्रह देखें</string>\n    <string name=\"wrong_font\">केवल टीटीएफ और ओटीएफ फ़ॉन्ट ही आयात किए जा सकते हैं</string>\n    <string name=\"import_font\">फ़ॉन्ट आयात करें (TTF/OTF)</string>\n    <string name=\"export_fonts\">फ़ॉन्ट निर्यात करें</string>\n    <string name=\"imported_fonts\">आयातित फ़ॉन्ट</string>\n    <string name=\"error_while_saving\">प्रयास सहेजते समय त्रुटि, आउटपुट फ़ोल्डर बदलने का प्रयास करें</string>\n    <string name=\"filename_is_not_set\">फ़ाइल नाम सेट नहीं है</string>\n    <string name=\"none\">कोई नहीं</string>\n    <string name=\"custom_pages\">कस्टम पेज</string>\n    <string name=\"pages_selection\">पेज चयन</string>\n    <string name=\"tool_exit_confirmation\">टूल निकास पुष्टिकरण</string>\n    <string name=\"tool_exit_confirmation_sub\">यदि आपके पास विशेष टूल का उपयोग करते समय सहेजे नहीं गए परिवर्तन हैं और इसे बंद करने का प्रयास करते हैं, तो पुष्टि संवाद दिखाया जाएगा</string>\n    <string name=\"edit_exif_screen\">EXIF संपादित करें</string>\n    <string name=\"edit_exif_screen_sub\">पुनर्संपीड़न के बिना एकल छवि का मेटाडेटा बदलें</string>\n    <string name=\"edit_exif_tag\">उपलब्ध टैग संपादित करने के लिए टैप करें</string>\n    <string name=\"change_sticker\">स्टीकर बदलें</string>\n    <string name=\"fit_width\">फ़िट चौड़ाई</string>\n    <string name=\"fit_height\">फ़िट ऊंचाई</string>\n    <string name=\"batch_compare\">बैच तुलना</string>\n    <string name=\"pick_files_to_checksum\">चयनित एल्गोरिदम के आधार पर इसके चेकसम की गणना करने के लिए फ़ाइल/फ़ाइलें चुनें</string>\n    <string name=\"pick_files\">फ़ाइलें चुनें</string>\n    <string name=\"pick_directory\">निर्देशिका चुनें</string>\n    <string name=\"head_length_scale\">सिर की लंबाई का पैमाना</string>\n    <string name=\"stamp\">टिकट</string>\n    <string name=\"timestamp\">समय-चिह्न</string>\n    <string name=\"format_pattern\">प्रारूप पैटर्न</string>\n    <string name=\"padding\">पैडिंग</string>\n    <string name=\"image_cutting\">छवि काटना</string>\n    <string name=\"image_cutting_sub\">छवि वाले भाग को काटें और बाएँ भाग को ऊर्ध्वाधर या क्षैतिज रेखाओं द्वारा मर्ज करें (उलटा भी हो सकता है)।</string>\n    <string name=\"vertical_pivot_line\">लंबवत धुरी रेखा</string>\n    <string name=\"horizontal_pivot_line\">क्षैतिज धुरी रेखा</string>\n    <string name=\"inverse_selection\">उलटा चयन</string>\n    <string name=\"inverse_vertical_selection_sub\">कटे हुए क्षेत्र के आसपास के हिस्सों को मिलाने के बजाय, लंबवत कटे हुए हिस्से को छोड़ दिया जाएगा</string>\n    <string name=\"inverse_horizontal_selection_sub\">कटे हुए क्षेत्र के चारों ओर के हिस्सों को मिलाने के बजाय, क्षैतिज कटे हुए हिस्से को छोड़ दिया जाएगा</string>\n    <string name=\"collection_mesh_gradients\">मेष ग्रेडिएंट्स का संग्रह</string>\n    <string name=\"mesh_gradients_sub\">गांठों और रिज़ॉल्यूशन की कस्टम मात्रा के साथ जाल ढाल बनाएं</string>\n    <string name=\"gradient_maker_type_image_mesh\">मेष ग्रेडिएंट ओवरले</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">दी गई छवियों के शीर्ष की जालीदार ढाल लिखें</string>\n    <string name=\"points_customization\">अंक अनुकूलन</string>\n    <string name=\"grid_size\">ग्रिड का आकार</string>\n    <string name=\"resolution_x\">संकल्प एक्स</string>\n    <string name=\"resolution_y\">संकल्प वाई</string>\n    <string name=\"resolution\">संकल्प</string>\n    <string name=\"pixel_by_pixel\">पिक्सेल दर पिक्सेल</string>\n    <string name=\"highlight_color\">रंग हाइलाइट करें</string>\n    <string name=\"pixel_comparison_type\">पिक्सेल तुलना प्रकार</string>\n    <string name=\"scan_barcode\">बारकोड स्कैन करें</string>\n    <string name=\"height_ratio\">ऊंचाई अनुपात</string>\n    <string name=\"barcode_type\">बारकोड प्रकार</string>\n    <string name=\"enforce_bw\">बी/डब्ल्यू लागू करें</string>\n    <string name=\"enforce_bw_sub\">बारकोड छवि पूरी तरह से काली और सफेद होगी और ऐप की थीम के अनुसार रंगीन नहीं होगी</string>\n    <string name=\"barcodes_sub\">किसी भी बारकोड (QR, EAN, AZTEC,…) को स्कैन करें और उसकी सामग्री प्राप्त करें या नया उत्पन्न करने के लिए अपना टेक्स्ट पेस्ट करें</string>\n    <string name=\"no_barcode_found\">कोई बारकोड नहीं मिला</string>\n    <string name=\"generated_barcode_will_be_here\">जनरेट किया गया बारकोड यहां होगा</string>\n    <string name=\"audio_cover_extractor\">ऑडियो कवर</string>\n    <string name=\"audio_cover_extractor_sub\">ऑडियो फ़ाइलों से एल्बम कवर छवियां निकालें, अधिकांश सामान्य प्रारूप समर्थित हैं</string>\n    <string name=\"pick_audio_to_start\">आरंभ करने के लिए ऑडियो चुनें</string>\n    <string name=\"pick_audio\">ऑडियो चुनें</string>\n    <string name=\"no_covers_found\">कोई कवर नहीं मिला</string>\n    <string name=\"send_logs\">लॉग भेजें</string>\n    <string name=\"send_logs_sub\">ऐप लॉग फ़ाइल साझा करने के लिए क्लिक करें, इससे मुझे समस्या का पता लगाने और समस्याओं को ठीक करने में मदद मिल सकती है</string>\n    <string name=\"crash_title\">ओह! कुछ गलत हो गया है</string>\n    <string name=\"crash_subtitle\">आप नीचे दिए गए विकल्पों का उपयोग करके मुझसे संपर्क कर सकते हैं और मैं समाधान खोजने का प्रयास करूंगा।\\n(लॉग संलग्न करना न भूलें)</string>\n    <string name=\"ocr_write_to_file\">फाइल करने के लिए लिखें</string>\n    <string name=\"ocr_write_to_file_sub\">छवियों के बैच से टेक्स्ट निकालें और इसे एक टेक्स्ट फ़ाइल में संग्रहीत करें</string>\n    <string name=\"ocr_write_to_metadata\">मेटाडेटा पर लिखें</string>\n    <string name=\"ocr_write_to_metadata_sub\">प्रत्येक छवि से टेक्स्ट निकालें और उसे संबंधित फ़ोटो की EXIF ​​जानकारी में रखें</string>\n    <string name=\"invisible_mode\">अदृश्य मोड</string>\n    <string name=\"invisible_mode_sub\">अपनी छवियों के बाइट्स के अंदर आंखों के लिए अदृश्य वॉटरमार्क बनाने के लिए स्टेग्नोग्राफ़ी का उपयोग करें</string>\n    <string name=\"use_lsb\">एलएसबी का प्रयोग करें</string>\n    <string name=\"use_lsb_sub\">एलएसबी (कम महत्वपूर्ण बिट) स्टेग्नोग्राफ़ी विधि का उपयोग किया जाएगा, एफडी (फ़्रीक्वेंसी डोमेन) अन्यथा</string>\n    <string name=\"auto_remove_red_eyes\">लाल आँखें स्वतः हटाएँ</string>\n    <string name=\"password\">पासवर्ड</string>\n    <string name=\"unlock\">अनलॉक</string>\n    <string name=\"pdf_is_protected\">पीडीएफ सुरक्षित है</string>\n    <string name=\"operation_almost_complete\">ऑपरेशन लगभग पूरा हो गया है. अब रद्द करने पर इसे पुनः प्रारंभ करने की आवश्यकता होगी</string>\n    <string name=\"sort_by_date_modified\">डेटा संशोधित</string>\n    <string name=\"sort_by_date_modified_reversed\">संशोधित तिथि (उलट)</string>\n    <string name=\"sort_by_size\">आकार</string>\n    <string name=\"sort_by_size_reversed\">आकार (उलटा)</string>\n    <string name=\"sort_by_mime_type\">माइम प्रकार</string>\n    <string name=\"sort_by_mime_type_reversed\">माइम प्रकार (उलटा)</string>\n    <string name=\"sort_by_extension\">विस्तार</string>\n    <string name=\"sort_by_extension_reversed\">एक्सटेंशन (उलटा)</string>\n    <string name=\"sort_by_date_added\">तिथि जोड़ी</string>\n    <string name=\"sort_by_date_added_reversed\">जोड़ी गई तारीख (उलट)</string>\n    <string name=\"left_to_right\">बाएं से दायां</string>\n    <string name=\"right_to_left\">दाएं से बाएं</string>\n    <string name=\"top_to_bottom\">नीचे से ऊपर</string>\n    <string name=\"bottom_to_top\">नीचे से शीर्ष तक</string>\n    <string name=\"liquid_glass\">तरल ग्लास</string>\n    <string name=\"liquid_glass_sub\">हाल ही में घोषित IOS 26 और इसके लिक्विड ग्लास डिज़ाइन सिस्टम पर आधारित एक स्विच</string>\n    <string name=\"pick_image_or_base64\">छवि चुनें या नीचे बेस64 डेटा चिपकाएँ/आयात करें</string>\n    <string name=\"type_image_link\">आरंभ करने के लिए छवि लिंक टाइप करें</string>\n    <string name=\"paste_link\">लिंक पेस्ट करो</string>\n    <string name=\"kaleidoscope\">बहुरूपदर्शक</string>\n    <string name=\"secondary_angle\">द्वितीयक कोण</string>\n    <string name=\"sides\">पक्षों</string>\n    <string name=\"channel_mix\">चैनल मिक्स</string>\n    <string name=\"blue_green\">नीले हरे</string>\n    <string name=\"red_blue\">लाल नीला</string>\n    <string name=\"green_red\">हरी लाल</string>\n    <string name=\"into_red\">लाल रंग में</string>\n    <string name=\"into_green\">हरे रंग में</string>\n    <string name=\"into_blue\">नीले रंग में</string>\n    <string name=\"cyan\">सियान</string>\n    <string name=\"magenta\">मैजेंटा</string>\n    <string name=\"yellow\">पीला</string>\n    <string name=\"color_halftone\">आंशिक रंग</string>\n    <string name=\"contour\">समोच्च</string>\n    <string name=\"levels\">स्तरों</string>\n    <string name=\"offset\">ओफ़्सेट</string>\n    <string name=\"voronoi_crystallize\">वोरोनोई क्रिस्टलाइज़</string>\n    <string name=\"shape\">आकार</string>\n    <string name=\"stretch\">खींचना</string>\n    <string name=\"randomness\">अनियमितता</string>\n    <string name=\"despeckle\">डेस्पेकल</string>\n    <string name=\"diffuse\">बिखरा हुआ</string>\n    <string name=\"dog\">कुत्ता</string>\n    <string name=\"second_radius\">दूसरा दायरा</string>\n    <string name=\"equalize\">बराबर</string>\n    <string name=\"glow\">चमकना</string>\n    <string name=\"whirl_and_pinch\">चक्कर और चुटकी</string>\n    <string name=\"pointillize\">बिंदुवार</string>\n    <string name=\"border_color\">सीमा रंग</string>\n    <string name=\"polar_coordinates\">ध्रुवीय निर्देशांक</string>\n    <string name=\"rect_to_polar\">ध्रुवीय की ओर सीधा</string>\n    <string name=\"polar_to_rect\">ध्रुवीय से आयताकार</string>\n    <string name=\"invert_in_circle\">वृत्त में उलटा करें</string>\n    <string name=\"reduce_noise\">शोर कम करें</string>\n    <string name=\"simple_solarize\">सरल सोलराइज़</string>\n    <string name=\"weave\">बुनना</string>\n    <string name=\"x_gap\">एक्स गैप</string>\n    <string name=\"y_gap\">वाई गैप</string>\n    <string name=\"x_width\">एक्स चौड़ाई</string>\n    <string name=\"y_wdth\">वाई चौड़ाई</string>\n    <string name=\"twirl\">घुमाव</string>\n    <string name=\"rubber_stmp\">रबड़ की मोहर</string>\n    <string name=\"smear\">धब्बा</string>\n    <string name=\"density\">घनत्व</string>\n    <string name=\"mix\">मिक्स</string>\n    <string name=\"sphere_lensh_distortion\">क्षेत्र लेंस विरूपण</string>\n    <string name=\"refraction_index\">अपवर्तन सूचकांक</string>\n    <string name=\"arc\">आर्क</string>\n    <string name=\"spread_angle\">फैला हुआ कोण</string>\n    <string name=\"sparkle\">चमक</string>\n    <string name=\"rays\">किरणों</string>\n    <string name=\"ascii\">एएससीआईआई</string>\n    <string name=\"gradient\">ढाल</string>\n    <string name=\"moire\">मेरी</string>\n    <string name=\"autumn\">शरद ऋतु</string>\n    <string name=\"bone\">हड्डी</string>\n    <string name=\"jet\">जेट</string>\n    <string name=\"winter\">सर्दी</string>\n    <string name=\"ocean\">महासागर</string>\n    <string name=\"summer\">गर्मी</string>\n    <string name=\"spring\">वसंत</string>\n    <string name=\"cool_variant\">कूल वेरिएंट</string>\n    <string name=\"hsv\">एचएसवी</string>\n    <string name=\"pink\">गुलाबी</string>\n    <string name=\"hot\">गर्म</string>\n    <string name=\"parula\">शब्द</string>\n    <string name=\"magma\">मेग्मा</string>\n    <string name=\"inferno\">नरक</string>\n    <string name=\"plasma\">प्लाज्मा</string>\n    <string name=\"viridis\">विरिडीस</string>\n    <string name=\"cividis\">नागरिकों</string>\n    <string name=\"twilight\">सांझ</string>\n    <string name=\"twilight_shifted\">गोधूलि स्थानांतरित</string>\n    <string name=\"auto_perspective\">परिप्रेक्ष्य ऑटो</string>\n    <string name=\"deskew\">डेस्क्यू</string>\n    <string name=\"allow_crop\">फसल की अनुमति दें</string>\n    <string name=\"crop_or_perspective\">फसल या परिप्रेक्ष्य</string>\n    <string name=\"absolute\">निरपेक्ष</string>\n    <string name=\"turbo\">टर्बो</string>\n    <string name=\"deep_green\">गहरा हरा</string>\n    <string name=\"lens_correction\">लेंस सुधार</string>\n    <string name=\"target_lens_profile\">JSON प्रारूप में लक्ष्य लेंस प्रोफ़ाइल फ़ाइल</string>\n    <string name=\"download_ready_lens_profiles\">तैयार लेंस प्रोफ़ाइल डाउनलोड करें</string>\n    <string name=\"part_percents\">भाग प्रतिशत</string>\n    <string name=\"export_as_json\">JSON के रूप में निर्यात करें</string>\n    <string name=\"export_as_json_sub\">json प्रतिनिधित्व के रूप में पैलेट डेटा के साथ स्ट्रिंग की प्रतिलिपि बनाएँ</string>\n    <string name=\"seam_carving\">सीवन नक्काशी</string>\n    <string name=\"home_screen\">होम स्क्रीन</string>\n    <string name=\"lock_screen\">लॉक स्क्रीन</string>\n    <string name=\"built_in\">में निर्मित</string>\n    <string name=\"wallpapers_export\">वॉलपेपर निर्यात</string>\n    <string name=\"refresh\">ताज़ा करना</string>\n    <string name=\"wallpapers_export_sub\">वर्तमान होम, लॉक और अंतर्निर्मित वॉलपेपर प्राप्त करें</string>\n    <string name=\"allow_access_to_all_files_for_wp\">सभी फ़ाइलों तक पहुंच की अनुमति दें, वॉलपेपर पुनः प्राप्त करने के लिए यह आवश्यक है</string>\n    <string name=\"allow_read_media_images_for_wp\">बाह्य संग्रहण प्रबंधित करने की अनुमति पर्याप्त नहीं है, आपको अपनी छवियों तक पहुंच की अनुमति देनी होगी, सुनिश्चित करें कि \\\"सभी को अनुमति दें\\\" का चयन करें</string>\n    <string name=\"add_preset_to_filename\">फ़ाइल नाम में प्रीसेट जोड़ें</string>\n    <string name=\"add_preset_to_filename_sub\">छवि फ़ाइल नाम में चयनित प्रीसेट के साथ प्रत्यय जोड़ता है</string>\n    <string name=\"add_image_scale_mode_to_filename\">फ़ाइल नाम में छवि स्केल मोड जोड़ें</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">छवि फ़ाइल नाम में चयनित छवि स्केल मोड के साथ प्रत्यय जोड़ता है</string>\n    <string name=\"ascii_art\">आस्की कला</string>\n    <string name=\"ascii_art_sub\">चित्र को एएससीआई टेक्स्ट में बदलें जो छवि जैसा दिखेगा</string>\n    <string name=\"params\">पैरामीटर</string>\n    <string name=\"invert_colors_ascii_sub\">कुछ मामलों में बेहतर परिणाम के लिए छवि पर नकारात्मक फ़िल्टर लागू करता है</string>\n    <string name=\"processing_screenshot\">स्क्रीनशॉट संसाधित हो रहा है</string>\n    <string name=\"screenshot_not_captured_try_again\">स्क्रीनशॉट कैप्चर नहीं हुआ, पुनः प्रयास करें</string>\n    <string name=\"skipped_saving\">सहेजना छोड़ दिया गया</string>\n    <string name=\"skipped_saving_multiple\">%1$s फ़ाइलें छोड़ दी गईं</string>\n    <string name=\"allow_skip_if_larger\">यदि बड़ा हो तो छोड़ें की अनुमति दें</string>\n    <string name=\"allow_skip_if_larger_sub\">यदि परिणामी फ़ाइल का आकार मूल से बड़ा होगा तो कुछ टूल को छवियों को सहेजना छोड़ने की अनुमति दी जाएगी</string>\n    <string name=\"qr_type_calendar_event\">कैलेंडर इवेंट</string>\n    <string name=\"qr_type_contact_info\">संपर्क</string>\n    <string name=\"qr_type_email\">ईमेल</string>\n    <string name=\"qr_type_geo_point\">जगह</string>\n    <string name=\"qr_type_phone\">फ़ोन</string>\n    <string name=\"qr_type_plain\">मूलपाठ</string>\n    <string name=\"qr_type_sms\">एसएमएस</string>\n    <string name=\"qr_type_url\">यूआरएल</string>\n    <string name=\"qr_type_wifi\">वाईफ़ाई</string>\n    <string name=\"open_network\">नेटवर्क खोलें</string>\n    <string name=\"not_specified\">एन/ए</string>\n    <string name=\"ssid\">एसएसआईडी</string>\n    <string name=\"phone\">फ़ोन</string>\n    <string name=\"message\">संदेश</string>\n    <string name=\"address\">पता</string>\n    <string name=\"subject\">विषय</string>\n    <string name=\"body\">शरीर</string>\n    <string name=\"name\">नाम</string>\n    <string name=\"organization\">संगठन</string>\n    <string name=\"title\">शीर्षक</string>\n    <string name=\"phones\">फ़ोनों</string>\n    <string name=\"emails\">ईमेल</string>\n    <string name=\"urls\">यूआरएल</string>\n    <string name=\"addresses\">पतों</string>\n    <string name=\"summary\">सारांश</string>\n    <string name=\"description\">विवरण</string>\n    <string name=\"location\">जगह</string>\n    <string name=\"organizer\">व्यवस्था करनेवाला</string>\n    <string name=\"start_date\">आरंभ करने की तिथि</string>\n    <string name=\"end_date\">अंतिम तिथि</string>\n    <string name=\"status\">स्थिति</string>\n    <string name=\"latitude\">अक्षांश</string>\n    <string name=\"longitude\">देशान्तर</string>\n    <string name=\"create_barcode\">बारकोड बनाएं</string>\n    <string name=\"edit_barcode\">बारकोड संपादित करें</string>\n    <string name=\"wifi_configuration\">वाई-फ़ाई कॉन्फ़िगरेशन</string>\n    <string name=\"security\">सुरक्षा</string>\n    <string name=\"pick_contact\">संपर्क चुनें</string>\n    <string name=\"grant_contact_permission\">चयनित संपर्क का उपयोग करके सेटिंग्स में संपर्कों को स्वतः भरण की अनुमति दें</string>\n    <string name=\"contact_info\">संपर्क सूचना</string>\n    <string name=\"first_name\">पहला नाम</string>\n    <string name=\"middle_name\">मध्य नाम</string>\n    <string name=\"last_name\">उपनाम</string>\n    <string name=\"pronunciation\">उच्चारण</string>\n    <string name=\"add_phone\">फ़ोन जोड़ें</string>\n    <string name=\"add_email\">ईमेल जोड़ें</string>\n    <string name=\"add_address\">पता जोड़ें</string>\n    <string name=\"website\">वेबसाइट</string>\n    <string name=\"add_website\">वेबसाइट जोड़ें</string>\n    <string name=\"formatted_name\">स्वरूपित नाम</string>\n    <string name=\"qr_code_top_image\">इस छवि का उपयोग बारकोड के ऊपर लगाने के लिए किया जाएगा</string>\n    <string name=\"code_customization\">कोड अनुकूलन</string>\n    <string name=\"qr_logo_image\">इस छवि का उपयोग क्यूआर कोड के केंद्र में लोगो के रूप में किया जाएगा</string>\n    <string name=\"logo\">प्रतीक चिन्ह</string>\n    <string name=\"logo_padding\">लोगो पैडिंग</string>\n    <string name=\"logo_size\">लोगो का आकार</string>\n    <string name=\"logo_corners\">लोगो के कोने</string>\n    <string name=\"fourth_eye\">चौथी आँख</string>\n    <string name=\"fourth_eye_description\">निचले सिरे के कोने पर चौथी आँख जोड़कर क्यूआर कोड में नेत्र समरूपता जोड़ता है</string>\n    <string name=\"pixel_shape\">पिक्सेल आकार</string>\n    <string name=\"frame_shape\">फ़्रेम का आकार</string>\n    <string name=\"ball_shape\">गेंद का आकार</string>\n    <string name=\"error_correction_level\">त्रुटि सुधार स्तर</string>\n    <string name=\"dark_color\">गहरा रंग</string>\n    <string name=\"light_color\">हल्के रंग</string>\n    <string name=\"hyper_os\">हाइपर ओएस</string>\n    <string name=\"hyper_os_sub\">Xiaomi हाइपरओएस जैसा स्टाइल</string>\n    <string name=\"mask_pattern\">मुखौटा पैटर्न</string>\n    <string name=\"code_may_be_not_scannable\">यह कोड स्कैन करने योग्य नहीं हो सकता है, इसे सभी उपकरणों के साथ पढ़ने योग्य बनाने के लिए स्वरूप पैरामीटर बदलें</string>\n    <string name=\"not_scannable\">स्कैन करने योग्य नहीं</string>\n    <string name=\"launcher_mode_sub\">टूल अधिक कॉम्पैक्ट होने के लिए होम स्क्रीन ऐप लॉन्चर की तरह दिखेंगे</string>\n    <string name=\"launcher_mode\">लॉन्चर मोड</string>\n    <string name=\"flood_fill_sub\">किसी क्षेत्र को चयनित ब्रश और शैली से भर देता है</string>\n    <string name=\"flood_fill\">बाढ़ भरण</string>\n    <string name=\"spray\">फुहार</string>\n    <string name=\"spray_sub\">भित्तिचित्र शैली वाला पथ बनाता है</string>\n    <string name=\"square_particles\">चौकोर कण</string>\n    <string name=\"square_particles_sub\">स्प्रे कण वृत्तों के बजाय चौकोर आकार के होंगे</string>\n    <string name=\"palette_tools\">पैलेट उपकरण</string>\n    <string name=\"palette_tools_sub\">छवि से अपने पैलेट में मूल/सामग्री उत्पन्न करें, या विभिन्न पैलेट प्रारूपों में आयात/निर्यात करें</string>\n    <string name=\"edit_palette\">पैलेट संपादित करें</string>\n    <string name=\"edit_palette_sub\">विभिन्न प्रारूपों में निर्यात/आयात पैलेट</string>\n    <string name=\"color_name\">रंग का नाम</string>\n    <string name=\"palette_name\">पैलेट नाम</string>\n    <string name=\"palette_format\">पैलेट प्रारूप</string>\n    <string name=\"export_palette_sub\">उत्पन्न पैलेट को विभिन्न प्रारूपों में निर्यात करें</string>\n    <string name=\"add_color_palette_sub\">मौजूदा पैलेट में नया रंग जोड़ता है</string>\n    <string name=\"palette_name_not_supported\">%1$s प्रारूप पैलेट नाम प्रदान करने का समर्थन नहीं करता</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store नीतियों के कारण, इस सुविधा को वर्तमान बिल्ड में शामिल नहीं किया जा सकता है। इस कार्यक्षमता तक पहुँचने के लिए, कृपया वैकल्पिक स्रोत से ImageToolbox डाउनलोड करें। आप नीचे GitHub पर उपलब्ध बिल्ड पा सकते हैं।</string>\n    <string name=\"open_github_page\">जीथब पेज खोलें</string>\n    <string name=\"overwrite_files_sub_short\">मूल फ़ाइल को चयनित फ़ोल्डर में सहेजने के बजाय नई फ़ाइल से बदल दिया जाएगा</string>\n    <string name=\"hidden_watermark_text_detected\">छिपे हुए वॉटरमार्क टेक्स्ट का पता लगाया गया</string>\n    <string name=\"hidden_watermark_image_detected\">छिपी हुई वॉटरमार्क छवि का पता लगाया गया</string>\n    <string name=\"this_image_was_hidden\">यह छवि छिपाई गई थी</string>\n    <string name=\"generative_inpaint\">जनरेटिव इनपेंटिंग</string>\n    <string name=\"generative_inpaint_sub\">आपको OpenCV पर भरोसा किए बिना, AI मॉडल का उपयोग करके किसी छवि में ऑब्जेक्ट को हटाने की अनुमति देता है। इस सुविधा का उपयोग करने के लिए, ऐप GitHub से आवश्यक मॉडल (~200 एमबी) डाउनलोड करेगा</string>\n    <string name=\"generative_inpaint_ready_sub\">आपको OpenCV पर भरोसा किए बिना, AI मॉडल का उपयोग करके किसी छवि में ऑब्जेक्ट को हटाने की अनुमति देता है। यह लंबे समय तक चलने वाला ऑपरेशन हो सकता है</string>\n    <string name=\"error_level_analysis\">त्रुटि स्तर विश्लेषण</string>\n    <string name=\"luminance_gradient\">चमक प्रवणता</string>\n    <string name=\"average_distance\">औसत दूरी</string>\n    <string name=\"copy_move_detection\">मूव डिटेक्शन कॉपी करें</string>\n    <string name=\"retain\">बनाए रखना</string>\n    <string name=\"coefficent\">गुणक</string>\n    <string name=\"clipboard_data_is_too_large\">क्लिपबोर्ड डेटा बहुत बड़ा है</string>\n    <string name=\"data_is_too_large_to_copy\">कॉपी करने के लिए डेटा बहुत बड़ा है</string>\n    <string name=\"simple_weave_pixelization\">सरल बुनाई पिक्सेलकरण</string>\n    <string name=\"staggered_pixelization\">क्रमबद्ध पिक्सेलकरण</string>\n    <string name=\"cross_pixelization\">क्रॉस पिक्सेलाइज़ेशन</string>\n    <string name=\"micro_macro_pixelization\">माइक्रो मैक्रो पिक्सेलाइजेशन</string>\n    <string name=\"orbital_pixelization\">कक्षीय पिक्सेलकरण</string>\n    <string name=\"vortex_pixelization\">भंवर पिक्सेलकरण</string>\n    <string name=\"pulse_grid_pixelization\">पल्स ग्रिड पिक्सेलाइजेशन</string>\n    <string name=\"nucleus_pixelization\">न्यूक्लियस पिक्सेलाइजेशन</string>\n    <string name=\"radial_weave_pixelization\">रेडियल बुनाई पिक्सेलाइजेशन</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\" नहीं खुल सकता</string>\n    <string name=\"snowfall_mode\">बर्फबारी मोड</string>\n    <string name=\"enabled\">सक्रिय</string>\n    <string name=\"border_frame\">सीमा फ़्रेम</string>\n    <string name=\"glitch_variant\">गड़बड़ संस्करण</string>\n    <string name=\"channel_shift\">चैनल शिफ्ट</string>\n    <string name=\"max_offset\">अधिकतम ऑफसेट</string>\n    <string name=\"vhs\">वीएचएस</string>\n    <string name=\"block_glitch\">ब्लॉक गड़बड़ी</string>\n    <string name=\"block_size\">ब्लॉक का आकार</string>\n    <string name=\"crt_curvature\">सीआरटी वक्रता</string>\n    <string name=\"curvature\">वक्रता</string>\n    <string name=\"chroma\">क्रोमा</string>\n    <string name=\"pixel_melt\">पिक्सेल पिघल गया</string>\n    <string name=\"max_drop\">मैक्स ड्रॉप</string>\n    <string name=\"ai_tools\">एआई उपकरण</string>\n    <string name=\"ai_tools_sub\">एआई मॉडल के माध्यम से छवियों को संसाधित करने के लिए विभिन्न उपकरण जैसे आर्टिफैक्ट हटाना या डीनोइज़िंग</string>\n    <string name=\"model_anime_undeint\">संपीड़न, दांतेदार रेखाएं</string>\n    <string name=\"model_broadcast\">कार्टून, प्रसारण संपीड़न</string>\n    <string name=\"model_rgb_max_denoise_fp16\">सामान्य संपीड़न, सामान्य शोर</string>\n    <string name=\"model_wb_denoise\">बेरंग कार्टून शोर</string>\n    <string name=\"model_span_anime_pretrain\">तेज़, सामान्य संपीड़न, सामान्य शोर, एनीमेशन/कॉमिक्स/एनीमे</string>\n    <string name=\"model_book_scan\">पुस्तक स्कैनिंग</string>\n    <string name=\"model_overexposure\">एक्सपोज़र सुधार</string>\n    <string name=\"model_fbcnn_color_fp16\">सामान्य संपीड़न, रंगीन छवियों में सर्वश्रेष्ठ</string>\n    <string name=\"model_fbcnn_gray_fp16\">सामान्य संपीड़न, ग्रेस्केल छवियों में सर्वश्रेष्ठ</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">सामान्य संपीड़न, ग्रेस्केल छवियां, मजबूत</string>\n    <string name=\"model_scunet_color_gan_fp16\">सामान्य शोर, रंगीन छवियाँ</string>\n    <string name=\"model_scunet_color_psnr_fp16\">सामान्य शोर, रंगीन चित्र, बेहतर विवरण</string>\n    <string name=\"model_scunet_gray_15_fp16\">सामान्य शोर, ग्रेस्केल छवियां</string>\n    <string name=\"model_scunet_gray_25_fp16\">सामान्य शोर, ग्रेस्केल छवियां, अधिक मजबूत</string>\n    <string name=\"model_scunet_gray_50_fp16\">सामान्य शोर, ग्रेस्केल छवियां, सबसे मजबूत</string>\n    <string name=\"model_jpeg_destroyer\">सामान्य संपीड़न</string>\n    <string name=\"model_jaywreck\">सामान्य संपीड़न</string>\n    <string name=\"model_h264\">टेक्सचराइज़ेशन, h264 संपीड़न</string>\n    <string name=\"model_vhs\">वीएचएस संपीड़न</string>\n    <string name=\"model_cinepak\">गैर-मानक संपीड़न (सिनेपैक, एमएसवीडियो1, आरओक्यू)</string>\n    <string name=\"model_debink_v4\">बिंक संपीड़न, ज्यामिति पर बेहतर</string>\n    <string name=\"model_debink_v5\">बिंक संपीड़न, मजबूत</string>\n    <string name=\"model_debink_v6\">बिंक संपीड़न, नरम, विवरण बरकरार रखता है</string>\n    <string name=\"model_antialias\">सीढ़ी-चरण प्रभाव को समाप्त करना, चौरसाई करना</string>\n    <string name=\"model_kdm_scans\">स्कैन की गई कला/चित्र, हल्का संपीड़न, मौयर</string>\n    <string name=\"model_bandage\">रंग बैंडिंग</string>\n    <string name=\"model_halftone\">धीरे-धीरे, हाफ़टोन हटाते हुए</string>\n    <string name=\"model_colorizer\">ग्रेस्केल/बीडब्ल्यू छवियों के लिए सामान्य कलराइज़र, बेहतर परिणामों के लिए DDColor का उपयोग करें</string>\n    <string name=\"model_deedge\">किनारा हटाना</string>\n    <string name=\"model_desharpen\">अत्यधिक तीक्ष्णता को दूर करता है</string>\n    <string name=\"model_dither\">धीमा, डगमगाता हुआ</string>\n    <string name=\"model_gainres\">एंटी-अलियासिंग, सामान्य कलाकृतियाँ, सीजीआई</string>\n    <string name=\"model_kdm003_scans\">KDM003 स्कैन प्रोसेसिंग</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">हल्के वजन वाली छवि वृद्धि मॉडल</string>\n    <string name=\"model_bcgone_detailed_v2\">संपीड़न विरूपण साक्ष्य हटाना</string>\n    <string name=\"model_bcgone_smooth\">संपीड़न विरूपण साक्ष्य हटाना</string>\n    <string name=\"model_bandage_smooth\">सहज परिणामों के साथ पट्टी हटाना</string>\n    <string name=\"model_bendel_halftone\">हाफ़टोन पैटर्न प्रसंस्करण</string>\n    <string name=\"model_dither_deleter_v3_smooth\">दिदर पैटर्न हटाना V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG विरूपण साक्ष्य निष्कासन V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 बनावट संवर्द्धन</string>\n    <string name=\"model_vhs_sharpen\">वीएचएस को तेज़ करना और बढ़ाना</string>\n    <string name=\"merging\">विलय</string>\n    <string name=\"chunk_size\">खंड आकार</string>\n    <string name=\"overlap_size\">ओवरलैप आकार</string>\n    <string name=\"note_chunk_info\">%1$s px से अधिक की छवियों को टुकड़ों में काटा और संसाधित किया जाएगा, दृश्यमान सीमों को रोकने के लिए ओवरलैप इन्हें मिश्रित करता है।</string>\n    <string name=\"large_chunk_warning\">बड़े आकार निम्न-स्तरीय उपकरणों के साथ अस्थिरता पैदा कर सकते हैं</string>\n    <string name=\"select_one_to_start\">आरंभ करने के लिए एक का चयन करें</string>\n    <string name=\"delete_model_sub\">क्या आप %1$s मॉडल को हटाना चाहते हैं? आपको इसे दोबारा डाउनलोड करना होगा</string>\n    <string name=\"confirm\">पुष्टि करना</string>\n    <string name=\"models\">मॉडल</string>\n    <string name=\"downloaded_models\">डाउनलोड किए गए मॉडल</string>\n    <string name=\"available_models\">उपलब्ध मॉडल</string>\n    <string name=\"preparing\">तैयारी</string>\n    <string name=\"active_model\">सक्रिय मॉडल</string>\n    <string name=\"failed_to_open_session\">सत्र खोलने में विफल</string>\n    <string name=\"only_onnx_models\">केवल .onnx/.ort मॉडल आयात किए जा सकते हैं</string>\n    <string name=\"import_model\">आयात मॉडल</string>\n    <string name=\"import_model_sub\">आगे उपयोग के लिए कस्टम ओएनएक्स मॉडल आयात करें, केवल ओएनएक्स/ओआरटी मॉडल स्वीकार किए जाते हैं, लगभग सभी एसर्गन जैसे वेरिएंट का समर्थन करता है</string>\n    <string name=\"imported_models\">आयातित मॉडल</string>\n    <string name=\"model_scunet_color_15_fp16\">सामान्य शोर, रंगीन चित्र</string>\n    <string name=\"model_scunet_color_25_fp16\">सामान्य शोर, रंगीन चित्र, अधिक मजबूत</string>\n    <string name=\"model_scunet_color_50_fp16\">सामान्य शोर, रंगीन छवियाँ, सबसे मजबूत</string>\n    <string name=\"model_artifacts_dithering_alsa\">बिखरती कलाकृतियों और रंग बैंडिंग को कम करता है, चिकनी ग्रेडिएंट और सपाट रंग क्षेत्रों में सुधार करता है।</string>\n    <string name=\"model_nmkd_brighten_redux\">प्राकृतिक रंगों को संरक्षित करते हुए संतुलित हाइलाइट्स के साथ छवि की चमक और कंट्रास्ट को बढ़ाता है।</string>\n    <string name=\"model_nmkd_brighten\">विवरण बनाए रखते हुए और ओवरएक्सपोज़र से बचते हुए गहरे रंग की छवियों को चमकाता है।</string>\n    <string name=\"model_nmkd_detoon\">अत्यधिक रंग टोनिंग को हटाता है और अधिक तटस्थ और प्राकृतिक रंग संतुलन बहाल करता है।</string>\n    <string name=\"model_noise_toner_poisson_detailed\">बारीक विवरण और बनावट को संरक्षित करने पर जोर देने के साथ पॉइसन-आधारित शोर टोनिंग लागू करता है।</string>\n    <string name=\"model_noise_toner_poisson_soft\">सहज और कम आक्रामक दृश्य परिणामों के लिए नरम पॉइसन शोर टोनिंग लागू करता है।</string>\n    <string name=\"model_noise_toner_uniform_detailed\">समान शोर टोनिंग विवरण संरक्षण और छवि स्पष्टता पर केंद्रित है।</string>\n    <string name=\"model_noise_toner_uniform_soft\">सूक्ष्म बनावट और चिकनी उपस्थिति के लिए सौम्य समान शोर टोनिंग।</string>\n    <string name=\"model_repainter\">कलाकृतियों को दोबारा रंगकर और छवि स्थिरता में सुधार करके क्षतिग्रस्त या असमान क्षेत्रों की मरम्मत करता है।</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">हल्के डिबैंडिंग मॉडल जो न्यूनतम प्रदर्शन लागत के साथ रंग बैंडिंग को हटा देता है।</string>\n    <string name=\"model_jpeg_0_20\">बेहतर स्पष्टता के लिए छवियों को बहुत उच्च संपीड़न कलाकृतियों (0-20% गुणवत्ता) के साथ अनुकूलित करता है।</string>\n    <string name=\"model_jpeg_20_40\">उच्च संपीड़न कलाकृतियों (20-40% गुणवत्ता) के साथ छवियों को बढ़ाता है, विवरण बहाल करता है और शोर को कम करता है।</string>\n    <string name=\"model_jpeg_40_60\">मध्यम संपीड़न (40-60% गुणवत्ता) के साथ छवियों को बेहतर बनाता है, तीक्ष्णता और चिकनाई को संतुलित करता है।</string>\n    <string name=\"model_jpeg_60_80\">सूक्ष्म विवरण और बनावट को बढ़ाने के लिए छवियों को हल्के संपीड़न (60-80% गुणवत्ता) के साथ परिष्कृत करता है।</string>\n    <string name=\"model_jpeg_80_100\">प्राकृतिक लुक और विवरण को संरक्षित करते हुए लगभग दोषरहित छवियों (80-100% गुणवत्ता) को थोड़ा बढ़ाता है।</string>\n    <string name=\"model_spongecolor_lite\">सरल और तेज़ रंगीकरण, कार्टून, आदर्श नहीं</string>\n    <string name=\"model_deblr\">कलाकृतियों को पेश किए बिना छवि के धुंधलेपन को थोड़ा कम करता है, तीक्ष्णता में सुधार करता है।</string>\n    <string name=\"processing_channel\">लंबे समय तक चलने वाले ऑपरेशन</string>\n    <string name=\"processing_image\">छवि प्रसंस्करण</string>\n    <string name=\"processing\">प्रसंस्करण</string>\n    <string name=\"model_artifacts_jpg_0_20\">बहुत कम गुणवत्ता वाली छवियों (0-20%) में भारी JPEG संपीड़न कलाकृतियों को हटा देता है।</string>\n    <string name=\"model_artifacts_jpg_20_40\">अत्यधिक संपीड़ित छवियों (20-40%) में मजबूत JPEG कलाकृतियों को कम करता है।</string>\n    <string name=\"model_artifacts_jpg_40_60\">छवि विवरण (40-60%) संरक्षित करते हुए मध्यम जेपीईजी कलाकृतियों को साफ करता है।</string>\n    <string name=\"model_artifacts_jpg_60_80\">प्रकाश JPEG कलाकृतियों को काफी उच्च गुणवत्ता वाली छवियों (60-80%) में परिष्कृत करता है।</string>\n    <string name=\"model_artifacts_jpg_80_100\">लगभग दोषरहित छवियों (80-100%) में मामूली जेपीईजी कलाकृतियों को सूक्ष्मता से कम कर देता है।</string>\n    <string name=\"model_redetail_v2\">बारीक विवरण और बनावट को बढ़ाता है, भारी कलाकृतियों के बिना कथित तीक्ष्णता में सुधार करता है।</string>\n    <string name=\"processing_finished\">प्रसंस्करण समाप्त हो गया</string>\n    <string name=\"processing_failed\">प्रसंस्करण विफल रहा</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">गति के लिए अनुकूलित, प्राकृतिक लुक बनाए रखते हुए त्वचा की बनावट और विवरण को बढ़ाता है।</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG संपीड़न कलाकृतियों को हटाता है और संपीड़ित फ़ोटो के लिए छवि गुणवत्ता पुनर्स्थापित करता है।</string>\n    <string name=\"model_iso_denoise_v1\">कम रोशनी की स्थिति में ली गई तस्वीरों में आईएसओ शोर को कम करता है, विवरण संरक्षित करता है।</string>\n    <string name=\"model_dejumbo\">ओवरएक्सपोज़्ड या \\\"जंबो\\\" हाइलाइट्स को ठीक करता है और बेहतर टोनल संतुलन बहाल करता है।</string>\n    <string name=\"model_ddcolor_tiny\">हल्का और तेज़ रंगीकरण मॉडल जो ग्रेस्केल छवियों में प्राकृतिक रंग जोड़ता है।</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">डेनोइज़</string>\n    <string name=\"type_colorize\">रंग दें</string>\n    <string name=\"type_artifacts\">कलाकृतियों</string>\n    <string name=\"type_enhance\">बढ़ाना</string>\n    <string name=\"type_anime\">एनिमे</string>\n    <string name=\"type_scans\">स्कैन</string>\n    <string name=\"type_upscale\">एक उच्च स्तरीय</string>\n    <string name=\"model_realesrgan_x4v3\">सामान्य छवियों के लिए X4 अपस्केलर; छोटा मॉडल जो कम जीपीयू और समय का उपयोग करता है, मध्यम डिब्लर और डीनोइज़ के साथ।</string>\n    <string name=\"model_realesrgan_x2plus\">सामान्य छवियों, बनावट और प्राकृतिक विवरणों को संरक्षित करने के लिए X2 अपस्केलर।</string>\n    <string name=\"model_realesrgan_x4plus\">उन्नत बनावट और यथार्थवादी परिणामों के साथ सामान्य छवियों के लिए X4 अपस्केलर।</string>\n    <string name=\"model_realesrgan_x4plus_anime\">एनीमे छवियों के लिए अनुकूलित X4 अपस्केलर; स्पष्ट रेखाओं और विवरणों के लिए 6 आरआरडीबी ब्लॉक।</string>\n    <string name=\"model_realesrnet_x4plus\">MSE हानि के साथ X4 अपस्केलर, सामान्य छवियों के लिए बेहतर परिणाम और कम कलाकृतियाँ उत्पन्न करता है।</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 अपस्केलर एनीमे छवियों के लिए अनुकूलित; अधिक स्पष्ट विवरण और चिकनी रेखाओं वाला 4B32F संस्करण।</string>\n    <string name=\"model_ultrasharp_v2_x4\">सामान्य छवियों के लिए X4 UltraSharp V2 मॉडल; तीक्ष्णता और स्पष्टता पर जोर देता है।</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 अल्ट्राशार्प V2 लाइट; तेज़ और छोटा, कम GPU मेमोरी का उपयोग करते हुए विवरण को सुरक्षित रखता है।</string>\n    <string name=\"model_rmbg_1_4\">त्वरित पृष्ठभूमि हटाने के लिए हल्का मॉडल। संतुलित प्रदर्शन और सटीकता। पोर्ट्रेट, वस्तुओं और दृश्यों के साथ काम करता है। अधिकांश उपयोग के मामलों के लिए अनुशंसित.</string>\n    <string name=\"type_removebg\">बीजी हटाएँ</string>\n    <string name=\"horizontal_border_thickness\">क्षैतिज सीमा मोटाई</string>\n    <string name=\"vertical_border_thickness\">ऊर्ध्वाधर सीमा मोटाई</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s रंग</item>\n        <item quantity=\"other\">%1$s रंग</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">वर्तमान मॉडल चंकिंग का समर्थन नहीं करता है, छवि को मूल आयामों में संसाधित किया जाएगा, इससे उच्च मेमोरी खपत और लो-एंड डिवाइस के साथ समस्याएं हो सकती हैं</string>\n    <string name=\"chunking_disabled\">चंकिंग अक्षम, छवि को मूल आयामों में संसाधित किया जाएगा, इससे उच्च मेमोरी खपत और कम-अंत डिवाइसों के साथ समस्याएं हो सकती हैं लेकिन अनुमान लगाने पर बेहतर परिणाम मिल सकते हैं</string>\n    <string name=\"chunking\">ठस</string>\n    <string name=\"model_u2net\">पृष्ठभूमि हटाने के लिए उच्च सटीकता छवि विभाजन मॉडल</string>\n    <string name=\"model_u2netp\">कम मेमोरी उपयोग के साथ तेजी से पृष्ठभूमि हटाने के लिए U2Net का हल्का संस्करण।</string>\n    <string name=\"model_ddcolor\">पूर्ण DDColor मॉडल न्यूनतम कलाकृतियों के साथ सामान्य छवियों के लिए उच्च गुणवत्ता वाला रंगीकरण प्रदान करता है। सभी रंगीकरण मॉडलों का सर्वोत्तम विकल्प।</string>\n    <string name=\"model_ddcolor_artistic\">DDColor प्रशिक्षित और निजी कलात्मक डेटासेट; कम अवास्तविक रंग कलाकृतियों के साथ विविध और कलात्मक रंगीकरण परिणाम उत्पन्न करता है।</string>\n    <string name=\"model_birefnet\">सटीक पृष्ठभूमि हटाने के लिए स्विन ट्रांसफार्मर पर आधारित हल्के BiRefNet मॉडल।</string>\n    <string name=\"model_inspyrenet\">तेज किनारों और उत्कृष्ट विवरण संरक्षण के साथ उच्च गुणवत्ता वाली पृष्ठभूमि हटाना, विशेष रूप से जटिल वस्तुओं और पेचीदा पृष्ठभूमि पर।</string>\n    <string name=\"model_isnet\">पृष्ठभूमि हटाने वाला मॉडल जो चिकने किनारों के साथ सटीक मास्क तैयार करता है, जो सामान्य वस्तुओं और मध्यम विवरण संरक्षण के लिए उपयुक्त है।</string>\n    <string name=\"model_already_downloaded\">मॉडल पहले ही डाउनलोड हो चुका है</string>\n    <string name=\"model_successfully_imported\">मॉडल सफलतापूर्वक आयात किया गया</string>\n    <string name=\"type\">प्रकार</string>\n    <string name=\"keyword\">कीवर्ड</string>\n    <string name=\"very_fast\">बहुत तेज</string>\n    <string name=\"normal\">सामान्य</string>\n    <string name=\"slow\">धीमा</string>\n    <string name=\"very_slow\">बहुत धीमी गति से</string>\n    <string name=\"compute_percents\">प्रतिशत की गणना करें</string>\n    <string name=\"minimum_value_is\">न्यूनतम मान %1$s है</string>\n    <string name=\"warp_sub\">उंगलियों से चित्र बनाकर विकृत करें</string>\n    <string name=\"warp\">ताना</string>\n    <string name=\"hardness\">कठोरता</string>\n    <string name=\"warp_mode\">ताना मोड</string>\n    <string name=\"warp_mode_move\">कदम</string>\n    <string name=\"warp_mode_grow\">बढ़ना</string>\n    <string name=\"warp_mode_shrink\">सिकुड़ना</string>\n    <string name=\"warp_mode_swirl_cw\">भंवर सीडब्ल्यू</string>\n    <string name=\"warp_mode_swirl_ccw\">भंवर CCW</string>\n    <string name=\"fade_strength\">फीकी ताकत</string>\n    <string name=\"top_drop\">शीर्ष ड्रॉप</string>\n    <string name=\"bottom_drop\">नीचे की बूंद</string>\n    <string name=\"start_drop\">ड्रॉप प्रारंभ करें</string>\n    <string name=\"end_drop\">अंत ड्रॉप</string>\n    <string name=\"downloading\">डाउनलोड</string>\n    <string name=\"smooth_shapes\">चिकनी आकृतियाँ</string>\n    <string name=\"smooth_shapes_sub\">चिकनी, अधिक प्राकृतिक आकृतियों के लिए मानक गोल आयतों के बजाय सुपरलिप्स का उपयोग करें</string>\n    <string name=\"shape_type\">आकार प्रकार</string>\n    <string name=\"cut\">काटना</string>\n    <string name=\"rounded\">गोल</string>\n    <string name=\"smooth\">चिकना</string>\n    <string name=\"cut_shapes_sub\">बिना गोलाई के तेज किनारे</string>\n    <string name=\"rounded_shapes_sub\">क्लासिक गोलाकार कोने</string>\n    <string name=\"shapes_type\">आकृतियाँ प्रकार</string>\n    <string name=\"corners_size\">कोनों का आकार</string>\n    <string name=\"squircle\">स्क्विर्कल</string>\n    <string name=\"squircle_shapes_sub\">सुंदर गोलाकार यूआई तत्व</string>\n    <string name=\"filename_format\">फ़ाइल नाम प्रारूप</string>\n    <string name=\"prefix_pattern_description\">फ़ाइल नाम की शुरुआत में कस्टम टेक्स्ट रखा गया है, जो प्रोजेक्ट नाम, ब्रांड या व्यक्तिगत टैग के लिए बिल्कुल उपयुक्त है।</string>\n    <string name=\"original_filename_pattern_description\">बिना एक्सटेंशन के मूल फ़ाइल नाम का उपयोग करता है, जिससे आपको स्रोत पहचान बरकरार रखने में मदद मिलती है।</string>\n    <string name=\"width_pattern_description\">पिक्सेल में छवि की चौड़ाई, रिज़ॉल्यूशन परिवर्तन या स्केलिंग परिणामों को ट्रैक करने के लिए उपयोगी है।</string>\n    <string name=\"height_pattern_description\">पिक्सेल में छवि की ऊंचाई, पहलू अनुपात या निर्यात के साथ काम करते समय सहायक होती है।</string>\n    <string name=\"random_numbers_pattern_description\">अद्वितीय फ़ाइल नामों की गारंटी के लिए यादृच्छिक अंक उत्पन्न करता है; डुप्लिकेट के विरुद्ध अतिरिक्त सुरक्षा के लिए अधिक अंक जोड़ें।</string>\n    <string name=\"sequence_number_pattern_description\">बैच निर्यात के लिए ऑटो-इंक्रीमेंटिंग काउंटर, एक सत्र में एकाधिक छवियों को सहेजते समय आदर्श।</string>\n    <string name=\"preset_info_pattern_description\">लागू प्रीसेट नाम को फ़ाइल नाम में सम्मिलित करता है ताकि आप आसानी से याद रख सकें कि छवि कैसे संसाधित की गई थी।</string>\n    <string name=\"scale_mode_pattern_description\">प्रसंस्करण के दौरान उपयोग किए गए छवि स्केलिंग मोड को प्रदर्शित करता है, जो आकार, क्रॉप या फिट की गई छवियों को अलग करने में मदद करता है।</string>\n    <string name=\"suffix_pattern_description\">फ़ाइल नाम के अंत में कस्टम टेक्स्ट रखा गया है, जो _v2, _edited, या _final जैसे संस्करण के लिए उपयोगी है।</string>\n    <string name=\"extension_pattern_description\">फ़ाइल एक्सटेंशन (पीएनजी, जेपीजी, वेबपी, आदि), स्वचालित रूप से वास्तविक सहेजे गए प्रारूप से मेल खाता है।</string>\n    <string name=\"formatted_timestamp_pattern_description\">एक अनुकूलन योग्य टाइमस्टैम्प जो आपको सही सॉर्टिंग के लिए जावा विनिर्देश द्वारा अपना स्वयं का प्रारूप परिभाषित करने देता है।</string>\n    <string name=\"fling_type\">फ़्लिंग प्रकार</string>\n    <string name=\"android_native\">एंड्रॉइड नेटिव</string>\n    <string name=\"ios_style\">आईओएस स्टाइल</string>\n    <string name=\"smooth_curve\">चिकना वक्र</string>\n    <string name=\"quick_stop\">जल्दी बंद</string>\n    <string name=\"bouncy\">Bouncy</string>\n    <string name=\"floaty\">हलका</string>\n    <string name=\"snappy\">तेज़</string>\n    <string name=\"ultra_smooth\">अत्यंत चिकना</string>\n    <string name=\"adaptive\">अनुकूली</string>\n    <string name=\"accessibility_aware\">अभिगम्यता जागरूक</string>\n    <string name=\"reduced_motion\">कम गति</string>\n    <string name=\"android_native_sub\">बेसलाइन तुलना के लिए मूल एंड्रॉइड स्क्रॉल भौतिकी</string>\n    <string name=\"smooth_sub\">सामान्य उपयोग के लिए संतुलित, सहज स्क्रॉलिंग</string>\n    <string name=\"ios_style_sub\">उच्च घर्षण आईओएस जैसा स्क्रॉल व्यवहार</string>\n    <string name=\"smooth_curve_sub\">विशिष्ट स्क्रॉल अनुभव के लिए अद्वितीय तख़्ता वक्र</string>\n    <string name=\"quick_stop_sub\">त्वरित रोक के साथ सटीक स्क्रॉलिंग</string>\n    <string name=\"bouncy_sub\">चंचल, प्रतिक्रियाशील उछालभरी स्क्रॉल</string>\n    <string name=\"floaty_sub\">सामग्री ब्राउज़िंग के लिए लंबी, फिसलती हुई स्क्रॉल</string>\n    <string name=\"snappy_sub\">इंटरैक्टिव यूआई के लिए त्वरित, प्रतिक्रियाशील स्क्रॉलिंग</string>\n    <string name=\"ultra_smooth_sub\">विस्तारित गति के साथ प्रीमियम सहज स्क्रॉलिंग</string>\n    <string name=\"adaptive_sub\">फ़्लिंग वेग के आधार पर भौतिकी को समायोजित करता है</string>\n    <string name=\"accessibility_aware_sub\">सिस्टम एक्सेसिबिलिटी सेटिंग्स का सम्मान करता है</string>\n    <string name=\"reduced_motion_sub\">पहुंच आवश्यकताओं के लिए न्यूनतम गति</string>\n    <string name=\"primary_lines\">प्राथमिक पंक्तियाँ</string>\n    <string name=\"primary_lines_sub\">प्रत्येक पाँचवीं पंक्ति में मोटी रेखा जोड़ता है</string>\n    <string name=\"fill_color\">रंग भरना</string>\n    <string name=\"hidden_tools\">छिपे हुए उपकरण</string>\n    <string name=\"hidden_for_share\">साझा करने के लिए छिपे हुए उपकरण</string>\n    <string name=\"color_library\">रंग पुस्तकालय</string>\n    <string name=\"color_library_sub\">रंगों का विशाल संग्रह ब्राउज़ करें</string>\n    <string name=\"model_fatality_deblur\">प्राकृतिक विवरण बनाए रखते हुए छवियों से धुंधलापन को तेज और हटा देता है, जो फोकस से बाहर की तस्वीरों को ठीक करने के लिए आदर्श है।</string>\n    <string name=\"model_unresize_v3\">खोए हुए विवरण और बनावट को पुनर्प्राप्त करते हुए, पहले से आकार बदल दी गई छवियों को बुद्धिमानी से पुनर्स्थापित करता है।</string>\n    <string name=\"model_liveaction_v1_span\">लाइव-एक्शन सामग्री के लिए अनुकूलित, संपीड़न कलाकृतियों को कम करता है और मूवी/टीवी शो फ्रेम में बारीक विवरण बढ़ाता है।</string>\n    <string name=\"model_vhs2hd_realplksr\">वीएचएस-गुणवत्ता वाले फ़ुटेज को एचडी में परिवर्तित करता है, टेप के शोर को हटाता है और पुराने अनुभव को संरक्षित करते हुए रिज़ॉल्यूशन को बढ़ाता है।</string>\n    <string name=\"model_text2hd_v1\">टेक्स्ट-भारी छवियों और स्क्रीनशॉट के लिए विशेषीकृत, अक्षरों को तेज़ करता है और पठनीयता में सुधार करता है।</string>\n    <string name=\"model_frankendata_pretrainer\">विविध डेटासेट पर प्रशिक्षित उन्नत अपस्केलिंग, सामान्य प्रयोजन फोटो एन्हांसमेंट के लिए उत्कृष्ट।</string>\n    <string name=\"model_realwebphoto_v2\">वेब-संपीड़ित फ़ोटो के लिए अनुकूलित, JPEG कलाकृतियों को हटाता है और प्राकृतिक स्वरूप को पुनर्स्थापित करता है।</string>\n    <string name=\"model_realwebphoto_v4\">बेहतर बनावट संरक्षण और कलाकृतियों में कमी के साथ वेब फ़ोटो के लिए उन्नत संस्करण।</string>\n    <string name=\"model_dat_2x\">डुअल एग्रीगेशन ट्रांसफार्मर तकनीक के साथ 2x अपस्केलिंग, तीक्ष्णता और प्राकृतिक विवरण बनाए रखता है।</string>\n    <string name=\"model_dat_3x\">उन्नत ट्रांसफॉर्मर आर्किटेक्चर का उपयोग करके 3x अपस्केलिंग, मध्यम विस्तार आवश्यकताओं के लिए आदर्श।</string>\n    <string name=\"model_dat_4x\">अत्याधुनिक ट्रांसफार्मर नेटवर्क के साथ 4x उच्च-गुणवत्ता वाला अपस्केलिंग, बड़े पैमाने पर बारीक विवरणों को संरक्षित करता है।</string>\n    <string name=\"model_nafnet_deblurring\">फ़ोटो से धुंधलापन/शोर और कंपन हटाता है। सामान्य प्रयोजन लेकिन तस्वीरों में सर्वोत्तम।</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">BSRGAN गिरावट के लिए अनुकूलित Swin2SR ट्रांसफार्मर का उपयोग करके निम्न-गुणवत्ता वाली छवियों को पुनर्स्थापित करता है। भारी संपीड़न कलाकृतियों को ठीक करने और 4x पैमाने पर विवरण बढ़ाने के लिए बढ़िया।</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">बीएसआरजीएएन गिरावट पर प्रशिक्षित स्विनआईआर ट्रांसफार्मर के साथ 4x अपस्केलिंग। फ़ोटो और जटिल दृश्यों में तेज़ बनावट और अधिक प्राकृतिक विवरण के लिए GAN का उपयोग करता है।</string>\n    <string name=\"path\">पथ</string>\n    <string name=\"merge_pdf\">पीडीएफ मर्ज करें</string>\n    <string name=\"merge_pdf_sub\">एकाधिक पीडीएफ फाइलों को एक दस्तावेज़ में संयोजित करें</string>\n    <string name=\"files_order\">फ़ाइलें आदेश</string>\n    <string name=\"pages_short\">पीपी.</string>\n    <string name=\"split_pdf\">पीडीएफ को विभाजित करें</string>\n    <string name=\"split_pdf_sub\">पीडीएफ दस्तावेज़ से विशिष्ट पृष्ठ निकालें</string>\n    <string name=\"rotate_pdf\">पीडीएफ घुमाएँ</string>\n    <string name=\"rotate_pdf_sub\">पेज ओरिएंटेशन को स्थायी रूप से ठीक करें</string>\n    <string name=\"pages\">पृष्ठों</string>\n    <string name=\"rearrange_pdf\">पीडीएफ को पुनर्व्यवस्थित करें</string>\n    <string name=\"rearrange_pdf_sub\">पृष्ठों को पुनः व्यवस्थित करने के लिए उन्हें खींचें और छोड़ें</string>\n    <string name=\"hold_drag_drop\">पेजों को पकड़ें और खींचें</string>\n    <string name=\"page_numbers\">पेज नंबर</string>\n    <string name=\"page_numbers_sub\">अपने दस्तावेज़ों में स्वचालित रूप से क्रमांकन जोड़ें</string>\n    <string name=\"label_format\">लेबल प्रारूप</string>\n    <string name=\"pdf_to_text\">पीडीएफ से टेक्स्ट (ओसीआर)</string>\n    <string name=\"pdf_to_text_sub\">अपने पीडीएफ दस्तावेजों से सादा पाठ निकालें</string>\n    <string name=\"watermark_pdf_sub\">ब्रांडिंग या सुरक्षा के लिए कस्टम टेक्स्ट को ओवरले करें</string>\n    <string name=\"signature\">हस्ताक्षर</string>\n    <string name=\"signature_sub\">किसी भी दस्तावेज़ में अपना इलेक्ट्रॉनिक हस्ताक्षर जोड़ें</string>\n    <string name=\"will_be_for_signature\">इसका उपयोग हस्ताक्षर के रूप में किया जाएगा</string>\n    <string name=\"unlock_pdf\">पीडीएफ अनलॉक करें</string>\n    <string name=\"unlock_pdf_sub\">अपनी सुरक्षित फ़ाइलों से पासवर्ड हटाएँ</string>\n    <string name=\"protect_pdf\">पीडीएफ को सुरक्षित रखें</string>\n    <string name=\"protect_pdf_sub\">अपने दस्तावेज़ों को मजबूत एन्क्रिप्शन के साथ सुरक्षित करें</string>\n    <string name=\"success\">सफलता</string>\n    <string name=\"pdf_unlocked\">पीडीएफ अनलॉक हो गया है, आप इसे सहेज सकते हैं या साझा कर सकते हैं</string>\n    <string name=\"repair_pdf\">पीडीएफ की मरम्मत करें</string>\n    <string name=\"repair_pdf_sub\">दूषित या अपठनीय दस्तावेज़ों को ठीक करने का प्रयास करें</string>\n    <string name=\"grayscale\">स्केल</string>\n    <string name=\"grayscale_pdf_sub\">सभी दस्तावेज़ एम्बेडेड छवियों को ग्रेस्केल में बदलें</string>\n    <string name=\"compress_pdf\">पीडीएफ को कंप्रेस करें</string>\n    <string name=\"compress_pdf_sub\">आसान साझाकरण के लिए अपने दस्तावेज़ फ़ाइल आकार को अनुकूलित करें</string>\n    <string name=\"repair_info\">ImageToolbox आंतरिक क्रॉस-रेफरेंस तालिका का पुनर्निर्माण करता है और फ़ाइल संरचना को स्क्रैच से पुनर्जीवित करता है। यह कई फ़ाइलों तक पहुंच बहाल कर सकता है जिन्हें \\\"खोला नहीं जा सकता\\\"</string>\n    <string name=\"grayscale_info\">यह टूल सभी दस्तावेज़ छवियों को ग्रेस्केल में परिवर्तित करता है। मुद्रण और फ़ाइल आकार को कम करने के लिए सर्वोत्तम</string>\n    <string name=\"metadata\">मेटाडाटा</string>\n    <string name=\"metadata_pdf_sub\">बेहतर गोपनीयता के लिए दस्तावेज़ गुणों को संपादित करें</string>\n    <string name=\"tags\">टैग</string>\n    <string name=\"producer\">निर्माता</string>\n    <string name=\"author\">लेखक</string>\n    <string name=\"keywords\">कीवर्ड</string>\n    <string name=\"creator\">निर्माता</string>\n    <string name=\"privacy_deep_clean\">प्राइवेसी डीप क्लीन</string>\n    <string name=\"privacy_deep_clean_sub\">इस दस्तावेज़ के लिए सभी उपलब्ध मेटाडेटा साफ़ करें</string>\n    <string name=\"page\">पेज</string>\n    <string name=\"deep_ocr\">गहरा ओसीआर</string>\n    <string name=\"deep_ocr_sub\">टेस्सेरैक्ट इंजन का उपयोग करके दस्तावेज़ से टेक्स्ट निकालें और उसे एक टेक्स्ट फ़ाइल में संग्रहीत करें</string>\n    <string name=\"cant_remove_all\">सभी पेज नहीं निकाले जा सकते</string>\n    <string name=\"remove_pages_pdf\">पीडीएफ पेज हटाएं</string>\n    <string name=\"remove_pages_pdf_sub\">पीडीएफ दस्तावेज़ से विशिष्ट पृष्ठ हटाएँ</string>\n    <string name=\"tap_to_remove\">हटाने के लिए टैप करें</string>\n    <string name=\"manually\">मैन्युअल</string>\n    <string name=\"crop_pdf\">पीडीएफ को काटें</string>\n    <string name=\"crop_pdf_sub\">दस्तावेज़ पृष्ठों को किसी भी सीमा तक काटें</string>\n    <string name=\"flatten_pdf\">पीडीएफ को समतल करें</string>\n    <string name=\"flatten_pdf_sub\">दस्तावेज़ पृष्ठों को व्यवस्थित करके पीडीएफ को अपरिवर्तनीय बनाएं</string>\n    <string name=\"camera_failed_to_open\">कैमरा प्रारंभ नहीं हो सका. कृपया अनुमतियाँ जांचें और सुनिश्चित करें कि इसका उपयोग किसी अन्य ऐप द्वारा नहीं किया जा रहा है।</string>\n    <string name=\"extract_images\">छवियाँ निकालें</string>\n    <string name=\"extract_images_sub\">पीडीएफ़ में एम्बेड की गई छवियों को उनके मूल रिज़ॉल्यूशन पर निकालें</string>\n    <string name=\"pdf_no_embedded\">इस पीडीएफ फाइल में कोई एम्बेडेड छवि नहीं है</string>\n    <string name=\"extract_images_info\">यह टूल प्रत्येक पृष्ठ को स्कैन करता है और पूर्ण-गुणवत्ता वाली स्रोत छवियां पुनर्प्राप्त करता है - दस्तावेज़ों से मूल को सहेजने के लिए बिल्कुल सही</string>\n    <string name=\"draw_signature\">हस्ताक्षर बनाएं</string>\n    <string name=\"pen_params\">पेन पैराम्स</string>\n    <string name=\"draw_signature_sub\">दस्तावेज़ों पर लगाने के लिए छवि के रूप में स्वयं के हस्ताक्षर का उपयोग करें</string>\n    <string name=\"zip_pdf\">ज़िप पीडीएफ</string>\n    <string name=\"zip_pdf_sub\">दिए गए अंतराल के साथ दस्तावेज़ को विभाजित करें और नए दस्तावेज़ों को ज़िप संग्रह में पैक करें</string>\n    <string name=\"interval\">अंतराल</string>\n    <string name=\"print_pdf\">पीडीएफ प्रिंट करें</string>\n    <string name=\"print_pdf_sub\">कस्टम पेज आकार के साथ मुद्रण के लिए दस्तावेज़ तैयार करें</string>\n    <string name=\"pages_per_sheet\">पत्र के अनुसार पृष्ठों</string>\n    <string name=\"orientation\">अभिविन्यास</string>\n    <string name=\"page_size\">पृष्ठ का आकार</string>\n    <string name=\"margin\">अंतर</string>\n    <string name=\"bloom\">खिलना</string>\n    <string name=\"soft_knee\">नरम घुटना</string>\n    <string name=\"model_realesr_animevideo_v3x4\">एनीमे और कार्टून के लिए अनुकूलित। बेहतर प्राकृतिक रंगों और कम कलाकृतियों के साथ तेजी से उन्नति</string>\n    <string name=\"one_ui_sub\">सैमसंग वन यूआई 7 जैसा स्टाइल</string>\n    <string name=\"calculate_hint\">वांछित मान की गणना करने के लिए यहां बुनियादी गणित प्रतीक दर्ज करें (उदाहरण के लिए (5+5)*10)</string>\n    <string name=\"math_expression\">गणित अभिव्यक्ति</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s तक छवियाँ उठाएँ</string>\n    <string name=\"keep_date_time\">दिनांक समय रखें</string>\n    <string name=\"keep_date_time_sub\">दिनांक और समय से संबंधित एक्सिफ़ टैग को हमेशा सुरक्षित रखें, एक्सिफ़ विकल्प को बनाए रखने से स्वतंत्र रूप से काम करता है</string>\n    <string name=\"background_color_for_alpha_formats\">अल्फ़ा प्रारूपों के लिए पृष्ठभूमि रंग</string>\n    <string name=\"background_color_for_alpha_formats_sub\">अल्फ़ा समर्थन के साथ प्रत्येक छवि प्रारूप के लिए पृष्ठभूमि रंग सेट करने की क्षमता जोड़ता है, अक्षम होने पर यह केवल गैर अल्फ़ा वाले के लिए उपलब्ध होता है</string>\n    <string name=\"open_markup_project\">ओपन प्रोजेक्ट</string>\n    <string name=\"open_markup_project_sub\">पहले से सहेजे गए छवि टूलबॉक्स प्रोजेक्ट का संपादन जारी रखें</string>\n    <string name=\"markup_project_open_failed\">छवि टूलबॉक्स प्रोजेक्ट खोलने में असमर्थ</string>\n    <string name=\"markup_project_missing_data\">इमेज टूलबॉक्स प्रोजेक्ट में प्रोजेक्ट डेटा गुम है</string>\n    <string name=\"markup_project_corrupted\">छवि टूलबॉक्स प्रोजेक्ट दूषित है</string>\n    <string name=\"unsupported_markup_project_version\">असमर्थित छवि टूलबॉक्स प्रोजेक्ट संस्करण: %1$d</string>\n    <string name=\"save_markup_project\">प्रोजेक्ट सहेजें</string>\n    <string name=\"save_markup_project_sub\">एक संपादन योग्य प्रोजेक्ट फ़ाइल में परतें, पृष्ठभूमि और संपादन इतिहास संग्रहीत करें</string>\n    <string name=\"failed_to_open\">खोलने में विफल</string>\n    <string name=\"ocr_write_to_searchable_pdf\">खोजने योग्य पीडीएफ में लिखें</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">छवि बैच से पाठ को पहचानें और छवि और चयन योग्य पाठ परत के साथ खोजने योग्य पीडीएफ को सहेजें</string>\n    <string name=\"layer_alpha\">परत अल्फा</string>\n    <string name=\"horizontal_flip\">क्षैतिज फ़्लिप</string>\n    <string name=\"vertical_flip\">लंबवत फ्लिप</string>\n    <string name=\"lock\">ताला</string>\n    <string name=\"add_shadow\">छाया जोड़ें</string>\n    <string name=\"shadow_color\">छाया रंग</string>\n    <string name=\"text_geometry\">पाठ ज्यामिति</string>\n    <string name=\"text_geometry_sub\">अधिक स्पष्ट शैलीकरण के लिए पाठ को फैलाएँ या तिरछा करें</string>\n    <string name=\"scale_x\">स्केल एक्स</string>\n    <string name=\"skew_x\">तिरछा एक्स</string>\n    <string name=\"remove_annotations\">एनोटेशन हटाएँ</string>\n    <string name=\"remove_annotations_sub\">पीडीएफ पृष्ठों से चयनित एनोटेशन प्रकार जैसे लिंक, टिप्पणियाँ, हाइलाइट्स, आकार या फॉर्म फ़ील्ड हटा दें</string>\n    <string name=\"annotation_link\">हाइपरलिंक</string>\n    <string name=\"annotation_file_attachment\">फ़ाइल अनुलग्नक</string>\n    <string name=\"annotation_line\">पंक्तियां</string>\n    <string name=\"annotation_popup\">पॉप अप</string>\n    <string name=\"annotation_stamp\">टिकटों</string>\n    <string name=\"annotation_shapes\">आकार</string>\n    <string name=\"annotation_text\">पाठ नोट्स</string>\n    <string name=\"annotation_text_markup\">टेक्स्ट मार्कअप</string>\n    <string name=\"annotation_widget\">प्रपत्र फ़ील्ड</string>\n    <string name=\"annotation_markup\">मार्कअप</string>\n    <string name=\"annotation_unknown\">अज्ञात</string>\n    <string name=\"annotations\">एनोटेशन</string>\n    <string name=\"ungroup\">असमूहीकृत</string>\n    <string name=\"add_shadow_sub\">कॉन्फ़िगर करने योग्य रंग और ऑफसेट के साथ परत के पीछे धुंधली छाया जोड़ें</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-hu/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"sharpen\">Élesítés</string>\n    <string name=\"palette\">Paletta</string>\n    <string name=\"size\">Méret%1$s</string>\n    <string name=\"image_not_saved_sub\">Ha most kilép, minden mentetlen változás el lesz veszve</string>\n    <string name=\"about_app\">Az appról</string>\n    <string name=\"halftone\">Féltónus</string>\n    <string name=\"images\">Képek: %d</string>\n    <string name=\"close\">Bezár</string>\n    <string name=\"save\">Mentés</string>\n    <string name=\"color_blue\">Kék</string>\n    <string name=\"distance\">Távolság</string>\n    <string name=\"no_palette\">Nem tudunk palettát készíteni ehez a képhez</string>\n    <string name=\"scale\">Méretezés</string>\n    <string name=\"load_image_from_net\">Web Kép Betöltése</string>\n    <string name=\"filter\">Szűrő</string>\n    <string name=\"reset\">Visszaállítás</string>\n    <string name=\"search_here\">Keresés itt</string>\n    <string name=\"effect\">Efekt</string>\n    <string name=\"compare\">Összevetés</string>\n    <string name=\"add_original_filename\">Adjon hozzá eredeti fájlnevet</string>\n    <string name=\"temperature\">Hőmérséklet</string>\n    <string name=\"surface\">Felszín</string>\n    <string name=\"blur\">Elmosás</string>\n    <string name=\"content_scale\">Tartalom méretezés</string>\n    <string name=\"gaussian_blur\">Gaussian Elmosás</string>\n    <string name=\"original\">Eredeti</string>\n    <string name=\"flexible_description\">Átméretezi a képeket úgy, hogy a hosszabbik oldaluk megfeleljen a megadott magasságnak vagy szélességnek. Minden méretbeli számítás a mentés után történik. A képek képaránya megmarad.</string>\n    <string name=\"no_image\">Nincs kép</string>\n    <string name=\"remove\">Eltávolítás</string>\n    <string name=\"app_closing\">Az App bezár</string>\n    <string name=\"tertiary\">Harmadlagos</string>\n    <string name=\"donation_sub\">Ez az app teljesen ingyenes, de ha szeretné, támogathatja a fejlesztését, ha ide kattint</string>\n    <string name=\"zoom\">Kép nagyítás</string>\n    <string name=\"hue\">Színárnyalat</string>\n    <string name=\"angle\">Szög</string>\n    <string name=\"alpha\">Átlátszóság</string>\n    <string name=\"pick_image_alt\">Kép kiválasztása</string>\n    <string name=\"replace_sequence_number\">Cserélje ki a sorszámot</string>\n    <string name=\"bulge\">Kidudorodás</string>\n    <string name=\"reset_image\">Kép visszaállítása</string>\n    <string name=\"slope\">Meredek</string>\n    <string name=\"dynamic_colors_sub\">Ha engedélyezett, az app színei követni fogják a háttérkép színeit</string>\n    <string name=\"negative\">Negatív</string>\n    <string name=\"height\">Magasság %1$s</string>\n    <string name=\"add_filter\">Szűrő hozzáadása</string>\n    <string name=\"color_green\">Zöld</string>\n    <string name=\"black_and_white\">Fekete-fehér</string>\n    <string name=\"clear\">Törlés</string>\n    <string name=\"app_closing_sub\">Tényleg be szeretné zárni az appot?</string>\n    <string name=\"grant\">Megadás</string>\n    <string name=\"clear_exif\">EXIF Törlése</string>\n    <string name=\"emoji\">Hangulatjel</string>\n    <string name=\"radius\">Sugár</string>\n    <string name=\"swirl\">Örvény</string>\n    <string name=\"device_storage\">Eszköztárhely</string>\n    <string name=\"restart_app\">App újraindítása</string>\n    <string name=\"pick_two_images\">Két kép kiválasztása a kezdéshez</string>\n    <string name=\"replace_sequence_number_sub\">Ha engedélyezett, kicseréli a hagyományos időbélyeget a kép sorszámára, ha kötegelt feldolgozást használ</string>\n    <string name=\"image_not_saved\">Mentés…</string>\n    <string name=\"emojis_count\">Hangulatjelek száma</string>\n    <string name=\"edit\">Szerkesztés</string>\n    <string name=\"unsupported_type\">Nem támogatott típus: %1$s</string>\n    <string name=\"update\">Frissítés</string>\n    <string name=\"pick_color\">Színválasztó</string>\n    <string name=\"gallery_picker\">Galléria</string>\n    <string name=\"kuwahara\">Kuwahara Lágyítás</string>\n    <string name=\"file_explorer_picker_sub\">Használja a GetContent intent-et a képválasztáshoz. Mindenhol működik, de valamely eszközökön hibás. ez nem a mi hibánk, és nem tudunk mit tenni ellene.</string>\n    <string name=\"keep_exif\">EXIF Megtartása</string>\n    <string name=\"folder\">Kimeneti mappa</string>\n    <string name=\"gallery_picker_sub\">Egyszerű galléria képválasztó. Csak akkor működik, ha van egy app, amely tud képet megadni</string>\n    <string name=\"highlights\">Megvilágítás</string>\n    <string name=\"unspecified\">Meghatározatlan</string>\n    <string name=\"filename\">Fájlnév</string>\n    <string name=\"help_translate_sub\">Javítson a fordításban vagy fordítson más nyelvekre</string>\n    <string name=\"light\">Világos</string>\n    <string name=\"pick_color_sub\">Szín kinyerése képből, másolás vagy megosztás</string>\n    <string name=\"bilaterial_blur\">Kétoldali elmosódás</string>\n    <string name=\"image\">Kép</string>\n    <string name=\"prefix\">Előtag</string>\n    <string name=\"presets\">Előbeállítások</string>\n    <string name=\"options_arrangement\">Opciók elrendezése</string>\n    <string name=\"tint\">Tinta</string>\n    <string name=\"filters\">Szűrők</string>\n    <string name=\"end\">Vége</string>\n    <string name=\"primary\">Elsődleges</string>\n    <string name=\"line_width\">Vonal szélesség</string>\n    <string name=\"start\">Kezdés</string>\n    <string name=\"delete_exif\">EXIF Törlése</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"fab_alignment\">FAB ilesztése</string>\n    <string name=\"version\">Verzió</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nincs mit beilleszteni</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">Ok</string>\n    <string name=\"order\">Sorolás</string>\n    <string name=\"monochrome\">Monokróm</string>\n    <string name=\"copied\">Másolva a vágólapra</string>\n    <string name=\"help_translate\">Segítsen a fordításban</string>\n    <string name=\"something_went_wrong\">Valami nem sikerült</string>\n    <string name=\"spacing\">Térköz</string>\n    <string name=\"pick_images\">Képek kiválasztása</string>\n    <string name=\"secondary\">Másodlagos</string>\n    <string name=\"box_blur\">Doboz elmosás</string>\n    <string name=\"cga_colorspace\">CGA Színtér</string>\n    <string name=\"distortion\">Torzítás</string>\n    <string name=\"emboss\">domborzat</string>\n    <string name=\"customization\">Testreszabás</string>\n    <string name=\"add_tag\">Címke hozzáadása</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Érvényes aRGB színkód beillesztése</string>\n    <string name=\"dynamic_colors\">Dinamikus színek</string>\n    <string name=\"photo_picker\">Képválasztó</string>\n    <string name=\"image_source\">Kép forrása</string>\n    <string name=\"contrast\">Kontraszt</string>\n    <string name=\"palette_sub\">Színpaletta minta létrehozása adott képből</string>\n    <string name=\"check_source_code_sub\">Töltse le a legújabb frissítést, jelezzen hibákat, és egyéb</string>\n    <string name=\"pick_image\">Válasszon képet a kezdéshez</string>\n    <string name=\"vibrance\">Élénkség</string>\n    <string name=\"issue_tracker_sub\">Hibajelentés és funkciókérés itt jelenthető</string>\n    <string name=\"allow_image_monet_sub\">Ha engedélyezett, képszerkesztéskor az app színei követik a kép színeit</string>\n    <string name=\"permission_sub\">Az app működéséhez és képek szerkesztéséhez engedély kell a Tárhely eléréséhez. kérjük adja meg az engedélyt a következő ablakban.</string>\n    <string name=\"filename_not_work_with_photopicker\">Az eredeti fájlnév nem adható hozzá, ha a képet képválasztóból választott képet</string>\n    <string name=\"color_filter\">Színszűrő</string>\n    <string name=\"by_bytes_resize\">Átméretezés Súly alapján</string>\n    <string name=\"clear_exif_sub\">A kép minden EXIF adata törölve lesz. Ez nem visszafordítható!</string>\n    <string name=\"sobel_edge\">Sobel-élek</string>\n    <string name=\"single_edit\">Egyedüli Szerkesztés</string>\n    <string name=\"solarize\">Megéget</string>\n    <string name=\"dilation\">Tágulás</string>\n    <string name=\"image_preview_sub\">Bármijen kép előnézete: GIF, SVG, és így tovább…</string>\n    <string name=\"color_copied\">Szín másolva</string>\n    <string name=\"flexible\">Rugalmas</string>\n    <string name=\"image_preview\">Kép Előnézet</string>\n    <string name=\"sepia\">Szépia</string>\n    <string name=\"values_reset\">Értékek sikeresen visszaállítva</string>\n    <string name=\"order_sub\">Meghatározza az eszközök sorrendjét a főképernyőn</string>\n    <string name=\"check_source_code\">Forráskód</string>\n    <string name=\"single_edit_sub\">Egy kép módosítása, átméretezése és szerkesztése</string>\n    <string name=\"dark\">Sötét</string>\n    <string name=\"width\">Szélesség %1$s</string>\n    <string name=\"emoji_sub\">Válassza ki, mely hangulatjel jelenjen meg a főképernyőn</string>\n    <string name=\"cancel\">Mégsem</string>\n    <string name=\"extension\">Fájlkiterjesztés</string>\n    <string name=\"no_updates\">Nem található frissítés</string>\n    <string name=\"stay\">Marad</string>\n    <string name=\"shadows\">Árnyékok</string>\n    <string name=\"reset_image_sub\">Kép változásai pontos értékekre fognak visszaállni</string>\n    <string name=\"failed_to_save\">%d kép mentése sikertelen</string>\n    <string name=\"amoled_mode\">Amoled mód</string>\n    <string name=\"sphere_refraction\">Gömbtörés</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Az alkalmazás színsémája nem módosítható, amíg a dinamikus színek be vannak kapcsolva</string>\n    <string name=\"add_file_size_sub\">Ha engedélyezett, hozzáadja a kép magasságát és szélességét a kép fájlnevéhez</string>\n    <string name=\"nothing_found_by_search\">Semmi nem található a keresésre</string>\n    <string name=\"delete_exif_sub\">EXIF Adat törlése bármennyi képnél</string>\n    <string name=\"border_thickness\">Határ vastagsága</string>\n    <string name=\"language\">Nyelv</string>\n    <string name=\"check_updates\">Frissítések keresése</string>\n    <string name=\"color_scheme\">Színséma</string>\n    <string name=\"smth_went_wrong\">Valami nem sikerült %1$s</string>\n    <string name=\"white_balance\">Fehéregyensúly</string>\n    <string name=\"def\">Alap</string>\n    <string name=\"generate_palette\">Paletta Generálása</string>\n    <string name=\"amoled_mode_sub\">Ha engedélyezett, a felszíni színek teljesen feketék lesznek Éjszakai módban</string>\n    <string name=\"file_explorer_picker\">Fájlkezelő</string>\n    <string name=\"issue_tracker\">Hiba követő</string>\n    <string name=\"check_updates_sub\">Ha engedélyezett, a frissítési ablak meg fog jelenni az app indításakor</string>\n    <string name=\"quality\">Minőség</string>\n    <string name=\"saturation\">Telítettség</string>\n    <string name=\"light_aka_illumination\">Fény</string>\n    <string name=\"permission\">Engedély</string>\n    <string name=\"settings\">Beállítások</string>\n    <string name=\"loading\">Betöltés…</string>\n    <string name=\"image_link\">Kép Linkje</string>\n    <string name=\"allow_image_monet\">Kép monet engedélyezése</string>\n    <string name=\"add_file_size\">Fájlméret megadása</string>\n    <string name=\"grant_permission_manual\">A működéshez szükség van erre az engedélyre. kérjük, adja meg manuálisan</string>\n    <string name=\"exception\">Kivétel</string>\n    <string name=\"max_bytes\">Maximum méret KB-ban</string>\n    <string name=\"explicit_description\">Átméretezi a képeket a megadott magasságra és szélességre. A képek képaránya megváltozhat.</string>\n    <string name=\"no_exif\">Nem található EXIF adat</string>\n    <string name=\"night_mode\">Éjszakai mód</string>\n    <string name=\"image_too_large_preview\">A kép túl nagy az előnézethez, a mentést így is megkisérlem</string>\n    <string name=\"load_image_from_net_sub\">Töltsön be képet az internetről, és szerkessze, nagyítsa, és mentse el ha akarja.</string>\n    <string name=\"system\">Rendszer</string>\n    <string name=\"brightness\">Fényesség</string>\n    <string name=\"by_bytes_resize_sub\">Kép átméretezése adott KB-méretet követve</string>\n    <string name=\"new_version\">Új verzió %1$s</string>\n    <string name=\"share\">Megosztás</string>\n    <string name=\"add\">Hozzáad</string>\n    <string name=\"monet_colors\">Monet színek</string>\n    <string name=\"crosshatch\">Sraffozás</string>\n    <string name=\"color_red\">Piros</string>\n    <string name=\"fill\">Kitőltés</string>\n    <string name=\"highlights_shadows\">Megvilágítás és árnyékok</string>\n    <string name=\"crop\">Körülvágás</string>\n    <string name=\"change_preview\">Előnézet megváltoztatása</string>\n    <string name=\"custom\">Saját</string>\n    <string name=\"external_storage\">Külső Tárhely</string>\n    <string name=\"edit_exif\">EXIF Módosítása</string>\n    <string name=\"filter_sub\">Szűrőláncok alkalmazása a képekre</string>\n    <string name=\"color\">Szín</string>\n    <string name=\"photo_picker_sub\">Modern Android képválasztó, amely a képernyő alján jelenik meg, és Android 12 fölött is működik. Rosszul tudja az EXIF adatot magával hozni</string>\n    <string name=\"values\">Értékek</string>\n    <string name=\"resize_type\">Átméretezés módja</string>\n    <string name=\"add_original_filename_sub\">Ha engedélyezett, hozzáadja az eredeti fájlnevet a kész kép fájlnevéhez</string>\n    <string name=\"compare_sub\">Két kép összevetése</string>\n    <string name=\"pick_accent_color\">Az app témája a választott színen fog alapulni</string>\n    <string name=\"original_filename\">EredetiFájlnév</string>\n    <string name=\"haze\">köd</string>\n    <string name=\"enhanced_glitch\">Továbbfejlesztett Glitch</string>\n    <string name=\"channel_shift_x\">Csatornaváltás X</string>\n    <string name=\"channel_shift_y\">Csatornaváltás Y</string>\n    <string name=\"corruption_size\">Korrupció mérete</string>\n    <string name=\"tent_blur\">Sátor Blur</string>\n    <string name=\"bottom\">Alsó</string>\n    <string name=\"strength\">Erő</string>\n    <string name=\"segmentation_mode_osd_only\">Tájolás &amp; Csak szkriptészlelés</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatikus tájolás &amp; Szkriptészlelés</string>\n    <string name=\"segmentation_mode_single_column\">Egyetlen oszlop</string>\n    <string name=\"segmentation_mode_circle_word\">Kör szó</string>\n    <string name=\"glitch\">Hiba</string>\n    <string name=\"amount\">Összeg</string>\n    <string name=\"seed\">Mag</string>\n    <string name=\"anaglyph\">Anaglif</string>\n    <string name=\"shuffle\">Keverés</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"images_overwritten\">A képek felülírva az eredeti célhelyen</string>\n    <string name=\"cannot_change_image_format\">Nem lehet módosítani a képformátumot, ha a fájlok felülírása opció engedélyezve van</string>\n    <string name=\"emoji_as_color_scheme\">Emoji színsémaként</string>\n    <string name=\"refractive_index\">Törésmutató</string>\n    <string name=\"glass_sphere_refraction\">Üveggömb fénytörés</string>\n    <string name=\"color_matrix\">Színes mátrix</string>\n    <string name=\"opacity\">Átlátszatlanság</string>\n    <string name=\"limits_resize\">Átméretezés Korlátok alapján</string>\n    <string name=\"limits_resize_sub\">A képek átméretezése a megadott magasságra és szélességre a képarány megtartása mellett</string>\n    <string name=\"sketch\">Vázlat</string>\n    <string name=\"threshold\">Küszöb</string>\n    <string name=\"quantizationLevels\">Kvantálási szintek</string>\n    <string name=\"smooth_toon\">Sima ton</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"rgb_filter\">RGB szűrő</string>\n    <string name=\"false_color\">Hamis szín</string>\n    <string name=\"first_color\">Első szín</string>\n    <string name=\"second_color\">Második szín</string>\n    <string name=\"blur_center_x\">Elmosódás középen x</string>\n    <string name=\"blur_center_y\">Elmosódás középen y</string>\n    <string name=\"zoom_blur\">Zoom elmosódás</string>\n    <string name=\"color_balance\">Színegyensúly</string>\n    <string name=\"luminance_threshold\">Fénysűrűség küszöb</string>\n    <string name=\"draw_on_image\">Rajzolj a képre</string>\n    <string name=\"draw_on_image_sub\">Válassz egy képet, és rajzolj rá valamit</string>\n    <string name=\"draw_on_background\">Rajzolj a háttérre</string>\n    <string name=\"draw_on_background_sub\">Válassza ki a háttérszínt, és rajzoljon rá</string>\n    <string name=\"background_color\">Háttérszín</string>\n    <string name=\"cipher_sub\">Bármilyen fájl titkosítása és visszafejtése (nem csak a kép) különféle elérhető titkosítási algoritmusok alapján</string>\n    <string name=\"pick_file\">Válasszon fájlt</string>\n    <string name=\"encrypt\">Titkosítás</string>\n    <string name=\"decrypt\">Dekódolás</string>\n    <string name=\"pick_file_to_start\">Az indításhoz válassza ki a fájlt</string>\n    <string name=\"decryption\">Dekódolás</string>\n    <string name=\"encryption\">Titkosítás</string>\n    <string name=\"key\">Kulcs</string>\n    <string name=\"implementation\">Végrehajtás</string>\n    <string name=\"implementation_sub\">AES-256, GCM mód, párnázás nélkül, alapértelmezettként 12 bájtos véletlenszerű IV-k. Igényelt algoritmus kiválasztható. A kulcsok 256 bites SHA-3 hash-ként vannak használva.</string>\n    <string name=\"compatibility\">Kompatibilitás</string>\n    <string name=\"features_sub\">Fájlok jelszó alapú titkosítása. A továbbhaladott fájlok a kiválasztott könyvtárban tárolhatók vagy megoszthatók. A visszafejtett fájlok közvetlenül is megnyithatók.</string>\n    <string name=\"file_size\">Fájl méret</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Érvénytelen jelszó vagy a kiválasztott fájl nincs titkosítva</string>\n    <string name=\"image_size_warning\">A kép megadott szélességgel és magassággal történő mentése memóriahiány hibát okozhat. Csak saját felelősségre.</string>\n    <string name=\"auto_cache_clearing\">Automatikus gyorsítótár törlése</string>\n    <string name=\"auto_cache_clearing_sub\">Ha engedélyezve van, az alkalmazás gyorsítótára törlődik az alkalmazás indításakor</string>\n    <string name=\"create\">Teremt</string>\n    <string name=\"tools\">Eszközök</string>\n    <string name=\"group_options_by_type_sub\">A főképernyőn megjelenő lehetőségeket típusuk szerint csoportosítja az egyéni listaelrendezés helyett</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Az elrendezés nem módosítható, ha az opciók csoportosítása engedélyezett</string>\n    <string name=\"secondary_customization\">Másodlagos testreszabás</string>\n    <string name=\"screenshot\">Képernyőkép</string>\n    <string name=\"fallback_option\">Tartalék opció</string>\n    <string name=\"skip\">Kihagyás</string>\n    <string name=\"copy\">Másolat</string>\n    <string name=\"warning_bytes\">A %1$s módban történő mentés instabil lehet, mivel ez veszteségmentes formátum</string>\n    <string name=\"randomize_filename\">Véletlenszerű fájlnév</string>\n    <string name=\"randomize_filename_sub\">Ha engedélyezve van, a kimeneti fájlnév teljesen véletlenszerű lesz</string>\n    <string name=\"image_crop_mask_sub\">Használja ezt a maszktípust a maszk létrehozásához az adott képből, figyelje meg, hogy alfa csatornával KELL rendelkeznie</string>\n    <string name=\"restore_sub\">Alkalmazásbeállítások visszaállítása a korábban létrehozott fájlból</string>\n    <string name=\"settings_restored\">A beállítások visszaállítása sikerült</string>\n    <string name=\"contact_me\">Keress meg</string>\n    <string name=\"reset_settings_sub\">Ezzel visszaállítja a beállításokat az alapértelmezett értékekre. Vegye figyelembe, hogy ez nem vonható vissza a feljebb említett biztonsági mentési fájl nélkül.</string>\n    <string name=\"delete\">Töröl</string>\n    <string name=\"delete_color_scheme_warn\">A kiválasztott színséma törlésére készül. Ez a művelet nem vonható vissza</string>\n    <string name=\"delete_color_scheme_title\">Séma törlése</string>\n    <string name=\"font\">Betűtípus</string>\n    <string name=\"text\">Szöveg</string>\n    <string name=\"font_scale\">Betűméret</string>\n    <string name=\"defaultt\">Alapértelmezett</string>\n    <string name=\"using_large_fonts_warn\">A nagy betűméretek használata UI-hibákat és problémákat okozhat, amelyeket nem javítunk ki. Óvatosan használja.</string>\n    <string name=\"alphabet_and_numbers\">Aa Áá Bb Cc Cs cs Dd Dz dz Dzs dzs Ee Éé Ff Gg Gy gy Hh Ii Íí Jj Kk Ll Ly ly Mm Nn Ny ny Oo Óó Öö Őő Pp Qq Rr Ss Sz sz Tt Ty ty Uu Úú Üü Űű Vv Ww Xx Yy Zz Zs zs 0123456789 !?</string>\n    <string name=\"emotions\">Érzelmek</string>\n    <string name=\"activities\">Tevékenységek</string>\n    <string name=\"background_remover\">Háttéreltávolító</string>\n    <string name=\"background_remover_sub\">Távolítsa el a hátteret a képről rajzolással, vagy használja az Auto opciót</string>\n    <string name=\"erase_mode\">Törlés mód</string>\n    <string name=\"erase_background\">Háttér törlése</string>\n    <string name=\"restore_background\">Háttér visszaállítása</string>\n    <string name=\"blur_radius\">Elmosási sugár</string>\n    <string name=\"pipette\">Pipetta</string>\n    <string name=\"draw_mode\">Rajz mód</string>\n    <string name=\"create_issue\">Probléma létrehozása</string>\n    <string name=\"something_went_wrong_emphasis\">Hoppá… Hiba történt. Írhat nekem az alábbi lehetőségek segítségével, és megpróbálok megoldást találni</string>\n    <string name=\"resize_and_convert\">Átméretezés és Konvertálás</string>\n    <string name=\"crashlytics_sub\">Ez lehetővé teszi az alkalmazás számára, hogy automatikusan gyűjtsön hibajelentéseket</string>\n    <string name=\"image_exif_warning\">Jelenleg a %1$s formátum csak az EXIF-metaadatok olvasását teszi lehetővé Androidon. Mentéskor a kimeneti képnek egyáltalán nem lesznek metaadatai.</string>\n    <string name=\"saving_almost_complete\">A mentés majdnem kész. A mostani lemondáshoz ismét mentésre lesz szükség.</string>\n    <string name=\"updates\">Frissítések</string>\n    <string name=\"draw_arrows\">Nyilak rajzolása</string>\n    <string name=\"draw_arrows_sub\">Ha engedélyezve van, a rajzi útvonal mutató nyílként jelenik meg</string>\n    <string name=\"brush_softness\">Ecset puhaság</string>\n    <string name=\"crop_description\">A képek középen a megadott méretre lesznek levágva. Ha a kép kisebb a megadott méreteknél, a vászon a megadott háttérszínnel bővül.</string>\n    <string name=\"donation\">Adomány</string>\n    <string name=\"image_stitching\">Képek Összeillesztése</string>\n    <string name=\"image_stitching_sub\">Kombinálja a megadott képeket, hogy egy nagyot kapjon</string>\n    <string name=\"pick_at_least_two_images\">Válasszon legalább 2 képet</string>\n    <string name=\"output_image_scale\">Kimeneti kép léptéke</string>\n    <string name=\"horizontal\">Vízszintes</string>\n    <string name=\"vertical\">Függőleges</string>\n    <string name=\"scale_small_images_to_large\">A kis képeket nagyra méretezheti</string>\n    <string name=\"scale_small_images_to_large_sub\">Ha engedélyezve van, a rendszer a kis képeket a sorozat legnagyobb méretére méretezi</string>\n    <string name=\"images_order\">Képek sorrendje</string>\n    <string name=\"regular\">Szabályos</string>\n    <string name=\"blur_edges\">Élek elmosása</string>\n    <string name=\"blur_edges_sub\">Elmosódott éleket rajzol az eredeti kép alá, hogy kitöltse a körülötte lévő tereket az egyetlen szín helyett, ha engedélyezve van</string>\n    <string name=\"diamond_pixelation\">Gyémánt pixelezés</string>\n    <string name=\"circle_pixelation\">Kör pixeláció</string>\n    <string name=\"enhanced_circle_pixelation\">Továbbfejlesztett kör pixelezés</string>\n    <string name=\"replace_color\">Cserélje ki a színt</string>\n    <string name=\"recode\">Átkódolni</string>\n    <string name=\"pixel_size\">Pixel méret</string>\n    <string name=\"lock_draw_orientation\">A rajzolás irányának rögzítése</string>\n    <string name=\"lock_draw_orientation_sub\">Ha rajz módban engedélyezve van, a képernyő nem forog</string>\n    <string name=\"check_for_updates\">Frissítések keresése</string>\n    <string name=\"palette_style\">Paletta stílus</string>\n    <string name=\"tonal_spot\">Tonális folt</string>\n    <string name=\"neutral\">Semleges</string>\n    <string name=\"vibrant\">Élénk</string>\n    <string name=\"expressive\">Kifejező</string>\n    <string name=\"rainbow\">Szivárvány</string>\n    <string name=\"fruit_salad\">Gyümölcssaláta</string>\n    <string name=\"fidelity\">Hűség</string>\n    <string name=\"content\">Tartalom</string>\n    <string name=\"neutral_sub\">Egy stílus, amely valamivel inkább kromatikus, mint a monokróm</string>\n    <string name=\"vibrant_sub\">Hangos téma, a színesség maximum az elsődleges palettánál, a többinél fokozott</string>\n    <string name=\"pdf_tools_sub\">Működtessen PDF fájlokkal: Előnézet, konvertálás képek köteggé, vagy hozzon létre egyet adott képekből</string>\n    <string name=\"preview_pdf\">PDF előnézete</string>\n    <string name=\"pdf_to_images\">PDF-ből képekre</string>\n    <string name=\"tonal_spot_sub\">Alapértelmezett palettastílus, lehetővé teszi mind a négy szín testreszabását, mások csak a kulcsszín beállítását teszik lehetővé</string>\n    <string name=\"pdf_to_images_sub\">Konvertálja a PDF-et képekké a megadott kimeneti formátumban</string>\n    <string name=\"mask_filter\">Maszk szűrő</string>\n    <string name=\"mask_filter_sub\">Alkalmazzon szűrőláncokat adott maszkolt területeken, minden maszkterület meghatározhatja a saját szűrőkészletét</string>\n    <string name=\"masks\">Maszkok</string>\n    <string name=\"add_mask\">Maszk hozzáadása</string>\n    <string name=\"mask_indexed\">Maszk %d</string>\n    <string name=\"mask_color\">Maszk színe</string>\n    <string name=\"mask_preview\">Maszk előnézete</string>\n    <string name=\"mask_preview_sub\">A megrajzolt szűrőmaszk a hozzávetőleges eredmény megjelenítéséhez</string>\n    <string name=\"inverse_fill_type\">Inverz kitöltési típus</string>\n    <string name=\"inverse_fill_type_sub\">Ha engedélyezve van, az összes nem maszkolt terület szűrésre kerül az alapértelmezett viselkedés helyett</string>\n    <string name=\"delete_mask_warn\">A kiválasztott szűrőmaszk törlésére készül. Ez a művelet nem vonható vissza</string>\n    <string name=\"full_filter\">Teljes Szűrő</string>\n    <string name=\"full_filter_sub\">Alkalmazzon bármilyen szűrőláncot adott képekre vagy egyetlen képre</string>\n    <string name=\"start_position\">Rajt</string>\n    <string name=\"center_position\">Központ</string>\n    <string name=\"end_position\">Vége</string>\n    <string name=\"simple_variants\">Egyszerű változatok</string>\n    <string name=\"highlighter\">Kiemelő</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Toll</string>\n    <string name=\"privacy_blur\">Privacy Blur</string>\n    <string name=\"highlighter_sub\">Rajzoljon félig átlátszó, éles kiemelő útvonalakat</string>\n    <string name=\"neon_sub\">Adjon valami izzó hatást a rajzaihoz</string>\n    <string name=\"pen_sub\">Alapértelmezett, legegyszerűbb – csak a szín</string>\n    <string name=\"privacy_blur_sub\">Elhomályosítja a képet a megrajzolt útvonal alatt, így mindent el szeretne rejteni</string>\n    <string name=\"buttons_shadow\">Gombok</string>\n    <string name=\"buttons_shadow_sub\">Árnyék rajzolása gombok mögé</string>\n    <string name=\"app_bars_shadow\">Alkalmazássávok</string>\n    <string name=\"app_bars_shadow_sub\">Árnyék rajzolása alkalmazásrácsok mögé</string>\n    <string name=\"value_in_range\">Érték a(z) %1$s–%2$s tartományban</string>\n    <string name=\"auto_rotate_limits\">Automata forgatás</string>\n    <string name=\"auto_rotate_limits_sub\">Lehetővé teszi a határdoboz alkalmazását a képtájoláshoz</string>\n    <string name=\"draw_path_mode\">Útvonal rajzolása mód</string>\n    <string name=\"line_arrow\">Vonal nyíl</string>\n    <string name=\"free_drawing_sub\">Bemeneti értékként rajzolja meg az útvonalat</string>\n    <string name=\"line_sub\">Az útvonalat a kezdőponttól a végpontig vonalként rajzolja meg</string>\n    <string name=\"line_arrow_sub\">A mutató nyilat a kezdőponttól a végpontig vonalként rajzolja</string>\n    <string name=\"arrow_sub\">Mutató nyíl rajzolása egy adott útvonal mentén</string>\n    <string name=\"double_line_arrow_sub\">Dupla mutató nyilat rajzol a kezdőponttól a végpontig vonalként</string>\n    <string name=\"outlined_rect\">Vázolt Rect</string>\n    <string name=\"oval\">Ovális</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"outlined_oval_sub\">A kiindulási ponttól a végpontig körvonalazott oválisan rajzol</string>\n    <string name=\"outlined_rect_sub\">A kezdőponttól a végpontig egyenesen körvonalazva rajzol</string>\n    <string name=\"lasso_sub\">Zárt kitöltött útvonalat rajzol adott útvonalonként</string>\n    <string name=\"rows_count\">Sorok száma</string>\n    <string name=\"columns_count\">Oszlopok száma</string>\n    <string name=\"no_such_directory\">Nem található \\\"%1$s\\\" könyvtár, átváltottuk az alapértelmezettre. Kérjük, mentse újra a fájlt</string>\n    <string name=\"auto_pin_sub\">Ha engedélyezve van, automatikusan hozzáadja a mentett képet a vágólapra</string>\n    <string name=\"vibration_strength\">Rezgés erőssége</string>\n    <string name=\"overwrite_file_requirements\">A fájlok felülírásához \\\"Explorer\\\" képforrást kell használnia, próbálja meg újra kiválasztani a képeket, a képforrást megváltoztattuk a szükségesre</string>\n    <string name=\"overwrite_files\">Fájlok felülírása</string>\n    <string name=\"only_clip_sub\">A tárhelyre mentés nem történik meg, a képet csak a vágólapra próbálja meg elhelyezni</string>\n    <string name=\"saved_to_original\">Fájl felülírva a következővel: %1$s az eredeti célhelyen</string>\n    <string name=\"magnifier_sub\">Engedélyezi a nagyítót az ujj tetején rajzi módokban a jobb hozzáférhetőség érdekében</string>\n    <string name=\"force_exif_widget_initial_value\">Kezdeti érték kényszerítése</string>\n    <string name=\"rate\">Mérték</string>\n    <string name=\"rate_app_sub\">Ez az alkalmazás teljesen ingyenes, ha azt szeretné, hogy nagyobb legyen, csillagozza meg a projektet a Githubon 😄</string>\n    <string name=\"segmentation_mode_auto_only\">Csak automata</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Egy blokkos függőleges szöveg</string>\n    <string name=\"segmentation_mode_single_block\">Egyetlen blokk</string>\n    <string name=\"segmentation_mode_single_line\">Egyvonalas</string>\n    <string name=\"segmentation_mode_single_word\">Egyetlen szó</string>\n    <string name=\"segmentation_mode_single_char\">Egyetlen karakter</string>\n    <string name=\"segmentation_mode_sparse_text\">Ritka szöveg</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Ritka szöveg tájolása &amp; Szkript észlelése</string>\n    <string name=\"segmentation_mode_raw_line\">Nyers vonal</string>\n    <string name=\"delete_language_sub\">Törölni szeretné a \\\"%1$s\\\" nyelv OCR betanítási adatait az összes felismerési típusnál, vagy csak egy kiválasztottnál (%2$s)?</string>\n    <string name=\"bayer_eight_dithering\">Bayer Nyolc Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes-féle ditherezés</string>\n    <string name=\"left_to_right_dithering\">Balról jobbra Dithering</string>\n    <string name=\"random_dithering\">Véletlenszerű dithering</string>\n    <string name=\"simple_threshold_dithering\">Egyszerű küszöb-dithering</string>\n    <string name=\"b_spline_sub\">A darabonként definiált bikubikus polinom függvényeket használja a görbe vagy felület zökkenőmentes interpolálásához és közelítéséhez, rugalmas és folytonos alakábrázoláshoz</string>\n    <string name=\"noise\">Zaj</string>\n    <string name=\"pixel_sort\">Pixel rendezés</string>\n    <string name=\"corruption_shift_x\">Korrupciós műszak X</string>\n    <string name=\"corruption_shift_y\">Korrupciós műszak Y</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">Oldal</string>\n    <string name=\"top\">Top</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmikus hangleképezés</string>\n    <string name=\"oil\">Olaj</string>\n    <string name=\"water_effect\">Víz hatás</string>\n    <string name=\"just_size\">Méret</string>\n    <string name=\"color_matrix_4x4\">Színes mátrix 4x4</string>\n    <string name=\"color_matrix_3x3\">Színes mátrix 3x3</string>\n    <string name=\"simple_effects\">Egyszerű effektusok</string>\n    <string name=\"deutaromaly\">Deuteranomália</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Éjszakai látás</string>\n    <string name=\"warm\">Meleg</string>\n    <string name=\"cool\">Menő</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Achromatomaly</string>\n    <string name=\"hot_summer\">Forró nyári</string>\n    <string name=\"purple_mist\">Lila köd</string>\n    <string name=\"sunrise\">Napkelte</string>\n    <string name=\"colorful_swirl\">Színes örvény</string>\n    <string name=\"soft_spring_light\">Puha tavaszi fény</string>\n    <string name=\"lemonade_light\">Limonádé fény</string>\n    <string name=\"night_magic\">Éjszakai varázslat</string>\n    <string name=\"electric_gradient\">Elektromos gradiens</string>\n    <string name=\"caramel_darkness\">Karamell sötétség</string>\n    <string name=\"futuristic_gradient\">Futurisztikus színátmenet</string>\n    <string name=\"rainbow_world\">Szivárványvilág</string>\n    <string name=\"deep_purple\">Mély lila</string>\n    <string name=\"icon_shape\">Ikon alakja</string>\n    <string name=\"cutoff\">Levág</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Átmenet</string>\n    <string name=\"peak\">Csúcs</string>\n    <string name=\"color_anomaly\">Szín anomália</string>\n    <string name=\"emoji_as_color_scheme_sub\">Az emoji elsődleges színét használja alkalmazás színsémaként a kézzel definiált helyett</string>\n    <string name=\"explicit\">Kifejezett</string>\n    <string name=\"crop_sub\">Vágja le a képet bármilyen határig</string>\n    <string name=\"email\">Email</string>\n    <string name=\"sequence_num\">szekvenciaNum</string>\n    <string name=\"fit\">Elfér</string>\n    <string name=\"exposure\">Kitettség</string>\n    <string name=\"laplacian\">laplaci</string>\n    <string name=\"vignette\">Címke</string>\n    <string name=\"stack_blur\">Stack blur</string>\n    <string name=\"posterize\">Plakátolni</string>\n    <string name=\"non_maximum_suppression\">Nem maximális elnyomás</string>\n    <string name=\"weak_pixel_inclusion\">Gyenge pixelbefoglalás</string>\n    <string name=\"lookup\">Nézz fel</string>\n    <string name=\"convolution3x3\">Konvolúció 3x3</string>\n    <string name=\"reorder\">Újrarendelés</string>\n    <string name=\"fast_blur\">Gyors elmosódás</string>\n    <string name=\"blur_size\">Elmosódás mérete</string>\n    <string name=\"activate_files\">Letiltotta a Fájlok alkalmazást, aktiválja a funkció használatához</string>\n    <string name=\"draw\">Húz</string>\n    <string name=\"draw_sub\">Rajzoljon a képre, mint egy vázlatfüzetben, vagy rajzoljon magára a háttérre</string>\n    <string name=\"paint_color\">Festék színe</string>\n    <string name=\"paint_alpha\">Alfa festék</string>\n    <string name=\"cipher\">Rejtjel</string>\n    <string name=\"file_proceed\">Fájl feldolgozva</string>\n    <string name=\"store_file_desc\">Tárolja ezt a fájlt az eszközén, vagy használja a megosztási műveletet, hogy bárhová elhelyezze</string>\n    <string name=\"features\">Jellemzők</string>\n    <string name=\"compatibility_sub\">Kérjük, vegye figyelembe, hogy a kompatibilitás más fájltitkosítási szoftverekkel vagy szolgáltatásokkal nem garantált. A kissé eltérő kulcskezelés vagy titkosítási konfiguráció összeférhetetlenséget okozhat.</string>\n    <string name=\"cache\">Gyorsítótár</string>\n    <string name=\"cache_size\">Gyorsítótár mérete</string>\n    <string name=\"found_s\">Talált: %1$s</string>\n    <string name=\"group_options_by_type\">Csoportosítsa a lehetőségeket típus szerint</string>\n    <string name=\"edit_screenshot\">Képernyőkép szerkesztése</string>\n    <string name=\"presets_sub\" formatted=\"false\">Ha a 125-ös beállítást választotta, a kép az eredeti kép 125%-os méretében lesz mentve. Ha az 50-es beállítást választja, akkor a kép 50%-os méretben lesz mentve.</string>\n    <string name=\"presets_sub_bytes\">A beállítás itt határozza meg a kimeneti fájl %-át, azaz ha az 50-es beállítást választja az 5 MB-os képen, akkor a mentés után 2,5 MB-os képet kap.</string>\n    <string name=\"saved_to\">Mentve %1$s mappába a következő névvel: %2$s</string>\n    <string name=\"saved_to_without_filename\">Mentve a(z) %1$s mappába</string>\n    <string name=\"tg_chat\">Telegram chat</string>\n    <string name=\"tg_chat_sub\">Beszélje meg az alkalmazást, és kérjen visszajelzést más felhasználóktól. Ott béta frissítéseket és betekintést is kaphat.</string>\n    <string name=\"crop_mask\">Termés maszk</string>\n    <string name=\"aspect_ratio\">Képarány</string>\n    <string name=\"backup_and_restore\">Mentés és visszaállítás</string>\n    <string name=\"backup\">biztonsági mentés</string>\n    <string name=\"restore\">visszaállítás</string>\n    <string name=\"backup_sub\">Készítsen biztonsági másolatot az alkalmazás beállításairól egy fájlba</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Sérült fájl vagy nem biztonsági másolat</string>\n    <string name=\"food_and_drink\">Étel és ital</string>\n    <string name=\"nature_and_animals\">Természet és állatok</string>\n    <string name=\"objects\">Objektumok</string>\n    <string name=\"symbols\">Szimbólumok</string>\n    <string name=\"enable_emoji\">Emoji engedélyezése</string>\n    <string name=\"travels_and_places\">Utazások és helyek</string>\n    <string name=\"trim_image\">Kép vágása</string>\n    <string name=\"keep_exif_sub\">A kép eredeti metaadatai megmaradnak</string>\n    <string name=\"trim_image_sub\">A kép körüli átlátszó terek le lesznek vágva</string>\n    <string name=\"auto_erase_background\">Háttér automatikus törlése</string>\n    <string name=\"restore_image\">Kép visszaállítása</string>\n    <string name=\"resize_and_convert_sub\">Módosítsa az adott képek méretét, vagy konvertálja őket más formátumba. Az EXIF metaadatok itt is szerkeszthetők, ha egyetlen képet választ.</string>\n    <string name=\"max_colors_count\">Max színszám</string>\n    <string name=\"analytics\">Analitika</string>\n    <string name=\"analytics_sub\">Anonim alkalmazáshasználati statisztikák gyűjtésének engedélyezése</string>\n    <string name=\"effort\">Erőfeszítés</string>\n    <string name=\"effort_sub\">A %1$s érték gyors tömörítést jelent, ami viszonylag nagy fájlméretet eredményez. Az %2$s lassabb tömörítést jelent, ami kisebb fájlt eredményez.</string>\n    <string name=\"wait\">Várjon</string>\n    <string name=\"allow_betas\">Béták engedélyezése</string>\n    <string name=\"allow_betas_sub\">A frissítések ellenőrzése az alkalmazás bétaverzióit is magában foglalja, ha engedélyezve van</string>\n    <string name=\"image_orientation\">Képtájolás</string>\n    <string name=\"pixelation\">Pixeláció</string>\n    <string name=\"enhanced_pixelation\">Továbbfejlesztett pixelezés</string>\n    <string name=\"stroke_pixelation\">Stroke Pixelation</string>\n    <string name=\"enhanced_diamond_pixelation\">Továbbfejlesztett gyémánt pixelezés</string>\n    <string name=\"tolerance\">Megértés</string>\n    <string name=\"color_to_replace\">Cserélni kívánt szín</string>\n    <string name=\"target_color\">Célszín</string>\n    <string name=\"color_to_remove\">Eltávolítandó szín</string>\n    <string name=\"remove_color\">Szín eltávolítása</string>\n    <string name=\"playful_scheme\">Játékos téma – a forrásszín árnyalata nem jelenik meg a témában</string>\n    <string name=\"monochrome_sub\">Monokróm téma, a színek tisztán fekete/fehér/szürke</string>\n    <string name=\"content_sub\">Egy séma, amely a forrásszínt a Scheme.primaryContainerben helyezi el</string>\n    <string name=\"fidelity_sub\">A tartalomsémához nagyon hasonló séma</string>\n    <string name=\"foss_update_checker_warning\">Ez a frissítés-ellenőrző csatlakozik a GitHubhoz, hogy ellenőrizze, van-e elérhető új frissítés</string>\n    <string name=\"attention\">Figyelem</string>\n    <string name=\"fading_edges\">Elhalványuló élek</string>\n    <string name=\"disabled\">Tiltva</string>\n    <string name=\"both\">Mindkét</string>\n    <string name=\"invert_colors\">Színek megfordítása</string>\n    <string name=\"invert_colors_sub\">Ha engedélyezve van, a téma színeit negatívra cseréli</string>\n    <string name=\"search_option\">Keresés</string>\n    <string name=\"search_option_sub\">Lehetővé teszi a keresést a főképernyőn elérhető összes eszköz között</string>\n    <string name=\"pdf_tools\">PDF-Eszközök</string>\n    <string name=\"images_to_pdf\">Képek PDF-be</string>\n    <string name=\"preview_pdf_sub\">Egyszerű PDF előnézet</string>\n    <string name=\"images_to_pdf_sub\">Csomagolja be a megadott képeket kimeneti PDF fájlba</string>\n    <string name=\"delete_mask\">Maszk törlése</string>\n    <string name=\"pixelation_sub\">Hasonló az adatvédelmi elmosódáshoz, de az elmosódás helyett pixeleket képez</string>\n    <string name=\"containers_shadow\">Konténerek</string>\n    <string name=\"containers_shadow_sub\">Árnyék rajzolása tárolók mögé</string>\n    <string name=\"sliders_shadow\">Csúszkák</string>\n    <string name=\"switches_shadow\">Kapcsolók</string>\n    <string name=\"fabs_shadow\">FAB-ok</string>\n    <string name=\"sliders_shadow_sub\">Árnyék rajzolása csúszkák mögé</string>\n    <string name=\"switches_shadow_sub\">Árnyék rajzolása kapcsolók mögé</string>\n    <string name=\"fabs_shadow_sub\">Árnyék rajzolása lebegő műveletgombok mögé</string>\n    <string name=\"double_line_arrow\">Dupla vonalú nyíl</string>\n    <string name=\"free_drawing\">Ingyenes rajz</string>\n    <string name=\"double_arrow\">Dupla nyíl</string>\n    <string name=\"arrow\">Nyíl</string>\n    <string name=\"line\">Vonal</string>\n    <string name=\"double_arrow_sub\">Dupla mutató nyilat rajzol egy adott útvonalról</string>\n    <string name=\"outlined_oval\">Vázolt ovális</string>\n    <string name=\"rect_sub\">Egyenesen rajzol a kezdőponttól a végpontig</string>\n    <string name=\"oval_sub\">Oválisan rajzol a kezdőponttól a végpontig</string>\n    <string name=\"lasso\">Lasszó</string>\n    <string name=\"free\">Ingyenes</string>\n    <string name=\"horizontal_grid\">Vízszintes rács</string>\n    <string name=\"vertical_grid\">Függőleges rács</string>\n    <string name=\"stitch_mode\">Stitch mód</string>\n    <string name=\"clipboard\">Vágólap</string>\n    <string name=\"auto_pin\">Auto pin</string>\n    <string name=\"vibration\">Rezgés</string>\n    <string name=\"overwrite_files_sub\">Az eredeti fájl a kiválasztott mappába való mentés helyett újra cserélődik</string>\n    <string name=\"empty\">Üres</string>\n    <string name=\"suffix\">Utótag</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anizotropikus Diffúzió</string>\n    <string name=\"diffusion\">Diffúzió</string>\n    <string name=\"conduction\">Vezetés</string>\n    <string name=\"horizontal_wind_stagger\">Vízszintes széllépcső</string>\n    <string name=\"fast_bilaterial_blur\">Gyors kétoldali életlenítés</string>\n    <string name=\"poisson_blur\">Poisson-Elmosás</string>\n    <string name=\"crystallize\">Kristályosítsd</string>\n    <string name=\"stroke_color\">Körvonal színe</string>\n    <string name=\"fractal_glass\">Fraktál üveg</string>\n    <string name=\"amplitude\">Amplitúdó</string>\n    <string name=\"marble\">Üveggolyó</string>\n    <string name=\"turbulence\">Légörvény</string>\n    <string name=\"frequency_x\">X frekvencia</string>\n    <string name=\"frequency_y\">Y frekvencia</string>\n    <string name=\"amplitude_x\">X amplitúdó</string>\n    <string name=\"amplitude_y\">Y amplitúdó</string>\n    <string name=\"perlin_distortion\">Perlin-torzítás</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Tónusleképezés</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"current\">Jelenlegi</string>\n    <string name=\"all\">Minden</string>\n    <string name=\"gradient_maker\">Átmenetkészítő</string>\n    <string name=\"gradient_maker_sub\">Adott kimeneti méretű színátmenet létrehozása testreszabott színekkel és megjelenéstípussal</string>\n    <string name=\"speed\">Sebesség</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"rate_app\">Értékeld az alkalmazást</string>\n    <string name=\"polaroid\">polaroid</string>\n    <string name=\"tritonomaly\">Tritanomalía</string>\n    <string name=\"protonomaly\">Protanomália</string>\n    <string name=\"vintage\">Szüret</string>\n    <string name=\"achromatopsia\">Achromatopsia</string>\n    <string name=\"gradient_type_linear\">Lineáris</string>\n    <string name=\"gradient_type_radial\">Sugárirányú</string>\n    <string name=\"gradient_type_sweep\">Söprés</string>\n    <string name=\"gradient_type\">Gradiens típusa</string>\n    <string name=\"center_x\">X központ</string>\n    <string name=\"center_y\">Y központ</string>\n    <string name=\"tile_mode\">Csempe mód</string>\n    <string name=\"tile_mode_repeated\">Megismételt</string>\n    <string name=\"tile_mode_mirror\">Tükör</string>\n    <string name=\"tile_mode_clamp\">Szorító</string>\n    <string name=\"tile_mode_decal\">Matrica</string>\n    <string name=\"color_stops\">Szín megáll</string>\n    <string name=\"add_color\">Szín hozzáadása</string>\n    <string name=\"properties\">Tulajdonságok</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Kvantifikátor</string>\n    <string name=\"gray_scale\">Szürke skála</string>\n    <string name=\"bayer_two_dithering\">Bayer Kettő Haladt</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Kétsoros Sierra dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Hamis Floyd Steinberg Dhering</string>\n    <string name=\"scale_mode\">Méretezési mód</string>\n    <string name=\"bilinear\">Bilineáris</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Remete</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Legközelebb</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Alapvető</string>\n    <string name=\"default_value\">Alapértelmezett érték</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Térbeli Szigma</string>\n    <string name=\"median_blur\">Medián elmosódás</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"bilinear_sub\">A lineáris (vagy bilineáris, kétdimenziós) interpoláció általában jó a kép méretének megváltoztatására, de a részletek nemkívánatos lágyulását okozza, és így is kissé szaggatott lehet.</string>\n    <string name=\"bicubic_sub\">A jobb skálázási módszerek közé tartozik a Lanczos újramintavételezés és a Mitchell-Netravali szűrők</string>\n    <string name=\"nearest_sub\">A méretnövelés egyik egyszerűbb módja, minden képpont lecserélése azonos színű pixelekre</string>\n    <string name=\"basic_sub\">A legegyszerűbb Android méretezési mód, amelyet szinte minden alkalmazásban használnak</string>\n    <string name=\"catmull_sub\">Módszer a vezérlőpontok halmazának zökkenőmentes interpolálására és újramintavételezésére, amelyet általában a számítógépes grafikában használnak sima görbék létrehozására</string>\n    <string name=\"hann_sub\">A jelfeldolgozásban gyakran alkalmazott ablakos funkció a spektrális szivárgás minimalizálása és a frekvenciaelemzés pontosságának javítása a jel széleinek szűkítésével</string>\n    <string name=\"hermite_sub\">Matematikai interpolációs technika, amely a görbeszakaszok végpontjain lévő értékeket és deriváltokat használja sima és folyamatos görbe létrehozásához</string>\n    <string name=\"lanczos_sub\">Újramintavételezési módszer, amely fenntartja a kiváló minőségű interpolációt súlyozott sinc függvény alkalmazásával a pixelértékekre</string>\n    <string name=\"mitchell_sub\">Újramintavételezési módszer, amely állítható paraméterekkel rendelkező konvolúciós szűrőt használ az élesség és az élsimítás közötti egyensúly eléréséhez a méretezett képen</string>\n    <string name=\"spline_sub\">A darabonként definiált polinom függvényeket használja a görbe vagy felület zökkenőmentes interpolálásához és közelítéséhez, rugalmas és folytonos alakábrázolást biztosítva</string>\n    <string name=\"only_clip\">Csak klip</string>\n    <string name=\"icon_shape_sub\">Hozzáad egy kiválasztott alakzatú tárolót az ikonok alá</string>\n    <string name=\"brightness_enforcement\">Fényerő Kényszerítése</string>\n    <string name=\"screen\">Képernyő</string>\n    <string name=\"gradient_maker_type_image\">Színátmenet</string>\n    <string name=\"gradient_maker_type_image_sub\">Tetszőleges átmenetet készít a megadott képek tetejére</string>\n    <string name=\"transformations\">Átváltozások</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Kép készítése kamerával. Ne feledje, hogy ebből a képforrásból lehet, hogy csak egy kép szerezhető</string>\n    <string name=\"grain\">Gabona</string>\n    <string name=\"unsharp\">Nem éles</string>\n    <string name=\"pastel\">Pasztell</string>\n    <string name=\"orange_haze\">Orange Haze</string>\n    <string name=\"pink_dream\">Rózsaszín álom</string>\n    <string name=\"golden_hour\">Arany óra</string>\n    <string name=\"autumn_tones\">Őszi hangok</string>\n    <string name=\"lavender_dream\">Levendula álom</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"spectral_fire\">Spektrális tűz</string>\n    <string name=\"fantasy_landscape\">Fantázia táj</string>\n    <string name=\"color_explosion\">Színrobbanás</string>\n    <string name=\"green_sun\">Zöld Nap</string>\n    <string name=\"space_portal\">Űrportál</string>\n    <string name=\"red_swirl\">Vörös Örvény</string>\n    <string name=\"digital_code\">Digitális kód</string>\n    <string name=\"watermarking\">Vízjelezés</string>\n    <string name=\"watermarking_sub\">Fedje le a képeket testreszabható szöveges/képes vízjelekkel</string>\n    <string name=\"repeat_watermark\">Ismételje meg a vízjelet</string>\n    <string name=\"repeat_watermark_sub\">Megismétli a vízjelet a kép felett, ahelyett, hogy egy adott pozícióban lenne</string>\n    <string name=\"offset_x\">X eltolás</string>\n    <string name=\"offset_y\">Eltolás Y</string>\n    <string name=\"watermark_type\">Vízjel típusa</string>\n    <string name=\"watermarking_image_sub\">Ezt a képet mintaként fogják használni a vízjelhez</string>\n    <string name=\"text_color\">Szöveg szín</string>\n    <string name=\"overlay_mode\">Overlay mód</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">GIF Eszközök</string>\n    <string name=\"gif_tools_sub\">Konvertálja a képeket GIF-képpé, vagy bontsa ki a kereteket az adott GIF-képből</string>\n    <string name=\"gif_type_to_image\">GIF a képekhez</string>\n    <string name=\"gif_type_to_image_sub\">Konvertálja a GIF fájlt képek kötegévé</string>\n    <string name=\"gif_type_to_gif_sub\">Kötegelt képek konvertálása GIF-fájlba</string>\n    <string name=\"gif_type_to_gif\">Képek GIF-be</string>\n    <string name=\"select_gif_image_to_start\">A kezdéshez válassza ki a GIF-képet</string>\n    <string name=\"use_size_of_first_frame\">Használja az Első keret méretét</string>\n    <string name=\"use_size_of_first_frame_sub\">Cserélje ki a megadott méretet az első keret méretére</string>\n    <string name=\"repeat_count\">Ismételje meg a Számlálást</string>\n    <string name=\"frame_delay\">Képkocka késleltetés</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Használd a Lassót</string>\n    <string name=\"use_lasso_sub\">A Lasso-t használja, mint a rajz módban a törléshez</string>\n    <string name=\"original_image_preview_alpha\">Eredeti kép előnézete Alpha</string>\n    <string name=\"random_emojis_sub\">Az alkalmazás sávjának hangulatjele véletlenszerűen fog változni</string>\n    <string name=\"random_emojis\">Véletlenszerű Hangulatjelek</string>\n    <string name=\"random_emojis_error\">Véletlenszerű hangulatjelek nem használhatóak, ha a hangulatjelek ki vannak kapcsolva</string>\n    <string name=\"emoji_selection_error\">Nem lehet hangulatjelet kiválasztani, ha a véletlenszerű hangulatjelek be vannak kapcsolva</string>\n    <string name=\"old_tv\">Régi Tv</string>\n    <string name=\"shuffle_blur\">Véletlenszerű elhomályosítás</string>\n    <string name=\"recognize_text\">OCR (szövegfelismerés)</string>\n    <string name=\"recognize_text_sub\">Szöveg felismerése az adott képről, több mint 120 nyelv támogatott</string>\n    <string name=\"picture_has_no_text\">A képen nincs szöveg, vagy az alkalmazás nem találta meg</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Felismerés típusa</string>\n    <string name=\"fast\">Gyors</string>\n    <string name=\"standard\">Alapértelmezett</string>\n    <string name=\"best\">Legjobb</string>\n    <string name=\"no_data\">Nincs adat</string>\n    <string name=\"download_description\">A Tesseract OCR megfelelő működéséhez további edzésadatokat (%1$s) kell letölteni eszközére. \\nSzeretne letölteni %2$s adatokat?</string>\n    <string name=\"download\">Letöltés</string>\n    <string name=\"no_connection\">Nincs kapcsolat, ellenőrizze, és próbálja újra a vonatmodellek letöltéséhez</string>\n    <string name=\"downloaded_languages\">Letöltött nyelvek</string>\n    <string name=\"available_languages\">Elérhető nyelvek</string>\n    <string name=\"segmentation_mode\">Szegmentációs mód</string>\n    <string name=\"restore_background_sub\">Az ecset törlés helyett a hátteret állítja vissza</string>\n    <string name=\"use_pixel_switch\">Használja a Pixel Switchet</string>\n    <string name=\"use_pixel_switch_sub\">Google Pixel-szerű kapcsolót használ</string>\n    <string name=\"slide\">Csúszik</string>\n    <string name=\"side_by_side\">Egymás mellett</string>\n    <string name=\"toggle_tap\">Koppintás Váltó</string>\n    <string name=\"transparency\">Átláthatóság</string>\n    <string name=\"magnifier\">Nagyító</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Az exif widgetet kezdetben ellenőrizni kényszeríti</string>\n    <string name=\"allow_multiple_languages\">Több nyelv engedélyezése</string>\n    <string name=\"favorite\">Kedvenc</string>\n    <string name=\"no_favorite_filters\">Még nincsenek kedvenc szűrők hozzáadva</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"native_stack_blur\">Natív Stack Blur</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"confetti\">Konfetti</string>\n    <string name=\"confetti_sub\">A konfetti mentés, megosztás és egyéb elsődleges műveletek esetén megjelenik</string>\n    <string name=\"secure_mode\">Biztonságos Mód</string>\n    <string name=\"secure_mode_sub\">Elrejti az alkalmazás tartalmát a legutóbbi alkalmazások listán. A tartalom nem rögzíthető és nem készíthető róla képernyőkép.</string>\n    <string name=\"exit\">Kijárat</string>\n    <string name=\"preview_closing\">Ha most kilép az előnézetből, újra hozzá kell adnia a képeket</string>\n    <string name=\"image_format\">Képformátum</string>\n    <string name=\"dark_colors\">Sötét Színek</string>\n    <string name=\"material_you_sub\">Létrehoz\\\" Material You \\\" paletta kép</string>\n    <string name=\"dark_colors_sub\">Éjszakai mód színsémát használ a fényváltozat helyett</string>\n    <string name=\"copy_as_compose_code\">Másolás \\\"Jetpack Compose\\\" kódként</string>\n    <string name=\"ring_blur\">Gyűrű Elmosódás</string>\n    <string name=\"circle_blur\">Körkörös Elmosódás</string>\n    <string name=\"star_blur\">Vezetés Elmosódás</string>\n    <string name=\"cross_blur\">Kereszt Elmosódás</string>\n    <string name=\"linear_tilt_shift\">Lineáris Dőléseltolás</string>\n    <string name=\"tags_to_remove\">Az Eltávolítandó Címkék</string>\n    <string name=\"apng_tools\">APNG Eszközök</string>\n    <string name=\"apng_tools_sub\">Konvertálja a képeket APNG-képpé, vagy bontsa ki a kereteket az adott APNG-képből</string>\n    <string name=\"apng_type_to_image\">APNG a képekhez</string>\n    <string name=\"apng_type_to_apng_sub\">Kötegelt képek konvertálása APNG-fájlba</string>\n    <string name=\"select_apng_image_to_start\">A kezdéshez válassza az APNG-képet</string>\n    <string name=\"motion_blur\">Elmosódás</string>\n    <string name=\"apng_type_to_image_sub\">APNG-fájl konvertálása képek kötegévé</string>\n    <string name=\"apng_type_to_apng\">Képek APNG-be</string>\n    <string name=\"zip\">Postai irányítószám</string>\n    <string name=\"zip_sub\">Zip fájl létrehozása adott fájlokból vagy képekből</string>\n    <string name=\"drag_handle_width\">Húzza Fogantyú Szélesség</string>\n    <string name=\"try_again\">Újrapróbálkozás</string>\n    <string name=\"switch_type\">Kapcsolótípus</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF képek átalakítása JXL animált képekké</string>\n    <string name=\"no_permissions\">Nincsenek engedélyek</string>\n    <string name=\"embedded_picker\">Beágyazott Választó</string>\n    <string name=\"pick\">Kiválasztás</string>\n    <string name=\"rain\">Eső</string>\n    <string name=\"jxl_type_to_jpeg\">JXL → JPEG</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG → JXL</string>\n    <string name=\"lanczos_bessel_sub\">Átmintavételezési módszer, amely magas minőségű interpolációt biztosít a pixelértékekre alkalmazott Bessel (jinc) függvénnyel</string>\n    <string name=\"gif_type_to_jxl\">GIF → JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG → JXL</string>\n    <string name=\"jxl_type_to_images\">JXL → Képek</string>\n    <string name=\"jxl_type_to_images_sub\">JXL animáció átalakítása képek sorozatává</string>\n    <string name=\"jxl_type_to_jxl\">Képek → JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Képsorozat átalakítása JXL animációvá</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG képek átalakítása JXL animált képekké</string>\n    <string name=\"behavior\">Viselkedés</string>\n    <string name=\"skip_file_picking_sub\">A fájlválasztó azonnal megjelenik, ha ez lehetséges a kiválasztott képernyőn</string>\n    <string name=\"lossy_compression_sub\">Veszteséges tömörítést használ a fájl méretének csökkentésére veszteségmentes helyett</string>\n    <string name=\"compression_type\">Tömörítési típus</string>\n    <string name=\"sorting\">Rendezés</string>\n    <string name=\"sort_by_date\">Dátum</string>\n    <string name=\"sort_by_date_reversed\">Dátum (fordított)</string>\n    <string name=\"sort_by_name\">Név</string>\n    <string name=\"sort_by_name_reversed\">Név (fordított)</string>\n    <string name=\"channels_configuration\">Csatornabeállítások</string>\n    <string name=\"header_today\">Ma</string>\n    <string name=\"header_yesterday\">Tegnap</string>\n    <string name=\"request\">Kérés</string>\n    <string name=\"pick_single_media\">Egyetlen média kiválasztása</string>\n    <string name=\"fullscreen_settings\">Teljes képernyős beállítások</string>\n    <string name=\"fullscreen_settings_sub\">Ezt bekapcsolva a beállítások oldal mindig teljes képernyőn nyílik meg a húzható menü helyett</string>\n    <string name=\"compose\">Összeállítás</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"use_sampled_palette\">Mintavételezett paletta használata</string>\n    <string name=\"use_sampled_palette_sub\">Ha ez az opció be van kapcsolva, a kvantálási paletta mintavételezve lesz</string>\n    <string name=\"path_omit\">Útvonal kihagyása</string>\n    <string name=\"min_color_ratio\">Minimális színarány</string>\n    <string name=\"lines_threshold\">Vonal küszöbérték</string>\n    <string name=\"quadratic_threshold\">Kvadratikus küszöbérték</string>\n    <string name=\"path_scale\">Útvonal méretezése</string>\n    <string name=\"reset_properties\">Tulajdonságok visszaállítása</string>\n    <string name=\"detailed\">Részletes</string>\n    <string name=\"default_line_width\">Alapértelmezett vonalszélesség</string>\n    <string name=\"confetti_type\">Konfetti Típus</string>\n    <string name=\"explode\">Robban</string>\n    <string name=\"jxl_tools\">JXL Eszközök</string>\n    <string name=\"harmonization_color\">Harmonizációs Szín</string>\n    <string name=\"lossy_compression\">Veszteséges Tömörítés</string>\n    <string name=\"material_you_switch_sub\">Egy Material You kapcsoló</string>\n    <string name=\"fluent_switch_sub\">Egy a \\\"Fluent\\\" dizájnrendszeren alapuló kapcsoló</string>\n    <string name=\"cupertino_switch_sub\">Egy a \\\"Cupertino\\\" dizájnrendszeren alapuló kapcsoló</string>\n    <string name=\"images_to_svg\">Képek → SVG</string>\n    <string name=\"downscale_image_sub\">A kép feldolgozás előtt kisebb méretre lesz lekicsinyítve, ami segíti az eszköz gyorsabb és biztonságosabb működését</string>\n    <string name=\"resize_anchor\">Átméretezés kiindulópontja</string>\n    <string name=\"max\">Maximum</string>\n    <string name=\"select_jxl_image_to_start\">Válasszon egy JXL képet a kezdéshez</string>\n    <string name=\"festive\">Ünnepi</string>\n    <string name=\"jxl_tools_sub\">Végezzen JXL és JPEG közötti átkódolást minőségromlás nélkül, vagy konvertálja a GIF/APNG fájlokat JXL animációvá</string>\n    <string name=\"auto_paste\">Automatikus beillesztés</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordináták kerekítési tűrése</string>\n    <string name=\"corners\">Sarkok</string>\n    <string name=\"embedded_picker_sub\">Az Image Toolbox képkiválasztója</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"downscale_image\">Kép lekicsinyítése</string>\n    <string name=\"auto_paste_sub\">Engedélyezi az alkalmazás számára, hogy automatikusan beillessze a vágólap tartalmát, így az megjelenik a főképernyőn, és feldolgozhatóvá válik</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Végezzen veszteségmentes átkódolást JXL-ről JPEG-re</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Végezzen veszteségmentes átkódolást JPEG-ről JXL-re</string>\n    <string name=\"fast_gaussian_blur_2d\">Gyors 2D Gauss-elmosás</string>\n    <string name=\"fast_gaussian_blur_3d\">Gyors 3D Gauss-elmosás</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"reset_properties_sub\">Minden tulajdonság vissza lesz állítva az alapértelmezett értékre. Figyelem, ez a művelet nem vonható vissza</string>\n    <string name=\"svg_warning\">Ennek az eszköznek a használata nagy képek nyomkövetésére lekicsinyítés nélkül nem ajánlott, mert összeomláshoz vezethet és megnövelheti a feldolgozási időt</string>\n    <string name=\"skip_file_picking\">Fájlválasztás kihagyása</string>\n    <string name=\"pick_multiple_media\">Több média kiválasztása</string>\n    <string name=\"show_settings_in_landscape\">Beállítások megjelenítése fekvő módban</string>\n    <string name=\"generate_previews\">Előnézetek generálása</string>\n    <string name=\"generate_previews_sub\">Előnézet-generálás engedélyezése, ez segíthet elkerülni az összeomlásokat bizonyos eszközökön, viszont ezzel egyidejűleg az önálló szerkesztési mód használata közben néhány funkció nem lesz elérhető</string>\n    <string name=\"harmonization_level\">Harmonizációs Szint</string>\n    <string name=\"images_to_svg_sub\">Megadott képek átrajzolása SVG képekké</string>\n    <string name=\"show_settings_in_landscape_sub\">Ha ez ki van kapcsolva, akkor fekvő módban a beállítások a felső alkalmazássáv gombjából nyílnak meg, mint mindig, ahelyett, hogy folyamatosan láthatóak lennének</string>\n    <string name=\"fast_gaussian_blur_4d\">Gyors 4D Gauss-elmosás</string>\n    <string name=\"speed_sub\">Az eredményül kapott kép dekódolási sebességét szabályozza, ami segíthet a kész kép gyorsabb megnyitásában. A %1$s érték a leglassabb dekódolást jelenti, míg a %2$s a leggyorsabbat. Ez a beállítás megnövelheti a kimeneti kép méretét</string>\n    <string name=\"compose_switch_sub\">Egy Jetpack Compose Material You kapcsoló</string>\n    <string name=\"engine_mode\">Motor Mód</string>\n    <string name=\"legacy\">Örökölt</string>\n    <string name=\"lstm_network\">LSTM hálózat</string>\n    <string name=\"legacy_and_lstm\">Örökölt &amp; LSTM</string>\n    <string name=\"convert\">Átalakítás</string>\n    <string name=\"convert_sub\">Képkötegek átalakítása adott formátumra</string>\n    <string name=\"add_new_folder\">Új Mappa Létrehozása</string>\n    <string name=\"tag_bits_per_sample\">Bitek Mintánként</string>\n    <string name=\"tag_compression\">Tömörítés</string>\n    <string name=\"tag_photometric_interpretation\">Fotometriai értelmezés</string>\n    <string name=\"tag_samples_per_pixel\">Minták Per Pixel</string>\n    <string name=\"tag_planar_configuration\">Sík Beállítás</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sub Mintázás</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Elhelyezés</string>\n    <string name=\"tag_x_resolution\">X Felbontás</string>\n    <string name=\"tag_y_resolution\">Y Felbontás</string>\n    <string name=\"tag_resolution_unit\">Felbontás Mértékegység</string>\n    <string name=\"tag_strip_offsets\">Strip Offsets</string>\n    <string name=\"tag_rows_per_strip\">Sorok csíkonként</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG csereformátum</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG csereformátum hossza</string>\n    <string name=\"tag_transfer_function\">Átviteli funkció</string>\n    <string name=\"tag_white_point\">Fehér Pont</string>\n    <string name=\"tag_primary_chromaticities\">Elsődleges kromatika</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr együtthatók</string>\n    <string name=\"tag_reference_black_white\">Referencia Fekete-fehér</string>\n    <string name=\"tag_datetime\">Dátum Idő</string>\n    <string name=\"tag_image_description\">Kép leírása</string>\n    <string name=\"tag_make\">Készíts</string>\n    <string name=\"tag_model\">Modell</string>\n    <string name=\"tag_software\">Szoftver</string>\n    <string name=\"tag_artist\">Művész</string>\n    <string name=\"tag_copyright\">Szerzői jog</string>\n    <string name=\"tag_exif_version\">Exif verzió</string>\n    <string name=\"tag_flashpix_version\">Flashpix verzió</string>\n    <string name=\"tag_color_space\">Színtér</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y méret</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Tömörített bit/pixel</string>\n    <string name=\"tag_maker_note\">Készítő megjegyzés</string>\n    <string name=\"tag_user_comment\">Felhasználói megjegyzés</string>\n    <string name=\"tag_related_sound_file\">Kapcsolódó hangfájl</string>\n    <string name=\"tag_datetime_original\">Dátum Idő Eredeti</string>\n    <string name=\"tag_datetime_digitized\">Dátum Idő digitalizálás</string>\n    <string name=\"tag_offset_time\">Eltolási idő</string>\n    <string name=\"tag_offset_time_original\">Eltolási idő eredeti</string>\n    <string name=\"tag_offset_time_digitized\">Eltolási idő digitalizálva</string>\n    <string name=\"tag_subsec_time\">Sub Sec Time</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Time Eredeti</string>\n    <string name=\"tag_subsec_time_digitized\">Sub Sec Time Digitalizálva</string>\n    <string name=\"tag_exposure_time\">Kitettségi idő</string>\n    <string name=\"tag_f_number\">F Szám</string>\n    <string name=\"tag_exposure_program\">Expozíciós program</string>\n    <string name=\"tag_spectral_sensitivity\">Spektrális érzékenység</string>\n    <string name=\"tag_photographic_sensitivity\">Fényképérzékenység</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Érzékenység típusa</string>\n    <string name=\"tag_standard_output_sensitivity\">Normál kimeneti érzékenység</string>\n    <string name=\"tag_recommended_exposure_index\">Ajánlott expozíciós index</string>\n    <string name=\"tag_iso_speed\">ISO Speed</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Speed ​​Latitude yyyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Speed ​​Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Zársebesség értéke</string>\n    <string name=\"tag_aperture_value\">Rekesznyílás értéke</string>\n    <string name=\"tag_brightness_value\">Fényerő érték</string>\n    <string name=\"tag_exposure_bias_value\">Expozíciós torzítás értéke</string>\n    <string name=\"tag_max_aperture_value\">Maximális rekeszérték</string>\n    <string name=\"tag_subject_distance\">Tárgy távolság</string>\n    <string name=\"tag_metering_mode\">Mérési mód</string>\n    <string name=\"tag_flash\">Vaku</string>\n    <string name=\"tag_subject_area\">Témakör</string>\n    <string name=\"tag_focal_length\">Gyújtótávolság</string>\n    <string name=\"tag_flash_energy\">Flash energia</string>\n    <string name=\"tag_spatial_frequency_response\">Térbeli frekvenciaválasz</string>\n    <string name=\"tag_focal_plane_x_resolution\">X fókuszsík felbontás</string>\n    <string name=\"tag_focal_plane_y_resolution\">Y fókuszsík felbontása</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Fókuszsík-felbontási egység</string>\n    <string name=\"tag_subject_location\">Tárgy helye</string>\n    <string name=\"tag_exposure_index\">Expozíciós index</string>\n    <string name=\"tag_sensing_method\">Érzékelési módszer</string>\n    <string name=\"tag_file_source\">Fájlforrás</string>\n    <string name=\"tag_cfa_pattern\">CFA minta</string>\n    <string name=\"tag_custom_rendered\">Egyedi renderelt</string>\n    <string name=\"tag_exposure_mode\">Expozíciós mód</string>\n    <string name=\"tag_white_balance\">Fehéregyensúly</string>\n    <string name=\"tag_digital_zoom_ratio\">Digitális zoom arány</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Fókusztávolság 35 mm-es filmben</string>\n    <string name=\"tag_scene_capture_type\">Jelenet rögzítési típusa</string>\n    <string name=\"tag_gain_control\">Szerezze meg az irányítást</string>\n    <string name=\"tag_contrast\">Kontraszt</string>\n    <string name=\"tag_saturation\">Telítettség</string>\n    <string name=\"tag_sharpness\">Élesség</string>\n    <string name=\"tag_device_setting_description\">Eszközbeállítás leírása</string>\n    <string name=\"tag_subject_distance_range\">Tárgy távolsági tartomány</string>\n    <string name=\"tag_image_unique_id\">Egyedi képazonosító</string>\n    <string name=\"tag_camera_owner_name\">A kamera tulajdonosának neve</string>\n    <string name=\"tag_body_serial_number\">Test sorozatszáma</string>\n    <string name=\"tag_lens_specification\">Lencse specifikáció</string>\n    <string name=\"tag_lens_make\">Lencse gyártmány</string>\n    <string name=\"tag_lens_model\">Objektív modell</string>\n    <string name=\"tag_lens_serial_number\">Az objektív sorozatszáma</string>\n    <string name=\"tag_gps_version_id\">GPS verzióazonosító</string>\n    <string name=\"tag_gps_latitude_ref\">GPS szélesség Ref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitude</string>\n    <string name=\"tag_gps_longitude_ref\">GPS hosszúság Ref</string>\n    <string name=\"tag_gps_longitude\">GPS hosszúság</string>\n    <string name=\"tag_gps_altitude_ref\">GPS magasság Ref</string>\n    <string name=\"tag_gps_altitude\">GPS magasság</string>\n    <string name=\"tag_gps_timestamp\">GPS időbélyegző</string>\n    <string name=\"tag_gps_satellites\">GPS műholdak</string>\n    <string name=\"tag_gps_status\">GPS állapot</string>\n    <string name=\"tag_gps_measure_mode\">GPS mérési mód</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS Sebesség Ref</string>\n    <string name=\"tag_gps_speed\">GPS sebesség</string>\n    <string name=\"tag_gps_track_ref\">GPS nyomvonal Ref</string>\n    <string name=\"tag_gps_track\">GPS nyomvonal</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img Irány Ref</string>\n    <string name=\"tag_gps_img_direction\">GPS Img Irány</string>\n    <string name=\"tag_gps_map_datum\">GPS térkép Datum</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Cél szélesség Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS célszélesség</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS cél hosszúsági ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS cél hosszúság</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS célcsapágy ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS cél távolság Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS cél távolság</string>\n    <string name=\"tag_gps_processing_method\">GPS feldolgozási módszer</string>\n    <string name=\"tag_gps_area_information\">GPS terület információ</string>\n    <string name=\"tag_gps_datestamp\">GPS dátumbélyegző</string>\n    <string name=\"tag_gps_differential\">GPS differenciálmű</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H helymeghatározási hiba</string>\n    <string name=\"tag_interoperability_index\">Interoperabilitási index</string>\n    <string name=\"tag_dng_version\">DNG verzió</string>\n    <string name=\"tag_default_crop_size\">Alapértelmezett vágási méret</string>\n    <string name=\"tag_orf_preview_image_start\">Preview Image Start</string>\n    <string name=\"tag_orf_preview_image_length\">Előnézet kép hossza</string>\n    <string name=\"tag_orf_aspect_frame\">Képarány keret</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Érzékelő alsó szegélye</string>\n    <string name=\"tag_rw2_sensor_left_border\">Érzékelő bal szegélye</string>\n    <string name=\"tag_rw2_sensor_right_border\">Érzékelő jobb szegélye</string>\n    <string name=\"tag_rw2_sensor_top_border\">Érzékelő felső szegély</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Szöveg rajzolása az útvonalra adott betűtípussal és színnel</string>\n    <string name=\"font_size\">Betűméret</string>\n    <string name=\"watermark_size\">Vízjel mérete</string>\n    <string name=\"repeat_text\">Szöveg ismétlése</string>\n    <string name=\"repeat_text_sub\">Az aktuális szöveg megismétlődik az elérési út végéig az egyszeri rajz helyett</string>\n    <string name=\"dash_size\">Dash Size</string>\n    <string name=\"draw_mode_image_sub\">A kiválasztott kép segítségével rajzolja meg a megadott útvonalon</string>\n    <string name=\"draw_image_sub\">Ezt a képet a program a megrajzolt útvonal ismétlődő bejegyzéseként fogja használni</string>\n    <string name=\"outlined_triangle_sub\">Körvonalas háromszöget rajzol a kezdőponttól a végpontig</string>\n    <string name=\"triangle_sub\">Körvonalas háromszöget rajzol a kezdőponttól a végpontig</string>\n    <string name=\"outlined_triangle\">Vázolt háromszög</string>\n    <string name=\"triangle\">Háromszög</string>\n    <string name=\"polygon_sub\">Sokszöget rajzol a kezdőponttól a végpontig</string>\n    <string name=\"polygon\">Poligon</string>\n    <string name=\"outlined_polygon\">Vázolt sokszög</string>\n    <string name=\"outlined_polygon_sub\">Körvonalas sokszöget rajzol a kezdőponttól a végpontig</string>\n    <string name=\"vertices\">Csúcsok</string>\n    <string name=\"draw_regular_polygon\">Rajzolj szabályos sokszöget</string>\n    <string name=\"draw_regular_polygon_sub\">Rajzolj sokszöget, amely szabályos lesz a szabad forma helyett</string>\n    <string name=\"star_sub\">Csillagot rajzol a kezdőponttól a végpontig</string>\n    <string name=\"star\">Csillag</string>\n    <string name=\"outlined_star\">Vázolt csillag</string>\n    <string name=\"outlined_star_sub\">Körvonalas csillagot rajzol a kezdőponttól a végpontig</string>\n    <string name=\"inner_radius_ratio\">Belső sugár arány</string>\n    <string name=\"draw_regular_star\">Rajzolj szabályos csillagot</string>\n    <string name=\"draw_regular_star_sub\">Rajzolj csillagot, amely szabályos lesz a szabad forma helyett</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Lehetővé teszi az élsimítást az éles szélek elkerülése érdekében</string>\n    <string name=\"open_edit_instead_of_preview\">Nyissa meg a Szerkesztést az előnézet helyett</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Ha az ImageToolboxban kiválasztja a megnyitandó képet (előnézetet), a szerkesztési kijelölési lap megnyílik az előnézet helyett</string>\n    <string name=\"document_scanner\">Dokumentum szkenner</string>\n    <string name=\"document_scanner_sub\">Szkenneljen be dokumentumokat, és készítsen PDF-fájlt vagy különítsen el belőlük képeket</string>\n    <string name=\"click_to_start_scanning\">Kattintson a szkennelés elindításához</string>\n    <string name=\"start_scanning\">Indítsa el a szkennelést</string>\n    <string name=\"save_as_pdf\">Mentés Pdf-ként</string>\n    <string name=\"share_as_pdf\">Megosztás Pdf-ként</string>\n    <string name=\"options_below_is_for_images\">Az alábbi lehetőségek képek mentésére szolgálnak, nem PDF-re</string>\n    <string name=\"equalize_histogram_hsv\">HSV hisztogram kiegyenlítése</string>\n    <string name=\"equalize_histogram\">Hisztogram kiegyenlítése</string>\n    <string name=\"enter_percentage\">Írja be a százalékot</string>\n    <string name=\"allow_enter_by_text_field\">Engedélyezze a bevitelt szöveges mezőben</string>\n    <string name=\"allow_enter_by_text_field_sub\">Engedélyezi a szövegmezőt az előre beállított értékek kijelölése mögött, hogy azokat menet közben beírja</string>\n    <string name=\"scale_color_space\">Skála színtér</string>\n    <string name=\"linear\">Lineáris</string>\n    <string name=\"equalize_histogram_pixelation\">Hisztogram pixeláció kiegyenlítése</string>\n    <string name=\"grid_size_x\">Rács mérete X</string>\n    <string name=\"grid_size_y\">Rácsméret Y</string>\n    <string name=\"equalize_histogram_adaptive\">A hisztogram kiegyenlítése adaptív</string>\n    <string name=\"equalize_histogram_adaptive_luv\">A hisztogram adaptív LUV kiegyenlítése</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Hisztogram adaptív LAB kiegyenlítése</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Vágás tartalomra</string>\n    <string name=\"frame_color\">Keret színe</string>\n    <string name=\"color_to_ignore\">Figyelmen kívül hagyandó szín</string>\n    <string name=\"template\">Sablon</string>\n    <string name=\"no_template_filters\">Nincsenek sablonszűrők hozzáadva</string>\n    <string name=\"create_new\">Új létrehozása</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">A beolvasott QR-kód nem érvényes szűrősablon</string>\n    <string name=\"scan_qr_code\">QR-kód beolvasása</string>\n    <string name=\"opened_file_have_no_filter_template\">A kiválasztott fájlban nincsenek szűrősablon adatok</string>\n    <string name=\"create_template\">Sablon létrehozása</string>\n    <string name=\"template_name\">Sablon neve</string>\n    <string name=\"select_template_preview\">Ezt a képet használjuk a szűrősablon előnézetéhez</string>\n    <string name=\"template_filter\">Sablonszűrő</string>\n    <string name=\"as_qr_code\">QR-kód képként</string>\n    <string name=\"as_file\">Fájlként</string>\n    <string name=\"save_as_file\">Mentés fájlként</string>\n    <string name=\"save_as_qr_code_image\">Mentés QR-kód képként</string>\n    <string name=\"delete_template\">Sablon törlése</string>\n    <string name=\"delete_template_warn\">A kiválasztott sablonszűrő törlésére készül. Ez a művelet nem vonható vissza</string>\n    <string name=\"added_filter_template\">Szűrősablon hozzáadva a következő névvel: \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Szűrő előnézete</string>\n    <string name=\"qr_code\">QR és vonalkód</string>\n    <string name=\"qr_code_sub\">Olvassa be a QR-kódot, és szerezze be a tartalmát, vagy illessze be a karakterláncot új kód létrehozásához</string>\n    <string name=\"code_content\">Kódtartalom</string>\n    <string name=\"scan_qr_code_to_replace_content\">Olvasson be bármilyen vonalkódot a mező tartalmának lecseréléséhez, vagy írjon be valamit, hogy új vonalkódot generáljon a kiválasztott típussal</string>\n    <string name=\"qr_description\">QR leírás</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Adjon kameraengedélyt a beállításokban a QR-kód beolvasásához</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Adjon kameraengedélyt a beállításokban a dokumentumszkenner beolvasásához</string>\n    <string name=\"cubic\">Kocka alakú</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Rászed</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gauss-féle</string>\n    <string name=\"sphinx\">Szfinksz</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">császár</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Doboz</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">A köbös interpoláció simább skálázást biztosít a legközelebbi 16 képpont figyelembevételével, jobb eredményt adva, mint a bilineáris</string>\n    <string name=\"bspline_sub\">A darabonként definiált polinom függvényeket használja a görbe vagy felület zökkenőmentes interpolálásához és közelítéséhez, rugalmas és folyamatos alakábrázoláshoz</string>\n    <string name=\"hamming_sub\">Ablakfunkció, amely a jel széleinek szűkítésével csökkenti a spektrális szivárgást, hasznos a jelfeldolgozásban</string>\n    <string name=\"hanning_sub\">A Hann-ablak egy változata, amelyet általában a spektrális szivárgás csökkentésére használnak jelfeldolgozó alkalmazásokban</string>\n    <string name=\"blackman_sub\">A jelfeldolgozásban gyakran használt ablakfunkció, amely jó frekvenciafelbontást biztosít a spektrális szivárgás minimalizálásával</string>\n    <string name=\"welch_sub\">A jelfeldolgozó alkalmazásokban gyakran használt ablakfunkció, amelyet arra terveztek, hogy jó frekvenciafelbontást biztosítson csökkentett spektrális szivárgással</string>\n    <string name=\"quadric_sub\">Olyan módszer, amely másodfokú függvényt használ az interpolációhoz, sima és folyamatos eredményeket biztosítva</string>\n    <string name=\"gaussian_sub\">Gauss-függvényt alkalmazó interpolációs módszer, amely hasznos a képek simítására és zajcsökkentésére</string>\n    <string name=\"sphinx_sub\">Speciális újramintavételezési módszer, amely kiváló minőségű interpolációt biztosít minimális műtermékekkel</string>\n    <string name=\"bartlett_sub\">A jelfeldolgozásban használt háromszögablakos funkció a spektrális szivárgás csökkentésére</string>\n    <string name=\"robidoux_sub\">Kiváló minőségű interpolációs módszer a kép természetes átméretezésére, az élesség és a simaság egyensúlyára</string>\n    <string name=\"robidoux_sharp_sub\">A Robidoux-módszer élesebb változata, éles képméretezésre optimalizálva</string>\n    <string name=\"spline16_sub\">Spline alapú interpolációs módszer, amely sima eredményeket biztosít egy 16 koppintásos szűrővel</string>\n    <string name=\"spline36_sub\">Spline-alapú interpolációs módszer, amely sima eredményeket biztosít egy 36 koppintásos szűrő használatával</string>\n    <string name=\"spline64_sub\">Spline alapú interpolációs módszer, amely sima eredményeket biztosít egy 64 érintéssel járó szűrővel</string>\n    <string name=\"kaiser_sub\">Egy interpolációs módszer, amely a Kaiser ablakot használja, jó szabályozást biztosítva a főlebeny szélessége és az oldallebeny szintje közötti kompromisszum felett</string>\n    <string name=\"bartlett_hann_sub\">A Bartlett és a Hann ablakokat kombináló hibrid ablak funkció, amely a jelfeldolgozásban a spektrális szivárgás csökkentésére szolgál.</string>\n    <string name=\"box_sub\">Egy egyszerű újramintavételi módszer, amely a legközelebbi pixelértékek átlagát használja, ami gyakran blokkos megjelenést eredményez</string>\n    <string name=\"bohman_sub\">A spektrális szivárgás csökkentésére használt ablak funkció, amely jó frekvenciafelbontást biztosít jelfeldolgozó alkalmazásokban</string>\n    <string name=\"lanczos2_sub\">Újramintavételi módszer, amely 2 lebenyű Lanczos szűrőt használ a kiváló minőségű interpoláció érdekében minimális műtermékekkel</string>\n    <string name=\"lanczos3_sub\">Újramintavételi módszer, amely 3 lebenyű Lanczos szűrőt használ a kiváló minőségű interpoláció érdekében minimális műtermékekkel</string>\n    <string name=\"lanczos4_sub\">Újramintavételi módszer, amely 4 lebenyű Lanczos szűrőt használ a kiváló minőségű interpoláció érdekében minimális műtermékekkel</string>\n    <string name=\"lanczos2_jinc_sub\">A Lanczos 2 szűrő egy változata, amely a jinc funkciót használja, kiváló minőségű interpolációt biztosít minimális műtermékekkel</string>\n    <string name=\"lanczos3_jinc_sub\">A Lanczos 3 szűrő egy változata, amely a jinc funkciót használja, kiváló minőségű interpolációt biztosít minimális műtermékekkel</string>\n    <string name=\"lanczos4_jinc_sub\">A Lanczos 4 szűrő egy változata, amely a jinc funkciót használja, kiváló minőségű interpolációt biztosít minimális műtermékekkel</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">A Hanning-szűrő elliptikus súlyozott átlag (EWA) változata a sima interpoláció és újramintavételezés érdekében</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">A Robidoux szűrő elliptikus súlyozott átlag (EWA) változata a kiváló minőségű újramintavételezés érdekében</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">A Blackman-szűrő elliptikus súlyozott átlagú (EWA) változata a csengetési műtermékek minimalizálása érdekében</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">A Quadric szűrő elliptikus súlyozott átlag (EWA) változata a sima interpoláció érdekében</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">A Robidoux Sharp szűrő elliptikus súlyozott átlag (EWA) változata az élesebb eredmények érdekében</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">A Lanczos 3 Jinc szűrő elliptikus súlyozott átlag (EWA) változata a kiváló minőségű újramintavételezéshez csökkentett álnevekkel</string>\n    <string name=\"ginseng\">Ginzeng</string>\n    <string name=\"ginseng_sub\">Újramintavevő szűrő, amelyet kiváló minőségű képfeldolgozásra terveztek, az élesség és a simaság jó egyensúlyával</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">A Ginseng szűrő elliptikus súlyozott átlag (EWA) változata a jobb képminőség érdekében</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">A Lanczos Sharp szűrő elliptikus súlyozott átlag (EWA) változata az éles eredmények eléréséhez minimális műtermékekkel</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 legélesebb EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">A Lanczos 4 Sharpest szűrő elliptikus súlyozott átlag (EWA) változata a rendkívül éles képek újramintavételezéséhez</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">A Lanczos Soft szűrő elliptikus súlyozott átlag (EWA) változata a simább kép-újramintavételezés érdekében</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">A Haasn által tervezett újramintavevő szűrő a sima és műtermékmentes képméretezés érdekében</string>\n    <string name=\"format_conversion\">Formátum átalakítás</string>\n    <string name=\"format_conversion_sub\">Kötegelt képek konvertálása egyik formátumból a másikba</string>\n    <string name=\"dismiss_forever\">Elvetés örökre</string>\n    <string name=\"image_stacking\">Kép halmozás</string>\n    <string name=\"image_stacking_sub\">A kiválasztott keverési módokkal egymásra halmozhatja a képeket</string>\n    <string name=\"add_image\">Kép hozzáadása elemre</string>\n    <string name=\"bins_count\">A kukák számítanak</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Hisztogram adaptív HSL kiegyenlítése</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Hisztogram adaptív HSV kiegyenlítése</string>\n    <string name=\"edge_mode\">Edge mód</string>\n    <string name=\"clip\">Csipesz</string>\n    <string name=\"wrap\">Betakar</string>\n    <string name=\"color_blind_scheme\">Színvakság</string>\n    <string name=\"color_blind_scheme_sub\">Válassza ki a módot a téma színeinek a kiválasztott színvakság változathoz való igazításához</string>\n    <string name=\"protanomaly_sub\">Nehéz megkülönböztetni a vörös és a zöld árnyalatokat</string>\n    <string name=\"deuteranomaly_sub\">Nehéz megkülönböztetni a zöld és a vörös árnyalatokat</string>\n    <string name=\"tritanomaly_sub\">Nehéz megkülönböztetni a kék és a sárga árnyalatokat</string>\n    <string name=\"protanopia_sub\">Képtelenség érzékelni a vörös árnyalatokat</string>\n    <string name=\"deuteranopia_sub\">Képtelenség érzékelni a zöld árnyalatokat</string>\n    <string name=\"tritanopia_sub\">Képtelenség érzékelni a kék árnyalatokat</string>\n    <string name=\"achromatomaly_sub\">Csökkentett érzékenység minden színre</string>\n    <string name=\"achromatopsia_sub\">Teljes színvakság, csak a szürke árnyalatait látja</string>\n    <string name=\"not_use_color_blind_scheme\">Ne használja a színvak sémát</string>\n    <string name=\"not_use_color_blind_scheme_sub\">A színek pontosan olyanok lesznek, mint a témában</string>\n    <string name=\"sigmoidal\">Szigmoidális</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">2-es rendű Lagrange interpolációs szűrő, amely kiváló minőségű képméretezésre alkalmas sima átmenetekkel</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">A 3. rendű Lagrange interpolációs szűrő jobb pontosságot és egyenletesebb eredményeket kínál a képméretezéshez</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">A Lanczos resampling szűrő magasabb, 6-os nagyságrenddel élesebb és pontosabb képméretezést biztosít</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">A Lanczos 6 szűrő egy Jinc funkcióval rendelkező változata a jobb kép-újramintavételi minőség érdekében</string>\n    <string name=\"linear_box_blur\">Lineáris Box Blur</string>\n    <string name=\"linear_tent_blur\">Lineáris sátorelmosás</string>\n    <string name=\"linear_gaussian_box_blur\">Lineáris Gauss-box elmosódás</string>\n    <string name=\"linear_stack_blur\">Lineáris Stack Blur</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lineáris gyors Gauss-elmosás Következő</string>\n    <string name=\"linear_fast_gaussian_blur\">Lineáris gyors Gauss-elmosás</string>\n    <string name=\"linear_gaussian_blur\">Lineáris Gauss-elmosás</string>\n    <string name=\"draw_filter_sub\">Válasszon egy szűrőt, hogy festékként használja</string>\n    <string name=\"replace_filter\">Cserélje ki a szűrőt</string>\n    <string name=\"pick_filter_info\">Válassza ki az alábbi szűrőt, ha ecsetként szeretné használni a rajzában</string>\n    <string name=\"tiff_compression_scheme\">TIFF tömörítési séma</string>\n    <string name=\"low_poly\">Alacsony poli</string>\n    <string name=\"sand_painting\">Homokfestés</string>\n    <string name=\"image_splitting\">Képfelosztás</string>\n    <string name=\"image_splitting_sub\">Egyetlen kép felosztása sorok vagy oszlopok szerint</string>\n    <string name=\"fit_to_bounds\">Fit to Bounds</string>\n    <string name=\"fit_to_bounds_sub\">Kombinálja a kivágás átméretezési módot ezzel a paraméterrel a kívánt viselkedés eléréséhez (Körbevágás/Igazítás a képarányhoz)</string>\n    <string name=\"languages_imported\">A nyelvek importálása sikeres volt</string>\n    <string name=\"backup_ocr_models\">Tartalék OCR modellek</string>\n    <string name=\"import_word\">Importálás</string>\n    <string name=\"export\">Export</string>\n    <string name=\"position\">Pozíció</string>\n    <string name=\"center\">Központ</string>\n    <string name=\"top_left\">Bal felső</string>\n    <string name=\"top_right\">Jobbra fent</string>\n    <string name=\"bottom_left\">Balra lent</string>\n    <string name=\"bottom_right\">Jobbra lent</string>\n    <string name=\"top_center\">Felső központ</string>\n    <string name=\"center_right\">Jobb középső</string>\n    <string name=\"bottom_center\">Alsó központ</string>\n    <string name=\"center_left\">Bal középen</string>\n    <string name=\"target_image\">Célkép</string>\n    <string name=\"palette_transfer\">Paletta átvitel</string>\n    <string name=\"enhanced_oil\">Fokozott olaj</string>\n    <string name=\"simple_old_tv\">Egyszerű régi TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Egyszerű vázlat</string>\n    <string name=\"soft_glow\">Lágy Glow</string>\n    <string name=\"color_poster\">Színes poszter</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Harmadik szín</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olks</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Petty</string>\n    <string name=\"clustered_2x2_dithering\">Csoportosított 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Csoportosított 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">Csoportosított 8x8 dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma dithering</string>\n    <string name=\"no_favorite_options_selected\">Nincsenek kiválasztva kedvenc opciók, adja hozzá őket az eszközök oldalon</string>\n    <string name=\"add_favorites\">Kedvencek hozzáadása</string>\n    <string name=\"harmony_complementary\">Kiegészítő</string>\n    <string name=\"harmony_analogous\">Hasonló</string>\n    <string name=\"harmony_triadic\">Triadikus</string>\n    <string name=\"harmony_split_complementary\">Megosztott kiegészítő</string>\n    <string name=\"harmony_tetradic\">Tetradic</string>\n    <string name=\"harmony_square\">Négyzet</string>\n    <string name=\"harmony_analogous_complementary\">Analóg + Kiegészítő</string>\n    <string name=\"color_tools\">Színes eszközök</string>\n    <string name=\"color_tools_sub\">Keverj, készíts tónusokat, generálj árnyalatokat és így tovább</string>\n    <string name=\"color_harmonies\">Színharmóniák</string>\n    <string name=\"color_shading\">Színes árnyékolás</string>\n    <string name=\"variation\">Variáció</string>\n    <string name=\"tints\">Tints</string>\n    <string name=\"tones\">Hangok</string>\n    <string name=\"shades\">Shades</string>\n    <string name=\"color_mixing\">Színkeverés</string>\n    <string name=\"color_info\">Színes információ</string>\n    <string name=\"selected_color\">Kiválasztott szín</string>\n    <string name=\"color_to_mix\">Szín Keverhető</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Nem használható pénz, ha a dinamikus színek be vannak kapcsolva</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Cél LUT-kép</string>\n    <string name=\"amatorka\">Egy amatőr</string>\n    <string name=\"miss_etikate\">Miss Etikett</string>\n    <string name=\"soft_elegance\">Puha elegancia</string>\n    <string name=\"soft_elegance_variant\">Soft Elegance Variant</string>\n    <string name=\"palette_transfer_variant\">Paletta átviteli változat</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Cél 3D LUT-fájl (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Gyertyafény</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Edgy Amber</string>\n    <string name=\"fall_colors\">Őszi színek</string>\n    <string name=\"film_stock_50\">Filmkészlet 50</string>\n    <string name=\"foggy_night\">Ködös éjszaka</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Töltse le a semleges LUT-képet</string>\n    <string name=\"save_empty_lut_sub\">Először is használja kedvenc képszerkesztő alkalmazását, hogy alkalmazzon szűrőt a semleges LUT-ra, amelyet itt szerezhet be. Ahhoz, hogy ez megfelelően működjön, az egyes pixelszínek nem függhetnek a többi képponttól (például az elmosódás nem működik). Ha készen áll, használja az új LUT-képet bemenetként az 512*512-es LUT-szűrőhöz</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"coffee\">Kávé</string>\n    <string name=\"golden_forest\">Arany Erdő</string>\n    <string name=\"greenish\">Zöldes</string>\n    <string name=\"retro_yellow\">Retro sárga</string>\n    <string name=\"links_preview\">Linkek előnézete</string>\n    <string name=\"links_preview_sub\">Lehetővé teszi a hivatkozás előnézetének lekérését olyan helyeken, ahol szöveget kaphat (QRCode, OCR stb.)</string>\n    <string name=\"links\">Linkek</string>\n    <string name=\"ico_size_warning\">Az ICO fájlok legfeljebb 256 x 256 méretben menthetők</string>\n    <string name=\"gif_type_to_webp\">GIF a WEBP-re</string>\n    <string name=\"gif_type_to_webp_sub\">GIF-képek konvertálása WEBP-animált képekké</string>\n    <string name=\"webp_tools\">WEBP Eszközök</string>\n    <string name=\"webp_tools_sub\">Konvertálja a képeket WEBP animált képpé, vagy bontsa ki a kereteket az adott WEBP animációból</string>\n    <string name=\"webp_type_to_image\">WEBP a képekhez</string>\n    <string name=\"webp_type_to_image_sub\">A WEBP fájl konvertálása képek kötegévé</string>\n    <string name=\"webp_type_to_webp_sub\">Kötegelt képek konvertálása WEBP-fájllá</string>\n    <string name=\"webp_type_to_webp\">Képek a WEBP-re</string>\n    <string name=\"select_webp_image_to_start\">A kezdéshez válassza ki a WEBP képet</string>\n    <string name=\"manage_storage_extra_types\">Nincs teljes hozzáférés a fájlokhoz</string>\n    <string name=\"manage_storage_extra_types_sub\">Engedélyezze az összes fájlhoz való hozzáférést a JXL, QOI és más olyan képek megtekintéséhez, amelyeket nem ismer fel képként az Android. Engedély nélkül az Image Toolbox nem tudja megjeleníteni ezeket a képeket</string>\n    <string name=\"default_draw_color\">Alapértelmezett rajzszín</string>\n    <string name=\"default_draw_path_mode\">Alapértelmezett rajzolási útvonal mód</string>\n    <string name=\"add_timestamp\">Időbélyeg hozzáadása</string>\n    <string name=\"add_timestamp_sub\">Lehetővé teszi az időbélyeg hozzáadását a kimeneti fájlnévhez</string>\n    <string name=\"formatted_timestamp\">Formázott időbélyeg</string>\n    <string name=\"formatted_timestamp_sub\">Engedélyezze az időbélyeg formázást a kimeneti fájlnévben az alap millis helyett</string>\n    <string name=\"enable_timestamps_to_format_them\">A formátum kiválasztásához engedélyezze az Időbélyegeket</string>\n    <string name=\"one_time_save_location\">Egyszeri mentési hely</string>\n    <string name=\"one_time_save_location_sub\">Tekintse meg és szerkessze az egyszeri mentési helyeket, amelyeket a mentés gomb hosszan lenyomásával használhat, többnyire minden lehetőségnél</string>\n    <string name=\"recently_used\">Nemrég használt</string>\n    <string name=\"ci_channel\">CI csatorna</string>\n    <string name=\"group\">Csoport</string>\n    <string name=\"image_toolbox_in_telegram\">Kép eszköztár a Telegramban 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Csatlakozz a chatünkhöz, ahol megbeszélhetsz bármit, amit szeretnél, és nézz be a CI csatornára is, ahol bétákat és bejelentéseket teszek közzé</string>\n    <string name=\"ci_channel_sub\">Értesítést kaphat az alkalmazás új verzióiról, és olvassa el a közleményeket</string>\n    <string name=\"fit_description\">Illessze a képet a megadott méretekhez, és alkalmazzon elmosódást vagy színt a háttérre</string>\n    <string name=\"tools_arrangement\">Eszközök elrendezése</string>\n    <string name=\"group_tools_by_type\">Csoportosítsa az eszközöket típus szerint</string>\n    <string name=\"group_tools_by_type_sub\">Az egyéni listaelrendezés helyett típusuk szerint csoportosítja az eszközöket a főképernyőn</string>\n    <string name=\"default_values\">Alapértelmezett értékek</string>\n    <string name=\"system_bars_visibility\">Rendszersávok láthatósága</string>\n    <string name=\"show_system_bars_by_swipe\">Rendszersávok megjelenítése ellopással</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Lehetővé teszi a csúsztatást a rendszersávok megjelenítéséhez, ha el vannak rejtve</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Összes elrejtése</string>\n    <string name=\"show_all\">Összes megjelenítése</string>\n    <string name=\"hide_nav_bar\">Navigációs sáv elrejtése</string>\n    <string name=\"hide_status_bar\">Állapotsor elrejtése</string>\n    <string name=\"noise_generation\">Zajgenerálás</string>\n    <string name=\"noise_generation_sub\">Különféle zajokat generál, mint például a Perlin vagy más típusú</string>\n    <string name=\"frequency\">Frekvencia</string>\n    <string name=\"noise_type\">Zajtípus</string>\n    <string name=\"rotation_type\">Forgatás típusa</string>\n    <string name=\"fractal_type\">Fraktál típus</string>\n    <string name=\"octaves\">Oktávok</string>\n    <string name=\"lacunarity\">Lacunarity</string>\n    <string name=\"gain\">Nyereség</string>\n    <string name=\"weighted_strength\">Súlyozott erő</string>\n    <string name=\"ping_pong_strength\">Ping Pong Erő</string>\n    <string name=\"distance_function\">Távolság funkció</string>\n    <string name=\"return_type\">Visszatérés típusa</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"alignment\">Igazítás</string>\n    <string name=\"custom_filename\">Egyéni fájlnév</string>\n    <string name=\"custom_filename_sub\">Válassza ki azt a helyet és fájlnevet, amelyet az aktuális kép mentéséhez használni fog</string>\n    <string name=\"saved_to_custom\">Mentve egy mappába egyéni névvel</string>\n    <string name=\"collage_maker\">Kollázskészítő</string>\n    <string name=\"collage_maker_sub\">Kollázsokat készíthet akár 20 képből</string>\n    <string name=\"collage_type\">Kollázs típusa</string>\n    <string name=\"collages_info\">Tartsa lenyomva a képet a cseréhez, mozgatáshoz és nagyításhoz a pozíció beállításához</string>\n    <string name=\"disable_rotation\">Forgatás letiltása</string>\n    <string name=\"disable_rotation_sub\">Megakadályozza a képek elforgatását kétujjas kézmozdulatokkal</string>\n    <string name=\"enable_snapping_to_borders\">A szegélyekhez illesztés engedélyezése</string>\n    <string name=\"enable_snapping_to_borders_sub\">Mozgatás vagy nagyítás után a képek kattannak, hogy kitöltsék a keret széleit</string>\n    <string name=\"histogram\">Hisztogram</string>\n    <string name=\"histogram_sub\">RGB vagy Brightness kép hisztogramja, amely segít a beállítások elvégzésében</string>\n    <string name=\"image_for_histogram\">Ezt a képet RGB és Fényerő hisztogramok generálására használják fel</string>\n    <string name=\"tesseract_options\">Tesseact Options</string>\n    <string name=\"tesseract_options_sub\">Alkalmazzon néhány bemeneti változót a tesseract motorhoz</string>\n    <string name=\"custom_options\">Egyéni beállítások</string>\n    <string name=\"custom_params_info\">A beállításokat a következő minta szerint kell megadni: \\\"--{opció_neve} {érték}\\\"</string>\n    <string name=\"auto_crop\">Automatikus kivágás</string>\n    <string name=\"free_corners\">Szabad sarkok</string>\n    <string name=\"free_corners_sub\">Vágja a képet sokszögenként, ezzel is korrigálja a perspektívát</string>\n    <string name=\"coerce_points_to_image_bounds\">Pontok kényszerítése képhatárokra</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">A pontokat nem korlátozzák a képhatárok, ez a perspektíva pontosabb korrekciójához hasznos</string>\n    <string name=\"mask\">Maszk</string>\n    <string name=\"spot_heal_sub\">Tartalomtudatos kitöltés a megrajzolt útvonal alatt</string>\n    <string name=\"spot_heal\">Gyógyítóhely</string>\n    <string name=\"use_circle_kernel\">Használja a Circle Kernelt</string>\n    <string name=\"opening\">Nyílás</string>\n    <string name=\"closing\">Záró</string>\n    <string name=\"morphological_gradient\">Morfológiai gradiens</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Fekete kalap</string>\n    <string name=\"tone_curves\">Hanggörbék</string>\n    <string name=\"reset_curves\">Görbék visszaállítása</string>\n    <string name=\"reset_curves_sub\">A görbék visszaállnak az alapértelmezett értékre</string>\n    <string name=\"line_style\">Vonalstílus</string>\n    <string name=\"gap_size\">Gap Size</string>\n    <string name=\"dashed\">Szaggatott</string>\n    <string name=\"dot_dashed\">Pont szaggatott</string>\n    <string name=\"stamped\">Bélyeges</string>\n    <string name=\"zigzag\">Cikcakk</string>\n    <string name=\"dashed_sub\">Szaggatott vonalat húz a megrajzolt útvonal mentén meghatározott hézagmérettel</string>\n    <string name=\"dot_dashed_sub\">Pontot és szaggatott vonalat rajzol az adott útvonal mentén</string>\n    <string name=\"defaultt_sub\">Csak alapértelmezett egyenes vonalak</string>\n    <string name=\"stamped_sub\">Kijelölt alakzatokat rajzol az útvonal mentén meghatározott térközzel</string>\n    <string name=\"zigzag_sub\">Hullámos cikkcakkokat rajzol az ösvény mentén</string>\n    <string name=\"zigzag_ratio\">Cikcakk arány</string>\n    <string name=\"create_shortcut\">Parancsikon létrehozása</string>\n    <string name=\"create_shortcut_title\">Válassza ki a rögzíteni kívánt eszközt</string>\n    <string name=\"create_shortcut_subtitle\">Az eszköz felkerül az indító kezdőképernyőjére parancsikonként, és használja a \\\"Fájlválasztás kihagyása\\\" beállítással kombinálva a kívánt viselkedés eléréséhez.</string>\n    <string name=\"dont_stack_frames\">Ne rakja egymásra a kereteket</string>\n    <string name=\"dont_stack_frames_sub\">Lehetővé teszi a korábbi képkockák selejtezését, így azok nem fognak egymásra rakódni</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">A keretek egymásba kerülnek</string>\n    <string name=\"crossfade_count\">A Crossfade képkockák számítanak</string>\n    <string name=\"threshold_one\">Egyes küszöb</string>\n    <string name=\"threshold_two\">Kettes küszöb</string>\n    <string name=\"canny\">Ravasz</string>\n    <string name=\"mirror_101\">Tükör 101</string>\n    <string name=\"enhanced_zoom_blur\">Továbbfejlesztett zoom elmosódás</string>\n    <string name=\"laplacian_simple\">laplaci egyszerű</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Segítő rács</string>\n    <string name=\"helper_grid_sub\">A rajzterület felett a támasztórácsot jeleníti meg a pontos manipulációk elősegítése érdekében</string>\n    <string name=\"grid_color\">Rács színe</string>\n    <string name=\"cell_width\">Cell Width</string>\n    <string name=\"cell_height\">Cell magasság</string>\n    <string name=\"compact_selectors\">Kompakt kiválasztók</string>\n    <string name=\"compact_selectors_sub\">Egyes kiválasztási vezérlők kompakt elrendezést használnak, hogy kevesebb helyet foglaljanak</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Adja meg a kamera engedélyét a beállításokban a kép rögzítéséhez</string>\n    <string name=\"layout\">Elrendezés</string>\n    <string name=\"main_screen_title\">Főképernyő címe</string>\n    <string name=\"constant_rate_factor\">Állandó rátafaktor (CRF)</string>\n    <string name=\"crf_sub\">A %1$s érték lassú tömörítést jelent, ami viszonylag kis fájlméretet eredményez. A %2$s gyorsabb tömörítést jelent, ami nagy fájlt eredményez.</string>\n    <string name=\"lut_library\">Lut Könyvtár</string>\n    <string name=\"lut_library_sub\">Töltse le a LUT-gyűjteményt, amelyet a letöltés után alkalmazhat</string>\n    <string name=\"lut_library_update_sub\">Frissítse a LUT-ok gyűjteményét (csak az újak kerülnek sorba), amelyeket a letöltés után alkalmazhat</string>\n    <string name=\"filter_preview_image_sub\">A szűrők alapértelmezett kép-előnézetének módosítása</string>\n    <string name=\"filter_preview_image\">Kép előnézete</string>\n    <string name=\"hide\">Elrejt</string>\n    <string name=\"show\">Megmutat</string>\n    <string name=\"slider_type\">Csúszka típusa</string>\n    <string name=\"fancy\">Képzelet</string>\n    <string name=\"material_2\">2. anyag</string>\n    <string name=\"fancy_sub\">Egy díszes megjelenésű csúszka. Ez az alapértelmezett beállítás</string>\n    <string name=\"material_2_sub\">Egy Material 2 csúszka</string>\n    <string name=\"material_you_slider_sub\">A Material You csúszka</string>\n    <string name=\"apply\">Alkalmazni</string>\n    <string name=\"center_align_dialog_buttons\">Központi párbeszédpanel gombok</string>\n    <string name=\"center_align_dialog_buttons_sub\">A párbeszédpanelek gombjai lehetőleg a bal oldal helyett középen helyezkednek el</string>\n    <string name=\"open_source_licenses\">Nyílt forráskódú licencek</string>\n    <string name=\"open_source_licenses_sub\">Tekintse meg az ebben az alkalmazásban használt nyílt forráskódú könyvtárak licenceit</string>\n    <string name=\"area\">Terület</string>\n    <string name=\"area_sub\">Újramintavételezés pixel terület reláció segítségével. Előnyben részesített módszer lehet a képtizedelésre, mivel moire-mentes eredményeket ad. De a kép nagyítása hasonló a \\\"Legközelebbi\\\" módszerhez.</string>\n    <string name=\"enable_tonemapping\">Tonemapping engedélyezése</string>\n    <string name=\"enter_percent\">Írja be a %</string>\n    <string name=\"unknown_host\">Nem tud hozzáférni a webhelyhez, próbáljon meg VPN-t használni, vagy ellenőrizze, hogy az URL helyes-e</string>\n    <string name=\"markup_layers\">Jelölőrétegek</string>\n    <string name=\"markup_layers_sub\">Rétegek mód képek, szövegek és egyebek szabad elhelyezésének lehetőségével</string>\n    <string name=\"edit_layer\">Réteg szerkesztése</string>\n    <string name=\"layers_on_image\">Rétegek a képen</string>\n    <string name=\"layers_on_image_sub\">Használjon egy képet háttérként, és adjon hozzá különböző rétegeket</string>\n    <string name=\"layers_on_background\">Rétegek a háttérben</string>\n    <string name=\"layers_on_background_sub\">Ugyanaz, mint az első opció, de kép helyett színnel</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Gyorsbeállítások oldal</string>\n    <string name=\"fast_settings_side_sub\">A képek szerkesztése közben adjon hozzá egy lebegő csíkot a kiválasztott oldalhoz, amelyre kattintva megnyílik a gyors beállítások</string>\n    <string name=\"clear_selection\">Kiválasztás törlése</string>\n    <string name=\"settings_group_visibility_hidden\">A \\\"%1$s\\\" beállításcsoport alapértelmezés szerint össze lesz csukva</string>\n    <string name=\"settings_group_visibility_visible\">A \\\"%1$s\\\" beállításcsoport alapértelmezés szerint ki lesz bontva</string>\n    <string name=\"base_64_tools\">Base64 eszközök</string>\n    <string name=\"base_64_tools_sub\">Dekódolja a Base64 karakterláncot képpé, vagy kódolja a képet Base64 formátumba</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">A megadott érték nem érvényes Base64 karakterlánc</string>\n    <string name=\"copy_not_a_valid_base_64\">Üres vagy érvénytelen Base64 karakterlánc nem másolható</string>\n    <string name=\"paste_base_64\">Beillesztés Base64</string>\n    <string name=\"copy_base_64\">Másolás Base64</string>\n    <string name=\"base_64_tips\">Töltse be a képet a Base64 karakterlánc másolásához vagy mentéséhez. Ha megvan maga a karakterlánc, beillesztheti a fenti képhez</string>\n    <string name=\"save_base_64\">Base64 mentése</string>\n    <string name=\"share_base_64\">Share Base64</string>\n    <string name=\"options\">Opciók</string>\n    <string name=\"actions\">Akciók</string>\n    <string name=\"import_base_64\">Import Base64</string>\n    <string name=\"base_64_actions\">Base64 műveletek</string>\n    <string name=\"add_outline\">Vázlat hozzáadása</string>\n    <string name=\"add_outline_sub\">Adjon hozzá körvonalat a szöveg körül meghatározott színnel és szélességgel</string>\n    <string name=\"outline_color\">Vázlat színe</string>\n    <string name=\"outline_size\">Vázlat mérete</string>\n    <string name=\"rotation\">Forgás</string>\n    <string name=\"checksum_as_filename\">Ellenőrző összeg fájlnévként</string>\n    <string name=\"checksum_as_filename_sub\">A kimeneti képek neve megfelel az adatok ellenőrző összegének</string>\n    <string name=\"free_software_partner\">Ingyenes szoftver (partner)</string>\n    <string name=\"free_software_partner_sub\">További hasznos szoftverek az Android alkalmazások partnercsatornájában</string>\n    <string name=\"algorithms\">Algoritmus</string>\n    <string name=\"checksum_tools\">Ellenőrzőösszeg eszközök</string>\n    <string name=\"checksum_tools_sub\">Ellenőrző összegek összehasonlítása, hash kiszámítása vagy hexadecimális karakterláncok létrehozása fájlokból különböző kivonatolási algoritmusok segítségével</string>\n    <string name=\"calculate\">Számítsa ki</string>\n    <string name=\"text_hash\">Szöveg Hash</string>\n    <string name=\"checksum\">Ellenőrző összeg</string>\n    <string name=\"pick_file_to_checksum\">Válassza ki a fájlt az ellenőrző összeg kiszámításához a kiválasztott algoritmus alapján</string>\n    <string name=\"enter_text_to_checksum\">Írjon be egy szöveget az ellenőrző összeg kiszámításához a kiválasztott algoritmus alapján</string>\n    <string name=\"source_checksum\">Forrás ellenőrző összeg</string>\n    <string name=\"checksum_to_compare\">Összehasonlítandó ellenőrző összeg</string>\n    <string name=\"match\">Mérkőzés!</string>\n    <string name=\"difference\">Különbség</string>\n    <string name=\"match_sub\">Az ellenőrző összegek egyenlőek, ez biztonságos lehet</string>\n    <string name=\"difference_sub\">Az ellenőrző összegek nem egyenlőek, a fájl nem biztonságos!</string>\n    <string name=\"mesh_gradients\">Mesh színátmenetek</string>\n    <string name=\"collection_mesh_gradients_sub\">Tekintse meg a Mesh Gradients online gyűjteményét</string>\n    <string name=\"wrong_font\">Csak TTF és OTF betűtípusok importálhatók</string>\n    <string name=\"import_font\">Betűtípus importálása (TTF/OTF)</string>\n    <string name=\"export_fonts\">Betűtípusok exportálása</string>\n    <string name=\"imported_fonts\">Importált betűtípusok</string>\n    <string name=\"error_while_saving\">Hiba történt a mentési kísérlet során, próbálja meg megváltoztatni a kimeneti mappát</string>\n    <string name=\"filename_is_not_set\">A fájlnév nincs beállítva</string>\n    <string name=\"none\">Egyik sem</string>\n    <string name=\"custom_pages\">Egyedi oldalak</string>\n    <string name=\"pages_selection\">Oldalak kiválasztása</string>\n    <string name=\"tool_exit_confirmation\">Szerszám kilépés megerősítése</string>\n    <string name=\"tool_exit_confirmation_sub\">Ha bizonyos eszközök használata közben nem mentett módosításokat, és megpróbálja bezárni, akkor megjelenik a megerősítés párbeszédpanel</string>\n    <string name=\"edit_exif_screen\">EXIF szerkesztése</string>\n    <string name=\"edit_exif_screen_sub\">Egyetlen kép metaadatainak módosítása újratömörítés nélkül</string>\n    <string name=\"edit_exif_tag\">Érintse meg az elérhető címkék szerkesztéséhez</string>\n    <string name=\"change_sticker\">Cserélje ki a matricát</string>\n    <string name=\"fit_width\">Fit Width</string>\n    <string name=\"fit_height\">Fit Height</string>\n    <string name=\"batch_compare\">Kötegelt összehasonlítás</string>\n    <string name=\"pick_files_to_checksum\">Válassza ki a fájlt/fájlokat az ellenőrző összeg kiszámításához a kiválasztott algoritmus alapján</string>\n    <string name=\"pick_files\">Válassza ki a Fájlokat</string>\n    <string name=\"pick_directory\">Válassza ki a Címtárat</string>\n    <string name=\"head_length_scale\">Fejhossz skála</string>\n    <string name=\"stamp\">Bélyeg</string>\n    <string name=\"timestamp\">Időbélyeg</string>\n    <string name=\"format_pattern\">Formátumminta</string>\n    <string name=\"padding\">Párnázás</string>\n    <string name=\"image_cutting\">Képvágás</string>\n    <string name=\"image_cutting_sub\">Vágja ki a képrészt, és egyesítse a bal oldaliakat (lehet inverz) függőleges vagy vízszintes vonalakkal</string>\n    <string name=\"vertical_pivot_line\">Függőleges forgási vonal</string>\n    <string name=\"horizontal_pivot_line\">Vízszintes forgásvonal</string>\n    <string name=\"inverse_selection\">Inverz kiválasztás</string>\n    <string name=\"inverse_vertical_selection_sub\">A függőleges vágott rész kimarad, ahelyett, hogy a vágott terület körül egyesítené a részeket</string>\n    <string name=\"inverse_horizontal_selection_sub\">A vízszintes vágott rész meg lesz hagyva, ahelyett, hogy a vágott terület körül egyesítené a részeket</string>\n    <string name=\"collection_mesh_gradients\">Háló színátmenetek gyűjteménye</string>\n    <string name=\"mesh_gradients_sub\">Hozzon létre háló gradienst egyéni csomópontszámmal és felbontással</string>\n    <string name=\"gradient_maker_type_image_mesh\">Mesh gradiens fedvény</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Háló gradiens létrehozása adott képek tetején</string>\n    <string name=\"points_customization\">Pontok testreszabása</string>\n    <string name=\"grid_size\">Rács mérete</string>\n    <string name=\"resolution_x\">X. határozat</string>\n    <string name=\"resolution_y\">Y. határozat</string>\n    <string name=\"resolution\">Felbontás</string>\n    <string name=\"pixel_by_pixel\">Pixel by Pixel</string>\n    <string name=\"highlight_color\">Jelölje ki a Színt</string>\n    <string name=\"pixel_comparison_type\">Pixel-összehasonlítás típusa</string>\n    <string name=\"scan_barcode\">Vonalkód beolvasása</string>\n    <string name=\"height_ratio\">Magasság aránya</string>\n    <string name=\"barcode_type\">Vonalkód típusa</string>\n    <string name=\"enforce_bw\">B/W érvényesítése</string>\n    <string name=\"enforce_bw_sub\">A vonalkód kép teljesen fekete-fehér lesz, és nem színezi az alkalmazás témája</string>\n    <string name=\"barcodes_sub\">Szkenneljen be bármilyen vonalkódot (QR, EAN, AZTEC stb.), és szerezze be a tartalmát, vagy illessze be a szöveget új létrehozásához</string>\n    <string name=\"no_barcode_found\">Nem található vonalkód</string>\n    <string name=\"generated_barcode_will_be_here\">A generált vonalkód itt lesz</string>\n    <string name=\"audio_cover_extractor\">Audio borítók</string>\n    <string name=\"audio_cover_extractor_sub\">Az albumborítóképek kibontása hangfájlokból, a legtöbb általános formátum támogatott</string>\n    <string name=\"pick_audio_to_start\">Az indításhoz válassza ki a hangot</string>\n    <string name=\"pick_audio\">Válassza az Audio lehetőséget</string>\n    <string name=\"no_covers_found\">Nem található borító</string>\n    <string name=\"send_logs\">Naplók küldése</string>\n    <string name=\"send_logs_sub\">Kattintson az alkalmazásnaplófájl megosztásához, ez segíthet a probléma észlelésében és a problémák megoldásában</string>\n    <string name=\"crash_title\">Hoppá… Hiba történt</string>\n    <string name=\"crash_subtitle\">Az alábbi lehetőségek segítségével kapcsolatba léphet velem, és megpróbálok megoldást találni.\\n(Ne felejtse el csatolni a naplókat)</string>\n    <string name=\"ocr_write_to_file\">Írás fájlba</string>\n    <string name=\"ocr_write_to_file_sub\">Kivonja a szöveget a képek kötegéből, és tárolja egy szövegfájlban</string>\n    <string name=\"ocr_write_to_metadata\">Írás a metaadatokba</string>\n    <string name=\"ocr_write_to_metadata_sub\">Vonja ki a szöveget az egyes képekből, és helyezze el a relatív fotók EXIF-információi közé</string>\n    <string name=\"invisible_mode\">Láthatatlan mód</string>\n    <string name=\"invisible_mode_sub\">A szteganográfia segítségével szemmel láthatatlan vízjeleket hozhat létre a képek bájtjaiban</string>\n    <string name=\"use_lsb\">Használj LSB-t</string>\n    <string name=\"use_lsb_sub\">LSB (Less Significant Bit) szteganográfiai módszer kerül alkalmazásra, egyébként FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Vörös szemek automatikus eltávolítása</string>\n    <string name=\"password\">Jelszó</string>\n    <string name=\"unlock\">Kinyit</string>\n    <string name=\"pdf_is_protected\">A PDF védett</string>\n    <string name=\"operation_almost_complete\">A művelet majdnem kész. A mostani lemondáshoz újra kell indítani</string>\n    <string name=\"sort_by_date_modified\">Módosítás dátuma</string>\n    <string name=\"sort_by_date_modified_reversed\">Módosítás dátuma (megfordítva)</string>\n    <string name=\"sort_by_size\">Méret</string>\n    <string name=\"sort_by_size_reversed\">Méret (fordított)</string>\n    <string name=\"sort_by_mime_type\">MIME típus</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME típus (fordított)</string>\n    <string name=\"sort_by_extension\">Kiterjesztés</string>\n    <string name=\"sort_by_extension_reversed\">Kiterjesztés (fordított)</string>\n    <string name=\"sort_by_date_added\">Hozzáadás dátuma</string>\n    <string name=\"sort_by_date_added_reversed\">Hozzáadás dátuma (megfordítva)</string>\n    <string name=\"left_to_right\">Balról jobbra</string>\n    <string name=\"right_to_left\">Jobbról balra</string>\n    <string name=\"top_to_bottom\">Fentről lefelé</string>\n    <string name=\"bottom_to_top\">Alulról felfelé</string>\n    <string name=\"liquid_glass\">Folyékony üveg</string>\n    <string name=\"liquid_glass_sub\">A nemrég bejelentett IOS 26-on és annak folyékony üveg tervezési rendszerén alapuló kapcsoló</string>\n    <string name=\"pick_image_or_base64\">Válassza ki a képet vagy illessze be/importálja a Base64 adatokat alább</string>\n    <string name=\"type_image_link\">A kezdéshez írja be a kép hivatkozását</string>\n    <string name=\"paste_link\">Link beillesztése</string>\n    <string name=\"kaleidoscope\">Kaleidoszkóp</string>\n    <string name=\"secondary_angle\">Másodlagos szög</string>\n    <string name=\"sides\">Oldalak</string>\n    <string name=\"channel_mix\">Csatorna mix</string>\n    <string name=\"blue_green\">Kék zöld</string>\n    <string name=\"red_blue\">Piros kék</string>\n    <string name=\"green_red\">Zöld piros</string>\n    <string name=\"into_red\">Vörösbe</string>\n    <string name=\"into_green\">Zöldbe</string>\n    <string name=\"into_blue\">Kékbe</string>\n    <string name=\"cyan\">Cián</string>\n    <string name=\"magenta\">Bíborvörös</string>\n    <string name=\"yellow\">Sárga</string>\n    <string name=\"color_halftone\">Színes Féltónus</string>\n    <string name=\"contour\">Körvonal</string>\n    <string name=\"levels\">Szintek</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi kristályosodik</string>\n    <string name=\"shape\">Alak</string>\n    <string name=\"stretch\">Nyújtsd</string>\n    <string name=\"randomness\">Véletlenszerűség</string>\n    <string name=\"despeckle\">Folttalanítás</string>\n    <string name=\"diffuse\">Diffúz</string>\n    <string name=\"dog\">Kutya</string>\n    <string name=\"second_radius\">Második sugár</string>\n    <string name=\"equalize\">Egyenlíteni</string>\n    <string name=\"glow\">Izzás</string>\n    <string name=\"whirl_and_pinch\">Forgasd és csipkedj</string>\n    <string name=\"pointillize\">Pontozás</string>\n    <string name=\"border_color\">Szegély színe</string>\n    <string name=\"polar_coordinates\">Polárkoordináták</string>\n    <string name=\"rect_to_polar\">Közvetlenül a polárisra</string>\n    <string name=\"polar_to_rect\">Polárisról egyenesre</string>\n    <string name=\"invert_in_circle\">Fordítsa meg a kört</string>\n    <string name=\"reduce_noise\">Zaj csökkentése</string>\n    <string name=\"simple_solarize\">Egyszerű Solarize</string>\n    <string name=\"weave\">Szövés</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X szélesség</string>\n    <string name=\"y_wdth\">Y Szélesség</string>\n    <string name=\"twirl\">Forgat</string>\n    <string name=\"rubber_stmp\">Gumibélyegző</string>\n    <string name=\"smear\">Kenet</string>\n    <string name=\"density\">Sűrűség</string>\n    <string name=\"mix\">Keverék</string>\n    <string name=\"sphere_lensh_distortion\">Gömblencse torzítása</string>\n    <string name=\"refraction_index\">Törésmutató</string>\n    <string name=\"arc\">Ív</string>\n    <string name=\"spread_angle\">Terítési szög</string>\n    <string name=\"sparkle\">Szikra</string>\n    <string name=\"rays\">Sugarak</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradiens</string>\n    <string name=\"moire\">Mary</string>\n    <string name=\"autumn\">Őszi</string>\n    <string name=\"bone\">Csont</string>\n    <string name=\"jet\">Sugárhajtású</string>\n    <string name=\"winter\">Téli</string>\n    <string name=\"ocean\">Óceán</string>\n    <string name=\"summer\">Nyári</string>\n    <string name=\"spring\">Tavaszi</string>\n    <string name=\"cool_variant\">Cool Variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rózsaszín</string>\n    <string name=\"hot\">Forró</string>\n    <string name=\"parula\">Szó</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Pokol</string>\n    <string name=\"plasma\">Vérplazma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Polgárok</string>\n    <string name=\"twilight\">Szürkület</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspektíva Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Vágás engedélyezése</string>\n    <string name=\"crop_or_perspective\">Termés vagy perspektíva</string>\n    <string name=\"absolute\">Abszolút</string>\n    <string name=\"turbo\">Turbó</string>\n    <string name=\"deep_green\">Mélyzöld</string>\n    <string name=\"lens_correction\">Lencsekorrekció</string>\n    <string name=\"target_lens_profile\">A céllencse profilfájlja JSON formátumban</string>\n    <string name=\"download_ready_lens_profiles\">Töltse le a kész lencseprofilokat</string>\n    <string name=\"part_percents\">Rész százalékok</string>\n    <string name=\"export_as_json\">Exportálás JSON-ként</string>\n    <string name=\"export_as_json_sub\">Karakterlánc másolása palettaadatokkal JSON-ábrázolásként</string>\n    <string name=\"seam_carving\">Varrás faragás</string>\n    <string name=\"home_screen\">Kezdőképernyő</string>\n    <string name=\"lock_screen\">Képernyőzár</string>\n    <string name=\"built_in\">Beépített</string>\n    <string name=\"wallpapers_export\">Háttérképek exportálása</string>\n    <string name=\"refresh\">Frissítés</string>\n    <string name=\"wallpapers_export_sub\">Szerezze be az aktuális otthoni, zárolási és beépített háttérképeket</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Engedélyezze a hozzáférést az összes fájlhoz, ez szükséges a háttérképek letöltéséhez</string>\n    <string name=\"allow_read_media_images_for_wp\">A külső tárhely engedélyének kezelése nem elegendő, engedélyeznie kell a képekhez való hozzáférést, és feltétlenül válassza az \\\"Minden engedélyezése\\\" lehetőséget.</string>\n    <string name=\"add_preset_to_filename\">Előbeállítás hozzáadása a fájlnévhez</string>\n    <string name=\"add_preset_to_filename_sub\">A kiválasztott előre beállított utótagot hozzáfűzi a képfájl nevéhez</string>\n    <string name=\"add_image_scale_mode_to_filename\">Képméretezési mód hozzáadása a fájlnévhez</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">A kiválasztott képméretezési móddal utótagot fűz a képfájl nevéhez</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Konvertálja a képet ascii szöveggé, amely képnek fog kinézni</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Egyes esetekben negatív szűrőt alkalmaz a képre a jobb eredmény érdekében</string>\n    <string name=\"processing_screenshot\">Képernyőkép feldolgozása</string>\n    <string name=\"screenshot_not_captured_try_again\">A képernyőkép nem készült, próbálkozzon újra</string>\n    <string name=\"skipped_saving\">A mentés kimaradt</string>\n    <string name=\"skipped_saving_multiple\">%1$s fájl kimaradt</string>\n    <string name=\"allow_skip_if_larger\">Engedélyezze az átugrást, ha nagyobb</string>\n    <string name=\"allow_skip_if_larger_sub\">Egyes eszközök kihagyhatják a képek mentését, ha az eredményül kapott fájlméret nagyobb, mint az eredeti</string>\n    <string name=\"qr_type_calendar_event\">Eseménynaptár</string>\n    <string name=\"qr_type_contact_info\">Érintkezés</string>\n    <string name=\"qr_type_email\">Email</string>\n    <string name=\"qr_type_geo_point\">Elhelyezkedés</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Szöveg</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Nyitott hálózat</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Üzenet</string>\n    <string name=\"address\">Cím</string>\n    <string name=\"subject\">Téma</string>\n    <string name=\"body\">Test</string>\n    <string name=\"name\">Név</string>\n    <string name=\"organization\">Szervezet</string>\n    <string name=\"title\">Cím</string>\n    <string name=\"phones\">Telefonok</string>\n    <string name=\"emails\">E-mailek</string>\n    <string name=\"urls\">URL-ek</string>\n    <string name=\"addresses\">Címek</string>\n    <string name=\"summary\">Összegzés</string>\n    <string name=\"description\">Leírás</string>\n    <string name=\"location\">Elhelyezkedés</string>\n    <string name=\"organizer\">Szervező</string>\n    <string name=\"start_date\">Kezdés dátuma</string>\n    <string name=\"end_date\">Befejezés dátuma</string>\n    <string name=\"status\">Állapot</string>\n    <string name=\"latitude\">Szélesség</string>\n    <string name=\"longitude\">Hosszúság</string>\n    <string name=\"create_barcode\">Vonalkód létrehozása</string>\n    <string name=\"edit_barcode\">Vonalkód szerkesztése</string>\n    <string name=\"wifi_configuration\">Wi-Fi konfiguráció</string>\n    <string name=\"security\">Biztonság</string>\n    <string name=\"pick_contact\">Válassza ki a kapcsolatot</string>\n    <string name=\"grant_contact_permission\">Adjon engedélyt a névjegyeknek a beállításokban, hogy automatikusan kitöltsék a kiválasztott névjegyet</string>\n    <string name=\"contact_info\">Elérhetőségi adatok</string>\n    <string name=\"first_name\">Keresztnév</string>\n    <string name=\"middle_name\">Középső név</string>\n    <string name=\"last_name\">Vezetéknév</string>\n    <string name=\"pronunciation\">Kiejtés</string>\n    <string name=\"add_phone\">Telefon hozzáadása</string>\n    <string name=\"add_email\">E-mail hozzáadása</string>\n    <string name=\"add_address\">Adjon hozzá címet</string>\n    <string name=\"website\">Weboldal</string>\n    <string name=\"add_website\">Webhely hozzáadása</string>\n    <string name=\"formatted_name\">Formázott név</string>\n    <string name=\"qr_code_top_image\">Ezt a képet a vonalkód fölé helyezzük el</string>\n    <string name=\"code_customization\">Kód testreszabása</string>\n    <string name=\"qr_logo_image\">Ezt a képet logóként fogják használni a QR-kód közepén</string>\n    <string name=\"logo\">Logó</string>\n    <string name=\"logo_padding\">Logó párnázás</string>\n    <string name=\"logo_size\">Logó mérete</string>\n    <string name=\"logo_corners\">Logó sarkok</string>\n    <string name=\"fourth_eye\">Negyedik szem</string>\n    <string name=\"fourth_eye_description\">Szemszimmetriát ad a QR-kódhoz azáltal, hogy az alsó végsarokhoz hozzáad egy negyedik szemet</string>\n    <string name=\"pixel_shape\">Pixel alak</string>\n    <string name=\"frame_shape\">Keret alakja</string>\n    <string name=\"ball_shape\">Labda alakú</string>\n    <string name=\"error_correction_level\">Hibajavítási szint</string>\n    <string name=\"dark_color\">Sötét szín</string>\n    <string name=\"light_color\">Világos szín</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS-szerű stílus</string>\n    <string name=\"mask_pattern\">Maszk minta</string>\n    <string name=\"code_may_be_not_scannable\">Előfordulhat, hogy ez a kód nem szkennelhető, módosítsa a megjelenési paramétereket, hogy minden eszközzel olvasható legyen</string>\n    <string name=\"not_scannable\">Nem szkennelhető</string>\n    <string name=\"launcher_mode_sub\">Az eszközök úgy néznek ki, mint a kezdőképernyőn megjelenő alkalmazásindító, hogy kompaktabbak legyenek</string>\n    <string name=\"launcher_mode\">Indító mód</string>\n    <string name=\"flood_fill_sub\">Egy területet kitölt a kiválasztott ecsettel és stílussal</string>\n    <string name=\"flood_fill\">Flood Fill</string>\n    <string name=\"spray\">Permet</string>\n    <string name=\"spray_sub\">Graffity stílusú útvonalat rajzol</string>\n    <string name=\"square_particles\">Négyzet alakú részecskék</string>\n    <string name=\"square_particles_sub\">A permetező részecskék körök helyett négyzet alakúak lesznek</string>\n    <string name=\"palette_tools\">Paletta eszközök</string>\n    <string name=\"palette_tools_sub\">Létrehozhat alap/anyagot a palettán a képből, vagy importálhat/exportálhat különböző palettaformátumokba</string>\n    <string name=\"edit_palette\">Paletta szerkesztése</string>\n    <string name=\"edit_palette_sub\">Exportálás/importálás paletta különböző formátumokba</string>\n    <string name=\"color_name\">Színnév</string>\n    <string name=\"palette_name\">A paletta neve</string>\n    <string name=\"palette_format\">Paletta formátum</string>\n    <string name=\"export_palette_sub\">A létrehozott paletta exportálása különböző formátumokba</string>\n    <string name=\"add_color_palette_sub\">Új színt ad az aktuális palettához</string>\n    <string name=\"palette_name_not_supported\">A %1$s formátum nem támogatja a palettanév megadását</string>\n    <string name=\"wallpapers_export_not_avaialbe\">A Play Áruház irányelvei miatt ez a funkció nem illeszthető bele a jelenlegi buildbe. A funkció eléréséhez töltse le az ImageToolbox alkalmazást egy másik forrásból. A GitHubon elérhető buildeket alább találja.</string>\n    <string name=\"open_github_page\">Nyissa meg a Github oldalt</string>\n    <string name=\"overwrite_files_sub_short\">Az eredeti fájl a kiválasztott mappába való mentés helyett újra cserélődik</string>\n    <string name=\"hidden_watermark_text_detected\">Rejtett vízjelszöveg észlelve</string>\n    <string name=\"hidden_watermark_image_detected\">Rejtett vízjelképet észlelt</string>\n    <string name=\"this_image_was_hidden\">Ez a kép el volt rejtve</string>\n    <string name=\"generative_inpaint\">Generatív festészet</string>\n    <string name=\"generative_inpaint_sub\">Lehetővé teszi objektumok eltávolítását a képről mesterséges intelligencia modell segítségével, anélkül, hogy az OpenCV-re támaszkodna. A funkció használatához az alkalmazás letölti a szükséges modellt (~200 MB) a GitHubról</string>\n    <string name=\"generative_inpaint_ready_sub\">Lehetővé teszi objektumok eltávolítását a képről mesterséges intelligencia modell segítségével, anélkül, hogy az OpenCV-re támaszkodna. Ez egy hosszú ideig tartó művelet lehet</string>\n    <string name=\"error_level_analysis\">Hibaszint-elemzés</string>\n    <string name=\"luminance_gradient\">Fényerő gradiens</string>\n    <string name=\"average_distance\">Átlagos távolság</string>\n    <string name=\"copy_move_detection\">Mozgásérzékelés másolása</string>\n    <string name=\"retain\">Tartsa meg</string>\n    <string name=\"coefficent\">Együttható</string>\n    <string name=\"clipboard_data_is_too_large\">A vágólap adatai túl nagyok</string>\n    <string name=\"data_is_too_large_to_copy\">Az adatok túl nagyok a másoláshoz</string>\n    <string name=\"simple_weave_pixelization\">Egyszerű szövés pixelizálás</string>\n    <string name=\"staggered_pixelization\">Lépcsőzetes pixelizáció</string>\n    <string name=\"cross_pixelization\">Keresztpixelizáció</string>\n    <string name=\"micro_macro_pixelization\">Mikro makró pixelizálás</string>\n    <string name=\"orbital_pixelization\">Orbitális pixelizáció</string>\n    <string name=\"vortex_pixelization\">Vortex pixelizálás</string>\n    <string name=\"pulse_grid_pixelization\">Impulzus rács pixelizálás</string>\n    <string name=\"nucleus_pixelization\">A mag pixelizációja</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave pixelizáció</string>\n    <string name=\"cannot_open_uri\">Nem lehet megnyitni a következőt: \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Havazás mód</string>\n    <string name=\"enabled\">Engedélyezve</string>\n    <string name=\"border_frame\">Szegély keret</string>\n    <string name=\"glitch_variant\">Glitch Variant</string>\n    <string name=\"channel_shift\">Csatornaváltás</string>\n    <string name=\"max_offset\">Max Offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Glitch blokkolása</string>\n    <string name=\"block_size\">Blokkméret</string>\n    <string name=\"crt_curvature\">CRT görbület</string>\n    <string name=\"curvature\">Görbület</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">AI eszközök</string>\n    <string name=\"ai_tools_sub\">Különféle eszközök a képek feldolgozásához ai modelleken keresztül, például műtermékek eltávolítása vagy zajtalanítása</string>\n    <string name=\"model_anime_undeint\">Tömörítés, szaggatott vonalak</string>\n    <string name=\"model_broadcast\">Rajzfilmek, adás tömörítés</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Általános tömörítés, általános zaj</string>\n    <string name=\"model_wb_denoise\">Színtelen rajzfilm zaj</string>\n    <string name=\"model_span_anime_pretrain\">Gyors, általános tömörítés, általános zaj, animáció/képregény/anime</string>\n    <string name=\"model_book_scan\">Könyv szkennelés</string>\n    <string name=\"model_overexposure\">Expozíció korrekció</string>\n    <string name=\"model_fbcnn_color_fp16\">A legjobb általános tömörítésnél, színes képeknél</string>\n    <string name=\"model_fbcnn_gray_fp16\">A legjobb az általános tömörítésnél, szürkeárnyalatos képeknél</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Általános tömörítés, szürkeárnyalatos képek, erősebb</string>\n    <string name=\"model_scunet_color_gan_fp16\">Általános zaj, színes képek</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Általános zaj, színes képek, jobb részletek</string>\n    <string name=\"model_scunet_gray_15_fp16\">Általános zaj, szürkeárnyalatos képek</string>\n    <string name=\"model_scunet_gray_25_fp16\">Általános zaj, szürkeárnyalatos képek, erősebbek</string>\n    <string name=\"model_scunet_gray_50_fp16\">Általános zaj, szürkeárnyalatos képek, legerősebb</string>\n    <string name=\"model_jpeg_destroyer\">Általános tömörítés</string>\n    <string name=\"model_jaywreck\">Általános tömörítés</string>\n    <string name=\"model_h264\">Texturizálás, h264 tömörítés</string>\n    <string name=\"model_vhs\">VHS tömörítés</string>\n    <string name=\"model_cinepak\">Nem szabványos tömörítés (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink tömörítés, jobb a geometriában</string>\n    <string name=\"model_debink_v5\">Bink tömörítés, erősebb</string>\n    <string name=\"model_debink_v6\">Bink tömörítés, puha, megőrzi a részleteket</string>\n    <string name=\"model_antialias\">Lépcső-lépés hatás megszüntetése, simítás</string>\n    <string name=\"model_kdm_scans\">Szkennelt műalkotások/rajzok, enyhe tömörítés, moire</string>\n    <string name=\"model_bandage\">Színes sávozás</string>\n    <string name=\"model_halftone\">Lassú, féltónusok eltávolítása</string>\n    <string name=\"model_colorizer\">Általános színező a szürkeárnyalatos/fekete képekhez, a jobb eredmény érdekében használja a DDColort</string>\n    <string name=\"model_deedge\">Él eltávolítása</string>\n    <string name=\"model_desharpen\">Eltávolítja a túlélezést</string>\n    <string name=\"model_dither\">Lassú, háborgó</string>\n    <string name=\"model_gainres\">Anti-aliasing, általános műtermékek, CGI</string>\n    <string name=\"model_kdm003_scans\">A KDM003 vizsgálati feldolgozás</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Könnyű képjavító modell</string>\n    <string name=\"model_bcgone_detailed_v2\">Tömörítési műtermékek eltávolítása</string>\n    <string name=\"model_bcgone_smooth\">Tömörítési műtermékek eltávolítása</string>\n    <string name=\"model_bandage_smooth\">Kötszer eltávolítás sima eredménnyel</string>\n    <string name=\"model_bendel_halftone\">Féltónus minta feldolgozás</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Dither minta eltávolítása V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG műtermék eltávolítása V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 textúra javítás</string>\n    <string name=\"model_vhs_sharpen\">VHS élesítés és javítás</string>\n    <string name=\"merging\">Összevonás</string>\n    <string name=\"chunk_size\">Darab mérete</string>\n    <string name=\"overlap_size\">Átfedési méret</string>\n    <string name=\"note_chunk_info\">A %1$s px-nél nagyobb képeket a rendszer szeletelve és darabokban dolgozza fel, átfedésben keveri ezeket a látható varratok elkerülése érdekében.</string>\n    <string name=\"large_chunk_warning\">A nagy méretek instabilitást okozhatnak az alacsony kategóriás eszközöknél</string>\n    <string name=\"select_one_to_start\">Válasszon egyet az indításhoz</string>\n    <string name=\"delete_model_sub\">Törli a %1$s modellt? Újra le kell töltenie</string>\n    <string name=\"confirm\">Erősítse meg</string>\n    <string name=\"models\">Modellek</string>\n    <string name=\"downloaded_models\">Letöltött modellek</string>\n    <string name=\"available_models\">Elérhető modellek</string>\n    <string name=\"preparing\">Felkészülés</string>\n    <string name=\"active_model\">Aktív modell</string>\n    <string name=\"failed_to_open_session\">Nem sikerült megnyitni a munkamenetet</string>\n    <string name=\"only_onnx_models\">Csak .onnx/.ort modellek importálhatók</string>\n    <string name=\"import_model\">Import modell</string>\n    <string name=\"import_model_sub\">Egyéni onnx modell importálása további használatra, csak az onnx/ort modellek fogadhatók el, szinte minden esrgan-szerű változatot támogat</string>\n    <string name=\"imported_models\">Importált modellek</string>\n    <string name=\"model_scunet_color_15_fp16\">Általános zaj, színes képek</string>\n    <string name=\"model_scunet_color_25_fp16\">Általános zaj, színes képek, erősebbek</string>\n    <string name=\"model_scunet_color_50_fp16\">Általános zaj, színes képek, a legerősebb</string>\n    <string name=\"model_artifacts_dithering_alsa\">Csökkenti a dithering műtermékeket és a színsávosodást, javítja a sima színátmeneteket és az egyenletes színterületeket.</string>\n    <string name=\"model_nmkd_brighten_redux\">Fokozza a kép fényerejét és kontrasztját a kiegyensúlyozott fénypontokkal, miközben megőrzi a természetes színeket.</string>\n    <string name=\"model_nmkd_brighten\">Világosabbá teszi a sötét képeket, miközben megtartja a részleteket és elkerüli a túlexponálást.</string>\n    <string name=\"model_nmkd_detoon\">Eltávolítja a túlzott színtónust, és visszaállítja a semlegesebb és természetesebb színegyensúlyt.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Poisson-alapú zajtonizálást alkalmaz, hangsúlyt fektetve a finom részletek és textúrák megőrzésére.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Lágy Poisson zajtónizálást alkalmaz a simább és kevésbé agresszív vizuális eredmény érdekében.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Egységes zajtónus a részletek megőrzésére és a kép tisztaságára összpontosít.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Gyengéd, egyenletes zajtónus a finom textúra és sima megjelenés érdekében.</string>\n    <string name=\"model_repainter\">Javítja a sérült vagy egyenetlen területeket a műtermékek újrafestésével és a kép konzisztenciájának javításával.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Könnyű sávbontású modell, amely minimális teljesítményköltséggel távolítja el a színsávokat.</string>\n    <string name=\"model_jpeg_0_20\">Optimalizálja a képeket nagyon nagy tömörítésű műtermékekkel (0-20%-os minőség) a jobb tisztaság érdekében.</string>\n    <string name=\"model_jpeg_20_40\">Javítja a képeket nagy tömörítésű műtermékekkel (20-40%-os minőség), visszaállítja a részleteket és csökkenti a zajt.</string>\n    <string name=\"model_jpeg_40_60\">Javítja a képeket mérsékelt tömörítéssel (40-60%-os minőség), egyensúlyban tartva az élességet és a simaságot.</string>\n    <string name=\"model_jpeg_60_80\">Finomítja a képeket enyhe tömörítéssel (60-80%-os minőség), hogy javítsa a finom részleteket és textúrákat.</string>\n    <string name=\"model_jpeg_80_100\">Kissé javítja a szinte veszteségmentes képeket (80-100%-os minőség), miközben megőrzi a természetes megjelenést és a részleteket.</string>\n    <string name=\"model_spongecolor_lite\">Egyszerű és gyors színezés, rajzfilmek, nem ideális</string>\n    <string name=\"model_deblr\">Kissé csökkenti a kép elmosódását, javítja az élességet anélkül, hogy műtermékeket okozna.</string>\n    <string name=\"processing_channel\">Hosszú távú műveletek</string>\n    <string name=\"processing_image\">Kép feldolgozása</string>\n    <string name=\"processing\">Feldolgozás</string>\n    <string name=\"model_artifacts_jpg_0_20\">Eltávolítja a nehéz JPEG tömörítési műtermékeket a nagyon gyenge minőségű képekről (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Csökkenti az erős JPEG műtermékeket az erősen tömörített képeken (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Megtisztítja a közepes JPEG műtermékeket, miközben megőrzi a kép részleteit (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Finomítja a könnyű JPEG műtermékeket meglehetősen jó minőségű képeken (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Finoman csökkenti a kisebb JPEG műtermékeket a szinte veszteségmentes képeken (80-100%).</string>\n    <string name=\"model_redetail_v2\">Javítja a finom részleteket és textúrákat, javítja az észlelt élességet súlyos műtermékek nélkül.</string>\n    <string name=\"processing_finished\">A feldolgozás befejeződött</string>\n    <string name=\"processing_failed\">A feldolgozás sikertelen</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Javítja a bőr textúráját és részleteit, miközben megőrzi a természetes megjelenést, a sebességre optimalizálva.</string>\n    <string name=\"model_sbdv_dejpeg\">Eltávolítja a JPEG tömörítési műtermékeket, és visszaállítja a tömörített fényképek képminőségét.</string>\n    <string name=\"model_iso_denoise_v1\">Csökkenti az ISO-zajt a gyenge fényviszonyok mellett készült fényképeken, megőrzi a részleteket.</string>\n    <string name=\"model_dejumbo\">Javítja a túlexponált vagy „jumbo” kiemeléseket, és helyreállítja a jobb tónusegyensúlyt.</string>\n    <string name=\"model_ddcolor_tiny\">Könnyű és gyors színezésű modell, amely természetes színeket ad a szürkeárnyalatos képekhez.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Színezd ki</string>\n    <string name=\"type_artifacts\">Műtárgyak</string>\n    <string name=\"type_enhance\">Növelje</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Szkennel</string>\n    <string name=\"type_upscale\">Előkelő</string>\n    <string name=\"model_realesrgan_x4v3\">X4 felskálázó általános képekhez; apró modell, amely kevesebb GPU-t és időt használ, mérsékelt elmosódással és zajjal.</string>\n    <string name=\"model_realesrgan_x2plus\">X2-es felskálázó az általános képekhez, a textúrák és a természetes részletek megőrzéséhez.</string>\n    <string name=\"model_realesrgan_x4plus\">X4-es felskálázó általános képekhez továbbfejlesztett textúrákkal és valósághű eredményekkel.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Anime képekhez optimalizált X4 felskálázó; 6 RRDB blokk az élesebb vonalak és részletek érdekében.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 felskálázó MSE veszteséggel, egyenletesebb eredményeket és kevesebb műterméket biztosít az általános képekhez.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">Anime képekhez optimalizált X4 Upscaler; 4B32F változat élesebb részletekkel és sima vonalakkal.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 modell általános képekhez; kiemeli az élességet és a tisztaságot.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; gyorsabb és kisebb, megőrzi a részleteket, miközben kevesebb GPU-memóriát használ.</string>\n    <string name=\"model_rmbg_1_4\">Könnyű modell a háttér gyors eltávolításához. Kiegyensúlyozott teljesítmény és pontosság. Portrékkal, tárgyakkal és jelenetekkel működik. A legtöbb használati esetre ajánlott.</string>\n    <string name=\"type_removebg\">Távolítsa el a BG-t</string>\n    <string name=\"horizontal_border_thickness\">Vízszintes határvastagság</string>\n    <string name=\"vertical_border_thickness\">Függőleges határvastagság</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s színek</item>\n        <item quantity=\"other\">%1$s színek</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">A jelenlegi modell nem támogatja a darabolást, a kép az eredeti méretekben kerül feldolgozásra, ami nagy memóriafogyasztást és problémákat okozhat az alsó kategóriás eszközökkel</string>\n    <string name=\"chunking_disabled\">A darabolás le van tiltva, a kép az eredeti méretekben kerül feldolgozásra, ami nagy memóriafogyasztást és problémákat okozhat az alsó kategóriás eszközökkel, de jobb eredményeket ad a következtetéseknél</string>\n    <string name=\"chunking\">Dobogó</string>\n    <string name=\"model_u2net\">Nagy pontosságú képszegmentációs modell a háttér eltávolításához</string>\n    <string name=\"model_u2netp\">Az U2Net könnyű változata a háttér gyorsabb eltávolításához kisebb memóriahasználat mellett.</string>\n    <string name=\"model_ddcolor\">A Full DDColor modell kiváló minőségű színezést biztosít az általános képekhez minimális műtermékekkel. A legjobb választás az összes színezési modell közül.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Képzett és privát művészi adatkészletek; változatos és művészi színezési eredményeket hoz létre kevesebb irreális színművel.</string>\n    <string name=\"model_birefnet\">Swin Transformer alapú könnyű BiRefNet modell a pontos háttér eltávolításhoz.</string>\n    <string name=\"model_inspyrenet\">Kiváló minőségű háttéreltávolítás éles szélekkel és kiváló részletmegőrzéssel, különösen összetett tárgyakon és bonyolult háttereken.</string>\n    <string name=\"model_isnet\">Háttéreltávolító modell, amely pontos, sima élű maszkokat készít, általános tárgyakhoz és mérsékelt részletmegőrzéshez alkalmas.</string>\n    <string name=\"model_already_downloaded\">A modell már letöltve</string>\n    <string name=\"model_successfully_imported\">A modell sikeresen importálva</string>\n    <string name=\"type\">Írja be</string>\n    <string name=\"keyword\">Kulcsszó</string>\n    <string name=\"very_fast\">Nagyon gyors</string>\n    <string name=\"normal\">Normál</string>\n    <string name=\"slow\">Lassú</string>\n    <string name=\"very_slow\">Nagyon lassú</string>\n    <string name=\"compute_percents\">Számítsd ki a százalékokat</string>\n    <string name=\"minimum_value_is\">A minimális érték %1$s</string>\n    <string name=\"warp_sub\">Kép torzítása ujjakkal való rajzolással</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">Keménység</string>\n    <string name=\"warp_mode\">Warp mód</string>\n    <string name=\"warp_mode_move\">Mozog</string>\n    <string name=\"warp_mode_grow\">Nő</string>\n    <string name=\"warp_mode_shrink\">Összezsugorodik</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Örvény CCW</string>\n    <string name=\"fade_strength\">Fade Strength</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Alsó csepp</string>\n    <string name=\"start_drop\">Start Drop</string>\n    <string name=\"end_drop\">Vége csepp</string>\n    <string name=\"downloading\">Letöltés</string>\n    <string name=\"smooth_shapes\">Sima formák</string>\n    <string name=\"smooth_shapes_sub\">Használjon szuperellipszeket a szokásos lekerekített téglalapok helyett a simább, természetesebb formák érdekében</string>\n    <string name=\"shape_type\">Alaktípus</string>\n    <string name=\"cut\">Vágott</string>\n    <string name=\"rounded\">Lekerekített</string>\n    <string name=\"smooth\">Sima</string>\n    <string name=\"cut_shapes_sub\">Éles élek lekerekítés nélkül</string>\n    <string name=\"rounded_shapes_sub\">Klasszikus lekerekített sarkok</string>\n    <string name=\"shapes_type\">Formák típusa</string>\n    <string name=\"corners_size\">Sarkok mérete</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elegáns, lekerekített felhasználói felület elemei</string>\n    <string name=\"filename_format\">Fájlnév formátum</string>\n    <string name=\"prefix_pattern_description\">A fájlnév legelején elhelyezett egyéni szöveg, tökéletes projektnevekhez, márkákhoz vagy személyes címkékhez.</string>\n    <string name=\"original_filename_pattern_description\">Az eredeti fájlnevet használja kiterjesztés nélkül, így segít megőrizni a forrás azonosítását.</string>\n    <string name=\"width_pattern_description\">A kép szélessége pixelben, hasznos a felbontás változásainak követéséhez vagy az eredmények méretezéséhez.</string>\n    <string name=\"height_pattern_description\">A képmagasság pixelben, ami hasznos a képarányok vagy az exportálás során.</string>\n    <string name=\"random_numbers_pattern_description\">Véletlen számjegyeket generál az egyedi fájlnevek garantálása érdekében; adjon hozzá több számjegyet az ismétlődések elleni fokozott biztonság érdekében.</string>\n    <string name=\"sequence_number_pattern_description\">Automatikusan növekvő számláló kötegelt exportáláshoz, ideális több kép mentéséhez egy munkamenetben.</string>\n    <string name=\"preset_info_pattern_description\">Az alkalmazott előre beállított nevet beszúrja a fájlnévbe, így könnyen megjegyezheti, hogyan dolgozták fel a képet.</string>\n    <string name=\"scale_mode_pattern_description\">Megjeleníti a feldolgozás során használt képméretezési módot, segítve az átméretezett, vágott vagy illesztett képek megkülönböztetését.</string>\n    <string name=\"suffix_pattern_description\">A fájlnév végén elhelyezett egyéni szöveg, amely hasznos a verziószámításhoz, például a _v2, _edited vagy _final.</string>\n    <string name=\"extension_pattern_description\">A fájl kiterjesztése (png, jpg, webp stb.), amely automatikusan megfelel a tényleges mentett formátumnak.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Egy testreszabható időbélyeg, amely lehetővé teszi, hogy saját formátumot határozzon meg Java specifikációval a tökéletes rendezés érdekében.</string>\n    <string name=\"fling_type\">Fling típus</string>\n    <string name=\"android_native\">Android natív</string>\n    <string name=\"ios_style\">iOS stílus</string>\n    <string name=\"smooth_curve\">Sima görbe</string>\n    <string name=\"quick_stop\">Gyors Stop</string>\n    <string name=\"bouncy\">Ugráló</string>\n    <string name=\"floaty\">Úszó</string>\n    <string name=\"snappy\">Lendületes</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">Adaptív</string>\n    <string name=\"accessibility_aware\">Kisegítő lehetőségek tudatában</string>\n    <string name=\"reduced_motion\">Csökkentett mozgás</string>\n    <string name=\"android_native_sub\">Natív Android görgetőfizika az alapvonal összehasonlításához</string>\n    <string name=\"smooth_sub\">Kiegyensúlyozott, sima görgetés általános használatra</string>\n    <string name=\"ios_style_sub\">Nagyobb súrlódású iOS-szerű görgetési viselkedés</string>\n    <string name=\"smooth_curve_sub\">Egyedülálló spline-görbe a határozott görgetéshez</string>\n    <string name=\"quick_stop_sub\">Precíz görgetés gyors leállítással</string>\n    <string name=\"bouncy_sub\">Játékos, érzékeny pattogó tekercs</string>\n    <string name=\"floaty_sub\">Hosszú, csúszó tekercsek a tartalomböngészéshez</string>\n    <string name=\"snappy_sub\">Gyors, érzékeny görgetés az interaktív felhasználói felületekhez</string>\n    <string name=\"ultra_smooth_sub\">Prémium sima görgetés kiterjesztett lendülettel</string>\n    <string name=\"adaptive_sub\">A fizikát a kirepülési sebesség alapján állítja be</string>\n    <string name=\"accessibility_aware_sub\">Tiszteletben tartja a rendszer akadálymentesítési beállításait</string>\n    <string name=\"reduced_motion_sub\">Minimális mozgás a hozzáférhetőségi igényekhez</string>\n    <string name=\"primary_lines\">Elsődleges vonalak</string>\n    <string name=\"primary_lines_sub\">Minden ötödik sor vastagabb vonalat ad hozzá</string>\n    <string name=\"fill_color\">Kitöltés színe</string>\n    <string name=\"hidden_tools\">Rejtett eszközök</string>\n    <string name=\"hidden_for_share\">Megosztáshoz rejtett eszközök</string>\n    <string name=\"color_library\">Színes könyvtár</string>\n    <string name=\"color_library_sub\">Böngésszen a színek hatalmas gyűjteményében</string>\n    <string name=\"model_fatality_deblur\">Élesíti és eltávolítja a képek elmosódását, miközben megőrzi a természetes részleteket, ideális az életlen fényképek kijavításához.</string>\n    <string name=\"model_unresize_v3\">Intelligensen visszaállítja a korábban átméretezett képeket, helyreállítva az elveszett részleteket és textúrákat.</string>\n    <string name=\"model_liveaction_v1_span\">Élőszereplős tartalomhoz optimalizálva, csökkenti a tömörítési műtermékeket, és javítja a film/TV-műsor képkockáinak finom részleteit.</string>\n    <string name=\"model_vhs2hd_realplksr\">A VHS-minőségű felvételeket HD-vé alakítja, eltávolítja a szalagzajt és javítja a felbontást, miközben megőrzi a vintage hangulatot.</string>\n    <string name=\"model_text2hd_v1\">A nehéz szöveget tartalmazó képekre és képernyőképekre specializálódott, élesíti a karaktereket és javítja az olvashatóságot.</string>\n    <string name=\"model_frankendata_pretrainer\">Különféle adatkészletekre kiképzett fejlett felskálázás, kiváló általános célú fényképjavításhoz.</string>\n    <string name=\"model_realwebphoto_v2\">Interneten tömörített fényképekhez optimalizálva, eltávolítja a JPEG műtermékeket és visszaállítja a természetes megjelenést.</string>\n    <string name=\"model_realwebphoto_v4\">Továbbfejlesztett változat webes fényképekhez jobb textúramegőrzéssel és műtermékcsökkentéssel.</string>\n    <string name=\"model_dat_2x\">Kétszeres felskálázás a Dual Aggregation Transformer technológiával, megőrzi az élességet és a természetes részleteket.</string>\n    <string name=\"model_dat_3x\">3-szoros felskálázás fejlett transzformátor architektúrával, ideális közepes nagyítási igényekhez.</string>\n    <string name=\"model_dat_4x\">4x kiváló minőségű felskálázás a legmodernebb transzformátor hálózattal, megőrzi a finom részleteket nagyobb méretekben.</string>\n    <string name=\"model_nafnet_deblurring\">Eltávolítja az elmosódást/zajt és a remegést a fényképekről. Általános célú, de legjobb fotókon.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Az alacsony minőségű képeket visszaállítja a Swin2SR transzformátor segítségével, amely a BSRGAN leromlására van optimalizálva. Kiválóan alkalmas erős tömörítési műtermékek rögzítésére és 4-szeres léptékű részletek javítására.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x-es felskálázás a BSRGAN degradációra kiképzett SwinIR transzformátorral. GAN-t használ az élesebb textúrák és a természetesebb részletek érdekében a fényképeken és az összetett jeleneteken.</string>\n    <string name=\"path\">Útvonal</string>\n    <string name=\"merge_pdf\">PDF egyesítése</string>\n    <string name=\"merge_pdf_sub\">Több PDF fájl egyesítése egyetlen dokumentumban</string>\n    <string name=\"files_order\">Fájlok sorrendje</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">PDF felosztása</string>\n    <string name=\"split_pdf_sub\">Konkrét oldalak kibontása a PDF-dokumentumból</string>\n    <string name=\"rotate_pdf\">PDF forgatása</string>\n    <string name=\"rotate_pdf_sub\">Állandóan javítsa az oldal tájolását</string>\n    <string name=\"pages\">Oldalak</string>\n    <string name=\"rearrange_pdf\">PDF átrendezése</string>\n    <string name=\"rearrange_pdf_sub\">Az oldalak átrendezéséhez húzza át őket</string>\n    <string name=\"hold_drag_drop\">Tartsa és húzza az oldalakat</string>\n    <string name=\"page_numbers\">Oldalszámok</string>\n    <string name=\"page_numbers_sub\">Automatikusan adja hozzá a számozást a dokumentumokhoz</string>\n    <string name=\"label_format\">Címke formátum</string>\n    <string name=\"pdf_to_text\">PDF szöveggé (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Egyszerű szöveg kinyerése PDF-dokumentumaiból</string>\n    <string name=\"watermark_pdf_sub\">Egyéni fedvényszöveg márkaépítéshez vagy biztonsághoz</string>\n    <string name=\"signature\">Aláírás</string>\n    <string name=\"signature_sub\">Adja hozzá elektronikus aláírását bármely dokumentumhoz</string>\n    <string name=\"will_be_for_signature\">Ezt aláírásként fogják használni</string>\n    <string name=\"unlock_pdf\">PDF feloldása</string>\n    <string name=\"unlock_pdf_sub\">Távolítsa el a jelszavakat a védett fájljaiból</string>\n    <string name=\"protect_pdf\">PDF védelme</string>\n    <string name=\"protect_pdf_sub\">Biztosítsa dokumentumait erős titkosítással</string>\n    <string name=\"success\">Siker</string>\n    <string name=\"pdf_unlocked\">PDF feloldva, mentheti vagy megoszthatja</string>\n    <string name=\"repair_pdf\">PDF javítása</string>\n    <string name=\"repair_pdf_sub\">Próbálja meg kijavítani a sérült vagy olvashatatlan dokumentumokat</string>\n    <string name=\"grayscale\">Szürkeárnyalatos</string>\n    <string name=\"grayscale_pdf_sub\">Konvertálja az összes dokumentumba ágyazott képet szürkeárnyalatossá</string>\n    <string name=\"compress_pdf\">PDF tömörítése</string>\n    <string name=\"compress_pdf_sub\">Optimalizálja a dokumentumfájl méretét a könnyebb megosztás érdekében</string>\n    <string name=\"repair_info\">Az ImageToolbox újraépíti a belső kereszthivatkozási táblát, és a semmiből regenerálja a fájlstruktúrát. Ezzel visszaállíthatja a hozzáférést számos olyan fájlhoz, amelyeket \\\\\"nem lehet megnyitni\\\\\"</string>\n    <string name=\"grayscale_info\">Ez az eszköz az összes dokumentumképet szürkeárnyalatossá alakítja. A legjobb a nyomtatáshoz és a fájlméret csökkentéséhez</string>\n    <string name=\"metadata\">Metaadatok</string>\n    <string name=\"metadata_pdf_sub\">Szerkessze a dokumentum tulajdonságait a jobb adatvédelem érdekében</string>\n    <string name=\"tags\">Címkék</string>\n    <string name=\"producer\">Termelő</string>\n    <string name=\"author\">Szerző</string>\n    <string name=\"keywords\">Kulcsszavak</string>\n    <string name=\"creator\">Teremtő</string>\n    <string name=\"privacy_deep_clean\">Adatvédelem Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Törölje a dokumentum összes elérhető metaadatát</string>\n    <string name=\"page\">oldal</string>\n    <string name=\"deep_ocr\">Mély OCR</string>\n    <string name=\"deep_ocr_sub\">Kivonja a szöveget a dokumentumból, és tárolja azt egyetlen szövegfájlban a Tesseract motor segítségével</string>\n    <string name=\"cant_remove_all\">Nem lehet eltávolítani az összes oldalt</string>\n    <string name=\"remove_pages_pdf\">PDF-oldalak eltávolítása</string>\n    <string name=\"remove_pages_pdf_sub\">Adott oldalak eltávolítása a PDF-dokumentumból</string>\n    <string name=\"tap_to_remove\">Koppintson az Eltávolítás elemre</string>\n    <string name=\"manually\">Manuálisan</string>\n    <string name=\"crop_pdf\">PDF vágása</string>\n    <string name=\"crop_pdf_sub\">A dokumentum oldalainak levágása tetszőleges határig</string>\n    <string name=\"flatten_pdf\">PDF lapítása</string>\n    <string name=\"flatten_pdf_sub\">A PDF-et módosíthatatlanná teheti a dokumentumoldalak raszterezésével</string>\n    <string name=\"camera_failed_to_open\">Nem sikerült elindítani a kamerát. Kérjük, ellenőrizze az engedélyeket, és győződjön meg arról, hogy más alkalmazás nem használja.</string>\n    <string name=\"extract_images\">Képek kibontása</string>\n    <string name=\"extract_images_sub\">Kivonja a PDF-be ágyazott képeket eredeti felbontásukban</string>\n    <string name=\"pdf_no_embedded\">Ez a PDF-fájl nem tartalmaz beágyazott képeket</string>\n    <string name=\"extract_images_info\">Ez az eszköz minden oldalt beolvas, és teljes minőségű forrásképeket állít vissza – tökéletes az eredeti dokumentumok dokumentumokból való mentéséhez</string>\n    <string name=\"draw_signature\">Aláírás rajzolása</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">Használjon saját aláírást képként a dokumentumokon</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Ossza fel a dokumentumot adott időközönként, és csomagolja az új dokumentumokat zip archívumba</string>\n    <string name=\"interval\">Intervallum</string>\n    <string name=\"print_pdf\">Nyomtatás PDF</string>\n    <string name=\"print_pdf_sub\">Készítse elő a dokumentumot egyéni oldalmérettel történő nyomtatáshoz</string>\n    <string name=\"pages_per_sheet\">Oldalak Laponként</string>\n    <string name=\"orientation\">Tájolás</string>\n    <string name=\"page_size\">Oldalméret</string>\n    <string name=\"margin\">Margó</string>\n    <string name=\"bloom\">Virágzás</string>\n    <string name=\"soft_knee\">Puha térd</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Animéhez és rajzfilmekhez optimalizálva. Gyors felskálázás továbbfejlesztett természetes színekkel és kevesebb műtermékkel</string>\n    <string name=\"one_ui_sub\">A Samsung One UI 7 stílusa</string>\n    <string name=\"calculate_hint\">Írja be ide az alapvető matematikai szimbólumokat a kívánt érték kiszámításához (pl. (5+5)*10)</string>\n    <string name=\"math_expression\">Matematikai kifejezés</string>\n    <string name=\"pick_up_to_n_collage_images\">Válasszon legfeljebb %1$s képet</string>\n    <string name=\"keep_date_time\">Tartsa a dátumot és az időt</string>\n    <string name=\"keep_date_time_sub\">Mindig őrizze meg a dátumhoz és az időhöz kapcsolódó exif címkéket, az exif megtartása opciótól függetlenül működik</string>\n    <string name=\"background_color_for_alpha_formats\">Háttérszín Alfa formátumokhoz</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Lehetővé teszi a háttérszín beállítását minden alfa-támogatással rendelkező képformátumhoz, ha le van tiltva, ez csak a nem alfa-formátumok esetén érhető el</string>\n    <string name=\"open_markup_project\">Projekt megnyitása</string>\n    <string name=\"open_markup_project_sub\">Folytassa a korábban elmentett Image Toolbox projekt szerkesztését</string>\n    <string name=\"markup_project_open_failed\">Nem lehet megnyitni az Image Toolbox projektet</string>\n    <string name=\"markup_project_missing_data\">Az Image Toolbox projektből hiányoznak a projektadatok</string>\n    <string name=\"markup_project_corrupted\">Az Image Toolbox projekt sérült</string>\n    <string name=\"unsupported_markup_project_version\">Nem támogatott Image Toolbox projektverzió: %1$d</string>\n    <string name=\"save_markup_project\">Projekt mentése</string>\n    <string name=\"save_markup_project_sub\">Tárolja a rétegeket, a hátteret és a szerkesztési előzményeket egy szerkeszthető projektfájlban</string>\n    <string name=\"failed_to_open\">Nem sikerült megnyitni</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Írás kereshető PDF-be</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Szöveg felismerése képkötegből, és kereshető PDF mentése képpel és kiválasztható szövegréteggel</string>\n    <string name=\"layer_alpha\">Alfa réteg</string>\n    <string name=\"horizontal_flip\">Vízszintes Flip</string>\n    <string name=\"vertical_flip\">Függőleges Flip</string>\n    <string name=\"lock\">Zár</string>\n    <string name=\"add_shadow\">Árnyék hozzáadása</string>\n    <string name=\"shadow_color\">Árnyék színe</string>\n    <string name=\"text_geometry\">Szöveggeometria</string>\n    <string name=\"text_geometry_sub\">Nyújtsa vagy ferdítse a szöveget az élesebb stilizáció érdekében</string>\n    <string name=\"scale_x\">X skála</string>\n    <string name=\"skew_x\">Ferde X</string>\n    <string name=\"remove_annotations\">Távolítsa el a megjegyzéseket</string>\n    <string name=\"remove_annotations_sub\">A kiválasztott megjegyzéstípusok, például hivatkozások, megjegyzések, kiemelések, alakzatok vagy űrlapmezők eltávolítása a PDF-oldalakról</string>\n    <string name=\"annotation_link\">Hiperhivatkozások</string>\n    <string name=\"annotation_file_attachment\">Fájlmellékletek</string>\n    <string name=\"annotation_line\">Vonalak</string>\n    <string name=\"annotation_popup\">Előugró ablakok</string>\n    <string name=\"annotation_stamp\">Bélyegek</string>\n    <string name=\"annotation_shapes\">Alakzatok</string>\n    <string name=\"annotation_text\">Szöveg Megjegyzések</string>\n    <string name=\"annotation_text_markup\">Szövegjelölés</string>\n    <string name=\"annotation_widget\">Űrlapmezők</string>\n    <string name=\"annotation_markup\">Jelölés</string>\n    <string name=\"annotation_unknown\">Ismeretlen</string>\n    <string name=\"annotations\">Annotációk</string>\n    <string name=\"ungroup\">Csoportbontás feloldása</string>\n    <string name=\"add_shadow_sub\">Adjon hozzá homályos árnyékot a réteg mögé konfigurálható színekkel és eltolásokkal</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-in/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"smth_went_wrong\">Ada yang tidak beres: %1$s</string>\n    <string name=\"size\">Ukuran %1$s</string>\n    <string name=\"copied\">Disalin ke papan klip</string>\n    <string name=\"cancel\">Batal</string>\n    <string name=\"pick_color\">Pilih warna</string>\n    <string name=\"pick_color_sub\">Pilih warna dari gambar, salin atau bagikan</string>\n    <string name=\"keep_exif\">Simpan EXIF</string>\n    <string name=\"images\">Gambar: %d</string>\n    <string name=\"change_preview\">Ubah pratinjau</string>\n    <string name=\"remove\">Menghapus</string>\n    <string name=\"def\">Default</string>\n    <string name=\"light\">Cahaya</string>\n    <string name=\"system\">Sistem</string>\n    <string name=\"dynamic_colors\">Warna-warna yang dinamis</string>\n    <string name=\"customization\">Kustomisasi</string>\n    <string name=\"about_app\">Tentang aplikasi</string>\n    <string name=\"nothing_found_by_search\">Tidak ada yang ditemukan oleh kueri Anda</string>\n    <string name=\"add\">Menambahkan</string>\n    <string name=\"loading\">Memuat…</string>\n    <string name=\"image_too_large_preview\">Gambar terlalu besar untuk dipratinjau, tetapi akan dicoba untuk disimpan</string>\n    <string name=\"pick_image\">Pilih gambar untuk memulai</string>\n    <string name=\"width\">Lebar %1$s</string>\n    <string name=\"height\">Tinggi %1$s</string>\n    <string name=\"quality\">Kualitas</string>\n    <string name=\"extension\">Perluasan</string>\n    <string name=\"resize_type\">Mengubah ukuran jenis</string>\n    <string name=\"explicit\">Eksplisit</string>\n    <string name=\"flexible\">Fleksibel</string>\n    <string name=\"pick_image_alt\">Pilih Gambar</string>\n    <string name=\"app_closing_sub\">Apakah Anda ingin menutup aplikasi?</string>\n    <string name=\"app_closing\">Penutupan aplikasi</string>\n    <string name=\"stay\">Tetap di sini</string>\n    <string name=\"close\">Tutup</string>\n    <string name=\"reset_image\">Atur ulang gambar</string>\n    <string name=\"reset_image_sub\">Perubahan gambar akan dikembalikan ke semula</string>\n    <string name=\"values_reset\">Nilai diatur ulang dengan benar</string>\n    <string name=\"reset\">Atur ulang</string>\n    <string name=\"something_went_wrong\">Ada yang tidak beres</string>\n    <string name=\"restart_app\">Mulai ulang aplikasi</string>\n    <string name=\"exception\">Pengecualian</string>\n    <string name=\"edit_exif\">Edit EXIF</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">Tidak ditemukan data EXIF</string>\n    <string name=\"add_tag\">Tambahkan tag</string>\n    <string name=\"save\">Simpan</string>\n    <string name=\"clear\">Bersihkan</string>\n    <string name=\"clear_exif\">Hapus EXIF</string>\n    <string name=\"clear_exif_sub\">Semua data EXIF gambar akan dihapus, tindakan ini tidak dapat dibatalkan!</string>\n    <string name=\"presets\">Preset</string>\n    <string name=\"crop\">Pangkas</string>\n    <string name=\"image_not_saved\">Menyimpan</string>\n    <string name=\"image_not_saved_sub\">Semua perubahan yang belum disimpan akan hilang, jika Anda keluar sekarang</string>\n    <string name=\"check_source_code\">Kode sumber</string>\n    <string name=\"check_source_code_sub\">Dapatkan informasi terbaru, diskusikan berbagai isu, dan lainnya</string>\n    <string name=\"single_edit\">Ubah ukuran tunggal</string>\n    <string name=\"single_edit_sub\">Mengubah spesifikasi gambar tunggal yang diberikan</string>\n    <string name=\"image\">Gambar</string>\n    <string name=\"color\">Warna</string>\n    <string name=\"color_copied\">Warna disalin</string>\n    <string name=\"crop_sub\">Pangkas gambar hingga batas apa pun</string>\n    <string name=\"version\">Versi</string>\n    <string name=\"palette_sub\">Menghasilkan contoh palet warna dari gambar yang diberikan</string>\n    <string name=\"generate_palette\">Menghasilkan palet</string>\n    <string name=\"palette\">Palet</string>\n    <string name=\"update\">Memperbarui</string>\n    <string name=\"new_version\">Versi baru %1$s</string>\n    <string name=\"unsupported_type\">Jenis yang tidak didukung: %1$s</string>\n    <string name=\"no_palette\">Tidak dapat menghasilkan palet untuk gambar yang diberikan</string>\n    <string name=\"original\">Asli</string>\n    <string name=\"folder\">Folder keluaran</string>\n    <string name=\"custom\">Kustom</string>\n    <string name=\"unspecified\">Tidak ditentukan</string>\n    <string name=\"device_storage\">Penyimpanan perangkat</string>\n    <string name=\"by_bytes_resize\">Ubah ukuran berdasarkan berat</string>\n    <string name=\"max_bytes\">Ukuran maksimum dalam KB</string>\n    <string name=\"by_bytes_resize_sub\">Mengubah ukuran gambar mengikuti ukuran yang diberikan dalam KB</string>\n    <string name=\"compare\">Bandingkan</string>\n    <string name=\"compare_sub\">Bandingkan dua gambar yang diberikan</string>\n    <string name=\"pick_two_images\">Pilih dua gambar untuk memulai</string>\n    <string name=\"pick_images\">Pilih gambar</string>\n    <string name=\"settings\">Pengaturan</string>\n    <string name=\"night_mode\">Mode Malam</string>\n    <string name=\"dark\">Gelap</string>\n    <string name=\"allow_image_monet\">Izinkan monetisasi gambar</string>\n    <string name=\"allow_image_monet_sub\">Jika diaktifkan, ketika Anda memilih gambar untuk diedit, warna aplikasi akan diadopsi ke gambar ini</string>\n    <string name=\"language\">Bahasa</string>\n    <string name=\"amoled_mode\">Mode Amoled</string>\n    <string name=\"amoled_mode_sub\">Jika diaktifkan, warna permukaan akan ditetapkan ke gelap mutlak dalam mode malam</string>\n    <string name=\"color_scheme\">Skema warna</string>\n    <string name=\"color_red\">Merah</string>\n    <string name=\"color_green\">Hijau</string>\n    <string name=\"color_blue\">Biru</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Rekatkan Kode aRGB yang valid.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Tidak ada yang bisa ditempelkan</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Tidak dapat mengubah skema warna aplikasi saat warna dinamis diaktifkan</string>\n    <string name=\"pick_accent_color\">Tema aplikasi akan didasarkan pada warna yang dipilih</string>\n    <string name=\"no_updates\">Tidak ada pembaruan yang ditemukan</string>\n    <string name=\"issue_tracker\">Pelacak masalah</string>\n    <string name=\"issue_tracker_sub\">Kirim laporan bug dan permintaan fitur di sini</string>\n    <string name=\"help_translate\">Bantu menerjemahkan</string>\n    <string name=\"help_translate_sub\">Memperbaiki kesalahan terjemahan atau melokalkan proyek ke bahasa lain</string>\n    <string name=\"search_here\">Cari di sini</string>\n    <string name=\"dynamic_colors_sub\">Jika diaktifkan, maka warna aplikasi akan diadopsi ke warna wallpaper</string>\n    <string name=\"failed_to_save\">Gagal menyimpan gambar %d</string>\n    <string name=\"primary\">Primer</string>\n    <string name=\"tertiary\">Tersier</string>\n    <string name=\"secondary\">Sekunder</string>\n    <string name=\"border_thickness\">Ketebalan perbatasan</string>\n    <string name=\"surface\">Permukaan</string>\n    <string name=\"values\">Nilai-nilai</string>\n    <string name=\"permission\">Izin</string>\n    <string name=\"grant\">Hibah</string>\n    <string name=\"permission_sub\">Aplikasi perlu akses ke penyimpanan Anda untuk menyimpan gambar untuk bekerja, Harap berikan izin di kotak dialog berikutnya.</string>\n    <string name=\"grant_permission_manual\">Aplikasi membutuhkan izin ini untuk bekerja, mohon berikan secara manual</string>\n    <string name=\"external_storage\">Penyimpanan eksternal</string>\n    <string name=\"monet_colors\">Warna monet</string>\n    <string name=\"donation_sub\">Aplikasi ini sepenuhnya gratis, tetapi jika Anda ingin mendukung pengembangan proyek, Anda dapat mengklik di sini</string>\n    <string name=\"fab_alignment\">Penyelarasan FAB</string>\n    <string name=\"check_updates\">Periksa pembaruan</string>\n    <string name=\"check_updates_sub\">Jika diaktifkan, dialog pembaruan akan ditampilkan kepada Anda setelah aplikasi dimulai</string>\n    <string name=\"zoom\">Zoom gambar</string>\n    <string name=\"share\">Bagikan</string>\n    <string name=\"prefix\">Awalan</string>\n    <string name=\"filename\">Nama file</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Pilih emoji mana yang akan ditampilkan di layar utama</string>\n    <string name=\"add_file_size\">Tambah ukuran file</string>\n    <string name=\"add_file_size_sub\">Jika diaktifkan, menambahkan lebar dan tinggi gambar yang disimpan ke nama file output</string>\n    <string name=\"delete_exif\">Hapus EXIF</string>\n    <string name=\"delete_exif_sub\">Hapus metadata EXIF dari beberapa gambar</string>\n    <string name=\"image_preview_sub\">Pratinjau semua jenis gambar: GIF, SVG, dan sebagainya</string>\n    <string name=\"image_preview\">Pratinjau gambar</string>\n    <string name=\"order_sub\">Menentukan urutan alat di layar utama</string>\n    <string name=\"photo_picker_sub\">Pemilih foto modern Android yang muncul di bagian bawah layar, mungkin hanya berfungsi pada Android 12+ dan juga memiliki masalah dengan penerimaan metadata EXIF</string>\n    <string name=\"image_source\">Sumber gambar</string>\n    <string name=\"photo_picker\">Pemilih foto</string>\n    <string name=\"file_explorer_picker\">Penjelajah file</string>\n    <string name=\"gallery_picker_sub\">Pemilih gambar galeri sederhana, hanya akan berfungsi jika Anda memiliki aplikasi tersebut</string>\n    <string name=\"options_arrangement\">Pengaturan opsi</string>\n    <string name=\"edit\">Ubah</string>\n    <string name=\"order\">Urutan</string>\n    <string name=\"emojis_count\">Jumlah emoji</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"add_original_filename\">Tambahkan nama file asli</string>\n    <string name=\"add_original_filename_sub\">Jika diaktifkan, akan menambahkan nama file asli pada nama gambar output</string>\n    <string name=\"file_explorer_picker_sub\">Gunakan GetContent untuk memilih gambar, berfungsi di mana saja, tetapi juga dapat mengalami masalah dengan menerima gambar yang dipilih pada beberapa perangkat, itu bukan kesalahan saya</string>\n    <string name=\"replace_sequence_number\">Ganti nomor urut</string>\n    <string name=\"replace_sequence_number_sub\">Jika diaktifkan akan menggantikan cap waktu standar ke nomor urut gambar jika Anda menggunakan pemrosesan batch</string>\n    <string name=\"filename_not_work_with_photopicker\">Menambahkan nama file asli tidak berfungsi jika sumber gambar pemilih foto dipilih</string>\n    <string name=\"tint\">Warna</string>\n    <string name=\"monochrome\">Satu warna</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Sorotan dan bayangan</string>\n    <string name=\"negative\">Negatif</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">Jarak</string>\n    <string name=\"line_width\">Lebar garis</string>\n    <string name=\"radius\">Radius</string>\n    <string name=\"scale\">Skala</string>\n    <string name=\"add_filter\">Tambahkan filter</string>\n    <string name=\"limits_resize\">Batas mengubah ukuran</string>\n    <string name=\"limits_resize_sub\">Ubah ukuran gambar yang diberikan untuk mengikuti batas lebar dan tinggi yang diberikan dengan rasio aspek hemat</string>\n    <string name=\"sketch\">Sketsa</string>\n    <string name=\"threshold\">Ambang</string>\n    <string name=\"non_maximum_suppression\">Penindasan tidak maksimal</string>\n    <string name=\"lookup\">Lihatlah</string>\n    <string name=\"stack_blur\">Tumpukan buram</string>\n    <string name=\"fast_blur\">kabur cepat</string>\n    <string name=\"load_image_from_net\">Muat gambar dari net</string>\n    <string name=\"load_image_from_net_sub\">Muat gambar apa pun dari internet, pratinjau, perbesar, dan juga simpan atau edit jika Anda mau</string>\n    <string name=\"image_link\">Tautan gambar</string>\n    <string name=\"fill\">Mengisi</string>\n    <string name=\"fit\">Bugar</string>\n    <string name=\"content_scale\">Skala konten</string>\n    <string name=\"explicit_description\">Memaksa setiap gambar menjadi gambar yang ditentukan oleh parameter Lebar dan Tinggi - dapat mengubah rasio aspek</string>\n    <string name=\"flexible_description\">Mengubah ukuran gambar menjadi gambar dengan sisi panjang yang ditentukan oleh parameter Lebar atau Tinggi, semua penghitungan ukuran akan dilakukan setelah menyimpan - mempertahankan rasio aspek</string>\n    <string name=\"brightness\">Kecerahan</string>\n    <string name=\"contrast\">Kontras</string>\n    <string name=\"hue\">Warna</string>\n    <string name=\"saturation\">Kejenuhan</string>\n    <string name=\"filter\">Saring</string>\n    <string name=\"filter_sub\">Terapkan rantai filter apa pun ke gambar yang diberikan</string>\n    <string name=\"filters\">Filter</string>\n    <string name=\"light_aka_illumination\">Lampu</string>\n    <string name=\"color_filter\">Penyaring warna</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"exposure\">Paparan</string>\n    <string name=\"white_balance\">Keseimbangan putih</string>\n    <string name=\"temperature\">Suhu</string>\n    <string name=\"highlights\">Highlight</string>\n    <string name=\"shadows\">Bayangan</string>\n    <string name=\"haze\">Kabut</string>\n    <string name=\"effect\">Memengaruhi</string>\n    <string name=\"distance\">Jarak</string>\n    <string name=\"slope\">Lereng</string>\n    <string name=\"sharpen\">Mengasah</string>\n    <string name=\"sepia\">Warna coklat tua</string>\n    <string name=\"solarize\">Solarisasi</string>\n    <string name=\"vibrance\">Getaran</string>\n    <string name=\"black_and_white\">Hitam dan putih</string>\n    <string name=\"sobel_edge\">Tepi sobel</string>\n    <string name=\"blur\">Mengaburkan</string>\n    <string name=\"halftone\">Setengah suara</string>\n    <string name=\"cga_colorspace\">ruang warna GCA</string>\n    <string name=\"gaussian_blur\">gaussian blur</string>\n    <string name=\"box_blur\">Kabur kotak</string>\n    <string name=\"bilaterial_blur\">Kabur bilateral</string>\n    <string name=\"emboss\">Menatah</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Skema</string>\n    <string name=\"start\">Awal</string>\n    <string name=\"end\">Akhir</string>\n    <string name=\"kuwahara\">Kuwahara menghaluskan</string>\n    <string name=\"distortion\">Distorsi</string>\n    <string name=\"angle\">Sudut</string>\n    <string name=\"swirl\">Keramaian</string>\n    <string name=\"bulge\">Tonjolan</string>\n    <string name=\"dilation\">Pelebaran</string>\n    <string name=\"sphere_refraction\">Refraksi bola</string>\n    <string name=\"refractive_index\">Indeks bias</string>\n    <string name=\"glass_sphere_refraction\">Refraksi bola kaca</string>\n    <string name=\"color_matrix\">Matriks warna</string>\n    <string name=\"opacity\">Kegelapan</string>\n    <string name=\"quantizationLevels\">Tingkat kuantisasi</string>\n    <string name=\"smooth_toon\">Toon halus</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Buat poster</string>\n    <string name=\"weak_pixel_inclusion\">Inklusi piksel lemah</string>\n    <string name=\"convolution3x3\">Konvolusi 3x3</string>\n    <string name=\"rgb_filter\">penyaring RGB</string>\n    <string name=\"false_color\">Warna palsu</string>\n    <string name=\"first_color\">Warna pertama</string>\n    <string name=\"second_color\">Warna kedua</string>\n    <string name=\"reorder\">Susun ulang</string>\n    <string name=\"blur_size\">Ukuran buram</string>\n    <string name=\"blur_center_x\">Pusat buram x</string>\n    <string name=\"blur_center_y\">Pusat buram y</string>\n    <string name=\"zoom_blur\">Zoom buram</string>\n    <string name=\"color_balance\">Keseimbangan warna</string>\n    <string name=\"luminance_threshold\">Ambang batas pencahayaan</string>\n    <string name=\"gallery_picker\">Galeri</string>\n    <string name=\"no_image\">Tidak ada gambar</string>\n    <string name=\"file_size\">Ukuran file</string>\n    <string name=\"cache_size\">Ukuran cache</string>\n    <string name=\"draw_sub\">Gambarlah seperti di buku sketsa, atau gambarlah di latar belakang itu sendiri</string>\n    <string name=\"paint_color\">Warna cat</string>\n    <string name=\"paint_alpha\">Cat alfa</string>\n    <string name=\"draw_on_image\">Menggambar pada gambar</string>\n    <string name=\"draw_on_image_sub\">Pilih gambar dan gambar sesuatu di atasnya</string>\n    <string name=\"draw_on_background\">Menggambar di latar belakang</string>\n    <string name=\"store_file_desc\">Simpan file ini di perangkat Anda atau gunakan tindakan berbagi untuk meletakkannya di mana pun Anda mau</string>\n    <string name=\"skip\">Melewati</string>\n    <string name=\"warning_bytes\">Menyimpan dalam mode %1$s bisa jadi tidak stabil, karena merupakan format lossless</string>\n    <string name=\"activate_files\">Anda menonaktifkan aplikasi File, aktifkan untuk menggunakan fitur ini</string>\n    <string name=\"draw\">Menggambar</string>\n    <string name=\"background_color\">Warna latar belakang</string>\n    <string name=\"encrypt\">Enkripsi</string>\n    <string name=\"decrypt\">Dekripsi</string>\n    <string name=\"implementation_sub\">AES-256, mode GCM, tanpa padding, infus acak 12 byte. Kunci digunakan sebagai hash SHA-3 (256 bit).</string>\n    <string name=\"compatibility\">Kesesuaian</string>\n    <string name=\"found_s\">Ditemukan %1$s</string>\n    <string name=\"auto_cache_clearing_sub\">Jika diaktifkan, cache aplikasi akan dihapus saat memulai aplikasi</string>\n    <string name=\"tools\">Peralatan</string>\n    <string name=\"group_options_by_type\">Kelompokkan opsi berdasarkan jenis</string>\n    <string name=\"group_options_by_type_sub\">Opsi grup di layar utama jenisnya alih-alih pengaturan daftar kustom</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Tidak dapat mengubah pengaturan saat pengelompokan opsi diaktifkan</string>\n    <string name=\"decryption\">Dekripsi</string>\n    <string name=\"compatibility_sub\">Harap perhatikan bahwa kompatibilitas dengan perangkat lunak atau layanan enkripsi file lainnya tidak dijamin. Perawatan kunci atau konfigurasi sandi yang sedikit berbeda mungkin menjadi alasan ketidakcocokan.</string>\n    <string name=\"secondary_customization\">Kustomisasi sekunder</string>\n    <string name=\"draw_on_background_sub\">Pilih warna latar belakang dan gambar di atasnya</string>\n    <string name=\"pick_file_to_start\">Pilih file untuk memulai</string>\n    <string name=\"encryption\">Enkripsi</string>\n    <string name=\"image_size_warning\">Mencoba menyimpan gambar dengan lebar dan tinggi tertentu dapat menyebabkan kesalahan OOM, lakukan ini dengan risiko Anda sendiri, dan jangan bilang saya tidak memperingatkan Anda!</string>\n    <string name=\"auto_cache_clearing\">Pembersihan cache otomatis</string>\n    <string name=\"edit_screenshot\">Sunting tangkapan layar</string>\n    <string name=\"screenshot\">Tangkapan layar</string>\n    <string name=\"fallback_option\">Opsi mundur</string>\n    <string name=\"copy\">Menyalin</string>\n    <string name=\"cipher\">Sandi</string>\n    <string name=\"cipher_sub\">Enkripsi dan Dekripsi file apa pun (tidak hanya gambar) berdasarkan algoritme kripto AES</string>\n    <string name=\"pick_file\">Pilih berkas</string>\n    <string name=\"key\">Kunci</string>\n    <string name=\"features\">Fitur</string>\n    <string name=\"implementation\">Penerapan</string>\n    <string name=\"file_size_sub\">Ukuran file maksimum dibatasi oleh OS Android dan memori yang tersedia, yang jelas bergantung pada perangkat Anda. \\nHarap diperhatikan: memori bukanlah penyimpanan.</string>\n    <string name=\"file_proceed\">Berkas diproses</string>\n    <string name=\"invalid_password_or_not_encrypted\">Kata sandi tidak valid atau file yang dipilih tidak dienkripsi</string>\n    <string name=\"features_sub\">Enkripsi file berbasis kata sandi. File yang diproses dapat disimpan di direktori yang dipilih atau dibagikan. File yang didekripsi juga bisa langsung dibuka.</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"create\">Membuat</string>\n    <string name=\"presets_sub_bytes\">Preset di sini menentukan % dari file output, misalnya jika Anda memilih preset 50 pada gambar 5mb maka Anda akan mendapatkan gambar 2,5mb setelah disimpan</string>\n    <string name=\"presets_sub\" formatted=\"false\">Jika Anda memilih preset 125, gambar akan disimpan dengan ukuran 125% dari gambar asli. Jika Anda memilih preset 50, gambar akan disimpan dengan ukuran 50%</string>\n    <string name=\"randomize_filename_sub\">Jika diaktifkan, nama file keluaran akan sepenuhnya acak</string>\n    <string name=\"randomize_filename\">Acak nama file</string>\n    <string name=\"saved_to\">Simpan ke folder %1$s dengan nama %2$s</string>\n    <string name=\"saved_to_without_filename\">Disimpan ke folder %1$s</string>\n    <string name=\"tg_chat\">Obrolan Telegram</string>\n    <string name=\"tg_chat_sub\">Diskusikan aplikasi dan dapatkan tanggapan dari pengguna lain, di sini Anda bisa mendapatkan pembaruan dan wawasan beta</string>\n    <string name=\"columns_count\">Hitungan Kolom</string>\n    <string name=\"enhanced_pixelation\">Pikselasi yang Ditingkatkan</string>\n    <string name=\"stroke_pixelation\">Pikselasi Goresan</string>\n    <string name=\"enhanced_diamond_pixelation\">Pikselasi Berlian yang Ditingkatkan</string>\n    <string name=\"diamond_pixelation\">Pikselasi Berlian</string>\n    <string name=\"symbols\">Simbol</string>\n    <string name=\"draw_mode\">Modus menggambar</string>\n    <string name=\"enhanced_glitch\">Kesalahan yang Ditingkatkan</string>\n    <string name=\"channel_shift_x\">Pergeseran Saluran X</string>\n    <string name=\"corruption_shift_y\">Pergeseran Korupsi Y</string>\n    <string name=\"activities\">Kegiatan</string>\n    <string name=\"food_and_drink\">Makanan dan minuman</string>\n    <string name=\"contact_me\">Hubungi saya</string>\n    <string name=\"brush_softness\">Kelembutan sikat</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"restore_image\">Pulihkan gambar</string>\n    <string name=\"erase_background\">Hapus latar belakang</string>\n    <string name=\"draw_arrows_sub\">Jika diaktifkan, jalur gambar akan direpresentasikan sebagai panah penunjuk</string>\n    <string name=\"backup\">Cadangan</string>\n    <string name=\"settings_restored\">Pengaturan berhasil dipulihkan</string>\n    <string name=\"emotions\">Emosi</string>\n    <string name=\"auto_erase_background\">Hapus latar belakang secara otomatis</string>\n    <string name=\"create_issue\">Buat Masalah</string>\n    <string name=\"pipette\">Pipet</string>\n    <string name=\"text\">Teks</string>\n    <string name=\"delete_color_scheme_title\">Hapus Skema</string>\n    <string name=\"font\">huruf</string>\n    <string name=\"using_large_fonts_warn\">Menggunakan skala font yang besar dapat menyebabkan gangguan dan masalah UI, yang tidak dapat diperbaiki. Gunakan dengan hati-hati.</string>\n    <string name=\"restore_sub\">Pulihkan pengaturan aplikasi dari file yang dibuat sebelumnya</string>\n    <string name=\"erase_mode\">Modus hapus</string>\n    <string name=\"travels_and_places\">Perjalanan dan Tempat</string>\n    <string name=\"updates\">Pembaruan</string>\n    <string name=\"segmentation_mode_osd_only\">Orientasi &amp; Hanya Deteksi Skrip</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientasi Otomatis &amp; Deteksi Skrip</string>\n    <string name=\"segmentation_mode_auto_only\">Hanya otomatis</string>\n    <string name=\"segmentation_mode_auto\">Mobil</string>\n    <string name=\"segmentation_mode_single_line\">Garis tunggal</string>\n    <string name=\"segmentation_mode_single_word\">Kata tunggal</string>\n    <string name=\"segmentation_mode_circle_word\">Lingkari kata</string>\n    <string name=\"glitch\">Kesalahan</string>\n    <string name=\"amount\">Jumlah</string>\n    <string name=\"seed\">Benih</string>\n    <string name=\"anaglyph\">Anaglif</string>\n    <string name=\"noise\">Kebisingan</string>\n    <string name=\"pixel_sort\">Sortir Piksel</string>\n    <string name=\"shuffle\">Acak</string>\n    <string name=\"delete_mask_warn\">Anda akan menghapus masker filter yang dipilih. Operasi ini tidak dapat dibatalkan</string>\n    <string name=\"delete_mask\">Hapus Masker</string>\n    <string name=\"drago\">Naga</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Memotong</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Transisi</string>\n    <string name=\"peak\">Puncak</string>\n    <string name=\"color_anomaly\">Anomali Warna</string>\n    <string name=\"no_such_directory\">Direktori \\\"%1$s\\\" tidak ditemukan, kami mengalihkannya ke direktori default, harap simpan kembali file tersebut</string>\n    <string name=\"clipboard\">papan klip</string>\n    <string name=\"auto_pin\">Pin otomatis</string>\n    <string name=\"vibration\">Getaran</string>\n    <string name=\"vibration_strength\">Kekuatan Getaran</string>\n    <string name=\"overwrite_files\">Timpa File</string>\n    <string name=\"empty\">Kosong</string>\n    <string name=\"suffix\">Akhiran</string>\n    <string name=\"search_option\">Mencari</string>\n    <string name=\"search_option_sub\">Memungkinkan kemampuan untuk mencari melalui semua alat yang tersedia di layar utama</string>\n    <string name=\"free\">Bebas</string>\n    <string name=\"images_overwritten\">Gambar ditimpa di tujuan semula</string>\n    <string name=\"emoji_as_color_scheme\">Emoji sebagai Skema Warna</string>\n    <string name=\"crop_mask\">Masker tanaman</string>\n    <string name=\"aspect_ratio\">Rasio aspek</string>\n    <string name=\"image_crop_mask_sub\">Gunakan jenis topeng ini untuk membuat topeng dari gambar tertentu, perhatikan bahwa gambar tersebut HARUS memiliki saluran alfa</string>\n    <string name=\"backup_and_restore\">Cadangkan dan pulihkan</string>\n    <string name=\"reset_settings_sub\">Ini akan mengembalikan pengaturan Anda ke nilai default. Perhatikan bahwa ini tidak dapat dibatalkan tanpa file cadangan yang disebutkan di atas.</string>\n    <string name=\"delete_color_scheme_warn\">Anda akan menghapus skema warna yang dipilih. Operasi ini tidak dapat dibatalkan</string>\n    <string name=\"font_scale\">Skala font</string>\n    <string name=\"defaultt\">Bawaan</string>\n    <string name=\"nature_and_animals\">Alam dan Hewan</string>\n    <string name=\"objects\">Objek</string>\n    <string name=\"enable_emoji\">Aktifkan emoji</string>\n    <string name=\"background_remover\">Penghapus latar belakang</string>\n    <string name=\"background_remover_sub\">Hapus latar belakang dari gambar dengan menggambar atau menggunakan opsi Otomatis</string>\n    <string name=\"trim_image\">Pangkas gambar</string>\n    <string name=\"keep_exif_sub\">Metadata gambar asli akan disimpan</string>\n    <string name=\"trim_image_sub\">Ruang transparan di sekitar gambar akan dipangkas</string>\n    <string name=\"blur_radius\">Radius kabur</string>\n    <string name=\"something_went_wrong_emphasis\">Ups… Ada yang tidak beres. Anda dapat menulis kepada saya menggunakan opsi di bawah ini dan saya akan mencoba mencari solusinya</string>\n    <string name=\"resize_and_convert_sub\">Ubah ukuran gambar tertentu atau konversikan ke format lain. Metadata EXIF juga dapat diedit di sini jika memilih satu gambar.</string>\n    <string name=\"crashlytics_sub\">Hal ini memungkinkan aplikasi mengumpulkan laporan kerusakan secara manual</string>\n    <string name=\"analytics\">Analisis</string>\n    <string name=\"image_exif_warning\">Saat ini, format %1$s hanya mengizinkan pembacaan metadata EXIF di Android. Gambar keluaran tidak akan memiliki metadata sama sekali saat disimpan.</string>\n    <string name=\"saving_almost_complete\">Penghematan hampir selesai. Membatalkan sekarang memerlukan penyimpanan lagi.</string>\n    <string name=\"allow_betas\">Izinkan beta</string>\n    <string name=\"allow_betas_sub\">Pemeriksaan pembaruan akan mencakup versi aplikasi beta jika diaktifkan</string>\n    <string name=\"horizontal\">Horisontal</string>\n    <string name=\"scale_small_images_to_large\">Skalakan gambar kecil ke besar</string>\n    <string name=\"scale_small_images_to_large_sub\">Gambar kecil akan diperbesar ke gambar terbesar secara berurutan jika diaktifkan</string>\n    <string name=\"blur_edges_sub\">Menggambar tepi buram di bawah gambar asli untuk mengisi ruang di sekitarnya, bukan satu warna jika diaktifkan</string>\n    <string name=\"pixelation\">Pikselasi</string>\n    <string name=\"enhanced_circle_pixelation\">Pikselasi Lingkaran yang Ditingkatkan</string>\n    <string name=\"tolerance\">Toleransi</string>\n    <string name=\"color_to_replace\">Warna untuk Diganti</string>\n    <string name=\"target_color\">Warna Sasaran</string>\n    <string name=\"remove_color\">Hapus Warna</string>\n    <string name=\"recode\">Kode ulang</string>\n    <string name=\"neutral_sub\">Sebuah gaya yang sedikit lebih berwarna daripada monokrom</string>\n    <string name=\"vibrant_sub\">Tema yang keras, warna-warni maksimal untuk palet Primer, meningkat untuk palet lainnya</string>\n    <string name=\"playful_scheme\">Tema yang menyenangkan - rona warna sumber tidak muncul dalam tema</string>\n    <string name=\"monochrome_sub\">Tema monokrom, warna murni hitam/putih/abu-abu</string>\n    <string name=\"content_sub\">Skema yang menempatkan warna sumber di Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Skema yang sangat mirip dengan skema konten</string>\n    <string name=\"disabled\">Dengan disabilitas</string>\n    <string name=\"mask_filter\">Filter Masker</string>\n    <string name=\"mask_filter_sub\">Terapkan rantai filter pada area bertopeng tertentu, setiap area topeng dapat menentukan kumpulan filternya sendiri</string>\n    <string name=\"add_mask\">Tambahkan Masker</string>\n    <string name=\"mask_indexed\">Masker %d</string>\n    <string name=\"mask_preview_sub\">Masker filter yang digambar akan ditampilkan untuk menunjukkan kepada Anda hasil perkiraan</string>\n    <string name=\"simple_variants\">Varian Sederhana</string>\n    <string name=\"highlighter\">Stabilo</string>\n    <string name=\"privacy_blur\">Privasi Kabur</string>\n    <string name=\"highlighter_sub\">Gambarlah jalur stabilo runcing semi-transparan</string>\n    <string name=\"neon_sub\">Tambahkan beberapa efek bercahaya pada gambar Anda</string>\n    <string name=\"pen_sub\">Yang default, paling sederhana - hanya warnanya</string>\n    <string name=\"privacy_blur_sub\">Mengaburkan gambar di bawah jalur yang digambar untuk mengamankan apa pun yang ingin Anda sembunyikan</string>\n    <string name=\"pixelation_sub\">Mirip dengan keburaman privasi, tetapi berpiksel, bukan buram</string>\n    <string name=\"app_bars_shadow\">Bilah Aplikasi</string>\n    <string name=\"app_bars_shadow_sub\">Mengaktifkan gambar bayangan di belakang bilah aplikasi</string>\n    <string name=\"free_drawing_sub\">Menggambar jalur sebagai nilai input</string>\n    <string name=\"outlined_rect\">Diuraikan Rek</string>\n    <string name=\"oval\">Bulat telur</string>\n    <string name=\"rect\">Benar</string>\n    <string name=\"rect_sub\">Menarik garis lurus dari titik awal ke titik akhir</string>\n    <string name=\"oval_sub\">Menggambar oval dari titik awal hingga titik akhir</string>\n    <string name=\"auto_pin_sub\">Secara otomatis menambahkan gambar yang disimpan ke clipboard jika diaktifkan</string>\n    <string name=\"overwrite_file_requirements\">Untuk menimpa file, Anda perlu menggunakan sumber gambar \\\"Explorer\\\", coba pilih ulang gambar, kami telah mengubah sumber gambar ke sumber yang diperlukan</string>\n    <string name=\"overwrite_files_sub\">File asli akan diganti dengan yang baru alih-alih disimpan di folder yang dipilih, opsi ini harus berupa sumber gambar \\\"Explorer\\\" atau GetContent, saat mengaktifkannya, ini akan disetel secara otomatis</string>\n    <string name=\"bicubic_sub\">Metode penskalaan yang lebih baik mencakup pengambilan sampel ulang Lanczos dan filter Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Salah satu cara sederhana untuk memperbesar ukuran adalah dengan mengganti setiap piksel dengan sejumlah piksel dengan warna yang sama</string>\n    <string name=\"basic_sub\">Mode penskalaan Android paling sederhana yang digunakan di hampir semua aplikasi</string>\n    <string name=\"catmull_sub\">Metode untuk menginterpolasi dan mengambil sampel ulang sekumpulan titik kontrol dengan lancar, biasanya digunakan dalam grafik komputer untuk membuat kurva yang mulus</string>\n    <string name=\"hann_sub\">Fungsi windowing sering diterapkan dalam pemrosesan sinyal untuk meminimalkan kebocoran spektral dan meningkatkan akurasi analisis frekuensi dengan memperkecil tepi sinyal</string>\n    <string name=\"hermite_sub\">Teknik interpolasi matematis yang menggunakan nilai dan turunan pada titik ujung suatu segmen kurva untuk menghasilkan kurva yang mulus dan kontinu</string>\n    <string name=\"lanczos_sub\">Metode pengambilan sampel ulang yang mempertahankan interpolasi berkualitas tinggi dengan menerapkan fungsi sinc tertimbang pada nilai piksel</string>\n    <string name=\"mitchell_sub\">Metode pengambilan sampel ulang yang menggunakan filter konvolusi dengan parameter yang dapat disesuaikan untuk mencapai keseimbangan antara ketajaman dan anti-aliasing pada gambar yang diskalakan</string>\n    <string name=\"spline_sub\">Memanfaatkan fungsi polinomial yang ditentukan sedikit demi sedikit untuk menginterpolasi dan memperkirakan kurva atau permukaan dengan lancar, representasi bentuk yang fleksibel dan berkelanjutan</string>\n    <string name=\"segmentation_mode_single_column\">Kolom tunggal</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Teks vertikal blok tunggal</string>\n    <string name=\"segmentation_mode_single_block\">Blok tunggal</string>\n    <string name=\"segmentation_mode_single_char\">karakter tunggal</string>\n    <string name=\"segmentation_mode_sparse_text\">Teks jarang</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Orientasi teks jarang &amp; Deteksi Skrip</string>\n    <string name=\"segmentation_mode_raw_line\">Garis mentah</string>\n    <string name=\"delete_language_sub\">Apakah Anda ingin menghapus data pelatihan OCR bahasa \\\"%1$s\\\" untuk semua jenis pengenalan, atau hanya untuk jenis pengenalan tertentu (%2$s)?</string>\n    <string name=\"current\">Saat ini</string>\n    <string name=\"camera_sub\">Menggunakan kamera untuk mengambil gambar, perhatikan bahwa hanya mungkin mengambil satu gambar dari sumber gambar ini</string>\n    <string name=\"repeat_watermark\">Ulangi tanda air</string>\n    <string name=\"repeat_watermark_sub\">Mengulangi tanda air pada gambar, bukan satu tanda air pada posisi tertentu</string>\n    <string name=\"offset_y\">Mengimbangi Y</string>\n    <string name=\"watermark_type\">Jenis Tanda Air</string>\n    <string name=\"bayer_two_dithering\">Bayer Dua Per Dua Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Tiga Per Tiga Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Empat Demi Empat Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Keragu-raguan Floyd Steinberg yang Palsu</string>\n    <string name=\"channel_shift_y\">Pergeseran Saluran Y</string>\n    <string name=\"corruption_size\">Ukuran Korupsi</string>\n    <string name=\"corruption_shift_x\">Pergeseran Korupsi X</string>\n    <string name=\"tent_blur\">Tenda Kabur</string>\n    <string name=\"side_fade\">Sisi Memudar</string>\n    <string name=\"side\">Samping</string>\n    <string name=\"top\">Atas</string>\n    <string name=\"bottom\">Dasar</string>\n    <string name=\"strength\">Kekuatan</string>\n    <string name=\"marble\">Marmer</string>\n    <string name=\"turbulence\">Pergolakan</string>\n    <string name=\"oil\">Minyak</string>\n    <string name=\"frequency_x\">Frekuensi X</string>\n    <string name=\"frequency_y\">Frekuensi Y</string>\n    <string name=\"amplitude_x\">Amplitudo X</string>\n    <string name=\"amplitude_y\">Amplitudo Y</string>\n    <string name=\"perlin_distortion\">Distorsi Perlin</string>\n    <string name=\"color_matrix_3x3\">Matriks Warna 3x3</string>\n    <string name=\"simple_effects\">Efek Sederhana</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomali</string>\n    <string name=\"deutaromaly\">Ulangan</string>\n    <string name=\"protonomaly\">protonomali</string>\n    <string name=\"browni\">browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Penglihatan Malam</string>\n    <string name=\"warm\">Hangat</string>\n    <string name=\"cool\">Dingin</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"golden_hour\">Jam Emas</string>\n    <string name=\"hot_summer\">Musim Panas yang Panas</string>\n    <string name=\"purple_mist\">Kabut Ungu</string>\n    <string name=\"sunrise\">Matahari terbit</string>\n    <string name=\"colorful_swirl\">Pusaran Warna-warni</string>\n    <string name=\"soft_spring_light\">Cahaya Musim Semi yang Lembut</string>\n    <string name=\"autumn_tones\">Nada Musim Gugur</string>\n    <string name=\"lemonade_light\">Cahaya Limun</string>\n    <string name=\"spectral_fire\">Api Spektral</string>\n    <string name=\"night_magic\">Sihir Malam</string>\n    <string name=\"fantasy_landscape\">Pemandangan Fantasi</string>\n    <string name=\"color_explosion\">Ledakan Warna</string>\n    <string name=\"electric_gradient\">Gradien Listrik</string>\n    <string name=\"caramel_darkness\">Kegelapan Karamel</string>\n    <string name=\"futuristic_gradient\">Gradien Futuristik</string>\n    <string name=\"space_portal\">Portal Luar Angkasa</string>\n    <string name=\"red_swirl\">pusaran merah</string>\n    <string name=\"digital_code\">Kode Digital</string>\n    <string name=\"cannot_change_image_format\">Tidak dapat mengubah format gambar saat opsi timpa file diaktifkan</string>\n    <string name=\"emoji_as_color_scheme_sub\">Menggunakan warna utama emoji sebagai skema warna aplikasi, bukan skema warna yang ditentukan secara manual</string>\n    <string name=\"restore_background\">Pulihkan latar belakang</string>\n    <string name=\"resize_and_convert\">Ubah ukuran dan Konversi</string>\n    <string name=\"effort\">Upaya</string>\n    <string name=\"draw_arrows\">Menggambar Panah</string>\n    <string name=\"donation\">Sumbangan</string>\n    <string name=\"circle_pixelation\">Pikselasi Lingkaran</string>\n    <string name=\"replace_color\">Ganti Warna</string>\n    <string name=\"color_to_remove\">Warna untuk Dihapus</string>\n    <string name=\"erode\">Mengikis</string>\n    <string name=\"anisotropic_diffusion\">Difusi Anisotropik</string>\n    <string name=\"diffusion\">Difusi</string>\n    <string name=\"conduction\">Konduksi</string>\n    <string name=\"horizontal_wind_stagger\">Terhuyung-huyung Angin Horisontal</string>\n    <string name=\"fast_bilaterial_blur\">Buram Bilateral Cepat</string>\n    <string name=\"poisson_blur\">racun kabur</string>\n    <string name=\"logarithmic_tone_mapping\">Pemetaan Nada Logaritmik</string>\n    <string name=\"crystallize\">Direalisasikan</string>\n    <string name=\"stroke_color\">Warna Goresan</string>\n    <string name=\"fractal_glass\">Kaca Fraktal</string>\n    <string name=\"amplitude\">Amplitudo</string>\n    <string name=\"water_effect\">Efek Air</string>\n    <string name=\"just_size\">Ukuran</string>\n    <string name=\"hable_filmic_tone_mapping\">Pemetaan Nada Filmik Hable</string>\n    <string name=\"heji_burgess_tone_mapping\">Pemetaan Nada Hejl Burgess</string>\n    <string name=\"aces_filmic_tone_mapping\">Pemetaan Nada Film ACES</string>\n    <string name=\"aces_hill_tone_mapping\">Pemetaan Nada Bukit ACES</string>\n    <string name=\"all\">Semua</string>\n    <string name=\"full_filter\">Penyaring Penuh</string>\n    <string name=\"center_position\">Tengah</string>\n    <string name=\"start_position\">Awal</string>\n    <string name=\"end_position\">Akhir</string>\n    <string name=\"full_filter_sub\">Terapkan rantai filter apa pun ke gambar tertentu atau gambar tunggal</string>\n    <string name=\"pdf_tools_sub\">Beroperasi dengan file PDF: Pratinjau, Konversikan ke kumpulan gambar atau buat satu dari gambar tertentu</string>\n    <string name=\"preview_pdf\">Pratinjau PDF</string>\n    <string name=\"pdf_to_images\">PDF ke Gambar</string>\n    <string name=\"images_to_pdf\">Gambar ke PDF</string>\n    <string name=\"preview_pdf_sub\">Pratinjau PDF sederhana</string>\n    <string name=\"pdf_to_images_sub\">Konversi PDF ke Gambar dalam format keluaran tertentu</string>\n    <string name=\"images_to_pdf_sub\">Kemas Gambar yang diberikan ke dalam file PDF keluaran</string>\n    <string name=\"gradient_maker\">Pembuat Gradien</string>\n    <string name=\"gradient_maker_sub\">Buat gradien dengan ukuran keluaran tertentu dengan warna dan jenis tampilan yang disesuaikan</string>\n    <string name=\"speed\">Kecepatan</string>\n    <string name=\"dehaze\">Hilangkan kabut</string>\n    <string name=\"omega\">Akhir</string>\n    <string name=\"pdf_tools\">Alat PDF</string>\n    <string name=\"rate_app\">Nilai Aplikasi</string>\n    <string name=\"rate\">Kecepatan</string>\n    <string name=\"rate_app_sub\">Aplikasi ini sepenuhnya gratis, jika Anda ingin menjadi lebih besar, silakan bintangi proyek ini di Github 😄</string>\n    <string name=\"color_matrix_4x4\">Matriks Warna 4x4</string>\n    <string name=\"vintage\">Antik</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Akromatomali</string>\n    <string name=\"achromatopsia\">Akromatopsia</string>\n    <string name=\"gradient_type_linear\">Linier</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Menyapu</string>\n    <string name=\"gradient_type\">Tipe Gradien</string>\n    <string name=\"center_x\">Pusat X</string>\n    <string name=\"center_y\">Pusat Y</string>\n    <string name=\"tile_mode\">Mode Ubin</string>\n    <string name=\"tile_mode_repeated\">Ulang</string>\n    <string name=\"tile_mode_mirror\">Cermin</string>\n    <string name=\"tile_mode_clamp\">Penjepit</string>\n    <string name=\"tile_mode_decal\">Stiker</string>\n    <string name=\"color_stops\">Warna Berhenti</string>\n    <string name=\"add_color\">Tambahkan Warna</string>\n    <string name=\"properties\">Properti</string>\n    <string name=\"email\">Surel</string>\n    <string name=\"lasso\">Laso</string>\n    <string name=\"lasso_sub\">Menggambar jalur tertutup yang diisi dengan jalur tertentu</string>\n    <string name=\"draw_path_mode\">Mode Gambar Jalur</string>\n    <string name=\"double_line_arrow\">Panah Garis Ganda</string>\n    <string name=\"free_drawing\">Gambar Gratis</string>\n    <string name=\"double_arrow\">Panah Ganda</string>\n    <string name=\"line_arrow\">Panah Garis</string>\n    <string name=\"arrow\">Anak panah</string>\n    <string name=\"line\">Garis</string>\n    <string name=\"line_sub\">Menggambar jalur dari titik awal ke titik akhir sebagai sebuah garis</string>\n    <string name=\"line_arrow_sub\">Menggambar panah penunjuk dari titik awal ke titik akhir sebagai sebuah garis</string>\n    <string name=\"arrow_sub\">Menggambar panah penunjuk dari jalur tertentu</string>\n    <string name=\"double_line_arrow_sub\">Menggambar panah penunjuk ganda dari titik awal ke titik akhir sebagai sebuah garis</string>\n    <string name=\"double_arrow_sub\">Menggambar panah penunjuk ganda dari jalur tertentu</string>\n    <string name=\"outlined_oval\">Diuraikan Oval</string>\n    <string name=\"outlined_oval_sub\">Menggambar garis oval dari titik awal hingga titik akhir</string>\n    <string name=\"outlined_rect_sub\">Menggambar garis lurus dari titik awal ke titik akhir</string>\n    <string name=\"dithering\">ragu-ragu</string>\n    <string name=\"quantizier\">Pengukur</string>\n    <string name=\"gray_scale\">Skala Abu-abu</string>\n    <string name=\"bayer_eight_dithering\">Bayer Delapan Kali Delapan Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg ragu-ragu</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Dithering Dua Baris Sierra</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson ragu-ragu</string>\n    <string name=\"stucki_dithering\">Terjebak Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"left_to_right_dithering\">Dithering Kiri Ke Kanan</string>\n    <string name=\"random_dithering\">Dithering Acak</string>\n    <string name=\"simple_threshold_dithering\">Dithering Ambang Batas Sederhana</string>\n    <string name=\"max_colors_count\">Jumlah warna maksimal</string>\n    <string name=\"analytics_sub\">Izinkan pengumpulan statistik penggunaan aplikasi anonim</string>\n    <string name=\"wait\">Tunggu</string>\n    <string name=\"mask_color\">Warna Masker</string>\n    <string name=\"mask_preview\">Pratinjau Topeng</string>\n    <string name=\"scale_mode\">Modus skala</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"hann\">Han</string>\n    <string name=\"hermite\">pertapa</string>\n    <string name=\"lanczos\">Lanzos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Terdekat</string>\n    <string name=\"spline\">spline</string>\n    <string name=\"basic\">Dasar</string>\n    <string name=\"default_value\">Nilai Bawaan</string>\n    <string name=\"value_in_range\">Nilai dalam rentang %1$s - %2$s</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma Spasial</string>\n    <string name=\"median_blur\">Kabur Median</string>\n    <string name=\"catmull\">kucingmull</string>\n    <string name=\"bicubic\">Bikubik</string>\n    <string name=\"bilinear_sub\">Interpolasi linier (atau bilinear, dalam dua dimensi) biasanya baik untuk mengubah ukuran gambar, namun menyebabkan beberapa pelunakan detail yang tidak diinginkan dan masih bisa agak bergerigi.</string>\n    <string name=\"only_clip\">Hanya Klip</string>\n    <string name=\"only_clip_sub\">Penyimpanan ke penyimpanan tidak akan dilakukan, dan gambar akan dicoba dimasukkan ke clipboard saja</string>\n    <string name=\"icon_shape_sub\">Menambahkan wadah dengan bentuk yang dipilih di bawah ikon utama kartu</string>\n    <string name=\"icon_shape\">Bentuk Ikon</string>\n    <string name=\"image_stitching\">Jahitan Gambar</string>\n    <string name=\"image_stitching_sub\">Gabungkan gambar yang diberikan untuk mendapatkan satu gambar besar</string>\n    <string name=\"brightness_enforcement\">Penegakan Kecerahan</string>\n    <string name=\"screen\">Layar</string>\n    <string name=\"gradient_maker_type_image\">Hamparan Gradien</string>\n    <string name=\"gradient_maker_type_image_sub\">Buatlah gradien apa pun di bagian atas gambar yang diberikan</string>\n    <string name=\"transformations\">Transformasi</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"pick_at_least_two_images\">Pilih setidaknya 2 gambar</string>\n    <string name=\"output_image_scale\">Skala gambar keluaran</string>\n    <string name=\"image_orientation\">Orientasi Gambar</string>\n    <string name=\"grain\">Bulir</string>\n    <string name=\"unsharp\">Tidak tajam</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Kabut Oranye</string>\n    <string name=\"pink_dream\">Mimpi Merah Muda</string>\n    <string name=\"lavender_dream\">Mimpi Lavender</string>\n    <string name=\"cyberpunk\">dunia maya</string>\n    <string name=\"green_sun\">Matahari Hijau</string>\n    <string name=\"rainbow_world\">Dunia Pelangi</string>\n    <string name=\"deep_purple\">Ungu gelap</string>\n    <string name=\"watermarking\">Tanda air</string>\n    <string name=\"watermarking_sub\">Sampul gambar dengan tanda air teks/gambar yang dapat disesuaikan</string>\n    <string name=\"offset_x\">Mengimbangi X</string>\n    <string name=\"watermarking_image_sub\">Gambar ini akan digunakan sebagai pola untuk watermarking</string>\n    <string name=\"text_color\">Warna teks</string>\n    <string name=\"overlay_mode\">Modus Hamparan</string>\n    <string name=\"pixel_size\">Ukuran Piksel</string>\n    <string name=\"lock_draw_orientation\">Kunci orientasi gambar</string>\n    <string name=\"effort_sub\">Nilai %1$s berarti kompresi yang cepat sehingga menghasilkan ukuran file yang relatif besar. %2$s berarti kompresi lebih lambat, sehingga menghasilkan file lebih kecil.</string>\n    <string name=\"lock_draw_orientation_sub\">Jika diaktifkan dalam mode menggambar, layar tidak akan berputar</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">Alat GIF</string>\n    <string name=\"gif_tools_sub\">Konversikan gambar menjadi gambar GIF atau ekstrak bingkai dari gambar GIF yang diberikan</string>\n    <string name=\"gif_type_to_image\">GIF ke gambar</string>\n    <string name=\"gif_type_to_image_sub\">Konversikan file GIF menjadi kumpulan gambar</string>\n    <string name=\"gif_type_to_gif_sub\">Konversikan kumpulan gambar ke file GIF</string>\n    <string name=\"gif_type_to_gif\">Gambar ke GIF</string>\n    <string name=\"select_gif_image_to_start\">Pilih gambar GIF untuk memulai</string>\n    <string name=\"use_size_of_first_frame\">Gunakan ukuran bingkai Pertama</string>\n    <string name=\"use_size_of_first_frame_sub\">Ganti ukuran yang ditentukan dengan dimensi bingkai pertama</string>\n    <string name=\"repeat_count\">Ulangi Hitungan</string>\n    <string name=\"frame_delay\">Penundaan Bingkai</string>\n    <string name=\"millis\">milis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Gunakan Laso</string>\n    <string name=\"use_lasso_sub\">Menggunakan Lasso seperti dalam mode menggambar untuk melakukan penghapusan</string>\n    <string name=\"original_image_preview_alpha\">Pratinjau Gambar Asli Alfa</string>\n    <string name=\"masks\">Masker</string>\n    <string name=\"random_emojis\">Emoji Acak</string>\n    <string name=\"random_emojis_sub\">Emoji bilah aplikasi akan terus diubah secara acak alih-alih menggunakan emoji yang dipilih</string>\n    <string name=\"random_emojis_error\">Tidak dapat menggunakan pemilihan emoji acak saat emoji dinonaktifkan</string>\n    <string name=\"emoji_selection_error\">Tidak dapat memilih emoji saat memilih emoji acak diaktifkan</string>\n    <string name=\"check_for_updates\">Periksa pembaruan</string>\n    <string name=\"restore\">Memulihkan</string>\n    <string name=\"backup_sub\">Cadangkan pengaturan aplikasi Anda ke file</string>\n    <string name=\"corrupted_file_or_not_a_backup\">File rusak atau tidak dicadangkan</string>\n    <string name=\"delete\">Menghapus</string>\n    <string name=\"old_tv\">TV Lama</string>\n    <string name=\"shuffle_blur\">Acak Buram</string>\n    <string name=\"recognize_text\">OCR (Kenali Teks)</string>\n    <string name=\"recognize_text_sub\">Kenali teks dari gambar yang diberikan, didukung 120+ bahasa</string>\n    <string name=\"picture_has_no_text\">Gambar tidak memiliki teks, atau aplikasi tidak menemukannya</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Jenis Pengakuan</string>\n    <string name=\"fast\">Cepat</string>\n    <string name=\"standard\">Standar</string>\n    <string name=\"best\">Terbaik</string>\n    <string name=\"no_data\">Tidak ada data</string>\n    <string name=\"download_description\">Agar Tesseract OCR berfungsi dengan baik, data pelatihan tambahan (%1$s) perlu diunduh ke perangkat Anda. \\nApakah Anda ingin mengunduh data %2$s?</string>\n    <string name=\"download\">Unduh</string>\n    <string name=\"no_connection\">Tidak ada koneksi, periksa dan coba lagi untuk mendownload model kereta</string>\n    <string name=\"downloaded_languages\">Bahasa yang Diunduh</string>\n    <string name=\"available_languages\">Bahasa yang Tersedia</string>\n    <string name=\"segmentation_mode\">Modus Segmentasi</string>\n    <string name=\"restore_background_sub\">Kuas akan memulihkan latar belakang alih-alih menghapus</string>\n    <string name=\"horizontal_grid\">Kotak Horisontal</string>\n    <string name=\"vertical_grid\">Kotak Vertikal</string>\n    <string name=\"stitch_mode\">Mode Jahitan</string>\n    <string name=\"rows_count\">Jumlah Baris</string>\n    <string name=\"use_pixel_switch\">Gunakan Sakelar Piksel</string>\n    <string name=\"use_pixel_switch_sub\">Sakelar seperti piksel akan digunakan sebagai pengganti materi Google yang Anda buat</string>\n    <string name=\"slide\">Menggeser</string>\n    <string name=\"side_by_side\">Bersebelahan</string>\n    <string name=\"toggle_tap\">Alihkan Ketuk</string>\n    <string name=\"transparency\">Transparansi</string>\n    <string name=\"saved_to_original\">File yang ditimpa dengan nama %1$s di tujuan aslinya</string>\n    <string name=\"magnifier\">Kaca pembesar</string>\n    <string name=\"magnifier_sub\">Mengaktifkan kaca pembesar di bagian atas jari dalam mode menggambar untuk aksesibilitas yang lebih baik</string>\n    <string name=\"force_exif_widget_initial_value\">Paksa nilai awal</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Memaksa widget exic untuk diperiksa terlebih dahulu</string>\n    <string name=\"allow_multiple_languages\">Izinkan Banyak Bahasa</string>\n    <string name=\"favorite\">Favorit</string>\n    <string name=\"no_favorite_filters\">Belum ada filter favorit yang ditambahkan</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Memanfaatkan fungsi polinomial bikubik yang ditentukan sedikit demi sedikit untuk menginterpolasi dan memperkirakan kurva atau permukaan dengan lancar, representasi bentuk yang fleksibel dan berkelanjutan</string>\n    <string name=\"native_stack_blur\">Keburaman Tumpukan Asli</string>\n    <string name=\"tilt_shift\">Pergeseran Kemiringan</string>\n    <string name=\"regular\">Reguler</string>\n    <string name=\"blur_edges\">Mengaburkan tepinya</string>\n    <string name=\"inverse_fill_type\">Jenis Isian Terbalik</string>\n    <string name=\"inverse_fill_type_sub\">Jika diaktifkan, semua area yang tidak disamarkan akan difilter, bukan perilaku default</string>\n    <string name=\"confetti\">Konfeti</string>\n    <string name=\"confetti_sub\">Confetti akan ditampilkan saat menyimpan, berbagi, dan tindakan utama lainnya</string>\n    <string name=\"secure_mode\">Modus Aman</string>\n    <string name=\"secure_mode_sub\">Menyembunyikan konten saat keluar, dan layar juga tidak dapat ditangkap atau direkam</string>\n    <string name=\"crop_description\">Gambar akan dipotong tengah sesuai ukuran yang dimasukkan. Kanvas akan diperluas dengan warna latar belakang tertentu jika gambar lebih kecil dari dimensi yang dimasukkan.</string>\n    <string name=\"vertical\">Vertikal</string>\n    <string name=\"images_order\">Urutan gambar</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Pena</string>\n    <string name=\"auto_rotate_limits\">Rotasi otomatis</string>\n    <string name=\"auto_rotate_limits_sub\">Memungkinkan kotak batas diadopsi untuk orientasi gambar</string>\n    <string name=\"palette_style\">Gaya palet</string>\n    <string name=\"tonal_spot\">Tempat Nada</string>\n    <string name=\"neutral\">Netral</string>\n    <string name=\"vibrant\">Bersemangat</string>\n    <string name=\"expressive\">Ekspresif</string>\n    <string name=\"rainbow\">Pelangi</string>\n    <string name=\"fruit_salad\">Salad buah</string>\n    <string name=\"fidelity\">Kesetiaan</string>\n    <string name=\"content\">Isi</string>\n    <string name=\"tonal_spot_sub\">Gaya palet default, memungkinkan untuk menyesuaikan keempat warna, yang lain memungkinkan Anda mengatur hanya warna utama</string>\n    <string name=\"containers_shadow\">Kontainer</string>\n    <string name=\"containers_shadow_sub\">Mengaktifkan gambar bayangan di belakang wadah</string>\n    <string name=\"sliders_shadow\">Penggeser</string>\n    <string name=\"switches_shadow\">Beralih</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">Tombol</string>\n    <string name=\"sliders_shadow_sub\">Mengaktifkan gambar bayangan di belakang bilah geser</string>\n    <string name=\"switches_shadow_sub\">Mengaktifkan gambar bayangan di belakang sakelar</string>\n    <string name=\"fabs_shadow_sub\">Mengaktifkan gambar bayangan di belakang tombol aksi mengambang</string>\n    <string name=\"buttons_shadow_sub\">Mengaktifkan gambar bayangan di belakang tombol default</string>\n    <string name=\"foss_update_checker_warning\">Pemeriksa pembaruan ini akan terhubung ke GitHub untuk memeriksa apakah ada pembaruan baru yang tersedia</string>\n    <string name=\"attention\">Perhatian</string>\n    <string name=\"fading_edges\">Tepi Memudar</string>\n    <string name=\"both\">Keduanya</string>\n    <string name=\"invert_colors\">Balikkan Warna</string>\n    <string name=\"invert_colors_sub\">Mengganti warna tema menjadi warna negatif jika diaktifkan</string>\n    <string name=\"exit\">Keluar</string>\n    <string name=\"preview_closing\">Jika Anda keluar dari pratinjau sekarang, Anda perlu menambahkan gambar lagi</string>\n    <string name=\"image_format\">Format Gambar</string>\n    <string name=\"material_you_sub\">Membuat palet “Material You” dari gambar</string>\n    <string name=\"dark_colors\">Warna Gelap</string>\n    <string name=\"copy_as_compose_code\">Salin sebagai kode\\\" Jetpack Compose\\\"</string>\n    <string name=\"dark_colors_sub\">Menggunakan skema warna mode malam alih-alih varian cahaya</string>\n    <string name=\"ring_blur\">Cincin Kabur</string>\n    <string name=\"cross_blur\">Pengaburan silang</string>\n    <string name=\"circle_blur\">Lingkaran Kabur</string>\n    <string name=\"star_blur\">Bintang Kabur</string>\n    <string name=\"linear_tilt_shift\">Pergeseran Kemiringan Linier</string>\n    <string name=\"tags_to_remove\">Tag untuk dihapus</string>\n    <string name=\"apng_tools\">Alat APNG</string>\n    <string name=\"apng_tools_sub\">Konversikan gambar ke gambar APNG atau ekstrak bingkai dari gambar APNG yang diberikan</string>\n    <string name=\"select_apng_image_to_start\">Pilih gambar APNG untuk memulai</string>\n    <string name=\"apng_type_to_image\">APNG ke gambar</string>\n    <string name=\"apng_type_to_image_sub\">Konversikan file APNG menjadi kumpulan gambar</string>\n    <string name=\"apng_type_to_apng\">Gambar ke APNG</string>\n    <string name=\"motion_blur\">Gerakan Buram</string>\n    <string name=\"apng_type_to_apng_sub\">Konversikan kumpulan gambar ke file APNG</string>\n    <string name=\"zip\">Ritsleting</string>\n    <string name=\"zip_sub\">Buat file Zip dari file atau gambar tertentu</string>\n    <string name=\"drag_handle_width\">Seret Lebar Pegangan</string>\n    <string name=\"festive\">Meriah</string>\n    <string name=\"explode\">Meledak</string>\n    <string name=\"rain\">Hujan</string>\n    <string name=\"corners\">Sudut</string>\n    <string name=\"confetti_type\">Jenis Konfeti</string>\n    <string name=\"gif_type_to_jxl_sub\">Ubah gambar GIF menjadi gambar animasi JXL</string>\n    <string name=\"lanczos_bessel_sub\">Metode pengambilan sampel ulang yang menjaga interpolasi berkualitas tinggi dengan menerapkan fungsi Bessel (jinc) pada nilai piksel</string>\n    <string name=\"generate_previews_sub\">Menyalakan pembuatan pratinjau, ini dapat membantu menghindari kerusakan pada beberapa perangkat, ini juga menonaktifkan beberapa fungsi pengeditan dalam opsi pengeditan tunggal</string>\n    <string name=\"skip_file_picking_sub\">Pemilih berkas akan segera ditampilkan jika memungkinkan pada layar yang dipilih</string>\n    <string name=\"sort_by_name_reversed\">Urutkan Berdasarkan Nama (Terbalik)</string>\n    <string name=\"channels_configuration\">Konfigurasi Saluran</string>\n    <string name=\"header_yesterday\">Kemarin</string>\n    <string name=\"sort_by_date_reversed\">Urutkan Berdasarkan Tanggal (Terbalik)</string>\n    <string name=\"try_again\">Coba Lagi</string>\n    <string name=\"show_settings_in_landscape\">Tampilkan Pengaturan Dalam Lanskap</string>\n    <string name=\"show_settings_in_landscape_sub\">Jika ini dimatikan maka dalam mode lanskap pengaturan akan dibuka pada tombol di bilah aplikasi atas seperti biasa, bukan opsi yang terlihat permanen</string>\n    <string name=\"jxl_tools\">Alat JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL ke JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Lakukan transkode lossless dari JXL ke JPEG</string>\n    <string name=\"jxl_tools_sub\">Lakukan JXL ~ JPEG transkode tanpa kehilangan kualitas, atau ubah GIF/APNG menjadi animasi JXL</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Lakukan transkode lossless dari JPEG ke JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG ke JXL</string>\n    <string name=\"select_jxl_image_to_start\">Pilih gambar JXL untuk memulai</string>\n    <string name=\"fullscreen_settings\">Pengaturan Layar Penuh</string>\n    <string name=\"fullscreen_settings_sub\">Nyalakan dan halaman pengaturan akan selalu dibuka sebagai layar penuh, bukan lembaran laci yang dapat digeser</string>\n    <string name=\"switch_type\">Jenis Tombol</string>\n    <string name=\"compose\">Menyusun</string>\n    <string name=\"pick_multiple_media\">Pilih Beberapa Media</string>\n    <string name=\"pick_single_media\">Pilih Satu Media</string>\n    <string name=\"pick\">Pilih</string>\n    <string name=\"material_you_switch_sub\">Menggunakan basis tampilan material yang Anda pilih, yang ini terlihat lebih hebat dari yang lain dan memiliki animasi yang bagus</string>\n    <string name=\"compose_switch_sub\">Menggunakan material Jetpack Compose yang Anda pilih, tampilannya tidak seindah berbasis tampilan</string>\n    <string name=\"fast_gaussian_blur_2d\">Gaussian Blur 2D cepat</string>\n    <string name=\"fast_gaussian_blur_3d\">Gaussian Blur 3D cepat</string>\n    <string name=\"fast_gaussian_blur_4d\">Gaussian Blur 4D cepat</string>\n    <string name=\"max\">Maksimal</string>\n    <string name=\"resize_anchor\">Ubah Ukuran Jangkar</string>\n    <string name=\"header_today\">Hari ini</string>\n    <string name=\"embedded_picker\">Pemilih Tersemat</string>\n    <string name=\"embedded_picker_sub\">Menggunakan pemilih gambar bawaan Image Toolbox, bukan pemilih gambar yang telah ditentukan sistem</string>\n    <string name=\"no_permissions\">Tidak Ada Izin</string>\n    <string name=\"request\">Permintaan</string>\n    <string name=\"auto_paste\">Tempel Otomatis</string>\n    <string name=\"auto_paste_sub\">Mengizinkan aplikasi menempelkan data papan klip secara otomatis, sehingga akan muncul di layar utama dan Anda dapat memprosesnya</string>\n    <string name=\"harmonization_color\">Harmonisasi Warna</string>\n    <string name=\"harmonization_level\">Tingkat Harmonisasi</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"gif_type_to_jxl\">GIF ke JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG ke JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Ubah gambar APNG menjadi gambar animasi JXL</string>\n    <string name=\"jxl_type_to_images\">JXL ke Gambar</string>\n    <string name=\"jxl_type_to_images_sub\">Ubah animasi JXL menjadi kumpulan gambar</string>\n    <string name=\"jxl_type_to_jxl\">Gambar ke JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Ubah kumpulan gambar menjadi animasi JXL</string>\n    <string name=\"behavior\">Perilaku</string>\n    <string name=\"skip_file_picking\">Lewati Pengambilan Berkas</string>\n    <string name=\"generate_previews\">Buat Pratinjau</string>\n    <string name=\"lossy_compression\">Kompresi Rugi</string>\n    <string name=\"lossy_compression_sub\">Menggunakan kompresi lossy untuk mengurangi ukuran berkas daripada lossless</string>\n    <string name=\"compression_type\">Jenis Kompresi</string>\n    <string name=\"speed_sub\">Mengontrol kecepatan decoding gambar yang dihasilkan, ini akan membantu membuka gambar yang dihasilkan lebih cepat, nilai %1$s berarti decoding paling lambat, sedangkan %2$s - tercepat, pengaturan ini dapat meningkatkan ukuran gambar keluaran</string>\n    <string name=\"sorting\">Mengurutkan</string>\n    <string name=\"sort_by_date\">Urutkan Berdasarkan Tanggal</string>\n    <string name=\"sort_by_name\">Urutkan Berdasarkan Nama</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"legacy\">Lama</string>\n    <string name=\"images_to_svg\">Gambar ke SVG</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">Menggunakan gaya sakelar Windows 11 berdasarkan sistem desain \\\"Fluent\\\"</string>\n    <string name=\"min_color_ratio\">Rasio Warna Minimum</string>\n    <string name=\"default_line_width\">Lebar Garis Default</string>\n    <string name=\"engine_mode\">Mode Mesin</string>\n    <string name=\"lstm_network\">Jaringan LSTM</string>\n    <string name=\"convert\">Konversi</string>\n    <string name=\"add_new_folder\">Tambah Folder Baru</string>\n    <string name=\"cupertino_switch_sub\">Menggunakan gaya sakelar iOS berdasarkan sistem desain Cupertino</string>\n    <string name=\"images_to_svg_sub\">Menjiplak gambar ke gambar SVG</string>\n    <string name=\"use_sampled_palette\">Gunakan Palet Sampel</string>\n    <string name=\"use_sampled_palette_sub\">Palet kuantisasi akan diambil sampelnya jika opsi ini diaktifkan</string>\n    <string name=\"path_omit\">Jalur Hilang</string>\n    <string name=\"svg_warning\">Penggunaan alat ini untuk menelusuri gambar besar tanpa penurunan skala tidak disarankan, karena dapat menyebabkan kerusakan dan menambah waktu pemrosesan</string>\n    <string name=\"downscale_image\">Gambar yang diperkecil</string>\n    <string name=\"downscale_image_sub\">Gambar akan diturunkan skalanya ke dimensi yang lebih rendah sebelum diproses, hal ini membantu alat bekerja lebih cepat dan aman</string>\n    <string name=\"lines_threshold\">Ambang Batas Garis</string>\n    <string name=\"quadratic_threshold\">Ambang Batas Kuadrat</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordinat Pembulatan Toleransi</string>\n    <string name=\"path_scale\">Skala Jalur</string>\n    <string name=\"reset_properties\">Setel ulang properti</string>\n    <string name=\"reset_properties_sub\">Semua properti akan disetel ke nilai default, perhatikan bahwa tindakan ini tidak dapat dibatalkan</string>\n    <string name=\"detailed\">Berdetail</string>\n    <string name=\"legacy_and_lstm\">Warisan &amp;amp; LSTM</string>\n    <string name=\"convert_sub\">Konversi kumpulan gambar ke format tertentu</string>\n    <string name=\"tag_bits_per_sample\">Bit Per Sampel</string>\n    <string name=\"tag_compression\">Kompresi</string>\n    <string name=\"tag_photometric_interpretation\">Interpretasi Fotometrik</string>\n    <string name=\"tag_samples_per_pixel\">Sampel Per Piksel</string>\n    <string name=\"tag_planar_configuration\">Konfigurasi Planar</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Sub Sampling Y Cb Cr</string>\n    <string name=\"tag_y_cb_cr_positioning\">Posisi Y Cb Cr</string>\n    <string name=\"tag_x_resolution\">X Resolusi</string>\n    <string name=\"tag_y_resolution\">Resolusi Y</string>\n    <string name=\"tag_resolution_unit\">Satuan Resolusi</string>\n    <string name=\"tag_strip_offsets\">Strip Offset</string>\n    <string name=\"tag_rows_per_strip\">Baris Per Strip</string>\n    <string name=\"tag_strip_byte_counts\">Hapus Jumlah Byte</string>\n    <string name=\"tag_jpeg_interchange_format\">Format Pertukaran JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Panjang Format Pertukaran JPEG</string>\n    <string name=\"tag_transfer_function\">Fungsi Pemindahan</string>\n    <string name=\"tag_white_point\">Titik Putih</string>\n    <string name=\"tag_primary_chromaticities\">Kromatisitas Primer</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Koefisien Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">Referensi Hitam Putih</string>\n    <string name=\"tag_datetime\">Tanggal Waktu</string>\n    <string name=\"tag_image_description\">Deskripsi Gambar</string>\n    <string name=\"tag_make\">Membuat</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Perangkat lunak</string>\n    <string name=\"tag_artist\">Artis</string>\n    <string name=\"tag_copyright\">Hak cipta</string>\n    <string name=\"tag_exif_version\">Versi Exif</string>\n    <string name=\"tag_flashpix_version\">Versi Flashpix</string>\n    <string name=\"tag_color_space\">Ruang Warna</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Dimensi Piksel X</string>\n    <string name=\"tag_pixel_y_dimension\">Dimensi Piksel Y</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Bit Terkompresi Per Piksel</string>\n    <string name=\"tag_maker_note\">Catatan Pembuat</string>\n    <string name=\"tag_user_comment\">Komentar Pengguna</string>\n    <string name=\"tag_related_sound_file\">File Suara Terkait</string>\n    <string name=\"tag_datetime_original\">Tanggal Waktu Asli</string>\n    <string name=\"tag_datetime_digitized\">Tanggal Waktu Didigitalkan</string>\n    <string name=\"tag_offset_time\">Waktu Pengimbangan</string>\n    <string name=\"tag_offset_time_original\">Waktu Offset Asli</string>\n    <string name=\"tag_offset_time_digitized\">Waktu Offset Didigitalkan</string>\n    <string name=\"tag_subsec_time\">Waktu Sub Detik</string>\n    <string name=\"tag_subsec_time_original\">Sub Detik Waktu Asli</string>\n    <string name=\"tag_subsec_time_digitized\">Waktu Sub Detik Didigitalkan</string>\n    <string name=\"tag_exposure_time\">Waktu paparan</string>\n    <string name=\"tag_f_number\">Nomor F</string>\n    <string name=\"tag_exposure_program\">Program Paparan</string>\n    <string name=\"tag_spectral_sensitivity\">Sensitivitas Spektral</string>\n    <string name=\"tag_photographic_sensitivity\">Sensitivitas Fotografi</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Tipe Sensitivitas</string>\n    <string name=\"tag_standard_output_sensitivity\">Sensitivitas Keluaran Standar</string>\n    <string name=\"tag_recommended_exposure_index\">Indeks Eksposur yang Direkomendasikan</string>\n    <string name=\"tag_iso_speed\">Kecepatan ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Lintang Kecepatan ISO yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Garis Lintang Kecepatan ISO zzz</string>\n    <string name=\"tag_shutter_speed_value\">Nilai Kecepatan Rana</string>\n    <string name=\"tag_aperture_value\">Nilai Bukaan</string>\n    <string name=\"tag_brightness_value\">Nilai Kecerahan</string>\n    <string name=\"tag_exposure_bias_value\">Nilai Bias Eksposur</string>\n    <string name=\"tag_max_aperture_value\">Nilai Apertur Maks</string>\n    <string name=\"tag_subject_distance\">Jarak Subjek</string>\n    <string name=\"tag_metering_mode\">Mode Pengukuran</string>\n    <string name=\"tag_flash\">Kilatan</string>\n    <string name=\"tag_subject_area\">Bidang Subyek</string>\n    <string name=\"tag_focal_length\">Panjang Fokus</string>\n    <string name=\"tag_flash_energy\">Energi Kilatan</string>\n    <string name=\"tag_spatial_frequency_response\">Respon Frekuensi Spasial</string>\n    <string name=\"tag_focal_plane_x_resolution\">Resolusi Bidang Fokus X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Resolusi Bidang Fokus Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Unit Resolusi Bidang Fokus</string>\n    <string name=\"tag_subject_location\">Lokasi Subjek</string>\n    <string name=\"tag_exposure_index\">Indeks Paparan</string>\n    <string name=\"tag_sensing_method\">Metode Penginderaan</string>\n    <string name=\"tag_file_source\">Sumber Berkas</string>\n    <string name=\"tag_cfa_pattern\">Pola CFA</string>\n    <string name=\"tag_custom_rendered\">Dirender Khusus</string>\n    <string name=\"tag_exposure_mode\">Mode Eksposur</string>\n    <string name=\"tag_white_balance\">Keseimbangan Putih</string>\n    <string name=\"tag_digital_zoom_ratio\">Rasio Zoom Digital</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Film Panjang Fokus Dalam 35mm</string>\n    <string name=\"tag_scene_capture_type\">Jenis Pengambilan Pemandangan</string>\n    <string name=\"tag_gain_control\">Dapatkan Kontrol</string>\n    <string name=\"tag_contrast\">Kontras</string>\n    <string name=\"tag_saturation\">Kejenuhan</string>\n    <string name=\"tag_sharpness\">Ketajaman</string>\n    <string name=\"tag_device_setting_description\">Deskripsi Pengaturan Perangkat</string>\n    <string name=\"tag_subject_distance_range\">Rentang Jarak Subjek</string>\n    <string name=\"tag_image_unique_id\">ID Unik Gambar</string>\n    <string name=\"tag_camera_owner_name\">Nama Pemilik Kamera</string>\n    <string name=\"tag_body_serial_number\">Nomor Seri Tubuh</string>\n    <string name=\"tag_lens_specification\">Spesifikasi Lensa</string>\n    <string name=\"tag_lens_make\">Pembuatan Lensa</string>\n    <string name=\"tag_lens_model\">Model Lensa</string>\n    <string name=\"tag_lens_serial_number\">Nomor Seri Lensa</string>\n    <string name=\"tag_gps_version_id\">ID Versi GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Referensi Garis Lintang GPS</string>\n    <string name=\"tag_gps_latitude\">Garis Lintang GPS</string>\n    <string name=\"tag_gps_longitude_ref\">Referensi Bujur GPS</string>\n    <string name=\"tag_gps_longitude\">Bujur GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Referensi Ketinggian GPS</string>\n    <string name=\"tag_gps_altitude\">Ketinggian GPS</string>\n    <string name=\"tag_gps_timestamp\">Stempel Waktu GPS</string>\n    <string name=\"tag_gps_satellites\">Satelit GPS</string>\n    <string name=\"tag_gps_status\">Status GPS</string>\n    <string name=\"tag_gps_measure_mode\">Mode Pengukuran GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Referensi Kecepatan GPS</string>\n    <string name=\"tag_gps_speed\">Kecepatan GPS</string>\n    <string name=\"tag_gps_track_ref\">Referensi Jalur GPS</string>\n    <string name=\"tag_gps_track\">Jalur GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Referensi Arah Gambar GPS</string>\n    <string name=\"tag_gps_img_direction\">Arah Gambar GPS</string>\n    <string name=\"tag_gps_map_datum\">Data Peta GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Referensi Garis Lintang Tujuan GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Lintang Tujuan GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Referensi Bujur Tujuan GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Bujur Tujuan GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Referensi Bantalan Tujuan GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Bantalan Tujuan GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Ref. Jarak Tujuan GPS</string>\n    <string name=\"tag_gps_dest_distance\">Jarak Tujuan GPS</string>\n    <string name=\"tag_gps_processing_method\">Metode Pemrosesan GPS</string>\n    <string name=\"tag_gps_area_information\">Informasi Area GPS</string>\n    <string name=\"tag_gps_datestamp\">Stempel Tanggal GPS</string>\n    <string name=\"tag_gps_differential\">Diferensial GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Kesalahan Penentuan Posisi GPS H</string>\n    <string name=\"tag_interoperability_index\">Indeks Interoperabilitas</string>\n    <string name=\"tag_dng_version\">Versi DNG</string>\n    <string name=\"tag_default_crop_size\">Ukuran Pangkas Default</string>\n    <string name=\"tag_orf_preview_image_start\">Pratinjau Gambar Mulai</string>\n    <string name=\"tag_orf_preview_image_length\">Pratinjau Panjang Gambar</string>\n    <string name=\"tag_orf_aspect_frame\">Bingkai Aspek</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Batas Bawah Sensor</string>\n    <string name=\"tag_rw2_sensor_left_border\">Perbatasan Kiri Sensor</string>\n    <string name=\"tag_rw2_sensor_right_border\">Perbatasan Kanan Sensor</string>\n    <string name=\"tag_rw2_sensor_top_border\">Batas Atas Sensor</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Gambar Teks di jalur dengan font dan warna tertentu</string>\n    <string name=\"font_size\">Ukuran Huruf</string>\n    <string name=\"watermark_size\">Ukuran Tanda Air</string>\n    <string name=\"repeat_text\">Ulangi Teks</string>\n    <string name=\"repeat_text_sub\">Teks saat ini akan diulang hingga jalur berakhir, bukan satu kali menggambar</string>\n    <string name=\"dash_size\">Ukuran Garis Dasbor</string>\n    <string name=\"draw_mode_image_sub\">Gunakan gambar yang dipilih untuk menggambarnya di sepanjang jalur yang diberikan</string>\n    <string name=\"draw_image_sub\">Gambar ini akan digunakan sebagai entri berulang dari jalur yang digambar</string>\n    <string name=\"outlined_triangle_sub\">Menggambar garis luar segitiga dari titik awal hingga titik akhir</string>\n    <string name=\"triangle_sub\">Menggambar garis luar segitiga dari titik awal hingga titik akhir</string>\n    <string name=\"outlined_triangle\">Segitiga yang Diuraikan</string>\n    <string name=\"triangle\">Segi tiga</string>\n    <string name=\"polygon_sub\">Menggambar poligon dari titik awal ke titik akhir</string>\n    <string name=\"polygon\">Poligon</string>\n    <string name=\"outlined_polygon\">Poligon yang Diuraikan</string>\n    <string name=\"outlined_polygon_sub\">Menggambar garis poligon dari titik awal hingga titik akhir</string>\n    <string name=\"vertices\">simpul</string>\n    <string name=\"draw_regular_polygon\">Menggambar Poligon Beraturan</string>\n    <string name=\"draw_regular_polygon_sub\">Gambarlah poligon yang beraturan, bukan bentuk bebas</string>\n    <string name=\"star_sub\">Menggambar bintang dari titik awal ke titik akhir</string>\n    <string name=\"star\">Bintang</string>\n    <string name=\"outlined_star\">Bintang yang Diuraikan</string>\n    <string name=\"outlined_star_sub\">Menggambar garis luar bintang dari titik awal hingga titik akhir</string>\n    <string name=\"inner_radius_ratio\">Rasio Radius Dalam</string>\n    <string name=\"draw_regular_star\">Gambar Bintang Biasa</string>\n    <string name=\"draw_regular_star_sub\">Gambarlah bintang yang berbentuk biasa, bukan berbentuk bebas</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Mengaktifkan antialiasing untuk mencegah tepi tajam</string>\n    <string name=\"open_edit_instead_of_preview\">Buka Edit, Bukan Pratinjau</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Saat Anda memilih gambar untuk dibuka (pratinjau) di ImageToolbox, lembar pilihan edit akan dibuka alih-alih dipratinjau</string>\n    <string name=\"document_scanner\">Pemindai Dokumen</string>\n    <string name=\"document_scanner_sub\">Pindai dokumen dan buat PDF atau pisahkan gambar darinya</string>\n    <string name=\"click_to_start_scanning\">Klik untuk mulai memindai</string>\n    <string name=\"start_scanning\">Mulai Memindai</string>\n    <string name=\"save_as_pdf\">Simpan Sebagai Pdf</string>\n    <string name=\"share_as_pdf\">Bagikan Sebagai Pdf</string>\n    <string name=\"options_below_is_for_images\">Opsi di bawah ini adalah untuk menyimpan gambar, bukan PDF</string>\n    <string name=\"equalize_histogram_hsv\">Menyamakan Histogram HSV</string>\n    <string name=\"equalize_histogram\">Menyamakan Histogram</string>\n    <string name=\"enter_percentage\">Masukkan Persentase</string>\n    <string name=\"allow_enter_by_text_field\">Izinkan masuk dengan Bidang Teks</string>\n    <string name=\"allow_enter_by_text_field_sub\">Mengaktifkan Bidang Teks di belakang pilihan prasetel, untuk memasukkannya dengan cepat</string>\n    <string name=\"scale_color_space\">Skala Ruang Warna</string>\n    <string name=\"linear\">Linier</string>\n    <string name=\"equalize_histogram_pixelation\">Menyamakan Pikselasi Histogram</string>\n    <string name=\"grid_size_x\">Ukuran Kotak X</string>\n    <string name=\"grid_size_y\">Ukuran Kotak Y</string>\n    <string name=\"equalize_histogram_adaptive\">Menyamakan Histogram Adaptif</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Menyamakan Histogram Adaptif LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Menyamakan LAB Adaptif Histogram</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">LAB CLAHE</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Pangkas ke Konten</string>\n    <string name=\"frame_color\">Warna Bingkai</string>\n    <string name=\"color_to_ignore\">Warna Untuk Diabaikan</string>\n    <string name=\"template\">Templat</string>\n    <string name=\"no_template_filters\">Tidak ada filter template yang ditambahkan</string>\n    <string name=\"create_new\">Buat Baru</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Kode QR yang dipindai bukan template filter yang valid</string>\n    <string name=\"scan_qr_code\">Pindai kode QR</string>\n    <string name=\"opened_file_have_no_filter_template\">File yang dipilih tidak memiliki data template filter</string>\n    <string name=\"create_template\">Buat Templat</string>\n    <string name=\"template_name\">Nama Templat</string>\n    <string name=\"select_template_preview\">Gambar ini akan digunakan untuk melihat pratinjau template filter ini</string>\n    <string name=\"template_filter\">Filter Templat</string>\n    <string name=\"as_qr_code\">Sebagai gambar kode QR</string>\n    <string name=\"as_file\">Sebagai file</string>\n    <string name=\"save_as_file\">Simpan sebagai file</string>\n    <string name=\"save_as_qr_code_image\">Simpan sebagai gambar kode QR</string>\n    <string name=\"delete_template\">Hapus Templat</string>\n    <string name=\"delete_template_warn\">Anda akan menghapus filter template yang dipilih. Operasi ini tidak dapat dibatalkan</string>\n    <string name=\"added_filter_template\">Menambahkan templat filter dengan nama \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Pratinjau Filter</string>\n    <string name=\"qr_code\">QR &amp;amp; Kode Batang</string>\n    <string name=\"qr_code_sub\">Pindai kode QR dan dapatkan kontennya atau tempel string Anda untuk menghasilkan yang baru</string>\n    <string name=\"code_content\">Konten Kode</string>\n    <string name=\"scan_qr_code_to_replace_content\">Pindai kode batang apa pun untuk mengganti konten di bidang, atau ketik sesuatu untuk menghasilkan kode batang baru dengan jenis yang dipilih</string>\n    <string name=\"qr_description\">Deskripsi QR</string>\n    <string name=\"min\">Minimal</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Berikan izin kamera di pengaturan untuk memindai kode QR</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Berikan izin kamera dalam pengaturan untuk memindai Pemindai Dokumen</string>\n    <string name=\"cubic\">Kubik</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">orang kulit hitam</string>\n    <string name=\"welch\">Selamat</string>\n    <string name=\"quadric\">Kuadrik</string>\n    <string name=\"gaussian\">Gaussian</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Tajam</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">kaisar</string>\n    <string name=\"bartlett_hann\">Bartlett-Dia</string>\n    <string name=\"box\">Kotak</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanzos 2</string>\n    <string name=\"lanczos3\">Lanzos 3</string>\n    <string name=\"lanczos4\">Lanzos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Interpolasi kubik memberikan penskalaan yang lebih halus dengan mempertimbangkan 16 piksel terdekat, sehingga memberikan hasil yang lebih baik daripada bilinear</string>\n    <string name=\"bspline_sub\">Memanfaatkan fungsi polinomial yang ditentukan sedikit demi sedikit untuk menginterpolasi dan memperkirakan kurva atau permukaan dengan lancar, representasi bentuk yang fleksibel dan berkelanjutan</string>\n    <string name=\"hamming_sub\">Fungsi jendela yang digunakan untuk mengurangi kebocoran spektral dengan meruncingkan tepi sinyal, berguna dalam pemrosesan sinyal</string>\n    <string name=\"hanning_sub\">Varian dari jendela Hann, biasa digunakan untuk mengurangi kebocoran spektral dalam aplikasi pemrosesan sinyal</string>\n    <string name=\"blackman_sub\">Fungsi jendela yang memberikan resolusi frekuensi yang baik dengan meminimalkan kebocoran spektral, sering digunakan dalam pemrosesan sinyal</string>\n    <string name=\"welch_sub\">Fungsi jendela yang dirancang untuk memberikan resolusi frekuensi yang baik dengan mengurangi kebocoran spektral, sering digunakan dalam aplikasi pemrosesan sinyal</string>\n    <string name=\"quadric_sub\">Sebuah metode yang menggunakan fungsi kuadrat untuk interpolasi, memberikan hasil yang halus dan berkelanjutan</string>\n    <string name=\"gaussian_sub\">Metode interpolasi yang menerapkan fungsi Gaussian, berguna untuk menghaluskan dan mengurangi noise pada gambar</string>\n    <string name=\"sphinx_sub\">Metode pengambilan sampel ulang tingkat lanjut yang memberikan interpolasi berkualitas tinggi dengan artefak minimal</string>\n    <string name=\"bartlett_sub\">Fungsi jendela segitiga yang digunakan dalam pemrosesan sinyal untuk mengurangi kebocoran spektral</string>\n    <string name=\"robidoux_sub\">Metode interpolasi berkualitas tinggi yang dioptimalkan untuk mengubah ukuran gambar secara alami, menyeimbangkan ketajaman dan kehalusan</string>\n    <string name=\"robidoux_sharp_sub\">Varian yang lebih tajam dari metode Robidoux, dioptimalkan untuk pengubahan ukuran gambar yang tajam</string>\n    <string name=\"spline16_sub\">Metode interpolasi berbasis spline yang memberikan hasil halus menggunakan filter 16 ketukan</string>\n    <string name=\"spline36_sub\">Metode interpolasi berbasis spline yang memberikan hasil halus menggunakan filter 36 ketukan</string>\n    <string name=\"spline64_sub\">Metode interpolasi berbasis spline yang memberikan hasil halus menggunakan filter 64 ketukan</string>\n    <string name=\"kaiser_sub\">Metode interpolasi yang menggunakan jendela Kaiser, memberikan kontrol yang baik atas trade-off antara lebar lobus utama dan tingkat lobus samping</string>\n    <string name=\"bartlett_hann_sub\">Fungsi jendela hibrid yang menggabungkan jendela Bartlett dan Hann, digunakan untuk mengurangi kebocoran spektral dalam pemrosesan sinyal</string>\n    <string name=\"box_sub\">Metode pengambilan sampel ulang sederhana yang menggunakan rata-rata nilai piksel terdekat, yang sering kali menghasilkan tampilan kotak-kotak</string>\n    <string name=\"bohman_sub\">Fungsi jendela yang digunakan untuk mengurangi kebocoran spektral, memberikan resolusi frekuensi yang baik dalam aplikasi pemrosesan sinyal</string>\n    <string name=\"lanczos2_sub\">Metode pengambilan sampel ulang yang menggunakan filter Lanczos 2 lobus untuk interpolasi berkualitas tinggi dengan artefak minimal</string>\n    <string name=\"lanczos3_sub\">Metode pengambilan sampel ulang yang menggunakan filter Lanczos 3 lobus untuk interpolasi berkualitas tinggi dengan artefak minimal</string>\n    <string name=\"lanczos4_sub\">Metode pengambilan sampel ulang yang menggunakan filter Lanczos 4 lobus untuk interpolasi berkualitas tinggi dengan artefak minimal</string>\n    <string name=\"lanczos2_jinc_sub\">Varian filter Lanczos 2 yang menggunakan fungsi jinc, memberikan interpolasi berkualitas tinggi dengan artefak minimal</string>\n    <string name=\"lanczos3_jinc_sub\">Varian filter Lanczos 3 yang menggunakan fungsi jinc, memberikan interpolasi berkualitas tinggi dengan artefak minimal</string>\n    <string name=\"lanczos4_jinc_sub\">Varian filter Lanczos 4 yang menggunakan fungsi jinc, memberikan interpolasi berkualitas tinggi dengan artefak minimal</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Varian Elliptical Weighted Average (EWA) dari filter Hanning untuk interpolasi dan pengambilan sampel ulang yang lancar</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Varian Elliptical Weighted Average (EWA) dari filter Robidoux untuk pengambilan sampel ulang berkualitas tinggi</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Varian Elliptical Weighted Average (EWA) dari filter Blackman untuk meminimalkan artefak dering</string>\n    <string name=\"ewa_quadric\">EWA kuadrik</string>\n    <string name=\"ewa_quadric_sub\">Varian Elliptical Weighted Average (EWA) dari filter Quadric untuk interpolasi yang mulus</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Tajam EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Varian Elliptical Weighted Average (EWA) dari filter Robidoux Sharp untuk hasil yang lebih tajam</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Varian Elliptical Weighted Average (EWA) dari filter Lanczos 3 Jinc untuk pengambilan sampel ulang berkualitas tinggi dengan pengurangan aliasing</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Filter pengambilan sampel ulang yang dirancang untuk pemrosesan gambar berkualitas tinggi dengan keseimbangan ketajaman dan kehalusan yang baik</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Varian Elliptical Weighted Average (EWA) dari filter Ginseng untuk meningkatkan kualitas gambar</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Tajam EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Varian Elliptical Weighted Average (EWA) dari filter Lanczos Sharp untuk mencapai hasil yang tajam dengan artefak minimal</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA Paling Tajam</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Varian Elliptical Weighted Average (EWA) dari filter Lanczos 4 Sharpest untuk pengambilan sampel ulang gambar yang sangat tajam</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Lembut EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Varian Elliptical Weighted Average (EWA) dari filter Lanczos Soft untuk pengambilan sampel ulang gambar yang lebih halus</string>\n    <string name=\"haasn_soft\">Haasn Lembut</string>\n    <string name=\"haasn_soft_sub\">Filter pengambilan sampel ulang yang dirancang oleh Haasn untuk penskalaan gambar yang mulus dan bebas artefak</string>\n    <string name=\"format_conversion\">Konversi Format</string>\n    <string name=\"format_conversion_sub\">Konversi kumpulan gambar dari satu format ke format lainnya</string>\n    <string name=\"dismiss_forever\">Singkirkan Selamanya</string>\n    <string name=\"image_stacking\">Penumpukan Gambar</string>\n    <string name=\"image_stacking_sub\">Tumpuk gambar di atas satu sama lain dengan mode campuran yang dipilih</string>\n    <string name=\"add_image\">Tambahkan Gambar</string>\n    <string name=\"bins_count\">Jumlah sampah</string>\n    <string name=\"clahe_hsl\">Cheh HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Menyamakan Histogram Adaptif HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Menyamakan Histogram Adaptif HSV</string>\n    <string name=\"edge_mode\">Modus Tepi</string>\n    <string name=\"clip\">Klip</string>\n    <string name=\"wrap\">Membungkus</string>\n    <string name=\"color_blind_scheme\">Buta Warna</string>\n    <string name=\"color_blind_scheme_sub\">Pilih mode untuk mengadaptasi warna tema untuk varian buta warna yang dipilih</string>\n    <string name=\"protanomaly_sub\">Kesulitan membedakan warna merah dan hijau</string>\n    <string name=\"deuteranomaly_sub\">Kesulitan membedakan warna hijau dan merah</string>\n    <string name=\"tritanomaly_sub\">Kesulitan membedakan warna biru dan kuning</string>\n    <string name=\"protanopia_sub\">Ketidakmampuan untuk melihat warna merah</string>\n    <string name=\"deuteranopia_sub\">Ketidakmampuan untuk melihat warna hijau</string>\n    <string name=\"tritanopia_sub\">Ketidakmampuan untuk melihat warna biru</string>\n    <string name=\"achromatomaly_sub\">Mengurangi sensitivitas terhadap semua warna</string>\n    <string name=\"achromatopsia_sub\">Buta warna total, hanya melihat gradasi warna abu-abu</string>\n    <string name=\"not_use_color_blind_scheme\">Jangan gunakan skema Buta Warna</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Warna akan persis seperti yang ditetapkan dalam tema</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Keterlambatan 2</string>\n    <string name=\"lagrange_2_sub\">Filter interpolasi Lagrange orde 2, cocok untuk penskalaan gambar berkualitas tinggi dengan transisi yang mulus</string>\n    <string name=\"lagrange_3\">Keterlambatan 3</string>\n    <string name=\"lagrange_3_sub\">Filter interpolasi Lagrange urutan 3, menawarkan akurasi lebih baik dan hasil penskalaan gambar lebih halus</string>\n    <string name=\"lanczos_6\">Lanzos 6</string>\n    <string name=\"lanczos_6_sub\">Filter pengambilan sampel ulang Lanczos dengan urutan 6 lebih tinggi, memberikan penskalaan gambar yang lebih tajam dan akurat</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Varian filter Lanczos 6 yang menggunakan fungsi Jinc untuk meningkatkan kualitas pengambilan sampel ulang gambar</string>\n    <string name=\"linear_box_blur\">Kabur Kotak Linier</string>\n    <string name=\"linear_tent_blur\">Kabur Tenda Linear</string>\n    <string name=\"linear_gaussian_box_blur\">Kabur Kotak Gaussian Linier</string>\n    <string name=\"linear_stack_blur\">Kekaburan Tumpukan Linier</string>\n    <string name=\"gaussian_box_blur\">Kabur Kotak Gaussian</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linear Fast Gaussian Blur Berikutnya</string>\n    <string name=\"linear_fast_gaussian_blur\">Buram Gaussian Cepat Linier</string>\n    <string name=\"linear_gaussian_blur\">Kekaburan Gaussian Linier</string>\n    <string name=\"draw_filter_sub\">Pilih satu filter untuk digunakan sebagai cat</string>\n    <string name=\"replace_filter\">Ganti Filter</string>\n    <string name=\"pick_filter_info\">Pilih filter di bawah untuk menggunakannya sebagai kuas pada gambar Anda</string>\n    <string name=\"tiff_compression_scheme\">Skema kompresi TIFF</string>\n    <string name=\"low_poly\">Poli Rendah</string>\n    <string name=\"sand_painting\">Lukisan Pasir</string>\n    <string name=\"image_splitting\">Pemisahan Gambar</string>\n    <string name=\"image_splitting_sub\">Pisahkan satu gambar berdasarkan baris atau kolom</string>\n    <string name=\"fit_to_bounds\">Sesuai Batas</string>\n    <string name=\"fit_to_bounds_sub\">Gabungkan mode pengubahan ukuran pangkas dengan parameter ini untuk mencapai perilaku yang diinginkan (Pangkas/Sesuaikan dengan rasio aspek)</string>\n    <string name=\"languages_imported\">Bahasa berhasil diimpor</string>\n    <string name=\"backup_ocr_models\">Cadangkan model OCR</string>\n    <string name=\"import_word\">Impor</string>\n    <string name=\"export\">Ekspor</string>\n    <string name=\"position\">Posisi</string>\n    <string name=\"center\">Tengah</string>\n    <string name=\"top_left\">Kiri Atas</string>\n    <string name=\"top_right\">Kanan atas</string>\n    <string name=\"bottom_left\">Kiri Bawah</string>\n    <string name=\"bottom_right\">Kanan Bawah</string>\n    <string name=\"top_center\">Pusat Atas</string>\n    <string name=\"center_right\">Kanan Tengah</string>\n    <string name=\"bottom_center\">Tengah Bawah</string>\n    <string name=\"center_left\">Kiri Tengah</string>\n    <string name=\"target_image\">Gambar Sasaran</string>\n    <string name=\"palette_transfer\">Pemindahan Palet</string>\n    <string name=\"enhanced_oil\">Minyak yang Ditingkatkan</string>\n    <string name=\"simple_old_tv\">TV Lama Sederhana</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Sketsa Sederhana</string>\n    <string name=\"soft_glow\">Cahaya Lembut</string>\n    <string name=\"color_poster\">Poster Berwarna</string>\n    <string name=\"tri_tone\">Tri Nada</string>\n    <string name=\"third_color\">Warna ketiga</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka dot</string>\n    <string name=\"clustered_2x2_dithering\">Dithering 2x2 Berkelompok</string>\n    <string name=\"clustered_4x4_dithering\">Dithering 4x4 Berkelompok</string>\n    <string name=\"clustered_8x8_dithering\">Dithering 8x8 Berkelompok</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Tidak ada opsi favorit yang dipilih, tambahkan di halaman alat</string>\n    <string name=\"add_favorites\">Tambahkan Favorit</string>\n    <string name=\"harmony_complementary\">Komplementer</string>\n    <string name=\"harmony_analogous\">Sejalan</string>\n    <string name=\"harmony_triadic\">Triadik</string>\n    <string name=\"harmony_split_complementary\">Terpisah Komplementer</string>\n    <string name=\"harmony_tetradic\">Tetradik</string>\n    <string name=\"harmony_square\">Persegi</string>\n    <string name=\"harmony_analogous_complementary\">Analog + Komplementer</string>\n    <string name=\"color_tools\">Alat Warna</string>\n    <string name=\"color_tools_sub\">Mencampur, membuat nada, menghasilkan corak, dan banyak lagi</string>\n    <string name=\"color_harmonies\">Harmoni Warna</string>\n    <string name=\"color_shading\">Bayangan Warna</string>\n    <string name=\"variation\">Variasi</string>\n    <string name=\"tints\">warna</string>\n    <string name=\"tones\">Nada</string>\n    <string name=\"shades\">Nuansa</string>\n    <string name=\"color_mixing\">Pencampuran Warna</string>\n    <string name=\"color_info\">Info Warna</string>\n    <string name=\"selected_color\">Warna yang Dipilih</string>\n    <string name=\"color_to_mix\">Warna Untuk Dicampur</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Tidak dapat menggunakan monet saat warna dinamis diaktifkan</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Targetkan gambar LUT</string>\n    <string name=\"amatorka\">Seorang amatir</string>\n    <string name=\"miss_etikate\">Nona Etiket</string>\n    <string name=\"soft_elegance\">Keanggunan Lembut</string>\n    <string name=\"soft_elegance_variant\">Varian Keanggunan Lembut</string>\n    <string name=\"palette_transfer_variant\">Varian Transfer Palet</string>\n    <string name=\"cube_lut\">LUT 3D</string>\n    <string name=\"target_cube_lut_file\">Targetkan File LUT 3D (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bypass Pemutih</string>\n    <string name=\"candlelight\">Cahaya lilin</string>\n    <string name=\"drop_blues\">Jatuhkan Blues</string>\n    <string name=\"edgy_amber\">Amber yang tegang</string>\n    <string name=\"fall_colors\">Warna Musim Gugur</string>\n    <string name=\"film_stock_50\">Stok Film 50</string>\n    <string name=\"foggy_night\">Malam Berkabut</string>\n    <string name=\"kodak\">Memotret dgn kodak</string>\n    <string name=\"save_empty_lut\">Dapatkan gambar LUT Netral</string>\n    <string name=\"save_empty_lut_sub\">Pertama, gunakan aplikasi edit foto favorit Anda untuk menerapkan filter pada LUT netral yang bisa Anda dapatkan di sini. Agar ini berfungsi dengan baik, setiap warna piksel tidak boleh bergantung pada piksel lainnya (misalnya, keburaman tidak akan berfungsi). Setelah siap, gunakan gambar LUT baru Anda sebagai masukan untuk filter LUT 512*512</string>\n    <string name=\"pop_art\">Seni Pop</string>\n    <string name=\"celluloid\">Seluloida</string>\n    <string name=\"coffee\">Kopi</string>\n    <string name=\"golden_forest\">Hutan Emas</string>\n    <string name=\"greenish\">kehijauan</string>\n    <string name=\"retro_yellow\">Retro Kuning</string>\n    <string name=\"links_preview\">Pratinjau Tautan</string>\n    <string name=\"links_preview_sub\">Mengaktifkan pengambilan pratinjau tautan di tempat Anda dapat memperoleh teks (QRCode, OCR, dll)</string>\n    <string name=\"links\">Tautan</string>\n    <string name=\"ico_size_warning\">File ICO hanya dapat disimpan dengan ukuran maksimal 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF ke WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Konversi gambar GIF menjadi gambar animasi WEBP</string>\n    <string name=\"webp_tools\">Alat WEBP</string>\n    <string name=\"webp_tools_sub\">Konversikan gambar menjadi gambar animasi WEBP atau ekstrak bingkai dari animasi WEBP yang diberikan</string>\n    <string name=\"webp_type_to_image\">WEBP ke gambar</string>\n    <string name=\"webp_type_to_image_sub\">Konversikan file WEBP menjadi kumpulan gambar</string>\n    <string name=\"webp_type_to_webp_sub\">Konversikan kumpulan gambar ke file WEBP</string>\n    <string name=\"webp_type_to_webp\">Gambar ke WEBP</string>\n    <string name=\"select_webp_image_to_start\">Pilih gambar WEBP untuk memulai</string>\n    <string name=\"manage_storage_extra_types\">Tidak ada akses penuh ke file</string>\n    <string name=\"manage_storage_extra_types_sub\">Izinkan semua akses file untuk melihat JXL, QOI dan gambar lain yang tidak dikenali sebagai gambar di Android. Tanpa izin, Image Toolbox tidak dapat menampilkan gambar-gambar itu</string>\n    <string name=\"default_draw_color\">Warna Gambar Default</string>\n    <string name=\"default_draw_path_mode\">Mode Jalur Gambar Default</string>\n    <string name=\"add_timestamp\">Tambahkan Stempel Waktu</string>\n    <string name=\"add_timestamp_sub\">Mengaktifkan penambahan Stempel Waktu ke nama file keluaran</string>\n    <string name=\"formatted_timestamp\">Stempel Waktu yang Diformat</string>\n    <string name=\"formatted_timestamp_sub\">Aktifkan pemformatan Stempel Waktu dalam nama file keluaran, bukan mili dasar</string>\n    <string name=\"enable_timestamps_to_format_them\">Aktifkan Stempel Waktu untuk memilih formatnya</string>\n    <string name=\"one_time_save_location\">Satu Kali Simpan Lokasi</string>\n    <string name=\"one_time_save_location_sub\">Lihat dan Edit lokasi penyimpanan satu kali yang dapat Anda gunakan dengan menekan lama tombol simpan di sebagian besar semua opsi</string>\n    <string name=\"recently_used\">Baru-baru ini Digunakan</string>\n    <string name=\"ci_channel\">saluran CI</string>\n    <string name=\"group\">Kelompok</string>\n    <string name=\"image_toolbox_in_telegram\">Kotak Alat Gambar di Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Bergabunglah dengan obrolan kami di mana Anda dapat mendiskusikan apa pun yang Anda inginkan dan juga melihat saluran CI tempat saya memposting beta dan pengumuman</string>\n    <string name=\"ci_channel_sub\">Dapatkan pemberitahuan tentang versi aplikasi baru, dan baca pengumuman</string>\n    <string name=\"fit_description\">Sesuaikan gambar dengan dimensi tertentu dan terapkan buram atau warna pada latar belakang</string>\n    <string name=\"tools_arrangement\">Penataan Alat</string>\n    <string name=\"group_tools_by_type\">Kelompokkan alat berdasarkan jenisnya</string>\n    <string name=\"group_tools_by_type_sub\">Mengelompokkan alat di layar utama berdasarkan jenisnya, bukan berdasarkan susunan daftar khusus</string>\n    <string name=\"default_values\">Nilai Bawaan</string>\n    <string name=\"system_bars_visibility\">Visibilitas Bilah Sistem</string>\n    <string name=\"show_system_bars_by_swipe\">Tampilkan Bilah Sistem Dengan Gesek</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Mengaktifkan gesekan untuk menampilkan bilah sistem jika disembunyikan</string>\n    <string name=\"auto\">Mobil</string>\n    <string name=\"hide_all\">Sembunyikan Semua</string>\n    <string name=\"show_all\">Tampilkan Semua</string>\n    <string name=\"hide_nav_bar\">Sembunyikan Bilah Navigasi</string>\n    <string name=\"hide_status_bar\">Sembunyikan Bilah Status</string>\n    <string name=\"noise_generation\">Pembangkitan Kebisingan</string>\n    <string name=\"noise_generation_sub\">Hasilkan suara yang berbeda seperti Perlin atau jenis lainnya</string>\n    <string name=\"frequency\">Frekuensi</string>\n    <string name=\"noise_type\">Jenis Kebisingan</string>\n    <string name=\"rotation_type\">Tipe Rotasi</string>\n    <string name=\"fractal_type\">Tipe Fraktal</string>\n    <string name=\"octaves\">Oktaf</string>\n    <string name=\"lacunarity\">kekurangan</string>\n    <string name=\"gain\">Memperoleh</string>\n    <string name=\"weighted_strength\">Kekuatan Tertimbang</string>\n    <string name=\"ping_pong_strength\">Kekuatan Ping Pong</string>\n    <string name=\"distance_function\">Fungsi Jarak</string>\n    <string name=\"return_type\">Jenis Pengembalian</string>\n    <string name=\"jitter\">Naik opelet</string>\n    <string name=\"domain_warp\">Kelengkungan Domain</string>\n    <string name=\"alignment\">Penyelarasan</string>\n    <string name=\"custom_filename\">Nama File Khusus</string>\n    <string name=\"custom_filename_sub\">Pilih lokasi dan nama file yang akan digunakan untuk menyimpan gambar saat ini</string>\n    <string name=\"saved_to_custom\">Disimpan ke folder dengan nama khusus</string>\n    <string name=\"collage_maker\">Pembuat Kolase</string>\n    <string name=\"collage_maker_sub\">Buat kolase hingga 20 gambar</string>\n    <string name=\"collage_type\">Jenis Kolase</string>\n    <string name=\"collages_info\">Tahan gambar untuk menukar, memindahkan dan memperbesar untuk menyesuaikan posisi</string>\n    <string name=\"disable_rotation\">Nonaktifkan rotasi</string>\n    <string name=\"disable_rotation_sub\">Mencegah memutar gambar dengan gerakan dua jari</string>\n    <string name=\"enable_snapping_to_borders\">Aktifkan gertakan ke batas</string>\n    <string name=\"enable_snapping_to_borders_sub\">Setelah dipindahkan atau diperbesar, gambar akan diambil untuk memenuhi tepi bingkai</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">Histogram gambar RGB atau Kecerahan untuk membantu Anda melakukan penyesuaian</string>\n    <string name=\"image_for_histogram\">Gambar ini akan digunakan untuk menghasilkan histogram RGB dan Brightness</string>\n    <string name=\"tesseract_options\">Opsi Tesseract</string>\n    <string name=\"tesseract_options_sub\">Terapkan beberapa variabel masukan untuk mesin tesseract</string>\n    <string name=\"custom_options\">Opsi Kustom</string>\n    <string name=\"custom_params_info\">Opsi harus dimasukkan mengikuti pola ini: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Pangkas Otomatis</string>\n    <string name=\"free_corners\">Sudut Bebas</string>\n    <string name=\"free_corners_sub\">Pangkas gambar berdasarkan poligon, ini juga mengoreksi perspektif</string>\n    <string name=\"coerce_points_to_image_bounds\">Paksaan Menunjuk Ke Batas Gambar</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Titik tidak akan dibatasi oleh batas gambar, hal ini berguna untuk koreksi perspektif yang lebih tepat</string>\n    <string name=\"mask\">Masker</string>\n    <string name=\"spot_heal_sub\">Isi sadar konten di bawah jalur yang digambar</string>\n    <string name=\"spot_heal\">Tempat Sembuh</string>\n    <string name=\"use_circle_kernel\">Gunakan Kernel Lingkaran</string>\n    <string name=\"opening\">Pembukaan</string>\n    <string name=\"closing\">Penutupan</string>\n    <string name=\"morphological_gradient\">Gradien Morfologi</string>\n    <string name=\"top_hat\">Topi Atas</string>\n    <string name=\"black_hat\">Topi Hitam</string>\n    <string name=\"tone_curves\">Kurva Nada</string>\n    <string name=\"reset_curves\">Atur Ulang Kurva</string>\n    <string name=\"reset_curves_sub\">Kurva akan dikembalikan ke nilai default</string>\n    <string name=\"line_style\">Gaya Garis</string>\n    <string name=\"gap_size\">Ukuran Celah</string>\n    <string name=\"dashed\">Putus-putus</string>\n    <string name=\"dot_dashed\">Titik putus-putus</string>\n    <string name=\"stamped\">Dicap</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Menarik garis putus-putus di sepanjang jalur yang ditarik dengan ukuran celah yang ditentukan</string>\n    <string name=\"dot_dashed_sub\">Menggambar titik dan garis putus-putus di sepanjang jalur tertentu</string>\n    <string name=\"defaultt_sub\">Hanya garis lurus default</string>\n    <string name=\"stamped_sub\">Menggambar bentuk yang dipilih di sepanjang jalur dengan jarak tertentu</string>\n    <string name=\"zigzag_sub\">Menggambar zigzag bergelombang di sepanjang jalan</string>\n    <string name=\"zigzag_ratio\">Rasio zigzag</string>\n    <string name=\"create_shortcut\">Buat Pintasan</string>\n    <string name=\"create_shortcut_title\">Pilih alat untuk disematkan</string>\n    <string name=\"create_shortcut_subtitle\">Alat akan ditambahkan ke layar beranda peluncur Anda sebagai pintasan, gunakan alat tersebut dengan menggabungkan pengaturan \\\"Lewati pengambilan file\\\" untuk mencapai perilaku yang diperlukan</string>\n    <string name=\"dont_stack_frames\">Jangan menumpuk bingkai</string>\n    <string name=\"dont_stack_frames_sub\">Memungkinkan pembuangan bingkai sebelumnya, sehingga bingkai tersebut tidak akan saling bertumpuk</string>\n    <string name=\"crossfade\">memudar silang</string>\n    <string name=\"crossfade_sub\">Bingkai akan saling memudar satu sama lain</string>\n    <string name=\"crossfade_count\">Bingkai crossfade dihitung</string>\n    <string name=\"threshold_one\">Ambang Batas Satu</string>\n    <string name=\"threshold_two\">Ambang Batas Dua</string>\n    <string name=\"canny\">Cerdik</string>\n    <string name=\"mirror_101\">Cermin 101</string>\n    <string name=\"enhanced_zoom_blur\">Keburaman Zoom yang Ditingkatkan</string>\n    <string name=\"laplacian_simple\">Laplacian Sederhana</string>\n    <string name=\"sobel_simple\">Sobel Sederhana</string>\n    <string name=\"helper_grid\">Kotak Pembantu</string>\n    <string name=\"helper_grid_sub\">Menampilkan kisi pendukung di atas area gambar untuk membantu manipulasi yang tepat</string>\n    <string name=\"grid_color\">Warna Kotak</string>\n    <string name=\"cell_width\">Lebar Sel</string>\n    <string name=\"cell_height\">Tinggi Sel</string>\n    <string name=\"compact_selectors\">Penyeleksi Ringkas</string>\n    <string name=\"compact_selectors_sub\">Beberapa kontrol pemilihan akan menggunakan tata letak yang ringkas untuk menghemat ruang</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Berikan izin kamera dalam pengaturan untuk mengambil gambar</string>\n    <string name=\"layout\">Tata Letak</string>\n    <string name=\"main_screen_title\">Judul Layar Utama</string>\n    <string name=\"constant_rate_factor\">Faktor Tingkat Konstan (CRF)</string>\n    <string name=\"crf_sub\">Nilai %1$s berarti kompresi yang lambat sehingga menghasilkan ukuran file yang relatif kecil. %2$s berarti kompresi lebih cepat sehingga menghasilkan file besar.</string>\n    <string name=\"lut_library\">Perpustakaan Luth</string>\n    <string name=\"lut_library_sub\">Download kumpulan LUT yang dapat Anda terapkan setelah mendownload</string>\n    <string name=\"lut_library_update_sub\">Perbarui koleksi LUT (hanya yang baru yang akan dimasukkan dalam antrean), yang dapat Anda terapkan setelah mengunduh</string>\n    <string name=\"filter_preview_image_sub\">Ubah pratinjau gambar default untuk filter</string>\n    <string name=\"filter_preview_image\">Pratinjau Gambar</string>\n    <string name=\"hide\">Bersembunyi</string>\n    <string name=\"show\">Menunjukkan</string>\n    <string name=\"slider_type\">Tipe Penggeser</string>\n    <string name=\"fancy\">Menyukai</string>\n    <string name=\"material_2\">Bahan 2</string>\n    <string name=\"fancy_sub\">Slider yang tampak mewah. Ini adalah opsi default</string>\n    <string name=\"material_2_sub\">Penggeser Material 2</string>\n    <string name=\"material_you_slider_sub\">Penggeser Materi Anda</string>\n    <string name=\"apply\">Menerapkan</string>\n    <string name=\"center_align_dialog_buttons\">Tombol Dialog Tengah</string>\n    <string name=\"center_align_dialog_buttons_sub\">Tombol dialog akan diposisikan di tengah, bukan di kiri jika memungkinkan</string>\n    <string name=\"open_source_licenses\">Lisensi Sumber Terbuka</string>\n    <string name=\"open_source_licenses_sub\">Lihat lisensi perpustakaan sumber terbuka yang digunakan dalam aplikasi ini</string>\n    <string name=\"area\">Daerah</string>\n    <string name=\"area_sub\">Pengambilan sampel ulang menggunakan relasi area piksel. Ini mungkin merupakan metode yang lebih disukai untuk penipisan gambar, karena memberikan hasil bebas moire. Namun saat gambar diperbesar, serupa dengan metode \\\"Terdekat\\\".</string>\n    <string name=\"enable_tonemapping\">Aktifkan Pemetaan Nada</string>\n    <string name=\"enter_percent\">Memasuki %</string>\n    <string name=\"unknown_host\">Tidak dapat mengakses situs, coba gunakan VPN atau periksa apakah urlnya benar</string>\n    <string name=\"markup_layers\">Lapisan Markup</string>\n    <string name=\"markup_layers_sub\">Mode lapisan dengan kemampuan untuk secara bebas menempatkan gambar, teks, dan lainnya</string>\n    <string name=\"edit_layer\">Sunting lapisan</string>\n    <string name=\"layers_on_image\">Lapisan pada gambar</string>\n    <string name=\"layers_on_image_sub\">Gunakan gambar sebagai latar belakang dan tambahkan lapisan berbeda di atasnya</string>\n    <string name=\"layers_on_background\">Lapisan di latar belakang</string>\n    <string name=\"layers_on_background_sub\">Sama seperti opsi pertama tetapi dengan warna, bukan gambar</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Sisi Pengaturan Cepat</string>\n    <string name=\"fast_settings_side_sub\">Tambahkan strip mengambang di sisi yang dipilih saat mengedit gambar, yang akan membuka pengaturan cepat saat diklik</string>\n    <string name=\"clear_selection\">Hapus pilihan</string>\n    <string name=\"settings_group_visibility_hidden\">Grup pengaturan \\\"%1$s\\\" akan diciutkan secara default</string>\n    <string name=\"settings_group_visibility_visible\">Grup pengaturan \\\"%1$s\\\" akan diperluas secara default</string>\n    <string name=\"base_64_tools\">Alat Base64</string>\n    <string name=\"base_64_tools_sub\">Dekode string Base64 menjadi gambar, atau enkode gambar ke format Base64</string>\n    <string name=\"base_64\">Basis64</string>\n    <string name=\"not_a_valid_base_64\">Nilai yang diberikan bukan string Base64 yang valid</string>\n    <string name=\"copy_not_a_valid_base_64\">Tidak dapat menyalin string Base64 yang kosong atau tidak valid</string>\n    <string name=\"paste_base_64\">Tempel Base64</string>\n    <string name=\"copy_base_64\">Salin Base64</string>\n    <string name=\"base_64_tips\">Muat gambar untuk menyalin atau menyimpan string Base64. Jika Anda memiliki stringnya sendiri, Anda dapat menempelkannya di atas untuk mendapatkan gambar</string>\n    <string name=\"save_base_64\">Simpan Base64</string>\n    <string name=\"share_base_64\">Bagikan Base64</string>\n    <string name=\"options\">Pilihan</string>\n    <string name=\"actions\">Tindakan</string>\n    <string name=\"import_base_64\">Impor Base64</string>\n    <string name=\"base_64_actions\">Tindakan Base64</string>\n    <string name=\"add_outline\">Tambahkan Garis Besar</string>\n    <string name=\"add_outline_sub\">Tambahkan garis luar di sekitar teks dengan warna dan lebar tertentu</string>\n    <string name=\"outline_color\">Warna Garis Besar</string>\n    <string name=\"outline_size\">Ukuran Garis Besar</string>\n    <string name=\"rotation\">Rotasi</string>\n    <string name=\"checksum_as_filename\">Checksum sebagai Nama File</string>\n    <string name=\"checksum_as_filename_sub\">Gambar keluaran akan memiliki nama yang sesuai dengan checksum datanya</string>\n    <string name=\"free_software_partner\">Perangkat Lunak Gratis (Mitra)</string>\n    <string name=\"free_software_partner_sub\">Perangkat lunak yang lebih berguna di saluran mitra aplikasi Android</string>\n    <string name=\"algorithms\">Algoritma</string>\n    <string name=\"checksum_tools\">Alat Checksum</string>\n    <string name=\"checksum_tools_sub\">Bandingkan checksum, hitung hash, atau buat string hex dari file menggunakan algoritma hashing yang berbeda</string>\n    <string name=\"calculate\">Menghitung</string>\n    <string name=\"text_hash\">Teks Hash</string>\n    <string name=\"checksum\">Jumlah pemeriksaan</string>\n    <string name=\"pick_file_to_checksum\">Pilih file untuk menghitung checksumnya berdasarkan algoritma yang dipilih</string>\n    <string name=\"enter_text_to_checksum\">Masukkan teks untuk menghitung checksumnya berdasarkan algoritma yang dipilih</string>\n    <string name=\"source_checksum\">Sumber Checksum</string>\n    <string name=\"checksum_to_compare\">Checksum Untuk Membandingkan</string>\n    <string name=\"match\">Cocok!</string>\n    <string name=\"difference\">Perbedaan</string>\n    <string name=\"match_sub\">Checksumnya sama, bisa aman</string>\n    <string name=\"difference_sub\">Checksum tidak sama, file bisa jadi tidak aman!</string>\n    <string name=\"mesh_gradients\">Gradien Jala</string>\n    <string name=\"collection_mesh_gradients_sub\">Lihatlah koleksi online Mesh Gradients</string>\n    <string name=\"wrong_font\">Hanya font TTF dan OTF yang dapat diimpor</string>\n    <string name=\"import_font\">Impor font (TTF/OTF)</string>\n    <string name=\"export_fonts\">Ekspor font</string>\n    <string name=\"imported_fonts\">Font yang diimpor</string>\n    <string name=\"error_while_saving\">Terjadi kesalahan saat mencoba menyimpan, coba ubah folder keluaran</string>\n    <string name=\"filename_is_not_set\">Nama file tidak disetel</string>\n    <string name=\"none\">Tidak ada</string>\n    <string name=\"custom_pages\">Halaman Khusus</string>\n    <string name=\"pages_selection\">Pemilihan Halaman</string>\n    <string name=\"tool_exit_confirmation\">Konfirmasi Keluar Alat</string>\n    <string name=\"tool_exit_confirmation_sub\">Jika Anda memiliki perubahan yang belum disimpan saat menggunakan alat tertentu dan mencoba menutupnya, dialog konfirmasi akan ditampilkan</string>\n    <string name=\"edit_exif_screen\">Sunting EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Ubah metadata gambar tunggal tanpa kompresi ulang</string>\n    <string name=\"edit_exif_tag\">Ketuk untuk mengedit tag yang tersedia</string>\n    <string name=\"change_sticker\">Ganti Stiker</string>\n    <string name=\"fit_width\">Lebar Pas</string>\n    <string name=\"fit_height\">Cocok Tinggi</string>\n    <string name=\"batch_compare\">Bandingkan Batch</string>\n    <string name=\"pick_files_to_checksum\">Pilih file/file untuk menghitung checksumnya berdasarkan algoritma yang dipilih</string>\n    <string name=\"pick_files\">Pilih File</string>\n    <string name=\"pick_directory\">Pilih Direktori</string>\n    <string name=\"head_length_scale\">Skala Panjang Kepala</string>\n    <string name=\"stamp\">Perangko</string>\n    <string name=\"timestamp\">Stempel waktu</string>\n    <string name=\"format_pattern\">Pola Format</string>\n    <string name=\"padding\">Lapisan</string>\n    <string name=\"image_cutting\">Pemotongan Gambar</string>\n    <string name=\"image_cutting_sub\">Potong bagian gambar dan gabungkan bagian kiri (bisa terbalik) dengan garis vertikal atau horizontal</string>\n    <string name=\"vertical_pivot_line\">Garis Pivot Vertikal</string>\n    <string name=\"horizontal_pivot_line\">Garis Pivot Horisontal</string>\n    <string name=\"inverse_selection\">Seleksi Terbalik</string>\n    <string name=\"inverse_vertical_selection_sub\">Bagian yang dipotong secara vertikal akan dibiarkan, alih-alih menggabungkan bagian di sekitar area yang dipotong</string>\n    <string name=\"inverse_horizontal_selection_sub\">Bagian yang dipotong secara horizontal akan dibiarkan, bukannya menggabungkan bagian di sekitar area yang dipotong</string>\n    <string name=\"collection_mesh_gradients\">Koleksi Gradien Mesh</string>\n    <string name=\"mesh_gradients_sub\">Buat gradien mesh dengan jumlah simpul dan resolusi khusus</string>\n    <string name=\"gradient_maker_type_image_mesh\">Hamparan Gradien Jala</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Buat gradien mesh di bagian atas gambar yang diberikan</string>\n    <string name=\"points_customization\">Kustomisasi Poin</string>\n    <string name=\"grid_size\">Ukuran Kotak</string>\n    <string name=\"resolution_x\">Resolusi X</string>\n    <string name=\"resolution_y\">Resolusi Y</string>\n    <string name=\"resolution\">Resolusi</string>\n    <string name=\"pixel_by_pixel\">Piksel Demi Piksel</string>\n    <string name=\"highlight_color\">Warna Sorotan</string>\n    <string name=\"pixel_comparison_type\">Jenis Perbandingan Piksel</string>\n    <string name=\"scan_barcode\">Pindai kode batang</string>\n    <string name=\"height_ratio\">Rasio Tinggi Badan</string>\n    <string name=\"barcode_type\">Jenis Kode Batang</string>\n    <string name=\"enforce_bw\">Menerapkan Hitam dan Putih</string>\n    <string name=\"enforce_bw_sub\">Gambar Barcode akan sepenuhnya hitam putih dan tidak diwarnai berdasarkan tema aplikasi</string>\n    <string name=\"barcodes_sub\">Pindai Barcode apa pun (QR, EAN, AZTEC,…) dan dapatkan kontennya atau tempel teks Anda untuk menghasilkan yang baru</string>\n    <string name=\"no_barcode_found\">Tidak Ditemukan Kode Batang</string>\n    <string name=\"generated_barcode_will_be_here\">Barcode yang Dihasilkan Akan Ada Di Sini</string>\n    <string name=\"audio_cover_extractor\">Sampul Audio</string>\n    <string name=\"audio_cover_extractor_sub\">Ekstrak gambar sampul album dari file audio, format paling umum didukung</string>\n    <string name=\"pick_audio_to_start\">Pilih audio untuk memulai</string>\n    <string name=\"pick_audio\">Pilih Audio</string>\n    <string name=\"no_covers_found\">Tidak Ada Sampul yang Ditemukan</string>\n    <string name=\"send_logs\">Kirim Log</string>\n    <string name=\"send_logs_sub\">Klik untuk membagikan file log aplikasi, ini dapat membantu saya menemukan masalah dan memperbaiki masalah</string>\n    <string name=\"crash_title\">Ups… Ada yang tidak beres</string>\n    <string name=\"crash_subtitle\">Anda dapat menghubungi saya menggunakan opsi di bawah dan saya akan mencoba mencari solusinya.\\n(Jangan lupa melampirkan log)</string>\n    <string name=\"ocr_write_to_file\">Tulis Ke File</string>\n    <string name=\"ocr_write_to_file_sub\">Ekstrak teks dari kumpulan gambar dan simpan dalam satu file teks</string>\n    <string name=\"ocr_write_to_metadata\">Tulis Ke Metadata</string>\n    <string name=\"ocr_write_to_metadata_sub\">Ekstrak teks dari setiap gambar dan letakkan di info EXIF ​​​​dari foto relatif</string>\n    <string name=\"invisible_mode\">Modus Tak Terlihat</string>\n    <string name=\"invisible_mode_sub\">Gunakan steganografi untuk membuat tanda air yang tidak terlihat oleh mata di dalam byte gambar Anda</string>\n    <string name=\"use_lsb\">Gunakan LSB</string>\n    <string name=\"use_lsb_sub\">Metode steganografi LSB (Less Significant Bit) akan digunakan, FD (Frequency Domain) sebaliknya</string>\n    <string name=\"auto_remove_red_eyes\">Hapus Otomatis Mata Merah</string>\n    <string name=\"password\">Kata sandi</string>\n    <string name=\"unlock\">Membuka kunci</string>\n    <string name=\"pdf_is_protected\">PDF dilindungi</string>\n    <string name=\"operation_almost_complete\">Operasi hampir selesai. Membatalkan sekarang memerlukan memulai ulang</string>\n    <string name=\"sort_by_date_modified\">Tanggal Dimodifikasi</string>\n    <string name=\"sort_by_date_modified_reversed\">Tanggal Dimodifikasi (Terbalik)</string>\n    <string name=\"sort_by_size\">Ukuran</string>\n    <string name=\"sort_by_size_reversed\">Ukuran (Terbalik)</string>\n    <string name=\"sort_by_mime_type\">Tipe MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Jenis MIME (Terbalik)</string>\n    <string name=\"sort_by_extension\">Perpanjangan</string>\n    <string name=\"sort_by_extension_reversed\">Ekstensi (Terbalik)</string>\n    <string name=\"sort_by_date_added\">Tanggal Ditambahkan</string>\n    <string name=\"sort_by_date_added_reversed\">Tanggal Ditambahkan (Terbalik)</string>\n    <string name=\"left_to_right\">Kiri ke Kanan</string>\n    <string name=\"right_to_left\">Kanan ke Kiri</string>\n    <string name=\"top_to_bottom\">Atas ke Bawah</string>\n    <string name=\"bottom_to_top\">Bawah ke Atas</string>\n    <string name=\"liquid_glass\">Kaca Cair</string>\n    <string name=\"liquid_glass_sub\">Peralihan berdasarkan IOS 26 yang baru diumumkan dan sistem desain kaca cairnya</string>\n    <string name=\"pick_image_or_base64\">Pilih gambar atau tempel/impor data Base64 di bawah</string>\n    <string name=\"type_image_link\">Ketik tautan gambar untuk memulai</string>\n    <string name=\"paste_link\">Tempel tautan</string>\n    <string name=\"kaleidoscope\">Kaledoskop</string>\n    <string name=\"secondary_angle\">Sudut sekunder</string>\n    <string name=\"sides\">Sisi</string>\n    <string name=\"channel_mix\">Campuran Saluran</string>\n    <string name=\"blue_green\">Biru hijau</string>\n    <string name=\"red_blue\">Merah biru</string>\n    <string name=\"green_red\">Hijau merah</string>\n    <string name=\"into_red\">Menjadi merah</string>\n    <string name=\"into_green\">Menjadi hijau</string>\n    <string name=\"into_blue\">Menjadi biru</string>\n    <string name=\"cyan\">Sian</string>\n    <string name=\"magenta\">ungu</string>\n    <string name=\"yellow\">Kuning</string>\n    <string name=\"color_halftone\">Warna Halftone</string>\n    <string name=\"contour\">Kontur</string>\n    <string name=\"levels\">Tingkat</string>\n    <string name=\"offset\">Mengimbangi</string>\n    <string name=\"voronoi_crystallize\">Voronoi Mengkristal</string>\n    <string name=\"shape\">Membentuk</string>\n    <string name=\"stretch\">Menggeliat</string>\n    <string name=\"randomness\">Keserampangan</string>\n    <string name=\"despeckle\">bintik</string>\n    <string name=\"diffuse\">Membaur</string>\n    <string name=\"dog\">Anjing</string>\n    <string name=\"second_radius\">Jari-jari kedua</string>\n    <string name=\"equalize\">Menyamakan</string>\n    <string name=\"glow\">Binar</string>\n    <string name=\"whirl_and_pinch\">Berputar dan Jepit</string>\n    <string name=\"pointillize\">Menunjuk</string>\n    <string name=\"border_color\">Warna perbatasan</string>\n    <string name=\"polar_coordinates\">Koordinat Kutub</string>\n    <string name=\"rect_to_polar\">Searah ke kutub</string>\n    <string name=\"polar_to_rect\">Kutub untuk meluruskan</string>\n    <string name=\"invert_in_circle\">Balikkan dalam lingkaran</string>\n    <string name=\"reduce_noise\">Kurangi Kebisingan</string>\n    <string name=\"simple_solarize\">Solarisasi Sederhana</string>\n    <string name=\"weave\">Menenun</string>\n    <string name=\"x_gap\">X Kesenjangan</string>\n    <string name=\"y_gap\">kesenjangan Y</string>\n    <string name=\"x_width\">X Lebar</string>\n    <string name=\"y_wdth\">Y Lebar</string>\n    <string name=\"twirl\">Berputar</string>\n    <string name=\"rubber_stmp\">Stempel Karet</string>\n    <string name=\"smear\">Mengolesi</string>\n    <string name=\"density\">Kepadatan</string>\n    <string name=\"mix\">Mencampur</string>\n    <string name=\"sphere_lensh_distortion\">Distorsi Lensa Bola</string>\n    <string name=\"refraction_index\">Indeks refraksi</string>\n    <string name=\"arc\">Busur</string>\n    <string name=\"spread_angle\">Sudut penyebaran</string>\n    <string name=\"sparkle\">Berkilau</string>\n    <string name=\"rays\">sinar</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradien</string>\n    <string name=\"moire\">Maria</string>\n    <string name=\"autumn\">Musim gugur</string>\n    <string name=\"bone\">Tulang</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Musim dingin</string>\n    <string name=\"ocean\">Laut</string>\n    <string name=\"summer\">Musim panas</string>\n    <string name=\"spring\">Musim semi</string>\n    <string name=\"cool_variant\">Varian Keren</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Berwarna merah muda</string>\n    <string name=\"hot\">Panas</string>\n    <string name=\"parula\">Kata</string>\n    <string name=\"magma\">magma</string>\n    <string name=\"inferno\">Neraka</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Warga negara</string>\n    <string name=\"twilight\">Senja</string>\n    <string name=\"twilight_shifted\">Senja Bergeser</string>\n    <string name=\"auto_perspective\">Perspektif Otomatis</string>\n    <string name=\"deskew\">meja tulis</string>\n    <string name=\"allow_crop\">Izinkan pemangkasan</string>\n    <string name=\"crop_or_perspective\">Pangkas atau Perspektif</string>\n    <string name=\"absolute\">Mutlak</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Hijau Tua</string>\n    <string name=\"lens_correction\">Koreksi Lensa</string>\n    <string name=\"target_lens_profile\">File profil lensa target dalam format JSON</string>\n    <string name=\"download_ready_lens_profiles\">Unduh profil lensa siap pakai</string>\n    <string name=\"part_percents\">Bagian persen</string>\n    <string name=\"export_as_json\">Ekspor sebagai JSON</string>\n    <string name=\"export_as_json_sub\">Salin string dengan data palet sebagai representasi json</string>\n    <string name=\"seam_carving\">Ukiran Jahitan</string>\n    <string name=\"home_screen\">Layar Beranda</string>\n    <string name=\"lock_screen\">Layar Kunci</string>\n    <string name=\"built_in\">Bawaan</string>\n    <string name=\"wallpapers_export\">Ekspor Wallpaper</string>\n    <string name=\"refresh\">Menyegarkan</string>\n    <string name=\"wallpapers_export_sub\">Dapatkan wallpaper Beranda, Kunci, dan Bawaan terkini</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Izinkan akses ke semua file, ini diperlukan untuk mengambil wallpaper</string>\n    <string name=\"allow_read_media_images_for_wp\">Izin mengelola penyimpanan eksternal saja tidak cukup, Anda perlu mengizinkan akses ke gambar Anda, pastikan untuk memilih \\\"Izinkan semua\\\"</string>\n    <string name=\"add_preset_to_filename\">Tambahkan Preset Ke Nama File</string>\n    <string name=\"add_preset_to_filename_sub\">Menambahkan akhiran dengan preset yang dipilih ke nama file gambar</string>\n    <string name=\"add_image_scale_mode_to_filename\">Tambahkan Mode Skala Gambar Ke Nama File</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Menambahkan akhiran dengan mode skala gambar yang dipilih ke nama file gambar</string>\n    <string name=\"ascii_art\">Seni Ascii</string>\n    <string name=\"ascii_art_sub\">Ubah gambar menjadi teks ascii yang akan terlihat seperti gambar</string>\n    <string name=\"params\">Param</string>\n    <string name=\"invert_colors_ascii_sub\">Menerapkan filter negatif pada gambar untuk hasil yang lebih baik dalam beberapa kasus</string>\n    <string name=\"processing_screenshot\">Memproses tangkapan layar</string>\n    <string name=\"screenshot_not_captured_try_again\">Tangkapan layar tidak diambil, coba lagi</string>\n    <string name=\"skipped_saving\">Menyimpan dilewati</string>\n    <string name=\"skipped_saving_multiple\">%1$s file dilewati</string>\n    <string name=\"allow_skip_if_larger\">Izinkan Lewati Jika Lebih Besar</string>\n    <string name=\"allow_skip_if_larger_sub\">Beberapa alat akan diizinkan untuk melewatkan penyimpanan gambar jika ukuran file yang dihasilkan lebih besar dari aslinya</string>\n    <string name=\"qr_type_calendar_event\">Acara Kalender</string>\n    <string name=\"qr_type_contact_info\">Kontak</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Lokasi</string>\n    <string name=\"qr_type_phone\">Telepon</string>\n    <string name=\"qr_type_plain\">Teks</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Jaringan terbuka</string>\n    <string name=\"not_specified\">T/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telepon</string>\n    <string name=\"message\">Pesan</string>\n    <string name=\"address\">Alamat</string>\n    <string name=\"subject\">Subjek</string>\n    <string name=\"body\">Tubuh</string>\n    <string name=\"name\">Nama</string>\n    <string name=\"organization\">Organisasi</string>\n    <string name=\"title\">Judul</string>\n    <string name=\"phones\">Telepon</string>\n    <string name=\"emails\">email</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Alamat</string>\n    <string name=\"summary\">Ringkasan</string>\n    <string name=\"description\">Keterangan</string>\n    <string name=\"location\">Lokasi</string>\n    <string name=\"organizer\">Penyelenggara</string>\n    <string name=\"start_date\">Tanggal mulai</string>\n    <string name=\"end_date\">Tanggal akhir</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Lintang</string>\n    <string name=\"longitude\">Garis bujur</string>\n    <string name=\"create_barcode\">Buat Kode Batang</string>\n    <string name=\"edit_barcode\">Sunting Kode Batang</string>\n    <string name=\"wifi_configuration\">Konfigurasi Wi-Fi</string>\n    <string name=\"security\">Keamanan</string>\n    <string name=\"pick_contact\">Pilih kontak</string>\n    <string name=\"grant_contact_permission\">Berikan izin pada kontak di pengaturan untuk mengisi otomatis menggunakan kontak yang dipilih</string>\n    <string name=\"contact_info\">Informasi kontak</string>\n    <string name=\"first_name\">Nama depan</string>\n    <string name=\"middle_name\">Nama tengah</string>\n    <string name=\"last_name\">Nama belakang</string>\n    <string name=\"pronunciation\">Pengucapan</string>\n    <string name=\"add_phone\">Tambahkan telepon</string>\n    <string name=\"add_email\">Tambahkan email</string>\n    <string name=\"add_address\">Tambahkan alamat</string>\n    <string name=\"website\">Situs web</string>\n    <string name=\"add_website\">Tambahkan situs web</string>\n    <string name=\"formatted_name\">Nama yang diformat</string>\n    <string name=\"qr_code_top_image\">Gambar ini akan digunakan untuk ditempatkan di atas barcode</string>\n    <string name=\"code_customization\">Kustomisasi kode</string>\n    <string name=\"qr_logo_image\">Gambar ini akan digunakan sebagai logo di tengah kode QR</string>\n    <string name=\"logo\">logo</string>\n    <string name=\"logo_padding\">Bantalan logo</string>\n    <string name=\"logo_size\">Ukuran logo</string>\n    <string name=\"logo_corners\">Sudut logo</string>\n    <string name=\"fourth_eye\">Mata keempat</string>\n    <string name=\"fourth_eye_description\">Menambahkan simetri mata ke kode qr dengan menambahkan mata keempat di sudut ujung bawah</string>\n    <string name=\"pixel_shape\">Bentuk piksel</string>\n    <string name=\"frame_shape\">Bentuk bingkai</string>\n    <string name=\"ball_shape\">Bentuk bola</string>\n    <string name=\"error_correction_level\">Tingkat koreksi kesalahan</string>\n    <string name=\"dark_color\">Warna gelap</string>\n    <string name=\"light_color\">Warna terang</string>\n    <string name=\"hyper_os\">OS hiper</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS menyukai gaya</string>\n    <string name=\"mask_pattern\">Pola topeng</string>\n    <string name=\"code_may_be_not_scannable\">Kode ini mungkin tidak dapat dipindai, ubah parameter tampilan agar dapat dibaca oleh semua perangkat</string>\n    <string name=\"not_scannable\">Tidak dapat dipindai</string>\n    <string name=\"launcher_mode_sub\">Alat akan terlihat seperti peluncur aplikasi layar beranda agar lebih ringkas</string>\n    <string name=\"launcher_mode\">Mode Peluncur</string>\n    <string name=\"flood_fill_sub\">Mengisi area dengan kuas dan gaya yang dipilih</string>\n    <string name=\"flood_fill\">Isi Banjir</string>\n    <string name=\"spray\">Semprot</string>\n    <string name=\"spray_sub\">Menggambar jalur bergaya grafiti</string>\n    <string name=\"square_particles\">Partikel Persegi</string>\n    <string name=\"square_particles_sub\">Partikel semprotan akan berbentuk persegi, bukan lingkaran</string>\n    <string name=\"palette_tools\">Alat Palet</string>\n    <string name=\"palette_tools_sub\">Hasilkan palet dasar/bahan Anda dari gambar, atau impor/ekspor ke berbagai format palet berbeda</string>\n    <string name=\"edit_palette\">Sunting Palet</string>\n    <string name=\"edit_palette_sub\">Ekspor/impor palet dalam berbagai format</string>\n    <string name=\"color_name\">Nama warna</string>\n    <string name=\"palette_name\">Nama palet</string>\n    <string name=\"palette_format\">Format Palet</string>\n    <string name=\"export_palette_sub\">Ekspor palet yang dihasilkan ke format berbeda</string>\n    <string name=\"add_color_palette_sub\">Menambahkan warna baru ke palet saat ini</string>\n    <string name=\"palette_name_not_supported\">Format %1$s tidak mendukung pemberian nama palet</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Karena kebijakan Play Store, fitur ini tidak dapat disertakan dalam versi saat ini. Untuk mengakses fungsi ini, silakan unduh ImageToolbox dari sumber alternatif. Anda dapat menemukan build yang tersedia di GitHub di bawah.</string>\n    <string name=\"open_github_page\">Buka halaman Github</string>\n    <string name=\"overwrite_files_sub_short\">File asli akan diganti dengan yang baru alih-alih disimpan di folder yang dipilih</string>\n    <string name=\"hidden_watermark_text_detected\">Teks tanda air tersembunyi terdeteksi</string>\n    <string name=\"hidden_watermark_image_detected\">Terdeteksi gambar tanda air tersembunyi</string>\n    <string name=\"this_image_was_hidden\">Gambar ini disembunyikan</string>\n    <string name=\"generative_inpaint\">Lukisan Generatif</string>\n    <string name=\"generative_inpaint_sub\">Memungkinkan Anda menghapus objek dalam gambar menggunakan model AI, tanpa bergantung pada OpenCV. Untuk menggunakan fitur ini, aplikasi akan mengunduh model yang diperlukan (~200 MB) dari GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Memungkinkan Anda menghapus objek dalam gambar menggunakan model AI, tanpa bergantung pada OpenCV. Ini mungkin merupakan operasi yang berjalan lama</string>\n    <string name=\"error_level_analysis\">Analisis Tingkat Kesalahan</string>\n    <string name=\"luminance_gradient\">Gradien Pencahayaan</string>\n    <string name=\"average_distance\">Jarak Rata-rata</string>\n    <string name=\"copy_move_detection\">Salin Deteksi Pemindahan</string>\n    <string name=\"retain\">Mempertahankan</string>\n    <string name=\"coefficent\">Koefisien</string>\n    <string name=\"clipboard_data_is_too_large\">Data papan klip terlalu besar</string>\n    <string name=\"data_is_too_large_to_copy\">Data terlalu besar untuk disalin</string>\n    <string name=\"simple_weave_pixelization\">Pikselisasi Tenun Sederhana</string>\n    <string name=\"staggered_pixelization\">Pikselisasi Terhuyung</string>\n    <string name=\"cross_pixelization\">Pikselisasi Silang</string>\n    <string name=\"micro_macro_pixelization\">Pikselisasi Makro Mikro</string>\n    <string name=\"orbital_pixelization\">Pikselisasi Orbital</string>\n    <string name=\"vortex_pixelization\">Pikselisasi Pusaran</string>\n    <string name=\"pulse_grid_pixelization\">Pikselisasi Jaringan Pulsa</string>\n    <string name=\"nucleus_pixelization\">Pikselisasi Inti</string>\n    <string name=\"radial_weave_pixelization\">Pikselisasi Tenunan Radial</string>\n    <string name=\"cannot_open_uri\">Tidak dapat membuka uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Mode Hujan Salju</string>\n    <string name=\"enabled\">Diaktifkan</string>\n    <string name=\"border_frame\">Bingkai Perbatasan</string>\n    <string name=\"glitch_variant\">Varian Kesalahan</string>\n    <string name=\"channel_shift\">Pergeseran Saluran</string>\n    <string name=\"max_offset\">Offset Maks</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blokir Kesalahan</string>\n    <string name=\"block_size\">Ukuran Blok</string>\n    <string name=\"crt_curvature\">kelengkungan CRT</string>\n    <string name=\"curvature\">Lengkungan</string>\n    <string name=\"chroma\">Kroma</string>\n    <string name=\"pixel_melt\">Pencairan Piksel</string>\n    <string name=\"max_drop\">Penurunan Maks</string>\n    <string name=\"ai_tools\">Alat AI</string>\n    <string name=\"ai_tools_sub\">Berbagai alat untuk memproses gambar melalui model AI seperti penghilangan atau penghilangan artefak</string>\n    <string name=\"model_anime_undeint\">Kompresi, garis bergerigi</string>\n    <string name=\"model_broadcast\">Kartun, kompresi siaran</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Kompresi umum, kebisingan umum</string>\n    <string name=\"model_wb_denoise\">Suara kartun tak berwarna</string>\n    <string name=\"model_span_anime_pretrain\">Cepat, kompresi umum, kebisingan umum, animasi/komik/anime</string>\n    <string name=\"model_book_scan\">Pemindaian buku</string>\n    <string name=\"model_overexposure\">Koreksi eksposur</string>\n    <string name=\"model_fbcnn_color_fp16\">Terbaik dalam kompresi umum, gambar berwarna</string>\n    <string name=\"model_fbcnn_gray_fp16\">Terbaik dalam kompresi umum, gambar skala abu-abu</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Kompresi umum, gambar skala abu-abu, lebih kuat</string>\n    <string name=\"model_scunet_color_gan_fp16\">Kebisingan umum, gambar berwarna</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Kebisingan umum, gambar berwarna, detail lebih baik</string>\n    <string name=\"model_scunet_gray_15_fp16\">Kebisingan umum, gambar skala abu-abu</string>\n    <string name=\"model_scunet_gray_25_fp16\">Kebisingan umum, gambar skala abu-abu, lebih kuat</string>\n    <string name=\"model_scunet_gray_50_fp16\">Kebisingan umum, gambar skala abu-abu, paling kuat</string>\n    <string name=\"model_jpeg_destroyer\">Kompresi umum</string>\n    <string name=\"model_jaywreck\">Kompresi umum</string>\n    <string name=\"model_h264\">Teksturisasi, kompresi h264</string>\n    <string name=\"model_vhs\">Kompresi VHS</string>\n    <string name=\"model_cinepak\">Kompresi non-standar (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Kompresi bink, lebih baik pada geometri</string>\n    <string name=\"model_debink_v5\">Kompresi bink, lebih kuat</string>\n    <string name=\"model_debink_v6\">Kompresi bink, lembut, mempertahankan detail</string>\n    <string name=\"model_antialias\">Menghilangkan efek tangga, menghaluskan</string>\n    <string name=\"model_kdm_scans\">Seni/gambar yang dipindai, kompresi ringan, moire</string>\n    <string name=\"model_bandage\">Garis warna</string>\n    <string name=\"model_halftone\">Lambat, menghilangkan halftone</string>\n    <string name=\"model_colorizer\">Pewarna umum untuk gambar skala abu-abu/bw, untuk hasil lebih baik gunakan DDColor</string>\n    <string name=\"model_deedge\">Penghapusan tepi</string>\n    <string name=\"model_desharpen\">Menghilangkan penajaman yang berlebihan</string>\n    <string name=\"model_dither\">Lambat, ragu-ragu</string>\n    <string name=\"model_gainres\">Anti-aliasing, artefak umum, CGI</string>\n    <string name=\"model_kdm003_scans\">Pemrosesan pemindaian KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Model peningkatan gambar yang ringan</string>\n    <string name=\"model_bcgone_detailed_v2\">Penghapusan artefak kompresi</string>\n    <string name=\"model_bcgone_smooth\">Penghapusan artefak kompresi</string>\n    <string name=\"model_bandage_smooth\">Pelepasan perban dengan hasil yang halus</string>\n    <string name=\"model_bendel_halftone\">Pemrosesan pola halftone</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Penghapusan pola gentar V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Penghapusan artefak JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Peningkatan tekstur H.264</string>\n    <string name=\"model_vhs_sharpen\">Penajaman dan peningkatan VHS</string>\n    <string name=\"merging\">Penggabungan</string>\n    <string name=\"chunk_size\">Ukuran Potongan</string>\n    <string name=\"overlap_size\">Ukuran Tumpang Tindih</string>\n    <string name=\"note_chunk_info\">Gambar di atas %1$s px akan diiris dan diproses dalam beberapa bagian, campuran ini tumpang tindih untuk mencegah jahitan terlihat.</string>\n    <string name=\"large_chunk_warning\">Ukuran yang besar dapat menyebabkan ketidakstabilan pada perangkat kelas bawah</string>\n    <string name=\"select_one_to_start\">Pilih satu untuk memulai</string>\n    <string name=\"delete_model_sub\">Apakah Anda ingin menghapus model %1$s? Anda perlu mengunduhnya lagi</string>\n    <string name=\"confirm\">Mengonfirmasi</string>\n    <string name=\"models\">Model</string>\n    <string name=\"downloaded_models\">Model yang Diunduh</string>\n    <string name=\"available_models\">Model yang Tersedia</string>\n    <string name=\"preparing\">Mempersiapkan</string>\n    <string name=\"active_model\">Model aktif</string>\n    <string name=\"failed_to_open_session\">Gagal membuka sesi</string>\n    <string name=\"only_onnx_models\">Hanya model .onnx/.ort yang dapat diimpor</string>\n    <string name=\"import_model\">Model impor</string>\n    <string name=\"import_model_sub\">Impor model onnx khusus untuk digunakan lebih lanjut, hanya model onnx/ort yang diterima, mendukung hampir semua varian seperti esrgan</string>\n    <string name=\"imported_models\">Model yang Diimpor</string>\n    <string name=\"model_scunet_color_15_fp16\">Kebisingan umum, gambar berwarna</string>\n    <string name=\"model_scunet_color_25_fp16\">Kebisingan umum, gambar berwarna, lebih kuat</string>\n    <string name=\"model_scunet_color_50_fp16\">Kebisingan umum, gambar berwarna, paling kuat</string>\n    <string name=\"model_artifacts_dithering_alsa\">Mengurangi artefak yang ragu-ragu dan garis warna, meningkatkan gradien halus dan area warna datar.</string>\n    <string name=\"model_nmkd_brighten_redux\">Meningkatkan kecerahan dan kontras gambar dengan sorotan seimbang sekaligus mempertahankan warna alami.</string>\n    <string name=\"model_nmkd_brighten\">Mencerahkan gambar gelap sekaligus menjaga detail dan menghindari pencahayaan berlebih.</string>\n    <string name=\"model_nmkd_detoon\">Menghilangkan toning warna yang berlebihan dan mengembalikan keseimbangan warna yang lebih netral dan alami.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Menerapkan noise toning berbasis Poisson dengan penekanan pada pelestarian detail dan tekstur halus.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Menerapkan toning noise Poisson yang lembut untuk hasil visual yang lebih halus dan tidak terlalu agresif.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Nada noise seragam berfokus pada pelestarian detail dan kejernihan gambar.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Nada kebisingan seragam yang lembut untuk tekstur halus dan penampilan halus.</string>\n    <string name=\"model_repainter\">Memperbaiki area yang rusak atau tidak rata dengan mengecat ulang artefak dan meningkatkan konsistensi gambar.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Model pelepasan pita ringan yang menghilangkan pita warna dengan biaya kinerja minimal.</string>\n    <string name=\"model_jpeg_0_20\">Mengoptimalkan gambar dengan artefak kompresi sangat tinggi (kualitas 0-20%) untuk meningkatkan kejernihan.</string>\n    <string name=\"model_jpeg_20_40\">Meningkatkan gambar dengan artefak kompresi tinggi (kualitas 20-40%), memulihkan detail dan mengurangi noise.</string>\n    <string name=\"model_jpeg_40_60\">Meningkatkan gambar dengan kompresi sedang (kualitas 40-60%), menyeimbangkan ketajaman dan kehalusan.</string>\n    <string name=\"model_jpeg_60_80\">Memperbaiki gambar dengan kompresi ringan (kualitas 60-80%) untuk menyempurnakan detail dan tekstur halus.</string>\n    <string name=\"model_jpeg_80_100\">Sedikit menyempurnakan gambar yang nyaris lossless (kualitas 80-100%) dengan tetap menjaga tampilan dan detail alami.</string>\n    <string name=\"model_spongecolor_lite\">Pewarnaan sederhana dan cepat, kartun, tidak ideal</string>\n    <string name=\"model_deblr\">Sedikit mengurangi keburaman gambar, meningkatkan ketajaman tanpa menimbulkan artefak.</string>\n    <string name=\"processing_channel\">Operasi yang berjalan lama</string>\n    <string name=\"processing_image\">Memproses gambar</string>\n    <string name=\"processing\">Pengolahan</string>\n    <string name=\"model_artifacts_jpg_0_20\">Menghapus artefak kompresi JPEG yang berat pada gambar berkualitas sangat rendah (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Mengurangi artefak JPEG yang kuat pada gambar yang sangat terkompresi (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Membersihkan artefak JPEG moderat sambil mempertahankan detail gambar (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Memperbaiki artefak JPEG ringan dalam gambar berkualitas cukup tinggi (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Secara halus mengurangi artefak JPEG kecil pada gambar yang hampir tidak ada kerugian (80-100%).</string>\n    <string name=\"model_redetail_v2\">Meningkatkan detail dan tekstur halus, meningkatkan ketajaman yang dirasakan tanpa artefak berat.</string>\n    <string name=\"processing_finished\">Pemrosesan selesai</string>\n    <string name=\"processing_failed\">Pemrosesan gagal</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Meningkatkan tekstur dan detail kulit sekaligus menjaga tampilan alami, dioptimalkan untuk kecepatan.</string>\n    <string name=\"model_sbdv_dejpeg\">Menghapus artefak kompresi JPEG dan mengembalikan kualitas gambar untuk foto terkompresi.</string>\n    <string name=\"model_iso_denoise_v1\">Mengurangi noise ISO pada foto yang diambil dalam kondisi cahaya redup, menjaga detailnya.</string>\n    <string name=\"model_dejumbo\">Memperbaiki sorotan yang terlalu terang atau “jumbo” dan mengembalikan keseimbangan warna yang lebih baik.</string>\n    <string name=\"model_ddcolor_tiny\">Model pewarnaan yang ringan dan cepat yang menambahkan warna alami pada gambar skala abu-abu.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Tolak kebisingan</string>\n    <string name=\"type_colorize\">Mewarnai</string>\n    <string name=\"type_artifacts\">Artefak</string>\n    <string name=\"type_enhance\">Meningkatkan</string>\n    <string name=\"type_anime\">anime</string>\n    <string name=\"type_scans\">Pemindaian</string>\n    <string name=\"type_upscale\">Kelas atas</string>\n    <string name=\"model_realesrgan_x4v3\">Peningkatan X4 untuk gambar umum; model kecil yang menggunakan lebih sedikit GPU dan waktu, dengan deblur dan denoise sedang.</string>\n    <string name=\"model_realesrgan_x2plus\">Peningkatan X2 untuk gambar umum, menjaga tekstur dan detail alami.</string>\n    <string name=\"model_realesrgan_x4plus\">Peningkatan X4 untuk gambar umum dengan tekstur yang ditingkatkan dan hasil yang realistis.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Peningkatan X4 dioptimalkan untuk gambar anime; 6 blok RRDB untuk garis dan detail yang lebih tajam.</string>\n    <string name=\"model_realesrnet_x4plus\">Peningkatan X4 dengan kerugian MSE, memberikan hasil yang lebih halus dan mengurangi artefak untuk gambar umum.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler dioptimalkan untuk gambar anime; Varian 4B32F dengan detail lebih tajam dan garis halus.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Model X4 UltraSharp V2 untuk gambar umum; menekankan ketajaman dan kejelasan.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; lebih cepat dan lebih kecil, menjaga detail sambil menggunakan lebih sedikit memori GPU.</string>\n    <string name=\"model_rmbg_1_4\">Model ringan untuk penghapusan latar belakang dengan cepat. Performa dan akurasi seimbang. Bekerja dengan potret, objek, dan pemandangan. Direkomendasikan untuk sebagian besar kasus penggunaan.</string>\n    <string name=\"type_removebg\">Hapus BG</string>\n    <string name=\"horizontal_border_thickness\">Ketebalan Perbatasan Horisontal</string>\n    <string name=\"vertical_border_thickness\">Ketebalan Batas Vertikal</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s warna</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Model saat ini tidak mendukung chunking, gambar akan diproses dalam dimensi aslinya, hal ini dapat menyebabkan konsumsi memori yang tinggi dan masalah pada perangkat kelas bawah</string>\n    <string name=\"chunking_disabled\">Chunking dinonaktifkan, gambar akan diproses dalam dimensi aslinya, hal ini dapat menyebabkan konsumsi memori yang tinggi dan masalah pada perangkat kelas bawah tetapi dapat memberikan hasil inferensi yang lebih baik</string>\n    <string name=\"chunking\">Potongan</string>\n    <string name=\"model_u2net\">Model segmentasi gambar dengan akurasi tinggi untuk penghapusan latar belakang</string>\n    <string name=\"model_u2netp\">Versi ringan U2Net untuk menghapus latar belakang lebih cepat dengan penggunaan memori lebih kecil.</string>\n    <string name=\"model_ddcolor\">Model DDColor penuh menghadirkan pewarnaan berkualitas tinggi untuk gambar umum dengan artefak minimal. Pilihan terbaik dari semua model pewarnaan.</string>\n    <string name=\"model_ddcolor_artistic\">Kumpulan data artistik pribadi dan terlatih DDColor; menghasilkan hasil pewarnaan yang beragam dan artistik dengan lebih sedikit artefak warna yang tidak realistis.</string>\n    <string name=\"model_birefnet\">Model BiRefNet ringan berdasarkan Swin Transformer untuk menghilangkan latar belakang secara akurat.</string>\n    <string name=\"model_inspyrenet\">Penghapusan latar belakang berkualitas tinggi dengan tepi tajam dan pelestarian detail yang sangat baik, terutama pada objek kompleks dan latar belakang rumit.</string>\n    <string name=\"model_isnet\">Model penghapusan latar belakang yang menghasilkan topeng akurat dengan tepi halus, cocok untuk objek umum dan pelestarian detail moderat.</string>\n    <string name=\"model_already_downloaded\">Model sudah diunduh</string>\n    <string name=\"model_successfully_imported\">Model berhasil diimpor</string>\n    <string name=\"type\">Jenis</string>\n    <string name=\"keyword\">Kata kunci</string>\n    <string name=\"very_fast\">Sangat cepat</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Lambat</string>\n    <string name=\"very_slow\">Sangat Lambat</string>\n    <string name=\"compute_percents\">Hitung Persen</string>\n    <string name=\"minimum_value_is\">Nilai minimumnya adalah %1$s</string>\n    <string name=\"warp_sub\">Distorsi gambar dengan menggambar dengan jari</string>\n    <string name=\"warp\">Melengkung</string>\n    <string name=\"hardness\">Kekerasan</string>\n    <string name=\"warp_mode\">Mode Warp</string>\n    <string name=\"warp_mode_move\">Bergerak</string>\n    <string name=\"warp_mode_grow\">Tumbuh</string>\n    <string name=\"warp_mode_shrink\">Menyusut</string>\n    <string name=\"warp_mode_swirl_cw\">Putar CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Putar CCW</string>\n    <string name=\"fade_strength\">Kekuatan Pudar</string>\n    <string name=\"top_drop\">Penurunan Teratas</string>\n    <string name=\"bottom_drop\">Penurunan Bawah</string>\n    <string name=\"start_drop\">Mulai Jatuhkan</string>\n    <string name=\"end_drop\">Akhir Penurunan</string>\n    <string name=\"downloading\">Mengunduh</string>\n    <string name=\"smooth_shapes\">Bentuk Halus</string>\n    <string name=\"smooth_shapes_sub\">Gunakan superelips daripada persegi panjang bulat standar untuk mendapatkan bentuk yang lebih halus dan alami</string>\n    <string name=\"shape_type\">Tipe Bentuk</string>\n    <string name=\"cut\">Memotong</string>\n    <string name=\"rounded\">Bulat</string>\n    <string name=\"smooth\">Mulus</string>\n    <string name=\"cut_shapes_sub\">Tepi tajam tanpa pembulatan</string>\n    <string name=\"rounded_shapes_sub\">Sudut membulat klasik</string>\n    <string name=\"shapes_type\">Tipe Bentuk</string>\n    <string name=\"corners_size\">Ukuran Sudut</string>\n    <string name=\"squircle\">tupai</string>\n    <string name=\"squircle_shapes_sub\">Elemen UI bulat yang elegan</string>\n    <string name=\"filename_format\">Format Nama File</string>\n    <string name=\"prefix_pattern_description\">Teks khusus ditempatkan di awal nama file, cocok untuk nama proyek, merek, atau tag pribadi.</string>\n    <string name=\"original_filename_pattern_description\">Menggunakan nama file asli tanpa ekstensi, membantu Anda menjaga identifikasi sumber tetap utuh.</string>\n    <string name=\"width_pattern_description\">Lebar gambar dalam piksel, berguna untuk melacak perubahan resolusi atau menskalakan hasil.</string>\n    <string name=\"height_pattern_description\">Tinggi gambar dalam piksel, berguna saat bekerja dengan rasio aspek atau ekspor.</string>\n    <string name=\"random_numbers_pattern_description\">Menghasilkan digit acak untuk menjamin nama file unik; tambahkan lebih banyak digit untuk keamanan ekstra terhadap duplikat.</string>\n    <string name=\"sequence_number_pattern_description\">Penghitung penambahan otomatis untuk ekspor batch, ideal saat menyimpan banyak gambar dalam satu sesi.</string>\n    <string name=\"preset_info_pattern_description\">Menyisipkan nama preset yang diterapkan ke dalam nama file sehingga Anda dapat dengan mudah mengingat bagaimana gambar diproses.</string>\n    <string name=\"scale_mode_pattern_description\">Menampilkan mode penskalaan gambar yang digunakan selama pemrosesan, membantu membedakan gambar yang diubah ukurannya, dipotong, atau dipasang.</string>\n    <string name=\"suffix_pattern_description\">Teks khusus ditempatkan di akhir nama file, berguna untuk pembuatan versi seperti _v2, _edited, atau _final.</string>\n    <string name=\"extension_pattern_description\">Ekstensi file (png, jpg, webp, dll.), secara otomatis cocok dengan format penyimpanan sebenarnya.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Stempel waktu yang dapat disesuaikan yang memungkinkan Anda menentukan format Anda sendiri berdasarkan spesifikasi java untuk penyortiran yang sempurna.</string>\n    <string name=\"fling_type\">Tipe Lemparan</string>\n    <string name=\"android_native\">Android Asli</string>\n    <string name=\"ios_style\">Gaya iOS</string>\n    <string name=\"smooth_curve\">Kurva Halus</string>\n    <string name=\"quick_stop\">Berhenti Cepat</string>\n    <string name=\"bouncy\">Goyang</string>\n    <string name=\"floaty\">Ringan</string>\n    <string name=\"snappy\">Tajam</string>\n    <string name=\"ultra_smooth\">Sangat Halus</string>\n    <string name=\"adaptive\">adaptif</string>\n    <string name=\"accessibility_aware\">Sadar Aksesibilitas</string>\n    <string name=\"reduced_motion\">Gerakan Berkurang</string>\n    <string name=\"android_native_sub\">Fisika gulir Android asli</string>\n    <string name=\"smooth_sub\">Pengguliran yang seimbang dan mulus untuk penggunaan umum</string>\n    <string name=\"ios_style_sub\">Perilaku gulir mirip iOS dengan gesekan lebih tinggi</string>\n    <string name=\"smooth_curve_sub\">Kurva spline yang unik untuk nuansa gulir yang berbeda</string>\n    <string name=\"quick_stop_sub\">Pengguliran yang tepat dengan penghentian cepat</string>\n    <string name=\"bouncy_sub\">Gulir goyang yang menyenangkan dan responsif</string>\n    <string name=\"floaty_sub\">Gulungan yang panjang dan meluncur untuk penelusuran konten</string>\n    <string name=\"snappy_sub\">Pengguliran cepat dan responsif untuk UI interaktif</string>\n    <string name=\"ultra_smooth_sub\">Pengguliran mulus premium dengan momentum yang diperpanjang</string>\n    <string name=\"adaptive_sub\">Menyesuaikan fisika berdasarkan kecepatan lemparan</string>\n    <string name=\"accessibility_aware_sub\">Menghargai pengaturan aksesibilitas sistem</string>\n    <string name=\"reduced_motion_sub\">Gerakan minimal untuk kebutuhan aksesibilitas</string>\n    <string name=\"primary_lines\">Jalur Utama</string>\n    <string name=\"primary_lines_sub\">Menambahkan garis tebal setiap baris kelima</string>\n    <string name=\"fill_color\">Isi Warna</string>\n    <string name=\"hidden_tools\">Alat Tersembunyi</string>\n    <string name=\"hidden_for_share\">Alat Tersembunyi Untuk Dibagikan</string>\n    <string name=\"color_library\">Perpustakaan Warna</string>\n    <string name=\"color_library_sub\">Jelajahi banyak koleksi warna</string>\n    <string name=\"model_fatality_deblur\">Mempertajam dan menghilangkan keburaman pada gambar sambil mempertahankan detail alami, ideal untuk memperbaiki foto yang tidak fokus.</string>\n    <string name=\"model_unresize_v3\">Secara cerdas mengembalikan gambar yang telah diubah ukurannya sebelumnya, memulihkan detail dan tekstur yang hilang.</string>\n    <string name=\"model_liveaction_v1_span\">Dioptimalkan untuk konten aksi langsung, mengurangi artefak kompresi, dan menyempurnakan detail halus dalam bingkai film/acara TV.</string>\n    <string name=\"model_vhs2hd_realplksr\">Mengonversi rekaman berkualitas VHS ke HD, menghilangkan noise rekaman dan meningkatkan resolusi sekaligus mempertahankan nuansa vintage.</string>\n    <string name=\"model_text2hd_v1\">Khusus untuk gambar dan tangkapan layar yang banyak teks, mempertajam karakter dan meningkatkan keterbacaan.</string>\n    <string name=\"model_frankendata_pretrainer\">Peningkatan tingkat lanjut dilatih pada beragam kumpulan data, sangat baik untuk penyempurnaan foto tujuan umum.</string>\n    <string name=\"model_realwebphoto_v2\">Dioptimalkan untuk foto terkompresi web, menghilangkan artefak JPEG dan mengembalikan tampilan alami.</string>\n    <string name=\"model_realwebphoto_v4\">Versi yang ditingkatkan untuk foto web dengan pelestarian tekstur dan pengurangan artefak yang lebih baik.</string>\n    <string name=\"model_dat_2x\">Peningkatan 2x dengan teknologi Dual Aggregation Transformer, menjaga ketajaman dan detail alami.</string>\n    <string name=\"model_dat_3x\">Peningkatan 3x menggunakan arsitektur transformator canggih, ideal untuk kebutuhan pembesaran sedang.</string>\n    <string name=\"model_dat_4x\">4x peningkatan kualitas tinggi dengan jaringan transformator canggih, mempertahankan detail halus pada skala yang lebih besar.</string>\n    <string name=\"model_nafnet_deblurring\">Menghilangkan keburaman/noise dan guncangan pada foto. Tujuan umum tetapi terbaik untuk foto.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Mengembalikan gambar berkualitas rendah menggunakan transformator Swin2SR, dioptimalkan untuk degradasi BSRGAN. Sangat bagus untuk memperbaiki artefak kompresi berat dan meningkatkan detail pada skala 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Peningkatan 4x dengan transformator SwinIR yang dilatih tentang degradasi BSRGAN. Menggunakan GAN untuk tekstur yang lebih tajam dan detail yang lebih alami dalam foto dan pemandangan yang kompleks.</string>\n    <string name=\"path\">Jalur</string>\n    <string name=\"merge_pdf\">Gabungkan PDF</string>\n    <string name=\"merge_pdf_sub\">Gabungkan beberapa file PDF menjadi satu dokumen</string>\n    <string name=\"files_order\">Urutan File</string>\n    <string name=\"pages_short\">hal.</string>\n    <string name=\"split_pdf\">Pisahkan PDF</string>\n    <string name=\"split_pdf_sub\">Ekstrak halaman tertentu dari dokumen PDF</string>\n    <string name=\"rotate_pdf\">Putar PDF</string>\n    <string name=\"rotate_pdf_sub\">Perbaiki orientasi halaman secara permanen</string>\n    <string name=\"pages\">Halaman</string>\n    <string name=\"rearrange_pdf\">Susun ulang PDF</string>\n    <string name=\"rearrange_pdf_sub\">Seret dan lepas halaman untuk menyusun ulang</string>\n    <string name=\"hold_drag_drop\">Tahan &amp;amp; Seret halaman</string>\n    <string name=\"page_numbers\">Nomor Halaman</string>\n    <string name=\"page_numbers_sub\">Tambahkan penomoran ke dokumen Anda secara otomatis</string>\n    <string name=\"label_format\">Format Label</string>\n    <string name=\"pdf_to_text\">PDF ke Teks (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Ekstrak teks biasa dari dokumen PDF Anda</string>\n    <string name=\"watermark_pdf_sub\">Hamparkan teks khusus untuk pencitraan merek atau keamanan</string>\n    <string name=\"signature\">Tanda tangan</string>\n    <string name=\"signature_sub\">Tambahkan tanda tangan elektronik Anda ke dokumen apa pun</string>\n    <string name=\"will_be_for_signature\">Ini akan digunakan sebagai tanda tangan</string>\n    <string name=\"unlock_pdf\">Buka kunci PDF</string>\n    <string name=\"unlock_pdf_sub\">Hapus kata sandi dari file Anda yang dilindungi</string>\n    <string name=\"protect_pdf\">Lindungi PDF</string>\n    <string name=\"protect_pdf_sub\">Amankan dokumen Anda dengan enkripsi yang kuat</string>\n    <string name=\"success\">Kesuksesan</string>\n    <string name=\"pdf_unlocked\">PDF tidak terkunci, Anda dapat menyimpan atau membagikannya</string>\n    <string name=\"repair_pdf\">Perbaiki PDF</string>\n    <string name=\"repair_pdf_sub\">Mencoba memperbaiki dokumen yang rusak atau tidak dapat dibaca</string>\n    <string name=\"grayscale\">Skala abu-abu</string>\n    <string name=\"grayscale_pdf_sub\">Ubah semua gambar yang disematkan pada dokumen menjadi skala abu-abu</string>\n    <string name=\"compress_pdf\">Kompres PDF</string>\n    <string name=\"compress_pdf_sub\">Optimalkan ukuran file dokumen Anda agar lebih mudah dibagikan</string>\n    <string name=\"repair_info\">ImageToolbox membangun kembali tabel referensi silang internal dan membuat ulang struktur file dari awal. Ini dapat memulihkan akses ke banyak file yang \\\\\"tidak dapat dibuka\\\\\"</string>\n    <string name=\"grayscale_info\">Alat ini mengubah semua gambar dokumen menjadi skala abu-abu. Terbaik untuk mencetak dan mengurangi ukuran file</string>\n    <string name=\"metadata\">Metadata</string>\n    <string name=\"metadata_pdf_sub\">Edit properti dokumen untuk privasi yang lebih baik</string>\n    <string name=\"tags\">Tag</string>\n    <string name=\"producer\">Produsen</string>\n    <string name=\"author\">Pengarang</string>\n    <string name=\"keywords\">Kata kunci</string>\n    <string name=\"creator\">Pencipta</string>\n    <string name=\"privacy_deep_clean\">Privasi Sangat Bersih</string>\n    <string name=\"privacy_deep_clean_sub\">Hapus semua metadata yang tersedia untuk dokumen ini</string>\n    <string name=\"page\">Halaman</string>\n    <string name=\"deep_ocr\">OCR yang dalam</string>\n    <string name=\"deep_ocr_sub\">Ekstrak teks dari dokumen dan simpan dalam satu file teks menggunakan mesin Tesseract</string>\n    <string name=\"cant_remove_all\">Tidak dapat menghapus semua halaman</string>\n    <string name=\"remove_pages_pdf\">Hapus halaman PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Hapus halaman tertentu dari dokumen PDF</string>\n    <string name=\"tap_to_remove\">Ketuk Untuk Menghapus</string>\n    <string name=\"manually\">Secara manual</string>\n    <string name=\"crop_pdf\">Pangkas PDF</string>\n    <string name=\"crop_pdf_sub\">Pangkas halaman dokumen hingga batas apa pun</string>\n    <string name=\"flatten_pdf\">Ratakan PDF</string>\n    <string name=\"flatten_pdf_sub\">Jadikan PDF tidak dapat dimodifikasi dengan melakukan raster pada halaman dokumen</string>\n    <string name=\"camera_failed_to_open\">Tidak dapat memulai kamera. Silakan periksa izin dan pastikan itu tidak digunakan oleh aplikasi lain.</string>\n    <string name=\"extract_images\">Ekstrak Gambar</string>\n    <string name=\"extract_images_sub\">Ekstrak gambar yang tertanam dalam PDF pada resolusi aslinya</string>\n    <string name=\"pdf_no_embedded\">File PDF ini tidak berisi gambar apa pun yang disematkan</string>\n    <string name=\"extract_images_info\">Alat ini memindai setiap halaman dan memulihkan gambar sumber berkualitas penuh — sempurna untuk menyimpan dokumen asli</string>\n    <string name=\"draw_signature\">Gambar Tanda Tangan</string>\n    <string name=\"pen_params\">Param Pena</string>\n    <string name=\"draw_signature_sub\">Gunakan tanda tangan sendiri sebagai gambar untuk ditempatkan pada dokumen</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Pisahkan dokumen dengan interval tertentu dan kemas dokumen baru ke dalam arsip zip</string>\n    <string name=\"interval\">Selang</string>\n    <string name=\"print_pdf\">Cetak PDF</string>\n    <string name=\"print_pdf_sub\">Siapkan dokumen untuk dicetak dengan ukuran halaman khusus</string>\n    <string name=\"pages_per_sheet\">Halaman Per Lembar</string>\n    <string name=\"orientation\">Orientasi</string>\n    <string name=\"page_size\">Ukuran Halaman</string>\n    <string name=\"margin\">Batas</string>\n    <string name=\"bloom\">Bunga</string>\n    <string name=\"soft_knee\">Lutut Lembut</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Dioptimalkan untuk anime dan kartun. Peningkatan cepat dengan peningkatan warna alami dan lebih sedikit artefak</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 menyukai gaya</string>\n    <string name=\"calculate_hint\">Masukkan simbol matematika dasar di sini untuk menghitung nilai yang diinginkan (misalnya (5+5)*10)</string>\n    <string name=\"math_expression\">Ekspresi matematika</string>\n    <string name=\"pick_up_to_n_collage_images\">Ambil hingga %1$s gambar</string>\n    <string name=\"keep_date_time\">Pertahankan Tanggal Waktu</string>\n    <string name=\"keep_date_time_sub\">Selalu pertahankan tag Exif yang terkait dengan tanggal dan waktu, bekerja secara independen dari opsi Keep Exic</string>\n    <string name=\"background_color_for_alpha_formats\">Warna Latar Belakang Untuk Format Alfa</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Menambahkan kemampuan untuk mengatur warna latar belakang untuk setiap format gambar dengan dukungan alfa, jika dinonaktifkan, ini hanya tersedia untuk format non alfa</string>\n    <string name=\"open_markup_project\">Buka proyek</string>\n    <string name=\"open_markup_project_sub\">Lanjutkan mengedit proyek Image Toolbox yang disimpan sebelumnya</string>\n    <string name=\"markup_project_open_failed\">Tidak dapat membuka proyek Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Proyek Image Toolbox tidak memiliki data proyek</string>\n    <string name=\"markup_project_corrupted\">Proyek Image Toolbox rusak</string>\n    <string name=\"unsupported_markup_project_version\">Versi proyek Image Toolbox yang tidak didukung: %1$d</string>\n    <string name=\"save_markup_project\">Simpan proyek</string>\n    <string name=\"save_markup_project_sub\">Simpan lapisan, latar belakang, dan riwayat edit dalam file proyek yang dapat diedit</string>\n    <string name=\"failed_to_open\">Gagal dibuka</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Tulis Ke PDF yang Dapat Dicari</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Kenali teks dari kumpulan gambar dan simpan PDF yang dapat dicari dengan gambar dan lapisan teks yang dapat dipilih</string>\n    <string name=\"layer_alpha\">Lapisan alfa</string>\n    <string name=\"horizontal_flip\">Balik Horisontal</string>\n    <string name=\"vertical_flip\">Balik Vertikal</string>\n    <string name=\"lock\">Kunci</string>\n    <string name=\"add_shadow\">Tambahkan Bayangan</string>\n    <string name=\"shadow_color\">Warna Bayangan</string>\n    <string name=\"text_geometry\">Geometri Teks</string>\n    <string name=\"text_geometry_sub\">Regangkan atau miringkan teks untuk gaya yang lebih tajam</string>\n    <string name=\"scale_x\">Skala X</string>\n    <string name=\"skew_x\">miring X</string>\n    <string name=\"remove_annotations\">Hapus anotasi</string>\n    <string name=\"remove_annotations_sub\">Hapus jenis anotasi yang dipilih seperti tautan, komentar, sorotan, bentuk, atau bidang formulir dari halaman PDF</string>\n    <string name=\"annotation_link\">Hyperlink</string>\n    <string name=\"annotation_file_attachment\">Lampiran Berkas</string>\n    <string name=\"annotation_line\">Garis</string>\n    <string name=\"annotation_popup\">Popup</string>\n    <string name=\"annotation_stamp\">Perangko</string>\n    <string name=\"annotation_shapes\">Bentuk</string>\n    <string name=\"annotation_text\">Catatan Teks</string>\n    <string name=\"annotation_text_markup\">Markup Teks</string>\n    <string name=\"annotation_widget\">Bidang Formulir</string>\n    <string name=\"annotation_markup\">Menandai</string>\n    <string name=\"annotation_unknown\">Tidak dikenal</string>\n    <string name=\"annotations\">Anotasi</string>\n    <string name=\"ungroup\">Pisahkan</string>\n    <string name=\"add_shadow_sub\">Tambahkan bayangan buram di belakang lapisan dengan warna dan offset yang dapat dikonfigurasi</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-it/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"smth_went_wrong\">Qualcosa non ha funzionato: %1$s</string>\n    <string name=\"size\">Dimensione %1$s</string>\n    <string name=\"loading\">Caricamento…</string>\n    <string name=\"image_too_large_preview\">L\\'immagine è troppo grande per mostrarne un\\'anteprima, ma verrà tentato comunque il salvataggio</string>\n    <string name=\"pick_image\">Scegli un\\'immagine per iniziare</string>\n    <string name=\"width\">Larghezza %1$s</string>\n    <string name=\"height\">Altezza %1$s</string>\n    <string name=\"quality\">Qualità</string>\n    <string name=\"extension\">Estensione</string>\n    <string name=\"resize_type\">Tipo di ridimensionamento</string>\n    <string name=\"explicit\">Specifico</string>\n    <string name=\"flexible\">Flessibile</string>\n    <string name=\"pick_image_alt\">Scegli un\\'immagine</string>\n    <string name=\"app_closing_sub\">Vuoi davvero chiudere l\\'applicazione?</string>\n    <string name=\"app_closing\">Chiusura dell\\'applicazione</string>\n    <string name=\"stay\">Rimani</string>\n    <string name=\"close\">Chiudi</string>\n    <string name=\"reset_image\">Reimposta immagine</string>\n    <string name=\"reset_image_sub\">Le modifiche all\\'immagine verranno reimpostate ai valori iniziali.</string>\n    <string name=\"values_reset\">Valori correttamente reimpostati</string>\n    <string name=\"reset\">Reimposta</string>\n    <string name=\"something_went_wrong\">Qualcosa non ha funzionato</string>\n    <string name=\"restart_app\">Riavvia app</string>\n    <string name=\"copied\">Copia negli appunti</string>\n    <string name=\"exception\">Eccezione</string>\n    <string name=\"edit_exif\">Modifica EXIF</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">Nessun EXIF trovato</string>\n    <string name=\"add_tag\">Aggiungi tag</string>\n    <string name=\"save\">Salva</string>\n    <string name=\"clear\">Pulisci</string>\n    <string name=\"clear_exif\">Cancella EXIF</string>\n    <string name=\"cancel\">Cancella</string>\n    <string name=\"clear_exif_sub\">Tutti i dati EXIF dell\\'immagine verranno rimossi. Questa azione è irreversibile!</string>\n    <string name=\"presets\">Preconfigurazioni</string>\n    <string name=\"crop\">Ritaglia</string>\n    <string name=\"image_not_saved\">Salvataggio</string>\n    <string name=\"image_not_saved_sub\">Tutte le modifiche andranno perse se abbandoni adesso.</string>\n    <string name=\"check_source_code\">Consulta il codice sorgente</string>\n    <string name=\"check_source_code_sub\">Ricevi gli ultimi aggiornamenti, discuti dei problemi e altro.</string>\n    <string name=\"single_edit\">Ridimensionamento Singolo</string>\n    <string name=\"single_edit_sub\">Modifica e ridimensiona una singola immagine.</string>\n    <string name=\"pick_color\">Selettore colore</string>\n    <string name=\"pick_color_sub\">Estrai, copia o condividi un colore da un\\'immagine.</string>\n    <string name=\"image\">Immagine</string>\n    <string name=\"color\">Colore</string>\n    <string name=\"color_copied\">Colore copiato</string>\n    <string name=\"crop_sub\">Ritaglia un\\'immagine</string>\n    <string name=\"version\">Versione</string>\n    <string name=\"keep_exif\">Mantieni EXIF</string>\n    <string name=\"images\">Immagini: %d</string>\n    <string name=\"change_preview\">Cambia anteprima</string>\n    <string name=\"remove\">Rimuovi</string>\n    <string name=\"palette_sub\">Genera una palette di colori da un\\'immagine.</string>\n    <string name=\"generate_palette\">Genera Palette</string>\n    <string name=\"palette\">Palette</string>\n    <string name=\"update\">Aggiorna</string>\n    <string name=\"new_version\">Nuova versione %1$s</string>\n    <string name=\"unsupported_type\">Tipo non supportato: %1$s</string>\n    <string name=\"no_palette\">Impossibile generare una palette per l\\'immagine specificata.</string>\n    <string name=\"original\">Originale</string>\n    <string name=\"folder\">Cartella di output</string>\n    <string name=\"def\">Predefinita</string>\n    <string name=\"custom\">Personalizzata</string>\n    <string name=\"unspecified\">Non specificata</string>\n    <string name=\"device_storage\">Memoria del telefono</string>\n    <string name=\"by_bytes_resize\">Ridimensiona per Peso</string>\n    <string name=\"max_bytes\">Dimensione massima in KB</string>\n    <string name=\"by_bytes_resize_sub\">Ridimensiona un\\'immagine in base alla grandezza specificata in KB.</string>\n    <string name=\"compare\">Confrontare</string>\n    <string name=\"compare_sub\">Confronto tra due immagini date</string>\n    <string name=\"pick_images\">Scegli un\\'immagine</string>\n    <string name=\"pick_two_images\">Scegli un\\'immagine per iniziare</string>\n    <string name=\"settings\">Impostazioni</string>\n    <string name=\"night_mode\">Modalità notturna</string>\n    <string name=\"dark\">Oscuro</string>\n    <string name=\"light\">Leggero</string>\n    <string name=\"system\">Sistema</string>\n    <string name=\"allow_image_monet\">Consenti monet immagine</string>\n    <string name=\"language\">Lingua</string>\n    <string name=\"dynamic_colors\">Colori dinamici</string>\n    <string name=\"customization\">Personalizzazione</string>\n    <string name=\"allow_image_monet_sub\">Se abilitato, quando scegli un\\'immagine da modificare, i colori dell\\'app verranno adottati per questa immagine</string>\n    <string name=\"amoled_mode\">Modalità Amoled</string>\n    <string name=\"amoled_mode_sub\">Se abilitato, il colore delle superfici verrà impostato su buio assoluto in modalità notturna</string>\n    <string name=\"color_red\">Rosso</string>\n    <string name=\"clipboard_paste_invalid_empty\">Niente da incollare</string>\n    <string name=\"color_scheme\">Schema di colore</string>\n    <string name=\"color_blue\">Blu</string>\n    <string name=\"color_green\">Verde</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Incolla un codice aRGB valido</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Impossibile modificare la combinazione di colori dell\\'app mentre i colori dinamici sono attivi</string>\n    <string name=\"pick_accent_color\">Il tema dell\\'app sarà basato sul colore selezionato</string>\n    <string name=\"issue_tracker\">Segnalazioni bug</string>\n    <string name=\"help_translate\">Aiuta a tradurre</string>\n    <string name=\"no_updates\">Nessun aggiornamento trovato</string>\n    <string name=\"about_app\">Informazioni sull\\'app</string>\n    <string name=\"issue_tracker_sub\">Invia segnalazioni di bug e richieste di funzionalità qui</string>\n    <string name=\"search_here\">Cerca qui</string>\n    <string name=\"help_translate_sub\">Correggi gli errori di traduzione o localizza il progetto in un\\'altra lingua</string>\n    <string name=\"nothing_found_by_search\">Nessun risultato per questa ricerca</string>\n    <string name=\"dynamic_colors_sub\">Se abilitato, i colori dell\\'app verranno adottati per i colori dello sfondo</string>\n    <string name=\"failed_to_save\">Impossibile salvare le immagini %d</string>\n    <string name=\"surface\">Superficie</string>\n    <string name=\"secondary\">Secondario</string>\n    <string name=\"permission_sub\">L\\'app ha bisogno di accedere alla memoria per salvare le immagini. Per favore concedi l\\'autorizzazione nella finestra di dialogo seguente</string>\n    <string name=\"monet_colors\">Colori Monet</string>\n    <string name=\"donation_sub\">Questa applicazione è completamente gratuita, ma se vuoi sostenere lo sviluppo del progetto, puoi cliccare qui</string>\n    <string name=\"fab_alignment\">Allineamento FAB</string>\n    <string name=\"check_updates\">Controlla gli aggiornamenti</string>\n    <string name=\"check_updates_sub\">Se abilitata, la finestra di aggiornamento verrà mostrata all\\'avvio dell\\'app</string>\n    <string name=\"values\">Valori</string>\n    <string name=\"add\">Aggiungi</string>\n    <string name=\"primary\">Primario</string>\n    <string name=\"tertiary\">Terziario</string>\n    <string name=\"permission\">Permesso</string>\n    <string name=\"grant\">Consenti</string>\n    <string name=\"zoom\">Zoom immagine</string>\n    <string name=\"prefix\">Prefisso</string>\n    <string name=\"filename\">Nome del file</string>\n    <string name=\"grant_permission_manual\">L\\'app ha bisogno di questa autorizzazione per funzionare, per favore concedila manualmente</string>\n    <string name=\"border_thickness\">Spessore del bordo</string>\n    <string name=\"share\">Condividi</string>\n    <string name=\"external_storage\">Archiviazione esterna</string>\n    <string name=\"add_file_size\">Aggiungi dimensione file</string>\n    <string name=\"add_file_size_sub\">Se abilitato, aggiunge larghezza e altezza dell\\'immagine al nome del file salvato</string>\n    <string name=\"emoji_sub\">Scegli quale emoji mostrare sulla schermata principale</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Luci e ombre</string>\n    <string name=\"highlights\">Punti salienti</string>\n    <string name=\"shadows\">Ombre</string>\n    <string name=\"negative\">Negativo</string>\n    <string name=\"spacing\">Spaziatura</string>\n    <string name=\"line_width\">Larghezza della linea</string>\n    <string name=\"sobel_edge\">Bordo di Sobel</string>\n    <string name=\"radius\">Raggio</string>\n    <string name=\"image_link\">Collegamento immagine</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"swirl\">Vortice</string>\n    <string name=\"limits_resize\">Limiti ridimensionamento</string>\n    <string name=\"lookup\">Cercare</string>\n    <string name=\"stack_blur\">Sfocatura dello stack</string>\n    <string name=\"convolution3x3\">Convoluzione 3x3</string>\n    <string name=\"blur_center_y\">Centro sfocatura y</string>\n    <string name=\"luminance_threshold\">Soglia di luminanza</string>\n    <string name=\"delete_exif\">Elimina EXIF</string>\n    <string name=\"delete_exif_sub\">Elimina i metadati EXIF da qualsiasi set di immagini</string>\n    <string name=\"image_preview\">Anteprima Immagine</string>\n    <string name=\"image_preview_sub\">Visualizza l\\'anteprima di qualsiasi tipo di immagine: GIF, SVG e così via</string>\n    <string name=\"image_source\">Fonte immagine</string>\n    <string name=\"photo_picker\">Selettore di foto</string>\n    <string name=\"gallery_picker\">Galleria</string>\n    <string name=\"file_explorer_picker\">Esplora file</string>\n    <string name=\"photo_picker_sub\">Selettore di foto moderno per Android che appare nella parte inferiore dello schermo, potrebbe funzionare solo su android 12+. Presenta problemi con la ricezione dei metadati EXIF</string>\n    <string name=\"gallery_picker_sub\">Semplice selettore di immagini della galleria. Funziona solo se hai un\\'app per la selezione di file multimediali</string>\n    <string name=\"file_explorer_picker_sub\">Usa l\\'intento GetContent per scegliere l\\'immagine. Funziona ovunque, ma su alcuni dispositivi può avere problemi con la ricezione di immagini selezionate. Non è colpa mia.</string>\n    <string name=\"options_arrangement\">Disposizione delle opzioni</string>\n    <string name=\"edit\">Modificare</string>\n    <string name=\"order\">Ordine</string>\n    <string name=\"order_sub\">Modifica l\\'ordine delle opzioni sulla schermata principale</string>\n    <string name=\"emojis_count\">Contano gli emoji</string>\n    <string name=\"replace_sequence_number\">Sostituisci il numero di sequenza</string>\n    <string name=\"replace_sequence_number_sub\">Se abilitato, sostituisce il timestamp standard al numero di sequenza dell\\'immagine se si utilizza l\\'elaborazione batch</string>\n    <string name=\"filename_not_work_with_photopicker\">L\\'aggiunta del nome file originale non funziona se è selezionata l\\'origine dell\\'immagine del selettore di foto</string>\n    <string name=\"load_image_from_net\">Carica l\\'immagine dalla rete</string>\n    <string name=\"no_image\">Nessuna immagine</string>\n    <string name=\"fill\">Riempire</string>\n    <string name=\"fit\">Adatto</string>\n    <string name=\"explicit_description\">Forza ogni immagine in un\\'immagine data dal parametro Larghezza e Altezza - può cambiare le proporzioni</string>\n    <string name=\"flexible_description\">Ridimensiona le immagini in immagini con un lato lungo dato dal parametro Larghezza o Altezza, tutti i calcoli delle dimensioni verranno eseguiti dopo il salvataggio - mantiene le proporzioni</string>\n    <string name=\"brightness\">Luminosità</string>\n    <string name=\"contrast\">Contrasto</string>\n    <string name=\"hue\">Tinta</string>\n    <string name=\"saturation\">Saturazione</string>\n    <string name=\"add_filter\">Aggiungi filtro</string>\n    <string name=\"filter\">Filtro</string>\n    <string name=\"filter_sub\">Applica qualsiasi catena di filtri a determinate immagini</string>\n    <string name=\"filters\">Filtri</string>\n    <string name=\"light_aka_illumination\">Leggero</string>\n    <string name=\"color_filter\">Filtro colore</string>\n    <string name=\"exposure\">Esposizione</string>\n    <string name=\"white_balance\">bilanciamento del bianco</string>\n    <string name=\"temperature\">Temperatura</string>\n    <string name=\"tint\">Tinta</string>\n    <string name=\"monochrome\">Monocromo</string>\n    <string name=\"haze\">Foschia</string>\n    <string name=\"effect\">Effetto</string>\n    <string name=\"distance\">Distanza</string>\n    <string name=\"slope\">Pendenza</string>\n    <string name=\"sharpen\">Affilare</string>\n    <string name=\"sepia\">Seppia</string>\n    <string name=\"solarize\">Solarizza</string>\n    <string name=\"vibrance\">Vividezza</string>\n    <string name=\"black_and_white\">Bianco e nero</string>\n    <string name=\"crosshatch\">Tratteggio incrociato</string>\n    <string name=\"blur\">Sfocatura</string>\n    <string name=\"halftone\">Mezzitoni</string>\n    <string name=\"cga_colorspace\">Spazio colore GCA</string>\n    <string name=\"gaussian_blur\">sfocatura gaussiana</string>\n    <string name=\"box_blur\">Sfocatura della casella</string>\n    <string name=\"bilaterial_blur\">Sfocatura bilaterale</string>\n    <string name=\"emboss\">Rilievo</string>\n    <string name=\"laplacian\">Laplaciano</string>\n    <string name=\"vignette\">Vignetta</string>\n    <string name=\"start\">Inizio</string>\n    <string name=\"end\">FINE</string>\n    <string name=\"kuwahara\">Levigatura Kuwahara</string>\n    <string name=\"scale\">Scala</string>\n    <string name=\"distortion\">Distorsione</string>\n    <string name=\"angle\">Angolo</string>\n    <string name=\"bulge\">Rigonfiamento</string>\n    <string name=\"dilation\">Dilatazione</string>\n    <string name=\"sphere_refraction\">Rifrazione della sfera</string>\n    <string name=\"refractive_index\">Indice di rifrazione</string>\n    <string name=\"glass_sphere_refraction\">Rifrazione della sfera di vetro</string>\n    <string name=\"color_matrix\">Matrice di colori</string>\n    <string name=\"opacity\">Opacità</string>\n    <string name=\"limits_resize_sub\">Ridimensiona le immagini scelte in base a determinati limiti di larghezza e altezza rispettando le proporzioni</string>\n    <string name=\"sketch\">Schizzo</string>\n    <string name=\"threshold\">Soglia</string>\n    <string name=\"quantizationLevels\">Livelli di quantizzazione</string>\n    <string name=\"smooth_toon\">Tono liscio</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterizza</string>\n    <string name=\"non_maximum_suppression\">Soppressione non massima</string>\n    <string name=\"weak_pixel_inclusion\">Inclusione di pixel debole</string>\n    <string name=\"rgb_filter\">Filtro RGB</string>\n    <string name=\"false_color\">Falso colore</string>\n    <string name=\"first_color\">Primo colore</string>\n    <string name=\"second_color\">Secondo colore</string>\n    <string name=\"reorder\">Riordina</string>\n    <string name=\"fast_blur\">Sfocatura veloce</string>\n    <string name=\"blur_size\">Dimensione sfocatura</string>\n    <string name=\"blur_center_x\">Centro sfocatura x</string>\n    <string name=\"zoom_blur\">Sfocatura dello zoom</string>\n    <string name=\"color_balance\">Bilanciamento del colore</string>\n    <string name=\"load_image_from_net_sub\">Carica qualsiasi immagine da internet, visualizzala in anteprima, ingrandiscila, salvala e modificala se lo desideri.</string>\n    <string name=\"content_scale\">Scala del contenuto</string>\n    <string name=\"sequence_num\">sequenzaNum</string>\n    <string name=\"original_filename\">originaleNome file</string>\n    <string name=\"add_original_filename\">Aggiungi il nome del file originale</string>\n    <string name=\"add_original_filename_sub\">Se abilitato aggiunge il nome file originale nel nome dell\\'immagine di output</string>\n    <string name=\"implementation\">Implementazione</string>\n    <string name=\"pick_file\">Scegli file</string>\n    <string name=\"group_options_by_type\">Opzioni di gruppo per tipo</string>\n    <string name=\"found_s\">Trovato %1$s</string>\n    <string name=\"fallback_option\">Opzione di riserva</string>\n    <string name=\"decrypt\">Decrittare</string>\n    <string name=\"features_sub\">Crittografia dei file basata su password. I file ottenuti possono essere archiviati nella directory selezionata o condivisi. I file decifrati possono anche essere aperti direttamente.</string>\n    <string name=\"file_size_sub\">La dimensione massima del file è limitata dal sistema operativo Android e dalla memoria disponibile, che dipende dal dispositivo. \\nNota: per memoria non si intende quella di archiviazione.</string>\n    <string name=\"cache_size\">Dimensione della cache</string>\n    <string name=\"tools\">Utensili</string>\n    <string name=\"group_options_by_type_sub\">Raggruppa le opzioni sulla schermata principale per tipologia invece di usare la disposizione personalizzata</string>\n    <string name=\"secondary_customization\">Personalizzazione secondaria</string>\n    <string name=\"screenshot\">Immagine dello schermo</string>\n    <string name=\"cipher_sub\">Crittografa e decrittografa qualsiasi file (non solo l\\'immagine) in base a vari algoritmi crittografici</string>\n    <string name=\"encrypt\">Crittografare</string>\n    <string name=\"draw\">Disegno</string>\n    <string name=\"draw_sub\">Disegna sull\\'immagine come in uno sketchbook o disegna sullo sfondo stesso</string>\n    <string name=\"paint_alpha\">Dipingi alfa</string>\n    <string name=\"draw_on_background_sub\">Scegli il colore di sfondo e disegnaci sopra</string>\n    <string name=\"pick_file_to_start\">Scegli il file per iniziare</string>\n    <string name=\"store_file_desc\">Archivia questo file sul tuo dispositivo o usa l\\'azione di condivisione per metterlo dove vuoi</string>\n    <string name=\"features\">Caratteristiche</string>\n    <string name=\"skip\">Saltare</string>\n    <string name=\"activate_files\">L\\'app Files è disabilitata, attivala per utilizzare questa funzione</string>\n    <string name=\"edit_screenshot\">Modifica schermata</string>\n    <string name=\"invalid_password_or_not_encrypted\">Password non valida o il file scelto non è crittografato</string>\n    <string name=\"compatibility\">Compatibilità</string>\n    <string name=\"background_color\">Colore di sfondo</string>\n    <string name=\"file_proceed\">File elaborato</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Impossibile modificare la disposizione mentre il raggruppamento delle opzioni è abilitato</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"auto_cache_clearing_sub\">Se abilitata, la cache dell\\'app verrà cancellata all\\'avvio dell\\'app</string>\n    <string name=\"create\">Creare</string>\n    <string name=\"compatibility_sub\">Si prega di notare che la compatibilità con altri software o servizi di crittografia dei file non è garantita. Un trattamento della chiave o una configurazione di cifratura leggermente diversi possono causare incompatibilità.</string>\n    <string name=\"image_size_warning\">Il tentativo di salvare l\\'immagine con una determinata larghezza e altezza potrebbe causare un errore OOM. Fallo a tuo rischio e non dire che non ti avevo avvertito!</string>\n    <string name=\"auto_cache_clearing\">Cancellazione automatica della cache</string>\n    <string name=\"copy\">copia</string>\n    <string name=\"warning_bytes\">Il salvataggio in modalità %1$s può essere instabile, perché è un formato senza perdita di dati</string>\n    <string name=\"paint_color\">Colore della vernice</string>\n    <string name=\"draw_on_image\">Disegna sull\\'immagine</string>\n    <string name=\"draw_on_image_sub\">Scegli un\\'immagine e disegna qualcosa su di essa</string>\n    <string name=\"draw_on_background\">Disegna sullo sfondo</string>\n    <string name=\"cipher\">Cifra</string>\n    <string name=\"decryption\">Decrittazione</string>\n    <string name=\"encryption\">Crittografia</string>\n    <string name=\"key\">Chiave</string>\n    <string name=\"implementation_sub\">AES-256, modalità GCM, nessuna spaziatura interna, IV casuali a 12 byte. (Per impostazione predefinita, ma è possibile selezionare l\\'algoritmo desiderato) Le chiavi vengono utilizzate come hash SHA-3 (256 bit).</string>\n    <string name=\"file_size\">Dimensione del file</string>\n    <string name=\"presets_sub\" formatted=\"false\">Se hai selezionato il preset 125, l\\'immagine verrà salvata con il 125% della dimensione originale. Se hai scelto il preset 50, allora l\\'immagine verrà salvata con il 50% della dimensione.</string>\n    <string name=\"reset_settings_sub\">In questo modo verranno ripristinate le impostazioni ai valori predefiniti. Si noti che questa operazione non può essere annullata senza un file di backup menzionato sopra.</string>\n    <string name=\"something_went_wrong_emphasis\">Oops… Qualcosa è andato storto. Puoi scrivermi utilizzando le opzioni di seguito e cercherò di trovare una soluzione</string>\n    <string name=\"tg_chat\">Chat Telegram</string>\n    <string name=\"nature_and_animals\">Natura e animali</string>\n    <string name=\"activities\">Attività</string>\n    <string name=\"food_and_drink\">Cibo e Bevande</string>\n    <string name=\"contact_me\">Contattami</string>\n    <string name=\"backup_sub\">Fai il backup delle impostazioni dell\\'app</string>\n    <string name=\"corrupted_file_or_not_a_backup\">File corrotto o non un backup</string>\n    <string name=\"analytics_sub\">Permette di inviare dati anonimi sull\\'utilizzo dell\\'app</string>\n    <string name=\"font_scale\">Scala dei caratteri</string>\n    <string name=\"draw_mode\">Modalità disegno</string>\n    <string name=\"restore\">Ripristina</string>\n    <string name=\"trim_image_sub\">Gli spazi trasparenti intorno all\\'immagine saranno sbarrati</string>\n    <string name=\"tg_chat_sub\">Discuti dell\\'app e ricevi feedback da altri utenti. Puoi anche ottenere aggiornamenti e approfondimenti sulla versione beta.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Zz 0123456789 !?</string>\n    <string name=\"erase_background\">Cancella sfondo</string>\n    <string name=\"restore_image\">Ripristina l\\'immagine</string>\n    <string name=\"delete\">Elimina</string>\n    <string name=\"aspect_ratio\">Proporzioni</string>\n    <string name=\"background_remover\">Rimozione sfondo</string>\n    <string name=\"trim_image\">Ritaglia l\\'immagine</string>\n    <string name=\"background_remover_sub\">Rimuovi lo sfondo dall\\'immagine disegnando o usando l\\'opzione Automatica</string>\n    <string name=\"delete_color_scheme_warn\">Stai per cancellare lo schema dei colori. Questa operazione non può essere annullata</string>\n    <string name=\"saved_to_without_filename\">Salvato nella cartella %1$s</string>\n    <string name=\"settings_restored\">Impostazioni ripristinate con successo</string>\n    <string name=\"backup_and_restore\">Backup e ripristina</string>\n    <string name=\"backup\">Backup</string>\n    <string name=\"auto_erase_background\">Cancella lo sfondo automaticamente</string>\n    <string name=\"emotions\">Emoji</string>\n    <string name=\"crashlytics_sub\">Questo permette all\\'app di collezzionare dati sui crash manualmente</string>\n    <string name=\"create_issue\">Crea segnalazione</string>\n    <string name=\"saved_to\">Salva in questa cartella %1$s, con questo nome %2$s</string>\n    <string name=\"symbols\">Simboli</string>\n    <string name=\"analytics\">Analisi</string>\n    <string name=\"image_crop_mask_sub\">Usa questo tipo di maschera per creare una maschera da una data immagine, nota che DOVREBBE avere un canale alfa</string>\n    <string name=\"enable_emoji\">Abilita emoji</string>\n    <string name=\"resize_and_convert\">Ridimensiona e converti</string>\n    <string name=\"objects\">Oggetti</string>\n    <string name=\"randomize_filename\">Nome file casuale</string>\n    <string name=\"text\">Testo</string>\n    <string name=\"defaultt\">Predefinito</string>\n    <string name=\"delete_color_scheme_title\">Cancella schema</string>\n    <string name=\"restore_background\">Ripristina sfondo</string>\n    <string name=\"font\">Carattere</string>\n    <string name=\"resize_and_convert_sub\">Cambia la dimensione dell\\'immagine e convertila in altri formati. I dati EXIF possono essere modificati se si seleziona una sola foto</string>\n    <string name=\"using_large_fonts_warn\">L\\'uso di caratteri di grandi dimensioni può causare glitch e problemi dell\\'interfaccia utente, che non verranno risolti. Usa con cautela.</string>\n    <string name=\"randomize_filename_sub\">Se abilitato il nome del file sarà casuale</string>\n    <string name=\"keep_exif_sub\">I metadati dell\\'immagine originale verranno conservati</string>\n    <string name=\"restore_sub\">Ripristina le impostazioni dal backup precedente</string>\n    <string name=\"presets_sub_bytes\">Il preset qui determina la % del file di output, ad esempio se si seleziona il preset 50 su un\\'immagine da 5 MB, si otterrà un\\'immagine da 2,5 mb dopo il salvataggio</string>\n    <string name=\"erase_mode\">Modalità gomma</string>\n    <string name=\"travels_and_places\">Viaggi e Luoghi</string>\n    <string name=\"updates\">Aggiornamenti</string>\n    <string name=\"horizontal\">Orizzontale</string>\n    <string name=\"crop_mask\">Maschera di ritaglio</string>\n    <string name=\"max_colors_count\">Numero max colori</string>\n    <string name=\"wait\">Attesa</string>\n    <string name=\"image_exif_warning\">Al momento, il formato %1$s consente la sola lettura dei metadati EXIF su android. L\\'immagine generata non avrà alcun metadato, quando verrà salvata.</string>\n    <string name=\"images_order\">Ordine immagini</string>\n    <string name=\"brush_softness\">Morbidezza pennello</string>\n    <string name=\"blur_edges\">Arrotonda angoli</string>\n    <string name=\"effort_sub\">In valore di %1$s indica una compressione veloce, che produrrà un file di dimensioni relativamente grandi. %2$s indica una compressione più lenta, che produrrà file di dimensioni più piccole.</string>\n    <string name=\"image_stitching\">Cuci Immagini</string>\n    <string name=\"allow_betas\">Consenti beta</string>\n    <string name=\"draw_arrows\">Disegna Frecce</string>\n    <string name=\"pick_at_least_two_images\">Scegli almeno 2 immagini</string>\n    <string name=\"draw_arrows_sub\">Se abilitato, il percorso di disegno sarà rappresentato da una freccia a punta</string>\n    <string name=\"blur_radius\">Raggio sfocatura</string>\n    <string name=\"scale_small_images_to_large_sub\">Se abilitato, le immagini piccole saranno scalate sulla base delle dimensioni di quella più grande</string>\n    <string name=\"image_stitching_sub\">Combina le immagini scelte in una singola immagine grande</string>\n    <string name=\"saving_almost_complete\">Salvataggio quasi completato. Se si annulla ora bisognerà salvare di nuovo.</string>\n    <string name=\"pipette\">Contagocce</string>\n    <string name=\"image_orientation\">Orientamento Immagine</string>\n    <string name=\"vertical\">Verticale</string>\n    <string name=\"effort\">Iterazioni</string>\n    <string name=\"crop_description\">Le immagini saranno ritagliate al centro in base alle dimensioni inserite. L\\'area verrà espansa con il colore di sfondo indicato se l\\'immagine è più piccola delle dimensioni inserite.</string>\n    <string name=\"donation\">Donazioni</string>\n    <string name=\"output_image_scale\">Scala immagine generata</string>\n    <string name=\"regular\">Regolare</string>\n    <string name=\"allow_betas_sub\">Se abilitato, il controllo aggiornamenti includerà le versioni beta dell\\'app</string>\n    <string name=\"scale_small_images_to_large\">Scala le immagini piccole ingrandendole</string>\n    <string name=\"enhanced_circle_pixelation\">Pixelizzazione del cerchio migliorata</string>\n    <string name=\"color_to_remove\">Colore da rimuovere</string>\n    <string name=\"remove_color\">Rimuovi colore</string>\n    <string name=\"top\">Superiore</string>\n    <string name=\"strength\">Forza</string>\n    <string name=\"segmentation_mode_osd_only\">Orientamento &amp; Solo rilevamento script</string>\n    <string name=\"segmentation_mode_single_char\">Carattere singolo</string>\n    <string name=\"glitch\">Problema</string>\n    <string name=\"amount\">Quantità</string>\n    <string name=\"seed\">Seme</string>\n    <string name=\"delete_mask_warn\">Stai per eliminare la maschera filtro selezionata. Questa operazione non può essere annullata</string>\n    <string name=\"no_such_directory\">Nessuna directory \\\"%1$s\\\" trovata, l\\'abbiamo impostata su quella predefinita, salva nuovamente il file</string>\n    <string name=\"vibration_strength\">Forza delle vibrazioni</string>\n    <string name=\"overwrite_files\">Sovrascrivi file</string>\n    <string name=\"empty\">Vuoto</string>\n    <string name=\"suffix\">Suffisso</string>\n    <string name=\"search_option\">Ricerca</string>\n    <string name=\"free\">Libero</string>\n    <string name=\"enhanced_pixelation\">Pixelizzazione migliorata</string>\n    <string name=\"stroke_pixelation\">Pixelizzazione del tratto</string>\n    <string name=\"enhanced_diamond_pixelation\">Pixelazione del diamante migliorata</string>\n    <string name=\"tolerance\">Tolleranza</string>\n    <string name=\"color_to_replace\">Colore da sostituire</string>\n    <string name=\"target_color\">Colore target</string>\n    <string name=\"recode\">Ricodificare</string>\n    <string name=\"vibrant\">Vibrante</string>\n    <string name=\"expressive\">Espressivo</string>\n    <string name=\"rainbow\">Arcobaleno</string>\n    <string name=\"fruit_salad\">Macedonia</string>\n    <string name=\"fidelity\">Fedeltà</string>\n    <string name=\"content\">Contenuto</string>\n    <string name=\"tonal_spot_sub\">Stile palette predefinito, permette di personalizzare tutti e quattro i colori, altri permettono di impostare solo il colore chiave</string>\n    <string name=\"neutral_sub\">Uno stile leggermente più cromatico che monocromatico</string>\n    <string name=\"vibrant_sub\">Un tema forte, la vivacità è massima per la tavolozza Primaria, aumentata per le altre</string>\n    <string name=\"playful_scheme\">Un tema giocoso: la tonalità del colore di origine non appare nel tema</string>\n    <string name=\"monochrome_sub\">Un tema monocromatico, i colori sono puramente nero/bianco/grigio</string>\n    <string name=\"content_sub\">Uno schema che inserisce il colore di origine in Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Uno schema che è molto simile allo schema dei contenuti</string>\n    <string name=\"search_option_sub\">Abilita la possibilità di effettuare ricerche tra tutte le opzioni disponibili nella schermata principale</string>\n    <string name=\"pdf_tools_sub\">Opera con file PDF: visualizza l\\'anteprima, converti in batch di immagini o creane uno da determinate immagini</string>\n    <string name=\"preview_pdf\">Anteprima del PDF</string>\n    <string name=\"pdf_to_images\">PDF in immagini</string>\n    <string name=\"images_to_pdf\">Immagini in PDF</string>\n    <string name=\"preview_pdf_sub\">Anteprima PDF semplice</string>\n    <string name=\"pdf_to_images_sub\">Converti PDF in immagini nel formato di output specificato</string>\n    <string name=\"images_to_pdf_sub\">Comprimi le immagini fornite nel file PDF di output</string>\n    <string name=\"mask_filter\">Filtro maschera</string>\n    <string name=\"mask_filter_sub\">Applica catene di filtri su determinate aree mascherate, ciascuna area mascherata può determinare il proprio set di filtri</string>\n    <string name=\"masks\">Maschere</string>\n    <string name=\"add_mask\">Aggiungi maschera</string>\n    <string name=\"mask_indexed\">Maschera %d</string>\n    <string name=\"inverse_fill_type_sub\">Se abilitato, tutte le aree non mascherate verranno filtrate invece del comportamento predefinito</string>\n    <string name=\"delete_mask\">Elimina maschera</string>\n    <string name=\"simple_variants\">Varianti semplici</string>\n    <string name=\"highlighter\">Evidenziatore</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Penna</string>\n    <string name=\"privacy_blur\">Sfocatura della privacy</string>\n    <string name=\"neon_sub\">Aggiungi un effetto luminoso ai tuoi disegni</string>\n    <string name=\"pen_sub\">Quello predefinito, il più semplice: solo il colore</string>\n    <string name=\"privacy_blur_sub\">Sfoca l\\'immagine sotto il percorso disegnato per proteggere tutto ciò che desideri nascondere</string>\n    <string name=\"pixelation_sub\">Simile alla sfocatura della privacy, ma pixela invece di sfocare</string>\n    <string name=\"sliders_shadow_sub\">Abilita il disegno dell\\'ombra dietro i cursori</string>\n    <string name=\"switches_shadow_sub\">Abilita il disegno delle ombre dietro gli interruttori</string>\n    <string name=\"fabs_shadow_sub\">Abilita il disegno dell\\'ombra dietro i pulsanti di azione mobili</string>\n    <string name=\"buttons_shadow_sub\">Abilita il disegno dell\\'ombra dietro i pulsanti predefiniti</string>\n    <string name=\"app_bars_shadow\">Barre delle app</string>\n    <string name=\"app_bars_shadow_sub\">Abilita il disegno dell\\'ombra dietro le barre dell\\'app</string>\n    <string name=\"auto_rotate_limits\">Rotazione automatica</string>\n    <string name=\"auto_rotate_limits_sub\">Consente di adottare la casella limite per l\\'orientamento dell\\'immagine</string>\n    <string name=\"free_drawing_sub\">Disegna il percorso come valore di input</string>\n    <string name=\"line_sub\">Disegna il percorso dal punto iniziale al punto finale come una linea</string>\n    <string name=\"line_arrow_sub\">Disegna la freccia che punta dal punto iniziale al punto finale come una linea</string>\n    <string name=\"arrow_sub\">Disegna una freccia puntata da un determinato percorso</string>\n    <string name=\"double_line_arrow_sub\">Disegna una freccia a doppia punta dal punto iniziale al punto finale come una linea</string>\n    <string name=\"double_arrow_sub\">Disegna una freccia a doppia punta da un determinato percorso</string>\n    <string name=\"rect_sub\">Disegna il rettangolo dal punto iniziale al punto finale</string>\n    <string name=\"oval_sub\">Disegna l\\'ovale dal punto iniziale al punto finale</string>\n    <string name=\"outlined_oval_sub\">Disegna l\\'ovale delineato dal punto iniziale al punto finale</string>\n    <string name=\"outlined_rect_sub\">Disegna il rettangolo delineato dal punto iniziale al punto finale</string>\n    <string name=\"clipboard\">Appunti</string>\n    <string name=\"auto_pin\">Perno automatico</string>\n    <string name=\"auto_pin_sub\">Se abilitato, aggiunge automaticamente l\\'immagine salvata agli appunti</string>\n    <string name=\"vibration\">Vibrazione</string>\n    <string name=\"overwrite_file_requirements\">Per sovrascrivere i file è necessario utilizzare l\\'origine immagine \\\"Explorer\\\", prova a riselezionare le immagini, abbiamo cambiato l\\'origine immagine con quella necessaria</string>\n    <string name=\"overwrite_files_sub\">Il file originale verrà sostituito con uno nuovo invece di essere salvato nella cartella selezionata, questa opzione deve essere \\\"Explorer\\\" o GetContent, quando si attiva questa opzione, verrà impostata automaticamente</string>\n    <string name=\"bicubic\">Bicubico</string>\n    <string name=\"basic\">Di base</string>\n    <string name=\"bilinear_sub\">L\\'interpolazione lineare (o bilineare, in due dimensioni) è generalmente utile per modificare le dimensioni di un\\'immagine, ma provoca un ammorbidimento indesiderato dei dettagli e può comunque risultare un po\\' frastagliato</string>\n    <string name=\"bicubic_sub\">Metodi di ridimensionamento migliori includono il ricampionamento di Lanczos e i filtri Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Uno dei modi più semplici per aumentare le dimensioni, sostituendo ogni pixel con un numero di pixel dello stesso colore</string>\n    <string name=\"basic_sub\">La modalità di ridimensionamento Android più semplice utilizzata in quasi tutte le app</string>\n    <string name=\"catmull_sub\">Metodo per l\\'interpolazione e il ricampionamento uniforme di una serie di punti di controllo, comunemente utilizzato nella grafica computerizzata per creare curve uniformi</string>\n    <string name=\"hann_sub\">Funzione di finestra spesso applicata nell\\'elaborazione del segnale per ridurre al minimo la perdita spettrale e migliorare la precisione dell\\'analisi della frequenza assottigliando i bordi di un segnale</string>\n    <string name=\"hermite_sub\">Tecnica di interpolazione matematica che utilizza i valori e le derivate agli estremi di un segmento di curva per generare una curva uniforme e continua</string>\n    <string name=\"lanczos_sub\">Metodo di ricampionamento che mantiene l\\'interpolazione di alta qualità applicando una funzione di sincronizzazione ponderata ai valori dei pixel</string>\n    <string name=\"mitchell_sub\">Metodo di ricampionamento che utilizza un filtro di convoluzione con parametri regolabili per ottenere un equilibrio tra nitidezza e anti-aliasing nell\\'immagine ridimensionata</string>\n    <string name=\"spline_sub\">Utilizza funzioni polinomiali definite a tratti per interpolare e approssimare in modo uniforme una curva o una superficie, rappresentazione di forme flessibili e continue</string>\n    <string name=\"only_clip_sub\">Il salvataggio nella memoria non verrà eseguito e l\\'immagine verrà tentata solo di essere inserita negli appunti</string>\n    <string name=\"restore_background_sub\">Il pennello ripristinerà lo sfondo invece di cancellarlo</string>\n    <string name=\"use_pixel_switch_sub\">Verrà utilizzato un interruttore simile a pixel al posto del materiale di Google basato su quello</string>\n    <string name=\"saved_to_original\">File sovrascritto con nome %1$s nella destinazione originale</string>\n    <string name=\"magnifier\">Lente d\\'ingrandimento</string>\n    <string name=\"magnifier_sub\">Abilita la lente d\\'ingrandimento sulla parte superiore del dito nelle modalità di disegno per una migliore accessibilità</string>\n    <string name=\"force_exif_widget_initial_value\">Forza il valore iniziale</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Forza il controllo iniziale del widget EXIF</string>\n    <string name=\"allow_multiple_languages\">Consenti più lingue</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientamento automatico &amp; Rilevamento script</string>\n    <string name=\"segmentation_mode_auto_only\">Solo automatico</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Colonna singola</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Testo verticale a blocco singolo</string>\n    <string name=\"segmentation_mode_single_block\">Blocco unico</string>\n    <string name=\"segmentation_mode_single_line\">Linea singola</string>\n    <string name=\"segmentation_mode_single_word\">Singola parola</string>\n    <string name=\"segmentation_mode_circle_word\">Parola circolare</string>\n    <string name=\"segmentation_mode_sparse_text\">Testo scarno</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Orientamento del testo sparse &amp; Rilevamento script</string>\n    <string name=\"segmentation_mode_raw_line\">Linea cruda</string>\n    <string name=\"delete_language_sub\">Vuoi eliminare i dati di addestramento OCR della lingua \\\"%1$s\\\" per tutti i tipi di riconoscimento o solo per quello selezionato (%2$s)?</string>\n    <string name=\"all\">Tutto</string>\n    <string name=\"gradient_maker_sub\">Crea un gradiente della dimensione di output specificata con colori e tipo di aspetto personalizzati</string>\n    <string name=\"gradient_type\">Tipo di gradiente</string>\n    <string name=\"center_x\">Centro X</string>\n    <string name=\"center_y\">Centro Y</string>\n    <string name=\"tile_mode\">Modalità tessera</string>\n    <string name=\"tile_mode_repeated\">Ripetuto</string>\n    <string name=\"tile_mode_mirror\">Specchio</string>\n    <string name=\"tile_mode_clamp\">MORSETTO</string>\n    <string name=\"tile_mode_decal\">Decalcomania</string>\n    <string name=\"color_stops\">Il colore si ferma</string>\n    <string name=\"add_color\">Aggiungi colore</string>\n    <string name=\"properties\">Proprietà</string>\n    <string name=\"camera_sub\">Utilizza la fotocamera per scattare foto, tieni presente che è possibile ottenere solo un\\'immagine da questa sorgente immagine</string>\n    <string name=\"repeat_watermark_sub\">Ripete la filigrana sull\\'immagine anziché su una singola nella posizione specificata</string>\n    <string name=\"offset_x\">Scostamento X</string>\n    <string name=\"offset_y\">Scostamento Y</string>\n    <string name=\"watermark_type\">Tipo di filigrana</string>\n    <string name=\"overlay_mode\">Modalità sovrapposizione</string>\n    <string name=\"gif_tools\">Strumenti GIF</string>\n    <string name=\"gif_tools_sub\">Converti immagini in immagini GIF o estrai fotogrammi da una determinata immagine GIF</string>\n    <string name=\"gif_type_to_image\">GIF alle immagini</string>\n    <string name=\"gif_type_to_image_sub\">Converti file GIF in batch di immagini</string>\n    <string name=\"gif_type_to_gif_sub\">Converti batch di immagini in file GIF</string>\n    <string name=\"gif_type_to_gif\">Immagini in GIF</string>\n    <string name=\"select_gif_image_to_start\">Scegli l\\'immagine GIF per iniziare</string>\n    <string name=\"use_size_of_first_frame\">Usa la dimensione del primo fotogramma</string>\n    <string name=\"use_size_of_first_frame_sub\">Sostituisci la dimensione specificata con le prime dimensioni del telaio</string>\n    <string name=\"repeat_count\">Ripeti conteggio</string>\n    <string name=\"frame_delay\">Ritardo fotogramma</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"secure_mode_sub\">Nasconde il contenuto all\\'uscita, inoltre lo schermo non può essere catturato o registrato</string>\n    <string name=\"gray_scale\">Scala di grigi</string>\n    <string name=\"bayer_two_dithering\">Bayer due a due dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer tre per tre tentennamenti</string>\n    <string name=\"bayer_four_dithering\">Bayer quattro a quattro dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Otto per Otto Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Titubante</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke esita</string>\n    <string name=\"sierra_dithering\">Sierra dithering</string>\n    <string name=\"two_row_sierra_dithering\">Dithering Sierra a due righe</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes esita</string>\n    <string name=\"left_to_right_dithering\">Dithering da sinistra a destra</string>\n    <string name=\"b_spline_sub\">Utilizza funzioni polinomiali bicubiche definite a tratti per interpolare e approssimare in modo uniforme una curva o una superficie, rappresentazione di forme flessibili e continue</string>\n    <string name=\"anaglyph\">Anaglifo</string>\n    <string name=\"noise\">Rumore</string>\n    <string name=\"pixel_sort\">Ordinamento pixel</string>\n    <string name=\"shuffle\">Mescola</string>\n    <string name=\"enhanced_glitch\">Glitch migliorato</string>\n    <string name=\"channel_shift_x\">Spostamento canale X</string>\n    <string name=\"channel_shift_y\">Cambio canale Y</string>\n    <string name=\"corruption_size\">Dimensione della corruzione</string>\n    <string name=\"corruption_shift_x\">Spostamento della corruzione X</string>\n    <string name=\"corruption_shift_y\">Spostamento della corruzione Y</string>\n    <string name=\"tent_blur\">Sfocatura della tenda</string>\n    <string name=\"side_fade\">Dissolvenza laterale</string>\n    <string name=\"side\">Lato</string>\n    <string name=\"bottom\">Metter il fondo a</string>\n    <string name=\"crystallize\">Cristallizzare</string>\n    <string name=\"stroke_color\">Colore del tratto</string>\n    <string name=\"fractal_glass\">Vetro frattale</string>\n    <string name=\"oil\">Olio</string>\n    <string name=\"water_effect\">Effetto Acqua</string>\n    <string name=\"just_size\">Misurare</string>\n    <string name=\"frequency_x\">Frequenza X</string>\n    <string name=\"frequency_y\">Frequenza Y</string>\n    <string name=\"amplitude_x\">Ampiezza X</string>\n    <string name=\"color_matrix_3x3\">Matrice di colori 3x3</string>\n    <string name=\"simple_effects\">Effetti semplici</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomalia</string>\n    <string name=\"deutaromaly\">Deuteranomalia</string>\n    <string name=\"protonomaly\">Protanomalia</string>\n    <string name=\"vintage\">Vintage ▾</string>\n    <string name=\"coda_chrome\">Coda Cromata</string>\n    <string name=\"night_vision\">Visione notturna</string>\n    <string name=\"warm\">Caldo</string>\n    <string name=\"cool\">Freddo</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deuteranopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Acromatomalia</string>\n    <string name=\"orange_haze\">Foschia arancione</string>\n    <string name=\"pink_dream\">Sogno rosa</string>\n    <string name=\"golden_hour\">Ora d\\'oro</string>\n    <string name=\"purple_mist\">Nebbia Viola</string>\n    <string name=\"sunrise\">Alba</string>\n    <string name=\"colorful_swirl\">Vortice colorato</string>\n    <string name=\"spectral_fire\">Fuoco spettrale</string>\n    <string name=\"red_swirl\">Vortice rosso</string>\n    <string name=\"digital_code\">Codice digitale</string>\n    <string name=\"no_favorite_filters\">Nessun filtro preferito ancora aggiunto</string>\n    <string name=\"icon_shape\">Forma dell\\'icona</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Tagliare</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Transizione</string>\n    <string name=\"peak\">Picco</string>\n    <string name=\"color_anomaly\">Anomalia del colore</string>\n    <string name=\"images_overwritten\">Immagini sovrascritte nella destinazione originale</string>\n    <string name=\"cannot_change_image_format\">Impossibile modificare il formato dell\\'immagine mentre l\\'opzione di sovrascrittura dei file è abilitata</string>\n    <string name=\"emoji_as_color_scheme\">Emoji come combinazione di colori</string>\n    <string name=\"emoji_as_color_scheme_sub\">Utilizza il colore primario delle emoji come combinazione di colori dell\\'app invece di quello definito manualmente</string>\n    <string name=\"blur_edges_sub\">Se abilitato, disegna bordi sfocati sotto l\\'immagine originale per riempire gli spazi attorno ad essa anziché un singolo colore</string>\n    <string name=\"pixelation\">Pixelizzazione</string>\n    <string name=\"diamond_pixelation\">Pixelizzazione del diamante</string>\n    <string name=\"circle_pixelation\">Pixelizzazione del cerchio</string>\n    <string name=\"replace_color\">Sostituisci colore</string>\n    <string name=\"erode\">Erodere</string>\n    <string name=\"anisotropic_diffusion\">Diffusione anisotropa</string>\n    <string name=\"diffusion\">Diffusione</string>\n    <string name=\"conduction\">Conduzione</string>\n    <string name=\"horizontal_wind_stagger\">Sfalsamento del vento orizzontale</string>\n    <string name=\"fast_bilaterial_blur\">Sfocatura bilaterale veloce</string>\n    <string name=\"poisson_blur\">Sfocatura di Poisson</string>\n    <string name=\"logarithmic_tone_mapping\">Mappatura dei toni logaritmici</string>\n    <string name=\"aces_filmic_tone_mapping\">Mappatura dei toni filmici di ACES</string>\n    <string name=\"amplitude\">Ampiezza</string>\n    <string name=\"marble\">Marmo</string>\n    <string name=\"turbulence\">Turbolenza</string>\n    <string name=\"amplitude_y\">Ampiezza Y</string>\n    <string name=\"perlin_distortion\">Distorsione Perlin</string>\n    <string name=\"hable_filmic_tone_mapping\">Mappatura dei toni filmici Hable</string>\n    <string name=\"heji_burgess_tone_mapping\">Mappatura dei toni di Hejl Burgess</string>\n    <string name=\"aces_hill_tone_mapping\">Mappatura dei toni di collina ACES</string>\n    <string name=\"current\">Attuale</string>\n    <string name=\"full_filter\">Filtro completo</string>\n    <string name=\"start_position\">Inizio</string>\n    <string name=\"center_position\">Centro</string>\n    <string name=\"end_position\">FINE</string>\n    <string name=\"full_filter_sub\">Applica eventuali catene di filtri a determinate immagini o a una singola immagine</string>\n    <string name=\"gradient_maker\">Creatore di gradienti</string>\n    <string name=\"speed\">Velocità</string>\n    <string name=\"dehaze\">Defoschia</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"pdf_tools\">Strumenti PDF</string>\n    <string name=\"rate_app\">Valuta l\\'app</string>\n    <string name=\"rate\">Valutare</string>\n    <string name=\"rate_app_sub\">Questa app è completamente gratuita, se vuoi che diventi più grande, avvia il progetto su Github 😄</string>\n    <string name=\"color_matrix_4x4\">Matrice di colori 4x4</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"achromatopsia\">Acromatopsia</string>\n    <string name=\"gradient_type_linear\">Lineare</string>\n    <string name=\"gradient_type_radial\">Radiale</string>\n    <string name=\"gradient_type_sweep\">Spazzare</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"lasso\">Lazo</string>\n    <string name=\"lasso_sub\">Disegna un percorso pieno chiuso in base al percorso specificato</string>\n    <string name=\"double_line_arrow\">Freccia a doppia linea</string>\n    <string name=\"draw_path_mode\">Modalità traccia percorso</string>\n    <string name=\"free_drawing\">Disegno libero</string>\n    <string name=\"double_arrow\">Doppia freccia</string>\n    <string name=\"line_arrow\">Freccia di linea</string>\n    <string name=\"arrow\">Freccia</string>\n    <string name=\"line\">Linea</string>\n    <string name=\"outlined_oval\">Ovale delineato</string>\n    <string name=\"outlined_rect\">Rett. delineato</string>\n    <string name=\"oval\">Ovale</string>\n    <string name=\"rect\">Rett</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizzatore</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falso Floyd Steinberg Dithering</string>\n    <string name=\"random_dithering\">Dithering casuale</string>\n    <string name=\"simple_threshold_dithering\">Dithering della soglia semplice</string>\n    <string name=\"mask_color\">Colore maschera</string>\n    <string name=\"mask_preview\">Anteprima della maschera</string>\n    <string name=\"mask_preview_sub\">La maschera del filtro disegnata verrà renderizzata per mostrarti il risultato approssimativo</string>\n    <string name=\"bilinear\">Bilineare</string>\n    <string name=\"scale_mode\">Modalità scala</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Ermita</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Più vicino</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"default_value\">Valore di default</string>\n    <string name=\"value_in_range\">Valore nell\\'intervallo %1$s - %2$s</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma spaziale</string>\n    <string name=\"median_blur\">Sfocatura mediana</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"only_clip\">Solo clip</string>\n    <string name=\"icon_shape_sub\">Aggiunge il contenitore con la forma selezionata sotto le icone principali delle carte</string>\n    <string name=\"brightness_enforcement\">Applicazione della luminosità</string>\n    <string name=\"screen\">Schermo</string>\n    <string name=\"gradient_maker_type_image\">Sovrapposizione gradiente</string>\n    <string name=\"gradient_maker_type_image_sub\">Componi qualsiasi sfumatura della parte superiore dell\\'immagine specificata</string>\n    <string name=\"transformations\">Trasformazioni</string>\n    <string name=\"camera\">Telecamera</string>\n    <string name=\"grain\">Grano</string>\n    <string name=\"unsharp\">Non nitido</string>\n    <string name=\"pastel\">Pastello</string>\n    <string name=\"hot_summer\">Estate calda</string>\n    <string name=\"soft_spring_light\">Luce soffusa primaverile</string>\n    <string name=\"autumn_tones\">Toni autunnali</string>\n    <string name=\"lavender_dream\">Sogno di lavanda</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Limonata leggera</string>\n    <string name=\"night_magic\">Magia notturna</string>\n    <string name=\"fantasy_landscape\">Paesaggio di fantasia</string>\n    <string name=\"color_explosion\">Esplosione di colori</string>\n    <string name=\"electric_gradient\">Gradiente elettrico</string>\n    <string name=\"caramel_darkness\">Oscurità caramellata</string>\n    <string name=\"futuristic_gradient\">Gradiente futuristico</string>\n    <string name=\"green_sun\">Sole Verde</string>\n    <string name=\"rainbow_world\">Mondo Arcobaleno</string>\n    <string name=\"deep_purple\">Viola profondo</string>\n    <string name=\"space_portal\">Portale spaziale</string>\n    <string name=\"watermarking\">Filigrana</string>\n    <string name=\"watermarking_sub\">Coprire le immagini con filigrane di testo/immagine personalizzabili</string>\n    <string name=\"repeat_watermark\">Ripeti filigrana</string>\n    <string name=\"watermarking_image_sub\">Questa immagine verrà utilizzata come modello per la filigrana</string>\n    <string name=\"text_color\">Colore del testo</string>\n    <string name=\"pixel_size\">Dimensione pixel</string>\n    <string name=\"lock_draw_orientation\">Blocca l\\'orientamento del disegno</string>\n    <string name=\"lock_draw_orientation_sub\">Se abilitato in modalità disegno, lo schermo non ruoterà</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"use_lasso\">Usa il lazo</string>\n    <string name=\"use_lasso_sub\">Utilizza Lazo come in modalità disegno per eseguire la cancellazione</string>\n    <string name=\"original_image_preview_alpha\">Anteprima dell\\'immagine originale alfa</string>\n    <string name=\"random_emojis_sub\">L\\'emoji della barra dell\\'app verrà modificata continuamente in modo casuale invece di utilizzare quella selezionata</string>\n    <string name=\"random_emojis\">Emoji casuali</string>\n    <string name=\"random_emojis_error\">Non è possibile utilizzare la selezione casuale di emoji mentre gli emoji sono disabilitati</string>\n    <string name=\"emoji_selection_error\">Impossibile selezionare un emoji mentre se ne seleziona uno casuale abilitato</string>\n    <string name=\"check_for_updates\">Controlla gli aggiornamenti</string>\n    <string name=\"old_tv\">Vecchia televisione</string>\n    <string name=\"shuffle_blur\">Sfocatura casuale</string>\n    <string name=\"recognize_text\">OCR (riconoscimento del testo)</string>\n    <string name=\"recognize_text_sub\">Riconosci il testo da una determinata immagine, sono supportate oltre 120 lingue</string>\n    <string name=\"picture_has_no_text\">L\\'immagine non contiene testo oppure l\\'app non l\\'ha trovata</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Tipo di riconoscimento</string>\n    <string name=\"fast\">Veloce</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"best\">Migliore</string>\n    <string name=\"no_data\">Nessun dato</string>\n    <string name=\"download_description\">Per il corretto funzionamento di Tesseract OCR è necessario scaricare sul dispositivo dati di allenamento aggiuntivi (%1$s). \\nVuoi scaricare i dati %2$s?</string>\n    <string name=\"download\">Scaricamento</string>\n    <string name=\"no_connection\">Nessuna connessione, controlla e riprova per scaricare i modelli dei treni</string>\n    <string name=\"downloaded_languages\">Lingue scaricate</string>\n    <string name=\"available_languages\">Lingue disponibili</string>\n    <string name=\"segmentation_mode\">Modalità di segmentazione</string>\n    <string name=\"horizontal_grid\">Griglia orizzontale</string>\n    <string name=\"vertical_grid\">Griglia verticale</string>\n    <string name=\"stitch_mode\">Modalità punto</string>\n    <string name=\"rows_count\">Conteggio delle righe</string>\n    <string name=\"columns_count\">Conteggio delle colonne</string>\n    <string name=\"use_pixel_switch\">Utilizza Pixel Switch</string>\n    <string name=\"slide\">Diapositiva</string>\n    <string name=\"side_by_side\">Fianco a fianco</string>\n    <string name=\"toggle_tap\">Attiva/Disattiva tocco</string>\n    <string name=\"transparency\">Trasparenza</string>\n    <string name=\"favorite\">Preferito</string>\n    <string name=\"b_spline\">Spline B</string>\n    <string name=\"native_stack_blur\">Sfocatura stack nativa</string>\n    <string name=\"tilt_shift\">Spostamento dell\\'inclinazione</string>\n    <string name=\"inverse_fill_type\">Tipo di riempimento inverso</string>\n    <string name=\"confetti\">Coriandoli</string>\n    <string name=\"confetti_sub\">I coriandoli verranno visualizzati durante il salvataggio, la condivisione e altre azioni primarie</string>\n    <string name=\"secure_mode\">Modalità protetta</string>\n    <string name=\"palette_style\">Stile tavolozza</string>\n    <string name=\"tonal_spot\">Macchia tonale</string>\n    <string name=\"neutral\">Neutro</string>\n    <string name=\"highlighter_sub\">Disegna percorsi di evidenziatore più nitidi semitrasparenti</string>\n    <string name=\"containers_shadow\">Contenitori</string>\n    <string name=\"containers_shadow_sub\">Abilita il disegno dell\\'ombra dietro i contenitori</string>\n    <string name=\"sliders_shadow\">Cursori</string>\n    <string name=\"switches_shadow\">Interruttori</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">Pulsanti</string>\n    <string name=\"attention\">Attenzione</string>\n    <string name=\"foss_update_checker_warning\">Questo controllo aggiornamenti si connetterà a GitHub per verificare se è disponibile un nuovo aggiornamento</string>\n    <string name=\"fading_edges\">Bordi sbiaditi</string>\n    <string name=\"disabled\">Disabilitato</string>\n    <string name=\"both\">Entrambi</string>\n    <string name=\"invert_colors\">Inverti i colori</string>\n    <string name=\"invert_colors_sub\">Sostituisce i colori del tema con quelli negativi, se abilitato</string>\n    <string name=\"exit\">Uscita</string>\n    <string name=\"preview_closing\">Se lasci l\\'anteprima ora, dovrai aggiungere nuovamente le immagini</string>\n    <string name=\"image_format\">Formato immagine</string>\n    <string name=\"dark_colors\">Colori scuri</string>\n    <string name=\"dark_colors_sub\">Utilizza modalità notte combinazione di colori invece di luce variante</string>\n    <string name=\"copy_as_compose_code\">Copia come codice” Jetpack Compose\\\"</string>\n    <string name=\"material_you_sub\">Crea la tavolozza \\\"Material You\\\" dall\\'immagine</string>\n    <string name=\"ring_blur\">Sfocatura dell\\'anello</string>\n    <string name=\"cross_blur\">Sfocatura incrociata</string>\n    <string name=\"star_blur\">Sfocatura stellare</string>\n    <string name=\"linear_tilt_shift\">Spostamento dell\\'inclinazione lineare</string>\n    <string name=\"circle_blur\">Sfocatura del cerchio</string>\n    <string name=\"tags_to_remove\">Tag da rimuovere</string>\n    <string name=\"apng_tools\">Strumenti APNG</string>\n    <string name=\"apng_tools_sub\">Converti immagini in immagini APNG o estrai fotogrammi da una determinata immagine APNG</string>\n    <string name=\"apng_type_to_image\">APNG alle immagini</string>\n    <string name=\"apng_type_to_apng_sub\">Converti batch di immagini in file APNG</string>\n    <string name=\"apng_type_to_apng\">Immagini in APNG</string>\n    <string name=\"select_apng_image_to_start\">Scegli l\\'immagine APNG per iniziare</string>\n    <string name=\"motion_blur\">Sfocatura movimento</string>\n    <string name=\"apng_type_to_image_sub\">Converti file APNG in batch di immagini</string>\n    <string name=\"zip\">Compressione</string>\n    <string name=\"zip_sub\">Crea file zip da determinati file o immagini</string>\n    <string name=\"drag_handle_width\">Trascina la larghezza della maniglia</string>\n    <string name=\"confetti_type\">Tipo Coriandoli</string>\n    <string name=\"festive\">Da festa</string>\n    <string name=\"explode\">Esplosione</string>\n    <string name=\"rain\">Pioggia</string>\n    <string name=\"corners\">Angoli</string>\n    <string name=\"jxl_tools\">Strumenti JXL</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Esegui la transcodifica senza perdita da JXL a JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Eseguire la transcodifica senza perdita da JPEG a JXL</string>\n    <string name=\"jxl_type_to_jpeg\">Da JXL a JPEG</string>\n    <string name=\"jxl_tools_sub\">Esegui la transcodifica JXL ~ JPEG senza perdita di qualità o converti le GIF/APNG in animazioni JXL.</string>\n    <string name=\"jpeg_type_to_jxl\">Da JPEG a JXL</string>\n    <string name=\"harmonization_level\">Livello Armonizzazione</string>\n    <string name=\"generate_previews_sub\">Abilita la generazione di anteprime, questo può aiutare a evitare crash su alcuni dispositivi, ma disabilita anche alcune funzionalità di modifica all\\'interno dell\\'opzione di modifica singola.</string>\n    <string name=\"auto_paste\">Auto Incolla</string>\n    <string name=\"auto_paste_sub\">Consente all\\'app di incollare automaticamente i dati degli appunti, in modo da farli apparire nella schermata principale e poterli elaborare.</string>\n    <string name=\"harmonization_color\">Colore Armonizzazione</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"gif_type_to_jxl\">Da GIF a JXL</string>\n    <string name=\"apng_type_to_jxl\">Da APNG a JXL</string>\n    <string name=\"jxl_type_to_images\">Da JXL a Immagini</string>\n    <string name=\"jxl_type_to_images_sub\">Converti l\\'animazione JXL in un gruppo di immagini</string>\n    <string name=\"jxl_type_to_jxl\">Immagini in JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Converti un gruppo di immagini in un\\'animazione JXL</string>\n    <string name=\"behavior\">Comportamento</string>\n    <string name=\"skip_file_picking\">Salta Selezione File</string>\n    <string name=\"skip_file_picking_sub\">Il selezionatore di file verrà mostrato immediatamente, se possibile, nella schermata scelta</string>\n    <string name=\"generate_previews\">Genera Anteprime</string>\n    <string name=\"gif_type_to_jxl_sub\">Converti immagini GIF in animazioni JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Converti immagini APNG in animazioni JXL</string>\n    <string name=\"sorting\">Ordinamento</string>\n    <string name=\"sort_by_date\">Ordina Per Data</string>\n    <string name=\"sort_by_name\">Ordina Per Nome</string>\n    <string name=\"sort_by_name_reversed\">Ordina Per Nome (Invertito)</string>\n    <string name=\"sort_by_date_reversed\">Ordina Per Data (Invertito)</string>\n    <string name=\"no_permissions\">Nessun Permesso</string>\n    <string name=\"select_jxl_image_to_start\">Scegli l\\'immagine JXL per iniziare</string>\n    <string name=\"header_today\">Oggi</string>\n    <string name=\"header_yesterday\">Ieri</string>\n    <string name=\"request\">Richiesta</string>\n    <string name=\"images_to_svg\">Immagini in Svg</string>\n    <string name=\"try_again\">Riprova</string>\n    <string name=\"lanczos_bessel_sub\">Metodo di ricampionamento che mantiene un\\'interpolazione di alta qualità applicando una funzione di Bessel (jinc) ai valori dei pixel</string>\n    <string name=\"embedded_picker_sub\">Utilizza il selezionatore di immagini di Image Toolbox invece di quelli predefiniti dal sistema.</string>\n    <string name=\"show_settings_in_landscape\">Mostra le impostazioni in orizzontale</string>\n    <string name=\"fullscreen_settings\">Impostazioni a schermo intero</string>\n    <string name=\"fullscreen_settings_sub\">Abilita e la pagina delle impostazioni verrà sempre aperta a schermo intero invece che lateralmente</string>\n    <string name=\"pick_multiple_media\">Seleziona più media</string>\n    <string name=\"pick_single_media\">Seleziona un media</string>\n    <string name=\"pick\">Seleziona</string>\n    <string name=\"fast_gaussian_blur_2d\">Sfocatura Gaussiana Veloce 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Sfocatura Gaussiana Veloce 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Sfocatura Gaussiana Veloce 4D</string>\n    <string name=\"channels_configuration\">Configurazione dei canali</string>\n    <string name=\"embedded_picker\">Selettore incorporato</string>\n    <string name=\"lossy_compression\">Compressione con perdita</string>\n    <string name=\"compression_type\">Tipo di compressione</string>\n    <string name=\"show_settings_in_landscape_sub\">Se disattivata, le impostazioni in modalità panorama saranno aperte tramite il pulsante nella barra superiore invece di averle sempre visibili.</string>\n    <string name=\"switch_type\">Cambia Tipo</string>\n    <string name=\"compose\">Componi</string>\n    <string name=\"speed_sub\">Controlla la velocità di decodifica del risultato per renderne l\\'apertura più rapida. Un valore di %1$s indica la decodifica più lenta, mentre %2$s la più veloce. Quest\\'impostazione può aumentare le dimensioni dell\\'immagine finale.</string>\n    <string name=\"lossy_compression_sub\">Usa una compressione con perdita di dati per ridurre le dimensioni del file invece di una senza perdita.</string>\n    <string name=\"material_you_switch_sub\">Usa Material Your basato sulla vista, è molto meglio degli altri e ha belle animazioni</string>\n    <string name=\"compose_switch_sub\">Utilizza il Material You Jetpack Compose che cambi, non è così bello come quello basato sulla vista</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Ridimensiona Ancora</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch_sub\">Usa interruttori in stile Windows 11 basati sul sistema di design \\\"Fluent\\\"</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"tag_transfer_function\">Trasferisci Funzione</string>\n    <string name=\"tag_y_resolution\">Risoluzione Y</string>\n    <string name=\"tag_reference_black_white\">Nero Bianco di Riferimento</string>\n    <string name=\"min_color_ratio\">Minimo Rapporto del Colore</string>\n    <string name=\"tag_image_description\">Descrizione dell\\'Immagine</string>\n    <string name=\"detailed\">Dettagliato/a</string>\n    <string name=\"tag_samples_per_pixel\">Campioni Per Pixel</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"downscale_image\">Riduci la risoluzione dell\\'immagine</string>\n    <string name=\"lines_threshold\">Soglia delle linee</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolleranza dell\\'Arrotondamento delle Coordinate</string>\n    <string name=\"path_scale\">Scala del percorso</string>\n    <string name=\"default_line_width\">Larghezza Predefinita della Linea</string>\n    <string name=\"lstm_network\">network LSTM</string>\n    <string name=\"add_new_folder\">Aggiungi una Nuova Cartella</string>\n    <string name=\"tag_bits_per_sample\">Bit Per Campione</string>\n    <string name=\"tag_compression\">Compressione</string>\n    <string name=\"tag_photometric_interpretation\">Interpretazione fotometrica</string>\n    <string name=\"tag_planar_configuration\">Configurazione Planare</string>\n    <string name=\"tag_x_resolution\">Risoluzione X</string>\n    <string name=\"tag_resolution_unit\">Unità di risoluzione</string>\n    <string name=\"tag_rows_per_strip\">Righe Per Striscia</string>\n    <string name=\"tag_white_point\">Punto Bianco</string>\n    <string name=\"tag_primary_chromaticities\">Cromaticità Primarie</string>\n    <string name=\"svg_warning\">L\\'utilizzo di questo strumento per tracciare immagini larghe senza riduzione della dimensione non è consigliato, può causare crash e aumentare il tempo di elaborazione</string>\n    <string name=\"reset_properties\">Ripristina proprietà</string>\n    <string name=\"reset_properties_sub\">Tutte le proprietà saranno impostate ai valori di default, nota che questa azione non può essere annullata</string>\n    <string name=\"save_empty_lut_sub\">Prima, usa la tua applicazione di editing di foto per applicare un filtro per LUT neutro che puoi ottenere qui. Per fare in modo che questo funzioni correttamente ogni colore di ogni pixel non deve dipendere da altri pixel (es. la sfocatura non funzionerà). Appena pronto, usa la tua nuova immagine LUT come input per un filtro LUT 512*512</string>\n    <string name=\"convert\">Converti</string>\n    <string name=\"downscale_image_sub\">La risoluzione dell\\'immagine verrà ridotta per ridurre le dimensioni prima di processare, questo aiuta lo strumento ad essere più veloce e sicuro</string>\n    <string name=\"convert_sub\">Converti i batch di immagini nel formato specificato</string>\n    <string name=\"images_to_svg_sub\">Traccia le immagini fornite in immagini SVG</string>\n    <string name=\"cupertino_switch_sub\">Utilizza uno switch simile ad iOS basato sul cupertino design system</string>\n    <string name=\"gradient\">Gradiente</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"rays\">Raggi</string>\n    <string name=\"sparkle\">Scintilla</string>\n    <string name=\"spread_angle\">Angolo di Apertura</string>\n    <string name=\"arc\">Arco</string>\n    <string name=\"refraction_index\">Indice di rifrazione</string>\n    <string name=\"use_sampled_palette\">Usa Palette Campionata</string>\n    <string name=\"use_sampled_palette_sub\">La palette di quantificazione verrà campionata se questa opzione è abilitata</string>\n    <string name=\"path_omit\">Ometti Percorso</string>\n    <string name=\"quadratic_threshold\">Soglia Quadratica</string>\n    <string name=\"engine_mode\">Modalità Motore</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Coefficienti Y Cb Cr</string>\n    <string name=\"tag_datetime\">Data Ora</string>\n    <string name=\"tag_make\">Crea</string>\n    <string name=\"tag_model\">Modello</string>\n    <string name=\"tag_artist\">Artista</string>\n    <string name=\"tag_exif_version\">Versione Exif</string>\n    <string name=\"tag_pixel_x_dimension\">Dimensione Pixel X</string>\n    <string name=\"tag_pixel_y_dimension\">Dimensione Pixel Y</string>\n    <string name=\"tag_maker_note\">Nota Creatore</string>\n    <string name=\"tag_user_comment\">Commento Utente</string>\n    <string name=\"tag_datetime_original\">Data Ora Originali</string>\n    <string name=\"tag_datetime_digitized\">Data Ora Digitalizzati</string>\n    <string name=\"tag_exposure_time\">Tempo di Esposizione</string>\n    <string name=\"tag_f_number\">Numero F</string>\n    <string name=\"tag_exposure_program\">Programma di Esposizione</string>\n    <string name=\"tag_spectral_sensitivity\">Sensibilità Spettrale</string>\n    <string name=\"tag_photographic_sensitivity\">Sensibilità Fotografica</string>\n    <string name=\"tag_sensitivity_type\">Tipo Sensibilità</string>\n    <string name=\"tag_standard_output_sensitivity\">Sensibilità di Uscita Standard</string>\n    <string name=\"tag_iso_speed\">Velocità ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Velocità ISO Latitudine yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Velocità ISO Latitudine zzz</string>\n    <string name=\"tag_aperture_value\">Valore di Apertura</string>\n    <string name=\"tag_brightness_value\">Valore di Luminosità</string>\n    <string name=\"tag_max_aperture_value\">Valore di Apertura Massima</string>\n    <string name=\"tag_subject_distance\">Distanza Soggetto</string>\n    <string name=\"tag_subject_area\">Area Soggetto</string>\n    <string name=\"tag_focal_length\">Distanza Focale</string>\n    <string name=\"tag_flash_energy\">Energia Flash</string>\n    <string name=\"tag_focal_plane_x_resolution\">Risoluzione Piano Focale X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Risoluzione Piano Focale Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Unità Risoluzione Piano Focale</string>\n    <string name=\"tag_subject_location\">Posizione Soggetto</string>\n    <string name=\"tag_exposure_index\">Indice di Esposizione</string>\n    <string name=\"tag_file_source\">Sorgente File</string>\n    <string name=\"tag_exposure_mode\">Modalità Esposizione</string>\n    <string name=\"tag_white_balance\">Bilanciamento Bianco</string>\n    <string name=\"tag_saturation\">Saturazione</string>\n    <string name=\"tag_contrast\">Contrasto</string>\n    <string name=\"tag_sharpness\">Nitidezza</string>\n    <string name=\"tag_device_setting_description\">Descrizione Impostazioni Dispositivo</string>\n    <string name=\"tag_image_unique_id\">ID Unico Immagine</string>\n    <string name=\"tag_camera_owner_name\">Nome Proprietario Fotocamera</string>\n    <string name=\"tag_body_serial_number\">Numero di Serie Corpo</string>\n    <string name=\"tag_lens_specification\">Specifiche Lente</string>\n    <string name=\"tag_lens_make\">Marca Lente</string>\n    <string name=\"tag_lens_model\">Modello Lente</string>\n    <string name=\"tag_lens_serial_number\">Numero Di Serie Lente</string>\n    <string name=\"tag_gps_version_id\">ID Versione GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Riferimento Latitudine GPS</string>\n    <string name=\"tag_gps_latitude\">Latitudine GPS</string>\n    <string name=\"tag_gps_longitude_ref\">Riferimento Longitudine GPS</string>\n    <string name=\"tag_gps_longitude\">Longitudine GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Riferimento Altitudine GPS</string>\n    <string name=\"tag_gps_altitude\">Altitudine GPS</string>\n    <string name=\"tag_gps_satellites\">Satelliti GPS</string>\n    <string name=\"tag_gps_status\">Stato GPS</string>\n    <string name=\"tag_gps_measure_mode\">Modalità Misurazione GPS</string>\n    <string name=\"tag_gps_speed_ref\">Riferimento Velocità GPS</string>\n    <string name=\"tag_gps_speed\">Velocità GPS</string>\n    <string name=\"tag_gps_track_ref\">Riferimento Traccia GPS</string>\n    <string name=\"tag_gps_track\">Traccia GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Riferimento Direzione Immagine GPS</string>\n    <string name=\"tag_gps_img_direction\">Direzione Immagine GPS</string>\n    <string name=\"tag_gps_map_datum\">Dato Mappa GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Riferimento Latitudine Dest GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Latitudine Dest GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Riferimento Longitudine Dest GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Longitudine Dest GPS</string>\n    <string name=\"font_size\">Dimensione Scritte</string>\n    <string name=\"watermark_size\">Dimensione Filigrana</string>\n    <string name=\"repeat_text\">Ripeti Testo</string>\n    <string name=\"repeat_text_sub\">Il testo corrente verrà ripetuto fino alla fine del percorso invece di un unica volta</string>\n    <string name=\"vertices\">Vertici</string>\n    <string name=\"polygon\">Poligono</string>\n    <string name=\"triangle\">Triangolo</string>\n    <string name=\"outlined_triangle\">Triangolo Delineato</string>\n    <string name=\"polygon_sub\">Disegna un poligono dal punto di partenza al punto finale</string>\n    <string name=\"outlined_polygon\">Poligono Delineato</string>\n    <string name=\"star\">Stella</string>\n    <string name=\"outlined_star\">Stella Delineata</string>\n    <string name=\"draw_mode_image_sub\">Usa l\\'immagine selezionata per disegnarla lungo il percorso dato</string>\n    <string name=\"draw_image_sub\">Questa immagine sarà utilizzata come ripetizione nel percorso disegnato</string>\n    <string name=\"outlined_triangle_sub\">Disegna un triangolo delineato dal punto di partenza al punto finale</string>\n    <string name=\"triangle_sub\">Disegna un triangolo delineato dal punto di partenza al punto finale</string>\n    <string name=\"outlined_polygon_sub\">Disegna un poligono delineato dal punto di partenza al punto finale</string>\n    <string name=\"draw_regular_polygon\">Disegna Poligono Regolare</string>\n    <string name=\"draw_regular_polygon_sub\">Disegnare poligono regolare invece che in forma libera</string>\n    <string name=\"star_sub\">Disegna una stella dal punto di partenza al punto finale</string>\n    <string name=\"outlined_star_sub\">Disegna una stella delineata dal punto di partenza al punto finale</string>\n    <string name=\"inner_radius_ratio\">Rapporto Raggio Interno</string>\n    <string name=\"draw_regular_star\">Disegna Stella Regolare</string>\n    <string name=\"draw_regular_star_sub\">Disegna una stella regolare invece che in forma libera</string>\n    <string name=\"open_edit_instead_of_preview\">Apri Modifica Invece Di Anteprima</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Quando selezioni l\\'immagine da aprire (anteprima) in ImageToolbox, verrà aperto la selezione di modifica invece di visualizzare in anteprima</string>\n    <string name=\"document_scanner\">Scanner Documenti</string>\n    <string name=\"document_scanner_sub\">Scansiona documenti e crea PDF o immagini separate</string>\n    <string name=\"click_to_start_scanning\">Clicca per iniziare la scansione</string>\n    <string name=\"start_scanning\">Inizia Scansione</string>\n    <string name=\"save_as_pdf\">Salva Come PDF</string>\n    <string name=\"share_as_pdf\">Condividi Come PDF</string>\n    <string name=\"options_below_is_for_images\">Le opzioni di seguito sono per salvare immagini, non PDF</string>\n    <string name=\"enter_percentage\">Inserisci Percentuale</string>\n    <string name=\"scan_qr_code\">Scansiona Codice QR</string>\n    <string name=\"opened_file_have_no_filter_template\">Il file selezionato non ha dati sul modello di filtro</string>\n    <string name=\"create_template\">Crea Modello</string>\n    <string name=\"template_name\">Nome Modello</string>\n    <string name=\"select_template_preview\">Questa immagine sarà usata per visualizzare in anteprima questo modello di filtro</string>\n    <string name=\"template_filter\">Modello di Filtro</string>\n    <string name=\"as_qr_code\">Come Immagine QR</string>\n    <string name=\"as_file\">Come file</string>\n    <string name=\"save_as_file\">Salva come file</string>\n    <string name=\"save_as_qr_code_image\">Salva come Immagine QR</string>\n    <string name=\"delete_template\">Cancella Modello</string>\n    <string name=\"delete_template_warn\">Stai per eliminare il modello di filtro selezionato. Questa operazione non può essere annullata</string>\n    <string name=\"added_filter_template\">Aggiunto modello di filtro con nome \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Anteprima Filtro</string>\n    <string name=\"qr_code\">Codice a barre &amp; QR</string>\n    <string name=\"qr_code_sub\">Scansiona il codice QR e ottieni il suo contenuto o incolla la tua stringa per generarne uno nuovo</string>\n    <string name=\"code_content\">Contenuto Codice</string>\n    <string name=\"scan_qr_code_to_replace_content\">Scansiona qualsiasi codice a barre per sostituire il contenuto nel campo o digita qualcosa per generare un nuovo codice a barre con il tipo selezionato</string>\n    <string name=\"qr_description\">Descrizione QR</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Concedi l\\'autorizzazione della fotocamera nelle impostazioni per la scansione di codici QR</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Concedi l\\'autorizzazione della fotocamera nelle impostazioni per la scansione di documenti</string>\n    <string name=\"cubic\">Cubica</string>\n    <string name=\"quadric\">Quadratica</string>\n    <string name=\"gaussian\">Gaussiana</string>\n    <string name=\"format_conversion\">Conversione Formato</string>\n    <string name=\"format_conversion_sub\">Converti una serie di immagini da un formato all\\'altro</string>\n    <string name=\"tag_copyright\">Diritti d\\'autore</string>\n    <string name=\"tag_flashpix_version\">Versione Flashpix</string>\n    <string name=\"tag_color_space\">Spazio Colore</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Bit Compressi Per Pixel</string>\n    <string name=\"tag_related_sound_file\">File Audio Associato</string>\n    <string name=\"tag_strip_offsets\">Scostamenti Striscia</string>\n    <string name=\"tag_strip_byte_counts\">Numero Byte Striscia</string>\n    <string name=\"tag_offset_time\">Tempo Scostamento</string>\n    <string name=\"tag_offset_time_original\">Tempo Scostamento Originale</string>\n    <string name=\"tag_offset_time_digitized\">Tempo Scostamento Digitalizzato</string>\n    <string name=\"offset\">Scostamento</string>\n    <string name=\"max_offset\">Scostamento Massimo</string>\n    <string name=\"tag_subsec_time\">Tempo Sub Sec</string>\n    <string name=\"tag_subsec_time_original\">Tempo Sub Sec Originale</string>\n    <string name=\"tag_subsec_time_digitized\">Tempo Sub Sec Digitalizzato</string>\n    <string name=\"tag_recommended_exposure_index\">Indice Esposizione Consigliato</string>\n    <string name=\"tag_shutter_speed_value\">Valore Velocità Otturatore</string>\n    <string name=\"tag_metering_mode\">Modalità Misurazione</string>\n    <string name=\"tag_spatial_frequency_response\">Risposta Frequenza Spaziale</string>\n    <string name=\"tag_sensing_method\">Metodo Rilevamento</string>\n    <string name=\"tag_digital_zoom_ratio\">Rapporto Zoom Digitale</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Distanza Focale in pellicola da 35mm</string>\n    <string name=\"tag_scene_capture_type\">Tipo Cattura Scena</string>\n    <string name=\"tag_default_crop_size\">Dimensione Ritaglio Predefinita</string>\n    <string name=\"tag_orf_preview_image_start\">Inizio Anteprima Immagine</string>\n    <string name=\"tag_orf_preview_image_length\">Lunghezza Anteprima Immagine</string>\n    <string name=\"tag_rw2_sensor_left_border\">Bordo Sinistro Sensore</string>\n    <string name=\"tag_rw2_sensor_right_border\">Bordo Destro Sensore</string>\n    <string name=\"tag_rw2_sensor_top_border\">Bordo Superiore Sensore</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Bordo Inferiore Sensore</string>\n    <string name=\"border_color\">Colore bordo</string>\n    <string name=\"linear\">Lineare</string>\n    <string name=\"scale_color_space\">Scala Spazio Colore</string>\n    <string name=\"grid_size_x\">Dimensione Griglia X</string>\n    <string name=\"grid_size_y\">Dimensione Griglia Y</string>\n    <string name=\"legacy\">Eredità</string>\n    <string name=\"legacy_and_lstm\">Legacy e LSTM</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sottocampionamento</string>\n    <string name=\"tag_y_cb_cr_positioning\">Posizionamento Y Cb Cr</string>\n    <string name=\"tag_jpeg_interchange_format\">Formato di interscambio JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Lunghezza del formato di interscambio JPEG</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_exposure_bias_value\">Valore di compensazione dell\\'esposizione</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_cfa_pattern\">Modello CFA</string>\n    <string name=\"tag_custom_rendered\">Rendering personalizzato</string>\n    <string name=\"tag_gain_control\">Ottieni il controllo</string>\n    <string name=\"tag_subject_distance_range\">Intervallo di distanza del soggetto</string>\n    <string name=\"tag_gps_timestamp\">Timbro orario GPS</string>\n    <string name=\"tag_gps_dop\">GPSDOP</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Rif. rilevamento destinazione GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Rilevamento destinazione GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Rif. distanza dest GPS</string>\n    <string name=\"tag_gps_dest_distance\">Distanza di destinazione GPS</string>\n    <string name=\"tag_gps_processing_method\">Metodo di elaborazione GPS</string>\n    <string name=\"tag_gps_area_information\">Informazioni sull\\'area GPS</string>\n    <string name=\"tag_gps_datestamp\">Timbro data GPS</string>\n    <string name=\"tag_gps_differential\">Differenziale GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Errore di posizionamento GPS H</string>\n    <string name=\"tag_interoperability_index\">Indice di interoperabilità</string>\n    <string name=\"tag_dng_version\">Versione DNG</string>\n    <string name=\"tag_orf_aspect_frame\">Cornice aspetto</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Disegna il testo sul percorso con il carattere e il colore specificati</string>\n    <string name=\"dash_size\">Dimensione del trattino</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Abilita l\\'antialiasing per evitare spigoli vivi</string>\n    <string name=\"equalize_histogram_hsv\">Equalizza l\\'istogramma HSV</string>\n    <string name=\"equalize_histogram\">Equalizza l\\'istogramma</string>\n    <string name=\"allow_enter_by_text_field\">Consenti l\\'immissione tramite campo di testo</string>\n    <string name=\"allow_enter_by_text_field_sub\">Abilita il campo di testo dietro la selezione delle preimpostazioni, per inserirle al volo</string>\n    <string name=\"equalize_histogram_pixelation\">Equalizza la pixelizzazione dell\\'istogramma</string>\n    <string name=\"equalize_histogram_adaptive\">Equalizza istogramma adattivo</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Equalizza l\\'istogramma LUV adattivo</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalizza istogramma LAB adattivo</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">LABORATORIO CLAHE</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Ritaglia al contenuto</string>\n    <string name=\"frame_color\">Colore della cornice</string>\n    <string name=\"color_to_ignore\">Colore da ignorare</string>\n    <string name=\"template\">Modello</string>\n    <string name=\"no_template_filters\">Nessun filtro modello aggiunto</string>\n    <string name=\"create_new\">Crea nuovo</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Il codice QR scansionato non è un modello di filtro valido</string>\n    <string name=\"min\">minimo</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Uomo Nero</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"sphinx\">Sfinge</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux tagliente</string>\n    <string name=\"spline16\">Splina 16</string>\n    <string name=\"spline36\">Splina 36</string>\n    <string name=\"spline64\">Splina 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Scatola</string>\n    <string name=\"bohman\">Bohmann</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">L\\'interpolazione cubica fornisce un ridimensionamento più uniforme considerando i 16 pixel più vicini, fornendo risultati migliori rispetto a quello bilineare</string>\n    <string name=\"bspline_sub\">Utilizza funzioni polinomiali definite a tratti per interpolare e approssimare in modo uniforme una curva o una superficie, rappresentazione di forme flessibili e continue</string>\n    <string name=\"hamming_sub\">Una funzione finestra utilizzata per ridurre la perdita spettrale assottigliando i bordi di un segnale, utile nell\\'elaborazione del segnale</string>\n    <string name=\"hanning_sub\">Una variante della finestra di Hann, comunemente utilizzata per ridurre la dispersione spettrale nelle applicazioni di elaborazione del segnale</string>\n    <string name=\"blackman_sub\">Una funzione finestra che fornisce una buona risoluzione di frequenza riducendo al minimo la perdita spettrale, spesso utilizzata nell\\'elaborazione del segnale</string>\n    <string name=\"welch_sub\">Una funzione finestra progettata per fornire una buona risoluzione di frequenza con una ridotta dispersione spettrale, spesso utilizzata nelle applicazioni di elaborazione del segnale</string>\n    <string name=\"quadric_sub\">Un metodo che utilizza una funzione quadratica per l\\'interpolazione, fornendo risultati uniformi e continui</string>\n    <string name=\"gaussian_sub\">Un metodo di interpolazione che applica una funzione gaussiana, utile per attenuare e ridurre il rumore nelle immagini</string>\n    <string name=\"sphinx_sub\">Un metodo di ricampionamento avanzato che fornisce un\\'interpolazione di alta qualità con artefatti minimi</string>\n    <string name=\"bartlett_sub\">Una funzione di finestra triangolare utilizzata nell\\'elaborazione del segnale per ridurre la dispersione spettrale</string>\n    <string name=\"robidoux_sub\">Un metodo di interpolazione di alta qualità ottimizzato per il ridimensionamento naturale delle immagini, bilanciando nitidezza e uniformità</string>\n    <string name=\"robidoux_sharp_sub\">Una variante più nitida del metodo Robidoux, ottimizzata per un ridimensionamento nitido delle immagini</string>\n    <string name=\"spline16_sub\">Un metodo di interpolazione basato su spline che fornisce risultati uniformi utilizzando un filtro a 16 tocchi</string>\n    <string name=\"spline36_sub\">Un metodo di interpolazione basato su spline che fornisce risultati uniformi utilizzando un filtro a 36 tocchi</string>\n    <string name=\"spline64_sub\">Un metodo di interpolazione basato su spline che fornisce risultati uniformi utilizzando un filtro a 64 tocchi</string>\n    <string name=\"kaiser_sub\">Un metodo di interpolazione che utilizza la finestra Kaiser, fornendo un buon controllo sul compromesso tra larghezza del lobo principale e livello del lobo laterale</string>\n    <string name=\"bartlett_hann_sub\">Una funzione di finestra ibrida che combina le finestre Bartlett e Hann, utilizzata per ridurre la perdita spettrale nell\\'elaborazione del segnale</string>\n    <string name=\"box_sub\">Un semplice metodo di ricampionamento che utilizza la media dei valori dei pixel più vicini, spesso risultando in un aspetto a blocchi</string>\n    <string name=\"bohman_sub\">Una funzione finestra utilizzata per ridurre la dispersione spettrale, fornendo una buona risoluzione di frequenza nelle applicazioni di elaborazione del segnale</string>\n    <string name=\"lanczos2_sub\">Un metodo di ricampionamento che utilizza un filtro Lanczos a 2 lobi per un\\'interpolazione di alta qualità con artefatti minimi</string>\n    <string name=\"lanczos3_sub\">Un metodo di ricampionamento che utilizza un filtro Lanczos a 3 lobi per un\\'interpolazione di alta qualità con artefatti minimi</string>\n    <string name=\"lanczos4_sub\">Un metodo di ricampionamento che utilizza un filtro Lanczos a 4 lobi per un\\'interpolazione di alta qualità con artefatti minimi</string>\n    <string name=\"lanczos2_jinc_sub\">Una variante del filtro Lanczos 2 che utilizza la funzione jinc, fornendo un\\'interpolazione di alta qualità con artefatti minimi</string>\n    <string name=\"lanczos3_jinc_sub\">Una variante del filtro Lanczos 3 che utilizza la funzione jinc, fornendo un\\'interpolazione di alta qualità con artefatti minimi</string>\n    <string name=\"lanczos4_jinc_sub\">Una variante del filtro Lanczos 4 che utilizza la funzione jinc, fornendo un\\'interpolazione di alta qualità con artefatti minimi</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Variante ellittica ponderata media (EWA) del filtro Hanning per un\\'interpolazione e un ricampionamento uniformi</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Variante ellittica ponderata media (EWA) del filtro Robidoux per un ricampionamento di alta qualità</string>\n    <string name=\"ewa_blackman\">Blackman EVA</string>\n    <string name=\"ewa_blackman_sub\">Variante ellittica ponderata media (EWA) del filtro Blackman per ridurre al minimo gli artefatti di squillo</string>\n    <string name=\"ewa_quadric\">Quadrica EWA</string>\n    <string name=\"ewa_quadric_sub\">Variante della media ponderata ellittica (EWA) del filtro Quadric per un\\'interpolazione uniforme</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Variante ellittica ponderata media (EWA) del filtro Robidoux Sharp per risultati più nitidi</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Variante Elliptical Weighted Average (EWA) del filtro Lanczos 3 Jinc per ricampionamento di alta qualità con aliasing ridotto</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Un filtro di ricampionamento progettato per l\\'elaborazione delle immagini di alta qualità con un buon equilibrio tra nitidezza e morbidezza</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Variante ellittica media ponderata (EWA) del filtro Ginseng per una migliore qualità dell\\'immagine</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Variante ellittica ponderata media (EWA) del filtro Lanczos Sharp per ottenere risultati nitidi con artefatti minimi</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA più nitido</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Variante Elliptical Weighted Average (EWA) del filtro Lanczos 4 Sharpest per un ricampionamento delle immagini estremamente nitido</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Variante EWA (Elliptical Weighted Average) del filtro Lanczos Soft per un ricampionamento delle immagini più fluido</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Un filtro di ricampionamento progettato da Haasn per un ridimensionamento delle immagini fluido e privo di artefatti</string>\n    <string name=\"dismiss_forever\">Licenzia per sempre</string>\n    <string name=\"image_stacking\">Impilamento delle immagini</string>\n    <string name=\"image_stacking_sub\">Impila le immagini una sopra l\\'altra con le modalità di fusione scelte</string>\n    <string name=\"add_image\">Aggiungi immagine</string>\n    <string name=\"bins_count\">I contenitori contano</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Equalizza l\\'HSL adattivo dell\\'istogramma</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Equalizza l\\'istogramma Adaptive HSV</string>\n    <string name=\"edge_mode\">Modalità bordo</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Avvolgere</string>\n    <string name=\"color_blind_scheme\">Daltonismo</string>\n    <string name=\"color_blind_scheme_sub\">Seleziona la modalità per adattare i colori del tema alla variante daltonica selezionata</string>\n    <string name=\"protanomaly_sub\">Difficoltà a distinguere tra tonalità rosse e verdi</string>\n    <string name=\"deuteranomaly_sub\">Difficoltà a distinguere tra tonalità verdi e rosse</string>\n    <string name=\"tritanomaly_sub\">Difficoltà a distinguere tra tonalità blu e gialle</string>\n    <string name=\"protanopia_sub\">Incapacità di percepire le tonalità rosse</string>\n    <string name=\"deuteranopia_sub\">Incapacità di percepire le tonalità verdi</string>\n    <string name=\"tritanopia_sub\">Incapacità di percepire le tonalità del blu</string>\n    <string name=\"achromatomaly_sub\">Sensibilità ridotta a tutti i colori</string>\n    <string name=\"achromatopsia_sub\">Daltonismo completo, vedendo solo sfumature di grigio</string>\n    <string name=\"not_use_color_blind_scheme\">Non utilizzare lo schema daltonico</string>\n    <string name=\"not_use_color_blind_scheme_sub\">I colori saranno esattamente come impostati nel tema</string>\n    <string name=\"sigmoidal\">Sigmoidale</string>\n    <string name=\"lagrange_2\">Lagrangiano 2</string>\n    <string name=\"lagrange_2_sub\">Un filtro di interpolazione Lagrange di ordine 2, adatto per il ridimensionamento di immagini di alta qualità con transizioni uniformi</string>\n    <string name=\"lagrange_3\">Lagrangiano 3</string>\n    <string name=\"lagrange_3_sub\">Un filtro di interpolazione Lagrange di ordine 3, che offre migliore precisione e risultati più uniformi per il ridimensionamento delle immagini</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Un filtro di ricampionamento Lanczos con un ordine superiore a 6, che fornisce un ridimensionamento dell\\'immagine più nitido e accurato</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Una variante del filtro Lanczos 6 che utilizza una funzione Jinc per una migliore qualità di ricampionamento dell\\'immagine</string>\n    <string name=\"linear_box_blur\">Sfocatura casella lineare</string>\n    <string name=\"linear_tent_blur\">Sfocatura tenda lineare</string>\n    <string name=\"linear_gaussian_box_blur\">Sfocatura lineare della scatola gaussiana</string>\n    <string name=\"linear_stack_blur\">Sfocatura stack lineare</string>\n    <string name=\"gaussian_box_blur\">Sfocatura gaussiana della scatola</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Sfocatura gaussiana veloce lineare successiva</string>\n    <string name=\"linear_fast_gaussian_blur\">Sfocatura gaussiana veloce lineare</string>\n    <string name=\"linear_gaussian_blur\">Sfocatura gaussiana lineare</string>\n    <string name=\"draw_filter_sub\">Scegli un filtro per usarlo come vernice</string>\n    <string name=\"replace_filter\">Sostituisci il filtro</string>\n    <string name=\"pick_filter_info\">Scegli il filtro qui sotto per usarlo come pennello nel tuo disegno</string>\n    <string name=\"tiff_compression_scheme\">Schema di compressione TIFF</string>\n    <string name=\"low_poly\">Basso poli</string>\n    <string name=\"sand_painting\">Pittura con sabbia</string>\n    <string name=\"image_splitting\">Divisione delle immagini</string>\n    <string name=\"image_splitting_sub\">Dividi una singola immagine per righe o colonne</string>\n    <string name=\"fit_to_bounds\">Adatta ai limiti</string>\n    <string name=\"fit_to_bounds_sub\">Combina la modalità di ridimensionamento del ritaglio con questo parametro per ottenere il comportamento desiderato (Ritaglia/Adatta alle proporzioni)</string>\n    <string name=\"languages_imported\">Lingue importate correttamente</string>\n    <string name=\"backup_ocr_models\">Backup dei modelli OCR</string>\n    <string name=\"import_word\">Importare</string>\n    <string name=\"export\">Esportare</string>\n    <string name=\"position\">Posizione</string>\n    <string name=\"center\">Centro</string>\n    <string name=\"top_left\">In alto a sinistra</string>\n    <string name=\"top_right\">In alto a destra</string>\n    <string name=\"bottom_left\">In basso a sinistra</string>\n    <string name=\"bottom_right\">In basso a destra</string>\n    <string name=\"top_center\">Centro in alto</string>\n    <string name=\"center_right\">Centrodestra</string>\n    <string name=\"bottom_center\">In basso al centro</string>\n    <string name=\"center_left\">Centrosinistra</string>\n    <string name=\"target_image\">Immagine di destinazione</string>\n    <string name=\"palette_transfer\">Trasferimento tavolozza</string>\n    <string name=\"enhanced_oil\">Olio potenziato</string>\n    <string name=\"simple_old_tv\">Vecchia TV semplice</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Schizzo semplice</string>\n    <string name=\"soft_glow\">Bagliore morbido</string>\n    <string name=\"color_poster\">Manifesto a colori</string>\n    <string name=\"tri_tone\">Tritono</string>\n    <string name=\"third_color\">Terzo colore</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">A pois</string>\n    <string name=\"clustered_2x2_dithering\">Dithering 2x2 in cluster</string>\n    <string name=\"clustered_4x4_dithering\">Dithering 4x4 in cluster</string>\n    <string name=\"clustered_8x8_dithering\">Dithering 8x8 in cluster</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Nessuna opzione preferita selezionata, aggiungila nella pagina degli strumenti</string>\n    <string name=\"add_favorites\">Aggiungi preferiti</string>\n    <string name=\"harmony_complementary\">Complementare</string>\n    <string name=\"harmony_analogous\">Analogo</string>\n    <string name=\"harmony_triadic\">Triadico</string>\n    <string name=\"harmony_split_complementary\">Complementare diviso</string>\n    <string name=\"harmony_tetradic\">Tetradico</string>\n    <string name=\"harmony_square\">Piazza</string>\n    <string name=\"harmony_analogous_complementary\">Analogo + Complementare</string>\n    <string name=\"color_tools\">Strumenti colore</string>\n    <string name=\"color_tools_sub\">Mescola, crea toni, genera sfumature e altro ancora</string>\n    <string name=\"color_harmonies\">Armonie di colori</string>\n    <string name=\"color_shading\">Sfumatura di colore</string>\n    <string name=\"variation\">Variazione</string>\n    <string name=\"tints\">Tinte</string>\n    <string name=\"tones\">Toni</string>\n    <string name=\"shades\">Sfumature</string>\n    <string name=\"color_mixing\">Miscelazione dei colori</string>\n    <string name=\"color_info\">Informazioni sul colore</string>\n    <string name=\"selected_color\">Colore selezionato</string>\n    <string name=\"color_to_mix\">Colore da mescolare</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Non è possibile utilizzare Monet mentre i colori dinamici sono attivi</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Immagine LUT di destinazione</string>\n    <string name=\"amatorka\">Un dilettante</string>\n    <string name=\"miss_etikate\">Signorina Etichetta</string>\n    <string name=\"soft_elegance\">Eleganza morbida</string>\n    <string name=\"soft_elegance_variant\">Variante Eleganza Morbida</string>\n    <string name=\"palette_transfer_variant\">Variante di trasferimento tavolozza</string>\n    <string name=\"cube_lut\">LUT 3D</string>\n    <string name=\"target_cube_lut_file\">File LUT 3D di destinazione (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bypass della candeggina</string>\n    <string name=\"candlelight\">Lume di candela</string>\n    <string name=\"drop_blues\">Abbandona il blues</string>\n    <string name=\"edgy_amber\">Ambra tagliente</string>\n    <string name=\"fall_colors\">Colori autunnali</string>\n    <string name=\"film_stock_50\">Filmato 50</string>\n    <string name=\"foggy_night\">Notte nebbiosa</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Ottieni un\\'immagine LUT neutra</string>\n    <string name=\"pop_art\">Pop art</string>\n    <string name=\"celluloid\">Celluloide</string>\n    <string name=\"coffee\">Caffè</string>\n    <string name=\"golden_forest\">Foresta d\\'Oro</string>\n    <string name=\"greenish\">Verdastro</string>\n    <string name=\"retro_yellow\">Giallo retrò</string>\n    <string name=\"links_preview\">Anteprima dei collegamenti</string>\n    <string name=\"links_preview_sub\">Abilita il recupero dell\\'anteprima del collegamento nei luoghi in cui è possibile ottenere testo (QRCode, OCR ecc.)</string>\n    <string name=\"links\">Collegamenti</string>\n    <string name=\"ico_size_warning\">I file ICO possono essere salvati solo alla dimensione massima di 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF in WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Converti immagini GIF in immagini animate WEBP</string>\n    <string name=\"webp_tools\">Strumenti WEBP</string>\n    <string name=\"webp_tools_sub\">Converti immagini in immagini animate WEBP o estrai fotogrammi da una determinata animazione WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP alle immagini</string>\n    <string name=\"webp_type_to_image_sub\">Converti file WEBP in batch di immagini</string>\n    <string name=\"webp_type_to_webp_sub\">Converti batch di immagini in file WEBP</string>\n    <string name=\"webp_type_to_webp\">Immagini su WEBP</string>\n    <string name=\"select_webp_image_to_start\">Scegli l\\'immagine WEBP per iniziare</string>\n    <string name=\"manage_storage_extra_types\">Nessun accesso completo ai file</string>\n    <string name=\"manage_storage_extra_types_sub\">Consenti l\\'accesso a tutti i file per vedere JXL, QOI e altre immagini che non sono riconosciute come immagini su Android. Senza l\\'autorizzazione Image Toolbox non è in grado di mostrare tali immagini</string>\n    <string name=\"default_draw_color\">Colore di disegno predefinito</string>\n    <string name=\"default_draw_path_mode\">Modalità di tracciamento predefinita</string>\n    <string name=\"add_timestamp\">Aggiungi timestamp</string>\n    <string name=\"add_timestamp_sub\">Abilita l\\'aggiunta del timestamp al nome del file di output</string>\n    <string name=\"formatted_timestamp\">Timestamp formattato</string>\n    <string name=\"formatted_timestamp_sub\">Abilita la formattazione del timestamp nel nome del file di output anziché nei millis di base</string>\n    <string name=\"enable_timestamps_to_format_them\">Abilita Timestamp per selezionarne il formato</string>\n    <string name=\"one_time_save_location\">Salvataggio della posizione una volta</string>\n    <string name=\"one_time_save_location_sub\">Visualizza e modifica le posizioni di salvataggio una tantum che puoi utilizzare premendo a lungo il pulsante di salvataggio nella maggior parte delle opzioni</string>\n    <string name=\"recently_used\">Usato di recente</string>\n    <string name=\"ci_channel\">CI channel</string>\n    <string name=\"group\">Gruppo</string>\n    <string name=\"image_toolbox_in_telegram\">Casella degli strumenti per immagini in Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Unisciti alla nostra chat dove puoi discutere di tutto ciò che desideri e guarda anche il canale CI dove pubblico beta e annunci</string>\n    <string name=\"ci_channel_sub\">Ricevi notifiche sulle nuove versioni dell\\'app e leggi gli annunci</string>\n    <string name=\"fit_description\">Adatta un\\'immagine alle dimensioni specificate e applica sfocatura o colore allo sfondo</string>\n    <string name=\"tools_arrangement\">Disposizione degli strumenti</string>\n    <string name=\"group_tools_by_type\">Raggruppare gli strumenti per tipo</string>\n    <string name=\"group_tools_by_type_sub\">Raggruppa gli strumenti nella schermata principale in base al tipo anziché a una disposizione di elenchi personalizzata</string>\n    <string name=\"default_values\">Valori predefiniti</string>\n    <string name=\"system_bars_visibility\">Visibilità delle barre di sistema</string>\n    <string name=\"show_system_bars_by_swipe\">Mostra le barre di sistema tramite scorrimento</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Consente lo scorrimento per mostrare le barre di sistema se sono nascoste</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Nascondi tutto</string>\n    <string name=\"show_all\">Mostra tutto</string>\n    <string name=\"hide_nav_bar\">Nascondi barra di navigazione</string>\n    <string name=\"hide_status_bar\">Nascondi barra di stato</string>\n    <string name=\"noise_generation\">Generazione di rumore</string>\n    <string name=\"noise_generation_sub\">Genera rumori diversi come Perlin o altri tipi</string>\n    <string name=\"frequency\">Frequenza</string>\n    <string name=\"noise_type\">Tipo di rumore</string>\n    <string name=\"rotation_type\">Tipo di rotazione</string>\n    <string name=\"fractal_type\">Tipo frattale</string>\n    <string name=\"octaves\">Ottave</string>\n    <string name=\"lacunarity\">Lacunarità</string>\n    <string name=\"gain\">Guadagno</string>\n    <string name=\"weighted_strength\">Forza ponderata</string>\n    <string name=\"ping_pong_strength\">Forza del ping pong</string>\n    <string name=\"distance_function\">Funzione Distanza</string>\n    <string name=\"return_type\">Tipo di reso</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Deformazione del dominio</string>\n    <string name=\"alignment\">Allineamento</string>\n    <string name=\"custom_filename\">Nome file personalizzato</string>\n    <string name=\"custom_filename_sub\">Seleziona la posizione e il nome del file che verranno utilizzati per salvare l\\'immagine corrente</string>\n    <string name=\"saved_to_custom\">Salvato nella cartella con nome personalizzato</string>\n    <string name=\"collage_maker\">Creatore di collage</string>\n    <string name=\"collage_maker_sub\">Realizza collage contenenti fino a 20 immagini</string>\n    <string name=\"collage_type\">Tipo di collage</string>\n    <string name=\"collages_info\">Tieni l\\'immagine per scambiare, spostare e ingrandire per regolare la posizione</string>\n    <string name=\"disable_rotation\">Disabilita rotazione</string>\n    <string name=\"disable_rotation_sub\">Impedisce la rotazione delle immagini con i gesti con due dita</string>\n    <string name=\"enable_snapping_to_borders\">Abilita l\\'aggancio ai bordi</string>\n    <string name=\"enable_snapping_to_borders_sub\">Dopo lo spostamento o lo zoom, le immagini verranno agganciate per riempire i bordi della cornice</string>\n    <string name=\"histogram\">Istogramma</string>\n    <string name=\"histogram_sub\">Istogramma dell\\'immagine RGB o luminosità per aiutarti a apportare modifiche</string>\n    <string name=\"image_for_histogram\">Questa immagine verrà utilizzata per generare istogrammi RGB e luminosità</string>\n    <string name=\"tesseract_options\">Opzioni Tesseract</string>\n    <string name=\"tesseract_options_sub\">Applica alcune variabili di input per il motore tesseract</string>\n    <string name=\"custom_options\">Opzioni personalizzate</string>\n    <string name=\"custom_params_info\">Le opzioni devono essere inserite seguendo questo schema: \\\"--{nome_opzione} {valore}\\\"</string>\n    <string name=\"auto_crop\">Ritaglio automatico</string>\n    <string name=\"free_corners\">Angoli liberi</string>\n    <string name=\"free_corners_sub\">Ritaglia l\\'immagine per poligono, questo corregge anche la prospettiva</string>\n    <string name=\"coerce_points_to_image_bounds\">Coercizione dei punti sui limiti dell\\'immagine</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">I punti non saranno limitati dai limiti dell\\'immagine, il che è utile per una correzione prospettica più precisa</string>\n    <string name=\"mask\">Maschera</string>\n    <string name=\"spot_heal_sub\">Riempimento consapevole del contenuto sotto il percorso disegnato</string>\n    <string name=\"spot_heal\">Punto di guarigione</string>\n    <string name=\"use_circle_kernel\">Usa Circle Kernel</string>\n    <string name=\"opening\">Apertura</string>\n    <string name=\"closing\">Chiusura</string>\n    <string name=\"morphological_gradient\">Gradiente morfologico</string>\n    <string name=\"top_hat\">Cappello a cilindro</string>\n    <string name=\"black_hat\">Cappello Nero</string>\n    <string name=\"tone_curves\">Curve di tono</string>\n    <string name=\"reset_curves\">Reimposta curve</string>\n    <string name=\"reset_curves_sub\">Le curve verranno ripristinate al valore predefinito</string>\n    <string name=\"line_style\">Stile linea</string>\n    <string name=\"gap_size\">Dimensione spazio</string>\n    <string name=\"dashed\">Tratteggiato</string>\n    <string name=\"dot_dashed\">Punto tratteggiato</string>\n    <string name=\"stamped\">Timbrato</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Disegna una linea tratteggiata lungo il percorso disegnato con la dimensione dello spazio specificata</string>\n    <string name=\"dot_dashed_sub\">Disegna una linea punto e tratteggiata lungo il percorso indicato</string>\n    <string name=\"defaultt_sub\">Solo linee rette predefinite</string>\n    <string name=\"stamped_sub\">Disegna le forme selezionate lungo il percorso con la spaziatura specificata</string>\n    <string name=\"zigzag_sub\">Disegna zigzag ondulati lungo il percorso</string>\n    <string name=\"zigzag_ratio\">Rapporto a zigzag</string>\n    <string name=\"create_shortcut\">Crea collegamento</string>\n    <string name=\"create_shortcut_title\">Scegli lo strumento da appuntare</string>\n    <string name=\"create_shortcut_subtitle\">Lo strumento verrà aggiunto alla schermata iniziale del programma di avvio come scorciatoia, utilizzalo in combinazione con l\\'impostazione \\\"Salta selezione file\\\" per ottenere il comportamento necessario</string>\n    <string name=\"dont_stack_frames\">Non impilare i fotogrammi</string>\n    <string name=\"dont_stack_frames_sub\">Abilita l\\'eliminazione dei fotogrammi precedenti, in modo che non si accumulino l\\'uno sull\\'altro</string>\n    <string name=\"crossfade\">Dissolvenza incrociata</string>\n    <string name=\"crossfade_sub\">I fotogrammi verranno sfumati l\\'uno nell\\'altro</string>\n    <string name=\"crossfade_count\">Conteggio dei fotogrammi di dissolvenza incrociata</string>\n    <string name=\"threshold_one\">Soglia Uno</string>\n    <string name=\"threshold_two\">Soglia Due</string>\n    <string name=\"canny\">Astuto</string>\n    <string name=\"mirror_101\">Specchio 101</string>\n    <string name=\"enhanced_zoom_blur\">Sfocatura zoom migliorata</string>\n    <string name=\"laplacian_simple\">Laplaciano semplice</string>\n    <string name=\"sobel_simple\">Sobel Semplice</string>\n    <string name=\"helper_grid\">Griglia di aiuto</string>\n    <string name=\"helper_grid_sub\">Mostra la griglia di supporto sopra l\\'area di disegno per facilitare le manipolazioni precise</string>\n    <string name=\"grid_color\">Colore della griglia</string>\n    <string name=\"cell_width\">Larghezza della cella</string>\n    <string name=\"cell_height\">Altezza della cella</string>\n    <string name=\"compact_selectors\">Selettori compatti</string>\n    <string name=\"compact_selectors_sub\">Alcuni controlli di selezione utilizzeranno un layout compatto per occupare meno spazio</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Concedi l\\'autorizzazione alla fotocamera nelle impostazioni per acquisire l\\'immagine</string>\n    <string name=\"layout\">Disposizione</string>\n    <string name=\"main_screen_title\">Titolo della schermata principale</string>\n    <string name=\"constant_rate_factor\">Fattore di tasso costante (CRF)</string>\n    <string name=\"crf_sub\">Un valore di %1$s indica una compressione lenta, che risulta in una dimensione del file relativamente piccola. %2$s significa una compressione più veloce, che risulta in un file di grandi dimensioni.</string>\n    <string name=\"lut_library\">Biblioteca Lut</string>\n    <string name=\"lut_library_sub\">Scarica la raccolta di LUT, che puoi applicare dopo il download</string>\n    <string name=\"lut_library_update_sub\">Aggiorna la raccolta di LUT (solo quelle nuove verranno messe in coda), che puoi applicare dopo il download</string>\n    <string name=\"filter_preview_image_sub\">Modifica l\\'anteprima dell\\'immagine predefinita per i filtri</string>\n    <string name=\"filter_preview_image\">Anteprima immagine</string>\n    <string name=\"hide\">Nascondere</string>\n    <string name=\"show\">Spettacolo</string>\n    <string name=\"slider_type\">Tipo di cursore</string>\n    <string name=\"fancy\">Fantasia</string>\n    <string name=\"material_2\">Materiale 2</string>\n    <string name=\"fancy_sub\">Uno slider dall\\'aspetto fantasioso. Questa è l\\'opzione predefinita</string>\n    <string name=\"material_2_sub\">Un cursore Materiale 2</string>\n    <string name=\"material_you_slider_sub\">Uno slider Materiale Tu</string>\n    <string name=\"apply\">Fare domanda a</string>\n    <string name=\"center_align_dialog_buttons\">Pulsanti della finestra di dialogo centrale</string>\n    <string name=\"center_align_dialog_buttons_sub\">I pulsanti delle finestre di dialogo verranno posizionati al centro anziché a sinistra, se possibile</string>\n    <string name=\"open_source_licenses\">Licenze Open Source</string>\n    <string name=\"open_source_licenses_sub\">Visualizza le licenze delle librerie open source utilizzate in questa app</string>\n    <string name=\"area\">Zona</string>\n    <string name=\"area_sub\">Ricampionamento utilizzando la relazione dell\\'area dei pixel. Potrebbe essere il metodo preferito per la decimazione delle immagini, poiché fornisce risultati privi di effetto moiré. Ma quando l\\'immagine viene ingrandita, è simile al metodo \\\"Più vicino\\\".</string>\n    <string name=\"enable_tonemapping\">Abilita la mappatura dei toni</string>\n    <string name=\"enter_percent\">Inserisci %</string>\n    <string name=\"unknown_host\">Impossibile accedere al sito, provare a utilizzare la VPN o verificare se l\\'URL è corretto</string>\n    <string name=\"markup_layers\">Livelli di marcatura</string>\n    <string name=\"markup_layers_sub\">Modalità livelli con possibilità di posizionare liberamente immagini, testo e altro</string>\n    <string name=\"edit_layer\">Modifica livello</string>\n    <string name=\"layers_on_image\">Strati sull\\'immagine</string>\n    <string name=\"layers_on_image_sub\">Usa un\\'immagine come sfondo e aggiungi diversi livelli sopra di essa</string>\n    <string name=\"layers_on_background\">Strati sullo sfondo</string>\n    <string name=\"layers_on_background_sub\">Come la prima opzione, ma con il colore anziché l\\'immagine</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Lato Impostazioni veloci</string>\n    <string name=\"fast_settings_side_sub\">Aggiungi una striscia mobile sul lato selezionato durante la modifica delle immagini, che aprirà le impostazioni rapide quando si fa clic</string>\n    <string name=\"clear_selection\">Cancella selezione</string>\n    <string name=\"settings_group_visibility_hidden\">Il gruppo di impostazioni \\\"%1$s\\\" verrà compresso per impostazione predefinita</string>\n    <string name=\"settings_group_visibility_visible\">Il gruppo di impostazioni \\\"%1$s\\\" verrà espanso per impostazione predefinita</string>\n    <string name=\"base_64_tools\">Strumenti Base64</string>\n    <string name=\"base_64_tools_sub\">Decodifica la stringa Base64 in immagine o codifica l\\'immagine in formato Base64</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">Il valore fornito non è una stringa Base64 valida</string>\n    <string name=\"copy_not_a_valid_base_64\">Impossibile copiare una stringa Base64 vuota o non valida</string>\n    <string name=\"paste_base_64\">Incolla Base64</string>\n    <string name=\"copy_base_64\">Copia Base64</string>\n    <string name=\"base_64_tips\">Carica l\\'immagine per copiare o salvare la stringa Base64. Se hai la stringa stessa, puoi incollarla sopra per ottenere l\\'immagine</string>\n    <string name=\"save_base_64\">Salva Base64</string>\n    <string name=\"share_base_64\">Condividi Base64</string>\n    <string name=\"options\">Opzioni</string>\n    <string name=\"actions\">Azioni</string>\n    <string name=\"import_base_64\">Importa Base64</string>\n    <string name=\"base_64_actions\">Azioni Base64</string>\n    <string name=\"add_outline\">Aggiungi contorno</string>\n    <string name=\"add_outline_sub\">Aggiungi un contorno attorno al testo con il colore e la larghezza specificati</string>\n    <string name=\"outline_color\">Colore contorno</string>\n    <string name=\"outline_size\">Dimensione del contorno</string>\n    <string name=\"rotation\">Rotazione</string>\n    <string name=\"checksum_as_filename\">Checksum come nome file</string>\n    <string name=\"checksum_as_filename_sub\">Le immagini di output avranno un nome corrispondente al checksum dei dati</string>\n    <string name=\"free_software_partner\">Software gratuito (partner)</string>\n    <string name=\"free_software_partner_sub\">Software più utile nel canale partner delle applicazioni Android</string>\n    <string name=\"algorithms\">Algoritmo</string>\n    <string name=\"checksum_tools\">Strumenti per il checksum</string>\n    <string name=\"checksum_tools_sub\">Confronta checksum, calcola hash o crea stringhe esadecimali da file utilizzando diversi algoritmi di hashing</string>\n    <string name=\"calculate\">Calcolare</string>\n    <string name=\"text_hash\">Hash di testo</string>\n    <string name=\"checksum\">Somma di controllo</string>\n    <string name=\"pick_file_to_checksum\">Scegli il file per calcolarne il checksum in base all\\'algoritmo selezionato</string>\n    <string name=\"enter_text_to_checksum\">Inserisci il testo per calcolare il checksum in base all\\'algoritmo selezionato</string>\n    <string name=\"source_checksum\">Checksum della fonte</string>\n    <string name=\"checksum_to_compare\">Checksum per confrontare</string>\n    <string name=\"match\">Incontro!</string>\n    <string name=\"difference\">Differenza</string>\n    <string name=\"match_sub\">I checksum sono uguali, può essere sicuro</string>\n    <string name=\"difference_sub\">I checksum non sono uguali, il file può essere pericoloso!</string>\n    <string name=\"mesh_gradients\">Gradienti della maglia</string>\n    <string name=\"collection_mesh_gradients_sub\">Guarda la raccolta online di gradienti mesh</string>\n    <string name=\"wrong_font\">È possibile importare solo i caratteri TTF e OTF</string>\n    <string name=\"import_font\">Importa carattere (TTF/OTF)</string>\n    <string name=\"export_fonts\">Esporta caratteri</string>\n    <string name=\"imported_fonts\">Caratteri importati</string>\n    <string name=\"error_while_saving\">Errore durante il tentativo di salvataggio, prova a cambiare la cartella di output</string>\n    <string name=\"filename_is_not_set\">Il nome del file non è impostato</string>\n    <string name=\"none\">Nessuno</string>\n    <string name=\"custom_pages\">Pagine personalizzate</string>\n    <string name=\"pages_selection\">Selezione delle pagine</string>\n    <string name=\"tool_exit_confirmation\">Conferma uscita strumento</string>\n    <string name=\"tool_exit_confirmation_sub\">Se sono presenti modifiche non salvate durante l\\'utilizzo di strumenti particolari e provi a chiuderlo, verrà visualizzata la finestra di dialogo di conferma</string>\n    <string name=\"edit_exif_screen\">Modifica EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Modifica i metadati di una singola immagine senza ricompressione</string>\n    <string name=\"edit_exif_tag\">Tocca per modificare i tag disponibili</string>\n    <string name=\"change_sticker\">Cambia adesivo</string>\n    <string name=\"fit_width\">Adatta larghezza</string>\n    <string name=\"fit_height\">Adatta all\\'altezza</string>\n    <string name=\"batch_compare\">Confronto batch</string>\n    <string name=\"pick_files_to_checksum\">Scegli uno o più file per calcolarne il checksum in base all\\'algoritmo selezionato</string>\n    <string name=\"pick_files\">Scegli file</string>\n    <string name=\"pick_directory\">Scegli Directory</string>\n    <string name=\"head_length_scale\">Scala della lunghezza della testa</string>\n    <string name=\"stamp\">Timbro</string>\n    <string name=\"timestamp\">Timestamp</string>\n    <string name=\"format_pattern\">Modello di formato</string>\n    <string name=\"padding\">Imbottitura</string>\n    <string name=\"image_cutting\">Taglio dell\\'immagine</string>\n    <string name=\"image_cutting_sub\">Taglia la parte dell\\'immagine e unisci quelle di sinistra (può essere inverso) tramite linee verticali o orizzontali</string>\n    <string name=\"vertical_pivot_line\">Linea pivot verticale</string>\n    <string name=\"horizontal_pivot_line\">Linea pivot orizzontale</string>\n    <string name=\"inverse_selection\">Selezione inversa</string>\n    <string name=\"inverse_vertical_selection_sub\">La parte tagliata verticale verrà lasciata, invece di unire le parti attorno all\\'area tagliata</string>\n    <string name=\"inverse_horizontal_selection_sub\">La parte tagliata orizzontale verrà lasciata, invece di unire le parti attorno all\\'area tagliata</string>\n    <string name=\"collection_mesh_gradients\">Raccolta di gradienti di mesh</string>\n    <string name=\"mesh_gradients_sub\">Crea gradiente mesh con quantità personalizzata di nodi e risoluzione</string>\n    <string name=\"gradient_maker_type_image_mesh\">Sovrapposizione sfumatura mesh</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Componi il gradiente mesh della parte superiore delle immagini specificate</string>\n    <string name=\"points_customization\">Personalizzazione dei punti</string>\n    <string name=\"grid_size\">Dimensione della griglia</string>\n    <string name=\"resolution_x\">Risoluzione X</string>\n    <string name=\"resolution_y\">Risoluzione Y</string>\n    <string name=\"resolution\">Risoluzione</string>\n    <string name=\"pixel_by_pixel\">Pixel per pixel</string>\n    <string name=\"highlight_color\">Evidenzia colore</string>\n    <string name=\"pixel_comparison_type\">Tipo di confronto pixel</string>\n    <string name=\"scan_barcode\">Scansiona il codice a barre</string>\n    <string name=\"height_ratio\">Rapporto altezza</string>\n    <string name=\"barcode_type\">Tipo di codice a barre</string>\n    <string name=\"enforce_bw\">Applica B/N</string>\n    <string name=\"enforce_bw_sub\">L\\'immagine del codice a barre sarà completamente in bianco e nero e non sarà colorata in base al tema dell\\'app</string>\n    <string name=\"barcodes_sub\">Scansiona qualsiasi codice a barre (QR, EAN, AZTEC, …) e ottieni il suo contenuto o incolla il testo per generarne uno nuovo</string>\n    <string name=\"no_barcode_found\">Nessun codice a barre trovato</string>\n    <string name=\"generated_barcode_will_be_here\">Il codice a barre generato sarà qui</string>\n    <string name=\"audio_cover_extractor\">Copertine audio</string>\n    <string name=\"audio_cover_extractor_sub\">Estrai le immagini delle copertine degli album dai file audio, sono supportati i formati più comuni</string>\n    <string name=\"pick_audio_to_start\">Scegli l\\'audio per iniziare</string>\n    <string name=\"pick_audio\">Scegli Audio</string>\n    <string name=\"no_covers_found\">Nessuna copertina trovata</string>\n    <string name=\"send_logs\">Invia registri</string>\n    <string name=\"send_logs_sub\">Fare clic per condividere il file di registro dell\\'app, questo può aiutarmi a individuare il problema e risolverlo</string>\n    <string name=\"crash_title\">Spiacenti… Qualcosa è andato storto</string>\n    <string name=\"crash_subtitle\">Puoi contattarmi utilizzando le opzioni di seguito e cercherò di trovare una soluzione.\\n(Non dimenticare di allegare i log)</string>\n    <string name=\"ocr_write_to_file\">Scrivi su file</string>\n    <string name=\"ocr_write_to_file_sub\">Estrai il testo da un batch di immagini e memorizzalo in un unico file di testo</string>\n    <string name=\"ocr_write_to_metadata\">Scrivi nei metadati</string>\n    <string name=\"ocr_write_to_metadata_sub\">Estrai il testo da ciascuna immagine e inseriscilo nelle informazioni EXIF ​​​​delle foto relative</string>\n    <string name=\"invisible_mode\">Modalità invisibile</string>\n    <string name=\"invisible_mode_sub\">Usa la steganografia per creare filigrane invisibili agli occhi all\\'interno dei byte delle tue immagini</string>\n    <string name=\"use_lsb\">Usa LSB</string>\n    <string name=\"use_lsb_sub\">Verrà utilizzato il metodo steganografia LSB (Less Significant Bit), altrimenti FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Rimuovi automaticamente gli occhi rossi</string>\n    <string name=\"password\">Password</string>\n    <string name=\"unlock\">Sbloccare</string>\n    <string name=\"pdf_is_protected\">Il PDF è protetto</string>\n    <string name=\"operation_almost_complete\">Operazione quasi completata. L\\'annullamento ora richiederà il riavvio</string>\n    <string name=\"sort_by_date_modified\">Data di modifica</string>\n    <string name=\"sort_by_date_modified_reversed\">Data di modifica (invertita)</string>\n    <string name=\"sort_by_size\">Misurare</string>\n    <string name=\"sort_by_size_reversed\">Dimensioni (invertite)</string>\n    <string name=\"sort_by_mime_type\">Tipo MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Tipo MIME (invertito)</string>\n    <string name=\"sort_by_extension\">Estensione</string>\n    <string name=\"sort_by_extension_reversed\">Estensione (invertita)</string>\n    <string name=\"sort_by_date_added\">Data aggiunta</string>\n    <string name=\"sort_by_date_added_reversed\">Data di aggiunta (invertita)</string>\n    <string name=\"left_to_right\">Da sinistra a destra</string>\n    <string name=\"right_to_left\">Da destra a sinistra</string>\n    <string name=\"top_to_bottom\">Dall\\'alto verso il basso</string>\n    <string name=\"bottom_to_top\">Dal basso verso l\\'alto</string>\n    <string name=\"liquid_glass\">Vetro liquido</string>\n    <string name=\"liquid_glass_sub\">Uno switch basato sull\\'IOS 26 recentemente annunciato e sul suo sistema di progettazione del vetro liquido</string>\n    <string name=\"pick_image_or_base64\">Scegli l\\'immagine o incolla/importa i dati Base64 di seguito</string>\n    <string name=\"type_image_link\">Digita il collegamento all\\'immagine per iniziare</string>\n    <string name=\"paste_link\">Incolla collegamento</string>\n    <string name=\"kaleidoscope\">Caleidoscopio</string>\n    <string name=\"secondary_angle\">Angolo secondario</string>\n    <string name=\"sides\">Lati</string>\n    <string name=\"channel_mix\">Miscelazione dei canali</string>\n    <string name=\"blue_green\">Verde blu</string>\n    <string name=\"red_blue\">Rosso blu</string>\n    <string name=\"green_red\">Verde rosso</string>\n    <string name=\"into_red\">Nel rosso</string>\n    <string name=\"into_green\">Nel verde</string>\n    <string name=\"into_blue\">Nel blu</string>\n    <string name=\"cyan\">Ciano</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Giallo</string>\n    <string name=\"color_halftone\">Mezzitoni a colori</string>\n    <string name=\"contour\">Contorno</string>\n    <string name=\"levels\">Livelli</string>\n    <string name=\"voronoi_crystallize\">Voronoi cristallizza</string>\n    <string name=\"shape\">Forma</string>\n    <string name=\"stretch\">Stirata</string>\n    <string name=\"randomness\">Casualità</string>\n    <string name=\"despeckle\">Smacchiare</string>\n    <string name=\"diffuse\">Diffondere</string>\n    <string name=\"dog\">Cane</string>\n    <string name=\"second_radius\">Secondo raggio</string>\n    <string name=\"equalize\">Pareggiare</string>\n    <string name=\"glow\">Incandescenza</string>\n    <string name=\"whirl_and_pinch\">Gira e pizzica</string>\n    <string name=\"pointillize\">Puntare</string>\n    <string name=\"polar_coordinates\">Coordinate polari</string>\n    <string name=\"rect_to_polar\">Rettangolo al polare</string>\n    <string name=\"polar_to_rect\">Polare per rettificare</string>\n    <string name=\"invert_in_circle\">Invertire in cerchio</string>\n    <string name=\"reduce_noise\">Riduci il rumore</string>\n    <string name=\"simple_solarize\">Solarizzazione semplice</string>\n    <string name=\"weave\">Tessere</string>\n    <string name=\"x_gap\">X divario</string>\n    <string name=\"y_gap\">Divario Y</string>\n    <string name=\"x_width\">Larghezza X</string>\n    <string name=\"y_wdth\">Larghezza Y</string>\n    <string name=\"twirl\">Girare</string>\n    <string name=\"rubber_stmp\">Timbro di gomma</string>\n    <string name=\"smear\">Spalmare</string>\n    <string name=\"density\">Densità</string>\n    <string name=\"mix\">Mescolare</string>\n    <string name=\"sphere_lensh_distortion\">Distorsione della lente sferica</string>\n    <string name=\"moire\">Maria</string>\n    <string name=\"autumn\">Autunno</string>\n    <string name=\"bone\">Osso</string>\n    <string name=\"jet\">Getto</string>\n    <string name=\"winter\">Inverno</string>\n    <string name=\"ocean\">Oceano</string>\n    <string name=\"summer\">Estate</string>\n    <string name=\"spring\">Primavera</string>\n    <string name=\"cool_variant\">Variante interessante</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rosa</string>\n    <string name=\"hot\">Caldo</string>\n    <string name=\"parula\">Parola</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Cittadini</string>\n    <string name=\"twilight\">Crepuscolo</string>\n    <string name=\"twilight_shifted\">Crepuscolo spostato</string>\n    <string name=\"auto_perspective\">Prospettiva automatica</string>\n    <string name=\"deskew\">Allineamento</string>\n    <string name=\"allow_crop\">Consenti ritaglio</string>\n    <string name=\"crop_or_perspective\">Ritaglia o Prospettiva</string>\n    <string name=\"absolute\">Assoluto</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Verde intenso</string>\n    <string name=\"lens_correction\">Correzione dell\\'obiettivo</string>\n    <string name=\"target_lens_profile\">File del profilo dell\\'obiettivo target in formato JSON</string>\n    <string name=\"download_ready_lens_profiles\">Scarica i profili obiettivo pronti</string>\n    <string name=\"part_percents\">Percentuali di parte</string>\n    <string name=\"export_as_json\">Esporta come JSON</string>\n    <string name=\"export_as_json_sub\">Copia una stringa con i dati di una tavolozza come rappresentazione JSON</string>\n    <string name=\"seam_carving\">Intaglio della cucitura</string>\n    <string name=\"home_screen\">Schermata iniziale</string>\n    <string name=\"lock_screen\">Schermata di blocco</string>\n    <string name=\"built_in\">Integrato</string>\n    <string name=\"wallpapers_export\">Esportazione di sfondi</string>\n    <string name=\"refresh\">Aggiorna</string>\n    <string name=\"wallpapers_export_sub\">Ottieni gli sfondi attuali per la casa, il blocco e gli sfondi integrati</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Consenti l\\'accesso a tutti i file, è necessario per recuperare gli sfondi</string>\n    <string name=\"allow_read_media_images_for_wp\">L\\'autorizzazione per gestire l\\'archiviazione esterna non è sufficiente, devi consentire l\\'accesso alle tue immagini, assicurati di selezionare \\\"Consenti tutto\\\"</string>\n    <string name=\"add_preset_to_filename\">Aggiungi preimpostazione al nome file</string>\n    <string name=\"add_preset_to_filename_sub\">Aggiunge il suffisso con la preimpostazione selezionata al nome del file immagine</string>\n    <string name=\"add_image_scale_mode_to_filename\">Aggiungi la modalità scala immagine al nome file</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Aggiunge il suffisso con la modalità di scala dell\\'immagine selezionata al nome del file dell\\'immagine</string>\n    <string name=\"ascii_art\">Arte Ascii</string>\n    <string name=\"ascii_art_sub\">Converti l\\'immagine in testo ASCII che assomiglierà all\\'immagine</string>\n    <string name=\"params\">Param</string>\n    <string name=\"invert_colors_ascii_sub\">Applica il filtro negativo all\\'immagine per ottenere risultati migliori in alcuni casi</string>\n    <string name=\"processing_screenshot\">Schermata di elaborazione</string>\n    <string name=\"screenshot_not_captured_try_again\">Screenshot non catturato, riprova</string>\n    <string name=\"skipped_saving\">Salvataggio saltato</string>\n    <string name=\"skipped_saving_multiple\">%1$s file ignorati</string>\n    <string name=\"allow_skip_if_larger\">Consenti Salta se più grande</string>\n    <string name=\"allow_skip_if_larger_sub\">Ad alcuni strumenti sarà consentito saltare il salvataggio delle immagini se la dimensione del file risultante è maggiore dell\\'originale</string>\n    <string name=\"qr_type_calendar_event\">Evento del calendario</string>\n    <string name=\"qr_type_contact_info\">Contatto</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Posizione</string>\n    <string name=\"qr_type_phone\">Telefono</string>\n    <string name=\"qr_type_plain\">Testo</string>\n    <string name=\"qr_type_sms\">sms</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wifi</string>\n    <string name=\"open_network\">Rete aperta</string>\n    <string name=\"not_specified\">N / A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefono</string>\n    <string name=\"message\">Messaggio</string>\n    <string name=\"address\">Indirizzo</string>\n    <string name=\"subject\">Soggetto</string>\n    <string name=\"body\">Corpo</string>\n    <string name=\"name\">Nome</string>\n    <string name=\"organization\">Organizzazione</string>\n    <string name=\"title\">Titolo</string>\n    <string name=\"phones\">Telefoni</string>\n    <string name=\"emails\">E-mail</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Indirizzi</string>\n    <string name=\"summary\">Riepilogo</string>\n    <string name=\"description\">Descrizione</string>\n    <string name=\"location\">Posizione</string>\n    <string name=\"organizer\">Organizzatore</string>\n    <string name=\"start_date\">Data di inizio</string>\n    <string name=\"end_date\">Data di fine</string>\n    <string name=\"status\">Stato</string>\n    <string name=\"latitude\">Latitudine</string>\n    <string name=\"longitude\">Longitudine</string>\n    <string name=\"create_barcode\">Crea codice a barre</string>\n    <string name=\"edit_barcode\">Modifica codice a barre</string>\n    <string name=\"wifi_configuration\">Configurazione Wi-Fi</string>\n    <string name=\"security\">Sicurezza</string>\n    <string name=\"pick_contact\">Scegli il contatto</string>\n    <string name=\"grant_contact_permission\">Concedi ai contatti l\\'autorizzazione nelle impostazioni per il riempimento automatico utilizzando il contatto selezionato</string>\n    <string name=\"contact_info\">Informazioni di contatto</string>\n    <string name=\"first_name\">Nome di battesimo</string>\n    <string name=\"middle_name\">Secondo nome</string>\n    <string name=\"last_name\">Cognome</string>\n    <string name=\"pronunciation\">Pronuncia</string>\n    <string name=\"add_phone\">Aggiungi telefono</string>\n    <string name=\"add_email\">Aggiungi e-mail</string>\n    <string name=\"add_address\">Aggiungi indirizzo</string>\n    <string name=\"website\">Sito web</string>\n    <string name=\"add_website\">Aggiungi sito web</string>\n    <string name=\"formatted_name\">Nome formattato</string>\n    <string name=\"qr_code_top_image\">Questa immagine verrà utilizzata per posizionare sopra il codice a barre</string>\n    <string name=\"code_customization\">Personalizzazione del codice</string>\n    <string name=\"qr_logo_image\">Questa immagine verrà utilizzata come logo al centro del codice QR</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Imbottitura logata</string>\n    <string name=\"logo_size\">Dimensioni del logo</string>\n    <string name=\"logo_corners\">Angoli del logo</string>\n    <string name=\"fourth_eye\">Quarto occhio</string>\n    <string name=\"fourth_eye_description\">Aggiunge la simmetria dell\\'occhio al codice QR aggiungendo il quarto occhio nell\\'angolo inferiore</string>\n    <string name=\"pixel_shape\">Forma pixelata</string>\n    <string name=\"frame_shape\">Forma del telaio</string>\n    <string name=\"ball_shape\">Forma a palla</string>\n    <string name=\"error_correction_level\">Livello di correzione degli errori</string>\n    <string name=\"dark_color\">Colore scuro</string>\n    <string name=\"light_color\">Colore chiaro</string>\n    <string name=\"hyper_os\">Sistema operativo iper</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS come lo stile</string>\n    <string name=\"mask_pattern\">Modello di maschera</string>\n    <string name=\"code_may_be_not_scannable\">Questo codice potrebbe non essere scansionabile, modificare i parametri di aspetto per renderlo leggibile con tutti i dispositivi</string>\n    <string name=\"not_scannable\">Non scansionabile</string>\n    <string name=\"launcher_mode_sub\">Gli strumenti assomiglieranno all\\'avvio delle app della schermata iniziale per essere più compatti</string>\n    <string name=\"launcher_mode\">Modalità di avvio</string>\n    <string name=\"flood_fill_sub\">Riempie un\\'area con il pennello e lo stile selezionati</string>\n    <string name=\"flood_fill\">Riempimento</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Disegna un percorso in stile graffito</string>\n    <string name=\"square_particles\">Particelle quadrate</string>\n    <string name=\"square_particles_sub\">Le particelle dello spray saranno di forma quadrata invece che circolare</string>\n    <string name=\"palette_tools\">Strumenti tavolozza</string>\n    <string name=\"palette_tools_sub\">Genera base/materiale per la tavolozza dall\\'immagine o importa/esporta tra diversi formati di tavolozza</string>\n    <string name=\"edit_palette\">Modifica tavolozza</string>\n    <string name=\"edit_palette_sub\">Esporta/importa tavolozza in vari formati</string>\n    <string name=\"color_name\">Nome del colore</string>\n    <string name=\"palette_name\">Nome della tavolozza</string>\n    <string name=\"palette_format\">Formato tavolozza</string>\n    <string name=\"export_palette_sub\">Esporta la tavolozza generata in diversi formati</string>\n    <string name=\"add_color_palette_sub\">Aggiunge un nuovo colore alla tavolozza corrente</string>\n    <string name=\"palette_name_not_supported\">Il formato %1$s non supporta l\\'indicazione del nome della tavolozza</string>\n    <string name=\"wallpapers_export_not_avaialbe\">A causa delle politiche del Play Store, questa funzionalità non può essere inclusa nella build attuale. Per accedere a questa funzionalità, scarica ImageToolbox da una fonte alternativa. Di seguito puoi trovare le build disponibili su GitHub.</string>\n    <string name=\"open_github_page\">Apri la pagina Github</string>\n    <string name=\"overwrite_files_sub_short\">Il file originale verrà sostituito con uno nuovo invece di essere salvato nella cartella selezionata</string>\n    <string name=\"hidden_watermark_text_detected\">Rilevato testo di filigrana nascosto</string>\n    <string name=\"hidden_watermark_image_detected\">Rilevata immagine filigrana nascosta</string>\n    <string name=\"this_image_was_hidden\">Questa immagine era nascosta</string>\n    <string name=\"generative_inpaint\">Pittura generativa</string>\n    <string name=\"generative_inpaint_sub\">Ti consente di rimuovere oggetti in un\\'immagine utilizzando un modello AI, senza fare affidamento su OpenCV. Per utilizzare questa funzione, l\\'app scaricherà il modello richiesto (~200 MB) da GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Ti consente di rimuovere oggetti in un\\'immagine utilizzando un modello AI, senza fare affidamento su OpenCV. Potrebbe trattarsi di un\\'operazione a lungo termine</string>\n    <string name=\"error_level_analysis\">Analisi del livello di errore</string>\n    <string name=\"luminance_gradient\">Gradiente di luminanza</string>\n    <string name=\"average_distance\">Distanza media</string>\n    <string name=\"copy_move_detection\">Rilevamento spostamento copia</string>\n    <string name=\"retain\">Conservare</string>\n    <string name=\"coefficent\">Coefficiente</string>\n    <string name=\"clipboard_data_is_too_large\">I dati degli appunti sono troppo grandi</string>\n    <string name=\"data_is_too_large_to_copy\">I dati sono troppo grandi per essere copiati</string>\n    <string name=\"simple_weave_pixelization\">Pixelizzazione della trama semplice</string>\n    <string name=\"staggered_pixelization\">Pixelizzazione sfalsata</string>\n    <string name=\"cross_pixelization\">Pixelizzazione incrociata</string>\n    <string name=\"micro_macro_pixelization\">Micro macro pixelizzazione</string>\n    <string name=\"orbital_pixelization\">Pixelizzazione orbitale</string>\n    <string name=\"vortex_pixelization\">Pixelizzazione del vortice</string>\n    <string name=\"pulse_grid_pixelization\">Pixelizzazione della griglia di impulsi</string>\n    <string name=\"nucleus_pixelization\">Pixelizzazione del nucleo</string>\n    <string name=\"radial_weave_pixelization\">Pixelizzazione della trama radiale</string>\n    <string name=\"cannot_open_uri\">Impossibile aprire l\\'URI \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Modalità nevicata</string>\n    <string name=\"enabled\">Abilitato</string>\n    <string name=\"border_frame\">Cornice di confine</string>\n    <string name=\"glitch_variant\">Variante glitch</string>\n    <string name=\"channel_shift\">Cambio di canale</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blocco problema tecnico</string>\n    <string name=\"block_size\">Dimensione del blocco</string>\n    <string name=\"crt_curvature\">Curvatura del cinescopio</string>\n    <string name=\"curvature\">Curvatura</string>\n    <string name=\"chroma\">Croma</string>\n    <string name=\"pixel_melt\">Pixel Fusione</string>\n    <string name=\"max_drop\">Caduta massima</string>\n    <string name=\"ai_tools\">Strumenti di intelligenza artificiale</string>\n    <string name=\"ai_tools_sub\">Vari strumenti per elaborare le immagini attraverso modelli di intelligenza artificiale come la rimozione degli artefatti o la riduzione del rumore</string>\n    <string name=\"model_anime_undeint\">Compressione, linee frastagliate</string>\n    <string name=\"model_broadcast\">Cartoni animati, compressione delle trasmissioni</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Compressione generale, rumore generale</string>\n    <string name=\"model_wb_denoise\">Rumore incolore dei cartoni animati</string>\n    <string name=\"model_span_anime_pretrain\">Veloce, compressione generale, rumore generale, animazione/fumetti/anime</string>\n    <string name=\"model_book_scan\">Scansione di libri</string>\n    <string name=\"model_overexposure\">Correzione dell\\'esposizione</string>\n    <string name=\"model_fbcnn_color_fp16\">Migliore per compressione generale, immagini a colori</string>\n    <string name=\"model_fbcnn_gray_fp16\">Migliore per compressione generale, immagini in scala di grigi</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Compressione generale, immagini in scala di grigi, più forti</string>\n    <string name=\"model_scunet_color_gan_fp16\">Rumore generale, immagini a colori</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Rumore generale, immagini a colori, dettagli migliori</string>\n    <string name=\"model_scunet_gray_15_fp16\">Rumore generale, immagini in scala di grigi</string>\n    <string name=\"model_scunet_gray_25_fp16\">Rumore generale, immagini in scala di grigi, più forte</string>\n    <string name=\"model_scunet_gray_50_fp16\">Rumore generale, immagini in scala di grigi, più forte</string>\n    <string name=\"model_jpeg_destroyer\">Compressione generale</string>\n    <string name=\"model_jaywreck\">Compressione generale</string>\n    <string name=\"model_h264\">Texturizzazione, compressione h264</string>\n    <string name=\"model_vhs\">Compressione VHS</string>\n    <string name=\"model_cinepak\">Non-standard compression (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Compressione Bink, migliore sulla geometria</string>\n    <string name=\"model_debink_v5\">Compressione Bink, più forte</string>\n    <string name=\"model_debink_v6\">Compressione Bink, morbida, mantiene i dettagli</string>\n    <string name=\"model_antialias\">Elimina l\\'effetto scalino, levigante</string>\n    <string name=\"model_kdm_scans\">Grafica/disegni scansionati, leggera compressione, effetto moiré</string>\n    <string name=\"model_bandage\">Bande di colore</string>\n    <string name=\"model_halftone\">Lento, rimuovendo i mezzitoni</string>\n    <string name=\"model_colorizer\">Coloratore generale per immagini in scala di grigi/bianco e nero, per risultati migliori utilizzare DDColor</string>\n    <string name=\"model_deedge\">Rimozione dei bordi</string>\n    <string name=\"model_desharpen\">Rimuove l\\'eccessiva nitidezza</string>\n    <string name=\"model_dither\">Lento, esitante</string>\n    <string name=\"model_gainres\">Anti-aliasing, artefatti generali, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 esegue la scansione dell\\'elaborazione</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Modello leggero di miglioramento delle immagini</string>\n    <string name=\"model_bcgone_detailed_v2\">Rimozione degli artefatti da compressione</string>\n    <string name=\"model_bcgone_smooth\">Rimozione degli artefatti da compressione</string>\n    <string name=\"model_bandage_smooth\">Rimozione della benda con risultati uniformi</string>\n    <string name=\"model_bendel_halftone\">Elaborazione del motivo mezzitoni</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Rimozione del motivo dithering V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Rimozione artefatti JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Miglioramento della trama H.264</string>\n    <string name=\"model_vhs_sharpen\">Affilatura e miglioramento VHS</string>\n    <string name=\"merging\">Fusione</string>\n    <string name=\"chunk_size\">Dimensione del pezzo</string>\n    <string name=\"overlap_size\">Dimensioni sovrapposte</string>\n    <string name=\"note_chunk_info\">Le immagini superiori a %1$s px verranno tagliate ed elaborate in blocchi, la sovrapposizione le fonde per evitare cuciture visibili.</string>\n    <string name=\"large_chunk_warning\">Le grandi dimensioni possono causare instabilità con i dispositivi di fascia bassa</string>\n    <string name=\"select_one_to_start\">Selezionane uno per iniziare</string>\n    <string name=\"delete_model_sub\">Vuoi eliminare il modello %1$s? Dovrai scaricarlo di nuovo</string>\n    <string name=\"confirm\">Confermare</string>\n    <string name=\"models\">Modelli</string>\n    <string name=\"downloaded_models\">Modelli scaricati</string>\n    <string name=\"available_models\">Modelli disponibili</string>\n    <string name=\"preparing\">Preparazione</string>\n    <string name=\"active_model\">Modello attivo</string>\n    <string name=\"failed_to_open_session\">Impossibile aprire la sessione</string>\n    <string name=\"only_onnx_models\">È possibile importare solo modelli .onnx/.ort</string>\n    <string name=\"import_model\">Importa modello</string>\n    <string name=\"import_model_sub\">Importa il modello onnx personalizzato per un ulteriore utilizzo, sono accettati solo i modelli onnx/ort, supporta quasi tutte le varianti simili a esrgan</string>\n    <string name=\"imported_models\">Modelli importati</string>\n    <string name=\"model_scunet_color_15_fp16\">Rumore generale, immagini colorate</string>\n    <string name=\"model_scunet_color_25_fp16\">Rumore generale, immagini colorate, più forti</string>\n    <string name=\"model_scunet_color_50_fp16\">Rumore generale, immagini colorate, più forte</string>\n    <string name=\"model_artifacts_dithering_alsa\">Riduce gli artefatti dovuti al dithering e le bande di colore, migliorando le sfumature uniformi e le aree di colore piatte.</string>\n    <string name=\"model_nmkd_brighten_redux\">Migliora la luminosità e il contrasto dell\\'immagine con luci bilanciate preservando i colori naturali.</string>\n    <string name=\"model_nmkd_brighten\">Schiarisce le immagini scure mantenendo i dettagli ed evitando la sovraesposizione.</string>\n    <string name=\"model_nmkd_detoon\">Rimuove l\\'eccessivo viraggio del colore e ripristina un equilibrio cromatico più neutro e naturale.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Applica la tonalità del rumore basata su Poisson ponendo l\\'accento sulla conservazione dei dettagli e delle texture più fini.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Applica una tonalità morbida del rumore Poisson per risultati visivi più fluidi e meno aggressivi.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Tonalità del rumore uniforme focalizzata sulla conservazione dei dettagli e sulla chiarezza dell\\'immagine.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Tonificazione delicata e uniforme del rumore per una consistenza sottile e un aspetto liscio.</string>\n    <string name=\"model_repainter\">Ripara le aree danneggiate o irregolari ridipingendo gli artefatti e migliorando la coerenza dell\\'immagine.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Modello di debandatura leggero che rimuove le bande di colore con costi prestazionali minimi.</string>\n    <string name=\"model_jpeg_0_20\">Ottimizza le immagini con artefatti di compressione molto elevati (qualità 0-20%) per una maggiore chiarezza.</string>\n    <string name=\"model_jpeg_20_40\">Migliora le immagini con artefatti ad alta compressione (qualità 20-40%), ripristinando i dettagli e riducendo il rumore.</string>\n    <string name=\"model_jpeg_40_60\">Migliora le immagini con una compressione moderata (qualità 40-60%), bilanciando nitidezza e morbidezza.</string>\n    <string name=\"model_jpeg_60_80\">Perfeziona le immagini con una leggera compressione (qualità 60-80%) per migliorare i dettagli e le texture sottili.</string>\n    <string name=\"model_jpeg_80_100\">Migliora leggermente le immagini quasi senza perdita di dati (qualità 80-100%) preservando l\\'aspetto e i dettagli naturali.</string>\n    <string name=\"model_spongecolor_lite\">Colorazione semplice e veloce, cartoni animati, non ideale</string>\n    <string name=\"model_deblr\">Riduce leggermente la sfocatura dell\\'immagine, migliorando la nitidezza senza introdurre artefatti.</string>\n    <string name=\"processing_channel\">Operazioni di lunga durata</string>\n    <string name=\"processing_image\">Elaborazione dell\\'immagine</string>\n    <string name=\"processing\">Elaborazione</string>\n    <string name=\"model_artifacts_jpg_0_20\">Rimuove i pesanti artefatti di compressione JPEG in immagini di qualità molto bassa (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Riduce i forti artefatti JPEG nelle immagini altamente compresse (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Ripulisce gli artefatti JPEG moderati preservando i dettagli dell\\'immagine (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Perfeziona gli artefatti JPEG leggeri in immagini di qualità piuttosto elevata (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Riduce leggermente gli artefatti JPEG minori in immagini quasi senza perdita di dati (80-100%).</string>\n    <string name=\"model_redetail_v2\">Esalta i dettagli e le texture più fini, migliorando la nitidezza percepita senza artefatti pesanti.</string>\n    <string name=\"processing_finished\">Elaborazione terminata</string>\n    <string name=\"processing_failed\">Elaborazione non riuscita</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Migliora le texture e i dettagli della pelle mantenendo un aspetto naturale, ottimizzato per la velocità.</string>\n    <string name=\"model_sbdv_dejpeg\">Rimuove gli artefatti di compressione JPEG e ripristina la qualità dell\\'immagine per le foto compresse.</string>\n    <string name=\"model_iso_denoise_v1\">Riduce il rumore ISO nelle foto scattate in condizioni di scarsa illuminazione, preservando i dettagli.</string>\n    <string name=\"model_dejumbo\">Corregge le luci sovraesposte o \\\"jumbo\\\" e ripristina un migliore equilibrio tonale.</string>\n    <string name=\"model_ddcolor_tiny\">Modello di colorazione leggero e veloce che aggiunge colori naturali alle immagini in scala di grigi.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Eliminazione del rumore</string>\n    <string name=\"type_colorize\">Colora</string>\n    <string name=\"type_artifacts\">Artefatti</string>\n    <string name=\"type_enhance\">Migliorare</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Scansioni</string>\n    <string name=\"type_upscale\">Di lusso</string>\n    <string name=\"model_realesrgan_x4v3\">upscaler X4 per immagini generali; modello minuscolo che utilizza meno GPU e tempo, con deblur e denoise moderati.</string>\n    <string name=\"model_realesrgan_x2plus\">Upscaler X2 per immagini generali, preservando trame e dettagli naturali.</string>\n    <string name=\"model_realesrgan_x4plus\">Upscaler X4 per immagini generali con texture migliorate e risultati realistici.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Upscaler X4 ottimizzato per immagini anime; 6 blocchi RRDB per linee e dettagli più nitidi.</string>\n    <string name=\"model_realesrnet_x4plus\">L\\'upscaler X4 con perdita MSE, produce risultati più uniformi e artefatti ridotti per immagini generali.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler ottimizzato per immagini anime; Variante 4B32F con dettagli più nitidi e linee morbide.</string>\n    <string name=\"model_ultrasharp_v2_x4\">modello X4 UltraSharp V2 per immagini generali; enfatizza la nitidezza e la chiarezza.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; più veloce e più piccolo, preserva i dettagli utilizzando meno memoria GPU.</string>\n    <string name=\"model_rmbg_1_4\">Modello leggero per una rapida rimozione dello sfondo. Prestazioni e precisione bilanciate. Funziona con ritratti, oggetti e scene. Consigliato per la maggior parte dei casi d\\'uso.</string>\n    <string name=\"type_removebg\">Rimuovi BG</string>\n    <string name=\"horizontal_border_thickness\">Spessore del bordo orizzontale</string>\n    <string name=\"vertical_border_thickness\">Spessore del bordo verticale</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s colore</item>\n        <item quantity=\"other\">%1$s colori</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Il modello attuale non supporta il suddivisione in blocchi, l\\'immagine verrà elaborata nelle dimensioni originali, ciò potrebbe causare un elevato consumo di memoria e problemi con i dispositivi di fascia bassa</string>\n    <string name=\"chunking_disabled\">Chunking disabilitato, l\\'immagine verrà elaborata nelle dimensioni originali, ciò potrebbe causare un elevato consumo di memoria e problemi con i dispositivi di fascia bassa ma potrebbe fornire risultati migliori nell\\'inferenza</string>\n    <string name=\"chunking\">Spezzatura</string>\n    <string name=\"model_u2net\">Modello di segmentazione delle immagini ad alta precisione per la rimozione dello sfondo</string>\n    <string name=\"model_u2netp\">Versione leggera di U2Net per una rimozione dello sfondo più rapida con un utilizzo ridotto della memoria.</string>\n    <string name=\"model_ddcolor\">Il modello DDColor completo offre una colorazione di alta qualità per immagini generiche con artefatti minimi. La scelta migliore tra tutti i modelli di colorazione.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Set di dati artistici formati e privati; produce risultati di colorazione diversi e artistici con meno artefatti cromatici non realistici.</string>\n    <string name=\"model_birefnet\">Modello BiRefNet leggero basato su Swin Transformer per una rimozione accurata dello sfondo.</string>\n    <string name=\"model_inspyrenet\">Rimozione dello sfondo di alta qualità con bordi netti ed eccellente conservazione dei dettagli, soprattutto su oggetti complessi e sfondi difficili.</string>\n    <string name=\"model_isnet\">Modello di rimozione dello sfondo che produce maschere accurate con bordi smussati, adatte per oggetti generici e conservazione moderata dei dettagli.</string>\n    <string name=\"model_already_downloaded\">Modello già scaricato</string>\n    <string name=\"model_successfully_imported\">Modello importato con successo</string>\n    <string name=\"type\">Tipo</string>\n    <string name=\"keyword\">Parola chiave</string>\n    <string name=\"very_fast\">Molto veloce</string>\n    <string name=\"normal\">Normale</string>\n    <string name=\"slow\">Lento</string>\n    <string name=\"very_slow\">Molto lento</string>\n    <string name=\"compute_percents\">Calcola percentuali</string>\n    <string name=\"minimum_value_is\">Il valore minimo è %1$s</string>\n    <string name=\"warp_sub\">Distorcere l\\'immagine disegnando con le dita</string>\n    <string name=\"warp\">Ordito</string>\n    <string name=\"hardness\">Durezza</string>\n    <string name=\"warp_mode\">Modalità di deformazione</string>\n    <string name=\"warp_mode_move\">Mossa</string>\n    <string name=\"warp_mode_grow\">Crescere</string>\n    <string name=\"warp_mode_shrink\">Restringersi</string>\n    <string name=\"warp_mode_swirl_cw\">Vortice in senso orario</string>\n    <string name=\"warp_mode_swirl_ccw\">Girare in senso antiorario</string>\n    <string name=\"fade_strength\">Forza della dissolvenza</string>\n    <string name=\"top_drop\">Goccia in alto</string>\n    <string name=\"bottom_drop\">Goccia dal basso</string>\n    <string name=\"start_drop\">Inizia a rilasciare</string>\n    <string name=\"end_drop\">Fine Goccia</string>\n    <string name=\"downloading\">Scaricamento in corso</string>\n    <string name=\"smooth_shapes\">Forme morbide</string>\n    <string name=\"smooth_shapes_sub\">Utilizza le superellissi invece dei rettangoli arrotondati standard per forme più morbide e naturali</string>\n    <string name=\"shape_type\">Tipo di forma</string>\n    <string name=\"cut\">Taglio</string>\n    <string name=\"rounded\">Arrotondato</string>\n    <string name=\"smooth\">Liscio</string>\n    <string name=\"cut_shapes_sub\">Spigoli vivi senza arrotondamenti</string>\n    <string name=\"rounded_shapes_sub\">Angoli arrotondati classici</string>\n    <string name=\"shapes_type\">Tipo di forme</string>\n    <string name=\"corners_size\">Dimensioni degli angoli</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Eleganti elementi dell\\'interfaccia utente arrotondati</string>\n    <string name=\"filename_format\">Formato nome file</string>\n    <string name=\"prefix_pattern_description\">Testo personalizzato posizionato all\\'inizio del nome file, perfetto per nomi di progetti, marchi o tag personali.</string>\n    <string name=\"original_filename_pattern_description\">Utilizza il nome del file originale senza estensione, aiutandoti a mantenere intatta l\\'identificazione della fonte.</string>\n    <string name=\"width_pattern_description\">La larghezza dell\\'immagine in pixel, utile per tenere traccia delle modifiche alla risoluzione o del ridimensionamento dei risultati.</string>\n    <string name=\"height_pattern_description\">L\\'altezza dell\\'immagine in pixel, utile quando si lavora con proporzioni o esportazioni.</string>\n    <string name=\"random_numbers_pattern_description\">Genera cifre casuali per garantire nomi di file univoci; aggiungi più cifre per una maggiore sicurezza contro i duplicati.</string>\n    <string name=\"sequence_number_pattern_description\">Contatore con incremento automatico per esportazioni batch, ideale quando si salvano più immagini in un\\'unica sessione.</string>\n    <string name=\"preset_info_pattern_description\">Inserisce il nome della preimpostazione applicata nel nome del file in modo da poter ricordare facilmente come è stata elaborata l\\'immagine.</string>\n    <string name=\"scale_mode_pattern_description\">Visualizza la modalità di ridimensionamento dell\\'immagine utilizzata durante l\\'elaborazione, aiutando a distinguere le immagini ridimensionate, ritagliate o adattate.</string>\n    <string name=\"suffix_pattern_description\">Testo personalizzato posizionato alla fine del nome file, utile per il controllo delle versioni come _v2, _edited o _final.</string>\n    <string name=\"extension_pattern_description\">L\\'estensione del file (png, jpg, webp, ecc.), che corrisponde automaticamente al formato effettivamente salvato.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Un timestamp personalizzabile che ti consente di definire il tuo formato in base alle specifiche Java per un ordinamento perfetto.</string>\n    <string name=\"fling_type\">Tipo di lancio</string>\n    <string name=\"android_native\">Android nativo</string>\n    <string name=\"ios_style\">Stile iOS</string>\n    <string name=\"smooth_curve\">Curva liscia</string>\n    <string name=\"quick_stop\">Arresto rapido</string>\n    <string name=\"bouncy\">Rimbalzante</string>\n    <string name=\"floaty\">Galleggiante</string>\n    <string name=\"snappy\">Scattante</string>\n    <string name=\"ultra_smooth\">Ultra liscio</string>\n    <string name=\"adaptive\">Adattivo</string>\n    <string name=\"accessibility_aware\">Accessibilità consapevole</string>\n    <string name=\"reduced_motion\">Movimento ridotto</string>\n    <string name=\"android_native_sub\">Fisica di scorrimento nativa di Android</string>\n    <string name=\"smooth_sub\">Scorrimento bilanciato e fluido per uso generale</string>\n    <string name=\"ios_style_sub\">Comportamento di scorrimento simile a iOS con maggiore attrito</string>\n    <string name=\"smooth_curve_sub\">Curva spline unica per una sensazione di scorrimento distinta</string>\n    <string name=\"quick_stop_sub\">Scorrimento preciso con arresto rapido</string>\n    <string name=\"bouncy_sub\">Scorrimento rimbalzante giocoso e reattivo</string>\n    <string name=\"floaty_sub\">Pergamene lunghe e scorrevoli per la navigazione dei contenuti</string>\n    <string name=\"snappy_sub\">Scorrimento rapido e reattivo per interfacce utente interattive</string>\n    <string name=\"ultra_smooth_sub\">Scorrimento fluido premium con slancio esteso</string>\n    <string name=\"adaptive_sub\">Regola la fisica in base alla velocità di lancio</string>\n    <string name=\"accessibility_aware_sub\">Rispetta le impostazioni di accessibilità del sistema</string>\n    <string name=\"reduced_motion_sub\">Movimento minimo per esigenze di accessibilità</string>\n    <string name=\"primary_lines\">Linee primarie</string>\n    <string name=\"primary_lines_sub\">Aggiunge una linea più spessa ogni quinta linea</string>\n    <string name=\"fill_color\">Colore riempimento</string>\n    <string name=\"hidden_tools\">Strumenti nascosti</string>\n    <string name=\"hidden_for_share\">Strumenti nascosti per la condivisione</string>\n    <string name=\"color_library\">Libreria dei colori</string>\n    <string name=\"color_library_sub\">Sfoglia una vasta collezione di colori</string>\n    <string name=\"model_fatality_deblur\">Rende più nitidi e rimuove la sfocatura dalle immagini mantenendo i dettagli naturali, ideale per correggere le foto sfocate.</string>\n    <string name=\"model_unresize_v3\">Ripristina in modo intelligente le immagini che sono state precedentemente ridimensionate, recuperando dettagli e texture perdute.</string>\n    <string name=\"model_liveaction_v1_span\">Ottimizzato per contenuti live-action, riduce gli artefatti di compressione e migliora i dettagli più fini nei fotogrammi di film/programmi TV.</string>\n    <string name=\"model_vhs2hd_realplksr\">Converte filmati di qualità VHS in HD, rimuovendo il rumore del nastro e migliorando la risoluzione preservando l\\'atmosfera vintage.</string>\n    <string name=\"model_text2hd_v1\">Specializzato per immagini e screenshot con molto testo, rende più nitidi i caratteri e migliora la leggibilità.</string>\n    <string name=\"model_frankendata_pretrainer\">Upscaling avanzato addestrato su diversi set di dati, eccellente per il miglioramento fotografico generico.</string>\n    <string name=\"model_realwebphoto_v2\">Ottimizzato per foto compresse sul Web, rimuove gli artefatti JPEG e ripristina l\\'aspetto naturale.</string>\n    <string name=\"model_realwebphoto_v4\">Versione migliorata per le foto web con migliore conservazione della texture e riduzione degli artefatti.</string>\n    <string name=\"model_dat_2x\">Upscaling 2x con tecnologia Dual Aggregation Transformer, mantiene nitidezza e dettagli naturali.</string>\n    <string name=\"model_dat_3x\">Upscaling 3x utilizzando un\\'architettura avanzata del trasformatore, ideale per esigenze di ingrandimento moderate.</string>\n    <string name=\"model_dat_4x\">Upscaling 4x di alta qualità con rete di trasformatori all\\'avanguardia, preserva i dettagli più fini su scale più grandi.</string>\n    <string name=\"model_nafnet_deblurring\">Rimuove sfocature/rumore e vibrazioni dalle foto. Scopo generale ma migliore per le foto.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Ripristina immagini di bassa qualità utilizzando il trasformatore Swin2SR, ottimizzato per il degrado BSRGAN. Ottimo per correggere artefatti da compressione pesante e migliorare i dettagli su scala 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Upscaling 4x con trasformatore SwinIR addestrato sulla degradazione BSRGAN. Utilizza GAN per texture più nitide e dettagli più naturali in foto e scene complesse.</string>\n    <string name=\"path\">Sentiero</string>\n    <string name=\"merge_pdf\">Unisci PDF</string>\n    <string name=\"merge_pdf_sub\">Combina più file PDF in un unico documento</string>\n    <string name=\"files_order\">Ordine dei file</string>\n    <string name=\"pages_short\">pag.</string>\n    <string name=\"split_pdf\">PDF diviso</string>\n    <string name=\"split_pdf_sub\">Estrai pagine specifiche dal documento PDF</string>\n    <string name=\"rotate_pdf\">Ruota PDF</string>\n    <string name=\"rotate_pdf_sub\">Correggi l\\'orientamento della pagina in modo permanente</string>\n    <string name=\"pages\">Pagine</string>\n    <string name=\"rearrange_pdf\">Riorganizzare il PDF</string>\n    <string name=\"rearrange_pdf_sub\">Trascina e rilascia le pagine per riordinarle</string>\n    <string name=\"hold_drag_drop\">Tieni premuto e trascina le pagine</string>\n    <string name=\"page_numbers\">Numeri di pagina</string>\n    <string name=\"page_numbers_sub\">Aggiungi automaticamente la numerazione ai tuoi documenti</string>\n    <string name=\"label_format\">Formato etichetta</string>\n    <string name=\"pdf_to_text\">Da PDF a testo (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Estrai testo semplice dai tuoi documenti PDF</string>\n    <string name=\"watermark_pdf_sub\">Sovrapponi testo personalizzato per il branding o la sicurezza</string>\n    <string name=\"signature\">Firma</string>\n    <string name=\"signature_sub\">Aggiungi la tua firma elettronica a qualsiasi documento</string>\n    <string name=\"will_be_for_signature\">Questo verrà utilizzato come firma</string>\n    <string name=\"unlock_pdf\">Sblocca PDF</string>\n    <string name=\"unlock_pdf_sub\">Rimuovi le password dai tuoi file protetti</string>\n    <string name=\"protect_pdf\">Proteggi PDF</string>\n    <string name=\"protect_pdf_sub\">Proteggi i tuoi documenti con una crittografia avanzata</string>\n    <string name=\"success\">Successo</string>\n    <string name=\"pdf_unlocked\">PDF sbloccato, puoi salvarlo o condividerlo</string>\n    <string name=\"repair_pdf\">Ripara PDF</string>\n    <string name=\"repair_pdf_sub\">Tentare di correggere documenti danneggiati o illeggibili</string>\n    <string name=\"grayscale\">Scala di grigi</string>\n    <string name=\"grayscale_pdf_sub\">Converti tutte le immagini incorporate nel documento in scala di grigi</string>\n    <string name=\"compress_pdf\">Comprimi PDF</string>\n    <string name=\"compress_pdf_sub\">Ottimizza le dimensioni del file del tuo documento per una condivisione più semplice</string>\n    <string name=\"repair_info\">ImageToolbox ricostruisce la tabella dei riferimenti incrociati interna e rigenera la struttura dei file da zero. Ciò può ripristinare l\\'accesso a molti file che \\\\\"non possono essere aperti\\\\\"</string>\n    <string name=\"grayscale_info\">Questo strumento converte tutte le immagini del documento in scala di grigi. Ideale per stampare e ridurre le dimensioni del file</string>\n    <string name=\"metadata\">Metadati</string>\n    <string name=\"metadata_pdf_sub\">Modifica le proprietà del documento per una migliore privacy</string>\n    <string name=\"tags\">Tag</string>\n    <string name=\"producer\">Produttore</string>\n    <string name=\"author\">Autore</string>\n    <string name=\"keywords\">Parole chiave</string>\n    <string name=\"creator\">Creatore</string>\n    <string name=\"privacy_deep_clean\">Privacy Pulizia profonda</string>\n    <string name=\"privacy_deep_clean_sub\">Cancella tutti i metadati disponibili per questo documento</string>\n    <string name=\"page\">Pagina</string>\n    <string name=\"deep_ocr\">OCR profondo</string>\n    <string name=\"deep_ocr_sub\">Estrai il testo dal documento e memorizzalo in un unico file di testo utilizzando il motore Tesseract</string>\n    <string name=\"cant_remove_all\">Impossibile rimuovere tutte le pagine</string>\n    <string name=\"remove_pages_pdf\">Rimuovere le pagine PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Rimuovi pagine specifiche dal documento PDF</string>\n    <string name=\"tap_to_remove\">Tocca per rimuovere</string>\n    <string name=\"manually\">Manualmente</string>\n    <string name=\"crop_pdf\">Ritaglia PDF</string>\n    <string name=\"crop_pdf_sub\">Ritaglia le pagine del documento fino a qualsiasi limite</string>\n    <string name=\"flatten_pdf\">Appiattisci PDF</string>\n    <string name=\"flatten_pdf_sub\">Rendi il PDF immodificabile rasterizzando le pagine del documento</string>\n    <string name=\"camera_failed_to_open\">Impossibile avviare la fotocamera. Controlla le autorizzazioni e assicurati che non sia utilizzata da un\\'altra app.</string>\n    <string name=\"extract_images\">Estrai immagini</string>\n    <string name=\"extract_images_sub\">Estrai le immagini incorporate nei PDF alla loro risoluzione originale</string>\n    <string name=\"pdf_no_embedded\">Questo file PDF non contiene immagini incorporate</string>\n    <string name=\"extract_images_info\">Questo strumento esegue la scansione di ogni pagina e recupera immagini originali di qualità completa, perfette per salvare gli originali dai documenti</string>\n    <string name=\"draw_signature\">Disegna firma</string>\n    <string name=\"pen_params\">Parametri penna</string>\n    <string name=\"draw_signature_sub\">Utilizza la propria firma come immagine da inserire sui documenti</string>\n    <string name=\"zip_pdf\">PDF zippato</string>\n    <string name=\"zip_pdf_sub\">Dividi il documento con un determinato intervallo e inserisci i nuovi documenti nell\\'archivio zip</string>\n    <string name=\"interval\">Intervallo</string>\n    <string name=\"print_pdf\">Stampa PDF</string>\n    <string name=\"print_pdf_sub\">Preparare il documento per la stampa con dimensioni di pagina personalizzate</string>\n    <string name=\"pages_per_sheet\">Pagine per foglio</string>\n    <string name=\"orientation\">Orientamento</string>\n    <string name=\"page_size\">Dimensioni della pagina</string>\n    <string name=\"margin\">Margine</string>\n    <string name=\"bloom\">Fioritura</string>\n    <string name=\"soft_knee\">Ginocchio morbido</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Ottimizzato per anime e cartoni animati. Upscaling veloce con colori naturali migliorati e meno artefatti</string>\n    <string name=\"one_ui_sub\">Stile simile a Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Inserisci qui i simboli matematici di base per calcolare il valore desiderato (ad esempio (5+5)*10)</string>\n    <string name=\"math_expression\">Espressione matematica</string>\n    <string name=\"pick_up_to_n_collage_images\">Scegli fino a %1$s immagini</string>\n    <string name=\"keep_date_time\">Mantieni data e ora</string>\n    <string name=\"keep_date_time_sub\">Conserva sempre i tag EXIF ​​relativi a data e ora, funziona indipendentemente dall\\'opzione Mantieni EXIF</string>\n    <string name=\"background_color_for_alpha_formats\">Colore di sfondo per i formati Alpha</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Aggiunge la possibilità di impostare il colore di sfondo per ogni formato immagine con supporto alpha, quando disabilitato è disponibile solo per quelli non alpha</string>\n    <string name=\"open_markup_project\">Apri progetto</string>\n    <string name=\"open_markup_project_sub\">Continua a modificare un progetto Image Toolbox salvato in precedenza</string>\n    <string name=\"markup_project_open_failed\">Impossibile aprire il progetto Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Nel progetto Image Toolbox mancano i dati del progetto</string>\n    <string name=\"markup_project_corrupted\">Il progetto Image Toolbox è danneggiato</string>\n    <string name=\"unsupported_markup_project_version\">Versione del progetto Image Toolbox non supportata: %1$d</string>\n    <string name=\"save_markup_project\">Salva progetto</string>\n    <string name=\"save_markup_project_sub\">Memorizza livelli, sfondo e cronologia delle modifiche in un file di progetto modificabile</string>\n    <string name=\"failed_to_open\">Impossibile aprire</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Scrivi su PDF ricercabile</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Riconosci il testo da un batch di immagini e salva PDF ricercabili con immagine e livello di testo selezionabile</string>\n    <string name=\"layer_alpha\">Livello alfa</string>\n    <string name=\"horizontal_flip\">Capovolgimento orizzontale</string>\n    <string name=\"vertical_flip\">Capovolgimento verticale</string>\n    <string name=\"lock\">Serratura</string>\n    <string name=\"add_shadow\">Aggiungi ombra</string>\n    <string name=\"shadow_color\">Colore dell\\'ombra</string>\n    <string name=\"text_geometry\">Geometria del testo</string>\n    <string name=\"text_geometry_sub\">Allunga o inclina il testo per una stilizzazione più nitida</string>\n    <string name=\"scale_x\">Scala X</string>\n    <string name=\"skew_x\">Inclina X</string>\n    <string name=\"remove_annotations\">Rimuovi le annotazioni</string>\n    <string name=\"remove_annotations_sub\">Rimuovi i tipi di annotazioni selezionati come collegamenti, commenti, evidenziazioni, forme o campi modulo dalle pagine PDF</string>\n    <string name=\"annotation_link\">Collegamenti ipertestuali</string>\n    <string name=\"annotation_file_attachment\">Allegati file</string>\n    <string name=\"annotation_line\">Linee</string>\n    <string name=\"annotation_popup\">Popup</string>\n    <string name=\"annotation_stamp\">Francobolli</string>\n    <string name=\"annotation_shapes\">Forme</string>\n    <string name=\"annotation_text\">Note di testo</string>\n    <string name=\"annotation_text_markup\">Markup del testo</string>\n    <string name=\"annotation_widget\">Campi del modulo</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">Sconosciuto</string>\n    <string name=\"annotations\">Annotazioni</string>\n    <string name=\"ungroup\">Separa</string>\n    <string name=\"add_shadow_sub\">Aggiungi ombra sfocata dietro il livello con colori e offset configurabili</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-iw/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"exception\">חריג</string>\n    <string name=\"edit_exif\">ערוך EXIF</string>\n    <string name=\"save\">שמור</string>\n    <string name=\"pick_color_sub\">בחר צבע מהתמונה, העתק או שתף</string>\n    <string name=\"image\">תמונה</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">לא ניתן לשנות את ערכת הצבעים של האפליקציה בזמן שצבעים דינמיים מופעלים</string>\n    <string name=\"pick_accent_color\">עיצוב האפליקציה יתבסס על צבע, אותו תבחר</string>\n    <string name=\"about_app\">אודות האפליקציה</string>\n    <string name=\"share\">שתף</string>\n    <string name=\"smth_went_wrong\">משהו השתבש: %1$s</string>\n    <string name=\"size\">גודל %1$s</string>\n    <string name=\"loading\">טוען…</string>\n    <string name=\"image_too_large_preview\">התמונה גדולה מדי לתצוגה מקדימה, אך אנסה לשמור אותה בכל זאת</string>\n    <string name=\"pick_image\">בחר תמונה כדי להתחיל</string>\n    <string name=\"width\">רוחב %1$s</string>\n    <string name=\"app_closing\">האפליקציה נסגרת</string>\n    <string name=\"stay\">להישאר</string>\n    <string name=\"close\">סגור</string>\n    <string name=\"height\">גובה %1$s</string>\n    <string name=\"quality\">איכות</string>\n    <string name=\"extension\">סיומת</string>\n    <string name=\"resize_type\">סוג שיטת שינוי הגודל</string>\n    <string name=\"explicit\">מפורש</string>\n    <string name=\"flexible\">גמיש</string>\n    <string name=\"pick_image_alt\">בחר תמונה</string>\n    <string name=\"app_closing_sub\">האם אתה רוצה לסגור את האפליקציה?</string>\n    <string name=\"reset_image\">אפס תמונה</string>\n    <string name=\"reset_image_sub\">שינויים בתמונה יוחזרו לערכים הראשונים</string>\n    <string name=\"values_reset\">ערכים מאופסים כראוי</string>\n    <string name=\"reset\">איפוס</string>\n    <string name=\"something_went_wrong\">משהו השתבש</string>\n    <string name=\"restart_app\">הפעל את האפליקציה מחדש</string>\n    <string name=\"copied\">הועתק</string>\n    <string name=\"ok\">בסדר</string>\n    <string name=\"no_exif\">לא נמצאו נתוני EXIF</string>\n    <string name=\"add_tag\">הוסף תגית</string>\n    <string name=\"clear\">נקה</string>\n    <string name=\"clear_exif\">נקה EXIF</string>\n    <string name=\"cancel\">ביטול</string>\n    <string name=\"clear_exif_sub\">כל נתוני ה-EXIF של התמונה יימחקו, פעולה זו לא ניתנת לביטול!</string>\n    <string name=\"presets\">הגדרות קבועות מראש</string>\n    <string name=\"crop\">חיתוך</string>\n    <string name=\"image_not_saved\">שומר</string>\n    <string name=\"image_not_saved_sub\">כל השינויים שלא נשמרו יאבדו אם תעזוב עכשיו</string>\n    <string name=\"check_source_code\">קוד מקור</string>\n    <string name=\"check_source_code_sub\">קבל את העדכונים האחרונים, התחל לדון בבעיות ועוד</string>\n    <string name=\"single_edit\">עריכה בודדת</string>\n    <string name=\"single_edit_sub\">התאם, שנה גודל וערוך תמונה בודדת</string>\n    <string name=\"pick_color\">בוחר צבעים</string>\n    <string name=\"color\">צבע</string>\n    <string name=\"color_copied\">צבע הועתק</string>\n    <string name=\"crop_sub\">חתוך תמונה לכל גבול</string>\n    <string name=\"version\">גירסא</string>\n    <string name=\"keep_exif\">שמור EXIF</string>\n    <string name=\"images\">תמונות: %d</string>\n    <string name=\"change_preview\">שנה תצוגה מקדימה</string>\n    <string name=\"remove\">הסר</string>\n    <string name=\"palette_sub\">צור דוגמית פלטת צבעים מתמונה נתונה</string>\n    <string name=\"generate_palette\">צור פלטת צבעים</string>\n    <string name=\"palette\">לוח צבעים</string>\n    <string name=\"update\">עדכון</string>\n    <string name=\"new_version\">גרסא חדשה %1$s</string>\n    <string name=\"unsupported_type\">סוג לא נתמך: %1$s</string>\n    <string name=\"no_palette\">לא ניתן ליצור פלטת צבעים עבור תמונה נתונה</string>\n    <string name=\"original\">מקורי</string>\n    <string name=\"folder\">תיקיית שמירה</string>\n    <string name=\"def\">ברירת מחדל</string>\n    <string name=\"custom\">מותאם אישית</string>\n    <string name=\"unspecified\">לא מוגדר</string>\n    <string name=\"device_storage\">אחסון מכשיר</string>\n    <string name=\"by_bytes_resize\">שנה גודל לפי משקל</string>\n    <string name=\"max_bytes\">גודל מקסימלי ב-KB</string>\n    <string name=\"by_bytes_resize_sub\">שנה גודל תמונה בהתאם לגודל נתון ב-KB</string>\n    <string name=\"compare\">השוואה</string>\n    <string name=\"compare_sub\">השווה בין שתי תמונות</string>\n    <string name=\"pick_two_images\">בחר שתי תמונות כדי להתחיל</string>\n    <string name=\"pick_images\">בחר תמונות</string>\n    <string name=\"settings\">הגדרות</string>\n    <string name=\"night_mode\">מצב לילה</string>\n    <string name=\"dark\">כהה</string>\n    <string name=\"light\">בהיר</string>\n    <string name=\"system\">מערכת</string>\n    <string name=\"dynamic_colors\">צבעים דינמיים</string>\n    <string name=\"customization\">התאמה אישית</string>\n    <string name=\"allow_image_monet\">אפשר תמונה של מונט</string>\n    <string name=\"allow_image_monet_sub\">אם אפשרות זו מופעלת, כאשר תבחר תמונה לעריכה, צבעי האפליקציה יאומצו לתמונה זו</string>\n    <string name=\"language\">שפה</string>\n    <string name=\"amoled_mode\">מצב אמולד</string>\n    <string name=\"amoled_mode_sub\">אם מופעל, צבע המשטחים יוגדר לשחור מוחלט במצב לילה</string>\n    <string name=\"color_scheme\">סכמת צבעים</string>\n    <string name=\"color_red\">אדום</string>\n    <string name=\"color_green\">ירוק</string>\n    <string name=\"color_blue\">כחול</string>\n    <string name=\"clipboard_paste_invalid_color_code\">הדבק קוד צבע aRGB חוקי.</string>\n    <string name=\"clipboard_paste_invalid_empty\">אין מה להדביק</string>\n    <string name=\"no_updates\">לא נמצאו עדכונים</string>\n    <string name=\"issue_tracker\">עוקב אחר בעיות</string>\n    <string name=\"issue_tracker_sub\">שלח לכאן דוחות באגים ובקשות לתכונות חדשות</string>\n    <string name=\"failed_to_save\">שמירת התמונות %d נכשלה</string>\n    <string name=\"help_translate\">עזרה בתרגום</string>\n    <string name=\"help_translate_sub\">תקן טעויות תרגום או התאם את הפרויקט לשפות אחרות</string>\n    <string name=\"nothing_found_by_search\">שום דבר לא נמצא על ידי השאילתה שלך</string>\n    <string name=\"search_here\">חפש כאן</string>\n    <string name=\"dynamic_colors_sub\">אם מופעל, אז צבעי האפליקציה יאומצו לצבעי טפט</string>\n    <string name=\"primary\">ראשון</string>\n    <string name=\"tertiary\">שלישי</string>\n    <string name=\"secondary\">משני</string>\n    <string name=\"border_thickness\">עובי גבול</string>\n    <string name=\"surface\">משטח</string>\n    <string name=\"values\">ערכים</string>\n    <string name=\"add\">הוסף</string>\n    <string name=\"permission\">הרשאה</string>\n    <string name=\"grant\">הענק</string>\n    <string name=\"permission_sub\">האפליקציה צריכה גישה לאחסון שלך כדי לשמור תמונות, זה הכרחי, בלי זה היא לא יכולה לעבוד, נא הענק הרשאה בתיבת הדו-שיח הבאה</string>\n    <string name=\"grant_permission_manual\">האפליקציה זקוקה להרשאה זו כדי לעבוד, אנא הענק אותה באופן ידני</string>\n    <string name=\"external_storage\">אחסון חיצוני</string>\n    <string name=\"monet_colors\">צבעי מונה</string>\n    <string name=\"donation_sub\">אפליקציה זו חינמית לחלוטין, אך אם ברצונך לתמוך בפיתוח הפרויקט, תוכלו ללחוץ כאן</string>\n    <string name=\"fab_alignment\">יישור FAB</string>\n    <string name=\"check_updates\">חפש עדכונים</string>\n    <string name=\"check_updates_sub\">אם מופעל, תיבת דו-שיח עדכון תוצג לך לאחר הפעלת האפליקציה</string>\n    <string name=\"zoom\">זום תמונה</string>\n    <string name=\"prefix\">קידומת</string>\n    <string name=\"filename\">שם קובץ</string>\n    <string name=\"alpha\">אלפא</string>\n    <string name=\"tint\">לצבוע</string>\n    <string name=\"monochrome\">מונוכרום</string>\n    <string name=\"gamma\">גמא</string>\n    <string name=\"highlights_shadows\">בהירות והצללות</string>\n    <string name=\"highlights\">עיקרי הדברים</string>\n    <string name=\"shadows\">הצללות</string>\n    <string name=\"haze\">ערפל</string>\n    <string name=\"sepia\">חום כהה</string>\n    <string name=\"emboss\">הבלטה</string>\n    <string name=\"delete_exif\">מחק EXIF</string>\n    <string name=\"no_image\">אין תמונה</string>\n    <string name=\"filter\">סינון</string>\n    <string name=\"color_filter\">מסנן צבע</string>\n    <string name=\"exposure\">חשיפה</string>\n    <string name=\"negative\">שלילי</string>\n    <string name=\"vibrance\">חיוניות</string>\n    <string name=\"crosshatch\">הצלבה</string>\n    <string name=\"line_width\">רוחב קו</string>\n    <string name=\"blur\">טישטוש</string>\n    <string name=\"start\">התחלה</string>\n    <string name=\"color_matrix\">מטריצת צבע</string>\n    <string name=\"limits_resize\">שינוי גודל לפי גבולות</string>\n    <string name=\"limits_resize_sub\">שנה את גודל התמונות לפי הרוחב והגובה תוך שמירת היחס המקורי</string>\n    <string name=\"sketch\">סקיצה</string>\n    <string name=\"threshold\">מפתן</string>\n    <string name=\"quantizationLevels\">רמות קוונטיזציה</string>\n    <string name=\"smooth_toon\">טון חלק</string>\n    <string name=\"toon\">טון</string>\n    <string name=\"non_maximum_suppression\">דיכוי לא מקסימלי</string>\n    <string name=\"weak_pixel_inclusion\">הכללת פיקסלים חלשה</string>\n    <string name=\"lookup\">הבט מעלה</string>\n    <string name=\"stack_blur\">טשטוש ערימה</string>\n    <string name=\"convolution3x3\">קונבולוציה 3x3</string>\n    <string name=\"first_color\">צבע ראשון</string>\n    <string name=\"second_color\">צבע שני</string>\n    <string name=\"reorder\">סדר מחדש</string>\n    <string name=\"fast_blur\">טשטוש מהיר</string>\n    <string name=\"luminance_threshold\">סף בהירות</string>\n    <string name=\"add_file_size\">הוסף גודל קובץ</string>\n    <string name=\"add_file_size_sub\">אם מופעל מוסיף רוחב וגובה של התמונה השמורה לשם ה קובץ</string>\n    <string name=\"emoji\">אימוג\\'י</string>\n    <string name=\"emoji_sub\">בחר איזה אמוג\\'י יוצג במסך הראשי</string>\n    <string name=\"delete_exif_sub\">מחק מטא נתונים של EXIF מכל סט תמונות</string>\n    <string name=\"image_preview\">תצוגה מקדימה של תמונה</string>\n    <string name=\"image_preview_sub\">תצוגה מקדימה של כל סוג של תמונות: GIF, SVG וכן הלאה</string>\n    <string name=\"image_source\">מקור תמונה</string>\n    <string name=\"photo_picker\">בוחר תמונות</string>\n    <string name=\"gallery_picker\">גלריה</string>\n    <string name=\"file_explorer_picker\">סייר קבצים</string>\n    <string name=\"photo_picker_sub\">בוחר התמונות המודרני של אנדרואיד המופיע בתחתית המסך, עשוי לעבוד רק על אנדרואיד 12+ ויש לו גם בעיות בקבלת מטא נתונים של EXIF</string>\n    <string name=\"options_arrangement\">הסדר אפשרויות</string>\n    <string name=\"edit\">ערוך</string>\n    <string name=\"order\">סדר</string>\n    <string name=\"emojis_count\">ספירת אמוג\\'ים</string>\n    <string name=\"load_image_from_net\">טען תמונה מהרשת</string>\n    <string name=\"load_image_from_net_sub\">טען כל תמונה מהאינטרנט, הצג אותה בתצוגה מקדימה, הגדל אותה, וגם שמור או ערוך אותה אם תרצה</string>\n    <string name=\"image_link\">קישור לתמונה</string>\n    <string name=\"fill\">למלא</string>\n    <string name=\"fit\">התאם</string>\n    <string name=\"explicit_description\">משנה תמונות לפי ערכי הגובה והרוחב הנבחרים. עשוי לשנות את יחס הגובה והרוחב.</string>\n    <string name=\"flexible_description\">משנה את גודל התמונות לתמונות עם צד ארוך כלשהו לפי פרמטר רוחב או גובה, כל חישובי הגודל יבוצעו לאחר השמירה - שומר על יחס רוחב-גובה</string>\n    <string name=\"brightness\">בהירות</string>\n    <string name=\"contrast\">ניגודיות</string>\n    <string name=\"hue\">צבע</string>\n    <string name=\"saturation\">רוויה</string>\n    <string name=\"add_filter\">הוסף מסנן</string>\n    <string name=\"filter_sub\">החל שרשרת פילטרים על תמונות</string>\n    <string name=\"filters\">מסננים</string>\n    <string name=\"light_aka_illumination\">מואר</string>\n    <string name=\"white_balance\">לבן מאוזן</string>\n    <string name=\"temperature\">טמפרטורה</string>\n    <string name=\"effect\">אפקט</string>\n    <string name=\"distance\">מרחק</string>\n    <string name=\"slope\">מדרון</string>\n    <string name=\"sharpen\">חידוד</string>\n    <string name=\"solarize\">סולריזציה</string>\n    <string name=\"black_and_white\">שחור ולבן</string>\n    <string name=\"spacing\">מרווחים</string>\n    <string name=\"sobel_edge\">קצה סובל</string>\n    <string name=\"halftone\">חצי טון</string>\n    <string name=\"cga_colorspace\">מרחב הצבעים של GCA</string>\n    <string name=\"gaussian_blur\">טישטוש גאוסיאני</string>\n    <string name=\"box_blur\">תיבת טשטוש</string>\n    <string name=\"bilaterial_blur\">טשטוש דו צדדי</string>\n    <string name=\"laplacian\">לאפלסיאן</string>\n    <string name=\"vignette\">וינייט</string>\n    <string name=\"end\">סוף</string>\n    <string name=\"kuwahara\">החלקת קוואהרה</string>\n    <string name=\"radius\">רדיוס</string>\n    <string name=\"scale\">קנה מידה</string>\n    <string name=\"distortion\">עיוות</string>\n    <string name=\"angle\">זווית</string>\n    <string name=\"swirl\">ערבוב</string>\n    <string name=\"bulge\">בליטות</string>\n    <string name=\"dilation\">הרחבה</string>\n    <string name=\"sphere_refraction\">שבירה של כדור</string>\n    <string name=\"refractive_index\">מקדם השבירה</string>\n    <string name=\"glass_sphere_refraction\">שבירה של כדור זכוכית</string>\n    <string name=\"opacity\">אטימות</string>\n    <string name=\"posterize\">פוסטר</string>\n    <string name=\"rgb_filter\">מסנן RGB</string>\n    <string name=\"false_color\">צבע מזויף</string>\n    <string name=\"blur_size\">גודל טשטוש</string>\n    <string name=\"blur_center_x\">מרכז טשטוש x</string>\n    <string name=\"blur_center_y\">מרכז טשטוש y</string>\n    <string name=\"zoom_blur\">טשטוש זום</string>\n    <string name=\"color_balance\">איזון צבע</string>\n    <string name=\"gallery_picker_sub\">בוחר תמונות פשוט של גלריה, זה יעבוד רק אם יש לך את האפליקציה הזו</string>\n    <string name=\"file_explorer_picker_sub\">השתמש בכוונה של GetContent לבחירת תמונה, עובד בכל מקום, אבל יכול להיות גם בעיות בקבלת תמונות שנבחרו במכשירים מסוימים, זו לא אשמתי</string>\n    <string name=\"order_sub\">קבע את סדר הכלים במסך הראשי</string>\n    <string name=\"content_scale\">סולם תוכן</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">שם הקובץ המקורי</string>\n    <string name=\"add_original_filename\">הוסף שם קובץ מקורי</string>\n    <string name=\"add_original_filename_sub\">אם מופעל מוסיף שם קובץ מקורי בשם של התמונה שנערכה</string>\n    <string name=\"replace_sequence_number\">החלף את מספר הרצף</string>\n    <string name=\"replace_sequence_number_sub\">אם מופעל מחליף חותמת זמן סטנדרטית למספר רצף התמונה אם אתה משתמש בעיבוד אצווה</string>\n    <string name=\"filename_not_work_with_photopicker\">הוספת שם קובץ מקורי לא עובדת אם נבחר מקור תמונה בבורר התמונות</string>\n    <string name=\"fallback_option\">אפשרות גיבוי</string>\n    <string name=\"file_proceed\">הקובץ בעיבוד</string>\n    <string name=\"edit_screenshot\">ערוך צילום מסך</string>\n    <string name=\"copy\">עותק</string>\n    <string name=\"skip\">דלג</string>\n    <string name=\"activate_files\">השבתת את אפליקציית הקבצים, הפעל אותה כדי להשתמש בתכונה זו</string>\n    <string name=\"draw\">צייר</string>\n    <string name=\"draw_sub\">צייר על תמונה כמו בספר סקיצות, או צייר על הרקע עצמו</string>\n    <string name=\"paint_color\">צבע הצבע</string>\n    <string name=\"paint_alpha\">צבע אלפא</string>\n    <string name=\"draw_on_image\">צייר על תמונה</string>\n    <string name=\"draw_on_image_sub\">בחר תמונה וצייר עליה משהו</string>\n    <string name=\"draw_on_background\">צייר על רקע</string>\n    <string name=\"draw_on_background_sub\">בחר צבע רקע וצייר עליו</string>\n    <string name=\"features\">תכונות</string>\n    <string name=\"implementation\">יישום</string>\n    <string name=\"compatibility\">תאימות</string>\n    <string name=\"image_size_warning\">‌ניסיון לשמור תמונה עם רוחב וגובה נתונים עלול לגרום לשגיאת זיכרון מלא, עשה זאת על אחריותך בלבד.</string>\n    <string name=\"cache\">מטמון</string>\n    <string name=\"found_s\">נמצא %1$s</string>\n    <string name=\"auto_cache_clearing_sub\">אם מופעלת מטמון האפליקציה ינוקה בעת הפעלת האפליקציה</string>\n    <string name=\"tools\">כלים</string>\n    <string name=\"group_options_by_type\">קבץ אפשרויות לפי סוג</string>\n    <string name=\"group_options_by_type_sub\">אפשרויות קבוצות במסך הראשי של סוגן במקום סידור רשימה מותאם אישית</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">לא ניתן לשנות סידור בזמן שקיבוץ אפשרויות מופעל</string>\n    <string name=\"secondary_customization\">התאמה אישית משנית</string>\n    <string name=\"screenshot\">צילום מסך</string>\n    <string name=\"invalid_password_or_not_encrypted\">סיסמה לא חוקית או קובץ שנבחר אינו מוצפן</string>\n    <string name=\"encrypt\">הצפן</string>\n    <string name=\"features_sub\">הצפנה מבוססת סיסמה של קבצים. ניתן לאחסן קבצים שהמשיכו בספרייה הנבחרת או לשתף. ניתן גם לפתוח ישירות קבצים מפוענחים.</string>\n    <string name=\"cache_size\">גודל המטמון</string>\n    <string name=\"decrypt\">פענח</string>\n    <string name=\"file_size\">גודל הקובץ</string>\n    <string name=\"warning_bytes\">שמירה במצב %1$s עלולה להיות לא יציבה, מכיוון שהיא פורמט ללא אובדן</string>\n    <string name=\"background_color\">צבע רקע</string>\n    <string name=\"store_file_desc\">אחסן את הקובץ הזה במכשיר שלך או השתמש בכפתור השיתוף כדי לשתף אותו לכל מקום שתרצה</string>\n    <string name=\"file_size_sub\">גודל הקובץ המרבי מוגבל על ידי מערכת ההפעלה אנדרואיד והזיכרון הזמין, וזה כמובן תלוי במכשיר שלך. \\nשימו לב: הזיכרון אינו אחסון.</string>\n    <string name=\"auto_cache_clearing\">ניקוי מטמון אוטומטי</string>\n    <string name=\"cipher\">הצפנה</string>\n    <string name=\"cipher_sub\">הצפנה ופענוח של כל קובץ (לא רק תמונה) בהתבסס על אלגוריתמי קריפטו שונים זמינים</string>\n    <string name=\"pick_file\">בחר קובץ</string>\n    <string name=\"pick_file_to_start\">בחר קובץ כדי להתחיל</string>\n    <string name=\"decryption\">פענוח</string>\n    <string name=\"encryption\">הצפנה</string>\n    <string name=\"key\">מפתח</string>\n    <string name=\"implementation_sub\">AES-256, מצב GCM, ללא ריפוד, IVs אקראיים של 12 בתים. (כברירת מחדל, אך ניתן לבחור את האלגוריתם הרצוי) מפתחות משמשים כ-hashes של SHA-3 (256 סיביות).</string>\n    <string name=\"compatibility_sub\">שים לב שתאימות לתוכנות או שירותים אחרים להצפנת קבצים אינה מובטחת. טיפול מפתח או תצורת צופן שונה במקצת עשויות להיות סיבות לאי התאמה.</string>\n    <string name=\"create\">צור</string>\n    <string name=\"updates\">עדכונים</string>\n    <string name=\"tg_chat\">צא\\'ט טלגרם</string>\n    <string name=\"nature_and_animals\">טבע וחיות</string>\n    <string name=\"wait\">המתן</string>\n    <string name=\"food_and_drink\">אוכל ושתייה</string>\n    <string name=\"contact_me\">צור קשר</string>\n    <string name=\"corrupted_file_or_not_a_backup\">קובץ פגום או שאינו גיבוי</string>\n    <string name=\"pick_at_least_two_images\">בחר לפחות את 2 תמונות</string>\n    <string name=\"restore\">שחזור</string>\n    <string name=\"restore_image\">שחזור תמונה</string>\n    <string name=\"delete\">מחק</string>\n    <string name=\"saved_to_without_filename\">נשמר בתיקייה %1$s</string>\n    <string name=\"settings_restored\">ההגדרות שוחזרו בהצלחה</string>\n    <string name=\"backup_and_restore\">גיבוי ושחזור</string>\n    <string name=\"backup\">גיבוי</string>\n    <string name=\"saved_to\">שמור ל קובץ %1$s ע\\\"פ שם %2$s</string>\n    <string name=\"analytics\">אנליטיקס</string>\n    <string name=\"effort\">מאמץ</string>\n    <string name=\"objects\">חפצים</string>\n    <string name=\"randomize_filename\">צור שם קובץ אקראי</string>\n    <string name=\"text\">טקסט</string>\n    <string name=\"defaultt\">ברירת מחדל</string>\n    <string name=\"font\">גופן</string>\n    <string name=\"donation\">תרום</string>\n    <string name=\"enhanced_pixelation\">פיקסלים משופרים</string>\n    <string name=\"diamond_pixelation\">פיקסלים של יהלום</string>\n    <string name=\"crop_mask\">חיתוך מסכה</string>\n    <string name=\"restore_sub\">שחזר את הגדרות האפליקציה מקובץ שנוצר בעבר</string>\n    <string name=\"trim_image\">חתוך תמונה</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"top\">חלק עליון</string>\n    <string name=\"bottom\">תחתית</string>\n    <string name=\"strength\">כוח</string>\n    <string name=\"brush_softness\">רכות מברשת</string>\n    <string name=\"activities\">פעילויות</string>\n    <string name=\"alphabet_and_numbers\">א ב ג ד ה ו ז ח ט י כ ל מ נ ס ע פ צ ק ר ש ת 0123456789 !?</string>\n    <string name=\"pipette\">פיפטה</string>\n    <string name=\"create_issue\">דיווח בעיה</string>\n    <string name=\"segmentation_mode_osd_only\">כיוון &amp; זיהוי סקריפט בלבד</string>\n    <string name=\"segmentation_mode_auto_osd\">זיהוי סקריפט &amp; אוטומטי</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">כיוון טקסט דליל &amp; זיהוי סקריפט</string>\n    <string name=\"glitch\">תקלה</string>\n    <string name=\"amount\">כמות</string>\n    <string name=\"seed\">זרע</string>\n    <string name=\"anaglyph\">אנגליף</string>\n    <string name=\"noise\">רגע</string>\n    <string name=\"pixel_sort\">מיון פיקסל</string>\n    <string name=\"shuffle\">עירבוב</string>\n    <string name=\"delete_mask_warn\">אתה עומד למחוק את מסכת המסנן שנבחרה. לא ניתן לבטל פעולה זו</string>\n    <string name=\"delete_mask\">מחק מסכה</string>\n    <string name=\"drago\">דראגו</string>\n    <string name=\"aldridge\">אולדריג\\'</string>\n    <string name=\"cutoff\">לחתוך</string>\n    <string name=\"no_such_directory\">לא נמצאה ספריה \\\"%1$s\\\", החלפנו אותה לברירת מחדל, נא לשמור את הקובץ שוב</string>\n    <string name=\"clipboard\">לוח העתקה</string>\n    <string name=\"auto_pin\">הצמדה אוטומטית</string>\n    <string name=\"vibration\">רטט</string>\n    <string name=\"vibration_strength\">חוזק רטט</string>\n    <string name=\"overwrite_files\">החלף קבצים</string>\n    <string name=\"search_option\">חיפוש</string>\n    <string name=\"search_option_sub\">מאפשר חיפוש בכל הכלים הזמינים במסך הראשי</string>\n    <string name=\"free\">חינם</string>\n    <string name=\"images_overwritten\">תמונות שהוחלפו ביעד המקורי</string>\n    <string name=\"cannot_change_image_format\">לא ניתן לשנות את פורמט התמונה כאשר אפשרות החלפת קבצים מופעלת</string>\n    <string name=\"emoji_as_color_scheme\">אמוג\\'י בתור ערכת צבעים</string>\n    <string name=\"presets_sub\" formatted=\"false\">אם בחרת בהגדרה 125, התמונה תישמר בגודל של 125% מהתמונה המקורית. אם תבחר בהגדרה 50, התמונה תישמר בגודל של 50%.</string>\n    <string name=\"presets_sub_bytes\">הגדרה מראש כאן קובעת את % מקובץ הפלט, כלומר אם תבחר הגדרה מראש 50 בתמונה של 5MB אז תקבל תמונה של 2.5MB לאחר השמירה</string>\n    <string name=\"image_crop_mask_sub\">השתמש בסוג המסכה הזה כדי ליצור מסכה מהתמונה הנתונה, שימו לב שהיא אמורה להיות בעלת ערוץ אלפא</string>\n    <string name=\"backup_sub\">גבה את הגדרות האפליקציה שלך לקובץ</string>\n    <string name=\"reset_settings_sub\">זה יחזיר את ההגדרות שלך לערכי ברירת המחדל. שימו לב שלא ניתן לבטל זאת ללא קובץ גיבוי שהוזכר לעיל.</string>\n    <string name=\"delete_color_scheme_warn\">אתה עומד למחוק את ערכת הצבעים שנבחרה. לא ניתן לבטל פעולה זו</string>\n    <string name=\"font_scale\">סולם גופנים</string>\n    <string name=\"using_large_fonts_warn\">שימוש בקנה מידה גדול של גופנים עלול לגרום לתקלות ובעיות בממשק המשתמש, אשר לא יתוקנו. השתמש בזהירות.</string>\n    <string name=\"emotions\">רגשות</string>\n    <string name=\"symbols\">סמלים</string>\n    <string name=\"travels_and_places\">מסעות ומקומות</string>\n    <string name=\"background_remover\">מסיר הרקע</string>\n    <string name=\"background_remover_sub\">הסר רקע מהתמונה על ידי ציור או השתמש באפשרות אוטומטי</string>\n    <string name=\"keep_exif_sub\">מטא נתונים של התמונה המקורית יישמרו</string>\n    <string name=\"trim_image_sub\">רווחים שקופים סביב התמונה יחתכו</string>\n    <string name=\"auto_erase_background\">מחיקה אוטומטית של רקע</string>\n    <string name=\"erase_mode\">מצב מחיקה</string>\n    <string name=\"erase_background\">מחק רקע</string>\n    <string name=\"restore_background\">שחזר רקע</string>\n    <string name=\"blur_radius\">רדיוס טשטוש</string>\n    <string name=\"draw_mode\">מצב ציור</string>\n    <string name=\"something_went_wrong_emphasis\">אופס… משהו השתבש. אתה יכול לכתוב לי באמצעות האפשרויות למטה ואנסה למצוא פתרון.</string>\n    <string name=\"resize_and_convert\">שנה גודל והמר</string>\n    <string name=\"resize_and_convert_sub\">שנה גודל של תמונות נתונות או המר אותן לפורמטים אחרים. ניתן לערוך כאן מטא נתונים של EXIF גם אם בוחרים תמונה בודדת.</string>\n    <string name=\"crashlytics_sub\">זה מאפשר לאפליקציה לאסוף דוחות קריסה באופן אוטומטי</string>\n    <string name=\"analytics_sub\">אפשר איסוף סטטיסטיקות שימוש אנונימיות באפליקציה</string>\n    <string name=\"image_exif_warning\">נכון לעכשיו, פורמט %1$s מאפשר קריאת מטא נתונים של EXIF רק ב-Android. לתמונת פלט לא יהיו מטא נתונים כלל, כאשר היא נשמרת.</string>\n    <string name=\"effort_sub\">ערך של %1$s פירושו דחיסה מהירה, וכתוצאה מכך גודל קובץ גדול יחסית. %2$s פירושו דחיסה איטית יותר, וכתוצאה מכך קובץ קטן יותר.</string>\n    <string name=\"allow_betas\">אפשר בטא</string>\n    <string name=\"allow_betas_sub\">בדיקת העדכונים תכלול גרסאות של אפליקציות בטא אם מופעלת</string>\n    <string name=\"draw_arrows\">צייר חצים</string>\n    <string name=\"draw_arrows_sub\">אם מופעל נתיב הציור יוצג כחץ מצביע</string>\n    <string name=\"circle_pixelation\">פיקסלציה של מעגל</string>\n    <string name=\"tolerance\">סובלנות</string>\n    <string name=\"color_to_replace\">צבע להחלפה</string>\n    <string name=\"target_color\">צבע יעד</string>\n    <string name=\"fidelity\">נאמנות</string>\n    <string name=\"content\">תוכן</string>\n    <string name=\"tonal_spot_sub\">סגנון פלטת ברירת המחדל, זה מאפשר להתאים אישית את כל ארבעת הצבעים, אחרים מאפשרים לך להגדיר רק את צבע המפתח</string>\n    <string name=\"neutral_sub\">סגנון קצת יותר כרומטי מאשר מונוכרום</string>\n    <string name=\"vibrant_sub\">נושא רועש, הצבעוניות היא מקסימלית עבור פלטת ראשי, מוגברת עבור אחרים</string>\n    <string name=\"playful_scheme\">ערכת נושא שובבה - הגוון של צבע המקור אינו מופיע בערכת הנושא</string>\n    <string name=\"monochrome_sub\">נושא מונוכרום, הצבעים הם אך ורק שחור/לבן/אפור</string>\n    <string name=\"content_sub\">סכימה שממקמת את צבע המקור ב- Scheme.primaryContainer</string>\n    <string name=\"inverse_fill_type\">סוג מילוי הפוך</string>\n    <string name=\"inverse_fill_type_sub\">אם מופעל, כל האזורים הלא-מסוכים יסוננו במקום התנהגות ברירת המחדל</string>\n    <string name=\"app_bars_shadow\">סרגלי אפליקציה</string>\n    <string name=\"app_bars_shadow_sub\">צייר צל מאחורי סרגלי אפליקציה</string>\n    <string name=\"free_drawing_sub\">מצייר נתיב כערך קלט</string>\n    <string name=\"line_sub\">מצייר נתיב מנקודת התחלה לנקודת סיום בתור קו</string>\n    <string name=\"line_arrow_sub\">מצייר חץ מצביע מנקודת התחלה לנקודת סיום בתור קו</string>\n    <string name=\"rect_sub\">מצייר ישר מנקודת התחלה לנקודת סיום</string>\n    <string name=\"oval_sub\">מצייר אליפסה מנקודת התחלה לנקודת סיום</string>\n    <string name=\"outlined_oval_sub\">מצייר אליפסה עם קווי מתאר מנקודת ההתחלה לנקודת הסיום</string>\n    <string name=\"outlined_rect_sub\">מצייר ישר מתואר מנקודת ההתחלה לנקודת הסיום</string>\n    <string name=\"auto_pin_sub\">מוסיף אוטומטית תמונה שנשמרה ללוח אם מופעל</string>\n    <string name=\"overwrite_files_sub\">הקובץ המקורי יוחלף בחדש במקום לשמור בתיקייה שנבחרה, אפשרות זו צריכה להיות מקור התמונה \\\"Explorer\\\" או GetContent, כאשר מחליפים את זה, היא תוגדר אוטומטית</string>\n    <string name=\"overwrite_file_requirements\">כדי להחליף קבצים אתה צריך להשתמש במקור התמונה של \\\"סייר\\\", נסה לבחור תמונות מחדש, שינינו את מקור התמונה למקור הדרוש</string>\n    <string name=\"empty\">ריק</string>\n    <string name=\"suffix\">סִיוֹמֶת</string>\n    <string name=\"bilinear_sub\">אינטרפולציה ליניארית (או בילינארית, בשני מימדים) טובה בדרך כלל לשינוי גודל תמונה, אך גורמת לריכוך לא רצוי של פרטים ועדיין יכולה להיות מעט משוננים</string>\n    <string name=\"bicubic_sub\">שיטות קנה מידה טובות יותר כוללות דגימה מחדש של Lanczos ומסנני Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">אחת הדרכים הפשוטות יותר להגדיל את הגודל, החלפת כל פיקסל במספר פיקסלים מאותו צבע</string>\n    <string name=\"basic_sub\">מצב קנה המידה הפשוט ביותר של אנדרואיד שהיה בשימוש כמעט בכל האפליקציות</string>\n    <string name=\"catmull_sub\">שיטה לאינטרפולציה חלקה ודגימה מחדש של קבוצה של נקודות בקרה, נפוץ בגרפיקה ממוחשבת ליצירת עקומות חלקות</string>\n    <string name=\"hann_sub\">פונקציית חלונות מיושמת לעתים קרובות בעיבוד אותות כדי למזער דליפה ספקטרלית ולשפר את הדיוק של ניתוח תדרים על ידי הקטנת הקצוות של האות</string>\n    <string name=\"hermite_sub\">טכניקת אינטרפולציה מתמטית המשתמשת בערכים ובנגזרות בנקודות הקצה של קטע עקומה כדי ליצור עקומה חלקה ורציפה</string>\n    <string name=\"lanczos_sub\">שיטת דגימה מחדש השומרת על אינטרפולציה איכותית על ידי החלת פונקציית sinc משוקללת על ערכי הפיקסלים</string>\n    <string name=\"mitchell_sub\">שיטת דגימה חוזרת המשתמשת במסנן קונבולוציה עם פרמטרים מתכווננים כדי להשיג איזון בין חדות ל-anti-aliasing בתמונה המוקטנת</string>\n    <string name=\"allow_multiple_languages\">אפשר מספר שפות</string>\n    <string name=\"segmentation_mode_auto_only\">אוטומטי בלבד</string>\n    <string name=\"segmentation_mode_auto\">אוטומטי</string>\n    <string name=\"segmentation_mode_single_column\">טור יחיד</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">טקסט אנכי בלוק בודד</string>\n    <string name=\"segmentation_mode_single_block\">בלוק בודד</string>\n    <string name=\"segmentation_mode_single_line\">שורה בודדת</string>\n    <string name=\"segmentation_mode_single_word\">מילה בודדת</string>\n    <string name=\"segmentation_mode_circle_word\">עיגול מילה</string>\n    <string name=\"segmentation_mode_single_char\">פח בודד</string>\n    <string name=\"segmentation_mode_sparse_text\">טקסט דליל</string>\n    <string name=\"segmentation_mode_raw_line\">קו גולמי</string>\n    <string name=\"delete_language_sub\">האם ברצונך למחוק נתוני אימון OCR בשפה \\\"%1$s\\\" עבור כל סוגי הזיהוי, או רק עבור אחד נבחר (%2$s)?</string>\n    <string name=\"watermarking_sub\">כיסוי תמונות עם סימני מים ניתנים להתאמה אישית של טקסט/תמונה</string>\n    <string name=\"repeat_watermark_sub\">חוזר על סימן מים על פני תמונה במקום יחיד במיקום נתון</string>\n    <string name=\"offset_x\">היסט X</string>\n    <string name=\"offset_y\">קיזוז Y</string>\n    <string name=\"watermark_type\">סוג סימן מים</string>\n    <string name=\"sierra_lite_dithering\">סיירה לייט דיטה</string>\n    <string name=\"atkinson_dithering\">אטקינסון דיטה</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"b_spline_sub\">משתמש בפונקציות פולינום דו-קוביות המוגדרות באופן חלקי כדי לבצע אינטרפולציה חלקה ולקירוב של עקומה או משטח, ייצוג צורה גמיש ורציף</string>\n    <string name=\"enhanced_glitch\">תקלה משופרת</string>\n    <string name=\"channel_shift_x\">ערוץ Shift X</string>\n    <string name=\"channel_shift_y\">משמרת ערוץ Y</string>\n    <string name=\"corruption_size\">גודל שחיתות</string>\n    <string name=\"side\">צד</string>\n    <string name=\"corruption_shift_x\">משמרת שחיתות X</string>\n    <string name=\"corruption_shift_y\">משמרת שחיתות Y</string>\n    <string name=\"tent_blur\">טשטוש אוהל</string>\n    <string name=\"deutaromaly\">דאוטרנומליה</string>\n    <string name=\"protonomaly\">פרוטנומליה</string>\n    <string name=\"vintage\">בָּצִיר</string>\n    <string name=\"browni\">בראוני</string>\n    <string name=\"coda_chrome\">קודה כרום</string>\n    <string name=\"night_vision\">ראיית לילה</string>\n    <string name=\"warm\">נעים</string>\n    <string name=\"cool\">מגניב</string>\n    <string name=\"protanopia\">פרוטנופיה</string>\n    <string name=\"achromatomaly\">אכרומטומיה</string>\n    <string name=\"pastel\">פסטל</string>\n    <string name=\"orange_haze\">אובך כתום</string>\n    <string name=\"pink_dream\">חלום ורוד</string>\n    <string name=\"golden_hour\">שעת הזהב</string>\n    <string name=\"hot_summer\">קיץ חם</string>\n    <string name=\"soft_spring_light\">אור קפיץ רך</string>\n    <string name=\"autumn_tones\">צלילי סתיו</string>\n    <string name=\"lavender_dream\">לבנדר חלום</string>\n    <string name=\"cyberpunk\">סייברפאנק</string>\n    <string name=\"lemonade_light\">לימונדה אור</string>\n    <string name=\"spectral_fire\">אש ספקטרלית</string>\n    <string name=\"night_magic\">קסם לילה</string>\n    <string name=\"fantasy_landscape\">נוף פנטזיה</string>\n    <string name=\"rainbow_world\">עולם הקשת</string>\n    <string name=\"uchimura\">אוצ\\'ימורה</string>\n    <string name=\"mobius\">מוביוס</string>\n    <string name=\"transition\">מעבר</string>\n    <string name=\"peak\">שִׂיא</string>\n    <string name=\"color_anomaly\">אנומליה בצבע</string>\n    <string name=\"emoji_as_color_scheme_sub\">משתמש בצבע עיקרי של אמוג\\'י כסכמת צבעי אפליקציה במקום אחד שהוגדר ידנית</string>\n    <string name=\"tg_chat_sub\">דון באפליקציה וקבל משוב ממשתמשים אחרים. אתה יכול גם לקבל עדכוני בטא ותובנות כאן.</string>\n    <string name=\"enable_emoji\">אפשר אמוג\\'י</string>\n    <string name=\"enhanced_diamond_pixelation\">פיקסלציה משופרת של יהלום</string>\n    <string name=\"enhanced_circle_pixelation\">פיקסלים עיגולים משופרים</string>\n    <string name=\"color_to_remove\">צבע להסרה</string>\n    <string name=\"remove_color\">הסר צבע</string>\n    <string name=\"recode\">קידוד מחדש</string>\n    <string name=\"erode\">לשחוק</string>\n    <string name=\"anisotropic_diffusion\">דיפוזיה אניזוטרופית</string>\n    <string name=\"diffusion\">ריכוך</string>\n    <string name=\"conduction\">הולכה חשמלית</string>\n    <string name=\"horizontal_wind_stagger\">מתנודד רוח אופקי</string>\n    <string name=\"fast_bilaterial_blur\">טשטוש דו צדדי מהיר</string>\n    <string name=\"poisson_blur\">טשטוש פויסון</string>\n    <string name=\"logarithmic_tone_mapping\">מיפוי טון לוגריתמי</string>\n    <string name=\"crystallize\">לגבש</string>\n    <string name=\"stroke_color\">צבע שבץ</string>\n    <string name=\"fractal_glass\">זכוכית פרקטל</string>\n    <string name=\"amplitude\">אמפליטודה</string>\n    <string name=\"marble\">שיש</string>\n    <string name=\"turbulence\">מערבולת</string>\n    <string name=\"oil\">שמן</string>\n    <string name=\"water_effect\">אפקט המים</string>\n    <string name=\"frequency_x\">תדר X</string>\n    <string name=\"just_size\">גודל</string>\n    <string name=\"frequency_y\">תדר Y</string>\n    <string name=\"amplitude_x\">משרעת X</string>\n    <string name=\"amplitude_y\">משרעת Y</string>\n    <string name=\"perlin_distortion\">פרלין דיסטורשן</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mipping</string>\n    <string name=\"heji_burgess_tone_mapping\">מיפוי טון הייל בורגס</string>\n    <string name=\"aces_filmic_tone_mapping\">מיפוי טון סרטי ACES</string>\n    <string name=\"aces_hill_tone_mapping\">מיפוי הטון של ACES Hill</string>\n    <string name=\"current\">נוֹכְחִי</string>\n    <string name=\"all\">את כל</string>\n    <string name=\"email\">אימייל</string>\n    <string name=\"full_filter\">מסנן מלא</string>\n    <string name=\"start_position\">התחלה</string>\n    <string name=\"center_position\">מרכז</string>\n    <string name=\"end_position\">סוף</string>\n    <string name=\"full_filter_sub\">החל כל שרשראות סינון על תמונות נתונות או תמונה בודדת</string>\n    <string name=\"pdf_tools_sub\">פעל עם קבצי PDF: תצוגה מקדימה, המר לקבוצת תמונות או צור אחת מתמונות נתונות</string>\n    <string name=\"preview_pdf\">תצוגה מקדימה של PDF</string>\n    <string name=\"pdf_to_images\">PDF לתמונות</string>\n    <string name=\"images_to_pdf\">תמונות ל-PDF</string>\n    <string name=\"preview_pdf_sub\">תצוגה מקדימה פשוטה של PDF</string>\n    <string name=\"pdf_to_images_sub\">המר PDF לתמונות בפורמט פלט נתון</string>\n    <string name=\"images_to_pdf_sub\">ארוז תמונות שניתנו לקובץ PDF פלט</string>\n    <string name=\"gradient_maker\">יוצר צבע</string>\n    <string name=\"gradient_maker_sub\">צור שיפוע של גודל פלט נתון עם צבעים וסוג מראה מותאמים אישית</string>\n    <string name=\"speed\">מְהִירוּת</string>\n    <string name=\"dehaze\">מעורפל</string>\n    <string name=\"omega\">אוֹמֶגָה</string>\n    <string name=\"pdf_tools\">כלי PDF</string>\n    <string name=\"rate_app\">דרג אפליקציה</string>\n    <string name=\"rate\">ציון</string>\n    <string name=\"rate_app_sub\">האפליקציה הזו חינמית לחלוטין, אם אתה רוצה שהיא תהפוך לגדולה יותר, נא לככב את הפרויקט ב- Github 😄</string>\n    <string name=\"color_matrix_4x4\">צבע מטריקס 4x4</string>\n    <string name=\"color_matrix_3x3\">מטריצת צבע 3x3</string>\n    <string name=\"simple_effects\">אפקטים פשוטים</string>\n    <string name=\"polaroid\">פולארויד</string>\n    <string name=\"tritonomaly\">טריטנומליה</string>\n    <string name=\"tritanopia\">טריטנופיה</string>\n    <string name=\"deutaronotopia\">דאוטרנופיה</string>\n    <string name=\"achromatopsia\">אכרומטופיה</string>\n    <string name=\"gradient_type_linear\">ליניארי</string>\n    <string name=\"gradient_type_radial\">רדיאלי</string>\n    <string name=\"gradient_type_sweep\">לטאטא</string>\n    <string name=\"gradient_type\">סוג שיפוע</string>\n    <string name=\"center_x\">מרכז X</string>\n    <string name=\"center_y\">מרכז Y</string>\n    <string name=\"tile_mode\">מצב אריחים</string>\n    <string name=\"tile_mode_repeated\">חוזר על עצמו</string>\n    <string name=\"tile_mode_mirror\">מראה</string>\n    <string name=\"tile_mode_clamp\">מהדק</string>\n    <string name=\"tile_mode_decal\">מדבקות</string>\n    <string name=\"color_stops\">עצירות צבע</string>\n    <string name=\"add_color\">הוסף צבע</string>\n    <string name=\"properties\">נכסים</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">מצייר נתיב מלא סגור לפי נתיב נתון</string>\n    <string name=\"draw_path_mode\">מצב ציור נתיב</string>\n    <string name=\"double_line_arrow\">חץ קו כפול</string>\n    <string name=\"free_drawing\">ציור חינם</string>\n    <string name=\"double_arrow\">חץ כפול</string>\n    <string name=\"line_arrow\">חץ קו</string>\n    <string name=\"arrow\">חץ</string>\n    <string name=\"line\">קו</string>\n    <string name=\"arrow_sub\">מצייר חץ מצביע מנתיב נתון</string>\n    <string name=\"double_line_arrow_sub\">מצייר חץ מצביע כפול מנקודת התחלה לנקודת סיום בתור קו</string>\n    <string name=\"double_arrow_sub\">מצייר חץ מצביע כפול מנתיב נתון</string>\n    <string name=\"outlined_oval\">סגלגל מתואר</string>\n    <string name=\"outlined_rect\">מתואר רקט</string>\n    <string name=\"oval\">סגלגל</string>\n    <string name=\"rect\">רקט</string>\n    <string name=\"dithering\">התרפקות</string>\n    <string name=\"quantizier\">קוונטיזיר</string>\n    <string name=\"gray_scale\">סולם אפור</string>\n    <string name=\"bayer_two_dithering\">באייר שניים</string>\n    <string name=\"bayer_three_dithering\">באייר שלוש על שלוש מתנודדות</string>\n    <string name=\"bayer_four_dithering\">באייר ארבע על ארבע דיבורים</string>\n    <string name=\"bayer_eight_dithering\">באייר שמונה על שמונה דיבורים</string>\n    <string name=\"floyd_steinberg_dithering\">פלויד סטיינברג דיטה</string>\n    <string name=\"jarvis_judice_ninke_dithering\">ג\\'רוויס ג\\'ודיס נינקה דיטה</string>\n    <string name=\"sierra_dithering\">סיירה דיטרינג</string>\n    <string name=\"two_row_sierra_dithering\">שתי שורות סיירה דיטה</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">שקר פלויד סטיינברג דיטה</string>\n    <string name=\"left_to_right_dithering\">שיוף משמאל לימין</string>\n    <string name=\"random_dithering\">חילוף אקראי</string>\n    <string name=\"simple_threshold_dithering\">הסרת סף פשוטה</string>\n    <string name=\"max_colors_count\">ספירת צבעים מקסימלית</string>\n    <string name=\"saving_almost_complete\">השמירה כמעט הושלמה. ביטול כעת יחייב שמירה שוב.</string>\n    <string name=\"mask_color\">צבע מסכה</string>\n    <string name=\"scale_mode\">מצב קנה מידה</string>\n    <string name=\"bilinear\">ביליניארי</string>\n    <string name=\"hann\">האן</string>\n    <string name=\"hermite\">הרמיט</string>\n    <string name=\"lanczos\">לנצ\\'וס</string>\n    <string name=\"mitchell\">מיטשל</string>\n    <string name=\"nearest\">הכי קרוב</string>\n    <string name=\"spline\">שֶׁגֶם</string>\n    <string name=\"basic\">בסיסי</string>\n    <string name=\"default_value\">ערך ברירת מחדל</string>\n    <string name=\"value_in_range\">ערך בטווח %1$s - %2$s</string>\n    <string name=\"sigma\">סיגמא</string>\n    <string name=\"spatial_sigma\">סיגמא מרחבית</string>\n    <string name=\"median_blur\">טשטוש חציוני</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"spline_sub\">משתמש בפונקציות פולינום המוגדרות חלקית כדי לבצע אינטרפולציה חלקה ולהעריך עקומה או משטח, מאפשר ייצוג צורה גמיש ורציף</string>\n    <string name=\"only_clip\">רק קליפ</string>\n    <string name=\"only_clip_sub\">שמירה לאחסון לא תתבצע, ותנסה להכניס תמונה ללוח בלבד</string>\n    <string name=\"icon_shape_sub\">מוסיף מיכל עם צורה נבחרת מתחת לסמלים המובילים של כרטיסים</string>\n    <string name=\"icon_shape\">צורת סמל</string>\n    <string name=\"image_stitching\">תפירת תמונה</string>\n    <string name=\"image_stitching_sub\">שלב את התמונות הנתונות כדי לקבל תמונה אחת גדולה</string>\n    <string name=\"randomize_filename_sub\">אם מופעל שם קובץ הפלט יהיה אקראי לחלוטין</string>\n    <string name=\"brightness_enforcement\">אכיפת בהירות</string>\n    <string name=\"screen\">מסך</string>\n    <string name=\"gradient_maker_type_image\">שכבת שיפוע</string>\n    <string name=\"gradient_maker_type_image_sub\">חבר כל גרדיאנט של החלק העליון של תמונות נתונות</string>\n    <string name=\"transformations\">טרנספורמציות</string>\n    <string name=\"camera\">מצלמה</string>\n    <string name=\"camera_sub\">צלם תמונה בעזרת המצלמה, שימו לב שאפשר לקבל רק תמונה אחת ממקור תמונה זה</string>\n    <string name=\"output_image_scale\">סולם תמונה פלט</string>\n    <string name=\"image_orientation\">כיוון תמונה</string>\n    <string name=\"horizontal\">אופקי</string>\n    <string name=\"vertical\">אנכי</string>\n    <string name=\"scale_small_images_to_large\">קנה מידה של תמונות קטנות לגדולות</string>\n    <string name=\"scale_small_images_to_large_sub\">תמונות קטנות יותאמו לגדולה ברצף אם מופעלת</string>\n    <string name=\"images_order\">סדר תמונות</string>\n    <string name=\"grain\">תְבוּאָה</string>\n    <string name=\"unsharp\">לא חד</string>\n    <string name=\"purple_mist\">ערפל סגול</string>\n    <string name=\"sunrise\">זריחה</string>\n    <string name=\"colorful_swirl\">מערבולת צבעונית</string>\n    <string name=\"color_explosion\">פיצוץ צבע</string>\n    <string name=\"electric_gradient\">שיפוע חשמלי</string>\n    <string name=\"caramel_darkness\">כהה קרמל</string>\n    <string name=\"futuristic_gradient\">שיפוע עתידני</string>\n    <string name=\"green_sun\">שמש ירוקה</string>\n    <string name=\"deep_purple\">סגול עמוק</string>\n    <string name=\"space_portal\">פורטל החלל</string>\n    <string name=\"red_swirl\">מערבולת אדומה</string>\n    <string name=\"digital_code\">קוד דיגיטלי</string>\n    <string name=\"watermarking\">סימון מים</string>\n    <string name=\"repeat_watermark\">חזור על סימן מים</string>\n    <string name=\"watermarking_image_sub\">תמונה זו תשמש כתבנית לסימון מים</string>\n    <string name=\"text_color\">צבע טקסט</string>\n    <string name=\"overlay_mode\">מצב שכבת-על</string>\n    <string name=\"pixel_size\">גודל פיקסל</string>\n    <string name=\"lock_draw_orientation\">נעל את כיוון הציור</string>\n    <string name=\"lock_draw_orientation_sub\">אם מופעל במצב ציור, המסך לא יסתובב</string>\n    <string name=\"bokeh\">בוקה</string>\n    <string name=\"gif_tools\">כלי GIF</string>\n    <string name=\"gif_tools_sub\">המר תמונות לתמונת GIF או חלץ מסגרות מתמונת GIF נתונה</string>\n    <string name=\"gif_type_to_image\">GIF לתמונות</string>\n    <string name=\"gif_type_to_image_sub\">המרת קובץ GIF לקבוצת תמונות</string>\n    <string name=\"gif_type_to_gif_sub\">המר אצווה של תמונות לקובץ GIF</string>\n    <string name=\"gif_type_to_gif\">תמונות ל-GIF</string>\n    <string name=\"select_gif_image_to_start\">בחר תמונת GIF כדי להתחיל</string>\n    <string name=\"use_size_of_first_frame\">השתמש בגודל של מסגרת ראשונה</string>\n    <string name=\"use_size_of_first_frame_sub\">החלף את הגודל שצוין במידות המסגרת הראשונה</string>\n    <string name=\"repeat_count\">חזור על ספירה</string>\n    <string name=\"frame_delay\">השהיית מסגרת</string>\n    <string name=\"millis\">מילי</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">השתמש בלאסו</string>\n    <string name=\"use_lasso_sub\">משתמש ב-Lasso כמו במצב ציור כדי לבצע מחיקה</string>\n    <string name=\"original_image_preview_alpha\">תצוגה מקדימה של תמונה מקורית אלפא</string>\n    <string name=\"mask_filter\">מסנן מסכה</string>\n    <string name=\"masks\">מסכות</string>\n    <string name=\"random_emojis_sub\">האימוג\\'י של סרגל האפליקציה ישתנה באקראי</string>\n    <string name=\"random_emojis\">אמוג\\'י אקראיים</string>\n    <string name=\"random_emojis_error\">לא ניתן להשתמש בבחירת אמוג\\'י אקראית בזמן שהאימוג\\'י מושבתים</string>\n    <string name=\"emoji_selection_error\">לא ניתן לבחור אמוג\\'י בזמן שבחירת אימוג\\'ים אקראית פעילה</string>\n    <string name=\"check_for_updates\">בדוק עדכונים</string>\n    <string name=\"aspect_ratio\">יחס גובה-רוחב</string>\n    <string name=\"delete_color_scheme_title\">מחק סכמה</string>\n    <string name=\"add_mask\">הוסף מסכה</string>\n    <string name=\"old_tv\">טלוויזיה ישנה</string>\n    <string name=\"shuffle_blur\">ערבוב טשטוש</string>\n    <string name=\"recognize_text\">OCR (זיהוי טקסט)</string>\n    <string name=\"recognize_text_sub\">זיהוי טקסט מתמונה נתונה, 120+ שפות נתמכות</string>\n    <string name=\"picture_has_no_text\">לתמונה אין טקסט, או שהאפליקציה לא מצאה אותה</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">סוג זיהוי</string>\n    <string name=\"fast\">מָהִיר</string>\n    <string name=\"standard\">תֶקֶן</string>\n    <string name=\"best\">הטוב ביותר</string>\n    <string name=\"no_data\">אין מידע</string>\n    <string name=\"download_description\">לתפקוד תקין של Tesseract OCR יש להוריד נתוני אימון נוספים (%1$s) למכשיר שלך. \\nהאם ברצונך להוריד נתוני %2$s?</string>\n    <string name=\"download\">הורד</string>\n    <string name=\"no_connection\">אין חיבור, בדוק את זה ונסה שוב כדי להוריד דגמי רכבת</string>\n    <string name=\"downloaded_languages\">שפות שהורדו</string>\n    <string name=\"available_languages\">שפות זמינות</string>\n    <string name=\"segmentation_mode\">מצב פילוח</string>\n    <string name=\"restore_background_sub\">המברשת תשחזר את הרקע במקום למחוק</string>\n    <string name=\"horizontal_grid\">רשת אופקית</string>\n    <string name=\"vertical_grid\">רשת אנכית</string>\n    <string name=\"stitch_mode\">מצב תפירה</string>\n    <string name=\"rows_count\">ספירת שורות</string>\n    <string name=\"columns_count\">ספירת עמודות</string>\n    <string name=\"use_pixel_switch\">השתמש ב-Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">משתמש במתג דמוי פיקסל של Google</string>\n    <string name=\"slide\">שקופית</string>\n    <string name=\"side_by_side\">זה לצד זה</string>\n    <string name=\"toggle_tap\">החלף הקש</string>\n    <string name=\"transparency\">שְׁקִיפוּת</string>\n    <string name=\"saved_to_original\">קובץ שהוחלף עם השם %1$s ביעד המקורי</string>\n    <string name=\"magnifier\">זכוכית מגדלת</string>\n    <string name=\"magnifier_sub\">מאפשר זכוכית מגדלת בחלק העליון של האצבע במצבי ציור עבור נגישות טובה יותר</string>\n    <string name=\"force_exif_widget_initial_value\">לכפות ערך התחלתי</string>\n    <string name=\"force_exif_widget_initial_value_sub\">מאלץ את הווידג\\'ט של ה-exif להיבדק תחילה</string>\n    <string name=\"favorite\">אהוב</string>\n    <string name=\"no_favorite_filters\">עדיין לא נוספו מסננים מועדפים</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"native_stack_blur\">טשטוש מחסנית מקורי</string>\n    <string name=\"tilt_shift\">הטיה שיפט</string>\n    <string name=\"regular\">רגיל</string>\n    <string name=\"blur_edges\">טשטוש קצוות</string>\n    <string name=\"blur_edges_sub\">מצייר קצוות מטושטשים מתחת לתמונה המקורית כדי למלא רווחים סביבה במקום צבע בודד אם מופעל</string>\n    <string name=\"confetti\">פתיתי נייר ססגוניים</string>\n    <string name=\"confetti_sub\">קונפטי יוצג על שמירה, שיתוף ופעולות עיקריות אחרות</string>\n    <string name=\"secure_mode\">מצב בטוח</string>\n    <string name=\"secure_mode_sub\">מסתיר תוכן במסך \\'יישומים אחרונים\\', לא יהיה ניתן ללכוד או להקליט.</string>\n    <string name=\"crop_description\">התמונות ייחתכו במרכז לגודל שהוזן. הקנבס יורחב עם צבע רקע נתון אם התמונה קטנה מהמידות שהוזנו.</string>\n    <string name=\"pixelation\">פיקסלים</string>\n    <string name=\"stroke_pixelation\">Pixelation שבץ</string>\n    <string name=\"replace_color\">החלף צבע</string>\n    <string name=\"fidelity_sub\">סכימה שדומה מאוד לסכימת התוכן</string>\n    <string name=\"mask_filter_sub\">החלת שרשראות סינון על אזורים מסווים, כל אזור מסכה יכול לקבוע את קבוצת המסננים שלו</string>\n    <string name=\"mask_indexed\">מסכה %d</string>\n    <string name=\"mask_preview\">תצוגה מקדימה של מסכה</string>\n    <string name=\"mask_preview_sub\">מסכת מסנן מצוירת תוצג כדי להראות לך את התוצאה המשוערת</string>\n    <string name=\"simple_variants\">גרסאות פשוטות</string>\n    <string name=\"highlighter\">סימון</string>\n    <string name=\"neon\">ניאון</string>\n    <string name=\"pen\">עט</string>\n    <string name=\"privacy_blur\">טשטוש פרטיות</string>\n    <string name=\"neon_sub\">הוסף אפקט זוהר לציורים שלך</string>\n    <string name=\"pen_sub\">ברירת מחדל, הפשוטה ביותר - רק הצבע</string>\n    <string name=\"pixelation_sub\">דומה לטשטוש הפרטיות, אבל מפיקסל במקום טשטוש</string>\n    <string name=\"auto_rotate_limits\">סיבוב אוטומטי</string>\n    <string name=\"auto_rotate_limits_sub\">מאפשר לאמץ תיבת מגבלה עבור כיוון תמונה</string>\n    <string name=\"palette_style\">סגנון פלטה</string>\n    <string name=\"tonal_spot\">נקודה טונאלית</string>\n    <string name=\"neutral\">ניטראלי</string>\n    <string name=\"vibrant\">תוסס</string>\n    <string name=\"expressive\">אקספרסבי</string>\n    <string name=\"rainbow\">קשת בענן</string>\n    <string name=\"fruit_salad\">סלט פירות</string>\n    <string name=\"highlighter_sub\">צייר נתיבי סימון מחודדים שקופים למחצה</string>\n    <string name=\"privacy_blur_sub\">מטשטשת תמונה מתחת לנתיב המצויר כדי לאבטח כל מה שאתה רוצה להסתיר</string>\n    <string name=\"containers_shadow\">מיכלים</string>\n    <string name=\"containers_shadow_sub\">צייר צל מאחורי קונטיינרים</string>\n    <string name=\"sliders_shadow\">סליידרים</string>\n    <string name=\"switches_shadow\">מתגים</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">כפתורים</string>\n    <string name=\"sliders_shadow_sub\">צייר צל מאחורי המחוונים</string>\n    <string name=\"switches_shadow_sub\">מאפשר ציור צל מאחורי מתגים</string>\n    <string name=\"fabs_shadow_sub\">מאפשר ציור צל מאחורי לחצני פעולה צפים</string>\n    <string name=\"buttons_shadow_sub\">צייר צל מאחורי כפתורים</string>\n    <string name=\"foss_update_checker_warning\">בודק העדכונים הזה יתחבר ל-GitHub בגלל בדיקה אם יש עדכון חדש זמין</string>\n    <string name=\"attention\">תשומת הלב</string>\n    <string name=\"fading_edges\">קצוות דוהים</string>\n    <string name=\"disabled\">השבת</string>\n    <string name=\"both\">שניהם</string>\n    <string name=\"invert_colors\">הפוך צבעים</string>\n    <string name=\"invert_colors_sub\">מחליף צבעי ערכת נושא לשליליים אם מופעל</string>\n    <string name=\"exit\">יציאה</string>\n    <string name=\"preview_closing\">אם תעזוב את התצוגה המקדימה כעת, תצטרך להוסיף את התמונות שוב</string>\n    <string name=\"image_format\">פורמט תמונה</string>\n    <string name=\"material_you_sub\">יוצר\\\"Material You\\\" צבעים מתמונה</string>\n    <string name=\"copy_as_compose_code\">העתק כקוד \\\" Jetpack Compose\\\"</string>\n    <string name=\"dark_colors\">צבעים כהים</string>\n    <string name=\"dark_colors_sub\">משתמש ערכת צבעי מצב הלילה במקום וריאנט אור</string>\n    <string name=\"ring_blur\">טשטוש טבעת</string>\n    <string name=\"cross_blur\">טשטוש צולב</string>\n    <string name=\"circle_blur\">טשטוש מעגל</string>\n    <string name=\"star_blur\">טשטוש כוכבים</string>\n    <string name=\"linear_tilt_shift\">שינוי הטיה ליניארי</string>\n    <string name=\"tags_to_remove\">תגיות להסרה</string>\n    <string name=\"apng_tools_sub\">המר תמונות לתמונת APNG או חלץ מסגרות מתמונת APNG נתונה</string>\n    <string name=\"apng_type_to_image\">APNG לתמונות</string>\n    <string name=\"apng_type_to_image_sub\">המרת קובץ APNG לקבוצת תמונות</string>\n    <string name=\"apng_type_to_apng\">תמונות ל-APNG</string>\n    <string name=\"select_apng_image_to_start\">בחר תמונת APNG כדי להתחיל</string>\n    <string name=\"motion_blur\">טשטוש תנועה</string>\n    <string name=\"zip_sub\">צור קובץ Zip מקבצים או תמונות נתונים</string>\n    <string name=\"apng_type_to_apng_sub\">המר אצווה של תמונות לקובץ APNG</string>\n    <string name=\"zip\">רוכסן</string>\n    <string name=\"apng_tools\">כלי APNG</string>\n    <string name=\"drag_handle_width\">רוחב ידית גרור</string>\n    <string name=\"confetti_type\">סוג קונפטי</string>\n    <string name=\"corners\">פינות</string>\n    <string name=\"jxl_tools\">כלי JXL</string>\n    <string name=\"jxl_tools_sub\">בצע קידוד JXL ~ JPEG ללא אובדן איכות, או המרת GIF/APNG לאנימציית JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL ל JPEG</string>\n    <string name=\"festive\">חגיגי</string>\n    <string name=\"explode\">מתפוצץ</string>\n    <string name=\"rain\">גֶשֶׁם</string>\n    <string name=\"jxl_type_to_jpeg_sub\">בצע המרת קידוד ללא הפסדים מ-JXL ל-JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">בצע המרת קידוד ללא הפסדים מ-JPEG ל-JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG עד JXL</string>\n    <string name=\"select_jxl_image_to_start\">בחר תמונת JXL כדי להתחיל</string>\n    <string name=\"fast_gaussian_blur_2d\">טשטוש גאוס מהיר 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">טשטוש גאוס מהיר תלת מימד</string>\n    <string name=\"fast_gaussian_blur_4d\">טשטוש גאוס מהיר 4D</string>\n    <string name=\"auto_paste\">פסחא לרכב</string>\n    <string name=\"auto_paste_sub\">מאפשר לאפליקציה להדביק אוטומטית נתוני לוח, כך שהם יופיעו במסך הראשי ותוכלו לעבד אותם</string>\n    <string name=\"harmonization_color\">צבע הרמוניזציה</string>\n    <string name=\"harmonization_level\">רמת הרמוניזציה</string>\n    <string name=\"lanczos_bessel\">לנצ\\'וס בסל</string>\n    <string name=\"lanczos_bessel_sub\">שיטת דגימה מחדש השומרת על אינטרפולציה איכותית על ידי החלת פונקציית Bessel (jinc) על ערכי הפיקסלים</string>\n    <string name=\"gif_type_to_jxl\">GIF ל-JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">המר תמונות GIF לתמונות מונפשות של JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG ל-JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">המר תמונות APNG לתמונות מונפשות של JXL</string>\n    <string name=\"jxl_type_to_images\">JXL לתמונות</string>\n    <string name=\"jxl_type_to_images_sub\">המר אנימציית JXL לקבוצת תמונות</string>\n    <string name=\"jxl_type_to_jxl\">תמונות ל-JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">המר אצווה של תמונות לאנימציית JXL</string>\n    <string name=\"behavior\">התנהגות</string>\n    <string name=\"skip_file_picking\">דלג על בחירת קבצים</string>\n    <string name=\"skip_file_picking_sub\">בוחר הקבצים יוצג מיד אם זה אפשרי במסך שנבחר</string>\n    <string name=\"generate_previews\">צור תצוגות מקדימות</string>\n    <string name=\"generate_previews_sub\">מאפשר יצירת תצוגה מקדימה, זה עשוי לעזור למנוע קריסות במכשירים מסוימים, זה גם משבית חלק מפונקציונליות העריכה בתוך אפשרות עריכה אחת</string>\n    <string name=\"lossy_compression\">דחיסה אבודה</string>\n    <string name=\"lossy_compression_sub\">משתמש בדחיסה מאבדת כדי להקטין את גודל הקובץ במקום ללא אובדן</string>\n    <string name=\"compression_type\">סוג דחיסה</string>\n    <string name=\"speed_sub\">שולט במהירות פענוח התמונה המתקבלת, זה אמור לעזור לפתוח את התמונה המתקבלת מהר יותר, הערך של %1$s פירושו הפענוח האיטי ביותר, ואילו %2$s - המהיר ביותר, הגדרה זו עשויה להגדיל את גודל תמונת הפלט</string>\n    <string name=\"sorting\">מיון</string>\n    <string name=\"sort_by_date\">תאריך</string>\n    <string name=\"sort_by_date_reversed\">תאריך (הפוך)</string>\n    <string name=\"sort_by_name\">שם</string>\n    <string name=\"sort_by_name_reversed\">שם (הפוך)</string>\n    <string name=\"channels_configuration\">תצורת ערוצים</string>\n    <string name=\"header_today\">היום</string>\n    <string name=\"header_yesterday\">אתמול</string>\n    <string name=\"embedded_picker\">בוחר מוטבע</string>\n    <string name=\"embedded_picker_sub\">בוחר התמונות של ארגז הכלים של תמונות</string>\n    <string name=\"no_permissions\">אין הרשאות</string>\n    <string name=\"request\">בקשה</string>\n    <string name=\"pick_multiple_media\">בחירת מדיה מרובה</string>\n    <string name=\"pick_single_media\">בחר מדיה אחת</string>\n    <string name=\"pick\">בחירה</string>\n    <string name=\"try_again\">נסה שוב</string>\n    <string name=\"show_settings_in_landscape\">הצג הגדרות בנוף</string>\n    <string name=\"show_settings_in_landscape_sub\">אם זה מושבת, הגדרות מצב לרוחב ייפתחו על הכפתור בסרגל האפליקציה העליון כמו תמיד, במקום אפשרות גלויה קבועה</string>\n    <string name=\"fullscreen_settings\">הגדרות מסך מלא</string>\n    <string name=\"fullscreen_settings_sub\">הפעל אותו ודף ההגדרות ייפתח תמיד כמסך מלא במקום גיליון מגירה הניתן להחלקה</string>\n    <string name=\"switch_type\">סוג מתג</string>\n    <string name=\"compose\">לחבר</string>\n    <string name=\"compose_switch_sub\">Jetpack Compose חומר שאתה מחליף</string>\n    <string name=\"material_you_switch_sub\">חומר שאתה מחליף</string>\n    <string name=\"max\">מקסימום</string>\n    <string name=\"resize_anchor\">שנה גודל עוגן</string>\n    <string name=\"pixel_switch\">פיקסל</string>\n    <string name=\"fluent_switch\">שׁוֹטֵף</string>\n    <string name=\"fluent_switch_sub\">מתג המבוסס על מערכת העיצוב \\\"Fluent\\\".</string>\n    <string name=\"cupertino_switch\">קופרטינו</string>\n    <string name=\"cupertino_switch_sub\">מתג המבוסס על מערכת העיצוב \\\"קופרטינו\\\".</string>\n    <string name=\"images_to_svg\">תמונות ל-SVG</string>\n    <string name=\"images_to_svg_sub\">עקבו אחר תמונות שניתנו לתמונות SVG</string>\n    <string name=\"use_sampled_palette\">השתמש בלוח מדגם</string>\n    <string name=\"use_sampled_palette_sub\">פלטת קוונטיזציה תידגם אם אפשרות זו מופעלת</string>\n    <string name=\"path_omit\">השמיטת נתיב</string>\n    <string name=\"svg_warning\">השימוש בכלי זה למעקב אחר תמונות גדולות ללא הקטנת קנה מידה אינו מומלץ, הוא עלול לגרום לקריסה ולהגדיל את זמן העיבוד</string>\n    <string name=\"downscale_image\">תמונה בקנה מידה נמוך</string>\n    <string name=\"downscale_image_sub\">התמונה תוקטן לממדים נמוכים יותר לפני העיבוד, זה עוזר לכלי לעבוד מהר ובטוח יותר</string>\n    <string name=\"min_color_ratio\">יחס צבע מינימלי</string>\n    <string name=\"lines_threshold\">סף קווים</string>\n    <string name=\"quadratic_threshold\">סף ריבועי</string>\n    <string name=\"coordinates_rounding_tolerance\">קואורדינטות עיגול סובלנות</string>\n    <string name=\"path_scale\">סולם נתיב</string>\n    <string name=\"reset_properties\">אפס מאפיינים</string>\n    <string name=\"reset_properties_sub\">כל המאפיינים יוגדרו לערכי ברירת מחדל, שימו לב שלא ניתן לבטל פעולה זו</string>\n    <string name=\"detailed\">מְפוֹרָט</string>\n    <string name=\"default_line_width\">ברירת המחדל של רוחב קו</string>\n    <string name=\"engine_mode\">מצב מנוע</string>\n    <string name=\"legacy\">מוֹרֶשֶׁת</string>\n    <string name=\"lstm_network\">רשת LSTM</string>\n    <string name=\"legacy_and_lstm\">דור קודם ו-LSTM</string>\n    <string name=\"convert\">המרה</string>\n    <string name=\"convert_sub\">המרת קבוצות תמונות לפורמט נתון</string>\n    <string name=\"add_new_folder\">הוסף תיקיה חדשה</string>\n    <string name=\"tag_bits_per_sample\">ביטים לדגימה</string>\n    <string name=\"tag_compression\">דְחִיסָה</string>\n    <string name=\"tag_photometric_interpretation\">פרשנות פוטומטרית</string>\n    <string name=\"tag_samples_per_pixel\">דגימות לכל פיקסל</string>\n    <string name=\"tag_planar_configuration\">תצורה מישורית</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">דגימת משנה של Y Cb Cr</string>\n    <string name=\"tag_y_cb_cr_positioning\">מיקום Y Cb Cr</string>\n    <string name=\"tag_x_resolution\">X רזולוציה</string>\n    <string name=\"tag_y_resolution\">Y רזולוציה</string>\n    <string name=\"tag_resolution_unit\">יחידת רזולוציה</string>\n    <string name=\"tag_strip_offsets\">סטריפ קיזוז</string>\n    <string name=\"tag_rows_per_strip\">שורות לכל רצועה</string>\n    <string name=\"tag_strip_byte_counts\">Strip Bytes Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">פורמט JPEG Interchange</string>\n    <string name=\"tag_jpeg_interchange_format_length\">אורך פורמט JPEG Interchange</string>\n    <string name=\"tag_transfer_function\">פונקציית העברה</string>\n    <string name=\"tag_white_point\">נקודה לבנה</string>\n    <string name=\"tag_primary_chromaticities\">צבעוניות ראשונית</string>\n    <string name=\"tag_y_cb_cr_coefficients\">מקדמי Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">הפניה שחור לבן</string>\n    <string name=\"tag_datetime\">תאריך שעה</string>\n    <string name=\"tag_image_description\">תיאור תמונה</string>\n    <string name=\"tag_make\">לַעֲשׂוֹת</string>\n    <string name=\"tag_model\">דֶגֶם</string>\n    <string name=\"tag_software\">תוֹכנָה</string>\n    <string name=\"tag_artist\">אָמָן</string>\n    <string name=\"tag_copyright\">זְכוּת יְוֹצרִים</string>\n    <string name=\"tag_exif_version\">גרסת ה-Exif</string>\n    <string name=\"tag_flashpix_version\">גרסת פלאשפיקס</string>\n    <string name=\"tag_color_space\">מרחב צבע</string>\n    <string name=\"tag_gamma\">גמא</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y Dimension</string>\n    <string name=\"tag_compressed_bits_per_pixel\">ביטים דחוסים לכל פיקסל</string>\n    <string name=\"tag_maker_note\">הערה מייצרת</string>\n    <string name=\"tag_user_comment\">הערת משתמש</string>\n    <string name=\"tag_related_sound_file\">קובץ סאונד קשור</string>\n    <string name=\"tag_datetime_original\">תאריך שעה מקורי</string>\n    <string name=\"tag_datetime_digitized\">תאריך זמן דיגיטלי</string>\n    <string name=\"tag_offset_time\">זמן קיזוז</string>\n    <string name=\"tag_offset_time_original\">קיזוז זמן מקורי</string>\n    <string name=\"tag_offset_time_digitized\">קיזוז זמן דיגיטלי</string>\n    <string name=\"tag_subsec_time\">זמן משנה</string>\n    <string name=\"tag_subsec_time_original\">זמן משנה משנה</string>\n    <string name=\"tag_subsec_time_digitized\">תת שניות זמן דיגיטלי</string>\n    <string name=\"tag_exposure_time\">זמן חשיפה</string>\n    <string name=\"tag_f_number\">מספר F</string>\n    <string name=\"tag_exposure_program\">תוכנית חשיפה</string>\n    <string name=\"tag_spectral_sensitivity\">רגישות ספקטרלית</string>\n    <string name=\"tag_photographic_sensitivity\">רגישות לצילום</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">סוג רגישות</string>\n    <string name=\"tag_standard_output_sensitivity\">רגישות פלט סטנדרטית</string>\n    <string name=\"tag_recommended_exposure_index\">מדד החשיפה המומלץ</string>\n    <string name=\"tag_iso_speed\">מהירות ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">מהירות ISO רוחב yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Speed ​​Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">ערך מהירות תריס</string>\n    <string name=\"tag_aperture_value\">ערך צמצם</string>\n    <string name=\"tag_brightness_value\">ערך בהירות</string>\n    <string name=\"tag_exposure_bias_value\">ערך הטיית חשיפה</string>\n    <string name=\"tag_max_aperture_value\">ערך צמצם מרבי</string>\n    <string name=\"tag_subject_distance\">מרחק נושא</string>\n    <string name=\"tag_metering_mode\">מצב מדידה</string>\n    <string name=\"tag_flash\">הֶבזֵק</string>\n    <string name=\"tag_subject_area\">אזור נושא</string>\n    <string name=\"tag_focal_length\">אורך מוקד</string>\n    <string name=\"tag_flash_energy\">אנרגיית פלאש</string>\n    <string name=\"tag_spatial_frequency_response\">תגובת תדר מרחבית</string>\n    <string name=\"tag_focal_plane_x_resolution\">רזולוציית מישור מוקד X</string>\n    <string name=\"tag_focal_plane_y_resolution\">רזולוציית מישור מוקד Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">יחידת רזולוציה של מישור מוקד</string>\n    <string name=\"tag_subject_location\">מיקום הנושא</string>\n    <string name=\"tag_exposure_index\">מדד החשיפה</string>\n    <string name=\"tag_sensing_method\">שיטת חישה</string>\n    <string name=\"tag_file_source\">מקור הקובץ</string>\n    <string name=\"tag_cfa_pattern\">דפוס CFA</string>\n    <string name=\"tag_custom_rendered\">עיבוד מותאם אישית</string>\n    <string name=\"tag_exposure_mode\">מצב חשיפה</string>\n    <string name=\"tag_white_balance\">איזון לבן</string>\n    <string name=\"tag_digital_zoom_ratio\">יחס זום דיגיטלי</string>\n    <string name=\"tag_focal_length_in_35mm_film\">אורך מוקד בסרט 35 מ\\\"מ</string>\n    <string name=\"tag_scene_capture_type\">סוג לכידת סצנה</string>\n    <string name=\"tag_gain_control\">השג שליטה</string>\n    <string name=\"tag_contrast\">לְהַשְׁווֹת</string>\n    <string name=\"tag_saturation\">רִוּוּי</string>\n    <string name=\"tag_sharpness\">חַדוּת</string>\n    <string name=\"tag_device_setting_description\">תיאור הגדרת ההתקן</string>\n    <string name=\"tag_subject_distance_range\">טווח מרחק נושא</string>\n    <string name=\"tag_image_unique_id\">מזהה ייחודי לתמונה</string>\n    <string name=\"tag_camera_owner_name\">שם בעל המצלמה</string>\n    <string name=\"tag_body_serial_number\">מספר סידורי גוף</string>\n    <string name=\"tag_lens_specification\">מפרט עדשה</string>\n    <string name=\"tag_lens_make\">תוצרת עדשה</string>\n    <string name=\"tag_lens_model\">דגם עדשה</string>\n    <string name=\"tag_lens_serial_number\">מספר סידורי של עדשה</string>\n    <string name=\"tag_gps_version_id\">מזהה גרסת GPS</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Ref</string>\n    <string name=\"tag_gps_latitude\">GPS רוחב</string>\n    <string name=\"tag_gps_longitude_ref\">GPS קו אורך Ref</string>\n    <string name=\"tag_gps_longitude\">GPS קו אורך</string>\n    <string name=\"tag_gps_altitude_ref\">GPS גובה רפ</string>\n    <string name=\"tag_gps_altitude\">GPS גובה</string>\n    <string name=\"tag_gps_timestamp\">חותמת זמן GPS</string>\n    <string name=\"tag_gps_satellites\">לווייני GPS</string>\n    <string name=\"tag_gps_status\">מצב GPS</string>\n    <string name=\"tag_gps_measure_mode\">מצב מדידת GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">מהירות GPS Ref</string>\n    <string name=\"tag_gps_speed\">מהירות GPS</string>\n    <string name=\"tag_gps_track_ref\">מסלול GPS Ref</string>\n    <string name=\"tag_gps_track\">מסלול GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img כיוון Ref</string>\n    <string name=\"tag_gps_img_direction\">GPS Img כיוון</string>\n    <string name=\"tag_gps_map_datum\">תאריך מפה של GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS יעד קו אורך Ref</string>\n    <string name=\"tag_gps_dest_longitude\">קו אורך יעד של GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">מיסב יעד GPS</string>\n    <string name=\"tag_gps_dest_bearing\">מיסב יעד GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">מרחק יעד GPS Ref</string>\n    <string name=\"tag_gps_dest_distance\">מרחק יעד GPS</string>\n    <string name=\"tag_gps_processing_method\">שיטת עיבוד GPS</string>\n    <string name=\"tag_gps_area_information\">מידע על אזור GPS</string>\n    <string name=\"tag_gps_datestamp\">חותמת תאריך של GPS</string>\n    <string name=\"tag_gps_differential\">הפרש GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">שגיאת מיקום GPS H</string>\n    <string name=\"tag_interoperability_index\">אינדקס יכולת פעולה הדדית</string>\n    <string name=\"tag_dng_version\">גרסת DNG</string>\n    <string name=\"tag_default_crop_size\">גודל חיתוך ברירת מחדל</string>\n    <string name=\"tag_orf_preview_image_start\">תצוגה מקדימה של התחלת תמונה</string>\n    <string name=\"tag_orf_preview_image_length\">אורך תמונה בתצוגה מקדימה</string>\n    <string name=\"tag_orf_aspect_frame\">מסגרת היבט</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">גבול תחתון של חיישן</string>\n    <string name=\"tag_rw2_sensor_left_border\">גבול שמאל של חיישן</string>\n    <string name=\"tag_rw2_sensor_right_border\">גבול ימין של חיישן</string>\n    <string name=\"tag_rw2_sensor_top_border\">גבול עליון חיישן</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">צייר טקסט על הנתיב עם גופן וצבע נתונים</string>\n    <string name=\"font_size\">גודל גופן</string>\n    <string name=\"watermark_size\">גודל סימן מים</string>\n    <string name=\"repeat_text\">חזור על טקסט</string>\n    <string name=\"repeat_text_sub\">הטקסט הנוכחי יחזור על עצמו עד לסיום הנתיב במקום ציור חד פעמי</string>\n    <string name=\"dash_size\">גודל מקף</string>\n    <string name=\"draw_mode_image_sub\">השתמש בתמונה שנבחרה כדי לצייר אותה לאורך נתיב נתון</string>\n    <string name=\"draw_image_sub\">תמונה זו תשמש ככניסה חוזרת ונשנית של הנתיב המצויר</string>\n    <string name=\"outlined_triangle_sub\">מצייר משולש מתאר מנקודת ההתחלה לנקודת הסיום</string>\n    <string name=\"triangle_sub\">מצייר משולש מתאר מנקודת ההתחלה לנקודת הסיום</string>\n    <string name=\"outlined_triangle\">משולש מתואר</string>\n    <string name=\"triangle\">מְשּוּלָשׁ</string>\n    <string name=\"polygon_sub\">מצייר מצולע מנקודת התחלה לנקודת סיום</string>\n    <string name=\"polygon\">מְצוּלָע</string>\n    <string name=\"outlined_polygon\">מצולע מתואר</string>\n    <string name=\"outlined_polygon_sub\">מצייר מצולע מתואר מנקודת התחלה לנקודת סיום</string>\n    <string name=\"vertices\">קודקודים</string>\n    <string name=\"draw_regular_polygon\">צייר מצולע רגיל</string>\n    <string name=\"draw_regular_polygon_sub\">צייר מצולע שיהיה רגיל במקום צורה חופשית</string>\n    <string name=\"star_sub\">מצייר כוכב מנקודת התחלה לנקודת סיום</string>\n    <string name=\"star\">כּוֹכָב</string>\n    <string name=\"outlined_star\">כוכב מתואר</string>\n    <string name=\"outlined_star_sub\">מצייר כוכב מסומן מנקודת ההתחלה לנקודת הסיום</string>\n    <string name=\"inner_radius_ratio\">יחס רדיוס פנימי</string>\n    <string name=\"draw_regular_star\">צייר כוכב רגיל</string>\n    <string name=\"draw_regular_star_sub\">צייר כוכב שיהיה רגיל במקום צורה חופשית</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">מאפשר הדפסה נגדית כדי למנוע קצוות חדים</string>\n    <string name=\"open_edit_instead_of_preview\">פתח את עריכה במקום תצוגה מקדימה</string>\n    <string name=\"open_edit_instead_of_preview_sub\">כאשר אתה בוחר תמונה לפתיחה (תצוגה מקדימה) ב-ImageToolbox, גיליון הבחירה של עריכה ייפתח במקום תצוגה מקדימה</string>\n    <string name=\"document_scanner\">סורק מסמכים</string>\n    <string name=\"document_scanner_sub\">סרוק מסמכים וצור PDF או הפרד מהם תמונות</string>\n    <string name=\"click_to_start_scanning\">לחץ כדי להתחיל בסריקה</string>\n    <string name=\"start_scanning\">התחל בסריקה</string>\n    <string name=\"save_as_pdf\">שמור כ-PDF</string>\n    <string name=\"share_as_pdf\">שתף כ-Pdf</string>\n    <string name=\"options_below_is_for_images\">האפשרויות להלן הן לשמירת תמונות, לא ל-PDF</string>\n    <string name=\"equalize_histogram_hsv\">השווה היסטוגרמה HSV</string>\n    <string name=\"equalize_histogram\">השווה את ההיסטוגרמה</string>\n    <string name=\"enter_percentage\">הזן אחוז</string>\n    <string name=\"allow_enter_by_text_field\">אפשר להיכנס לפי שדה טקסט</string>\n    <string name=\"allow_enter_by_text_field_sub\">מאפשר שדה טקסט מאחורי בחירת הגדרות מוגדרות מראש, כדי להזין אותם תוך כדי תנועה</string>\n    <string name=\"scale_color_space\">קנה מידה של מרחב צבע</string>\n    <string name=\"linear\">ליניארי</string>\n    <string name=\"equalize_histogram_pixelation\">השווה פיקסלים היסטוגרמה</string>\n    <string name=\"grid_size_x\">גודל רשת X</string>\n    <string name=\"grid_size_y\">גודל רשת Y</string>\n    <string name=\"equalize_histogram_adaptive\">השוואת היסטוגרמה מסתגלת</string>\n    <string name=\"equalize_histogram_adaptive_luv\">שווי היסטוגרמה אדפטיבית LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalize Histogram Adaptive LAB</string>\n    <string name=\"clahe\">קלה</string>\n    <string name=\"clahe_lab\">מעבדת CLAHE</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">חתוך לתוכן</string>\n    <string name=\"frame_color\">צבע מסגרת</string>\n    <string name=\"color_to_ignore\">צבע להתעלם</string>\n    <string name=\"template\">תבנית</string>\n    <string name=\"no_template_filters\">לא נוספו מסנני תבנית</string>\n    <string name=\"create_new\">צור חדש</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">קוד ה-QR הסרוק אינו תבנית סינון חוקית</string>\n    <string name=\"scan_qr_code\">סרוק קוד QR</string>\n    <string name=\"opened_file_have_no_filter_template\">לקובץ שנבחר אין נתוני תבנית סינון</string>\n    <string name=\"create_template\">צור תבנית</string>\n    <string name=\"template_name\">שם התבנית</string>\n    <string name=\"select_template_preview\">תמונה זו תשמש לתצוגה מקדימה של תבנית סינון זו</string>\n    <string name=\"template_filter\">מסנן תבניות</string>\n    <string name=\"as_qr_code\">כתמונת קוד QR</string>\n    <string name=\"as_file\">בתור קובץ</string>\n    <string name=\"save_as_file\">שמור כקובץ</string>\n    <string name=\"save_as_qr_code_image\">שמור כתמונת קוד QR</string>\n    <string name=\"delete_template\">מחק תבנית</string>\n    <string name=\"delete_template_warn\">אתה עומד למחוק את מסנן התבניות שנבחר. לא ניתן לבטל פעולה זו</string>\n    <string name=\"added_filter_template\">נוספה תבנית סינון בשם \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">תצוגה מקדימה של מסנן</string>\n    <string name=\"qr_code\">QR וברקוד</string>\n    <string name=\"qr_code_sub\">סרוק קוד QR וקבל את התוכן שלו או הדבק את המחרוזת שלך כדי ליצור מחרוזת חדשה</string>\n    <string name=\"code_content\">תוכן קוד</string>\n    <string name=\"scan_qr_code_to_replace_content\">סרוק כל ברקוד כדי להחליף תוכן בשדה, או הקלד משהו כדי ליצור ברקוד חדש עם סוג נבחר</string>\n    <string name=\"qr_description\">תיאור QR</string>\n    <string name=\"min\">מינימום</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">הענק הרשאה למצלמה בהגדרות לסרוק קוד QR</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">הענק הרשאה למצלמה בהגדרות כדי לסרוק את סורק המסמכים</string>\n    <string name=\"cubic\">מְעוּקָב</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">האמינג</string>\n    <string name=\"hanning\">האנינג</string>\n    <string name=\"blackman\">בלקמן</string>\n    <string name=\"welch\">ולץ\\'</string>\n    <string name=\"quadric\">קוואדרי</string>\n    <string name=\"gaussian\">גאוס</string>\n    <string name=\"sphinx\">ספִינקס</string>\n    <string name=\"bartlett\">ברטלט</string>\n    <string name=\"robidoux\">רובידווקס</string>\n    <string name=\"robidoux_sharp\">רובידווקס שארפ</string>\n    <string name=\"spline16\">ספליין 16</string>\n    <string name=\"spline36\">ספליין 36</string>\n    <string name=\"spline64\">ספליין 64</string>\n    <string name=\"kaiser\">קֵיסָר</string>\n    <string name=\"bartlett_hann\">בארטלט-היי</string>\n    <string name=\"box\">קוּפסָה</string>\n    <string name=\"bohman\">בוהמן</string>\n    <string name=\"lanczos2\">לנצ\\'וס 2</string>\n    <string name=\"lanczos3\">לנצ\\'וס 3</string>\n    <string name=\"lanczos4\">לנצ\\'וס 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">אינטרפולציה מעוקבת מספקת קנה מידה חלק יותר על ידי התחשבות ב-16 הפיקסלים הקרובים ביותר, ונותנת תוצאות טובות יותר מאשר בילינאריות</string>\n    <string name=\"bspline_sub\">משתמש בפונקציות פולינום המוגדרות חלקית כדי לבצע אינטרפולציה חלקה ולהעריך עקומה או משטח, ייצוג צורה גמיש ורציף</string>\n    <string name=\"hamming_sub\">פונקציית חלון המשמשת להפחתת דליפה ספקטרלית על ידי הקטנת קצוות האות, שימושית בעיבוד אותות</string>\n    <string name=\"hanning_sub\">גרסה של חלון Hann, המשמש בדרך כלל להפחתת דליפה ספקטרלית ביישומי עיבוד אותות</string>\n    <string name=\"blackman_sub\">פונקציית חלון המספקת רזולוציית תדר טובה על ידי מזעור דליפה ספקטרלית, המשמשת לעתים קרובות בעיבוד אותות</string>\n    <string name=\"welch_sub\">פונקציית חלון שנועדה לתת רזולוציית תדר טובה עם דליפה ספקטרלית מופחתת, המשמשת לעתים קרובות ביישומי עיבוד אותות</string>\n    <string name=\"quadric_sub\">שיטה המשתמשת בפונקציה ריבועית לאינטרפולציה, המספקת תוצאות חלקות ורציפות</string>\n    <string name=\"gaussian_sub\">שיטת אינטרפולציה המיישמת פונקציה גאוסית, שימושית להחלקה והפחתת רעש בתמונות</string>\n    <string name=\"sphinx_sub\">שיטת דגימה מחדש מתקדמת המספקת אינטרפולציה באיכות גבוהה עם חפצים מינימליים</string>\n    <string name=\"bartlett_sub\">פונקציית חלון משולש המשמשת בעיבוד אותות להפחתת דליפה ספקטרלית</string>\n    <string name=\"robidoux_sub\">שיטת אינטרפולציה איכותית המותאמת לשינוי גודל תמונה טבעי, איזון חדות וחלקות</string>\n    <string name=\"robidoux_sharp_sub\">גרסה חדה יותר של שיטת Robidoux, מותאמת לשינוי גודל תמונה חד</string>\n    <string name=\"spline16_sub\">שיטת אינטרפולציה מבוססת ספליין המספקת תוצאות חלקות באמצעות מסנן של 16 ברז</string>\n    <string name=\"spline36_sub\">שיטת אינטרפולציה מבוססת ספליין המספקת תוצאות חלקות באמצעות מסנן של 36 ברז</string>\n    <string name=\"spline64_sub\">שיטת אינטרפולציה מבוססת ספליין המספקת תוצאות חלקות באמצעות מסנן של 64 ברז</string>\n    <string name=\"kaiser_sub\">שיטת אינטרפולציה המשתמשת בחלון הקייזר, המספקת שליטה טובה על ההחלפה בין רוחב האונה הראשית לרמת האונה הצדדית</string>\n    <string name=\"bartlett_hann_sub\">פונקציית חלון היברידית המשלבת את חלונות Bartlett ו-Hann, משמשת להפחתת דליפה ספקטרלית בעיבוד אותות</string>\n    <string name=\"box_sub\">שיטת דגימה מחודשת פשוטה המשתמשת בממוצע של ערכי הפיקסלים הקרובים ביותר, ולעתים קרובות גורמת למראה חסום</string>\n    <string name=\"bohman_sub\">פונקציית חלון המשמשת להפחתת דליפה ספקטרלית, המספקת רזולוציית תדר טובה ביישומי עיבוד אותות</string>\n    <string name=\"lanczos2_sub\">שיטת דגימה חוזרת המשתמשת במסנן Lanczos בעל 2 אונות לאינטרפולציה איכותית עם חפצים מינימליים</string>\n    <string name=\"lanczos3_sub\">שיטת דגימה חוזרת המשתמשת במסנן Lanczos בעל 3 אונות לאינטרפולציה איכותית עם חפצים מינימליים</string>\n    <string name=\"lanczos4_sub\">שיטת דגימה חוזרת המשתמשת במסנן Lanczos בעל 4 אונות לאינטרפולציה איכותית עם חפצים מינימליים</string>\n    <string name=\"lanczos2_jinc_sub\">גרסה של מסנן Lanczos 2 המשתמש בפונקציית jinc, המספקת אינטרפולציה באיכות גבוהה עם חפצים מינימליים</string>\n    <string name=\"lanczos3_jinc_sub\">גרסה של מסנן Lanczos 3 המשתמש בפונקציית jinc, המספקת אינטרפולציה באיכות גבוהה עם חפצים מינימליים</string>\n    <string name=\"lanczos4_jinc_sub\">גרסה של מסנן Lanczos 4 המשתמש בפונקציית jinc, המספקת אינטרפולציה איכותית עם חפצים מינימליים</string>\n    <string name=\"ewa_hanning\">הנינג EWA</string>\n    <string name=\"ewa_hanning_sub\">גרסה אליפטית משוקללת (EWA) של מסנן האנינג לאינטרפולציה חלקה ודגימה מחדש</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">גרסה אליפטית משוקללת (EWA) של מסנן Robidoux לדגימה מחדש באיכות גבוהה</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">גרסת ממוצע משוקלל אליפטי (EWA) של מסנן Blackman למזעור חפצי צלצול</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">גרסת ממוצע משוקלל אליפטי (EWA) של מסנן Quadric לאינטרפולציה חלקה</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">גרסה אליפטית משוקללת (EWA) של מסנן Robidoux Sharp לתוצאות חדות יותר</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">גרסה אליפטית משוקללת (EWA) של מסנן Lanczos 3 Jinc לדגימה מחדש באיכות גבוהה עם כינוי מופחת</string>\n    <string name=\"ginseng\">ג\\'ינסנג</string>\n    <string name=\"ginseng_sub\">מסנן דגימה מחדש המיועד לעיבוד תמונה באיכות גבוהה עם איזון טוב של חדות וחלקות</string>\n    <string name=\"ewa_ginseng\">ג\\'ינסנג EWA</string>\n    <string name=\"ewa_ginseng_sub\">גרסה אליפטית משוקללת (EWA) של מסנן הג\\'ינסנג לאיכות תמונה משופרת</string>\n    <string name=\"ewa_lanczos_sharp\">לנצ\\'וס שארפ EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">גרסת ממוצע משוקלל אליפטי (EWA) של מסנן Lanczos Sharp להשגת תוצאות חדות עם חפצים מינימליים</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">גרסת ממוצע משוקלל אליפטי (EWA) של מסנן Lanczos 4 Sharpest לדגימה מחדש של תמונה חדה במיוחד</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">גרסה אליפטית משוקללת (EWA) של מסנן Lanczos Soft לדגימה מחדש של תמונה חלקה יותר</string>\n    <string name=\"haasn_soft\">האסן סופט</string>\n    <string name=\"haasn_soft_sub\">מסנן דגימה מחדש שעוצב על ידי Haasn לשינוי קנה מידה חלק וללא חפצים</string>\n    <string name=\"format_conversion\">המרת פורמט</string>\n    <string name=\"format_conversion_sub\">המר אצווה של תמונות מפורמט אחד לאחר</string>\n    <string name=\"dismiss_forever\">תפטר לנצח</string>\n    <string name=\"image_stacking\">ערימת תמונה</string>\n    <string name=\"image_stacking_sub\">ערמו תמונות זו על גבי זו עם מצבי מיזוג נבחרים</string>\n    <string name=\"add_image\">הוסף תמונה</string>\n    <string name=\"bins_count\">ספירת פחים</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">השוואת היסטוגרמה אדפטיבית HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">השוואת היסטוגרמה HSV אדפטיבית</string>\n    <string name=\"edge_mode\">מצב קצה</string>\n    <string name=\"clip\">לְקַצֵץ</string>\n    <string name=\"wrap\">לַעֲטוֹף</string>\n    <string name=\"color_blind_scheme\">עיוורון צבעים</string>\n    <string name=\"color_blind_scheme_sub\">בחר מצב כדי להתאים את צבעי הנושא לגרסה של עיוורון צבעים שנבחרה</string>\n    <string name=\"protanomaly_sub\">קושי להבחין בין גוונים אדומים לירוקים</string>\n    <string name=\"deuteranomaly_sub\">קושי להבחין בין גוונים ירוקים לאדומים</string>\n    <string name=\"tritanomaly_sub\">קושי להבחין בין גוונים כחולים לצהובים</string>\n    <string name=\"protanopia_sub\">חוסר יכולת לתפוס גוונים אדומים</string>\n    <string name=\"deuteranopia_sub\">חוסר יכולת לתפוס גוונים ירוקים</string>\n    <string name=\"tritanopia_sub\">חוסר יכולת לתפוס גוונים כחולים</string>\n    <string name=\"achromatomaly_sub\">רגישות מופחתת לכל הצבעים</string>\n    <string name=\"achromatopsia_sub\">עיוורון צבעים מוחלט, רואה רק גוונים של אפור</string>\n    <string name=\"not_use_color_blind_scheme\">אל תשתמש בערכת עיוור צבעים</string>\n    <string name=\"not_use_color_blind_scheme_sub\">הצבעים יהיו בדיוק כפי שנקבעו בערכת הנושא</string>\n    <string name=\"sigmoidal\">סיגמואידי</string>\n    <string name=\"lagrange_2\">לגראנג\\' 2</string>\n    <string name=\"lagrange_2_sub\">מסנן אינטרפולציה של Lagrange בסדר 2, מתאים לשינוי קנה מידה באיכות גבוהה עם מעברים חלקים</string>\n    <string name=\"lagrange_3\">לגראנז\\' 3</string>\n    <string name=\"lagrange_3_sub\">מסנן אינטרפולציה של Lagrange בסדר 3, המציע דיוק טוב יותר ותוצאות חלקות יותר עבור קנה מידה של תמונה</string>\n    <string name=\"lanczos_6\">לנצ\\'וס 6</string>\n    <string name=\"lanczos_6_sub\">מסנן דגימה מחדש של Lanczos בסדר גבוה יותר של 6, המספק קנה מידה חד ומדויק יותר של תמונה</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">גרסה של מסנן Lanczos 6 באמצעות פונקציית Jinc לשיפור איכות דגימת התמונה מחדש</string>\n    <string name=\"linear_box_blur\">טשטוש תיבה לינארית</string>\n    <string name=\"linear_tent_blur\">טשטוש אוהל ליניארי</string>\n    <string name=\"linear_gaussian_box_blur\">טשטוש תיבת גאוס ליניארי</string>\n    <string name=\"linear_stack_blur\">טשטוש מחסנית ליניארי</string>\n    <string name=\"gaussian_box_blur\">טשטוש תיבת גאוס</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linear Fast Gaussian Blur Next</string>\n    <string name=\"linear_fast_gaussian_blur\">טשטוש גאוסי מהיר ליניארי</string>\n    <string name=\"linear_gaussian_blur\">טשטוש גאוס ליניארי</string>\n    <string name=\"draw_filter_sub\">בחר מסנן אחד כדי להשתמש בו כצבע</string>\n    <string name=\"replace_filter\">החלף מסנן</string>\n    <string name=\"pick_filter_info\">בחר מסנן למטה כדי להשתמש בו בתור מברשת בציור שלך</string>\n    <string name=\"tiff_compression_scheme\">ערכת דחיסת TIFF</string>\n    <string name=\"low_poly\">פולי נמוך</string>\n    <string name=\"sand_painting\">ציור חול</string>\n    <string name=\"image_splitting\">פיצול תמונה</string>\n    <string name=\"image_splitting_sub\">פיצול תמונה אחת לפי שורות או עמודות</string>\n    <string name=\"fit_to_bounds\">התאמה לגבולות</string>\n    <string name=\"fit_to_bounds_sub\">שלב מצב שינוי גודל חיתוך עם פרמטר זה כדי להשיג התנהגות רצויה (חיתוך/התאמה ליחס רוחב-גובה)</string>\n    <string name=\"languages_imported\">שפות יובאו בהצלחה</string>\n    <string name=\"backup_ocr_models\">גיבוי דגמי OCR</string>\n    <string name=\"import_word\">יְבוּא</string>\n    <string name=\"export\">יְצוּא</string>\n    <string name=\"position\">מַצָב</string>\n    <string name=\"center\">מֶרְכָּז</string>\n    <string name=\"top_left\">שמאל למעלה</string>\n    <string name=\"top_right\">למעלה מימין</string>\n    <string name=\"bottom_left\">שמאל למטה</string>\n    <string name=\"bottom_right\">ימין למטה</string>\n    <string name=\"top_center\">מרכז העליון</string>\n    <string name=\"center_right\">מרכז ימין</string>\n    <string name=\"bottom_center\">מרכז תחתון</string>\n    <string name=\"center_left\">מרכז שמאל</string>\n    <string name=\"target_image\">תמונת יעד</string>\n    <string name=\"palette_transfer\">העברת פלטות</string>\n    <string name=\"enhanced_oil\">שמן משופר</string>\n    <string name=\"simple_old_tv\">טלוויזיה ישנה פשוטה</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">סקיצה פשוטה</string>\n    <string name=\"soft_glow\">זוהר רך</string>\n    <string name=\"color_poster\">פוסטר צבעוני</string>\n    <string name=\"tri_tone\">טרי טון</string>\n    <string name=\"third_color\">צבע שלישי</string>\n    <string name=\"clahe_oklab\">קלה אוקלאב</string>\n    <string name=\"clahe_oklch\">קלרה אולך</string>\n    <string name=\"clahe_jzazbz\">קלה ג\\'זבז</string>\n    <string name=\"polka_dot\">נקודה</string>\n    <string name=\"clustered_2x2_dithering\">מקבץ 2x2 ניתוק</string>\n    <string name=\"clustered_4x4_dithering\">מקבץ 4x4 דיטה</string>\n    <string name=\"clustered_8x8_dithering\">מקבץ 8x8 ניתוק</string>\n    <string name=\"yililoma_dithering\">שיוף ילילומה</string>\n    <string name=\"no_favorite_options_selected\">לא נבחרו אפשרויות מועדפות, הוסף אותן בדף הכלים</string>\n    <string name=\"add_favorites\">הוסף מועדפים</string>\n    <string name=\"harmony_complementary\">מַשׁלִים</string>\n    <string name=\"harmony_analogous\">מַקְבִּיל</string>\n    <string name=\"harmony_triadic\">טריאדי</string>\n    <string name=\"harmony_split_complementary\">פיצול משלים</string>\n    <string name=\"harmony_tetradic\">טטראדי</string>\n    <string name=\"harmony_square\">מְרוּבָּע</string>\n    <string name=\"harmony_analogous_complementary\">אנלוגי + משלים</string>\n    <string name=\"color_tools\">כלי צבע</string>\n    <string name=\"color_tools_sub\">לערבב, ליצור גוונים, ליצור גוונים ועוד</string>\n    <string name=\"color_harmonies\">הרמוניות צבע</string>\n    <string name=\"color_shading\">הצללת צבע</string>\n    <string name=\"variation\">וָרִיאַצִיָה</string>\n    <string name=\"tints\">גוונים</string>\n    <string name=\"tones\">צלילים</string>\n    <string name=\"shades\">מִשְׁקפֵי שֶׁמֶשׁ</string>\n    <string name=\"color_mixing\">ערבוב צבעים</string>\n    <string name=\"color_info\">מידע על צבע</string>\n    <string name=\"selected_color\">צבע נבחר</string>\n    <string name=\"color_to_mix\">צבע לערבב</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">לא ניתן להשתמש ב-Monte בזמן שצבעים דינמיים מופעלים</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">תמונת LUT יעד</string>\n    <string name=\"amatorka\">חובבן</string>\n    <string name=\"miss_etikate\">מיס נימוס</string>\n    <string name=\"soft_elegance\">אלגנטיות רכה</string>\n    <string name=\"soft_elegance_variant\">וריאנט אלגנטיות רכה</string>\n    <string name=\"palette_transfer_variant\">וריאנט העברת צבעים</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">יעד קובץ LUT 3D (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">מעקף אקונומיקה</string>\n    <string name=\"candlelight\">אור נרות</string>\n    <string name=\"drop_blues\">זרוק בלוז</string>\n    <string name=\"edgy_amber\">אמבר עצבנית</string>\n    <string name=\"fall_colors\">צבעי סתיו</string>\n    <string name=\"film_stock_50\">מלאי סרטים 50</string>\n    <string name=\"foggy_night\">לילה ערפילי</string>\n    <string name=\"kodak\">קודאק</string>\n    <string name=\"save_empty_lut\">קבל תמונת LUT ניטראלית</string>\n    <string name=\"save_empty_lut_sub\">ראשית, השתמש באפליקציית עריכת התמונות המועדפת עליך כדי להחיל מסנן על LUT ניטרלי שתוכל להשיג כאן. כדי שזה יעבוד כמו שצריך, אסור שכל צבע פיקסל יהיה תלוי בפיקסלים אחרים (למשל, טשטוש לא יעבוד). ברגע שאתה מוכן, השתמש בתמונת LUT החדשה שלך כקלט עבור מסנן 512*512 LUT</string>\n    <string name=\"pop_art\">פופ ארט</string>\n    <string name=\"celluloid\">צִיבִית</string>\n    <string name=\"coffee\">קָפֶה</string>\n    <string name=\"golden_forest\">יער הזהב</string>\n    <string name=\"greenish\">יְרַקרַק</string>\n    <string name=\"retro_yellow\">רטרו צהוב</string>\n    <string name=\"links_preview\">תצוגה מקדימה של קישורים</string>\n    <string name=\"links_preview_sub\">מאפשר אחזור תצוגה מקדימה של קישורים במקומות שבהם אתה יכול להשיג טקסט (QRCode, OCR וכו\\')</string>\n    <string name=\"links\">קישורים</string>\n    <string name=\"ico_size_warning\">ניתן לשמור קבצי ICO רק בגודל המרבי של 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF ל-WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">המר תמונות GIF לתמונות מונפשות WEBP</string>\n    <string name=\"webp_tools\">כלי WEBP</string>\n    <string name=\"webp_tools_sub\">המר תמונות לתמונה מונפשת של WEBP או חלץ מסגרות מהנפשת WEBP נתונה</string>\n    <string name=\"webp_type_to_image\">WEBP לתמונות</string>\n    <string name=\"webp_type_to_image_sub\">המרת קובץ WEBP לקבוצת תמונות</string>\n    <string name=\"webp_type_to_webp_sub\">המר אצווה של תמונות לקובץ WEBP</string>\n    <string name=\"webp_type_to_webp\">תמונות ל-WEBP</string>\n    <string name=\"select_webp_image_to_start\">בחר תמונת WEBP כדי להתחיל</string>\n    <string name=\"manage_storage_extra_types\">אין גישה מלאה לקבצים</string>\n    <string name=\"manage_storage_extra_types_sub\">אפשר לכל הקבצים גישה לראות JXL, QOI ותמונות אחרות שאינן מזוהות כתמונות באנדרואיד. ללא הרשאה Image Toolbox אינו יכול להציג את התמונות הללו</string>\n    <string name=\"default_draw_color\">צבע ציור ברירת מחדל</string>\n    <string name=\"default_draw_path_mode\">מצב ציור ברירת מחדל</string>\n    <string name=\"add_timestamp\">הוסף חותמת זמן</string>\n    <string name=\"add_timestamp_sub\">מאפשר הוספה של חותמת זמן לשם קובץ הפלט</string>\n    <string name=\"formatted_timestamp\">חותמת זמן מעוצבת</string>\n    <string name=\"formatted_timestamp_sub\">אפשר עיצוב חותמת זמן בשם קובץ הפלט במקום מיליס בסיסי</string>\n    <string name=\"enable_timestamps_to_format_them\">אפשר חותמות זמן כדי לבחור את הפורמט שלהן</string>\n    <string name=\"one_time_save_location\">מיקום חד פעמי של שמירה</string>\n    <string name=\"one_time_save_location_sub\">הצג וערוך מיקומי שמירה חד-פעמיים שבהם תוכל להשתמש בלחיצה ארוכה על כפתור השמירה ברוב האפשרויות</string>\n    <string name=\"recently_used\">בשימוש לאחרונה</string>\n    <string name=\"ci_channel\">ערוץ CI</string>\n    <string name=\"group\">קְבוּצָה</string>\n    <string name=\"image_toolbox_in_telegram\">ארגז כלים לתמונה בטלגרם 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">הצטרף לצ\\'אט שלנו שבו אתה יכול לדון בכל מה שאתה רוצה וגם להסתכל בערוץ CI שבו אני מפרסם בטא והודעות</string>\n    <string name=\"ci_channel_sub\">קבל הודעה על גרסאות חדשות של האפליקציה וקרא הודעות</string>\n    <string name=\"fit_description\">התאם תמונה למידות נתונות והחל טשטוש או צבע על הרקע</string>\n    <string name=\"tools_arrangement\">סידור כלים</string>\n    <string name=\"group_tools_by_type\">קבץ כלים לפי סוג</string>\n    <string name=\"group_tools_by_type_sub\">מקבץ כלים במסך הראשי לפי סוגם במקום סידור רשימה מותאם אישית</string>\n    <string name=\"default_values\">ערכי ברירת מחדל</string>\n    <string name=\"system_bars_visibility\">נראות סרגלי מערכת</string>\n    <string name=\"show_system_bars_by_swipe\">הצג את סרגלי המערכת באמצעות החלקה</string>\n    <string name=\"show_system_bars_by_swipe_sub\">מאפשר החלקה כדי להציג סרגלי מערכת אם הם מוסתרים</string>\n    <string name=\"auto\">אוטומטי</string>\n    <string name=\"hide_all\">הסתר הכל</string>\n    <string name=\"show_all\">הצג הכל</string>\n    <string name=\"hide_nav_bar\">הסתר Nav Bar</string>\n    <string name=\"hide_status_bar\">הסתר את שורת המצב</string>\n    <string name=\"noise_generation\">יצירת רעש</string>\n    <string name=\"noise_generation_sub\">צור רעשים שונים כמו פרלין או סוגים אחרים</string>\n    <string name=\"frequency\">תֶדֶר</string>\n    <string name=\"noise_type\">סוג רעש</string>\n    <string name=\"rotation_type\">סוג סיבוב</string>\n    <string name=\"fractal_type\">סוג פרקטל</string>\n    <string name=\"octaves\">אוקטבות</string>\n    <string name=\"lacunarity\">לאקונריות</string>\n    <string name=\"gain\">לְהַשִׂיג</string>\n    <string name=\"weighted_strength\">כוח משוקלל</string>\n    <string name=\"ping_pong_strength\">חוזק פינג פונג</string>\n    <string name=\"distance_function\">פונקציית מרחק</string>\n    <string name=\"return_type\">סוג החזרה</string>\n    <string name=\"jitter\">לְהִתְעַצְבֵּן</string>\n    <string name=\"domain_warp\">עיוות דומיין</string>\n    <string name=\"alignment\">מַעֲרָך</string>\n    <string name=\"custom_filename\">שם קובץ מותאם אישית</string>\n    <string name=\"custom_filename_sub\">בחר מיקום ושם קובץ אשר ישמשו לשמירת התמונה הנוכחית</string>\n    <string name=\"saved_to_custom\">נשמר בתיקייה עם שם מותאם אישית</string>\n    <string name=\"collage_maker\">קולאז\\' יוצר</string>\n    <string name=\"collage_maker_sub\">צור קולאז\\'ים מ-20 תמונות לכל היותר</string>\n    <string name=\"collage_type\">סוג קולאז\\'</string>\n    <string name=\"collages_info\">החזק את התמונה כדי להחליף, להזיז ולהתקרב כדי להתאים את המיקום</string>\n    <string name=\"disable_rotation\">השבת סיבוב</string>\n    <string name=\"disable_rotation_sub\">מונע סיבוב תמונות באמצעות תנועות בשתי אצבעות</string>\n    <string name=\"enable_snapping_to_borders\">אפשר הצמדה לגבולות</string>\n    <string name=\"enable_snapping_to_borders_sub\">לאחר הזזה או התקרבות, התמונות יוצמדו כדי למלא את קצוות המסגרת</string>\n    <string name=\"histogram\">היסטוגרמה</string>\n    <string name=\"histogram_sub\">היסטוגרמת תמונת RGB או Brightness כדי לעזור לך לבצע התאמות</string>\n    <string name=\"image_for_histogram\">תמונה זו תשמש ליצירת היסטוגרמות RGB ובהירות</string>\n    <string name=\"tesseract_options\">אפשרויות Tesseract</string>\n    <string name=\"tesseract_options_sub\">החל כמה משתני קלט עבור מנוע tesseract</string>\n    <string name=\"custom_options\">אפשרויות מותאמות אישית</string>\n    <string name=\"custom_params_info\">יש להזין אפשרויות לפי הדפוס הזה: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">חיתוך אוטומטי</string>\n    <string name=\"free_corners\">פינות חופשיות</string>\n    <string name=\"free_corners_sub\">חתוך תמונה לפי מצולע, זה גם מתקן פרספקטיבה</string>\n    <string name=\"coerce_points_to_image_bounds\">כפייה מצביע על גבולות תמונה</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">נקודות לא יוגבלו על ידי גבולות התמונה, זה שימושי לתיקון פרספקטיבה מדויק יותר</string>\n    <string name=\"mask\">מַסֵכָה</string>\n    <string name=\"spot_heal_sub\">מילוי מודע לתוכן תחת נתיב מצויר</string>\n    <string name=\"spot_heal\">נקודת ריפוי</string>\n    <string name=\"use_circle_kernel\">השתמש ב- Circle Kernel</string>\n    <string name=\"opening\">פְּתִיחָה</string>\n    <string name=\"closing\">סְגִירָה</string>\n    <string name=\"morphological_gradient\">שיפוע מורפולוגי</string>\n    <string name=\"top_hat\">כּוֹבַע צִילִינדר</string>\n    <string name=\"black_hat\">כובע שחור</string>\n    <string name=\"tone_curves\">עקומות טון</string>\n    <string name=\"reset_curves\">אפס עקומות</string>\n    <string name=\"reset_curves_sub\">עקומות יוחזרו לערך ברירת המחדל</string>\n    <string name=\"line_style\">סגנון קו</string>\n    <string name=\"gap_size\">גודל פער</string>\n    <string name=\"dashed\">מקווקו</string>\n    <string name=\"dot_dashed\">דוט מקווקו</string>\n    <string name=\"stamped\">חָתוּם</string>\n    <string name=\"zigzag\">לְזַגזֵג</string>\n    <string name=\"dashed_sub\">מצייר קו מקווקו לאורך הנתיב המצויר עם גודל הרווח שצוין</string>\n    <string name=\"dot_dashed_sub\">מצייר נקודות וקו מקווקו לאורך הנתיב הנתון</string>\n    <string name=\"defaultt_sub\">רק ברירת מחדל קווים ישרים</string>\n    <string name=\"stamped_sub\">מצייר צורות נבחרות לאורך הנתיב עם מרווח שצוין</string>\n    <string name=\"zigzag_sub\">מצייר זיגזג גלי לאורך השביל</string>\n    <string name=\"zigzag_ratio\">יחס זיגזג</string>\n    <string name=\"create_shortcut\">צור קיצור דרך</string>\n    <string name=\"create_shortcut_title\">בחר כלי להצמדה</string>\n    <string name=\"create_shortcut_subtitle\">הכלי יתווסף למסך הבית של המשגר ​​שלך כקיצור דרך, השתמש בו בשילוב עם הגדרת \\\"דלג על בחירת קבצים\\\" כדי להשיג התנהגות נדרשת</string>\n    <string name=\"dont_stack_frames\">אל תערמו מסגרות</string>\n    <string name=\"dont_stack_frames_sub\">מאפשר סילוק מסגרות קודמות, כך שהן לא ייערמו אחת על השנייה</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">מסגרות יהיו מוצלבות זו לזו</string>\n    <string name=\"crossfade_count\">מסגרות Crossfade נחשבות</string>\n    <string name=\"threshold_one\">סף ראשון</string>\n    <string name=\"threshold_two\">סף שני</string>\n    <string name=\"canny\">עַרמוּמִי</string>\n    <string name=\"mirror_101\">מראה 101</string>\n    <string name=\"enhanced_zoom_blur\">טשטוש זום משופר</string>\n    <string name=\"laplacian_simple\">Laplacian Simple</string>\n    <string name=\"sobel_simple\">סובל סימפל</string>\n    <string name=\"helper_grid\">רשת עוזרת</string>\n    <string name=\"helper_grid_sub\">מציג רשת תומכת מעל אזור הציור כדי לעזור במניפולציות מדויקות</string>\n    <string name=\"grid_color\">צבע רשת</string>\n    <string name=\"cell_width\">רוחב תא</string>\n    <string name=\"cell_height\">גובה תא</string>\n    <string name=\"compact_selectors\">בוררים קומפקטיים</string>\n    <string name=\"compact_selectors_sub\">חלק מפקדי הבחירה ישתמשו בפריסה קומפקטית כדי לקחת פחות מקום</string>\n    <string name=\"grant_camera_permission_to_capture_image\">הענק הרשאה למצלמה בהגדרות לצילום תמונה</string>\n    <string name=\"layout\">מַעֲרָך</string>\n    <string name=\"main_screen_title\">כותרת המסך הראשית</string>\n    <string name=\"constant_rate_factor\">פקטור קצב קבוע (CRF)</string>\n    <string name=\"crf_sub\">ערך של %1$s פירושו דחיסה איטית, וכתוצאה מכך גודל קובץ קטן יחסית. %2$s פירושו דחיסה מהירה יותר, וכתוצאה מכך קובץ גדול.</string>\n    <string name=\"lut_library\">ספריית לוט</string>\n    <string name=\"lut_library_sub\">הורד אוסף של LUTs, שתוכל ליישם לאחר ההורדה</string>\n    <string name=\"lut_library_update_sub\">עדכון אוסף של LUTs (רק חדשים יעמדו בתור), שתוכל להחיל לאחר ההורדה</string>\n    <string name=\"filter_preview_image_sub\">שנה את ברירת המחדל של תצוגה מקדימה של תמונה עבור מסננים</string>\n    <string name=\"filter_preview_image\">תצוגה מקדימה של תמונה</string>\n    <string name=\"hide\">לְהַסתִיר</string>\n    <string name=\"show\">לְהַצִיג</string>\n    <string name=\"slider_type\">סוג המחוון</string>\n    <string name=\"fancy\">לְחַבֵּב</string>\n    <string name=\"material_2\">חומר 2</string>\n    <string name=\"fancy_sub\">סליידר בעל מראה מהודר. זוהי אפשרות ברירת המחדל</string>\n    <string name=\"material_2_sub\">מחוון חומר 2</string>\n    <string name=\"material_you_slider_sub\">מחוון חומר אתה</string>\n    <string name=\"apply\">לִפְנוֹת</string>\n    <string name=\"center_align_dialog_buttons\">לחצני דיאלוג מרכזי</string>\n    <string name=\"center_align_dialog_buttons_sub\">לחצנים של דיאלוגים ימוקמו במרכז במקום בצד שמאל במידת האפשר</string>\n    <string name=\"open_source_licenses\">רישיונות קוד פתוח</string>\n    <string name=\"open_source_licenses_sub\">הצג רישיונות של ספריות קוד פתוח המשמשות באפליקציה זו</string>\n    <string name=\"area\">אֵזוֹר</string>\n    <string name=\"area_sub\">דגימה מחדש באמצעות יחס שטח פיקסלים. זו עשויה להיות שיטה מועדפת להפחתת תמונה, מכיוון שהיא נותנת תוצאות נטולות מואר. אבל כשהתמונה מוגדלת, היא דומה לשיטת ה\\\"קרוב\\\".</string>\n    <string name=\"enable_tonemapping\">הפעל מיפוי גוונים</string>\n    <string name=\"enter_percent\">הזן %</string>\n    <string name=\"unknown_host\">לא מצליח לגשת לאתר, נסה להשתמש ב-VPN או בדוק אם כתובת האתר נכונה</string>\n    <string name=\"markup_layers\">סימון שכבות</string>\n    <string name=\"markup_layers_sub\">מצב שכבות עם יכולת למקם בחופשיות תמונות, טקסט ועוד</string>\n    <string name=\"edit_layer\">ערוך שכבה</string>\n    <string name=\"layers_on_image\">שכבות על התמונה</string>\n    <string name=\"layers_on_image_sub\">השתמש בתמונה כרקע והוסף שכבות שונות מעליה</string>\n    <string name=\"layers_on_background\">שכבות על רקע</string>\n    <string name=\"layers_on_background_sub\">זהה לאפשרות הראשונה אבל עם צבע במקום תמונה</string>\n    <string name=\"beta\">בטא</string>\n    <string name=\"fast_settings_side\">צד הגדרות מהיר</string>\n    <string name=\"fast_settings_side_sub\">הוסף רצועה צפה בצד הנבחר בעת עריכת תמונות, אשר תפתח הגדרות מהירות בלחיצה</string>\n    <string name=\"clear_selection\">נקה בחירה</string>\n    <string name=\"settings_group_visibility_hidden\">קבוצת ההגדרה \\\"%1$s\\\" תכווץ כברירת מחדל</string>\n    <string name=\"settings_group_visibility_visible\">קבוצת ההגדרה \\\"%1$s\\\" תורחב כברירת מחדל</string>\n    <string name=\"base_64_tools\">כלים של Base64</string>\n    <string name=\"base_64_tools_sub\">פענח מחרוזת Base64 לתמונה, או קידד תמונה לפורמט Base64</string>\n    <string name=\"base_64\">בסיס 64</string>\n    <string name=\"not_a_valid_base_64\">הערך שסופק אינו מחרוזת Base64 חוקית</string>\n    <string name=\"copy_not_a_valid_base_64\">לא ניתן להעתיק מחרוזת Base64 ריקה או לא חוקית</string>\n    <string name=\"paste_base_64\">הדבק את Base64</string>\n    <string name=\"copy_base_64\">העתק את Base64</string>\n    <string name=\"base_64_tips\">טען תמונה כדי להעתיק או לשמור מחרוזת Base64. אם יש לך את המחרוזת עצמה, אתה יכול להדביק אותה למעלה כדי לקבל תמונה</string>\n    <string name=\"save_base_64\">שמור את Base64</string>\n    <string name=\"share_base_64\">שתף את Base64</string>\n    <string name=\"options\">אפשרויות</string>\n    <string name=\"actions\">פעולות</string>\n    <string name=\"import_base_64\">ייבוא ​​Base64</string>\n    <string name=\"base_64_actions\">פעולות Base64</string>\n    <string name=\"add_outline\">הוסף מתאר</string>\n    <string name=\"add_outline_sub\">הוסף קווי מתאר סביב טקסט עם צבע ורוחב שצוינו</string>\n    <string name=\"outline_color\">צבע מתאר</string>\n    <string name=\"outline_size\">גודל מתאר</string>\n    <string name=\"rotation\">רוֹטַציָה</string>\n    <string name=\"checksum_as_filename\">בדיקת סכום כשם קובץ</string>\n    <string name=\"checksum_as_filename_sub\">לתמונות הפלט יהיה שם המתאים לסכום הבדיקה שלהן</string>\n    <string name=\"free_software_partner\">תוכנה חופשית (שותף)</string>\n    <string name=\"free_software_partner_sub\">תוכנה שימושית יותר בערוץ השותפים של אפליקציות אנדרואיד</string>\n    <string name=\"algorithms\">אַלגוֹרִיתְם</string>\n    <string name=\"checksum_tools\">כלי סכום ביקורת</string>\n    <string name=\"checksum_tools_sub\">השווה סכומי בדיקה, חישוב גיבוב או צור מחרוזות hex מקבצים באמצעות אלגוריתמי גיבוב שונים</string>\n    <string name=\"calculate\">לְחַשֵׁב</string>\n    <string name=\"text_hash\">טקסט Hash</string>\n    <string name=\"checksum\">סכום בדיקה</string>\n    <string name=\"pick_file_to_checksum\">בחר קובץ כדי לחשב את סכום הבדיקה שלו בהתבסס על האלגוריתם שנבחר</string>\n    <string name=\"enter_text_to_checksum\">הזן טקסט כדי לחשב את סכום הבדיקה שלו בהתבסס על האלגוריתם שנבחר</string>\n    <string name=\"source_checksum\">בדיקת סכום מקור</string>\n    <string name=\"checksum_to_compare\">Checksum להשוואה</string>\n    <string name=\"match\">לְהַתְאִים!</string>\n    <string name=\"difference\">הֶבדֵל</string>\n    <string name=\"match_sub\">סכומי המחאה שווים, זה יכול להיות בטוח</string>\n    <string name=\"difference_sub\">סכומי המחאה אינם שווים, הקובץ יכול להיות לא בטוח!</string>\n    <string name=\"mesh_gradients\">מעברי רשת</string>\n    <string name=\"collection_mesh_gradients_sub\">תסתכל על אוסף מקוון של Mesh Gradients</string>\n    <string name=\"wrong_font\">ניתן לייבא רק גופני TTF ו-OTF</string>\n    <string name=\"import_font\">ייבוא ​​גופן (TTF/OTF)</string>\n    <string name=\"export_fonts\">ייצוא גופנים</string>\n    <string name=\"imported_fonts\">גופנים מיובאים</string>\n    <string name=\"error_while_saving\">שגיאה בעת שמירת הניסיון, נסה לשנות את תיקיית הפלט</string>\n    <string name=\"filename_is_not_set\">שם הקובץ לא מוגדר</string>\n    <string name=\"none\">אַף לֹא אֶחָד</string>\n    <string name=\"custom_pages\">דפים מותאמים אישית</string>\n    <string name=\"pages_selection\">בחירת דפים</string>\n    <string name=\"tool_exit_confirmation\">אישור יציאת הכלי</string>\n    <string name=\"tool_exit_confirmation_sub\">אם יש לך שינויים שלא נשמרו תוך כדי שימוש בכלים מסוימים ותנסה לסגור אותם, תוצג תיבת הדו-שיח לאישור</string>\n    <string name=\"edit_exif_screen\">ערוך EXIF</string>\n    <string name=\"edit_exif_screen_sub\">שנה מטא נתונים של תמונה בודדת ללא דחיסה מחדש</string>\n    <string name=\"edit_exif_tag\">הקש כדי לערוך תגים זמינים</string>\n    <string name=\"change_sticker\">שנה מדבקה</string>\n    <string name=\"fit_width\">התאמה לרוחב</string>\n    <string name=\"fit_height\">גובה מתאים</string>\n    <string name=\"batch_compare\">השוואת אצווה</string>\n    <string name=\"pick_files_to_checksum\">בחר קובץ/קבצים כדי לחשב את סכום הבדיקה שלו בהתבסס על האלגוריתם שנבחר</string>\n    <string name=\"pick_files\">בחר קבצים</string>\n    <string name=\"pick_directory\">בחר ספרייה</string>\n    <string name=\"head_length_scale\">סולם אורך ראש</string>\n    <string name=\"stamp\">חוֹתֶמֶת</string>\n    <string name=\"timestamp\">חותמת זמן</string>\n    <string name=\"format_pattern\">עיצוב דפוס</string>\n    <string name=\"padding\">ריפוד</string>\n    <string name=\"image_cutting\">חיתוך תמונה</string>\n    <string name=\"image_cutting_sub\">חותכים חלק של התמונה וממזג את החלקים השמאליים (יכולים להיות הפוכים) על ידי קווים אנכיים או אופקיים</string>\n    <string name=\"vertical_pivot_line\">קו ציר אנכי</string>\n    <string name=\"horizontal_pivot_line\">קו ציר אופקי</string>\n    <string name=\"inverse_selection\">בחירה הפוכה</string>\n    <string name=\"inverse_vertical_selection_sub\">חלק חתוך אנכי ישאיר, במקום מיזוג חלקים סביב אזור החתך</string>\n    <string name=\"inverse_horizontal_selection_sub\">חלק חתוך אופקי ישאיר, במקום למזג חלקים סביב אזור החתך</string>\n    <string name=\"collection_mesh_gradients\">אוסף של מעברי רשת</string>\n    <string name=\"mesh_gradients_sub\">צור שיפוע רשת עם כמות מותאמת אישית של קשרים ורזולוציה</string>\n    <string name=\"gradient_maker_type_image_mesh\">שכבת שיפוע רשת</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">צור שיפוע רשת של החלק העליון של תמונות נתונות</string>\n    <string name=\"points_customization\">התאמה אישית של נקודות</string>\n    <string name=\"grid_size\">גודל רשת</string>\n    <string name=\"resolution_x\">רזולוציה X</string>\n    <string name=\"resolution_y\">החלטה Y</string>\n    <string name=\"resolution\">הַחְלָטָה</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">הדגש צבע</string>\n    <string name=\"pixel_comparison_type\">סוג השוואת פיקסלים</string>\n    <string name=\"scan_barcode\">סרוק ברקוד</string>\n    <string name=\"height_ratio\">יחס גובה</string>\n    <string name=\"barcode_type\">סוג ברקוד</string>\n    <string name=\"enforce_bw\">לאכוף שחור/לבן</string>\n    <string name=\"enforce_bw_sub\">תמונת ברקוד תהיה בשחור-לבן לחלוטין ולא צבועה לפי נושא האפליקציה</string>\n    <string name=\"barcodes_sub\">סרוק כל ברקוד (QR, EAN, AZTEC, …) וקבל את התוכן שלו או הדבק את הטקסט שלך כדי ליצור אחד חדש</string>\n    <string name=\"no_barcode_found\">לא נמצא ברקוד</string>\n    <string name=\"generated_barcode_will_be_here\">ברקוד שנוצר יהיה כאן</string>\n    <string name=\"audio_cover_extractor\">עטיפות אודיו</string>\n    <string name=\"audio_cover_extractor_sub\">חלץ תמונות עטיפת אלבום מקובצי אודיו, רוב הפורמטים הנפוצים נתמכים</string>\n    <string name=\"pick_audio_to_start\">בחר אודיו כדי להתחיל</string>\n    <string name=\"pick_audio\">בחר אודיו</string>\n    <string name=\"no_covers_found\">לא נמצאו עטיפות</string>\n    <string name=\"send_logs\">שלח יומנים</string>\n    <string name=\"send_logs_sub\">לחץ כדי לשתף קובץ יומני אפליקציה, זה יכול לעזור לי לזהות את הבעיה ולתקן בעיות</string>\n    <string name=\"crash_title\">אופס… משהו השתבש</string>\n    <string name=\"crash_subtitle\">אתה יכול ליצור איתי קשר באמצעות האפשרויות למטה ואני אנסה למצוא פתרון.\\n(אל תשכח לצרף יומנים)</string>\n    <string name=\"ocr_write_to_file\">כתוב לקובץ</string>\n    <string name=\"ocr_write_to_file_sub\">חלץ טקסט מקבוצת תמונות ואחסן אותו בקובץ הטקסט האחד</string>\n    <string name=\"ocr_write_to_metadata\">כתוב למטא נתונים</string>\n    <string name=\"ocr_write_to_metadata_sub\">חלץ טקסט מכל תמונה והצב אותו ב-EXIF info של תמונות יחסית</string>\n    <string name=\"invisible_mode\">מצב בלתי נראה</string>\n    <string name=\"invisible_mode_sub\">השתמש בסטגנוגרפיה כדי ליצור סימני מים בלתי נראים בעיניים בתוך בתים של התמונות שלך</string>\n    <string name=\"use_lsb\">השתמש ב-LSB</string>\n    <string name=\"use_lsb_sub\">ייעשה שימוש בשיטת סטגנוגרפיה LSB (Less Significant Bit), אחרת FD (דומיין תדר)</string>\n    <string name=\"auto_remove_red_eyes\">הסרה אוטומטית של עיניים אדומות</string>\n    <string name=\"password\">סִיסמָה</string>\n    <string name=\"unlock\">לִפְתוֹחַ</string>\n    <string name=\"pdf_is_protected\">PDF מוגן</string>\n    <string name=\"operation_almost_complete\">המבצע כמעט הושלם. ביטול כעת יחייב הפעלה מחדש</string>\n    <string name=\"sort_by_date_modified\">תאריך שינוי</string>\n    <string name=\"sort_by_date_modified_reversed\">תאריך שינוי (הפוך)</string>\n    <string name=\"sort_by_size\">גוֹדֶל</string>\n    <string name=\"sort_by_size_reversed\">גודל (הפוך)</string>\n    <string name=\"sort_by_mime_type\">סוג MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">סוג MIME (הפוך)</string>\n    <string name=\"sort_by_extension\">הַרחָבָה</string>\n    <string name=\"sort_by_extension_reversed\">הרחבה (הפוכה)</string>\n    <string name=\"sort_by_date_added\">תאריך נוסף</string>\n    <string name=\"sort_by_date_added_reversed\">תאריך הוספה (הפוך)</string>\n    <string name=\"left_to_right\">משמאל לימין</string>\n    <string name=\"right_to_left\">מימין לשמאל</string>\n    <string name=\"top_to_bottom\">מלמעלה למטה</string>\n    <string name=\"bottom_to_top\">מלמטה למעלה</string>\n    <string name=\"liquid_glass\">זכוכית נוזלית</string>\n    <string name=\"liquid_glass_sub\">מתג המבוסס על IOS 26 שהוכרז לאחרונה ומערכת עיצוב הזכוכית הנוזלית שלו</string>\n    <string name=\"pick_image_or_base64\">בחר תמונה או הדבק/ייבא נתוני Base64 למטה</string>\n    <string name=\"type_image_link\">הקלד קישור לתמונה כדי להתחיל</string>\n    <string name=\"paste_link\">הדבק קישור</string>\n    <string name=\"kaleidoscope\">קָלֵידוֹסקוֹפּ</string>\n    <string name=\"secondary_angle\">זווית משנית</string>\n    <string name=\"sides\">צדדים</string>\n    <string name=\"channel_mix\">מיקס ערוץ</string>\n    <string name=\"blue_green\">כחול ירוק</string>\n    <string name=\"red_blue\">אדום כחול</string>\n    <string name=\"green_red\">ירוק אדום</string>\n    <string name=\"into_red\">לתוך אדום</string>\n    <string name=\"into_green\">לתוך ירוק</string>\n    <string name=\"into_blue\">לתוך כחול</string>\n    <string name=\"cyan\">ציאן</string>\n    <string name=\"magenta\">מַגֶנטָה</string>\n    <string name=\"yellow\">צָהוֹב</string>\n    <string name=\"color_halftone\">צבע חצי טון</string>\n    <string name=\"contour\">קוֹנטוּר</string>\n    <string name=\"levels\">רמות</string>\n    <string name=\"offset\">לְקַזֵז</string>\n    <string name=\"voronoi_crystallize\">Voronoi להתגבש</string>\n    <string name=\"shape\">צוּרָה</string>\n    <string name=\"stretch\">לִמְתוֹחַ</string>\n    <string name=\"randomness\">אקראיות</string>\n    <string name=\"despeckle\">משחרר כתמים</string>\n    <string name=\"diffuse\">מְפוּזָר</string>\n    <string name=\"dog\">כֶּלֶב</string>\n    <string name=\"second_radius\">רדיוס שני</string>\n    <string name=\"equalize\">לְהַשְׁווֹת</string>\n    <string name=\"glow\">לַהַט</string>\n    <string name=\"whirl_and_pinch\">מערבלים וצבטים</string>\n    <string name=\"pointillize\">פוינטיליזציה</string>\n    <string name=\"border_color\">צבע גבול</string>\n    <string name=\"polar_coordinates\">קואורדינטות קוטב</string>\n    <string name=\"rect_to_polar\">ישר לקוטב</string>\n    <string name=\"polar_to_rect\">קוטבי לתקן</string>\n    <string name=\"invert_in_circle\">הפוך במעגל</string>\n    <string name=\"reduce_noise\">הפחת רעש</string>\n    <string name=\"simple_solarize\">Solarize פשוט</string>\n    <string name=\"weave\">לֶאֱרוֹג</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X רוחב</string>\n    <string name=\"y_wdth\">רוחב Y</string>\n    <string name=\"twirl\">לְסוֹבֵב</string>\n    <string name=\"rubber_stmp\">חותמת גומי</string>\n    <string name=\"smear\">לִמְרוֹחַ</string>\n    <string name=\"density\">צְפִיפוּת</string>\n    <string name=\"mix\">לְעַרְבֵּב</string>\n    <string name=\"sphere_lensh_distortion\">עיוות עדשת כדור</string>\n    <string name=\"refraction_index\">מדד השבירה</string>\n    <string name=\"arc\">קֶשֶׁת</string>\n    <string name=\"spread_angle\">זווית התפשטות</string>\n    <string name=\"sparkle\">נִצנוּץ</string>\n    <string name=\"rays\">קרניים</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">מִדרוֹן</string>\n    <string name=\"moire\">מרי</string>\n    <string name=\"autumn\">סתָיו</string>\n    <string name=\"bone\">עֶצֶם</string>\n    <string name=\"jet\">סִילוֹן</string>\n    <string name=\"winter\">חוֹרֶף</string>\n    <string name=\"ocean\">יָם</string>\n    <string name=\"summer\">קַיִץ</string>\n    <string name=\"spring\">אָבִיב</string>\n    <string name=\"cool_variant\">וריאנט מגניב</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">וָרוֹד</string>\n    <string name=\"hot\">חַם</string>\n    <string name=\"parula\">מִלָה</string>\n    <string name=\"magma\">מִקפָּה</string>\n    <string name=\"inferno\">תוֹפֶת</string>\n    <string name=\"plasma\">פְּלַסמָה</string>\n    <string name=\"viridis\">וירידיס</string>\n    <string name=\"cividis\">אזרחים</string>\n    <string name=\"twilight\">דִמדוּם</string>\n    <string name=\"twilight_shifted\">דמדומים הוסט</string>\n    <string name=\"auto_perspective\">פרספקטיבה אוטומטית</string>\n    <string name=\"deskew\">הטיה</string>\n    <string name=\"allow_crop\">אפשר חיתוך</string>\n    <string name=\"crop_or_perspective\">חיתוך או פרספקטיבה</string>\n    <string name=\"absolute\">מוּחלָט</string>\n    <string name=\"turbo\">טורבו</string>\n    <string name=\"deep_green\">ירוק עמוק</string>\n    <string name=\"lens_correction\">תיקון עדשה</string>\n    <string name=\"target_lens_profile\">קובץ פרופיל העדשה היעד בפורמט JSON</string>\n    <string name=\"download_ready_lens_profiles\">הורד פרופילי עדשות מוכנים</string>\n    <string name=\"part_percents\">אחוזי חלק</string>\n    <string name=\"export_as_json\">ייצא כ-JSON</string>\n    <string name=\"export_as_json_sub\">העתק מחרוזת עם נתוני לוח כייצוג של json</string>\n    <string name=\"seam_carving\">גילוף תפר</string>\n    <string name=\"home_screen\">מסך הבית</string>\n    <string name=\"lock_screen\">מסך נעילה</string>\n    <string name=\"built_in\">מובנה</string>\n    <string name=\"wallpapers_export\">ייצוא טפטים</string>\n    <string name=\"refresh\">לְרַעֲנֵן</string>\n    <string name=\"wallpapers_export_sub\">השג טפטים עדכניים של בית, מנעול וטפטים מובנים</string>\n    <string name=\"allow_access_to_all_files_for_wp\">אפשר גישה לכל הקבצים, זה נחוץ כדי לאחזר טפטים</string>\n    <string name=\"allow_read_media_images_for_wp\">ניהול הרשאת אחסון חיצוני אינו מספיק, אתה צריך לאפשר גישה לתמונות שלך, הקפד לבחור \\\"אפשר הכל\\\"</string>\n    <string name=\"add_preset_to_filename\">הוסף מוגדר מראש לשם הקובץ</string>\n    <string name=\"add_preset_to_filename_sub\">מוסיף סיומת עם הגדרה מראש שנבחרה לשם קובץ התמונה</string>\n    <string name=\"add_image_scale_mode_to_filename\">הוסף מצב סולם תמונה לשם הקובץ</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">מוסיף סיומת עם מצב קנה המידה של התמונה שנבחר לשם קובץ התמונה</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">המר תמונה לטקסט ascii שייראה כמו תמונה</string>\n    <string name=\"params\">פרמס</string>\n    <string name=\"invert_colors_ascii_sub\">מחיל מסנן שלילי על התמונה לקבלת תוצאה טובה יותר במקרים מסוימים</string>\n    <string name=\"processing_screenshot\">מעבד צילום מסך</string>\n    <string name=\"screenshot_not_captured_try_again\">צילום מסך לא צולם, נסה שוב</string>\n    <string name=\"skipped_saving\">השמירה דילגה</string>\n    <string name=\"skipped_saving_multiple\">%1$s קבצים דילגו</string>\n    <string name=\"allow_skip_if_larger\">אפשר לדלג אם גדול יותר</string>\n    <string name=\"allow_skip_if_larger_sub\">חלק מהכלים יורשו לדלג על שמירת תמונות אם גודל הקובץ המתקבל יהיה גדול מהמקור</string>\n    <string name=\"qr_type_calendar_event\">אירוע לוח שנה</string>\n    <string name=\"qr_type_contact_info\">מַגָע</string>\n    <string name=\"qr_type_email\">אֶלֶקטרוֹנִי</string>\n    <string name=\"qr_type_geo_point\">מִקוּם</string>\n    <string name=\"qr_type_phone\">טֵלֵפוֹן</string>\n    <string name=\"qr_type_plain\">טֶקסט</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">כתובת אתר</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">רשת פתוחה</string>\n    <string name=\"not_specified\">לא</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">טֵלֵפוֹן</string>\n    <string name=\"message\">הוֹדָעָה</string>\n    <string name=\"address\">כְּתוֹבֶת</string>\n    <string name=\"subject\">נוֹשֵׂא</string>\n    <string name=\"body\">גוּף</string>\n    <string name=\"name\">שֵׁם</string>\n    <string name=\"organization\">אִרגוּן</string>\n    <string name=\"title\">כּוֹתֶרֶת</string>\n    <string name=\"phones\">טלפונים</string>\n    <string name=\"emails\">אימיילים</string>\n    <string name=\"urls\">כתובות אתרים</string>\n    <string name=\"addresses\">כתובות</string>\n    <string name=\"summary\">תַקצִיר</string>\n    <string name=\"description\">תֵאוּר</string>\n    <string name=\"location\">מִקוּם</string>\n    <string name=\"organizer\">מְאַרגֵן</string>\n    <string name=\"start_date\">תאריך התחלה</string>\n    <string name=\"end_date\">תאריך סיום</string>\n    <string name=\"status\">סטָטוּס</string>\n    <string name=\"latitude\">רוֹחַב</string>\n    <string name=\"longitude\">קו אורך</string>\n    <string name=\"create_barcode\">צור ברקוד</string>\n    <string name=\"edit_barcode\">ערוך ברקוד</string>\n    <string name=\"wifi_configuration\">תצורת Wi-Fi</string>\n    <string name=\"security\">בִּטָחוֹן</string>\n    <string name=\"pick_contact\">בחר איש קשר</string>\n    <string name=\"grant_contact_permission\">הענק לאנשי קשר הרשאה בהגדרות למילוי אוטומטי באמצעות איש קשר נבחר</string>\n    <string name=\"contact_info\">פרטי יצירת קשר</string>\n    <string name=\"first_name\">שֵׁם פְּרַטִי</string>\n    <string name=\"middle_name\">שם אמצעי</string>\n    <string name=\"last_name\">שֵׁם מִשׁפָּחָה</string>\n    <string name=\"pronunciation\">מִבטָא</string>\n    <string name=\"add_phone\">הוסף טלפון</string>\n    <string name=\"add_email\">הוסף אימייל</string>\n    <string name=\"add_address\">הוסף כתובת</string>\n    <string name=\"website\">אֲתַר אִינטֶרנֶט</string>\n    <string name=\"add_website\">הוסף אתר</string>\n    <string name=\"formatted_name\">שם מעוצב</string>\n    <string name=\"qr_code_top_image\">תמונה זו תשמש למיקום מעל ברקוד</string>\n    <string name=\"code_customization\">התאמה אישית של קוד</string>\n    <string name=\"qr_logo_image\">תמונה זו תשמש כלוגו במרכז קוד QR</string>\n    <string name=\"logo\">סֵמֶל</string>\n    <string name=\"logo_padding\">ריפוד לוגו</string>\n    <string name=\"logo_size\">גודל לוגו</string>\n    <string name=\"logo_corners\">פינות לוגו</string>\n    <string name=\"fourth_eye\">עין רביעית</string>\n    <string name=\"fourth_eye_description\">מוסיף סימטרית עין לקוד qr על ידי הוספת עין רביעית בפינה התחתונה</string>\n    <string name=\"pixel_shape\">צורת פיקסל</string>\n    <string name=\"frame_shape\">צורת מסגרת</string>\n    <string name=\"ball_shape\">צורת כדור</string>\n    <string name=\"error_correction_level\">רמת תיקון השגיאה</string>\n    <string name=\"dark_color\">צבע כהה</string>\n    <string name=\"light_color\">צבע בהיר</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">סגנון כמו Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">דפוס מסכה</string>\n    <string name=\"code_may_be_not_scannable\">ייתכן שקוד זה אינו ניתן לסריקה, שנה פרמטרים של מראה כדי שיהיה קריא עם כל המכשירים</string>\n    <string name=\"not_scannable\">לא ניתן לסריקה</string>\n    <string name=\"launcher_mode_sub\">הכלים ייראו כמו משגר אפליקציות מסך הבית כדי להיות קומפקטי יותר</string>\n    <string name=\"launcher_mode\">מצב משגר</string>\n    <string name=\"flood_fill_sub\">ממלא אזור במברשת ובסגנון נבחרים</string>\n    <string name=\"flood_fill\">מילוי הצפה</string>\n    <string name=\"spray\">תַרסִיס</string>\n    <string name=\"spray_sub\">מצייר נתיב בסגנון גרפיטי</string>\n    <string name=\"square_particles\">חלקיקים מרובעים</string>\n    <string name=\"square_particles_sub\">חלקיקי הריסוס יהיו בצורת ריבוע במקום עיגולים</string>\n    <string name=\"palette_tools\">כלי לוח</string>\n    <string name=\"palette_tools_sub\">צור חומר בסיסי/חומר שאתה לוח מתמונה, או ייבא/ייצא על פני פורמטים שונים של לוח צבעים</string>\n    <string name=\"edit_palette\">ערוך לוח</string>\n    <string name=\"edit_palette_sub\">פלטת ייצוא/ייבוא ​​בפורמטים שונים</string>\n    <string name=\"color_name\">שם צבע</string>\n    <string name=\"palette_name\">שם פלטה</string>\n    <string name=\"palette_format\">פורמט פלטה</string>\n    <string name=\"export_palette_sub\">ייצוא פלטה שנוצרה לפורמטים שונים</string>\n    <string name=\"add_color_palette_sub\">מוסיף צבע חדש ללוח הנוכחי</string>\n    <string name=\"palette_name_not_supported\">פורמט %1$s אינו תומך במתן שם לוח</string>\n    <string name=\"wallpapers_export_not_avaialbe\">עקב מדיניות חנות Play, לא ניתן לכלול תכונה זו במבנה הנוכחי. כדי לגשת לפונקציונליות זו, אנא הורד את ImageToolbox ממקור חלופי. אתה יכול למצוא את ה-builds הזמינים ב-GitHub למטה.</string>\n    <string name=\"open_github_page\">פתח את דף Github</string>\n    <string name=\"overwrite_files_sub_short\">הקובץ המקורי יוחלף בקובץ חדש במקום לשמור בתיקייה שנבחרה</string>\n    <string name=\"hidden_watermark_text_detected\">זוהה טקסט של סימן מים מוסתר</string>\n    <string name=\"hidden_watermark_image_detected\">זוהתה תמונת סימן מים נסתרת</string>\n    <string name=\"this_image_was_hidden\">התמונה הזו הוסתרה</string>\n    <string name=\"generative_inpaint\">ציור גנרטיבי</string>\n    <string name=\"generative_inpaint_sub\">מאפשר להסיר אובייקטים בתמונה באמצעות מודל AI, מבלי להסתמך על OpenCV. כדי להשתמש בתכונה זו, האפליקציה תוריד את הדגם הנדרש (~200 MB) מ-GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">מאפשר להסיר אובייקטים בתמונה באמצעות מודל AI, מבלי להסתמך על OpenCV. זה יכול להיות פעולה ארוכה</string>\n    <string name=\"error_level_analysis\">ניתוח רמת שגיאה</string>\n    <string name=\"luminance_gradient\">שיפוע בהירות</string>\n    <string name=\"average_distance\">מרחק ממוצע</string>\n    <string name=\"copy_move_detection\">העתק זיהוי תזוזה</string>\n    <string name=\"retain\">לִשְׁמוֹר</string>\n    <string name=\"coefficent\">מקדם</string>\n    <string name=\"clipboard_data_is_too_large\">נתוני הלוח גדולים מדי</string>\n    <string name=\"data_is_too_large_to_copy\">הנתונים גדולים מדי להעתקה</string>\n    <string name=\"simple_weave_pixelization\">פיקסליזציה מארג פשוטה</string>\n    <string name=\"staggered_pixelization\">פיקסליזציה מדורגת</string>\n    <string name=\"cross_pixelization\">פיקסליזציה צולבת</string>\n    <string name=\"micro_macro_pixelization\">פיקסלים של מיקרו מאקרו</string>\n    <string name=\"orbital_pixelization\">פיקסליזציה של מסלול</string>\n    <string name=\"vortex_pixelization\">פיקסליזציה של וורטקס</string>\n    <string name=\"pulse_grid_pixelization\">Pixelization של רשת הדופק</string>\n    <string name=\"nucleus_pixelization\">פיקסליזציה של גרעין</string>\n    <string name=\"radial_weave_pixelization\">Pixelization של אריגה רדיאלית</string>\n    <string name=\"cannot_open_uri\">לא ניתן לפתוח את uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">מצב שלג</string>\n    <string name=\"enabled\">מופעל</string>\n    <string name=\"border_frame\">מסגרת גבול</string>\n    <string name=\"glitch_variant\">וריאנט תקלות</string>\n    <string name=\"channel_shift\">שינוי ערוץ</string>\n    <string name=\"max_offset\">מקסימום היסט</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">בלוק תקלה</string>\n    <string name=\"block_size\">גודל בלוק</string>\n    <string name=\"crt_curvature\">עקמומיות CRT</string>\n    <string name=\"curvature\">עַקמוּמִיוּת</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">מקסימום דרופ</string>\n    <string name=\"ai_tools\">כלי AI</string>\n    <string name=\"ai_tools_sub\">כלים שונים לעיבוד תמונות באמצעות מודלים של AI כמו הסרת חפצים או דה-נוז</string>\n    <string name=\"model_anime_undeint\">דחיסה, קווים משוננים</string>\n    <string name=\"model_broadcast\">קריקטורות, דחיסת שידור</string>\n    <string name=\"model_rgb_max_denoise_fp16\">דחיסה כללית, רעש כללי</string>\n    <string name=\"model_wb_denoise\">רעש מצויר חסר צבע</string>\n    <string name=\"model_span_anime_pretrain\">מהיר, דחיסה כללית, רעש כללי, אנימציה/קומיקס/אנימה</string>\n    <string name=\"model_book_scan\">סריקת ספרים</string>\n    <string name=\"model_overexposure\">תיקון חשיפה</string>\n    <string name=\"model_fbcnn_color_fp16\">הכי טוב בדחיסה כללית, תמונות צבעוניות</string>\n    <string name=\"model_fbcnn_gray_fp16\">הטוב ביותר בדחיסה כללית, תמונות בגווני אפור</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">דחיסה כללית, תמונות בגווני אפור, חזקות יותר</string>\n    <string name=\"model_scunet_color_gan_fp16\">רעש כללי, תמונות צבעוניות</string>\n    <string name=\"model_scunet_color_psnr_fp16\">רעש כללי, תמונות צבעוניות, פרטים טובים יותר</string>\n    <string name=\"model_scunet_gray_15_fp16\">רעש כללי, תמונות בגווני אפור</string>\n    <string name=\"model_scunet_gray_25_fp16\">רעש כללי, תמונות בגווני אפור, חזק יותר</string>\n    <string name=\"model_scunet_gray_50_fp16\">רעש כללי, תמונות בגווני אפור, החזק ביותר</string>\n    <string name=\"model_jpeg_destroyer\">דחיסה כללית</string>\n    <string name=\"model_jaywreck\">דחיסה כללית</string>\n    <string name=\"model_h264\">טקסטוריזציה, דחיסה של h264</string>\n    <string name=\"model_vhs\">דחיסת VHS</string>\n    <string name=\"model_cinepak\">דחיסה לא סטנדרטית (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">דחיסת Bink, טוב יותר בגיאומטריה</string>\n    <string name=\"model_debink_v5\">דחיסת Bink, חזקה יותר</string>\n    <string name=\"model_debink_v6\">דחיסת בינק, רכה, שומרת על פרטים</string>\n    <string name=\"model_antialias\">ביטול אפקט מדרגות המדרגות, החלקה</string>\n    <string name=\"model_kdm_scans\">אמנות/רישומים סרוקים, דחיסה מתונה, מואר</string>\n    <string name=\"model_bandage\">פסי צבע</string>\n    <string name=\"model_halftone\">איטי, מסיר חצאי גוונים</string>\n    <string name=\"model_colorizer\">צבעוני כללי לתמונות בגווני אפור/לבלב, לתוצאות טובות יותר השתמש ב-DDColor</string>\n    <string name=\"model_deedge\">הסרת קצוות</string>\n    <string name=\"model_desharpen\">מסיר חידוד יתר</string>\n    <string name=\"model_dither\">לאט, מתערער</string>\n    <string name=\"model_gainres\">אנטי-aliasing, חפצים כלליים, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 סורק עיבוד</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">דגם קל משקל לשיפור תמונה</string>\n    <string name=\"model_bcgone_detailed_v2\">הסרת חפצי דחיסה</string>\n    <string name=\"model_bcgone_smooth\">הסרת חפצי דחיסה</string>\n    <string name=\"model_bandage_smooth\">הסרת תחבושת עם תוצאות חלקות</string>\n    <string name=\"model_bendel_halftone\">עיבוד דפוסי חצי גוון</string>\n    <string name=\"model_dither_deleter_v3_smooth\">הסרת דפוסי זוהר V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">הסרת חפצי JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">שיפור מרקם H.264</string>\n    <string name=\"model_vhs_sharpen\">חידוד ושיפור VHS</string>\n    <string name=\"merging\">מיזוג</string>\n    <string name=\"chunk_size\">גודל נתח</string>\n    <string name=\"overlap_size\">גודל חפיפה</string>\n    <string name=\"note_chunk_info\">תמונות מעל %1$s פיקסלים יפורסו ויעובדו בחתיכות, חופפות מיזוג אלה כדי למנוע תפרים גלויים.</string>\n    <string name=\"large_chunk_warning\">גדלים גדולים עלולים לגרום לחוסר יציבות במכשירים מתקדמים</string>\n    <string name=\"select_one_to_start\">בחר אחד כדי להתחיל</string>\n    <string name=\"delete_model_sub\">האם ברצונך למחוק מודל %1$s? תצטרך להוריד אותו שוב</string>\n    <string name=\"confirm\">לְאַשֵׁר</string>\n    <string name=\"models\">דגמים</string>\n    <string name=\"downloaded_models\">מודלים שהורדו</string>\n    <string name=\"available_models\">דגמים זמינים</string>\n    <string name=\"preparing\">עֲרִיכָה</string>\n    <string name=\"active_model\">דגם פעיל</string>\n    <string name=\"failed_to_open_session\">פתיחת ההפעלה נכשלה</string>\n    <string name=\"only_onnx_models\">ניתן לייבא רק דגמי .onnx/.ort</string>\n    <string name=\"import_model\">דגם ייבוא</string>\n    <string name=\"import_model_sub\">יבא מודל onnx מותאם אישית לשימוש נוסף, רק דגמי onnx/ort מתקבלים, תומך כמעט בכל הגרסאות הדומות ל-esrgan</string>\n    <string name=\"imported_models\">דגמים מיובאים</string>\n    <string name=\"model_scunet_color_15_fp16\">רעש כללי, תמונות צבעוניות</string>\n    <string name=\"model_scunet_color_25_fp16\">רעש כללי, תמונות צבעוניות, חזק יותר</string>\n    <string name=\"model_scunet_color_50_fp16\">רעש כללי, תמונות צבעוניות, החזק ביותר</string>\n    <string name=\"model_artifacts_dithering_alsa\">מפחית חפצים מטלטלים ורצועות צבע, משפר שיפועים חלקים ואזורי צבע שטוחים.</string>\n    <string name=\"model_nmkd_brighten_redux\">משפר את הבהירות והניגודיות של התמונה עם הבהרה מאוזנת תוך שמירה על צבעים טבעיים.</string>\n    <string name=\"model_nmkd_brighten\">מבהיר תמונות כהות תוך שמירה על פרטים והימנעות מחשיפת יתר.</string>\n    <string name=\"model_nmkd_detoon\">מסיר גוון צבע מוגזם ומשחזר איזון צבע ניטרלי וטבעי יותר.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">מחיל גוון רעש מבוסס Poisson עם דגש על שימור פרטים ומרקמים עדינים.</string>\n    <string name=\"model_noise_toner_poisson_soft\">מחיל גוון רעש רך של Poisson לתוצאות חזותיות חלקות ופחות אגרסיביות.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">גוון רעש אחיד המתמקד בשימור פרטים ובהירות התמונה.</string>\n    <string name=\"model_noise_toner_uniform_soft\">גוון רעש עדין אחיד למרקם עדין ומראה חלק.</string>\n    <string name=\"model_repainter\">מתקן אזורים פגומים או לא אחידים על ידי צביעה מחדש של חפצים ושיפור עקביות התמונה.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">דגם קל משקל המסיר פסי צבע בעלות ביצועים מינימלית.</string>\n    <string name=\"model_jpeg_0_20\">מייעל תמונות עם חפצי דחיסה גבוהים מאוד (איכות 0-20%) לשיפור הבהירות.</string>\n    <string name=\"model_jpeg_20_40\">משפר תמונות עם חפצי דחיסה גבוהים (איכות 20-40%), שחזור פרטים והפחתת רעש.</string>\n    <string name=\"model_jpeg_40_60\">משפר תמונות עם דחיסה מתונה (איכות 40-60%), מאזן חדות וחלקות.</string>\n    <string name=\"model_jpeg_60_80\">מחדד תמונות עם דחיסה קלה (איכות 60-80%) כדי לשפר פרטים ומרקמים עדינים.</string>\n    <string name=\"model_jpeg_80_100\">משפר מעט תמונות כמעט ללא אובדן (איכות 80-100%) תוך שמירה על מראה ופרטים טבעיים.</string>\n    <string name=\"model_spongecolor_lite\">צביעה פשוטה ומהירה, קריקטורות, לא אידיאלי</string>\n    <string name=\"model_deblr\">מפחית מעט את טשטוש התמונה, משפר את החדות מבלי להכניס חפצים.</string>\n    <string name=\"processing_channel\">פעולות ארוכות טווח</string>\n    <string name=\"processing_image\">מעבד תמונה</string>\n    <string name=\"processing\">עיבוד</string>\n    <string name=\"model_artifacts_jpg_0_20\">מסיר חפצי דחיסה כבדים של JPEG בתמונות באיכות נמוכה מאוד (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">מפחית חפצי JPEG חזקים בתמונות דחוסות מאוד (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">מנקה חפצי JPEG מתונים תוך שמירה על פרטי התמונה (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">מחדד חפצי JPEG קלים בתמונות באיכות גבוהה למדי (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">מפחית בעדינות חפצי JPEG קלים בתמונות כמעט ללא אובדן (80-100%).</string>\n    <string name=\"model_redetail_v2\">משפר פרטים ומרקמים עדינים, משפר את החדות הנתפסת ללא חפצים כבדים.</string>\n    <string name=\"processing_finished\">העיבוד הסתיים</string>\n    <string name=\"processing_failed\">העיבוד נכשל</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">משפר את מרקמי העור ואת הפרטים תוך שמירה על מראה טבעי, מותאם למהירות.</string>\n    <string name=\"model_sbdv_dejpeg\">מסיר חפצי דחיסת JPEG ומשחזר את איכות התמונה עבור תמונות דחוסות.</string>\n    <string name=\"model_iso_denoise_v1\">מפחית את רעשי ה-ISO בתמונות שצולמו בתנאי תאורה חלשים, תוך שמירה על פרטים.</string>\n    <string name=\"model_dejumbo\">מתקן הדגשות חשופות יתר או \\\"ג\\'מבו\\\" ומשחזר איזון טונאלי טוב יותר.</string>\n    <string name=\"model_ddcolor_tiny\">דגם צביעה קל משקל ומהיר המוסיף צבעים טבעיים לתמונות בגווני אפור.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">דנואיז</string>\n    <string name=\"type_colorize\">צבע</string>\n    <string name=\"type_artifacts\">חפצים</string>\n    <string name=\"type_enhance\">לְהַגבִּיר</string>\n    <string name=\"type_anime\">אנימה</string>\n    <string name=\"type_scans\">סריקות</string>\n    <string name=\"type_upscale\">יוקרתי</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler לתמונות כלליות; דגם קטנטן שמשתמש בפחות GPU וזמן, עם טשטוש ו-denoise מתונים.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler לתמונות כלליות, שמירה על טקסטורות ופרטים טבעיים.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 יוקרתי לתמונות כלליות עם טקסטורות משופרות ותוצאות מציאותיות.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler מותאם לתמונות אנימה; 6 בלוקים RRDB לקווים ופרטים חדים יותר.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 upscaler עם אובדן MSE, מייצר תוצאות חלקות יותר וחפצים מופחתים עבור תמונות כלליות.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler מותאם לתמונות אנימה; גרסת 4B32F עם פרטים חדים יותר וקווים חלקים.</string>\n    <string name=\"model_ultrasharp_v2_x4\">דגם X4 UltraSharp V2 לתמונות כלליות; מדגיש חדות ובהירות.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; מהיר יותר וקטן יותר, שומר על פרטים תוך שימוש בפחות זיכרון GPU.</string>\n    <string name=\"model_rmbg_1_4\">דגם קל משקל להסרת רקע מהירה. ביצועים ודיוק מאוזנים. עובד עם פורטרטים, אובייקטים וסצנות. מומלץ לרוב מקרי השימוש.</string>\n    <string name=\"type_removebg\">הסר את BG</string>\n    <string name=\"horizontal_border_thickness\">עובי גבול אופקי</string>\n    <string name=\"vertical_border_thickness\">עובי גבול אנכי</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s צבעים</item>\n        <item quantity=\"many\">%1$s צבעים</item>\n        <item quantity=\"one\">%1$s צבעים</item>\n        <item quantity=\"two\">%1$s צבעים</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">הדגם הנוכחי אינו תומך ב-chunking, התמונה תעובד במידות מקוריות, הדבר עלול לגרום לצריכת זיכרון גבוהה ולבעיות במכשירים מתקדמים</string>\n    <string name=\"chunking_disabled\">Chunking מושבת, התמונה תעובד במידות מקוריות, זה עלול לגרום לצריכת זיכרון גבוהה ולבעיות במכשירים מתקדמים אך עשוי לתת תוצאות טובות יותר בהסקת מסקנות</string>\n    <string name=\"chunking\">צ\\'אנקינג</string>\n    <string name=\"model_u2net\">מודל פילוח תמונה ברמת דיוק גבוהה להסרת רקע</string>\n    <string name=\"model_u2netp\">גרסה קלת משקל של U2Net להסרת רקע מהירה יותר עם שימוש קטן יותר בזיכרון.</string>\n    <string name=\"model_ddcolor\">דגם DDColor מלא מספק צביעה באיכות גבוהה לתמונות כלליות עם חפצים מינימליים. הבחירה הטובה ביותר מכל דגמי הצביעה.</string>\n    <string name=\"model_ddcolor_artistic\">מערכי נתונים אומנותיים פרטיים מאומנים ב-DDColor; מייצר תוצאות צביעה מגוונות ואמנותיות עם פחות חפצי צבע לא מציאותיים.</string>\n    <string name=\"model_birefnet\">דגם BiRefNet קל משקל המבוסס על Swin Transformer להסרת רקע מדויקת.</string>\n    <string name=\"model_inspyrenet\">הסרת רקע איכותית עם קצוות חדים ושימור פרטים מעולה, במיוחד על אובייקטים מורכבים ורקעים מסובכים.</string>\n    <string name=\"model_isnet\">דגם הסרת רקע המייצר מסכות מדויקות עם קצוות חלקים, מתאים לחפצים כלליים ולשימור מתון לפרטים.</string>\n    <string name=\"model_already_downloaded\">הדגם כבר הורד</string>\n    <string name=\"model_successfully_imported\">הדגם יובא בהצלחה</string>\n    <string name=\"type\">סוּג</string>\n    <string name=\"keyword\">מילת מפתח</string>\n    <string name=\"very_fast\">מהיר מאוד</string>\n    <string name=\"normal\">נוֹרמָלִי</string>\n    <string name=\"slow\">לְהַאֵט</string>\n    <string name=\"very_slow\">מאוד איטי</string>\n    <string name=\"compute_percents\">חישוב אחוזים</string>\n    <string name=\"minimum_value_is\">הערך המינימלי הוא %1$s</string>\n    <string name=\"warp_sub\">עיוות תמונה על ידי ציור עם אצבעות</string>\n    <string name=\"warp\">לְעַקֵם</string>\n    <string name=\"hardness\">קַשִׁיוּת</string>\n    <string name=\"warp_mode\">מצב עיוות</string>\n    <string name=\"warp_mode_move\">מַהֲלָך</string>\n    <string name=\"warp_mode_grow\">לִגדוֹל</string>\n    <string name=\"warp_mode_shrink\">לְצַמֵק</string>\n    <string name=\"warp_mode_swirl_cw\">מערבולת CW</string>\n    <string name=\"warp_mode_swirl_ccw\">סיבוב CCW</string>\n    <string name=\"fade_strength\">חוזק דעיכה</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">ירידה למטה</string>\n    <string name=\"start_drop\">התחל ירידה</string>\n    <string name=\"end_drop\">סוף ירידה</string>\n    <string name=\"downloading\">מוריד</string>\n    <string name=\"smooth_shapes\">צורות חלקות</string>\n    <string name=\"smooth_shapes_sub\">השתמש בסופראליפסות במקום במלבנים מעוגלים סטנדרטיים לקבלת צורות חלקות וטבעיות יותר</string>\n    <string name=\"shape_type\">סוג צורה</string>\n    <string name=\"cut\">גְזִירָה</string>\n    <string name=\"rounded\">מְעוּגָל</string>\n    <string name=\"smooth\">לְהַחלִיק</string>\n    <string name=\"cut_shapes_sub\">קצוות חדים ללא עיגול</string>\n    <string name=\"rounded_shapes_sub\">פינות מעוגלות קלאסיות</string>\n    <string name=\"shapes_type\">סוג צורות</string>\n    <string name=\"corners_size\">גודל פינות</string>\n    <string name=\"squircle\">סקוורקל</string>\n    <string name=\"squircle_shapes_sub\">רכיבי ממשק משתמש מעוגלים ואלגנטיים</string>\n    <string name=\"filename_format\">פורמט שם קובץ</string>\n    <string name=\"prefix_pattern_description\">טקסט מותאם אישית ממוקם ממש בתחילת שם הקובץ, מושלם עבור שמות פרויקטים, מותגים או תגים אישיים.</string>\n    <string name=\"original_filename_pattern_description\">משתמש בשם הקובץ המקורי ללא סיומת, ועוזר לך לשמור על זיהוי המקור ללא פגע.</string>\n    <string name=\"width_pattern_description\">רוחב התמונה בפיקסלים, שימושי למעקב אחר שינויים ברזולוציה או שינוי קנה מידה של תוצאות.</string>\n    <string name=\"height_pattern_description\">גובה התמונה בפיקסלים, מועיל בעבודה עם יחסי גובה-רוחב או ייצוא.</string>\n    <string name=\"random_numbers_pattern_description\">יוצר ספרות אקראיות כדי להבטיח שמות קבצים ייחודיים; הוסף ספרות נוספות לבטיחות נוספת מפני כפילויות.</string>\n    <string name=\"sequence_number_pattern_description\">מונה הגדלה אוטומטית ליצוא אצווה, אידיאלי בעת שמירת תמונות מרובות בסשן אחד.</string>\n    <string name=\"preset_info_pattern_description\">מכניס את השם המוגדר מראש שהוחל לשם הקובץ כך שתוכל לזכור בקלות כיצד עבדה התמונה.</string>\n    <string name=\"scale_mode_pattern_description\">מציג את מצב קנה המידה של התמונה המשמש במהלך העיבוד, ועוזר להבחין בין תמונות שגודלו, חתכו או הותאמו.</string>\n    <string name=\"suffix_pattern_description\">טקסט מותאם אישית ממוקם בסוף שם הקובץ, שימושי לניהול גרסאות כמו _v2, _edited או _final.</string>\n    <string name=\"extension_pattern_description\">סיומת הקובץ (png, jpg, webp וכו\\'), תואמת אוטומטית לפורמט השמור בפועל.</string>\n    <string name=\"formatted_timestamp_pattern_description\">חותמת זמן הניתנת להתאמה אישית המאפשרת לך להגדיר פורמט משלך לפי מפרט Java למיון מושלם.</string>\n    <string name=\"fling_type\">סוג השלכה</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">סגנון iOS</string>\n    <string name=\"smooth_curve\">עקומה חלקה</string>\n    <string name=\"quick_stop\">עצירה מהירה</string>\n    <string name=\"bouncy\">קופצני</string>\n    <string name=\"floaty\">צף</string>\n    <string name=\"snappy\">נִמרָץ</string>\n    <string name=\"ultra_smooth\">אולטרה חלק</string>\n    <string name=\"adaptive\">הסתגלות</string>\n    <string name=\"accessibility_aware\">מודע לנגישות</string>\n    <string name=\"reduced_motion\">תנועה מופחתת</string>\n    <string name=\"android_native_sub\">פיזיקת גלילה מקורית של אנדרואיד להשוואה בסיסית</string>\n    <string name=\"smooth_sub\">גלילה מאוזנת וחלקה לשימוש כללי</string>\n    <string name=\"ios_style_sub\">חיכוך גבוה יותר התנהגות גלילה דמוית iOS</string>\n    <string name=\"smooth_curve_sub\">עקומת ספליין ייחודית לתחושת גלילה ברורה</string>\n    <string name=\"quick_stop_sub\">גלילה מדויקת עם עצירה מהירה</string>\n    <string name=\"bouncy_sub\">גלילה קופצנית שובבה ומגיבה</string>\n    <string name=\"floaty_sub\">מגילות ארוכות וגולשות לגלישה בתוכן</string>\n    <string name=\"snappy_sub\">גלילה מהירה ומגיבה עבור ממשקי משתמש אינטראקטיביים</string>\n    <string name=\"ultra_smooth_sub\">גלילה חלקה מובחרת עם מומנטום מורחב</string>\n    <string name=\"adaptive_sub\">מתאים את הפיזיקה על סמך מהירות הטיפה</string>\n    <string name=\"accessibility_aware_sub\">מכבד את הגדרות נגישות המערכת</string>\n    <string name=\"reduced_motion_sub\">תנועה מינימלית לצרכי נגישות</string>\n    <string name=\"primary_lines\">קווים ראשיים</string>\n    <string name=\"primary_lines_sub\">מוסיף קו עבה יותר בכל שורה חמישית</string>\n    <string name=\"fill_color\">צבע מילוי</string>\n    <string name=\"hidden_tools\">כלים נסתרים</string>\n    <string name=\"hidden_for_share\">כלים מוסתרים לשיתוף</string>\n    <string name=\"color_library\">ספריית צבע</string>\n    <string name=\"color_library_sub\">עיין באוסף עצום של צבעים</string>\n    <string name=\"model_fatality_deblur\">מחדד ומסיר טשטוש מתמונות תוך שמירה על פרטים טבעיים, אידיאלי לתיקון תמונות לא ממוקדות.</string>\n    <string name=\"model_unresize_v3\">משחזר באופן אינטליגנטי תמונות ששונו בעבר, משחזר פרטים ומרקמים שאבדו.</string>\n    <string name=\"model_liveaction_v1_span\">מותאם לתוכן חי, מפחית חפצי דחיסה ומשפר פרטים עדינים במסגרות של סרטים/תוכניות טלוויזיה.</string>\n    <string name=\"model_vhs2hd_realplksr\">ממיר קטעים באיכות VHS ל-HD, מסיר רעשי קלטת ושיפור הרזולוציה תוך שמירה על תחושת וינטג\\'.</string>\n    <string name=\"model_text2hd_v1\">מתמחה לתמונות וצילומי מסך עתירי טקסט, מחדד תווים ומשפר את הקריאה.</string>\n    <string name=\"model_frankendata_pretrainer\">שיפור קנה מידה מתקדם מאומן על מערכי נתונים מגוונים, מצוין לשיפור צילום למטרות כלליות.</string>\n    <string name=\"model_realwebphoto_v2\">מותאם לתמונות דחוסות באינטרנט, מסיר חפצי JPEG ומשחזר מראה טבעי.</string>\n    <string name=\"model_realwebphoto_v4\">גרסה משופרת לתמונות אינטרנט עם שימור מרקם טוב יותר והפחתת חפצים.</string>\n    <string name=\"model_dat_2x\">העלאת קנה מידה פי 2 עם טכנולוגיית Dual Aggregation Transformer, שומרת על חדות ופרטים טבעיים.</string>\n    <string name=\"model_dat_3x\">הגדלה פי 3 באמצעות ארכיטקטורת שנאים מתקדמת, אידיאלית לצרכי הגדלה מתונים.</string>\n    <string name=\"model_dat_4x\">שיפוץ קנה מידה איכותי פי 4 עם רשת שנאים מתקדמת, משמרת פרטים עדינים בקנה מידה גדול יותר.</string>\n    <string name=\"model_nafnet_deblurring\">מסיר טשטוש/רעש ורעידות מתמונות. מטרה כללית אבל הכי טובה בתמונות.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">משחזר תמונות באיכות נמוכה באמצעות שנאי Swin2SR, מותאם לפירוק BSRGAN. נהדר לתיקון חפצי דחיסה כבדים ושיפור פרטים בקנה מידה פי 4.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">העלאת קנה מידה פי 4 עם שנאי SwinIR מאומן על השפלה של BSRGAN. משתמש ב-GAN למרקמים חדים יותר ופרטים טבעיים יותר בתמונות ובסצנות מורכבות.</string>\n    <string name=\"path\">נָתִיב</string>\n    <string name=\"merge_pdf\">מיזוג PDF</string>\n    <string name=\"merge_pdf_sub\">שלב קובצי PDF מרובים למסמך אחד</string>\n    <string name=\"files_order\">סדר קבצים</string>\n    <string name=\"pages_short\">עמ.</string>\n    <string name=\"split_pdf\">פיצול PDF</string>\n    <string name=\"split_pdf_sub\">חלץ דפים ספציפיים ממסמך PDF</string>\n    <string name=\"rotate_pdf\">סובב PDF</string>\n    <string name=\"rotate_pdf_sub\">תקן את כיוון העמוד לצמיתות</string>\n    <string name=\"pages\">דפים</string>\n    <string name=\"rearrange_pdf\">סידור מחדש של PDF</string>\n    <string name=\"rearrange_pdf_sub\">גרור ושחרר דפים כדי לסדר אותם מחדש</string>\n    <string name=\"hold_drag_drop\">החזק וגרור דפים</string>\n    <string name=\"page_numbers\">מספרי עמודים</string>\n    <string name=\"page_numbers_sub\">הוסף מספור למסמכים שלך באופן אוטומטי</string>\n    <string name=\"label_format\">פורמט תווית</string>\n    <string name=\"pdf_to_text\">PDF לטקסט (OCR)</string>\n    <string name=\"pdf_to_text_sub\">חלץ טקסט רגיל ממסמכי ה-PDF שלך</string>\n    <string name=\"watermark_pdf_sub\">כיסוי טקסט מותאם אישית למיתוג או אבטחה</string>\n    <string name=\"signature\">חֲתִימָה</string>\n    <string name=\"signature_sub\">הוסף את החתימה האלקטרונית שלך לכל מסמך</string>\n    <string name=\"will_be_for_signature\">זה ישמש כחתימה</string>\n    <string name=\"unlock_pdf\">ביטול נעילת PDF</string>\n    <string name=\"unlock_pdf_sub\">הסר סיסמאות מהקבצים המוגנים שלך</string>\n    <string name=\"protect_pdf\">הגן על PDF</string>\n    <string name=\"protect_pdf_sub\">אבטח את המסמכים שלך עם הצפנה חזקה</string>\n    <string name=\"success\">הַצלָחָה</string>\n    <string name=\"pdf_unlocked\">PDF לא נעול, אתה יכול לשמור או לשתף אותו</string>\n    <string name=\"repair_pdf\">תיקון PDF</string>\n    <string name=\"repair_pdf_sub\">ניסיון לתקן מסמכים פגומים או בלתי קריאים</string>\n    <string name=\"grayscale\">גווני אפור</string>\n    <string name=\"grayscale_pdf_sub\">המר את כל התמונות המוטבעות במסמכים לגווני אפור</string>\n    <string name=\"compress_pdf\">דחוס PDF</string>\n    <string name=\"compress_pdf_sub\">בצע אופטימיזציה של גודל קובץ המסמך שלך לשיתוף קל יותר</string>\n    <string name=\"repair_info\">ImageToolbox בונה מחדש את טבלת ההפניות הפנימית ומחדשת את מבנה הקובץ מאפס. זה יכול לשחזר גישה לקבצים רבים ש\\\\\"לא ניתן לפתוח\\\\\"</string>\n    <string name=\"grayscale_info\">כלי זה ממיר את כל תמונות המסמכים לגווני אפור. הטוב ביותר להדפסה ולהקטנת גודל הקובץ</string>\n    <string name=\"metadata\">מטא נתונים</string>\n    <string name=\"metadata_pdf_sub\">ערוך מאפייני מסמך לפרטיות טובה יותר</string>\n    <string name=\"tags\">תגים</string>\n    <string name=\"producer\">יַצרָן</string>\n    <string name=\"author\">מְחַבֵּר</string>\n    <string name=\"keywords\">מילות מפתח</string>\n    <string name=\"creator\">יוֹצֵר</string>\n    <string name=\"privacy_deep_clean\">פרטיות ניקוי עמוק</string>\n    <string name=\"privacy_deep_clean_sub\">נקה את כל המטא נתונים הזמינים עבור מסמך זה</string>\n    <string name=\"page\">עַמוּד</string>\n    <string name=\"deep_ocr\">OCR עמוק</string>\n    <string name=\"deep_ocr_sub\">חלץ טקסט מהמסמך ואחסן אותו בקובץ הטקסט האחד באמצעות מנוע Tesseract</string>\n    <string name=\"cant_remove_all\">לא ניתן להסיר את כל הדפים</string>\n    <string name=\"remove_pages_pdf\">הסר דפי PDF</string>\n    <string name=\"remove_pages_pdf_sub\">הסר דפים ספציפיים ממסמך PDF</string>\n    <string name=\"tap_to_remove\">הקש כדי להסיר</string>\n    <string name=\"manually\">באופן ידני</string>\n    <string name=\"crop_pdf\">חיתוך PDF</string>\n    <string name=\"crop_pdf_sub\">חתוך דפי מסמכים לכל גבול</string>\n    <string name=\"flatten_pdf\">שטח PDF</string>\n    <string name=\"flatten_pdf_sub\">הפוך את PDF לבלתי ניתן לשינוי על ידי רסטר דפי מסמכים</string>\n    <string name=\"camera_failed_to_open\">לא ניתן להפעיל את המצלמה. אנא בדוק הרשאות וודא שהיא לא בשימוש על ידי אפליקציה אחרת.</string>\n    <string name=\"extract_images\">חלץ תמונות</string>\n    <string name=\"extract_images_sub\">חלץ תמונות המוטבעות בקובצי PDF ברזולוציה המקורית שלהן</string>\n    <string name=\"pdf_no_embedded\">קובץ PDF זה אינו מכיל תמונות מוטבעות</string>\n    <string name=\"extract_images_info\">כלי זה סורק כל עמוד ומשחזר תמונות מקור באיכות מלאה - מושלם לשמירת מסמכי מקור ממסמכים</string>\n    <string name=\"draw_signature\">צייר חתימה</string>\n    <string name=\"pen_params\">עט פרמס</string>\n    <string name=\"draw_signature_sub\">השתמש בחתימה משלך כתמונה שתוצב על מסמכים</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">פצל מסמך עם מרווח נתון וארוז מסמכים חדשים לארכיון zip</string>\n    <string name=\"interval\">הַפסָקָה</string>\n    <string name=\"print_pdf\">הדפס PDF</string>\n    <string name=\"print_pdf_sub\">הכן מסמך להדפסה עם גודל עמוד מותאם אישית</string>\n    <string name=\"pages_per_sheet\">דפים לגיליון</string>\n    <string name=\"orientation\">הִתמַצְאוּת</string>\n    <string name=\"page_size\">גודל עמוד</string>\n    <string name=\"margin\">מֶתַח</string>\n    <string name=\"bloom\">לִפְרוֹחַ</string>\n    <string name=\"soft_knee\">ברך רכה</string>\n    <string name=\"model_realesr_animevideo_v3x4\">מותאם לאנימה וסרטים מצוירים. שיפור קנה מידה מהיר עם צבעים טבעיים משופרים ופחות חפצים</string>\n    <string name=\"one_ui_sub\">סגנון כמו Samsung One UI 7</string>\n    <string name=\"calculate_hint\">הזן כאן סמלים מתמטיים בסיסיים כדי לחשב את הערך הרצוי (למשל (5+5)*10)</string>\n    <string name=\"math_expression\">ביטוי מתמטי</string>\n    <string name=\"pick_up_to_n_collage_images\">אסוף עד %1$s תמונות</string>\n    <string name=\"keep_date_time\">שמור על תאריך שעון</string>\n    <string name=\"keep_date_time_sub\">שמור תמיד תגיות exif הקשורות לתאריך ושעה, עובד ללא תלות באפשרות Keep exif</string>\n    <string name=\"background_color_for_alpha_formats\">צבע רקע עבור פורמטי אלפא</string>\n    <string name=\"background_color_for_alpha_formats_sub\">מוסיף יכולת להגדיר צבע רקע עבור כל פורמט תמונה עם תמיכה באלפא, כאשר מושבת זה זמין עבור לא אלפא בלבד</string>\n    <string name=\"open_markup_project\">פרויקט פתוח</string>\n    <string name=\"open_markup_project_sub\">המשך לערוך פרויקט תמונה כלים שנשמר בעבר</string>\n    <string name=\"markup_project_open_failed\">לא ניתן לפתוח את פרויקט Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">בפרויקט Image Toolbox חסרים נתוני פרויקט</string>\n    <string name=\"markup_project_corrupted\">פרויקט Image Toolbox פגום</string>\n    <string name=\"unsupported_markup_project_version\">גרסת פרויקט Image Toolbox לא נתמכת: %1$d</string>\n    <string name=\"save_markup_project\">שמור פרויקט</string>\n    <string name=\"save_markup_project_sub\">אחסן שכבות, רקע והיסטוריית עריכה בקובץ פרויקט הניתן לעריכה</string>\n    <string name=\"failed_to_open\">הפתיחה נכשלה</string>\n    <string name=\"ocr_write_to_searchable_pdf\">כתוב ל-PDF הניתן לחיפוש</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">זיהוי טקסט מאצוות תמונה ושמור PDF שניתן לחיפוש עם תמונה ושכבת טקסט לבחירה</string>\n    <string name=\"layer_alpha\">שכבת אלפא</string>\n    <string name=\"horizontal_flip\">היפוך אופקי</string>\n    <string name=\"vertical_flip\">Flip אנכי</string>\n    <string name=\"lock\">לִנְעוֹל</string>\n    <string name=\"add_shadow\">הוסף צל</string>\n    <string name=\"shadow_color\">צבע צל</string>\n    <string name=\"text_geometry\">גיאומטריית טקסט</string>\n    <string name=\"text_geometry_sub\">למתוח או להטות טקסט לסטייליזציה חדה יותר</string>\n    <string name=\"scale_x\">סולם X</string>\n    <string name=\"skew_x\">עיוות X</string>\n    <string name=\"remove_annotations\">הסר הערות</string>\n    <string name=\"remove_annotations_sub\">הסר סוגי הערות שנבחרו כגון קישורים, הערות, הדגשות, צורות או שדות טופס מדפי PDF</string>\n    <string name=\"annotation_link\">היפר-קישורים</string>\n    <string name=\"annotation_file_attachment\">קבצים מצורפים</string>\n    <string name=\"annotation_line\">קווים</string>\n    <string name=\"annotation_popup\">חלונות קופצים</string>\n    <string name=\"annotation_stamp\">חותמות</string>\n    <string name=\"annotation_shapes\">צורות</string>\n    <string name=\"annotation_text\">הערות טקסט</string>\n    <string name=\"annotation_text_markup\">סימון טקסט</string>\n    <string name=\"annotation_widget\">שדות טופס</string>\n    <string name=\"annotation_markup\">סימון</string>\n    <string name=\"annotation_unknown\">לֹא יְדוּעַ</string>\n    <string name=\"annotations\">הערות</string>\n    <string name=\"ungroup\">בטל קבוצה</string>\n    <string name=\"add_shadow_sub\">הוסף צל טשטוש מאחורי השכבה עם צבע והיסטים הניתנים להגדרה</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ja/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">問題が発生しました: %1$s</string>\n    <string name=\"check_source_code_sub\">最新のアップデートを入手し、問題を議論するなど</string>\n    <string name=\"color_red\">赤</string>\n    <string name=\"about_app\">アプリについて</string>\n    <string name=\"nothing_found_by_search\">検索クエリに一致するものが見つかりませんでした</string>\n    <string name=\"size\">サイズ %1$s</string>\n    <string name=\"loading\">読み込み中…</string>\n    <string name=\"image_too_large_preview\">画像はプレビューするには大きすぎますが、保存は試みます</string>\n    <string name=\"pick_image\">画像を選択して開始</string>\n    <string name=\"width\">幅 %1$s</string>\n    <string name=\"height\">高さ %1$s</string>\n    <string name=\"quality\">品質</string>\n    <string name=\"extension\">拡張子</string>\n    <string name=\"resize_type\">リサイズタイプ</string>\n    <string name=\"explicit\">絶対指定</string>\n    <string name=\"flexible\">相対指定</string>\n    <string name=\"pick_image_alt\">画像を選択</string>\n    <string name=\"app_closing_sub\">アプリを終了してもよろしいですか？</string>\n    <string name=\"app_closing\">アプリ終了</string>\n    <string name=\"stay\">残る</string>\n    <string name=\"close\">閉じる</string>\n    <string name=\"reset_image\">画像をリセット</string>\n    <string name=\"reset_image_sub\">画像の変更が初期値に戻ります</string>\n    <string name=\"values_reset\">値が正しくリセットされました</string>\n    <string name=\"reset\">リセット</string>\n    <string name=\"something_went_wrong\">問題が発生しました</string>\n    <string name=\"restart_app\">アプリを再起動</string>\n    <string name=\"copied\">クリップボードにコピーしました</string>\n    <string name=\"exception\">例外</string>\n    <string name=\"edit_exif\">EXIF編集</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">EXIF データが見つかりませんでした</string>\n    <string name=\"add_tag\">タグを追加</string>\n    <string name=\"save\">保存</string>\n    <string name=\"clear\">クリア</string>\n    <string name=\"clear_exif\">EXIFをクリア</string>\n    <string name=\"cancel\">キャンセル</string>\n    <string name=\"clear_exif_sub\">画像のすべてのEXIFデータが消去されます。この操作は元に戻せません！</string>\n    <string name=\"presets\">プリセット</string>\n    <string name=\"crop\">切り抜き</string>\n    <string name=\"image_not_saved\">保存中</string>\n    <string name=\"image_not_saved_sub\">今終了すると、保存されていない変更はすべて失われます</string>\n    <string name=\"check_source_code\">ソースコード</string>\n    <string name=\"single_edit\">単一編集</string>\n    <string name=\"single_edit_sub\">指定された単一の画像の仕様を変更</string>\n    <string name=\"pick_color\">色を抽出</string>\n    <string name=\"pick_color_sub\">画像から色を選んで、コピーまたは共有</string>\n    <string name=\"image\">画像</string>\n    <string name=\"color\">色</string>\n    <string name=\"color_copied\">色をコピーしました</string>\n    <string name=\"images\">画像: %d</string>\n    <string name=\"crop_sub\">画像を任意の範囲でトリミング</string>\n    <string name=\"version\">バージョン</string>\n    <string name=\"keep_exif\">EXIFを保持</string>\n    <string name=\"change_preview\">プレビューを変更</string>\n    <string name=\"remove\">削除</string>\n    <string name=\"palette_sub\">指定された画像からカラーパレットスウォッチを生成</string>\n    <string name=\"generate_palette\">パレットを生成</string>\n    <string name=\"palette\">パレット</string>\n    <string name=\"update\">更新</string>\n    <string name=\"new_version\">新バージョン %1$s</string>\n    <string name=\"unsupported_type\">サポートされていないタイプ: %1$s</string>\n    <string name=\"no_palette\">この画像のパレットを生成できません</string>\n    <string name=\"original\">オリジナル</string>\n    <string name=\"folder\">出力フォルダ</string>\n    <string name=\"def\">デフォルト</string>\n    <string name=\"custom\">カスタム</string>\n    <string name=\"unspecified\">未指定</string>\n    <string name=\"device_storage\">デバイスストレージ</string>\n    <string name=\"by_bytes_resize\">サイズ指定でリサイズ</string>\n    <string name=\"max_bytes\">KBでの最大サイズ</string>\n    <string name=\"by_bytes_resize_sub\">KB単位で指定したサイズに画像をリサイズ</string>\n    <string name=\"compare\">比較</string>\n    <string name=\"compare_sub\">指定された2つの画像を比較</string>\n    <string name=\"pick_two_images\">開始するには2つの画像を選択してください</string>\n    <string name=\"pick_images\">画像を選択</string>\n    <string name=\"settings\">設定</string>\n    <string name=\"night_mode\">ナイトモード</string>\n    <string name=\"dark\">ダーク</string>\n    <string name=\"light\">ライト</string>\n    <string name=\"system\">システム</string>\n    <string name=\"dynamic_colors\">ダイナミックカラー</string>\n    <string name=\"customization\">カスタマイズ</string>\n    <string name=\"allow_image_monet\">画像モネを許可</string>\n    <string name=\"allow_image_monet_sub\">有効にすると、編集する画像を選択したとき、アプリの色がその画像に合わせて調整されます</string>\n    <string name=\"language\">言語</string>\n    <string name=\"amoled_mode\">AMOLED モード</string>\n    <string name=\"amoled_mode_sub\">有効にすると、ナイトモードでサーフェスカラーが完全な黒に設定されます</string>\n    <string name=\"color_scheme\">カラースキーム</string>\n    <string name=\"color_green\">緑</string>\n    <string name=\"color_blue\">青</string>\n    <string name=\"clipboard_paste_invalid_color_code\">有効なaRGBコードを貼り付けてください</string>\n    <string name=\"clipboard_paste_invalid_empty\">貼り付けるものがありません</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">ダイナミックカラーがオンの間はアプリの配色を変更できません</string>\n    <string name=\"pick_accent_color\">アプリテーマは選択した色に基づいて設定されます</string>\n    <string name=\"no_updates\">アップデートが見つかりません</string>\n    <string name=\"issue_tracker\">問題追跡</string>\n    <string name=\"issue_tracker_sub\">バグレポートや機能リクエストはこちらへ</string>\n    <string name=\"help_translate\">翻訳を手伝う</string>\n    <string name=\"help_translate_sub\">翻訳の間違いを修正したり、プロジェクトを他の言語にローカライズしたりする</string>\n    <string name=\"search_here\">ここで検索</string>\n    <string name=\"dynamic_colors_sub\">有効にすると、アプリの色が壁紙の色に合わせて調整されます</string>\n    <string name=\"failed_to_save\">%d個の画像の保存に失敗しました</string>\n    <string name=\"values\">値</string>\n    <string name=\"add\">追加</string>\n    <string name=\"permission\">権限</string>\n    <string name=\"border_thickness\">枠線の太さ</string>\n    <string name=\"surface\">サーフェス</string>\n    <string name=\"donation_sub\">このアプリケーションは完全に無料ですが、プロジェクト開発をサポートしたい場合はここをクリックしてください</string>\n    <string name=\"external_storage\">外部ストレージ</string>\n    <string name=\"fab_alignment\">FABの配置</string>\n    <string name=\"check_updates\">アップデートの確認</string>\n    <string name=\"check_updates_sub\">有効にすると、アプリ起動時にアップデートダイアログが表示されます</string>\n    <string name=\"primary\">プライマリ</string>\n    <string name=\"tertiary\">第三</string>\n    <string name=\"secondary\">セカンダリ</string>\n    <string name=\"grant\">許可</string>\n    <string name=\"permission_sub\">アプリが機能するには、画像を保存するためにストレージへのアクセス権が必要です。次のダイアログボックスで権限を許可してください。</string>\n    <string name=\"zoom\">画像ズーム</string>\n    <string name=\"prefix\">接頭辞</string>\n    <string name=\"filename\">ファイル名</string>\n    <string name=\"grant_permission_manual\">アプリが機能するにはこの権限が必要です。手動で許可してください</string>\n    <string name=\"share\">共有</string>\n    <string name=\"monet_colors\">Monetカラー</string>\n    <string name=\"emoji\">絵文字</string>\n    <string name=\"emoji_sub\">メイン画面に表示する絵文字を選択</string>\n    <string name=\"add_file_size\">ファイルサイズを追加</string>\n    <string name=\"add_file_size_sub\">有効にすると、出力ファイルの名前に保存済み画像の幅と高さが追加されます</string>\n    <string name=\"delete_exif\">EXIFを削除</string>\n    <string name=\"delete_exif_sub\">任意の画像セットからEXIFメタデータを削除</string>\n    <string name=\"image_preview\">画像プレビュー</string>\n    <string name=\"image_preview_sub\">GIF、SVGなど、あらゆるタイプの画像をプレビュー</string>\n    <string name=\"photo_picker_sub\">画面下部に表示されるAndroidのモダンなフォトピッカーで、Android 12以上でのみ動作する可能性があります。EXIFメタデータの取得に問題がある場合があります</string>\n    <string name=\"image_source\">画像ソース</string>\n    <string name=\"photo_picker\">フォトピッカー</string>\n    <string name=\"file_explorer_picker_sub\">画像を選択するためにGetContentインテントを使用します。どこでも動作しますが、一部のデバイスでは選択した画像の取得に問題があることが知られています。これは私のせいではありません。</string>\n    <string name=\"options_arrangement\">オプションの配置</string>\n    <string name=\"emojis_count\">絵文字の数</string>\n    <string name=\"sequence_num\">連番</string>\n    <string name=\"original_filename\">元のファイル名</string>\n    <string name=\"add_original_filename\">元のファイル名を追加</string>\n    <string name=\"add_original_filename_sub\">有効にすると、出力画像の名前に元のファイル名が追加されます</string>\n    <string name=\"replace_sequence_number\">連番を置き換え</string>\n    <string name=\"replace_sequence_number_sub\">有効にすると、バッチ処理を使用する場合、標準のタイムスタンプが画像の連番に置き換えられます</string>\n    <string name=\"filename_not_work_with_photopicker\">フォトピッカー画像ソースを選択している場合、元のファイル名の追加は機能しません</string>\n    <string name=\"gallery_picker\">ギャラリー</string>\n    <string name=\"file_explorer_picker\">ファイルエクスプローラー</string>\n    <string name=\"gallery_picker_sub\">シンプルなギャラリー画像ピッカー。メディアピッキングを提供するアプリがある場合のみ機能します</string>\n    <string name=\"edit\">編集</string>\n    <string name=\"order\">順序</string>\n    <string name=\"order_sub\">メイン画面上のツールの順序を決定します</string>\n    <string name=\"highlights\">ハイライト</string>\n    <string name=\"shadows\">シャドウ</string>\n    <string name=\"sharpen\">シャープ</string>\n    <string name=\"crosshatch\">クロスハッチ</string>\n    <string name=\"spacing\">間隔</string>\n    <string name=\"line_width\">線の幅</string>\n    <string name=\"image_link\">画像リンク</string>\n    <string name=\"fill\">塗りつぶし</string>\n    <string name=\"add_filter\">フィルター追加</string>\n    <string name=\"filter\">フィルター</string>\n    <string name=\"monochrome\">モノクロ</string>\n    <string name=\"swirl\">渦巻き</string>\n    <string name=\"bulge\">膨張</string>\n    <string name=\"dilation\">拡張</string>\n    <string name=\"sphere_refraction\">球面屈折</string>\n    <string name=\"color_matrix\">カラーマトリックス</string>\n    <string name=\"limits_resize\">制限付きサイズ変更</string>\n    <string name=\"non_maximum_suppression\">非最大抑制</string>\n    <string name=\"stack_blur\">スタックぼかし</string>\n    <string name=\"luminance_threshold\">輝度しきい値</string>\n    <string name=\"second_color\">第二色</string>\n    <string name=\"load_image_from_net\">Webから画像を読み込む</string>\n    <string name=\"load_image_from_net_sub\">インターネットから任意の画像を読み込んでプレビュー、ズーム、編集し、必要に応じて保存できます。</string>\n    <string name=\"fit\">フィット</string>\n    <string name=\"explicit_description\">指定された高さと幅に画像のサイズを変更します。画像のアスペクト比が変わる可能性があります。</string>\n    <string name=\"flexible_description\">長辺を指定した幅または高さに合わせて画像をリサイズします。サイズ計算はすべて保存後に行われ、アスペクト比は維持されます。</string>\n    <string name=\"brightness\">明るさ</string>\n    <string name=\"contrast\">コントラスト</string>\n    <string name=\"hue\">色相</string>\n    <string name=\"saturation\">彩度</string>\n    <string name=\"filter_sub\">画像に一連のフィルターを適用する</string>\n    <string name=\"filters\">フィルター</string>\n    <string name=\"light_aka_illumination\">ライト</string>\n    <string name=\"color_filter\">カラーフィルター</string>\n    <string name=\"alpha\">アルファ</string>\n    <string name=\"exposure\">露出</string>\n    <string name=\"white_balance\">ホワイトバランス</string>\n    <string name=\"temperature\">色温度</string>\n    <string name=\"tint\">色合い</string>\n    <string name=\"gamma\">ガンマ</string>\n    <string name=\"highlights_shadows\">ハイライトとシャドウ</string>\n    <string name=\"haze\">ヘイズ</string>\n    <string name=\"effect\">エフェクト</string>\n    <string name=\"distance\">距離</string>\n    <string name=\"slope\">傾き</string>\n    <string name=\"sepia\">セピア</string>\n    <string name=\"negative\">ネガティブ</string>\n    <string name=\"solarize\">ソラリゼーション</string>\n    <string name=\"vibrance\">バイブランス</string>\n    <string name=\"black_and_white\">白黒</string>\n    <string name=\"sobel_edge\">ソーベルエッジ</string>\n    <string name=\"blur\">ぼかし</string>\n    <string name=\"halftone\">ハーフトーン</string>\n    <string name=\"cga_colorspace\">CGAカラースペース</string>\n    <string name=\"gaussian_blur\">ガウスぼかし</string>\n    <string name=\"box_blur\">ボックスぼかし</string>\n    <string name=\"bilaterial_blur\">バイラテラルぼかし</string>\n    <string name=\"emboss\">エンボス</string>\n    <string name=\"laplacian\">ラプラシアン</string>\n    <string name=\"vignette\">ビネット</string>\n    <string name=\"start\">開始</string>\n    <string name=\"end\">終了</string>\n    <string name=\"kuwahara\">桑原スムージング</string>\n    <string name=\"radius\">半径</string>\n    <string name=\"scale\">スケール</string>\n    <string name=\"distortion\">歪み</string>\n    <string name=\"angle\">角度</string>\n    <string name=\"refractive_index\">屈折率</string>\n    <string name=\"glass_sphere_refraction\">ガラス球体屈折</string>\n    <string name=\"opacity\">不透明度</string>\n    <string name=\"limits_resize_sub\">アスペクト比を維持しながら、指定された高さと幅に画像のサイズを変更します</string>\n    <string name=\"sketch\">スケッチ</string>\n    <string name=\"threshold\">しきい値</string>\n    <string name=\"quantizationLevels\">量子化レベル</string>\n    <string name=\"smooth_toon\">スムーズトゥーン</string>\n    <string name=\"toon\">トゥーン</string>\n    <string name=\"posterize\">ポスタライズ</string>\n    <string name=\"weak_pixel_inclusion\">弱ピクセル包含</string>\n    <string name=\"lookup\">ルックアップ</string>\n    <string name=\"convolution3x3\">畳み込み 3x3</string>\n    <string name=\"rgb_filter\">RGBフィルター</string>\n    <string name=\"false_color\">偽色</string>\n    <string name=\"first_color\">第一色</string>\n    <string name=\"reorder\">並べ替え</string>\n    <string name=\"fast_blur\">高速ぼかし</string>\n    <string name=\"blur_size\">ぼかしサイズ</string>\n    <string name=\"blur_center_x\">ぼかし中心X</string>\n    <string name=\"blur_center_y\">ぼかし中心Y</string>\n    <string name=\"zoom_blur\">ズームぼかし</string>\n    <string name=\"color_balance\">カラーバランス</string>\n    <string name=\"no_image\">画像がありません</string>\n    <string name=\"content_scale\">コンテンツスケール</string>\n    <string name=\"screenshot\">スクリーンショット</string>\n    <string name=\"skip\">スキップ</string>\n    <string name=\"invalid_password_or_not_encrypted\">パスワードが無効か、選択したファイルが暗号化されていません</string>\n    <string name=\"auto_cache_clearing\">自動キャッシュクリア</string>\n    <string name=\"draw_on_background\">背景に描画</string>\n    <string name=\"pick_file\">ファイルを選択</string>\n    <string name=\"store_file_desc\">このファイルをデバイスに保存するか、共有アクションを使用して好きな場所に配置してください</string>\n    <string name=\"features\">機能</string>\n    <string name=\"cache\">キャッシュ</string>\n    <string name=\"secondary_customization\">セカンダリカスタマイズ</string>\n    <string name=\"fallback_option\">フォールバックオプション</string>\n    <string name=\"decrypt\">復号化</string>\n    <string name=\"pick_file_to_start\">開始するにはファイルを選択してください</string>\n    <string name=\"decryption\">復号化</string>\n    <string name=\"compatibility\">互換性</string>\n    <string name=\"implementation_sub\">AES-256をGCMモードで動作させ、パディングは行いません。デフォルトでは12バイトのランダムIVを使用します。必要に応じてアルゴリズムを選択でき、鍵には256ビット長のSHA-3ハッシュを用います。</string>\n    <string name=\"file_size\">ファイルサイズ</string>\n    <string name=\"file_proceed\">ファイル処理完了</string>\n    <string name=\"file_size_sub\">最大ファイルサイズはAndroid OSと利用可能なメモリによって制限されており、これはデバイスに依存します。 \\n注意：メモリはストレージではありません。</string>\n    <string name=\"compatibility_sub\">他のファイル暗号化ソフトウェアやサービスとの互換性は保証されないことにご注意ください。キーの扱いや暗号の設定がわずかに異なると問題が発生する可能性があります</string>\n    <string name=\"image_size_warning\">指定した幅と高さで画像を保存しようとすると、メモリ不足のエラーが発生することがあります。 自己責任で行ってください。</string>\n    <string name=\"cache_size\">キャッシュサイズ</string>\n    <string name=\"auto_cache_clearing_sub\">有効にするとアプリ起動時にアプリキャッシュがクリアされます</string>\n    <string name=\"tools\">ツール</string>\n    <string name=\"group_options_by_type\">タイプ別にオプションをグループ化</string>\n    <string name=\"group_options_by_type_sub\">メイン画面上のオプションをカスタムリスト配置ではなく、タイプ別にグループ化します</string>\n    <string name=\"draw_on_image_sub\">画像を選択してその上に何かを描画します</string>\n    <string name=\"encrypt\">暗号化</string>\n    <string name=\"implementation\">実装</string>\n    <string name=\"found_s\">%1$sが見つかりました</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">オプショングループ化が有効な間は配置を変更できません</string>\n    <string name=\"edit_screenshot\">スクリーンショットを編集</string>\n    <string name=\"copy\">コピー</string>\n    <string name=\"warning_bytes\">%1$sモードでの保存は、可逆フォーマットであるため不安定な場合があります</string>\n    <string name=\"activate_files\">ファイルアプリを無効にしました。この機能を使用するには有効にしてください</string>\n    <string name=\"draw\">描画</string>\n    <string name=\"draw_sub\">スケッチブックのように画像に描画したり、背景自体に描画したりします</string>\n    <string name=\"paint_color\">ペイントの色</string>\n    <string name=\"paint_alpha\">ペイントの透明度</string>\n    <string name=\"draw_on_image\">画像に描画</string>\n    <string name=\"draw_on_background_sub\">背景色を選択してその上に描画します</string>\n    <string name=\"background_color\">背景色</string>\n    <string name=\"cipher\">暗号化</string>\n    <string name=\"cipher_sub\">様々な暗号化アルゴリズムを基にファイル（画像だけでなく）を暗号化/復号化します</string>\n    <string name=\"encryption\">暗号化</string>\n    <string name=\"key\">キー</string>\n    <string name=\"features_sub\">パスワードベースのファイル暗号化。処理されたファイルは選択したディレクトリに保存するか共有することができます。復号化されたファイルも直接開くことができます。</string>\n    <string name=\"create\">作成</string>\n    <string name=\"enhanced_pixelation\">拡張ピクセル化</string>\n    <string name=\"stroke_pixelation\">ストロークピクセル化</string>\n    <string name=\"diamond_pixelation\">ダイヤモンドピクセル化</string>\n    <string name=\"tg_chat\">Telegramチャット</string>\n    <string name=\"randomize_filename_sub\">有効にすると出力ファイル名が完全にランダムになります</string>\n    <string name=\"food_and_drink\">食べ物と飲み物</string>\n    <string name=\"email\">メール</string>\n    <string name=\"restore\">復元</string>\n    <string name=\"background_remover\">背景除去</string>\n    <string name=\"background_remover_sub\">描画または自動オプションを使用して画像から背景を削除します</string>\n    <string name=\"trim_image\">画像のトリミング</string>\n    <string name=\"backup_and_restore\">バックアップと復元</string>\n    <string name=\"image_crop_mask_sub\">指定した画像からマスクを作成するにはこのマスクタイプを使用します。アルファチャンネルが必要なことに注意してください</string>\n    <string name=\"randomize_filename\">ファイル名をランダム化</string>\n    <string name=\"delete_color_scheme_title\">スキームを削除</string>\n    <string name=\"text\">テキスト</string>\n    <string name=\"defaultt\">デフォルト</string>\n    <string name=\"font\">フォント</string>\n    <string name=\"presets_sub_bytes\">ここでの設定値は出力ファイルの容量の%を決定します。つまり5MBの画像で50を選択すると、2.5MBの画像として保存されます。</string>\n    <string name=\"erase_mode\">消去モード</string>\n    <string name=\"updates\">更新</string>\n    <string name=\"segmentation_mode_auto_osd\">自動方向とスクリプト検出</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">単一ブロック垂直テキスト</string>\n    <string name=\"glitch\">グリッチ</string>\n    <string name=\"amount\">量</string>\n    <string name=\"seed\">シード</string>\n    <string name=\"delete_mask_warn\">選択したフィルターマスクを削除しようとしています。この操作は元に戻せません</string>\n    <string name=\"no_such_directory\">\\\"%1$s\\\"ディレクトリが見つかりません。デフォルトに切り替えましたので、ファイルを再度保存してください</string>\n    <string name=\"clipboard\">クリップボード</string>\n    <string name=\"auto_pin\">自動ピン</string>\n    <string name=\"overwrite_file_requirements\">ファイルを上書きするには「エクスプローラー」画像ソースを使用する必要があります。画像を再選択してください。必要な画像ソースに変更しました</string>\n    <string name=\"overwrite_files\">ファイルを上書き</string>\n    <string name=\"empty\">空</string>\n    <string name=\"suffix\">接尾辞</string>\n    <string name=\"free\">自由</string>\n    <string name=\"tg_chat_sub\">アプリについて議論し、他のユーザーからフィードバックを得ることができます。ベータ版のアップデートや洞察もここで得られます。</string>\n    <string name=\"crop_mask\">切り抜きマスク</string>\n    <string name=\"aspect_ratio\">アスペクト比</string>\n    <string name=\"backup\">バックアップ</string>\n    <string name=\"backup_sub\">アプリの設定をファイルにバックアップします</string>\n    <string name=\"restore_sub\">以前に生成されたファイルからアプリの設定を復元します</string>\n    <string name=\"contact_me\">連絡先</string>\n    <string name=\"reset_settings_sub\">これにより設定がデフォルト値に戻ります。上記のバックアップファイルがなければ元に戻せないことに注意してください</string>\n    <string name=\"corrupted_file_or_not_a_backup\">破損したファイルまたはバックアップではありません</string>\n    <string name=\"settings_restored\">設定が正常に復元されました</string>\n    <string name=\"delete\">削除</string>\n    <string name=\"font_scale\">フォントスケール</string>\n    <string name=\"using_large_fonts_warn\">大きなフォントスケールを使用すると、UIの不具合や問題が発生する可能性があり、それらは修正されません。慎重に使用してください。</string>\n    <string name=\"alphabet_and_numbers\">あ い う え お か き く け こ さ し す せ そ た ち つ て と な に ぬ ね の は ひ ふ へ ほ ま み む め も や ゆ よ ら り る れ ろ わ を ん 0123456789 !?</string>\n    <string name=\"emotions\">感情</string>\n    <string name=\"objects\">物体</string>\n    <string name=\"symbols\">記号</string>\n    <string name=\"enable_emoji\">絵文字を有効化</string>\n    <string name=\"travels_and_places\">旅行と場所</string>\n    <string name=\"activities\">活動</string>\n    <string name=\"trim_image_sub\">画像周りの透明なスペースがトリミングされます</string>\n    <string name=\"auto_erase_background\">背景の自動消去</string>\n    <string name=\"restore_image\">画像を復元</string>\n    <string name=\"erase_background\">背景を消去</string>\n    <string name=\"restore_background\">背景を復元</string>\n    <string name=\"blur_radius\">ぼかし半径</string>\n    <string name=\"draw_mode\">描画モード</string>\n    <string name=\"something_went_wrong_emphasis\">おっと…何か問題が発生しました。以下のオプションを使用して私に連絡してください。解決策を見つけようとします</string>\n    <string name=\"resize_and_convert_sub\">指定された画像のサイズを変更したり、他の形式に変換したりします。単一の画像を選択する場合はEXIFメタデータもここで編集できます。</string>\n    <string name=\"image_exif_warning\">現在、%1$s形式ではAndroidでのEXIFメタデータの読み取りのみが可能です。保存されると出力画像にはメタデータがまったく含まれません。</string>\n    <string name=\"allow_betas_sub\">有効にすると、アップデートチェックにはベータ版のアプリバージョンも含まれます</string>\n    <string name=\"draw_arrows\">矢印を描画</string>\n    <string name=\"draw_arrows_sub\">有効にすると描画パスが指す矢印として表示されます</string>\n    <string name=\"brush_softness\">ブラシの柔らかさ</string>\n    <string name=\"donation\">寄付</string>\n    <string name=\"pick_at_least_two_images\">少なくとも2つの画像を選択してください</string>\n    <string name=\"image_orientation\">画像の向き</string>\n    <string name=\"horizontal\">水平</string>\n    <string name=\"vertical\">垂直</string>\n    <string name=\"scale_small_images_to_large\">小さな画像を大きくする</string>\n    <string name=\"scale_small_images_to_large_sub\">有効にすると、小さい画像はシーケンス内の最大の画像にスケーリングされます</string>\n    <string name=\"images_order\">画像の順序</string>\n    <string name=\"blur_edges_sub\">有効にすると、元の画像の下にぼかしたエッジを描画して、単色の代わりに周囲のスペースを埋めます</string>\n    <string name=\"enhanced_diamond_pixelation\">拡張ダイヤモンドピクセル化</string>\n    <string name=\"circle_pixelation\">円形ピクセル化</string>\n    <string name=\"target_color\">ターゲット色</string>\n    <string name=\"color_to_remove\">削除する色</string>\n    <string name=\"remove_color\">色を削除</string>\n    <string name=\"recode\">再コード化</string>\n    <string name=\"lock_draw_orientation_sub\">描画モードで有効にすると、画面が回転しなくなります</string>\n    <string name=\"check_for_updates\">アップデートを確認</string>\n    <string name=\"palette_style\">パレットスタイル</string>\n    <string name=\"tonal_spot\">トーナルスポット</string>\n    <string name=\"neutral\">ニュートラル</string>\n    <string name=\"vibrant\">ビブラント</string>\n    <string name=\"expressive\">エクスプレッシブ</string>\n    <string name=\"rainbow\">虹</string>\n    <string name=\"fruit_salad\">フルーツサラダ</string>\n    <string name=\"fidelity\">フィデリティ</string>\n    <string name=\"content\">コンテンツ</string>\n    <string name=\"tonal_spot_sub\">デフォルトのパレットスタイルで、4色すべてをカスタマイズできます。他のスタイルではキーカラーのみを設定できます</string>\n    <string name=\"neutral_sub\">モノクロよりもわずかに彩度の高いスタイル</string>\n    <string name=\"vibrant_sub\">派手なテーマ、プライマリパレットの彩度が最大で、他のパレットでも増加します</string>\n    <string name=\"playful_scheme\">プレイフルなテーマ - 元の色相がテーマに表示されません</string>\n    <string name=\"monochrome_sub\">モノクロのテーマ、色は純粋な黒/白/グレーです</string>\n    <string name=\"content_sub\">ソースカラーをScheme.primaryContainerに配置するスキーム</string>\n    <string name=\"fidelity_sub\">コンテンツスキームに非常に似たスキーム</string>\n    <string name=\"foss_update_checker_warning\">このアップデートチェッカーは、新しいアップデートがあるかどうかを確認するためにGitHubに接続します</string>\n    <string name=\"attention\">注意</string>\n    <string name=\"fading_edges\">フェードエッジ</string>\n    <string name=\"disabled\">無効</string>\n    <string name=\"both\">両方</string>\n    <string name=\"invert_colors_sub\">有効にするとテーマの色を反転した色に置き換えます</string>\n    <string name=\"search_option\">検索</string>\n    <string name=\"search_option_sub\">メインスクリーンで利用可能なすべてのツールを検索する機能を有効にします</string>\n    <string name=\"pdf_tools\">PDFツール</string>\n    <string name=\"pdf_to_images_sub\">PDFを指定した出力形式の画像に変換</string>\n    <string name=\"images_to_pdf_sub\">指定した画像を出力PDFファイルにパッケージ化</string>\n    <string name=\"add_mask\">マスクを追加</string>\n    <string name=\"mask_indexed\">マスク %d</string>\n    <string name=\"mask_preview\">マスクプレビュー</string>\n    <string name=\"mask_preview_sub\">描画されたフィルターマスクがレンダリングされ、おおよその結果が表示されます</string>\n    <string name=\"inverse_fill_type_sub\">有効にすると、デフォルトの動作ではなく、マスクされていないすべての領域がフィルターされます</string>\n    <string name=\"delete_mask\">マスクを削除</string>\n    <string name=\"full_filter_sub\">指定された画像または単一画像にフィルターチェーンを適用します</string>\n    <string name=\"simple_variants\">シンプルバリアント</string>\n    <string name=\"highlighter\">ハイライター</string>\n    <string name=\"pen\">ペン</string>\n    <string name=\"privacy_blur\">プライバシーぼかし</string>\n    <string name=\"highlighter_sub\">半透明で先鋭化されたハイライターパスを描画</string>\n    <string name=\"neon_sub\">描画に光る効果を追加</string>\n    <string name=\"pen_sub\">デフォルト、最もシンプル - 色だけ</string>\n    <string name=\"privacy_blur_sub\">隠したいものを保護するために描画されたパスの下の画像をぼかします</string>\n    <string name=\"pixelation_sub\">プライバシーぼかしに似ていますが、ぼかす代わりにピクセル化します</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">ボタン</string>\n    <string name=\"sliders_shadow_sub\">スライダーの背後に影を描画する</string>\n    <string name=\"switches_shadow_sub\">スイッチの背後に影を描画する</string>\n    <string name=\"fabs_shadow_sub\">フローティングアクションボタンの背後に影を描画する</string>\n    <string name=\"buttons_shadow_sub\">ボタンの背後に影を描画する</string>\n    <string name=\"app_bars_shadow\">アプリバー</string>\n    <string name=\"app_bars_shadow_sub\">アプリバーの背後に影を描画する</string>\n    <string name=\"line_arrow\">線矢印</string>\n    <string name=\"arrow\">矢印</string>\n    <string name=\"line\">線</string>\n    <string name=\"free_drawing_sub\">入力値としてパスを描画</string>\n    <string name=\"line_sub\">開始点から終了点までのパスを線として描画</string>\n    <string name=\"line_arrow_sub\">開始点から終了点まで線として指し示す矢印を描画</string>\n    <string name=\"arrow_sub\">指定されたパスから指し示す矢印を描画</string>\n    <string name=\"rect\">矩形</string>\n    <string name=\"rect_sub\">開始点から終了点まで矩形を描画</string>\n    <string name=\"stitch_mode\">結合モード</string>\n    <string name=\"rows_count\">行数</string>\n    <string name=\"columns_count\">列数</string>\n    <string name=\"auto_pin_sub\">有効にすると保存した画像を自動的にクリップボードに追加します</string>\n    <string name=\"vibration\">振動</string>\n    <string name=\"vibration_strength\">振動の強さ</string>\n    <string name=\"overwrite_files_sub\">元のファイルは選択したフォルダに保存する代わりに新しいものに置き換えられます。このオプションには画像ソースが「エクスプローラー」またはGetContentである必要があります</string>\n    <string name=\"bilinear_sub\">線形（または二次元ではバイリニア）補間は、画像のサイズ変更には一般的に適していますが、望ましくない詳細のぼかしを引き起こします</string>\n    <string name=\"bicubic_sub\">より優れたスケーリング方法には、ランチョスリサンプリングやミッチェル-ネトラバリフィルターがあります</string>\n    <string name=\"nearest_sub\">サイズを大きくする最も単純な方法の1つで、各ピクセルを同じ色のピクセル数に置き換えます</string>\n    <string name=\"basic_sub\">ほとんどすべてのアプリで使用されている最もシンプルなAndroidスケーリングモード</string>\n    <string name=\"catmull_sub\">滑らかな曲線を作成するためにコンピュータグラフィックスでよく使用される、制御点セットを滑らかに補間およびリサンプリングする方法</string>\n    <string name=\"hann_sub\">信号のエッジをテーパリングすることでスペクトルリークを最小限に抑え、周波数分析の精度を向上させるために信号処理でよく適用されるウィンドウ関数</string>\n    <string name=\"hermite_sub\">曲線セグメントのエンドポイントでの値と導関数を使用して滑らかで連続的な曲線を生成する数学的補間技術</string>\n    <string name=\"lanczos_sub\">ピクセル値に重み付けされたsinc関数を適用することで高品質の補間を維持するリサンプリング方法</string>\n    <string name=\"mitchell_sub\">スケーリングされた画像の鮮明さとアンチエイリアシングのバランスを取るために調整可能なパラメータを持つ畳み込みフィルターを使用するリサンプリング方法</string>\n    <string name=\"spline_sub\">区分的に定義された多項式関数を使用して、曲線または面を滑らかに補間および近似し、柔軟で連続的な形状表現を提供します</string>\n    <string name=\"only_clip_sub\">ストレージへの保存は行われず、クリップボードにのみ画像を配置しようとします</string>\n    <string name=\"restore_background_sub\">ブラシは消去する代わりに背景を復元します</string>\n    <string name=\"force_exif_widget_initial_value\">初期値を強制</string>\n    <string name=\"force_exif_widget_initial_value_sub\">EXIFウィジェットが最初にチェックされるよう強制します</string>\n    <string name=\"allow_multiple_languages\">複数言語を許可</string>\n    <string name=\"slide\">スライド</string>\n    <string name=\"side_by_side\">並べて表示</string>\n    <string name=\"toggle_tap\">タップで切り替え</string>\n    <string name=\"transparency\">透明度</string>\n    <string name=\"rate_app_sub\">このアプリは完全に無料です。もっと大きくしたい場合は、Githubでプロジェクトにスターをつけてください 😄</string>\n    <string name=\"segmentation_mode_osd_only\">方向とスクリプト検出のみ</string>\n    <string name=\"segmentation_mode_auto_only\">自動のみ</string>\n    <string name=\"segmentation_mode_auto\">自動</string>\n    <string name=\"segmentation_mode_single_column\">単一列</string>\n    <string name=\"segmentation_mode_single_block\">単一ブロック</string>\n    <string name=\"segmentation_mode_single_line\">単一行</string>\n    <string name=\"segmentation_mode_single_word\">単一単語</string>\n    <string name=\"segmentation_mode_circle_word\">円形の単語</string>\n    <string name=\"segmentation_mode_single_char\">単一文字</string>\n    <string name=\"segmentation_mode_sparse_text\">まばらなテキスト</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">まばらなテキストの方向とスクリプト検出</string>\n    <string name=\"segmentation_mode_raw_line\">生の行</string>\n    <string name=\"delete_language_sub\">言語「%1$s」のOCRトレーニングデータをすべての認識タイプで削除しますか、それとも選択したタイプ（%2$s）のみで削除しますか？</string>\n    <string name=\"all\">すべて</string>\n    <string name=\"gradient_maker\">グラデーション作成</string>\n    <string name=\"gradient_maker_sub\">カスタマイズされた色と外観タイプで指定された出力サイズのグラデーションを作成</string>\n    <string name=\"center_y\">中心Y</string>\n    <string name=\"tile_mode\">タイルモード</string>\n    <string name=\"tile_mode_repeated\">繰り返し</string>\n    <string name=\"tile_mode_mirror\">ミラー</string>\n    <string name=\"tile_mode_clamp\">クランプ</string>\n    <string name=\"tile_mode_decal\">デカール</string>\n    <string name=\"color_stops\">カラーストップ</string>\n    <string name=\"add_color\">色を追加</string>\n    <string name=\"properties\">プロパティ</string>\n    <string name=\"camera\">カメラ</string>\n    <string name=\"camera_sub\">写真を撮るためにカメラを使用します。この画像ソースからは1つの画像しか取得できないことに注意してください</string>\n    <string name=\"watermarking_sub\">カスタマイズ可能なテキスト/画像ウォーターマークで写真をカバー</string>\n    <string name=\"watermarking_image_sub\">この画像はウォーターマークのパターンとして使用されます</string>\n    <string name=\"repeat_count\">繰り返し回数</string>\n    <string name=\"frame_delay\">フレーム遅延</string>\n    <string name=\"millis\">ミリ秒</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"secure_mode_sub\">最近使用したアプリのアプリコンテンツを非表示にします。キャプチャや録画はできません。</string>\n    <string name=\"quantizier\">量子化器</string>\n    <string name=\"gray_scale\">グレースケール</string>\n    <string name=\"bayer_two_dithering\">ベイヤー2×2ディザリング</string>\n    <string name=\"bayer_four_dithering\">ベイヤー4×4ディザリング</string>\n    <string name=\"bayer_eight_dithering\">ベイヤー8×8ディザリング</string>\n    <string name=\"floyd_steinberg_dithering\">フロイドスタインバーグディザリング</string>\n    <string name=\"jarvis_judice_ninke_dithering\">ジャービス・ジュディス・ニンケディザリング</string>\n    <string name=\"sierra_lite_dithering\">シエラライトディザリング</string>\n    <string name=\"atkinson_dithering\">アトキンソンディザリング</string>\n    <string name=\"median_blur\">メディアンぼかし</string>\n    <string name=\"b_spline_sub\">曲線や表面を滑らかに補間および近似するために区分的に定義された双三次多項式関数を利用し、柔軟で連続的な形状表現を提供します</string>\n    <string name=\"native_stack_blur\">ネイティブスタックぼかし</string>\n    <string name=\"tilt_shift\">チルトシフト</string>\n    <string name=\"anaglyph\">アナグリフ</string>\n    <string name=\"noise\">ノイズ</string>\n    <string name=\"pixel_sort\">ピクセルソート</string>\n    <string name=\"shuffle\">シャッフル</string>\n    <string name=\"enhanced_glitch\">拡張グリッチ</string>\n    <string name=\"channel_shift_x\">チャンネルシフトX</string>\n    <string name=\"channel_shift_y\">チャンネルシフトY</string>\n    <string name=\"corruption_size\">破損サイズ</string>\n    <string name=\"corruption_shift_x\">破損シフトX</string>\n    <string name=\"corruption_shift_y\">破損シフトY</string>\n    <string name=\"tent_blur\">テントぼかし</string>\n    <string name=\"side_fade\">サイドフェード</string>\n    <string name=\"side\">側面</string>\n    <string name=\"top\">上部</string>\n    <string name=\"bottom\">下部</string>\n    <string name=\"strength\">強度</string>\n    <string name=\"fractal_glass\">フラクタルガラス</string>\n    <string name=\"aces_hill_tone_mapping\">ACESヒルトーンマッピング</string>\n    <string name=\"color_matrix_3x3\">カラーマトリックス3x3</string>\n    <string name=\"simple_effects\">シンプルエフェクト</string>\n    <string name=\"polaroid\">ポラロイド</string>\n    <string name=\"tritonomaly\">トリタノマリー</string>\n    <string name=\"protonomaly\">プロタノマリー</string>\n    <string name=\"vintage\">ヴィンテージ</string>\n    <string name=\"browni\">ブラウニ</string>\n    <string name=\"coda_chrome\">コダクローム</string>\n    <string name=\"night_vision\">ナイトビジョン</string>\n    <string name=\"warm\">暖色</string>\n    <string name=\"cool\">寒色</string>\n    <string name=\"tritanopia\">トリタノピア</string>\n    <string name=\"deutaronotopia\">デューテラノピア</string>\n    <string name=\"protanopia\">プロタノピア</string>\n    <string name=\"achromatomaly\">アクロマトマリー</string>\n    <string name=\"achromatopsia\">アクロマトプシア</string>\n    <string name=\"pink_dream\">ピンクドリーム</string>\n    <string name=\"golden_hour\">ゴールデンアワー</string>\n    <string name=\"hot_summer\">ホットサマー</string>\n    <string name=\"purple_mist\">パープルミスト</string>\n    <string name=\"sunrise\">日の出</string>\n    <string name=\"colorful_swirl\">カラフルスワール</string>\n    <string name=\"soft_spring_light\">ソフトスプリングライト</string>\n    <string name=\"autumn_tones\">秋のトーン</string>\n    <string name=\"lavender_dream\">ラベンダードリーム</string>\n    <string name=\"cyberpunk\">サイバーパンク</string>\n    <string name=\"lemonade_light\">レモネードライト</string>\n    <string name=\"spectral_fire\">スペクトラルファイア</string>\n    <string name=\"night_magic\">ナイトマジック</string>\n    <string name=\"fantasy_landscape\">ファンタジーランドスケープ</string>\n    <string name=\"color_explosion\">カラーエクスプロージョン</string>\n    <string name=\"electric_gradient\">エレクトリックグラデーション</string>\n    <string name=\"caramel_darkness\">キャラメルダークネス</string>\n    <string name=\"deep_purple\">ディープパープル</string>\n    <string name=\"shuffle_blur\">シャッフルぼかし</string>\n    <string name=\"no_favorite_filters\">お気に入りフィルターはまだ追加されていません</string>\n    <string name=\"icon_shape_sub\">カードの先頭アイコンの下に選択された形状のコンテナを追加します</string>\n    <string name=\"icon_shape\">アイコンの形状</string>\n    <string name=\"drago\">ドラゴ</string>\n    <string name=\"aldridge\">アルドリッジ</string>\n    <string name=\"cutoff\">カットオフ</string>\n    <string name=\"uchimura\">ウチムラ</string>\n    <string name=\"mobius\">メビウス</string>\n    <string name=\"transition\">トランジション</string>\n    <string name=\"peak\">ピーク</string>\n    <string name=\"color_anomaly\">色異常</string>\n    <string name=\"images_overwritten\">画像は元の場所で上書きされました</string>\n    <string name=\"cannot_change_image_format\">ファイル上書きオプションが有効な間は画像フォーマットを変更できません</string>\n    <string name=\"emoji_as_color_scheme\">絵文字をカラースキームとして使用</string>\n    <string name=\"emoji_as_color_scheme_sub\">手動で定義されたものの代わりに絵文字のプライマリカラーをアプリのカラースキームとして使用</string>\n    <string name=\"saved_to\">%1$sフォルダに%2$sという名前で保存されました</string>\n    <string name=\"saved_to_without_filename\">%1$sフォルダに保存されました</string>\n    <string name=\"delete_color_scheme_warn\">選択したカラースキームを削除しようとしています。この操作は元に戻せません</string>\n    <string name=\"nature_and_animals\">自然と動物</string>\n    <string name=\"keep_exif_sub\">元の画像のメタデータが保持されます</string>\n    <string name=\"pipette\">スポイト</string>\n    <string name=\"create_issue\">問題を作成</string>\n    <string name=\"resize_and_convert\">サイズ変更と変換</string>\n    <string name=\"saving_almost_complete\">保存がほぼ完了しました。今キャンセルすると再度保存する必要があります。</string>\n    <string name=\"allow_betas\">ベータ版を許可</string>\n    <string name=\"crop_description\">画像は入力されたサイズに中央でトリミングされます。画像が入力された寸法より小さい場合、キャンバスは指定された背景色で拡張されます。</string>\n    <string name=\"enhanced_circle_pixelation\">拡張円形ピクセル化</string>\n    <string name=\"replace_color\">色の置換</string>\n    <string name=\"tolerance\">許容値</string>\n    <string name=\"color_to_replace\">置換する色</string>\n    <string name=\"erode\">侵食</string>\n    <string name=\"anisotropic_diffusion\">異方性拡散</string>\n    <string name=\"diffusion\">拡散</string>\n    <string name=\"conduction\">伝導</string>\n    <string name=\"horizontal_wind_stagger\">水平風ずらし</string>\n    <string name=\"fast_bilaterial_blur\">高速バイラテラルぼかし</string>\n    <string name=\"poisson_blur\">ポアソンぼかし</string>\n    <string name=\"logarithmic_tone_mapping\">対数トーンマッピング</string>\n    <string name=\"crystallize\">結晶化</string>\n    <string name=\"stroke_color\">ストロークの色</string>\n    <string name=\"amplitude\">振幅</string>\n    <string name=\"marble\">マーブル</string>\n    <string name=\"turbulence\">乱流</string>\n    <string name=\"oil\">油彩</string>\n    <string name=\"water_effect\">水の効果</string>\n    <string name=\"just_size\">サイズ</string>\n    <string name=\"frequency_x\">周波数X</string>\n    <string name=\"frequency_y\">周波数Y</string>\n    <string name=\"perlin_distortion\">パーリン歪み</string>\n    <string name=\"amplitude_x\">振幅X</string>\n    <string name=\"amplitude_y\">振幅Y</string>\n    <string name=\"hable_filmic_tone_mapping\">ハーブルフィルムトーンマッピング</string>\n    <string name=\"heji_burgess_tone_mapping\">ヘイジルバージェストーンマッピング</string>\n    <string name=\"aces_filmic_tone_mapping\">ACESフィルムトーンマッピング</string>\n    <string name=\"current\">現在</string>\n    <string name=\"full_filter\">フルフィルター</string>\n    <string name=\"start_position\">開始</string>\n    <string name=\"center_position\">中央</string>\n    <string name=\"end_position\">終了</string>\n    <string name=\"pdf_tools_sub\">PDFファイルを操作：プレビュー、画像バッチへの変換、または指定した写真からの作成</string>\n    <string name=\"preview_pdf\">PDFプレビュー</string>\n    <string name=\"pdf_to_images\">PDFから画像へ</string>\n    <string name=\"images_to_pdf\">画像からPDFへ</string>\n    <string name=\"preview_pdf_sub\">シンプルなPDFプレビュー</string>\n    <string name=\"speed\">速度</string>\n    <string name=\"dehaze\">デヘイズ</string>\n    <string name=\"omega\">オメガ</string>\n    <string name=\"rate_app\">アプリを評価</string>\n    <string name=\"rate\">評価</string>\n    <string name=\"color_matrix_4x4\">カラーマトリックス4x4</string>\n    <string name=\"deutaromaly\">デューテラノマリー</string>\n    <string name=\"gradient_type_linear\">線形</string>\n    <string name=\"gradient_type_radial\">放射状</string>\n    <string name=\"gradient_type_sweep\">スイープ</string>\n    <string name=\"gradient_type\">グラデーションタイプ</string>\n    <string name=\"center_x\">中心X</string>\n    <string name=\"lasso\">投げ縄</string>\n    <string name=\"lasso_sub\">指定されたパスで閉じた塗りつぶしパスを描画</string>\n    <string name=\"draw_path_mode\">描画パスモード</string>\n    <string name=\"double_line_arrow\">二重線矢印</string>\n    <string name=\"free_drawing\">自由描画</string>\n    <string name=\"double_arrow\">二重矢印</string>\n    <string name=\"double_line_arrow_sub\">開始点から終了点まで線として二重の指し示す矢印を描画</string>\n    <string name=\"double_arrow_sub\">指定されたパスから二重の指し示す矢印を描画</string>\n    <string name=\"outlined_oval\">アウトライン楕円</string>\n    <string name=\"outlined_rect\">アウトライン矩形</string>\n    <string name=\"oval\">楕円</string>\n    <string name=\"oval_sub\">開始点から終了点まで楕円を描画</string>\n    <string name=\"outlined_oval_sub\">開始点から終了点までアウトラインのある楕円を描画</string>\n    <string name=\"outlined_rect_sub\">開始点から終了点までアウトラインのある矩形を描画</string>\n    <string name=\"dithering\">ディザリング</string>\n    <string name=\"bayer_three_dithering\">ベイヤー3×3ディザリング</string>\n    <string name=\"sierra_dithering\">シエラディザリング</string>\n    <string name=\"two_row_sierra_dithering\">2行シエラディザリング</string>\n    <string name=\"stucki_dithering\">スタッキディザリング</string>\n    <string name=\"burkes_dithering\">バークスディザリング</string>\n    <string name=\"false_floyd_steinberg_dithering\">疑似フロイドスタインバーグディザリング</string>\n    <string name=\"left_to_right_dithering\">左から右へのディザリング</string>\n    <string name=\"random_dithering\">ランダムディザリング</string>\n    <string name=\"simple_threshold_dithering\">シンプルしきい値ディザリング</string>\n    <string name=\"max_colors_count\">最大色数</string>\n    <string name=\"crashlytics_sub\">アプリがクラッシュレポートを自動的に収集できるようにします</string>\n    <string name=\"analytics\">分析</string>\n    <string name=\"analytics_sub\">匿名のアプリ使用統計情報の収集を許可する</string>\n    <string name=\"effort\">エフォート</string>\n    <string name=\"effort_sub\">%1$sの値は高速圧縮を意味し、比較的大きなファイルサイズになります。%2$sはより遅い圧縮を意味し、より小さなファイルになります。</string>\n    <string name=\"wait\">お待ちください</string>\n    <string name=\"mask_color\">マスクの色</string>\n    <string name=\"scale_mode\">スケールモード</string>\n    <string name=\"bilinear\">バイリニア</string>\n    <string name=\"lanczos\">ランチョス</string>\n    <string name=\"mitchell\">ミッチェル</string>\n    <string name=\"hann\">ハン</string>\n    <string name=\"hermite\">エルミート</string>\n    <string name=\"nearest\">ニアレスト</string>\n    <string name=\"spline\">スプライン</string>\n    <string name=\"basic\">ベーシック</string>\n    <string name=\"default_value\">デフォルト値</string>\n    <string name=\"presets_sub\" formatted=\"false\">プリセット125を選択した場合、画像は元のサイズの125%のサイズで保存されます。プリセット50を選択した場合、画像は元のサイズの50%で保存されます</string>\n    <string name=\"value_in_range\">範囲内の値 %1$s - %2$s</string>\n    <string name=\"sigma\">シグマ</string>\n    <string name=\"spatial_sigma\">空間シグマ</string>\n    <string name=\"catmull\">キャトムル</string>\n    <string name=\"bicubic\">バイキュービック</string>\n    <string name=\"only_clip\">クリップのみ</string>\n    <string name=\"image_stitching\">画像結合</string>\n    <string name=\"image_stitching_sub\">指定された画像を組み合わせて1つの大きな画像を作成します</string>\n    <string name=\"brightness_enforcement\">明るさの強制</string>\n    <string name=\"screen\">スクリーン</string>\n    <string name=\"gradient_maker_type_image\">グラデーションオーバーレイ</string>\n    <string name=\"gradient_maker_type_image_sub\">指定された画像の上に任意のグラデーションを構成</string>\n    <string name=\"transformations\">変形</string>\n    <string name=\"output_image_scale\">出力画像のスケール</string>\n    <string name=\"grain\">グレイン</string>\n    <string name=\"unsharp\">アンシャープ</string>\n    <string name=\"pastel\">パステル</string>\n    <string name=\"orange_haze\">オレンジヘイズ</string>\n    <string name=\"futuristic_gradient\">未来的グラデーション</string>\n    <string name=\"green_sun\">グリーンサン</string>\n    <string name=\"rainbow_world\">レインボーワールド</string>\n    <string name=\"space_portal\">スペースポータル</string>\n    <string name=\"red_swirl\">レッドスワール</string>\n    <string name=\"digital_code\">デジタルコード</string>\n    <string name=\"watermarking\">ウォーターマーク</string>\n    <string name=\"repeat_watermark\">ウォーターマークを繰り返す</string>\n    <string name=\"repeat_watermark_sub\">指定された位置に単一ではなく、画像全体にウォーターマークを繰り返します</string>\n    <string name=\"offset_x\">オフセットX</string>\n    <string name=\"offset_y\">オフセットY</string>\n    <string name=\"watermark_type\">ウォーターマークタイプ</string>\n    <string name=\"text_color\">テキストの色</string>\n    <string name=\"overlay_mode\">オーバーレイモード</string>\n    <string name=\"pixel_size\">ピクセルサイズ</string>\n    <string name=\"lock_draw_orientation\">描画方向をロック</string>\n    <string name=\"bokeh\">ボケ</string>\n    <string name=\"gif_tools\">GIFツール</string>\n    <string name=\"gif_tools_sub\">画像をGIF画像に変換したり、指定されたGIF画像からフレームを抽出したりします</string>\n    <string name=\"gif_type_to_image\">GIFから画像へ</string>\n    <string name=\"gif_type_to_image_sub\">GIFファイルを画像のバッチに変換</string>\n    <string name=\"gif_type_to_gif_sub\">画像のバッチをGIFファイルに変換</string>\n    <string name=\"gif_type_to_gif\">画像からGIFへ</string>\n    <string name=\"select_gif_image_to_start\">開始するにはGIF画像を選択</string>\n    <string name=\"use_size_of_first_frame\">最初のフレームのサイズを使用</string>\n    <string name=\"use_size_of_first_frame_sub\">指定されたサイズを最初のフレームの寸法に置き換えます</string>\n    <string name=\"use_lasso\">投げ縄を使用</string>\n    <string name=\"use_lasso_sub\">描画モードのように投げ縄を使用して消去を実行します</string>\n    <string name=\"original_image_preview_alpha\">元画像プレビューの透明度</string>\n    <string name=\"mask_filter\">マスクフィルター</string>\n    <string name=\"mask_filter_sub\">指定されたマスク領域にフィルターチェーンを適用します。各マスク領域は独自のフィルターセットを決定できます</string>\n    <string name=\"masks\">マスク</string>\n    <string name=\"random_emojis_sub\">選択した絵文字を使用する代わりに、アプリバーの絵文字がランダムに連続して変更されます</string>\n    <string name=\"random_emojis\">ランダム絵文字</string>\n    <string name=\"random_emojis_error\">絵文字が無効化されている間はランダム絵文字選択を使用できません</string>\n    <string name=\"emoji_selection_error\">ランダム絵文字選択が有効になっている間は絵文字を選択できません</string>\n    <string name=\"old_tv\">古いテレビ</string>\n    <string name=\"recognize_text\">OCR（テキスト認識）</string>\n    <string name=\"recognize_text_sub\">指定された画像からテキストを認識、120以上の言語がサポートされています</string>\n    <string name=\"picture_has_no_text\">画像にはテキストがないか、アプリが見つけられませんでした</string>\n    <string name=\"accuracy\">精度：%1$s</string>\n    <string name=\"recognition_type\">認識タイプ</string>\n    <string name=\"fast\">高速</string>\n    <string name=\"standard\">標準</string>\n    <string name=\"best\">最高</string>\n    <string name=\"no_data\">データなし</string>\n    <string name=\"download_description\">Tesseract OCRが正常に機能するには、追加のトレーニングデータ（%1$s）をデバイスにダウンロードする必要があります。\\n%2$sデータをダウンロードしますか？</string>\n    <string name=\"download\">ダウンロード</string>\n    <string name=\"no_connection\">接続がありません。確認してトレーニングモデルをダウンロードするために再試行してください</string>\n    <string name=\"downloaded_languages\">ダウンロード済み言語</string>\n    <string name=\"available_languages\">利用可能な言語</string>\n    <string name=\"segmentation_mode\">セグメンテーションモード</string>\n    <string name=\"horizontal_grid\">水平グリッド</string>\n    <string name=\"vertical_grid\">垂直グリッド</string>\n    <string name=\"use_pixel_switch\">ピクセルスイッチを使用</string>\n    <string name=\"use_pixel_switch_sub\">Pixelのようなスイッチを使用</string>\n    <string name=\"saved_to_original\">元の場所に%1$s名で上書きされました</string>\n    <string name=\"magnifier\">拡大鏡</string>\n    <string name=\"magnifier_sub\">アクセシビリティ向上のため、描画モードで指先の上に拡大鏡を有効にします</string>\n    <string name=\"favorite\">お気に入り</string>\n    <string name=\"b_spline\">Bスプライン</string>\n    <string name=\"regular\">通常</string>\n    <string name=\"blur_edges\">エッジぼかし</string>\n    <string name=\"pixelation\">ピクセル化</string>\n    <string name=\"inverse_fill_type\">反転塗りつぶしタイプ</string>\n    <string name=\"confetti\">紙吹雪</string>\n    <string name=\"confetti_sub\">保存、共有、その他の主要アクションで紙吹雪が表示されます</string>\n    <string name=\"secure_mode\">セキュアモード</string>\n    <string name=\"neon\">ネオン</string>\n    <string name=\"auto_rotate_limits\">自動回転</string>\n    <string name=\"auto_rotate_limits_sub\">リミットボックスが画像の向きに適応することを許可します</string>\n    <string name=\"containers_shadow\">コンテナ</string>\n    <string name=\"containers_shadow_sub\">コンテナの背後に影を描画する</string>\n    <string name=\"sliders_shadow\">スライダー</string>\n    <string name=\"switches_shadow\">スイッチ</string>\n    <string name=\"invert_colors\">色を反転</string>\n    <string name=\"exit\">終了</string>\n    <string name=\"preview_closing\">今プレビューを終了すると、画像を再度追加する必要があります</string>\n    <string name=\"image_format\">画像フォーマット</string>\n    <string name=\"material_you_sub\">画像からMaterial Youパレットを作成</string>\n    <string name=\"dark_colors\">ダークカラー</string>\n    <string name=\"dark_colors_sub\">ライトバリアントの代わりにナイトモードのカラースキームを使用</string>\n    <string name=\"copy_as_compose_code\">Jetpack Composeコードとしてコピー</string>\n    <string name=\"ring_blur\">リングぼかし</string>\n    <string name=\"cross_blur\">クロスぼかし</string>\n    <string name=\"circle_blur\">円形ぼかし</string>\n    <string name=\"star_blur\">星型ぼかし</string>\n    <string name=\"linear_tilt_shift\">直線的な傾斜移動</string>\n    <string name=\"tags_to_remove\">削除するタグ</string>\n    <string name=\"apng_tools\">APNGツール</string>\n    <string name=\"apng_tools_sub\">画像をAPNG画像に変換したり、指定されたAPNG画像からフレームを抽出したりします</string>\n    <string name=\"apng_type_to_image\">APNGから画像へ</string>\n    <string name=\"motion_blur\">モーションぼかし</string>\n    <string name=\"apng_type_to_image_sub\">APNGファイルを画像のバッチに変換</string>\n    <string name=\"apng_type_to_apng_sub\">画像のバッチをAPNGファイルに変換</string>\n    <string name=\"apng_type_to_apng\">画像からAPNGへ</string>\n    <string name=\"select_apng_image_to_start\">開始するにはAPNG画像を選択</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">指定されたファイルや画像からZipファイルを作成</string>\n    <string name=\"drag_handle_width\">ドラッグハンドル幅</string>\n    <string name=\"confetti_type\">紙吹雪のタイプ</string>\n    <string name=\"festive\">お祝い</string>\n    <string name=\"explode\">爆発</string>\n    <string name=\"rain\">雨</string>\n    <string name=\"corners\">コーナー</string>\n    <string name=\"jxl_tools\">JXLツール</string>\n    <string name=\"jxl_tools_sub\">品質損失なしでJXL～JPEG変換を実行、またはGIF/APNGをJXLアニメーションに変換</string>\n    <string name=\"jxl_type_to_jpeg\">JXLからJPEGへ</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXLからJPEGへの可逆変換を実行</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEGからJXLへの可逆変換を実行</string>\n    <string name=\"jpeg_type_to_jxl\">JPEGからJXLへ</string>\n    <string name=\"select_jxl_image_to_start\">開始するにはJXL画像を選択</string>\n    <string name=\"fast_gaussian_blur_2d\">高速ガウスぼかし2D</string>\n    <string name=\"fast_gaussian_blur_3d\">高速ガウスぼかし3D</string>\n    <string name=\"fast_gaussian_blur_4d\">高速ガウスぼかし4D</string>\n    <string name=\"auto_paste\">自動貼り付け</string>\n    <string name=\"gif_type_to_jxl\">GIFからJXLへ</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF画像をJXLアニメーション画像に変換</string>\n    <string name=\"apng_type_to_jxl\">APNGからJXLへ</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG画像をJXLアニメーション画像に変換</string>\n    <string name=\"jxl_type_to_images\">JXLから画像へ</string>\n    <string name=\"jxl_type_to_images_sub\">JXLアニメーションを画像のバッチに変換</string>\n    <string name=\"jxl_type_to_jxl\">画像からJXLへ</string>\n    <string name=\"jxl_type_to_jxl_sub\">画像のバッチをJXLアニメーションに変換</string>\n    <string name=\"path_omit\">パス省略</string>\n    <string name=\"downscale_image_sub\">画像は処理前に低い寸法にダウンスケールされます。これによりツールがより速く安全に動作するようになります</string>\n    <string name=\"cupertino_switch_sub\">クパチーノデザインシステムに基づいたiOSライクなスイッチを使用します</string>\n    <string name=\"lanczos_bessel\">ランチョスベッセル</string>\n    <string name=\"lanczos_bessel_sub\">ピクセル値にベッセル（jinc）関数を適用することで高品質の補間を維持するリサンプリング方法</string>\n    <string name=\"generate_previews\">プレビューを生成</string>\n    <string name=\"generate_previews_sub\">プレビュー生成を有効にします。これは一部のデバイスでのクラッシュを回避するのに役立ちますが、単一編集オプション内の一部の編集機能も無効になります</string>\n    <string name=\"lossy_compression\">非可逆圧縮</string>\n    <string name=\"lossy_compression_sub\">可逆圧縮の代わりに非可逆圧縮を使用してファイルサイズを削減</string>\n    <string name=\"speed_sub\">結果画像のデコード速度を制御します。これにより結果画像の開く速度を速くできます。%1$sの値は最も遅いデコードを意味し、%2$sは最速です。この設定はファイルサイズを増加させる可能性があります</string>\n    <string name=\"sorting\">並び替え</string>\n    <string name=\"sort_by_date\">日付</string>\n    <string name=\"sort_by_date_reversed\">日付（逆順）</string>\n    <string name=\"svg_warning\">このツールをダウンスケールなしで大きな画像のトレースに使用することはお勧めできません。クラッシュを引き起こし処理時間を増加させる可能性があります</string>\n    <string name=\"sort_by_name\">名前</string>\n    <string name=\"sort_by_name_reversed\">名前（逆順）</string>\n    <string name=\"header_today\">今日</string>\n    <string name=\"embedded_picker\">埋め込みピッカー</string>\n    <string name=\"images_to_svg_sub\">指定された画像をSVG画像にトレース</string>\n    <string name=\"channels_configuration\">チャンネル構成</string>\n    <string name=\"header_yesterday\">昨日</string>\n    <string name=\"auto_paste_sub\">アプリがクリップボードデータを自動で貼り付けることを許可し、メイン画面に表示して処理できるようにします</string>\n    <string name=\"harmonization_color\">調和色</string>\n    <string name=\"harmonization_level\">調和レベル</string>\n    <string name=\"behavior\">動作</string>\n    <string name=\"skip_file_picking\">ファイル選択をスキップ</string>\n    <string name=\"skip_file_picking_sub\">選択した画面でこれが可能な場合、ファイルピッカーが直ちに表示されます</string>\n    <string name=\"compression_type\">圧縮タイプ</string>\n    <string name=\"images_to_svg\">画像からSVGへ</string>\n    <string name=\"use_sampled_palette\">サンプリングされたパレットを使用</string>\n    <string name=\"use_sampled_palette_sub\">このオプションが有効になっている場合、量子化パレットはサンプリングされます</string>\n    <string name=\"downscale_image\">画像をダウンスケール</string>\n    <string name=\"min_color_ratio\">最小色比率</string>\n    <string name=\"lines_threshold\">線のしきい値</string>\n    <string name=\"quadratic_threshold\">二次しきい値</string>\n    <string name=\"coordinates_rounding_tolerance\">座標丸め許容値</string>\n    <string name=\"path_scale\">パススケール</string>\n    <string name=\"reset_properties\">プロパティをリセット</string>\n    <string name=\"try_again\">再試行</string>\n    <string name=\"show_settings_in_landscape\">横向きで設定を表示</string>\n    <string name=\"show_settings_in_landscape_sub\">これが無効になっている場合、横向きモードでは常時表示オプションではなく、トップアプリバーのボタンで設定が開かれます</string>\n    <string name=\"fullscreen_settings\">全画面設定</string>\n    <string name=\"fullscreen_settings_sub\">有効にすると、設定ページは常にスライド可能なドロワーシートではなく全画面で開かれます</string>\n    <string name=\"pick_multiple_media\">複数メディアの選択</string>\n    <string name=\"pick_single_media\">単一メディアの選択</string>\n    <string name=\"pick\">選択</string>\n    <string name=\"embedded_picker_sub\">システム定義のものの代わりにImage Toolbox独自の画像ピッカーを使用します</string>\n    <string name=\"no_permissions\">権限なし</string>\n    <string name=\"request\">リクエスト</string>\n    <string name=\"tag_gps_dest_latitude\">GPS目的地緯度</string>\n    <string name=\"font_size\">フォントサイズ</string>\n    <string name=\"watermark_size\">ウォーターマークサイズ</string>\n    <string name=\"tag_rows_per_strip\">ストリップあたりの行数</string>\n    <string name=\"tag_cfa_pattern\">CFAパターン</string>\n    <string name=\"tag_y_resolution\">Y解像度</string>\n    <string name=\"compose\">コンポーズ</string>\n    <string name=\"tag_reference_black_white\">参照黒白</string>\n    <string name=\"reset_properties_sub\">すべてのプロパティがデフォルト値に設定されます。この操作は元に戻せないことに注意してください</string>\n    <string name=\"tag_lens_serial_number\">レンズシリアル番号</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO感度緯度zzz</string>\n    <string name=\"tag_gamma\">ガンマ</string>\n    <string name=\"lstm_network\">LSTMネットワーク</string>\n    <string name=\"tag_samples_per_pixel\">ピクセルあたりのサンプル数</string>\n    <string name=\"tag_primary_chromaticities\">原色色度</string>\n    <string name=\"tag_exposure_program\">露出プログラム</string>\n    <string name=\"tag_gps_dest_distance\">GPS目的地距離</string>\n    <string name=\"convert\">変換</string>\n    <string name=\"tag_color_space\">色空間</string>\n    <string name=\"tag_flashpix_version\">Flashpixバージョン</string>\n    <string name=\"tag_pixel_x_dimension\">ピクセルX寸法</string>\n    <string name=\"tag_pixel_y_dimension\">ピクセルY寸法</string>\n    <string name=\"tag_compressed_bits_per_pixel\">圧縮ピクセルあたりビット数</string>\n    <string name=\"tag_maker_note\">メーカーノート</string>\n    <string name=\"tag_user_comment\">ユーザーコメント</string>\n    <string name=\"tag_related_sound_file\">関連サウンドファイル</string>\n    <string name=\"tag_subsec_time\">サブ秒時間</string>\n    <string name=\"tag_subsec_time_original\">元のサブ秒時間</string>\n    <string name=\"tag_subsec_time_digitized\">デジタイズされたサブ秒時間</string>\n    <string name=\"tag_exposure_time\">露出時間</string>\n    <string name=\"tag_f_number\">F値</string>\n    <string name=\"tag_spectral_sensitivity\">分光感度</string>\n    <string name=\"tag_photographic_sensitivity\">写真感度</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">感度タイプ</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO感度緯度yyy</string>\n    <string name=\"tag_brightness_value\">明るさ値</string>\n    <string name=\"tag_exposure_bias_value\">露出補正値</string>\n    <string name=\"tag_custom_rendered\">カスタムレンダリング</string>\n    <string name=\"tag_exposure_mode\">露出モード</string>\n    <string name=\"tag_white_balance\">ホワイトバランス</string>\n    <string name=\"tag_focal_length_in_35mm_film\">35mmフィルムでの焦点距離</string>\n    <string name=\"tag_scene_capture_type\">シーンキャプチャタイプ</string>\n    <string name=\"tag_gain_control\">ゲイン制御</string>\n    <string name=\"tag_saturation\">彩度</string>\n    <string name=\"tag_sharpness\">シャープネス</string>\n    <string name=\"tag_image_unique_id\">画像固有ID</string>\n    <string name=\"tag_camera_owner_name\">カメラ所有者名</string>\n    <string name=\"tag_lens_specification\">レンズ仕様</string>\n    <string name=\"tag_gps_speed\">GPS速度</string>\n    <string name=\"tag_gps_track\">GPSトラック</string>\n    <string name=\"tag_gps_img_direction\">GPS画像方向</string>\n    <string name=\"tag_gps_processing_method\">GPS処理方法</string>\n    <string name=\"tag_gps_area_information\">GPS地域情報</string>\n    <string name=\"tag_gps_datestamp\">GPS日付</string>\n    <string name=\"tag_gps_differential\">GPS差動</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS水平位置誤差</string>\n    <string name=\"tag_dng_version\">DNGバージョン</string>\n    <string name=\"tag_default_crop_size\">デフォルト切り抜きサイズ</string>\n    <string name=\"tag_orf_preview_image_length\">プレビュー画像長</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">センサー下端境界</string>\n    <string name=\"tag_rw2_sensor_right_border\">センサー右端境界</string>\n    <string name=\"dash_size\">ダッシュサイズ</string>\n    <string name=\"draw_image_sub\">この画像は描画パスの反復要素として使用されます</string>\n    <string name=\"pixel_switch\">ピクセル</string>\n    <string name=\"fluent_switch\">フルーエント</string>\n    <string name=\"fluent_switch_sub\">「フルーエント」デザインシステムに基づいたWindows 11スタイルのスイッチを使用します</string>\n    <string name=\"cupertino_switch\">クパチーノ</string>\n    <string name=\"switch_type\">スイッチタイプ</string>\n    <string name=\"compose_switch_sub\">Jetpack Compose マテリアル You スイッチを使用します。ビューベースよりも美しくありません</string>\n    <string name=\"material_you_switch_sub\">ビューベースのマテリアル You スイッチを使用します。これは他のものよりも見栄えが良く、素敵なアニメーション効果があります</string>\n    <string name=\"max\">最大</string>\n    <string name=\"resize_anchor\">リサイズアンカー</string>\n    <string name=\"detailed\">詳細</string>\n    <string name=\"default_line_width\">デフォルトの線幅</string>\n    <string name=\"engine_mode\">エンジンモード</string>\n    <string name=\"legacy\">レガシー</string>\n    <string name=\"legacy_and_lstm\">レガシーとLSTM</string>\n    <string name=\"convert_sub\">画像バッチを指定された形式に変換</string>\n    <string name=\"add_new_folder\">新しいフォルダを追加</string>\n    <string name=\"tag_bits_per_sample\">サンプルあたりのビット数</string>\n    <string name=\"tag_compression\">圧縮</string>\n    <string name=\"tag_photometric_interpretation\">測光解釈</string>\n    <string name=\"tag_planar_configuration\">平面構成</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">YCbCrサブサンプリング</string>\n    <string name=\"tag_y_cb_cr_positioning\">YCbCr位置決め</string>\n    <string name=\"tag_x_resolution\">X解像度</string>\n    <string name=\"tag_resolution_unit\">解像度単位</string>\n    <string name=\"tag_strip_offsets\">ストリップオフセット</string>\n    <string name=\"tag_strip_byte_counts\">ストリップバイト数</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG交換形式</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG交換形式の長さ</string>\n    <string name=\"tag_transfer_function\">転送関数</string>\n    <string name=\"tag_white_point\">ホワイトポイント</string>\n    <string name=\"tag_y_cb_cr_coefficients\">YCbCr係数</string>\n    <string name=\"tag_datetime\">日時</string>\n    <string name=\"tag_image_description\">画像説明</string>\n    <string name=\"tag_make\">メーカー</string>\n    <string name=\"tag_model\">モデル</string>\n    <string name=\"tag_software\">ソフトウェア</string>\n    <string name=\"tag_artist\">アーティスト</string>\n    <string name=\"tag_copyright\">著作権</string>\n    <string name=\"tag_exif_version\">Exifバージョン</string>\n    <string name=\"tag_datetime_original\">元の日時</string>\n    <string name=\"tag_datetime_digitized\">デジタイズされた日時</string>\n    <string name=\"tag_offset_time\">オフセット時間</string>\n    <string name=\"tag_offset_time_original\">元のオフセット時間</string>\n    <string name=\"tag_offset_time_digitized\">デジタイズされたオフセット時間</string>\n    <string name=\"tag_standard_output_sensitivity\">標準出力感度</string>\n    <string name=\"draw_text_sub\">指定されたフォントと色でパスにテキストを描画</string>\n    <string name=\"tag_recommended_exposure_index\">推奨露出指数</string>\n    <string name=\"tag_iso_speed\">ISO感度</string>\n    <string name=\"tag_sensing_method\">センシング方法</string>\n    <string name=\"tag_lens_make\">レンズメーカー</string>\n    <string name=\"tag_gps_version_id\">GPSバージョンID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS緯度参照</string>\n    <string name=\"tag_gps_timestamp\">GPSタイムスタンプ</string>\n    <string name=\"tag_gps_status\">GPSステータス</string>\n    <string name=\"tag_gps_measure_mode\">GPS測定モード</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS速度参照</string>\n    <string name=\"tag_rw2_sensor_top_border\">センサー上端境界</string>\n    <string name=\"kaiser\">カイザー</string>\n    <string name=\"hamming_sub\">信号のエッジをテーパリングすることでスペクトルリークを低減する窓関数で、信号処理に有用です</string>\n    <string name=\"gaussian_sub\">ガウス関数を適用する補間方法で、画像のスムージングやノイズ低減に有用です</string>\n    <string name=\"lanczos3_jinc_sub\">jinc関数を使用するランチョス3フィルターの変種で、最小限のアーティファクトで高品質な補間を提供します</string>\n    <string name=\"add_image\">画像を追加</string>\n    <string name=\"clahe_hsv\">CLAHE HSV</string>\n    <string name=\"fit_to_bounds\">境界に合わせる</string>\n    <string name=\"simple_sketch\">シンプルスケッチ</string>\n    <string name=\"soft_glow\">ソフトグロー</string>\n    <string name=\"color_poster\">カラーポスター</string>\n    <string name=\"harmony_square\">正方形</string>\n    <string name=\"calculate\">計算</string>\n    <string name=\"text_hash\">テキストハッシュ</string>\n    <string name=\"checksum\">チェックサム</string>\n    <string name=\"enter_text_to_checksum\">選択したアルゴリズムに基づいてチェックサムを計算するテキストを入力</string>\n    <string name=\"source_checksum\">ソースチェックサム</string>\n    <string name=\"checksum_to_compare\">比較するチェックサム</string>\n    <string name=\"match\">一致！</string>\n    <string name=\"difference\">相違</string>\n    <string name=\"match_sub\">チェックサムが等しく、安全かもしれません</string>\n    <string name=\"difference_sub\">チェックサムが等しくありません。ファイルは安全でない可能性があります！</string>\n    <string name=\"edge_mode\">エッジモード</string>\n    <string name=\"linear_box_blur\">線形ボックスぼかし</string>\n    <string name=\"ocr_write_to_metadata\">メタデータに書き込む</string>\n    <string name=\"color_blind_scheme\">色覚異常スキーム</string>\n    <string name=\"protanopia_sub\">赤色の色相を知覚できない</string>\n    <string name=\"lanczos_6_jinc\">ランチョス6 Jinc</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS目的地緯度参照</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS目的地経度参照</string>\n    <string name=\"batch_compare\">バッチ比較</string>\n    <string name=\"pick_files_to_checksum\">選択したアルゴリズムに基づいてチェックサムを計算するファイル/ファイルを選択</string>\n    <string name=\"document_scanner_sub\">ドキュメントをスキャンしてPDFや個別の画像を作成します</string>\n    <string name=\"bartlett_hann\">バートレット・ハン</string>\n    <string name=\"box\">ボックス</string>\n    <string name=\"bohman\">ボーマン</string>\n    <string name=\"mesh_gradients\">メッシュグラデーション</string>\n    <string name=\"mesh_gradients_sub\">カスタム数のノットと解像度でメッシュグラデーションを作成</string>\n    <string name=\"clip\">クリップ</string>\n    <string name=\"error_while_saving\">保存試行中にエラーが発生しました。出力フォルダを変更してみてください</string>\n    <string name=\"filename_is_not_set\">ファイル名が設定されていません</string>\n    <string name=\"low_poly\">ローポリ</string>\n    <string name=\"sand_painting\">サンドペインティング</string>\n    <string name=\"polygon_sub\">開始点から終了点まで多角形を描画します</string>\n    <string name=\"free_software_partner\">フリーソフトウェア（パートナー）</string>\n    <string name=\"algorithms\">アルゴリズム</string>\n    <string name=\"polka_dot\">水玉模様</string>\n    <string name=\"tints\">ティント</string>\n    <string name=\"bartlett_hann_sub\">バートレット窓とハン窓を組み合わせたハイブリッド窓関数で、信号処理でスペクトルリークを低減するために使用されます</string>\n    <string name=\"crop_to_content\">コンテンツに合わせて切り抜き</string>\n    <string name=\"one_time_save_location_sub\">ほとんどのオプションで保存ボタンを長押しすることで使用できる一度だけの保存場所を表示および編集します</string>\n    <string name=\"ewa_lanczos_soft_sub\">よりスムーズな画像リサンプリングのためのランチョスソフトフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"spline16_sub\">16タップフィルターを使用して滑らかな結果を提供するスプライン基準の補間方法</string>\n    <string name=\"draw_mode_image_sub\">指定されたパスに沿って選択した画像を描画します</string>\n    <string name=\"save_as_qr_code_image\">QRコード画像として保存</string>\n    <string name=\"collage_maker\">コラージュメーカー</string>\n    <string name=\"center_left\">中央左</string>\n    <string name=\"base_64_tips\">Base64文字列をコピーまたは保存するには画像をロードしてください。文字列自体がある場合は、上に貼り付けて画像を取得できます</string>\n    <string name=\"outlined_triangle\">アウトライン三角形</string>\n    <string name=\"custom_options\">カスタムオプション</string>\n    <string name=\"color_info\">色情報</string>\n    <string name=\"tag_metering_mode\">測光モード</string>\n    <string name=\"webp_type_to_image_sub\">WEBPファイルを画像のバッチに変換</string>\n    <string name=\"harmony_triadic\">三色</string>\n    <string name=\"golden_forest\">ゴールデンフォレスト</string>\n    <string name=\"dot_dashed_sub\">指定されたパスに沿って点線と破線を描画</string>\n    <string name=\"harmony_analogous\">類似色</string>\n    <string name=\"ewa_robidoux_sub\">高品質リサンプリングのためのロビドゥーフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"fancy_sub\">アニメーション付きのカスタムファンシースタイルスライダー。これがこのアプリのデフォルトです</string>\n    <string name=\"histogram_sub\">調整に役立つRGBまたは明るさの画像ヒストグラム</string>\n    <string name=\"create_template\">テンプレート作成</string>\n    <string name=\"third_color\">第三色</string>\n    <string name=\"bspline\">Bスプライン</string>\n    <string name=\"lagrange_3_sub\">3次のラグランジュ補間フィルターで、画像スケーリングにより高い精度とより滑らかな結果を提供します</string>\n    <string name=\"repeat_text\">テキストを繰り返す</string>\n    <string name=\"mask\">マスク</string>\n    <string name=\"crf_sub\">%1$sの値は遅い圧縮を意味し、比較的小さなファイルサイズになります。%2$sはより速い圧縮を意味し、大きなファイルになります。</string>\n    <string name=\"free_corners_sub\">多角形で画像を切り抜き、パースペクティブも修正します</string>\n    <string name=\"top_right\">右上</string>\n    <string name=\"qr_code\">QRコード</string>\n    <string name=\"ewa_robidoux\">ロビドゥーEWA</string>\n    <string name=\"amatorka\">アマトルカ</string>\n    <string name=\"image_splitting\">画像分割</string>\n    <string name=\"image_stacking\">画像スタッキング</string>\n    <string name=\"delete_template_warn\">選択したテンプレートフィルターを削除しようとしています。この操作は元に戻せません</string>\n    <string name=\"pick_files\">ファイルを選択</string>\n    <string name=\"pick_directory\">ディレクトリを選択</string>\n    <string name=\"save_as_file\">ファイルとして保存</string>\n    <string name=\"selected_color\">選択した色</string>\n    <string name=\"ci_channel_sub\">アプリの新バージョンについて通知を受け、お知らせを読む</string>\n    <string name=\"drop_blues\">ドロップブルース</string>\n    <string name=\"markup_layers\">マークアップレイヤー</string>\n    <string name=\"tones\">トーン</string>\n    <string name=\"auto\">自動</string>\n    <string name=\"spot_heal\">スポット修復</string>\n    <string name=\"tag_file_source\">ファイルソース</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"hanning\">ハニング</string>\n    <string name=\"checksum_as_filename\">チェックサムをファイル名として使用</string>\n    <string name=\"hide_nav_bar\">ナビゲーションバーを非表示</string>\n    <string name=\"settings_group_visibility_hidden\">設定グループ「%1$s」はデフォルトで折りたたまれます</string>\n    <string name=\"edit_exif_screen\">EXIF編集</string>\n    <string name=\"edit_exif_screen_sub\">単一画像のメタデータを再圧縮なしで変更</string>\n    <string name=\"change_sticker\">ステッカーを変更</string>\n    <string name=\"area\">領域</string>\n    <string name=\"outlined_polygon\">アウトライン多角形</string>\n    <string name=\"tag_focal_plane_y_resolution\">焦点面Y解像度</string>\n    <string name=\"scan_barcode\">バーコードをスキャン</string>\n    <string name=\"height_ratio\">高さ比</string>\n    <string name=\"barcode_type\">バーコードタイプ</string>\n    <string name=\"enforce_bw\">白黒を強制</string>\n    <string name=\"enforce_bw_sub\">バーコード画像はアプリのテーマで色付けされず、完全に白黒になります</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"tag_shutter_speed_value\">シャッタースピード値</string>\n    <string name=\"tag_aperture_value\">絞り値</string>\n    <string name=\"tag_max_aperture_value\">最大絞り値</string>\n    <string name=\"tag_subject_distance\">被写体距離</string>\n    <string name=\"tag_flash\">フラッシュ</string>\n    <string name=\"tag_subject_area\">被写体エリア</string>\n    <string name=\"tag_focal_length\">焦点距離</string>\n    <string name=\"tag_exposure_index\">露出指数</string>\n    <string name=\"tag_subject_location\">被写体位置</string>\n    <string name=\"tag_digital_zoom_ratio\">デジタルズーム比</string>\n    <string name=\"tag_contrast\">コントラスト</string>\n    <string name=\"tag_device_setting_description\">デバイス設定の説明</string>\n    <string name=\"tag_subject_distance_range\">被写体距離範囲</string>\n    <string name=\"tag_body_serial_number\">本体シリアル番号</string>\n    <string name=\"tag_lens_model\">レンズモデル</string>\n    <string name=\"tag_gps_latitude\">GPS緯度</string>\n    <string name=\"tag_gps_longitude_ref\">GPS経度参照</string>\n    <string name=\"tag_gps_longitude\">GPS経度</string>\n    <string name=\"tag_gps_altitude_ref\">GPS高度参照</string>\n    <string name=\"tag_gps_altitude\">GPS高度</string>\n    <string name=\"tag_gps_satellites\">GPS衛星</string>\n    <string name=\"tag_gps_track_ref\">GPSトラック参照</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS画像方向参照</string>\n    <string name=\"tag_gps_map_datum\">GPS地図基準</string>\n    <string name=\"tag_gps_dest_longitude\">GPS目的地経度</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS目的地方位参照</string>\n    <string name=\"tag_gps_dest_bearing\">GPS目的地方位</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS目的地距離参照</string>\n    <string name=\"tag_interoperability_index\">相互運用性インデックス</string>\n    <string name=\"tag_orf_preview_image_start\">プレビュー画像開始</string>\n    <string name=\"tag_orf_aspect_frame\">アスペクトフレーム</string>\n    <string name=\"tag_rw2_sensor_left_border\">センサー左端境界</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"triangle\">三角形</string>\n    <string name=\"repeat_text_sub\">現在のテキストは1回だけでなくパスの終わりまで繰り返されます</string>\n    <string name=\"outlined_triangle_sub\">開始点から終了点までアウトラインのある三角形を描画します</string>\n    <string name=\"triangle_sub\">開始点から終了点まで三角形を描画します</string>\n    <string name=\"outlined_polygon_sub\">開始点から終了点までアウトラインのある多角形を描画します</string>\n    <string name=\"draw_regular_polygon\">正多角形を描画</string>\n    <string name=\"draw_regular_polygon_sub\">自由形式ではなく正多角形を描画します</string>\n    <string name=\"star_sub\">開始点から終了点まで星を描画します</string>\n    <string name=\"star\">星</string>\n    <string name=\"outlined_star\">アウトライン星</string>\n    <string name=\"inner_radius_ratio\">内部半径比</string>\n    <string name=\"draw_regular_star\">正星形を描画</string>\n    <string name=\"outlined_star_sub\">開始点から終了点までアウトラインのある星を描画します</string>\n    <string name=\"antialias\">アンチエイリアス</string>\n    <string name=\"draw_regular_star_sub\">自由形式ではなく正星形を描画します</string>\n    <string name=\"antialias_sub\">鋭いエッジを防止するためにアンチエイリアスを有効にします</string>\n    <string name=\"open_edit_instead_of_preview\">プレビューの代わりに編集を開く</string>\n    <string name=\"open_edit_instead_of_preview_sub\">ImageToolboxで画像を開く（プレビュー）を選択すると、プレビューの代わりに編集選択シートが開きます</string>\n    <string name=\"document_scanner\">ドキュメントスキャナー</string>\n    <string name=\"click_to_start_scanning\">クリックしてスキャンを開始</string>\n    <string name=\"start_scanning\">スキャン開始</string>\n    <string name=\"save_as_pdf\">PDFとして保存</string>\n    <string name=\"share_as_pdf\">PDFとして共有</string>\n    <string name=\"options_below_is_for_images\">以下のオプションはPDFではなく画像の保存用です</string>\n    <string name=\"equalize_histogram_hsv\">ヒストグラム平均化HSV</string>\n    <string name=\"equalize_histogram\">ヒストグラム平均化</string>\n    <string name=\"scale_color_space\">スケールカラースペース</string>\n    <string name=\"linear\">線形</string>\n    <string name=\"allow_enter_by_text_field\">テキストフィールドでの入力を許可</string>\n    <string name=\"equalize_histogram_pixelation\">ヒストグラム平均化ピクセル化</string>\n    <string name=\"grid_size_x\">グリッドサイズX</string>\n    <string name=\"allow_enter_by_text_field_sub\">プリセット選択の背後にテキストフィールドを有効にして、その場で入力できるようにします</string>\n    <string name=\"grid_size_y\">グリッドサイズY</string>\n    <string name=\"equalize_histogram_adaptive\">適応的ヒストグラム平均化</string>\n    <string name=\"equalize_histogram_adaptive_luv\">適応的ヒストグラム平均化LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">適応的ヒストグラム平均化LAB</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"frame_color\">フレームの色</string>\n    <string name=\"color_to_ignore\">無視する色</string>\n    <string name=\"no_template_filters\">テンプレートフィルターが追加されていません</string>\n    <string name=\"create_new\">新規作成</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">スキャンしたQRコードは有効なフィルターテンプレートではありません</string>\n    <string name=\"scan_qr_code\">QRコードをスキャン</string>\n    <string name=\"template\">テンプレート</string>\n    <string name=\"opened_file_have_no_filter_template\">選択したファイルにはフィルターテンプレートデータがありません</string>\n    <string name=\"template_name\">テンプレート名</string>\n    <string name=\"select_template_preview\">この画像はこのフィルターテンプレートのプレビューとして使用されます</string>\n    <string name=\"template_filter\">テンプレートフィルター</string>\n    <string name=\"as_qr_code\">QRコード画像として</string>\n    <string name=\"added_filter_template\">名前「%1$s」（%2$s）のフィルターテンプレートを追加しました</string>\n    <string name=\"filter_preview\">フィルタープレビュー</string>\n    <string name=\"code_content\">コード内容</string>\n    <string name=\"qr_code_sub\">QRコードをスキャンして内容を取得するか、文字列を貼り付けて新しいQRコードを生成します</string>\n    <string name=\"scan_qr_code_to_replace_content\">QRコードをスキャンしてフィールドの内容を置き換えるか、テキストを入力して新しいQRコードを生成します</string>\n    <string name=\"qr_description\">QR説明</string>\n    <string name=\"min\">最小</string>\n    <string name=\"cubic\">キュービック</string>\n    <string name=\"robidoux\">ロビドゥー</string>\n    <string name=\"robidoux_sharp\">ロビドゥーシャープ</string>\n    <string name=\"spline16\">スプライン16</string>\n    <string name=\"spline36\">スプライン36</string>\n    <string name=\"spline64\">スプライン64</string>\n    <string name=\"quadric_sub\">補間に二次関数を使用する方法で、滑らかで連続的な結果を提供します</string>\n    <string name=\"box_sub\">最も近いピクセル値の平均を使用する単純なリサンプリング方法で、しばしばブロック状の外観になります</string>\n    <string name=\"lanczos2_sub\">最小限のアーティファクトで高品質な補間のために2ローブのランチョスフィルターを使用するリサンプリング方法</string>\n    <string name=\"lanczos3_sub\">最小限のアーティファクトで高品質な補間のために3ローブのランチョスフィルターを使用するリサンプリング方法</string>\n    <string name=\"lanczos4_sub\">最小限のアーティファクトで高品質な補間のために4ローブのランチョスフィルターを使用するリサンプリング方法</string>\n    <string name=\"ewa_blackman_sub\">リンギングアーティファクトを最小限に抑えるためのブラックマンフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"ewa_quadric\">クアドリックEWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">エイリアシングを低減した高品質リサンプリングのためのランチョス3 Jincフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"ginseng\">ジンセン</string>\n    <string name=\"ginseng_sub\">鮮明さとスムーズさのバランスが良好な高品質画像処理用に設計されたリサンプリングフィルター</string>\n    <string name=\"ewa_ginseng\">ジンセンEWA</string>\n    <string name=\"ewa_ginseng_sub\">画質向上のためのジンセンフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"ewa_lanczos_sharp\">ランチョスシャープEWA</string>\n    <string name=\"ewa_lanczos_4_sharpest\">ランチョス4最シャープEWA</string>\n    <string name=\"ewa_lanczos_soft\">ランチョスソフトEWA</string>\n    <string name=\"haasn_soft\">ハースンソフト</string>\n    <string name=\"haasn_soft_sub\">スムーズでアーティファクトのない画像スケーリングのためにハースンによって設計されたリサンプリングフィルター</string>\n    <string name=\"format_conversion\">フォーマット変換</string>\n    <string name=\"color_blind_scheme_sub\">指定された色覚異常タイプに合わせてテーマカラーを適応させるモードを選択します</string>\n    <string name=\"achromatomaly_sub\">すべての色に対する感度が低下</string>\n    <string name=\"achromatopsia_sub\">完全な色覚異常で、グレーの階調のみ見える</string>\n    <string name=\"not_use_color_blind_scheme\">色覚異常スキームを使用しない</string>\n    <string name=\"tritanopia_sub\">青色の色相を知覚できない</string>\n    <string name=\"not_use_color_blind_scheme_sub\">テーマで設定されたとおりに色が表示されます</string>\n    <string name=\"sigmoidal\">シグモイド</string>\n    <string name=\"lagrange_3\">ラグランジュ3</string>\n    <string name=\"lanczos_6\">ランチョス6</string>\n    <string name=\"lanczos_6_sub\">より高次の6を持つランチョスリサンプリングフィルターで、より鮮明で正確な画像スケーリングを提供します</string>\n    <string name=\"linear_stack_blur\">線形スタックぼかし</string>\n    <string name=\"gaussian_box_blur\">ガウシアンボックスぼかし</string>\n    <string name=\"linear_fast_gaussian_blur_next\">線形高速ガウシアンぼかしネクスト</string>\n    <string name=\"pick_filter_info\">描画のブラシとして使用するフィルターを以下から選択してください</string>\n    <string name=\"tiff_compression_scheme\">TIFF圧縮スキーム</string>\n    <string name=\"image_splitting_sub\">単一画像を行または列で分割</string>\n    <string name=\"fit_to_bounds_sub\">希望する動作（切り抜き/アスペクト比に合わせる）を実現するために、このパラメータを切り抜きリサイズモードと組み合わせます</string>\n    <string name=\"languages_imported\">言語のインポートに成功しました</string>\n    <string name=\"backup_ocr_models\">OCRモデルのバックアップ</string>\n    <string name=\"import_word\">インポート</string>\n    <string name=\"export\">エクスポート</string>\n    <string name=\"position\">位置</string>\n    <string name=\"bottom_right\">右下</string>\n    <string name=\"center_right\">中央右</string>\n    <string name=\"bottom_center\">下中央</string>\n    <string name=\"gotham\">ゴッサム</string>\n    <string name=\"tri_tone\">トリトーン</string>\n    <string name=\"clahe_jzazbz\">CLAHE Jzazbz</string>\n    <string name=\"clahe_oklab\">CLAHE Oklab</string>\n    <string name=\"clahe_oklch\">CLAHE Oklch</string>\n    <string name=\"clustered_8x8_dithering\">クラスタ化8x8ディザリング</string>\n    <string name=\"harmony_tetradic\">四色</string>\n    <string name=\"variation\">バリエーション</string>\n    <string name=\"shades\">シェード</string>\n    <string name=\"color_mixing\">色の混合</string>\n    <string name=\"color_to_mix\">混合する色</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">ダイナミックカラーが有効になっている間はモネを使用できません</string>\n    <string name=\"miss_etikate\">ミスエティケイト</string>\n    <string name=\"soft_elegance\">ソフトエレガンス</string>\n    <string name=\"palette_transfer_variant\">パレット転送バリアント</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"bleach_bypass\">ブリーチバイパス</string>\n    <string name=\"candlelight\">キャンドルライト</string>\n    <string name=\"edgy_amber\">エッジーアンバー</string>\n    <string name=\"fall_colors\">秋色</string>\n    <string name=\"pop_art\">ポップアート</string>\n    <string name=\"celluloid\">セルロイド</string>\n    <string name=\"gif_type_to_webp\">GIFからWEBPへ</string>\n    <string name=\"gif_type_to_webp_sub\">GIF画像をWEBPアニメーション画像に変換</string>\n    <string name=\"webp_tools\">WEBPツール</string>\n    <string name=\"webp_tools_sub\">画像をWEBPアニメーション画像に変換したり、指定されたWEBPアニメーションからフレームを抽出したりします</string>\n    <string name=\"webp_type_to_webp_sub\">画像のバッチをWEBPファイルに変換</string>\n    <string name=\"webp_type_to_webp\">画像からWEBPへ</string>\n    <string name=\"select_webp_image_to_start\">開始するにはWEBP画像を選択</string>\n    <string name=\"manage_storage_extra_types_sub\">JXL、QOIおよびAndroidで画像ファイルとして認識されない他の形式の画像を見るには、全ファイルへのアクセスを許可してください</string>\n    <string name=\"default_draw_path_mode\">デフォルトの描画パスモード</string>\n    <string name=\"manage_storage_extra_types\">ファイルへの完全アクセスがありません</string>\n    <string name=\"add_timestamp\">タイムスタンプを追加</string>\n    <string name=\"one_time_save_location\">一度だけの保存場所</string>\n    <string name=\"recently_used\">最近使用した</string>\n    <string name=\"ci_channel\">CIチャンネル</string>\n    <string name=\"group\">グループ</string>\n    <string name=\"image_toolbox_in_telegram\">ImageToolbox in Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">何でも議論できるチャットに参加してください。また、ベータ版や発表を投稿するCIチャンネルもチェックできます</string>\n    <string name=\"fit_description\">画像を指定した寸法に合わせ、背景にぼかしや色を適用します</string>\n    <string name=\"group_tools_by_type\">タイプ別にツールをグループ化</string>\n    <string name=\"tools_arrangement\">ツール配置</string>\n    <string name=\"group_tools_by_type_sub\">メイン画面のツールをカスタムリスト配置ではなく、タイプ別にグループ化します</string>\n    <string name=\"default_values\">デフォルト値</string>\n    <string name=\"system_bars_visibility\">システムバーの表示</string>\n    <string name=\"show_system_bars_by_swipe_sub\">非表示の場合にスワイプでシステムバーを表示できるようにします</string>\n    <string name=\"hide_all\">すべて非表示</string>\n    <string name=\"show_all\">すべて表示</string>\n    <string name=\"noise_generation\">ノイズ生成</string>\n    <string name=\"hide_status_bar\">ステータスバーを非表示</string>\n    <string name=\"noise_generation_sub\">パーリンやその他のタイプのノイズを生成します</string>\n    <string name=\"frequency\">周波数</string>\n    <string name=\"noise_type\">ノイズタイプ</string>\n    <string name=\"rotation_type\">回転タイプ</string>\n    <string name=\"ping_pong_strength\">ピンポン強度</string>\n    <string name=\"distance_function\">距離関数</string>\n    <string name=\"return_type\">戻り値タイプ</string>\n    <string name=\"jitter\">ジッター</string>\n    <string name=\"dashed\">破線</string>\n    <string name=\"dot_dashed\">点線と破線</string>\n    <string name=\"stamped\">スタンプ</string>\n    <string name=\"zigzag\">ジグザグ</string>\n    <string name=\"dashed_sub\">指定されたギャップサイズで描画されたパスに沿って破線を描画</string>\n    <string name=\"defaultt_sub\">単なるデフォルトの直線</string>\n    <string name=\"create_shortcut\">ショートカットを作成</string>\n    <string name=\"create_shortcut_title\">固定するツールを選択</string>\n    <string name=\"dont_stack_frames_sub\">前のフレームを破棄するようにして、フレームが互いにスタックしないようにします</string>\n    <string name=\"crossfade_sub\">フレームは互いにクロスフェードされます</string>\n    <string name=\"crossfade_count\">クロスフェードフレーム数</string>\n    <string name=\"threshold_one\">しきい値1</string>\n    <string name=\"threshold_two\">しきい値2</string>\n    <string name=\"mirror_101\">ミラー101</string>\n    <string name=\"enhanced_zoom_blur\">拡張ズームぼかし</string>\n    <string name=\"laplacian_simple\">シンプルラプラシアン</string>\n    <string name=\"sobel_simple\">シンプルソーベル</string>\n    <string name=\"helper_grid\">ヘルパーグリッド</string>\n    <string name=\"helper_grid_sub\">正確な操作に役立つよう描画領域の上にサポートグリッドを表示</string>\n    <string name=\"grid_color\">グリッドの色</string>\n    <string name=\"cell_width\">セル幅</string>\n    <string name=\"cell_height\">セル高</string>\n    <string name=\"compact_selectors\">コンパクトセレクター</string>\n    <string name=\"compact_selectors_sub\">一部の選択コントロールはスペースを取らないようにコンパクトなレイアウトを使用します</string>\n    <string name=\"layout\">レイアウト</string>\n    <string name=\"lut_library\">LUTライブラリ</string>\n    <string name=\"lut_library_sub\">ダウンロード後に適用できるLUTのコレクションをダウンロード</string>\n    <string name=\"lut_library_update_sub\">LUTのコレクションを更新します（新しいもののみがキューに追加されます）。ダウンロード後に適用できます</string>\n    <string name=\"filter_preview_image_sub\">フィルターのデフォルトプレビュー画像を変更</string>\n    <string name=\"filter_preview_image\">プレビュー画像</string>\n    <string name=\"hide\">非表示</string>\n    <string name=\"show\">表示</string>\n    <string name=\"slider_type\">スライダータイプ</string>\n    <string name=\"fancy\">ファンシー</string>\n    <string name=\"material_you_slider_sub\">モダンなマテリアルYouスライダー。未来的でフレッシュ、アクセシブルです</string>\n    <string name=\"apply\">適用</string>\n    <string name=\"center_align_dialog_buttons\">ダイアログボタンを中央揃え</string>\n    <string name=\"center_align_dialog_buttons_sub\">可能であればダイアログのボタンは左側ではなく中央に配置されます</string>\n    <string name=\"open_source_licenses\">オープンソースライセンス</string>\n    <string name=\"open_source_licenses_sub\">このアプリで使用されているオープンソースライブラリのライセンスを表示</string>\n    <string name=\"area_sub\">ピクセル面積関係を使用したリサンプリング。モアレのない結果が得られるため、画像縮小に適した方法かもしれません。ただし、画像が拡大されると、最近傍法に似ています</string>\n    <string name=\"enable_tonemapping\">トーンマッピングを有効化</string>\n    <string name=\"enter_percent\">%を入力</string>\n    <string name=\"unknown_host\">サイトにアクセスできません。VPNを使用するか、URLが正しいか確認してください</string>\n    <string name=\"markup_layers_sub\">画像、テキストなどを自由に配置できるレイヤーモード</string>\n    <string name=\"edit_layer\">レイヤーを編集</string>\n    <string name=\"layers_on_image\">画像上のレイヤー</string>\n    <string name=\"beta\">ベータ</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">空または無効なBase64文字列はコピーできません</string>\n    <string name=\"paste_base_64\">Base64を貼り付け</string>\n    <string name=\"copy_base_64\">Base64をコピー</string>\n    <string name=\"not_a_valid_base_64\">提供された値は有効なBase64文字列ではありません</string>\n    <string name=\"save_base_64\">Base64を保存</string>\n    <string name=\"share_base_64\">Base64を共有</string>\n    <string name=\"options\">オプション</string>\n    <string name=\"actions\">アクション</string>\n    <string name=\"import_base_64\">Base64をインポート</string>\n    <string name=\"base_64_actions\">Base64アクション</string>\n    <string name=\"add_outline\">アウトラインを追加</string>\n    <string name=\"add_outline_sub\">指定した色と幅でテキストの周りにアウトラインを追加</string>\n    <string name=\"outline_color\">アウトラインの色</string>\n    <string name=\"outline_size\">アウトラインのサイズ</string>\n    <string name=\"rotation\">回転</string>\n    <string name=\"fractal_type\">フラクタルタイプ</string>\n    <string name=\"octaves\">オクターブ</string>\n    <string name=\"lacunarity\">ラキュナリティ</string>\n    <string name=\"gain\">ゲイン</string>\n    <string name=\"weighted_strength\">重み付け強度</string>\n    <string name=\"head_length_scale\">頭部長さスケール</string>\n    <string name=\"no_barcode_found\">バーコードが見つかりません</string>\n    <string name=\"generated_barcode_will_be_here\">生成されたバーコードがここに表示されます</string>\n    <string name=\"audio_cover_extractor\">音声ファイルのカバー画像抽出</string>\n    <string name=\"audio_cover_extractor_sub\">オーディオファイルからアルバムカバー画像を抽出。最も一般的なフォーマットがサポートされています</string>\n    <string name=\"stamp\">スタンプ</string>\n    <string name=\"pick_audio_to_start\">開始するにはオーディオを選択</string>\n    <string name=\"pick_audio\">オーディオを選択</string>\n    <string name=\"fit_width\">幅に合わせる</string>\n    <string name=\"fit_height\">高さに合わせる</string>\n    <string name=\"none\">なし</string>\n    <string name=\"custom_pages\">カスタムページ</string>\n    <string name=\"pages_selection\">ページ選択</string>\n    <string name=\"image_cutting\">画像切り取り</string>\n    <string name=\"image_cutting_sub\">垂直または水平線で画像の一部を切り取り、残りの部分を結合（反転も可能）</string>\n    <string name=\"vertical_pivot_line\">垂直ピボットライン</string>\n    <string name=\"film_stock_50\">フィルムストック50</string>\n    <string name=\"foggy_night\">霧の夜</string>\n    <string name=\"kodak\">コダック</string>\n    <string name=\"top_center\">上中央</string>\n    <string name=\"tool_exit_confirmation\">ツール終了確認</string>\n    <string name=\"tool_exit_confirmation_sub\">特定のツールを使用中に保存されていない変更がある場合に閉じようとすると、確認ダイアログが表示されます</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">ドキュメントスキャナーを使用するには設定でカメラ権限を許可してください</string>\n    <string name=\"tag_flash_energy\">フラッシュエネルギー</string>\n    <string name=\"hamming\">ハミング</string>\n    <string name=\"tag_spatial_frequency_response\">空間周波数応答</string>\n    <string name=\"blackman\">ブラックマン</string>\n    <string name=\"tag_focal_plane_x_resolution\">焦点面X解像度</string>\n    <string name=\"welch\">ウェルチ</string>\n    <string name=\"quadric\">クアドリック</string>\n    <string name=\"gaussian\">ガウシアン</string>\n    <string name=\"sphinx\">スフィンクス</string>\n    <string name=\"bartlett\">バートレット</string>\n    <string name=\"lanczos2\">ランチョス2</string>\n    <string name=\"lanczos3\">ランチョス3</string>\n    <string name=\"lanczos4\">ランチョス4</string>\n    <string name=\"lanczos2_jinc\">ランチョス2 Jinc</string>\n    <string name=\"tag_focal_plane_resolution_unit\">焦点面解像度単位</string>\n    <string name=\"polygon\">多角形</string>\n    <string name=\"vertices\">頂点</string>\n    <string name=\"enter_percentage\">パーセンテージを入力</string>\n    <string name=\"as_file\">ファイルとして</string>\n    <string name=\"delete_template\">テンプレートを削除</string>\n    <string name=\"lanczos3_jinc\">ランチョス3 Jinc</string>\n    <string name=\"lanczos4_jinc\">ランチョス4 Jinc</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QRコードをスキャンするには設定でカメラ権限を許可してください</string>\n    <string name=\"hanning_sub\">ハン窓の変形で、信号処理アプリケーションでスペクトルリークを低減するためによく使用されます</string>\n    <string name=\"kaiser_sub\">カイザー窓を使用する補間方法で、メインローブの幅とサイドローブのレベルのトレードオフを適切に制御できます</string>\n    <string name=\"lanczos2_jinc_sub\">jinc関数を使用するランチョス2フィルターの変種で、最小限のアーティファクトで高品質な補間を提供します</string>\n    <string name=\"deuteranopia_sub\">緑色の色相を知覚できない</string>\n    <string name=\"tesseract_options_sub\">Tesseractエンジンの入力変数を適用</string>\n    <string name=\"layers_on_background_sub\">最初のオプションと同じですが、画像の代わりに色を使用</string>\n    <string name=\"protanomaly_sub\">赤と緑の色相の区別が困難</string>\n    <string name=\"send_logs_sub\">クリックしてアプリログファイルを共有。これは問題を特定して解決するのに役立ちます</string>\n    <string name=\"checksum_tools_sub\">チェックサムの比較、ハッシュの計算、様々なハッシュアルゴリズムを使用したファイルからのHEX文字列の作成が可能です</string>\n    <string name=\"sphinx_sub\">最小限のアーティファクトで高品質な補間を提供する高度なリサンプリング方法</string>\n    <string name=\"bartlett_sub\">信号処理でスペクトルリークを低減するために使用される三角窓関数</string>\n    <string name=\"spline36_sub\">36タップフィルターを使用して滑らかな結果を提供するスプライン基準の補間方法</string>\n    <string name=\"spline64_sub\">64タップフィルターを使用して滑らかな結果を提供するスプライン基準の補間方法</string>\n    <string name=\"ewa_hanning\">ハニングEWA</string>\n    <string name=\"ewa_blackman\">ブラックマンEWA</string>\n    <string name=\"bohman_sub\">スペクトルリークを低減するために使用される窓関数で、信号処理アプリケーションで優れた周波数分解能を提供します</string>\n    <string name=\"lanczos4_jinc_sub\">jinc関数を使用するランチョス4フィルターの変種で、最小限のアーティファクトで高品質な補間を提供します</string>\n    <string name=\"ewa_hanning_sub\">滑らかな補間とリサンプリングのためのハニングフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"ewa_robidoux_sharp\">ロビドゥーシャープEWA</string>\n    <string name=\"ewa_lanczos3_jinc\">ランチョス3 Jinc EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">最小限のアーティファクトでシャープな結果を得るためのランチョスシャープフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"dismiss_forever\">永久に非表示</string>\n    <string name=\"bins_count\">ビン数</string>\n    <string name=\"clahe_hsl\">CLAHE HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">適応的ヒストグラム平均化HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">適応的ヒストグラム平均化HSV</string>\n    <string name=\"wrap\">ラップ</string>\n    <string name=\"lagrange_2\">ラグランジュ2</string>\n    <string name=\"lagrange_2_sub\">2次のラグランジュ補間フィルターで、滑らかな遷移による高品質な画像スケーリングに適しています</string>\n    <string name=\"lanczos_6_jinc_sub\">画像リサンプリング品質を向上させるためにJinc関数を使用するランチョス6フィルターの変種</string>\n    <string name=\"linear_tent_blur\">線形テントぼかし</string>\n    <string name=\"linear_gaussian_box_blur\">線形ガウシアンボックスぼかし</string>\n    <string name=\"linear_fast_gaussian_blur\">線形高速ガウシアンぼかし</string>\n    <string name=\"center\">中央</string>\n    <string name=\"top_left\">左上</string>\n    <string name=\"bottom_left\">左下</string>\n    <string name=\"target_image\">ターゲット画像</string>\n    <string name=\"linear_gaussian_blur\">線形ガウシアンぼかし</string>\n    <string name=\"replace_filter\">フィルターを置換</string>\n    <string name=\"palette_transfer\">パレット転送</string>\n    <string name=\"enhanced_oil\">拡張油彩</string>\n    <string name=\"simple_old_tv\">シンプル古いテレビ</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"clustered_2x2_dithering\">クラスタ化2x2ディザリング</string>\n    <string name=\"clustered_4x4_dithering\">クラスタ化4x4ディザリング</string>\n    <string name=\"yililoma_dithering\">ユリローマディザリング</string>\n    <string name=\"no_favorite_options_selected\">お気に入りオプションが選択されていません。ツールページで追加してください</string>\n    <string name=\"add_favorites\">お気に入りを追加</string>\n    <string name=\"harmony_complementary\">補色</string>\n    <string name=\"harmony_split_complementary\">分裂補色</string>\n    <string name=\"harmony_analogous_complementary\">類似色と補色</string>\n    <string name=\"color_tools\">カラーツール</string>\n    <string name=\"coffee\">コーヒー</string>\n    <string name=\"greenish\">緑っぽい</string>\n    <string name=\"color_harmonies\">カラーハーモニー</string>\n    <string name=\"color_shading\">カラーシェーディング</string>\n    <string name=\"target_lut_image\">ターゲットLUT画像</string>\n    <string name=\"soft_elegance_variant\">ソフトエレガンスバリアント</string>\n    <string name=\"target_cube_lut_file\">ターゲット3D LUTファイル（.cube / .CUBE）</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"save_empty_lut\">ニュートラルLUT画像を取得</string>\n    <string name=\"retro_yellow\">レトロイエロー</string>\n    <string name=\"links_preview\">リンクプレビュー</string>\n    <string name=\"links\">リンク</string>\n    <string name=\"ico_size_warning\">Icoファイルは256×256の最大サイズでのみ保存できます。より大きいサイズは結果画像で自動的に調整されます</string>\n    <string name=\"default_draw_color\">デフォルトの描画色</string>\n    <string name=\"formatted_timestamp\">フォーマット済みタイムスタンプ</string>\n    <string name=\"enable_timestamps_to_format_them\">フォーマットするためにタイムスタンプを有効にする</string>\n    <string name=\"show_system_bars_by_swipe\">スワイプでシステムバーを表示</string>\n    <string name=\"domain_warp\">ドメインワープ</string>\n    <string name=\"alignment\">配置</string>\n    <string name=\"custom_filename\">カスタムファイル名</string>\n    <string name=\"saved_to_custom\">カスタム名でフォルダに保存されました</string>\n    <string name=\"collage_type\">コラージュタイプ</string>\n    <string name=\"collages_info\">画像を長押しして入れ替え、移動とズームで位置を調整</string>\n    <string name=\"histogram\">ヒストグラム</string>\n    <string name=\"image_for_histogram\">この画像はRGBと明るさのヒストグラム生成に使用されます</string>\n    <string name=\"tesseract_options\">Tesseractオプション</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">オプションは次のパターンに従って入力する必要があります：「--{option_name} {value}」</string>\n    <string name=\"auto_crop\">自動切り抜き</string>\n    <string name=\"free_corners\">自由コーナー</string>\n    <string name=\"coerce_points_to_image_bounds\">点を画像境界に強制</string>\n    <string name=\"use_circle_kernel\">円形カーネルを使用</string>\n    <string name=\"opening\">オープニング</string>\n    <string name=\"closing\">クロージング</string>\n    <string name=\"morphological_gradient\">モルフォロジカルグラデーション</string>\n    <string name=\"top_hat\">トップハット</string>\n    <string name=\"tone_curves\">トーンカーブ</string>\n    <string name=\"black_hat\">ブラックハット</string>\n    <string name=\"reset_curves\">カーブをリセット</string>\n    <string name=\"line_style\">線のスタイル</string>\n    <string name=\"gap_size\">ギャップサイズ</string>\n    <string name=\"zigzag_ratio\">ジグザグ比率</string>\n    <string name=\"create_shortcut_subtitle\">ツールはランチャーのホーム画面にショートカットとして追加されます。必要な動作を実現するために「ファイル選択をスキップ」設定と組み合わせて使用してください</string>\n    <string name=\"dont_stack_frames\">フレームをスタックしない</string>\n    <string name=\"stamped_sub\">指定された間隔でパスに沿って選択した形状を描画</string>\n    <string name=\"crossfade\">クロスフェード</string>\n    <string name=\"canny\">キャニー</string>\n    <string name=\"grant_camera_permission_to_capture_image\">画像をキャプチャするには設定でカメラ権限を許可してください</string>\n    <string name=\"main_screen_title\">メイン画面タイトル</string>\n    <string name=\"constant_rate_factor\">固定レート係数（CRF）</string>\n    <string name=\"material_2\">マテリアル2</string>\n    <string name=\"layers_on_background\">背景上のレイヤー</string>\n    <string name=\"fast_settings_side\">クイック設定側面</string>\n    <string name=\"clear_selection\">選択をクリア</string>\n    <string name=\"settings_group_visibility_visible\">設定グループ「%1$s」はデフォルトで展開されます</string>\n    <string name=\"base_64_tools\">Base64ツール</string>\n    <string name=\"checksum_tools\">チェックサムツール</string>\n    <string name=\"wrong_font\">インポートできるのはTTFフォントのみです</string>\n    <string name=\"import_font\">フォントをインポート（TTF/OTF）</string>\n    <string name=\"export_fonts\">フォントをエクスポート</string>\n    <string name=\"imported_fonts\">インポートしたフォント</string>\n    <string name=\"edit_exif_tag\">タップして利用可能なタグを編集</string>\n    <string name=\"timestamp\">タイムスタンプ</string>\n    <string name=\"padding\">パディング</string>\n    <string name=\"format_pattern\">フォーマットパターン</string>\n    <string name=\"horizontal_pivot_line\">水平ピボットライン</string>\n    <string name=\"inverse_selection\">選択を反転</string>\n    <string name=\"points_customization\">ポイントのカスタマイズ</string>\n    <string name=\"grid_size\">グリッドサイズ</string>\n    <string name=\"resolution_x\">解像度X</string>\n    <string name=\"no_covers_found\">カバーが見つかりません</string>\n    <string name=\"crash_title\">おっと… 何か問題が発生しました</string>\n    <string name=\"crash_subtitle\">以下のオプションを使用して連絡していただければ、解決策を見つけるよう努めます。\\n（ログの添付をお忘れなく）</string>\n    <string name=\"ocr_write_to_file\">ファイルに書き込む</string>\n    <string name=\"invisible_mode\">不可視モード</string>\n    <string name=\"ocr_write_to_file_sub\">画像のバッチからテキストを抽出し、1つのテキストファイルに保存</string>\n    <string name=\"use_lsb\">LSBを使用</string>\n    <string name=\"auto_remove_red_eyes\">赤目を自動削除</string>\n    <string name=\"robidoux_sharp_sub\">ロビドゥー方法のより鮮明なバリアントで、くっきりとした画像リサイズに最適化されています</string>\n    <string name=\"bspline_sub\">区分的に定義された多項式関数を利用して曲線や表面を滑らかに補間および近似し、柔軟で連続的な形状表現を提供します</string>\n    <string name=\"tritanomaly_sub\">青と黄色の色相の区別が困難</string>\n    <string name=\"ocr_write_to_metadata_sub\">各画像からテキストを抽出し、関連する写真のEXIF情報に配置</string>\n    <string name=\"custom_filename_sub\">現在の画像の保存に使用される場所とファイル名を選択</string>\n    <string name=\"links_preview_sub\">テキストを取得できる場所（QRコード、OCRなど）でリンクプレビューの取得を有効にします</string>\n    <string name=\"layers_on_image_sub\">画像を背景として使用し、その上に異なるレイヤーを追加できます</string>\n    <string name=\"reset_curves_sub\">カーブはデフォルト値に戻されます</string>\n    <string name=\"cubic_sub\">キュービック補間は最も近い16ピクセルを考慮してよりスムーズなスケーリングを提供し、バイリニアよりも優れた結果を得られます</string>\n    <string name=\"formatted_timestamp_sub\">出力ファイル名に基本的なミリ秒の代わりにフォーマット済みタイムスタンプを有効にします</string>\n    <string name=\"blackman_sub\">スペクトルリークを最小限に抑えることで優れた周波数分解能を提供する窓関数で、信号処理でよく使用されます</string>\n    <string name=\"ewa_robidoux_sharp_sub\">よりシャープな結果を得るためのロビドゥーシャープフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"welch_sub\">スペクトルリークを低減しながら優れた周波数分解能を提供するように設計された窓関数で、信号処理アプリケーションでよく使用されます</string>\n    <string name=\"invisible_mode_sub\">ステガノグラフィーを使用して、画像のバイト内に目に見えないウォーターマークを作成</string>\n    <string name=\"ewa_quadric_sub\">滑らかな補間のためのクアドリックフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"robidoux_sub\">自然画像のリサイズに最適化された高品質補間方法で、鮮明さとスムーズさのバランスを取ります</string>\n    <string name=\"zigzag_sub\">パスに沿って波状のジグザグを描画</string>\n    <string name=\"inverse_vertical_selection_sub\">切り取り領域の周りの部分を結合する代わりに、垂直切り取り部分が残されます</string>\n    <string name=\"base_64_tools_sub\">Base64文字列を画像にデコードするか、画像をBase64形式にエンコードします</string>\n    <string name=\"fast_settings_side_sub\">画像編集中に選択した側面にフローティングストリップを追加し、クリックするとクイック設定が開きます</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">非常にシャープな画像リサンプリングのためのランチョス4最シャープフィルターの楕円加重平均（EWA）変種</string>\n    <string name=\"deuteranomaly_sub\">緑と赤の色相の区別が困難</string>\n    <string name=\"draw_filter_sub\">ペイントとして使用するフィルターを1つ選択</string>\n    <string name=\"color_tools_sub\">色の混合、トーン作成、シェード生成など</string>\n    <string name=\"checksum_as_filename_sub\">出力画像はそのデータチェックサムに対応する名前になります</string>\n    <string name=\"format_conversion_sub\">画像のバッチを一つのフォーマットから別のフォーマットに変換</string>\n    <string name=\"image_stacking_sub\">選択したブレンドモードで画像を重ね合わせる</string>\n    <string name=\"save_empty_lut_sub\">まず、ここで取得できるニュートラルLUTにお気に入りの写真編集アプリケーションでフィルターを適用します。これが正しく機能するためには、各ピクセルの色が変更されていないことが必要です</string>\n    <string name=\"add_timestamp_sub\">出力ファイル名へのタイムスタンプ追加を有効にします</string>\n    <string name=\"collage_maker_sub\">20枚の画像からさまざまなコラージュを作成します</string>\n    <string name=\"free_software_partner_sub\">Androidアプリケーションのパートナーチャンネルで、より多くの役立つソフトウェア</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">点は画像境界に制限されません。これはより正確なパースペクティブ修正に役立ちます</string>\n    <string name=\"spot_heal_sub\">描画されたパスの下でコンテンツアウェアフィル</string>\n    <string name=\"material_2_sub\">マテリアル2ベースのスライダー。モダンではなくシンプルで直感的です</string>\n    <string name=\"inverse_horizontal_selection_sub\">切り取り領域の周りの部分を結合する代わりに、水平切り取り部分が残されます</string>\n    <string name=\"use_lsb_sub\">LSB（最下位ビット）ステガノグラフィー方式が使用されます。そうでない場合はFD（周波数領域）</string>\n    <string name=\"barcodes_sub\">任意のバーコード（QR、EAN、AZTECなど）をスキャンしてその内容を取得するか、テキストを貼り付けて新しいものを生成します</string>\n    <string name=\"webp_type_to_image\">WEBPから画像へ</string>\n    <string name=\"collection_mesh_gradients_sub\">メッシュグラデーションのオンラインコレクションを閲覧</string>\n    <string name=\"collection_mesh_gradients\">メッシュグラデーションのコレクション</string>\n    <string name=\"gradient_maker_type_image_mesh\">メッシュグラデーションオーバーレイ</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">指定された画像の上にメッシュグラデーションを合成</string>\n    <string name=\"resolution_y\">解像度Y</string>\n    <string name=\"resolution\">解像度</string>\n    <string name=\"pick_file_to_checksum\">選択したアルゴリズムに基づいてチェックサムを計算するファイルを選択</string>\n    <string name=\"send_logs\">ログを送信</string>\n    <string name=\"pixel_by_pixel\">ピクセルごと</string>\n    <string name=\"highlight_color\">ハイライトの色</string>\n    <string name=\"pixel_comparison_type\">ピクセル比較タイプ</string>\n    <string name=\"top_to_bottom\">上から下</string>\n    <string name=\"pdf_is_protected\">PDFは保護されています</string>\n    <string name=\"sort_by_size_reversed\">サイズ（逆順）</string>\n    <string name=\"sort_by_mime_type\">MIMEタイプ</string>\n    <string name=\"sort_by_size\">サイズ</string>\n    <string name=\"unlock\">ロック解除</string>\n    <string name=\"password\">パスワード</string>\n    <string name=\"operation_almost_complete\">操作はほぼ完了しています。今キャンセルすると、再開するには最初からやり直す必要があります。</string>\n    <string name=\"sort_by_date_modified\">更新日</string>\n    <string name=\"sort_by_date_modified_reversed\">更新日（逆順）</string>\n    <string name=\"sort_by_mime_type_reversed\">MIMEタイプ（逆順）</string>\n    <string name=\"sort_by_extension\">拡張子</string>\n    <string name=\"sort_by_extension_reversed\">拡張子（逆順）</string>\n    <string name=\"sort_by_date_added\">追加日</string>\n    <string name=\"sort_by_date_added_reversed\">追加日（逆順）</string>\n    <string name=\"left_to_right\">左から右</string>\n    <string name=\"right_to_left\">右から左</string>\n    <string name=\"bottom_to_top\">下から上</string>\n    <string name=\"into_red\">赤色化</string>\n    <string name=\"into_green\">緑色化</string>\n    <string name=\"into_blue\">青色化</string>\n    <string name=\"cyan\">シアン</string>\n    <string name=\"magenta\">マゼンタ</string>\n    <string name=\"yellow\">イエロー</string>\n    <string name=\"red_blue\">マゼンタ系</string>\n    <string name=\"green_red\">イエロー系</string>\n    <string name=\"blue_green\">シアン系</string>\n    <string name=\"channel_mix\">チャンネルミックス</string>\n    <string name=\"disable_rotation\">回転を無効化</string>\n    <string name=\"disable_rotation_sub\">画像の回転機能を無効にします</string>\n    <string name=\"enable_snapping_to_borders\">枠線への吸着を有効化</string>\n    <string name=\"enable_snapping_to_borders_sub\">編集時に要素が枠線に自動的に吸着します</string>\n    <string name=\"liquid_glass\">リキッドグラス</string>\n    <string name=\"liquid_glass_sub\">流動的なガラス効果を画像に適用します</string>\n    <string name=\"pick_image_or_base64\">画像を選択またはBase64データを入力</string>\n    <string name=\"type_image_link\">画像のリンクを入力</string>\n    <string name=\"paste_link\">リンクを貼り付け</string>\n    <string name=\"kaleidoscope\">万華鏡</string>\n    <string name=\"secondary_angle\">副角度</string>\n    <string name=\"sides\">辺の数</string>\n    <string name=\"color_halftone\">カラーハーフトーン</string>\n    <string name=\"contour\">輪郭</string>\n    <string name=\"levels\">レベル</string>\n    <string name=\"offset\">オフセット</string>\n    <string name=\"voronoi_crystallize\">ボロノイ結晶化</string>\n    <string name=\"shape\">形状</string>\n    <string name=\"stretch\">ストレッチ</string>\n    <string name=\"randomness\">ランダム性</string>\n    <string name=\"despeckle\">ノイズ除去</string>\n    <string name=\"diffuse\">拡散</string>\n    <string name=\"dog\">DoG フィルター</string>\n    <string name=\"second_radius\">第2半径</string>\n    <string name=\"equalize\">均等化</string>\n    <string name=\"glow\">グロー</string>\n    <string name=\"whirl_and_pinch\">渦と引き寄せ</string>\n    <string name=\"pointillize\">点描</string>\n    <string name=\"border_color\">枠線の色</string>\n    <string name=\"polar_coordinates\">極座標</string>\n    <string name=\"rect_to_polar\">矩形から極座標へ</string>\n    <string name=\"polar_to_rect\">極座標から矩形へ</string>\n    <string name=\"invert_in_circle\">円内反転</string>\n    <string name=\"reduce_noise\">ノイズ軽減</string>\n    <string name=\"simple_solarize\">シンプルソラライズ</string>\n    <string name=\"weave\">織物</string>\n    <string name=\"x_gap\">X間隔</string>\n    <string name=\"y_gap\">Y間隔</string>\n    <string name=\"x_width\">X幅</string>\n    <string name=\"y_wdth\">Y幅</string>\n    <string name=\"twirl\">ツイスト</string>\n    <string name=\"rubber_stmp\">ゴム印</string>\n    <string name=\"smear\">スミア</string>\n    <string name=\"density\">密度</string>\n    <string name=\"mix\">ミックス</string>\n    <string name=\"sphere_lensh_distortion\">球面レンズ歪み</string>\n    <string name=\"refraction_index\">屈折率</string>\n    <string name=\"arc\">アーク</string>\n    <string name=\"spread_angle\">広がり角度</string>\n    <string name=\"sparkle\">スパークル</string>\n    <string name=\"rays\">光線</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">グラデーション</string>\n    <string name=\"moire\">モアレ</string>\n    <string name=\"autumn\">秋</string>\n    <string name=\"bone\">骨</string>\n    <string name=\"jet\">ジェット</string>\n    <string name=\"winter\">冬</string>\n    <string name=\"ocean\">海</string>\n    <string name=\"summer\">夏</string>\n    <string name=\"spring\">春</string>\n    <string name=\"cool_variant\">クール</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">ピンク</string>\n    <string name=\"hot\">ホット</string>\n    <string name=\"parula\">パルーラ</string>\n    <string name=\"magma\">マグマ</string>\n    <string name=\"inferno\">インフェルノ</string>\n    <string name=\"plasma\">プラズマ</string>\n    <string name=\"viridis\">ビリディス</string>\n    <string name=\"cividis\">シヴィディス</string>\n    <string name=\"twilight\">トワイライト</string>\n    <string name=\"twilight_shifted\">トワイライトシフト</string>\n    <string name=\"auto_perspective\">自動透視変換</string>\n    <string name=\"deskew\">自動傾き補正</string>\n    <string name=\"allow_crop\">切り抜きを許可</string>\n    <string name=\"crop_or_perspective\">切り抜きまたは透視変換を選択</string>\n    <string name=\"absolute\">絶対</string>\n    <string name=\"turbo\">ターボ</string>\n    <string name=\"deep_green\">ディープグリーン</string>\n    <string name=\"lens_correction\">レンズ補正</string>\n    <string name=\"target_lens_profile\">対象レンズプロファイル</string>\n    <string name=\"download_ready_lens_profiles\">利用可能なレンズプロファイルをダウンロード</string>\n    <string name=\"part_percents\">パーセンテージ</string>\n    <string name=\"export_as_json\">JSONとしてエクスポート</string>\n    <string name=\"export_as_json_sub\">編集内容をJSON形式でエクスポートして、後で読み込み直すことができます</string>\n    <string name=\"seam_carving\">シームカービング</string>\n    <string name=\"home_screen\">ホーム画面</string>\n    <string name=\"lock_screen\">ロック画面</string>\n    <string name=\"built_in\">ビルトイン</string>\n    <string name=\"wallpapers_export\">壁紙をエクスポート</string>\n    <string name=\"refresh\">更新</string>\n    <string name=\"wallpapers_export_sub\">編集済みの画像を壁紙として保存します</string>\n    <string name=\"allow_access_to_all_files_for_wp\">壁紙設定のため全ファイルへのアクセスを許可</string>\n    <string name=\"allow_read_media_images_for_wp\">壁紙設定のためメディア画像の読み取りを許可</string>\n    <string name=\"add_preset_to_filename\">プリセット名をファイル名に追加</string>\n    <string name=\"add_preset_to_filename_sub\">保存時にプリセット名を自動的にファイル名に含めます</string>\n    <string name=\"add_image_scale_mode_to_filename\">スケールモードをファイル名に追加</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">保存時にスケールモードを自動的にファイル名に含めます</string>\n    <string name=\"ascii_art\">ASCIIアート</string>\n    <string name=\"ascii_art_sub\">画像をASCII文字アートに変換します</string>\n    <string name=\"params\">パラメーター</string>\n    <string name=\"invert_colors_ascii_sub\">ASCIIアートの色を反転します</string>\n    <string name=\"processing_screenshot\">スクリーンショットを処理中です</string>\n    <string name=\"screenshot_not_captured_try_again\">スクリーンショットの取得に失敗しました。もう一度お試しください</string>\n    <string name=\"skipped_saving\">保存をスキップしました</string>\n    <string name=\"skipped_saving_multiple\">%1$sファイルをスキップしました</string>\n    <string name=\"allow_skip_if_larger\">ファイルサイズが大きい場合は保存をスキップ</string>\n    <string name=\"allow_skip_if_larger_sub\">元のファイルより大きくなる場合は自動的に保存をスキップします</string>\n    <string name=\"qr_type_calendar_event\">カレンダーイベント</string>\n    <string name=\"qr_type_contact_info\">連絡先情報</string>\n    <string name=\"qr_type_email\">メール</string>\n    <string name=\"qr_type_geo_point\">地理的位置</string>\n    <string name=\"qr_type_phone\">電話番号</string>\n    <string name=\"qr_type_plain\">プレーンテキスト</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">オープンネットワーク</string>\n    <string name=\"not_specified\">指定されていません</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">電話番号</string>\n    <string name=\"message\">メッセージ</string>\n    <string name=\"address\">住所</string>\n    <string name=\"subject\">件名</string>\n    <string name=\"body\">本文</string>\n    <string name=\"name\">名前</string>\n    <string name=\"organization\">組織</string>\n    <string name=\"title\">タイトル</string>\n    <string name=\"phones\">電話番号</string>\n    <string name=\"emails\">メールアドレス</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">住所</string>\n    <string name=\"summary\">概要</string>\n    <string name=\"description\">説明</string>\n    <string name=\"location\">場所</string>\n    <string name=\"organizer\">主催者</string>\n    <string name=\"start_date\">開始日</string>\n    <string name=\"end_date\">終了日</string>\n    <string name=\"status\">ステータス</string>\n    <string name=\"latitude\">緯度</string>\n    <string name=\"longitude\">経度</string>\n    <string name=\"create_barcode\">バーコードを作成</string>\n    <string name=\"edit_barcode\">バーコードを編集</string>\n    <string name=\"wifi_configuration\">Wi-Fi設定</string>\n    <string name=\"security\">セキュリティ</string>\n    <string name=\"pick_contact\">連絡先を選択</string>\n    <string name=\"grant_contact_permission\">連絡先へのアクセス許可を付与</string>\n    <string name=\"contact_info\">連絡先情報</string>\n    <string name=\"first_name\">名</string>\n    <string name=\"middle_name\">ミドルネーム</string>\n    <string name=\"last_name\">姓</string>\n    <string name=\"pronunciation\">発音</string>\n    <string name=\"add_phone\">電話番号を追加</string>\n    <string name=\"add_email\">メールアドレスを追加</string>\n    <string name=\"add_address\">住所を追加</string>\n    <string name=\"website\">ウェブサイト</string>\n    <string name=\"add_website\">ウェブサイトを追加</string>\n    <string name=\"formatted_name\">表示名</string>\n    <string name=\"qr_code_top_image\">QRコード上部の画像</string>\n    <string name=\"code_customization\">コードカスタマイズ</string>\n    <string name=\"qr_logo_image\">QRロゴ画像</string>\n    <string name=\"logo\">ロゴ</string>\n    <string name=\"logo_padding\">ロゴパディング</string>\n    <string name=\"logo_size\">ロゴサイズ</string>\n    <string name=\"logo_corners\">ロゴコーナー</string>\n    <string name=\"fourth_eye\">第4の目</string>\n    <string name=\"fourth_eye_description\">QRコード内に追加の位置検出パターンを配置します</string>\n    <string name=\"pixel_shape\">ピクセル形状</string>\n    <string name=\"frame_shape\">フレーム形状</string>\n    <string name=\"ball_shape\">ボール形状</string>\n    <string name=\"error_correction_level\">誤り訂正レベル</string>\n    <string name=\"dark_color\">暗い色</string>\n    <string name=\"light_color\">明るい色</string>\n    <string name=\"hyper_os\">HyperOS</string>\n    <string name=\"hyper_os_sub\">HyperOSデザインシステムに基づいたUIを使用します</string>\n    <string name=\"mask_pattern\">マスクパターン</string>\n    <string name=\"code_may_be_not_scannable\">このコードはスキャンできない可能性があります。すべてのデバイスで読み取れるように外観パラメータを変更してください</string>\n    <string name=\"not_scannable\">スキャン不可</string>\n    <string name=\"launcher_mode_sub\">ツールはホーム画面のアプリランチャーのようになり、よりコンパクトになります</string>\n    <string name=\"launcher_mode\">ランチャーモード</string>\n    <string name=\"flood_fill_sub\">選択したブラシとスタイルで領域を塗りつぶします</string>\n    <string name=\"flood_fill\">塗りつぶし</string>\n    <string name=\"spray\">スプレー</string>\n    <string name=\"spray_sub\">グラフィティスタイルのパスを描画します</string>\n    <string name=\"square_particles\">四角い粒子</string>\n    <string name=\"square_particles_sub\">スプレー粒子は円ではなく正方形になります</string>\n    <string name=\"palette_tools\">パレットツール</string>\n    <string name=\"palette_tools_sub\">画像からパレットに使用するベーシック/マテリアルを生成、またはさまざまなパレット形式でインポート/エクスポート</string>\n    <string name=\"edit_palette\">パレットの編集</string>\n    <string name=\"edit_palette_sub\">さまざまな形式でパレットをエクスポート/インポート</string>\n    <string name=\"color_name\">色の名前</string>\n    <string name=\"palette_name\">パレット名</string>\n    <string name=\"palette_format\">パレットフォーマット</string>\n    <string name=\"export_palette_sub\">生成されたパレットをさまざまな形式でエクスポートする</string>\n    <string name=\"add_color_palette_sub\">現在のパレットに新しい色を追加します</string>\n    <string name=\"palette_name_not_supported\">%1$s 形式はパレット名の指定をサポートしていません</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play ストアのポリシーにより、この機能は現在のビルドに含めることができません。この機能にアクセスするには、別のソースから ImageToolbox をダウンロードしてください。利用可能なビルドは以下の GitHub で見つけることができます。</string>\n    <string name=\"open_github_page\">Githubページを開く</string>\n    <string name=\"overwrite_files_sub_short\">選択したフォルダーに保存されるのではなく、元のファイルが新しいファイルに置き換えられます</string>\n    <string name=\"hidden_watermark_text_detected\">検出された隠し透かしテキスト</string>\n    <string name=\"hidden_watermark_image_detected\">検出された隠し透かし画像</string>\n    <string name=\"this_image_was_hidden\">この画像は非表示にされました</string>\n    <string name=\"generative_inpaint\">ジェネレーティブ・インペインティング</string>\n    <string name=\"generative_inpaint_sub\">OpenCV に依存せずに、AI モデルを使用して画像内のオブジェクトを削除できます。この機能を使用するには、アプリは必要なモデル (約 200 MB) を GitHub からダウンロードします。</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV に依存せずに、AI モデルを使用して画像内のオブジェクトを削除できます。これは長時間実行される操作になる可能性があります</string>\n    <string name=\"error_level_analysis\">エラーレベル分析</string>\n    <string name=\"luminance_gradient\">輝度勾配</string>\n    <string name=\"average_distance\">平均距離</string>\n    <string name=\"copy_move_detection\">コピー移動検出</string>\n    <string name=\"retain\">保持</string>\n    <string name=\"coefficent\">係数</string>\n    <string name=\"clipboard_data_is_too_large\">クリップボードのデータが大きすぎます</string>\n    <string name=\"data_is_too_large_to_copy\">データが大きすぎてコピーできない</string>\n    <string name=\"simple_weave_pixelization\">シンプルな織りのピクセル化</string>\n    <string name=\"staggered_pixelization\">千鳥状ピクセル化</string>\n    <string name=\"cross_pixelization\">クロスピクセル化</string>\n    <string name=\"micro_macro_pixelization\">マイクロマクロピクセル化</string>\n    <string name=\"orbital_pixelization\">軌道ピクセル化</string>\n    <string name=\"vortex_pixelization\">渦ピクセル化</string>\n    <string name=\"pulse_grid_pixelization\">パルスグリッドピクセル化</string>\n    <string name=\"nucleus_pixelization\">核のピクセル化</string>\n    <string name=\"radial_weave_pixelization\">放射状織りピクセル化</string>\n    <string name=\"cannot_open_uri\">URI「%1$s」を開けません</string>\n    <string name=\"snowfall_mode\">降雪モード</string>\n    <string name=\"enabled\">有効</string>\n    <string name=\"border_frame\">ボーダーフレーム</string>\n    <string name=\"glitch_variant\">グリッチのバリアント</string>\n    <string name=\"channel_shift\">チャンネルシフト</string>\n    <string name=\"max_offset\">最大オフセット</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">ブロックグリッチ</string>\n    <string name=\"block_size\">ブロックサイズ</string>\n    <string name=\"crt_curvature\">CRTの曲率</string>\n    <string name=\"curvature\">曲率</string>\n    <string name=\"chroma\">彩度</string>\n    <string name=\"pixel_melt\">ピクセルメルト</string>\n    <string name=\"max_drop\">最大ドロップ</string>\n    <string name=\"ai_tools\">AIツール</string>\n    <string name=\"ai_tools_sub\">アーティファクトの除去やノイズ除去など、AI モデルを通じて画像を処理するためのさまざまなツール</string>\n    <string name=\"model_anime_undeint\">圧縮、ギザギザの線</string>\n    <string name=\"model_broadcast\">漫画、放送圧縮</string>\n    <string name=\"model_rgb_max_denoise_fp16\">一般的な圧縮、一般的なノイズ</string>\n    <string name=\"model_wb_denoise\">無色の漫画のノイズ</string>\n    <string name=\"model_span_anime_pretrain\">高速、一般的な圧縮、一般的なノイズ、アニメーション/コミック/アニメ</string>\n    <string name=\"model_book_scan\">本のスキャン</string>\n    <string name=\"model_overexposure\">露出補正</string>\n    <string name=\"model_fbcnn_color_fp16\">一般的な圧縮、カラー画像に最適</string>\n    <string name=\"model_fbcnn_gray_fp16\">一般的な圧縮、グレースケール画像に最適</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">一般圧縮、グレースケール画像、強力</string>\n    <string name=\"model_scunet_color_gan_fp16\">一般的なノイズ、カラー画像</string>\n    <string name=\"model_scunet_color_psnr_fp16\">一般的なノイズ、カラー画像、より詳細なディテール</string>\n    <string name=\"model_scunet_gray_15_fp16\">一般的なノイズ、グレースケール画像</string>\n    <string name=\"model_scunet_gray_25_fp16\">一般的なノイズ、グレースケール画像、強め</string>\n    <string name=\"model_scunet_gray_50_fp16\">一般的なノイズ、グレースケール画像、最も強い</string>\n    <string name=\"model_jpeg_destroyer\">一般的な圧縮</string>\n    <string name=\"model_jaywreck\">一般的な圧縮</string>\n    <string name=\"model_h264\">テクスチャライゼーション、h264 圧縮</string>\n    <string name=\"model_vhs\">VHS圧縮</string>\n    <string name=\"model_cinepak\">非標準圧縮 (cinepak、msvideo1、roq)</string>\n    <string name=\"model_debink_v4\">ビンク圧縮、ジオメトリでの改善</string>\n    <string name=\"model_debink_v5\">ビンク圧縮、強化</string>\n    <string name=\"model_debink_v6\">ビンク圧縮、ソフト、ディテール保持</string>\n    <string name=\"model_antialias\">階段状の効果を除去し、滑らかにする</string>\n    <string name=\"model_kdm_scans\">スキャンしたアート/図面、軽度の圧縮、モアレ</string>\n    <string name=\"model_bandage\">カラーバンディング</string>\n    <string name=\"model_halftone\">ゆっくりとハーフトーンを除去します</string>\n    <string name=\"model_colorizer\">グレースケール/白黒画像用の一般的なカラーライザー。より良い結果を得るには、DDColor を使用します。</string>\n    <string name=\"model_deedge\">エッジ除去</string>\n    <string name=\"model_desharpen\">過度の研ぎを除去します</string>\n    <string name=\"model_dither\">遅い、ディザリング</string>\n    <string name=\"model_gainres\">アンチエイリアシング、一般的なアーティファクト、CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 スキャン処理</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">軽量画質向上モデル</string>\n    <string name=\"model_bcgone_detailed_v2\">圧縮アーティファクトの除去</string>\n    <string name=\"model_bcgone_smooth\">圧縮アーティファクトの除去</string>\n    <string name=\"model_bandage_smooth\">スムーズな結果による包帯除去</string>\n    <string name=\"model_bendel_halftone\">ハーフトーンパターン処理</string>\n    <string name=\"model_dither_deleter_v3_smooth\">ディザパターン除去V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEGアーチファクト除去V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 テクスチャの強化</string>\n    <string name=\"model_vhs_sharpen\">VHS のシャープ化と強化</string>\n    <string name=\"merging\">結合</string>\n    <string name=\"chunk_size\">チャンクサイズ</string>\n    <string name=\"overlap_size\">オーバーラップサイズ</string>\n    <string name=\"note_chunk_info\">%1$s ピクセルを超える画像はスライスされてチャンクに処理され、継ぎ目が見えないようにこれらをオーバーラップ ブレンドします。</string>\n    <string name=\"large_chunk_warning\">サイズが大きいと、ローエンド デバイスで不安定になる可能性があります</string>\n    <string name=\"select_one_to_start\">開始するには 1 つを選択してください</string>\n    <string name=\"delete_model_sub\">%1$s モデルを削除しますか?再度ダウンロードする必要があります</string>\n    <string name=\"confirm\">確認する</string>\n    <string name=\"models\">モデル</string>\n    <string name=\"downloaded_models\">ダウンロードしたモデル</string>\n    <string name=\"available_models\">利用可能なモデル</string>\n    <string name=\"preparing\">準備中</string>\n    <string name=\"active_model\">アクティブモデル</string>\n    <string name=\"failed_to_open_session\">セッションを開けませんでした</string>\n    <string name=\"only_onnx_models\">.onnx/.ort モデルのみインポート可能</string>\n    <string name=\"import_model\">インポートモデル</string>\n    <string name=\"import_model_sub\">さらに使用するためにカスタム onnx モデルをインポートします。onnx/ort モデルのみが受け入れられ、ほぼすべての esrgan のようなバリアントをサポートします。</string>\n    <string name=\"imported_models\">輸入モデル</string>\n    <string name=\"model_scunet_color_15_fp16\">一般的なノイズ、カラー画像</string>\n    <string name=\"model_scunet_color_25_fp16\">一般的なノイズ、カラー画像、強め</string>\n    <string name=\"model_scunet_color_50_fp16\">一般的なノイズ、カラー画像、最強</string>\n    <string name=\"model_artifacts_dithering_alsa\">ディザリングアーティファクトとカラーバンディングを軽減し、滑らかなグラデーションと平坦なカラー領域を改善します。</string>\n    <string name=\"model_nmkd_brighten_redux\">自然な色を維持しながら、バランスの取れたハイライトで画像の明るさとコントラストを強化します。</string>\n    <string name=\"model_nmkd_brighten\">暗い画像を細部を維持し、露出オーバーを避けながら明るくします。</string>\n    <string name=\"model_nmkd_detoon\">過度な色調を除去し、よりニュートラルで自然なカラーバランスを取り戻します。</string>\n    <string name=\"model_noise_toner_poisson_detailed\">細かいディテールとテクスチャの維持に重点を置いて、ポアソン ベースのノイズ トーンを適用します。</string>\n    <string name=\"model_noise_toner_poisson_soft\">ソフトなポアソン ノイズ トーンを適用して、よりスムーズで攻撃性の低い視覚的な結果を実現します。</string>\n    <string name=\"model_noise_toner_uniform_detailed\">均一なノイズ調色は、ディテールの維持と画像の鮮明さに重点を置いています。</string>\n    <string name=\"model_noise_toner_uniform_soft\">穏やかで均一なノイズ調色により、繊細な質感と滑らかな外観を実現します。</string>\n    <string name=\"model_repainter\">アーティファクトを再描画し、画像の一貫性を向上させることで、損傷した領域や不均一な領域を修復します。</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">最小限のパフォーマンスコストでカラーバンディングを除去する軽量デバンディングモデル。</string>\n    <string name=\"model_jpeg_0_20\">非常に高圧縮アーティファクト (品質 0 ～ 20%) を含む画像を最適化し、鮮明さを向上させます。</string>\n    <string name=\"model_jpeg_20_40\">高圧縮アーティファクト (品質 20 ～ 40%) で画像を強化し、詳細を復元し、ノイズを低減します。</string>\n    <string name=\"model_jpeg_40_60\">適度な圧縮 (品質 40 ～ 60%) で画像を改善し、鮮明さと滑らかさのバランスをとります。</string>\n    <string name=\"model_jpeg_60_80\">軽い圧縮 (60 ～ 80% の品質) で画像を洗練し、微妙なディテールやテクスチャを強調します。</string>\n    <string name=\"model_jpeg_80_100\">自然な外観と詳細を維持しながら、ほぼ損失のない画像 (80 ～ 100% の品質) をわずかに向上させます。</string>\n    <string name=\"model_spongecolor_lite\">シンプルで素早いカラー化、漫画、理想的ではない</string>\n    <string name=\"model_deblr\">画像のぼやけをわずかに軽減し、アーティファクトを発生させることなくシャープネスを向上させます。</string>\n    <string name=\"processing_channel\">長時間実行される操作</string>\n    <string name=\"processing_image\">画像処理中</string>\n    <string name=\"processing\">処理</string>\n    <string name=\"model_artifacts_jpg_0_20\">非常に低品質の画像 (0 ～ 20%) に含まれる重い JPEG 圧縮アーティファクトを除去します。</string>\n    <string name=\"model_artifacts_jpg_20_40\">高圧縮画像内の強力な JPEG アーティファクトを軽減します (20 ～ 40%)。</string>\n    <string name=\"model_artifacts_jpg_40_60\">画像の詳細 (40 ～ 60%) を維持しながら、中程度の JPEG アーティファクトをクリーンアップします。</string>\n    <string name=\"model_artifacts_jpg_60_80\">軽い JPEG アーティファクトをかなり高品質の画像 (60 ～ 80%) に調整します。</string>\n    <string name=\"model_artifacts_jpg_80_100\">ほぼロスレス画像の小さな JPEG アーティファクトを微妙に軽減します (80 ～ 100%)。</string>\n    <string name=\"model_redetail_v2\">細かいディテールとテクスチャを強化し、大きなアーティファクトを発生させることなく知覚されるシャープネスを向上させます。</string>\n    <string name=\"processing_finished\">処理が完了しました</string>\n    <string name=\"processing_failed\">処理に失敗しました</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">自然な外観を維持しながら肌のテクスチャとディテールを強化し、速度を最適化します。</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG 圧縮アーティファクトを除去し、圧縮された写真の画質を復元します。</string>\n    <string name=\"model_iso_denoise_v1\">暗い場所で撮影した写真の ISO ノイズを低減し、ディテールを維持します。</string>\n    <string name=\"model_dejumbo\">露出過度または「ジャンボ」ハイライトを修正し、より良い色調バランスを復元します。</string>\n    <string name=\"model_ddcolor_tiny\">グレースケール画像に自然な色を追加する、軽量かつ高速なカラー化モデル。</string>\n    <string name=\"type_dejpeg\">デジェペグ</string>\n    <string name=\"type_denoise\">ノイズ除去</string>\n    <string name=\"type_colorize\">色付け</string>\n    <string name=\"type_artifacts\">アーティファクト</string>\n    <string name=\"type_enhance\">強化する</string>\n    <string name=\"type_anime\">アニメ</string>\n    <string name=\"type_scans\">スキャン</string>\n    <string name=\"type_upscale\">高級感のある</string>\n    <string name=\"model_realesrgan_x4v3\">一般画像用の X4 アップスケーラ。 GPU の使用量と時間が少なく、適度なブラー除去とノイズ除去を備えた小型モデル。</string>\n    <string name=\"model_realesrgan_x2plus\">テクスチャと自然なディテールを維持する、一般的な画像用の X2 アップスケーラー。</string>\n    <string name=\"model_realesrgan_x4plus\">強化されたテクスチャとリアルな結果を備えた一般画像用の X4 アップスケーラー。</string>\n    <string name=\"model_realesrgan_x4plus_anime\">アニメ画像に最適化された X4 アップスケーラー。 6 つの RRDB ブロックにより、より鮮明なラインとディテールが実現します。</string>\n    <string name=\"model_realesrnet_x4plus\">MSE 損失を備えた X4 アップスケーラーは、よりスムーズな結果を生成し、一般的な画像のアーティファクトを軽減します。</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">アニメ画像に最適化された X4 アップスケーラー。よりシャープなディテールと滑らかなラインを備えた 4B32F バリアント。</string>\n    <string name=\"model_ultrasharp_v2_x4\">一般画像用の X4 UltraSharp V2 モデル。シャープさと明瞭さを強調します。</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4デジタルハイエンドシリーズV2ライト。高速かつ小型で、GPU メモリの使用量を減らしながらディテールを維持します。</string>\n    <string name=\"model_rmbg_1_4\">素早い背景除去が可能な軽量モデル。バランスのとれたパフォーマンスと精度。ポートレート、オブジェクト、シーンに使用します。ほとんどの使用例に推奨されます。</string>\n    <string name=\"type_removebg\">BGを削除する</string>\n    <string name=\"horizontal_border_thickness\">水平方向の境界線の太さ</string>\n    <string name=\"vertical_border_thickness\">垂直方向の境界線の太さ</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s色</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">現在のモデルはチャンキングをサポートしていません。画像は元のサイズで処理されます。これにより、メモリ消費量が多くなり、ローエンド デバイスで問題が発生する可能性があります。</string>\n    <string name=\"chunking_disabled\">チャンキングが無効になっていると、画像は元のサイズで処理されます。これにより、メモリ消費量が多くなり、ローエンド デバイスで問題が発生する可能性がありますが、推論ではより良い結果が得られる可能性があります。</string>\n    <string name=\"chunking\">チャンク化</string>\n    <string name=\"model_u2net\">背景除去のための高精度画像セグメンテーションモデル</string>\n    <string name=\"model_u2netp\">少ないメモリ使用量で高速にバックグラウンドを削除できる U2Net の軽量バージョン。</string>\n    <string name=\"model_ddcolor\">完全な DDColor モデルは、アーティファクトを最小限に抑えながら、一般的な画像に対して高品質のカラー化を実現します。すべてのカラー化モデルの中で最良の選択。</string>\n    <string name=\"model_ddcolor_artistic\">DDColor トレーニング済みのプライベート芸術データセット。非現実的な色のアーティファクトが少なく、多様で芸術的な色付け結果が得られます。</string>\n    <string name=\"model_birefnet\">正確な背景除去のための Swin Transformer に基づく軽量 BiRefNet モデル。</string>\n    <string name=\"model_inspyrenet\">特に複雑なオブジェクトや扱いにくい背景において、シャープなエッジと優れたディテール保持による高品質の背景除去。</string>\n    <string name=\"model_isnet\">滑らかなエッジを持つ正確なマスクを生成する背景除去モデル。一般的なオブジェクトと適度なディテールの保持に適しています。</string>\n    <string name=\"model_already_downloaded\">モデルはすでにダウンロードされています</string>\n    <string name=\"model_successfully_imported\">モデルは正常にインポートされました</string>\n    <string name=\"type\">タイプ</string>\n    <string name=\"keyword\">キーワード</string>\n    <string name=\"very_fast\">非常に速い</string>\n    <string name=\"normal\">普通</string>\n    <string name=\"slow\">遅い</string>\n    <string name=\"very_slow\">非常に遅い</string>\n    <string name=\"compute_percents\">パーセントを計算する</string>\n    <string name=\"minimum_value_is\">最小値は %1$s です</string>\n    <string name=\"warp_sub\">指で描いて画像を歪ませる</string>\n    <string name=\"warp\">ワープ</string>\n    <string name=\"hardness\">硬度</string>\n    <string name=\"warp_mode\">ワープモード</string>\n    <string name=\"warp_mode_move\">動く</string>\n    <string name=\"warp_mode_grow\">育つ</string>\n    <string name=\"warp_mode_shrink\">縮む</string>\n    <string name=\"warp_mode_swirl_cw\">CWに旋回</string>\n    <string name=\"warp_mode_swirl_ccw\">反時計回りに旋回</string>\n    <string name=\"fade_strength\">フェード強度</string>\n    <string name=\"top_drop\">トップドロップ</string>\n    <string name=\"bottom_drop\">ボトムドロップ</string>\n    <string name=\"start_drop\">スタートドロップ</string>\n    <string name=\"end_drop\">エンドドロップ</string>\n    <string name=\"downloading\">ダウンロード中</string>\n    <string name=\"smooth_shapes\">滑らかな形状</string>\n    <string name=\"smooth_shapes_sub\">より滑らかで自然な形状を得るには、標準の角丸長方形の代わりに超楕円を使用します。</string>\n    <string name=\"shape_type\">形状タイプ</string>\n    <string name=\"cut\">カット</string>\n    <string name=\"rounded\">丸い</string>\n    <string name=\"smooth\">スムーズ</string>\n    <string name=\"cut_shapes_sub\">丸みのないシャープなエッジ</string>\n    <string name=\"rounded_shapes_sub\">クラシックな丸い角</string>\n    <string name=\"shapes_type\">形状の種類</string>\n    <string name=\"corners_size\">コーナーサイズ</string>\n    <string name=\"squircle\">スクワクル</string>\n    <string name=\"squircle_shapes_sub\">エレガントな丸みを帯びた UI 要素</string>\n    <string name=\"filename_format\">ファイル名の形式</string>\n    <string name=\"prefix_pattern_description\">ファイル名の先頭に配置されるカスタム テキスト。プロジェクト名、ブランド、個人タグに最適です。</string>\n    <string name=\"original_filename_pattern_description\">拡張子なしの元のファイル名を使用するため、ソースの識別をそのまま維持できます。</string>\n    <string name=\"width_pattern_description\">ピクセル単位の画像幅。解像度の変更の追跡や結果のスケーリングに役立ちます。</string>\n    <string name=\"height_pattern_description\">画像の高さ (ピクセル単位)。アスペクト比やエクスポートを操作するときに役立ちます。</string>\n    <string name=\"random_numbers_pattern_description\">ランダムな数字を生成して、一意のファイル名を保証します。重複に対する安全性を高めるために、さらに桁を追加します。</string>\n    <string name=\"sequence_number_pattern_description\">バッチエクスポート用の自動インクリメントカウンター。1 つのセッションで複数の画像を保存する場合に最適です。</string>\n    <string name=\"preset_info_pattern_description\">適用されたプリセット名をファイル名に挿入すると、画像がどのように処理されたかを簡単に思い出すことができます。</string>\n    <string name=\"scale_mode_pattern_description\">処理中に使用される画像スケーリング モードを表示し、サイズ変更、トリミング、またはフィットした画像を区別するのに役立ちます。</string>\n    <string name=\"suffix_pattern_description\">ファイル名の末尾に配置されるカスタム テキスト。_v2、_edited、_final などのバージョン管理に役立ちます。</string>\n    <string name=\"extension_pattern_description\">ファイル拡張子 (png、jpg、webp など) は、実際に保存された形式に自動的に一致します。</string>\n    <string name=\"formatted_timestamp_pattern_description\">カスタマイズ可能なタイムスタンプを使用すると、完璧な並べ替えのために Java 仕様に従って独自の形式を定義できます。</string>\n    <string name=\"fling_type\">フリングタイプ</string>\n    <string name=\"android_native\">Androidネイティブ</string>\n    <string name=\"ios_style\">iOSスタイル</string>\n    <string name=\"smooth_curve\">滑らかな曲線</string>\n    <string name=\"quick_stop\">クイックストップ</string>\n    <string name=\"bouncy\">弾む</string>\n    <string name=\"floaty\">ふわふわ</string>\n    <string name=\"snappy\">キビキビ</string>\n    <string name=\"ultra_smooth\">ウルトラスムーズ</string>\n    <string name=\"adaptive\">アダプティブ</string>\n    <string name=\"accessibility_aware\">アクセシビリティを意識した</string>\n    <string name=\"reduced_motion\">モーションの軽減</string>\n    <string name=\"android_native_sub\">Android のネイティブ スクロール物理学</string>\n    <string name=\"smooth_sub\">一般的な用途向けのバランスの取れたスムーズなスクロール</string>\n    <string name=\"ios_style_sub\">摩擦が大きい iOS のようなスクロール動作</string>\n    <string name=\"smooth_curve_sub\">独特のスプライン曲線で独特のスクロール感を実現</string>\n    <string name=\"quick_stop_sub\">正確なスクロールと素早い停止</string>\n    <string name=\"bouncy_sub\">遊び心のある、応答性の高い弾むスクロール</string>\n    <string name=\"floaty_sub\">コンテンツ閲覧のための長くて滑らかなスクロール</string>\n    <string name=\"snappy_sub\">インタラクティブ UI の迅速で応答性の高いスクロール</string>\n    <string name=\"ultra_smooth_sub\">勢いを増したプレミアムでスムーズなスクロール</string>\n    <string name=\"adaptive_sub\">飛行速度に基づいて物理を調整します</string>\n    <string name=\"accessibility_aware_sub\">システムのアクセシビリティ設定を尊重します</string>\n    <string name=\"reduced_motion_sub\">アクセシビリティのニーズに合わせた最小限の動き</string>\n    <string name=\"primary_lines\">プライマリライン</string>\n    <string name=\"primary_lines_sub\">5行ごとに太い線を追加します</string>\n    <string name=\"fill_color\">塗りつぶしの色</string>\n    <string name=\"hidden_tools\">隠しツール</string>\n    <string name=\"hidden_for_share\">共有用に非表示になっているツール</string>\n    <string name=\"color_library\">カラーライブラリ</string>\n    <string name=\"color_library_sub\">膨大な色のコレクションを閲覧する</string>\n    <string name=\"model_fatality_deblur\">自然なディテールを維持しながら、画像のぼやけを鮮明にして除去します。焦点の合っていない写真を修正するのに最適です。</string>\n    <string name=\"model_unresize_v3\">以前にサイズ変更された画像をインテリジェントに復元し、失われたディテールやテクスチャを復元します。</string>\n    <string name=\"model_liveaction_v1_span\">実写コンテンツ用に最適化されており、圧縮アーチファクトが軽減され、映画/テレビ番組のフレームの細部が強調されます。</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS 品質の映像を HD に変換し、テープノイズを除去し、ヴィンテージ感を維持しながら解像度を高めます。</string>\n    <string name=\"model_text2hd_v1\">テキストの多い画像やスクリーンショットに特化しており、文字を鮮明にして読みやすさを向上させます。</string>\n    <string name=\"model_frankendata_pretrainer\">多様なデータセットでトレーニングされた高度なアップスケーリングで、汎用の写真補正に優れています。</string>\n    <string name=\"model_realwebphoto_v2\">Web 圧縮された写真用に最適化され、JPEG アーティファクトを除去し、自然な外観を復元します。</string>\n    <string name=\"model_realwebphoto_v4\">テクスチャの保存とアーティファクトの削減が向上した、Web 写真用の改良版。</string>\n    <string name=\"model_dat_2x\">Dual Aggregation Transformer テクノロジーによる 2 倍のアップスケーリングにより、鮮明さと自然なディテールが維持されます。</string>\n    <string name=\"model_dat_3x\">高度なトランス アーキテクチャを使用した 3 倍のアップスケーリングは、中程度の拡大ニーズに最適です。</string>\n    <string name=\"model_dat_4x\">最先端のトランスネットワークによる 4 倍の高品質アップスケーリングにより、大規模なスケールでも微細なディテールを維持します。</string>\n    <string name=\"model_nafnet_deblurring\">写真のブレやノイズ、手ぶれを除去します。汎用ですが写真に最適です。</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">BSRGAN の劣化に対して最適化された Swin2SR トランスフォーマーを使用して低品質の画像を復元します。重度の圧縮アーティファクトを修正し、4 倍スケールで細部を強調するのに最適です。</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN 劣化でトレーニングされた SwinIR トランスフォーマーによる 4 倍のアップスケーリング。 GAN を使用して、写真や複雑なシーンのより鮮明なテクスチャとより自然なディテールを実現します。</string>\n    <string name=\"path\">パス</string>\n    <string name=\"merge_pdf\">PDFを結合</string>\n    <string name=\"merge_pdf_sub\">複数の PDF ファイルを 1 つのドキュメントに結合する</string>\n    <string name=\"files_order\">ファイルの順序</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">PDFの分割</string>\n    <string name=\"split_pdf_sub\">PDFドキュメントから特定のページを抽出</string>\n    <string name=\"rotate_pdf\">PDFを回転する</string>\n    <string name=\"rotate_pdf_sub\">ページの向きを永続的に修正する</string>\n    <string name=\"pages\">ページ</string>\n    <string name=\"rearrange_pdf\">PDF を並べ替える</string>\n    <string name=\"rearrange_pdf_sub\">ページをドラッグ アンド ドロップして順序を変更します</string>\n    <string name=\"hold_drag_drop\">ページを押したままドラッグ</string>\n    <string name=\"page_numbers\">ページ番号</string>\n    <string name=\"page_numbers_sub\">文書に番号を自動的に追加する</string>\n    <string name=\"label_format\">ラベルフォーマット</string>\n    <string name=\"pdf_to_text\">PDF からテキストへ (OCR)</string>\n    <string name=\"pdf_to_text_sub\">PDF ドキュメントからプレーンテキストを抽出する</string>\n    <string name=\"watermark_pdf_sub\">ブランドまたはセキュリティのためのオーバーレイカスタムテキスト</string>\n    <string name=\"signature\">サイン</string>\n    <string name=\"signature_sub\">あらゆる文書に電子署名を追加します</string>\n    <string name=\"will_be_for_signature\">これは署名として使用されます</string>\n    <string name=\"unlock_pdf\">PDFのロックを解除する</string>\n    <string name=\"unlock_pdf_sub\">保護されたファイルからパスワードを削除する</string>\n    <string name=\"protect_pdf\">PDFを保護する</string>\n    <string name=\"protect_pdf_sub\">強力な暗号化でドキュメントを保護する</string>\n    <string name=\"success\">成功</string>\n    <string name=\"pdf_unlocked\">PDF のロックが解除され、保存または共有できます</string>\n    <string name=\"repair_pdf\">PDFを修復する</string>\n    <string name=\"repair_pdf_sub\">破損した文書または判読不能な文書を修復してみます</string>\n    <string name=\"grayscale\">グレースケール</string>\n    <string name=\"grayscale_pdf_sub\">すべてのドキュメントに埋め込まれた画像をグレースケールに変換します</string>\n    <string name=\"compress_pdf\">PDFを圧縮する</string>\n    <string name=\"compress_pdf_sub\">ドキュメントのファイル サイズを最適化して共有しやすくします</string>\n    <string name=\"repair_info\">ImageToolbox は内部相互参照テーブルを再構築し、ファイル構造を最初から再生成します。これにより、「開けない」多くのファイルへのアクセスを復元できます。</string>\n    <string name=\"grayscale_info\">このツールはすべての文書画像をグレースケールに変換します。印刷やファイルサイズの縮小に最適</string>\n    <string name=\"metadata\">メタデータ</string>\n    <string name=\"metadata_pdf_sub\">プライバシーを向上させるためにドキュメントのプロパティを編集する</string>\n    <string name=\"tags\">タグ</string>\n    <string name=\"producer\">プロデューサー</string>\n    <string name=\"author\">著者</string>\n    <string name=\"keywords\">キーワード</string>\n    <string name=\"creator\">クリエイター</string>\n    <string name=\"privacy_deep_clean\">プライバシーのディープクリーン</string>\n    <string name=\"privacy_deep_clean_sub\">このドキュメントの利用可能なメタデータをすべてクリアします</string>\n    <string name=\"page\">ページ</string>\n    <string name=\"deep_ocr\">ディープ OCR</string>\n    <string name=\"deep_ocr_sub\">Tesseract エンジンを使用してドキュメントからテキストを抽出し、1 つのテキスト ファイルに保存します</string>\n    <string name=\"cant_remove_all\">すべてのページを削除できません</string>\n    <string name=\"remove_pages_pdf\">PDF ページを削除する</string>\n    <string name=\"remove_pages_pdf_sub\">PDF ドキュメントから特定のページを削除する</string>\n    <string name=\"tap_to_remove\">タップして削除</string>\n    <string name=\"manually\">手動で</string>\n    <string name=\"crop_pdf\">PDFのトリミング</string>\n    <string name=\"crop_pdf_sub\">ドキュメントページを任意の境界にトリミング</string>\n    <string name=\"flatten_pdf\">PDF を平坦化する</string>\n    <string name=\"flatten_pdf_sub\">文書ページをラスター化して PDF を変更不可能にする</string>\n    <string name=\"camera_failed_to_open\">カメラを起動できませんでした。権限を確認し、別のアプリによって使用されていないことを確認してください。</string>\n    <string name=\"extract_images\">画像の抽出</string>\n    <string name=\"extract_images_sub\">PDFに埋め込まれた画像を元の解像度で抽出します</string>\n    <string name=\"pdf_no_embedded\">この PDF ファイルには埋め込み画像が含まれていません</string>\n    <string name=\"extract_images_info\">このツールはすべてのページをスキャンし、フル品質のソース画像を復元します。ドキュメントからオリジナルを保存するのに最適です。</string>\n    <string name=\"draw_signature\">署名を描く</string>\n    <string name=\"pen_params\">ペンパラメータ</string>\n    <string name=\"draw_signature_sub\">自分の署名を文書に配置する画像として使用する</string>\n    <string name=\"zip_pdf\">PDF を圧縮</string>\n    <string name=\"zip_pdf_sub\">指定された間隔でドキュメントを分割し、新しいドキュメントを zip アーカイブに圧縮します</string>\n    <string name=\"interval\">間隔</string>\n    <string name=\"print_pdf\">PDFを印刷する</string>\n    <string name=\"print_pdf_sub\">カスタム ページ サイズで印刷するドキュメントを準備する</string>\n    <string name=\"pages_per_sheet\">シートあたりのページ数</string>\n    <string name=\"orientation\">向き</string>\n    <string name=\"page_size\">ページサイズ</string>\n    <string name=\"margin\">マージン</string>\n    <string name=\"bloom\">咲く</string>\n    <string name=\"soft_knee\">ソフトニー</string>\n    <string name=\"model_realesr_animevideo_v3x4\">アニメや漫画向けに最適化されています。改善された自然な色と少ないアーティファクトによる高速アップスケーリング</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 のようなスタイル</string>\n    <string name=\"calculate_hint\">ここに基本的な数学記号を入力して、目的の値を計算します (例: (5+5)*10)</string>\n    <string name=\"math_expression\">数学式</string>\n    <string name=\"pick_up_to_n_collage_images\">最大 %1$s 枚の画像を選択します</string>\n    <string name=\"keep_date_time\">日付時刻を保持する</string>\n    <string name=\"keep_date_time_sub\">日付と時刻に関連する exif タグを常に保持し、exif を保持するオプションとは独立して機能します。</string>\n    <string name=\"background_color_for_alpha_formats\">アルファ形式の背景色</string>\n    <string name=\"background_color_for_alpha_formats_sub\">アルファサポートを使用してすべての画像フォーマットの背景色を設定する機能を追加します。無効にすると、アルファ以外のフォーマットでのみ使用できます。</string>\n    <string name=\"open_markup_project\">プロジェクトを開く</string>\n    <string name=\"open_markup_project_sub\">以前に保存した Image Toolbox プロジェクトの編集を続行する</string>\n    <string name=\"markup_project_open_failed\">Image Toolbox プロジェクトを開けません</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox プロジェクトにプロジェクト データがありません</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox プロジェクトが破損しています</string>\n    <string name=\"unsupported_markup_project_version\">サポートされていない Image Toolbox プロジェクト バージョン: %1$d</string>\n    <string name=\"save_markup_project\">プロジェクトの保存</string>\n    <string name=\"save_markup_project_sub\">レイヤー、背景、編集履歴を編集可能なプロジェクト ファイルに保存</string>\n    <string name=\"failed_to_open\">開けませんでした</string>\n    <string name=\"ocr_write_to_searchable_pdf\">検索可能な PDF に書き込む</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">画像バッチからテキストを認識し、画像と選択可能なテキストレイヤーを含む検索可能な PDF を保存します</string>\n    <string name=\"layer_alpha\">レイヤーアルファ</string>\n    <string name=\"horizontal_flip\">水平反転</string>\n    <string name=\"vertical_flip\">垂直反転</string>\n    <string name=\"lock\">ロック</string>\n    <string name=\"add_shadow\">影を追加する</string>\n    <string name=\"shadow_color\">影の色</string>\n    <string name=\"text_geometry\">テキストジオメトリ</string>\n    <string name=\"text_geometry_sub\">テキストを引き伸ばしたり傾けたりして、よりシャープなスタイルを実現します</string>\n    <string name=\"scale_x\">スケールX</string>\n    <string name=\"skew_x\">スキューX</string>\n    <string name=\"remove_annotations\">注釈を削除する</string>\n    <string name=\"remove_annotations_sub\">リンク、コメント、ハイライト、図形、フォームフィールドなどの選択した注釈タイプを PDF ページから削除します</string>\n    <string name=\"annotation_link\">ハイパーリンク</string>\n    <string name=\"annotation_file_attachment\">添付ファイル</string>\n    <string name=\"annotation_line\">ライン</string>\n    <string name=\"annotation_popup\">ポップアップ</string>\n    <string name=\"annotation_stamp\">スタンプ</string>\n    <string name=\"annotation_shapes\">形状</string>\n    <string name=\"annotation_text\">テキストメモ</string>\n    <string name=\"annotation_text_markup\">テキストのマークアップ</string>\n    <string name=\"annotation_widget\">フォームフィールド</string>\n    <string name=\"annotation_markup\">マークアップ</string>\n    <string name=\"annotation_unknown\">未知</string>\n    <string name=\"annotations\">注釈</string>\n    <string name=\"ungroup\">グループを解除する</string>\n    <string name=\"add_shadow_sub\">構成可能な色とオフセットを使用してレイヤーの後ろにぼかしシャドウを追加します</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-kk/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"updates\">Жаңартулар</string>\n    <string name=\"palette\">Палитра</string>\n    <string name=\"image_not_saved_sub\">Қазір шықсаңыз, барлық сақталмаған өңдеме жоғалады</string>\n    <string name=\"about_app\">Қолданба туралы</string>\n    <string name=\"pick_file_to_start\">Бастау үшін файл таңдаңыз</string>\n    <string name=\"images\">Суреттер: %d</string>\n    <string name=\"close\">Шығу</string>\n    <string name=\"save\">Сақтау</string>\n    <string name=\"color_blue\">Көк</string>\n    <string name=\"reset\">Арылту</string>\n    <string name=\"compare\">Салыстыру</string>\n    <string name=\"add_original_filename\">Түпнұсқа файл атауын қосу</string>\n    <string name=\"nature_and_animals\">Табиғат пен жануар</string>\n    <string name=\"original\">Түпнұсқа</string>\n    <string name=\"wait\">Күте тұрыңыз</string>\n    <string name=\"food_and_drink\">Тағам мен сусын</string>\n    <string name=\"no_image\">Сурет жоқ</string>\n    <string name=\"app_closing\">Қолданбадан шығу</string>\n    <string name=\"cache\">Кәш</string>\n    <string name=\"rainbow\">Кемпірқосақ</string>\n    <string name=\"zoom\">Сурет үлкейту</string>\n    <string name=\"angle\">Бұрыш</string>\n    <string name=\"pick_image_alt\">Сурет таңдау</string>\n    <string name=\"image_stitching\">Суреттерді біріктіру</string>\n    <string name=\"pdf_tools\">PDF құралдары</string>\n    <string name=\"font_scale\">Қаріп өлшемі</string>\n    <string name=\"height\">Биіктігі %1$s</string>\n    <string name=\"color_green\">Жасыл</string>\n    <string name=\"black_and_white\">Ақ-қара</string>\n    <string name=\"clear\">Тазарту</string>\n    <string name=\"app_closing_sub\">Қолданбадан шығасыз ба?</string>\n    <string name=\"clear_exif\">EXIF тазарту</string>\n    <string name=\"screenshot\">Скриншот</string>\n    <string name=\"radius\">Радиус</string>\n    <string name=\"restart_app\">Қолданбаны қайта қосу</string>\n    <string name=\"pick_two_images\">Бастау үшін екі сурет таңдаңыз</string>\n    <string name=\"image_not_saved\">Сақтауда</string>\n    <string name=\"edit\">Өңдеу</string>\n    <string name=\"copy\">Көшіру</string>\n    <string name=\"update\">Жаңарту</string>\n    <string name=\"pick_color\">Түс таңдау</string>\n    <string name=\"keep_exif\">EXIF сақтау</string>\n    <string name=\"alphabet_and_numbers\">Аа Әә Бб Вв Гг Ғғ Дд Ее Ёё Жж Зз Ии Йй Кк Ққ Лл Мм Нн Ңң Оо Өө Пп Рр Сс Тт Уу Ұұ Үү Фф Хх Һһ Цц Чч Шш Щщ Ъъ Ыы Іі Ьь Ээ Юю Яя 0123456789 !?</string>\n    <string name=\"search_option\">Іздеу</string>\n    <string name=\"filename\">Файл атауы</string>\n    <string name=\"replace_color\">Түсті ауыстыру</string>\n    <string name=\"image\">Сурет</string>\n    <string name=\"presets\">Үлгілер</string>\n    <string name=\"delete\">Жою</string>\n    <string name=\"delete_exif\">EXIF жою</string>\n    <string name=\"gamma\">Гамма</string>\n    <string name=\"version\">Нұсқа</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">ОК</string>\n    <string name=\"copied\">Алмасу буферіне көшірілді</string>\n    <string name=\"help_translate\">Аударуға көмектесу</string>\n    <string name=\"rgb_filter\">RGB сүзгісі</string>\n    <string name=\"skip\">Өткізу</string>\n    <string name=\"add_tag\">Тег қосу</string>\n    <string name=\"backup\">Сақтық көшірме</string>\n    <string name=\"contrast\">Кереғарлық</string>\n    <string name=\"cache_size\">Кәш өлшемі</string>\n    <string name=\"pick_image\">Бастау үшін сурет таңдаңыз</string>\n    <string name=\"masks\">Маскалар</string>\n    <string name=\"color_copied\">Түс көшірілді</string>\n    <string name=\"image_preview\">Алдын ала қарау</string>\n    <string name=\"sepia\">Сепия</string>\n    <string name=\"check_source_code\">Бастапқы коды</string>\n    <string name=\"preview_pdf\">PDF алдын ала қарау</string>\n    <string name=\"width\">Ені %1$s</string>\n    <string name=\"cancel\">Болдырмау</string>\n    <string name=\"check_for_updates\">Жаңартуларды тексеру</string>\n    <string name=\"pipette\">Тамызғыш</string>\n    <string name=\"stay\">Қалу</string>\n    <string name=\"failed_to_save\">%d сурет сақталмады</string>\n    <string name=\"amoled_mode\">Amoled режімі</string>\n    <string name=\"disabled\">Сөндірулі</string>\n    <string name=\"language\">Тіл</string>\n    <string name=\"symbols\">Таңба</string>\n    <string name=\"tools\">Құралдар</string>\n    <string name=\"file_size\">Файл өлшемі</string>\n    <string name=\"def\">Әдепкі</string>\n    <string name=\"enable_emoji\">Эмоджи қосу</string>\n    <string name=\"key\">Кілт</string>\n    <string name=\"saturation\">Қанықтық</string>\n    <string name=\"permission\">Рұқсат</string>\n    <string name=\"settings\">Баптау</string>\n    <string name=\"objects\">Зат</string>\n    <string name=\"randomize_filename\">Кездейсоқ файл атауы</string>\n    <string name=\"loading\">Жүктелуде…</string>\n    <string name=\"image_link\">Сурет сілтемесі</string>\n    <string name=\"text\">Мәтін</string>\n    <string name=\"defaultt\">Әдепкі</string>\n    <string name=\"font\">Қаріп</string>\n    <string name=\"exception\">Айрықшалық</string>\n    <string name=\"edit_screenshot\">Скриншот өңдеу</string>\n    <string name=\"no_exif\">EXIF деректері табылмады</string>\n    <string name=\"night_mode\">Түнгі режім</string>\n    <string name=\"palette_style\">Палитра стилі</string>\n    <string name=\"brightness\">Жарықтық</string>\n    <string name=\"encrypt\">Шифрлау</string>\n    <string name=\"new_version\">Жаңа нұсқа %1$s</string>\n    <string name=\"share\">Бөлісу</string>\n    <string name=\"erase_mode\">Өшіру режімі</string>\n    <string name=\"color_red\">Қызыл</string>\n    <string name=\"fill\">Толтыру</string>\n    <string name=\"crop\">Қиып алу</string>\n    <string name=\"edit_exif\">EXIF өңдеу</string>\n    <string name=\"color\">Түс</string>\n    <string name=\"size\">Өлшем %1$s</string>\n    <string name=\"extension\">Кеңейтім</string>\n    <string name=\"smth_went_wrong\">Бірдеңе дұрыс болмады: %1$s</string>\n    <string name=\"quality\">Сапасы</string>\n    <string name=\"image_too_large_preview\">Кескін алдын ала қарау үшін тым үлкен, бірақ оны бәрібір сақтауға тырысады</string>\n    <string name=\"no_palette\">Берілген кескін үшін палитраны жасау мүмкін емес</string>\n    <string name=\"search_here\">Осы жерден іздеңіз</string>\n    <string name=\"surface\">Беткей</string>\n    <string name=\"remove\">Жою</string>\n    <string name=\"tertiary\">Үшіншілік</string>\n    <string name=\"donation_sub\">Бұл қолданба толығымен тегін, бірақ жобаны әзірлеуге қолдау көрсеткіңіз келсе, осы жерді басуға болады</string>\n    <string name=\"explicit\">Айқын</string>\n    <string name=\"reset_image\">Кескінді қалпына келтіру</string>\n    <string name=\"warning_bytes\">%1$s режимінде сақтау тұрақсыз болуы мүмкін, себебі ол жоғалтпайтын пішім</string>\n    <string name=\"dynamic_colors_sub\">Қосылған болса, қолданба түстері тұсқағаз түстеріне қабылданады</string>\n    <string name=\"grant\">Грант</string>\n    <string name=\"device_storage\">Құрылғыны сақтау</string>\n    <string name=\"unsupported_type\">Қолдау көрсетілмейтін түрі: %1$s</string>\n    <string name=\"folder\">Шығару қалтасы</string>\n    <string name=\"unspecified\">Анықталмаған</string>\n    <string name=\"help_translate_sub\">Аударма қателерін түзетіңіз немесе жобаны басқа тілдерге локализациялаңыз</string>\n    <string name=\"light\">Жарық</string>\n    <string name=\"pick_color_sub\">Суреттен түсті таңдаңыз, көшіріңіз немесе бөлісіңіз</string>\n    <string name=\"prefix\">Префикс</string>\n    <string name=\"primary\">Негізгі</string>\n    <string name=\"fab_alignment\">FAB туралау</string>\n    <string name=\"clipboard_paste_invalid_empty\">Қоюға ештеңе жоқ</string>\n    <string name=\"something_went_wrong\">Бірдеңе дұрыс болмады</string>\n    <string name=\"saved_to_without_filename\">%1$s қалтасына сақталды</string>\n    <string name=\"pick_images\">Суреттерді таңдаңыз</string>\n    <string name=\"secondary\">Екінші</string>\n    <string name=\"customization\">Баптау</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Жарамды aRGB кодын қойыңыз.</string>\n    <string name=\"dynamic_colors\">Динамикалық түстер</string>\n    <string name=\"palette_sub\">Берілген кескіннен түстер палитрасының үлгісін жасаңыз</string>\n    <string name=\"check_source_code_sub\">Соңғы жаңартуларды алыңыз, мәселелерді талқылаңыз және т.б</string>\n    <string name=\"allow_image_monet_sub\">Қосылған болса, өңдеу үшін кескінді таңдағанда, қолданба түстері осы кескінге қабылданады</string>\n    <string name=\"by_bytes_resize\">Салмақ бойынша өлшемін өзгерту</string>\n    <string name=\"flexible\">Икемді</string>\n    <string name=\"values_reset\">Мәндер дұрыс қалпына келтірілді</string>\n    <string name=\"single_edit_sub\">Берілген бір кескіннің сипаттамаларын өзгерту</string>\n    <string name=\"dark\">Қараңғы</string>\n    <string name=\"no_updates\">Жаңартулар табылмады</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Динамикалық түстер қосулы кезде қолданбаның түс схемасын өзгерту мүмкін емес</string>\n    <string name=\"nothing_found_by_search\">Сұрауыңыз бойынша ештеңе табылмады</string>\n    <string name=\"border_thickness\">Жиектің қалыңдығы</string>\n    <string name=\"check_updates\">Жаңартуларды тексеру</string>\n    <string name=\"color_scheme\">Түс схемасы</string>\n    <string name=\"crop_sub\">Кескінді кез келген шекке дейін қиыңыз</string>\n    <string name=\"generate_palette\">Палитра жасау</string>\n    <string name=\"amoled_mode_sub\">Қосылған жағдайда беттердің түсі түнгі режимде абсолютті қараңғыға орнатылады</string>\n    <string name=\"issue_tracker\">Мәселе бақылаушысы</string>\n    <string name=\"check_updates_sub\">Қосылған болса, қолданба іске қосылғаннан кейін жаңарту диалогы көрсетіледі</string>\n    <string name=\"light_aka_illumination\">Жарық</string>\n    <string name=\"allow_image_monet\">Монет кескініне рұқсат ету</string>\n    <string name=\"grant_permission_manual\">Қолданба жұмыс істеуі үшін бұл рұқсат қажет, оны қолмен беріңіз</string>\n    <string name=\"max_bytes\">Ең үлкен өлшем КБ</string>\n    <string name=\"system\">Жүйе</string>\n    <string name=\"by_bytes_resize_sub\">Кескіннің өлшемін КБ-де берілген өлшемнен кейін өзгертіңіз</string>\n    <string name=\"add\">қосу</string>\n    <string name=\"monet_colors\">Монет түстері</string>\n    <string name=\"change_preview\">Алдын ала қарауды өзгерту</string>\n    <string name=\"custom\">Арнаулы</string>\n    <string name=\"external_storage\">Сыртқы жад</string>\n    <string name=\"values\">Құндылықтар</string>\n    <string name=\"resize_type\">Өлшем түрін өзгерту</string>\n    <string name=\"compare_sub\">Берілген екі суретті салыстырыңыз</string>\n    <string name=\"enhanced_glitch\">Жетілдірілген ақау</string>\n    <string name=\"channel_shift_x\">Channel Shift X</string>\n    <string name=\"channel_shift_y\">Арнаны ауыстыру Y</string>\n    <string name=\"corruption_size\">Сыбайлас жемқорлық мөлшері</string>\n    <string name=\"corruption_shift_x\">Сыбайлас жемқорлықтың ауысуы X</string>\n    <string name=\"corruption_shift_y\">Сыбайлас жемқорлықтың ауысуы Y</string>\n    <string name=\"tent_blur\">Шатыр бұлыңғыр</string>\n    <string name=\"side_fade\">Бүйірлік әлсіреу</string>\n    <string name=\"side\">Бүйір</string>\n    <string name=\"top\">Жоғарғы</string>\n    <string name=\"bottom\">Төменгі</string>\n    <string name=\"strength\">Күш</string>\n    <string name=\"segmentation_mode_osd_only\">Бағдар &amp; Тек сценарийді анықтау</string>\n    <string name=\"segmentation_mode_auto_osd\">Автоматты бағдарлау &amp; сценарийді анықтау</string>\n    <string name=\"segmentation_mode_auto_only\">Тек авто</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Сирек мәтін бағыты &amp; сценарийді анықтау</string>\n    <string name=\"segmentation_mode_raw_line\">Шикі сызық</string>\n    <string name=\"glitch\">Ақаулық</string>\n    <string name=\"amount\">Сома</string>\n    <string name=\"seed\">Тұқым</string>\n    <string name=\"anaglyph\">Анаглиф</string>\n    <string name=\"noise\">Шу</string>\n    <string name=\"pixel_sort\">Пиксельді сұрыптау</string>\n    <string name=\"shuffle\">Араластыру</string>\n    <string name=\"delete_mask_warn\">Сіз таңдалған сүзгі маскасын жойғалы жатырсыз. Бұл әрекетті қайтару мүмкін емес</string>\n    <string name=\"delete_mask\">Масканы жою</string>\n    <string name=\"drago\">Драго</string>\n    <string name=\"aldridge\">Олдридж</string>\n    <string name=\"cutoff\">Кесіп алу</string>\n    <string name=\"uchimura\">Учимура</string>\n    <string name=\"mobius\">Мобиус</string>\n    <string name=\"transition\">Өту</string>\n    <string name=\"peak\">шың</string>\n    <string name=\"color_anomaly\">Түс аномалиясы</string>\n    <string name=\"clipboard\">Алмасу буфері</string>\n    <string name=\"vibration\">Діріл</string>\n    <string name=\"vibration_strength\">Діріл күші</string>\n    <string name=\"overwrite_file_requirements\">Файлдарды қайта жазу үшін \\\"Explorer\\\" кескін көзін пайдалану керек, суреттерді қайталап көріңіз, біз сурет көзін қажеттіге өзгерттік</string>\n    <string name=\"overwrite_files\">Файлдарды қайта жазу</string>\n    <string name=\"free\">Тегін</string>\n    <string name=\"images_overwritten\">Бастапқы тағайындалған жерде қайта жазылған кескіндер</string>\n    <string name=\"file_explorer_picker_sub\">Кескінді таңдау үшін GetContent мақсатын пайдаланыңыз. Барлық жерде жұмыс істейді, бірақ кейбір құрылғыларда таңдалған кескіндерді қабылдауда мәселелер бар екені белгілі. Бұл менің кінәм емес.</string>\n    <string name=\"options_arrangement\">Опцияларды реттеу</string>\n    <string name=\"order\">Тапсырыс</string>\n    <string name=\"order_sub\">Негізгі экрандағы опциялардың ретін анықтайды</string>\n    <string name=\"emojis_count\">Эмодзилер саны</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">бастапқы файл аты</string>\n    <string name=\"add_original_filename_sub\">Қосылған болса, шығыс кескінінің атына бастапқы файл атауын қосады</string>\n    <string name=\"replace_sequence_number\">Реттік нөмірді ауыстырыңыз</string>\n    <string name=\"filename_not_work_with_photopicker\">Фотосурет таңдау құралының кескін көзі таңдалған болса, бастапқы файл атауын қосу жұмыс істемейді</string>\n    <string name=\"replace_sequence_number_sub\">Қосылған болса, пакеттік өңдеуді пайдалансаңыз, стандартты уақыт белгісін кескін реттік нөміріне ауыстырады</string>\n    <string name=\"load_image_from_net\">Кескінді желіден жүктеңіз</string>\n    <string name=\"load_image_from_net_sub\">Қаласаңыз, алдын ала қарау, масштабтау, өңдеу және сақтау үшін интернеттен кез келген суретті жүктеңіз.</string>\n    <string name=\"fit\">Сәйкес</string>\n    <string name=\"content_scale\">Мазмұн масштабы</string>\n    <string name=\"explicit_description\">Әрбір суретті Width және Height параметрі арқылы берілген кескінге мәжбүрлейді - арақатынасын өзгертуі мүмкін</string>\n    <string name=\"flexible_description\">Суреттердің өлшемін Width немесе Height параметрі арқылы берілген ұзын жағы бар кескіндерге өзгертеді, барлық өлшемді есептеулер сақталғаннан кейін орындалады - арақатынасын сақтайды</string>\n    <string name=\"filter_sub\">Берілген кескіндерге кез келген сүзгі тізбегін қолданыңыз</string>\n    <string name=\"filters\">Сүзгілер</string>\n    <string name=\"color_filter\">Түс сүзгісі</string>\n    <string name=\"alpha\">Альфа</string>\n    <string name=\"exposure\">Экспозиция</string>\n    <string name=\"white_balance\">Ақ баланс</string>\n    <string name=\"temperature\">Температура</string>\n    <string name=\"tint\">Реңк</string>\n    <string name=\"monochrome\">Монохромды</string>\n    <string name=\"highlights_shadows\">Бөлек нүктелер мен көлеңкелер</string>\n    <string name=\"cga_colorspace\">CGA түс кеңістігі</string>\n    <string name=\"gaussian_blur\">Гаусс бұлдыры</string>\n    <string name=\"box_blur\">Қораптың бұлыңғырлығы</string>\n    <string name=\"bilaterial_blur\">Екі жақты бұлыңғырлық</string>\n    <string name=\"emboss\">Бедер</string>\n    <string name=\"laplacian\">Лаплациялық</string>\n    <string name=\"vignette\">Виньетка</string>\n    <string name=\"start\">Бастау</string>\n    <string name=\"end\">Соңы</string>\n    <string name=\"kuwahara\">Кувахара тегістеу</string>\n    <string name=\"stack_blur\">Стек бұлыңғыр</string>\n    <string name=\"scale\">Масштаб</string>\n    <string name=\"false_color\">Жалған түс</string>\n    <string name=\"first_color\">Бірінші түс</string>\n    <string name=\"zoom_blur\">Масштабты бұлыңғырлау</string>\n    <string name=\"color_balance\">Түс балансы</string>\n    <string name=\"luminance_threshold\">Жарықтық шегі</string>\n    <string name=\"draw\">Сурет салу</string>\n    <string name=\"activate_files\">Сіз Files қолданбасын өшірдіңіз, осы мүмкіндікті пайдалану үшін оны белсендіріңіз</string>\n    <string name=\"draw_sub\">Суретке эскиз кітапшасындағыдай сурет салыңыз немесе фонның өзінде сурет салыңыз</string>\n    <string name=\"paint_color\">Бояу түсі</string>\n    <string name=\"paint_alpha\">Бояу альфа</string>\n    <string name=\"draw_on_image\">Суретке салу</string>\n    <string name=\"draw_on_image_sub\">Суретті таңдап, оған бірдеңе салыңыз</string>\n    <string name=\"background_color\">Фон түсі</string>\n    <string name=\"cipher\">Шифр</string>\n    <string name=\"cipher_sub\">AES криптографиялық алгоритміне негізделген кез келген файлды (тек суретті ғана емес) шифрлаңыз және шифрын шешіңіз</string>\n    <string name=\"pick_file\">Файлды таңдаңыз</string>\n    <string name=\"decrypt\">Шифрын шешу</string>\n    <string name=\"decryption\">Шифрды шешу</string>\n    <string name=\"encryption\">Шифрлау</string>\n    <string name=\"file_proceed\">Файл өңделді</string>\n    <string name=\"store_file_desc\">Бұл файлды құрылғыда сақтаңыз немесе оны қалаған жерге қою үшін бөлісу әрекетін пайдаланыңыз</string>\n    <string name=\"implementation_sub\">AES-256, GCM режимі, толтыру жоқ, 12 байт кездейсоқ IV. Кілттер SHA-3 хэштері (256 бит) ретінде пайдаланылады.</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">Басқа файлды шифрлау бағдарламалық құралымен немесе қызметтерімен үйлесімділікке кепілдік берілмейтінін ескеріңіз. Сәл басқаша кілт өңдеуі немесе шифр конфигурациясы сәйкессіздікті тудыруы мүмкін.</string>\n    <string name=\"randomize_filename_sub\">Қосылған жағдайда шығыс файл атауы толығымен кездейсоқ болады</string>\n    <string name=\"saved_to\">%2$s атымен %1$s қалтасына сақталды</string>\n    <string name=\"reset_settings_sub\">Бұл параметрлерді әдепкі мәндерге қайтарады. Жоғарыда аталған сақтық көшірме файлынсыз мұны қайтару мүмкін емес екенін ескеріңіз.</string>\n    <string name=\"effort_sub\">%1$s мәні салыстырмалы түрде үлкен файл өлшеміне әкелетін жылдам қысуды білдіреді. %2$s кішірек файлға әкелетін баяу қысуды білдіреді.</string>\n    <string name=\"saving_almost_complete\">Сақтау аяқталды. Қазір бас тарту үшін қайта сақтау қажет болады.</string>\n    <string name=\"allow_betas_sub\">Қосылған болса, жаңартуды тексеру қолданбаның бета нұсқаларын қамтиды</string>\n    <string name=\"draw_arrows\">Көрсеткілерді салыңыз</string>\n    <string name=\"brush_softness\">Қылқаламның жұмсақтығы</string>\n    <string name=\"blur_edges\">Жиектерді бұлдырату</string>\n    <string name=\"blur_edges_sub\">Қосылған болса, бір түстің орнына айналасындағы бос орындарды толтыру үшін түпнұсқа кескіннің астындағы бұлыңғыр жиектерді салады</string>\n    <string name=\"pixelation\">Пикселдеу</string>\n    <string name=\"enhanced_pixelation\">Жетілдірілген пиксельдеу</string>\n    <string name=\"stroke_pixelation\">Инсульт пикселизациясы</string>\n    <string name=\"enhanced_diamond_pixelation\">Жетілдірілген гауһар пикселизациясы</string>\n    <string name=\"diamond_pixelation\">Алмаз пиксельдеу</string>\n    <string name=\"circle_pixelation\">Шеңбер пикселизациясы</string>\n    <string name=\"enhanced_circle_pixelation\">Жетілдірілген шеңбер пиксельденуі</string>\n    <string name=\"color_to_replace\">Ауыстыру үшін түс</string>\n    <string name=\"target_color\">Мақсатты түс</string>\n    <string name=\"color_to_remove\">Жою керек түс</string>\n    <string name=\"fruit_salad\">Жеміс салаты</string>\n    <string name=\"fidelity\">Адалдық</string>\n    <string name=\"content\">Мазмұны</string>\n    <string name=\"tonal_spot_sub\">Әдепкі палитра стилі, ол барлық төрт түсті теңшеуге мүмкіндік береді, басқалары тек негізгі түсті орнатуға мүмкіндік береді</string>\n    <string name=\"neutral_sub\">Монохромдыдан сәл хроматикалық стиль</string>\n    <string name=\"vibrant_sub\">Бастапқы палитра үшін қатты тақырып, түстілік максимум, басқалары үшін артады</string>\n    <string name=\"playful_scheme\">Көңілді тақырып - тақырыпта бастапқы түстің реңктері көрсетілмейді</string>\n    <string name=\"monochrome_sub\">Монохромды тақырып, түстер таза қара / ақ / сұр</string>\n    <string name=\"content_sub\">Бастапқы түсті Scheme.primaryContainer ішіне орналастыратын схема</string>\n    <string name=\"foss_update_checker_warning\">Бұл жаңарту тексерушісі жаңа жаңартудың бар-жоғын тексеру үшін GitHub қызметіне қосылады</string>\n    <string name=\"fidelity_sub\">Мазмұндық схемаға өте ұқсас схема</string>\n    <string name=\"attention\">Назар аударыңыз</string>\n    <string name=\"fading_edges\">Өңделетін жиектер</string>\n    <string name=\"both\">Екеуі де</string>\n    <string name=\"invert_colors\">Түстерді инверттеу</string>\n    <string name=\"invert_colors_sub\">Қосылған болса, тақырып түстерін теріс түстерге ауыстырады</string>\n    <string name=\"search_option_sub\">Негізгі экрандағы барлық қолжетімді опциялар арқылы іздеу мүмкіндігін қосады</string>\n    <string name=\"pdf_to_images\">PDF - кескіндерге</string>\n    <string name=\"images_to_pdf\">Суреттер PDF форматына</string>\n    <string name=\"preview_pdf_sub\">Қарапайым PDF алдын ала қарау</string>\n    <string name=\"pdf_to_images_sub\">Берілген шығыс пішімінде PDF форматын кескіндерге түрлендіру</string>\n    <string name=\"images_to_pdf_sub\">Берілген кескіндерді шығыс PDF файлына жинаңыз</string>\n    <string name=\"mask_filter\">Маска сүзгісі</string>\n    <string name=\"inverse_fill_type_sub\">Қосылған болса, әдепкі әрекеттің орнына маскаланбаған аумақтардың барлығы сүзіледі</string>\n    <string name=\"simple_variants\">Қарапайым нұсқалар</string>\n    <string name=\"highlighter\">Бөлектеу құралы</string>\n    <string name=\"pen\">Қалам</string>\n    <string name=\"privacy_blur\">Құпиялылық бұлыңғыр</string>\n    <string name=\"highlighter_sub\">Жартылай мөлдір өткірленген бөлектеуіш жолдарын сызыңыз</string>\n    <string name=\"neon_sub\">Сызбаларыңызға жарқыраған әсер қосыңыз</string>\n    <string name=\"pen_sub\">Әдепкі, ең қарапайым - тек түс</string>\n    <string name=\"privacy_blur_sub\">Жасырғыңыз келетін кез келген нәрсені қорғау үшін сызылған жолдың астындағы кескінді бұлдыратады</string>\n    <string name=\"pixelation_sub\">Құпиялылық бұлыңғырлығына ұқсас, бірақ бұлыңғырлаудың орнына пиксельдейді</string>\n    <string name=\"double_line_arrow_sub\">Қос меңзегіш көрсеткіні бастапқы нүктеден соңғы нүктеге дейін сызық ретінде салады</string>\n    <string name=\"double_arrow_sub\">Берілген жолдан қос көрсеткіні салады</string>\n    <string name=\"outlined_rect\">Белгіленген Рект</string>\n    <string name=\"oval\">Сопақ</string>\n    <string name=\"rect\">Рект</string>\n    <string name=\"rect_sub\">Бастапқы нүктеден соңғы нүктеге дейін түзу салады</string>\n    <string name=\"oval_sub\">Бастапқы нүктеден соңғы нүктеге дейін сопақ сызады</string>\n    <string name=\"outlined_oval_sub\">Бастапқы нүктеден соңғы нүктеге дейін сызылған сопақ сызады</string>\n    <string name=\"no_such_directory\">\\\"%1$s\\\" каталогы табылмады, біз оны әдепкіге ауыстырдық, файлды қайта сақтаңыз</string>\n    <string name=\"auto_pin\">Автоматты бекіту</string>\n    <string name=\"auto_pin_sub\">Қосылған болса, сақталған кескінді алмасу буферіне автоматты түрде қосады</string>\n    <string name=\"overwrite_files_sub\">Түпнұсқа файл таңдалған қалтада сақтаудың орнына жаңасымен ауыстырылады, бұл опция сурет көзі \\\"Explorer\\\" немесе GetContent болуы керек, оны ауыстырған кезде ол автоматты түрде орнатылады.</string>\n    <string name=\"empty\">Бос</string>\n    <string name=\"suffix\">Суффикс</string>\n    <string name=\"mitchell_sub\">Масштабталған кескіндегі айқындық пен антиалиазинг арасындағы тепе-теңдікке қол жеткізу үшін реттелетін параметрлері бар конволюция сүзгісін қолданатын қайта үлгілеу әдісі</string>\n    <string name=\"spline_sub\">Қисық сызықты немесе бетті, икемді және үздіксіз пішінді бейнелеуді біркелкі интерполяциялау және жақындату үшін бөліктермен анықталған көпмүшелік функцияларды пайдаланады.</string>\n    <string name=\"segmentation_mode_auto\">Автоматты</string>\n    <string name=\"segmentation_mode_single_column\">Бір баған</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Бір блокты тік мәтін</string>\n    <string name=\"segmentation_mode_single_block\">Бір блок</string>\n    <string name=\"segmentation_mode_single_line\">Бір жол</string>\n    <string name=\"segmentation_mode_single_word\">Бір сөз</string>\n    <string name=\"segmentation_mode_circle_word\">Шеңбер сөз</string>\n    <string name=\"segmentation_mode_single_char\">Жалғыз таңба</string>\n    <string name=\"segmentation_mode_sparse_text\">Сирек мәтін</string>\n    <string name=\"delete_language_sub\">Барлық тану түрлері үшін немесе тек таңдалған біреуіне (%2$s) арналған \\\"%1$s\\\" OCR оқу деректерін жойғыңыз келе ме?</string>\n    <string name=\"all\">Барлық</string>\n    <string name=\"gray_scale\">Сұр шкала</string>\n    <string name=\"bayer_two_dithering\">Байер екіден екіге дитеринг</string>\n    <string name=\"bayer_three_dithering\">Байер Үштен Үшке Дитеринг</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"stucki_dithering\">Стукки Дитеринг</string>\n    <string name=\"burkes_dithering\">Беркс Дитеринг</string>\n    <string name=\"false_floyd_steinberg_dithering\">Жалған Флойд Стейнберг Дитеринг</string>\n    <string name=\"left_to_right_dithering\">Солдан оңға қарай дитеринг</string>\n    <string name=\"oil\">Мұнай</string>\n    <string name=\"protonomaly\">Протономалия</string>\n    <string name=\"vintage\">Винтаж</string>\n    <string name=\"browni\">Брауни</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"cool\">Керемет</string>\n    <string name=\"tritanopia\">Тританопия</string>\n    <string name=\"deutaronotopia\">Дейтаронотопия</string>\n    <string name=\"achromatopsia\">Ахроматопсия</string>\n    <string name=\"orange_haze\">Қызғылт сары тұман</string>\n    <string name=\"pink_dream\">Қызғылт арман</string>\n    <string name=\"golden_hour\">Алтын сағат</string>\n    <string name=\"hot_summer\">Ыстық жаз</string>\n    <string name=\"purple_mist\">Күлгін тұман</string>\n    <string name=\"sunrise\">Күннің шығуы</string>\n    <string name=\"colorful_swirl\">Түрлі-түсті бұрылыс</string>\n    <string name=\"soft_spring_light\">Жұмсақ көктемгі жарық</string>\n    <string name=\"autumn_tones\">Күз тондары</string>\n    <string name=\"lavender_dream\">Лаванда арманы</string>\n    <string name=\"cyberpunk\">Киберпанк</string>\n    <string name=\"lemonade_light\">Лимонадты жарық</string>\n    <string name=\"spectral_fire\">Спектрлік өрт</string>\n    <string name=\"night_magic\">Түнгі сиқыр</string>\n    <string name=\"fantasy_landscape\">Фантастикалық пейзаж</string>\n    <string name=\"color_explosion\">Түс жарылысы</string>\n    <string name=\"electric_gradient\">Электр градиенті</string>\n    <string name=\"rainbow_world\">Кемпірқосақ әлемі</string>\n    <string name=\"deep_purple\">Қою күлгін</string>\n    <string name=\"digital_code\">Сандық код</string>\n    <string name=\"space_portal\">Ғарыш порталы</string>\n    <string name=\"red_swirl\">Қызыл бұрылыс</string>\n    <string name=\"cannot_change_image_format\">Файлдарды қайта жазу опциясы қосылған кезде кескін пішімін өзгерту мүмкін емес</string>\n    <string name=\"emoji_as_color_scheme\">Эмодзи түстер схемасы ретінде</string>\n    <string name=\"emoji_as_color_scheme_sub\">Қолмен анықталғанның орнына қолданбаның түс схемасы ретінде негізгі эмодзи түсін пайдаланады</string>\n    <string name=\"erode\">Эрозия</string>\n    <string name=\"anisotropic_diffusion\">Анизотропты диффузия</string>\n    <string name=\"diffusion\">Диффузия</string>\n    <string name=\"conduction\">Өткізгіштік</string>\n    <string name=\"horizontal_wind_stagger\">Көлденең жел тепкіш</string>\n    <string name=\"fast_bilaterial_blur\">Жылдам екі жақты бұлыңғыр</string>\n    <string name=\"poisson_blur\">Пуассон бұлыңғырлығы</string>\n    <string name=\"logarithmic_tone_mapping\">Логарифмдік тонды кескіндеу</string>\n    <string name=\"crystallize\">Кристалдану</string>\n    <string name=\"stroke_color\">Сызық түсі</string>\n    <string name=\"fractal_glass\">Фракталды шыны</string>\n    <string name=\"amplitude\">Амплитудасы</string>\n    <string name=\"marble\">Мәрмәр</string>\n    <string name=\"turbulence\">Турбуленттілік</string>\n    <string name=\"water_effect\">Су әсері</string>\n    <string name=\"just_size\">Өлшем</string>\n    <string name=\"frequency_x\">X жиілігі</string>\n    <string name=\"frequency_y\">Жиілік Y</string>\n    <string name=\"amplitude_x\">Амплитудасы X</string>\n    <string name=\"amplitude_y\">Амплитудасы Y</string>\n    <string name=\"perlin_distortion\">Перлиннің бұрмалануы</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES фильмдік тонды салыстыру</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"current\">Ағымдағы</string>\n    <string name=\"full_filter\">Толық сүзгі</string>\n    <string name=\"start_position\">Бастау</string>\n    <string name=\"center_position\">Орталық</string>\n    <string name=\"end_position\">Соңы</string>\n    <string name=\"full_filter_sub\">Берілген кескіндерге немесе бір кескінге кез келген сүзгі тізбегін қолданыңыз</string>\n    <string name=\"gradient_maker\">Градиент жасаушы</string>\n    <string name=\"gradient_maker_sub\">Реттелетін түстермен және сыртқы түрімен берілген шығыс өлшемінің градиентін жасаңыз</string>\n    <string name=\"speed\">Жылдамдық</string>\n    <string name=\"dehaze\">Дехазе</string>\n    <string name=\"omega\">Омега</string>\n    <string name=\"rate_app\">Қолданбаны бағалаңыз</string>\n    <string name=\"rate\">Бағалау</string>\n    <string name=\"rate_app_sub\">Бұл қолданба толығымен тегін, егер сіз оның үлкенірек болғанын қаласаңыз, жобаны Github-да жұлдызшамен белгілеңіз 😄</string>\n    <string name=\"color_matrix_4x4\">Түс матрицасы 4x4</string>\n    <string name=\"color_matrix_3x3\">Түс матрицасы 3x3</string>\n    <string name=\"simple_effects\">Қарапайым әсерлер</string>\n    <string name=\"polaroid\">Полароид</string>\n    <string name=\"tritonomaly\">Тритономия</string>\n    <string name=\"deutaromaly\">Деутаромалы</string>\n    <string name=\"night_vision\">Түнгі көру</string>\n    <string name=\"warm\">Жылы</string>\n    <string name=\"protanopia\">Протанопия</string>\n    <string name=\"achromatomaly\">Ахроматомалия</string>\n    <string name=\"gradient_type_linear\">Сызықтық</string>\n    <string name=\"gradient_type_radial\">Радиалды</string>\n    <string name=\"gradient_type_sweep\">Тазарту</string>\n    <string name=\"gradient_type\">Градиент түрі</string>\n    <string name=\"center_x\">Орталық X</string>\n    <string name=\"center_y\">Орталық Y</string>\n    <string name=\"tile_mode\">Тақта режимі</string>\n    <string name=\"tile_mode_repeated\">Қайталанды</string>\n    <string name=\"tile_mode_mirror\">Айна</string>\n    <string name=\"tile_mode_clamp\">Қысқыш</string>\n    <string name=\"tile_mode_decal\">Жапсырма</string>\n    <string name=\"color_stops\">Түс тоқтайды</string>\n    <string name=\"add_color\">Түс қосу</string>\n    <string name=\"properties\">Қасиеттер</string>\n    <string name=\"lasso\">Ласо</string>\n    <string name=\"lasso_sub\">Берілген жол бойынша жабық толтырылған жолды салады</string>\n    <string name=\"draw_path_mode\">Сурет салу режимі</string>\n    <string name=\"double_line_arrow\">Қос сызықты көрсеткі</string>\n    <string name=\"free_drawing\">Еркін сурет салу</string>\n    <string name=\"double_arrow\">Қос көрсеткі</string>\n    <string name=\"line_arrow\">Сызық көрсеткі</string>\n    <string name=\"arrow\">Жебе</string>\n    <string name=\"line\">Түзу</string>\n    <string name=\"free_drawing_sub\">Жолды кіріс мәні ретінде салады</string>\n    <string name=\"line_sub\">Жолды бастапқы нүктеден соңғы нүктеге дейін сызық ретінде салады</string>\n    <string name=\"line_arrow_sub\">Меңзегіш көрсеткіні бастапқы нүктеден соңғы нүктеге дейін сызық ретінде салады</string>\n    <string name=\"arrow_sub\">Берілген жолдан меңзейтін көрсеткіні салады</string>\n    <string name=\"outlined_oval\">Контурланған сопақ</string>\n    <string name=\"outlined_rect_sub\">Бастапқы нүктеден соңғы нүктеге дейін сызылған түзу салады</string>\n    <string name=\"dithering\">Дитеринг</string>\n    <string name=\"quantizier\">Квантизатор</string>\n    <string name=\"bayer_four_dithering\">Байер төрттен төртке Дитеринг</string>\n    <string name=\"bayer_eight_dithering\">Байер сегіз сегіздік дитеринг</string>\n    <string name=\"floyd_steinberg_dithering\">Флойд Стейнберг Дитеринг</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Джарвис Джудис Нинке Дитеринг</string>\n    <string name=\"sierra_dithering\">Сьерра Дитеринг</string>\n    <string name=\"two_row_sierra_dithering\">Екі қатарлы Сьерра Дитеринг</string>\n    <string name=\"atkinson_dithering\">Аткинсон Дитеринг</string>\n    <string name=\"random_dithering\">Кездейсоқ дитеринг</string>\n    <string name=\"simple_threshold_dithering\">Қарапайым шекті дитеринг</string>\n    <string name=\"scale_mode\">Масштаб режимі</string>\n    <string name=\"bilinear\">Билинарлық</string>\n    <string name=\"hann\">Ханн</string>\n    <string name=\"hermite\">Эрмит</string>\n    <string name=\"lanczos\">Ланчос</string>\n    <string name=\"mitchell\">Митчелл</string>\n    <string name=\"nearest\">Ең жақын</string>\n    <string name=\"spline\">Сплайн</string>\n    <string name=\"basic\">Негізгі</string>\n    <string name=\"default_value\">Әдепкі мән</string>\n    <string name=\"sigma\">Сигма</string>\n    <string name=\"spatial_sigma\">Кеңістіктік сигма</string>\n    <string name=\"median_blur\">Медиандық бұлыңғыр</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Бикуб</string>\n    <string name=\"bilinear_sub\">Сызықтық (немесе екі өлшемді, екі өлшемді) интерполяция әдетте кескіннің өлшемін өзгерту үшін жақсы, бірақ бөлшектердің кейбір жағымсыз жұмсартуын тудырады және әлі де біраз қисық болуы мүмкін.</string>\n    <string name=\"bicubic_sub\">Жақсырақ масштабтау әдістеріне Lanczos қайта үлгілеу және Митчелл-Нетравали сүзгілері кіреді</string>\n    <string name=\"nearest_sub\">Өлшемді үлкейтудің қарапайым тәсілдерінің бірі, әр пикселді бірдей түсті пикселдер санымен ауыстыру</string>\n    <string name=\"basic_sub\">Барлық дерлік қолданбаларда қолданылатын қарапайым Android масштабтау режимі</string>\n    <string name=\"catmull_sub\">Бірқалыпты қисықтарды жасау үшін компьютерлік графикада әдетте қолданылатын басқару нүктелерінің жиынын біркелкі интерполяциялау және қайта үлгілеу әдісі</string>\n    <string name=\"hann_sub\">Терезе функциясы жиі спектрлік ағып кетуді азайту және сигналдың жиектерін тарылту арқылы жиілікті талдаудың дәлдігін жақсарту үшін сигналды өңдеуде қолданылады.</string>\n    <string name=\"hermite_sub\">Тегіс және үздіксіз қисық генерациялау үшін қисық сегменттің соңғы нүктелеріндегі мәндер мен туындыларды пайдаланатын математикалық интерполяция әдісі</string>\n    <string name=\"lanczos_sub\">Пиксель мәндеріне өлшенген sinc функциясын қолдану арқылы жоғары сапалы интерполяцияны сақтайтын қайта үлгілеу әдісі</string>\n    <string name=\"only_clip\">Тек клип</string>\n    <string name=\"only_clip_sub\">Жадқа сақтау орындалмайды және кескін тек алмасу буферіне қойылады</string>\n    <string name=\"icon_shape_sub\">Таңдалған пішіні бар контейнерді карталардың жетекші белгішелерінің астына қосады</string>\n    <string name=\"icon_shape\">Белгіше пішіні</string>\n    <string name=\"brightness_enforcement\">Жарықтықты қамтамасыз ету</string>\n    <string name=\"screen\">Экран</string>\n    <string name=\"gradient_maker_type_image\">Градиент қабаттасуы</string>\n    <string name=\"gradient_maker_type_image_sub\">Берілген кескіннің жоғарғы жағының кез келген градиентін жасаңыз</string>\n    <string name=\"transformations\">Трансформациялар</string>\n    <string name=\"camera\">Камера</string>\n    <string name=\"camera_sub\">Суретке түсіру үшін камераны пайдаланады, осы сурет көзінен бір ғана суретті алуға болатынын ескеріңіз</string>\n    <string name=\"grain\">Астық</string>\n    <string name=\"unsharp\">Өшіру</string>\n    <string name=\"pastel\">Пастел</string>\n    <string name=\"caramel_darkness\">Карамель қараңғылығы</string>\n    <string name=\"futuristic_gradient\">Футуристік градиент</string>\n    <string name=\"green_sun\">Жасыл күн</string>\n    <string name=\"watermarking\">Су таңбалау</string>\n    <string name=\"watermarking_sub\">Суреттерді реттелетін мәтін/сурет су белгілерімен жабыңыз</string>\n    <string name=\"repeat_watermark\">Су таңбасын қайталаңыз</string>\n    <string name=\"repeat_watermark_sub\">Берілген орындағы жалғыздың орнына су таңбасын кескіннің үстіне қайталайды</string>\n    <string name=\"offset_x\">Офсет X</string>\n    <string name=\"offset_y\">Офсет Y</string>\n    <string name=\"watermark_type\">Су таңбасы түрі</string>\n    <string name=\"watermarking_image_sub\">Бұл сурет су таңбасы үшін үлгі ретінде пайдаланылады</string>\n    <string name=\"text_color\">Мәтін түсі</string>\n    <string name=\"overlay_mode\">Қабаттасу режимі</string>\n    <string name=\"bokeh\">Боке</string>\n    <string name=\"gif_tools\">GIF құралдары</string>\n    <string name=\"gif_tools_sub\">Суреттерді GIF суретіне түрлендіру немесе берілген GIF кескінінен жақтауларды шығарып алу</string>\n    <string name=\"gif_type_to_image\">суреттерге GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF файлын суреттер топтамасына түрлендіру</string>\n    <string name=\"gif_type_to_gif_sub\">Суреттер партиясын GIF файлына түрлендіру</string>\n    <string name=\"gif_type_to_gif\">GIF форматындағы суреттер</string>\n    <string name=\"select_gif_image_to_start\">Бастау үшін GIF кескінін таңдаңыз</string>\n    <string name=\"use_size_of_first_frame\">Бірінші кадрдың өлшемін пайдаланыңыз</string>\n    <string name=\"use_size_of_first_frame_sub\">Көрсетілген өлшемді бірінші жақтау өлшемдерімен ауыстырыңыз</string>\n    <string name=\"repeat_count\">Сананы қайталау</string>\n    <string name=\"frame_delay\">Кадр кідірісі</string>\n    <string name=\"millis\">миллис</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Lasso пайдаланыңыз</string>\n    <string name=\"use_lasso_sub\">Өшіруді орындау үшін сурет режимінде Lasso сияқты пайдаланады</string>\n    <string name=\"original_image_preview_alpha\">Түпнұсқа кескінді алдын ала қарау альфасы</string>\n    <string name=\"random_emojis_sub\">Қолданбалар тақтасының эмодзилері таңдалғанды пайдаланудың орнына кездейсоқ түрде үздіксіз өзгертіледі</string>\n    <string name=\"random_emojis\">Кездейсоқ эмодзилер</string>\n    <string name=\"random_emojis_error\">Эмодзилер өшірілген кезде кездейсоқ эмодзилерді таңдау мүмкін емес</string>\n    <string name=\"emoji_selection_error\">Кездейсоқ таңдалған кезде эмодзиді таңдау мүмкін емес</string>\n    <string name=\"highlights\">Маңызды жерлер</string>\n    <string name=\"shadows\">Көлеңкелер</string>\n    <string name=\"haze\">Тұман</string>\n    <string name=\"effect\">Әсер</string>\n    <string name=\"distance\">Қашықтық</string>\n    <string name=\"slope\">Еңіс</string>\n    <string name=\"sharpen\">Қайрау</string>\n    <string name=\"negative\">Теріс</string>\n    <string name=\"solarize\">Соляризация</string>\n    <string name=\"vibrance\">Діріл</string>\n    <string name=\"crosshatch\">Кроссшеч</string>\n    <string name=\"spacing\">Аралық</string>\n    <string name=\"line_width\">Сызық ені</string>\n    <string name=\"sobel_edge\">Собель жиегі</string>\n    <string name=\"blur\">Бұлыңғыр</string>\n    <string name=\"halftone\">Жартылай реңк</string>\n    <string name=\"old_tv\">Ескі теледидар</string>\n    <string name=\"shuffle_blur\">Бұлыңғырлықты араластыру</string>\n    <string name=\"recognize_text\">OCR (мәтінді тану)</string>\n    <string name=\"recognize_text_sub\">Берілген кескіндегі мәтінді тану, 120+ тілге қолдау көрсетіледі</string>\n    <string name=\"picture_has_no_text\">Суретте мәтін жоқ немесе қолданба оны таппады</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Тану түрі</string>\n    <string name=\"fast\">Жылдам</string>\n    <string name=\"standard\">Стандартты</string>\n    <string name=\"best\">Ең жақсы</string>\n    <string name=\"no_data\">Деректер жоқ</string>\n    <string name=\"download_description\">Tesseract OCR дұрыс жұмыс істеуі үшін құрылғыңызға қосымша жаттығу деректерін (%1$s) жүктеп алу қажет. \\n%2$s деректерін жүктеп алғыңыз келе ме?</string>\n    <string name=\"download\">Жүктеп алу</string>\n    <string name=\"no_connection\">Байланыс жоқ, пойыз үлгілерін жүктеп алу үшін оны тексеріп, әрекетті қайталаңыз</string>\n    <string name=\"downloaded_languages\">Жүктелген тілдер</string>\n    <string name=\"available_languages\">Қолжетімді тілдер</string>\n    <string name=\"segmentation_mode\">Сегменттеу режимі</string>\n    <string name=\"restore_background_sub\">Қылқалам өшірудің орнына фонды қалпына келтіреді</string>\n    <string name=\"horizontal_grid\">Көлденең тор</string>\n    <string name=\"vertical_grid\">Тік тор</string>\n    <string name=\"stitch_mode\">Тігіс режимі</string>\n    <string name=\"rows_count\">Жолдар саны</string>\n    <string name=\"columns_count\">Бағандар саны</string>\n    <string name=\"use_pixel_switch\">Pixel Switch пайдаланыңыз</string>\n    <string name=\"use_pixel_switch_sub\">Сіз негізделген google материалының орнына пикселге ұқсас қосқыш пайдаланылады</string>\n    <string name=\"slide\">Слайд</string>\n    <string name=\"side_by_side\">Қатар</string>\n    <string name=\"toggle_tap\">Түртуді ауыстырып қосу</string>\n    <string name=\"transparency\">Мөлдірлік</string>\n    <string name=\"saved_to_original\">Бастапқы тағайындалған жерде %1$s атымен қайта жазылған файл</string>\n    <string name=\"magnifier\">Үлкейткіш</string>\n    <string name=\"magnifier_sub\">Жақсырақ қол жетімділік үшін сурет салу режимдерінде саусақтың жоғарғы жағындағы ұлғайтқышты қосады</string>\n    <string name=\"force_exif_widget_initial_value\">Бастапқы мәнді мәжбүрлеу</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Бастапқыда exif виджетін тексеруге мәжбүрлейді</string>\n    <string name=\"allow_multiple_languages\">Бірнеше тілге рұқсат ету</string>\n    <string name=\"favorite\">Таңдаулы</string>\n    <string name=\"no_favorite_filters\">Таңдаулы сүзгілер әлі қосылмаған</string>\n    <string name=\"b_spline\">B Сплайн</string>\n    <string name=\"b_spline_sub\">Қисық сызықты немесе бетті, икемді және үздіксіз пішінді бейнелеуді біркелкі интерполяциялау және жақындату үшін бөліктермен анықталған екі кубтық көпмүшелік функцияларды пайдаланады</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Еңкейту жылжыту</string>\n    <string name=\"reset_image_sub\">Кескін өзгертулері бастапқы мәндерге оралады</string>\n    <string name=\"clear_exif_sub\">Барлық кескін EXIF деректері жойылады. Бұл әрекетті қайтару мүмкін емес!</string>\n    <string name=\"single_edit\">Жалғыз өңдеу</string>\n    <string name=\"pick_accent_color\">Қолданба тақырыбы таңдалған түске негізделеді</string>\n    <string name=\"issue_tracker_sub\">Қате туралы есептерді және мүмкіндік сұрауларын осында жіберіңіз</string>\n    <string name=\"email\">Электрондық пошта</string>\n    <string name=\"permission_sub\">Жұмыс істеу үшін кескіндерді сақтау үшін қолданбаға жадқа кіру рұқсаты қажет. Келесі диалогтық терезеде рұқсат беріңіз.</string>\n    <string name=\"emoji\">Эмодзи</string>\n    <string name=\"emoji_sub\">Негізгі экранда қандай эмодзи көрсетілетінін таңдаңыз</string>\n    <string name=\"add_file_size\">Файл өлшемін қосыңыз</string>\n    <string name=\"add_file_size_sub\">Қосылған болса, шығыс файлының атына сақталған кескіннің енін және биіктігін қосады</string>\n    <string name=\"delete_exif_sub\">Кез келген кескіндер жинағынан EXIF метадеректерін жойыңыз</string>\n    <string name=\"image_preview_sub\">Кескіндердің кез келген түрін алдын ала қараңыз: GIF, SVG және т.б</string>\n    <string name=\"image_source\">Сурет көзі</string>\n    <string name=\"photo_picker\">Фото таңдаушы</string>\n    <string name=\"gallery_picker\">Галерея</string>\n    <string name=\"file_explorer_picker\">Файл зерттеушісі</string>\n    <string name=\"photo_picker_sub\">Экранның төменгі жағында пайда болатын Android заманауи фото таңдау құралы тек Android 12+ жүйесінде жұмыс істей алады. EXIF метадеректерін қабылдауда мәселелер бар</string>\n    <string name=\"gallery_picker_sub\">Қарапайым галерея кескінін таңдау құралы. Ол медиа таңдауды қамтамасыз ететін қолданба болған жағдайда ғана жұмыс істейді</string>\n    <string name=\"hue\">Реңк</string>\n    <string name=\"add_filter\">Сүзгіні қосыңыз</string>\n    <string name=\"filter\">Сүзгі</string>\n    <string name=\"distortion\">Бұрмалау</string>\n    <string name=\"swirl\">Айналмалы</string>\n    <string name=\"bulge\">Дөңес</string>\n    <string name=\"dilation\">Кеңейту</string>\n    <string name=\"sphere_refraction\">Шардың сынуы</string>\n    <string name=\"refractive_index\">Сыну көрсеткіші</string>\n    <string name=\"glass_sphere_refraction\">Шыны шардың сынуы</string>\n    <string name=\"color_matrix\">Түс матрицасы</string>\n    <string name=\"opacity\">Мөлдірлік</string>\n    <string name=\"limits_resize\">Өлшемді өзгертуге шектеулер</string>\n    <string name=\"limits_resize_sub\">Таңдалған кескіндердің өлшемін өзгертіп, арақатынасын сақтай отырып, берілген ені мен биіктігі шектеулерін орындаңыз</string>\n    <string name=\"sketch\">Эскиз</string>\n    <string name=\"threshold\">Табалдырық</string>\n    <string name=\"quantizationLevels\">Кванттау деңгейлері</string>\n    <string name=\"smooth_toon\">Тегіс тон</string>\n    <string name=\"toon\">Тон</string>\n    <string name=\"posterize\">Постеризация</string>\n    <string name=\"non_maximum_suppression\">Максималды емес басу</string>\n    <string name=\"weak_pixel_inclusion\">Әлсіз пиксельді қосу</string>\n    <string name=\"lookup\">Іздеу</string>\n    <string name=\"convolution3x3\">Конволюция 3x3</string>\n    <string name=\"second_color\">Екінші түс</string>\n    <string name=\"reorder\">Қайта реттеу</string>\n    <string name=\"fast_blur\">Жылдам бұлыңғыр</string>\n    <string name=\"blur_size\">Бұлыңғыр өлшем</string>\n    <string name=\"blur_center_x\">Бұлыңғырлық орталығы x</string>\n    <string name=\"blur_center_y\">Бұлыңғырлық орталығы y</string>\n    <string name=\"draw_on_background\">Фонға сурет салу</string>\n    <string name=\"draw_on_background_sub\">Фон түсін таңдап, оның үстіне сызыңыз</string>\n    <string name=\"features\">Ерекше өзгешеліктері</string>\n    <string name=\"implementation\">Іске асыру</string>\n    <string name=\"compatibility\">Үйлесімділік</string>\n    <string name=\"features_sub\">Құпия сөз негізінде файлдарды шифрлау. Жалғастырылған файлдарды таңдалған каталогта сақтауға немесе ортақ пайдалануға болады. Шифры шешілген файлдарды да тікелей ашуға болады.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Жарамсыз құпия сөз немесе таңдалған файл шифрланбаған</string>\n    <string name=\"image_size_warning\">Кескінді берілген ені мен биіктігімен сақтауға әрекет OOM қатесін тудыруы мүмкін. Мұны өз тәуекеліңізге байланысты жасаңыз және мен сізге ескертпедім деп айтпаңыз!</string>\n    <string name=\"found_s\">%1$s табылды</string>\n    <string name=\"auto_cache_clearing\">Автоматты кэшті тазалау</string>\n    <string name=\"auto_cache_clearing_sub\">Қосылған болса, қолданбаның кэші қолданбаны іске қосқан кезде тазаланады</string>\n    <string name=\"create\">Жасау</string>\n    <string name=\"group_options_by_type\">Опцияларды түрі бойынша топтаңыз</string>\n    <string name=\"group_options_by_type_sub\">Негізгі экрандағы опцияларды реттелетін тізім реттеуінің орнына түрі бойынша топтайды</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Опцияларды топтау қосулы кезде реттеуді өзгерту мүмкін емес</string>\n    <string name=\"secondary_customization\">Қосымша теңшеу</string>\n    <string name=\"fallback_option\">Кері опция</string>\n    <string name=\"presets_sub\" formatted=\"false\">Алдын ала орнатылған 125 параметрін таңдасаңыз, сурет 100% сапасымен түпнұсқа кескіннің 125% өлшемі ретінде сақталады. Алдын ала орнатылған 50 параметрін таңдасаңыз, сурет 50% өлшеммен және 50% сапамен сақталады.</string>\n    <string name=\"presets_sub_bytes\">Мұнда алдын ала орнату шығыс файлының % анықтайды, яғни 5 мб суретте алдын ала орнатылған 50 параметрін таңдасаңыз, сақталғаннан кейін 2,5 мб кескінді аласыз.</string>\n    <string name=\"tg_chat\">Telegram чаты</string>\n    <string name=\"tg_chat_sub\">Қолданбаны талқылаңыз және басқа пайдаланушылардан пікір алыңыз. Сондай-ақ, бета жаңартулары мен түсініктерін осы жерден ала аласыз.</string>\n    <string name=\"crop_mask\">Кептірілген маска</string>\n    <string name=\"aspect_ratio\">Аспект арақатынасы</string>\n    <string name=\"image_crop_mask_sub\">Берілген кескіннен маска жасау үшін осы маска түрін пайдаланыңыз, оның альфа арнасы болуы КЕРЕК екенін ескеріңіз</string>\n    <string name=\"backup_and_restore\">Сақтық көшірме жасау және қалпына келтіру</string>\n    <string name=\"restore\">Қалпына келтіру</string>\n    <string name=\"backup_sub\">Қолданба параметрлерінің сақтық көшірмесін файлға жасаңыз</string>\n    <string name=\"restore_sub\">Бұрын жасалған файлдан қолданба параметрлерін қалпына келтіріңіз</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Зақымдалған файл немесе сақтық көшірме емес</string>\n    <string name=\"settings_restored\">Параметрлер сәтті қалпына келтірілді</string>\n    <string name=\"contact_me\">Менімен хабарлас</string>\n    <string name=\"delete_color_scheme_warn\">Сіз таңдалған түс схемасын жойғалы жатырсыз. Бұл әрекетті қайтару мүмкін емес</string>\n    <string name=\"delete_color_scheme_title\">Схеманы жою</string>\n    <string name=\"using_large_fonts_warn\">Үлкен қаріп масштабтарын пайдалану UI ақаулары мен ақауларын тудыруы мүмкін, олар түзетілмейді. Абайлаңыз.</string>\n    <string name=\"emotions\">Эмоциялар</string>\n    <string name=\"travels_and_places\">Саяхат және орындар</string>\n    <string name=\"activities\">Іс-шаралар</string>\n    <string name=\"background_remover\">Фонды кетіргіш</string>\n    <string name=\"background_remover_sub\">Суреттен фондық суретті алып тастаңыз немесе Авто опциясын пайдаланыңыз</string>\n    <string name=\"trim_image\">Кескінді кесу</string>\n    <string name=\"keep_exif_sub\">Түпнұсқа кескін метадеректері сақталады</string>\n    <string name=\"trim_image_sub\">Кескіннің айналасындағы мөлдір кеңістіктер кесіледі</string>\n    <string name=\"auto_erase_background\">Фонды автоматты түрде өшіру</string>\n    <string name=\"restore_image\">Кескінді қалпына келтіру</string>\n    <string name=\"erase_background\">Фонды өшіру</string>\n    <string name=\"restore_background\">Фонды қалпына келтіру</string>\n    <string name=\"blur_radius\">Бұлыңғырлық радиусы</string>\n    <string name=\"draw_mode\">Сурет салу режимі</string>\n    <string name=\"create_issue\">Мәселе жасау</string>\n    <string name=\"something_went_wrong_emphasis\">Ой… Бірдеңе дұрыс болмады. Төмендегі опцияларды пайдаланып маған жаза аласыз, мен шешім табуға тырысамын</string>\n    <string name=\"resize_and_convert\">Өлшемін өзгерту және түрлендіру</string>\n    <string name=\"resize_and_convert_sub\">Берілген кескіндердің өлшемін өзгертіңіз немесе оларды басқа пішімдерге түрлендіріңіз. Бір суретті таңдасаңыз, EXIF метадеректерін де осы жерде өңдеуге болады.</string>\n    <string name=\"max_colors_count\">Максималды түс саны</string>\n    <string name=\"crashlytics_sub\">Бұл қолданбаға бұзылу есептерін қолмен жинауға мүмкіндік береді</string>\n    <string name=\"analytics\">Аналитика</string>\n    <string name=\"analytics_sub\">Анонимді қолданбаны пайдалану статистикасын жинауға рұқсат ету</string>\n    <string name=\"image_exif_warning\">Қазіргі уақытта %1$s пішімі тек Android құрылғысында EXIF метадеректерін оқуға мүмкіндік береді. Шығарылған кескінде сақталған кезде метадеректер мүлдем болмайды.</string>\n    <string name=\"effort\">Күш</string>\n    <string name=\"allow_betas\">Бета нұсқасына рұқсат беріңіз</string>\n    <string name=\"images_order\">Суреттер тәртібі</string>\n    <string name=\"tolerance\">Толеранттылық</string>\n    <string name=\"remove_color\">Түсті жою</string>\n    <string name=\"recode\">Қайта кодтау</string>\n    <string name=\"pixel_size\">Пиксель өлшемі</string>\n    <string name=\"lock_draw_orientation\">Сызба бағдарын құлыптау</string>\n    <string name=\"lock_draw_orientation_sub\">Сурет салу режимінде қосылса, экран айналмайды</string>\n    <string name=\"tonal_spot\">Тоналды нүкте</string>\n    <string name=\"neutral\">Бейтарап</string>\n    <string name=\"vibrant\">Жанды</string>\n    <string name=\"expressive\">Экспрессивті</string>\n    <string name=\"mask_filter_sub\">Берілген бетперделенген аймақтарға сүзгі тізбегін қолданыңыз, әрбір маска аймағы өзінің сүзгілер жинағын анықтай алады</string>\n    <string name=\"add_mask\">Маска қосыңыз</string>\n    <string name=\"mask_indexed\">Маска %d</string>\n    <string name=\"mask_color\">Маска түсі</string>\n    <string name=\"mask_preview\">Масканы алдын ала қарау</string>\n    <string name=\"mask_preview_sub\">Сізге шамамен нәтиже көрсету үшін сызылған сүзгі маскасы көрсетіледі</string>\n    <string name=\"inverse_fill_type\">Кері толтыру түрі</string>\n    <string name=\"confetti\">Конфетти</string>\n    <string name=\"confetti_sub\">Конфетти сақтау, бөлісу және басқа негізгі әрекеттерде көрсетіледі</string>\n    <string name=\"secure_mode\">Қауіпсіз режим</string>\n    <string name=\"secure_mode_sub\">Шығу кезінде мазмұнды жасырады, сонымен қатар экранды түсіру немесе жазу мүмкін емес</string>\n    <string name=\"draw_arrows_sub\">Қосылған болса, сызба жолы меңзегіш көрсеткі ретінде көрсетіледі</string>\n    <string name=\"crop_description\">Суреттер енгізілген өлшемге дейін ортасынан қиылады. Кескін енгізілген өлшемдерден кішірек болса, кенеп берілген өң түсімен кеңейтіледі.</string>\n    <string name=\"donation\">Қайырымдылық</string>\n    <string name=\"image_stitching_sub\">Бір үлкен кескін алу үшін берілген кескіндерді біріктіріңіз</string>\n    <string name=\"pick_at_least_two_images\">Кем дегенде 2 суретті таңдаңыз</string>\n    <string name=\"output_image_scale\">Шығарылатын кескін масштабы</string>\n    <string name=\"image_orientation\">Кескінді бағдарлау</string>\n    <string name=\"horizontal\">Көлденең</string>\n    <string name=\"vertical\">Вертикалды</string>\n    <string name=\"scale_small_images_to_large\">Кішкентай кескіндерді үлкенге дейін масштабтаңыз</string>\n    <string name=\"scale_small_images_to_large_sub\">Қосылған болса, шағын кескіндер реттіліктегі ең үлкеніне дейін масштабталады</string>\n    <string name=\"regular\">Тұрақты</string>\n    <string name=\"pdf_tools_sub\">PDF файлдарымен жұмыс істеу: алдын ала қарау, кескіндер топтамасына түрлендіру немесе берілген суреттерден біреуін жасау</string>\n    <string name=\"neon\">Неон</string>\n    <string name=\"value_in_range\">%1$s - %2$s ауқымындағы мән</string>\n    <string name=\"auto_rotate_limits\">Автоматты айналдыру</string>\n    <string name=\"auto_rotate_limits_sub\">Кескінді бағдарлау үшін шектеу жолағын қабылдауға мүмкіндік береді</string>\n    <string name=\"containers_shadow\">Контейнерлер</string>\n    <string name=\"containers_shadow_sub\">Контейнерлердің артындағы көлеңкелі суретті қосады</string>\n    <string name=\"sliders_shadow\">Жүгірткілер</string>\n    <string name=\"switches_shadow\">Коммутаторлар</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">Түймелер</string>\n    <string name=\"sliders_shadow_sub\">Жүгірткілердің артындағы көлеңкелі суретті қосады</string>\n    <string name=\"switches_shadow_sub\">Коммутаторлардың артындағы көлеңке сызбасын қосады</string>\n    <string name=\"fabs_shadow_sub\">Қалқымалы әрекет түймелерінің артында көлеңкелі сурет салуды қосады</string>\n    <string name=\"buttons_shadow_sub\">Әдепкі түймелердің артындағы көлеңке сызбасын қосады</string>\n    <string name=\"app_bars_shadow\">Қолданба жолақтары</string>\n    <string name=\"app_bars_shadow_sub\">Қолданба жолақтарының артындағы көлеңкелі суретті қосады</string>\n    <string name=\"exit\">Шығу</string>\n    <string name=\"preview_closing\">Алдын ала қараудан қазір шықсаңыз, суреттерді қайта қосуыңыз керек</string>\n    <string name=\"image_format\">Сурет пішімі</string>\n    <string name=\"material_you_sub\">Кескіннен \\\"Material You \\\" палитрасын жасайды</string>\n    <string name=\"dark_colors\">Қою Түстер</string>\n    <string name=\"dark_colors_sub\">Жарық нұсқасының орнына түнгі режимнің түс схемасын қолданады</string>\n    <string name=\"copy_as_compose_code\">\\\"Jetpack Compose\\\" коды ретінде көшіріңіз</string>\n    <string name=\"linear_tilt_shift\">Сызықтық көлбеу жылжу</string>\n    <string name=\"ring_blur\">Сақинаның Бұлыңғырлығы</string>\n    <string name=\"cross_blur\">Көлденең Бұлыңғырлық</string>\n    <string name=\"circle_blur\">Шеңбер Бұлыңғыр</string>\n    <string name=\"star_blur\">Жұлдызды Бұлыңғырлық</string>\n    <string name=\"tags_to_remove\">Жою Үшін Тегтер</string>\n    <string name=\"apng_type_to_image\">Суреттерге APNG</string>\n    <string name=\"apng_type_to_image_sub\">APNG файлын суреттер топтамасына түрлендіру</string>\n    <string name=\"apng_tools\">APNG құралдары</string>\n    <string name=\"apng_tools_sub\">Суреттерді APNG суретіне түрлендіру немесе берілген APNG кескінінен жақтауларды шығарып алу</string>\n    <string name=\"apng_type_to_apng_sub\">Суреттер партиясын APNG файлына түрлендіру</string>\n    <string name=\"apng_type_to_apng\">Суреттер APNG</string>\n    <string name=\"select_apng_image_to_start\">Бастау үшін APNG кескінін таңдаңыз</string>\n    <string name=\"motion_blur\">Размытие движением</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Берілген файлдардан немесе кескіндерден Zip файлын жасаңыз</string>\n    <string name=\"drag_handle_width\">Тұтқаны ені сүйреңіз</string>\n    <string name=\"confetti_type\">Конфетти түрі</string>\n    <string name=\"festive\">Мерекелік</string>\n    <string name=\"explode\">Жарылу</string>\n    <string name=\"rain\">Жаңбыр</string>\n    <string name=\"corners\">Бұрыштар</string>\n    <string name=\"jxl_tools\">JXL құралдары</string>\n    <string name=\"jxl_tools_sub\">JXL ~ JPEG кодтауын сапа жоғалтпай орындаңыз немесе GIF/APNG форматын JXL анимациясына түрлендіріңіз.</string>\n    <string name=\"jxl_type_to_jpeg\">JXL - JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL-ден JPEG-ге жоғалтпай қайта кодтауды орындаңыз</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG-ден JXL-ге жоғалтпай қайта кодтауды орындаңыз</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG - JXL</string>\n    <string name=\"select_jxl_image_to_start\">Бастау үшін JXL кескінін таңдаңыз</string>\n    <string name=\"fast_gaussian_blur_2d\">Жылдам Gaussian Blur 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Жылдам Gaussian Blur 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Жылдам Gaussian Blur 4D</string>\n    <string name=\"auto_paste\">Көлік Пасха</string>\n    <string name=\"auto_paste_sub\">Қолданбаға алмасу буферінің деректерін автоматты қоюға рұқсат береді, сондықтан ол негізгі экранда пайда болады және сіз оны өңдей аласыз</string>\n    <string name=\"harmonization_color\">Гармонизация түсі</string>\n    <string name=\"harmonization_level\">Гармонизация деңгейі</string>\n    <string name=\"lanczos_bessel\">Ланчос Бессель</string>\n    <string name=\"lanczos_bessel_sub\">Бессель (jinc) функциясын пиксель мәндеріне қолдану арқылы жоғары сапалы интерполяцияны сақтайтын қайта үлгілеу әдісі</string>\n    <string name=\"gif_type_to_jxl\">JXL үшін GIF</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF кескіндерін JXL анимациялық суреттеріне түрлендіру</string>\n    <string name=\"apng_type_to_jxl\">APNG – JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG кескіндерін JXL анимациялық суреттеріне түрлендіру</string>\n    <string name=\"jxl_type_to_images\">JXL-ден Суреттерге</string>\n    <string name=\"jxl_type_to_images_sub\">JXL анимациясын суреттер топтамасына түрлендіру</string>\n    <string name=\"jxl_type_to_jxl\">Суреттер JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Суреттер партиясын JXL анимациясына түрлендіру</string>\n    <string name=\"behavior\">Мінез-құлық</string>\n    <string name=\"skip_file_picking\">Файлды таңдауды өткізіп жіберу</string>\n    <string name=\"skip_file_picking_sub\">Мүмкін болса, таңдалған экранда файл таңдау құралы бірден көрсетіледі</string>\n    <string name=\"generate_previews\">Алдын ала қарауларды жасау</string>\n    <string name=\"generate_previews_sub\">Алдын ала қарау генерациясын қосады, бұл кейбір құрылғыларда бұзылуларды болдырмауға көмектесуі мүмкін, сонымен қатар бір өңдеу опциясындағы кейбір өңдеу функцияларын өшіреді</string>\n    <string name=\"lossy_compression\">Жоғалған қысу</string>\n    <string name=\"lossy_compression_sub\">Файл өлшемін жоғалтпайтын орнына азайту үшін жоғалтатын қысуды пайдаланады</string>\n    <string name=\"compression_type\">Қысу түрі</string>\n    <string name=\"speed_sub\">Нәтижедегі кескінді декодтау жылдамдығын басқарады, бұл алынған кескінді тезірек ашуға көмектеседі, %1$s мәні ең баяу декодтауды білдіреді, ал %2$s - ең жылдам, бұл параметр шығыс кескін өлшемін арттыруы мүмкін</string>\n    <string name=\"sorting\">Сұрыптау</string>\n    <string name=\"sort_by_date\">Күн</string>\n    <string name=\"sort_by_date_reversed\">Күні (кері)</string>\n    <string name=\"sort_by_name\">Аты</string>\n    <string name=\"sort_by_name_reversed\">Аты (кері)</string>\n    <string name=\"channels_configuration\">Арналар конфигурациясы</string>\n    <string name=\"header_today\">Бүгін</string>\n    <string name=\"header_yesterday\">Кеше</string>\n    <string name=\"embedded_picker\">Енгізілген таңдау құралы</string>\n    <string name=\"embedded_picker_sub\">Кескін құралдар жинағының кескін таңдау құралы</string>\n    <string name=\"no_permissions\">Рұқсат жоқ</string>\n    <string name=\"request\">Сұраныс</string>\n    <string name=\"pick_multiple_media\">Бірнеше медианы таңдаңыз</string>\n    <string name=\"pick_single_media\">Бір медианы таңдаңыз</string>\n    <string name=\"pick\">Таңдау</string>\n    <string name=\"try_again\">Қайтадан байқап көріңіз</string>\n    <string name=\"show_settings_in_landscape\">Параметрлерді ландшафтта көрсету</string>\n    <string name=\"show_settings_in_landscape_sub\">Егер бұл өшірілсе, ландшафт режимінде параметрлер тұрақты көрінетін опцияның орнына әдеттегідей жоғарғы қолданбалар жолағындағы түймеде ашылады.</string>\n    <string name=\"fullscreen_settings\">Толық экран параметрлері</string>\n    <string name=\"fullscreen_settings_sub\">Оны қосыңыз және параметрлер беті жылжымалы тартпа парағының орнына әрқашан толық экран ретінде ашылады</string>\n    <string name=\"switch_type\">Ауыстыру түрі</string>\n    <string name=\"compose\">Құрастыру</string>\n    <string name=\"compose_switch_sub\">Jetpack құрастыру материалы Сіз ауыстырасыз</string>\n    <string name=\"material_you_switch_sub\">Сіз ауыстыратын материал</string>\n    <string name=\"max\">Макс</string>\n    <string name=\"resize_anchor\">Анкордың өлшемін өзгерту</string>\n    <string name=\"pixel_switch\">пиксел</string>\n    <string name=\"fluent_switch\">Еркін</string>\n    <string name=\"fluent_switch_sub\">\\\"Fluent\\\" дизайн жүйесіне негізделген қосқыш</string>\n    <string name=\"cupertino_switch\">Купертино</string>\n    <string name=\"cupertino_switch_sub\">\\\"Купертино\\\" дизайн жүйесіне негізделген қосқыш</string>\n    <string name=\"images_to_svg\">Суреттер SVG</string>\n    <string name=\"images_to_svg_sub\">SVG кескіндеріне берілген кескіндерді қадағалаңыз</string>\n    <string name=\"use_sampled_palette\">Үлгі палитрасын пайдаланыңыз</string>\n    <string name=\"use_sampled_palette_sub\">Бұл опция қосылған болса, кванттау палитрасы таңдалады</string>\n    <string name=\"path_omit\">Жолды қалдыру</string>\n    <string name=\"svg_warning\">Бұл құралды масштабты кішірейтусіз үлкен кескіндерді қадағалау үшін пайдалану ұсынылмайды, ол бұзылуға және өңдеу уақытын арттыруға әкелуі мүмкін.</string>\n    <string name=\"downscale_image\">Кескінді кішірейту</string>\n    <string name=\"downscale_image_sub\">Кескін өңдеу алдында кіші өлшемдерге дейін кішірейтіледі, бұл құралдың жылдамырақ және қауіпсіз жұмыс істеуіне көмектеседі</string>\n    <string name=\"min_color_ratio\">Минималды түс қатынасы</string>\n    <string name=\"lines_threshold\">Жолдардың шегі</string>\n    <string name=\"quadratic_threshold\">Квадраттық шек</string>\n    <string name=\"coordinates_rounding_tolerance\">Дөңгелектеу төзімділігін үйлестіреді</string>\n    <string name=\"path_scale\">Жол масштабы</string>\n    <string name=\"reset_properties\">Сипаттарды қалпына келтіру</string>\n    <string name=\"reset_properties_sub\">Барлық сипаттар әдепкі мәндерге орнатылады, бұл әрекетті қайтару мүмкін емес екенін ескеріңіз</string>\n    <string name=\"detailed\">Егжей-тегжейлі</string>\n    <string name=\"default_line_width\">Әдепкі сызық ені</string>\n    <string name=\"engine_mode\">Қозғалтқыш режимі</string>\n    <string name=\"legacy\">Мұра</string>\n    <string name=\"lstm_network\">LSTM желісі</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp;amp; LSTM</string>\n    <string name=\"convert\">Түрлендіру</string>\n    <string name=\"convert_sub\">Кескін топтамаларын берілген пішімге түрлендіру</string>\n    <string name=\"add_new_folder\">Жаңа қалта қосу</string>\n    <string name=\"tag_bits_per_sample\">Бір үлгідегі бит</string>\n    <string name=\"tag_compression\">Қысу</string>\n    <string name=\"tag_photometric_interpretation\">Фотометриялық интерпретация</string>\n    <string name=\"tag_samples_per_pixel\">Бір пиксельге арналған үлгілер</string>\n    <string name=\"tag_planar_configuration\">Жазық конфигурация</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr ішкі сынама алу</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Орналастыру</string>\n    <string name=\"tag_x_resolution\">X ажыратымдылығы</string>\n    <string name=\"tag_y_resolution\">Y Ажыратымдылығы</string>\n    <string name=\"tag_resolution_unit\">Ажыратымдылық бірлігі</string>\n    <string name=\"tag_strip_offsets\">Жолақтардың ығысулары</string>\n    <string name=\"tag_rows_per_strip\">Жолақтағы жолдар</string>\n    <string name=\"tag_strip_byte_counts\">Жолақ байт санаулары</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG алмасу пішімі</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG алмасу пішімінің ұзындығы</string>\n    <string name=\"tag_transfer_function\">Тасымалдау функциясы</string>\n    <string name=\"tag_white_point\">Ақ нүкте</string>\n    <string name=\"tag_primary_chromaticities\">Бастапқы хроматиктер</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr коэффициенттері</string>\n    <string name=\"tag_reference_black_white\">Анықтама қара ақ</string>\n    <string name=\"tag_datetime\">Күн уақыты</string>\n    <string name=\"tag_image_description\">Сурет сипаттамасы</string>\n    <string name=\"tag_make\">Жасаңыз</string>\n    <string name=\"tag_model\">Үлгі</string>\n    <string name=\"tag_software\">Бағдарламалық қамтамасыз ету</string>\n    <string name=\"tag_artist\">Суретші</string>\n    <string name=\"tag_copyright\">Авторлық құқық</string>\n    <string name=\"tag_exif_version\">Exif нұсқасы</string>\n    <string name=\"tag_flashpix_version\">Flashpix нұсқасы</string>\n    <string name=\"tag_color_space\">Түс кеңістігі</string>\n    <string name=\"tag_gamma\">Гамма</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X өлшемі</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y өлшемі</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Бір пиксельге қысылған бит</string>\n    <string name=\"tag_maker_note\">Жасаушы жазбасы</string>\n    <string name=\"tag_user_comment\">Пайдаланушы пікірі</string>\n    <string name=\"tag_related_sound_file\">Қатысты дыбыс файлы</string>\n    <string name=\"tag_datetime_original\">Күні Уақыт Түпнұсқа</string>\n    <string name=\"tag_datetime_digitized\">Цифрланған күн уақыты</string>\n    <string name=\"tag_offset_time\">Ауыстыру уақыты</string>\n    <string name=\"tag_offset_time_original\">Офсет уақыты түпнұсқасы</string>\n    <string name=\"tag_offset_time_digitized\">Офсет уақыты цифрланған</string>\n    <string name=\"tag_subsec_time\">Қосымша секунд уақыты</string>\n    <string name=\"tag_subsec_time_original\">Қосымша секунд уақыты Түпнұсқа</string>\n    <string name=\"tag_subsec_time_digitized\">Қосалқы сек уақыты Цифрланған</string>\n    <string name=\"tag_exposure_time\">Экспозиция уақыты</string>\n    <string name=\"tag_f_number\">F саны</string>\n    <string name=\"tag_exposure_program\">Экспозиция бағдарламасы</string>\n    <string name=\"tag_spectral_sensitivity\">Спектрлік сезімталдық</string>\n    <string name=\"tag_photographic_sensitivity\">Фотосезімталдық</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Сезімталдық түрі</string>\n    <string name=\"tag_standard_output_sensitivity\">Стандартты шығыс сезімталдығы</string>\n    <string name=\"tag_recommended_exposure_index\">Ұсынылатын экспозиция индексі</string>\n    <string name=\"tag_iso_speed\">ISO жылдамдығы</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO жылдамдығы ендік жж</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO жылдамдығы ендік zzz</string>\n    <string name=\"tag_shutter_speed_value\">Ысырма жылдамдығының мәні</string>\n    <string name=\"tag_aperture_value\">Диафрагма мәні</string>\n    <string name=\"tag_brightness_value\">Жарықтық мәні</string>\n    <string name=\"tag_exposure_bias_value\">Экспозицияның ауытқу мәні</string>\n    <string name=\"tag_max_aperture_value\">Максималды диафрагма мәні</string>\n    <string name=\"tag_subject_distance\">Тақырып қашықтығы</string>\n    <string name=\"tag_metering_mode\">Есептеу режимі</string>\n    <string name=\"tag_flash\">Жарқыл</string>\n    <string name=\"tag_subject_area\">Пән аймағы</string>\n    <string name=\"tag_focal_length\">Фокус ұзындығы</string>\n    <string name=\"tag_flash_energy\">Жарқыл энергиясы</string>\n    <string name=\"tag_spatial_frequency_response\">Кеңістіктік жиілікке жауап беру</string>\n    <string name=\"tag_focal_plane_x_resolution\">Фокус жазықтығы X ажыратымдылығы</string>\n    <string name=\"tag_focal_plane_y_resolution\">Фокус жазықтығы Y ажыратымдылығы</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Фокус жазықтығы ажыратымдылық бірлігі</string>\n    <string name=\"tag_subject_location\">Тақырып орны</string>\n    <string name=\"tag_exposure_index\">Экспозиция индексі</string>\n    <string name=\"tag_sensing_method\">Сезімдеу әдісі</string>\n    <string name=\"tag_file_source\">Файл көзі</string>\n    <string name=\"tag_cfa_pattern\">CFA үлгісі</string>\n    <string name=\"tag_custom_rendered\">Арнайы көрсетілген</string>\n    <string name=\"tag_exposure_mode\">Экспозиция режимі</string>\n    <string name=\"tag_white_balance\">Ақ баланс</string>\n    <string name=\"tag_digital_zoom_ratio\">Сандық масштабтау коэффициенті</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Фокус ұзындығы 35 мм пленка</string>\n    <string name=\"tag_scene_capture_type\">Көрініс түсіру түрі</string>\n    <string name=\"tag_gain_control\">Бақылауды алу</string>\n    <string name=\"tag_contrast\">Контраст</string>\n    <string name=\"tag_saturation\">Қанықтылық</string>\n    <string name=\"tag_sharpness\">Айқындық</string>\n    <string name=\"tag_device_setting_description\">Құрылғы параметрінің сипаттамасы</string>\n    <string name=\"tag_subject_distance_range\">Тақырып қашықтығы</string>\n    <string name=\"tag_image_unique_id\">Кескіннің бірегей идентификаторы</string>\n    <string name=\"tag_camera_owner_name\">Камера иесінің аты</string>\n    <string name=\"tag_body_serial_number\">Дененің сериялық нөмірі</string>\n    <string name=\"tag_lens_specification\">Линзаның сипаттамасы</string>\n    <string name=\"tag_lens_make\">Объектив жасау</string>\n    <string name=\"tag_lens_model\">Объектив үлгісі</string>\n    <string name=\"tag_lens_serial_number\">Объективтің сериялық нөмірі</string>\n    <string name=\"tag_gps_version_id\">GPS нұсқасының идентификаторы</string>\n    <string name=\"tag_gps_latitude_ref\">GPS ендік сілтемесі</string>\n    <string name=\"tag_gps_latitude\">GPS ендігі</string>\n    <string name=\"tag_gps_longitude_ref\">GPS бойлық сілтемесі</string>\n    <string name=\"tag_gps_longitude\">GPS бойлығы</string>\n    <string name=\"tag_gps_altitude_ref\">GPS биіктігі сілтемесі</string>\n    <string name=\"tag_gps_altitude\">GPS биіктігі</string>\n    <string name=\"tag_gps_timestamp\">GPS уақыт белгісі</string>\n    <string name=\"tag_gps_satellites\">GPS спутниктері</string>\n    <string name=\"tag_gps_status\">GPS күйі</string>\n    <string name=\"tag_gps_measure_mode\">GPS өлшеу режимі</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS жылдамдығы сілтемесі</string>\n    <string name=\"tag_gps_speed\">GPS жылдамдығы</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS Track</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img бағыты сілтемесі</string>\n    <string name=\"tag_gps_img_direction\">GPS Img бағыты</string>\n    <string name=\"tag_gps_map_datum\">GPS картасының деректері</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS мақсатты бойлық сілтемесі</string>\n    <string name=\"tag_gps_dest_longitude\">GPS мақсатты бойлық</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS тіреуіш</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS мақсатты қашықтығы сілтемесі</string>\n    <string name=\"tag_gps_dest_distance\">GPS мақсатты қашықтығы</string>\n    <string name=\"tag_gps_processing_method\">GPS өңдеу әдісі</string>\n    <string name=\"tag_gps_area_information\">GPS аймағы туралы ақпарат</string>\n    <string name=\"tag_gps_datestamp\">GPS күн белгісі</string>\n    <string name=\"tag_gps_differential\">GPS дифференциалы</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H орналасу қатесі</string>\n    <string name=\"tag_interoperability_index\">Өзара жұмыс істеу индексі</string>\n    <string name=\"tag_dng_version\">DNG нұсқасы</string>\n    <string name=\"tag_default_crop_size\">Әдепкі қию өлшемі</string>\n    <string name=\"tag_orf_preview_image_start\">Кескінді алдын ала қарауды бастау</string>\n    <string name=\"tag_orf_preview_image_length\">Кескін ұзындығын алдын ала қарау</string>\n    <string name=\"tag_orf_aspect_frame\">Аспект жақтауы</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Датчиктің төменгі жиегі</string>\n    <string name=\"tag_rw2_sensor_left_border\">Датчиктің сол жақ шекарасы</string>\n    <string name=\"tag_rw2_sensor_right_border\">Датчиктің оң жақ жиегі</string>\n    <string name=\"tag_rw2_sensor_top_border\">Сенсордың жоғарғы жиегі</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Берілген қаріп пен түспен жолға мәтін салыңыз</string>\n    <string name=\"font_size\">Қаріп өлшемі</string>\n    <string name=\"watermark_size\">Су таңбасының өлшемі</string>\n    <string name=\"repeat_text\">Мәтінді қайталау</string>\n    <string name=\"repeat_text_sub\">Ағымдағы мәтін бір рет салудың орнына жолдың соңына дейін қайталанады</string>\n    <string name=\"dash_size\">Сызық өлшемі</string>\n    <string name=\"draw_mode_image_sub\">Таңдалған кескінді берілген жол бойымен салу үшін пайдаланыңыз</string>\n    <string name=\"draw_image_sub\">Бұл сурет сызылған жолдың қайталанатын жазбасы ретінде пайдаланылады</string>\n    <string name=\"outlined_triangle_sub\">Сызылған үшбұрышты бастапқы нүктеден соңғы нүктеге дейін салады</string>\n    <string name=\"triangle_sub\">Сызылған үшбұрышты бастапқы нүктеден соңғы нүктеге дейін салады</string>\n    <string name=\"outlined_triangle\">Сызылған үшбұрыш</string>\n    <string name=\"triangle\">Үшбұрыш</string>\n    <string name=\"polygon_sub\">Бастапқы нүктеден соңғы нүктеге дейін көпбұрышты салады</string>\n    <string name=\"polygon\">Көпбұрыш</string>\n    <string name=\"outlined_polygon\">Құрылған көпбұрыш</string>\n    <string name=\"outlined_polygon_sub\">Бастапқы нүктеден соңғы нүктеге дейін сызылған көпбұрышты салады</string>\n    <string name=\"vertices\">Шыңдар</string>\n    <string name=\"draw_regular_polygon\">Тұрақты көпбұрышты сызу</string>\n    <string name=\"draw_regular_polygon_sub\">Еркін пішіннің орнына тұрақты болатын көпбұрышты сызыңыз</string>\n    <string name=\"star_sub\">Жұлдызшаны бастапқы нүктеден соңғы нүктеге дейін салады</string>\n    <string name=\"star\">Жұлдыз</string>\n    <string name=\"outlined_star\">Белгіленген жұлдыз</string>\n    <string name=\"outlined_star_sub\">Сызылған жұлдызды бастапқы нүктеден соңғы нүктеге дейін салады</string>\n    <string name=\"inner_radius_ratio\">Ішкі радиус қатынасы</string>\n    <string name=\"draw_regular_star\">Тұрақты жұлдызды сал</string>\n    <string name=\"draw_regular_star_sub\">Еркін пішіннің орнына тұрақты болатын жұлдызды сызыңыз</string>\n    <string name=\"antialias\">Антиалиас</string>\n    <string name=\"antialias_sub\">Өткір жиектерді болдырмау үшін антиалиазингті қосады</string>\n    <string name=\"open_edit_instead_of_preview\">Алдын ала қараудың орнына Өңдеуді ашыңыз</string>\n    <string name=\"open_edit_instead_of_preview_sub\">ImageToolbox қолданбасында ашу (алдын ала қарау) үшін кескінді таңдаған кезде, таңдау парағы алдын ала қараудың орнына ашылады.</string>\n    <string name=\"document_scanner\">Құжат сканері</string>\n    <string name=\"document_scanner_sub\">Құжаттарды сканерлеңіз және олардан PDF немесе бөлек кескіндер жасаңыз</string>\n    <string name=\"click_to_start_scanning\">Сканерлеуді бастау үшін басыңыз</string>\n    <string name=\"start_scanning\">Сканерлеуді бастаңыз</string>\n    <string name=\"save_as_pdf\">Pdf ретінде сақтау</string>\n    <string name=\"share_as_pdf\">Pdf ретінде бөлісіңіз</string>\n    <string name=\"options_below_is_for_images\">Төмендегі опциялар PDF емес, кескіндерді сақтауға арналған</string>\n    <string name=\"equalize_histogram_hsv\">HSV гистограммасын теңестіру</string>\n    <string name=\"equalize_histogram\">Гистограмманы теңестіру</string>\n    <string name=\"enter_percentage\">Процентті енгізіңіз</string>\n    <string name=\"allow_enter_by_text_field\">Мәтін өрісі арқылы енгізуге рұқсат етіңіз</string>\n    <string name=\"allow_enter_by_text_field_sub\">Оларды жылдам енгізу үшін алдын ала орнату таңдауының артындағы мәтін өрісін қосады</string>\n    <string name=\"scale_color_space\">Түс кеңістігінің масштабы</string>\n    <string name=\"linear\">Сызықтық</string>\n    <string name=\"equalize_histogram_pixelation\">Гистограмма пикселін теңестіру</string>\n    <string name=\"grid_size_x\">Тор өлшемі X</string>\n    <string name=\"grid_size_y\">Тор өлшемі Y</string>\n    <string name=\"equalize_histogram_adaptive\">Gistogram Adaptive теңестіру</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Адаптивті LUV гистограммасын теңестіру</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Гистограмманы теңестіру Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Мазмұнға қию</string>\n    <string name=\"frame_color\">Жақтау түсі</string>\n    <string name=\"color_to_ignore\">Елемеу үшін түс</string>\n    <string name=\"template\">Үлгі</string>\n    <string name=\"no_template_filters\">Үлгі сүзгілері қосылмаған</string>\n    <string name=\"create_new\">Жаңа жасау</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Сканерленген QR коды жарамды сүзгі үлгісі емес</string>\n    <string name=\"scan_qr_code\">QR кодын сканерлеңіз</string>\n    <string name=\"opened_file_have_no_filter_template\">Таңдалған файлда сүзгі үлгі деректері жоқ</string>\n    <string name=\"create_template\">Үлгі жасау</string>\n    <string name=\"template_name\">Үлгі атауы</string>\n    <string name=\"select_template_preview\">Бұл сурет осы сүзгі үлгісін алдын ала қарау үшін пайдаланылады</string>\n    <string name=\"template_filter\">Үлгі сүзгісі</string>\n    <string name=\"as_qr_code\">QR код суреті ретінде</string>\n    <string name=\"as_file\">Файл ретінде</string>\n    <string name=\"save_as_file\">Файл ретінде сақтау</string>\n    <string name=\"save_as_qr_code_image\">QR код суреті ретінде сақтаңыз</string>\n    <string name=\"delete_template\">Үлгіні жою</string>\n    <string name=\"delete_template_warn\">Таңдалған үлгі сүзгісін жойғалы жатырсыз. Бұл әрекетті қайтару мүмкін емес</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) атты сүзгі үлгісі қосылды</string>\n    <string name=\"filter_preview\">Сүзгі алдын ала қарау</string>\n    <string name=\"qr_code\">QR және штрих-код</string>\n    <string name=\"qr_code_sub\">QR кодын сканерлеңіз және оның мазмұнын алыңыз немесе жаңасын жасау үшін жолды қойыңыз</string>\n    <string name=\"code_content\">Код мазмұны</string>\n    <string name=\"scan_qr_code_to_replace_content\">Өрістегі мазмұнды ауыстыру үшін кез келген штрих-кодты сканерлеңіз немесе таңдалған түрі бар жаңа штрих-код жасау үшін бірдеңені теріңіз</string>\n    <string name=\"qr_description\">QR сипаттамасы</string>\n    <string name=\"min\">Мин</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR кодын сканерлеу үшін параметрлерде камераға рұқсат беріңіз</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Құжат сканерін сканерлеу үшін параметрлерде камераға рұқсат беріңіз</string>\n    <string name=\"cubic\">Текше</string>\n    <string name=\"bspline\">B-Сплайн</string>\n    <string name=\"hamming\">Хэминг</string>\n    <string name=\"hanning\">Ханнинг</string>\n    <string name=\"blackman\">Блэкман</string>\n    <string name=\"welch\">Уэлч</string>\n    <string name=\"quadric\">Квадрат</string>\n    <string name=\"gaussian\">Гаусс</string>\n    <string name=\"sphinx\">Сфинкс</string>\n    <string name=\"bartlett\">Барлетт</string>\n    <string name=\"robidoux\">Робиду</string>\n    <string name=\"robidoux_sharp\">Робиду Шарп</string>\n    <string name=\"spline16\">Сплайн 16</string>\n    <string name=\"spline36\">Сплайн 36</string>\n    <string name=\"spline64\">Сплайн 64</string>\n    <string name=\"kaiser\">Кайзер</string>\n    <string name=\"bartlett_hann\">Бартлет-О</string>\n    <string name=\"box\">Қорап</string>\n    <string name=\"bohman\">Боман</string>\n    <string name=\"lanczos2\">Ланчос 2</string>\n    <string name=\"lanczos3\">Ланчос 3</string>\n    <string name=\"lanczos4\">Ланчос 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Кубтық интерполяция ең жақын 16 пиксельді ескере отырып, біркелкі масштабтауды қамтамасыз етеді, екі сызықтыға қарағанда жақсы нәтиже береді.</string>\n    <string name=\"bspline_sub\">Қисық сызықты немесе бетті, икемді және үздіксіз пішінді бейнелеуді біркелкі интерполяциялау және жақындату үшін бөліктермен анықталған көпмүшелік функцияларды пайдаланады.</string>\n    <string name=\"hamming_sub\">Сигналдың жиектерін кішірейту арқылы спектрлік ағып кетуді азайту үшін қолданылатын терезе функциясы, сигналды өңдеуде пайдалы</string>\n    <string name=\"hanning_sub\">Сигналды өңдеу қолданбаларында спектрлік ағып кетуді азайту үшін әдетте қолданылатын Hann терезесінің нұсқасы</string>\n    <string name=\"blackman_sub\">Сигналдарды өңдеуде жиі қолданылатын спектрлік ағып кетуді азайту арқылы жақсы жиілікті ажыратымдылықты қамтамасыз ететін терезе функциясы</string>\n    <string name=\"welch_sub\">Сигналдарды өңдеу қолданбаларында жиі қолданылатын спектрлік ағып кетуді азайту арқылы жақсы жиілік ажыратымдылығын беруге арналған терезе функциясы</string>\n    <string name=\"quadric_sub\">Біркелкі және үздіксіз нәтижелерді қамтамасыз ететін интерполяция үшін квадраттық функцияны қолданатын әдіс</string>\n    <string name=\"gaussian_sub\">Гаусс функциясын қолданатын интерполяция әдісі, кескіндердегі шуды тегістеу және азайту үшін пайдалы</string>\n    <string name=\"sphinx_sub\">Ең аз артефактілермен жоғары сапалы интерполяцияны қамтамасыз ететін кеңейтілген қайта үлгілеу әдісі</string>\n    <string name=\"bartlett_sub\">Спектрлік ағып кетуді азайту үшін сигналды өңдеуде қолданылатын үшбұрышты терезе функциясы</string>\n    <string name=\"robidoux_sub\">Суреттің табиғи өлшемін өзгерту, айқындық пен тегістікті теңестіру үшін оңтайландырылған жоғары сапалы интерполяция әдісі</string>\n    <string name=\"robidoux_sharp_sub\">Кескін өлшемін анық өзгерту үшін оңтайландырылған Robidoux әдісінің айқынырақ нұсқасы</string>\n    <string name=\"spline16_sub\">16 түрту сүзгісі арқылы біркелкі нәтижелерді қамтамасыз ететін сплайн негізіндегі интерполяция әдісі</string>\n    <string name=\"spline36_sub\">36 түрту сүзгісі арқылы біркелкі нәтижелерді қамтамасыз ететін сплайн негізіндегі интерполяция әдісі</string>\n    <string name=\"spline64_sub\">64 түрту сүзгісі арқылы біркелкі нәтижелерді қамтамасыз ететін сплайн негізіндегі интерполяция әдісі</string>\n    <string name=\"kaiser_sub\">Кайзер терезесін пайдаланатын интерполяция әдісі, негізгі лоб ені мен бүйірлік лоб деңгейі арасындағы айырбасты жақсы бақылауды қамтамасыз етеді.</string>\n    <string name=\"bartlett_hann_sub\">Сигналды өңдеу кезінде спектрлік ағып кетуді азайту үшін қолданылатын Бартлетт пен Ханн терезелерін біріктіретін гибридті терезе функциясы</string>\n    <string name=\"box_sub\">Ең жақын пиксель мәндерінің орташа мәнін пайдаланатын қарапайым қайта іріктеу әдісі, көбінесе бұғатталған көрініске әкеледі.</string>\n    <string name=\"bohman_sub\">Сигналды өңдеу қолданбаларында жақсы жиілікті ажыратымдылықты қамтамасыз ететін спектрлік ағып кетуді азайту үшін пайдаланылатын терезе функциясы</string>\n    <string name=\"lanczos2_sub\">Ең аз артефактілермен жоғары сапалы интерполяция үшін 2 лобты Lanczos сүзгісін қолданатын қайта үлгілеу әдісі</string>\n    <string name=\"lanczos3_sub\">Ең аз артефактілермен жоғары сапалы интерполяция үшін 3 лобты Lanczos сүзгісін қолданатын қайта үлгілеу әдісі</string>\n    <string name=\"lanczos4_sub\">Ең аз артефактілермен жоғары сапалы интерполяция үшін 4 лобты Lanczos сүзгісін қолданатын қайта үлгілеу әдісі</string>\n    <string name=\"lanczos2_jinc_sub\">Ең аз артефактілермен жоғары сапалы интерполяцияны қамтамасыз ететін jinc функциясын пайдаланатын Lanczos 2 сүзгісінің нұсқасы</string>\n    <string name=\"lanczos3_jinc_sub\">Ең аз артефактілермен жоғары сапалы интерполяцияны қамтамасыз ететін jinc функциясын пайдаланатын Lanczos 3 сүзгісінің нұсқасы</string>\n    <string name=\"lanczos4_jinc_sub\">Ең аз артефактілермен жоғары сапалы интерполяцияны қамтамасыз ететін jinc функциясын пайдаланатын Lanczos 4 сүзгісінің нұсқасы</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Тегіс интерполяция және қайта үлгілеу үшін Hanning сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Жоғары сапалы қайта үлгілеуге арналған Robidoux сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_blackman\">Блэкмен ЭВЕ</string>\n    <string name=\"ewa_blackman_sub\">Қоңырау артефактілерін азайтуға арналған Блэкман сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Тегіс интерполяцияға арналған квадрикалық сүзгінің Эллиптикалық салмақты орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Анық нәтижелер үшін Robidoux Sharp сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Азайтылған бүркеншік атпен жоғары сапалы қайта үлгілеуге арналған Lanczos 3 Jinc сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ginseng\">женьшень</string>\n    <string name=\"ginseng_sub\">Айқындық пен тегістіктің жақсы тепе-теңдігі бар жоғары сапалы кескінді өңдеуге арналған қайта үлгілеу сүзгісі</string>\n    <string name=\"ewa_ginseng\">Женьшень EWA</string>\n    <string name=\"ewa_ginseng_sub\">Кескін сапасын жақсартуға арналған женьшень сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Ең аз артефактілермен айқын нәтижелерге қол жеткізу үшін Lanczos Sharp сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Ең өткір EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Өте анық кескінді қайта үлгілеуге арналған Lanczos 4 Sharpest сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Кескінді қайта үлгілеуге арналған Lanczos Soft сүзгісінің эллиптикалық орташа (EWA) нұсқасы</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Кескінді тегіс және артефактсыз масштабтау үшін Haasn жасаған қайта үлгілеу сүзгісі</string>\n    <string name=\"format_conversion\">Форматты түрлендіру</string>\n    <string name=\"format_conversion_sub\">Суреттер партиясын бір пішімнен екіншісіне түрлендіру</string>\n    <string name=\"dismiss_forever\">Мәңгілікке шығару</string>\n    <string name=\"image_stacking\">Кескінді жинақтау</string>\n    <string name=\"image_stacking_sub\">Таңдалған араластыру режимдерімен кескіндерді бірінің үстіне бірін жинаңыз</string>\n    <string name=\"add_image\">Кескін қосу</string>\n    <string name=\"bins_count\">Қоқыс жәшіктері</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Гистограмманы теңестіру Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Гистограмманы теңестіру адаптивті HSV</string>\n    <string name=\"edge_mode\">Жиек режимі</string>\n    <string name=\"clip\">Клип</string>\n    <string name=\"wrap\">Орау</string>\n    <string name=\"color_blind_scheme\">Түс соқырлығы</string>\n    <string name=\"color_blind_scheme_sub\">Таңдалған түс соқырлығы нұсқасына тақырып түстерін бейімдеу үшін режимді таңдаңыз</string>\n    <string name=\"protanomaly_sub\">Қызыл және жасыл реңктерді ажырату қиын</string>\n    <string name=\"deuteranomaly_sub\">Жасыл және қызыл реңктерді ажырату қиын</string>\n    <string name=\"tritanomaly_sub\">Көк және сары реңктерді ажырату қиын</string>\n    <string name=\"protanopia_sub\">Қызыл реңктерді қабылдай алмау</string>\n    <string name=\"deuteranopia_sub\">Жасыл реңктерді қабылдай алмау</string>\n    <string name=\"tritanopia_sub\">Көк реңктерді қабылдай алмау</string>\n    <string name=\"achromatomaly_sub\">Барлық түстерге сезімталдықтың төмендеуі</string>\n    <string name=\"achromatopsia_sub\">Толық түсті соқырлық, тек сұр реңктерді көру</string>\n    <string name=\"not_use_color_blind_scheme\">Color Blind схемасын пайдаланбаңыз</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Түстер тақырыпта көрсетілгендей болады</string>\n    <string name=\"sigmoidal\">Сигмоидальды</string>\n    <string name=\"lagrange_2\">Лагранж 2</string>\n    <string name=\"lagrange_2_sub\">2 ретті Лагранж интерполяциялық сүзгісі, біркелкі ауысулары бар жоғары сапалы кескінді масштабтау үшін жарамды</string>\n    <string name=\"lagrange_3\">Лагранж 3</string>\n    <string name=\"lagrange_3_sub\">Кескінді масштабтау үшін жақсырақ дәлдік пен тегіс нәтижелерді ұсынатын 3 ретті Лагранж интерполяциялық сүзгісі</string>\n    <string name=\"lanczos_6\">Ланчос 6</string>\n    <string name=\"lanczos_6_sub\">Кескінді нақтырақ және дәлірек масштабтауды қамтамасыз ететін, жоғарырақ реті 6 болатын Lanczos қайта үлгілеу сүзгісі.</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Кескінді қайта үлгілеу сапасын жақсарту үшін Jinc функциясын пайдаланатын Lanczos 6 сүзгісінің нұсқасы</string>\n    <string name=\"linear_box_blur\">Сызықтық қорап бұлыңғыр</string>\n    <string name=\"linear_tent_blur\">Сызықтық шатыр бұлдыры</string>\n    <string name=\"linear_gaussian_box_blur\">Сызықтық гаусс қорапшасының бұлыңғырлығы</string>\n    <string name=\"linear_stack_blur\">Сызықтық стек бұлыңғыр</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Сызықтық жылдам гаусс бұлыңғырлығы Келесі</string>\n    <string name=\"linear_fast_gaussian_blur\">Сызықтық жылдам гаусс бұлыңғырлығы</string>\n    <string name=\"linear_gaussian_blur\">Сызықтық Гаусс бұлыңғырлығы</string>\n    <string name=\"draw_filter_sub\">Бояу ретінде пайдалану үшін бір сүзгіні таңдаңыз</string>\n    <string name=\"replace_filter\">Сүзгіні ауыстыру</string>\n    <string name=\"pick_filter_info\">Оны суретте қылқалам ретінде пайдалану үшін төмендегі сүзгіні таңдаңыз</string>\n    <string name=\"tiff_compression_scheme\">TIFF қысу схемасы</string>\n    <string name=\"low_poly\">Төмен поли</string>\n    <string name=\"sand_painting\">Құммен сурет салу</string>\n    <string name=\"image_splitting\">Кескінді бөлу</string>\n    <string name=\"image_splitting_sub\">Бір кескінді жолдар немесе бағандар бойынша бөлу</string>\n    <string name=\"fit_to_bounds\">Шектерге сәйкес</string>\n    <string name=\"fit_to_bounds_sub\">Қажетті әрекетке қол жеткізу үшін кесу өлшемін өзгерту режимін осы параметрмен біріктіріңіз (Пікірлер арақатынасына қию/Сәйкестендіру)</string>\n    <string name=\"languages_imported\">Тілдер сәтті импортталды</string>\n    <string name=\"backup_ocr_models\">OCR үлгілерінің сақтық көшірмесін жасау</string>\n    <string name=\"import_word\">Импорттау</string>\n    <string name=\"export\">Экспорттау</string>\n    <string name=\"position\">Позиция</string>\n    <string name=\"center\">Орталық</string>\n    <string name=\"top_left\">Жоғарғы сол</string>\n    <string name=\"top_right\">Жоғарғы оң</string>\n    <string name=\"bottom_left\">Төменгі сол</string>\n    <string name=\"bottom_right\">Төменгі оң жақ</string>\n    <string name=\"top_center\">Жоғарғы орталық</string>\n    <string name=\"center_right\">Орталық оң</string>\n    <string name=\"bottom_center\">Төменгі орталық</string>\n    <string name=\"center_left\">Орталық сол</string>\n    <string name=\"target_image\">Мақсатты кескін</string>\n    <string name=\"palette_transfer\">Палитраны тасымалдау</string>\n    <string name=\"enhanced_oil\">Жетілдірілген май</string>\n    <string name=\"simple_old_tv\">Қарапайым ескі теледидар</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Готам</string>\n    <string name=\"simple_sketch\">Қарапайым эскиз</string>\n    <string name=\"soft_glow\">Жұмсақ жарқырау</string>\n    <string name=\"color_poster\">Түсті плакат</string>\n    <string name=\"tri_tone\">Үш тон</string>\n    <string name=\"third_color\">Үшінші түс</string>\n    <string name=\"clahe_oklab\">Клахе Оклаб</string>\n    <string name=\"clahe_oklch\">Клара Олкс</string>\n    <string name=\"clahe_jzazbz\">Клахе Джазбз</string>\n    <string name=\"polka_dot\">Полка нүкте</string>\n    <string name=\"clustered_2x2_dithering\">Кластерленген 2x2 Дитеринг</string>\n    <string name=\"clustered_4x4_dithering\">Кластерленген 4x4 дитеринг</string>\n    <string name=\"clustered_8x8_dithering\">Кластерленген 8x8 Дитеринг</string>\n    <string name=\"yililoma_dithering\">Йилиома Дитеринг</string>\n    <string name=\"no_favorite_options_selected\">Таңдаулы опциялар таңдалмаған, оларды құралдар бетіне қосыңыз</string>\n    <string name=\"add_favorites\">Таңдаулыларды қосу</string>\n    <string name=\"harmony_complementary\">Қосымша</string>\n    <string name=\"harmony_analogous\">Аналогты</string>\n    <string name=\"harmony_triadic\">Үштік</string>\n    <string name=\"harmony_split_complementary\">Бөлу қосымшасы</string>\n    <string name=\"harmony_tetradic\">Тетрадик</string>\n    <string name=\"harmony_square\">Шаршы</string>\n    <string name=\"harmony_analogous_complementary\">Аналогтық + Толықтауыш</string>\n    <string name=\"color_tools\">Түс құралдары</string>\n    <string name=\"color_tools_sub\">Араластырыңыз, тондар жасаңыз, реңктер жасаңыз және т.б</string>\n    <string name=\"color_harmonies\">Түс гармониясы</string>\n    <string name=\"color_shading\">Түс көлеңкесі</string>\n    <string name=\"variation\">Вариация</string>\n    <string name=\"tints\">Реңктер</string>\n    <string name=\"tones\">Тондар</string>\n    <string name=\"shades\">Көлеңкелер</string>\n    <string name=\"color_mixing\">Түсті араластыру</string>\n    <string name=\"color_info\">Түс туралы ақпарат</string>\n    <string name=\"selected_color\">Таңдалған түс</string>\n    <string name=\"color_to_mix\">Араластыратын түс</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Динамикалық түстер қосулы кезде monet пайдалану мүмкін емес</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Мақсатты LUT кескіні</string>\n    <string name=\"amatorka\">Әуесқой</string>\n    <string name=\"miss_etikate\">Этикет ханым</string>\n    <string name=\"soft_elegance\">Жұмсақ талғампаздық</string>\n    <string name=\"soft_elegance_variant\">Жұмсақ талғампаздық нұсқасы</string>\n    <string name=\"palette_transfer_variant\">Палитраны тасымалдау нұсқасы</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Мақсатты 3D LUT файлы (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Ағартқышты айналып өту</string>\n    <string name=\"candlelight\">Шам жарығы</string>\n    <string name=\"drop_blues\">Блюзді тастаңыз</string>\n    <string name=\"edgy_amber\">Қатты амбер</string>\n    <string name=\"fall_colors\">Күз түстері</string>\n    <string name=\"film_stock_50\">Фильм қоры 50</string>\n    <string name=\"foggy_night\">Тұманды түн</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Бейтарап LUT кескінін алыңыз</string>\n    <string name=\"save_empty_lut_sub\">Алдымен бейтарап LUT-ге сүзгіні қолдану үшін таңдаулы фотосуреттерді өңдеу қолданбасын пайдаланыңыз, оны осы жерден алуға болады. Бұл дұрыс жұмыс істеуі үшін әрбір пиксель түсі басқа пикселдерге тәуелді болмауы керек (мысалы, бұлыңғырлық жұмыс істемейді). Дайын болғаннан кейін, жаңа LUT кескінін 512*512 LUT сүзгісі үшін кіріс ретінде пайдаланыңыз</string>\n    <string name=\"pop_art\">Поп-арт</string>\n    <string name=\"celluloid\">Целлулоид</string>\n    <string name=\"coffee\">Кофе</string>\n    <string name=\"golden_forest\">Алтын орман</string>\n    <string name=\"greenish\">Жасыл түсті</string>\n    <string name=\"retro_yellow\">Ретро сары</string>\n    <string name=\"links_preview\">Сілтемелерді алдын ала қарау</string>\n    <string name=\"links_preview_sub\">Мәтін алуға болатын жерлерде (QRCode, OCR т.б.) сілтемені алдын ала қарауды қосады.</string>\n    <string name=\"links\">Сілтемелер</string>\n    <string name=\"ico_size_warning\">ICO файлдарын тек 256 x 256 максималды өлшемінде сақтауға болады</string>\n    <string name=\"gif_type_to_webp\">GIF-тен WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">GIF кескіндерін WEBP анимациялық суреттеріне түрлендіру</string>\n    <string name=\"webp_tools\">WEBP құралдары</string>\n    <string name=\"webp_tools_sub\">Суреттерді WEBP анимациялық суретіне түрлендіру немесе берілген WEBP анимациясынан кадрларды шығарып алу</string>\n    <string name=\"webp_type_to_image\">Суреттерге WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP файлын суреттер топтамасына түрлендіру</string>\n    <string name=\"webp_type_to_webp_sub\">Суреттер партиясын WEBP файлына түрлендіру</string>\n    <string name=\"webp_type_to_webp\">Суреттер WEBP</string>\n    <string name=\"select_webp_image_to_start\">Бастау үшін WEBP кескінін таңдаңыз</string>\n    <string name=\"manage_storage_extra_types\">Файлдарға толық рұқсат жоқ</string>\n    <string name=\"manage_storage_extra_types_sub\">JXL, QOI және Android жүйесінде кескін ретінде танылмаған басқа кескіндерді көру үшін барлық файлдарға рұқсат беріңіз. Рұқсатсыз Image Toolbox бұл кескіндерді көрсете алмайды</string>\n    <string name=\"default_draw_color\">Әдепкі сызу түсі</string>\n    <string name=\"default_draw_path_mode\">Әдепкі сызу жолы режимі</string>\n    <string name=\"add_timestamp\">Уақыт белгісін қосыңыз</string>\n    <string name=\"add_timestamp_sub\">Уақыт белгісін шығыс файл атауына қосуды қосады</string>\n    <string name=\"formatted_timestamp\">Пішімделген уақыт белгісі</string>\n    <string name=\"formatted_timestamp_sub\">Негізгі миллис орнына шығыс файл атауында уақыт белгісін пішімдеуді қосыңыз</string>\n    <string name=\"enable_timestamps_to_format_them\">Уақыт белгілерін олардың пішімін таңдау үшін қосыңыз</string>\n    <string name=\"one_time_save_location\">Орынды бір рет сақтау</string>\n    <string name=\"one_time_save_location_sub\">Негізінен барлық опцияларда сақтау түймесін ұзақ басу арқылы пайдалануға болатын бір рет сақтау орындарын қараңыз және өңдеңіз</string>\n    <string name=\"recently_used\">Жақында пайдаланылған</string>\n    <string name=\"ci_channel\">CI арнасы</string>\n    <string name=\"group\">Топ</string>\n    <string name=\"image_toolbox_in_telegram\">Telegram-дағы кескін құралдар жинағы 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Біздің чатқа қосылыңыз, онда сіз қалаған нәрсені талқылай аласыз, сонымен қатар мен бета нұсқалары мен хабарландыруларды жариялайтын CI арнасын қараңыз.</string>\n    <string name=\"ci_channel_sub\">Қолданбаның жаңа нұсқалары туралы хабарландыру алыңыз және хабарландыруларды оқыңыз</string>\n    <string name=\"fit_description\">Кескінді берілген өлшемдерге сәйкестендіру және фонға бұлыңғырлау немесе түс қолдану</string>\n    <string name=\"tools_arrangement\">Құралдарды реттеу</string>\n    <string name=\"group_tools_by_type\">Құралдарды түрлеріне қарай топтастыру</string>\n    <string name=\"group_tools_by_type_sub\">Негізгі экрандағы құралдарды реттелетін тізім реттеуінің орнына түрі бойынша топтайды</string>\n    <string name=\"default_values\">Әдепкі мәндер</string>\n    <string name=\"system_bars_visibility\">Жүйе жолақтарының көрінуі</string>\n    <string name=\"show_system_bars_by_swipe\">Жүйе жолақтарын сырғыту арқылы көрсету</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Жүйе жолақтары жасырылған болса, оларды көрсету үшін сырғыту мүмкіндігін қосады</string>\n    <string name=\"auto\">Авто</string>\n    <string name=\"hide_all\">Барлығын жасыру</string>\n    <string name=\"show_all\">Барлығын көрсету</string>\n    <string name=\"hide_nav_bar\">Навигация жолағын жасыру</string>\n    <string name=\"hide_status_bar\">Күй жолағын жасыру</string>\n    <string name=\"noise_generation\">Шудың пайда болуы</string>\n    <string name=\"noise_generation_sub\">Perlin немесе басқа түрлер сияқты әртүрлі шуды жасаңыз</string>\n    <string name=\"frequency\">Жиілік</string>\n    <string name=\"noise_type\">Шу түрі</string>\n    <string name=\"rotation_type\">Айналу түрі</string>\n    <string name=\"fractal_type\">Фракталды түрі</string>\n    <string name=\"octaves\">Октавалар</string>\n    <string name=\"lacunarity\">Лакунарлылық</string>\n    <string name=\"gain\">Табыс</string>\n    <string name=\"weighted_strength\">Салмақты күш</string>\n    <string name=\"ping_pong_strength\">Пинг-понг күші</string>\n    <string name=\"distance_function\">Қашықтық функциясы</string>\n    <string name=\"return_type\">Қайтару түрі</string>\n    <string name=\"jitter\">Дірілдеу</string>\n    <string name=\"domain_warp\">Доменнің бұзылуы</string>\n    <string name=\"alignment\">Туралау</string>\n    <string name=\"custom_filename\">Пайдаланушы файл аты</string>\n    <string name=\"custom_filename_sub\">Ағымдағы кескінді сақтау үшін пайдаланылатын орын мен файл атауын таңдаңыз</string>\n    <string name=\"saved_to_custom\">Пайдаланушы аты бар қалтаға сақталды</string>\n    <string name=\"collage_maker\">Коллаж жасаушы</string>\n    <string name=\"collage_maker_sub\">20 суретке дейін коллаждар жасаңыз</string>\n    <string name=\"collage_type\">Коллаж түрі</string>\n    <string name=\"collages_info\">Орынды реттеу үшін ауыстыру, жылжыту және масштабтау үшін кескінді басып тұрыңыз</string>\n    <string name=\"disable_rotation\">Айналуды өшіру</string>\n    <string name=\"disable_rotation_sub\">Екі саусақ қимылымен кескіндердің айналуын болдырмайды</string>\n    <string name=\"enable_snapping_to_borders\">Жиектерге түсіруді қосыңыз</string>\n    <string name=\"enable_snapping_to_borders_sub\">Жылжытқаннан немесе масштабтағаннан кейін кескіндер жақтау жиектерін толтыру үшін түсіріледі</string>\n    <string name=\"histogram\">Гистограмма</string>\n    <string name=\"histogram_sub\">RGB немесе Жарықтық кескінінің гистограммасы түзетулер енгізуге көмектеседі</string>\n    <string name=\"image_for_histogram\">Бұл кескін RGB және Brightness гистограммаларын жасау үшін пайдаланылады</string>\n    <string name=\"tesseract_options\">Tesseract опциялары</string>\n    <string name=\"tesseract_options_sub\">Тессеракт қозғалтқышы үшін кейбір кіріс айнымалыларын қолданыңыз</string>\n    <string name=\"custom_options\">Теңшелетін опциялар</string>\n    <string name=\"custom_params_info\">Параметрлерді мына үлгі бойынша енгізу керек: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Автоматты қию</string>\n    <string name=\"free_corners\">Еркін бұрыштар</string>\n    <string name=\"free_corners_sub\">Кескінді көпбұрыш бойынша қию, бұл да перспективаны түзетеді</string>\n    <string name=\"coerce_points_to_image_bounds\">Кескін шекараларына мәжбүрлеу нүктелері</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Ұпайлар кескін шекараларымен шектелмейді, бұл перспективаны дәлірек түзету үшін пайдалы</string>\n    <string name=\"mask\">Маска</string>\n    <string name=\"spot_heal_sub\">Сызылған жолдың астындағы мазмұнды толтыру</string>\n    <string name=\"spot_heal\">Емдеу нүктесі</string>\n    <string name=\"use_circle_kernel\">Шеңбер ядросын пайдаланыңыз</string>\n    <string name=\"opening\">Ашылу</string>\n    <string name=\"closing\">Жабу</string>\n    <string name=\"morphological_gradient\">Морфологиялық градиент</string>\n    <string name=\"top_hat\">Жоғарғы қалпақ</string>\n    <string name=\"black_hat\">Қара қалпақ</string>\n    <string name=\"tone_curves\">Тондық қисықтар</string>\n    <string name=\"reset_curves\">Қисықтарды қалпына келтіру</string>\n    <string name=\"reset_curves_sub\">Қисықтар әдепкі мәнге оралады</string>\n    <string name=\"line_style\">Сызық стилі</string>\n    <string name=\"gap_size\">Саңылау өлшемі</string>\n    <string name=\"dashed\">Сызық</string>\n    <string name=\"dot_dashed\">Нүкте сызықша</string>\n    <string name=\"stamped\">Мөр басылған</string>\n    <string name=\"zigzag\">Зигзаг</string>\n    <string name=\"dashed_sub\">Белгіленген саңылау өлшемімен сызылған жол бойымен үзік сызық сызады</string>\n    <string name=\"dot_dashed_sub\">Берілген жол бойымен нүкте және үзік сызық сызады</string>\n    <string name=\"defaultt_sub\">Тек әдепкі түзу сызықтар</string>\n    <string name=\"stamped_sub\">Белгіленген аралықпен жол бойымен таңдалған кескіндерді салады</string>\n    <string name=\"zigzag_sub\">Жол бойымен толқынды ирек сызбаларды салады</string>\n    <string name=\"zigzag_ratio\">Зигзаг қатынасы</string>\n    <string name=\"create_shortcut\">Таңбаша жасау</string>\n    <string name=\"create_shortcut_title\">Бекіту үшін құралды таңдаңыз</string>\n    <string name=\"create_shortcut_subtitle\">Құрал іске қосу құралының негізгі экранына таңбаша ретінде қосылады, қажетті әрекетке жету үшін оны \\\"Файлды таңдауды өткізіп жіберу\\\" параметрімен біріктіріп пайдаланыңыз.</string>\n    <string name=\"dont_stack_frames\">Жақтауларды жинақтамаңыз</string>\n    <string name=\"dont_stack_frames_sub\">Алдыңғы кадрларды жоюға мүмкіндік береді, сондықтан олар бір-біріне жиналмайды</string>\n    <string name=\"crossfade\">Кроссфад</string>\n    <string name=\"crossfade_sub\">Жақтаулар бір-біріне қиылысады</string>\n    <string name=\"crossfade_count\">Кроссфад кадрлары есептеледі</string>\n    <string name=\"threshold_one\">Бір табалдырық</string>\n    <string name=\"threshold_two\">Екінші шек</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Айна 101</string>\n    <string name=\"enhanced_zoom_blur\">Жетілдірілген масштабтауды бұлыңғырлау</string>\n    <string name=\"laplacian_simple\">Қарапайым лаплас</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Көмекші торы</string>\n    <string name=\"helper_grid_sub\">Нақты манипуляцияларға көмектесу үшін сызба аймағының үстіндегі тірек торын көрсетеді</string>\n    <string name=\"grid_color\">Тор түсі</string>\n    <string name=\"cell_width\">Ұяшық ені</string>\n    <string name=\"cell_height\">Ұяшықтың биіктігі</string>\n    <string name=\"compact_selectors\">Шағын селекторлар</string>\n    <string name=\"compact_selectors_sub\">Кейбір таңдауды басқару элементтері аз орын алу үшін ықшам орналасуды пайдаланады</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Суретке түсіру үшін параметрлерде камераға рұқсат беріңіз</string>\n    <string name=\"layout\">Орналасу</string>\n    <string name=\"main_screen_title\">Негізгі экран тақырыбы</string>\n    <string name=\"constant_rate_factor\">Тұрақты мөлшерлеме коэффициенті (CRF)</string>\n    <string name=\"crf_sub\">%1$s мәні салыстырмалы түрде шағын файл өлшеміне әкелетін баяу қысуды білдіреді. %2$s жылдамырақ қысуды білдіреді, нәтижесінде үлкен файл пайда болады.</string>\n    <string name=\"lut_library\">Лут кітапханасы</string>\n    <string name=\"lut_library_sub\">Жүктеп алғаннан кейін қолдануға болатын LUT жинағын жүктеп алыңыз</string>\n    <string name=\"lut_library_update_sub\">Жүктеп алғаннан кейін қолдануға болатын LUT жиынтығын жаңарту (тек жаңалары кезекке қойылады).</string>\n    <string name=\"filter_preview_image_sub\">Сүзгілер үшін әдепкі кескінді алдын ала қарауды өзгертіңіз</string>\n    <string name=\"filter_preview_image\">Кескінді алдын ала қарау</string>\n    <string name=\"hide\">Жасыру</string>\n    <string name=\"show\">Көрсету</string>\n    <string name=\"slider_type\">Слайдер түрі</string>\n    <string name=\"fancy\">Керемет</string>\n    <string name=\"material_2\">Материал 2</string>\n    <string name=\"fancy_sub\">Сәнді көрінетін сырғытпа. Бұл әдепкі опция</string>\n    <string name=\"material_2_sub\">Материал 2 сырғытпасы</string>\n    <string name=\"material_you_slider_sub\">Сіз сырғытатын материал</string>\n    <string name=\"apply\">Қолдану</string>\n    <string name=\"center_align_dialog_buttons\">Орталық диалогтық түймелер</string>\n    <string name=\"center_align_dialog_buttons_sub\">Диалогтардың түймелері мүмкіндігінше сол жақтың орнына орталықта орналасады</string>\n    <string name=\"open_source_licenses\">Ашық бастапқы лицензиялар</string>\n    <string name=\"open_source_licenses_sub\">Осы қолданбада пайдаланылатын ашық бастапқы кітапханалардың лицензияларын қараңыз</string>\n    <string name=\"area\">Аудан</string>\n    <string name=\"area_sub\">Пиксель аймағы қатынасын пайдаланып қайта үлгілеу. Ол муарсыз нәтижелер беретіндіктен кескінді жоюдың таңдаулы әдісі болуы мүмкін. Бірақ кескінді үлкейткенде, ол \\\"Ең жақын\\\" әдісіне ұқсайды.</string>\n    <string name=\"enable_tonemapping\">Tonemapping қосу</string>\n    <string name=\"enter_percent\">% енгізіңіз</string>\n    <string name=\"unknown_host\">Сайтқа кіру мүмкін емес, VPN пайдаланып көріңіз немесе URL мекенжайының дұрыстығын тексеріңіз</string>\n    <string name=\"markup_layers\">Белгілеу қабаттары</string>\n    <string name=\"markup_layers_sub\">Суреттерді, мәтінді және т.б. еркін орналастыру мүмкіндігі бар қабаттар режимі</string>\n    <string name=\"edit_layer\">Қабатты өңдеу</string>\n    <string name=\"layers_on_image\">Суреттегі қабаттар</string>\n    <string name=\"layers_on_image_sub\">Кескінді фон ретінде пайдаланыңыз және оның үстіне әртүрлі қабаттарды қосыңыз</string>\n    <string name=\"layers_on_background\">Фондағы қабаттар</string>\n    <string name=\"layers_on_background_sub\">Бірінші нұсқа сияқты, бірақ суреттің орнына түсті</string>\n    <string name=\"beta\">Бета</string>\n    <string name=\"fast_settings_side\">Жылдам параметрлер жағы</string>\n    <string name=\"fast_settings_side_sub\">Суреттерді өңдеу кезінде таңдалған жағына қалқымалы жолақты қосыңыз, ол басқан кезде жылдам параметрлерді ашады</string>\n    <string name=\"clear_selection\">Таңдауды тазалау</string>\n    <string name=\"settings_group_visibility_hidden\">\\\"%1$s\\\" параметр тобы әдепкі бойынша жиырылады</string>\n    <string name=\"settings_group_visibility_visible\">\\\"%1$s\\\" параметр тобы әдепкі бойынша кеңейтіледі</string>\n    <string name=\"base_64_tools\">Base64 құралдары</string>\n    <string name=\"base_64_tools_sub\">Base64 жолын кескінге декодтаңыз немесе кескінді Base64 пішіміне кодтаңыз</string>\n    <string name=\"base_64\">База 64</string>\n    <string name=\"not_a_valid_base_64\">Берілген мән жарамды Base64 жолы емес</string>\n    <string name=\"copy_not_a_valid_base_64\">Бос немесе жарамсыз Base64 жолын көшіру мүмкін емес</string>\n    <string name=\"paste_base_64\">64 негізін қойыңыз</string>\n    <string name=\"copy_base_64\">Base64 көшіру</string>\n    <string name=\"base_64_tips\">Base64 жолын көшіру немесе сақтау үшін суретті жүктеңіз. Егер сізде жолдың өзі болса, суретті алу үшін оны жоғарыға қоюға болады</string>\n    <string name=\"save_base_64\">Base64 сақтау</string>\n    <string name=\"share_base_64\">64 базасын бөлісу</string>\n    <string name=\"options\">Параметрлер</string>\n    <string name=\"actions\">Әрекеттер</string>\n    <string name=\"import_base_64\">Импорттық база 64</string>\n    <string name=\"base_64_actions\">Base64 әрекеттері</string>\n    <string name=\"add_outline\">Құрылымды қосу</string>\n    <string name=\"add_outline_sub\">Белгіленген түсі мен ені бар мәтіннің айналасына контур қосыңыз</string>\n    <string name=\"outline_color\">Контур түсі</string>\n    <string name=\"outline_size\">Контур өлшемі</string>\n    <string name=\"rotation\">Айналу</string>\n    <string name=\"checksum_as_filename\">Файл аты ретінде бақылау сомасы</string>\n    <string name=\"checksum_as_filename_sub\">Шығарылатын кескіндердің деректердің бақылау сомасына сәйкес атауы болады</string>\n    <string name=\"free_software_partner\">Тегін бағдарламалық қамтамасыз ету (серіктес)</string>\n    <string name=\"free_software_partner_sub\">Android қолданбаларының серіктес арнасындағы пайдалырақ бағдарламалық құрал</string>\n    <string name=\"algorithms\">Алгоритм</string>\n    <string name=\"checksum_tools\">Бақылау сомасы құралдары</string>\n    <string name=\"checksum_tools_sub\">Бақылау сомасын салыстырыңыз, хэштерді есептеңіз немесе әртүрлі хэштеу алгоритмдерін пайдаланып файлдардан он алтылық жолдарды жасаңыз</string>\n    <string name=\"calculate\">Есептеу</string>\n    <string name=\"text_hash\">Мәтін хэші</string>\n    <string name=\"checksum\">Бақылау сомасы</string>\n    <string name=\"pick_file_to_checksum\">Таңдалған алгоритм негізінде бақылау сомасын есептеу үшін файлды таңдаңыз</string>\n    <string name=\"enter_text_to_checksum\">Таңдалған алгоритм негізінде бақылау сомасын есептеу үшін мәтінді енгізіңіз</string>\n    <string name=\"source_checksum\">Бастапқы бақылау сомасы</string>\n    <string name=\"checksum_to_compare\">Салыстыру үшін бақылау сомасы</string>\n    <string name=\"match\">Сәйкес!</string>\n    <string name=\"difference\">Айырмашылық</string>\n    <string name=\"match_sub\">Бақылау сомасы тең, ол қауіпсіз болуы мүмкін</string>\n    <string name=\"difference_sub\">Бақылау сомасы бірдей емес, файл қауіпті болуы мүмкін!</string>\n    <string name=\"mesh_gradients\">Тор градиенттері</string>\n    <string name=\"collection_mesh_gradients_sub\">Mesh Gradients онлайн жинағын қараңыз</string>\n    <string name=\"wrong_font\">Тек TTF және OTF қаріптерін импорттауға болады</string>\n    <string name=\"import_font\">Импорттау қаріпі (TTF/OTF)</string>\n    <string name=\"export_fonts\">Қаріптерді экспорттау</string>\n    <string name=\"imported_fonts\">Импортталған қаріптер</string>\n    <string name=\"error_while_saving\">Әрекетті сақтау кезінде қате орын алды, шығыс қалтасын өзгертіп көріңіз</string>\n    <string name=\"filename_is_not_set\">Файл атауы орнатылмаған</string>\n    <string name=\"none\">Жоқ</string>\n    <string name=\"custom_pages\">Теңшелетін беттер</string>\n    <string name=\"pages_selection\">Беттерді таңдау</string>\n    <string name=\"tool_exit_confirmation\">Құралдан шығуды растау</string>\n    <string name=\"tool_exit_confirmation_sub\">Белгілі бір құралдарды пайдалану кезінде сақталмаған өзгерістер болса және оны жабуға әрекеттенсеңіз, растау диалогы көрсетіледі</string>\n    <string name=\"edit_exif_screen\">EXIF файлын өңдеу</string>\n    <string name=\"edit_exif_screen_sub\">Бір кескіннің метадеректерін қайта қыспай өзгертіңіз</string>\n    <string name=\"edit_exif_tag\">Қол жетімді тегтерді өңдеу үшін түртіңіз</string>\n    <string name=\"change_sticker\">Стикерді өзгерту</string>\n    <string name=\"fit_width\">Сәйкес ені</string>\n    <string name=\"fit_height\">Сәйкес биіктік</string>\n    <string name=\"batch_compare\">Пакеттік салыстыру</string>\n    <string name=\"pick_files_to_checksum\">Таңдалған алгоритм негізінде бақылау сомасын есептеу үшін файлды/файлдарды таңдаңыз</string>\n    <string name=\"pick_files\">Файлдарды таңдаңыз</string>\n    <string name=\"pick_directory\">Каталогты таңдаңыз</string>\n    <string name=\"head_length_scale\">Бас ұзындығы шкаласы</string>\n    <string name=\"stamp\">Мөр</string>\n    <string name=\"timestamp\">Уақыт белгісі</string>\n    <string name=\"format_pattern\">Формат үлгісі</string>\n    <string name=\"padding\">Толтырғыш</string>\n    <string name=\"image_cutting\">Кескінді кесу</string>\n    <string name=\"image_cutting_sub\">Кескін бөлігін кесіп, сол жақтарын (кері болуы мүмкін) тік немесе көлденең сызықтармен біріктіріңіз</string>\n    <string name=\"vertical_pivot_line\">Тік айналмалы сызық</string>\n    <string name=\"horizontal_pivot_line\">Көлденең айналмалы сызық</string>\n    <string name=\"inverse_selection\">Кері таңдау</string>\n    <string name=\"inverse_vertical_selection_sub\">Кесілген аумақтың айналасындағы бөліктерді біріктірудің орнына тік кесілген бөлік қалдырылады</string>\n    <string name=\"inverse_horizontal_selection_sub\">Кесілген аумақтың айналасындағы бөліктерді біріктірудің орнына көлденең кесілген бөлік қалдырылады</string>\n    <string name=\"collection_mesh_gradients\">Тор градиенттерінің жинағы</string>\n    <string name=\"mesh_gradients_sub\">Түйіндердің реттелетін саны мен ажыратымдылығы бар торлы градиент жасаңыз</string>\n    <string name=\"gradient_maker_type_image_mesh\">Торлы градиент қабаттасуы</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Берілген кескіндердің жоғарғы жағындағы тор градиентін құрастырыңыз</string>\n    <string name=\"points_customization\">Ұпайларды теңшеу</string>\n    <string name=\"grid_size\">Тор өлшемі</string>\n    <string name=\"resolution_x\">X ажыратымдылығы</string>\n    <string name=\"resolution_y\">Y шешімі</string>\n    <string name=\"resolution\">Ажыратымдылық</string>\n    <string name=\"pixel_by_pixel\">Pixel by Pixel</string>\n    <string name=\"highlight_color\">Түсті бөлектеу</string>\n    <string name=\"pixel_comparison_type\">Пиксельді салыстыру түрі</string>\n    <string name=\"scan_barcode\">Штрих-кодты сканерлеу</string>\n    <string name=\"height_ratio\">Биіктік қатынасы</string>\n    <string name=\"barcode_type\">Штрихкод түрі</string>\n    <string name=\"enforce_bw\">B/W режимін орындау</string>\n    <string name=\"enforce_bw_sub\">Штрих-код кескіні толығымен ақ-қара болады және қолданбаның тақырыбы бойынша боялмайды</string>\n    <string name=\"barcodes_sub\">Кез келген штрих-кодты сканерлеңіз (QR, EAN, AZTEC, …) және оның мазмұнын алыңыз немесе жаңасын жасау үшін мәтініңізді қойыңыз.</string>\n    <string name=\"no_barcode_found\">Штрихкод табылмады</string>\n    <string name=\"generated_barcode_will_be_here\">Жасалған штрих-код осында болады</string>\n    <string name=\"audio_cover_extractor\">Аудио мұқабалар</string>\n    <string name=\"audio_cover_extractor_sub\">Аудио файлдардан альбом мұқабасының кескіндерін шығарып алыңыз, ең көп таралған пішімдерге қолдау көрсетіледі</string>\n    <string name=\"pick_audio_to_start\">Бастау үшін дыбысты таңдаңыз</string>\n    <string name=\"pick_audio\">Аудио таңдаңыз</string>\n    <string name=\"no_covers_found\">Ешқандай мұқаба табылмады</string>\n    <string name=\"send_logs\">Журналдарды жіберу</string>\n    <string name=\"send_logs_sub\">Қолданба журналдары файлын ортақ пайдалану үшін басыңыз, бұл мәселені анықтауға және мәселелерді шешуге көмектеседі</string>\n    <string name=\"crash_title\">Ой… Бірдеңе дұрыс болмады</string>\n    <string name=\"crash_subtitle\">Төмендегі опцияларды пайдаланып маған хабарласуыңызға болады, мен шешімді табуға тырысамын.\\n(Журналдарды тіркеуді ұмытпаңыз)</string>\n    <string name=\"ocr_write_to_file\">Файлға жазу</string>\n    <string name=\"ocr_write_to_file_sub\">Суреттер топтамасынан мәтінді шығарып, оны бір мәтіндік файлда сақтаңыз</string>\n    <string name=\"ocr_write_to_metadata\">Метадеректерге жазу</string>\n    <string name=\"ocr_write_to_metadata_sub\">Әр суреттен мәтінді шығарып, оны салыстырмалы фотосуреттердің EXIF ​​ақпаратына орналастырыңыз</string>\n    <string name=\"invisible_mode\">Көрінбейтін режим</string>\n    <string name=\"invisible_mode_sub\">Суреттеріңіздің байттары ішінде көзге көрінбейтін су белгілерін жасау үшін стеганографияны пайдаланыңыз</string>\n    <string name=\"use_lsb\">LSB пайдаланыңыз</string>\n    <string name=\"use_lsb_sub\">LSB (аз маңызды бит) стеганография әдісі пайдаланылады, әйтпесе FD (жиілік домені)</string>\n    <string name=\"auto_remove_red_eyes\">Қызыл көзді автоматты түрде жою</string>\n    <string name=\"password\">Құпия сөз</string>\n    <string name=\"unlock\">Құлыпты ашу</string>\n    <string name=\"pdf_is_protected\">PDF қорғалған</string>\n    <string name=\"operation_almost_complete\">Операция аяқталуға жақын. Қазір бас тарту үшін оны қайта іске қосу қажет болады</string>\n    <string name=\"sort_by_date_modified\">Өзгертілген күні</string>\n    <string name=\"sort_by_date_modified_reversed\">Өзгертілген күні (керісінше)</string>\n    <string name=\"sort_by_size\">Өлшем</string>\n    <string name=\"sort_by_size_reversed\">Өлшем (кері)</string>\n    <string name=\"sort_by_mime_type\">MIME түрі</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME түрі (кері)</string>\n    <string name=\"sort_by_extension\">Кеңейтім</string>\n    <string name=\"sort_by_extension_reversed\">Кеңейтім (кері)</string>\n    <string name=\"sort_by_date_added\">Қосылған күні</string>\n    <string name=\"sort_by_date_added_reversed\">Қосылған күні (кері)</string>\n    <string name=\"left_to_right\">Солдан оңға</string>\n    <string name=\"right_to_left\">Оңнан солға</string>\n    <string name=\"top_to_bottom\">Жоғарыдан төменге</string>\n    <string name=\"bottom_to_top\">Төменнен жоғарыға</string>\n    <string name=\"liquid_glass\">Сұйық шыны</string>\n    <string name=\"liquid_glass_sub\">Жақында жарияланған IOS 26 және оның сұйық шыны дизайн жүйесіне негізделген қосқыш</string>\n    <string name=\"pick_image_or_base64\">Төмендегі суретті таңдаңыз немесе Base64 деректерін қойыңыз/импорттаңыз</string>\n    <string name=\"type_image_link\">Бастау үшін сурет сілтемесін теріңіз</string>\n    <string name=\"paste_link\">Сілтемені қою</string>\n    <string name=\"kaleidoscope\">Калейдоскоп</string>\n    <string name=\"secondary_angle\">Қосымша бұрыш</string>\n    <string name=\"sides\">Тараптар</string>\n    <string name=\"channel_mix\">Арна қоспасы</string>\n    <string name=\"blue_green\">Көк жасыл</string>\n    <string name=\"red_blue\">Қызыл көк</string>\n    <string name=\"green_red\">Жасыл қызыл</string>\n    <string name=\"into_red\">Қызылға</string>\n    <string name=\"into_green\">Жасыл түске</string>\n    <string name=\"into_blue\">Көк түске</string>\n    <string name=\"cyan\">Көгілдір</string>\n    <string name=\"magenta\">Қызыл қызыл</string>\n    <string name=\"yellow\">Сары</string>\n    <string name=\"color_halftone\">Түс жарты реңк</string>\n    <string name=\"contour\">Контур</string>\n    <string name=\"levels\">Деңгейлер</string>\n    <string name=\"offset\">Офсет</string>\n    <string name=\"voronoi_crystallize\">Воронойдың кристалдануы</string>\n    <string name=\"shape\">Пішін</string>\n    <string name=\"stretch\">Созылу</string>\n    <string name=\"randomness\">Кездейсоқтық</string>\n    <string name=\"despeckle\">Деспекл</string>\n    <string name=\"diffuse\">Диффузиялық</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Екінші радиус</string>\n    <string name=\"equalize\">Теңестіру</string>\n    <string name=\"glow\">Жарқырау</string>\n    <string name=\"whirl_and_pinch\">Айналаңыз және қысыңыз</string>\n    <string name=\"pointillize\">Пунтилизация</string>\n    <string name=\"border_color\">Жиек түсі</string>\n    <string name=\"polar_coordinates\">Полярлық координаттар</string>\n    <string name=\"rect_to_polar\">Полярға тік</string>\n    <string name=\"polar_to_rect\">Полярдан тікке дейін</string>\n    <string name=\"invert_in_circle\">Шеңберге айналдыру</string>\n    <string name=\"reduce_noise\">Шуды азайту</string>\n    <string name=\"simple_solarize\">Қарапайым Solarize</string>\n    <string name=\"weave\">Тоқу</string>\n    <string name=\"x_gap\">X аралығы</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X Ені</string>\n    <string name=\"y_wdth\">Y Ені</string>\n    <string name=\"twirl\">Бұралу</string>\n    <string name=\"rubber_stmp\">Резеңке мөртабан</string>\n    <string name=\"smear\">Жағынды</string>\n    <string name=\"density\">Тығыздығы</string>\n    <string name=\"mix\">Араластырыңыз</string>\n    <string name=\"sphere_lensh_distortion\">Сфералық линзаның бұрмалануы</string>\n    <string name=\"refraction_index\">Сыну көрсеткіші</string>\n    <string name=\"arc\">Арк</string>\n    <string name=\"spread_angle\">Таралу бұрышы</string>\n    <string name=\"sparkle\">Жарқырау</string>\n    <string name=\"rays\">Сәулелер</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Градиент</string>\n    <string name=\"moire\">Мэри</string>\n    <string name=\"autumn\">Күз</string>\n    <string name=\"bone\">Сүйек</string>\n    <string name=\"jet\">Реактивті</string>\n    <string name=\"winter\">Қыс</string>\n    <string name=\"ocean\">Мұхит</string>\n    <string name=\"summer\">Жаз</string>\n    <string name=\"spring\">Көктем</string>\n    <string name=\"cool_variant\">Салқын нұсқа</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Қызғылт</string>\n    <string name=\"hot\">Ыстық</string>\n    <string name=\"parula\">Сөз</string>\n    <string name=\"magma\">Магма</string>\n    <string name=\"inferno\">Тозақ</string>\n    <string name=\"plasma\">Плазма</string>\n    <string name=\"viridis\">Виридис</string>\n    <string name=\"cividis\">Азаматтар</string>\n    <string name=\"twilight\">Ымырт</string>\n    <string name=\"twilight_shifted\">Ымырт ауысты</string>\n    <string name=\"auto_perspective\">Перспективалық авто</string>\n    <string name=\"deskew\">Дескрипт</string>\n    <string name=\"allow_crop\">Кесуге рұқсат етіңіз</string>\n    <string name=\"crop_or_perspective\">Кесу немесе перспектива</string>\n    <string name=\"absolute\">Абсолютті</string>\n    <string name=\"turbo\">Турбо</string>\n    <string name=\"deep_green\">Қою жасыл</string>\n    <string name=\"lens_correction\">Линзаны түзету</string>\n    <string name=\"target_lens_profile\">JSON пішіміндегі мақсатты линза профилі файлы</string>\n    <string name=\"download_ready_lens_profiles\">Дайын объектив профильдерін жүктеп алыңыз</string>\n    <string name=\"part_percents\">Бөлшек пайыздар</string>\n    <string name=\"export_as_json\">JSON ретінде экспорттау</string>\n    <string name=\"export_as_json_sub\">Json көрінісі ретінде палитра деректерімен жолды көшіріңіз</string>\n    <string name=\"seam_carving\">Тігіс оюы</string>\n    <string name=\"home_screen\">Негізгі экран</string>\n    <string name=\"lock_screen\">Экранды құлыптау</string>\n    <string name=\"built_in\">Кірістірілген</string>\n    <string name=\"wallpapers_export\">Түсқағаздар экспорты</string>\n    <string name=\"refresh\">Жаңарту</string>\n    <string name=\"wallpapers_export_sub\">Ағымдағы үй, құлып және кірістірілген тұсқағаздарды алыңыз</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Барлық файлдарға кіруге рұқсат беріңіз, бұл тұсқағаздарды алу үшін қажет</string>\n    <string name=\"allow_read_media_images_for_wp\">Сыртқы жадты басқару рұқсаты жеткіліксіз, суреттерге кіруге рұқсат беру керек, \\\"Барлығына рұқсат беру\\\" опциясын таңдауды ұмытпаңыз.</string>\n    <string name=\"add_preset_to_filename\">Файл атауына алдын ала орнатуды қосыңыз</string>\n    <string name=\"add_preset_to_filename_sub\">Кескін файлының атына таңдалған алдын ала орнатылған жұрнақ қосады</string>\n    <string name=\"add_image_scale_mode_to_filename\">Файл атына кескін масштабы режимін қосыңыз</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Кескін файлының атына таңдалған кескін масштабы режимі бар жұрнақ қосады</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Суретті кескінге ұқсайтын ascii мәтініне түрлендіру</string>\n    <string name=\"params\">Парам</string>\n    <string name=\"invert_colors_ascii_sub\">Кейбір жағдайларда жақсы нәтиже алу үшін кескінге теріс сүзгіні қолданады</string>\n    <string name=\"processing_screenshot\">Скриншот өңделуде</string>\n    <string name=\"screenshot_not_captured_try_again\">Скриншот түсірілмеді, әрекетті қайталаңыз</string>\n    <string name=\"skipped_saving\">Сақтау өткізіп жіберілді</string>\n    <string name=\"skipped_saving_multiple\">%1$s файлдар өткізіп жіберілді</string>\n    <string name=\"allow_skip_if_larger\">Үлкенірек болса, өткізіп жіберуге рұқсат етіңіз</string>\n    <string name=\"allow_skip_if_larger_sub\">Нәтижедегі файл өлшемі түпнұсқадан үлкенірек болса, кейбір құралдарға кескіндерді сақтауды өткізіп жіберуге рұқсат етіледі</string>\n    <string name=\"qr_type_calendar_event\">Күнтізбе оқиғасы</string>\n    <string name=\"qr_type_contact_info\">Байланыс</string>\n    <string name=\"qr_type_email\">Электрондық пошта</string>\n    <string name=\"qr_type_geo_point\">Орналасқан жері</string>\n    <string name=\"qr_type_phone\">Телефон</string>\n    <string name=\"qr_type_plain\">Мәтін</string>\n    <string name=\"qr_type_sms\">қысқаша хабар қызметі</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Сымсыз дәлдiк</string>\n    <string name=\"open_network\">Ашық желі</string>\n    <string name=\"not_specified\">Жоқ</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Телефон</string>\n    <string name=\"message\">Хабарлама</string>\n    <string name=\"address\">Мекенжай</string>\n    <string name=\"subject\">Тақырып</string>\n    <string name=\"body\">Дене</string>\n    <string name=\"name\">Аты</string>\n    <string name=\"organization\">Ұйымдастыру</string>\n    <string name=\"title\">Тақырып</string>\n    <string name=\"phones\">Телефондар</string>\n    <string name=\"emails\">Электрондық пошталар</string>\n    <string name=\"urls\">URL мекенжайлары</string>\n    <string name=\"addresses\">Мекенжайлар</string>\n    <string name=\"summary\">Түйіндеме</string>\n    <string name=\"description\">Сипаттама</string>\n    <string name=\"location\">Орналасқан жері</string>\n    <string name=\"organizer\">Ұйымдастырушы</string>\n    <string name=\"start_date\">Басталу күні</string>\n    <string name=\"end_date\">Аяқталу күні</string>\n    <string name=\"status\">Күй</string>\n    <string name=\"latitude\">Ендік</string>\n    <string name=\"longitude\">Бойлық</string>\n    <string name=\"create_barcode\">Штрих-код жасау</string>\n    <string name=\"edit_barcode\">Штрихкодты өңдеу</string>\n    <string name=\"wifi_configuration\">Wi-Fi конфигурациясы</string>\n    <string name=\"security\">Қауіпсіздік</string>\n    <string name=\"pick_contact\">Контакт таңдау</string>\n    <string name=\"grant_contact_permission\">Параметрлерде контактілерге таңдалған контактіні пайдаланып автотолтыруға рұқсат беріңіз</string>\n    <string name=\"contact_info\">Байланыс ақпараты</string>\n    <string name=\"first_name\">Аты</string>\n    <string name=\"middle_name\">Екінші аты</string>\n    <string name=\"last_name\">Фамилия</string>\n    <string name=\"pronunciation\">Айтылуы</string>\n    <string name=\"add_phone\">Телефон қосыңыз</string>\n    <string name=\"add_email\">Электрондық поштаны қосыңыз</string>\n    <string name=\"add_address\">Мекенжай қосыңыз</string>\n    <string name=\"website\">Веб-сайт</string>\n    <string name=\"add_website\">Веб-сайтты қосыңыз</string>\n    <string name=\"formatted_name\">Пішімделген атау</string>\n    <string name=\"qr_code_top_image\">Бұл сурет штрих-кодтың үстіне қою үшін пайдаланылады</string>\n    <string name=\"code_customization\">Кодты теңшеу</string>\n    <string name=\"qr_logo_image\">Бұл сурет QR кодының ортасында логотип ретінде пайдаланылады</string>\n    <string name=\"logo\">Логотип</string>\n    <string name=\"logo_padding\">Логотипті толтыру</string>\n    <string name=\"logo_size\">Логотип өлшемі</string>\n    <string name=\"logo_corners\">Логотип бұрыштары</string>\n    <string name=\"fourth_eye\">Төртінші көз</string>\n    <string name=\"fourth_eye_description\">Төменгі шеткі бұрышқа төртінші көзді қосу арқылы qr кодына көз симметриясын қосады</string>\n    <string name=\"pixel_shape\">Пиксель пішіні</string>\n    <string name=\"frame_shape\">Жақтау пішіні</string>\n    <string name=\"ball_shape\">Шар пішіні</string>\n    <string name=\"error_correction_level\">Қатені түзету деңгейі</string>\n    <string name=\"dark_color\">Қою түсті</string>\n    <string name=\"light_color\">Ашық түс</string>\n    <string name=\"hyper_os\">Гипер ОЖ</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS стилі ұнайды</string>\n    <string name=\"mask_pattern\">Маска үлгісі</string>\n    <string name=\"code_may_be_not_scannable\">Бұл код сканерленбеуі мүмкін, оны барлық құрылғылармен оқуға болатындай ету үшін сыртқы көрініс параметрлерін өзгертіңіз</string>\n    <string name=\"not_scannable\">Сканерлеу мүмкін емес</string>\n    <string name=\"launcher_mode_sub\">Құралдар ықшам болу үшін негізгі экран қолданбасын іске қосу құралы сияқты болады</string>\n    <string name=\"launcher_mode\">Іске қосу режимі</string>\n    <string name=\"flood_fill_sub\">Таңдалған щеткамен және стильмен аумақты толтырады</string>\n    <string name=\"flood_fill\">Су тасқыны</string>\n    <string name=\"spray\">Бүріккіш</string>\n    <string name=\"spray_sub\">Граффити стиліндегі жолды салады</string>\n    <string name=\"square_particles\">Шаршы бөлшектер</string>\n    <string name=\"square_particles_sub\">Бүріккіш бөлшектер шеңбердің орнына шаршы пішінді болады</string>\n    <string name=\"palette_tools\">Палитра құралдары</string>\n    <string name=\"palette_tools_sub\">Кескіннен негізгі/материалды бояғышты жасаңыз немесе әртүрлі палитра пішімдері бойынша импорттау/экспорттау</string>\n    <string name=\"edit_palette\">Палитраны өңдеу</string>\n    <string name=\"edit_palette_sub\">Түрлі пішімдер бойынша палитраны экспорттау/импорттау</string>\n    <string name=\"color_name\">Түс атауы</string>\n    <string name=\"palette_name\">Палитра атауы</string>\n    <string name=\"palette_format\">Палитра пішімі</string>\n    <string name=\"export_palette_sub\">Жасалған палитраны әртүрлі пішімдерге экспорттау</string>\n    <string name=\"add_color_palette_sub\">Ағымдағы палитраға жаңа түс қосады</string>\n    <string name=\"palette_name_not_supported\">%1$s пішімі палитра атауын беруді қолдамайды</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store саясаттарына байланысты бұл мүмкіндікті ағымдағы құрастыруға қосу мүмкін емес. Бұл функцияға қол жеткізу үшін ImageToolbox қолданбасын балама көзден жүктеп алыңыз. Төменде GitHub сайтында қолжетімді құрылымдарды таба аласыз.</string>\n    <string name=\"open_github_page\">Github бетін ашыңыз</string>\n    <string name=\"overwrite_files_sub_short\">Түпнұсқа файл таңдалған қалтада сақтаудың орнына жаңасымен ауыстырылады</string>\n    <string name=\"hidden_watermark_text_detected\">Жасырын су таңбасының мәтіні анықталды</string>\n    <string name=\"hidden_watermark_image_detected\">Жасырын су таңбасының кескіні анықталды</string>\n    <string name=\"this_image_was_hidden\">Бұл сурет жасырылды</string>\n    <string name=\"generative_inpaint\">Генеративті кескіндеме</string>\n    <string name=\"generative_inpaint_sub\">OpenCV-ге сенбей, AI үлгісін пайдаланып кескіндегі нысандарды жоюға мүмкіндік береді. Бұл мүмкіндікті пайдалану үшін қолданба GitHub сайтынан қажетті үлгіні (~200 МБ) жүктеп алады</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV-ге сенбей, AI үлгісін пайдаланып кескіндегі нысандарды жоюға мүмкіндік береді. Бұл ұзаққа созылатын операция болуы мүмкін</string>\n    <string name=\"error_level_analysis\">Қате деңгейін талдау</string>\n    <string name=\"luminance_gradient\">Жарықтық градиенті</string>\n    <string name=\"average_distance\">Орташа қашықтық</string>\n    <string name=\"copy_move_detection\">Көшіру жылжытуды анықтау</string>\n    <string name=\"retain\">Сақтау</string>\n    <string name=\"coefficent\">Коэффицент</string>\n    <string name=\"clipboard_data_is_too_large\">Алмасу буферінің деректері тым үлкен</string>\n    <string name=\"data_is_too_large_to_copy\">Деректер көшіру үшін тым үлкен</string>\n    <string name=\"simple_weave_pixelization\">Қарапайым тоқыма пикселизациясы</string>\n    <string name=\"staggered_pixelization\">Кезеңдік пикселдеу</string>\n    <string name=\"cross_pixelization\">Айқас пикселизация</string>\n    <string name=\"micro_macro_pixelization\">Микро макропикселизация</string>\n    <string name=\"orbital_pixelization\">Орбиталық пикселизация</string>\n    <string name=\"vortex_pixelization\">Құйынның пикселизациясы</string>\n    <string name=\"pulse_grid_pixelization\">Импульстік тордың пикселизациясы</string>\n    <string name=\"nucleus_pixelization\">Ядроның пикселизациясы</string>\n    <string name=\"radial_weave_pixelization\">Радиалды тоқыма пикселизациясы</string>\n    <string name=\"cannot_open_uri\">\\\"%1$s\\\" uri ашылмады</string>\n    <string name=\"snowfall_mode\">Қар жауу режимі</string>\n    <string name=\"enabled\">Қосылған</string>\n    <string name=\"border_frame\">Жиек жақтауы</string>\n    <string name=\"glitch_variant\">Ақаулық нұсқасы</string>\n    <string name=\"channel_shift\">Арнаны ауыстыру</string>\n    <string name=\"max_offset\">Максималды ығысу</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Glitch блоктау</string>\n    <string name=\"block_size\">Блок өлшемі</string>\n    <string name=\"crt_curvature\">CRT қисықтығы</string>\n    <string name=\"curvature\">Қисықтық</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Максималды құлдырау</string>\n    <string name=\"ai_tools\">AI құралдары</string>\n    <string name=\"ai_tools_sub\">Артефакттарды жою немесе жою сияқты AI үлгілері арқылы кескіндерді өңдеуге арналған әртүрлі құралдар</string>\n    <string name=\"model_anime_undeint\">Сығымдау, кесілген сызықтар</string>\n    <string name=\"model_broadcast\">Мультфильмдер, хабар тарату</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Жалпы қысу, жалпы шу</string>\n    <string name=\"model_wb_denoise\">Түссіз мультфильм шуы</string>\n    <string name=\"model_span_anime_pretrain\">Жылдам, жалпы қысу, жалпы шу, анимация/комикс/аниме</string>\n    <string name=\"model_book_scan\">Кітапты сканерлеу</string>\n    <string name=\"model_overexposure\">Экспозицияны түзету</string>\n    <string name=\"model_fbcnn_color_fp16\">Жалпы қысу, түрлі-түсті кескіндер бойынша ең жақсы</string>\n    <string name=\"model_fbcnn_gray_fp16\">Ең жақсы жалпы қысу, сұр түсті кескіндер</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Жалпы қысу, сұр түсті кескіндер, күштірек</string>\n    <string name=\"model_scunet_color_gan_fp16\">Жалпы шу, түрлі-түсті бейнелер</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Жалпы шу, түрлі-түсті кескіндер, жақсырақ мәліметтер</string>\n    <string name=\"model_scunet_gray_15_fp16\">Жалпы шу, сұр түсті кескіндер</string>\n    <string name=\"model_scunet_gray_25_fp16\">Жалпы шу, сұр түсті кескіндер, күштірек</string>\n    <string name=\"model_scunet_gray_50_fp16\">Жалпы шу, сұр түсті кескіндер, ең күшті</string>\n    <string name=\"model_jpeg_destroyer\">Жалпы қысу</string>\n    <string name=\"model_jaywreck\">Жалпы қысу</string>\n    <string name=\"model_h264\">Текстуризация, h264 қысу</string>\n    <string name=\"model_vhs\">VHS қысу</string>\n    <string name=\"model_cinepak\">Стандартты емес қысу (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Бинк қысу, геометрияда жақсырақ</string>\n    <string name=\"model_debink_v5\">Бинк қысу, күштірек</string>\n    <string name=\"model_debink_v6\">Бинк қысу, жұмсақ, бөлшектерді сақтайды</string>\n    <string name=\"model_antialias\">Баспалдақ әсерін жою, тегістеу</string>\n    <string name=\"model_kdm_scans\">Сканерленген өнер/сызбалар, жұмсақ сығымдау, муар</string>\n    <string name=\"model_bandage\">Түсті ленталау</string>\n    <string name=\"model_halftone\">Баяу, жартылай реңктерді жою</string>\n    <string name=\"model_colorizer\">Сұр реңкті/bw кескіндерге арналған жалпы бояғыш, жақсы нәтижелер алу үшін DDColor пайдаланыңыз</string>\n    <string name=\"model_deedge\">Жиекті жою</string>\n    <string name=\"model_desharpen\">Артық қайрауды жояды</string>\n    <string name=\"model_dither\">Баяу, дірілдеу</string>\n    <string name=\"model_gainres\">Антиалиазинг, жалпы артефактілер, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 сканерлеуді өңдеу</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Жеңіл кескінді жақсарту үлгісі</string>\n    <string name=\"model_bcgone_detailed_v2\">Компрессиялық артефактты жою</string>\n    <string name=\"model_bcgone_smooth\">Компрессиялық артефактты жою</string>\n    <string name=\"model_bandage_smooth\">Тегіс нәтиже беретін таңғышты алып тастау</string>\n    <string name=\"model_bendel_halftone\">Жартылай тон үлгісін өңдеу</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Дитер үлгісін жою V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG артефактілерін жою V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 текстурасын жақсарту</string>\n    <string name=\"model_vhs_sharpen\">VHS нақтылау және жақсарту</string>\n    <string name=\"merging\">Біріктіру</string>\n    <string name=\"chunk_size\">Бөлшек өлшемі</string>\n    <string name=\"overlap_size\">Қабаттасу өлшемі</string>\n    <string name=\"note_chunk_info\">%1$s пиксельден асатын кескіндер кесектерге кесіледі және өңделеді, көрінетін тігістердің алдын алу үшін қабаттасу араласады.</string>\n    <string name=\"large_chunk_warning\">Үлкен өлшемдер төмен деңгейлі құрылғылармен тұрақсыздықты тудыруы мүмкін</string>\n    <string name=\"select_one_to_start\">Бастау үшін біреуін таңдаңыз</string>\n    <string name=\"delete_model_sub\">%1$s үлгісін жойғыңыз келе ме? Сіз оны қайтадан жүктеп алуыңыз керек</string>\n    <string name=\"confirm\">Растау</string>\n    <string name=\"models\">Модельдер</string>\n    <string name=\"downloaded_models\">Жүктелген үлгілер</string>\n    <string name=\"available_models\">Қолжетімді үлгілер</string>\n    <string name=\"preparing\">Дайындалуда</string>\n    <string name=\"active_model\">Белсенді модель</string>\n    <string name=\"failed_to_open_session\">Сеанс ашылмады</string>\n    <string name=\"only_onnx_models\">Тек .onnx/.ort үлгілерін импорттауға болады</string>\n    <string name=\"import_model\">Импорт үлгісі</string>\n    <string name=\"import_model_sub\">Әрі қарай пайдалану үшін пайдаланушы onnx моделін импорттаңыз, тек onnx/ort үлгілері қабылданады, барлық дерлік esrgan сияқты нұсқаларды қолдайды</string>\n    <string name=\"imported_models\">Импортталған үлгілер</string>\n    <string name=\"model_scunet_color_15_fp16\">Жалпы шу, түрлі-түсті суреттер</string>\n    <string name=\"model_scunet_color_25_fp16\">Жалпы шу, түрлі-түсті кескіндер, күштірек</string>\n    <string name=\"model_scunet_color_50_fp16\">Жалпы шу, түрлі-түсті суреттер, ең күшті</string>\n    <string name=\"model_artifacts_dithering_alsa\">Тегіс градиенттер мен тегіс түс аумақтарын жақсартып, артефактілер мен түс жолағын азайтады.</string>\n    <string name=\"model_nmkd_brighten_redux\">Табиғи түстерді сақтай отырып, теңдестірілген жарықтандыру арқылы кескіннің жарықтығы мен контрастын жақсартады.</string>\n    <string name=\"model_nmkd_brighten\">Мәліметтерді сақтай отырып және шамадан тыс экспозицияны болдырмай, күңгірт кескіндерді ағартады.</string>\n    <string name=\"model_nmkd_detoon\">Түстердің шамадан тыс тонусын жояды және бейтарап және табиғи түс балансын қалпына келтіреді.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Нәзік бөлшектер мен текстураларды сақтауға баса назар аудара отырып, Пуассон негізіндегі шуды сергітеді.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Тегіс және аз агрессивті визуалды нәтижелер үшін жұмсақ Пуассон шуыл тонусын қолданады.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Бөлшектерді сақтауға және кескіннің анықтығына бағытталған біркелкі шуды тондау.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Нәзік текстура мен тегіс көрініс үшін жұмсақ біркелкі шуды сергітеді.</string>\n    <string name=\"model_repainter\">Артефактілерді қайта бояу және кескіннің үйлесімділігін жақсарту арқылы зақымдалған немесе тегіс емес жерлерді жөндейді.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Ең аз өнімділік құнымен түс жолағын жоятын жеңіл жолақты жою үлгісі.</string>\n    <string name=\"model_jpeg_0_20\">Жақсартылған айқындық үшін өте жоғары қысу артефактілері (0-20% сапа) бар кескіндерді оңтайландырады.</string>\n    <string name=\"model_jpeg_20_40\">Суреттерді жоғары қысу артефактілерімен жақсартады (20-40% сапа), мәліметтерді қалпына келтіреді және шуды азайтады.</string>\n    <string name=\"model_jpeg_40_60\">Орташа қысумен (40-60% сапа) кескіндерді жақсартады, айқындық пен тегістікті теңестіреді.</string>\n    <string name=\"model_jpeg_60_80\">Нәзік бөлшектер мен текстураларды жақсарту үшін жеңіл қысумен (60-80% сапа) кескіндерді нақтылайды.</string>\n    <string name=\"model_jpeg_80_100\">Табиғи көрініс пен бөлшектерді сақтай отырып, жоғалмайтын кескіндерді (80-100% сапа) аздап жақсартады.</string>\n    <string name=\"model_spongecolor_lite\">Қарапайым және жылдам бояу, мультфильмдер, идеалды емес</string>\n    <string name=\"model_deblr\">Кескіннің бұлыңғырлығын аздап азайтады, артефактілерді енгізбестен айқындықты жақсартады.</string>\n    <string name=\"processing_channel\">Ұзақ мерзімді операциялар</string>\n    <string name=\"processing_image\">Кескінді өңдеу</string>\n    <string name=\"processing\">Өңдеу</string>\n    <string name=\"model_artifacts_jpg_0_20\">Өте төмен сапалы кескіндердегі ауыр JPEG қысу артефактілерін жояды (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Жоғары қысылған кескіндердегі күшті JPEG артефактілерін азайтады (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Кескін мәліметтерін сақтай отырып, қалыпты JPEG артефактілерін тазартады (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Жеткілікті жоғары сапалы кескіндердегі жеңіл JPEG артефактілерін нақтылайды (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Жоғалмайтын кескіндердегі кішігірім JPEG артефактілерін (80-100%) азайтады.</string>\n    <string name=\"model_redetail_v2\">Ауыр артефактілерсіз қабылданатын айқындықты жақсарта отырып, ұсақ бөлшектер мен текстураларды жақсартады.</string>\n    <string name=\"processing_finished\">Өңдеу аяқталды</string>\n    <string name=\"processing_failed\">Өңдеу сәтсіз аяқталды</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Жылдамдық үшін оңтайландырылған табиғи көріністі сақтай отырып, тері құрылымы мен бөлшектерін жақсартады.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG қысу артефактілерін жояды және қысылған фотосуреттер үшін кескін сапасын қалпына келтіреді.</string>\n    <string name=\"model_iso_denoise_v1\">Жарық аз жағдайда түсірілген фотосуреттердегі ISO шуылын азайтып, бөлшектерді сақтайды.</string>\n    <string name=\"model_dejumbo\">Шамадан тыс экспозиция немесе «джумбо» бөлектеулерді түзетеді және жақсырақ тоналды тепе-теңдікті қалпына келтіреді.</string>\n    <string name=\"model_ddcolor_tiny\">Сұр реңктегі кескіндерге табиғи түстер қосатын жеңіл және жылдам түс беру үлгісі.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Түстендіріңіз</string>\n    <string name=\"type_artifacts\">Артефактілер</string>\n    <string name=\"type_enhance\">Жақсарту</string>\n    <string name=\"type_anime\">Аниме</string>\n    <string name=\"type_scans\">Сканерлеу</string>\n    <string name=\"type_upscale\">Жоғары деңгейлі</string>\n    <string name=\"model_realesrgan_x4v3\">Жалпы кескіндер үшін X4 кеңейткіші; графикалық процессорды және уақытты аз пайдаланатын, орташа ақауы бар және денозы бар шағын модель.</string>\n    <string name=\"model_realesrgan_x2plus\">Текстуралар мен табиғи бөлшектерді сақтай отырып, жалпы кескіндерге арналған X2 кеңейткіш.</string>\n    <string name=\"model_realesrgan_x4plus\">Жетілдірілген текстурасы мен шынайы нәтижелері бар жалпы кескіндерге арналған X4 кеңейткіш.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Аниме кескіндері үшін оңтайландырылған X4 кеңейткіші; Өткір сызықтар мен бөлшектер үшін 6 RRDB блоктары.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE жоғалтуы бар X4 кеңейткіші тегіс нәтижелер береді және жалпы кескіндер үшін артефактілерді азайтады.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler аниме кескіндері үшін оңтайландырылған; Өткір бөлшектері мен тегіс сызықтары бар 4B32F нұсқасы.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Жалпы кескіндерге арналған X4 UltraSharp V2 үлгісі; айқындық пен айқындылыққа баса назар аударады.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; жылдамырақ және кішірек, GPU жадын аз пайдалану кезінде мәліметтерді сақтайды.</string>\n    <string name=\"model_rmbg_1_4\">Фонды жылдам жоюға арналған жеңіл модель. Теңдестірілген өнімділік пен дәлдік. Портреттермен, заттармен және көріністермен жұмыс істейді. Көптеген пайдалану жағдайлары үшін ұсынылады.</string>\n    <string name=\"type_removebg\">BG алып тастаңыз</string>\n    <string name=\"horizontal_border_thickness\">Көлденең шекараның қалыңдығы</string>\n    <string name=\"vertical_border_thickness\">Тік жиек қалыңдығы</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s түстер</item>\n        <item quantity=\"other\">%1$s түстер</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Ағымдағы үлгі бөлшектеуге қолдау көрсетпейді, кескін бастапқы өлшемдерде өңделеді, бұл жадты көп тұтынуды және төмен деңгейлі құрылғылармен ақауларды тудыруы мүмкін.</string>\n    <string name=\"chunking_disabled\">Бөлшектеу өшірілген, кескін бастапқы өлшемдерде өңделеді, бұл жадты жоғары тұтынуды және төмен деңгейлі құрылғылармен ақауларды тудыруы мүмкін, бірақ қорытынды жасауда жақсы нәтижелер беруі мүмкін.</string>\n    <string name=\"chunking\">Бөлшектеу</string>\n    <string name=\"model_u2net\">Фонды жоюға арналған жоғары дәлдіктегі кескінді сегменттеу үлгісі</string>\n    <string name=\"model_u2netp\">Жадты азырақ пайдалану арқылы фонды жылдам жоюға арналған U2Net жеңіл нұсқасы.</string>\n    <string name=\"model_ddcolor\">Толық DDColor үлгісі ең аз артефактілермен жалпы кескіндер үшін жоғары сапалы түс беруді қамтамасыз етеді. Барлық бояу үлгілерінің ең жақсы таңдауы.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Оқытылған және жеке көркем деректер жиыны; азырақ шынайы емес түсті артефактілермен әртүрлі және көркем бояу нәтижелерін береді.</string>\n    <string name=\"model_birefnet\">Фонды дәл жою үшін Swin Transformer негізіндегі жеңіл BiRefNet моделі.</string>\n    <string name=\"model_inspyrenet\">Өткір жиектері бар жоғары сапалы фонды жою және егжей-тегжейлерді тамаша сақтау, әсіресе күрделі нысандар мен күрделі фондар.</string>\n    <string name=\"model_isnet\">Жалпы нысандарға және орташа бөлшектерді сақтауға жарамды, тегіс жиектері бар дәл маскаларды шығаратын фонды жою үлгісі.</string>\n    <string name=\"model_already_downloaded\">Үлгі жүктеп алынған</string>\n    <string name=\"model_successfully_imported\">Модель сәтті импортталды</string>\n    <string name=\"type\">Түр</string>\n    <string name=\"keyword\">Негізгі сөз</string>\n    <string name=\"very_fast\">Өте жылдам</string>\n    <string name=\"normal\">Қалыпты</string>\n    <string name=\"slow\">Баяу</string>\n    <string name=\"very_slow\">Өте баяу</string>\n    <string name=\"compute_percents\">Проценттерді есептеу</string>\n    <string name=\"minimum_value_is\">Минималды мән – %1$s</string>\n    <string name=\"warp_sub\">Саусақтармен сурет салу арқылы кескінді бұрмалау</string>\n    <string name=\"warp\">Соғыс</string>\n    <string name=\"hardness\">Қаттылық</string>\n    <string name=\"warp_mode\">Бұрмалау режимі</string>\n    <string name=\"warp_mode_move\">Жылжыту</string>\n    <string name=\"warp_mode_grow\">Өсу</string>\n    <string name=\"warp_mode_shrink\">Кішірейту</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Айналмалы CCW</string>\n    <string name=\"fade_strength\">Өшіру күші</string>\n    <string name=\"top_drop\">Жоғарғы тамшы</string>\n    <string name=\"bottom_drop\">Төменгі тамшы</string>\n    <string name=\"start_drop\">Drop бастау</string>\n    <string name=\"end_drop\">Аяқтау</string>\n    <string name=\"downloading\">Жүктеп алынуда</string>\n    <string name=\"smooth_shapes\">Тегіс пішіндер</string>\n    <string name=\"smooth_shapes_sub\">Тегіс, табиғи пішіндер үшін стандартты дөңгелектелген төртбұрыштардың орнына суперэллипстерді пайдаланыңыз</string>\n    <string name=\"shape_type\">Пішін түрі</string>\n    <string name=\"cut\">Кесу</string>\n    <string name=\"rounded\">Дөңгеленген</string>\n    <string name=\"smooth\">Тегіс</string>\n    <string name=\"cut_shapes_sub\">Дөңгелектеусіз өткір жиектер</string>\n    <string name=\"rounded_shapes_sub\">Классикалық дөңгелек бұрыштар</string>\n    <string name=\"shapes_type\">Фигуралар түрі</string>\n    <string name=\"corners_size\">Бұрыштардың өлшемі</string>\n    <string name=\"squircle\">Айналма</string>\n    <string name=\"squircle_shapes_sub\">Керемет дөңгелектенген UI элементтері</string>\n    <string name=\"filename_format\">Файл атауы пішімі</string>\n    <string name=\"prefix_pattern_description\">Жоба атаулары, брендтер немесе жеке тегтер үшін тамаша файл атауының ең басында орналастырылған теңшелетін мәтін.</string>\n    <string name=\"original_filename_pattern_description\">Бастапқы файл атауын кеңейтусіз пайдаланады, бұл бастапқы идентификацияны сақтауыңызға көмектеседі.</string>\n    <string name=\"width_pattern_description\">Ажыратымдылық өзгерістерін немесе масштабтау нәтижелерін бақылау үшін пайдалы пиксельдегі кескін ені.</string>\n    <string name=\"height_pattern_description\">Пиксельдегі кескін биіктігі, пропорциялармен немесе экспорттармен жұмыс істегенде пайдалы.</string>\n    <string name=\"random_numbers_pattern_description\">Бірегей файл атауларына кепілдік беру үшін кездейсоқ сандарды жасайды; көшірмелерден қосымша қауіпсіздік үшін қосымша сандарды қосыңыз.</string>\n    <string name=\"sequence_number_pattern_description\">Пакеттік экспортқа арналған автоматты ұлғайту есептегіші, бір сеанста бірнеше кескінді сақтау үшін өте қолайлы.</string>\n    <string name=\"preset_info_pattern_description\">Кескіннің қалай өңделгенін оңай есте сақтау үшін қолданылатын алдын ала орнатылған атауды файл атауына енгізеді.</string>\n    <string name=\"scale_mode_pattern_description\">Өлшемі өзгертілген, қиылған немесе орнатылған кескіндерді ажыратуға көмектесетін өңдеу кезінде пайдаланылатын кескін масштабтау режимін көрсетеді.</string>\n    <string name=\"suffix_pattern_description\">Файл атауының соңында орналастырылған теңшелетін мәтін, _v2, _edited немесе _final сияқты нұсқалар үшін пайдалы.</string>\n    <string name=\"extension_pattern_description\">Файл кеңейтімі (png, jpg, webp, т.б.), нақты сақталған пішімге автоматты түрде сәйкес келеді.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Керемет сұрыптау үшін java спецификациясы бойынша өз пішіміңізді анықтауға мүмкіндік беретін теңшелетін уақыт белгісі.</string>\n    <string name=\"fling_type\">Ұшу түрі</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">iOS стилі</string>\n    <string name=\"smooth_curve\">Тегіс қисық</string>\n    <string name=\"quick_stop\">Жылдам тоқтату</string>\n    <string name=\"bouncy\">Боунси</string>\n    <string name=\"floaty\">Қалқымалы</string>\n    <string name=\"snappy\">Жылдам</string>\n    <string name=\"ultra_smooth\">Ультра тегіс</string>\n    <string name=\"adaptive\">Бейімделу</string>\n    <string name=\"accessibility_aware\">Қол жетімділікті біледі</string>\n    <string name=\"reduced_motion\">Қысқартылған қозғалыс</string>\n    <string name=\"android_native_sub\">Жергілікті Android айналдыру физикасы</string>\n    <string name=\"smooth_sub\">Жалпы пайдалану үшін теңдестірілген, тегіс айналдыру</string>\n    <string name=\"ios_style_sub\">Жоғары үйкеліс iOS тәрізді айналдыру әрекеті</string>\n    <string name=\"smooth_curve_sub\">Айналдыру сезімі үшін ерекше сплайн қисығы</string>\n    <string name=\"quick_stop_sub\">Жылдам тоқтату арқылы дәл айналдыру</string>\n    <string name=\"bouncy_sub\">Ойын, жауап беретін серпінді шиыршық</string>\n    <string name=\"floaty_sub\">Мазмұнды шолу үшін ұзын, жылжымалы айналдырулар</string>\n    <string name=\"snappy_sub\">Интерактивті UI үшін жылдам, жауапты айналдыру</string>\n    <string name=\"ultra_smooth_sub\">Ұзартылған серпінмен премиум тегіс айналдыру</string>\n    <string name=\"adaptive_sub\">Ұшу жылдамдығына негізделген физиканы реттейді</string>\n    <string name=\"accessibility_aware_sub\">Жүйенің қол жетімділік параметрлерін құрметтейді</string>\n    <string name=\"reduced_motion_sub\">Қол жетімділік қажеттіліктері үшін минималды қозғалыс</string>\n    <string name=\"primary_lines\">Бастапқы сызықтар</string>\n    <string name=\"primary_lines_sub\">Әрбір бесінші жолға қалыңырақ жолды қосады</string>\n    <string name=\"fill_color\">Түсті толтыру</string>\n    <string name=\"hidden_tools\">Жасырын құралдар</string>\n    <string name=\"hidden_for_share\">Бөлісу үшін жасырылған құралдар</string>\n    <string name=\"color_library\">Түстер кітапханасы</string>\n    <string name=\"color_library_sub\">Түстердің кең жиынтығын шолыңыз</string>\n    <string name=\"model_fatality_deblur\">Табиғи мәліметтерді сақтай отырып, кескіндерді айқындайды және бұлыңғырлықты жояды, бұл фокустан тыс фотосуреттерді бекіту үшін өте қолайлы.</string>\n    <string name=\"model_unresize_v3\">Жоғалған мәліметтер мен текстураларды қалпына келтіре отырып, бұрын өлшемі өзгертілген кескіндерді ақылды түрде қалпына келтіреді.</string>\n    <string name=\"model_liveaction_v1_span\">Тікелей эфир мазмұны үшін оңтайландырылған, қысу артефактілерін азайтады және фильмдер/теледидар шоу кадрларындағы ұсақ бөлшектерді жақсартады.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS-сапалы бейнелерді HD форматына түрлендіреді, таспа шуын жояды және винтаждық сезімді сақтай отырып, ажыратымдылықты арттырады.</string>\n    <string name=\"model_text2hd_v1\">Мәтінді көп қажет ететін кескіндер мен скриншоттар үшін мамандандырылған, кейіпкерлерді айқындайды және оқылуды жақсартады.</string>\n    <string name=\"model_frankendata_pretrainer\">Жетілдірілген масштабтау әртүрлі деректер жиынында оқытылады, жалпы мақсаттағы фотосуреттерді жақсарту үшін тамаша.</string>\n    <string name=\"model_realwebphoto_v2\">Веб-қысылған фотосуреттер үшін оңтайландырылған, JPEG артефактілерін жояды және табиғи көріністі қалпына келтіреді.</string>\n    <string name=\"model_realwebphoto_v4\">Текстураны жақсырақ сақтау және артефакті азайту арқылы веб-фотосуреттерге арналған жетілдірілген нұсқасы.</string>\n    <string name=\"model_dat_2x\">Қос біріктіру трансформаторы технологиясымен 2 есе үлкейту, анықтық пен табиғи бөлшектерді сақтайды.</string>\n    <string name=\"model_dat_3x\">Трансформатордың жетілдірілген архитектурасын пайдаланып масштабты 3 есе арттыру, қалыпты үлкейту қажеттіліктері үшін өте қолайлы.</string>\n    <string name=\"model_dat_4x\">Соңғы үлгідегі трансформатор желісімен 4 есе жоғары сапалы масштабтау, үлкенірек масштабта ұсақ бөлшектерді сақтайды.</string>\n    <string name=\"model_nafnet_deblurring\">Фотосуреттердегі бұлыңғырлықты/ шуды және дірілдерді жояды. Жалпы мақсат, бірақ фотосуреттерде жақсы.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">BSRGAN деградациясы үшін оңтайландырылған Swin2SR трансформаторын пайдаланып сапасыз кескіндерді қалпына келтіреді. Ауыр қысу артефактілерін бекіту және 4x масштабындағы мәліметтерді жақсарту үшін тамаша.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN деградациясына үйретілген SwinIR трансформаторымен 4 есе кеңейту. Фотосуреттер мен күрделі көріністердегі анық текстуралар мен табиғи бөлшектер үшін GAN пайдаланады.</string>\n    <string name=\"path\">Жол</string>\n    <string name=\"merge_pdf\">PDF біріктіру</string>\n    <string name=\"merge_pdf_sub\">Бірнеше PDF файлдарын бір құжатқа біріктіріңіз</string>\n    <string name=\"files_order\">Файлдар тәртібі</string>\n    <string name=\"pages_short\">бет.</string>\n    <string name=\"split_pdf\">PDF бөлу</string>\n    <string name=\"split_pdf_sub\">PDF құжатынан арнайы беттерді шығарып алыңыз</string>\n    <string name=\"rotate_pdf\">PDF файлын бұру</string>\n    <string name=\"rotate_pdf_sub\">Бет бағытын біржола түзетіңіз</string>\n    <string name=\"pages\">Беттер</string>\n    <string name=\"rearrange_pdf\">PDF файлын қайта реттеңіз</string>\n    <string name=\"rearrange_pdf_sub\">Беттерді ретін өзгерту үшін сүйреп апарыңыз</string>\n    <string name=\"hold_drag_drop\">Беттерді ұстап тұрыңыз және сүйреңіз</string>\n    <string name=\"page_numbers\">Бет нөмірлері</string>\n    <string name=\"page_numbers_sub\">Құжаттарыңызға нөмірлеуді автоматты түрде қосыңыз</string>\n    <string name=\"label_format\">Белгі пішімі</string>\n    <string name=\"pdf_to_text\">PDF-мәтінге (OCR)</string>\n    <string name=\"pdf_to_text_sub\">PDF құжаттарынан кәдімгі мәтінді шығарып алыңыз</string>\n    <string name=\"watermark_pdf_sub\">Брендинг немесе қауіпсіздік үшін реттелетін мәтінді қабаттастырыңыз</string>\n    <string name=\"signature\">Қол қою</string>\n    <string name=\"signature_sub\">Кез келген құжатқа электрондық қолтаңбаңызды қосыңыз</string>\n    <string name=\"will_be_for_signature\">Бұл қолтаңба ретінде пайдаланылады</string>\n    <string name=\"unlock_pdf\">PDF құлпын ашу</string>\n    <string name=\"unlock_pdf_sub\">Құпия сөздерді қорғалған файлдардан жойыңыз</string>\n    <string name=\"protect_pdf\">PDF файлын қорғаңыз</string>\n    <string name=\"protect_pdf_sub\">Құжаттарды күшті шифрлау арқылы қорғаңыз</string>\n    <string name=\"success\">Сәттілік</string>\n    <string name=\"pdf_unlocked\">PDF құлпы ашылды, оны сақтауға немесе бөлісуге болады</string>\n    <string name=\"repair_pdf\">PDF жөндеу</string>\n    <string name=\"repair_pdf_sub\">Бүлінген немесе оқылмайтын құжаттарды түзету әрекеті</string>\n    <string name=\"grayscale\">Сұр реңк</string>\n    <string name=\"grayscale_pdf_sub\">Барлық ендірілген құжат кескіндерін сұр реңкке түрлендіріңіз</string>\n    <string name=\"compress_pdf\">PDF файлын қысыңыз</string>\n    <string name=\"compress_pdf_sub\">Бөлісуді жеңілдету үшін құжат файлының өлшемін оңтайландырыңыз</string>\n    <string name=\"repair_info\">ImageToolbox ішкі айқас сілтеме кестесін қайта құрады және файл құрылымын нөлден бастап қайта жасайды. Бұл \\\\\"ашу мүмкін емес\\\\\" көптеген файлдарға кіру рұқсатын қалпына келтіре алады.</string>\n    <string name=\"grayscale_info\">Бұл құрал барлық құжат кескіндерін сұр реңкке түрлендіреді. Басып шығару және файл өлшемін азайту үшін ең жақсы</string>\n    <string name=\"metadata\">Метадеректер</string>\n    <string name=\"metadata_pdf_sub\">Құпиялықты жақсарту үшін құжат сипаттарын өңдеңіз</string>\n    <string name=\"tags\">Тегтер</string>\n    <string name=\"producer\">Продюсер</string>\n    <string name=\"author\">Автор</string>\n    <string name=\"keywords\">Негізгі сөздер</string>\n    <string name=\"creator\">Жаратушы</string>\n    <string name=\"privacy_deep_clean\">Құпиялылық Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Осы құжат үшін барлық қолжетімді метадеректерді өшіріңіз</string>\n    <string name=\"page\">Бет</string>\n    <string name=\"deep_ocr\">Терең OCR</string>\n    <string name=\"deep_ocr_sub\">Құжаттан мәтінді шығарып, оны Tesseract қозғалтқышының көмегімен бір мәтіндік файлға сақтаңыз</string>\n    <string name=\"cant_remove_all\">Барлық беттерді жою мүмкін емес</string>\n    <string name=\"remove_pages_pdf\">PDF беттерін жою</string>\n    <string name=\"remove_pages_pdf_sub\">PDF құжатынан арнайы беттерді алып тастаңыз</string>\n    <string name=\"tap_to_remove\">Жою үшін түртіңіз</string>\n    <string name=\"manually\">Қолмен</string>\n    <string name=\"crop_pdf\">PDF қию</string>\n    <string name=\"crop_pdf_sub\">Құжат беттерін кез келген шекке қию</string>\n    <string name=\"flatten_pdf\">PDF файлын тегістеңіз</string>\n    <string name=\"flatten_pdf_sub\">Құжат беттерін растирлеу арқылы PDF файлын өзгертілмейтін етіңіз</string>\n    <string name=\"camera_failed_to_open\">Камераны іске қосу мүмкін болмады. Рұқсаттарды тексеріп, оны басқа қолданба пайдаланбайтынына көз жеткізіңіз.</string>\n    <string name=\"extract_images\">Суреттерді шығару</string>\n    <string name=\"extract_images_sub\">PDF файлдарына ендірілген кескіндерді бастапқы ажыратымдылығымен шығарып алыңыз</string>\n    <string name=\"pdf_no_embedded\">Бұл PDF файлында ендірілген кескіндер жоқ</string>\n    <string name=\"extract_images_info\">Бұл құрал әрбір бетті сканерлейді және толық сапалы бастапқы кескіндерді қалпына келтіреді — құжаттардан түпнұсқаларды сақтауға өте ыңғайлы</string>\n    <string name=\"draw_signature\">Қолтаңбаны салу</string>\n    <string name=\"pen_params\">Қалам параметрлері</string>\n    <string name=\"draw_signature_sub\">Құжаттарға орналастыру үшін сурет ретінде өз қолтаңбасын пайдаланыңыз</string>\n    <string name=\"zip_pdf\">ZIP PDF</string>\n    <string name=\"zip_pdf_sub\">Берілген аралықпен құжатты бөліңіз және жаңа құжаттарды zip мұрағатына салыңыз</string>\n    <string name=\"interval\">Аралық</string>\n    <string name=\"print_pdf\">PDF басып шығару</string>\n    <string name=\"print_pdf_sub\">Құжатты бет өлшемімен басып шығаруға дайындаңыз</string>\n    <string name=\"pages_per_sheet\">Парақтағы беттер</string>\n    <string name=\"orientation\">Бағдарлау</string>\n    <string name=\"page_size\">Бет өлшемі</string>\n    <string name=\"margin\">Маржа</string>\n    <string name=\"bloom\">Блум</string>\n    <string name=\"soft_knee\">Жұмсақ тізе</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Аниме және мультфильмдер үшін оңтайландырылған. Жақсартылған табиғи түстермен және аз артефактілермен жылдам үлкейту</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 стиліне ұқсас</string>\n    <string name=\"calculate_hint\">Қажетті мәнді есептеу үшін осы жерге негізгі математикалық белгілерді енгізіңіз (мысалы, (5+5)*10)</string>\n    <string name=\"math_expression\">Математикалық өрнек</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s суретке дейін таңдаңыз</string>\n    <string name=\"keep_date_time\">Күн уақытын сақтаңыз</string>\n    <string name=\"keep_date_time_sub\">Әрқашан күн мен уақытқа қатысты exif тегтерін сақтаңыз, exif сақтау опциясынан тәуелсіз жұмыс істейді</string>\n    <string name=\"background_color_for_alpha_formats\">Альфа пішімдері үшін фон түсі</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Альфа қолдауы бар әрбір кескін пішімі үшін фон түсін орнату мүмкіндігін қосады, өшірілген кезде бұл тек альфа еместер үшін қолжетімді.</string>\n    <string name=\"open_markup_project\">Ашық жоба</string>\n    <string name=\"open_markup_project_sub\">Бұрын сақталған Image Toolbox жобасын өңдеуді жалғастырыңыз</string>\n    <string name=\"markup_project_open_failed\">Image Toolbox жобасын ашу мүмкін емес</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox жобасында жоба деректері жоқ</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox жобасы бүлінген</string>\n    <string name=\"unsupported_markup_project_version\">Қолдау көрсетілмейтін Image Toolbox жобасының нұсқасы: %1$d</string>\n    <string name=\"save_markup_project\">Жобаны сақтау</string>\n    <string name=\"save_markup_project_sub\">Қабаттарды, фондық және өңдеу журналын өңделетін жоба файлында сақтаңыз</string>\n    <string name=\"failed_to_open\">Ашылмады</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Іздеуге болатын PDF файлына жазыңыз</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Кескін топтамасынан мәтінді танып, сурет пен таңдалатын мәтін қабатымен ізделетін PDF файлын сақтаңыз</string>\n    <string name=\"layer_alpha\">Альфа қабаты</string>\n    <string name=\"horizontal_flip\">Көлденең айналдыру</string>\n    <string name=\"vertical_flip\">Тік бұру</string>\n    <string name=\"lock\">Құлыптау</string>\n    <string name=\"add_shadow\">Көлеңке қосу</string>\n    <string name=\"shadow_color\">Көлеңке түсі</string>\n    <string name=\"text_geometry\">Мәтін геометриясы</string>\n    <string name=\"text_geometry_sub\">Анық стильдеу үшін мәтінді созыңыз немесе қисайтыңыз</string>\n    <string name=\"scale_x\">X шкаласы</string>\n    <string name=\"skew_x\">Скью X</string>\n    <string name=\"remove_annotations\">Аннотацияларды жою</string>\n    <string name=\"remove_annotations_sub\">PDF беттерінен сілтемелер, түсініктемелер, ерекшеліктер, пішіндер немесе пішін өрістері сияқты таңдалған аннотация түрлерін алып тастаңыз</string>\n    <string name=\"annotation_link\">Гиперсілтемелер</string>\n    <string name=\"annotation_file_attachment\">Файл қосымшалары</string>\n    <string name=\"annotation_line\">Сызықтар</string>\n    <string name=\"annotation_popup\">Қалқымалы терезелер</string>\n    <string name=\"annotation_stamp\">Маркалар</string>\n    <string name=\"annotation_shapes\">Пішіндер</string>\n    <string name=\"annotation_text\">Мәтіндік жазбалар</string>\n    <string name=\"annotation_text_markup\">Мәтінді белгілеу</string>\n    <string name=\"annotation_widget\">Пішін өрістері</string>\n    <string name=\"annotation_markup\">Белгілеу</string>\n    <string name=\"annotation_unknown\">Белгісіз</string>\n    <string name=\"annotations\">Аннотациялар</string>\n    <string name=\"ungroup\">Топтан шығару</string>\n    <string name=\"add_shadow_sub\">Конфигурацияланатын түс пен ығысу арқылы қабаттың артына бұлыңғыр көлеңке қосыңыз</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ko/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"pick_image\">이미지 선택</string>\n    <string name=\"width\">너비 %1$s</string>\n    <string name=\"height\">높이 %1$s</string>\n    <string name=\"quality\">품질</string>\n    <string name=\"resize_type\">크기 조정 유형</string>\n    <string name=\"size\">파일크기 %1$s</string>\n    <string name=\"pick_image_alt\">이미지 선택</string>\n    <string name=\"app_closing\">앱 종료</string>\n    <string name=\"stay\">머물기</string>\n    <string name=\"reset_image_sub\">이미지 변경 사항이 시작값으로 변경됩니다</string>\n    <string name=\"reset_image\">이미지 초기화</string>\n    <string name=\"reset\">초기화</string>\n    <string name=\"close\">닫기</string>\n    <string name=\"values_reset\">설정값이 초기화 되었습니다</string>\n    <string name=\"something_went_wrong\">문제가 발생했습니다</string>\n    <string name=\"restart_app\">앱 재시작</string>\n    <string name=\"smth_went_wrong\">문제 발생: %1$s</string>\n    <string name=\"explicit\">명시적</string>\n    <string name=\"flexible\">유연성</string>\n    <string name=\"exception\">예외</string>\n    <string name=\"save\">저장</string>\n    <string name=\"clear\">지우기</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"check_source_code\">소스 코드</string>\n    <string name=\"image_not_saved\">저장중</string>\n    <string name=\"check_source_code_sub\">최신 업데이트 받기, 문제 논의 등</string>\n    <string name=\"color\">색상</string>\n    <string name=\"image\">이미지</string>\n    <string name=\"color_copied\">색상이 복사되었습니다</string>\n    <string name=\"single_edit\">단일 크기 조정</string>\n    <string name=\"single_edit_sub\">하나의 이미지 수정, 크기 조정 및 편집</string>\n    <string name=\"remove\">삭제</string>\n    <string name=\"palette_sub\">지정된 이미지에서 색상 팔레트 견본 생성</string>\n    <string name=\"generate_palette\">팔레트 생성</string>\n    <string name=\"palette\">팔레트</string>\n    <string name=\"new_version\">새로운 버전 %1$s</string>\n    <string name=\"unsupported_type\">지원되지 않는 유형: %1$s</string>\n    <string name=\"no_palette\">지정된 이미지에 대한 팔레트를 생성할 수 없습니다</string>\n    <string name=\"original\">원본</string>\n    <string name=\"def\">기본값</string>\n    <string name=\"device_storage\">장치 저장 공간</string>\n    <string name=\"by_bytes_resize\">용량으로 크기 조정</string>\n    <string name=\"max_bytes\">최대 크기 KB</string>\n    <string name=\"unspecified\">미지정</string>\n    <string name=\"compare\">비교</string>\n    <string name=\"compare_sub\">지정된 두 이미지를 비교</string>\n    <string name=\"folder\">출력 폴더</string>\n    <string name=\"custom\">사용자 지정</string>\n    <string name=\"pick_images\">이미지 선택</string>\n    <string name=\"settings\">설정</string>\n    <string name=\"night_mode\">야간 모드</string>\n    <string name=\"dark\">어둡게</string>\n    <string name=\"light\">밝게</string>\n    <string name=\"system\">시스템</string>\n    <string name=\"dynamic_colors\">동적 색상</string>\n    <string name=\"customization\">사용자 지정</string>\n    <string name=\"allow_image_monet\">이미지 모네 허용</string>\n    <string name=\"allow_image_monet_sub\">이 기능을 활성화하면 편집할 이미지를 선택하면 이 이미지에 앱 색상이 적용됩니다.</string>\n    <string name=\"color_red\">빨간색</string>\n    <string name=\"color_green\">초록색</string>\n    <string name=\"amoled_mode\">아몰레드 모드</string>\n    <string name=\"language\">언어</string>\n    <string name=\"color_scheme\">색 구성표</string>\n    <string name=\"clipboard_paste_invalid_color_code\">aRGB 코드 붙여넣기</string>\n    <string name=\"clipboard_paste_invalid_empty\">붙여넣을 항목 없음</string>\n    <string name=\"about_app\">앱 정보</string>\n    <string name=\"pick_accent_color\">앱 테마는 선택한 색상을 기반으로 합니다.</string>\n    <string name=\"help_translate\">번역을 도와주세요</string>\n    <string name=\"help_translate_sub\">번역 실수를 수정하거나 프로젝트를 다른 언어로 현지화</string>\n    <string name=\"nothing_found_by_search\">검색어에서 아무것도 찾지 못했습니다.</string>\n    <string name=\"search_here\">여기에서 검색</string>\n    <string name=\"failed_to_save\">%d 이미지 저장 실패</string>\n    <string name=\"primary\">기본</string>\n    <string name=\"tertiary\">제삼기</string>\n    <string name=\"secondary\">보조</string>\n    <string name=\"border_thickness\">테두리 두께</string>\n    <string name=\"values\">값</string>\n    <string name=\"add\">추가</string>\n    <string name=\"permission\">권한</string>\n    <string name=\"grant\">승인</string>\n    <string name=\"grant_permission_manual\">앱이 작동하려면 이 권한이 필요하므로 수동으로 권한을 부여하세요.</string>\n    <string name=\"external_storage\">외부 저장소</string>\n    <string name=\"monet_colors\">모네 색상</string>\n    <string name=\"loading\">불러오는중…</string>\n    <string name=\"extension\">확장자</string>\n    <string name=\"app_closing_sub\">앱을 정말 종료하시겠습니까?</string>\n    <string name=\"copied\">클립보드에 복사되었습니다</string>\n    <string name=\"edit_exif\">EXIF 수정</string>\n    <string name=\"no_exif\">EXIF 데이터를 찾을 수 없습니다</string>\n    <string name=\"add_tag\">tag 추가</string>\n    <string name=\"cancel\">취소</string>\n    <string name=\"clear_exif_sub\">이미지의 모든 EXIF 데이터가 지워집니다. 이 작업은 되돌릴 수 없습니다!</string>\n    <string name=\"clear_exif\">EXIF 지우기</string>\n    <string name=\"presets\">사전설정</string>\n    <string name=\"version\">버전</string>\n    <string name=\"crop\">자르기</string>\n    <string name=\"pick_color\">색상 선택</string>\n    <string name=\"crop_sub\">원하는 범위로 이미지 자르기</string>\n    <string name=\"pick_color_sub\">이미지에서 색상을 선택, 복사 또는 공유</string>\n    <string name=\"keep_exif\">EXIF 유지</string>\n    <string name=\"image_not_saved_sub\">지금 나가면 저장되지 않은 모든 변경사항이 손실됩니다</string>\n    <string name=\"images\">이미지: %d</string>\n    <string name=\"change_preview\">변경 미리보기</string>\n    <string name=\"by_bytes_resize_sub\">주어진 크기 KB 에 따라 이미지 크기 조정</string>\n    <string name=\"pick_two_images\">이미지 두 개를 선택하세요</string>\n    <string name=\"color_blue\">파란색</string>\n    <string name=\"issue_tracker_sub\">여기에 버그 보고서 및 기능 요청을 보내주십시오.</string>\n    <string name=\"update\">업데이트</string>\n    <string name=\"amoled_mode_sub\">활성화된 경우 야간 모드에서 표면 색상이 완전히 어둡게 설정됩니다.</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">동적 색상이 켜져 있는 동안에는 앱 색 구성표를 변경할 수 없습니다.</string>\n    <string name=\"no_updates\">업데이트가 없습니다.</string>\n    <string name=\"issue_tracker\">이슈 트래커</string>\n    <string name=\"dynamic_colors_sub\">활성화하면 앱 색상이 배경 화면 색상에 적용됩니다.</string>\n    <string name=\"surface\">표면</string>\n    <string name=\"permission_sub\">앱이 이미지를 저장하려면 저장소에 액세스해야하며, 그렇지 않으면 작동 할 수 없으므로 다음 대화 상자에서 권한을 부여하세요.</string>\n    <string name=\"donation_sub\">이 애플리케이션은 완전 무료이지만, 프로젝트 개발을 지원하고 싶다면 여기를 클릭하세요.</string>\n    <string name=\"image_too_large_preview\">이미지가 너무 커서 미리 볼 수 없지만, 일단 저장을 시도합니다</string>\n    <string name=\"fab_alignment\">FAB 정렬</string>\n    <string name=\"check_updates\">업데이트 확인</string>\n    <string name=\"check_updates_sub\">활성화하면 앱 시작 후 업데이트 대화 상자가 표시됩니다.</string>\n    <string name=\"zoom\">이미지 확대/축소</string>\n    <string name=\"prefix\">접두사</string>\n    <string name=\"filename\">파일 이름</string>\n    <string name=\"share\">공유</string>\n    <string name=\"emoji\">이모티콘</string>\n    <string name=\"add_file_size_sub\">활성화하면 저장된 이미지의 너비와 높이가 출력 파일의 이름에 추가됩니다.</string>\n    <string name=\"add_file_size\">파일 크기 추가</string>\n    <string name=\"delete_exif\">EXIF 삭제</string>\n    <string name=\"image_source\">이미지 출처</string>\n    <string name=\"photo_picker\">사진 선택기</string>\n    <string name=\"photo_picker_sub\">화면 하단에 표시되는 Android 최신 사진 선택기는 Android 12 이상에서만 작동할 수 있으며 EXIF 메타데이터 수신에 문제가 있습니다.</string>\n    <string name=\"gallery_picker\">갤러리</string>\n    <string name=\"file_explorer_picker\">파일 탐색기</string>\n    <string name=\"gallery_picker_sub\">간단한 갤러리 이미지 선택기, 해당 앱이 있는 경우에만 작동합니다.</string>\n    <string name=\"options_arrangement\">옵션 배열</string>\n    <string name=\"edit\">편집하기</string>\n    <string name=\"order\">주문하다</string>\n    <string name=\"emojis_count\">이모티콘 수</string>\n    <string name=\"sequence_num\">시퀀스 번호</string>\n    <string name=\"original_filename\">원본 파일 이름</string>\n    <string name=\"add_original_filename\">원본 파일 이름 추가</string>\n    <string name=\"add_original_filename_sub\">활성화되면 출력 이미지의 이름에 원래 파일 이름을 추가합니다.</string>\n    <string name=\"file_explorer_picker_sub\">GetContent 의도를 사용하여 이미지를 선택하고 모든 곳에서 작동하지만 일부 장치에서 선택한 이미지를 수신하는 데 문제가 있을 수 있습니다. 제 잘못이 아닙니다</string>\n    <string name=\"replace_sequence_number\">시퀀스 번호 바꾸기</string>\n    <string name=\"emoji_sub\">메인 화면에 표시할 이모티콘 선택</string>\n    <string name=\"delete_exif_sub\">모든 이미지에서 EXIF 메타데이터 삭제</string>\n    <string name=\"image_preview\">이미지 미리보기</string>\n    <string name=\"image_preview_sub\">모든 유형의 이미지 미리보기: GIF, SVG 등</string>\n    <string name=\"order_sub\">메인 화면에서 도구의 순서를 결정합니다.</string>\n    <string name=\"replace_sequence_number_sub\">활성화된 경우 일괄 처리를 사용하는 경우 표준 타임스탬프를 이미지 시퀀스 번호로 바꿉니다.</string>\n    <string name=\"filename_not_work_with_photopicker\">사진 선택기 이미지 소스를 선택한 경우 원본 파일 이름 추가가 작동하지 않음</string>\n    <string name=\"highlights\">하이라이트</string>\n    <string name=\"shadows\">그림자</string>\n    <string name=\"vibrance\">생동감</string>\n    <string name=\"crosshatch\">크로스해칭</string>\n    <string name=\"spacing\">간격</string>\n    <string name=\"line_width\">선의 폭</string>\n    <string name=\"sobel_edge\">소벨 엣지</string>\n    <string name=\"filters\">필터</string>\n    <string name=\"exposure\">노출</string>\n    <string name=\"tint\">색조</string>\n    <string name=\"refractive_index\">굴절률</string>\n    <string name=\"opacity\">불투명</string>\n    <string name=\"limits_resize\">크기 조정 제한</string>\n    <string name=\"limits_resize_sub\">가로 세로 비율을 유지하면서 지정된 높이와 너비에 맞게 이미지 크기 조정하기</string>\n    <string name=\"non_maximum_suppression\">최대가 아닌 억제</string>\n    <string name=\"stack_blur\">스택 블러</string>\n    <string name=\"reorder\">재 주문</string>\n    <string name=\"load_image_from_net\">웹에서 이미지 불러오기</string>\n    <string name=\"load_image_from_net_sub\">인터넷에서 이미지 형식을 로드하고, 미리 보고, 확대하고, 원하는 경우 저장하거나 편집할 수도 있습니다.</string>\n    <string name=\"no_image\">이미지 없음</string>\n    <string name=\"image_link\">이미지 링크</string>\n    <string name=\"fill\">채우다</string>\n    <string name=\"fit\">맞다</string>\n    <string name=\"explicit_description\">지정된 높이와 너비에 맞게 이미지 크기를 조정합니다. - 이미지의 가로 세로 비율이 변경될 수 있습니다.</string>\n    <string name=\"flexible_description\">측면이 긴 이미지의 크기를 지정된 높이 또는 너비에 맞게 조정합니다. 모든 크기 계산은 저장 후 수행됩니다. 이미지의 가로 세로 비율은 그대로 유지됩니다.</string>\n    <string name=\"brightness\">명도</string>\n    <string name=\"contrast\">차이</string>\n    <string name=\"hue\">색조</string>\n    <string name=\"saturation\">포화</string>\n    <string name=\"add_filter\">필터 추가</string>\n    <string name=\"filter\">필터</string>\n    <string name=\"filter_sub\">주어진 이미지에 필터 체인 적용</string>\n    <string name=\"light_aka_illumination\">빛</string>\n    <string name=\"color_filter\">컬러 필터</string>\n    <string name=\"alpha\">알파</string>\n    <string name=\"white_balance\">화이트 밸런스</string>\n    <string name=\"temperature\">온도</string>\n    <string name=\"monochrome\">단색화</string>\n    <string name=\"gamma\">감마</string>\n    <string name=\"highlights_shadows\">하이라이트와 그림자</string>\n    <string name=\"haze\">안개</string>\n    <string name=\"effect\">효과</string>\n    <string name=\"distance\">거리</string>\n    <string name=\"slope\">경사</string>\n    <string name=\"sharpen\">갈다</string>\n    <string name=\"sepia\">세피아</string>\n    <string name=\"negative\">부정적인</string>\n    <string name=\"solarize\">솔라라이즈</string>\n    <string name=\"black_and_white\">검정색과 흰색</string>\n    <string name=\"blur\">흐림</string>\n    <string name=\"halftone\">반음</string>\n    <string name=\"cga_colorspace\">GCA 색상 공간</string>\n    <string name=\"gaussian_blur\">가우스 흐림</string>\n    <string name=\"box_blur\">상자 흐림</string>\n    <string name=\"bilaterial_blur\">양자 흐림</string>\n    <string name=\"emboss\">양각</string>\n    <string name=\"laplacian\">라플라시안</string>\n    <string name=\"vignette\">삽화</string>\n    <string name=\"start\">시작</string>\n    <string name=\"end\">끝</string>\n    <string name=\"kuwahara\">쿠와하라 스무딩</string>\n    <string name=\"radius\">반지름</string>\n    <string name=\"scale\">규모</string>\n    <string name=\"distortion\">왜곡</string>\n    <string name=\"angle\">각도</string>\n    <string name=\"swirl\">소용돌이</string>\n    <string name=\"bulge\">부풀다</string>\n    <string name=\"dilation\">팽창</string>\n    <string name=\"sphere_refraction\">구 굴절</string>\n    <string name=\"glass_sphere_refraction\">유리 구 굴절</string>\n    <string name=\"color_matrix\">컬러 매트릭스</string>\n    <string name=\"sketch\">스케치</string>\n    <string name=\"threshold\">한계점</string>\n    <string name=\"quantizationLevels\">양자화 수준</string>\n    <string name=\"smooth_toon\">부드러운 툰</string>\n    <string name=\"toon\">인도 마호가니</string>\n    <string name=\"posterize\">포스터라이즈</string>\n    <string name=\"weak_pixel_inclusion\">약한 픽셀 포함</string>\n    <string name=\"lookup\">조회</string>\n    <string name=\"convolution3x3\">컨볼루션 3x3</string>\n    <string name=\"rgb_filter\">RGB 필터</string>\n    <string name=\"false_color\">거짓 색상</string>\n    <string name=\"first_color\">첫 번째 색상</string>\n    <string name=\"second_color\">두 번째 색상</string>\n    <string name=\"fast_blur\">빠른 흐림</string>\n    <string name=\"blur_size\">블러 크기</string>\n    <string name=\"blur_center_x\">블러 센터 x</string>\n    <string name=\"blur_center_y\">블러 센터 y</string>\n    <string name=\"zoom_blur\">줌 블러</string>\n    <string name=\"color_balance\">색의 균형</string>\n    <string name=\"luminance_threshold\">휘도 임계값</string>\n    <string name=\"content_scale\">콘텐츠 규모</string>\n    <string name=\"file_proceed\">파일 처리됨</string>\n    <string name=\"cipher_sub\">AES 암호화 알고리즘을 기반으로 모든 파일 (이미지뿐만 아니라) 암호화 및 해독</string>\n    <string name=\"compatibility\">호환성</string>\n    <string name=\"draw_on_image_sub\">이미지를 선택하고 그 위에 무언가를 그립니다.</string>\n    <string name=\"draw_on_background\">배경에 그리기</string>\n    <string name=\"draw_on_background_sub\">배경색을 선택하고 그 위에 그림을 그립니다.</string>\n    <string name=\"activate_files\">파일 앱을 비활성화했습니다. 이 기능을 사용하려면 활성화하세요.</string>\n    <string name=\"background_color\">배경색</string>\n    <string name=\"cipher\">암호</string>\n    <string name=\"key\">열쇠</string>\n    <string name=\"store_file_desc\">이 파일을 기기에 저장하거나 공유 작업을 사용하여 원하는 위치에 배치하세요.</string>\n    <string name=\"decryption\">복호화</string>\n    <string name=\"features\">특징</string>\n    <string name=\"implementation\">구현</string>\n    <string name=\"cache\">은닉처</string>\n    <string name=\"cache_size\">캐시 크기</string>\n    <string name=\"found_s\">발견 %1$s</string>\n    <string name=\"auto_cache_clearing\">자동 캐시 지우기</string>\n    <string name=\"group_options_by_type_sub\">사용자 지정 목록 정렬 대신 해당 유형의 기본 화면에 있는 그룹 옵션</string>\n    <string name=\"auto_cache_clearing_sub\">활성화된 경우 앱 시작 시 앱 캐시가 지워집니다.</string>\n    <string name=\"tools\">도구</string>\n    <string name=\"secondary_customization\">보조 사용자화</string>\n    <string name=\"invalid_password_or_not_encrypted\">비밀번호가 잘못되었거나 선택한 파일이 암호화되지 않았습니다.</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">옵션 그룹화가 활성화된 상태에서는 배열을 변경할 수 없습니다.</string>\n    <string name=\"edit_screenshot\">스크린샷 수정</string>\n    <string name=\"fallback_option\">폴백 옵션</string>\n    <string name=\"skip\">건너뛰다</string>\n    <string name=\"copy\">복사</string>\n    <string name=\"warning_bytes\">%1$s 모드는 무손실 형식이므로 저장이 불안정할 수 있습니다.</string>\n    <string name=\"draw\">그리다</string>\n    <string name=\"pick_file\">파일 선택</string>\n    <string name=\"encryption\">암호화</string>\n    <string name=\"file_size_sub\">최대 파일 크기는 Android OS 및 사용 가능한 메모리에 의해 제한되며 이는 분명히 장치에 따라 다릅니다. \\n참고: 메모리는 스토리지가 아닙니다.</string>\n    <string name=\"compatibility_sub\">다른 파일 암호화 소프트웨어 또는 서비스와의 호환성은 보장되지 않습니다. 약간 다른 키 처리 또는 암호 구성이 비호환성의 원인이 될 수 있습니다.</string>\n    <string name=\"image_size_warning\">지정된 너비와 높이로 이미지를 저장하려고 하면 메모리 부족 오류가 발생할 수 있습니다. 이 작업에서 발생한 문제는 사용자 책임입니다.</string>\n    <string name=\"screenshot\">스크린샷</string>\n    <string name=\"group_options_by_type\">유형별로 그룹화 옵션</string>\n    <string name=\"draw_sub\">스케치북처럼 이미지 위에 그리거나, 배경 그 자체에 그립니다.</string>\n    <string name=\"paint_color\">페인트 색상</string>\n    <string name=\"paint_alpha\">페인트 알파</string>\n    <string name=\"draw_on_image\">이미지에 그리기</string>\n    <string name=\"encrypt\">암호화</string>\n    <string name=\"decrypt\">복호화</string>\n    <string name=\"pick_file_to_start\">시작할 파일 선택</string>\n    <string name=\"features_sub\">암호 기반 파일 암호화. 진행된 파일은 선택한 디렉토리에 저장하거나 공유할 수 있습니다. 해독된 파일을 직접 열 수도 있습니다.</string>\n    <string name=\"implementation_sub\">AES-256, GCM 모드, 패딩 없음, 12바이트 임의 IV. 키는 SHA-3 해시(256비트)로 사용됩니다.</string>\n    <string name=\"file_size\">파일 크기</string>\n    <string name=\"create\">만들기</string>\n    <string name=\"enhanced_pixelation\">향상된 픽셀화</string>\n    <string name=\"stroke_pixelation\">뇌졸중 픽셀화</string>\n    <string name=\"enhanced_diamond_pixelation\">향상된 다이아몬드 픽셀화</string>\n    <string name=\"diamond_pixelation\">다이아몬드 픽셀화</string>\n    <string name=\"circle_pixelation\">원 픽셀화</string>\n    <string name=\"enhanced_circle_pixelation\">향상된 원 픽셀화</string>\n    <string name=\"replace_color\">색상 바꾸기</string>\n    <string name=\"tolerance\">용인</string>\n    <string name=\"color_to_replace\">교체할 색상</string>\n    <string name=\"email\">이메일</string>\n    <string name=\"crop_mask\">자르기 마스크</string>\n    <string name=\"backup_sub\">앱 설정을 파일로 백업하세요</string>\n    <string name=\"contact_me\">저에게 연락하세요</string>\n    <string name=\"enhanced_glitch\">향상된 글리치</string>\n    <string name=\"corruption_shift_x\">부패 전환 X</string>\n    <string name=\"bottom\">맨 아래</string>\n    <string name=\"strength\">힘</string>\n    <string name=\"restore\">복원하다</string>\n    <string name=\"segmentation_mode_osd_only\">방향 &amp; 스크립트 감지 전용</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">단일 블록 세로 텍스트</string>\n    <string name=\"segmentation_mode_circle_word\">동그라미 단어</string>\n    <string name=\"segmentation_mode_single_char\">단일 문자</string>\n    <string name=\"segmentation_mode_sparse_text\">희소 텍스트</string>\n    <string name=\"glitch\">결함</string>\n    <string name=\"delete_mask_warn\">선택한 필터 마스크를 삭제하려고 합니다. 이 작업은 취소할 수 없습니다.</string>\n    <string name=\"delete_mask\">마스크 삭제</string>\n    <string name=\"drago\">드라고</string>\n    <string name=\"no_such_directory\">\\\"%1$s\\\" 디렉터리를 찾을 수 없습니다. 기본 디렉터리로 전환했습니다. 파일을 다시 저장하세요.</string>\n    <string name=\"overwrite_files_sub\">선택한 폴더에 저장하는 대신 원본 파일이 새 파일로 대체됩니다. 이 옵션은 이미지 소스가 \\\"Explorer\\\" 또는 GetContent여야 하며, 이 옵션을 전환하면 자동으로 설정됩니다.</string>\n    <string name=\"empty\">비어 있는</string>\n    <string name=\"free\">무료</string>\n    <string name=\"presets_sub\" formatted=\"false\">사전 설정에서 125를 선택한 경우 이미지가 원본 이미지의 125% 크기로 저장됩니다. 사전 설정에서 50을 선택하면 이미지가 50% 크기로 저장됩니다.</string>\n    <string name=\"presets_sub_bytes\">여기 사전 설정은 출력 파일의 %를 결정합니다. 즉, 5MB 이미지에서 사전 설정 50을 선택하면 저장 후 2.5MB 이미지를 얻게 됩니다.</string>\n    <string name=\"randomize_filename_sub\">활성화하면 출력 파일 이름이 완전히 무작위가 됩니다.</string>\n    <string name=\"saved_to_without_filename\">%1$s 폴더에 저장됨</string>\n    <string name=\"tg_chat\">텔레그램 채팅</string>\n    <string name=\"tg_chat_sub\">앱에 대해 토론하고 다른 사용자로부터 피드백을 받으세요. 여기에서 베타 업데이트와 통찰력을 얻을 수도 있습니다.</string>\n    <string name=\"aspect_ratio\">종횡비</string>\n    <string name=\"image_crop_mask_sub\">주어진 이미지에서 마스크를 생성하려면 이 마스크 유형을 사용하세요. 알파 채널이 있어야 합니다.</string>\n    <string name=\"backup_and_restore\">백업 및 복원</string>\n    <string name=\"reset_settings_sub\">그러면 설정이 기본값으로 롤백됩니다. 위에서 언급한 백업 파일 없이는 이 작업을 취소할 수 없습니다.</string>\n    <string name=\"delete_color_scheme_title\">구성표 삭제</string>\n    <string name=\"font_scale\">글꼴 크기</string>\n    <string name=\"using_large_fonts_warn\">큰 글꼴 크기를 사용하면 UI 결함 및 문제가 발생할 수 있으며 이는 해결되지 않습니다. 주의해서 사용하세요.</string>\n    <string name=\"alphabet_and_numbers\">가 나 다 라 마 바 사 아 자 차 카 타 파 하 0123456789 !?</string>\n    <string name=\"emotions\">감정</string>\n    <string name=\"food_and_drink\">음식과 음료</string>\n    <string name=\"nature_and_animals\">자연과 동물</string>\n    <string name=\"objects\">사물</string>\n    <string name=\"symbols\">기호</string>\n    <string name=\"enable_emoji\">이모티콘 활성화</string>\n    <string name=\"travels_and_places\">여행과 장소</string>\n    <string name=\"activities\">활동</string>\n    <string name=\"background_remover\">배경 제거기</string>\n    <string name=\"background_remover_sub\">그림을 그리거나 자동 옵션을 사용하여 이미지에서 배경을 제거합니다.</string>\n    <string name=\"trim_image\">이미지 자르기</string>\n    <string name=\"keep_exif_sub\">원본 이미지 메타데이터는 유지됩니다.</string>\n    <string name=\"trim_image_sub\">이미지 주변의 투명한 공간이 잘립니다.</string>\n    <string name=\"auto_erase_background\">배경 자동 삭제</string>\n    <string name=\"erase_background\">배경 지우기</string>\n    <string name=\"something_went_wrong_emphasis\">이런… 문제가 발생했습니다. 아래 옵션을 사용하여 저에게 메일을 보내주시면 제가 해결 방법을 찾아보겠습니다.</string>\n    <string name=\"resize_and_convert\">크기 조정 및 변환</string>\n    <string name=\"image_exif_warning\">현재 %1$s 형식은 Android에서 EXIF 메타데이터 읽기만 허용합니다. 출력 이미지에는 저장 시 메타데이터가 전혀 포함되지 않습니다.</string>\n    <string name=\"updates\">업데이트</string>\n    <string name=\"allow_betas\">베타 허용</string>\n    <string name=\"allow_betas_sub\">활성화된 경우 업데이트 확인에 베타 앱 버전이 포함됩니다.</string>\n    <string name=\"draw_arrows\">화살표 그리기</string>\n    <string name=\"draw_arrows_sub\">활성화된 경우 그리기 경로는 가리키는 화살표로 표시됩니다.</string>\n    <string name=\"brush_softness\">브러시 부드러움</string>\n    <string name=\"donation\">기부</string>\n    <string name=\"horizontal\">수평의</string>\n    <string name=\"vertical\">수직의</string>\n    <string name=\"scale_small_images_to_large\">작은 이미지를 크게 확대</string>\n    <string name=\"scale_small_images_to_large_sub\">활성화된 경우 작은 이미지는 시퀀스에서 가장 큰 이미지로 크기가 조정됩니다.</string>\n    <string name=\"images_order\">이미지 순서</string>\n    <string name=\"target_color\">대상 색상</string>\n    <string name=\"color_to_remove\">제거할 색상</string>\n    <string name=\"remove_color\">색상 제거</string>\n    <string name=\"recode\">녹음</string>\n    <string name=\"lock_draw_orientation_sub\">그리기 모드에서 활성화하면 화면이 회전하지 않습니다.</string>\n    <string name=\"tonal_spot\">토널 스팟</string>\n    <string name=\"neutral\">중립적</string>\n    <string name=\"vibrant\">떠는</string>\n    <string name=\"fruit_salad\">과일 샐러드</string>\n    <string name=\"fidelity\">충실도</string>\n    <string name=\"content\">콘텐츠</string>\n    <string name=\"tonal_spot_sub\">기본 팔레트 스타일로 4가지 색상을 모두 사용자 정의할 수 있으며 다른 색상은 주요 색상만 설정할 수 있습니다.</string>\n    <string name=\"neutral_sub\">모노크롬보다 살짝 더 유채색인 스타일</string>\n    <string name=\"vibrant_sub\">시끄러운 테마, 기본 팔레트에서는 다채로움이 최대이고 다른 팔레트에서는 증가합니다.</string>\n    <string name=\"playful_scheme\">재미있는 테마 - 원본 색상의 색조가 테마에 표시되지 않습니다.</string>\n    <string name=\"monochrome_sub\">단색 테마, 색상은 순수 검정/흰색/회색입니다.</string>\n    <string name=\"content_sub\">Scheme.primaryContainer에 소스 색상을 배치하는 구성표</string>\n    <string name=\"fidelity_sub\">콘텐츠 구성표와 매우 유사한 구성표</string>\n    <string name=\"both\">둘 다</string>\n    <string name=\"invert_colors_sub\">활성화된 경우 테마 색상을 부정적인 색상으로 바꿉니다.</string>\n    <string name=\"search_option\">찾다</string>\n    <string name=\"search_option_sub\">메인 화면에서 사용 가능한 모든 도구를 검색할 수 있습니다.</string>\n    <string name=\"pdf_to_images_sub\">주어진 출력 형식의 PDF를 이미지로 변환</string>\n    <string name=\"images_to_pdf_sub\">주어진 이미지를 출력 PDF 파일로 압축</string>\n    <string name=\"mask_indexed\">마스크 %d</string>\n    <string name=\"simple_variants\">단순 변형</string>\n    <string name=\"highlighter\">형광펜</string>\n    <string name=\"neon\">네온</string>\n    <string name=\"pen\">펜</string>\n    <string name=\"privacy_blur\">개인 정보 보호 흐림</string>\n    <string name=\"neon_sub\">그림에 빛나는 효과를 추가하세요</string>\n    <string name=\"pen_sub\">기본 하나, 가장 간단함 - 색상만 있음</string>\n    <string name=\"privacy_blur_sub\">숨기고 싶은 것을 보호하기 위해 그려진 경로 아래의 이미지를 흐리게 합니다.</string>\n    <string name=\"pixelation_sub\">프라이버시 블러와 유사하지만 블러링 대신 픽셀화됩니다.</string>\n    <string name=\"sliders_shadow_sub\">슬라이더 뒤에 그림자 그리기를 활성화합니다.</string>\n    <string name=\"switches_shadow_sub\">스위치 뒤에 그림자 그리기를 활성화합니다.</string>\n    <string name=\"fabs_shadow_sub\">플로팅 액션 버튼 뒤에 그림자 그리기를 활성화합니다.</string>\n    <string name=\"buttons_shadow_sub\">기본 버튼 뒤에 그림자 그리기를 활성화합니다.</string>\n    <string name=\"app_bars_shadow_sub\">앱 바 뒤에 그림자 그리기를 활성화합니다.</string>\n    <string name=\"auto_rotate_limits\">자동 회전</string>\n    <string name=\"auto_rotate_limits_sub\">이미지 방향에 제한 상자를 채택할 수 있습니다.</string>\n    <string name=\"line_sub\">시작점에서 끝점까지의 경로를 선으로 그립니다.</string>\n    <string name=\"line_arrow_sub\">시작점에서 끝점까지 가리키는 화살표를 선으로 그립니다.</string>\n    <string name=\"arrow_sub\">지정된 경로에서 가리키는 화살표를 그립니다.</string>\n    <string name=\"double_line_arrow_sub\">시작점에서 끝점까지 이중 화살표를 선으로 그립니다.</string>\n    <string name=\"double_arrow_sub\">지정된 경로에서 이중 가리키는 화살표를 그립니다.</string>\n    <string name=\"rect_sub\">시작점에서 끝점까지 직사각형을 그립니다.</string>\n    <string name=\"oval_sub\">시작점에서 끝점까지 타원을 그립니다.</string>\n    <string name=\"outlined_oval_sub\">시작점에서 끝점까지 윤곽선이 있는 타원을 그립니다.</string>\n    <string name=\"outlined_rect_sub\">시작점에서 끝점까지 윤곽선이 있는 직사각형을 그립니다.</string>\n    <string name=\"vertical_grid\">수직 그리드</string>\n    <string name=\"stitch_mode\">스티치 모드</string>\n    <string name=\"rows_count\">행 수</string>\n    <string name=\"columns_count\">열 개수</string>\n    <string name=\"clipboard\">클립보드</string>\n    <string name=\"auto_pin\">자동 핀</string>\n    <string name=\"auto_pin_sub\">활성화된 경우 저장된 이미지를 클립보드에 자동으로 추가합니다.</string>\n    <string name=\"vibration\">진동</string>\n    <string name=\"vibration_strength\">진동 강도</string>\n    <string name=\"overwrite_file_requirements\">파일을 덮어쓰려면 \\\"탐색기\\\" 이미지 소스를 사용해야 합니다. 이미지를 다시 선택해 보세요. 이미지 소스를 필요한 이미지 소스로 변경했습니다.</string>\n    <string name=\"overwrite_files\">파일 덮어쓰기</string>\n    <string name=\"suffix\">접미사</string>\n    <string name=\"bicubic\">쌍입방</string>\n    <string name=\"basic\">기초적인</string>\n    <string name=\"bilinear_sub\">선형(또는 2차원의 이중선형) 보간은 일반적으로 이미지 크기를 변경하는 데 적합하지만 세부 사항이 바람직하지 않게 부드러워지고 여전히 들쭉날쭉해질 수 있습니다.</string>\n    <string name=\"bicubic_sub\">더 나은 스케일링 방법에는 Lanczos 리샘플링 및 Mitchell-Netravali 필터가 포함됩니다.</string>\n    <string name=\"nearest_sub\">크기를 늘리는 간단한 방법 중 하나입니다. 모든 픽셀을 동일한 색상의 여러 픽셀로 바꾸는 것입니다.</string>\n    <string name=\"basic_sub\">거의 모든 앱에서 사용되는 가장 간단한 안드로이드 스케일링 모드</string>\n    <string name=\"catmull_sub\">부드러운 곡선을 만들기 위해 컴퓨터 그래픽에서 일반적으로 사용되는 일련의 제어점을 부드럽게 보간하고 리샘플링하는 방법</string>\n    <string name=\"hann_sub\">스펙트럼 누출을 최소화하고 신호의 가장자리를 테이퍼링하여 주파수 분석의 정확성을 향상시키기 위해 신호 처리에 자주 적용되는 윈도우 기능</string>\n    <string name=\"hermite_sub\">부드럽고 연속적인 곡선을 생성하기 위해 곡선 세그먼트의 끝점에서 값과 도함수를 사용하는 수학적 보간 기술</string>\n    <string name=\"lanczos_sub\">픽셀값에 가중치를 부여한 sinc 함수를 적용하여 고품질의 보간을 유지하는 리샘플링 방식</string>\n    <string name=\"mitchell_sub\">조정 가능한 매개변수가 있는 컨볼루션 필터를 사용하여 크기 조정된 이미지의 선명도와 앤티앨리어싱 간의 균형을 달성하는 리샘플링 방법</string>\n    <string name=\"spline_sub\">조각별로 정의된 다항식 함수를 사용하여 커브 또는 표면을 부드럽게 보간하고 근사치를 구하여 유연하고 연속적인 모양 표현을 제공합니다..</string>\n    <string name=\"only_clip_sub\">저장소에 저장되지 않으며, 클립보드에만 이미지를 넣으려고 합니다.</string>\n    <string name=\"use_pixel_switch_sub\">구글 픽셀과 같은 스위치를 사용합니다.</string>\n    <string name=\"saved_to_original\">원래 대상에 이름이 %1$s인 파일을 덮어썼습니다.</string>\n    <string name=\"magnifier\">돋보기</string>\n    <string name=\"force_exif_widget_initial_value\">강제 초기값</string>\n    <string name=\"magnifier_sub\">더 나은 접근성을 위해 그리기 모드에서 손가락 상단에 돋보기를 활성화합니다.</string>\n    <string name=\"force_exif_widget_initial_value_sub\">EXIF 위젯을 처음에 강제로 확인합니다.</string>\n    <string name=\"allow_multiple_languages\">다중 언어 허용</string>\n    <string name=\"toggle_tap\">탭 전환</string>\n    <string name=\"rate_app_sub\">이 앱은 완전 무료입니다. 앱이 더 커지길 원한다면 Github에서 프로젝트에 별표를 표시해 주세요 😄</string>\n    <string name=\"segmentation_mode_auto_osd\">자동 방향 지정 &amp; 스크립트 감지</string>\n    <string name=\"segmentation_mode_auto_only\">자동만</string>\n    <string name=\"segmentation_mode_auto\">자동</string>\n    <string name=\"segmentation_mode_single_column\">단일 열</string>\n    <string name=\"segmentation_mode_single_block\">단일 블록</string>\n    <string name=\"segmentation_mode_single_line\">하나의 선</string>\n    <string name=\"segmentation_mode_single_word\">한 단어</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">희소 텍스트 방향 &amp; 스크립트 감지</string>\n    <string name=\"segmentation_mode_raw_line\">원시 라인</string>\n    <string name=\"delete_language_sub\">모든 인식 유형에 대한 언어 \\\"%1$s\\\" OCR 훈련 데이터를 삭제하시겠습니까, 아니면 선택한 인식 유형(%2$s)에 대해서만 삭제하시겠습니까?</string>\n    <string name=\"properties\">속성</string>\n    <string name=\"gradient_maker_type_image_sub\">주어진 이미지 상단의 그라데이션을 구성합니다.</string>\n    <string name=\"camera\">카메라</string>\n    <string name=\"watermarking_sub\">사용자 정의 가능한 텍스트/이미지 워터마크로 사진 표지</string>\n    <string name=\"offset_y\">오프셋 Y</string>\n    <string name=\"watermark_type\">워터마크 유형</string>\n    <string name=\"watermarking_image_sub\">이 이미지는 워터마킹의 패턴으로 사용됩니다.</string>\n    <string name=\"gif_type_to_image\">GIF를 이미지로</string>\n    <string name=\"gif_type_to_image_sub\">GIF 파일을 사진 묶음으로 변환</string>\n    <string name=\"gif_type_to_gif_sub\">일괄 이미지를 GIF 파일로 변환</string>\n    <string name=\"gif_type_to_gif\">이미지를 GIF로</string>\n    <string name=\"select_gif_image_to_start\">시작하려면 GIF 이미지를 선택하세요.</string>\n    <string name=\"use_size_of_first_frame\">첫 번째 프레임 크기 사용</string>\n    <string name=\"use_size_of_first_frame_sub\">지정된 크기를 첫 번째 프레임 크기로 바꾸기</string>\n    <string name=\"repeat_count\">반복 횟수</string>\n    <string name=\"frame_delay\">프레임 지연</string>\n    <string name=\"millis\">밀리초</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"confetti\">색종이 조각</string>\n    <string name=\"confetti_sub\">저장, 공유 및 기타 기본 작업에 색종이가 표시됩니다.</string>\n    <string name=\"secure_mode\">보안 모드</string>\n    <string name=\"secure_mode_sub\">종료 시 콘텐츠를 숨깁니다. 또한 화면을 캡처하거나 녹화할 수 없습니다.</string>\n    <string name=\"gray_scale\">그레이 스케일</string>\n    <string name=\"bayer_two_dithering\">바이엘 투 바이 투 디더링</string>\n    <string name=\"bayer_three_dithering\">바이엘 3x3 디더링</string>\n    <string name=\"bayer_four_dithering\">바이엘 포 바이 포 디더링</string>\n    <string name=\"floyd_steinberg_dithering\">플로이드 스타인버그 디더링</string>\n    <string name=\"jarvis_judice_ninke_dithering\">자비스 주디스 닌케 디더링</string>\n    <string name=\"sierra_dithering\">시에라 디더링</string>\n    <string name=\"two_row_sierra_dithering\">두 행 시에라 디더링</string>\n    <string name=\"sierra_lite_dithering\">시에라 라이트 디더링</string>\n    <string name=\"atkinson_dithering\">앳킨슨 디더링</string>\n    <string name=\"stucki_dithering\">스투키 디더링</string>\n    <string name=\"burkes_dithering\">버크스 디더링</string>\n    <string name=\"random_dithering\">랜덤 디더링</string>\n    <string name=\"simple_threshold_dithering\">단순 임계값 디더링</string>\n    <string name=\"tilt_shift\">경사 변화</string>\n    <string name=\"amount\">양</string>\n    <string name=\"b_spline_sub\">조각별로 정의된 쌍삼차 다항식 함수를 활용하여 곡선이나 표면을 부드럽게 보간하고 근사화하며 유연하고 연속적인 모양 표현을 제공합니다.</string>\n    <string name=\"seed\">씨앗</string>\n    <string name=\"anaglyph\">애너글리프</string>\n    <string name=\"noise\">소음</string>\n    <string name=\"pixel_sort\">픽셀 정렬</string>\n    <string name=\"shuffle\">혼합</string>\n    <string name=\"channel_shift_x\">채널 이동 X</string>\n    <string name=\"channel_shift_y\">채널 이동 Y</string>\n    <string name=\"corruption_size\">손상 크기</string>\n    <string name=\"corruption_shift_y\">부패 변화 Y</string>\n    <string name=\"tent_blur\">텐트 블러</string>\n    <string name=\"side_fade\">사이드 페이드</string>\n    <string name=\"side\">옆</string>\n    <string name=\"top\">맨 위</string>\n    <string name=\"water_effect\">물 효과</string>\n    <string name=\"color_matrix_3x3\">컬러 매트릭스 3x3</string>\n    <string name=\"simple_effects\">간단한 효과</string>\n    <string name=\"polaroid\">폴라로이드</string>\n    <string name=\"tritonomaly\">청색약</string>\n    <string name=\"deutaromaly\">녹색약</string>\n    <string name=\"protonomaly\">적색약</string>\n    <string name=\"vintage\">포도 수확</string>\n    <string name=\"coda_chrome\">코다 크롬</string>\n    <string name=\"night_vision\">나이트 비전</string>\n    <string name=\"cool\">시원한</string>\n    <string name=\"tritanopia\">삼변맹</string>\n    <string name=\"deutaronotopia\">듀타로노토피아</string>\n    <string name=\"protanopia\">백색맹</string>\n    <string name=\"achromatomaly\">색종종</string>\n    <string name=\"achromatopsia\">색맹</string>\n    <string name=\"purple_mist\">보라색 안개</string>\n    <string name=\"sunrise\">해돋이</string>\n    <string name=\"colorful_swirl\">다채로운 소용돌이</string>\n    <string name=\"soft_spring_light\">부드러운 봄빛</string>\n    <string name=\"autumn_tones\">가을 톤</string>\n    <string name=\"lavender_dream\">라벤더 드림</string>\n    <string name=\"lemonade_light\">레모네이드 라이트</string>\n    <string name=\"spectral_fire\">스펙트럼 파이어</string>\n    <string name=\"night_magic\">나이트 매직</string>\n    <string name=\"fantasy_landscape\">환상의 풍경</string>\n    <string name=\"color_explosion\">컬러 폭발</string>\n    <string name=\"electric_gradient\">전기 그래디언트</string>\n    <string name=\"caramel_darkness\">카라멜 다크니스</string>\n    <string name=\"futuristic_gradient\">미래 지향적인 그라데이션</string>\n    <string name=\"green_sun\">그린 썬</string>\n    <string name=\"rainbow_world\">레인보우 월드</string>\n    <string name=\"deep_purple\">딥 퍼플</string>\n    <string name=\"space_portal\">우주 포털</string>\n    <string name=\"red_swirl\">붉은 소용돌이</string>\n    <string name=\"digital_code\">디지털 코드</string>\n    <string name=\"icon_shape\">아이콘 모양</string>\n    <string name=\"aldridge\">알드리지</string>\n    <string name=\"cutoff\">끊다</string>\n    <string name=\"uchimura\">우치무라</string>\n    <string name=\"mobius\">뫼비우스</string>\n    <string name=\"transition\">이행</string>\n    <string name=\"peak\">정점</string>\n    <string name=\"color_anomaly\">색상 이상</string>\n    <string name=\"images_overwritten\">원래 대상에서 덮어쓴 이미지</string>\n    <string name=\"cannot_change_image_format\">파일 덮어쓰기 옵션이 활성화된 동안에는 이미지 형식을 변경할 수 없습니다.</string>\n    <string name=\"emoji_as_color_scheme\">색 구성표로서의 이모티콘</string>\n    <string name=\"emoji_as_color_scheme_sub\">수동으로 정의한 색상 대신 이모티콘 기본 색상을 앱 색상 구성표로 사용합니다.</string>\n    <string name=\"corrupted_file_or_not_a_backup\">파일이 손상되었거나 백업이 아님</string>\n    <string name=\"defaultt\">기본</string>\n    <string name=\"restore_background\">배경 복원</string>\n    <string name=\"resize_and_convert_sub\">주어진 이미지의 크기를 변경하거나 다른 형식으로 변환하세요. 단일 이미지를 선택하는 경우 여기에서 EXIF 메타데이터를 편집할 수도 있습니다.</string>\n    <string name=\"crop_description\">사진은 입력한 크기에 맞게 가운데가 잘립니다. 이미지가 입력한 크기보다 작을 경우 캔버스가 지정된 배경색으로 확장됩니다.</string>\n    <string name=\"erode\">좀먹다</string>\n    <string name=\"anisotropic_diffusion\">이방성 확산</string>\n    <string name=\"diffusion\">확산</string>\n    <string name=\"conduction\">전도</string>\n    <string name=\"horizontal_wind_stagger\">수평풍 비틀거림</string>\n    <string name=\"fast_bilaterial_blur\">빠른 양측 흐림</string>\n    <string name=\"poisson_blur\">포아송 블러</string>\n    <string name=\"logarithmic_tone_mapping\">로그 톤 매핑</string>\n    <string name=\"crystallize\">결정화하다</string>\n    <string name=\"stroke_color\">획 색상</string>\n    <string name=\"fractal_glass\">프랙탈 유리</string>\n    <string name=\"amplitude\">진폭</string>\n    <string name=\"marble\">대리석</string>\n    <string name=\"turbulence\">난기류</string>\n    <string name=\"oil\">기름</string>\n    <string name=\"just_size\">크기</string>\n    <string name=\"frequency_x\">빈도 X</string>\n    <string name=\"frequency_y\">빈도 Y</string>\n    <string name=\"amplitude_x\">진폭 X</string>\n    <string name=\"amplitude_y\">진폭 Y</string>\n    <string name=\"perlin_distortion\">펄린 왜곡</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable 필름 톤 매핑</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess 톤 매핑</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES 영화 톤 매핑</string>\n    <string name=\"aces_hill_tone_mapping\">ACES 힐 톤 매핑</string>\n    <string name=\"current\">현재의</string>\n    <string name=\"all\">모두</string>\n    <string name=\"full_filter\">전체 필터</string>\n    <string name=\"start_position\">시작</string>\n    <string name=\"center_position\">센터</string>\n    <string name=\"end_position\">끝</string>\n    <string name=\"full_filter_sub\">특정 이미지 또는 단일 이미지에 필터 체인 적용</string>\n    <string name=\"pdf_tools_sub\">PDF 파일로 작업: 미리보기, 이미지 배치로 변환 또는 주어진 사진에서 하나 생성</string>\n    <string name=\"preview_pdf\">PDF 미리보기</string>\n    <string name=\"pdf_to_images\">PDF를 이미지로</string>\n    <string name=\"images_to_pdf\">이미지를 PDF로</string>\n    <string name=\"preview_pdf_sub\">간단한 PDF 미리보기</string>\n    <string name=\"gradient_maker\">그라디언트 메이커</string>\n    <string name=\"gradient_maker_sub\">사용자 정의된 색상 및 모양 유형으로 지정된 출력 크기의 그라데이션 생성</string>\n    <string name=\"speed\">속도</string>\n    <string name=\"dehaze\">디헤이즈</string>\n    <string name=\"omega\">오메가</string>\n    <string name=\"pdf_tools\">PDF 도구</string>\n    <string name=\"rate_app\">앱 평가</string>\n    <string name=\"rate\">비율</string>\n    <string name=\"color_matrix_4x4\">컬러 매트릭스 4x4</string>\n    <string name=\"browni\">브라우니</string>\n    <string name=\"warm\">따뜻한</string>\n    <string name=\"gradient_type_linear\">선의</string>\n    <string name=\"gradient_type_radial\">방사형</string>\n    <string name=\"gradient_type_sweep\">스위프</string>\n    <string name=\"gradient_type\">그라데이션 유형</string>\n    <string name=\"center_x\">센터 X</string>\n    <string name=\"center_y\">센터 Y</string>\n    <string name=\"tile_mode\">타일 모드</string>\n    <string name=\"tile_mode_repeated\">반복됨</string>\n    <string name=\"tile_mode_mirror\">거울</string>\n    <string name=\"tile_mode_clamp\">집게</string>\n    <string name=\"tile_mode_decal\">데칼</string>\n    <string name=\"color_stops\">컬러 정지</string>\n    <string name=\"add_color\">색상 추가</string>\n    <string name=\"lasso\">올가미</string>\n    <string name=\"lasso_sub\">주어진 경로로 닫힌 채워진 경로를 그립니다.</string>\n    <string name=\"draw_path_mode\">경로 그리기 모드</string>\n    <string name=\"double_line_arrow\">이중선 화살표</string>\n    <string name=\"free_drawing\">무료 드로잉</string>\n    <string name=\"double_arrow\">이중 화살표</string>\n    <string name=\"line_arrow\">선 화살표</string>\n    <string name=\"arrow\">화살</string>\n    <string name=\"line\">선</string>\n    <string name=\"free_drawing_sub\">입력 값으로 경로를 그립니다.</string>\n    <string name=\"outlined_oval\">윤곽선이 있는 타원형</string>\n    <string name=\"outlined_rect\">윤곽선이 있는 직사각형</string>\n    <string name=\"oval\">타원형</string>\n    <string name=\"rect\">직사각형</string>\n    <string name=\"dithering\">디더링</string>\n    <string name=\"quantizier\">양자화기</string>\n    <string name=\"bayer_eight_dithering\">바이엘 에이트 바이 에이트 디더링</string>\n    <string name=\"false_floyd_steinberg_dithering\">거짓 플로이드 스타인버그 디더링</string>\n    <string name=\"left_to_right_dithering\">왼쪽에서 오른쪽으로 디더링</string>\n    <string name=\"max_colors_count\">최대 색상 수</string>\n    <string name=\"crashlytics_sub\">이를 통해 앱이 충돌 보고서를 자동으로 수집할 수 있습니다.</string>\n    <string name=\"effort\">노력</string>\n    <string name=\"effort_sub\">%1$s 값은 빠른 압축을 의미하므로 파일 크기가 상대적으로 커집니다. %2$s는 압축 속도가 느려져 파일 크기가 작아짐을 의미합니다.</string>\n    <string name=\"wait\">기다리다</string>\n    <string name=\"saving_almost_complete\">저장이 거의 완료되었습니다. 지금 취소하면 다시 저장해야 합니다.</string>\n    <string name=\"mask_color\">마스크 색상</string>\n    <string name=\"mask_preview\">마스크 미리보기</string>\n    <string name=\"mask_preview_sub\">그려진 필터 마스크가 렌더링되어 대략적인 결과를 보여줍니다.</string>\n    <string name=\"scale_mode\">스케일 모드</string>\n    <string name=\"bilinear\">이중선형</string>\n    <string name=\"hann\">한</string>\n    <string name=\"hermite\">에르미트</string>\n    <string name=\"lanczos\">란초스</string>\n    <string name=\"mitchell\">미첼</string>\n    <string name=\"nearest\">가장 가까운</string>\n    <string name=\"spline\">운형자</string>\n    <string name=\"default_value\">기본값</string>\n    <string name=\"value_in_range\">%1$s - %2$s 범위의 값</string>\n    <string name=\"sigma\">시그마</string>\n    <string name=\"spatial_sigma\">공간 시그마</string>\n    <string name=\"median_blur\">중앙값 흐림</string>\n    <string name=\"catmull\">캣멀</string>\n    <string name=\"only_clip\">클립만</string>\n    <string name=\"icon_shape_sub\">카드의 주요 아이콘 아래에 선택한 모양의 컨테이너를 추가합니다.</string>\n    <string name=\"image_stitching\">이미지 스티칭</string>\n    <string name=\"image_stitching_sub\">주어진 이미지를 결합하여 하나의 큰 이미지를 얻으세요</string>\n    <string name=\"brightness_enforcement\">밝기 강화</string>\n    <string name=\"screen\">화면</string>\n    <string name=\"gradient_maker_type_image\">그라데이션 오버레이</string>\n    <string name=\"transformations\">변환</string>\n    <string name=\"camera_sub\">카메라를 사용하여 사진을 찍습니다. 이 이미지 소스에서는 단 하나의 이미지만 가져올 수 있습니다.</string>\n    <string name=\"pick_at_least_two_images\">이미지를 2개 이상 선택하세요.</string>\n    <string name=\"output_image_scale\">출력 이미지 크기</string>\n    <string name=\"image_orientation\">이미지 방향</string>\n    <string name=\"grain\">곡물</string>\n    <string name=\"unsharp\">언샵</string>\n    <string name=\"pastel\">파스텔</string>\n    <string name=\"orange_haze\">오렌지 헤이즈</string>\n    <string name=\"pink_dream\">핑크 드림</string>\n    <string name=\"golden_hour\">골든아워</string>\n    <string name=\"hot_summer\">더운 여름</string>\n    <string name=\"cyberpunk\">사이버펑크</string>\n    <string name=\"watermarking\">워터마킹</string>\n    <string name=\"repeat_watermark\">워터마크 반복</string>\n    <string name=\"repeat_watermark_sub\">주어진 위치에서 단일 워터마크 대신 이미지 전체에 워터마크를 반복합니다.</string>\n    <string name=\"offset_x\">오프셋 X</string>\n    <string name=\"text_color\">텍스트 색상</string>\n    <string name=\"overlay_mode\">오버레이 모드</string>\n    <string name=\"pixel_size\">픽셀 크기</string>\n    <string name=\"lock_draw_orientation\">그리기 방향 잠금</string>\n    <string name=\"bokeh\">보케</string>\n    <string name=\"gif_tools\">GIF 도구</string>\n    <string name=\"gif_tools_sub\">이미지를 GIF 그림으로 변환하거나 주어진 GIF 이미지에서 프레임을 추출합니다.</string>\n    <string name=\"use_lasso\">올가미 사용</string>\n    <string name=\"use_lasso_sub\">그리기 모드에서와 같이 올가미를 사용하여 지우기를 수행합니다.</string>\n    <string name=\"original_image_preview_alpha\">원본 이미지 미리보기 알파</string>\n    <string name=\"mask_filter\">마스크 필터</string>\n    <string name=\"mask_filter_sub\">지정된 마스크 영역에 필터 체인을 적용합니다. 각 마스크 영역은 자체 필터 세트를 결정할 수 있습니다.</string>\n    <string name=\"masks\">마스크</string>\n    <string name=\"add_mask\">마스크 추가</string>\n    <string name=\"random_emojis_sub\">앱바 이모지가 무작위로 변경됩니다.</string>\n    <string name=\"random_emojis\">무작위 이모티콘</string>\n    <string name=\"random_emojis_error\">이모티콘이 비활성화된 동안에는 무작위 이모티콘 선택을 사용할 수 없습니다.</string>\n    <string name=\"emoji_selection_error\">무작위로 이모티콘을 선택하는 동안에는 이모티콘을 선택할 수 없습니다.</string>\n    <string name=\"check_for_updates\">업데이트 확인</string>\n    <string name=\"randomize_filename\">파일 이름 무작위화</string>\n    <string name=\"saved_to\">이름이 %2$s인 %1$s 폴더에 저장되었습니다.</string>\n    <string name=\"backup\">지원</string>\n    <string name=\"restore_sub\">이전에 생성된 파일에서 앱 설정 복원</string>\n    <string name=\"settings_restored\">설정이 성공적으로 복원되었습니다.</string>\n    <string name=\"delete\">삭제</string>\n    <string name=\"delete_color_scheme_warn\">선택한 색 구성표를 삭제하려고 합니다. 이 작업은 취소할 수 없습니다.</string>\n    <string name=\"font\">폰트</string>\n    <string name=\"text\">텍스트</string>\n    <string name=\"restore_image\">이미지 복원</string>\n    <string name=\"erase_mode\">지우기 모드</string>\n    <string name=\"blur_radius\">흐림 반경</string>\n    <string name=\"pipette\">피펫</string>\n    <string name=\"draw_mode\">그리기 모드</string>\n    <string name=\"create_issue\">이슈 생성</string>\n    <string name=\"analytics\">해석학</string>\n    <string name=\"analytics_sub\">익명의 앱 사용 통계 수집 허용</string>\n    <string name=\"old_tv\">오래된 TV</string>\n    <string name=\"shuffle_blur\">셔플 블러</string>\n    <string name=\"recognize_text\">OCR(텍스트 인식)</string>\n    <string name=\"recognize_text_sub\">주어진 이미지에서 텍스트를 인식합니다. 120개 이상의 언어가 지원됩니다.</string>\n    <string name=\"picture_has_no_text\">사진에 텍스트가 없거나 앱에서 텍스트를 찾지 못했습니다.</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">인식 유형</string>\n    <string name=\"fast\">빠른</string>\n    <string name=\"standard\">기준</string>\n    <string name=\"best\">최상의</string>\n    <string name=\"no_data\">데이터 없음</string>\n    <string name=\"download_description\">Tesseract OCR이 제대로 작동하려면 추가 학습 데이터(%1$s)를 기기에 다운로드해야 합니다. \\n%2$s 데이터를 다운로드하시겠습니까?</string>\n    <string name=\"download\">다운로드</string>\n    <string name=\"no_connection\">연결되지 않았습니다. 기차 모델을 다운로드하려면 확인하고 다시 시도하세요.</string>\n    <string name=\"downloaded_languages\">다운로드된 언어</string>\n    <string name=\"available_languages\">사용 가능한 언어</string>\n    <string name=\"segmentation_mode\">분할 모드</string>\n    <string name=\"restore_background_sub\">브러시는 배경을 지우는 대신 복원합니다.</string>\n    <string name=\"horizontal_grid\">수평 그리드</string>\n    <string name=\"use_pixel_switch\">픽셀 스위치 사용</string>\n    <string name=\"slide\">미끄러지 다</string>\n    <string name=\"side_by_side\">나란히</string>\n    <string name=\"transparency\">투명도</string>\n    <string name=\"favorite\">가장 좋아하는</string>\n    <string name=\"no_favorite_filters\">아직 즐겨찾기 필터가 추가되지 않았습니다.</string>\n    <string name=\"b_spline\">B 스플라인</string>\n    <string name=\"native_stack_blur\">네이티브 스택 블러</string>\n    <string name=\"blur_edges\">가장자리를 흐리게 처리</string>\n    <string name=\"blur_edges_sub\">활성화된 경우 단일 색상 대신 원본 이미지 아래에 흐린 가장자리를 그려 주변 공간을 채웁니다.</string>\n    <string name=\"regular\">정기적인</string>\n    <string name=\"pixelation\">픽셀화</string>\n    <string name=\"inverse_fill_type\">역 채우기 유형</string>\n    <string name=\"inverse_fill_type_sub\">활성화하면 마스크되지 않은 모든 영역이 기본 동작 대신 필터링됩니다.</string>\n    <string name=\"palette_style\">팔레트 스타일</string>\n    <string name=\"expressive\">나타내는</string>\n    <string name=\"rainbow\">무지개</string>\n    <string name=\"highlighter_sub\">반투명의 날카로운 형광펜 경로 그리기</string>\n    <string name=\"containers_shadow\">컨테이너</string>\n    <string name=\"containers_shadow_sub\">컨테이너 뒤에 그림자 그리기를 활성화합니다.</string>\n    <string name=\"sliders_shadow\">슬라이더</string>\n    <string name=\"switches_shadow\">스위치</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">버튼</string>\n    <string name=\"app_bars_shadow\">앱바</string>\n    <string name=\"foss_update_checker_warning\">이 업데이트 검사기는 사용 가능한 새 업데이트가 있는지 확인하기 위해 GitHub에 연결됩니다.</string>\n    <string name=\"attention\">주목</string>\n    <string name=\"fading_edges\">페이딩 엣지</string>\n    <string name=\"disabled\">장애가 있는</string>\n    <string name=\"invert_colors\">색상 반전</string>\n    <string name=\"exit\">출구</string>\n    <string name=\"preview_closing\">지금 미리보기를 종료하면 이미지를 다시 추가해야 합니다.</string>\n    <string name=\"image_format\">이미지 형식</string>\n    <string name=\"material_you_sub\">이미지에서\\\"Material You \\\"팔레트를 만듭니다</string>\n    <string name=\"dark_colors\">어두운 색상</string>\n    <string name=\"dark_colors_sub\">라이트 변형 대신 야간 모드 색 구성표 사용</string>\n    <string name=\"copy_as_compose_code\">\\\"Jetpack Compose\\\"코드로 복사</string>\n    <string name=\"ring_blur\">링 블러</string>\n    <string name=\"cross_blur\">크로스 블러</string>\n    <string name=\"circle_blur\">원 흐림</string>\n    <string name=\"star_blur\">스타 블러</string>\n    <string name=\"linear_tilt_shift\">선형 경사 교대</string>\n    <string name=\"tags_to_remove\">제거할 태그</string>\n    <string name=\"apng_type_to_apng\">이미지를 APNG로</string>\n    <string name=\"apng_type_to_image_sub\">APNG 파일을 사진 배치로 변환</string>\n    <string name=\"apng_type_to_apng_sub\">배치 이미지를 APNG 파일로 변환</string>\n    <string name=\"apng_tools\">APNG 도구</string>\n    <string name=\"apng_tools_sub\">이미지를 APNG 그림으로 변환하거나 주어진 APNG 이미지에서 프레임을 추출합니다</string>\n    <string name=\"apng_type_to_image\">APNG를 이미지로</string>\n    <string name=\"select_apng_image_to_start\">시작하려면 APNG 이미지를 선택하세요</string>\n    <string name=\"motion_blur\">모션 블러</string>\n    <string name=\"zip\">지퍼</string>\n    <string name=\"zip_sub\">주어진 파일이나 이미지로 Zip 파일 만들기</string>\n    <string name=\"drag_handle_width\">드래그 핸들 너비</string>\n    <string name=\"confetti_type\">색종이 종류</string>\n    <string name=\"festive\">축제</string>\n    <string name=\"explode\">폭발</string>\n    <string name=\"rain\">비</string>\n    <string name=\"corners\">모서리</string>\n    <string name=\"jxl_tools\">JXL 도구</string>\n    <string name=\"jxl_tools_sub\">품질 손실 없이 JXL ~ JPEG 트랜스코딩을 수행하거나 GIF/APNG를 JXL 애니메이션으로 변환합니다.</string>\n    <string name=\"jxl_type_to_jpeg\">JXL 에서 JPEG로</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL에서 JPEG로 무손실 트랜스코딩을 수행합니다.</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG에서 JXL로 무손실 트랜스코딩을 수행합니다.</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG에서 JXL로</string>\n    <string name=\"select_jxl_image_to_start\">JXL 이미지를 선택하여 시작하세요.</string>\n    <string name=\"fast_gaussian_blur_2d\">빠른 정규분포 블러 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">빠른 정규분포 블러 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">빠른 정규분포 블러 4D</string>\n    <string name=\"auto_paste\">자동 붙여넣기</string>\n    <string name=\"auto_paste_sub\">앱이 클립보드 데이터를 자동으로 붙여넣을 수 있도록 허용하여 메인 화면에 표시되고 처리할 수 있습니다.</string>\n    <string name=\"harmonization_color\">색상 조화</string>\n    <string name=\"harmonization_level\">레벨 조화</string>\n    <string name=\"lanczos_bessel\">란코스 베셀</string>\n    <string name=\"lanczos_bessel_sub\">픽셀 값에 베셀(jinc) 함수를 적용하여 고품질 보간을 유지하는 리샘플링 방법</string>\n    <string name=\"gif_type_to_jxl\">GIF에서 JXL로</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF 이미지를 JXL 애니메이션 사진으로 변환합니다.</string>\n    <string name=\"apng_type_to_jxl\">APNG에서 JXL로</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG 이미지를 JXL 애니메이션 사진으로 변환합니다.</string>\n    <string name=\"jxl_type_to_images\">JXL에서 사진으로</string>\n    <string name=\"jxl_type_to_images_sub\">JXL 애니메이션을 사진 배치로 변환합니다.</string>\n    <string name=\"jxl_type_to_jxl\">사진에서 JXL으로</string>\n    <string name=\"jxl_type_to_jxl_sub\">사진 배치를 JXL 애니메이션으로 변환합니다.</string>\n    <string name=\"behavior\">행동</string>\n    <string name=\"skip_file_picking\">파일 선택 건너뛰기</string>\n    <string name=\"skip_file_picking_sub\">선택한 화면에서 가능한 경우 파일 선택기가 즉시 표시됩니다.</string>\n    <string name=\"generate_previews\">미리보기 생성</string>\n    <string name=\"generate_previews_sub\">미리보기 생성을 활성화하면 일부 장치에서 충돌을 방지하는 데 도움이 될 수 있으며, 단일 편집 옵션 내에서 일부 편집 기능을 비활성화할 수도 있습니다.</string>\n    <string name=\"lossy_compression\">손실 압축</string>\n    <string name=\"lossy_compression_sub\">무손실 압축을 사용하여 무손실 대신 파일 크기를 줄입니다.</string>\n    <string name=\"compression_type\">압축 타입</string>\n    <string name=\"speed_sub\">결과 이미지 디코딩 속도를 제어하여 결과 이미지를 더 빠르게 열 수 있으며, %1$s 값은 가장 느린 디코딩을 의미하고 %2$s는 가장 빠른 디코딩을 의미하며, 이 설정은 출력 이미지 크기를 증가시킬 수 있습니다.</string>\n    <string name=\"sorting\">분류</string>\n    <string name=\"sort_by_date\">날짜</string>\n    <string name=\"sort_by_date_reversed\">날짜 (역순)</string>\n    <string name=\"sort_by_name\">이름</string>\n    <string name=\"sort_by_name_reversed\">이름 (역순)</string>\n    <string name=\"channels_configuration\">채널 구성</string>\n    <string name=\"header_today\">오늘</string>\n    <string name=\"header_yesterday\">어제</string>\n    <string name=\"embedded_picker\">내장 선택기</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox의 이미지 선택기</string>\n    <string name=\"no_permissions\">권한이 없습니다</string>\n    <string name=\"request\">요청</string>\n    <string name=\"pick_multiple_media\">여러 미디어 선택</string>\n    <string name=\"pick_single_media\">미디어 하나 선택</string>\n    <string name=\"pick\">선택</string>\n    <string name=\"try_again\">다시 시도하기</string>\n    <string name=\"show_settings_in_landscape\">가로에서 설정 표시</string>\n    <string name=\"show_settings_in_landscape_sub\">이 설정을 비활성화하면 가로 모드 설정은 영구적으로 표시되는 옵션 대신 항상 앱 상단 표시줄의 버튼에서 열립니다.</string>\n    <string name=\"fullscreen_settings\">전체화면 설정</string>\n    <string name=\"fullscreen_settings_sub\">이 기능을 활성화하면 설정 페이지가 슬라이드 가능한 서랍 시트 대신 항상 전체 화면으로 열립니다.</string>\n    <string name=\"switch_type\">스위치 타입</string>\n    <string name=\"compose\">구성</string>\n    <string name=\"compose_switch_sub\">제트팩 구성 재료를 교체하세요.</string>\n    <string name=\"material_you_switch_sub\">A 머티리얼 전환</string>\n    <string name=\"max\">맥스</string>\n    <string name=\"resize_anchor\">앵커 크기 조정</string>\n    <string name=\"pixel_switch\">픽셀</string>\n    <string name=\"fluent_switch\">유창한</string>\n    <string name=\"fluent_switch_sub\">\\\"Fluent\\\" 디자인 시스템을 기반으로 한 스위치</string>\n    <string name=\"cupertino_switch\">쿠퍼티노</string>\n    <string name=\"cupertino_switch_sub\">\\\"Cupertino\\\" 디자인 시스템을 기반으로 한 스위치</string>\n    <string name=\"images_to_svg\">이미지를 SVG로</string>\n    <string name=\"images_to_svg_sub\">주어진 이미지를 SVG 이미지로 추적</string>\n    <string name=\"use_sampled_palette\">샘플링된 팔레트 사용</string>\n    <string name=\"use_sampled_palette_sub\">이 옵션을 활성화하면 양자화 팔레트가 샘플링됩니다.</string>\n    <string name=\"path_omit\">경로 생략</string>\n    <string name=\"svg_warning\">축소 없이 큰 이미지를 추적하기 위해 이 도구를 사용하는 것은 권장되지 않습니다. 충돌이 발생하고 처리 시간이 늘어날 수 있습니다.</string>\n    <string name=\"downscale_image\">이미지 축소</string>\n    <string name=\"downscale_image_sub\">처리하기 전에 이미지 크기가 더 낮은 크기로 축소됩니다. 이는 도구가 더 빠르고 안전하게 작동하는 데 도움이 됩니다.</string>\n    <string name=\"min_color_ratio\">최소 색상 비율</string>\n    <string name=\"lines_threshold\">라인 임계값</string>\n    <string name=\"quadratic_threshold\">2차 임계값</string>\n    <string name=\"coordinates_rounding_tolerance\">좌표 반올림 공차</string>\n    <string name=\"path_scale\">경로 규모</string>\n    <string name=\"reset_properties\">속성 재설정</string>\n    <string name=\"reset_properties_sub\">모든 속성이 기본값으로 설정됩니다. 이 작업은 취소할 수 없습니다.</string>\n    <string name=\"detailed\">상세한</string>\n    <string name=\"default_line_width\">기본 줄 너비</string>\n    <string name=\"engine_mode\">엔진 모드</string>\n    <string name=\"legacy\">유산</string>\n    <string name=\"lstm_network\">LSTM 네트워크</string>\n    <string name=\"legacy_and_lstm\">레거시 및 LSTM</string>\n    <string name=\"convert\">전환하다</string>\n    <string name=\"convert_sub\">이미지 배치를 지정된 형식으로 변환</string>\n    <string name=\"add_new_folder\">새 폴더 추가</string>\n    <string name=\"tag_bits_per_sample\">샘플당 비트</string>\n    <string name=\"tag_compression\">압축</string>\n    <string name=\"tag_photometric_interpretation\">광도 해석</string>\n    <string name=\"tag_samples_per_pixel\">픽셀당 샘플</string>\n    <string name=\"tag_planar_configuration\">평면 구성</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr 하위 샘플링</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr 포지셔닝</string>\n    <string name=\"tag_x_resolution\">X 해상도</string>\n    <string name=\"tag_y_resolution\">Y 해상도</string>\n    <string name=\"tag_resolution_unit\">분해능 단위</string>\n    <string name=\"tag_strip_offsets\">스트립 오프셋</string>\n    <string name=\"tag_rows_per_strip\">스트립당 행</string>\n    <string name=\"tag_strip_byte_counts\">스트립 바이트 수</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG 교환 형식</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG 교환 형식 길이</string>\n    <string name=\"tag_transfer_function\">전달 함수</string>\n    <string name=\"tag_white_point\">화이트 포인트</string>\n    <string name=\"tag_primary_chromaticities\">기본 색도</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr 계수</string>\n    <string name=\"tag_reference_black_white\">참조 블랙 화이트</string>\n    <string name=\"tag_datetime\">날짜 시간</string>\n    <string name=\"tag_image_description\">이미지 설명</string>\n    <string name=\"tag_make\">만들다</string>\n    <string name=\"tag_model\">모델</string>\n    <string name=\"tag_software\">소프트웨어</string>\n    <string name=\"tag_artist\">아티스트</string>\n    <string name=\"tag_copyright\">저작권</string>\n    <string name=\"tag_exif_version\">Exif 버전</string>\n    <string name=\"tag_flashpix_version\">플래시픽스 버전</string>\n    <string name=\"tag_color_space\">색 공간</string>\n    <string name=\"tag_gamma\">감마</string>\n    <string name=\"tag_pixel_x_dimension\">픽셀 X 차원</string>\n    <string name=\"tag_pixel_y_dimension\">픽셀 Y 차원</string>\n    <string name=\"tag_compressed_bits_per_pixel\">픽셀당 압축된 비트</string>\n    <string name=\"tag_maker_note\">메이커노트</string>\n    <string name=\"tag_user_comment\">사용자 코멘트</string>\n    <string name=\"tag_related_sound_file\">관련 사운드 파일</string>\n    <string name=\"tag_datetime_original\">날짜 시간 원본</string>\n    <string name=\"tag_datetime_digitized\">디지털화된 날짜 시간</string>\n    <string name=\"tag_offset_time\">오프셋 시간</string>\n    <string name=\"tag_offset_time_original\">오프셋 시간 원본</string>\n    <string name=\"tag_offset_time_digitized\">오프셋 시간이 디지털화됨</string>\n    <string name=\"tag_subsec_time\">하위 초 시간</string>\n    <string name=\"tag_subsec_time_original\">하위 초 시간 원본</string>\n    <string name=\"tag_subsec_time_digitized\">1초 미만의 시간이 디지털화됨</string>\n    <string name=\"tag_exposure_time\">노출 시간</string>\n    <string name=\"tag_f_number\">F 번호</string>\n    <string name=\"tag_exposure_program\">노출 프로그램</string>\n    <string name=\"tag_spectral_sensitivity\">스펙트럼 감도</string>\n    <string name=\"tag_photographic_sensitivity\">사진 감도</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">감도 유형</string>\n    <string name=\"tag_standard_output_sensitivity\">표준 출력 감도</string>\n    <string name=\"tag_recommended_exposure_index\">권장 노출 지수</string>\n    <string name=\"tag_iso_speed\">ISO 속도</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO 속도 위도 yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO 속도 위도 zzz</string>\n    <string name=\"tag_shutter_speed_value\">셔터 속도 값</string>\n    <string name=\"tag_aperture_value\">조리개 값</string>\n    <string name=\"tag_brightness_value\">밝기 값</string>\n    <string name=\"tag_exposure_bias_value\">노출 바이어스 값</string>\n    <string name=\"tag_max_aperture_value\">최대 조리개 값</string>\n    <string name=\"tag_subject_distance\">피사체 거리</string>\n    <string name=\"tag_metering_mode\">측광 모드</string>\n    <string name=\"tag_flash\">플래시</string>\n    <string name=\"tag_subject_area\">주제 영역</string>\n    <string name=\"tag_focal_length\">초점 거리</string>\n    <string name=\"tag_flash_energy\">플래시 에너지</string>\n    <string name=\"tag_spatial_frequency_response\">공간 주파수 응답</string>\n    <string name=\"tag_focal_plane_x_resolution\">초점면 X 해상도</string>\n    <string name=\"tag_focal_plane_y_resolution\">초점면 Y 해상도</string>\n    <string name=\"tag_focal_plane_resolution_unit\">초점면 해상도 단위</string>\n    <string name=\"tag_subject_location\">주제 위치</string>\n    <string name=\"tag_exposure_index\">노출지수</string>\n    <string name=\"tag_sensing_method\">감지방식</string>\n    <string name=\"tag_file_source\">파일 소스</string>\n    <string name=\"tag_cfa_pattern\">CFA 패턴</string>\n    <string name=\"tag_custom_rendered\">맞춤 렌더링됨</string>\n    <string name=\"tag_exposure_mode\">노출 모드</string>\n    <string name=\"tag_white_balance\">화이트 밸런스</string>\n    <string name=\"tag_digital_zoom_ratio\">디지털 줌 비율</string>\n    <string name=\"tag_focal_length_in_35mm_film\">초점 거리 In35mm 필름</string>\n    <string name=\"tag_scene_capture_type\">장면 캡처 유형</string>\n    <string name=\"tag_gain_control\">이득 제어</string>\n    <string name=\"tag_contrast\">차이</string>\n    <string name=\"tag_saturation\">포화</string>\n    <string name=\"tag_sharpness\">날카로움</string>\n    <string name=\"tag_device_setting_description\">장치 설정 설명</string>\n    <string name=\"tag_subject_distance_range\">피사체 거리 범위</string>\n    <string name=\"tag_image_unique_id\">이미지 고유 ID</string>\n    <string name=\"tag_camera_owner_name\">카메라 소유자 이름</string>\n    <string name=\"tag_body_serial_number\">본체 일련번호</string>\n    <string name=\"tag_lens_specification\">렌즈 사양</string>\n    <string name=\"tag_lens_make\">렌즈 제조사</string>\n    <string name=\"tag_lens_model\">렌즈 모델</string>\n    <string name=\"tag_lens_serial_number\">렌즈 일련번호</string>\n    <string name=\"tag_gps_version_id\">GPS 버전 ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS 위도 참조</string>\n    <string name=\"tag_gps_latitude\">GPS 위도</string>\n    <string name=\"tag_gps_longitude_ref\">GPS 경도 참조</string>\n    <string name=\"tag_gps_longitude\">GPS 경도</string>\n    <string name=\"tag_gps_altitude_ref\">GPS 고도 참조</string>\n    <string name=\"tag_gps_altitude\">GPS 고도</string>\n    <string name=\"tag_gps_timestamp\">GPS 타임 스탬프</string>\n    <string name=\"tag_gps_satellites\">GPS 위성</string>\n    <string name=\"tag_gps_status\">GPS 상태</string>\n    <string name=\"tag_gps_measure_mode\">GPS 측정 모드</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS 속도 참조</string>\n    <string name=\"tag_gps_speed\">GPS 속도</string>\n    <string name=\"tag_gps_track_ref\">GPS 트랙 참조</string>\n    <string name=\"tag_gps_track\">GPS 트랙</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS 이미지 방향 참조</string>\n    <string name=\"tag_gps_img_direction\">GPS 이미지 방향</string>\n    <string name=\"tag_gps_map_datum\">GPS 지도 데이텀</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS 목적지 위도 참조</string>\n    <string name=\"tag_gps_dest_latitude\">GPS 목적지 위도</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS 목적지 경도 참조</string>\n    <string name=\"tag_gps_dest_longitude\">GPS 목적지 경도</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS 목적지 베어링 참조</string>\n    <string name=\"tag_gps_dest_bearing\">GPS 대상 베어링</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS 목적지 거리 참조</string>\n    <string name=\"tag_gps_dest_distance\">GPS 목적지 거리</string>\n    <string name=\"tag_gps_processing_method\">GPS 처리 방식</string>\n    <string name=\"tag_gps_area_information\">GPS 지역 정보</string>\n    <string name=\"tag_gps_datestamp\">GPS 날짜 스탬프</string>\n    <string name=\"tag_gps_differential\">GPS 차동</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H 포지셔닝 오류</string>\n    <string name=\"tag_interoperability_index\">상호 운용성 지수</string>\n    <string name=\"tag_dng_version\">DNG 버전</string>\n    <string name=\"tag_default_crop_size\">기본 자르기 크기</string>\n    <string name=\"tag_orf_preview_image_start\">미리보기 이미지 시작</string>\n    <string name=\"tag_orf_preview_image_length\">미리보기 이미지 길이</string>\n    <string name=\"tag_orf_aspect_frame\">화면 프레임</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">센서 하단 테두리</string>\n    <string name=\"tag_rw2_sensor_left_border\">센서 왼쪽 테두리</string>\n    <string name=\"tag_rw2_sensor_right_border\">센서 오른쪽 테두리</string>\n    <string name=\"tag_rw2_sensor_top_border\">센서 상단 테두리</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">주어진 글꼴과 색상으로 경로에 텍스트 그리기</string>\n    <string name=\"font_size\">글꼴 크기</string>\n    <string name=\"watermark_size\">워터마크 크기</string>\n    <string name=\"repeat_text\">텍스트 반복</string>\n    <string name=\"repeat_text_sub\">한 번만 그리는 대신 경로 끝까지 현재 텍스트가 반복됩니다.</string>\n    <string name=\"dash_size\">대시 크기</string>\n    <string name=\"draw_mode_image_sub\">선택한 이미지를 사용하여 주어진 경로를 따라 그립니다.</string>\n    <string name=\"draw_image_sub\">이 이미지는 그려진 경로의 반복 항목으로 사용됩니다.</string>\n    <string name=\"outlined_triangle_sub\">시작점에서 끝점까지 윤곽선이 있는 삼각형을 그립니다.</string>\n    <string name=\"triangle_sub\">시작점에서 끝점까지 윤곽선이 있는 삼각형을 그립니다.</string>\n    <string name=\"outlined_triangle\">윤곽이 있는 삼각형</string>\n    <string name=\"triangle\">삼각형</string>\n    <string name=\"polygon_sub\">시작점에서 끝점까지 다각형을 그립니다.</string>\n    <string name=\"polygon\">다각형</string>\n    <string name=\"outlined_polygon\">윤곽이 있는 다각형</string>\n    <string name=\"outlined_polygon_sub\">시작점에서 끝점까지 윤곽이 있는 다각형을 그립니다.</string>\n    <string name=\"vertices\">정점</string>\n    <string name=\"draw_regular_polygon\">정다각형 그리기</string>\n    <string name=\"draw_regular_polygon_sub\">자유 형식이 아닌 규칙적인 다각형을 그립니다.</string>\n    <string name=\"star_sub\">시작점부터 끝점까지 별을 그립니다.</string>\n    <string name=\"star\">별</string>\n    <string name=\"outlined_star\">윤곽선 별</string>\n    <string name=\"outlined_star_sub\">시작점에서 끝점까지 윤곽선 별을 그립니다.</string>\n    <string name=\"inner_radius_ratio\">내부 반경 비율</string>\n    <string name=\"draw_regular_star\">일반 별 그리기</string>\n    <string name=\"draw_regular_star_sub\">자유형이 아닌 규칙적인 별을 그려보세요</string>\n    <string name=\"antialias\">앤티앨리어스</string>\n    <string name=\"antialias_sub\">날카로운 모서리를 방지하기 위해 앤티앨리어싱을 활성화합니다.</string>\n    <string name=\"open_edit_instead_of_preview\">미리보기 대신 편집 열기</string>\n    <string name=\"open_edit_instead_of_preview_sub\">ImageToolbox에서 열려는(미리보기) 이미지를 선택하면 미리보기 대신 편집 선택 시트가 열립니다.</string>\n    <string name=\"document_scanner\">문서 스캐너</string>\n    <string name=\"document_scanner_sub\">문서를 스캔하고 PDF를 생성하거나 문서에서 이미지를 분리하세요</string>\n    <string name=\"click_to_start_scanning\">스캔을 시작하려면 클릭하세요</string>\n    <string name=\"start_scanning\">스캔 시작</string>\n    <string name=\"save_as_pdf\">PDF로 저장</string>\n    <string name=\"share_as_pdf\">PDF로 공유</string>\n    <string name=\"options_below_is_for_images\">아래 옵션은 PDF가 아닌 이미지 저장을 위한 것입니다.</string>\n    <string name=\"equalize_histogram_hsv\">히스토그램 HSV 균등화</string>\n    <string name=\"equalize_histogram\">히스토그램 균등화</string>\n    <string name=\"enter_percentage\">백분율 입력</string>\n    <string name=\"allow_enter_by_text_field\">텍스트 필드로 입력 허용</string>\n    <string name=\"allow_enter_by_text_field_sub\">사전 설정 선택 뒤에 텍스트 필드를 활성화하여 즉시 입력할 수 있습니다.</string>\n    <string name=\"scale_color_space\">스케일 색 공간</string>\n    <string name=\"linear\">선의</string>\n    <string name=\"equalize_histogram_pixelation\">히스토그램 픽셀화 균등화</string>\n    <string name=\"grid_size_x\">그리드 크기 X</string>\n    <string name=\"grid_size_y\">그리드 크기 Y</string>\n    <string name=\"equalize_histogram_adaptive\">히스토그램 적응형 균등화</string>\n    <string name=\"equalize_histogram_adaptive_luv\">히스토그램 적응형 LUV 균등화</string>\n    <string name=\"equalize_histogram_adaptive_lab\">히스토그램 적응형 LAB 균등화</string>\n    <string name=\"clahe\">클라헤</string>\n    <string name=\"clahe_lab\">클라헤 연구소</string>\n    <string name=\"clahe_luv\">클라헤 루브</string>\n    <string name=\"crop_to_content\">내용에 맞춰 자르기</string>\n    <string name=\"frame_color\">프레임 색상</string>\n    <string name=\"color_to_ignore\">무시할 색상</string>\n    <string name=\"template\">주형</string>\n    <string name=\"no_template_filters\">추가된 템플릿 필터가 없습니다.</string>\n    <string name=\"create_new\">새로 만들기</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">스캔한 QR 코드는 유효한 필터 템플릿이 아닙니다.</string>\n    <string name=\"scan_qr_code\">QR 코드 스캔</string>\n    <string name=\"opened_file_have_no_filter_template\">선택한 파일에는 필터 템플릿 데이터가 없습니다.</string>\n    <string name=\"create_template\">템플릿 생성</string>\n    <string name=\"template_name\">템플릿 이름</string>\n    <string name=\"select_template_preview\">이 이미지는 이 필터 템플릿을 미리 보는 데 사용됩니다.</string>\n    <string name=\"template_filter\">템플릿 필터</string>\n    <string name=\"as_qr_code\">QR코드 이미지로</string>\n    <string name=\"as_file\">파일로</string>\n    <string name=\"save_as_file\">파일로 저장</string>\n    <string name=\"save_as_qr_code_image\">QR 코드 이미지로 저장</string>\n    <string name=\"delete_template\">템플릿 삭제</string>\n    <string name=\"delete_template_warn\">선택한 템플릿 필터를 삭제하려고 합니다. 이 작업은 취소할 수 없습니다.</string>\n    <string name=\"added_filter_template\">이름이 \\\"%1$s\\\"(%2$s)인 필터 템플릿이 추가되었습니다.</string>\n    <string name=\"filter_preview\">필터 미리보기</string>\n    <string name=\"qr_code\">QR 및 바코드</string>\n    <string name=\"qr_code_sub\">QR 코드를 스캔하여 내용을 가져오거나 문자열을 붙여넣어 새 내용을 생성하세요.</string>\n    <string name=\"code_content\">코드 내용</string>\n    <string name=\"scan_qr_code_to_replace_content\">바코드를 스캔하여 필드의 콘텐츠를 바꾸거나 무언가를 입력하여 선택한 유형의 새 바코드를 생성하세요.</string>\n    <string name=\"qr_description\">QR 설명</string>\n    <string name=\"min\">최소</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR 코드를 스캔하려면 설정에서 카메라 권한을 부여하세요.</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">문서 스캐너를 스캔하려면 설정에서 카메라 권한을 부여하세요.</string>\n    <string name=\"cubic\">큐빅</string>\n    <string name=\"bspline\">B-스플라인</string>\n    <string name=\"hamming\">해밍</string>\n    <string name=\"hanning\">해닝</string>\n    <string name=\"blackman\">블랙맨</string>\n    <string name=\"welch\">웨일스 말</string>\n    <string name=\"quadric\">2차</string>\n    <string name=\"gaussian\">가우스</string>\n    <string name=\"sphinx\">스핑크스</string>\n    <string name=\"bartlett\">바틀렛</string>\n    <string name=\"robidoux\">로비두</string>\n    <string name=\"robidoux_sharp\">로비두 샤프</string>\n    <string name=\"spline16\">스플라인 16</string>\n    <string name=\"spline36\">스플라인 36</string>\n    <string name=\"spline64\">스플라인 64</string>\n    <string name=\"kaiser\">황제</string>\n    <string name=\"bartlett_hann\">바틀렛-헤</string>\n    <string name=\"box\">상자</string>\n    <string name=\"bohman\">보만</string>\n    <string name=\"lanczos2\">란초스 2</string>\n    <string name=\"lanczos3\">란초스 3</string>\n    <string name=\"lanczos4\">란초스 4</string>\n    <string name=\"lanczos2_jinc\">란초스 2 징크</string>\n    <string name=\"lanczos3_jinc\">란초스 3 징크</string>\n    <string name=\"lanczos4_jinc\">란초스 4 징크</string>\n    <string name=\"cubic_sub\">큐빅 보간은 가장 가까운 16픽셀을 고려하여 더 부드러운 스케일링을 제공하여 바이리니어 보간보다 더 나은 결과를 제공합니다.</string>\n    <string name=\"bspline_sub\">조각별로 정의된 다항식 함수를 활용하여 곡선이나 표면을 부드럽게 보간하고 근사화하며 유연하고 연속적인 모양 표현을 제공합니다.</string>\n    <string name=\"hamming_sub\">신호 처리에 유용한 신호 가장자리를 테이퍼링하여 스펙트럼 누출을 줄이는 데 사용되는 창 기능</string>\n    <string name=\"hanning_sub\">신호 처리 응용 분야에서 스펙트럼 누출을 줄이기 위해 일반적으로 사용되는 Hann 창의 변형입니다.</string>\n    <string name=\"blackman_sub\">신호 처리에 자주 사용되는 스펙트럼 누출을 최소화하여 우수한 주파수 분해능을 제공하는 윈도우 함수</string>\n    <string name=\"welch_sub\">신호 처리 응용 분야에서 자주 사용되는 스펙트럼 누출을 줄이면서 우수한 주파수 분해능을 제공하도록 설계된 창 기능</string>\n    <string name=\"quadric_sub\">보간을 위해 2차 함수를 사용하는 방법으로 부드럽고 연속적인 결과를 제공합니다.</string>\n    <string name=\"gaussian_sub\">이미지의 노이즈를 부드럽게 하고 줄이는 데 유용한 가우스 함수를 적용하는 보간 방법</string>\n    <string name=\"sphinx_sub\">아티팩트를 최소화하면서 고품질 보간을 제공하는 고급 리샘플링 방법</string>\n    <string name=\"bartlett_sub\">스펙트럼 누출을 줄이기 위해 신호 처리에 사용되는 삼각형 창 기능</string>\n    <string name=\"robidoux_sub\">자연스러운 이미지 크기 조정, 선명도와 부드러움의 균형을 맞추는 데 최적화된 고품질 보간 방법</string>\n    <string name=\"robidoux_sharp_sub\">선명한 이미지 크기 조정에 최적화된 Robidoux 방법의 보다 선명한 변형</string>\n    <string name=\"spline16_sub\">16탭 필터를 사용하여 부드러운 결과를 제공하는 스플라인 기반 보간 방법</string>\n    <string name=\"spline36_sub\">36탭 필터를 사용하여 부드러운 결과를 제공하는 스플라인 기반 보간법</string>\n    <string name=\"spline64_sub\">64탭 필터를 사용하여 부드러운 결과를 제공하는 스플라인 기반 보간 방법</string>\n    <string name=\"kaiser_sub\">카이저 창을 사용하는 보간 방법으로 메인 로브 너비와 사이드 로브 수준 간의 균형을 효과적으로 제어할 수 있습니다.</string>\n    <string name=\"bartlett_hann_sub\">신호 처리에서 스펙트럼 누출을 줄이는 데 사용되는 Bartlett 창과 Hann 창을 결합한 하이브리드 창 기능</string>\n    <string name=\"box_sub\">가장 가까운 픽셀 값의 평균을 사용하는 간단한 리샘플링 방법으로 종종 덩어리진 모양이 발생합니다.</string>\n    <string name=\"bohman_sub\">스펙트럼 누출을 줄이는 데 사용되는 창 기능으로 신호 처리 응용 분야에서 우수한 주파수 분해능을 제공합니다.</string>\n    <string name=\"lanczos2_sub\">아티팩트를 최소화한 고품질 보간을 위해 2-엽 Lanczos 필터를 사용하는 리샘플링 방법</string>\n    <string name=\"lanczos3_sub\">아티팩트를 최소화한 고품질 보간을 위해 3-엽 Lanczos 필터를 사용하는 리샘플링 방법</string>\n    <string name=\"lanczos4_sub\">아티팩트를 최소화한 고품질 보간을 위해 4-엽 Lanczos 필터를 사용하는 리샘플링 방법</string>\n    <string name=\"lanczos2_jinc_sub\">jinc 함수를 사용하여 아티팩트를 최소화하면서 고품질 보간을 제공하는 Lanczos 2 필터의 변형입니다.</string>\n    <string name=\"lanczos3_jinc_sub\">jinc 기능을 사용하여 아티팩트를 최소화하면서 고품질 보간을 제공하는 Lanczos 3 필터의 변형입니다.</string>\n    <string name=\"lanczos4_jinc_sub\">jinc 기능을 사용하여 아티팩트를 최소화하면서 고품질 보간을 제공하는 Lanczos 4 필터의 변형입니다.</string>\n    <string name=\"ewa_hanning\">해닝 EWA</string>\n    <string name=\"ewa_hanning_sub\">원활한 보간 및 리샘플링을 위한 해닝 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_robidoux\">로비두 EWA</string>\n    <string name=\"ewa_robidoux_sub\">고품질 리샘플링을 위한 Robidoux 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_blackman\">블랙맨 이브</string>\n    <string name=\"ewa_blackman_sub\">링잉 아티팩트를 최소화하기 위한 Blackman 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_quadric\">2차 EWA</string>\n    <string name=\"ewa_quadric_sub\">원활한 보간을 위한 Quadric 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_robidoux_sharp\">로비두 샤프 EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">보다 선명한 결과를 위한 Robidoux Sharp 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 진크 EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">감소된 앨리어싱으로 고품질 리샘플링을 위한 Lanczos 3 Jinc 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ginseng\">인삼</string>\n    <string name=\"ginseng_sub\">선명도와 부드러움의 균형이 잘 잡힌 고품질 이미지 처리를 위해 설계된 리샘플링 필터</string>\n    <string name=\"ewa_ginseng\">인삼 EWA</string>\n    <string name=\"ewa_ginseng_sub\">향상된 이미지 품질을 위한 Ginseng 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_lanczos_sharp\">란초스 샤프 EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">아티팩트를 최소화하면서 선명한 결과를 얻기 위한 Lanczos Sharp 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 샤프스트 EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">매우 선명한 이미지 리샘플링을 위한 Lanczos 4 Sharpest 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"ewa_lanczos_soft\">란초스 소프트 EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">더욱 부드러운 이미지 리샘플링을 위한 Lanczos Soft 필터의 EWA(Elliptical Weighted Average) 변형</string>\n    <string name=\"haasn_soft\">하슨소프트</string>\n    <string name=\"haasn_soft_sub\">부드럽고 아티팩트 없는 이미지 스케일링을 위해 Haasn이 설계한 리샘플링 필터</string>\n    <string name=\"format_conversion\">형식 변환</string>\n    <string name=\"format_conversion_sub\">이미지 배치를 한 형식에서 다른 형식으로 변환</string>\n    <string name=\"dismiss_forever\">영원히 해고하다</string>\n    <string name=\"image_stacking\">이미지 스태킹</string>\n    <string name=\"image_stacking_sub\">선택한 블렌드 모드를 사용하여 이미지를 서로 쌓습니다.</string>\n    <string name=\"add_image\">이미지 추가</string>\n    <string name=\"bins_count\">빈 개수</string>\n    <string name=\"clahe_hsl\">클라헤 HSL</string>\n    <string name=\"clahe_hsv\">클라헤 HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">히스토그램 적응형 HSL 균등화</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">히스토그램 적응형 HSV 균등화</string>\n    <string name=\"edge_mode\">엣지 모드</string>\n    <string name=\"clip\">클립</string>\n    <string name=\"wrap\">포장하다</string>\n    <string name=\"color_blind_scheme\">색맹</string>\n    <string name=\"color_blind_scheme_sub\">선택한 색맹 변형에 테마 색상을 적용하려면 모드를 선택하세요.</string>\n    <string name=\"protanomaly_sub\">빨간색과 녹색 색상을 구별하기가 어렵습니다.</string>\n    <string name=\"deuteranomaly_sub\">녹색과 빨간색 색상을 구별하기가 어렵습니다.</string>\n    <string name=\"tritanomaly_sub\">파란색과 노란색 색상을 구별하기가 어렵습니다.</string>\n    <string name=\"protanopia_sub\">붉은색을 인식할 수 없음</string>\n    <string name=\"deuteranopia_sub\">녹색 색상을 인식할 수 없음</string>\n    <string name=\"tritanopia_sub\">푸른 색조를 인식할 수 없음</string>\n    <string name=\"achromatomaly_sub\">모든 색상에 대한 민감도 감소</string>\n    <string name=\"achromatopsia_sub\">완전한 색맹, 회색 음영만 보는 색맹</string>\n    <string name=\"not_use_color_blind_scheme\">색맹 구성표를 사용하지 마십시오</string>\n    <string name=\"not_use_color_blind_scheme_sub\">색상은 테마에 설정된 대로 정확하게 적용됩니다.</string>\n    <string name=\"sigmoidal\">S자형</string>\n    <string name=\"lagrange_2\">라그랑주 2</string>\n    <string name=\"lagrange_2_sub\">부드러운 전환이 가능한 고품질 이미지 스케일링에 적합한 2차 라그랑주 보간 필터</string>\n    <string name=\"lagrange_3\">라그랑주 3</string>\n    <string name=\"lagrange_3_sub\">이미지 스케일링에 대해 더 나은 정확도와 더 부드러운 결과를 제공하는 3차 라그랑주 보간 필터</string>\n    <string name=\"lanczos_6\">란초스 6</string>\n    <string name=\"lanczos_6_sub\">더 선명하고 정확한 이미지 스케일링을 제공하는 더 높은 차수 6의 Lanczos 리샘플링 필터</string>\n    <string name=\"lanczos_6_jinc\">란초스 6 징크</string>\n    <string name=\"lanczos_6_jinc_sub\">향상된 이미지 리샘플링 품질을 위해 Jinc 기능을 사용하는 Lanczos 6 필터의 변형</string>\n    <string name=\"linear_box_blur\">선형 상자 흐림</string>\n    <string name=\"linear_tent_blur\">선형 텐트 흐림</string>\n    <string name=\"linear_gaussian_box_blur\">선형 가우스 상자 흐림</string>\n    <string name=\"linear_stack_blur\">선형 스택 흐림</string>\n    <string name=\"gaussian_box_blur\">가우시안 박스 블러</string>\n    <string name=\"linear_fast_gaussian_blur_next\">선형 고속 가우스 흐림 다음</string>\n    <string name=\"linear_fast_gaussian_blur\">선형 고속 가우스 흐림</string>\n    <string name=\"linear_gaussian_blur\">선형 가우시안 블러</string>\n    <string name=\"draw_filter_sub\">하나의 필터를 선택하여 페인트로 사용</string>\n    <string name=\"replace_filter\">필터 교체</string>\n    <string name=\"pick_filter_info\">그림에서 브러시로 사용하려면 아래 필터를 선택하세요.</string>\n    <string name=\"tiff_compression_scheme\">TIFF 압축 방식</string>\n    <string name=\"low_poly\">낮은 폴리</string>\n    <string name=\"sand_painting\">모래 그림</string>\n    <string name=\"image_splitting\">이미지 분할</string>\n    <string name=\"image_splitting_sub\">단일 이미지를 행 또는 열로 분할</string>\n    <string name=\"fit_to_bounds\">경계에 맞추기</string>\n    <string name=\"fit_to_bounds_sub\">원하는 동작을 달성하려면 자르기 크기 조정 모드를 이 매개변수와 결합하세요(종횡비에 맞게 자르기/맞춤).</string>\n    <string name=\"languages_imported\">성공적으로 가져온 언어</string>\n    <string name=\"backup_ocr_models\">백업 OCR 모델</string>\n    <string name=\"import_word\">수입</string>\n    <string name=\"export\">내보내다</string>\n    <string name=\"position\">위치</string>\n    <string name=\"center\">센터</string>\n    <string name=\"top_left\">왼쪽 위</string>\n    <string name=\"top_right\">오른쪽 상단</string>\n    <string name=\"bottom_left\">왼쪽 하단</string>\n    <string name=\"bottom_right\">오른쪽 하단</string>\n    <string name=\"top_center\">상단 중앙</string>\n    <string name=\"center_right\">중앙 오른쪽</string>\n    <string name=\"bottom_center\">하단 중앙</string>\n    <string name=\"center_left\">중앙 왼쪽</string>\n    <string name=\"target_image\">대상 이미지</string>\n    <string name=\"palette_transfer\">팔레트 이송</string>\n    <string name=\"enhanced_oil\">강화 오일</string>\n    <string name=\"simple_old_tv\">단순한 오래된 TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">고담</string>\n    <string name=\"simple_sketch\">간단한 스케치</string>\n    <string name=\"soft_glow\">부드러운 빛</string>\n    <string name=\"color_poster\">컬러 포스터</string>\n    <string name=\"tri_tone\">트라이톤</string>\n    <string name=\"third_color\">세 번째 색상</string>\n    <string name=\"clahe_oklab\">클라헤 오크랩</string>\n    <string name=\"clahe_oklch\">클라라 올치</string>\n    <string name=\"clahe_jzazbz\">클라헤 자즈브즈</string>\n    <string name=\"polka_dot\">폴카 도트</string>\n    <string name=\"clustered_2x2_dithering\">클러스터링된 2x2 디더링</string>\n    <string name=\"clustered_4x4_dithering\">클러스터링된 4x4 디더링</string>\n    <string name=\"clustered_8x8_dithering\">클러스터링된 8x8 디더링</string>\n    <string name=\"yililoma_dithering\">Yililoma 디더링</string>\n    <string name=\"no_favorite_options_selected\">즐겨찾는 옵션이 선택되지 않았습니다. 도구 페이지에 추가하세요.</string>\n    <string name=\"add_favorites\">즐겨찾기 추가</string>\n    <string name=\"harmony_complementary\">보완적인</string>\n    <string name=\"harmony_analogous\">유사한</string>\n    <string name=\"harmony_triadic\">삼극체</string>\n    <string name=\"harmony_split_complementary\">분할 보완</string>\n    <string name=\"harmony_tetradic\">테트라딕</string>\n    <string name=\"harmony_square\">정사각형</string>\n    <string name=\"harmony_analogous_complementary\">유사 + 보완</string>\n    <string name=\"color_tools\">컬러 도구</string>\n    <string name=\"color_tools_sub\">믹스, 톤 만들기, 셰이드 생성 등</string>\n    <string name=\"color_harmonies\">색상 조화</string>\n    <string name=\"color_shading\">색상 음영</string>\n    <string name=\"variation\">변화</string>\n    <string name=\"tints\">색조</string>\n    <string name=\"tones\">톤</string>\n    <string name=\"shades\">그늘</string>\n    <string name=\"color_mixing\">색상 혼합</string>\n    <string name=\"color_info\">색상 정보</string>\n    <string name=\"selected_color\">선택한 색상</string>\n    <string name=\"color_to_mix\">혼합할 색상</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">동적 색상이 켜져 있는 동안에는 모네를 사용할 수 없습니다.</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">대상 LUT 이미지</string>\n    <string name=\"amatorka\">아마추어</string>\n    <string name=\"miss_etikate\">미스 에티켓</string>\n    <string name=\"soft_elegance\">부드러운 우아함</string>\n    <string name=\"soft_elegance_variant\">소프트 엘레강스 변형</string>\n    <string name=\"palette_transfer_variant\">팔레트 전송 변형</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">대상 3D LUT 파일(.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">표백제 우회</string>\n    <string name=\"candlelight\">촛불</string>\n    <string name=\"drop_blues\">드롭 블루스</string>\n    <string name=\"edgy_amber\">엣지있는 앰버</string>\n    <string name=\"fall_colors\">가을 색</string>\n    <string name=\"film_stock_50\">필름 스톡 50</string>\n    <string name=\"foggy_night\">안개가 자욱한 밤</string>\n    <string name=\"kodak\">코닥</string>\n    <string name=\"save_empty_lut\">중립 LUT 이미지 가져오기</string>\n    <string name=\"save_empty_lut_sub\">먼저, 즐겨 사용하는 사진 편집 애플리케이션을 사용하여 여기에서 얻을 수 있는 중립 LUT에 필터를 적용하세요. 이것이 제대로 작동하려면 각 픽셀 색상이 다른 픽셀에 종속되어서는 안 됩니다(예: 흐림 효과는 작동하지 않습니다). 준비가 되면 새 LUT 이미지를 512*512 LUT 필터의 입력으로 사용합니다.</string>\n    <string name=\"pop_art\">팝아트</string>\n    <string name=\"celluloid\">셀룰로이드</string>\n    <string name=\"coffee\">커피</string>\n    <string name=\"golden_forest\">황금의 숲</string>\n    <string name=\"greenish\">녹색을 띠는</string>\n    <string name=\"retro_yellow\">레트로 옐로우</string>\n    <string name=\"links_preview\">링크 미리보기</string>\n    <string name=\"links_preview_sub\">텍스트(QRCode, OCR 등)를 얻을 수 있는 위치에서 링크 미리보기 검색을 활성화합니다.</string>\n    <string name=\"links\">모래밭</string>\n    <string name=\"ico_size_warning\">ICO 파일은 최대 256 x 256 크기로만 저장할 수 있습니다.</string>\n    <string name=\"gif_type_to_webp\">WEBP로 GIF</string>\n    <string name=\"gif_type_to_webp_sub\">GIF 이미지를 WEBP 애니메이션 사진으로 변환</string>\n    <string name=\"webp_tools\">WEBP 도구</string>\n    <string name=\"webp_tools_sub\">이미지를 WEBP 애니메이션 그림으로 변환하거나 특정 WEBP 애니메이션에서 프레임을 추출합니다.</string>\n    <string name=\"webp_type_to_image\">WEBP를 이미지로</string>\n    <string name=\"webp_type_to_image_sub\">WEBP 파일을 사진 배치로 변환</string>\n    <string name=\"webp_type_to_webp_sub\">이미지 배치를 WEBP 파일로 변환</string>\n    <string name=\"webp_type_to_webp\">WEBP에 대한 이미지</string>\n    <string name=\"select_webp_image_to_start\">시작하려면 WEBP 이미지를 선택하세요.</string>\n    <string name=\"manage_storage_extra_types\">파일에 대한 전체 액세스 권한이 없습니다.</string>\n    <string name=\"manage_storage_extra_types_sub\">안드로이드에서 이미지로 인식되지 않는 JXL, QOI 등의 이미지를 보려면 모든 파일 접근을 허용하세요. 권한이 없으면 Image Toolbox가 해당 이미지를 표시할 수 없습니다.</string>\n    <string name=\"default_draw_color\">기본 그리기 색상</string>\n    <string name=\"default_draw_path_mode\">기본 그리기 경로 모드</string>\n    <string name=\"add_timestamp\">타임스탬프 추가</string>\n    <string name=\"add_timestamp_sub\">출력 파일 이름에 타임스탬프 추가를 활성화합니다.</string>\n    <string name=\"formatted_timestamp\">형식화된 타임스탬프</string>\n    <string name=\"formatted_timestamp_sub\">기본 밀리초 대신 출력 파일 이름에 타임스탬프 형식을 활성화합니다.</string>\n    <string name=\"enable_timestamps_to_format_them\">타임스탬프를 활성화하여 형식을 선택하세요</string>\n    <string name=\"one_time_save_location\">일회용 저장 위치</string>\n    <string name=\"one_time_save_location_sub\">대부분의 모든 옵션에서 저장 버튼을 길게 눌러 사용할 수 있는 일회용 저장 위치를 ​​보고 편집합니다.</string>\n    <string name=\"recently_used\">최근 사용됨</string>\n    <string name=\"ci_channel\">CI 채널</string>\n    <string name=\"group\">그룹</string>\n    <string name=\"image_toolbox_in_telegram\">텔레그램의 이미지 도구 상자 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">원하는 무엇이든 토론할 수 있는 채팅에 참여하고 베타 및 공지사항을 게시하는 CI 채널도 살펴보세요.</string>\n    <string name=\"ci_channel_sub\">앱의 새 버전에 대한 알림을 받고 공지사항을 읽어보세요.</string>\n    <string name=\"fit_description\">주어진 크기에 이미지를 맞추고 배경에 흐림이나 색상을 적용합니다.</string>\n    <string name=\"tools_arrangement\">도구 배열</string>\n    <string name=\"group_tools_by_type\">유형별로 도구 그룹화</string>\n    <string name=\"group_tools_by_type_sub\">사용자 정의 목록 정렬 대신 유형별로 기본 화면의 도구를 그룹화합니다.</string>\n    <string name=\"default_values\">기본값</string>\n    <string name=\"system_bars_visibility\">시스템 표시줄 가시성</string>\n    <string name=\"show_system_bars_by_swipe\">스와이프하여 시스템 표시줄 표시</string>\n    <string name=\"show_system_bars_by_swipe_sub\">숨겨진 경우 스와이프하여 시스템 표시줄을 표시할 수 있습니다.</string>\n    <string name=\"auto\">자동</string>\n    <string name=\"hide_all\">모두 숨기기</string>\n    <string name=\"show_all\">모두 표시</string>\n    <string name=\"hide_nav_bar\">탐색 모음 숨기기</string>\n    <string name=\"hide_status_bar\">상태 표시줄 숨기기</string>\n    <string name=\"noise_generation\">소음 발생</string>\n    <string name=\"noise_generation_sub\">Perlin이나 다른 유형과 같은 다양한 노이즈 생성</string>\n    <string name=\"frequency\">빈도</string>\n    <string name=\"noise_type\">소음 유형</string>\n    <string name=\"rotation_type\">회전 유형</string>\n    <string name=\"fractal_type\">프랙탈 유형</string>\n    <string name=\"octaves\">옥타브</string>\n    <string name=\"lacunarity\">빈약함</string>\n    <string name=\"gain\">얻다</string>\n    <string name=\"weighted_strength\">가중 강도</string>\n    <string name=\"ping_pong_strength\">탁구의 힘</string>\n    <string name=\"distance_function\">거리 함수</string>\n    <string name=\"return_type\">반환 유형</string>\n    <string name=\"jitter\">지터</string>\n    <string name=\"domain_warp\">도메인 워프</string>\n    <string name=\"alignment\">조정</string>\n    <string name=\"custom_filename\">사용자 정의 파일 이름</string>\n    <string name=\"custom_filename_sub\">현재 이미지를 저장하는 데 사용될 위치와 파일 이름을 선택하십시오.</string>\n    <string name=\"saved_to_custom\">맞춤 이름으로 폴더에 저장됨</string>\n    <string name=\"collage_maker\">콜라주 메이커</string>\n    <string name=\"collage_maker_sub\">최대 20개의 이미지로 콜라주 만들기</string>\n    <string name=\"collage_type\">콜라주 유형</string>\n    <string name=\"collages_info\">이미지를 잡고 위치를 조정하고 이동하고 확대/축소하세요.</string>\n    <string name=\"disable_rotation\">회전 비활성화</string>\n    <string name=\"disable_rotation_sub\">두 손가락 동작으로 이미지 회전 방지</string>\n    <string name=\"enable_snapping_to_borders\">테두리에 맞추기 활성화</string>\n    <string name=\"enable_snapping_to_borders_sub\">이동하거나 확대/축소한 후에는 이미지가 프레임 가장자리를 채우도록 스냅됩니다.</string>\n    <string name=\"histogram\">히스토그램</string>\n    <string name=\"histogram_sub\">조정에 도움이 되는 RGB 또는 밝기 이미지 히스토그램</string>\n    <string name=\"image_for_histogram\">이 이미지는 RGB 및 밝기 히스토그램을 생성하는 데 사용됩니다.</string>\n    <string name=\"tesseract_options\">테서랙트 옵션</string>\n    <string name=\"tesseract_options_sub\">Tesseract 엔진에 일부 입력 변수 적용</string>\n    <string name=\"custom_options\">맞춤 옵션</string>\n    <string name=\"custom_params_info\">옵션은 다음 패턴에 따라 입력해야 합니다: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">자동 자르기</string>\n    <string name=\"free_corners\">무료 코너</string>\n    <string name=\"free_corners_sub\">다각형으로 이미지 자르기, 원근감도 수정됩니다.</string>\n    <string name=\"coerce_points_to_image_bounds\">포인트를 이미지 경계로 강제 변환</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">포인트는 이미지 경계에 의해 제한되지 않으며 이는 보다 정확한 원근 교정에 유용합니다.</string>\n    <string name=\"mask\">마스크</string>\n    <string name=\"spot_heal_sub\">그려진 경로 아래 내용 인식 채우기</string>\n    <string name=\"spot_heal\">힐 스팟</string>\n    <string name=\"use_circle_kernel\">서클 커널 사용</string>\n    <string name=\"opening\">열기</string>\n    <string name=\"closing\">폐쇄</string>\n    <string name=\"morphological_gradient\">형태학적 구배</string>\n    <string name=\"top_hat\">모자</string>\n    <string name=\"black_hat\">검은 모자</string>\n    <string name=\"tone_curves\">톤 곡선</string>\n    <string name=\"reset_curves\">곡선 재설정</string>\n    <string name=\"reset_curves_sub\">곡선이 기본값으로 롤백됩니다.</string>\n    <string name=\"line_style\">선 스타일</string>\n    <string name=\"gap_size\">간격 크기</string>\n    <string name=\"dashed\">점선</string>\n    <string name=\"dot_dashed\">점선</string>\n    <string name=\"stamped\">스탬프가 찍힌</string>\n    <string name=\"zigzag\">지그재그</string>\n    <string name=\"dashed_sub\">지정된 간격 크기로 그려진 경로를 따라 점선을 그립니다.</string>\n    <string name=\"dot_dashed_sub\">주어진 경로를 따라 점선과 점선을 그립니다.</string>\n    <string name=\"defaultt_sub\">그냥 기본 직선</string>\n    <string name=\"stamped_sub\">지정된 간격으로 경로를 따라 선택한 모양을 그립니다.</string>\n    <string name=\"zigzag_sub\">경로를 따라 물결 모양의 지그재그를 그립니다.</string>\n    <string name=\"zigzag_ratio\">지그재그 비율</string>\n    <string name=\"create_shortcut\">바로가기 만들기</string>\n    <string name=\"create_shortcut_title\">고정할 도구 선택</string>\n    <string name=\"create_shortcut_subtitle\">도구는 실행기의 홈 화면에 바로가기로 추가됩니다. 필요한 동작을 달성하려면 \\\"파일 선택 건너뛰기\\\" 설정과 결합하여 사용하세요.</string>\n    <string name=\"dont_stack_frames\">프레임을 쌓지 마세요</string>\n    <string name=\"dont_stack_frames_sub\">이전 프레임을 폐기하여 서로 쌓이지 않도록 합니다.</string>\n    <string name=\"crossfade\">크로스페이드</string>\n    <string name=\"crossfade_sub\">프레임이 서로 크로스페이드됩니다.</string>\n    <string name=\"crossfade_count\">크로스페이드 프레임 수</string>\n    <string name=\"threshold_one\">임계값 1</string>\n    <string name=\"threshold_two\">임계값 2</string>\n    <string name=\"canny\">영리한</string>\n    <string name=\"mirror_101\">거울 101</string>\n    <string name=\"enhanced_zoom_blur\">향상된 줌 블러</string>\n    <string name=\"laplacian_simple\">라플라시안 단순</string>\n    <string name=\"sobel_simple\">소벨 심플</string>\n    <string name=\"helper_grid\">도우미 그리드</string>\n    <string name=\"helper_grid_sub\">정확한 조작을 돕기 위해 도면 영역 위에 지지 그리드를 표시합니다.</string>\n    <string name=\"grid_color\">그리드 색상</string>\n    <string name=\"cell_width\">셀 너비</string>\n    <string name=\"cell_height\">셀 높이</string>\n    <string name=\"compact_selectors\">컴팩트 셀렉터</string>\n    <string name=\"compact_selectors_sub\">일부 선택 컨트롤은 공간을 덜 차지하기 위해 컴팩트한 레이아웃을 사용합니다.</string>\n    <string name=\"grant_camera_permission_to_capture_image\">이미지를 캡처하려면 설정에서 카메라 권한을 부여하세요.</string>\n    <string name=\"layout\">공들여 나열한 것</string>\n    <string name=\"main_screen_title\">메인 화면 제목</string>\n    <string name=\"constant_rate_factor\">고정율 인자(CRF)</string>\n    <string name=\"crf_sub\">%1$s 값은 압축 속도가 느려 파일 크기가 상대적으로 작아짐을 의미합니다. %2$s은 압축 속도가 빨라져 파일 크기가 커진다는 의미입니다.</string>\n    <string name=\"lut_library\">루트 도서관</string>\n    <string name=\"lut_library_sub\">다운로드 후 적용할 수 있는 LUT 컬렉션 다운로드</string>\n    <string name=\"lut_library_update_sub\">다운로드 후 적용할 수 있는 LUT 컬렉션 업데이트(새 LUT만 대기열에 추가됨)</string>\n    <string name=\"filter_preview_image_sub\">필터의 기본 이미지 미리보기 변경</string>\n    <string name=\"filter_preview_image\">미리보기 이미지</string>\n    <string name=\"hide\">숨다</string>\n    <string name=\"show\">보여주다</string>\n    <string name=\"slider_type\">슬라이더 유형</string>\n    <string name=\"fancy\">팬시한</string>\n    <string name=\"material_2\">자료 2</string>\n    <string name=\"fancy_sub\">고급스러워 보이는 슬라이더. 기본 옵션입니다</string>\n    <string name=\"material_2_sub\">머티리얼 2 슬라이더</string>\n    <string name=\"material_you_slider_sub\">재료 당신 슬라이더</string>\n    <string name=\"apply\">적용하다</string>\n    <string name=\"center_align_dialog_buttons\">중앙 대화 상자 버튼</string>\n    <string name=\"center_align_dialog_buttons_sub\">가능한 경우 대화 상자의 버튼은 왼쪽 대신 중앙에 배치됩니다.</string>\n    <string name=\"open_source_licenses\">오픈 소스 라이선스</string>\n    <string name=\"open_source_licenses_sub\">이 앱에 사용된 오픈 소스 라이브러리의 라이선스 보기</string>\n    <string name=\"area\">영역</string>\n    <string name=\"area_sub\">픽셀 영역 관계를 사용한 리샘플링. 모아레 없는 결과를 제공하므로 이미지 데시메이션에 선호되는 방법일 수 있습니다. 하지만 이미지를 확대하면 \\\"Nearest\\\" 방법과 유사합니다.</string>\n    <string name=\"enable_tonemapping\">톤 매핑 활성화</string>\n    <string name=\"enter_percent\">입력하다 %</string>\n    <string name=\"unknown_host\">사이트에 액세스할 수 없습니다. VPN을 사용해 보거나 URL이 올바른지 확인하세요.</string>\n    <string name=\"markup_layers\">마크업 레이어</string>\n    <string name=\"markup_layers_sub\">이미지, 텍스트 등을 자유롭게 배치할 수 있는 레이어 모드</string>\n    <string name=\"edit_layer\">레이어 편집</string>\n    <string name=\"layers_on_image\">이미지의 레이어</string>\n    <string name=\"layers_on_image_sub\">이미지를 배경으로 사용하고 그 위에 다양한 레이어를 추가하세요.</string>\n    <string name=\"layers_on_background\">배경 레이어</string>\n    <string name=\"layers_on_background_sub\">첫 번째 옵션과 동일하지만 이미지 대신 색상이 사용됨</string>\n    <string name=\"beta\">베타</string>\n    <string name=\"fast_settings_side\">빠른 설정 측면</string>\n    <string name=\"fast_settings_side_sub\">이미지를 편집하는 동안 선택한 면에 플로팅 스트립을 추가하면 클릭 시 빠른 설정이 열립니다.</string>\n    <string name=\"clear_selection\">선택 취소</string>\n    <string name=\"settings_group_visibility_hidden\">\\\"%1$s\\\" 설정 그룹은 기본적으로 축소됩니다.</string>\n    <string name=\"settings_group_visibility_visible\">기본적으로 \\\"%1$s\\\" 설정 그룹이 확장됩니다.</string>\n    <string name=\"base_64_tools\">Base64 도구</string>\n    <string name=\"base_64_tools_sub\">Base64 문자열을 이미지로 디코딩하거나 이미지를 Base64 형식으로 인코딩합니다.</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">제공된 값은 유효한 Base64 문자열이 아닙니다.</string>\n    <string name=\"copy_not_a_valid_base_64\">비어 있거나 유효하지 않은 Base64 문자열을 복사할 수 없습니다.</string>\n    <string name=\"paste_base_64\">Base64 붙여넣기</string>\n    <string name=\"copy_base_64\">Base64 복사</string>\n    <string name=\"base_64_tips\">Base64 문자열을 복사하거나 저장하려면 이미지를 로드하세요. 문자열 자체가 있는 경우 위에 붙여넣어 이미지를 얻을 수 있습니다.</string>\n    <string name=\"save_base_64\">Base64 저장</string>\n    <string name=\"share_base_64\">Base64 공유</string>\n    <string name=\"options\">옵션</string>\n    <string name=\"actions\">행위</string>\n    <string name=\"import_base_64\">Base64 가져오기</string>\n    <string name=\"base_64_actions\">Base64 작업</string>\n    <string name=\"add_outline\">개요 추가</string>\n    <string name=\"add_outline_sub\">지정된 색상과 너비로 텍스트 주위에 윤곽선 추가</string>\n    <string name=\"outline_color\">외곽선 색상</string>\n    <string name=\"outline_size\">외곽선 크기</string>\n    <string name=\"rotation\">회전</string>\n    <string name=\"checksum_as_filename\">파일 이름으로 체크섬</string>\n    <string name=\"checksum_as_filename_sub\">출력 이미지에는 데이터 체크섬에 해당하는 이름이 있습니다.</string>\n    <string name=\"free_software_partner\">자유 소프트웨어(파트너)</string>\n    <string name=\"free_software_partner_sub\">Android 애플리케이션 파트너 채널의 더 유용한 소프트웨어</string>\n    <string name=\"algorithms\">연산</string>\n    <string name=\"checksum_tools\">체크섬 도구</string>\n    <string name=\"checksum_tools_sub\">다양한 해싱 알고리즘을 사용하여 체크섬 비교, 해시 계산 또는 파일에서 16진수 문자열 생성</string>\n    <string name=\"calculate\">믿다</string>\n    <string name=\"text_hash\">텍스트 해시</string>\n    <string name=\"checksum\">체크섬</string>\n    <string name=\"pick_file_to_checksum\">선택한 알고리즘을 기반으로 체크섬을 계산할 파일을 선택하세요.</string>\n    <string name=\"enter_text_to_checksum\">선택한 알고리즘을 기반으로 체크섬을 계산하려면 텍스트를 입력하세요.</string>\n    <string name=\"source_checksum\">소스 체크섬</string>\n    <string name=\"checksum_to_compare\">비교할 체크섬</string>\n    <string name=\"match\">성냥!</string>\n    <string name=\"difference\">차이점</string>\n    <string name=\"match_sub\">체크섬이 동일하므로 안전할 수 있습니다.</string>\n    <string name=\"difference_sub\">체크섬이 동일하지 않아 파일이 안전하지 않을 수 있습니다!</string>\n    <string name=\"mesh_gradients\">메쉬 그라디언트</string>\n    <string name=\"collection_mesh_gradients_sub\">메쉬 그라디언트의 온라인 컬렉션을 살펴보세요</string>\n    <string name=\"wrong_font\">TTF 및 OTF 글꼴만 가져올 수 있습니다.</string>\n    <string name=\"import_font\">글꼴 가져오기(TTF/OTF)</string>\n    <string name=\"export_fonts\">글꼴 내보내기</string>\n    <string name=\"imported_fonts\">가져온 글꼴</string>\n    <string name=\"error_while_saving\">시도를 저장하는 중 오류가 발생했습니다. 출력 폴더를 변경해 보세요.</string>\n    <string name=\"filename_is_not_set\">파일 이름이 설정되지 않았습니다.</string>\n    <string name=\"none\">없음</string>\n    <string name=\"custom_pages\">사용자 정의 페이지</string>\n    <string name=\"pages_selection\">페이지 선택</string>\n    <string name=\"tool_exit_confirmation\">도구 종료 확인</string>\n    <string name=\"tool_exit_confirmation_sub\">특정 도구를 사용하는 동안 저장하지 않은 변경 사항이 있는 경우 이를 닫으려고 하면 확인 대화 상자가 표시됩니다.</string>\n    <string name=\"edit_exif_screen\">EXIF 편집</string>\n    <string name=\"edit_exif_screen_sub\">재압축 없이 단일 이미지의 메타데이터 변경</string>\n    <string name=\"edit_exif_tag\">사용 가능한 태그를 수정하려면 탭하세요.</string>\n    <string name=\"change_sticker\">스티커 변경</string>\n    <string name=\"fit_width\">너비에 맞게</string>\n    <string name=\"fit_height\">맞는 높이</string>\n    <string name=\"batch_compare\">일괄 비교</string>\n    <string name=\"pick_files_to_checksum\">선택한 알고리즘을 기반으로 체크섬을 계산할 파일을 선택하세요.</string>\n    <string name=\"pick_files\">파일 선택</string>\n    <string name=\"pick_directory\">디렉토리 선택</string>\n    <string name=\"head_length_scale\">머리 길이 척도</string>\n    <string name=\"stamp\">우표</string>\n    <string name=\"timestamp\">타임스탬프</string>\n    <string name=\"format_pattern\">형식 패턴</string>\n    <string name=\"padding\">심</string>\n    <string name=\"image_cutting\">이미지 커팅</string>\n    <string name=\"image_cutting_sub\">이미지 부분을 자르고 왼쪽 부분을 수직 또는 수평선으로 병합합니다(반전 가능).</string>\n    <string name=\"vertical_pivot_line\">수직 피벗선</string>\n    <string name=\"horizontal_pivot_line\">수평 피벗선</string>\n    <string name=\"inverse_selection\">역선택</string>\n    <string name=\"inverse_vertical_selection_sub\">절단 영역 주위의 부분을 병합하는 대신 수직 절단 부분이 남습니다.</string>\n    <string name=\"inverse_horizontal_selection_sub\">절단 영역 주위의 부품을 병합하는 대신 수평 절단 부분이 남습니다.</string>\n    <string name=\"collection_mesh_gradients\">메쉬 그라디언트 컬렉션</string>\n    <string name=\"mesh_gradients_sub\">사용자 정의된 매듭 수와 해상도로 메쉬 그라디언트 생성</string>\n    <string name=\"gradient_maker_type_image_mesh\">메쉬 그라디언트 오버레이</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">주어진 이미지 상단의 메쉬 그래디언트 구성</string>\n    <string name=\"points_customization\">포인트 맞춤화</string>\n    <string name=\"grid_size\">그리드 크기</string>\n    <string name=\"resolution_x\">해상도 X</string>\n    <string name=\"resolution_y\">해상도 Y</string>\n    <string name=\"resolution\">해결</string>\n    <string name=\"pixel_by_pixel\">픽셀 단위</string>\n    <string name=\"highlight_color\">하이라이트 색상</string>\n    <string name=\"pixel_comparison_type\">픽셀 비교 유형</string>\n    <string name=\"scan_barcode\">바코드 스캔</string>\n    <string name=\"height_ratio\">높이 비율</string>\n    <string name=\"barcode_type\">바코드 유형</string>\n    <string name=\"enforce_bw\">흑백 적용</string>\n    <string name=\"enforce_bw_sub\">바코드 이미지는 완전히 흑백이며 앱 테마에 따라 색상이 지정되지 않습니다.</string>\n    <string name=\"barcodes_sub\">바코드(QR, EAN, AZTEC 등)를 스캔하고 내용을 가져오거나 텍스트를 붙여넣어 새 바코드를 생성하세요.</string>\n    <string name=\"no_barcode_found\">바코드를 찾을 수 없습니다</string>\n    <string name=\"generated_barcode_will_be_here\">생성된 바코드가 여기에 있습니다</string>\n    <string name=\"audio_cover_extractor\">오디오 커버</string>\n    <string name=\"audio_cover_extractor_sub\">오디오 파일에서 앨범 표지 이미지를 추출합니다. 가장 일반적인 형식이 지원됩니다.</string>\n    <string name=\"pick_audio_to_start\">시작할 오디오 선택</string>\n    <string name=\"pick_audio\">오디오 선택</string>\n    <string name=\"no_covers_found\">표지를 찾을 수 없습니다</string>\n    <string name=\"send_logs\">로그 보내기</string>\n    <string name=\"send_logs_sub\">앱 로그 파일을 공유하려면 클릭하세요. 그러면 문제를 파악하고 해결하는 데 도움이 될 수 있습니다.</string>\n    <string name=\"crash_title\">이런… 문제가 발생했습니다.</string>\n    <string name=\"crash_subtitle\">아래 옵션을 사용하여 저에게 연락하시면 해결 방법을 찾아보겠습니다.\\n(로그를 첨부하는 것을 잊지 마세요)</string>\n    <string name=\"ocr_write_to_file\">파일에 쓰기</string>\n    <string name=\"ocr_write_to_file_sub\">이미지 배치에서 텍스트를 추출하여 하나의 텍스트 파일에 저장합니다.</string>\n    <string name=\"ocr_write_to_metadata\">메타데이터에 쓰기</string>\n    <string name=\"ocr_write_to_metadata_sub\">각 이미지에서 텍스트를 추출하여 관련 사진의 EXIF ​​정보에 배치합니다.</string>\n    <string name=\"invisible_mode\">보이지 않는 모드</string>\n    <string name=\"invisible_mode_sub\">스테가노그래피를 사용하여 이미지 바이트 안에 눈에 보이지 않는 워터마크 만들기</string>\n    <string name=\"use_lsb\">LSB 사용</string>\n    <string name=\"use_lsb_sub\">LSB(Less Significant Bit) 스테가노그래피 방법이 사용되며, 그렇지 않으면 FD(Frequency Domain)가 사용됩니다.</string>\n    <string name=\"auto_remove_red_eyes\">적목 현상 자동 제거</string>\n    <string name=\"password\">비밀번호</string>\n    <string name=\"unlock\">터놓다</string>\n    <string name=\"pdf_is_protected\">PDF가 보호됩니다</string>\n    <string name=\"operation_almost_complete\">작업이 거의 완료되었습니다. 지금 취소하면 다시 시작해야 합니다.</string>\n    <string name=\"sort_by_date_modified\">수정된 날짜</string>\n    <string name=\"sort_by_date_modified_reversed\">수정 날짜(역순)</string>\n    <string name=\"sort_by_size\">크기</string>\n    <string name=\"sort_by_size_reversed\">크기(역순)</string>\n    <string name=\"sort_by_mime_type\">MIME 유형</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME 유형(역방향)</string>\n    <string name=\"sort_by_extension\">확대</string>\n    <string name=\"sort_by_extension_reversed\">확장(역방향)</string>\n    <string name=\"sort_by_date_added\">추가된 날짜</string>\n    <string name=\"sort_by_date_added_reversed\">추가된 날짜(역순)</string>\n    <string name=\"left_to_right\">왼쪽에서 오른쪽으로</string>\n    <string name=\"right_to_left\">오른쪽에서 왼쪽으로</string>\n    <string name=\"top_to_bottom\">위에서 아래로</string>\n    <string name=\"bottom_to_top\">아래에서 위로</string>\n    <string name=\"liquid_glass\">액체 유리</string>\n    <string name=\"liquid_glass_sub\">최근 발표된 IOS 26 및 액체 유리 설계 시스템을 기반으로 한 스위치</string>\n    <string name=\"pick_image_or_base64\">이미지를 선택하거나 아래에서 Base64 데이터를 붙여넣거나 가져오세요.</string>\n    <string name=\"type_image_link\">시작하려면 이미지 링크를 입력하세요.</string>\n    <string name=\"paste_link\">링크 붙여넣기</string>\n    <string name=\"kaleidoscope\">만화경</string>\n    <string name=\"secondary_angle\">보조 각도</string>\n    <string name=\"sides\">측면</string>\n    <string name=\"channel_mix\">채널 믹스</string>\n    <string name=\"blue_green\">청록색</string>\n    <string name=\"red_blue\">빨간색 파란색</string>\n    <string name=\"green_red\">녹색 빨간색</string>\n    <string name=\"into_red\">빨간색으로</string>\n    <string name=\"into_green\">녹색으로</string>\n    <string name=\"into_blue\">파란색으로</string>\n    <string name=\"cyan\">청록색</string>\n    <string name=\"magenta\">마젠타</string>\n    <string name=\"yellow\">노란색</string>\n    <string name=\"color_halftone\">색상 하프톤</string>\n    <string name=\"contour\">윤곽</string>\n    <string name=\"levels\">레벨</string>\n    <string name=\"offset\">오프셋</string>\n    <string name=\"voronoi_crystallize\">보로노이 크리스탈라이즈</string>\n    <string name=\"shape\">모양</string>\n    <string name=\"stretch\">뻗기</string>\n    <string name=\"randomness\">무작위성</string>\n    <string name=\"despeckle\">얼룩 제거</string>\n    <string name=\"diffuse\">퍼지다</string>\n    <string name=\"dog\">개</string>\n    <string name=\"second_radius\">두 번째 반경</string>\n    <string name=\"equalize\">같게 하다</string>\n    <string name=\"glow\">불타는 듯한 빛깔</string>\n    <string name=\"whirl_and_pinch\">소용돌이와 핀치</string>\n    <string name=\"pointillize\">점묘화</string>\n    <string name=\"border_color\">테두리 색상</string>\n    <string name=\"polar_coordinates\">극좌표</string>\n    <string name=\"rect_to_polar\">극좌표에서 직사각형으로</string>\n    <string name=\"polar_to_rect\">극좌표에서 직사각형으로</string>\n    <string name=\"invert_in_circle\">원으로 반전</string>\n    <string name=\"reduce_noise\">소음 감소</string>\n    <string name=\"simple_solarize\">단순 솔라라이즈</string>\n    <string name=\"weave\">짜다</string>\n    <string name=\"x_gap\">X 간격</string>\n    <string name=\"y_gap\">Y 간격</string>\n    <string name=\"x_width\">X 폭</string>\n    <string name=\"y_wdth\">Y 폭</string>\n    <string name=\"twirl\">회전</string>\n    <string name=\"rubber_stmp\">고무 도장</string>\n    <string name=\"smear\">도말 표본</string>\n    <string name=\"density\">밀도</string>\n    <string name=\"mix\">혼합</string>\n    <string name=\"sphere_lensh_distortion\">구형 렌즈 왜곡</string>\n    <string name=\"refraction_index\">굴절률</string>\n    <string name=\"arc\">호</string>\n    <string name=\"spread_angle\">확산 각도</string>\n    <string name=\"sparkle\">불꽃</string>\n    <string name=\"rays\">광선</string>\n    <string name=\"ascii\">아스키</string>\n    <string name=\"gradient\">구배</string>\n    <string name=\"moire\">메리</string>\n    <string name=\"autumn\">가을</string>\n    <string name=\"bone\">뼈</string>\n    <string name=\"jet\">제트기</string>\n    <string name=\"winter\">겨울</string>\n    <string name=\"ocean\">대양</string>\n    <string name=\"summer\">여름</string>\n    <string name=\"spring\">봄</string>\n    <string name=\"cool_variant\">멋진 변형</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">분홍색</string>\n    <string name=\"hot\">더운</string>\n    <string name=\"parula\">단어</string>\n    <string name=\"magma\">연한 덩어리</string>\n    <string name=\"inferno\">지옥</string>\n    <string name=\"plasma\">혈장</string>\n    <string name=\"viridis\">비리디스</string>\n    <string name=\"cividis\">시민</string>\n    <string name=\"twilight\">어스름</string>\n    <string name=\"twilight_shifted\">황혼의 변화</string>\n    <string name=\"auto_perspective\">원근 자동</string>\n    <string name=\"deskew\">왜곡 보정</string>\n    <string name=\"allow_crop\">자르기 허용</string>\n    <string name=\"crop_or_perspective\">자르기 또는 원근감</string>\n    <string name=\"absolute\">순수한</string>\n    <string name=\"turbo\">터보</string>\n    <string name=\"deep_green\">딥 그린</string>\n    <string name=\"lens_correction\">렌즈 교정</string>\n    <string name=\"target_lens_profile\">JSON 형식의 대상 렌즈 프로필 파일</string>\n    <string name=\"download_ready_lens_profiles\">준비된 렌즈 프로필 다운로드</string>\n    <string name=\"part_percents\">부분 퍼센트</string>\n    <string name=\"export_as_json\">JSON으로 내보내기</string>\n    <string name=\"export_as_json_sub\">팔레트 데이터가 포함된 문자열을 JSON 표현으로 복사</string>\n    <string name=\"seam_carving\">솔기 조각</string>\n    <string name=\"home_screen\">홈 화면</string>\n    <string name=\"lock_screen\">잠금 화면</string>\n    <string name=\"built_in\">내장</string>\n    <string name=\"wallpapers_export\">배경화면 내보내기</string>\n    <string name=\"refresh\">새로 고치다</string>\n    <string name=\"wallpapers_export_sub\">현재 홈, 자물쇠 및 내장 배경화면을 받으세요.</string>\n    <string name=\"allow_access_to_all_files_for_wp\">모든 파일에 대한 액세스를 허용합니다. 배경화면을 검색하는 데 필요합니다.</string>\n    <string name=\"allow_read_media_images_for_wp\">외부 저장소 권한 관리만으로는 충분하지 않습니다. 이미지에 대한 액세스를 허용해야 합니다. \\\"모두 허용\\\"을 선택하세요.</string>\n    <string name=\"add_preset_to_filename\">파일 이름에 사전 설정 추가</string>\n    <string name=\"add_preset_to_filename_sub\">이미지 파일 이름에 선택한 사전 설정이 포함된 접미사를 추가합니다.</string>\n    <string name=\"add_image_scale_mode_to_filename\">파일 이름에 이미지 크기 모드 추가</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">선택한 이미지 크기 모드가 포함된 접미사를 이미지 파일 이름에 추가합니다.</string>\n    <string name=\"ascii_art\">아스키 아트</string>\n    <string name=\"ascii_art_sub\">그림을 이미지처럼 보이는 ASCII 텍스트로 변환</string>\n    <string name=\"params\">매개변수</string>\n    <string name=\"invert_colors_ascii_sub\">경우에 따라 더 나은 결과를 얻기 위해 이미지에 네거티브 필터를 적용합니다.</string>\n    <string name=\"processing_screenshot\">스크린샷 처리 중</string>\n    <string name=\"screenshot_not_captured_try_again\">스크린샷이 캡처되지 않았습니다. 다시 시도해 주세요.</string>\n    <string name=\"skipped_saving\">저장을 건너뛰었습니다.</string>\n    <string name=\"skipped_saving_multiple\">%1$s 파일을 건너뛰었습니다.</string>\n    <string name=\"allow_skip_if_larger\">더 큰 경우 건너뛰기 허용</string>\n    <string name=\"allow_skip_if_larger_sub\">결과 파일 크기가 원본보다 클 경우 일부 도구에서는 이미지 저장을 건너뛸 수 있습니다.</string>\n    <string name=\"qr_type_calendar_event\">캘린더 이벤트</string>\n    <string name=\"qr_type_contact_info\">연락하다</string>\n    <string name=\"qr_type_email\">이메일</string>\n    <string name=\"qr_type_geo_point\">위치</string>\n    <string name=\"qr_type_phone\">핸드폰</string>\n    <string name=\"qr_type_plain\">텍스트</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">개방형 네트워크</string>\n    <string name=\"not_specified\">해당 없음</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">핸드폰</string>\n    <string name=\"message\">메시지</string>\n    <string name=\"address\">주소</string>\n    <string name=\"subject\">주제</string>\n    <string name=\"body\">몸</string>\n    <string name=\"name\">이름</string>\n    <string name=\"organization\">조직</string>\n    <string name=\"title\">제목</string>\n    <string name=\"phones\">전화기</string>\n    <string name=\"emails\">이메일</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">구애</string>\n    <string name=\"summary\">요약</string>\n    <string name=\"description\">설명</string>\n    <string name=\"location\">위치</string>\n    <string name=\"organizer\">조직자</string>\n    <string name=\"start_date\">시작일</string>\n    <string name=\"end_date\">종료일</string>\n    <string name=\"status\">상태</string>\n    <string name=\"latitude\">위도</string>\n    <string name=\"longitude\">경도</string>\n    <string name=\"create_barcode\">바코드 생성</string>\n    <string name=\"edit_barcode\">바코드 편집</string>\n    <string name=\"wifi_configuration\">Wi-Fi 구성</string>\n    <string name=\"security\">보안</string>\n    <string name=\"pick_contact\">연락처 선택</string>\n    <string name=\"grant_contact_permission\">선택한 연락처를 사용하여 자동 완성하려면 설정에서 연락처 권한을 부여하세요.</string>\n    <string name=\"contact_info\">연락처 정보</string>\n    <string name=\"first_name\">이름</string>\n    <string name=\"middle_name\">중간 이름</string>\n    <string name=\"last_name\">성</string>\n    <string name=\"pronunciation\">발음</string>\n    <string name=\"add_phone\">전화 추가</string>\n    <string name=\"add_email\">이메일 추가</string>\n    <string name=\"add_address\">주소 추가</string>\n    <string name=\"website\">웹사이트</string>\n    <string name=\"add_website\">웹사이트 추가</string>\n    <string name=\"formatted_name\">형식화된 이름</string>\n    <string name=\"qr_code_top_image\">이 이미지는 바코드 위에 배치하는 데 사용됩니다.</string>\n    <string name=\"code_customization\">코드 사용자 정의</string>\n    <string name=\"qr_logo_image\">QR코드 중앙에 로고로 사용될 이미지입니다.</string>\n    <string name=\"logo\">심벌 마크</string>\n    <string name=\"logo_padding\">로고 패딩</string>\n    <string name=\"logo_size\">로고 크기</string>\n    <string name=\"logo_corners\">로고 코너</string>\n    <string name=\"fourth_eye\">네 번째 눈</string>\n    <string name=\"fourth_eye_description\">하단 모서리에 네 번째 눈을 추가하여 qr 코드에 눈 대칭을 추가합니다.</string>\n    <string name=\"pixel_shape\">픽셀 모양</string>\n    <string name=\"frame_shape\">프레임 모양</string>\n    <string name=\"ball_shape\">공 모양</string>\n    <string name=\"error_correction_level\">오류 수정 수준</string>\n    <string name=\"dark_color\">어두운 색</string>\n    <string name=\"light_color\">연한 색</string>\n    <string name=\"hyper_os\">하이퍼 OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS와 같은 스타일</string>\n    <string name=\"mask_pattern\">마스크 패턴</string>\n    <string name=\"code_may_be_not_scannable\">이 코드는 스캔이 불가능할 수 있습니다. 모든 장치에서 읽을 수 있도록 모양 매개변수를 변경하세요.</string>\n    <string name=\"not_scannable\">스캔할 수 없음</string>\n    <string name=\"launcher_mode_sub\">도구는 더 컴팩트해지기 위해 홈 화면 앱 실행기처럼 보일 것입니다.</string>\n    <string name=\"launcher_mode\">런처 모드</string>\n    <string name=\"flood_fill_sub\">선택한 브러시와 스타일로 영역을 채웁니다.</string>\n    <string name=\"flood_fill\">홍수 채우기</string>\n    <string name=\"spray\">스프레이</string>\n    <string name=\"spray_sub\">낙서 스타일의 경로를 그립니다.</string>\n    <string name=\"square_particles\">정사각형 입자</string>\n    <string name=\"square_particles_sub\">스프레이 입자는 원형이 아닌 정사각형 모양이 됩니다.</string>\n    <string name=\"palette_tools\">팔레트 도구</string>\n    <string name=\"palette_tools_sub\">이미지에서 기본/재료 팔레트를 생성하거나 다양한 팔레트 형식으로 가져오기/내보내기</string>\n    <string name=\"edit_palette\">팔레트 편집</string>\n    <string name=\"edit_palette_sub\">다양한 형식으로 팔레트 내보내기/가져오기</string>\n    <string name=\"color_name\">색상명</string>\n    <string name=\"palette_name\">팔레트 이름</string>\n    <string name=\"palette_format\">팔레트 형식</string>\n    <string name=\"export_palette_sub\">생성된 팔레트를 다른 형식으로 내보내기</string>\n    <string name=\"add_color_palette_sub\">현재 팔레트에 새로운 색상을 추가합니다.</string>\n    <string name=\"palette_name_not_supported\">%1$s 형식은 팔레트 이름 제공을 지원하지 않습니다.</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play 스토어 정책으로 인해 이 기능은 현재 빌드에 포함될 수 없습니다. 이 기능에 액세스하려면 대체 소스에서 ImageToolbox를 다운로드하십시오. 아래 GitHub에서 사용 가능한 빌드를 찾을 수 있습니다.</string>\n    <string name=\"open_github_page\">Github 페이지 열기</string>\n    <string name=\"overwrite_files_sub_short\">선택한 폴더에 저장하는 대신 원본 파일이 새 파일로 대체됩니다.</string>\n    <string name=\"hidden_watermark_text_detected\">숨겨진 워터마크 텍스트가 감지되었습니다.</string>\n    <string name=\"hidden_watermark_image_detected\">숨겨진 워터마크 이미지가 감지되었습니다.</string>\n    <string name=\"this_image_was_hidden\">이 이미지는 숨겨져 있습니다</string>\n    <string name=\"generative_inpaint\">생성적 인페인팅</string>\n    <string name=\"generative_inpaint_sub\">OpenCV에 의존하지 않고 AI 모델을 사용하여 이미지의 개체를 제거할 수 있습니다. 이 기능을 사용하려면 앱이 GitHub에서 필요한 모델(~200MB)을 다운로드합니다.</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV에 의존하지 않고 AI 모델을 사용하여 이미지의 개체를 제거할 수 있습니다. 이는 장기간 실행되는 작업일 수 있습니다.</string>\n    <string name=\"error_level_analysis\">오류 수준 분석</string>\n    <string name=\"luminance_gradient\">휘도 변화도</string>\n    <string name=\"average_distance\">평균 거리</string>\n    <string name=\"copy_move_detection\">복사 이동 감지</string>\n    <string name=\"retain\">유지하다</string>\n    <string name=\"coefficent\">계수</string>\n    <string name=\"clipboard_data_is_too_large\">클립보드 데이터가 너무 큽니다.</string>\n    <string name=\"data_is_too_large_to_copy\">데이터가 너무 커서 복사할 수 없습니다.</string>\n    <string name=\"simple_weave_pixelization\">단순 직조 픽셀화</string>\n    <string name=\"staggered_pixelization\">시차적 픽셀화</string>\n    <string name=\"cross_pixelization\">교차 픽셀화</string>\n    <string name=\"micro_macro_pixelization\">마이크로 매크로 픽셀화</string>\n    <string name=\"orbital_pixelization\">궤도 픽셀화</string>\n    <string name=\"vortex_pixelization\">소용돌이 픽셀화</string>\n    <string name=\"pulse_grid_pixelization\">펄스 그리드 픽셀화</string>\n    <string name=\"nucleus_pixelization\">핵 픽셀화</string>\n    <string name=\"radial_weave_pixelization\">방사형 직조 픽셀화</string>\n    <string name=\"cannot_open_uri\">URI \\\"%1$s\\\"을(를) 열 수 없습니다.</string>\n    <string name=\"snowfall_mode\">강설 모드</string>\n    <string name=\"enabled\">활성화됨</string>\n    <string name=\"border_frame\">테두리 프레임</string>\n    <string name=\"glitch_variant\">글리치 변형</string>\n    <string name=\"channel_shift\">채널 이동</string>\n    <string name=\"max_offset\">최대 오프셋</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">블록 글리치</string>\n    <string name=\"block_size\">블록 크기</string>\n    <string name=\"crt_curvature\">CRT 곡률</string>\n    <string name=\"curvature\">곡률</string>\n    <string name=\"chroma\">크로마</string>\n    <string name=\"pixel_melt\">픽셀 용해</string>\n    <string name=\"max_drop\">최대 드롭</string>\n    <string name=\"ai_tools\">AI 도구</string>\n    <string name=\"ai_tools_sub\">아티팩트 제거 또는 노이즈 제거와 같은 AI 모델을 통해 이미지를 처리하는 다양한 도구</string>\n    <string name=\"model_anime_undeint\">압축, 들쭉날쭉한 선</string>\n    <string name=\"model_broadcast\">만화, 방송 압축</string>\n    <string name=\"model_rgb_max_denoise_fp16\">일반 압축, 일반 소음</string>\n    <string name=\"model_wb_denoise\">무색 만화 소음</string>\n    <string name=\"model_span_anime_pretrain\">빠른 일반 압축, 일반 노이즈, 애니메이션/만화/애니메이션</string>\n    <string name=\"model_book_scan\">도서 스캔</string>\n    <string name=\"model_overexposure\">노출 보정</string>\n    <string name=\"model_fbcnn_color_fp16\">일반 압축, 컬러 이미지에 가장 적합</string>\n    <string name=\"model_fbcnn_gray_fp16\">일반 압축, 회색조 이미지에 가장 적합</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">일반 압축, 회색조 이미지, 더 강력함</string>\n    <string name=\"model_scunet_color_gan_fp16\">일반 노이즈, 컬러 이미지</string>\n    <string name=\"model_scunet_color_psnr_fp16\">일반 노이즈, 컬러 이미지, 더 나은 디테일</string>\n    <string name=\"model_scunet_gray_15_fp16\">일반 노이즈, 회색조 이미지</string>\n    <string name=\"model_scunet_gray_25_fp16\">일반 노이즈, 회색조 이미지, 더 강함</string>\n    <string name=\"model_scunet_gray_50_fp16\">일반 노이즈, 회색조 이미지, 가장 강함</string>\n    <string name=\"model_jpeg_destroyer\">일반 압축</string>\n    <string name=\"model_jaywreck\">일반 압축</string>\n    <string name=\"model_h264\">텍스처화, h264 압축</string>\n    <string name=\"model_vhs\">VHS 압축</string>\n    <string name=\"model_cinepak\">비표준 압축(cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink 압축, 기하학에 더 좋음</string>\n    <string name=\"model_debink_v5\">Bink 압축, 더 강력해짐</string>\n    <string name=\"model_debink_v6\">Bink 압축, 부드러움, 디테일 유지</string>\n    <string name=\"model_antialias\">계단현상 제거, 스무딩</string>\n    <string name=\"model_kdm_scans\">스캔한 아트/도면, 약한 압축, 모아레</string>\n    <string name=\"model_bandage\">컬러 밴딩</string>\n    <string name=\"model_halftone\">천천히, 중간색 제거</string>\n    <string name=\"model_colorizer\">회색조/bw 이미지용 일반 컬러라이저, 더 나은 결과를 얻으려면 DDColor를 사용하세요.</string>\n    <string name=\"model_deedge\">가장자리 제거</string>\n    <string name=\"model_desharpen\">과도한 선명도 제거</string>\n    <string name=\"model_dither\">느리고 디더링됨</string>\n    <string name=\"model_gainres\">앤티앨리어싱, 일반 아티팩트, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 스캔 처리 중</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">경량 이미지 향상 모델</string>\n    <string name=\"model_bcgone_detailed_v2\">압축 아티팩트 제거</string>\n    <string name=\"model_bcgone_smooth\">압축 아티팩트 제거</string>\n    <string name=\"model_bandage_smooth\">원활한 결과로 붕대 제거</string>\n    <string name=\"model_bendel_halftone\">하프톤 패턴 처리</string>\n    <string name=\"model_dither_deleter_v3_smooth\">디더 패턴 제거 V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG 아티팩트 제거 V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 텍스처 향상</string>\n    <string name=\"model_vhs_sharpen\">VHS 선명화 및 향상</string>\n    <string name=\"merging\">병합</string>\n    <string name=\"chunk_size\">청크 크기</string>\n    <string name=\"overlap_size\">중복 크기</string>\n    <string name=\"note_chunk_info\">%1$s픽셀을 초과하는 이미지는 분할되어 청크로 처리되며, 이음새가 보이지 않도록 겹쳐서 혼합됩니다.</string>\n    <string name=\"large_chunk_warning\">크기가 크면 저가형 장치가 불안정해질 수 있습니다.</string>\n    <string name=\"select_one_to_start\">시작하려면 하나를 선택하세요.</string>\n    <string name=\"delete_model_sub\">%1$s 모델을 삭제하시겠습니까? 다시 다운로드해야 합니다.</string>\n    <string name=\"confirm\">확인하다</string>\n    <string name=\"models\">모델</string>\n    <string name=\"downloaded_models\">다운로드한 모델</string>\n    <string name=\"available_models\">사용 가능한 모델</string>\n    <string name=\"preparing\">준비 중</string>\n    <string name=\"active_model\">활성 모델</string>\n    <string name=\"failed_to_open_session\">세션을 열지 못했습니다.</string>\n    <string name=\"only_onnx_models\">.onnx/.ort 모델만 가져올 수 있습니다.</string>\n    <string name=\"import_model\">수입모델</string>\n    <string name=\"import_model_sub\">추가 사용을 위해 사용자 정의 onnx 모델 가져오기, onnx/ort 모델만 허용, 변형과 같은 거의 모든 esrgan 지원</string>\n    <string name=\"imported_models\">가져온 모델</string>\n    <string name=\"model_scunet_color_15_fp16\">일반 노이즈, 컬러 이미지</string>\n    <string name=\"model_scunet_color_25_fp16\">일반 노이즈, 컬러 이미지, 더 강함</string>\n    <string name=\"model_scunet_color_50_fp16\">일반 노이즈, 컬러 이미지, 가장 강함</string>\n    <string name=\"model_artifacts_dithering_alsa\">디더링 아티팩트와 색상 밴딩을 줄여 부드러운 그라데이션과 단조로운 색상 영역을 개선합니다.</string>\n    <string name=\"model_nmkd_brighten_redux\">자연스러운 색상을 유지하면서 균형 잡힌 하이라이트로 이미지 밝기와 대비를 향상시킵니다.</string>\n    <string name=\"model_nmkd_brighten\">디테일을 유지하고 과다 노출을 방지하면서 어두운 이미지를 밝게 합니다.</string>\n    <string name=\"model_nmkd_detoon\">과도한 색상 톤을 제거하고 보다 중립적이고 자연스러운 색상 균형을 복원합니다.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">미세한 디테일과 질감을 유지하는 데 중점을 두고 포아송 기반 노이즈 토닝을 적용합니다.</string>\n    <string name=\"model_noise_toner_poisson_soft\">보다 부드럽고 덜 공격적인 시각적 결과를 위해 부드러운 포아송 노이즈 토닝을 적용합니다.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">디테일 보존과 이미지 선명도에 초점을 맞춘 균일한 노이즈 토닝.</string>\n    <string name=\"model_noise_toner_uniform_soft\">미묘한 질감과 부드러운 외관을 위한 부드럽고 균일한 노이즈 토닝.</string>\n    <string name=\"model_repainter\">아티팩트를 다시 칠하고 이미지 일관성을 개선하여 손상되거나 고르지 않은 영역을 복구합니다.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">최소한의 성능 비용으로 컬러 밴딩을 제거하는 경량 디밴딩 모델입니다.</string>\n    <string name=\"model_jpeg_0_20\">선명도 향상을 위해 매우 높은 압축 아티팩트(0-20% 품질)로 이미지를 최적화합니다.</string>\n    <string name=\"model_jpeg_20_40\">고압축 아티팩트(20-40% 품질)로 이미지를 향상하여 세부 사항을 복원하고 노이즈를 줄입니다.</string>\n    <string name=\"model_jpeg_40_60\">선명도와 부드러움의 균형을 유지하면서 적당한 압축(40-60% 품질)으로 이미지를 개선합니다.</string>\n    <string name=\"model_jpeg_60_80\">가벼운 압축(60-80% 품질)으로 이미지를 개선하여 미묘한 디테일과 질감을 향상합니다.</string>\n    <string name=\"model_jpeg_80_100\">자연스러운 모양과 디테일을 유지하면서 거의 무손실 이미지(80-100% 품질)를 약간 향상시킵니다.</string>\n    <string name=\"model_spongecolor_lite\">간단하고 빠른 채색, 만화, 이상적이지 않음</string>\n    <string name=\"model_deblr\">이미지 흐림을 약간 줄여 아티팩트 없이 선명도를 향상시킵니다.</string>\n    <string name=\"processing_channel\">장기 실행 작업</string>\n    <string name=\"processing_image\">이미지 처리 중</string>\n    <string name=\"processing\">처리</string>\n    <string name=\"model_artifacts_jpg_0_20\">매우 낮은 품질의 이미지(0-20%)에서 심한 JPEG 압축 아티팩트를 제거합니다.</string>\n    <string name=\"model_artifacts_jpg_20_40\">압축률이 높은 이미지에서 강한 JPEG 아티팩트를 줄입니다(20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">이미지 세부 정보(40-60%)를 유지하면서 적당한 JPEG 아티팩트를 정리합니다.</string>\n    <string name=\"model_artifacts_jpg_60_80\">상당히 높은 품질의 이미지(60-80%)에서 가벼운 JPEG 아티팩트를 개선합니다.</string>\n    <string name=\"model_artifacts_jpg_80_100\">거의 무손실 이미지(80-100%)에서 사소한 JPEG 아티팩트를 미묘하게 줄입니다.</string>\n    <string name=\"model_redetail_v2\">미세한 디테일과 질감을 향상시켜 큰 아티팩트 없이 인지된 선명도를 향상시킵니다.</string>\n    <string name=\"processing_finished\">처리 완료</string>\n    <string name=\"processing_failed\">처리 실패</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">속도에 최적화되어 자연스러운 모습을 유지하면서 피부 질감과 디테일을 향상시킵니다.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG 압축 아티팩트를 제거하고 압축된 사진의 이미지 품질을 복원합니다.</string>\n    <string name=\"model_iso_denoise_v1\">저조도 조건에서 촬영한 사진의 ISO 노이즈를 줄여 디테일을 보존합니다.</string>\n    <string name=\"model_dejumbo\">과다 노출 또는 \\\"점보\\\" 하이라이트를 수정하고 더 나은 색조 균형을 복원합니다.</string>\n    <string name=\"model_ddcolor_tiny\">회색조 이미지에 자연스러운 색상을 추가하는 가볍고 빠른 색상화 모델입니다.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">노이즈 제거</string>\n    <string name=\"type_colorize\">색상화</string>\n    <string name=\"type_artifacts\">유물</string>\n    <string name=\"type_enhance\">향상시키다</string>\n    <string name=\"type_anime\">일본 만화 영화</string>\n    <string name=\"type_scans\">스캔</string>\n    <string name=\"type_upscale\">고급</string>\n    <string name=\"model_realesrgan_x4v3\">일반 이미지용 X4 업스케일러; GPU와 시간을 덜 사용하고 중간 정도의 디블러와 노이즈 제거 기능을 갖춘 작은 모델입니다.</string>\n    <string name=\"model_realesrgan_x2plus\">일반 이미지를 위한 X2 업스케일러로 질감과 자연스러운 디테일을 보존합니다.</string>\n    <string name=\"model_realesrgan_x4plus\">향상된 질감과 사실적인 결과를 제공하는 일반 이미지용 X4 업스케일러입니다.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">애니메이션 이미지에 최적화된 X4 업스케일러; 더욱 선명한 라인과 디테일을 위한 6개의 RRDB 블록.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE 손실이 포함된 X4 업스케일러는 일반 이미지에 대해 더 부드러운 결과를 생성하고 아티팩트를 줄입니다.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">애니메이션 이미지에 최적화된 X4 업스케일러; 더 선명한 디테일과 부드러운 라인을 갖춘 4B32F 변형입니다.</string>\n    <string name=\"model_ultrasharp_v2_x4\">일반 이미지용 X4 UltraSharp V2 모델; 선명함과 선명함을 강조합니다.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 라이트; 더 빠르고 더 작아지며, GPU 메모리를 덜 사용하면서 디테일을 보존합니다.</string>\n    <string name=\"model_rmbg_1_4\">빠른 배경 제거를 위한 경량 모델입니다. 균형 잡힌 성능과 정확성. 인물 사진, 사물, 장면과 함께 작동합니다. 대부분의 사용 사례에 권장됩니다.</string>\n    <string name=\"type_removebg\">BG 제거</string>\n    <string name=\"horizontal_border_thickness\">가로 테두리 두께</string>\n    <string name=\"vertical_border_thickness\">세로 테두리 두께</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s 색상</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">현재 모델은 청킹을 지원하지 않습니다. 이미지는 원래 크기로 처리되므로 메모리 소모가 많아 저사양 장치에서 문제가 발생할 수 있습니다.</string>\n    <string name=\"chunking_disabled\">청킹이 비활성화되었습니다. 이미지는 원래 크기로 처리됩니다. 이로 인해 메모리 소비가 많아지고 저사양 장치에 문제가 발생할 수 있지만 추론에서는 더 나은 결과를 얻을 수 있습니다.</string>\n    <string name=\"chunking\">청킹</string>\n    <string name=\"model_u2net\">배경 제거를 위한 고정밀 이미지 분할 모델</string>\n    <string name=\"model_u2netp\">더 적은 메모리 사용량으로 더 빠른 배경 제거를 위한 U2Net의 경량 버전입니다.</string>\n    <string name=\"model_ddcolor\">전체 DDColor 모델은 아티팩트를 최소화하면서 일반 이미지에 대한 고품질 색상화를 제공합니다. 모든 색상화 모델 중 최고의 선택입니다.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor 훈련된 개인 예술 데이터 세트 비현실적인 색상 아티팩트를 줄여 다양하고 예술적인 색상화 결과를 만들어냅니다.</string>\n    <string name=\"model_birefnet\">정확한 배경 제거를 위해 Swin Transformer를 기반으로 한 경량 BiRefNet 모델입니다.</string>\n    <string name=\"model_inspyrenet\">특히 복잡한 물체와 까다로운 배경에서 날카로운 모서리와 뛰어난 세부 묘사 보존 기능을 갖춘 고품질 배경 제거 기능을 제공합니다.</string>\n    <string name=\"model_isnet\">가장자리가 부드러운 정확한 마스크를 생성하는 배경 제거 모델로 일반 객체에 적합하며 적당한 디테일 보존이 가능합니다.</string>\n    <string name=\"model_already_downloaded\">모델이 이미 다운로드됨</string>\n    <string name=\"model_successfully_imported\">모델을 성공적으로 가져왔습니다.</string>\n    <string name=\"type\">유형</string>\n    <string name=\"keyword\">예어</string>\n    <string name=\"very_fast\">매우 빠름</string>\n    <string name=\"normal\">정상</string>\n    <string name=\"slow\">느린</string>\n    <string name=\"very_slow\">매우 느림</string>\n    <string name=\"compute_percents\">백분율 계산</string>\n    <string name=\"minimum_value_is\">최소값은 %1$s입니다.</string>\n    <string name=\"warp_sub\">손가락으로 그려 이미지 왜곡</string>\n    <string name=\"warp\">경사</string>\n    <string name=\"hardness\">경도</string>\n    <string name=\"warp_mode\">워프 모드</string>\n    <string name=\"warp_mode_move\">이동하다</string>\n    <string name=\"warp_mode_grow\">자라다</string>\n    <string name=\"warp_mode_shrink\">수축</string>\n    <string name=\"warp_mode_swirl_cw\">소용돌이 CW</string>\n    <string name=\"warp_mode_swirl_ccw\">소용돌이 CCW</string>\n    <string name=\"fade_strength\">페이드 강도</string>\n    <string name=\"top_drop\">탑 드롭</string>\n    <string name=\"bottom_drop\">하단 드롭</string>\n    <string name=\"start_drop\">드롭 시작</string>\n    <string name=\"end_drop\">엔드 드롭</string>\n    <string name=\"downloading\">다운로드 중</string>\n    <string name=\"smooth_shapes\">부드러운 모양</string>\n    <string name=\"smooth_shapes_sub\">더 부드럽고 자연스러운 모양을 위해 표준 둥근 직사각형 대신 초타원을 사용하세요.</string>\n    <string name=\"shape_type\">모양 유형</string>\n    <string name=\"cut\">자르다</string>\n    <string name=\"rounded\">둥근</string>\n    <string name=\"smooth\">매끄러운</string>\n    <string name=\"cut_shapes_sub\">둥글게 뭉치지 않고 날카로운 모서리</string>\n    <string name=\"rounded_shapes_sub\">클래식한 둥근 모서리</string>\n    <string name=\"shapes_type\">모양 유형</string>\n    <string name=\"corners_size\">모서리 크기</string>\n    <string name=\"squircle\">다람쥐</string>\n    <string name=\"squircle_shapes_sub\">우아한 둥근 UI 요소</string>\n    <string name=\"filename_format\">파일 이름 형식</string>\n    <string name=\"prefix_pattern_description\">파일 이름 맨 앞에 배치되는 사용자 정의 텍스트로 프로젝트 이름, 브랜드 또는 개인 태그에 적합합니다.</string>\n    <string name=\"original_filename_pattern_description\">확장자 없이 원본 파일 이름을 사용하므로 소스 식별을 그대로 유지하는 데 도움이 됩니다.</string>\n    <string name=\"width_pattern_description\">해상도 변경을 추적하거나 결과를 조정하는 데 유용한 이미지 너비(픽셀)입니다.</string>\n    <string name=\"height_pattern_description\">픽셀 단위의 이미지 높이. 종횡비 작업이나 내보내기 작업 시 유용합니다.</string>\n    <string name=\"random_numbers_pattern_description\">고유한 파일 이름을 보장하기 위해 임의의 숫자를 생성합니다. 중복에 대한 추가 안전을 위해 더 많은 숫자를 추가하십시오.</string>\n    <string name=\"sequence_number_pattern_description\">일괄 내보내기를 위한 자동 증가 카운터로, 한 세션에서 여러 이미지를 저장할 때 이상적입니다.</string>\n    <string name=\"preset_info_pattern_description\">적용된 프리셋 이름을 파일 이름에 삽입하여 이미지 처리 방법을 쉽게 기억할 수 있습니다.</string>\n    <string name=\"scale_mode_pattern_description\">처리 중에 사용되는 이미지 크기 조정 모드를 표시하여 크기가 조정되거나 잘리거나 맞는 이미지를 구별하는 데 도움이 됩니다.</string>\n    <string name=\"suffix_pattern_description\">파일 이름 끝에 배치된 사용자 정의 텍스트는 _v2, _edited 또는 _final과 같은 버전 관리에 유용합니다.</string>\n    <string name=\"extension_pattern_description\">파일 확장자(png, jpg, webp 등)는 실제 저장된 형식과 자동으로 일치합니다.</string>\n    <string name=\"formatted_timestamp_pattern_description\">완벽한 정렬을 위해 Java 사양에 따라 고유한 형식을 정의할 수 있는 사용자 정의 가능한 타임스탬프입니다.</string>\n    <string name=\"fling_type\">플링타입</string>\n    <string name=\"android_native\">안드로이드 네이티브</string>\n    <string name=\"ios_style\">iOS 스타일</string>\n    <string name=\"smooth_curve\">부드러운 곡선</string>\n    <string name=\"quick_stop\">급정지</string>\n    <string name=\"bouncy\">탄력</string>\n    <string name=\"floaty\">뜨는</string>\n    <string name=\"snappy\">팔팔한</string>\n    <string name=\"ultra_smooth\">울트라 스무스</string>\n    <string name=\"adaptive\">적응형</string>\n    <string name=\"accessibility_aware\">접근성 인식</string>\n    <string name=\"reduced_motion\">움직임 감소</string>\n    <string name=\"android_native_sub\">기준선 비교를 위한 기본 Android 스크롤 물리학</string>\n    <string name=\"smooth_sub\">일반적인 사용을 위한 균형 있고 부드러운 스크롤</string>\n    <string name=\"ios_style_sub\">마찰이 더 높은 iOS와 유사한 스크롤 동작</string>\n    <string name=\"smooth_curve_sub\">독특한 스크롤 느낌을 위한 독특한 스플라인 곡선</string>\n    <string name=\"quick_stop_sub\">빠른 정지로 정확한 스크롤</string>\n    <string name=\"bouncy_sub\">재미있고 반응성이 뛰어난 탄력 있는 스크롤</string>\n    <string name=\"floaty_sub\">콘텐츠 탐색을 위한 길고 미끄러지는 스크롤</string>\n    <string name=\"snappy_sub\">대화형 UI를 위한 빠르고 반응성이 뛰어난 스크롤</string>\n    <string name=\"ultra_smooth_sub\">확장된 추진력을 갖춘 프리미엄 부드러운 스크롤링</string>\n    <string name=\"adaptive_sub\">플링 속도에 따라 물리학을 조정합니다.</string>\n    <string name=\"accessibility_aware_sub\">시스템 접근성 설정을 존중합니다.</string>\n    <string name=\"reduced_motion_sub\">접근성 요구 사항에 맞는 최소한의 동작</string>\n    <string name=\"primary_lines\">기본 라인</string>\n    <string name=\"primary_lines_sub\">다섯 번째 줄마다 더 두꺼운 줄을 추가합니다.</string>\n    <string name=\"fill_color\">채우기 색상</string>\n    <string name=\"hidden_tools\">숨겨진 도구</string>\n    <string name=\"hidden_for_share\">공유를 위해 숨겨진 도구</string>\n    <string name=\"color_library\">컬러 라이브러리</string>\n    <string name=\"color_library_sub\">다양한 색상 컬렉션을 살펴보세요</string>\n    <string name=\"model_fatality_deblur\">자연스러운 디테일을 유지하면서 이미지의 흐림을 선명하게 하고 제거하여 초점이 맞지 않는 사진을 수정하는 데 이상적입니다.</string>\n    <string name=\"model_unresize_v3\">이전에 크기가 조정된 이미지를 지능적으로 복원하여 손실된 세부 정보와 질감을 복구합니다.</string>\n    <string name=\"model_liveaction_v1_span\">실사 콘텐츠에 최적화되어 압축 아티팩트를 줄이고 영화/TV 쇼 프레임의 미세한 디테일을 향상시킵니다.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS 품질의 영상을 HD로 변환하여 빈티지 느낌을 유지하면서 테이프 노이즈를 제거하고 해상도를 향상시킵니다.</string>\n    <string name=\"model_text2hd_v1\">텍스트가 많은 이미지와 스크린샷에 특화되어 문자를 선명하게 하고 가독성을 높입니다.</string>\n    <string name=\"model_frankendata_pretrainer\">다양한 데이터 세트에 대해 훈련된 고급 업스케일링으로 범용 사진 향상에 탁월합니다.</string>\n    <string name=\"model_realwebphoto_v2\">웹 압축 사진에 최적화되어 JPEG 아티팩트를 제거하고 자연스러운 모습을 복원합니다.</string>\n    <string name=\"model_realwebphoto_v4\">더 나은 질감 보존 및 아티팩트 감소 기능을 갖춘 웹 사진용 개선 버전입니다.</string>\n    <string name=\"model_dat_2x\">Dual Aggregation Transformer 기술로 2배 업스케일링하여 선명도와 자연스러운 디테일을 유지합니다.</string>\n    <string name=\"model_dat_3x\">고급 트랜스포머 아키텍처를 사용한 3배 업스케일링으로 적당한 확장 요구 사항에 이상적입니다.</string>\n    <string name=\"model_dat_4x\">최첨단 변압기 네트워크를 통한 4배 고품질 업스케일링으로 더 큰 규모에서도 미세한 디테일을 보존합니다.</string>\n    <string name=\"model_nafnet_deblurring\">사진에서 흐림/노이즈 및 흔들림을 제거합니다. 일반적인 용도이지만 사진에 가장 적합합니다.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">BSRGAN 저하에 최적화된 Swin2SR 변환기를 사용하여 저품질 이미지를 복원합니다. 과도한 압축 아티팩트를 수정하고 4배율로 디테일을 향상시키는 데 적합합니다.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN 저하에 대해 훈련된 SwinIR 변환기를 사용한 4배 업스케일링. 사진과 복잡한 장면에서 더 선명한 질감과 더 자연스러운 디테일을 위해 GAN을 사용합니다.</string>\n    <string name=\"path\">길</string>\n    <string name=\"merge_pdf\">PDF 병합</string>\n    <string name=\"merge_pdf_sub\">여러 PDF 파일을 하나의 문서로 결합</string>\n    <string name=\"files_order\">파일 순서</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">PDF 분할</string>\n    <string name=\"split_pdf_sub\">PDF 문서에서 특정 페이지 추출</string>\n    <string name=\"rotate_pdf\">PDF 회전</string>\n    <string name=\"rotate_pdf_sub\">페이지 방향을 영구적으로 수정</string>\n    <string name=\"pages\">페이지</string>\n    <string name=\"rearrange_pdf\">PDF 재정렬</string>\n    <string name=\"rearrange_pdf_sub\">페이지를 드래그 앤 드롭하여 재정렬하세요.</string>\n    <string name=\"hold_drag_drop\">페이지 유지 및 드래그</string>\n    <string name=\"page_numbers\">페이지 번호</string>\n    <string name=\"page_numbers_sub\">문서에 자동으로 번호 매기기 추가</string>\n    <string name=\"label_format\">라벨 형식</string>\n    <string name=\"pdf_to_text\">PDF를 텍스트로(OCR)</string>\n    <string name=\"pdf_to_text_sub\">PDF 문서에서 일반 텍스트 추출</string>\n    <string name=\"watermark_pdf_sub\">브랜딩 또는 보안을 위한 오버레이 사용자 정의 텍스트</string>\n    <string name=\"signature\">서명</string>\n    <string name=\"signature_sub\">모든 문서에 전자 서명을 추가하세요</string>\n    <string name=\"will_be_for_signature\">서명으로 사용됩니다.</string>\n    <string name=\"unlock_pdf\">PDF 잠금해제</string>\n    <string name=\"unlock_pdf_sub\">보호된 파일에서 비밀번호를 제거하세요</string>\n    <string name=\"protect_pdf\">PDF 보호</string>\n    <string name=\"protect_pdf_sub\">강력한 암호화로 문서를 보호하세요</string>\n    <string name=\"success\">성공</string>\n    <string name=\"pdf_unlocked\">PDF가 잠금 해제되었습니다. 저장하거나 공유할 수 있습니다.</string>\n    <string name=\"repair_pdf\">PDF 복구</string>\n    <string name=\"repair_pdf_sub\">손상되었거나 읽을 수 없는 문서를 수정하려고 시도합니다.</string>\n    <string name=\"grayscale\">그레이스케일</string>\n    <string name=\"grayscale_pdf_sub\">문서에 포함된 모든 이미지를 회색조로 변환</string>\n    <string name=\"compress_pdf\">PDF 압축</string>\n    <string name=\"compress_pdf_sub\">더 쉽게 공유할 수 있도록 문서 파일 크기를 최적화하세요.</string>\n    <string name=\"repair_info\">ImageToolbox는 내부 상호 참조 테이블을 다시 작성하고 파일 구조를 처음부터 다시 생성합니다. 이렇게 하면 \\\\\"열 수 없는\\\\\" 많은 파일에 대한 액세스를 복원할 수 있습니다.</string>\n    <string name=\"grayscale_info\">이 도구는 모든 문서 이미지를 회색조로 변환합니다. 인쇄 및 파일 크기 축소에 가장 적합</string>\n    <string name=\"metadata\">메타데이터</string>\n    <string name=\"metadata_pdf_sub\">더 나은 개인 정보 보호를 위해 문서 속성 편집</string>\n    <string name=\"tags\">태그</string>\n    <string name=\"producer\">생산자</string>\n    <string name=\"author\">작가</string>\n    <string name=\"keywords\">키워드</string>\n    <string name=\"creator\">창조자</string>\n    <string name=\"privacy_deep_clean\">개인 정보 보호 딥 클린</string>\n    <string name=\"privacy_deep_clean_sub\">이 문서에 사용 가능한 모든 메타데이터 지우기</string>\n    <string name=\"page\">페이지</string>\n    <string name=\"deep_ocr\">깊은 OCR</string>\n    <string name=\"deep_ocr_sub\">Tesseract 엔진을 사용하여 문서에서 텍스트를 추출하고 하나의 텍스트 파일에 저장합니다.</string>\n    <string name=\"cant_remove_all\">모든 페이지를 제거할 수 없습니다</string>\n    <string name=\"remove_pages_pdf\">PDF 페이지 제거</string>\n    <string name=\"remove_pages_pdf_sub\">PDF 문서에서 특정 페이지 제거</string>\n    <string name=\"tap_to_remove\">삭제하려면 탭하세요.</string>\n    <string name=\"manually\">수동으로</string>\n    <string name=\"crop_pdf\">PDF 자르기</string>\n    <string name=\"crop_pdf_sub\">문서 페이지를 원하는 대로 자르기</string>\n    <string name=\"flatten_pdf\">PDF를 병합</string>\n    <string name=\"flatten_pdf_sub\">문서 페이지를 래스터링하여 PDF를 수정할 수 없게 만듭니다.</string>\n    <string name=\"camera_failed_to_open\">카메라를 시작할 수 없습니다. 권한을 확인하고 다른 앱에서 사용하고 있지 않은지 확인하세요.</string>\n    <string name=\"extract_images\">이미지 추출</string>\n    <string name=\"extract_images_sub\">PDF에 포함된 이미지를 원래 해상도로 추출</string>\n    <string name=\"pdf_no_embedded\">이 PDF 파일에는 삽입된 이미지가 없습니다.</string>\n    <string name=\"extract_images_info\">이 도구는 모든 페이지를 스캔하고 최고 품질의 소스 이미지를 복구합니다. 문서의 원본을 저장하는 데 적합합니다.</string>\n    <string name=\"draw_signature\">서명 그리기</string>\n    <string name=\"pen_params\">펜 매개변수</string>\n    <string name=\"draw_signature_sub\">자신의 서명을 이미지로 사용하여 문서에 배치</string>\n    <string name=\"zip_pdf\">PDF 압축</string>\n    <string name=\"zip_pdf_sub\">주어진 간격으로 문서를 분할하고 새 문서를 zip 아카이브로 압축합니다.</string>\n    <string name=\"interval\">간격</string>\n    <string name=\"print_pdf\">PDF 인쇄</string>\n    <string name=\"print_pdf_sub\">사용자 정의 페이지 크기로 인쇄할 문서 준비</string>\n    <string name=\"pages_per_sheet\">시트당 페이지 수</string>\n    <string name=\"orientation\">정위</string>\n    <string name=\"page_size\">페이지 크기</string>\n    <string name=\"margin\">여유</string>\n    <string name=\"bloom\">꽃</string>\n    <string name=\"soft_knee\">소프트니</string>\n    <string name=\"model_realesr_animevideo_v3x4\">애니메이션과 만화에 최적화되어 있습니다. 자연스러운 색상이 향상되고 아티팩트가 적어 빠른 확장이 가능합니다.</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 같은 스타일</string>\n    <string name=\"calculate_hint\">여기에 기본 수학 기호를 입력하여 원하는 값을 계산하세요(예: (5+5)*10)</string>\n    <string name=\"math_expression\">수학 표현</string>\n    <string name=\"pick_up_to_n_collage_images\">최대 %1$s 이미지 선택</string>\n    <string name=\"background_color_for_alpha_formats\">알파 형식의 배경색</string>\n    <string name=\"background_color_for_alpha_formats_sub\">알파 지원이 포함된 모든 이미지 형식에 배경색을 설정하는 기능을 추가합니다. 이 기능을 비활성화하면 알파가 아닌 형식에만 사용할 수 있습니다.</string>\n    <string name=\"keep_date_time\">날짜 시간 유지</string>\n    <string name=\"keep_date_time_sub\">날짜 및 시간과 관련된 EXIF ​​태그를 항상 유지하며, EXIF ​​유지 옵션과 독립적으로 작동합니다.</string>\n    <string name=\"open_markup_project\">프로젝트 열기</string>\n    <string name=\"open_markup_project_sub\">이전에 저장한 Image Toolbox 프로젝트 계속 편집</string>\n    <string name=\"markup_project_open_failed\">이미지 도구 상자 프로젝트를 열 수 없습니다</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox 프로젝트에 프로젝트 데이터가 없습니다.</string>\n    <string name=\"markup_project_corrupted\">이미지 도구 상자 프로젝트가 손상되었습니다</string>\n    <string name=\"unsupported_markup_project_version\">지원되지 않는 Image Toolbox 프로젝트 버전: %1$d</string>\n    <string name=\"save_markup_project\">프로젝트 저장</string>\n    <string name=\"save_markup_project_sub\">편집 가능한 프로젝트 파일에 레이어, 배경 및 편집 기록 저장</string>\n    <string name=\"failed_to_open\">열지 못했습니다.</string>\n    <string name=\"ocr_write_to_searchable_pdf\">검색 가능한 PDF에 쓰기</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">이미지 일괄에서 텍스트를 인식하고 이미지 및 선택 가능한 텍스트 레이어와 함께 검색 가능한 PDF를 저장합니다.</string>\n    <string name=\"layer_alpha\">레이어 알파</string>\n    <string name=\"horizontal_flip\">수평 뒤집기</string>\n    <string name=\"vertical_flip\">수직 뒤집기</string>\n    <string name=\"lock\">잠그다</string>\n    <string name=\"add_shadow\">그림자 추가</string>\n    <string name=\"shadow_color\">그림자 색상</string>\n    <string name=\"text_geometry\">텍스트 기하학</string>\n    <string name=\"text_geometry_sub\">더 선명한 스타일을 위해 텍스트를 늘리거나 기울입니다.</string>\n    <string name=\"scale_x\">스케일 X</string>\n    <string name=\"skew_x\">기울이기 X</string>\n    <string name=\"remove_annotations\">주석 제거</string>\n    <string name=\"remove_annotations_sub\">PDF 페이지에서 링크, 주석, 강조 표시, 모양 또는 양식 필드와 같은 선택한 주석 유형을 제거합니다.</string>\n    <string name=\"annotation_link\">하이퍼링크</string>\n    <string name=\"annotation_file_attachment\">파일 첨부</string>\n    <string name=\"annotation_line\">윤곽</string>\n    <string name=\"annotation_popup\">팝업</string>\n    <string name=\"annotation_stamp\">우표</string>\n    <string name=\"annotation_shapes\">모양</string>\n    <string name=\"annotation_text\">텍스트 참고</string>\n    <string name=\"annotation_text_markup\">텍스트 마크업</string>\n    <string name=\"annotation_widget\">양식 필드</string>\n    <string name=\"annotation_markup\">마크업</string>\n    <string name=\"annotation_unknown\">알려지지 않은</string>\n    <string name=\"annotations\">주석</string>\n    <string name=\"ungroup\">그룹 해제</string>\n    <string name=\"add_shadow_sub\">구성 가능한 색상과 오프셋을 사용하여 레이어 뒤에 흐림 그림자 추가</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-lt/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"single_edit\">Vienas redagavimas</string>\n    <string name=\"create_shortcut_title\">Pasirinkite įrankį, kurį prisegti</string>\n    <string name=\"smth_went_wrong\">Kažkas nutiko ne taip: %1$s.</string>\n    <string name=\"size\">%1$s dydis</string>\n    <string name=\"loading\">Įkeliama…</string>\n    <string name=\"image_too_large_preview\">Vaizdas per didelis, kad būtų galima peržiūrėti, bet vis tiek bus bandoma išsaugoti.</string>\n    <string name=\"pick_image\">Pasirinkite vaizdą, kad pradėtumėte</string>\n    <string name=\"width\">%1$s plotis</string>\n    <string name=\"height\">%1$s aukštis</string>\n    <string name=\"quality\">Kokybė</string>\n    <string name=\"extension\">Plėtinys</string>\n    <string name=\"single_edit_sub\">Modifikuokite, keiskite dydį ir redaguokite vieną vaizdą.</string>\n    <string name=\"update\">Atnaujinti</string>\n    <string name=\"check_updates\">Tikrinti naujinimus</string>\n    <string name=\"tool_exit_confirmation_sub\">Jei naudodami tam tikrus įrankius turite neišsaugotų pakeitimų ir bandote juos užverti, bus rodomas patvirtinimo dialogas.</string>\n    <string name=\"tool_exit_confirmation\">Įrankio išėjimo patvirtinimas</string>\n    <string name=\"pages_selection\">Puslapių pasirinkimas</string>\n    <string name=\"custom_pages\">Pasirinktiniai puslapiai</string>\n    <string name=\"check_source_code_sub\">Gaukite naujausius naujinimus, aptarkite problemas ir daugiau.</string>\n    <string name=\"no_updates\">Naujinimų nerasta</string>\n    <string name=\"updates\">Naujinimai</string>\n    <string name=\"search_here\">Ieškokite čia</string>\n    <string name=\"check_updates_sub\">Jei įjungta, naujinimo dialogo langas bus rodomas paleidžiant programėlę.</string>\n    <string name=\"lut_library_update_sub\">Atnaujinti LUT kolekciją (į eilę bus įtraukti tik nauji), kurią galėsite taikyti atsisiuntę.</string>\n    <string name=\"tg_chat_sub\">Aptarkite programėlę ir gaukite kitų naudotojų atsiliepimų. Čia taip pat galite gauti beta versijos naujinimų ir įžvalgų.</string>\n    <string name=\"check_for_updates\">Tikrinti, ar yra naujinimų</string>\n    <string name=\"allow_betas_sub\">Jei įjungta, į naujinimų tikrinimą bus įtrauktos beta programėlės versijos.</string>\n    <string name=\"foss_update_checker_warning\">Šis naujinimų tikrintuvas prisijungs prie „GitHub“, kad patikrintų, ar yra naujas naujinimas.</string>\n    <string name=\"nothing_found_by_search\">Nieko nerasta pagal jūsų užklausą</string>\n    <string name=\"by_bytes_resize_sub\">Pakeiskite vaizdo dydį pagal nurodytą dydį vienetu KB.</string>\n    <string name=\"resize_type\">Keisti dydžio tipą</string>\n    <string name=\"by_bytes_resize\">Keisti dydį pagal svorį</string>\n    <string name=\"max_bytes\">Didžiausias dydis vienetu KB</string>\n    <string name=\"donation_sub\">Ši programa yra visiškai nemokama, bet jei norite paremti projekto kūrimą, galite spustelėti čia.</string>\n    <string name=\"contact_me\">Susisiekite su manimi</string>\n    <string name=\"donation\">Aukojimas</string>\n    <string name=\"search_option\">Paieška</string>\n    <string name=\"search_option_sub\">Suteikia galimybę ieškoti visų pagrindiniame ekrane esančių įrankių.</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Junkitės prie mūsų pokalbio, kuriame galite aptarti viską, ką norite, ir taip pat pažvelkite į CI kanalą, kuriame skelbiu beta versijas ir skelbimus.</string>\n    <string name=\"reset_settings_sub\">Tai sugrąžins jūsų nustatymus į numatytąsias reikšmes. Atkreipkite dėmesį, kad to negalima anuliuoti be pirmiau minėto atsarginės kopijos failo.</string>\n    <string name=\"send_logs\">Siųsti žurnalus</string>\n    <string name=\"send_logs_sub\">Spustelėkite norint bendrinti programėlės žurnalų failą. Tai gali padėti man pastebėti ir išspręsti problemas.</string>\n    <string name=\"close\">Užverti</string>\n    <string name=\"reset\">Nustatyti iš naujo</string>\n    <string name=\"check_source_code\">Šaltinio kodas</string>\n    <string name=\"about_app\">Apie programėlę</string>\n    <string name=\"tg_chat\">„Telegram“ pokalbis</string>\n    <string name=\"restore\">Atkurti</string>\n    <string name=\"restore_sub\">Atkurkite programėlės nustatymus iš anksčiau sugeneruoto failo.</string>\n    <string name=\"allow_betas\">Leisti beta versijų</string>\n    <string name=\"ci_channel\">CI kanalas</string>\n    <string name=\"group\">Grupė</string>\n    <string name=\"image_toolbox_in_telegram\">„Image Toolbox“ programėlėje „Telegram“ 🎉</string>\n    <string name=\"ci_channel_sub\">Gaukite pranešimų apie naujas programėlės versijas ir skaitykite skelbimus.</string>\n    <string name=\"crash_subtitle\">Galite susisiekti su manimi naudojant žemiau nurodytas parinktis ir aš bandysiu surasti sprendimą.\\n\\n(Nepamirškite pridėti žurnalus).</string>\n    <string name=\"explicit\">Aiškus</string>\n    <string name=\"flexible\">Lankstus</string>\n    <string name=\"pick_image_alt\">Pasirinkite vaizdą</string>\n    <string name=\"app_closing_sub\">Ar tikrai norite užverti programą?</string>\n    <string name=\"app_closing\">Programa užveriama</string>\n    <string name=\"stay\">Likti</string>\n    <string name=\"reset_image\">Nustatyti iš naujo vaizdą</string>\n    <string name=\"reset_image_sub\">Vaizdo pakeitimai bus grąžinti į pradines reikšmes.</string>\n    <string name=\"values_reset\">Reikšmės tinkamai iš naujo nustatytos.</string>\n    <string name=\"something_went_wrong\">Kažkas nutiko</string>\n    <string name=\"restart_app\">Paleisti programą iš naujo</string>\n    <string name=\"copied\">Nukopijuota į iškarpinę.</string>\n    <string name=\"exception\">Išimtis</string>\n    <string name=\"edit_exif\">Redaguoti EXIF</string>\n    <string name=\"ok\">Gerai</string>\n    <string name=\"no_exif\">EXIF duomenų nerasta.</string>\n    <string name=\"add_tag\">Pridėti žymę</string>\n    <string name=\"save\">Išsaugoti</string>\n    <string name=\"clear\">Valyti</string>\n    <string name=\"clear_exif\">Valyti EXIF</string>\n    <string name=\"cancel\">Atšaukti</string>\n    <string name=\"clear_exif_sub\">Visi vaizdo EXIF duomenys bus ištrinti. Šio veiksmo anuliuoti negalima.</string>\n    <string name=\"presets\">Išankstiniai nustatymai</string>\n    <string name=\"crop\">Apkirpti</string>\n    <string name=\"image_not_saved\">Išsaugoma</string>\n    <string name=\"image_not_saved_sub\">Jei dabar išeisite, visi neišsaugoti pakeitimai bus prarasti.</string>\n    <string name=\"pick_color\">Spalvų parinkiklis</string>\n    <string name=\"pick_color_sub\">Pasirinkite spalvą iš vaizdo, nukopijuokite arba bendrinkite.</string>\n    <string name=\"image\">Vaizdas</string>\n    <string name=\"color\">Spalva</string>\n    <string name=\"color_copied\">Spalva nukopijuota</string>\n    <string name=\"crop_sub\">Apkirpkite vaizdą iki bet kokių ribų.</string>\n    <string name=\"version\">Versija</string>\n    <string name=\"keep_exif\">Išlaikyti EXIF</string>\n    <string name=\"images\">Vaizdai: %d</string>\n    <string name=\"change_preview\">Keisti peržiūrą</string>\n    <string name=\"remove\">Šalinti</string>\n    <string name=\"palette_sub\">Generuokite spalvų paletės pavyzdį iš nurodyto vaizdo.</string>\n    <string name=\"generate_palette\">Generuoti paletę</string>\n    <string name=\"palette\">Paletė</string>\n    <string name=\"new_version\">Nauja versija %1$s</string>\n    <string name=\"unsupported_type\">Nepalaikomas tipas: %1$s</string>\n    <string name=\"no_palette\">Nepavyko sugeneruoti paletės nurodytam vaizdui.</string>\n    <string name=\"original\">Originalus</string>\n    <string name=\"folder\">Išvesties aplankas</string>\n    <string name=\"def\">Numatytoji</string>\n    <string name=\"custom\">Pasirinktinis</string>\n    <string name=\"unspecified\">Nenurodyta</string>\n    <string name=\"device_storage\">Įrenginio saugykla</string>\n    <string name=\"compare\">Palyginti</string>\n    <string name=\"compare_sub\">Palyginkite du pateiktus vaizdus</string>\n    <string name=\"pick_two_images\">Norėdami pradėti, pasirinkite du vaizdus</string>\n    <string name=\"pick_images\">Pasirinkite vaizdus</string>\n    <string name=\"settings\">Nustatymai</string>\n    <string name=\"night_mode\">Naktinis režimas</string>\n    <string name=\"dark\">Tamsus</string>\n    <string name=\"light\">Šviesa</string>\n    <string name=\"system\">Sistema</string>\n    <string name=\"dynamic_colors\">Dinaminės spalvos</string>\n    <string name=\"customization\">Tinkinimas</string>\n    <string name=\"allow_image_monet\">Leisti vaizdo pinigų</string>\n    <string name=\"allow_image_monet_sub\">Jei įjungta, kai pasirenkate redaguotiną vaizdą, programos spalvos bus pritaikytos šiam vaizdui</string>\n    <string name=\"language\">Kalba</string>\n    <string name=\"amoled_mode\">Amoled režimas</string>\n    <string name=\"amoled_mode_sub\">Jei įjungta, nakties režimu paviršių spalva bus visiškai tamsi</string>\n    <string name=\"color_scheme\">Spalvų schema</string>\n    <string name=\"color_red\">Raudona</string>\n    <string name=\"color_green\">Žalia</string>\n    <string name=\"color_blue\">Mėlyna</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Įklijuokite tinkamą aRGB spalvos kodą</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nėra ką įklijuoti</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Programos spalvų schemos pakeisti negalima, kol įjungtos dinaminės spalvos</string>\n    <string name=\"pick_accent_color\">Programos tema bus pagrįsta pasirinkta spalva</string>\n    <string name=\"issue_tracker\">Problemų stebėjimo priemonė</string>\n    <string name=\"issue_tracker_sub\">Siųskite klaidų ataskaitas ir funkcijų užklausas čia</string>\n    <string name=\"help_translate\">Padėkite išversti</string>\n    <string name=\"help_translate_sub\">Ištaisykite vertimo klaidas arba lokalizuokite projektą kitomis kalbomis</string>\n    <string name=\"dynamic_colors_sub\">Jei įjungta, programos spalvos bus pritaikytos ekrano fono spalvoms</string>\n    <string name=\"failed_to_save\">Nepavyko išsaugoti %d vaizdo (-ų)</string>\n    <string name=\"email\">El. paštas</string>\n    <string name=\"primary\">Pirminis</string>\n    <string name=\"tertiary\">Tretinis</string>\n    <string name=\"secondary\">Antrinis</string>\n    <string name=\"border_thickness\">Krašto storis</string>\n    <string name=\"surface\">Paviršius</string>\n    <string name=\"values\">Vertybės</string>\n    <string name=\"add\">Pridėti</string>\n    <string name=\"permission\">Leidimas</string>\n    <string name=\"grant\">Suteikti</string>\n    <string name=\"permission_sub\">Programai reikia prieigos prie jūsų saugyklos, kad galėtų išsaugoti vaizdus, ​​​​kad veiktų, tai būtina. Suteikite leidimą kitame dialogo lange.</string>\n    <string name=\"grant_permission_manual\">Programai reikalingas šis leidimas, kad veiktų, suteikite jį rankiniu būdu</string>\n    <string name=\"external_storage\">Išorinė saugykla</string>\n    <string name=\"monet_colors\">Monet spalvos</string>\n    <string name=\"fab_alignment\">FAB lygiavimas</string>\n    <string name=\"zoom\">Vaizdo priartinimas</string>\n    <string name=\"share\">Dalintis</string>\n    <string name=\"prefix\">Priešdėlis</string>\n    <string name=\"filename\">Failo pavadinimas</string>\n    <string name=\"emoji\">Jaustukai</string>\n    <string name=\"emoji_sub\">Pasirinkite jaustukus, kuriuos norite rodyti pagrindiniame ekrane</string>\n    <string name=\"add_file_size\">Pridėti failo dydį</string>\n    <string name=\"add_file_size_sub\">Jei įjungta, prie išvesties failo pavadinimo pridedamas išsaugoto vaizdo plotis ir aukštis</string>\n    <string name=\"delete_exif\">Ištrinkite EXIF</string>\n    <string name=\"delete_exif_sub\">Ištrinkite EXIF ​​metaduomenis iš bet kurio vaizdų rinkinio</string>\n    <string name=\"image_preview\">Vaizdo peržiūra</string>\n    <string name=\"image_preview_sub\">Peržiūrėkite bet kokio tipo vaizdus: GIF, SVG ir pan</string>\n    <string name=\"image_source\">Vaizdo šaltinis</string>\n    <string name=\"photo_picker\">Nuotraukų rinkėjas</string>\n    <string name=\"gallery_picker\">Galerija</string>\n    <string name=\"file_explorer_picker\">Failų naršyklė</string>\n    <string name=\"photo_picker_sub\">„Android“ modernus nuotraukų rinkiklis, kuris rodomas ekrano apačioje, gali veikti tik 12 ir naujesnėse versijose „Android“. Iškilo problemų gaunant EXIF ​​metaduomenis</string>\n    <string name=\"gallery_picker_sub\">Paprastas galerijos vaizdų rinkiklis. Tai veiks tik tuo atveju, jei turite programą, kuri teikia medijos rinkimą</string>\n    <string name=\"file_explorer_picker_sub\">Norėdami pasirinkti vaizdą, naudokite „GetContent“ tikslą. Veikia visur, tačiau žinoma, kad kai kuriuose įrenginiuose kyla problemų gaunant pasirinktus vaizdus. Tai ne mano kaltė.</string>\n    <string name=\"options_arrangement\">Pasirinkimų išdėstymas</string>\n    <string name=\"edit\">Redaguoti</string>\n    <string name=\"order\">Užsakyti</string>\n    <string name=\"order_sub\">Nustato įrankių tvarką pagrindiniame ekrane</string>\n    <string name=\"emojis_count\">Jaustukų skaičius</string>\n    <string name=\"sequence_num\">sekaNum</string>\n    <string name=\"original_filename\">originalus failo pavadinimas</string>\n    <string name=\"add_original_filename\">Pridėkite originalų failo pavadinimą</string>\n    <string name=\"add_original_filename_sub\">Jei įjungta, į išvesties vaizdo pavadinimą įtraukiamas originalus failo pavadinimas</string>\n    <string name=\"replace_sequence_number\">Pakeiskite eilės numerį</string>\n    <string name=\"replace_sequence_number_sub\">Jei įjungta, standartinė laiko žyma pakeičiama vaizdo sekos numeriu, jei naudojate paketinį apdorojimą</string>\n    <string name=\"filename_not_work_with_photopicker\">Pradinio failo pavadinimo pridėjimas neveiks, jei pasirinktas nuotraukų rinkiklio vaizdo šaltinis</string>\n    <string name=\"load_image_from_net\">Interneto vaizdo įkėlimas</string>\n    <string name=\"load_image_from_net_sub\">Jei norite, įkelkite bet kurį vaizdą iš interneto, kad galėtumėte peržiūrėti, keisti mastelį, redaguoti ir išsaugoti.</string>\n    <string name=\"no_image\">Nėra vaizdo</string>\n    <string name=\"image_link\">Vaizdo nuoroda</string>\n    <string name=\"fill\">Užpildykite</string>\n    <string name=\"fit\">Tinka</string>\n    <string name=\"content_scale\">Turinio skalė</string>\n    <string name=\"explicit_description\">Pakeičia vaizdų dydį iki nurodyto aukščio ir pločio. Vaizdų formato santykis gali keistis.</string>\n    <string name=\"flexible_description\">Pakeičia ilgos kraštinės vaizdų dydį iki nurodyto aukščio arba pločio. Visi dydžio skaičiavimai bus atlikti po išsaugojimo. Vaizdų formato santykis bus išsaugotas.</string>\n    <string name=\"brightness\">Ryškumas</string>\n    <string name=\"contrast\">Kontrastas</string>\n    <string name=\"hue\">Atspalvis</string>\n    <string name=\"saturation\">Sodrumas</string>\n    <string name=\"add_filter\">Pridėti filtrą</string>\n    <string name=\"filter\">Filtruoti</string>\n    <string name=\"filter_sub\">Taikyti filtrų grandines vaizdams</string>\n    <string name=\"filters\">Filtrai</string>\n    <string name=\"light_aka_illumination\">Šviesa</string>\n    <string name=\"color_filter\">Spalvų filtras</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"exposure\">Poveikis</string>\n    <string name=\"white_balance\">Baltos spalvos balansas</string>\n    <string name=\"temperature\">Temperatūra</string>\n    <string name=\"tint\">Atspalvis</string>\n    <string name=\"monochrome\">Vienspalvis</string>\n    <string name=\"gamma\">Gama</string>\n    <string name=\"highlights_shadows\">Akcentai ir šešėliai</string>\n    <string name=\"highlights\">Akcentai</string>\n    <string name=\"shadows\">Šešėliai</string>\n    <string name=\"haze\">Migla</string>\n    <string name=\"effect\">Efektas</string>\n    <string name=\"distance\">Atstumas</string>\n    <string name=\"slope\">Šlaitas</string>\n    <string name=\"sharpen\">Galąsti</string>\n    <string name=\"sepia\">Sepija</string>\n    <string name=\"negative\">Neigiamas</string>\n    <string name=\"solarize\">Pasideginti</string>\n    <string name=\"vibrance\">Vibrance</string>\n    <string name=\"black_and_white\">Juoda ir balta</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">Tarpai</string>\n    <string name=\"line_width\">Linijos plotis</string>\n    <string name=\"sobel_edge\">Sobelio kraštas</string>\n    <string name=\"blur\">Suliejimas</string>\n    <string name=\"halftone\">Pustonis</string>\n    <string name=\"cga_colorspace\">CGA spalvų erdvė</string>\n    <string name=\"gaussian_blur\">Gauso neryškumas</string>\n    <string name=\"box_blur\">Dėžutės suliejimas</string>\n    <string name=\"bilaterial_blur\">Dvipusis suliejimas</string>\n    <string name=\"emboss\">Reljefinis</string>\n    <string name=\"laplacian\">laplakietis</string>\n    <string name=\"vignette\">Vinjetė</string>\n    <string name=\"start\">Pradėti</string>\n    <string name=\"end\">Pabaiga</string>\n    <string name=\"kuwahara\">Kuwahara lyginimas</string>\n    <string name=\"stack_blur\">Stack suliejimas</string>\n    <string name=\"radius\">Spindulys</string>\n    <string name=\"scale\">Skalė</string>\n    <string name=\"distortion\">Iškraipymas</string>\n    <string name=\"angle\">Kampas</string>\n    <string name=\"swirl\">Sūkurys</string>\n    <string name=\"bulge\">Išsipūtimas</string>\n    <string name=\"dilation\">Išsiplėtimas</string>\n    <string name=\"sphere_refraction\">Sferos refrakcija</string>\n    <string name=\"refractive_index\">Lūžio rodiklis</string>\n    <string name=\"glass_sphere_refraction\">Stiklo sferos refrakcija</string>\n    <string name=\"color_matrix\">Spalvų matrica</string>\n    <string name=\"opacity\">Neskaidrumas</string>\n    <string name=\"limits_resize\">Keisti dydį pagal ribas</string>\n    <string name=\"limits_resize_sub\">Pakeiskite vaizdų dydį iki nurodyto aukščio ir pločio, išlaikydami formato santykį</string>\n    <string name=\"sketch\">Eskizas</string>\n    <string name=\"threshold\">Slenkstis</string>\n    <string name=\"quantizationLevels\">Kvantavimo lygiai</string>\n    <string name=\"smooth_toon\">Lygus tonas</string>\n    <string name=\"toon\">Toonas</string>\n    <string name=\"posterize\">Plakatas</string>\n    <string name=\"non_maximum_suppression\">Ne maksimalus slopinimas</string>\n    <string name=\"weak_pixel_inclusion\">Silpnas pikselių įtraukimas</string>\n    <string name=\"lookup\">Ieškoti</string>\n    <string name=\"convolution3x3\">Konvoliucija 3x3</string>\n    <string name=\"rgb_filter\">RGB filtras</string>\n    <string name=\"false_color\">Klaidinga spalva</string>\n    <string name=\"first_color\">Pirmoji spalva</string>\n    <string name=\"second_color\">Antra spalva</string>\n    <string name=\"reorder\">Pertvarkyti</string>\n    <string name=\"fast_blur\">Greitas suliejimas</string>\n    <string name=\"blur_size\">Suliejimo dydis</string>\n    <string name=\"blur_center_x\">Sulieti centrą x</string>\n    <string name=\"blur_center_y\">Suliejimo centras y</string>\n    <string name=\"zoom_blur\">Mastelio suliejimas</string>\n    <string name=\"color_balance\">Spalvų balansas</string>\n    <string name=\"luminance_threshold\">Skaisčio slenkstis</string>\n    <string name=\"activate_files\">Išjungėte programą „Failai“, suaktyvinkite ją, kad galėtumėte naudotis šia funkcija</string>\n    <string name=\"draw\">Lygiosios</string>\n    <string name=\"draw_sub\">Pieškite ant paveikslėlio kaip eskizų knygelėje arba pieškite pačiame fone</string>\n    <string name=\"paint_color\">Dažų spalva</string>\n    <string name=\"paint_alpha\">Dažai alfa</string>\n    <string name=\"draw_on_image\">Pieškite ant paveikslėlio</string>\n    <string name=\"draw_on_image_sub\">Pasirinkite paveikslėlį ir nupieškite ką nors ant jo</string>\n    <string name=\"draw_on_background\">Pieškite fone</string>\n    <string name=\"draw_on_background_sub\">Pasirinkite fono spalvą ir pieškite ant jos</string>\n    <string name=\"background_color\">Fono spalva</string>\n    <string name=\"cipher\">Šifravimas</string>\n    <string name=\"cipher_sub\">Šifruokite ir iššifruokite bet kurį failą (ne tik vaizdą), pagrįstą įvairiais prieinamais šifravimo algoritmais</string>\n    <string name=\"pick_file\">Pasirinkite failą</string>\n    <string name=\"encrypt\">Šifruoti</string>\n    <string name=\"decrypt\">Iššifruoti</string>\n    <string name=\"pick_file_to_start\">Norėdami pradėti, pasirinkite failą</string>\n    <string name=\"decryption\">Iššifravimas</string>\n    <string name=\"encryption\">Šifravimas</string>\n    <string name=\"key\">Raktas</string>\n    <string name=\"file_proceed\">Failas apdorotas</string>\n    <string name=\"store_file_desc\">Išsaugokite šį failą savo įrenginyje arba naudokite bendrinimo veiksmą, kad įdėtumėte jį kur norite</string>\n    <string name=\"features\">Savybės</string>\n    <string name=\"implementation\">Įgyvendinimas</string>\n    <string name=\"compatibility\">Suderinamumas</string>\n    <string name=\"features_sub\">Failų šifravimas slaptažodžiu. Tęsti failai gali būti saugomi pasirinktame kataloge arba bendrinami. Iššifruotus failus taip pat galima atidaryti tiesiogiai.</string>\n    <string name=\"implementation_sub\">AES-256, GCM režimas, be užpildymo, 12 baitų atsitiktiniai IV pagal numatytuosius nustatymus. Galite pasirinkti reikiamą algoritmą. Raktai naudojami kaip 256 bitų SHA-3 maišos</string>\n    <string name=\"file_size\">Failo dydis</string>\n    <string name=\"file_size_sub\">Didžiausią failo dydį riboja „Android“ OS ir turima atmintis, kuri priklauso nuo įrenginio.\n\\nAtkreipkite dėmesį: atmintis nėra saugykla.</string>\n    <string name=\"compatibility_sub\">Atminkite, kad suderinamumas su kita failų šifravimo programine įranga ar paslaugomis negarantuojamas. Šiek tiek kitoks raktų apdorojimas arba šifro konfigūracija gali sukelti nesuderinamumą.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Neteisingas slaptažodis arba pasirinktas failas nėra užšifruotas</string>\n    <string name=\"image_size_warning\">Bandant išsaugoti nurodyto pločio ir aukščio vaizdą, gali atsirasti atminties trūkumo klaida. Darykite tai savo rizika.</string>\n    <string name=\"cache\">Talpykla</string>\n    <string name=\"cache_size\">Talpyklos dydis</string>\n    <string name=\"found_s\">Rasta %1$s</string>\n    <string name=\"auto_cache_clearing\">Automatinis talpyklos išvalymas</string>\n    <string name=\"auto_cache_clearing_sub\">Jei įjungta, programos talpykla bus išvalyta paleidžiant programą</string>\n    <string name=\"create\">Sukurti</string>\n    <string name=\"tools\">Įrankiai</string>\n    <string name=\"group_options_by_type\">Grupuokite parinktis pagal tipą</string>\n    <string name=\"group_options_by_type_sub\">Grupuoja pagrindinio ekrano parinktis pagal jų tipą, o ne tinkintą sąrašo išdėstymą</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Negalima pakeisti išdėstymo, kai įjungtas parinkčių grupavimas</string>\n    <string name=\"edit_screenshot\">Redaguoti ekrano kopiją</string>\n    <string name=\"secondary_customization\">Antrinis pritaikymas</string>\n    <string name=\"screenshot\">Ekrano kopija</string>\n    <string name=\"fallback_option\">Atsarginis variantas</string>\n    <string name=\"skip\">Praleisti</string>\n    <string name=\"copy\">Kopijuoti</string>\n    <string name=\"warning_bytes\">Įrašymas %1$s režimu gali būti nestabilus, nes tai yra be nuostolių formatas</string>\n    <string name=\"presets_sub\">Jei pasirinkote išankstinį nustatymą 125, vaizdas bus išsaugotas kaip 125% pradinio vaizdo dydžio. Jei pasirinksite iš anksto nustatytą 50, vaizdas bus išsaugotas 50% dydžiu</string>\n    <string name=\"presets_sub_bytes\">Iš anksto nustatytas čia nustato išvesties failo %, t. y. jei pasirinksite iš anksto nustatytą 50 5 MB vaizde, tada išsaugoję gausite 2,5 MB vaizdą</string>\n    <string name=\"randomize_filename\">Atsitiktinai nustatyti failo pavadinimą</string>\n    <string name=\"randomize_filename_sub\">Jei įjungta, išvesties failo pavadinimas bus visiškai atsitiktinis</string>\n    <string name=\"saved_to\">Išsaugota %1$s aplanke pavadinimu %2$s</string>\n    <string name=\"saved_to_without_filename\">Išsaugota %1$s aplanke</string>\n    <string name=\"crop_mask\">Pasėlių kaukė</string>\n    <string name=\"aspect_ratio\">Kraštinių santykis</string>\n    <string name=\"image_crop_mask_sub\">Naudokite šį kaukės tipą, kad sukurtumėte kaukę iš pateikto vaizdo, atkreipkite dėmesį, kad jis TURI turėti alfa kanalą</string>\n    <string name=\"backup_and_restore\">Atsarginė kopija ir atkūrimas</string>\n    <string name=\"backup\">Atsarginė kopija</string>\n    <string name=\"backup_sub\">Kurkite atsarginę programos nustatymų kopiją į failą</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Sugadintas failas arba ne atsarginė kopija</string>\n    <string name=\"settings_restored\">Nustatymai sėkmingai atkurti</string>\n    <string name=\"delete\">Ištrinti</string>\n    <string name=\"delete_color_scheme_warn\">Ketinate ištrinti pasirinktą spalvų schemą. Šios operacijos anuliuoti negalima</string>\n    <string name=\"delete_color_scheme_title\">Ištrinti schemą</string>\n    <string name=\"font\">Šriftas</string>\n    <string name=\"text\">Tekstas</string>\n    <string name=\"font_scale\">Šrifto mastelis</string>\n    <string name=\"defaultt\">Numatytoji</string>\n    <string name=\"using_large_fonts_warn\">Naudojant didelius šrifto mastelius, gali kilti vartotojo sąsajos trikdžių ir problemų, kurios nebus ištaisytos. Naudokite atsargiai.</string>\n    <string name=\"alphabet_and_numbers\">Aa Ąą Bb Cc Čč Dd Ee Ęę Ėė Ff Gg Hh Ii Įį Yy Jj Kk Ll Mm Nn Oo Pp Rr Ss Šš Tt Uu Ųų Ūū Vv Zz Žž 0123456789 !?</string>\n    <string name=\"emotions\">Emocijos</string>\n    <string name=\"food_and_drink\">Maistas ir gėrimai</string>\n    <string name=\"nature_and_animals\">Gamta ir gyvūnai</string>\n    <string name=\"objects\">Objektai</string>\n    <string name=\"symbols\">Simboliai</string>\n    <string name=\"enable_emoji\">Įgalinti jaustukus</string>\n    <string name=\"travels_and_places\">Kelionės ir vietos</string>\n    <string name=\"activities\">Veikla</string>\n    <string name=\"background_remover\">Fono valiklis</string>\n    <string name=\"background_remover_sub\">Pašalinkite foną iš vaizdo piešdami arba naudokite parinktį Automatinis</string>\n    <string name=\"trim_image\">Apkarpyti vaizdą</string>\n    <string name=\"keep_exif_sub\">Originalūs vaizdo metaduomenys bus saugomi</string>\n    <string name=\"trim_image_sub\">Permatomos erdvės aplink vaizdą bus apkarpytos</string>\n    <string name=\"auto_erase_background\">Automatiškai ištrinti foną</string>\n    <string name=\"restore_image\">Atkurti vaizdą</string>\n    <string name=\"erase_mode\">Ištrynimo režimas</string>\n    <string name=\"erase_background\">Ištrinti foną</string>\n    <string name=\"restore_background\">Atkurti foną</string>\n    <string name=\"blur_radius\">Suliejimo spindulys</string>\n    <string name=\"pipette\">Pipete</string>\n    <string name=\"draw_mode\">Piešimo režimas</string>\n    <string name=\"create_issue\">Sukurti problemą</string>\n    <string name=\"something_went_wrong_emphasis\">Oi… Kažkas ne taip. Galite parašyti man naudodami toliau pateiktas parinktis ir aš pabandysiu rasti sprendimą</string>\n    <string name=\"resize_and_convert\">Keisti dydį ir konvertuoti</string>\n    <string name=\"resize_and_convert_sub\">Pakeiskite pateiktų vaizdų dydį arba konvertuokite juos į kitus formatus. Čia taip pat galima redaguoti EXIF ​​metaduomenis, jei pasirenkamas vienas vaizdas.</string>\n    <string name=\"max_colors_count\">Maksimalus spalvų skaičius</string>\n    <string name=\"crashlytics_sub\">Tai leidžia programai automatiškai rinkti gedimų ataskaitas</string>\n    <string name=\"analytics\">Analizė</string>\n    <string name=\"analytics_sub\">Leisti rinkti anoniminę programos naudojimo statistiką</string>\n    <string name=\"image_exif_warning\">Šiuo metu %1$s formatas leidžia skaityti tik EXIF ​​metaduomenis „Android“. Išsaugotas vaizdas iš viso neturės metaduomenų.</string>\n    <string name=\"effort\">Pastangos</string>\n    <string name=\"effort_sub\">%1$s reikšmė reiškia greitą suspaudimą, dėl kurio failas yra gana didelis. %2$s reiškia lėtesnį glaudinimą, todėl failas bus mažesnis.</string>\n    <string name=\"wait\">Palauk</string>\n    <string name=\"saving_almost_complete\">Išsaugojimas beveik baigtas. Atšaukus dabar, reikės dar kartą išsaugoti.</string>\n    <string name=\"draw_arrows\">Nubrėžkite rodykles</string>\n    <string name=\"draw_arrows_sub\">Jei įjungta, piešimo kelias bus rodomas kaip rodyklė</string>\n    <string name=\"brush_softness\">Šepetėlio minkštumas</string>\n    <string name=\"crop_description\">Nuotraukos bus apkarpytos centre iki įvesto dydžio. Drobė bus išplėsta naudojant nurodytą fono spalvą, jei vaizdas bus mažesnis nei įvesti matmenys.</string>\n    <string name=\"image_stitching\">Vaizdo susiuvimas</string>\n    <string name=\"image_stitching_sub\">Sujunkite pateiktus vaizdus, ​​​​kad gautumėte vieną didelį</string>\n    <string name=\"pick_at_least_two_images\">Pasirinkite bent 2 vaizdus</string>\n    <string name=\"output_image_scale\">Išvesties vaizdo skalė</string>\n    <string name=\"image_orientation\">Vaizdo orientacija</string>\n    <string name=\"horizontal\">Horizontaliai</string>\n    <string name=\"vertical\">Vertikalus</string>\n    <string name=\"scale_small_images_to_large\">Pakeiskite mažus vaizdus į didelius</string>\n    <string name=\"scale_small_images_to_large_sub\">Jei įjungta, mažų vaizdų mastelis bus padidintas iki didžiausio</string>\n    <string name=\"images_order\">Vaizdų tvarka</string>\n    <string name=\"regular\">Reguliarus</string>\n    <string name=\"blur_edges\">Sulieti kraštus</string>\n    <string name=\"blur_edges_sub\">Nupiešia neryškius kraštus po pradiniu vaizdu, kad užpildytų tarpus aplink jį, o ne viena spalva, jei įjungta</string>\n    <string name=\"pixelation\">Pikseliacija</string>\n    <string name=\"enhanced_pixelation\">Patobulintas pikseliavimas</string>\n    <string name=\"stroke_pixelation\">Brūkšnio pikseliavimas</string>\n    <string name=\"enhanced_diamond_pixelation\">Patobulintas deimantinis pikseliavimas</string>\n    <string name=\"diamond_pixelation\">Deimantinis pikseliavimas</string>\n    <string name=\"circle_pixelation\">Apskritimo pikseliavimas</string>\n    <string name=\"enhanced_circle_pixelation\">Patobulintas apskritimo pikseliavimas</string>\n    <string name=\"replace_color\">Pakeisti spalvą</string>\n    <string name=\"tolerance\">Tolerancija</string>\n    <string name=\"color_to_replace\">Spalva, kurią reikia pakeisti</string>\n    <string name=\"target_color\">Tikslinė spalva</string>\n    <string name=\"color_to_remove\">Pašalinti spalva</string>\n    <string name=\"remove_color\">Pašalinti spalvą</string>\n    <string name=\"recode\">Perkoduoti</string>\n    <string name=\"pixel_size\">Pikselių dydis</string>\n    <string name=\"lock_draw_orientation\">Užrakinti piešimo orientaciją</string>\n    <string name=\"lock_draw_orientation_sub\">Jei įjungta piešimo režimu, ekranas nesisuks</string>\n    <string name=\"palette_style\">Paletės stilius</string>\n    <string name=\"tonal_spot\">Toninė dėmė</string>\n    <string name=\"neutral\">Neutralus</string>\n    <string name=\"vibrant\">Gyvybingas</string>\n    <string name=\"expressive\">Išraiškingas</string>\n    <string name=\"rainbow\">Vaivorykštė</string>\n    <string name=\"fruit_salad\">Vaisių salotos</string>\n    <string name=\"fidelity\">Ištikimybė</string>\n    <string name=\"content\">Turinys</string>\n    <string name=\"tonal_spot_sub\">Numatytasis paletės stilius, leidžia pritaikyti visas keturias spalvas, kitos leidžia nustatyti tik rakto spalvą</string>\n    <string name=\"neutral_sub\">Stilius, kuris yra šiek tiek chromatiškesnis nei vienspalvis</string>\n    <string name=\"vibrant_sub\">Garsi tema, spalvingumas pirminei paletei maksimalus, kitiems padidintas</string>\n    <string name=\"playful_scheme\">Žaisminga tema – šaltinio spalvos atspalvis temoje nerodomas</string>\n    <string name=\"monochrome_sub\">Vienspalvė tema, spalvos yra grynai juoda / balta / pilka</string>\n    <string name=\"content_sub\">Schema, kuri įdeda šaltinio spalvą į Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Schema, kuri labai panaši į turinio schemą</string>\n    <string name=\"attention\">Dėmesio</string>\n    <string name=\"fading_edges\">Išblukę kraštai</string>\n    <string name=\"disabled\">Išjungta</string>\n    <string name=\"both\">Abu</string>\n    <string name=\"invert_colors\">Invertuoti spalvas</string>\n    <string name=\"invert_colors_sub\">Jei įjungta, temos spalvas pakeičia neigiamomis</string>\n    <string name=\"pdf_tools\">PDF įrankiai</string>\n    <string name=\"pdf_tools_sub\">Dirbkite su PDF failais: Peržiūrėkite, konvertuokite į vaizdų paketą arba sukurkite vieną iš pateiktų paveikslėlių</string>\n    <string name=\"preview_pdf\">Peržiūrėti PDF</string>\n    <string name=\"pdf_to_images\">PDF į vaizdus</string>\n    <string name=\"images_to_pdf\">Vaizdai į pdf</string>\n    <string name=\"preview_pdf_sub\">Paprasta PDF peržiūra</string>\n    <string name=\"pdf_to_images_sub\">Konvertuokite PDF į vaizdus nurodytu išvesties formatu</string>\n    <string name=\"images_to_pdf_sub\">Supakuokite pateiktus vaizdus į išvesties PDF failą</string>\n    <string name=\"mask_filter\">Kaukės filtras</string>\n    <string name=\"mask_filter_sub\">Taikykite filtrų grandines nurodytose užmaskuotose srityse, kiekviena kaukės sritis gali nustatyti savo filtrų rinkinį</string>\n    <string name=\"masks\">Kaukės</string>\n    <string name=\"add_mask\">Pridėti kaukę</string>\n    <string name=\"mask_indexed\">Kaukė %d</string>\n    <string name=\"mask_color\">Kaukės spalva</string>\n    <string name=\"mask_preview\">Kaukės peržiūra</string>\n    <string name=\"mask_preview_sub\">Nupiešta filtro kaukė bus atvaizduota, kad būtų rodomas apytikslis rezultatas</string>\n    <string name=\"inverse_fill_type\">Atvirkštinis užpildymo tipas</string>\n    <string name=\"inverse_fill_type_sub\">Jei įjungta, visos neužmaskuotos sritys bus filtruojamos vietoj numatytosios elgsenos</string>\n    <string name=\"delete_mask_warn\">Ketinate ištrinti pasirinktą filtro kaukę. Šios operacijos anuliuoti negalima</string>\n    <string name=\"delete_mask\">Ištrinti kaukę</string>\n    <string name=\"full_filter\">Pilnas filtras</string>\n    <string name=\"full_filter_sub\">Taikyti bet kokias filtrų grandines pateiktiems vaizdams arba vienam vaizdui</string>\n    <string name=\"start_position\">Pradėti</string>\n    <string name=\"center_position\">centras</string>\n    <string name=\"end_position\">Pabaiga</string>\n    <string name=\"simple_variants\">Paprasti variantai</string>\n    <string name=\"highlighter\">Paryškintuvas</string>\n    <string name=\"neon\">Neoninis</string>\n    <string name=\"pen\">Rašiklis</string>\n    <string name=\"privacy_blur\">Privatumo suliejimas</string>\n    <string name=\"highlighter_sub\">Nubrėžkite pusiau permatomus paryškintus žymeklio kelius</string>\n    <string name=\"neon_sub\">Pridėkite šiek tiek švytinčio efekto savo piešiniams</string>\n    <string name=\"pen_sub\">Numatytasis, paprasčiausias – tik spalva</string>\n    <string name=\"privacy_blur_sub\">Sulieja vaizdą po nupieštu keliu, kad apsaugotų viską, ką norite paslėpti</string>\n    <string name=\"pixelation_sub\">Panašus į privatumo suliejimą, bet vietoj suliejimo sukuria pikselius</string>\n    <string name=\"containers_shadow\">Konteineriai</string>\n    <string name=\"containers_shadow_sub\">Nubrėžkite šešėlį už konteinerių</string>\n    <string name=\"sliders_shadow\">Slankikliai</string>\n    <string name=\"switches_shadow\">Jungikliai</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">Mygtukai</string>\n    <string name=\"sliders_shadow_sub\">Nubrėžkite šešėlį už slankiklių</string>\n    <string name=\"switches_shadow_sub\">Nubrėžkite šešėlį už jungiklių</string>\n    <string name=\"fabs_shadow_sub\">Nubrėžkite šešėlį už slankiųjų veiksmų mygtukų</string>\n    <string name=\"buttons_shadow_sub\">Nubrėžkite šešėlį už mygtukų</string>\n    <string name=\"app_bars_shadow\">Programų juostos</string>\n    <string name=\"app_bars_shadow_sub\">Nubrėžkite šešėlį už programos juostų</string>\n    <string name=\"value_in_range\">Vertė diapazone %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Automatinis pasukimas</string>\n    <string name=\"auto_rotate_limits_sub\">Leidžia naudoti ribinį langelį vaizdo orientacijai</string>\n    <string name=\"draw_path_mode\">Nubrėžti kelią</string>\n    <string name=\"double_line_arrow\">Dvigubos linijos rodyklė</string>\n    <string name=\"free_drawing\">Nemokamas piešimas</string>\n    <string name=\"double_arrow\">Dviguba rodyklė</string>\n    <string name=\"line_arrow\">Linijinė rodyklė</string>\n    <string name=\"arrow\">Rodyklė</string>\n    <string name=\"line\">Linija</string>\n    <string name=\"free_drawing_sub\">Nubrėžia kelią kaip įvesties reikšmę</string>\n    <string name=\"line_sub\">Nubrėžia kelią nuo pradžios taško iki pabaigos taško kaip liniją</string>\n    <string name=\"line_arrow_sub\">Nubrėžia rodyklę nuo pradžios taško iki pabaigos taško kaip liniją</string>\n    <string name=\"arrow_sub\">Nubrėžia rodyklę iš nurodyto kelio</string>\n    <string name=\"double_line_arrow_sub\">Nubrėžia dvigubą rodyklę nuo pradžios taško iki pabaigos taško kaip liniją</string>\n    <string name=\"double_arrow_sub\">Nubrėžia dvigubą rodyklę iš nurodyto kelio</string>\n    <string name=\"outlined_oval\">Kontūrinis ovalas</string>\n    <string name=\"outlined_rect\">Nurodyta rekt</string>\n    <string name=\"oval\">Ovalus</string>\n    <string name=\"rect\">Rekt</string>\n    <string name=\"rect_sub\">Brėžia tiesiai nuo pradžios taško iki pabaigos taško</string>\n    <string name=\"oval_sub\">Piešia ovalą nuo pradžios iki pabaigos taško</string>\n    <string name=\"outlined_oval_sub\">Nubrėžia ovalą nuo pradžios iki pabaigos taško</string>\n    <string name=\"outlined_rect_sub\">Nubrėžia tiesią kontūrą nuo pradžios taško iki pabaigos taško</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Nubrėžia uždarą užpildytą kelią pagal nurodytą kelią</string>\n    <string name=\"free\">Nemokama</string>\n    <string name=\"horizontal_grid\">Horizontalus tinklelis</string>\n    <string name=\"vertical_grid\">Vertikalus tinklelis</string>\n    <string name=\"stitch_mode\">Dygsnio režimas</string>\n    <string name=\"rows_count\">Eilučių skaičius</string>\n    <string name=\"columns_count\">Stulpelių skaičius</string>\n    <string name=\"no_such_directory\">Nerastas \\\"%1$s\\\" katalogas, perjungėme jį į numatytąjį, išsaugokite failą dar kartą</string>\n    <string name=\"clipboard\">Iškarpinė</string>\n    <string name=\"auto_pin\">Automatinis kaištis</string>\n    <string name=\"auto_pin_sub\">Automatiškai prideda išsaugotą vaizdą į mainų sritį, jei įjungta</string>\n    <string name=\"vibration\">Vibracija</string>\n    <string name=\"vibration_strength\">Vibracijos stiprumas</string>\n    <string name=\"overwrite_file_requirements\">Norėdami perrašyti failus, turite naudoti \\\"Explorer\\\" vaizdo šaltinį, pabandykite perrinkti vaizdus, ​​mes pakeitėme vaizdo šaltinį į reikiamą</string>\n    <string name=\"overwrite_files\">Perrašyti failus</string>\n    <string name=\"overwrite_files_sub\">Originalus failas bus pakeistas nauju, o ne išsaugoti pasirinktame aplanke, šios parinkties vaizdo šaltinis turi būti \\\"Explorer\\\" arba GetContent, perjungus tai bus nustatyta automatiškai</string>\n    <string name=\"empty\">Tuščia</string>\n    <string name=\"suffix\">Priesaga</string>\n    <string name=\"scale_mode\">Mastelio režimas</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bikubinis</string>\n    <string name=\"hann\">Jis</string>\n    <string name=\"hermite\">Atsiskyrėlis</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Artimiausias</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Pagrindinis</string>\n    <string name=\"default_value\">Numatytoji reikšmė</string>\n    <string name=\"bilinear_sub\">Linijinė (arba bilinijinė, dviejų matmenų) interpoliacija paprastai tinka vaizdo dydžiui keisti, tačiau sukelia tam tikrą nepageidaujamą detalių sušvelninimą ir vis tiek gali būti šiek tiek dantyta.</string>\n    <string name=\"bicubic_sub\">Geresni mastelio keitimo metodai apima Lanczos resampling ir Mitchell-Netravali filtrus</string>\n    <string name=\"nearest_sub\">Vienas iš paprastesnių būdų padidinti dydį, pakeičiant kiekvieną pikselį tos pačios spalvos pikselių skaičiumi</string>\n    <string name=\"basic_sub\">Paprasčiausias „Android“ mastelio keitimo režimas, naudojamas beveik visose programose</string>\n    <string name=\"catmull_sub\">Valdymo taškų rinkinio sklandaus interpoliavimo ir atrinkimo metodas, dažniausiai naudojamas kompiuterinėje grafikoje, kad būtų sukurtos lygios kreivės</string>\n    <string name=\"hann_sub\">Langų funkcija, dažnai taikoma apdorojant signalą, siekiant sumažinti spektrinį nutekėjimą ir pagerinti dažnių analizės tikslumą siaurinant signalo kraštus.</string>\n    <string name=\"hermite_sub\">Matematinės interpoliacijos metodas, kuris naudoja vertes ir išvestines kreivės segmento galiniuose taškuose, kad būtų sukurta lygi ir ištisinė kreivė</string>\n    <string name=\"lanczos_sub\">Pakartotinio atrankos metodas, užtikrinantis aukštos kokybės interpoliaciją, pikselių reikšmėms taikant svertinę sinc funkciją</string>\n    <string name=\"mitchell_sub\">Pakartotinio atrankos metodas, kai naudojamas konvoliucijos filtras su reguliuojamais parametrais, kad būtų pasiekta pusiausvyra tarp ryškumo ir pakeitimo mastelio vaizde.</string>\n    <string name=\"spline_sub\">Naudoja dalimis apibrėžtas daugianario funkcijas, kad sklandžiai interpoliuotų ir aproksimuotų kreivę arba paviršių, užtikrinant lankstų ir nuolatinį formos vaizdavimą</string>\n    <string name=\"only_clip\">Tik klipas</string>\n    <string name=\"only_clip_sub\">Išsaugojimas saugykloje nebus vykdomas, o vaizdas bus bandomas įdėti tik į mainų sritį</string>\n    <string name=\"restore_background_sub\">Teptukas atkurs foną, o ne ištrins</string>\n    <string name=\"recognize_text\">OCR (teksto atpažinimas)</string>\n    <string name=\"recognize_text_sub\">Atpažinti tekstą iš pateikto vaizdo, palaikoma daugiau nei 120 kalbų</string>\n    <string name=\"picture_has_no_text\">Nuotraukoje nėra teksto arba programa jo nerado</string>\n    <string name=\"accuracy\">\\\"Tikslumas: %1$s\\\"</string>\n    <string name=\"recognition_type\">Atpažinimo tipas</string>\n    <string name=\"fast\">Greitai</string>\n    <string name=\"standard\">Standartinis</string>\n    <string name=\"best\">Geriausia</string>\n    <string name=\"no_data\">Nėra duomenų</string>\n    <string name=\"download_description\">Kad Tesseract OCR tinkamai veiktų, į įrenginį reikia atsisiųsti papildomus mokymo duomenis (%1$s).\\nAr norite atsisiųsti %2$s duomenis?</string>\n    <string name=\"download\">Atsisiųsti</string>\n    <string name=\"no_connection\">Nėra ryšio, patikrinkite ir bandykite dar kartą, kad atsisiųstumėte traukinių modelius</string>\n    <string name=\"downloaded_languages\">Atsisiųstos kalbos</string>\n    <string name=\"available_languages\">Galimos kalbos</string>\n    <string name=\"segmentation_mode\">Segmentavimo režimas</string>\n    <string name=\"use_pixel_switch\">Naudokite Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Naudojamas į Google Pixel panašus jungiklis</string>\n    <string name=\"saved_to_original\">Perrašytas failas pavadinimu %1$s pradinėje paskirties vietoje</string>\n    <string name=\"magnifier\">Didintuvas</string>\n    <string name=\"magnifier_sub\">Piešimo režimais įgalina didintuvą piršto viršuje, kad būtų lengviau pasiekti</string>\n    <string name=\"force_exif_widget_initial_value\">Priversti pradinę vertę</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Priverčia iš pradžių patikrinti exif valdiklį</string>\n    <string name=\"allow_multiple_languages\">Leisti kelias kalbas</string>\n    <string name=\"slide\">Skaidrė</string>\n    <string name=\"side_by_side\">Side By Side</string>\n    <string name=\"toggle_tap\">Perjungti bakstelėjimą</string>\n    <string name=\"transparency\">Skaidrumas</string>\n    <string name=\"rate_app\">Įvertinkite programą</string>\n    <string name=\"rate\">Įvertink</string>\n    <string name=\"rate_app_sub\">Ši programa yra visiškai nemokama, jei norite, kad ji taptų didesnė, pažymėkite projektą „Github“ 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Tik orientacija ir scenarijaus aptikimas</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatinė orientacija ir scenarijaus aptikimas</string>\n    <string name=\"segmentation_mode_auto_only\">Tik auto</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Viena kolona</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Vieno bloko vertikalus tekstas</string>\n    <string name=\"segmentation_mode_single_block\">Vienas blokas</string>\n    <string name=\"segmentation_mode_single_line\">Viena linija</string>\n    <string name=\"segmentation_mode_single_word\">Vienas žodis</string>\n    <string name=\"segmentation_mode_circle_word\">Apskritimo žodis</string>\n    <string name=\"segmentation_mode_single_char\">Vienas simbolis</string>\n    <string name=\"segmentation_mode_sparse_text\">Retas tekstas</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Retai teksto orientacija ir scenarijaus aptikimas</string>\n    <string name=\"segmentation_mode_raw_line\">Neapdorota linija</string>\n    <string name=\"delete_language_sub\">Ar norite ištrinti kalbos \\\"%1$s\\\" OCR mokymo duomenis visiems atpažinimo tipams, ar tik pasirinktam vienam (%2$s)?</string>\n    <string name=\"current\">Dabartinė</string>\n    <string name=\"all\">Visi</string>\n    <string name=\"gradient_maker\">Gradiento kūrėjas</string>\n    <string name=\"gradient_maker_sub\">Sukurkite nurodyto išvesties dydžio gradientą naudodami tinkintas spalvas ir išvaizdos tipą</string>\n    <string name=\"gradient_type_linear\">Linijinis</string>\n    <string name=\"gradient_type_radial\">Radialinis</string>\n    <string name=\"gradient_type_sweep\">Šluoti</string>\n    <string name=\"gradient_type\">Gradiento tipas</string>\n    <string name=\"center_x\">Centras X</string>\n    <string name=\"center_y\">Centras Y</string>\n    <string name=\"tile_mode\">Plytelių režimas</string>\n    <string name=\"tile_mode_repeated\">Pasikartojo</string>\n    <string name=\"tile_mode_mirror\">Veidrodis</string>\n    <string name=\"tile_mode_clamp\">Spaustuvas</string>\n    <string name=\"tile_mode_decal\">Lipdukas</string>\n    <string name=\"color_stops\">Spalvos sustojimai</string>\n    <string name=\"add_color\">Pridėti spalvą</string>\n    <string name=\"properties\">Savybės</string>\n    <string name=\"brightness_enforcement\">Ryškumo užtikrinimas</string>\n    <string name=\"screen\">Ekranas</string>\n    <string name=\"gradient_maker_type_image\">Gradiento perdanga</string>\n    <string name=\"gradient_maker_type_image_sub\">Sukurkite bet kokį pateiktų vaizdų viršaus gradientą</string>\n    <string name=\"transformations\">Transformacijos</string>\n    <string name=\"camera\">Fotoaparatas</string>\n    <string name=\"camera_sub\">Fotografuokite fotoaparatu. Atminkite, kad iš šio vaizdo šaltinio galima gauti tik vieną vaizdą</string>\n    <string name=\"watermarking\">Vandens ženklai</string>\n    <string name=\"watermarking_sub\">Uždenkite paveikslėlius tinkinamais teksto / vaizdo vandens ženklais</string>\n    <string name=\"repeat_watermark\">Pakartokite vandens ženklą</string>\n    <string name=\"repeat_watermark_sub\">Tam tikroje padėtyje pakartoja vandens ženklą virš vaizdo, o ne vieną</string>\n    <string name=\"offset_x\">Poslinkis X</string>\n    <string name=\"offset_y\">Poslinkis Y</string>\n    <string name=\"watermark_type\">Vandens ženklo tipas</string>\n    <string name=\"watermarking_image_sub\">Šis paveikslėlis bus naudojamas kaip vandens ženklų piešinys</string>\n    <string name=\"text_color\">Teksto spalva</string>\n    <string name=\"overlay_mode\">Perdangos režimas</string>\n    <string name=\"gif_tools\">GIF įrankiai</string>\n    <string name=\"gif_tools_sub\">Konvertuokite vaizdus į GIF paveikslėlį arba ištraukite rėmelius iš nurodyto GIF vaizdo</string>\n    <string name=\"gif_type_to_image\">GIF į vaizdus</string>\n    <string name=\"gif_type_to_image_sub\">Konvertuokite GIF failą į nuotraukų paketą</string>\n    <string name=\"gif_type_to_gif_sub\">Konvertuoti vaizdų paketą į GIF failą</string>\n    <string name=\"gif_type_to_gif\">Vaizdai į GIF</string>\n    <string name=\"select_gif_image_to_start\">Norėdami pradėti, pasirinkite GIF vaizdą</string>\n    <string name=\"use_size_of_first_frame\">Naudokite pirmojo kadro dydį</string>\n    <string name=\"use_size_of_first_frame_sub\">Nurodytą dydį pakeiskite pirmojo rėmo matmenimis</string>\n    <string name=\"repeat_count\">Pakartokite skaičių</string>\n    <string name=\"frame_delay\">Kadro delsa</string>\n    <string name=\"millis\">mln</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Naudokite Lasso</string>\n    <string name=\"use_lasso_sub\">Naudoja Lasso kaip piešimo režimu, kad atliktų trynimą</string>\n    <string name=\"original_image_preview_alpha\">Originalaus vaizdo peržiūra Alpha</string>\n    <string name=\"confetti\">Konfeti</string>\n    <string name=\"confetti_sub\">Konfeti bus rodomi taupant, dalijantis ir atliekant kitus pagrindinius veiksmus</string>\n    <string name=\"secure_mode\">Saugus režimas</string>\n    <string name=\"secure_mode_sub\">Paslepia programų turinį naujausiose programose. Jo negalima užfiksuoti ar įrašyti.</string>\n    <string name=\"exit\">Išeiti</string>\n    <string name=\"preview_closing\">Jei dabar paliksite peržiūrą, turėsite dar kartą pridėti vaizdų</string>\n    <string name=\"dithering\">Dingimas</string>\n    <string name=\"quantizier\">Kvantifikatorius</string>\n    <string name=\"gray_scale\">Pilka skalė</string>\n    <string name=\"bayer_two_dithering\">„Bayer Two By Two Dithering“.</string>\n    <string name=\"bayer_three_dithering\">„Bayer Three By Three Dathering“.</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floydas Steinbergas</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarviso teisėja Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Dviejų eilių Sierra dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinsono diteringas</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">False Floyd Steinberg dithering</string>\n    <string name=\"left_to_right_dithering\">Skirstymas iš kairės į dešinę</string>\n    <string name=\"random_dithering\">Atsitiktinis suskaidymas</string>\n    <string name=\"simple_threshold_dithering\">Paprastas slenkstis</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Erdvinė sigma</string>\n    <string name=\"median_blur\">Vidutinis suliejimas</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Naudoja dalimis apibrėžtas dvikubines daugianario funkcijas, kad sklandžiai interpoliuotų ir aproksimuotų kreivę arba paviršių, lankstų ir ištisinį formos vaizdavimą</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"glitch\">Gedimas</string>\n    <string name=\"amount\">Suma</string>\n    <string name=\"seed\">Sėkla</string>\n    <string name=\"anaglyph\">Anaglifas</string>\n    <string name=\"noise\">Triukšmas</string>\n    <string name=\"pixel_sort\">Pikselių rūšiavimas</string>\n    <string name=\"shuffle\">Maišyti</string>\n    <string name=\"enhanced_glitch\">Patobulintas Glitch</string>\n    <string name=\"channel_shift_x\">Kanalo poslinkis X</string>\n    <string name=\"channel_shift_y\">Kanalo poslinkis Y</string>\n    <string name=\"corruption_size\">Korupcijos dydis</string>\n    <string name=\"corruption_shift_x\">Korupcijos pamaina X</string>\n    <string name=\"corruption_shift_y\">Korupcijos pamaina Y</string>\n    <string name=\"tent_blur\">Tent Blur</string>\n    <string name=\"side_fade\">Šoninis išnykimas</string>\n    <string name=\"side\">Šoninė</string>\n    <string name=\"top\">Į viršų</string>\n    <string name=\"bottom\">Apačia</string>\n    <string name=\"strength\">Jėga</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anizotropinė difuzija</string>\n    <string name=\"diffusion\">Difuzija</string>\n    <string name=\"conduction\">Laidumas</string>\n    <string name=\"horizontal_wind_stagger\">Horizontalus vėjo stabdys</string>\n    <string name=\"fast_bilaterial_blur\">Greitas dvišalis suliejimas</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritminis tonų atvaizdavimas</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"crystallize\">Iškristalizuokite</string>\n    <string name=\"stroke_color\">Potėpio spalva</string>\n    <string name=\"fractal_glass\">Fraktalinis stiklas</string>\n    <string name=\"amplitude\">Amplitudė</string>\n    <string name=\"marble\">Marmuras</string>\n    <string name=\"turbulence\">Turbulencija</string>\n    <string name=\"oil\">Aliejus</string>\n    <string name=\"water_effect\">Vandens efektas</string>\n    <string name=\"just_size\">Dydis</string>\n    <string name=\"frequency_x\">X dažnis</string>\n    <string name=\"frequency_y\">Dažnis Y</string>\n    <string name=\"amplitude_x\">Amplitudė X</string>\n    <string name=\"amplitude_y\">Amplitudė Y</string>\n    <string name=\"perlin_distortion\">Perlino iškraipymas</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Tonų žemėlapis</string>\n    <string name=\"speed\">Greitis</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Spalvų matrica 4x4</string>\n    <string name=\"color_matrix_3x3\">Spalvų matrica 3x3</string>\n    <string name=\"simple_effects\">Paprasti efektai</string>\n    <string name=\"polaroid\">Polaroidas</string>\n    <string name=\"tritonomaly\">Tritanomalija</string>\n    <string name=\"deutaromaly\">Deuteranomalija</string>\n    <string name=\"protonomaly\">Protanomalija</string>\n    <string name=\"vintage\">Vintažinis</string>\n    <string name=\"browni\">Browno</string>\n    <string name=\"coda_chrome\">„Coda Chrome“.</string>\n    <string name=\"night_vision\">Naktinis matymas</string>\n    <string name=\"warm\">Šiltas</string>\n    <string name=\"cool\">Kietas</string>\n    <string name=\"tritanopia\">Tritanopija</string>\n    <string name=\"deutaronotopia\">Deutaronotopija</string>\n    <string name=\"protanopia\">Protanopija</string>\n    <string name=\"achromatomaly\">Achromatomalija</string>\n    <string name=\"achromatopsia\">Achromatopsija</string>\n    <string name=\"grain\">Grūdai</string>\n    <string name=\"unsharp\">Neryškus</string>\n    <string name=\"pastel\">Pastelinė</string>\n    <string name=\"orange_haze\">Oranžinė migla</string>\n    <string name=\"pink_dream\">Rožinė svajonė</string>\n    <string name=\"golden_hour\">Auksinė valanda</string>\n    <string name=\"hot_summer\">Karšta vasara</string>\n    <string name=\"purple_mist\">Violetinė migla</string>\n    <string name=\"sunrise\">Saulėtekis</string>\n    <string name=\"colorful_swirl\">Spalvingas sūkurys</string>\n    <string name=\"soft_spring_light\">Minkšta pavasario lemputė</string>\n    <string name=\"autumn_tones\">Rudens tonai</string>\n    <string name=\"lavender_dream\">Levandų svajonė</string>\n    <string name=\"cyberpunk\">Kiberpankas</string>\n    <string name=\"lemonade_light\">Šviesus limonadas</string>\n    <string name=\"spectral_fire\">Spektrinė ugnis</string>\n    <string name=\"night_magic\">Naktinė magija</string>\n    <string name=\"fantasy_landscape\">Fantastinis peizažas</string>\n    <string name=\"color_explosion\">Spalvų sprogimas</string>\n    <string name=\"electric_gradient\">Elektrinis gradientas</string>\n    <string name=\"caramel_darkness\">Karamelinė tamsa</string>\n    <string name=\"futuristic_gradient\">Futuristinis gradientas</string>\n    <string name=\"green_sun\">Žalia saulė</string>\n    <string name=\"rainbow_world\">Vaivorykštės pasaulis</string>\n    <string name=\"deep_purple\">Giliai violetinė</string>\n    <string name=\"space_portal\">Kosmoso portalas</string>\n    <string name=\"red_swirl\">Raudonasis sūkurys</string>\n    <string name=\"digital_code\">Skaitmeninis kodas</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">Programų juostos jaustukai keisis atsitiktinai</string>\n    <string name=\"random_emojis\">Atsitiktinės emocijos</string>\n    <string name=\"random_emojis_error\">Negalite naudoti atsitiktinių jaustukų, kai jaustukai išjungti</string>\n    <string name=\"emoji_selection_error\">Negalite pasirinkti jaustukų, kai įjungti atsitiktiniai jaustukai</string>\n    <string name=\"old_tv\">Senas tv</string>\n    <string name=\"shuffle_blur\">Maišyti suliejimą</string>\n    <string name=\"favorite\">Mėgstamiausias</string>\n    <string name=\"no_favorite_filters\">Mėgstamiausių filtrų dar nepridėta</string>\n    <string name=\"image_format\">Vaizdo formatas</string>\n    <string name=\"icon_shape_sub\">Prideda konteinerį su pasirinkta forma po piktogramomis</string>\n    <string name=\"icon_shape\">Piktogramos forma</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridžas</string>\n    <string name=\"cutoff\">Atkarpa</string>\n    <string name=\"uchimura\">Tu pabundi</string>\n    <string name=\"mobius\">Mobiusas</string>\n    <string name=\"transition\">Perėjimas</string>\n    <string name=\"peak\">Peak</string>\n    <string name=\"color_anomaly\">Spalvos anomalija</string>\n    <string name=\"images_overwritten\">Vaizdai perrašyti pradinėje paskirties vietoje</string>\n    <string name=\"cannot_change_image_format\">Negalima pakeisti vaizdo formato, kai įjungta failų perrašymo parinktis</string>\n    <string name=\"emoji_as_color_scheme\">Jaustukai kaip spalvų schema</string>\n    <string name=\"emoji_as_color_scheme_sub\">Naudoja jaustukų pagrindinę spalvą kaip programos spalvų schemą, o ne rankiniu būdu apibrėžtą</string>\n    <string name=\"material_you_sub\">Sukuria Material You paletę iš vaizdo</string>\n    <string name=\"dark_colors\">Tamsios Spalvos</string>\n    <string name=\"dark_colors_sub\">Naudoja naktinio režimo spalvų schemą, o ne šviesų variantą</string>\n    <string name=\"copy_as_compose_code\">Nukopijuokite kaip „Jetpack Compose“ kodą</string>\n    <string name=\"ring_blur\">Žiedo suliejimas</string>\n    <string name=\"cross_blur\">Kryžminis suliejimas</string>\n    <string name=\"circle_blur\">Apskritimo suliejimas</string>\n    <string name=\"star_blur\">Žvaigždžių suliejimas</string>\n    <string name=\"linear_tilt_shift\">Linijinis „Tilt-Shift“.</string>\n    <string name=\"tags_to_remove\">Žymos, kurias reikia pašalinti</string>\n    <string name=\"apng_tools\">APNG įrankiai</string>\n    <string name=\"apng_tools_sub\">Konvertuokite vaizdus į APNG paveikslėlį arba ištraukite rėmelius iš nurodyto APNG vaizdo</string>\n    <string name=\"apng_type_to_image\">APNG vaizdams</string>\n    <string name=\"apng_type_to_image_sub\">Konvertuokite APNG failą į nuotraukų paketą</string>\n    <string name=\"apng_type_to_apng_sub\">Konvertuoti vaizdų paketą į APNG failą</string>\n    <string name=\"apng_type_to_apng\">Vaizdai į APNG</string>\n    <string name=\"select_apng_image_to_start\">Norėdami pradėti, pasirinkite APNG vaizdą</string>\n    <string name=\"motion_blur\">Judesio suliejimas</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Sukurkite ZIP failą iš pateiktų failų ar vaizdų</string>\n    <string name=\"drag_handle_width\">Vilkimo rankenos plotis</string>\n    <string name=\"confetti_type\">Konfeti tipas</string>\n    <string name=\"festive\">Šventinis</string>\n    <string name=\"explode\">Sprogti</string>\n    <string name=\"rain\">Lietus</string>\n    <string name=\"corners\">Kampai</string>\n    <string name=\"jxl_tools\">JXL įrankiai</string>\n    <string name=\"jxl_tools_sub\">Atlikite JXL ~ JPEG perkodavimą neprarandant kokybės arba konvertuokite GIF / APNG į JXL animaciją</string>\n    <string name=\"jxl_type_to_jpeg\">JXL į JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Atlikite be nuostolių perkodavimą iš JXL į JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Atlikite be nuostolių perkodavimą iš JPEG į JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG į JXL</string>\n    <string name=\"select_jxl_image_to_start\">Norėdami pradėti, pasirinkite JXL vaizdą</string>\n    <string name=\"fast_gaussian_blur_2d\">Greitas Gauso suliejimas 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Greitas Gauso suliejimas 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Greitas Gauso suliejimas 4D</string>\n    <string name=\"auto_paste\">Automobilių Velykos</string>\n    <string name=\"auto_paste_sub\">Leidžia programai automatiškai įklijuoti mainų srities duomenis, kad jie būtų rodomi pagrindiniame ekrane ir galėsite juos apdoroti</string>\n    <string name=\"harmonization_color\">Harmonizavimo spalva</string>\n    <string name=\"harmonization_level\">Harmonizavimo lygis</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Pakartotinis atrankos metodas, užtikrinantis aukštos kokybės interpoliaciją pikselių reikšmėms taikant Beselio (jinc) funkciją</string>\n    <string name=\"gif_type_to_jxl\">GIF į JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Konvertuokite GIF vaizdus į JXL animacinius paveikslėlius</string>\n    <string name=\"apng_type_to_jxl\">APNG į JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Konvertuokite APNG vaizdus į JXL animacinius paveikslėlius</string>\n    <string name=\"jxl_type_to_images\">JXL į vaizdus</string>\n    <string name=\"jxl_type_to_images_sub\">Konvertuokite JXL animaciją į nuotraukų paketą</string>\n    <string name=\"jxl_type_to_jxl\">Vaizdai į JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Konvertuokite paveikslėlių paketą į JXL animaciją</string>\n    <string name=\"behavior\">Elgesys</string>\n    <string name=\"skip_file_picking\">Praleisti failų pasirinkimą</string>\n    <string name=\"skip_file_picking_sub\">Failų rinkiklis bus iškart parodytas pasirinktame ekrane, jei tai įmanoma</string>\n    <string name=\"generate_previews\">Generuokite peržiūras</string>\n    <string name=\"generate_previews_sub\">Įgalina peržiūros generavimą, tai gali padėti išvengti kai kurių įrenginių gedimų, taip pat išjungia kai kurias redagavimo funkcijas naudojant vieną redagavimo parinktį</string>\n    <string name=\"lossy_compression\">Prarastos kompresijos</string>\n    <string name=\"lossy_compression_sub\">Naudoja nuostolingą glaudinimą, kad sumažintų failo dydį, o ne be nuostolių</string>\n    <string name=\"compression_type\">Suspaudimo tipas</string>\n    <string name=\"speed_sub\">Valdo vaizdo dekodavimo greitį, tai turėtų padėti greičiau atidaryti gautą vaizdą, %1$s reikšmė reiškia lėčiausią dekodavimą, o %2$s - greičiausią, šis nustatymas gali padidinti išvesties vaizdo dydį</string>\n    <string name=\"sorting\">Rūšiavimas</string>\n    <string name=\"sort_by_date\">Data</string>\n    <string name=\"sort_by_date_reversed\">Data (atvirkščiai)</string>\n    <string name=\"sort_by_name\">Vardas</string>\n    <string name=\"sort_by_name_reversed\">Vardas (atvirkščias)</string>\n    <string name=\"channels_configuration\">Kanalų konfigūracija</string>\n    <string name=\"header_today\">Šiandien</string>\n    <string name=\"header_yesterday\">vakar</string>\n    <string name=\"embedded_picker\">Įterptasis rinkiklis</string>\n    <string name=\"embedded_picker_sub\">Vaizdo įrankių rinkinio vaizdų rinkiklis</string>\n    <string name=\"no_permissions\">Jokių leidimų</string>\n    <string name=\"request\">Prašymas</string>\n    <string name=\"pick_multiple_media\">Pasirinkite kelias laikmenas</string>\n    <string name=\"pick_single_media\">Pasirinkite vieną laikmeną</string>\n    <string name=\"pick\">Pasirinkti</string>\n    <string name=\"try_again\">Bandykite dar kartą</string>\n    <string name=\"show_settings_in_landscape\">Rodyti nustatymus kraštovaizdyje</string>\n    <string name=\"show_settings_in_landscape_sub\">Jei tai išjungta, gulsčiojo režimo nustatymai bus atidaryti viršutinėje programos juostoje esančiame mygtuke, kaip visada, vietoj nuolatinės matomos parinkties</string>\n    <string name=\"fullscreen_settings\">Viso ekrano nustatymai</string>\n    <string name=\"fullscreen_settings_sub\">Įjunkite jį ir nustatymų puslapis visada bus atidarytas kaip viso ekrano režimas, o ne slankiojantis stalčiaus lapas</string>\n    <string name=\"switch_type\">Jungiklio tipas</string>\n    <string name=\"compose\">Sukurti</string>\n    <string name=\"compose_switch_sub\">„Jetpack Compose“ medžiaga, kurią perjungiate</string>\n    <string name=\"material_you_switch_sub\">Medžiaga, kurią perjungiate</string>\n    <string name=\"max\">Maks</string>\n    <string name=\"resize_anchor\">Inkaro dydžio keitimas</string>\n    <string name=\"pixel_switch\">Pikselis</string>\n    <string name=\"fluent_switch\">Sklandžiai</string>\n    <string name=\"fluent_switch_sub\">Jungiklis, pagrįstas \\\"Fluent\\\" dizaino sistema</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Jungiklis, pagrįstas \\\"Cupertino\\\" dizaino sistema</string>\n    <string name=\"images_to_svg\">Vaizdai į SVG</string>\n    <string name=\"images_to_svg_sub\">Atsekti pateiktus vaizdus į SVG vaizdus</string>\n    <string name=\"use_sampled_palette\">Naudokite pavyzdinę paletę</string>\n    <string name=\"use_sampled_palette_sub\">Kvantifikavimo paletė bus atrinkta, jei ši parinktis įjungta</string>\n    <string name=\"path_omit\">Kelias praleisti</string>\n    <string name=\"svg_warning\">Nerekomenduojama naudoti šio įrankio dideliems vaizdams sekti be mastelio sumažinimo, nes tai gali sukelti strigtį ir pailginti apdorojimo laiką</string>\n    <string name=\"downscale_image\">Sumažintas vaizdas</string>\n    <string name=\"downscale_image_sub\">Prieš apdorojimą vaizdas bus sumažintas iki mažesnių matmenų, todėl įrankis veiks greičiau ir saugiau</string>\n    <string name=\"min_color_ratio\">Minimalus spalvų santykis</string>\n    <string name=\"lines_threshold\">Linijų slenkstis</string>\n    <string name=\"quadratic_threshold\">Kvadratinis slenkstis</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordinatės apvalinimo tolerancija</string>\n    <string name=\"path_scale\">Kelio skalė</string>\n    <string name=\"reset_properties\">Iš naujo nustatyti savybes</string>\n    <string name=\"reset_properties_sub\">Visoms ypatybėms bus nustatytos numatytosios vertės, atkreipkite dėmesį, kad šio veiksmo anuliuoti negalima</string>\n    <string name=\"detailed\">Išsamus</string>\n    <string name=\"default_line_width\">Numatytasis linijos plotis</string>\n    <string name=\"engine_mode\">Variklio režimas</string>\n    <string name=\"legacy\">Palikimas</string>\n    <string name=\"lstm_network\">LSTM tinklas</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp;amp; LSTM</string>\n    <string name=\"convert\">Konvertuoti</string>\n    <string name=\"convert_sub\">Konvertuoti vaizdų paketus į nurodytą formatą</string>\n    <string name=\"add_new_folder\">Pridėti naują aplanką</string>\n    <string name=\"tag_bits_per_sample\">Bitai vienam mėginiui</string>\n    <string name=\"tag_compression\">Suspaudimas</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrinis aiškinimas</string>\n    <string name=\"tag_samples_per_pixel\">Pavyzdžiai pikseliui</string>\n    <string name=\"tag_planar_configuration\">Plokštuminė konfigūracija</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr sub mėginių ėmimas</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr padėties nustatymas</string>\n    <string name=\"tag_x_resolution\">X rezoliucija</string>\n    <string name=\"tag_y_resolution\">Y rezoliucija</string>\n    <string name=\"tag_resolution_unit\">Rezoliucijos vienetas</string>\n    <string name=\"tag_strip_offsets\">Juostelių poslinkiai</string>\n    <string name=\"tag_rows_per_strip\">Eilutės per juostelę</string>\n    <string name=\"tag_strip_byte_counts\">Juostelės baitų skaičius</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG mainų formatas</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG mainų formato ilgis</string>\n    <string name=\"tag_transfer_function\">Perdavimo funkcija</string>\n    <string name=\"tag_white_point\">Baltasis taškas</string>\n    <string name=\"tag_primary_chromaticities\">Pirminiai chromatai</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr koeficientai</string>\n    <string name=\"tag_reference_black_white\">Nuoroda Black White</string>\n    <string name=\"tag_datetime\">Data Laikas</string>\n    <string name=\"tag_image_description\">Vaizdo aprašymas</string>\n    <string name=\"tag_make\">Padaryti</string>\n    <string name=\"tag_model\">Modelis</string>\n    <string name=\"tag_software\">Programinė įranga</string>\n    <string name=\"tag_artist\">Menininkas</string>\n    <string name=\"tag_copyright\">Autorių teisės</string>\n    <string name=\"tag_exif_version\">Exif versija</string>\n    <string name=\"tag_flashpix_version\">Flashpix versija</string>\n    <string name=\"tag_color_space\">Spalvų erdvė</string>\n    <string name=\"tag_gamma\">Gama</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y matmuo</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Suspausti bitai pikselyje</string>\n    <string name=\"tag_maker_note\">Kūrėjo pastaba</string>\n    <string name=\"tag_user_comment\">Vartotojo komentaras</string>\n    <string name=\"tag_related_sound_file\">Susijęs garso failas</string>\n    <string name=\"tag_datetime_original\">Data Laikas Originalas</string>\n    <string name=\"tag_datetime_digitized\">Data Laikas Suskaitmenintas</string>\n    <string name=\"tag_offset_time\">Poslinkio laikas</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Poslinkio laikas suskaitmenintas</string>\n    <string name=\"tag_subsec_time\">Subsekundės laikas</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Time Original</string>\n    <string name=\"tag_subsec_time_digitized\">Subsekundės laikas suskaitmenintas</string>\n    <string name=\"tag_exposure_time\">Kontakto trukmė</string>\n    <string name=\"tag_f_number\">F Skaičius</string>\n    <string name=\"tag_exposure_program\">Ekspozicijos programa</string>\n    <string name=\"tag_spectral_sensitivity\">Spektrinis jautrumas</string>\n    <string name=\"tag_photographic_sensitivity\">Fotografinis jautrumas</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Jautrumo tipas</string>\n    <string name=\"tag_standard_output_sensitivity\">Standartinis išvesties jautrumas</string>\n    <string name=\"tag_recommended_exposure_index\">Rekomenduojamas ekspozicijos indeksas</string>\n    <string name=\"tag_iso_speed\">ISO greitis</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO greitis Platuma yyyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO greitis Platuma zzz</string>\n    <string name=\"tag_shutter_speed_value\">Užrakto greičio vertė</string>\n    <string name=\"tag_aperture_value\">Diafragmos vertė</string>\n    <string name=\"tag_brightness_value\">Ryškumo vertė</string>\n    <string name=\"tag_exposure_bias_value\">Ekspozicijos šališkumo vertė</string>\n    <string name=\"tag_max_aperture_value\">Maksimali diafragmos vertė</string>\n    <string name=\"tag_subject_distance\">Dalyko atstumas</string>\n    <string name=\"tag_metering_mode\">Matavimo režimas</string>\n    <string name=\"tag_flash\">Blykstė</string>\n    <string name=\"tag_subject_area\">Dalyko sritis</string>\n    <string name=\"tag_focal_length\">Židinio nuotolis</string>\n    <string name=\"tag_flash_energy\">Blykstės energija</string>\n    <string name=\"tag_spatial_frequency_response\">Erdvinio dažnio atsakas</string>\n    <string name=\"tag_focal_plane_x_resolution\">X židinio plokštumos skiriamoji geba</string>\n    <string name=\"tag_focal_plane_y_resolution\">Židinio plokštumos Y skiriamoji geba</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Židinio plokštumos skyros vienetas</string>\n    <string name=\"tag_subject_location\">Dalyko vieta</string>\n    <string name=\"tag_exposure_index\">Ekspozicijos indeksas</string>\n    <string name=\"tag_sensing_method\">Jutimo metodas</string>\n    <string name=\"tag_file_source\">Failo šaltinis</string>\n    <string name=\"tag_cfa_pattern\">CFA modelis</string>\n    <string name=\"tag_custom_rendered\">Pateikta pagal užsakymą</string>\n    <string name=\"tag_exposure_mode\">Ekspozicijos režimas</string>\n    <string name=\"tag_white_balance\">Baltos spalvos balansas</string>\n    <string name=\"tag_digital_zoom_ratio\">Skaitmeninis priartinimo koeficientas</string>\n    <string name=\"tag_focal_length_in_35mm_film\">35 mm židinio nuotolio juosta</string>\n    <string name=\"tag_scene_capture_type\">Scenos fiksavimo tipas</string>\n    <string name=\"tag_gain_control\">Įgykite kontrolę</string>\n    <string name=\"tag_contrast\">Kontrastas</string>\n    <string name=\"tag_saturation\">Sodrumas</string>\n    <string name=\"tag_sharpness\">Ryškumas</string>\n    <string name=\"tag_device_setting_description\">Įrenginio nustatymų aprašymas</string>\n    <string name=\"tag_subject_distance_range\">Dalyko atstumo diapazonas</string>\n    <string name=\"tag_image_unique_id\">Vaizdo unikalus ID</string>\n    <string name=\"tag_camera_owner_name\">Kameros savininko vardas</string>\n    <string name=\"tag_body_serial_number\">Korpuso serijos numeris</string>\n    <string name=\"tag_lens_specification\">Objektyvo specifikacija</string>\n    <string name=\"tag_lens_make\">Objektyvo gaminys</string>\n    <string name=\"tag_lens_model\">Objektyvo modelis</string>\n    <string name=\"tag_lens_serial_number\">Objektyvo serijos numeris</string>\n    <string name=\"tag_gps_version_id\">GPS versijos ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS platumos nuorod</string>\n    <string name=\"tag_gps_latitude\">GPS platuma</string>\n    <string name=\"tag_gps_longitude_ref\">GPS ilguma nuorod</string>\n    <string name=\"tag_gps_longitude\">GPS ilguma</string>\n    <string name=\"tag_gps_altitude_ref\">GPS aukštis nuorod</string>\n    <string name=\"tag_gps_altitude\">GPS aukštis</string>\n    <string name=\"tag_gps_timestamp\">GPS laiko žyma</string>\n    <string name=\"tag_gps_satellites\">GPS palydovai</string>\n    <string name=\"tag_gps_status\">GPS būsena</string>\n    <string name=\"tag_gps_measure_mode\">GPS matavimo režimas</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS greičio nuorod</string>\n    <string name=\"tag_gps_speed\">GPS greitis</string>\n    <string name=\"tag_gps_track_ref\">GPS sekimo nuoroda</string>\n    <string name=\"tag_gps_track\">GPS sekimas</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img kryptis nuorod</string>\n    <string name=\"tag_gps_img_direction\">GPS Img kryptis</string>\n    <string name=\"tag_gps_map_datum\">GPS žemėlapio data</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS paskirties platumos nuorod</string>\n    <string name=\"tag_gps_dest_latitude\">GPS paskirties platuma</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS paskirties ilgumos nuorod</string>\n    <string name=\"tag_gps_dest_longitude\">GPS paskirties ilguma</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS tiksl. guolio Nr</string>\n    <string name=\"tag_gps_dest_bearing\">GPS tikslus guolis</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS paskirties atstumo nuoroda</string>\n    <string name=\"tag_gps_dest_distance\">GPS paskirties atstumas</string>\n    <string name=\"tag_gps_processing_method\">GPS apdorojimo metodas</string>\n    <string name=\"tag_gps_area_information\">GPS srities informacija</string>\n    <string name=\"tag_gps_datestamp\">GPS datos antspaudas</string>\n    <string name=\"tag_gps_differential\">GPS diferencialas</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H padėties nustatymo klaida</string>\n    <string name=\"tag_interoperability_index\">Sąveikos indeksas</string>\n    <string name=\"tag_dng_version\">DNG versija</string>\n    <string name=\"tag_default_crop_size\">Numatytasis apkarpymo dydis</string>\n    <string name=\"tag_orf_preview_image_start\">Vaizdo peržiūros pradžia</string>\n    <string name=\"tag_orf_preview_image_length\">Peržiūrėti vaizdo ilgį</string>\n    <string name=\"tag_orf_aspect_frame\">Aspekto rėmelis</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Jutiklio apatinė kraštinė</string>\n    <string name=\"tag_rw2_sensor_left_border\">Jutiklio kairioji sienelė</string>\n    <string name=\"tag_rw2_sensor_right_border\">Jutiklio dešinė kraštinė</string>\n    <string name=\"tag_rw2_sensor_top_border\">Jutiklio viršutinė sienelė</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Nubrėžkite tekstą kelyje su nurodytu šriftu ir spalva</string>\n    <string name=\"font_size\">Šrifto dydis</string>\n    <string name=\"watermark_size\">Vandens ženklo dydis</string>\n    <string name=\"repeat_text\">Pakartokite tekstą</string>\n    <string name=\"repeat_text_sub\">Dabartinis tekstas bus kartojamas iki kelio pabaigos, o ne vieną kartą</string>\n    <string name=\"dash_size\">Brūkšnelio dydis</string>\n    <string name=\"draw_mode_image_sub\">Naudokite pasirinktą vaizdą, kad nubrėžtumėte jį nurodytu keliu</string>\n    <string name=\"draw_image_sub\">Šis vaizdas bus naudojamas kaip pasikartojantis nubrėžto kelio įvedimas</string>\n    <string name=\"outlined_triangle_sub\">Nubrėžia nubrėžtą trikampį nuo pradžios iki pabaigos taško</string>\n    <string name=\"triangle_sub\">Nubrėžia nubrėžtą trikampį nuo pradžios iki pabaigos taško</string>\n    <string name=\"outlined_triangle\">Nubrėžtas trikampis</string>\n    <string name=\"triangle\">Trikampis</string>\n    <string name=\"polygon_sub\">Brėžia daugiakampį nuo pradžios taško iki pabaigos taško</string>\n    <string name=\"polygon\">Daugiakampis</string>\n    <string name=\"outlined_polygon\">Kontūrinis daugiakampis</string>\n    <string name=\"outlined_polygon_sub\">Nubrėžia daugiakampį nuo pradžios iki pabaigos taško</string>\n    <string name=\"vertices\">Viršūnės</string>\n    <string name=\"draw_regular_polygon\">Nubrėžkite reguliarųjį daugiakampį</string>\n    <string name=\"draw_regular_polygon_sub\">Nubrėžkite daugiakampį, kuris bus taisyklingas, o ne laisvos formos</string>\n    <string name=\"star_sub\">Nubrėžia žvaigždę nuo pradžios iki pabaigos taško</string>\n    <string name=\"star\">Žvaigždė</string>\n    <string name=\"outlined_star\">Nubrėžta žvaigždė</string>\n    <string name=\"outlined_star_sub\">Nubrėžia žvaigždę nuo pradžios iki pabaigos taško</string>\n    <string name=\"inner_radius_ratio\">Vidinio spindulio santykis</string>\n    <string name=\"draw_regular_star\">Nupieškite įprastą žvaigždę</string>\n    <string name=\"draw_regular_star_sub\">Nubrėžkite žvaigždę, kuri bus įprasta, o ne laisvos formos</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Įgalina antialiasing, kad būtų išvengta aštrių kraštų</string>\n    <string name=\"open_edit_instead_of_preview\">Atidarykite Redaguoti, o ne peržiūrą</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Pasirinkus vaizdą, kurį norite atidaryti (peržiūrėti) „ImageToolbox“, bus atidarytas redagavimo pasirinkimo lapas, o ne peržiūra</string>\n    <string name=\"document_scanner\">Dokumentų skaitytuvas</string>\n    <string name=\"document_scanner_sub\">Nuskaitykite dokumentus ir kurkite PDF arba atskirkite iš jų vaizdus</string>\n    <string name=\"click_to_start_scanning\">Spustelėkite norėdami pradėti nuskaitymą</string>\n    <string name=\"start_scanning\">Pradėti nuskaitymą</string>\n    <string name=\"save_as_pdf\">Išsaugoti kaip pdf</string>\n    <string name=\"share_as_pdf\">Bendrinti kaip pdf</string>\n    <string name=\"options_below_is_for_images\">Toliau pateiktos parinktys skirtos vaizdams išsaugoti, o ne PDF</string>\n    <string name=\"equalize_histogram_hsv\">Išlyginkite HSV histogramą</string>\n    <string name=\"equalize_histogram\">Išlyginti histogramą</string>\n    <string name=\"enter_percentage\">Įveskite procentą</string>\n    <string name=\"allow_enter_by_text_field\">Leisti įvesti teksto lauke</string>\n    <string name=\"allow_enter_by_text_field_sub\">Įgalina teksto lauką už išankstinių nustatymų pasirinkimo, kad juos būtų galima įvesti iškart</string>\n    <string name=\"scale_color_space\">Spalvų erdvės skalė</string>\n    <string name=\"linear\">Linijinis</string>\n    <string name=\"equalize_histogram_pixelation\">Išlyginkite histogramos pikseliavimą</string>\n    <string name=\"grid_size_x\">Tinklelio dydis X</string>\n    <string name=\"grid_size_y\">Tinklelio dydis Y</string>\n    <string name=\"equalize_histogram_adaptive\">Išlyginti histogramą prisitaikanti</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Išlyginkite histogramos adaptyvųjį LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Išlyginti histogramos adaptyviąją LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Apkarpyti iki turinio</string>\n    <string name=\"frame_color\">Rėmo spalva</string>\n    <string name=\"color_to_ignore\">Spalva Ignoruoti</string>\n    <string name=\"template\">Šablonas</string>\n    <string name=\"no_template_filters\">Nepridėta jokių šablonų filtrų</string>\n    <string name=\"create_new\">Sukurti naują</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Nuskaitytas QR kodas nėra tinkamas filtro šablonas</string>\n    <string name=\"scan_qr_code\">Nuskaitykite QR kodą</string>\n    <string name=\"opened_file_have_no_filter_template\">Pasirinktame faile nėra filtro šablono duomenų</string>\n    <string name=\"create_template\">Sukurti šabloną</string>\n    <string name=\"template_name\">Šablono pavadinimas</string>\n    <string name=\"select_template_preview\">Šis vaizdas bus naudojamas šiam filtro šablonui peržiūrėti</string>\n    <string name=\"template_filter\">Šablonų filtras</string>\n    <string name=\"as_qr_code\">Kaip QR kodo vaizdas</string>\n    <string name=\"as_file\">Kaip failas</string>\n    <string name=\"save_as_file\">Išsaugoti kaip failą</string>\n    <string name=\"save_as_qr_code_image\">Išsaugoti kaip QR kodo vaizdą</string>\n    <string name=\"delete_template\">Ištrinti šabloną</string>\n    <string name=\"delete_template_warn\">Ketinate ištrinti pasirinktą šablono filtrą. Šios operacijos anuliuoti negalima</string>\n    <string name=\"added_filter_template\">Pridėtas filtro šablonas pavadinimu \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Filtro peržiūra</string>\n    <string name=\"qr_code\">QR ir brūkšninis kodas</string>\n    <string name=\"qr_code_sub\">Nuskaitykite QR kodą ir gaukite jo turinį arba įklijuokite eilutę, kad sukurtumėte naują</string>\n    <string name=\"code_content\">Kodo turinys</string>\n    <string name=\"scan_qr_code_to_replace_content\">Nuskaitykite bet kokį brūkšninį kodą, kad pakeistumėte turinį lauke, arba įveskite ką nors, kad sugeneruotumėte naują pasirinkto tipo brūkšninį kodą</string>\n    <string name=\"qr_description\">QR aprašymas</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Nustatymuose suteikite fotoaparatui leidimą nuskaityti QR kodą</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Nustatymuose suteikite fotoaparato leidimą nuskaityti dokumentų skaitytuvą</string>\n    <string name=\"cubic\">Kubinis</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hammingas</string>\n    <string name=\"hanning\">Hanningas</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Keturkampis</string>\n    <string name=\"gaussian\">Gauso</string>\n    <string name=\"sphinx\">Sfinksas</string>\n    <string name=\"bartlett\">Bartlettas</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaizeris</string>\n    <string name=\"bartlett_hann\">Bartlettas-Jis</string>\n    <string name=\"box\">Dėžutė</string>\n    <string name=\"bohman\">Bohmanas</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kubinė interpoliacija užtikrina sklandesnį mastelio keitimą, atsižvelgiant į artimiausius 16 pikselių, o tai suteikia geresnių rezultatų nei dvilinijinis</string>\n    <string name=\"bspline_sub\">Naudoja dalimis apibrėžtas daugianario funkcijas, kad sklandžiai interpoliuotų ir aproksimuotų kreivę arba paviršių, lankstų ir ištisinį formos vaizdavimą</string>\n    <string name=\"hamming_sub\">Lango funkcija, naudojama spektriniam nutekėjimui sumažinti siaurinant signalo kraštus, naudinga apdorojant signalą</string>\n    <string name=\"hanning_sub\">Hann lango variantas, dažniausiai naudojamas spektriniam nutekėjimui sumažinti signalų apdorojimo programose</string>\n    <string name=\"blackman_sub\">Lango funkcija, užtikrinanti gerą dažnio skiriamąją gebą sumažindama spektrinį nuotėkį, dažnai naudojama signalų apdorojimui</string>\n    <string name=\"welch_sub\">Lango funkcija, skirta užtikrinti gerą dažnio skiriamąją gebą su mažesniu spektro nuotėkiu, dažnai naudojama signalų apdorojimo programose</string>\n    <string name=\"quadric_sub\">Metodas, kuriame interpoliacijai naudojama kvadratinė funkcija, užtikrinanti sklandžius ir nuolatinius rezultatus</string>\n    <string name=\"gaussian_sub\">Interpoliacijos metodas, kuriame taikoma Gauso funkcija, naudinga norint išlyginti ir sumažinti vaizdų triukšmą</string>\n    <string name=\"sphinx_sub\">Pažangus pakartotinio atrankos metodas, užtikrinantis aukštos kokybės interpoliaciją su minimaliais artefaktais</string>\n    <string name=\"bartlett_sub\">Trikampio lango funkcija, naudojama apdorojant signalą, siekiant sumažinti spektrinį nuotėkį</string>\n    <string name=\"robidoux_sub\">Aukštos kokybės interpoliacijos metodas, optimizuotas natūraliam vaizdo dydžio keitimui, ryškumui ir glotnumui subalansuoti</string>\n    <string name=\"robidoux_sharp_sub\">Ryškesnis Robidoux metodo variantas, optimizuotas aiškaus vaizdo dydžio keitimui</string>\n    <string name=\"spline16_sub\">Spline pagrįstas interpoliacijos metodas, užtikrinantis sklandžius rezultatus naudojant 16 bakstelėjimų filtrą</string>\n    <string name=\"spline36_sub\">Spline pagrįstas interpoliacijos metodas, užtikrinantis sklandžius rezultatus naudojant 36 bakstelėjimų filtrą</string>\n    <string name=\"spline64_sub\">Spline pagrįstas interpoliacijos metodas, užtikrinantis sklandžius rezultatus naudojant 64 bakstelėjimų filtrą</string>\n    <string name=\"kaiser_sub\">Interpoliacijos metodas, kuriame naudojamas Kaiser langas, leidžiantis gerai valdyti pagrindinės skilties pločio ir šoninės skilties lygio kompromisą</string>\n    <string name=\"bartlett_hann_sub\">Hibridinė lango funkcija, jungianti Bartlett ir Hann langus, naudojama signalų apdorojimo spektriniam nutekėjimui sumažinti</string>\n    <string name=\"box_sub\">Paprastas pakartotinio atrankos metodas, kuris naudoja artimiausių pikselių reikšmių vidurkį, todėl dažnai atrodo blokuotas</string>\n    <string name=\"bohman_sub\">Lango funkcija, naudojama spektriniam nutekėjimui sumažinti, užtikrinanti gerą dažnio skiriamąją gebą signalų apdorojimo programose</string>\n    <string name=\"lanczos2_sub\">Pakartotinio mėginių ėmimo metodas, kuriame naudojamas 2 skilčių Lanczos filtras aukštos kokybės interpoliacijai su minimaliais artefaktais</string>\n    <string name=\"lanczos3_sub\">Pakartotinio mėginių ėmimo metodas, kuriame naudojamas 3 skilčių Lanczos filtras aukštos kokybės interpoliacijai su minimaliais artefaktais</string>\n    <string name=\"lanczos4_sub\">Pakartotinio mėginių ėmimo metodas, kuriame naudojamas 4 skilčių Lanczos filtras aukštos kokybės interpoliacijai su minimaliais artefaktais</string>\n    <string name=\"lanczos2_jinc_sub\">Lanczos 2 filtro variantas, kuriame naudojama jinc funkcija, užtikrinanti aukštos kokybės interpoliaciją su minimaliais artefaktais</string>\n    <string name=\"lanczos3_jinc_sub\">Lanczos 3 filtro variantas, kuriame naudojama jinc funkcija, užtikrinanti aukštos kokybės interpoliaciją su minimaliais artefaktais</string>\n    <string name=\"lanczos4_jinc_sub\">Lanczos 4 filtro variantas, kuriame naudojama jinc funkcija, užtikrinanti aukštos kokybės interpoliaciją su minimaliais artefaktais</string>\n    <string name=\"ewa_hanning\">Hanningas EWA</string>\n    <string name=\"ewa_hanning_sub\">Hanningo filtro elipsinio svertinio vidurkio (EWA) variantas sklandžiam interpoliavimui ir pakartotiniam mėginių ėmimui</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elipsinis svertinis vidurkis (EWA) Robidoux filtro variantas, skirtas aukštos kokybės pakartotiniam mėginių ėmimui</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Elipsinis svertinis vidurkis (EWA) Blackman filtro variantas, skirtas sumažinti skambėjimo artefaktus</string>\n    <string name=\"ewa_quadric\">Keturkampis EWA</string>\n    <string name=\"ewa_quadric_sub\">Kvadrinio filtro elipsinio svertinio vidurkio (EWA) variantas sklandžiam interpoliavimui</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elipsinis svertinis vidurkis (EWA) Robidoux Sharp filtro variantas, kad rezultatai būtų ryškesni</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Lanczos 3 Jinc filtro elipsinio svertinio vidurkio (EWA) variantas, skirtas aukštos kokybės pakartotiniam atrankai su sumažintu slapyvardžiu</string>\n    <string name=\"ginseng\">Ženšenis</string>\n    <string name=\"ginseng_sub\">Resampling filtras, sukurtas aukštos kokybės vaizdo apdorojimui su geru ryškumo ir lygumo balansu</string>\n    <string name=\"ewa_ginseng\">Ženšenis EWA</string>\n    <string name=\"ewa_ginseng_sub\">Ženšenio filtro elipsinio svertinio vidurkio (EWA) variantas pagerina vaizdo kokybę</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Lanczos Sharp filtro elipsinio svertinio vidurkio (EWA) variantas, kad būtų pasiekti ryškūs rezultatai su minimaliais artefaktais</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 aštriausias EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Lanczos 4 Sharpest filtro elipsinio svertinio vidurkio (EWA) variantas itin ryškiems vaizdams pakartotinai atrinkti</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Lanczos Soft filtro elipsinio svertinio vidurkio (EWA) variantas, skirtas sklandžiau atrinkti vaizdą</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Haasn sukurtas pakartotinio atrankos filtras sklandžiam ir be artefaktų vaizdo mastelio keitimui</string>\n    <string name=\"format_conversion\">Formato konvertavimas</string>\n    <string name=\"format_conversion_sub\">Konvertuokite vaizdų paketą iš vieno formato į kitą</string>\n    <string name=\"dismiss_forever\">Atsisakyti amžinai</string>\n    <string name=\"image_stacking\">Vaizdų krovimas</string>\n    <string name=\"image_stacking_sub\">Sudėkite vaizdus vieną ant kito naudodami pasirinktus maišymo režimus</string>\n    <string name=\"add_image\">Pridėti vaizdą</string>\n    <string name=\"bins_count\">Dėžės skaičiuojamos</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Išlyginkite histogramos adaptyvųjį HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Išlyginkite histogramos adaptyvųjį HSV</string>\n    <string name=\"edge_mode\">Krašto režimas</string>\n    <string name=\"clip\">Klipas</string>\n    <string name=\"wrap\">Apvyniokite</string>\n    <string name=\"color_blind_scheme\">Spalvų aklumas</string>\n    <string name=\"color_blind_scheme_sub\">Pasirinkite režimą, kad pritaikytumėte temos spalvas pasirinktam daltonizmo variantui</string>\n    <string name=\"protanomaly_sub\">Sunku atskirti raudonus ir žalius atspalvius</string>\n    <string name=\"deuteranomaly_sub\">Sunku atskirti žalius ir raudonus atspalvius</string>\n    <string name=\"tritanomaly_sub\">Sunku atskirti mėlynus ir geltonus atspalvius</string>\n    <string name=\"protanopia_sub\">Nesugebėjimas suvokti raudonų atspalvių</string>\n    <string name=\"deuteranopia_sub\">Nesugebėjimas suvokti žalių atspalvių</string>\n    <string name=\"tritanopia_sub\">Nesugebėjimas suvokti mėlynų atspalvių</string>\n    <string name=\"achromatomaly_sub\">Sumažintas jautrumas visoms spalvoms</string>\n    <string name=\"achromatopsia_sub\">Visiškas daltonizmas, matantis tik pilkus atspalvius</string>\n    <string name=\"not_use_color_blind_scheme\">Nenaudokite Color Blind schemos</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Spalvos bus tiksliai tokios, kaip nustatytos temoje</string>\n    <string name=\"sigmoidal\">Sigmoidinis</string>\n    <string name=\"lagrange_2\">Lagranžas 2</string>\n    <string name=\"lagrange_2_sub\">2 eilės Lagrange interpoliacijos filtras, tinkantis aukštos kokybės vaizdo mastelio keitimui su sklandžiais perėjimais</string>\n    <string name=\"lagrange_3\">Lagranžas 3</string>\n    <string name=\"lagrange_3_sub\">3 eilės Lagrange interpoliacijos filtras, užtikrinantis didesnį tikslumą ir sklandesnius vaizdo mastelio keitimo rezultatus</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Lanczos resampling filtras su didesne eile 6, užtikrinantis ryškesnį ir tikslesnį vaizdo mastelį</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">„Lanczos 6“ filtro variantas, naudojant „Jinc“ funkciją, kad pagerintų vaizdo atrankos kokybę</string>\n    <string name=\"linear_box_blur\">Linijinis langelio suliejimas</string>\n    <string name=\"linear_tent_blur\">Linijinis palapinės suliejimas</string>\n    <string name=\"linear_gaussian_box_blur\">Linijinis Gauso langelio suliejimas</string>\n    <string name=\"linear_stack_blur\">Linijinis dėklo suliejimas</string>\n    <string name=\"gaussian_box_blur\">Gauso langelio suliejimas</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linijinis greitas Gauso suliejimas Kitas</string>\n    <string name=\"linear_fast_gaussian_blur\">Linijinis greitas Gauso suliejimas</string>\n    <string name=\"linear_gaussian_blur\">Linijinis Gauso suliejimas</string>\n    <string name=\"draw_filter_sub\">Pasirinkite vieną filtrą, kad naudotumėte jį kaip dažus</string>\n    <string name=\"replace_filter\">Pakeiskite filtrą</string>\n    <string name=\"pick_filter_info\">Toliau pasirinkite filtrą, kad galėtumėte naudoti jį kaip teptuką piešinyje</string>\n    <string name=\"tiff_compression_scheme\">TIFF suspaudimo schema</string>\n    <string name=\"low_poly\">Žemas poli</string>\n    <string name=\"sand_painting\">Smėlio tapyba</string>\n    <string name=\"image_splitting\">Vaizdo padalijimas</string>\n    <string name=\"image_splitting_sub\">Padalinkite vieną vaizdą į eilutes arba stulpelius</string>\n    <string name=\"fit_to_bounds\">Tinka riboms</string>\n    <string name=\"fit_to_bounds_sub\">Sujunkite apkarpymo dydžio keitimo režimą su šiuo parametru, kad pasiektumėte pageidaujamą elgseną (apkarpyti / pritaikyti formatui)</string>\n    <string name=\"languages_imported\">Kalbos sėkmingai importuotos</string>\n    <string name=\"backup_ocr_models\">Atsarginiai OCR modeliai</string>\n    <string name=\"import_word\">Importuoti</string>\n    <string name=\"export\">Eksportuoti</string>\n    <string name=\"position\">Padėtis</string>\n    <string name=\"center\">centras</string>\n    <string name=\"top_left\">Viršuje kairėje</string>\n    <string name=\"top_right\">Viršuje dešinėje</string>\n    <string name=\"bottom_left\">Apačioje kairėje</string>\n    <string name=\"bottom_right\">Apačioje dešinėje</string>\n    <string name=\"top_center\">Viršutinis centras</string>\n    <string name=\"center_right\">Centras dešinėje</string>\n    <string name=\"bottom_center\">Apatinis centras</string>\n    <string name=\"center_left\">Centras kairėje</string>\n    <string name=\"target_image\">Tikslinis vaizdas</string>\n    <string name=\"palette_transfer\">Paletės perkėlimas</string>\n    <string name=\"enhanced_oil\">Patobulintas aliejus</string>\n    <string name=\"simple_old_tv\">Paprastas senas televizorius</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotemas</string>\n    <string name=\"simple_sketch\">Paprastas eskizas</string>\n    <string name=\"soft_glow\">Minkštas švytėjimas</string>\n    <string name=\"color_poster\">Spalvotas plakatas</string>\n    <string name=\"tri_tone\">Tri tonas</string>\n    <string name=\"third_color\">Trečia spalva</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Klara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Sugrupuotas 2x2 dithering</string>\n    <string name=\"clustered_4x4_dithering\">Sugrupuotas 4x4 dithering</string>\n    <string name=\"clustered_8x8_dithering\">Klasterizuotas 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma dithering</string>\n    <string name=\"no_favorite_options_selected\">Mėgstamiausių parinkčių nepasirinkta, pridėkite jas įrankių puslapyje</string>\n    <string name=\"add_favorites\">Pridėti parankinius</string>\n    <string name=\"harmony_complementary\">Papildomas</string>\n    <string name=\"harmony_analogous\">Analogiškas</string>\n    <string name=\"harmony_triadic\">Triadinis</string>\n    <string name=\"harmony_split_complementary\">Suskaidytas papildomas</string>\n    <string name=\"harmony_tetradic\">Tetradicinis</string>\n    <string name=\"harmony_square\">Kvadratas</string>\n    <string name=\"harmony_analogous_complementary\">Analogiškas + papildomas</string>\n    <string name=\"color_tools\">Spalvų įrankiai</string>\n    <string name=\"color_tools_sub\">Maišykite, sukurkite tonus, generuokite atspalvius ir dar daugiau</string>\n    <string name=\"color_harmonies\">Spalvų harmonijos</string>\n    <string name=\"color_shading\">Spalvų šešėliavimas</string>\n    <string name=\"variation\">Variacija</string>\n    <string name=\"tints\">Atspalviai</string>\n    <string name=\"tones\">Tonai</string>\n    <string name=\"shades\">Atspalviai</string>\n    <string name=\"color_mixing\">Spalvų maišymas</string>\n    <string name=\"color_info\">Spalvos informacija</string>\n    <string name=\"selected_color\">Pasirinkta spalva</string>\n    <string name=\"color_to_mix\">Spalva Maišyti</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Negalima naudoti pinigų, kai įjungtos dinaminės spalvos</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Tikslinis LUT vaizdas</string>\n    <string name=\"amatorka\">Mėgėjas</string>\n    <string name=\"miss_etikate\">Ponia etiketas</string>\n    <string name=\"soft_elegance\">Minkšta elegancija</string>\n    <string name=\"soft_elegance_variant\">Minkštos elegancijos variantas</string>\n    <string name=\"palette_transfer_variant\">Paletės perkėlimo variantas</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Tikslinis 3D LUT failas (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Baliklio aplinkkelis</string>\n    <string name=\"candlelight\">Žvakių šviesa</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Švelnus Gintaras</string>\n    <string name=\"fall_colors\">Rudens spalvos</string>\n    <string name=\"film_stock_50\">Filmo atsargos 50</string>\n    <string name=\"foggy_night\">Miglota naktis</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Gaukite neutralų LUT vaizdą</string>\n    <string name=\"save_empty_lut_sub\">Pirmiausia naudokite savo mėgstamą nuotraukų redagavimo programą ir pritaikykite filtrą neutraliam LUT, kurį galite gauti čia. Kad tai veiktų tinkamai, kiekviena pikselio spalva neturi priklausyti nuo kitų pikselių (pvz., suliejimas neveiks). Kai būsite pasiruošę, naudokite naują LUT vaizdą kaip 512*512 LUT filtro įvestį</string>\n    <string name=\"pop_art\">Pop menas</string>\n    <string name=\"celluloid\">Celiuliozė</string>\n    <string name=\"coffee\">Kava</string>\n    <string name=\"golden_forest\">Auksinis miškas</string>\n    <string name=\"greenish\">Žalsvos spalvos</string>\n    <string name=\"retro_yellow\">Retro geltona</string>\n    <string name=\"links_preview\">Nuorodų peržiūra</string>\n    <string name=\"links_preview_sub\">Įgalina nuorodų peržiūrą tose vietose, kur galite gauti tekstą (QRCcode, OCR ir kt.)</string>\n    <string name=\"links\">Nuorodos</string>\n    <string name=\"ico_size_warning\">ICO failus galima išsaugoti tik maksimaliu 256 x 256 dydžiu</string>\n    <string name=\"gif_type_to_webp\">GIF į WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Konvertuokite GIF vaizdus į WEBP animuotus paveikslėlius</string>\n    <string name=\"webp_tools\">WEBP įrankiai</string>\n    <string name=\"webp_tools_sub\">Konvertuokite vaizdus į WEBP animuotą paveikslėlį arba ištraukite kadrus iš pateiktos WEBP animacijos</string>\n    <string name=\"webp_type_to_image\">WEBP į vaizdus</string>\n    <string name=\"webp_type_to_image_sub\">Konvertuoti WEBP failą į nuotraukų paketą</string>\n    <string name=\"webp_type_to_webp_sub\">Konvertuoti vaizdų paketą į WEBP failą</string>\n    <string name=\"webp_type_to_webp\">Vaizdai į WEBP</string>\n    <string name=\"select_webp_image_to_start\">Norėdami pradėti, pasirinkite WEBP vaizdą</string>\n    <string name=\"manage_storage_extra_types\">Nėra visiškos prieigos prie failų</string>\n    <string name=\"manage_storage_extra_types_sub\">Leiskite visiems failams pasiekti JXL, QOI ir kitus vaizdus, ​​kurie „Android“ neatpažįstami kaip vaizdai. Be leidimo „Image Toolbox“ negali rodyti tų vaizdų</string>\n    <string name=\"default_draw_color\">Numatytoji piešimo spalva</string>\n    <string name=\"default_draw_path_mode\">Numatytasis piešimo kelio režimas</string>\n    <string name=\"add_timestamp\">Pridėti laiko žymą</string>\n    <string name=\"add_timestamp_sub\">Įgalina laiko žymos pridėjimą prie išvesties failo pavadinimo</string>\n    <string name=\"formatted_timestamp\">Suformatuota laiko žyma</string>\n    <string name=\"formatted_timestamp_sub\">Įgalinkite laiko žymos formatavimą išvesties failo pavadinime, o ne pagrindiniame milis</string>\n    <string name=\"enable_timestamps_to_format_them\">Įgalinkite laiko žymes, kad pasirinktumėte jų formatą</string>\n    <string name=\"one_time_save_location\">Vienkartinė išsaugojimo vieta</string>\n    <string name=\"one_time_save_location_sub\">Peržiūrėkite ir redaguokite vienkartines išsaugojimo vietas, kurias galite naudoti ilgai paspaudę išsaugojimo mygtuką dažniausiai visose parinktyse</string>\n    <string name=\"recently_used\">Neseniai naudotas</string>\n    <string name=\"fit_description\">Pritaikykite vaizdą pagal nurodytus matmenis ir pritaikykite fono suliejimą arba spalvą</string>\n    <string name=\"tools_arrangement\">Įrankių išdėstymas</string>\n    <string name=\"group_tools_by_type\">Grupuokite įrankius pagal tipą</string>\n    <string name=\"group_tools_by_type_sub\">Grupuoja įrankius pagrindiniame ekrane pagal jų tipą, o ne tinkintą sąrašo išdėstymą</string>\n    <string name=\"default_values\">Numatytosios reikšmės</string>\n    <string name=\"system_bars_visibility\">Sistemos juostų matomumas</string>\n    <string name=\"show_system_bars_by_swipe\">Rodyti sistemos juostas perbraukiant</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Įgalinamas perbraukimas, kad būtų rodomos sistemos juostos, jei jos paslėptos</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Slėpti viską</string>\n    <string name=\"show_all\">Rodyti viską</string>\n    <string name=\"hide_nav_bar\">Slėpti navigacijos juostą</string>\n    <string name=\"hide_status_bar\">Slėpti būsenos juostą</string>\n    <string name=\"noise_generation\">Triukšmo generavimas</string>\n    <string name=\"noise_generation_sub\">Sukurkite įvairius garsus, pvz., Perlin ar kitų tipų garsus</string>\n    <string name=\"frequency\">Dažnis</string>\n    <string name=\"noise_type\">Triukšmo tipas</string>\n    <string name=\"rotation_type\">Sukimosi tipas</string>\n    <string name=\"fractal_type\">Fraktalų tipas</string>\n    <string name=\"octaves\">oktavos</string>\n    <string name=\"lacunarity\">Lacuariškumas</string>\n    <string name=\"gain\">Pelnas</string>\n    <string name=\"weighted_strength\">Pasverta jėga</string>\n    <string name=\"ping_pong_strength\">Ping Pong Jėga</string>\n    <string name=\"distance_function\">Atstumo funkcija</string>\n    <string name=\"return_type\">Grąžinimo tipas</string>\n    <string name=\"jitter\">Drebulys</string>\n    <string name=\"domain_warp\">Domeno deformacija</string>\n    <string name=\"alignment\">Lygiavimas</string>\n    <string name=\"custom_filename\">Pasirinktinis failo pavadinimas</string>\n    <string name=\"custom_filename_sub\">Pasirinkite vietą ir failo pavadinimą, kurie bus naudojami dabartiniam vaizdui išsaugoti</string>\n    <string name=\"saved_to_custom\">Išsaugota aplanke pasirinktu pavadinimu</string>\n    <string name=\"collage_maker\">Koliažų kūrėjas</string>\n    <string name=\"collage_maker_sub\">Kurkite koliažus iš iki 20 vaizdų</string>\n    <string name=\"collage_type\">Koliažo tipas</string>\n    <string name=\"collages_info\">Laikykite vaizdą, kad pakeistumėte, perkeltumėte ir priartintumėte, kad sureguliuotumėte padėtį</string>\n    <string name=\"disable_rotation\">Išjungti sukimąsi</string>\n    <string name=\"disable_rotation_sub\">Neleidžia pasukti vaizdų dviem pirštų gestais</string>\n    <string name=\"enable_snapping_to_borders\">Įgalinti pririšimą prie kraštinių</string>\n    <string name=\"enable_snapping_to_borders_sub\">Perkėlus arba padidinus mastelį, vaizdai užsifiksuos, kad užpildytų rėmelio kraštus</string>\n    <string name=\"histogram\">Histograma</string>\n    <string name=\"histogram_sub\">RGB arba Brightness vaizdo histograma, padėsianti koreguoti</string>\n    <string name=\"image_for_histogram\">Šis vaizdas bus naudojamas RGB ir šviesumo histogramoms generuoti</string>\n    <string name=\"tesseract_options\">Tesseact parinktys</string>\n    <string name=\"tesseract_options_sub\">Taikykite kai kuriuos tesseract variklio įvesties kintamuosius</string>\n    <string name=\"custom_options\">Pasirinktinės parinktys</string>\n    <string name=\"custom_params_info\">Parinktys turi būti įvedamos pagal šį šabloną: \\\"--{parinkties_pavadinimas} {value}\\\"</string>\n    <string name=\"auto_crop\">Automatinis apkarpymas</string>\n    <string name=\"free_corners\">Nemokami kampai</string>\n    <string name=\"free_corners_sub\">Apkarpykite vaizdą pagal daugiakampį, tai taip pat pataiso perspektyvą</string>\n    <string name=\"coerce_points_to_image_bounds\">Priversti taškus į vaizdo ribas</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Taškai nebus ribojami vaizdo ribomis, tai naudinga norint tiksliau koreguoti perspektyvą</string>\n    <string name=\"mask\">Kaukė</string>\n    <string name=\"spot_heal_sub\">Užpildykite turinį pagal nubrėžtą kelią</string>\n    <string name=\"spot_heal\">Gydymo vieta</string>\n    <string name=\"use_circle_kernel\">Naudokite Circle Kernel</string>\n    <string name=\"opening\">Atidarymas</string>\n    <string name=\"closing\">Uždarymas</string>\n    <string name=\"morphological_gradient\">Morfologinis gradientas</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Juoda skrybėlė</string>\n    <string name=\"tone_curves\">Tonų kreivės</string>\n    <string name=\"reset_curves\">Iš naujo nustatyti kreives</string>\n    <string name=\"reset_curves_sub\">Kreivės bus grąžintos į numatytąją vertę</string>\n    <string name=\"line_style\">Linijos stilius</string>\n    <string name=\"gap_size\">Tarpo dydis</string>\n    <string name=\"dashed\">Brūkšniuotas</string>\n    <string name=\"dot_dashed\">Brūkšninis taškas</string>\n    <string name=\"stamped\">Antspauduotas</string>\n    <string name=\"zigzag\">Zigzagas</string>\n    <string name=\"dashed_sub\">Nubrėžia punktyrinę liniją palei nubrėžtą kelią su nurodytu tarpo dydžiu</string>\n    <string name=\"dot_dashed_sub\">Nubrėžia tašką ir punktyrinę liniją palei nurodytą kelią</string>\n    <string name=\"defaultt_sub\">Tiesiog numatytosios tiesios linijos</string>\n    <string name=\"stamped_sub\">Nubrėžia pasirinktas figūras išilgai kelio su nurodytais tarpais</string>\n    <string name=\"zigzag_sub\">Nubrėžia banguotu zigzagu palei taką</string>\n    <string name=\"zigzag_ratio\">Zigzago santykis</string>\n    <string name=\"create_shortcut\">Sukurti nuorodą</string>\n    <string name=\"create_shortcut_subtitle\">Įrankis bus pridėtas prie paleidimo priemonės pagrindinio ekrano kaip spartusis klavišas, naudokite jį kartu su nustatymu \\\"Praleisti failų pasirinkimą\\\", kad pasiektumėte reikiamą elgesį</string>\n    <string name=\"dont_stack_frames\">Nekraukite rėmelių</string>\n    <string name=\"dont_stack_frames_sub\">Leidžia išmesti ankstesnius rėmelius, todėl jie nebus sukrauti vienas ant kito</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Rėmeliai bus perbraukti vienas į kitą</string>\n    <string name=\"crossfade_count\">Crossfade kadrų skaičius</string>\n    <string name=\"threshold_one\">Slenkstis vienas</string>\n    <string name=\"threshold_two\">Antras slenkstis</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Veidrodis 101</string>\n    <string name=\"enhanced_zoom_blur\">Patobulintas priartinimo suliejimas</string>\n    <string name=\"laplacian_simple\">Paprastas laplasietis</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Pagalbinis tinklelis</string>\n    <string name=\"helper_grid_sub\">Virš piešimo srities rodomas atraminis tinklelis, kad būtų lengviau atlikti tikslias manipuliacijas</string>\n    <string name=\"grid_color\">Tinklelio spalva</string>\n    <string name=\"cell_width\">Ląstelės plotis</string>\n    <string name=\"cell_height\">Ląstelės aukštis</string>\n    <string name=\"compact_selectors\">Kompaktiški selektoriai</string>\n    <string name=\"compact_selectors_sub\">Kai kurie pasirinkimo valdikliai naudos kompaktišką išdėstymą, kad užimtų mažiau vietos</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Nustatymuose suteikite fotoaparato leidimą fotografuoti</string>\n    <string name=\"layout\">Išdėstymas</string>\n    <string name=\"main_screen_title\">Pagrindinio ekrano pavadinimas</string>\n    <string name=\"constant_rate_factor\">Pastovios normos koeficientas (CRF)</string>\n    <string name=\"crf_sub\">%1$s reikšmė reiškia lėtą glaudinimą, dėl kurio failo dydis yra palyginti mažas. %2$s reiškia greitesnį suspaudimą, todėl failas yra didelis.</string>\n    <string name=\"lut_library\">Lut biblioteka</string>\n    <string name=\"lut_library_sub\">Atsisiųskite LUT kolekciją, kurią galėsite pritaikyti atsisiuntę</string>\n    <string name=\"filter_preview_image_sub\">Pakeiskite numatytąją filtrų vaizdo peržiūrą</string>\n    <string name=\"filter_preview_image\">Vaizdo peržiūra</string>\n    <string name=\"hide\">Slėpti</string>\n    <string name=\"show\">Rodyti</string>\n    <string name=\"slider_type\">Slankiklio tipas</string>\n    <string name=\"fancy\">Išgalvotas</string>\n    <string name=\"material_2\">2 medžiaga</string>\n    <string name=\"fancy_sub\">Prabangiai atrodantis slankiklis. Tai numatytoji parinktis</string>\n    <string name=\"material_2_sub\">2 medžiagos slankiklis</string>\n    <string name=\"material_you_slider_sub\">Slankiklis „Material You“.</string>\n    <string name=\"apply\">Taikyti</string>\n    <string name=\"center_align_dialog_buttons\">Centriniai dialogo mygtukai</string>\n    <string name=\"center_align_dialog_buttons_sub\">Jei įmanoma, dialogo langų mygtukai bus išdėstyti centre, o ne kairėje</string>\n    <string name=\"open_source_licenses\">Atvirojo kodo licencijos</string>\n    <string name=\"open_source_licenses_sub\">Peržiūrėkite šioje programoje naudojamų atvirojo kodo bibliotekų licencijas</string>\n    <string name=\"area\">Plotas</string>\n    <string name=\"area_sub\">Atranka naudojant pikselių ploto santykį. Tai gali būti tinkamiausias vaizdų naikinimo metodas, nes jis duoda rezultatus be muaro. Bet kai vaizdas padidinamas, jis panašus į \\\"Arčiausiai\\\" metodą.</string>\n    <string name=\"enable_tonemapping\">Įgalinti Tonemapping</string>\n    <string name=\"enter_percent\">Įveskite %</string>\n    <string name=\"unknown_host\">Negalite pasiekti svetainės, pabandykite naudoti VPN arba patikrinkite, ar teisingas URL</string>\n    <string name=\"markup_layers\">Žymėjimo sluoksniai</string>\n    <string name=\"markup_layers_sub\">Sluoksnių režimas su galimybe laisvai dėti vaizdus, ​​tekstą ir kt</string>\n    <string name=\"edit_layer\">Redaguoti sluoksnį</string>\n    <string name=\"layers_on_image\">Sluoksniai ant vaizdo</string>\n    <string name=\"layers_on_image_sub\">Naudokite vaizdą kaip foną ir pridėkite skirtingus sluoksnius ant jo</string>\n    <string name=\"layers_on_background\">Sluoksniai fone</string>\n    <string name=\"layers_on_background_sub\">Tas pats, kaip ir pirmasis variantas, bet su spalva vietoj paveikslėlio</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Greitųjų nustatymų pusė</string>\n    <string name=\"fast_settings_side_sub\">Redaguodami vaizdus pasirinktoje pusėje pridėkite slankiąją juostelę, kurią spustelėjus atsidarys greiti nustatymai</string>\n    <string name=\"clear_selection\">Išvalyti pasirinkimą</string>\n    <string name=\"settings_group_visibility_hidden\">Nustatymų grupė \\\"%1$s\\\" bus sutraukta pagal numatytuosius nustatymus</string>\n    <string name=\"settings_group_visibility_visible\">Nustatymų grupė \\\"%1$s\\\" bus išplėsta pagal numatytuosius nustatymus</string>\n    <string name=\"base_64_tools\">„Base64“ įrankiai</string>\n    <string name=\"base_64_tools_sub\">Iššifruokite „Base64“ eilutę į vaizdą arba užkoduokite vaizdą į „Base64“ formatą</string>\n    <string name=\"base_64\">Bazė64</string>\n    <string name=\"not_a_valid_base_64\">Pateikta vertė nėra tinkama Base64 eilutė</string>\n    <string name=\"copy_not_a_valid_base_64\">Negalima nukopijuoti tuščios arba netinkamos Base64 eilutės</string>\n    <string name=\"paste_base_64\">Įklijuoti pagrindą64</string>\n    <string name=\"copy_base_64\">Kopijuoti bazę64</string>\n    <string name=\"base_64_tips\">Įkelkite vaizdą, kad nukopijuotumėte arba išsaugotumėte Base64 eilutę. Jei turite pačią eilutę, galite ją įklijuoti aukščiau, kad gautumėte vaizdą</string>\n    <string name=\"save_base_64\">Išsaugoti bazę64</string>\n    <string name=\"share_base_64\">Bendrinti bazę64</string>\n    <string name=\"options\">Parinktys</string>\n    <string name=\"actions\">Veiksmai</string>\n    <string name=\"import_base_64\">Importavimo bazė64</string>\n    <string name=\"base_64_actions\">„Base64“ veiksmai</string>\n    <string name=\"add_outline\">Pridėti kontūrą</string>\n    <string name=\"add_outline_sub\">Pridėkite kontūrą aplink tekstą su nurodyta spalva ir pločiu</string>\n    <string name=\"outline_color\">Kontūro spalva</string>\n    <string name=\"outline_size\">Kontūro dydis</string>\n    <string name=\"rotation\">Rotacija</string>\n    <string name=\"checksum_as_filename\">Kontrolinė suma kaip failo pavadinimas</string>\n    <string name=\"checksum_as_filename_sub\">Išvesties vaizdai turės pavadinimą, atitinkantį jų duomenų kontrolinę sumą</string>\n    <string name=\"free_software_partner\">Nemokama programinė įranga (partneris)</string>\n    <string name=\"free_software_partner_sub\">Daugiau naudingos programinės įrangos Android programų partnerių kanale</string>\n    <string name=\"algorithms\">Algoritmas</string>\n    <string name=\"checksum_tools\">Kontrolinės sumos įrankiai</string>\n    <string name=\"checksum_tools_sub\">Palyginkite kontrolines sumas, apskaičiuokite maišą arba kurkite šešioliktaines eilutes iš failų naudodami skirtingus maišos algoritmus</string>\n    <string name=\"calculate\">Apskaičiuokite</string>\n    <string name=\"text_hash\">Teksto maiša</string>\n    <string name=\"checksum\">Kontrolinė suma</string>\n    <string name=\"pick_file_to_checksum\">Pasirinkite failą, kad apskaičiuotumėte jo kontrolinę sumą pagal pasirinktą algoritmą</string>\n    <string name=\"enter_text_to_checksum\">Įveskite tekstą, kad apskaičiuotumėte jo kontrolinę sumą pagal pasirinktą algoritmą</string>\n    <string name=\"source_checksum\">Šaltinio kontrolinė suma</string>\n    <string name=\"checksum_to_compare\">Kontrolinė suma Palyginti</string>\n    <string name=\"match\">Rungtynės!</string>\n    <string name=\"difference\">Skirtumas</string>\n    <string name=\"match_sub\">Kontrolinės sumos yra lygios, tai gali būti saugu</string>\n    <string name=\"difference_sub\">Kontrolinės sumos nėra lygios, failas gali būti nesaugus!</string>\n    <string name=\"mesh_gradients\">Tinklelio gradientai</string>\n    <string name=\"collection_mesh_gradients_sub\">Peržiūrėkite internetinę tinklelio gradientų kolekciją</string>\n    <string name=\"wrong_font\">Galima importuoti tik TTF ir OTF šriftus</string>\n    <string name=\"import_font\">Importuoti šriftą (TTF / OTF)</string>\n    <string name=\"export_fonts\">Eksportuoti šriftus</string>\n    <string name=\"imported_fonts\">Importuoti šriftai</string>\n    <string name=\"error_while_saving\">Išsaugant bandymą įvyko klaida, pabandykite pakeisti išvesties aplanką</string>\n    <string name=\"filename_is_not_set\">Failo pavadinimas nenustatytas</string>\n    <string name=\"none\">Nėra</string>\n    <string name=\"edit_exif_screen\">Redaguoti EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Pakeiskite vieno vaizdo metaduomenis be pakartotinio suspaudimo</string>\n    <string name=\"edit_exif_tag\">Palieskite, jei norite redaguoti galimas žymas</string>\n    <string name=\"change_sticker\">Keisti lipduką</string>\n    <string name=\"fit_width\">Pritaikyti plotį</string>\n    <string name=\"fit_height\">Tinkamo aukščio</string>\n    <string name=\"batch_compare\">Palyginti partiją</string>\n    <string name=\"pick_files_to_checksum\">Pasirinkite failą / failus, kad apskaičiuotumėte jo kontrolinę sumą pagal pasirinktą algoritmą</string>\n    <string name=\"pick_files\">Pasirinkite failus</string>\n    <string name=\"pick_directory\">Pasirinkite katalogą</string>\n    <string name=\"head_length_scale\">Galvos ilgio skalė</string>\n    <string name=\"stamp\">Antspaudas</string>\n    <string name=\"timestamp\">Laiko žyma</string>\n    <string name=\"format_pattern\">Formato šablonas</string>\n    <string name=\"padding\">Paminkštinimas</string>\n    <string name=\"image_cutting\">Vaizdo pjovimas</string>\n    <string name=\"image_cutting_sub\">Iškirpti vaizdo dalį ir sujungti kairę (gali būti atvirkštinė) vertikaliomis arba horizontaliomis linijomis</string>\n    <string name=\"vertical_pivot_line\">Vertikali sukimosi linija</string>\n    <string name=\"horizontal_pivot_line\">Horizontali sukimosi linija</string>\n    <string name=\"inverse_selection\">Atvirkštinis pasirinkimas</string>\n    <string name=\"inverse_vertical_selection_sub\">Vertikali nupjauta dalis bus palikta, o ne sujungti dalis aplink nupjautą vietą</string>\n    <string name=\"inverse_horizontal_selection_sub\">Horizontali nupjauta dalis bus palikta, o ne sujungti dalis aplink nupjautą vietą</string>\n    <string name=\"collection_mesh_gradients\">Tinklelio gradientų kolekcija</string>\n    <string name=\"mesh_gradients_sub\">Sukurkite tinklelio gradientą naudodami pasirinktinį mazgų kiekį ir skiriamąją gebą</string>\n    <string name=\"gradient_maker_type_image_mesh\">Tinklelio gradiento perdanga</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Sukurkite pateiktų vaizdų viršaus tinklinį gradientą</string>\n    <string name=\"points_customization\">Taškų pritaikymas</string>\n    <string name=\"grid_size\">Tinklelio dydis</string>\n    <string name=\"resolution_x\">X rezoliucija</string>\n    <string name=\"resolution_y\">Rezoliucija Y</string>\n    <string name=\"resolution\">Rezoliucija</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">Paryškinkite spalvą</string>\n    <string name=\"pixel_comparison_type\">Pikselių palyginimo tipas</string>\n    <string name=\"scan_barcode\">Nuskaityti brūkšninį kodą</string>\n    <string name=\"height_ratio\">Aukščio santykis</string>\n    <string name=\"barcode_type\">Brūkšninio kodo tipas</string>\n    <string name=\"enforce_bw\">Įgyvendinti nespalvotą</string>\n    <string name=\"enforce_bw_sub\">Brūkšninio kodo vaizdas bus visiškai nespalvotas ir nenuspalvintas pagal programos temą</string>\n    <string name=\"barcodes_sub\">Nuskaitykite bet kokį brūkšninį kodą (QR, EAN, AZTEC ir kt.) ir gaukite jo turinį arba įklijuokite tekstą, kad sukurtumėte naują</string>\n    <string name=\"no_barcode_found\">Brūkšninio kodo nerasta</string>\n    <string name=\"generated_barcode_will_be_here\">Sugeneruotas brūkšninis kodas bus čia</string>\n    <string name=\"audio_cover_extractor\">Garso viršeliai</string>\n    <string name=\"audio_cover_extractor_sub\">Iš garso failų ištraukite albumo viršelio vaizdus, ​​palaikomi dažniausiai naudojami formatai</string>\n    <string name=\"pick_audio_to_start\">Norėdami pradėti, pasirinkite garso įrašą</string>\n    <string name=\"pick_audio\">Pasirinkite garso įrašą</string>\n    <string name=\"no_covers_found\">Viršelių nerasta</string>\n    <string name=\"crash_title\">Oi… Kažkas ne taip</string>\n    <string name=\"ocr_write_to_file\">Rašyti į failą</string>\n    <string name=\"ocr_write_to_file_sub\">Ištraukite tekstą iš vaizdų paketo ir išsaugokite jį viename tekstiniame faile</string>\n    <string name=\"ocr_write_to_metadata\">Rašyti į metaduomenis</string>\n    <string name=\"ocr_write_to_metadata_sub\">Ištraukite tekstą iš kiekvieno vaizdo ir įdėkite jį į atitinkamų nuotraukų EXIF ​​informaciją</string>\n    <string name=\"invisible_mode\">Nematomas režimas</string>\n    <string name=\"invisible_mode_sub\">Naudokite steganografiją, kad sukurtumėte akims nematomus vandens ženklus savo vaizdų baitų viduje</string>\n    <string name=\"use_lsb\">Naudokite LSB</string>\n    <string name=\"use_lsb_sub\">Bus naudojamas LSB (Less Significant Bit) steganografijos metodas, kitu atveju FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Automatinis raudonų akių pašalinimas</string>\n    <string name=\"password\">Slaptažodis</string>\n    <string name=\"unlock\">Atrakinti</string>\n    <string name=\"pdf_is_protected\">PDF yra apsaugotas</string>\n    <string name=\"operation_almost_complete\">Operacija beveik baigta. Norint atšaukti dabar, reikės iš naujo paleisti</string>\n    <string name=\"sort_by_date_modified\">Pakeitimo data</string>\n    <string name=\"sort_by_date_modified_reversed\">Pakeitimo data (atvirkščiai)</string>\n    <string name=\"sort_by_size\">Dydis</string>\n    <string name=\"sort_by_size_reversed\">Dydis (atvirkštinis)</string>\n    <string name=\"sort_by_mime_type\">MIME tipas</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME tipas (atvirkštinis)</string>\n    <string name=\"sort_by_extension\">Pratęsimas</string>\n    <string name=\"sort_by_extension_reversed\">Plėtinys (atvirkštinis)</string>\n    <string name=\"sort_by_date_added\">Įtraukimo data</string>\n    <string name=\"sort_by_date_added_reversed\">Pridėjimo data (atvirkščiai)</string>\n    <string name=\"left_to_right\">Iš kairės į dešinę</string>\n    <string name=\"right_to_left\">Iš dešinės į kairę</string>\n    <string name=\"top_to_bottom\">Iš viršaus į apačią</string>\n    <string name=\"bottom_to_top\">Iš apačios į viršų</string>\n    <string name=\"liquid_glass\">Skystas stiklas</string>\n    <string name=\"liquid_glass_sub\">Jungiklis, pagrįstas neseniai paskelbta IOS 26 ir jos skysto stiklo dizaino sistema</string>\n    <string name=\"pick_image_or_base64\">Toliau pasirinkite vaizdą arba įklijuokite / importuokite „Base64“ duomenis</string>\n    <string name=\"type_image_link\">Norėdami pradėti, įveskite paveikslėlio nuorodą</string>\n    <string name=\"paste_link\">Įklijuoti nuorodą</string>\n    <string name=\"kaleidoscope\">Kaleidoskopas</string>\n    <string name=\"secondary_angle\">Antrinis kampas</string>\n    <string name=\"sides\">Šonai</string>\n    <string name=\"channel_mix\">Kanalų mišinys</string>\n    <string name=\"blue_green\">Mėlyna žalia</string>\n    <string name=\"red_blue\">Raudona mėlyna</string>\n    <string name=\"green_red\">Žalia raudona</string>\n    <string name=\"into_red\">Į raudoną</string>\n    <string name=\"into_green\">Į žalią</string>\n    <string name=\"into_blue\">Į mėlyną</string>\n    <string name=\"cyan\">Žydra spalva</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Geltona</string>\n    <string name=\"color_halftone\">Spalva Pustonis</string>\n    <string name=\"contour\">Kontūras</string>\n    <string name=\"levels\">Lygiai</string>\n    <string name=\"offset\">Užskaita</string>\n    <string name=\"voronoi_crystallize\">Voronojaus kristalizacija</string>\n    <string name=\"shape\">Forma</string>\n    <string name=\"stretch\">Ištempti</string>\n    <string name=\"randomness\">Atsitiktinumas</string>\n    <string name=\"despeckle\">Išblukinti</string>\n    <string name=\"diffuse\">Difuzinis</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Antrasis spindulys</string>\n    <string name=\"equalize\">Išlyginti</string>\n    <string name=\"glow\">Švytėjimas</string>\n    <string name=\"whirl_and_pinch\">Sūkurys ir žiupsnelis</string>\n    <string name=\"pointillize\">Pointilizuoti</string>\n    <string name=\"border_color\">Krašto spalva</string>\n    <string name=\"polar_coordinates\">Poliarinės koordinatės</string>\n    <string name=\"rect_to_polar\">Tiesiai į poliarinį</string>\n    <string name=\"polar_to_rect\">Poliarinis į tiesiąją</string>\n    <string name=\"invert_in_circle\">Apverskite ratu</string>\n    <string name=\"reduce_noise\">Sumažinti Triukšmą</string>\n    <string name=\"simple_solarize\">Paprastas soliarizavimas</string>\n    <string name=\"weave\">Pynimas</string>\n    <string name=\"x_gap\">X tarpas</string>\n    <string name=\"y_gap\">Y tarpas</string>\n    <string name=\"x_width\">X plotis</string>\n    <string name=\"y_wdth\">Y Plotis</string>\n    <string name=\"twirl\">Sukti</string>\n    <string name=\"rubber_stmp\">Guminis antspaudas</string>\n    <string name=\"smear\">Ištepti</string>\n    <string name=\"density\">Tankis</string>\n    <string name=\"mix\">Sumaišykite</string>\n    <string name=\"sphere_lensh_distortion\">Sferinis objektyvo iškraipymas</string>\n    <string name=\"refraction_index\">Refrakcijos rodiklis</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Skleidimo kampas</string>\n    <string name=\"sparkle\">Sparkle</string>\n    <string name=\"rays\">Spinduliai</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradientas</string>\n    <string name=\"moire\">Marija</string>\n    <string name=\"autumn\">Ruduo</string>\n    <string name=\"bone\">Kaulas</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Žiema</string>\n    <string name=\"ocean\">Vandenynas</string>\n    <string name=\"summer\">Vasara</string>\n    <string name=\"spring\">Pavasaris</string>\n    <string name=\"cool_variant\">Šaunus variantas</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rožinė</string>\n    <string name=\"hot\">Karšta</string>\n    <string name=\"parula\">Žodis</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plazma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Piliečiai</string>\n    <string name=\"twilight\">Prieblanda</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspektyva Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Leisti apkarpyti</string>\n    <string name=\"crop_or_perspective\">Pasėlis arba perspektyva</string>\n    <string name=\"absolute\">Absoliutus</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Giliai žalia</string>\n    <string name=\"lens_correction\">Objektyvo korekcija</string>\n    <string name=\"target_lens_profile\">Tikslinio objektyvo profilio failas JSON formatu</string>\n    <string name=\"download_ready_lens_profiles\">Atsisiųskite paruoštus objektyvo profilius</string>\n    <string name=\"part_percents\">Dalies procentai</string>\n    <string name=\"export_as_json\">Eksportuoti kaip JSON</string>\n    <string name=\"export_as_json_sub\">Nukopijuokite eilutę su paletės duomenimis kaip JSON atvaizdą</string>\n    <string name=\"seam_carving\">Siūlių drožyba</string>\n    <string name=\"home_screen\">Pagrindinis ekranas</string>\n    <string name=\"lock_screen\">Užrakinimo ekranas</string>\n    <string name=\"built_in\">Įmontuotas</string>\n    <string name=\"wallpapers_export\">Užsklandos eksportas</string>\n    <string name=\"refresh\">Atnaujinti</string>\n    <string name=\"wallpapers_export_sub\">Gaukite dabartinius namų, užrakto ir įmontuotus fono paveikslėlius</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Suteikite prieigą prie visų failų, to reikia norint gauti fono paveikslėlius</string>\n    <string name=\"allow_read_media_images_for_wp\">Nepakanka tvarkyti išorinės saugyklos leidimo, turite leisti prieigą prie vaizdų, būtinai pasirinkite \\\"Leisti viską\\\"</string>\n    <string name=\"add_preset_to_filename\">Pridėti išankstinį nustatymą prie failo pavadinimo</string>\n    <string name=\"add_preset_to_filename_sub\">Prie vaizdo failo pavadinimo pridedamas priesaga su pasirinktu išankstiniu nustatymu</string>\n    <string name=\"add_image_scale_mode_to_filename\">Pridėti vaizdo mastelio režimą prie failo pavadinimo</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Prie vaizdo failo pavadinimo prideda priesagą su pasirinktu vaizdo mastelio režimu</string>\n    <string name=\"ascii_art\">Ascii str</string>\n    <string name=\"ascii_art_sub\">Konvertuokite paveikslėlį į ASCII tekstą, kuris atrodys kaip vaizdas</string>\n    <string name=\"params\">Paramos</string>\n    <string name=\"invert_colors_ascii_sub\">Tam, kad kai kuriais atvejais būtų geresnis rezultatas, vaizdui taikomas neigiamas filtras</string>\n    <string name=\"processing_screenshot\">Apdorojama ekrano kopija</string>\n    <string name=\"screenshot_not_captured_try_again\">Ekrano kopija neužfiksuota, bandykite dar kartą</string>\n    <string name=\"skipped_saving\">Išsaugojimas praleistas</string>\n    <string name=\"skipped_saving_multiple\">%1$s failai praleisti</string>\n    <string name=\"allow_skip_if_larger\">Leisti praleisti, jei didesnis</string>\n    <string name=\"allow_skip_if_larger_sub\">Kai kuriems įrankiams bus leidžiama praleisti vaizdų įrašymą, jei gautas failo dydis būtų didesnis nei originalas</string>\n    <string name=\"qr_type_calendar_event\">Kalendoriaus įvykis</string>\n    <string name=\"qr_type_contact_info\">Susisiekite</string>\n    <string name=\"qr_type_email\">El. paštas</string>\n    <string name=\"qr_type_geo_point\">Vieta</string>\n    <string name=\"qr_type_phone\">Telefonas</string>\n    <string name=\"qr_type_plain\">Tekstas</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Atviras tinklas</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefonas</string>\n    <string name=\"message\">Pranešimas</string>\n    <string name=\"address\">Adresas</string>\n    <string name=\"subject\">Tema</string>\n    <string name=\"body\">Kūnas</string>\n    <string name=\"name\">Vardas</string>\n    <string name=\"organization\">Organizacija</string>\n    <string name=\"title\">Pavadinimas</string>\n    <string name=\"phones\">Telefonai</string>\n    <string name=\"emails\">Laiškai</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Adresai</string>\n    <string name=\"summary\">Santrauka</string>\n    <string name=\"description\">Aprašymas</string>\n    <string name=\"location\">Vieta</string>\n    <string name=\"organizer\">Organizatorius</string>\n    <string name=\"start_date\">Pradžios data</string>\n    <string name=\"end_date\">Pabaigos data</string>\n    <string name=\"status\">Būsena</string>\n    <string name=\"latitude\">Platuma</string>\n    <string name=\"longitude\">Ilguma</string>\n    <string name=\"create_barcode\">Sukurti brūkšninį kodą</string>\n    <string name=\"edit_barcode\">Redaguoti brūkšninį kodą</string>\n    <string name=\"wifi_configuration\">Wi-Fi konfigūracija</string>\n    <string name=\"security\">Saugumas</string>\n    <string name=\"pick_contact\">Pasirinkite kontaktą</string>\n    <string name=\"grant_contact_permission\">Nustatymuose suteikite kontaktams leidimą automatiškai pildyti naudojant pasirinktą kontaktą</string>\n    <string name=\"contact_info\">Kontaktinė informacija</string>\n    <string name=\"first_name\">Vardas</string>\n    <string name=\"middle_name\">Vidurinis vardas</string>\n    <string name=\"last_name\">Pavardė</string>\n    <string name=\"pronunciation\">Tarimas</string>\n    <string name=\"add_phone\">Pridėti telefoną</string>\n    <string name=\"add_email\">Pridėti el</string>\n    <string name=\"add_address\">Pridėti adresą</string>\n    <string name=\"website\">Svetainė</string>\n    <string name=\"add_website\">Pridėti svetainę</string>\n    <string name=\"formatted_name\">Suformatuotas pavadinimas</string>\n    <string name=\"qr_code_top_image\">Šis vaizdas bus naudojamas virš brūkšninio kodo įdėti</string>\n    <string name=\"code_customization\">Kodo pritaikymas</string>\n    <string name=\"qr_logo_image\">Šis vaizdas bus naudojamas kaip logotipas QR kodo centre</string>\n    <string name=\"logo\">Logotipas</string>\n    <string name=\"logo_padding\">Logotipo pamušalas</string>\n    <string name=\"logo_size\">Logotipo dydis</string>\n    <string name=\"logo_corners\">Logotipo kampai</string>\n    <string name=\"fourth_eye\">Ketvirtoji akis</string>\n    <string name=\"fourth_eye_description\">Prideda akių simetriją prie qr kodo pridedant ketvirtą akį apatiniame galo kampe</string>\n    <string name=\"pixel_shape\">Pikselio forma</string>\n    <string name=\"frame_shape\">Rėmo forma</string>\n    <string name=\"ball_shape\">Rutulio forma</string>\n    <string name=\"error_correction_level\">Klaidų taisymo lygis</string>\n    <string name=\"dark_color\">Tamsi spalva</string>\n    <string name=\"light_color\">Šviesios spalvos</string>\n    <string name=\"hyper_os\">Hiper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS stilius</string>\n    <string name=\"mask_pattern\">Kaukės raštas</string>\n    <string name=\"code_may_be_not_scannable\">Šio kodo gali nepavykti nuskaityti, pakeiskite išvaizdos parametrus, kad jį būtų galima nuskaityti visuose įrenginiuose</string>\n    <string name=\"not_scannable\">Nenuskaitoma</string>\n    <string name=\"launcher_mode_sub\">Įrankiai atrodys kaip pradinio ekrano programų paleidimo priemonė, kad būtų kompaktiškesni</string>\n    <string name=\"launcher_mode\">Paleidimo režimas</string>\n    <string name=\"flood_fill_sub\">Užpildo sritį pasirinktu teptuku ir stiliumi</string>\n    <string name=\"flood_fill\">Potvynių užpildymas</string>\n    <string name=\"spray\">Purkšti</string>\n    <string name=\"spray_sub\">Piešia graffito stiliaus kelią</string>\n    <string name=\"square_particles\">Kvadratinės dalelės</string>\n    <string name=\"square_particles_sub\">Purškimo dalelės bus kvadrato formos, o ne apskritimų</string>\n    <string name=\"palette_tools\">Paletės įrankiai</string>\n    <string name=\"palette_tools_sub\">Sukurkite pagrindinę / medžiagą savo paletę iš vaizdo arba importuokite / eksportuokite į skirtingus paletės formatus</string>\n    <string name=\"edit_palette\">Redaguoti paletę</string>\n    <string name=\"edit_palette_sub\">Eksportuoti / importuoti paletę įvairiais formatais</string>\n    <string name=\"color_name\">Spalvos pavadinimas</string>\n    <string name=\"palette_name\">Paletės pavadinimas</string>\n    <string name=\"palette_format\">Paletės formatas</string>\n    <string name=\"export_palette_sub\">Eksportuokite sugeneruotą paletę į skirtingus formatus</string>\n    <string name=\"add_color_palette_sub\">Prideda naują spalvą į dabartinę paletę</string>\n    <string name=\"palette_name_not_supported\">%1$s formatas nepalaiko paletės pavadinimo</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Dėl „Play“ parduotuvės politikos šios funkcijos negalima įtraukti į dabartinę versiją. Norėdami pasiekti šią funkciją, atsisiųskite ImageToolbox iš alternatyvaus šaltinio. Galimas versijas „GitHub“ rasite toliau.</string>\n    <string name=\"open_github_page\">Atidarykite „Github“ puslapį</string>\n    <string name=\"overwrite_files_sub_short\">Originalus failas bus pakeistas nauju, o ne išsaugoti pasirinktame aplanke</string>\n    <string name=\"hidden_watermark_text_detected\">Aptiktas paslėptas vandens ženklo tekstas</string>\n    <string name=\"hidden_watermark_image_detected\">Aptiktas paslėptas vandens ženklo vaizdas</string>\n    <string name=\"this_image_was_hidden\">Šis vaizdas buvo paslėptas</string>\n    <string name=\"generative_inpaint\">Generatyvus tapymas</string>\n    <string name=\"generative_inpaint_sub\">Leidžia pašalinti objektus vaizde naudojant AI modelį, nepasikliaujant OpenCV. Norėdami naudotis šia funkcija, programa atsisiųs reikiamą modelį (~200 MB) iš GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Leidžia pašalinti objektus vaizde naudojant AI modelį, nepasikliaujant OpenCV. Tai gali būti ilgai trunkanti operacija</string>\n    <string name=\"error_level_analysis\">Klaidos lygio analizė</string>\n    <string name=\"luminance_gradient\">Šviesumo gradientas</string>\n    <string name=\"average_distance\">Vidutinis atstumas</string>\n    <string name=\"copy_move_detection\">Kopijuoti judėjimo aptikimą</string>\n    <string name=\"retain\">Išlaikyti</string>\n    <string name=\"coefficent\">Koeficientas</string>\n    <string name=\"clipboard_data_is_too_large\">Iškarpinės duomenys per dideli</string>\n    <string name=\"data_is_too_large_to_copy\">Duomenys per dideli, kad juos būtų galima kopijuoti</string>\n    <string name=\"simple_weave_pixelization\">Paprastas pynimo pikseliavimas</string>\n    <string name=\"staggered_pixelization\">Laipsniškas pikseliavimas</string>\n    <string name=\"cross_pixelization\">Kryžminis pikselis</string>\n    <string name=\"micro_macro_pixelization\">Mikro makro pikseliavimas</string>\n    <string name=\"orbital_pixelization\">Orbitos pikseliavimas</string>\n    <string name=\"vortex_pixelization\">Sūkurio pikseliavimas</string>\n    <string name=\"pulse_grid_pixelization\">Impulsinio tinklelio pikseliavimas</string>\n    <string name=\"nucleus_pixelization\">Branduolio pikseliavimas</string>\n    <string name=\"radial_weave_pixelization\">Radialinio pynimo pikseliavimas</string>\n    <string name=\"cannot_open_uri\">Negalima atidaryti uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Sniego režimas</string>\n    <string name=\"enabled\">Įjungta</string>\n    <string name=\"border_frame\">Kraštinis rėmelis</string>\n    <string name=\"glitch_variant\">Glitch variantas</string>\n    <string name=\"channel_shift\">Kanalo poslinkis</string>\n    <string name=\"max_offset\">Maksimalus poslinkis</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blokuoti Glitch</string>\n    <string name=\"block_size\">Bloko dydis</string>\n    <string name=\"crt_curvature\">CRT kreivumas</string>\n    <string name=\"curvature\">Kreivumas</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pikselių tirpimas</string>\n    <string name=\"max_drop\">Maksimalus lašas</string>\n    <string name=\"ai_tools\">AI įrankiai</string>\n    <string name=\"ai_tools_sub\">Įvairūs įrankiai vaizdams apdoroti naudojant AI modelius, pvz., artefaktų pašalinimą arba triukšmo mažinimą</string>\n    <string name=\"model_anime_undeint\">Suspaudimas, dantytos linijos</string>\n    <string name=\"model_broadcast\">Animaciniai filmai, transliacijų suspaudimas</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Bendras suspaudimas, bendras triukšmas</string>\n    <string name=\"model_wb_denoise\">Bespalvis animacinis triukšmas</string>\n    <string name=\"model_span_anime_pretrain\">Greitas, bendras suspaudimas, bendras triukšmas, animacija/komiksai/anime</string>\n    <string name=\"model_book_scan\">Knygų skenavimas</string>\n    <string name=\"model_overexposure\">Ekspozicijos korekcija</string>\n    <string name=\"model_fbcnn_color_fp16\">Geriausias bendras suspaudimas, spalvoti vaizdai</string>\n    <string name=\"model_fbcnn_gray_fp16\">Geriausiai tinka bendram suspaudimui, pilkos spalvos atvaizdams</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Bendras suspaudimas, pilkos spalvos vaizdai, stipresni</string>\n    <string name=\"model_scunet_color_gan_fp16\">Bendras triukšmas, spalvoti vaizdai</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Bendras triukšmas, spalvoti vaizdai, geresnės detalės</string>\n    <string name=\"model_scunet_gray_15_fp16\">Bendras triukšmas, pilkos spalvos vaizdai</string>\n    <string name=\"model_scunet_gray_25_fp16\">Bendras triukšmas, pilkų atspalvių vaizdai, stipresni</string>\n    <string name=\"model_scunet_gray_50_fp16\">Bendras triukšmas, pilkos spalvos vaizdai, stipriausi</string>\n    <string name=\"model_jpeg_destroyer\">Bendras suspaudimas</string>\n    <string name=\"model_jaywreck\">Bendras suspaudimas</string>\n    <string name=\"model_h264\">Tekstūravimas, h264 suspaudimas</string>\n    <string name=\"model_vhs\">VHS suspaudimas</string>\n    <string name=\"model_cinepak\">Nestandartinis glaudinimas (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink suspaudimas, geriau geometrijoje</string>\n    <string name=\"model_debink_v5\">Bink suspaudimas, stipresnis</string>\n    <string name=\"model_debink_v6\">Bink suspaudimas, minkštas, išlaiko detales</string>\n    <string name=\"model_antialias\">Laiptų efekto pašalinimas, išlyginimas</string>\n    <string name=\"model_kdm_scans\">Nuskaityti meno kūriniai/piešiniai, švelnus suspaudimas, muare</string>\n    <string name=\"model_bandage\">Spalvų juostos</string>\n    <string name=\"model_halftone\">Lėtas, pašalinantis pustonius</string>\n    <string name=\"model_colorizer\">Bendras pilkos spalvos / juodos spalvos vaizdų spalvinimas, geresniems rezultatams naudokite DDColor</string>\n    <string name=\"model_deedge\">Kraštų pašalinimas</string>\n    <string name=\"model_desharpen\">Pašalina perdėtą galandimą</string>\n    <string name=\"model_dither\">Lėtas, niūrus</string>\n    <string name=\"model_gainres\">Anti-aliasing, bendrieji artefaktai, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 nuskaito apdorojimas</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Lengvas vaizdo pagerinimo modelis</string>\n    <string name=\"model_bcgone_detailed_v2\">Suspaudimo artefaktų pašalinimas</string>\n    <string name=\"model_bcgone_smooth\">Suspaudimo artefaktų pašalinimas</string>\n    <string name=\"model_bandage_smooth\">Tvarsčio pašalinimas su sklandžiais rezultatais</string>\n    <string name=\"model_bendel_halftone\">Pustonių raštų apdorojimas</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Dydžio rašto pašalinimas V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG artefaktų pašalinimas V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 tekstūros pagerinimas</string>\n    <string name=\"model_vhs_sharpen\">VHS ryškinimas ir tobulinimas</string>\n    <string name=\"merging\">Sujungimas</string>\n    <string name=\"chunk_size\">Dalies dydis</string>\n    <string name=\"overlap_size\">Persidengimo dydis</string>\n    <string name=\"note_chunk_info\">Didesni nei %1$s px vaizdai bus supjaustomi ir apdorojami gabalais, juos perdengiant, kad nebūtų matomų siūlių.</string>\n    <string name=\"large_chunk_warning\">Dideli dydžiai gali sukelti nestabilumą naudojant žemos klasės įrenginius</string>\n    <string name=\"select_one_to_start\">Pasirinkite vieną, kad pradėtumėte</string>\n    <string name=\"delete_model_sub\">Ar norite ištrinti %1$s modelį? Turėsite jį atsisiųsti dar kartą</string>\n    <string name=\"confirm\">Patvirtinti</string>\n    <string name=\"models\">Modeliai</string>\n    <string name=\"downloaded_models\">Parsisiųsti modeliai</string>\n    <string name=\"available_models\">Galimi modeliai</string>\n    <string name=\"preparing\">Ruošiamasi</string>\n    <string name=\"active_model\">Aktyvus modelis</string>\n    <string name=\"failed_to_open_session\">Nepavyko atidaryti seanso</string>\n    <string name=\"only_onnx_models\">Galima importuoti tik .onnx/.ort modelius</string>\n    <string name=\"import_model\">Importo modelis</string>\n    <string name=\"import_model_sub\">Importuokite pasirinktinį onnx modelį tolesniam naudojimui, priimami tik onnx / ort modeliai, palaiko beveik visus esrgan tipo variantus</string>\n    <string name=\"imported_models\">Importuoti modeliai</string>\n    <string name=\"model_scunet_color_15_fp16\">Bendras triukšmas, spalvoti vaizdai</string>\n    <string name=\"model_scunet_color_25_fp16\">Bendras triukšmas, spalvoti vaizdai, stipresni</string>\n    <string name=\"model_scunet_color_50_fp16\">Bendras triukšmas, spalvoti vaizdai, stipriausi</string>\n    <string name=\"model_artifacts_dithering_alsa\">Sumažina artefaktus ir spalvų juostas, pagerina lygius gradientus ir lygias spalvų sritis.</string>\n    <string name=\"model_nmkd_brighten_redux\">Padidina vaizdo ryškumą ir kontrastą subalansuotais akcentais, išsaugant natūralias spalvas.</string>\n    <string name=\"model_nmkd_brighten\">Paryškina tamsius vaizdus, ​​išsaugant detales ir išvengiant per didelio eksponavimo.</string>\n    <string name=\"model_nmkd_detoon\">Pašalina pernelyg didelį spalvų atspalvį ir atkuria neutralesnį bei natūralesnį spalvų balansą.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Taiko Puasono pagrindu sukurtą triukšmo tonizavimą, pabrėžiant smulkių detalių ir tekstūrų išsaugojimą.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Taiko švelnų Puasono triukšmo atspalvį, kad vaizdo rezultatai būtų lygesni ir ne tokie agresyvūs.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Vienodas triukšmo atspalvis, skirtas detalių išsaugojimui ir vaizdo aiškumui.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Švelnus vienodas triukšmo tonizavimas subtiliai tekstūrai ir lygiai išvaizdai.</string>\n    <string name=\"model_repainter\">Taiso pažeistas ar nelygias vietas perdažydamas artefaktus ir pagerindamas vaizdo nuoseklumą.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Lengvas juostų pašalinimo modelis, kuris pašalina spalvų juostas su minimaliomis eksploatacinėmis sąnaudomis.</string>\n    <string name=\"model_jpeg_0_20\">Optimizuoja vaizdus su labai dideliu suspaudimo artefaktu (0–20 % kokybė), kad būtų geresnis aiškumas.</string>\n    <string name=\"model_jpeg_20_40\">Patobulina vaizdus su didelio suspaudimo artefaktais (20–40 % kokybė), atkuria detales ir sumažina triukšmą.</string>\n    <string name=\"model_jpeg_40_60\">Pagerina vaizdus su vidutiniu suspaudimu (40–60 % kokybė), subalansuojant ryškumą ir lygumą.</string>\n    <string name=\"model_jpeg_60_80\">Patobulina vaizdus su lengvu suspaudimu (60–80 % kokybė), kad paryškintų subtilias detales ir tekstūras.</string>\n    <string name=\"model_jpeg_80_100\">Šiek tiek pagerina beveik neprarandančius vaizdus (80–100 % kokybė), išsaugant natūralią išvaizdą ir detales.</string>\n    <string name=\"model_spongecolor_lite\">Paprastas ir greitas spalvinimas, animaciniai filmukai, ne idealu</string>\n    <string name=\"model_deblr\">Šiek tiek sumažina vaizdo susiliejimą, pagerina ryškumą, neįvedant artefaktų.</string>\n    <string name=\"processing_channel\">Ilgos operacijos</string>\n    <string name=\"processing_image\">Apdorojamas vaizdas</string>\n    <string name=\"processing\">Apdorojimas</string>\n    <string name=\"model_artifacts_jpg_0_20\">Pašalina sunkius JPEG glaudinimo artefaktus iš labai žemos kokybės vaizdų (0–20 %).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Sumažina stiprius JPEG artefaktus labai suspaustuose vaizduose (20–40 %).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Išvalo vidutinio sunkumo JPEG artefaktus, išsaugant vaizdo detales (40–60 %).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Patobulina šviesius JPEG artefaktus gana aukštos kokybės vaizduose (60–80 %).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Subtiliai sumažina smulkius JPEG artefaktus beveik neprarandant vaizdus (80–100 %).</string>\n    <string name=\"model_redetail_v2\">Paryškina smulkias detales ir tekstūras, pagerina suvokiamą ryškumą be sunkių artefaktų.</string>\n    <string name=\"processing_finished\">Apdorojimas baigtas</string>\n    <string name=\"processing_failed\">Apdoroti nepavyko</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Pagerina odos tekstūrą ir detales išlaikant natūralią išvaizdą, optimizuotą greitumui.</string>\n    <string name=\"model_sbdv_dejpeg\">Pašalina JPEG glaudinimo artefaktus ir atkuria suglaudintų nuotraukų vaizdo kokybę.</string>\n    <string name=\"model_iso_denoise_v1\">Sumažina ISO triukšmą nuotraukose, darytose prasto apšvietimo sąlygomis, išsaugodamas detales.</string>\n    <string name=\"model_dejumbo\">Pataiso per daug eksponuotus arba „jumbo“ paryškinimus ir atkuria geresnę tonų pusiausvyrą.</string>\n    <string name=\"model_ddcolor_tiny\">Lengvas ir greitas spalvinimo modelis, kuris pilkų tonų vaizdams suteikia natūralių spalvų.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Nuspalvinti</string>\n    <string name=\"type_artifacts\">Artefaktai</string>\n    <string name=\"type_enhance\">Padidinti</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Nuskaito</string>\n    <string name=\"type_upscale\">Prabangus</string>\n    <string name=\"model_realesrgan_x4v3\">X4 padidinimas bendriems vaizdams; mažas modelis, kuris naudoja mažiau GPU ir laiko, su nedideliu išblukimu ir triukšmu.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 padidinimo priemonė bendriems vaizdams, tekstūrų ir natūralių detalių išsaugojimui.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 padidinimo priemonė bendriems vaizdams su patobulintomis tekstūromis ir tikroviškais rezultatais.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 padidinimas, optimizuotas anime vaizdams; 6 RRDB blokai ryškesnėms linijoms ir detalėms.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 padidinimas su MSE praradimu, sukuria sklandesnius rezultatus ir sumažina bendrųjų vaizdų artefaktus.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimizuotas anime vaizdams; 4B32F variantas su ryškesnėmis detalėmis ir lygiomis linijomis.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 modelis bendriems vaizdams; pabrėžia ryškumą ir aiškumą.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; greitesnis ir mažesnis, išsaugo detales ir naudoja mažiau GPU atminties.</string>\n    <string name=\"model_rmbg_1_4\">Lengvas modelis greitam fono pašalinimui. Subalansuotas našumas ir tikslumas. Dirba su portretais, objektais ir scenomis. Rekomenduojama daugeliui naudojimo atvejų.</string>\n    <string name=\"type_removebg\">Pašalinti BG</string>\n    <string name=\"horizontal_border_thickness\">Horizontalios kraštinės storis</string>\n    <string name=\"vertical_border_thickness\">Vertikalios kraštinės storis</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"many\">%1$s spalvos</item>\n        <item quantity=\"one\">%1$s spalva</item>\n        <item quantity=\"few\">%1$s spalvos</item>\n        <item quantity=\"other\">%1$s spalvos</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Dabartinis modelis nepalaiko smulkinimo, vaizdas bus apdorojamas originaliais matmenimis, todėl gali sunaudoti daug atminties ir kilti problemų su žemos klasės įrenginiais</string>\n    <string name=\"chunking_disabled\">Dalijimas išjungtas, vaizdas bus apdorojamas originalių matmenų, todėl gali sunaudoti daug atminties ir gali kilti problemų su žemos klasės įrenginiais, bet gali duoti geresnių išvadų rezultatų</string>\n    <string name=\"chunking\">Susmulkinti</string>\n    <string name=\"model_u2net\">Didelio tikslumo vaizdo segmentavimo modelis, skirtas fono pašalinimui</string>\n    <string name=\"model_u2netp\">Lengva U2Net versija, skirta greičiau pašalinti foną naudojant mažiau atminties.</string>\n    <string name=\"model_ddcolor\">Visas DDColor modelis užtikrina aukštos kokybės bendrų vaizdų spalvinimą su minimaliais artefaktais. Geriausias pasirinkimas iš visų spalvinimo modelių.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Išmokyti ir privatūs meniniai duomenų rinkiniai; sukuria įvairius ir meniškus spalvinimo rezultatus su mažiau nerealių spalvų artefaktų.</string>\n    <string name=\"model_birefnet\">Lengvas BiRefNet modelis, pagrįstas Swin Transformer, kad būtų galima tiksliai pašalinti foną.</string>\n    <string name=\"model_inspyrenet\">Aukštos kokybės fono pašalinimas su aštriais kraštais ir puikiu detalių išsaugojimu, ypač sudėtinguose objektuose ir sudėtingame fone.</string>\n    <string name=\"model_isnet\">Fono pašalinimo modelis, gaminantis tikslias kaukes su lygiais kraštais, tinkamas bendriems objektams ir saikingam detalių išsaugojimui.</string>\n    <string name=\"model_already_downloaded\">Modelis jau atsisiųstas</string>\n    <string name=\"model_successfully_imported\">Modelis sėkmingai importuotas</string>\n    <string name=\"type\">Tipas</string>\n    <string name=\"keyword\">raktinis žodis</string>\n    <string name=\"very_fast\">Labai greitai</string>\n    <string name=\"normal\">Normalus</string>\n    <string name=\"slow\">Lėtas</string>\n    <string name=\"very_slow\">Labai lėtas</string>\n    <string name=\"compute_percents\">Apskaičiuokite procentus</string>\n    <string name=\"minimum_value_is\">Minimali vertė yra %1$s</string>\n    <string name=\"warp_sub\">Iškraipykite vaizdą piešdami pirštais</string>\n    <string name=\"warp\">Metmenys</string>\n    <string name=\"hardness\">Kietumas</string>\n    <string name=\"warp_mode\">Metimo režimas</string>\n    <string name=\"warp_mode_move\">Judėti</string>\n    <string name=\"warp_mode_grow\">Augti</string>\n    <string name=\"warp_mode_shrink\">Susitraukti</string>\n    <string name=\"warp_mode_swirl_cw\">Sūkurys CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Sūkurys CCW</string>\n    <string name=\"fade_strength\">Išblukimo stiprumas</string>\n    <string name=\"top_drop\">Viršutinis lašas</string>\n    <string name=\"bottom_drop\">Apatinis lašas</string>\n    <string name=\"start_drop\">Pradėti Drop</string>\n    <string name=\"end_drop\">Pabaigos kritimas</string>\n    <string name=\"downloading\">Atsisiunčiama</string>\n    <string name=\"smooth_shapes\">Lygios formos</string>\n    <string name=\"smooth_shapes_sub\">Naudokite superelipses, o ne standartinius suapvalintus stačiakampius, kad gautumėte lygesnes, natūralesnes formas</string>\n    <string name=\"shape_type\">Formos tipas</string>\n    <string name=\"cut\">Iškirpti</string>\n    <string name=\"rounded\">Suapvalinti</string>\n    <string name=\"smooth\">Sklandžiai</string>\n    <string name=\"cut_shapes_sub\">Aštrūs kraštai be apvalinimo</string>\n    <string name=\"rounded_shapes_sub\">Klasikiniai užapvalinti kampai</string>\n    <string name=\"shapes_type\">Formos tipas</string>\n    <string name=\"corners_size\">Kampų dydis</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elegantiški suapvalinti vartotojo sąsajos elementai</string>\n    <string name=\"filename_format\">Failo vardo formatas</string>\n    <string name=\"prefix_pattern_description\">Pasirinktinis tekstas, patalpintas pačioje failo pavadinimo pradžioje, puikiai tinka projektų pavadinimams, prekių ženklams ar asmeninėms žymoms.</string>\n    <string name=\"original_filename_pattern_description\">Naudoja originalų failo pavadinimą be plėtinio, padedantį išlaikyti šaltinio identifikavimo duomenis.</string>\n    <string name=\"width_pattern_description\">Vaizdo plotis pikseliais, naudingas stebint skiriamosios gebos pokyčius arba keičiant mastelio rezultatus.</string>\n    <string name=\"height_pattern_description\">Vaizdo aukštis pikseliais, naudinga dirbant su formato koeficientu arba eksportuojant.</string>\n    <string name=\"random_numbers_pattern_description\">Generuoja atsitiktinius skaitmenis, kad garantuotų unikalius failų pavadinimus; pridėkite daugiau skaitmenų, kad išvengtumėte dublikatų.</string>\n    <string name=\"sequence_number_pattern_description\">Automatiškai didėjantis paketinio eksporto skaitiklis, idealiai tinka išsaugant kelis vaizdus per vieną sesiją.</string>\n    <string name=\"preset_info_pattern_description\">Į failo pavadinimą įterpia pritaikytą išankstinio nustatymo pavadinimą, kad galėtumėte lengvai prisiminti, kaip buvo apdorotas vaizdas.</string>\n    <string name=\"scale_mode_pattern_description\">Rodomas vaizdo mastelio keitimo režimas, naudojamas apdorojimo metu, padedantis atskirti pakeisto dydžio, apkarpytus ar pritaikytus vaizdus.</string>\n    <string name=\"suffix_pattern_description\">Pasirinktinis tekstas, dedamas failo pavadinimo pabaigoje, naudingas kuriant versijas, pvz., _v2, _edited arba _final.</string>\n    <string name=\"extension_pattern_description\">Failo plėtinys (png, jpg, webp ir kt.), automatiškai atitinkantis tikrąjį išsaugotą formatą.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Pritaikoma laiko žyma, leidžianti nustatyti savo formatą pagal „Java“ specifikaciją, kad būtų galima tobulai rūšiuoti.</string>\n    <string name=\"fling_type\">Išmetimo tipas</string>\n    <string name=\"android_native\">„Android Native“.</string>\n    <string name=\"ios_style\">iOS stilius</string>\n    <string name=\"smooth_curve\">Lygi kreivė</string>\n    <string name=\"quick_stop\">Greitas sustojimas</string>\n    <string name=\"bouncy\">Bouncy</string>\n    <string name=\"floaty\">Plūduriuojantis</string>\n    <string name=\"snappy\">Šmaikštus</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">Prisitaikantis</string>\n    <string name=\"accessibility_aware\">Prieinamumas Aware</string>\n    <string name=\"reduced_motion\">Sumažintas judesys</string>\n    <string name=\"android_native_sub\">„Android“ slinkties fizika, skirta pradiniam palyginimui</string>\n    <string name=\"smooth_sub\">Subalansuotas, sklandus slinkimas bendram naudojimui</string>\n    <string name=\"ios_style_sub\">Didesnė trintis, panaši į „iOS“ slinkimo elgsena</string>\n    <string name=\"smooth_curve_sub\">Unikali spline kreivė, leidžianti aiškiai slinkti</string>\n    <string name=\"quick_stop_sub\">Tikslus slinkimas su greitu stabdymu</string>\n    <string name=\"bouncy_sub\">Žaismingas, reaguojantis šokinėjantis slinktis</string>\n    <string name=\"floaty_sub\">Ilgi, slenkantys slinktys, skirti naršyti turinį</string>\n    <string name=\"snappy_sub\">Greitas, reaguojantis interaktyvių vartotojo sąsajų slinkimas</string>\n    <string name=\"ultra_smooth_sub\">Aukščiausios kokybės sklandus slinkimas su padidintu impulsu</string>\n    <string name=\"adaptive_sub\">Koreguoja fiziką pagal svaidymo greitį</string>\n    <string name=\"accessibility_aware_sub\">Gerbia sistemos prieinamumo nustatymus</string>\n    <string name=\"reduced_motion_sub\">Minimalus judėjimas pasiekiamumo poreikiams</string>\n    <string name=\"primary_lines\">Pirminės linijos</string>\n    <string name=\"primary_lines_sub\">Kas penktą eilutę prideda storesnė linija</string>\n    <string name=\"fill_color\">Užpildymo spalva</string>\n    <string name=\"hidden_tools\">Paslėpti įrankiai</string>\n    <string name=\"hidden_for_share\">Įrankiai, paslėpti bendrinimui</string>\n    <string name=\"color_library\">Spalvų biblioteka</string>\n    <string name=\"color_library_sub\">Naršykite didelę spalvų kolekciją</string>\n    <string name=\"model_fatality_deblur\">Paryškina ir pašalina vaizdų susiliejimą išlaikant natūralias detales, idealiai tinka taisyti nesufokusuotas nuotraukas.</string>\n    <string name=\"model_unresize_v3\">Protingai atkuria vaizdus, ​​kurių dydis anksčiau buvo pakeistas, atkuriant prarastas detales ir tekstūras.</string>\n    <string name=\"model_liveaction_v1_span\">Optimizuotas tiesioginio veiksmo turiniui, sumažina suspaudimo artefaktus ir pagerina smulkias detales filmų / TV laidų kadruose.</string>\n    <string name=\"model_vhs2hd_realplksr\">Konvertuoja VHS kokybės filmuotą medžiagą į HD, pašalina juostos triukšmą ir padidina skiriamąją gebą, išsaugant senovinį pojūtį.</string>\n    <string name=\"model_text2hd_v1\">Specializuotas vaizdams ir ekrano kopijoms, kuriuose yra daug teksto, paryškina simbolius ir pagerina skaitomumą.</string>\n    <string name=\"model_frankendata_pretrainer\">Išplėstinis padidinimas, parengtas naudojant įvairius duomenų rinkinius, puikiai tinka bendrosios paskirties nuotraukų patobulinimui.</string>\n    <string name=\"model_realwebphoto_v2\">Optimizuotas žiniatinklyje suspaustoms nuotraukoms, pašalina JPEG artefaktus ir atkuria natūralią išvaizdą.</string>\n    <string name=\"model_realwebphoto_v4\">Patobulinta žiniatinklio nuotraukų versija su geresniu tekstūros išsaugojimu ir artefaktų mažinimu.</string>\n    <string name=\"model_dat_2x\">2x padidinimas naudojant Dual Aggregation Transformer technologiją, išlaiko ryškumą ir natūralias detales.</string>\n    <string name=\"model_dat_3x\">3x padidinimas naudojant pažangią transformatoriaus architektūrą, idealiai tinka vidutinio dydžio padidinimo poreikiams.</string>\n    <string name=\"model_dat_4x\">4x aukštos kokybės padidinimas naudojant moderniausią transformatorių tinklą, išsaugo smulkias detales esant didesniam masteliui.</string>\n    <string name=\"model_nafnet_deblurring\">Pašalina nuotraukų susiliejimą/triukšmą ir drebėjimą. Bendra paskirtis, bet geriausia nuotraukose.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Atkuria žemos kokybės vaizdus naudojant Swin2SR transformatorių, optimizuotą BSRGAN degradacijai. Puikiai tinka tvirtinti stiprius suspaudimo artefaktus ir patobulinti detales 4 kartus.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x padidinimas naudojant SwinIR transformatorių, apmokytą BSRGAN degradacijai. Naudoja GAN, kad nuotraukose ir sudėtingose scenose būtų ryškesnės tekstūros ir natūralesnės detalės.</string>\n    <string name=\"path\">Kelias</string>\n    <string name=\"merge_pdf\">Sujungti PDF</string>\n    <string name=\"merge_pdf_sub\">Sujunkite kelis PDF failus į vieną dokumentą</string>\n    <string name=\"files_order\">Failų tvarka</string>\n    <string name=\"pages_short\">p.</string>\n    <string name=\"split_pdf\">Padalinti PDF</string>\n    <string name=\"split_pdf_sub\">Ištraukite konkrečius puslapius iš PDF dokumento</string>\n    <string name=\"rotate_pdf\">Pasukti PDF</string>\n    <string name=\"rotate_pdf_sub\">Pataisykite puslapio orientaciją visam laikui</string>\n    <string name=\"pages\">Puslapiai</string>\n    <string name=\"rearrange_pdf\">Pertvarkyti PDF</string>\n    <string name=\"rearrange_pdf_sub\">Nuvilkite puslapius, kad juos pakeistumėte</string>\n    <string name=\"hold_drag_drop\">Laikykite ir vilkite puslapius</string>\n    <string name=\"page_numbers\">Puslapių numeriai</string>\n    <string name=\"page_numbers_sub\">Automatiškai pridėkite numeraciją prie savo dokumentų</string>\n    <string name=\"label_format\">Etiketės formatas</string>\n    <string name=\"pdf_to_text\">PDF į tekstą (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Ištraukite paprastą tekstą iš savo PDF dokumentų</string>\n    <string name=\"watermark_pdf_sub\">Perdenkite tinkintą tekstą, skirtą prekės ženklui arba saugai</string>\n    <string name=\"signature\">Parašas</string>\n    <string name=\"signature_sub\">Pridėkite savo elektroninį parašą prie bet kurio dokumento</string>\n    <string name=\"will_be_for_signature\">Tai bus naudojama kaip parašas</string>\n    <string name=\"unlock_pdf\">Atrakinti PDF</string>\n    <string name=\"unlock_pdf_sub\">Pašalinkite slaptažodžius iš apsaugotų failų</string>\n    <string name=\"protect_pdf\">Apsaugoti PDF</string>\n    <string name=\"protect_pdf_sub\">Apsaugokite dokumentus naudodami tvirtą šifravimą</string>\n    <string name=\"success\">Sėkmės</string>\n    <string name=\"pdf_unlocked\">PDF atrakintas, galite jį išsaugoti arba bendrinti</string>\n    <string name=\"repair_pdf\">Pataisyti PDF</string>\n    <string name=\"repair_pdf_sub\">Bandykite taisyti sugadintus arba neįskaitomus dokumentus</string>\n    <string name=\"grayscale\">Pilkos spalvos</string>\n    <string name=\"grayscale_pdf_sub\">Konvertuoti visus dokumento įterptus vaizdus į pilkos spalvos tonus</string>\n    <string name=\"compress_pdf\">Suspausti PDF</string>\n    <string name=\"compress_pdf_sub\">Optimizuokite dokumento failo dydį, kad būtų lengviau bendrinti</string>\n    <string name=\"repair_info\">„ImageToolbox“ atkuria vidinę kryžminių nuorodų lentelę ir atkuria failo struktūrą nuo nulio. Tai gali atkurti prieigą prie daugelio failų, kurių \\\\\"negalima atidaryti\\\\\"</string>\n    <string name=\"grayscale_info\">Šis įrankis konvertuoja visus dokumentų vaizdus į pilkos spalvos tonus. Geriausiai tinka spausdinti ir sumažinti failo dydį</string>\n    <string name=\"metadata\">Metaduomenys</string>\n    <string name=\"metadata_pdf_sub\">Redaguokite dokumento ypatybes, kad užtikrintumėte didesnį privatumą</string>\n    <string name=\"tags\">Žymos</string>\n    <string name=\"producer\">Gamintojas</string>\n    <string name=\"author\">Autorius</string>\n    <string name=\"keywords\">Raktažodžiai</string>\n    <string name=\"creator\">Kūrėjas</string>\n    <string name=\"privacy_deep_clean\">Privatumas Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Išvalyti visus galimus šio dokumento metaduomenis</string>\n    <string name=\"page\">Puslapis</string>\n    <string name=\"deep_ocr\">Gilus OCR</string>\n    <string name=\"deep_ocr_sub\">Ištraukite tekstą iš dokumento ir išsaugokite jį viename tekstiniame faile naudodami Tesseract variklį</string>\n    <string name=\"cant_remove_all\">Negalima pašalinti visų puslapių</string>\n    <string name=\"remove_pages_pdf\">Pašalinti PDF puslapius</string>\n    <string name=\"remove_pages_pdf_sub\">Pašalinkite konkrečius puslapius iš PDF dokumento</string>\n    <string name=\"tap_to_remove\">Bakstelėkite Norėdami pašalinti</string>\n    <string name=\"manually\">Rankiniu būdu</string>\n    <string name=\"crop_pdf\">Apkarpyti PDF</string>\n    <string name=\"crop_pdf_sub\">Apkarpykite dokumento puslapius iki bet kokių ribų</string>\n    <string name=\"flatten_pdf\">Išlyginti PDF</string>\n    <string name=\"flatten_pdf_sub\">Padarykite PDF nekeičiamą rastruodami dokumento puslapius</string>\n    <string name=\"camera_failed_to_open\">Nepavyko paleisti fotoaparato. Patikrinkite leidimus ir įsitikinkite, kad jo nenaudoja kita programa.</string>\n    <string name=\"extract_images\">Ištraukite vaizdus</string>\n    <string name=\"extract_images_sub\">Ištraukite į PDF failus įterptus vaizdus pradine raiška</string>\n    <string name=\"pdf_no_embedded\">Šiame PDF faile nėra įterptų vaizdų</string>\n    <string name=\"extract_images_info\">Šis įrankis nuskaito kiekvieną puslapį ir atkuria visos kokybės šaltinio vaizdus – puikiai tinka išsaugoti originalus iš dokumentų</string>\n    <string name=\"draw_signature\">Piešti parašą</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">Naudokite savo parašą kaip vaizdą, kuris bus dedamas ant dokumentų</string>\n    <string name=\"zip_pdf\">ZIP PDF</string>\n    <string name=\"zip_pdf_sub\">Padalinkite dokumentą nurodytu intervalu ir supakuokite naujus dokumentus į ZIP archyvą</string>\n    <string name=\"interval\">Intervalas</string>\n    <string name=\"print_pdf\">Spausdinti PDF</string>\n    <string name=\"print_pdf_sub\">Paruoškite dokumentą spausdinti pagal pasirinktinį puslapio dydį</string>\n    <string name=\"pages_per_sheet\">Puslapiai lape</string>\n    <string name=\"orientation\">Orientacija</string>\n    <string name=\"page_size\">Puslapio dydis</string>\n    <string name=\"margin\">Marža</string>\n    <string name=\"bloom\">Bloom</string>\n    <string name=\"soft_knee\">Minkštas kelias</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimizuotas anime ir animaciniams filmams. Greitas mastelio padidinimas su patobulintomis natūraliomis spalvomis ir mažiau artefaktų</string>\n    <string name=\"one_ui_sub\">„Samsung One UI 7“ panašus stilius</string>\n    <string name=\"calculate_hint\">Norėdami apskaičiuoti norimą reikšmę, įveskite čia pagrindinius matematinius simbolius (pvz., (5+5)*10)</string>\n    <string name=\"math_expression\">Matematinė išraiška</string>\n    <string name=\"pick_up_to_n_collage_images\">Paimkite iki %1$s vaizdų</string>\n    <string name=\"keep_date_time\">Išsaugokite datos laiką</string>\n    <string name=\"keep_date_time_sub\">Visada išsaugokite exif žymas, susijusias su data ir laiku, veikia nepriklausomai nuo parinkties išlaikyti exif</string>\n    <string name=\"background_color_for_alpha_formats\">Fono spalva Alfa formatams</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Pridedama galimybė nustatyti fono spalvą kiekvienam vaizdo formatui su alfa palaikymu, kai išjungta, tai galima tik ne alfa formatams</string>\n    <string name=\"open_markup_project\">Atviras projektas</string>\n    <string name=\"open_markup_project_sub\">Tęskite anksčiau išsaugoto vaizdo įrankių dėžės projekto redagavimą</string>\n    <string name=\"markup_project_open_failed\">Nepavyko atidaryti „Image Toolbox“ projekto</string>\n    <string name=\"markup_project_missing_data\">Vaizdo įrankių dėžutės projekte trūksta projekto duomenų</string>\n    <string name=\"markup_project_corrupted\">Vaizdo įrankių dėžutės projektas sugadintas</string>\n    <string name=\"unsupported_markup_project_version\">Nepalaikoma „Image Toolbox“ projekto versija: %1$d</string>\n    <string name=\"save_markup_project\">Išsaugoti projektą</string>\n    <string name=\"save_markup_project_sub\">Saugokite sluoksnius, foną ir redaguokite istoriją redaguojamame projekto faile</string>\n    <string name=\"failed_to_open\">Nepavyko atidaryti</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Rašyti į ieškomą PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Atpažinkite tekstą iš vaizdų paketo ir išsaugokite ieškomą PDF su vaizdu ir pasirenkamu teksto sluoksniu</string>\n    <string name=\"layer_alpha\">Alfa sluoksnis</string>\n    <string name=\"horizontal_flip\">Horizontalus apvertimas</string>\n    <string name=\"vertical_flip\">Vertikalus apvertimas</string>\n    <string name=\"lock\">Užraktas</string>\n    <string name=\"add_shadow\">Pridėti šešėlį</string>\n    <string name=\"shadow_color\">Šešėlių spalva</string>\n    <string name=\"text_geometry\">Teksto geometrija</string>\n    <string name=\"text_geometry_sub\">Ištempkite arba pasukite tekstą, kad stilizacija būtų ryškesnė</string>\n    <string name=\"scale_x\">X skalė</string>\n    <string name=\"skew_x\">Iškreiptas X</string>\n    <string name=\"remove_annotations\">Pašalinti komentarus</string>\n    <string name=\"remove_annotations_sub\">Pašalinkite pasirinktus komentarų tipus, pvz., nuorodas, komentarus, paryškinimus, figūras ar formos laukus iš PDF puslapių</string>\n    <string name=\"annotation_link\">Hipersaitai</string>\n    <string name=\"annotation_file_attachment\">Failų priedai</string>\n    <string name=\"annotation_line\">Linijos</string>\n    <string name=\"annotation_popup\">Iššokantys langai</string>\n    <string name=\"annotation_stamp\">Antspaudai</string>\n    <string name=\"annotation_shapes\">Formos</string>\n    <string name=\"annotation_text\">Teksto pastabos</string>\n    <string name=\"annotation_text_markup\">Teksto žymėjimas</string>\n    <string name=\"annotation_widget\">Formos laukai</string>\n    <string name=\"annotation_markup\">Žymėjimas</string>\n    <string name=\"annotation_unknown\">Nežinoma</string>\n    <string name=\"annotations\">Anotacijos</string>\n    <string name=\"ungroup\">Išgrupuoti</string>\n    <string name=\"add_shadow_sub\">Už sluoksnio pridėkite neryškų šešėlį su konfigūruojama spalva ir poslinkiais</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-mr/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"smth_went_wrong\">काहीतरी चूक झाली: %1$s</string>\n    <string name=\"size\">आकार %1$s</string>\n    <string name=\"loading\">लोड होत आहे…</string>\n    <string name=\"image_too_large_preview\">प्रतिदर्शनासाठी प्रतिमा खूप मोठी आहे, परंतु तरीही ती सेव्ह करण्याचा प्रयत्न केला जाईल.</string>\n    <string name=\"pick_image\">सुरू करण्यासाठी प्रतिमा निवडा</string>\n    <string name=\"width\">रुंदी %1$s</string>\n    <string name=\"height\">उंची %1$s</string>\n    <string name=\"quality\">गुणवत्ता</string>\n    <string name=\"extension\">विस्तार</string>\n    <string name=\"resize_type\">आकाराचा प्रकार बदला</string>\n    <string name=\"explicit\">स्पष्ट</string>\n    <string name=\"flexible\">लवचिक</string>\n    <string name=\"pick_image_alt\">प्रतिमा निवडा</string>\n    <string name=\"app_closing_sub\">तुम्हाला खात्री आहे की तुम्हाला ॲप बंद करायचे आहे?</string>\n    <string name=\"app_closing\">ॲप बंद होत आहे</string>\n    <string name=\"stay\">थांबा</string>\n    <string name=\"close\">बंद करा</string>\n    <string name=\"reset_image\">प्रतिमा रीसेट करा</string>\n    <string name=\"reset_image_sub\">प्रतिमांमध्ये केलेले बदल त्यांच्या सुरुवातीच्या मूल्यांवर परत येतील.</string>\n    <string name=\"values_reset\">मूल्ये योग्यरित्या रीसेट केली गेली.</string>\n    <string name=\"reset\">रीसेट करा</string>\n    <string name=\"something_went_wrong\">काहीतरी चूक झाली.</string>\n    <string name=\"restart_app\">ॲप रीस्टार्ट करा</string>\n    <string name=\"copied\">क्लिपबोर्डवर कॉपी केले</string>\n    <string name=\"exception\">अपवाद</string>\n    <string name=\"edit_exif\">EXIF संपादित करा</string>\n    <string name=\"ok\">ठीक आहे</string>\n    <string name=\"nearest\">सर्वात जवळचे</string>\n    <string name=\"sort_by_size\">आकार</string>\n    <string name=\"something_went_wrong_emphasis\">अरेरे… काहीतरी चूक झाली आहे. तुम्ही खाली दिलेल्या पर्यायांचा वापर करून मला लिहू शकता आणि मी त्यावर उपाय शोधण्याचा प्रयत्न करेन.</string>\n    <string name=\"repeat_watermark_sub\">दिलेल्या ठिकाणी एकदाच वॉटरमार्क लावण्याऐवजी, तो प्रतिमेवर पुन्हा लावतो.</string>\n    <string name=\"offset_x\">ऑफसेट एक्स</string>\n    <string name=\"not_scannable\">स्कॅन करण्यायोग्य नाही</string>\n    <string name=\"lanczos_6_jinc\">लॅन्झोस ६ जिंक</string>\n    <string name=\"lanczos\">लॅन्झोस</string>\n    <string name=\"max_bytes\">कमाल आकार केबी मध्ये</string>\n    <string name=\"by_bytes_resize_sub\">दिलेल्या केबी (KB) आकारानुसार प्रतिमेचा आकार बदला.</string>\n    <string name=\"compare\">तुलना करा</string>\n    <string name=\"compare_sub\">दिलेल्या दोन प्रतिमांची तुलना करा.</string>\n    <string name=\"pick_two_images\">सुरुवात करण्यासाठी दोन प्रतिमा निवडा.</string>\n    <string name=\"pick_images\">प्रतिमा निवडा</string>\n    <string name=\"settings\">सेटिंग्ज</string>\n    <string name=\"night_mode\">रात्री मोड</string>\n    <string name=\"dark\">गडद</string>\n    <string name=\"light\">प्रकाश</string>\n    <string name=\"def\">डीफॉल्ट</string>\n    <string name=\"custom\">सानुकूल</string>\n    <string name=\"unspecified\">अनिर्दिष्ट</string>\n    <string name=\"device_storage\">डिव्हाइस स्टोरेज</string>\n    <string name=\"remove\">काढा</string>\n    <string name=\"palette_sub\">दिलेल्या प्रतिमेवरून कलर पॅलेट स्वॉच तयार करा</string>\n    <string name=\"generate_palette\">पॅलेट तयार करा</string>\n    <string name=\"palette\">पॅलेट</string>\n    <string name=\"update\">अद्यतन</string>\n    <string name=\"new_version\">नवीन आवृत्ती %1$s</string>\n    <string name=\"unsupported_type\">असमर्थित प्रकार: %1$s</string>\n    <string name=\"no_palette\">दिलेल्या प्रतिमेसाठी पॅलेट तयार करता येत नाही.</string>\n    <string name=\"original\">मूळ</string>\n    <string name=\"folder\">आउटपुट फोल्डर</string>\n    <string name=\"by_bytes_resize\">वजनानुसार आकार बदला</string>\n    <string name=\"system\">प्रणाली</string>\n    <string name=\"dynamic_colors\">गतिशील रंग</string>\n    <string name=\"customization\">सानुकूलन</string>\n    <string name=\"allow_image_monet\">प्रतिमा कमाईला परवानगी द्या</string>\n    <string name=\"allow_image_monet_sub\">जर हे वैशिष्ट्य सक्षम केले असेल, तर जेव्हा तुम्ही संपादनासाठी एखादी प्रतिमा निवडाल, तेव्हा ॲपचे रंग त्या प्रतिमेनुसार बदलले जातील.</string>\n    <string name=\"language\">भाषा</string>\n    <string name=\"amoled_mode\">अमोलेड मोड</string>\n    <string name=\"amoled_mode_sub\">सक्षम केल्यास, नाईट मोडमध्ये पृष्ठभागांचा रंग पूर्णपणे गडद होईल.</string>\n    <string name=\"color_scheme\">रंगसंगती</string>\n    <string name=\"color_red\">लाल</string>\n    <string name=\"color_green\">हिरवा</string>\n    <string name=\"color_blue\">निळा</string>\n    <string name=\"clipboard_paste_invalid_color_code\">एक वैध aRGB कलर कोड पेस्ट करा.</string>\n    <string name=\"clipboard_paste_invalid_empty\">पेस्ट करण्यासाठी काहीही नाही</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">डायनॅमिक रंग चालू असताना ॲपची रंगसंगती बदलता येत नाही.</string>\n    <string name=\"pick_accent_color\">ॲपची थीम निवडलेल्या रंगावर आधारित असेल.</string>\n    <string name=\"about_app\">अ‍ॅपबद्दल</string>\n    <string name=\"no_updates\">कोणतेही अपडेट्स आढळले नाहीत.</string>\n    <string name=\"issue_tracker\">समस्या ट्रॅकर</string>\n    <string name=\"issue_tracker_sub\">बग रिपोर्ट आणि वैशिष्ट्यांच्या विनंत्या येथे पाठवा.</string>\n    <string name=\"help_translate\">भाषांतर करण्यास मदत करा</string>\n    <string name=\"help_translate_sub\">भाषांतरातील चुका दुरुस्त करा किंवा प्रकल्प इतर भाषांमध्ये स्थानिकृत करा.</string>\n    <string name=\"nothing_found_by_search\">तुमच्या शोधानुसार काहीही सापडले नाही.</string>\n    <string name=\"search_here\">येथे शोधा</string>\n    <string name=\"dynamic_colors_sub\">जर हे सक्षम केले असेल, तर ॲपचे रंग वॉलपेपरच्या रंगांनुसार बदलतील.</string>\n    <string name=\"failed_to_save\">%d प्रतिमा जतन करण्यात अयशस्वी.</string>\n    <string name=\"email\">ईमेल</string>\n    <string name=\"primary\">प्राथमिक</string>\n    <string name=\"secondary\">माध्यमिक</string>\n    <string name=\"tertiary\">तृतीयक</string>\n    <string name=\"border_thickness\">बॉर्डरची जाडी</string>\n    <string name=\"surface\">पृष्ठभाग</string>\n    <string name=\"values\">मुल्ये</string>\n    <string name=\"add\">जोडा</string>\n    <string name=\"permission\">परवानगी</string>\n    <string name=\"grant\">अनुदान</string>\n    <string name=\"permission_sub\">ॲपला काम करण्यासाठी आणि प्रतिमा सेव्ह करण्यासाठी तुमच्या स्टोरेजमध्ये प्रवेशाची आवश्यकता आहे, हे आवश्यक आहे. कृपया पुढील संवाद बॉक्समध्ये परवानगी द्या.</string>\n    <string name=\"grant_permission_manual\">ॲपला काम करण्यासाठी या परवानगीची आवश्यकता आहे, कृपया ती स्वतःहून मंजूर करा.</string>\n    <string name=\"external_storage\">बाह्य संचयन</string>\n    <string name=\"monet_colors\">मोनेट रंग</string>\n    <string name=\"donation_sub\">हा ॲप्लिकेशन पूर्णपणे विनामूल्य आहे, परंतु जर तुम्हाला प्रकल्पाच्या विकासाला पाठिंबा द्यायचा असेल, तर तुम्ही येथे क्लिक करू शकता.</string>\n    <string name=\"fab_alignment\">एफएबी संरेखन</string>\n    <string name=\"check_updates\">अपडेट्स तपासा</string>\n    <string name=\"check_updates_sub\">सक्षम केल्यास, ॲप सुरू झाल्यावर तुम्हाला अपडेटचा संवाद दिसेल.</string>\n    <string name=\"zoom\">प्रतिमा झूम</string>\n    <string name=\"share\">सामायिक करा</string>\n    <string name=\"prefix\">उपसर्ग</string>\n    <string name=\"filename\">फाइलचे नाव</string>\n    <string name=\"emoji\">इमोजी</string>\n    <string name=\"emoji_sub\">मुख्य स्क्रीनवर कोणता इमोजी प्रदर्शित करायचा ते निवडा.</string>\n    <string name=\"add_file_size\">फाइलचा आकार जोडा</string>\n    <string name=\"add_file_size_sub\">सक्षम केल्यास, सेव्ह केलेल्या प्रतिमेची रुंदी आणि उंची आउटपुट फाइलच्या नावात जोडली जाते.</string>\n    <string name=\"delete_exif\">EXIF हटवा</string>\n    <string name=\"delete_exif_sub\">कोणत्याही प्रतिमांच्या संचातून EXIF मेटाडेटा हटवा.</string>\n    <string name=\"image_preview\">प्रतिमा पूर्वावलोकन</string>\n    <string name=\"image_preview_sub\">कोणत्याही प्रकारच्या प्रतिमांचे पूर्वावलोकन करा: GIF, SVG, आणि इतर.</string>\n    <string name=\"image_source\">प्रतिमा स्रोत</string>\n    <string name=\"photo_picker\">फोटो निवडक</string>\n    <string name=\"gallery_picker\">गॅलरी</string>\n    <string name=\"file_explorer_picker\">फाइल एक्सप्लोरर</string>\n    <string name=\"photo_picker_sub\">स्क्रीनच्या तळाशी दिसणारा अँड्रॉइडचा आधुनिक फोटो पिकर, कदाचित फक्त अँड्रॉइड १२+ वरच काम करेल. त्याला EXIF मेटाडेटा मिळवण्यात समस्या येतात.</string>\n    <string name=\"gallery_picker_sub\">एक साधे गॅलरी इमेज पिकर. हे फक्त तेव्हाच काम करेल जेव्हा तुमच्याकडे मीडिया निवडण्याची सुविधा देणारे ॲप असेल.</string>\n    <string name=\"file_explorer_picker_sub\">प्रतिमा निवडण्यासाठी GetContent इंटेंट वापरा. हे सर्वत्र काम करते, परंतु काही उपकरणांवर निवडलेल्या प्रतिमा प्राप्त करताना समस्या येत असल्याचे दिसून आले आहे. यात माझा दोष नाही.</string>\n    <string name=\"options_arrangement\">पर्यायांची मांडणी</string>\n    <string name=\"edit\">संपादित करा</string>\n    <string name=\"order\">ऑर्डर</string>\n    <string name=\"order_sub\">मुख्य स्क्रीनवरील साधनांचा क्रम निश्चित करतो.</string>\n    <string name=\"emojis_count\">इमोजींची संख्या</string>\n    <string name=\"sequence_num\">अनुक्रम क्रमांक</string>\n    <string name=\"original_filename\">मूळ फाइलनाव</string>\n    <string name=\"add_original_filename\">मूळ फाइलचे नाव जोडा</string>\n    <string name=\"add_original_filename_sub\">सक्षम केल्यास, आउटपुट प्रतिमेच्या नावात मूळ फाइलचे नाव जोडले जाते.</string>\n    <string name=\"replace_sequence_number\">अनुक्रमांक बदला</string>\n    <string name=\"replace_sequence_number_sub\">सक्षम केल्यास, बॅच प्रोसेसिंग वापरताना, हे स्टँडर्ड टाइमस्टॅम्पऐवजी इमेजचा अनुक्रमांक वापरेल.</string>\n    <string name=\"filename_not_work_with_photopicker\">फोटो पिकर इमेज स्रोत निवडल्यास मूळ फाइलचे नाव जोडणे काम करत नाही.</string>\n    <string name=\"load_image_from_net\">वेब प्रतिमा लोडिंग</string>\n    <string name=\"load_image_from_net_sub\">पूर्वावलोकन करण्यासाठी, झूम करण्यासाठी, संपादित करण्यासाठी आणि इच्छित असल्यास सेव्ह करण्यासाठी इंटरनेटवरून कोणतीही प्रतिमा लोड करा.</string>\n    <string name=\"no_image\">कोणतीही प्रतिमा नाही</string>\n    <string name=\"image_link\">प्रतिमा दुवा</string>\n    <string name=\"fill\">भरा</string>\n    <string name=\"fit\">फिट</string>\n    <string name=\"content_scale\">सामग्री प्रमाण</string>\n    <string name=\"explicit_description\">प्रतिमेचा आकार दिलेल्या उंची आणि रुंदीनुसार बदला. प्रतिमांचे गुणोत्तर बदलू शकते.</string>\n    <string name=\"flexible_description\">प्रतिमेच्या सर्वात लांब बाजूला दिलेल्या उंची किंवा रुंदीनुसार आकार बदला. सर्व आकारांची गणना सेव्ह केल्यानंतर केली जाईल. प्रतिमांचे गुणोत्तर प्रमाण कायम राखले जाईल.</string>\n    <string name=\"brightness\">चमक</string>\n    <string name=\"contrast\">फरक</string>\n    <string name=\"hue\">रंगछटा</string>\n    <string name=\"saturation\">संतृप्ति</string>\n    <string name=\"add_filter\">फिल्टर जोडा</string>\n    <string name=\"filter\">फिल्टर</string>\n    <string name=\"filter_sub\">प्रतिमांवर फिल्टर चेन लागू करा</string>\n    <string name=\"filters\">फिल्टर</string>\n    <string name=\"light_aka_illumination\">प्रकाश</string>\n    <string name=\"color_filter\">रंग फिल्टर</string>\n    <string name=\"alpha\">अल्फा</string>\n    <string name=\"exposure\">उद्भासन</string>\n    <string name=\"white_balance\">पांढरा शिल्लक</string>\n    <string name=\"temperature\">तापमान</string>\n    <string name=\"tint\">रंगछटा</string>\n    <string name=\"monochrome\">मोनोक्रोम</string>\n    <string name=\"gamma\">गामा</string>\n    <string name=\"highlights_shadows\">हायलाइट्स आणि सावल्या</string>\n    <string name=\"highlights\">ठळक मुद्दे</string>\n    <string name=\"shadows\">सावल्या</string>\n    <string name=\"haze\">धुके</string>\n    <string name=\"effect\">परिणाम</string>\n    <string name=\"distance\">अंतर</string>\n    <string name=\"slope\">उतार</string>\n    <string name=\"sharpen\">धार लावा</string>\n    <string name=\"sepia\">सेपिया</string>\n    <string name=\"negative\">नकारात्मक</string>\n    <string name=\"solarize\">सोलराइझ करा</string>\n    <string name=\"vibrance\">कंपन</string>\n    <string name=\"black_and_white\">काळा आणि पांढरा</string>\n    <string name=\"no_exif\">कोणताही EXIF ​​डेटा आढळला नाही</string>\n    <string name=\"add_tag\">टॅग जोडा</string>\n    <string name=\"save\">जतन करा</string>\n    <string name=\"clear\">साफ</string>\n    <string name=\"clear_exif\">EXIF साफ करा</string>\n    <string name=\"cancel\">रद्द करा</string>\n    <string name=\"clear_exif_sub\">सर्व प्रतिमा EXIF ​​डेटा मिटविला जाईल. ही क्रिया पूर्ववत केली जाऊ शकत नाही!</string>\n    <string name=\"presets\">प्रीसेट</string>\n    <string name=\"crop\">पीक</string>\n    <string name=\"image_not_saved\">बचत करत आहे</string>\n    <string name=\"image_not_saved_sub\">तुम्ही आता बाहेर पडल्यास सर्व जतन न केलेले बदल गमावले जातील</string>\n    <string name=\"check_source_code\">स्त्रोत कोड</string>\n    <string name=\"check_source_code_sub\">नवीनतम अद्यतने मिळवा, समस्यांवर चर्चा करा आणि बरेच काही</string>\n    <string name=\"single_edit\">एकल संपादन</string>\n    <string name=\"single_edit_sub\">एक प्रतिमा सुधारा, आकार बदला आणि संपादित करा</string>\n    <string name=\"pick_color\">रंग निवडक</string>\n    <string name=\"pick_color_sub\">प्रतिमेतून रंग निवडा, कॉपी करा किंवा शेअर करा</string>\n    <string name=\"image\">प्रतिमा</string>\n    <string name=\"color\">रंग</string>\n    <string name=\"color_copied\">रंग कॉपी केला</string>\n    <string name=\"crop_sub\">प्रतिमा कोणत्याही मर्यादेपर्यंत क्रॉप करा</string>\n    <string name=\"version\">आवृत्ती</string>\n    <string name=\"keep_exif\">EXIF ठेवा</string>\n    <string name=\"images\">प्रतिमा: %d</string>\n    <string name=\"change_preview\">पूर्वावलोकन बदला</string>\n    <string name=\"crosshatch\">क्रॉसशॅच</string>\n    <string name=\"spacing\">अंतर</string>\n    <string name=\"line_width\">ओळीची रुंदी</string>\n    <string name=\"sobel_edge\">सोबेल काठ</string>\n    <string name=\"blur\">अस्पष्ट</string>\n    <string name=\"halftone\">हाफटोन</string>\n    <string name=\"cga_colorspace\">CGA कलरस्पेस</string>\n    <string name=\"gaussian_blur\">गॉसियन अस्पष्टता</string>\n    <string name=\"box_blur\">बॉक्स ब्लर</string>\n    <string name=\"bilaterial_blur\">द्विपक्षीय अस्पष्टता</string>\n    <string name=\"emboss\">एम्बॉस</string>\n    <string name=\"laplacian\">लॅपलाशियन</string>\n    <string name=\"vignette\">विग्नेट</string>\n    <string name=\"start\">सुरू करा</string>\n    <string name=\"end\">शेवट</string>\n    <string name=\"kuwahara\">कुवाहरा गुळगुळीत</string>\n    <string name=\"stack_blur\">स्टॅक ब्लर</string>\n    <string name=\"radius\">त्रिज्या</string>\n    <string name=\"scale\">स्केल</string>\n    <string name=\"distortion\">विकृती</string>\n    <string name=\"angle\">कोन</string>\n    <string name=\"swirl\">फिरणे</string>\n    <string name=\"bulge\">फुगवटा</string>\n    <string name=\"dilation\">फैलाव</string>\n    <string name=\"sphere_refraction\">गोलाकार अपवर्तन</string>\n    <string name=\"refractive_index\">अपवर्तक निर्देशांक</string>\n    <string name=\"glass_sphere_refraction\">काचेच्या गोलाचे अपवर्तन</string>\n    <string name=\"color_matrix\">रंग मॅट्रिक्स</string>\n    <string name=\"opacity\">अपारदर्शकता</string>\n    <string name=\"limits_resize\">मर्यादेनुसार आकार बदला</string>\n    <string name=\"limits_resize_sub\">आस्पेक्ट रेशो ठेवताना दिलेल्या उंची आणि रुंदीनुसार प्रतिमांचा आकार बदला</string>\n    <string name=\"sketch\">स्केच</string>\n    <string name=\"threshold\">उंबरठा</string>\n    <string name=\"quantizationLevels\">परिमाणीकरण पातळी</string>\n    <string name=\"smooth_toon\">गुळगुळीत टून</string>\n    <string name=\"toon\">टून</string>\n    <string name=\"posterize\">पोस्टराइझ करा</string>\n    <string name=\"non_maximum_suppression\">कमाल दडपशाही नाही</string>\n    <string name=\"weak_pixel_inclusion\">कमकुवत पिक्सेल समावेश</string>\n    <string name=\"lookup\">पहा</string>\n    <string name=\"convolution3x3\">कंव्होल्युशन 3x3</string>\n    <string name=\"rgb_filter\">आरजीबी फिल्टर</string>\n    <string name=\"false_color\">खोटा रंग</string>\n    <string name=\"first_color\">पहिला रंग</string>\n    <string name=\"second_color\">दुसरा रंग</string>\n    <string name=\"reorder\">पुनर्क्रमित करा</string>\n    <string name=\"fast_blur\">जलद अस्पष्टता</string>\n    <string name=\"blur_size\">अस्पष्ट आकार</string>\n    <string name=\"blur_center_x\">अस्पष्ट केंद्र x</string>\n    <string name=\"blur_center_y\">अस्पष्ट केंद्र y</string>\n    <string name=\"zoom_blur\">झूम ब्लर</string>\n    <string name=\"color_balance\">रंग शिल्लक</string>\n    <string name=\"luminance_threshold\">ल्युमिनेन्स थ्रेशोल्ड</string>\n    <string name=\"activate_files\">तुम्ही Files ॲप अक्षम केले आहे, हे वैशिष्ट्य वापरण्यासाठी ते सक्रिय करा</string>\n    <string name=\"draw\">काढा</string>\n    <string name=\"draw_sub\">स्केचबुक प्रमाणे प्रतिमेवर काढा किंवा पार्श्वभूमीवरच काढा</string>\n    <string name=\"paint_color\">पेंट रंग</string>\n    <string name=\"paint_alpha\">अल्फा पेंट करा</string>\n    <string name=\"draw_on_image\">प्रतिमेवर काढा</string>\n    <string name=\"draw_on_image_sub\">एक प्रतिमा निवडा आणि त्यावर काहीतरी काढा</string>\n    <string name=\"draw_on_background\">पार्श्वभूमीवर काढा</string>\n    <string name=\"draw_on_background_sub\">पार्श्वभूमी रंग निवडा आणि त्याच्या वर काढा</string>\n    <string name=\"background_color\">पार्श्वभूमी रंग</string>\n    <string name=\"cipher\">सायफर</string>\n    <string name=\"cipher_sub\">विविध उपलब्ध क्रिप्टो अल्गोरिदमवर आधारित कोणतीही फाईल (केवळ प्रतिमाच नाही) कूटबद्ध आणि डिक्रिप्ट करा</string>\n    <string name=\"pick_file\">फाइल निवडा</string>\n    <string name=\"encrypt\">एनक्रिप्ट करा</string>\n    <string name=\"decrypt\">डिक्रिप्ट करा</string>\n    <string name=\"pick_file_to_start\">सुरू करण्यासाठी फाइल निवडा</string>\n    <string name=\"decryption\">डिक्रिप्शन</string>\n    <string name=\"encryption\">एनक्रिप्शन</string>\n    <string name=\"key\">की</string>\n    <string name=\"file_proceed\">फाइल प्रक्रिया केली</string>\n    <string name=\"store_file_desc\">ही फाईल तुमच्या डिव्हाइसवर साठवा किंवा तुम्हाला पाहिजे तेथे ठेवण्यासाठी शेअर कृती वापरा</string>\n    <string name=\"features\">वैशिष्ट्ये</string>\n    <string name=\"implementation\">अंमलबजावणी</string>\n    <string name=\"compatibility\">सुसंगतता</string>\n    <string name=\"features_sub\">फाइल्सचे पासवर्ड-आधारित एनक्रिप्शन. पुढे केलेल्या फायली निवडलेल्या निर्देशिकेत संग्रहित केल्या जाऊ शकतात किंवा सामायिक केल्या जाऊ शकतात. डिक्रिप्ट केलेल्या फायली थेट उघडल्या जाऊ शकतात.</string>\n    <string name=\"implementation_sub\">AES-256, GCM मोड, कोणतेही पॅडिंग नाही, 12 बाइट यादृच्छिक IV डीफॉल्टनुसार. आपण आवश्यक अल्गोरिदम निवडू शकता. की 256-बिट SHA-3 हॅश म्हणून वापरल्या जातात</string>\n    <string name=\"file_size\">फाइल आकार</string>\n    <string name=\"file_size_sub\">जास्तीत जास्त फाइल आकार Android OS आणि उपलब्ध मेमरीद्वारे प्रतिबंधित आहे, जी डिव्हाइसवर अवलंबून आहे.\n\\nकृपया लक्षात ठेवा: मेमरी ही स्टोरेज नाही.</string>\n    <string name=\"compatibility_sub\">कृपया लक्षात घ्या की इतर फाइल एन्क्रिप्शन सॉफ्टवेअर किंवा सेवांच्या सुसंगततेची हमी दिलेली नाही. किंचित भिन्न की उपचार किंवा सायफर कॉन्फिगरेशनमुळे विसंगतता येऊ शकते.</string>\n    <string name=\"invalid_password_or_not_encrypted\">अवैध पासवर्ड किंवा निवडलेली फाइल एनक्रिप्ट केलेली नाही</string>\n    <string name=\"image_size_warning\">दिलेल्या रुंदी आणि उंचीसह प्रतिमा जतन करण्याचा प्रयत्न केल्याने मेमरी त्रुटी होऊ शकते. हे तुमच्या स्वतःच्या जोखमीवर करा.</string>\n    <string name=\"cache\">कॅशे</string>\n    <string name=\"cache_size\">कॅशे आकार</string>\n    <string name=\"found_s\">%1$s सापडले</string>\n    <string name=\"auto_cache_clearing\">ऑटो कॅशे क्लिअरिंग</string>\n    <string name=\"auto_cache_clearing_sub\">सक्षम असल्यास ॲप कॅशे ॲप स्टार्टअपवर साफ केला जाईल</string>\n    <string name=\"create\">तयार करा</string>\n    <string name=\"tools\">साधने</string>\n    <string name=\"group_options_by_type\">प्रकारानुसार गट पर्याय</string>\n    <string name=\"group_options_by_type_sub\">सानुकूल सूची व्यवस्थेऐवजी मुख्य स्क्रीनवरील पर्याय त्यांच्या प्रकारानुसार गटबद्ध करा</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">पर्याय गटिंग सक्षम असताना व्यवस्था बदलू शकत नाही</string>\n    <string name=\"edit_screenshot\">स्क्रीनशॉट संपादित करा</string>\n    <string name=\"secondary_customization\">दुय्यम सानुकूलन</string>\n    <string name=\"screenshot\">स्क्रीनशॉट</string>\n    <string name=\"fallback_option\">फॉलबॅक पर्याय</string>\n    <string name=\"skip\">वगळा</string>\n    <string name=\"copy\">कॉपी करा</string>\n    <string name=\"warning_bytes\">%1$s मोडमध्ये जतन करणे अस्थिर असू शकते, कारण ते नुकसानरहित स्वरूप आहे</string>\n    <string name=\"presets_sub\">तुम्ही प्रीसेट 125 निवडले असल्यास, इमेज मूळ प्रतिमेच्या 125% आकारात सेव्ह केली जाईल. आपण प्रीसेट 50 निवडल्यास, प्रतिमा 50% आकारासह जतन केली जाईल</string>\n    <string name=\"presets_sub_bytes\">येथे प्रीसेट आउटपुट फाइलचे % ठरवते, म्हणजे तुम्ही 5 MB प्रतिमेवर प्रीसेट 50 निवडल्यास, सेव्ह केल्यानंतर तुम्हाला 2,5 MB प्रतिमा मिळेल.</string>\n    <string name=\"randomize_filename\">फाइलनाव यादृच्छिक करा</string>\n    <string name=\"randomize_filename_sub\">सक्षम केल्यास आउटपुट फाइलनाव पूर्णपणे यादृच्छिक असेल</string>\n    <string name=\"saved_to\">%2$s नावाने %1$s फोल्डरमध्ये जतन केले</string>\n    <string name=\"saved_to_without_filename\">%1$s फोल्डरमध्ये जतन केले</string>\n    <string name=\"tg_chat\">टेलीग्राम गप्पा</string>\n    <string name=\"tg_chat_sub\">ॲपवर चर्चा करा आणि इतर वापरकर्त्यांकडून फीडबॅक मिळवा. तुम्ही तेथे बीटा अपडेट्स आणि अंतर्दृष्टी देखील मिळवू शकता.</string>\n    <string name=\"crop_mask\">क्रॉप मास्क</string>\n    <string name=\"aspect_ratio\">आस्पेक्ट रेशो</string>\n    <string name=\"image_crop_mask_sub\">दिलेल्या प्रतिमेतून मुखवटा तयार करण्यासाठी हा मुखवटा प्रकार वापरा, लक्षात घ्या की त्यात अल्फा चॅनेल असणे आवश्यक आहे</string>\n    <string name=\"backup_and_restore\">बॅकअप आणि पुनर्संचयित करा</string>\n    <string name=\"backup\">बॅकअप</string>\n    <string name=\"restore\">पुनर्संचयित करा</string>\n    <string name=\"backup_sub\">तुमच्या ॲप सेटिंग्जचा एका फाईलमध्ये बॅकअप घ्या</string>\n    <string name=\"restore_sub\">पूर्वी व्युत्पन्न केलेल्या फाइलमधून ॲप सेटिंग्ज पुनर्संचयित करा</string>\n    <string name=\"corrupted_file_or_not_a_backup\">दूषित फाइल किंवा बॅकअप नाही</string>\n    <string name=\"settings_restored\">सेटिंग्ज यशस्वीरित्या पुनर्संचयित केल्या</string>\n    <string name=\"contact_me\">माझ्याशी संपर्क साधा</string>\n    <string name=\"reset_settings_sub\">हे तुमची सेटिंग्ज डीफॉल्ट मूल्यांवर परत आणेल. लक्षात घ्या की वर नमूद केलेल्या बॅकअप फाइलशिवाय हे पूर्ववत केले जाऊ शकत नाही.</string>\n    <string name=\"delete\">हटवा</string>\n    <string name=\"delete_color_scheme_warn\">तुम्ही निवडलेली रंगसंगती हटवणार आहात. हे ऑपरेशन पूर्ववत केले जाऊ शकत नाही</string>\n    <string name=\"delete_color_scheme_title\">योजना हटवा</string>\n    <string name=\"font\">फॉन्ट</string>\n    <string name=\"text\">मजकूर</string>\n    <string name=\"font_scale\">फॉन्ट स्केल</string>\n    <string name=\"defaultt\">डीफॉल्ट</string>\n    <string name=\"using_large_fonts_warn\">मोठ्या फॉन्ट स्केल वापरल्याने UI त्रुटी आणि समस्या उद्भवू शकतात, ज्याचे निराकरण केले जाणार नाही. सावधपणे वापरा.</string>\n    <string name=\"alphabet_and_numbers\">अ आ इ ई उ ऊ ऋ ए ऐ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण त थ द ध न प फ ब भ म य र ल व श ष स ह 0123456789 !?</string>\n    <string name=\"emotions\">भावना</string>\n    <string name=\"food_and_drink\">अन्न आणि पेय</string>\n    <string name=\"nature_and_animals\">निसर्ग आणि प्राणी</string>\n    <string name=\"objects\">वस्तू</string>\n    <string name=\"symbols\">चिन्हे</string>\n    <string name=\"enable_emoji\">इमोजी सक्षम करा</string>\n    <string name=\"travels_and_places\">प्रवास आणि ठिकाणे</string>\n    <string name=\"activities\">उपक्रम</string>\n    <string name=\"background_remover\">पार्श्वभूमी रिमूव्हर</string>\n    <string name=\"background_remover_sub\">चित्रातून पार्श्वभूमी काढा किंवा ऑटो पर्याय वापरा</string>\n    <string name=\"trim_image\">प्रतिमा ट्रिम करा</string>\n    <string name=\"keep_exif_sub\">मूळ इमेज मेटाडेटा ठेवला जाईल</string>\n    <string name=\"trim_image_sub\">प्रतिमेभोवतीची पारदर्शक जागा ट्रिम केली जाईल</string>\n    <string name=\"auto_erase_background\">पार्श्वभूमी स्वयं पुसून टाका</string>\n    <string name=\"restore_image\">प्रतिमा पुनर्संचयित करा</string>\n    <string name=\"erase_mode\">मिटवा मोड</string>\n    <string name=\"erase_background\">पार्श्वभूमी पुसून टाका</string>\n    <string name=\"restore_background\">पार्श्वभूमी पुनर्संचयित करा</string>\n    <string name=\"blur_radius\">अस्पष्ट त्रिज्या</string>\n    <string name=\"pipette\">पिपेट</string>\n    <string name=\"draw_mode\">रेखाचित्र मोड</string>\n    <string name=\"create_issue\">समस्या तयार करा</string>\n    <string name=\"resize_and_convert\">आकार बदला आणि रूपांतरित करा</string>\n    <string name=\"resize_and_convert_sub\">दिलेल्या प्रतिमांचा आकार बदला किंवा त्यांना इतर स्वरूपांमध्ये रूपांतरित करा. एकल प्रतिमा निवडल्यास EXIF ​​मेटाडेटा देखील येथे संपादित केला जाऊ शकतो.</string>\n    <string name=\"max_colors_count\">कमाल रंग संख्या</string>\n    <string name=\"crashlytics_sub\">हे ॲपला आपोआप क्रॅश अहवाल संकलित करण्यास अनुमती देते</string>\n    <string name=\"analytics\">विश्लेषण</string>\n    <string name=\"analytics_sub\">अनामित ॲप वापर आकडेवारी गोळा करण्यास अनुमती द्या</string>\n    <string name=\"image_exif_warning\">सध्या, %1$s फॉरमॅट केवळ Android वर EXIF ​​मेटाडेटा वाचण्याची अनुमती देते. सेव्ह केल्यावर आउटपुट इमेजमध्ये मेटाडेटा अजिबात नसेल.</string>\n    <string name=\"effort\">प्रयत्न</string>\n    <string name=\"effort_sub\">%1$s चे मूल्य म्हणजे जलद कॉम्प्रेशन, परिणामी फाइल आकारमानाने मोठा होतो. %2$s म्हणजे धीमे कॉम्प्रेशन, परिणामी एक लहान फाईल.</string>\n    <string name=\"wait\">थांबा</string>\n    <string name=\"saving_almost_complete\">जतन करणे जवळजवळ पूर्ण झाले. आता रद्द करण्यासाठी पुन्हा बचत करणे आवश्यक आहे.</string>\n    <string name=\"updates\">अपडेट्स</string>\n    <string name=\"allow_betas\">बीटास परवानगी द्या</string>\n    <string name=\"allow_betas_sub\">सक्षम केले असल्यास अद्यतन तपासणीमध्ये बीटा ॲप आवृत्त्यांचा समावेश असेल</string>\n    <string name=\"draw_arrows\">बाण काढा</string>\n    <string name=\"draw_arrows_sub\">सक्षम असल्यास रेखाचित्र मार्ग पॉइंटिंग ॲरो म्हणून दर्शविला जाईल</string>\n    <string name=\"brush_softness\">ब्रश मऊपणा</string>\n    <string name=\"crop_description\">एंटर केलेल्या आकारानुसार चित्रे मध्यभागी क्रॉप केली जातील. इमेज एंटर केलेल्या आयामांपेक्षा लहान असल्यास कॅनव्हास दिलेल्या पार्श्वभूमी रंगाने विस्तारित केला जाईल.</string>\n    <string name=\"donation\">दान</string>\n    <string name=\"image_stitching\">प्रतिमा स्टिचिंग</string>\n    <string name=\"image_stitching_sub\">एक मोठी प्रतिमा मिळविण्यासाठी दिलेल्या प्रतिमा एकत्र करा</string>\n    <string name=\"pick_at_least_two_images\">किमान 2 प्रतिमा निवडा</string>\n    <string name=\"output_image_scale\">आउटपुट प्रतिमा स्केल</string>\n    <string name=\"image_orientation\">प्रतिमा अभिमुखता</string>\n    <string name=\"horizontal\">क्षैतिज</string>\n    <string name=\"vertical\">उभ्या</string>\n    <string name=\"scale_small_images_to_large\">लहान प्रतिमा मोठ्या करा</string>\n    <string name=\"scale_small_images_to_large_sub\">सक्षम केल्यास लहान प्रतिमा अनुक्रमातील सर्वात मोठ्या प्रतिमांवर मोजल्या जातील</string>\n    <string name=\"images_order\">प्रतिमा क्रम</string>\n    <string name=\"regular\">नियमित</string>\n    <string name=\"blur_edges\">अस्पष्ट कडा</string>\n    <string name=\"blur_edges_sub\">सक्षम असल्यास एकल रंगाऐवजी त्याच्या सभोवतालची जागा भरण्यासाठी मूळ प्रतिमेखाली अस्पष्ट कडा काढते</string>\n    <string name=\"pixelation\">पिक्सेलेशन</string>\n    <string name=\"enhanced_pixelation\">वर्धित पिक्सेलेशन</string>\n    <string name=\"stroke_pixelation\">स्ट्रोक पिक्सेलेशन</string>\n    <string name=\"enhanced_diamond_pixelation\">वर्धित डायमंड पिक्सेलेशन</string>\n    <string name=\"diamond_pixelation\">डायमंड पिक्सेलेशन</string>\n    <string name=\"circle_pixelation\">सर्कल पिक्सेलेशन</string>\n    <string name=\"enhanced_circle_pixelation\">वर्धित सर्कल पिक्सेलेशन</string>\n    <string name=\"replace_color\">रंग बदला</string>\n    <string name=\"tolerance\">सहिष्णुता</string>\n    <string name=\"color_to_replace\">बदलण्यासाठी रंग</string>\n    <string name=\"target_color\">लक्ष्य रंग</string>\n    <string name=\"color_to_remove\">काढण्यासाठी रंग</string>\n    <string name=\"remove_color\">रंग काढा</string>\n    <string name=\"recode\">रीकोड करा</string>\n    <string name=\"pixel_size\">पिक्सेल आकार</string>\n    <string name=\"lock_draw_orientation\">लॉक ड्रॉ ओरिएंटेशन</string>\n    <string name=\"lock_draw_orientation_sub\">ड्रॉइंग मोडमध्ये सक्षम केल्यास, स्क्रीन फिरणार नाही</string>\n    <string name=\"check_for_updates\">अद्यतनांसाठी तपासा</string>\n    <string name=\"palette_style\">पॅलेट शैली</string>\n    <string name=\"tonal_spot\">टोनल स्पॉट</string>\n    <string name=\"neutral\">तटस्थ</string>\n    <string name=\"vibrant\">दोलायमान</string>\n    <string name=\"expressive\">अभिव्यक्त</string>\n    <string name=\"rainbow\">इंद्रधनुष्य</string>\n    <string name=\"fruit_salad\">फळ कोशिंबीर</string>\n    <string name=\"fidelity\">निष्ठा</string>\n    <string name=\"content\">सामग्री</string>\n    <string name=\"tonal_spot_sub\">डीफॉल्ट पॅलेट शैली, हे सर्व चार रंग सानुकूलित करण्याची परवानगी देते, इतर तुम्हाला फक्त मुख्य रंग सेट करण्याची परवानगी देतात</string>\n    <string name=\"neutral_sub\">एक शैली जी मोनोक्रोमपेक्षा थोडी अधिक रंगीत आहे</string>\n    <string name=\"vibrant_sub\">एक मोठा थीम, प्राथमिक पॅलेटसाठी रंगीतपणा जास्तीत जास्त आहे, इतरांसाठी वाढला आहे</string>\n    <string name=\"playful_scheme\">एक खेळकर थीम - स्रोत रंगाची छटा थीममध्ये दिसत नाही</string>\n    <string name=\"monochrome_sub\">एक मोनोक्रोम थीम, रंग पूर्णपणे काळा / पांढरा / राखाडी आहेत</string>\n    <string name=\"content_sub\">एक योजना जी Scheme.primaryContainer मध्ये स्त्रोत रंग ठेवते</string>\n    <string name=\"fidelity_sub\">एक योजना जी सामग्री योजनेसारखीच आहे</string>\n    <string name=\"foss_update_checker_warning\">नवीन अपडेट उपलब्ध आहे की नाही हे तपासण्याच्या कारणास्तव हा अपडेट तपासक GitHub शी कनेक्ट होईल</string>\n    <string name=\"attention\">लक्ष द्या</string>\n    <string name=\"fading_edges\">धूसर कडा</string>\n    <string name=\"disabled\">अक्षम</string>\n    <string name=\"both\">दोन्ही</string>\n    <string name=\"invert_colors\">उलटे रंग</string>\n    <string name=\"invert_colors_sub\">सक्षम असल्यास थीमचे रंग नकारात्मक रंगांमध्ये बदलते</string>\n    <string name=\"search_option\">शोधा</string>\n    <string name=\"search_option_sub\">मुख्य स्क्रीनवरील सर्व उपलब्ध साधनांमधून शोधण्याची क्षमता सक्षम करते</string>\n    <string name=\"pdf_tools\">PDF साधने</string>\n    <string name=\"pdf_tools_sub\">PDF फाइल्ससह ऑपरेट करा: पूर्वावलोकन करा, प्रतिमांच्या बॅचमध्ये रूपांतरित करा किंवा दिलेल्या चित्रांमधून एक तयार करा</string>\n    <string name=\"preview_pdf\">पीडीएफचे पूर्वावलोकन करा</string>\n    <string name=\"pdf_to_images\">PDF ते प्रतिमा</string>\n    <string name=\"images_to_pdf\">PDF मध्ये प्रतिमा</string>\n    <string name=\"preview_pdf_sub\">साधे पीडीएफ पूर्वावलोकन</string>\n    <string name=\"pdf_to_images_sub\">दिलेल्या आउटपुट फॉरमॅटमध्ये पीडीएफला प्रतिमांमध्ये रूपांतरित करा</string>\n    <string name=\"images_to_pdf_sub\">दिलेल्या प्रतिमा आउटपुट PDF फाईलमध्ये पॅक करा</string>\n    <string name=\"mask_filter\">मास्क फिल्टर</string>\n    <string name=\"mask_filter_sub\">दिलेल्या मास्क केलेल्या भागांवर फिल्टर चेन लावा, प्रत्येक मास्क क्षेत्र स्वतःचे फिल्टरचे संच ठरवू शकते</string>\n    <string name=\"masks\">मुखवटे</string>\n    <string name=\"add_mask\">मास्क जोडा</string>\n    <string name=\"mask_indexed\">मुखवटा %d</string>\n    <string name=\"mask_color\">मुखवटा रंग</string>\n    <string name=\"mask_preview\">मुखवटा पूर्वावलोकन</string>\n    <string name=\"mask_preview_sub\">तुम्हाला अंदाजे परिणाम दर्शविण्यासाठी काढलेला फिल्टर मास्क रेंडर केला जाईल</string>\n    <string name=\"inverse_fill_type\">व्यस्त भरण प्रकार</string>\n    <string name=\"inverse_fill_type_sub\">सक्षम केल्यास सर्व मुखवटा नसलेले क्षेत्र डीफॉल्ट वर्तनाऐवजी फिल्टर केले जातील</string>\n    <string name=\"delete_mask_warn\">तुम्ही निवडलेला फिल्टर मास्क हटवणार आहात. हे ऑपरेशन पूर्ववत केले जाऊ शकत नाही</string>\n    <string name=\"delete_mask\">मास्क हटवा</string>\n    <string name=\"full_filter\">पूर्ण फिल्टर</string>\n    <string name=\"full_filter_sub\">दिलेल्या प्रतिमा किंवा एकल प्रतिमेवर कोणतेही फिल्टर चेन लागू करा</string>\n    <string name=\"start_position\">सुरू करा</string>\n    <string name=\"center_position\">केंद्र</string>\n    <string name=\"end_position\">शेवट</string>\n    <string name=\"simple_variants\">साधी रूपे</string>\n    <string name=\"highlighter\">हायलाइटर</string>\n    <string name=\"neon\">निऑन</string>\n    <string name=\"pen\">पेन</string>\n    <string name=\"privacy_blur\">गोपनीयता अस्पष्टता</string>\n    <string name=\"highlighter_sub\">अर्ध-पारदर्शक तीक्ष्ण हायलाइटर मार्ग काढा</string>\n    <string name=\"neon_sub\">तुमच्या रेखाचित्रांमध्ये काही चमकणारा प्रभाव जोडा</string>\n    <string name=\"pen_sub\">डीफॉल्ट एक, सर्वात सोपा - फक्त रंग</string>\n    <string name=\"privacy_blur_sub\">आपण लपवू इच्छित असलेली कोणतीही गोष्ट सुरक्षित करण्यासाठी काढलेल्या मार्गाखाली प्रतिमा अस्पष्ट करते</string>\n    <string name=\"pixelation_sub\">प्रायव्हसी ब्लर प्रमाणेच, परंतु अस्पष्ट करण्याऐवजी पिक्सेलेट</string>\n    <string name=\"containers_shadow\">कंटेनर</string>\n    <string name=\"containers_shadow_sub\">कंटेनरच्या मागे सावली काढा</string>\n    <string name=\"sliders_shadow\">स्लाइडर</string>\n    <string name=\"switches_shadow\">स्विचेस</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">बटणे</string>\n    <string name=\"sliders_shadow_sub\">स्लाइडरच्या मागे सावली काढा</string>\n    <string name=\"switches_shadow_sub\">स्विचच्या मागे सावली काढा</string>\n    <string name=\"fabs_shadow_sub\">फ्लोटिंग ॲक्शन बटणांच्या मागे सावली काढा</string>\n    <string name=\"buttons_shadow_sub\">बटणांच्या मागे सावली काढा</string>\n    <string name=\"app_bars_shadow\">ॲप बार</string>\n    <string name=\"app_bars_shadow_sub\">ॲप बारच्या मागे सावली काढा</string>\n    <string name=\"value_in_range\">श्रेणीतील मूल्य %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">स्वयं फिरवा</string>\n    <string name=\"auto_rotate_limits_sub\">प्रतिमा अभिमुखतेसाठी मर्यादा बॉक्स स्वीकारण्याची अनुमती देते</string>\n    <string name=\"draw_path_mode\">पथ मोड काढा</string>\n    <string name=\"double_line_arrow\">दुहेरी रेषा बाण</string>\n    <string name=\"free_drawing\">विनामूल्य रेखाचित्र</string>\n    <string name=\"double_arrow\">दुहेरी बाण</string>\n    <string name=\"line_arrow\">रेषा बाण</string>\n    <string name=\"arrow\">बाण</string>\n    <string name=\"line\">ओळ</string>\n    <string name=\"free_drawing_sub\">इनपुट मूल्य म्हणून मार्ग काढतो</string>\n    <string name=\"line_sub\">रेषा म्हणून प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंतचा मार्ग काढतो</string>\n    <string name=\"line_arrow_sub\">सुरुवातीच्या बिंदूपासून शेवटच्या बिंदूपर्यंत एक रेषा म्हणून सूचक बाण काढतो</string>\n    <string name=\"arrow_sub\">दिलेल्या मार्गावरून सूचक बाण काढतो</string>\n    <string name=\"double_line_arrow_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत एक रेषा म्हणून दुहेरी पॉइंटिंग बाण काढतो</string>\n    <string name=\"double_arrow_sub\">दिलेल्या मार्गावरून दुहेरी निर्देश करणारा बाण काढतो</string>\n    <string name=\"outlined_oval\">रेखांकित ओव्हल</string>\n    <string name=\"outlined_rect\">रेखांकित रेक्ट</string>\n    <string name=\"oval\">ओव्हल</string>\n    <string name=\"rect\">रेक्ट</string>\n    <string name=\"rect_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत आयत काढतो</string>\n    <string name=\"oval_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत अंडाकृती काढतो</string>\n    <string name=\"outlined_oval_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत बाह्यरेखित अंडाकृती काढतो</string>\n    <string name=\"outlined_rect_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत बाह्यरेखा काढतो</string>\n    <string name=\"lasso\">लॅसो</string>\n    <string name=\"lasso_sub\">दिलेल्या मार्गाने बंद भरलेला मार्ग काढतो</string>\n    <string name=\"free\">मोफत</string>\n    <string name=\"horizontal_grid\">क्षैतिज ग्रिड</string>\n    <string name=\"vertical_grid\">अनुलंब ग्रिड</string>\n    <string name=\"stitch_mode\">स्टिच मोड</string>\n    <string name=\"rows_count\">पंक्तींची संख्या</string>\n    <string name=\"columns_count\">स्तंभांची संख्या</string>\n    <string name=\"no_such_directory\">कोणतीही \\\"%1$s\\\" निर्देशिका आढळली नाही, आम्ही ती डीफॉल्टवर स्विच केली, कृपया फाइल पुन्हा सेव्ह करा</string>\n    <string name=\"clipboard\">क्लिपबोर्ड</string>\n    <string name=\"auto_pin\">ऑटो पिन</string>\n    <string name=\"auto_pin_sub\">सक्षम असल्यास क्लिपबोर्डवर जतन केलेली प्रतिमा स्वयंचलितपणे जोडते</string>\n    <string name=\"vibration\">कंपन</string>\n    <string name=\"vibration_strength\">कंपन शक्ती</string>\n    <string name=\"overwrite_file_requirements\">फाइल्स ओव्हरराइट करण्यासाठी तुम्हाला \\\"एक्सप्लोरर\\\" इमेज सोर्स वापरण्याची गरज आहे, इमेज रिपिक करून पहा, आम्ही इमेज सोर्स आवश्यकतेनुसार बदलला आहे.</string>\n    <string name=\"overwrite_files\">फायली अधिलिखित करा</string>\n    <string name=\"overwrite_files_sub\">मूळ फाइल निवडलेल्या फोल्डरमध्ये सेव्ह करण्याऐवजी नवीन फाइलने बदलली जाईल, या पर्यायाला इमेज सोर्स \\\"एक्सप्लोरर\\\" किंवा GetContent असणे आवश्यक आहे, हे टॉगल करताना, ते स्वयंचलितपणे सेट केले जाईल.</string>\n    <string name=\"empty\">रिकामे</string>\n    <string name=\"suffix\">प्रत्यय</string>\n    <string name=\"scale_mode\">स्केल मोड</string>\n    <string name=\"bilinear\">द्विरेखीय</string>\n    <string name=\"catmull\">कॅटमुल</string>\n    <string name=\"bicubic\">बायक्यूबिक</string>\n    <string name=\"hann\">तो</string>\n    <string name=\"hermite\">संन्यासी</string>\n    <string name=\"mitchell\">मिशेल</string>\n    <string name=\"spline\">पट्टी</string>\n    <string name=\"basic\">बेसिक</string>\n    <string name=\"default_value\">डीफॉल्ट मूल्य</string>\n    <string name=\"bilinear_sub\">प्रतिमेचा आकार बदलण्यासाठी रेखीय (किंवा द्विरेखीय, दोन आयामांमध्ये) इंटरपोलेशन सामान्यत: चांगले असते, परंतु तपशिलांना काही अवांछित मऊ बनवते आणि तरीही काहीसे दातेरी असू शकते.</string>\n    <string name=\"bicubic_sub\">उत्तम स्केलिंग पद्धतींमध्ये लँकझोस रीसॅम्पलिंग आणि मिशेल-नेत्रावली फिल्टर समाविष्ट आहेत</string>\n    <string name=\"nearest_sub\">आकार वाढवण्याचा एक सोपा मार्ग, प्रत्येक पिक्सेलला एकाच रंगाच्या अनेक पिक्सेलसह बदलणे</string>\n    <string name=\"basic_sub\">सर्वात सोपा Android स्केलिंग मोड जो जवळजवळ सर्व ॲप्समध्ये वापरला जातो</string>\n    <string name=\"catmull_sub\">गुळगुळीत वक्र तयार करण्यासाठी सामान्यतः संगणक ग्राफिक्समध्ये वापरल्या जाणाऱ्या कंट्रोल पॉइंट्सच्या संचाचे सहजतेने इंटरपोलेटिंग आणि रीसेम्पलिंग करण्याची पद्धत</string>\n    <string name=\"hann_sub\">स्पेक्ट्रल गळती कमी करण्यासाठी आणि सिग्नलच्या कडा कमी करून वारंवारता विश्लेषणाची अचूकता सुधारण्यासाठी सिग्नल प्रक्रियेमध्ये विंडोिंग फंक्शन अनेकदा लागू केले जाते.</string>\n    <string name=\"hermite_sub\">गणितीय इंटरपोलेशन तंत्र जे वक्र विभागाच्या शेवटच्या बिंदूंवर एक गुळगुळीत आणि सतत वक्र तयार करण्यासाठी मूल्ये आणि व्युत्पन्न वापरते</string>\n    <string name=\"lanczos_sub\">पिक्सेल मूल्यांवर भारित sinc फंक्शन लागू करून उच्च-गुणवत्तेचे इंटरपोलेशन राखणारी रीसॅम्पलिंग पद्धत</string>\n    <string name=\"mitchell_sub\">रीसॅम्पलिंग पद्धत जी मोजमाप केलेल्या प्रतिमेमध्ये तीक्ष्णता आणि अँटी-अलायझिंग दरम्यान संतुलन साधण्यासाठी समायोज्य पॅरामीटर्ससह कॉन्व्होल्यूशन फिल्टर वापरते</string>\n    <string name=\"spline_sub\">लवचिक आणि सतत आकाराचे प्रतिनिधित्व प्रदान करून, वक्र किंवा पृष्ठभागावर सहजतेने इंटरपोलेट करण्यासाठी आणि अंदाजे करण्यासाठी तुकड्यानुसार-परिभाषित बहुपदीय कार्ये वापरते</string>\n    <string name=\"only_clip\">फक्त क्लिप</string>\n    <string name=\"only_clip_sub\">स्टोरेजमध्ये सेव्हिंग केले जाणार नाही आणि इमेज फक्त क्लिपबोर्डमध्ये ठेवण्याचा प्रयत्न केला जाईल</string>\n    <string name=\"restore_background_sub\">ब्रश मिटवण्याऐवजी पार्श्वभूमी पुनर्संचयित करेल</string>\n    <string name=\"recognize_text\">OCR (मजकूर ओळखा)</string>\n    <string name=\"recognize_text_sub\">दिलेल्या प्रतिमेतून मजकूर ओळखा, 120+ भाषा समर्थित</string>\n    <string name=\"picture_has_no_text\">चित्रात मजकूर नाही किंवा ॲपला तो सापडला नाही</string>\n    <string name=\"accuracy\">\\\"अचूकता: %1$s\\\"</string>\n    <string name=\"recognition_type\">ओळख प्रकार</string>\n    <string name=\"fast\">जलद</string>\n    <string name=\"standard\">मानक</string>\n    <string name=\"best\">सर्वोत्तम</string>\n    <string name=\"no_data\">डेटा नाही</string>\n    <string name=\"download_description\">Tesseract OCR च्या योग्य कार्यासाठी अतिरिक्त प्रशिक्षण डेटा (%1$s) आपल्या डिव्हाइसवर डाउनलोड करणे आवश्यक आहे.\\nतुम्हाला %2$s डेटा डाउनलोड करायचा आहे का?</string>\n    <string name=\"download\">डाउनलोड करा</string>\n    <string name=\"no_connection\">कोणतेही कनेक्शन नाही, ते तपासा आणि ट्रेन मॉडेल डाउनलोड करण्यासाठी पुन्हा प्रयत्न करा</string>\n    <string name=\"downloaded_languages\">डाउनलोड केलेल्या भाषा</string>\n    <string name=\"available_languages\">उपलब्ध भाषा</string>\n    <string name=\"segmentation_mode\">सेगमेंटेशन मोड</string>\n    <string name=\"use_pixel_switch\">पिक्सेल स्विच वापरा</string>\n    <string name=\"use_pixel_switch_sub\">Google Pixel सारखे स्विच वापरते</string>\n    <string name=\"saved_to_original\">मूळ गंतव्यस्थानावर %1$s नावासह अधिलिखित फाइल</string>\n    <string name=\"magnifier\">भिंग</string>\n    <string name=\"magnifier_sub\">उत्तम प्रवेशयोग्यतेसाठी रेखाचित्र मोडमध्ये बोटाच्या शीर्षस्थानी भिंग सक्षम करते</string>\n    <string name=\"force_exif_widget_initial_value\">प्रारंभिक मूल्य सक्ती करा</string>\n    <string name=\"force_exif_widget_initial_value_sub\">सुरुवातीला exif विजेट तपासण्याची सक्ती करते</string>\n    <string name=\"allow_multiple_languages\">एकाधिक भाषांना परवानगी द्या</string>\n    <string name=\"slide\">स्लाइड करा</string>\n    <string name=\"side_by_side\">शेजारी शेजारी</string>\n    <string name=\"toggle_tap\">टॅप टॉगल करा</string>\n    <string name=\"transparency\">पारदर्शकता</string>\n    <string name=\"rate_app\">ॲपला रेट करा</string>\n    <string name=\"rate\">रेट करा</string>\n    <string name=\"rate_app_sub\">हे ॲप पूर्णपणे विनामूल्य आहे, जर तुम्हाला ते मोठे व्हायचे असेल तर कृपया Github वर प्रोजेक्ट स्टार करा 😄</string>\n    <string name=\"segmentation_mode_osd_only\">केवळ अभिमुखता आणि स्क्रिप्ट शोध</string>\n    <string name=\"segmentation_mode_auto_osd\">ऑटो ओरिएंटेशन आणि स्क्रिप्ट शोध</string>\n    <string name=\"segmentation_mode_auto_only\">फक्त ऑटो</string>\n    <string name=\"segmentation_mode_auto\">ऑटो</string>\n    <string name=\"segmentation_mode_single_column\">सिंगल कॉलम</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">एकल ब्लॉक अनुलंब मजकूर</string>\n    <string name=\"segmentation_mode_single_block\">सिंगल ब्लॉक</string>\n    <string name=\"segmentation_mode_single_line\">एकच ओळ</string>\n    <string name=\"segmentation_mode_single_word\">एकच शब्द</string>\n    <string name=\"segmentation_mode_circle_word\">वर्तुळ शब्द</string>\n    <string name=\"segmentation_mode_single_char\">एकच चारी</string>\n    <string name=\"segmentation_mode_sparse_text\">विरळ मजकूर</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">विरळ मजकूर अभिमुखता आणि स्क्रिप्ट शोध</string>\n    <string name=\"segmentation_mode_raw_line\">कच्ची ओळ</string>\n    <string name=\"delete_language_sub\">तुम्ही सर्व ओळख प्रकारांसाठी भाषा \\\"%1$s\\\" OCR प्रशिक्षण डेटा हटवू इच्छिता की फक्त निवडलेल्या (%2$s) साठी?</string>\n    <string name=\"current\">चालू</string>\n    <string name=\"all\">सर्व</string>\n    <string name=\"gradient_maker\">ग्रेडियंट मेकर</string>\n    <string name=\"gradient_maker_sub\">सानुकूलित रंग आणि देखावा प्रकारासह दिलेल्या आउटपुट आकाराचा ग्रेडियंट तयार करा</string>\n    <string name=\"gradient_type_linear\">रेखीय</string>\n    <string name=\"gradient_type_radial\">रेडियल</string>\n    <string name=\"gradient_type_sweep\">स्वीप करा</string>\n    <string name=\"gradient_type\">ग्रेडियंट प्रकार</string>\n    <string name=\"center_x\">केंद्र एक्स</string>\n    <string name=\"center_y\">केंद्र वाय</string>\n    <string name=\"tile_mode\">टाइल मोड</string>\n    <string name=\"tile_mode_repeated\">वारंवार</string>\n    <string name=\"tile_mode_mirror\">आरसा</string>\n    <string name=\"tile_mode_clamp\">पकडीत घट्ट करणे</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"color_stops\">रंग थांबतो</string>\n    <string name=\"add_color\">रंग जोडा</string>\n    <string name=\"properties\">गुणधर्म</string>\n    <string name=\"brightness_enforcement\">ब्राइटनेस अंमलबजावणी</string>\n    <string name=\"screen\">पडदा</string>\n    <string name=\"gradient_maker_type_image\">ग्रेडियंट आच्छादन</string>\n    <string name=\"gradient_maker_type_image_sub\">दिलेल्या प्रतिमांच्या शीर्षस्थानी कोणताही ग्रेडियंट तयार करा</string>\n    <string name=\"transformations\">परिवर्तने</string>\n    <string name=\"camera\">कॅमेरा</string>\n    <string name=\"camera_sub\">कॅमेऱ्याने फोटो काढा. लक्षात ठेवा की या प्रतिमा स्त्रोतावरून फक्त एक प्रतिमा मिळविणे शक्य आहे</string>\n    <string name=\"watermarking\">वॉटरमार्किंग</string>\n    <string name=\"watermarking_sub\">सानुकूल करण्यायोग्य मजकूर/प्रतिमा वॉटरमार्कसह चित्रे कव्हर करा</string>\n    <string name=\"repeat_watermark\">वॉटरमार्कची पुनरावृत्ती करा</string>\n    <string name=\"offset_y\">ऑफसेट Y</string>\n    <string name=\"watermark_type\">वॉटरमार्क प्रकार</string>\n    <string name=\"watermarking_image_sub\">ही प्रतिमा वॉटरमार्किंगसाठी नमुना म्हणून वापरली जाईल</string>\n    <string name=\"text_color\">मजकूर रंग</string>\n    <string name=\"overlay_mode\">आच्छादन मोड</string>\n    <string name=\"gif_tools\">GIF साधने</string>\n    <string name=\"gif_tools_sub\">प्रतिमांना GIF चित्रात रूपांतरित करा किंवा दिलेल्या GIF प्रतिमेमधून फ्रेम्स काढा</string>\n    <string name=\"gif_type_to_image\">प्रतिमांना GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF फाइल चित्रांच्या बॅचमध्ये रूपांतरित करा</string>\n    <string name=\"gif_type_to_gif_sub\">प्रतिमांचा बॅच GIF फाइलमध्ये रूपांतरित करा</string>\n    <string name=\"gif_type_to_gif\">GIF मध्ये प्रतिमा</string>\n    <string name=\"select_gif_image_to_start\">प्रारंभ करण्यासाठी GIF प्रतिमा निवडा</string>\n    <string name=\"use_size_of_first_frame\">प्रथम फ्रेमचा आकार वापरा</string>\n    <string name=\"use_size_of_first_frame_sub\">प्रथम फ्रेम परिमाणांसह निर्दिष्ट आकार पुनर्स्थित करा</string>\n    <string name=\"repeat_count\">पुनरावृत्ती गणना</string>\n    <string name=\"frame_delay\">फ्रेम विलंब</string>\n    <string name=\"millis\">मिलिस</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">लॅसो वापरा</string>\n    <string name=\"use_lasso_sub\">मिटवण्यासाठी ड्रॉईंग मोडमध्ये Lasso चा वापर करते</string>\n    <string name=\"original_image_preview_alpha\">मूळ प्रतिमा पूर्वावलोकन अल्फा</string>\n    <string name=\"confetti\">कॉन्फेटी</string>\n    <string name=\"confetti_sub\">सेव्हिंग, शेअरिंग आणि इतर प्राथमिक क्रियांवर कॉन्फेटी दाखवली जाईल</string>\n    <string name=\"secure_mode\">सुरक्षित मोड</string>\n    <string name=\"secure_mode_sub\">अलीकडील ॲप्समधील ॲप सामग्री लपवते. ते कॅप्चर किंवा रेकॉर्ड केले जाऊ शकत नाही.</string>\n    <string name=\"exit\">बाहेर पडा</string>\n    <string name=\"preview_closing\">तुम्ही आता पूर्वावलोकन सोडल्यास, तुम्हाला पुन्हा प्रतिमा जोडण्याची आवश्यकता असेल</string>\n    <string name=\"dithering\">डिथरिंग</string>\n    <string name=\"quantizier\">क्वांटायझर</string>\n    <string name=\"gray_scale\">ग्रे स्केल</string>\n    <string name=\"bayer_two_dithering\">बायर टू बाय टू डिथरिंग</string>\n    <string name=\"bayer_three_dithering\">बायर थ्री बाय थ्री डिथरिंग</string>\n    <string name=\"bayer_four_dithering\">बायर फोर बाय फोर डिथरिंग</string>\n    <string name=\"bayer_eight_dithering\">बायर आठ बाय आठ डिथरिंग</string>\n    <string name=\"floyd_steinberg_dithering\">फ्लॉइड स्टीनबर्ग डिथरिंग</string>\n    <string name=\"jarvis_judice_ninke_dithering\">जार्विस न्यायाधीश निन्के डिथरिंग</string>\n    <string name=\"sierra_dithering\">सिएरा डिथरिंग</string>\n    <string name=\"two_row_sierra_dithering\">दोन पंक्ती सिएरा डिथरिंग</string>\n    <string name=\"sierra_lite_dithering\">सिएरा लाइट डिथरिंग</string>\n    <string name=\"atkinson_dithering\">ॲटकिन्सन डिथरिंग</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">बर्क्स डिथरिंग</string>\n    <string name=\"false_floyd_steinberg_dithering\">खोटे फ्लॉइड स्टीनबर्ग डिथरिंग</string>\n    <string name=\"left_to_right_dithering\">डावीकडून उजवीकडे डिथरिंग</string>\n    <string name=\"random_dithering\">यादृच्छिक डिथरिंग</string>\n    <string name=\"simple_threshold_dithering\">साधे थ्रेशोल्ड डिथरिंग</string>\n    <string name=\"sigma\">सिग्मा</string>\n    <string name=\"spatial_sigma\">अवकाशीय सिग्मा</string>\n    <string name=\"median_blur\">मध्यम अस्पष्टता</string>\n    <string name=\"b_spline\">बी स्प्लाइन</string>\n    <string name=\"b_spline_sub\">वक्र किंवा पृष्ठभाग, लवचिक आणि सतत आकाराचे प्रतिनिधित्व सहजतेने इंटरपोलेट करण्यासाठी आणि अंदाजे करण्यासाठी तुकडावार-परिभाषित बायक्यूबिक बहुपदी कार्ये वापरते</string>\n    <string name=\"native_stack_blur\">नेटिव्ह स्टॅक ब्लर</string>\n    <string name=\"tilt_shift\">टिल्ट शिफ्ट</string>\n    <string name=\"glitch\">गडबड</string>\n    <string name=\"amount\">रक्कम</string>\n    <string name=\"seed\">बी</string>\n    <string name=\"anaglyph\">ॲनाग्लिफ</string>\n    <string name=\"noise\">गोंगाट</string>\n    <string name=\"pixel_sort\">पिक्सेल क्रमवारी</string>\n    <string name=\"shuffle\">शफल</string>\n    <string name=\"enhanced_glitch\">वर्धित ग्लिच</string>\n    <string name=\"channel_shift_x\">चॅनल शिफ्ट एक्स</string>\n    <string name=\"channel_shift_y\">चॅनल शिफ्ट वाई</string>\n    <string name=\"corruption_size\">भ्रष्टाचाराचा आकार</string>\n    <string name=\"corruption_shift_x\">भ्रष्टाचार शिफ्ट एक्स</string>\n    <string name=\"corruption_shift_y\">भ्रष्टाचार शिफ्ट वाई</string>\n    <string name=\"tent_blur\">तंबू अंधुक</string>\n    <string name=\"side_fade\">बाजूला फिकट</string>\n    <string name=\"side\">बाजू</string>\n    <string name=\"top\">वर</string>\n    <string name=\"bottom\">तळ</string>\n    <string name=\"strength\">ताकद</string>\n    <string name=\"erode\">इरोड</string>\n    <string name=\"anisotropic_diffusion\">ॲनिसोट्रॉपिक प्रसार</string>\n    <string name=\"diffusion\">प्रसार</string>\n    <string name=\"conduction\">वहन</string>\n    <string name=\"horizontal_wind_stagger\">क्षैतिज वारा स्टॅगर</string>\n    <string name=\"fast_bilaterial_blur\">जलद द्विपक्षीय अस्पष्टता</string>\n    <string name=\"poisson_blur\">पॉयसन ब्लर</string>\n    <string name=\"logarithmic_tone_mapping\">लॉगरिदमिक टोन मॅपिंग</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES फिल्मिक टोन मॅपिंग</string>\n    <string name=\"crystallize\">स्फटिक करणे</string>\n    <string name=\"stroke_color\">स्ट्रोक रंग</string>\n    <string name=\"fractal_glass\">फ्रॅक्टल ग्लास</string>\n    <string name=\"amplitude\">मोठेपणा</string>\n    <string name=\"marble\">संगमरवरी</string>\n    <string name=\"turbulence\">अशांतता</string>\n    <string name=\"oil\">तेल</string>\n    <string name=\"water_effect\">पाण्याचा प्रभाव</string>\n    <string name=\"just_size\">आकार</string>\n    <string name=\"frequency_x\">वारंवारता X</string>\n    <string name=\"frequency_y\">वारंवारता Y</string>\n    <string name=\"amplitude_x\">मोठेपणा X</string>\n    <string name=\"amplitude_y\">मोठेपणा Y</string>\n    <string name=\"perlin_distortion\">पर्लिन विरूपण</string>\n    <string name=\"aces_hill_tone_mapping\">ACES हिल टोन मॅपिंग</string>\n    <string name=\"hable_filmic_tone_mapping\">हेबल फिल्मिक टोन मॅपिंग</string>\n    <string name=\"heji_burgess_tone_mapping\">हेजी-बर्गेस टोन मॅपिंग</string>\n    <string name=\"speed\">गती</string>\n    <string name=\"dehaze\">देहाळे</string>\n    <string name=\"omega\">ओमेगा</string>\n    <string name=\"color_matrix_4x4\">कलर मॅट्रिक्स 4x4</string>\n    <string name=\"color_matrix_3x3\">कलर मॅट्रिक्स 3x3</string>\n    <string name=\"simple_effects\">साधे प्रभाव</string>\n    <string name=\"polaroid\">पोलरॉइड</string>\n    <string name=\"tritonomaly\">ट्रायटॅनोमली</string>\n    <string name=\"deutaromaly\">Deuteranomaly</string>\n    <string name=\"protonomaly\">प्रोटोनोमली</string>\n    <string name=\"vintage\">विंटेज</string>\n    <string name=\"browni\">तपकिरी च्या</string>\n    <string name=\"coda_chrome\">कोडा क्रोम</string>\n    <string name=\"night_vision\">नाईट व्हिजन</string>\n    <string name=\"warm\">उबदार</string>\n    <string name=\"cool\">मस्त</string>\n    <string name=\"tritanopia\">ट्रायटॅनोपिया</string>\n    <string name=\"deutaronotopia\">ड्युटारोनोटोपिया</string>\n    <string name=\"protanopia\">प्रोटानोपिया</string>\n    <string name=\"achromatomaly\">अक्रोमॅटोमॅली</string>\n    <string name=\"achromatopsia\">ऍक्रोमॅटोप्सिया</string>\n    <string name=\"grain\">धान्य</string>\n    <string name=\"unsharp\">अनशार्प</string>\n    <string name=\"pastel\">पेस्टल</string>\n    <string name=\"orange_haze\">नारिंगी धुके</string>\n    <string name=\"pink_dream\">गुलाबी स्वप्न</string>\n    <string name=\"golden_hour\">गोल्डन अवर</string>\n    <string name=\"hot_summer\">गरम उन्हाळा</string>\n    <string name=\"purple_mist\">जांभळा धुके</string>\n    <string name=\"sunrise\">सूर्योदय</string>\n    <string name=\"colorful_swirl\">रंगीबेरंगी चक्कर</string>\n    <string name=\"soft_spring_light\">मऊ स्प्रिंग लाइट</string>\n    <string name=\"autumn_tones\">शरद ऋतूतील टोन</string>\n    <string name=\"lavender_dream\">लॅव्हेंडर स्वप्न</string>\n    <string name=\"cyberpunk\">सायबरपंक</string>\n    <string name=\"lemonade_light\">लिंबूपाणी प्रकाश</string>\n    <string name=\"spectral_fire\">स्पेक्ट्रल फायर</string>\n    <string name=\"night_magic\">रात्रीची जादू</string>\n    <string name=\"fantasy_landscape\">कल्पनारम्य लँडस्केप</string>\n    <string name=\"color_explosion\">रंग स्फोट</string>\n    <string name=\"electric_gradient\">इलेक्ट्रिक ग्रेडियंट</string>\n    <string name=\"caramel_darkness\">कारमेल अंधार</string>\n    <string name=\"futuristic_gradient\">फ्युचरिस्टिक ग्रेडियंट</string>\n    <string name=\"green_sun\">हिरवा सूर्य</string>\n    <string name=\"rainbow_world\">इंद्रधनुष्य जग</string>\n    <string name=\"deep_purple\">खोल जांभळा</string>\n    <string name=\"space_portal\">स्पेस पोर्टल</string>\n    <string name=\"red_swirl\">लाल चक्कर</string>\n    <string name=\"digital_code\">डिजिटल कोड</string>\n    <string name=\"bokeh\">बोकेह</string>\n    <string name=\"random_emojis_sub\">ॲप बार इमोजी यादृच्छिकपणे बदलेल</string>\n    <string name=\"random_emojis\">यादृच्छिक इमोजी</string>\n    <string name=\"random_emojis_error\">इमोजी अक्षम असताना तुम्ही यादृच्छिक इमोजी वापरू शकत नाही</string>\n    <string name=\"emoji_selection_error\">यादृच्छिक इमोजी सक्षम असताना तुम्ही इमोजी निवडू शकत नाही</string>\n    <string name=\"old_tv\">जुना टीव्ही</string>\n    <string name=\"shuffle_blur\">अस्पष्टता शफल करा</string>\n    <string name=\"favorite\">आवडते</string>\n    <string name=\"no_favorite_filters\">अद्याप कोणतेही आवडते फिल्टर जोडलेले नाहीत</string>\n    <string name=\"image_format\">प्रतिमा स्वरूप</string>\n    <string name=\"icon_shape_sub\">चिन्हांखाली निवडलेल्या आकारासह कंटेनर जोडते</string>\n    <string name=\"icon_shape\">चिन्ह आकार</string>\n    <string name=\"drago\">ड्रॅगो</string>\n    <string name=\"aldridge\">अल्ड्रिज</string>\n    <string name=\"cutoff\">कटऑफ</string>\n    <string name=\"uchimura\">तुम्ही जागे व्हा</string>\n    <string name=\"mobius\">मोबियस</string>\n    <string name=\"transition\">संक्रमण</string>\n    <string name=\"peak\">शिखर</string>\n    <string name=\"color_anomaly\">रंग विसंगती</string>\n    <string name=\"images_overwritten\">मूळ गंतव्यस्थानावर ओव्हरराईट केलेल्या प्रतिमा</string>\n    <string name=\"cannot_change_image_format\">फाइल्स ओव्हरराइट पर्याय सक्षम असताना इमेज फॉरमॅट बदलू शकत नाही</string>\n    <string name=\"emoji_as_color_scheme\">रंग योजना म्हणून इमोजी</string>\n    <string name=\"emoji_as_color_scheme_sub\">मॅन्युअली परिभाषित रंगाऐवजी इमोजी प्राथमिक रंग ॲप कलर स्कीम म्हणून वापरते</string>\n    <string name=\"material_you_sub\">इमेजमधून मटेरियल यू पॅलेट तयार करते</string>\n    <string name=\"dark_colors\">गडद रंग</string>\n    <string name=\"dark_colors_sub\">लाइट वेरिएंटऐवजी नाईट मोड कलर स्कीम वापरते</string>\n    <string name=\"copy_as_compose_code\">Jetpack कंपोझ कोड म्हणून कॉपी करा</string>\n    <string name=\"ring_blur\">रिंग ब्लर</string>\n    <string name=\"cross_blur\">क्रॉस ब्लर</string>\n    <string name=\"circle_blur\">वर्तुळ अस्पष्ट</string>\n    <string name=\"star_blur\">तारा अस्पष्ट</string>\n    <string name=\"linear_tilt_shift\">रेखीय टिल्ट-शिफ्ट</string>\n    <string name=\"tags_to_remove\">टॅग्ज काढण्यासाठी</string>\n    <string name=\"apng_tools\">APNG साधने</string>\n    <string name=\"apng_tools_sub\">प्रतिमा APNG चित्रात रूपांतरित करा किंवा दिलेल्या APNG प्रतिमेमधून फ्रेम काढा</string>\n    <string name=\"apng_type_to_image\">प्रतिमांना APNG</string>\n    <string name=\"apng_type_to_image_sub\">APNG फाइल चित्रांच्या बॅचमध्ये रूपांतरित करा</string>\n    <string name=\"apng_type_to_apng_sub\">प्रतिमांचा बॅच APNG फाईलमध्ये रूपांतरित करा</string>\n    <string name=\"apng_type_to_apng\">APNG वर प्रतिमा</string>\n    <string name=\"select_apng_image_to_start\">सुरू करण्यासाठी APNG प्रतिमा निवडा</string>\n    <string name=\"motion_blur\">मोशन ब्लर</string>\n    <string name=\"zip\">जि.प</string>\n    <string name=\"zip_sub\">दिलेल्या फाईल्स किंवा इमेजेसमधून Zip फाइल तयार करा</string>\n    <string name=\"drag_handle_width\">हँडल रुंदी ड्रॅग करा</string>\n    <string name=\"confetti_type\">कॉन्फेटी प्रकार</string>\n    <string name=\"festive\">सण</string>\n    <string name=\"explode\">स्फोट</string>\n    <string name=\"rain\">पाऊस</string>\n    <string name=\"corners\">कोपरे</string>\n    <string name=\"jxl_tools\">JXL साधने</string>\n    <string name=\"jxl_tools_sub\">गुणवत्ता कमी न करता JXL ~ JPEG ट्रान्सकोडिंग करा किंवा GIF/APNG ते JXL ॲनिमेशनमध्ये रूपांतरित करा</string>\n    <string name=\"jxl_type_to_jpeg\">JXL ते JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL ते JPEG ला लॉसलेस ट्रान्सकोडिंग करा</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG ते JXL पर्यंत लॉसलेस ट्रान्सकोडिंग करा</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG ते JXL</string>\n    <string name=\"select_jxl_image_to_start\">सुरू करण्यासाठी JXL प्रतिमा निवडा</string>\n    <string name=\"fast_gaussian_blur_2d\">जलद गॉसियन ब्लर 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">जलद गॉसियन ब्लर 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">जलद गॉसियन ब्लर 4D</string>\n    <string name=\"auto_paste\">कार इस्टर</string>\n    <string name=\"auto_paste_sub\">ॲपला क्लिपबोर्ड डेटा स्वयं पेस्ट करण्याची अनुमती देते, त्यामुळे तो मुख्य स्क्रीनवर दिसेल आणि तुम्ही त्यावर प्रक्रिया करू शकाल</string>\n    <string name=\"harmonization_color\">सुसंवाद रंग</string>\n    <string name=\"harmonization_level\">सामंजस्य पातळी</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">पिक्सेल मूल्यांवर बेसल (जिंक) फंक्शन लागू करून उच्च-गुणवत्तेचे इंटरपोलेशन राखणारी रीसॅम्पलिंग पद्धत</string>\n    <string name=\"gif_type_to_jxl\">GIF ते JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF प्रतिमांना JXL ॲनिमेटेड चित्रांमध्ये रूपांतरित करा</string>\n    <string name=\"apng_type_to_jxl\">APNG ते JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG प्रतिमांना JXL ॲनिमेटेड चित्रांमध्ये रूपांतरित करा</string>\n    <string name=\"jxl_type_to_images\">JXL ते प्रतिमा</string>\n    <string name=\"jxl_type_to_images_sub\">JXL ॲनिमेशनला चित्रांच्या बॅचमध्ये रूपांतरित करा</string>\n    <string name=\"jxl_type_to_jxl\">JXL साठी प्रतिमा</string>\n    <string name=\"jxl_type_to_jxl_sub\">चित्रांच्या बॅचचे JXL ॲनिमेशनमध्ये रूपांतर करा</string>\n    <string name=\"behavior\">वागणूक</string>\n    <string name=\"skip_file_picking\">फाइल निवडणे वगळा</string>\n    <string name=\"skip_file_picking_sub\">निवडलेल्या स्क्रीनवर हे शक्य असल्यास फाइल पिकर त्वरित दर्शविला जाईल</string>\n    <string name=\"generate_previews\">पूर्वावलोकने व्युत्पन्न करा</string>\n    <string name=\"generate_previews_sub\">पूर्वावलोकन निर्मिती सक्षम करते, हे काही उपकरणांवर क्रॅश टाळण्यास मदत करू शकते, हे एकल संपादन पर्यायामध्ये काही संपादन कार्यक्षमता देखील अक्षम करते</string>\n    <string name=\"lossy_compression\">हानीकारक कॉम्प्रेशन</string>\n    <string name=\"lossy_compression_sub\">लॉसलेस ऐवजी फाईलचा आकार कमी करण्यासाठी हानीकारक कॉम्प्रेशन वापरते</string>\n    <string name=\"compression_type\">कॉम्प्रेशन प्रकार</string>\n    <string name=\"speed_sub\">परिणामी प्रतिमा डीकोडिंग गती नियंत्रित करते, यामुळे परिणामी प्रतिमा जलद उघडण्यास मदत होईल, %1$s चे मूल्य म्हणजे सर्वात धीमे डीकोडिंग, तर %2$s - सर्वात वेगवान, ही सेटिंग आउटपुट प्रतिमा आकार वाढवू शकते</string>\n    <string name=\"sorting\">वर्गीकरण</string>\n    <string name=\"sort_by_date\">तारीख</string>\n    <string name=\"sort_by_date_reversed\">तारीख (उलट)</string>\n    <string name=\"sort_by_name\">नाव</string>\n    <string name=\"sort_by_name_reversed\">नाव (उलट)</string>\n    <string name=\"channels_configuration\">चॅनेल कॉन्फिगरेशन</string>\n    <string name=\"header_today\">आज</string>\n    <string name=\"header_yesterday\">काल</string>\n    <string name=\"embedded_picker\">एम्बेडेड पिकर</string>\n    <string name=\"embedded_picker_sub\">इमेज टूलबॉक्सचा इमेज पिकर</string>\n    <string name=\"no_permissions\">परवानग्या नाहीत</string>\n    <string name=\"request\">विनंती</string>\n    <string name=\"pick_multiple_media\">एकाधिक मीडिया निवडा</string>\n    <string name=\"pick_single_media\">सिंगल मीडिया निवडा</string>\n    <string name=\"pick\">निवडा</string>\n    <string name=\"try_again\">पुन्हा प्रयत्न करा</string>\n    <string name=\"show_settings_in_landscape\">लँडस्केपमध्ये सेटिंग्ज दर्शवा</string>\n    <string name=\"show_settings_in_landscape_sub\">हे अक्षम केल्यास, कायमस्वरूपी दृश्यमान पर्यायाऐवजी, नेहमीप्रमाणे वरच्या ॲप बारमधील बटणावर लँडस्केप मोड सेटिंग्ज उघडतील.</string>\n    <string name=\"fullscreen_settings\">पूर्णस्क्रीन सेटिंग्ज</string>\n    <string name=\"fullscreen_settings_sub\">ते सक्षम करा आणि सेटिंग्ज पृष्ठ नेहमी स्लाइड करण्यायोग्य ड्रॉवर शीटऐवजी फुलस्क्रीन म्हणून उघडले जाईल</string>\n    <string name=\"switch_type\">स्विच प्रकार</string>\n    <string name=\"compose\">रचना करा</string>\n    <string name=\"compose_switch_sub\">तुम्ही स्विच करता ते जेटपॅक कंपोझ मटेरियल</string>\n    <string name=\"material_you_switch_sub\">एक मटेरिअल तुम्ही स्विच करता</string>\n    <string name=\"max\">कमाल</string>\n    <string name=\"resize_anchor\">अँकरचा आकार बदला</string>\n    <string name=\"pixel_switch\">पिक्सेल</string>\n    <string name=\"fluent_switch\">अस्खलित</string>\n    <string name=\"fluent_switch_sub\">\\\"फ्लुएंट\\\" डिझाइन प्रणालीवर आधारित स्विच</string>\n    <string name=\"cupertino_switch\">क्युपर्टिनो</string>\n    <string name=\"cupertino_switch_sub\">\\\"क्युपर्टिनो\\\" डिझाइन प्रणालीवर आधारित एक स्विच</string>\n    <string name=\"images_to_svg\">SVG साठी प्रतिमा</string>\n    <string name=\"images_to_svg_sub\">SVG प्रतिमांना दिलेल्या प्रतिमा ट्रेस करा</string>\n    <string name=\"use_sampled_palette\">नमुना पॅलेट वापरा</string>\n    <string name=\"use_sampled_palette_sub\">हा पर्याय सक्षम केल्यास क्वांटायझेशन पॅलेट नमुना केला जाईल</string>\n    <string name=\"path_omit\">मार्ग सोडून द्या</string>\n    <string name=\"svg_warning\">डाउनस्केलिंगशिवाय मोठ्या प्रतिमा ट्रेस करण्यासाठी या साधनाचा वापर करण्याची शिफारस केलेली नाही, यामुळे क्रॅश होऊ शकतो आणि प्रक्रियेचा वेळ वाढू शकतो.</string>\n    <string name=\"downscale_image\">डाउनस्केल प्रतिमा</string>\n    <string name=\"downscale_image_sub\">प्रक्रिया करण्यापूर्वी प्रतिमा कमी आकारात कमी केली जाईल, हे साधन जलद आणि सुरक्षित कार्य करण्यास मदत करते</string>\n    <string name=\"min_color_ratio\">किमान रंग गुणोत्तर</string>\n    <string name=\"lines_threshold\">लाईन्स थ्रेशोल्ड</string>\n    <string name=\"quadratic_threshold\">चतुर्भुज थ्रेशोल्ड</string>\n    <string name=\"coordinates_rounding_tolerance\">गोलाकार सहिष्णुता समन्वयित करते</string>\n    <string name=\"path_scale\">पथ स्केल</string>\n    <string name=\"reset_properties\">गुणधर्म रीसेट करा</string>\n    <string name=\"reset_properties_sub\">सर्व गुणधर्म डीफॉल्ट मूल्यांवर सेट केले जातील, लक्षात घ्या की ही क्रिया पूर्ववत केली जाऊ शकत नाही</string>\n    <string name=\"detailed\">तपशीलवार</string>\n    <string name=\"default_line_width\">डीफॉल्ट लाइन रुंदी</string>\n    <string name=\"engine_mode\">इंजिन मोड</string>\n    <string name=\"legacy\">वारसा</string>\n    <string name=\"lstm_network\">LSTM नेटवर्क</string>\n    <string name=\"legacy_and_lstm\">वारसा आणि LSTM</string>\n    <string name=\"convert\">रूपांतर करा</string>\n    <string name=\"convert_sub\">इमेज बॅचेस दिलेल्या फॉरमॅटमध्ये रूपांतरित करा</string>\n    <string name=\"add_new_folder\">नवीन फोल्डर जोडा</string>\n    <string name=\"tag_bits_per_sample\">प्रति नमुना बिट्स</string>\n    <string name=\"tag_compression\">संक्षेप</string>\n    <string name=\"tag_photometric_interpretation\">फोटोमेट्रिक व्याख्या</string>\n    <string name=\"tag_samples_per_pixel\">प्रति पिक्सेल नमुने</string>\n    <string name=\"tag_planar_configuration\">प्लॅनर कॉन्फिगरेशन</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr सब सॅम्पलिंग</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr पोझिशनिंग</string>\n    <string name=\"tag_x_resolution\">एक्स रिझोल्यूशन</string>\n    <string name=\"tag_y_resolution\">Y ठराव</string>\n    <string name=\"tag_resolution_unit\">रिझोल्यूशन युनिट</string>\n    <string name=\"tag_strip_offsets\">स्ट्रिप ऑफसेट्स</string>\n    <string name=\"tag_rows_per_strip\">पंक्ती प्रति पट्टी</string>\n    <string name=\"tag_strip_byte_counts\">स्ट्रिप बाइट संख्या</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG इंटरचेंज स्वरूप</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG इंटरचेंज फॉरमॅटची लांबी</string>\n    <string name=\"tag_transfer_function\">हस्तांतरण कार्य</string>\n    <string name=\"tag_white_point\">पांढरा बिंदू</string>\n    <string name=\"tag_primary_chromaticities\">प्राथमिक रंगसंगती</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr गुणांक</string>\n    <string name=\"tag_reference_black_white\">संदर्भ काळा पांढरा</string>\n    <string name=\"tag_datetime\">तारीख वेळ</string>\n    <string name=\"tag_image_description\">प्रतिमा वर्णन</string>\n    <string name=\"tag_make\">बनवा</string>\n    <string name=\"tag_model\">मॉडेल</string>\n    <string name=\"tag_software\">सॉफ्टवेअर</string>\n    <string name=\"tag_artist\">कलाकार</string>\n    <string name=\"tag_copyright\">कॉपीराइट</string>\n    <string name=\"tag_exif_version\">Exif आवृत्ती</string>\n    <string name=\"tag_flashpix_version\">फ्लॅशपिक्स आवृत्ती</string>\n    <string name=\"tag_color_space\">रंगीत जागा</string>\n    <string name=\"tag_gamma\">गामा</string>\n    <string name=\"tag_pixel_x_dimension\">पिक्सेल एक्स परिमाण</string>\n    <string name=\"tag_pixel_y_dimension\">पिक्सेल वाई परिमाण</string>\n    <string name=\"tag_compressed_bits_per_pixel\">संकुचित बिट्स प्रति पिक्सेल</string>\n    <string name=\"tag_maker_note\">मेकर नोट</string>\n    <string name=\"tag_user_comment\">वापरकर्ता टिप्पणी</string>\n    <string name=\"tag_related_sound_file\">संबंधित ध्वनी फाइल</string>\n    <string name=\"tag_datetime_original\">तारीख वेळ मूळ</string>\n    <string name=\"tag_datetime_digitized\">तारीख वेळ डिजिटाइझ केली</string>\n    <string name=\"tag_offset_time\">ऑफसेट वेळ</string>\n    <string name=\"tag_offset_time_original\">ऑफसेट वेळ मूळ</string>\n    <string name=\"tag_offset_time_digitized\">ऑफसेट टाईम डिजिटायझ्ड</string>\n    <string name=\"tag_subsec_time\">उप सेकंद वेळ</string>\n    <string name=\"tag_subsec_time_original\">उप सेकंद वेळ मूळ</string>\n    <string name=\"tag_subsec_time_digitized\">सब सेक टाइम डिजीटल</string>\n    <string name=\"tag_exposure_time\">उद्भासन वेळ</string>\n    <string name=\"tag_f_number\">F क्रमांक</string>\n    <string name=\"tag_exposure_program\">एक्सपोजर कार्यक्रम</string>\n    <string name=\"tag_spectral_sensitivity\">वर्णक्रमीय संवेदनशीलता</string>\n    <string name=\"tag_photographic_sensitivity\">फोटोग्राफिक संवेदनशीलता</string>\n    <string name=\"tag_oecf\">ओईसीएफ</string>\n    <string name=\"tag_sensitivity_type\">संवेदनशीलता प्रकार</string>\n    <string name=\"tag_standard_output_sensitivity\">मानक आउटपुट संवेदनशीलता</string>\n    <string name=\"tag_recommended_exposure_index\">शिफारस केलेले एक्सपोजर इंडेक्स</string>\n    <string name=\"tag_iso_speed\">ISO गती</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO गती अक्षांश yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO स्पीड अक्षांश zzz</string>\n    <string name=\"tag_shutter_speed_value\">शटर गती मूल्य</string>\n    <string name=\"tag_aperture_value\">छिद्र मूल्य</string>\n    <string name=\"tag_brightness_value\">ब्राइटनेस मूल्य</string>\n    <string name=\"tag_exposure_bias_value\">एक्सपोजर बायस मूल्य</string>\n    <string name=\"tag_max_aperture_value\">कमाल छिद्र मूल्य</string>\n    <string name=\"tag_subject_distance\">विषय अंतर</string>\n    <string name=\"tag_metering_mode\">मीटरिंग मोड</string>\n    <string name=\"tag_flash\">फ्लॅश</string>\n    <string name=\"tag_subject_area\">विषय क्षेत्र</string>\n    <string name=\"tag_focal_length\">फोकल लांबी</string>\n    <string name=\"tag_flash_energy\">फ्लॅश एनर्जी</string>\n    <string name=\"tag_spatial_frequency_response\">अवकाशीय वारंवारता प्रतिसाद</string>\n    <string name=\"tag_focal_plane_x_resolution\">फोकल प्लेन एक्स रिझोल्यूशन</string>\n    <string name=\"tag_focal_plane_y_resolution\">फोकल प्लेन वाई रिझोल्यूशन</string>\n    <string name=\"tag_focal_plane_resolution_unit\">फोकल प्लेन रिझोल्यूशन युनिट</string>\n    <string name=\"tag_subject_location\">विषय स्थान</string>\n    <string name=\"tag_exposure_index\">एक्सपोजर इंडेक्स</string>\n    <string name=\"tag_sensing_method\">सेन्सिंग पद्धत</string>\n    <string name=\"tag_file_source\">फाइल स्रोत</string>\n    <string name=\"tag_cfa_pattern\">CFA नमुना</string>\n    <string name=\"tag_custom_rendered\">सानुकूल प्रस्तुत</string>\n    <string name=\"tag_exposure_mode\">एक्सपोजर मोड</string>\n    <string name=\"tag_white_balance\">पांढरा शिल्लक</string>\n    <string name=\"tag_digital_zoom_ratio\">डिजिटल झूम प्रमाण</string>\n    <string name=\"tag_focal_length_in_35mm_film\">फोकल लांबी In35mm फिल्म</string>\n    <string name=\"tag_scene_capture_type\">दृश्य कॅप्चर प्रकार</string>\n    <string name=\"tag_gain_control\">नियंत्रण मिळवा</string>\n    <string name=\"tag_contrast\">कॉन्ट्रास्ट</string>\n    <string name=\"tag_saturation\">संपृक्तता</string>\n    <string name=\"tag_sharpness\">तीक्ष्णपणा</string>\n    <string name=\"tag_device_setting_description\">डिव्हाइस सेटिंग वर्णन</string>\n    <string name=\"tag_subject_distance_range\">विषय अंतर श्रेणी</string>\n    <string name=\"tag_image_unique_id\">प्रतिमा अद्वितीय आयडी</string>\n    <string name=\"tag_camera_owner_name\">कॅमेरा मालकाचे नाव</string>\n    <string name=\"tag_body_serial_number\">मुख्य भाग अनुक्रमांक</string>\n    <string name=\"tag_lens_specification\">लेन्स तपशील</string>\n    <string name=\"tag_lens_make\">लेन्स बनवा</string>\n    <string name=\"tag_lens_model\">लेन्स मॉडेल</string>\n    <string name=\"tag_lens_serial_number\">लेन्स अनुक्रमांक</string>\n    <string name=\"tag_gps_version_id\">GPS आवृत्ती आयडी</string>\n    <string name=\"tag_gps_latitude_ref\">GPS अक्षांश संदर्भ</string>\n    <string name=\"tag_gps_latitude\">GPS अक्षांश</string>\n    <string name=\"tag_gps_longitude_ref\">GPS रेखांश संदर्भ</string>\n    <string name=\"tag_gps_longitude\">GPS रेखांश</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Altitude Ref</string>\n    <string name=\"tag_gps_altitude\">जीपीएस उंची</string>\n    <string name=\"tag_gps_timestamp\">जीपीएस टाइम स्टॅम्प</string>\n    <string name=\"tag_gps_satellites\">GPS उपग्रह</string>\n    <string name=\"tag_gps_status\">जीपीएस स्थिती</string>\n    <string name=\"tag_gps_measure_mode\">GPS मापन मोड</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS गती संदर्भ</string>\n    <string name=\"tag_gps_speed\">GPS गती</string>\n    <string name=\"tag_gps_track_ref\">GPS ट्रॅक संदर्भ</string>\n    <string name=\"tag_gps_track\">जीपीएस ट्रॅक</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img दिशा रेफ</string>\n    <string name=\"tag_gps_img_direction\">GPS Img दिशा</string>\n    <string name=\"tag_gps_map_datum\">जीपीएस नकाशा डेटाम</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS डेस्ट अक्षांश</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS डेस्ट रेखांश संदर्भ</string>\n    <string name=\"tag_gps_dest_longitude\">GPS गंतव्य रेखांश</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS डेस्ट बेअरिंग रेफ</string>\n    <string name=\"tag_gps_dest_bearing\">GPS डेस्ट बेअरिंग</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS गंतव्य अंतर</string>\n    <string name=\"tag_gps_processing_method\">जीपीएस प्रक्रिया पद्धत</string>\n    <string name=\"tag_gps_area_information\">जीपीएस क्षेत्र माहिती</string>\n    <string name=\"tag_gps_datestamp\">जीपीएस तारीख स्टॅम्प</string>\n    <string name=\"tag_gps_differential\">जीपीएस भिन्नता</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H पोझिशनिंग एरर</string>\n    <string name=\"tag_interoperability_index\">इंटरऑपरेबिलिटी इंडेक्स</string>\n    <string name=\"tag_dng_version\">DNG आवृत्ती</string>\n    <string name=\"tag_default_crop_size\">डीफॉल्ट क्रॉप आकार</string>\n    <string name=\"tag_orf_preview_image_start\">पूर्वावलोकन प्रतिमा प्रारंभ</string>\n    <string name=\"tag_orf_preview_image_length\">पूर्वावलोकन प्रतिमा लांबी</string>\n    <string name=\"tag_orf_aspect_frame\">आस्पेक्ट फ्रेम</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">सेन्सर तळाची सीमा</string>\n    <string name=\"tag_rw2_sensor_left_border\">सेन्सर डावी सीमा</string>\n    <string name=\"tag_rw2_sensor_right_border\">सेन्सर उजवी सीमा</string>\n    <string name=\"tag_rw2_sensor_top_border\">सेन्सर शीर्ष सीमा</string>\n    <string name=\"tag_rw2_iso\">आयएसओ</string>\n    <string name=\"draw_text_sub\">दिलेल्या फॉन्ट आणि रंगाने पथावर मजकूर काढा</string>\n    <string name=\"font_size\">फॉन्ट आकार</string>\n    <string name=\"watermark_size\">वॉटरमार्क आकार</string>\n    <string name=\"repeat_text\">मजकूर पुन्हा करा</string>\n    <string name=\"repeat_text_sub\">एक वेळ काढण्याऐवजी पाथ संपेपर्यंत वर्तमान मजकूराची पुनरावृत्ती केली जाईल</string>\n    <string name=\"dash_size\">डॅश आकार</string>\n    <string name=\"draw_mode_image_sub\">दिलेल्या मार्गावर ती काढण्यासाठी निवडलेली प्रतिमा वापरा</string>\n    <string name=\"draw_image_sub\">ही प्रतिमा काढलेल्या मार्गाची पुनरावृत्ती एंट्री म्हणून वापरली जाईल</string>\n    <string name=\"outlined_triangle_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत बाह्यरेखित त्रिकोण काढतो</string>\n    <string name=\"triangle_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत बाह्यरेखित त्रिकोण काढतो</string>\n    <string name=\"outlined_triangle\">बाह्यरेखित त्रिकोण</string>\n    <string name=\"triangle\">त्रिकोण</string>\n    <string name=\"polygon_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत बहुभुज काढतो</string>\n    <string name=\"polygon\">बहुभुज</string>\n    <string name=\"outlined_polygon\">बाह्यरेखित बहुभुज</string>\n    <string name=\"outlined_polygon_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत बाह्यरेखित बहुभुज काढतो</string>\n    <string name=\"vertices\">शिरोबिंदू</string>\n    <string name=\"draw_regular_polygon\">नियमित बहुभुज काढा</string>\n    <string name=\"draw_regular_polygon_sub\">बहुभुज काढा जो फ्री फॉर्म ऐवजी नियमित असेल</string>\n    <string name=\"star_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत तारा काढतो</string>\n    <string name=\"star\">तारा</string>\n    <string name=\"outlined_star\">आराखडा तारा</string>\n    <string name=\"outlined_star_sub\">प्रारंभ बिंदूपासून शेवटच्या बिंदूपर्यंत बाह्यरेखित तारा काढतो</string>\n    <string name=\"inner_radius_ratio\">आतील त्रिज्या प्रमाण</string>\n    <string name=\"draw_regular_star\">नियमित तारा काढा</string>\n    <string name=\"draw_regular_star_sub\">तारा काढा जो फ्री फॉर्म ऐवजी नियमित असेल</string>\n    <string name=\"antialias\">अँटिलियास</string>\n    <string name=\"antialias_sub\">तीक्ष्ण कडा रोखण्यासाठी अँटिलायझिंग सक्षम करते</string>\n    <string name=\"open_edit_instead_of_preview\">पूर्वावलोकनाऐवजी संपादन उघडा</string>\n    <string name=\"open_edit_instead_of_preview_sub\">जेव्हा तुम्ही ImageToolbox मध्ये उघडण्यासाठी (पूर्वावलोकन) प्रतिमा निवडता, तेव्हा पूर्वावलोकन करण्याऐवजी संपादन निवड पत्रक उघडले जाईल</string>\n    <string name=\"document_scanner\">दस्तऐवज स्कॅनर</string>\n    <string name=\"document_scanner_sub\">दस्तऐवज स्कॅन करा आणि त्यांच्यापासून PDF किंवा वेगळ्या प्रतिमा तयार करा</string>\n    <string name=\"click_to_start_scanning\">स्कॅनिंग सुरू करण्यासाठी क्लिक करा</string>\n    <string name=\"start_scanning\">स्कॅनिंग सुरू करा</string>\n    <string name=\"save_as_pdf\">पीडीएफ म्हणून सेव्ह करा</string>\n    <string name=\"share_as_pdf\">पीडीएफ म्हणून शेअर करा</string>\n    <string name=\"options_below_is_for_images\">खालील पर्याय प्रतिमा जतन करण्यासाठी आहेत, PDF नाही</string>\n    <string name=\"equalize_histogram_hsv\">हिस्टोग्राम HSV समान करा</string>\n    <string name=\"equalize_histogram\">हिस्टोग्राम समान करा</string>\n    <string name=\"enter_percentage\">टक्केवारी प्रविष्ट करा</string>\n    <string name=\"allow_enter_by_text_field\">मजकूर फील्डद्वारे प्रविष्ट करण्यास अनुमती द्या</string>\n    <string name=\"allow_enter_by_text_field_sub\">प्रीसेट निवडीच्या मागे मजकूर फील्ड सक्षम करते, त्यांना फ्लायवर प्रविष्ट करण्यासाठी</string>\n    <string name=\"scale_color_space\">स्केल कलर स्पेस</string>\n    <string name=\"linear\">रेखीय</string>\n    <string name=\"equalize_histogram_pixelation\">हिस्टोग्राम पिक्सेलेशन समान करा</string>\n    <string name=\"grid_size_x\">ग्रिड आकार X</string>\n    <string name=\"grid_size_y\">ग्रिड आकार Y</string>\n    <string name=\"equalize_histogram_adaptive\">हिस्टोग्राम अनुकूली समान करा</string>\n    <string name=\"equalize_histogram_adaptive_luv\">हिस्टोग्राम अडॅप्टिव्ह LUV समान करा</string>\n    <string name=\"equalize_histogram_adaptive_lab\">हिस्टोग्राम ॲडॉप्टिव्ह LAB समान करा</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE लॅब</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">सामग्रीसाठी क्रॉप करा</string>\n    <string name=\"frame_color\">फ्रेम रंग</string>\n    <string name=\"color_to_ignore\">दुर्लक्ष करण्यासाठी रंग</string>\n    <string name=\"template\">साचा</string>\n    <string name=\"no_template_filters\">कोणतेही टेम्पलेट फिल्टर जोडलेले नाहीत</string>\n    <string name=\"create_new\">नवीन तयार करा</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">स्कॅन केलेला QR कोड वैध फिल्टर टेम्पलेट नाही</string>\n    <string name=\"scan_qr_code\">QR कोड स्कॅन करा</string>\n    <string name=\"opened_file_have_no_filter_template\">निवडलेल्या फाइलमध्ये फिल्टर टेम्पलेट डेटा नाही</string>\n    <string name=\"create_template\">टेम्पलेट तयार करा</string>\n    <string name=\"template_name\">टेम्पलेट नाव</string>\n    <string name=\"select_template_preview\">ही प्रतिमा या फिल्टर टेम्पलेटचे पूर्वावलोकन करण्यासाठी वापरली जाईल</string>\n    <string name=\"template_filter\">टेम्पलेट फिल्टर</string>\n    <string name=\"as_qr_code\">QR कोड प्रतिमा म्हणून</string>\n    <string name=\"as_file\">फाइल म्हणून</string>\n    <string name=\"save_as_file\">फाइल म्हणून सेव्ह करा</string>\n    <string name=\"save_as_qr_code_image\">QR कोड प्रतिमा म्हणून जतन करा</string>\n    <string name=\"delete_template\">टेम्पलेट हटवा</string>\n    <string name=\"delete_template_warn\">तुम्ही निवडलेले टेम्पलेट फिल्टर हटवणार आहात. हे ऑपरेशन पूर्ववत केले जाऊ शकत नाही</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) नावासह फिल्टर टेम्पलेट जोडले</string>\n    <string name=\"filter_preview\">फिल्टर पूर्वावलोकन</string>\n    <string name=\"qr_code\">QR आणि बारकोड</string>\n    <string name=\"qr_code_sub\">QR कोड स्कॅन करा आणि त्याची सामग्री मिळवा किंवा नवीन तयार करण्यासाठी तुमची स्ट्रिंग पेस्ट करा</string>\n    <string name=\"code_content\">कोड सामग्री</string>\n    <string name=\"scan_qr_code_to_replace_content\">फील्डमधील सामग्री बदलण्यासाठी कोणताही बारकोड स्कॅन करा किंवा निवडलेल्या प्रकारासह नवीन बारकोड तयार करण्यासाठी काहीतरी टाइप करा</string>\n    <string name=\"qr_description\">QR वर्णन</string>\n    <string name=\"min\">मि</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR कोड स्कॅन करण्यासाठी सेटिंग्जमध्ये कॅमेरा परवानगी द्या</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">दस्तऐवज स्कॅनर स्कॅन करण्यासाठी सेटिंग्जमध्ये कॅमेरा परवानगी द्या</string>\n    <string name=\"cubic\">घन</string>\n    <string name=\"bspline\">बी-स्प्लाइन</string>\n    <string name=\"hamming\">हॅमिंग</string>\n    <string name=\"hanning\">हॅनिंग</string>\n    <string name=\"blackman\">ब्लॅकमन</string>\n    <string name=\"welch\">वेल्च</string>\n    <string name=\"quadric\">चौकोन</string>\n    <string name=\"gaussian\">गॉसियन</string>\n    <string name=\"sphinx\">स्फिंक्स</string>\n    <string name=\"bartlett\">बार्टलेट</string>\n    <string name=\"robidoux\">रॉबिडॉक्स</string>\n    <string name=\"robidoux_sharp\">रॉबिडॉक्स शार्प</string>\n    <string name=\"spline16\">स्प्लाइन 16</string>\n    <string name=\"spline36\">स्प्लाइन 36</string>\n    <string name=\"spline64\">स्प्लाइन 64</string>\n    <string name=\"kaiser\">कैसर</string>\n    <string name=\"bartlett_hann\">बार्टलेट-हे</string>\n    <string name=\"box\">पेटी</string>\n    <string name=\"bohman\">बोहमन</string>\n    <string name=\"lanczos2\">लॅन्झोस २</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">लॅन्झोस ४</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">क्यूबिक इंटरपोलेशन सर्वात जवळच्या 16 पिक्सेलचा विचार करून नितळ स्केलिंग प्रदान करते, द्विरेखीय पेक्षा चांगले परिणाम देते</string>\n    <string name=\"bspline_sub\">वक्र किंवा पृष्ठभाग, लवचिक आणि सतत आकाराचे प्रतिनिधित्व सहजतेने इंटरपोलेट करण्यासाठी आणि अंदाजे करण्यासाठी तुकडावार-परिभाषित बहुपदीय कार्ये वापरते</string>\n    <string name=\"hamming_sub\">सिग्नलच्या कडांना निमुळता करून वर्णक्रमीय गळती कमी करण्यासाठी वापरलेले विंडो फंक्शन, सिग्नल प्रक्रियेत उपयुक्त</string>\n    <string name=\"hanning_sub\">हॅन विंडोचा एक प्रकार, सामान्यतः सिग्नल प्रोसेसिंग ऍप्लिकेशन्समध्ये वर्णक्रमीय गळती कमी करण्यासाठी वापरला जातो</string>\n    <string name=\"blackman_sub\">एक विंडो फंक्शन जे स्पेक्ट्रल गळती कमी करून चांगले वारंवारता रिझोल्यूशन प्रदान करते, बहुतेकदा सिग्नल प्रक्रियेत वापरले जाते</string>\n    <string name=\"welch_sub\">कमी स्पेक्ट्रल गळतीसह चांगले वारंवारता रिझोल्यूशन देण्यासाठी डिझाइन केलेले विंडो फंक्शन, अनेकदा सिग्नल प्रोसेसिंग ऍप्लिकेशनमध्ये वापरले जाते</string>\n    <string name=\"quadric_sub\">गुळगुळीत आणि सतत परिणाम प्रदान करून प्रक्षेपणासाठी चतुर्भुज कार्य वापरणारी पद्धत</string>\n    <string name=\"gaussian_sub\">एक इंटरपोलेशन पद्धत जी गॉसियन फंक्शन लागू करते, प्रतिमा गुळगुळीत करण्यासाठी आणि आवाज कमी करण्यासाठी उपयुक्त</string>\n    <string name=\"sphinx_sub\">कमीत कमी कलाकृतींसह उच्च-गुणवत्तेचे इंटरपोलेशन प्रदान करणारी प्रगत पुनर्नमुने करण्याची पद्धत</string>\n    <string name=\"bartlett_sub\">स्पेक्ट्रल गळती कमी करण्यासाठी सिग्नल प्रक्रियेमध्ये वापरलेले त्रिकोणी विंडो कार्य</string>\n    <string name=\"robidoux_sub\">नैसर्गिक प्रतिमेचा आकार बदलण्यासाठी, तीक्ष्णता आणि गुळगुळीतपणा संतुलित करण्यासाठी ऑप्टिमाइझ केलेली उच्च-गुणवत्तेची इंटरपोलेशन पद्धत</string>\n    <string name=\"robidoux_sharp_sub\">रॉबिडॉक्स पद्धतीचा एक तीक्ष्ण प्रकार, कुरकुरीत प्रतिमा आकार बदलण्यासाठी अनुकूल</string>\n    <string name=\"spline16_sub\">एक स्प्लाइन-आधारित इंटरपोलेशन पद्धत जी 16-टॅप फिल्टर वापरून गुळगुळीत परिणाम प्रदान करते</string>\n    <string name=\"spline36_sub\">एक स्प्लाइन-आधारित इंटरपोलेशन पद्धत जी 36-टॅप फिल्टर वापरून गुळगुळीत परिणाम प्रदान करते</string>\n    <string name=\"spline64_sub\">एक स्प्लाइन-आधारित इंटरपोलेशन पद्धत जी 64-टॅप फिल्टर वापरून गुळगुळीत परिणाम प्रदान करते</string>\n    <string name=\"kaiser_sub\">एक इंटरपोलेशन पद्धत जी कैसर विंडो वापरते, मुख्य-लोब रुंदी आणि साइड-लोब लेव्हलमधील ट्रेड-ऑफवर चांगले नियंत्रण प्रदान करते.</string>\n    <string name=\"bartlett_hann_sub\">बार्टलेट आणि हॅन विंडो एकत्र करणारे एक संकरित विंडो फंक्शन, सिग्नल प्रक्रियेत वर्णक्रमीय गळती कमी करण्यासाठी वापरले जाते</string>\n    <string name=\"box_sub\">नजीकच्या पिक्सेल मूल्यांची सरासरी वापरणारी एक साधी पुनर्नमुना पद्धत, अनेकदा ब्लॉकी दिसणे</string>\n    <string name=\"bohman_sub\">स्पेक्ट्रल गळती कमी करण्यासाठी वापरलेले विंडो फंक्शन, सिग्नल प्रोसेसिंग ऍप्लिकेशन्समध्ये चांगले वारंवारता रिझोल्यूशन प्रदान करते</string>\n    <string name=\"lanczos2_sub\">किमान कलाकृतींसह उच्च-गुणवत्तेच्या इंटरपोलेशनसाठी 2-लोब लँकझोस फिल्टर वापरणारी पुनर्नमुना पद्धत</string>\n    <string name=\"lanczos3_sub\">किमान कलाकृतींसह उच्च-गुणवत्तेच्या इंटरपोलेशनसाठी 3-लोब लॅन्झोस फिल्टर वापरणारी पुनर्नमुना पद्धत</string>\n    <string name=\"lanczos4_sub\">किमान कलाकृतींसह उच्च-गुणवत्तेच्या इंटरपोलेशनसाठी 4-लोब लँकझोस फिल्टर वापरणारी पुनर्नमुना पद्धत</string>\n    <string name=\"lanczos2_jinc_sub\">Lanczos 2 फिल्टरचा एक प्रकार जो जिंक फंक्शन वापरतो, कमीत कमी कलाकृतींसह उच्च-गुणवत्तेचा इंटरपोलेशन प्रदान करतो</string>\n    <string name=\"lanczos3_jinc_sub\">Lanczos 3 फिल्टरचा एक प्रकार जो जिंक फंक्शन वापरतो, कमीत कमी कलाकृतींसह उच्च-गुणवत्तेचा इंटरपोलेशन प्रदान करतो</string>\n    <string name=\"lanczos4_jinc_sub\">Lanczos 4 फिल्टरचा एक प्रकार जो झिंक फंक्शन वापरतो, कमीत कमी कलाकृतींसह उच्च-गुणवत्तेचा इंटरपोलेशन प्रदान करतो</string>\n    <string name=\"ewa_hanning\">हॅनिंग EWA</string>\n    <string name=\"ewa_hanning_sub\">गुळगुळीत इंटरपोलेशन आणि रीसॅम्पलिंगसाठी हॅनिंग फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">उच्च-गुणवत्तेच्या पुनर्नमुनाकरणासाठी रॉबिडॉक्स फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_blackman\">ब्लॅकमन इव्ह</string>\n    <string name=\"ewa_blackman_sub\">रिंगिंग आर्टिफॅक्ट्स कमी करण्यासाठी ब्लॅकमॅन फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_quadric\">क्वाड्रिक EWA</string>\n    <string name=\"ewa_quadric_sub\">गुळगुळीत इंटरपोलेशनसाठी क्वाड्रिक फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux शार्प EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">तीव्र परिणामांसाठी रॉबिडॉक्स शार्प फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">कमी अलियासिंगसह उच्च-गुणवत्तेच्या रिसॅम्पलिंगसाठी Lanczos 3 Jinc फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ginseng\">जिनसेंग</string>\n    <string name=\"ginseng_sub\">तीक्ष्णता आणि गुळगुळीतपणाच्या चांगल्या संतुलनासह उच्च-गुणवत्तेच्या प्रतिमा प्रक्रियेसाठी डिझाइन केलेले पुनर्नमुना फिल्टर</string>\n    <string name=\"ewa_ginseng\">जिनसेंग EWA</string>\n    <string name=\"ewa_ginseng_sub\">वर्धित प्रतिमेच्या गुणवत्तेसाठी जिनसेंग फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos शार्प EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">कमीत कमी कलाकृतींसह तीव्र परिणाम प्राप्त करण्यासाठी लँकझोस शार्प फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 शार्पेस्ट EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">अत्यंत तीक्ष्ण इमेज रिसॅम्पलिंगसाठी लँकझोस 4 शार्पेस्ट फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos सॉफ्ट EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">स्मूथ इमेज रिसॅम्पलिंगसाठी लँकझोस सॉफ्ट फिल्टरचे लंबवर्तुळ भारित सरासरी (EWA) प्रकार</string>\n    <string name=\"haasn_soft\">हसन सॉफ्ट</string>\n    <string name=\"haasn_soft_sub\">गुळगुळीत आणि आर्टिफॅक्ट-मुक्त प्रतिमा स्केलिंगसाठी हसनने डिझाइन केलेले पुनर्नमुना फिल्टर</string>\n    <string name=\"format_conversion\">स्वरूप रूपांतरण</string>\n    <string name=\"format_conversion_sub\">प्रतिमांचा बॅच एका फॉरमॅटमधून दुसऱ्या फॉरमॅटमध्ये रूपांतरित करा</string>\n    <string name=\"dismiss_forever\">कायमचे डिसमिस करा</string>\n    <string name=\"image_stacking\">प्रतिमा स्टॅकिंग</string>\n    <string name=\"image_stacking_sub\">निवडलेल्या मिश्रण मोडसह प्रतिमा एकमेकांच्या वर स्टॅक करा</string>\n    <string name=\"add_image\">प्रतिमा जोडा</string>\n    <string name=\"bins_count\">डब्यांची संख्या</string>\n    <string name=\"clahe_hsl\">क्ले एचएसएल</string>\n    <string name=\"clahe_hsv\">क्ले एचएसव्ही</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">हिस्टोग्राम अडॅप्टिव्ह HSL समान करा</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">हिस्टोग्राम अनुकूली HSV समान करा</string>\n    <string name=\"edge_mode\">एज मोड</string>\n    <string name=\"clip\">क्लिप</string>\n    <string name=\"wrap\">गुंडाळणे</string>\n    <string name=\"color_blind_scheme\">रंग अंधत्व</string>\n    <string name=\"color_blind_scheme_sub\">निवडलेल्या रंग अंधत्व प्रकारासाठी थीम रंग जुळवून घेण्यासाठी मोड निवडा</string>\n    <string name=\"protanomaly_sub\">लाल आणि हिरव्या रंगांमध्ये फरक करण्यात अडचण</string>\n    <string name=\"deuteranomaly_sub\">हिरव्या आणि लाल रंगांमध्ये फरक करण्यात अडचण</string>\n    <string name=\"tritanomaly_sub\">निळ्या आणि पिवळ्या रंगांमध्ये फरक करण्यात अडचण</string>\n    <string name=\"protanopia_sub\">लाल रंगाची छटा समजण्यास असमर्थता</string>\n    <string name=\"deuteranopia_sub\">हिरव्या रंगाची छटा ओळखण्यास असमर्थता</string>\n    <string name=\"tritanopia_sub\">निळ्या रंगाची छटा समजण्यास असमर्थता</string>\n    <string name=\"achromatomaly_sub\">सर्व रंगांसाठी कमी संवेदनशीलता</string>\n    <string name=\"achromatopsia_sub\">पूर्ण रंग अंधत्व, फक्त राखाडी छटा पाहणे</string>\n    <string name=\"not_use_color_blind_scheme\">कलर ब्लाइंड स्कीम वापरू नका</string>\n    <string name=\"not_use_color_blind_scheme_sub\">थीममध्ये सेट केल्याप्रमाणे रंग अचूक असतील</string>\n    <string name=\"sigmoidal\">सिग्मॉइडल</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">ऑर्डर 2 चा लॅग्रेंज इंटरपोलेशन फिल्टर, गुळगुळीत संक्रमणांसह उच्च-गुणवत्तेच्या प्रतिमा स्केलिंगसाठी योग्य</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">ऑर्डर 3 चा लॅग्रेंज इंटरपोलेशन फिल्टर, इमेज स्केलिंगसाठी अधिक अचूकता आणि नितळ परिणाम देते</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">6 च्या उच्च ऑर्डरसह एक Lanczos रीसॅम्पलिंग फिल्टर, तीक्ष्ण आणि अधिक अचूक प्रतिमा स्केलिंग प्रदान करते</string>\n    <string name=\"lanczos_6_jinc_sub\">सुधारित इमेज रिसॅम्पलिंग गुणवत्तेसाठी जिन फंक्शन वापरून लॅन्झोस 6 फिल्टरचा एक प्रकार</string>\n    <string name=\"linear_box_blur\">लिनियर बॉक्स ब्लर</string>\n    <string name=\"linear_tent_blur\">रेखीय तंबू अस्पष्ट</string>\n    <string name=\"linear_gaussian_box_blur\">रेखीय गॉसियन बॉक्स ब्लर</string>\n    <string name=\"linear_stack_blur\">रेखीय स्टॅक ब्लर</string>\n    <string name=\"gaussian_box_blur\">गॉसियन बॉक्स ब्लर</string>\n    <string name=\"linear_fast_gaussian_blur_next\">लीनियर फास्ट गॉसियन ब्लर पुढे</string>\n    <string name=\"linear_fast_gaussian_blur\">लीनियर फास्ट गॉसियन ब्लर</string>\n    <string name=\"linear_gaussian_blur\">रेखीय गॉसियन ब्लर</string>\n    <string name=\"draw_filter_sub\">पेंट म्हणून वापरण्यासाठी एक फिल्टर निवडा</string>\n    <string name=\"replace_filter\">फिल्टर बदला</string>\n    <string name=\"pick_filter_info\">तुमच्या ड्रॉईंगमध्ये ब्रश म्हणून वापरण्यासाठी खालील फिल्टर निवडा</string>\n    <string name=\"tiff_compression_scheme\">TIFF कॉम्प्रेशन योजना</string>\n    <string name=\"low_poly\">कमी पॉली</string>\n    <string name=\"sand_painting\">वाळू चित्रकला</string>\n    <string name=\"image_splitting\">प्रतिमा विभाजन</string>\n    <string name=\"image_splitting_sub\">पंक्ती किंवा स्तंभांद्वारे एकल प्रतिमा विभाजित करा</string>\n    <string name=\"fit_to_bounds\">सीमेवर फिट</string>\n    <string name=\"fit_to_bounds_sub\">इच्छित वर्तन साध्य करण्यासाठी या पॅरामीटरसह क्रॉप रिसाइज मोड एकत्र करा (क्रॉप/फिट टू ॲस्पेक्ट रेशो)</string>\n    <string name=\"languages_imported\">भाषा यशस्वीरित्या आयात केल्या</string>\n    <string name=\"backup_ocr_models\">OCR मॉडेल्सचा बॅकअप घ्या</string>\n    <string name=\"import_word\">आयात करा</string>\n    <string name=\"export\">निर्यात करा</string>\n    <string name=\"position\">स्थिती</string>\n    <string name=\"center\">केंद्र</string>\n    <string name=\"top_left\">वर डावीकडे</string>\n    <string name=\"top_right\">वर उजवीकडे</string>\n    <string name=\"bottom_left\">तळ डावीकडे</string>\n    <string name=\"bottom_right\">तळ उजवीकडे</string>\n    <string name=\"top_center\">शीर्ष केंद्र</string>\n    <string name=\"center_right\">मध्यभागी उजवीकडे</string>\n    <string name=\"bottom_center\">तळ केंद्र</string>\n    <string name=\"center_left\">मध्यभागी डावीकडे</string>\n    <string name=\"target_image\">लक्ष्य प्रतिमा</string>\n    <string name=\"palette_transfer\">पॅलेट हस्तांतरण</string>\n    <string name=\"enhanced_oil\">वर्धित तेल</string>\n    <string name=\"simple_old_tv\">साधा जुना टीव्ही</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">गोथम</string>\n    <string name=\"simple_sketch\">साधे स्केच</string>\n    <string name=\"soft_glow\">मऊ चमक</string>\n    <string name=\"color_poster\">रंगीत पोस्टर</string>\n    <string name=\"tri_tone\">ट्राय टोन</string>\n    <string name=\"third_color\">तिसरा रंग</string>\n    <string name=\"clahe_oklab\">क्ले ओकलाब</string>\n    <string name=\"clahe_oklch\">क्लारा ओल्च</string>\n    <string name=\"clahe_jzazbz\">क्ले ज्जाज्ब्ज</string>\n    <string name=\"polka_dot\">पोल्का डॉट</string>\n    <string name=\"clustered_2x2_dithering\">क्लस्टर केलेले 2x2 डिथरिंग</string>\n    <string name=\"clustered_4x4_dithering\">क्लस्टर केलेले 4x4 डिथरिंग</string>\n    <string name=\"clustered_8x8_dithering\">क्लस्टर केलेले 8x8 डिथरिंग</string>\n    <string name=\"yililoma_dithering\">यिलीलोमा डिथरिंग</string>\n    <string name=\"no_favorite_options_selected\">कोणतेही आवडते पर्याय निवडलेले नाहीत, त्यांना टूल पेजमध्ये जोडा</string>\n    <string name=\"add_favorites\">आवडी जोडा</string>\n    <string name=\"harmony_complementary\">पूरक</string>\n    <string name=\"harmony_analogous\">समानार्थी</string>\n    <string name=\"harmony_triadic\">ट्रायडिक</string>\n    <string name=\"harmony_split_complementary\">स्प्लिट पूरक</string>\n    <string name=\"harmony_tetradic\">टेट्राडिक</string>\n    <string name=\"harmony_square\">चौरस</string>\n    <string name=\"harmony_analogous_complementary\">समान + पूरक</string>\n    <string name=\"color_tools\">रंग साधने</string>\n    <string name=\"color_tools_sub\">मिक्स करा, टोन बनवा, शेड्स तयार करा आणि बरेच काही</string>\n    <string name=\"color_harmonies\">रंगसंगती</string>\n    <string name=\"color_shading\">कलर शेडिंग</string>\n    <string name=\"variation\">तफावत</string>\n    <string name=\"tints\">टिंट्स</string>\n    <string name=\"tones\">स्वर</string>\n    <string name=\"shades\">छटा</string>\n    <string name=\"color_mixing\">रंग मिक्सिंग</string>\n    <string name=\"color_info\">रंग माहिती</string>\n    <string name=\"selected_color\">निवडलेला रंग</string>\n    <string name=\"color_to_mix\">मिक्स करण्यासाठी रंग</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">डायनॅमिक रंग चालू असताना मोनेट वापरू शकत नाही</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">लक्ष्य LUT प्रतिमा</string>\n    <string name=\"amatorka\">एक हौशी</string>\n    <string name=\"miss_etikate\">मिस शिष्टाचार</string>\n    <string name=\"soft_elegance\">मऊ अभिजात</string>\n    <string name=\"soft_elegance_variant\">सॉफ्ट एलिगन्स व्हेरिएंट</string>\n    <string name=\"palette_transfer_variant\">पॅलेट हस्तांतरण प्रकार</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">लक्ष्य 3D LUT फाइल (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">ब्लीच बायपास</string>\n    <string name=\"candlelight\">मेणबत्ती</string>\n    <string name=\"drop_blues\">ब्लूज ड्रॉप करा</string>\n    <string name=\"edgy_amber\">कडक अंबर</string>\n    <string name=\"fall_colors\">फॉल कलर्स</string>\n    <string name=\"film_stock_50\">फिल्म स्टॉक 50</string>\n    <string name=\"foggy_night\">धुक्याची रात्र</string>\n    <string name=\"kodak\">कोडॅक</string>\n    <string name=\"save_empty_lut\">तटस्थ LUT प्रतिमा मिळवा</string>\n    <string name=\"save_empty_lut_sub\">प्रथम, तटस्थ LUT वर फिल्टर लागू करण्यासाठी तुमचा आवडता फोटो संपादन अनुप्रयोग वापरा जो तुम्ही येथे मिळवू शकता. हे योग्यरित्या कार्य करण्यासाठी प्रत्येक पिक्सेल रंग इतर पिक्सेलवर अवलंबून नसावा (उदा. अस्पष्ट काम करणार नाही). एकदा तयार झाल्यावर, 512*512 LUT फिल्टरसाठी इनपुट म्हणून तुमची नवीन LUT प्रतिमा वापरा</string>\n    <string name=\"pop_art\">पॉप आर्ट</string>\n    <string name=\"celluloid\">सेल्युलॉइड</string>\n    <string name=\"coffee\">कॉफी</string>\n    <string name=\"golden_forest\">गोल्डन फॉरेस्ट</string>\n    <string name=\"greenish\">हिरवट</string>\n    <string name=\"retro_yellow\">रेट्रो पिवळा</string>\n    <string name=\"links_preview\">दुवे पूर्वावलोकन</string>\n    <string name=\"links_preview_sub\">तुम्ही मजकूर मिळवू शकता अशा ठिकाणी लिंक पूर्वावलोकन पुनर्प्राप्त करणे सक्षम करते (QRCode, OCR इ.)</string>\n    <string name=\"links\">दुवे</string>\n    <string name=\"ico_size_warning\">ICO फायली केवळ 256 x 256 च्या कमाल आकारात जतन केल्या जाऊ शकतात</string>\n    <string name=\"gif_type_to_webp\">WEBP वर GIF</string>\n    <string name=\"gif_type_to_webp_sub\">GIF प्रतिमा WEBP ॲनिमेटेड चित्रांमध्ये रूपांतरित करा</string>\n    <string name=\"webp_tools\">WEBP साधने</string>\n    <string name=\"webp_tools_sub\">प्रतिमांना WEBP ॲनिमेटेड चित्रात रूपांतरित करा किंवा दिलेल्या WEBP ॲनिमेशनमधून फ्रेम्स काढा</string>\n    <string name=\"webp_type_to_image\">प्रतिमांसाठी WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP फाइल चित्रांच्या बॅचमध्ये रूपांतरित करा</string>\n    <string name=\"webp_type_to_webp_sub\">प्रतिमांचा बॅच WEBP फाइलमध्ये रूपांतरित करा</string>\n    <string name=\"webp_type_to_webp\">WEBP वर प्रतिमा</string>\n    <string name=\"select_webp_image_to_start\">सुरू करण्यासाठी WEBP प्रतिमा निवडा</string>\n    <string name=\"manage_storage_extra_types\">फायलींमध्ये पूर्ण प्रवेश नाही</string>\n    <string name=\"manage_storage_extra_types_sub\">Android वर प्रतिमा म्हणून ओळखल्या जात नसलेल्या JXL, QOI आणि इतर प्रतिमा पाहण्यासाठी सर्व फायलींना प्रवेश द्या. परवानगीशिवाय इमेज टूलबॉक्स त्या प्रतिमा दाखवू शकत नाही</string>\n    <string name=\"default_draw_color\">डीफॉल्ट ड्रॉ रंग</string>\n    <string name=\"default_draw_path_mode\">डीफॉल्ट ड्रॉ पथ मोड</string>\n    <string name=\"add_timestamp\">टाइमस्टॅम्प जोडा</string>\n    <string name=\"add_timestamp_sub\">आउटपुट फाइलनावामध्ये टाइमस्टॅम्प जोडणे सक्षम करते</string>\n    <string name=\"formatted_timestamp\">स्वरूपित टाइमस्टॅम्प</string>\n    <string name=\"formatted_timestamp_sub\">मूलभूत मिलिसऐवजी आउटपुट फाइलनावामध्ये टाइमस्टॅम्प स्वरूपन सक्षम करा</string>\n    <string name=\"enable_timestamps_to_format_them\">टाइमस्टॅम्प त्यांचे स्वरूप निवडण्यासाठी सक्षम करा</string>\n    <string name=\"one_time_save_location\">वन टाइम सेव्ह लोकेशन</string>\n    <string name=\"one_time_save_location_sub\">एक वेळ सेव्ह स्थाने पहा आणि संपादित करा जी तुम्ही बहुतेक सर्व पर्यायांमध्ये सेव्ह बटण जास्त वेळ दाबून वापरू शकता</string>\n    <string name=\"recently_used\">अलीकडे वापरले</string>\n    <string name=\"ci_channel\">सीआय चॅनेल</string>\n    <string name=\"group\">गट</string>\n    <string name=\"image_toolbox_in_telegram\">टेलीग्राम मधील इमेज टूलबॉक्स 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">आमच्या चॅटमध्ये सामील व्हा जिथे तुम्ही तुम्हाला पाहिजे असलेल्या कोणत्याही गोष्टीवर चर्चा करू शकता आणि मी बीटा आणि घोषणा पोस्ट करत असलेल्या CI चॅनेलमध्ये देखील पाहू शकता</string>\n    <string name=\"ci_channel_sub\">ॲपच्या नवीन आवृत्त्यांबद्दल सूचना मिळवा आणि घोषणा वाचा</string>\n    <string name=\"fit_description\">दिलेल्या परिमाणांमध्ये प्रतिमा फिट करा आणि पार्श्वभूमीला अस्पष्ट किंवा रंग लागू करा</string>\n    <string name=\"tools_arrangement\">साधने व्यवस्था</string>\n    <string name=\"group_tools_by_type\">प्रकारानुसार गट साधने</string>\n    <string name=\"group_tools_by_type_sub\">सानुकूल सूची व्यवस्थेऐवजी मुख्य स्क्रीनवर साधने त्यांच्या प्रकारानुसार गटबद्ध करा</string>\n    <string name=\"default_values\">डीफॉल्ट मूल्ये</string>\n    <string name=\"system_bars_visibility\">सिस्टम बार दृश्यमानता</string>\n    <string name=\"show_system_bars_by_swipe\">स्वाइप करून सिस्टम बार दर्शवा</string>\n    <string name=\"show_system_bars_by_swipe_sub\">सिस्टम बार लपविल्या असल्यास ते दर्शविण्यासाठी स्वाइप करणे सक्षम करते</string>\n    <string name=\"auto\">ऑटो</string>\n    <string name=\"hide_all\">सर्व लपवा</string>\n    <string name=\"show_all\">सर्व दाखवा</string>\n    <string name=\"hide_nav_bar\">नव बार लपवा</string>\n    <string name=\"hide_status_bar\">स्टेटस बार लपवा</string>\n    <string name=\"noise_generation\">आवाज निर्मिती</string>\n    <string name=\"noise_generation_sub\">पर्लिन किंवा इतर प्रकारचे वेगवेगळे आवाज निर्माण करा</string>\n    <string name=\"frequency\">वारंवारता</string>\n    <string name=\"noise_type\">आवाज प्रकार</string>\n    <string name=\"rotation_type\">रोटेशन प्रकार</string>\n    <string name=\"fractal_type\">फ्रॅक्टल प्रकार</string>\n    <string name=\"octaves\">सप्तक</string>\n    <string name=\"lacunarity\">अक्षता</string>\n    <string name=\"gain\">मिळवणे</string>\n    <string name=\"weighted_strength\">भारित सामर्थ्य</string>\n    <string name=\"ping_pong_strength\">पिंग पाँग सामर्थ्य</string>\n    <string name=\"distance_function\">अंतराचे कार्य</string>\n    <string name=\"return_type\">परतीचा प्रकार</string>\n    <string name=\"jitter\">जिटर</string>\n    <string name=\"domain_warp\">डोमेन वार्प</string>\n    <string name=\"alignment\">संरेखन</string>\n    <string name=\"custom_filename\">सानुकूल फाइलनाव</string>\n    <string name=\"custom_filename_sub\">स्थान आणि फाइल नाव निवडा जे वर्तमान प्रतिमा जतन करण्यासाठी वापरले जाईल</string>\n    <string name=\"saved_to_custom\">सानुकूल नावासह फोल्डरमध्ये जतन केले</string>\n    <string name=\"collage_maker\">कोलाज मेकर</string>\n    <string name=\"collage_maker_sub\">20 प्रतिमांपासून कोलाज बनवा</string>\n    <string name=\"collage_type\">कोलाज प्रकार</string>\n    <string name=\"collages_info\">बदलण्यासाठी प्रतिमा धरून ठेवा, हलवा आणि स्थिती समायोजित करण्यासाठी झूम करा</string>\n    <string name=\"disable_rotation\">रोटेशन अक्षम करा</string>\n    <string name=\"disable_rotation_sub\">दोन-बोटांच्या जेश्चरने प्रतिमा फिरवण्यास प्रतिबंधित करते</string>\n    <string name=\"enable_snapping_to_borders\">सीमांवर स्नॅपिंग सक्षम करा</string>\n    <string name=\"enable_snapping_to_borders_sub\">हलवल्यानंतर किंवा झूम केल्यानंतर, फ्रेमच्या कडा भरण्यासाठी प्रतिमा स्नॅप होतील</string>\n    <string name=\"histogram\">हिस्टोग्राम</string>\n    <string name=\"histogram_sub\">तुम्हाला समायोजन करण्यात मदत करण्यासाठी RGB किंवा ब्राइटनेस इमेज हिस्टोग्राम</string>\n    <string name=\"image_for_histogram\">ही प्रतिमा RGB आणि ब्राइटनेस हिस्टोग्राम तयार करण्यासाठी वापरली जाईल</string>\n    <string name=\"tesseract_options\">टेसरॅक्ट पर्याय</string>\n    <string name=\"tesseract_options_sub\">टेसरॅक्ट इंजिनसाठी काही इनपुट व्हेरिएबल्स लागू करा</string>\n    <string name=\"custom_options\">सानुकूल पर्याय</string>\n    <string name=\"custom_params_info\">या पॅटर्ननुसार पर्याय प्रविष्ट केले पाहिजेत: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">ऑटो क्रॉप</string>\n    <string name=\"free_corners\">मोफत कोपरे</string>\n    <string name=\"free_corners_sub\">बहुभुजानुसार प्रतिमा क्रॉप करा, हे दृष्टीकोन देखील सुधारते</string>\n    <string name=\"coerce_points_to_image_bounds\">इमेज बाऊंड्सवर जबरदस्ती पॉइंट्स</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">पॉइंट्स प्रतिमेच्या सीमांद्वारे मर्यादित नसतील, हे अधिक अचूक दृष्टीकोन सुधारण्यासाठी उपयुक्त आहे</string>\n    <string name=\"mask\">मुखवटा</string>\n    <string name=\"spot_heal_sub\">काढलेल्या मार्गाखाली सामग्री जागरूक भरा</string>\n    <string name=\"spot_heal\">बरे स्पॉट</string>\n    <string name=\"use_circle_kernel\">सर्कल कर्नल वापरा</string>\n    <string name=\"opening\">उघडत आहे</string>\n    <string name=\"closing\">बंद होत आहे</string>\n    <string name=\"morphological_gradient\">मॉर्फोलॉजिकल ग्रेडियंट</string>\n    <string name=\"top_hat\">टॉप हॅट</string>\n    <string name=\"black_hat\">काळी टोपी</string>\n    <string name=\"tone_curves\">टोन वक्र</string>\n    <string name=\"reset_curves\">वक्र रीसेट करा</string>\n    <string name=\"reset_curves_sub\">वक्र डीफॉल्ट मूल्यावर परत आणले जातील</string>\n    <string name=\"line_style\">रेखा शैली</string>\n    <string name=\"gap_size\">अंतर आकार</string>\n    <string name=\"dashed\">डॅश</string>\n    <string name=\"dot_dashed\">डॉट डॅश</string>\n    <string name=\"stamped\">शिक्का मारला</string>\n    <string name=\"zigzag\">झिगझॅग</string>\n    <string name=\"dashed_sub\">निर्दिष्ट अंतर आकारासह काढलेल्या मार्गावर डॅश रेषा काढते</string>\n    <string name=\"dot_dashed_sub\">दिलेल्या मार्गावर बिंदू आणि डॅश रेषा काढतो</string>\n    <string name=\"defaultt_sub\">फक्त डीफॉल्ट सरळ रेषा</string>\n    <string name=\"stamped_sub\">निर्दिष्ट अंतरासह मार्गावर निवडलेले आकार काढतो</string>\n    <string name=\"zigzag_sub\">मार्गावर लहरी झिगझॅग काढतो</string>\n    <string name=\"zigzag_ratio\">झिगझॅग प्रमाण</string>\n    <string name=\"create_shortcut\">शॉर्टकट तयार करा</string>\n    <string name=\"create_shortcut_title\">पिन करण्यासाठी साधन निवडा</string>\n    <string name=\"create_shortcut_subtitle\">शॉर्टकट म्हणून तुमच्या लाँचरच्या होम स्क्रीनवर टूल जोडले जाईल, आवश्यक वर्तन साध्य करण्यासाठी ते \\\"फाइल निवडणे वगळा\\\" सेटिंगसह एकत्र वापरा</string>\n    <string name=\"dont_stack_frames\">फ्रेम स्टॅक करू नका</string>\n    <string name=\"dont_stack_frames_sub\">मागील फ्रेम्सची विल्हेवाट लावणे सक्षम करते, जेणेकरून ते एकमेकांवर स्टॅक करणार नाहीत</string>\n    <string name=\"crossfade\">क्रॉसफेड</string>\n    <string name=\"crossfade_sub\">फ्रेम्स एकमेकांमध्ये क्रॉसफेड ​​केल्या जातील</string>\n    <string name=\"crossfade_count\">क्रॉसफेड ​​फ्रेम्स मोजतात</string>\n    <string name=\"threshold_one\">थ्रेशोल्ड वन</string>\n    <string name=\"threshold_two\">थ्रेशोल्ड दोन</string>\n    <string name=\"canny\">कॅनी</string>\n    <string name=\"mirror_101\">मिरर 101</string>\n    <string name=\"enhanced_zoom_blur\">वर्धित झूम ब्लर</string>\n    <string name=\"laplacian_simple\">लॅपलाशियन साधे</string>\n    <string name=\"sobel_simple\">सोबेल साधे</string>\n    <string name=\"helper_grid\">हेल्पर ग्रिड</string>\n    <string name=\"helper_grid_sub\">अचूक हेरफेर करण्यात मदत करण्यासाठी रेखांकन क्षेत्राच्या वर सहाय्यक ग्रिड दर्शविते</string>\n    <string name=\"grid_color\">ग्रिड रंग</string>\n    <string name=\"cell_width\">सेल रुंदी</string>\n    <string name=\"cell_height\">सेलची उंची</string>\n    <string name=\"compact_selectors\">कॉम्पॅक्ट सिलेक्टर</string>\n    <string name=\"compact_selectors_sub\">काही निवड नियंत्रणे कमी जागा घेण्यासाठी कॉम्पॅक्ट लेआउट वापरतील</string>\n    <string name=\"grant_camera_permission_to_capture_image\">प्रतिमा कॅप्चर करण्यासाठी सेटिंग्जमध्ये कॅमेरा परवानगी द्या</string>\n    <string name=\"layout\">मांडणी</string>\n    <string name=\"main_screen_title\">मुख्य स्क्रीन शीर्षक</string>\n    <string name=\"constant_rate_factor\">स्थिर दर घटक (CRF)</string>\n    <string name=\"crf_sub\">%1$s चे मूल्य म्हणजे मंद कॉम्प्रेशन, परिणामी तुलनेने लहान फाइल आकार. %2$s म्हणजे जलद कॉम्प्रेशन, परिणामी फाइल मोठी होते.</string>\n    <string name=\"lut_library\">लुट लायब्ररी</string>\n    <string name=\"lut_library_sub\">LUTs चा संग्रह डाउनलोड करा, जो तुम्ही डाउनलोड केल्यानंतर अर्ज करू शकता</string>\n    <string name=\"lut_library_update_sub\">LUT चे संकलन अद्यतनित करा (फक्त नवीन रांगेत असतील), जे तुम्ही डाउनलोड केल्यानंतर अर्ज करू शकता</string>\n    <string name=\"filter_preview_image_sub\">फिल्टरसाठी डीफॉल्ट प्रतिमा पूर्वावलोकन बदला</string>\n    <string name=\"filter_preview_image\">पूर्वावलोकन प्रतिमा</string>\n    <string name=\"hide\">लपवा</string>\n    <string name=\"show\">दाखवा</string>\n    <string name=\"slider_type\">स्लाइडर प्रकार</string>\n    <string name=\"fancy\">फॅन्सी</string>\n    <string name=\"material_2\">साहित्य २</string>\n    <string name=\"fancy_sub\">फॅन्सी दिसणारा स्लाइडर. हा डीफॉल्ट पर्याय आहे</string>\n    <string name=\"material_2_sub\">एक साहित्य 2 स्लाइडर</string>\n    <string name=\"material_you_slider_sub\">एक साहित्य आपण स्लाइडर</string>\n    <string name=\"apply\">अर्ज करा</string>\n    <string name=\"center_align_dialog_buttons\">मध्यभागी संवाद बटणे</string>\n    <string name=\"center_align_dialog_buttons_sub\">शक्य असल्यास डायलॉग्सची बटणे डाव्या बाजूला ऐवजी मध्यभागी ठेवली जातील</string>\n    <string name=\"open_source_licenses\">मुक्त स्रोत परवाने</string>\n    <string name=\"open_source_licenses_sub\">या ॲपमध्ये वापरलेल्या मुक्त स्रोत लायब्ररींचे परवाने पहा</string>\n    <string name=\"area\">क्षेत्रफळ</string>\n    <string name=\"area_sub\">पिक्सेल एरिया रिलेशन वापरून रिसॅम्पलिंग. प्रतिमा नष्ट करण्यासाठी ही एक पसंतीची पद्धत असू शकते, कारण ती मोअर\\'-मुक्त परिणाम देते. परंतु जेव्हा प्रतिमा झूम केली जाते, तेव्हा ती \\\"जवळपास\\\" पद्धतीसारखी असते.</string>\n    <string name=\"enable_tonemapping\">टोनमॅपिंग सक्षम करा</string>\n    <string name=\"enter_percent\">% प्रविष्ट करा</string>\n    <string name=\"unknown_host\">साइटवर प्रवेश करू शकत नाही, VPN वापरून पहा किंवा url बरोबर आहे का ते तपासा</string>\n    <string name=\"markup_layers\">मार्कअप स्तर</string>\n    <string name=\"markup_layers_sub\">मुक्तपणे प्रतिमा, मजकूर आणि बरेच काही ठेवण्याच्या क्षमतेसह स्तर मोड</string>\n    <string name=\"edit_layer\">स्तर संपादित करा</string>\n    <string name=\"layers_on_image\">प्रतिमेवरील स्तर</string>\n    <string name=\"layers_on_image_sub\">पार्श्वभूमी म्हणून प्रतिमा वापरा आणि तिच्या वर विविध स्तर जोडा</string>\n    <string name=\"layers_on_background\">पार्श्वभूमीवरील स्तर</string>\n    <string name=\"layers_on_background_sub\">पहिल्या पर्यायाप्रमाणेच परंतु प्रतिमेऐवजी रंगासह</string>\n    <string name=\"beta\">बीटा</string>\n    <string name=\"fast_settings_side\">जलद सेटिंग्ज बाजूला</string>\n    <string name=\"fast_settings_side_sub\">प्रतिमा संपादित करताना निवडलेल्या बाजूला फ्लोटिंग स्ट्रिप जोडा, जे क्लिक केल्यावर जलद सेटिंग्ज उघडेल</string>\n    <string name=\"clear_selection\">निवड साफ करा</string>\n    <string name=\"settings_group_visibility_hidden\">सेट करणे गट \\\"%1$s\\\" डीफॉल्टनुसार संकुचित केले जाईल</string>\n    <string name=\"settings_group_visibility_visible\">सेटिंग गट \\\"%1$s\\\" डीफॉल्टनुसार विस्तारित केला जाईल</string>\n    <string name=\"base_64_tools\">बेस64 साधने</string>\n    <string name=\"base_64_tools_sub\">Base64 स्ट्रिंगला इमेज डीकोड करा किंवा Base64 फॉरमॅटमध्ये इमेज एन्कोड करा</string>\n    <string name=\"base_64\">बेस64</string>\n    <string name=\"not_a_valid_base_64\">प्रदान केलेले मूल्य वैध Base64 स्ट्रिंग नाही</string>\n    <string name=\"copy_not_a_valid_base_64\">रिक्त किंवा अवैध Base64 स्ट्रिंग कॉपी करू शकत नाही</string>\n    <string name=\"paste_base_64\">बेस64 पेस्ट करा</string>\n    <string name=\"copy_base_64\">बेस64 कॉपी करा</string>\n    <string name=\"base_64_tips\">Base64 स्ट्रिंग कॉपी किंवा सेव्ह करण्यासाठी इमेज लोड करा. जर तुमच्याकडे स्ट्रिंग असेल, तर तुम्ही इमेज मिळवण्यासाठी वर पेस्ट करू शकता</string>\n    <string name=\"save_base_64\">बेस64 जतन करा</string>\n    <string name=\"share_base_64\">शेअर बेस64</string>\n    <string name=\"options\">पर्याय</string>\n    <string name=\"actions\">क्रिया</string>\n    <string name=\"import_base_64\">बेस64 आयात करा</string>\n    <string name=\"base_64_actions\">बेस64 क्रिया</string>\n    <string name=\"add_outline\">बाह्यरेखा जोडा</string>\n    <string name=\"add_outline_sub\">निर्दिष्ट रंग आणि रुंदीसह मजकुराभोवती बाह्यरेखा जोडा</string>\n    <string name=\"outline_color\">बाह्यरेखा रंग</string>\n    <string name=\"outline_size\">बाह्यरेखा आकार</string>\n    <string name=\"rotation\">रोटेशन</string>\n    <string name=\"checksum_as_filename\">फाइलनाव म्हणून चेकसम</string>\n    <string name=\"checksum_as_filename_sub\">आउटपुट प्रतिमांना त्यांच्या डेटा चेकसमशी संबंधित नाव असेल</string>\n    <string name=\"free_software_partner\">मोफत सॉफ्टवेअर (भागीदार)</string>\n    <string name=\"free_software_partner_sub\">Android अनुप्रयोगांच्या भागीदार चॅनेलमध्ये अधिक उपयुक्त सॉफ्टवेअर</string>\n    <string name=\"algorithms\">अल्गोरिदम</string>\n    <string name=\"checksum_tools\">चेकसम साधने</string>\n    <string name=\"checksum_tools_sub\">चेकसमची तुलना करा, हॅशची गणना करा किंवा भिन्न हॅशिंग अल्गोरिदम वापरून फाइल्समधून हेक्स स्ट्रिंग तयार करा</string>\n    <string name=\"calculate\">गणना करा</string>\n    <string name=\"text_hash\">मजकूर हॅश</string>\n    <string name=\"checksum\">चेकसम</string>\n    <string name=\"pick_file_to_checksum\">निवडलेल्या अल्गोरिदमवर आधारित त्याच्या चेकसमची गणना करण्यासाठी फाइल निवडा</string>\n    <string name=\"enter_text_to_checksum\">निवडलेल्या अल्गोरिदमवर आधारित त्याच्या चेकसमची गणना करण्यासाठी मजकूर प्रविष्ट करा</string>\n    <string name=\"source_checksum\">स्त्रोत चेकसम</string>\n    <string name=\"checksum_to_compare\">तुलना करण्यासाठी चेकसम</string>\n    <string name=\"match\">जुळवा!</string>\n    <string name=\"difference\">फरक</string>\n    <string name=\"match_sub\">चेकसम समान आहेत, ते सुरक्षित असू शकतात</string>\n    <string name=\"difference_sub\">चेकसम समान नाहीत, फाइल असुरक्षित असू शकते!</string>\n    <string name=\"mesh_gradients\">मेष ग्रेडियंट्स</string>\n    <string name=\"collection_mesh_gradients_sub\">मेश ग्रेडियंटचे ऑनलाइन संग्रह पहा</string>\n    <string name=\"wrong_font\">फक्त TTF आणि OTF फॉन्ट आयात केले जाऊ शकतात</string>\n    <string name=\"import_font\">फॉन्ट आयात करा (TTF/OTF)</string>\n    <string name=\"export_fonts\">फॉन्ट निर्यात करा</string>\n    <string name=\"imported_fonts\">आयात केलेले फॉन्ट</string>\n    <string name=\"error_while_saving\">प्रयत्न जतन करताना त्रुटी, आउटपुट फोल्डर बदलण्याचा प्रयत्न करा</string>\n    <string name=\"filename_is_not_set\">फाइलनाव सेट केलेले नाही</string>\n    <string name=\"none\">काहीही नाही</string>\n    <string name=\"custom_pages\">सानुकूल पृष्ठे</string>\n    <string name=\"pages_selection\">पृष्ठे निवड</string>\n    <string name=\"tool_exit_confirmation\">साधन निर्गमन पुष्टीकरण</string>\n    <string name=\"tool_exit_confirmation_sub\">तुमच्याकडे विशिष्ट टूल्स वापरताना सेव्ह न केलेले बदल असल्यास आणि ते बंद करण्याचा प्रयत्न केल्यास, पुष्टी करा संवाद दर्शविला जाईल</string>\n    <string name=\"edit_exif_screen\">EXIF संपादित करा</string>\n    <string name=\"edit_exif_screen_sub\">रीकंप्रेशनशिवाय सिंगल इमेजचा मेटाडेटा बदला</string>\n    <string name=\"edit_exif_tag\">उपलब्ध टॅग संपादित करण्यासाठी टॅप करा</string>\n    <string name=\"change_sticker\">स्टिकर बदला</string>\n    <string name=\"fit_width\">फिट रुंदी</string>\n    <string name=\"fit_height\">फिट उंची</string>\n    <string name=\"batch_compare\">बॅचची तुलना करा</string>\n    <string name=\"pick_files_to_checksum\">निवडलेल्या अल्गोरिदमवर आधारित त्याच्या चेकसमची गणना करण्यासाठी फाइल/फाईल्स निवडा</string>\n    <string name=\"pick_files\">फाइल्स निवडा</string>\n    <string name=\"pick_directory\">निर्देशिका निवडा</string>\n    <string name=\"head_length_scale\">डोके लांबी स्केल</string>\n    <string name=\"stamp\">मुद्रांक</string>\n    <string name=\"timestamp\">टाईमस्टॅम्प</string>\n    <string name=\"format_pattern\">स्वरूप नमुना</string>\n    <string name=\"padding\">पॅडिंग</string>\n    <string name=\"image_cutting\">प्रतिमा कटिंग</string>\n    <string name=\"image_cutting_sub\">प्रतिमेचा भाग कट करा आणि डाव्या भागांना उभ्या किंवा क्षैतिज रेषांनी एकत्र करा (विलोम असू शकते).</string>\n    <string name=\"vertical_pivot_line\">अनुलंब पिव्होट लाइन</string>\n    <string name=\"horizontal_pivot_line\">क्षैतिज पिव्होट लाइन</string>\n    <string name=\"inverse_selection\">व्यस्त निवड</string>\n    <string name=\"inverse_vertical_selection_sub\">कट क्षेत्राभोवती भाग विलीन करण्याऐवजी अनुलंब कट भाग सोडला जाईल</string>\n    <string name=\"inverse_horizontal_selection_sub\">कट क्षेत्राभोवती भाग विलीन करण्याऐवजी, क्षैतिज कट भाग सोडला जाईल</string>\n    <string name=\"collection_mesh_gradients\">मेष ग्रेडियंट्सचे संकलन</string>\n    <string name=\"mesh_gradients_sub\">सानुकूल नॉट्स आणि रिझोल्यूशनसह जाळी ग्रेडियंट तयार करा</string>\n    <string name=\"gradient_maker_type_image_mesh\">मेष ग्रेडियंट आच्छादन</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">दिलेल्या प्रतिमांच्या शीर्षस्थानी मेश ग्रेडियंट तयार करा</string>\n    <string name=\"points_customization\">पॉइंट्स कस्टमायझेशन</string>\n    <string name=\"grid_size\">ग्रिड आकार</string>\n    <string name=\"resolution_x\">ठराव X</string>\n    <string name=\"resolution_y\">ठराव Y</string>\n    <string name=\"resolution\">ठराव</string>\n    <string name=\"pixel_by_pixel\">पिक्सेल बाय पिक्सेल</string>\n    <string name=\"highlight_color\">रंग हायलाइट करा</string>\n    <string name=\"pixel_comparison_type\">पिक्सेल तुलना प्रकार</string>\n    <string name=\"scan_barcode\">बारकोड स्कॅन करा</string>\n    <string name=\"height_ratio\">उंचीचे प्रमाण</string>\n    <string name=\"barcode_type\">बारकोड प्रकार</string>\n    <string name=\"enforce_bw\">B/W ला लागू करा</string>\n    <string name=\"enforce_bw_sub\">बारकोड प्रतिमा पूर्णपणे काळा आणि पांढरी असेल आणि ॲपच्या थीमनुसार रंगीत नसेल</string>\n    <string name=\"barcodes_sub\">कोणताही बारकोड स्कॅन करा (QR, EAN, AZTEC, …) आणि त्याची सामग्री मिळवा किंवा नवीन तयार करण्यासाठी तुमचा मजकूर पेस्ट करा</string>\n    <string name=\"no_barcode_found\">बारकोड सापडला नाही</string>\n    <string name=\"generated_barcode_will_be_here\">जनरेट केलेला बारकोड येथे असेल</string>\n    <string name=\"audio_cover_extractor\">ऑडिओ कव्हर्स</string>\n    <string name=\"audio_cover_extractor_sub\">ऑडिओ फायलींमधून अल्बम कव्हर प्रतिमा काढा, सर्वात सामान्य स्वरूप समर्थित आहेत</string>\n    <string name=\"pick_audio_to_start\">सुरू करण्यासाठी ऑडिओ निवडा</string>\n    <string name=\"pick_audio\">ऑडिओ निवडा</string>\n    <string name=\"no_covers_found\">कोणतेही कव्हर्स आढळले नाहीत</string>\n    <string name=\"send_logs\">नोंदी पाठवा</string>\n    <string name=\"send_logs_sub\">ॲप लॉग फाइल शेअर करण्यासाठी क्लिक करा, हे मला समस्या शोधण्यात आणि समस्यांचे निराकरण करण्यात मदत करू शकते</string>\n    <string name=\"crash_title\">अरेरे… काहीतरी चूक झाली</string>\n    <string name=\"crash_subtitle\">तुम्ही खालील पर्याय वापरून माझ्याशी संपर्क साधू शकता आणि मी उपाय शोधण्याचा प्रयत्न करेन.\\n(लॉग जोडण्यास विसरू नका)</string>\n    <string name=\"ocr_write_to_file\">फाइलवर लिहा</string>\n    <string name=\"ocr_write_to_file_sub\">प्रतिमांच्या बॅचमधून मजकूर काढा आणि एका मजकूर फाइलमध्ये संग्रहित करा</string>\n    <string name=\"ocr_write_to_metadata\">मेटाडेटा वर लिहा</string>\n    <string name=\"ocr_write_to_metadata_sub\">प्रत्येक प्रतिमेतून मजकूर काढा आणि संबंधित फोटोंच्या EXIF ​​माहितीमध्ये ठेवा</string>\n    <string name=\"invisible_mode\">अदृश्य मोड</string>\n    <string name=\"invisible_mode_sub\">तुमच्या इमेजच्या बाइट्समध्ये डोळा अदृश्य वॉटरमार्क तयार करण्यासाठी स्टेग्नोग्राफी वापरा</string>\n    <string name=\"use_lsb\">LSB वापरा</string>\n    <string name=\"use_lsb_sub\">एलएसबी (लेस सिग्निफिकंट बिट) स्टेग्नोग्राफी पद्धत वापरली जाईल, अन्यथा एफडी (फ्रिक्वेंसी डोमेन)</string>\n    <string name=\"auto_remove_red_eyes\">स्वयं लाल डोळे काढा</string>\n    <string name=\"password\">पासवर्ड</string>\n    <string name=\"unlock\">अनलॉक करा</string>\n    <string name=\"pdf_is_protected\">PDF संरक्षित आहे</string>\n    <string name=\"operation_almost_complete\">ऑपरेशन जवळजवळ पूर्ण झाले. आता रद्द करण्यासाठी ते रीस्टार्ट करणे आवश्यक आहे</string>\n    <string name=\"sort_by_date_modified\">तारीख सुधारली</string>\n    <string name=\"sort_by_date_modified_reversed\">तारीख सुधारित (उलट)</string>\n    <string name=\"sort_by_size_reversed\">आकार (उलट)</string>\n    <string name=\"sort_by_mime_type\">MIME प्रकार</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME प्रकार (उलट)</string>\n    <string name=\"sort_by_extension\">विस्तार</string>\n    <string name=\"sort_by_extension_reversed\">विस्तार (उलट)</string>\n    <string name=\"sort_by_date_added\">तारीख जोडली</string>\n    <string name=\"sort_by_date_added_reversed\">जोडलेली तारीख (उलट)</string>\n    <string name=\"left_to_right\">डावीकडून उजवीकडे</string>\n    <string name=\"right_to_left\">उजवीकडून डावीकडे</string>\n    <string name=\"top_to_bottom\">वरपासून खालपर्यंत</string>\n    <string name=\"bottom_to_top\">तळापासून वरपर्यंत</string>\n    <string name=\"liquid_glass\">लिक्विड ग्लास</string>\n    <string name=\"liquid_glass_sub\">अलीकडेच घोषित केलेल्या IOS 26 आणि त्याच्या लिक्विड ग्लास डिझाइन सिस्टमवर आधारित एक स्विच</string>\n    <string name=\"pick_image_or_base64\">प्रतिमा निवडा किंवा खाली बेस64 डेटा पेस्ट/इंपोर्ट करा</string>\n    <string name=\"type_image_link\">सुरू करण्यासाठी इमेज लिंक टाइप करा</string>\n    <string name=\"paste_link\">लिंक पेस्ट करा</string>\n    <string name=\"kaleidoscope\">कॅलिडोस्कोप</string>\n    <string name=\"secondary_angle\">दुय्यम कोन</string>\n    <string name=\"sides\">बाजू</string>\n    <string name=\"channel_mix\">चॅनेल मिक्स</string>\n    <string name=\"blue_green\">निळा हिरवा</string>\n    <string name=\"red_blue\">लाल निळा</string>\n    <string name=\"green_red\">हिरवा लाल</string>\n    <string name=\"into_red\">लाल मध्ये</string>\n    <string name=\"into_green\">हिरव्या मध्ये</string>\n    <string name=\"into_blue\">निळ्या रंगात</string>\n    <string name=\"cyan\">निळसर</string>\n    <string name=\"magenta\">किरमिजी रंग</string>\n    <string name=\"yellow\">पिवळा</string>\n    <string name=\"color_halftone\">रंग हाफटोन</string>\n    <string name=\"contour\">समोच्च</string>\n    <string name=\"levels\">स्तर</string>\n    <string name=\"offset\">ऑफसेट</string>\n    <string name=\"voronoi_crystallize\">व्होरोनोई क्रिस्टलाइझ</string>\n    <string name=\"shape\">आकार</string>\n    <string name=\"stretch\">ताणणे</string>\n    <string name=\"randomness\">यादृच्छिकता</string>\n    <string name=\"despeckle\">डिस्पेकल</string>\n    <string name=\"diffuse\">पसरणे</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">दुसरी त्रिज्या</string>\n    <string name=\"equalize\">बरोबरी करा</string>\n    <string name=\"glow\">चमकणे</string>\n    <string name=\"whirl_and_pinch\">चक्कर आणि चिमूटभर</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">सीमा रंग</string>\n    <string name=\"polar_coordinates\">ध्रुवीय निर्देशांक</string>\n    <string name=\"rect_to_polar\">ध्रुवीय कडे वळवा</string>\n    <string name=\"polar_to_rect\">दुरुस्त करण्यासाठी ध्रुवीय</string>\n    <string name=\"invert_in_circle\">वर्तुळात उलटा</string>\n    <string name=\"reduce_noise\">आवाज कमी करा</string>\n    <string name=\"simple_solarize\">साधे सोलाराइज</string>\n    <string name=\"weave\">विणणे</string>\n    <string name=\"x_gap\">X अंतर</string>\n    <string name=\"y_gap\">Y अंतर</string>\n    <string name=\"x_width\">X रुंदी</string>\n    <string name=\"y_wdth\">वाई रुंदी</string>\n    <string name=\"twirl\">फिरणे</string>\n    <string name=\"rubber_stmp\">रबर स्टॅम्प</string>\n    <string name=\"smear\">स्मीअर</string>\n    <string name=\"density\">घनता</string>\n    <string name=\"mix\">मिसळा</string>\n    <string name=\"sphere_lensh_distortion\">स्फेअर लेन्स विरूपण</string>\n    <string name=\"refraction_index\">अपवर्तन निर्देशांक</string>\n    <string name=\"arc\">चाप</string>\n    <string name=\"spread_angle\">स्प्रेड कोन</string>\n    <string name=\"sparkle\">चमचमीत</string>\n    <string name=\"rays\">किरण</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">ग्रेडियंट</string>\n    <string name=\"moire\">मेरी</string>\n    <string name=\"autumn\">शरद ऋतूतील</string>\n    <string name=\"bone\">हाड</string>\n    <string name=\"jet\">जेट</string>\n    <string name=\"winter\">हिवाळा</string>\n    <string name=\"ocean\">महासागर</string>\n    <string name=\"summer\">उन्हाळा</string>\n    <string name=\"spring\">वसंत</string>\n    <string name=\"cool_variant\">छान प्रकार</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">गुलाबी</string>\n    <string name=\"hot\">गरम</string>\n    <string name=\"parula\">शब्द</string>\n    <string name=\"magma\">मॅग्मा</string>\n    <string name=\"inferno\">इन्फर्नो</string>\n    <string name=\"plasma\">प्लाझ्मा</string>\n    <string name=\"viridis\">विरिडीस</string>\n    <string name=\"cividis\">नागरिक</string>\n    <string name=\"twilight\">संधिप्रकाश</string>\n    <string name=\"twilight_shifted\">ट्वायलाइट शिफ्ट झाला</string>\n    <string name=\"auto_perspective\">परिप्रेक्ष्य ऑटो</string>\n    <string name=\"deskew\">डेस्क्यू</string>\n    <string name=\"allow_crop\">पीक परवानगी द्या</string>\n    <string name=\"crop_or_perspective\">क्रॉप किंवा दृष्टीकोन</string>\n    <string name=\"absolute\">निरपेक्ष</string>\n    <string name=\"turbo\">टर्बो</string>\n    <string name=\"deep_green\">खोल हिरवा</string>\n    <string name=\"lens_correction\">लेन्स सुधारणा</string>\n    <string name=\"target_lens_profile\">लक्ष्य लेन्स प्रोफाइल फाइल JSON फॉरमॅटमध्ये</string>\n    <string name=\"download_ready_lens_profiles\">तयार लेन्स प्रोफाइल डाउनलोड करा</string>\n    <string name=\"part_percents\">भाग टक्के</string>\n    <string name=\"export_as_json\">JSON म्हणून निर्यात करा</string>\n    <string name=\"export_as_json_sub\">json प्रतिनिधित्व म्हणून पॅलेट डेटासह स्ट्रिंग कॉपी करा</string>\n    <string name=\"seam_carving\">शिवण कोरीव काम</string>\n    <string name=\"home_screen\">होम स्क्रीन</string>\n    <string name=\"lock_screen\">लॉक स्क्रीन</string>\n    <string name=\"built_in\">अंगभूत</string>\n    <string name=\"wallpapers_export\">वॉलपेपर निर्यात</string>\n    <string name=\"refresh\">रिफ्रेश करा</string>\n    <string name=\"wallpapers_export_sub\">वर्तमान घर, लॉक आणि अंगभूत वॉलपेपर मिळवा</string>\n    <string name=\"allow_access_to_all_files_for_wp\">सर्व फायलींमध्ये प्रवेश करण्याची परवानगी द्या, वॉलपेपर पुनर्प्राप्त करण्यासाठी हे आवश्यक आहे</string>\n    <string name=\"allow_read_media_images_for_wp\">बाह्य संचयन परवानगी व्यवस्थापित करणे पुरेसे नाही, तुम्हाला तुमच्या प्रतिमांमध्ये प्रवेश देण्याची आवश्यकता आहे, \\\"सर्वांना अनुमती द्या\\\" निवडण्याचे सुनिश्चित करा</string>\n    <string name=\"add_preset_to_filename\">फाइलनावमध्ये प्रीसेट जोडा</string>\n    <string name=\"add_preset_to_filename_sub\">इमेज फाइलनावामध्ये निवडलेल्या प्रीसेटसह प्रत्यय जोडते</string>\n    <string name=\"add_image_scale_mode_to_filename\">फाइलनावामध्ये इमेज स्केल मोड जोडा</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">इमेज फाइलनावामध्ये निवडलेल्या इमेज स्केल मोडसह प्रत्यय जोडतो</string>\n    <string name=\"ascii_art\">Ascii कला</string>\n    <string name=\"ascii_art_sub\">चित्राला ascii मजकुरात रूपांतरित करा जे प्रतिमेसारखे दिसेल</string>\n    <string name=\"params\">परम्स</string>\n    <string name=\"invert_colors_ascii_sub\">काही प्रकरणांमध्ये चांगल्या परिणामासाठी प्रतिमेवर नकारात्मक फिल्टर लागू करते</string>\n    <string name=\"processing_screenshot\">स्क्रीनशॉटवर प्रक्रिया करत आहे</string>\n    <string name=\"screenshot_not_captured_try_again\">स्क्रीनशॉट कॅप्चर केला नाही, पुन्हा प्रयत्न करा</string>\n    <string name=\"skipped_saving\">जतन करणे वगळले</string>\n    <string name=\"skipped_saving_multiple\">%1$s फायली वगळल्या</string>\n    <string name=\"allow_skip_if_larger\">मोठे असल्यास वगळा</string>\n    <string name=\"allow_skip_if_larger_sub\">परिणामी फाइलचा आकार मूळपेक्षा मोठा असल्यास प्रतिमा जतन करणे वगळण्यासाठी काही साधनांना परवानगी दिली जाईल.</string>\n    <string name=\"qr_type_calendar_event\">कॅलेंडर इव्हेंट</string>\n    <string name=\"qr_type_contact_info\">संपर्क करा</string>\n    <string name=\"qr_type_email\">ईमेल</string>\n    <string name=\"qr_type_geo_point\">स्थान</string>\n    <string name=\"qr_type_phone\">फोन</string>\n    <string name=\"qr_type_plain\">मजकूर</string>\n    <string name=\"qr_type_sms\">एसएमएस</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">वाय-फाय</string>\n    <string name=\"open_network\">नेटवर्क उघडा</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">फोन</string>\n    <string name=\"message\">संदेश</string>\n    <string name=\"address\">पत्ता</string>\n    <string name=\"subject\">विषय</string>\n    <string name=\"body\">शरीर</string>\n    <string name=\"name\">नाव</string>\n    <string name=\"organization\">संघटना</string>\n    <string name=\"title\">शीर्षक</string>\n    <string name=\"phones\">फोन</string>\n    <string name=\"emails\">ईमेल्स</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">पत्ते</string>\n    <string name=\"summary\">सारांश</string>\n    <string name=\"description\">वर्णन</string>\n    <string name=\"location\">स्थान</string>\n    <string name=\"organizer\">आयोजक</string>\n    <string name=\"start_date\">प्रारंभ तारीख</string>\n    <string name=\"end_date\">शेवटची तारीख</string>\n    <string name=\"status\">स्थिती</string>\n    <string name=\"latitude\">अक्षांश</string>\n    <string name=\"longitude\">रेखांश</string>\n    <string name=\"create_barcode\">बारकोड तयार करा</string>\n    <string name=\"edit_barcode\">बारकोड संपादित करा</string>\n    <string name=\"wifi_configuration\">वाय-फाय कॉन्फिगरेशन</string>\n    <string name=\"security\">सुरक्षा</string>\n    <string name=\"pick_contact\">संपर्क निवडा</string>\n    <string name=\"grant_contact_permission\">निवडलेला संपर्क वापरून ऑटोफिल करण्यासाठी सेटिंग्जमध्ये संपर्कांना परवानगी द्या</string>\n    <string name=\"contact_info\">संपर्क माहिती</string>\n    <string name=\"first_name\">नाव</string>\n    <string name=\"middle_name\">मधले नाव</string>\n    <string name=\"last_name\">आडनाव</string>\n    <string name=\"pronunciation\">उच्चार</string>\n    <string name=\"add_phone\">फोन जोडा</string>\n    <string name=\"add_email\">ईमेल जोडा</string>\n    <string name=\"add_address\">पत्ता जोडा</string>\n    <string name=\"website\">वेबसाइट</string>\n    <string name=\"add_website\">वेबसाइट जोडा</string>\n    <string name=\"formatted_name\">स्वरूपित नाव</string>\n    <string name=\"qr_code_top_image\">ही प्रतिमा वर बारकोड ठेवण्यासाठी वापरली जाईल</string>\n    <string name=\"code_customization\">कोड सानुकूलन</string>\n    <string name=\"qr_logo_image\">ही प्रतिमा QR कोडच्या मध्यभागी लोगो म्हणून वापरली जाईल</string>\n    <string name=\"logo\">लोगो</string>\n    <string name=\"logo_padding\">लोगो पॅडिंग</string>\n    <string name=\"logo_size\">लोगो आकार</string>\n    <string name=\"logo_corners\">लोगोचे कोपरे</string>\n    <string name=\"fourth_eye\">चौथा डोळा</string>\n    <string name=\"fourth_eye_description\">खालच्या टोकाच्या कोपर्यात चौथा डोळा जोडून क्यूआर कोडमध्ये डोळ्याची सममिती जोडते</string>\n    <string name=\"pixel_shape\">पिक्सेल आकार</string>\n    <string name=\"frame_shape\">फ्रेम आकार</string>\n    <string name=\"ball_shape\">चेंडू आकार</string>\n    <string name=\"error_correction_level\">त्रुटी सुधारण्याची पातळी</string>\n    <string name=\"dark_color\">गडद रंग</string>\n    <string name=\"light_color\">हलका रंग</string>\n    <string name=\"hyper_os\">हायपर ओएस</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS सारखी शैली</string>\n    <string name=\"mask_pattern\">मुखवटा नमुना</string>\n    <string name=\"code_may_be_not_scannable\">हा कोड स्कॅन करण्यायोग्य नसू शकतो, तो सर्व उपकरणांसह वाचनीय बनवण्यासाठी देखावा पॅराम्स बदला</string>\n    <string name=\"launcher_mode_sub\">टूल्स अधिक कॉम्पॅक्ट होण्यासाठी होम स्क्रीन ॲप लाँचरसारखे दिसतील</string>\n    <string name=\"launcher_mode\">लाँचर मोड</string>\n    <string name=\"flood_fill_sub\">निवडलेल्या ब्रश आणि शैलीसह क्षेत्र भरते</string>\n    <string name=\"flood_fill\">पूर भरणे</string>\n    <string name=\"spray\">फवारणी</string>\n    <string name=\"spray_sub\">ग्राफिटी शैलीचा मार्ग काढतो</string>\n    <string name=\"square_particles\">चौरस कण</string>\n    <string name=\"square_particles_sub\">स्प्रे कण वर्तुळांऐवजी चौरस आकाराचे असतील</string>\n    <string name=\"palette_tools\">पॅलेट साधने</string>\n    <string name=\"palette_tools_sub\">इमेजमधून तुम्ही पॅलेट करता ते मूलभूत/साहित्य तयार करा किंवा वेगवेगळ्या पॅलेट फॉरमॅटमध्ये आयात/निर्यात करा</string>\n    <string name=\"edit_palette\">पॅलेट संपादित करा</string>\n    <string name=\"edit_palette_sub\">विविध स्वरूपांमध्ये पॅलेट निर्यात/आयात करा</string>\n    <string name=\"color_name\">रंगाचे नाव</string>\n    <string name=\"palette_name\">पॅलेट नाव</string>\n    <string name=\"palette_format\">पॅलेट स्वरूप</string>\n    <string name=\"export_palette_sub\">व्युत्पन्न केलेले पॅलेट वेगवेगळ्या फॉरमॅटमध्ये एक्सपोर्ट करा</string>\n    <string name=\"add_color_palette_sub\">वर्तमान पॅलेटमध्ये नवीन रंग जोडतो</string>\n    <string name=\"palette_name_not_supported\">%1$s स्वरूप पॅलेट नाव प्रदान करण्यास समर्थन देत नाही</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store धोरणांमुळे, हे वैशिष्ट्य सध्याच्या बिल्डमध्ये समाविष्ट केले जाऊ शकत नाही. या कार्यक्षमतेमध्ये प्रवेश करण्यासाठी, कृपया वैकल्पिक स्रोतावरून इमेजटूलबॉक्स डाउनलोड करा. आपण खाली GitHub वर उपलब्ध बिल्ड शोधू शकता.</string>\n    <string name=\"open_github_page\">Github पृष्ठ उघडा</string>\n    <string name=\"overwrite_files_sub_short\">निवडलेल्या फोल्डरमध्ये सेव्ह करण्याऐवजी मूळ फाइल नवीन फाइलने बदलली जाईल</string>\n    <string name=\"hidden_watermark_text_detected\">लपवलेला वॉटरमार्क मजकूर आढळला</string>\n    <string name=\"hidden_watermark_image_detected\">लपलेली वॉटरमार्क प्रतिमा शोधली</string>\n    <string name=\"this_image_was_hidden\">ही प्रतिमा लपलेली होती</string>\n    <string name=\"generative_inpaint\">जनरेटिव्ह इनपेंटिंग</string>\n    <string name=\"generative_inpaint_sub\">OpenCV वर विसंबून न राहता, AI मॉडेलचा वापर करून इमेजमधील वस्तू काढण्याची तुम्हाला अनुमती देते. हे वैशिष्ट्य वापरण्यासाठी, ॲप GitHub वरून आवश्यक मॉडेल (~200 MB) डाउनलोड करेल</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV वर विसंबून न राहता, AI मॉडेलचा वापर करून इमेजमधील वस्तू काढण्याची तुम्हाला अनुमती देते. हे दीर्घकाळ चालणारे ऑपरेशन असू शकते</string>\n    <string name=\"error_level_analysis\">त्रुटी पातळी विश्लेषण</string>\n    <string name=\"luminance_gradient\">ल्युमिनन्स ग्रेडियंट</string>\n    <string name=\"average_distance\">सरासरी अंतर</string>\n    <string name=\"copy_move_detection\">कॉपी मूव्ह डिटेक्शन</string>\n    <string name=\"retain\">राखून ठेवा</string>\n    <string name=\"coefficent\">गुणांक</string>\n    <string name=\"clipboard_data_is_too_large\">क्लिपबोर्ड डेटा खूप मोठा आहे</string>\n    <string name=\"data_is_too_large_to_copy\">कॉपी करण्यासाठी डेटा खूप मोठा आहे</string>\n    <string name=\"simple_weave_pixelization\">साधे विणणे पिक्सेलीकरण</string>\n    <string name=\"staggered_pixelization\">स्टॅगर्ड पिक्सेलीकरण</string>\n    <string name=\"cross_pixelization\">क्रॉस पिक्सेलायझेशन</string>\n    <string name=\"micro_macro_pixelization\">मायक्रो मॅक्रो पिक्सेलायझेशन</string>\n    <string name=\"orbital_pixelization\">ऑर्बिटल पिक्सेलायझेशन</string>\n    <string name=\"vortex_pixelization\">व्होर्टेक्स पिक्सेलायझेशन</string>\n    <string name=\"pulse_grid_pixelization\">पल्स ग्रिड पिक्सेलायझेशन</string>\n    <string name=\"nucleus_pixelization\">न्यूक्लियस पिक्सेलायझेशन</string>\n    <string name=\"radial_weave_pixelization\">रेडियल विणणे पिक्सेलायझेशन</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\" उघडू शकत नाही</string>\n    <string name=\"snowfall_mode\">हिमवर्षाव मोड</string>\n    <string name=\"enabled\">सक्षम केले</string>\n    <string name=\"border_frame\">सीमा फ्रेम</string>\n    <string name=\"glitch_variant\">ग्लिच प्रकार</string>\n    <string name=\"channel_shift\">चॅनल शिफ्ट</string>\n    <string name=\"max_offset\">कमाल ऑफसेट</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">ब्लॉक ग्लिच</string>\n    <string name=\"block_size\">ब्लॉक आकार</string>\n    <string name=\"crt_curvature\">CRT वक्रता</string>\n    <string name=\"curvature\">वक्रता</string>\n    <string name=\"chroma\">क्रोमा</string>\n    <string name=\"pixel_melt\">पिक्सेल वितळणे</string>\n    <string name=\"max_drop\">कमाल ड्रॉप</string>\n    <string name=\"ai_tools\">एआय टूल्स</string>\n    <string name=\"ai_tools_sub\">AI मॉडेलद्वारे प्रतिमांवर प्रक्रिया करण्यासाठी विविध साधने जसे की आर्टिफॅक्ट काढून टाकणे किंवा डिनोइझिंग</string>\n    <string name=\"model_anime_undeint\">कॉम्प्रेशन, दातेरी रेषा</string>\n    <string name=\"model_broadcast\">व्यंगचित्रे, प्रसारण संक्षेप</string>\n    <string name=\"model_rgb_max_denoise_fp16\">सामान्य कम्प्रेशन, सामान्य आवाज</string>\n    <string name=\"model_wb_denoise\">रंगहीन कार्टूनचा आवाज</string>\n    <string name=\"model_span_anime_pretrain\">वेगवान, सामान्य कॉम्प्रेशन, सामान्य आवाज, ॲनिमेशन/कॉमिक्स/ॲनिमे</string>\n    <string name=\"model_book_scan\">पुस्तक स्कॅनिंग</string>\n    <string name=\"model_overexposure\">एक्सपोजर सुधारणा</string>\n    <string name=\"model_fbcnn_color_fp16\">सामान्य कॉम्प्रेशन, रंगीत प्रतिमांमध्ये सर्वोत्तम</string>\n    <string name=\"model_fbcnn_gray_fp16\">सामान्य कॉम्प्रेशन, ग्रेस्केल प्रतिमांमध्ये सर्वोत्तम</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">सामान्य कॉम्प्रेशन, ग्रेस्केल प्रतिमा, अधिक मजबूत</string>\n    <string name=\"model_scunet_color_gan_fp16\">सामान्य आवाज, रंगीत प्रतिमा</string>\n    <string name=\"model_scunet_color_psnr_fp16\">सामान्य आवाज, रंगीत प्रतिमा, चांगले तपशील</string>\n    <string name=\"model_scunet_gray_15_fp16\">सामान्य आवाज, ग्रेस्केल प्रतिमा</string>\n    <string name=\"model_scunet_gray_25_fp16\">सामान्य आवाज, ग्रेस्केल प्रतिमा, अधिक मजबूत</string>\n    <string name=\"model_scunet_gray_50_fp16\">सामान्य आवाज, ग्रेस्केल प्रतिमा, सर्वात मजबूत</string>\n    <string name=\"model_jpeg_destroyer\">सामान्य कम्प्रेशन</string>\n    <string name=\"model_jaywreck\">सामान्य कम्प्रेशन</string>\n    <string name=\"model_h264\">टेक्स्चरायझेशन, h264 कॉम्प्रेशन</string>\n    <string name=\"model_vhs\">व्हीएचएस कॉम्प्रेशन</string>\n    <string name=\"model_cinepak\">नॉन-स्टँडर्ड कॉम्प्रेशन (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">बिंक कॉम्प्रेशन, भूमितीवर चांगले</string>\n    <string name=\"model_debink_v5\">बिंक कॉम्प्रेशन, मजबूत</string>\n    <string name=\"model_debink_v6\">बिंक कॉम्प्रेशन, मऊ, तपशील राखून ठेवते</string>\n    <string name=\"model_antialias\">पायर्या-चरण प्रभाव काढून टाकणे, गुळगुळीत करणे</string>\n    <string name=\"model_kdm_scans\">स्कॅन केलेली कला/रेखाचित्रे, सौम्य कॉम्प्रेशन, मोअर</string>\n    <string name=\"model_bandage\">रंग बँडिंग</string>\n    <string name=\"model_halftone\">हळू, हाफटोन काढून टाकत आहे</string>\n    <string name=\"model_colorizer\">ग्रेस्केल/bw प्रतिमांसाठी सामान्य कलरलायझर, चांगल्या परिणामांसाठी DDCcolor वापरा</string>\n    <string name=\"model_deedge\">कडा काढणे</string>\n    <string name=\"model_desharpen\">ओव्हरशार्पनिंग काढून टाकते</string>\n    <string name=\"model_dither\">मंद, विचलित</string>\n    <string name=\"model_gainres\">अँटी-अलायझिंग, सामान्य कलाकृती, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 स्कॅन प्रक्रिया</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">लाइटवेट इमेज एन्हांसमेंट मॉडेल</string>\n    <string name=\"model_bcgone_detailed_v2\">कॉम्प्रेशन आर्टिफॅक्ट काढणे</string>\n    <string name=\"model_bcgone_smooth\">कॉम्प्रेशन आर्टिफॅक्ट काढणे</string>\n    <string name=\"model_bandage_smooth\">गुळगुळीत परिणामांसह मलमपट्टी काढणे</string>\n    <string name=\"model_bendel_halftone\">हाफटोन नमुना प्रक्रिया</string>\n    <string name=\"model_dither_deleter_v3_smooth\">डिथर नमुना काढणे V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG आर्टिफॅक्ट काढणे V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 पोत वाढवणे</string>\n    <string name=\"model_vhs_sharpen\">VHS शार्पनिंग आणि एन्हांसमेंट</string>\n    <string name=\"merging\">विलीन होत आहे</string>\n    <string name=\"chunk_size\">भाग आकार</string>\n    <string name=\"overlap_size\">ओव्हरलॅप आकार</string>\n    <string name=\"note_chunk_info\">%1$s px पेक्षा जास्त प्रतिमा कापल्या जातील आणि भागांमध्ये प्रक्रिया केल्या जातील, दृश्यमान शिवण टाळण्यासाठी त्यांना ओव्हरलॅप मिश्रित करते.</string>\n    <string name=\"large_chunk_warning\">मोठ्या आकारामुळे लो-एंड डिव्हाइसेससह अस्थिरता येऊ शकते</string>\n    <string name=\"select_one_to_start\">सुरू करण्यासाठी एक निवडा</string>\n    <string name=\"delete_model_sub\">तुम्ही %1$s मॉडेल हटवू इच्छिता? तुम्हाला ते पुन्हा डाउनलोड करावे लागेल</string>\n    <string name=\"confirm\">पुष्टी करा</string>\n    <string name=\"models\">मॉडेल्स</string>\n    <string name=\"downloaded_models\">डाउनलोड केलेले मॉडेल</string>\n    <string name=\"available_models\">उपलब्ध मॉडेल्स</string>\n    <string name=\"preparing\">तयारी करत आहे</string>\n    <string name=\"active_model\">सक्रिय मॉडेल</string>\n    <string name=\"failed_to_open_session\">सत्र उघडण्यात अयशस्वी</string>\n    <string name=\"only_onnx_models\">फक्त .onnx/.ort मॉडेल आयात केले जाऊ शकतात</string>\n    <string name=\"import_model\">मॉडेल आयात करा</string>\n    <string name=\"import_model_sub\">पुढील वापरासाठी सानुकूल onnx मॉडेल आयात करा, फक्त onnx/ort मॉडेल स्वीकारले जातात, जवळजवळ सर्व esrgan सारख्या प्रकारांना समर्थन देते</string>\n    <string name=\"imported_models\">आयात केलेले मॉडेल</string>\n    <string name=\"model_scunet_color_15_fp16\">सामान्य आवाज, रंगीत प्रतिमा</string>\n    <string name=\"model_scunet_color_25_fp16\">सामान्य आवाज, रंगीत प्रतिमा, अधिक मजबूत</string>\n    <string name=\"model_scunet_color_50_fp16\">सामान्य आवाज, रंगीत प्रतिमा, सर्वात मजबूत</string>\n    <string name=\"model_artifacts_dithering_alsa\">डिथरिंग आर्टिफॅक्ट्स आणि कलर बँडिंग कमी करते, गुळगुळीत ग्रेडियंट आणि सपाट रंग क्षेत्र सुधारते.</string>\n    <string name=\"model_nmkd_brighten_redux\">नैसर्गिक रंग जतन करून संतुलित हायलाइटसह प्रतिमेची चमक आणि कॉन्ट्रास्ट वाढवते.</string>\n    <string name=\"model_nmkd_brighten\">तपशील ठेवताना आणि जास्त एक्सपोजर टाळताना गडद प्रतिमा उजळतात.</string>\n    <string name=\"model_nmkd_detoon\">अत्यधिक रंग टोनिंग काढून टाकते आणि अधिक तटस्थ आणि नैसर्गिक रंग संतुलन पुनर्संचयित करते.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">बारीक तपशील आणि पोत जतन करण्यावर भर देऊन पॉसॉन-आधारित आवाज टोनिंग लागू करते.</string>\n    <string name=\"model_noise_toner_poisson_soft\">नितळ आणि कमी आक्रमक व्हिज्युअल परिणामांसाठी सॉफ्ट पॉसॉन नॉइज टोनिंग लागू करते.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">एकसमान आवाज टोनिंग तपशील संरक्षण आणि प्रतिमा स्पष्टतेवर केंद्रित आहे.</string>\n    <string name=\"model_noise_toner_uniform_soft\">सूक्ष्म पोत आणि गुळगुळीत दिसण्यासाठी सौम्य एकसमान आवाज टोनिंग.</string>\n    <string name=\"model_repainter\">कलाकृती पुन्हा रंगवून आणि प्रतिमा सुसंगतता सुधारून खराब झालेले किंवा असमान भाग दुरुस्त करा.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">लाइटवेट डीबँडिंग मॉडेल जे कमीतकमी कार्यप्रदर्शन खर्चासह रंग बँडिंग काढून टाकते.</string>\n    <string name=\"model_jpeg_0_20\">सुधारित स्पष्टतेसाठी अतिशय उच्च कॉम्प्रेशन आर्टिफॅक्ट (0-20% गुणवत्ता) असलेल्या प्रतिमा ऑप्टिमाइझ करते.</string>\n    <string name=\"model_jpeg_20_40\">उच्च कॉम्प्रेशन आर्टिफॅक्ट्स (20-40% गुणवत्ता), तपशील पुनर्संचयित करून आणि आवाज कमी करून प्रतिमा सुधारते.</string>\n    <string name=\"model_jpeg_40_60\">मध्यम कम्प्रेशन (40-60% गुणवत्ता) सह प्रतिमा सुधारते, तीक्ष्णता आणि गुळगुळीतपणा संतुलित करते.</string>\n    <string name=\"model_jpeg_60_80\">सूक्ष्म तपशील आणि पोत वर्धित करण्यासाठी प्रकाश कॉम्प्रेशन (60-80% गुणवत्ता) सह प्रतिमा परिष्कृत करते.</string>\n    <string name=\"model_jpeg_80_100\">नैसर्गिक देखावा आणि तपशील जतन करून जवळच्या-तोटारहित प्रतिमा (80-100% गुणवत्ता) किंचित वाढवते.</string>\n    <string name=\"model_spongecolor_lite\">साधे आणि जलद रंगीकरण, व्यंगचित्रे, आदर्श नाही</string>\n    <string name=\"model_deblr\">प्रतिमेची अस्पष्टता किंचित कमी करते, कलाकृतींचा परिचय न करता तीक्ष्णता सुधारते.</string>\n    <string name=\"processing_channel\">लांब चालणारी ऑपरेशन्स</string>\n    <string name=\"processing_image\">इमेजवर प्रक्रिया करत आहे</string>\n    <string name=\"processing\">प्रक्रिया करत आहे</string>\n    <string name=\"model_artifacts_jpg_0_20\">अत्यंत कमी गुणवत्तेच्या (0-20%) प्रतिमांमधील भारी JPEG कॉम्प्रेशन आर्टिफॅक्ट्स काढून टाकते.</string>\n    <string name=\"model_artifacts_jpg_20_40\">अत्यंत संकुचित प्रतिमा (20-40%) मध्ये मजबूत JPEG कलाकृती कमी करते.</string>\n    <string name=\"model_artifacts_jpg_40_60\">प्रतिमा तपशील (40-60%) जतन करताना मध्यम JPEG कलाकृती साफ करते.</string>\n    <string name=\"model_artifacts_jpg_60_80\">हलक्या JPEG कलाकृतींना उच्च दर्जाच्या प्रतिमांमध्ये परिष्कृत करते (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">जवळच्या-तोटारहित प्रतिमांमध्ये (80-100%) किरकोळ JPEG कलाकृती सूक्ष्मपणे कमी करते.</string>\n    <string name=\"model_redetail_v2\">बारीक तपशील आणि पोत वाढवते, जड कलाकृतींशिवाय समजलेली तीक्ष्णता सुधारते.</string>\n    <string name=\"processing_finished\">प्रक्रिया पूर्ण झाली</string>\n    <string name=\"processing_failed\">प्रक्रिया अयशस्वी</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">नैसर्गिक देखावा ठेवताना त्वचेचे पोत आणि तपशील वाढवते, गतीसाठी अनुकूल.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG कॉम्प्रेशन आर्टिफॅक्ट्स काढून टाकते आणि कॉम्प्रेस केलेल्या फोटोंसाठी इमेज क्वालिटी रिस्टोअर करते.</string>\n    <string name=\"model_iso_denoise_v1\">कमी प्रकाशाच्या स्थितीत घेतलेल्या फोटोंमधील ISO आवाज कमी करते, तपशील जतन करते.</string>\n    <string name=\"model_dejumbo\">ओव्हरएक्सपोज केलेले किंवा \\\"जंबो\\\" हायलाइट्स दुरुस्त करते आणि चांगले टोनल बॅलन्स पुनर्संचयित करते.</string>\n    <string name=\"model_ddcolor_tiny\">हलके आणि जलद रंगीकरण मॉडेल जे ग्रेस्केल प्रतिमांमध्ये नैसर्गिक रंग जोडते.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">रंगीत करा</string>\n    <string name=\"type_artifacts\">कलाकृती</string>\n    <string name=\"type_enhance\">वर्धित करा</string>\n    <string name=\"type_anime\">ॲनिमी</string>\n    <string name=\"type_scans\">स्कॅन करा</string>\n    <string name=\"type_upscale\">अपस्केल</string>\n    <string name=\"model_realesrgan_x4v3\">सामान्य प्रतिमांसाठी X4 अपस्केलर; लहान मॉडेल जे कमी GPU आणि वेळ वापरते, मध्यम deblur आणि denoise सह.</string>\n    <string name=\"model_realesrgan_x2plus\">सामान्य प्रतिमांसाठी X2 अपस्केलर, पोत आणि नैसर्गिक तपशील जतन.</string>\n    <string name=\"model_realesrgan_x4plus\">वर्धित पोत आणि वास्तववादी परिणामांसह सामान्य प्रतिमांसाठी X4 अपस्केलर.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">ऍनिम ​​प्रतिमांसाठी एक्स 4 अपस्केलर ऑप्टिमाइझ; तीक्ष्ण रेषा आणि तपशीलांसाठी 6 RRDB ब्लॉक.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE नुकसानासह X4 अपस्केलर, सामान्य प्रतिमांसाठी नितळ परिणाम आणि कमी कलाकृती निर्माण करतो.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">एक्स 4 अपस्केलर ॲनिम प्रतिमांसाठी अनुकूलित; तीक्ष्ण तपशील आणि गुळगुळीत रेषांसह 4B32F प्रकार.</string>\n    <string name=\"model_ultrasharp_v2_x4\">सामान्य प्रतिमांसाठी X4 UltraSharp V2 मॉडेल; तीक्ष्णता आणि स्पष्टतेवर जोर देते.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 अल्ट्राशार्प V2 लाइट; वेगवान आणि लहान, कमी GPU मेमरी वापरताना तपशील जतन करते.</string>\n    <string name=\"model_rmbg_1_4\">द्रुत पार्श्वभूमी काढण्यासाठी हलके मॉडेल. संतुलित कामगिरी आणि अचूकता. पोर्ट्रेट, वस्तू आणि दृश्यांसह कार्य करते. बहुतेक वापराच्या प्रकरणांसाठी शिफारस केलेले.</string>\n    <string name=\"type_removebg\">बीजी काढा</string>\n    <string name=\"horizontal_border_thickness\">क्षैतिज सीमा जाडी</string>\n    <string name=\"vertical_border_thickness\">अनुलंब सीमा जाडी</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s रंग</item>\n        <item quantity=\"other\">%1$s रंग</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">वर्तमान मॉडेल चंकिंगला समर्थन देत नाही, प्रतिमेवर मूळ परिमाणांमध्ये प्रक्रिया केली जाईल, यामुळे उच्च मेमरी वापर आणि लो-एंड उपकरणांसह समस्या उद्भवू शकतात</string>\n    <string name=\"chunking_disabled\">चंकिंग अक्षम केले आहे, प्रतिमेवर मूळ परिमाणांमध्ये प्रक्रिया केली जाईल, यामुळे उच्च मेमरी वापर आणि कमी-अंत उपकरणांसह समस्या उद्भवू शकतात परंतु अनुमानांवर चांगले परिणाम देऊ शकतात</string>\n    <string name=\"chunking\">चंकिंग</string>\n    <string name=\"model_u2net\">पार्श्वभूमी काढण्यासाठी उच्च-अचूकता प्रतिमा विभाजन मॉडेल</string>\n    <string name=\"model_u2netp\">लहान मेमरी वापरासह जलद पार्श्वभूमी काढण्यासाठी U2Net ची हलकी आवृत्ती.</string>\n    <string name=\"model_ddcolor\">पूर्ण DDCcolor मॉडेल किमान कलाकृतींसह सामान्य प्रतिमांसाठी उच्च-गुणवत्तेचे रंगीकरण प्रदान करते. सर्व रंगीकरण मॉडेल्सची सर्वोत्तम निवड.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor प्रशिक्षित आणि खाजगी कलात्मक डेटासेट; कमी अवास्तव कलर आर्टिफॅक्ट्ससह वैविध्यपूर्ण आणि कलात्मक रंगीकरण परिणाम तयार करते.</string>\n    <string name=\"model_birefnet\">अचूक पार्श्वभूमी काढण्यासाठी स्विन ट्रान्सफॉर्मरवर आधारित लाइटवेट BiRefNet मॉडेल.</string>\n    <string name=\"model_inspyrenet\">तीक्ष्ण कडा आणि उत्कृष्ट तपशील संरक्षणासह उच्च-गुणवत्तेची पार्श्वभूमी काढणे, विशेषत: जटिल वस्तू आणि अवघड पार्श्वभूमीवर.</string>\n    <string name=\"model_isnet\">पार्श्वभूमी काढण्याचे मॉडेल जे गुळगुळीत कडा असलेले अचूक मुखवटे तयार करते, सामान्य वस्तूंसाठी योग्य आणि मध्यम तपशील संरक्षण.</string>\n    <string name=\"model_already_downloaded\">मॉडेल आधीच डाउनलोड केले आहे</string>\n    <string name=\"model_successfully_imported\">मॉडेल यशस्वीरित्या आयात केले</string>\n    <string name=\"type\">प्रकार</string>\n    <string name=\"keyword\">कीवर्ड</string>\n    <string name=\"very_fast\">खूप जलद</string>\n    <string name=\"normal\">सामान्य</string>\n    <string name=\"slow\">मंद</string>\n    <string name=\"very_slow\">खूप हळू</string>\n    <string name=\"compute_percents\">टक्केवारीची गणना करा</string>\n    <string name=\"minimum_value_is\">किमान मूल्य %1$s आहे</string>\n    <string name=\"warp_sub\">बोटांनी रेखाटून प्रतिमा विकृत करा</string>\n    <string name=\"warp\">ताना</string>\n    <string name=\"hardness\">कडकपणा</string>\n    <string name=\"warp_mode\">वार्प मोड</string>\n    <string name=\"warp_mode_move\">हलवा</string>\n    <string name=\"warp_mode_grow\">वाढतात</string>\n    <string name=\"warp_mode_shrink\">संकुचित करा</string>\n    <string name=\"warp_mode_swirl_cw\">फिरणे CW</string>\n    <string name=\"warp_mode_swirl_ccw\">फिरणे CCW</string>\n    <string name=\"fade_strength\">फिकट ताकद</string>\n    <string name=\"top_drop\">शीर्ष ड्रॉप</string>\n    <string name=\"bottom_drop\">तळ ड्रॉप</string>\n    <string name=\"start_drop\">ड्रॉप सुरू करा</string>\n    <string name=\"end_drop\">समाप्ती ड्रॉप</string>\n    <string name=\"downloading\">डाउनलोड करत आहे</string>\n    <string name=\"smooth_shapes\">गुळगुळीत आकार</string>\n    <string name=\"smooth_shapes_sub\">गुळगुळीत, अधिक नैसर्गिक आकारांसाठी मानक गोलाकार आयतांऐवजी सुपरएलिप्स वापरा</string>\n    <string name=\"shape_type\">आकार प्रकार</string>\n    <string name=\"cut\">कट</string>\n    <string name=\"rounded\">गोलाकार</string>\n    <string name=\"smooth\">गुळगुळीत</string>\n    <string name=\"cut_shapes_sub\">गोलाकार न करता तीक्ष्ण कडा</string>\n    <string name=\"rounded_shapes_sub\">क्लासिक गोलाकार कोपरे</string>\n    <string name=\"shapes_type\">आकार प्रकार</string>\n    <string name=\"corners_size\">कोपऱ्यांचा आकार</string>\n    <string name=\"squircle\">गिलहरी</string>\n    <string name=\"squircle_shapes_sub\">मोहक गोलाकार UI घटक</string>\n    <string name=\"filename_format\">फाइलनाव स्वरूप</string>\n    <string name=\"prefix_pattern_description\">सानुकूल मजकूर फाइल नावाच्या अगदी सुरुवातीला ठेवलेला आहे, प्रकल्प नावे, ब्रँड किंवा वैयक्तिक टॅगसाठी योग्य.</string>\n    <string name=\"original_filename_pattern_description\">मूळ फाइल नाव विस्ताराशिवाय वापरते, तुम्हाला स्त्रोत ओळख अबाधित ठेवण्यास मदत करते.</string>\n    <string name=\"width_pattern_description\">प्रतिमेची रुंदी पिक्सेलमध्ये, रिझोल्यूशन बदलांचा मागोवा घेण्यासाठी किंवा परिणाम स्केलिंगसाठी उपयुक्त.</string>\n    <string name=\"height_pattern_description\">प्रतिमेची उंची पिक्सेलमध्ये, गुणोत्तर किंवा निर्यातीसह कार्य करताना उपयुक्त.</string>\n    <string name=\"random_numbers_pattern_description\">अद्वितीय फाइलनावांची हमी देण्यासाठी यादृच्छिक अंक व्युत्पन्न करते; डुप्लिकेट विरूद्ध अतिरिक्त सुरक्षिततेसाठी अधिक अंक जोडा.</string>\n    <string name=\"sequence_number_pattern_description\">बॅच निर्यातीसाठी स्वयं-वाढीव काउंटर, एका सत्रात एकाधिक प्रतिमा जतन करताना आदर्श.</string>\n    <string name=\"preset_info_pattern_description\">फाइलनावामध्ये लागू केलेले प्रीसेट नाव समाविष्ट करते जेणेकरुन तुम्ही इमेजवर प्रक्रिया कशी केली हे सहज लक्षात ठेवू शकता.</string>\n    <string name=\"scale_mode_pattern_description\">प्रक्रिया करताना वापरलेला प्रतिमा स्केलिंग मोड प्रदर्शित करते, आकार बदललेल्या, क्रॉप केलेल्या किंवा फिट केलेल्या प्रतिमा वेगळे करण्यात मदत करते.</string>\n    <string name=\"suffix_pattern_description\">फाइल नावाच्या शेवटी ठेवलेला सानुकूल मजकूर, _v2, _edited किंवा _final सारख्या आवृत्तीसाठी उपयुक्त.</string>\n    <string name=\"extension_pattern_description\">फाइल विस्तार (png, jpg, webp, इ.), वास्तविक जतन केलेल्या स्वरूपाशी स्वयंचलितपणे जुळणारा.</string>\n    <string name=\"formatted_timestamp_pattern_description\">एक सानुकूल करण्यायोग्य टाइमस्टॅम्प जो तुम्हाला परिपूर्ण क्रमवारीसाठी जावा विनिर्देशानुसार तुमचे स्वतःचे स्वरूप परिभाषित करू देतो.</string>\n    <string name=\"fling_type\">फ्लिंग प्रकार</string>\n    <string name=\"android_native\">Android नेटिव्ह</string>\n    <string name=\"ios_style\">iOS शैली</string>\n    <string name=\"smooth_curve\">गुळगुळीत वक्र</string>\n    <string name=\"quick_stop\">द्रुत थांबा</string>\n    <string name=\"bouncy\">उछाल</string>\n    <string name=\"floaty\">फ्लोटी</string>\n    <string name=\"snappy\">स्नॅपी</string>\n    <string name=\"ultra_smooth\">अल्ट्रा स्मूथ</string>\n    <string name=\"adaptive\">अनुकूल</string>\n    <string name=\"accessibility_aware\">प्रवेशयोग्यता जागरूक</string>\n    <string name=\"reduced_motion\">कमी गती</string>\n    <string name=\"android_native_sub\">मूळ Android स्क्रोल भौतिकशास्त्र</string>\n    <string name=\"smooth_sub\">सामान्य वापरासाठी संतुलित, गुळगुळीत स्क्रोलिंग</string>\n    <string name=\"ios_style_sub\">उच्च घर्षण iOS-सारखे स्क्रोल वर्तन</string>\n    <string name=\"smooth_curve_sub\">वेगळ्या स्क्रोल अनुभवासाठी अद्वितीय स्प्लाइन वक्र</string>\n    <string name=\"quick_stop_sub\">द्रुत थांबा सह अचूक स्क्रोलिंग</string>\n    <string name=\"bouncy_sub\">खेळकर, प्रतिसाद देणारा बाऊन्सी स्क्रोल</string>\n    <string name=\"floaty_sub\">सामग्री ब्राउझिंगसाठी लांब, ग्लाइडिंग स्क्रोल</string>\n    <string name=\"snappy_sub\">परस्परसंवादी UI साठी द्रुत, प्रतिसादात्मक स्क्रोलिंग</string>\n    <string name=\"ultra_smooth_sub\">विस्तारित गतीसह प्रीमियम गुळगुळीत स्क्रोलिंग</string>\n    <string name=\"adaptive_sub\">फ्लिंग वेगावर आधारित भौतिकशास्त्र समायोजित करते</string>\n    <string name=\"accessibility_aware_sub\">सिस्टम प्रवेशयोग्यता सेटिंग्जचा आदर करते</string>\n    <string name=\"reduced_motion_sub\">प्रवेशयोग्यता गरजांसाठी किमान गती</string>\n    <string name=\"primary_lines\">प्राथमिक ओळी</string>\n    <string name=\"primary_lines_sub\">प्रत्येक पाचव्या ओळीत जाड ओळ जोडते</string>\n    <string name=\"fill_color\">रंग भरा</string>\n    <string name=\"hidden_tools\">लपलेली साधने</string>\n    <string name=\"hidden_for_share\">शेअरसाठी लपवलेली साधने</string>\n    <string name=\"color_library\">रंगीत लायब्ररी</string>\n    <string name=\"color_library_sub\">रंगांचा एक विशाल संग्रह ब्राउझ करा</string>\n    <string name=\"model_fatality_deblur\">नैसर्गिक तपशिलांची देखभाल करताना प्रतिमांना तीक्ष्ण करते आणि अस्पष्टता काढून टाकते, फोकस नसलेले फोटो निश्चित करण्यासाठी आदर्श.</string>\n    <string name=\"model_unresize_v3\">पूर्वी आकार बदललेल्या प्रतिमा हुशारीने पुनर्संचयित करते, गमावलेले तपशील आणि पोत पुनर्प्राप्त करते.</string>\n    <string name=\"model_liveaction_v1_span\">लाइव्ह-ॲक्शन सामग्रीसाठी ऑप्टिमाइझ केलेले, कॉम्प्रेशन आर्टिफॅक्ट्स कमी करते आणि मूव्ही/टीव्ही शो फ्रेममधील बारीकसारीक तपशील वाढवते.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS-गुणवत्तेचे फुटेज HD मध्ये रूपांतरित करते, टेपचा आवाज काढून टाकते आणि विंटेज फील जतन करून रिझोल्यूशन वाढवते.</string>\n    <string name=\"model_text2hd_v1\">मजकूर-भारी प्रतिमा आणि स्क्रीनशॉटसाठी खास, वर्ण धारदार करते आणि वाचनीयता सुधारते.</string>\n    <string name=\"model_frankendata_pretrainer\">विविध डेटासेटवर प्रशिक्षित प्रगत अपस्केलिंग, सामान्य-उद्देश फोटो वर्धित करण्यासाठी उत्कृष्ट.</string>\n    <string name=\"model_realwebphoto_v2\">वेब-संकुचित फोटोंसाठी ऑप्टिमाइझ केलेले, JPEG कलाकृती काढून टाकते आणि नैसर्गिक स्वरूप पुनर्संचयित करते.</string>\n    <string name=\"model_realwebphoto_v4\">वेब फोटोंसाठी सुधारित आवृत्ती उत्तम पोत संरक्षण आणि कलाकृती कमी करणे.</string>\n    <string name=\"model_dat_2x\">ड्युअल एग्रीगेशन ट्रान्सफॉर्मर तंत्रज्ञानासह 2x अपस्केलिंग, तीक्ष्णता आणि नैसर्गिक तपशील राखते.</string>\n    <string name=\"model_dat_3x\">प्रगत ट्रान्सफॉर्मर आर्किटेक्चरचा वापर करून 3x अपस्केलिंग, मध्यम विस्तार गरजांसाठी आदर्श.</string>\n    <string name=\"model_dat_4x\">अत्याधुनिक ट्रान्सफॉर्मर नेटवर्कसह 4x उच्च-गुणवत्तेचे अपस्केलिंग, मोठ्या प्रमाणात सूक्ष्म तपशील जतन करते.</string>\n    <string name=\"model_nafnet_deblurring\">फोटोंमधून अस्पष्टता/आवाज आणि शेक काढून टाकते. सामान्य हेतू परंतु फोटोंसाठी सर्वोत्तम.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Swin2SR ट्रान्सफॉर्मर वापरून कमी-गुणवत्तेच्या प्रतिमा पुनर्संचयित करते, BSRGAN डिग्रेडेशनसाठी ऑप्टिमाइझ केलेले. हेवी कॉम्प्रेशन आर्टिफॅक्ट्स निश्चित करण्यासाठी आणि 4x स्केलवर तपशील वाढविण्यासाठी उत्तम.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN डिग्रेडेशनवर प्रशिक्षित स्विनआयआर ट्रान्सफॉर्मरसह 4x अपस्केलिंग. फोटो आणि जटिल दृश्यांमध्ये तीक्ष्ण पोत आणि अधिक नैसर्गिक तपशीलांसाठी GAN वापरते.</string>\n    <string name=\"path\">मार्ग</string>\n    <string name=\"merge_pdf\">पीडीएफ मर्ज करा</string>\n    <string name=\"merge_pdf_sub\">एका दस्तऐवजात अनेक पीडीएफ फाइल्स एकत्र करा</string>\n    <string name=\"files_order\">फाईल्स ऑर्डर</string>\n    <string name=\"pages_short\">pp</string>\n    <string name=\"split_pdf\">पीडीएफ विभाजित करा</string>\n    <string name=\"split_pdf_sub\">पीडीएफ दस्तऐवजातून विशिष्ट पृष्ठे काढा</string>\n    <string name=\"rotate_pdf\">पीडीएफ फिरवा</string>\n    <string name=\"rotate_pdf_sub\">पृष्ठ अभिमुखता कायमचे निश्चित करा</string>\n    <string name=\"pages\">पृष्ठे</string>\n    <string name=\"rearrange_pdf\">पीडीएफची पुनर्रचना करा</string>\n    <string name=\"rearrange_pdf_sub\">पृष्ठे पुन्हा क्रमाने लावण्यासाठी ड्रॅग आणि ड्रॉप करा</string>\n    <string name=\"hold_drag_drop\">पृष्ठे धरा आणि ड्रॅग करा</string>\n    <string name=\"page_numbers\">पृष्ठ क्रमांक</string>\n    <string name=\"page_numbers_sub\">तुमच्या दस्तऐवजांमध्ये आपोआप क्रमांकन जोडा</string>\n    <string name=\"label_format\">लेबल स्वरूप</string>\n    <string name=\"pdf_to_text\">PDF टू टेक्स्ट (OCR)</string>\n    <string name=\"pdf_to_text_sub\">तुमच्या PDF दस्तऐवजांमधून साधा मजकूर काढा</string>\n    <string name=\"watermark_pdf_sub\">ब्रँडिंग किंवा सुरक्षिततेसाठी सानुकूल मजकूर आच्छादित करा</string>\n    <string name=\"signature\">स्वाक्षरी</string>\n    <string name=\"signature_sub\">कोणत्याही दस्तऐवजात तुमची इलेक्ट्रॉनिक स्वाक्षरी जोडा</string>\n    <string name=\"will_be_for_signature\">हे स्वाक्षरी म्हणून वापरले जाईल</string>\n    <string name=\"unlock_pdf\">पीडीएफ अनलॉक करा</string>\n    <string name=\"unlock_pdf_sub\">तुमच्या संरक्षित फाइल्समधून पासवर्ड काढा</string>\n    <string name=\"protect_pdf\">पीडीएफ संरक्षित करा</string>\n    <string name=\"protect_pdf_sub\">मजबूत एन्क्रिप्शनसह तुमचे दस्तऐवज सुरक्षित करा</string>\n    <string name=\"success\">यश</string>\n    <string name=\"pdf_unlocked\">पीडीएफ अनलॉक, तुम्ही सेव्ह किंवा शेअर करू शकता</string>\n    <string name=\"repair_pdf\">पीडीएफ दुरुस्त करा</string>\n    <string name=\"repair_pdf_sub\">खराब झालेले किंवा न वाचलेले दस्तऐवज दुरुस्त करण्याचा प्रयत्न</string>\n    <string name=\"grayscale\">ग्रेस्केल</string>\n    <string name=\"grayscale_pdf_sub\">सर्व दस्तऐवज एम्बेड केलेल्या प्रतिमा ग्रेस्केलमध्ये रूपांतरित करा</string>\n    <string name=\"compress_pdf\">पीडीएफ कॉम्प्रेस करा</string>\n    <string name=\"compress_pdf_sub\">सुलभ सामायिकरणासाठी तुमचा दस्तऐवज फाइल आकार ऑप्टिमाइझ करा</string>\n    <string name=\"repair_info\">इमेजटूलबॉक्स अंतर्गत क्रॉस-रेफरन्स टेबलची पुनर्बांधणी करते आणि स्क्रॅचमधून फाइल संरचना पुन्हा निर्माण करते. हे \\\\\"उघडले जाऊ शकत नाही\\\\\" अशा अनेक फाइल्समध्ये प्रवेश पुनर्संचयित करू शकते.</string>\n    <string name=\"grayscale_info\">हे साधन सर्व दस्तऐवज प्रतिमा ग्रेस्केलमध्ये रूपांतरित करते. मुद्रित करण्यासाठी आणि फाइल आकार कमी करण्यासाठी सर्वोत्तम</string>\n    <string name=\"metadata\">मेटाडेटा</string>\n    <string name=\"metadata_pdf_sub\">चांगल्या गोपनीयतेसाठी दस्तऐवज गुणधर्म संपादित करा</string>\n    <string name=\"tags\">टॅग्ज</string>\n    <string name=\"producer\">निर्माता</string>\n    <string name=\"author\">लेखक</string>\n    <string name=\"keywords\">कीवर्ड</string>\n    <string name=\"creator\">निर्माता</string>\n    <string name=\"privacy_deep_clean\">गोपनीयता खोल स्वच्छ</string>\n    <string name=\"privacy_deep_clean_sub\">या दस्तऐवजासाठी सर्व उपलब्ध मेटाडेटा साफ करा</string>\n    <string name=\"page\">पान</string>\n    <string name=\"deep_ocr\">खोल OCR</string>\n    <string name=\"deep_ocr_sub\">दस्तऐवजातून मजकूर काढा आणि टेसरॅक्ट इंजिन वापरून एका मजकूर फाइलमध्ये संग्रहित करा</string>\n    <string name=\"cant_remove_all\">सर्व पृष्ठे काढू शकत नाही</string>\n    <string name=\"remove_pages_pdf\">PDF पृष्ठे काढा</string>\n    <string name=\"remove_pages_pdf_sub\">पीडीएफ दस्तऐवजातून विशिष्ट पृष्ठे काढा</string>\n    <string name=\"tap_to_remove\">काढण्यासाठी टॅप करा</string>\n    <string name=\"manually\">स्वहस्ते</string>\n    <string name=\"crop_pdf\">पीडीएफ क्रॉप करा</string>\n    <string name=\"crop_pdf_sub\">दस्तऐवजाची पृष्ठे कोणत्याही मर्यादेपर्यंत क्रॉप करा</string>\n    <string name=\"flatten_pdf\">सपाट पीडीएफ</string>\n    <string name=\"flatten_pdf_sub\">दस्तऐवजाची पृष्ठे रास्टर करून PDF बदलण्यायोग्य बनवा</string>\n    <string name=\"camera_failed_to_open\">कॅमेरा सुरू करू शकलो नाही. कृपया परवानग्या तपासा आणि ते दुसऱ्या ॲपद्वारे वापरले जात नसल्याचे सुनिश्चित करा.</string>\n    <string name=\"extract_images\">प्रतिमा काढा</string>\n    <string name=\"extract_images_sub\">PDF मध्ये एम्बेड केलेल्या प्रतिमा त्यांच्या मूळ रिझोल्यूशनवर काढा</string>\n    <string name=\"pdf_no_embedded\">या PDF फाइलमध्ये कोणत्याही एम्बेड केलेल्या प्रतिमा नाहीत</string>\n    <string name=\"extract_images_info\">हे साधन प्रत्येक पृष्ठ स्कॅन करते आणि पूर्ण-गुणवत्तेच्या स्त्रोत प्रतिमा पुनर्प्राप्त करते — दस्तऐवजांमधून मूळ जतन करण्यासाठी योग्य</string>\n    <string name=\"draw_signature\">स्वाक्षरी काढा</string>\n    <string name=\"pen_params\">पेन परम्स</string>\n    <string name=\"draw_signature_sub\">दस्तऐवजांवर ठेवण्यासाठी प्रतिमा म्हणून स्वतःची स्वाक्षरी वापरा</string>\n    <string name=\"zip_pdf\">झिप पीडीएफ</string>\n    <string name=\"zip_pdf_sub\">दिलेल्या मध्यांतरासह दस्तऐवज विभाजित करा आणि नवीन दस्तऐवज झिप आर्काइव्हमध्ये पॅक करा</string>\n    <string name=\"interval\">मध्यांतर</string>\n    <string name=\"print_pdf\">PDF प्रिंट करा</string>\n    <string name=\"print_pdf_sub\">सानुकूल पृष्ठ आकारासह मुद्रणासाठी दस्तऐवज तयार करा</string>\n    <string name=\"pages_per_sheet\">प्रति पत्रक पृष्ठे</string>\n    <string name=\"orientation\">अभिमुखता</string>\n    <string name=\"page_size\">पृष्ठ आकार</string>\n    <string name=\"margin\">समास</string>\n    <string name=\"bloom\">तजेला</string>\n    <string name=\"soft_knee\">मऊ गुडघा</string>\n    <string name=\"model_realesr_animevideo_v3x4\">ॲनिम आणि कार्टूनसाठी ऑप्टिमाइझ केलेले. सुधारित नैसर्गिक रंग आणि कमी कलाकृतींसह जलद अपस्केलिंग</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 सारखी शैली</string>\n    <string name=\"calculate_hint\">इच्छित मूल्याची गणना करण्यासाठी येथे मूलभूत गणित चिन्हे प्रविष्ट करा (उदा. (5+5)*10)</string>\n    <string name=\"math_expression\">गणित अभिव्यक्ती</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s पर्यंत प्रतिमा घ्या</string>\n    <string name=\"keep_date_time\">तारीख वेळ ठेवा</string>\n    <string name=\"keep_date_time_sub\">तारीख आणि वेळेशी संबंधित exif टॅग नेहमी जतन करा, Keep exif पर्यायापेक्षा स्वतंत्रपणे कार्य करते</string>\n    <string name=\"background_color_for_alpha_formats\">अल्फा स्वरूपांसाठी पार्श्वभूमी रंग</string>\n    <string name=\"background_color_for_alpha_formats_sub\">अल्फा सपोर्टसह प्रत्येक इमेज फॉरमॅटसाठी पार्श्वभूमी रंग सेट करण्याची क्षमता जोडते, जेव्हा हे अक्षम केले जाते तेव्हा हे केवळ अल्फा नसलेल्यांसाठी उपलब्ध असते</string>\n    <string name=\"open_markup_project\">प्रकल्प उघडा</string>\n    <string name=\"open_markup_project_sub\">पूर्वी जतन केलेला प्रतिमा टूलबॉक्स प्रकल्प संपादित करणे सुरू ठेवा</string>\n    <string name=\"markup_project_open_failed\">इमेज टूलबॉक्स प्रोजेक्ट उघडण्यात अक्षम</string>\n    <string name=\"markup_project_missing_data\">इमेज टूलबॉक्स प्रोजेक्टमध्ये प्रोजेक्ट डेटा गहाळ आहे</string>\n    <string name=\"markup_project_corrupted\">इमेज टूलबॉक्स प्रोजेक्ट दूषित झाला आहे</string>\n    <string name=\"unsupported_markup_project_version\">असमर्थित प्रतिमा टूलबॉक्स प्रकल्प आवृत्ती: %1$d</string>\n    <string name=\"save_markup_project\">प्रकल्प जतन करा</string>\n    <string name=\"save_markup_project_sub\">संपादन करण्यायोग्य प्रकल्प फाइलमध्ये स्तर, पार्श्वभूमी आणि संपादित इतिहास संग्रहित करा</string>\n    <string name=\"failed_to_open\">उघडण्यात अयशस्वी</string>\n    <string name=\"ocr_write_to_searchable_pdf\">शोधण्यायोग्य PDF वर लिहा</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">इमेज बॅचमधील मजकूर ओळखा आणि शोधण्यायोग्य PDF प्रतिमा आणि निवडण्यायोग्य मजकूर स्तरासह जतन करा</string>\n    <string name=\"layer_alpha\">लेयर अल्फा</string>\n    <string name=\"horizontal_flip\">क्षैतिज फ्लिप</string>\n    <string name=\"vertical_flip\">उभ्या फ्लिप</string>\n    <string name=\"lock\">कुलूप</string>\n    <string name=\"add_shadow\">सावली जोडा</string>\n    <string name=\"shadow_color\">सावलीचा रंग</string>\n    <string name=\"text_geometry\">मजकूर भूमिती</string>\n    <string name=\"text_geometry_sub\">तीक्ष्ण शैलीकरणासाठी मजकूर स्ट्रेच किंवा स्क्यू करा</string>\n    <string name=\"scale_x\">स्केल एक्स</string>\n    <string name=\"skew_x\">स्क्यू एक्स</string>\n    <string name=\"remove_annotations\">भाष्ये काढा</string>\n    <string name=\"remove_annotations_sub\">पीडीएफ पेजेसमधून निवडक भाष्य प्रकार जसे की लिंक्स, टिप्पण्या, हायलाइट्स, आकार किंवा फॉर्म फील्ड काढून टाका</string>\n    <string name=\"annotation_link\">हायपरलिंक्स</string>\n    <string name=\"annotation_file_attachment\">फाइल संलग्नक</string>\n    <string name=\"annotation_line\">ओळी</string>\n    <string name=\"annotation_popup\">पॉपअप</string>\n    <string name=\"annotation_stamp\">शिक्के</string>\n    <string name=\"annotation_shapes\">आकार</string>\n    <string name=\"annotation_text\">मजकूर नोट्स</string>\n    <string name=\"annotation_text_markup\">मजकूर मार्कअप</string>\n    <string name=\"annotation_widget\">फॉर्म फील्ड</string>\n    <string name=\"annotation_markup\">मार्कअप</string>\n    <string name=\"annotation_unknown\">अज्ञात</string>\n    <string name=\"annotations\">भाष्ये</string>\n    <string name=\"ungroup\">गट रद्द करा</string>\n    <string name=\"add_shadow_sub\">कॉन्फिगर करण्यायोग्य रंग आणि ऑफसेटसह लेयरच्या मागे ब्लर शॅडो जोडा</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-night/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">#2A3025</color>\n    <color name=\"onPrimary\">#ABE87C</color>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-night-v31/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">@android:color/system_accent2_800</color>\n    <color name=\"onPrimary\">@android:color/system_accent1_100</color>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-nl/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"size\">Formaat %1$s</string>\n    <string name=\"loading\">Laden…</string>\n    <string name=\"pick_image\">Kies afbeelding om te starten</string>\n    <string name=\"extension\">Extensie</string>\n    <string name=\"resize_type\">Type formaatswijziging</string>\n    <string name=\"explicit\">Expliciet</string>\n    <string name=\"flexible\">Flexibel</string>\n    <string name=\"pick_image_alt\">Afbeelding kiezen</string>\n    <string name=\"app_closing_sub\">Wil je de app echt afsluiten?</string>\n    <string name=\"app_closing\">App sluiten</string>\n    <string name=\"stay\">Blijven</string>\n    <string name=\"reset_image_sub\">Afbeeldingswijzigingen worden teruggezet naar de oorspronkelijke waarden</string>\n    <string name=\"values_reset\">Waarden correct teruggezet</string>\n    <string name=\"no_exif\">Geen EXIF data gevonden</string>\n    <string name=\"add_tag\">Label toevoegen</string>\n    <string name=\"save\">Opslaan</string>\n    <string name=\"clear\">Duidelijk</string>\n    <string name=\"clear_exif\">EXIF wissen</string>\n    <string name=\"cancel\">Annuleren</string>\n    <string name=\"clear_exif_sub\">Alle EXIF-gegevens van afbeeldingen worden gewist. Deze actie kan niet ongedaan gemaakt worden!</string>\n    <string name=\"presets\">Voorinstellingen</string>\n    <string name=\"crop\">Bijsnijden</string>\n    <string name=\"image_not_saved_sub\">Alle niet-opgeslagen wijzigingen gaan verloren als je nu afsluit</string>\n    <string name=\"check_source_code\">Broncode</string>\n    <string name=\"check_source_code_sub\">Ontvang de laatste updates, bespreek problemen en meer</string>\n    <string name=\"single_edit\">Enkele bewerking</string>\n    <string name=\"pick_color\">Kies kleur</string>\n    <string name=\"color\">Kleur</string>\n    <string name=\"color_copied\">Kleur gekopieerd</string>\n    <string name=\"crop_sub\">Snijd de afbeelding bij tot de gewenste afmetingen</string>\n    <string name=\"version\">Versie</string>\n    <string name=\"keep_exif\">Behoud EXIF</string>\n    <string name=\"images\">Afbeeldingen: %d</string>\n    <string name=\"change_preview\">Pas voorvertoning aan</string>\n    <string name=\"remove\">Verwijderen</string>\n    <string name=\"palette_sub\">Genereer kleurenpalet uit een afbeelding</string>\n    <string name=\"generate_palette\">Genereer kleurenpalet</string>\n    <string name=\"palette\">Kleurenpalet</string>\n    <string name=\"update\">Update</string>\n    <string name=\"new_version\">Nieuwe versie %1$s</string>\n    <string name=\"unsupported_type\">Niet-ondersteund type: %1$s</string>\n    <string name=\"no_palette\">Kan geen palet genereren voor een bepaalde afbeelding</string>\n    <string name=\"original\">Origineel</string>\n    <string name=\"def\">Standaard</string>\n    <string name=\"custom\">Aangepast</string>\n    <string name=\"unspecified\">Niet-gespecificeerd</string>\n    <string name=\"device_storage\">Apparaat opslag</string>\n    <string name=\"by_bytes_resize\">Formaat wijzigen op gewicht</string>\n    <string name=\"max_bytes\">Max. Grootte in KB</string>\n    <string name=\"smth_went_wrong\">Er is iets misgegaan:%1$s</string>\n    <string name=\"image_too_large_preview\">Afbeelding is te groot om een voorbeeld te bekijken, maar opslaan wordt toch geprobeerd</string>\n    <string name=\"width\">Breedte %1$s</string>\n    <string name=\"close\">Sluiten</string>\n    <string name=\"reset_image\">Afbeelding terugzetten</string>\n    <string name=\"something_went_wrong\">Er is iets misgegaan</string>\n    <string name=\"height\">Hoogte %1$s</string>\n    <string name=\"reset\">Terugzetten</string>\n    <string name=\"copied\">Gekopieerd naar klembord</string>\n    <string name=\"quality\">Kwaliteit</string>\n    <string name=\"restart_app\">App opnieuw starten</string>\n    <string name=\"exception\">Uitzondering</string>\n    <string name=\"edit_exif\">EXIF bewerken</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">Ok</string>\n    <string name=\"single_edit_sub\">Specificaties wijzigen van een enkele afbeelding</string>\n    <string name=\"pick_color_sub\">Kies de kleur uit de afbeelding, kopieer of deel</string>\n    <string name=\"image\">Afbeelding</string>\n    <string name=\"folder\">Uitvoer map</string>\n    <string name=\"image_not_saved\">Opslaan</string>\n    <string name=\"donation_sub\">Deze applicatie is geheel gratis, maar als je de projectontwikkeling wilt ondersteunen, kun je hier klikken</string>\n    <string name=\"fab_alignment\">FAB-uitlijning</string>\n    <string name=\"check_updates\">Controleer op updates</string>\n    <string name=\"zoom\">Beeldzoom</string>\n    <string name=\"add_file_size_sub\">Indien ingeschakeld, worden breedte en hoogte van de opgeslagen afbeelding toegevoegd aan de naam van het uitvoerbestand</string>\n    <string name=\"delete_exif\">EXIF verwijderen</string>\n    <string name=\"delete_exif_sub\">EXIF-metagegevens verwijderen van alle afbeeldingen</string>\n    <string name=\"image_preview\">Afbeeldingsvoorbeeld</string>\n    <string name=\"image_preview_sub\">Bekijk een voorbeeld van elk type afbeelding: GIF, SVG, enzovoort</string>\n    <string name=\"image_source\">Afbeeldingsbron</string>\n    <string name=\"photo_picker\">Fotokiezer</string>\n    <string name=\"gallery_picker\">Galerij</string>\n    <string name=\"file_explorer_picker\">Bestandsverkenner</string>\n    <string name=\"photo_picker_sub\">De moderne Android-fotokiezer die onderaan het scherm verschijnt, werkt mogelijk alleen op Android 12+ en heeft problemen met EXIF-metagegevens</string>\n    <string name=\"gallery_picker_sub\">Eenvoudige afbeeldingsgalerij-kiezer. Het werkt alleen als je een app hebt die mediaselectie mogelijk maakt</string>\n    <string name=\"file_explorer_picker_sub\">Gebruik de GetContent-intentie om een afbeelding te kiezen. Werkt overal, maar kan op sommige apparaten problemen geven met het verwerken van geselecteerde afbeeldingen. Dat is niet mijn schuld.</string>\n    <string name=\"options_arrangement\">Opties arrangement</string>\n    <string name=\"edit\">Bewerken</string>\n    <string name=\"order\">Volgorde</string>\n    <string name=\"order_sub\">Bepaalt de volgorde van de hulpmiddelen op het hoofdscherm</string>\n    <string name=\"emojis_count\">Emoji\\'s tellen</string>\n    <string name=\"sequence_num\">reeksNum</string>\n    <string name=\"original_filename\">origineleBestandsnaam</string>\n    <string name=\"flexible_description\">Wijzigt het formaat van afbeeldingen naar afbeeldingen met een lange zijde, gegeven door de breedte- of hoogteparameter. Alle grootteberekeningen worden uitgevoerd na het opslaan - behoudt de beeldverhouding</string>\n    <string name=\"tint\">Tint</string>\n    <string name=\"monochrome\">Monochroom</string>\n    <string name=\"line_width\">Lijnbreedte</string>\n    <string name=\"sobel_edge\">Sobel rand</string>\n    <string name=\"blur\">Vervaging</string>\n    <string name=\"halftone\">Halftoon</string>\n    <string name=\"swirl\">Wervelen</string>\n    <string name=\"bulge\">Uitstulping</string>\n    <string name=\"dilation\">Uitzetting</string>\n    <string name=\"sphere_refraction\">Bolbreking</string>\n    <string name=\"refractive_index\">Brekingsindex</string>\n    <string name=\"glass_sphere_refraction\">Breking van glazen bol</string>\n    <string name=\"sketch\">Schetsen</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"fast_blur\">Snelle Waas</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Kan de rangschikking niet wijzigen terwijl optiegroepering is ingeschakeld</string>\n    <string name=\"edit_screenshot\">Schermopname bewerken</string>\n    <string name=\"erase_background\">Achtergrond wissen</string>\n    <string name=\"restore_background\">Achtergrond herstellen</string>\n    <string name=\"blur_radius\">Vervaging radius</string>\n    <string name=\"pipette\">Pipet</string>\n    <string name=\"draw_mode\">Tekenmodus</string>\n    <string name=\"create_issue\">Probleem maken</string>\n    <string name=\"both\">Beide</string>\n    <string name=\"mask_preview\">Maskervoorbeeld</string>\n    <string name=\"inverse_fill_type_sub\">Indien ingeschakeld worden alle niet-gemaskeerde gebieden gefilterd in plaats van het standaardgedrag</string>\n    <string name=\"delete_mask_warn\">Je staat op het punt het geselecteerde filtermasker te verwijderen. Deze bewerking kan niet ongedaan worden gemaakt</string>\n    <string name=\"double_arrow_sub\">Tekent een dubbel wijzende pijl vanaf een bepaald pad</string>\n    <string name=\"oval_sub\">Tekent een ovaal van beginpunt tot eindpunt</string>\n    <string name=\"outlined_oval_sub\">Tekent een omlijnd ovaal van beginpunt tot eindpunt</string>\n    <string name=\"outlined_rect_sub\">Tekent een omlijnde rechte lijn van beginpunt tot eindpunt</string>\n    <string name=\"free\">Vrij</string>\n    <string name=\"horizontal_grid\">Horizontaal raster</string>\n    <string name=\"vertical_grid\">Verticaal raster</string>\n    <string name=\"stitch_mode\">Steekmodus</string>\n    <string name=\"rows_count\">Rijen tellen</string>\n    <string name=\"columns_count\">Kolommen tellen</string>\n    <string name=\"overwrite_files\">Bestanden overschrijven</string>\n    <string name=\"overwrite_files_sub\">Het originele bestand wordt vervangen door een nieuw bestand in plaats van het op te slaan in de geselecteerde map. Deze optie moet de afbeeldingsbron \\\"Explorer\\\" of GetContent zijn. Wanneer u dit omschakelt, wordt dit automatisch ingesteld</string>\n    <string name=\"spline\">Splijn</string>\n    <string name=\"bilinear_sub\">Lineaire (of bilineaire, in twee dimensies) interpolatie is doorgaans goed voor het wijzigen van de grootte van een afbeelding, maar veroorzaakt enige ongewenste verzachting van details en kan nog steeds enigszins gekarteld zijn</string>\n    <string name=\"bicubic_sub\">Betere schaalmethoden zijn onder meer resampling van Lanczos en Mitchell-Netravali-filters</string>\n    <string name=\"only_clip\">Alleen Clip</string>\n    <string name=\"favorite\">Favoriet</string>\n    <string name=\"no_favorite_filters\">Nog geen favoriete filters toegevoegd</string>\n    <string name=\"image_format\">Beeldformaat</string>\n    <string name=\"icon_shape_sub\">Voegt een container met geselecteerde vorm toe onder de leidende pictogrammen van kaarten</string>\n    <string name=\"icon_shape\">Pictogramvorm</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Afsnijden</string>\n    <string name=\"cannot_change_image_format\">Kan het afbeeldingsformaat niet wijzigen terwijl de optie voor het overschrijven van bestanden is ingeschakeld</string>\n    <string name=\"emoji_as_color_scheme\">Emoji als kleurenschema</string>\n    <string name=\"emoji_as_color_scheme_sub\">Gebruikt de primaire kleur van emoji als app-kleurenschema in plaats van handmatig gedefinieerd</string>\n    <string name=\"material_you_sub\">Maakt een \\\"Material You\\\"-palet aan van afbeelding</string>\n    <string name=\"dark_colors\">Donkere kleuren</string>\n    <string name=\"dark_colors_sub\">Maakt gebruik van het nachtmoduskleurenschema in plaats van de lichtvariant</string>\n    <string name=\"copy_as_compose_code\">Kopieer als Jetpack Compose-code</string>\n    <string name=\"ring_blur\">Ringvervaging</string>\n    <string name=\"cross_blur\">Kruisvervaging</string>\n    <string name=\"circle_blur\">Cirkelvervaging</string>\n    <string name=\"star_blur\">Stervervaging</string>\n    <string name=\"linear_tilt_shift\">Lineaire tilt-shift</string>\n    <string name=\"by_bytes_resize_sub\">Pas het formaat van een afbeelding aan volgens de opgegeven grootte in KB</string>\n    <string name=\"compare\">Vergelijken</string>\n    <string name=\"compare_sub\">Vergelijk twee gegeven afbeeldingen</string>\n    <string name=\"pick_two_images\">Kies twee afbeeldingen om te beginnen</string>\n    <string name=\"pick_images\">Kies afbeeldingen</string>\n    <string name=\"settings\">Instellingen</string>\n    <string name=\"night_mode\">Nachtmodus</string>\n    <string name=\"dark\">Donker</string>\n    <string name=\"light\">Licht</string>\n    <string name=\"system\">Systeem</string>\n    <string name=\"dynamic_colors\">Dynamische kleuren</string>\n    <string name=\"customization\">Maatwerk</string>\n    <string name=\"allow_image_monet\">Afbeeldingsmonet toestaan</string>\n    <string name=\"allow_image_monet_sub\">Indien ingeschakeld, worden bij bewerking van een afbeelding, de app-kleuren erop toegepast</string>\n    <string name=\"language\">Taal</string>\n    <string name=\"amoled_mode\">Amoled-modus</string>\n    <string name=\"amoled_mode_sub\">Indien ingeschakeld, wordt de kleur van oppervlakken in de nachtmodus ingesteld op absoluut donker</string>\n    <string name=\"color_scheme\">Kleurenschema</string>\n    <string name=\"color_red\">Rood</string>\n    <string name=\"color_green\">Groente</string>\n    <string name=\"color_blue\">Blauw</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Plak geldige aRGB-code.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Niets om te plakken</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Kan het kleurenschema van de app niet wijzigen terwijl dynamische kleuren zijn ingeschakeld</string>\n    <string name=\"pick_accent_color\">Het app-thema is gebaseerd op de geselecteerde kleur</string>\n    <string name=\"about_app\">Over app</string>\n    <string name=\"no_updates\">Geen updates gevonden</string>\n    <string name=\"issue_tracker\">Probleemtracker</string>\n    <string name=\"issue_tracker_sub\">Stuur hier bugrapporten en functieverzoeken</string>\n    <string name=\"help_translate\">Help vertalen</string>\n    <string name=\"help_translate_sub\">Corrigeer vertaalfouten of lokaliseer het project naar een andere taal</string>\n    <string name=\"nothing_found_by_search\">De zoekopdracht heeft niets opgeleverd</string>\n    <string name=\"search_here\">Zoek hier</string>\n    <string name=\"dynamic_colors_sub\">Indien ingeschakeld, worden app-kleuren overgenomen in achtergrondkleuren</string>\n    <string name=\"failed_to_save\">Kan %d afbeelding(en) niet opslaan</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"primary\">Primair</string>\n    <string name=\"tertiary\">Tertiair</string>\n    <string name=\"secondary\">Ondergeschikt</string>\n    <string name=\"border_thickness\">Randdikte</string>\n    <string name=\"surface\">Oppervlak</string>\n    <string name=\"values\">Waarden</string>\n    <string name=\"add\">Toevoegen</string>\n    <string name=\"permission\">Toestemming</string>\n    <string name=\"grant\">Studiebeurs</string>\n    <string name=\"permission_sub\">De app heeft toegang tot je opslag nodig om afbeeldingen op te slaan om te werken, dit is noodzakelijk. Geef toestemming in het volgende dialoogvenster.</string>\n    <string name=\"grant_permission_manual\">De app heeft deze toestemming nodig om te werken. Verleen deze toestemming handmatig</string>\n    <string name=\"external_storage\">Externe opslag</string>\n    <string name=\"monet_colors\">Monet-kleuren</string>\n    <string name=\"check_updates_sub\">Indien ingeschakeld, wordt het updatevenster getoond bij het opstarten van de app</string>\n    <string name=\"share\">Deel</string>\n    <string name=\"prefix\">Voorvoegsel</string>\n    <string name=\"filename\">Bestandsnaam</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Selecteer welke emoji u op het hoofdscherm wilt weergeven</string>\n    <string name=\"add_file_size\">Bestandsgrootte invoeren</string>\n    <string name=\"add_original_filename\">Originele bestandsnaam toevoegen</string>\n    <string name=\"add_original_filename_sub\">Indien ingeschakeld, wordt de originele bestandsnaam toegevoegd aan de naam van de uitvoerafbeelding</string>\n    <string name=\"replace_sequence_number\">Volgnummer vervangen</string>\n    <string name=\"replace_sequence_number_sub\">Indien ingeschakeld, wordt de standaardtijdstempel vervangen door het volgnummer van de afbeelding als je reeksverwerking gebruikt</string>\n    <string name=\"filename_not_work_with_photopicker\">Het toevoegen van de originele bestandsnaam werkt niet als de afbeeldingsbron van de fotokiezer is geselecteerd</string>\n    <string name=\"load_image_from_net\">Afbeelding laden van net</string>\n    <string name=\"load_image_from_net_sub\">Laad elke afbeelding van internet om deze te bekijken, in te zoomen, te bewerken en op te slaan.</string>\n    <string name=\"no_image\">Geen afbeelding</string>\n    <string name=\"image_link\">Afbeeldingslink</string>\n    <string name=\"fill\">Vullen</string>\n    <string name=\"fit\">Passend</string>\n    <string name=\"content_scale\">Inhoud schaal</string>\n    <string name=\"explicit_description\">Forceert elke afbeelding in een afbeelding die wordt gegeven door de parameter Breedte en Hoogte - kan de beeldverhouding veranderen</string>\n    <string name=\"brightness\">Helderheid</string>\n    <string name=\"contrast\">Contrast</string>\n    <string name=\"hue\">Tint</string>\n    <string name=\"saturation\">Verzadiging</string>\n    <string name=\"add_filter\">Filter toevoegen</string>\n    <string name=\"filter\">Filter</string>\n    <string name=\"filter_sub\">Pas een filterketen toe op bepaalde afbeeldingen</string>\n    <string name=\"filters\">Filters</string>\n    <string name=\"light_aka_illumination\">Licht</string>\n    <string name=\"color_filter\">Kleurfilter</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"exposure\">Blootstelling</string>\n    <string name=\"white_balance\">witbalans</string>\n    <string name=\"temperature\">Temperatuur</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Hoogtepunten en schaduwen</string>\n    <string name=\"highlights\">Hoogtepunten</string>\n    <string name=\"shadows\">Schaduwen</string>\n    <string name=\"haze\">Nevel</string>\n    <string name=\"effect\">Effect</string>\n    <string name=\"distance\">Afstand</string>\n    <string name=\"slope\">Helling</string>\n    <string name=\"sharpen\">Verscherpen</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negatief</string>\n    <string name=\"solarize\">Solariseren</string>\n    <string name=\"vibrance\">Vitaliteit</string>\n    <string name=\"black_and_white\">Zwart en wit</string>\n    <string name=\"crosshatch\">Dubbel gearceerd</string>\n    <string name=\"spacing\">Spatiëring</string>\n    <string name=\"cga_colorspace\">CGA-kleurruimte</string>\n    <string name=\"gaussian_blur\">Gaussiaanse vervaging</string>\n    <string name=\"box_blur\">Vak-vervaging</string>\n    <string name=\"bilaterial_blur\">Bilaterale vervaging</string>\n    <string name=\"emboss\">Embosseren</string>\n    <string name=\"laplacian\">Laplaciaans</string>\n    <string name=\"vignette\">Vignet</string>\n    <string name=\"start\">Begin</string>\n    <string name=\"end\">Einde</string>\n    <string name=\"kuwahara\">Kuwahara-verzachting</string>\n    <string name=\"stack_blur\">Stapelvervaging</string>\n    <string name=\"radius\">Straal</string>\n    <string name=\"scale\">Schaal</string>\n    <string name=\"distortion\">Vervorming</string>\n    <string name=\"angle\">Hoek</string>\n    <string name=\"color_matrix\">Kleurmatrix</string>\n    <string name=\"opacity\">Dekking</string>\n    <string name=\"limits_resize\">Grootte van limieten wijzigen</string>\n    <string name=\"blur_center_x\">Vervaging midden x</string>\n    <string name=\"limits_resize_sub\">Pas het formaat van geselecteerde afbeeldingen aan om de gegeven breedte- en hoogtelimieten te volgen, terwijl de beeldverhouding behouden blijft</string>\n    <string name=\"threshold\">Drempelwaarde</string>\n    <string name=\"quantizationLevels\">Kwantiseringsniveaus</string>\n    <string name=\"smooth_toon\">Vlotte toon</string>\n    <string name=\"posterize\">Posterformaat</string>\n    <string name=\"non_maximum_suppression\">Niet-maximale onderdrukking</string>\n    <string name=\"weak_pixel_inclusion\">Zwakke pixelopname</string>\n    <string name=\"lookup\">Opzoeken</string>\n    <string name=\"convolution3x3\">Convolutie 3x3</string>\n    <string name=\"rgb_filter\">RGB-filter</string>\n    <string name=\"false_color\">Valse kleur</string>\n    <string name=\"first_color\">Eerste kleur</string>\n    <string name=\"second_color\">Tweede kleur</string>\n    <string name=\"reorder\">Opnieuw ordenen</string>\n    <string name=\"blur_size\">Vervagingsgrootte</string>\n    <string name=\"blur_center_y\">Vervaging midden y</string>\n    <string name=\"zoom_blur\">Zoomvervaging</string>\n    <string name=\"color_balance\">Kleur balans</string>\n    <string name=\"luminance_threshold\">Luminantiedrempel</string>\n    <string name=\"activate_files\">Je hebt de Bestanden-app uitgeschakeld. Activeer deze om deze functie te gebruiken</string>\n    <string name=\"draw\">Tekenen</string>\n    <string name=\"draw_sub\">Teken op de afbeelding zoals in een schetsboek, of teken op de achtergrond zelf</string>\n    <string name=\"paint_color\">Verfkleur</string>\n    <string name=\"paint_alpha\">Verf alfa</string>\n    <string name=\"draw_on_image\">Teken op afbeelding</string>\n    <string name=\"draw_on_image_sub\">Kies een afbeelding en teken er iets op</string>\n    <string name=\"draw_on_background\">Teken op de achtergrond</string>\n    <string name=\"draw_on_background_sub\">Kies de achtergrondkleur en teken er bovenop</string>\n    <string name=\"background_color\">Achtergrond kleur</string>\n    <string name=\"cipher\">Versleuteling</string>\n    <string name=\"cipher_sub\">Versleutel en decodeer elk bestand (niet alleen de afbeelding) op basis van beschikbare versleutelingsalgoritmes</string>\n    <string name=\"pick_file\">Kies bestand</string>\n    <string name=\"encrypt\">Versleutelen</string>\n    <string name=\"decrypt\">Ontsleutelen</string>\n    <string name=\"pick_file_to_start\">Kies het bestand om te starten</string>\n    <string name=\"decryption\">Decryptie</string>\n    <string name=\"encryption\">Encryptie</string>\n    <string name=\"key\">Sleutel</string>\n    <string name=\"file_proceed\">Bestand verwerkt</string>\n    <string name=\"store_file_desc\">Bewaar dit bestand op je apparaat of gebruik de deelactie om het te plaatsen waar je maar wilt</string>\n    <string name=\"features\">Functies</string>\n    <string name=\"implementation\">Implementatie</string>\n    <string name=\"compatibility\">Compatibiliteit</string>\n    <string name=\"features_sub\">Wachtwoordgebaseerde versleuteling van bestanden. Vervolgbestanden kunnen in de geselecteerde map worden opgeslagen of gedeeld. Gedecodeerde bestanden kunnen ook direct worden geopend.</string>\n    <string name=\"implementation_sub\">AES-256, GCM-modus, geen opvulling, 12 bytes willekeurige IV\\'s. Sleutels worden gebruikt als (256 bits) SHA-3-hashes. (Standaard, maar het is mogelijk om het benodigde algoritme selecteren).</string>\n    <string name=\"file_size\">Bestandsgrootte</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">Houd er rekening mee dat compatibiliteit met andere bestandsversleutelingssoftware of -services niet kan worden gegarandeerd. Een iets andere versleutelings- of coderingsconfiguratie kan incompatibiliteit veroorzaken.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Ongeldig wachtwoord of gekozen bestand is niet gecodeerd</string>\n    <string name=\"image_size_warning\">Als je probeert een afbeelding met de opgegeven breedte en hoogte op te slaan, kan dit een OOM-fout veroorzaken. Doe dit op eigen risico en zeg niet dat ik je niet heb gewaarschuwd!</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Cache grootte</string>\n    <string name=\"found_s\">Gevonden %1$s</string>\n    <string name=\"auto_cache_clearing\">Automatisch cache wissen</string>\n    <string name=\"auto_cache_clearing_sub\">Indien ingeschakeld, wordt de app-cache gewist bij het opstarten van de app</string>\n    <string name=\"create\">Creëren</string>\n    <string name=\"tools\">Hulpmiddelen</string>\n    <string name=\"group_options_by_type\">Groepeer opties op type</string>\n    <string name=\"group_options_by_type_sub\">Groepeert opties op het hoofdscherm op type in plaats van een aangepaste lijstindeling</string>\n    <string name=\"secondary_customization\">Secundair maatwerk</string>\n    <string name=\"screenshot\">Schermopname</string>\n    <string name=\"fallback_option\">Terugval optie</string>\n    <string name=\"skip\">Overslaan</string>\n    <string name=\"copy\">Kopiëren</string>\n    <string name=\"warning_bytes\">Opslaan in de modus %1$s kan onstabiel zijn, omdat het een verliesvrij formaat is</string>\n    <string name=\"presets_sub\" formatted=\"false\">Bij voorinstelling 125, wordt de afbeelding opgeslagen als 125% van de originele afbeelding. Bij voorinstelling 50, wordt de afbeelding opgeslagen met 50% grootte.</string>\n    <string name=\"presets_sub_bytes\">De voorinstelling hier bepaalt het percentage van het uitvoerbestand, d.w.z. bij voorinstelling 50 op een afbeelding van 5 MB, krijg je na het opslaan een afbeelding van 2,5 MB</string>\n    <string name=\"randomize_filename\">Willekeurige bestandsnaam</string>\n    <string name=\"randomize_filename_sub\">Indien ingeschakeld zal de uitvoerbestandsnaam volledig willekeurig zijn</string>\n    <string name=\"saved_to\">Opgeslagen in map %1$s met naam %2$s</string>\n    <string name=\"saved_to_without_filename\">Opgeslagen in map %1$s</string>\n    <string name=\"tg_chat\">Telegram-chat</string>\n    <string name=\"tg_chat_sub\">Bespreek de app en krijg feedback van andere gebruikers. Je kunt hier ook bèta-updates en inzichten krijgen.</string>\n    <string name=\"crop_mask\">Masker bijsnijden</string>\n    <string name=\"aspect_ratio\">Beeldverhouding</string>\n    <string name=\"image_crop_mask_sub\">Gebruik dit maskertype om een masker te maken van een bepaalde afbeelding. Merk op dat het een alfakanaal MOET hebben</string>\n    <string name=\"backup_and_restore\">Backup en herstellen</string>\n    <string name=\"backup\">Back-up</string>\n    <string name=\"restore\">Herstellen</string>\n    <string name=\"backup_sub\">Een back-up van de app-instellingen maken</string>\n    <string name=\"restore_sub\">Herstel app-instellingen van een eerder gegenereerd bestand</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Beschadigd bestand of geen back-up</string>\n    <string name=\"settings_restored\">Instellingen succesvol hersteld</string>\n    <string name=\"contact_me\">Neem contact met mij op</string>\n    <string name=\"reset_settings_sub\">Hiermee worden de instellingen teruggezet naar de standaardwaarden. Merk op dat dit niet ongedaan kan worden gemaakt zonder een hierboven vermeld back-upbestand.</string>\n    <string name=\"delete\">Verwijderen</string>\n    <string name=\"delete_color_scheme_warn\">Je staat op het punt het geselecteerde kleurenschema te verwijderen. Deze bewerking kan niet ongedaan worden gemaakt</string>\n    <string name=\"delete_color_scheme_title\">Schema verwijderen</string>\n    <string name=\"font\">Lettertype</string>\n    <string name=\"text\">Tekst</string>\n    <string name=\"font_scale\">Lettertype schaal</string>\n    <string name=\"defaultt\">Standaard</string>\n    <string name=\"using_large_fonts_warn\">Het gebruik van grote lettertypeschalen kan UI-fouten en problemen veroorzaken, die niet kunnen worden opgelost. Gebruik voorzichtig.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"emotions\">Emoties</string>\n    <string name=\"food_and_drink\">Eten en drinken</string>\n    <string name=\"nature_and_animals\">Natuur en Dieren</string>\n    <string name=\"objects\">Voorwerpen</string>\n    <string name=\"symbols\">Symbolen</string>\n    <string name=\"enable_emoji\">Schakel emoji in</string>\n    <string name=\"travels_and_places\">Reizen en plaatsen</string>\n    <string name=\"activities\">Activiteiten</string>\n    <string name=\"background_remover\">Achtergrondverwijderaar</string>\n    <string name=\"background_remover_sub\">Verwijder de achtergrond uit de afbeelding door te tekenen of gebruik de Auto-optie</string>\n    <string name=\"trim_image\">Afbeelding bijsnijden</string>\n    <string name=\"keep_exif_sub\">De originele metagegevens van de afbeelding blijven behouden</string>\n    <string name=\"trim_image_sub\">Transparante ruimtes rond de afbeelding worden bijgesneden</string>\n    <string name=\"auto_erase_background\">Achtergrond automatisch wissen</string>\n    <string name=\"restore_image\">Afbeelding herstellen</string>\n    <string name=\"erase_mode\">Wismodus</string>\n    <string name=\"something_went_wrong_emphasis\">Oeps… Er is iets misgegaan. Je kunt me schrijven met behulp van de onderstaande opties en ik zal proberen een oplossing te vinden</string>\n    <string name=\"resize_and_convert\">Formaat wijzigen en converteren</string>\n    <string name=\"resize_and_convert_sub\">Wijzig de grootte van bepaalde afbeeldingen of converteer ze naar andere formaten. EXIF-metagegevens kunnen hier ook worden bewerkt als u een enkele afbeelding kiest.</string>\n    <string name=\"max_colors_count\">Maximaal aantal kleuren</string>\n    <string name=\"crashlytics_sub\">Hierdoor kan de app crashrapporten handmatig verzamelen</string>\n    <string name=\"analytics\">Analyses</string>\n    <string name=\"analytics_sub\">Sta het verzamelen van anonieme app-gebruiksstatistieken toe</string>\n    <string name=\"image_exif_warning\">Momenteel staat het %1$s-formaat alleen het lezen van EXIF-metagegevens op Android toe. De uitvoerafbeelding heeft helemaal geen metagegevens wanneer deze wordt opgeslagen.</string>\n    <string name=\"effort\">Poging</string>\n    <string name=\"effort_sub\">Een waarde van %1$s betekent een snelle compressie, wat resulteert in een relatief grote bestandsgrootte. %2$s betekent een langzamere compressie, wat resulteert in een kleiner bestand.</string>\n    <string name=\"wait\">Wachten</string>\n    <string name=\"saving_almost_complete\">Opslaan bijna voltooid. Als u nu annuleert, moet u opnieuw opslaan.</string>\n    <string name=\"updates\">Updates</string>\n    <string name=\"allow_betas\">Bèta\\'s toestaan</string>\n    <string name=\"allow_betas_sub\">Updatecontrole omvat bèta-app-versies, indien ingeschakeld</string>\n    <string name=\"draw_arrows\">Teken pijlen</string>\n    <string name=\"draw_arrows_sub\">Indien ingeschakeld, wordt het tekenpad weergegeven als een wijzende pijl</string>\n    <string name=\"brush_softness\">Zachtheid van de borstel</string>\n    <string name=\"crop_description\">Foto\\'s worden in het midden bijgesneden tot het ingevoerde formaat. Canvas wordt uitgebreid met de opgegeven achtergrondkleur als de afbeelding kleiner is dan de ingevoerde afmetingen.</string>\n    <string name=\"donation\">Bijdrage</string>\n    <string name=\"image_stitching\">Beeldsteken</string>\n    <string name=\"image_stitching_sub\">Combineer de gegeven afbeeldingen om één grote te krijgen</string>\n    <string name=\"pick_at_least_two_images\">Kies minimaal 2 afbeeldingen</string>\n    <string name=\"output_image_scale\">Uitvoer afbeeldingsschaal</string>\n    <string name=\"image_orientation\">Beeldoriëntatie</string>\n    <string name=\"horizontal\">Horizontaal</string>\n    <string name=\"vertical\">Verticaal</string>\n    <string name=\"scale_small_images_to_large\">Schaal kleine afbeeldingen naar groot</string>\n    <string name=\"scale_small_images_to_large_sub\">Kleine afbeeldingen worden, indien ingeschakeld, geschaald naar de grootste in de reeks</string>\n    <string name=\"images_order\">Afbeeldingen bestellen</string>\n    <string name=\"regular\">Normaal</string>\n    <string name=\"blur_edges\">Vervaging randen</string>\n    <string name=\"blur_edges_sub\">Tekent vage randen onder de originele afbeelding om de ruimtes eromheen te vullen in plaats van één kleur, indien ingeschakeld</string>\n    <string name=\"pixelation\">Pixelvorming</string>\n    <string name=\"enhanced_pixelation\">Verbeterde pixelvorming</string>\n    <string name=\"foss_update_checker_warning\">Deze updatechecker maakt verbinding met GitHub om te controleren of er een nieuwe update beschikbaar is</string>\n    <string name=\"stroke_pixelation\">Penseel-pixelvorming</string>\n    <string name=\"enhanced_diamond_pixelation\">Verbeterde ruit-pixelvorming</string>\n    <string name=\"diamond_pixelation\">Ruit-pixelvorming</string>\n    <string name=\"circle_pixelation\">Cirkel-pixelvorming</string>\n    <string name=\"enhanced_circle_pixelation\">Verbeterde cirkel-pixelvorming</string>\n    <string name=\"replace_color\">Kleur vervangen</string>\n    <string name=\"tolerance\">Tolerantie</string>\n    <string name=\"color_to_replace\">Kleur om te vervangen</string>\n    <string name=\"target_color\">Doelkleur</string>\n    <string name=\"color_to_remove\">Kleur om te verwijderen</string>\n    <string name=\"remove_color\">Kleur verwijderen</string>\n    <string name=\"recode\">Hercoderen</string>\n    <string name=\"pixel_size\">Pixelgrootte</string>\n    <string name=\"lock_draw_orientation\">Tekenrichting vergrendelen</string>\n    <string name=\"lock_draw_orientation_sub\">Indien ingeschakeld in de tekenmodus, draait het scherm niet</string>\n    <string name=\"check_for_updates\">Controleer op updates</string>\n    <string name=\"palette_style\">Paletstijl</string>\n    <string name=\"tonal_spot\">Tonale plek</string>\n    <string name=\"neutral\">Neutrale</string>\n    <string name=\"vibrant\">Levendig</string>\n    <string name=\"expressive\">Expressief</string>\n    <string name=\"rainbow\">Regenboog</string>\n    <string name=\"fruit_salad\">Fruit salade</string>\n    <string name=\"fidelity\">Trouw</string>\n    <string name=\"content\">Inhoud</string>\n    <string name=\"tonal_spot_sub\">Standaard paletstijl waarin alle vier de kleuren zijn aan te passen, bij andere kan alleen de hoofdkleur worden ingesteld</string>\n    <string name=\"neutral_sub\">Een stijl die iets chromatischer is dan monochroom</string>\n    <string name=\"vibrant_sub\">Een luid thema, kleurrijkheid is maximaal voor het primaire palet, verhoogd voor anderen</string>\n    <string name=\"playful_scheme\">Een speels thema: de tint van de bronkleur komt niet voor in het thema</string>\n    <string name=\"monochrome_sub\">Een monochroom thema, kleuren zijn puur zwart/wit/grijs</string>\n    <string name=\"content_sub\">Een schema dat de bronkleur in Scheme.primaryContainer plaatst</string>\n    <string name=\"fidelity_sub\">Een schema dat sterk lijkt op het inhoudschema</string>\n    <string name=\"attention\">Aandacht</string>\n    <string name=\"fading_edges\">Vervagende randen</string>\n    <string name=\"disabled\">Gehandicapt</string>\n    <string name=\"invert_colors\">Kleuren omkeren</string>\n    <string name=\"start_position\">Begin</string>\n    <string name=\"invert_colors_sub\">Vervangt themakleuren door negatieve kleuren, indien ingeschakeld</string>\n    <string name=\"center_position\">Centrum</string>\n    <string name=\"search_option\">Zoekopdracht</string>\n    <string name=\"search_option_sub\">Maakt het mogelijk om door alle beschikbare hulpmiddelen op het hoofdscherm te zoeken</string>\n    <string name=\"pdf_tools\">PDF-hulpmiddelen</string>\n    <string name=\"pdf_tools_sub\">Werk met PDF-bestanden: bekijk een voorbeeld, converteer naar een reeks afbeeldingen of maak er een van bepaalde afbeeldingen</string>\n    <string name=\"preview_pdf\">Voorbeeld van pdf</string>\n    <string name=\"pdf_to_images\">PDF naar afbeeldingen</string>\n    <string name=\"images_to_pdf\">Afbeeldingen naar PDF</string>\n    <string name=\"preview_pdf_sub\">Eenvoudig PDF-voorbeeld</string>\n    <string name=\"pdf_to_images_sub\">Converteer PDF naar afbeeldingen in een bepaald uitvoerformaat</string>\n    <string name=\"images_to_pdf_sub\">Verpak de gegeven afbeeldingen in een uitvoer-PDF-bestand</string>\n    <string name=\"mask_filter\">Maskerfilter</string>\n    <string name=\"mask_filter_sub\">Pas filterketens toe op bepaalde gemaskeerde gebieden. Elk maskergebied kan zijn eigen set filters bepalen</string>\n    <string name=\"masks\">Maskers</string>\n    <string name=\"add_mask\">Masker toevoegen</string>\n    <string name=\"mask_indexed\">Masker %d</string>\n    <string name=\"mask_color\">Maskerkleur</string>\n    <string name=\"mask_preview_sub\">Er wordt een getekend filtermasker weergegeven om het geschatte resultaat te tonen</string>\n    <string name=\"inverse_fill_type\">Omgekeerd vultype</string>\n    <string name=\"delete_mask\">Masker verwijderen</string>\n    <string name=\"full_filter\">Volledig filter</string>\n    <string name=\"full_filter_sub\">Pas eventuele filterketens toe op bepaalde afbeeldingen of op één afbeelding</string>\n    <string name=\"end_position\">Einde</string>\n    <string name=\"simple_variants\">Eenvoudige varianten</string>\n    <string name=\"highlighter\">Markeerstift</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Pen</string>\n    <string name=\"privacy_blur\">Privacyvervaging</string>\n    <string name=\"highlighter_sub\">Teken semi-transparante, scherpe markeerstiftpaden</string>\n    <string name=\"neon_sub\">Voeg een gloeiend effect toe aan je tekeningen</string>\n    <string name=\"pen_sub\">Standaard één, eenvoudigste: alleen de kleur</string>\n    <string name=\"privacy_blur_sub\">Vervaagt het beeld onder het getekende pad om alles te beveiligen dat je wilt verbergen</string>\n    <string name=\"pixelation_sub\">Vergelijkbaar met privacyvervaging, maar met pixelvorming i.p.v. vervaging</string>\n    <string name=\"containers_shadow\">Containers</string>\n    <string name=\"containers_shadow_sub\">Maakt schaduwtekenen achter containers mogelijk</string>\n    <string name=\"sliders_shadow\">Schuifregelaars</string>\n    <string name=\"switches_shadow\">Schakelaars</string>\n    <string name=\"fabs_shadow\">FAB\\'s</string>\n    <string name=\"buttons_shadow\">Toetsen</string>\n    <string name=\"sliders_shadow_sub\">Maakt schaduwtekenen achter schuifregelaars mogelijk</string>\n    <string name=\"switches_shadow_sub\">Maakt schaduwtekenen achter schakelaars mogelijk</string>\n    <string name=\"fabs_shadow_sub\">Maakt schaduwtekenen achter zwevende actieknoppen mogelijk</string>\n    <string name=\"buttons_shadow_sub\">Schakelt schaduwtekening achter standaardknoppen in</string>\n    <string name=\"app_bars_shadow\">App-balken</string>\n    <string name=\"app_bars_shadow_sub\">Maakt schaduwtekenen achter app-balken mogelijk</string>\n    <string name=\"value_in_range\">Waarde binnen bereik %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Automatisch draaien</string>\n    <string name=\"auto_rotate_limits_sub\">Maakt het mogelijk om een limietvak te gebruiken voor de beeldoriëntatie</string>\n    <string name=\"draw_path_mode\">Tekenpadmodus</string>\n    <string name=\"double_line_arrow\">Dubbele lijnpijl</string>\n    <string name=\"free_drawing\">Gratis tekening</string>\n    <string name=\"double_arrow\">Dubbele pijl</string>\n    <string name=\"line_arrow\">Lijnpijl</string>\n    <string name=\"arrow\">Pijl</string>\n    <string name=\"line\">Lijn</string>\n    <string name=\"free_drawing_sub\">Tekent pad als invoerwaarde</string>\n    <string name=\"line_sub\">Tekent het pad van beginpunt naar eindpunt als een lijn</string>\n    <string name=\"line_arrow_sub\">Tekent de wijzende pijl van beginpunt tot eindpunt als een lijn</string>\n    <string name=\"arrow_sub\">Tekent een wijzende pijl vanaf een bepaald pad</string>\n    <string name=\"double_line_arrow_sub\">Tekent een dubbel wijzende pijl van beginpunt tot eindpunt als een lijn</string>\n    <string name=\"outlined_oval\">Geschetst ovaal</string>\n    <string name=\"outlined_rect\">Geschetst rect</string>\n    <string name=\"oval\">ovaal</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Tekent een rechte lijn van beginpunt tot eindpunt</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Tekent een gesloten gevuld pad volgens een gegeven pad</string>\n    <string name=\"no_such_directory\">Geen map \\\"%1$s\\\" gevonden. We hebben dit gewijzigd in de standaardmap. Sla het bestand opnieuw op</string>\n    <string name=\"clipboard\">Klembord</string>\n    <string name=\"auto_pin\">Automatische pin</string>\n    <string name=\"auto_pin_sub\">Voegt automatisch opgeslagen afbeeldingen toe aan het klembord, indien ingeschakeld</string>\n    <string name=\"vibration\">Trillingen</string>\n    <string name=\"vibration_strength\">Trillingssterkte</string>\n    <string name=\"overwrite_file_requirements\">Om bestanden te overschrijven moet je de afbeeldingsbron \\\"Explorer\\\" gebruiken. Probeer de afbeeldingen opnieuw te kiezen. We hebben de afbeeldingsbron gewijzigd in de benodigde bron.</string>\n    <string name=\"empty\">Leeg</string>\n    <string name=\"suffix\">Achtervoegsel</string>\n    <string name=\"scale_mode\">Schaalmodus</string>\n    <string name=\"bilinear\">Bilineair</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubisch</string>\n    <string name=\"hann\">Han</string>\n    <string name=\"hermite\">Hermiet</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Dichtstbijzijnde</string>\n    <string name=\"basic\">Basis</string>\n    <string name=\"default_value\">Standaardwaarde</string>\n    <string name=\"nearest_sub\">Een van de eenvoudigere manieren om de grootte te vergroten, is door elke pixel te vervangen door een aantal pixels van dezelfde kleur</string>\n    <string name=\"basic_sub\">Eenvoudigste Android-schaalmodus die in bijna alle apps wordt gebruikt</string>\n    <string name=\"catmull_sub\">Methode voor het soepel interpoleren en opnieuw bemonsteren van een reeks controlepunten, vaak gebruikt in computergraphics om vloeiende curven te creëren</string>\n    <string name=\"hann_sub\">Windowing-functie die vaak wordt toegepast bij signaalverwerking om spectrale lekkage te minimaliseren en de nauwkeurigheid van frequentieanalyse te verbeteren door de randen van een signaal taps te maken</string>\n    <string name=\"hermite_sub\">Wiskundige interpolatietechniek die de waarden en afgeleiden aan de eindpunten van een curvesegment gebruikt om een vloeiende en continue curve te genereren</string>\n    <string name=\"lanczos_sub\">Resamplingmethode die interpolatie van hoge kwaliteit handhaaft door een gewogen sinc-functie op de pixelwaarden toe te passen</string>\n    <string name=\"mitchell_sub\">Resampling-methode die gebruik maakt van een convolutiefilter met aanpasbare parameters om een balans te bereiken tussen scherpte en anti-aliasing in het geschaalde beeld</string>\n    <string name=\"spline_sub\">Maakt gebruik van stuksgewijs gedefinieerde polynomiale functies om een curve of oppervlak soepel te interpoleren en te benaderen, een flexibele en continue vormrepresentatie</string>\n    <string name=\"only_clip_sub\">Opslaan naar opslag wordt niet uitgevoerd en er wordt alleen geprobeerd de afbeelding op het klembord te plaatsen</string>\n    <string name=\"restore_background_sub\">Penseel herstelt de achtergrond in plaats van te wissen</string>\n    <string name=\"recognize_text\">OCR (tekst herkennen)</string>\n    <string name=\"recognize_text_sub\">Herken tekst van een bepaalde afbeelding, meer dan 120 talen ondersteund</string>\n    <string name=\"picture_has_no_text\">De afbeelding bevat geen tekst, of de app heeft deze niet gevonden</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Herkenningstype</string>\n    <string name=\"fast\">Snel</string>\n    <string name=\"standard\">Standaard</string>\n    <string name=\"best\">Best</string>\n    <string name=\"no_data\">Geen gegevens</string>\n    <string name=\"download_description\">Voor een goede werking van Tesseract OCR moeten aanvullende trainingsgegevens (%1$s) naar je apparaat worden gedownload. \\nWil je %2$s gegevens downloaden?</string>\n    <string name=\"download\">Downloaden</string>\n    <string name=\"no_connection\">Geen verbinding, controleer dit en probeer het opnieuw om trainingsmodellen te downloaden</string>\n    <string name=\"downloaded_languages\">Gedownloade talen</string>\n    <string name=\"available_languages\">Beschikbare talen</string>\n    <string name=\"segmentation_mode\">Segmentatiemodus</string>\n    <string name=\"use_pixel_switch\">Gebruik Pixelswitch</string>\n    <string name=\"use_pixel_switch_sub\">Pixel-achtige schakelaar wordt gebruikt in plaats van een schakelaar gebaseerd op Google\\'s Material You</string>\n    <string name=\"saved_to_original\">Overschreven bestand met naam %1$s op oorspronkelijke bestemming</string>\n    <string name=\"magnifier\">Vergrootglas</string>\n    <string name=\"magnifier_sub\">Schakelt vergrootglas aan de bovenkant van de vinger in tekenmodi in voor betere toegankelijkheid</string>\n    <string name=\"force_exif_widget_initial_value\">Beginwaarde forceren</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Forceert dat de exif-widget in eerste instantie wordt gecontroleerd</string>\n    <string name=\"segmentation_mode_single_line\">Enkele lijn</string>\n    <string name=\"segmentation_mode_single_word\">Een woord</string>\n    <string name=\"allow_multiple_languages\">Meerdere talen toestaan</string>\n    <string name=\"slide\">Dia</string>\n    <string name=\"side_by_side\">Zij aan zij</string>\n    <string name=\"toggle_tap\">Wisseltikken</string>\n    <string name=\"transparency\">Transparantie</string>\n    <string name=\"rate_app\">Beoordeel app</string>\n    <string name=\"rate\">Tarief</string>\n    <string name=\"rate_app_sub\">Deze app is volledig gratis. Als je wilt dat hij groter wordt, geef dan een ster aan het project op Github 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Oriëntatie &amp; Alleen scriptdetectie</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatische oriëntatie &amp; Scriptdetectie</string>\n    <string name=\"segmentation_mode_auto_only\">Alleen automatisch</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Enkele kolom</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Enkel blok verticale tekst</string>\n    <string name=\"segmentation_mode_single_block\">Enkel blok</string>\n    <string name=\"segmentation_mode_circle_word\">Cirkel woord</string>\n    <string name=\"segmentation_mode_single_char\">Enkel teken</string>\n    <string name=\"segmentation_mode_sparse_text\">Schaarse tekst</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Sparse tekst Oriëntatie &amp; Scriptdetectie</string>\n    <string name=\"segmentation_mode_raw_line\">Ruwe lijn</string>\n    <string name=\"delete_language_sub\">Wil je OCR-trainingsgegevens van taal \\\"%1$s\\\" verwijderen voor alle herkenningstypen, of alleen voor een geselecteerd type (%2$s)?</string>\n    <string name=\"current\">Huidig</string>\n    <string name=\"all\">Alle</string>\n    <string name=\"gradient_maker\">Verloopmaker</string>\n    <string name=\"gradient_maker_sub\">Creëer een verloop van een bepaald uitvoerformaat met aangepaste kleuren en uiterlijktype</string>\n    <string name=\"gradient_type_linear\">Lineair</string>\n    <string name=\"gradient_type_radial\">Radiaal</string>\n    <string name=\"gradient_type_sweep\">Vegen</string>\n    <string name=\"gradient_type\">Verlooptype</string>\n    <string name=\"center_x\">Centrum X</string>\n    <string name=\"center_y\">Centrum Y</string>\n    <string name=\"tile_mode\">Tegelmodus</string>\n    <string name=\"tile_mode_repeated\">Herhaald</string>\n    <string name=\"tile_mode_mirror\">Spiegelen</string>\n    <string name=\"tile_mode_clamp\">Klem</string>\n    <string name=\"tile_mode_decal\">Sticker</string>\n    <string name=\"color_stops\">Kleur stopt</string>\n    <string name=\"add_color\">Kleur toevoegen</string>\n    <string name=\"properties\">Eigenschappen</string>\n    <string name=\"brightness_enforcement\">Helderheidshandhaving</string>\n    <string name=\"screen\">Scherm</string>\n    <string name=\"gradient_maker_type_image\">Verloopoverlay</string>\n    <string name=\"gradient_maker_type_image_sub\">Stel elk verloop van de bovenkant van de gegeven afbeeldingen samen</string>\n    <string name=\"transformations\">Transformaties</string>\n    <string name=\"camera\">Camera</string>\n    <string name=\"camera_sub\">Gebruikt de camera om een foto te maken. Houd er rekening mee dat het mogelijk is om slechts één afbeelding uit deze afbeeldingsbron te halen</string>\n    <string name=\"watermarking\">Watermerken</string>\n    <string name=\"watermarking_sub\">Omslagafbeeldingen met aanpasbare tekst-/afbeeldingswatermerken</string>\n    <string name=\"repeat_watermark\">Herhaal watermerk</string>\n    <string name=\"repeat_watermark_sub\">Herhaalt het watermerk over de afbeelding in plaats van enkelvoudig op een bepaalde positie</string>\n    <string name=\"offset_x\">Offset X</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermark_type\">Watermerktype</string>\n    <string name=\"watermarking_image_sub\">Deze afbeelding wordt gebruikt als patroon voor watermerken</string>\n    <string name=\"text_color\">Tekst kleur</string>\n    <string name=\"overlay_mode\">Overlay-modus</string>\n    <string name=\"gif_tools\">GIF-hulpmiddelen</string>\n    <string name=\"gif_tools_sub\">Converteer afbeeldingen naar GIF-afbeelding of extraheer frames uit een bepaalde GIF-afbeelding</string>\n    <string name=\"gif_type_to_image\">GIF naar afbeeldingen</string>\n    <string name=\"gif_type_to_image_sub\">Converteer een GIF-bestand naar een reeks afbeeldingen</string>\n    <string name=\"gif_type_to_gif_sub\">Converteer een reeks afbeeldingen naar een GIF-bestand</string>\n    <string name=\"gif_type_to_gif\">Afbeeldingen naar GIF</string>\n    <string name=\"select_gif_image_to_start\">Kies een GIF-afbeelding om te beginnen</string>\n    <string name=\"use_size_of_first_frame\">Gebruik de grootte van het eerste frame</string>\n    <string name=\"use_size_of_first_frame_sub\">Vervang de opgegeven maat door de eerste frameafmetingen</string>\n    <string name=\"original_image_preview_alpha\">Origineel afbeeldingsvoorbeeld Alpha</string>\n    <string name=\"repeat_count\">Herhaal telling</string>\n    <string name=\"frame_delay\">Framevertraging</string>\n    <string name=\"millis\">milli</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Gebruik lasso</string>\n    <string name=\"use_lasso_sub\">Gebruikt Lasso zoals in de tekenmodus om te wissen</string>\n    <string name=\"confetti\">Confetti</string>\n    <string name=\"confetti_sub\">Er wordt confetti getoond over opslaan, delen en andere primaire acties</string>\n    <string name=\"secure_mode\">Veilige modus</string>\n    <string name=\"secure_mode_sub\">Verbergt inhoud bij het afsluiten, ook kan het scherm niet worden vastgelegd of opgenomen</string>\n    <string name=\"exit\">Uitgang</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite-dithering</string>\n    <string name=\"preview_closing\">Als je het voorbeeld nu verlaat, moet je de afbeeldingen opnieuw toevoegen</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizer</string>\n    <string name=\"gray_scale\">Grijsschaal</string>\n    <string name=\"bayer_two_dithering\">Bayer twee aan twee dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer drie aan drie dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer vier bij vier dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Acht Bij Acht Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra dithering</string>\n    <string name=\"two_row_sierra_dithering\">Sierra-dithering met twee rijen</string>\n    <string name=\"atkinson_dithering\">Atkinson-dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Valse Floyd Steinberg-dithering</string>\n    <string name=\"left_to_right_dithering\">Van links naar rechts ditheren</string>\n    <string name=\"random_dithering\">Willekeurig ditheren</string>\n    <string name=\"simple_threshold_dithering\">Eenvoudige drempeldithering</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Ruimtelijke Sigma</string>\n    <string name=\"median_blur\">Mediane vervaging</string>\n    <string name=\"b_spline\">B Splijn</string>\n    <string name=\"b_spline_sub\">Maakt gebruik van stuksgewijs gedefinieerde bicubische polynoomfuncties om een curve of oppervlak soepel te interpoleren en te benaderen, een flexibele en continue vormrepresentatie</string>\n    <string name=\"native_stack_blur\">Native stapelvervaging</string>\n    <string name=\"tilt_shift\">Focus verleggen</string>\n    <string name=\"glitch\">Hapering</string>\n    <string name=\"amount\">Hoeveelheid</string>\n    <string name=\"seed\">Zaad</string>\n    <string name=\"anaglyph\">Anaglief</string>\n    <string name=\"noise\">Lawaai</string>\n    <string name=\"pixel_sort\">Pixel sorteren</string>\n    <string name=\"shuffle\">Schudden</string>\n    <string name=\"enhanced_glitch\">Verbeterde storing</string>\n    <string name=\"channel_shift_x\">Kanaalverschuiving X</string>\n    <string name=\"channel_shift_y\">Kanaalverschuiving Y</string>\n    <string name=\"corruption_size\">Grootte van corruptie</string>\n    <string name=\"corruption_shift_x\">Corruptieverschuiving X</string>\n    <string name=\"corruption_shift_y\">Corruptieverschuiving Y</string>\n    <string name=\"tent_blur\">Tentvervaging</string>\n    <string name=\"side_fade\">Zijkant vervagen</string>\n    <string name=\"side\">Kant</string>\n    <string name=\"top\">Bovenkant</string>\n    <string name=\"bottom\">Onderkant</string>\n    <string name=\"strength\">Kracht</string>\n    <string name=\"erode\">Eroderen</string>\n    <string name=\"anisotropic_diffusion\">Anisotrope diffusie</string>\n    <string name=\"diffusion\">Verspreiding</string>\n    <string name=\"conduction\">Geleiding</string>\n    <string name=\"horizontal_wind_stagger\">Horizontale windspreiding</string>\n    <string name=\"fast_bilaterial_blur\">Snelle bilaterale vervaging</string>\n    <string name=\"poisson_blur\">Poisson-vervaging</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmische toonmapping</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES filmische toonmapping</string>\n    <string name=\"crystallize\">Kristalliseren</string>\n    <string name=\"stroke_color\">Lijnkleur</string>\n    <string name=\"fractal_glass\">Fractaal glas</string>\n    <string name=\"amplitude\">Amplitude</string>\n    <string name=\"marble\">Marmer</string>\n    <string name=\"turbulence\">Turbulentie</string>\n    <string name=\"oil\">Olie</string>\n    <string name=\"water_effect\">Watereffect</string>\n    <string name=\"just_size\">Maat</string>\n    <string name=\"frequency_x\">Frequentie X</string>\n    <string name=\"frequency_y\">Frequentie Y</string>\n    <string name=\"amplitude_x\">Amplitude X</string>\n    <string name=\"amplitude_y\">Amplitude Y</string>\n    <string name=\"perlin_distortion\">Perlin-vervorming</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable filmische toonmapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess-toonmapping</string>\n    <string name=\"speed\">Snelheid</string>\n    <string name=\"dehaze\">Ontnevelen</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Kleurenmatrix 4x4</string>\n    <string name=\"color_matrix_3x3\">Kleurenmatrix 3x3</string>\n    <string name=\"simple_effects\">Eenvoudige effecten</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomalie</string>\n    <string name=\"deutaromaly\">Deuteranomalie</string>\n    <string name=\"protonomaly\">Protanomalie</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chroom</string>\n    <string name=\"night_vision\">Nachtzicht</string>\n    <string name=\"warm\">Warm</string>\n    <string name=\"cool\">Koel</string>\n    <string name=\"tritanopia\">Tritanopie</string>\n    <string name=\"deutaronotopia\">Deuteranopie</string>\n    <string name=\"protanopia\">Protanopie</string>\n    <string name=\"achromatomaly\">Achromatomalie</string>\n    <string name=\"achromatopsia\">Achromatopsie</string>\n    <string name=\"grain\">Korrel</string>\n    <string name=\"unsharp\">Onscherp</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Oranje waas</string>\n    <string name=\"pink_dream\">Roze droom</string>\n    <string name=\"golden_hour\">Gouden uur</string>\n    <string name=\"hot_summer\">Hete zomer</string>\n    <string name=\"purple_mist\">Paarse mist</string>\n    <string name=\"sunrise\">zonsopkomst</string>\n    <string name=\"colorful_swirl\">Kleurrijke werveling</string>\n    <string name=\"soft_spring_light\">Zacht lentelicht</string>\n    <string name=\"autumn_tones\">Herfsttinten</string>\n    <string name=\"lavender_dream\">Lavendel droom</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Limonade licht</string>\n    <string name=\"spectral_fire\">Spectraal vuur</string>\n    <string name=\"night_magic\">Nachtelijke magie</string>\n    <string name=\"fantasy_landscape\">Fantasielandschap</string>\n    <string name=\"color_explosion\">Kleur explosie</string>\n    <string name=\"electric_gradient\">Elektrisch verloop</string>\n    <string name=\"caramel_darkness\">Karamel Duisternis</string>\n    <string name=\"futuristic_gradient\">Futuristisch verloop</string>\n    <string name=\"green_sun\">Groene zon</string>\n    <string name=\"rainbow_world\">Regenboog wereld</string>\n    <string name=\"deep_purple\">Donker paars</string>\n    <string name=\"space_portal\">Ruimteportaal</string>\n    <string name=\"red_swirl\">Rode Werveling</string>\n    <string name=\"digital_code\">Digitale code</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">App-balk-emoji wordt voortdurend willekeurig gewijzigd in plaats van een geselecteerde te gebruiken</string>\n    <string name=\"random_emojis\">Willekeurige emoji\\'s</string>\n    <string name=\"random_emojis_error\">Kan geen willekeurige emoji\\'s gebruiken als emoji\\'s zijn uitgeschakeld</string>\n    <string name=\"emoji_selection_error\">Kan geen emoji selecteren terwijl willekeurige emoji is ingeschakeld</string>\n    <string name=\"old_tv\">Oude televisie</string>\n    <string name=\"shuffle_blur\">Shuffle-vervaging</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Overgang</string>\n    <string name=\"peak\">Hoogtepunt</string>\n    <string name=\"color_anomaly\">Kleurafwijking</string>\n    <string name=\"images_overwritten\">Afbeeldingen die op de oorspronkelijke bestemming zijn overschreven</string>\n    <string name=\"tags_to_remove\">Tags Om Te Verwijderen</string>\n    <string name=\"apng_tools\">APNG-hulpmiddelen</string>\n    <string name=\"apng_type_to_image\">APNG naar afbeeldingen</string>\n    <string name=\"select_apng_image_to_start\">Kies APNG-afbeelding om te beginnen</string>\n    <string name=\"motion_blur\">Bewegingsonscherpte</string>\n    <string name=\"apng_tools_sub\">Converteer afbeeldingen naar APNG-afbeelding of extraheer frames uit een bepaalde APNG-afbeelding</string>\n    <string name=\"apng_type_to_image_sub\">Converteer een APNG-bestand naar een reeks afbeeldingen</string>\n    <string name=\"apng_type_to_apng_sub\">Converteer een reeks afbeeldingen naar een APNG-bestand</string>\n    <string name=\"apng_type_to_apng\">Afbeeldingen naar APNG</string>\n    <string name=\"zip\">ZIP-hulpmiddelen</string>\n    <string name=\"zip_sub\">Maak een zip-bestand van bepaalde bestanden of afbeeldingen</string>\n    <string name=\"drag_handle_width\">Sleep handvatbreedte</string>\n    <string name=\"confetti_type\">Confetti-type</string>\n    <string name=\"festive\">Feestelijk</string>\n    <string name=\"explode\">Explosie</string>\n    <string name=\"rain\">Regen</string>\n    <string name=\"corners\">Hoeken</string>\n    <string name=\"try_again\">Probeer het opnieuw</string>\n    <string name=\"show_settings_in_landscape\">Instellingen in de breedte weergeven</string>\n    <string name=\"show_settings_in_landscape_sub\">Indien uitgeschakeld, worden landschapsinstellingen geopend met de knop in de bovenste app-balk in plaats van altijd zichtbaar te zijn</string>\n    <string name=\"add_new_folder\">Nieuwe map toevoegen</string>\n    <string name=\"tag_bits_per_sample\">Bits Per Sample</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG uitwisselingsformaat</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG uitwisselingsformaatlengte</string>\n    <string name=\"tag_compression\">Compressie</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrische interpretatie</string>\n    <string name=\"tag_samples_per_pixel\">Samples Per Pixel</string>\n    <string name=\"tag_planar_configuration\">Planaire configuratie</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr sub-sampling</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr positionering</string>\n    <string name=\"tag_x_resolution\">X-resolutie</string>\n    <string name=\"tag_y_resolution\">Y-resolutie</string>\n    <string name=\"tag_resolution_unit\">Resolutie-eenheid</string>\n    <string name=\"tag_white_point\">Witpunt</string>\n    <string name=\"tag_primary_chromaticities\">Primaire chromaticiteiten</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr coëfficiënten</string>\n    <string name=\"tag_reference_black_white\">Zwart-witreferentie</string>\n    <string name=\"tag_datetime\">Datum/tijd</string>\n    <string name=\"tag_image_description\">Afbeeldingsbeschrijving</string>\n    <string name=\"tag_make\">Aanmaken</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_artist\">Maker</string>\n    <string name=\"tag_copyright\">Auteursrecht</string>\n    <string name=\"tag_flashpix_version\">Flashpix-versie</string>\n    <string name=\"tag_exif_version\">Exif-versie</string>\n    <string name=\"tag_color_space\">Kleurruimte</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X-grootte</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y-grootte</string>\n    <string name=\"tag_sensitivity_type\">Gevoeligheidstype</string>\n    <string name=\"tag_scene_capture_type\">Scène-opnametype</string>\n    <string name=\"tag_gps_area_information\">GPS-gebiedsinformatie</string>\n    <string name=\"jxl_type_to_jpeg\">JXL naar JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Verliesloze transcodering uitvoeren van JXL naar JPEG</string>\n    <string name=\"jxl_tools\">JXL-hulpmiddelen</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Verliesloze transcodering uitvoeren van JPEG naar JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG naar JXL</string>\n    <string name=\"select_jxl_image_to_start\">Kies JXL-afbeelding om te starten</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"pick_multiple_media\">Kies meerdere media</string>\n    <string name=\"pick_single_media\">Kies enkele media</string>\n    <string name=\"pick\">Kiezen</string>\n    <string name=\"compose_switch_sub\">Gebruikt Jetpack Compose Material You, het is niet zo mooi als op weergave gebaseerd</string>\n    <string name=\"fast_gaussian_blur_2d\">Snelle Gaussiaanse vervaging 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Snelle Gaussiaanse vervaging 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Snelle Gaussiaanse vervaging 4D</string>\n    <string name=\"gif_type_to_jxl\">GIF naar JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Converteer reeks afbeeldingen naar JXL-animatie</string>\n    <string name=\"gif_type_to_jxl_sub\">Converteer GIF-afbeeldingen naar JXL-geanimeerde afbeeldingen</string>\n    <string name=\"switch_type\">Schakeltype</string>\n    <string name=\"auto_paste_sub\">Hiermee kan de app klembordgegevens automatisch plakken, zodat deze op het hoofdscherm verschijnen en je deze kunt verwerken</string>\n    <string name=\"lanczos_bessel_sub\">Resampling-methode die interpolatie van hoge kwaliteit handhaaft door een Bessel (jinc) -functie toe te passen op de pixelwaarden</string>\n    <string name=\"generate_previews_sub\">Maakt het maken van voorbeelden mogelijk, wat crashes op sommige apparaten kan helpen voorkomen, maar dit schakelt ook enkele framebewerkingsfuncties uit</string>\n    <string name=\"lossy_compression\">Verliesgevende compressie</string>\n    <string name=\"lossy_compression_sub\">Gebruikt verliesgevende compressie om de bestandsgrootte te verkleinen</string>\n    <string name=\"speed_sub\">Bedient de resulterende beelddecoderingssnelheid, dit zou moeten helpen om het resulterende beeld sneller te openen, waarde %1$s staat voor de langzaamste decodering, %2$s is de snelste, deze instelling heeft invloed op de grootte van het uitvoerbeeld</string>\n    <string name=\"sorting\">Sortering</string>\n    <string name=\"fullscreen_settings_sub\">Indien ingeschakeld, worden de instellingen altijd op volledig scherm weergegeven in plaats van een schuifbaar ladeblad</string>\n    <string name=\"fullscreen_settings\">Volledig scherm-instellingen</string>\n    <string name=\"max\">Max</string>\n    <string name=\"fluent_switch_sub\">Gebruikt een Windows 11-stijl schakelaar op basis van het \\\"Fluent\\\" ontwerpsysteem</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"downscale_image_sub\">Afbeelding wordt voor verwerking verkleind, zodat de verwerking ervan sneller en veiliger kan worden uitgevoerd</string>\n    <string name=\"reset_properties_sub\">Alle eigenschappen worden ingesteld op standaardwaarden, deze actie kan niet ongedaan worden gemaakt</string>\n    <string name=\"default_line_width\">Standaard lijndikte</string>\n    <string name=\"resize_anchor\">Ankerformaat wijzigen</string>\n    <string name=\"fluent_switch\">Vloeiend</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Gebruikt iOS-achtige schakelaar op basis van een cupertino-ontwerpsysteem</string>\n    <string name=\"channels_configuration\">Kanalenconfiguratie</string>\n    <string name=\"header_today\">Vandaag</string>\n    <string name=\"header_yesterday\">Gisteren</string>\n    <string name=\"embedded_picker\">Ingesloten kiezer</string>\n    <string name=\"embedded_picker_sub\">Gebruik Image Toolbox\\'s eigen afbeeldingenkiezer in plaats van de systeemkiezer</string>\n    <string name=\"no_permissions\">Geen rechten</string>\n    <string name=\"request\">Verzoek</string>\n    <string name=\"legacy\">Verouderd</string>\n    <string name=\"lstm_network\">LSTM-netwerk</string>\n    <string name=\"legacy_and_lstm\">Verouderd &amp; LSTM</string>\n    <string name=\"auto_paste\">Automatisch plakken</string>\n    <string name=\"harmonization_color\">Kleurharmonisatie</string>\n    <string name=\"harmonization_level\">Harmonisatieniveau</string>\n    <string name=\"convert_sub\">Converteer reeksen afbeeldingen naar een bepaald formaat</string>\n    <string name=\"convert\">Converteren</string>\n    <string name=\"apng_type_to_jxl\">APNG naar JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Converteer APNG-afbeeldingen naar JXL-animaties</string>\n    <string name=\"jxl_type_to_images\">JXL naar afbeeldingen</string>\n    <string name=\"jxl_type_to_images_sub\">Converteer JXL-animatie naar reeks fotoreeks</string>\n    <string name=\"jxl_type_to_jxl\">Afbeeldingen naar JXL</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"behavior\">Gedrag</string>\n    <string name=\"skip_file_picking\">Bestandskeuze overslaan</string>\n    <string name=\"generate_previews\">Voorbeeldweergaven genereren</string>\n    <string name=\"skip_file_picking_sub\">Indien mogelijk wordt de bestandenkiezer automatisch geopend</string>\n    <string name=\"jxl_tools_sub\">JXL ~ JPEG-transcodering uitvoeren zonder kwaliteitsverlies, of converteer GIF/APNG naar JXL-animatie</string>\n    <string name=\"compression_type\">Compressietype</string>\n    <string name=\"sort_by_date\">Sortering op datum</string>\n    <string name=\"sort_by_date_reversed\">Sortering op datum (omgekeerd)</string>\n    <string name=\"sort_by_name\">Sortering op naam</string>\n    <string name=\"sort_by_name_reversed\">Sortering op naam (omgekeerd)</string>\n    <string name=\"images_to_svg\">Afbeeldingen naar SVG</string>\n    <string name=\"images_to_svg_sub\">Traceer bepaalde afbeeldingen naar SVG</string>\n    <string name=\"use_sampled_palette_sub\">Het kwantiseringspalet wordt bemonsterd als deze optie is ingeschakeld</string>\n    <string name=\"use_sampled_palette\">Bemonsterd palet gebruiken</string>\n    <string name=\"path_omit\">Pad negeren</string>\n    <string name=\"svg_warning\">Het gebruik van dit hulpmiddel voor het traceren van grote afbeeldingen zonder verkleining wordt afgeraden, het verhoogt de verwerkingstijd en kan leiden tot een crash</string>\n    <string name=\"downscale_image\">Afbeelding verkleinen</string>\n    <string name=\"min_color_ratio\">Minimale kleurverhouding</string>\n    <string name=\"lines_threshold\">Drempelwaarde lijnen</string>\n    <string name=\"quadratic_threshold\">Drempelwaarde kwadratisch</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolerantie voor afronding van coördinaten</string>\n    <string name=\"path_scale\">Padvergroting</string>\n    <string name=\"reset_properties\">Eigenschappen opnieuw instellen</string>\n    <string name=\"detailed\">Gedetailleerd</string>\n    <string name=\"tag_transfer_function\">Overdrachtsfunctie</string>\n    <string name=\"tag_strip_byte_counts\">Strip byte-tellingen</string>\n    <string name=\"tag_related_sound_file\">Gerelateerd geluidsbestand</string>\n    <string name=\"tag_user_comment\">Gebruikerscommentaar</string>\n    <string name=\"tag_maker_note\">Makersnotitie</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Gecomprimeerde Bits Per Pixel</string>\n    <string name=\"tag_datetime_original\">Datum/tijd origineel</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_spectral_sensitivity\">Spectrale gevoeligheid</string>\n    <string name=\"tag_exposure_program\">Belichtingsprogramma</string>\n    <string name=\"tag_f_number\">F-nummer</string>\n    <string name=\"tag_exposure_time\">Belichtingstijd</string>\n    <string name=\"tag_datetime_digitized\">Datum/tijd gedigitaliseerd</string>\n    <string name=\"tag_offset_time\">Offset-tijd</string>\n    <string name=\"tag_offset_time_original\">Offset-tijd origineel</string>\n    <string name=\"tag_offset_time_digitized\">Offset-tijd gedigitaliseerd</string>\n    <string name=\"tag_subsec_time\">Sub Sec-tijd</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec-tijd origineel</string>\n    <string name=\"tag_cfa_pattern\">CFA-patroon</string>\n    <string name=\"tag_file_source\">Bestandsbron</string>\n    <string name=\"tag_sensing_method\">Sensormethode</string>\n    <string name=\"tag_exposure_index\">Belichtingsindex</string>\n    <string name=\"tag_subject_location\">Onderwerp locatie</string>\n    <string name=\"tag_flash_energy\">Flitsvermogen</string>\n    <string name=\"tag_focal_length\">Brandpuntsafstand</string>\n    <string name=\"tag_subject_area\">Onderwerpgebied</string>\n    <string name=\"tag_flash\">Flits</string>\n    <string name=\"tag_metering_mode\">Meetmodus</string>\n    <string name=\"tag_subject_distance\">Onderwerp afstand</string>\n    <string name=\"tag_max_aperture_value\">Max. diafragmawaarde</string>\n    <string name=\"tag_exposure_bias_value\">Belichtingsbiaswaarde</string>\n    <string name=\"tag_brightness_value\">Helderheid waarde</string>\n    <string name=\"tag_aperture_value\">Diafragma waarde</string>\n    <string name=\"tag_shutter_speed_value\">Sluitersnelheid waarde</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Speed lengtegraad zzz</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Speed lengtegraad yyy</string>\n    <string name=\"tag_iso_speed\">ISO Speed</string>\n    <string name=\"tag_recommended_exposure_index\">Aanbevolen belichtingsindex</string>\n    <string name=\"tag_standard_output_sensitivity\">Standaard uitvoergevoeligheid</string>\n    <string name=\"tag_sharpness\">Scherpte</string>\n    <string name=\"tag_saturation\">Verzadiging</string>\n    <string name=\"tag_contrast\">Contrast</string>\n    <string name=\"tag_gain_control\">Versterking</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Brandpuntsafstand bij 35mm</string>\n    <string name=\"tag_digital_zoom_ratio\">Digitale zoomverhouding</string>\n    <string name=\"tag_white_balance\">Witbalans</string>\n    <string name=\"tag_exposure_mode\">Belichtingsmodus</string>\n    <string name=\"tag_custom_rendered\">Aangepaste weergave</string>\n    <string name=\"tag_gps_version_id\">GPS-versie ID</string>\n    <string name=\"tag_lens_serial_number\">Lens serienummer</string>\n    <string name=\"tag_lens_model\">Lens model</string>\n    <string name=\"tag_lens_make\">Lens merk</string>\n    <string name=\"tag_lens_specification\">Lens specificatie</string>\n    <string name=\"tag_body_serial_number\">Body serienummer</string>\n    <string name=\"tag_camera_owner_name\">Camera eigenaar</string>\n    <string name=\"tag_image_unique_id\">Afbeelding uniek ID</string>\n    <string name=\"tag_subject_distance_range\">Onderwerp afstandbereik</string>\n    <string name=\"tag_device_setting_description\">Apparaatinstelling beschrijving</string>\n    <string name=\"tag_gps_timestamp\">GPS-tijdstempel</string>\n    <string name=\"tag_gps_altitude\">GPS-hoogte</string>\n    <string name=\"tag_gps_longitude\">GPS-lengtegraad</string>\n    <string name=\"tag_gps_longitude_ref\">GPS-lengtegraad ref</string>\n    <string name=\"tag_gps_latitude\">GPS-breedtegraad</string>\n    <string name=\"tag_gps_latitude_ref\">GPS-breedtegraad ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS-bestemming Lengtegraad</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS-bestemmingskoers ref</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS-bestemmingsafstand ref</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS-bestemming lengtegraad ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS-bestemming breedtegraad</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS-bestemming breedtegraad ref</string>\n    <string name=\"tag_gps_map_datum\">GPS-kaart datum</string>\n    <string name=\"tag_gps_img_direction\">GPS-beeldkoers</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS-beeldkoers ref</string>\n    <string name=\"tag_gps_track\">GPS-spoor</string>\n    <string name=\"tag_gps_track_ref\">GPS-spoor ref</string>\n    <string name=\"tag_gps_speed\">GPS-snelheid</string>\n    <string name=\"tag_gps_speed_ref\">GPS-snelheid ref</string>\n    <string name=\"tag_gps_dop\">GPS-DOP</string>\n    <string name=\"tag_gps_measure_mode\">GPS-maatmodus</string>\n    <string name=\"tag_gps_status\">GPS-status</string>\n    <string name=\"tag_gps_satellites\">GPS-satellieten</string>\n    <string name=\"draw_text_sub\">Teken tekst op pad met gegeven lettertype en kleur</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sensor-bovenrand</string>\n    <string name=\"tag_rw2_sensor_right_border\">Sensor-rechterrand</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Sensor-onderrand</string>\n    <string name=\"tag_orf_aspect_frame\">Kaderverhouding</string>\n    <string name=\"tag_orf_preview_image_length\">Lengte voorbeeld</string>\n    <string name=\"tag_orf_preview_image_start\">Voorbeeld start</string>\n    <string name=\"tag_default_crop_size\">Standaard bijsnijdmaat</string>\n    <string name=\"tag_dng_version\">DNG-versie</string>\n    <string name=\"tag_interoperability_index\">Interoperabiliteitsindex</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H-positioneringsfout</string>\n    <string name=\"tag_gps_dest_distance\">GPS-bestemmingsafstand</string>\n    <string name=\"tag_gps_processing_method\">GPS-verwerkingsmethode</string>\n    <string name=\"tag_gps_differential\">GPS-differentiaal</string>\n    <string name=\"watermark_size\">Watermerkgrootte</string>\n    <string name=\"font_size\">Lettergrootte</string>\n    <string name=\"repeat_text_sub\">De huidige tekst wordt herhaald tot het einde van het pad in plaats van één keer tekenen</string>\n    <string name=\"repeat_text\">Tekst herhalen</string>\n    <string name=\"dash_size\">Streeplengte</string>\n    <string name=\"draw_image_sub\">Deze afbeelding wordt gebruikt als een herhaalde invoer van getekend pad</string>\n    <string name=\"draw_mode_image_sub\">Gebruik de geselecteerde afbeelding om deze langs het gegeven pad te tekenen</string>\n    <string name=\"share_as_pdf\">Delen als PDF</string>\n    <string name=\"save_as_pdf\">Opslaan als PDF</string>\n    <string name=\"start_scanning\">Scan starten</string>\n    <string name=\"click_to_start_scanning\">Klik om te scannen</string>\n    <string name=\"document_scanner\">Document-scanner</string>\n    <string name=\"equalize_histogram\">Histogram vereffenen</string>\n    <string name=\"allow_enter_by_text_field\">Invoer via tekstveld</string>\n    <string name=\"triangle\">Driehoek</string>\n    <string name=\"outlined_triangle\">Driehoek-contour</string>\n    <string name=\"triangle_sub\">Tekent een driehoek-contour van beginpunt tot eindpunt</string>\n    <string name=\"outlined_triangle_sub\">Tekent een driehoek van beginpunt tot eindpunt</string>\n    <string name=\"vertices\">Hoekpunten</string>\n    <string name=\"outlined_polygon_sub\">Tekent een veelhoek-contour van beginpunt tot eindpunt</string>\n    <string name=\"outlined_polygon\">Veelhoek-contour</string>\n    <string name=\"polygon\">Veelhoek</string>\n    <string name=\"polygon_sub\">Tekent een veelhoek van beginpunt tot eindpunt</string>\n    <string name=\"inner_radius_ratio\">Inwendige radiusverhouding</string>\n    <string name=\"outlined_star\">Stercontour</string>\n    <string name=\"outlined_star_sub\">Tekent een stercontour van beginpunt tot eindpunt</string>\n    <string name=\"star\">Ster</string>\n    <string name=\"star_sub\">Tekent een ster van beginpunt tot eindpunt</string>\n    <string name=\"draw_regular_polygon_sub\">Teken een regelmatige veelhoek in plaats van een vrije vorm</string>\n    <string name=\"draw_regular_polygon\">Regelmatige veelhoek tekenen</string>\n    <string name=\"material_you_switch_sub\">View Based Material You-schakelaar gebruiken. Dit oogt beter en bevat fraaie animaties.</string>\n    <string name=\"draw_regular_star_sub\">Teken een regelmatige ster in plaats van een vrije vorm</string>\n    <string name=\"tag_strip_offsets\">Strip offsets</string>\n    <string name=\"tag_rows_per_strip\">Rijen per strip</string>\n    <string name=\"enter_percentage\">Percentage invoeren</string>\n    <string name=\"equalize_histogram_hsv\">HSV-histogram vereffenen</string>\n    <string name=\"options_below_is_for_images\">Onderstaande opties betreffen de opslag van afbeeldingen, niet PDF</string>\n    <string name=\"document_scanner_sub\">Scan documenten om er een PDF of een reeks afbeeldingen van te maken</string>\n    <string name=\"draw_regular_star\">Regelmatige ster tekenen</string>\n    <string name=\"tag_rw2_sensor_left_border\">Sensor-linkerrand</string>\n    <string name=\"tag_gps_dest_bearing\">GPS-bestemmingskoers</string>\n    <string name=\"tag_gps_datestamp\">GPS-datumstempel</string>\n    <string name=\"tag_gps_altitude_ref\">GPS-hoogte ref</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Focusvlak resolutie-eenheid</string>\n    <string name=\"tag_focal_plane_y_resolution\">Focusvlak Y-resolutie</string>\n    <string name=\"tag_focal_plane_x_resolution\">Focusvlak X-resolutie</string>\n    <string name=\"tag_spatial_frequency_response\">Ruimtelijke frequentierespons</string>\n    <string name=\"tag_photographic_sensitivity\">Fotografische gevoeligheid</string>\n    <string name=\"tag_subsec_time_digitized\">Sub Sec-tijd gedigitaliseerd</string>\n    <string name=\"allow_enter_by_text_field_sub\">Maakt tekstveld achter de selectie van voorinstellingen mogelijk om deze direct in te voeren</string>\n    <string name=\"engine_mode\">Machine-modus</string>\n    <string name=\"antialias_sub\">Maakt anti-aliasing mogelijk om scherpe randen te voorkomen</string>\n    <string name=\"antialias\">Anti-alias</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Wanneer je een afbeelding selecteert om te openen (preview) in ImageToolbox, wordt het selectieblad voor bewerken geopend in plaats van een voorbeeld te bekijken</string>\n    <string name=\"open_edit_instead_of_preview\">Open Bewerken in plaats van Voorbeeld</string>\n    <string name=\"scale_color_space\">Kleurruimte-schaal</string>\n    <string name=\"linear\">Lineair</string>\n    <string name=\"equalize_histogram_pixelation\">Pixelvorming-histogram vereffenen</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Histogram adaptief vereffenen LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Histogram adaptief vereffenen LAB</string>\n    <string name=\"grid_size_x\">Rastergrootte X</string>\n    <string name=\"grid_size_y\">Rastergrootte Y</string>\n    <string name=\"equalize_histogram_adaptive\">Histogram adaptief vereffenen</string>\n    <string name=\"clahe\">Clahe</string>\n    <string name=\"clahe_lab\">Clahe LAB</string>\n    <string name=\"clahe_luv\">Clahe LUV</string>\n    <string name=\"crop_to_content\">Bijsnijden naar inhoud</string>\n    <string name=\"frame_color\">Kleur kader</string>\n    <string name=\"color_to_ignore\">Kleur om te negeren</string>\n    <string name=\"template_filter\">Filtersjabloon</string>\n    <string name=\"as_qr_code\">Als QR-code afbeelding</string>\n    <string name=\"as_file\">Als bestand</string>\n    <string name=\"save_as_file\">Opslaan als bestand</string>\n    <string name=\"save_as_qr_code_image\">Opslaan als QR-code afbeelding</string>\n    <string name=\"delete_template\">Sjabloon verwijderen</string>\n    <string name=\"delete_template_warn\">Je staat op het punt het geselecteerde sjabloonfilter te verwijderen. Deze operatie kan niet ongedaan worden gemaakt.</string>\n    <string name=\"added_filter_template\">Filtersjabloon toegevoegd met naam \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Filtervoorbeeld</string>\n    <string name=\"qr_code\">QR-code</string>\n    <string name=\"qr_code_sub\">Scan QR-code voor de inhoud of plak de tekenreeks om een nieuwe te genereren</string>\n    <string name=\"code_content\">Inhoudscode</string>\n    <string name=\"template\">Sjabloon</string>\n    <string name=\"no_template_filters\">Geen filtersjabloon toegevoegd</string>\n    <string name=\"create_new\">Nieuw aanmaken</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">De gescande QR-code is geen geldig filtersjabloon</string>\n    <string name=\"create_template\">Sjabloon aanmaken</string>\n    <string name=\"scan_qr_code\">QR-code scannen</string>\n    <string name=\"opened_file_have_no_filter_template\">Geselecteerd bestand bevat geen filtersjabloongegevens</string>\n    <string name=\"template_name\">Sjabloonnaam</string>\n    <string name=\"select_template_preview\">Deze afbeelding wordt gebruikt als voorbeeld voor het filtersjabloon</string>\n    <string name=\"scan_qr_code_to_replace_content\">Scan QR-code om inhoud in het veld te vervangen of typ iets om nieuwe QR-code te genereren</string>\n    <string name=\"qr_description\">QR-beschrijving</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Geef camera toestemming in instellingen om QR-codes te scannen</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kubische interpolatie zorgt voor een soepelere schaal door de dichtstbijzijnde 16 pixels te beschouwen, wat betere resultaten oplevert dan bilineair</string>\n    <string name=\"bspline_sub\">Maakt gebruik van door het werk gedefinieerde polynoomfuncties om een curve of oppervlak soepel te interpoleren en te benaderen, flexibele en continue vormweergave</string>\n    <string name=\"hamming_sub\">Een functie die wordt gebruikt om spectrale lekkage te verminderen door de randen van een signaal af te bouwen, handig bij signaalverwerking</string>\n    <string name=\"welch_sub\">Een functie die is ontworpen om een goede frequentieresolutie te geven met verminderde spectrale lekkage, vaak gebruikt in signaalverwerkingstoepassingen</string>\n    <string name=\"quadric_sub\">Een methode die een kwadratische functie gebruikt voor interpolatie, die soepele en continue resultaten oplevert</string>\n    <string name=\"sphinx_sub\">Een geavanceerde methode van herbemonstering die hoogwaardige interpolatie biedt met minimale artefacten</string>\n    <string name=\"box_sub\">Een eenvoudige methode van herbemonstering die het gemiddelde van de dichtstbijzijnde pixelwaarden gebruikt, wat vaak in een blokachtig resultaat oplevert</string>\n    <string name=\"bohman_sub\">Een functie die wordt gebruikt om spectrale lekkage te verminderen, wat zorgt voor een goede frequentieresolutie in signaalverwerkingstoepassingen</string>\n    <string name=\"lanczos2_sub\">Een methode van herbemonstering die een Lanczos-filter met 2 lobben gebruikt voor hoogwaardige interpolatie met minimale artefacten</string>\n    <string name=\"lanczos3_sub\">Een methode van herbemonstering die een Lanczos-filter met 3 lobben gebruikt voor hoogwaardige interpolatie met minimale artefacten</string>\n    <string name=\"lanczos4_sub\">Een methode van herbemonstering die een Lanczos-filter met 4 lobben gebruikt voor hoogwaardige interpolatie met minimale artefacten</string>\n    <string name=\"lanczos2_jinc_sub\">Een variant van het Lanczos 2-filter dat gebruik maakt van de jinc-functie en hoogwaardige interpolatie biedt met minimale artefacten</string>\n    <string name=\"lanczos3_jinc_sub\">Een variant van het Lanczos 3-filter dat de jinc-functie gebruikt en hoogwaardige interpolatie biedt met minimale artefacten</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"box\">Box</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"cubic\">Cubic</string>\n    <string name=\"gaussian\">Gaussian</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"spline36_sub\">Een op spline gebaseerde interpolatiemethode die vloeiende resultaten oplevert met een 36-tapfilter</string>\n    <string name=\"hanning_sub\">Een variant van het Hann-venster, vaak gebruikt om spectrale lekkage in signaalverwerkingstoepassingen te verminderen</string>\n    <string name=\"blackman_sub\">Een functie die een goede frequentieresolutie biedt door spectrale lekkage te minimaliseren, vaak gebruikt bij signaalverwerking</string>\n    <string name=\"bartlett_sub\">Een driehoekige functie die wordt gebruikt bij signaalverwerking om spectrale lekkage te verminderen</string>\n    <string name=\"gaussian_sub\">Een interpolatiemethode die een Gauss-functie toepast, handig om ruis in afbeeldingen glad te strijken en te verminderen</string>\n    <string name=\"robidoux_sub\">Een hoogwaardige interpolatiemethode die is geoptimaliseerd voor het verkleinen van natuurlijke beelden, het balanceren van scherpte en gladheid</string>\n    <string name=\"robidoux_sharp_sub\">Een scherpere variant van de Robidoux-methode, geoptimaliseerd voor scherp beeldformaat</string>\n    <string name=\"spline16_sub\">Een op spline gebaseerde interpolatiemethode die vloeiende resultaten oplevert met een 16-tapfilter</string>\n    <string name=\"spline64_sub\">Een op spline gebaseerde interpolatiemethode die vloeiende resultaten oplevert met een 64-tapfilter</string>\n    <string name=\"kaiser_sub\">Een interpolatiemethode die gebruik maakt van het Kaiser-venster, die een goede controle biedt over de afweging tussen de breedte van de hoofdlobben en het niveau van de zijlobben</string>\n    <string name=\"bartlett_hann_sub\">Een hybride functie die de Bartlett- en Hann-vensters combineert, die wordt gebruikt om spectrale lekkage in signaalverwerking te verminderen</string>\n    <string name=\"lanczos4_jinc_sub\">Een variant van het Lanczos 4-filter dat gebruik maakt van de jinc-functie en hoogwaardige interpolatie biedt met minimale artefacten</string>\n    <string name=\"ewa_blackman_sub\">Elliptiisch gewogen gemiddelde (EWA) -variant van het Blackman-filter voor het minimaliseren van ringartefacten</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Elliptische gewogen gemiddelde (EWA) variant van het Hanning-filter voor soepele interpolatie en resampling</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elliptische gewogen gemiddelde (EWA) variant van het Robidoux-filter voor hoogwaardige resampling</string>\n    <string name=\"ewa_quadric_sub\">Elliptisch gewogen gemiddelde (EWA) -variant van het quadrische filter voor soepele interpolatie</string>\n    <string name=\"ginseng_sub\">Een resamplingfilter ontworpen voor hoogwaardige beeldverwerking met een goede balans tussen scherpte en gladheid</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elliptische gewogen gemiddelde (EWA) variant van het Robidoux Sharp-filter voor scherpere resultaten</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Elliptisch gewogen gemiddelde (EWA) variant van het Lanczos 3 Jinc filter voor hoogwaardige resampling met gereduceerde aliasing</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Elliptische gewogen gemiddelde (EWA) variant van het Ginseng-filter voor verbeterde beeldkwaliteit</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Elliptische gewogen gemiddelde (EWA) variant van het Lanczos Sharp-filter voor het bereiken van scherpe resultaten met minimale artefacten</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Elliptisch gewogen gemiddelde (EWA) -variant van de Lanczos 4 Sharpest-filter voor extreem scherpe beeldherbinding</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptisch gewogen gemiddelde (EWA) -variant van het Lanczos Soft-filter voor een soepelere beeldherbemonstering</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"format_conversion\">Formaatconversie</string>\n    <string name=\"haasn_soft_sub\">Een door Haasn ontworpen resamplingfilter voor een soepele en artefactvrije beeldschaling</string>\n    <string name=\"format_conversion_sub\">Reeks afbeeldingen van het ene formaat naar het andere omzetten</string>\n    <string name=\"dismiss_forever\">Voor altijd afwijzen</string>\n    <string name=\"add_image\">Afbeelding toevoegen</string>\n    <string name=\"image_stacking\">Afbeeldingen stapelen</string>\n    <string name=\"image_stacking_sub\">Stapel afbeeldingen op elkaar met gekozen mengmodi</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Histogram egaliseren - Adaptieve HSL</string>\n    <string name=\"bins_count\">Aantal bins</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Histogram egaliseren - Adaptieve HSV</string>\n    <string name=\"wrap\">Wikkelen</string>\n    <string name=\"edge_mode\">Edge-modus</string>\n    <string name=\"clip\">Knippen</string>\n    <string name=\"color_blind_scheme\">Schema voor kleurblindheid</string>\n    <string name=\"protanopia_sub\">Onvermogen om rode tinten waar te nemen</string>\n    <string name=\"deuteranopia_sub\">Onvermogen om groene tinten waar te nemen</string>\n    <string name=\"not_use_color_blind_scheme\">Geen schema voor kleurblindheid gebruiken</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Een 3e orde Lagrange interpolatiefilter, met betere nauwkeurigheid en vloeiendere resultaten voor beeldschaling</string>\n    <string name=\"lanczos_6_sub\">Een 6e orde Lanczos-resamplingfilter, voor scherpere en nauwkeurigere beeldschaling</string>\n    <string name=\"tritanomaly_sub\">Moeite met onderscheid tussen blauwe en gele tinten</string>\n    <string name=\"tritanopia_sub\">Onvermogen om blauwe tinten waar te nemen</string>\n    <string name=\"achromatomaly_sub\">Verminderde gevoeligheid voor alle kleuren</string>\n    <string name=\"achromatopsia_sub\">Volledige kleurenblindheid met alleen grijstinten</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Kleuren zijn precies zoals vastgelegd in het thema</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Een 2e orde Lagrange interpolatiefilter, geschikt voor hoogwaardige beeldschaling met vloeiende overgangen</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Een variant van het Lanczos 6-filter met behulp van een Jinc-functie voor verbeterde beeldresamplingkwaliteit</string>\n    <string name=\"deuteranomaly_sub\">Moeite met onderscheid tussen groene en rode tinten</string>\n    <string name=\"protanomaly_sub\">Moeite met onderscheid tussen rode en groene tinten</string>\n    <string name=\"color_blind_scheme_sub\">Selecteer modus om themakleuren aan te passen voor een bepaalde variant in kleurblindheid</string>\n    <string name=\"linear_gaussian_box_blur\">Lineaire Gaussbox-vervaging</string>\n    <string name=\"linear_tent_blur\">Lineaire tent-vervaging</string>\n    <string name=\"linear_box_blur\">Lineaire vak-vervaging</string>\n    <string name=\"linear_stack_blur\">Lineaire gestapelde vervaging</string>\n    <string name=\"gaussian_box_blur\">Gaussiaanse vak-vervaging</string>\n    <string name=\"replace_filter\">Filter vervangen</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lineaire snelle Gaussiaanse vervaging Next</string>\n    <string name=\"linear_fast_gaussian_blur\">Lineaire snelle Gaussiaanse vervaging</string>\n    <string name=\"linear_gaussian_blur\">Lineaire Gaussiaanse vervaging</string>\n    <string name=\"draw_filter_sub\">Kies een filter om als verf te gebruiken</string>\n    <string name=\"pick_filter_info\">Kies hieronder het filter om het als penseel in je tekening te gebruiken</string>\n    <string name=\"tiff_compression_scheme\">TIFF-compressiemethode</string>\n    <string name=\"sand_painting\">Zandschildering</string>\n    <string name=\"low_poly\">Low Poly</string>\n    <string name=\"image_splitting\">Afbeelding splitsen</string>\n    <string name=\"image_splitting_sub\">Splits een enkele afbeelding in rijen en kolommen</string>\n    <string name=\"languages_imported\">Talen met succes geïmporteerd</string>\n    <string name=\"backup_ocr_models\">Back-up OCR-modellen</string>\n    <string name=\"import_word\">Importeren</string>\n    <string name=\"export\">Exporteren</string>\n    <string name=\"position\">Positie</string>\n    <string name=\"center\">Midden</string>\n    <string name=\"top_left\">Linksboven</string>\n    <string name=\"fit_to_bounds\">Passend binnen begrenzing</string>\n    <string name=\"fit_to_bounds_sub\">Combineer grootte aanpassen met deze parameter om het gewenste gedrag te bereiken (Bijsnijden/Passend in verhouding)</string>\n    <string name=\"top_right\">Rechtsboven</string>\n    <string name=\"bottom_left\">Linksonder</string>\n    <string name=\"bottom_right\">Rechtsonder</string>\n    <string name=\"top_center\">Midden boven</string>\n    <string name=\"center_right\">Midden rechts</string>\n    <string name=\"bottom_center\">Midden onder</string>\n    <string name=\"center_left\">Midden links</string>\n    <string name=\"enhanced_oil\">Verbeterd olie</string>\n    <string name=\"simple_old_tv\">Eenvoudige TV</string>\n    <string name=\"target_image\">Doel</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"palette_transfer\">Palet overzetten</string>\n    <string name=\"simple_sketch\">Eenvoudige schets</string>\n    <string name=\"soft_glow\">Zachte gloed</string>\n    <string name=\"color_poster\">Kleurenposter</string>\n    <string name=\"tri_tone\">Driekleur</string>\n    <string name=\"third_color\">Derde kleur</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"clustered_8x8_dithering\">Geclusterde 8x8 dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma dithering</string>\n    <string name=\"polka_dot\">Polkadot</string>\n    <string name=\"clustered_2x2_dithering\">Geclusterde 2x2 dithering</string>\n    <string name=\"clustered_4x4_dithering\">Geclusterde 4x4 dithering</string>\n    <string name=\"harmony_complementary\">Complementair</string>\n    <string name=\"harmony_analogous\">Analoog</string>\n    <string name=\"harmony_triadic\">Triadisch</string>\n    <string name=\"harmony_split_complementary\">Gescheiden Complementair</string>\n    <string name=\"harmony_tetradic\">Tetradisch</string>\n    <string name=\"harmony_square\">Vierkant</string>\n    <string name=\"harmony_analogous_complementary\">Analoog + Complementair</string>\n    <string name=\"tints\">Tinten</string>\n    <string name=\"tones\">Tonen</string>\n    <string name=\"color_mixing\">Kleurmenging</string>\n    <string name=\"color_info\">Kleurinformatie</string>\n    <string name=\"selected_color\">Geselecteerde kleur</string>\n    <string name=\"color_to_mix\">Kleur om te mengen</string>\n    <string name=\"shades\">Tinten</string>\n    <string name=\"target_lut_image\">LUT-doelafbeelding</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"soft_elegance_variant\">Soft Elegance-variant</string>\n    <string name=\"no_favorite_options_selected\">Geen favoriete opties geselecteerd, voeg ze toe aan de pagina Hulpmiddelen</string>\n    <string name=\"add_favorites\">Favorieten toevoegen</string>\n    <string name=\"color_tools\">Kleurentools</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"variation\">Variatie</string>\n    <string name=\"soft_elegance\">Soft Elegance</string>\n    <string name=\"color_tools_sub\">Meng, maak tonen, genereer tinten en meer</string>\n    <string name=\"color_harmonies\">Kleurharmonieën</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"color_shading\">Kleurtint</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Kan Monet niet gebruiken terwijl dynamische kleuren zijn ingeschakeld</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"palette_transfer_variant\">Paletoverdracht-variant</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"fall_colors\">Herfstkleuren</string>\n    <string name=\"foggy_night\">Mistige nacht</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"save_empty_lut\">Neutrale LUT-afbeelding verkrijgen</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Doel 3D LUT-bestand (.cube / .CUBE)</string>\n    <string name=\"candlelight\">Kaarslicht</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut_sub\">Gebruik eerst je favoriete fotobewerkingstoepassing om een filter toe te passen op neutrale LUT die je hier kunt verkrijgen. Om dit goed te laten werken, mag elke pixelkleur niet afhankelijk zijn van andere pixels (onverduistering werkt bijvoorbeeld niet). Als je klaar bent, gebruik je je nieuwe LUT-afbeelding als invoer voor 512*512 LUT-filter</string>\n    <string name=\"edgy_amber\">Edgy Amber</string>\n    <string name=\"film_stock_50\">Film Stock 50</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"golden_forest\">Golden Forest</string>\n    <string name=\"coffee\">Koffie</string>\n    <string name=\"greenish\">Greenish</string>\n    <string name=\"retro_yellow\">Retro Yellow</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Geef camera toestemming in Instellingen om Document-scanner te scannen</string>\n    <string name=\"links_preview\">Links Voorbeeld</string>\n    <string name=\"links\">Links</string>\n    <string name=\"links_preview_sub\">Hiermee kun je een voorbeeld van een link ophalen op plaatsen waar je tekst kunt verkrijgen (QRCode, OCR etc)</string>\n    <string name=\"ico_size_warning\">Ico-bestanden kunnen alleen worden opgeslagen met een maximale grootte van 256*256, grotere waarden worden naar deze afmetingen verkleind</string>\n    <string name=\"webp_type_to_webp_sub\">Converteer een reeks afbeeldingen naar een WEBP-bestand</string>\n    <string name=\"webp_type_to_webp\">Images naar WEBP</string>\n    <string name=\"select_webp_image_to_start\">Kies een WEBP-afbeelding om te starten</string>\n    <string name=\"gif_type_to_webp\">GIF naar WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Converteer GIF-afbeeldingen naar WEBP-animatiefoto\\'s</string>\n    <string name=\"webp_type_to_image_sub\">Converteer het WEBP-bestand naar een reeks afbeeldingen</string>\n    <string name=\"webp_tools\">WEBP-hulpmiddelen</string>\n    <string name=\"webp_tools_sub\">Converteer afbeeldingen naar WEBP-animatie of extraheer frames van gegeven WEBP-animatie</string>\n    <string name=\"webp_type_to_image\">WEBP naar afbeeldingen</string>\n    <string name=\"manage_storage_extra_types\">Geen volledige toegang tot bestanden</string>\n    <string name=\"default_draw_color\">Standaard tekenkleur</string>\n    <string name=\"default_draw_path_mode\">Standaard padmodus tekenen</string>\n    <string name=\"add_timestamp\">Tijdstempel toevoegen</string>\n    <string name=\"add_timestamp_sub\">Schakelt Tijdstempel in en voegt deze toe aan de naam van het uitvoerbestand</string>\n    <string name=\"formatted_timestamp\">Tijdstempel met opmaak</string>\n    <string name=\"enable_timestamps_to_format_them\">Schakel Tijdstempel in om de opmaak te selecteren</string>\n    <string name=\"manage_storage_extra_types_sub\">Verleen toegang tot alle bestanden om JXL, QOI en andere afbeeldingen te zien die op Android niet worden herkend als afbeeldingsbestanden. Zonder deze toestemming, zijn deze afbeeldingen hier niet zien.</string>\n    <string name=\"formatted_timestamp_sub\">Tijdstempel-opmaak inschakelen in de naam van het uitvoerbestand in plaats van standaard milliseconden</string>\n    <string name=\"recently_used\">Recent gebruikt</string>\n    <string name=\"ci_channel\">CI-kanaal</string>\n    <string name=\"one_time_save_location\">Eenmalige opslaglocatie</string>\n    <string name=\"group\">Groep</string>\n    <string name=\"one_time_save_location_sub\">Eenmalige opslaglocaties bekijken en bewerken die u kunt gebruiken door lang op de opslagknop te drukken in vrijwel alle opties</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Sluit aan bij onze chat waar je alles kunt bespreken wat je wilt en kijk ook naar het CI-kanaal waar ik bèta\\'s en aankondigingen plaats</string>\n    <string name=\"ci_channel_sub\">Ontvang een melding over nieuwe versies van de app en lees aankondigingen</string>\n    <string name=\"image_toolbox_in_telegram\">ImageToolbox op Telegram 🎉</string>\n    <string name=\"fit_description\">Pas een afbeelding aan op een bepaalde afmeting en pas vervaging of kleur toe op de achtergrond</string>\n    <string name=\"tools_arrangement\">Hulpmiddelen ordenen</string>\n    <string name=\"group_tools_by_type\">Groeperen op type</string>\n    <string name=\"group_tools_by_type_sub\">Groepeer hulpmiddelen op het hoofdscherm op basis van hun type in plaats van een aangepaste lijstindeling</string>\n    <string name=\"default_values\">Standaardwaarden</string>\n    <string name=\"system_bars_visibility\">Zichtbaarheid van systeembalken</string>\n    <string name=\"show_system_bars_by_swipe\">Systeembalken weergeven door te vegen</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Maakt vegen mogelijk om systeembalken weer te geven als ze verborgen zijn</string>\n    <string name=\"auto\">Autom.</string>\n    <string name=\"show_all\">Alles weergeven</string>\n    <string name=\"hide_nav_bar\">Navigatiebalk verbergen</string>\n    <string name=\"hide_status_bar\">Statusbalk verbergen</string>\n    <string name=\"noise_generation\">Ruis genereren</string>\n    <string name=\"noise_generation_sub\">Genereer verschillende varianten ruis zoals Perlin of andere typen</string>\n    <string name=\"frequency\">Frequentie</string>\n    <string name=\"noise_type\">Type ruis</string>\n    <string name=\"rotation_type\">Rotatie</string>\n    <string name=\"fractal_type\">Fractal</string>\n    <string name=\"octaves\">Octaven</string>\n    <string name=\"lacunarity\">Lacunariteit</string>\n    <string name=\"gain\">Versterking</string>\n    <string name=\"weighted_strength\">Gewogen sterkte</string>\n    <string name=\"ping_pong_strength\">Ping-pongsterkte</string>\n    <string name=\"distance_function\">Afstandsfunctie</string>\n    <string name=\"return_type\">Returntype</string>\n    <string name=\"domain_warp\">Domein Warp</string>\n    <string name=\"alignment\">Uitlijning</string>\n    <string name=\"custom_filename\">Aangepaste bestandsnaam</string>\n    <string name=\"saved_to_custom\">Opgeslagen in map met aangepaste naam</string>\n    <string name=\"hide_all\">Alles verbergen</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"custom_filename_sub\">Selecteer de locatie en bestandsnaam die worden gebruikt om de huidige afbeelding op te slaan</string>\n    <string name=\"collage_maker\">Collagemaker</string>\n    <string name=\"collage_maker_sub\">Maak verschillende collages van 20 afbeeldingen</string>\n    <string name=\"collage_type\">Collagetype</string>\n    <string name=\"collages_info\">Houd de afbeelding ingedrukt om de positie te wisselen, verplaatsen en zoomen</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">RGB- of helderheidsbeeldhistogram om je te helpen aanpassingen te maken</string>\n    <string name=\"image_for_histogram\">Deze afbeelding wordt gebruikt om RGB- en helderheidshistogrammen te genereren</string>\n    <string name=\"custom_options\">Aangepaste opties</string>\n    <string name=\"custom_params_info\">Voer opties in volgens dit patroon: \\\"--{optie_naam} {waarde}\\\"</string>\n    <string name=\"tesseract_options\">Tesseract-opties</string>\n    <string name=\"tesseract_options_sub\">Geef enkele invoervariabelen op voor de tesseract-engine</string>\n    <string name=\"free_corners\">Vrije hoeken</string>\n    <string name=\"coerce_points_to_image_bounds\">Punten naar afbeeldingsgrenzen dwingen</string>\n    <string name=\"spot_heal_sub\">Inhoudsbewust invullen onder getekend pad</string>\n    <string name=\"spot_heal\">Vlekcorrectie</string>\n    <string name=\"auto_crop\">Autom. bijsnijden</string>\n    <string name=\"free_corners_sub\">Afbeelding bijsnijden met veelhoek. (incl. perspectiefcorrectie)</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Punten worden niet beperkt door beeldgrenzen, dit is handig voor nauwkeurigere perspectiefcorrectie</string>\n    <string name=\"mask\">Masker</string>\n    <string name=\"opening\">Openen</string>\n    <string name=\"morphological_gradient\">Morfologisch kleurverloop</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"use_circle_kernel\">Cirkelkern gebruiken</string>\n    <string name=\"closing\">Sluiten</string>\n    <string name=\"black_hat\">Black Hat</string>\n    <string name=\"tone_curves\">Kleurtooncurven</string>\n    <string name=\"reset_curves\">Curven terugzetten</string>\n    <string name=\"reset_curves_sub\">Curven worden hersteld naar standaardwaarden</string>\n    <string name=\"line_style\">Lijnstijl</string>\n    <string name=\"gap_size\">Tussenruimte</string>\n    <string name=\"dashed\">Gestreept</string>\n    <string name=\"dot_dashed\">Streep-punt</string>\n    <string name=\"stamped\">Gestempeld</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Tekent een stippellijn langs het getekende pad met gespecificeerde tussenruimte</string>\n    <string name=\"dot_dashed_sub\">Tekent punt en stippellijn langs het gegeven pad</string>\n    <string name=\"defaultt_sub\">Gewoon standaard rechte lijnen</string>\n    <string name=\"stamped_sub\">Tekent geselecteerde vormen langs het pad met gespecificeerde afstand</string>\n    <string name=\"zigzag_sub\">Tekent golvende zigzag langs het pad</string>\n    <string name=\"zigzag_ratio\">Zigzag-verhouding</string>\n    <string name=\"create_shortcut_title\">Vast te maken hulpmiddel</string>\n    <string name=\"dont_stack_frames_sub\">Maakt het mogelijk om voorgaande frames te verwijderen, zodat ze niet opstapelen</string>\n    <string name=\"dont_stack_frames\">Frames niet opstapelen</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Frames maken een overgang via vermenging</string>\n    <string name=\"crossfade_count\">Aantal crossfade-frames</string>\n    <string name=\"threshold_one\">Drempelwaarde 1</string>\n    <string name=\"threshold_two\">Drempelwaarde 2</string>\n    <string name=\"create_shortcut\">Snelkoppeling aanmaken</string>\n    <string name=\"create_shortcut_subtitle\">Hulpmiddel wordt als snelkoppeling toegevoegd aan het startscherm, gebruik het in combinatie met de optie \\\"bestandskeuze overslaan\\\" om het benodigde gedrag te bereiken</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Spiegelen 101</string>\n    <string name=\"enhanced_zoom_blur\">Verbeterde zoomvervaging</string>\n    <string name=\"sobel_simple\">Sobel Eenvoudig</string>\n    <string name=\"laplacian_simple\">Laplaciaans Eenvoudig</string>\n    <string name=\"helper_grid\">Hulpraster</string>\n    <string name=\"helper_grid_sub\">Toont ondersteunend raster over het tekengebied om te helpen bij nauwkeurige manipulaties</string>\n    <string name=\"grid_color\">Rasterkleur</string>\n    <string name=\"cell_width\">Celbreedte</string>\n    <string name=\"cell_height\">Celhoogte</string>\n    <string name=\"compact_selectors_sub\">Sommige selectiebesturingselementen gebruiken een compacte lay-out om minder ruimte in te nemen</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Geef de camera toestemming in de instellingen om een afbeelding vast te leggen</string>\n    <string name=\"layout\">Opmaak</string>\n    <string name=\"main_screen_title\">Titel van het hoofdscherm</string>\n    <string name=\"compact_selectors\">Compacte keuzeschakelaars</string>\n    <string name=\"constant_rate_factor\">Constant Rate Factor (CRF)</string>\n    <string name=\"crf_sub\">Een waarde %1$s betekent een langzame compressie, resulterend in een relatief kleine bestandsgrootte. %2$s betekent een snellere compressie, resulterend in een groot bestand.</string>\n    <string name=\"lut_library\">Lut-bilbiotheek</string>\n    <string name=\"lut_library_sub\">Download een verzameling LUT\\'s die je vervolgens kunt toepassen</string>\n    <string name=\"lut_library_update_sub\">Collectie LUT\\'s bijwerken (alleen nieuwe worden in de wachtrij geplaatst), die je vervolgens kunt toepassen</string>\n    <string name=\"filter_preview_image\">Voorbeeldweergave</string>\n    <string name=\"filter_preview_image_sub\">Standaard voorbeeldweergave voor filters wijzigen</string>\n    <string name=\"hide\">Verbergen</string>\n    <string name=\"show\">Weergeven</string>\n    <string name=\"fancy_sub\">Aangepaste, mooi uitziende schuifregelaar met animaties, dit is standaard voor deze app</string>\n    <string name=\"slider_type\">Schuifregelaar</string>\n    <string name=\"material_you_slider_sub\">Moderne Material You-schuifregelaar, futuristisch, fris, toegankelijk</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy\">Fraai</string>\n    <string name=\"material_2_sub\">Material 2 gebaseerde schuifregelaar, niet modern, eenvoudig en rechttoe rechtaan</string>\n    <string name=\"apply\">Toepassen</string>\n    <string name=\"center_align_dialog_buttons\">Dialoogknoppen centreren</string>\n    <string name=\"open_source_licenses\">Open source-licenties</string>\n    <string name=\"open_source_licenses_sub\">Bekijk licenties van open source-bibliotheken die in deze app worden gebruikt</string>\n    <string name=\"center_align_dialog_buttons_sub\">Knoppen van dialogen worden indien mogelijk in het midden geplaatst in plaats van aan de linkerkant</string>\n    <string name=\"area\">Oppervlakte</string>\n    <string name=\"enable_tonemapping\">Tonemapping inschakelen</string>\n    <string name=\"area_sub\">Opnieuw bemonsteren op basis van pixelgebiedrelatie. Deze methode geniet de voorkeur beelddecimering, omdat het resultaten levert zonder moiré. Maar wanneer het beeld is ingezoomd, is het vergelijkbaar met de dichtstbijzijnde-methode.</string>\n    <string name=\"markup_layers_sub\">Lagen-modus met mogelijkheid om afbeeldingen, tekst en meer vrij te plaatsen</string>\n    <string name=\"edit_layer\">Laag bewerken</string>\n    <string name=\"layers_on_background\">Lagen in achtergrond</string>\n    <string name=\"layers_on_background_sub\">Hetzelfde als eerste optie, maar met kleur in plaats van afbeelding</string>\n    <string name=\"unknown_host\">Geen toegang tot de site, probeer VPN te gebruiken of controleer of de url correct is</string>\n    <string name=\"markup_layers\">Opmaaklagen</string>\n    <string name=\"layers_on_image\">Lagen over afbeelding</string>\n    <string name=\"layers_on_image_sub\">Gebruik afbeelding als achtergrond en voeg er verschillende lagen bovenop toe</string>\n    <string name=\"enter_percent\">% invoeren</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Snelle instellingen-strook</string>\n    <string name=\"fast_settings_side_sub\">Voeg een zwevende strook toe aan de gekozen kant tijdens het bewerken van afbeeldingen, die snelle instellingen opent als erop wordt geklikt</string>\n    <string name=\"clear_selection\">Selectie wissen</string>\n    <string name=\"settings_group_visibility_visible\">In te stellen groep \\\"%1$s\\\" wordt standaard uitgevouwen</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">De opgegeven waarde is geen geldige Base64-tekenreeks</string>\n    <string name=\"paste_base_64\">Base64 plakken</string>\n    <string name=\"copy_base_64\">Base64 kopiëren</string>\n    <string name=\"base_64_tips\">Laad de afbeelding om de Base64-tekenreeks te kopiëren of op te slaan, als je die hebt, kun je deze hierboven plakken om de afbeelding te verkrijgen</string>\n    <string name=\"options\">Opties</string>\n    <string name=\"actions\">Acties</string>\n    <string name=\"import_base_64\">Base64 importeren</string>\n    <string name=\"share_base_64\">Base64 delen</string>\n    <string name=\"base_64_tools_sub\">Base64-tekenreeks decoderen naar afbeelding of afbeelding coderen naar Base64-indeling</string>\n    <string name=\"settings_group_visibility_hidden\">In te stellen groep \\\"%1$s\\\" wordt standaard samengevouwen</string>\n    <string name=\"base_64_tools\">Base64 Hulpmiddelen</string>\n    <string name=\"save_base_64\">Base64 opslaan</string>\n    <string name=\"copy_not_a_valid_base_64\">Kan geen lege of ongeldige Base64-tekenreeks kopiëren</string>\n    <string name=\"base_64_actions\">Base64-actions</string>\n    <string name=\"outline_color\">Contourkleur</string>\n    <string name=\"outline_size\">Contourdikte</string>\n    <string name=\"add_outline\">Contour toevoegen</string>\n    <string name=\"add_outline_sub\">Contour rondom tekst toevoegen met opgegeven kleur en breedte</string>\n    <string name=\"rotation\">Rotatie</string>\n    <string name=\"checksum_as_filename_sub\">Uitvoerafbeeldingen krijgen naam in overeenkomst met het controlegetal van de gegevens</string>\n    <string name=\"checksum_as_filename\">Controlegtal als bestandsnaam</string>\n    <string name=\"match_sub\">Controlegetallen zijn gelijk, het kan veilig zijn</string>\n    <string name=\"difference_sub\">Controlegetallen zijn niet gelijk, bestand kan onveilig zijn!</string>\n    <string name=\"checksum_tools\">Controlegetal-hulpmiddelen</string>\n    <string name=\"text_hash\">Tekst-hash</string>\n    <string name=\"checksum\">Controlegetal</string>\n    <string name=\"pick_file_to_checksum\">Kies het bestand om de controlesom te berekenen op basis van het geselecteerde algoritme</string>\n    <string name=\"calculate\">Berekenen</string>\n    <string name=\"free_software_partner_sub\">Meer handige software in het partnerkanaal van Android-applicaties</string>\n    <string name=\"enter_text_to_checksum\">Voer tekst in om de controlesom te berekenen op basis van het geselecteerde algoritme</string>\n    <string name=\"mesh_gradients\">Maaswerk-verlopen</string>\n    <string name=\"algorithms\">Algoritme</string>\n    <string name=\"collection_mesh_gradients_sub\">Bekijk de online collectie van maaswerk-verlopen</string>\n    <string name=\"checksum_tools_sub\">Vergelijk controlegetallen, bereken hashes, maak hexadecimale tekenreeksen van bestanden met behulp van verschillende hashing-algoritmen</string>\n    <string name=\"difference\">Verschil</string>\n    <string name=\"match\">Overeenkomst!</string>\n    <string name=\"free_software_partner\">Vrije software (Partner)</string>\n    <string name=\"source_checksum\">Bron van controlegetal</string>\n    <string name=\"checksum_to_compare\">Controlegetallen vergelijken</string>\n    <string name=\"import_font\">Lettertype importeren (TTF/OTF)</string>\n    <string name=\"imported_fonts\">Geïmporteerde lettertypen</string>\n    <string name=\"wrong_font\">Alleen TTF-lettertypen kunnen worden geïmporteerd</string>\n    <string name=\"export_fonts\">Lettertypen exporteren</string>\n    <string name=\"filename_is_not_set\">Geen bestandsnaam</string>\n    <string name=\"error_while_saving\">Fout tijdens poging tot opslaan, probeer de uitvoermap te wijzigen</string>\n    <string name=\"custom_pages\">Aangepaste pagina\\'s</string>\n    <string name=\"pages_selection\">Selectie van pagina\\'s</string>\n    <string name=\"none\">Geen</string>\n    <string name=\"tool_exit_confirmation\">Bevestiging bij het afsluiten van tools</string>\n    <string name=\"tool_exit_confirmation_sub\">Als je niet-opgeslagen wijzigingen hebt tijdens het gebruik van bepaalde tools en deze probeert te sluiten, wordt het bevestigingsdialoogvenster weergegeven</string>\n    <string name=\"edit_exif_screen\">EXIF bewerken</string>\n    <string name=\"edit_exif_screen_sub\">Metagegevens bewerken van een enkele afbeelding zonder hercompressie</string>\n    <string name=\"change_sticker\">Sticker wijzigen</string>\n    <string name=\"edit_exif_tag\">Tik om beschikbare tags te bewerken</string>\n    <string name=\"batch_compare\">Reeks vergelijken</string>\n    <string name=\"pick_files_to_checksum\">Kies bestand/bestanden om de controlesom te berekenen op basis van het geselecteerde algoritme</string>\n    <string name=\"fit_width\">Breedte passend</string>\n    <string name=\"fit_height\">Hoogte passend</string>\n    <string name=\"pick_directory\">Map kiezen</string>\n    <string name=\"pick_files\">Bestanden kiezen</string>\n    <string name=\"head_length_scale\">Lengte schaal kop</string>\n    <string name=\"stamp\">Stempel</string>\n    <string name=\"timestamp\">Tijdstempel</string>\n    <string name=\"padding\">Binnenruimte</string>\n    <string name=\"format_pattern\">Patroonopmaak</string>\n    <string name=\"vertical_pivot_line\">Verticale draailijn</string>\n    <string name=\"horizontal_pivot_line\">Horizontale draailijn</string>\n    <string name=\"inverse_selection\">Selectie inverteren</string>\n    <string name=\"inverse_horizontal_selection_sub\">Het horizontaal gesneden deel wordt verlaten, in plaats van delen samen te voegen rond het snijgebied</string>\n    <string name=\"image_cutting\">Afbeelding versnijden</string>\n    <string name=\"image_cutting_sub\">Knip het afbeeldingsgedeelte af en voeg het linkerdeel samen (kan omgekeerd zijn) door verticale of horizontale lijnen</string>\n    <string name=\"inverse_vertical_selection_sub\">Verticaal gesneden deel wordt verlaten, in plaats van delen samen te voegen rond het snijgebied</string>\n    <string name=\"mesh_gradients_sub\">Een maaswerk-verloop aanmaken met een aangepast aantal knopen en resolutie</string>\n    <string name=\"collection_mesh_gradients\">Verzameling van maaswerk-verlopen</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Maaswerk-verloop samenstellen van de bovenkant van gegeven afbeeldingen</string>\n    <string name=\"resolution_x\">Resolutie X</string>\n    <string name=\"resolution_y\">Resolutie Y</string>\n    <string name=\"resolution\">Resolutie</string>\n    <string name=\"gradient_maker_type_image_mesh\">Maaswerk-verloop overlay</string>\n    <string name=\"points_customization\">Punten aanpassen</string>\n    <string name=\"grid_size\">Rastergrootte</string>\n    <string name=\"highlight_color\">Markeringskleur</string>\n    <string name=\"pixel_by_pixel\">Pixel per pixel</string>\n    <string name=\"pixel_comparison_type\">Pixel-vergelijking</string>\n    <string name=\"scan_barcode\">Streepjescode scannen</string>\n    <string name=\"barcode_type\">Type streepjescode</string>\n    <string name=\"enforce_bw_sub\">De afbeelding van de streepjescode is volledig zwart-wit en niet gekleurd op het thema van de app</string>\n    <string name=\"barcodes_sub\">Scan een streepjescode (QR, EAN, AZTEC, …) om de inhoud te lezen of plak een tekst om een nieuwe te genereren</string>\n    <string name=\"height_ratio\">Hoogteverhouding</string>\n    <string name=\"enforce_bw\">Z/W afdwingen</string>\n    <string name=\"audio_cover_extractor_sub\">Afbeeldingen van albumhoezen uit audiobestanden extraheren, de meest voorkomende formaten worden ondersteund</string>\n    <string name=\"audio_cover_extractor\">Audiohoezen extraheren</string>\n    <string name=\"no_barcode_found\">Geen barcode aangetroffen</string>\n    <string name=\"generated_barcode_will_be_here\">Gegenereerde barcode komt hier</string>\n    <string name=\"pick_audio_to_start\">Kies audio om te starten</string>\n    <string name=\"pick_audio\">Audio kiezen</string>\n    <string name=\"no_covers_found\">Geen hoezen gevonden</string>\n    <string name=\"disable_rotation\">Rotatie uitschakelen</string>\n    <string name=\"disable_rotation_sub\">Voorkomt het roteren van afbeeldingen met gebaren met twee vingers</string>\n    <string name=\"enable_snapping_to_borders\">Schakel uitlijnen naar randen in</string>\n    <string name=\"enable_snapping_to_borders_sub\">Na het verplaatsen of zoomen worden afbeeldingen uitgelijnd om de frameranden te vullen</string>\n    <string name=\"send_logs\">Logboeken verzenden</string>\n    <string name=\"send_logs_sub\">Klik om het app-logboekbestand te delen. Dit kan mij helpen het probleem op te sporen en problemen op te lossen</string>\n    <string name=\"crash_title\">Oeps… Er is iets misgegaan</string>\n    <string name=\"crash_subtitle\">U kunt contact met mij opnemen via onderstaande opties en ik zal proberen een oplossing te vinden.\\n(Vergeet niet om logboeken bij te voegen)</string>\n    <string name=\"ocr_write_to_file\">Schrijven naar bestand</string>\n    <string name=\"ocr_write_to_file_sub\">Extraheer tekst uit een batch afbeeldingen en sla deze op in één tekstbestand</string>\n    <string name=\"ocr_write_to_metadata\">Schrijven naar metadata</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extraheer tekst uit elke afbeelding en plaats deze in EXIF-info van relatieve foto\\'s</string>\n    <string name=\"invisible_mode\">Onzichtbare modus</string>\n    <string name=\"invisible_mode_sub\">Gebruik steganografie om voor het oog onzichtbare watermerken te creëren in bytes van uw afbeeldingen</string>\n    <string name=\"use_lsb\">Gebruik LSB</string>\n    <string name=\"use_lsb_sub\">Er zal gebruik worden gemaakt van de LSB-steganografiemethode (Less Significant Bit), anders FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Rode ogen automatisch verwijderen</string>\n    <string name=\"password\">Wachtwoord</string>\n    <string name=\"unlock\">Ontgrendelen</string>\n    <string name=\"pdf_is_protected\">PDF is beveiligd</string>\n    <string name=\"operation_almost_complete\">Operatie bijna voltooid. Als u nu annuleert, moet u het programma opnieuw opstarten</string>\n    <string name=\"sort_by_date_modified\">Datum gewijzigd</string>\n    <string name=\"sort_by_date_modified_reversed\">Datum gewijzigd (omgekeerd)</string>\n    <string name=\"sort_by_size\">Maat</string>\n    <string name=\"sort_by_size_reversed\">Grootte (omgekeerd)</string>\n    <string name=\"sort_by_mime_type\">MIME-type</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME-type (omgekeerd)</string>\n    <string name=\"sort_by_extension\">Verlenging</string>\n    <string name=\"sort_by_extension_reversed\">Extensie (omgekeerd)</string>\n    <string name=\"sort_by_date_added\">Datum toegevoegd</string>\n    <string name=\"sort_by_date_added_reversed\">Datum toegevoegd (omgekeerd)</string>\n    <string name=\"left_to_right\">Van links naar rechts</string>\n    <string name=\"right_to_left\">Rechts naar links</string>\n    <string name=\"top_to_bottom\">Van boven naar beneden</string>\n    <string name=\"bottom_to_top\">Van onder naar boven</string>\n    <string name=\"liquid_glass\">Vloeibaar glas</string>\n    <string name=\"liquid_glass_sub\">Een schakelaar gebaseerd op de onlangs aangekondigde IOS 26 en zijn vloeistofglasontwerpsysteem</string>\n    <string name=\"pick_image_or_base64\">Kies een afbeelding of plak/importeer Base64-gegevens hieronder</string>\n    <string name=\"type_image_link\">Typ een afbeeldingslink om te beginnen</string>\n    <string name=\"paste_link\">Link plakken</string>\n    <string name=\"kaleidoscope\">Caleidoscoop</string>\n    <string name=\"secondary_angle\">Secundaire hoek</string>\n    <string name=\"sides\">Zijkanten</string>\n    <string name=\"channel_mix\">Kanaalmix</string>\n    <string name=\"blue_green\">Blauw groen</string>\n    <string name=\"red_blue\">Rood blauw</string>\n    <string name=\"green_red\">Groen rood</string>\n    <string name=\"into_red\">In rood</string>\n    <string name=\"into_green\">In groen</string>\n    <string name=\"into_blue\">In blauw</string>\n    <string name=\"cyan\">Cyaan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Geel</string>\n    <string name=\"color_halftone\">Kleur halftoon</string>\n    <string name=\"contour\">Contour</string>\n    <string name=\"levels\">Niveaus</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi kristalliseert</string>\n    <string name=\"shape\">Vorm</string>\n    <string name=\"stretch\">Strek</string>\n    <string name=\"randomness\">Willekeurigheid</string>\n    <string name=\"despeckle\">Ontspikkelen</string>\n    <string name=\"diffuse\">Diffuus</string>\n    <string name=\"dog\">Hond</string>\n    <string name=\"second_radius\">Tweede straal</string>\n    <string name=\"equalize\">Egaliseren</string>\n    <string name=\"glow\">Gloed</string>\n    <string name=\"whirl_and_pinch\">Draai en knijp</string>\n    <string name=\"pointillize\">Pointilliseren</string>\n    <string name=\"border_color\">Randkleur</string>\n    <string name=\"polar_coordinates\">Polaire coördinaten</string>\n    <string name=\"rect_to_polar\">Rect naar polair</string>\n    <string name=\"polar_to_rect\">Polair om te rectificeren</string>\n    <string name=\"invert_in_circle\">Omkeren in cirkel</string>\n    <string name=\"reduce_noise\">Verminder ruis</string>\n    <string name=\"simple_solarize\">Eenvoudig Solariseren</string>\n    <string name=\"weave\">Weven</string>\n    <string name=\"x_gap\">X kloof</string>\n    <string name=\"y_gap\">Y-opening</string>\n    <string name=\"x_width\">X Breedte</string>\n    <string name=\"y_wdth\">Y-breedte</string>\n    <string name=\"twirl\">Draai</string>\n    <string name=\"rubber_stmp\">Rubberen stempel</string>\n    <string name=\"smear\">Smeren</string>\n    <string name=\"density\">Dikte</string>\n    <string name=\"mix\">Mengen</string>\n    <string name=\"sphere_lensh_distortion\">Vervorming van bollens</string>\n    <string name=\"refraction_index\">Brekingsindex</string>\n    <string name=\"arc\">Boog</string>\n    <string name=\"spread_angle\">Spreidingshoek</string>\n    <string name=\"sparkle\">Fonkeling</string>\n    <string name=\"rays\">Stralen</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Verloop</string>\n    <string name=\"moire\">Maria</string>\n    <string name=\"autumn\">Herfst</string>\n    <string name=\"bone\">Bot</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Winter</string>\n    <string name=\"ocean\">Oceaan</string>\n    <string name=\"summer\">Zomer</string>\n    <string name=\"spring\">Lente</string>\n    <string name=\"cool_variant\">Coole variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Roze</string>\n    <string name=\"hot\">Heet</string>\n    <string name=\"parula\">Woord</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridi\\'s</string>\n    <string name=\"cividis\">Burgers</string>\n    <string name=\"twilight\">Schemering</string>\n    <string name=\"twilight_shifted\">Schemering verschoven</string>\n    <string name=\"auto_perspective\">Perspectief Auto</string>\n    <string name=\"deskew\">Rechtzetten</string>\n    <string name=\"allow_crop\">Bijsnijden toestaan</string>\n    <string name=\"crop_or_perspective\">Bijsnijden of perspectief</string>\n    <string name=\"absolute\">Absoluut</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Diepgroen</string>\n    <string name=\"lens_correction\">Lenscorrectie</string>\n    <string name=\"target_lens_profile\">Doellensprofielbestand in JSON-indeling</string>\n    <string name=\"download_ready_lens_profiles\">Download kant-en-klare lensprofielen</string>\n    <string name=\"part_percents\">Deelpercentages</string>\n    <string name=\"export_as_json\">Exporteren als JSON</string>\n    <string name=\"export_as_json_sub\">Kopieer de tekenreeks met paletgegevens als JSON-representatie</string>\n    <string name=\"seam_carving\">Naad snijwerk</string>\n    <string name=\"home_screen\">Startscherm</string>\n    <string name=\"lock_screen\">Vergrendelscherm</string>\n    <string name=\"built_in\">Ingebouwd</string>\n    <string name=\"wallpapers_export\">Achtergronden exporteren</string>\n    <string name=\"refresh\">Vernieuwen</string>\n    <string name=\"wallpapers_export_sub\">Verkrijg huidige Home-, Lock- en Built-in-achtergronden</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Geef toegang tot alle bestanden, dit is nodig om achtergronden op te halen</string>\n    <string name=\"allow_read_media_images_for_wp\">Toestemming voor externe opslag beheren is niet voldoende. U moet toegang tot uw afbeeldingen toestaan. Zorg ervoor dat u \\\"Alles toestaan\\\" selecteert</string>\n    <string name=\"add_preset_to_filename\">Voorinstelling toevoegen aan bestandsnaam</string>\n    <string name=\"add_preset_to_filename_sub\">Voegt het achtervoegsel met de geselecteerde voorinstelling toe aan de bestandsnaam van de afbeelding</string>\n    <string name=\"add_image_scale_mode_to_filename\">Voeg afbeeldingsschaalmodus toe aan bestandsnaam</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Voegt het achtervoegsel met de geselecteerde afbeeldingsschaalmodus toe aan de bestandsnaam van de afbeelding</string>\n    <string name=\"ascii_art\">Ascii-kunst</string>\n    <string name=\"ascii_art_sub\">Converteer de afbeelding naar ASCII-tekst die op een afbeelding lijkt</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Past in sommige gevallen een negatief filter toe op de afbeelding voor een beter resultaat</string>\n    <string name=\"processing_screenshot\">Schermafbeelding verwerken</string>\n    <string name=\"screenshot_not_captured_try_again\">Screenshot niet vastgelegd. Probeer het opnieuw</string>\n    <string name=\"skipped_saving\">Opslaan overgeslagen</string>\n    <string name=\"skipped_saving_multiple\">%1$s bestanden overgeslagen</string>\n    <string name=\"allow_skip_if_larger\">Overslaan toestaan ​​indien groter</string>\n    <string name=\"allow_skip_if_larger_sub\">Sommige tools mogen het opslaan van afbeeldingen overslaan als de resulterende bestandsgrootte groter zou zijn dan het origineel</string>\n    <string name=\"qr_type_calendar_event\">Kalender evenement</string>\n    <string name=\"qr_type_contact_info\">Contact</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Locatie</string>\n    <string name=\"qr_type_phone\">Telefoon</string>\n    <string name=\"qr_type_plain\">Tekst</string>\n    <string name=\"qr_type_sms\">Sms</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wifi</string>\n    <string name=\"open_network\">Open netwerk</string>\n    <string name=\"not_specified\">N.v.t</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefoon</string>\n    <string name=\"message\">Bericht</string>\n    <string name=\"address\">Adres</string>\n    <string name=\"subject\">Onderwerp</string>\n    <string name=\"body\">Lichaam</string>\n    <string name=\"name\">Naam</string>\n    <string name=\"organization\">Organisatie</string>\n    <string name=\"title\">Titel</string>\n    <string name=\"phones\">Telefoons</string>\n    <string name=\"emails\">E-mails</string>\n    <string name=\"urls\">URL\\'s</string>\n    <string name=\"addresses\">Adressen</string>\n    <string name=\"summary\">Samenvatting</string>\n    <string name=\"description\">Beschrijving</string>\n    <string name=\"location\">Locatie</string>\n    <string name=\"organizer\">Organisator</string>\n    <string name=\"start_date\">Startdatum</string>\n    <string name=\"end_date\">Einddatum</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Breedte</string>\n    <string name=\"longitude\">Lengte</string>\n    <string name=\"create_barcode\">Streepjescode maken</string>\n    <string name=\"edit_barcode\">Streepjescode bewerken</string>\n    <string name=\"wifi_configuration\">Wi-Fi-configuratie</string>\n    <string name=\"security\">Beveiliging</string>\n    <string name=\"pick_contact\">Contactpersoon kiezen</string>\n    <string name=\"grant_contact_permission\">Verleen contacten toestemming in de instellingen om automatisch aan te vullen met het geselecteerde contact</string>\n    <string name=\"contact_info\">Contactgegevens</string>\n    <string name=\"first_name\">Voornaam</string>\n    <string name=\"middle_name\">Middelste naam</string>\n    <string name=\"last_name\">Achternaam</string>\n    <string name=\"pronunciation\">Uitspraak</string>\n    <string name=\"add_phone\">Telefoon toevoegen</string>\n    <string name=\"add_email\">E-mailadres toevoegen</string>\n    <string name=\"add_address\">Adres toevoegen</string>\n    <string name=\"website\">Website</string>\n    <string name=\"add_website\">Website toevoegen</string>\n    <string name=\"formatted_name\">Opgemaakte naam</string>\n    <string name=\"qr_code_top_image\">Deze afbeelding wordt gebruikt om boven de streepjescode te plaatsen</string>\n    <string name=\"code_customization\">Code-aanpassing</string>\n    <string name=\"qr_logo_image\">Deze afbeelding wordt gebruikt als logo in het midden van de QR-code</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo-opvulling</string>\n    <string name=\"logo_size\">Logo-grootte</string>\n    <string name=\"logo_corners\">Logo-hoeken</string>\n    <string name=\"fourth_eye\">Vierde oog</string>\n    <string name=\"fourth_eye_description\">Voegt oogsymmetrie toe aan QR-code door een vierde oog toe te voegen aan de onderste eindhoek</string>\n    <string name=\"pixel_shape\">Pixelvorm</string>\n    <string name=\"frame_shape\">Framevorm</string>\n    <string name=\"ball_shape\">Bolvorm</string>\n    <string name=\"error_correction_level\">Foutcorrectieniveau</string>\n    <string name=\"dark_color\">Donkere kleur</string>\n    <string name=\"light_color\">Lichte kleur</string>\n    <string name=\"hyper_os\">Hyper-OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS-achtige stijl</string>\n    <string name=\"mask_pattern\">Maskerpatroon</string>\n    <string name=\"code_may_be_not_scannable\">Deze code is mogelijk niet scanbaar. Wijzig de uiterlijkparameters om deze op alle apparaten leesbaar te maken</string>\n    <string name=\"not_scannable\">Niet scanbaar</string>\n    <string name=\"launcher_mode_sub\">Tools zullen er compacter uitzien als het app-opstartprogramma op het startscherm</string>\n    <string name=\"launcher_mode\">Launcher-modus</string>\n    <string name=\"flood_fill_sub\">Vult een gebied met het geselecteerde penseel en de geselecteerde stijl</string>\n    <string name=\"flood_fill\">Overstromingsvulling</string>\n    <string name=\"spray\">Spuiten</string>\n    <string name=\"spray_sub\">Tekent een pad in graffitistijl</string>\n    <string name=\"square_particles\">Vierkante deeltjes</string>\n    <string name=\"square_particles_sub\">Spuitdeeltjes hebben een vierkante vorm in plaats van cirkels</string>\n    <string name=\"palette_tools\">Palethulpmiddelen</string>\n    <string name=\"palette_tools_sub\">Genereer basismateriaal/materiaal dat u palet uit een afbeelding, of import/exporteer naar verschillende paletformaten</string>\n    <string name=\"edit_palette\">Palet bewerken</string>\n    <string name=\"edit_palette_sub\">Export-/importpalet in verschillende formaten</string>\n    <string name=\"color_name\">Kleur naam</string>\n    <string name=\"palette_name\">Naam palet</string>\n    <string name=\"palette_format\">Paletformaat</string>\n    <string name=\"export_palette_sub\">Exporteer het gegenereerde palet naar verschillende formaten</string>\n    <string name=\"add_color_palette_sub\">Voegt een nieuwe kleur toe aan het huidige palet</string>\n    <string name=\"palette_name_not_supported\">De indeling %1$s biedt geen ondersteuning voor het opgeven van een paletnaam</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Vanwege het Play Store-beleid kan deze functie niet worden opgenomen in de huidige build. Om toegang te krijgen tot deze functionaliteit, downloadt u ImageToolbox van een alternatieve bron. Hieronder vindt u de beschikbare builds op GitHub.</string>\n    <string name=\"open_github_page\">Open Github-pagina</string>\n    <string name=\"overwrite_files_sub_short\">Het originele bestand wordt vervangen door een nieuw bestand in plaats van het op te slaan in de geselecteerde map</string>\n    <string name=\"hidden_watermark_text_detected\">Verborgen watermerktekst gedetecteerd</string>\n    <string name=\"hidden_watermark_image_detected\">Verborgen watermerkafbeelding gedetecteerd</string>\n    <string name=\"this_image_was_hidden\">Deze afbeelding was verborgen</string>\n    <string name=\"generative_inpaint\">Generatief inschilderen</string>\n    <string name=\"generative_inpaint_sub\">Hiermee kunt u objecten in een afbeelding verwijderen met behulp van een AI-model, zonder afhankelijk te zijn van OpenCV. Om deze functie te gebruiken, downloadt de app het vereiste model (~200 MB) van GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Hiermee kunt u objecten in een afbeelding verwijderen met behulp van een AI-model, zonder afhankelijk te zijn van OpenCV. Dit kan een langdurige operatie zijn</string>\n    <string name=\"error_level_analysis\">Analyse van foutniveau</string>\n    <string name=\"luminance_gradient\">Luminantiegradiënt</string>\n    <string name=\"average_distance\">Gemiddelde afstand</string>\n    <string name=\"copy_move_detection\">Kopieerbewegingsdetectie</string>\n    <string name=\"retain\">Behouden</string>\n    <string name=\"coefficent\">Coëfficiënt</string>\n    <string name=\"clipboard_data_is_too_large\">Klembordgegevens zijn te groot</string>\n    <string name=\"data_is_too_large_to_copy\">Gegevens zijn te groot om te kopiëren</string>\n    <string name=\"simple_weave_pixelization\">Eenvoudige weefpixelisatie</string>\n    <string name=\"staggered_pixelization\">Gespreide pixelisatie</string>\n    <string name=\"cross_pixelization\">Kruispixelisatie</string>\n    <string name=\"micro_macro_pixelization\">Micro-macropixelisatie</string>\n    <string name=\"orbital_pixelization\">Orbitale pixelisatie</string>\n    <string name=\"vortex_pixelization\">Vortex-pixelisatie</string>\n    <string name=\"pulse_grid_pixelization\">Pulse Grid-pixelisatie</string>\n    <string name=\"nucleus_pixelization\">Nucleuspixelisatie</string>\n    <string name=\"radial_weave_pixelization\">Radiale weefpixelisatie</string>\n    <string name=\"cannot_open_uri\">Kan uri \\\"%1$s\\\" niet openen</string>\n    <string name=\"snowfall_mode\">Sneeuwval-modus</string>\n    <string name=\"enabled\">Ingeschakeld</string>\n    <string name=\"border_frame\">Grenskader</string>\n    <string name=\"glitch_variant\">Glitch-variant</string>\n    <string name=\"channel_shift\">Kanaalverschuiving</string>\n    <string name=\"max_offset\">Maximale compensatie</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blokkeerfout</string>\n    <string name=\"block_size\">Blokgrootte</string>\n    <string name=\"crt_curvature\">CRT-kromming</string>\n    <string name=\"curvature\">Kromming</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel smelt</string>\n    <string name=\"max_drop\">Maximale daling</string>\n    <string name=\"ai_tools\">AI-hulpmiddelen</string>\n    <string name=\"ai_tools_sub\">Verschillende tools om afbeeldingen te verwerken via AI-modellen, zoals het verwijderen van artefacten of het verwijderen van ruis</string>\n    <string name=\"model_anime_undeint\">Compressie, gekartelde lijnen</string>\n    <string name=\"model_broadcast\">Tekenfilms, compressie van uitzendingen</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Algemene compressie, algemeen geluid</string>\n    <string name=\"model_wb_denoise\">Kleurloos cartoongeluid</string>\n    <string name=\"model_span_anime_pretrain\">Snel, algemene compressie, algemene ruis, animatie/strips/anime</string>\n    <string name=\"model_book_scan\">Boek scannen</string>\n    <string name=\"model_overexposure\">Belichtingscorrectie</string>\n    <string name=\"model_fbcnn_color_fp16\">Beste bij algemene compressie, kleurenafbeeldingen</string>\n    <string name=\"model_fbcnn_gray_fp16\">Beste bij algemene compressie, grijswaardenafbeeldingen</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Algemene compressie, grijswaardenafbeeldingen, sterker</string>\n    <string name=\"model_scunet_color_gan_fp16\">Algemene ruis, kleurenafbeeldingen</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Algemene ruis, kleurenafbeeldingen, betere details</string>\n    <string name=\"model_scunet_gray_15_fp16\">Algemene ruis, grijswaardenafbeeldingen</string>\n    <string name=\"model_scunet_gray_25_fp16\">Algemene ruis, grijswaardenafbeeldingen, sterker</string>\n    <string name=\"model_scunet_gray_50_fp16\">Algemene ruis, grijswaardenafbeeldingen, het sterkst</string>\n    <string name=\"model_jpeg_destroyer\">Algemene compressie</string>\n    <string name=\"model_jaywreck\">Algemene compressie</string>\n    <string name=\"model_h264\">Texturisatie, h264-compressie</string>\n    <string name=\"model_vhs\">VHS-compressie</string>\n    <string name=\"model_cinepak\">Niet-standaard compressie (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink-compressie, beter op het gebied van geometrie</string>\n    <string name=\"model_debink_v5\">Binkcompressie, sterker</string>\n    <string name=\"model_debink_v6\">Binkcompressie, zacht, behoudt details</string>\n    <string name=\"model_antialias\">Eliminatie van het traptrede-effect, gladmakend</string>\n    <string name=\"model_kdm_scans\">Gescande kunst/tekeningen, milde compressie, moiré</string>\n    <string name=\"model_bandage\">Kleur strepen</string>\n    <string name=\"model_halftone\">Langzaam, waarbij halftonen worden verwijderd</string>\n    <string name=\"model_colorizer\">Algemene inkleurer voor grijswaarden/zwart-witafbeeldingen. Gebruik DDColor voor betere resultaten</string>\n    <string name=\"model_deedge\">Rand verwijderen</string>\n    <string name=\"model_desharpen\">Verwijdert overmatige verscherping</string>\n    <string name=\"model_dither\">Langzaam, aarzelend</string>\n    <string name=\"model_gainres\">Anti-aliasing, algemene artefacten, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 scanverwerking</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Lichtgewicht model voor beeldverbetering</string>\n    <string name=\"model_bcgone_detailed_v2\">Verwijdering van compressieartefacten</string>\n    <string name=\"model_bcgone_smooth\">Verwijdering van compressieartefacten</string>\n    <string name=\"model_bandage_smooth\">Verbandverwijdering met soepel resultaat</string>\n    <string name=\"model_bendel_halftone\">Halftoonpatroonverwerking</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Ditherpatroon verwijderen V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Verwijdering van JPEG-artefacten V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Verbetering van de H.264-textuur</string>\n    <string name=\"model_vhs_sharpen\">VHS-verscherping en -verbetering</string>\n    <string name=\"merging\">Samenvoegen</string>\n    <string name=\"chunk_size\">Brokgrootte</string>\n    <string name=\"overlap_size\">Overlapgrootte</string>\n    <string name=\"note_chunk_info\">Afbeeldingen groter dan %1$s px worden in stukken gesneden en verwerkt. Overlap vermengt deze om zichtbare naden te voorkomen.</string>\n    <string name=\"large_chunk_warning\">Grote maten kunnen instabiliteit veroorzaken bij goedkope apparaten</string>\n    <string name=\"select_one_to_start\">Selecteer er een om te starten</string>\n    <string name=\"delete_model_sub\">Wilt u het %1$s model verwijderen? U moet het opnieuw downloaden</string>\n    <string name=\"confirm\">Bevestigen</string>\n    <string name=\"models\">Modellen</string>\n    <string name=\"downloaded_models\">Gedownloade modellen</string>\n    <string name=\"available_models\">Beschikbare modellen</string>\n    <string name=\"preparing\">Voorbereiden</string>\n    <string name=\"active_model\">Actief model</string>\n    <string name=\"failed_to_open_session\">Kan sessie niet openen</string>\n    <string name=\"only_onnx_models\">Alleen .onnx/.ort-modellen kunnen worden geïmporteerd</string>\n    <string name=\"import_model\">Model importeren</string>\n    <string name=\"import_model_sub\">Importeer een aangepast onnx-model voor verder gebruik, alleen onnx/ort-modellen worden geaccepteerd, ondersteunt bijna alle esrgan-achtige varianten</string>\n    <string name=\"imported_models\">Geïmporteerde modellen</string>\n    <string name=\"model_scunet_color_15_fp16\">Algemene ruis, gekleurde beelden</string>\n    <string name=\"model_scunet_color_25_fp16\">Algemene ruis, gekleurde beelden, sterker</string>\n    <string name=\"model_scunet_color_50_fp16\">Algemene ruis, gekleurde beelden, het sterkst</string>\n    <string name=\"model_artifacts_dithering_alsa\">Vermindert dithering-artefacten en kleurbanden, waardoor vloeiende kleurovergangen en vlakke kleurgebieden worden verbeterd.</string>\n    <string name=\"model_nmkd_brighten_redux\">Verbetert de helderheid en het contrast van het beeld met gebalanceerde highlights terwijl de natuurlijke kleuren behouden blijven.</string>\n    <string name=\"model_nmkd_brighten\">Maakt donkere beelden helderder, terwijl de details behouden blijven en overbelichting wordt vermeden.</string>\n    <string name=\"model_nmkd_detoon\">Verwijdert overmatige kleurtonen en herstelt een meer neutrale en natuurlijke kleurbalans.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Past op Poisson gebaseerde ruistoning toe met de nadruk op het behoud van fijne details en texturen.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Past zachte Poisson-ruistinten toe voor vloeiendere en minder agressieve visuele resultaten.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Uniforme ruistoning gericht op detailbehoud en beeldhelderheid.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Zachte uniforme ruistoning voor subtiele textuur en een glad uiterlijk.</string>\n    <string name=\"model_repainter\">Repareert beschadigde of oneffen gebieden door artefacten opnieuw te schilderen en de beeldconsistentie te verbeteren.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Lichtgewicht ontbandingsmodel dat kleurbanden verwijdert met minimale prestatiekosten.</string>\n    <string name=\"model_jpeg_0_20\">Optimaliseert afbeeldingen met zeer hoge compressieartefacten (0-20% kwaliteit) voor verbeterde helderheid.</string>\n    <string name=\"model_jpeg_20_40\">Verbetert afbeeldingen met hoge compressieartefacten (20-40% kwaliteit), waardoor details worden hersteld en ruis wordt verminderd.</string>\n    <string name=\"model_jpeg_40_60\">Verbetert afbeeldingen met gematigde compressie (40-60% kwaliteit), waarbij scherpte en vloeiendheid in evenwicht worden gebracht.</string>\n    <string name=\"model_jpeg_60_80\">Verfijnt afbeeldingen met lichte compressie (60-80% kwaliteit) om subtiele details en texturen te verbeteren.</string>\n    <string name=\"model_jpeg_80_100\">Verbetert vrijwel verliesvrije beelden enigszins (80-100% kwaliteit) terwijl de natuurlijke uitstraling en details behouden blijven.</string>\n    <string name=\"model_spongecolor_lite\">Eenvoudige en snelle inkleuring, tekenfilms, niet ideaal</string>\n    <string name=\"model_deblr\">Vermindert beeldonscherpte enigszins, waardoor de scherpte wordt verbeterd zonder artefacten te introduceren.</string>\n    <string name=\"processing_channel\">Langlopende operaties</string>\n    <string name=\"processing_image\">Beeld verwerken</string>\n    <string name=\"processing\">Verwerking</string>\n    <string name=\"model_artifacts_jpg_0_20\">Verwijdert zware JPEG-compressieartefacten in afbeeldingen van zeer lage kwaliteit (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Vermindert sterke JPEG-artefacten in sterk gecomprimeerde afbeeldingen (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Ruimt gemiddelde JPEG-artefacten op terwijl de beelddetails behouden blijven (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Verfijnt lichte JPEG-artefacten in afbeeldingen van redelijk hoge kwaliteit (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Vermindert op subtiele wijze kleine JPEG-artefacten in vrijwel verliesvrije beelden (80-100%).</string>\n    <string name=\"model_redetail_v2\">Verbetert fijne details en texturen, waardoor de waargenomen scherpte wordt verbeterd zonder zware artefacten.</string>\n    <string name=\"processing_finished\">Verwerking voltooid</string>\n    <string name=\"processing_failed\">Verwerking mislukt</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Verbetert huidtexturen en details met behoud van een natuurlijke uitstraling, geoptimaliseerd voor snelheid.</string>\n    <string name=\"model_sbdv_dejpeg\">Verwijdert JPEG-compressieartefacten en herstelt de beeldkwaliteit voor gecomprimeerde foto\\'s.</string>\n    <string name=\"model_iso_denoise_v1\">Vermindert ISO-ruis in foto\\'s gemaakt bij weinig licht, waarbij details behouden blijven.</string>\n    <string name=\"model_dejumbo\">Corrigeert overbelichte of ‘jumbo’ highlights en herstelt een betere toonbalans.</string>\n    <string name=\"model_ddcolor_tiny\">Lichtgewicht en snel kleurmodel dat natuurlijke kleuren toevoegt aan grijswaardenafbeeldingen.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Inkleuren</string>\n    <string name=\"type_artifacts\">Artefacten</string>\n    <string name=\"type_enhance\">Uitbreiden</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Scannen</string>\n    <string name=\"type_upscale\">Luxe</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler voor algemene afbeeldingen; klein model dat minder GPU en tijd gebruikt, met matige vervaging en ruisonderdrukking.</string>\n    <string name=\"model_realesrgan_x2plus\">X2-upscaler voor algemene afbeeldingen, waarbij texturen en natuurlijke details behouden blijven.</string>\n    <string name=\"model_realesrgan_x4plus\">X4-upscaler voor algemene afbeeldingen met verbeterde texturen en realistische resultaten.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4-upscaler geoptimaliseerd voor anime-afbeeldingen; 6 RRDB-blokken voor scherpere lijnen en details.</string>\n    <string name=\"model_realesrnet_x4plus\">X4-upscaler met MSE-verlies produceert vloeiendere resultaten en minder artefacten voor algemene afbeeldingen.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler geoptimaliseerd voor anime-afbeeldingen; 4B32F-variant met scherpere details en vloeiende lijnen.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2-model voor algemene afbeeldingen; benadrukt scherpte en helderheid.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; sneller en kleiner, behoudt details terwijl minder GPU-geheugen wordt gebruikt.</string>\n    <string name=\"model_rmbg_1_4\">Lichtgewicht model voor snelle achtergrondverwijdering. Evenwichtige prestaties en nauwkeurigheid. Werkt met portretten, objecten en scènes. Aanbevolen voor de meeste gebruikssituaties.</string>\n    <string name=\"type_removebg\">BG verwijderen</string>\n    <string name=\"horizontal_border_thickness\">Horizontale randdikte</string>\n    <string name=\"vertical_border_thickness\">Verticale randdikte</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s kleur</item>\n        <item quantity=\"other\">%1$s kleuren</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Het huidige model ondersteunt geen chunking, de afbeelding wordt verwerkt in de originele afmetingen, dit kan een hoog geheugengebruik en problemen met goedkope apparaten veroorzaken</string>\n    <string name=\"chunking_disabled\">Chunking uitgeschakeld, afbeelding wordt verwerkt in de oorspronkelijke afmetingen. Dit kan een hoog geheugengebruik en problemen met goedkope apparaten veroorzaken, maar kan betere resultaten opleveren bij gevolgtrekking</string>\n    <string name=\"chunking\">Chunken</string>\n    <string name=\"model_u2net\">Zeer nauwkeurig beeldsegmentatiemodel voor het verwijderen van achtergronden</string>\n    <string name=\"model_u2netp\">Lichtgewicht versie van U2Net voor snellere achtergrondverwijdering met kleiner geheugengebruik.</string>\n    <string name=\"model_ddcolor\">Het volledige DDColor-model levert hoogwaardige inkleuring voor algemene afbeeldingen met minimale artefacten. Beste keuze van alle inkleuringsmodellen.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Getrainde en particuliere artistieke datasets; produceert diverse en artistieke kleurresultaten met minder onrealistische kleurartefacten.</string>\n    <string name=\"model_birefnet\">Lichtgewicht BiRefNet-model gebaseerd op Swin Transformer voor nauwkeurige achtergrondverwijdering.</string>\n    <string name=\"model_inspyrenet\">Hoogwaardige achtergrondverwijdering met scherpe randen en uitstekend detailbehoud, vooral bij complexe objecten en lastige achtergronden.</string>\n    <string name=\"model_isnet\">Model voor achtergrondverwijdering dat nauwkeurige maskers met gladde randen produceert, geschikt voor algemene objecten en matig detailbehoud.</string>\n    <string name=\"model_already_downloaded\">Model al gedownload</string>\n    <string name=\"model_successfully_imported\">Model succesvol geïmporteerd</string>\n    <string name=\"type\">Type</string>\n    <string name=\"keyword\">Trefwoord</string>\n    <string name=\"very_fast\">Zeer snel</string>\n    <string name=\"normal\">Normaal</string>\n    <string name=\"slow\">Langzaam</string>\n    <string name=\"very_slow\">Zeer langzaam</string>\n    <string name=\"compute_percents\">Bereken procenten</string>\n    <string name=\"minimum_value_is\">Minimale waarde is %1$s</string>\n    <string name=\"warp_sub\">Vervorm het beeld door met de vingers te tekenen</string>\n    <string name=\"warp\">Verdraaien</string>\n    <string name=\"hardness\">Hardheid</string>\n    <string name=\"warp_mode\">Warp-modus</string>\n    <string name=\"warp_mode_move\">Beweging</string>\n    <string name=\"warp_mode_grow\">Groeien</string>\n    <string name=\"warp_mode_shrink\">Krimpen</string>\n    <string name=\"warp_mode_swirl_cw\">Werveling CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Draai CCW</string>\n    <string name=\"fade_strength\">Vervagen sterkte</string>\n    <string name=\"top_drop\">Topdaling</string>\n    <string name=\"bottom_drop\">Onderste daling</string>\n    <string name=\"start_drop\">Begin druppel</string>\n    <string name=\"end_drop\">Einde daling</string>\n    <string name=\"downloading\">Downloaden</string>\n    <string name=\"smooth_shapes\">Gladde vormen</string>\n    <string name=\"smooth_shapes_sub\">Gebruik superellipsen in plaats van standaard afgeronde rechthoeken voor vloeiendere, natuurlijkere vormen</string>\n    <string name=\"shape_type\">Vormtype</string>\n    <string name=\"cut\">Snee</string>\n    <string name=\"rounded\">Afgerond</string>\n    <string name=\"smooth\">Zacht</string>\n    <string name=\"cut_shapes_sub\">Scherpe randen zonder afronding</string>\n    <string name=\"rounded_shapes_sub\">Klassieke afgeronde hoeken</string>\n    <string name=\"shapes_type\">Vormentype</string>\n    <string name=\"corners_size\">Hoeken maat</string>\n    <string name=\"squircle\">Eekhoorn</string>\n    <string name=\"squircle_shapes_sub\">Elegante afgeronde UI-elementen</string>\n    <string name=\"filename_format\">Bestandsnaamformaat</string>\n    <string name=\"prefix_pattern_description\">Aangepaste tekst helemaal aan het begin van de bestandsnaam, perfect voor projectnamen, merken of persoonlijke tags.</string>\n    <string name=\"original_filename_pattern_description\">Gebruikt de originele bestandsnaam zonder extensie, zodat u de bronidentificatie intact kunt houden.</string>\n    <string name=\"width_pattern_description\">De afbeeldingsbreedte in pixels, handig voor het volgen van resolutiewijzigingen of schaalresultaten.</string>\n    <string name=\"height_pattern_description\">De afbeeldingshoogte in pixels, handig bij het werken met beeldverhoudingen of exporten.</string>\n    <string name=\"random_numbers_pattern_description\">Genereert willekeurige cijfers om unieke bestandsnamen te garanderen; voeg meer cijfers toe voor extra veiligheid tegen duplicaten.</string>\n    <string name=\"sequence_number_pattern_description\">Automatisch oplopende teller voor batchexports, ideaal bij het opslaan van meerdere afbeeldingen in één sessie.</string>\n    <string name=\"preset_info_pattern_description\">Voegt de toegepaste voorinstellingsnaam in de bestandsnaam in, zodat u gemakkelijk kunt onthouden hoe de afbeelding is verwerkt.</string>\n    <string name=\"scale_mode_pattern_description\">Toont de afbeeldingsschaalmodus die wordt gebruikt tijdens de verwerking, zodat afbeeldingen waarvan het formaat is aangepast, bijgesneden of passend zijn gemaakt, beter te onderscheiden zijn.</string>\n    <string name=\"suffix_pattern_description\">Aangepaste tekst aan het einde van de bestandsnaam, handig voor versiebeheer zoals _v2, _edited of _final.</string>\n    <string name=\"extension_pattern_description\">De bestandsextensie (png, jpg, webp, etc.), die automatisch overeenkomt met het daadwerkelijk opgeslagen formaat.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Een aanpasbare tijdstempel waarmee u uw eigen formaat kunt definiëren via Java-specificatie voor perfecte sortering.</string>\n    <string name=\"fling_type\">Fling-type</string>\n    <string name=\"android_native\">Android-native</string>\n    <string name=\"ios_style\">iOS-stijl</string>\n    <string name=\"smooth_curve\">Gladde curve</string>\n    <string name=\"quick_stop\">Snelle stop</string>\n    <string name=\"bouncy\">Veerkrachtig</string>\n    <string name=\"floaty\">Zwevend</string>\n    <string name=\"snappy\">Pittig</string>\n    <string name=\"ultra_smooth\">Ultraglad</string>\n    <string name=\"adaptive\">Adaptief</string>\n    <string name=\"accessibility_aware\">Toegankelijkheid bewust</string>\n    <string name=\"reduced_motion\">Verminderde beweging</string>\n    <string name=\"android_native_sub\">Native Android-scrollfysica voor basislijnvergelijking</string>\n    <string name=\"smooth_sub\">Gebalanceerd, soepel scrollen voor algemeen gebruik</string>\n    <string name=\"ios_style_sub\">Hogere wrijving iOS-achtig scrollgedrag</string>\n    <string name=\"smooth_curve_sub\">Unieke spline-curve voor een duidelijk scrollgevoel</string>\n    <string name=\"quick_stop_sub\">Nauwkeurig scrollen met snelle stop</string>\n    <string name=\"bouncy_sub\">Speelse, responsieve veerkrachtige scroll</string>\n    <string name=\"floaty_sub\">Lange, glijdende scrolls voor het bladeren door inhoud</string>\n    <string name=\"snappy_sub\">Snel, responsief scrollen voor interactieve gebruikersinterfaces</string>\n    <string name=\"ultra_smooth_sub\">Premium soepel scrollen met uitgebreid momentum</string>\n    <string name=\"adaptive_sub\">Past de fysica aan op basis van de vliegsnelheid</string>\n    <string name=\"accessibility_aware_sub\">Respecteert de instellingen voor systeemtoegankelijkheid</string>\n    <string name=\"reduced_motion_sub\">Minimale beweging voor toegankelijkheidsbehoeften</string>\n    <string name=\"primary_lines\">Primaire lijnen</string>\n    <string name=\"primary_lines_sub\">Voegt elke vijfde lijn een dikkere lijn toe</string>\n    <string name=\"fill_color\">Vulkleur</string>\n    <string name=\"hidden_tools\">Verborgen hulpmiddelen</string>\n    <string name=\"hidden_for_share\">Hulpmiddelen verborgen om te delen</string>\n    <string name=\"color_library\">Kleurenbibliotheek</string>\n    <string name=\"color_library_sub\">Blader door een uitgebreide collectie kleuren</string>\n    <string name=\"model_fatality_deblur\">Verscherpt en verwijdert onscherpte uit afbeeldingen met behoud van natuurlijke details, ideaal voor het corrigeren van onscherpe foto\\'s.</string>\n    <string name=\"model_unresize_v3\">Herstelt op intelligente wijze afbeeldingen waarvan het formaat eerder is gewijzigd, waarbij verloren details en texturen worden hersteld.</string>\n    <string name=\"model_liveaction_v1_span\">Geoptimaliseerd voor live-action-inhoud, vermindert compressieartefacten en verbetert fijne details in film-/tv-showframes.</string>\n    <string name=\"model_vhs2hd_realplksr\">Converteert beelden van VHS-kwaliteit naar HD, verwijdert bandruis en verbetert de resolutie met behoud van het vintage gevoel.</string>\n    <string name=\"model_text2hd_v1\">Gespecialiseerd voor afbeeldingen en schermafbeeldingen met veel tekst, verscherpt karakters en verbetert de leesbaarheid.</string>\n    <string name=\"model_frankendata_pretrainer\">Geavanceerde opschaling getraind op diverse datasets, uitstekend geschikt voor algemene fotoverbetering.</string>\n    <string name=\"model_realwebphoto_v2\">Geoptimaliseerd voor webgecomprimeerde foto\\'s, verwijdert JPEG-artefacten en herstelt de natuurlijke uitstraling.</string>\n    <string name=\"model_realwebphoto_v4\">Verbeterde versie voor webfoto\\'s met beter behoud van textuur en vermindering van artefacten.</string>\n    <string name=\"model_dat_2x\">2x opschalen met Dual Aggregation Transformer-technologie, behoudt scherpte en natuurlijke details.</string>\n    <string name=\"model_dat_3x\">3x opschaling met behulp van geavanceerde transformatorarchitectuur, ideaal voor gematigde uitbreidingsbehoeften.</string>\n    <string name=\"model_dat_4x\">4x hoogwaardige opschaling met het modernste transformatornetwerk, behoudt fijne details op grotere schaal.</string>\n    <string name=\"model_nafnet_deblurring\">Verwijdert onscherpte/ruis en trillingen uit foto\\'s. Algemeen gebruik, maar het beste op foto\\'s.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Herstelt afbeeldingen van lage kwaliteit met behulp van de Swin2SR-transformator, geoptimaliseerd voor BSRGAN-degradatie. Ideaal voor het corrigeren van zware compressieartefacten en het verbeteren van details op 4x schaal.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x opschalen met SwinIR-transformator getraind op BSRGAN-degradatie. Gebruikt GAN voor scherpere texturen en natuurlijkere details in foto\\'s en complexe scènes.</string>\n    <string name=\"path\">Pad</string>\n    <string name=\"merge_pdf\">PDF samenvoegen</string>\n    <string name=\"merge_pdf_sub\">Combineer meerdere PDF-bestanden in één document</string>\n    <string name=\"files_order\">Bestanden bestellen</string>\n    <string name=\"pages_short\">blz.</string>\n    <string name=\"split_pdf\">PDF splitsen</string>\n    <string name=\"split_pdf_sub\">Extraheer specifieke pagina\\'s uit een PDF-document</string>\n    <string name=\"rotate_pdf\">PDF roteren</string>\n    <string name=\"rotate_pdf_sub\">Pagina-oriëntatie permanent corrigeren</string>\n    <string name=\"pages\">Pagina\\'s</string>\n    <string name=\"rearrange_pdf\">PDF opnieuw rangschikken</string>\n    <string name=\"rearrange_pdf_sub\">Versleep pagina\\'s om ze opnieuw te ordenen</string>\n    <string name=\"hold_drag_drop\">Pagina\\'s vasthouden en slepen</string>\n    <string name=\"page_numbers\">Paginanummers</string>\n    <string name=\"page_numbers_sub\">Voeg automatisch nummering toe aan uw documenten</string>\n    <string name=\"label_format\">Labelformaat</string>\n    <string name=\"pdf_to_text\">PDF naar tekst (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extraheer platte tekst uit uw PDF-documenten</string>\n    <string name=\"watermark_pdf_sub\">Overlay met aangepaste tekst voor branding of beveiliging</string>\n    <string name=\"signature\">Handtekening</string>\n    <string name=\"signature_sub\">Voeg uw elektronische handtekening toe aan elk document</string>\n    <string name=\"will_be_for_signature\">Deze wordt gebruikt als handtekening</string>\n    <string name=\"unlock_pdf\">Ontgrendel PDF</string>\n    <string name=\"unlock_pdf_sub\">Verwijder wachtwoorden uit uw beveiligde bestanden</string>\n    <string name=\"protect_pdf\">Bescherm PDF</string>\n    <string name=\"protect_pdf_sub\">Beveilig uw documenten met sterke encryptie</string>\n    <string name=\"success\">Succes</string>\n    <string name=\"pdf_unlocked\">PDF ontgrendeld, u kunt het opslaan of delen</string>\n    <string name=\"repair_pdf\">PDF repareren</string>\n    <string name=\"repair_pdf_sub\">Probeer beschadigde of onleesbare documenten te repareren</string>\n    <string name=\"grayscale\">Grijstinten</string>\n    <string name=\"grayscale_pdf_sub\">Converteer alle in het document ingebedde afbeeldingen naar grijswaarden</string>\n    <string name=\"compress_pdf\">PDF comprimeren</string>\n    <string name=\"compress_pdf_sub\">Optimaliseer de bestandsgrootte van uw document om gemakkelijker te kunnen delen</string>\n    <string name=\"repair_info\">ImageToolbox bouwt de interne kruisverwijzingstabel opnieuw op en genereert de bestandsstructuur helemaal opnieuw. Hierdoor kan de toegang tot veel bestanden worden hersteld die \\\\\"niet kunnen worden geopend\\\\\"</string>\n    <string name=\"grayscale_info\">Deze tool converteert alle documentafbeeldingen naar grijswaarden. Beste voor afdrukken en verkleinen van de bestandsgrootte</string>\n    <string name=\"metadata\">Metagegevens</string>\n    <string name=\"metadata_pdf_sub\">Bewerk documenteigenschappen voor betere privacy</string>\n    <string name=\"tags\">Labels</string>\n    <string name=\"producer\">Producent</string>\n    <string name=\"author\">Auteur</string>\n    <string name=\"keywords\">Trefwoorden</string>\n    <string name=\"creator\">Schepper</string>\n    <string name=\"privacy_deep_clean\">Privacy Diep schoon</string>\n    <string name=\"privacy_deep_clean_sub\">Wis alle beschikbare metagegevens voor dit document</string>\n    <string name=\"page\">Pagina</string>\n    <string name=\"deep_ocr\">Diepe OCR</string>\n    <string name=\"deep_ocr_sub\">Extraheer tekst uit het document en sla deze op in één tekstbestand met behulp van de Tesseract-engine</string>\n    <string name=\"cant_remove_all\">Kan niet alle pagina\\'s verwijderen</string>\n    <string name=\"remove_pages_pdf\">Verwijder PDF-pagina\\'s</string>\n    <string name=\"remove_pages_pdf_sub\">Verwijder specifieke pagina\\'s uit het PDF-document</string>\n    <string name=\"tap_to_remove\">Tik om te verwijderen</string>\n    <string name=\"manually\">Handmatig</string>\n    <string name=\"crop_pdf\">PDF bijsnijden</string>\n    <string name=\"crop_pdf_sub\">Snijd documentpagina\\'s bij tot de gewenste grenzen</string>\n    <string name=\"flatten_pdf\">PDF plat maken</string>\n    <string name=\"flatten_pdf_sub\">Maak PDF onaanpasbaar door documentpagina\\'s te rasteren</string>\n    <string name=\"camera_failed_to_open\">Kan de camera niet starten. Controleer de rechten en zorg ervoor dat deze niet door een andere app wordt gebruikt.</string>\n    <string name=\"extract_images\">Afbeeldingen extraheren</string>\n    <string name=\"extract_images_sub\">Extraheer afbeeldingen die zijn ingesloten in PDF\\'s met hun oorspronkelijke resolutie</string>\n    <string name=\"pdf_no_embedded\">Dit PDF-bestand bevat geen ingesloten afbeeldingen</string>\n    <string name=\"extract_images_info\">Deze tool scant elke pagina en herstelt bronafbeeldingen van volledige kwaliteit – perfect voor het opslaan van originelen uit documenten</string>\n    <string name=\"draw_signature\">Handtekening tekenen</string>\n    <string name=\"pen_params\">Penparams</string>\n    <string name=\"draw_signature_sub\">Gebruik uw eigen handtekening als afbeelding voor plaatsing op documenten</string>\n    <string name=\"zip_pdf\">Zip-PDF</string>\n    <string name=\"zip_pdf_sub\">Splits het document met een bepaald interval en pak nieuwe documenten in een zip-archief</string>\n    <string name=\"interval\">Interval</string>\n    <string name=\"print_pdf\">PDF afdrukken</string>\n    <string name=\"print_pdf_sub\">Document voorbereiden voor afdrukken met aangepast paginaformaat</string>\n    <string name=\"pages_per_sheet\">Pagina\\'s per vel</string>\n    <string name=\"orientation\">Oriëntatie</string>\n    <string name=\"page_size\">Paginagrootte</string>\n    <string name=\"margin\">Marge</string>\n    <string name=\"bloom\">Bloeien</string>\n    <string name=\"soft_knee\">Zachte knie</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Geoptimaliseerd voor anime en tekenfilms. Snel opschalen met verbeterde natuurlijke kleuren en minder artefacten</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7-achtige stijl</string>\n    <string name=\"calculate_hint\">Voer hier elementaire wiskundige symbolen in om de gewenste waarde te berekenen (bijvoorbeeld (5+5)*10)</string>\n    <string name=\"math_expression\">Wiskundige uitdrukking</string>\n    <string name=\"pick_up_to_n_collage_images\">Neem maximaal %1$s afbeeldingen op</string>\n    <string name=\"keep_date_time\">Datum en tijd behouden</string>\n    <string name=\"keep_date_time_sub\">Bewaar altijd exif-tags gerelateerd aan datum en tijd, werkt onafhankelijk van de optie exif behouden</string>\n    <string name=\"background_color_for_alpha_formats\">Achtergrondkleur voor alfaformaten</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Voegt de mogelijkheid toe om de achtergrondkleur in te stellen voor elk afbeeldingsformaat met alfa-ondersteuning, indien uitgeschakeld is dit alleen beschikbaar voor niet-alfa-formaten</string>\n    <string name=\"open_markup_project\">Project openen</string>\n    <string name=\"open_markup_project_sub\">Ga door met het bewerken van een eerder opgeslagen Image Toolbox-project</string>\n    <string name=\"markup_project_open_failed\">Kan het Image Toolbox-project niet openen</string>\n    <string name=\"markup_project_missing_data\">Bij het Image Toolbox-project ontbreken projectgegevens</string>\n    <string name=\"markup_project_corrupted\">Het Image Toolbox-project is beschadigd</string>\n    <string name=\"unsupported_markup_project_version\">Niet-ondersteunde Image Toolbox-projectversie: %1$d</string>\n    <string name=\"save_markup_project\">Project opslaan</string>\n    <string name=\"save_markup_project_sub\">Bewaar lagen, achtergronden en bewerkingsgeschiedenis in een bewerkbaar projectbestand</string>\n    <string name=\"failed_to_open\">Kan niet worden geopend</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Schrijf naar doorzoekbare PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Herken tekst uit de afbeeldingsbatch en sla doorzoekbare PDF op met afbeelding en selecteerbare tekstlaag</string>\n    <string name=\"layer_alpha\">Laag-alfa</string>\n    <string name=\"horizontal_flip\">Horizontale spiegeling</string>\n    <string name=\"vertical_flip\">Verticale spiegeling</string>\n    <string name=\"lock\">Slot</string>\n    <string name=\"add_shadow\">Schaduw toevoegen</string>\n    <string name=\"shadow_color\">Schaduwkleur</string>\n    <string name=\"text_geometry\">Tekstgeometrie</string>\n    <string name=\"text_geometry_sub\">Rek tekst uit of scheef voor scherpere stilering</string>\n    <string name=\"scale_x\">Schaal X</string>\n    <string name=\"skew_x\">Scheef X</string>\n    <string name=\"remove_annotations\">Annotaties verwijderen</string>\n    <string name=\"remove_annotations_sub\">Verwijder geselecteerde annotatietypen, zoals koppelingen, opmerkingen, markeringen, vormen of formuliervelden, van de PDF-pagina\\'s</string>\n    <string name=\"annotation_link\">Hyperlinks</string>\n    <string name=\"annotation_file_attachment\">Bestandsbijlagen</string>\n    <string name=\"annotation_line\">Lijnen</string>\n    <string name=\"annotation_popup\">Pop-ups</string>\n    <string name=\"annotation_stamp\">Stempels</string>\n    <string name=\"annotation_shapes\">Vormen</string>\n    <string name=\"annotation_text\">Tekstnotities</string>\n    <string name=\"annotation_text_markup\">Tekstopmaak</string>\n    <string name=\"annotation_widget\">Formuliervelden</string>\n    <string name=\"annotation_markup\">Opmaak</string>\n    <string name=\"annotation_unknown\">Onbekend</string>\n    <string name=\"annotations\">Annotaties</string>\n    <string name=\"ungroup\">Degroeperen</string>\n    <string name=\"add_shadow_sub\">Voeg vervagingsschaduw toe achter de laag met configureerbare kleuren en offsets</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-pa/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"smth_went_wrong\">ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ: %1$s</string>\n    <string name=\"size\">ਆਕਾਰ %1$s</string>\n    <string name=\"loading\">Loading…</string>\n    <string name=\"image_too_large_preview\">ਪੂਰਵਦਰਸ਼ਨ ਲਈ ਚਿੱਤਰ ਬਹੁਤ ਵੱਡਾ ਹੈ, ਪਰ ਫਿਰ ਵੀ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਜਾਵੇਗੀ</string>\n    <string name=\"pick_image\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"width\">ਚੌੜਾਈ %1$s</string>\n    <string name=\"height\">ਉਚਾਈ %1$s</string>\n    <string name=\"quality\">ਗੁਣਵੱਤਾ</string>\n    <string name=\"extension\">ਐਕਸਟੈਂਸ਼ਨ</string>\n    <string name=\"resize_type\">ਆਕਾਰ ਬਦਲੋ</string>\n    <string name=\"explicit\">ਸਪਸ਼ਟ</string>\n    <string name=\"flexible\">ਲਚਕੀਲਾ</string>\n    <string name=\"pick_image_alt\">ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"app_closing_sub\">ਕੀ ਤੁਸੀਂ ਅਸਲ ਵਿੱਚ ਐਪ ਨੂੰ ਬੰਦ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?</string>\n    <string name=\"app_closing\">ਐਪ ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ</string>\n    <string name=\"stay\">ਰਹੋ</string>\n    <string name=\"close\">ਬੰਦ ਕਰੋ</string>\n    <string name=\"reset_image\">ਚਿੱਤਰ ਰੀਸੈਟ ਕਰੋ</string>\n    <string name=\"reset_image_sub\">ਚਿੱਤਰ ਤਬਦੀਲੀਆਂ ਸ਼ੁਰੂਆਤੀ ਮੁੱਲਾਂ \\'ਤੇ ਵਾਪਸ ਆ ਜਾਣਗੀਆਂ</string>\n    <string name=\"values_reset\">ਮੁੱਲ ਸਹੀ ਢੰਗ ਨਾਲ ਰੀਸੈਟ ਕਰੋ</string>\n    <string name=\"reset\">ਰੀਸੈਟ ਕਰੋ</string>\n    <string name=\"something_went_wrong\">ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ</string>\n    <string name=\"restart_app\">ਐਪ ਨੂੰ ਰੀਸਟਾਰਟ ਕਰੋ</string>\n    <string name=\"copied\">ਕਲਿੱਪਬੋਰਡ \\'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"exception\">ਅਪਵਾਦ</string>\n    <string name=\"edit_exif\">EXIF ਸੰਪਾਦਿਤ ਕਰੋ</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">ਠੀਕ ਹੈ</string>\n    <string name=\"no_exif\">ਕੋਈ EXIF ਡੇਟਾ ਨਹੀਂ ਮਿਲਿਆ</string>\n    <string name=\"add_tag\">ਟੈਗ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"save\">ਸੇਵ ਕਰੋ</string>\n    <string name=\"clear\">ਸਾਫ਼</string>\n    <string name=\"clear_exif\">EXIF ਸਾਫ਼ ਕਰੋ</string>\n    <string name=\"cancel\">ਰੱਦ ਕਰੋ</string>\n    <string name=\"clear_exif_sub\">ਸਾਰਾ ਚਿੱਤਰ EXIF ਡੇਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ। ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਅਣਕੀਤਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ!</string>\n    <string name=\"presets\">ਪ੍ਰੀਸੈਟਸ</string>\n    <string name=\"crop\">ਫਸਲ</string>\n    <string name=\"image_not_saved\">ਸੰਭਾਲ ਰਿਹਾ ਹੈ</string>\n    <string name=\"image_not_saved_sub\">ਜੇਕਰ ਤੁਸੀਂ ਹੁਣੇ ਬਾਹਰ ਨਿਕਲਦੇ ਹੋ ਤਾਂ ਸਾਰੀਆਂ ਅਣਰੱਖਿਅਤ ਤਬਦੀਲੀਆਂ ਖਤਮ ਹੋ ਜਾਣਗੀਆਂ</string>\n    <string name=\"check_source_code\">ਸੂਤਰ ਸੰਕੇਤਾਵਲੀ</string>\n    <string name=\"check_source_code_sub\">ਨਵੀਨਤਮ ਅਪਡੇਟਸ ਪ੍ਰਾਪਤ ਕਰੋ, ਮੁੱਦਿਆਂ \\'ਤੇ ਚਰਚਾ ਕਰੋ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ</string>\n    <string name=\"single_edit\">ਸਿੰਗਲ ਸੰਪਾਦਨ</string>\n    <string name=\"single_edit_sub\">ਦਿੱਤੇ ਗਏ ਇੱਕਲੇ ਚਿੱਤਰ ਦੇ ਚਸ਼ਮੇ ਬਦਲੋ</string>\n    <string name=\"pick_color\">ਰੰਗ ਚੁਣੋ</string>\n    <string name=\"pick_color_sub\">ਚਿੱਤਰ, ਕਾਪੀ ਜਾਂ ਸ਼ੇਅਰ ਤੋਂ ਰੰਗ ਚੁਣੋ</string>\n    <string name=\"image\">ਚਿੱਤਰ</string>\n    <string name=\"color\">ਰੰਗ</string>\n    <string name=\"color_copied\">ਰੰਗ ਕਾਪੀ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"crop_sub\">ਚਿੱਤਰ ਨੂੰ ਕਿਸੇ ਵੀ ਹੱਦ ਤੱਕ ਕੱਟੋ</string>\n    <string name=\"version\">ਸੰਸਕਰਣ</string>\n    <string name=\"keep_exif\">EXIF ਰੱਖੋ</string>\n    <string name=\"images\">Images: %d</string>\n    <string name=\"change_preview\">ਝਲਕ ਬਦਲੋ</string>\n    <string name=\"remove\">ਹਟਾਓ</string>\n    <string name=\"palette_sub\">ਦਿੱਤੇ ਚਿੱਤਰ ਤੋਂ ਰੰਗ ਪੈਲੇਟ ਸਵੈਚ ਤਿਆਰ ਕਰੋ</string>\n    <string name=\"generate_palette\">ਪੈਲੇਟ ਤਿਆਰ ਕਰੋ</string>\n    <string name=\"palette\">ਪੈਲੇਟ</string>\n    <string name=\"update\">ਅੱਪਡੇਟ ਕਰੋ</string>\n    <string name=\"new_version\">ਨਵਾਂ ਸੰਸਕਰਣ %1$s</string>\n    <string name=\"unsupported_type\">ਅਸਮਰਥਿਤ ਕਿਸਮ: %1$s</string>\n    <string name=\"no_palette\">ਦਿੱਤੇ ਚਿੱਤਰ ਲਈ ਪੈਲੇਟ ਤਿਆਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ</string>\n    <string name=\"original\">ਮੂਲ</string>\n    <string name=\"folder\">ਆਉਟਪੁੱਟ ਫੋਲਡਰ</string>\n    <string name=\"def\">ਡਿਫਾਲਟ</string>\n    <string name=\"custom\">ਪ੍ਰਥਾ</string>\n    <string name=\"unspecified\">ਨਿਰਦਿਸ਼ਟ</string>\n    <string name=\"device_storage\">ਡਿਵਾਈਸ ਸਟੋਰੇਜ</string>\n    <string name=\"by_bytes_resize\">ਭਾਰ ਦੁਆਰਾ ਆਕਾਰ ਬਦਲੋ</string>\n    <string name=\"max_bytes\">KB ਵਿੱਚ ਅਧਿਕਤਮ ਆਕਾਰ</string>\n    <string name=\"by_bytes_resize_sub\">KB ਵਿੱਚ ਦਿੱਤੇ ਆਕਾਰ ਦੇ ਬਾਅਦ ਇੱਕ ਚਿੱਤਰ ਨੂੰ ਮੁੜ ਆਕਾਰ ਦਿਓ</string>\n    <string name=\"compare\">ਤੁਲਨਾ ਕਰੋ</string>\n    <string name=\"compare_sub\">ਦਿੱਤੇ ਗਏ ਦੋ ਚਿੱਤਰਾਂ ਦੀ ਤੁਲਨਾ ਕਰੋ</string>\n    <string name=\"pick_two_images\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਦੋ ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"pick_images\">ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"settings\">ਸੈਟਿੰਗਾਂ</string>\n    <string name=\"night_mode\">ਨਾਈਟ ਮੋਡ</string>\n    <string name=\"dark\">ਹਨੇਰ</string>\n    <string name=\"light\">ਚਾਨਣ</string>\n    <string name=\"system\">ਸਿਸਟਮ</string>\n    <string name=\"dynamic_colors\">ਗਤੀਸ਼ੀਲ ਰੰਗ</string>\n    <string name=\"customization\">ਕਸਟਮਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"allow_image_monet\">ਚਿੱਤਰ ਮੋਨੇਟ ਦੀ ਆਗਿਆ ਦਿਓ</string>\n    <string name=\"allow_image_monet_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਹੈ, ਜਦੋਂ ਤੁਸੀਂ ਸੰਪਾਦਿਤ ਕਰਨ ਲਈ ਇੱਕ ਚਿੱਤਰ ਚੁਣਦੇ ਹੋ, ਤਾਂ ਐਪ ਦੇ ਰੰਗ ਇਸ ਚਿੱਤਰ ਲਈ ਅਪਣਾਏ ਜਾਣਗੇ</string>\n    <string name=\"language\">ਭਾਸ਼ਾ</string>\n    <string name=\"amoled_mode\">ਅਮੋਲਡ ਮੋਡ</string>\n    <string name=\"amoled_mode_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਸਤਹਾਂ ਦਾ ਰੰਗ ਰਾਤ ਦੇ ਮੋਡ ਵਿੱਚ ਬਿਲਕੁਲ ਗੂੜ੍ਹੇ \\'ਤੇ ਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"color_scheme\">ਰੰਗ ਸਕੀਮ</string>\n    <string name=\"color_red\">ਲਾਲ</string>\n    <string name=\"color_green\">ਹਰਾ</string>\n    <string name=\"color_blue\">ਨੀਲਾ</string>\n    <string name=\"clipboard_paste_invalid_color_code\">ਵੈਧ aRGB-ਕੋਡ ਪੇਸਟ ਕਰੋ।</string>\n    <string name=\"clipboard_paste_invalid_empty\">ਪੇਸਟ ਕਰਨ ਲਈ ਕੁਝ ਨਹੀਂ</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">ਡਾਇਨਾਮਿਕ ਰੰਗ ਚਾਲੂ ਹੋਣ \\'ਤੇ ਐਪ ਰੰਗ ਸਕੀਮ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ</string>\n    <string name=\"pick_accent_color\">ਐਪ ਥੀਮ ਚੁਣੇ ਗਏ ਰੰਗ \\'ਤੇ ਆਧਾਰਿਤ ਹੋਵੇਗੀ</string>\n    <string name=\"about_app\">ਐਪ ਬਾਰੇ</string>\n    <string name=\"no_updates\">ਕੋਈ ਅੱਪਡੇਟ ਨਹੀਂ ਮਿਲੇ</string>\n    <string name=\"issue_tracker\">ਮੁੱਦਾ ਟਰੈਕਰ</string>\n    <string name=\"issue_tracker_sub\">ਇੱਥੇ ਬੱਗ ਰਿਪੋਰਟਾਂ ਅਤੇ ਵਿਸ਼ੇਸ਼ਤਾ ਬੇਨਤੀਆਂ ਭੇਜੋ</string>\n    <string name=\"help_translate\">ਅਨੁਵਾਦ ਵਿੱਚ ਮਦਦ ਕਰੋ</string>\n    <string name=\"help_translate_sub\">ਅਨੁਵਾਦ ਦੀਆਂ ਗਲਤੀਆਂ ਨੂੰ ਠੀਕ ਕਰੋ ਜਾਂ ਕਿਸੇ ਹੋਰ ਭਾਸ਼ਾ ਵਿੱਚ ਪ੍ਰੋਜੈਕਟ ਦਾ ਸਥਾਨੀਕਰਨ ਕਰੋ</string>\n    <string name=\"nothing_found_by_search\">ਤੁਹਾਡੀ ਪੁੱਛਗਿੱਛ ਦੁਆਰਾ ਕੁਝ ਨਹੀਂ ਮਿਲਿਆ</string>\n    <string name=\"search_here\">ਇੱਥੇ ਖੋਜ ਕਰੋ</string>\n    <string name=\"dynamic_colors_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਹੈ, ਤਾਂ ਐਪ ਦੇ ਰੰਗਾਂ ਨੂੰ ਵਾਲਪੇਪਰ ਦੇ ਰੰਗਾਂ ਲਈ ਅਪਣਾਇਆ ਜਾਵੇਗਾ</string>\n    <string name=\"failed_to_save\">%d ਚਿੱਤਰ(ਚਿੱਤਰਾਂ) ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਵਿੱਚ ਅਸਫਲ</string>\n    <string name=\"email\">ਈ - ਮੇਲ</string>\n    <string name=\"primary\">ਪ੍ਰਾਇਮਰੀ</string>\n    <string name=\"tertiary\">ਤੀਜੇ ਦਰਜੇ</string>\n    <string name=\"secondary\">ਸੈਕੰਡਰੀ</string>\n    <string name=\"border_thickness\">ਬਾਰਡਰ ਮੋਟਾਈ</string>\n    <string name=\"surface\">ਸਤ੍ਹਾ</string>\n    <string name=\"values\">ਮੁੱਲ</string>\n    <string name=\"add\">ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"permission\">ਇਜਾਜ਼ਤ</string>\n    <string name=\"grant\">ਗ੍ਰਾਂਟ</string>\n    <string name=\"permission_sub\">ਐਪ ਨੂੰ ਕੰਮ ਕਰਨ ਲਈ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਤੁਹਾਡੀ ਸਟੋਰੇਜ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ, ਇਹ ਜ਼ਰੂਰੀ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਅਗਲੇ ਡਾਇਲਾਗ ਬਾਕਸ ਵਿੱਚ ਇਜਾਜ਼ਤ ਦਿਓ।</string>\n    <string name=\"grant_permission_manual\">ਐਪ ਨੂੰ ਕੰਮ ਕਰਨ ਲਈ ਇਸ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਇਸਨੂੰ ਹੱਥੀਂ ਦਿਓ</string>\n    <string name=\"external_storage\">ਬਾਹਰੀ ਸਟੋਰੇਜ</string>\n    <string name=\"monet_colors\">ਮੋਨੇਟ ਰੰਗ</string>\n    <string name=\"donation_sub\">ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਪੂਰੀ ਤਰ੍ਹਾਂ ਮੁਫਤ ਹੈ, ਪਰ ਜੇ ਤੁਸੀਂ ਪ੍ਰੋਜੈਕਟ ਦੇ ਵਿਕਾਸ ਦਾ ਸਮਰਥਨ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ ਇੱਥੇ ਕਲਿੱਕ ਕਰ ਸਕਦੇ ਹੋ</string>\n    <string name=\"fab_alignment\">FAB ਅਲਾਈਨਮੈਂਟ</string>\n    <string name=\"check_updates\">ਅੱਪਡੇਟ ਲਈ ਚੈੱਕ ਕਰੋ</string>\n    <string name=\"check_updates_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਹੈ, ਤਾਂ ਐਪ ਸਟਾਰਟਅੱਪ \\'ਤੇ ਅੱਪਡੇਟ ਡਾਇਲਾਗ ਤੁਹਾਨੂੰ ਦਿਖਾਇਆ ਜਾਵੇਗਾ</string>\n    <string name=\"zoom\">ਚਿੱਤਰ ਜ਼ੂਮ</string>\n    <string name=\"share\">ਸ਼ੇਅਰ ਕਰੋ</string>\n    <string name=\"prefix\">ਅਗੇਤਰ</string>\n    <string name=\"filename\">ਫਾਈਲ ਦਾ ਨਾਮ</string>\n    <string name=\"emoji\">ਇਮੋਜੀ</string>\n    <string name=\"emoji_sub\">ਮੁੱਖ ਸਕ੍ਰੀਨ \\'ਤੇ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰਨ ਲਈ ਕਿਹੜਾ ਇਮੋਜੀ ਚੁਣੋ</string>\n    <string name=\"add_file_size\">ਫਾਈਲ ਦਾ ਆਕਾਰ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_file_size_sub\">ਜੇਕਰ ਸਮਰੱਥ ਹੈ, ਤਾਂ ਆਉਟਪੁੱਟ ਫਾਈਲ ਦੇ ਨਾਮ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਚਿੱਤਰ ਦੀ ਚੌੜਾਈ ਅਤੇ ਉਚਾਈ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"delete_exif\">EXIF ਮਿਟਾਓ</string>\n    <string name=\"delete_exif_sub\">ਚਿੱਤਰਾਂ ਦੇ ਕਿਸੇ ਵੀ ਸਮੂਹ ਤੋਂ EXIF ਮੈਟਾਡੇਟਾ ਮਿਟਾਓ</string>\n    <string name=\"image_preview\">ਚਿੱਤਰ ਝਲਕ</string>\n    <string name=\"image_preview_sub\">ਕਿਸੇ ਵੀ ਕਿਸਮ ਦੀਆਂ ਤਸਵੀਰਾਂ ਦਾ ਪੂਰਵਦਰਸ਼ਨ ਕਰੋ: GIF, SVG, ਅਤੇ ਹੋਰ</string>\n    <string name=\"image_source\">ਚਿੱਤਰ ਸਰੋਤ</string>\n    <string name=\"photo_picker\">ਫੋਟੋ ਚੋਣਕਾਰ</string>\n    <string name=\"gallery_picker\">ਗੈਲਰੀ</string>\n    <string name=\"file_explorer_picker\">ਫਾਈਲ ਐਕਸਪਲੋਰਰ</string>\n    <string name=\"photo_picker_sub\">ਐਂਡਰੌਇਡ ਆਧੁਨਿਕ ਫੋਟੋ ਚੋਣਕਾਰ ਜੋ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ, ਸਿਰਫ ਐਂਡਰਾਇਡ 12+ \\'ਤੇ ਕੰਮ ਕਰ ਸਕਦਾ ਹੈ। EXIF ਮੈਟਾਡੇਟਾ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆਵਾਂ ਹਨ</string>\n    <string name=\"gallery_picker_sub\">ਸਧਾਰਨ ਗੈਲਰੀ ਚਿੱਤਰ ਚੋਣਕਾਰ। ਇਹ ਤਾਂ ਹੀ ਕੰਮ ਕਰੇਗਾ ਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਐਪ ਹੈ ਜੋ ਮੀਡੀਆ ਪਿਕਿੰਗ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ</string>\n    <string name=\"file_explorer_picker_sub\">ਚਿੱਤਰ ਚੁਣਨ ਲਈ GetContent ਇਰਾਦੇ ਦੀ ਵਰਤੋਂ ਕਰੋ। ਹਰ ਜਗ੍ਹਾ ਕੰਮ ਕਰਦਾ ਹੈ, ਪਰ ਕੁਝ ਡਿਵਾਈਸਾਂ \\'ਤੇ ਚੁਣੀਆਂ ਗਈਆਂ ਤਸਵੀਰਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆਵਾਂ ਲਈ ਜਾਣਿਆ ਜਾਂਦਾ ਹੈ। ਇਹ ਮੇਰਾ ਕਸੂਰ ਨਹੀਂ ਹੈ।</string>\n    <string name=\"options_arrangement\">ਵਿਕਲਪ ਪ੍ਰਬੰਧ</string>\n    <string name=\"edit\">ਸੰਪਾਦਿਤ ਕਰੋ</string>\n    <string name=\"order\">ਆਰਡਰ</string>\n    <string name=\"order_sub\">ਮੁੱਖ ਸਕ੍ਰੀਨ \\'ਤੇ ਵਿਕਲਪਾਂ ਦਾ ਕ੍ਰਮ ਨਿਰਧਾਰਤ ਕਰਦਾ ਹੈ</string>\n    <string name=\"emojis_count\">ਇਮੋਜੀ ਦੀ ਗਿਣਤੀ</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">ਅਸਲੀ ਫਾਈਲ ਨਾਮ</string>\n    <string name=\"add_original_filename\">ਅਸਲ ਫਾਈਲ ਨਾਮ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_original_filename_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਹੈ ਤਾਂ ਆਉਟਪੁੱਟ ਚਿੱਤਰ ਦੇ ਨਾਮ ਵਿੱਚ ਅਸਲੀ ਫਾਈਲ ਨਾਮ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"replace_sequence_number\">ਕ੍ਰਮ ਨੰਬਰ ਬਦਲੋ</string>\n    <string name=\"replace_sequence_number_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਹੈ ਤਾਂ ਸਟੈਂਡਰਡ ਟਾਈਮਸਟੈਂਪ ਨੂੰ ਚਿੱਤਰ ਕ੍ਰਮ ਨੰਬਰ \\'ਤੇ ਬਦਲ ਦਿੰਦਾ ਹੈ ਜੇਕਰ ਤੁਸੀਂ ਬੈਚ ਪ੍ਰੋਸੈਸਿੰਗ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋ</string>\n    <string name=\"filename_not_work_with_photopicker\">ਜੇਕਰ ਫੋਟੋ ਚੋਣਕਾਰ ਚਿੱਤਰ ਸਰੋਤ ਚੁਣਿਆ ਗਿਆ ਹੈ ਤਾਂ ਅਸਲ ਫਾਈਲ ਨਾਮ ਜੋੜਨਾ ਕੰਮ ਨਹੀਂ ਕਰਦਾ</string>\n    <string name=\"load_image_from_net\">ਨੈੱਟ ਤੋਂ ਚਿੱਤਰ ਲੋਡ ਕਰੋ</string>\n    <string name=\"load_image_from_net_sub\">ਜੇਕਰ ਤੁਸੀਂ ਚਾਹੋ ਤਾਂ ਪੂਰਵਦਰਸ਼ਨ, ਜ਼ੂਮ, ਸੰਪਾਦਿਤ ਅਤੇ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਇੰਟਰਨੈਟ ਤੋਂ ਕਿਸੇ ਵੀ ਚਿੱਤਰ ਨੂੰ ਲੋਡ ਕਰੋ।</string>\n    <string name=\"no_image\">ਕੋਈ ਚਿੱਤਰ ਨਹੀਂ</string>\n    <string name=\"image_link\">ਚਿੱਤਰ ਲਿੰਕ</string>\n    <string name=\"fill\">ਭਰੋ</string>\n    <string name=\"fit\">ਫਿੱਟ</string>\n    <string name=\"content_scale\">ਸਮੱਗਰੀ ਦਾ ਪੈਮਾਨਾ</string>\n    <string name=\"explicit_description\">ਹਰ ਤਸਵੀਰ ਨੂੰ ਚੌੜਾਈ ਅਤੇ ਉਚਾਈ ਪੈਰਾਮੀਟਰ ਦੁਆਰਾ ਦਿੱਤੇ ਗਏ ਚਿੱਤਰ ਵਿੱਚ ਮਜਬੂਰ ਕਰਦਾ ਹੈ - ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲ ਸਕਦਾ ਹੈ</string>\n    <string name=\"flexible_description\">ਚੌੜਾਈ ਜਾਂ ਉਚਾਈ ਪੈਰਾਮੀਟਰ ਦੁਆਰਾ ਦਿੱਤੇ ਗਏ ਲੰਬੇ ਸਾਈਡ ਵਾਲੇ ਚਿੱਤਰਾਂ ਦਾ ਆਕਾਰ ਬਦਲਦਾ ਹੈ, ਸਾਰੇ ਆਕਾਰ ਦੀ ਗਣਨਾ ਸੁਰੱਖਿਅਤ ਕਰਨ ਤੋਂ ਬਾਅਦ ਕੀਤੀ ਜਾਵੇਗੀ - ਆਕਾਰ ਅਨੁਪਾਤ ਰੱਖਦਾ ਹੈ</string>\n    <string name=\"brightness\">ਚਮਕ</string>\n    <string name=\"contrast\">ਕੰਟ੍ਰਾਸਟ</string>\n    <string name=\"hue\">ਹਿਊ</string>\n    <string name=\"saturation\">ਸੰਤ੍ਰਿਪਤਾ</string>\n    <string name=\"add_filter\">ਫਿਲਟਰ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"filter\">ਫਿਲਟਰ</string>\n    <string name=\"filter_sub\">ਦਿੱਤੇ ਚਿੱਤਰਾਂ \\'ਤੇ ਕੋਈ ਵੀ ਫਿਲਟਰ ਚੇਨ ਲਾਗੂ ਕਰੋ</string>\n    <string name=\"filters\">ਫਿਲਟਰ</string>\n    <string name=\"light_aka_illumination\">ਚਾਨਣ</string>\n    <string name=\"color_filter\">ਰੰਗ ਫਿਲਟਰ</string>\n    <string name=\"alpha\">ਅਲਫ਼ਾ</string>\n    <string name=\"exposure\">ਸੰਪਰਕ</string>\n    <string name=\"white_balance\">ਚਿੱਟਾ ਸੰਤੁਲਨ</string>\n    <string name=\"temperature\">ਤਾਪਮਾਨ</string>\n    <string name=\"tint\">ਰੰਗਤ</string>\n    <string name=\"monochrome\">ਮੋਨੋਕ੍ਰੋਮ</string>\n    <string name=\"gamma\">ਗਾਮਾ</string>\n    <string name=\"highlights_shadows\">ਹਾਈਲਾਈਟਸ ਅਤੇ ਸ਼ੈਡੋ</string>\n    <string name=\"highlights\">ਹਾਈਲਾਈਟਸ</string>\n    <string name=\"shadows\">ਪਰਛਾਵੇਂ</string>\n    <string name=\"haze\">ਧੁੰਦ</string>\n    <string name=\"effect\">ਪ੍ਰਭਾਵ</string>\n    <string name=\"distance\">ਦੂਰੀ</string>\n    <string name=\"slope\">ਢਲਾਨ</string>\n    <string name=\"sharpen\">ਤਿੱਖਾ ਕਰੋ</string>\n    <string name=\"sepia\">ਸੇਪੀਆ</string>\n    <string name=\"negative\">ਨਕਾਰਾਤਮਕ</string>\n    <string name=\"solarize\">ਸੋਲਰਾਈਜ਼ ਕਰੋ</string>\n    <string name=\"vibrance\">ਵਾਈਬ੍ਰੈਂਸ</string>\n    <string name=\"black_and_white\">ਕਾਲਾ ਅਤੇ ਚਿੱਟਾ</string>\n    <string name=\"crosshatch\">ਕਰਾਸਸ਼ੈਚ</string>\n    <string name=\"spacing\">ਵਿੱਥ</string>\n    <string name=\"line_width\">ਲਾਈਨ ਦੀ ਚੌੜਾਈ</string>\n    <string name=\"sobel_edge\">ਸੋਬਲ ਕਿਨਾਰੇ</string>\n    <string name=\"blur\">ਧੁੰਦਲਾ</string>\n    <string name=\"halftone\">ਹਾਫਟੋਨ</string>\n    <string name=\"cga_colorspace\">CGA ਕਲਰਸਪੇਸ</string>\n    <string name=\"gaussian_blur\">ਗੌਸੀਅਨ ਬਲਰ</string>\n    <string name=\"box_blur\">ਬਾਕਸ ਬਲਰ</string>\n    <string name=\"bilaterial_blur\">ਦੋ-ਪੱਖੀ ਧੁੰਦਲਾਪਨ</string>\n    <string name=\"emboss\">ਐਮਬੌਸ</string>\n    <string name=\"laplacian\">ਲੈਪਲੇਸ਼ੀਅਨ</string>\n    <string name=\"vignette\">ਵਿਗਨੇਟ</string>\n    <string name=\"start\">ਸ਼ੁਰੂ ਕਰੋ</string>\n    <string name=\"end\">ਅੰਤ</string>\n    <string name=\"kuwahara\">ਕੁਵਾਹਰਾ ਸਮੂਥਿੰਗ</string>\n    <string name=\"stack_blur\">ਸਟੈਕ ਬਲਰ</string>\n    <string name=\"radius\">ਰੇਡੀਅਸ</string>\n    <string name=\"scale\">ਸਕੇਲ</string>\n    <string name=\"distortion\">ਵਿਗਾੜ</string>\n    <string name=\"angle\">ਕੋਣ</string>\n    <string name=\"swirl\">ਘੁੰਮਣਾ</string>\n    <string name=\"bulge\">ਬਲਜ</string>\n    <string name=\"dilation\">ਫੈਲਾਅ</string>\n    <string name=\"sphere_refraction\">ਗੋਲਾਕਾਰ ਪ੍ਰਤੀਕਰਮ</string>\n    <string name=\"refractive_index\">ਰਿਫ੍ਰੈਕਟਿਵ ਇੰਡੈਕਸ</string>\n    <string name=\"glass_sphere_refraction\">ਕੱਚ ਦਾ ਗੋਲਾ ਅਪਵਰਤਨ</string>\n    <string name=\"color_matrix\">ਰੰਗ ਮੈਟ੍ਰਿਕਸ</string>\n    <string name=\"opacity\">ਧੁੰਦਲਾਪਨ</string>\n    <string name=\"limits_resize\">ਸੀਮਾਵਾਂ ਦਾ ਆਕਾਰ ਬਦਲਣਾ</string>\n    <string name=\"limits_resize_sub\">ਦਿੱਤੀ ਗਈ ਚੌੜਾਈ ਅਤੇ ਉਚਾਈ ਸੀਮਾਵਾਂ ਦੀ ਪਾਲਣਾ ਕਰਨ ਲਈ ਚੁਣੀਆਂ ਗਈਆਂ ਤਸਵੀਰਾਂ ਦਾ ਆਕਾਰ ਅਨੁਪਾਤ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਦੇ ਹੋਏ ਮੁੜ ਆਕਾਰ ਦਿਓ</string>\n    <string name=\"sketch\">ਸਕੈਚ</string>\n    <string name=\"threshold\">ਥ੍ਰੈਸ਼ਹੋਲਡ</string>\n    <string name=\"quantizationLevels\">ਕੁਆਂਟਾਇਜ਼ੇਸ਼ਨ ਪੱਧਰ</string>\n    <string name=\"smooth_toon\">ਨਿਰਵਿਘਨ ਟੂਨ</string>\n    <string name=\"toon\">ਟੂਨ</string>\n    <string name=\"posterize\">ਪੋਸਟਰਾਈਜ਼ ਕਰੋ</string>\n    <string name=\"non_maximum_suppression\">ਗੈਰ ਅਧਿਕਤਮ ਦਮਨ</string>\n    <string name=\"weak_pixel_inclusion\">ਕਮਜ਼ੋਰ ਪਿਕਸਲ ਸੰਮਿਲਨ</string>\n    <string name=\"lookup\">ਝਾਂਕਨਾ</string>\n    <string name=\"convolution3x3\">ਕਨਵੋਲਿਊਸ਼ਨ 3x3</string>\n    <string name=\"rgb_filter\">RGB ਫਿਲਟਰ</string>\n    <string name=\"false_color\">ਝੂਠਾ ਰੰਗ</string>\n    <string name=\"first_color\">ਪਹਿਲਾ ਰੰਗ</string>\n    <string name=\"second_color\">ਦੂਜਾ ਰੰਗ</string>\n    <string name=\"reorder\">ਮੁੜ ਕ੍ਰਮਬੱਧ ਕਰੋ</string>\n    <string name=\"fast_blur\">ਤੇਜ਼ ਬਲਰ</string>\n    <string name=\"blur_size\">ਧੁੰਦਲਾ ਆਕਾਰ</string>\n    <string name=\"blur_center_x\">ਧੁੰਦਲਾ ਕੇਂਦਰ x</string>\n    <string name=\"blur_center_y\">ਬਲਰ ਸੈਂਟਰ y</string>\n    <string name=\"zoom_blur\">ਜ਼ੂਮ ਬਲਰ</string>\n    <string name=\"color_balance\">ਰੰਗ ਸੰਤੁਲਨ</string>\n    <string name=\"luminance_threshold\">ਲੂਮਿਨੈਂਸ ਥ੍ਰੈਸ਼ਹੋਲਡ</string>\n    <string name=\"activate_files\">ਤੁਸੀਂ Files ਐਪ ਨੂੰ ਅਯੋਗ ਕਰ ਦਿੱਤਾ ਹੈ, ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਇਸਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ</string>\n    <string name=\"draw\">ਡਰਾਅ</string>\n    <string name=\"draw_sub\">ਚਿੱਤਰ \\'ਤੇ ਖਿੱਚੋ ਜਿਵੇਂ ਕਿ ਇੱਕ ਸਕੈਚਬੁੱਕ ਵਿੱਚ, ਜਾਂ ਬੈਕਗ੍ਰਾਉਂਡ \\'ਤੇ ਹੀ ਖਿੱਚੋ</string>\n    <string name=\"paint_color\">ਪੇਂਟ ਰੰਗ</string>\n    <string name=\"paint_alpha\">ਪੇਂਟ ਅਲਫ਼ਾ</string>\n    <string name=\"draw_on_image\">ਚਿੱਤਰ \\'ਤੇ ਖਿੱਚੋ</string>\n    <string name=\"draw_on_image_sub\">ਇੱਕ ਚਿੱਤਰ ਚੁਣੋ ਅਤੇ ਇਸ \\'ਤੇ ਕੁਝ ਖਿੱਚੋ</string>\n    <string name=\"draw_on_background\">ਬੈਕਗ੍ਰਾਊਂਡ \\'ਤੇ ਖਿੱਚੋ</string>\n    <string name=\"draw_on_background_sub\">ਬੈਕਗ੍ਰਾਉਂਡ ਰੰਗ ਚੁਣੋ ਅਤੇ ਇਸਦੇ ਸਿਖਰ \\'ਤੇ ਖਿੱਚੋ</string>\n    <string name=\"background_color\">ਬੈਕਗ੍ਰਾਊਂਡ ਦਾ ਰੰਗ</string>\n    <string name=\"cipher\">ਸਿਫਰ</string>\n    <string name=\"cipher_sub\">ਏਈਐਸ ਕ੍ਰਿਪਟੋ ਐਲਗੋਰਿਦਮ ਦੇ ਅਧਾਰ ਤੇ ਕਿਸੇ ਵੀ ਫਾਈਲ ਨੂੰ ਐਨਕ੍ਰਿਪਟ ਅਤੇ ਡੀਕ੍ਰਿਪਟ ਕਰੋ (ਸਿਰਫ ਚਿੱਤਰ ਹੀ ਨਹੀਂ)</string>\n    <string name=\"pick_file\">ਫਾਈਲ ਚੁਣੋ</string>\n    <string name=\"encrypt\">ਐਨਕ੍ਰਿਪਟ</string>\n    <string name=\"decrypt\">ਡੀਕ੍ਰਿਪਟ ਕਰੋ</string>\n    <string name=\"pick_file_to_start\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਫਾਈਲ ਚੁਣੋ</string>\n    <string name=\"decryption\">ਡਿਕ੍ਰਿਪਸ਼ਨ</string>\n    <string name=\"encryption\">ਐਨਕ੍ਰਿਪਸ਼ਨ</string>\n    <string name=\"key\">ਕੁੰਜੀ</string>\n    <string name=\"file_proceed\">ਫ਼ਾਈਲ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕੀਤੀ ਗਈ</string>\n    <string name=\"store_file_desc\">ਇਸ ਫ਼ਾਈਲ ਨੂੰ ਆਪਣੀ ਡੀਵਾਈਸ \\'ਤੇ ਸਟੋਰ ਕਰੋ ਜਾਂ ਇਸਨੂੰ ਜਿੱਥੇ ਚਾਹੋ ਉੱਥੇ ਰੱਖਣ ਲਈ ਸਾਂਝਾਕਰਨ ਕਾਰਵਾਈ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"features\">ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ</string>\n    <string name=\"implementation\">ਲਾਗੂ ਕਰਨ</string>\n    <string name=\"compatibility\">ਅਨੁਕੂਲਤਾ</string>\n    <string name=\"features_sub\">ਫਾਈਲਾਂ ਦੀ ਪਾਸਵਰਡ-ਅਧਾਰਿਤ ਏਨਕ੍ਰਿਪਸ਼ਨ। ਅੱਗੇ ਵਧੀਆਂ ਫਾਈਲਾਂ ਨੂੰ ਚੁਣੀ ਗਈ ਡਾਇਰੈਕਟਰੀ ਵਿੱਚ ਸਟੋਰ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ ਜਾਂ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ। ਡੀਕ੍ਰਿਪਟਡ ਫਾਈਲਾਂ ਨੂੰ ਸਿੱਧੇ ਵੀ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ ਹੈ.</string>\n    <string name=\"implementation_sub\">AES-256, GCM ਮੋਡ, ਕੋਈ ਪੈਡਿੰਗ ਨਹੀਂ, 12 ਬਾਈਟ ਬੇਤਰਤੀਬੇ IVs। ਕੁੰਜੀਆਂ SHA-3 ਹੈਸ਼ਾਂ (256 ਬਿੱਟ) ਵਜੋਂ ਵਰਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ।</string>\n    <string name=\"file_size\">ਫ਼ਾਈਲ ਦਾ ਆਕਾਰ</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">ਕਿਰਪਾ ਕਰਕੇ ਨੋਟ ਕਰੋ ਕਿ ਹੋਰ ਫਾਈਲ ਐਨਕ੍ਰਿਪਸ਼ਨ ਸੌਫਟਵੇਅਰ ਜਾਂ ਸੇਵਾਵਾਂ ਲਈ ਅਨੁਕੂਲਤਾ ਦੀ ਗਰੰਟੀ ਨਹੀਂ ਹੈ। ਇੱਕ ਥੋੜ੍ਹਾ ਵੱਖਰਾ ਕੁੰਜੀ ਇਲਾਜ ਜਾਂ ਸਿਫਰ ਕੌਂਫਿਗਰੇਸ਼ਨ ਅਸੰਗਤਤਾ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੀ ਹੈ।</string>\n    <string name=\"invalid_password_or_not_encrypted\">ਅਵੈਧ ਪਾਸਵਰਡ ਜਾਂ ਚੁਣੀ ਗਈ ਫਾਈਲ ਐਨਕ੍ਰਿਪਟਡ ਨਹੀਂ ਹੈ</string>\n    <string name=\"image_size_warning\">ਦਿੱਤੀ ਗਈ ਚੌੜਾਈ ਅਤੇ ਉਚਾਈ ਦੇ ਨਾਲ ਚਿੱਤਰ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਨਾਲ ਇੱਕ OOM ਗਲਤੀ ਹੋ ਸਕਦੀ ਹੈ। ਇਹ ਆਪਣੇ ਜੋਖਮ \\'ਤੇ ਕਰੋ, ਅਤੇ ਇਹ ਨਾ ਕਹੋ ਕਿ ਮੈਂ ਤੁਹਾਨੂੰ ਚੇਤਾਵਨੀ ਨਹੀਂ ਦਿੱਤੀ!</string>\n    <string name=\"cache\">ਕੈਸ਼</string>\n    <string name=\"cache_size\">ਕੈਸ਼ ਆਕਾਰ</string>\n    <string name=\"found_s\">%1$s ਮਿਲਿਆ</string>\n    <string name=\"auto_cache_clearing\">ਆਟੋ ਕੈਸ਼ ਕਲੀਅਰਿੰਗ</string>\n    <string name=\"auto_cache_clearing_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਐਪ ਕੈਸ਼ ਐਪ ਸਟਾਰਟਅਪ \\'ਤੇ ਕਲੀਅਰ ਕੀਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"create\">ਬਣਾਓ</string>\n    <string name=\"tools\">ਸੰਦ</string>\n    <string name=\"group_options_by_type\">ਕਿਸਮ ਦੇ ਅਨੁਸਾਰ ਸਮੂਹ ਵਿਕਲਪ</string>\n    <string name=\"group_options_by_type_sub\">ਇੱਕ ਕਸਟਮ ਸੂਚੀ ਪ੍ਰਬੰਧ ਦੀ ਬਜਾਏ ਉਹਨਾਂ ਦੀ ਕਿਸਮ ਦੁਆਰਾ ਮੁੱਖ ਸਕ੍ਰੀਨ \\'ਤੇ ਸਮੂਹ ਵਿਕਲਪ</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">ਵਿਕਲਪ ਗਰੁੱਪਿੰਗ ਯੋਗ ਹੋਣ \\'ਤੇ ਵਿਵਸਥਾ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ</string>\n    <string name=\"edit_screenshot\">ਸਕ੍ਰੀਨਸ਼ੌਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ</string>\n    <string name=\"secondary_customization\">ਸੈਕੰਡਰੀ ਅਨੁਕੂਲਤਾ</string>\n    <string name=\"screenshot\">ਸਕਰੀਨਸ਼ਾਟ</string>\n    <string name=\"fallback_option\">ਫਾਲਬੈਕ ਵਿਕਲਪ</string>\n    <string name=\"skip\">ਛੱਡੋ</string>\n    <string name=\"copy\">ਕਾਪੀ ਕਰੋ</string>\n    <string name=\"warning_bytes\">%1$s ਮੋਡ ਵਿੱਚ ਸੰਭਾਲਣਾ ਅਸਥਿਰ ਹੋ ਸਕਦਾ ਹੈ, ਕਿਉਂਕਿ ਇਹ ਇੱਕ ਨੁਕਸਾਨ ਰਹਿਤ ਫਾਰਮੈਟ ਹੈ</string>\n    <string name=\"presets_sub\" formatted=\"false\">ਜੇਕਰ ਤੁਸੀਂ ਪ੍ਰੀਸੈਟ 125 ਦੀ ਚੋਣ ਕੀਤੀ ਹੈ, ਤਾਂ ਚਿੱਤਰ ਨੂੰ 100% ਗੁਣਵੱਤਾ ਦੇ ਨਾਲ ਅਸਲ ਚਿੱਤਰ ਦੇ 125% ਆਕਾਰ ਵਜੋਂ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਜਾਵੇਗਾ। ਜੇਕਰ ਤੁਸੀਂ ਪ੍ਰੀਸੈਟ 50 ਦੀ ਚੋਣ ਕਰਦੇ ਹੋ, ਤਾਂ ਚਿੱਤਰ ਨੂੰ 50% ਆਕਾਰ ਅਤੇ 50% ਗੁਣਵੱਤਾ ਨਾਲ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਜਾਵੇਗਾ।</string>\n    <string name=\"presets_sub_bytes\">ਇੱਥੇ ਪ੍ਰੀਸੈਟ ਆਉਟਪੁੱਟ ਫਾਈਲ ਦਾ % ਨਿਰਧਾਰਤ ਕਰਦਾ ਹੈ, ਭਾਵ ਜੇਕਰ ਤੁਸੀਂ 5mb ਚਿੱਤਰ \\'ਤੇ ਪ੍ਰੀਸੈਟ 50 ਦੀ ਚੋਣ ਕਰਦੇ ਹੋ ਤਾਂ ਤੁਹਾਨੂੰ ਸੇਵ ਕਰਨ ਤੋਂ ਬਾਅਦ 2.5mb ਚਿੱਤਰ ਮਿਲੇਗਾ।</string>\n    <string name=\"randomize_filename\">ਫਾਈਲ ਨਾਮ ਨੂੰ ਰੈਂਡਮਾਈਜ਼ ਕਰੋ</string>\n    <string name=\"randomize_filename_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਆਉਟਪੁੱਟ ਫਾਈਲ ਨਾਮ ਪੂਰੀ ਤਰ੍ਹਾਂ ਬੇਤਰਤੀਬ ਹੋ ਜਾਵੇਗਾ</string>\n    <string name=\"saved_to\">%2$s ਨਾਮ ਦੇ ਨਾਲ %1$s ਫੋਲਡਰ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"saved_to_without_filename\">%1$s ਫੋਲਡਰ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"tg_chat\">ਟੈਲੀਗ੍ਰਾਮ ਚੈਟ</string>\n    <string name=\"tg_chat_sub\">ਐਪ \\'ਤੇ ਚਰਚਾ ਕਰੋ ਅਤੇ ਦੂਜੇ ਉਪਭੋਗਤਾਵਾਂ ਤੋਂ ਫੀਡਬੈਕ ਪ੍ਰਾਪਤ ਕਰੋ। ਤੁਸੀਂ ਇੱਥੇ ਬੀਟਾ ਅੱਪਡੇਟ ਅਤੇ ਇਨਸਾਈਟਸ ਵੀ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ।</string>\n    <string name=\"crop_mask\">ਫਸਲ ਮਾਸਕ</string>\n    <string name=\"aspect_ratio\">ਆਕਾਰ ਅਨੁਪਾਤ</string>\n    <string name=\"image_crop_mask_sub\">ਦਿੱਤੇ ਚਿੱਤਰ ਤੋਂ ਮਾਸਕ ਬਣਾਉਣ ਲਈ ਇਸ ਮਾਸਕ ਕਿਸਮ ਦੀ ਵਰਤੋਂ ਕਰੋ, ਧਿਆਨ ਦਿਓ ਕਿ ਇਸ ਵਿੱਚ ਅਲਫ਼ਾ ਚੈਨਲ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ</string>\n    <string name=\"backup_and_restore\">ਬੈਕਅੱਪ ਅਤੇ ਰੀਸਟੋਰ</string>\n    <string name=\"backup\">ਬੈਕਅੱਪ</string>\n    <string name=\"restore\">ਰੀਸਟੋਰ ਕਰੋ</string>\n    <string name=\"backup_sub\">ਇੱਕ ਫਾਈਲ ਵਿੱਚ ਆਪਣੀਆਂ ਐਪ ਸੈਟਿੰਗਾਂ ਦਾ ਬੈਕਅੱਪ ਲਓ</string>\n    <string name=\"restore_sub\">ਪਹਿਲਾਂ ਤਿਆਰ ਕੀਤੀ ਫਾਈਲ ਤੋਂ ਐਪ ਸੈਟਿੰਗਾਂ ਨੂੰ ਰੀਸਟੋਰ ਕਰੋ</string>\n    <string name=\"corrupted_file_or_not_a_backup\">ਖਰਾਬ ਫਾਈਲ ਜਾਂ ਬੈਕਅੱਪ ਨਹੀਂ</string>\n    <string name=\"settings_restored\">ਸੈਟਿੰਗਾਂ ਸਫਲਤਾਪੂਰਵਕ ਰੀਸਟੋਰ ਕੀਤੀਆਂ ਗਈਆਂ</string>\n    <string name=\"contact_me\">ਮੇਰੇ ਨਾਲ ਸੰਪਰਕ ਕਰੋ</string>\n    <string name=\"reset_settings_sub\">ਇਹ ਤੁਹਾਡੀਆਂ ਸੈਟਿੰਗਾਂ ਨੂੰ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਮੁੱਲਾਂ \\'ਤੇ ਵਾਪਸ ਭੇਜ ਦੇਵੇਗਾ। ਧਿਆਨ ਦਿਓ ਕਿ ਉੱਪਰ ਦੱਸੇ ਬੈਕਅੱਪ ਫਾਈਲ ਤੋਂ ਬਿਨਾਂ ਇਸਨੂੰ ਅਣਕੀਤਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।</string>\n    <string name=\"delete\">ਮਿਟਾਓ</string>\n    <string name=\"delete_color_scheme_warn\">ਤੁਸੀਂ ਚੁਣੀ ਗਈ ਰੰਗ ਸਕੀਮ ਨੂੰ ਮਿਟਾਉਣ ਲੱਗੇ ਹੋ। ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਅਣਕੀਤਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ</string>\n    <string name=\"delete_color_scheme_title\">ਸਕੀਮ ਮਿਟਾਓ</string>\n    <string name=\"font\">ਫੌਂਟ</string>\n    <string name=\"text\">ਟੈਕਸਟ</string>\n    <string name=\"font_scale\">ਫੌਂਟ ਸਕੇਲ</string>\n    <string name=\"defaultt\">ਡਿਫਾਲਟ</string>\n    <string name=\"using_large_fonts_warn\">ਵੱਡੇ ਫੌਂਟ ਸਕੇਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਨਾਲ UI ਗੜਬੜੀਆਂ ਅਤੇ ਸਮੱਸਿਆਵਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ, ਜੋ ਠੀਕ ਨਹੀਂ ਕੀਤੀਆਂ ਜਾਣਗੀਆਂ। ਸਾਵਧਾਨੀ ਨਾਲ ਵਰਤੋ.</string>\n    <string name=\"alphabet_and_numbers\">ਅ ਆ ਇ ਈ ਉ ਊ ਏ ਐ ਓ ਔ ਕ ਖ ਗ ਘ ਙ ਚ ਛ ਜ ਝ ਞ ਟ ਠ ਡ ਢ ਣ ਤ ਥ ਦ ਧ ਨ ਪ ਫ ਬ ਭ ਮ ਯ ਰ ਲ ਵ ਸ ਹ 0123456789 !?</string>\n    <string name=\"emotions\">ਜਜ਼ਬਾਤ</string>\n    <string name=\"food_and_drink\">ਭੋਜਨ ਅਤੇ ਪੀ</string>\n    <string name=\"nature_and_animals\">ਕੁਦਰਤ ਅਤੇ ਜਾਨਵਰ</string>\n    <string name=\"objects\">ਵਸਤੂਆਂ</string>\n    <string name=\"symbols\">ਚਿੰਨ੍ਹ</string>\n    <string name=\"enable_emoji\">ਇਮੋਜੀ ਚਾਲੂ ਕਰੋ</string>\n    <string name=\"travels_and_places\">ਯਾਤਰਾਵਾਂ ਅਤੇ ਸਥਾਨ</string>\n    <string name=\"activities\">ਗਤੀਵਿਧੀਆਂ</string>\n    <string name=\"background_remover\">ਬੈਕਗ੍ਰਾਊਂਡ ਰਿਮੂਵਰ</string>\n    <string name=\"background_remover_sub\">ਡਰਾਇੰਗ ਦੁਆਰਾ ਚਿੱਤਰ ਤੋਂ ਪਿਛੋਕੜ ਹਟਾਓ ਜਾਂ ਆਟੋ ਵਿਕਲਪ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"trim_image\">ਚਿੱਤਰ ਨੂੰ ਕੱਟੋ</string>\n    <string name=\"keep_exif_sub\">ਅਸਲ ਚਿੱਤਰ ਮੈਟਾਡੇਟਾ ਰੱਖਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"trim_image_sub\">ਚਿੱਤਰ ਦੇ ਆਲੇ-ਦੁਆਲੇ ਪਾਰਦਰਸ਼ੀ ਖਾਲੀ ਥਾਂਵਾਂ ਨੂੰ ਕੱਟਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"auto_erase_background\">ਬੈਕਗ੍ਰਾਊਂਡ ਨੂੰ ਸਵੈਚਲਿਤ ਤੌਰ \\'ਤੇ ਮਿਟਾਓ</string>\n    <string name=\"restore_image\">ਚਿੱਤਰ ਰੀਸਟੋਰ ਕਰੋ</string>\n    <string name=\"erase_mode\">ਮਿਟਾਓ ਮੋਡ</string>\n    <string name=\"erase_background\">ਪਿਛੋਕੜ ਮਿਟਾਓ</string>\n    <string name=\"restore_background\">ਬੈਕਗ੍ਰਾਊਂਡ ਰੀਸਟੋਰ ਕਰੋ</string>\n    <string name=\"blur_radius\">ਧੁੰਦਲਾ ਘੇਰਾ</string>\n    <string name=\"pipette\">ਪਾਈਪੇਟ</string>\n    <string name=\"draw_mode\">ਡਰਾਅ ਮੋਡ</string>\n    <string name=\"create_issue\">ਮੁੱਦਾ ਬਣਾਓ</string>\n    <string name=\"something_went_wrong_emphasis\">ਓਹੋ… ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ। ਤੁਸੀਂ ਹੇਠਾਂ ਦਿੱਤੇ ਵਿਕਲਪਾਂ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਮੈਨੂੰ ਲਿਖ ਸਕਦੇ ਹੋ ਅਤੇ ਮੈਂ ਹੱਲ ਲੱਭਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਾਂਗਾ</string>\n    <string name=\"resize_and_convert\">ਮੁੜ ਆਕਾਰ ਦਿਓ ਅਤੇ ਕਨਵਰਟ ਕਰੋ</string>\n    <string name=\"resize_and_convert_sub\">ਦਿੱਤੇ ਚਿੱਤਰਾਂ ਦਾ ਆਕਾਰ ਬਦਲੋ ਜਾਂ ਉਹਨਾਂ ਨੂੰ ਹੋਰ ਫਾਰਮੈਟਾਂ ਵਿੱਚ ਬਦਲੋ। EXIF ਮੈਟਾਡੇਟਾ ਨੂੰ ਵੀ ਇੱਥੇ ਸੰਪਾਦਿਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ ਜੇਕਰ ਇੱਕ ਸਿੰਗਲ ਚਿੱਤਰ ਨੂੰ ਚੁਣਿਆ ਜਾ ਰਿਹਾ ਹੈ.</string>\n    <string name=\"max_colors_count\">ਅਧਿਕਤਮ ਰੰਗ ਦੀ ਗਿਣਤੀ</string>\n    <string name=\"crashlytics_sub\">ਇਹ ਐਪ ਨੂੰ ਕਰੈਸ਼ ਰਿਪੋਰਟਾਂ ਨੂੰ ਹੱਥੀਂ ਇਕੱਠਾ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ</string>\n    <string name=\"analytics\">ਵਿਸ਼ਲੇਸ਼ਣ</string>\n    <string name=\"analytics_sub\">ਅਗਿਆਤ ਐਪ ਵਰਤੋਂ ਦੇ ਅੰਕੜੇ ਇਕੱਠੇ ਕਰਨ ਦਿਓ</string>\n    <string name=\"image_exif_warning\">ਵਰਤਮਾਨ ਵਿੱਚ, %1$s ਫਾਰਮੈਟ ਸਿਰਫ ਐਂਡਰਾਇਡ \\'ਤੇ EXIF ਮੈਟਾਡੇਟਾ ਨੂੰ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੁਰੱਖਿਅਤ ਕੀਤੇ ਜਾਣ \\'ਤੇ ਆਉਟਪੁੱਟ ਚਿੱਤਰ ਵਿੱਚ ਮੇਟਾਡੇਟਾ ਬਿਲਕੁਲ ਨਹੀਂ ਹੋਵੇਗਾ।</string>\n    <string name=\"effort\">ਜਤਨ</string>\n    <string name=\"effort_sub\">%1$s ਦੇ ਮੁੱਲ ਦਾ ਅਰਥ ਹੈ ਇੱਕ ਤੇਜ਼ ਕੰਪਰੈਸ਼ਨ, ਜਿਸਦੇ ਨਤੀਜੇ ਵਜੋਂ ਇੱਕ ਮੁਕਾਬਲਤਨ ਵੱਡਾ ਫਾਈਲ ਆਕਾਰ ਹੁੰਦਾ ਹੈ। %2$s ਦਾ ਮਤਲਬ ਹੈ ਇੱਕ ਹੌਲੀ ਕੰਪਰੈਸ਼ਨ, ਨਤੀਜੇ ਵਜੋਂ ਇੱਕ ਛੋਟੀ ਫਾਈਲ।</string>\n    <string name=\"wait\">ਉਡੀਕ ਕਰੋ</string>\n    <string name=\"saving_almost_complete\">ਸੰਭਾਲਣਾ ਲਗਭਗ ਪੂਰਾ ਹੋਇਆ। ਹੁਣੇ ਰੱਦ ਕਰਨ ਲਈ ਦੁਬਾਰਾ ਬੱਚਤ ਕਰਨ ਦੀ ਲੋੜ ਹੋਵੇਗੀ।</string>\n    <string name=\"updates\">ਅੱਪਡੇਟ</string>\n    <string name=\"allow_betas\">ਬੀਟਾ ਦੀ ਆਗਿਆ ਦਿਓ</string>\n    <string name=\"allow_betas_sub\">ਅੱਪਡੇਟ ਜਾਂਚ ਵਿੱਚ ਬੀਟਾ ਐਪ ਵਰਜਨ ਸ਼ਾਮਲ ਹੋਣਗੇ ਜੇਕਰ ਸਮਰਥਿਤ ਹੈ</string>\n    <string name=\"draw_arrows\">ਤੀਰ ਖਿੱਚੋ</string>\n    <string name=\"draw_arrows_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਡਰਾਇੰਗ ਮਾਰਗ ਨੂੰ ਪੁਆਇੰਟਿੰਗ ਐਰੋ ਵਜੋਂ ਦਰਸਾਇਆ ਜਾਵੇਗਾ</string>\n    <string name=\"brush_softness\">ਬੁਰਸ਼ ਨਰਮਤਾ</string>\n    <string name=\"crop_description\">ਤਸਵੀਰਾਂ ਨੂੰ ਦਾਖਲ ਕੀਤੇ ਆਕਾਰ ਦੇ ਵਿਚਕਾਰ ਕੱਟਿਆ ਜਾਵੇਗਾ। ਜੇਕਰ ਚਿੱਤਰ ਦਾਖਲ ਕੀਤੇ ਮਾਪਾਂ ਤੋਂ ਛੋਟਾ ਹੈ ਤਾਂ ਕੈਨਵਸ ਨੂੰ ਦਿੱਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਰੰਗ ਨਾਲ ਵਿਸਤਾਰ ਕੀਤਾ ਜਾਵੇਗਾ।</string>\n    <string name=\"donation\">ਦਾਨ</string>\n    <string name=\"image_stitching\">ਚਿੱਤਰ ਸਿਲਾਈ</string>\n    <string name=\"image_stitching_sub\">ਇੱਕ ਵੱਡਾ ਚਿੱਤਰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਦਿੱਤੇ ਚਿੱਤਰਾਂ ਨੂੰ ਜੋੜੋ</string>\n    <string name=\"pick_at_least_two_images\">ਘੱਟੋ-ਘੱਟ 2 ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"output_image_scale\">ਆਉਟਪੁੱਟ ਚਿੱਤਰ ਸਕੇਲ</string>\n    <string name=\"image_orientation\">ਚਿੱਤਰ ਸਥਿਤੀ</string>\n    <string name=\"horizontal\">ਹਰੀਜੱਟਲ</string>\n    <string name=\"vertical\">ਵਰਟੀਕਲ</string>\n    <string name=\"scale_small_images_to_large\">ਛੋਟੇ ਚਿੱਤਰਾਂ ਨੂੰ ਵੱਡੇ ਤੱਕ ਸਕੇਲ ਕਰੋ</string>\n    <string name=\"scale_small_images_to_large_sub\">ਛੋਟੇ ਚਿੱਤਰਾਂ ਨੂੰ ਕ੍ਰਮ ਵਿੱਚ ਸਭ ਤੋਂ ਵੱਡੇ ਚਿੱਤਰਾਂ ਤੱਕ ਸਕੇਲ ਕੀਤਾ ਜਾਵੇਗਾ ਜੇਕਰ ਸਮਰੱਥ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ</string>\n    <string name=\"images_order\">ਚਿੱਤਰ ਆਰਡਰ</string>\n    <string name=\"regular\">ਰੋਜਾਨਾ</string>\n    <string name=\"blur_edges\">ਕਿਨਾਰਿਆਂ ਨੂੰ ਧੁੰਦਲਾ ਕਰੋ</string>\n    <string name=\"blur_edges_sub\">ਜੇਕਰ ਸਮਰੱਥ ਹੋਵੇ ਤਾਂ ਇੱਕਲੇ ਰੰਗ ਦੀ ਬਜਾਏ ਇਸਦੇ ਆਲੇ ਦੁਆਲੇ ਖਾਲੀ ਥਾਂਵਾਂ ਨੂੰ ਭਰਨ ਲਈ ਅਸਲ ਚਿੱਤਰ ਦੇ ਹੇਠਾਂ ਧੁੰਦਲੇ ਕਿਨਾਰਿਆਂ ਨੂੰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"pixelation\">ਪਿਕਸਲੇਸ਼ਨ</string>\n    <string name=\"enhanced_pixelation\">ਵਿਸਤ੍ਰਿਤ ਪਿਕਸਲੇਸ਼ਨ</string>\n    <string name=\"stroke_pixelation\">ਸਟ੍ਰੋਕ ਪਿਕਸਲੇਸ਼ਨ</string>\n    <string name=\"enhanced_diamond_pixelation\">ਵਿਸਤ੍ਰਿਤ ਡਾਇਮੰਡ ਪਿਕਸਲੇਸ਼ਨ</string>\n    <string name=\"diamond_pixelation\">ਡਾਇਮੰਡ ਪਿਕਸਲੇਸ਼ਨ</string>\n    <string name=\"circle_pixelation\">ਸਰਕਲ ਪਿਕਸਲੇਸ਼ਨ</string>\n    <string name=\"enhanced_circle_pixelation\">ਵਿਸਤ੍ਰਿਤ ਸਰਕਲ ਪਿਕਸਲੇਸ਼ਨ</string>\n    <string name=\"replace_color\">ਰੰਗ ਬਦਲੋ</string>\n    <string name=\"tolerance\">ਸਹਿਣਸ਼ੀਲਤਾ</string>\n    <string name=\"color_to_replace\">ਬਦਲਣ ਲਈ ਰੰਗ</string>\n    <string name=\"target_color\">ਨਿਸ਼ਾਨਾ ਰੰਗ</string>\n    <string name=\"color_to_remove\">ਹਟਾਉਣ ਲਈ ਰੰਗ</string>\n    <string name=\"remove_color\">ਰੰਗ ਹਟਾਓ</string>\n    <string name=\"recode\">ਰੀਕੋਡ ਕਰੋ</string>\n    <string name=\"pixel_size\">ਪਿਕਸਲ ਆਕਾਰ</string>\n    <string name=\"lock_draw_orientation\">ਲੌਕ ਡਰਾਅ ਸਥਿਤੀ</string>\n    <string name=\"lock_draw_orientation_sub\">ਜੇਕਰ ਡਰਾਇੰਗ ਮੋਡ ਵਿੱਚ ਸਮਰਥਿਤ ਹੈ, ਤਾਂ ਸਕ੍ਰੀਨ ਘੁੰਮੇਗੀ ਨਹੀਂ</string>\n    <string name=\"check_for_updates\">ਅੱਪਡੇਟ ਲਈ ਚੈੱਕ ਕਰੋ</string>\n    <string name=\"palette_style\">ਪੈਲੇਟ ਸ਼ੈਲੀ</string>\n    <string name=\"tonal_spot\">ਟੋਨਲ ਸਪਾਟ</string>\n    <string name=\"neutral\">ਨਿਰਪੱਖ</string>\n    <string name=\"vibrant\">ਉਤੇਜਿਤ</string>\n    <string name=\"expressive\">ਭਾਵਪੂਰਤ</string>\n    <string name=\"rainbow\">ਸਤਰੰਗੀ ਪੀ</string>\n    <string name=\"fruit_salad\">ਫਲ ਸਲਾਦ</string>\n    <string name=\"fidelity\">ਵਫ਼ਾਦਾਰੀ</string>\n    <string name=\"content\">ਸਮੱਗਰੀ</string>\n    <string name=\"tonal_spot_sub\">ਡਿਫੌਲਟ ਪੈਲੇਟ ਸਟਾਈਲ, ਇਹ ਸਾਰੇ ਚਾਰ ਰੰਗਾਂ ਨੂੰ ਅਨੁਕੂਲਿਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ, ਹੋਰ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਮੁੱਖ ਰੰਗ ਸੈੱਟ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ</string>\n    <string name=\"neutral_sub\">ਇੱਕ ਸ਼ੈਲੀ ਜੋ ਮੋਨੋਕ੍ਰੋਮ ਨਾਲੋਂ ਥੋੜ੍ਹੀ ਜ਼ਿਆਦਾ ਰੰਗੀਨ ਹੈ</string>\n    <string name=\"vibrant_sub\">ਇੱਕ ਉੱਚੀ ਥੀਮ, ਰੰਗੀਨਤਾ ਪ੍ਰਾਇਮਰੀ ਪੈਲੇਟ ਲਈ ਵੱਧ ਤੋਂ ਵੱਧ ਹੈ, ਦੂਜਿਆਂ ਲਈ ਵਧੀ ਹੋਈ ਹੈ</string>\n    <string name=\"playful_scheme\">ਇੱਕ ਚੰਚਲ ਥੀਮ - ਸਰੋਤ ਰੰਗ ਦਾ ਰੰਗ ਥੀਮ ਵਿੱਚ ਦਿਖਾਈ ਨਹੀਂ ਦਿੰਦਾ ਹੈ</string>\n    <string name=\"monochrome_sub\">ਇੱਕ ਮੋਨੋਕ੍ਰੋਮ ਥੀਮ, ਰੰਗ ਬਿਲਕੁਲ ਕਾਲੇ / ਚਿੱਟੇ / ਸਲੇਟੀ ਹਨ</string>\n    <string name=\"content_sub\">ਇੱਕ ਸਕੀਮ ਜੋ Scheme.primaryContainer ਵਿੱਚ ਸਰੋਤ ਰੰਗ ਰੱਖਦੀ ਹੈ</string>\n    <string name=\"fidelity_sub\">ਇੱਕ ਸਕੀਮ ਜੋ ਸਮੱਗਰੀ ਸਕੀਮ ਨਾਲ ਬਹੁਤ ਮਿਲਦੀ ਜੁਲਦੀ ਹੈ</string>\n    <string name=\"foss_update_checker_warning\">ਇਹ ਅੱਪਡੇਟ ਚੈਕਰ GitHub ਨਾਲ ਕਨੈਕਟ ਕਰੇਗਾ ਜਾਂਚ ਦੇ ਕਾਰਨ ਕਿ ਕੀ ਕੋਈ ਨਵਾਂ ਅੱਪਡੇਟ ਉਪਲਬਧ ਹੈ</string>\n    <string name=\"attention\">ਧਿਆਨ</string>\n    <string name=\"fading_edges\">ਫੇਡਿੰਗ ਕਿਨਾਰੇ</string>\n    <string name=\"disabled\">ਅਯੋਗ</string>\n    <string name=\"both\">ਦੋਵੇਂ</string>\n    <string name=\"invert_colors\">ਉਲਟਾ ਰੰਗ</string>\n    <string name=\"invert_colors_sub\">ਜੇਕਰ ਸਮਰੱਥ ਹੋਵੇ ਤਾਂ ਥੀਮ ਦੇ ਰੰਗਾਂ ਨੂੰ ਨਕਾਰਾਤਮਕ ਰੰਗਾਂ ਨਾਲ ਬਦਲਦਾ ਹੈ</string>\n    <string name=\"search_option\">ਖੋਜ</string>\n    <string name=\"search_option_sub\">ਮੁੱਖ ਸਕ੍ਰੀਨ \\'ਤੇ ਉਪਲਬਧ ਸਾਰੇ ਵਿਕਲਪਾਂ ਰਾਹੀਂ ਖੋਜ ਕਰਨ ਦੀ ਸਮਰੱਥਾ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"pdf_tools\">PDF ਟੂਲ</string>\n    <string name=\"pdf_tools_sub\">PDF ਫਾਈਲਾਂ ਨਾਲ ਸੰਚਾਲਿਤ ਕਰੋ: ਪੂਰਵਦਰਸ਼ਨ ਕਰੋ, ਚਿੱਤਰਾਂ ਦੇ ਬੈਚ ਵਿੱਚ ਬਦਲੋ ਜਾਂ ਦਿੱਤੀਆਂ ਤਸਵੀਰਾਂ ਵਿੱਚੋਂ ਇੱਕ ਬਣਾਓ</string>\n    <string name=\"preview_pdf\">PDF ਦੀ ਝਲਕ</string>\n    <string name=\"pdf_to_images\">ਚਿੱਤਰਾਂ ਲਈ PDF</string>\n    <string name=\"images_to_pdf\">PDF ਲਈ ਚਿੱਤਰ</string>\n    <string name=\"preview_pdf_sub\">ਸਧਾਰਨ PDF ਝਲਕ</string>\n    <string name=\"pdf_to_images_sub\">ਦਿੱਤੇ ਆਉਟਪੁੱਟ ਫਾਰਮੈਟ ਵਿੱਚ PDF ਨੂੰ ਚਿੱਤਰਾਂ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"images_to_pdf_sub\">ਦਿੱਤੇ ਚਿੱਤਰਾਂ ਨੂੰ ਆਉਟਪੁੱਟ PDF ਫਾਈਲ ਵਿੱਚ ਪੈਕ ਕਰੋ</string>\n    <string name=\"mask_filter\">ਮਾਸਕ ਫਿਲਟਰ</string>\n    <string name=\"mask_filter_sub\">ਦਿੱਤੇ ਮਾਸਕ ਵਾਲੇ ਖੇਤਰਾਂ \\'ਤੇ ਫਿਲਟਰ ਚੇਨ ਲਗਾਓ, ਹਰੇਕ ਮਾਸਕ ਖੇਤਰ ਇਸ ਦੇ ਆਪਣੇ ਫਿਲਟਰਾਂ ਦੇ ਸੈੱਟ ਨੂੰ ਨਿਰਧਾਰਤ ਕਰ ਸਕਦਾ ਹੈ</string>\n    <string name=\"masks\">ਮਾਸਕ</string>\n    <string name=\"add_mask\">ਮਾਸਕ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"mask_indexed\">ਮਾਸਕ %d</string>\n    <string name=\"mask_color\">ਮਾਸਕ ਰੰਗ</string>\n    <string name=\"mask_preview\">ਮਾਸਕ ਪੂਰਵਦਰਸ਼ਨ</string>\n    <string name=\"mask_preview_sub\">ਤੁਹਾਨੂੰ ਅੰਦਾਜ਼ਨ ਨਤੀਜਾ ਦਿਖਾਉਣ ਲਈ ਖਿੱਚਿਆ ਫਿਲਟਰ ਮਾਸਕ ਰੈਂਡਰ ਕੀਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"inverse_fill_type\">ਉਲਟ ਭਰਨ ਦੀ ਕਿਸਮ</string>\n    <string name=\"inverse_fill_type_sub\">ਜੇਕਰ ਯੋਗ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਤਾਂ ਸਾਰੇ ਗੈਰ-ਮਾਸਕ ਕੀਤੇ ਖੇਤਰਾਂ ਨੂੰ ਡਿਫੌਲਟ ਵਿਵਹਾਰ ਦੀ ਬਜਾਏ ਫਿਲਟਰ ਕੀਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"delete_mask_warn\">ਤੁਸੀਂ ਚੁਣੇ ਹੋਏ ਫਿਲਟਰ ਮਾਸਕ ਨੂੰ ਮਿਟਾਉਣ ਲੱਗੇ ਹੋ। ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਅਣਕੀਤਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ</string>\n    <string name=\"delete_mask\">ਮਾਸਕ ਮਿਟਾਓ</string>\n    <string name=\"full_filter\">ਪੂਰਾ ਫਿਲਟਰ</string>\n    <string name=\"full_filter_sub\">ਦਿੱਤੇ ਚਿੱਤਰਾਂ ਜਾਂ ਸਿੰਗਲ ਚਿੱਤਰ \\'ਤੇ ਕੋਈ ਵੀ ਫਿਲਟਰ ਚੇਨ ਲਾਗੂ ਕਰੋ</string>\n    <string name=\"start_position\">ਸ਼ੁਰੂ ਕਰੋ</string>\n    <string name=\"center_position\">ਕੇਂਦਰ</string>\n    <string name=\"end_position\">ਅੰਤ</string>\n    <string name=\"simple_variants\">ਸਧਾਰਨ ਰੂਪ</string>\n    <string name=\"highlighter\">ਹਾਈਲਾਈਟਰ</string>\n    <string name=\"neon\">ਨਿਓਨ</string>\n    <string name=\"pen\">ਕਲਮ</string>\n    <string name=\"privacy_blur\">ਪਰਦੇਦਾਰੀ ਬਲਰ</string>\n    <string name=\"highlighter_sub\">ਅਰਧ-ਪਾਰਦਰਸ਼ੀ ਤਿੱਖੇ ਹਾਈਲਾਈਟਰ ਮਾਰਗ ਬਣਾਓ</string>\n    <string name=\"neon_sub\">ਆਪਣੀਆਂ ਡਰਾਇੰਗਾਂ ਵਿੱਚ ਕੁਝ ਚਮਕਦਾਰ ਪ੍ਰਭਾਵ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"pen_sub\">ਡਿਫੌਲਟ ਇੱਕ, ਸਰਲ - ਬਸ ਰੰਗ</string>\n    <string name=\"privacy_blur_sub\">ਜੋ ਵੀ ਤੁਸੀਂ ਲੁਕਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ ਉਸ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਖਿੱਚੇ ਗਏ ਮਾਰਗ ਦੇ ਹੇਠਾਂ ਚਿੱਤਰ ਨੂੰ ਬਲਰ ਕਰਦਾ ਹੈ</string>\n    <string name=\"pixelation_sub\">ਗੋਪਨੀਯਤਾ ਬਲਰ ਦੇ ਸਮਾਨ, ਪਰ ਧੁੰਦਲਾ ਕਰਨ ਦੀ ਬਜਾਏ ਪਿਕਸਲੇਟ</string>\n    <string name=\"containers_shadow\">ਕੰਟੇਨਰ</string>\n    <string name=\"containers_shadow_sub\">ਕੰਟੇਨਰਾਂ ਦੇ ਪਿੱਛੇ ਸ਼ੈਡੋ ਡਰਾਇੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"sliders_shadow\">ਸਲਾਈਡਰ</string>\n    <string name=\"switches_shadow\">ਸਵਿੱਚ</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">ਬਟਨ</string>\n    <string name=\"sliders_shadow_sub\">ਸਲਾਈਡਰਾਂ ਦੇ ਪਿੱਛੇ ਸ਼ੈਡੋ ਡਰਾਇੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"switches_shadow_sub\">ਸਵਿੱਚਾਂ ਦੇ ਪਿੱਛੇ ਸ਼ੈਡੋ ਡਰਾਇੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"fabs_shadow_sub\">ਫਲੋਟਿੰਗ ਐਕਸ਼ਨ ਬਟਨਾਂ ਦੇ ਪਿੱਛੇ ਸ਼ੈਡੋ ਡਰਾਇੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"buttons_shadow_sub\">ਡਿਫੌਲਟ ਬਟਨਾਂ ਦੇ ਪਿੱਛੇ ਸ਼ੈਡੋ ਡਰਾਇੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"app_bars_shadow\">ਐਪ ਬਾਰ</string>\n    <string name=\"app_bars_shadow_sub\">ਐਪ ਬਾਰਾਂ ਦੇ ਪਿੱਛੇ ਸ਼ੈਡੋ ਡਰਾਇੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"value_in_range\">ਰੇਂਜ %1$s - %2$s ਵਿੱਚ ਮੁੱਲ</string>\n    <string name=\"auto_rotate_limits\">ਆਟੋ ਘੁੰਮਾਓ</string>\n    <string name=\"auto_rotate_limits_sub\">ਚਿੱਤਰ ਸਥਿਤੀ ਲਈ ਸੀਮਾ ਬਾਕਸ ਨੂੰ ਅਪਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ</string>\n    <string name=\"draw_path_mode\">ਪਾਥ ਮੋਡ ਬਣਾਓ</string>\n    <string name=\"double_line_arrow\">ਡਬਲ ਲਾਈਨ ਐਰੋ</string>\n    <string name=\"free_drawing\">ਮੁਫਤ ਡਰਾਇੰਗ</string>\n    <string name=\"double_arrow\">ਡਬਲ ਤੀਰ</string>\n    <string name=\"line_arrow\">ਰੇਖਾ ਤੀਰ</string>\n    <string name=\"arrow\">ਤੀਰ</string>\n    <string name=\"line\">ਲਾਈਨ</string>\n    <string name=\"free_drawing_sub\">ਪਾਥ ਨੂੰ ਇਨਪੁਟ ਮੁੱਲ ਦੇ ਤੌਰ \\'ਤੇ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"line_sub\">ਇੱਕ ਲਾਈਨ ਦੇ ਰੂਪ ਵਿੱਚ ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਮਾਰਗ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"line_arrow_sub\">ਇੱਕ ਲਾਈਨ ਦੇ ਰੂਪ ਵਿੱਚ ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਪੁਆਇੰਟਿੰਗ ਤੀਰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"arrow_sub\">ਦਿੱਤੇ ਮਾਰਗ ਤੋਂ ਪੁਆਇੰਟਿੰਗ ਤੀਰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"double_line_arrow_sub\">ਇੱਕ ਲਾਈਨ ਦੇ ਰੂਪ ਵਿੱਚ ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਡਬਲ ਪੁਆਇੰਟਿੰਗ ਤੀਰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"double_arrow_sub\">ਦਿੱਤੇ ਮਾਰਗ ਤੋਂ ਡਬਲ ਪੁਆਇੰਟਿੰਗ ਤੀਰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"outlined_oval\">ਰੂਪਰੇਖਾ ਓਵਲ</string>\n    <string name=\"outlined_rect\">ਰੂਪਰੇਖਾ Rect</string>\n    <string name=\"oval\">ਓਵਲ</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਰੇਕਟ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"oval_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਅੰਡਾਕਾਰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"outlined_oval_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਰੂਪਰੇਖਾ ਅੰਡਾਕਾਰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"outlined_rect_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਬਾਹਰੀ ਰੇਕਟ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"lasso\">ਲੱਸੋ</string>\n    <string name=\"lasso_sub\">ਦਿੱਤੇ ਮਾਰਗ ਦੁਆਰਾ ਬੰਦ ਭਰੇ ਮਾਰਗ ਨੂੰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"free\">ਮੁਫ਼ਤ</string>\n    <string name=\"horizontal_grid\">ਹਰੀਜ਼ੱਟਲ ਗਰਿੱਡ</string>\n    <string name=\"vertical_grid\">ਵਰਟੀਕਲ ਗਰਿੱਡ</string>\n    <string name=\"stitch_mode\">ਸਟੀਚ ਮੋਡ</string>\n    <string name=\"rows_count\">ਕਤਾਰਾਂ ਦੀ ਗਿਣਤੀ</string>\n    <string name=\"columns_count\">ਕਾਲਮਾਂ ਦੀ ਗਿਣਤੀ</string>\n    <string name=\"no_such_directory\">ਕੋਈ \\\"%1$s\\\" ਡਾਇਰੈਕਟਰੀ ਨਹੀਂ ਮਿਲੀ, ਅਸੀਂ ਇਸਨੂੰ ਡਿਫੌਲਟ ਇੱਕ ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਫਾਈਲ ਨੂੰ ਦੁਬਾਰਾ ਸੁਰੱਖਿਅਤ ਕਰੋ</string>\n    <string name=\"clipboard\">ਕਲਿੱਪਬੋਰਡ</string>\n    <string name=\"auto_pin\">ਆਟੋ ਪਿੰਨ</string>\n    <string name=\"auto_pin_sub\">ਜੇਕਰ ਸਮਰਥਿਤ ਹੋਵੇ ਤਾਂ ਸਵੈਚਲਿਤ ਤੌਰ \\'ਤੇ ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਚਿੱਤਰ ਸ਼ਾਮਲ ਕਰਦਾ ਹੈ</string>\n    <string name=\"vibration\">ਵਾਈਬ੍ਰੇਸ਼ਨ</string>\n    <string name=\"vibration_strength\">ਵਾਈਬ੍ਰੇਸ਼ਨ ਤਾਕਤ</string>\n    <string name=\"overwrite_file_requirements\">ਫਾਈਲਾਂ ਨੂੰ ਓਵਰਰਾਈਟ ਕਰਨ ਲਈ ਤੁਹਾਨੂੰ \\\"ਐਕਸਪਲੋਰਰ\\\" ਚਿੱਤਰ ਸਰੋਤ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ, ਚਿੱਤਰਾਂ ਨੂੰ ਰੀਪਿਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ, ਅਸੀਂ ਚਿੱਤਰ ਸਰੋਤ ਨੂੰ ਲੋੜੀਂਦੇ ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ ਹੈ</string>\n    <string name=\"overwrite_files\">ਫਾਈਲਾਂ ਨੂੰ ਓਵਰਰਾਈਟ ਕਰੋ</string>\n    <string name=\"overwrite_files_sub\">ਮੂਲ ਫਾਈਲ ਨੂੰ ਚੁਣੇ ਹੋਏ ਫੋਲਡਰ ਵਿੱਚ ਸੇਵ ਕਰਨ ਦੀ ਬਜਾਏ ਨਵੀਂ ਨਾਲ ਬਦਲ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਇਸ ਵਿਕਲਪ ਨੂੰ ਚਿੱਤਰ ਸਰੋਤ \\\"ਐਕਸਪਲੋਰਰ\\\" ਜਾਂ GetContent ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, ਜਦੋਂ ਇਸਨੂੰ ਟੌਗਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਇਹ ਆਪਣੇ ਆਪ ਸੈੱਟ ਹੋ ਜਾਵੇਗਾ</string>\n    <string name=\"empty\">ਖਾਲੀ</string>\n    <string name=\"suffix\">ਪਿਛੇਤਰ</string>\n    <string name=\"scale_mode\">ਸਕੇਲ ਮੋਡ</string>\n    <string name=\"bilinear\">ਦੋਲੀਨੀਅਰ</string>\n    <string name=\"catmull\">ਕੈਟਮੁਲ</string>\n    <string name=\"bicubic\">ਬਾਈਕੂਬਿਕ</string>\n    <string name=\"hann\">ਹੈਨ</string>\n    <string name=\"hermite\">ਹਰਮਾਈਟ</string>\n    <string name=\"lanczos\">ਲੈਂਕਜ਼ੋਸ</string>\n    <string name=\"mitchell\">ਮਿਸ਼ੇਲ</string>\n    <string name=\"nearest\">ਨਜ਼ਦੀਕੀ</string>\n    <string name=\"spline\">ਸਪਲਾਈਨ</string>\n    <string name=\"basic\">ਮੂਲ</string>\n    <string name=\"default_value\">ਪੂਰਵ-ਨਿਰਧਾਰਤ ਮੁੱਲ</string>\n    <string name=\"bilinear_sub\">ਰੇਖਿਕ (ਜਾਂ ਦੋ-ਲੀਨੀਅਰ, ਦੋ ਅਯਾਮਾਂ ਵਿੱਚ) ਇੰਟਰਪੋਲੇਸ਼ਨ ਇੱਕ ਚਿੱਤਰ ਦੇ ਆਕਾਰ ਨੂੰ ਬਦਲਣ ਲਈ ਆਮ ਤੌਰ \\'ਤੇ ਵਧੀਆ ਹੁੰਦਾ ਹੈ, ਪਰ ਵੇਰਵਿਆਂ ਦੇ ਕੁਝ ਅਣਚਾਹੇ ਨਰਮ ਹੋਣ ਦਾ ਕਾਰਨ ਬਣਦਾ ਹੈ ਅਤੇ ਅਜੇ ਵੀ ਕੁਝ ਹੱਦ ਤੱਕ ਜਾਗਡ ਹੋ ਸਕਦਾ ਹੈ।</string>\n    <string name=\"bicubic_sub\">ਬਿਹਤਰ ਸਕੇਲਿੰਗ ਵਿਧੀਆਂ ਵਿੱਚ ਲੈਂਕਜ਼ੋਸ ਰੀਸੈਪਲਿੰਗ ਅਤੇ ਮਿਸ਼ੇਲ-ਨੇਤਰਾਵਲੀ ਫਿਲਟਰ ਸ਼ਾਮਲ ਹਨ।</string>\n    <string name=\"nearest_sub\">ਆਕਾਰ ਵਧਾਉਣ ਦਾ ਇੱਕ ਸਰਲ ਤਰੀਕਾ, ਹਰੇਕ ਪਿਕਸਲ ਨੂੰ ਇੱਕੋ ਰੰਗ ਦੇ ਕਈ ਪਿਕਸਲਾਂ ਨਾਲ ਬਦਲਣਾ</string>\n    <string name=\"basic_sub\">ਸਭ ਤੋਂ ਸਰਲ ਐਂਡਰਾਇਡ ਸਕੇਲਿੰਗ ਮੋਡ ਜੋ ਲਗਭਗ ਸਾਰੀਆਂ ਐਪਾਂ ਵਿੱਚ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ</string>\n    <string name=\"catmull_sub\">ਨਿਯੰਤਰਣ ਬਿੰਦੂਆਂ ਦੇ ਇੱਕ ਸਮੂਹ ਨੂੰ ਸੁਚਾਰੂ ਰੂਪ ਵਿੱਚ ਇੰਟਰਪੋਲੇਟ ਕਰਨ ਅਤੇ ਦੁਬਾਰਾ ਨਮੂਨੇ ਬਣਾਉਣ ਲਈ ਵਿਧੀ, ਆਮ ਤੌਰ \\'ਤੇ ਨਿਰਵਿਘਨ ਕਰਵ ਬਣਾਉਣ ਲਈ ਕੰਪਿਊਟਰ ਗ੍ਰਾਫਿਕਸ ਵਿੱਚ ਵਰਤੀ ਜਾਂਦੀ ਹੈ।</string>\n    <string name=\"hann_sub\">ਵਿੰਡੋਿੰਗ ਫੰਕਸ਼ਨ ਅਕਸਰ ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਨੂੰ ਘੱਟ ਕਰਨ ਅਤੇ ਸਿਗਨਲ ਦੇ ਕਿਨਾਰਿਆਂ ਨੂੰ ਟੇਪਰ ਕਰਕੇ ਬਾਰੰਬਾਰਤਾ ਵਿਸ਼ਲੇਸ਼ਣ ਦੀ ਸ਼ੁੱਧਤਾ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਵਿੱਚ ਲਾਗੂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।</string>\n    <string name=\"hermite_sub\">ਗਣਿਤਿਕ ਇੰਟਰਪੋਲੇਸ਼ਨ ਤਕਨੀਕ ਜੋ ਇੱਕ ਨਿਰਵਿਘਨ ਅਤੇ ਨਿਰੰਤਰ ਕਰਵ ਬਣਾਉਣ ਲਈ ਇੱਕ ਕਰਵ ਹਿੱਸੇ ਦੇ ਅੰਤਮ ਬਿੰਦੂਆਂ \\'ਤੇ ਮੁੱਲਾਂ ਅਤੇ ਡੈਰੀਵੇਟਿਵਜ਼ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ</string>\n    <string name=\"lanczos_sub\">ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਪਿਕਸਲ ਮੁੱਲਾਂ \\'ਤੇ ਭਾਰ ਵਾਲੇ sinc ਫੰਕਸ਼ਨ ਨੂੰ ਲਾਗੂ ਕਰਕੇ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਨੂੰ ਕਾਇਮ ਰੱਖਦੀ ਹੈ</string>\n    <string name=\"mitchell_sub\">ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਸਕੇਲ ਕੀਤੇ ਚਿੱਤਰ ਵਿੱਚ ਤਿੱਖਾਪਨ ਅਤੇ ਐਂਟੀ-ਅਲਾਈਜ਼ਿੰਗ ਵਿਚਕਾਰ ਸੰਤੁਲਨ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਵਿਵਸਥਿਤ ਪੈਰਾਮੀਟਰਾਂ ਦੇ ਨਾਲ ਇੱਕ ਕਨਵੋਲਿਊਸ਼ਨ ਫਿਲਟਰ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ</string>\n    <string name=\"spline_sub\">ਇੱਕ ਵਕਰ ਜਾਂ ਸਤਹ, ਲਚਕਦਾਰ ਅਤੇ ਨਿਰੰਤਰ ਸ਼ਕਲ ਦੀ ਨੁਮਾਇੰਦਗੀ ਨੂੰ ਸੁਚਾਰੂ ਰੂਪ ਵਿੱਚ ਇੰਟਰਪੋਲੇਟ ਕਰਨ ਅਤੇ ਅਨੁਮਾਨਿਤ ਕਰਨ ਲਈ ਟੁਕੜੇ-ਵਾਰ-ਪਰਿਭਾਸ਼ਿਤ ਬਹੁਪਦ ਫੰਕਸ਼ਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"only_clip\">ਸਿਰਫ਼ ਕਲਿੱਪ</string>\n    <string name=\"only_clip_sub\">ਸਟੋਰੇਜ ਵਿੱਚ ਸੇਵ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ, ਅਤੇ ਚਿੱਤਰ ਨੂੰ ਸਿਰਫ਼ ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ ਪਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਜਾਵੇਗੀ</string>\n    <string name=\"restore_background_sub\">ਬੁਰਸ਼ ਮਿਟਾਉਣ ਦੀ ਬਜਾਏ ਪਿਛੋਕੜ ਨੂੰ ਬਹਾਲ ਕਰੇਗਾ</string>\n    <string name=\"recognize_text\">OCR (ਟੈਕਸਟ ਪਛਾਣੋ)</string>\n    <string name=\"recognize_text_sub\">ਦਿੱਤੇ ਚਿੱਤਰ ਤੋਂ ਟੈਕਸਟ ਨੂੰ ਪਛਾਣੋ, 120+ ਭਾਸ਼ਾਵਾਂ ਸਮਰਥਿਤ ਹਨ</string>\n    <string name=\"picture_has_no_text\">ਤਸਵੀਰ ਵਿੱਚ ਕੋਈ ਟੈਕਸਟ ਨਹੀਂ ਹੈ, ਜਾਂ ਐਪ ਨੇ ਇਸਨੂੰ ਨਹੀਂ ਲੱਭਿਆ</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">ਪਛਾਣ ਦੀ ਕਿਸਮ</string>\n    <string name=\"fast\">ਤੇਜ਼</string>\n    <string name=\"standard\">ਮਿਆਰੀ</string>\n    <string name=\"best\">ਵਧੀਆ</string>\n    <string name=\"no_data\">ਕੋਈ ਡਾਟਾ ਨਹੀਂ</string>\n    <string name=\"download_description\">Tesseract OCR ਦੇ ਸਹੀ ਕੰਮ ਕਰਨ ਲਈ ਵਾਧੂ ਸਿਖਲਾਈ ਡੇਟਾ (%1$s) ਨੂੰ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਡਾਊਨਲੋਡ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।\\nਕੀ ਤੁਸੀਂ %2$s ਡੇਟਾ ਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?</string>\n    <string name=\"download\">ਡਾਊਨਲੋਡ ਕਰੋ</string>\n    <string name=\"no_connection\">ਕੋਈ ਕਨੈਕਸ਼ਨ ਨਹੀਂ ਹੈ, ਇਸਦੀ ਜਾਂਚ ਕਰੋ ਅਤੇ ਟ੍ਰੇਨ ਮਾਡਲਾਂ ਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ</string>\n    <string name=\"downloaded_languages\">ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਭਾਸ਼ਾਵਾਂ</string>\n    <string name=\"available_languages\">ਉਪਲਬਧ ਭਾਸ਼ਾਵਾਂ</string>\n    <string name=\"segmentation_mode\">ਵਿਭਾਜਨ ਮੋਡ</string>\n    <string name=\"use_pixel_switch\">Pixel ਸਵਿੱਚ ਵਰਤੋ</string>\n    <string name=\"use_pixel_switch_sub\">ਤੁਹਾਡੇ ਦੁਆਰਾ ਆਧਾਰਿਤ ਗੂਗਲ ਦੀ ਸਮੱਗਰੀ ਦੀ ਬਜਾਏ ਪਿਕਸਲ ਵਰਗਾ ਸਵਿੱਚ ਵਰਤਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"saved_to_original\">ਮੂਲ ਮੰਜ਼ਿਲ \\'ਤੇ ਨਾਮ %1$s ਨਾਲ ਓਵਰਰਾਈਟ ਕੀਤੀ ਫਾਈਲ</string>\n    <string name=\"magnifier\">ਵੱਡਦਰਸ਼ੀ</string>\n    <string name=\"magnifier_sub\">ਬਿਹਤਰ ਪਹੁੰਚਯੋਗਤਾ ਲਈ ਡਰਾਇੰਗ ਮੋਡਾਂ ਵਿੱਚ ਉਂਗਲੀ ਦੇ ਸਿਖਰ \\'ਤੇ ਵੱਡਦਰਸ਼ੀ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"force_exif_widget_initial_value\">ਸ਼ੁਰੂਆਤੀ ਮੁੱਲ ਨੂੰ ਜ਼ੋਰ ਦਿਓ</string>\n    <string name=\"force_exif_widget_initial_value_sub\">ਸ਼ੁਰੂਆਤੀ ਤੌਰ \\'ਤੇ exif ਵਿਜੇਟ ਦੀ ਜਾਂਚ ਕਰਨ ਲਈ ਮਜ਼ਬੂਰ ਕਰਦਾ ਹੈ</string>\n    <string name=\"allow_multiple_languages\">ਕਈ ਭਾਸ਼ਾਵਾਂ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ</string>\n    <string name=\"slide\">ਸਲਾਈਡ</string>\n    <string name=\"side_by_side\">ਨਾਲ ਨਾਲ</string>\n    <string name=\"toggle_tap\">ਟੈਪ ਟੌਗਲ ਕਰੋ</string>\n    <string name=\"transparency\">ਪਾਰਦਰਸ਼ਤਾ</string>\n    <string name=\"rate_app\">ਐਪ ਨੂੰ ਰੇਟ ਕਰੋ</string>\n    <string name=\"rate\">ਦਰ</string>\n    <string name=\"rate_app_sub\">ਇਹ ਐਪ ਪੂਰੀ ਤਰ੍ਹਾਂ ਮੁਫਤ ਹੈ, ਜੇਕਰ ਤੁਸੀਂ ਇਸ ਨੂੰ ਵੱਡਾ ਬਣਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਕਿਰਪਾ ਕਰਕੇ Github \\'ਤੇ ਪ੍ਰੋਜੈਕਟ ਨੂੰ ਸਟਾਰ ਕਰੋ 😄</string>\n    <string name=\"segmentation_mode_osd_only\">ਓਰੀਐਂਟੇਸ਼ਨ &amp; ਸਿਰਫ਼ ਸਕ੍ਰਿਪਟ ਖੋਜ</string>\n    <string name=\"segmentation_mode_auto_osd\">ਆਟੋ ਓਰੀਐਂਟੇਸ਼ਨ &amp; ਸਕ੍ਰਿਪਟ ਖੋਜ</string>\n    <string name=\"segmentation_mode_auto_only\">ਸਿਰਫ਼ ਆਟੋ</string>\n    <string name=\"segmentation_mode_auto\">ਆਟੋ</string>\n    <string name=\"segmentation_mode_single_column\">ਸਿੰਗਲ ਕਾਲਮ</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">ਸਿੰਗਲ ਬਲਾਕ ਵਰਟੀਕਲ ਟੈਕਸਟ</string>\n    <string name=\"segmentation_mode_single_block\">ਸਿੰਗਲ ਬਲਾਕ</string>\n    <string name=\"segmentation_mode_single_line\">ਸਿੰਗਲ ਲਾਈਨ</string>\n    <string name=\"segmentation_mode_single_word\">ਇੱਕ ਸ਼ਬਦ</string>\n    <string name=\"segmentation_mode_circle_word\">ਚੱਕਰ ਸ਼ਬਦ</string>\n    <string name=\"segmentation_mode_single_char\">ਸਿੰਗਲ ਅੱਖਰ</string>\n    <string name=\"segmentation_mode_sparse_text\">ਸਪਾਰਸ ਟੈਕਸਟ</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">ਸਪਾਰਸ ਟੈਕਸਟ ਓਰੀਐਂਟੇਸ਼ਨ &amp; ਸਕ੍ਰਿਪਟ ਖੋਜ</string>\n    <string name=\"segmentation_mode_raw_line\">ਕੱਚੀ ਲਾਈਨ</string>\n    <string name=\"delete_language_sub\">ਕੀ ਤੁਸੀਂ ਸਾਰੀਆਂ ਮਾਨਤਾ ਕਿਸਮਾਂ ਲਈ ਭਾਸ਼ਾ \\\"%1$s\\\" OCR ਸਿਖਲਾਈ ਡੇਟਾ ਨੂੰ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ, ਜਾਂ ਸਿਰਫ਼ ਇੱਕ ਚੁਣੀ ਹੋਈ (%2$s) ਲਈ?</string>\n    <string name=\"current\">ਵਰਤਮਾਨ</string>\n    <string name=\"all\">ਸਾਰੇ</string>\n    <string name=\"gradient_maker\">ਗਰੇਡੀਐਂਟ ਮੇਕਰ</string>\n    <string name=\"gradient_maker_sub\">ਕਸਟਮਾਈਜ਼ਡ ਰੰਗਾਂ ਅਤੇ ਦਿੱਖ ਕਿਸਮ ਦੇ ਨਾਲ ਦਿੱਤੇ ਆਉਟਪੁੱਟ ਆਕਾਰ ਦਾ ਗਰੇਡੀਐਂਟ ਬਣਾਓ</string>\n    <string name=\"gradient_type_linear\">ਰੇਖਿਕ</string>\n    <string name=\"gradient_type_radial\">ਰੇਡੀਅਲ</string>\n    <string name=\"gradient_type_sweep\">ਸਵੀਪ ਕਰੋ</string>\n    <string name=\"gradient_type\">ਗਰੇਡੀਐਂਟ ਕਿਸਮ</string>\n    <string name=\"center_x\">ਸੈਂਟਰ ਐਕਸ</string>\n    <string name=\"center_y\">ਸੈਂਟਰ ਵਾਈ</string>\n    <string name=\"tile_mode\">ਟਾਇਲ ਮੋਡ</string>\n    <string name=\"tile_mode_repeated\">ਦੁਹਰਾਇਆ</string>\n    <string name=\"tile_mode_mirror\">ਮਿਰਰ</string>\n    <string name=\"tile_mode_clamp\">ਕਲੈਂਪ</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"color_stops\">ਰੰਗ ਸਟਾਪ</string>\n    <string name=\"add_color\">ਰੰਗ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"properties\">ਗੁਣ</string>\n    <string name=\"brightness_enforcement\">ਚਮਕ ਲਾਗੂ ਕਰਨਾ</string>\n    <string name=\"screen\">ਸਕਰੀਨ</string>\n    <string name=\"gradient_maker_type_image\">ਗਰੇਡੀਐਂਟ ਓਵਰਲੇ</string>\n    <string name=\"gradient_maker_type_image_sub\">ਦਿੱਤੇ ਚਿੱਤਰ ਦੇ ਸਿਖਰ ਦਾ ਕੋਈ ਵੀ ਗਰੇਡੀਐਂਟ ਲਿਖੋ</string>\n    <string name=\"transformations\">ਪਰਿਵਰਤਨ</string>\n    <string name=\"camera\">ਕੈਮਰਾ</string>\n    <string name=\"camera_sub\">ਤਸਵੀਰ ਲੈਣ ਲਈ ਕੈਮਰੇ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਧਿਆਨ ਦਿਓ ਕਿ ਇਸ ਚਿੱਤਰ ਸਰੋਤ ਤੋਂ ਸਿਰਫ ਇੱਕ ਚਿੱਤਰ ਪ੍ਰਾਪਤ ਕਰਨਾ ਸੰਭਵ ਹੈ</string>\n    <string name=\"watermarking\">ਵਾਟਰਮਾਰਕਿੰਗ</string>\n    <string name=\"watermarking_sub\">ਅਨੁਕੂਲਿਤ ਟੈਕਸਟ/ਚਿੱਤਰ ਵਾਟਰਮਾਰਕਸ ਨਾਲ ਤਸਵੀਰਾਂ ਨੂੰ ਕਵਰ ਕਰੋ</string>\n    <string name=\"repeat_watermark\">ਵਾਟਰਮਾਰਕ ਨੂੰ ਦੁਹਰਾਓ</string>\n    <string name=\"repeat_watermark_sub\">ਦਿੱਤੀ ਸਥਿਤੀ \\'ਤੇ ਸਿੰਗਲ ਦੀ ਬਜਾਏ ਚਿੱਤਰ ਉੱਤੇ ਵਾਟਰਮਾਰਕ ਨੂੰ ਦੁਹਰਾਓ</string>\n    <string name=\"offset_x\">ਆਫਸੈੱਟ ਐਕਸ</string>\n    <string name=\"offset_y\">ਆਫਸੈੱਟ ਵਾਈ</string>\n    <string name=\"watermark_type\">ਵਾਟਰਮਾਰਕ ਦੀ ਕਿਸਮ</string>\n    <string name=\"watermarking_image_sub\">ਇਹ ਚਿੱਤਰ ਵਾਟਰਮਾਰਕਿੰਗ ਲਈ ਪੈਟਰਨ ਵਜੋਂ ਵਰਤਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"text_color\">ਟੈਕਸਟ ਰੰਗ</string>\n    <string name=\"overlay_mode\">ਓਵਰਲੇ ਮੋਡ</string>\n    <string name=\"gif_tools\">GIF ਟੂਲ</string>\n    <string name=\"gif_tools_sub\">ਚਿੱਤਰਾਂ ਨੂੰ GIF ਤਸਵੀਰ ਵਿੱਚ ਬਦਲੋ ਜਾਂ ਦਿੱਤੇ GIF ਚਿੱਤਰ ਤੋਂ ਫਰੇਮਾਂ ਨੂੰ ਐਕਸਟਰੈਕਟ ਕਰੋ</string>\n    <string name=\"gif_type_to_image\">ਚਿੱਤਰਾਂ ਲਈ GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF ਫਾਈਲ ਨੂੰ ਤਸਵੀਰਾਂ ਦੇ ਬੈਚ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"gif_type_to_gif_sub\">ਚਿੱਤਰਾਂ ਦੇ ਬੈਚ ਨੂੰ GIF ਫਾਈਲ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"gif_type_to_gif\">GIF ਲਈ ਚਿੱਤਰ</string>\n    <string name=\"select_gif_image_to_start\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ GIF ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"use_size_of_first_frame\">ਪਹਿਲੇ ਫਰੇਮ ਦਾ ਆਕਾਰ ਵਰਤੋ</string>\n    <string name=\"use_size_of_first_frame_sub\">ਨਿਰਧਾਰਤ ਆਕਾਰ ਨੂੰ ਪਹਿਲੇ ਫਰੇਮ ਮਾਪਾਂ ਨਾਲ ਬਦਲੋ</string>\n    <string name=\"repeat_count\">ਦੁਹਰਾਓ ਗਿਣਤੀ</string>\n    <string name=\"frame_delay\">ਫਰੇਮ ਦੇਰੀ</string>\n    <string name=\"millis\">ਮਿਲੀਸ</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">ਲੱਸੋ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"use_lasso_sub\">ਮਿਟਾਉਣ ਲਈ ਡਰਾਇੰਗ ਮੋਡ ਵਿੱਚ ਲਾਸੋ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"original_image_preview_alpha\">ਅਸਲ ਚਿੱਤਰ ਪ੍ਰੀਵਿਊ ਅਲਫ਼ਾ</string>\n    <string name=\"confetti\">ਕੰਫੇਟੀ</string>\n    <string name=\"confetti_sub\">ਕਨਫੇਟੀ ਨੂੰ ਸੇਵਿੰਗ, ਸ਼ੇਅਰਿੰਗ ਅਤੇ ਹੋਰ ਪ੍ਰਾਇਮਰੀ ਐਕਸ਼ਨ \\'ਤੇ ਦਿਖਾਇਆ ਜਾਵੇਗਾ</string>\n    <string name=\"secure_mode\">ਸੁਰੱਖਿਅਤ ਮੋਡ</string>\n    <string name=\"secure_mode_sub\">ਬਾਹਰ ਜਾਣ \\'ਤੇ ਸਮਗਰੀ ਨੂੰ ਲੁਕਾਉਂਦਾ ਹੈ, ਨਾਲ ਹੀ ਸਕ੍ਰੀਨ ਨੂੰ ਕੈਪਚਰ ਜਾਂ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ</string>\n    <string name=\"exit\">ਨਿਕਾਸ</string>\n    <string name=\"preview_closing\">ਜੇਕਰ ਤੁਸੀਂ ਹੁਣੇ ਪੂਰਵਦਰਸ਼ਨ ਛੱਡ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਦੁਬਾਰਾ ਚਿੱਤਰ ਜੋੜਨ ਦੀ ਲੋੜ ਪਵੇਗੀ</string>\n    <string name=\"dithering\">ਡਿਥਰਿੰਗ</string>\n    <string name=\"quantizier\">ਕੁਆਂਟਿਜ਼ੀਅਰ</string>\n    <string name=\"gray_scale\">ਸਲੇਟੀ ਸਕੇਲ</string>\n    <string name=\"bayer_two_dithering\">ਬੇਅਰ ਟੂ ਬਾਈ ਟੂ ਡਿਥਰਿੰਗ</string>\n    <string name=\"bayer_three_dithering\">ਬੇਅਰ ਥ੍ਰੀ ਬਾਈ ਥ੍ਰੀ ਡਿਥਰਿੰਗ</string>\n    <string name=\"bayer_four_dithering\">ਬੇਅਰ ਫੋਰ ਬਾਈ ਫੋਰ ਡਿਥਰਿੰਗ</string>\n    <string name=\"bayer_eight_dithering\">ਬੇਅਰ ਅੱਠ ਦੁਆਰਾ ਅੱਠ ਡਿਥਰਿੰਗ</string>\n    <string name=\"floyd_steinberg_dithering\">ਫਲੋਇਡ ਸਟੀਨਬਰਗ ਡਿਥਰਿੰਗ</string>\n    <string name=\"jarvis_judice_ninke_dithering\">ਜਾਰਵਿਸ ਜੁਡੀਸ ਨਿੰਕੇ ਡਿਥਰਿੰਗ</string>\n    <string name=\"sierra_dithering\">ਸੀਅਰਾ ਡਿਥਰਿੰਗ</string>\n    <string name=\"two_row_sierra_dithering\">ਦੋ ਕਤਾਰ ਸੀਅਰਾ ਡਿਥਰਿੰਗ</string>\n    <string name=\"sierra_lite_dithering\">ਸੀਅਰਾ ਲਾਈਟ ਡਿਥਰਿੰਗ</string>\n    <string name=\"atkinson_dithering\">ਐਟਕਿੰਸਨ ਡਿਥਰਿੰਗ</string>\n    <string name=\"stucki_dithering\">ਸਟਕੀ ਡਿਥਰਿੰਗ</string>\n    <string name=\"burkes_dithering\">ਬਰਕਸ ਡਿਥਰਿੰਗ</string>\n    <string name=\"false_floyd_steinberg_dithering\">ਝੂਠੇ ਫਲੋਇਡ ਸਟੀਨਬਰਗ ਡਿਥਰਿੰਗ</string>\n    <string name=\"left_to_right_dithering\">ਖੱਬੇ ਤੋਂ ਸੱਜੇ ਡਿਥਰਿੰਗ</string>\n    <string name=\"random_dithering\">ਰੈਂਡਮ ਡਿਥਰਿੰਗ</string>\n    <string name=\"simple_threshold_dithering\">ਸਧਾਰਨ ਥ੍ਰੈਸ਼ਹੋਲਡ ਡਿਥਰਿੰਗ</string>\n    <string name=\"sigma\">ਸਿਗਮਾ</string>\n    <string name=\"spatial_sigma\">ਸਥਾਨਿਕ ਸਿਗਮਾ</string>\n    <string name=\"median_blur\">ਮੱਧਮ ਬਲਰ</string>\n    <string name=\"b_spline\">ਬੀ ਸਪਲਾਈਨ</string>\n    <string name=\"b_spline_sub\">ਇੱਕ ਵਕਰ ਜਾਂ ਸਤਹ, ਲਚਕਦਾਰ ਅਤੇ ਨਿਰੰਤਰ ਸ਼ਕਲ ਦੀ ਨੁਮਾਇੰਦਗੀ ਨੂੰ ਸੁਚਾਰੂ ਰੂਪ ਵਿੱਚ ਇੰਟਰਪੋਲੇਟ ਕਰਨ ਅਤੇ ਅਨੁਮਾਨਿਤ ਕਰਨ ਲਈ ਟੁਕੜੇ-ਵਾਰ-ਪਰਿਭਾਸ਼ਿਤ ਬਾਈਕਿਊਬਿਕ ਪੌਲੀਨੋਮੀਅਲ ਫੰਕਸ਼ਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"native_stack_blur\">ਨੇਟਿਵ ਸਟੈਕ ਬਲਰ</string>\n    <string name=\"tilt_shift\">ਟਿਲਟ ਸ਼ਿਫਟ</string>\n    <string name=\"glitch\">ਗਲਚ</string>\n    <string name=\"amount\">ਦੀ ਰਕਮ</string>\n    <string name=\"seed\">ਬੀਜ</string>\n    <string name=\"anaglyph\">ਐਨਾਗਲਿਫ</string>\n    <string name=\"noise\">ਰੌਲਾ</string>\n    <string name=\"pixel_sort\">ਪਿਕਸਲ ਲੜੀਬੱਧ</string>\n    <string name=\"shuffle\">ਸ਼ਫਲ</string>\n    <string name=\"enhanced_glitch\">ਵਧੀ ਹੋਈ ਗੜਬੜ</string>\n    <string name=\"channel_shift_x\">ਚੈਨਲ ਸ਼ਿਫਟ ਐਕਸ</string>\n    <string name=\"channel_shift_y\">ਚੈਨਲ ਸ਼ਿਫਟ ਵਾਈ</string>\n    <string name=\"corruption_size\">ਭ੍ਰਿਸ਼ਟਾਚਾਰ ਦਾ ਆਕਾਰ</string>\n    <string name=\"corruption_shift_x\">ਭ੍ਰਿਸ਼ਟਾਚਾਰ ਸ਼ਿਫਟ ਐਕਸ</string>\n    <string name=\"corruption_shift_y\">ਭ੍ਰਿਸ਼ਟਾਚਾਰ ਸ਼ਿਫਟ ਵਾਈ</string>\n    <string name=\"tent_blur\">ਟੈਂਟ ਬਲਰ</string>\n    <string name=\"side_fade\">ਪਾਸੇ ਫੇਡ</string>\n    <string name=\"side\">ਪਾਸੇ</string>\n    <string name=\"top\">ਸਿਖਰ</string>\n    <string name=\"bottom\">ਥੱਲੇ</string>\n    <string name=\"strength\">ਤਾਕਤ</string>\n    <string name=\"erode\">ਇਰੋਡ</string>\n    <string name=\"anisotropic_diffusion\">ਐਨੀਸੋਟ੍ਰੋਪਿਕ ਫੈਲਾਅ</string>\n    <string name=\"diffusion\">ਫੈਲਾ</string>\n    <string name=\"conduction\">ਸੰਚਾਲਨ</string>\n    <string name=\"horizontal_wind_stagger\">ਹਰੀਜ਼ੱਟਲ ਵਿੰਡ ਸਟੈਗਰ</string>\n    <string name=\"fast_bilaterial_blur\">ਤੇਜ਼ ਦੁਵੱਲੀ ਬਲਰ</string>\n    <string name=\"poisson_blur\">ਪੋਇਸਨ ਬਲਰ</string>\n    <string name=\"logarithmic_tone_mapping\">ਲੋਗਾਰਿਦਮਿਕ ਟੋਨ ਮੈਪਿੰਗ</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES ਫਿਲਮਿਕ ਟੋਨ ਮੈਪਿੰਗ</string>\n    <string name=\"crystallize\">ਕ੍ਰਿਸਟਾਲਾਈਜ਼</string>\n    <string name=\"stroke_color\">ਸਟ੍ਰੋਕ ਰੰਗ</string>\n    <string name=\"fractal_glass\">ਫ੍ਰੈਕਟਲ ਗਲਾਸ</string>\n    <string name=\"amplitude\">ਐਪਲੀਟਿਊਡ</string>\n    <string name=\"marble\">ਮਾਰਬਲ</string>\n    <string name=\"turbulence\">ਗੜਬੜ</string>\n    <string name=\"oil\">ਤੇਲ</string>\n    <string name=\"water_effect\">ਪਾਣੀ ਦਾ ਪ੍ਰਭਾਵ</string>\n    <string name=\"just_size\">ਆਕਾਰ</string>\n    <string name=\"frequency_x\">ਬਾਰੰਬਾਰਤਾ ਐਕਸ</string>\n    <string name=\"frequency_y\">ਬਾਰੰਬਾਰਤਾ ਵਾਈ</string>\n    <string name=\"amplitude_x\">ਐਪਲੀਟਿਊਡ ਐਕਸ</string>\n    <string name=\"amplitude_y\">ਐਪਲੀਟਿਊਡ Y</string>\n    <string name=\"perlin_distortion\">ਪਰਲਿਨ ਵਿਗਾੜ</string>\n    <string name=\"aces_hill_tone_mapping\">ACES ਹਿੱਲ ਟੋਨ ਮੈਪਿੰਗ</string>\n    <string name=\"hable_filmic_tone_mapping\">ਹੈਬਲ ਫਿਲਮਿਕ ਟੋਨ ਮੈਪਿੰਗ</string>\n    <string name=\"heji_burgess_tone_mapping\">ਹੇਜਲ ਬਰਗੇਸ ਟੋਨ ਮੈਪਿੰਗ</string>\n    <string name=\"speed\">ਗਤੀ</string>\n    <string name=\"dehaze\">ਦੇਹਜ਼ੇ</string>\n    <string name=\"omega\">ਓਮੇਗਾ</string>\n    <string name=\"color_matrix_4x4\">ਰੰਗ ਮੈਟ੍ਰਿਕਸ 4x4</string>\n    <string name=\"color_matrix_3x3\">ਰੰਗ ਮੈਟ੍ਰਿਕਸ 3x3</string>\n    <string name=\"simple_effects\">ਸਧਾਰਨ ਪ੍ਰਭਾਵ</string>\n    <string name=\"polaroid\">ਪੋਲਰਾਇਡ</string>\n    <string name=\"tritonomaly\">ਟ੍ਰਾਈਟੋਨੋਮਲੀ</string>\n    <string name=\"deutaromaly\">ਡਿਊਟਰੋਮਾਲੀ</string>\n    <string name=\"protonomaly\">ਪ੍ਰੋਟੋਨੋਮਲੀ</string>\n    <string name=\"vintage\">ਵਿੰਟੇਜ</string>\n    <string name=\"browni\">ਬਰਾਊਨੀ</string>\n    <string name=\"coda_chrome\">ਕੋਡਾ ਕਰੋਮ</string>\n    <string name=\"night_vision\">ਨਾਈਟ ਵਿਜ਼ਨ</string>\n    <string name=\"warm\">ਗਰਮ</string>\n    <string name=\"cool\">ਠੰਡਾ</string>\n    <string name=\"tritanopia\">ਤ੍ਰਿਟਾਨੋਪੀਆ</string>\n    <string name=\"deutaronotopia\">ਡਿਊਟਾਰੋਨੋਟੋਪੀਆ</string>\n    <string name=\"protanopia\">ਪ੍ਰੋਟਾਨੋਪੀਆ</string>\n    <string name=\"achromatomaly\">ਐਕਰੋਮੈਟੋਮਾਲੀ</string>\n    <string name=\"achromatopsia\">ਐਕਰੋਮੈਟੋਪਸੀਆ</string>\n    <string name=\"grain\">ਅਨਾਜ</string>\n    <string name=\"unsharp\">ਅਨਸ਼ਾਰਪ</string>\n    <string name=\"pastel\">ਪੇਸਟਲ</string>\n    <string name=\"orange_haze\">ਸੰਤਰੀ ਧੁੰਦ</string>\n    <string name=\"pink_dream\">ਗੁਲਾਬੀ ਸੁਪਨਾ</string>\n    <string name=\"golden_hour\">ਗੋਲਡਨ ਆਵਰ</string>\n    <string name=\"hot_summer\">ਗਰਮ ਗਰਮੀ</string>\n    <string name=\"purple_mist\">ਜਾਮਨੀ ਧੁੰਦ</string>\n    <string name=\"sunrise\">ਸੂਰਜ ਚੜ੍ਹਨਾ</string>\n    <string name=\"colorful_swirl\">ਰੰਗੀਨ ਘੁੰਮਣਾ</string>\n    <string name=\"soft_spring_light\">ਨਰਮ ਬਸੰਤ ਰੋਸ਼ਨੀ</string>\n    <string name=\"autumn_tones\">ਪਤਝੜ ਟੋਨ</string>\n    <string name=\"lavender_dream\">ਲਵੈਂਡਰ ਡਰੀਮ</string>\n    <string name=\"cyberpunk\">ਸਾਈਬਰਪੰਕ</string>\n    <string name=\"lemonade_light\">ਨਿੰਬੂ ਪਾਣੀ ਦੀ ਰੌਸ਼ਨੀ</string>\n    <string name=\"spectral_fire\">ਸਪੈਕਟ੍ਰਲ ਅੱਗ</string>\n    <string name=\"night_magic\">ਰਾਤ ਦਾ ਜਾਦੂ</string>\n    <string name=\"fantasy_landscape\">ਕਲਪਨਾ ਲੈਂਡਸਕੇਪ</string>\n    <string name=\"color_explosion\">ਰੰਗ ਧਮਾਕਾ</string>\n    <string name=\"electric_gradient\">ਇਲੈਕਟ੍ਰਿਕ ਗਰੇਡੀਐਂਟ</string>\n    <string name=\"caramel_darkness\">ਕਾਰਾਮਲ ਹਨੇਰਾ</string>\n    <string name=\"futuristic_gradient\">ਭਵਿੱਖਵਾਦੀ ਗਰੇਡੀਐਂਟ</string>\n    <string name=\"green_sun\">ਹਰਾ ਸੂਰਜ</string>\n    <string name=\"rainbow_world\">ਰੇਨਬੋ ਵਰਲਡ</string>\n    <string name=\"deep_purple\">ਗੂੜਾ ਜਾਮਨੀ</string>\n    <string name=\"space_portal\">ਸਪੇਸ ਪੋਰਟਲ</string>\n    <string name=\"red_swirl\">ਲਾਲ ਘੁੰਮਣਾ</string>\n    <string name=\"digital_code\">ਡਿਜੀਟਲ ਕੋਡ</string>\n    <string name=\"bokeh\">ਬੋਕੇਹ</string>\n    <string name=\"random_emojis_sub\">ਐਪ ਬਾਰ ਇਮੋਜੀ ਨੂੰ ਚੁਣੇ ਹੋਏ ਇੱਕ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਬਜਾਏ ਲਗਾਤਾਰ ਬਦਲਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"random_emojis\">ਬੇਤਰਤੀਬ ਇਮੋਜੀ</string>\n    <string name=\"random_emojis_error\">ਇਮੋਜੀ ਬੰਦ ਹੋਣ \\'ਤੇ ਬੇਤਰਤੀਬ ਇਮੋਜੀ ਚੁਣਨ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ</string>\n    <string name=\"emoji_selection_error\">ਬੇਤਰਤੀਬ ਇੱਕ ਯੋਗ ਚੁਣਦੇ ਹੋਏ ਇੱਕ ਇਮੋਜੀ ਦੀ ਚੋਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ</string>\n    <string name=\"old_tv\">ਪੁਰਾਣਾ ਟੀ.ਵੀ</string>\n    <string name=\"shuffle_blur\">ਬਲਰ ਨੂੰ ਸ਼ਫਲ ਕਰੋ</string>\n    <string name=\"favorite\">ਮਨਪਸੰਦ</string>\n    <string name=\"no_favorite_filters\">ਅਜੇ ਤੱਕ ਕੋਈ ਮਨਪਸੰਦ ਫਿਲਟਰ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤੇ ਗਏ ਹਨ</string>\n    <string name=\"image_format\">ਚਿੱਤਰ ਫਾਰਮੈਟ</string>\n    <string name=\"icon_shape_sub\">ਕਾਰਡਾਂ ਦੇ ਪ੍ਰਮੁੱਖ ਆਈਕਨਾਂ ਦੇ ਹੇਠਾਂ ਚੁਣੀ ਹੋਈ ਸ਼ਕਲ ਵਾਲਾ ਕੰਟੇਨਰ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"icon_shape\">ਆਈਕਨ ਆਕਾਰ</string>\n    <string name=\"drago\">ਡਰੈਗੋ</string>\n    <string name=\"aldridge\">ਐਲਡਰਿਜ</string>\n    <string name=\"cutoff\">ਬੰਦ ਕਰ ਦਿਓ</string>\n    <string name=\"uchimura\">ਉਚੀਮੁਰਾ</string>\n    <string name=\"mobius\">ਮੋਬੀਅਸ</string>\n    <string name=\"transition\">ਤਬਦੀਲੀ</string>\n    <string name=\"peak\">ਪੀਕ</string>\n    <string name=\"color_anomaly\">ਰੰਗ ਦੀ ਵਿਗਾੜ</string>\n    <string name=\"images_overwritten\">ਅਸਲ ਮੰਜ਼ਿਲ \\'ਤੇ ਚਿੱਤਰਾਂ ਨੂੰ ਓਵਰਰਾਈਟ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"cannot_change_image_format\">ਓਵਰਰਾਈਟ ਫਾਈਲਾਂ ਵਿਕਲਪ ਯੋਗ ਹੋਣ \\'ਤੇ ਚਿੱਤਰ ਫਾਰਮੈਟ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ</string>\n    <string name=\"emoji_as_color_scheme\">ਰੰਗ ਸਕੀਮ ਵਜੋਂ ਇਮੋਜੀ</string>\n    <string name=\"emoji_as_color_scheme_sub\">ਹੱਥੀਂ ਪਰਿਭਾਸ਼ਿਤ ਇੱਕ ਦੀ ਬਜਾਏ ਐਪ ਰੰਗ ਸਕੀਮ ਦੇ ਤੌਰ \\'ਤੇ ਇਮੋਜੀ ਪ੍ਰਾਇਮਰੀ ਰੰਗ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"material_you_sub\">ਚਿੱਤਰ ਤੋਂ ਮੈਟੀਰੀਅਲ ਯੂ ਪੈਲੇਟ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"dark_colors\">ਗੂੜ੍ਹੇ ਰੰਗ</string>\n    <string name=\"dark_colors_sub\">ਲਾਈਟ ਵੇਰੀਐਂਟ ਦੀ ਬਜਾਏ ਨਾਈਟ ਮੋਡ ਕਲਰ ਸਕੀਮ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"copy_as_compose_code\">Jetpack ਕੰਪੋਜ਼ ਕੋਡ ਵਜੋਂ ਕਾਪੀ ਕਰੋ</string>\n    <string name=\"ring_blur\">ਰਿੰਗ ਬਲਰ</string>\n    <string name=\"cross_blur\">ਕ੍ਰਾਸ ਬਲਰ</string>\n    <string name=\"circle_blur\">ਚੱਕਰ ਧੁੰਦਲਾ</string>\n    <string name=\"star_blur\">ਸਟਾਰ ਬਲਰ</string>\n    <string name=\"linear_tilt_shift\">ਲੀਨੀਅਰ ਟਿਲਟ ਸ਼ਿਫਟ</string>\n    <string name=\"tags_to_remove\">ਹਟਾਉਣ ਲਈ ਟੈਗਸ</string>\n    <string name=\"apng_tools\">APNG ਟੂਲ</string>\n    <string name=\"apng_tools_sub\">ਚਿੱਤਰਾਂ ਨੂੰ APNG ਤਸਵੀਰ ਵਿੱਚ ਬਦਲੋ ਜਾਂ ਦਿੱਤੇ APNG ਚਿੱਤਰ ਤੋਂ ਫਰੇਮਾਂ ਨੂੰ ਐਕਸਟਰੈਕਟ ਕਰੋ</string>\n    <string name=\"apng_type_to_image\">ਚਿੱਤਰਾਂ ਲਈ APNG</string>\n    <string name=\"apng_type_to_image_sub\">APNG ਫਾਈਲ ਨੂੰ ਤਸਵੀਰਾਂ ਦੇ ਬੈਚ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"apng_type_to_apng_sub\">ਚਿੱਤਰਾਂ ਦੇ ਬੈਚ ਨੂੰ APNG ਫਾਈਲ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"apng_type_to_apng\">APNG ਲਈ ਚਿੱਤਰ</string>\n    <string name=\"select_apng_image_to_start\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ APNG ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"motion_blur\">ਮੋਸ਼ਨ ਬਲਰ</string>\n    <string name=\"zip_sub\">ਦਿੱਤੀਆਂ ਫਾਈਲਾਂ ਜਾਂ ਚਿੱਤਰਾਂ ਤੋਂ ਜ਼ਿਪ ਫਾਈਲ ਬਣਾਓ</string>\n    <string name=\"zip\">ਜ਼ਿਪ</string>\n    <string name=\"drag_handle_width\">ਹੈਂਡਲ ਦੀ ਚੌੜਾਈ ਨੂੰ ਘਸੀਟੋ</string>\n    <string name=\"confetti_type\">ਕੰਫੇਟੀ ਦੀ ਕਿਸਮ</string>\n    <string name=\"festive\">ਤਿਉਹਾਰ</string>\n    <string name=\"explode\">ਵਿਸਫੋਟ</string>\n    <string name=\"rain\">ਮੀਂਹ</string>\n    <string name=\"corners\">ਕੋਨੇ</string>\n    <string name=\"jxl_tools\">JXL ਟੂਲ</string>\n    <string name=\"jxl_tools_sub\">ਬਿਨਾਂ ਗੁਣਵੱਤਾ ਦੇ ਨੁਕਸਾਨ ਦੇ JXL ~ JPEG ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਕਰੋ, ਜਾਂ GIF/APNG ਨੂੰ JXL ਐਨੀਮੇਸ਼ਨ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"jxl_type_to_jpeg\">JXL ਤੋਂ JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL ਤੋਂ JPEG ਤੱਕ ਨੁਕਸਾਨ ਰਹਿਤ ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਕਰੋ</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG ਤੋਂ JXL ਤੱਕ ਨੁਕਸਾਨ ਰਹਿਤ ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਕਰੋ</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG ਤੋਂ JXL</string>\n    <string name=\"select_jxl_image_to_start\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ JXL ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"fast_gaussian_blur_2d\">ਤੇਜ਼ ਗੌਸੀ ਬਲਰ 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">ਤੇਜ਼ ਗੌਸੀਅਨ ਬਲਰ 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">ਤੇਜ਼ ਗੌਸੀਅਨ ਬਲਰ 4D</string>\n    <string name=\"auto_paste\">ਕਾਰ ਈਸਟਰ</string>\n    <string name=\"auto_paste_sub\">ਐਪ ਨੂੰ ਕਲਿੱਪਬੋਰਡ ਡੇਟਾ ਨੂੰ ਆਟੋ ਪੇਸਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਸ ਲਈ ਇਹ ਮੁੱਖ ਸਕ੍ਰੀਨ \\'ਤੇ ਦਿਖਾਈ ਦੇਵੇਗਾ ਅਤੇ ਤੁਸੀਂ ਇਸ \\'ਤੇ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਗੇ</string>\n    <string name=\"harmonization_color\">ਹਾਰਮੋਨਾਈਜ਼ੇਸ਼ਨ ਰੰਗ</string>\n    <string name=\"harmonization_level\">ਹਾਰਮੋਨਾਈਜ਼ੇਸ਼ਨ ਪੱਧਰ</string>\n    <string name=\"lanczos_bessel\">ਲੈਂਕਜ਼ੋਸ ਬੇਸਲ</string>\n    <string name=\"lanczos_bessel_sub\">ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਪਿਕਸਲ ਮੁੱਲਾਂ ਲਈ ਬੇਸਲ (ਜਿੰਕ) ਫੰਕਸ਼ਨ ਨੂੰ ਲਾਗੂ ਕਰਕੇ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਨੂੰ ਕਾਇਮ ਰੱਖਦੀ ਹੈ</string>\n    <string name=\"gif_type_to_jxl\">JXL ਨੂੰ GIF</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF ਚਿੱਤਰਾਂ ਨੂੰ JXL ਐਨੀਮੇਟਡ ਤਸਵੀਰਾਂ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"apng_type_to_jxl\">APNG ਤੋਂ JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG ਚਿੱਤਰਾਂ ਨੂੰ JXL ਐਨੀਮੇਟਡ ਤਸਵੀਰਾਂ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"jxl_type_to_images\">ਚਿੱਤਰਾਂ ਲਈ JXL</string>\n    <string name=\"jxl_type_to_images_sub\">JXL ਐਨੀਮੇਸ਼ਨ ਨੂੰ ਤਸਵੀਰਾਂ ਦੇ ਬੈਚ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"jxl_type_to_jxl\">JXL ਲਈ ਚਿੱਤਰ</string>\n    <string name=\"jxl_type_to_jxl_sub\">ਤਸਵੀਰਾਂ ਦੇ ਬੈਚ ਨੂੰ JXL ਐਨੀਮੇਸ਼ਨ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"behavior\">ਵਿਵਹਾਰ</string>\n    <string name=\"skip_file_picking\">ਫਾਈਲ ਚੁਣਨਾ ਛੱਡੋ</string>\n    <string name=\"skip_file_picking_sub\">ਜੇ ਚੁਣੀ ਹੋਈ ਸਕ੍ਰੀਨ \\'ਤੇ ਇਹ ਸੰਭਵ ਹੋਵੇ ਤਾਂ ਫਾਈਲ ਚੋਣਕਾਰ ਨੂੰ ਤੁਰੰਤ ਦਿਖਾਇਆ ਜਾਵੇਗਾ</string>\n    <string name=\"generate_previews\">ਪੂਰਵਦਰਸ਼ਨ ਤਿਆਰ ਕਰੋ</string>\n    <string name=\"generate_previews_sub\">ਪ੍ਰੀਵਿਊ ਜਨਰੇਸ਼ਨ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ, ਇਹ ਕੁਝ ਡਿਵਾਈਸਾਂ \\'ਤੇ ਕ੍ਰੈਸ਼ ਤੋਂ ਬਚਣ ਵਿੱਚ ਮਦਦ ਕਰ ਸਕਦਾ ਹੈ, ਇਹ ਸਿੰਗਲ ਐਡਿਟ ਵਿਕਲਪ ਦੇ ਅੰਦਰ ਕੁਝ ਸੰਪਾਦਨ ਕਾਰਜਸ਼ੀਲਤਾ ਨੂੰ ਵੀ ਅਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"lossy_compression\">ਨੁਕਸਾਨਦਾਇਕ ਸੰਕੁਚਨ</string>\n    <string name=\"lossy_compression_sub\">ਲੌਸਲੇਸ ਦੀ ਬਜਾਏ ਫਾਈਲ ਦਾ ਆਕਾਰ ਘਟਾਉਣ ਲਈ ਨੁਕਸਾਨਦੇਹ ਕੰਪਰੈਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"compression_type\">ਕੰਪਰੈਸ਼ਨ ਦੀ ਕਿਸਮ</string>\n    <string name=\"speed_sub\">ਨਤੀਜੇ ਵਜੋਂ ਚਿੱਤਰ ਡੀਕੋਡਿੰਗ ਦੀ ਗਤੀ ਨੂੰ ਨਿਯੰਤਰਿਤ ਕਰਦਾ ਹੈ, ਇਸ ਨਾਲ ਨਤੀਜੇ ਵਾਲੇ ਚਿੱਤਰ ਨੂੰ ਤੇਜ਼ੀ ਨਾਲ ਖੋਲ੍ਹਣ ਵਿੱਚ ਮਦਦ ਮਿਲੇਗੀ, %1$s ਦੇ ਮੁੱਲ ਦਾ ਮਤਲਬ ਹੈ ਸਭ ਤੋਂ ਹੌਲੀ ਡੀਕੋਡਿੰਗ, ਜਦੋਂ ਕਿ %2$s - ਸਭ ਤੋਂ ਤੇਜ਼, ਇਹ ਸੈਟਿੰਗ ਆਉਟਪੁੱਟ ਚਿੱਤਰ ਆਕਾਰ ਨੂੰ ਵਧਾ ਸਕਦੀ ਹੈ</string>\n    <string name=\"sorting\">ਛਾਂਟੀ</string>\n    <string name=\"sort_by_date\">ਮਿਤੀ</string>\n    <string name=\"sort_by_date_reversed\">ਮਿਤੀ (ਉਲਟ)</string>\n    <string name=\"sort_by_name\">ਨਾਮ</string>\n    <string name=\"sort_by_name_reversed\">ਨਾਮ (ਉਲਟ)</string>\n    <string name=\"channels_configuration\">ਚੈਨਲ ਸੰਰਚਨਾ</string>\n    <string name=\"header_today\">ਅੱਜ</string>\n    <string name=\"header_yesterday\">ਕੱਲ੍ਹ</string>\n    <string name=\"embedded_picker\">ਏਮਬੈੱਡ ਚੋਣਕਾਰ</string>\n    <string name=\"embedded_picker_sub\">ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਦਾ ਚਿੱਤਰ ਚੋਣਕਾਰ</string>\n    <string name=\"no_permissions\">ਕੋਈ ਇਜਾਜ਼ਤ ਨਹੀਂ</string>\n    <string name=\"request\">ਬੇਨਤੀ</string>\n    <string name=\"pick_multiple_media\">ਮਲਟੀਪਲ ਮੀਡੀਆ ਚੁਣੋ</string>\n    <string name=\"pick_single_media\">ਸਿੰਗਲ ਮੀਡੀਆ ਚੁਣੋ</string>\n    <string name=\"pick\">ਚੁਣੋ</string>\n    <string name=\"try_again\">ਫਿਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ</string>\n    <string name=\"show_settings_in_landscape\">ਲੈਂਡਸਕੇਪ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਦਿਖਾਓ</string>\n    <string name=\"show_settings_in_landscape_sub\">ਜੇਕਰ ਇਹ ਅਸਮਰੱਥ ਹੈ, ਤਾਂ ਲੈਂਡਸਕੇਪ ਮੋਡ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਸਥਾਈ ਦਿੱਖ ਵਿਕਲਪ ਦੀ ਬਜਾਏ, ਹਮੇਸ਼ਾ ਦੀ ਤਰ੍ਹਾਂ ਸਿਖਰ ਐਪ ਬਾਰ ਵਿੱਚ ਬਟਨ \\'ਤੇ ਖੋਲ੍ਹਿਆ ਜਾਵੇਗਾ।</string>\n    <string name=\"fullscreen_settings\">ਪੂਰੀ ਸਕ੍ਰੀਨ ਸੈਟਿੰਗਾਂ</string>\n    <string name=\"fullscreen_settings_sub\">ਇਸਨੂੰ ਸਮਰੱਥ ਕਰੋ ਅਤੇ ਸੈਟਿੰਗਾਂ ਪੰਨਾ ਹਮੇਸ਼ਾ ਸਲਾਈਡ ਹੋਣ ਯੋਗ ਦਰਾਜ਼ ਸ਼ੀਟ ਦੀ ਬਜਾਏ ਪੂਰੀ ਸਕਰੀਨ ਦੇ ਤੌਰ \\'ਤੇ ਖੋਲ੍ਹਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"switch_type\">ਸਵਿੱਚ ਦੀ ਕਿਸਮ</string>\n    <string name=\"compose\">ਕੰਪੋਜ਼ ਕਰੋ</string>\n    <string name=\"compose_switch_sub\">ਇੱਕ Jetpack ਕੰਪੋਜ਼ ਸਮੱਗਰੀ ਜੋ ਤੁਸੀਂ ਬਦਲਦੇ ਹੋ</string>\n    <string name=\"material_you_switch_sub\">ਇੱਕ ਸਮੱਗਰੀ ਜੋ ਤੁਸੀਂ ਬਦਲਦੇ ਹੋ</string>\n    <string name=\"max\">ਅਧਿਕਤਮ</string>\n    <string name=\"resize_anchor\">ਐਂਕਰ ਦਾ ਆਕਾਰ ਬਦਲੋ</string>\n    <string name=\"pixel_switch\">ਪਿਕਸਲ</string>\n    <string name=\"fluent_switch\">ਪ੍ਰਵਾਹ</string>\n    <string name=\"fluent_switch_sub\">\\\"Fluent\\\" ਡਿਜ਼ਾਈਨ ਸਿਸਟਮ \\'ਤੇ ਆਧਾਰਿਤ ਇੱਕ ਸਵਿੱਚ</string>\n    <string name=\"cupertino_switch\">ਕੁਪਰਟੀਨੋ</string>\n    <string name=\"cupertino_switch_sub\">\\\"Cupertino\\\" ਡਿਜ਼ਾਈਨ ਸਿਸਟਮ \\'ਤੇ ਆਧਾਰਿਤ ਇੱਕ ਸਵਿੱਚ</string>\n    <string name=\"images_to_svg\">SVG ਲਈ ਚਿੱਤਰ</string>\n    <string name=\"images_to_svg_sub\">ਦਿੱਤੇ ਚਿੱਤਰਾਂ ਨੂੰ SVG ਚਿੱਤਰਾਂ ਨੂੰ ਟਰੇਸ ਕਰੋ</string>\n    <string name=\"use_sampled_palette\">ਸੈਂਪਲ ਪੈਲੇਟ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"use_sampled_palette_sub\">ਜੇਕਰ ਇਹ ਵਿਕਲਪ ਯੋਗ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਤਾਂ ਕੁਆਂਟਾਈਜ਼ੇਸ਼ਨ ਪੈਲੇਟ ਦਾ ਨਮੂਨਾ ਲਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"path_omit\">ਮਾਰਗ ਛੱਡ ਦਿੱਤਾ</string>\n    <string name=\"svg_warning\">ਡਾਊਨਸਕੇਲਿੰਗ ਤੋਂ ਬਿਨਾਂ ਵੱਡੀਆਂ ਤਸਵੀਰਾਂ ਨੂੰ ਟਰੇਸ ਕਰਨ ਲਈ ਇਸ ਟੂਲ ਦੀ ਵਰਤੋਂ ਦੀ ਸਿਫ਼ਾਰਸ਼ ਨਹੀਂ ਕੀਤੀ ਜਾਂਦੀ, ਇਹ ਕਰੈਸ਼ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੀ ਹੈ ਅਤੇ ਪ੍ਰੋਸੈਸਿੰਗ ਸਮੇਂ ਨੂੰ ਵਧਾ ਸਕਦੀ ਹੈ।</string>\n    <string name=\"downscale_image\">ਡਾਊਨਸਕੇਲ ਚਿੱਤਰ</string>\n    <string name=\"downscale_image_sub\">ਪ੍ਰੋਸੈਸਿੰਗ ਤੋਂ ਪਹਿਲਾਂ ਚਿੱਤਰ ਨੂੰ ਹੇਠਲੇ ਮਾਪਾਂ ਤੱਕ ਘਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਇਹ ਟੂਲ ਨੂੰ ਤੇਜ਼ ਅਤੇ ਸੁਰੱਖਿਅਤ ਕੰਮ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦਾ ਹੈ</string>\n    <string name=\"min_color_ratio\">ਘੱਟੋ-ਘੱਟ ਰੰਗ ਅਨੁਪਾਤ</string>\n    <string name=\"lines_threshold\">ਲਾਈਨਾਂ ਥ੍ਰੈਸ਼ਹੋਲਡ</string>\n    <string name=\"quadratic_threshold\">ਚਤੁਰਭੁਜ ਥ੍ਰੈਸ਼ਹੋਲਡ</string>\n    <string name=\"coordinates_rounding_tolerance\">ਕੋਆਰਡੀਨੇਟਸ ਰਾਊਂਡਿੰਗ ਸਹਿਣਸ਼ੀਲਤਾ</string>\n    <string name=\"path_scale\">ਪਾਥ ਸਕੇਲ</string>\n    <string name=\"reset_properties\">ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਰੀਸੈਟ ਕਰੋ</string>\n    <string name=\"reset_properties_sub\">ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਮੁੱਲਾਂ \\'ਤੇ ਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਧਿਆਨ ਦਿਓ ਕਿ ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਅਣਕੀਤਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ</string>\n    <string name=\"detailed\">ਵਿਸਤ੍ਰਿਤ</string>\n    <string name=\"default_line_width\">ਪੂਰਵ-ਨਿਰਧਾਰਤ ਲਾਈਨ ਚੌੜਾਈ</string>\n    <string name=\"engine_mode\">ਇੰਜਣ ਮੋਡ</string>\n    <string name=\"legacy\">ਵਿਰਾਸਤ</string>\n    <string name=\"lstm_network\">LSTM ਨੈੱਟਵਰਕ</string>\n    <string name=\"legacy_and_lstm\">ਵਿਰਾਸਤ ਅਤੇ LSTM</string>\n    <string name=\"convert\">ਬਦਲੋ</string>\n    <string name=\"convert_sub\">ਚਿੱਤਰ ਬੈਚਾਂ ਨੂੰ ਦਿੱਤੇ ਫਾਰਮੈਟ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"add_new_folder\">ਨਵਾਂ ਫੋਲਡਰ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"tag_bits_per_sample\">ਬਿੱਟ ਪ੍ਰਤੀ ਨਮੂਨਾ</string>\n    <string name=\"tag_compression\">ਕੰਪਰੈਸ਼ਨ</string>\n    <string name=\"tag_photometric_interpretation\">ਫੋਟੋਮੈਟ੍ਰਿਕ ਵਿਆਖਿਆ</string>\n    <string name=\"tag_samples_per_pixel\">ਨਮੂਨੇ ਪ੍ਰਤੀ ਪਿਕਸਲ</string>\n    <string name=\"tag_planar_configuration\">ਪਲੈਨਰ ​​ਸੰਰਚਨਾ</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr ਸਬ ਸੈਂਪਲਿੰਗ</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr ਪੋਜੀਸ਼ਨਿੰਗ</string>\n    <string name=\"tag_x_resolution\">ਐਕਸ ਰੈਜ਼ੋਲਿਊਸ਼ਨ</string>\n    <string name=\"tag_y_resolution\">Y ਰੈਜ਼ੋਲਿਊਸ਼ਨ</string>\n    <string name=\"tag_resolution_unit\">ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਯੂਨਿਟ</string>\n    <string name=\"tag_strip_offsets\">ਸਟ੍ਰਿਪ ਆਫਸੈਟਸ</string>\n    <string name=\"tag_rows_per_strip\">ਕਤਾਰਾਂ ਪ੍ਰਤੀ ਪੱਟੀ</string>\n    <string name=\"tag_strip_byte_counts\">ਸਟ੍ਰਿਪ ਬਾਈਟ ਗਿਣਤੀ</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG ਇੰਟਰਚੇਂਜ ਫਾਰਮੈਟ</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG ਇੰਟਰਚੇਂਜ ਫਾਰਮੈਟ ਲੰਬਾਈ</string>\n    <string name=\"tag_transfer_function\">ਟ੍ਰਾਂਸਫਰ ਫੰਕਸ਼ਨ</string>\n    <string name=\"tag_white_point\">ਵ੍ਹਾਈਟ ਪੁਆਇੰਟ</string>\n    <string name=\"tag_primary_chromaticities\">ਪ੍ਰਾਇਮਰੀ ਰੰਗੀਨਤਾਵਾਂ</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr ਗੁਣਾਂਕ</string>\n    <string name=\"tag_reference_black_white\">ਹਵਾਲਾ ਬਲੈਕ ਵ੍ਹਾਈਟ</string>\n    <string name=\"tag_datetime\">ਮਿਤੀ ਸਮਾਂ</string>\n    <string name=\"tag_image_description\">ਚਿੱਤਰ ਵਰਣਨ</string>\n    <string name=\"tag_make\">ਬਣਾਉ</string>\n    <string name=\"tag_model\">ਮਾਡਲ</string>\n    <string name=\"tag_software\">ਸਾਫਟਵੇਅਰ</string>\n    <string name=\"tag_artist\">ਕਲਾਕਾਰ</string>\n    <string name=\"tag_copyright\">ਕਾਪੀਰਾਈਟ</string>\n    <string name=\"tag_exif_version\">Exif ਸੰਸਕਰਣ</string>\n    <string name=\"tag_flashpix_version\">ਫਲੈਸ਼ਪਿਕਸ ਸੰਸਕਰਣ</string>\n    <string name=\"tag_color_space\">ਰੰਗ ਸਪੇਸ</string>\n    <string name=\"tag_gamma\">ਗਾਮਾ</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X ਮਾਪ</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y ਮਾਪ</string>\n    <string name=\"tag_compressed_bits_per_pixel\">ਕੰਪਰੈੱਸਡ ਬਿੱਟ ਪ੍ਰਤੀ ਪਿਕਸਲ</string>\n    <string name=\"tag_maker_note\">ਮੇਕਰ ਨੋਟ</string>\n    <string name=\"tag_user_comment\">ਉਪਭੋਗਤਾ ਟਿੱਪਣੀ</string>\n    <string name=\"tag_related_sound_file\">ਸੰਬੰਧਿਤ ਸਾਊਂਡ ਫਾਈਲ</string>\n    <string name=\"tag_datetime_original\">ਮਿਤੀ ਸਮਾਂ ਮੂਲ</string>\n    <string name=\"tag_datetime_digitized\">ਮਿਤੀ ਸਮਾਂ ਡਿਜੀਟਾਈਜ਼ਡ</string>\n    <string name=\"tag_offset_time\">ਔਫਸੈੱਟ ਸਮਾਂ</string>\n    <string name=\"tag_offset_time_original\">ਔਫਸੈੱਟ ਸਮਾਂ ਮੂਲ</string>\n    <string name=\"tag_offset_time_digitized\">ਔਫਸੈੱਟ ਸਮਾਂ ਡਿਜੀਟਾਈਜ਼ਡ</string>\n    <string name=\"tag_subsec_time\">ਸਬ ਸਕਿੰਟ ਸਮਾਂ</string>\n    <string name=\"tag_subsec_time_original\">ਸਬ ਸਕਿੰਟ ਸਮਾਂ ਮੂਲ</string>\n    <string name=\"tag_subsec_time_digitized\">ਸਬ ਸਕਿੰਟ ਟਾਈਮ ਡਿਜੀਟਾਈਜ਼ਡ</string>\n    <string name=\"tag_exposure_time\">ਸੰਪਰਕ ਦਾ ਸਮਾਂ</string>\n    <string name=\"tag_f_number\">F ਨੰਬਰ</string>\n    <string name=\"tag_exposure_program\">ਐਕਸਪੋਜ਼ਰ ਪ੍ਰੋਗਰਾਮ</string>\n    <string name=\"tag_spectral_sensitivity\">ਸਪੈਕਟ੍ਰਲ ਸੰਵੇਦਨਸ਼ੀਲਤਾ</string>\n    <string name=\"tag_photographic_sensitivity\">ਫੋਟੋਗ੍ਰਾਫਿਕ ਸੰਵੇਦਨਸ਼ੀਲਤਾ</string>\n    <string name=\"tag_oecf\">ਓ.ਈ.ਸੀ.ਐਫ</string>\n    <string name=\"tag_sensitivity_type\">ਸੰਵੇਦਨਸ਼ੀਲਤਾ ਦੀ ਕਿਸਮ</string>\n    <string name=\"tag_standard_output_sensitivity\">ਮਿਆਰੀ ਆਉਟਪੁੱਟ ਸੰਵੇਦਨਸ਼ੀਲਤਾ</string>\n    <string name=\"tag_recommended_exposure_index\">ਸਿਫਾਰਸ਼ੀ ਐਕਸਪੋਜ਼ਰ ਸੂਚਕਾਂਕ</string>\n    <string name=\"tag_iso_speed\">ISO ਸਪੀਡ</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO ਸਪੀਡ ਅਕਸ਼ਾਂਸ਼ yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO ਸਪੀਡ ਵਿਥਕਾਰ zzz</string>\n    <string name=\"tag_shutter_speed_value\">ਸ਼ਟਰ ਸਪੀਡ ਮੁੱਲ</string>\n    <string name=\"tag_aperture_value\">ਅਪਰਚਰ ਮੁੱਲ</string>\n    <string name=\"tag_brightness_value\">ਚਮਕ ਦਾ ਮੁੱਲ</string>\n    <string name=\"tag_exposure_bias_value\">ਐਕਸਪੋਜ਼ਰ ਪੱਖਪਾਤ ਮੁੱਲ</string>\n    <string name=\"tag_max_aperture_value\">ਅਧਿਕਤਮ ਅਪਰਚਰ ਮੁੱਲ</string>\n    <string name=\"tag_subject_distance\">ਵਿਸ਼ੇ ਦੀ ਦੂਰੀ</string>\n    <string name=\"tag_metering_mode\">ਮੀਟਰਿੰਗ ਮੋਡ</string>\n    <string name=\"tag_flash\">ਫਲੈਸ਼</string>\n    <string name=\"tag_subject_area\">ਵਿਸ਼ਾ ਖੇਤਰ</string>\n    <string name=\"tag_focal_length\">ਫੋਕਲ ਲੰਬਾਈ</string>\n    <string name=\"tag_flash_energy\">ਫਲੈਸ਼ ਊਰਜਾ</string>\n    <string name=\"tag_spatial_frequency_response\">ਸਥਾਨਿਕ ਬਾਰੰਬਾਰਤਾ ਜਵਾਬ</string>\n    <string name=\"tag_focal_plane_x_resolution\">ਫੋਕਲ ਪਲੇਨ ਐਕਸ ਰੈਜ਼ੋਲਿਊਸ਼ਨ</string>\n    <string name=\"tag_focal_plane_y_resolution\">ਫੋਕਲ ਪਲੇਨ Y ਰੈਜ਼ੋਲਿਊਸ਼ਨ</string>\n    <string name=\"tag_focal_plane_resolution_unit\">ਫੋਕਲ ਪਲੇਨ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਯੂਨਿਟ</string>\n    <string name=\"tag_subject_location\">ਵਿਸ਼ਾ ਟਿਕਾਣਾ</string>\n    <string name=\"tag_exposure_index\">ਐਕਸਪੋਜ਼ਰ ਸੂਚਕਾਂਕ</string>\n    <string name=\"tag_sensing_method\">ਸੈਂਸਿੰਗ ਵਿਧੀ</string>\n    <string name=\"tag_file_source\">ਫਾਈਲ ਸਰੋਤ</string>\n    <string name=\"tag_cfa_pattern\">CFA ਪੈਟਰਨ</string>\n    <string name=\"tag_custom_rendered\">ਕਸਟਮ ਰੈਂਡਰ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"tag_exposure_mode\">ਐਕਸਪੋਜ਼ਰ ਮੋਡ</string>\n    <string name=\"tag_white_balance\">ਚਿੱਟਾ ਸੰਤੁਲਨ</string>\n    <string name=\"tag_digital_zoom_ratio\">ਡਿਜੀਟਲ ਜ਼ੂਮ ਅਨੁਪਾਤ</string>\n    <string name=\"tag_focal_length_in_35mm_film\">ਫੋਕਲ ਲੰਬਾਈ ਵਿੱਚ 35mm ਫਿਲਮ</string>\n    <string name=\"tag_scene_capture_type\">ਸੀਨ ਕੈਪਚਰ ਦੀ ਕਿਸਮ</string>\n    <string name=\"tag_gain_control\">ਕੰਟਰੋਲ ਹਾਸਲ ਕਰੋ</string>\n    <string name=\"tag_contrast\">ਕੰਟ੍ਰਾਸਟ</string>\n    <string name=\"tag_saturation\">ਸੰਤ੍ਰਿਪਤਾ</string>\n    <string name=\"tag_sharpness\">ਤਿੱਖਾਪਨ</string>\n    <string name=\"tag_device_setting_description\">ਡਿਵਾਈਸ ਸੈਟਿੰਗ ਦਾ ਵੇਰਵਾ</string>\n    <string name=\"tag_subject_distance_range\">ਵਿਸ਼ਾ ਦੂਰੀ ਸੀਮਾ</string>\n    <string name=\"tag_image_unique_id\">ਚਿੱਤਰ ਵਿਲੱਖਣ ID</string>\n    <string name=\"tag_camera_owner_name\">ਕੈਮਰੇ ਦੇ ਮਾਲਕ ਦਾ ਨਾਮ</string>\n    <string name=\"tag_body_serial_number\">ਬਾਡੀ ਸੀਰੀਅਲ ਨੰਬਰ</string>\n    <string name=\"tag_lens_specification\">ਲੈਂਸ ਨਿਰਧਾਰਨ</string>\n    <string name=\"tag_lens_make\">ਲੈਂਸ ਬਣਾਉ</string>\n    <string name=\"tag_lens_model\">ਲੈਂਸ ਮਾਡਲ</string>\n    <string name=\"tag_lens_serial_number\">ਲੈਂਸ ਸੀਰੀਅਲ ਨੰਬਰ</string>\n    <string name=\"tag_gps_version_id\">GPS ਸੰਸਕਰਣ ਆਈ.ਡੀ</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS ਵਿਥਕਾਰ</string>\n    <string name=\"tag_gps_longitude_ref\">GPS ਲੰਬਕਾਰ ਰੈਫ</string>\n    <string name=\"tag_gps_longitude\">GPS ਲੰਬਕਾਰ</string>\n    <string name=\"tag_gps_altitude_ref\">GPS ਉਚਾਈ ਰੈਫ</string>\n    <string name=\"tag_gps_altitude\">GPS ਉਚਾਈ</string>\n    <string name=\"tag_gps_timestamp\">GPS ਟਾਈਮ ਸਟੈਂਪ</string>\n    <string name=\"tag_gps_satellites\">GPS ਸੈਟੇਲਾਈਟ</string>\n    <string name=\"tag_gps_status\">GPS ਸਥਿਤੀ</string>\n    <string name=\"tag_gps_measure_mode\">GPS ਮਾਪ ਮੋਡ</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS ਸਪੀਡ ਰੈਫ</string>\n    <string name=\"tag_gps_speed\">GPS ਸਪੀਡ</string>\n    <string name=\"tag_gps_track_ref\">GPS ਟਰੈਕ ਰੈਫ</string>\n    <string name=\"tag_gps_track\">GPS ਟਰੈਕ</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img ਨਿਰਦੇਸ਼ਕ ਰੈਫ</string>\n    <string name=\"tag_gps_img_direction\">GPS Img ਦਿਸ਼ਾ</string>\n    <string name=\"tag_gps_map_datum\">GPS ਨਕਸ਼ਾ ਡਾਟਾ</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS ਡੈਸਟ ਵਿਥਕਾਰ</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS ਡੈਸਟ ਲੰਬਕਾਰ ਰੈਫ</string>\n    <string name=\"tag_gps_dest_longitude\">GPS ਡੈਸਟ ਲੰਬਕਾਰ</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS ਡੈਸਟ ਬੇਅਰਿੰਗ ਰੈਫ</string>\n    <string name=\"tag_gps_dest_bearing\">GPS ਡੈਸਟ ਬੇਅਰਿੰਗ</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS ਡੈਸਟ ਡਿਸਟੈਂਸ ਰੈਫ</string>\n    <string name=\"tag_gps_dest_distance\">GPS ਡੈਸਟ ਦੂਰੀ</string>\n    <string name=\"tag_gps_processing_method\">GPS ਪ੍ਰੋਸੈਸਿੰਗ ਵਿਧੀ</string>\n    <string name=\"tag_gps_area_information\">GPS ਖੇਤਰ ਜਾਣਕਾਰੀ</string>\n    <string name=\"tag_gps_datestamp\">GPS ਮਿਤੀ ਸਟੈਂਪ</string>\n    <string name=\"tag_gps_differential\">GPS ਅੰਤਰ</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H ਪੋਜੀਸ਼ਨਿੰਗ ਗਲਤੀ</string>\n    <string name=\"tag_interoperability_index\">ਅੰਤਰ-ਕਾਰਜਸ਼ੀਲਤਾ ਸੂਚਕਾਂਕ</string>\n    <string name=\"tag_dng_version\">DNG ਸੰਸਕਰਣ</string>\n    <string name=\"tag_default_crop_size\">ਡਿਫੌਲਟ ਕ੍ਰੌਪ ਆਕਾਰ</string>\n    <string name=\"tag_orf_preview_image_start\">ਝਲਕ ਚਿੱਤਰ ਸ਼ੁਰੂ</string>\n    <string name=\"tag_orf_preview_image_length\">ਝਲਕ ਚਿੱਤਰ ਦੀ ਲੰਬਾਈ</string>\n    <string name=\"tag_orf_aspect_frame\">ਆਸਪੈਕਟ ਫਰੇਮ</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">ਸੈਂਸਰ ਬੌਟਮ ਬਾਰਡਰ</string>\n    <string name=\"tag_rw2_sensor_left_border\">ਸੈਂਸਰ ਖੱਬਾ ਬਾਰਡਰ</string>\n    <string name=\"tag_rw2_sensor_right_border\">ਸੈਂਸਰ ਸੱਜਾ ਕਿਨਾਰਾ</string>\n    <string name=\"tag_rw2_sensor_top_border\">ਸੈਂਸਰ ਸਿਖਰ ਬਾਰਡਰ</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">ਦਿੱਤੇ ਗਏ ਫੌਂਟ ਅਤੇ ਰੰਗ ਨਾਲ ਮਾਰਗ \\'ਤੇ ਟੈਕਸਟ ਡਰਾਅ ਕਰੋ</string>\n    <string name=\"font_size\">ਫੌਂਟ ਦਾ ਆਕਾਰ</string>\n    <string name=\"watermark_size\">ਵਾਟਰਮਾਰਕ ਦਾ ਆਕਾਰ</string>\n    <string name=\"repeat_text\">ਪਾਠ ਦੁਹਰਾਓ</string>\n    <string name=\"repeat_text_sub\">ਮੌਜੂਦਾ ਟੈਕਸਟ ਨੂੰ ਇੱਕ ਵਾਰ ਡਰਾਇੰਗ ਦੀ ਬਜਾਏ ਮਾਰਗ ਦੇ ਅੰਤ ਤੱਕ ਦੁਹਰਾਇਆ ਜਾਵੇਗਾ</string>\n    <string name=\"dash_size\">ਡੈਸ਼ ਦਾ ਆਕਾਰ</string>\n    <string name=\"draw_mode_image_sub\">ਚੁਣੇ ਹੋਏ ਚਿੱਤਰ ਨੂੰ ਦਿੱਤੇ ਮਾਰਗ \\'ਤੇ ਖਿੱਚਣ ਲਈ ਵਰਤੋ</string>\n    <string name=\"draw_image_sub\">ਇਹ ਚਿੱਤਰ ਖਿੱਚੇ ਗਏ ਮਾਰਗ ਦੀ ਦੁਹਰਾਉਣ ਵਾਲੀ ਐਂਟਰੀ ਵਜੋਂ ਵਰਤਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"outlined_triangle_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਰੂਪਰੇਖਾ ਤਿਕੋਣ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"triangle_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਰੂਪਰੇਖਾ ਤਿਕੋਣ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"outlined_triangle\">ਰੂਪਰੇਖਾ ਤਿਕੋਣ</string>\n    <string name=\"triangle\">ਤਿਕੋਣ</string>\n    <string name=\"polygon_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਬਹੁਭੁਜ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"polygon\">ਬਹੁਭੁਜ</string>\n    <string name=\"outlined_polygon\">ਰੂਪਰੇਖਾ ਬਹੁਭੁਜ</string>\n    <string name=\"outlined_polygon_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਰੂਪਰੇਖਾ ਬਹੁਭੁਜ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"vertices\">ਸਿਰਲੇਖ</string>\n    <string name=\"draw_regular_polygon\">ਨਿਯਮਤ ਬਹੁਭੁਜ ਖਿੱਚੋ</string>\n    <string name=\"draw_regular_polygon_sub\">ਬਹੁਭੁਜ ਖਿੱਚੋ ਜੋ ਮੁਫਤ ਰੂਪ ਦੀ ਬਜਾਏ ਨਿਯਮਤ ਹੋਵੇਗਾ</string>\n    <string name=\"star_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਤਾਰਾ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"star\">ਤਾਰਾ</string>\n    <string name=\"outlined_star\">ਰੂਪਰੇਖਾਬੱਧ ਤਾਰਾ</string>\n    <string name=\"outlined_star_sub\">ਸ਼ੁਰੂਆਤੀ ਬਿੰਦੂ ਤੋਂ ਅੰਤ ਬਿੰਦੂ ਤੱਕ ਰੂਪਰੇਖਾਬੱਧ ਤਾਰਾ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"inner_radius_ratio\">ਅੰਦਰੂਨੀ ਰੇਡੀਅਸ ਅਨੁਪਾਤ</string>\n    <string name=\"draw_regular_star\">ਨਿਯਮਤ ਤਾਰਾ ਖਿੱਚੋ</string>\n    <string name=\"draw_regular_star_sub\">ਤਾਰਾ ਖਿੱਚੋ ਜੋ ਮੁਫਤ ਫਾਰਮ ਦੀ ਬਜਾਏ ਨਿਯਮਤ ਹੋਵੇਗਾ</string>\n    <string name=\"antialias\">ਐਂਟੀਅਲੀਅਸ</string>\n    <string name=\"antialias_sub\">ਤਿੱਖੇ ਕਿਨਾਰਿਆਂ ਨੂੰ ਰੋਕਣ ਲਈ ਐਂਟੀਅਲਾਈਜ਼ਿੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"open_edit_instead_of_preview\">ਪੂਰਵਦਰਸ਼ਨ ਦੀ ਬਜਾਏ ਸੰਪਾਦਨ ਖੋਲ੍ਹੋ</string>\n    <string name=\"open_edit_instead_of_preview_sub\">ਜਦੋਂ ਤੁਸੀਂ ਇਮੇਜਟੂਲਬਾਕਸ ਵਿੱਚ ਖੋਲ੍ਹਣ ਲਈ (ਪੂਰਵਦਰਸ਼ਨ) ਚਿੱਤਰ ਦੀ ਚੋਣ ਕਰਦੇ ਹੋ, ਤਾਂ ਪੂਰਵਦਰਸ਼ਨ ਦੀ ਬਜਾਏ ਸੰਪਾਦਨ ਚੋਣ ਸ਼ੀਟ ਖੋਲ੍ਹਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"document_scanner\">ਦਸਤਾਵੇਜ਼ ਸਕੈਨਰ</string>\n    <string name=\"document_scanner_sub\">ਦਸਤਾਵੇਜ਼ਾਂ ਨੂੰ ਸਕੈਨ ਕਰੋ ਅਤੇ ਉਹਨਾਂ ਤੋਂ PDF ਜਾਂ ਵੱਖਰੀਆਂ ਤਸਵੀਰਾਂ ਬਣਾਓ</string>\n    <string name=\"click_to_start_scanning\">ਸਕੈਨਿੰਗ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ</string>\n    <string name=\"start_scanning\">ਸਕੈਨਿੰਗ ਸ਼ੁਰੂ ਕਰੋ</string>\n    <string name=\"save_as_pdf\">ਪੀਡੀਐਫ ਵਜੋਂ ਸੇਵ ਕਰੋ</string>\n    <string name=\"share_as_pdf\">ਪੀਡੀਐਫ ਵਜੋਂ ਸਾਂਝਾ ਕਰੋ</string>\n    <string name=\"options_below_is_for_images\">ਹੇਠਾਂ ਦਿੱਤੇ ਵਿਕਲਪ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਹਨ, PDF ਨਹੀਂ</string>\n    <string name=\"equalize_histogram_hsv\">ਹਿਸਟੋਗ੍ਰਾਮ HSV ਨੂੰ ਬਰਾਬਰ ਕਰੋ</string>\n    <string name=\"equalize_histogram\">ਹਿਸਟੋਗ੍ਰਾਮ ਨੂੰ ਬਰਾਬਰ ਕਰੋ</string>\n    <string name=\"enter_percentage\">ਪ੍ਰਤੀਸ਼ਤ ਦਰਜ ਕਰੋ</string>\n    <string name=\"allow_enter_by_text_field\">ਟੈਕਸਟ ਫੀਲਡ ਦੁਆਰਾ ਦਾਖਲ ਹੋਣ ਦਿਓ</string>\n    <string name=\"allow_enter_by_text_field_sub\">ਉਹਨਾਂ ਨੂੰ ਉੱਡਣ \\'ਤੇ ਦਾਖਲ ਕਰਨ ਲਈ, ਪ੍ਰੀਸੈਟਸ ਦੀ ਚੋਣ ਦੇ ਪਿੱਛੇ ਟੈਕਸਟ ਫੀਲਡ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"scale_color_space\">ਸਕੇਲ ਰੰਗ ਸਪੇਸ</string>\n    <string name=\"linear\">ਰੇਖਿਕ</string>\n    <string name=\"equalize_histogram_pixelation\">ਹਿਸਟੋਗ੍ਰਾਮ ਪਿਕਸਲੇਸ਼ਨ ਨੂੰ ਬਰਾਬਰ ਬਣਾਓ</string>\n    <string name=\"grid_size_x\">ਗਰਿੱਡ ਦਾ ਆਕਾਰ X</string>\n    <string name=\"grid_size_y\">ਗਰਿੱਡ ਦਾ ਆਕਾਰ Y</string>\n    <string name=\"equalize_histogram_adaptive\">ਹਿਸਟੋਗ੍ਰਾਮ ਅਡੈਪਟਿਵ ਨੂੰ ਬਰਾਬਰ ਬਣਾਓ</string>\n    <string name=\"equalize_histogram_adaptive_luv\">ਹਿਸਟੋਗ੍ਰਾਮ ਅਡੈਪਟਿਵ LUV ਨੂੰ ਬਰਾਬਰ ਬਣਾਓ</string>\n    <string name=\"equalize_histogram_adaptive_lab\">ਹਿਸਟੋਗ੍ਰਾਮ ਅਡੈਪਟਿਵ LAB ਨੂੰ ਬਰਾਬਰ ਬਣਾਓ</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE ਲੈਬ</string>\n    <string name=\"clahe_luv\">ਕਲੇ ਲਵ</string>\n    <string name=\"crop_to_content\">ਸਮੱਗਰੀ ਨੂੰ ਕੱਟੋ</string>\n    <string name=\"frame_color\">ਫਰੇਮ ਦਾ ਰੰਗ</string>\n    <string name=\"color_to_ignore\">ਅਣਡਿੱਠ ਕਰਨ ਲਈ ਰੰਗ</string>\n    <string name=\"template\">ਟੈਂਪਲੇਟ</string>\n    <string name=\"no_template_filters\">ਕੋਈ ਟੈਮਪਲੇਟ ਫਿਲਟਰ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤੇ ਗਏ</string>\n    <string name=\"create_new\">ਨਵਾਂ ਬਣਾਓ</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">ਸਕੈਨ ਕੀਤਾ QR ਕੋਡ ਇੱਕ ਵੈਧ ਫਿਲਟਰ ਟੈਮਪਲੇਟ ਨਹੀਂ ਹੈ</string>\n    <string name=\"scan_qr_code\">QR ਕੋਡ ਸਕੈਨ ਕਰੋ</string>\n    <string name=\"opened_file_have_no_filter_template\">ਚੁਣੀ ਗਈ ਫ਼ਾਈਲ ਵਿੱਚ ਕੋਈ ਫਿਲਟਰ ਟੈਮਪਲੇਟ ਡਾਟਾ ਨਹੀਂ ਹੈ</string>\n    <string name=\"create_template\">ਟੈਮਪਲੇਟ ਬਣਾਓ</string>\n    <string name=\"template_name\">ਟੈਮਪਲੇਟ ਦਾ ਨਾਮ</string>\n    <string name=\"select_template_preview\">ਇਸ ਚਿੱਤਰ ਦੀ ਵਰਤੋਂ ਇਸ ਫਿਲਟਰ ਟੈਮਪਲੇਟ ਦੀ ਝਲਕ ਲਈ ਕੀਤੀ ਜਾਵੇਗੀ</string>\n    <string name=\"template_filter\">ਟੈਮਪਲੇਟ ਫਿਲਟਰ</string>\n    <string name=\"as_qr_code\">QR ਕੋਡ ਚਿੱਤਰ ਵਜੋਂ</string>\n    <string name=\"as_file\">ਫਾਈਲ ਦੇ ਰੂਪ ਵਿੱਚ</string>\n    <string name=\"save_as_file\">ਫਾਈਲ ਦੇ ਰੂਪ ਵਿੱਚ ਸੇਵ ਕਰੋ</string>\n    <string name=\"save_as_qr_code_image\">QR ਕੋਡ ਚਿੱਤਰ ਵਜੋਂ ਸੁਰੱਖਿਅਤ ਕਰੋ</string>\n    <string name=\"delete_template\">ਟੈਮਪਲੇਟ ਮਿਟਾਓ</string>\n    <string name=\"delete_template_warn\">ਤੁਸੀਂ ਚੁਣੇ ਹੋਏ ਟੈਮਪਲੇਟ ਫਿਲਟਰ ਨੂੰ ਮਿਟਾਉਣ ਲੱਗੇ ਹੋ। ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਅਣਕੀਤਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) ਨਾਮ ਨਾਲ ਫਿਲਟਰ ਟੈਮਪਲੇਟ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"filter_preview\">ਫਿਲਟਰ ਪ੍ਰੀਵਿਊ</string>\n    <string name=\"qr_code\">QR ਅਤੇ ਬਾਰਕੋਡ</string>\n    <string name=\"qr_code_sub\">QR ਕੋਡ ਨੂੰ ਸਕੈਨ ਕਰੋ ਅਤੇ ਇਸਦੀ ਸਮੱਗਰੀ ਪ੍ਰਾਪਤ ਕਰੋ ਜਾਂ ਨਵਾਂ ਬਣਾਉਣ ਲਈ ਆਪਣੀ ਸਟ੍ਰਿੰਗ ਪੇਸਟ ਕਰੋ</string>\n    <string name=\"code_content\">ਕੋਡ ਸਮੱਗਰੀ</string>\n    <string name=\"scan_qr_code_to_replace_content\">ਖੇਤਰ ਵਿੱਚ ਸਮੱਗਰੀ ਨੂੰ ਬਦਲਣ ਲਈ ਕਿਸੇ ਵੀ ਬਾਰਕੋਡ ਨੂੰ ਸਕੈਨ ਕਰੋ, ਜਾਂ ਚੁਣੀ ਗਈ ਕਿਸਮ ਦੇ ਨਾਲ ਨਵਾਂ ਬਾਰਕੋਡ ਬਣਾਉਣ ਲਈ ਕੁਝ ਟਾਈਪ ਕਰੋ</string>\n    <string name=\"qr_description\">QR ਵਰਣਨ</string>\n    <string name=\"min\">ਘੱਟੋ-ਘੱਟ</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR ਕੋਡ ਨੂੰ ਸਕੈਨ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਕੈਮਰੇ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">ਦਸਤਾਵੇਜ਼ ਸਕੈਨਰ ਨੂੰ ਸਕੈਨ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਕੈਮਰਾ ਇਜਾਜ਼ਤ ਦਿਓ</string>\n    <string name=\"cubic\">ਘਣ</string>\n    <string name=\"bspline\">ਬੀ-ਸਪਲਾਈਨ</string>\n    <string name=\"hamming\">ਹੈਮਿੰਗ</string>\n    <string name=\"hanning\">ਹੈਨਿੰਗ</string>\n    <string name=\"blackman\">ਬਲੈਕਮੈਨ</string>\n    <string name=\"welch\">ਵੈਲਚ</string>\n    <string name=\"quadric\">ਚਤੁਰਭੁਜ</string>\n    <string name=\"gaussian\">ਗੌਸੀ</string>\n    <string name=\"sphinx\">ਸਪਿੰਕਸ</string>\n    <string name=\"bartlett\">ਬਾਰਟਲੇਟ</string>\n    <string name=\"robidoux\">ਰੋਬੀਡੌਕਸ</string>\n    <string name=\"robidoux_sharp\">ਰੋਬੀਡੌਕਸ ਸ਼ਾਰਪ</string>\n    <string name=\"spline16\">ਸਪਲਾਈਨ 16</string>\n    <string name=\"spline36\">ਸਪਲਾਈਨ 36</string>\n    <string name=\"spline64\">ਸਪਲਾਈਨ 64</string>\n    <string name=\"kaiser\">ਕੈਸਰ</string>\n    <string name=\"bartlett_hann\">ਬਾਰਟਲੇਟ-ਉਹ</string>\n    <string name=\"box\">ਬਾਕਸ</string>\n    <string name=\"bohman\">ਬੋਹਮਨ</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 ਜਿਨਕ</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 ਜਿਨਕ</string>\n    <string name=\"cubic_sub\">ਕਿਊਬਿਕ ਇੰਟਰਪੋਲੇਸ਼ਨ ਸਭ ਤੋਂ ਨਜ਼ਦੀਕੀ 16 ਪਿਕਸਲਾਂ \\'ਤੇ ਵਿਚਾਰ ਕਰਕੇ ਨਿਰਵਿਘਨ ਸਕੇਲਿੰਗ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ, ਬਾਇਲੀਨੀਅਰ ਨਾਲੋਂ ਵਧੀਆ ਨਤੀਜੇ ਦਿੰਦਾ ਹੈ</string>\n    <string name=\"bspline_sub\">ਇੱਕ ਵਕਰ ਜਾਂ ਸਤਹ, ਲਚਕਦਾਰ ਅਤੇ ਨਿਰੰਤਰ ਸ਼ਕਲ ਦੀ ਨੁਮਾਇੰਦਗੀ ਨੂੰ ਸੁਚਾਰੂ ਰੂਪ ਵਿੱਚ ਇੰਟਰਪੋਲੇਟ ਕਰਨ ਅਤੇ ਅਨੁਮਾਨਿਤ ਕਰਨ ਲਈ ਟੁਕੜੇ-ਵਾਰ-ਪਰਿਭਾਸ਼ਿਤ ਬਹੁਪਦ ਫੰਕਸ਼ਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"hamming_sub\">ਇੱਕ ਵਿੰਡੋ ਫੰਕਸ਼ਨ ਇੱਕ ਸਿਗਨਲ ਦੇ ਕਿਨਾਰਿਆਂ ਨੂੰ ਟੇਪਰ ਕਰਕੇ ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਨੂੰ ਘਟਾਉਣ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ, ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਵਿੱਚ ਉਪਯੋਗੀ</string>\n    <string name=\"hanning_sub\">ਹੈਨ ਵਿੰਡੋ ਦਾ ਇੱਕ ਰੂਪ, ਆਮ ਤੌਰ \\'ਤੇ ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਿੱਚ ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਨੂੰ ਘਟਾਉਣ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ</string>\n    <string name=\"blackman_sub\">ਇੱਕ ਵਿੰਡੋ ਫੰਕਸ਼ਨ ਜੋ ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਨੂੰ ਘੱਟ ਕਰਕੇ ਵਧੀਆ ਬਾਰੰਬਾਰਤਾ ਰੈਜ਼ੋਲੂਸ਼ਨ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ, ਅਕਸਰ ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਵਿੱਚ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ</string>\n    <string name=\"welch_sub\">ਇੱਕ ਵਿੰਡੋ ਫੰਕਸ਼ਨ ਜੋ ਘੱਟ ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਦੇ ਨਾਲ ਵਧੀਆ ਬਾਰੰਬਾਰਤਾ ਰੈਜ਼ੋਲੂਸ਼ਨ ਦੇਣ ਲਈ ਤਿਆਰ ਕੀਤਾ ਗਿਆ ਹੈ, ਅਕਸਰ ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਿੱਚ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ</string>\n    <string name=\"quadric_sub\">ਇੱਕ ਵਿਧੀ ਜੋ ਇੰਟਰਪੋਲੇਸ਼ਨ ਲਈ ਇੱਕ ਚਤੁਰਭੁਜ ਫੰਕਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ, ਨਿਰਵਿਘਨ ਅਤੇ ਨਿਰੰਤਰ ਨਤੀਜੇ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ</string>\n    <string name=\"gaussian_sub\">ਇੱਕ ਇੰਟਰਪੋਲੇਸ਼ਨ ਵਿਧੀ ਜੋ ਇੱਕ ਗੌਸੀ ਫੰਕਸ਼ਨ ਨੂੰ ਲਾਗੂ ਕਰਦੀ ਹੈ, ਚਿੱਤਰਾਂ ਵਿੱਚ ਸ਼ੋਰ ਨੂੰ ਸੁਚਾਰੂ ਬਣਾਉਣ ਅਤੇ ਘਟਾਉਣ ਲਈ ਉਪਯੋਗੀ</string>\n    <string name=\"sphinx_sub\">ਇੱਕ ਉੱਨਤ ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ</string>\n    <string name=\"bartlett_sub\">ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਨੂੰ ਘਟਾਉਣ ਲਈ ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਵਿੱਚ ਵਰਤਿਆ ਜਾਂਦਾ ਇੱਕ ਤਿਕੋਣੀ ਵਿੰਡੋ ਫੰਕਸ਼ਨ</string>\n    <string name=\"robidoux_sub\">ਇੱਕ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਵਿਧੀ ਜੋ ਕੁਦਰਤੀ ਚਿੱਤਰ ਨੂੰ ਮੁੜ ਆਕਾਰ ਦੇਣ, ਤਿੱਖਾਪਨ ਅਤੇ ਨਿਰਵਿਘਨਤਾ ਨੂੰ ਸੰਤੁਲਿਤ ਕਰਨ ਲਈ ਅਨੁਕੂਲ ਹੈ</string>\n    <string name=\"robidoux_sharp_sub\">ਰੋਬੀਡੌਕਸ ਵਿਧੀ ਦਾ ਇੱਕ ਤਿੱਖਾ ਰੂਪ, ਕਰਿਸਪ ਚਿੱਤਰ ਨੂੰ ਮੁੜ ਆਕਾਰ ਦੇਣ ਲਈ ਅਨੁਕੂਲਿਤ</string>\n    <string name=\"spline16_sub\">ਇੱਕ ਸਪਲਾਈਨ-ਅਧਾਰਿਤ ਇੰਟਰਪੋਲੇਸ਼ਨ ਵਿਧੀ ਜੋ 16-ਟੈਪ ਫਿਲਟਰ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਨਿਰਵਿਘਨ ਨਤੀਜੇ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ</string>\n    <string name=\"spline36_sub\">ਇੱਕ ਸਪਲਾਈਨ-ਅਧਾਰਿਤ ਇੰਟਰਪੋਲੇਸ਼ਨ ਵਿਧੀ ਜੋ 36-ਟੈਪ ਫਿਲਟਰ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਨਿਰਵਿਘਨ ਨਤੀਜੇ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ</string>\n    <string name=\"spline64_sub\">ਇੱਕ ਸਪਲਾਈਨ-ਅਧਾਰਿਤ ਇੰਟਰਪੋਲੇਸ਼ਨ ਵਿਧੀ ਜੋ 64-ਟੈਪ ਫਿਲਟਰ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਨਿਰਵਿਘਨ ਨਤੀਜੇ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ</string>\n    <string name=\"kaiser_sub\">ਇੱਕ ਇੰਟਰਪੋਲੇਸ਼ਨ ਵਿਧੀ ਜੋ ਕੈਸਰ ਵਿੰਡੋ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ, ਮੁੱਖ-ਲੋਬ ਚੌੜਾਈ ਅਤੇ ਸਾਈਡ-ਲੋਬ ਪੱਧਰ ਦੇ ਵਿਚਕਾਰ ਵਪਾਰ-ਬੰਦ \\'ਤੇ ਚੰਗਾ ਨਿਯੰਤਰਣ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ।</string>\n    <string name=\"bartlett_hann_sub\">ਬਾਰਟਲੇਟ ਅਤੇ ਹੈਨ ਵਿੰਡੋਜ਼ ਨੂੰ ਜੋੜਦਾ ਇੱਕ ਹਾਈਬ੍ਰਿਡ ਵਿੰਡੋ ਫੰਕਸ਼ਨ, ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਵਿੱਚ ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਨੂੰ ਘਟਾਉਣ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ</string>\n    <string name=\"box_sub\">ਇੱਕ ਸਧਾਰਨ ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਨਜ਼ਦੀਕੀ ਪਿਕਸਲ ਮੁੱਲਾਂ ਦੀ ਔਸਤ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ, ਅਕਸਰ ਇੱਕ ਬਲਾਕੀ ਦਿੱਖ ਦੇ ਨਤੀਜੇ ਵਜੋਂ</string>\n    <string name=\"bohman_sub\">ਇੱਕ ਵਿੰਡੋ ਫੰਕਸ਼ਨ ਸਪੈਕਟ੍ਰਲ ਲੀਕੇਜ ਨੂੰ ਘਟਾਉਣ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ, ਸਿਗਨਲ ਪ੍ਰੋਸੈਸਿੰਗ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਿੱਚ ਵਧੀਆ ਬਾਰੰਬਾਰਤਾ ਰੈਜ਼ੋਲੂਸ਼ਨ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ</string>\n    <string name=\"lanczos2_sub\">ਇੱਕ ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਲਈ 2-ਲੋਬ ਲੈਂਕਜ਼ੋਸ ਫਿਲਟਰ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ</string>\n    <string name=\"lanczos3_sub\">ਇੱਕ ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਲਈ 3-ਲੋਬ ਲੈਂਕਜ਼ੋਸ ਫਿਲਟਰ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ</string>\n    <string name=\"lanczos4_sub\">ਇੱਕ ਰੀਸੈਪਲਿੰਗ ਵਿਧੀ ਜੋ ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਲਈ 4-ਲੋਬ ਲੈਂਕਜ਼ੋਸ ਫਿਲਟਰ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ</string>\n    <string name=\"lanczos2_jinc_sub\">Lanczos 2 ਫਿਲਟਰ ਦਾ ਇੱਕ ਰੂਪ ਜੋ ਕਿ ਜਿੰਕ ਫੰਕਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ</string>\n    <string name=\"lanczos3_jinc_sub\">Lanczos 3 ਫਿਲਟਰ ਦਾ ਇੱਕ ਰੂਪ ਜੋ ਜਿੰਕ ਫੰਕਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ</string>\n    <string name=\"lanczos4_jinc_sub\">Lanczos 4 ਫਿਲਟਰ ਦਾ ਇੱਕ ਰੂਪ ਜੋ ਜਿੰਕ ਫੰਕਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਇੰਟਰਪੋਲੇਸ਼ਨ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ</string>\n    <string name=\"ewa_hanning\">ਹੈਨਿੰਗ EWA</string>\n    <string name=\"ewa_hanning_sub\">ਨਿਰਵਿਘਨ ਇੰਟਰਪੋਲੇਸ਼ਨ ਅਤੇ ਰੀਸੈਪਲਿੰਗ ਲਈ ਹੈਨਿੰਗ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">ਉੱਚ-ਗੁਣਵੱਤਾ ਦੇ ਰੀਸੈਪਲਿੰਗ ਲਈ ਰੋਬਿਡੌਕਸ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_blackman\">ਬਲੈਕਮੈਨ ਈ.ਵੀ</string>\n    <string name=\"ewa_blackman_sub\">ਰਿੰਗਿੰਗ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਘੱਟ ਤੋਂ ਘੱਟ ਕਰਨ ਲਈ ਬਲੈਕਮੈਨ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">ਨਿਰਵਿਘਨ ਇੰਟਰਪੋਲੇਸ਼ਨ ਲਈ ਕਵਾਡ੍ਰਿਕ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਵੇਟਿਡ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_robidoux_sharp\">ਰੋਬਿਡੌਕਸ ਸ਼ਾਰਪ EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">ਤਿੱਖੇ ਨਤੀਜਿਆਂ ਲਈ ਰੋਬਿਡੌਕਸ ਸ਼ਾਰਪ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">ਲੈਂਕਜ਼ੋਸ 3 ਜਿੰਕ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਵੇਟਿਡ ਔਸਤ (EWA) ਵੇਰੀਐਂਟ ਘੱਟ ਅਲੀਅਸਿੰਗ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਦੇ ਰੀਸੈਪਲਿੰਗ ਲਈ</string>\n    <string name=\"ginseng\">ਜਿਨਸੇਂਗ</string>\n    <string name=\"ginseng_sub\">ਤਿੱਖਾਪਨ ਅਤੇ ਨਿਰਵਿਘਨਤਾ ਦੇ ਚੰਗੇ ਸੰਤੁਲਨ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਚਿੱਤਰ ਪ੍ਰੋਸੈਸਿੰਗ ਲਈ ਤਿਆਰ ਕੀਤਾ ਗਿਆ ਇੱਕ ਰੀਸੈਪਲਿੰਗ ਫਿਲਟਰ</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">ਵਿਸਤ੍ਰਿਤ ਚਿੱਤਰ ਗੁਣਵੱਤਾ ਲਈ ਜਿਨਸੇਂਗ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਤਿੱਖੇ ਨਤੀਜੇ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਲੈਂਕਜ਼ੋਸ ਸ਼ਾਰਪ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 ਤਿੱਖਾ EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">ਬਹੁਤ ਹੀ ਤਿੱਖੀ ਚਿੱਤਰ ਰੀਸੈਪਲਿੰਗ ਲਈ ਲੈਂਕਜ਼ੋਸ 4 ਸ਼ਾਰਪਸਟ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos ਸਾਫਟ EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">ਨਿਰਵਿਘਨ ਚਿੱਤਰ ਰੀਸੈਪਲਿੰਗ ਲਈ ਲੈਂਕਜ਼ੋਸ ਸਾਫਟ ਫਿਲਟਰ ਦਾ ਅੰਡਾਕਾਰ ਭਾਰ ਵਾਲਾ ਔਸਤ (EWA) ਰੂਪ</string>\n    <string name=\"haasn_soft\">ਹਸਨ ਨਰਮ</string>\n    <string name=\"haasn_soft_sub\">ਨਿਰਵਿਘਨ ਅਤੇ ਕਲਾਤਮਕ-ਮੁਕਤ ਚਿੱਤਰ ਸਕੇਲਿੰਗ ਲਈ ਹਾਸਨ ਦੁਆਰਾ ਤਿਆਰ ਕੀਤਾ ਗਿਆ ਇੱਕ ਰੀਸੈਪਲਿੰਗ ਫਿਲਟਰ</string>\n    <string name=\"format_conversion\">ਫਾਰਮੈਟ ਰੂਪਾਂਤਰਨ</string>\n    <string name=\"format_conversion_sub\">ਚਿੱਤਰਾਂ ਦੇ ਬੈਚ ਨੂੰ ਇੱਕ ਫਾਰਮੈਟ ਤੋਂ ਦੂਜੇ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"dismiss_forever\">ਹਮੇਸ਼ਾ ਲਈ ਖਾਰਜ ਕਰੋ</string>\n    <string name=\"image_stacking\">ਚਿੱਤਰ ਸਟੈਕਿੰਗ</string>\n    <string name=\"image_stacking_sub\">ਚੁਣੇ ਹੋਏ ਮਿਸ਼ਰਣ ਮੋਡਾਂ ਨਾਲ ਚਿੱਤਰਾਂ ਨੂੰ ਇੱਕ ਦੂਜੇ ਦੇ ਸਿਖਰ \\'ਤੇ ਸਟੈਕ ਕਰੋ</string>\n    <string name=\"add_image\">ਚਿੱਤਰ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"bins_count\">ਡੱਬਿਆਂ ਦੀ ਗਿਣਤੀ</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">ਹਿਸਟੋਗ੍ਰਾਮ ਅਡੈਪਟਿਵ HSL ਨੂੰ ਬਰਾਬਰ ਬਣਾਓ</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">ਹਿਸਟੋਗ੍ਰਾਮ ਅਡੈਪਟਿਵ HSV ਨੂੰ ਬਰਾਬਰ ਬਣਾਓ</string>\n    <string name=\"edge_mode\">ਕਿਨਾਰਾ ਮੋਡ</string>\n    <string name=\"clip\">ਕਲਿੱਪ</string>\n    <string name=\"wrap\">ਲਪੇਟ</string>\n    <string name=\"color_blind_scheme\">ਰੰਗ ਅੰਨ੍ਹਾਪਨ</string>\n    <string name=\"color_blind_scheme_sub\">ਚੁਣੇ ਗਏ ਰੰਗ ਅੰਨ੍ਹੇਪਣ ਰੂਪ ਲਈ ਥੀਮ ਦੇ ਰੰਗਾਂ ਨੂੰ ਅਨੁਕੂਲ ਬਣਾਉਣ ਲਈ ਮੋਡ ਚੁਣੋ</string>\n    <string name=\"protanomaly_sub\">ਲਾਲ ਅਤੇ ਹਰੇ ਰੰਗ ਦੇ ਵਿਚਕਾਰ ਫਰਕ ਕਰਨ ਵਿੱਚ ਮੁਸ਼ਕਲ</string>\n    <string name=\"deuteranomaly_sub\">ਹਰੇ ਅਤੇ ਲਾਲ ਰੰਗਾਂ ਵਿੱਚ ਫਰਕ ਕਰਨ ਵਿੱਚ ਮੁਸ਼ਕਲ</string>\n    <string name=\"tritanomaly_sub\">ਨੀਲੇ ਅਤੇ ਪੀਲੇ ਰੰਗਾਂ ਵਿੱਚ ਫਰਕ ਕਰਨ ਵਿੱਚ ਮੁਸ਼ਕਲ</string>\n    <string name=\"protanopia_sub\">ਲਾਲ ਰੰਗਾਂ ਨੂੰ ਸਮਝਣ ਵਿੱਚ ਅਸਮਰੱਥਾ</string>\n    <string name=\"deuteranopia_sub\">ਹਰੇ ਰੰਗ ਨੂੰ ਸਮਝਣ ਵਿੱਚ ਅਸਮਰੱਥਾ</string>\n    <string name=\"tritanopia_sub\">ਨੀਲੇ ਰੰਗ ਨੂੰ ਸਮਝਣ ਵਿੱਚ ਅਸਮਰੱਥਾ</string>\n    <string name=\"achromatomaly_sub\">ਸਾਰੇ ਰੰਗਾਂ ਪ੍ਰਤੀ ਘੱਟ ਸੰਵੇਦਨਸ਼ੀਲਤਾ</string>\n    <string name=\"achromatopsia_sub\">ਸੰਪੂਰਨ ਰੰਗ ਅੰਨ੍ਹਾਪਣ, ਸਿਰਫ ਸਲੇਟੀ ਰੰਗਾਂ ਨੂੰ ਵੇਖਣਾ</string>\n    <string name=\"not_use_color_blind_scheme\">ਕਲਰ ਬਲਾਇੰਡ ਸਕੀਮ ਦੀ ਵਰਤੋਂ ਨਾ ਕਰੋ</string>\n    <string name=\"not_use_color_blind_scheme_sub\">ਰੰਗ ਬਿਲਕੁਲ ਉਸੇ ਤਰ੍ਹਾਂ ਹੋਣਗੇ ਜਿਵੇਂ ਥੀਮ ਵਿੱਚ ਸੈੱਟ ਕੀਤਾ ਗਿਆ ਹੈ</string>\n    <string name=\"sigmoidal\">ਸਿਗਮੋਇਡਲ</string>\n    <string name=\"lagrange_2\">ਲਾਗਰੇਂਜ ੨</string>\n    <string name=\"lagrange_2_sub\">ਆਰਡਰ 2 ਦਾ ਇੱਕ ਲੈਗਰੇਂਜ ਇੰਟਰਪੋਲੇਸ਼ਨ ਫਿਲਟਰ, ਨਿਰਵਿਘਨ ਤਬਦੀਲੀਆਂ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਚਿੱਤਰ ਸਕੇਲਿੰਗ ਲਈ ਢੁਕਵਾਂ</string>\n    <string name=\"lagrange_3\">ਲਾਗਰੇਂਜ ੩</string>\n    <string name=\"lagrange_3_sub\">ਆਰਡਰ 3 ਦਾ ਇੱਕ ਲੈਗਰੇਂਜ ਇੰਟਰਪੋਲੇਸ਼ਨ ਫਿਲਟਰ, ਚਿੱਤਰ ਸਕੇਲਿੰਗ ਲਈ ਬਿਹਤਰ ਸ਼ੁੱਧਤਾ ਅਤੇ ਨਿਰਵਿਘਨ ਨਤੀਜੇ ਪੇਸ਼ ਕਰਦਾ ਹੈ</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">6 ਦੇ ਉੱਚ ਆਰਡਰ ਦੇ ਨਾਲ ਇੱਕ ਲੈਂਕਜ਼ੋਸ ਰੀਸੈਪਲਿੰਗ ਫਿਲਟਰ, ਤਿੱਖਾ ਅਤੇ ਵਧੇਰੇ ਸਹੀ ਚਿੱਤਰ ਸਕੇਲਿੰਗ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 ਜਿਨਕ</string>\n    <string name=\"lanczos_6_jinc_sub\">ਬਿਹਤਰ ਚਿੱਤਰ ਰੀਸੈਪਲਿੰਗ ਕੁਆਲਿਟੀ ਲਈ ਜਿਨਕ ਫੰਕਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਲੈਂਕਜ਼ੋਸ 6 ਫਿਲਟਰ ਦਾ ਇੱਕ ਰੂਪ</string>\n    <string name=\"linear_box_blur\">ਲੀਨੀਅਰ ਬਾਕਸ ਬਲਰ</string>\n    <string name=\"linear_tent_blur\">ਰੇਖਿਕ ਟੈਂਟ ਬਲਰ</string>\n    <string name=\"linear_gaussian_box_blur\">ਰੇਖਿਕ ਗੌਸੀ ਬਾਕਸ ਬਲਰ</string>\n    <string name=\"linear_stack_blur\">ਰੇਖਿਕ ਸਟੈਕ ਬਲਰ</string>\n    <string name=\"gaussian_box_blur\">ਗੌਸੀ ਬਾਕਸ ਬਲਰ</string>\n    <string name=\"linear_fast_gaussian_blur_next\">ਰੇਖਿਕ ਤੇਜ਼ ਗੌਸੀਅਨ ਬਲਰ ਅੱਗੇ</string>\n    <string name=\"linear_fast_gaussian_blur\">ਰੇਖਿਕ ਤੇਜ਼ ਗੌਸੀ ਬਲਰ</string>\n    <string name=\"linear_gaussian_blur\">ਰੇਖਿਕ ਗੌਸੀ ਬਲਰ</string>\n    <string name=\"draw_filter_sub\">ਇਸ ਨੂੰ ਪੇਂਟ ਵਜੋਂ ਵਰਤਣ ਲਈ ਇੱਕ ਫਿਲਟਰ ਚੁਣੋ</string>\n    <string name=\"replace_filter\">ਫਿਲਟਰ ਬਦਲੋ</string>\n    <string name=\"pick_filter_info\">ਇਸ ਨੂੰ ਆਪਣੀ ਡਰਾਇੰਗ ਵਿੱਚ ਬੁਰਸ਼ ਵਜੋਂ ਵਰਤਣ ਲਈ ਹੇਠਾਂ ਫਿਲਟਰ ਚੁਣੋ</string>\n    <string name=\"tiff_compression_scheme\">TIFF ਕੰਪਰੈਸ਼ਨ ਸਕੀਮ</string>\n    <string name=\"low_poly\">ਘੱਟ ਪੌਲੀ</string>\n    <string name=\"sand_painting\">ਰੇਤ ਪੇਂਟਿੰਗ</string>\n    <string name=\"image_splitting\">ਚਿੱਤਰ ਵੰਡਣਾ</string>\n    <string name=\"image_splitting_sub\">ਇੱਕ ਚਿੱਤਰ ਨੂੰ ਕਤਾਰਾਂ ਜਾਂ ਕਾਲਮਾਂ ਦੁਆਰਾ ਵੰਡੋ</string>\n    <string name=\"fit_to_bounds\">ਸੀਮਾਵਾਂ ਲਈ ਫਿੱਟ</string>\n    <string name=\"fit_to_bounds_sub\">ਲੋੜੀਂਦੇ ਵਿਵਹਾਰ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਇਸ ਪੈਰਾਮੀਟਰ ਦੇ ਨਾਲ ਕ੍ਰੌਪ ਰੀਸਾਈਜ਼ ਮੋਡ ਨੂੰ ਜੋੜੋ (ਪਹਿਲੂ ਅਨੁਪਾਤ ਲਈ ਕ੍ਰੌਪ/ਫਿੱਟ)</string>\n    <string name=\"languages_imported\">ਭਾਸ਼ਾਵਾਂ ਸਫਲਤਾਪੂਰਵਕ ਆਯਾਤ ਕੀਤੀਆਂ ਗਈਆਂ</string>\n    <string name=\"backup_ocr_models\">ਬੈਕਅੱਪ OCR ਮਾਡਲ</string>\n    <string name=\"import_word\">ਆਯਾਤ ਕਰੋ</string>\n    <string name=\"export\">ਨਿਰਯਾਤ</string>\n    <string name=\"position\">ਸਥਿਤੀ</string>\n    <string name=\"center\">ਕੇਂਦਰ</string>\n    <string name=\"top_left\">ਉੱਪਰ ਖੱਬੇ</string>\n    <string name=\"top_right\">ਉੱਪਰ ਸੱਜੇ</string>\n    <string name=\"bottom_left\">ਹੇਠਾਂ ਖੱਬੇ ਪਾਸੇ</string>\n    <string name=\"bottom_right\">ਹੇਠਾਂ ਸੱਜੇ</string>\n    <string name=\"top_center\">ਸਿਖਰ ਕੇਂਦਰ</string>\n    <string name=\"center_right\">ਕੇਂਦਰ ਦਾ ਸੱਜਾ</string>\n    <string name=\"bottom_center\">ਹੇਠਲਾ ਕੇਂਦਰ</string>\n    <string name=\"center_left\">ਸੈਂਟਰ ਖੱਬੇ</string>\n    <string name=\"target_image\">ਨਿਸ਼ਾਨਾ ਚਿੱਤਰ</string>\n    <string name=\"palette_transfer\">ਪੈਲੇਟ ਟ੍ਰਾਂਸਫਰ</string>\n    <string name=\"enhanced_oil\">ਵਧਿਆ ਤੇਲ</string>\n    <string name=\"simple_old_tv\">ਸਧਾਰਨ ਪੁਰਾਣਾ ਟੀ.ਵੀ</string>\n    <string name=\"hdr\">ਐਚ.ਡੀ.ਆਰ</string>\n    <string name=\"gotham\">ਗੋਥਮ</string>\n    <string name=\"simple_sketch\">ਸਧਾਰਨ ਸਕੈਚ</string>\n    <string name=\"soft_glow\">ਨਰਮ ਗਲੋ</string>\n    <string name=\"color_poster\">ਰੰਗ ਪੋਸਟਰ</string>\n    <string name=\"tri_tone\">ਟ੍ਰਾਈ ਟੋਨ</string>\n    <string name=\"third_color\">ਤੀਜਾ ਰੰਗ</string>\n    <string name=\"clahe_oklab\">ਕਲੇਹ ਓਕਲਾਬ</string>\n    <string name=\"clahe_oklch\">ਕਲਾਰਾ ਓਲਚ</string>\n    <string name=\"clahe_jzazbz\">ਕਲੇਹ ਜਜ਼ਬਜ਼</string>\n    <string name=\"polka_dot\">ਪੋਲਕਾ ਡਾਟ</string>\n    <string name=\"clustered_2x2_dithering\">ਕਲੱਸਟਰਡ 2x2 ਡਿਥਰਿੰਗ</string>\n    <string name=\"clustered_4x4_dithering\">ਕਲੱਸਟਰਡ 4x4 ਡਿਥਰਿੰਗ</string>\n    <string name=\"clustered_8x8_dithering\">ਕਲੱਸਟਰਡ 8x8 ਡਿਥਰਿੰਗ</string>\n    <string name=\"yililoma_dithering\">ਯਿਲੀਲੋਮਾ ਡਿਥਰਿੰਗ</string>\n    <string name=\"no_favorite_options_selected\">ਕੋਈ ਪਸੰਦੀਦਾ ਵਿਕਲਪ ਨਹੀਂ ਚੁਣਿਆ ਗਿਆ, ਉਹਨਾਂ ਨੂੰ ਟੂਲਸ ਪੰਨੇ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_favorites\">ਮਨਪਸੰਦ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"harmony_complementary\">ਪੂਰਕ</string>\n    <string name=\"harmony_analogous\">ਅਨੁਰੂਪ</string>\n    <string name=\"harmony_triadic\">ਤ੍ਰਿਯਾਦਿਕ</string>\n    <string name=\"harmony_split_complementary\">ਸਪਲਿਟ ਪੂਰਕ</string>\n    <string name=\"harmony_tetradic\">ਟੈਟਰਾਡਿਕ</string>\n    <string name=\"harmony_square\">ਵਰਗ</string>\n    <string name=\"harmony_analogous_complementary\">ਸਮਾਨ + ਪੂਰਕ</string>\n    <string name=\"color_tools\">ਰੰਗ ਸੰਦ</string>\n    <string name=\"color_tools_sub\">ਮਿਕਸ ਕਰੋ, ਟੋਨ ਬਣਾਓ, ਸ਼ੇਡ ਬਣਾਓ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ</string>\n    <string name=\"color_harmonies\">ਰੰਗ ਹਾਰਮੋਨੀਜ਼</string>\n    <string name=\"color_shading\">ਰੰਗ ਦੀ ਛਾਂ</string>\n    <string name=\"variation\">ਪਰਿਵਰਤਨ</string>\n    <string name=\"tints\">ਟਿੰਟਸ</string>\n    <string name=\"tones\">ਟੋਨਸ</string>\n    <string name=\"shades\">ਸ਼ੇਡਜ਼</string>\n    <string name=\"color_mixing\">ਰੰਗ ਮਿਕਸਿੰਗ</string>\n    <string name=\"color_info\">ਰੰਗ ਜਾਣਕਾਰੀ</string>\n    <string name=\"selected_color\">ਚੁਣਿਆ ਰੰਗ</string>\n    <string name=\"color_to_mix\">ਮਿਕਸ ਕਰਨ ਲਈ ਰੰਗ</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">ਡਾਇਨਾਮਿਕ ਰੰਗ ਚਾਲੂ ਹੋਣ \\'ਤੇ ਮੋਨੇਟ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">ਟੀਚਾ LUT ਚਿੱਤਰ</string>\n    <string name=\"amatorka\">ਇੱਕ ਸ਼ੁਕੀਨ</string>\n    <string name=\"miss_etikate\">ਮਿਸ ਸ਼ਿਸ਼ਟਾਚਾਰ</string>\n    <string name=\"soft_elegance\">ਨਰਮ ਸੁੰਦਰਤਾ</string>\n    <string name=\"soft_elegance_variant\">ਸਾਫਟ ਐਲੀਗੈਂਸ ਵੇਰੀਐਂਟ</string>\n    <string name=\"palette_transfer_variant\">ਪੈਲੇਟ ਟ੍ਰਾਂਸਫਰ ਵੇਰੀਐਂਟ</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">ਟਾਰਗੇਟ 3D LUT ਫਾਈਲ (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">ਬਲੀਚ ਬਾਈਪਾਸ</string>\n    <string name=\"candlelight\">ਮੋਮਬੱਤੀ ਦੀ ਰੌਸ਼ਨੀ</string>\n    <string name=\"drop_blues\">ਬਲੂਜ਼ ਸੁੱਟੋ</string>\n    <string name=\"edgy_amber\">ਐਡੀ ਅੰਬਰ</string>\n    <string name=\"fall_colors\">ਪਤਝੜ ਦੇ ਰੰਗ</string>\n    <string name=\"film_stock_50\">ਫਿਲਮ ਸਟਾਕ 50</string>\n    <string name=\"foggy_night\">ਧੁੰਦ ਵਾਲੀ ਰਾਤ</string>\n    <string name=\"kodak\">ਕੋਡਕ</string>\n    <string name=\"save_empty_lut\">ਨਿਰਪੱਖ LUT ਚਿੱਤਰ ਪ੍ਰਾਪਤ ਕਰੋ</string>\n    <string name=\"save_empty_lut_sub\">ਪਹਿਲਾਂ, ਨਿਰਪੱਖ LUT \\'ਤੇ ਫਿਲਟਰ ਲਗਾਉਣ ਲਈ ਆਪਣੀ ਮਨਪਸੰਦ ਫੋਟੋ ਸੰਪਾਦਨ ਐਪਲੀਕੇਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰੋ ਜੋ ਤੁਸੀਂ ਇੱਥੇ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ। ਇਸਦੇ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਕਰਨ ਲਈ ਹਰੇਕ ਪਿਕਸਲ ਦਾ ਰੰਗ ਦੂਜੇ ਪਿਕਸਲਾਂ \\'ਤੇ ਨਿਰਭਰ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ (ਜਿਵੇਂ ਕਿ ਬਲਰ ਕੰਮ ਨਹੀਂ ਕਰੇਗਾ)। ਇੱਕ ਵਾਰ ਤਿਆਰ ਹੋਣ \\'ਤੇ, 512*512 LUT ਫਿਲਟਰ ਲਈ ਆਪਣੀ ਨਵੀਂ LUT ਚਿੱਤਰ ਨੂੰ ਇਨਪੁਟ ਵਜੋਂ ਵਰਤੋ</string>\n    <string name=\"pop_art\">ਪੌਪ ਆਰਟ</string>\n    <string name=\"celluloid\">ਸੈਲੂਲੋਇਡ</string>\n    <string name=\"coffee\">ਕਾਫੀ</string>\n    <string name=\"golden_forest\">ਸੁਨਹਿਰੀ ਜੰਗਲ</string>\n    <string name=\"greenish\">ਹਰਿਆਲੀ</string>\n    <string name=\"retro_yellow\">ਰੀਟਰੋ ਪੀਲਾ</string>\n    <string name=\"links_preview\">ਲਿੰਕ ਪੂਰਵਦਰਸ਼ਨ</string>\n    <string name=\"links_preview_sub\">ਉਹਨਾਂ ਥਾਵਾਂ \\'ਤੇ ਲਿੰਕ ਪੂਰਵਦਰਸ਼ਨ ਨੂੰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ ਜਿੱਥੇ ਤੁਸੀਂ ਟੈਕਸਟ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ (QRCode, OCR ਆਦਿ)</string>\n    <string name=\"links\">ਲਿੰਕ</string>\n    <string name=\"ico_size_warning\">ICO ਫਾਈਲਾਂ ਨੂੰ ਸਿਰਫ 256 x 256 ਦੇ ਅਧਿਕਤਮ ਆਕਾਰ \\'ਤੇ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ</string>\n    <string name=\"gif_type_to_webp\">WEBP ਨੂੰ GIF</string>\n    <string name=\"gif_type_to_webp_sub\">GIF ਚਿੱਤਰਾਂ ਨੂੰ WEBP ਐਨੀਮੇਟਡ ਤਸਵੀਰਾਂ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"webp_tools\">WEBP ਟੂਲ</string>\n    <string name=\"webp_tools_sub\">ਚਿੱਤਰਾਂ ਨੂੰ WEBP ਐਨੀਮੇਟਡ ਤਸਵੀਰ ਵਿੱਚ ਬਦਲੋ ਜਾਂ ਦਿੱਤੇ ਗਏ WEBP ਐਨੀਮੇਸ਼ਨ ਤੋਂ ਫਰੇਮਾਂ ਨੂੰ ਐਕਸਟਰੈਕਟ ਕਰੋ</string>\n    <string name=\"webp_type_to_image\">ਚਿੱਤਰਾਂ ਲਈ WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP ਫਾਈਲ ਨੂੰ ਤਸਵੀਰਾਂ ਦੇ ਬੈਚ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"webp_type_to_webp_sub\">ਚਿੱਤਰਾਂ ਦੇ ਬੈਚ ਨੂੰ WEBP ਫਾਈਲ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"webp_type_to_webp\">WEBP ਲਈ ਚਿੱਤਰ</string>\n    <string name=\"select_webp_image_to_start\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ WEBP ਚਿੱਤਰ ਚੁਣੋ</string>\n    <string name=\"manage_storage_extra_types\">ਫਾਈਲਾਂ ਤੱਕ ਪੂਰੀ ਪਹੁੰਚ ਨਹੀਂ ਹੈ</string>\n    <string name=\"manage_storage_extra_types_sub\">ਸਾਰੀਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ JXL, QOI ਅਤੇ ਹੋਰ ਚਿੱਤਰਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਪਹੁੰਚ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ ਜੋ Android \\'ਤੇ ਚਿੱਤਰਾਂ ਵਜੋਂ ਨਹੀਂ ਪਛਾਣੀਆਂ ਗਈਆਂ ਹਨ। ਇਜਾਜ਼ਤ ਤੋਂ ਬਿਨਾਂ ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਉਹਨਾਂ ਚਿੱਤਰਾਂ ਨੂੰ ਦਿਖਾਉਣ ਵਿੱਚ ਅਸਮਰੱਥ ਹੈ</string>\n    <string name=\"default_draw_color\">ਡਿਫੌਲਟ ਡਰਾਅ ਰੰਗ</string>\n    <string name=\"default_draw_path_mode\">ਡਿਫੌਲਟ ਡਰਾਅ ਮਾਰਗ ਮੋਡ</string>\n    <string name=\"add_timestamp\">ਟਾਈਮਸਟੈਂਪ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_timestamp_sub\">ਟਾਈਮਸਟੈਂਪ ਨੂੰ ਆਉਟਪੁੱਟ ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਜੋੜਨ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ</string>\n    <string name=\"formatted_timestamp\">ਫਾਰਮੈਟ ਕੀਤਾ ਟਾਈਮਸਟੈਂਪ</string>\n    <string name=\"formatted_timestamp_sub\">ਮੂਲ ਮਿਲੀਸ ਦੀ ਬਜਾਏ ਆਉਟਪੁੱਟ ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਟਾਈਮਸਟੈਂਪ ਫਾਰਮੈਟਿੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ</string>\n    <string name=\"enable_timestamps_to_format_them\">ਟਾਈਮਸਟੈਂਪਸ ਨੂੰ ਉਹਨਾਂ ਦਾ ਫਾਰਮੈਟ ਚੁਣਨ ਲਈ ਸਮਰੱਥ ਬਣਾਓ</string>\n    <string name=\"one_time_save_location\">ਵਨ ਟਾਈਮ ਸੇਵ ਟਿਕਾਣਾ</string>\n    <string name=\"one_time_save_location_sub\">ਵਨ ਟਾਈਮ ਸੇਵ ਟਿਕਾਣਿਆਂ ਨੂੰ ਦੇਖੋ ਅਤੇ ਸੰਪਾਦਿਤ ਕਰੋ ਜਿਸਦੀ ਵਰਤੋਂ ਤੁਸੀਂ ਜ਼ਿਆਦਾਤਰ ਸਾਰੇ ਵਿਕਲਪਾਂ ਵਿੱਚ ਸੇਵ ਬਟਨ ਨੂੰ ਦਬਾ ਕੇ ਕਰ ਸਕਦੇ ਹੋ</string>\n    <string name=\"recently_used\">ਹਾਲ ਹੀ ਵਿੱਚ ਵਰਤਿਆ ਗਿਆ</string>\n    <string name=\"ci_channel\">ਸੀਆਈ ਚੈਨਲ</string>\n    <string name=\"group\">ਸਮੂਹ</string>\n    <string name=\"image_toolbox_in_telegram\">ਟੈਲੀਗ੍ਰਾਮ 🎉 ਵਿੱਚ ਚਿੱਤਰ ਟੂਲਬਾਕਸ</string>\n    <string name=\"image_toolbox_in_telegram_sub\">ਸਾਡੀ ਚੈਟ ਵਿੱਚ ਸ਼ਾਮਲ ਹੋਵੋ ਜਿੱਥੇ ਤੁਸੀਂ ਕਿਸੇ ਵੀ ਚੀਜ਼ \\'ਤੇ ਚਰਚਾ ਕਰ ਸਕਦੇ ਹੋ ਜੋ ਤੁਸੀਂ ਚਾਹੁੰਦੇ ਹੋ ਅਤੇ CI ਚੈਨਲ ਨੂੰ ਵੀ ਦੇਖ ਸਕਦੇ ਹੋ ਜਿੱਥੇ ਮੈਂ ਬੀਟਾ ਅਤੇ ਘੋਸ਼ਣਾਵਾਂ ਪੋਸਟ ਕਰਦਾ ਹਾਂ</string>\n    <string name=\"ci_channel_sub\">ਐਪ ਦੇ ਨਵੇਂ ਸੰਸਕਰਣਾਂ ਬਾਰੇ ਸੂਚਨਾ ਪ੍ਰਾਪਤ ਕਰੋ, ਅਤੇ ਘੋਸ਼ਣਾਵਾਂ ਪੜ੍ਹੋ</string>\n    <string name=\"fit_description\">ਇੱਕ ਚਿੱਤਰ ਨੂੰ ਦਿੱਤੇ ਮਾਪਾਂ ਵਿੱਚ ਫਿੱਟ ਕਰੋ ਅਤੇ ਬੈਕਗ੍ਰਾਉਂਡ ਵਿੱਚ ਧੁੰਦਲਾ ਜਾਂ ਰੰਗ ਲਾਗੂ ਕਰੋ</string>\n    <string name=\"tools_arrangement\">ਸੰਦ ਪ੍ਰਬੰਧ</string>\n    <string name=\"group_tools_by_type\">ਕਿਸਮ ਦੇ ਅਨੁਸਾਰ ਸਮੂਹ ਟੂਲ</string>\n    <string name=\"group_tools_by_type_sub\">ਇੱਕ ਕਸਟਮ ਸੂਚੀ ਪ੍ਰਬੰਧ ਦੀ ਬਜਾਏ ਉਹਨਾਂ ਦੀ ਕਿਸਮ ਦੁਆਰਾ ਮੁੱਖ ਸਕ੍ਰੀਨ \\'ਤੇ ਸਮੂਹ ਟੂਲਸ</string>\n    <string name=\"default_values\">ਪੂਰਵ-ਨਿਰਧਾਰਤ ਮੁੱਲ</string>\n    <string name=\"system_bars_visibility\">ਸਿਸਟਮ ਬਾਰਾਂ ਦੀ ਦਿੱਖ</string>\n    <string name=\"show_system_bars_by_swipe\">ਸਵਾਈਪ ਦੁਆਰਾ ਸਿਸਟਮ ਬਾਰ ਦਿਖਾਓ</string>\n    <string name=\"show_system_bars_by_swipe_sub\">ਸਿਸਟਮ ਬਾਰਾਂ ਨੂੰ ਦਿਖਾਉਣ ਲਈ ਸਵਾਈਪਿੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ ਜੇਕਰ ਉਹ ਲੁਕੀਆਂ ਹੋਈਆਂ ਹਨ</string>\n    <string name=\"auto\">ਆਟੋ</string>\n    <string name=\"hide_all\">ਸਭ ਲੁਕਾਓ</string>\n    <string name=\"show_all\">ਸਭ ਦਿਖਾਓ</string>\n    <string name=\"hide_nav_bar\">ਨਵ ਬਾਰ ਨੂੰ ਲੁਕਾਓ</string>\n    <string name=\"hide_status_bar\">ਸਥਿਤੀ ਪੱਟੀ ਨੂੰ ਲੁਕਾਓ</string>\n    <string name=\"noise_generation\">ਸ਼ੋਰ ਪੈਦਾ ਕਰਨਾ</string>\n    <string name=\"noise_generation_sub\">ਪਰਲਿਨ ਜਾਂ ਹੋਰ ਕਿਸਮਾਂ ਵਰਗੇ ਵੱਖੋ-ਵੱਖਰੇ ਸ਼ੋਰ ਪੈਦਾ ਕਰੋ</string>\n    <string name=\"frequency\">ਬਾਰੰਬਾਰਤਾ</string>\n    <string name=\"noise_type\">ਸ਼ੋਰ ਦੀ ਕਿਸਮ</string>\n    <string name=\"rotation_type\">ਰੋਟੇਸ਼ਨ ਦੀ ਕਿਸਮ</string>\n    <string name=\"fractal_type\">ਫ੍ਰੈਕਟਲ ਕਿਸਮ</string>\n    <string name=\"octaves\">ਅਸ਼ਟ</string>\n    <string name=\"lacunarity\">ਲਕੁਨਾਰਿਟੀ</string>\n    <string name=\"gain\">ਹਾਸਲ ਕਰੋ</string>\n    <string name=\"weighted_strength\">ਵਜ਼ਨ ਵਾਲੀ ਤਾਕਤ</string>\n    <string name=\"ping_pong_strength\">ਪਿੰਗ ਪੋਂਗ ਤਾਕਤ</string>\n    <string name=\"distance_function\">ਦੂਰੀ ਫੰਕਸ਼ਨ</string>\n    <string name=\"return_type\">ਵਾਪਸੀ ਦੀ ਕਿਸਮ</string>\n    <string name=\"jitter\">ਜਿਟਰ</string>\n    <string name=\"domain_warp\">ਡੋਮੇਨ ਵਾਰਪ</string>\n    <string name=\"alignment\">ਅਲਾਈਨਮੈਂਟ</string>\n    <string name=\"custom_filename\">ਕਸਟਮ ਫਾਈਲ ਨਾਮ</string>\n    <string name=\"custom_filename_sub\">ਸਥਾਨ ਅਤੇ ਫਾਈਲ ਨਾਮ ਚੁਣੋ ਜੋ ਮੌਜੂਦਾ ਚਿੱਤਰ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਵਰਤੇ ਜਾਣਗੇ</string>\n    <string name=\"saved_to_custom\">ਕਸਟਮ ਨਾਮ ਦੇ ਨਾਲ ਫੋਲਡਰ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"collage_maker\">ਕੋਲਾਜ ਮੇਕਰ</string>\n    <string name=\"collage_maker_sub\">20 ਚਿੱਤਰਾਂ ਤੱਕ ਕੋਲਾਜ ਬਣਾਓ</string>\n    <string name=\"collage_type\">ਕੋਲਾਜ ਦੀ ਕਿਸਮ</string>\n    <string name=\"collages_info\">ਸਥਿਤੀ ਨੂੰ ਅਨੁਕੂਲ ਕਰਨ ਲਈ ਸਵੈਪ, ਮੂਵ ਅਤੇ ਜ਼ੂਮ ਕਰਨ ਲਈ ਚਿੱਤਰ ਨੂੰ ਫੜੀ ਰੱਖੋ</string>\n    <string name=\"disable_rotation\">ਰੋਟੇਸ਼ਨ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ</string>\n    <string name=\"disable_rotation_sub\">ਦੋ-ਉਂਗਲਾਂ ਦੇ ਇਸ਼ਾਰਿਆਂ ਨਾਲ ਚਿੱਤਰਾਂ ਨੂੰ ਘੁੰਮਾਉਣ ਤੋਂ ਰੋਕਦਾ ਹੈ</string>\n    <string name=\"enable_snapping_to_borders\">ਬਾਰਡਰਾਂ \\'ਤੇ ਸਨੈਪਿੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ</string>\n    <string name=\"enable_snapping_to_borders_sub\">ਮੂਵ ਜਾਂ ਜ਼ੂਮ ਕਰਨ ਤੋਂ ਬਾਅਦ, ਚਿੱਤਰ ਫਰੇਮ ਦੇ ਕਿਨਾਰਿਆਂ ਨੂੰ ਭਰਨ ਲਈ ਸਨੈਪ ਹੋਣਗੇ</string>\n    <string name=\"histogram\">ਹਿਸਟੋਗ੍ਰਾਮ</string>\n    <string name=\"histogram_sub\">ਵਿਵਸਥਾਵਾਂ ਕਰਨ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਲਈ RGB ਜਾਂ ਬ੍ਰਾਈਟਨੈੱਸ ਚਿੱਤਰ ਹਿਸਟੋਗ੍ਰਾਮ</string>\n    <string name=\"image_for_histogram\">ਇਹ ਚਿੱਤਰ RGB ਅਤੇ ਚਮਕ ਹਿਸਟੋਗ੍ਰਾਮ ਬਣਾਉਣ ਲਈ ਵਰਤਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"tesseract_options\">ਟੈਸਰੈਕਟ ਵਿਕਲਪ</string>\n    <string name=\"tesseract_options_sub\">ਟੈਸਰੈਕਟ ਇੰਜਣ ਲਈ ਕੁਝ ਇਨਪੁਟ ਵੇਰੀਏਬਲ ਲਾਗੂ ਕਰੋ</string>\n    <string name=\"custom_options\">ਕਸਟਮ ਵਿਕਲਪ</string>\n    <string name=\"custom_params_info\">ਵਿਕਲਪਾਂ ਨੂੰ ਇਸ ਪੈਟਰਨ ਦੇ ਬਾਅਦ ਦਾਖਲ ਕੀਤਾ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">ਆਟੋ ਕ੍ਰੌਪ</string>\n    <string name=\"free_corners\">ਮੁਫਤ ਕੋਨੇ</string>\n    <string name=\"free_corners_sub\">ਬਹੁਭੁਜ ਦੁਆਰਾ ਚਿੱਤਰ ਨੂੰ ਕੱਟੋ, ਇਹ ਦ੍ਰਿਸ਼ਟੀਕੋਣ ਨੂੰ ਵੀ ਠੀਕ ਕਰਦਾ ਹੈ</string>\n    <string name=\"coerce_points_to_image_bounds\">ਚਿੱਤਰ ਸੀਮਾਵਾਂ ਲਈ ਜ਼ੋਰ ਪੁਆਇੰਟ</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">ਪੁਆਇੰਟ ਚਿੱਤਰ ਸੀਮਾਵਾਂ ਦੁਆਰਾ ਸੀਮਿਤ ਨਹੀਂ ਹੋਣਗੇ, ਇਹ ਵਧੇਰੇ ਸਟੀਕ ਦ੍ਰਿਸ਼ਟੀਕੋਣ ਸੁਧਾਰ ਲਈ ਉਪਯੋਗੀ ਹੈ</string>\n    <string name=\"mask\">ਮਾਸਕ</string>\n    <string name=\"spot_heal_sub\">ਤਿਆਰ ਕੀਤੇ ਮਾਰਗ ਦੇ ਹੇਠਾਂ ਸਮੱਗਰੀ ਜਾਗਰੂਕਤਾ ਭਰੋ</string>\n    <string name=\"spot_heal\">ਹੀਲ ਸਪਾਟ</string>\n    <string name=\"use_circle_kernel\">ਸਰਕਲ ਕਰਨਲ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"opening\">ਖੁੱਲ ਰਿਹਾ ਹੈ</string>\n    <string name=\"closing\">ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ</string>\n    <string name=\"morphological_gradient\">ਰੂਪ ਵਿਗਿਆਨਿਕ ਗਰੇਡੀਐਂਟ</string>\n    <string name=\"top_hat\">ਸਿਖਰ ਦੀ ਟੋਪੀ</string>\n    <string name=\"black_hat\">ਕਾਲੀ ਟੋਪੀ</string>\n    <string name=\"tone_curves\">ਟੋਨ ਕਰਵਜ਼</string>\n    <string name=\"reset_curves\">ਕਰਵ ਰੀਸੈੱਟ ਕਰੋ</string>\n    <string name=\"reset_curves_sub\">ਕਰਵ ਨੂੰ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਮੁੱਲ \\'ਤੇ ਰੋਲ ਕੀਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"line_style\">ਲਾਈਨ ਸ਼ੈਲੀ</string>\n    <string name=\"gap_size\">ਗੈਪ ਦਾ ਆਕਾਰ</string>\n    <string name=\"dashed\">ਡੈਸ਼ਡ</string>\n    <string name=\"dot_dashed\">ਡੌਟ ਡੈਸ਼ਡ</string>\n    <string name=\"stamped\">ਮੋਹਰ ਲਗਾਈ</string>\n    <string name=\"zigzag\">ਜਿਗਜ਼ੈਗ</string>\n    <string name=\"dashed_sub\">ਨਿਸ਼ਚਿਤ ਅੰਤਰ ਆਕਾਰ ਦੇ ਨਾਲ ਖਿੱਚੇ ਮਾਰਗ ਦੇ ਨਾਲ ਡੈਸ਼ਡ ਲਾਈਨ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"dot_dashed_sub\">ਦਿੱਤੇ ਮਾਰਗ ਦੇ ਨਾਲ ਬਿੰਦੀ ਅਤੇ ਡੈਸ਼ਡ ਲਾਈਨ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"defaultt_sub\">ਸਿਰਫ਼ ਡਿਫੌਲਟ ਸਿੱਧੀਆਂ ਲਾਈਨਾਂ</string>\n    <string name=\"stamped_sub\">ਨਿਰਧਾਰਤ ਸਪੇਸਿੰਗ ਦੇ ਨਾਲ ਮਾਰਗ ਦੇ ਨਾਲ ਚੁਣੀਆਂ ਹੋਈਆਂ ਆਕਾਰਾਂ ਨੂੰ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"zigzag_sub\">ਮਾਰਗ ਦੇ ਨਾਲ ਲਹਿਰਦਾਰ ਜ਼ਿਗਜ਼ੈਗ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"zigzag_ratio\">ਜ਼ਿਗਜ਼ੈਗ ਅਨੁਪਾਤ</string>\n    <string name=\"create_shortcut\">ਸ਼ਾਰਟਕੱਟ ਬਣਾਓ</string>\n    <string name=\"create_shortcut_title\">ਪਿੰਨ ਕਰਨ ਲਈ ਟੂਲ ਚੁਣੋ</string>\n    <string name=\"create_shortcut_subtitle\">ਟੂਲ ਨੂੰ ਤੁਹਾਡੇ ਲਾਂਚਰ ਦੀ ਹੋਮ ਸਕ੍ਰੀਨ \\'ਤੇ ਸ਼ਾਰਟਕੱਟ ਦੇ ਤੌਰ \\'ਤੇ ਜੋੜਿਆ ਜਾਵੇਗਾ, ਲੋੜੀਂਦੇ ਵਿਹਾਰ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਇਸਨੂੰ \\\"ਫਾਇਲ ਚੁਣਨਾ ਛੱਡੋ\\\" ਸੈਟਿੰਗ ਦੇ ਨਾਲ ਜੋੜ ਕੇ ਵਰਤੋ।</string>\n    <string name=\"dont_stack_frames\">ਫਰੇਮਾਂ ਨੂੰ ਸਟੈਕ ਨਾ ਕਰੋ</string>\n    <string name=\"dont_stack_frames_sub\">ਪਿਛਲੇ ਫਰੇਮਾਂ ਦੇ ਨਿਪਟਾਰੇ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਂਦਾ ਹੈ, ਇਸਲਈ ਉਹ ਇੱਕ ਦੂਜੇ \\'ਤੇ ਸਟੈਕ ਨਹੀਂ ਕਰਨਗੇ</string>\n    <string name=\"crossfade\">ਕਰਾਸਫੇਡ</string>\n    <string name=\"crossfade_sub\">ਫਰੇਮ ਇੱਕ ਦੂਜੇ ਵਿੱਚ ਕ੍ਰਾਸਫੇਡ ਕੀਤੇ ਜਾਣਗੇ</string>\n    <string name=\"crossfade_count\">ਕਰਾਸਫੇਡ ਫਰੇਮਾਂ ਦੀ ਗਿਣਤੀ</string>\n    <string name=\"threshold_one\">ਥ੍ਰੈਸ਼ਹੋਲਡ ਇੱਕ</string>\n    <string name=\"threshold_two\">ਥ੍ਰੈਸ਼ਹੋਲਡ ਦੋ</string>\n    <string name=\"canny\">ਕੈਨੀ</string>\n    <string name=\"mirror_101\">ਮਿਰਰ 101</string>\n    <string name=\"enhanced_zoom_blur\">ਵਿਸਤ੍ਰਿਤ ਜ਼ੂਮ ਬਲਰ</string>\n    <string name=\"laplacian_simple\">ਲੈਪਲੇਸ਼ੀਅਨ ਸਧਾਰਨ</string>\n    <string name=\"sobel_simple\">ਸੋਬਲ ਸਧਾਰਨ</string>\n    <string name=\"helper_grid\">ਸਹਾਇਕ ਗਰਿੱਡ</string>\n    <string name=\"helper_grid_sub\">ਸਹੀ ਹੇਰਾਫੇਰੀ ਵਿੱਚ ਮਦਦ ਕਰਨ ਲਈ ਡਰਾਇੰਗ ਖੇਤਰ ਦੇ ਉੱਪਰ ਸਹਾਇਕ ਗਰਿੱਡ ਦਿਖਾਉਂਦਾ ਹੈ</string>\n    <string name=\"grid_color\">ਗਰਿੱਡ ਦਾ ਰੰਗ</string>\n    <string name=\"cell_width\">ਸੈੱਲ ਚੌੜਾਈ</string>\n    <string name=\"cell_height\">ਸੈੱਲ ਦੀ ਉਚਾਈ</string>\n    <string name=\"compact_selectors\">ਸੰਖੇਪ ਚੋਣਕਾਰ</string>\n    <string name=\"compact_selectors_sub\">ਕੁਝ ਚੋਣ ਨਿਯੰਤਰਣ ਘੱਟ ਜਗ੍ਹਾ ਲੈਣ ਲਈ ਇੱਕ ਸੰਖੇਪ ਖਾਕੇ ਦੀ ਵਰਤੋਂ ਕਰਨਗੇ</string>\n    <string name=\"grant_camera_permission_to_capture_image\">ਚਿੱਤਰ ਨੂੰ ਕੈਪਚਰ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਕੈਮਰੇ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ</string>\n    <string name=\"layout\">ਖਾਕਾ</string>\n    <string name=\"main_screen_title\">ਮੁੱਖ ਸਕ੍ਰੀਨ ਸਿਰਲੇਖ</string>\n    <string name=\"constant_rate_factor\">ਸਥਿਰ ਦਰ ਕਾਰਕ (CRF)</string>\n    <string name=\"crf_sub\">%1$s ਦੇ ਮੁੱਲ ਦਾ ਅਰਥ ਹੈ ਇੱਕ ਹੌਲੀ ਸੰਕੁਚਨ, ਨਤੀਜੇ ਵਜੋਂ ਇੱਕ ਮੁਕਾਬਲਤਨ ਛੋਟਾ ਫਾਈਲ ਆਕਾਰ। %2$s ਦਾ ਅਰਥ ਹੈ ਇੱਕ ਤੇਜ਼ ਕੰਪਰੈਸ਼ਨ, ਨਤੀਜੇ ਵਜੋਂ ਇੱਕ ਵੱਡੀ ਫਾਈਲ।</string>\n    <string name=\"lut_library\">ਲੂਟ ਲਾਇਬ੍ਰੇਰੀ</string>\n    <string name=\"lut_library_sub\">LUTs ਦਾ ਸੰਗ੍ਰਹਿ ਡਾਊਨਲੋਡ ਕਰੋ, ਜਿਸ ਨੂੰ ਤੁਸੀਂ ਡਾਊਨਲੋਡ ਕਰਨ ਤੋਂ ਬਾਅਦ ਅਰਜ਼ੀ ਦੇ ਸਕਦੇ ਹੋ</string>\n    <string name=\"lut_library_update_sub\">LUTs ਦਾ ਸੰਗ੍ਰਹਿ ਅੱਪਡੇਟ ਕਰੋ (ਸਿਰਫ਼ ਨਵੇਂ ਕਤਾਰਬੱਧ ਹੋਣਗੇ), ਜਿਸ ਨੂੰ ਤੁਸੀਂ ਡਾਊਨਲੋਡ ਕਰਨ ਤੋਂ ਬਾਅਦ ਅਰਜ਼ੀ ਦੇ ਸਕਦੇ ਹੋ</string>\n    <string name=\"filter_preview_image_sub\">ਫਿਲਟਰਾਂ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਚਿੱਤਰ ਝਲਕ ਨੂੰ ਬਦਲੋ</string>\n    <string name=\"filter_preview_image\">ਚਿੱਤਰ ਦੀ ਝਲਕ</string>\n    <string name=\"hide\">ਓਹਲੇ</string>\n    <string name=\"show\">ਦਿਖਾਓ</string>\n    <string name=\"slider_type\">ਸਲਾਈਡਰ ਦੀ ਕਿਸਮ</string>\n    <string name=\"fancy\">ਫੈਂਸੀ</string>\n    <string name=\"material_2\">ਸਮੱਗਰੀ 2</string>\n    <string name=\"fancy_sub\">ਇੱਕ ਸ਼ਾਨਦਾਰ ਦਿੱਖ ਵਾਲਾ ਸਲਾਈਡਰ। ਇਹ ਡਿਫਾਲਟ ਵਿਕਲਪ ਹੈ</string>\n    <string name=\"material_2_sub\">ਇੱਕ ਸਮੱਗਰੀ 2 ਸਲਾਈਡਰ</string>\n    <string name=\"material_you_slider_sub\">ਇੱਕ ਸਮੱਗਰੀ ਜੋ ਤੁਸੀਂ ਸਲਾਈਡਰ ਕਰਦੇ ਹੋ</string>\n    <string name=\"apply\">ਲਾਗੂ ਕਰੋ</string>\n    <string name=\"center_align_dialog_buttons\">ਸੈਂਟਰ ਡਾਇਲਾਗ ਬਟਨ</string>\n    <string name=\"center_align_dialog_buttons_sub\">ਜੇਕਰ ਸੰਭਵ ਹੋਵੇ ਤਾਂ ਡਾਇਲਾਗਸ ਦੇ ਬਟਨ ਖੱਬੇ ਪਾਸੇ ਦੀ ਬਜਾਏ ਕੇਂਦਰ ਵਿੱਚ ਰੱਖੇ ਜਾਣਗੇ</string>\n    <string name=\"open_source_licenses\">ਓਪਨ ਸੋਰਸ ਲਾਇਸੰਸ</string>\n    <string name=\"open_source_licenses_sub\">ਇਸ ਐਪ ਵਿੱਚ ਵਰਤੀਆਂ ਗਈਆਂ ਓਪਨ ਸੋਰਸ ਲਾਇਬ੍ਰੇਰੀਆਂ ਦੇ ਲਾਇਸੰਸ ਦੇਖੋ</string>\n    <string name=\"area\">ਖੇਤਰ</string>\n    <string name=\"area_sub\">ਪਿਕਸਲ ਏਰੀਆ ਰਿਲੇਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਰੀਸੈਪਲਿੰਗ। ਇਹ ਚਿੱਤਰ ਨੂੰ ਖਤਮ ਕਰਨ ਲਈ ਇੱਕ ਤਰਜੀਹੀ ਢੰਗ ਹੋ ਸਕਦਾ ਹੈ, ਕਿਉਂਕਿ ਇਹ ਮੋਇਰ\\'-ਮੁਕਤ ਨਤੀਜੇ ਦਿੰਦਾ ਹੈ। ਪਰ ਜਦੋਂ ਚਿੱਤਰ ਨੂੰ ਜ਼ੂਮ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਇਹ \\\"ਨੇੜਲੇ\\\" ਵਿਧੀ ਦੇ ਸਮਾਨ ਹੁੰਦਾ ਹੈ।</string>\n    <string name=\"enable_tonemapping\">ਟੋਨਮੈਪਿੰਗ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ</string>\n    <string name=\"enter_percent\">% ਦਰਜ ਕਰੋ</string>\n    <string name=\"unknown_host\">ਸਾਈਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ, VPN ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜਾਂ ਜਾਂਚ ਕਰੋ ਕਿ ਕੀ url ਸਹੀ ਹੈ</string>\n    <string name=\"markup_layers\">ਮਾਰਕਅੱਪ ਲੇਅਰਸ</string>\n    <string name=\"markup_layers_sub\">ਤਸਵੀਰਾਂ, ਟੈਕਸਟ ਅਤੇ ਹੋਰ ਚੀਜ਼ਾਂ ਨੂੰ ਸੁਤੰਤਰ ਤੌਰ \\'ਤੇ ਰੱਖਣ ਦੀ ਸਮਰੱਥਾ ਵਾਲਾ ਲੇਅਰ ਮੋਡ</string>\n    <string name=\"edit_layer\">ਪਰਤ ਦਾ ਸੰਪਾਦਨ ਕਰੋ</string>\n    <string name=\"layers_on_image\">ਚਿੱਤਰ \\'ਤੇ ਪਰਤਾਂ</string>\n    <string name=\"layers_on_image_sub\">ਇੱਕ ਬੈਕਗ੍ਰਾਉਂਡ ਦੇ ਤੌਰ ਤੇ ਇੱਕ ਚਿੱਤਰ ਦੀ ਵਰਤੋਂ ਕਰੋ ਅਤੇ ਇਸਦੇ ਸਿਖਰ \\'ਤੇ ਵੱਖ-ਵੱਖ ਪਰਤਾਂ ਜੋੜੋ</string>\n    <string name=\"layers_on_background\">ਪਿਛੋਕੜ \\'ਤੇ ਪਰਤਾਂ</string>\n    <string name=\"layers_on_background_sub\">ਪਹਿਲੇ ਵਿਕਲਪ ਵਾਂਗ ਹੀ ਪਰ ਚਿੱਤਰ ਦੀ ਬਜਾਏ ਰੰਗ ਨਾਲ</string>\n    <string name=\"beta\">ਬੀਟਾ</string>\n    <string name=\"fast_settings_side\">ਤੇਜ਼ ਸੈਟਿੰਗ ਸਾਈਡ</string>\n    <string name=\"fast_settings_side_sub\">ਚਿੱਤਰਾਂ ਨੂੰ ਸੰਪਾਦਿਤ ਕਰਦੇ ਸਮੇਂ ਚੁਣੇ ਹੋਏ ਪਾਸੇ \\'ਤੇ ਫਲੋਟਿੰਗ ਸਟ੍ਰਿਪ ਸ਼ਾਮਲ ਕਰੋ, ਜੋ ਕਿ ਕਲਿੱਕ ਕਰਨ \\'ਤੇ ਤੇਜ਼ ਸੈਟਿੰਗਾਂ ਨੂੰ ਖੋਲ੍ਹ ਦੇਵੇਗੀ</string>\n    <string name=\"clear_selection\">ਚੋਣ ਸਾਫ਼ ਕਰੋ</string>\n    <string name=\"settings_group_visibility_hidden\">ਸੈੱਟਿੰਗ ਗਰੁੱਪ \\\"%1$s\\\" ਨੂੰ ਮੂਲ ਰੂਪ ਵਿੱਚ ਸਮੇਟਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"settings_group_visibility_visible\">ਸੈੱਟਿੰਗ ਗਰੁੱਪ \\\"%1$s\\\" ਨੂੰ ਮੂਲ ਰੂਪ ਵਿੱਚ ਵਿਸਤਾਰ ਕੀਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"base_64_tools\">ਬੇਸ 64 ਟੂਲ</string>\n    <string name=\"base_64_tools_sub\">ਬੇਸ 64 ਸਟ੍ਰਿੰਗ ਨੂੰ ਚਿੱਤਰ ਵਿੱਚ ਡੀਕੋਡ ਕਰੋ, ਜਾਂ ਚਿੱਤਰ ਨੂੰ ਬੇਸ64 ਫਾਰਮੈਟ ਵਿੱਚ ਏਨਕੋਡ ਕਰੋ</string>\n    <string name=\"base_64\">ਬੇਸ 64</string>\n    <string name=\"not_a_valid_base_64\">ਪ੍ਰਦਾਨ ਕੀਤਾ ਮੁੱਲ ਇੱਕ ਵੈਧ Base64 ਸਤਰ ਨਹੀਂ ਹੈ</string>\n    <string name=\"copy_not_a_valid_base_64\">ਖਾਲੀ ਜਾਂ ਅਵੈਧ Base64 ਸਤਰ ਦੀ ਨਕਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ</string>\n    <string name=\"paste_base_64\">ਬੇਸ 64 ਪੇਸਟ ਕਰੋ</string>\n    <string name=\"copy_base_64\">ਬੇਸ 64 ਕਾਪੀ ਕਰੋ</string>\n    <string name=\"base_64_tips\">ਬੇਸ 64 ਸਟ੍ਰਿੰਗ ਨੂੰ ਕਾਪੀ ਜਾਂ ਸੇਵ ਕਰਨ ਲਈ ਚਿੱਤਰ ਲੋਡ ਕਰੋ। ਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਸਟ੍ਰਿੰਗ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਚਿੱਤਰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਇਸਨੂੰ ਉੱਪਰ ਪੇਸਟ ਕਰ ਸਕਦੇ ਹੋ</string>\n    <string name=\"save_base_64\">ਬੇਸ 64 ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ</string>\n    <string name=\"share_base_64\">ਸ਼ੇਅਰ ਬੇਸ 64</string>\n    <string name=\"options\">ਵਿਕਲਪ</string>\n    <string name=\"actions\">ਕਾਰਵਾਈਆਂ</string>\n    <string name=\"import_base_64\">ਬੇਸ 64 ਆਯਾਤ ਕਰੋ</string>\n    <string name=\"base_64_actions\">ਬੇਸ 64 ਕਾਰਵਾਈਆਂ</string>\n    <string name=\"add_outline\">ਰੂਪਰੇਖਾ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_outline_sub\">ਖਾਸ ਰੰਗ ਅਤੇ ਚੌੜਾਈ ਦੇ ਨਾਲ ਟੈਕਸਟ ਦੇ ਆਲੇ-ਦੁਆਲੇ ਰੂਪਰੇਖਾ ਜੋੜੋ</string>\n    <string name=\"outline_color\">ਰੂਪਰੇਖਾ ਰੰਗ</string>\n    <string name=\"outline_size\">ਰੂਪਰੇਖਾ ਦਾ ਆਕਾਰ</string>\n    <string name=\"rotation\">ਰੋਟੇਸ਼ਨ</string>\n    <string name=\"checksum_as_filename\">ਫਾਈਲ ਨਾਮ ਵਜੋਂ ਚੈੱਕਸਮ</string>\n    <string name=\"checksum_as_filename_sub\">ਆਉਟਪੁੱਟ ਚਿੱਤਰਾਂ ਦਾ ਨਾਮ ਉਹਨਾਂ ਦੇ ਡੇਟਾ ਚੈੱਕਸਮ ਦੇ ਅਨੁਸਾਰੀ ਹੋਵੇਗਾ</string>\n    <string name=\"free_software_partner\">ਮੁਫਤ ਸਾਫਟਵੇਅਰ (ਸਾਥੀ)</string>\n    <string name=\"free_software_partner_sub\">ਐਂਡਰਾਇਡ ਐਪਲੀਕੇਸ਼ਨਾਂ ਦੇ ਸਹਿਭਾਗੀ ਚੈਨਲ ਵਿੱਚ ਵਧੇਰੇ ਉਪਯੋਗੀ ਸੌਫਟਵੇਅਰ</string>\n    <string name=\"algorithms\">ਐਲਗੋਰਿਦਮ</string>\n    <string name=\"checksum_tools\">ਚੈੱਕਸਮ ਟੂਲਜ਼</string>\n    <string name=\"checksum_tools_sub\">ਵੱਖੋ-ਵੱਖਰੇ ਹੈਸ਼ਿੰਗ ਐਲਗੋਰਿਦਮ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਚੈੱਕਸਮ ਦੀ ਤੁਲਨਾ ਕਰੋ, ਹੈਸ਼ਾਂ ਦੀ ਗਣਨਾ ਕਰੋ ਜਾਂ ਫਾਈਲਾਂ ਤੋਂ ਹੈਕਸ ਸਤਰ ਬਣਾਓ</string>\n    <string name=\"calculate\">ਗਣਨਾ ਕਰੋ</string>\n    <string name=\"text_hash\">ਟੈਕਸਟ ਹੈਸ਼</string>\n    <string name=\"checksum\">ਚੈੱਕਸਮ</string>\n    <string name=\"pick_file_to_checksum\">ਚੁਣੇ ਹੋਏ ਐਲਗੋਰਿਦਮ ਦੇ ਆਧਾਰ \\'ਤੇ ਇਸ ਦੇ ਚੈਕਸਮ ਦੀ ਗਣਨਾ ਕਰਨ ਲਈ ਫਾਈਲ ਚੁਣੋ</string>\n    <string name=\"enter_text_to_checksum\">ਚੁਣੇ ਹੋਏ ਐਲਗੋਰਿਦਮ ਦੇ ਆਧਾਰ \\'ਤੇ ਇਸ ਦੇ ਚੈਕਸਮ ਦੀ ਗਣਨਾ ਕਰਨ ਲਈ ਟੈਕਸਟ ਦਰਜ ਕਰੋ</string>\n    <string name=\"source_checksum\">ਸਰੋਤ ਚੈੱਕਸਮ</string>\n    <string name=\"checksum_to_compare\">ਤੁਲਨਾ ਕਰਨ ਲਈ ਚੈੱਕਸਮ</string>\n    <string name=\"match\">ਮੈਚ!</string>\n    <string name=\"difference\">ਅੰਤਰ</string>\n    <string name=\"match_sub\">ਚੈੱਕਸਮ ਬਰਾਬਰ ਹਨ, ਇਹ ਸੁਰੱਖਿਅਤ ਹੋ ਸਕਦਾ ਹੈ</string>\n    <string name=\"difference_sub\">ਚੈੱਕਸਮ ਬਰਾਬਰ ਨਹੀਂ ਹਨ, ਫਾਈਲ ਅਸੁਰੱਖਿਅਤ ਹੋ ਸਕਦੀ ਹੈ!</string>\n    <string name=\"mesh_gradients\">ਜਾਲ ਗਰੇਡੀਐਂਟ</string>\n    <string name=\"collection_mesh_gradients_sub\">Mesh Gradients ਦੇ ਔਨਲਾਈਨ ਸੰਗ੍ਰਹਿ ਨੂੰ ਦੇਖੋ</string>\n    <string name=\"wrong_font\">ਸਿਰਫ਼ TTF ਅਤੇ OTF ਫੋਂਟ ਹੀ ਆਯਾਤ ਕੀਤੇ ਜਾ ਸਕਦੇ ਹਨ</string>\n    <string name=\"import_font\">ਫੌਂਟ ਆਯਾਤ ਕਰੋ (TTF/OTF)</string>\n    <string name=\"export_fonts\">ਫੌਂਟ ਨਿਰਯਾਤ ਕਰੋ</string>\n    <string name=\"imported_fonts\">ਆਯਾਤ ਕੀਤੇ ਫੌਂਟ</string>\n    <string name=\"error_while_saving\">ਕੋਸ਼ਿਸ਼ ਨੂੰ ਸੰਭਾਲਣ ਦੌਰਾਨ ਗਲਤੀ, ਆਉਟਪੁੱਟ ਫੋਲਡਰ ਨੂੰ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ</string>\n    <string name=\"filename_is_not_set\">ਫਾਈਲ ਨਾਮ ਸੈੱਟ ਨਹੀਂ ਹੈ</string>\n    <string name=\"none\">ਕੋਈ ਨਹੀਂ</string>\n    <string name=\"custom_pages\">ਕਸਟਮ ਪੰਨੇ</string>\n    <string name=\"pages_selection\">ਪੰਨਿਆਂ ਦੀ ਚੋਣ</string>\n    <string name=\"tool_exit_confirmation\">ਟੂਲ ਐਗਜ਼ਿਟ ਪੁਸ਼ਟੀਕਰਨ</string>\n    <string name=\"tool_exit_confirmation_sub\">ਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਖਾਸ ਟੂਲਸ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਅਣ-ਸੰਭਾਲਿਤ ਤਬਦੀਲੀਆਂ ਹਨ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ, ਤਾਂ ਪੁਸ਼ਟੀ ਕਰੋ ਡਾਇਲਾਗ ਦਿਖਾਇਆ ਜਾਵੇਗਾ</string>\n    <string name=\"edit_exif_screen\">EXIF ਸੰਪਾਦਿਤ ਕਰੋ</string>\n    <string name=\"edit_exif_screen_sub\">ਰੀਕੰਪਰੇਸ਼ਨ ਤੋਂ ਬਿਨਾਂ ਸਿੰਗਲ ਚਿੱਤਰ ਦਾ ਮੈਟਾਡੇਟਾ ਬਦਲੋ</string>\n    <string name=\"edit_exif_tag\">ਉਪਲਬਧ ਟੈਗਾਂ ਨੂੰ ਸੰਪਾਦਿਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ</string>\n    <string name=\"change_sticker\">ਸਟਿੱਕਰ ਬਦਲੋ</string>\n    <string name=\"fit_width\">ਫਿੱਟ ਚੌੜਾਈ</string>\n    <string name=\"fit_height\">ਫਿੱਟ ਉਚਾਈ</string>\n    <string name=\"batch_compare\">ਬੈਚ ਦੀ ਤੁਲਨਾ ਕਰੋ</string>\n    <string name=\"pick_files_to_checksum\">ਚੁਣੇ ਗਏ ਐਲਗੋਰਿਦਮ ਦੇ ਆਧਾਰ \\'ਤੇ ਇਸ ਦੇ ਚੈੱਕਸਮ ਦੀ ਗਣਨਾ ਕਰਨ ਲਈ ਫਾਈਲ/ਫਾਈਲਾਂ ਨੂੰ ਚੁਣੋ</string>\n    <string name=\"pick_files\">ਫਾਈਲਾਂ ਚੁਣੋ</string>\n    <string name=\"pick_directory\">ਡਾਇਰੈਕਟਰੀ ਚੁਣੋ</string>\n    <string name=\"head_length_scale\">ਸਿਰ ਦੀ ਲੰਬਾਈ ਦਾ ਪੈਮਾਨਾ</string>\n    <string name=\"stamp\">ਸਟੈਂਪ</string>\n    <string name=\"timestamp\">ਟਾਈਮਸਟੈਂਪ</string>\n    <string name=\"format_pattern\">ਫਾਰਮੈਟ ਪੈਟਰਨ</string>\n    <string name=\"padding\">ਪੈਡਿੰਗ</string>\n    <string name=\"image_cutting\">ਚਿੱਤਰ ਕੱਟਣਾ</string>\n    <string name=\"image_cutting_sub\">ਚਿੱਤਰ ਦੇ ਹਿੱਸੇ ਨੂੰ ਕੱਟੋ ਅਤੇ ਖੱਬੇ ਪਾਸੇ ਨੂੰ ਮਿਲਾਓ (ਉਲਟਾ ਹੋ ਸਕਦਾ ਹੈ) ਲੰਬਕਾਰੀ ਜਾਂ ਖਿਤਿਜੀ ਰੇਖਾਵਾਂ ਦੁਆਰਾ</string>\n    <string name=\"vertical_pivot_line\">ਲੰਬਕਾਰੀ ਧਰੁਵੀ ਲਾਈਨ</string>\n    <string name=\"horizontal_pivot_line\">ਹਰੀਜ਼ੱਟਲ ਧਰੁਵੀ ਰੇਖਾ</string>\n    <string name=\"inverse_selection\">ਉਲਟ ਚੋਣ</string>\n    <string name=\"inverse_vertical_selection_sub\">ਕੱਟੇ ਹੋਏ ਖੇਤਰ ਦੇ ਆਲੇ ਦੁਆਲੇ ਹਿੱਸਿਆਂ ਨੂੰ ਮਿਲਾਉਣ ਦੀ ਬਜਾਏ, ਵਰਟੀਕਲ ਕੱਟ ਵਾਲੇ ਹਿੱਸੇ ਨੂੰ ਛੱਡ ਦਿੱਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"inverse_horizontal_selection_sub\">ਕੱਟੇ ਹੋਏ ਖੇਤਰ ਦੇ ਆਲੇ ਦੁਆਲੇ ਭਾਗਾਂ ਨੂੰ ਮਿਲਾਉਣ ਦੀ ਬਜਾਏ, ਹਰੀਜੱਟਲ ਕੱਟ ਵਾਲੇ ਹਿੱਸੇ ਨੂੰ ਛੱਡ ਦਿੱਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"collection_mesh_gradients\">ਜਾਲ ਗਰੇਡੀਐਂਟਸ ਦਾ ਸੰਗ੍ਰਹਿ</string>\n    <string name=\"mesh_gradients_sub\">ਗੰਢਾਂ ਅਤੇ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਦੀ ਕਸਟਮ ਮਾਤਰਾ ਨਾਲ ਜਾਲ ਗਰੇਡੀਐਂਟ ਬਣਾਓ</string>\n    <string name=\"gradient_maker_type_image_mesh\">ਜਾਲ ਗਰੇਡੀਐਂਟ ਓਵਰਲੇ</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">ਦਿੱਤੇ ਚਿੱਤਰਾਂ ਦੇ ਸਿਖਰ ਦਾ ਜਾਲ ਗਰੇਡੀਐਂਟ ਲਿਖੋ</string>\n    <string name=\"points_customization\">ਪੁਆਇੰਟ ਕਸਟਮਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"grid_size\">ਗਰਿੱਡ ਦਾ ਆਕਾਰ</string>\n    <string name=\"resolution_x\">ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਐਕਸ</string>\n    <string name=\"resolution_y\">ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਵਾਈ</string>\n    <string name=\"resolution\">ਮਤਾ</string>\n    <string name=\"pixel_by_pixel\">Pixel by Pixel</string>\n    <string name=\"highlight_color\">ਹਾਈਲਾਈਟ ਰੰਗ</string>\n    <string name=\"pixel_comparison_type\">Pixel ਤੁਲਨਾ ਦੀ ਕਿਸਮ</string>\n    <string name=\"scan_barcode\">ਬਾਰਕੋਡ ਸਕੈਨ ਕਰੋ</string>\n    <string name=\"height_ratio\">ਉਚਾਈ ਅਨੁਪਾਤ</string>\n    <string name=\"barcode_type\">ਬਾਰਕੋਡ ਦੀ ਕਿਸਮ</string>\n    <string name=\"enforce_bw\">B/W ਲਾਗੂ ਕਰੋ</string>\n    <string name=\"enforce_bw_sub\">ਬਾਰਕੋਡ ਚਿੱਤਰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਕਾਲਾ ਅਤੇ ਚਿੱਟਾ ਹੋਵੇਗਾ ਅਤੇ ਐਪ ਦੇ ਥੀਮ ਦੁਆਰਾ ਰੰਗੀਨ ਨਹੀਂ ਹੋਵੇਗਾ</string>\n    <string name=\"barcodes_sub\">ਕਿਸੇ ਵੀ ਬਾਰਕੋਡ (QR, EAN, AZTEC, …) ਨੂੰ ਸਕੈਨ ਕਰੋ ਅਤੇ ਇਸਦੀ ਸਮੱਗਰੀ ਪ੍ਰਾਪਤ ਕਰੋ ਜਾਂ ਨਵਾਂ ਬਣਾਉਣ ਲਈ ਆਪਣਾ ਟੈਕਸਟ ਪੇਸਟ ਕਰੋ</string>\n    <string name=\"no_barcode_found\">ਕੋਈ ਬਾਰਕੋਡ ਨਹੀਂ ਮਿਲਿਆ</string>\n    <string name=\"generated_barcode_will_be_here\">ਤਿਆਰ ਕੀਤਾ ਬਾਰਕੋਡ ਇੱਥੇ ਹੋਵੇਗਾ</string>\n    <string name=\"audio_cover_extractor\">ਆਡੀਓ ਕਵਰ</string>\n    <string name=\"audio_cover_extractor_sub\">ਆਡੀਓ ਫਾਈਲਾਂ ਤੋਂ ਐਲਬਮ ਕਵਰ ਚਿੱਤਰਾਂ ਨੂੰ ਐਕਸਟਰੈਕਟ ਕਰੋ, ਸਭ ਤੋਂ ਆਮ ਫਾਰਮੈਟ ਸਮਰਥਿਤ ਹਨ</string>\n    <string name=\"pick_audio_to_start\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਆਡੀਓ ਚੁਣੋ</string>\n    <string name=\"pick_audio\">ਆਡੀਓ ਚੁਣੋ</string>\n    <string name=\"no_covers_found\">ਕੋਈ ਕਵਰ ਨਹੀਂ ਮਿਲੇ</string>\n    <string name=\"send_logs\">ਲੌਗ ਭੇਜੋ</string>\n    <string name=\"send_logs_sub\">ਐਪ ਲੌਗਸ ਫਾਈਲ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ, ਇਹ ਸਮੱਸਿਆ ਨੂੰ ਲੱਭਣ ਅਤੇ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਹੱਲ ਕਰਨ ਵਿੱਚ ਮੇਰੀ ਮਦਦ ਕਰ ਸਕਦਾ ਹੈ</string>\n    <string name=\"crash_title\">ਓਹੋ… ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ</string>\n    <string name=\"crash_subtitle\">ਤੁਸੀਂ ਹੇਠਾਂ ਦਿੱਤੇ ਵਿਕਲਪਾਂ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਮੇਰੇ ਨਾਲ ਸੰਪਰਕ ਕਰ ਸਕਦੇ ਹੋ ਅਤੇ ਮੈਂ ਹੱਲ ਲੱਭਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਾਂਗਾ।\\n(ਲੌਗ ਨੱਥੀ ਕਰਨਾ ਨਾ ਭੁੱਲੋ)</string>\n    <string name=\"ocr_write_to_file\">ਫਾਈਲ ਵਿੱਚ ਲਿਖੋ</string>\n    <string name=\"ocr_write_to_file_sub\">ਚਿੱਤਰਾਂ ਦੇ ਬੈਚ ਤੋਂ ਟੈਕਸਟ ਐਕਸਟਰੈਕਟ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਇੱਕ ਟੈਕਸਟ ਫਾਈਲ ਵਿੱਚ ਸਟੋਰ ਕਰੋ</string>\n    <string name=\"ocr_write_to_metadata\">ਮੈਟਾਡੇਟਾ \\'ਤੇ ਲਿਖੋ</string>\n    <string name=\"ocr_write_to_metadata_sub\">ਹਰੇਕ ਚਿੱਤਰ ਤੋਂ ਟੈਕਸਟ ਐਕਸਟਰੈਕਟ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਸੰਬੰਧਿਤ ਫੋਟੋਆਂ ਦੀ EXIF ​​​​ਜਾਣਕਾਰੀ ਵਿੱਚ ਰੱਖੋ</string>\n    <string name=\"invisible_mode\">ਅਦਿੱਖ ਮੋਡ</string>\n    <string name=\"invisible_mode_sub\">ਆਪਣੀਆਂ ਤਸਵੀਰਾਂ ਦੇ ਬਾਈਟਾਂ ਦੇ ਅੰਦਰ ਅੱਖਾਂ ਦੇ ਅਦਿੱਖ ਵਾਟਰਮਾਰਕ ਬਣਾਉਣ ਲਈ ਸਟੈਗਨੋਗ੍ਰਾਫੀ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"use_lsb\">LSB ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"use_lsb_sub\">LSB (ਘੱਟ ਮਹੱਤਵਪੂਰਨ ਬਿੱਟ) ਸਟੈਗਨੋਗ੍ਰਾਫੀ ਵਿਧੀ ਵਰਤੀ ਜਾਵੇਗੀ, ਨਹੀਂ ਤਾਂ FD (ਫ੍ਰੀਕੁਐਂਸੀ ਡੋਮੇਨ)</string>\n    <string name=\"auto_remove_red_eyes\">ਲਾਲ ਅੱਖਾਂ ਨੂੰ ਆਟੋ ਹਟਾਓ</string>\n    <string name=\"password\">ਪਾਸਵਰਡ</string>\n    <string name=\"unlock\">ਅਨਲੌਕ ਕਰੋ</string>\n    <string name=\"pdf_is_protected\">PDF ਸੁਰੱਖਿਅਤ ਹੈ</string>\n    <string name=\"operation_almost_complete\">ਓਪਰੇਸ਼ਨ ਲਗਭਗ ਪੂਰਾ ਹੋ ਗਿਆ ਹੈ। ਹੁਣੇ ਰੱਦ ਕਰਨ ਲਈ ਇਸਨੂੰ ਮੁੜ ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੋਵੇਗੀ</string>\n    <string name=\"sort_by_date_modified\">ਸੰਸ਼ੋਧਿਤ ਮਿਤੀ</string>\n    <string name=\"sort_by_date_modified_reversed\">ਸੰਸ਼ੋਧਿਤ ਮਿਤੀ (ਉਲਟ)</string>\n    <string name=\"sort_by_size\">ਆਕਾਰ</string>\n    <string name=\"sort_by_size_reversed\">ਆਕਾਰ (ਉਲਟ)</string>\n    <string name=\"sort_by_mime_type\">MIME ਕਿਸਮ</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME ਕਿਸਮ (ਉਲਟ)</string>\n    <string name=\"sort_by_extension\">ਐਕਸਟੈਂਸ਼ਨ</string>\n    <string name=\"sort_by_extension_reversed\">ਐਕਸਟੈਂਸ਼ਨ (ਉਲਟ)</string>\n    <string name=\"sort_by_date_added\">ਜੋੜੀ ਗਈ ਮਿਤੀ</string>\n    <string name=\"sort_by_date_added_reversed\">ਜੋੜੀ ਗਈ ਮਿਤੀ (ਉਲਟ)</string>\n    <string name=\"left_to_right\">ਖੱਬੇ ਤੋਂ ਸੱਜੇ</string>\n    <string name=\"right_to_left\">ਸੱਜੇ ਤੋਂ ਖੱਬੇ</string>\n    <string name=\"top_to_bottom\">ਉੱਪਰ ਤੋਂ ਹੇਠਾਂ ਤੱਕ</string>\n    <string name=\"bottom_to_top\">ਹੇਠਾਂ ਤੋਂ ਸਿਖਰ ਤੱਕ</string>\n    <string name=\"liquid_glass\">ਤਰਲ ਗਲਾਸ</string>\n    <string name=\"liquid_glass_sub\">ਹਾਲ ਹੀ ਵਿੱਚ ਘੋਸ਼ਿਤ ਆਈਓਐਸ 26 ਅਤੇ ਇਸ ਦੇ ਤਰਲ ਗਲਾਸ ਡਿਜ਼ਾਈਨ ਸਿਸਟਮ \\'ਤੇ ਅਧਾਰਤ ਇੱਕ ਸਵਿੱਚ</string>\n    <string name=\"pick_image_or_base64\">ਚਿੱਤਰ ਚੁਣੋ ਜਾਂ ਹੇਠਾਂ ਬੇਸ64 ਡੇਟਾ ਪੇਸਟ/ਆਯਾਤ ਕਰੋ</string>\n    <string name=\"type_image_link\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਚਿੱਤਰ ਲਿੰਕ ਟਾਈਪ ਕਰੋ</string>\n    <string name=\"paste_link\">ਲਿੰਕ ਪੇਸਟ ਕਰੋ</string>\n    <string name=\"kaleidoscope\">ਕੈਲੀਡੋਸਕੋਪ</string>\n    <string name=\"secondary_angle\">ਸੈਕੰਡਰੀ ਕੋਣ</string>\n    <string name=\"sides\">ਪਾਸੇ</string>\n    <string name=\"channel_mix\">ਚੈਨਲ ਮਿਕਸ</string>\n    <string name=\"blue_green\">ਨੀਲਾ ਹਰਾ</string>\n    <string name=\"red_blue\">ਲਾਲ ਨੀਲਾ</string>\n    <string name=\"green_red\">ਹਰਾ ਲਾਲ</string>\n    <string name=\"into_red\">ਲਾਲ ਵਿੱਚ</string>\n    <string name=\"into_green\">ਹਰੇ ਵਿੱਚ</string>\n    <string name=\"into_blue\">ਨੀਲੇ ਵਿੱਚ</string>\n    <string name=\"cyan\">ਸਿਆਨ</string>\n    <string name=\"magenta\">ਮੈਜੈਂਟਾ</string>\n    <string name=\"yellow\">ਪੀਲਾ</string>\n    <string name=\"color_halftone\">ਰੰਗ ਹਾਫਟੋਨ</string>\n    <string name=\"contour\">ਕੰਟੋਰ</string>\n    <string name=\"levels\">ਪੱਧਰ</string>\n    <string name=\"offset\">ਆਫਸੈੱਟ</string>\n    <string name=\"voronoi_crystallize\">ਵੋਰੋਨੋਈ ਕ੍ਰਿਸਟਲਾਈਜ਼</string>\n    <string name=\"shape\">ਆਕਾਰ</string>\n    <string name=\"stretch\">ਖਿੱਚੋ</string>\n    <string name=\"randomness\">ਬੇਤਰਤੀਬਤਾ</string>\n    <string name=\"despeckle\">ਡੀਸਪੈਕਲ</string>\n    <string name=\"diffuse\">ਫੈਲਣਾ</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">ਦੂਜਾ ਘੇਰਾ</string>\n    <string name=\"equalize\">ਬਰਾਬਰ ਕਰੋ</string>\n    <string name=\"glow\">ਗਲੋ</string>\n    <string name=\"whirl_and_pinch\">ਚੱਕਰ ਅਤੇ ਚੂੰਡੀ</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">ਬਾਰਡਰ ਰੰਗ</string>\n    <string name=\"polar_coordinates\">ਪੋਲਰ ਕੋਆਰਡੀਨੇਟਸ</string>\n    <string name=\"rect_to_polar\">ਧਰੁਵੀ ਵੱਲ ਮੁੜੋ</string>\n    <string name=\"polar_to_rect\">ਠੀਕ ਕਰਨ ਲਈ ਧਰੁਵੀ</string>\n    <string name=\"invert_in_circle\">ਚੱਕਰ ਵਿੱਚ ਉਲਟ</string>\n    <string name=\"reduce_noise\">ਸ਼ੋਰ ਘਟਾਓ</string>\n    <string name=\"simple_solarize\">ਸਧਾਰਨ ਸੋਲਰਾਈਜ਼</string>\n    <string name=\"weave\">ਬੁਣਾਈ</string>\n    <string name=\"x_gap\">ਐਕਸ ਗੈਪ</string>\n    <string name=\"y_gap\">ਵਾਈ ਗੈਪ</string>\n    <string name=\"x_width\">X ਚੌੜਾਈ</string>\n    <string name=\"y_wdth\">Y ਚੌੜਾਈ</string>\n    <string name=\"twirl\">ਘੁੰਮਣਾ</string>\n    <string name=\"rubber_stmp\">ਰਬੜ ਦੀ ਮੋਹਰ</string>\n    <string name=\"smear\">ਸਮੀਅਰ</string>\n    <string name=\"density\">ਘਣਤਾ</string>\n    <string name=\"mix\">ਮਿਕਸ</string>\n    <string name=\"sphere_lensh_distortion\">ਗੋਲਾਕਾਰ ਲੈਂਸ ਵਿਗਾੜ</string>\n    <string name=\"refraction_index\">ਅਪਵਰਤਨ ਸੂਚਕਾਂਕ</string>\n    <string name=\"arc\">ਚਾਪ</string>\n    <string name=\"spread_angle\">ਫੈਲਾਓ ਕੋਣ</string>\n    <string name=\"sparkle\">ਚਮਕ</string>\n    <string name=\"rays\">ਕਿਰਨਾਂ</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">ਗਰੇਡੀਐਂਟ</string>\n    <string name=\"moire\">ਮੈਰੀ</string>\n    <string name=\"autumn\">ਪਤਝੜ</string>\n    <string name=\"bone\">ਹੱਡੀ</string>\n    <string name=\"jet\">ਜੈੱਟ</string>\n    <string name=\"winter\">ਸਰਦੀਆਂ</string>\n    <string name=\"ocean\">ਸਾਗਰ</string>\n    <string name=\"summer\">ਗਰਮੀਆਂ</string>\n    <string name=\"spring\">ਬਸੰਤ</string>\n    <string name=\"cool_variant\">ਠੰਡਾ ਵੇਰੀਐਂਟ</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">ਗੁਲਾਬੀ</string>\n    <string name=\"hot\">ਗਰਮ</string>\n    <string name=\"parula\">ਸ਼ਬਦ</string>\n    <string name=\"magma\">ਮੈਗਮਾ</string>\n    <string name=\"inferno\">ਇਨਫਰਨੋ</string>\n    <string name=\"plasma\">ਪਲਾਜ਼ਮਾ</string>\n    <string name=\"viridis\">ਵਿਰਿਡਿਸ</string>\n    <string name=\"cividis\">ਨਾਗਰਿਕ</string>\n    <string name=\"twilight\">ਸੰਧਿਆ</string>\n    <string name=\"twilight_shifted\">ਟਵਾਈਲਾਈਟ ਸ਼ਿਫਟ ਹੋ ਗਈ</string>\n    <string name=\"auto_perspective\">ਪਰਸਪੈਕਟਿਵ ਆਟੋ</string>\n    <string name=\"deskew\">ਡੈਸਕਿਊ</string>\n    <string name=\"allow_crop\">ਫਸਲ ਦੀ ਆਗਿਆ ਦਿਓ</string>\n    <string name=\"crop_or_perspective\">ਫਸਲ ਜਾਂ ਦ੍ਰਿਸ਼ਟੀਕੋਣ</string>\n    <string name=\"absolute\">ਸੰਪੂਰਨ</string>\n    <string name=\"turbo\">ਟਰਬੋ</string>\n    <string name=\"deep_green\">ਡੂੰਘੇ ਹਰੇ</string>\n    <string name=\"lens_correction\">ਲੈਂਸ ਸੁਧਾਰ</string>\n    <string name=\"target_lens_profile\">JSON ਫਾਰਮੈਟ ਵਿੱਚ ਟਾਰਗੇਟ ਲੈਂਸ ਪ੍ਰੋਫਾਈਲ ਫ਼ਾਈਲ</string>\n    <string name=\"download_ready_lens_profiles\">ਤਿਆਰ ਲੈਂਸ ਪ੍ਰੋਫਾਈਲਾਂ ਨੂੰ ਡਾਊਨਲੋਡ ਕਰੋ</string>\n    <string name=\"part_percents\">ਭਾਗ ਪ੍ਰਤੀਸ਼ਤ</string>\n    <string name=\"export_as_json\">JSON ਵਜੋਂ ਨਿਰਯਾਤ ਕਰੋ</string>\n    <string name=\"export_as_json_sub\">json ਨੁਮਾਇੰਦਗੀ ਦੇ ਤੌਰ \\'ਤੇ ਪੈਲੇਟ ਡੇਟਾ ਨਾਲ ਸਤਰ ਨੂੰ ਕਾਪੀ ਕਰੋ</string>\n    <string name=\"seam_carving\">ਸੀਮ ਕਾਰਵਿੰਗ</string>\n    <string name=\"home_screen\">ਹੋਮ ਸਕ੍ਰੀਨ</string>\n    <string name=\"lock_screen\">ਲਾਕ ਸਕ੍ਰੀਨ</string>\n    <string name=\"built_in\">ਬਿਲਟ-ਇਨ</string>\n    <string name=\"wallpapers_export\">ਵਾਲਪੇਪਰ ਨਿਰਯਾਤ</string>\n    <string name=\"refresh\">ਤਾਜ਼ਾ ਕਰੋ</string>\n    <string name=\"wallpapers_export_sub\">ਮੌਜੂਦਾ ਘਰ, ਲਾਕ ਅਤੇ ਬਿਲਟ-ਇਨ ਵਾਲਪੇਪਰ ਪ੍ਰਾਪਤ ਕਰੋ</string>\n    <string name=\"allow_access_to_all_files_for_wp\">ਸਾਰੀਆਂ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ, ਵਾਲਪੇਪਰਾਂ ਨੂੰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਇਸਦੀ ਲੋੜ ਹੈ</string>\n    <string name=\"allow_read_media_images_for_wp\">ਬਾਹਰੀ ਸਟੋਰੇਜ ਦੀ ਇਜਾਜ਼ਤ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨਾ ਕਾਫ਼ੀ ਨਹੀਂ ਹੈ, ਤੁਹਾਨੂੰ ਆਪਣੀਆਂ ਤਸਵੀਰਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਦੀ ਲੋੜ ਹੈ, \\\"ਸਭ ਨੂੰ ਇਜਾਜ਼ਤ ਦਿਓ\\\" ਨੂੰ ਚੁਣਨਾ ਯਕੀਨੀ ਬਣਾਓ।</string>\n    <string name=\"add_preset_to_filename\">ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਪ੍ਰੀਸੈਟ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_preset_to_filename_sub\">ਚਿੱਤਰ ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਚੁਣੇ ਹੋਏ ਪ੍ਰੀਸੈਟ ਨਾਲ ਪਿਛੇਤਰ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"add_image_scale_mode_to_filename\">ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਚਿੱਤਰ ਸਕੇਲ ਮੋਡ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">ਚੁਣੇ ਹੋਏ ਚਿੱਤਰ ਸਕੇਲ ਮੋਡ ਦੇ ਨਾਲ ਚਿੱਤਰ ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਪਿਛੇਤਰ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"ascii_art\">Ascii ਕਲਾ</string>\n    <string name=\"ascii_art_sub\">ਤਸਵੀਰ ਨੂੰ ascii ਟੈਕਸਟ ਵਿੱਚ ਬਦਲੋ ਜੋ ਚਿੱਤਰ ਵਰਗਾ ਦਿਖਾਈ ਦੇਵੇਗਾ</string>\n    <string name=\"params\">ਪਰਮ</string>\n    <string name=\"invert_colors_ascii_sub\">ਕੁਝ ਮਾਮਲਿਆਂ ਵਿੱਚ ਬਿਹਤਰ ਨਤੀਜੇ ਲਈ ਚਿੱਤਰ \\'ਤੇ ਨਕਾਰਾਤਮਕ ਫਿਲਟਰ ਲਾਗੂ ਕਰਦਾ ਹੈ</string>\n    <string name=\"processing_screenshot\">ਸਕ੍ਰੀਨਸ਼ੌਟ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ</string>\n    <string name=\"screenshot_not_captured_try_again\">ਸਕ੍ਰੀਨਸ਼ੌਟ ਕੈਪਚਰ ਨਹੀਂ ਕੀਤਾ ਗਿਆ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ</string>\n    <string name=\"skipped_saving\">ਸੁਰੱਖਿਅਤ ਕਰਨਾ ਛੱਡਿਆ ਗਿਆ</string>\n    <string name=\"skipped_saving_multiple\">%1$s ਫਾਈਲਾਂ ਛੱਡੀਆਂ ਗਈਆਂ</string>\n    <string name=\"allow_skip_if_larger\">ਜੇਕਰ ਵੱਡਾ ਹੋਵੇ ਤਾਂ ਛੱਡਣ ਦਿਓ</string>\n    <string name=\"allow_skip_if_larger_sub\">ਕੁਝ ਟੂਲਸ ਨੂੰ ਚਿੱਤਰਾਂ ਨੂੰ ਸੇਵ ਕਰਨਾ ਛੱਡਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ ਜਾਵੇਗੀ ਜੇਕਰ ਨਤੀਜੇ ਵਜੋਂ ਫਾਈਲ ਦਾ ਆਕਾਰ ਅਸਲ ਤੋਂ ਵੱਡਾ ਹੋਵੇਗਾ</string>\n    <string name=\"qr_type_calendar_event\">ਕੈਲੰਡਰ ਇਵੈਂਟ</string>\n    <string name=\"qr_type_contact_info\">ਸੰਪਰਕ ਕਰੋ</string>\n    <string name=\"qr_type_email\">ਈਮੇਲ</string>\n    <string name=\"qr_type_geo_point\">ਟਿਕਾਣਾ</string>\n    <string name=\"qr_type_phone\">ਫ਼ੋਨ</string>\n    <string name=\"qr_type_plain\">ਟੈਕਸਟ</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">ਵਾਈ-ਫਾਈ</string>\n    <string name=\"open_network\">ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">ਫ਼ੋਨ</string>\n    <string name=\"message\">ਸੁਨੇਹਾ</string>\n    <string name=\"address\">ਪਤਾ</string>\n    <string name=\"subject\">ਵਿਸ਼ਾ</string>\n    <string name=\"body\">ਸਰੀਰ</string>\n    <string name=\"name\">ਨਾਮ</string>\n    <string name=\"organization\">ਸੰਗਠਨ</string>\n    <string name=\"title\">ਸਿਰਲੇਖ</string>\n    <string name=\"phones\">ਫ਼ੋਨ</string>\n    <string name=\"emails\">ਈਮੇਲਾਂ</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">ਪਤੇ</string>\n    <string name=\"summary\">ਸੰਖੇਪ</string>\n    <string name=\"description\">ਵਰਣਨ</string>\n    <string name=\"location\">ਟਿਕਾਣਾ</string>\n    <string name=\"organizer\">ਆਯੋਜਕ</string>\n    <string name=\"start_date\">ਤਾਰੀਖ ਸ਼ੁਰੂ</string>\n    <string name=\"end_date\">ਸਮਾਪਤੀ ਮਿਤੀ</string>\n    <string name=\"status\">ਸਥਿਤੀ</string>\n    <string name=\"latitude\">ਵਿਥਕਾਰ</string>\n    <string name=\"longitude\">ਲੰਬਕਾਰ</string>\n    <string name=\"create_barcode\">ਬਾਰਕੋਡ ਬਣਾਓ</string>\n    <string name=\"edit_barcode\">ਬਾਰਕੋਡ ਦਾ ਸੰਪਾਦਨ ਕਰੋ</string>\n    <string name=\"wifi_configuration\">Wi-Fi ਸੰਰਚਨਾ</string>\n    <string name=\"security\">ਸੁਰੱਖਿਆ</string>\n    <string name=\"pick_contact\">ਸੰਪਰਕ ਚੁਣੋ</string>\n    <string name=\"grant_contact_permission\">ਚੁਣੇ ਗਏ ਸੰਪਰਕ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਆਟੋਫਿਲ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਸੰਪਰਕਾਂ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ</string>\n    <string name=\"contact_info\">ਸੰਪਰਕ ਜਾਣਕਾਰੀ</string>\n    <string name=\"first_name\">ਪਹਿਲਾ ਨਾਂ</string>\n    <string name=\"middle_name\">ਵਿਚਕਾਰਲਾ ਨਾਂ</string>\n    <string name=\"last_name\">ਆਖਰੀ ਨਾਂਮ</string>\n    <string name=\"pronunciation\">ਉਚਾਰਣ</string>\n    <string name=\"add_phone\">ਫ਼ੋਨ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_email\">ਈਮੇਲ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"add_address\">ਪਤਾ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"website\">ਵੈੱਬਸਾਈਟ</string>\n    <string name=\"add_website\">ਵੈੱਬਸਾਈਟ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"formatted_name\">ਫਾਰਮੈਟ ਕੀਤਾ ਨਾਮ</string>\n    <string name=\"qr_code_top_image\">ਇਹ ਚਿੱਤਰ ਬਾਰਕੋਡ ਦੇ ਉੱਪਰ ਰੱਖਣ ਲਈ ਵਰਤਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"code_customization\">ਕੋਡ ਅਨੁਕੂਲਤਾ</string>\n    <string name=\"qr_logo_image\">ਇਹ ਚਿੱਤਰ QR ਕੋਡ ਦੇ ਕੇਂਦਰ ਵਿੱਚ ਲੋਗੋ ਵਜੋਂ ਵਰਤਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"logo\">ਲੋਗੋ</string>\n    <string name=\"logo_padding\">ਲੋਗੋ ਪੈਡਿੰਗ</string>\n    <string name=\"logo_size\">ਲੋਗੋ ਦਾ ਆਕਾਰ</string>\n    <string name=\"logo_corners\">ਲੋਗੋ ਕੋਨੇ</string>\n    <string name=\"fourth_eye\">ਚੌਥੀ ਅੱਖ</string>\n    <string name=\"fourth_eye_description\">ਹੇਠਲੇ ਸਿਰੇ ਦੇ ਕੋਨੇ \\'ਤੇ ਚੌਥੀ ਅੱਖ ਜੋੜ ਕੇ ਕਿਊਆਰ ਕੋਡ ਵਿੱਚ ਅੱਖਾਂ ਦੀ ਸਮਰੂਪਤਾ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"pixel_shape\">ਪਿਕਸਲ ਆਕਾਰ</string>\n    <string name=\"frame_shape\">ਫਰੇਮ ਸ਼ਕਲ</string>\n    <string name=\"ball_shape\">ਗੇਂਦ ਦੀ ਸ਼ਕਲ</string>\n    <string name=\"error_correction_level\">ਗਲਤੀ ਸੁਧਾਰ ਪੱਧਰ</string>\n    <string name=\"dark_color\">ਗੂੜਾ ਰੰਗ</string>\n    <string name=\"light_color\">ਹਲਕਾ ਰੰਗ</string>\n    <string name=\"hyper_os\">ਹਾਈਪਰ ਓ.ਐਸ</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS ਵਰਗੀ ਸ਼ੈਲੀ</string>\n    <string name=\"mask_pattern\">ਮਾਸਕ ਪੈਟਰਨ</string>\n    <string name=\"code_may_be_not_scannable\">ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਕੋਡ ਸਕੈਨ ਕਰਨ ਯੋਗ ਨਾ ਹੋਵੇ, ਇਸ ਨੂੰ ਸਾਰੀਆਂ ਡਿਵਾਈਸਾਂ ਨਾਲ ਪੜ੍ਹਨਯੋਗ ਬਣਾਉਣ ਲਈ ਦਿੱਖ ਪੈਰਾਮਾਂ ਨੂੰ ਬਦਲੋ</string>\n    <string name=\"not_scannable\">ਸਕੈਨ ਕਰਨ ਯੋਗ ਨਹੀਂ</string>\n    <string name=\"launcher_mode_sub\">ਟੂਲ ਵਧੇਰੇ ਸੰਖੇਪ ਹੋਣ ਲਈ ਹੋਮ ਸਕ੍ਰੀਨ ਐਪ ਲਾਂਚਰ ਵਾਂਗ ਦਿਖਾਈ ਦੇਣਗੇ</string>\n    <string name=\"launcher_mode\">ਲਾਂਚਰ ਮੋਡ</string>\n    <string name=\"flood_fill_sub\">ਚੁਣੇ ਹੋਏ ਬੁਰਸ਼ ਅਤੇ ਸ਼ੈਲੀ ਨਾਲ ਇੱਕ ਖੇਤਰ ਭਰਦਾ ਹੈ</string>\n    <string name=\"flood_fill\">ਹੜ੍ਹ ਭਰਨ</string>\n    <string name=\"spray\">ਸਪਰੇਅ ਕਰੋ</string>\n    <string name=\"spray_sub\">ਗ੍ਰੈਫਿਟੀ ਸਟਾਈਲ ਵਾਲਾ ਮਾਰਗ ਖਿੱਚਦਾ ਹੈ</string>\n    <string name=\"square_particles\">ਵਰਗ ਕਣ</string>\n    <string name=\"square_particles_sub\">ਸਪਰੇਅ ਕਣ ਚੱਕਰ ਦੀ ਬਜਾਏ ਵਰਗ ਆਕਾਰ ਦੇ ਹੋਣਗੇ</string>\n    <string name=\"palette_tools\">ਪੈਲੇਟ ਟੂਲ</string>\n    <string name=\"palette_tools_sub\">ਚਿੱਤਰ ਤੋਂ ਮੂਲ/ਪੱਤਰ ਤਿਆਰ ਕਰੋ, ਜਾਂ ਵੱਖ-ਵੱਖ ਪੈਲੇਟ ਫਾਰਮੈਟਾਂ ਵਿੱਚ ਆਯਾਤ/ਨਿਰਯਾਤ ਕਰੋ</string>\n    <string name=\"edit_palette\">ਪੈਲੇਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ</string>\n    <string name=\"edit_palette_sub\">ਵੱਖ-ਵੱਖ ਫਾਰਮੈਟਾਂ ਵਿੱਚ ਨਿਰਯਾਤ/ਆਯਾਤ ਪੈਲੇਟ</string>\n    <string name=\"color_name\">ਰੰਗ ਦਾ ਨਾਮ</string>\n    <string name=\"palette_name\">ਪੈਲੇਟ ਨਾਮ</string>\n    <string name=\"palette_format\">ਪੈਲੇਟ ਫਾਰਮੈਟ</string>\n    <string name=\"export_palette_sub\">ਤਿਆਰ ਕੀਤੇ ਪੈਲੇਟ ਨੂੰ ਵੱਖ-ਵੱਖ ਫਾਰਮੈਟਾਂ ਵਿੱਚ ਨਿਰਯਾਤ ਕਰੋ</string>\n    <string name=\"add_color_palette_sub\">ਮੌਜੂਦਾ ਪੈਲੇਟ ਵਿੱਚ ਨਵਾਂ ਰੰਗ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"palette_name_not_supported\">%1$s ਫਾਰਮੈਟ ਪੈਲੇਟ ਨਾਮ ਪ੍ਰਦਾਨ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ</string>\n    <string name=\"wallpapers_export_not_avaialbe\">ਪਲੇ ਸਟੋਰ ਨੀਤੀਆਂ ਦੇ ਕਾਰਨ, ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਮੌਜੂਦਾ ਬਿਲਡ ਵਿੱਚ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ। ਇਸ ਕਾਰਜਕੁਸ਼ਲਤਾ ਨੂੰ ਐਕਸੈਸ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਕਿਸੇ ਵਿਕਲਪਿਕ ਸਰੋਤ ਤੋਂ ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਨੂੰ ਡਾਊਨਲੋਡ ਕਰੋ। ਤੁਸੀਂ ਹੇਠਾਂ GitHub \\'ਤੇ ਉਪਲਬਧ ਬਿਲਡਾਂ ਨੂੰ ਲੱਭ ਸਕਦੇ ਹੋ।</string>\n    <string name=\"open_github_page\">Github ਪੰਨਾ ਖੋਲ੍ਹੋ</string>\n    <string name=\"overwrite_files_sub_short\">ਮੂਲ ਫਾਈਲ ਨੂੰ ਚੁਣੇ ਹੋਏ ਫੋਲਡਰ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਬਜਾਏ ਨਵੀਂ ਫਾਈਲ ਨਾਲ ਬਦਲ ਦਿੱਤਾ ਜਾਵੇਗਾ</string>\n    <string name=\"hidden_watermark_text_detected\">ਲੁਕੇ ਹੋਏ ਵਾਟਰਮਾਰਕ ਟੈਕਸਟ ਦਾ ਪਤਾ ਲਗਾਇਆ ਗਿਆ</string>\n    <string name=\"hidden_watermark_image_detected\">ਲੁਕੇ ਹੋਏ ਵਾਟਰਮਾਰਕ ਚਿੱਤਰ ਨੂੰ ਖੋਜਿਆ ਗਿਆ</string>\n    <string name=\"this_image_was_hidden\">ਇਹ ਚਿੱਤਰ ਲੁਕਿਆ ਹੋਇਆ ਸੀ</string>\n    <string name=\"generative_inpaint\">ਜਨਰੇਟਿਵ ਪੇਂਟਿੰਗ</string>\n    <string name=\"generative_inpaint_sub\">ਤੁਹਾਨੂੰ OpenCV \\'ਤੇ ਭਰੋਸਾ ਕੀਤੇ ਬਿਨਾਂ, AI ਮਾਡਲ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਇੱਕ ਚਿੱਤਰ ਵਿੱਚ ਵਸਤੂਆਂ ਨੂੰ ਹਟਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ। ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ, ਐਪ GitHub ਤੋਂ ਲੋੜੀਂਦੇ ਮਾਡਲ (~ 200 MB) ਨੂੰ ਡਾਊਨਲੋਡ ਕਰੇਗੀ</string>\n    <string name=\"generative_inpaint_ready_sub\">ਤੁਹਾਨੂੰ OpenCV \\'ਤੇ ਭਰੋਸਾ ਕੀਤੇ ਬਿਨਾਂ, AI ਮਾਡਲ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਇੱਕ ਚਿੱਤਰ ਵਿੱਚ ਵਸਤੂਆਂ ਨੂੰ ਹਟਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ। ਇਹ ਇੱਕ ਲੰਬਾ ਚੱਲਦਾ ਆਪ੍ਰੇਸ਼ਨ ਹੋ ਸਕਦਾ ਹੈ</string>\n    <string name=\"error_level_analysis\">ਗਲਤੀ ਪੱਧਰ ਦਾ ਵਿਸ਼ਲੇਸ਼ਣ</string>\n    <string name=\"luminance_gradient\">ਲੂਮੀਨੈਂਸ ਗਰੇਡੀਐਂਟ</string>\n    <string name=\"average_distance\">ਔਸਤ ਦੂਰੀ</string>\n    <string name=\"copy_move_detection\">ਮੂਵ ਡਿਟੈਕਸ਼ਨ ਕਾਪੀ ਕਰੋ</string>\n    <string name=\"retain\">ਬਰਕਰਾਰ ਰੱਖੋ</string>\n    <string name=\"coefficent\">ਗੁਣਾਂਕ</string>\n    <string name=\"clipboard_data_is_too_large\">ਕਲਿੱਪਬੋਰਡ ਡਾਟਾ ਬਹੁਤ ਵੱਡਾ ਹੈ</string>\n    <string name=\"data_is_too_large_to_copy\">ਕਾਪੀ ਕਰਨ ਲਈ ਡਾਟਾ ਬਹੁਤ ਵੱਡਾ ਹੈ</string>\n    <string name=\"simple_weave_pixelization\">ਸਧਾਰਨ ਵੇਵ ਪਿਕਸਲਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"staggered_pixelization\">ਅਟਕਿਆ ਹੋਇਆ ਪਿਕਸਲੀਕਰਨ</string>\n    <string name=\"cross_pixelization\">ਕ੍ਰਾਸ Pixelization</string>\n    <string name=\"micro_macro_pixelization\">ਮਾਈਕ੍ਰੋ ਮੈਕਰੋ ਪਿਕਸਲਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"orbital_pixelization\">ਔਰਬਿਟਲ ਪਿਕਸਲਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"vortex_pixelization\">ਵੌਰਟੇਕਸ ਪਿਕਸਲਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"pulse_grid_pixelization\">ਪਲਸ ਗਰਿੱਡ ਪਿਕਸਲਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"nucleus_pixelization\">ਨਿਊਕਲੀਅਸ ਪਿਕਸਲਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"radial_weave_pixelization\">ਰੇਡੀਅਲ ਵੇਵ ਪਿਕਸਲਾਈਜ਼ੇਸ਼ਨ</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\" ਨੂੰ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ</string>\n    <string name=\"snowfall_mode\">ਬਰਫ਼ਬਾਰੀ ਮੋਡ</string>\n    <string name=\"enabled\">ਸਮਰਥਿਤ</string>\n    <string name=\"border_frame\">ਬਾਰਡਰ ਫਰੇਮ</string>\n    <string name=\"glitch_variant\">ਗਲਿਚ ਵੇਰੀਐਂਟ</string>\n    <string name=\"channel_shift\">ਚੈਨਲ ਸ਼ਿਫਟ</string>\n    <string name=\"max_offset\">ਅਧਿਕਤਮ ਔਫਸੈੱਟ</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">ਬਲਾਕ ਗਲਿਚ</string>\n    <string name=\"block_size\">ਬਲਾਕ ਆਕਾਰ</string>\n    <string name=\"crt_curvature\">CRT ਵਕਰਤਾ</string>\n    <string name=\"curvature\">ਵਕਰਤਾ</string>\n    <string name=\"chroma\">ਕ੍ਰੋਮਾ</string>\n    <string name=\"pixel_melt\">ਪਿਕਸਲ ਪਿਘਲਾ</string>\n    <string name=\"max_drop\">ਅਧਿਕਤਮ ਡ੍ਰੌਪ</string>\n    <string name=\"ai_tools\">AI ਟੂਲਜ਼</string>\n    <string name=\"ai_tools_sub\">ਏਆਈ ਮਾਡਲਾਂ ਦੁਆਰਾ ਚਿੱਤਰਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਲਈ ਕਈ ਟੂਲ ਜਿਵੇਂ ਕਿ ਆਰਟੀਫੈਕਟ ਨੂੰ ਹਟਾਉਣਾ ਜਾਂ ਨਕਾਰਾ ਕਰਨਾ</string>\n    <string name=\"model_anime_undeint\">ਕੰਪਰੈਸ਼ਨ, ਜਾਗਡ ਲਾਈਨਾਂ</string>\n    <string name=\"model_broadcast\">ਕਾਰਟੂਨ, ਪ੍ਰਸਾਰਣ ਸੰਕੁਚਨ</string>\n    <string name=\"model_rgb_max_denoise_fp16\">ਆਮ ਕੰਪਰੈਸ਼ਨ, ਆਮ ਰੌਲਾ</string>\n    <string name=\"model_wb_denoise\">ਰੰਗਹੀਣ ਕਾਰਟੂਨ ਸ਼ੋਰ</string>\n    <string name=\"model_span_anime_pretrain\">ਤੇਜ਼, ਆਮ ਕੰਪਰੈਸ਼ਨ, ਆਮ ਰੌਲਾ, ਐਨੀਮੇਸ਼ਨ/ਕਾਮਿਕਸ/ਐਨੀਮੇ</string>\n    <string name=\"model_book_scan\">ਕਿਤਾਬ ਸਕੈਨਿੰਗ</string>\n    <string name=\"model_overexposure\">ਐਕਸਪੋਜਰ ਸੁਧਾਰ</string>\n    <string name=\"model_fbcnn_color_fp16\">ਆਮ ਕੰਪਰੈਸ਼ਨ, ਰੰਗ ਚਿੱਤਰਾਂ \\'ਤੇ ਵਧੀਆ</string>\n    <string name=\"model_fbcnn_gray_fp16\">ਆਮ ਕੰਪਰੈਸ਼ਨ, ਗ੍ਰੇਸਕੇਲ ਚਿੱਤਰਾਂ \\'ਤੇ ਵਧੀਆ</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">ਆਮ ਕੰਪਰੈਸ਼ਨ, ਗ੍ਰੇਸਕੇਲ ਚਿੱਤਰ, ਮਜ਼ਬੂਤ</string>\n    <string name=\"model_scunet_color_gan_fp16\">ਆਮ ਰੌਲਾ, ਰੰਗ ਚਿੱਤਰ</string>\n    <string name=\"model_scunet_color_psnr_fp16\">ਆਮ ਰੌਲਾ, ਰੰਗ ਚਿੱਤਰ, ਬਿਹਤਰ ਵੇਰਵੇ</string>\n    <string name=\"model_scunet_gray_15_fp16\">ਆਮ ਰੌਲਾ, ਗ੍ਰੇਸਕੇਲ ਚਿੱਤਰ</string>\n    <string name=\"model_scunet_gray_25_fp16\">ਆਮ ਰੌਲਾ, ਗ੍ਰੇਸਕੇਲ ਚਿੱਤਰ, ਮਜ਼ਬੂਤ</string>\n    <string name=\"model_scunet_gray_50_fp16\">ਆਮ ਰੌਲਾ, ਗ੍ਰੇਸਕੇਲ ਚਿੱਤਰ, ਸਭ ਤੋਂ ਮਜ਼ਬੂਤ</string>\n    <string name=\"model_jpeg_destroyer\">ਆਮ ਕੰਪਰੈਸ਼ਨ</string>\n    <string name=\"model_jaywreck\">ਆਮ ਕੰਪਰੈਸ਼ਨ</string>\n    <string name=\"model_h264\">ਟੈਕਸਟੁਰਾਈਜ਼ੇਸ਼ਨ, h264 ਕੰਪਰੈਸ਼ਨ</string>\n    <string name=\"model_vhs\">VHS ਕੰਪਰੈਸ਼ਨ</string>\n    <string name=\"model_cinepak\">ਗੈਰ-ਸਟੈਂਡਰਡ ਕੰਪਰੈਸ਼ਨ (ਸਿਨਪੈਕ, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">ਬਿੰਕ ਕੰਪਰੈਸ਼ਨ, ਜਿਓਮੈਟਰੀ \\'ਤੇ ਬਿਹਤਰ</string>\n    <string name=\"model_debink_v5\">ਬਿੰਕ ਕੰਪਰੈਸ਼ਨ, ਮਜ਼ਬੂਤ</string>\n    <string name=\"model_debink_v6\">ਬਿੰਕ ਕੰਪਰੈਸ਼ਨ, ਨਰਮ, ਵੇਰਵੇ ਨੂੰ ਬਰਕਰਾਰ ਰੱਖਦਾ ਹੈ</string>\n    <string name=\"model_antialias\">ਪੌੜੀ-ਕਦਮ ਪ੍ਰਭਾਵ ਨੂੰ ਖਤਮ ਕਰਨਾ, ਸਮੂਥਿੰਗ</string>\n    <string name=\"model_kdm_scans\">ਸਕੈਨ ਕੀਤੀ ਕਲਾ/ਡਰਾਇੰਗ, ਮਾਮੂਲੀ ਕੰਪਰੈਸ਼ਨ, ਮੋਇਰ</string>\n    <string name=\"model_bandage\">ਰੰਗ ਬੈਂਡਿੰਗ</string>\n    <string name=\"model_halftone\">ਹੌਲੀ, ਹਾਫਟੋਨਸ ਨੂੰ ਹਟਾਉਣਾ</string>\n    <string name=\"model_colorizer\">ਗ੍ਰੇਸਕੇਲ/bw ਚਿੱਤਰਾਂ ਲਈ ਜਨਰਲ ਕਲਰਾਈਜ਼ਰ, ਬਿਹਤਰ ਨਤੀਜਿਆਂ ਲਈ ਡੀਡੀਕਲਰ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"model_deedge\">ਕਿਨਾਰੇ ਨੂੰ ਹਟਾਉਣਾ</string>\n    <string name=\"model_desharpen\">ਓਵਰਸ਼ਾਰਪਨਿੰਗ ਨੂੰ ਹਟਾਉਂਦਾ ਹੈ</string>\n    <string name=\"model_dither\">ਧੀਮਾ, ਭਟਕਣਾ</string>\n    <string name=\"model_gainres\">ਐਂਟੀ-ਅਲਾਈਜ਼ਿੰਗ, ਜਨਰਲ ਆਰਟੀਫੈਕਟਸ, ਸੀ.ਜੀ.ਆਈ</string>\n    <string name=\"model_kdm003_scans\">KDM003 ਸਕੈਨ ਪ੍ਰੋਸੈਸਿੰਗ</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">ਲਾਈਟਵੇਟ ਚਿੱਤਰ ਸੁਧਾਰ ਮਾਡਲ</string>\n    <string name=\"model_bcgone_detailed_v2\">ਕੰਪਰੈਸ਼ਨ ਆਰਟੀਫੈਕਟ ਹਟਾਉਣਾ</string>\n    <string name=\"model_bcgone_smooth\">ਕੰਪਰੈਸ਼ਨ ਆਰਟੀਫੈਕਟ ਹਟਾਉਣਾ</string>\n    <string name=\"model_bandage_smooth\">ਨਿਰਵਿਘਨ ਨਤੀਜਿਆਂ ਨਾਲ ਪੱਟੀ ਨੂੰ ਹਟਾਉਣਾ</string>\n    <string name=\"model_bendel_halftone\">ਹਾਫਟੋਨ ਪੈਟਰਨ ਪ੍ਰੋਸੈਸਿੰਗ</string>\n    <string name=\"model_dither_deleter_v3_smooth\">ਡਿਥਰ ਪੈਟਰਨ ਹਟਾਉਣ V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG ਆਰਟੀਫੈਕਟ ਹਟਾਉਣਾ V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 ਟੈਕਸਟ ਸੁਧਾਰ</string>\n    <string name=\"model_vhs_sharpen\">VHS ਸ਼ਾਰਪਨਿੰਗ ਅਤੇ ਇਨਹਾਂਸਮੈਂਟ</string>\n    <string name=\"merging\">ਮਿਲਾਉਣਾ</string>\n    <string name=\"chunk_size\">ਚੰਕ ਦਾ ਆਕਾਰ</string>\n    <string name=\"overlap_size\">ਓਵਰਲੈਪ ਆਕਾਰ</string>\n    <string name=\"note_chunk_info\">%1$s px ਤੋਂ ਵੱਧ ਚਿੱਤਰਾਂ ਨੂੰ ਟੁਕੜਿਆਂ ਵਿੱਚ ਕੱਟਿਆ ਜਾਵੇਗਾ ਅਤੇ ਸੰਸਾਧਿਤ ਕੀਤਾ ਜਾਵੇਗਾ, ਦਿਖਣਯੋਗ ਸੀਮਾਂ ਨੂੰ ਰੋਕਣ ਲਈ ਇਹਨਾਂ ਨੂੰ ਓਵਰਲੈਪ ਮਿਲਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"large_chunk_warning\">ਵੱਡੇ ਆਕਾਰ ਘੱਟ-ਅੰਤ ਵਾਲੇ ਡਿਵਾਈਸਾਂ ਨਾਲ ਅਸਥਿਰਤਾ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੇ ਹਨ</string>\n    <string name=\"select_one_to_start\">ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਇੱਕ ਚੁਣੋ</string>\n    <string name=\"delete_model_sub\">ਕੀ ਤੁਸੀਂ %1$s ਮਾਡਲ ਨੂੰ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਨੂੰ ਇਸਨੂੰ ਦੁਬਾਰਾ ਡਾਊਨਲੋਡ ਕਰਨ ਦੀ ਲੋੜ ਹੋਵੇਗੀ</string>\n    <string name=\"confirm\">ਪੁਸ਼ਟੀ ਕਰੋ</string>\n    <string name=\"models\">ਮਾਡਲ</string>\n    <string name=\"downloaded_models\">ਡਾਊਨਲੋਡ ਕੀਤੇ ਮਾਡਲ</string>\n    <string name=\"available_models\">ਉਪਲਬਧ ਮਾਡਲ</string>\n    <string name=\"preparing\">ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ</string>\n    <string name=\"active_model\">ਸਰਗਰਮ ਮਾਡਲ</string>\n    <string name=\"failed_to_open_session\">ਸੈਸ਼ਨ ਖੋਲ੍ਹਣ ਵਿੱਚ ਅਸਫਲ</string>\n    <string name=\"only_onnx_models\">ਸਿਰਫ਼ .onnx/.ort ਮਾਡਲਾਂ ਨੂੰ ਆਯਾਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ</string>\n    <string name=\"import_model\">ਮਾਡਲ ਆਯਾਤ ਕਰੋ</string>\n    <string name=\"import_model_sub\">ਹੋਰ ਵਰਤੋਂ ਲਈ ਕਸਟਮ onnx ਮਾਡਲ ਆਯਾਤ ਕਰੋ, ਸਿਰਫ਼ onnx/ort ਮਾਡਲ ਸਵੀਕਾਰ ਕੀਤੇ ਜਾਂਦੇ ਹਨ, ਲਗਭਗ ਸਾਰੇ esrgan ਜਿਵੇਂ ਕਿ ਰੂਪਾਂ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ</string>\n    <string name=\"imported_models\">ਆਯਾਤ ਕੀਤੇ ਮਾਡਲ</string>\n    <string name=\"model_scunet_color_15_fp16\">ਆਮ ਰੌਲਾ, ਰੰਗੀਨ ਚਿੱਤਰ</string>\n    <string name=\"model_scunet_color_25_fp16\">ਆਮ ਰੌਲਾ, ਰੰਗੀਨ ਚਿੱਤਰ, ਮਜ਼ਬੂਤ</string>\n    <string name=\"model_scunet_color_50_fp16\">ਆਮ ਰੌਲਾ, ਰੰਗੀਨ ਚਿੱਤਰ, ਸਭ ਤੋਂ ਮਜ਼ਬੂਤ</string>\n    <string name=\"model_artifacts_dithering_alsa\">ਡਿਥਰਿੰਗ ਆਰਟੀਫੈਕਟਸ ਅਤੇ ਕਲਰ ਬੈਂਡਿੰਗ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ, ਨਿਰਵਿਘਨ ਗਰੇਡੀਐਂਟ ਅਤੇ ਫਲੈਟ ਰੰਗ ਖੇਤਰਾਂ ਨੂੰ ਸੁਧਾਰਦਾ ਹੈ।</string>\n    <string name=\"model_nmkd_brighten_redux\">ਕੁਦਰਤੀ ਰੰਗਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦੇ ਹੋਏ ਸੰਤੁਲਿਤ ਹਾਈਲਾਈਟਸ ਦੇ ਨਾਲ ਚਿੱਤਰ ਦੀ ਚਮਕ ਅਤੇ ਵਿਪਰੀਤਤਾ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_nmkd_brighten\">ਵੇਰਵਿਆਂ ਨੂੰ ਰੱਖਦੇ ਹੋਏ ਅਤੇ ਜ਼ਿਆਦਾ ਐਕਸਪੋਜ਼ਰ ਤੋਂ ਬਚਣ ਦੌਰਾਨ ਹਨੇਰੇ ਚਿੱਤਰਾਂ ਨੂੰ ਚਮਕਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_nmkd_detoon\">ਬਹੁਤ ਜ਼ਿਆਦਾ ਰੰਗ ਟੋਨਿੰਗ ਨੂੰ ਹਟਾਉਂਦਾ ਹੈ ਅਤੇ ਵਧੇਰੇ ਨਿਰਪੱਖ ਅਤੇ ਕੁਦਰਤੀ ਰੰਗ ਸੰਤੁਲਨ ਨੂੰ ਬਹਾਲ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_noise_toner_poisson_detailed\">ਵਧੀਆ ਵੇਰਵਿਆਂ ਅਤੇ ਟੈਕਸਟ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਣ \\'ਤੇ ਜ਼ੋਰ ਦੇ ਨਾਲ ਪੋਇਸਨ-ਅਧਾਰਤ ਸ਼ੋਰ ਟੋਨਿੰਗ ਲਾਗੂ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_noise_toner_poisson_soft\">ਨਿਰਵਿਘਨ ਅਤੇ ਘੱਟ ਹਮਲਾਵਰ ਵਿਜ਼ੂਅਲ ਨਤੀਜਿਆਂ ਲਈ ਨਰਮ ਪੋਇਸਨ ਸ਼ੋਰ ਟੋਨਿੰਗ ਲਾਗੂ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_noise_toner_uniform_detailed\">ਇਕਸਾਰ ਸ਼ੋਰ ਟੋਨਿੰਗ ਵੇਰਵੇ ਦੀ ਸੰਭਾਲ ਅਤੇ ਚਿੱਤਰ ਸਪਸ਼ਟਤਾ \\'ਤੇ ਕੇਂਦ੍ਰਿਤ ਹੈ।</string>\n    <string name=\"model_noise_toner_uniform_soft\">ਸੂਖਮ ਟੈਕਸਟ ਅਤੇ ਨਿਰਵਿਘਨ ਦਿੱਖ ਲਈ ਕੋਮਲ ਇਕਸਾਰ ਸ਼ੋਰ ਟੋਨਿੰਗ।</string>\n    <string name=\"model_repainter\">ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਦੁਬਾਰਾ ਪੇਂਟ ਕਰਕੇ ਅਤੇ ਚਿੱਤਰ ਦੀ ਇਕਸਾਰਤਾ ਵਿੱਚ ਸੁਧਾਰ ਕਰਕੇ ਖਰਾਬ ਜਾਂ ਅਸਮਾਨ ਖੇਤਰਾਂ ਦੀ ਮੁਰੰਮਤ ਕਰੋ।</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">ਲਾਈਟਵੇਟ ਡੀਬੈਂਡਿੰਗ ਮਾਡਲ ਜੋ ਘੱਟੋ-ਘੱਟ ਪ੍ਰਦਰਸ਼ਨ ਲਾਗਤ ਨਾਲ ਰੰਗ ਬੈਂਡਿੰਗ ਨੂੰ ਹਟਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_jpeg_0_20\">ਬਿਹਤਰ ਸਪੱਸ਼ਟਤਾ ਲਈ ਬਹੁਤ ਉੱਚ ਸੰਕੁਚਨ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ (0-20% ਗੁਣਵੱਤਾ) ਦੇ ਨਾਲ ਚਿੱਤਰਾਂ ਨੂੰ ਅਨੁਕੂਲਿਤ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_jpeg_20_40\">ਉੱਚ ਸੰਕੁਚਨ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ (20-40% ਗੁਣਵੱਤਾ), ਵੇਰਵਿਆਂ ਨੂੰ ਬਹਾਲ ਕਰਨ ਅਤੇ ਰੌਲੇ ਨੂੰ ਘਟਾਉਣ ਵਾਲੀਆਂ ਤਸਵੀਰਾਂ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_jpeg_40_60\">ਮੱਧਮ ਕੰਪਰੈਸ਼ਨ (40-60% ਗੁਣਵੱਤਾ), ਤਿੱਖਾਪਨ ਅਤੇ ਨਿਰਵਿਘਨਤਾ ਨੂੰ ਸੰਤੁਲਿਤ ਕਰਨ ਵਾਲੇ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਧਾਰਦਾ ਹੈ।</string>\n    <string name=\"model_jpeg_60_80\">ਸੂਖਮ ਵੇਰਵਿਆਂ ਅਤੇ ਟੈਕਸਟ ਨੂੰ ਵਧਾਉਣ ਲਈ ਲਾਈਟ ਕੰਪਰੈਸ਼ਨ (60-80% ਗੁਣਵੱਤਾ) ਨਾਲ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਧਾਰਦਾ ਹੈ।</string>\n    <string name=\"model_jpeg_80_100\">ਕੁਦਰਤੀ ਦਿੱਖ ਅਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦੇ ਹੋਏ ਨੇੜੇ-ਨੁਕਸਾਨ ਰਹਿਤ ਚਿੱਤਰਾਂ (80-100% ਗੁਣਵੱਤਾ) ਨੂੰ ਥੋੜ੍ਹਾ ਵਧਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_spongecolor_lite\">ਸਧਾਰਨ ਅਤੇ ਤੇਜ਼ ਰੰਗੀਕਰਨ, ਕਾਰਟੂਨ, ਆਦਰਸ਼ ਨਹੀਂ</string>\n    <string name=\"model_deblr\">ਚਿੱਤਰ ਦੇ ਧੁੰਦਲੇਪਣ ਨੂੰ ਥੋੜ੍ਹਾ ਘਟਾਉਂਦਾ ਹੈ, ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਪੇਸ਼ ਕੀਤੇ ਬਿਨਾਂ ਤਿੱਖਾਪਨ ਨੂੰ ਸੁਧਾਰਦਾ ਹੈ।</string>\n    <string name=\"processing_channel\">ਲੰਬੇ ਚੱਲ ਰਹੇ ਓਪਰੇਸ਼ਨ</string>\n    <string name=\"processing_image\">ਚਿੱਤਰ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ</string>\n    <string name=\"processing\">ਪ੍ਰੋਸੈਸਿੰਗ</string>\n    <string name=\"model_artifacts_jpg_0_20\">ਬਹੁਤ ਘੱਟ ਗੁਣਵੱਤਾ ਵਾਲੀਆਂ ਤਸਵੀਰਾਂ (0-20%) ਵਿੱਚ ਭਾਰੀ JPEG ਕੰਪਰੈਸ਼ਨ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਹਟਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_artifacts_jpg_20_40\">ਬਹੁਤ ਜ਼ਿਆਦਾ ਸੰਕੁਚਿਤ ਚਿੱਤਰਾਂ (20-40%) ਵਿੱਚ ਮਜ਼ਬੂਤ ​​JPEG ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_artifacts_jpg_40_60\">ਚਿੱਤਰ ਵੇਰਵਿਆਂ (40-60%) ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦੇ ਹੋਏ ਦਰਮਿਆਨੀ JPEG ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਸਾਫ਼ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_artifacts_jpg_60_80\">ਕਾਫ਼ੀ ਉੱਚ ਗੁਣਵੱਤਾ ਵਾਲੀਆਂ ਤਸਵੀਰਾਂ (60-80%) ਵਿੱਚ ਹਲਕੇ JPEG ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਸੋਧਦਾ ਹੈ।</string>\n    <string name=\"model_artifacts_jpg_80_100\">ਨੇੜੇ-ਨੁਕਸਾਨ ਰਹਿਤ ਚਿੱਤਰਾਂ (80-100%) ਵਿੱਚ ਮਾਮੂਲੀ JPEG ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_redetail_v2\">ਵਧੀਆ ਵੇਰਵਿਆਂ ਅਤੇ ਟੈਕਸਟ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ, ਭਾਰੀ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਬਿਨਾਂ ਸਮਝੀ ਗਈ ਤਿੱਖਾਪਨ ਨੂੰ ਸੁਧਾਰਦਾ ਹੈ।</string>\n    <string name=\"processing_finished\">ਪ੍ਰਕਿਰਿਆ ਪੂਰੀ ਹੋਈ</string>\n    <string name=\"processing_failed\">ਪ੍ਰਕਿਰਿਆ ਅਸਫਲ ਰਹੀ</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">ਸਪੀਡ ਲਈ ਅਨੁਕੂਲਿਤ, ਕੁਦਰਤੀ ਦਿੱਖ ਰੱਖਦੇ ਹੋਏ ਚਮੜੀ ਦੀ ਬਣਤਰ ਅਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG ਕੰਪਰੈਸ਼ਨ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਹਟਾਉਂਦਾ ਹੈ ਅਤੇ ਸੰਕੁਚਿਤ ਫੋਟੋਆਂ ਲਈ ਚਿੱਤਰ ਗੁਣਵੱਤਾ ਨੂੰ ਬਹਾਲ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_iso_denoise_v1\">ਵੇਰਵਿਆਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦੇ ਹੋਏ, ਘੱਟ ਰੋਸ਼ਨੀ ਵਾਲੀਆਂ ਸਥਿਤੀਆਂ ਵਿੱਚ ਲਈਆਂ ਗਈਆਂ ਫੋਟੋਆਂ ਵਿੱਚ ISO ਸ਼ੋਰ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_dejumbo\">ਓਵਰਐਕਸਪੋਜ਼ਡ ਜਾਂ \\\"ਜੰਬੋ\\\" ਹਾਈਲਾਈਟਸ ਨੂੰ ਠੀਕ ਕਰਦਾ ਹੈ ਅਤੇ ਬਿਹਤਰ ਟੋਨਲ ਸੰਤੁਲਨ ਨੂੰ ਬਹਾਲ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_ddcolor_tiny\">ਹਲਕਾ ਅਤੇ ਤੇਜ਼ ਰੰਗੀਕਰਨ ਮਾਡਲ ਜੋ ਗ੍ਰੇਸਕੇਲ ਚਿੱਤਰਾਂ ਵਿੱਚ ਕੁਦਰਤੀ ਰੰਗ ਜੋੜਦਾ ਹੈ।</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">ਰੰਗੀਨ ਕਰੋ</string>\n    <string name=\"type_artifacts\">ਕਲਾਕ੍ਰਿਤੀਆਂ</string>\n    <string name=\"type_enhance\">ਵਧਾਓ</string>\n    <string name=\"type_anime\">ਅਨੀਮੀ</string>\n    <string name=\"type_scans\">ਸਕੈਨ</string>\n    <string name=\"type_upscale\">ਅੱਪਸਕੇਲ</string>\n    <string name=\"model_realesrgan_x4v3\">ਆਮ ਚਿੱਤਰਾਂ ਲਈ X4 ਅੱਪਸਕੇਲਰ; ਛੋਟਾ ਮਾਡਲ ਜੋ ਘੱਟ GPU ਅਤੇ ਸਮਾਂ ਵਰਤਦਾ ਹੈ, ਮੱਧਮ deblur ਅਤੇ denoise ਦੇ ਨਾਲ.</string>\n    <string name=\"model_realesrgan_x2plus\">ਆਮ ਚਿੱਤਰਾਂ ਲਈ X2 ਅੱਪਸਕੇਲਰ, ਟੈਕਸਟ ਅਤੇ ਕੁਦਰਤੀ ਵੇਰਵਿਆਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨਾ।</string>\n    <string name=\"model_realesrgan_x4plus\">ਵਿਸਤ੍ਰਿਤ ਟੈਕਸਟ ਅਤੇ ਯਥਾਰਥਵਾਦੀ ਨਤੀਜਿਆਂ ਦੇ ਨਾਲ ਆਮ ਚਿੱਤਰਾਂ ਲਈ X4 ਅੱਪਸਕੇਲਰ।</string>\n    <string name=\"model_realesrgan_x4plus_anime\">ਐਕਸ 4 ਅਪਸਕੇਲਰ ਐਨੀਮੇ ਚਿੱਤਰਾਂ ਲਈ ਅਨੁਕੂਲਿਤ; ਤਿੱਖੀਆਂ ਲਾਈਨਾਂ ਅਤੇ ਵੇਰਵਿਆਂ ਲਈ 6 RRDB ਬਲਾਕ।</string>\n    <string name=\"model_realesrnet_x4plus\">MSE ਨੁਕਸਾਨ ਦੇ ਨਾਲ X4 ਅੱਪਸਕੇਲਰ, ਆਮ ਚਿੱਤਰਾਂ ਲਈ ਨਿਰਵਿਘਨ ਨਤੀਜੇ ਅਤੇ ਘਟਾਏ ਗਏ ਕਲਾਕ੍ਰਿਤੀਆਂ ਦਾ ਉਤਪਾਦਨ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">ਐਕਸ 4 ਅਪਸਕੇਲਰ ਐਨੀਮੇ ਚਿੱਤਰਾਂ ਲਈ ਅਨੁਕੂਲਿਤ; ਤਿੱਖੇ ਵੇਰਵਿਆਂ ਅਤੇ ਨਿਰਵਿਘਨ ਲਾਈਨਾਂ ਵਾਲਾ 4B32F ਵੇਰੀਐਂਟ।</string>\n    <string name=\"model_ultrasharp_v2_x4\">ਆਮ ਚਿੱਤਰਾਂ ਲਈ X4 UltraSharp V2 ਮਾਡਲ; ਤਿੱਖਾਪਨ ਅਤੇ ਸਪਸ਼ਟਤਾ \\'ਤੇ ਜ਼ੋਰ ਦਿੰਦਾ ਹੈ।</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; ਤੇਜ਼ ਅਤੇ ਛੋਟਾ, ਘੱਟ GPU ਮੈਮੋਰੀ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਵੇਰਵੇ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦਾ ਹੈ।</string>\n    <string name=\"model_rmbg_1_4\">ਤੇਜ਼ ਪਿਛੋਕੜ ਨੂੰ ਹਟਾਉਣ ਲਈ ਹਲਕਾ ਮਾਡਲ। ਸੰਤੁਲਿਤ ਪ੍ਰਦਰਸ਼ਨ ਅਤੇ ਸ਼ੁੱਧਤਾ. ਪੋਰਟਰੇਟ, ਵਸਤੂਆਂ ਅਤੇ ਦ੍ਰਿਸ਼ਾਂ ਨਾਲ ਕੰਮ ਕਰਦਾ ਹੈ। ਜ਼ਿਆਦਾਤਰ ਵਰਤੋਂ ਦੇ ਮਾਮਲਿਆਂ ਲਈ ਸਿਫਾਰਸ਼ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।</string>\n    <string name=\"type_removebg\">BG ਨੂੰ ਹਟਾਓ</string>\n    <string name=\"horizontal_border_thickness\">ਹਰੀਜ਼ੱਟਲ ਬਾਰਡਰ ਮੋਟਾਈ</string>\n    <string name=\"vertical_border_thickness\">ਵਰਟੀਕਲ ਬਾਰਡਰ ਮੋਟਾਈ</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s ਰੰਗ</item>\n        <item quantity=\"other\">%1$s ਰੰਗ</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">ਮੌਜੂਦਾ ਮਾਡਲ ਚੰਕਿੰਗ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ, ਚਿੱਤਰ ਨੂੰ ਅਸਲ ਮਾਪਾਂ ਵਿੱਚ ਸੰਸਾਧਿਤ ਕੀਤਾ ਜਾਵੇਗਾ, ਇਸ ਨਾਲ ਉੱਚ ਮੈਮੋਰੀ ਦੀ ਖਪਤ ਹੋ ਸਕਦੀ ਹੈ ਅਤੇ ਘੱਟ-ਅੰਤ ਵਾਲੇ ਡਿਵਾਈਸਾਂ ਨਾਲ ਸਮੱਸਿਆਵਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ</string>\n    <string name=\"chunking_disabled\">ਚੰਕਿੰਗ ਅਯੋਗ ਹੈ, ਚਿੱਤਰ ਨੂੰ ਅਸਲ ਮਾਪਾਂ ਵਿੱਚ ਸੰਸਾਧਿਤ ਕੀਤਾ ਜਾਵੇਗਾ, ਇਸ ਨਾਲ ਉੱਚ ਮੈਮੋਰੀ ਦੀ ਖਪਤ ਹੋ ਸਕਦੀ ਹੈ ਅਤੇ ਘੱਟ-ਅੰਤ ਵਾਲੇ ਡਿਵਾਈਸਾਂ ਨਾਲ ਸਮੱਸਿਆਵਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ ਪਰ ਅਨੁਮਾਨ \\'ਤੇ ਵਧੀਆ ਨਤੀਜੇ ਦੇ ਸਕਦੇ ਹਨ</string>\n    <string name=\"chunking\">ਚੁੰਨੀ</string>\n    <string name=\"model_u2net\">ਪਿਛੋਕੜ ਨੂੰ ਹਟਾਉਣ ਲਈ ਉੱਚ-ਸ਼ੁੱਧਤਾ ਚਿੱਤਰ ਵਿਭਾਜਨ ਮਾਡਲ</string>\n    <string name=\"model_u2netp\">ਛੋਟੀ ਮੈਮੋਰੀ ਵਰਤੋਂ ਦੇ ਨਾਲ ਤੇਜ਼ ਪਿਛੋਕੜ ਨੂੰ ਹਟਾਉਣ ਲਈ U2Net ਦਾ ਹਲਕਾ ਸੰਸਕਰਣ।</string>\n    <string name=\"model_ddcolor\">ਪੂਰਾ DDCcolor ਮਾਡਲ ਘੱਟੋ-ਘੱਟ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਦੇ ਨਾਲ ਆਮ ਚਿੱਤਰਾਂ ਲਈ ਉੱਚ-ਗੁਣਵੱਤਾ ਰੰਗੀਕਰਨ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ। ਸਾਰੇ ਰੰਗੀਕਰਨ ਮਾਡਲਾਂ ਦੀ ਸਭ ਤੋਂ ਵਧੀਆ ਚੋਣ।</string>\n    <string name=\"model_ddcolor_artistic\">ਡੀਡੀਕਲਰ ਸਿਖਲਾਈ ਪ੍ਰਾਪਤ ਅਤੇ ਨਿੱਜੀ ਕਲਾਤਮਕ ਡੇਟਾਸੇਟ; ਘੱਟ ਗੈਰ-ਯਥਾਰਥਵਾਦੀ ਰੰਗਾਂ ਦੀਆਂ ਕਲਾਕ੍ਰਿਤੀਆਂ ਦੇ ਨਾਲ ਵਿਭਿੰਨ ਅਤੇ ਕਲਾਤਮਕ ਰੰਗੀਕਰਨ ਨਤੀਜੇ ਪੈਦਾ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_birefnet\">ਬੈਕਗਰਾਊਂਡ ਨੂੰ ਸਹੀ ਤਰ੍ਹਾਂ ਹਟਾਉਣ ਲਈ ਸਵਿਨ ਟਰਾਂਸਫਾਰਮਰ \\'ਤੇ ਆਧਾਰਿਤ ਲਾਈਟਵੇਟ BiRefNet ਮਾਡਲ।</string>\n    <string name=\"model_inspyrenet\">ਤਿੱਖੇ ਕਿਨਾਰਿਆਂ ਅਤੇ ਸ਼ਾਨਦਾਰ ਵੇਰਵੇ ਦੀ ਸੰਭਾਲ ਦੇ ਨਾਲ ਉੱਚ-ਗੁਣਵੱਤਾ ਵਾਲੇ ਪਿਛੋਕੜ ਨੂੰ ਹਟਾਉਣਾ, ਖਾਸ ਤੌਰ \\'ਤੇ ਗੁੰਝਲਦਾਰ ਵਸਤੂਆਂ ਅਤੇ ਗੁੰਝਲਦਾਰ ਪਿਛੋਕੜਾਂ \\'ਤੇ।</string>\n    <string name=\"model_isnet\">ਬੈਕਗ੍ਰਾਉਂਡ ਹਟਾਉਣ ਵਾਲਾ ਮਾਡਲ ਜੋ ਨਿਰਵਿਘਨ ਕਿਨਾਰਿਆਂ ਦੇ ਨਾਲ ਸਹੀ ਮਾਸਕ ਪੈਦਾ ਕਰਦਾ ਹੈ, ਆਮ ਵਸਤੂਆਂ ਲਈ ਢੁਕਵਾਂ ਅਤੇ ਮੱਧਮ ਵੇਰਵੇ ਦੀ ਸੰਭਾਲ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_already_downloaded\">ਮਾਡਲ ਪਹਿਲਾਂ ਹੀ ਡਾਊਨਲੋਡ ਕੀਤਾ ਗਿਆ ਹੈ</string>\n    <string name=\"model_successfully_imported\">ਮਾਡਲ ਸਫਲਤਾਪੂਰਵਕ ਆਯਾਤ ਕੀਤਾ ਗਿਆ</string>\n    <string name=\"type\">ਟਾਈਪ ਕਰੋ</string>\n    <string name=\"keyword\">ਕੀਵਰਡ</string>\n    <string name=\"very_fast\">ਬਹੁਤ ਤੇਜ਼</string>\n    <string name=\"normal\">ਸਧਾਰਣ</string>\n    <string name=\"slow\">ਹੌਲੀ</string>\n    <string name=\"very_slow\">ਬਹੁਤ ਹੌਲੀ</string>\n    <string name=\"compute_percents\">ਗਣਨਾ ਪ੍ਰਤੀਸ਼ਤ</string>\n    <string name=\"minimum_value_is\">ਨਿਊਨਤਮ ਮੁੱਲ %1$s ਹੈ</string>\n    <string name=\"warp_sub\">ਉਂਗਲਾਂ ਨਾਲ ਚਿੱਤਰ ਬਣਾ ਕੇ ਚਿੱਤਰ ਨੂੰ ਵਿਗਾੜੋ</string>\n    <string name=\"warp\">ਵਾਰਪ</string>\n    <string name=\"hardness\">ਕਠੋਰਤਾ</string>\n    <string name=\"warp_mode\">ਵਾਰਪ ਮੋਡ</string>\n    <string name=\"warp_mode_move\">ਮੂਵ ਕਰੋ</string>\n    <string name=\"warp_mode_grow\">ਵਧੋ</string>\n    <string name=\"warp_mode_shrink\">ਸੁੰਗੜੋ</string>\n    <string name=\"warp_mode_swirl_cw\">ਘੁੰਮਣਾ CW</string>\n    <string name=\"warp_mode_swirl_ccw\">ਘੁੰਮਣਾ CCW</string>\n    <string name=\"fade_strength\">ਫੇਡ ਤਾਕਤ</string>\n    <string name=\"top_drop\">ਸਿਖਰ ਡ੍ਰੌਪ</string>\n    <string name=\"bottom_drop\">ਹੇਠਲਾ ਬੂੰਦ</string>\n    <string name=\"start_drop\">ਡ੍ਰੌਪ ਸ਼ੁਰੂ ਕਰੋ</string>\n    <string name=\"end_drop\">ਡ੍ਰੌਪ ਖਤਮ ਕਰੋ</string>\n    <string name=\"downloading\">ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ</string>\n    <string name=\"smooth_shapes\">ਨਿਰਵਿਘਨ ਆਕਾਰ</string>\n    <string name=\"smooth_shapes_sub\">ਨਿਰਵਿਘਨ, ਵਧੇਰੇ ਕੁਦਰਤੀ ਆਕਾਰਾਂ ਲਈ ਮਿਆਰੀ ਗੋਲ ਆਇਤਕਾਰ ਦੀ ਬਜਾਏ ਸੁਪਰਇਲਿਪਸ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"shape_type\">ਆਕਾਰ ਦੀ ਕਿਸਮ</string>\n    <string name=\"cut\">ਕੱਟੋ</string>\n    <string name=\"rounded\">ਗੋਲ ਕੀਤਾ</string>\n    <string name=\"smooth\">ਨਿਰਵਿਘਨ</string>\n    <string name=\"cut_shapes_sub\">ਗੋਲ ਕੀਤੇ ਬਿਨਾਂ ਤਿੱਖੇ ਕਿਨਾਰੇ</string>\n    <string name=\"rounded_shapes_sub\">ਕਲਾਸਿਕ ਗੋਲ ਕੋਨੇ</string>\n    <string name=\"shapes_type\">ਆਕਾਰ ਦੀ ਕਿਸਮ</string>\n    <string name=\"corners_size\">ਕੋਨਿਆਂ ਦਾ ਆਕਾਰ</string>\n    <string name=\"squircle\">ਸਕਰਕਲ</string>\n    <string name=\"squircle_shapes_sub\">ਸ਼ਾਨਦਾਰ ਗੋਲ UI ਤੱਤ</string>\n    <string name=\"filename_format\">ਫਾਈਲ ਨਾਮ ਫਾਰਮੈਟ</string>\n    <string name=\"prefix_pattern_description\">ਕਸਟਮ ਟੈਕਸਟ ਫਾਈਲ ਨਾਮ ਦੇ ਬਿਲਕੁਲ ਸ਼ੁਰੂ ਵਿੱਚ ਰੱਖਿਆ ਗਿਆ, ਪ੍ਰੋਜੈਕਟ ਦੇ ਨਾਮਾਂ, ਬ੍ਰਾਂਡਾਂ ਜਾਂ ਨਿੱਜੀ ਟੈਗਾਂ ਲਈ ਸੰਪੂਰਨ।</string>\n    <string name=\"original_filename_pattern_description\">ਸਰੋਤ ਪਛਾਣ ਨੂੰ ਬਰਕਰਾਰ ਰੱਖਣ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਦੇ ਹੋਏ, ਐਕਸਟੈਂਸ਼ਨ ਦੇ ਬਿਨਾਂ ਮੂਲ ਫਾਈਲ ਨਾਮ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"width_pattern_description\">ਚਿੱਤਰ ਦੀ ਚੌੜਾਈ ਪਿਕਸਲਾਂ ਵਿੱਚ, ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਤਬਦੀਲੀਆਂ ਜਾਂ ਨਤੀਜਿਆਂ ਨੂੰ ਸਕੇਲਿੰਗ ਕਰਨ ਲਈ ਉਪਯੋਗੀ।</string>\n    <string name=\"height_pattern_description\">ਚਿੱਤਰ ਦੀ ਉਚਾਈ ਪਿਕਸਲ ਵਿੱਚ, ਆਕਾਰ ਅਨੁਪਾਤ ਜਾਂ ਨਿਰਯਾਤ ਨਾਲ ਕੰਮ ਕਰਨ ਵੇਲੇ ਮਦਦਗਾਰ।</string>\n    <string name=\"random_numbers_pattern_description\">ਵਿਲੱਖਣ ਫਾਈਲਨਾਮਾਂ ਦੀ ਗਰੰਟੀ ਦੇਣ ਲਈ ਬੇਤਰਤੀਬ ਅੰਕ ਤਿਆਰ ਕਰਦਾ ਹੈ; ਡੁਪਲੀਕੇਟ ਦੇ ਵਿਰੁੱਧ ਵਾਧੂ ਸੁਰੱਖਿਆ ਲਈ ਹੋਰ ਅੰਕ ਜੋੜੋ।</string>\n    <string name=\"sequence_number_pattern_description\">ਬੈਚ ਨਿਰਯਾਤ ਲਈ ਸਵੈ-ਵਧਾਉਣ ਵਾਲਾ ਕਾਊਂਟਰ, ਇੱਕ ਸੈਸ਼ਨ ਵਿੱਚ ਕਈ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਵੇਲੇ ਆਦਰਸ਼।</string>\n    <string name=\"preset_info_pattern_description\">ਲਾਗੂ ਕੀਤੇ ਪ੍ਰੀਸੈਟ ਨਾਮ ਨੂੰ ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰਦਾ ਹੈ ਤਾਂ ਜੋ ਤੁਸੀਂ ਆਸਾਨੀ ਨਾਲ ਯਾਦ ਰੱਖ ਸਕੋ ਕਿ ਚਿੱਤਰ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਿਵੇਂ ਕੀਤੀ ਗਈ ਸੀ।</string>\n    <string name=\"scale_mode_pattern_description\">ਪ੍ਰੋਸੈਸਿੰਗ ਦੌਰਾਨ ਵਰਤੇ ਗਏ ਚਿੱਤਰ ਸਕੇਲਿੰਗ ਮੋਡ ਨੂੰ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰਦਾ ਹੈ, ਮੁੜ ਆਕਾਰ, ਕੱਟੇ ਜਾਂ ਫਿੱਟ ਕੀਤੇ ਚਿੱਤਰਾਂ ਨੂੰ ਵੱਖ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"suffix_pattern_description\">ਫਾਈਲ ਨਾਮ ਦੇ ਅੰਤ ਵਿੱਚ ਰੱਖਿਆ ਕਸਟਮ ਟੈਕਸਟ, _v2, _edited, ਜਾਂ _final ਵਰਗੇ ਸੰਸਕਰਣ ਲਈ ਉਪਯੋਗੀ।</string>\n    <string name=\"extension_pattern_description\">ਫਾਈਲ ਐਕਸਟੈਂਸ਼ਨ (png, jpg, webp, ਆਦਿ), ਆਪਣੇ ਆਪ ਅਸਲ ਸੁਰੱਖਿਅਤ ਕੀਤੇ ਫਾਰਮੈਟ ਨਾਲ ਮੇਲ ਖਾਂਦੀ ਹੈ।</string>\n    <string name=\"formatted_timestamp_pattern_description\">ਇੱਕ ਅਨੁਕੂਲਿਤ ਟਾਈਮਸਟੈਂਪ ਜੋ ਤੁਹਾਨੂੰ ਸੰਪੂਰਨ ਛਾਂਟੀ ਲਈ ਜਾਵਾ ਨਿਰਧਾਰਨ ਦੁਆਰਾ ਆਪਣੇ ਖੁਦ ਦੇ ਫਾਰਮੈਟ ਨੂੰ ਪਰਿਭਾਸ਼ਿਤ ਕਰਨ ਦਿੰਦਾ ਹੈ।</string>\n    <string name=\"fling_type\">ਫਲਿੰਗ ਦੀ ਕਿਸਮ</string>\n    <string name=\"android_native\">Android ਮੂਲ</string>\n    <string name=\"ios_style\">ਆਈਓਐਸ ਸ਼ੈਲੀ</string>\n    <string name=\"smooth_curve\">ਨਿਰਵਿਘਨ ਕਰਵ</string>\n    <string name=\"quick_stop\">ਤੇਜ਼ ਸਟਾਪ</string>\n    <string name=\"bouncy\">ਉਛਾਲ</string>\n    <string name=\"floaty\">ਫਲੋਟੀ</string>\n    <string name=\"snappy\">ਸਨੈਪੀ</string>\n    <string name=\"ultra_smooth\">ਅਤਿ ਨਿਰਵਿਘਨ</string>\n    <string name=\"adaptive\">ਅਨੁਕੂਲ</string>\n    <string name=\"accessibility_aware\">ਪਹੁੰਚਯੋਗਤਾ ਜਾਗਰੂਕ</string>\n    <string name=\"reduced_motion\">ਘਟੀ ਹੋਈ ਗਤੀ</string>\n    <string name=\"android_native_sub\">ਬੇਸਲਾਈਨ ਤੁਲਨਾ ਲਈ ਨੇਟਿਵ ਐਂਡਰਾਇਡ ਸਕ੍ਰੋਲ ਭੌਤਿਕ ਵਿਗਿਆਨ</string>\n    <string name=\"smooth_sub\">ਆਮ ਵਰਤੋਂ ਲਈ ਸੰਤੁਲਿਤ, ਨਿਰਵਿਘਨ ਸਕ੍ਰੋਲਿੰਗ</string>\n    <string name=\"ios_style_sub\">ਉੱਚ ਰਗੜ ਆਈਓਐਸ-ਵਰਗੇ ਸਕ੍ਰੌਲ ਵਿਵਹਾਰ</string>\n    <string name=\"smooth_curve_sub\">ਵੱਖਰੇ ਸਕ੍ਰੌਲ ਮਹਿਸੂਸ ਲਈ ਵਿਲੱਖਣ ਸਪਲਾਈਨ ਕਰਵ</string>\n    <string name=\"quick_stop_sub\">ਤੇਜ਼ ਰੁਕਣ ਦੇ ਨਾਲ ਸਹੀ ਸਕ੍ਰੋਲਿੰਗ</string>\n    <string name=\"bouncy_sub\">ਹੁਸ਼ਿਆਰ, ਜਵਾਬਦੇਹ ਉਛਾਲ ਵਾਲੀ ਸਕ੍ਰੌਲ</string>\n    <string name=\"floaty_sub\">ਸਮੱਗਰੀ ਬ੍ਰਾਊਜ਼ਿੰਗ ਲਈ ਲੰਬੇ, ਗਲਾਈਡਿੰਗ ਸਕ੍ਰੋਲ</string>\n    <string name=\"snappy_sub\">ਇੰਟਰਐਕਟਿਵ UIs ਲਈ ਤੇਜ਼, ਜਵਾਬਦੇਹ ਸਕ੍ਰੋਲਿੰਗ</string>\n    <string name=\"ultra_smooth_sub\">ਵਿਸਤ੍ਰਿਤ ਗਤੀ ਦੇ ਨਾਲ ਪ੍ਰੀਮੀਅਮ ਨਿਰਵਿਘਨ ਸਕ੍ਰੋਲਿੰਗ</string>\n    <string name=\"adaptive_sub\">ਫਲਿੰਗ ਵੇਲੋਸਿਟੀ ਦੇ ਆਧਾਰ \\'ਤੇ ਭੌਤਿਕ ਵਿਗਿਆਨ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰਦਾ ਹੈ</string>\n    <string name=\"accessibility_aware_sub\">ਸਿਸਟਮ ਪਹੁੰਚਯੋਗਤਾ ਸੈਟਿੰਗਾਂ ਦਾ ਆਦਰ ਕਰਦਾ ਹੈ</string>\n    <string name=\"reduced_motion_sub\">ਪਹੁੰਚਯੋਗਤਾ ਲੋੜਾਂ ਲਈ ਨਿਊਨਤਮ ਗਤੀ</string>\n    <string name=\"primary_lines\">ਪ੍ਰਾਇਮਰੀ ਲਾਈਨਾਂ</string>\n    <string name=\"primary_lines_sub\">ਹਰ ਪੰਜਵੀਂ ਲਾਈਨ ਨੂੰ ਮੋਟੀ ਲਾਈਨ ਜੋੜਦਾ ਹੈ</string>\n    <string name=\"fill_color\">ਰੰਗ ਭਰੋ</string>\n    <string name=\"hidden_tools\">ਲੁਕਵੇਂ ਟੂਲ</string>\n    <string name=\"hidden_for_share\">ਸ਼ੇਅਰ ਲਈ ਲੁਕੇ ਹੋਏ ਟੂਲ</string>\n    <string name=\"color_library\">ਰੰਗ ਲਾਇਬ੍ਰੇਰੀ</string>\n    <string name=\"color_library_sub\">ਰੰਗਾਂ ਦਾ ਇੱਕ ਵਿਸ਼ਾਲ ਸੰਗ੍ਰਹਿ ਬ੍ਰਾਊਜ਼ ਕਰੋ</string>\n    <string name=\"model_fatality_deblur\">ਕੁਦਰਤੀ ਵੇਰਵਿਆਂ ਨੂੰ ਬਰਕਰਾਰ ਰੱਖਦੇ ਹੋਏ ਚਿੱਤਰਾਂ ਨੂੰ ਤਿੱਖਾ ਅਤੇ ਧੁੰਦਲਾ ਕਰਦਾ ਹੈ, ਫੋਕਸ ਤੋਂ ਬਾਹਰ ਦੀਆਂ ਫੋਟੋਆਂ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ ਆਦਰਸ਼।</string>\n    <string name=\"model_unresize_v3\">ਸਮਝਦਾਰੀ ਨਾਲ ਉਹਨਾਂ ਚਿੱਤਰਾਂ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਦਾ ਪਹਿਲਾਂ ਮੁੜ ਆਕਾਰ ਦਿੱਤਾ ਗਿਆ ਸੀ, ਗੁਆਚੇ ਵੇਰਵਿਆਂ ਅਤੇ ਟੈਕਸਟ ਨੂੰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_liveaction_v1_span\">ਲਾਈਵ-ਐਕਸ਼ਨ ਸਮੱਗਰੀ ਲਈ ਅਨੁਕੂਲਿਤ, ਕੰਪਰੈਸ਼ਨ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ ਮੂਵੀ/ਟੀਵੀ ਸ਼ੋਅ ਫਰੇਮਾਂ ਵਿੱਚ ਵਧੀਆ ਵੇਰਵਿਆਂ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS-ਗੁਣਵੱਤਾ ਫੁਟੇਜ ਨੂੰ HD ਵਿੱਚ ਬਦਲਦਾ ਹੈ, ਟੇਪ ਦੇ ਸ਼ੋਰ ਨੂੰ ਦੂਰ ਕਰਦਾ ਹੈ ਅਤੇ ਵਿੰਟੇਜ ਭਾਵਨਾ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦੇ ਹੋਏ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ।</string>\n    <string name=\"model_text2hd_v1\">ਟੈਕਸਟ-ਭਾਰੀ ਚਿੱਤਰਾਂ ਅਤੇ ਸਕ੍ਰੀਨਸ਼ੌਟਸ ਲਈ ਵਿਸ਼ੇਸ਼, ਅੱਖਰਾਂ ਨੂੰ ਤਿੱਖਾ ਕਰਦਾ ਹੈ ਅਤੇ ਪੜ੍ਹਨਯੋਗਤਾ ਵਿੱਚ ਸੁਧਾਰ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"model_frankendata_pretrainer\">ਵਿਭਿੰਨ ਡੇਟਾਸੈਟਾਂ \\'ਤੇ ਸਿਖਲਾਈ ਪ੍ਰਾਪਤ ਐਡਵਾਂਸਡ ਅਪਸਕੇਲਿੰਗ, ਆਮ-ਉਦੇਸ਼ ਵਾਲੀ ਫੋਟੋ ਸੁਧਾਰ ਲਈ ਸ਼ਾਨਦਾਰ।</string>\n    <string name=\"model_realwebphoto_v2\">ਵੈੱਬ-ਸੰਕੁਚਿਤ ਫੋਟੋਆਂ ਲਈ ਅਨੁਕੂਲਿਤ, JPEG ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਹਟਾਉਂਦੀ ਹੈ ਅਤੇ ਕੁਦਰਤੀ ਦਿੱਖ ਨੂੰ ਬਹਾਲ ਕਰਦੀ ਹੈ।</string>\n    <string name=\"model_realwebphoto_v4\">ਵਧੀਆ ਟੈਕਸਟਚਰ ਸੰਭਾਲ ਅਤੇ ਕਲਾਤਮਕ ਕਟੌਤੀ ਦੇ ਨਾਲ ਵੈੱਬ ਫੋਟੋਆਂ ਲਈ ਸੁਧਾਰਿਆ ਸੰਸਕਰਣ।</string>\n    <string name=\"model_dat_2x\">ਡੁਅਲ ਐਗਰੀਗੇਸ਼ਨ ਟ੍ਰਾਂਸਫਾਰਮਰ ਤਕਨਾਲੋਜੀ ਨਾਲ 2x ਅਪਸਕੇਲਿੰਗ, ਤਿੱਖਾਪਨ ਅਤੇ ਕੁਦਰਤੀ ਵੇਰਵਿਆਂ ਨੂੰ ਬਣਾਈ ਰੱਖਦਾ ਹੈ।</string>\n    <string name=\"model_dat_3x\">ਉੱਨਤ ਟ੍ਰਾਂਸਫਾਰਮਰ ਆਰਕੀਟੈਕਚਰ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ 3x ਅਪਸਕੇਲਿੰਗ, ਮੱਧਮ ਵਾਧੇ ਦੀਆਂ ਲੋੜਾਂ ਲਈ ਆਦਰਸ਼।</string>\n    <string name=\"model_dat_4x\">ਅਤਿ-ਆਧੁਨਿਕ ਟਰਾਂਸਫਾਰਮਰ ਨੈਟਵਰਕ ਦੇ ਨਾਲ 4x ਉੱਚ-ਗੁਣਵੱਤਾ ਅਪਸਕੇਲਿੰਗ, ਵੱਡੇ ਪੈਮਾਨੇ \\'ਤੇ ਵਧੀਆ ਵੇਰਵਿਆਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦੀ ਹੈ।</string>\n    <string name=\"model_nafnet_deblurring\">ਫੋਟੋਆਂ ਤੋਂ ਧੁੰਦਲਾ/ਸ਼ੋਰ ਅਤੇ ਹਿੱਲਣ ਨੂੰ ਹਟਾਉਂਦਾ ਹੈ। ਆਮ ਮਕਸਦ ਪਰ ਫੋਟੋਆਂ \\'ਤੇ ਵਧੀਆ।</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">BSRGAN ਡਿਗਰੇਡੇਸ਼ਨ ਲਈ ਅਨੁਕੂਲਿਤ, Swin2SR ਟ੍ਰਾਂਸਫਾਰਮਰ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਘੱਟ-ਗੁਣਵੱਤਾ ਵਾਲੀਆਂ ਤਸਵੀਰਾਂ ਨੂੰ ਰੀਸਟੋਰ ਕਰਦਾ ਹੈ। ਭਾਰੀ ਸੰਕੁਚਨ ਕਲਾਤਮਕ ਚੀਜ਼ਾਂ ਨੂੰ ਫਿਕਸ ਕਰਨ ਅਤੇ 4x ਸਕੇਲ \\'ਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਵਧਾਉਣ ਲਈ ਵਧੀਆ।</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN ਡਿਗਰੇਡੇਸ਼ਨ \\'ਤੇ ਸਿਖਲਾਈ ਪ੍ਰਾਪਤ ਸਵਿਨਆਈਆਰ ਟ੍ਰਾਂਸਫਾਰਮਰ ਨਾਲ 4x ਅਪਸਕੇਲਿੰਗ। ਫੋਟੋਆਂ ਅਤੇ ਗੁੰਝਲਦਾਰ ਦ੍ਰਿਸ਼ਾਂ ਵਿੱਚ ਤਿੱਖੇ ਟੈਕਸਟ ਅਤੇ ਹੋਰ ਕੁਦਰਤੀ ਵੇਰਵਿਆਂ ਲਈ GAN ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ।</string>\n    <string name=\"path\">ਮਾਰਗ</string>\n    <string name=\"merge_pdf\">PDF ਨੂੰ ਮਿਲਾਓ</string>\n    <string name=\"merge_pdf_sub\">ਇੱਕ ਦਸਤਾਵੇਜ਼ ਵਿੱਚ ਕਈ PDF ਫਾਈਲਾਂ ਨੂੰ ਜੋੜੋ</string>\n    <string name=\"files_order\">ਫਾਈਲਾਂ ਦਾ ਆਰਡਰ</string>\n    <string name=\"pages_short\">pp</string>\n    <string name=\"split_pdf\">PDF ਵੰਡੋ</string>\n    <string name=\"split_pdf_sub\">PDF ਦਸਤਾਵੇਜ਼ ਤੋਂ ਖਾਸ ਪੰਨਿਆਂ ਨੂੰ ਐਕਸਟਰੈਕਟ ਕਰੋ</string>\n    <string name=\"rotate_pdf\">PDF ਘੁੰਮਾਓ</string>\n    <string name=\"rotate_pdf_sub\">ਪੰਨਾ ਸਥਿਤੀ ਨੂੰ ਪੱਕੇ ਤੌਰ \\'ਤੇ ਠੀਕ ਕਰੋ</string>\n    <string name=\"pages\">ਪੰਨੇ</string>\n    <string name=\"rearrange_pdf\">PDF ਨੂੰ ਮੁੜ ਵਿਵਸਥਿਤ ਕਰੋ</string>\n    <string name=\"rearrange_pdf_sub\">ਉਹਨਾਂ ਨੂੰ ਮੁੜ ਕ੍ਰਮਬੱਧ ਕਰਨ ਲਈ ਪੰਨਿਆਂ ਨੂੰ ਖਿੱਚੋ ਅਤੇ ਛੱਡੋ</string>\n    <string name=\"hold_drag_drop\">ਪੰਨੇ ਫੜੋ ਅਤੇ ਖਿੱਚੋ</string>\n    <string name=\"page_numbers\">ਪੰਨਾ ਨੰਬਰ</string>\n    <string name=\"page_numbers_sub\">ਆਪਣੇ ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਸਵੈਚਲਿਤ ਤੌਰ \\'ਤੇ ਨੰਬਰਿੰਗ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"label_format\">ਲੇਬਲ ਫਾਰਮੈਟ</string>\n    <string name=\"pdf_to_text\">PDF ਤੋਂ ਟੈਕਸਟ (OCR)</string>\n    <string name=\"pdf_to_text_sub\">ਆਪਣੇ PDF ਦਸਤਾਵੇਜ਼ਾਂ ਤੋਂ ਸਾਦਾ ਟੈਕਸਟ ਐਕਸਟਰੈਕਟ ਕਰੋ</string>\n    <string name=\"watermark_pdf_sub\">ਬ੍ਰਾਂਡਿੰਗ ਜਾਂ ਸੁਰੱਖਿਆ ਲਈ ਕਸਟਮ ਟੈਕਸਟ ਨੂੰ ਓਵਰਲੇ ਕਰੋ</string>\n    <string name=\"signature\">ਦਸਤਖਤ</string>\n    <string name=\"signature_sub\">ਕਿਸੇ ਵੀ ਦਸਤਾਵੇਜ਼ ਵਿੱਚ ਆਪਣੇ ਇਲੈਕਟ੍ਰਾਨਿਕ ਦਸਤਖਤ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"will_be_for_signature\">ਇਹ ਦਸਤਖਤ ਵਜੋਂ ਵਰਤਿਆ ਜਾਵੇਗਾ</string>\n    <string name=\"unlock_pdf\">PDF ਨੂੰ ਅਨਲੌਕ ਕਰੋ</string>\n    <string name=\"unlock_pdf_sub\">ਆਪਣੀਆਂ ਸੁਰੱਖਿਅਤ ਫਾਈਲਾਂ ਤੋਂ ਪਾਸਵਰਡ ਹਟਾਓ</string>\n    <string name=\"protect_pdf\">PDF ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ</string>\n    <string name=\"protect_pdf_sub\">ਆਪਣੇ ਦਸਤਾਵੇਜ਼ਾਂ ਨੂੰ ਮਜ਼ਬੂਤ ​​ਏਨਕ੍ਰਿਪਸ਼ਨ ਨਾਲ ਸੁਰੱਖਿਅਤ ਕਰੋ</string>\n    <string name=\"success\">ਸਫਲਤਾ</string>\n    <string name=\"pdf_unlocked\">PDF ਅਨਲੌਕ, ਤੁਸੀਂ ਇਸਨੂੰ ਸੁਰੱਖਿਅਤ ਜਾਂ ਸਾਂਝਾ ਕਰ ਸਕਦੇ ਹੋ</string>\n    <string name=\"repair_pdf\">PDF ਦੀ ਮੁਰੰਮਤ ਕਰੋ</string>\n    <string name=\"repair_pdf_sub\">ਖਰਾਬ ਜਾਂ ਨਾ-ਪੜ੍ਹਨਯੋਗ ਦਸਤਾਵੇਜ਼ਾਂ ਨੂੰ ਠੀਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ</string>\n    <string name=\"grayscale\">ਗ੍ਰੇਸਕੇਲ</string>\n    <string name=\"grayscale_pdf_sub\">ਸਾਰੇ ਦਸਤਾਵੇਜ਼ ਏਮਬੈਡਡ ਚਿੱਤਰਾਂ ਨੂੰ ਗ੍ਰੇਸਕੇਲ ਵਿੱਚ ਬਦਲੋ</string>\n    <string name=\"compress_pdf\">ਪੀਡੀਐਫ ਨੂੰ ਸੰਕੁਚਿਤ ਕਰੋ</string>\n    <string name=\"compress_pdf_sub\">ਆਸਾਨੀ ਨਾਲ ਸਾਂਝਾ ਕਰਨ ਲਈ ਆਪਣੇ ਦਸਤਾਵੇਜ਼ ਫਾਈਲ ਆਕਾਰ ਨੂੰ ਅਨੁਕੂਲ ਬਣਾਓ</string>\n    <string name=\"repair_info\">ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਅੰਦਰੂਨੀ ਕਰਾਸ-ਰੈਫਰੈਂਸ ਟੇਬਲ ਨੂੰ ਦੁਬਾਰਾ ਬਣਾਉਂਦਾ ਹੈ ਅਤੇ ਸਕ੍ਰੈਚ ਤੋਂ ਫਾਈਲ ਬਣਤਰ ਨੂੰ ਦੁਬਾਰਾ ਬਣਾਉਂਦਾ ਹੈ। ਇਹ ਬਹੁਤ ਸਾਰੀਆਂ ਫਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਨੂੰ ਬਹਾਲ ਕਰ ਸਕਦਾ ਹੈ ਜੋ \\\\\"ਖੋਲ੍ਹੀਆਂ ਨਹੀਂ ਜਾ ਸਕਦੀਆਂ\\\\\"।</string>\n    <string name=\"grayscale_info\">ਇਹ ਟੂਲ ਸਾਰੇ ਦਸਤਾਵੇਜ਼ ਚਿੱਤਰਾਂ ਨੂੰ ਗ੍ਰੇਸਕੇਲ ਵਿੱਚ ਬਦਲਦਾ ਹੈ। ਪ੍ਰਿੰਟਿੰਗ ਅਤੇ ਫਾਈਲ ਦਾ ਆਕਾਰ ਘਟਾਉਣ ਲਈ ਸਭ ਤੋਂ ਵਧੀਆ</string>\n    <string name=\"metadata\">ਮੈਟਾਡਾਟਾ</string>\n    <string name=\"metadata_pdf_sub\">ਬਿਹਤਰ ਗੋਪਨੀਯਤਾ ਲਈ ਦਸਤਾਵੇਜ਼ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸੰਪਾਦਿਤ ਕਰੋ</string>\n    <string name=\"tags\">ਟੈਗਸ</string>\n    <string name=\"producer\">ਨਿਰਮਾਤਾ</string>\n    <string name=\"author\">ਲੇਖਕ</string>\n    <string name=\"keywords\">ਕੀਵਰਡਸ</string>\n    <string name=\"creator\">ਸਿਰਜਣਹਾਰ</string>\n    <string name=\"privacy_deep_clean\">ਗੋਪਨੀਯਤਾ ਡੂੰਘੀ ਸਾਫ਼</string>\n    <string name=\"privacy_deep_clean_sub\">ਇਸ ਦਸਤਾਵੇਜ਼ ਲਈ ਉਪਲਬਧ ਸਾਰੇ ਮੈਟਾਡੇਟਾ ਨੂੰ ਸਾਫ਼ ਕਰੋ</string>\n    <string name=\"page\">ਪੰਨਾ</string>\n    <string name=\"deep_ocr\">ਡੂੰਘੀ OCR</string>\n    <string name=\"deep_ocr_sub\">ਡੌਕੂਮੈਂਟ ਤੋਂ ਟੈਕਸਟ ਐਕਸਟਰੈਕਟ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਟੈਸਰੈਕਟ ਇੰਜਣ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਇੱਕ ਟੈਕਸਟ ਫਾਈਲ ਵਿੱਚ ਸਟੋਰ ਕਰੋ</string>\n    <string name=\"cant_remove_all\">ਸਾਰੇ ਪੰਨਿਆਂ ਨੂੰ ਹਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ</string>\n    <string name=\"remove_pages_pdf\">PDF ਪੰਨਿਆਂ ਨੂੰ ਹਟਾਓ</string>\n    <string name=\"remove_pages_pdf_sub\">PDF ਦਸਤਾਵੇਜ਼ ਤੋਂ ਖਾਸ ਪੰਨਿਆਂ ਨੂੰ ਹਟਾਓ</string>\n    <string name=\"tap_to_remove\">ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ</string>\n    <string name=\"manually\">ਹੱਥੀਂ</string>\n    <string name=\"crop_pdf\">PDF ਨੂੰ ਕੱਟੋ</string>\n    <string name=\"crop_pdf_sub\">ਦਸਤਾਵੇਜ਼ ਪੰਨਿਆਂ ਨੂੰ ਕਿਸੇ ਵੀ ਹੱਦ ਤੱਕ ਕੱਟੋ</string>\n    <string name=\"flatten_pdf\">PDF ਫਲੈਟ ਕਰੋ</string>\n    <string name=\"flatten_pdf_sub\">ਦਸਤਾਵੇਜ਼ ਪੰਨਿਆਂ ਨੂੰ ਰਾਸਟਰ ਕਰਕੇ PDF ਨੂੰ ਸੋਧਣਯੋਗ ਬਣਾਓ</string>\n    <string name=\"camera_failed_to_open\">ਕੈਮਰਾ ਚਾਲੂ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਅਨੁਮਤੀਆਂ ਦੀ ਜਾਂਚ ਕਰੋ ਅਤੇ ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਇਹ ਕਿਸੇ ਹੋਰ ਐਪ ਦੁਆਰਾ ਨਹੀਂ ਵਰਤੀ ਜਾ ਰਹੀ ਹੈ।</string>\n    <string name=\"extract_images\">ਚਿੱਤਰਾਂ ਨੂੰ ਐਕਸਟਰੈਕਟ ਕਰੋ</string>\n    <string name=\"extract_images_sub\">PDF ਵਿੱਚ ਏਮਬੇਡ ਕੀਤੀਆਂ ਤਸਵੀਰਾਂ ਨੂੰ ਉਹਨਾਂ ਦੇ ਅਸਲ ਰੈਜ਼ੋਲਿਊਸ਼ਨ \\'ਤੇ ਐਕਸਟਰੈਕਟ ਕਰੋ</string>\n    <string name=\"pdf_no_embedded\">ਇਸ PDF ਫਾਈਲ ਵਿੱਚ ਕੋਈ ਵੀ ਏਮਬੈਡਡ ਚਿੱਤਰ ਸ਼ਾਮਲ ਨਹੀਂ ਹਨ</string>\n    <string name=\"extract_images_info\">ਇਹ ਟੂਲ ਹਰ ਪੰਨੇ ਨੂੰ ਸਕੈਨ ਕਰਦਾ ਹੈ ਅਤੇ ਪੂਰੀ-ਗੁਣਵੱਤਾ ਵਾਲੇ ਸਰੋਤ ਚਿੱਤਰਾਂ ਨੂੰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਦਾ ਹੈ - ਦਸਤਾਵੇਜ਼ਾਂ ਤੋਂ ਮੂਲ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਸੰਪੂਰਨ</string>\n    <string name=\"draw_signature\">ਦਸਤਖਤ ਖਿੱਚੋ</string>\n    <string name=\"pen_params\">ਕਲਮ ਪਰਮ</string>\n    <string name=\"draw_signature_sub\">ਦਸਤਾਵੇਜ਼ਾਂ \\'ਤੇ ਰੱਖਣ ਲਈ ਚਿੱਤਰ ਵਜੋਂ ਆਪਣੇ ਦਸਤਖਤ ਦੀ ਵਰਤੋਂ ਕਰੋ</string>\n    <string name=\"zip_pdf\">ਜ਼ਿਪ PDF</string>\n    <string name=\"zip_pdf_sub\">ਦਿੱਤੇ ਅੰਤਰਾਲ ਦੇ ਨਾਲ ਦਸਤਾਵੇਜ਼ ਨੂੰ ਵੰਡੋ ਅਤੇ ਨਵੇਂ ਦਸਤਾਵੇਜ਼ਾਂ ਨੂੰ ਜ਼ਿਪ ਆਰਕਾਈਵ ਵਿੱਚ ਪੈਕ ਕਰੋ</string>\n    <string name=\"interval\">ਅੰਤਰਾਲ</string>\n    <string name=\"print_pdf\">PDF ਪ੍ਰਿੰਟ ਕਰੋ</string>\n    <string name=\"print_pdf_sub\">ਕਸਟਮ ਪੰਨੇ ਦੇ ਆਕਾਰ ਨਾਲ ਪ੍ਰਿੰਟਿੰਗ ਲਈ ਦਸਤਾਵੇਜ਼ ਤਿਆਰ ਕਰੋ</string>\n    <string name=\"pages_per_sheet\">ਪੰਨੇ ਪ੍ਰਤੀ ਸ਼ੀਟ</string>\n    <string name=\"orientation\">ਸਥਿਤੀ</string>\n    <string name=\"page_size\">ਪੰਨਾ ਆਕਾਰ</string>\n    <string name=\"margin\">ਹਾਸ਼ੀਏ</string>\n    <string name=\"bloom\">ਖਿੜ</string>\n    <string name=\"soft_knee\">ਨਰਮ ਗੋਡਾ</string>\n    <string name=\"model_realesr_animevideo_v3x4\">ਐਨੀਮੇ ਅਤੇ ਕਾਰਟੂਨਾਂ ਲਈ ਅਨੁਕੂਲਿਤ। ਸੁਧਰੇ ਹੋਏ ਕੁਦਰਤੀ ਰੰਗਾਂ ਅਤੇ ਘੱਟ ਕਲਾਕ੍ਰਿਤੀਆਂ ਦੇ ਨਾਲ ਤੇਜ਼ ਅਪਸਕੇਲਿੰਗ</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 ਵਰਗਾ ਸਟਾਈਲ</string>\n    <string name=\"calculate_hint\">ਲੋੜੀਂਦੇ ਮੁੱਲ ਦੀ ਗਣਨਾ ਕਰਨ ਲਈ ਇੱਥੇ ਮੂਲ ਗਣਿਤ ਚਿੰਨ੍ਹ ਦਾਖਲ ਕਰੋ (ਉਦਾਹਰਨ ਲਈ (5+5)*10)</string>\n    <string name=\"math_expression\">ਗਣਿਤ ਸਮੀਕਰਨ</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s ਤੱਕ ਚਿੱਤਰ ਚੁੱਕੋ</string>\n    <string name=\"background_color_for_alpha_formats\">ਅਲਫ਼ਾ ਫਾਰਮੈਟਾਂ ਲਈ ਪਿਛੋਕੜ ਦਾ ਰੰਗ</string>\n    <string name=\"background_color_for_alpha_formats_sub\">ਅਲਫ਼ਾ ਸਮਰਥਨ ਦੇ ਨਾਲ ਹਰ ਚਿੱਤਰ ਫਾਰਮੈਟ ਲਈ ਬੈਕਗ੍ਰਾਉਂਡ ਰੰਗ ਸੈੱਟ ਕਰਨ ਦੀ ਯੋਗਤਾ ਜੋੜਦਾ ਹੈ, ਜਦੋਂ ਇਹ ਅਸਮਰੱਥ ਹੁੰਦਾ ਹੈ ਤਾਂ ਇਹ ਸਿਰਫ਼ ਗੈਰ-ਅਲਫ਼ਾ ਲਈ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ</string>\n    <string name=\"keep_date_time\">ਮਿਤੀ ਸਮਾਂ ਰੱਖੋ</string>\n    <string name=\"keep_date_time_sub\">ਹਮੇਸ਼ਾਂ ਮਿਤੀ ਅਤੇ ਸਮੇਂ ਨਾਲ ਸੰਬੰਧਿਤ ਐਕਸੀਫ ਟੈਗਸ ਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖੋ, ਐਕਸੀਫ ਵਿਕਲਪ ਦੀ ਵਰਤੋਂ ਤੋਂ ਸੁਤੰਤਰ ਤੌਰ \\'ਤੇ ਕੰਮ ਕਰਦਾ ਹੈ</string>\n    <string name=\"open_markup_project\">ਪ੍ਰੋਜੈਕਟ ਖੋਲ੍ਹੋ</string>\n    <string name=\"open_markup_project_sub\">ਪਹਿਲਾਂ ਸੁਰੱਖਿਅਤ ਕੀਤੇ ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਪ੍ਰੋਜੈਕਟ ਨੂੰ ਸੰਪਾਦਿਤ ਕਰਨਾ ਜਾਰੀ ਰੱਖੋ</string>\n    <string name=\"markup_project_open_failed\">ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਪ੍ਰੋਜੈਕਟ ਨੂੰ ਖੋਲ੍ਹਣ ਵਿੱਚ ਅਸਮਰੱਥ</string>\n    <string name=\"markup_project_missing_data\">ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਪ੍ਰੋਜੈਕਟ ਵਿੱਚ ਪ੍ਰੋਜੈਕਟ ਡੇਟਾ ਗੁੰਮ ਹੈ</string>\n    <string name=\"markup_project_corrupted\">ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਪ੍ਰੋਜੈਕਟ ਖਰਾਬ ਹੈ</string>\n    <string name=\"unsupported_markup_project_version\">ਅਸਮਰਥਿਤ ਚਿੱਤਰ ਟੂਲਬਾਕਸ ਪ੍ਰੋਜੈਕਟ ਸੰਸਕਰਣ: %1$d</string>\n    <string name=\"save_markup_project\">ਪ੍ਰੋਜੈਕਟ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ</string>\n    <string name=\"save_markup_project_sub\">ਸੰਪਾਦਨਯੋਗ ਪ੍ਰੋਜੈਕਟ ਫਾਈਲ ਵਿੱਚ ਲੇਅਰਾਂ, ਬੈਕਗ੍ਰਾਉਂਡ ਅਤੇ ਸੰਪਾਦਨ ਇਤਿਹਾਸ ਨੂੰ ਸਟੋਰ ਕਰੋ</string>\n    <string name=\"failed_to_open\">ਖੋਲ੍ਹਣ ਵਿੱਚ ਅਸਫਲ</string>\n    <string name=\"ocr_write_to_searchable_pdf\">ਖੋਜਯੋਗ PDF ਵਿੱਚ ਲਿਖੋ</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">ਚਿੱਤਰ ਬੈਚ ਤੋਂ ਟੈਕਸਟ ਨੂੰ ਪਛਾਣੋ ਅਤੇ ਚਿੱਤਰ ਅਤੇ ਚੋਣਯੋਗ ਟੈਕਸਟ ਲੇਅਰ ਨਾਲ ਖੋਜਣ ਯੋਗ PDF ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ</string>\n    <string name=\"layer_alpha\">ਲੇਅਰ ਅਲਫ਼ਾ</string>\n    <string name=\"horizontal_flip\">ਹਰੀਜ਼ੱਟਲ ਫਲਿੱਪ</string>\n    <string name=\"vertical_flip\">ਵਰਟੀਕਲ ਫਲਿੱਪ</string>\n    <string name=\"lock\">ਤਾਲਾ</string>\n    <string name=\"add_shadow\">ਸ਼ੈਡੋ ਸ਼ਾਮਲ ਕਰੋ</string>\n    <string name=\"shadow_color\">ਸ਼ੈਡੋ ਰੰਗ</string>\n    <string name=\"text_geometry\">ਟੈਕਸਟ ਜਿਓਮੈਟਰੀ</string>\n    <string name=\"text_geometry_sub\">ਤਿੱਖੀ ਸ਼ੈਲੀ ਲਈ ਟੈਕਸਟ ਨੂੰ ਖਿੱਚੋ ਜਾਂ ਤਿੱਖਾ ਕਰੋ</string>\n    <string name=\"scale_x\">ਸਕੇਲ ਐਕਸ</string>\n    <string name=\"skew_x\">ਸਕਿਊ ਐਕਸ</string>\n    <string name=\"remove_annotations\">ਐਨੋਟੇਸ਼ਨਾਂ ਨੂੰ ਹਟਾਓ</string>\n    <string name=\"remove_annotations_sub\">PDF ਪੰਨਿਆਂ ਤੋਂ ਚੁਣੀਆਂ ਗਈਆਂ ਐਨੋਟੇਸ਼ਨ ਕਿਸਮਾਂ ਨੂੰ ਹਟਾਓ ਜਿਵੇਂ ਕਿ ਲਿੰਕ, ਟਿੱਪਣੀਆਂ, ਹਾਈਲਾਈਟਸ, ਆਕਾਰ ਜਾਂ ਫਾਰਮ ਖੇਤਰ</string>\n    <string name=\"annotation_link\">ਹਾਈਪਰਲਿੰਕਸ</string>\n    <string name=\"annotation_file_attachment\">ਫਾਈਲ ਅਟੈਚਮੈਂਟਸ</string>\n    <string name=\"annotation_line\">ਲਾਈਨਾਂ</string>\n    <string name=\"annotation_popup\">ਪੌਪਅੱਪ</string>\n    <string name=\"annotation_stamp\">ਸਟਪਸ</string>\n    <string name=\"annotation_shapes\">ਆਕਾਰ</string>\n    <string name=\"annotation_text\">ਟੈਕਸਟ ਨੋਟਸ</string>\n    <string name=\"annotation_text_markup\">ਟੈਕਸਟ ਮਾਰਕਅੱਪ</string>\n    <string name=\"annotation_widget\">ਫਾਰਮ ਖੇਤਰ</string>\n    <string name=\"annotation_markup\">ਮਾਰਕਅੱਪ</string>\n    <string name=\"annotation_unknown\">ਅਗਿਆਤ</string>\n    <string name=\"annotations\">ਐਨੋਟੇਸ਼ਨ</string>\n    <string name=\"ungroup\">ਅਨਗਰੁੱਪ ਕਰੋ</string>\n    <string name=\"add_shadow_sub\">ਸੰਰਚਨਾਯੋਗ ਰੰਗ ਅਤੇ ਆਫਸੈਟਾਂ ਦੇ ਨਾਲ ਪਰਤ ਦੇ ਪਿੱਛੇ ਬਲਰ ਸ਼ੈਡੋ ਸ਼ਾਮਲ ਕਰੋ</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-pl/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"size\">Rozmiar %1$s</string>\n    <string name=\"width\">Szerokość %1$s</string>\n    <string name=\"loading\">Ładowanie…</string>\n    <string name=\"image_too_large_preview\">Obraz jest zbyt duży do podglądu, ale i tak zostanie podjęta próba jego zapisania</string>\n    <string name=\"pick_image\">Wybierz obraz, aby rozpocząć</string>\n    <string name=\"smth_went_wrong\">Coś poszło nie tak: %1$s</string>\n    <string name=\"height\">Wysokość %1$s</string>\n    <string name=\"quality\">Jakość</string>\n    <string name=\"extension\">Rozszerzenie</string>\n    <string name=\"resize_type\">Typ zmiany rozmiaru</string>\n    <string name=\"restart_app\">Zrestartuj aplikację</string>\n    <string name=\"pick_image_alt\">Wybierz obraz</string>\n    <string name=\"app_closing_sub\">Czy na pewno chcesz wyjść z aplikacji?</string>\n    <string name=\"app_closing\">Zamykanie aplikacji</string>\n    <string name=\"stay\">Zostań</string>\n    <string name=\"close\">Zamknij</string>\n    <string name=\"reset_image\">Zresetuj obraz</string>\n    <string name=\"reset_image_sub\">Zmiany obrazu zostaną przywrócone do wartości początkowych</string>\n    <string name=\"values_reset\">Wartości prawidłowo zresetowane</string>\n    <string name=\"reset\">Resetuj</string>\n    <string name=\"something_went_wrong\">Coś poszło nie tak</string>\n    <string name=\"copied\">Skopiowano do schowka</string>\n    <string name=\"exception\">Wyjątek</string>\n    <string name=\"edit_exif\">Edytuj dane EXIF</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"amoled_mode\">Tryb Amoled</string>\n    <string name=\"amoled_mode_sub\">Jeśli ta opcja jest włączona, w trybie nocnym kolor tła zostanie ustawiony na całkowicie ciemny</string>\n    <string name=\"color_red\">Czerwony</string>\n    <string name=\"color_green\">Zielony</string>\n    <string name=\"color_blue\">Niebieski</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Wklej prawidłowy kod aRGB</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nic do wklejenia</string>\n    <string name=\"color_scheme\">Schemat kolorów</string>\n    <string name=\"explicit\">Wyraźny</string>\n    <string name=\"flexible\">Elastyczny</string>\n    <string name=\"add_tag\">Dodaj tag</string>\n    <string name=\"save\">Zapisz</string>\n    <string name=\"clear\">Wyczyść</string>\n    <string name=\"clear_exif\">Wyczyść dane EXIF</string>\n    <string name=\"cancel\">Anuluj</string>\n    <string name=\"clear_exif_sub\">Wszystkie dane EXIF obrazu zostaną usunięte. Tej czynności nie można cofnąć!</string>\n    <string name=\"presets\">Presety</string>\n    <string name=\"crop\">Przytnij</string>\n    <string name=\"image_not_saved\">Zapisywanie</string>\n    <string name=\"image_not_saved_sub\">Wszystkie niezapisane zmiany zostaną utracone, jeśli wyjdziesz teraz</string>\n    <string name=\"check_source_code\">Kod źródłowy</string>\n    <string name=\"check_source_code_sub\">Najnowsze aktualizacje, dyskusje i nie tylko</string>\n    <string name=\"single_edit\">Pojedyncza edycja</string>\n    <string name=\"single_edit_sub\">Modyfikacja, zmiana rozmiaru i edycja jednego obrazu</string>\n    <string name=\"pick_color\">Selektor kolorów</string>\n    <string name=\"pick_color_sub\">Wybierz kolor z obrazu, skopiuj lub udostępnij</string>\n    <string name=\"image\">Obraz</string>\n    <string name=\"color\">Kolor</string>\n    <string name=\"color_copied\">Skopiowano kolor</string>\n    <string name=\"crop_sub\">Przytnij obraz w dowolny sposób</string>\n    <string name=\"version\">Wersja</string>\n    <string name=\"keep_exif\">Zachowaj dane EXIF</string>\n    <string name=\"images\">Obrazy: %d</string>\n    <string name=\"remove\">Usuń</string>\n    <string name=\"custom\">Własny</string>\n    <string name=\"unspecified\">Nieokreślony</string>\n    <string name=\"device_storage\">Pamięć wewnętrzna</string>\n    <string name=\"by_bytes_resize\">Zmień rozmiar pliku</string>\n    <string name=\"max_bytes\">Maksymalny rozmiar w KB</string>\n    <string name=\"by_bytes_resize_sub\">Zmień wymiary obrazu, aby ograniczyć jego rozmiar w KB</string>\n    <string name=\"compare\">Porównaj</string>\n    <string name=\"compare_sub\">Porównaj dwa obrazy</string>\n    <string name=\"pick_two_images\">Wybierz dwa obrazy, aby rozpocząć</string>\n    <string name=\"pick_images\">Wybierz obrazy</string>\n    <string name=\"settings\">Ustawienia</string>\n    <string name=\"night_mode\">Tryb nocny</string>\n    <string name=\"customization\">Personalizacja</string>\n    <string name=\"allow_image_monet\">Użyj kolorów obrazu</string>\n    <string name=\"allow_image_monet_sub\">Jeśli opcja ta jest włączona, po wybraniu obrazu do edycji kolory aplikacji zostaną dostosowane do tego obrazu</string>\n    <string name=\"language\">Język</string>\n    <string name=\"update\">Aktualizuj</string>\n    <string name=\"no_palette\">Nie można wygenerować palety dla danego obrazu</string>\n    <string name=\"unsupported_type\">Nieobsługiwany typ: %1$s</string>\n    <string name=\"original\">Oryginał</string>\n    <string name=\"system\">Systemowy</string>\n    <string name=\"change_preview\">Zmień podgląd</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"new_version\">Nowa wersja %1$s</string>\n    <string name=\"palette_sub\">Wygeneruj próbkę palety kolorów z podanego obrazu</string>\n    <string name=\"generate_palette\">Wygeneruj paletę</string>\n    <string name=\"folder\">Folder wyjściowy</string>\n    <string name=\"def\">Domyślny</string>\n    <string name=\"dark\">Ciemny</string>\n    <string name=\"light\">Jasny</string>\n    <string name=\"dynamic_colors\">Dynamiczne kolory</string>\n    <string name=\"no_exif\">Nie znaleziono metadanych EXIF</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Nie można zmienić schematu kolorów aplikacji, gdy włączone są kolory dynamiczne</string>\n    <string name=\"pick_accent_color\">Motyw aplikacji będzie oparty na wybranym kolorze</string>\n    <string name=\"about_app\">O aplikacji</string>\n    <string name=\"no_updates\">Nie znaleziono aktualizacji</string>\n    <string name=\"issue_tracker\">Śledzenie błędów</string>\n    <string name=\"issue_tracker_sub\">Wysyłaj raporty o błędach i prośby o funkcje tutaj</string>\n    <string name=\"help_translate\">Pomóż w tłumaczeniu</string>\n    <string name=\"search_here\">Szukaj tutaj</string>\n    <string name=\"help_translate_sub\">Popraw błędy w tłumaczeniu lub przetłumacz projekt na nowe języki</string>\n    <string name=\"nothing_found_by_search\">Nic nie znaleziono na podstawie Twojego zapytania</string>\n    <string name=\"dynamic_colors_sub\">Jeśli opcja ta jest włączona, kolory aplikacji zostaną dostosowane do koloru tapety</string>\n    <string name=\"failed_to_save\">Nie udało się zapisać %d obrazów</string>\n    <string name=\"surface\">Powierzchnia</string>\n    <string name=\"fab_alignment\">Wyrównanie przycisków pływających</string>\n    <string name=\"check_updates\">Sprawdź, czy są aktualizacje</string>\n    <string name=\"check_updates_sub\">Jeśli opcja ta jest włączona, okno aktualizacji będzie wyświetlane podczas uruchamiania aplikacji</string>\n    <string name=\"values\">Wartości</string>\n    <string name=\"add\">Dodaj</string>\n    <string name=\"primary\">Główny</string>\n    <string name=\"tertiary\">Trzeciorzędny</string>\n    <string name=\"secondary\">Drugorzędny</string>\n    <string name=\"permission\">Uprawnienie</string>\n    <string name=\"grant\">Przyznaj</string>\n    <string name=\"permission_sub\">Aplikacja potrzebuje dostępu do pamięci, aby móc zapisywać obrazy. Przyznaj uprawnienie w następnym oknie dialogowym.</string>\n    <string name=\"zoom\">Powiększenie obrazu</string>\n    <string name=\"prefix\">Prefiks</string>\n    <string name=\"filename\">Nazwa pliku</string>\n    <string name=\"donation_sub\">Ta aplikacja jest całkowicie darmowa, ale możesz kliknąć tutaj, jeśli chcesz wesprzeć rozwój projektu</string>\n    <string name=\"grant_permission_manual\">Aplikacja potrzebuje tego uprawnienia do działania, prosimy o przyznanie go ręcznie.</string>\n    <string name=\"border_thickness\">Grubość ramki</string>\n    <string name=\"share\">Udostępnij</string>\n    <string name=\"external_storage\">Pamięć zewnętrzna</string>\n    <string name=\"monet_colors\">Kolory Monet</string>\n    <string name=\"sharpen\">Wyostrz</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"line_width\">Szerokość linii</string>\n    <string name=\"sobel_edge\">Krawędź Sobela</string>\n    <string name=\"photo_picker\">Selektor zdjęć</string>\n    <string name=\"brightness\">Jasność</string>\n    <string name=\"cga_colorspace\">Przestrzeń barw CGA</string>\n    <string name=\"gaussian_blur\">Rozmycie Gaussa</string>\n    <string name=\"radius\">Promień</string>\n    <string name=\"scale\">Skala</string>\n    <string name=\"limits_resize\">Zmiana rozmiaru przez limity</string>\n    <string name=\"sketch\">Szkic</string>\n    <string name=\"threshold\">Próg</string>\n    <string name=\"quantizationLevels\">Poziomy kwantyzacji</string>\n    <string name=\"smooth_toon\">Gładki toon</string>\n    <string name=\"stack_blur\">Rozmycie stosu</string>\n    <string name=\"convolution3x3\">Konwolucja 3x3</string>\n    <string name=\"rgb_filter\">Filtr RGB</string>\n    <string name=\"false_color\">Fałszywy kolor</string>\n    <string name=\"emoji\">Emotikony</string>\n    <string name=\"emoji_sub\">Wybierz, które emotikony będą wyświetlane na ekranie głównym</string>\n    <string name=\"add_file_size\">Dodaj rozmiar pliku</string>\n    <string name=\"add_file_size_sub\">Jeśli włączone, szerokość i wysokość zapisanego obrazu zostanie dodana do nazwy pliku wyjściowego</string>\n    <string name=\"delete_exif\">Usuń dane EXIF</string>\n    <string name=\"delete_exif_sub\">Usuń metadane EXIF z dowolnego zestawu obrazów</string>\n    <string name=\"image_preview\">Podgląd obrazu</string>\n    <string name=\"image_preview_sub\">Wyświetl podgląd dowolnego typu obrazów: GIF, SVG itd.</string>\n    <string name=\"image_source\">Źródło obrazu</string>\n    <string name=\"gallery_picker\">Galeria</string>\n    <string name=\"photo_picker_sub\">Nowoczesny selektor zdjęć Androida u dołu ekranu, może działać tylko na Androidzie 12+. Ma problemy z odczytem danych EXIF</string>\n    <string name=\"file_explorer_picker_sub\">Użyj intencji GetContent, aby wybrać obraz. Działa wszędzie, ale może też mieć problemy z odczytem wybranych obrazów na niektórych urządzeniach. To nie moja wina.</string>\n    <string name=\"options_arrangement\">Układ opcji</string>\n    <string name=\"emojis_count\">Liczba emotikonów</string>\n    <string name=\"replace_sequence_number\">Użyj numeru z sekwencji</string>\n    <string name=\"replace_sequence_number_sub\">Jeśli opcja ta jest włączona, zastępuje standardowy znacznik czasu numerem sekwencji w przypadku przetwarzania wielu plików</string>\n    <string name=\"load_image_from_net_sub\">Załaduj dowolny obraz z Internetu, aby go podejrzeć, powiększyć, edytować i zapisać.</string>\n    <string name=\"no_image\">Brak obrazu</string>\n    <string name=\"image_link\">Link do obrazu</string>\n    <string name=\"fill\">Wypełnij</string>\n    <string name=\"fit\">Dopasuj</string>\n    <string name=\"explicit_description\">Zmienia rozmiar obrazów do podanej wysokości i szerokości. Współczynnik proporcji obrazów może ulec zmianie.</string>\n    <string name=\"flexible_description\">Zmienia rozmiar obrazów o długim boku do podanej wysokości lub szerokości. Wszystkie obliczenia rozmiaru zostaną wykonane po zapisaniu. Proporcje obrazu zostaną zachowane.</string>\n    <string name=\"contrast\">Kontrast</string>\n    <string name=\"hue\">Odcień</string>\n    <string name=\"saturation\">Nasycenie</string>\n    <string name=\"add_filter\">Dodaj filtr</string>\n    <string name=\"filter\">Filtr</string>\n    <string name=\"filter_sub\">Zastosuj łańcuchy filtrów do obrazów</string>\n    <string name=\"filters\">Filtry</string>\n    <string name=\"light_aka_illumination\">Światło</string>\n    <string name=\"color_filter\">Filtr koloru</string>\n    <string name=\"alpha\">Kanał alfa</string>\n    <string name=\"exposure\">Ekspozycja</string>\n    <string name=\"white_balance\">Balans bieli</string>\n    <string name=\"temperature\">Temperatura</string>\n    <string name=\"tint\">Zabarwienie</string>\n    <string name=\"monochrome\">Monochromatyczność</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Światła i cienie</string>\n    <string name=\"highlights\">Światła</string>\n    <string name=\"shadows\">Cienie</string>\n    <string name=\"haze\">Mgła</string>\n    <string name=\"effect\">Efekt</string>\n    <string name=\"distance\">Dystans</string>\n    <string name=\"slope\">Nachylenie</string>\n    <string name=\"negative\">Negatyw</string>\n    <string name=\"solarize\">Solaryzacja</string>\n    <string name=\"vibrance\">Żywiołowość</string>\n    <string name=\"black_and_white\">Czarno-biały</string>\n    <string name=\"crosshatch\">Kreskowanie</string>\n    <string name=\"spacing\">Rozstaw</string>\n    <string name=\"blur\">Rozmycie</string>\n    <string name=\"halftone\">Półtony</string>\n    <string name=\"box_blur\">Rozmycie pudełkowe</string>\n    <string name=\"bilaterial_blur\">Rozmycie dwustronne</string>\n    <string name=\"emboss\">Tłoczenie</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Winieta</string>\n    <string name=\"start\">Początek</string>\n    <string name=\"end\">Koniec</string>\n    <string name=\"kuwahara\">Wygładzanie Kuwahary</string>\n    <string name=\"distortion\">Zniekształcenie</string>\n    <string name=\"angle\">Kąt</string>\n    <string name=\"swirl\">Wir</string>\n    <string name=\"bulge\">Wypukłość</string>\n    <string name=\"dilation\">Dylatacja</string>\n    <string name=\"sphere_refraction\">Refrakcja kuli</string>\n    <string name=\"refractive_index\">Współczynnik załamania światła</string>\n    <string name=\"glass_sphere_refraction\">Refrakcja szklanej kuli</string>\n    <string name=\"color_matrix\">Matryca kolorów</string>\n    <string name=\"opacity\">Krycie</string>\n    <string name=\"limits_resize_sub\">Zmień rozmiar obrazów do podanej wysokości i szerokości, zachowując współczynnik proporcji</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Plakatowanie</string>\n    <string name=\"non_maximum_suppression\">Nie maksymalne tłumienie</string>\n    <string name=\"weak_pixel_inclusion\">Słaba integracja pikseli</string>\n    <string name=\"lookup\">Przegląd</string>\n    <string name=\"first_color\">Pierwszy kolor</string>\n    <string name=\"second_color\">Drugi kolor</string>\n    <string name=\"reorder\">Zmień kolejność</string>\n    <string name=\"fast_blur\">Szybkie rozmycie</string>\n    <string name=\"blur_size\">Rozmiar rozmycia</string>\n    <string name=\"blur_center_x\">Rozmycie centrum x</string>\n    <string name=\"blur_center_y\">Rozmycie środka y</string>\n    <string name=\"zoom_blur\">Powiększ rozmycie</string>\n    <string name=\"color_balance\">Balans kolorów</string>\n    <string name=\"luminance_threshold\">Próg luminancji</string>\n    <string name=\"file_explorer_picker\">Przeglądarka plików</string>\n    <string name=\"gallery_picker_sub\">Prosty selektor obrazów w galerii. Działa tylko wtedy, gdy masz aplikację, która umożliwia wybieranie multimediów</string>\n    <string name=\"load_image_from_net\">Ładowanie obrazu sieciowego</string>\n    <string name=\"edit\">Edycja</string>\n    <string name=\"order\">Kolejność</string>\n    <string name=\"order_sub\">Określa kolejność narzędzi na ekranie głównym</string>\n    <string name=\"content_scale\">Skala zawartości</string>\n    <string name=\"sequence_num\">Sekwencja liczb</string>\n    <string name=\"original_filename\">Oryginalna nazwa pliku</string>\n    <string name=\"add_original_filename\">Dodaj oryginalną nazwę pliku</string>\n    <string name=\"add_original_filename_sub\">Jeśli włączone, dodaje oryginalną nazwę pliku do nazwy obrazu wyjściowego</string>\n    <string name=\"filename_not_work_with_photopicker\">Dodawanie oryginalnej nazwy pliku nie działa, jeśli wybrano źródło obrazu w selektorze zdjęć</string>\n    <string name=\"copy\">Kopiuj</string>\n    <string name=\"draw_sub\">Rysuj na obrazie jak w szkicowniku lub rysuj na samym tle</string>\n    <string name=\"draw\">Rysuj</string>\n    <string name=\"screenshot\">Zrzut ekranu</string>\n    <string name=\"paint_alpha\">Maluj alfa</string>\n    <string name=\"group_options_by_type\">Pogrupuj opcje według typu</string>\n    <string name=\"group_options_by_type_sub\">Grupuje opcje na ekranie głównym według ich typu zamiast niestandardowego układu listy</string>\n    <string name=\"edit_screenshot\">Edytuj zrzut ekranu</string>\n    <string name=\"secondary_customization\">Personalizacja dodatkowa</string>\n    <string name=\"fallback_option\">Opcja rezerwowa</string>\n    <string name=\"skip\">Pomiń</string>\n    <string name=\"warning_bytes\">Zapisywanie w trybie %1$s może być niestabilne, ponieważ jest to format bezstratny</string>\n    <string name=\"invalid_password_or_not_encrypted\">Nieprawidłowe hasło lub wybrany plik nie jest zaszyfrowany</string>\n    <string name=\"pick_file_to_start\">Wybierz plik, aby rozpocząć</string>\n    <string name=\"decryption\">Deszyfrowanie</string>\n    <string name=\"encryption\">Szyfrowanie</string>\n    <string name=\"key\">Klucz</string>\n    <string name=\"file_proceed\">Plik przetworzony</string>\n    <string name=\"features_sub\">Szyfrowanie plików oparte na hasłach. Przetworzone pliki mogą być przechowywane w wybranym katalogu lub udostępniane. Odszyfrowane pliki można również otworzyć bezpośrednio.</string>\n    <string name=\"file_size\">Rozmiar pliku</string>\n    <string name=\"cache_size\">Rozmiar pamięci podręcznej</string>\n    <string name=\"cache\">Pamięć podręczna</string>\n    <string name=\"image_size_warning\">Próba zapisania obrazu z podaną szerokością i wysokością może spowodować błąd braku pamięci. Robisz to na własne ryzyko.</string>\n    <string name=\"found_s\">Znaleziono %1$s</string>\n    <string name=\"create\">Twórz</string>\n    <string name=\"activate_files\">Wyłączyłeś aplikację Pliki. Aktywuj ją, aby korzystać z tej funkcji</string>\n    <string name=\"paint_color\">Kolor farby</string>\n    <string name=\"draw_on_image\">Narysuj na obrazie</string>\n    <string name=\"draw_on_image_sub\">Wybierz obrazek i narysuj coś na nim</string>\n    <string name=\"draw_on_background\">Rysuj na tle</string>\n    <string name=\"draw_on_background_sub\">Wybierz kolor tła i rysuj na nim</string>\n    <string name=\"background_color\">Kolor tła</string>\n    <string name=\"decrypt\">Odszyfruj</string>\n    <string name=\"compatibility\">Zgodność</string>\n    <string name=\"compatibility_sub\">Należy pamiętać, że zgodność z innym oprogramowaniem lub usługami do szyfrowania plików nie jest gwarantowana. Przyczyną niezgodności może być nieco inna obróbka klucza lub konfiguracja szyfru.</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Nie można zmienić układu, gdy włączone jest grupowanie opcji</string>\n    <string name=\"implementation_sub\">AES-256, tryb GCM, brak wypełnienia, domyślnie 12 bajtów losowych IV. Można wybrać odpowiedni algorytm. Klucze są używane jako 256-bitowe skróty SHA-3</string>\n    <string name=\"cipher\">Szyfr</string>\n    <string name=\"cipher_sub\">Szyfrowanie i deszyfrowanie dowolnego pliku (nie tylko obrazu) w oparciu o różne dostępne algorytmy kryptograficzne.</string>\n    <string name=\"pick_file\">Wybierz plik</string>\n    <string name=\"encrypt\">Szyfruj</string>\n    <string name=\"store_file_desc\">Zapisz ten plik na swoim urządzeniu lub użyj okna udostępniania, aby umieścić go w dowolnym miejscu</string>\n    <string name=\"features\">Funkcje</string>\n    <string name=\"implementation\">Implementacja</string>\n    <string name=\"file_size_sub\">Maksymalny rozmiar pliku jest ograniczony przez system operacyjny Android i dostępną pamięć RAM, co zależy od Twojego urządzenia. \\nUwaga: pamięć RAM to nie miejsce na dane.</string>\n    <string name=\"tools\">Narzędzia</string>\n    <string name=\"auto_cache_clearing\">Automatyczne czyszczenie pamięci podręcznej</string>\n    <string name=\"auto_cache_clearing_sub\">Jeśli ta opcja jest włączona, pamięć podręczna aplikacji zostanie wyczyszczona podczas uruchamiania aplikacji</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"backup_and_restore\">Kopia zapasowa i przywracanie</string>\n    <string name=\"objects\">Obiekty</string>\n    <string name=\"backup\">Kopia zapasowa</string>\n    <string name=\"draw_mode\">Tryb rysowania</string>\n    <string name=\"something_went_wrong_emphasis\">Ups… Coś poszło nie tak. Możesz do mnie napisać, korzystając z opcji poniżej, postaram się znaleźć rozwiązanie</string>\n    <string name=\"draw_arrows\">Narysuj strzałki</string>\n    <string name=\"draw_arrows_sub\">Jeśli ta opcja jest włączona, ścieżka rysowania będzie reprezentowana jako strzałka wskazująca</string>\n    <string name=\"enhanced_pixelation\">Ulepszona pikselizacja</string>\n    <string name=\"target_color\">Kolor docelowy</string>\n    <string name=\"tg_chat\">Czat Telegram</string>\n    <string name=\"enable_emoji\">Włącz emotikony</string>\n    <string name=\"travels_and_places\">Podróże i miejsca</string>\n    <string name=\"background_remover_sub\">Usuń tło poprzez obrysowane ręczne lub automatycznie.</string>\n    <string name=\"brush_softness\">Miękkość pędzla</string>\n    <string name=\"crop_mask\">Maska przycinania</string>\n    <string name=\"contact_me\">Skontaktuj się ze mną</string>\n    <string name=\"saved_to_without_filename\">Zapisano do folderu %1$s</string>\n    <string name=\"updates\">Aktualizacje</string>\n    <string name=\"allow_betas\">Zezwalaj na wersje beta</string>\n    <string name=\"invert_colors\">Odwróć kolory</string>\n    <string name=\"invert_colors_sub\">Zamienia kolory motywu na negatywne</string>\n    <string name=\"search_option\">Szukaj</string>\n    <string name=\"search_option_sub\">Umożliwia przeszukiwanie wszystkich dostępnych narzędzi na ekranie głównym</string>\n    <string name=\"scale_small_images_to_large_sub\">Jeśli ta opcja jest włączona, małe obrazy zostaną przeskalowane do największego w sekwencji</string>\n    <string name=\"background_remover\">Usuwanie tła</string>\n    <string name=\"symbols\">Symbole</string>\n    <string name=\"activities\">Aktywności</string>\n    <string name=\"erase_background\">Usuń tło</string>\n    <string name=\"restore_image\">Przywróć obraz</string>\n    <string name=\"restore_background\">Przywróć tło</string>\n    <string name=\"blur_radius\">Promień rozmycia</string>\n    <string name=\"erase_mode\">Gumka</string>\n    <string name=\"create_issue\">Utwórz problem</string>\n    <string name=\"resize_and_convert\">Zmień rozmiar i konwertuj</string>\n    <string name=\"pipette\">Pipeta</string>\n    <string name=\"allow_betas_sub\">Sprawdzanie aktualizacji obejmie wersje beta aplikacji, jeśli jest włączone</string>\n    <string name=\"crop_description\">Zdjęcia zostaną przycięte do środka do wprowadzonego rozmiaru. Kanwa zostanie powiększona o podany kolor tła, jeśli obraz będzie mniejszy niż wprowadzone wymiary.</string>\n    <string name=\"enhanced_diamond_pixelation\">Ulepszona diamentowa pikselizacja</string>\n    <string name=\"diamond_pixelation\">Diamentowa pikselizacja</string>\n    <string name=\"circle_pixelation\">Pikselizacja kołowa</string>\n    <string name=\"enhanced_circle_pixelation\">Ulepszona kołowa pikselizacja</string>\n    <string name=\"stroke_pixelation\">Pikselizacja obrysu</string>\n    <string name=\"color_to_replace\">Kolor do zamiany</string>\n    <string name=\"color_to_remove\">Kolor do usunięcia</string>\n    <string name=\"remove_color\">Usuń kolor</string>\n    <string name=\"recode\">Przekoduj</string>\n    <string name=\"preview_pdf\">Przeglądarka PDF</string>\n    <string name=\"pdf_to_images\">Zapisz PDF jako obraz</string>\n    <string name=\"images_to_pdf\">Zapisz obraz jako PDF</string>\n    <string name=\"preview_pdf_sub\">Prosty podgląd plików PDF</string>\n    <string name=\"pdf_tools\">Narzędzia PDF</string>\n    <string name=\"max_colors_count\">Maksymalna liczba kolorów</string>\n    <string name=\"image_stitching\">Łączenie obrazów</string>\n    <string name=\"image_stitching_sub\">Połącz podane obrazy, aby uzyskać jeden duży</string>\n    <string name=\"pick_at_least_two_images\">Wybierz co najmniej 2 obrazy</string>\n    <string name=\"output_image_scale\">Skala obrazu wyjściowego</string>\n    <string name=\"pixel_size\">Rozmiar piksela</string>\n    <string name=\"lock_draw_orientation\">Zablokuj orientację rysowania</string>\n    <string name=\"resize_and_convert_sub\">Zmień rozmiar podanych obrazów lub przekonwertuj je na inne formaty. Możesz też edytować metadane EXIF, jeśli wybierzesz jeden obraz.</string>\n    <string name=\"lock_draw_orientation_sub\">Jeśli opcja ta jest włączona w trybie rysowania, ekran nie będzie się obracał.</string>\n    <string name=\"restore\">Przywracanie</string>\n    <string name=\"backup_sub\">Utwórz kopię zapasową ustawień do pliku</string>\n    <string name=\"restore_sub\">Przywróć ustawienia aplikacji z ostatniego pliku</string>\n    <string name=\"auto_erase_background\">Automatycznie usuń tło</string>\n    <string name=\"check_for_updates\">Sprawdź nowe aktualizacje</string>\n    <string name=\"rainbow\">Tęcza</string>\n    <string name=\"tonal_spot_sub\">Domyślny styl palety, pozwala dostosować wszystkie cztery kolory, inne pozwalają ustawić tylko kolor kluczowy</string>\n    <string name=\"content_sub\">Schemat umieszczający kolor źródłowy w kontenerze Scheme.primaryContainer</string>\n    <string name=\"donation\">Darowizna</string>\n    <string name=\"image_orientation\">Orientacja obrazu</string>\n    <string name=\"horizontal\">Pozioma</string>\n    <string name=\"vertical\">Pionowa</string>\n    <string name=\"scale_small_images_to_large\">Skaluj małe obrazy do dużych</string>\n    <string name=\"images_order\">Kolejność zdjęć</string>\n    <string name=\"regular\">Normalny</string>\n    <string name=\"blur_edges\">Rozmyte krawędzie</string>\n    <string name=\"blur_edges_sub\">Rysuje rozmyte krawędzie pod oryginalnym obrazem, aby wypełnić przestrzenie wokół niego zamiast pojedynczego koloru.</string>\n    <string name=\"pixelation\">Pikselizacja</string>\n    <string name=\"replace_color\">Zamień kolor</string>\n    <string name=\"tolerance\">Tolerancja</string>\n    <string name=\"palette_style\">Styl palety</string>\n    <string name=\"tonal_spot\">Punkt tonalny</string>\n    <string name=\"neutral\">Neutralny</string>\n    <string name=\"vibrant\">Żywy</string>\n    <string name=\"expressive\">Ekspresyjny</string>\n    <string name=\"fruit_salad\">Sałatka owocowa</string>\n    <string name=\"fidelity\">Wierność</string>\n    <string name=\"content\">Zawartość</string>\n    <string name=\"neutral_sub\">Styl nieco bardziej chromatyczny niż monochromatyczny</string>\n    <string name=\"vibrant_sub\">Głośny motyw, kolorowość jest maksymalna dla palety podstawowej, zwiększona dla innych</string>\n    <string name=\"playful_scheme\">Zabawny motyw — odcień koloru źródłowego nie pojawia się w motywie</string>\n    <string name=\"monochrome_sub\">Motyw monochromatyczny, kolory są czysto czarne / białe / szare</string>\n    <string name=\"fidelity_sub\">Schemat bardzo podobny do schematu treści</string>\n    <string name=\"pdf_tools_sub\">Operuj na plikach PDF: Podgląd, Konwertuj na partię obrazów lub utwórz jeden z podanych zdjęć</string>\n    <string name=\"foss_update_checker_warning\">Ten moduł sprawdzania aktualizacji połączy się z GitHubem w celu sprawdzenia, czy dostępna jest nowa aktualizacja</string>\n    <string name=\"attention\">Uwaga</string>\n    <string name=\"fading_edges\">Zanikające krawędzie</string>\n    <string name=\"disabled\">wyłączony</string>\n    <string name=\"randomize_filename\">Losuj nazwę pliku</string>\n    <string name=\"randomize_filename_sub\">Jeśli włączone, nazwa pliku wyjściowego będzie w pełni losowa</string>\n    <string name=\"saved_to\">Zapisano w folderze %1$s z nazwą %2$s</string>\n    <string name=\"presets_sub_bytes\">Preset określa % rozmiaru pliku wyjściowego, tj. jeśli wybierzesz ustawienie wstępne 50 na obrazie o rozmiarze 5 MB, po zapisaniu otrzymasz obraz o rozmiarze 2,5 MB</string>\n    <string name=\"presets_sub\" formatted=\"false\">Jeśli wybrano ustawienie 125, obraz zostanie zapisany w rozmiarze 125% oryginalnego obrazu. W przypadku wybrania ustawienia 50 obraz zostanie zapisany w rozmiarze 50%.</string>\n    <string name=\"text\">Tekst</string>\n    <string name=\"font_scale\">Skala czcionki</string>\n    <string name=\"defaultt\">Domyślna</string>\n    <string name=\"using_large_fonts_warn\">Używanie dużych czcionek może powodować usterki interfejsu użytkownika i problemy, których nie da się naprawić. Używaj ostrożnie.</string>\n    <string name=\"alphabet_and_numbers\">Aa Ąą Bb Cc Ćć Dd Ee Ęę Ff Gg Hh Ii Jj Kk Ll Łł Mm Nn Ńń Oo Óó Pp Qq Rr Ss Śś Tt Uu Vv Ww Xx Yy Zz Źź Żż 0123456789 !?</string>\n    <string name=\"trim_image\">Przytnij obraz</string>\n    <string name=\"reset_settings_sub\">Spowoduje to przywrócenie ustawień domyślnych. Należy pamiętać, że nie można tego cofnąć bez pliku kopii zapasowej wspomnianego powyżej.</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Uszkodzony plik lub brak kopii zapasowej</string>\n    <string name=\"image_exif_warning\">Obecnie format %1$s pozwala jedynie na odczyt metadanych EXIF na Androidzie. Obraz wyjściowy nie będzie zawierał metadanych po zapisaniu.</string>\n    <string name=\"font\">Czcionka</string>\n    <string name=\"effort_sub\">Wartość %1$s oznacza szybką kompresję, co skutkuje stosunkowo dużym rozmiarem pliku. Wartość %2$s oznacza wolniejszą kompresję, co skutkuje mniejszym plikiem.</string>\n    <string name=\"keep_exif_sub\">Oryginalne metadane obrazu zostaną zachowane</string>\n    <string name=\"trim_image_sub\">Przezroczyste przestrzenie wokół obrazu zostaną przycięte</string>\n    <string name=\"crashlytics_sub\">Dzięki temu aplikacja może automatycznie zbierać raporty o awariach</string>\n    <string name=\"mask_preview\">Podgląd maski</string>\n    <string name=\"inverse_fill_type_sub\">Jeśli opcja ta jest włączona, wszystkie niezamaskowane obszary będą filtrowane zamiast domyślnego zachowania.</string>\n    <string name=\"highlighter_sub\">Rysuj półprzezroczyste, zaostrzone ścieżki zakreślacza</string>\n    <string name=\"delete_mask_warn\">Zamierzasz usunąć wybraną maskę filtru. Operacji tej nie można cofnąć</string>\n    <string name=\"wait\">Czekaj</string>\n    <string name=\"full_filter\">Pełny filtr</string>\n    <string name=\"start_position\">Początek</string>\n    <string name=\"center_position\">Środek</string>\n    <string name=\"end_position\">Koniec</string>\n    <string name=\"full_filter_sub\">Zastosuj dowolne łańcuchy filtrów do podanych obrazów lub pojedynczego obrazu</string>\n    <string name=\"pdf_to_images_sub\">Konwersja plików PDF na obrazy w podanym formacie wyjściowym</string>\n    <string name=\"images_to_pdf_sub\">Spakuj podane obrazy do wyjściowego pliku PDF</string>\n    <string name=\"effort\">Wysiłek</string>\n    <string name=\"mask_color\">Kolor maski</string>\n    <string name=\"masks\">Maski</string>\n    <string name=\"tg_chat_sub\">Podyskutuj o aplikacji i poznaj opinie innych użytkowników. Można tam również uzyskać aktualizacje wersji beta.</string>\n    <string name=\"aspect_ratio\">Proporcje</string>\n    <string name=\"image_crop_mask_sub\">Użyj tego typu maski, aby utworzyć maskę z danego obrazu, zauważ, że POWINNA ona mieć kanał alfa.</string>\n    <string name=\"settings_restored\">Ustawienia przywrócone pomyślnie</string>\n    <string name=\"delete\">Usuń</string>\n    <string name=\"emotions\">Emocje</string>\n    <string name=\"delete_color_scheme_warn\">Wybrany schemat kolorów zostanie usunięty. Operacji tej nie można cofnąć</string>\n    <string name=\"delete_color_scheme_title\">Usuń schemat</string>\n    <string name=\"food_and_drink\">Jedzenie i picie</string>\n    <string name=\"nature_and_animals\">Przyroda i zwierzęta</string>\n    <string name=\"analytics\">Analityka</string>\n    <string name=\"analytics_sub\">Zezwalaj na zbieranie anonimowych statystyk użytkowania aplikacji</string>\n    <string name=\"saving_almost_complete\">Zapisywanie prawie zakończone. Anulowanie będzie wymagało ponownego zapisania.</string>\n    <string name=\"mask_indexed\">Maska %d</string>\n    <string name=\"inverse_fill_type\">Odwróć typ wypełnienia</string>\n    <string name=\"mask_filter\">Filtr maskujący</string>\n    <string name=\"mask_filter_sub\">Zastosuj łańcuchy filtrów na danych maskowanych obszarach, każdy obszar maski może określić własny zestaw filtrów</string>\n    <string name=\"add_mask\">Dodaj maskę</string>\n    <string name=\"mask_preview_sub\">Narysowana maska filtra zostanie wyrenderowana, aby pokazać przybliżony wynik</string>\n    <string name=\"delete_mask\">Usuń maskę</string>\n    <string name=\"simple_variants\">Proste warianty</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Pióro</string>\n    <string name=\"privacy_blur\">Rozmycie prywatności</string>\n    <string name=\"highlighter\">Zakreślacz</string>\n    <string name=\"neon_sub\">Dodaj trochę blasku do swoich rysunków</string>\n    <string name=\"pen_sub\">Domyślny, najprostszy - tylko kolor</string>\n    <string name=\"pixelation_sub\">Podobne do rozmycia prywatności, ale pikselizuje zamiast rozmywać</string>\n    <string name=\"privacy_blur_sub\">Rozmywa obraz pod narysowaną ścieżką, aby zabezpieczyć wszystko, co chcesz ukryć.</string>\n    <string name=\"containers_shadow\">Kontenery</string>\n    <string name=\"containers_shadow_sub\">Rysuj cień za kontenerami</string>\n    <string name=\"sliders_shadow\">Suwaki</string>\n    <string name=\"switches_shadow\">Przełączniki</string>\n    <string name=\"both\">Oba</string>\n    <string name=\"fabs_shadow\">Pływające przyciski</string>\n    <string name=\"buttons_shadow\">Przyciski</string>\n    <string name=\"sliders_shadow_sub\">Rysuj cień za suwakami</string>\n    <string name=\"switches_shadow_sub\">Rysuj cień za przełącznikami</string>\n    <string name=\"fabs_shadow_sub\">Rysuj cień za pływającymi przyciskami akcji</string>\n    <string name=\"app_bars_shadow_sub\">Rysuj cień za paskami aplikacji</string>\n    <string name=\"value_in_range\">Wartość z zakresu %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Obrót automatyczny</string>\n    <string name=\"outlined_rect\">Prostokąt (kontury)</string>\n    <string name=\"rect\">Prostokąt</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"bicubic_sub\">Lepsze metody skalowania obejmują ponowne próbkowanie Lanczos i filtry Mitchell-Netravali</string>\n    <string name=\"basic_sub\">Najprostszy tryb skalowania Androida, który jest używany w prawie wszystkich aplikacjach</string>\n    <string name=\"restore_background_sub\">Pędzel przywróci tło zamiast je wymazywać</string>\n    <string name=\"best\">Najlepszy</string>\n    <string name=\"no_such_directory\">Nie znaleziono katalogu \\\"%1$s\\\", zmieniliśmy go na domyślny, zapisz plik ponownie</string>\n    <string name=\"clipboard\">Schowek</string>\n    <string name=\"auto_pin\">Automatyczne przypinanie</string>\n    <string name=\"auto_pin_sub\">Automatycznie dodaje zapisany obraz do schowka, jeśli jest włączone</string>\n    <string name=\"vibration\">Wibracje</string>\n    <string name=\"vibration_strength\">Siła wibracji</string>\n    <string name=\"overwrite_file_requirements\">Aby nadpisać pliki, musisz użyć źródła obrazu \\\"Explorer\\\". Spróbuj ponownie wybrać obrazy, zmieniliśmy źródło obrazu na wymagane</string>\n    <string name=\"overwrite_files\">Nadpisz pliki</string>\n    <string name=\"overwrite_files_sub\">Oryginalny plik zostanie zastąpiony nowym zamiast zapisywania w wybranym folderze. Ta opcja wymaga, aby źródłem obrazu był \\\"Explorer\\\" lub GetContent, po przełączeniu tej opcji zostanie ona ustawiona automatycznie.</string>\n    <string name=\"empty\">Pusty</string>\n    <string name=\"suffix\">Sufiks</string>\n    <string name=\"free\">Swobodny</string>\n    <string name=\"lasso_sub\">Rysuje zamkniętą, wypełnioną ścieżkę według podanej ścieżki</string>\n    <string name=\"draw_path_mode\">Tryb rysowania ścieżki</string>\n    <string name=\"double_line_arrow\">Strzałka z podwójną linią</string>\n    <string name=\"free_drawing\">Swobodne rysowanie</string>\n    <string name=\"double_arrow\">Podwójna strzałka</string>\n    <string name=\"line_arrow\">Strzałka liniowa</string>\n    <string name=\"arrow\">Strzałka</string>\n    <string name=\"line\">Linia</string>\n    <string name=\"free_drawing_sub\">Rysuje ścieżkę jako wartość wejściową</string>\n    <string name=\"line_sub\">Rysuje ścieżkę od punktu początkowego do końcowego jako linię</string>\n    <string name=\"line_arrow_sub\">Rysuje strzałkę wskazującą od punktu początkowego do punktu końcowego jako linię</string>\n    <string name=\"arrow_sub\">Rysuje strzałkę wskazującą z danej ścieżki</string>\n    <string name=\"double_line_arrow_sub\">Rysuje podwójną strzałkę od punktu początkowego do końcowego jako linię</string>\n    <string name=\"double_arrow_sub\">Rysuje podwójną strzałkę wskazującą z danej ścieżki</string>\n    <string name=\"oval\">Owal</string>\n    <string name=\"outlined_oval\">Owal (kontury)</string>\n    <string name=\"rect_sub\">Rysuje prostokąt od punktu początkowego do punktu końcowego</string>\n    <string name=\"oval_sub\">Rysuje owal od punktu początkowego do punktu końcowego</string>\n    <string name=\"outlined_oval_sub\">Rysuje kontury owala od punktu początkowego do punktu końcowego</string>\n    <string name=\"outlined_rect_sub\">Rysuje kontury prostokąta od punktu początkowego do punktu końcowego</string>\n    <string name=\"scale_mode\">Tryb skalowania</string>\n    <string name=\"bilinear\">Bilinearny</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Najbliższy</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Prosty</string>\n    <string name=\"default_value\">Domyślna wartość</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Dwusześcienny</string>\n    <string name=\"bilinear_sub\">Interpolacja liniowa (lub dwuliniowa, w dwóch wymiarach) jest zazwyczaj dobra do zmiany rozmiaru obrazu, ale powoduje pewne niepożądane zmiękczenie szczegółów i nadal może być nieco postrzępiona</string>\n    <string name=\"nearest_sub\">Jeden z prostszych sposobów na zwiększenie rozmiaru, zastępując każdy piksel liczbą pikseli tego samego koloru</string>\n    <string name=\"catmull_sub\">Metoda płynnej interpolacji i ponownego próbkowania zestawu punktów kontrolnych, powszechnie stosowana w grafice komputerowej do tworzenia gładkich krzywych.</string>\n    <string name=\"hermite_sub\">Matematyczna technika interpolacji, która wykorzystuje wartości i pochodne w punktach końcowych segmentu krzywej w celu wygenerowania gładkiej i ciągłej krzywej</string>\n    <string name=\"lanczos_sub\">Metoda ponownego próbkowania, która utrzymuje wysoką jakość interpolacji poprzez zastosowanie ważonej funkcji sinc do wartości pikseli</string>\n    <string name=\"mitchell_sub\">Metoda ponownego próbkowania wykorzystująca filtr splotowy z regulowanymi parametrami w celu uzyskania równowagi między ostrością a antyaliasingiem w skalowanym obrazie</string>\n    <string name=\"spline_sub\">Wykorzystuje zdefiniowane fragmentarycznie funkcje wielomianowe do płynnej interpolacji i aproksymacji krzywej lub powierzchni, zapewniając elastyczną i ciągłą reprezentację kształtu</string>\n    <string name=\"only_clip\">Tylko przytnij</string>\n    <string name=\"only_clip_sub\">Zapis do pamięci masowej nie zostanie wykonany, obraz będzie umieszczony tylko w schowku</string>\n    <string name=\"recognize_text\">OCR (rozpoznawanie tekstu)</string>\n    <string name=\"recognize_text_sub\">Rozpoznawanie tekstu z danego obrazu, obsługa ponad 120 języków</string>\n    <string name=\"picture_has_no_text\">Obraz nie zawiera tekstu lub aplikacja go nie znalazła</string>\n    <string name=\"accuracy\">Dokładność: %1$s</string>\n    <string name=\"recognition_type\">Typ rozpoznawania</string>\n    <string name=\"fast\">Szybki</string>\n    <string name=\"standard\">Standardowy</string>\n    <string name=\"horizontal_grid\">Siatka pozioma</string>\n    <string name=\"vertical_grid\">Siatka pionowa</string>\n    <string name=\"stitch_mode\">Tryb ściegu</string>\n    <string name=\"rows_count\">Liczba wierszy</string>\n    <string name=\"columns_count\">Liczba kolumn</string>\n    <string name=\"auto_rotate_limits_sub\">Umożliwia przyjęcie ramki ograniczającej dla orientacji obrazu</string>\n    <string name=\"buttons_shadow_sub\">Rysuj cień za przyciskami</string>\n    <string name=\"app_bars_shadow\">Paski aplikacji</string>\n    <string name=\"hann_sub\">Funkcja okienkowania często stosowana w przetwarzaniu sygnału w celu zminimalizowania wycieków widmowych i poprawy dokładności analizy częstotliwości poprzez zwężanie krawędzi sygnału.</string>\n    <string name=\"segmentation_mode_osd_only\">Tylko wykrywanie orientacji i skryptów</string>\n    <string name=\"segmentation_mode_auto\">Automatyczny</string>\n    <string name=\"segmentation_mode_single_column\">Pojedyncza kolumna</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Pojedynczy blok tekstu pionowego</string>\n    <string name=\"segmentation_mode_single_line\">Pojedyncza linia</string>\n    <string name=\"segmentation_mode_single_word\">Pojedyncze słowo</string>\n    <string name=\"segmentation_mode_raw_line\">Surowy wiersz</string>\n    <string name=\"amount\">Ilość</string>\n    <string name=\"use_pixel_switch_sub\">Używa przełącznika podobnego do Google Pixel</string>\n    <string name=\"rate_app\">Oceń aplikację</string>\n    <string name=\"rate\">Oceń</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatyczne wykrywanie orientacji i skryptów</string>\n    <string name=\"camera_sub\">Zrób zdjęcie aparatem. Należy pamiętać, że z tego źródła obrazu można uzyskać tylko jeden obraz</string>\n    <string name=\"segmentation_mode_auto_only\">Tylko automat</string>\n    <string name=\"segmentation_mode_single_block\">Pojedynczy blok</string>\n    <string name=\"segmentation_mode_circle_word\">Słowo w kółku</string>\n    <string name=\"segmentation_mode_sparse_text\">Obszerny tekst</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Wykrywanie krawędzi i skryptu obszernego tekstu</string>\n    <string name=\"segmentation_mode_single_char\">Pojedynczy znak</string>\n    <string name=\"all\">Wszystkie</string>\n    <string name=\"noise\">Szum</string>\n    <string name=\"shuffle\">Losuj</string>\n    <string name=\"no_data\">Brak danych</string>\n    <string name=\"downloaded_languages\">Pobrane języki</string>\n    <string name=\"brightness_enforcement\">Egzekwowanie jasności</string>\n    <string name=\"screen\">Ekran</string>\n    <string name=\"frame_delay\">Opóźnienie ramki</string>\n    <string name=\"gray_scale\">Skala szarości</string>\n    <string name=\"bayer_four_dithering\">Rozpraszanie Bayer Four By Four</string>\n    <string name=\"sierra_dithering\">Rozpraszanie Sierra</string>\n    <string name=\"sierra_lite_dithering\">Rozpraszanie Sierra Lite</string>\n    <string name=\"atkinson_dithering\">Rozpraszanie Atkinson</string>\n    <string name=\"bayer_eight_dithering\">Rozpraszanie Bayer Eight By Eight</string>\n    <string name=\"two_row_sierra_dithering\">Rozpraszanie Two Row Sierra</string>\n    <string name=\"stucki_dithering\">Rozpraszanie Stucki</string>\n    <string name=\"anaglyph\">Anaglif</string>\n    <string name=\"secure_mode_sub\">Ukrywa zawartość aplikacji w ostatnich aplikacjach. Nie można jej przechwycić ani nagrać.</string>\n    <string name=\"pixel_sort\">Sortowanie pikseli</string>\n    <string name=\"glitch\">Glitch</string>\n    <string name=\"seed\">Ziarno</string>\n    <string name=\"delete_language_sub\">Czy chcesz usunąć dane szkoleniowe OCR języka \\\"%1$s\\\" dla wszystkich typów rozpoznawania, czy tylko dla wybranego (%2$s)?</string>\n    <string name=\"current\">Wybrany</string>\n    <string name=\"gradient_maker\">Kreator gradientów</string>\n    <string name=\"gradient_maker_sub\">Twórz gradient o danym rozmiarze wyjściowym z niestandardowymi kolorami i typem wyglądu</string>\n    <string name=\"rate_app_sub\">Ta aplikacja jest całkowicie darmowa, jeśli chcesz, aby stała się większa, oznacz projekt na Github 😄.</string>\n    <string name=\"gradient_type_radial\">Promieniowy</string>\n    <string name=\"gradient_type_linear\">Liniowy</string>\n    <string name=\"gradient_type_sweep\">Stożkowy</string>\n    <string name=\"gradient_type\">Rodzaj gradientu</string>\n    <string name=\"center_x\">Środek X</string>\n    <string name=\"center_y\">Środek Y</string>\n    <string name=\"tile_mode\">Tryb kafelków</string>\n    <string name=\"tile_mode_repeated\">Powtarzane</string>\n    <string name=\"tile_mode_mirror\">Lustrzane odbicie</string>\n    <string name=\"tile_mode_clamp\">Uchwyt</string>\n    <string name=\"tile_mode_decal\">Kalkomania</string>\n    <string name=\"color_stops\">Ograniczniki kolorów</string>\n    <string name=\"add_color\">Dodaj kolor</string>\n    <string name=\"properties\">Właściwości</string>\n    <string name=\"quantizier\">Kwantyzator</string>\n    <string name=\"dithering\">Rozpraszanie</string>\n    <string name=\"bayer_two_dithering\">Rozpraszanie Bayer Two By Two</string>\n    <string name=\"bayer_three_dithering\">Rozpraszanie Bayer Three By Three</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Rozpraszanie Jarvis Judice Ninke</string>\n    <string name=\"burkes_dithering\">Rozpraszanie Burkes</string>\n    <string name=\"false_floyd_steinberg_dithering\">Rozpraszanie False Floyd Steinberg</string>\n    <string name=\"random_dithering\">Rozpraszanie losowe</string>\n    <string name=\"left_to_right_dithering\">Rozpraszanie z lewej do prawej</string>\n    <string name=\"simple_threshold_dithering\">Rozpraszanie Simple Threshold</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Spatial Sigma</string>\n    <string name=\"median_blur\">Rozmycie medianą</string>\n    <string name=\"gradient_maker_type_image\">Nakładka gradientu</string>\n    <string name=\"gradient_maker_type_image_sub\">Skomponuj dowolny gradient na danych obrazach</string>\n    <string name=\"transformations\">Przekształcenia</string>\n    <string name=\"camera\">Aparat</string>\n    <string name=\"watermarking\">Znaki wodne</string>\n    <string name=\"watermarking_sub\">Nakłada konfigurowalne tekstowe/graficzne znaki wodne</string>\n    <string name=\"repeat_watermark\">Powtarzanie znaku wodnego</string>\n    <string name=\"repeat_watermark_sub\">Powtarza znak wodny na obrazie zamiast pojedynczego w danej pozycji</string>\n    <string name=\"offset_x\">Przesunięcie X</string>\n    <string name=\"offset_y\">Przesunięcie Y</string>\n    <string name=\"watermark_type\">Typ znaku wodnego</string>\n    <string name=\"watermarking_image_sub\">Obraz ten zostanie użyty jako wzorzec dla znaku wodnego</string>\n    <string name=\"text_color\">Kolor tekstu</string>\n    <string name=\"overlay_mode\">Tryb nakładania</string>\n    <string name=\"gif_tools\">Narzędzia GIF</string>\n    <string name=\"gif_tools_sub\">Konwertuj obrazy na GIF-y lub wyodrębnij pojedynczą klatkę z animacji GIF</string>\n    <string name=\"gif_type_to_image_sub\">Konwertuj plik GIF do partii obrazów</string>\n    <string name=\"gif_type_to_gif_sub\">Konwertuj partię obrazów do pliku GIF</string>\n    <string name=\"gif_type_to_gif\">Obrazy do GIF</string>\n    <string name=\"select_gif_image_to_start\">Wybierz obraz GIF, aby rozpocząć</string>\n    <string name=\"use_size_of_first_frame\">Użyj rozmiaru pierwszej ramki</string>\n    <string name=\"use_size_of_first_frame_sub\">Zastąp określony rozmiar wymiarami pierwszej ramki</string>\n    <string name=\"repeat_count\">Liczba powtórzeń</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Użyj Lasso</string>\n    <string name=\"use_lasso_sub\">Używa Lasso jak w trybie rysowania do wymazywania</string>\n    <string name=\"original_image_preview_alpha\">Podgląd kanału alfa oryginalnego obrazu</string>\n    <string name=\"download\">Pobierz</string>\n    <string name=\"use_pixel_switch\">Użyj przełącznika pikseli</string>\n    <string name=\"slide\">Slajd</string>\n    <string name=\"side_by_side\">Obok siebie</string>\n    <string name=\"toggle_tap\">Przełączanie po stuknięciu</string>\n    <string name=\"transparency\">Przezroczystość</string>\n    <string name=\"saved_to_original\">Nadpisano plik o nazwie %1$s w oryginalnym miejscu docelowym</string>\n    <string name=\"magnifier\">Lupa</string>\n    <string name=\"magnifier_sub\">Włącza lupę w trybach rysowania dla lepszej dostępności.</string>\n    <string name=\"force_exif_widget_initial_value\">Wymuś wartość początkową</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Wymusza wstępne sprawdzenie widżetu exif</string>\n    <string name=\"allow_multiple_languages\">Zezwalaj na wiele języków</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"native_stack_blur\">Natywne rozmycie stosu</string>\n    <string name=\"tilt_shift\">Zmiana zabarwienia</string>\n    <string name=\"confetti\">Konfetti</string>\n    <string name=\"confetti_sub\">Konfetti będzie wyświetlane podczas zapisywania, udostępniania i innych podstawowych działań</string>\n    <string name=\"secure_mode\">Tryb bezpieczny</string>\n    <string name=\"exit\">Wyjdź</string>\n    <string name=\"preview_closing\">Jeśli teraz opuścisz podgląd, będziesz musiał ponownie dodać obrazy</string>\n    <string name=\"download_description\">Do poprawnego działania aplikacji Tesseract OCR konieczne jest pobranie na urządzenie dodatkowych danych szkoleniowych (%1$s). \\nCzy chcesz pobrać dane %2$s?</string>\n    <string name=\"no_connection\">Brak połączenia, sprawdź i spróbuj ponownie, aby pobrać modele trenujące</string>\n    <string name=\"available_languages\">Dostępne języki</string>\n    <string name=\"segmentation_mode\">Tryb segmentacji</string>\n    <string name=\"gif_type_to_image\">GIF do obrazów</string>\n    <string name=\"floyd_steinberg_dithering\">Rozpraszanie Floyd Steinberg</string>\n    <string name=\"b_spline_sub\">Wykorzystuje zdefiniowane fragmentarycznie funkcje wielomianu dwumianowego do płynnej interpolacji i aproksymacji krzywej lub powierzchni, elastycznej i ciągłej reprezentacji kształtu</string>\n    <string name=\"enhanced_glitch\">Rozszerzony Glitch</string>\n    <string name=\"channel_shift_x\">Przesuń kanał X</string>\n    <string name=\"channel_shift_y\">Przesuń kanał Y</string>\n    <string name=\"corruption_size\">Rozmiar korupcji</string>\n    <string name=\"corruption_shift_x\">Korupcyjna zmiana X</string>\n    <string name=\"corruption_shift_y\">Korupcyjna zmiana Y</string>\n    <string name=\"tent_blur\">Tent Blur</string>\n    <string name=\"top\">Szczyt</string>\n    <string name=\"bottom\">Spód</string>\n    <string name=\"aldridge\">Aldridge\\'a</string>\n    <string name=\"cutoff\">Odciąć</string>\n    <string name=\"uchimura\">Uchimurę</string>\n    <string name=\"mobius\">Mobiusa</string>\n    <string name=\"transition\">Przemiana</string>\n    <string name=\"peak\">Szczyt</string>\n    <string name=\"deutaromaly\">Deuteranomalia</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">Strona</string>\n    <string name=\"strength\">Wytrzymałość</string>\n    <string name=\"grain\">Ziarno</string>\n    <string name=\"orange_haze\">Pomarańczowa mgła</string>\n    <string name=\"colorful_swirl\">Kolorowy wir</string>\n    <string name=\"soft_spring_light\">Miękkie wiosenne światło</string>\n    <string name=\"autumn_tones\">Jesienne tony</string>\n    <string name=\"caramel_darkness\">Karmelowa ciemność</string>\n    <string name=\"space_portal\">Portal kosmiczny</string>\n    <string name=\"favorite\">Ulubiony</string>\n    <string name=\"icon_shape\">Kształt ikony</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"color_anomaly\">Anomalia kolorystyczna</string>\n    <string name=\"erode\">Erodować</string>\n    <string name=\"anisotropic_diffusion\">Dyfuzja anizotropowa</string>\n    <string name=\"diffusion\">Dyfuzja</string>\n    <string name=\"conduction\">Przewodzenie</string>\n    <string name=\"horizontal_wind_stagger\">Poziomy nachylenie wiatru</string>\n    <string name=\"fast_bilaterial_blur\">Szybkie rozmycie dwustronne</string>\n    <string name=\"poisson_blur\">Rozmycie Poissona</string>\n    <string name=\"logarithmic_tone_mapping\">Logarytmiczne mapowanie tonów</string>\n    <string name=\"crystallize\">Krystalizować</string>\n    <string name=\"stroke_color\">Kolor obrysu</string>\n    <string name=\"fractal_glass\">Szkło fraktalne</string>\n    <string name=\"amplitude\">Amplituda</string>\n    <string name=\"marble\">Marmur</string>\n    <string name=\"turbulence\">Turbulencja</string>\n    <string name=\"oil\">Olej</string>\n    <string name=\"water_effect\">Efekt wody</string>\n    <string name=\"just_size\">Rozmiar</string>\n    <string name=\"frequency_x\">Częstotliwość X</string>\n    <string name=\"frequency_y\">Częstotliwość Y</string>\n    <string name=\"amplitude_x\">Amplituda X</string>\n    <string name=\"amplitude_y\">Amplituda Y</string>\n    <string name=\"perlin_distortion\">Zniekształcenie Perlina</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmowe mapowanie tonów</string>\n    <string name=\"heji_burgess_tone_mapping\">Mapowanie tonów Heji-Burgess</string>\n    <string name=\"aces_filmic_tone_mapping\">Mapowanie tonów filmowych ACES</string>\n    <string name=\"aces_hill_tone_mapping\">Mapowanie tonów wzgórza ACES</string>\n    <string name=\"speed\">Prędkość</string>\n    <string name=\"dehaze\">Usuń zamglenie</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Matryca kolorów 4x4</string>\n    <string name=\"color_matrix_3x3\">Matryca kolorów 3x3</string>\n    <string name=\"simple_effects\">Proste efekty</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomalia</string>\n    <string name=\"protonomaly\">Protanomalia</string>\n    <string name=\"vintage\">Klasyczny</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Koda Chrome</string>\n    <string name=\"night_vision\">Nocna wizja</string>\n    <string name=\"warm\">Ciepły</string>\n    <string name=\"cool\">Fajny</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Achromatomalia</string>\n    <string name=\"achromatopsia\">Achromatopsja</string>\n    <string name=\"icon_shape_sub\">Dodaje pojemnik z wybranym kształtem pod ikonami</string>\n    <string name=\"unsharp\">Wyostrzyć</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"pink_dream\">Różowy sen</string>\n    <string name=\"golden_hour\">Złota godzina</string>\n    <string name=\"hot_summer\">Gorące lato</string>\n    <string name=\"purple_mist\">Fioletowa Mgła</string>\n    <string name=\"sunrise\">Wschód słońca</string>\n    <string name=\"lavender_dream\">Lawendowy sen</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Lekka lemoniada</string>\n    <string name=\"spectral_fire\">Spektralny Ogień</string>\n    <string name=\"night_magic\">Magia Nocy</string>\n    <string name=\"fantasy_landscape\">Krajobraz fantasy</string>\n    <string name=\"color_explosion\">Eksplozja kolorów</string>\n    <string name=\"electric_gradient\">Gradient elektryczny</string>\n    <string name=\"futuristic_gradient\">Futurystyczny gradient</string>\n    <string name=\"green_sun\">Zielone słońce</string>\n    <string name=\"rainbow_world\">Tęczowy Świat</string>\n    <string name=\"deep_purple\">Głęboki fiolet</string>\n    <string name=\"red_swirl\">Czerwony wir</string>\n    <string name=\"digital_code\">Kod cyfrowy</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">Emotikony paska aplikacji będą zmieniać się losowo</string>\n    <string name=\"random_emojis\">Losowe emotikony</string>\n    <string name=\"random_emojis_error\">Nie można używać losowych emotikonów, gdy są one wyłączone</string>\n    <string name=\"emoji_selection_error\">Nie można wybrać emotikonów, gdy włączone są losowe emotikony</string>\n    <string name=\"old_tv\">Stary telewizor</string>\n    <string name=\"shuffle_blur\">Mieszaj rozmycie</string>\n    <string name=\"no_favorite_filters\">Nie dodano jeszcze żadnych ulubionych filtrów</string>\n    <string name=\"image_format\">Format obrazu</string>\n    <string name=\"images_overwritten\">Obrazy nadpisane w oryginalnym miejscu docelowym</string>\n    <string name=\"emoji_as_color_scheme\">Emoji jako schemat kolorów</string>\n    <string name=\"cannot_change_image_format\">Nie można zmienić formatu obrazu, gdy włączona jest opcja nadpisywania plików</string>\n    <string name=\"emoji_as_color_scheme_sub\">Używa koloru podstawowego emoji jako schematu kolorów aplikacji zamiast ręcznie zdefiniowanego</string>\n    <string name=\"material_you_sub\">Tworzy paletę \\\"Material You\\\" z obrazu</string>\n    <string name=\"dark_colors\">Ciemne Kolory</string>\n    <string name=\"dark_colors_sub\">Wykorzystuje schemat kolorów trybu nocnego zamiast wariantu światła</string>\n    <string name=\"copy_as_compose_code\">Skopiuj jako kod \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Rozmycie Pierścienia</string>\n    <string name=\"cross_blur\">Rozmycie krzyżowe</string>\n    <string name=\"circle_blur\">Rozmycie w kółko</string>\n    <string name=\"star_blur\">Rozmycie gwiazdami</string>\n    <string name=\"linear_tilt_shift\">Liniowa zmiana nachylenia</string>\n    <string name=\"tags_to_remove\">Tagi Do Usunięcia</string>\n    <string name=\"apng_type_to_apng_sub\">Konwertuj partię obrazów do pliku APNG</string>\n    <string name=\"apng_tools\">Narzędzia APNG</string>\n    <string name=\"apng_tools_sub\">Konwertuj obrazy na obraz APNG lub wyodrębniaj klatki z danego obrazu APNG</string>\n    <string name=\"motion_blur\">Rozmycie w ruchu</string>\n    <string name=\"apng_type_to_image_sub\">Konwertuj plik APNG na partię zdjęć</string>\n    <string name=\"apng_type_to_image\">APNG do obrazów</string>\n    <string name=\"select_apng_image_to_start\">Aby rozpocząć, wybierz obraz APNG</string>\n    <string name=\"apng_type_to_apng\">Obrazy do APNG</string>\n    <string name=\"zip\">Archiwum ZIP</string>\n    <string name=\"zip_sub\">Utwórz plik ZIP z podanych plików lub obrazów</string>\n    <string name=\"drag_handle_width\">Przeciągnij szerokość uchwytu</string>\n    <string name=\"explode\">Eksplozja</string>\n    <string name=\"rain\">Deszcz</string>\n    <string name=\"confetti_type\">Typ konfetti</string>\n    <string name=\"festive\">Uroczysty</string>\n    <string name=\"corners\">Narożniki</string>\n    <string name=\"jxl_tools\">Narzędzia JXL</string>\n    <string name=\"jxl_tools_sub\">Transkodowanie JXL ~ JPEG bez utraty jakości lub konwersja animacji GIF/APNG do JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL do JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Bezstratne transkodowanie z formatu JXL do JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Wykonaj bezstratne transkodowanie z JPEG do JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG do JXL</string>\n    <string name=\"select_jxl_image_to_start\">Wybierz obraz JXL, aby rozpocząć</string>\n    <string name=\"auto_paste_sub\">Umożliwia aplikacji automatyczne wklejanie danych ze schowka, dzięki czemu pojawią się one na ekranie głównym i będzie można je przetworzyć</string>\n    <string name=\"pick_multiple_media\">Wybór wielu mediów</string>\n    <string name=\"pick_single_media\">Wybierz pojedyncze medium</string>\n    <string name=\"pick\">Wybierz</string>\n    <string name=\"fast_gaussian_blur_3d\">Szybkie rozmycie Gaussa 3D</string>\n    <string name=\"fast_gaussian_blur_2d\">Szybkie rozmycie Gaussa 2D</string>\n    <string name=\"fast_gaussian_blur_4d\">Szybkie rozmycie Gaussa 4D</string>\n    <string name=\"channels_configuration\">Konfiguracja kanałów</string>\n    <string name=\"header_today\">Dziś</string>\n    <string name=\"header_yesterday\">Wczoraj</string>\n    <string name=\"embedded_picker\">Wbudowany selektor</string>\n    <string name=\"embedded_picker_sub\">Selektor obrazów Image Toolbox</string>\n    <string name=\"no_permissions\">Brak uprawnień</string>\n    <string name=\"request\">Żądanie</string>\n    <string name=\"auto_paste\">Automatyczne wklejanie</string>\n    <string name=\"harmonization_color\">Harmonizacja kolorów</string>\n    <string name=\"harmonization_level\">Harmonizacja poziomów</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"gif_type_to_jxl\">GIF do JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG do JXL</string>\n    <string name=\"jxl_type_to_images\">JXL do obrazów</string>\n    <string name=\"jxl_type_to_images_sub\">Konwersja animacji JXL do partii obrazów</string>\n    <string name=\"apng_type_to_jxl_sub\">Konwersja obrazów APNG do animowanych obrazów JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Konwertuj obrazy GIF na animowane obrazy JXL</string>\n    <string name=\"jxl_type_to_jxl\">Obrazy do JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Konwersja partii zdjęć do animacji JXL</string>\n    <string name=\"behavior\">Zachowanie</string>\n    <string name=\"skip_file_picking\">Pomiń wybieranie plików</string>\n    <string name=\"skip_file_picking_sub\">Selektor plików zostanie wyświetlony natychmiast, jeśli będzie to możliwe na wybranym ekranie</string>\n    <string name=\"generate_previews\">Generowanie podglądów</string>\n    <string name=\"generate_previews_sub\">Włącza generowanie podglądu, co może pomóc uniknąć awarii na niektórych urządzeniach, a także wyłącza niektóre funkcje edycji w ramach opcji pojedynczej edycji</string>\n    <string name=\"lossy_compression\">Kompresja stratna</string>\n    <string name=\"lossy_compression_sub\">Używa kompresji stratnej w celu zmniejszenia rozmiaru pliku zamiast bezstratnej</string>\n    <string name=\"lanczos_bessel_sub\">Metoda ponownego próbkowania, która utrzymuje wysoką jakość interpolacji poprzez zastosowanie funkcji Bessela (jinc) do wartości pikseli</string>\n    <string name=\"compression_type\">Typ kompresji</string>\n    <string name=\"speed_sub\">Kontroluje prędkość dekodowania obrazu wynikowego, powinno to pomóc w szybszym otwieraniu obrazu wynikowego, wartość %1$s oznacza najwolniejsze dekodowanie, podczas gdy %2$s - najszybsze, to ustawienie może zwiększyć rozmiar obrazu wyjściowego</string>\n    <string name=\"sorting\">Sortowanie</string>\n    <string name=\"sort_by_date\">Data</string>\n    <string name=\"sort_by_date_reversed\">Data (odwrotnie)</string>\n    <string name=\"sort_by_name\">Nazwa</string>\n    <string name=\"sort_by_name_reversed\">Nazwa (odwrotnie)</string>\n    <string name=\"try_again\">Spróbuj ponownie</string>\n    <string name=\"show_settings_in_landscape\">Pokaż ustawienia w orientacji poziomej</string>\n    <string name=\"show_settings_in_landscape_sub\">Jeśli ta opcja jest wyłączona, to w trybie poziomym ustawienia będą otwierane na przycisku w górnym pasku aplikacji, jak zawsze, zamiast stałej, widocznej opcji.</string>\n    <string name=\"switch_type\">Rodzaj przełącznika</string>\n    <string name=\"compose\">Skomponuj</string>\n    <string name=\"fullscreen_settings\">Ustawienia trybu pełnoekranowego</string>\n    <string name=\"fullscreen_settings_sub\">Włączenie tej opcji spowoduje, że strona ustawień będzie zawsze otwierana jako pełnoekranowa zamiast wysuwanego arkusza szuflady</string>\n    <string name=\"material_you_switch_sub\">Przełącznik Material You</string>\n    <string name=\"compose_switch_sub\">Przełącznik \\\"Jetpack Compose Material You\\\"</string>\n    <string name=\"max\">Maks.</string>\n    <string name=\"resize_anchor\">Zmiana rozmiaru zakotwiczenia</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">Przełącznik oparty na systemie projektowym „Fluent”</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Przełącznik oparty na systemie projektowym „Cupertino”</string>\n    <string name=\"images_to_svg\">Obrazy do SVG</string>\n    <string name=\"images_to_svg_sub\">Konwertuj obrazy do grafik SVG</string>\n    <string name=\"use_sampled_palette\">Użyj próbkowanej palety</string>\n    <string name=\"use_sampled_palette_sub\">Jeśli ta opcja jest włączona, próbkowana będzie paleta kwantyzacji</string>\n    <string name=\"path_omit\">Pomiń ścieżkę</string>\n    <string name=\"downscale_image\">Obniżanie skali obrazu</string>\n    <string name=\"downscale_image_sub\">Obraz zostanie zmniejszony do niższych wymiarów przed przetworzeniem, co pomoże narzędziu pracować szybciej i bezpieczniej</string>\n    <string name=\"min_color_ratio\">Minimalny współczynnik kolorów</string>\n    <string name=\"lines_threshold\">Próg linii</string>\n    <string name=\"quadratic_threshold\">Próg kwadratowy</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolerancja zaokrąglania współrzędnych</string>\n    <string name=\"path_scale\">Skala ścieżki</string>\n    <string name=\"reset_properties\">Zresetuj właściwości</string>\n    <string name=\"reset_properties_sub\">Wszystkie właściwości zostaną ustawione na wartości domyślne, zauważ, że tej akcji nie można cofnąć</string>\n    <string name=\"detailed\">Szczegółowy</string>\n    <string name=\"svg_warning\">Nie zaleca się używania tego narzędzia do śledzenia dużych obrazów bez skalowania w dół, ponieważ może to spowodować awarię i wydłużyć czas przetwarzania</string>\n    <string name=\"default_line_width\">Domyślna szerokość wiersza</string>\n    <string name=\"engine_mode\">Tryb silnika</string>\n    <string name=\"legacy\">Starszy</string>\n    <string name=\"lstm_network\">Sieć LSTM</string>\n    <string name=\"legacy_and_lstm\">Starszy oraz LSTM</string>\n    <string name=\"convert\">Przekonwertuj</string>\n    <string name=\"convert_sub\">Konwersja partii obrazów do podanego formatu</string>\n    <string name=\"tag_samples_per_pixel\">Próbek na piksel</string>\n    <string name=\"add_new_folder\">Dodaj nowy folder</string>\n    <string name=\"tag_bits_per_sample\">Bitów na próbkę</string>\n    <string name=\"tag_compression\">Kompresja</string>\n    <string name=\"tag_photometric_interpretation\">Interpretacja fotometryczna</string>\n    <string name=\"tag_strip_offsets\">Przesunięcie paska</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Próbkowanie cząstkowe</string>\n    <string name=\"tag_y_cb_cr_positioning\">Pozycjonowanie Y Cb Cr</string>\n    <string name=\"tag_x_resolution\">Rozdzielczość X</string>\n    <string name=\"tag_y_resolution\">Rozdzielczość Y</string>\n    <string name=\"tag_resolution_unit\">Jednostka rozdzielczości</string>\n    <string name=\"tag_transfer_function\">Funkcja przenoszenia</string>\n    <string name=\"tag_white_point\">Biały punkt</string>\n    <string name=\"tag_primary_chromaticities\">Chromatyczność podstawowa</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Współczynniki Y Cb Cr</string>\n    <string name=\"tag_datetime\">Data Czas</string>\n    <string name=\"tag_image_description\">Opis obrazu</string>\n    <string name=\"tag_make\">Utwórz</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Oprogramowanie</string>\n    <string name=\"tag_artist\">Twórca</string>\n    <string name=\"tag_copyright\">Prawa autorskie</string>\n    <string name=\"tag_exif_version\">Wersja Exif</string>\n    <string name=\"tag_flashpix_version\">Wersja Flashpix</string>\n    <string name=\"tag_color_space\">Przestrzeń kolorów</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_rows_per_strip\">Wiersze na pasek</string>\n    <string name=\"tag_strip_byte_counts\">Liczba bajtów paska</string>\n    <string name=\"tag_jpeg_interchange_format\">Format wymiany JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Długość formatu wymiany JPEG</string>\n    <string name=\"tag_reference_black_white\">Referencyjna czerń i biel</string>\n    <string name=\"tag_shutter_speed_value\">Czas otwarcia migawki</string>\n    <string name=\"tag_brightness_value\">Wartość jasności</string>\n    <string name=\"tag_exposure_bias_value\">Wartość odchylenia ekspozycji</string>\n    <string name=\"tag_max_aperture_value\">Maksymalna wartość przysłony</string>\n    <string name=\"tag_aperture_value\">Wartość przysłony</string>\n    <string name=\"tag_flash\">Lampa błyskowa</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Skompresowane bity na piksel</string>\n    <string name=\"tag_maker_note\">Uwaga producenta</string>\n    <string name=\"tag_user_comment\">Komentarz użytkownika</string>\n    <string name=\"tag_related_sound_file\">Powiązany plik dźwiękowy</string>\n    <string name=\"tag_datetime_original\">Data Czas Oryginał</string>\n    <string name=\"tag_datetime_digitized\">Cyfrowa data i godzina</string>\n    <string name=\"tag_offset_time\">Czas przesunięcia</string>\n    <string name=\"tag_offset_time_original\">Czas przesunięcia Oryginał</string>\n    <string name=\"tag_offset_time_digitized\">Cyfrowy czas przesunięcia</string>\n    <string name=\"tag_subsec_time\">Czas sub-sekundowy</string>\n    <string name=\"tag_subsec_time_original\">Czas sub-sekundowy Oryginał</string>\n    <string name=\"tag_exposure_time\">Czas ekspozycji</string>\n    <string name=\"tag_f_number\">Numer F</string>\n    <string name=\"tag_exposure_program\">Program ekspozycji</string>\n    <string name=\"tag_sharpness\">Ostrość</string>\n    <string name=\"tag_camera_owner_name\">Nazwa użytkownika aparatu</string>\n    <string name=\"tag_saturation\">Nasycenie</string>\n    <string name=\"tag_lens_specification\">Specyfikacja obiektywu</string>\n    <string name=\"tag_lens_make\">Producent obiektywu</string>\n    <string name=\"tag_lens_model\">Model obiektywu</string>\n    <string name=\"tag_lens_serial_number\">Numer seryjny obiektywu</string>\n    <string name=\"font_size\">Rozmiar czcionki</string>\n    <string name=\"watermark_size\">Rozmiar znaku wodnego</string>\n    <string name=\"document_scanner\">Skaner dokumentów</string>\n    <string name=\"click_to_start_scanning\">Dotknij, aby zacząć skanować</string>\n    <string name=\"start_scanning\">Rozpocznij skanowanie</string>\n    <string name=\"save_as_pdf\">Zapisz jako PDF</string>\n    <string name=\"share_as_pdf\">Udostępnij jako PDF</string>\n    <string name=\"options_below_is_for_images\">Poniższe opcje dotyczą zapisywania skanów jako obrazów, a nie pliku PDF</string>\n    <string name=\"antialias_sub\">Włącza antyaliasing aby uniknąć ostrych krawędzi</string>\n    <string name=\"document_scanner_sub\">Skanuj dokumenty i utwórz PDF albo zapisz je jako oddzielne zdjęcia</string>\n    <string name=\"color_tools\">Narzędzia koloru</string>\n    <string name=\"color_to_mix\">Kolor do zmieszania</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Zeskanowany kod QR nie jest prawidłowym szablonem filtra</string>\n    <string name=\"scan_qr_code\">Skanuj kod QR</string>\n    <string name=\"scan_qr_code_to_replace_content\">Zeskanuj dowolny kod kreskowy, aby zastąpić zawartość pola, lub wpisz coś, aby wygenerować nowy kod kreskowy z wybranym typem.</string>\n    <string name=\"image_stacking\">Nakładanie obrazów</string>\n    <string name=\"select_webp_image_to_start\">Wybierz pliki WEBP, aby zacząć</string>\n    <string name=\"color_tools_sub\">Sprawdź informacje o kolorze, mieszaj kolory, generuj odcienie koloru</string>\n    <string name=\"color_info\">Informacje o kolorze</string>\n    <string name=\"selected_color\">Wybrany kolor</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Przyznaj uprawnienia dostępu do kamery aby skanować kod QR</string>\n    <string name=\"image_splitting\">Dzielenie obrazu</string>\n    <string name=\"image_splitting_sub\">Potnij obraz na części w pionie lub w poziomie</string>\n    <string name=\"format_conversion\">Konwersja formatów</string>\n    <string name=\"format_conversion_sub\">Zmień format plików</string>\n    <string name=\"noise_generation\">Generator szumu</string>\n    <string name=\"noise_generation_sub\">Generuj różne szumy, np. takie jak Perlin</string>\n    <string name=\"frequency\">Częstotliwość</string>\n    <string name=\"noise_type\">Typ szumu</string>\n    <string name=\"image_stacking_sub\">Układaj obrazy jeden na drugim w wybranym trybie nakładania</string>\n    <string name=\"collage_type\">Typ kolażu</string>\n    <string name=\"collage_maker\">Utwórz kolaż</string>\n    <string name=\"collage_maker_sub\">Twórz kolaże z maksymalnie 20 obrazami</string>\n    <string name=\"gif_type_to_webp_sub\">Konwertuj pliki GIF do animowanych obrazów WEBP</string>\n    <string name=\"webp_tools\">Narzędzia WEBP</string>\n    <string name=\"webp_tools_sub\">Konwertuj obrazy do animowanych plików WEBP albo lub wyodrębnij pojedyncze klatki z animacji WEBP</string>\n    <string name=\"webp_type_to_webp_sub\">Konwertuj serię obrazów do animacji WEBP</string>\n    <string name=\"webp_type_to_image_sub\">Konwertuj animację WEBP do serii obrazów</string>\n    <string name=\"gif_type_to_webp\">GIF do WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP do obrazów</string>\n    <string name=\"webp_type_to_webp\">Obrazy do WEBP</string>\n    <string name=\"qr_code\">Kod QR i kod kreskowy</string>\n    <string name=\"qr_code_sub\">Zeskanuj kod QR i otwórz jego zawartość lub wklej ciąg znaków, aby wygenerować nowy</string>\n    <string name=\"qr_description\">Opis kodu QR</string>\n    <string name=\"image_for_histogram\">Ten obraz zostanie wykorzystany do wygenerowania histogramów RGB i jasności</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">W ustawieniach udziel kamerze uprawnień skanowania dla skanera dokumentów</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"sphinx\">Sfinks</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Ostry Robidoux</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"kaiser\">Kajzer</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"box\">Box</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"gaussian_sub\">Metoda interpolacji wykorzystująca funkcję Gaussa, przydatna do wygładzania i redukcji szumów w obrazach</string>\n    <string name=\"spline16_sub\">Metoda interpolacji oparta na splajnie, która zapewnia gładkie wyniki przy użyciu filtra 16-krotnego</string>\n    <string name=\"spline36_sub\">Metoda interpolacji oparta na splajnie, która zapewnia gładkie wyniki przy użyciu filtra 36-krotnego</string>\n    <string name=\"spline64_sub\">Metoda interpolacji oparta na splajnie, która zapewnia gładkie wyniki przy użyciu filtra 64-krotnego</string>\n    <string name=\"kaiser_sub\">Metoda interpolacji wykorzystująca okno Kajzera, zapewniająca dobrą kontrolę nad kompromisem między szerokością płata głównego a poziomem płata bocznego</string>\n    <string name=\"bartlett_hann_sub\">Hybrydowa funkcja okna łącząca okna Bartletta i Hanna, używana do redukcji wycieków widmowych w przetwarzaniu sygnału</string>\n    <string name=\"box_sub\">Prosta metoda ponownego próbkowania, która wykorzystuje średnią najbliższych wartości pikseli, co często skutkuje blokowym wyglądem</string>\n    <string name=\"lanczos2_sub\">Metoda ponownego próbkowania wykorzystująca 2-płatowy filtr Lanczosa do wysokiej jakości interpolacji z minimalną ilością artefaktów</string>\n    <string name=\"lanczos4_jinc_sub\">Wariant filtru Lanczos 4, który wykorzystuje funkcję jinc, zapewniając wysokiej jakości interpolację z minimalnymi artefaktami</string>\n    <string name=\"haasn_soft\">Delikatny Haasn</string>\n    <string name=\"haasn_soft_sub\">Filtr resamplingu zaprojektowany przez Haasn do płynnego i pozbawionego artefaktów skalowania obrazu</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"backup_ocr_models\">Zapasowe modele OCR</string>\n    <string name=\"import_word\">Importuj</string>\n    <string name=\"export\">Eksportuj</string>\n    <string name=\"top_right\">U góry po prawej</string>\n    <string name=\"bottom_left\">Na dole po lewej</string>\n    <string name=\"bottom_right\">Na dole po prawej</string>\n    <string name=\"top_center\">U góry pośrodku</string>\n    <string name=\"center_right\">W środku po prawej</string>\n    <string name=\"bottom_center\">Pośrodku na dole</string>\n    <string name=\"center_left\">W środku po lewej</string>\n    <string name=\"clustered_4x4_dithering\">Dithering klastrowy 4x4</string>\n    <string name=\"clustered_8x8_dithering\">Dithering klastrowy 8x8</string>\n    <string name=\"yililoma_dithering\">Dithering Yililoma</string>\n    <string name=\"tones\">Tony</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Nie można używać monet, gdy włączone są dynamiczne kolory</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"edge_mode\">Tryb krawędziowy</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"group\">Grupa</string>\n    <string name=\"cubic\">Sześcienny</string>\n    <string name=\"hanning_sub\">Wariant okna Hanna, powszechnie stosowany do redukcji wycieków widmowych w aplikacjach przetwarzania sygnału</string>\n    <string name=\"lanczos3_sub\">Metoda ponownego próbkowania wykorzystująca 3-płatowy filtr Lanczosa do wysokiej jakości interpolacji z minimalnymi artefaktami</string>\n    <string name=\"lanczos2_jinc_sub\">Wariant filtra Lanczos 2, który wykorzystuje funkcję jinc, zapewniając wysokiej jakości interpolację z minimalnymi artefaktami</string>\n    <string name=\"lanczos3_jinc_sub\">Wariant filtru Lanczos 3, który wykorzystuje funkcję jinc, zapewniając wysokiej jakości interpolację z minimalnymi artefaktami.</string>\n    <string name=\"auto_crop\">Automatyczne kadrowanie</string>\n    <string name=\"triangle\">Trójkąt</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">Opcje powinny być wprowadzane zgodnie z tym wzorem: „--{nazwa_opcji} {wartość}\\</string>\n    <string name=\"clustered_2x2_dithering\">Dithering klastrowy 2x2</string>\n    <string name=\"links_preview_sub\">Umożliwia pobieranie podglądu linków w miejscach, w których można uzyskać tekst (QRCode, OCR itp.).</string>\n    <string name=\"tag_exposure_index\">Wskaźnik ekspozycji</string>\n    <string name=\"outlined_polygon_sub\">Rysuje obrysowany wielokąt od punktu początkowego do punktu końcowego</string>\n    <string name=\"template_name\">Nazwa szablonu</string>\n    <string name=\"min\">Min</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"crop_to_content\">Przytnij do zawartości</string>\n    <string name=\"as_file\">Jako plik</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lagrange_3_sub\">Filtr interpolacyjny Lagrange\\'a rzędu 3, oferujący lepszą dokładność i gładsze wyniki skalowania obrazu</string>\n    <string name=\"tag_planar_configuration\">Konfiguracja płaszczyznowa</string>\n    <string name=\"repeat_text_sub\">Bieżący tekst będzie powtarzany do końca ścieżki zamiast jednorazowego rysowania</string>\n    <string name=\"draw_regular_polygon\">Narysuj wielokąt foremny</string>\n    <string name=\"draw_text_sub\">Narysuj tekst na ścieżce z podaną czcionką i kolorem</string>\n    <string name=\"create_template\">Utwórz szablon</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Wariant eliptycznej średniej ważonej (EWA) filtra Lanczos 3 Jinc do wysokiej jakości resamplingu z redukcją aliasingu</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Filtr resamplingu przeznaczony do wysokiej jakości przetwarzania obrazu z dobrą równowagą ostrości i gładkości</string>\n    <string name=\"outlined_star\">Nakreślona gwiazda</string>\n    <string name=\"variation\">Wariacja</string>\n    <string name=\"vertices\">Wierzchołki</string>\n    <string name=\"ewa_ginseng_sub\">Eliptyczna średnia ważona (EWA) - wariant filtra Ginseng poprawiający jakość obrazu</string>\n    <string name=\"harmony_square\">Kwadrat</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Dołącz do naszego czatu, gdzie możesz omówić wszystko, co chcesz, a także zajrzyj na kanał CI, gdzie publikuję bety i ogłoszenia</string>\n    <string name=\"delete_template\">Usuń szablon</string>\n    <string name=\"lanczos_6_sub\">Filtr ponownego próbkowania Lanczos o wyższym rzędzie 6, zapewniający ostrzejsze i dokładniejsze skalowanie obrazu</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"frame_color\">Kolor obramowania</string>\n    <string name=\"outlined_polygon\">Nakreślony wielokąt</string>\n    <string name=\"outlined_star_sub\">Rysuje nakreśloną gwiazdę od punktu początkowego do punktu końcowego</string>\n    <string name=\"harmony_complementary\">Uzupełniający</string>\n    <string name=\"tag_cfa_pattern\">Wzorzec CFA</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"repeat_text\">Powtórz tekst</string>\n    <string name=\"dash_size\">Rozmiar kreski</string>\n    <string name=\"collages_info\">Przytrzymaj obraz, aby go zamienić, przesuń i powiększ, aby dostosować pozycję</string>\n    <string name=\"tag_flash_energy\">Moc lampy błyskowej</string>\n    <string name=\"deuteranopia_sub\">Niezdolność do postrzegania odcieni zieleni</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"image_toolbox_in_telegram\">Image Toolbox na Telegramie 🎉</string>\n    <string name=\"custom_options\">Opcje użytkownika</string>\n    <string name=\"protanopia_sub\">Niezdolność do postrzegania odcieni czerwieni</string>\n    <string name=\"coffee\">Kawa</string>\n    <string name=\"draw_image_sub\">Obraz ten zostanie użyty jako powtarzający się wpis narysowanej ścieżki</string>\n    <string name=\"draw_regular_polygon_sub\">Narysuj wielokąt, który będzie regularny zamiast dowolnego kształtu</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Wyrównanie histogramu Adaptive LAB</string>\n    <string name=\"quadric_sub\">Metoda wykorzystująca funkcję kwadratową do interpolacji, zapewniająca płynne i ciągłe wyniki</string>\n    <string name=\"select_template_preview\">Ten obraz będzie używany do podglądu tego szablonu filtra</string>\n    <string name=\"harmony_triadic\">Triadyczny</string>\n    <string name=\"added_filter_template\">Dodano szablon filtra o nazwie „%1$s” (%2$s)</string>\n    <string name=\"code_content\">Treść kodu</string>\n    <string name=\"quadric\">Kwadryczny</string>\n    <string name=\"gaussian\">Gaussowski</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"bspline_sub\">Wykorzystuje zdefiniowane fragmentarycznie funkcje wielomianowe do płynnej interpolacji i aproksymacji krzywej lub powierzchni, elastycznej i ciągłej reprezentacji kształtu</string>\n    <string name=\"robidoux_sharp_sub\">Ostrzejszy wariant metody Robidoux, zoptymalizowany pod kątem wyraźnej zmiany rozmiaru obrazu</string>\n    <string name=\"bohman_sub\">Funkcja okna używana do redukcji wycieków widmowych, zapewniająca dobrą rozdzielczość częstotliwości w aplikacjach przetwarzania sygnału</string>\n    <string name=\"ewa_hanning_sub\">Wariant eliptycznej średniej ważonej (EWA) filtra Hanninga do płynnej interpolacji i ponownego próbkowania</string>\n    <string name=\"ewa_robidoux_sharp\">Ostry Robidoux EWA</string>\n    <string name=\"ewa_quadric_sub\">Eliptyczna średnia ważona (EWA) - wariant filtru Quadric do płynnej interpolacji</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Eliptyczna średnia ważona (EWA) - wariant filtra Ostry Lanczos zapewniający ostre rezultaty przy minimalnej ilości artefaktów</string>\n    <string name=\"blackman_sub\">Funkcja okna, która zapewnia dobrą rozdzielczość częstotliwości poprzez minimalizację wycieku widmowego, często używana w przetwarzaniu sygnału</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Wyrównaj histogram Adaptacyjny HSL</string>\n    <string name=\"not_use_color_blind_scheme\">Nie używaj schematu Color Blind</string>\n    <string name=\"enhanced_oil\">Ulepszony olej</string>\n    <string name=\"palette_transfer\">Przeniesienie palety</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"color_harmonies\">Harmonie kolorów</string>\n    <string name=\"harmony_analogous_complementary\">Analogiczny + Uzupełniający</string>\n    <string name=\"color_shading\">Cieniowanie kolorów</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"fractal_type\">Rodzaj fraktala</string>\n    <string name=\"draw_regular_star\">Narysuj zwykłą gwiazdę</string>\n    <string name=\"draw_regular_star_sub\">Narysuj gwiazdę, która będzie regularna, a nie dowolna</string>\n    <string name=\"links_preview\">Podgląd linków</string>\n    <string name=\"achromatomaly_sub\">Zmniejszona wrażliwość na wszystkie kolory</string>\n    <string name=\"tag_focal_length\">Ogniskowa</string>\n    <string name=\"create_new\">Utwórz nowy</string>\n    <string name=\"coerce_points_to_image_bounds\">Wymuszanie punktów do granic obrazu</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"bins_count\">Liczba pojemników</string>\n    <string name=\"tag_subject_location\">Lokalizacja obiektu</string>\n    <string name=\"tag_sensing_method\">Metoda pomiaru</string>\n    <string name=\"tag_file_source\">Źródło pliku</string>\n    <string name=\"tag_custom_rendered\">Niestandardowo zrenderowano</string>\n    <string name=\"tag_exposure_mode\">Tryb ekspozycji</string>\n    <string name=\"tag_white_balance\">Balans bieli</string>\n    <string name=\"draw_mode_image_sub\">Użyj wybranego obrazu, aby narysować go wzdłuż danej ścieżki</string>\n    <string name=\"outlined_triangle_sub\">Rysuje trójkąt od punktu początkowego do końcowego</string>\n    <string name=\"triangle_sub\">Rysuje trójkąt od punktu początkowego do końcowego</string>\n    <string name=\"outlined_triangle\">Nakreślony trójkąt</string>\n    <string name=\"polygon_sub\">Rysuje wielokąt od punktu początkowego do punktu końcowego</string>\n    <string name=\"polygon\">Wielokąt</string>\n    <string name=\"star_sub\">Rysuje gwiazdę od punktu początkowego do końcowego</string>\n    <string name=\"star\">Gwiazda</string>\n    <string name=\"inner_radius_ratio\">Współczynnik promienia wewnętrznego</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"color_to_ignore\">Kolor do pominięcia</string>\n    <string name=\"template\">Szablon</string>\n    <string name=\"no_template_filters\">Nie dodano szablonu filtrów</string>\n    <string name=\"opened_file_have_no_filter_template\">Wybrany plik nie zawiera danych szablonu filtra</string>\n    <string name=\"template_filter\">Filtr szablonu</string>\n    <string name=\"as_qr_code\">Jako obraz kodu QR</string>\n    <string name=\"save_as_file\">Zapisz jako plik</string>\n    <string name=\"save_as_qr_code_image\">Zapisz jako obraz kodu QR</string>\n    <string name=\"filter_preview\">Podgląd filtra</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"hamming_sub\">Funkcja okna używana do redukcji wycieków widmowych poprzez zwężanie krawędzi sygnału, przydatna w przetwarzaniu sygnału</string>\n    <string name=\"sphinx_sub\">Zaawansowana metoda ponownego próbkowania zapewniająca wysokiej jakości interpolację z minimalną ilością artefaktów</string>\n    <string name=\"bartlett_sub\">Trójkątna funkcja okna używana w przetwarzaniu sygnału w celu zmniejszenia wycieku widmowego</string>\n    <string name=\"robidoux_sub\">Wysokiej jakości metoda interpolacji zoptymalizowana pod kątem naturalnej zmiany rozmiaru obrazu, równoważąca ostrość i gładkość</string>\n    <string name=\"lanczos4_sub\">Metoda ponownego próbkowania, która wykorzystuje 4-płatowy filtr Lanczosa do wysokiej jakości interpolacji z minimalnymi artefaktami</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_blackman_sub\">Eliptyczna średnia ważona (EWA) - wariant filtra Blackmana minimalizujący artefakty dzwonienia</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Eliptyczna średnia ważona (EWA) - wariant filtru Ostry Robidoux zapewniający ostrzejsze rezultaty</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_lanczos_sharp\">Ostry Lanczos EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Najostrzejszy Lanczos 4 EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Wariant eliptycznej średniej ważonej (EWA) filtru Najostrzejszy Lanczos 4 do wyjątkowo ostrego resamplingu obrazu</string>\n    <string name=\"ewa_lanczos_soft\">Delikatny Lanczos EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Wariant eliptycznej średniej ważonej (EWA) filtru Delikatny Lanczos do wygładzania obrazów</string>\n    <string name=\"dismiss_forever\">Odrzuć na zawsze</string>\n    <string name=\"add_image\">Dodaj obraz</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Wyrównaj histogram Adaptacyjny HSV</string>\n    <string name=\"color_blind_scheme_sub\">Wybierz tryb, aby dostosować kolory motywu do wybranego wariantu ślepoty barw</string>\n    <string name=\"protanomaly_sub\">Trudności w rozróżnianiu odcieni czerwieni i zieleni</string>\n    <string name=\"deuteranomaly_sub\">Trudności w rozróżnianiu odcieni zieleni i czerwieni</string>\n    <string name=\"color_poster\">Kolorowy plakat</string>\n    <string name=\"tri_tone\">Trójtonowy</string>\n    <string name=\"third_color\">Trzeci kolor</string>\n    <string name=\"no_favorite_options_selected\">Nie wybrano żadnych ulubionych opcji, dodaj je na stronie narzędzi</string>\n    <string name=\"add_favorites\">Dodaj do ulubionych</string>\n    <string name=\"shades\">Odcienie</string>\n    <string name=\"tints\">Barwy</string>\n    <string name=\"color_mixing\">Łączenie kolorów</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"golden_forest\">Złoty las</string>\n    <string name=\"greenish\">Zielonkawy</string>\n    <string name=\"retro_yellow\">Retro żółty</string>\n    <string name=\"links\">Linki</string>\n    <string name=\"ico_size_warning\">Pliki ICO można zapisywać tylko w maksymalnym rozmiarze 256 x 256</string>\n    <string name=\"recently_used\">Ostatnio używane</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"show_all\">Pokaż wszystko</string>\n    <string name=\"rotation_type\">Typ obrotu</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"alignment\">Wyrównanie</string>\n    <string name=\"custom_filename\">Własna nazwa pliku</string>\n    <string name=\"saved_to_custom\">Zapisane w folderze o niestandardowej nazwie</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">Histogram obrazu RGB lub jasności ułatwiający dokonywanie regulacji</string>\n    <string name=\"tesseract_options\">Opcje Tesseract</string>\n    <string name=\"free_corners\">Wolne rogi</string>\n    <string name=\"mask\">Maska</string>\n    <string name=\"soft_glow\">Delikatny blask</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"hide_status_bar\">Ukryj pasek stanu</string>\n    <string name=\"gain\">Wzmocnij</string>\n    <string name=\"ping_pong_strength\">Wytrzymałość ping ponga</string>\n    <string name=\"ci_channel\">Kanał Cl</string>\n    <string name=\"ci_channel_sub\">Otrzymuj powiadomienia o nowych wersjach aplikacji i czytaj ogłoszenia</string>\n    <string name=\"octaves\">Oktawy</string>\n    <string name=\"lacunarity\">Lakunarność</string>\n    <string name=\"tesseract_options_sub\">Zastosuj niektóre zmienne wejściowe dla silnika tesseract</string>\n    <string name=\"hide_all\">Ukryj wszystko</string>\n    <string name=\"spot_heal_sub\">Wypełnienie z uwzględnieniem zawartości pod narysowaną ścieżką</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Punkty nie będą ograniczone granicami obrazu, co jest przydatne do bardziej precyzyjnego korygowania perspektywy</string>\n    <string name=\"position\">Pozycja</string>\n    <string name=\"ewa_robidoux_sub\">Eliptyczna średnia ważona (EWA) - wariant filtra Robidoux do wysokiej jakości ponownego próbkowania</string>\n    <string name=\"cubic_sub\">Interpolacja sześcienna zapewnia płynniejsze skalowanie, biorąc pod uwagę najbliższe 16 pikseli, dając lepsze wyniki niż interpolacja dwuliniowa</string>\n    <string name=\"target_image\">Obraz docelowy</string>\n    <string name=\"harmony_split_complementary\">Podział uzupełniający</string>\n    <string name=\"harmony_tetradic\">Tetradyczny</string>\n    <string name=\"delete_template_warn\">Zamierzasz usunąć wybrany filtr szablonu. Tej operacji nie można cofnąć</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"welch_sub\">Funkcja okna zaprojektowana w celu zapewnienia dobrej rozdzielczości częstotliwości przy zmniejszonym wycieku widmowym, często używana w aplikacjach przetwarzania sygnału</string>\n    <string name=\"lagrange_2_sub\">Filtr interpolacyjny Lagrange\\'a rzędu 2, odpowiedni do wysokiej jakości skalowania obrazu z płynnymi przejściami</string>\n    <string name=\"simple_sketch\">Prosty szkic</string>\n    <string name=\"tritanopia_sub\">Niezdolność do postrzegania niebieskich odcieni</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Kolory będą dokładnie takie, jak ustawiono w motywie</string>\n    <string name=\"tritanomaly_sub\">Trudności w rozróżnianiu odcieni niebieskiego i żółtego</string>\n    <string name=\"achromatopsia_sub\">Całkowita ślepota barw, widzenie tylko odcieniach szarości</string>\n    <string name=\"lanczos_6_jinc_sub\">Wariant filtru Lanczos 6 wykorzystujący funkcję Jinc w celu poprawy jakości resamplingu obrazu</string>\n    <string name=\"simple_old_tv\">Prosty stary telewizor</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"top_left\">U góry po lewej</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"harmony_analogous\">Analogiczny</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"center\">Pośrodku</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"free_corners_sub\">Kadrowanie obrazu według wielokąta, koryguje również perspektywę</string>\n    <string name=\"custom_filename_sub\">Wybierz lokalizację i nazwę pliku, które zostaną użyte do zapisania bieżącego obrazu</string>\n    <string name=\"fit_description\">Dopasuj obraz do podanych wymiarów i zastosowanie rozmycia lub koloru tła</string>\n    <string name=\"hide_nav_bar\">Ukryj pasek nawigacji</string>\n    <string name=\"weighted_strength\">Wytrzymałość ważona</string>\n    <string name=\"tag_gps_track\">Ślad GPS</string>\n    <string name=\"pick_file_to_checksum\">Wybierz plik, aby obliczyć jego sumę kontrolną na podstawie wybranego algorytmu</string>\n    <string name=\"enter_text_to_checksum\">Wprowadź tekst, aby obliczyć jego sumę kontrolną na podstawie wybranego algorytmu</string>\n    <string name=\"source_checksum\">Źródłowa suma kontrolna</string>\n    <string name=\"checksum_to_compare\">Suma kontrolna do porównania</string>\n    <string name=\"match\">Zgadza się!</string>\n    <string name=\"difference\">Różnica</string>\n    <string name=\"difference_sub\">Sumy kontrolne nie są równe, plik może być niebezpieczny!</string>\n    <string name=\"match_sub\">Sumy kontrolne są równe, plik jest bezpieczny</string>\n    <string name=\"mesh_gradients\">Gradienty siatki</string>\n    <string name=\"algorithms\">Algorytm</string>\n    <string name=\"checksum_tools_sub\">Porównywanie sum kontrolnych, obliczanie skrótów, tworzenie ciągów szesnastkowych z plików przy użyciu różnych algorytmów haszujących</string>\n    <string name=\"tag_gps_img_direction\">Kierunek GPS Img</string>\n    <string name=\"tag_gps_altitude_ref\">Odniesienie do wysokości GPS</string>\n    <string name=\"tag_spatial_frequency_response\">Przestrzenna charakterystyka częstotliwościowa</string>\n    <string name=\"tag_spectral_sensitivity\">Czułość widmowa</string>\n    <string name=\"tag_gps_altitude\">Wysokość GPS</string>\n    <string name=\"tag_gps_satellites\">Satelity GPS</string>\n    <string name=\"tag_gps_status\">Stan GPS</string>\n    <string name=\"tag_gps_measure_mode\">Tryb pomiaru GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Odniesienie do prędkości GPS</string>\n    <string name=\"tag_gps_speed\">Prędkość GPS</string>\n    <string name=\"tag_gps_track_ref\">Odniesienie do śladu GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Odniesienie do kierunku GPS Img</string>\n    <string name=\"tag_gps_map_datum\">Data mapy GPS</string>\n    <string name=\"tag_gps_longitude\">Długość geograficzna GPS</string>\n    <string name=\"checksum_tools\">Narzędzie sum kontrolnych</string>\n    <string name=\"calculate\">Przelicz</string>\n    <string name=\"collection_mesh_gradients_sub\">Zobacz kolekcję gradientów siatki online</string>\n    <string name=\"checksum\">Suma kontrolna</string>\n    <string name=\"tag_gps_timestamp\">Znacznik czasu GPS</string>\n    <string name=\"tag_pixel_x_dimension\">Wymiar piksel X</string>\n    <string name=\"tag_pixel_y_dimension\">Wymiar piksel Y</string>\n    <string name=\"tag_subsec_time_digitized\">Digitalizowany czas podsekundowy</string>\n    <string name=\"tag_photographic_sensitivity\">Czułość fotograficzna</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"gaussian_box_blur\">Gaussowskie rozmycie pudełkowe</string>\n    <string name=\"pick_filter_info\">Wybierz poniższy filtr, aby użyć go jako pędzla na rysunku</string>\n    <string name=\"sand_painting\">Malowanie piaskiem</string>\n    <string name=\"languages_imported\">Języki zaimportowane pomyślnie</string>\n    <string name=\"palette_transfer_variant\">Wariant Transferu palety</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Docelowy plik 3D LUT (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"fall_colors\">Kolory jesieni</string>\n    <string name=\"film_stock_50\">Materiał filmowy 50</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Uzyskaj neutralny obraz LUT</string>\n    <string name=\"pop_art\">Sztuka pop</string>\n    <string name=\"text_hash\">Skrót tekstowy</string>\n    <string name=\"tag_focal_plane_x_resolution\">Rozdzielczość X płaszczyzny ogniskowej</string>\n    <string name=\"black_hat\">Czarny kapelusz</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Po wybraniu obrazu do otwarcia (podglądu) w ImageToolbox, zamiast podglądu zostanie otwarty arkusz wyboru edycji</string>\n    <string name=\"tag_subject_area\">Obszar przedmiotu</string>\n    <string name=\"tag_subject_distance\">Odległość przedmiotu</string>\n    <string name=\"tag_metering_mode\">Tryb pomiaru</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Jednostka rozdzielczości płaszczyzny ogniskowej</string>\n    <string name=\"tag_scene_capture_type\">Rodzaj przechwytywania sceny</string>\n    <string name=\"mirror_101\">Lustro 101</string>\n    <string name=\"tag_gps_dest_longitude\">Docelowa długość geograficzna GPS</string>\n    <string name=\"tag_gps_dest_distance\">Docelowa odległość GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Odniesienie do docelowej odległości GPS</string>\n    <string name=\"tag_gps_processing_method\">Metoda przetwarzania GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Namiar GPS</string>\n    <string name=\"linear_fast_gaussian_blur\">Szybkie liniowe rozmycie gaussowskie</string>\n    <string name=\"draw_filter_sub\">Wybierz jeden filtr, aby użyć go jako farby</string>\n    <string name=\"tiff_compression_scheme\">Schemat kompresji TIFF</string>\n    <string name=\"tag_rw2_sensor_right_border\">Prawe obramowanie czujnika</string>\n    <string name=\"tag_rw2_sensor_top_border\">Górne obramowanie czujnika</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Wyrównaj histogram Adaptacyjny LUV</string>\n    <string name=\"default_draw_color\">Domyślny kolor rysowania</string>\n    <string name=\"show_system_bars_by_swipe\">Pokaż paski systemowe poprzez przesunięcie</string>\n    <string name=\"tone_curves\">Krzywe tonalne</string>\n    <string name=\"gap_size\">Rozmiar szczeliny</string>\n    <string name=\"create_shortcut_subtitle\">Narzędzie zostanie dodane do ekranu głównego programu uruchamiającego jako skrót, użyj go w połączeniu z ustawieniem „Pomiń wybieranie plików”, aby osiągnąć pożądane zachowanie</string>\n    <string name=\"crossfade_sub\">Ramki będą przechodzić jedna w drugą</string>\n    <string name=\"stamped\">Stemplowany</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Umożliwia przesuwanie w celu wyświetlenia pasków systemowych, jeśli są ukryte</string>\n    <string name=\"crossfade_count\">Liczba klatek przejścia</string>\n    <string name=\"compact_selectors\">Selektory kompaktowe</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"paste_base_64\">Wklej Base64</string>\n    <string name=\"show\">Pokaż</string>\n    <string name=\"apply\">Zastosuj</string>\n    <string name=\"open_source_licenses\">Licencje na oprogramowanie napisane otwarty kodem źródłowym</string>\n    <string name=\"layers_on_background\">Warstwy na tle</string>\n    <string name=\"base_64_actions\">Działania Base64</string>\n    <string name=\"open_source_licenses_sub\">Wyświetl licencje bibliotek napisanych otwartym kodem źródłowym używanych w tej aplikacji</string>\n    <string name=\"markup_layers_sub\">Tryb warstw z możliwością dowolnego umieszczania obrazów, tekstu i innych elementów</string>\n    <string name=\"add_outline\">Dodaj obrys</string>\n    <string name=\"outline_size\">Rozmiar obrysu</string>\n    <string name=\"outline_color\">Kolor obrysu</string>\n    <string name=\"rotation\">Rotacja</string>\n    <string name=\"free_software_partner\">Wolne oprogramowanie (Partner)</string>\n    <string name=\"free_software_partner_sub\">Więcej przydatnego oprogramowania w kanale partnerskim aplikacji na Androida</string>\n    <string name=\"zigzag_ratio\">Współczynnik zygzaka</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Odniesienie do docelowej długości geograficznej GPS</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Prędkość ISO Szerokość geograficzna yyy</string>\n    <string name=\"crossfade\">Przejście</string>\n    <string name=\"main_screen_title\">Tytuł ekranu głównego</string>\n    <string name=\"tag_default_crop_size\">Domyślny rozmiar kadrowania</string>\n    <string name=\"lut_library_sub\">Pobierz kolekcję LUT, które możesz zastosować po pobraniu</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Odniesienie do docelowej szerokości geograficznej GPS</string>\n    <string name=\"cell_width\">Szerokość komórki</string>\n    <string name=\"line_style\">Styl linii</string>\n    <string name=\"tag_orf_aspect_frame\">Aspekt Ramki</string>\n    <string name=\"group_tools_by_type_sub\">Grupuje narzędzia na ekranie głównym według ich typu zamiast niestandardowego układu listy</string>\n    <string name=\"fancy_sub\">Elegancki suwak. Jest to opcja domyślna</string>\n    <string name=\"threshold_two\">Próg drugi</string>\n    <string name=\"opening\">Otwieranie</string>\n    <string name=\"equalize_histogram_pixelation\">Wyrównaj pikselację histogramu</string>\n    <string name=\"not_a_valid_base_64\">Podana wartość nie jest prawidłowym ciągiem Base64</string>\n    <string name=\"area\">Obszar</string>\n    <string name=\"enable_tonemapping\">Włącz mapowanie tonów</string>\n    <string name=\"save_base_64\">Zapisz Base64</string>\n    <string name=\"share_base_64\">Udostępnij Base64</string>\n    <string name=\"options\">Opcje</string>\n    <string name=\"actions\">Działania</string>\n    <string name=\"import_base_64\">Zaimportuj Base64</string>\n    <string name=\"tag_sensitivity_type\">Rodzaj czułości</string>\n    <string name=\"tag_standard_output_sensitivity\">Standardowa czułość wyjścia</string>\n    <string name=\"tag_recommended_exposure_index\">Zalecany wskaźnik ekspozycji</string>\n    <string name=\"tag_iso_speed\">Prędkość ISO</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Prędkość ISO Szerokość geograficzna zzz</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Ogniskowa filmu 35 mm</string>\n    <string name=\"tag_device_setting_description\">Opis ustawień urządzenia</string>\n    <string name=\"tag_subject_distance_range\">Zakres odległości przedmiotu</string>\n    <string name=\"tag_image_unique_id\">Unikalny identyfikator obrazu</string>\n    <string name=\"tag_body_serial_number\">Numer seryjny korpusu</string>\n    <string name=\"tag_gps_version_id\">Identyfikator wersji GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Odniesienie do szerokości geograficznej GPS</string>\n    <string name=\"tag_gps_latitude\">Szerokość geograficzna GPS</string>\n    <string name=\"tag_gps_longitude_ref\">Odniesienie do długości geograficznej GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Docelowa szerokość geograficzna GPS</string>\n    <string name=\"tag_gps_datestamp\">Znacznik daty GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Błąd pozycjonowania GPS H</string>\n    <string name=\"tag_interoperability_index\">Współczynnik interoperacyjności</string>\n    <string name=\"tag_dng_version\">Wersja DNG</string>\n    <string name=\"tag_orf_preview_image_start\">Początek podglądu obrazu</string>\n    <string name=\"tag_orf_preview_image_length\">Długość podglądu obrazu</string>\n    <string name=\"tag_rw2_sensor_left_border\">Lewe obramowanie czujnika</string>\n    <string name=\"antialias\">Antyaliasy</string>\n    <string name=\"open_edit_instead_of_preview\">Otwórz edycję zamiast podglądu</string>\n    <string name=\"equalize_histogram_hsv\">Wyrównaj histogram HSV</string>\n    <string name=\"clip\">Zaczep</string>\n    <string name=\"wrap\">Zwiń</string>\n    <string name=\"color_blind_scheme\">Ślepota barw</string>\n    <string name=\"sigmoidal\">Sygmoidalny</string>\n    <string name=\"linear_box_blur\">Rozmycie liniowe (pudło)</string>\n    <string name=\"replace_filter\">Wymień filtr</string>\n    <string name=\"target_lut_image\">Docelowy obraz LUT</string>\n    <string name=\"soft_elegance\">Delikatna elegancja</string>\n    <string name=\"soft_elegance_variant\">Wariant Delikatnej elegancji</string>\n    <string name=\"bleach_bypass\">Pomijanie wybielacza</string>\n    <string name=\"candlelight\">Światło świecy</string>\n    <string name=\"drop_blues\">Kropla Bluesa</string>\n    <string name=\"edgy_amber\">Elegancki bursztyn</string>\n    <string name=\"manage_storage_extra_types\">Brak pełnego dostępu do plików</string>\n    <string name=\"tools_arrangement\">Rozmieszczenie narzędzi</string>\n    <string name=\"group_tools_by_type\">Grupuj narzędzia według typu</string>\n    <string name=\"domain_warp\">Osnowa domeny</string>\n    <string name=\"spot_heal\">Leczenie punktowe</string>\n    <string name=\"use_circle_kernel\">Użyj jądra okręgu</string>\n    <string name=\"closing\">Zamykanie</string>\n    <string name=\"morphological_gradient\">Gradient morfologiczny</string>\n    <string name=\"reset_curves\">Zresetuj krzywe</string>\n    <string name=\"reset_curves_sub\">Krzywe zostaną przywrócone do wartości domyślnej</string>\n    <string name=\"stamped_sub\">Rysuje wybrane kształty wzdłuż ścieżki z określonymi odstępami</string>\n    <string name=\"zigzag_sub\">Rysuje falisty zygzak wzdłuż ścieżki</string>\n    <string name=\"laplacian_simple\">Prosty Laplacian</string>\n    <string name=\"sobel_simple\">Prosty Sobel</string>\n    <string name=\"helper_grid\">Siatka pomocnicza</string>\n    <string name=\"helper_grid_sub\">Pokazuje siatkę pomocniczą nad obszarem rysowania, aby pomóc w precyzyjnych manipulacjach</string>\n    <string name=\"grid_color\">Kolor siatki</string>\n    <string name=\"cell_height\">Wysokość komórki</string>\n    <string name=\"layout\">Układ</string>\n    <string name=\"constant_rate_factor\">Współczynnik stałej szybkości (CRF)</string>\n    <string name=\"lut_library\">Biblioteka Lut</string>\n    <string name=\"filter_preview_image_sub\">Zmiana domyślnego podglądu obrazu dla filtrów</string>\n    <string name=\"filter_preview_image\">Podgląd obrazu</string>\n    <string name=\"hide\">Ukryj</string>\n    <string name=\"slider_type\">Typ suwaka</string>\n    <string name=\"fancy\">Zmyślny</string>\n    <string name=\"material_you_slider_sub\">Suwak oparty na Material You</string>\n    <string name=\"enter_percent\">Wprowadź %</string>\n    <string name=\"edit_layer\">Edytuj warstwę</string>\n    <string name=\"layers_on_image\">Warstwy na obrazie</string>\n    <string name=\"layers_on_background_sub\">To samo, co pierwsza opcja, ale z kolorem zamiast obrazu</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Strona szybkich ustawień</string>\n    <string name=\"fast_settings_side_sub\">Dodaj pływający pasek po wybranej stronie podczas edycji obrazów, który po kliknięciu otworzy szybkie ustawienia</string>\n    <string name=\"clear_selection\">Wyczyść zaznaczenie</string>\n    <string name=\"settings_group_visibility_hidden\">Grupa ustawień „%1$s” będzie domyślnie zwinięta</string>\n    <string name=\"settings_group_visibility_visible\">Grupa ustawień „%1$s” będzie domyślnie rozwinięta</string>\n    <string name=\"base_64_tools\">Narzędzia Base64</string>\n    <string name=\"base_64_tools_sub\">Dekodowanie ciągu Base64 na obraz lub kodowanie obrazu do formatu Base64</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">Nie można skopiować pustego lub nieprawidłowego ciągu Base64</string>\n    <string name=\"copy_base_64\">Skopiuj Base64</string>\n    <string name=\"base_64_tips\">Załaduj obraz, aby skopiować lub zapisać ciąg Base64. Jeśli masz sam ciąg znaków, możesz wkleić go powyżej, aby uzyskać obraz</string>\n    <string name=\"checksum_as_filename\">Suma kontrolna jako nazwa pliku</string>\n    <string name=\"checksum_as_filename_sub\">Obrazy wyjściowe będą miały nazwę odpowiadającą ich sumie kontrolnej danych</string>\n    <string name=\"grid_size_x\">Rozmiar siatki X</string>\n    <string name=\"grid_size_y\">Rozmiar siatki Y</string>\n    <string name=\"equalize_histogram_adaptive\">Wyrównaj histogram adaptacyjnie</string>\n    <string name=\"distance_function\">Funkcja odległości</string>\n    <string name=\"return_type\">Typ powrotu</string>\n    <string name=\"linear_tent_blur\">Rozmycie liniowe (namiot)</string>\n    <string name=\"tag_focal_plane_y_resolution\">Rozdzielczość Y płaszczyzny ogniskowej</string>\n    <string name=\"tag_gain_control\">Kontrola wzmocnienia</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Punkt odniesienia namiaru GPS</string>\n    <string name=\"tag_digital_zoom_ratio\">Współczynnik powiększenia cyfrowego</string>\n    <string name=\"allow_enter_by_text_field\">Zezwalaj na wprowadzanie poprzez pole tekstowe</string>\n    <string name=\"threshold_one\">Próg pierwszy</string>\n    <string name=\"tag_gps_differential\">Odchylenie GPS</string>\n    <string name=\"scale_color_space\">Skalowanie przestrzeni kolorów</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"enter_percentage\">Wprowadź wartość procentową</string>\n    <string name=\"dashed\">Kreskowany</string>\n    <string name=\"tag_gps_area_information\">Informacje o obszarze GPS</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Liniowe szybkie rozmycie gaussowskie kolejne</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Dolne obramowanie czujnika</string>\n    <string name=\"linear\">Liniowe</string>\n    <string name=\"linear_gaussian_box_blur\">Rozmycie liniowe gaussowskie pudełkowe</string>\n    <string name=\"low_poly\">Niska polaryzacja</string>\n    <string name=\"foggy_night\">Mglista noc</string>\n    <string name=\"one_time_save_location\">Lokalizacja jednorazowego zapisu</string>\n    <string name=\"create_shortcut\">Utwórz skrót</string>\n    <string name=\"allow_enter_by_text_field_sub\">Włącza pole tekstowe za wyborem ustawień wstępnych, aby wprowadzać je na bieżąco</string>\n    <string name=\"fit_to_bounds\">Dopasowanie do granic</string>\n    <string name=\"equalize_histogram\">Wyrównaj histogram</string>\n    <string name=\"enable_timestamps_to_format_them\">Włącz znaczniki czasu, aby wybrać ich format</string>\n    <string name=\"linear_gaussian_blur\">Rozmycie liniowe gaussowskie</string>\n    <string name=\"default_draw_path_mode\">Domyślny tryb ścieżki rysowania</string>\n    <string name=\"one_time_save_location_sub\">Wyświetlanie i edytowanie lokalizacji jednorazowego zapisu, z których można korzystać poprzez długie naciśnięcie przycisku zapisu w większości opcji</string>\n    <string name=\"default_values\">Wartości domyślne</string>\n    <string name=\"create_shortcut_title\">Wybierz narzędzie do przypięcia</string>\n    <string name=\"linear_stack_blur\">Rozmycie liniowe stosu</string>\n    <string name=\"add_timestamp\">Dodaj znacznik czasu</string>\n    <string name=\"defaultt_sub\">Tylko domyślne linie proste</string>\n    <string name=\"dont_stack_frames\">Nie układaj ramek w stos</string>\n    <string name=\"fit_to_bounds_sub\">Połącz tryb zmiany rozmiaru kadrowania z tym parametrem, aby uzyskać pożądane zachowanie (Kadrowanie/Dopasowanie do proporcji)</string>\n    <string name=\"system_bars_visibility\">Widoczność pasków systemowych</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"save_empty_lut_sub\">Najpierw użyj swojej ulubionej aplikacji do edycji zdjęć, aby zastosować filtr do neutralnego LUT, który możesz uzyskać tutaj. Aby filtr działał poprawnie, kolor każdego piksela nie może zależeć od innych pikseli (np. rozmycie nie będzie działać). Po przygotowaniu, użyj nowego obrazu LUT jako danych wejściowych dla filtra LUT 512*512</string>\n    <string name=\"add_timestamp_sub\">Włącza dodawanie znacznika czasu do nazwy pliku wyjściowego</string>\n    <string name=\"top_hat\">Kapelusz</string>\n    <string name=\"dot_dashed\">Przerywana kropka</string>\n    <string name=\"dashed_sub\">Rysuje przerywaną linię wzdłuż narysowanej ścieżki z określonym rozmiarem odstępu</string>\n    <string name=\"formatted_timestamp\">Sformatowany znacznik czasu</string>\n    <string name=\"manage_storage_extra_types_sub\">Zezwól wszystkim plikom na dostęp do wyświetlania plików JXL, QOI i innych obrazów, które nie są rozpoznawane jako obrazy w systemie Android. Bez tego uprawnienia aplikacja Image Toolbox nie będzie w stanie wyświetlać tych obrazów</string>\n    <string name=\"zigzag\">Zygzak</string>\n    <string name=\"formatted_timestamp_sub\">Włącz formatowanie znacznika czasu w nazwie pliku wyjściowego zamiast podstawowych milisekund</string>\n    <string name=\"dot_dashed_sub\">Rysuje kropkę i przerywaną linię wzdłuż podanej ścieżki</string>\n    <string name=\"enhanced_zoom_blur\">Ulepszone rozmycie powiększenia</string>\n    <string name=\"dont_stack_frames_sub\">Umożliwia usuwanie poprzednich ramek, dzięki czemu nie będą się one na siebie nakładać</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Udzielenie kamerze uprawnień do przechwytywania obrazu w ustawieniach</string>\n    <string name=\"compact_selectors_sub\">Niektóre elementy sterujące wyborem będą miały kompaktowy układ, aby zajmować mniej miejsca</string>\n    <string name=\"layers_on_image_sub\">Użyj obrazu jako tła i dodaj do niego różne warstwy</string>\n    <string name=\"center_align_dialog_buttons\">Środkowe przyciski dialogowe</string>\n    <string name=\"markup_layers\">Warstwy znaczników</string>\n    <string name=\"lut_library_update_sub\">Zaktualizuj kolekcję LUT (tylko nowe zostaną umieszczone w kolejce), które można zastosować po pobraniu</string>\n    <string name=\"add_outline_sub\">Dodanie obrysu wokół tekstu o określonym kolorze i szerokości</string>\n    <string name=\"unknown_host\">Nie można uzyskać dostępu do witryny, spróbuj użyć VPN lub sprawdź, czy adres URL jest poprawny</string>\n    <string name=\"material_2_sub\">Suwak oparty na Material 2</string>\n    <string name=\"crf_sub\">Wartość %1$s oznacza wolną kompresję, co skutkuje stosunkowo małym rozmiarem pliku. %2$s oznacza szybszą kompresję, skutkującą dużym plikiem.</string>\n    <string name=\"center_align_dialog_buttons_sub\">Przyciski okien dialogowych będą umieszczane na środku zamiast po lewej stronie, jeśli to możliwe</string>\n    <string name=\"area_sub\">Ponowne próbkowanie przy użyciu relacji obszaru pikseli. Może to być preferowana metoda odszumiania obrazu, ponieważ daje wyniki wolne od efektu mory. Ale gdy obraz jest powiększony, jest podobny do metody „Najbliższy”.</string>\n    <string name=\"wrong_font\">Można importować tylko czcionki TTF i OTF</string>\n    <string name=\"import_font\">Import czcionki (TTF/OTF)</string>\n    <string name=\"export_fonts\">Wyeksportuj czcionki</string>\n    <string name=\"imported_fonts\">Zaimportowane czcionki</string>\n    <string name=\"filename_is_not_set\">Nazwa pliku nie została ustawiona</string>\n    <string name=\"error_while_saving\">Błąd podczas próby zapisu, spróbuj zmienić folder wyjściowy</string>\n    <string name=\"none\">Brak</string>\n    <string name=\"custom_pages\">Własne strony</string>\n    <string name=\"pages_selection\">Wybór stron</string>\n    <string name=\"tool_exit_confirmation\">Potwierdzenie wychodzenia z narzędzi</string>\n    <string name=\"tool_exit_confirmation_sub\">Jeśli masz niezapisane zmiany podczas korzystania z określonych narzędzi i spróbujesz je zamknąć, zostanie wyświetlone okno dialogowe potwierdzenia</string>\n    <string name=\"edit_exif_screen\">Edytuj EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Zmiana metadanych pojedynczego obrazu bez rekompresji</string>\n    <string name=\"edit_exif_tag\">Dotknij, aby edytować dostępne znacziki</string>\n    <string name=\"change_sticker\">Zmień naklejkę</string>\n    <string name=\"fit_height\">Dopasuj do wysokości</string>\n    <string name=\"fit_width\">Dopasuj do szerokości</string>\n    <string name=\"batch_compare\">Porównanie wsadowe</string>\n    <string name=\"pick_files_to_checksum\">Wybierz plik/pliki, aby obliczyć jego sumę kontrolną na podstawie wybranego algorytmu</string>\n    <string name=\"pick_files\">Wybierz pliki</string>\n    <string name=\"pick_directory\">Wybierz katalog</string>\n    <string name=\"head_length_scale\">Czołowa długość skali</string>\n    <string name=\"stamp\">Pieczęć</string>\n    <string name=\"timestamp\">Znacznik czasu</string>\n    <string name=\"format_pattern\">Wzór formatu</string>\n    <string name=\"padding\">Wypełnienie</string>\n    <string name=\"vertical_pivot_line\">Pionowa linia obrotu</string>\n    <string name=\"horizontal_pivot_line\">Pozioma linia obrotu</string>\n    <string name=\"inverse_selection\">Odwróć zaznaczenie</string>\n    <string name=\"inverse_vertical_selection_sub\">Pionowa część cięcia zostanie pozostawiona, zamiast łączenia części wokół obszaru cięcia</string>\n    <string name=\"image_cutting_sub\">Wycinanie części obrazu i łączenie lewych części (może być odwrotnie) za pomocą pionowych lub poziomych linii</string>\n    <string name=\"inverse_horizontal_selection_sub\">Pozioma część cięcia zostanie pozostawiona, zamiast łączenia części wokół obszaru cięcia</string>\n    <string name=\"image_cutting\">Przycinanie obrazu</string>\n    <string name=\"collection_mesh_gradients\">Kolekcja gradientów siatki</string>\n    <string name=\"gradient_maker_type_image_mesh\">Nakładka gradientu siatki</string>\n    <string name=\"mesh_gradients_sub\">Tworzenie gradientu siatki z własną ilością węzłów i rozdzielczością</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Skomponuj gradient siatki górnej części podanych obrazów</string>\n    <string name=\"points_customization\">Dostosowywanie punktów</string>\n    <string name=\"grid_size\">Rozmiar siatki</string>\n    <string name=\"resolution_x\">Rozdzielczość X</string>\n    <string name=\"resolution_y\">Rozdzielczość Y</string>\n    <string name=\"resolution\">Rozdzielczość</string>\n    <string name=\"pixel_by_pixel\">Piksel po pikselu</string>\n    <string name=\"highlight_color\">Kolor podświetlenia</string>\n    <string name=\"pixel_comparison_type\">Typ porównania pikseli</string>\n    <string name=\"scan_barcode\">Zeskanuj kod kreskowy</string>\n    <string name=\"height_ratio\">Współczynnik wysokości</string>\n    <string name=\"barcode_type\">Rodzaj kodu kreskowego</string>\n    <string name=\"enforce_bw\">Wymuś B/CZ</string>\n    <string name=\"enforce_bw_sub\">Obraz kodu kreskowego będzie w pełni czarno-biały i nie będzie kolorowany przez motyw aplikacji</string>\n    <string name=\"barcodes_sub\">Zeskanuj dowolny kod kreskowy (QR, EAN, AZTEC, …) i pobierz jego zawartość lub wklej tekst, aby wygenerować nowy</string>\n    <string name=\"generated_barcode_will_be_here\">Wygenerowany kod kreskowy będzie dostępny tutaj</string>\n    <string name=\"no_barcode_found\">Nie znaleziono kodu kreskowego</string>\n    <string name=\"audio_cover_extractor\">Okładki audio</string>\n    <string name=\"audio_cover_extractor_sub\">Wyodrębnianie obrazów okładek albumów z plików audio, obsługiwane są najpopularniejsze formaty</string>\n    <string name=\"no_covers_found\">Brak okładek</string>\n    <string name=\"pick_audio_to_start\">Wybierz dźwięk, aby rozpocząć</string>\n    <string name=\"pick_audio\">Wybierz dźwięk</string>\n    <string name=\"send_logs\">Wyślij dzienniki</string>\n    <string name=\"send_logs_sub\">Kliknij, aby udostępnić plik dziennika aplikacji, pomoże mi to wykryć i naprawić problem.</string>\n    <string name=\"crash_title\">Ups… Coś poszło nie tak</string>\n    <string name=\"crash_subtitle\">Możesz skontaktować się ze mną, korzystając z poniższych opcji, a ja postaram się znaleźć rozwiązanie.\\n(Nie zapomnij załączyć dziennika)</string>\n    <string name=\"ocr_write_to_file\">Zapisz do pliku</string>\n    <string name=\"ocr_write_to_file_sub\">Wyodrębnianie tekstu z partii obrazów i zapisywanie go w jednym pliku tekstowym</string>\n    <string name=\"ocr_write_to_metadata\">Zapisz do metadanych</string>\n    <string name=\"ocr_write_to_metadata_sub\">Wyodrębnianie tekstu z każdego obrazu i umieszczanie go w informacjach EXIF powiązanych zdjęć</string>\n    <string name=\"invisible_mode\">Tryb niewidzialności</string>\n    <string name=\"invisible_mode_sub\">Używaj techniki steganografii do tworzenia niewidocznych dla oka znaków wodnych w bajtach obrazów</string>\n    <string name=\"use_lsb\">Używaj LSB</string>\n    <string name=\"use_lsb_sub\">Zastosowana zostanie metoda steganografii LSB (Less Significant Bit - mniej znaczący bit), w przeciwnym razie użyta zostanie metoda FD (Frequency Domain - domena częstotliwości)</string>\n    <string name=\"auto_remove_red_eyes\">Automatyczne usuwanie czerwonych oczu</string>\n    <string name=\"password\">Hasło</string>\n    <string name=\"unlock\">Odblokuj</string>\n    <string name=\"pdf_is_protected\">PDF jest zabezpieczony</string>\n    <string name=\"sort_by_date_modified\">Data modyfikacji</string>\n    <string name=\"sort_by_mime_type\">Typ MIME</string>\n    <string name=\"sort_by_extension\">Rozszerzenie</string>\n    <string name=\"sort_by_extension_reversed\">Rozszerzenie (odwrotnie)</string>\n    <string name=\"sort_by_date_added\">Data dodania</string>\n    <string name=\"sort_by_size\">Rozmiar</string>\n    <string name=\"sort_by_size_reversed\">Rozmiar (odwrotnie)</string>\n    <string name=\"sort_by_mime_type_reversed\">Typ MIME (odwrotnie)</string>\n    <string name=\"sort_by_date_modified_reversed\">Data modyfikacji (odwrotnie)</string>\n    <string name=\"operation_almost_complete\">Operacja prawie zakończona. Anulowanie teraz będzie wymagało ponownego uruchomienia</string>\n    <string name=\"sort_by_date_added_reversed\">Data dodania (odwrotnie)</string>\n    <string name=\"left_to_right\">Od lewej do prawej</string>\n    <string name=\"right_to_left\">Od prawej do lewej</string>\n    <string name=\"top_to_bottom\">Od góry do dołu</string>\n    <string name=\"bottom_to_top\">Od dołu do góry</string>\n    <string name=\"liquid_glass\">Płynne szkło</string>\n    <string name=\"liquid_glass_sub\">Przełącznik oparty na niedawno ogłoszonym systemie IOS 26 i jego systemie projektowania płynnego szkła</string>\n    <string name=\"pick_image_or_base64\">Wybierz obraz lub wklej/zaimportuj dane Base64 poniżej</string>\n    <string name=\"type_image_link\">Wpisz link do obrazu, aby rozpocząć</string>\n    <string name=\"paste_link\">Wklej link</string>\n    <string name=\"kaleidoscope\">Kalejdoskop</string>\n    <string name=\"secondary_angle\">Dodatkowy kąt</string>\n    <string name=\"sides\">Boki</string>\n    <string name=\"channel_mix\">Kanał mieszany</string>\n    <string name=\"blue_green\">Niebiesko-zielony</string>\n    <string name=\"red_blue\">Czerwono-niebieski</string>\n    <string name=\"green_red\">Zielono-czerwony</string>\n    <string name=\"into_red\">W czerwień</string>\n    <string name=\"into_green\">W zieleń</string>\n    <string name=\"into_blue\">W błękit</string>\n    <string name=\"cyan\">Cyjan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Żółty</string>\n    <string name=\"color_halftone\">Kolorowy półton</string>\n    <string name=\"contour\">Kontur</string>\n    <string name=\"levels\">Poziomy</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi Crystallize</string>\n    <string name=\"shape\">Kształt</string>\n    <string name=\"stretch\">Rozciągnij</string>\n    <string name=\"randomness\">Losowość</string>\n    <string name=\"despeckle\">Usuwanie plam</string>\n    <string name=\"diffuse\">Rozprosz</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Drugi promień</string>\n    <string name=\"equalize\">Wyrównaj</string>\n    <string name=\"glow\">Blask</string>\n    <string name=\"whirl_and_pinch\">Wir i ściskanie</string>\n    <string name=\"pointillize\">Punktowanie</string>\n    <string name=\"border_color\">Kolor brzegu</string>\n    <string name=\"polar_coordinates\">Współrzędne biegunowe</string>\n    <string name=\"rect_to_polar\">Od prostokątnego do biegunowego</string>\n    <string name=\"polar_to_rect\">Od biegunowego do prostokątnego</string>\n    <string name=\"invert_in_circle\">Odwróć w okręgu</string>\n    <string name=\"reduce_noise\">Zmniejsz szum</string>\n    <string name=\"simple_solarize\">Prosta solaryzacja</string>\n    <string name=\"weave\">Splot</string>\n    <string name=\"x_gap\">Odstęp X</string>\n    <string name=\"y_gap\">Odstęp Y</string>\n    <string name=\"x_width\">Szerokość X</string>\n    <string name=\"y_wdth\">Szerokość Y</string>\n    <string name=\"twirl\">Wiruj</string>\n    <string name=\"rubber_stmp\">Pieczątka gumowa</string>\n    <string name=\"smear\">Rozmazywanie</string>\n    <string name=\"density\">Gęstość</string>\n    <string name=\"mix\">Miksuj</string>\n    <string name=\"sphere_lensh_distortion\">Zniekształcenie soczewki sferycznej</string>\n    <string name=\"refraction_index\">Współczynnik załamania światła</string>\n    <string name=\"arc\">Łuk</string>\n    <string name=\"spread_angle\">Kąt rozproszenia</string>\n    <string name=\"sparkle\">Iskra</string>\n    <string name=\"rays\">Promienie</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Mora</string>\n    <string name=\"autumn\">Jesień</string>\n    <string name=\"bone\">Kość</string>\n    <string name=\"jet\">Odrzutowiec</string>\n    <string name=\"winter\">Zima</string>\n    <string name=\"ocean\">Ocean</string>\n    <string name=\"summer\">Lato</string>\n    <string name=\"spring\">Wiosna</string>\n    <string name=\"cool_variant\">Wariant chłodny</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Różowy</string>\n    <string name=\"hot\">Gorąc</string>\n    <string name=\"parula\">Parula</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Piekło</string>\n    <string name=\"plasma\">Plazma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Cividis</string>\n    <string name=\"twilight\">Zmierzch</string>\n    <string name=\"twilight_shifted\">Zmieniony zmierz</string>\n    <string name=\"auto_perspective\">Auto perspektywa</string>\n    <string name=\"deskew\">Wyprostowanie</string>\n    <string name=\"allow_crop\">Zezwalaj na przycięcie</string>\n    <string name=\"crop_or_perspective\">Przytnij lub perspektywa</string>\n    <string name=\"absolute\">Absolutny</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Głęboka zieleń</string>\n    <string name=\"lens_correction\">Korekcja soczewki</string>\n    <string name=\"target_lens_profile\">Plik profilu obiektywu docelowego w formacie JSON</string>\n    <string name=\"download_ready_lens_profiles\">Pobierz gotowe profile obiektywów</string>\n    <string name=\"part_percents\">Procenty częściowe</string>\n    <string name=\"disable_rotation\">Wyłącz rotację</string>\n    <string name=\"disable_rotation_sub\">Zapobiega obracaniu obrazów za pomocą gestów dwoma palcami</string>\n    <string name=\"enable_snapping_to_borders\">Włącz przyciąganie do krawędzi</string>\n    <string name=\"enable_snapping_to_borders_sub\">Po przesunięciu lub powiększeniu obrazy zostaną dopasowane tak, aby wypełnić krawędzie ramki</string>\n    <string name=\"export_as_json\">Wyeksportuj do JSON</string>\n    <string name=\"export_as_json_sub\">Skopiuj ciąg znaków z danymi palety jako reprezentacją json</string>\n    <string name=\"home_screen\">Ekran główny</string>\n    <string name=\"lock_screen\">Zablokuj ekran</string>\n    <string name=\"built_in\">Wbudowany</string>\n    <string name=\"wallpapers_export\">Eksport tapet</string>\n    <string name=\"refresh\">Odśwież</string>\n    <string name=\"wallpapers_export_sub\">Pobierz aktualne tapety domowe, blokujące i wbudowane</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Zezwól na dostęp do wszystkich plików, jest to konieczne do pobrania tapet.</string>\n    <string name=\"allow_read_media_images_for_wp\">Zarządzanie uprawnieniami do pamięci zewnętrznej nie wystarczy, musisz zezwolić na dostęp do swoich zdjęć, upewnij się, że wybrałeś opcję „Zezwól na wszystko”</string>\n    <string name=\"add_preset_to_filename\">Dodaj ustawienie wstępne do nazwy pliku</string>\n    <string name=\"add_preset_to_filename_sub\">Dodaje sufiks z wybranym ustawieniem wstępnym do nazwy pliku obrazu</string>\n    <string name=\"add_image_scale_mode_to_filename\">Dodaj tryb skalowania obrazu do nazwy pliku</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Dodaje sufiks z wybranym trybem skalowania obrazu do nazwy pliku obrazu</string>\n    <string name=\"ascii_art\">Sztuka ASCII</string>\n    <string name=\"ascii_art_sub\">Konwertuj obraz na tekst ASCII, który będzie wyglądał jak obraz</string>\n    <string name=\"params\">Parametry</string>\n    <string name=\"invert_colors_ascii_sub\">W niektórych przypadkach stosuje filtr negatywowy do obrazu, aby uzyskać lepszy efekt</string>\n    <string name=\"seam_carving\">Rzeźbienie szwów</string>\n    <string name=\"processing_screenshot\">Przetwarzanie zrzutu ekranu</string>\n    <string name=\"screenshot_not_captured_try_again\">Nie wykonano zrzutu ekranu, spróbuj ponownie</string>\n    <string name=\"skipped_saving\">Pomijanie zapisu</string>\n    <string name=\"skipped_saving_multiple\">%1$s plików pominięto</string>\n    <string name=\"allow_skip_if_larger\">Pozwól na pomijanie jeśli większe</string>\n    <string name=\"allow_skip_if_larger_sub\">Niektóre narzędzia będą mogły pominąć zapisywanie obrazów, jeśli wynikowy rozmiar pliku będzie większy niż oryginalny</string>\n    <string name=\"qr_type_calendar_event\">Wydarzenie w kalendarzu</string>\n    <string name=\"qr_type_contact_info\">Kontakt</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Lokalizacja</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Tekst</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Otwórz sieć</string>\n    <string name=\"not_specified\">N/D</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Wiadomość</string>\n    <string name=\"address\">Adres</string>\n    <string name=\"subject\">Temat</string>\n    <string name=\"body\">Ciało</string>\n    <string name=\"name\">Nazwa</string>\n    <string name=\"organization\">Organizacja</string>\n    <string name=\"title\">Tytuł</string>\n    <string name=\"phones\">Telefony</string>\n    <string name=\"emails\">E-maile</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Adresy</string>\n    <string name=\"summary\">Podsumowanie</string>\n    <string name=\"description\">Opis</string>\n    <string name=\"location\">Lokalizacja</string>\n    <string name=\"organizer\">Organizer</string>\n    <string name=\"start_date\">Data rozpoczęcia</string>\n    <string name=\"end_date\">Data zakończenia</string>\n    <string name=\"status\">Stan</string>\n    <string name=\"latitude\">Szerokość geograficzna</string>\n    <string name=\"longitude\">Długość geograficzna</string>\n    <string name=\"create_barcode\">Utwórz kod kreskowy</string>\n    <string name=\"edit_barcode\">Edytuj kod kreskowy</string>\n    <string name=\"wifi_configuration\">Konfiguracja Wi-Fi</string>\n    <string name=\"security\">Bezpieczeństwo</string>\n    <string name=\"pick_contact\">Wybierz kontakt</string>\n    <string name=\"grant_contact_permission\">W ustawieniach udziel kontaktom pozwolenia na automatyczne wypełnianie kontaktów</string>\n    <string name=\"contact_info\">Dane kontaktowe</string>\n    <string name=\"first_name\">Imię</string>\n    <string name=\"middle_name\">Drugie imię</string>\n    <string name=\"last_name\">Nazwisko</string>\n    <string name=\"pronunciation\">Wymowa</string>\n    <string name=\"add_phone\">Dodaj telefon</string>\n    <string name=\"add_email\">Dodaj e-mail</string>\n    <string name=\"add_address\">Dodaj adres</string>\n    <string name=\"website\">Strona internetowa</string>\n    <string name=\"add_website\">Dodaj stronę internetową</string>\n    <string name=\"formatted_name\">Sformatowana nazwa</string>\n    <string name=\"qr_code_top_image\">Ten obraz zostanie umieszczony nad kodem kreskowym</string>\n    <string name=\"code_customization\">Dostosowanie kodu</string>\n    <string name=\"qr_logo_image\">Ten obraz zostanie użyty jako logo w środku kodu QR</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Wypełnienie logo</string>\n    <string name=\"logo_size\">Rozmiar logo</string>\n    <string name=\"logo_corners\">Narożniki logo</string>\n    <string name=\"fourth_eye\">Czwarte oko</string>\n    <string name=\"fourth_eye_description\">Dodaje symetrię oczu do kodu QR poprzez dodanie czwartego oka w dolnym rogu</string>\n    <string name=\"pixel_shape\">Kształt piksela</string>\n    <string name=\"frame_shape\">Kształt ramki</string>\n    <string name=\"ball_shape\">Kształt kuli</string>\n    <string name=\"error_correction_level\">Poziom korekcji błędów</string>\n    <string name=\"dark_color\">Ciemny kolor</string>\n    <string name=\"light_color\">Jasny kolor</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Styl podobny do Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Wzór maski</string>\n    <string name=\"code_may_be_not_scannable\">Ten kod może nie być skanowalny, zmień parametry wyglądu, aby był czytelny na wszystkich urządzeniach</string>\n    <string name=\"not_scannable\">Nie nadaje się do skanowania</string>\n    <string name=\"launcher_mode_sub\">Narzędzia będą wyglądały jak program uruchamiający aplikacje na ekranie głównym, aby były bardziej kompaktowe</string>\n    <string name=\"launcher_mode\">Tryb uruchamiania</string>\n    <string name=\"flood_fill_sub\">Wypełnia obszar wybranym pędzlem i stylem</string>\n    <string name=\"flood_fill\">Wypełnianie wodą</string>\n    <string name=\"spray\">Sprej</string>\n    <string name=\"spray_sub\">Rysuje ścieżkę w stylu graffiti</string>\n    <string name=\"square_particles\">Kwadratowe cząsteczki</string>\n    <string name=\"square_particles_sub\">Cząsteczki rozpylane będą miały kształt kwadratowy zamiast okrągłego</string>\n    <string name=\"palette_tools\">Narzędzia palety</string>\n    <string name=\"palette_tools_sub\">Generuj podstawową/materiałową paletę z obrazu lub importuj/eksportuj między różnymi formatami palet</string>\n    <string name=\"edit_palette\">Edytuj paletę</string>\n    <string name=\"edit_palette_sub\">Eksportuj/importuj paletę w różnych formatach</string>\n    <string name=\"color_name\">Nazwa koloru</string>\n    <string name=\"palette_name\">Nazwa palety</string>\n    <string name=\"palette_format\">Format palety</string>\n    <string name=\"export_palette_sub\">Eksportuj wygenerowaną paletę do różnych formatów</string>\n    <string name=\"add_color_palette_sub\">Dodaje nowy kolor do bieżącej palety</string>\n    <string name=\"palette_name_not_supported\">Format %1$s nie obsługuje podawania nazwy palety</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Ze względu na zasady sklepu Play Store ta funkcja nie może być zawarta w obecnej wersji. Aby uzyskać dostęp do tej funkcji, pobierz ImageToolbox z alternatywnego źródła. Dostępne wersje można znaleźć na GitHub poniżej.</string>\n    <string name=\"open_github_page\">Otwórz stronę Github</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s kolor</item>\n        <item quantity=\"few\">%1$s kolory</item>\n        <item quantity=\"many\">%1$s kolorów</item>\n        <item quantity=\"other\">%1$s kolorów</item>\n    </plurals>\n    <string name=\"overwrite_files_sub_short\">Oryginalny plik zostanie zastąpiony nowym zamiast zapisywania w wybranym folderze</string>\n    <string name=\"hidden_watermark_text_detected\">Wykryto ukryty tekst znaku wodnego</string>\n    <string name=\"hidden_watermark_image_detected\">Wykryto ukryty obraz znaku wodnego</string>\n    <string name=\"this_image_was_hidden\">Ten obraz został ukryty</string>\n    <string name=\"generative_inpaint\">Generatywne uzupełnianie obrazów</string>\n    <string name=\"generative_inpaint_sub\">Umożliwia usuwanie obiektów z obrazu przy użyciu modelu AI, bez konieczności korzystania z OpenCV. Aby skorzystać z tej funkcji, aplikacja pobierze wymagany model (~200 MB) z serwisu GitHub.</string>\n    <string name=\"generative_inpaint_ready_sub\">Umożliwia usuwanie obiektów z obrazu przy użyciu modelu AI, bez konieczności korzystania z OpenCV. Może to być operacja długotrwała.</string>\n    <string name=\"error_level_analysis\">Analiza poziomu błędów</string>\n    <string name=\"luminance_gradient\">Gradient luminancji</string>\n    <string name=\"average_distance\">Średnia odległość</string>\n    <string name=\"copy_move_detection\">Wykrywanie kopiowania i przenoszenia</string>\n    <string name=\"retain\">Zachowaj</string>\n    <string name=\"coefficent\">Współczynnik</string>\n    <string name=\"clipboard_data_is_too_large\">Dane w schowku są zbyt duże</string>\n    <string name=\"data_is_too_large_to_copy\">Dane są zbyt duże, aby je skopiować</string>\n    <string name=\"simple_weave_pixelization\">Prosta pikselizacja splotu</string>\n    <string name=\"staggered_pixelization\">Pikselizacja rozłożona w czasie</string>\n    <string name=\"cross_pixelization\">Pikselizacja krzyżowa</string>\n    <string name=\"micro_macro_pixelization\">Mikro-makro pikselizacja</string>\n    <string name=\"orbital_pixelization\">Pikselizacja orbitalna</string>\n    <string name=\"vortex_pixelization\">Pikselizacja wirowa</string>\n    <string name=\"pulse_grid_pixelization\">Pikselizacja siatki impulsowej</string>\n    <string name=\"nucleus_pixelization\">Pikselizacja jądra</string>\n    <string name=\"radial_weave_pixelization\">Pikselizacja splotu promieniowego</string>\n    <string name=\"cannot_open_uri\">Nie można otworzyć adresu URI „%1$s”</string>\n    <string name=\"snowfall_mode\">Tryb opadów śniegu</string>\n    <string name=\"enabled\">Włączono</string>\n    <string name=\"border_frame\">Ramka graniczna</string>\n    <string name=\"glitch_variant\">Wariant usterki</string>\n    <string name=\"channel_shift\">Zmiana kanału</string>\n    <string name=\"max_offset\">Maksymalne przesunięcie</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Usterka bloku</string>\n    <string name=\"block_size\">Rozmiar bloku</string>\n    <string name=\"crt_curvature\">Krzywizna CRT</string>\n    <string name=\"curvature\">Krzywizna</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Topnienie pikseli</string>\n    <string name=\"max_drop\">Maksymalny spadek</string>\n    <string name=\"ai_tools\">Narzędzia AI</string>\n    <string name=\"ai_tools_sub\">Różne narzędzia do przetwarzania obrazów za pomocą modeli AI, takie jak usuwanie artefaktów lub odszumianie</string>\n    <string name=\"model_anime_undeint\">Kompresja, postrzępione linie</string>\n    <string name=\"model_broadcast\">Kreskówki, kompresja programów</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Ogólna kompresja, ogólny hałas</string>\n    <string name=\"model_wb_denoise\">Bezbarwny dźwięk kreskówek</string>\n    <string name=\"model_span_anime_pretrain\">Szybka, ogólna kompresja, ogólny hałas, animacja/komiksy/anime</string>\n    <string name=\"model_book_scan\">Skanowanie książek</string>\n    <string name=\"model_overexposure\">Korekcja ekspozycji</string>\n    <string name=\"model_fbcnn_color_fp16\">Najlepiej przy ogólnej kompresji, kolorowe obrazy</string>\n    <string name=\"model_fbcnn_gray_fp16\">Najlepiej przy ogólnej kompresji obrazów w skali szarości</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Ogólna kompresja, obrazy w skali szarości, mocniejsze</string>\n    <string name=\"model_scunet_color_gan_fp16\">Ogólny szum, kolorowe obrazy</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Ogólny szum, kolorowe obrazy, lepsze szczegóły</string>\n    <string name=\"model_scunet_gray_15_fp16\">Ogólny szum, obrazy w skali szarości</string>\n    <string name=\"model_scunet_gray_25_fp16\">Ogólny szum, obrazy w skali szarości, mocniejsze</string>\n    <string name=\"model_scunet_gray_50_fp16\">Ogólny szum, obrazy w skali szarości, najsilniejszy</string>\n    <string name=\"model_jpeg_destroyer\">Ogólna kompresja</string>\n    <string name=\"model_jaywreck\">Ogólna kompresja</string>\n    <string name=\"model_h264\">Teksturowanie, kompresja h264</string>\n    <string name=\"model_vhs\">Kompresja VHS</string>\n    <string name=\"model_cinepak\">Niestandardowa kompresja (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Kompresja Bink, lepsza geometria</string>\n    <string name=\"model_debink_v5\">Kompresja Bink, silniejsza</string>\n    <string name=\"model_debink_v6\">Kompresja Bink, miękka, zachowuje szczegóły</string>\n    <string name=\"model_antialias\">Likwidacja efektu schodkowego, wygładzenie</string>\n    <string name=\"model_kdm_scans\">Zeskanowane dzieła sztuki/rysunki, łagodna kompresja, efekt mory</string>\n    <string name=\"model_bandage\">Pasowanie kolorów</string>\n    <string name=\"model_halftone\">Powolne, usuwanie półtonów</string>\n    <string name=\"model_colorizer\">Ogólny moduł koloryzujący dla obrazów w skali szarości/czarno-białych, aby uzyskać lepsze wyniki, użyj DColor</string>\n    <string name=\"model_deedge\">Usuwanie krawędzi</string>\n    <string name=\"model_desharpen\">Usuwa nadmierne wyostrzenie</string>\n    <string name=\"model_dither\">Powolny, drżący</string>\n    <string name=\"model_gainres\">Wygładzanie, ogólne artefakty, CGI</string>\n    <string name=\"model_kdm003_scans\">Przetwarzanie skanów KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Lekki model poprawiający obraz</string>\n    <string name=\"model_bcgone_detailed_v2\">Usuwanie artefaktów kompresji</string>\n    <string name=\"model_bcgone_smooth\">Usuwanie artefaktów kompresji</string>\n    <string name=\"model_bandage_smooth\">Usuwanie bandaży z gładkimi wynikami</string>\n    <string name=\"model_bendel_halftone\">Przetwarzanie wzoru rastrowego</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Usuwanie wzorca drgań V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Usuwanie artefaktów JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Ulepszenie tekstur H.264</string>\n    <string name=\"model_vhs_sharpen\">Wyostrzanie i ulepszanie VHS</string>\n    <string name=\"merging\">Łączenie</string>\n    <string name=\"chunk_size\">Rozmiar kawałka</string>\n    <string name=\"overlap_size\">Rozmiar nakładania się</string>\n    <string name=\"note_chunk_info\">Obrazy o rozmiarze większym niż %1$s pikseli zostaną pokrojone i przetworzone w kawałkach. Nakładanie łączy je, aby zapobiec widocznym łączeniom.</string>\n    <string name=\"large_chunk_warning\">Duże rozmiary mogą powodować niestabilność urządzeń z niższej półki</string>\n    <string name=\"select_one_to_start\">Wybierz jeden, aby rozpocząć</string>\n    <string name=\"delete_model_sub\">Czy chcesz usunąć model %1$s? Będziesz musiał pobrać go ponownie</string>\n    <string name=\"confirm\">Potwierdzać</string>\n    <string name=\"models\">Modele</string>\n    <string name=\"downloaded_models\">Pobrane modele</string>\n    <string name=\"available_models\">Dostępne modele</string>\n    <string name=\"preparing\">Przygotowanie</string>\n    <string name=\"active_model\">Aktywny model</string>\n    <string name=\"failed_to_open_session\">Nie udało się otworzyć sesji</string>\n    <string name=\"only_onnx_models\">Można importować tylko modele .onnx/.ort</string>\n    <string name=\"import_model\">Importuj model</string>\n    <string name=\"import_model_sub\">Zaimportuj niestandardowy model onnx do dalszego wykorzystania, akceptowane są tylko modele onnx/ort, obsługuje prawie wszystkie warianty podobne do esrgan</string>\n    <string name=\"imported_models\">Importowane modele</string>\n    <string name=\"model_scunet_color_15_fp16\">Ogólny hałas, kolorowe obrazy</string>\n    <string name=\"model_scunet_color_25_fp16\">Ogólny szum, kolorowe obrazy, mocniejsze</string>\n    <string name=\"model_scunet_color_50_fp16\">Ogólny szum, kolorowe obrazy, najsilniejszy</string>\n    <string name=\"model_artifacts_dithering_alsa\">Redukuje artefakty związane z ditheringiem i pasma kolorów, poprawiając gładkie gradienty i płaskie obszary kolorów.</string>\n    <string name=\"model_nmkd_brighten_redux\">Zwiększa jasność i kontrast obrazu dzięki zrównoważonym rozjaśnieniom, zachowując jednocześnie naturalne kolory.</string>\n    <string name=\"model_nmkd_brighten\">Rozjaśnia ciemne obrazy, zachowując szczegóły i unikając prześwietlenia.</string>\n    <string name=\"model_nmkd_detoon\">Usuwa nadmierne tonowanie kolorów i przywraca bardziej neutralną i naturalną równowagę kolorów.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Stosuje tonowanie szumu w oparciu o Poissona, kładąc nacisk na zachowanie drobnych szczegółów i tekstur.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Stosuje miękkie tonowanie szumu Poissona, aby uzyskać gładsze i mniej agresywne efekty wizualne.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Jednolite tonowanie szumów skupione na zachowaniu szczegółów i przejrzystości obrazu.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Delikatne, jednolite tonowanie szumów zapewnia subtelną teksturę i gładki wygląd.</string>\n    <string name=\"model_repainter\">Naprawia uszkodzone lub nierówne obszary, odmalowując artefakty i poprawiając spójność obrazu.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Lekki model usuwający paski, który usuwa kolorowe pasy przy minimalnych kosztach wydajności.</string>\n    <string name=\"model_jpeg_0_20\">Optymalizuje obrazy z artefaktami o bardzo wysokim stopniu kompresji (jakość 0–20%) w celu poprawy przejrzystości.</string>\n    <string name=\"model_jpeg_20_40\">Poprawia obrazy o artefakty o wysokiej kompresji (jakość 20–40%), przywracając szczegóły i redukując szumy.</string>\n    <string name=\"model_jpeg_40_60\">Poprawia obrazy przy umiarkowanej kompresji (jakość 40–60%), równoważąc ostrość i gładkość.</string>\n    <string name=\"model_jpeg_60_80\">Poprawia obrazy za pomocą lekkiej kompresji (jakość 60–80%), aby uwydatnić subtelne szczegóły i tekstury.</string>\n    <string name=\"model_jpeg_80_100\">Nieznacznie poprawia niemal bezstratne obrazy (jakość 80–100%), zachowując jednocześnie naturalny wygląd i szczegóły.</string>\n    <string name=\"model_spongecolor_lite\">Prosta i szybka koloryzacja, kreskówki, nie idealna</string>\n    <string name=\"model_deblr\">Nieznacznie zmniejsza rozmycie obrazu, poprawiając ostrość bez wprowadzania artefaktów.</string>\n    <string name=\"processing_channel\">Długotrwałe operacje</string>\n    <string name=\"processing_image\">Przetwarzanie obrazu</string>\n    <string name=\"processing\">Przetwarzanie</string>\n    <string name=\"model_artifacts_jpg_0_20\">Usuwa duże artefakty kompresji JPEG z obrazów o bardzo niskiej jakości (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Redukuje silne artefakty JPEG w obrazach o dużej kompresji (20–40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Usuwa umiarkowane artefakty JPEG, zachowując szczegóły obrazu (40–60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Poprawia jasne artefakty JPEG w obrazach o dość wysokiej jakości (60–80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Subtelnie redukuje drobne artefakty JPEG w niemal bezstratnych obrazach (80-100%).</string>\n    <string name=\"model_redetail_v2\">Uwydatnia drobne szczegóły i tekstury, poprawiając postrzeganą ostrość bez ciężkich artefaktów.</string>\n    <string name=\"processing_finished\">Przetwarzanie zakończone</string>\n    <string name=\"processing_failed\">Przetwarzanie nie powiodło się</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Poprawia teksturę i szczegóły skóry, zachowując jednocześnie naturalny wygląd, zoptymalizowany pod kątem szybkości.</string>\n    <string name=\"model_sbdv_dejpeg\">Usuwa artefakty kompresji JPEG i przywraca jakość obrazu skompresowanych zdjęć.</string>\n    <string name=\"model_iso_denoise_v1\">Redukuje szumy ISO na zdjęciach robionych w warunkach słabego oświetlenia, zachowując szczegóły.</string>\n    <string name=\"model_dejumbo\">Koryguje prześwietlone lub „duże” światła i przywraca lepszą równowagę tonalną.</string>\n    <string name=\"model_ddcolor_tiny\">Lekki i szybki model koloryzacji, który dodaje naturalne kolory do obrazów w skali szarości.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Odszumić</string>\n    <string name=\"type_colorize\">Koloruj</string>\n    <string name=\"type_artifacts\">Artefakty</string>\n    <string name=\"type_enhance\">Zwiększyć</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Skany</string>\n    <string name=\"type_upscale\">Ekskluzywny</string>\n    <string name=\"model_realesrgan_x4v3\">Upscaler X4 dla obrazów ogólnych; mały model, który zużywa mniej procesora graficznego i czasu, z umiarkowanym usuwaniem rozmycia i odszumiania.</string>\n    <string name=\"model_realesrgan_x2plus\">Moduł skalujący X2 do ogólnych obrazów, zachowujący tekstury i naturalne szczegóły.</string>\n    <string name=\"model_realesrgan_x4plus\">Moduł skalujący X4 do ogólnych obrazów z ulepszonymi teksturami i realistycznymi wynikami.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Upscaler X4 zoptymalizowany pod kątem obrazów anime; 6 bloków RRDB dla ostrzejszych linii i szczegółów.</string>\n    <string name=\"model_realesrnet_x4plus\">Moduł zwiększający skalę X4 ze stratą MSE, zapewnia gładsze wyniki i mniej artefaktów w przypadku ogólnych obrazów.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler zoptymalizowany pod kątem obrazów anime; Wariant 4B32F z ostrzejszymi detalami i gładkimi liniami.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Model X4 UltraSharp V2 do zdjęć ogólnych; podkreśla ostrość i klarowność.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; szybszy i mniejszy, zachowuje szczegóły przy mniejszym zużyciu pamięci GPU.</string>\n    <string name=\"model_rmbg_1_4\">Lekki model do szybkiego usuwania tła. Zrównoważona wydajność i dokładność. Działa z portretami, obiektami i scenami. Zalecane w większości przypadków użycia.</string>\n    <string name=\"type_removebg\">Usuń BG</string>\n    <string name=\"horizontal_border_thickness\">Grubość obramowania poziomego</string>\n    <string name=\"vertical_border_thickness\">Grubość obramowania pionowego</string>\n    <string name=\"current_model_not_chunkable\">Obecny model nie obsługuje fragmentowania, obraz zostanie przetworzony w oryginalnych wymiarach, może to powodować duże zużycie pamięci i problemy z urządzeniami z niższej półki</string>\n    <string name=\"chunking_disabled\">Dzielenie na kawałki wyłączone, obraz zostanie przetworzony w oryginalnych wymiarach, może to powodować duże zużycie pamięci i problemy z urządzeniami z niższej półki, ale może dać lepsze wyniki na podstawie wnioskowania</string>\n    <string name=\"chunking\">Kawałki</string>\n    <string name=\"model_u2net\">Model segmentacji obrazu o wysokiej dokładności do usuwania tła</string>\n    <string name=\"model_u2netp\">Lekka wersja U2Net do szybszego usuwania tła przy mniejszym zużyciu pamięci.</string>\n    <string name=\"model_ddcolor\">Model Full DColor zapewnia wysokiej jakości kolorowanie ogólnych obrazów przy minimalnej liczbie artefaktów. Najlepszy wybór ze wszystkich modeli koloryzacji.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Trained i prywatne zbiory danych artystycznych; zapewnia różnorodne i artystyczne rezultaty koloryzacji z mniejszą liczbą nierealistycznych artefaktów kolorystycznych.</string>\n    <string name=\"model_birefnet\">Lekki model BiRefNet oparty na transformatorze Swin do dokładnego usuwania tła.</string>\n    <string name=\"model_inspyrenet\">Wysokiej jakości usuwanie tła z ostrymi krawędziami i doskonałym zachowaniem szczegółów, szczególnie w przypadku skomplikowanych obiektów i trudnych środowisk.</string>\n    <string name=\"model_isnet\">Model usuwania tła, który tworzy dokładne maski o gładkich krawędziach, odpowiednie dla obiektów ogólnych i umiarkowanego zachowania szczegółów.</string>\n    <string name=\"model_already_downloaded\">Model już pobrany</string>\n    <string name=\"model_successfully_imported\">Model został pomyślnie zaimportowany</string>\n    <string name=\"type\">Typ</string>\n    <string name=\"keyword\">Słowo kluczowe</string>\n    <string name=\"very_fast\">Bardzo szybko</string>\n    <string name=\"normal\">Normalna</string>\n    <string name=\"slow\">Powolny</string>\n    <string name=\"very_slow\">Bardzo powolny</string>\n    <string name=\"compute_percents\">Oblicz procenty</string>\n    <string name=\"minimum_value_is\">Minimalna wartość to %1$s</string>\n    <string name=\"warp_sub\">Zniekształcanie obrazu poprzez rysowanie palcami</string>\n    <string name=\"warp\">Osnowa</string>\n    <string name=\"hardness\">Twardość</string>\n    <string name=\"warp_mode\">Tryb wypaczenia</string>\n    <string name=\"warp_mode_move\">Przenosić</string>\n    <string name=\"warp_mode_grow\">Rosnąć</string>\n    <string name=\"warp_mode_shrink\">Kurczyć się</string>\n    <string name=\"warp_mode_swirl_cw\">Wir CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Wiruj CCW</string>\n    <string name=\"fade_strength\">Siła blaknięcia</string>\n    <string name=\"top_drop\">Najwyższy spadek</string>\n    <string name=\"bottom_drop\">Dolny spadek</string>\n    <string name=\"start_drop\">Rozpocznij upuszczanie</string>\n    <string name=\"end_drop\">Koniec zrzutu</string>\n    <string name=\"downloading\">Pobieranie</string>\n    <string name=\"smooth_shapes\">Gładkie kształty</string>\n    <string name=\"smooth_shapes_sub\">Użyj superelips zamiast standardowych zaokrąglonych prostokątów, aby uzyskać gładsze, bardziej naturalne kształty</string>\n    <string name=\"shape_type\">Typ kształtu</string>\n    <string name=\"cut\">Cięcie</string>\n    <string name=\"rounded\">Bułczasty</string>\n    <string name=\"smooth\">Gładki</string>\n    <string name=\"cut_shapes_sub\">Ostre krawędzie bez zaokrągleń</string>\n    <string name=\"rounded_shapes_sub\">Klasycznie zaokrąglone rogi</string>\n    <string name=\"shapes_type\">Typ kształtów</string>\n    <string name=\"corners_size\">Rozmiar narożników</string>\n    <string name=\"squircle\">Wiercik</string>\n    <string name=\"squircle_shapes_sub\">Eleganckie zaokrąglone elementy interfejsu użytkownika</string>\n    <string name=\"filename_format\">Format nazwy pliku</string>\n    <string name=\"prefix_pattern_description\">Niestandardowy tekst umieszczany na samym początku nazwy pliku, idealny do nazw projektów, marek lub osobistych tagów.</string>\n    <string name=\"original_filename_pattern_description\">Używa oryginalnej nazwy pliku bez rozszerzenia, pomagając zachować nienaruszoną identyfikację źródła.</string>\n    <string name=\"width_pattern_description\">Szerokość obrazu w pikselach, przydatna do śledzenia zmian rozdzielczości lub wyników skalowania.</string>\n    <string name=\"height_pattern_description\">Wysokość obrazu w pikselach, pomocna podczas pracy ze współczynnikami proporcji lub eksportami.</string>\n    <string name=\"random_numbers_pattern_description\">Generuje losowe cyfry, aby zagwarantować unikalne nazwy plików; dodaj więcej cyfr, aby zapewnić dodatkowe bezpieczeństwo przed duplikatami.</string>\n    <string name=\"sequence_number_pattern_description\">Automatycznie zwiększający się licznik do eksportu wsadowego, idealny przy zapisywaniu wielu obrazów w jednej sesji.</string>\n    <string name=\"preset_info_pattern_description\">Wstawia zastosowaną nazwę ustawienia wstępnego do nazwy pliku, dzięki czemu można łatwo zapamiętać sposób przetwarzania obrazu.</string>\n    <string name=\"scale_mode_pattern_description\">Wyświetla tryb skalowania obrazu używany podczas przetwarzania, pomagając rozróżnić obrazy o zmienionym rozmiarze, przycięte lub dopasowane.</string>\n    <string name=\"suffix_pattern_description\">Niestandardowy tekst umieszczony na końcu nazwy pliku, przydatny przy wersjonowaniu, takim jak _v2, _edited lub _final.</string>\n    <string name=\"extension_pattern_description\">Rozszerzenie pliku (png, jpg, webp itp.), automatycznie dopasowujące się do aktualnie zapisanego formatu.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Konfigurowalny znacznik czasu, który pozwala zdefiniować własny format według specyfikacji Java w celu idealnego sortowania.</string>\n    <string name=\"fling_type\">Typ rzucania</string>\n    <string name=\"android_native\">Natywny Android</string>\n    <string name=\"ios_style\">Styl iOS</string>\n    <string name=\"smooth_curve\">Gładka krzywa</string>\n    <string name=\"quick_stop\">Szybkie zatrzymanie</string>\n    <string name=\"bouncy\">Sprężysty</string>\n    <string name=\"floaty\">Pływający</string>\n    <string name=\"snappy\">Żwawy</string>\n    <string name=\"ultra_smooth\">Ultragładka</string>\n    <string name=\"adaptive\">Adaptacyjny</string>\n    <string name=\"accessibility_aware\">Świadomość dostępności</string>\n    <string name=\"reduced_motion\">Ograniczony ruch</string>\n    <string name=\"android_native_sub\">Natywna fizyka przewijania Androida</string>\n    <string name=\"smooth_sub\">Zrównoważone, płynne przewijanie do ogólnego użytku</string>\n    <string name=\"ios_style_sub\">Zachowanie przewijania podobne do systemu iOS o większym tarciu</string>\n    <string name=\"smooth_curve_sub\">Unikalna krzywa splajnu zapewniająca wyraźne wyczucie przewijania</string>\n    <string name=\"quick_stop_sub\">Precyzyjne przewijanie z szybkim zatrzymaniem</string>\n    <string name=\"bouncy_sub\">Zabawny, responsywny, sprężysty przewijak</string>\n    <string name=\"floaty_sub\">Długie, przesuwające się zwoje do przeglądania treści</string>\n    <string name=\"snappy_sub\">Szybkie i responsywne przewijanie dla interaktywnych interfejsów użytkownika</string>\n    <string name=\"ultra_smooth_sub\">Wysokiej jakości płynne przewijanie z wydłużonym tempem</string>\n    <string name=\"adaptive_sub\">Dostosowuje fizykę w oparciu o prędkość rzucania</string>\n    <string name=\"accessibility_aware_sub\">Przestrzega systemowych ustawień dostępności</string>\n    <string name=\"reduced_motion_sub\">Minimalny ruch ze względu na potrzeby dostępności</string>\n    <string name=\"primary_lines\">Linie podstawowe</string>\n    <string name=\"primary_lines_sub\">Dodaje grubszą linię co piątą linię</string>\n    <string name=\"fill_color\">Kolor wypełnienia</string>\n    <string name=\"hidden_tools\">Ukryte narzędzia</string>\n    <string name=\"hidden_for_share\">Narzędzia ukryte do udostępnienia</string>\n    <string name=\"color_library\">Biblioteka kolorów</string>\n    <string name=\"color_library_sub\">Przeglądaj bogatą kolekcję kolorów</string>\n    <string name=\"model_fatality_deblur\">Wyostrza i usuwa rozmycia obrazów, zachowując naturalne szczegóły, idealne do poprawiania nieostrych zdjęć.</string>\n    <string name=\"model_unresize_v3\">Inteligentnie przywraca obrazy, których rozmiar został wcześniej zmieniony, odzyskując utracone szczegóły i tekstury.</string>\n    <string name=\"model_liveaction_v1_span\">Zoptymalizowany pod kątem treści zawierających akcję na żywo, redukuje artefakty powstałe w wyniku kompresji i poprawia drobne szczegóły w klatkach filmów/programów telewizyjnych.</string>\n    <string name=\"model_vhs2hd_realplksr\">Konwertuje materiał filmowy o jakości VHS na HD, usuwając szumy taśmy i zwiększając rozdzielczość, zachowując jednocześnie klimat vintage.</string>\n    <string name=\"model_text2hd_v1\">Specjalizuje się w obrazach i zrzutach ekranu zawierających dużo tekstu, wyostrza znaki i poprawia czytelność.</string>\n    <string name=\"model_frankendata_pretrainer\">Zaawansowane skalowanie trenowane na różnych zestawach danych, doskonałe do ogólnego ulepszania zdjęć.</string>\n    <string name=\"model_realwebphoto_v2\">Zoptymalizowany pod kątem zdjęć skompresowanych w Internecie, usuwa artefakty JPEG i przywraca naturalny wygląd.</string>\n    <string name=\"model_realwebphoto_v4\">Ulepszona wersja zdjęć internetowych z lepszym zachowaniem tekstur i redukcją artefaktów.</string>\n    <string name=\"model_dat_2x\">Dwukrotne skalowanie dzięki technologii podwójnego transformatora agregującego pozwala zachować ostrość i naturalne szczegóły.</string>\n    <string name=\"model_dat_3x\">3-krotne skalowanie przy użyciu zaawansowanej architektury transformatorowej, idealne do umiarkowanych potrzeb powiększenia.</string>\n    <string name=\"model_dat_4x\">4-krotne skalowanie wysokiej jakości dzięki najnowocześniejszej sieci transformatorowej pozwala zachować drobne szczegóły w większych skalach.</string>\n    <string name=\"model_nafnet_deblurring\">Usuwa rozmycie/szumy i drgania ze zdjęć. Ogólnego przeznaczenia, ale najlepiej na zdjęciach.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Przywraca obrazy o niskiej jakości przy użyciu transformatora Swin2SR, zoptymalizowanego pod kątem degradacji BSRGAN. Doskonały do ​​naprawiania artefaktów spowodowanych dużą kompresją i uwydatniania szczegółów w skali 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Skalowanie 4x za pomocą transformatora SwinIR trenowanego pod kątem degradacji BSRGAN. Wykorzystuje GAN, aby uzyskać ostrzejsze tekstury i bardziej naturalne szczegóły na zdjęciach i złożonych scenach.</string>\n    <string name=\"path\">Ścieżka</string>\n    <string name=\"merge_pdf\">Scal PDF</string>\n    <string name=\"merge_pdf_sub\">Połącz wiele plików PDF w jeden dokument</string>\n    <string name=\"files_order\">Kolejność plików</string>\n    <string name=\"pages_short\">s.</string>\n    <string name=\"split_pdf\">Podziel plik PDF</string>\n    <string name=\"split_pdf_sub\">Wyodrębnij określone strony z dokumentu PDF</string>\n    <string name=\"rotate_pdf\">Obróć plik PDF</string>\n    <string name=\"rotate_pdf_sub\">Napraw na stałe orientację strony</string>\n    <string name=\"pages\">Strony</string>\n    <string name=\"rearrange_pdf\">Zmień kolejność plików PDF</string>\n    <string name=\"rearrange_pdf_sub\">Przeciągnij i upuść strony, aby zmienić ich kolejność</string>\n    <string name=\"hold_drag_drop\">Przytrzymaj i przeciągnij strony</string>\n    <string name=\"page_numbers\">Numery stron</string>\n    <string name=\"page_numbers_sub\">Automatycznie dodawaj numerację do swoich dokumentów</string>\n    <string name=\"label_format\">Format etykiety</string>\n    <string name=\"pdf_to_text\">PDF na tekst (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Wyodrębnij zwykły tekst z dokumentów PDF</string>\n    <string name=\"watermark_pdf_sub\">Nałóż niestandardowy tekst dla marki lub bezpieczeństwa</string>\n    <string name=\"signature\">Podpis</string>\n    <string name=\"signature_sub\">Dodaj swój podpis elektroniczny do dowolnego dokumentu</string>\n    <string name=\"will_be_for_signature\">Będzie to używane jako podpis</string>\n    <string name=\"unlock_pdf\">Odblokuj PDF</string>\n    <string name=\"unlock_pdf_sub\">Usuń hasła z chronionych plików</string>\n    <string name=\"protect_pdf\">Chroń PDF</string>\n    <string name=\"protect_pdf_sub\">Zabezpiecz swoje dokumenty silnym szyfrowaniem</string>\n    <string name=\"success\">Sukces</string>\n    <string name=\"pdf_unlocked\">PDF odblokowany, możesz go zapisać lub udostępnić</string>\n    <string name=\"repair_pdf\">Napraw PDF</string>\n    <string name=\"repair_pdf_sub\">Spróbuj naprawić uszkodzone lub nieczytelne dokumenty</string>\n    <string name=\"grayscale\">Skala szarości</string>\n    <string name=\"grayscale_pdf_sub\">Konwertuj wszystkie obrazy osadzone w dokumencie na skalę szarości</string>\n    <string name=\"compress_pdf\">Kompresuj PDF</string>\n    <string name=\"compress_pdf_sub\">Zoptymalizuj rozmiar pliku dokumentu, aby ułatwić udostępnianie</string>\n    <string name=\"repair_info\">ImageToolbox odbudowuje wewnętrzną tabelę powiązań i ponownie generuje strukturę pliku od podstaw. Może to przywrócić dostęp do wielu plików, których „nie można otworzyć”</string>\n    <string name=\"grayscale_info\">To narzędzie konwertuje wszystkie obrazy dokumentów do skali szarości. Najlepsze do drukowania i zmniejszania rozmiaru pliku</string>\n    <string name=\"metadata\">Metadane</string>\n    <string name=\"metadata_pdf_sub\">Edytuj właściwości dokumentu, aby zapewnić większą prywatność</string>\n    <string name=\"tags\">Tagi</string>\n    <string name=\"producer\">Producent</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Słowa kluczowe</string>\n    <string name=\"creator\">Twórca</string>\n    <string name=\"privacy_deep_clean\">Głębokie czyszczenie prywatności</string>\n    <string name=\"privacy_deep_clean_sub\">Wyczyść wszystkie dostępne metadane dla tego dokumentu</string>\n    <string name=\"page\">Strona</string>\n    <string name=\"deep_ocr\">Głęboki OCR</string>\n    <string name=\"deep_ocr_sub\">Wyodrębnij tekst z dokumentu i zapisz go w jednym pliku tekstowym za pomocą silnika Tesseract</string>\n    <string name=\"cant_remove_all\">Nie można usunąć wszystkich stron</string>\n    <string name=\"remove_pages_pdf\">Usuń strony PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Usuń określone strony z dokumentu PDF</string>\n    <string name=\"tap_to_remove\">Kliknij, aby usunąć</string>\n    <string name=\"manually\">Ręcznie</string>\n    <string name=\"crop_pdf\">Przytnij plik PDF</string>\n    <string name=\"crop_pdf_sub\">Przytnij strony dokumentu do dowolnych granic</string>\n    <string name=\"flatten_pdf\">Spłaszcz plik PDF</string>\n    <string name=\"flatten_pdf_sub\">Spraw, aby plik PDF nie był modyfikowalny, rastrując strony dokumentu</string>\n    <string name=\"camera_failed_to_open\">Nie można uruchomić aparatu. Sprawdź uprawnienia i upewnij się, że nie jest używana przez inną aplikację.</string>\n    <string name=\"extract_images\">Wyodrębnij obrazy</string>\n    <string name=\"extract_images_sub\">Wyodrębnij obrazy osadzone w plikach PDF w ich oryginalnej rozdzielczości</string>\n    <string name=\"pdf_no_embedded\">Ten plik PDF nie zawiera żadnych osadzonych obrazów</string>\n    <string name=\"extract_images_info\">To narzędzie skanuje każdą stronę i odzyskuje obrazy źródłowe o pełnej jakości — idealne do zapisywania oryginałów z dokumentów</string>\n    <string name=\"draw_signature\">Narysuj podpis</string>\n    <string name=\"pen_params\">Parametry pióra</string>\n    <string name=\"draw_signature_sub\">Użyj własnego podpisu jako obrazu do umieszczenia na dokumentach</string>\n    <string name=\"zip_pdf\">Spakuj PDF</string>\n    <string name=\"zip_pdf_sub\">Podziel dokument w określonym przedziale czasu i spakuj nowe dokumenty do archiwum zip</string>\n    <string name=\"interval\">Interwał</string>\n    <string name=\"print_pdf\">Wydrukuj PDF</string>\n    <string name=\"print_pdf_sub\">Przygotuj dokument do druku z niestandardowym rozmiarem strony</string>\n    <string name=\"pages_per_sheet\">Strony na arkusz</string>\n    <string name=\"orientation\">Orientacja</string>\n    <string name=\"page_size\">Rozmiar strony</string>\n    <string name=\"margin\">Margines</string>\n    <string name=\"bloom\">Kwiat</string>\n    <string name=\"soft_knee\">Miękkie kolano</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Zoptymalizowany pod kątem anime i kreskówek. Szybkie skalowanie z ulepszonymi naturalnymi kolorami i mniejszą liczbą artefaktów</string>\n    <string name=\"one_ui_sub\">Styl Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Wprowadź tutaj podstawowe symbole matematyczne, aby obliczyć żądaną wartość (np. (5+5)*10)</string>\n    <string name=\"math_expression\">Wyrażenie matematyczne</string>\n    <string name=\"pick_up_to_n_collage_images\">Odbierz maksymalnie %1$s obrazów</string>\n    <string name=\"keep_date_time\">Zachowaj datę i godzinę</string>\n    <string name=\"keep_date_time_sub\">Zawsze zachowuj tagi exif powiązane z datą i godziną, działa niezależnie od opcji zachowywania exif</string>\n    <string name=\"background_color_for_alpha_formats\">Kolor tła dla formatów Alpha</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Dodaje możliwość ustawienia koloru tła dla każdego formatu obrazu z obsługą alfa, gdy jest wyłączona, dostępna tylko dla formatów innych niż alfa</string>\n    <string name=\"open_markup_project\">Otwórz projekt</string>\n    <string name=\"open_markup_project_sub\">Kontynuuj edycję wcześniej zapisanego projektu Image Toolbox</string>\n    <string name=\"markup_project_open_failed\">Nie można otworzyć projektu Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">W projekcie Image Toolbox brakuje danych projektu</string>\n    <string name=\"markup_project_corrupted\">Projekt Image Toolbox jest uszkodzony</string>\n    <string name=\"unsupported_markup_project_version\">Nieobsługiwana wersja projektu Image Toolbox: %1$d</string>\n    <string name=\"save_markup_project\">Zapisz projekt</string>\n    <string name=\"save_markup_project_sub\">Przechowuj warstwy, tło i historię edycji w edytowalnym pliku projektu</string>\n    <string name=\"failed_to_open\">Nie udało się otworzyć</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Zapisz w pliku PDF z możliwością przeszukiwania</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Rozpoznaj tekst z partii obrazów i zapisz plik PDF z możliwością przeszukiwania z obrazem i wybraną warstwą tekstową</string>\n    <string name=\"layer_alpha\">Warstwa alfa</string>\n    <string name=\"horizontal_flip\">Odwrócenie poziome</string>\n    <string name=\"vertical_flip\">Odwrócenie w pionie</string>\n    <string name=\"lock\">Zamek</string>\n    <string name=\"add_shadow\">Dodaj cień</string>\n    <string name=\"shadow_color\">Kolor cienia</string>\n    <string name=\"text_geometry\">Geometria tekstu</string>\n    <string name=\"text_geometry_sub\">Rozciągnij lub pochyl tekst, aby uzyskać ostrzejszą stylizację</string>\n    <string name=\"scale_x\">Skala X</string>\n    <string name=\"skew_x\">Pochylić X</string>\n    <string name=\"remove_annotations\">Usuń adnotacje</string>\n    <string name=\"remove_annotations_sub\">Usuń wybrane typy adnotacji, takie jak łącza, komentarze, wyróżnienia, kształty lub pola formularzy ze stron PDF</string>\n    <string name=\"annotation_link\">Hiperłącza</string>\n    <string name=\"annotation_file_attachment\">Załączniki plików</string>\n    <string name=\"annotation_line\">Kwestia</string>\n    <string name=\"annotation_popup\">Wyskakujące okienka</string>\n    <string name=\"annotation_stamp\">Znaczki</string>\n    <string name=\"annotation_shapes\">Kształty</string>\n    <string name=\"annotation_text\">Notatki tekstowe</string>\n    <string name=\"annotation_text_markup\">Oznaczenia tekstowe</string>\n    <string name=\"annotation_widget\">Pola formularza</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">Nieznany</string>\n    <string name=\"annotations\">Adnotacje</string>\n    <string name=\"ungroup\">Rozgrupuj</string>\n    <string name=\"add_shadow_sub\">Dodaj rozmyty cień za warstwą z konfigurowalnym kolorem i przesunięciami</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-pt-rBR/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">Algo deu errado: %1$s</string>\n    <string name=\"size\">Tamanho %1$s</string>\n    <string name=\"loading\">Carregando…</string>\n    <string name=\"image_too_large_preview\">A imagem é muito grande para ser visualizada, mas tentaremos salvar mesmo assim</string>\n    <string name=\"pick_image\">Escolha a imagem para começar</string>\n    <string name=\"width\">Largura %1$s</string>\n    <string name=\"height\">Altura %1$s</string>\n    <string name=\"quality\">Qualidade</string>\n    <string name=\"extension\">Extensão</string>\n    <string name=\"resize_type\">Tipo de redimensionamento</string>\n    <string name=\"explicit\">Explícito</string>\n    <string name=\"flexible\">Flexível</string>\n    <string name=\"pick_image_alt\">Escolha a imagem</string>\n    <string name=\"app_closing_sub\">Você tem certeza de que deseja encerrar o aplicativo?</string>\n    <string name=\"app_closing\">Fechar aplicativo</string>\n    <string name=\"stay\">Ficar</string>\n    <string name=\"close\">Fechar</string>\n    <string name=\"reset_image\">Redefinir imagem</string>\n    <string name=\"reset_image_sub\">As alterações na imagem retornarão aos valores iniciais</string>\n    <string name=\"values_reset\">Valores redefinidos corretamente</string>\n    <string name=\"reset\">Reiniciar</string>\n    <string name=\"something_went_wrong\">Algo deu errado</string>\n    <string name=\"restart_app\">Reinicie o aplicativo</string>\n    <string name=\"copied\">Copiado para a área de transferência</string>\n    <string name=\"exception\">Exceção</string>\n    <string name=\"edit_exif\">Editar EXIF</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">OK</string>\n    <string name=\"no_exif\">Nenhum dado EXIF encontrado</string>\n    <string name=\"add_tag\">Adicionar tag</string>\n    <string name=\"save\">Salvar</string>\n    <string name=\"clear\">Limpar</string>\n    <string name=\"clear_exif\">Limpar EXIF</string>\n    <string name=\"cancel\">Cancelar</string>\n    <string name=\"clear_exif_sub\">Todos os dados EXIF da imagem serão apagados. Essa ação não pode ser desfeita!</string>\n    <string name=\"presets\">Predefinições</string>\n    <string name=\"crop\">Cortar</string>\n    <string name=\"image_not_saved\">Salvando</string>\n    <string name=\"image_not_saved_sub\">Todas as alterações não salvas serão perdidas se você sair agora</string>\n    <string name=\"check_source_code\">Código fonte</string>\n    <string name=\"check_source_code_sub\">Receba as atualizações mais recentes, discuta problemas e muito mais</string>\n    <string name=\"single_edit\">Edição Única</string>\n    <string name=\"single_edit_sub\">Modificar, redimensionar e editar uma imagem</string>\n    <string name=\"pick_color\">Seletor de Cores</string>\n    <string name=\"pick_color_sub\">Escolha a cor da imagem, copie ou compartilhe</string>\n    <string name=\"image\">Imagem</string>\n    <string name=\"color\">Cor</string>\n    <string name=\"color_copied\">Cor copiada</string>\n    <string name=\"crop_sub\">Cortar imagem em qualquer limite</string>\n    <string name=\"version\">Versão</string>\n    <string name=\"keep_exif\">Manter EXIF</string>\n    <string name=\"images\">Imagens: %d</string>\n    <string name=\"change_preview\">Alterar visualização</string>\n    <string name=\"remove\">Remover</string>\n    <string name=\"palette_sub\">Gere amostra de paleta de cores a partir de determinada imagem</string>\n    <string name=\"generate_palette\">Gerar Paleta</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"update\">Atualizar</string>\n    <string name=\"new_version\">Nova versão %1$s</string>\n    <string name=\"unsupported_type\">Tipo não suportado: %1$s</string>\n    <string name=\"no_palette\">Não é possível gerar paleta para determinada imagem</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Pasta de saída</string>\n    <string name=\"def\">Padrão</string>\n    <string name=\"custom\">Personalizado</string>\n    <string name=\"unspecified\">Não especificado</string>\n    <string name=\"device_storage\">Dispositivo de armazenamento</string>\n    <string name=\"by_bytes_resize\">Redimensionar por Tamanho</string>\n    <string name=\"max_bytes\">Tamanho máximo em KB</string>\n    <string name=\"by_bytes_resize_sub\">Redimensione uma imagem seguindo o tamanho determinado em KB</string>\n    <string name=\"compare\">Comparar</string>\n    <string name=\"compare_sub\">Compare duas imagens fornecidas</string>\n    <string name=\"pick_two_images\">Escolha duas imagens para começar</string>\n    <string name=\"pick_images\">Escolher imagens</string>\n    <string name=\"settings\">Configurações</string>\n    <string name=\"night_mode\">Modo noturno</string>\n    <string name=\"dark\">Escuro</string>\n    <string name=\"light\">Claro</string>\n    <string name=\"system\">Sistema</string>\n    <string name=\"dynamic_colors\">Cores dinâmicas</string>\n    <string name=\"customization\">Personalização</string>\n    <string name=\"allow_image_monet\">Permitir monetização de imagem</string>\n    <string name=\"allow_image_monet_sub\">Se ativado, ao escolher uma imagem para editar, as cores do aplicativo serão adotadas para esta imagem</string>\n    <string name=\"language\">Idioma</string>\n    <string name=\"amoled_mode\">Modo AMOLED</string>\n    <string name=\"amoled_mode_sub\">Se ativado, a cor das superfícies será definida para escuro absoluto no modo noturno</string>\n    <string name=\"color_scheme\">Esquema de cores</string>\n    <string name=\"color_red\">Vermelho</string>\n    <string name=\"color_green\">Verde</string>\n    <string name=\"color_blue\">Azul</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Cole um código aRGB válido.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nada para colar</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">O esquema de cores do aplicativo não pode ser alterado enquanto as cores dinâmicas estiverem ativadas</string>\n    <string name=\"pick_accent_color\">O tema do aplicativo será baseado na cor selecionada</string>\n    <string name=\"about_app\">Sobre o aplicativo</string>\n    <string name=\"no_updates\">Nenhuma atualização encontrada</string>\n    <string name=\"issue_tracker\">Rastreador de problemas</string>\n    <string name=\"issue_tracker_sub\">Envie relatórios de bugs e solicitações de recursos aqui</string>\n    <string name=\"help_translate\">Ajude a traduzir</string>\n    <string name=\"help_translate_sub\">Corrija erros de tradução ou localize o projeto para outros idiomas</string>\n    <string name=\"nothing_found_by_search\">Nada encontrado pela sua consulta</string>\n    <string name=\"search_here\">Pesquise aqui</string>\n    <string name=\"dynamic_colors_sub\">Se ativado, as cores do aplicativo serão adotadas nas cores do papel de parede</string>\n    <string name=\"failed_to_save\">Falha ao salvar %d imagens</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"primary\">Primário</string>\n    <string name=\"tertiary\">Terciário</string>\n    <string name=\"secondary\">Secundário</string>\n    <string name=\"border_thickness\">Espessura da borda</string>\n    <string name=\"surface\">Superfície</string>\n    <string name=\"values\">Valores</string>\n    <string name=\"add\">Adicionar</string>\n    <string name=\"permission\">Permissão</string>\n    <string name=\"grant\">Conceder</string>\n    <string name=\"permission_sub\">O aplicativo precisa de acesso ao seu armazenamento para salvar as imagens para funcionar, é necessário. Conceda permissão na próxima caixa de diálogo.</string>\n    <string name=\"grant_permission_manual\">O aplicativo precisa desta permissão para funcionar, por favor conceda-a manualmente</string>\n    <string name=\"external_storage\">Armazenamento externo</string>\n    <string name=\"monet_colors\">Cores Monet</string>\n    <string name=\"donation_sub\">Esta aplicação é totalmente gratuita, mas se quiser apoiar o desenvolvimento do projeto, pode clicar aqui</string>\n    <string name=\"fab_alignment\">Alinhamento do FAB</string>\n    <string name=\"check_updates\">Buscar atualizações</string>\n    <string name=\"check_updates_sub\">Se ativado, a caixa de diálogo de atualização será mostrada na inicialização do aplicativo</string>\n    <string name=\"zoom\">Zoom da imagem</string>\n    <string name=\"share\">Compartilhar</string>\n    <string name=\"prefix\">Prefixo</string>\n    <string name=\"filename\">Nome do arquivo</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Selecione qual emoji exibir na tela principal</string>\n    <string name=\"add_file_size\">Adicionar tamanho de arquivo</string>\n    <string name=\"add_file_size_sub\">Se ativado, adiciona largura e altura da imagem salva ao nome do arquivo de saída</string>\n    <string name=\"delete_exif\">Excluir EXIF</string>\n    <string name=\"delete_exif_sub\">Exclua metadados EXIF de qualquer conjunto de imagens</string>\n    <string name=\"image_preview\">Previa de Imagem</string>\n    <string name=\"image_preview_sub\">Visualize qualquer tipo de imagem: GIF, SVG e assim por diante</string>\n    <string name=\"image_source\">Origem da imagem</string>\n    <string name=\"photo_picker\">Seletor de fotos</string>\n    <string name=\"gallery_picker\">Galeria</string>\n    <string name=\"file_explorer_picker\">Explorador de arquivos</string>\n    <string name=\"photo_picker_sub\">O seletor de fotos moderno do Android, que aparece na parte inferior da tela, pode funcionar apenas no Android 12+. Tem problemas ao receber metadados EXIF</string>\n    <string name=\"gallery_picker_sub\">Seletor de imagens de galeria simples. Funcionará apenas se você tiver um aplicativo que forneça seleção de mídia</string>\n    <string name=\"file_explorer_picker_sub\">Use a intenção GetContent para escolher a imagem. Funciona em qualquer lugar, mas é conhecido por ter problemas ao receber imagens selecionadas em alguns dispositivos. Não é minha culpa.</string>\n    <string name=\"options_arrangement\">Arranjo de opções</string>\n    <string name=\"edit\">Editar</string>\n    <string name=\"order\">Ordem</string>\n    <string name=\"order_sub\">Determina a ordem das ferramentas na tela principal</string>\n    <string name=\"emojis_count\">Contagem de emojis</string>\n    <string name=\"sequence_num\">sequênciaNum</string>\n    <string name=\"original_filename\">nome do arquivo original</string>\n    <string name=\"add_original_filename\">Adicione o nome do arquivo original</string>\n    <string name=\"add_original_filename_sub\">Se ativado, adiciona o nome do arquivo original ao nome da imagem de saída</string>\n    <string name=\"replace_sequence_number\">Substituir o número de sequência</string>\n    <string name=\"replace_sequence_number_sub\">Se ativado, substitui o carimbo de data e hora padrão pelo número de sequência da imagem se você usar o processamento em lote</string>\n    <string name=\"filename_not_work_with_photopicker\">Adicionar o nome do arquivo original não funciona se a fonte da imagem do seletor de fotos for selecionada</string>\n    <string name=\"load_image_from_net\">Carregamento de Imagens da Web</string>\n    <string name=\"load_image_from_net_sub\">Carregue qualquer imagem da internet para visualizar, ampliar, editar e salvar se desejar.</string>\n    <string name=\"no_image\">Nenhuma imagem</string>\n    <string name=\"image_link\">Link da imagem</string>\n    <string name=\"fill\">Preencher</string>\n    <string name=\"fit\">Ajustar</string>\n    <string name=\"content_scale\">Escala de conteúdo</string>\n    <string name=\"explicit_description\">Redimensiona as imagens para a altura e a largura fornecidas. A proporção de aspecto das imagens pode mudar.</string>\n    <string name=\"flexible_description\">Redimensiona as imagens com um lado longo para a altura ou a largura fornecida. Todos os cálculos de tamanho serão feitos após o salvamento. A proporção de aspecto das imagens será preservada.</string>\n    <string name=\"brightness\">Brilho</string>\n    <string name=\"contrast\">Contraste</string>\n    <string name=\"hue\">Matiz</string>\n    <string name=\"saturation\">Saturação</string>\n    <string name=\"add_filter\">Adicionar filtro</string>\n    <string name=\"filter\">Filtro</string>\n    <string name=\"filter_sub\">Aplicar cadeias de filtros às imagens</string>\n    <string name=\"filters\">Filtros</string>\n    <string name=\"light_aka_illumination\">Iluminação</string>\n    <string name=\"color_filter\">Filtro de cor</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"exposure\">Exposição</string>\n    <string name=\"white_balance\">Balanço de branco</string>\n    <string name=\"temperature\">Temperatura</string>\n    <string name=\"tint\">Matiz</string>\n    <string name=\"monochrome\">Monocromático</string>\n    <string name=\"gamma\">Gama</string>\n    <string name=\"highlights_shadows\">Destaques e sombras</string>\n    <string name=\"highlights\">Destaques</string>\n    <string name=\"shadows\">Sombras</string>\n    <string name=\"haze\">Confusão</string>\n    <string name=\"effect\">Efeito</string>\n    <string name=\"distance\">Distância</string>\n    <string name=\"slope\">Declive</string>\n    <string name=\"sharpen\">Afiado</string>\n    <string name=\"sepia\">Sépia</string>\n    <string name=\"negative\">Negativo</string>\n    <string name=\"solarize\">Solarizar</string>\n    <string name=\"vibrance\">Vibração</string>\n    <string name=\"black_and_white\">Preto e Branco</string>\n    <string name=\"crosshatch\">Hachura</string>\n    <string name=\"spacing\">Espaçamento</string>\n    <string name=\"line_width\">Espessura da linha</string>\n    <string name=\"sobel_edge\">Borda Sobel</string>\n    <string name=\"blur\">Desfoque</string>\n    <string name=\"halftone\">Meio-tom</string>\n    <string name=\"cga_colorspace\">Espaço de cores CGA</string>\n    <string name=\"gaussian_blur\">Desfoque gaussiano</string>\n    <string name=\"box_blur\">Desfoque de caixa</string>\n    <string name=\"bilaterial_blur\">Desfoque bilateral</string>\n    <string name=\"emboss\">Gravar</string>\n    <string name=\"laplacian\">Laplaciano</string>\n    <string name=\"vignette\">Vinheta</string>\n    <string name=\"start\">Iniciar</string>\n    <string name=\"end\">Fim</string>\n    <string name=\"kuwahara\">Suavização Kuwahara</string>\n    <string name=\"stack_blur\">Desfoque de pilha</string>\n    <string name=\"radius\">Raio</string>\n    <string name=\"scale\">Escala</string>\n    <string name=\"distortion\">Distorção</string>\n    <string name=\"angle\">Ângulo</string>\n    <string name=\"swirl\">Redemoinho</string>\n    <string name=\"bulge\">Protuberância</string>\n    <string name=\"dilation\">Dilatação</string>\n    <string name=\"sphere_refraction\">Refração de esfera</string>\n    <string name=\"refractive_index\">Índice de refração</string>\n    <string name=\"glass_sphere_refraction\">Refração da esfera de vidro</string>\n    <string name=\"color_matrix\">Matriz de cores</string>\n    <string name=\"opacity\">Opacidade</string>\n    <string name=\"limits_resize\">Redimensionar por Limites</string>\n    <string name=\"limits_resize_sub\">Redimensionar imagens para a altura e a largura fornecidas, mantendo a proporção de aspecto</string>\n    <string name=\"sketch\">Esboço</string>\n    <string name=\"threshold\">Limiar</string>\n    <string name=\"quantizationLevels\">Níveis de quantização</string>\n    <string name=\"smooth_toon\">Desenho suave</string>\n    <string name=\"toon\">Desenho animado</string>\n    <string name=\"posterize\">Posterizar</string>\n    <string name=\"non_maximum_suppression\">Supressão não máxima</string>\n    <string name=\"weak_pixel_inclusion\">Inclusão fraca de pixels</string>\n    <string name=\"lookup\">Olho para cima</string>\n    <string name=\"convolution3x3\">Convolução 3x3</string>\n    <string name=\"rgb_filter\">Filtro RGB</string>\n    <string name=\"false_color\">Cor falsa</string>\n    <string name=\"first_color\">Primeira cor</string>\n    <string name=\"second_color\">Segunda cor</string>\n    <string name=\"reorder\">Reordenar</string>\n    <string name=\"fast_blur\">Desfoque rápido</string>\n    <string name=\"blur_size\">Tamanho do desfoque</string>\n    <string name=\"blur_center_x\">Desfocar centro x</string>\n    <string name=\"blur_center_y\">Desfocar centro y</string>\n    <string name=\"zoom_blur\">Desfoque de zoom</string>\n    <string name=\"color_balance\">Equilíbrio de cores</string>\n    <string name=\"luminance_threshold\">Limite de luminância</string>\n    <string name=\"activate_files\">Você desativou o aplicativo \\\"Arquivos\\\", ative-o para usar este recurso</string>\n    <string name=\"draw\">Desenhar</string>\n    <string name=\"draw_sub\">Desenhe na imagem como em um caderno de desenho ou no próprio fundo</string>\n    <string name=\"paint_color\">Cor da tinta</string>\n    <string name=\"paint_alpha\">Pintura alfa</string>\n    <string name=\"draw_on_image\">Desenhar na imagem</string>\n    <string name=\"draw_on_image_sub\">Escolha uma imagem e desenhe algo nela</string>\n    <string name=\"draw_on_background\">Desenhe no fundo</string>\n    <string name=\"draw_on_background_sub\">Escolha a cor de fundo e desenhe sobre ela</string>\n    <string name=\"background_color\">Cor de fundo</string>\n    <string name=\"cipher\">Criptografia</string>\n    <string name=\"cipher_sub\">Criptografe e descriptografe qualquer arquivo (não apenas a imagem) com base em vários algoritmos de criptografia</string>\n    <string name=\"pick_file\">Escolher arquivo</string>\n    <string name=\"encrypt\">Criptografar</string>\n    <string name=\"decrypt\">Descriptografar</string>\n    <string name=\"pick_file_to_start\">Escolha o arquivo para começar</string>\n    <string name=\"decryption\">Descriptografia</string>\n    <string name=\"encryption\">Criptografia</string>\n    <string name=\"key\">Chave</string>\n    <string name=\"file_proceed\">Arquivo processado</string>\n    <string name=\"store_file_desc\">Armazene este arquivo no seu dispositivo ou use a ação de compartilhamento para colocá-lo onde quiser</string>\n    <string name=\"features\">Características</string>\n    <string name=\"implementation\">Implementação</string>\n    <string name=\"compatibility\">Compatibilidade</string>\n    <string name=\"features_sub\">Criptografia de arquivos baseada em senha. Os arquivos processados podem ser armazenados no diretório selecionado ou compartilhados. Os arquivos descriptografados também podem ser abertos diretamente.</string>\n    <string name=\"implementation_sub\">AES-256, modo GCM, sem preenchimento, IVs aleatórios de 12 bytes por padrão. Você pode selecionar o algoritmo necessário. As chaves são usadas como hashes SHA-3 de 256 bits</string>\n    <string name=\"file_size\">Tamanho do arquivo</string>\n    <string name=\"file_size_sub\">O tamanho máximo do arquivo é restrito pelo sistema operacional Android e pela memória disponível, que depende do dispositivo. \\nObserve: memória não é armazenamento.</string>\n    <string name=\"compatibility_sub\">Observe que a compatibilidade com outros softwares ou serviços de criptografia de arquivos não é garantida. Um tratamento de chave ou configuração de criptografia ligeiramente diferente pode causar incompatibilidade.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Senha inválida ou arquivo escolhido não está criptografado</string>\n    <string name=\"image_size_warning\">A tentativa de salvar a imagem com a largura e a altura fornecidas pode causar um erro de falta de memória. Faça isso por sua própria conta e risco.</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Tamanho da memória cache</string>\n    <string name=\"found_s\">Encontrado %1$s</string>\n    <string name=\"auto_cache_clearing\">Limpeza automática de cache</string>\n    <string name=\"auto_cache_clearing_sub\">Se ativado, o cache do aplicativo será limpo na inicialização do aplicativo</string>\n    <string name=\"create\">Criar</string>\n    <string name=\"tools\">Ferramentas</string>\n    <string name=\"group_options_by_type\">Opções de grupo por tipo</string>\n    <string name=\"group_options_by_type_sub\">Agrupa opções na tela principal por tipo, em vez de uma organização de lista personalizada</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Não é possível alterar a organização enquanto o agrupamento de opções está ativado</string>\n    <string name=\"edit_screenshot\">Editar captura de tela</string>\n    <string name=\"secondary_customization\">Personalização secundária</string>\n    <string name=\"screenshot\">Captura de tela</string>\n    <string name=\"fallback_option\">Opção alternativa</string>\n    <string name=\"skip\">Pular</string>\n    <string name=\"copy\">Copiar</string>\n    <string name=\"warning_bytes\">Salvar no modo %1$s pode ser instável, pois é um formato sem perdas</string>\n    <string name=\"presets_sub\" formatted=\"false\">Se você selecionou a predefinição 125, a imagem será salva com tamanho de 125% da imagem original. Se você escolher a predefinição 50, a imagem será salva com 50% tamanho</string>\n    <string name=\"presets_sub_bytes\">A predefinição aqui determina a % do arquivo de saída, ou seja, se você selecionar a predefinição 50 em uma imagem de 5 MB, obterá uma imagem de 2,5 MB após salvar</string>\n    <string name=\"randomize_filename\">Nome do arquivo aleatório</string>\n    <string name=\"randomize_filename_sub\">Se ativado, o nome do arquivo de saída será totalmente aleatório</string>\n    <string name=\"saved_to\">Salvo na pasta %1$s com o nome %2$s</string>\n    <string name=\"saved_to_without_filename\">Salvo na pasta %1$s</string>\n    <string name=\"tg_chat\">Telegram</string>\n    <string name=\"tg_chat_sub\">Discuta sobre o aplicativo e obtenha feedback de outros usuários. Você também pode obter atualizações beta e insights lá.</string>\n    <string name=\"crop_mask\">Máscara de corte</string>\n    <string name=\"aspect_ratio\">Proporção da tela</string>\n    <string name=\"image_crop_mask_sub\">Use este tipo de máscara para criar uma máscara a partir de uma determinada imagem, observe que DEVE ter canal alfa</string>\n    <string name=\"backup_and_restore\">Backup e restauração</string>\n    <string name=\"backup\">Backup</string>\n    <string name=\"restore\">Restaurar</string>\n    <string name=\"backup_sub\">Faça backup das configurações do seu aplicativo em um arquivo</string>\n    <string name=\"restore_sub\">Restaure as configurações do aplicativo do arquivo gerado anteriormente</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Arquivo corrompido ou não é um backup</string>\n    <string name=\"settings_restored\">Configurações restauradas com sucesso</string>\n    <string name=\"contact_me\">Me contatar</string>\n    <string name=\"reset_settings_sub\">Isso reverterá suas configurações para os valores padrão. Observe que isso não pode ser desfeito sem o arquivo de backup mencionado acima.</string>\n    <string name=\"delete\">Excluir</string>\n    <string name=\"delete_color_scheme_warn\">Você está prestes a excluir o esquema de cores selecionado. Esta operação não pode ser desfeita</string>\n    <string name=\"delete_color_scheme_title\">Excluir esquema</string>\n    <string name=\"font\">Fonte</string>\n    <string name=\"text\">Texto</string>\n    <string name=\"font_scale\">Escala de fonte</string>\n    <string name=\"defaultt\">Padrão</string>\n    <string name=\"using_large_fonts_warn\">O uso de escalas de fontes grandes pode causar falhas e problemas na interface do usuário, que não serão corrigidos. Use com cautela.</string>\n    <string name=\"alphabet_and_numbers\">Aa Áá Ââ Ãã Bb Cc Çç Dd Ee Éé Êê Ff Gg Hh Ii Íí Jj Kk Ll Mm Nn Oo Óó Ôô Õõ Pp Qq Rr Ss Tt Uu Úú Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"emotions\">Emoções</string>\n    <string name=\"food_and_drink\">Comida e bebida</string>\n    <string name=\"nature_and_animals\">Natureza e Animais</string>\n    <string name=\"objects\">Objetos</string>\n    <string name=\"symbols\">Símbolos</string>\n    <string name=\"enable_emoji\">Habilitar emoticons</string>\n    <string name=\"travels_and_places\">Viagens e lugares</string>\n    <string name=\"activities\">Atividades</string>\n    <string name=\"background_remover\">Removedor de Fundo</string>\n    <string name=\"background_remover_sub\">Remova o fundo da imagem desenhando ou use a opção \\\"Auto\\\"</string>\n    <string name=\"trim_image\">Cortar imagem</string>\n    <string name=\"keep_exif_sub\">Os metadados da imagem original serão mantidos</string>\n    <string name=\"trim_image_sub\">Os espaços transparentes ao redor da imagem serão cortados</string>\n    <string name=\"auto_erase_background\">Remover automaticamente o fundo</string>\n    <string name=\"restore_image\">Restaurar imagem</string>\n    <string name=\"erase_mode\">Modo remover</string>\n    <string name=\"erase_background\">Remover fundo</string>\n    <string name=\"restore_background\">Restaurar plano de fundo</string>\n    <string name=\"blur_radius\">Raio de desfoque</string>\n    <string name=\"pipette\">Pipeta</string>\n    <string name=\"draw_mode\">Modo de desenho</string>\n    <string name=\"create_issue\">Criar problema</string>\n    <string name=\"something_went_wrong_emphasis\">Ops… algo deu errado. Você pode escrever para mim usando as opções abaixo e tentarei encontrar uma solução</string>\n    <string name=\"resize_and_convert\">Redimensionar e Converter</string>\n    <string name=\"resize_and_convert_sub\">Altere o tamanho de determinadas imagens ou converta-as para outros formatos. Os metadados EXIF também podem ser editados aqui se você escolher uma única imagem.</string>\n    <string name=\"max_colors_count\">Contagem máxima de cores</string>\n    <string name=\"crashlytics_sub\">Isso permite que o aplicativo colete relatórios de falhas automaticamente</string>\n    <string name=\"analytics\">Analytics</string>\n    <string name=\"analytics_sub\">Permitir a coleta de estatísticas anônimas de uso de aplicativos</string>\n    <string name=\"image_exif_warning\">Atualmente, o formato %1$s só permite a leitura de metadados EXIF no Android. A imagem de saída não terá metadados quando salva.</string>\n    <string name=\"effort\">Esforço</string>\n    <string name=\"effort_sub\">Um valor %1$s significa uma compactação rápida, resultando em um tamanho de arquivo relativamente grande. %2$s significa uma compactação mais lenta, resultando em um arquivo menor.</string>\n    <string name=\"wait\">Espere</string>\n    <string name=\"saving_almost_complete\">Salvando quase completo. Cancelar agora exigirá salvar novamente.</string>\n    <string name=\"updates\">Atualizações</string>\n    <string name=\"allow_betas\">Permitir versões beta</string>\n    <string name=\"allow_betas_sub\">A verificação de atualização incluirá versões beta do aplicativo, se ativada</string>\n    <string name=\"draw_arrows\">Desenhar setas</string>\n    <string name=\"draw_arrows_sub\">Se ativado, o caminho do desenho serárepresentado como uma seta apontando</string>\n    <string name=\"brush_softness\">Suavidade do pincel</string>\n    <string name=\"crop_description\">As imagens serão cortadas no centro no tamanho inserido. A tela será expandida com determinada cor de fundo se a imagem for menor que as dimensões inseridas.</string>\n    <string name=\"donation\">Doação</string>\n    <string name=\"image_stitching\">Costura de Imagens</string>\n    <string name=\"image_stitching_sub\">Combine as imagens fornecidas para obter uma grande</string>\n    <string name=\"pick_at_least_two_images\">Escolha pelo menos 2 imagens</string>\n    <string name=\"output_image_scale\">Escala da imagem de saída</string>\n    <string name=\"image_orientation\">Orientação da imagem</string>\n    <string name=\"horizontal\">Horizontal</string>\n    <string name=\"vertical\">Vertical</string>\n    <string name=\"scale_small_images_to_large\">Dimensione imagens pequenas para grandes</string>\n    <string name=\"scale_small_images_to_large_sub\">Imagens pequenas serão dimensionadas para a maior na sequência, se habilitadas</string>\n    <string name=\"images_order\">Ordem das imagens</string>\n    <string name=\"regular\">Regular</string>\n    <string name=\"blur_edges\">Desfocar bordas</string>\n    <string name=\"blur_edges_sub\">Desenha bordas desfocadas sob a imagem original para preencher espaços ao redor dela em vez de cor única, se ativado</string>\n    <string name=\"pixelation\">Pixelização</string>\n    <string name=\"enhanced_pixelation\">Pixelização aprimorada</string>\n    <string name=\"stroke_pixelation\">Pixelização de traços</string>\n    <string name=\"enhanced_diamond_pixelation\">Pixelização de diamante aprimorada</string>\n    <string name=\"diamond_pixelation\">Pixelização de diamante</string>\n    <string name=\"circle_pixelation\">Pixelização do Círculo</string>\n    <string name=\"enhanced_circle_pixelation\">Pixelização de círculo aprimorada</string>\n    <string name=\"replace_color\">Substituir cor</string>\n    <string name=\"tolerance\">Tolerância</string>\n    <string name=\"color_to_replace\">Cor para substituir</string>\n    <string name=\"target_color\">Cor alvo</string>\n    <string name=\"color_to_remove\">Cor para remover</string>\n    <string name=\"remove_color\">Remover cor</string>\n    <string name=\"recode\">Recodificar</string>\n    <string name=\"pixel_size\">Tamanho dos pixels</string>\n    <string name=\"lock_draw_orientation\">Bloquear orientação em desenhos</string>\n    <string name=\"lock_draw_orientation_sub\">Se ativado no modo de desenho, a tela não gira</string>\n    <string name=\"check_for_updates\">Buscar atualizações</string>\n    <string name=\"palette_style\">Estilo de paleta</string>\n    <string name=\"tonal_spot\">Ponto Tonal</string>\n    <string name=\"neutral\">Neutro</string>\n    <string name=\"vibrant\">Vibrante</string>\n    <string name=\"expressive\">Expressivo</string>\n    <string name=\"rainbow\">Arco-íris</string>\n    <string name=\"fruit_salad\">Salada de Frutas</string>\n    <string name=\"fidelity\">Fidelidade</string>\n    <string name=\"content\">Contente</string>\n    <string name=\"tonal_spot_sub\">Estilo de paleta padrão, permite personalizar todas as quatro cores, outros permitem definir apenas a cor principal</string>\n    <string name=\"neutral_sub\">Um estilo um pouco mais cromático do que monocromático</string>\n    <string name=\"vibrant_sub\">Um tema barulhento, o colorido é máximo para a paleta Primária, aumentado para outras</string>\n    <string name=\"playful_scheme\">Um tema divertido – a tonalidade da cor de origem não aparece no tema</string>\n    <string name=\"monochrome_sub\">Um tema monocromático, as cores são puramente preto/branco/cinza</string>\n    <string name=\"content_sub\">Um esquema que coloca a cor de origem em Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Um esquema muito semelhante ao esquema de conteúdo</string>\n    <string name=\"foss_update_checker_warning\">Este verificador de atualização se conectará ao GitHub para verificar se há uma nova atualização disponível</string>\n    <string name=\"attention\">Atenção</string>\n    <string name=\"fading_edges\">Bordas desbotadas</string>\n    <string name=\"disabled\">Desabilitado</string>\n    <string name=\"both\">Ambos</string>\n    <string name=\"invert_colors\">Cores invertidas</string>\n    <string name=\"invert_colors_sub\">Substitui as cores do tema por cores negativas, se ativado</string>\n    <string name=\"search_option\">Procurar</string>\n    <string name=\"search_option_sub\">Permite a capacidade de pesquisar por todas as ferramentas disponíveis na tela principal</string>\n    <string name=\"pdf_tools\">Ferramentas de PDF</string>\n    <string name=\"pdf_tools_sub\">Opere com arquivos PDF: visualize, converta em lote de imagens ou crie um a partir de determinadas imagens</string>\n    <string name=\"preview_pdf\">Pré-visualização PDF</string>\n    <string name=\"pdf_to_images\">PDF para imagens</string>\n    <string name=\"images_to_pdf\">Imagens para PDF</string>\n    <string name=\"preview_pdf_sub\">Pré-visualização simples de PDF</string>\n    <string name=\"pdf_to_images_sub\">Converta PDF em imagens em determinado formato de saída</string>\n    <string name=\"images_to_pdf_sub\">Empacote as imagens fornecidas no arquivo PDF de saída</string>\n    <string name=\"mask_filter\">Filtro de máscara</string>\n    <string name=\"mask_filter_sub\">Aplicar cadeias de filtros em determinadas áreas mascaradas; cada área de máscara pode determinar seu próprio conjunto de filtros</string>\n    <string name=\"masks\">Máscaras</string>\n    <string name=\"add_mask\">Adicionar máscara</string>\n    <string name=\"mask_indexed\">Máscara %d</string>\n    <string name=\"mask_color\">Cor da máscara</string>\n    <string name=\"mask_preview\">Prévia da máscara</string>\n    <string name=\"mask_preview_sub\">A máscara de filtro desenhada será renderizada para mostrar o resultado aproximado</string>\n    <string name=\"inverse_fill_type\">Tipo de preenchimento inverso</string>\n    <string name=\"inverse_fill_type_sub\">Se ativado todas as áreas sem máscara serão filtradas no lugar do comportamento predefinido</string>\n    <string name=\"delete_mask_warn\">Você está prestes a excluir a máscara de filtro selecionada. Esta operação não pode ser desfeita</string>\n    <string name=\"delete_mask\">Excluir máscara</string>\n    <string name=\"full_filter\">Filtro Total</string>\n    <string name=\"full_filter_sub\">Aplique um conjunto de filtro à determinadas imagens ou à uma única imagem</string>\n    <string name=\"start_position\">Início</string>\n    <string name=\"center_position\">Centro</string>\n    <string name=\"end_position\">Fim</string>\n    <string name=\"simple_variants\">Variantes Simples</string>\n    <string name=\"highlighter\">Marcador</string>\n    <string name=\"neon\">Néon</string>\n    <string name=\"pen\">Caneta</string>\n    <string name=\"privacy_blur\">Desfoque de privacidade</string>\n    <string name=\"highlighter_sub\">Desenhe caminhos de realce nítidos e semitransparentes</string>\n    <string name=\"neon_sub\">Adicione algum efeito brilhante aos seus desenhos</string>\n    <string name=\"pen_sub\">Padrão, mais simples - apenas a cor</string>\n    <string name=\"privacy_blur_sub\">Desfoca a imagem sob o caminho desenhado para proteger tudo o que você deseja ocultar</string>\n    <string name=\"pixelation_sub\">Semelhante ao desfoque de privacidade, mas pixeliza em vez de desfocar</string>\n    <string name=\"containers_shadow\">Containers</string>\n    <string name=\"containers_shadow_sub\">Desenhe uma sombra atrás dos contêineres</string>\n    <string name=\"sliders_shadow\">Controles deslizantes</string>\n    <string name=\"switches_shadow\">Comuta</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">Botões</string>\n    <string name=\"sliders_shadow_sub\">Desenhar uma sombra atrás dos controles deslizantes</string>\n    <string name=\"switches_shadow_sub\">Desenhe uma sombra atrás dos interruptores</string>\n    <string name=\"fabs_shadow_sub\">Desenhar uma sombra atrás dos botões de ação flutuantes</string>\n    <string name=\"buttons_shadow_sub\">Desenhar uma sombra atrás dos botões</string>\n    <string name=\"app_bars_shadow\">Barras do app</string>\n    <string name=\"app_bars_shadow_sub\">Desenhe uma sombra atrás das barras do app</string>\n    <string name=\"value_in_range\">Valor no intervalo %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Auto rotação</string>\n    <string name=\"auto_rotate_limits_sub\">Permite que a caixa limite seja adotada para orientação da imagem</string>\n    <string name=\"draw_path_mode\">Modo Desenhar Caminho</string>\n    <string name=\"double_line_arrow\">Seta de linha dupla</string>\n    <string name=\"free_drawing\">Desenho Livre</string>\n    <string name=\"double_arrow\">Seta Dupla</string>\n    <string name=\"line_arrow\">Seta de linha</string>\n    <string name=\"arrow\">Seta</string>\n    <string name=\"line\">Linha</string>\n    <string name=\"free_drawing_sub\">Desenha o caminho como valor de entrada</string>\n    <string name=\"line_sub\">Desenha o caminho do ponto inicial ao ponto final como uma linha</string>\n    <string name=\"line_arrow_sub\">Desenha uma seta apontando do ponto inicial ao ponto final como uma linha</string>\n    <string name=\"arrow_sub\">Desenha uma seta apontando a partir de um determinado caminho</string>\n    <string name=\"double_line_arrow_sub\">Desenha uma seta dupla apontando do ponto inicial ao ponto final como uma linha</string>\n    <string name=\"double_arrow_sub\">Desenha uma seta dupla apontando de um determinado caminho</string>\n    <string name=\"outlined_oval\">Oval delineado</string>\n    <string name=\"outlined_rect\">Reto delineado</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Reto</string>\n    <string name=\"rect_sub\">Desenha um retângulo do ponto inicial ao ponto final</string>\n    <string name=\"oval_sub\">Desenha uma forma oval do ponto inicial ao ponto final</string>\n    <string name=\"outlined_oval_sub\">Desenha um contorno oval do ponto inicial ao ponto final</string>\n    <string name=\"outlined_rect_sub\">Desenha um retângulo delineado do ponto inicial ao ponto final</string>\n    <string name=\"lasso\">Laço</string>\n    <string name=\"lasso_sub\">Desenha um caminho preenchido fechado por um determinado caminho</string>\n    <string name=\"free\">Livre</string>\n    <string name=\"horizontal_grid\">Grade horizontal</string>\n    <string name=\"vertical_grid\">Grade Vertical</string>\n    <string name=\"stitch_mode\">Modo de costura</string>\n    <string name=\"rows_count\">Contagem de linhas</string>\n    <string name=\"columns_count\">Contagem de colunas</string>\n    <string name=\"no_such_directory\">Nenhum diretório \\\"%1$s\\\" encontrado, mudamos para o padrão, salve o arquivo novamente</string>\n    <string name=\"clipboard\">Área de transferência</string>\n    <string name=\"auto_pin\">Fixação automática</string>\n    <string name=\"auto_pin_sub\">Adiciona automaticamente a imagem salva à área de transferência, se ativado</string>\n    <string name=\"vibration\">Vibração</string>\n    <string name=\"vibration_strength\">Força de vibração</string>\n    <string name=\"overwrite_file_requirements\">Para substituir arquivos, você precisa usar a fonte de imagem Explorer, tente repickar imagens, alteramos a fonte da imagem para a necessária</string>\n    <string name=\"overwrite_files\">Substituir arquivos</string>\n    <string name=\"overwrite_files_sub\">O arquivo original será substituído por um novo ao invés de salvar na pasta selecionada, esta opção precisa que a fonte da imagem seja \\\"Explorer\\\" ou GetContent, ao alternar esta opção, ela será definida automaticamente</string>\n    <string name=\"empty\">Vazio</string>\n    <string name=\"suffix\">Sufixo</string>\n    <string name=\"scale_mode\">Modo de escala</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicúbico</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Eremita</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Mais próximo</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Básico</string>\n    <string name=\"default_value\">Valor padrão</string>\n    <string name=\"bilinear_sub\">A interpolação linear (ou bilinear, em duas dimensões) normalmente é boa para alterar o tamanho de uma imagem, mas causa alguma suavização indesejável de detalhes e ainda pode ser um tanto irregular</string>\n    <string name=\"bicubic_sub\">Melhores métodos de dimensionamento incluem reamostragem Lanczos e filtros Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Uma das maneiras mais simples de aumentar o tamanho, substituindo cada pixel por um número de pixels da mesma cor</string>\n    <string name=\"basic_sub\">Modo de escalabilidade Android mais simples usado em quase todos os aplicativos</string>\n    <string name=\"catmull_sub\">Método para interpolar e reamostrar suavemente um conjunto de pontos de controle, comumente usado em computação gráfica para criar curvas suaves</string>\n    <string name=\"hann_sub\">Função de janelamento frequentemente aplicada no processamento de sinal para minimizar o vazamento espectral e melhorar a precisão da análise de frequência, afunilando as bordas de um sinal</string>\n    <string name=\"hermite_sub\">Técnica de interpolação matemática que utiliza os valores e derivadas nas extremidades de um segmento de curva para gerar uma curva suave e contínua</string>\n    <string name=\"lanczos_sub\">Método de reamostragem que mantém interpolação de alta qualidade aplicando uma função sinc ponderada aos valores de pixel</string>\n    <string name=\"mitchell_sub\">Método de resampling que usa um filtro de convolução com parâmetros ajustáveis para alcançar um equilíbrio entre nitidez e suavização na imagem dimensionada</string>\n    <string name=\"spline_sub\">Usa funções polinomiais definidas por partes para interpolar e aproximar suavemente uma curva ou superfície, proporcionando uma representação flexível e contínua da forma</string>\n    <string name=\"only_clip\">Apenas clipe</string>\n    <string name=\"only_clip_sub\">O salvamento no armazenamento não será executado e a imagem será tentada apenas para ser colocada na área de transferência</string>\n    <string name=\"restore_background_sub\">O pincel irá restaurar o fundo em vez de apagar</string>\n    <string name=\"recognize_text\">OCR (reconhecer texto)</string>\n    <string name=\"recognize_text_sub\">Reconhecer texto de determinada imagem, mais de 120 idiomas suportados</string>\n    <string name=\"picture_has_no_text\">A imagem não tem texto ou o app não a encontrou</string>\n    <string name=\"accuracy\">Precisão: %1$s</string>\n    <string name=\"recognition_type\">Tipo de reconhecimento</string>\n    <string name=\"fast\">Rápido</string>\n    <string name=\"standard\">Padrão</string>\n    <string name=\"best\">Melhor</string>\n    <string name=\"no_data\">Sem dados</string>\n    <string name=\"download_description\">Para o funcionamento adequado do Tesseract OCR, dados de treinamento adicionais (%1$s) precisam ser baixados para o seu dispositivo.\\nDeseja baixar dados de %2$s?</string>\n    <string name=\"download\">Download</string>\n    <string name=\"no_connection\">Sem conexão, verifique e tente novamente para baixar modelos de trem</string>\n    <string name=\"downloaded_languages\">Idiomas baixados</string>\n    <string name=\"available_languages\">idiomas disponíveis</string>\n    <string name=\"segmentation_mode\">Modo de segmentação</string>\n    <string name=\"use_pixel_switch\">Use a troca de pixels</string>\n    <string name=\"use_pixel_switch_sub\">Usa um interruptor semelhante ao do Google Pixel</string>\n    <string name=\"saved_to_original\">Arquivo sobrescrito com nome %1$s no destino original</string>\n    <string name=\"magnifier\">Lupa</string>\n    <string name=\"magnifier_sub\">Ativa a lupa na parte superior do dedo nos modos de desenho para melhor acessibilidade</string>\n    <string name=\"force_exif_widget_initial_value\">Forçar valor inicial</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Força o widget exif a ser verificado inicialmente</string>\n    <string name=\"allow_multiple_languages\">Permitir vários idiomas</string>\n    <string name=\"slide\">Deslizar</string>\n    <string name=\"side_by_side\">Lado a lado</string>\n    <string name=\"toggle_tap\">Alternar Toque</string>\n    <string name=\"transparency\">Transparência</string>\n    <string name=\"rate_app\">Avaliar aplicativo</string>\n    <string name=\"rate\">Avaliar</string>\n    <string name=\"rate_app_sub\">Este aplicativo é totalmente gratuito, se você quiser que ele fique maior, marque o projeto com estrela no Github 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Orientação e Somente detecção de script</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientação automática e Detecção de script</string>\n    <string name=\"segmentation_mode_auto_only\">Somente automático</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_column\">Coluna Única</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Texto vertical em bloco único</string>\n    <string name=\"segmentation_mode_single_block\">Bloco único</string>\n    <string name=\"segmentation_mode_single_line\">Única linha</string>\n    <string name=\"segmentation_mode_single_word\">Única palavra</string>\n    <string name=\"segmentation_mode_circle_word\">Palavra circular</string>\n    <string name=\"segmentation_mode_single_char\">Caractere único</string>\n    <string name=\"segmentation_mode_sparse_text\">Texto esparso</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Orientação e texto esparso. Detecção de script</string>\n    <string name=\"segmentation_mode_raw_line\">Linha bruta</string>\n    <string name=\"delete_language_sub\">Deseja excluir os dados de treinamento de OCR do idioma \\\"%1$s\\\" para todos os tipos de reconhecimento ou apenas para um selecionado (%2$s)?</string>\n    <string name=\"current\">Atual</string>\n    <string name=\"all\">Todos</string>\n    <string name=\"gradient_maker\">Criador de Gradiente</string>\n    <string name=\"gradient_maker_sub\">Crie gradiente de determinado tamanho de saída com cores e tipo de aparência personalizados</string>\n    <string name=\"gradient_type_linear\">Linear</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Varrer</string>\n    <string name=\"gradient_type\">Tipo de gradiente</string>\n    <string name=\"center_x\">Centro (horizontal)</string>\n    <string name=\"center_y\">Centro (vertical)</string>\n    <string name=\"tile_mode\">Modo lado a lado</string>\n    <string name=\"tile_mode_repeated\">Repetido</string>\n    <string name=\"tile_mode_mirror\">Espelho</string>\n    <string name=\"tile_mode_clamp\">Braçadeira</string>\n    <string name=\"tile_mode_decal\">Decalque</string>\n    <string name=\"color_stops\">Paradas de cores</string>\n    <string name=\"add_color\">Adicionar cor</string>\n    <string name=\"properties\">Propriedades</string>\n    <string name=\"brightness_enforcement\">Aplicação de Brilho</string>\n    <string name=\"screen\">Tela</string>\n    <string name=\"gradient_maker_type_image\">Sobreposição de Gradiente</string>\n    <string name=\"gradient_maker_type_image_sub\">Componha qualquer gradiente por cima de determinadas imagens</string>\n    <string name=\"transformations\">Transformações</string>\n    <string name=\"camera\">Câmera</string>\n    <string name=\"camera_sub\">Tirar uma foto com uma câmera. Observe que é possível obter apenas uma imagem dessa fonte de imagem</string>\n    <string name=\"watermarking\">Marca d\\'água</string>\n    <string name=\"watermarking_sub\">Cubra as fotos com marcas d’água de texto/imagem personalizáveis</string>\n    <string name=\"repeat_watermark\">Repetir marca d\\'água</string>\n    <string name=\"repeat_watermark_sub\">Repete a marca d\\'água na imagem em vez de uma única em determinada posição</string>\n    <string name=\"offset_x\">Deslocamento (horizontal)</string>\n    <string name=\"offset_y\">Deslocamento (vertical)</string>\n    <string name=\"watermark_type\">Tipo de marca d\\'água</string>\n    <string name=\"watermarking_image_sub\">Esta imagem será usada como padrão para marca d\\'água</string>\n    <string name=\"text_color\">Cor do texto</string>\n    <string name=\"overlay_mode\">Modo de sobreposição</string>\n    <string name=\"gif_tools\">Ferramentas GIF</string>\n    <string name=\"gif_tools_sub\">Converta imagens em imagens GIF ou extraia quadros de uma determinada imagem GIF</string>\n    <string name=\"gif_type_to_image\">GIF para imagens</string>\n    <string name=\"gif_type_to_image_sub\">Converta arquivo GIF em lote de fotos</string>\n    <string name=\"gif_type_to_gif_sub\">Converta lote de imagens em arquivo GIF</string>\n    <string name=\"gif_type_to_gif\">Imagens para GIF</string>\n    <string name=\"select_gif_image_to_start\">Escolha a imagem GIF para começar</string>\n    <string name=\"use_size_of_first_frame\">Use o tamanho do primeiro quadro</string>\n    <string name=\"use_size_of_first_frame_sub\">Substitua o tamanho especificado pelas dimensões do primeiro quadro</string>\n    <string name=\"repeat_count\">Repetir contagem</string>\n    <string name=\"frame_delay\">Atraso de quadro</string>\n    <string name=\"millis\">milissegundos</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Usar laço</string>\n    <string name=\"use_lasso_sub\">Usa Lasso como no modo de desenho para apagar</string>\n    <string name=\"original_image_preview_alpha\">Pré-visualização da imagem original alfa</string>\n    <string name=\"confetti\">Confete</string>\n    <string name=\"confetti_sub\">Confetti será mostrado ao salvar, compartilhar e outras ações primárias</string>\n    <string name=\"secure_mode\">Modo Seguro</string>\n    <string name=\"secure_mode_sub\">Oculta o conteúdo do aplicativo em aplicativos recentes. Ele não pode ser capturado ou gravado.</string>\n    <string name=\"exit\">Sair</string>\n    <string name=\"preview_closing\">Se você sair da visualização agora, será necessário adicionar as imagens novamente</string>\n    <string name=\"dithering\">Pontilhamento</string>\n    <string name=\"quantizier\">Quantizador</string>\n    <string name=\"gray_scale\">Escala de Cinza</string>\n    <string name=\"bayer_two_dithering\">Bayer dois por dois pontilhamento</string>\n    <string name=\"bayer_three_dithering\">Bayer três por três hesitação</string>\n    <string name=\"bayer_four_dithering\">Bayer quatro por quatro hesitação</string>\n    <string name=\"bayer_eight_dithering\">Bayer oito por oito pontilhamento</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg hesitante</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke hesitante</string>\n    <string name=\"sierra_dithering\">Sierra hesitante</string>\n    <string name=\"two_row_sierra_dithering\">Pontilhamento Sierra de duas fileiras</string>\n    <string name=\"sierra_lite_dithering\">Pontilhamento Sierra Lite</string>\n    <string name=\"atkinson_dithering\">Atkinson hesitante</string>\n    <string name=\"stucki_dithering\">Stucki hesitante</string>\n    <string name=\"burkes_dithering\">Ruído Burkes</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falsa hesitação de Floyd Steinberg</string>\n    <string name=\"left_to_right_dithering\">Pontilhamento da esquerda para a direita</string>\n    <string name=\"random_dithering\">Pontilhamento aleatório</string>\n    <string name=\"simple_threshold_dithering\">Dithering de limite simples</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma Espacial</string>\n    <string name=\"median_blur\">Desfoque mediano</string>\n    <string name=\"b_spline\">Estria B</string>\n    <string name=\"b_spline_sub\">Utiliza funções polinomiais bicúbicas definidas por partes para interpolar e aproximar suavemente uma curva ou superfície, representação de forma flexível e contínua</string>\n    <string name=\"native_stack_blur\">Desfoque de pilha nativo</string>\n    <string name=\"tilt_shift\">Mudança de inclinação</string>\n    <string name=\"glitch\">Falha</string>\n    <string name=\"amount\">Quantia</string>\n    <string name=\"seed\">Semente</string>\n    <string name=\"anaglyph\">Anáglifo</string>\n    <string name=\"noise\">Barulho</string>\n    <string name=\"pixel_sort\">Classificação de pixels</string>\n    <string name=\"shuffle\">Aleatório</string>\n    <string name=\"enhanced_glitch\">Falha aprimorada</string>\n    <string name=\"channel_shift_x\">Mudança de canal (horizontal)</string>\n    <string name=\"channel_shift_y\">Mudança de canal (vertical)</string>\n    <string name=\"corruption_size\">Tamanho da corrupção</string>\n    <string name=\"corruption_shift_x\">Mudança de Corrupção (horizontal)</string>\n    <string name=\"corruption_shift_y\">Mudança de Corrupção (vertical)</string>\n    <string name=\"tent_blur\">Desfoque de barraca</string>\n    <string name=\"side_fade\">Desbotamento lateral</string>\n    <string name=\"side\">Lado</string>\n    <string name=\"top\">Principal</string>\n    <string name=\"bottom\">Fundo</string>\n    <string name=\"strength\">Força</string>\n    <string name=\"erode\">Erodir</string>\n    <string name=\"anisotropic_diffusion\">Difusão Anisotrópica</string>\n    <string name=\"diffusion\">Difusão</string>\n    <string name=\"conduction\">Condução</string>\n    <string name=\"horizontal_wind_stagger\">Escalonamento de Vento Horizontal</string>\n    <string name=\"fast_bilaterial_blur\">Desfoque bilateral rápido</string>\n    <string name=\"poisson_blur\">Desfoque Poisson</string>\n    <string name=\"logarithmic_tone_mapping\">Mapeamento logarítmico de tons</string>\n    <string name=\"aces_filmic_tone_mapping\">Mapeamento de tons fílmicos ACES</string>\n    <string name=\"crystallize\">Cristalizar</string>\n    <string name=\"stroke_color\">Cor do traço</string>\n    <string name=\"fractal_glass\">Vidro fractal</string>\n    <string name=\"amplitude\">Amplitude</string>\n    <string name=\"marble\">Mármore</string>\n    <string name=\"turbulence\">Turbulência</string>\n    <string name=\"oil\">Óleo</string>\n    <string name=\"water_effect\">Efeito Água</string>\n    <string name=\"just_size\">Tamanho</string>\n    <string name=\"frequency_x\">Frequência (horizontal)</string>\n    <string name=\"frequency_y\">Frequência (vertical)</string>\n    <string name=\"amplitude_x\">Amplitude (horizontal)</string>\n    <string name=\"amplitude_y\">Amplitude (vertical)</string>\n    <string name=\"perlin_distortion\">Distorção Perlin</string>\n    <string name=\"aces_hill_tone_mapping\">Mapeamento de tons de colina ACES</string>\n    <string name=\"hable_filmic_tone_mapping\">Mapeamento de tons fílmicos Hable</string>\n    <string name=\"heji_burgess_tone_mapping\">Mapeamento de Tons de Hejl Burgess</string>\n    <string name=\"speed\">Velocidade</string>\n    <string name=\"dehaze\">Desembaçar</string>\n    <string name=\"omega\">Ómega</string>\n    <string name=\"color_matrix_4x4\">Matriz de cores 4x4</string>\n    <string name=\"color_matrix_3x3\">Matriz de cores 3x3</string>\n    <string name=\"simple_effects\">Efeitos Simples</string>\n    <string name=\"polaroid\">Polaróide</string>\n    <string name=\"tritonomaly\">Tritanomalia</string>\n    <string name=\"deutaromaly\">Deuteranomalia</string>\n    <string name=\"protonomaly\">Protanomalia</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Brownie</string>\n    <string name=\"coda_chrome\">Coda Cromo</string>\n    <string name=\"night_vision\">Visão noturna</string>\n    <string name=\"warm\">Esquentar</string>\n    <string name=\"cool\">Legal</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Acromatomia</string>\n    <string name=\"achromatopsia\">Acromatopsia</string>\n    <string name=\"grain\">Grão</string>\n    <string name=\"unsharp\">Não nitidez</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Névoa Laranja</string>\n    <string name=\"pink_dream\">Sonho Rosa</string>\n    <string name=\"golden_hour\">Hora dourada</string>\n    <string name=\"hot_summer\">Verão quente</string>\n    <string name=\"purple_mist\">Névoa Roxa</string>\n    <string name=\"sunrise\">Nascer do sol</string>\n    <string name=\"colorful_swirl\">Redemoinho Colorido</string>\n    <string name=\"soft_spring_light\">Luz suave de primavera</string>\n    <string name=\"autumn_tones\">Tons de outono</string>\n    <string name=\"lavender_dream\">Sonho Lavanda</string>\n    <string name=\"cyberpunk\">Ciberpunk</string>\n    <string name=\"lemonade_light\">Limonada Light</string>\n    <string name=\"spectral_fire\">Fogo Espectral</string>\n    <string name=\"night_magic\">Magia Noturna</string>\n    <string name=\"fantasy_landscape\">Paisagem Fantástica</string>\n    <string name=\"color_explosion\">Explosão de cores</string>\n    <string name=\"electric_gradient\">Gradiente Elétrico</string>\n    <string name=\"caramel_darkness\">Escuridão Caramelo</string>\n    <string name=\"futuristic_gradient\">Gradiente Futurista</string>\n    <string name=\"green_sun\">Sol Verde</string>\n    <string name=\"rainbow_world\">Mundo Arco-Íris</string>\n    <string name=\"deep_purple\">Roxo profundo</string>\n    <string name=\"space_portal\">Portal Espacial</string>\n    <string name=\"red_swirl\">Redemoinho Vermelho</string>\n    <string name=\"digital_code\">Código digital</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">O emoji da barra do aplicativo irá mudar aleatoriamente</string>\n    <string name=\"random_emojis\">Emojis Aleatórios</string>\n    <string name=\"random_emojis_error\">Não é possível usar emojis aleatórios enquanto os emojis estiverem desativados</string>\n    <string name=\"emoji_selection_error\">Não é possível selecionar um emoji enquanto os emojis aleatórios estiverem ativados</string>\n    <string name=\"old_tv\">TV Antiga</string>\n    <string name=\"shuffle_blur\">Desfoque aleatório</string>\n    <string name=\"favorite\">Favorito</string>\n    <string name=\"no_favorite_filters\">Nenhum filtro favorito adicionado</string>\n    <string name=\"image_format\">Formato de imagem</string>\n    <string name=\"icon_shape_sub\">Adiciona um contêiner com a forma selecionada sob os ícones</string>\n    <string name=\"icon_shape\">Formato dos Ícones</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Cortar</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Móbius</string>\n    <string name=\"transition\">Transição</string>\n    <string name=\"peak\">Pico</string>\n    <string name=\"color_anomaly\">Anomalia de cor</string>\n    <string name=\"images_overwritten\">Imagens substituídas no destino original</string>\n    <string name=\"cannot_change_image_format\">Não é possível alterar o formato da imagem enquanto a opção sobrescrever arquivos está ativada</string>\n    <string name=\"emoji_as_color_scheme\">Emoji como esquema de cores</string>\n    <string name=\"emoji_as_color_scheme_sub\">Usa cor primária emoji como esquema de cores do aplicativo em vez de um definido manualmente</string>\n    <string name=\"material_you_sub\">Cria paleta \\\"Material You\\\" a partir da imagem</string>\n    <string name=\"dark_colors\">Cores Escuras</string>\n    <string name=\"dark_colors_sub\">Usa o esquema de cores do modo noturno em vez da variante de luz</string>\n    <string name=\"copy_as_compose_code\">Copiar como código \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Desfoque Anel</string>\n    <string name=\"cross_blur\">Desfoque Cruz</string>\n    <string name=\"star_blur\">Desfoque Estrela</string>\n    <string name=\"linear_tilt_shift\">Mudança de Inclinação Linear</string>\n    <string name=\"circle_blur\">Desfoque Circular</string>\n    <string name=\"tags_to_remove\">Tags a remover</string>\n    <string name=\"apng_type_to_image\">APNG para imagens</string>\n    <string name=\"select_apng_image_to_start\">Escolher imagem APNG para iniciar</string>\n    <string name=\"motion_blur\">Desfoque de movimento</string>\n    <string name=\"apng_tools_sub\">Converter imagens em imagem APNG ou extrair quadros de determinada imagem APNG</string>\n    <string name=\"apng_type_to_apng\">Imagens para APNG</string>\n    <string name=\"apng_tools\">Ferramentas APNG</string>\n    <string name=\"apng_type_to_image_sub\">Converta arquivo APNG em lote de fotos</string>\n    <string name=\"apng_type_to_apng_sub\">Converter lote de imagens em arquivo APNG</string>\n    <string name=\"zip_sub\">Crie um arquivo Zip a partir de determinados arquivos ou imagens</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"drag_handle_width\">Largura da alça de arrastar</string>\n    <string name=\"confetti_type\">Tipo de Confete</string>\n    <string name=\"festive\">Festivo</string>\n    <string name=\"explode\">Explosão</string>\n    <string name=\"rain\">Chuva</string>\n    <string name=\"jxl_type_to_jpeg\">JXL para JPEG</string>\n    <string name=\"jxl_tools\">Ferramentas JXL</string>\n    <string name=\"jxl_tools_sub\">Executar conversão JXL ~ JPEG sem perda de qualidade ou converta GIF/APNG em animação JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG para JXL</string>\n    <string name=\"select_jxl_image_to_start\">Escolha a imagem JXL para começar</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Executando conversão sem perdas de JXL para JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Executando conversão sem perdas de JPEG para JXL</string>\n    <string name=\"fast_gaussian_blur_2d\">Desfoque rápido Gaussiano 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Desfoque rápido Gaussiano 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Desfoque rápido Gaussiano 4D</string>\n    <string name=\"auto_paste_sub\">Permite que o aplicativo cole automaticamente os dados da área de transferência, para que apareçam na tela principal e você possa processá-los</string>\n    <string name=\"harmonization_color\">Cor de Harmonização</string>\n    <string name=\"harmonization_level\">Nível de Harmonização</string>\n    <string name=\"corners\">Cantos</string>\n    <string name=\"auto_paste\">Colar automaticamente</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"gif_type_to_jxl\">GIF para JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Converter imagens GIF em imagens animadas JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG para JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Converter imagens APNG em imagens animadas JXL</string>\n    <string name=\"jxl_type_to_images\">JXL para Imagens</string>\n    <string name=\"jxl_type_to_images_sub\">Converter animação JXL em lote de imagens</string>\n    <string name=\"jxl_type_to_jxl\">Imagens para JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Converter lote de imagens em animação JXL</string>\n    <string name=\"behavior\">Comportamento</string>\n    <string name=\"skip_file_picking\">Pular seleção de arquivos</string>\n    <string name=\"skip_file_picking_sub\">O seletor de arquivos será mostrado imediatamente se for possível na tela escolhida</string>\n    <string name=\"generate_previews\">Gerar visualizações</string>\n    <string name=\"lossy_compression\">Compressão com Perdas</string>\n    <string name=\"lanczos_bessel_sub\">Método de reamostragem que mantém interpolação de alta qualidade aplicando uma função Bessel (jinc) aos valores de pixel</string>\n    <string name=\"lossy_compression_sub\">Usa compactação \\\"com perdas\\\" para reduzir o tamanho do arquivo em vez de \\\"sem perdas\\\"</string>\n    <string name=\"generate_previews_sub\">Ativa a geração de visualização, o que pode ajudar a evitar travamentos em alguns dispositivos e também desativa algumas funcionalidades de edição na opção de edição única</string>\n    <string name=\"compression_type\">Tipo de compressão</string>\n    <string name=\"speed_sub\">Controla a velocidade de decodificação da imagem resultante, o que deve ajudar a abrir a imagem resultante mais rapidamente, o valor de %1$s significa a decodificação mais lenta, enquanto %2$s - a mais rápida, essa configuração pode aumentar o tamanho da imagem de saída</string>\n    <string name=\"sort_by_date\">Data</string>\n    <string name=\"sort_by_date_reversed\">Data (Inversa)</string>\n    <string name=\"sort_by_name\">Nome</string>\n    <string name=\"sort_by_name_reversed\">Nome (Inverso)</string>\n    <string name=\"sorting\">Ordenação</string>\n    <string name=\"channels_configuration\">Configuração de canais</string>\n    <string name=\"header_yesterday\">Ontem</string>\n    <string name=\"embedded_picker\">Seletor incorporado</string>\n    <string name=\"pick\">Escolha</string>\n    <string name=\"pick_multiple_media\">Escolha várias mídias</string>\n    <string name=\"pick_single_media\">Escolha uma mídia única</string>\n    <string name=\"embedded_picker_sub\">Seletor de imagens do nativo do Image Toolbox</string>\n    <string name=\"no_permissions\">Nenhuma permissão</string>\n    <string name=\"request\">Solicitação</string>\n    <string name=\"header_today\">Hoje</string>\n    <string name=\"try_again\">Tente novamente</string>\n    <string name=\"show_settings_in_landscape\">Mostrar configurações no modo paisagem</string>\n    <string name=\"show_settings_in_landscape_sub\">Se estiver desativado, as configurações do modo paisagem serão abertas no botão da barra superior do aplicativo, como sempre, em vez da opção visível permanente</string>\n    <string name=\"fullscreen_settings\">Configurações de tela cheia</string>\n    <string name=\"compose\">Compor</string>\n    <string name=\"switch_type\">Tipo de Interruptor</string>\n    <string name=\"fullscreen_settings_sub\">Ative-o e a página de configurações será sempre aberta em tela cheia, em vez da folha de gaveta deslizante</string>\n    <string name=\"material_you_switch_sub\">Um interruptor Material You</string>\n    <string name=\"compose_switch_sub\">Um interruptor Jetpack Material You</string>\n    <string name=\"max\">Máx</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"resize_anchor\">Redimensionar âncora</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">Um interruptor baseado no sistema de design \\\"Fluent\\\"</string>\n    <string name=\"cupertino_switch_sub\">Um interruptor baseado no sistema de design \\\"Cupertino\\\"</string>\n    <string name=\"images_to_svg\">Imagens para SVG</string>\n    <string name=\"images_to_svg_sub\">Rastrear imagens fornecidas em imagens SVG</string>\n    <string name=\"use_sampled_palette\">Usar paleta de amostra</string>\n    <string name=\"use_sampled_palette_sub\">A paleta de quantização será amostrada se esta opção estiver habilitada</string>\n    <string name=\"path_omit\">Caminho omitido</string>\n    <string name=\"svg_warning\">O uso desta ferramenta para rastrear imagens grandes sem redução de escala não é recomendado, pois pode causar travamento e aumentar o tempo de processamento</string>\n    <string name=\"downscale_image\">Imagem em escala reduzida</string>\n    <string name=\"downscale_image_sub\">A imagem será reduzida para dimensões inferiores antes do processamento, o que ajuda a ferramenta a trabalhar de forma mais rápida e segura</string>\n    <string name=\"min_color_ratio\">Proporção mínima de cores</string>\n    <string name=\"lines_threshold\">Limite de linhas</string>\n    <string name=\"quadratic_threshold\">Limite de quadros</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolerância de arredondamento de coordenadas</string>\n    <string name=\"path_scale\">Caminho de escala</string>\n    <string name=\"reset_properties\">Redefinir propriedades</string>\n    <string name=\"reset_properties_sub\">Todas as propriedades serão definidas com valores padrão, observe que esta ação não pode ser desfeita</string>\n    <string name=\"detailed\">Detalhado</string>\n    <string name=\"default_line_width\">Largura de linha padrão</string>\n    <string name=\"engine_mode\">Modo de Mecanismo</string>\n    <string name=\"legacy\">Legado</string>\n    <string name=\"lstm_network\">Rede LSTM</string>\n    <string name=\"legacy_and_lstm\">Legado &amp; LSTM</string>\n    <string name=\"convert_sub\">Converter lotes de imagens para determinado formato</string>\n    <string name=\"convert\">Converter</string>\n    <string name=\"tag_bits_per_sample\">Bits por amostra</string>\n    <string name=\"tag_compression\">Compressão</string>\n    <string name=\"tag_planar_configuration\">Configuração plana</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Subamostragem Cb Cr (vertical)</string>\n    <string name=\"tag_x_resolution\">Resolução (horizontal)</string>\n    <string name=\"tag_strip_offsets\">Deslocamentos da faixa</string>\n    <string name=\"tag_rows_per_strip\">Linhas por faixa</string>\n    <string name=\"tag_jpeg_interchange_format\">Formato de intercâmbio JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Comprimento do formato de intercâmbio JPEG</string>\n    <string name=\"tag_transfer_function\">Função de transferência</string>\n    <string name=\"tag_white_point\">Ponto Branco</string>\n    <string name=\"tag_primary_chromaticities\">Cromaticidades Primárias</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Coeficientes Cb Cr (vertical)</string>\n    <string name=\"add_new_folder\">Adicionar nova pasta</string>\n    <string name=\"tag_photometric_interpretation\">Interpretação fotométrica</string>\n    <string name=\"tag_samples_per_pixel\">Amostras por pixel</string>\n    <string name=\"tag_y_cb_cr_positioning\">Posicionamento Cb Cr (vertical)</string>\n    <string name=\"tag_y_resolution\">Resolução (vertical)</string>\n    <string name=\"tag_resolution_unit\">Unidade de Resolução</string>\n    <string name=\"tag_strip_byte_counts\">Tirar contagens de bytes</string>\n    <string name=\"tag_datetime\">Data Hora</string>\n    <string name=\"tag_image_description\">Descrição da imagem</string>\n    <string name=\"tag_make\">Criar</string>\n    <string name=\"tag_model\">Modelo</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_artist\">Artista</string>\n    <string name=\"tag_copyright\">Copyright</string>\n    <string name=\"tag_exif_version\">Versão Exif</string>\n    <string name=\"tag_color_space\">Espaço de Cores</string>\n    <string name=\"tag_gamma\">Gama</string>\n    <string name=\"tag_pixel_x_dimension\">Dimensão Pixel (horizontal)</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Bits compactados por pixel</string>\n    <string name=\"tag_maker_note\">Nota do fabricante</string>\n    <string name=\"tag_user_comment\">Comentário do usuário</string>\n    <string name=\"tag_related_sound_file\">Arquivo de som relacionado</string>\n    <string name=\"tag_datetime_original\">Data e hora original</string>\n    <string name=\"tag_datetime_digitized\">Data e hora digitalizada</string>\n    <string name=\"tag_offset_time\">Tempo de deslocamento</string>\n    <string name=\"tag_offset_time_original\">Tempo de deslocamento original</string>\n    <string name=\"tag_offset_time_digitized\">Tempo de deslocamento digitalizado</string>\n    <string name=\"tag_exposure_time\">Período de exposição</string>\n    <string name=\"tag_f_number\">Número F</string>\n    <string name=\"tag_exposure_program\">Programa de Exposição</string>\n    <string name=\"tag_spectral_sensitivity\">Sensibilidade Espectral</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Tipo de sensibilidade</string>\n    <string name=\"tag_standard_output_sensitivity\">Sensibilidade de saída padrão</string>\n    <string name=\"tag_recommended_exposure_index\">Índice de exposição recomendado</string>\n    <string name=\"tag_iso_speed\">Velocidade ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Latitude de velocidade ISO yyy</string>\n    <string name=\"tag_aperture_value\">Valor de abertura</string>\n    <string name=\"tag_brightness_value\">Valor de brilho</string>\n    <string name=\"tag_exposure_bias_value\">Valor de polarização de exposição</string>\n    <string name=\"tag_max_aperture_value\">Valor máximo de abertura</string>\n    <string name=\"tag_subject_distance\">Distância entre assuntos</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Velocidade ISO Latitude zzz</string>\n    <string name=\"tag_metering_mode\">Modo de medição</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Área da matéria</string>\n    <string name=\"tag_focal_length\">Comprimento focal</string>\n    <string name=\"tag_flash_energy\">Energia Flash</string>\n    <string name=\"tag_spatial_frequency_response\">Resposta de frequência espacial</string>\n    <string name=\"tag_focal_plane_x_resolution\">Resolução do plano focal (horizontal)</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Unidade de resolução do plano focal</string>\n    <string name=\"tag_subject_location\">Localização do assunto</string>\n    <string name=\"tag_exposure_index\">Índice de Exposição</string>\n    <string name=\"tag_sensing_method\">Método de detecção</string>\n    <string name=\"tag_file_source\">Fonte do arquivo</string>\n    <string name=\"tag_cfa_pattern\">Padrão CFA</string>\n    <string name=\"tag_custom_rendered\">Renderização personalizada</string>\n    <string name=\"tag_exposure_mode\">Modo de exposição</string>\n    <string name=\"tag_white_balance\">Balanço de branco</string>\n    <string name=\"tag_digital_zoom_ratio\">Taxa de zoom digital</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Filme de distância focal In35mm</string>\n    <string name=\"tag_scene_capture_type\">Tipo de captura de cena</string>\n    <string name=\"tag_gain_control\">Controle de ganho</string>\n    <string name=\"tag_contrast\">Contraste</string>\n    <string name=\"tag_saturation\">Saturação</string>\n    <string name=\"tag_sharpness\">Nitidez</string>\n    <string name=\"tag_device_setting_description\">Descrição da configuração do dispositivo</string>\n    <string name=\"tag_subject_distance_range\">Faixa de distância do assunto</string>\n    <string name=\"tag_image_unique_id\">ID exclusivo da imagem</string>\n    <string name=\"tag_camera_owner_name\">Nome do proprietário da câmera</string>\n    <string name=\"tag_body_serial_number\">Número de série do corpo</string>\n    <string name=\"tag_lens_make\">Marca da lente</string>\n    <string name=\"tag_lens_specification\">Especificação da lente</string>\n    <string name=\"tag_lens_model\">Modelo da lente</string>\n    <string name=\"tag_lens_serial_number\">Número de série da lente</string>\n    <string name=\"tag_gps_version_id\">ID da versão do GPS</string>\n    <string name=\"tag_gps_latitude\">Latitude do GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Referência de latitude do GPS</string>\n    <string name=\"tag_gps_longitude_ref\">Referência de longitude do GPS</string>\n    <string name=\"tag_gps_longitude\">Longitude do GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Referência de altitude do GPS</string>\n    <string name=\"tag_gps_altitude\">Altitude do GPS</string>\n    <string name=\"tag_gps_timestamp\">Data e hora do GPS</string>\n    <string name=\"tag_gps_satellites\">Satélites GPS</string>\n    <string name=\"tag_gps_status\">Status do GPS</string>\n    <string name=\"tag_gps_measure_mode\">Modo de medição do GPS</string>\n    <string name=\"tag_gps_speed_ref\">Referência de velocidade do GPS</string>\n    <string name=\"tag_gps_speed\">Velocidade do GPS</string>\n    <string name=\"tag_gps_track_ref\">Referência de rastreamento do GPS</string>\n    <string name=\"tag_gps_track\">Rastreamento do GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Referência de direção de imagem do GPS</string>\n    <string name=\"tag_gps_img_direction\">Direção de imagem do GPS</string>\n    <string name=\"tag_gps_map_datum\">Dados de mapa do GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Referência de latitude de destino do GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Latitude de destino do GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Referência de longitude de destino do GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Longitude de destino do GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Rolamento de destino do GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Referência de distância de destino do GPS</string>\n    <string name=\"tag_gps_dop\">DOP GPS</string>\n    <string name=\"tag_gps_dest_distance\">Distância de destino do GPS</string>\n    <string name=\"tag_gps_processing_method\">Método de processamento do GPS</string>\n    <string name=\"tag_gps_area_information\">Informações da área do GPS</string>\n    <string name=\"tag_gps_datestamp\">Data e hora do GPS</string>\n    <string name=\"tag_gps_differential\">Diferencial GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Erro de posicionamento H do GPS</string>\n    <string name=\"tag_interoperability_index\">Índice de interoperabilidade</string>\n    <string name=\"tag_dng_version\">Versão DNG</string>\n    <string name=\"tag_default_crop_size\">Tamanho de corte padrão</string>\n    <string name=\"tag_orf_preview_image_start\">Pré-visualizar início da imagem</string>\n    <string name=\"tag_orf_preview_image_length\">Pré-visualizar comprimento da imagem</string>\n    <string name=\"tag_orf_aspect_frame\">Aspecto de quadro</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Borda inferior do sensor</string>\n    <string name=\"tag_rw2_sensor_left_border\">Borda esquerda do sensor</string>\n    <string name=\"tag_rw2_sensor_right_border\">Borda direita do sensor</string>\n    <string name=\"tag_rw2_sensor_top_border\">Borda superior do sensor</string>\n    <string name=\"draw_text_sub\">Desenhe texto no caminho com determinada fonte e cor</string>\n    <string name=\"font_size\">Tamanho da fonte</string>\n    <string name=\"watermark_size\">Tamanho da marca d\\'água</string>\n    <string name=\"repeat_text\">Repetir texto</string>\n    <string name=\"repeat_text_sub\">O texto atual será repetido até o final do caminho, em vez de ser desenhado uma única vez</string>\n    <string name=\"dash_size\">Tamanho do traço</string>\n    <string name=\"draw_mode_image_sub\">Use a imagem selecionada para desenhá-la ao longo de um determinado caminho</string>\n    <string name=\"draw_image_sub\">Essa imagem será usada como entrada repetitiva do caminho desenhado</string>\n    <string name=\"triangle_sub\">Desenha um triângulo delineado do ponto inicial ao ponto final</string>\n    <string name=\"outlined_triangle\">Triângulo delineado</string>\n    <string name=\"triangle\">Triângulo</string>\n    <string name=\"polygon\">Polígono</string>\n    <string name=\"outlined_polygon\">Polígono delineado</string>\n    <string name=\"vertices\">Vínculos</string>\n    <string name=\"draw_regular_polygon\">Desenhar polígono regular</string>\n    <string name=\"draw_regular_polygon_sub\">Desenhe um polígono que será regular em vez de uma forma livre</string>\n    <string name=\"star_sub\">Desenha uma estrela do ponto inicial ao ponto final</string>\n    <string name=\"star\">Estrela</string>\n    <string name=\"outlined_star\">Estrela delineada</string>\n    <string name=\"outlined_star_sub\">Desenha uma estrela delineada do ponto inicial ao ponto final</string>\n    <string name=\"inner_radius_ratio\">Proporção do Raio Interno</string>\n    <string name=\"draw_regular_star\">Desenhar estrela regular</string>\n    <string name=\"draw_regular_star_sub\">Desenhe uma estrela que será regular em vez de uma forma livre</string>\n    <string name=\"antialias_sub\">Ativa o antialiasing para evitar bordas afiadas</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"tag_flashpix_version\">Versão Flashpix</string>\n    <string name=\"tag_pixel_y_dimension\">Dimensão Pixel (vertical)</string>\n    <string name=\"tag_photographic_sensitivity\">Sensibilidade Fotográfica</string>\n    <string name=\"tag_shutter_speed_value\">Valor da velocidade do obturador</string>\n    <string name=\"tag_focal_plane_y_resolution\">Resolução do plano focal (vertical)</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Referência do rolamento de destino do GPS</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"outlined_triangle_sub\">Desenha um triângulo delineado do ponto inicial ao ponto final</string>\n    <string name=\"tag_reference_black_white\">Referência Preto Branco</string>\n    <string name=\"polygon_sub\">Desenha o polígono do ponto inicial ao ponto final</string>\n    <string name=\"outlined_polygon_sub\">Desenha um polígono delineado do ponto inicial ao ponto final</string>\n    <string name=\"document_scanner\">Digitalizador de Documentos</string>\n    <string name=\"click_to_start_scanning\">Clique para iniciar a digitalização</string>\n    <string name=\"start_scanning\">Comece a digitalizar</string>\n    <string name=\"save_as_pdf\">Salvar como PDF</string>\n    <string name=\"share_as_pdf\">Compartilhar como PDF</string>\n    <string name=\"options_below_is_for_images\">As opções abaixo servem para salvar imagens, não PDF</string>\n    <string name=\"equalize_histogram_hsv\">Equalizar Histograma HSV</string>\n    <string name=\"equalize_histogram\">Equalizar Histograma</string>\n    <string name=\"document_scanner_sub\">Digitalize documentos e crie PDF ou separe imagens deles</string>\n    <string name=\"open_edit_instead_of_preview\">Abrir editor em vez da visualizar</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Quando você seleciona a imagem para abrir (visualizar) no ImageToolbox, a folha de seleção de edição será aberta em vez de visualizar</string>\n    <string name=\"tag_subsec_time\">Tempo sub-segundo</string>\n    <string name=\"tag_subsec_time_original\">Tempo sub-segundo original</string>\n    <string name=\"tag_subsec_time_digitized\">Tempo sub-segundo digitalizado</string>\n    <string name=\"enter_percentage\">Insira a porcentagem</string>\n    <string name=\"allow_enter_by_text_field\">Permitir entrada por campo de texto</string>\n    <string name=\"allow_enter_by_text_field_sub\">Ativa o campo de texto atrás da seleção de predefinições, para inseri-las instantaneamente</string>\n    <string name=\"linear\">Linear</string>\n    <string name=\"equalize_histogram_pixelation\">Equalizar pixelização do histograma</string>\n    <string name=\"scale_color_space\">Escalar Espaço de Cores</string>\n    <string name=\"grid_size_x\">Tamanho da grade (horizontal)</string>\n    <string name=\"grid_size_y\">Tamanho da grade (vertical)</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalizar Histograma Adaptive LAB</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"equalize_histogram_adaptive\">Equalizar histograma adaptativo</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Equalizar histograma LUV adaptativo</string>\n    <string name=\"crop_to_content\">Cortar para o Conteúdo</string>\n    <string name=\"color_to_ignore\">Cor a ser ignorada</string>\n    <string name=\"frame_color\">Cor da moldura</string>\n    <string name=\"template\">Modelo</string>\n    <string name=\"no_template_filters\">Nenhum filtro de modelo adicionado</string>\n    <string name=\"create_new\">Criar um novo</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">O código QR digitalizado não é um modelo de filtro válido</string>\n    <string name=\"scan_qr_code\">Digitalizar código QR</string>\n    <string name=\"opened_file_have_no_filter_template\">O arquivo selecionado não tem dados de modelo de filtro</string>\n    <string name=\"create_template\">Criar modelo</string>\n    <string name=\"template_name\">Nome do modelo</string>\n    <string name=\"select_template_preview\">Essa imagem será usada para visualizar esse modelo de filtro</string>\n    <string name=\"template_filter\">Filtro de modelo</string>\n    <string name=\"as_qr_code\">Como imagem de código QR</string>\n    <string name=\"as_file\">Como arquivo</string>\n    <string name=\"save_as_file\">Salvar como arquivo</string>\n    <string name=\"save_as_qr_code_image\">Salvar como imagem de código QR</string>\n    <string name=\"delete_template\">Excluir modelo</string>\n    <string name=\"delete_template_warn\">Você está prestes a excluir o filtro de modelo selecionado. Essa operação não pode ser desfeita</string>\n    <string name=\"added_filter_template\">Modelo de filtro adicionado com o nome \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Pré-visualização do filtro</string>\n    <string name=\"qr_code\">QR &amp; Barcode</string>\n    <string name=\"qr_code_sub\">Digitalize um código QR e obtenha seu conteúdo ou cole seu texto para gerar um código</string>\n    <string name=\"code_content\">Conteúdo do código</string>\n    <string name=\"scan_qr_code_to_replace_content\">Digitalize qualquer código de barras para substituir o conteúdo do campo ou digite algo para gerar um novo código de barras com o tipo selecionado</string>\n    <string name=\"qr_description\">Descrição do código QR</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Conceder permissão à câmara nas definições para digitalizar o código QR</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">A interpolação cúbica proporciona um dimensionamento mais suave ao considerar os 16 pixels mais próximos, proporcionando melhores resultados do que a interpolação bilinear</string>\n    <string name=\"bspline_sub\">Utiliza funções polinomiais definidas por partes para interpolar e aproximar suavemente uma curva ou superfície, representação de forma flexível e contínua</string>\n    <string name=\"hamming_sub\">Uma função de janela usada para reduzir o vazamento espectral, afinando as bordas de um sinal, útil no processamento de sinais</string>\n    <string name=\"hanning_sub\">Uma variante da janela de Hann, comumente usada para reduzir o vazamento espectral em aplicações de processamento de sinais</string>\n    <string name=\"blackman_sub\">Uma função de janela que fornece uma boa resolução de frequência ao minimizar o vazamento espectral, frequentemente usada no processamento de sinais</string>\n    <string name=\"welch_sub\">Uma função de janela projetada para oferecer boa resolução de frequência com vazamento espectral reduzido, geralmente usada em aplicações de processamento de sinais</string>\n    <string name=\"quadric_sub\">Um método que usa uma função quadrática para interpolação, fornecendo resultados suaves e contínuos</string>\n    <string name=\"gaussian_sub\">Um método de interpolação que aplica uma função gaussiana, útil para suavizar e reduzir o ruído em imagens</string>\n    <string name=\"robidoux_sub\">Um método de interpolação de alta qualidade otimizado para redimensionamento natural de imagens, equilibrando nitidez e suavidade</string>\n    <string name=\"spline16_sub\">Um método de interpolação baseado em spline que fornece resultados suaves usando um filtro de 16 toques</string>\n    <string name=\"spline36_sub\">Um método de interpolação baseado em spline que fornece resultados suaves usando um filtro de 36 toques</string>\n    <string name=\"box_sub\">Um método simples de reamostragem que usa a média dos valores de pixel mais próximos, geralmente resultando em uma aparência de blocos</string>\n    <string name=\"bohman_sub\">Uma função de janela usada para reduzir o vazamento espectral, proporcionando uma boa resolução de frequência em aplicações de processamento de sinais</string>\n    <string name=\"lanczos2_sub\">Um método de reamostragem que usa um filtro Lanczos de 2 lóbulos para interpolação de alta qualidade com o mínimo de artefatos</string>\n    <string name=\"lanczos3_sub\">Um método de reamostragem que usa um filtro Lanczos de 3 lóbulos para interpolação de alta qualidade com o mínimo de artefatos</string>\n    <string name=\"cubic\">Cúbico</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Redundância</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quádruplo</string>\n    <string name=\"gaussian\">Gaussiano</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline36\">Estria 36</string>\n    <string name=\"spline64\">Estria 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"spline16\">Estria 16</string>\n    <string name=\"box\">Caixa</string>\n    <string name=\"sphinx_sub\">Um método avançado de reamostragem que oferece interpolação de alta qualidade com o mínimo de artefatos</string>\n    <string name=\"bartlett_sub\">Uma função de janela triangular usada no processamento de sinais para reduzir o vazamento espectral</string>\n    <string name=\"robidoux_sharp_sub\">Uma variante mais nítida do método Robidoux, otimizada para redimensionamento de imagens nítidas</string>\n    <string name=\"spline64_sub\">Um método de interpolação baseado em spline que fornece resultados suaves usando um filtro de 64 toques</string>\n    <string name=\"bartlett_hann_sub\">Uma função de janela híbrida que combina as janelas de Bartlett e Hann, usada para reduzir o vazamento espectral no processamento de sinais</string>\n    <string name=\"kaiser_sub\">Um método de interpolação que usa a janela de Kaiser, proporcionando um bom controle sobre a compensação entre a largura do lóbulo principal e o nível do lóbulo lateral</string>\n    <string name=\"lanczos4_sub\">Um método de reamostragem que usa um filtro Lanczos de 4 lóbulos para interpolação de alta qualidade com o mínimo de artefatos</string>\n    <string name=\"lanczos2_jinc_sub\">Uma variante do filtro Lanczos 2 que usa a função jinc, proporcionando interpolação de alta qualidade com o mínimo de artefatos</string>\n    <string name=\"lanczos4_jinc_sub\">Uma variante do filtro Lanczos 4 que usa a função jinc, proporcionando interpolação de alta qualidade com o mínimo de artefatos</string>\n    <string name=\"lanczos3_jinc_sub\">Uma variante do filtro Lanczos 3 que usa a função jinc, proporcionando interpolação de alta qualidade com o mínimo de artefatos</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Variante de média ponderada elíptica (EWA) do filtro Hanning para interpolação e reamostragem suaves</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Variante de média ponderada elíptica (EWA) do filtro Lanczos Soft para reamostragem mais suave de imagens</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Um filtro de reamostragem projetado por Haasn para escalonamento de imagens suave e sem artefatos</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Variante de média ponderada elíptica (EWA) do filtro Lanczos 3 Jinc para reamostragem de alta qualidade com aliasing reduzido</string>\n    <string name=\"ewa_robidoux_sub\">Variante de média ponderada elíptica (EWA) do filtro Robidoux para reamostragem de alta qualidade</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_blackman_sub\">Variante de média ponderada elíptica (EWA) do filtro Blackman para minimizar artefatos de anelamento</string>\n    <string name=\"ewa_quadric_sub\">Variante EWA (Elliptical Weighted Average) do filtro Quadric para interpolação suave</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Variante de média ponderada elíptica (EWA) do filtro Robidoux Sharp para resultados mais nítidos</string>\n    <string name=\"ewa_quadric\">EWA Quadriculado</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Um filtro de reamostragem projetado para processamento de imagens de alta qualidade com um bom equilíbrio entre nitidez e suavidade</string>\n    <string name=\"ewa_ginseng_sub\">Variante de média ponderada elíptica (EWA) do filtro Ginseng para melhorar a qualidade da imagem</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Variante de média ponderada elíptica (EWA) do filtro Lanczos Sharp para obter resultados nítidos com o mínimo de artefatos</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Variante da média ponderada elíptica (EWA) do filtro Lanczos 4 Sharpest para reamostragem de imagens extremamente nítidas</string>\n    <string name=\"format_conversion_sub\">Converta lotes de imagens de um formato para outro</string>\n    <string name=\"dismiss_forever\">Dispensar definitivamente</string>\n    <string name=\"format_conversion\">Conversão de Formato</string>\n    <string name=\"image_stacking\">Empilhamento de Imagens</string>\n    <string name=\"image_stacking_sub\">Empilhe imagens umas sobre as outras com os modos de mesclagem escolhidos</string>\n    <string name=\"add_image\">Adicionar imagem</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Equalizar histograma HSL adaptativo</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Equalizar histograma HSV adaptativo</string>\n    <string name=\"bins_count\">Contagem de posições</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"wrap\">Envolver</string>\n    <string name=\"clip\">Cortar</string>\n    <string name=\"edge_mode\">Modo de Borda</string>\n    <string name=\"color_blind_scheme\">Correção de Cores</string>\n    <string name=\"protanopia_sub\">Incapacidade de perceber tons de vermelho</string>\n    <string name=\"deuteranopia_sub\">Incapacidade de perceber tons de verde</string>\n    <string name=\"tritanopia_sub\">Incapacidade de perceber tons de azul</string>\n    <string name=\"achromatomaly_sub\">Sensibilidade reduzida a todas as cores</string>\n    <string name=\"color_blind_scheme_sub\">Selecione o modo para adaptar as cores do tema para a variante de daltonismo selecionada</string>\n    <string name=\"protanomaly_sub\">Dificuldade em distinguir entre tons de vermelho e verde</string>\n    <string name=\"not_use_color_blind_scheme_sub\">As cores serão exatamente como definidas no tema</string>\n    <string name=\"deuteranomaly_sub\">Dificuldade em distinguir entre tons de verde e vermelho</string>\n    <string name=\"tritanomaly_sub\">Dificuldade em distinguir entre tons de azul e amarelo</string>\n    <string name=\"achromatopsia_sub\">Completa cegueira de cores, vendo apenas tons de cinza</string>\n    <string name=\"not_use_color_blind_scheme\">Não usar esquema daltônico</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2_sub\">Um filtro de interpolação Lagrange de ordem 2, adequado para escalonamento de imagens de alta qualidade com transições suaves</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_jinc_sub\">Uma variante do filtro Lanczos 6 usando uma função Jinc para melhorar a qualidade da reamostragem de imagens</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lagrange_3_sub\">Um filtro de interpolação Lagrange de ordem 3, que oferece melhor precisão e resultados mais suaves para o dimensionamento de imagens</string>\n    <string name=\"lanczos_6_sub\">Um filtro de reamostragem Lanczos com uma ordem superior a 6, proporcionando uma escala de imagem mais nítida e precisa</string>\n    <string name=\"linear_box_blur\">Desfoque de Caixa Linear</string>\n    <string name=\"soft_glow\">Brilho Suave</string>\n    <string name=\"color_poster\">Poster Colorido</string>\n    <string name=\"polka_dot\">Ponto Polka</string>\n    <string name=\"clustered_4x4_dithering\">Pontilhamento 4x4 Agrupado</string>\n    <string name=\"harmony_tetradic\">Tetrádica</string>\n    <string name=\"harmony_square\">Quadrada</string>\n    <string name=\"harmony_analogous_complementary\">Análoga + Complementar</string>\n    <string name=\"color_tools\">Ferramentas de Cor</string>\n    <string name=\"color_harmonies\">Harmonias de Cores</string>\n    <string name=\"shades\">Sombras</string>\n    <string name=\"color_mixing\">Mistura de Cores</string>\n    <string name=\"color_info\">Detalhes da Cor</string>\n    <string name=\"soft_elegance\">Elegância Suave</string>\n    <string name=\"soft_elegance_variant\">Elegância Suave Variante</string>\n    <string name=\"palette_transfer_variant\">Transferência de Paleta Variante</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Destino do Arquivo 3D LUT (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"candlelight\">Luz de Velas</string>\n    <string name=\"drop_blues\">Gotas de Azul</string>\n    <string name=\"edgy_amber\">Âmbar Ousado</string>\n    <string name=\"fall_colors\">Cores de Outono</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Obter imagem LUT neutra</string>\n    <string name=\"pop_art\">Arte Pop</string>\n    <string name=\"celluloid\">Celuloide</string>\n    <string name=\"coffee\">Café</string>\n    <string name=\"greenish\">Esverdeado</string>\n    <string name=\"retro_yellow\">Amarelo Retrô</string>\n    <string name=\"color_tools_sub\">Misture, crie tons, gere sombras e muito mais</string>\n    <string name=\"backup_ocr_models\">Salvar modelos OCR</string>\n    <string name=\"export\">Exportar</string>\n    <string name=\"center_right\">Centro Direito</string>\n    <string name=\"bottom_center\">Centro Inferior</string>\n    <string name=\"enhanced_oil\">Óleo Aprimorado</string>\n    <string name=\"simple_old_tv\">TV Antiga Simples</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"linear_gaussian_blur\">Desfoque Gaussiano Linear</string>\n    <string name=\"gaussian_box_blur\">Desfoque Gaussiano em Caixa</string>\n    <string name=\"languages_imported\">Idiomas importados com sucesso</string>\n    <string name=\"clear_selection\">Limpar seleção</string>\n    <string name=\"imported_fonts\">Fontes importadas</string>\n    <string name=\"export_fonts\">Exportar fontes</string>\n    <string name=\"calculate\">Calcular</string>\n    <string name=\"checksum\">Checksum</string>\n    <string name=\"text_hash\">Hash</string>\n    <string name=\"source_checksum\">Checksum de Origem</string>\n    <string name=\"match\">Coincide!</string>\n    <string name=\"difference_sub\">Os checksums não são iguais, o arquivo pode ser inseguro!</string>\n    <string name=\"difference\">Diferença</string>\n    <string name=\"collection_mesh_gradients_sub\">Veja a coleção on-line de Malhas de Gradientes</string>\n    <string name=\"mesh_gradients\">Malha de Gradientes</string>\n    <string name=\"tiff_compression_scheme\">Esquema de compactação TIFF</string>\n    <string name=\"checksum_tools\">Ferramentas de Checksum</string>\n    <string name=\"algorithms\">Algoritmo</string>\n    <string name=\"free_software_partner_sub\">Mais software útil no canal parceiro de aplicativos Android</string>\n    <string name=\"free_software_partner\">Free Software (Parceiro)</string>\n    <string name=\"webp_tools\">Ferramentas WEBP</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"outline_size\">Tamanho do Contorno</string>\n    <string name=\"links_preview_sub\">Permite a prévia de visualização de links em locais onde você pode obter texto (QRCode, OCR etc)</string>\n    <string name=\"webp_type_to_image_sub\">Converta arquivos WEBP em lotes de imagens</string>\n    <string name=\"gif_type_to_webp\">GIF para WEBP</string>\n    <string name=\"color_shading\">Sombreamento de Cores</string>\n    <string name=\"image_splitting\">Divisão de Imagens</string>\n    <string name=\"image_splitting_sub\">Dividir uma imagem em linhas ou colunas</string>\n    <string name=\"replace_filter\">Substituir Filtro</string>\n    <string name=\"rotation\">Rotação</string>\n    <string name=\"markup_layers_sub\">Modo de camadas com capacidade de colocar livremente imagens, texto e muito mais</string>\n    <string name=\"markup_layers\">Camadas Indexadas</string>\n    <string name=\"layers_on_image\">Camadas na imagem</string>\n    <string name=\"edit_layer\">Editar camada</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"linear_tent_blur\">Desfoque de Tenda Linear</string>\n    <string name=\"linear_gaussian_box_blur\">Desfoque Gaussiano Linear de Caixa</string>\n    <string name=\"linear_stack_blur\">Desfoque Linear em Pilha</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Desfoque Gaussiano Rápido Próximo Linear</string>\n    <string name=\"linear_fast_gaussian_blur\">Desfoque Gaussiano Rápido Linear</string>\n    <string name=\"draw_filter_sub\">Escolha um filtro para usá-lo como pintura</string>\n    <string name=\"low_poly\">Poucos Polígonos</string>\n    <string name=\"sand_painting\">Pintura em Areia</string>\n    <string name=\"fit_to_bounds\">Ajustar aos Limites</string>\n    <string name=\"import_word\">Importar</string>\n    <string name=\"position\">Posição</string>\n    <string name=\"bottom_left\">Inferior Esquerdo</string>\n    <string name=\"bottom_right\">Inferior Direito</string>\n    <string name=\"center_left\">Centro Esquerdo</string>\n    <string name=\"top_right\">Superior Direito</string>\n    <string name=\"top_left\">Superior Esquerdo</string>\n    <string name=\"top_center\">Superior Centro</string>\n    <string name=\"target_image\">Imagem Alvo</string>\n    <string name=\"palette_transfer\">Transferência de Paleta</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"simple_sketch\">Esboço Simples</string>\n    <string name=\"tri_tone\">Tom Triplo</string>\n    <string name=\"third_color\">Terceira cor</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"clustered_2x2_dithering\">Pontilhamento 2x2 Agrupado</string>\n    <string name=\"clustered_8x8_dithering\">Pontilhamento 8x8 Agrupado</string>\n    <string name=\"yililoma_dithering\">Pontilhamento Yililoma</string>\n    <string name=\"add_favorites\">Adicionar Favoritas</string>\n    <string name=\"harmony_complementary\">Complementar</string>\n    <string name=\"harmony_analogous\">Análoga</string>\n    <string name=\"harmony_triadic\">Triádica</string>\n    <string name=\"harmony_split_complementary\">Separada Complementar</string>\n    <string name=\"variation\">Variação</string>\n    <string name=\"tints\">Matizes</string>\n    <string name=\"tones\">Tons</string>\n    <string name=\"selected_color\">Cor Selecionada</string>\n    <string name=\"color_to_mix\">Cor Para Misturar</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Não é possível usar monet enquanto as cores dinâmicas estiverem ativadas</string>\n    <string name=\"target_lut_image\">Imagem Alvo do LUT</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"film_stock_50\">Filme Stock 50</string>\n    <string name=\"foggy_night\">Noite Nebulosa</string>\n    <string name=\"golden_forest\">Floresta Dourada</string>\n    <string name=\"links_preview\">Prévias de Links</string>\n    <string name=\"links\">Links</string>\n    <string name=\"webp_type_to_image\">WEBP para imagens</string>\n    <string name=\"webp_type_to_webp_sub\">Convert batch of images to WEBP file</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"layers_on_background\">Camadas no plano de fundo</string>\n    <string name=\"outline_color\">Cor do Contorno</string>\n    <string name=\"add_outline\">Adicionar Contorno</string>\n    <string name=\"actions\">Ações</string>\n    <string name=\"center\">Centro</string>\n    <string name=\"gif_type_to_webp_sub\">Converta imagens GIF em imagens animadas WEBP</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Conceda permissão de câmera nas configurações para usar o Digitalizador de Documentos</string>\n    <string name=\"pick_filter_info\">Escolha o filtro abaixo para usá-lo como pincel em seu desenho</string>\n    <string name=\"fit_to_bounds_sub\">Combine o modo de redimensionamento de corte com esse parâmetro para obter o comportamento desejado (Cortar/Ajustar à proporção)</string>\n    <string name=\"no_favorite_options_selected\">Não há opções favoritas selecionadas, adicione-as na página de ferramentas</string>\n    <string name=\"pick_file_to_checksum\">Escolha um arquivo para calcular sua soma de verificação com base no algoritmo selecionado</string>\n    <string name=\"import_font\">Importar fonte (TTF/OTF)</string>\n    <string name=\"wrong_font\">Somente fontes TTF e OTF podem ser importadas</string>\n    <string name=\"options\">Opções</string>\n    <string name=\"bleach_bypass\">Bypass de Branqueamento</string>\n    <string name=\"webp_tools_sub\">Converta imagens em imagens animadas WEBP ou extraia quadros de uma animação WEBP</string>\n    <string name=\"match_sub\">Os checksums são iguais, é seguro</string>\n    <string name=\"checksum_to_compare\">Checksum para Comparação</string>\n    <string name=\"enter_text_to_checksum\">Insira um texto para calcular sua soma de verificação com base no algoritmo selecionado</string>\n    <string name=\"checksum_tools_sub\">Compare checksums, calcule hashes ou crie cadeias hexadecimais de arquivos usando diferentes algoritmos de hashing</string>\n    <string name=\"default_draw_path_mode\">Modo de Desenho de Caminho Padrão</string>\n    <string name=\"ci_channel_sub\">Receba notificações sobre novas versões do aplicativo e leia os anúncios</string>\n    <string name=\"default_draw_color\">Cor de Desenho Padrão</string>\n    <string name=\"collage_maker_sub\">Faça colagens com até 20 imagens</string>\n    <string name=\"formatted_timestamp\">Data e Hora Formatados</string>\n    <string name=\"histogram\">Histograma</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Participe do nosso bate-papo, onde você pode discutir o que quiser, e também dê uma olhada no Canal CI, onde eu público betas e anúncios</string>\n    <string name=\"tesseract_options\">Opções do Tesseract</string>\n    <string name=\"image_toolbox_in_telegram\">Image Toolbox no Telegram 🎉</string>\n    <string name=\"save_empty_lut_sub\">Primeiro, use seu aplicativo de edição de fotos favorito para aplicar um filtro à LUT neutra que pode ser obtida aqui. Para que isso funcione corretamente, cada cor de pixel não deve depender de outros pixels (por exemplo, o desfoque não funcionará). Quando estiver pronta, use sua nova imagem LUT como entrada para o filtro LUT de 512*512</string>\n    <string name=\"ico_size_warning\">Os arquivos ICO só podem ser salvos no tamanho máximo de 256x256</string>\n    <string name=\"webp_type_to_webp\">Imagens para WEBP</string>\n    <string name=\"select_webp_image_to_start\">Escolha a imagem WEBP para iniciar</string>\n    <string name=\"manage_storage_extra_types\">Sem acesso total aos arquivos</string>\n    <string name=\"manage_storage_extra_types_sub\">Permitir o acesso de todos os arquivos para ver JXL, QOI e outras imagens que não são reconhecidas como imagens no Android. Sem a permissão, o Image Toolbox não poderá exibir essas imagens</string>\n    <string name=\"add_timestamp\">Adicionar Data e Hora</string>\n    <string name=\"recently_used\">Usados Recentemente</string>\n    <string name=\"ci_channel\">Canal CI</string>\n    <string name=\"group\">Grupo</string>\n    <string name=\"group_tools_by_type_sub\">Agrupa ferramentas na tela principal por tipo, em vez de um arranjo em lista personalizado</string>\n    <string name=\"hide_all\">Ocultar Todas</string>\n    <string name=\"show_all\">Mostrar Todas</string>\n    <string name=\"hide_nav_bar\">Ocultar Navegação</string>\n    <string name=\"hide_status_bar\">Ocultar Barra de Status</string>\n    <string name=\"noise_generation\">Geração de Ruído</string>\n    <string name=\"noise_generation_sub\">Gerar ruídos diferentes, como Perlin ou outros tipos</string>\n    <string name=\"weighted_strength\">Força Ponderada</string>\n    <string name=\"ping_pong_strength\">Força Ping Pong</string>\n    <string name=\"distance_function\">Função Distância</string>\n    <string name=\"return_type\">Tipo de Retorno</string>\n    <string name=\"custom_filename\">Nome Personalizado</string>\n    <string name=\"custom_filename_sub\">Selecione o local e o nome do arquivo que serão usados para salvar a imagem atual</string>\n    <string name=\"saved_to_custom\">Salvo em uma pasta com nome personalizado</string>\n    <string name=\"collage_maker\">Criador de Colagens</string>\n    <string name=\"collage_type\">Tipo de Colagem</string>\n    <string name=\"collages_info\">Mantenha a imagem pressionada para trocar, mover e aplicar zoom para ajustar a posição</string>\n    <string name=\"histogram_sub\">Histograma de imagem RGB ou Brilho para ajudá-lo a fazer ajustes</string>\n    <string name=\"tesseract_options_sub\">Aplicar algumas variáveis de entrada para o motor tesseract</string>\n    <string name=\"custom_options\">Opções Personalizadas</string>\n    <string name=\"fit_description\">Ajuste uma imagem às dimensões fornecidas e aplique desfoque ou cor ao plano de fundo</string>\n    <string name=\"tools_arrangement\">Arranjo de Ferramentas</string>\n    <string name=\"group_tools_by_type\">Agrupar ferramentas por tipo</string>\n    <string name=\"default_values\">Valores Padrão</string>\n    <string name=\"system_bars_visibility\">Visibilidade das Barras do Sistema</string>\n    <string name=\"show_system_bars_by_swipe\">Mostrar Barras do Sistema ao Deslizar</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Permite deslizar o dedo para mostrar as barras do sistema se elas estiverem ocultas</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"frequency\">Frequência</string>\n    <string name=\"noise_type\">Tipo de Ruído</string>\n    <string name=\"rotation_type\">Tipo de Rotação</string>\n    <string name=\"fractal_type\">Tipo Fractal</string>\n    <string name=\"octaves\">Octaves</string>\n    <string name=\"lacunarity\">Lacunaridade</string>\n    <string name=\"gain\">Ganho</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domínio Warp</string>\n    <string name=\"alignment\">Alinhamento</string>\n    <string name=\"spot_heal_sub\">Preenchimento com reconhecimento de conteúdo sob o caminho desenhado</string>\n    <string name=\"create_shortcut_subtitle\">A ferramenta será adicionada à tela inicial do seu launcher como atalho; use-a combinada com a configuração \\\"Ignorar seleção de arquivo\\\" para obter o comportamento necessário</string>\n    <string name=\"dont_stack_frames\">Não empilhar quadros</string>\n    <string name=\"dont_stack_frames_sub\">Permite o descarte de quadros anteriores, para que eles não sejam empilhados uns sobre os outros</string>\n    <string name=\"laplacian_simple\">Laplacian Simples</string>\n    <string name=\"free_corners_sub\">Cortar imagem por polígono, o que também corrige a perspectiva</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Os pontos não serão limitados pelos limites da imagem, o que é útil para uma correção de perspectiva mais precisa</string>\n    <string name=\"mask\">Máscara</string>\n    <string name=\"one_time_save_location_sub\">Visualize e Edite locais de salvamento único que podem ser usados pressionando longamente o botão salvar em quase todas as opções</string>\n    <string name=\"reset_curves_sub\">As curvas serão revertidas para o valor padrão</string>\n    <string name=\"crossfade\">Transição Gradual</string>\n    <string name=\"gap_size\">Tamanho do Espaço</string>\n    <string name=\"helper_grid\">Grade de Guia</string>\n    <string name=\"crf_sub\">Um valor de %1$s significa uma compactação lenta, resultando em um arquivo de tamanho relativamente pequeno. %2$s significa uma compactação mais rápida, resultando em um arquivo grande.</string>\n    <string name=\"constant_rate_factor\">Fator de Taxa Constante (CRF)</string>\n    <string name=\"defaultt_sub\">Apenas linhas retas padrão</string>\n    <string name=\"enable_timestamps_to_format_them\">Habilite os carimbos de data/hora para selecionar seu formato</string>\n    <string name=\"layout\">Disposição</string>\n    <string name=\"add_timestamp_sub\">Ativa a adição de carimbo de data/hora ao nome do arquivo de saída</string>\n    <string name=\"formatted_timestamp_sub\">Ativar a formatação do carimbo de data/hora no nome do arquivo de saída em vez de milissegundos básicos</string>\n    <string name=\"one_time_save_location\">Local Para Salvamento Único</string>\n    <string name=\"image_for_histogram\">Essa imagem será usada para gerar histogramas RGB e de brilho</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">As opções devem ser inseridas seguindo este padrão: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Cortar Automaticamente</string>\n    <string name=\"free_corners\">Cantos Livres</string>\n    <string name=\"coerce_points_to_image_bounds\">Limitação de Pontos para os Limites das Imagens</string>\n    <string name=\"spot_heal\">Correção de Manchas</string>\n    <string name=\"use_circle_kernel\">Usar Kernel Circle</string>\n    <string name=\"closing\">Fechando</string>\n    <string name=\"morphological_gradient\">Gradiente Morfológica</string>\n    <string name=\"top_hat\">Cartola</string>\n    <string name=\"black_hat\">Chapéu Preto</string>\n    <string name=\"tone_curves\">Curvas de Tom</string>\n    <string name=\"reset_curves\">Redefinir Curvas</string>\n    <string name=\"line_style\">Estilo de Linha</string>\n    <string name=\"dashed\">Tracejado</string>\n    <string name=\"dot_dashed\">Ponto Traço</string>\n    <string name=\"stamped\">Estampado</string>\n    <string name=\"zigzag\">Zigue-Zague</string>\n    <string name=\"dashed_sub\">Desenha uma linha tracejada ao longo do caminho desenhado com o tamanho de espaço especificado</string>\n    <string name=\"dot_dashed_sub\">Desenha pontos e linhas tracejadas ao longo de um determinado caminho</string>\n    <string name=\"stamped_sub\">Desenha as formas selecionadas ao longo do caminho com o espaçamento especificado</string>\n    <string name=\"zigzag_sub\">Desenha um zigue-zague ondulado ao longo do caminho</string>\n    <string name=\"zigzag_ratio\">Proporção do zigue-zague</string>\n    <string name=\"create_shortcut\">Criar Atalho</string>\n    <string name=\"create_shortcut_title\">Escolha a ferramenta a fixar</string>\n    <string name=\"crossfade_sub\">Os quadros serão suavemente cruzados uns com os outros</string>\n    <string name=\"crossfade_count\">Contagem de quadros de transição</string>\n    <string name=\"threshold_one\">Limiar Um</string>\n    <string name=\"threshold_two\">Limiar Dois</string>\n    <string name=\"canny\">Sagaz</string>\n    <string name=\"mirror_101\">Espelho 101</string>\n    <string name=\"enhanced_zoom_blur\">Desfoque de Zoom Aprimorado</string>\n    <string name=\"sobel_simple\">Sobel Simples</string>\n    <string name=\"helper_grid_sub\">Mostra a grade de suporte acima da área de desenho para ajudar em manipulações precisas</string>\n    <string name=\"grid_color\">Cor da Grade</string>\n    <string name=\"cell_width\">Largura de Célula</string>\n    <string name=\"cell_height\">Altura de Célula</string>\n    <string name=\"compact_selectors\">Seletores Compactos</string>\n    <string name=\"compact_selectors_sub\">Alguns controles de seleção usarão um layout compacto para ocupar menos espaço</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Conceda permissão à câmera nas configurações para capturar imagens</string>\n    <string name=\"main_screen_title\">Título na Tela Principal</string>\n    <string name=\"lut_library\">Biblioteca LUT</string>\n    <string name=\"lut_library_sub\">Baixe a coleção de LUTs, que você pode aplicar posteriormente</string>\n    <string name=\"opening\">Abrindo</string>\n    <string name=\"filename_is_not_set\">O nome do arquivo não está definido</string>\n    <string name=\"material_you_slider_sub\">Um controle deslizante Material You</string>\n    <string name=\"fast_settings_side_sub\">Adicione uma listra flutuante na lateral selecionada durante a edição de imagens, que abrirá configurações rápidas quando clicada</string>\n    <string name=\"settings_group_visibility_visible\">O grupo de configurações \\\"%1$s\\\" será expandido por padrão</string>\n    <string name=\"error_while_saving\">Erro ao tentar salvar, experimente alterar a pasta de saída</string>\n    <string name=\"apply\">Aplicar</string>\n    <string name=\"filter_preview_image_sub\">Alterar a imagem de visualização padrão para filtros</string>\n    <string name=\"filter_preview_image\">Prévia de Imagem</string>\n    <string name=\"base_64_actions\">Ações com Base64</string>\n    <string name=\"layers_on_image_sub\">Use uma imagem como plano de fundo e adicione diferentes camadas sobre ela</string>\n    <string name=\"copy_base_64\">Copiar Base64</string>\n    <string name=\"area\">Área</string>\n    <string name=\"area_sub\">Reamostragem usando a relação de área do pixel. Esse pode ser o método preferido para a decimação de imagens, pois oferece resultados sem moiré. Mas quando a imagem é ampliada, ela é semelhante ao método \\\"Mais Próximo\\\".</string>\n    <string name=\"enable_tonemapping\">Ativar Mapeamento de Tons</string>\n    <string name=\"lut_library_update_sub\">Atualizar a coleção de LUTs (somente as novas serão colocadas na fila), que você pode aplicar após o download</string>\n    <string name=\"hide\">Ocultar</string>\n    <string name=\"show\">Exibir</string>\n    <string name=\"slider_type\">Tipo de Slider</string>\n    <string name=\"fancy\">Extravagante</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy_sub\">Um controle deslizante de aparência sofisticada. Essa é a opção padrão</string>\n    <string name=\"material_2_sub\">Um controle deslizante Material 2</string>\n    <string name=\"center_align_dialog_buttons\">Botões de Diálogo Centralizados</string>\n    <string name=\"open_source_licenses\">Licenças de Código Aberto</string>\n    <string name=\"open_source_licenses_sub\">Veja as licenças das bibliotecas de código aberto usadas neste aplicativo</string>\n    <string name=\"enter_percent\">Digite %</string>\n    <string name=\"unknown_host\">Não é possível acessar o site, tente usar VPN ou verifique se a URL está correta</string>\n    <string name=\"layers_on_background_sub\">O mesmo que a primeira opção, mas com cor em vez de imagem</string>\n    <string name=\"fast_settings_side\">Acesso às Configurações na Lateral</string>\n    <string name=\"settings_group_visibility_hidden\">O grupo de configurações \\\"%1$s\\\" será recolhido por padrão</string>\n    <string name=\"base_64_tools\">Ferramentas Base64</string>\n    <string name=\"base_64_tools_sub\">Decodificar string Base64 para imagem ou codificar imagem para o formato Base64</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">O valor fornecido não é uma cadeia de caracteres Base64 válida</string>\n    <string name=\"copy_not_a_valid_base_64\">Não é possível copiar uma string Base64 vazia ou inválida</string>\n    <string name=\"paste_base_64\">Colar Base64</string>\n    <string name=\"base_64_tips\">Carregue a imagem para copiar ou salvar a cadeia de caracteres Base64. Se você tiver a própria cadeia de caracteres, poderá colá-la acima para obter a imagem</string>\n    <string name=\"save_base_64\">Salvar Base64</string>\n    <string name=\"share_base_64\">Compartilhar Base64</string>\n    <string name=\"import_base_64\">Importar Base64</string>\n    <string name=\"add_outline_sub\">Adicionar contorno ao redor do texto com cor e largura especificadas</string>\n    <string name=\"checksum_as_filename\">Checksum como Nome de Arquivo</string>\n    <string name=\"checksum_as_filename_sub\">As imagens de saída terão o nome correspondente à soma de verificação de seus dados</string>\n    <string name=\"center_align_dialog_buttons_sub\">Os botões das caixas de diálogo serão posicionados no centro em vez de no lado esquerdo, se possível</string>\n    <string name=\"none\">Nenhum</string>\n    <string name=\"custom_pages\">Páginas Personalizadas</string>\n    <string name=\"pages_selection\">Seleção de Páginas</string>\n    <string name=\"tool_exit_confirmation\">Confirmação ao Sair da Ferramenta</string>\n    <string name=\"tool_exit_confirmation_sub\">Se você tiver alterações não salvas ao usar determinadas ferramentas e tentar fechá-las, será exibida uma caixa de diálogo de confirmação</string>\n    <string name=\"edit_exif_screen\">Editar EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Alterar metadados de uma única imagem sem recompressão</string>\n    <string name=\"edit_exif_tag\">Toque para editar as tags disponíveis</string>\n    <string name=\"change_sticker\">Alterar Adesivo</string>\n    <string name=\"fit_width\">Ajustar Largura</string>\n    <string name=\"fit_height\">Ajustar Altura</string>\n    <string name=\"batch_compare\">Comparação em Lote</string>\n    <string name=\"pick_files_to_checksum\">Escolha o(s) arquivo(s) para calcular sua soma de verificação com base no algoritmo selecionado</string>\n    <string name=\"pick_directory\">Selecionar Pasta</string>\n    <string name=\"pick_files\">Selecionar Arquivos</string>\n    <string name=\"format_pattern\">Formato Padrão</string>\n    <string name=\"timestamp\">Carimbo de data</string>\n    <string name=\"padding\">Preenchimento</string>\n    <string name=\"head_length_scale\">Escala de Comprimento da Cabeça</string>\n    <string name=\"stamp\">Carimbo</string>\n    <string name=\"image_cutting\">Recorte de Imagem</string>\n    <string name=\"vertical_pivot_line\">Linha de Pivô Vertical</string>\n    <string name=\"horizontal_pivot_line\">Linha de Pivô Horizontal</string>\n    <string name=\"inverse_selection\">Inverter Seleção</string>\n    <string name=\"inverse_vertical_selection_sub\">A parte cortada verticalmente será deixada ao invés de mesclar as partes ao redor da área cortada</string>\n    <string name=\"inverse_horizontal_selection_sub\">A parte cortada horizontalmente será deixada ao invés de mesclar as partes ao redor da área cortada</string>\n    <string name=\"image_cutting_sub\">Corte parte da imagem e mescle as partes restantes (ou o inverso) por meio de linhas verticais ou horizontais</string>\n    <string name=\"mesh_gradients_sub\">Criar gradiente mesh com quantidade personalizada de nós e resolução</string>\n    <string name=\"gradient_maker_type_image_mesh\">Sobreposição de Gradiente Mesh</string>\n    <string name=\"points_customization\">Personalização de Pontos</string>\n    <string name=\"grid_size\">Tamanho da Grade</string>\n    <string name=\"resolution_x\">Resolução X</string>\n    <string name=\"resolution_y\">Resolução Y</string>\n    <string name=\"resolution\">Resolução</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Componha o gradiente mesh por cima das imagens fornecidas</string>\n    <string name=\"collection_mesh_gradients\">Coleção de Gradientes Mesh</string>\n    <string name=\"pixel_by_pixel\">Pixel Por Pixel</string>\n    <string name=\"highlight_color\">Destacar Cor</string>\n    <string name=\"pixel_comparison_type\">Tipo de Comparação de Pixels</string>\n    <string name=\"scan_barcode\">Escanear código de barras</string>\n    <string name=\"height_ratio\">Proporção de Altura</string>\n    <string name=\"barcode_type\">Tipo de Código de Barras</string>\n    <string name=\"enforce_bw\">Forçar P/B</string>\n    <string name=\"enforce_bw_sub\">A imagem do código de barras será totalmente em preto e branco e não será colorida pelo tema do aplicativo</string>\n    <string name=\"barcodes_sub\">Escaneie qualquer código de barras (QR, EAN, AZTEC, …) e obtenha seu conteúdo ou cole seu texto para gerar um código</string>\n    <string name=\"no_barcode_found\">Nenhum Código Encontrado</string>\n    <string name=\"generated_barcode_will_be_here\">O código de Barras Gerado Estará Aqui</string>\n    <string name=\"audio_cover_extractor\">Capas de Álbum</string>\n    <string name=\"audio_cover_extractor_sub\">Extraia imagens de capas de álbuns de arquivos de áudio, com suporte aos formatos mais comuns</string>\n    <string name=\"pick_audio_to_start\">Escolha um áudio para iniciar</string>\n    <string name=\"pick_audio\">Selecionar Áudio</string>\n    <string name=\"no_covers_found\">Nenhuma Capa Encontrada</string>\n    <string name=\"send_logs\">Enviar Registros</string>\n    <string name=\"send_logs_sub\">Clique para compartilhar o arquivo de registros do aplicativo, isso pode me ajudar a identificar e corrigir o problema</string>\n    <string name=\"crash_title\">Ops… Algo deu errado</string>\n    <string name=\"crash_subtitle\">Você pode entrar em contato comigo usando as opções abaixo e tentarei encontrar uma solução\\n(Não se esqueça de anexar os registros).</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extraia o texto de cada imagem e coloque-o nas informações EXIF das respectivas fotos</string>\n    <string name=\"ocr_write_to_file\">Gravar em Arquivo</string>\n    <string name=\"ocr_write_to_metadata\">Gravar nos Metadados</string>\n    <string name=\"ocr_write_to_file_sub\">Extraia o texto de um lote de imagens e armazene-o em um único arquivo de texto</string>\n    <string name=\"auto_remove_red_eyes\">Remover Olhos Vermelhos Automaticamente</string>\n    <string name=\"use_lsb_sub\">O método de esteganografia LSB (Less Significant Bit, bit menos significativo) será usado, caso contrário, FD (Frequency Domain, domínio de frequência)</string>\n    <string name=\"use_lsb\">Usar LSB</string>\n    <string name=\"invisible_mode_sub\">Usar esteganografia para criar marcas d\\'água invisíveis aos olhos dentro de bytes de suas imagens</string>\n    <string name=\"invisible_mode\">Modo Invisível</string>\n    <string name=\"password\">Senha</string>\n    <string name=\"unlock\">Desbloquear</string>\n    <string name=\"pdf_is_protected\">O PDF está protegido</string>\n    <string name=\"sort_by_date_modified\">Data de Modificação</string>\n    <string name=\"sort_by_size\">Tamanho</string>\n    <string name=\"sort_by_mime_type_reversed\">Tipo MIME (Inverso)</string>\n    <string name=\"sort_by_extension\">Extensão</string>\n    <string name=\"sort_by_extension_reversed\">Extensão (Inversa)</string>\n    <string name=\"sort_by_date_added_reversed\">Data de Adição (Inversa)</string>\n    <string name=\"sort_by_date_modified_reversed\">Data de Modificação (Inversa)</string>\n    <string name=\"sort_by_size_reversed\">Tamanho (Inverso)</string>\n    <string name=\"operation_almost_complete\">Operação quase concluída. Cancelar agora exigirá a reinicialização da operação</string>\n    <string name=\"sort_by_mime_type\">Tipo MIME</string>\n    <string name=\"sort_by_date_added\">Data de Adição</string>\n    <string name=\"left_to_right\">Esquerda para a Direita</string>\n    <string name=\"right_to_left\">Direita para a Esquerda</string>\n    <string name=\"bottom_to_top\">De Baixo para Cima</string>\n    <string name=\"top_to_bottom\">De Cima para Baixo</string>\n    <string name=\"liquid_glass\">Vidro Líquido</string>\n    <string name=\"pick_image_or_base64\">Escolha a imagem ou cole/importe os dados Base64 abaixo</string>\n    <string name=\"type_image_link\">Digite o link da imagem para iniciar</string>\n    <string name=\"paste_link\">Colar link</string>\n    <string name=\"liquid_glass_sub\">Um switch baseado no recém-anunciado IOS 26 e em seu sistema de design de vidro líquido</string>\n    <string name=\"kaleidoscope\">Caleidoscópio</string>\n    <string name=\"secondary_angle\">Ângulo secundário</string>\n    <string name=\"sides\">Lados</string>\n    <string name=\"channel_mix\">Mistura de Canais</string>\n    <string name=\"blue_green\">Azul verde</string>\n    <string name=\"red_blue\">Vermelho azul</string>\n    <string name=\"green_red\">Verde vermelho</string>\n    <string name=\"into_red\">No vermelho</string>\n    <string name=\"into_green\">No verde</string>\n    <string name=\"into_blue\">No azul</string>\n    <string name=\"cyan\">Ciano</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Amarelo</string>\n    <string name=\"color_halftone\">Meio-tom de Cor</string>\n    <string name=\"levels\">Níveis</string>\n    <string name=\"shape\">Forma</string>\n    <string name=\"disable_rotation\">Desativar rotação</string>\n    <string name=\"disable_rotation_sub\">Impede a rotação de imagens com gestos de dois dedos</string>\n    <string name=\"enable_snapping_to_borders\">Ativar encaixe nas bordas</string>\n    <string name=\"enable_snapping_to_borders_sub\">Após mover ou ampliar, as imagens se ajustarão para preencher as bordas do quadro</string>\n    <string name=\"contour\">Contorno</string>\n    <string name=\"voronoi_crystallize\">Cristalização Voronoi</string>\n    <string name=\"stretch\">Alongar</string>\n    <string name=\"randomness\">Aleatoriedade</string>\n    <string name=\"despeckle\">Remover manchas</string>\n    <string name=\"diffuse\">Difuso</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Segundo raio</string>\n    <string name=\"equalize\">Equalizar</string>\n    <string name=\"glow\">Brilhar</string>\n    <string name=\"whirl_and_pinch\">Girar e Pinçar</string>\n    <string name=\"pointillize\">Pontilhismo</string>\n    <string name=\"border_color\">Cor da borda</string>\n    <string name=\"polar_coordinates\">Coordenadas Polares</string>\n    <string name=\"rect_to_polar\">Rectangular para polar</string>\n    <string name=\"offset\">Deslocamento</string>\n    <string name=\"invert_in_circle\">Inverter em círculo</string>\n    <string name=\"reduce_noise\">Reduzir Ruído</string>\n    <string name=\"simple_solarize\">Solarizar Simples</string>\n    <string name=\"weave\">Entrelaçar</string>\n    <string name=\"x_gap\">Espaço X</string>\n    <string name=\"y_gap\">Espaço Y</string>\n    <string name=\"x_width\">Largura X</string>\n    <string name=\"y_wdth\">Largura Y</string>\n    <string name=\"twirl\">Rodopiar</string>\n    <string name=\"rubber_stmp\">Carimbo de Borracha</string>\n    <string name=\"smear\">Mancha</string>\n    <string name=\"density\">Densidade</string>\n    <string name=\"mix\">Mistura</string>\n    <string name=\"sphere_lensh_distortion\">Distorção por Lente Esférica</string>\n    <string name=\"refraction_index\">Índice de Refração</string>\n    <string name=\"arc\">Arco</string>\n    <string name=\"spread_angle\">Ângulo aberto</string>\n    <string name=\"sparkle\">Lampejo</string>\n    <string name=\"rays\">Raios</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradiente</string>\n    <string name=\"moire\">Moire</string>\n    <string name=\"autumn\">Outono</string>\n    <string name=\"bone\">Osso</string>\n    <string name=\"jet\">Jato</string>\n    <string name=\"winter\">Inverno</string>\n    <string name=\"ocean\">Oceano</string>\n    <string name=\"summer\">Verão</string>\n    <string name=\"spring\">Primavera</string>\n    <string name=\"cool_variant\">Variante Legal</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rosa</string>\n    <string name=\"hot\">Quente</string>\n    <string name=\"parula\">Parula</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Cividis</string>\n    <string name=\"twilight\">Crepúsculo</string>\n    <string name=\"twilight_shifted\">Crepúsculo Mudado</string>\n    <string name=\"auto_perspective\">Perspectiva Automática</string>\n    <string name=\"deskew\">Desalinhamento</string>\n    <string name=\"allow_crop\">Permitir corte</string>\n    <string name=\"crop_or_perspective\">Recorte ou Perspectiva</string>\n    <string name=\"absolute\">Absoluto</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Verde Intenso</string>\n    <string name=\"lens_correction\">Correção de Lentes</string>\n    <string name=\"download_ready_lens_profiles\">Baixar perfis de lentes prontos</string>\n    <string name=\"part_percents\">Porcentagens parciais</string>\n    <string name=\"export_as_json\">Exportar como JSON</string>\n    <string name=\"export_as_json_sub\">Copiar string com dados da paleta como representação json</string>\n    <string name=\"seam_carving\">Corte de Costura</string>\n    <string name=\"home_screen\">Tela Inicial</string>\n    <string name=\"lock_screen\">Tela de Bloqueio</string>\n    <string name=\"built_in\">Integrado</string>\n    <string name=\"wallpapers_export\">Exportação de Papéis de Parede</string>\n    <string name=\"refresh\">Atualizar</string>\n    <string name=\"wallpapers_export_sub\">Obter os papéis de parede atuais da Tela de Bloqueio e Tela Inicial</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Permita o acesso a todos os arquivos, isso é necessário para obter os papéis de parede</string>\n    <string name=\"allow_read_media_images_for_wp\">A permissão para Gerenciar o armazenamento externo não é suficiente, você precisa permitir o acesso às suas imagens. Certifique-se de selecionar “Permitir tudo”.</string>\n    <string name=\"add_preset_to_filename\">Adicionar Predefinição ao Nome do Arquivo</string>\n    <string name=\"add_preset_to_filename_sub\">Anexa o sufixo com a predefinição selecionada ao nome do arquivo de imagem</string>\n    <string name=\"add_image_scale_mode_to_filename\">Adicionar Modo De Escala De Imagem Ao Nome Do Arquivo</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Anexa o sufixo com o modo de escala de imagem selecionado ao nome do arquivo de imagem</string>\n    <string name=\"ascii_art\">Arte ASCII</string>\n    <string name=\"ascii_art_sub\">Converter a imagem em texto ASCII que se parecerá com a imagem</string>\n    <string name=\"params\">Parâmetros</string>\n    <string name=\"invert_colors_ascii_sub\">Aplica filtro negativo à imagem para obter melhores resultados em alguns casos</string>\n    <string name=\"processing_screenshot\">Processando captura de tela</string>\n    <string name=\"screenshot_not_captured_try_again\">Captura de tela não realizada, tente novamente</string>\n    <string name=\"skipped_saving\">Salvamento ignorado</string>\n    <string name=\"skipped_saving_multiple\">%1$s arquivos ignorados</string>\n    <string name=\"allow_skip_if_larger\">Permitir Ignorar se Maior</string>\n    <string name=\"allow_skip_if_larger_sub\">Algumas ferramentas poderão ignorar o salvamento de imagens se o tamanho do arquivo resultante for maior do que o original</string>\n    <string name=\"qr_type_calendar_event\">Evento de Calendário</string>\n    <string name=\"qr_type_contact_info\">Contato</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Localização</string>\n    <string name=\"qr_type_phone\">Telefone</string>\n    <string name=\"qr_type_plain\">Texto</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Abrir rede</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefone</string>\n    <string name=\"message\">Mensagem</string>\n    <string name=\"address\">Endereço</string>\n    <string name=\"subject\">Assunto</string>\n    <string name=\"body\">Corpo</string>\n    <string name=\"name\">Nome</string>\n    <string name=\"organization\">Empresa</string>\n    <string name=\"title\">Título</string>\n    <string name=\"phones\">Telefones</string>\n    <string name=\"emails\">E-mails</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">Endereços</string>\n    <string name=\"summary\">Resumo</string>\n    <string name=\"description\">Descrição</string>\n    <string name=\"location\">Localização</string>\n    <string name=\"organizer\">Organizador</string>\n    <string name=\"start_date\">Data de início</string>\n    <string name=\"end_date\">Data de término</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Latitude</string>\n    <string name=\"longitude\">Longitude</string>\n    <string name=\"create_barcode\">Criar Código de Barras</string>\n    <string name=\"edit_barcode\">Editar Código de Barras</string>\n    <string name=\"wifi_configuration\">Configuração de Wi-Fi</string>\n    <string name=\"security\">Segurança</string>\n    <string name=\"pick_contact\">Escolher contato</string>\n    <string name=\"grant_contact_permission\">Conceda a permissão de acesso aos contatos nas configurações para preenchimento automático usando o contato selecionado</string>\n    <string name=\"contact_info\">Informações de contato</string>\n    <string name=\"first_name\">Nome</string>\n    <string name=\"middle_name\">Nome do meio</string>\n    <string name=\"last_name\">Sobrenome</string>\n    <string name=\"pronunciation\">Pronúncia</string>\n    <string name=\"add_phone\">Adicionar telefone</string>\n    <string name=\"add_email\">Adicionar e-mail</string>\n    <string name=\"add_address\">Adicionar endereço</string>\n    <string name=\"website\">Site</string>\n    <string name=\"add_website\">Adicionar site</string>\n    <string name=\"formatted_name\">Nome formatado</string>\n    <string name=\"qr_code_top_image\">Esta imagem será usada para colocar acima do código de barras.</string>\n    <string name=\"code_customization\">Personalização do código</string>\n    <string name=\"qr_logo_image\">Esta imagem será usada como logotipo no centro do código QR.</string>\n    <string name=\"logo\">Logotipo</string>\n    <string name=\"logo_padding\">Preenchimento do logotipo</string>\n    <string name=\"block_size\">Tamanho do Bloco</string>\n    <string name=\"polar_to_rect\">Polar para Retangular</string>\n    <string name=\"target_lens_profile\">Arquivo de perfil de lente no formato JSON</string>\n    <string name=\"logo_size\">Tamanho do logotipo</string>\n    <string name=\"logo_corners\">Cantos do logotipo</string>\n    <string name=\"fourth_eye\">Quarto olho</string>\n    <string name=\"fourth_eye_description\">Adiciona simetria ao código QR, adicionando um quarto olho no canto inferior direito</string>\n    <string name=\"pixel_shape\">Forma do pixel</string>\n    <string name=\"frame_shape\">Formato da moldura</string>\n    <string name=\"ball_shape\">Forma esférica</string>\n    <string name=\"error_correction_level\">Nível de correção de erro</string>\n    <string name=\"dark_color\">Cor escura</string>\n    <string name=\"light_color\">Cor clara</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Estilo semelhante ao HyperOS da Xiaomi</string>\n    <string name=\"mask_pattern\">Padrão da máscara</string>\n    <string name=\"code_may_be_not_scannable\">Este código pode não ser digitalizável. Altere os parâmetros de aparência para torná-lo legível em todos os dispositivos</string>\n    <string name=\"not_scannable\">Não digitalizável</string>\n    <string name=\"launcher_mode_sub\">As ferramentas se parecerão com apps na tela inicial para serem mais compactas</string>\n    <string name=\"launcher_mode\">Modo de Abertura</string>\n    <string name=\"flood_fill_sub\">Preenche uma área com o pincel e o estilo selecionados</string>\n    <string name=\"flood_fill\">Inundação</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Desenha um caminho no estilo grafite</string>\n    <string name=\"square_particles\">Partículas Quadradas</string>\n    <string name=\"square_particles_sub\">As partículas pulverizadas terão formato quadrado em vez de circular</string>\n    <string name=\"palette_tools\">Ferramentas da Paleta</string>\n    <string name=\"palette_tools_sub\">Gerar paleta básica/material a partir de uma imagem ou importe/exporte entre diferentes formatos de paleta</string>\n    <string name=\"edit_palette\">Editar Paleta</string>\n    <string name=\"edit_palette_sub\">Exportar/importar paleta em vários formatos</string>\n    <string name=\"color_name\">Nome da cor</string>\n    <string name=\"palette_name\">Nome da paleta</string>\n    <string name=\"palette_format\">Formato da Paleta</string>\n    <string name=\"export_palette_sub\">Exportar a paleta gerada para diferentes formatos</string>\n    <string name=\"add_color_palette_sub\">Adiciona uma nova cor à paleta atual</string>\n    <string name=\"palette_name_not_supported\">O formato %1$s não suporta o fornecimento de um nome da paleta</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Devido às políticas da Play Store, esse recurso não pode ser incluído na versão atual. Para acessar essa funcionalidade, baixe o ImageToolbox de uma fonte alternativa. Você pode encontrar as versões disponíveis no GitHub abaixo.</string>\n    <string name=\"open_github_page\">Abrir página do Github</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s cor</item>\n        <item quantity=\"other\">%1$s cores</item>\n    </plurals>\n    <string name=\"overwrite_files_sub_short\">O arquivo original será substituído por um novo, em vez de ser salvo na pasta selecionada</string>\n    <string name=\"hidden_watermark_text_detected\">Texto de marca d\\'água oculto detectado</string>\n    <string name=\"hidden_watermark_image_detected\">Imagem com marca d\\'água oculta detectada</string>\n    <string name=\"this_image_was_hidden\">Esta imagem foi ocultada</string>\n    <string name=\"generative_inpaint\">Preenchimento Generativo</string>\n    <string name=\"generative_inpaint_sub\">Permite remover objetos de uma imagem usando um modelo de IA, sem depender do OpenCV. Para usar esse recurso, o aplicativo baixará o modelo necessário (~200 MB) do GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Permite remover objetos em uma imagem usando um modelo de IA, sem depender do OpenCV. Essa pode ser uma operação demorada</string>\n    <string name=\"error_level_analysis\">Análise do Nível de Erro</string>\n    <string name=\"luminance_gradient\">Gradiente de Luminância</string>\n    <string name=\"average_distance\">Distância Média</string>\n    <string name=\"copy_move_detection\">Detecção de Cópia e Movimentação</string>\n    <string name=\"retain\">Manter</string>\n    <string name=\"coefficent\">Coeficiente</string>\n    <string name=\"clipboard_data_is_too_large\">Os dados da área de transferência são muito grandes</string>\n    <string name=\"data_is_too_large_to_copy\">Os dados são muito grandes para serem copiados</string>\n    <string name=\"simple_weave_pixelization\">Pixelização de Tecelagem Simples</string>\n    <string name=\"staggered_pixelization\">Pixelização Escalonada</string>\n    <string name=\"cross_pixelization\">Pixelização Cruzada</string>\n    <string name=\"micro_macro_pixelization\">Micro Macro Pixelização</string>\n    <string name=\"orbital_pixelization\">Pixelização Orbital</string>\n    <string name=\"vortex_pixelization\">Pixelização em Vórtice</string>\n    <string name=\"pulse_grid_pixelization\">Pixelização em Grade de Pulsos</string>\n    <string name=\"nucleus_pixelization\">Pixelização do Núcleo</string>\n    <string name=\"radial_weave_pixelization\">Pixelização de Tecelagem Radial</string>\n    <string name=\"cannot_open_uri\">Não é possível abrir o uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Modo Neve</string>\n    <string name=\"enabled\">Ativado</string>\n    <string name=\"border_frame\">Moldura de Borda</string>\n    <string name=\"glitch_variant\">Variante Glitch</string>\n    <string name=\"channel_shift\">Mudança de Canal</string>\n    <string name=\"max_offset\">Desvio Máximo</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Bloco com Glitch</string>\n    <string name=\"crt_curvature\">Curvatura CRT</string>\n    <string name=\"curvature\">Curvatura</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Derretimento de Pixels</string>\n    <string name=\"max_drop\">Queda Máxima</string>\n    <string name=\"ai_tools\">Ferramentas de IA</string>\n    <string name=\"ai_tools_sub\">Várias ferramentas para processar imagens por meio de modelos de IA, como remoção de artefatos ou redução de ruído</string>\n    <string name=\"model_anime_undeint\">Compressão, linhas irregulares</string>\n    <string name=\"model_broadcast\">Desenhos animados, compressão de transmissão</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Compressão geral, ruído geral</string>\n    <string name=\"model_wb_denoise\">Ruído de desenho animado sem color</string>\n    <string name=\"model_span_anime_pretrain\">Rápido, compressão geral, ruído geral, animação/quadrinhos/anime</string>\n    <string name=\"model_book_scan\">Digitalização de livros</string>\n    <string name=\"model_overexposure\">Correção de exposição</string>\n    <string name=\"model_fbcnn_color_fp16\">Melhor em compressão geral, imagens coloridas</string>\n    <string name=\"model_fbcnn_gray_fp16\">Melhor em compressão geral, imagens em escala de cinza</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Compressão geral, imagens em escala de cinza, mais forte</string>\n    <string name=\"model_scunet_color_gan_fp16\">Ruído geral, imagens coloridas</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Ruído geral, imagens coloridas, melhores detalhes</string>\n    <string name=\"model_scunet_gray_15_fp16\">Ruído geral, imagens em escala de cinza</string>\n    <string name=\"model_scunet_gray_25_fp16\">Ruído geral, imagens em escala de cinza, mais forte</string>\n    <string name=\"model_scunet_gray_50_fp16\">Ruído geral, imagens em escala de cinza, a mais forte</string>\n    <string name=\"model_jpeg_destroyer\">Compressão geral</string>\n    <string name=\"model_jaywreck\">Compressão geral</string>\n    <string name=\"model_h264\">Texturização, compressão h264</string>\n    <string name=\"model_vhs\">Compressão VHS</string>\n    <string name=\"model_cinepak\">Compressão não padrão (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Compressão Blink, melhor em geometria</string>\n    <string name=\"model_debink_v5\">Compressão instantânea, mais forte</string>\n    <string name=\"model_debink_v6\">Compressão Blink, suave, mantém detalhes</string>\n    <string name=\"model_antialias\">Anti-aliasing</string>\n    <string name=\"model_kdm_scans\">Arte/desenhos digitalizados, compressão moderada, moiré</string>\n    <string name=\"model_bandage\">Faixas coloridas</string>\n    <string name=\"model_halftone\">Lento, removendo meios-tons</string>\n    <string name=\"model_colorizer\">Colorizador geral para imagens em escala de cinza/preto e branco</string>\n    <string name=\"model_deedge\">Remoção de bordas</string>\n    <string name=\"model_desharpen\">Remove o excesso de nitidez</string>\n    <string name=\"model_dither\">Lento, dithering</string>\n    <string name=\"model_gainres\">Anti-aliasing, artefatos gerais, CGI</string>\n    <string name=\"model_kdm003_scans\">Processamento de digitalizações KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Modelo leve de aprimoramento de imagem</string>\n    <string name=\"model_spongecolor_lite\">Modelo de colorização rápida que adiciona rapidamente cores naturais a imagens em escala de cinza.</string>\n    <string name=\"model_bcgone_detailed_v2\">Remoção de artefatos de compressão</string>\n    <string name=\"model_bcgone_smooth\">Remoção de artefatos de compressão</string>\n    <string name=\"model_bandage_smooth\">Remoção de curativos com resultados suaves</string>\n    <string name=\"model_bendel_halftone\">Processamento de padrões de meio-tom</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Remoção do padrão de dither V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Remoção de artefatos JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Aprimoramento de textura H.264</string>\n    <string name=\"model_vhs_sharpen\">Aprimoramento e nitidez de VHS</string>\n    <string name=\"merging\">Fusão</string>\n    <string name=\"chunk_size\">Tamanho do Pedaço</string>\n    <string name=\"overlap_size\">Tamanho da Sobreposição</string>\n    <string name=\"note_chunk_info\">Imagens com mais de %1$s px serão divididas e processadas em partes, que serão sobrepostas para evitar junções visíveis.</string>\n    <string name=\"large_chunk_warning\">Tamanhos grandes podem causar instabilidade em dispositivos de baixo custo</string>\n    <string name=\"select_one_to_start\">Selecione uma para começar</string>\n    <string name=\"delete_model_sub\">Deseja excluir o modelo %1$s? Você precisará baixá-lo novamente</string>\n    <string name=\"confirm\">Confirmar</string>\n    <string name=\"models\">Modelos</string>\n    <string name=\"downloaded_models\">Modelos Baixados</string>\n    <string name=\"available_models\">Modelos Disponíveis</string>\n    <string name=\"preparing\">Preparando</string>\n    <string name=\"active_model\">Modelo ativo</string>\n    <string name=\"failed_to_open_session\">Falha ao abrir sessão</string>\n    <string name=\"only_onnx_models\">Apenas modelos .onnx/.ort podem ser importados</string>\n    <string name=\"import_model\">Importar modelo</string>\n    <string name=\"import_model_sub\">Importar o modelo ONNX personalizado para uso posterior. Somente modelos ONNX/ORT são aceitos, com suporte para quase todas as variantes semelhantes ao ESRGAN</string>\n    <string name=\"imported_models\">Modelos Importados</string>\n    <string name=\"model_scunet_color_15_fp16\">Ruído geral, imagens coloridas</string>\n    <string name=\"model_scunet_color_25_fp16\">Ruído geral, imagens coloridas, mais forte</string>\n    <string name=\"model_scunet_color_50_fp16\">Ruído geral, imagens coloridas, o mais forte</string>\n    <string name=\"model_artifacts_dithering_alsa\">Reduz artefatos de dithering e faixas de cor, melhorando gradientes suaves e áreas de cor planas.</string>\n    <string name=\"model_nmkd_brighten_redux\">Melhora o brilho e o contraste da imagem com realces equilibrados, preservando as cores naturais.</string>\n    <string name=\"model_nmkd_brighten\">Ilumina imagens escuras, mantendo os detalhes e evitando a superexposição.</string>\n    <string name=\"model_nmkd_detoon\">Remove o excesso de tonalidade e restaura um equilíbrio de cores mais neutro e natural.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Aplica tonalidade de ruído baseada em Poisson com ênfase na preservação de detalhes finos e texturas.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Aplica um tom suave de ruído de Poisson para resultados visuais mais suaves e menos agressivos.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Tonalidade uniforme do ruído com foco na preservação dos detalhes e na nitidez da imagem.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Tom suave e uniforme para uma textura sutil e aparência suave.</string>\n    <string name=\"model_repainter\">Repara áreas danificadas ou irregulares repintando artefatos e melhorando a consistência da imagem.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Modelo leve de remoção de faixas que elimina as faixas de cor com um custo mínimo de desempenho.</string>\n    <string name=\"model_jpeg_0_20\">Otimiza imagens com artefatos de compressão muito elevados (qualidade de 0 a 20%) para melhorar a nitidez.</string>\n    <string name=\"model_jpeg_20_40\">Melhora imagens com artefatos de alta compressão (20-40% de qualidade), restaurando detalhes e reduzindo o ruído.</string>\n    <string name=\"model_jpeg_40_60\">Melhora as imagens com compressão moderada (40-60% de qualidade), equilibrando nitidez e suavidade.</string>\n    <string name=\"model_jpeg_60_80\">Refina imagens com compressão leve (60-80% de qualidade) para realçar detalhes e texturas sutis.</string>\n    <string name=\"model_jpeg_80_100\">Melhora ligeiramente imagens quase sem perdas (80-100% de qualidade), preservando a aparência natural e os detalhes.</string>\n    <string name=\"model_deblr\">Reduz ligeiramente o desfoque da imagem, melhorando a nitidez sem introduzir artefatos.</string>\n    <string name=\"processing_channel\">Operações de longa duração</string>\n    <string name=\"processing_image\">Processando imagem</string>\n    <string name=\"processing\">Processando</string>\n    <string name=\"model_artifacts_jpg_0_20\">Remove artefatos de compressão JPEG pesados em imagens de qualidade muito baixa (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Reduz artefatos JPEG fortes em imagens altamente comprimidas (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Limpa artefatos JPEG moderados enquanto preserva os detalhes da imagem (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Refina artefatos JPEG leves em imagens de qualidade bastante alta (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Reduz sutilmente pequenos artefatos JPEG em imagens quase sem perdas (80-100%).</string>\n    <string name=\"model_redetail_v2\">Aprimora detalhes e texturas finas, melhorando a nitidez percebida sem artefatos pesados.</string>\n    <string name=\"processing_finished\">Processamento concluído</string>\n    <string name=\"processing_failed\">Falha no processamento</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Melhora as texturas e detalhes da pele, mantendo uma aparência natural, otimizada para velocidade.</string>\n    <string name=\"model_sbdv_dejpeg\">Remove artefatos de compactação JPEG e restaura a qualidade da imagem para fotos compactadas.</string>\n    <string name=\"model_iso_denoise_v1\">Reduz o ruído ISO em fotos tiradas em condições de pouca luz, preservando os detalhes.</string>\n    <string name=\"model_dejumbo\">Corrige realces superexpostos ou “jumbo” e restaura um melhor equilíbrio tonal.</string>\n    <string name=\"model_ddcolor_tiny\">Modelo de colorização leve e rápido que adiciona cores naturais às imagens em tons de cinza.</string>\n    <string name=\"type_dejpeg\">DeJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Colorir</string>\n    <string name=\"type_artifacts\">Artefatos</string>\n    <string name=\"type_enhance\">Melhorar</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Verificações</string>\n    <string name=\"type_upscale\">Sofisticado</string>\n    <string name=\"model_realesrgan_x4v3\">Upscaler X4 para imagens gerais; modelo minúsculo que usa menos GPU e tempo, com desfoque e redução de ruído moderados.</string>\n    <string name=\"model_realesrgan_x2plus\">Upscaler X2 para imagens gerais, preservando texturas e detalhes naturais.</string>\n    <string name=\"model_realesrgan_x4plus\">Upscaler X4 para imagens gerais com texturas aprimoradas e resultados realistas.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Upscaler X4 otimizado para imagens de anime; 6 blocos RRDB para linhas e detalhes mais nítidos.</string>\n    <string name=\"model_realesrnet_x4plus\">O upscaler X4 com perda de MSE produz resultados mais suaves e artefatos reduzidos para imagens gerais.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler otimizado para imagens de anime; Variante 4B32F com detalhes mais nítidos e linhas suaves.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Modelo X4 UltraSharp V2 para imagens gerais; enfatiza nitidez e clareza.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; mais rápido e menor, preserva os detalhes enquanto usa menos memória da GPU.</string>\n    <string name=\"model_rmbg_1_4\">Modelo leve para remoção rápida de fundo. Desempenho e precisão equilibrados. Trabalha com retratos, objetos e cenas. Recomendado para a maioria dos casos de uso.</string>\n    <string name=\"type_removebg\">Remover glicemia</string>\n    <string name=\"horizontal_border_thickness\">Espessura da borda horizontal</string>\n    <string name=\"vertical_border_thickness\">Espessura da borda vertical</string>\n    <string name=\"current_model_not_chunkable\">O modelo atual não suporta chunking, a imagem será processada nas dimensões originais, isso pode causar alto consumo de memória e problemas com dispositivos de baixo custo</string>\n    <string name=\"chunking_disabled\">Chunking desativado, a imagem será processada nas dimensões originais, o que pode causar alto consumo de memória e problemas com dispositivos de baixo custo, mas pode fornecer melhores resultados na inferência</string>\n    <string name=\"chunking\">Pedaço</string>\n    <string name=\"model_u2net\">Modelo de segmentação de imagens de alta precisão para remoção de fundo</string>\n    <string name=\"model_u2netp\">Versão leve do U2Net para remoção mais rápida de fundo com menor uso de memória.</string>\n    <string name=\"model_ddcolor\">O modelo Full DDColor oferece colorização de alta qualidade para imagens gerais com o mínimo de artefatos. A melhor escolha de todos os modelos de colorização.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Conjuntos de dados artísticos treinados e privados; produz resultados de colorização diversos e artísticos com menos artefatos de cores irrealistas.</string>\n    <string name=\"model_birefnet\">Modelo BiRefNet leve baseado no Swin Transformer para remoção precisa do fundo.</string>\n    <string name=\"model_inspyrenet\">Remoção de fundo de alta qualidade com bordas nítidas e excelente preservação de detalhes, especialmente em objetos complexos e fundos complicados.</string>\n    <string name=\"model_isnet\">Modelo de remoção de fundo que produz máscaras precisas com bordas suaves, adequadas para objetos gerais e preservação moderada de detalhes.</string>\n    <string name=\"model_already_downloaded\">Modelo já baixado</string>\n    <string name=\"model_successfully_imported\">Modelo importado com sucesso</string>\n    <string name=\"type\">Tipo</string>\n    <string name=\"keyword\">Palavra-chave</string>\n    <string name=\"very_fast\">Muito rápido</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Lento</string>\n    <string name=\"very_slow\">Muito lento</string>\n    <string name=\"compute_percents\">Calcular Porcentagens</string>\n    <string name=\"minimum_value_is\">O valor mínimo é %1$s</string>\n    <string name=\"warp_sub\">Distorcer a imagem desenhando com os dedos</string>\n    <string name=\"warp\">Deformação</string>\n    <string name=\"hardness\">Dureza</string>\n    <string name=\"warp_mode\">Modo de Deformação</string>\n    <string name=\"warp_mode_move\">Mover</string>\n    <string name=\"warp_mode_grow\">Crescer</string>\n    <string name=\"warp_mode_shrink\">Encolher</string>\n    <string name=\"warp_mode_swirl_cw\">Torcer SH</string>\n    <string name=\"warp_mode_swirl_ccw\">Torcer SAH</string>\n    <string name=\"fade_strength\">Força de desbotamento</string>\n    <string name=\"top_drop\">Queda superior</string>\n    <string name=\"bottom_drop\">Queda inferior</string>\n    <string name=\"start_drop\">Iniciar queda</string>\n    <string name=\"end_drop\">Fim da queda</string>\n    <string name=\"downloading\">Baixando</string>\n    <string name=\"smooth_shapes\">Formas Suaves</string>\n    <string name=\"smooth_shapes_sub\">Use superelipses em vez de retângulos arredondados padrão para obter formas mais suaves e naturais</string>\n    <string name=\"shape_type\">Tipo de forma</string>\n    <string name=\"cut\">Corte</string>\n    <string name=\"rounded\">Arredondado</string>\n    <string name=\"smooth\">Suave</string>\n    <string name=\"cut_shapes_sub\">Arestas vivas sem arredondamento</string>\n    <string name=\"rounded_shapes_sub\">Cantos arredondados clássicos</string>\n    <string name=\"shapes_type\">Tipo de formas</string>\n    <string name=\"corners_size\">Tamanho dos cantos</string>\n    <string name=\"squircle\">Esquilo</string>\n    <string name=\"squircle_shapes_sub\">Elementos de UI elegantes e arredondados</string>\n    <string name=\"filename_format\">Formato do nome do arquivo</string>\n    <string name=\"prefix_pattern_description\">Texto personalizado colocado logo no início do nome do arquivo, perfeito para nomes de projetos, marcas ou tags pessoais.</string>\n    <string name=\"original_filename_pattern_description\">Usa o nome do arquivo original sem extensão, ajudando a manter intacta a identificação da fonte.</string>\n    <string name=\"width_pattern_description\">A largura da imagem em pixels, útil para rastrear alterações de resolução ou resultados de dimensionamento.</string>\n    <string name=\"height_pattern_description\">A altura da imagem em pixels, útil ao trabalhar com proporções ou exportações.</string>\n    <string name=\"random_numbers_pattern_description\">Gera dígitos aleatórios para garantir nomes de arquivos exclusivos; adicione mais dígitos para segurança extra contra duplicatas.</string>\n    <string name=\"sequence_number_pattern_description\">Contador de incremento automático para exportações em lote, ideal ao salvar várias imagens em uma sessão.</string>\n    <string name=\"preset_info_pattern_description\">Insere o nome da predefinição aplicada no nome do arquivo para que você possa lembrar facilmente como a imagem foi processada.</string>\n    <string name=\"scale_mode_pattern_description\">Exibe o modo de dimensionamento da imagem usado durante o processamento, ajudando a distinguir imagens redimensionadas, cortadas ou ajustadas.</string>\n    <string name=\"suffix_pattern_description\">Texto personalizado colocado no final do nome do arquivo, útil para controle de versão como _v2, _edited ou _final.</string>\n    <string name=\"extension_pattern_description\">A extensão do arquivo (png, jpg, webp, etc.), correspondendo automaticamente ao formato real salvo.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Um carimbo de data/hora personalizável que permite definir seu próprio formato por especificação Java para uma classificação perfeita.</string>\n    <string name=\"fling_type\">Tipo de arremesso</string>\n    <string name=\"android_native\">Android nativo</string>\n    <string name=\"ios_style\">Estilo iOS</string>\n    <string name=\"smooth_curve\">Curva Suave</string>\n    <string name=\"quick_stop\">Parada rápida</string>\n    <string name=\"bouncy\">Saltitante</string>\n    <string name=\"floaty\">Flutuante</string>\n    <string name=\"snappy\">Rápido</string>\n    <string name=\"ultra_smooth\">Ultra Suave</string>\n    <string name=\"adaptive\">Adaptativo</string>\n    <string name=\"accessibility_aware\">Consciente de acessibilidade</string>\n    <string name=\"reduced_motion\">Movimento Reduzido</string>\n    <string name=\"android_native_sub\">Física de rolagem nativa do Android</string>\n    <string name=\"smooth_sub\">Rolagem suave e equilibrada para uso geral</string>\n    <string name=\"ios_style_sub\">Comportamento de rolagem semelhante ao iOS de maior fricção</string>\n    <string name=\"smooth_curve_sub\">Curva spline exclusiva para uma sensação de rolagem distinta</string>\n    <string name=\"quick_stop_sub\">Rolagem precisa com parada rápida</string>\n    <string name=\"bouncy_sub\">Rolagem saltitante divertida e responsiva</string>\n    <string name=\"floaty_sub\">Pergaminhos longos e deslizantes para navegação de conteúdo</string>\n    <string name=\"snappy_sub\">Rolagem rápida e responsiva para UIs interativas</string>\n    <string name=\"ultra_smooth_sub\">Rolagem suave premium com impulso estendido</string>\n    <string name=\"adaptive_sub\">Ajusta a física com base na velocidade de arremesso</string>\n    <string name=\"accessibility_aware_sub\">Respeita as configurações de acessibilidade do sistema</string>\n    <string name=\"reduced_motion_sub\">Movimento mínimo para necessidades de acessibilidade</string>\n    <string name=\"primary_lines\">Linhas Primárias</string>\n    <string name=\"primary_lines_sub\">Adiciona linha mais grossa a cada quinta linha</string>\n    <string name=\"fill_color\">Cor de preenchimento</string>\n    <string name=\"hidden_tools\">Ferramentas ocultas</string>\n    <string name=\"hidden_for_share\">Ferramentas ocultas para compartilhamento</string>\n    <string name=\"color_library\">Biblioteca de cores</string>\n    <string name=\"color_library_sub\">Navegue por uma vasta coleção de cores</string>\n    <string name=\"model_fatality_deblur\">Torna mais nítida e remove o desfoque das imagens, mantendo os detalhes naturais, ideal para corrigir fotos fora de foco.</string>\n    <string name=\"model_unresize_v3\">Restaura de forma inteligente imagens que foram redimensionadas anteriormente, recuperando detalhes e texturas perdidas.</string>\n    <string name=\"model_liveaction_v1_span\">Otimizado para conteúdo de ação ao vivo, reduz artefatos de compactação e aprimora detalhes finos em quadros de filmes/programas de TV.</string>\n    <string name=\"model_vhs2hd_realplksr\">Converte imagens com qualidade VHS em HD, removendo o ruído da fita e melhorando a resolução, preservando a sensação vintage.</string>\n    <string name=\"model_text2hd_v1\">Especializado para imagens e capturas de tela com muito texto, torna os caracteres mais nítidos e melhora a legibilidade.</string>\n    <string name=\"model_frankendata_pretrainer\">Upscaling avançado treinado em diversos conjuntos de dados, excelente para aprimoramento de fotos de uso geral.</string>\n    <string name=\"model_realwebphoto_v2\">Otimizado para fotos compactadas na Web, remove artefatos JPEG e restaura a aparência natural.</string>\n    <string name=\"model_realwebphoto_v4\">Versão aprimorada para fotos da web com melhor preservação de textura e redução de artefatos.</string>\n    <string name=\"model_dat_2x\">Upscaling 2x com tecnologia Dual Aggregation Transformer, mantém a nitidez e os detalhes naturais.</string>\n    <string name=\"model_dat_3x\">Upscaling 3x usando arquitetura de transformador avançada, ideal para necessidades moderadas de ampliação.</string>\n    <string name=\"model_dat_4x\">Upscaling 4x de alta qualidade com rede de transformadores de última geração, preserva detalhes finos em escalas maiores.</string>\n    <string name=\"model_nafnet_deblurring\">Remove desfoque/ruído e tremores das fotos. Uso geral, mas melhor em fotos.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Restaura imagens de baixa qualidade usando o transformador Swin2SR, otimizado para degradação BSRGAN. Ótimo para corrigir artefatos de compactação pesada e aprimorar detalhes em escala 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Upscaling 4x com transformador SwinIR treinado na degradação BSRGAN. Usa GAN para texturas mais nítidas e detalhes mais naturais em fotos e cenas complexas.</string>\n    <string name=\"path\">Caminho</string>\n    <string name=\"merge_pdf\">Mesclar PDF</string>\n    <string name=\"merge_pdf_sub\">Combine vários arquivos PDF em um documento</string>\n    <string name=\"files_order\">Ordem dos arquivos</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Dividir PDF</string>\n    <string name=\"split_pdf_sub\">Extraia páginas específicas de um documento PDF</string>\n    <string name=\"rotate_pdf\">Girar PDF</string>\n    <string name=\"rotate_pdf_sub\">Corrija a orientação da página permanentemente</string>\n    <string name=\"pages\">Páginas</string>\n    <string name=\"rearrange_pdf\">Reorganizar PDF</string>\n    <string name=\"rearrange_pdf_sub\">Arraste e solte páginas para reordená-las</string>\n    <string name=\"hold_drag_drop\">Segure e arraste páginas</string>\n    <string name=\"page_numbers\">Números de página</string>\n    <string name=\"page_numbers_sub\">Adicione numeração aos seus documentos automaticamente</string>\n    <string name=\"label_format\">Formato da etiqueta</string>\n    <string name=\"pdf_to_text\">PDF para texto (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extraia texto simples de seus documentos PDF</string>\n    <string name=\"watermark_pdf_sub\">Sobreponha texto personalizado para marca ou segurança</string>\n    <string name=\"signature\">Assinatura</string>\n    <string name=\"signature_sub\">Adicione sua assinatura eletrônica a qualquer documento</string>\n    <string name=\"will_be_for_signature\">Isso será usado como assinatura</string>\n    <string name=\"unlock_pdf\">Desbloquear PDF</string>\n    <string name=\"unlock_pdf_sub\">Remova senhas de seus arquivos protegidos</string>\n    <string name=\"protect_pdf\">Proteger PDF</string>\n    <string name=\"protect_pdf_sub\">Proteja seus documentos com criptografia forte</string>\n    <string name=\"success\">Sucesso</string>\n    <string name=\"pdf_unlocked\">PDF desbloqueado, você pode salvá-lo ou compartilhá-lo</string>\n    <string name=\"repair_pdf\">Reparar PDF</string>\n    <string name=\"repair_pdf_sub\">Tentativa de consertar documentos corrompidos ou ilegíveis</string>\n    <string name=\"grayscale\">Tons de cinza</string>\n    <string name=\"grayscale_pdf_sub\">Converta todas as imagens incorporadas em documentos em tons de cinza</string>\n    <string name=\"compress_pdf\">Compactar PDF</string>\n    <string name=\"compress_pdf_sub\">Otimize o tamanho do arquivo do seu documento para facilitar o compartilhamento</string>\n    <string name=\"repair_info\">ImageToolbox reconstrói a tabela de referência cruzada interna e regenera a estrutura do arquivo do zero. Isso pode restaurar o acesso a muitos arquivos que \\\"não podem ser abertos\\\"</string>\n    <string name=\"grayscale_info\">Esta ferramenta converte todas as imagens de documentos em tons de cinza. Melhor para imprimir e reduzir o tamanho do arquivo</string>\n    <string name=\"metadata\">Metadados</string>\n    <string name=\"metadata_pdf_sub\">Edite as propriedades do documento para melhor privacidade</string>\n    <string name=\"tags\">Etiquetas</string>\n    <string name=\"producer\">Produtor</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Palavras-chave</string>\n    <string name=\"creator\">Criador</string>\n    <string name=\"privacy_deep_clean\">Limpeza Profunda de Privacidade</string>\n    <string name=\"privacy_deep_clean_sub\">Limpe todos os metadados disponíveis para este documento</string>\n    <string name=\"page\">Página</string>\n    <string name=\"deep_ocr\">OCR profundo</string>\n    <string name=\"deep_ocr_sub\">Extraia o texto do documento e armazene-o em um arquivo de texto usando o mecanismo Tesseract</string>\n    <string name=\"cant_remove_all\">Não é possível remover todas as páginas</string>\n    <string name=\"remove_pages_pdf\">Remover páginas PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Remova páginas específicas do documento PDF</string>\n    <string name=\"tap_to_remove\">Toque para remover</string>\n    <string name=\"manually\">Manualmente</string>\n    <string name=\"crop_pdf\">Cortar PDF</string>\n    <string name=\"crop_pdf_sub\">Cortar páginas do documento em qualquer limite</string>\n    <string name=\"flatten_pdf\">Achatar PDF</string>\n    <string name=\"flatten_pdf_sub\">Torne o PDF inalterável rasterizando as páginas do documento</string>\n    <string name=\"camera_failed_to_open\">Não foi possível iniciar a câmera. Verifique as permissões e certifique-se de que não esteja sendo usado por outro aplicativo.</string>\n    <string name=\"extract_images\">Extrair imagens</string>\n    <string name=\"extract_images_sub\">Extraia imagens incorporadas em PDFs em sua resolução original</string>\n    <string name=\"pdf_no_embedded\">Este arquivo PDF não contém imagens incorporadas</string>\n    <string name=\"extract_images_info\">Esta ferramenta digitaliza todas as páginas e recupera imagens originais de qualidade total – perfeita para salvar originais de documentos</string>\n    <string name=\"draw_signature\">Desenhar Assinatura</string>\n    <string name=\"pen_params\">Parâmetros de caneta</string>\n    <string name=\"draw_signature_sub\">Utilizar assinatura própria como imagem a ser colocada em documentos</string>\n    <string name=\"zip_pdf\">Compactar PDF</string>\n    <string name=\"zip_pdf_sub\">Divida o documento com determinado intervalo e empacote novos documentos em arquivo zip</string>\n    <string name=\"interval\">Intervalo</string>\n    <string name=\"print_pdf\">Imprimir PDF</string>\n    <string name=\"print_pdf_sub\">Prepare o documento para impressão com tamanho de página personalizado</string>\n    <string name=\"pages_per_sheet\">Páginas por folha</string>\n    <string name=\"orientation\">Orientação</string>\n    <string name=\"page_size\">Tamanho da página</string>\n    <string name=\"margin\">Margem</string>\n    <string name=\"bloom\">Florescer</string>\n    <string name=\"soft_knee\">Joelho macio</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Otimizado para anime e desenhos animados. Aprimoramento rápido com cores naturais aprimoradas e menos artefatos</string>\n    <string name=\"one_ui_sub\">Estilo semelhante ao Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Insira símbolos matemáticos básicos aqui para calcular o valor desejado (por exemplo, (5+5)*10)</string>\n    <string name=\"math_expression\">Expressão matemática</string>\n    <string name=\"pick_up_to_n_collage_images\">Selecione até %1$s imagens</string>\n    <string name=\"keep_date_time\">Manter data e hora</string>\n    <string name=\"keep_date_time_sub\">Sempre preserve tags exif relacionadas à data e hora, funciona independentemente da opção manter exif</string>\n    <string name=\"background_color_for_alpha_formats\">Cor de fundo para formatos alfa</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Adiciona a capacidade de definir a cor de fundo para cada formato de imagem com suporte alfa, quando desabilitado, disponível apenas para formatos não alfa</string>\n    <string name=\"open_markup_project\">Abrir projeto</string>\n    <string name=\"open_markup_project_sub\">Continue editando um projeto do Image Toolbox salvo anteriormente</string>\n    <string name=\"markup_project_open_failed\">Não é possível abrir o projeto do Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">O projeto do Image Toolbox está faltando dados do projeto</string>\n    <string name=\"markup_project_corrupted\">O projeto do Image Toolbox está corrompido</string>\n    <string name=\"unsupported_markup_project_version\">Versão do projeto do Image Toolbox não compatível: %1$d</string>\n    <string name=\"save_markup_project\">Salvar projeto</string>\n    <string name=\"save_markup_project_sub\">Armazene camadas, plano de fundo e histórico de edição em um arquivo de projeto editável</string>\n    <string name=\"failed_to_open\">Falha ao abrir</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Escreva em PDF pesquisável</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Reconheça texto de lote de imagens e salve PDF pesquisável com imagem e camada de texto selecionável</string>\n    <string name=\"layer_alpha\">Camada alfa</string>\n    <string name=\"horizontal_flip\">Inversão Horizontal</string>\n    <string name=\"vertical_flip\">Inversão Vertical</string>\n    <string name=\"lock\">Trancar</string>\n    <string name=\"add_shadow\">Adicionar sombra</string>\n    <string name=\"shadow_color\">Cor da sombra</string>\n    <string name=\"text_geometry\">Geometria do texto</string>\n    <string name=\"text_geometry_sub\">Esticar ou inclinar o texto para uma estilização mais nítida</string>\n    <string name=\"scale_x\">Escala X</string>\n    <string name=\"skew_x\">Inclinar X</string>\n    <string name=\"remove_annotations\">Remover anotações</string>\n    <string name=\"remove_annotations_sub\">Remova os tipos de anotação selecionados, como links, comentários, destaques, formas ou campos de formulário das páginas PDF</string>\n    <string name=\"annotation_link\">Hiperlinks</string>\n    <string name=\"annotation_file_attachment\">Anexos de arquivo</string>\n    <string name=\"annotation_line\">Linhas</string>\n    <string name=\"annotation_popup\">Pop-ups</string>\n    <string name=\"annotation_stamp\">Selos</string>\n    <string name=\"annotation_shapes\">Formas</string>\n    <string name=\"annotation_text\">Notas de texto</string>\n    <string name=\"annotation_text_markup\">Marcação de texto</string>\n    <string name=\"annotation_widget\">Campos de formulário</string>\n    <string name=\"annotation_markup\">Marcação</string>\n    <string name=\"annotation_unknown\">Desconhecido</string>\n    <string name=\"annotations\">Anotações</string>\n    <string name=\"ungroup\">Desagrupar</string>\n    <string name=\"add_shadow_sub\">Adicione sombra desfocada atrás da camada com cores e deslocamentos configuráveis</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ro/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"size\">Mărime %1$s</string>\n    <string name=\"height\">Înălțime %1$s</string>\n    <string name=\"quality\">Calitatea</string>\n    <string name=\"extension\">Extensie</string>\n    <string name=\"resize_type\">Tip de redimensionare</string>\n    <string name=\"explicit\">Explicit</string>\n    <string name=\"flexible\">Flexibil</string>\n    <string name=\"app_closing\">Închidere aplicație</string>\n    <string name=\"stay\">Rămâneți</string>\n    <string name=\"close\">Închideți</string>\n    <string name=\"reset_image\">Resetare imagine</string>\n    <string name=\"reset_image_sub\">Imaginele modificate vor fi readuse la valorile inițiale</string>\n    <string name=\"values_reset\">Valori resetate corespunzător</string>\n    <string name=\"reset\">Resetare</string>\n    <string name=\"restart_app\">Repornește aplicația</string>\n    <string name=\"copied\">Copiat în clipboard</string>\n    <string name=\"exception\">Excepție</string>\n    <string name=\"edit_exif\">Editare EXIF</string>\n    <string name=\"ok\">Ok</string>\n    <string name=\"no_exif\">Nu s-au găsit date EXIF</string>\n    <string name=\"add_tag\">Adăugați etichetă</string>\n    <string name=\"clear\">Curăță</string>\n    <string name=\"clear_exif\">Curăță EXIF</string>\n    <string name=\"clear_exif_sub\">Toate datele EXIF al imaginii vor fi șterse. Această acțiune nu poate fi anulată!</string>\n    <string name=\"presets\">Presetări</string>\n    <string name=\"crop\">Decupare</string>\n    <string name=\"image_not_saved\">Salvare</string>\n    <string name=\"image_not_saved_sub\">Toate modificările nesalvate vor fi pierdute, dacă ieșiți acum</string>\n    <string name=\"check_source_code_sub\">Obțineți cele mai recente actualizări, discutați probleme și multe altele</string>\n    <string name=\"single_edit\">Editare unică</string>\n    <string name=\"single_edit_sub\">Modificați specificațiile unei singure imagini date</string>\n    <string name=\"pick_color\">Alegeți culoarea</string>\n    <string name=\"image\">Imagine</string>\n    <string name=\"color_copied\">Culoare copiată</string>\n    <string name=\"crop_sub\">Decupați imaginea la orice limită</string>\n    <string name=\"version\">Versiune</string>\n    <string name=\"keep_exif\">Păstrează EXIF</string>\n    <string name=\"images\">Imagini: %d</string>\n    <string name=\"change_preview\">Modifică previzualizarea</string>\n    <string name=\"remove\">Elimină</string>\n    <string name=\"palette_sub\">Generarea paletei de culori din imaginea dată</string>\n    <string name=\"generate_palette\">Generarea paletei</string>\n    <string name=\"update\">Actualizează</string>\n    <string name=\"unsupported_type\">Tip nesuportat: %1$s</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Dosar de ieșire</string>\n    <string name=\"def\">Implicit</string>\n    <string name=\"custom\">Personalizat</string>\n    <string name=\"device_storage\">Stocarea dispozitivului</string>\n    <string name=\"max_bytes\">Dimensiune maximă în KB</string>\n    <string name=\"compare\">Compară</string>\n    <string name=\"compare_sub\">Compară două imagini date</string>\n    <string name=\"pick_two_images\">Alegeți două imagini pentru a începe</string>\n    <string name=\"pick_images\">Alegeți imagini</string>\n    <string name=\"settings\">Setări</string>\n    <string name=\"night_mode\">Modul de noapte</string>\n    <string name=\"dark\">Întunecat</string>\n    <string name=\"light\">Luminos</string>\n    <string name=\"dynamic_colors\">Culori dinamice</string>\n    <string name=\"customization\">Personalizare</string>\n    <string name=\"allow_image_monet\">Permiteți monetizarea imaginii</string>\n    <string name=\"language\">Limbă</string>\n    <string name=\"image_too_large_preview\">Imaginea este prea mare pentru previzualizare, dar salvarea va fi încercată oricum</string>\n    <string name=\"loading\">Se încarcă…</string>\n    <string name=\"smth_went_wrong\">Ceva nu a mers bine: %1$s</string>\n    <string name=\"pick_image\">Alegeți imaginea pentru a începe</string>\n    <string name=\"width\">Lățime %1$s</string>\n    <string name=\"pick_image_alt\">Alegeți imaginea</string>\n    <string name=\"app_closing_sub\">Ești sigur să închizi aplicația?</string>\n    <string name=\"something_went_wrong\">Ceva nu a mers bine</string>\n    <string name=\"cancel\">Anulare</string>\n    <string name=\"save\">Salvează</string>\n    <string name=\"check_source_code\">Codul sursă</string>\n    <string name=\"pick_color_sub\">Alegeți culoarea din imagine, copiați sau partajați</string>\n    <string name=\"color\">Culoare</string>\n    <string name=\"palette\">Paletă</string>\n    <string name=\"unspecified\">Nespecificat</string>\n    <string name=\"new_version\">Versiune nouă %1$s</string>\n    <string name=\"system\">Sistem</string>\n    <string name=\"no_palette\">Nu se poate genera paleta din imaginea selectată</string>\n    <string name=\"by_bytes_resize\">Redimensionare în funcție de dimensiune</string>\n    <string name=\"by_bytes_resize_sub\">Redimensionează o imagine după dimensiunea dată în KB</string>\n    <string name=\"allow_image_monet_sub\">Dacă este activată, atunci când alegeți o imagine pentru editare, culorile aplicației vor fi adoptate pentru această imagine</string>\n    <string name=\"amoled_mode\">Modul Amoled</string>\n    <string name=\"amoled_mode_sub\">Dacă este activată, culoarea suprafețelor va fi setată la întuneric absolut în modul de noapte</string>\n    <string name=\"color_red\">Roșu</string>\n    <string name=\"color_green\">Verde</string>\n    <string name=\"color_blue\">Albastru</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Lipiți codul aRGB valid.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nimic de lipit</string>\n    <string name=\"color_scheme\">Schema de culori</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Nu se poate schimba schema de culori a aplicației în timp ce culorile dinamice sunt activate</string>\n    <string name=\"pick_accent_color\">Tema aplicației se va baza pe culoarea selectată</string>\n    <string name=\"about_app\">Despre aplicație</string>\n    <string name=\"no_updates\">Nu s-au găsit actualizări</string>\n    <string name=\"issue_tracker\">Detector de probleme</string>\n    <string name=\"issue_tracker_sub\">Trimiteți rapoarte de erori și solicitări de caracteristici aici</string>\n    <string name=\"help_translate\">Ajutați la traducere</string>\n    <string name=\"search_here\">Căutați aici</string>\n    <string name=\"help_translate_sub\">Corectarea greșelilor de traducere sau localizarea proiectului în alte limbi</string>\n    <string name=\"nothing_found_by_search\">Interogarea dvs. nu a găsit nimic</string>\n    <string name=\"dynamic_colors_sub\">Dacă este activată, atunci culorile aplicației vor fi adoptate la culorile fundalului</string>\n    <string name=\"failed_to_save\">Nu a reușit să salveze imagini %d</string>\n    <string name=\"surface\">Suprafață</string>\n    <string name=\"primary\">Principal</string>\n    <string name=\"tertiary\">Terțiar</string>\n    <string name=\"secondary\">Secundar</string>\n    <string name=\"border_thickness\">Grosimea marginii</string>\n    <string name=\"donation_sub\">Această aplicație este complet gratuită, dar dacă doriți să sprijiniți dezvoltarea proiectului, puteți face clic aici</string>\n    <string name=\"values\">Valori</string>\n    <string name=\"add\">Adăugare</string>\n    <string name=\"permission\">Permisiune</string>\n    <string name=\"grant\">Acordă</string>\n    <string name=\"permission_sub\">Aplicația are nevoie de acces la spațiul dvs. de stocare pentru a salva imagini pentru a funcționa, este necesar. Vă rugăm să acordați permisiunea în caseta de dialog următoare.</string>\n    <string name=\"grant_permission_manual\">Aplicația necesită această permisiune pentru a funcționa, acordă-l manual</string>\n    <string name=\"external_storage\">Stocare externă</string>\n    <string name=\"monet_colors\">Culori monet</string>\n    <string name=\"fab_alignment\">Alinierea FAB</string>\n    <string name=\"check_updates\">Verifică dacă există actualizări</string>\n    <string name=\"check_updates_sub\">Dacă este activată, dialogul de actualizare vă va fi afișat la pornirea aplicației</string>\n    <string name=\"zoom\">Mărește imaginea</string>\n    <string name=\"prefix\">Prefix</string>\n    <string name=\"filename\">Numele fișierului</string>\n    <string name=\"share\">Partajare</string>\n    <string name=\"flexible_description\">Redimensionează imaginile în imagini cu o latură lungă dată de parametrul Lățime sau Înălțime, toate calculele de dimensiune vor fi efectuate după salvare - păstrează raportul de aspect</string>\n    <string name=\"hue\">Nuanţă</string>\n    <string name=\"saturation\">Saturare</string>\n    <string name=\"exposure\">Expunere</string>\n    <string name=\"white_balance\">Balans de alb</string>\n    <string name=\"temperature\">Temperatură</string>\n    <string name=\"highlights\">Repere</string>\n    <string name=\"shadows\">Umbre</string>\n    <string name=\"haze\">Ceață</string>\n    <string name=\"slope\">Pantă</string>\n    <string name=\"black_and_white\">Alb-negru</string>\n    <string name=\"line_width\">Lățimea liniei</string>\n    <string name=\"crosshatch\">Hașura încrucișată</string>\n    <string name=\"spacing\">Spațiere</string>\n    <string name=\"sobel_edge\">Marginea Sobel</string>\n    <string name=\"blur\">Estompare</string>\n    <string name=\"start\">Început</string>\n    <string name=\"replace_sequence_number\">Înlocuiți numărul de ordine</string>\n    <string name=\"image_link\">Link imagine</string>\n    <string name=\"fill\">Umplere</string>\n    <string name=\"fit\">Potrivire</string>\n    <string name=\"opacity\">Opacitate</string>\n    <string name=\"scale\">Scară</string>\n    <string name=\"radius\">Rază</string>\n    <string name=\"bulge\">Bulge</string>\n    <string name=\"limits_resize\">Limitele redimensionării</string>\n    <string name=\"limits_resize_sub\">Redimensionarea imaginilor selectate pentru a respecta limitele de lățime și înălțime date, păstrând în același timp raportul de aspect</string>\n    <string name=\"sketch\">Schiță</string>\n    <string name=\"threshold\">Prag</string>\n    <string name=\"non_maximum_suppression\">Suprimare non maximă</string>\n    <string name=\"weak_pixel_inclusion\">Includere slabă a pixelilor</string>\n    <string name=\"lookup\">Priveşte în sus</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Selectați ce emoji va fi afișat pe ecranul principal</string>\n    <string name=\"stack_blur\">Estompare stivă</string>\n    <string name=\"blur_center_y\">Încețoșează centrul y</string>\n    <string name=\"zoom_blur\">Încețoșare zoom</string>\n    <string name=\"add_file_size\">Adăugați dimensiunea fișierului</string>\n    <string name=\"add_file_size_sub\">Dacă este activată, adaugă lățimea și înălțimea imaginii salvate la numele fișierului de ieșire</string>\n    <string name=\"image_preview\">Previzualizare imagine</string>\n    <string name=\"image_preview_sub\">Previzualizați orice tip de imagine: GIF, SVG și așa mai departe</string>\n    <string name=\"photo_picker_sub\">Selector de fotografii modern Android, care apare în partea de jos a ecranului, poate funcționa numai pe Android 12+. Are probleme cu primirea metadatelor EXIF</string>\n    <string name=\"file_explorer_picker_sub\">Utilizați intenția GetContent (Obțineți conținut) pentru a selecta imaginea. Funcționează peste tot, dar se știe că are probleme cu primirea imaginilor selectate pe unele dispozitive. Nu este vina mea.</string>\n    <string name=\"order_sub\">Determină ordinea instrumentelor pe ecranul principal</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"add_original_filename\">Adăugați numele fișierului original</string>\n    <string name=\"add_original_filename_sub\">Dacă este activată, adaugă numele fișierului original în numele imaginii de ieșire</string>\n    <string name=\"replace_sequence_number_sub\">Dacă este activată, înlocuiește marcajul de timp standard cu numărul de secvență a imaginii dacă utilizați procesarea în lot</string>\n    <string name=\"filename_not_work_with_photopicker\">Adăugarea numelui original al fișierului nu funcționează dacă este selectată sursa de imagine a selectorului de fotografii</string>\n    <string name=\"load_image_from_net\">Încărcați imaginea de pe net</string>\n    <string name=\"load_image_from_net_sub\">Încărcați orice imagine de pe internet pentru a o previzualiza, mări, edita și salva dacă doriți.</string>\n    <string name=\"no_image\">Nicio imagine</string>\n    <string name=\"explicit_description\">Forțează fiecare imagine într-o imagine dată de parametrul Lățime și Înălțime - poate schimba raportul de aspect</string>\n    <string name=\"brightness\">Luminozitate</string>\n    <string name=\"contrast\">Contrast</string>\n    <string name=\"add_filter\">Adăugați filtru</string>\n    <string name=\"filter\">Filtru</string>\n    <string name=\"filter_sub\">Aplicați orice lanț de filtre pentru imaginile date</string>\n    <string name=\"filters\">Filtre</string>\n    <string name=\"light_aka_illumination\">Lumină</string>\n    <string name=\"color_filter\">Filtru de culoare</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"tint\">Tentă</string>\n    <string name=\"monochrome\">Monocrom</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Lumini și umbre</string>\n    <string name=\"effect\">Efect</string>\n    <string name=\"distance\">Distanţă</string>\n    <string name=\"sharpen\">Ascuțire</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negativ</string>\n    <string name=\"solarize\">Solarizare</string>\n    <string name=\"vibrance\">Vibranță</string>\n    <string name=\"halftone\">Semitonuri</string>\n    <string name=\"cga_colorspace\">Spațiul de culori CGA</string>\n    <string name=\"emboss\">Grava</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Vinietă</string>\n    <string name=\"end\">Sfârșit</string>\n    <string name=\"kuwahara\">Netezire Kuwahara</string>\n    <string name=\"distortion\">Deformare</string>\n    <string name=\"angle\">Unghi</string>\n    <string name=\"swirl\">Vârtej</string>\n    <string name=\"dilation\">Dilatarea</string>\n    <string name=\"sphere_refraction\">Refracția sferei</string>\n    <string name=\"refractive_index\">Indicele de refracție</string>\n    <string name=\"glass_sphere_refraction\">Refracția sferei de sticlă</string>\n    <string name=\"color_matrix\">Matricea de culori</string>\n    <string name=\"quantizationLevels\">Niveluri de cuantizare</string>\n    <string name=\"smooth_toon\">Toon neted</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterizați</string>\n    <string name=\"convolution3x3\">Convoluție 3x3</string>\n    <string name=\"rgb_filter\">filtru RGB</string>\n    <string name=\"false_color\">Culoare falsă</string>\n    <string name=\"first_color\">Prima culoare</string>\n    <string name=\"second_color\">A doua culoare</string>\n    <string name=\"reorder\">Reordonați</string>\n    <string name=\"blur_size\">Dimensiune estompare</string>\n    <string name=\"blur_center_x\">Încețoșează centrul x</string>\n    <string name=\"color_balance\">Echilibrul culorilor</string>\n    <string name=\"luminance_threshold\">Pragul de luminanță</string>\n    <string name=\"delete_exif\">Ștergeți EXIF</string>\n    <string name=\"delete_exif_sub\">Ștergeți metadatele EXIF din orice set de imagini</string>\n    <string name=\"image_source\">Sursa imaginii</string>\n    <string name=\"photo_picker\">Selector de fotografii</string>\n    <string name=\"gallery_picker\">Galerie</string>\n    <string name=\"file_explorer_picker\">Explorator de fișiere</string>\n    <string name=\"gallery_picker_sub\">Selector simplu de imagini pentru galerie. Acesta va funcționa numai dacă aveți o aplicație care oferă selectare media</string>\n    <string name=\"options_arrangement\">Aranjament de opțiuni</string>\n    <string name=\"edit\">Editare</string>\n    <string name=\"order\">Ordine</string>\n    <string name=\"content_scale\">Scara de conținut</string>\n    <string name=\"emojis_count\">Numărul de emoji</string>\n    <string name=\"file_proceed\">Fișier procesat</string>\n    <string name=\"pick_file\">Alegeți fișierul</string>\n    <string name=\"compatibility\">Compatibilitate</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"features_sub\">Criptarea fișierelor pe bază de parolă. Fișierele procesate pot fi stocate în directorul selectat sau partajate. De asemenea, fișierele decriptate pot fi deschise direct.</string>\n    <string name=\"implementation_sub\">AES-256, modul GCM, fără umplutură, IV-uri aleatoare de 12 octeți. Cheile sunt folosite ca hash-uri SHA-3 (256 de biți).</string>\n    <string name=\"file_size_sub\">Dimensiunea maximă a fișierului este restricționată de sistemul de operare Android și de memoria disponibilă, care depinde în mod evident de dispozitivul dvs. \\nVă rugăm să rețineți: memoria nu este stocare.</string>\n    <string name=\"image_size_warning\">Încercarea de a salva imaginea cu lățimea și înălțimea date poate cauza o eroare OOM. Faceți acest lucru pe propriul risc și să nu spuneți că nu v-am avertizat!</string>\n    <string name=\"found_s\">S-a găsit %1$s</string>\n    <string name=\"auto_cache_clearing\">Ștergerea automată a memoriei cache</string>\n    <string name=\"tools\">Instrumente</string>\n    <string name=\"group_options_by_type\">Grupați opțiunile după tip</string>\n    <string name=\"group_options_by_type_sub\">Grupează opțiunile de pe ecranul principal în funcție de tipul lor, în loc de un aranjament personalizat al listei</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Nu se poate modifica aranjamentul în timp ce gruparea opțiunilor este activată</string>\n    <string name=\"edit_screenshot\">Editați captura de ecran</string>\n    <string name=\"secondary_customization\">Personalizare secundară</string>\n    <string name=\"screenshot\">Captură de ecran</string>\n    <string name=\"invalid_password_or_not_encrypted\">Parola nevalidă sau fișierul ales nu este criptat</string>\n    <string name=\"fallback_option\">Opțiune de rezervă</string>\n    <string name=\"copy\">Copiere</string>\n    <string name=\"activate_files\">Ați dezactivat aplicația Fișiere, activați-o pentru a utiliza această caracteristică</string>\n    <string name=\"warning_bytes\">Salvarea în modul %1$s poate fi instabilă, deoarece este un format fără pierderi</string>\n    <string name=\"auto_cache_clearing_sub\">Dacă este activată, memoria cache a aplicației va fi ștearsă la pornirea aplicației</string>\n    <string name=\"skip\">Ocolire</string>\n    <string name=\"cache_size\">Mărimea cache-ului</string>\n    <string name=\"create\">Creare</string>\n    <string name=\"encrypt\">Criptare</string>\n    <string name=\"decrypt\">Decriptare</string>\n    <string name=\"pick_file_to_start\">Alegeți fișierul pentru a începe</string>\n    <string name=\"decryption\">Decriptare</string>\n    <string name=\"implementation\">Implementarea</string>\n    <string name=\"draw_sub\">Desenați pe imagine ca într-un caiet de schițe sau desenați pe fundal</string>\n    <string name=\"draw_on_image_sub\">Alegeți o imagine și desenați ceva pe ea</string>\n    <string name=\"draw_on_background\">Desenați pe fundal</string>\n    <string name=\"draw_on_background_sub\">Alegeți culoarea de fundal și desenați deasupra ei</string>\n    <string name=\"background_color\">Culoarea fundalului</string>\n    <string name=\"compatibility_sub\">Vă rugăm să rețineți că nu este garantată compatibilitatea cu alte programe sau servicii de criptare a fișierelor. Un tratament al cheii sau o configurație de cifrare ușor diferită poate cauza incompatibilitate.</string>\n    <string name=\"file_size\">Mărime fișier</string>\n    <string name=\"draw\">Desenare</string>\n    <string name=\"paint_color\">Culoarea vopselei</string>\n    <string name=\"paint_alpha\">Vopsea alfa</string>\n    <string name=\"draw_on_image\">Desenează pe imagine</string>\n    <string name=\"cipher\">Cifru</string>\n    <string name=\"cipher_sub\">Criptați și decriptați orice fișier (nu numai imaginile) pe baza algoritmului de criptare AES</string>\n    <string name=\"encryption\">Criptare</string>\n    <string name=\"key\">Cheie</string>\n    <string name=\"store_file_desc\">Stocați acest fișier pe dispozitiv sau utilizați acțiunea de partajare pentru a-l pune oriunde doriți</string>\n    <string name=\"features\">Caracteristici</string>\n    <string name=\"crop_mask\">Tăiere mască</string>\n    <string name=\"symbols\">Simboluri</string>\n    <string name=\"objects\">Obiecte</string>\n    <string name=\"enable_emoji\">Activați emoji</string>\n    <string name=\"travels_and_places\">Călătorii și Locuri</string>\n    <string name=\"trim_image_sub\">Spațiile transparente din jurul imaginii vor fi tăiate</string>\n    <string name=\"auto_erase_background\">Ștergere automată a fundalului</string>\n    <string name=\"restore_image\">Restaurați imaginea</string>\n    <string name=\"randomize_filename\">Nume de fișier aleatoriu</string>\n    <string name=\"randomize_filename_sub\">Dacă este activată, numele fișierului de ieșire va fi complet aleatoriu</string>\n    <string name=\"saved_to\">Salvat în dosarul %1$s cu numele %2$s</string>\n    <string name=\"saved_to_without_filename\">Salvat în folderul %1$s</string>\n    <string name=\"tg_chat\">Conversație prin Telegram</string>\n    <string name=\"tg_chat_sub\">Discutați despre aplicație și obțineți feedback de la alți utilizatori. De asemenea, puteți obține actualizări beta și informații de aici.</string>\n    <string name=\"aspect_ratio\">Raportul de aspect</string>\n    <string name=\"image_crop_mask_sub\">Utilizați acest tip de mască pentru a crea o mască din imaginea dată, observați că aceasta TREBUIE să aibă un canal alfa.</string>\n    <string name=\"backup_and_restore\">Backup și restaurare</string>\n    <string name=\"restore\">Restaurare</string>\n    <string name=\"backup_sub\">Salvați setările aplicației într-un fișier</string>\n    <string name=\"alphabet_and_numbers\">Aa Ăă Ââ Bb Cc Dd Ee Ff Gg Hh Ii Îî Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Șș Tt Țț Uu Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"emotions\">Emoții</string>\n    <string name=\"food_and_drink\">Mâncare și băutură</string>\n    <string name=\"nature_and_animals\">Natură și Animale</string>\n    <string name=\"activities\">Activități</string>\n    <string name=\"background_remover\">Eliminarea fundalului</string>\n    <string name=\"background_remover_sub\">Eliminați fundalul din imagine prin desenare sau utilizați opțiunea Auto</string>\n    <string name=\"trim_image\">Tăiați imaginea</string>\n    <string name=\"keep_exif_sub\">Metadatele imaginii originale vor fi păstrate</string>\n    <string name=\"erase_mode\">Mod radieră</string>\n    <string name=\"erase_background\">Ștergeți fundalul</string>\n    <string name=\"resize_and_convert\">Redimensionare și conversie</string>\n    <string name=\"backup\">Backup</string>\n    <string name=\"max_colors_count\">Număr maxim de culori</string>\n    <string name=\"analytics\">Analize</string>\n    <string name=\"settings_restored\">Setări restaurate cu succes</string>\n    <string name=\"contact_me\">Contactați-mă</string>\n    <string name=\"restore_sub\">Restaurați setările aplicației din fișierul generat anterior</string>\n    <string name=\"presets_sub\" formatted=\"false\">Dacă ați selectat presetarea 125, imaginea va fi salvată cu o dimensiune de 125% din imaginea originală. Dacă ați selectat preselecția 50, atunci imaginea va fi salvată cu dimensiunea de 50%</string>\n    <string name=\"restore_background\">Restaurați fundalul</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Fișier coruptat sau nu este un backup</string>\n    <string name=\"reset_settings_sub\">Acest lucru vă va readuce setările la valorile implicite. Rețineți că acest lucru nu poate fi anulat fără un fișier de backup menționat mai sus.</string>\n    <string name=\"delete_color_scheme_title\">Ștergeți schema</string>\n    <string name=\"font\">Font</string>\n    <string name=\"text\">Text</string>\n    <string name=\"delete\">Ștergeți</string>\n    <string name=\"delete_color_scheme_warn\">Sunteți pe cale să ștergeți schema de culori selectată, această operațiune nu poate fi anulată.</string>\n    <string name=\"font_scale\">Scara fontului</string>\n    <string name=\"defaultt\">Implicit</string>\n    <string name=\"using_large_fonts_warn\">Folosirea unor fonturi mari poate cauza erori și probleme ale interfeței utilizator, care nu vor putea fi remediate. Utilizați cu prudență.</string>\n    <string name=\"blur_radius\">Raza de estompare</string>\n    <string name=\"pipette\">Pipetă</string>\n    <string name=\"draw_mode\">Mod de desen</string>\n    <string name=\"create_issue\">Creați o problemă</string>\n    <string name=\"something_went_wrong_emphasis\">Oops… Ceva nu a mers bine. Îmi puteți scrie folosind opțiunile de mai jos și voi încerca să găsesc o soluție</string>\n    <string name=\"resize_and_convert_sub\">Modificați dimensiunea imaginilor date sau convertiți-le în alte formate, de asemenea, acolo puteți edita metadatele EXIF dacă alegeți o singură imagine</string>\n    <string name=\"presets_sub_bytes\">Pre-setarea aici determină % din fișierul de ieșire, de exemplu, dacă selectați pre-setarea 50 pe o imagine de 5 mb, atunci veți obține o imagine de 2,5 mb după salvare</string>\n    <string name=\"crashlytics_sub\">Acest lucru permite aplicației să colecteze rapoarte de crash-uri manual</string>\n    <string name=\"analytics_sub\">Permite colectarea de statistici anonime privind utilizarea aplicației</string>\n    <string name=\"image_exif_warning\">În prezent, formatul %1$s permite doar citirea metadatelor EXIF pe Android. Imaginea de ieșire nu va avea metadate deloc, atunci când este salvată.</string>\n    <string name=\"effort\">Efort</string>\n    <string name=\"updates\">Actualizări</string>\n    <string name=\"wait\">Așteptați</string>\n    <string name=\"effort_sub\">O valoare de %1$s înseamnă că se comprimă rapid, ceea ce duce la o dimensiune relativ mare a fișierului. %2$s înseamnă că trebuie să se petreacă mai mult timp comprimând, rezultând un fișier mai mic.</string>\n    <string name=\"allow_betas\">Permiteți beta</string>\n    <string name=\"saving_almost_complete\">Salvarea este aproape finalizată. Anularea acum va necesita salvarea din nou.</string>\n    <string name=\"allow_betas_sub\">Verificarea actualizărilor va include versiunile beta ale aplicațiilor, dacă este activată</string>\n    <string name=\"brush_softness\">Moliciunea periei</string>\n    <string name=\"draw_arrows\">Desenați săgeți</string>\n    <string name=\"draw_arrows_sub\">Dacă este activată, calea de desen va fi reprezentată ca o săgeată îndreptată</string>\n    <string name=\"crop_description\">Imaginile vor fi decupate central la dimensiunea introdusă. Pânza va fi extinsă cu culoarea de fundal dată dacă imaginea este mai mică decât dimensiunile introduse.</string>\n    <string name=\"donation\">Donație</string>\n    <string name=\"horizontal\">Orizontal</string>\n    <string name=\"recode\">Recodificați</string>\n    <string name=\"tolerance\">Toleranță</string>\n    <string name=\"both\">Ambele</string>\n    <string name=\"images_order\">Ordinea imaginilor</string>\n    <string name=\"fidelity\">Fidelitate</string>\n    <string name=\"blur_edges\">Margini blurate</string>\n    <string name=\"rainbow\">Curcubeu</string>\n    <string name=\"playful_scheme\">O temă jucăușă - nuanța culorii sursă nu apare în temă</string>\n    <string name=\"fading_edges\">Margini decolorate</string>\n    <string name=\"vibrant_sub\">O temă zgomotoasă, coloritul este maxim pentru paleta primară, crescut pentru ceilalți</string>\n    <string name=\"image_stitching\">Coaserea imaginii</string>\n    <string name=\"pixelation\">Pixelare</string>\n    <string name=\"neutral_sub\">Un stil care este puțin mai cromatic decât monocrom</string>\n    <string name=\"enhanced_pixelation\">Pixelare îmbunătățită</string>\n    <string name=\"target_color\">Culoare țintă</string>\n    <string name=\"pick_at_least_two_images\">Alegeți cel puțin 2 imagini</string>\n    <string name=\"foss_update_checker_warning\">Acest verificator de actualizare se va conecta la GitHub pentru a verifica dacă există o nouă actualizare disponibilă.</string>\n    <string name=\"pixel_size\">Dimensiunea pixelului</string>\n    <string name=\"content_sub\">O schemă care plasează culoarea sursă în Scheme.primaryContainer</string>\n    <string name=\"tonal_spot\">Spot tonal</string>\n    <string name=\"replace_color\">Înlocuiți culoarea</string>\n    <string name=\"diamond_pixelation\">Pixelare diamant</string>\n    <string name=\"blur_edges_sub\">Desenează margini neclare sub imaginea originală pentru a umple spațiile din jurul acesteia în loc de o singură culoare, dacă este activată</string>\n    <string name=\"remove_color\">Eliminați culoarea</string>\n    <string name=\"monochrome_sub\">O temă monocromă, culorile sunt pur și simplu negru / alb / gri</string>\n    <string name=\"scale_small_images_to_large_sub\">Imaginile mici vor fi scalate la cea mai mare imagine din secvență, dacă este activată</string>\n    <string name=\"fruit_salad\">Salată de fructe</string>\n    <string name=\"enhanced_diamond_pixelation\">Pixelare diamant îmbunătățite</string>\n    <string name=\"circle_pixelation\">Pixelare circular</string>\n    <string name=\"lock_draw_orientation\">Blocați orientarea desenului</string>\n    <string name=\"image_stitching_sub\">Combinați imaginile date pentru a obține una mare</string>\n    <string name=\"fidelity_sub\">O schemă care este foarte asemănătoare cu schema de conținut</string>\n    <string name=\"check_for_updates\">Verificați pentru actualizări</string>\n    <string name=\"image_orientation\">Orientarea imaginii</string>\n    <string name=\"content\">Conținut</string>\n    <string name=\"disabled\">Dezactivată</string>\n    <string name=\"vertical\">Vertical</string>\n    <string name=\"expressive\">Expresiv</string>\n    <string name=\"neutral\">Neutru</string>\n    <string name=\"color_to_remove\">Culoare de eliminat</string>\n    <string name=\"tonal_spot_sub\">Stilul implicit al paletei, permite personalizarea tuturor celor patru culori, altele vă permit să setați numai culoarea cheie</string>\n    <string name=\"color_to_replace\">Culoare de înlocuit</string>\n    <string name=\"output_image_scale\">Scara imaginii de ieșire</string>\n    <string name=\"lock_draw_orientation_sub\">Dacă este activată în modul desen, ecranul nu se va roti</string>\n    <string name=\"palette_style\">Stilul paletului</string>\n    <string name=\"vibrant\">Vibrant</string>\n    <string name=\"regular\">Regular</string>\n    <string name=\"enhanced_circle_pixelation\">Pixelare circular îmbunătățită</string>\n    <string name=\"attention\">Atenție</string>\n    <string name=\"scale_small_images_to_large\">Scalați imaginile mici la mari</string>\n    <string name=\"invert_colors_sub\">Înlocuiește culorile temei cu cele negative dacă este activată</string>\n    <string name=\"search_option\">Căutați</string>\n    <string name=\"search_option_sub\">Permite posibilitatea de a căuta prin toate instrumentele disponibile pe ecranul principal</string>\n    <string name=\"invert_colors\">Inversați culorile</string>\n    <string name=\"pdf_tools\">Instrumente PDF</string>\n    <string name=\"mask_filter\">Filtru mască</string>\n    <string name=\"images_to_pdf\">Imagini în PDF</string>\n    <string name=\"masks\">Măști</string>\n    <string name=\"preview_pdf\">Previzualizare PDF</string>\n    <string name=\"pdf_to_images\">PDF în Imagini</string>\n    <string name=\"images_to_pdf_sub\">Împachetați imaginile date într-un fișier PDF</string>\n    <string name=\"preview_pdf_sub\">Previzualizare PDF simplu</string>\n    <string name=\"add_mask\">Adăugați mască</string>\n    <string name=\"pdf_tools_sub\">Operați cu fișiere PDF: Previzualizați, convertiți în lot de imagini sau creați una din imaginile date</string>\n    <string name=\"mask_indexed\">Masca %d</string>\n    <string name=\"pdf_to_images_sub\">Convertiți PDF în imagini în formatul de ieșire dat</string>\n    <string name=\"enhanced_glitch\">Glitch îmbunătățit</string>\n    <string name=\"channel_shift_x\">Schimbarea canalului X</string>\n    <string name=\"channel_shift_y\">Schimbarea canalului Y</string>\n    <string name=\"corruption_size\">Dimensiunea corupției</string>\n    <string name=\"top\">Top</string>\n    <string name=\"bottom\">Fund</string>\n    <string name=\"strength\">Putere</string>\n    <string name=\"segmentation_mode_single_column\">O singură coloană</string>\n    <string name=\"segmentation_mode_single_block\">Bloc unic</string>\n    <string name=\"glitch\">Eroare</string>\n    <string name=\"amount\">Cantitate</string>\n    <string name=\"seed\">Sămânță</string>\n    <string name=\"anaglyph\">Anaglifă</string>\n    <string name=\"noise\">Zgomot</string>\n    <string name=\"pixel_sort\">Sortare pixeli</string>\n    <string name=\"shuffle\">Amesteca</string>\n    <string name=\"delete_mask\">Ștergeți masca</string>\n    <string name=\"delete_mask_warn\">Sunteți pe cale să ștergeți masca de filtru selectată. Această operațiune nu poate fi anulată</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"no_such_directory\">Nu s-a găsit niciun director \\\"%1$s\\\", l-am schimbat la unul implicit, salvați din nou fișierul</string>\n    <string name=\"clipboard\">Clipboard</string>\n    <string name=\"auto_pin\">Fixare automată</string>\n    <string name=\"auto_pin_sub\">Adaugă automat imaginea salvată în clipboard dacă este activată</string>\n    <string name=\"vibration\">Vibrație</string>\n    <string name=\"vibration_strength\">Puterea la vibrație</string>\n    <string name=\"overwrite_file_requirements\">Pentru a suprascrie fișierele, trebuie să utilizați sursa de imagine \\\"Explorer\\\", încercați să alegeți din nou imaginile, am schimbat sursa imaginii cu cea necesară</string>\n    <string name=\"overwrite_files_sub\">Fișierul original va fi înlocuit cu unul nou în loc să fie salvat în folderul selectat, această opțiune trebuie ca sursa imaginii să fie \\\"Explorer\\\" sau GetContent, când comutați, va fi setată automat</string>\n    <string name=\"empty\">Gol</string>\n    <string name=\"free\">Gratuit</string>\n    <string name=\"emoji_as_color_scheme\">Emoji ca schemă de culori</string>\n    <string name=\"mask_filter_sub\">Aplicați lanțuri de filtre pe anumite zone mascate, fiecare zonă de mască poate determina propriul set de filtre</string>\n    <string name=\"simple_variants\">Variante simple</string>\n    <string name=\"highlighter\">Evidențiator</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Pix</string>\n    <string name=\"privacy_blur\">Confidențialitate estompare</string>\n    <string name=\"highlighter_sub\">Desenați trasee de iluminare ascuțite semi-transparente</string>\n    <string name=\"neon_sub\">Adăugați un efect de strălucire desenelor dvs.</string>\n    <string name=\"pen_sub\">Una implicită, cea mai simplă - doar culoarea</string>\n    <string name=\"privacy_blur_sub\">Estompează imaginea sub traseul desenat pentru a securiza tot ce doriți să ascundeți</string>\n    <string name=\"pixelation_sub\">Similar cu ceața de confidențialitate, dar pixelizează în loc să blureze</string>\n    <string name=\"switches_shadow_sub\">Activează desenarea umbrelor în spatele comutatoarelor</string>\n    <string name=\"fabs_shadow_sub\">Activează desenarea umbrelor în spatele butoanelor de acțiune plutitoare</string>\n    <string name=\"buttons_shadow_sub\">Activează desenarea umbrelor în spatele butoanelor implicite</string>\n    <string name=\"app_bars_shadow_sub\">Activează desenarea umbrelor în spatele barelor aplicației</string>\n    <string name=\"auto_rotate_limits\">Rotire automată</string>\n    <string name=\"auto_rotate_limits_sub\">Permite adoptarea casetei de limită pentru orientarea imaginii</string>\n    <string name=\"double_line_arrow_sub\">Desenează săgeată dublă indicatoare de la punctul de început până la punctul final ca o linie</string>\n    <string name=\"outlined_oval_sub\">Desenează un oval conturat de la punctul de început până la punctul final</string>\n    <string name=\"outlined_rect_sub\">Desenează drept conturat de la punctul de început până la punctul final</string>\n    <string name=\"overwrite_files\">Suprascrieți fișierele</string>\n    <string name=\"suffix\">Sufix</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"bilinear_sub\">Interpolarea liniară (sau biliniară, în două dimensiuni) este, de obicei, bună pentru a schimba dimensiunea unei imagini, dar provoacă o oarecare înmuiere nedorită a detaliilor și poate fi totuși oarecum dințată</string>\n    <string name=\"bicubic_sub\">Metodele de scalare mai bune includ reeșantionarea Lanczos și filtrele Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Una dintre cele mai simple modalități de creștere a dimensiunii, înlocuind fiecare pixel cu un număr de pixeli de aceeași culoare</string>\n    <string name=\"basic_sub\">Cel mai simplu mod de scalare Android utilizat în aproape toate aplicațiile</string>\n    <string name=\"catmull_sub\">Metodă pentru interpolarea fără probleme și reeșantionarea unui set de puncte de control, utilizată în mod obișnuit în grafica computerizată pentru a crea curbe netede</string>\n    <string name=\"hann_sub\">Funcția de fereastră aplicată adesea în procesarea semnalului pentru a minimiza scurgerea spectrală și pentru a îmbunătăți acuratețea analizei de frecvență prin înclinarea marginilor unui semnal</string>\n    <string name=\"hermite_sub\">Tehnica de interpolare matematică care utilizează valorile și derivatele la punctele finale ale unui segment de curbă pentru a genera o curbă netedă și continuă</string>\n    <string name=\"lanczos_sub\">Metodă de reeșantionare care menține interpolarea de înaltă calitate prin aplicarea unei funcții sinc ponderate la valorile pixelilor</string>\n    <string name=\"mitchell_sub\">Metodă de reeșantionare care utilizează un filtru de convoluție cu parametri ajustabili pentru a obține un echilibru între claritate și anti-aliasing în imaginea scalată</string>\n    <string name=\"spline_sub\">Utilizează funcții polinomiale definite în bucăți pentru a interpola fără probleme și a aproxima o curbă sau o suprafață, o reprezentare flexibilă și continuă a formei</string>\n    <string name=\"only_clip_sub\">Salvarea în spațiul de stocare nu va fi efectuată, iar imaginea va fi încercată să fie pusă doar în clipboard</string>\n    <string name=\"allow_multiple_languages\">Permite mai multe limbi</string>\n    <string name=\"segmentation_mode_osd_only\">Numai orientare și detectarea scripturilor</string>\n    <string name=\"segmentation_mode_auto_osd\">Orientare automată și detectarea scripturilor</string>\n    <string name=\"segmentation_mode_auto_only\">Doar automat</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Text vertical cu un singur bloc</string>\n    <string name=\"segmentation_mode_single_line\">O singura linie</string>\n    <string name=\"segmentation_mode_single_word\">Un singur cuvânt</string>\n    <string name=\"segmentation_mode_circle_word\">Cuvânt în cerc</string>\n    <string name=\"segmentation_mode_single_char\">Un singur caracter</string>\n    <string name=\"segmentation_mode_sparse_text\">Text rar</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Orientarea textului dispersat și detectarea scripturilor</string>\n    <string name=\"segmentation_mode_raw_line\">Linie brută</string>\n    <string name=\"delete_language_sub\">Doriți să ștergeți datele de antrenament OCR în limba \\\"%1$s\\\" pentru toate tipurile de recunoaștere sau numai pentru unul selectat (%2$s)?</string>\n    <string name=\"color_stops\">Color Stops</string>\n    <string name=\"add_color\">Adăugați culoare</string>\n    <string name=\"properties\">Proprietăți</string>\n    <string name=\"repeat_watermark_sub\">Repetă filigranul peste imagine în loc de unul singur în poziția dată</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermarking_image_sub\">Această imagine va fi folosită ca model pentru filigranare</string>\n    <string name=\"frame_delay\">Întârziere de cadru</string>\n    <string name=\"millis\">milis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizier</string>\n    <string name=\"gray_scale\">Scara tonurilor de gri</string>\n    <string name=\"bayer_two_dithering\">Bayer Two Cat Two Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Fals Floyd Steinberg Dithering</string>\n    <string name=\"b_spline_sub\">Utilizează funcții polinomiale bicubice definite în bucăți pentru a interpola fără probleme și a aproxima o curbă sau o suprafață, o reprezentare flexibilă și continuă a formei</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"corruption_shift_x\">Corupția Shift X</string>\n    <string name=\"corruption_shift_y\">Schimbul de corupție Y</string>\n    <string name=\"tent_blur\">Cort Blur</string>\n    <string name=\"side_fade\">Fade lateral</string>\n    <string name=\"side\">Latură</string>\n    <string name=\"erode\">Eroda</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">Maparea tonurilor logaritmice</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"crystallize\">Cristaliza</string>\n    <string name=\"turbulence\">Turbulenţă</string>\n    <string name=\"oil\">Ulei</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"color_matrix_4x4\">Color Matrix 4x4</string>\n    <string name=\"color_matrix_3x3\">Color Matrix 3x3</string>\n    <string name=\"simple_effects\">Efecte simple</string>\n    <string name=\"polaroid\">polaroid</string>\n    <string name=\"tritonomaly\">Tritanomalie</string>\n    <string name=\"deutaromaly\">Deuteranomalie</string>\n    <string name=\"protonomaly\">Protanomalie</string>\n    <string name=\"vintage\">Epocă</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Vedere nocturnă</string>\n    <string name=\"warm\">Cald</string>\n    <string name=\"cool\">Misto</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deuteranopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Acromatomalie</string>\n    <string name=\"achromatopsia\">Acromatopsie</string>\n    <string name=\"orange_haze\">Orange Haze</string>\n    <string name=\"pink_dream\">Visul roz</string>\n    <string name=\"soft_spring_light\">Lumină moale de primăvară</string>\n    <string name=\"lavender_dream\">Visul de lavandă</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Lumină de limonadă</string>\n    <string name=\"spectral_fire\">Foc spectral</string>\n    <string name=\"night_magic\">Magia Nopții</string>\n    <string name=\"caramel_darkness\">Întunericul Caramel</string>\n    <string name=\"futuristic_gradient\">Gradient futurist</string>\n    <string name=\"green_sun\">Soarele Verde</string>\n    <string name=\"rainbow_world\">Lumea Curcubeului</string>\n    <string name=\"deep_purple\">Mov inchis</string>\n    <string name=\"space_portal\">Portalul Spațial</string>\n    <string name=\"no_favorite_filters\">Nu au fost adăugate filtre favorite încă</string>\n    <string name=\"icon_shape\">Forma pictogramei</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">A tăia calea</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Tranziție</string>\n    <string name=\"peak\">Vârf</string>\n    <string name=\"color_anomaly\">Anomalie de culoare</string>\n    <string name=\"images_overwritten\">Imaginile suprascrise la destinația inițială</string>\n    <string name=\"cannot_change_image_format\">Nu se poate schimba formatul imaginii când este activată opțiunea de suprascriere a fișierelor</string>\n    <string name=\"emoji_as_color_scheme_sub\">Utilizează culoarea primară emoji ca schemă de culori a aplicației în loc de una definită manual</string>\n    <string name=\"anisotropic_diffusion\">Difuzia anizotropă</string>\n    <string name=\"diffusion\">Difuzia</string>\n    <string name=\"conduction\">Conducere</string>\n    <string name=\"horizontal_wind_stagger\">Eșalonare orizontală a vântului</string>\n    <string name=\"fast_bilaterial_blur\">Blur bilateral rapid</string>\n    <string name=\"stroke_color\">Culoarea cursei</string>\n    <string name=\"fractal_glass\">Sticlă fractală</string>\n    <string name=\"amplitude\">Amplitudine</string>\n    <string name=\"marble\">Marmură</string>\n    <string name=\"water_effect\">Efectul apei</string>\n    <string name=\"just_size\">mărimea</string>\n    <string name=\"frequency_x\">Frecvența X</string>\n    <string name=\"frequency_y\">Frecvența Y</string>\n    <string name=\"amplitude_x\">Amplitudinea X</string>\n    <string name=\"amplitude_y\">Amplitudinea Y</string>\n    <string name=\"perlin_distortion\">Distorsiunea Perlin</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"current\">Actual</string>\n    <string name=\"all\">Toate</string>\n    <string name=\"full_filter\">Filtru complet</string>\n    <string name=\"full_filter_sub\">Aplicați orice lanțuri de filtre la imaginile date sau la o singură imagine</string>\n    <string name=\"start_position\">Început</string>\n    <string name=\"center_position\">Centru</string>\n    <string name=\"end_position\">Sfârşit</string>\n    <string name=\"gradient_maker\">Creator de gradient</string>\n    <string name=\"gradient_maker_sub\">Creați un gradient de o dimensiune de ieșire dată, cu culori personalizate și tip de aspect</string>\n    <string name=\"speed\">Viteză</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"rate_app\">Evaluați aplicația</string>\n    <string name=\"rate\">Evaluați</string>\n    <string name=\"rate_app_sub\">Această aplicație este complet gratuită, dacă doriți să devină mai mare, vă rugăm să vedeți proiectul pe Github 😄</string>\n    <string name=\"gradient_type_linear\">Liniar</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Mătura</string>\n    <string name=\"gradient_type\">Tipul gradientului</string>\n    <string name=\"center_x\">Centrul X</string>\n    <string name=\"center_y\">Centrul Y</string>\n    <string name=\"tile_mode_repeated\">Repetat</string>\n    <string name=\"tile_mode_mirror\">Oglindă</string>\n    <string name=\"tile_mode_clamp\">Clemă</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"lasso\">lasou</string>\n    <string name=\"lasso_sub\">Desenează calea umplută închisă după calea dată</string>\n    <string name=\"draw_path_mode\">Modul Draw Path</string>\n    <string name=\"double_line_arrow\">Săgeată cu linie dublă</string>\n    <string name=\"free_drawing\">Desen gratuit</string>\n    <string name=\"double_arrow\">Săgeată dublă</string>\n    <string name=\"line_arrow\">Săgeată linie</string>\n    <string name=\"arrow\">Săgeată</string>\n    <string name=\"line\">Linia</string>\n    <string name=\"free_drawing_sub\">Desenează calea ca valoare de intrare</string>\n    <string name=\"line_sub\">Desenează calea de la punctul de început până la punctul final ca o linie</string>\n    <string name=\"line_arrow_sub\">Desenează săgeata indicatoare de la punctul de început la punctul final ca o linie</string>\n    <string name=\"arrow_sub\">Desenează săgeata indicatoare dintr-o anumită cale</string>\n    <string name=\"double_arrow_sub\">Desenează săgeată dublă indicatoare dintr-o anumită cale</string>\n    <string name=\"outlined_oval\">Oval conturat</string>\n    <string name=\"outlined_rect\">Subliniat Rect</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Desenează rect de la punctul de început până la punctul final</string>\n    <string name=\"oval_sub\">Desenează oval de la punctul de început până la punctul final</string>\n    <string name=\"bayer_three_dithering\">Bayer Trei Câte Trei Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Patru Câte Patru Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Two Row Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"left_to_right_dithering\">Dithering de la stânga la dreapta</string>\n    <string name=\"random_dithering\">Dithering aleatoriu</string>\n    <string name=\"simple_threshold_dithering\">Dithering prag simplu</string>\n    <string name=\"mask_color\">Culoarea măștii</string>\n    <string name=\"mask_preview\">Previzualizare masca</string>\n    <string name=\"mask_preview_sub\">Masca de filtru desenată va fi redată pentru a vă arăta rezultatul aproximativ</string>\n    <string name=\"scale_mode\">Modul de scalare</string>\n    <string name=\"bilinear\">Biliniar</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Sihastrul</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Cel mai apropiat</string>\n    <string name=\"spline\">Splina</string>\n    <string name=\"basic\">De bază</string>\n    <string name=\"default_value\">Valoare implicită</string>\n    <string name=\"value_in_range\">Valoare în intervalul %1$s - %2$s</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma spațială</string>\n    <string name=\"median_blur\">Neclaritate mediană</string>\n    <string name=\"only_clip\">Doar Clip</string>\n    <string name=\"icon_shape_sub\">Adaugă containerul cu forma selectată sub pictogramele principale ale cardurilor</string>\n    <string name=\"brightness_enforcement\">Aplicarea luminozității</string>\n    <string name=\"screen\">Ecran</string>\n    <string name=\"gradient_maker_type_image\">Suprapunere gradient</string>\n    <string name=\"gradient_maker_type_image_sub\">Compuneți orice gradient al părții superioare a imaginii date</string>\n    <string name=\"transformations\">Transformări</string>\n    <string name=\"camera\">Cameră</string>\n    <string name=\"camera_sub\">Utilizează camera pentru a fotografia, rețineți că este posibil să obțineți o singură imagine din această sursă de imagine</string>\n    <string name=\"grain\">Cereale</string>\n    <string name=\"unsharp\">Neascutit</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"golden_hour\">Ora de aur</string>\n    <string name=\"hot_summer\">Vara fierbinte</string>\n    <string name=\"purple_mist\">Purple Mist</string>\n    <string name=\"sunrise\">răsărit</string>\n    <string name=\"colorful_swirl\">Vârtej colorat</string>\n    <string name=\"autumn_tones\">Tonuri de toamnă</string>\n    <string name=\"fantasy_landscape\">Peisaj fantastic</string>\n    <string name=\"color_explosion\">Explozie de culoare</string>\n    <string name=\"electric_gradient\">Gradient electric</string>\n    <string name=\"red_swirl\">Vârtej roșu</string>\n    <string name=\"digital_code\">Cod digital</string>\n    <string name=\"watermarking\">Filigranare</string>\n    <string name=\"watermarking_sub\">Acoperiți imagini cu filigrane de text/imagine personalizabile</string>\n    <string name=\"repeat_watermark\">Repetați filigranul</string>\n    <string name=\"offset_x\">Offset X</string>\n    <string name=\"watermark_type\">Tip filigran</string>\n    <string name=\"text_color\">Culoarea textului</string>\n    <string name=\"overlay_mode\">Modul de suprapunere</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">Instrumente GIF</string>\n    <string name=\"gif_tools_sub\">Convertiți imaginile în imagine GIF sau extrageți cadre din imaginea GIF dată</string>\n    <string name=\"gif_type_to_image\">GIF în imagini</string>\n    <string name=\"gif_type_to_image_sub\">Convertiți fișierul GIF într-un lot de imagini</string>\n    <string name=\"gif_type_to_gif_sub\">Convertiți un lot de imagini în fișier GIF</string>\n    <string name=\"gif_type_to_gif\">Imagini în GIF</string>\n    <string name=\"select_gif_image_to_start\">Alegeți imaginea GIF pentru a începe</string>\n    <string name=\"use_size_of_first_frame\">Utilizați dimensiunea Primului cadru</string>\n    <string name=\"use_size_of_first_frame_sub\">Înlocuiți dimensiunea specificată cu dimensiunile primului cadru</string>\n    <string name=\"repeat_count\">Repetați numărătoarea</string>\n    <string name=\"use_lasso\">Folosește Lasso</string>\n    <string name=\"use_lasso_sub\">Folosește Lasso ca în modul desen pentru a efectua ștergerea</string>\n    <string name=\"original_image_preview_alpha\">Previzualizare imagine originală Alpha</string>\n    <string name=\"random_emojis_sub\">Emoji-ul din bara de aplicații va fi schimbat continuu prin aleatoriu în loc să fie folosit unul selectat</string>\n    <string name=\"random_emojis\">Emoji aleatorii</string>\n    <string name=\"random_emojis_error\">Nu se poate folosi alegerea aleatorie a emoji-urilor când emoji-urile sunt dezactivate</string>\n    <string name=\"emoji_selection_error\">Nu se poate selecta un emoji când alegeți unul aleatoriu activat</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"old_tv\">televizor vechi</string>\n    <string name=\"shuffle_blur\">Amestecă estomparea</string>\n    <string name=\"recognize_text\">OCR (Recunoaștere text)</string>\n    <string name=\"recognize_text_sub\">Recunoașteți textul din imaginea dată, peste 120 de limbi acceptate</string>\n    <string name=\"picture_has_no_text\">Imaginea nu are text sau aplicația nu a găsit-o</string>\n    <string name=\"accuracy\">Acuratețe: %1$s</string>\n    <string name=\"recognition_type\">Tip de recunoaștere</string>\n    <string name=\"fast\">Rapid</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"best\">Cel mai bun</string>\n    <string name=\"no_data\">Nu există date</string>\n    <string name=\"download_description\">Pentru funcționarea corectă a Tesseract OCR, datele de antrenament suplimentare (%1$s) trebuie descărcate pe dispozitivul dvs. \\nDoriți să descărcați %2$s date?</string>\n    <string name=\"download\">Descarca</string>\n    <string name=\"no_connection\">Fără conexiune, verificați-o și încercați din nou pentru a descărca modele de tren</string>\n    <string name=\"downloaded_languages\">Limbi descărcate</string>\n    <string name=\"available_languages\">Limbi disponibile</string>\n    <string name=\"segmentation_mode\">Modul de segmentare</string>\n    <string name=\"restore_background_sub\">Peria va restabili fundalul în loc să îl ștergă</string>\n    <string name=\"horizontal_grid\">Grilă orizontală</string>\n    <string name=\"vertical_grid\">Grilă verticală</string>\n    <string name=\"stitch_mode\">Modul de cusătură</string>\n    <string name=\"rows_count\">Număr de rânduri</string>\n    <string name=\"columns_count\">Numărul de coloane</string>\n    <string name=\"use_pixel_switch\">Utilizați Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Comutatorul asemănător pixelilor va fi folosit în locul materialului Google pe care l-ați bazat</string>\n    <string name=\"slide\">Slide</string>\n    <string name=\"side_by_side\">Unul langa altul</string>\n    <string name=\"toggle_tap\">Comutați Atingeți</string>\n    <string name=\"transparency\">Transparenţă</string>\n    <string name=\"saved_to_original\">Fișier suprascris cu numele %1$s la destinația inițială</string>\n    <string name=\"magnifier\">Lupă</string>\n    <string name=\"magnifier_sub\">Activează lupa în partea de sus a degetului în modurile de desen pentru o mai bună accesibilitate</string>\n    <string name=\"force_exif_widget_initial_value\">Forțați valoarea inițială</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Forțează ca widgetul exif să fie verificat inițial</string>\n    <string name=\"favorite\">Favorite</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"native_stack_blur\">Estompare nativă a stivei</string>\n    <string name=\"inverse_fill_type\">Tip de umplere inversă</string>\n    <string name=\"inverse_fill_type_sub\">Dacă este activată, toate zonele care nu sunt mascate vor fi filtrate în locul comportamentului implicit</string>\n    <string name=\"confetti\">Confeti</string>\n    <string name=\"confetti_sub\">Confetti vor fi afișate la salvare, partajare și alte acțiuni principale</string>\n    <string name=\"secure_mode\">Modul securizat</string>\n    <string name=\"secure_mode_sub\">Ascunde conținutul la ieșire, de asemenea, ecranul nu poate fi capturat sau înregistrat</string>\n    <string name=\"containers_shadow\">Containere</string>\n    <string name=\"containers_shadow_sub\">Permite desenarea umbrelor în spatele containerelor</string>\n    <string name=\"sliders_shadow\">Glisoare</string>\n    <string name=\"switches_shadow\">Comutatoare</string>\n    <string name=\"fabs_shadow\">FAB-uri</string>\n    <string name=\"buttons_shadow\">Butoane</string>\n    <string name=\"sliders_shadow_sub\">Activează desenarea umbrelor în spatele glisoarelor</string>\n    <string name=\"app_bars_shadow\">Bare de aplicații</string>\n    <string name=\"exit\">Ieșire</string>\n    <string name=\"preview_closing\">Dacă părăsiți previzualizarea acum, va trebui să adăugați din nou imaginile</string>\n    <string name=\"image_format\">Formatul imaginii</string>\n    <string name=\"material_you_sub\">Creați paleta Material You din imagine</string>\n    <string name=\"dark_colors\">Culori Închise</string>\n    <string name=\"dark_colors_sub\">Utilizează schema de culori modul de noapte în loc de varianta de lumină</string>\n    <string name=\"copy_as_compose_code\">Copiați ca cod\\\" Jetpack Compose\\\"</string>\n    <string name=\"cross_blur\">Blur încrucișat</string>\n    <string name=\"ring_blur\">Inel Neclar</string>\n    <string name=\"circle_blur\">Cercul Blur</string>\n    <string name=\"star_blur\">Ceață stelară</string>\n    <string name=\"linear_tilt_shift\">Înclinare liniară Tilt Shift</string>\n    <string name=\"tags_to_remove\">Etichete Pentru a elimina</string>\n    <string name=\"apng_tools\">Instrumente APNG</string>\n    <string name=\"apng_tools_sub\">Convertiți imaginile în imagine APNG sau extrageți cadre din imaginea APNG dată</string>\n    <string name=\"apng_type_to_image\">APNG în imagini</string>\n    <string name=\"apng_type_to_image_sub\">Convertiți fișierul APNG într-un lot de imagini</string>\n    <string name=\"apng_type_to_apng\">Imagini în APNG</string>\n    <string name=\"select_apng_image_to_start\">Alegeți imaginea APNG pentru a începe</string>\n    <string name=\"motion_blur\">Neclaritate de miscare</string>\n    <string name=\"apng_type_to_apng_sub\">Convertiți un lot de imagini în fișier APNG</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Creați un fișier Zip din fișiere sau imagini date</string>\n    <string name=\"drag_handle_width\">Trageți Lățimea mânerului</string>\n    <string name=\"confetti_type\">Tip confetti</string>\n    <string name=\"festive\">Festiv</string>\n    <string name=\"explode\">Explozie</string>\n    <string name=\"rain\">Ploaie</string>\n    <string name=\"corners\">Colțuri</string>\n    <string name=\"jxl_tools\">Instrumente JXL</string>\n    <string name=\"jxl_tools_sub\">Efectuați transcodarea JXL ~ JPEG fără pierderi de calitate sau convertiți GIF/APNG în animație JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL în JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Efectuați transcodarea fără pierderi de la JXL la JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Efectuați transcodarea fără pierderi de la JPEG la JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG în JXL</string>\n    <string name=\"document_scanner_sub\">Scanați documente și creați PDF-uri sau imagini separate din acestea</string>\n    <string name=\"speed_sub\">Controlează viteza de decodare a imaginii rezultate, aceasta ar trebui să ajute la deschiderea mai rapidă a imaginii rezultate, valoarea de %1$s înseamnă cea mai lentă decodare, în timp ce %2$s - cea mai rapidă, această setare poate crește dimensiunea imaginii de ieșire</string>\n    <string name=\"svg_warning\">Nu se recomandă utilizarea acestui instrument pentru urmărirea imaginilor mari fără reducerea scalei, deoarece poate provoca blocarea și creșterea timpului de procesare</string>\n    <string name=\"create_shortcut\">Creare scurtătură</string>\n    <string name=\"create_shortcut_title\">Alegeți instrumentul pentru fixare</string>\n    <string name=\"create_shortcut_subtitle\">Instrumentul va fi adăugat la ecranul de pornire al lansatorului dvs. ca scurtătură, utilizați-l în combinație cu setarea \\\"Săriți peste selectarea fișierelor\\\" pentru a obține comportamentul necesar</string>\n    <string name=\"create_new\">Creare nou</string>\n    <string name=\"create_template\">Creare șablon</string>\n    <string name=\"select_jxl_image_to_start\">Alegeți imaginea JXL pentru a începe</string>\n    <string name=\"pick_filter_info\">Alegeți filtrul de mai jos pentru a-l utiliza ca pensulă în desenul dvs.</string>\n    <string name=\"pick_single_media\">Alegeți un singur mediu</string>\n    <string name=\"pick_multiple_media\">Alegeți mai multe medii</string>\n    <string name=\"pick\">Alegere</string>\n    <string name=\"markup_layers\">Straturi de marcare</string>\n    <string name=\"markup_layers_sub\">Modul straturi cu posibilitatea de a plasa liber imagini, text și multe altele</string>\n    <string name=\"layers_on_image\">Straturi pe imagine</string>\n    <string name=\"layers_on_image_sub\">Utilizați imaginea ca fundal și adăugați diferite straturi deasupra acesteia</string>\n    <string name=\"layers_on_background\">Straturi pe fundal</string>\n    <string name=\"layers_on_background_sub\">La fel ca prima opțiune, dar cu culoare în loc de imagine</string>\n    <string name=\"embedded_picker\">Selector încorporat</string>\n    <string name=\"embedded_picker_sub\">Folosește propriul selector de imagini Image Toolbox în locul celor predefinite de sistem</string>\n    <string name=\"skip_file_picking\">Săriți peste selectarea fișierelor</string>\n    <string name=\"skip_file_picking_sub\">Selectorul de fișiere va fi afișat imediat dacă acest lucru este posibil pe ecranul ales</string>\n    <string name=\"select_webp_image_to_start\">Alegeți imaginea WEBP pentru a începe</string>\n    <string name=\"no_favorite_options_selected\">Nu sunt selectate opțiuni favorite, adăugați-le în pagina de instrumente</string>\n    <string name=\"add_favorites\">Adăugați favorite</string>\n    <string name=\"target_lut_image\">Imagine LUT țintă</string>\n    <string name=\"target_cube_lut_file\">Fișier LUT 3D țintă (.cube / .CUBE)</string>\n    <string name=\"save_empty_lut\">Obțineți imaginea Neutral LUT</string>\n    <string name=\"lut_library_sub\">Descărcați colecția de LUT-uri, pe care le puteți aplica după descărcare</string>\n    <string name=\"lut_library_update_sub\">Actualizați colecția de LUT-uri (numai cele noi vor fi puse la coadă), pe care le puteți aplica după descărcare</string>\n    <string name=\"format_conversion_sub\">Convertiți un lot de imagini dintr-un format în altul</string>\n    <string name=\"format_conversion\">Conversie format</string>\n    <string name=\"added_filter_template\">Șablon de filtrare adăugat cu numele \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"no_template_filters\">Nu s-au adăugat filtre pentru șabloane</string>\n    <string name=\"opened_file_have_no_filter_template\">Fișierul selectat nu are date de șablon de filtrare</string>\n    <string name=\"template_name\">Nume șablon</string>\n    <string name=\"select_template_preview\">Această imagine va fi utilizată pentru a previzualiza acest model de filtru</string>\n    <string name=\"template_filter\">Filtru șablon</string>\n    <string name=\"delete_template\">Ștergeți șablonul</string>\n    <string name=\"save_empty_lut_sub\">În primul rând, utilizați aplicația dvs. preferată de editare foto pentru a aplica un filtru la LUT neutru pe care îl puteți obține aici. Pentru ca acest lucru să funcționeze corect, culoarea fiecărui pixel nu trebuie să depindă de alți pixeli (de exemplu, blur nu va funcționa). Odată gata, utilizați noua imagine LUT ca intrare pentru filtrul LUT 512*512</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Codul QR scanat nu este un model de filtru valid</string>\n    <string name=\"template\">Șablon</string>\n    <string name=\"delete_template_warn\">Sunteți pe cale să ștergeți filtrul șablon selectat. Această operațiune nu poate fi anulată</string>\n    <string name=\"compression_type\">Tipul de compresie</string>\n    <string name=\"tag_color_space\">Spațiul de culoare</string>\n    <string name=\"scale_color_space\">Scală spațiu de culoare</string>\n    <string name=\"tag_compression\">Comprimare</string>\n    <string name=\"tiff_compression_scheme\">Schemă de compresie TIFF</string>\n    <string name=\"engine_mode\">Modul motorului</string>\n    <string name=\"image_stacking\">Stivuirea imaginilor</string>\n    <string name=\"lossy_compression\">Compresie cu pierderi</string>\n    <string name=\"lagrange_3_sub\">Un filtru de interpolare Lagrange de ordinul 3, care oferă o precizie mai bună și rezultate mai netede pentru scalarea imaginilor</string>\n    <string name=\"image_splitting\">Împărțirea imaginii</string>\n    <string name=\"crf_sub\">O valoare de %1$s înseamnă o compresie lentă, rezultând o dimensiune relativ mică a fișierului. %2$s înseamnă o compresie mai rapidă, rezultând un fișier mare.</string>\n    <string name=\"base_64_tools_sub\">Decodați șirul Base64 în imagine sau codificați imaginea în format Base64</string>\n    <string name=\"tesseract_options\">Opțiuni Tesseract</string>\n    <string name=\"image_splitting_sub\">Împărțiți o singură imagine pe rânduri sau coloane</string>\n    <string name=\"image_stacking_sub\">Stivuiți imagini una peste alta cu moduri de amestecare alese</string>\n    <string name=\"qr_code_sub\">Scanați codul QR și obțineți conținutul acestuia sau lipiți șirul dvs. de caractere pentru a genera unul nou</string>\n    <string name=\"images_to_svg\">Imagini în Svg</string>\n    <string name=\"links_preview\">Previzualizare linkuri</string>\n    <string name=\"collage_maker\">Creare colaj</string>\n    <string name=\"collage_maker_sub\">Creați diverse colaje din 20 imagini</string>\n    <string name=\"collages_info\">Țineți apăsată imaginea pentru a o schimba, mutați și măriți pentru a ajusta poziția</string>\n    <string name=\"collage_type\">Tipul colajului</string>\n    <string name=\"lossy_compression_sub\">Folosește compresia cu pierderi pentru a reduce dimensiunea fișierului în loc de compresie fără pierderi</string>\n    <string name=\"images_to_svg_sub\">Trasarea imaginilor date în imagini SVG</string>\n    <string name=\"convert_sub\">Convertiți loturile de imagini în formatul dat</string>\n    <string name=\"watermark_size\">Dimensiunea filigranului</string>\n    <string name=\"options_below_is_for_images\">Opțiunile de mai jos sunt pentru salvarea imaginilor, nu a PDF-urilor</string>\n    <string name=\"as_qr_code\">Ca imagine de cod QR</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Acordați permisiunea camerei în setări pentru a scana codul QR</string>\n    <string name=\"scan_qr_code\">Scanați codul QR</string>\n    <string name=\"scan_qr_code_to_replace_content\">Scanați codul QR pentru a înlocui conținutul din câmp sau tastați ceva pentru a genera un nou cod QR</string>\n    <string name=\"links_preview_sub\">Permite preluarea previzualizării linkurilor în locuri în care puteți obține text (QRCode, OCR etc.)</string>\n    <string name=\"links\">Linkuri</string>\n    <string name=\"color_tools_sub\">Amestecați, creați tonuri, generați nuanțe și multe altele</string>\n    <string name=\"tesseract_options_sub\">Aplicați unele variabile de intrare pentru motorul tesseract</string>\n    <string name=\"document_scanner\">Scanner de documente</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Acordați permisiunea camerei în setări pentru a scana Scanerul de documente</string>\n    <string name=\"save_as_qr_code_image\">Salvați ca imagine de cod QR</string>\n    <string name=\"qr_code\">Cod QR</string>\n    <string name=\"qr_description\">Descriere QR</string>\n    <string name=\"spline64_sub\">O metodă de interpolare bazată pe spline care oferă rezultate netede utilizând un filtru cu 64 de picături</string>\n    <string name=\"gif_type_to_jxl\">GIF în JXL</string>\n    <string name=\"base_64_actions\">Acțiuni Base64</string>\n    <string name=\"gif_type_to_webp\">GIF în WEBP</string>\n    <string name=\"color_blind_scheme_sub\">Selectați modul de adaptare a culorilor temei pentru o anumită variantă de daltonism</string>\n    <string name=\"achromatopsia_sub\">Daltonism complet, văzând doar nuanțe de gri</string>\n    <string name=\"gif_type_to_webp_sub\">Convertiți imagini GIF în imagini animate WEBP</string>\n    <string name=\"apng_type_to_jxl_sub\">Convertiți imaginile APNG în imagini animate JXL</string>\n    <string name=\"jxl_type_to_images_sub\">Convertiți animația JXL în loturi de imagini</string>\n    <string name=\"not_use_color_blind_scheme\">Nu utilizați schema Color Blind</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Culorile vor fi exact așa cum sunt stabilite în temă</string>\n    <string name=\"fit_to_bounds_sub\">Combinați modul de redimensionare a decupării cu acest parametru pentru a obține comportamentul dorit (Decupare/Potrivire la raportul de aspect)</string>\n    <string name=\"reset_properties_sub\">Toate proprietățile vor fi setate la valorile implicite, rețineți că această acțiune nu poate fi anulată</string>\n    <string name=\"color_tools\">Instrumente de culoare</string>\n    <string name=\"webp_tools\">Instrumente WEBP</string>\n    <string name=\"webp_type_to_webp_sub\">Convertiți un lot de imagini într-un fișier WEBP</string>\n    <string name=\"manage_storage_extra_types_sub\">Permiteți accesul tuturor fișierelor pentru a vedea JXL, QOI și alte imagini care nu sunt recunoscute pe Android ca fișiere imagine, fără a acorda permisiunea nu veți putea vedea aceste imagini aici</string>\n    <string name=\"noise_generation\">Generarea zgomotului</string>\n    <string name=\"noise_generation_sub\">Generați diferite zgomote precum Perlin sau alte tipuri</string>\n    <string name=\"compact_selectors_sub\">Unele comenzi de selecție vor utiliza un aspect compact pentru a ocupa mai puțin spațiu</string>\n    <string name=\"layout\">Configurare</string>\n    <string name=\"base_64_tools\">Instrumente Base64</string>\n    <string name=\"not_a_valid_base_64\">Valoarea furnizată nu este un șir Base64 valid</string>\n    <string name=\"copy_not_a_valid_base_64\">Nu se poate copia un șir Base64 gol sau invalid</string>\n    <string name=\"copy_base_64\">Copiere Base64</string>\n    <string name=\"paste_base_64\">Lipire Base64</string>\n    <string name=\"base_64_tips\">Încărcați imaginea pentru a copia sau salva șirul Base64. Dacă aveți șirul în sine, îl puteți lipi mai sus pentru a obține imaginea</string>\n    <string name=\"open_source_licenses\">Licențe Open Source</string>\n    <string name=\"open_source_licenses_sub\">Vizualizați licențele bibliotecilor open source utilizate în această aplicație</string>\n    <string name=\"save_base_64\">Salvare Base64</string>\n    <string name=\"share_base_64\">Partajare Base64</string>\n    <string name=\"import_base_64\">Importare Base64</string>\n    <string name=\"gif_type_to_jxl_sub\">Convertiți imagini GIF în imagini animate JXL</string>\n    <string name=\"jxl_type_to_images\">JXL în imagini</string>\n    <string name=\"apng_type_to_jxl\">APNG în JXL</string>\n    <string name=\"jxl_type_to_jxl\">Imagini în JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Convertiți un lot de imagini în animație JXL</string>\n    <string name=\"behavior\">Comportament</string>\n    <string name=\"color_blind_scheme\">Schemă pentru daltoniști</string>\n    <string name=\"default_values\">Valorile implicite</string>\n    <string name=\"tools_arrangement\">Aranjamentul instrumentelor</string>\n    <string name=\"group_tools_by_type_sub\">Grupează instrumentele pe ecranul principal în funcție de tipul lor, în loc de un aranjament personalizat al listei</string>\n    <string name=\"webp_tools_sub\">Convertiți imaginile în imagini animate WEBP sau extrageți cadre din animațiile WEBP date</string>\n    <string name=\"settings_group_visibility_visible\">Grupul de setări \\\"%1$s\\\" va fi extins în mod implicit</string>\n    <string name=\"group\">Grup</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Alăturați-vă chat-ului nostru unde puteți discuta orice doriți și, de asemenea, uitați-vă la canalul CI unde postez versiuni beta și anunțuri</string>\n    <string name=\"settings_group_visibility_hidden\">Grupul de setări \\\"%1$s\\\" va fi colapsat în mod implicit</string>\n    <string name=\"reset_properties\">Resetați proprietățile</string>\n    <string name=\"group_tools_by_type\">Instrumente de grup în funcție de tip</string>\n    <string name=\"generate_previews\">Generați previzualizări</string>\n    <string name=\"generate_previews_sub\">Activați generarea previzualizării, acest lucru poate ajuta la evitarea blocajelor pe unele dispozitive, de asemenea, acest lucru dezactivează unele funcționalități de editare în cadrul opțiunii de editare unică</string>\n    <string name=\"lanczos2_sub\">O metodă de reeșantionare care utilizează un filtru Lanczos cu 2 lobi pentru interpolare de înaltă calitate cu artefacte minime</string>\n    <string name=\"lanczos3_sub\">O metodă de reeșantionare care utilizează un filtru Lanczos cu 3 lobi pentru o interpolare de înaltă calitate cu artefacte minime</string>\n    <string name=\"lanczos4_sub\">O metodă de reeșantionare care utilizează un filtru Lanczos cu 4 lobi pentru o interpolare de înaltă calitate cu artefacte minime</string>\n    <string name=\"lanczos_bessel_sub\">Metodă de reeșantionare care menține interpolarea de înaltă calitate prin aplicarea unei funcții Bessel (jinc) la valorile pixelilor</string>\n    <string name=\"ci_channel\">Canal CI</string>\n    <string name=\"image_for_histogram\">Această imagine va fi utilizată pentru a genera histograme RGB și de luminozitate</string>\n    <string name=\"constant_rate_factor\">Factor de rată constantă (CRF)</string>\n    <string name=\"lanczos_6_sub\">Un filtru de reeșantionare Lanczos cu un ordin mai mare de 6, care oferă o scalare mai clară și mai precisă a imaginii</string>\n    <string name=\"sphinx_sub\">O metodă avansată de reeșantionare care oferă o interpolare de înaltă calitate cu artefacte minime</string>\n    <string name=\"coordinates_rounding_tolerance\">Coordonate toleranță de rotunjire</string>\n    <string name=\"use_sampled_palette\">Utilizați paleta eșantionată</string>\n    <string name=\"use_sampled_palette_sub\">Paleta de cuantizare va fi eșantionată dacă această opțiune este activată</string>\n    <string name=\"downscale_image\">Redimensionare imagine</string>\n    <string name=\"min_color_ratio\">Raport minim de culoare</string>\n    <string name=\"path_scale\">Scara căii</string>\n    <string name=\"detailed\">Detaliat</string>\n    <string name=\"downscale_image_sub\">Imaginea va fi redusă la dimensiuni mai mici înainte de procesare, ceea ce ajută instrumentul să lucreze mai rapid și mai sigur</string>\n    <string name=\"fancy_sub\">Glisor personalizat cu aspect elegant cu animații, acesta este implicit pentru această aplicație</string>\n    <string name=\"add_outline\">Adăugați contur</string>\n    <string name=\"material_2_sub\">Glisor bazat pe Material 2, nu modern, simplu și direct</string>\n    <string name=\"ci_channel_sub\">Primiți notificări cu privire la noile versiuni ale aplicației și citiți anunțurile</string>\n    <string name=\"main_screen_title\">Titlul ecranului principal</string>\n    <string name=\"compact_selectors\">Selectori compacți</string>\n    <string name=\"slider_type\">Tip glisor</string>\n    <string name=\"fancy\">Elegant</string>\n    <string name=\"center_align_dialog_buttons\">Butoane de dialog centrale</string>\n    <string name=\"center_align_dialog_buttons_sub\">Dacă este posibil, butoanele dialogurilor vor fi poziționate în centru în loc de partea stângă</string>\n    <string name=\"add_outline_sub\">Adăugați contur în jurul textului cu culoarea și lățimea specificate</string>\n    <string name=\"harmonization_color\">Armonizare culoare</string>\n    <string name=\"harmonization_level\">Nivelul armonizării</string>\n    <string name=\"switch_type\">Tip comutator</string>\n    <string name=\"mesh_gradients\">Gradiente de plasă</string>\n    <string name=\"collection_mesh_gradients_sub\">Uitați-vă la colecția online de Gradiente de plasă</string>\n    <string name=\"checksum_tools\">Instrumente de control</string>\n    <string name=\"open_edit_instead_of_preview\">Deschideți în Editare în loc de Previzualizare</string>\n    <string name=\"checksum_as_filename_sub\">Imaginile de ieșire vor avea numele corespunzător sumei de control a datelor lor</string>\n    <string name=\"auto_paste_sub\">Permite aplicației să lipească automat datele din clipboard, astfel încât acestea vor apărea pe ecranul principal și le veți putea procesa</string>\n    <string name=\"default_line_width\">Lățimea implicită a liniei</string>\n    <string name=\"edit_exif_screen\">Editare EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Modificarea metadatelor unei singure imagini fără recompresie</string>\n    <string name=\"edit_exif_tag\">Atingeți pentru a edita etichetele disponibile</string>\n    <string name=\"default_draw_color\">Culoare de desen implicită</string>\n    <string name=\"default_draw_path_mode\">Mod implicit al căii de desenare</string>\n    <string name=\"one_time_save_location\">Salvare o singură dată Locație</string>\n    <string name=\"add_timestamp\">Adăugare marcaj temporal</string>\n    <string name=\"formatted_timestamp\">Marcaj temporal formatat</string>\n    <string name=\"formatted_timestamp_sub\">Activați formatarea marcajului temporal în numele fișierului de ieșire în loc de milisecunde de bază</string>\n    <string name=\"one_time_save_location_sub\">Vizualizați și editați locațiile de salvare unice pe care le puteți utiliza prin apăsarea lungă a butonului de salvare în majoritatea tuturor opțiunilor</string>\n    <string name=\"fast_settings_side\">Setări rapide lateral</string>\n    <string name=\"fast_settings_side_sub\">Adăugați o bandă plutitoare în partea aleasă în timpul editării imaginilor, care va deschide setările rapide dacă faceți clic pe ea</string>\n    <string name=\"checksum_as_filename\">Suma de control ca nume de fișier</string>\n    <string name=\"auto_paste\">Lipire automată</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Atunci când selectați imaginea pentru a o deschide (previzualizare) în ImageToolbox, în loc de previzualizare se va deschide foaia de selecție de editare</string>\n    <string name=\"allow_enter_by_text_field\">Permiteți introducerea pe câmpul de text</string>\n    <string name=\"allow_enter_by_text_field_sub\">Activează câmpul de text din spatele selecției presetărilor, pentru a le introduce din mers</string>\n    <string name=\"add_timestamp_sub\">Activează adăugarea marcajului temporal la numele fișierului de ieșire</string>\n    <string name=\"checksum_tools_sub\">Compararea sumelor de control, calcularea hașurilor, crearea de șiruri hexazecimale din fișiere utilizând diferiți algoritmi de hașurare</string>\n    <string name=\"show_settings_in_landscape\">Afișarea setărilor în peisaj</string>\n    <string name=\"show_settings_in_landscape_sub\">Dacă acest lucru este dezactivat, atunci în modul peisaj setările vor fi deschise pe butonul din bara de aplicații de sus, ca întotdeauna, în loc de opțiunea vizibilă permanentă</string>\n    <string name=\"fullscreen_settings\">Setări ecran complet</string>\n    <string name=\"fullscreen_settings_sub\">Activați-o și pagina de setări va fi întotdeauna deschisă ca ecran complet în loc de foaia glisantă a sertarului</string>\n    <string name=\"tool_exit_confirmation\">Confirmare ieșire instrument</string>\n    <string name=\"tool_exit_confirmation_sub\">Dacă aveți modificări nesalvate în timp ce utilizați anumite instrumente și încercați să le închideți, se va afișa un dialog de confirmare</string>\n    <string name=\"image_cutting\">Tăierea imaginii</string>\n    <string name=\"image_cutting_sub\">Tăiați o parte a imaginii și îmbinați cele din stânga (pot fi inverse) prin linii verticale sau orizontale</string>\n    <string name=\"gaussian_blur\">estompare gaussiană</string>\n    <string name=\"box_blur\">Cutie estompată</string>\n    <string name=\"bilaterial_blur\">estompare bilaterală</string>\n    <string name=\"fast_blur\">estompare rapidă</string>\n    <string name=\"stroke_pixelation\">Pixelarea accidentului vascular cerebral</string>\n    <string name=\"tile_mode\">Modul Tile</string>\n    <string name=\"fast_gaussian_blur_2d\">Blur Gaussian rapid 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Blur gaussian rapid 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Blur Gaussian rapid 4D</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"sorting\">Triere</string>\n    <string name=\"sort_by_date\">Data</string>\n    <string name=\"sort_by_date_reversed\">Data (inversată)</string>\n    <string name=\"sort_by_name\">Nume</string>\n    <string name=\"sort_by_name_reversed\">Nume (inversat)</string>\n    <string name=\"channels_configuration\">Configurarea canalelor</string>\n    <string name=\"header_today\">Astăzi</string>\n    <string name=\"header_yesterday\">Ieri</string>\n    <string name=\"no_permissions\">Fără permisiuni</string>\n    <string name=\"request\">Cerere</string>\n    <string name=\"try_again\">Încearcă din nou</string>\n    <string name=\"compose\">Compune</string>\n    <string name=\"compose_switch_sub\">Un Jetpack Compose Material pe care îl schimbați</string>\n    <string name=\"material_you_switch_sub\">Un material pe care îl schimbi</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Redimensionați ancora</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">Un comutator bazat pe sistemul de proiectare „Fluent”.</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Un comutator bazat pe sistemul de design „Cupertino”.</string>\n    <string name=\"path_omit\">Calea Omite</string>\n    <string name=\"lines_threshold\">Pragul liniilor</string>\n    <string name=\"quadratic_threshold\">Pragul cuadratic</string>\n    <string name=\"legacy\">Moştenire</string>\n    <string name=\"lstm_network\">Rețeaua LSTM</string>\n    <string name=\"legacy_and_lstm\">Legacy și LSTM</string>\n    <string name=\"convert\">Convertit</string>\n    <string name=\"add_new_folder\">Adăugați un dosar nou</string>\n    <string name=\"tag_bits_per_sample\">Biți pe probă</string>\n    <string name=\"tag_photometric_interpretation\">Interpretare fotometrică</string>\n    <string name=\"tag_samples_per_pixel\">Mostre per pixel</string>\n    <string name=\"tag_planar_configuration\">Configurație plană</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sub eșantionare</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Poziţionare</string>\n    <string name=\"tag_x_resolution\">X Rezoluție</string>\n    <string name=\"tag_y_resolution\">Rezoluție Y</string>\n    <string name=\"tag_resolution_unit\">Unitatea de rezoluție</string>\n    <string name=\"tag_strip_offsets\">Decalaje de benzi</string>\n    <string name=\"tag_rows_per_strip\">Rânduri pe bandă</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">Format de schimb JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Lungimea formatului de schimb JPEG</string>\n    <string name=\"tag_transfer_function\">Funcția de transfer</string>\n    <string name=\"tag_white_point\">Punctul Alb</string>\n    <string name=\"tag_primary_chromaticities\">Cromatici primare</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Coeficienți</string>\n    <string name=\"tag_reference_black_white\">Referință Black White</string>\n    <string name=\"tag_datetime\">Data Ora</string>\n    <string name=\"tag_image_description\">Descrierea imaginii</string>\n    <string name=\"tag_make\">Face</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Software</string>\n    <string name=\"tag_artist\">Artist</string>\n    <string name=\"tag_copyright\">Drepturi de autor</string>\n    <string name=\"tag_exif_version\">Versiune Exif</string>\n    <string name=\"tag_flashpix_version\">Versiunea Flashpix</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Dimensiunea Pixel X</string>\n    <string name=\"tag_pixel_y_dimension\">Dimensiunea pixelului Y</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Biți comprimați per pixel</string>\n    <string name=\"tag_maker_note\">Notă producătorului</string>\n    <string name=\"tag_user_comment\">Comentariu utilizator</string>\n    <string name=\"tag_related_sound_file\">Fișier de sunet înrudit</string>\n    <string name=\"tag_datetime_original\">Data Ora Original</string>\n    <string name=\"tag_datetime_digitized\">Data Ora digitizat</string>\n    <string name=\"tag_offset_time\">Timp de compensare</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Timp de compensare digitalizat</string>\n    <string name=\"tag_subsec_time\">Timp sub sec</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Time Original</string>\n    <string name=\"tag_subsec_time_digitized\">Timp sub sec. digitizat</string>\n    <string name=\"tag_exposure_time\">Timp de expunere</string>\n    <string name=\"tag_f_number\">Numărul F</string>\n    <string name=\"tag_exposure_program\">Programul de expunere</string>\n    <string name=\"tag_spectral_sensitivity\">Sensibilitatea spectrală</string>\n    <string name=\"tag_photographic_sensitivity\">Sensibilitate fotografică</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Tip de sensibilitate</string>\n    <string name=\"tag_standard_output_sensitivity\">Sensibilitate standard de ieșire</string>\n    <string name=\"tag_recommended_exposure_index\">Indicele de expunere recomandat</string>\n    <string name=\"tag_iso_speed\">Viteza ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Viteza ISO Latitudine aaa</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Viteza ISO Latitudine zzz</string>\n    <string name=\"tag_shutter_speed_value\">Valoarea vitezei obturatorului</string>\n    <string name=\"tag_aperture_value\">Valoarea diafragmei</string>\n    <string name=\"tag_brightness_value\">Valoarea luminozității</string>\n    <string name=\"tag_exposure_bias_value\">Valoarea părtinirii expunerii</string>\n    <string name=\"tag_max_aperture_value\">Valoarea maximă a diafragmei</string>\n    <string name=\"tag_subject_distance\">Distanța subiectului</string>\n    <string name=\"tag_metering_mode\">Modul de măsurare</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Domeniul de subiect</string>\n    <string name=\"tag_focal_length\">Distanța focală</string>\n    <string name=\"tag_flash_energy\">Energie Flash</string>\n    <string name=\"tag_spatial_frequency_response\">Răspuns în frecvență spațială</string>\n    <string name=\"tag_focal_plane_x_resolution\">Rezoluția planului focal X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Rezoluția Y a planului focal</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Unitatea de rezoluție în planul focal</string>\n    <string name=\"tag_subject_location\">Locația subiectului</string>\n    <string name=\"tag_exposure_index\">Indicele de expunere</string>\n    <string name=\"tag_sensing_method\">Metoda de detectare</string>\n    <string name=\"tag_file_source\">Sursa fișierului</string>\n    <string name=\"tag_cfa_pattern\">Model CFA</string>\n    <string name=\"tag_custom_rendered\">Personalizat randat</string>\n    <string name=\"tag_exposure_mode\">Modul de expunere</string>\n    <string name=\"tag_white_balance\">Balanța de alb</string>\n    <string name=\"tag_digital_zoom_ratio\">Raport de zoom digital</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Distanța focală în film de 35 mm</string>\n    <string name=\"tag_scene_capture_type\">Tip de captură a scenei</string>\n    <string name=\"tag_gain_control\">Obțineți controlul</string>\n    <string name=\"tag_contrast\">Contrast</string>\n    <string name=\"tag_saturation\">Saturaţie</string>\n    <string name=\"tag_sharpness\">Claritate</string>\n    <string name=\"tag_device_setting_description\">Descrierea setărilor dispozitivului</string>\n    <string name=\"tag_subject_distance_range\">Distanța subiectului</string>\n    <string name=\"tag_image_unique_id\">ID unic de imagine</string>\n    <string name=\"tag_camera_owner_name\">Numele proprietarului camerei</string>\n    <string name=\"tag_body_serial_number\">Numărul de serie al corpului</string>\n    <string name=\"tag_lens_specification\">Specificații lentile</string>\n    <string name=\"tag_lens_make\">Fabricarea lentilelor</string>\n    <string name=\"tag_lens_model\">Model de lentile</string>\n    <string name=\"tag_lens_serial_number\">Numărul de serie al obiectivului</string>\n    <string name=\"tag_gps_version_id\">ID versiunea GPS</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitudine Ref</string>\n    <string name=\"tag_gps_latitude\">GPS Latitudine</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Longitudine Ref</string>\n    <string name=\"tag_gps_longitude\">Longitudine GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Altitudine GPS Ref</string>\n    <string name=\"tag_gps_altitude\">Altitudine GPS</string>\n    <string name=\"tag_gps_timestamp\">Marca de timp GPS</string>\n    <string name=\"tag_gps_satellites\">Sateliți GPS</string>\n    <string name=\"tag_gps_status\">Stare GPS</string>\n    <string name=\"tag_gps_measure_mode\">Modul de măsurare GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Viteza GPS Ref</string>\n    <string name=\"tag_gps_speed\">Viteza GPS</string>\n    <string name=\"tag_gps_track_ref\">Traseu GPS Ref</string>\n    <string name=\"tag_gps_track\">Track GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Direcție imagini GPS Ref</string>\n    <string name=\"tag_gps_img_direction\">Direcția imaginii GPS</string>\n    <string name=\"tag_gps_map_datum\">Date de hartă GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitudine Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitudine Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Longitudine</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Rulment GPS Dest Ref</string>\n    <string name=\"tag_gps_dest_bearing\">Rulment GPS Dest</string>\n    <string name=\"tag_gps_dest_distance_ref\">Distanța de destinație GPS Ref</string>\n    <string name=\"tag_gps_dest_distance\">Distanța de destinație GPS</string>\n    <string name=\"tag_gps_processing_method\">Metoda de procesare GPS</string>\n    <string name=\"tag_gps_area_information\">Informații despre zonă GPS</string>\n    <string name=\"tag_gps_datestamp\">Ștampila de dată GPS</string>\n    <string name=\"tag_gps_differential\">Diferenţial GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Eroare de poziționare GPS H</string>\n    <string name=\"tag_interoperability_index\">Index de interoperabilitate</string>\n    <string name=\"tag_dng_version\">Versiunea DNG</string>\n    <string name=\"tag_default_crop_size\">Dimensiune implicită de decupare</string>\n    <string name=\"tag_orf_preview_image_start\">Previzualizare imagine Start</string>\n    <string name=\"tag_orf_preview_image_length\">Previzualizează lungimea imaginii</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect Frame</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Marginea inferioară a senzorului</string>\n    <string name=\"tag_rw2_sensor_left_border\">Senzor Chenar stânga</string>\n    <string name=\"tag_rw2_sensor_right_border\">Senzor Chenar drept</string>\n    <string name=\"tag_rw2_sensor_top_border\">Marginea superioară a senzorului</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Desenați text pe cale cu font și culoare date</string>\n    <string name=\"font_size\">Dimensiunea fontului</string>\n    <string name=\"repeat_text\">Repetați textul</string>\n    <string name=\"repeat_text_sub\">Textul curent va fi repetat până la sfârșitul căii în loc de desenul o singură dată</string>\n    <string name=\"dash_size\">Dimensiunea liniuței</string>\n    <string name=\"draw_mode_image_sub\">Utilizați imaginea selectată pentru a o desena de-a lungul căii date</string>\n    <string name=\"draw_image_sub\">Această imagine va fi folosită ca intrare repetitivă a căii desenate</string>\n    <string name=\"outlined_triangle_sub\">Desenează triunghiul conturat de la punctul de început până la punctul final</string>\n    <string name=\"triangle_sub\">Desenează triunghiul conturat de la punctul de început până la punctul final</string>\n    <string name=\"outlined_triangle\">Triunghi conturat</string>\n    <string name=\"triangle\">Triunghi</string>\n    <string name=\"polygon_sub\">Desenează poligon de la punctul de început până la punctul final</string>\n    <string name=\"polygon\">Poligon</string>\n    <string name=\"outlined_polygon\">Poligon conturat</string>\n    <string name=\"outlined_polygon_sub\">Desenează poligonul conturat de la punctul de început până la punctul final</string>\n    <string name=\"vertices\">Noduri</string>\n    <string name=\"draw_regular_polygon\">Desenați poligonul obișnuit</string>\n    <string name=\"draw_regular_polygon_sub\">Desenați poligon care va fi regulat în loc de formă liberă</string>\n    <string name=\"star_sub\">Desenează stea de la punctul de început până la punctul final</string>\n    <string name=\"star\">Stea</string>\n    <string name=\"outlined_star\">Steaua conturată</string>\n    <string name=\"outlined_star_sub\">Desenează stea conturată de la punctul de început până la punctul final</string>\n    <string name=\"inner_radius_ratio\">Raportul razei interioare</string>\n    <string name=\"draw_regular_star\">Desenați o stea obișnuită</string>\n    <string name=\"draw_regular_star_sub\">Desenați o stea care va fi o formă obișnuită în loc de liberă</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Activează antialiasing pentru a preveni marginile ascuțite</string>\n    <string name=\"click_to_start_scanning\">Faceți clic pentru a începe scanarea</string>\n    <string name=\"start_scanning\">Începeți scanarea</string>\n    <string name=\"save_as_pdf\">Salvați ca PDF</string>\n    <string name=\"share_as_pdf\">Distribuie ca PDF</string>\n    <string name=\"equalize_histogram_hsv\">Egalizare histograma HSV</string>\n    <string name=\"equalize_histogram\">Egalizare histograma</string>\n    <string name=\"enter_percentage\">Introduceți un procentaj</string>\n    <string name=\"linear\">Liniar</string>\n    <string name=\"equalize_histogram_pixelation\">Egalizați pixelarea histogramei</string>\n    <string name=\"grid_size_x\">Mărimea rețelei X</string>\n    <string name=\"grid_size_y\">Dimensiunea grilei Y</string>\n    <string name=\"equalize_histogram_adaptive\">Egalizare histogramă adaptivă</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Egalizare histogramă Adaptive LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Egalizare histogramă Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Decupați la conținut</string>\n    <string name=\"frame_color\">Culoarea cadrului</string>\n    <string name=\"color_to_ignore\">Culoare de ignorat</string>\n    <string name=\"as_file\">Ca dosar</string>\n    <string name=\"save_as_file\">Salvați ca fișier</string>\n    <string name=\"filter_preview\">Previzualizare filtru</string>\n    <string name=\"code_content\">Conținutul codului</string>\n    <string name=\"min\">Min</string>\n    <string name=\"cubic\">Cub</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">gaussian</string>\n    <string name=\"sphinx\">Sfinxul</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-El</string>\n    <string name=\"box\">Cutie</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Interpolarea cubică oferă o scalare mai lină, luând în considerare cei mai apropiați 16 pixeli, oferind rezultate mai bune decât biliniare</string>\n    <string name=\"bspline_sub\">Utilizează funcții polinomiale definite în bucăți pentru a interpola fără probleme și a aproxima o curbă sau o suprafață, o reprezentare flexibilă și continuă a formei</string>\n    <string name=\"hamming_sub\">O funcție de fereastră utilizată pentru a reduce scurgerea spectrală prin înclinarea marginilor unui semnal, utilă în procesarea semnalului</string>\n    <string name=\"hanning_sub\">O variantă a ferestrei Hann, folosită în mod obișnuit pentru a reduce scurgerea spectrală în aplicațiile de procesare a semnalului</string>\n    <string name=\"blackman_sub\">O funcție de fereastră care oferă o rezoluție bună de frecvență prin minimizarea scurgerilor spectrale, adesea folosită în procesarea semnalului</string>\n    <string name=\"welch_sub\">O funcție de fereastră concepută pentru a oferi o rezoluție bună de frecvență cu scurgeri spectrale reduse, adesea folosită în aplicațiile de procesare a semnalului</string>\n    <string name=\"quadric_sub\">O metodă care utilizează o funcție pătratică pentru interpolare, oferind rezultate netede și continue</string>\n    <string name=\"gaussian_sub\">O metodă de interpolare care aplică o funcție Gaussiană, utilă pentru netezirea și reducerea zgomotului în imagini</string>\n    <string name=\"bartlett_sub\">O funcție de fereastră triunghiulară utilizată în procesarea semnalului pentru a reduce scurgerea spectrală</string>\n    <string name=\"robidoux_sub\">O metodă de interpolare de înaltă calitate, optimizată pentru redimensionarea naturală a imaginii, echilibrând claritatea și netezimea</string>\n    <string name=\"robidoux_sharp_sub\">O variantă mai clară a metodei Robidoux, optimizată pentru redimensionarea clară a imaginii</string>\n    <string name=\"spline16_sub\">O metodă de interpolare bazată pe spline care oferă rezultate netede folosind un filtru de 16 atingeri</string>\n    <string name=\"spline36_sub\">O metodă de interpolare bazată pe spline care oferă rezultate netede folosind un filtru de 36 de atingeri</string>\n    <string name=\"kaiser_sub\">O metodă de interpolare care utilizează fereastra Kaiser, oferind un control bun asupra compromisului dintre lățimea lobului principal și nivelul lobului lateral</string>\n    <string name=\"bartlett_hann_sub\">O funcție de fereastră hibridă care combină ferestrele Bartlett și Hann, utilizată pentru a reduce scurgerea spectrală în procesarea semnalului</string>\n    <string name=\"box_sub\">O metodă simplă de reeșantionare care utilizează media celor mai apropiate valori ale pixelilor, rezultând adesea un aspect blocat</string>\n    <string name=\"bohman_sub\">O funcție de fereastră utilizată pentru a reduce scurgerea spectrală, oferind o rezoluție bună a frecvenței în aplicațiile de procesare a semnalului</string>\n    <string name=\"lanczos2_jinc_sub\">O variantă a filtrului Lanczos 2 care utilizează funcția jinc, oferind interpolare de înaltă calitate cu artefacte minime</string>\n    <string name=\"lanczos3_jinc_sub\">O variantă a filtrului Lanczos 3 care utilizează funcția jinc, oferind interpolare de înaltă calitate cu artefacte minime</string>\n    <string name=\"lanczos4_jinc_sub\">O variantă a filtrului Lanczos 4 care utilizează funcția jinc, oferind interpolare de înaltă calitate cu artefacte minime</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Varianta medie ponderată eliptică (EWA) a filtrului Hanning pentru interpolare și reeșantionare lină</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Varianta elliptical Weighted Average (EWA) a filtrului Robidoux pentru reeșantionare de înaltă calitate</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Varianta elliptical Weighted Average (EWA) a filtrului Blackman pentru minimizarea artefactelor de apel</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Varianta medie ponderată eliptică (EWA) a filtrului Quadric pentru o interpolare lină</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Varianta medie ponderată eliptică (EWA) a filtrului Robidoux Sharp pentru rezultate mai clare</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Varianta elliptical Weighted Average (EWA) a filtrului Lanczos 3 Jinc pentru reeșantionare de înaltă calitate cu aliasing redus</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Un filtru de reeșantionare conceput pentru procesarea imaginilor de înaltă calitate, cu un echilibru bun de claritate și netezime</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Varianta elliptical Weighted Average (EWA) a filtrului Ginseng pentru o calitate îmbunătățită a imaginii</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Varianta medie ponderată eliptică (EWA) a filtrului Lanczos Sharp pentru obținerea de rezultate clare cu artefacte minime</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Varianta elliptical Weighted Average (EWA) a filtrului Lanczos 4 Sharpest pentru reeșantionare extrem de clară a imaginii</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Varianta elliptical Weighted Average (EWA) a filtrului Lanczos Soft pentru o reeșantionare mai fluidă a imaginii</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Un filtru de reeșantionare conceput de Haasn pentru o scalare lină și fără artefacte a imaginii</string>\n    <string name=\"dismiss_forever\">Îndepărtează pentru totdeauna</string>\n    <string name=\"add_image\">Adăugați o imagine</string>\n    <string name=\"bins_count\">Coșurile numără</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Egalizare histogramă Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Egalizare histogramă Adaptive HSV</string>\n    <string name=\"edge_mode\">Modul Edge</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Înfășurați</string>\n    <string name=\"protanomaly_sub\">Dificultatea de a face distincția între nuanțe de roșu și verde</string>\n    <string name=\"deuteranomaly_sub\">Dificultate de a face distincția între nuanțe de verde și roșu</string>\n    <string name=\"tritanomaly_sub\">Dificultatea de a face distincția între nuanțe de albastru și galben</string>\n    <string name=\"protanopia_sub\">Incapacitatea de a percepe nuanțe roșii</string>\n    <string name=\"deuteranopia_sub\">Incapacitatea de a percepe nuanțe verzi</string>\n    <string name=\"tritanopia_sub\">Incapacitatea de a percepe nuanțe albastre</string>\n    <string name=\"achromatomaly_sub\">Sensibilitate redusă la toate culorile</string>\n    <string name=\"sigmoidal\">Sigmoidală</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Un filtru de interpolare Lagrange de ordinul 2, potrivit pentru scalarea imaginii de înaltă calitate, cu tranziții netede</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">O variantă a filtrului Lanczos 6 care utilizează o funcție Jinc pentru o calitate îmbunătățită a reeșantionării imaginii</string>\n    <string name=\"linear_box_blur\">Blur casetă liniară</string>\n    <string name=\"linear_tent_blur\">Blur liniar la cort</string>\n    <string name=\"linear_gaussian_box_blur\">Blur cutie gaussiană liniară</string>\n    <string name=\"linear_stack_blur\">Neclaritate stivă liniară</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Blur Gaussian Liniar Rapid În continuare</string>\n    <string name=\"linear_fast_gaussian_blur\">Blur Gaussian Liniar Rapid</string>\n    <string name=\"linear_gaussian_blur\">Neclaritate liniară Gaussiană</string>\n    <string name=\"draw_filter_sub\">Alegeți un filtru pentru a-l folosi ca vopsea</string>\n    <string name=\"replace_filter\">Înlocuiți filtrul</string>\n    <string name=\"low_poly\">Low Poly</string>\n    <string name=\"sand_painting\">Pictura pe nisip</string>\n    <string name=\"fit_to_bounds\">Fit To Bounds</string>\n    <string name=\"languages_imported\">Limbi importate cu succes</string>\n    <string name=\"backup_ocr_models\">Backup modele OCR</string>\n    <string name=\"import_word\">Import</string>\n    <string name=\"export\">Export</string>\n    <string name=\"position\">Poziţie</string>\n    <string name=\"center\">Centru</string>\n    <string name=\"top_left\">Sus Stânga</string>\n    <string name=\"top_right\">Sus dreapta</string>\n    <string name=\"bottom_left\">Stânga jos</string>\n    <string name=\"bottom_right\">Dreapta jos</string>\n    <string name=\"top_center\">Centru de sus</string>\n    <string name=\"center_right\">Centru dreapta</string>\n    <string name=\"bottom_center\">Centru de jos</string>\n    <string name=\"center_left\">Centru stânga</string>\n    <string name=\"target_image\">Imagine țintă</string>\n    <string name=\"palette_transfer\">Transfer de paletă</string>\n    <string name=\"enhanced_oil\">Ulei îmbunătățit</string>\n    <string name=\"simple_old_tv\">Televizor vechi simplu</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Schiță simplă</string>\n    <string name=\"soft_glow\">Strălucire moale</string>\n    <string name=\"color_poster\">Poster color</string>\n    <string name=\"tri_tone\">Tri Ton</string>\n    <string name=\"third_color\">A treia culoare</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Buline</string>\n    <string name=\"clustered_2x2_dithering\">Dithering 2x2 în cluster</string>\n    <string name=\"clustered_4x4_dithering\">Dithering 4x4 în cluster</string>\n    <string name=\"clustered_8x8_dithering\">Dithering 8x8 în cluster</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"harmony_complementary\">Complementar</string>\n    <string name=\"harmony_analogous\">Analog</string>\n    <string name=\"harmony_triadic\">triadic</string>\n    <string name=\"harmony_split_complementary\">Split Complementar</string>\n    <string name=\"harmony_tetradic\">tetradic</string>\n    <string name=\"harmony_square\">Pătrat</string>\n    <string name=\"harmony_analogous_complementary\">Analog + complementar</string>\n    <string name=\"color_harmonies\">Armonii de culoare</string>\n    <string name=\"color_shading\">Umbrire de culoare</string>\n    <string name=\"variation\">Variaţie</string>\n    <string name=\"tints\">Nuanțe</string>\n    <string name=\"tones\">Tonuri</string>\n    <string name=\"shades\">Nuanțe</string>\n    <string name=\"color_mixing\">Amestecarea culorilor</string>\n    <string name=\"color_info\">Informații despre culoare</string>\n    <string name=\"selected_color\">Culoare selectată</string>\n    <string name=\"color_to_mix\">Culoare de amestecat</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Nu se poate folosi monet în timp ce culorile dinamice sunt activate</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"amatorka\">Un amator</string>\n    <string name=\"miss_etikate\">Domnișoară Etichetă</string>\n    <string name=\"soft_elegance\">Eleganță moale</string>\n    <string name=\"soft_elegance_variant\">Varianta Soft Elegance</string>\n    <string name=\"palette_transfer_variant\">Varianta de transfer de paletă</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bypass pentru înălbitor</string>\n    <string name=\"candlelight\">Lumina lumânărilor</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Chihlimbar nervos</string>\n    <string name=\"fall_colors\">Culori de toamnă</string>\n    <string name=\"film_stock_50\">Stoc de film 50</string>\n    <string name=\"foggy_night\">Noapte de ceață</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celuloid</string>\n    <string name=\"coffee\">Cafea</string>\n    <string name=\"golden_forest\">Pădurea de Aur</string>\n    <string name=\"greenish\">Verzui</string>\n    <string name=\"retro_yellow\">Galben retro</string>\n    <string name=\"ico_size_warning\">Fișierele ICO pot fi salvate numai la dimensiunea maximă de 256 x 256</string>\n    <string name=\"webp_type_to_image\">WEBP la imagini</string>\n    <string name=\"webp_type_to_image_sub\">Convertiți fișierul WEBP într-un lot de imagini</string>\n    <string name=\"webp_type_to_webp\">Imagini pe WEBP</string>\n    <string name=\"manage_storage_extra_types\">Fără acces complet la fișiere</string>\n    <string name=\"enable_timestamps_to_format_them\">Activați marcajele de timp pentru a le selecta formatul</string>\n    <string name=\"recently_used\">Folosit recent</string>\n    <string name=\"image_toolbox_in_telegram\">Caseta de instrumente pentru imagini în Telegram 🎉</string>\n    <string name=\"fit_description\">Potriviți o imagine la dimensiunile date și aplicați estompare sau culoare fundalului</string>\n    <string name=\"system_bars_visibility\">Vizibilitatea barelor de sistem</string>\n    <string name=\"show_system_bars_by_swipe\">Afișați barele de sistem prin glisare</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Permite glisarea pentru a afișa barele de sistem dacă sunt ascunse</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Ascunde tot</string>\n    <string name=\"show_all\">Arată toate</string>\n    <string name=\"hide_nav_bar\">Ascundeți bara de navigare</string>\n    <string name=\"hide_status_bar\">Ascundeți bara de stare</string>\n    <string name=\"frequency\">Frecvenţă</string>\n    <string name=\"noise_type\">Tip de zgomot</string>\n    <string name=\"rotation_type\">Tip de rotație</string>\n    <string name=\"fractal_type\">Tip fractal</string>\n    <string name=\"octaves\">Octave</string>\n    <string name=\"lacunarity\">Lacunaritatea</string>\n    <string name=\"gain\">Câştig</string>\n    <string name=\"weighted_strength\">Forța ponderată</string>\n    <string name=\"ping_pong_strength\">Puterea Ping Pong</string>\n    <string name=\"distance_function\">Funcția de distanță</string>\n    <string name=\"return_type\">Tip de returnare</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Deformarea domeniului</string>\n    <string name=\"alignment\">Aliniere</string>\n    <string name=\"custom_filename\">Nume de fișier personalizat</string>\n    <string name=\"custom_filename_sub\">Selectați locația și numele fișierului care vor fi folosite pentru a salva imaginea curentă</string>\n    <string name=\"saved_to_custom\">Salvat în dosar cu nume personalizat</string>\n    <string name=\"disable_rotation\">Dezactivați rotația</string>\n    <string name=\"disable_rotation_sub\">Împiedică rotirea imaginilor cu gesturi cu două degete</string>\n    <string name=\"enable_snapping_to_borders\">Activați fixarea la margini</string>\n    <string name=\"enable_snapping_to_borders_sub\">După deplasare sau mărire, imaginile se vor fixa pentru a umple marginile cadrului</string>\n    <string name=\"histogram\">Histogramă</string>\n    <string name=\"histogram_sub\">Histograma imaginii RGB sau Luminozitate pentru a vă ajuta să faceți ajustări</string>\n    <string name=\"custom_options\">Opțiuni personalizate</string>\n    <string name=\"custom_params_info\">Opțiunile trebuie introduse după acest model: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Decupare automată</string>\n    <string name=\"free_corners\">Colțuri libere</string>\n    <string name=\"free_corners_sub\">Decupați imaginea după poligon, aceasta corectează și perspectiva</string>\n    <string name=\"coerce_points_to_image_bounds\">Coerce Puncte la limitele imaginii</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Punctele nu vor fi limitate de limitele imaginii, acest lucru util pentru corectarea mai precisă a perspectivei</string>\n    <string name=\"mask\">Masca</string>\n    <string name=\"spot_heal_sub\">Umplerea conștientă de conținut sub calea desenată</string>\n    <string name=\"spot_heal\">Vindecarea punctului</string>\n    <string name=\"use_circle_kernel\">Utilizați Circle Kernel</string>\n    <string name=\"opening\">Deschidere</string>\n    <string name=\"closing\">Închidere</string>\n    <string name=\"morphological_gradient\">Gradient morfologic</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Pălărie Neagră</string>\n    <string name=\"tone_curves\">Curbe de ton</string>\n    <string name=\"reset_curves\">Resetează curbele</string>\n    <string name=\"reset_curves_sub\">Curbele vor fi revenite la valoarea implicită</string>\n    <string name=\"line_style\">Stil de linie</string>\n    <string name=\"gap_size\">Dimensiunea golului</string>\n    <string name=\"dashed\">întreruptă</string>\n    <string name=\"dot_dashed\">Punct întrerupt</string>\n    <string name=\"stamped\">Ștampilat</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">Desenează o linie întreruptă de-a lungul traseului desenat cu dimensiunea spațiului specificat</string>\n    <string name=\"dot_dashed_sub\">Desenează punct și linie întreruptă de-a lungul căii date</string>\n    <string name=\"defaultt_sub\">Doar linii drepte implicite</string>\n    <string name=\"stamped_sub\">Desenează formele selectate de-a lungul căii cu spațiere specificată</string>\n    <string name=\"zigzag_sub\">Desenează în zig-zag ondulat de-a lungul căii</string>\n    <string name=\"zigzag_ratio\">Raport în zig-zag</string>\n    <string name=\"dont_stack_frames\">Nu stivuiți cadre</string>\n    <string name=\"dont_stack_frames_sub\">Permite eliminarea cadrelor anterioare, astfel încât acestea să nu se strângă unele pe altele</string>\n    <string name=\"crossfade\">Fade încrucișată</string>\n    <string name=\"crossfade_sub\">Cadrele vor fi încrucișate unele în altele</string>\n    <string name=\"crossfade_count\">Cadrele de difuzare încrucișată numără</string>\n    <string name=\"threshold_one\">Pragul Unu</string>\n    <string name=\"threshold_two\">Pragul doi</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Oglinda 101</string>\n    <string name=\"enhanced_zoom_blur\">Încețoșare zoom îmbunătățită</string>\n    <string name=\"laplacian_simple\">Laplacian Simplu</string>\n    <string name=\"sobel_simple\">Sobel Simplu</string>\n    <string name=\"helper_grid\">Grilă de ajutor</string>\n    <string name=\"helper_grid_sub\">Afișează grila de sprijin deasupra zonei de desen pentru a ajuta la manipulări precise</string>\n    <string name=\"grid_color\">Culoare grilă</string>\n    <string name=\"cell_width\">Lățimea celulei</string>\n    <string name=\"cell_height\">Înălțimea celulei</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Acordați permisiunea camerei în setări pentru a captura imaginea</string>\n    <string name=\"lut_library\">Biblioteca Lut</string>\n    <string name=\"filter_preview_image_sub\">Modificați previzualizarea implicită a imaginii pentru filtre</string>\n    <string name=\"filter_preview_image\">Imagine de previzualizare</string>\n    <string name=\"hide\">Ascunde</string>\n    <string name=\"show\">Spectacol</string>\n    <string name=\"material_2\">Materialul 2</string>\n    <string name=\"material_you_slider_sub\">Un cursor Material You</string>\n    <string name=\"apply\">Aplicați</string>\n    <string name=\"area\">Zonă</string>\n    <string name=\"area_sub\">Reeșantionarea utilizând relația de suprafață a pixelilor. Poate fi o metodă preferată pentru decimarea imaginii, deoarece oferă rezultate fără moire. Dar când imaginea este mărită, este similară cu metoda „Cel mai apropiat”.</string>\n    <string name=\"enable_tonemapping\">Activați Tonemapping</string>\n    <string name=\"enter_percent\">Introduceți %</string>\n    <string name=\"unknown_host\">Nu pot accesa site-ul, încercați să utilizați VPN sau verificați dacă adresa URL este corectă</string>\n    <string name=\"edit_layer\">Editați stratul</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"clear_selection\">Ștergeți selecția</string>\n    <string name=\"base_64\">Baza 64</string>\n    <string name=\"options\">Opțiuni</string>\n    <string name=\"actions\">Acțiuni</string>\n    <string name=\"outline_color\">Culoarea conturului</string>\n    <string name=\"outline_size\">Dimensiunea conturului</string>\n    <string name=\"rotation\">Rotaţie</string>\n    <string name=\"free_software_partner\">Software gratuit (partener)</string>\n    <string name=\"free_software_partner_sub\">Mai mult software util în canalul partener al aplicațiilor Android</string>\n    <string name=\"algorithms\">Algoritm</string>\n    <string name=\"calculate\">Calcula</string>\n    <string name=\"text_hash\">Text Hash</string>\n    <string name=\"checksum\">Sumă de control</string>\n    <string name=\"pick_file_to_checksum\">Alegeți fișierul pentru a calcula suma de control pe baza algoritmului selectat</string>\n    <string name=\"enter_text_to_checksum\">Introduceți text pentru a calcula suma de control pe baza algoritmului selectat</string>\n    <string name=\"source_checksum\">Sumă de control sursă</string>\n    <string name=\"checksum_to_compare\">Sumă de control de comparat</string>\n    <string name=\"match\">Meci!</string>\n    <string name=\"difference\">Diferenţă</string>\n    <string name=\"match_sub\">Sumele de control sunt egale, poate fi sigur</string>\n    <string name=\"difference_sub\">Sumele de control nu sunt egale, fișierul poate fi nesigur!</string>\n    <string name=\"wrong_font\">Numai fonturile TTF și OTF pot fi importate</string>\n    <string name=\"import_font\">Import font (TTF/OTF)</string>\n    <string name=\"export_fonts\">Exportați fonturi</string>\n    <string name=\"imported_fonts\">Fonturi importate</string>\n    <string name=\"error_while_saving\">Eroare la salvarea încercării, încercați să schimbați folderul de ieșire</string>\n    <string name=\"filename_is_not_set\">Numele fișierului nu este setat</string>\n    <string name=\"none\">Nici unul</string>\n    <string name=\"custom_pages\">Pagini personalizate</string>\n    <string name=\"pages_selection\">Selectarea paginilor</string>\n    <string name=\"change_sticker\">Schimbați autocolantul</string>\n    <string name=\"fit_width\">Lățimea de potrivire</string>\n    <string name=\"fit_height\">Înălțime de potrivire</string>\n    <string name=\"batch_compare\">Comparare lot</string>\n    <string name=\"pick_files_to_checksum\">Alegeți fișierul/fișierele pentru a calcula suma de control pe baza algoritmului selectat</string>\n    <string name=\"pick_files\">Alegeți Fișiere</string>\n    <string name=\"pick_directory\">Alegeți Director</string>\n    <string name=\"head_length_scale\">Scala de lungime a capului</string>\n    <string name=\"stamp\">Ştampila</string>\n    <string name=\"timestamp\">Marca temporală</string>\n    <string name=\"format_pattern\">Format Pattern</string>\n    <string name=\"padding\">Captuseala</string>\n    <string name=\"vertical_pivot_line\">Linie pivot verticală</string>\n    <string name=\"horizontal_pivot_line\">Linie pivot orizontală</string>\n    <string name=\"inverse_selection\">Selecția inversă</string>\n    <string name=\"inverse_vertical_selection_sub\">Partea tăiată verticală va fi părăsită, în loc de unirea părților în jurul zonei tăiate</string>\n    <string name=\"inverse_horizontal_selection_sub\">Partea tăiată orizontal va fi părăsită, în loc să îmbine părțile în jurul zonei tăiate</string>\n    <string name=\"collection_mesh_gradients\">Colecție de degrade de plasă</string>\n    <string name=\"mesh_gradients_sub\">Creați gradient de plasă cu o cantitate personalizată de noduri și rezoluție</string>\n    <string name=\"gradient_maker_type_image_mesh\">Suprapunere cu gradient de plasă</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Compune gradient de plasă din partea de sus a imaginilor date</string>\n    <string name=\"points_customization\">Personalizare puncte</string>\n    <string name=\"grid_size\">Dimensiunea grilei</string>\n    <string name=\"resolution_x\">Rezoluția X</string>\n    <string name=\"resolution_y\">Rezoluția Y</string>\n    <string name=\"resolution\">Rezoluţie</string>\n    <string name=\"pixel_by_pixel\">Pixel cu pixel</string>\n    <string name=\"highlight_color\">Evidențiați Culoare</string>\n    <string name=\"pixel_comparison_type\">Tip de comparație de pixeli</string>\n    <string name=\"scan_barcode\">Scanați codul de bare</string>\n    <string name=\"height_ratio\">Raportul de înălțime</string>\n    <string name=\"barcode_type\">Tip cod de bare</string>\n    <string name=\"enforce_bw\">Aplicați alb/negru</string>\n    <string name=\"enforce_bw_sub\">Imaginea codului de bare va fi complet alb-negru și nu va fi colorată după tema aplicației</string>\n    <string name=\"barcodes_sub\">Scanați orice cod de bare (QR, EAN, AZTEC, …) și obțineți conținutul acestuia sau inserați textul pentru a genera unul nou</string>\n    <string name=\"no_barcode_found\">Nu a fost găsit niciun cod de bare</string>\n    <string name=\"generated_barcode_will_be_here\">Codul de bare generat va fi aici</string>\n    <string name=\"audio_cover_extractor\">Coperți audio</string>\n    <string name=\"audio_cover_extractor_sub\">Extrageți imagini de copertă de album din fișierele audio, cele mai comune formate sunt acceptate</string>\n    <string name=\"pick_audio_to_start\">Alegeți audio pentru a începe</string>\n    <string name=\"pick_audio\">Alegeți Audio</string>\n    <string name=\"no_covers_found\">Nu s-au găsit coperți</string>\n    <string name=\"send_logs\">Trimiteți jurnalele</string>\n    <string name=\"send_logs_sub\">Faceți clic pentru a partaja fișierul jurnal al aplicației, acest lucru mă poate ajuta să identific problema și să remediez problemele</string>\n    <string name=\"crash_title\">Hopa… Ceva a mers prost</string>\n    <string name=\"crash_subtitle\">Mă puteți contacta folosind opțiunile de mai jos și voi încerca să găsesc o soluție.\\n(Nu uitați să atașați jurnalele)</string>\n    <string name=\"ocr_write_to_file\">Scrieți în fișier</string>\n    <string name=\"ocr_write_to_file_sub\">Extrageți text din lotul de imagini și stocați-l într-un singur fișier text</string>\n    <string name=\"ocr_write_to_metadata\">Scrieți în metadate</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extrageți text din fiecare imagine și plasați-l în informațiile EXIF ​​ale fotografiilor relative</string>\n    <string name=\"invisible_mode\">Modul invizibil</string>\n    <string name=\"invisible_mode_sub\">Utilizați steganografia pentru a crea filigrane invizibile pentru ochi în interiorul octeților imaginilor dvs</string>\n    <string name=\"use_lsb\">Folosiți LSB</string>\n    <string name=\"use_lsb_sub\">Se va folosi metoda steganografiei LSB (Less Significant Bit), în caz contrar FD (Frequency Domain).</string>\n    <string name=\"auto_remove_red_eyes\">Eliminare automată a ochilor roșii</string>\n    <string name=\"password\">Parolă</string>\n    <string name=\"unlock\">Deblocați</string>\n    <string name=\"pdf_is_protected\">PDF-ul este protejat</string>\n    <string name=\"operation_almost_complete\">Operațiune aproape finalizată. Anularea acum va necesita repornirea acestuia</string>\n    <string name=\"sort_by_date_modified\">Data modificării</string>\n    <string name=\"sort_by_date_modified_reversed\">Data modificării (inversată)</string>\n    <string name=\"sort_by_size\">Dimensiune</string>\n    <string name=\"sort_by_size_reversed\">Dimensiune (inversată)</string>\n    <string name=\"sort_by_mime_type\">Tip MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Tip MIME (inversat)</string>\n    <string name=\"sort_by_extension\">Extensie</string>\n    <string name=\"sort_by_extension_reversed\">Extensie (inversată)</string>\n    <string name=\"sort_by_date_added\">Data Adăugării</string>\n    <string name=\"sort_by_date_added_reversed\">Data adaugarii (inversata)</string>\n    <string name=\"left_to_right\">De la stânga la dreapta</string>\n    <string name=\"right_to_left\">De la dreapta la stânga</string>\n    <string name=\"top_to_bottom\">De sus în jos</string>\n    <string name=\"bottom_to_top\">De jos în sus</string>\n    <string name=\"liquid_glass\">Sticla lichida</string>\n    <string name=\"liquid_glass_sub\">Un comutator bazat pe IOS 26 anunțat recent și pe sistemul de design din sticlă lichidă</string>\n    <string name=\"pick_image_or_base64\">Alegeți imaginea sau inserați/importați datele Base64 de mai jos</string>\n    <string name=\"type_image_link\">Introduceți linkul pentru imagine pentru a începe</string>\n    <string name=\"paste_link\">Lipiți linkul</string>\n    <string name=\"kaleidoscope\">Caleidoscop</string>\n    <string name=\"secondary_angle\">Unghiul secundar</string>\n    <string name=\"sides\">Laturile</string>\n    <string name=\"channel_mix\">Mix de canale</string>\n    <string name=\"blue_green\">Albastru verde</string>\n    <string name=\"red_blue\">Roșu albastru</string>\n    <string name=\"green_red\">verde roșu</string>\n    <string name=\"into_red\">În roșu</string>\n    <string name=\"into_green\">În verde</string>\n    <string name=\"into_blue\">În albastru</string>\n    <string name=\"cyan\">Cyan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Galben</string>\n    <string name=\"color_halftone\">Culoare semiton</string>\n    <string name=\"contour\">Contur</string>\n    <string name=\"levels\">Niveluri</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi Cristalizează</string>\n    <string name=\"shape\">Formă</string>\n    <string name=\"stretch\">Întinde</string>\n    <string name=\"randomness\">Aleatorie</string>\n    <string name=\"despeckle\">Descurcă</string>\n    <string name=\"diffuse\">Difuz</string>\n    <string name=\"dog\">Câine</string>\n    <string name=\"second_radius\">Raza a doua</string>\n    <string name=\"equalize\">Egaliza</string>\n    <string name=\"glow\">Strălucire</string>\n    <string name=\"whirl_and_pinch\">Învârtiți și Ciupiți</string>\n    <string name=\"pointillize\">Pointilize</string>\n    <string name=\"border_color\">Culoarea chenarului</string>\n    <string name=\"polar_coordinates\">Coordonatele polare</string>\n    <string name=\"rect_to_polar\">Rect la polar</string>\n    <string name=\"polar_to_rect\">Polar spre rect</string>\n    <string name=\"invert_in_circle\">Întoarceți în cerc</string>\n    <string name=\"reduce_noise\">Reduceți zgomotul</string>\n    <string name=\"simple_solarize\">Solarizare simplă</string>\n    <string name=\"weave\">Ţese</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X Latime</string>\n    <string name=\"y_wdth\">Lățimea Y</string>\n    <string name=\"twirl\">Învârti</string>\n    <string name=\"rubber_stmp\">Ștampilă de cauciuc</string>\n    <string name=\"smear\">Frotiu</string>\n    <string name=\"density\">Densitate</string>\n    <string name=\"mix\">Amesteca</string>\n    <string name=\"sphere_lensh_distortion\">Distorsiunea lentilei sferice</string>\n    <string name=\"refraction_index\">Indicele de refracție</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Unghiul de răspândire</string>\n    <string name=\"sparkle\">Scânteie</string>\n    <string name=\"rays\">Raze</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Maria</string>\n    <string name=\"autumn\">Toamnă</string>\n    <string name=\"bone\">Os</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Iarnă</string>\n    <string name=\"ocean\">Ocean</string>\n    <string name=\"summer\">Vară</string>\n    <string name=\"spring\">Primăvară</string>\n    <string name=\"cool_variant\">Varianta cool</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Roz</string>\n    <string name=\"hot\">Fierbinte</string>\n    <string name=\"parula\">Cuvânt</string>\n    <string name=\"magma\">Magmă</string>\n    <string name=\"inferno\">Infern</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Cetăţeni</string>\n    <string name=\"twilight\">Amurg</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspectivă Auto</string>\n    <string name=\"deskew\">Declina</string>\n    <string name=\"allow_crop\">Permite decuparea</string>\n    <string name=\"crop_or_perspective\">Decupare sau Perspectivă</string>\n    <string name=\"absolute\">Absolut</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Verde adânc</string>\n    <string name=\"lens_correction\">Corectarea lentilelor</string>\n    <string name=\"target_lens_profile\">Fișierul de profil al obiectivului țintă în format JSON</string>\n    <string name=\"download_ready_lens_profiles\">Descărcați profile de lentile gata</string>\n    <string name=\"part_percents\">Procente de parte</string>\n    <string name=\"export_as_json\">Exportați ca JSON</string>\n    <string name=\"export_as_json_sub\">Copiați șirul cu date din paletă ca reprezentare json</string>\n    <string name=\"seam_carving\">Sculptura cusături</string>\n    <string name=\"home_screen\">Ecranul de pornire</string>\n    <string name=\"lock_screen\">Blocare ecran</string>\n    <string name=\"built_in\">Încorporat</string>\n    <string name=\"wallpapers_export\">Export de imagini de fundal</string>\n    <string name=\"refresh\">Reîmprospăta</string>\n    <string name=\"wallpapers_export_sub\">Obțineți imagini de fundal actuale Acasă, Blocare și încorporate</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Permiteți accesul la toate fișierele, acest lucru este necesar pentru a prelua imagini de fundal</string>\n    <string name=\"allow_read_media_images_for_wp\">Permisiunea de gestionare a stocării externe nu este suficientă, trebuie să permiteți accesul la imaginile dvs., asigurați-vă că selectați „Permiteți toate”</string>\n    <string name=\"add_preset_to_filename\">Adăugați presetarea la numele fișierului</string>\n    <string name=\"add_preset_to_filename_sub\">Adaugă sufixul cu presetarea selectată la numele fișierului imagine</string>\n    <string name=\"add_image_scale_mode_to_filename\">Adăugați modul de scalare a imaginii la numele fișierului</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Adaugă sufixul cu modul de scară a imaginii selectat la numele fișierului imagine</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Convertiți imaginea în text ascii care va arăta ca o imagine</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Aplică filtru negativ imaginii pentru un rezultat mai bun în unele cazuri</string>\n    <string name=\"processing_screenshot\">Se procesează captură de ecran</string>\n    <string name=\"screenshot_not_captured_try_again\">Captura de ecran nu a fost capturată, încercați din nou</string>\n    <string name=\"skipped_saving\">Salvarea a fost omisă</string>\n    <string name=\"skipped_saving_multiple\">%1$s fișiere au fost ignorate</string>\n    <string name=\"allow_skip_if_larger\">Permiteți săriți dacă este mai mare</string>\n    <string name=\"allow_skip_if_larger_sub\">Unele instrumente vor putea sări peste salvarea imaginilor dacă dimensiunea fișierului rezultat ar fi mai mare decât cea originală</string>\n    <string name=\"qr_type_calendar_event\">Eveniment din calendar</string>\n    <string name=\"qr_type_contact_info\">Contact</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Locaţie</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wifi</string>\n    <string name=\"open_network\">Rețea deschisă</string>\n    <string name=\"not_specified\">N / A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Mesaj</string>\n    <string name=\"address\">Adresa</string>\n    <string name=\"subject\">Subiect</string>\n    <string name=\"body\">Corp</string>\n    <string name=\"name\">Nume</string>\n    <string name=\"organization\">Organizare</string>\n    <string name=\"title\">Titlu</string>\n    <string name=\"phones\">Telefoane</string>\n    <string name=\"emails\">E-mailuri</string>\n    <string name=\"urls\">URL-uri</string>\n    <string name=\"addresses\">Adrese</string>\n    <string name=\"summary\">Rezumat</string>\n    <string name=\"description\">Descriere</string>\n    <string name=\"location\">Locaţie</string>\n    <string name=\"organizer\">Organizator</string>\n    <string name=\"start_date\">Data de începere</string>\n    <string name=\"end_date\">Data de încheiere</string>\n    <string name=\"status\">Stare</string>\n    <string name=\"latitude\">Latitudine</string>\n    <string name=\"longitude\">Longitudine</string>\n    <string name=\"create_barcode\">Creați cod de bare</string>\n    <string name=\"edit_barcode\">Editați codul de bare</string>\n    <string name=\"wifi_configuration\">Configurare Wi-Fi</string>\n    <string name=\"security\">Securitate</string>\n    <string name=\"pick_contact\">Alegeți contact</string>\n    <string name=\"grant_contact_permission\">Acordați persoanelor de contact din setări permisiunea de a completa automat folosind contactul selectat</string>\n    <string name=\"contact_info\">Informații de contact</string>\n    <string name=\"first_name\">Prenume</string>\n    <string name=\"middle_name\">Al doilea prenume</string>\n    <string name=\"last_name\">Nume</string>\n    <string name=\"pronunciation\">Pronunţie</string>\n    <string name=\"add_phone\">Adăugați telefon</string>\n    <string name=\"add_email\">Adăugați e-mail</string>\n    <string name=\"add_address\">Adăugați adresa</string>\n    <string name=\"website\">Site-ul web</string>\n    <string name=\"add_website\">Adăugați site-ul web</string>\n    <string name=\"formatted_name\">Nume formatat</string>\n    <string name=\"qr_code_top_image\">Această imagine va fi folosită pentru a plasa deasupra codului de bare</string>\n    <string name=\"code_customization\">Personalizarea codului</string>\n    <string name=\"qr_logo_image\">Această imagine va fi folosită ca logo în centrul codului QR</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Captuseala cu logo</string>\n    <string name=\"logo_size\">Dimensiunea logo-ului</string>\n    <string name=\"logo_corners\">Colțuri de logo</string>\n    <string name=\"fourth_eye\">Al patrulea ochi</string>\n    <string name=\"fourth_eye_description\">Adaugă simetria ochiului codului qr adăugând al patrulea ochi în colțul de jos</string>\n    <string name=\"pixel_shape\">Forma pixelului</string>\n    <string name=\"frame_shape\">Forma cadrului</string>\n    <string name=\"ball_shape\">Forma mingii</string>\n    <string name=\"error_correction_level\">Nivel de corectare a erorilor</string>\n    <string name=\"dark_color\">Culoare închisă</string>\n    <string name=\"light_color\">Culoare deschisă</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Stilul ca Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Model de mască</string>\n    <string name=\"code_may_be_not_scannable\">Este posibil ca acest cod să nu poată fi scanat, modificați parametrii de aspect pentru a-l face citibil cu toate dispozitivele</string>\n    <string name=\"not_scannable\">Nu se poate scana</string>\n    <string name=\"launcher_mode_sub\">Instrumentele vor arăta ca lansatorul de aplicații pe ecranul de pornire pentru a fi mai compact</string>\n    <string name=\"launcher_mode\">Modul Lansator</string>\n    <string name=\"flood_fill_sub\">Umple o zonă cu pensula și stilul selectate</string>\n    <string name=\"flood_fill\">Umplere de inundație</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Desenează calea în stil graffity</string>\n    <string name=\"square_particles\">Particule pătrate</string>\n    <string name=\"square_particles_sub\">Particulele de pulverizare vor avea formă pătrată în loc de cercuri</string>\n    <string name=\"palette_tools\">Instrumente de paletă</string>\n    <string name=\"palette_tools_sub\">Generați de bază/materialul pe care îl paletați din imagine sau importați/exportați în diferite formate de paletă</string>\n    <string name=\"edit_palette\">Editați paleta</string>\n    <string name=\"edit_palette_sub\">Paleta de export/import în diferite formate</string>\n    <string name=\"color_name\">Numele culorii</string>\n    <string name=\"palette_name\">Numele paletei</string>\n    <string name=\"palette_format\">Format paletă</string>\n    <string name=\"export_palette_sub\">Exportați paleta generată în diferite formate</string>\n    <string name=\"add_color_palette_sub\">Adaugă o nouă culoare paletei curente</string>\n    <string name=\"palette_name_not_supported\">Formatul %1$s nu acceptă furnizarea numelui paletei</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Din cauza politicilor Magazinului Play, această funcție nu poate fi inclusă în versiunea actuală. Pentru a accesa această funcționalitate, vă rugăm să descărcați ImageToolbox dintr-o sursă alternativă. Puteți găsi versiunile disponibile pe GitHub mai jos.</string>\n    <string name=\"open_github_page\">Deschideți pagina Github</string>\n    <string name=\"overwrite_files_sub_short\">Fișierul original va fi înlocuit cu unul nou în loc să fie salvat în folderul selectat</string>\n    <string name=\"hidden_watermark_text_detected\">S-a detectat text filigran ascuns</string>\n    <string name=\"hidden_watermark_image_detected\">S-a detectat imaginea de filigran ascunsă</string>\n    <string name=\"this_image_was_hidden\">Această imagine a fost ascunsă</string>\n    <string name=\"generative_inpaint\">Inpainting generativ</string>\n    <string name=\"generative_inpaint_sub\">Vă permite să eliminați obiecte dintr-o imagine folosind un model AI, fără a vă baza pe OpenCV. Pentru a utiliza această caracteristică, aplicația va descărca modelul necesar (~200 MB) de pe GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Vă permite să eliminați obiecte dintr-o imagine folosind un model AI, fără a vă baza pe OpenCV. Aceasta ar putea fi o operațiune de lungă durată</string>\n    <string name=\"error_level_analysis\">Analiza nivelului de eroare</string>\n    <string name=\"luminance_gradient\">Gradient de luminanță</string>\n    <string name=\"average_distance\">Distanța medie</string>\n    <string name=\"copy_move_detection\">Copiere detecție mișcare</string>\n    <string name=\"retain\">Reţine</string>\n    <string name=\"coefficent\">coeficient</string>\n    <string name=\"clipboard_data_is_too_large\">Datele din clipboard sunt prea mari</string>\n    <string name=\"data_is_too_large_to_copy\">Datele sunt prea mari pentru a fi copiate</string>\n    <string name=\"simple_weave_pixelization\">Pixelizare simplă a țesăturii</string>\n    <string name=\"staggered_pixelization\">Pixelizare eșalonată</string>\n    <string name=\"cross_pixelization\">Pixelizare încrucișată</string>\n    <string name=\"micro_macro_pixelization\">Micro Macro Pixelization</string>\n    <string name=\"orbital_pixelization\">Pixelizare orbitală</string>\n    <string name=\"vortex_pixelization\">Pixelizare vortex</string>\n    <string name=\"pulse_grid_pixelization\">Pixelizare grilă de impulsuri</string>\n    <string name=\"nucleus_pixelization\">Pixelizarea nucleului</string>\n    <string name=\"radial_weave_pixelization\">Pixelizare țesătură radială</string>\n    <string name=\"cannot_open_uri\">Nu se poate deschide uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Modul Zăpadă</string>\n    <string name=\"enabled\">Activat</string>\n    <string name=\"border_frame\">Cadru de chenar</string>\n    <string name=\"glitch_variant\">Varianta Glitch</string>\n    <string name=\"channel_shift\">Schimbarea canalului</string>\n    <string name=\"max_offset\">Offset maxim</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Block Glitch</string>\n    <string name=\"block_size\">Dimensiunea blocului</string>\n    <string name=\"crt_curvature\">curbura CRT</string>\n    <string name=\"curvature\">Curbură</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">Instrumente AI</string>\n    <string name=\"ai_tools_sub\">Diverse instrumente pentru procesarea imaginilor prin modele IA, cum ar fi eliminarea artefactelor sau eliminarea zgomotului</string>\n    <string name=\"model_anime_undeint\">Compresie, linii zimțate</string>\n    <string name=\"model_broadcast\">Desene animate, compresie de difuzare</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Compresie generală, zgomot general</string>\n    <string name=\"model_wb_denoise\">Zgomot incolor de desene animate</string>\n    <string name=\"model_span_anime_pretrain\">Rapid, compresie generală, zgomot general, animație/ benzi desenate/anime</string>\n    <string name=\"model_book_scan\">Scanarea cărților</string>\n    <string name=\"model_overexposure\">Corectarea expunerii</string>\n    <string name=\"model_fbcnn_color_fp16\">Cel mai bun la compresie generală, imagini color</string>\n    <string name=\"model_fbcnn_gray_fp16\">Cel mai bun la compresie generală, imagini în tonuri de gri</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Compresie generală, imagini în tonuri de gri, mai puternice</string>\n    <string name=\"model_scunet_color_gan_fp16\">Zgomot general, imagini color</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Zgomot general, imagini color, detalii mai bune</string>\n    <string name=\"model_scunet_gray_15_fp16\">Zgomot general, imagini în tonuri de gri</string>\n    <string name=\"model_scunet_gray_25_fp16\">Zgomot general, imagini în tonuri de gri, mai puternice</string>\n    <string name=\"model_scunet_gray_50_fp16\">Zgomot general, imagini în tonuri de gri, cel mai puternic</string>\n    <string name=\"model_jpeg_destroyer\">Compresie generală</string>\n    <string name=\"model_jaywreck\">Compresie generală</string>\n    <string name=\"model_h264\">Texturizare, compresie h264</string>\n    <string name=\"model_vhs\">compresie VHS</string>\n    <string name=\"model_cinepak\">Compresie non-standard (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Compresie Bink, mai bună la geometrie</string>\n    <string name=\"model_debink_v5\">Compresie bink, mai puternică</string>\n    <string name=\"model_debink_v6\">Bink compresie, moale, păstrează detaliile</string>\n    <string name=\"model_antialias\">Eliminarea efectului de treaptă, netezirea</string>\n    <string name=\"model_kdm_scans\">Artă/desene scanate, compresie ușoară, moire</string>\n    <string name=\"model_bandage\">Bande de culoare</string>\n    <string name=\"model_halftone\">Încet, eliminând semitonurile</string>\n    <string name=\"model_colorizer\">Colorizator general pentru imagini în tonuri de gri/bw, pentru rezultate mai bune utilizați DDColor</string>\n    <string name=\"model_deedge\">Îndepărtarea marginilor</string>\n    <string name=\"model_desharpen\">Îndepărtează supra-ascuțirea</string>\n    <string name=\"model_dither\">Încet, tremurând</string>\n    <string name=\"model_gainres\">Anti-aliasing, artefacte generale, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 scanează procesarea</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Model ușor de îmbunătățire a imaginii</string>\n    <string name=\"model_bcgone_detailed_v2\">Îndepărtarea artefactelor de compresie</string>\n    <string name=\"model_bcgone_smooth\">Îndepărtarea artefactelor de compresie</string>\n    <string name=\"model_bandage_smooth\">Îndepărtarea bandajului cu rezultate netede</string>\n    <string name=\"model_bendel_halftone\">Procesare model semiton</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Eliminarea modelului de dither V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Îndepărtarea artefactelor JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Îmbunătățirea texturii H.264</string>\n    <string name=\"model_vhs_sharpen\">Ascuțire și îmbunătățire VHS</string>\n    <string name=\"merging\">Fuzionarea</string>\n    <string name=\"chunk_size\">Dimensiunea bucatilor</string>\n    <string name=\"overlap_size\">Dimensiune de suprapunere</string>\n    <string name=\"note_chunk_info\">Imaginile de peste %1$s px vor fi tăiate și procesate în bucăți, suprapunerea le combină pentru a preveni cusăturile vizibile.</string>\n    <string name=\"large_chunk_warning\">Dimensiunile mari pot cauza instabilitate cu dispozitivele low-end</string>\n    <string name=\"select_one_to_start\">Selectați unul pentru a începe</string>\n    <string name=\"delete_model_sub\">Doriți să ștergeți modelul %1$s? Va trebui să-l descărcați din nou</string>\n    <string name=\"confirm\">Confirma</string>\n    <string name=\"models\">Modele</string>\n    <string name=\"downloaded_models\">Modele descărcate</string>\n    <string name=\"available_models\">Modele disponibile</string>\n    <string name=\"preparing\">Pregătirea</string>\n    <string name=\"active_model\">Model activ</string>\n    <string name=\"failed_to_open_session\">Sesiunea nu a putut fi deschisă</string>\n    <string name=\"only_onnx_models\">Numai modelele .onnx/.ort pot fi importate</string>\n    <string name=\"import_model\">Import model</string>\n    <string name=\"import_model_sub\">Importați modelul onnx personalizat pentru utilizare ulterioară, sunt acceptate doar modelele onnx/ort, acceptă aproape toate variantele de tip esrgan</string>\n    <string name=\"imported_models\">Modele importate</string>\n    <string name=\"model_scunet_color_15_fp16\">Zgomot general, imagini colorate</string>\n    <string name=\"model_scunet_color_25_fp16\">Zgomot general, imagini colorate, mai puternice</string>\n    <string name=\"model_scunet_color_50_fp16\">Zgomot general, imagini colorate, cel mai puternic</string>\n    <string name=\"model_artifacts_dithering_alsa\">Reduce artefactele de dithering și benzile de culoare, îmbunătățind degradeurile netede și zonele de culoare plate.</string>\n    <string name=\"model_nmkd_brighten_redux\">Îmbunătățește luminozitatea și contrastul imaginii cu lumini echilibrate, păstrând în același timp culorile naturale.</string>\n    <string name=\"model_nmkd_brighten\">Iluminează imaginile întunecate, păstrând în același timp detaliile și evitând supraexpunerea.</string>\n    <string name=\"model_nmkd_detoon\">Îndepărtează tonul excesiv de culoare și restabilește un echilibru de culoare mai neutru și natural.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Aplică tonuri de zgomot bazate pe Poisson, cu accent pe păstrarea detaliilor și texturilor fine.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Aplică un ton moale de zgomot Poisson pentru rezultate vizuale mai fine și mai puțin agresive.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Tonificare uniformă a zgomotului axată pe păstrarea detaliilor și claritatea imaginii.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Tonifiere uniformă de zgomot blând pentru o textură subtilă și un aspect neted.</string>\n    <string name=\"model_repainter\">Repara zonele deteriorate sau neuniforme prin revopsirea artefactelor și îmbunătățirea consistenței imaginii.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Model ușor de debandare care elimină benzile de culoare cu costuri minime de performanță.</string>\n    <string name=\"model_jpeg_0_20\">Optimizează imaginile cu artefacte de compresie foarte ridicate (calitate 0-20%) pentru o claritate îmbunătățită.</string>\n    <string name=\"model_jpeg_20_40\">Îmbunătățește imaginile cu artefacte de compresie ridicată (20-40% calitate), restabilind detaliile și reducând zgomotul.</string>\n    <string name=\"model_jpeg_40_60\">Îmbunătățește imaginile cu compresie moderată (40-60% calitate), echilibrând claritatea și netezimea.</string>\n    <string name=\"model_jpeg_60_80\">Rafinează imaginile cu compresie ușoară (60-80% calitate) pentru a îmbunătăți detaliile și texturile subtile.</string>\n    <string name=\"model_jpeg_80_100\">Îmbunătățește ușor imaginile aproape fără pierderi (calitate 80-100%), păstrând în același timp aspectul și detaliile naturale.</string>\n    <string name=\"model_spongecolor_lite\">Colorare simpla si rapida, desene animate, nu ideala</string>\n    <string name=\"model_deblr\">Reduce ușor neclaritatea imaginii, îmbunătățind claritatea fără a introduce artefacte.</string>\n    <string name=\"processing_channel\">Operațiuni de lungă durată</string>\n    <string name=\"processing_image\">Procesarea imaginii</string>\n    <string name=\"processing\">Prelucrare</string>\n    <string name=\"model_artifacts_jpg_0_20\">Îndepărtează artefactele mari de compresie JPEG în imagini de calitate foarte scăzută (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Reduce artefactele JPEG puternice în imaginile foarte comprimate (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Curăță artefactele JPEG moderate, păstrând în același timp detaliile imaginii (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Rafinează artefactele JPEG ușoare în imagini de calitate destul de înaltă (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Reduce subtil artefactele JPEG minore în imagini aproape fără pierderi (80-100%).</string>\n    <string name=\"model_redetail_v2\">Îmbunătățește detaliile și texturile fine, îmbunătățind claritatea percepută fără artefacte grele.</string>\n    <string name=\"processing_finished\">Procesare terminată</string>\n    <string name=\"processing_failed\">Procesarea nu a reușit</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Îmbunătățește texturile și detaliile pielii, păstrând în același timp un aspect natural, optimizat pentru viteză.</string>\n    <string name=\"model_sbdv_dejpeg\">Îndepărtează artefactele de compresie JPEG și restabilește calitatea imaginii pentru fotografiile comprimate.</string>\n    <string name=\"model_iso_denoise_v1\">Reduce zgomotul ISO în fotografiile realizate în condiții de lumină scăzută, păstrând detaliile.</string>\n    <string name=\"model_dejumbo\">Corectează luminile supraexpuse sau „jumbo” și restabilește un echilibru tonal mai bun.</string>\n    <string name=\"model_ddcolor_tiny\">Model de colorare ușor și rapid care adaugă culori naturale imaginilor în tonuri de gri.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Dezgomot</string>\n    <string name=\"type_colorize\">Colorează</string>\n    <string name=\"type_artifacts\">Artefacte</string>\n    <string name=\"type_enhance\">Spori</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Scanări</string>\n    <string name=\"type_upscale\">Upscale</string>\n    <string name=\"model_realesrgan_x4v3\">Upscaler X4 pentru imagini generale; model minuscul care utilizează mai puțin GPU și timp, cu estompare moderată și dezgomot.</string>\n    <string name=\"model_realesrgan_x2plus\">Upscaler X2 pentru imagini generale, păstrând texturile și detaliile naturale.</string>\n    <string name=\"model_realesrgan_x4plus\">Upscaler X4 pentru imagini generale cu texturi îmbunătățite și rezultate realiste.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Upscaler X4 optimizat pentru imagini anime; 6 blocuri RRDB pentru linii și detalii mai clare.</string>\n    <string name=\"model_realesrnet_x4plus\">Upscaler X4 cu pierdere MSE, produce rezultate mai fine și artefacte reduse pentru imagini generale.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimizat pentru imagini anime; Varianta 4B32F cu detalii mai clare și linii netede.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Model X4 UltraSharp V2 pentru imagini generale; accentuează claritatea și claritatea.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; mai rapid și mai mic, păstrează detaliile folosind mai puțină memorie GPU.</string>\n    <string name=\"model_rmbg_1_4\">Model ușor pentru îndepărtarea rapidă a fundalului. Performanță și precizie echilibrate. Funcționează cu portrete, obiecte și scene. Recomandat pentru majoritatea cazurilor de utilizare.</string>\n    <string name=\"type_removebg\">Eliminați BG</string>\n    <string name=\"horizontal_border_thickness\">Grosimea marginii orizontale</string>\n    <string name=\"vertical_border_thickness\">Grosimea chenarului vertical</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s culoare</item>\n        <item quantity=\"few\">%1$s culori</item>\n        <item quantity=\"other\">%1$s culori</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Modelul actual nu acceptă fragmentarea, imaginea va fi procesată la dimensiunile originale, acest lucru poate cauza un consum mare de memorie și probleme cu dispozitivele low-end</string>\n    <string name=\"chunking_disabled\">Îmbunătățirea în bucăți este dezactivată, imaginea va fi procesată la dimensiunile originale, acest lucru poate cauza un consum mare de memorie și probleme cu dispozitivele de ultimă generație, dar poate oferi rezultate mai bune la inferență</string>\n    <string name=\"chunking\">Bucățire</string>\n    <string name=\"model_u2net\">Model de segmentare a imaginii de mare precizie pentru eliminarea fundalului</string>\n    <string name=\"model_u2netp\">Versiune ușoară a U2Net pentru eliminarea mai rapidă a fundalului cu o utilizare mai mică a memoriei.</string>\n    <string name=\"model_ddcolor\">Modelul complet DDColor oferă o colorare de înaltă calitate pentru imagini generale cu artefacte minime. Cea mai bună alegere dintre toate modelele de colorare.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Seturi de date artistice antrenate și private; produce rezultate de colorare diverse și artistice cu mai puține artefacte de culoare nerealiste.</string>\n    <string name=\"model_birefnet\">Model ușor BiRefNet bazat pe Swin Transformer pentru eliminarea precisă a fundalului.</string>\n    <string name=\"model_inspyrenet\">Eliminare de fundal de înaltă calitate, cu margini ascuțite și păstrare excelentă a detaliilor, în special pe obiecte complexe și fundaluri complicate.</string>\n    <string name=\"model_isnet\">Model de îndepărtare a fundalului care produce măști precise, cu margini netede, potrivite pentru obiecte generale și pentru conservarea moderată a detaliilor.</string>\n    <string name=\"model_already_downloaded\">Model deja descărcat</string>\n    <string name=\"model_successfully_imported\">Modelul a fost importat cu succes</string>\n    <string name=\"type\">Tip</string>\n    <string name=\"keyword\">Cuvânt cheie</string>\n    <string name=\"very_fast\">Foarte rapid</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Lent</string>\n    <string name=\"very_slow\">Foarte lent</string>\n    <string name=\"compute_percents\">Calculați procente</string>\n    <string name=\"minimum_value_is\">Valoarea minimă este %1$s</string>\n    <string name=\"warp_sub\">Distorsionați imaginea desenând cu degetele</string>\n    <string name=\"warp\">Urzeală</string>\n    <string name=\"hardness\">Duritate</string>\n    <string name=\"warp_mode\">Modul Warp</string>\n    <string name=\"warp_mode_move\">Mişcare</string>\n    <string name=\"warp_mode_grow\">Creste</string>\n    <string name=\"warp_mode_shrink\">Se micsoreaza</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Rotiți în sens invers</string>\n    <string name=\"fade_strength\">Fade Strength</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Scădere de jos</string>\n    <string name=\"start_drop\">Începeți Drop</string>\n    <string name=\"end_drop\">Sfârșește Drop</string>\n    <string name=\"downloading\">Descărcarea</string>\n    <string name=\"smooth_shapes\">Forme netede</string>\n    <string name=\"smooth_shapes_sub\">Folosiți superelipse în loc de dreptunghiuri rotunjite standard pentru forme mai fine și mai naturale</string>\n    <string name=\"shape_type\">Tip de formă</string>\n    <string name=\"cut\">Tăiați</string>\n    <string name=\"rounded\">rotunjite</string>\n    <string name=\"smooth\">Netezi</string>\n    <string name=\"cut_shapes_sub\">Margini ascuțite fără rotunjire</string>\n    <string name=\"rounded_shapes_sub\">Colțuri clasice rotunjite</string>\n    <string name=\"shapes_type\">Tip de forme</string>\n    <string name=\"corners_size\">Dimensiunea colțurilor</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elemente elegante de UI rotunjite</string>\n    <string name=\"filename_format\">Format nume de fișier</string>\n    <string name=\"prefix_pattern_description\">Text personalizat plasat chiar la începutul numelui fișierului, perfect pentru numele proiectelor, mărci sau etichete personale.</string>\n    <string name=\"original_filename_pattern_description\">Folosește numele fișierului original fără extensie, ajutându-vă să păstrați intactă identificarea sursei.</string>\n    <string name=\"width_pattern_description\">Lățimea imaginii în pixeli, utilă pentru urmărirea modificărilor rezoluției sau scalarea rezultatelor.</string>\n    <string name=\"height_pattern_description\">Înălțimea imaginii în pixeli, utilă atunci când lucrați cu raporturi de aspect sau exporturi.</string>\n    <string name=\"random_numbers_pattern_description\">Generează cifre aleatorii pentru a garanta nume de fișiere unice; adăugați mai multe cifre pentru mai multă siguranță împotriva duplicatelor.</string>\n    <string name=\"sequence_number_pattern_description\">Contor cu incrementare automată pentru exporturi în loturi, ideal atunci când salvați mai multe imagini într-o singură sesiune.</string>\n    <string name=\"preset_info_pattern_description\">Inserează numele presetat aplicat în numele fișierului, astfel încât să vă puteți aminti cu ușurință cum a fost procesată imaginea.</string>\n    <string name=\"scale_mode_pattern_description\">Afișează modul de scalare a imaginii utilizat în timpul procesării, ajutând la distingerea imaginilor redimensionate, decupate sau adaptate.</string>\n    <string name=\"suffix_pattern_description\">Text personalizat plasat la sfârșitul numelui fișierului, util pentru versiuni precum _v2, _edited sau _final.</string>\n    <string name=\"extension_pattern_description\">Extensia fișierului (png, jpg, webp etc.), care se potrivește automat cu formatul salvat real.</string>\n    <string name=\"formatted_timestamp_pattern_description\">O marcaj de timp personalizabil care vă permite să vă definiți propriul format după specificațiile java pentru o sortare perfectă.</string>\n    <string name=\"fling_type\">Tip Fling</string>\n    <string name=\"android_native\">Nativ Android</string>\n    <string name=\"ios_style\">Stilul iOS</string>\n    <string name=\"smooth_curve\">Curba lină</string>\n    <string name=\"quick_stop\">Oprire rapidă</string>\n    <string name=\"bouncy\">Bouncy</string>\n    <string name=\"floaty\">Plutitor</string>\n    <string name=\"snappy\">Vioi</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">Adaptiv</string>\n    <string name=\"accessibility_aware\">Conștient de accesibilitate</string>\n    <string name=\"reduced_motion\">Mișcare redusă</string>\n    <string name=\"android_native_sub\">Fizica nativă a derulării Android</string>\n    <string name=\"smooth_sub\">Defilare echilibrată, lină pentru uz general</string>\n    <string name=\"ios_style_sub\">Comportament de defilare asemănător iOS cu frecare mai mare</string>\n    <string name=\"smooth_curve_sub\">Curba spline unică pentru o senzație distinctă de defilare</string>\n    <string name=\"quick_stop_sub\">Defilare precisă cu oprire rapidă</string>\n    <string name=\"bouncy_sub\">Scroll jucăuș și receptiv</string>\n    <string name=\"floaty_sub\">Defilări lungi, glisante, pentru navigarea prin conținut</string>\n    <string name=\"snappy_sub\">Defilare rapidă și receptivă pentru interfețele de utilizare interactive</string>\n    <string name=\"ultra_smooth_sub\">Defilare lină premium cu impuls extins</string>\n    <string name=\"adaptive_sub\">Ajustează fizica pe baza vitezei de aruncare</string>\n    <string name=\"accessibility_aware_sub\">Respectă setările de accesibilitate ale sistemului</string>\n    <string name=\"reduced_motion_sub\">Mișcare minimă pentru nevoile de accesibilitate</string>\n    <string name=\"primary_lines\">Liniile primare</string>\n    <string name=\"primary_lines_sub\">Adaugă o linie mai groasă la fiecare a cincea linie</string>\n    <string name=\"fill_color\">Culoare de umplere</string>\n    <string name=\"hidden_tools\">Instrumente ascunse</string>\n    <string name=\"hidden_for_share\">Instrumente ascunse pentru distribuire</string>\n    <string name=\"color_library\">Biblioteca de culori</string>\n    <string name=\"color_library_sub\">Răsfoiți o colecție vastă de culori</string>\n    <string name=\"model_fatality_deblur\">Clarifică și elimină neclaritatea din imagini, păstrând în același timp detaliile naturale, ideal pentru remedierea fotografiilor nefocalizate.</string>\n    <string name=\"model_unresize_v3\">Restaurează inteligent imaginile care au fost redimensionate anterior, recuperând detaliile și texturile pierdute.</string>\n    <string name=\"model_liveaction_v1_span\">Optimizat pentru conținut live-action, reduce artefactele de compresie și îmbunătățește detaliile fine în cadrele filmului/emisiunii TV.</string>\n    <string name=\"model_vhs2hd_realplksr\">Convertește filmările de calitate VHS în HD, eliminând zgomotul benzii și îmbunătățind rezoluția, păstrând în același timp aspectul vintage.</string>\n    <string name=\"model_text2hd_v1\">Specializat pentru imagini și capturi de ecran cu text intens, clarifică caracterele și îmbunătățește lizibilitatea.</string>\n    <string name=\"model_frankendata_pretrainer\">Upscaling avansat instruit pe diverse seturi de date, excelent pentru îmbunătățirea fotografiilor de uz general.</string>\n    <string name=\"model_realwebphoto_v2\">Optimizat pentru fotografii comprimate pe web, elimină artefactele JPEG și restabilește aspectul natural.</string>\n    <string name=\"model_realwebphoto_v4\">Versiune îmbunătățită pentru fotografiile web, cu o mai bună conservare a texturii și reducerea artefactelor.</string>\n    <string name=\"model_dat_2x\">2x upscaling cu tehnologia Dual Aggregation Transformer, menține claritatea și detaliile naturale.</string>\n    <string name=\"model_dat_3x\">Upscaling de 3x folosind arhitectura avansată a transformatorului, ideală pentru nevoi moderate de extindere.</string>\n    <string name=\"model_dat_4x\">Upscaling de înaltă calitate de 4x cu o rețea de transformatoare de ultimă generație, păstrează detaliile fine la o scară mai mare.</string>\n    <string name=\"model_nafnet_deblurring\">Îndepărtează neclaritatea/zgomotul și tremurăturile din fotografii. Scop general, dar cel mai bine pentru fotografii.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Restaurează imagini de calitate scăzută folosind transformatorul Swin2SR, optimizat pentru degradarea BSRGAN. Excelent pentru repararea artefactelor de compresie grele și îmbunătățirea detaliilor la scară de 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Upscaling de 4x cu transformator SwinIR instruit pe degradarea BSRGAN. Utilizează GAN pentru texturi mai clare și detalii mai naturale în fotografii și scene complexe.</string>\n    <string name=\"path\">Cale</string>\n    <string name=\"merge_pdf\">Îmbinați PDF</string>\n    <string name=\"merge_pdf_sub\">Combinați mai multe fișiere PDF într-un singur document</string>\n    <string name=\"files_order\">Ordinea fișierelor</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Divizarea PDF-ului</string>\n    <string name=\"split_pdf_sub\">Extrage anumite pagini din documentul PDF</string>\n    <string name=\"rotate_pdf\">Rotiți PDF</string>\n    <string name=\"rotate_pdf_sub\">Remediați permanent orientarea paginii</string>\n    <string name=\"pages\">Pagini</string>\n    <string name=\"rearrange_pdf\">Rearanjați PDF</string>\n    <string name=\"rearrange_pdf_sub\">Trageți și plasați paginile pentru a le reordona</string>\n    <string name=\"hold_drag_drop\">Țineți apăsat și trageți paginile</string>\n    <string name=\"page_numbers\">Numerele paginilor</string>\n    <string name=\"page_numbers_sub\">Adăugați automat numerotarea documentelor dvs</string>\n    <string name=\"label_format\">Format etichetă</string>\n    <string name=\"pdf_to_text\">PDF în text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extrageți text simplu din documentele dumneavoastră PDF</string>\n    <string name=\"watermark_pdf_sub\">Suprapuneți text personalizat pentru branding sau securitate</string>\n    <string name=\"signature\">Semnătura</string>\n    <string name=\"signature_sub\">Adaugă semnătura ta electronică la orice document</string>\n    <string name=\"will_be_for_signature\">Acesta va fi folosit ca semnătură</string>\n    <string name=\"unlock_pdf\">Deblocați PDF</string>\n    <string name=\"unlock_pdf_sub\">Eliminați parolele din fișierele dvs. protejate</string>\n    <string name=\"protect_pdf\">Protejați PDF</string>\n    <string name=\"protect_pdf_sub\">Asigurați-vă documentele cu criptare puternică</string>\n    <string name=\"success\">Succes</string>\n    <string name=\"pdf_unlocked\">PDF deblocat, îl puteți salva sau partaja</string>\n    <string name=\"repair_pdf\">Repara PDF</string>\n    <string name=\"repair_pdf_sub\">Încercați să remediați documentele corupte sau ilizibile</string>\n    <string name=\"grayscale\">Tonuri de gri</string>\n    <string name=\"grayscale_pdf_sub\">Convertiți toate imaginile încorporate în document în tonuri de gri</string>\n    <string name=\"compress_pdf\">Comprimați PDF</string>\n    <string name=\"compress_pdf_sub\">Optimizați dimensiunea fișierului documentului pentru o partajare mai ușoară</string>\n    <string name=\"repair_info\">ImageToolbox reconstruiește tabelul intern de referințe încrucișate și regenerează structura fișierului de la zero. Acest lucru poate restabili accesul la multe fișiere care „nu pot fi deschise”</string>\n    <string name=\"grayscale_info\">Acest instrument convertește toate imaginile documentului în tonuri de gri. Cel mai bun pentru tipărirea și reducerea dimensiunii fișierului</string>\n    <string name=\"metadata\">Metadate</string>\n    <string name=\"metadata_pdf_sub\">Editați proprietățile documentului pentru o confidențialitate mai bună</string>\n    <string name=\"tags\">Etichete</string>\n    <string name=\"producer\">Producător</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Cuvinte cheie</string>\n    <string name=\"creator\">Creator</string>\n    <string name=\"privacy_deep_clean\">Confidențialitate Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Ștergeți toate metadatele disponibile pentru acest document</string>\n    <string name=\"page\">Pagină</string>\n    <string name=\"deep_ocr\">OCR profund</string>\n    <string name=\"deep_ocr_sub\">Extrageți textul din document și stocați-l într-un singur fișier text folosind motorul Tesseract</string>\n    <string name=\"cant_remove_all\">Nu se pot elimina toate paginile</string>\n    <string name=\"remove_pages_pdf\">Eliminați paginile PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Eliminați anumite pagini din documentul PDF</string>\n    <string name=\"tap_to_remove\">Atinge Pentru a elimina</string>\n    <string name=\"manually\">Manual</string>\n    <string name=\"crop_pdf\">Decupați PDF</string>\n    <string name=\"crop_pdf_sub\">Decupați paginile documentului la orice limite</string>\n    <string name=\"flatten_pdf\">Aplatizați PDF</string>\n    <string name=\"flatten_pdf_sub\">Faceți PDF nemodificabil prin rasterizarea paginilor documentului</string>\n    <string name=\"camera_failed_to_open\">Camera nu a putut porni. Verificați permisiunile și asigurați-vă că nu este folosit de altă aplicație.</string>\n    <string name=\"extract_images\">Extrage imagini</string>\n    <string name=\"extract_images_sub\">Extrageți imagini încorporate în PDF-uri la rezoluția lor originală</string>\n    <string name=\"pdf_no_embedded\">Acest fișier PDF nu conține nicio imagine încorporată</string>\n    <string name=\"extract_images_info\">Acest instrument scanează fiecare pagină și recuperează imagini sursă de calitate completă - perfect pentru salvarea originalelor din documente</string>\n    <string name=\"draw_signature\">Desenați Semnătura</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">Utilizați propria semnătură ca imagine pentru a fi plasată pe documente</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Împărțiți documentul cu un interval dat și împachetați documente noi în arhiva zip</string>\n    <string name=\"interval\">Interval</string>\n    <string name=\"print_pdf\">Imprimați PDF</string>\n    <string name=\"print_pdf_sub\">Pregătiți documentul pentru imprimare cu dimensiunea paginii personalizată</string>\n    <string name=\"pages_per_sheet\">Pagini pe foaie</string>\n    <string name=\"orientation\">Orientare</string>\n    <string name=\"page_size\">Dimensiunea paginii</string>\n    <string name=\"margin\">Marja</string>\n    <string name=\"bloom\">Floare</string>\n    <string name=\"soft_knee\">Genunchi moale</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimizat pentru anime și desene animate. Upscaling rapid cu culori naturale îmbunătățite și mai puține artefacte</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 ca stil</string>\n    <string name=\"calculate_hint\">Introduceți aici simbolurile matematice de bază pentru a calcula valoarea dorită (de ex. (5+5)*10)</string>\n    <string name=\"math_expression\">Expresia matematică</string>\n    <string name=\"pick_up_to_n_collage_images\">Preluați până la %1$s imagini</string>\n    <string name=\"keep_date_time\">Păstrați data și ora</string>\n    <string name=\"keep_date_time_sub\">Păstrați întotdeauna etichetele exif legate de dată și oră, funcționează independent de opțiunea de păstrare exif</string>\n    <string name=\"background_color_for_alpha_formats\">Culoare de fundal pentru formatele Alpha</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Adaugă capacitatea de a seta culoarea de fundal pentru fiecare format de imagine cu suport alfa, când este dezactivat, acesta este disponibil numai pentru cele non alfa</string>\n    <string name=\"open_markup_project\">Proiect deschis</string>\n    <string name=\"open_markup_project_sub\">Continuați editarea unui proiect Image Toolbox salvat anterior</string>\n    <string name=\"markup_project_open_failed\">Imposibil de deschis proiectul Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Din proiectul Image Toolbox lipsesc date de proiect</string>\n    <string name=\"markup_project_corrupted\">Proiectul Image Toolbox este corupt</string>\n    <string name=\"unsupported_markup_project_version\">Versiunea proiectului Image Toolbox neacceptată: %1$d</string>\n    <string name=\"save_markup_project\">Salvați proiectul</string>\n    <string name=\"save_markup_project_sub\">Stocați straturi, fundal și editează istoricul într-un fișier de proiect editabil</string>\n    <string name=\"failed_to_open\">Deschiderea eșuată</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Scrieți într-un PDF care poate fi căutat</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Recunoașteți textul din lotul de imagini și salvați PDF care poate fi căutat cu imagine și strat de text selectabil</string>\n    <string name=\"layer_alpha\">Stratul alfa</string>\n    <string name=\"horizontal_flip\">Flip orizontal</string>\n    <string name=\"vertical_flip\">Flip vertical</string>\n    <string name=\"lock\">Blocare</string>\n    <string name=\"add_shadow\">Adaugă Shadow</string>\n    <string name=\"shadow_color\">Culoare umbră</string>\n    <string name=\"text_geometry\">Geometria textului</string>\n    <string name=\"text_geometry_sub\">Întindeți sau înclinați textul pentru o stilizare mai clară</string>\n    <string name=\"scale_x\">Scara X</string>\n    <string name=\"skew_x\">Înclinați X</string>\n    <string name=\"remove_annotations\">Eliminați adnotările</string>\n    <string name=\"remove_annotations_sub\">Eliminați tipurile de adnotări selectate, cum ar fi linkuri, comentarii, evidențieri, forme sau câmpuri de formular din paginile PDF</string>\n    <string name=\"annotation_link\">Hiperlinkuri</string>\n    <string name=\"annotation_file_attachment\">Fișiere atașate</string>\n    <string name=\"annotation_line\">Linii</string>\n    <string name=\"annotation_popup\">Ferestre pop-up</string>\n    <string name=\"annotation_stamp\">Timbre</string>\n    <string name=\"annotation_shapes\">Forme</string>\n    <string name=\"annotation_text\">Note de text</string>\n    <string name=\"annotation_text_markup\">Marcare text</string>\n    <string name=\"annotation_widget\">Câmpuri de formular</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">Necunoscut</string>\n    <string name=\"annotations\">Adnotări</string>\n    <string name=\"ungroup\">Degrupați</string>\n    <string name=\"add_shadow_sub\">Adăugați umbră încețoșată în spatele stratului cu culori și decalaje configurabile</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ru/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"smth_went_wrong\">Что-то пошло не так: %1$s</string>\n    <string name=\"size\">Размер %1$s</string>\n    <string name=\"loading\">Загрузка…</string>\n    <string name=\"image_too_large_preview\">Изображение слишком большое для предпросмотра, но мы постараемся сохранить его в любом случае</string>\n    <string name=\"pick_image\">Выберите изображение, чтобы начать</string>\n    <string name=\"width\">Ширина %1$s</string>\n    <string name=\"height\">Высота %1$s</string>\n    <string name=\"quality\">Качество</string>\n    <string name=\"extension\">Расширение</string>\n    <string name=\"resize_type\">Тип изменения</string>\n    <string name=\"explicit\">Строгий</string>\n    <string name=\"flexible\">Гибкий</string>\n    <string name=\"pick_image_alt\">Выбрать изображение</string>\n    <string name=\"app_closing_sub\">Вы действительно хотите закрыть приложение?</string>\n    <string name=\"app_closing\">Закрытие приложения</string>\n    <string name=\"stay\">Остаться</string>\n    <string name=\"close\">Закрыть</string>\n    <string name=\"reset_image\">Сбросить изображение</string>\n    <string name=\"reset_image_sub\">Все изменения будут отменены, а вы увидите исходное изображение</string>\n    <string name=\"values_reset\">Значения успешно сброшены</string>\n    <string name=\"reset\">Сброс</string>\n    <string name=\"something_went_wrong\">Что-то пошло не так</string>\n    <string name=\"restart_app\">Перезапустить приложение</string>\n    <string name=\"copied\">Скопировано в буфер обмена</string>\n    <string name=\"exception\">Исключение</string>\n    <string name=\"edit_exif\">Ред. EXIF</string>\n    <string name=\"ok\">Ок</string>\n    <string name=\"no_exif\">EXIF информация не найдена</string>\n    <string name=\"add_tag\">Добавить тег</string>\n    <string name=\"save\">Сохранить</string>\n    <string name=\"clear\">Очистить</string>\n    <string name=\"clear_exif\">Очистить EXIF</string>\n    <string name=\"cancel\">Отмена</string>\n    <string name=\"clear_exif_sub\">Все данные EXIF будут удалены, это действие нельзя отменить!</string>\n    <string name=\"presets\">Предустановки</string>\n    <string name=\"crop\">Обрезать</string>\n    <string name=\"image_not_saved\">Сохранение</string>\n    <string name=\"image_not_saved_sub\">Все несохраненные изменения будут отменены, если вы выйдете сейчас</string>\n    <string name=\"check_source_code\">Иcходный код</string>\n    <string name=\"check_source_code_sub\">Получайте последние обновления и следите за проектом</string>\n    <string name=\"single_edit\">Одиночное изменение</string>\n    <string name=\"single_edit_sub\">Изменение характеристик одного изображения</string>\n    <string name=\"pick_color\">Выбрать цвет</string>\n    <string name=\"pick_color_sub\">Воспользуйтесь пипеткой и получите цветовой код необходимого фрагмента изображения</string>\n    <string name=\"image\">Изображение</string>\n    <string name=\"color\">Цвет</string>\n    <string name=\"color_copied\">Цвет скопирован</string>\n    <string name=\"crop_sub\">Обрежьте изображение до произвольных границ</string>\n    <string name=\"version\">Версия</string>\n    <string name=\"keep_exif\">Сохранить EXIF</string>\n    <string name=\"images\">Изображения: %d</string>\n    <string name=\"change_preview\">Изменить превью</string>\n    <string name=\"remove\">Убрать</string>\n    <string name=\"palette_sub\">Создать образец цветовой палитры по данному изображению</string>\n    <string name=\"generate_palette\">Сгенерировать палитру</string>\n    <string name=\"palette\">Палитра</string>\n    <string name=\"new_version\">Обновление %1$s</string>\n    <string name=\"update\">Обновить</string>\n    <string name=\"unsupported_type\">Неподдерживаемый тип: %1$s</string>\n    <string name=\"no_palette\">Для данного изображения не удалось сгенерировать палитру</string>\n    <string name=\"original\">Оригинал</string>\n    <string name=\"folder\">Путь сохранения</string>\n    <string name=\"def\">По умолчанию</string>\n    <string name=\"custom\">Произвольный</string>\n    <string name=\"unspecified\">Не задан</string>\n    <string name=\"device_storage\">Память устройства</string>\n    <string name=\"by_bytes_resize\">Сжатие по весу</string>\n    <string name=\"max_bytes\">Максимальный вес в КБ</string>\n    <string name=\"by_bytes_resize_sub\">Сожмите изображение, чтобы оно занимало не более заданного количества КБ</string>\n    <string name=\"compare\">Сравнить</string>\n    <string name=\"compare_sub\">Сравните два заданных изображения</string>\n    <string name=\"pick_two_images\">Выберите два изображения, чтобы начать</string>\n    <string name=\"pick_images\">Выбрать изображения</string>\n    <string name=\"settings\">Настройки</string>\n    <string name=\"night_mode\">Ночной режим</string>\n    <string name=\"dark\">Тёмный</string>\n    <string name=\"light\">Светлый</string>\n    <string name=\"system\">Как в системе</string>\n    <string name=\"dynamic_colors\">Динамические цвета</string>\n    <string name=\"customization\">Кастомизация</string>\n    <string name=\"allow_image_monet\">Включить Monet</string>\n    <string name=\"allow_image_monet_sub\">Если включён, то цвета приложения будут подстраиваться под выбранное изображение в режиме редактирования</string>\n    <string name=\"language\">Язык</string>\n    <string name=\"amoled_mode\">Amoled режим</string>\n    <string name=\"amoled_mode_sub\">Если включено, то цвет поверхностей будет установлен на абсолютно тёмный в ночном режиме</string>\n    <string name=\"color_scheme\">Цветовая палитра</string>\n    <string name=\"color_red\">Красный</string>\n    <string name=\"color_green\">Зеленый</string>\n    <string name=\"color_blue\">Синий</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Вставьте правильный aRGB-код</string>\n    <string name=\"clipboard_paste_invalid_empty\">Нечего вставлять</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Невозможно изменить цвет приложения, если включены динамические цвета</string>\n    <string name=\"pick_accent_color\">Тема приложения будет основана на выбранном цвете</string>\n    <string name=\"about_app\">О приложении</string>\n    <string name=\"no_updates\">Обновлений не найдено</string>\n    <string name=\"issue_tracker\">Трекер ошибок</string>\n    <string name=\"issue_tracker_sub\">Отправляйте отчёты об ошибках и предлагайте новые идеи для развития проекта</string>\n    <string name=\"help_translate\">Помочь с переводом</string>\n    <string name=\"help_translate_sub\">Исправляйте ошибки в написании слов или переводите проект на новые языки</string>\n    <string name=\"nothing_found_by_search\">Ничего не найдено по вашему запросу</string>\n    <string name=\"search_here\">Ищите здесь</string>\n    <string name=\"dynamic_colors_sub\">При включении тема приложения будет подстраиваться под ваши обои</string>\n    <string name=\"failed_to_save\">Не удалось сохранить %d изображение(я)</string>\n    <string name=\"primary\">Первичный</string>\n    <string name=\"tertiary\">Третичный</string>\n    <string name=\"secondary\">Вторичный</string>\n    <string name=\"border_thickness\">Толщина окантовки</string>\n    <string name=\"surface\">Поверхность</string>\n    <string name=\"values\">Значения</string>\n    <string name=\"add\">Добавить</string>\n    <string name=\"permission\">Разрешение</string>\n    <string name=\"grant\">Одобрить</string>\n    <string name=\"permission_sub\">Приложению необходим доступ к памяти вашего телефона, чтобы сохранять изображения, пожалуйста, для продолжения работы разрешите доступ в появшемся окне</string>\n    <string name=\"grant_permission_manual\">Приложению необходимо это разрешение для работы, предоставьте его вручную</string>\n    <string name=\"external_storage\">Внешний накопитель</string>\n    <string name=\"monet_colors\">Динамические цвета</string>\n    <string name=\"donation_sub\">Это приложение полностью бесплатное, однако если вы хотите поддержать его разработку, вы можете нажать здесь</string>\n    <string name=\"fab_alignment\">Расположение кнопки</string>\n    <string name=\"check_updates\">Проверка обновлений</string>\n    <string name=\"check_updates_sub\">Если включено, при запуске вы увидите диалог, если будет доступна новая версия приложения</string>\n    <string name=\"zoom\">Приближение</string>\n    <string name=\"share\">Поделиться</string>\n    <string name=\"prefix\">Префикс</string>\n    <string name=\"filename\">Название файла</string>\n    <string name=\"emoji\">Эмодзи</string>\n    <string name=\"emoji_sub\">Выберите, какие эмодзи отображать на главном экране</string>\n    <string name=\"add_file_size\">Добавить размер файла</string>\n    <string name=\"add_file_size_sub\">Если включено, то при сохранении к названию файла будут добавлены ширина и высота изображения</string>\n    <string name=\"delete_exif\">Удаление EXIF</string>\n    <string name=\"delete_exif_sub\">Удалить метаданные EXIF из любого набора изображений</string>\n    <string name=\"image_preview\">Предпросмотр</string>\n    <string name=\"image_preview_sub\">Предварительный просмотр изображений любого типа: GIF, SVG и так далее</string>\n    <string name=\"image_source\">Источник изображений</string>\n    <string name=\"photo_picker\">Фото пикер</string>\n    <string name=\"gallery_picker\">Галерея</string>\n    <string name=\"file_explorer_picker\">Проводник</string>\n    <string name=\"photo_picker_sub\">Современный пикер фотографий Android, который появляется в нижней части экрана, может работать только на Android 12+. Имеет проблемы с получением метаданных EXIF</string>\n    <string name=\"gallery_picker_sub\">Простой пикер изображений из галереи, будет работать только если такое приложение установлено</string>\n    <string name=\"file_explorer_picker_sub\">Использует метод GetContent для получения изображений. Может не работать. Это не моя вина</string>\n    <string name=\"options_arrangement\">Расположение опций</string>\n    <string name=\"edit\">Изменить</string>\n    <string name=\"order\">Порядок</string>\n    <string name=\"order_sub\">Определяет порядок инструментов на главном экране</string>\n    <string name=\"emojis_count\">Количество эмодзи</string>\n    <string name=\"sequence_num\">sequenceNum</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"add_original_filename\">Добавить оригинальное имя файла</string>\n    <string name=\"add_original_filename_sub\">Если включено, добавляет имя исходного файла в имя выходного изображения</string>\n    <string name=\"replace_sequence_number\">Добавить порядковый номер</string>\n    <string name=\"replace_sequence_number_sub\">Если включено, заменяет стандартную метку времени на порядковый номер изображения, если используется пакетная обработка</string>\n    <string name=\"filename_not_work_with_photopicker\">Добавление оригинального имени файла не работает, если выбран источник изображения photopicker</string>\n    <string name=\"no_image\">Нет изображения</string>\n    <string name=\"load_image_from_net\">Загрузить из интернета</string>\n    <string name=\"load_image_from_net_sub\">Загрузите любое изображение из Интернета, чтобы просмотреть, масштабировать, отредактировать и сохранить его, если хотите</string>\n    <string name=\"image_link\">Ссылка на изображение</string>\n    <string name=\"fill\">Заполнить</string>\n    <string name=\"fit\">Вписать</string>\n    <string name=\"content_scale\">Масштаб контента</string>\n    <string name=\"explicit_description\">Принудительно превращает каждую картинку в изображение, заданное параметрами ширины и высоты - может изменить соотношение сторон</string>\n    <string name=\"flexible_description\">Изменяет размер картинок до изображений с длинной стороной, заданной параметром ширины - сохраняет соотношения сторон</string>\n    <string name=\"brightness\">Яркость</string>\n    <string name=\"contrast\">Контраст</string>\n    <string name=\"hue\">Оттенок</string>\n    <string name=\"filter\">Фильтр</string>\n    <string name=\"sharpen\">Резкость</string>\n    <string name=\"sepia\">Сепия</string>\n    <string name=\"solarize\">Соляризация</string>\n    <string name=\"black_and_white\">Ч/Б</string>\n    <string name=\"blur\">Размытие</string>\n    <string name=\"halftone\">Полутон</string>\n    <string name=\"gamma\">Гамма</string>\n    <string name=\"saturation\">Насыщенность</string>\n    <string name=\"shadows\">Тени</string>\n    <string name=\"light_aka_illumination\">Свет</string>\n    <string name=\"white_balance\">Баланс белого</string>\n    <string name=\"temperature\">Температура</string>\n    <string name=\"highlights\">Светлые</string>\n    <string name=\"add_filter\">Добавить фильтр</string>\n    <string name=\"filter_sub\">Примените любую цепочку фильтров к заданным изображениям</string>\n    <string name=\"exposure\">Экспозиция</string>\n    <string name=\"tint\">Оттенок</string>\n    <string name=\"filters\">Фильтры</string>\n    <string name=\"color_filter\">Цветофильтр</string>\n    <string name=\"alpha\">Альфа</string>\n    <string name=\"monochrome\">Монохром</string>\n    <string name=\"highlights_shadows\">Блики и тени</string>\n    <string name=\"haze\">Туман</string>\n    <string name=\"distance\">Расстояние</string>\n    <string name=\"effect\">Эффект</string>\n    <string name=\"slope\">Наклон</string>\n    <string name=\"spacing\">Интервал</string>\n    <string name=\"negative\">Негатив</string>\n    <string name=\"vibrance\">Вибранс</string>\n    <string name=\"crosshatch\">Штриховка</string>\n    <string name=\"line_width\">Ширина линии</string>\n    <string name=\"sobel_edge\">Кромка Собеля</string>\n    <string name=\"bilaterial_blur\">Двухстороннее размытие</string>\n    <string name=\"laplacian\">Лапласа</string>\n    <string name=\"cga_colorspace\">Цветовое пространство CGA</string>\n    <string name=\"emboss\">Эмбосс</string>\n    <string name=\"vignette\">Виньетка</string>\n    <string name=\"gaussian_blur\">Размытие по Гауссу</string>\n    <string name=\"box_blur\">Размытие прямоугольника</string>\n    <string name=\"start\">Начало</string>\n    <string name=\"end\">Конец</string>\n    <string name=\"stack_blur\">Размытие Стэком</string>\n    <string name=\"scale\">Увеличение</string>\n    <string name=\"radius\">Радиус</string>\n    <string name=\"distortion\">Искажение</string>\n    <string name=\"swirl\">Водоворот</string>\n    <string name=\"kuwahara\">Сглаживание Кувахары</string>\n    <string name=\"angle\">Угол</string>\n    <string name=\"dilation\">Дилация</string>\n    <string name=\"refractive_index\">Показатель преломления</string>\n    <string name=\"color_matrix\">Цветовая матрица</string>\n    <string name=\"bulge\">Выпуклость</string>\n    <string name=\"sphere_refraction\">Сферическое преломление</string>\n    <string name=\"glass_sphere_refraction\">Преломление стеклянной сферы</string>\n    <string name=\"opacity\">Непрозрачность</string>\n    <string name=\"limits_resize_sub\">Измените размер выбранных изображений, чтобы они соответствовали заданным ограничениям по ширине и высоте, сохраняя при этом соотношение сторон</string>\n    <string name=\"limits_resize\">Ограничение размера</string>\n    <string name=\"quantizationLevels\">Количественный уровень</string>\n    <string name=\"posterize\">Постеризация</string>\n    <string name=\"sketch\">Эскиз (Рисунок)</string>\n    <string name=\"smooth_toon\">Гладкий мультяшный</string>\n    <string name=\"threshold\">Порог</string>\n    <string name=\"toon\">Мультяшный</string>\n    <string name=\"non_maximum_suppression\">Немаксимальное подавление</string>\n    <string name=\"lookup\">Поиск</string>\n    <string name=\"weak_pixel_inclusion\">Слабое включение пикселей</string>\n    <string name=\"zoom_blur\">Размытие приближением</string>\n    <string name=\"color_balance\">Цветовой баланс</string>\n    <string name=\"luminance_threshold\">Порог свечения</string>\n    <string name=\"convolution3x3\">Конволюция 3x3</string>\n    <string name=\"fast_blur\">Быстрое размытие</string>\n    <string name=\"false_color\">Ложный цвет</string>\n    <string name=\"blur_center_x\">Центр размытия x</string>\n    <string name=\"blur_center_y\">Центр размытия y</string>\n    <string name=\"rgb_filter\">RGB-фильтр</string>\n    <string name=\"first_color\">Первый цвет</string>\n    <string name=\"second_color\">Второй цвет</string>\n    <string name=\"reorder\">Порядок</string>\n    <string name=\"blur_size\">Размер размытия</string>\n    <string name=\"activate_files\">Вы отключили приложение «Файлы». Активируйте его, чтобы использовать эту функцию</string>\n    <string name=\"draw\">Рисование</string>\n    <string name=\"draw_sub\">Рисуйте на изображении, как в альбоме или на выбранном фоне</string>\n    <string name=\"paint_color\">Цвет кисти</string>\n    <string name=\"paint_alpha\">Прозрачность кисти</string>\n    <string name=\"draw_on_image\">Рисовать на изображении</string>\n    <string name=\"draw_on_image_sub\">Выберите изображение и нарисуйте на нем что-нибудь</string>\n    <string name=\"draw_on_background\">Рисовать на фоне</string>\n    <string name=\"draw_on_background_sub\">Выберите цвет фона и рисуйте поверх него</string>\n    <string name=\"background_color\">Фоновый цвет</string>\n    <string name=\"pick_file\">Выбрать файл</string>\n    <string name=\"decryption\">Расшифровка</string>\n    <string name=\"encryption\">Шифровка</string>\n    <string name=\"key\">Ключ</string>\n    <string name=\"compatibility\">Совместимость</string>\n    <string name=\"cipher\">Шифр</string>\n    <string name=\"cipher_sub\">Зашифруйте и расшифруйте любой файл (не только изображение) на основе различных криптоалгоритмов</string>\n    <string name=\"encrypt\">Зашифровать</string>\n    <string name=\"decrypt\">Расшифровать</string>\n    <string name=\"pick_file_to_start\">Выберите файл, чтобы начать</string>\n    <string name=\"file_proceed\">Файл готов</string>\n    <string name=\"features\">Функции</string>\n    <string name=\"implementation\">Реализация</string>\n    <string name=\"features_sub\">Шифрование файлов на основе пароля. Полученные файлы могут храниться в выбранном каталоге. Расшифрованные файлы также могут быть открыты напрямую</string>\n    <string name=\"implementation_sub\">AES-256, режим GCM, без заполнения, 12 байт случайных IV. (По умолчанию, но вы можете выбрать необходимый алгоритм) Ключи используются в виде хэшей SHA-3 (256 бит)</string>\n    <string name=\"file_size\">Размер файла</string>\n    <string name=\"file_size_sub\">Максимальный размер файла ограничен ОС Android и доступной памятью, которая зависит от устройства. \\nОбратите внимание: память - не внутреннее хранилище</string>\n    <string name=\"compatibility_sub\">Обратите внимание, что совместимость с другим программным обеспечением или службами для шифрования файлов не гарантируется. Немного другая обработка ключа или конфигурация шифра могут быть причинами несовместимости</string>\n    <string name=\"store_file_desc\">Сохраните этот файл на своем устройстве или используйте действие «Поделиться», чтобы поместить его куда угодно</string>\n    <string name=\"found_s\">Найдено %1$s</string>\n    <string name=\"invalid_password_or_not_encrypted\">Неверный пароль или выбранный файл не зашифрован</string>\n    <string name=\"tools\">Инструменты</string>\n    <string name=\"group_options_by_type\">Сгруппировать опции по типу</string>\n    <string name=\"group_options_by_type_sub\">Группирует параметры на главном экране в соответствии с их типом вместо произвольного расположения списка</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Невозможно изменить расположение, пока включена группировка параметров</string>\n    <string name=\"image_size_warning\">Попытка сохранить изображение с заданной шириной и высотой может вызвать ошибку OOM, делайте это на свой страх и риск</string>\n    <string name=\"auto_cache_clearing\">Автоматическая очистка кэша</string>\n    <string name=\"cache\">Кэш</string>\n    <string name=\"cache_size\">Размер кэша</string>\n    <string name=\"auto_cache_clearing_sub\">Если включено, кэш приложения будет очищаться при запуске приложения</string>\n    <string name=\"create\">Создать</string>\n    <string name=\"edit_screenshot\">Редактировать скриншот</string>\n    <string name=\"secondary_customization\">Вторичная кастомизация</string>\n    <string name=\"screenshot\">Скриншот</string>\n    <string name=\"copy\">Копировать</string>\n    <string name=\"fallback_option\">Запасной вариант</string>\n    <string name=\"skip\">Пропуск</string>\n    <string name=\"warning_bytes\">Сохранение в режиме %1$s может быть нестабильным, потому что это формат без потерь</string>\n    <string name=\"tg_chat_sub\">Обсуждайте приложение и получайте отзывы от других пользователей. Здесь вы также можете получить бета-обновления и дополнительную информацию</string>\n    <string name=\"presets_sub\" formatted=\"false\">Если вы выбрали предустановку 125, изображение будет сохранено в размере 125% от исходного изображения. Если вы выберете предустановку 50, изображение будет сохранено с размером 50%</string>\n    <string name=\"presets_sub_bytes\">Предустановка здесь определяет % выходного файла, т.е. если вы выберете предустановку 50 на изображении размером 5 МБ, то после сохранения вы получите изображение размером 2,5 МБ</string>\n    <string name=\"randomize_filename\">Случайное имя файла</string>\n    <string name=\"randomize_filename_sub\">Если включено, имя выходного файла будет полностью случайным</string>\n    <string name=\"saved_to\">Сохранено в папку %1$s под именем %2$s</string>\n    <string name=\"saved_to_without_filename\">Сохранено в папку %1$s</string>\n    <string name=\"tg_chat\">Чат в телеграме</string>\n    <string name=\"aspect_ratio\">Соотношение сторон</string>\n    <string name=\"backup_and_restore\">Бэкап и восстановление</string>\n    <string name=\"backup\">Бэкап</string>\n    <string name=\"backup_sub\">Сохраните ваши настройки в файл</string>\n    <string name=\"restore_sub\">Восстановите настройки приложения из ранее сохраненного файла бэкапа</string>\n    <string name=\"settings_restored\">Настройки успешно восстановлены</string>\n    <string name=\"crop_mask\">Маска обрезки</string>\n    <string name=\"image_crop_mask_sub\">Используйте эту опцию, для создания маски из выбранного изображения, обратите внимание, что оно ДОЛЖНО иметь канал прозрачности</string>\n    <string name=\"restore\">Восстановление</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Повреждённый файл или не является файлом восстановления</string>\n    <string name=\"contact_me\">Связаться со мной</string>\n    <string name=\"reset_settings_sub\">Это вернёт ваши настройки к значениям по умолчанию. Обратите внимание, что это действие невозможно отменить без упомянутого выше файла резервной копии</string>\n    <string name=\"delete\">Удалить</string>\n    <string name=\"delete_color_scheme_warn\">Вы хотите удалить выбранную цветовую схему. Это действие невозможно отменить</string>\n    <string name=\"delete_color_scheme_title\">Удалить схему</string>\n    <string name=\"font\">Шрифт</string>\n    <string name=\"defaultt\">По умолчанию</string>\n    <string name=\"text\">Текст</string>\n    <string name=\"font_scale\">Масштаб шрифта</string>\n    <string name=\"using_large_fonts_warn\">Использование шрифтов большого размера может привести к проблемам с интерфейсом</string>\n    <string name=\"alphabet_and_numbers\">Аа Бб Вв Гг Дд Её Жж Зз Ии́ Кк Лл Мм Нн Оо Пп Рр Сс Тт Уу Фф Хх Цц Чч Шщ Ъь Ыы Ээ Юю Яя 0123456789 !?</string>\n    <string name=\"emotions\">Эмоции</string>\n    <string name=\"objects\">Объекты</string>\n    <string name=\"symbols\">Символы</string>\n    <string name=\"travels_and_places\">Путешествия и места</string>\n    <string name=\"background_remover_sub\">Удалите фон изображения, стерев лишние участки или используя опцию «Авто»</string>\n    <string name=\"keep_exif_sub\">Метаданные исходного изображения будут сохранены</string>\n    <string name=\"trim_image_sub\">Прозрачное пространство вокруг изображения будет обрезано</string>\n    <string name=\"food_and_drink\">Еда и напитки</string>\n    <string name=\"nature_and_animals\">Природа и животные</string>\n    <string name=\"enable_emoji\">Включить эмодзи</string>\n    <string name=\"activities\">Активности</string>\n    <string name=\"trim_image\">Обрезать изображение</string>\n    <string name=\"background_remover\">Удаление фона</string>\n    <string name=\"restore_image\">Восстановить изображение</string>\n    <string name=\"erase_mode\">Режим стирания</string>\n    <string name=\"erase_background\">Стирание фона</string>\n    <string name=\"restore_background\">Восстановление фона</string>\n    <string name=\"blur_radius\">Радиус размытия</string>\n    <string name=\"auto_erase_background\">Автоматическое удаление фона</string>\n    <string name=\"pipette\">Пипетка</string>\n    <string name=\"draw_mode\">Режим рисования</string>\n    <string name=\"create_issue\">Создать задачу</string>\n    <string name=\"something_went_wrong_emphasis\">Ой… Что-то пошло не так. Напишите мне, используя приведённые ниже варианты, и я постараюсь найти решение</string>\n    <string name=\"resize_and_convert_sub\">Измените размер заданных изображений или конвертируйте их в другие форматы. Метаданные EXIF также можно редактировать здесь, если вы выбираете одно изображение</string>\n    <string name=\"resize_and_convert\">Изменение размера и конвертация</string>\n    <string name=\"max_colors_count\">Максимальное количество цветов</string>\n    <string name=\"analytics\">Аналитика</string>\n    <string name=\"crashlytics_sub\">Это позволяет приложению собирать отчеты об ошибках автоматически</string>\n    <string name=\"analytics_sub\">Разрешите собирать анонимную статистику использования приложения</string>\n    <string name=\"image_exif_warning\">В настоящее время формат %1$s на Android позволяет только читать метаданные EXIF. При сохранении выходное изображение вообще не будет иметь метаданных</string>\n    <string name=\"updates\">Обновления</string>\n    <string name=\"wait\">Подождите</string>\n    <string name=\"effort_sub\">Значение %1$s означает быстрое сжатие, приводящее к относительно большому размеру файла. %2$s означает более медленное сжатие, в результате чего файл становится меньше</string>\n    <string name=\"allow_betas\">Разрешить обновления до бета-версий</string>\n    <string name=\"saving_almost_complete\">Сохранение почти завершено. Отмена сейчас потребует повторного сохранения</string>\n    <string name=\"effort\">Усилие</string>\n    <string name=\"allow_betas_sub\">Проверка обновлений будет включать бета-версии приложения, если она включена</string>\n    <string name=\"brush_softness\">Мягкость кисти</string>\n    <string name=\"draw_arrows\">Рисовать стрелки</string>\n    <string name=\"draw_arrows_sub\">Если включено, то на конце линии будет дорисовываться стрелка</string>\n    <string name=\"crop_description\">Изображения будут обрезаны по центру до введенного размера. Холст будет расширен с заданным цветом фона, если изображение меньше введенных размеров</string>\n    <string name=\"donation\">Пожертвование</string>\n    <string name=\"image_stitching\">Объединение изображений</string>\n    <string name=\"image_stitching_sub\">Объединить входные изображения в одно большое</string>\n    <string name=\"horizontal\">Горизонтальная</string>\n    <string name=\"images_order\">Порядок изображений</string>\n    <string name=\"pick_at_least_two_images\">Выберите минимум 2 изображения</string>\n    <string name=\"scale_small_images_to_large_sub\">Маленькие изображения будут масштабироваться до самого большого в последовательности, если эта опция включена</string>\n    <string name=\"image_orientation\">Ориентация изображения</string>\n    <string name=\"vertical\">Вертикальная</string>\n    <string name=\"output_image_scale\">Масштаб выходного изображения</string>\n    <string name=\"scale_small_images_to_large\">Масштабируйте маленькие изображения до больших</string>\n    <string name=\"blur_edges\">Размытие краёв</string>\n    <string name=\"pixelation\">Пикселизация</string>\n    <string name=\"blur_edges_sub\">Рисует размытые края под исходным изображением, чтобы заполнить пространство вокруг него, а не одним цветом, если включено</string>\n    <string name=\"regular\">Обычный</string>\n    <string name=\"recode\">Рекодирование</string>\n    <string name=\"tolerance\">Допуск</string>\n    <string name=\"enhanced_pixelation\">Красивая пикселизация</string>\n    <string name=\"target_color\">Заменяющий цвет</string>\n    <string name=\"replace_color\">Заменить цвет</string>\n    <string name=\"diamond_pixelation\">Алмазная пикселизация</string>\n    <string name=\"remove_color\">Удаление цвета</string>\n    <string name=\"enhanced_diamond_pixelation\">Улучшенная алмазная пикселизация</string>\n    <string name=\"circle_pixelation\">Круглая пикселизация</string>\n    <string name=\"color_to_remove\">Цвет для удаления</string>\n    <string name=\"color_to_replace\">Заменяемый цвет</string>\n    <string name=\"stroke_pixelation\">Строчная пикселизация</string>\n    <string name=\"enhanced_circle_pixelation\">Улучшенная круглая пикселизация</string>\n    <string name=\"pixel_size\">Размер пикселя</string>\n    <string name=\"lock_draw_orientation\">Блокировка ориентации рисования</string>\n    <string name=\"lock_draw_orientation_sub\">Если включено в режиме рисования, экран не будет вращаться</string>\n    <string name=\"fidelity\">Точность</string>\n    <string name=\"rainbow\">Радуга</string>\n    <string name=\"content_sub\">Схема, которая помещает исходный цвет в Scheme.primaryContainer</string>\n    <string name=\"fruit_salad\">Фруктовый салат</string>\n    <string name=\"fidelity_sub\">Схема, которая очень похожа на схему содержимого</string>\n    <string name=\"content\">Содержание</string>\n    <string name=\"playful_scheme\">Игривая тема: оттенок исходного цвета не отображается в теме</string>\n    <string name=\"vibrant_sub\">Яркая тема, красочность максимальна для Основной палитры и повышена для остальных</string>\n    <string name=\"neutral_sub\">Стиль немного более хроматический, чем монохромный</string>\n    <string name=\"tonal_spot\">Тональное пятно</string>\n    <string name=\"monochrome_sub\">Монохромная тема, цвета чисто чёрный/белый/серый</string>\n    <string name=\"check_for_updates\">Проверить наличие обновлений</string>\n    <string name=\"expressive\">Выразительный</string>\n    <string name=\"neutral\">Нейтральный</string>\n    <string name=\"tonal_spot_sub\">Стиль палитры по умолчанию, позволяет настроить все четыре цвета, другие позволяют установить только ключевой цвет</string>\n    <string name=\"palette_style\">Стиль палитры</string>\n    <string name=\"vibrant\">Яркий</string>\n    <string name=\"both\">Обе</string>\n    <string name=\"fading_edges\">Исчезающие края</string>\n    <string name=\"foss_update_checker_warning\">Проверка обновлений будет подключаться к GitHub для проверки доступности новых версий</string>\n    <string name=\"disabled\">Откл</string>\n    <string name=\"attention\">Внимание</string>\n    <string name=\"invert_colors_sub\">Заменяет цвета темы на негативные, если включено</string>\n    <string name=\"invert_colors\">Инвертировать Цвета</string>\n    <string name=\"search_option\">Поиск</string>\n    <string name=\"search_option_sub\">Включает возможность поиска по всем доступным инструментам на главном экране</string>\n    <string name=\"pdf_tools\">PDF инструменты</string>\n    <string name=\"images_to_pdf\">Изображения в PDF</string>\n    <string name=\"preview_pdf\">Предпросмотр PDF</string>\n    <string name=\"pdf_to_images\">PDF в изображения</string>\n    <string name=\"images_to_pdf_sub\">Упакуйте набор изображений в PDF файл</string>\n    <string name=\"preview_pdf_sub\">Простой просмотрщик PDF</string>\n    <string name=\"pdf_tools_sub\">Совершайте операции с PDF файлами: просмотрите, конвертируйте в набор изображений или создайте новый файл</string>\n    <string name=\"pdf_to_images_sub\">Конвертируйте PDF в изображения в заданном формате</string>\n    <string name=\"mask_filter\">Маска-фильтр</string>\n    <string name=\"mask_filter_sub\">Применяйте цепочки фильтров к заданным замаскированным областям, каждая область маски может определять свой собственный набор фильтров</string>\n    <string name=\"masks\">Маски</string>\n    <string name=\"add_mask\">Добавить маску</string>\n    <string name=\"mask_indexed\">Маска %d</string>\n    <string name=\"inverse_fill_type\">Обратное заполнение</string>\n    <string name=\"mask_preview\">Предпросмотр Маски</string>\n    <string name=\"inverse_fill_type_sub\">Если включено, то все фильтры будут наложены на все незамаскированные области</string>\n    <string name=\"mask_color\">Цвет маски</string>\n    <string name=\"mask_preview_sub\">Нарисованная маска будет отрисована чтобы вы смогли увидеть примерный результат</string>\n    <string name=\"delete_mask\">Удаление Маски</string>\n    <string name=\"delete_mask_warn\">Вы собираетесь удалить выбранную маску фильтрации. Эта операция не может быть отменена</string>\n    <string name=\"full_filter_sub\">Примените любые цепочки фильтров к заданным изображениям или одному изображению</string>\n    <string name=\"start_position\">Начало</string>\n    <string name=\"full_filter\">Полный фильтр</string>\n    <string name=\"end_position\">Конец</string>\n    <string name=\"center_position\">Центр</string>\n    <string name=\"neon_sub\">Добавьте эффект свечения к вашему рисунку</string>\n    <string name=\"neon\">Неон</string>\n    <string name=\"containers_shadow_sub\">Включает тени под контейнерами</string>\n    <string name=\"pen\">Ручка</string>\n    <string name=\"privacy_blur_sub\">Размывает изображение под вашим пальцем чтобы защитить все что вы хотите спрятать</string>\n    <string name=\"pen_sub\">Изначальный режим, самый простой - только цвет</string>\n    <string name=\"sliders_shadow\">Слайдеры</string>\n    <string name=\"highlighter_sub\">Выделите что либо полупрозрачной заливкой</string>\n    <string name=\"highlighter\">Выделитель</string>\n    <string name=\"simple_variants\">Простые Варианты</string>\n    <string name=\"pixelation_sub\">Такой же режим как и приватное размытие, но использует пикселизацию</string>\n    <string name=\"privacy_blur\">Приватное Размытие</string>\n    <string name=\"containers_shadow\">Контейнеры</string>\n    <string name=\"auto_rotate_limits\">Автоповорот</string>\n    <string name=\"buttons_shadow\">Кнопки</string>\n    <string name=\"fabs_shadow\">Левитирующие кнопки</string>\n    <string name=\"fabs_shadow_sub\">Включает тени под левитирующими кнопками</string>\n    <string name=\"switches_shadow\">Переключатели</string>\n    <string name=\"auto_rotate_limits_sub\">Позволяет ограничивающим размерам адаптироваться под ориентацию изображения</string>\n    <string name=\"sliders_shadow_sub\">Включает тени под слайдерами</string>\n    <string name=\"app_bars_shadow_sub\">Включить отрисовку теней под панелью действий</string>\n    <string name=\"buttons_shadow_sub\">Включает тени под кнопками</string>\n    <string name=\"app_bars_shadow\">Панели действий</string>\n    <string name=\"switches_shadow_sub\">Включает тени под переключателями</string>\n    <string name=\"value_in_range\">Значение в диапазоне %1$s - %2$s</string>\n    <string name=\"double_line_arrow\">Двойная стрелка - линия</string>\n    <string name=\"double_line_arrow_sub\">Рисует двойную указательную стрелку от начальной точки до конечной точки в виде линии</string>\n    <string name=\"arrow_sub\">Рисует указывающую стрелку на заданном пути</string>\n    <string name=\"free_drawing\">Свободное рисование</string>\n    <string name=\"outlined_oval\">Очерченный овал</string>\n    <string name=\"line\">Линия</string>\n    <string name=\"oval\">Овал</string>\n    <string name=\"rect\">Прямоугольник</string>\n    <string name=\"outlined_rect_sub\">Рисует очерченный прямоугольник от начальной точки до конечной</string>\n    <string name=\"lasso\">Лассо</string>\n    <string name=\"line_arrow\">Стрелка - линия</string>\n    <string name=\"line_sub\">Рисует путь от начальной точки до конечной в виде линии</string>\n    <string name=\"outlined_oval_sub\">Рисует очерченный овал от начальной точки до конечной</string>\n    <string name=\"lasso_sub\">Рисует замкнутый заполненный контур по заданному пути</string>\n    <string name=\"double_arrow\">Двойная стрелка</string>\n    <string name=\"arrow\">Стрелка</string>\n    <string name=\"free_drawing_sub\">Рисует путь как входное значение</string>\n    <string name=\"rect_sub\">Рисует прямоугольник от начальной точки до конечной</string>\n    <string name=\"line_arrow_sub\">Рисует указывающую стрелку от начальной точки до конечной точки в виде линии</string>\n    <string name=\"double_arrow_sub\">Рисует двойную стрелку, указывающую на заданный путь</string>\n    <string name=\"outlined_rect\">Очерченный прямоугольник</string>\n    <string name=\"oval_sub\">Рисует овал от начальной точки до конечной</string>\n    <string name=\"draw_path_mode\">Режим рисования пути</string>\n    <string name=\"free\">Свободно</string>\n    <string name=\"rows_count\">Количество строк</string>\n    <string name=\"stitch_mode\">Режим строчки</string>\n    <string name=\"horizontal_grid\">Горизонтальная сетка</string>\n    <string name=\"vertical_grid\">Вертикальная сетка</string>\n    <string name=\"columns_count\">Количество столбцов</string>\n    <string name=\"vibration\">Вибрация</string>\n    <string name=\"overwrite_file_requirements\">Для того, чтобы перезаписать файлы, вам нужно использовать источник изображений \\\"Проводник\\\", попробуйте переустановить изображения, мы изменили источник изображений на нужный</string>\n    <string name=\"auto_pin_sub\">Автоматически добавляет сохранённое изображение в буфер обмена, если оно включено</string>\n    <string name=\"no_such_directory\">Каталог \\\"%1$s\\\" не найден, мы переключили его на каталог по умолчанию, пожалуйста, сохраните файл еще раз</string>\n    <string name=\"clipboard\">Буфер обмена</string>\n    <string name=\"overwrite_files_sub\">Исходный файл будет заменен новым вместо сохранения в выбранной папке, для этой опции необходимо, чтобы источником изображения был \\\"Проводник\\\" или GetContent, при переключении этого параметра он будет установлен автоматически</string>\n    <string name=\"vibration_strength\">Сила вибрации</string>\n    <string name=\"overwrite_files\">Перезаписать файлы</string>\n    <string name=\"empty\">Пустой</string>\n    <string name=\"suffix\">Суффикс</string>\n    <string name=\"auto_pin\">Авто закрепление</string>\n    <string name=\"catmull\">Катмулл</string>\n    <string name=\"bicubic\">Бикубический</string>\n    <string name=\"hermite\">Гермит</string>\n    <string name=\"spline\">Сплайн</string>\n    <string name=\"scale_mode\">Режим масштабирования</string>\n    <string name=\"bilinear\">Билинейный</string>\n    <string name=\"hann\">Ханн</string>\n    <string name=\"lanczos\">Ланцош</string>\n    <string name=\"mitchell\">Митчелл</string>\n    <string name=\"nearest\">Ближайший</string>\n    <string name=\"basic\">Базовый</string>\n    <string name=\"default_value\">Значение по умолчанию</string>\n    <string name=\"bilinear_sub\">Линейная (или билинейная, в двух измерениях) интерполяция обычно подходит для изменения размера изображения, но вызывает нежелательное размытие деталей и все еще может быть немного зазубренной</string>\n    <string name=\"bicubic_sub\">Лучшие методы масштабирования включают метод Ланцоша и фильтры Митчелла-Нетравали</string>\n    <string name=\"nearest_sub\">Один из более простых способов увеличения размера, заменяющий каждый пиксель определенным количеством пикселей того же цвета</string>\n    <string name=\"basic_sub\">Простейший режим масштабирования Android, используемый практически во всех приложениях</string>\n    <string name=\"catmull_sub\">Метод для плавной интерполяции и пересэмплирования набора контрольных точек, широко используемый в компьютерной графике для создания плавных кривых</string>\n    <string name=\"hann_sub\">Оконная функция, часто применяемая в обработке сигналов для минимизации утечки спектра и улучшения точности анализа частот путем заострения краев сигнала</string>\n    <string name=\"hermite_sub\">Математический метод интерполяции, использующий значения и производные на конечных точках сегмента кривой для создания плавной и непрерывной кривой</string>\n    <string name=\"lanczos_sub\">Метод пересэмплирования, поддерживающий высококачественную интерполяцию с использованием взвешенной функции sinc для значений пикселей</string>\n    <string name=\"mitchell_sub\">Метод пересэмплирования, использующий свертку с настраиваемыми параметрами для достижения баланса между четкостью и сглаживанием в измененном изображении</string>\n    <string name=\"spline_sub\">Использует кусочно-заданные полиномиальные функции для плавной интерполяции и приближения кривой или поверхности, обеспечивая гибкое и непрерывное представление формы</string>\n    <string name=\"only_clip_sub\">Сохранение в хранилище не будет выполнено, и изображение при возможности будет помещено в буфер обмена</string>\n    <string name=\"only_clip\">Только закрепление</string>\n    <string name=\"recognize_text\">Распознавание текста</string>\n    <string name=\"accuracy\">Точность: %1$s</string>\n    <string name=\"fast\">Быстро</string>\n    <string name=\"no_data\">Нет данных</string>\n    <string name=\"download\">Загрузить</string>\n    <string name=\"no_connection\">Нет соединения с интернетом, проверьте подключение и попробуйте снова чтобы загрузить модель</string>\n    <string name=\"downloaded_languages\">Загруженные языки</string>\n    <string name=\"available_languages\">Доступные языки</string>\n    <string name=\"recognize_text_sub\">Распознайте текст с заданного изображения, поддерживается более 120 языков</string>\n    <string name=\"download_description\">Для правильной работы Tesseract OCR на ваше устройство необходимо загрузить дополнительные обучающие данные (%1$s). \\n Вы хотите загрузить данные %2$s?</string>\n    <string name=\"picture_has_no_text\">На изображении нет текста, или приложение не смогло его определить</string>\n    <string name=\"restore_background_sub\">Кисть будет восстанавливать стертое изображение вместо стирания</string>\n    <string name=\"recognition_type\">Тип распознавания</string>\n    <string name=\"standard\">Стандарт</string>\n    <string name=\"best\">Лучший</string>\n    <string name=\"segmentation_mode\">Режим сегментации</string>\n    <string name=\"use_pixel_switch\">Использовать переключатель Pixel</string>\n    <string name=\"use_pixel_switch_sub\">Будет использоваться переключатель, как на телефонах Pixel, вместо стандартного из Material You</string>\n    <string name=\"saved_to_original\">Перезаписан файл с именем %1$s в оригинальной папке</string>\n    <string name=\"magnifier_sub\">Включает лупу над пальцем во время рисования для лучшего понимания происходящего</string>\n    <string name=\"force_exif_widget_initial_value_sub\">EXIF переключатель будет в положении ВКЛ автоматически</string>\n    <string name=\"allow_multiple_languages\">Разрешить несколько языков</string>\n    <string name=\"magnifier\">Лупа</string>\n    <string name=\"force_exif_widget_initial_value\">Начальное значение</string>\n    <string name=\"side_by_side\">Бок о бок</string>\n    <string name=\"transparency\">Прозрачность</string>\n    <string name=\"rate\">Оценить</string>\n    <string name=\"rate_app\">Оцените приложение</string>\n    <string name=\"rate_app_sub\">Это приложение полностью бесплатно. Если вы хотите, чтобы оно стало масштабнее, поставьте звёздочку проекту на Github 😄</string>\n    <string name=\"slide\">Слайд</string>\n    <string name=\"toggle_tap\">Нажатие</string>\n    <string name=\"segmentation_mode_auto_only\">Только автоматически</string>\n    <string name=\"segmentation_mode_auto\">Автоматически</string>\n    <string name=\"segmentation_mode_single_column\">Одиночный столбец</string>\n    <string name=\"segmentation_mode_single_word\">Одно слово</string>\n    <string name=\"segmentation_mode_circle_word\">Круговое слово</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Разреженный текст, обнаружение ориентации и сценария</string>\n    <string name=\"segmentation_mode_raw_line\">Необработанная линия</string>\n    <string name=\"segmentation_mode_osd_only\">Только обнаружение ориентации и сценария</string>\n    <string name=\"segmentation_mode_auto_osd\">Автоматическое обнаружение ориентации и сценария</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Вертикальный текст в виде одного блока</string>\n    <string name=\"segmentation_mode_single_char\">Одиночный символ</string>\n    <string name=\"segmentation_mode_single_block\">Одиночный блок</string>\n    <string name=\"segmentation_mode_sparse_text\">Разреженный текст</string>\n    <string name=\"segmentation_mode_single_line\">Одиночная линия</string>\n    <string name=\"all\">Все</string>\n    <string name=\"gradient_type_sweep\">Развертка</string>\n    <string name=\"gradient_type\">Тип градиента</string>\n    <string name=\"center_x\">Центр X</string>\n    <string name=\"center_y\">Центр У</string>\n    <string name=\"tile_mode\">Режим плитки</string>\n    <string name=\"tile_mode_mirror\">Зеркало</string>\n    <string name=\"tile_mode_clamp\">Зажим</string>\n    <string name=\"tile_mode_decal\">Наклейка</string>\n    <string name=\"color_stops\">Ключевые точки</string>\n    <string name=\"add_color\">Добавить цвет</string>\n    <string name=\"properties\">Параметры</string>\n    <string name=\"delete_language_sub\">Вы хотите удалить данные обучения OCR языка \\\"%1$s\\\" для всех типов распознавания или только для выбранного (%2$s)?</string>\n    <string name=\"current\">Текущий</string>\n    <string name=\"tile_mode_repeated\">Повтор</string>\n    <string name=\"gradient_maker\">Создание градиентов</string>\n    <string name=\"gradient_maker_sub\">Создайте градиент заданного размера с настраиваемыми цветами и типом внешнего вида</string>\n    <string name=\"gradient_type_linear\">Линейный</string>\n    <string name=\"gradient_type_radial\">Радиальный</string>\n    <string name=\"brightness_enforcement\">Максимальная яркость</string>\n    <string name=\"screen\">Экран</string>\n    <string name=\"transformations\">Трансформации</string>\n    <string name=\"gradient_maker_type_image\">Наложение градиента</string>\n    <string name=\"gradient_maker_type_image_sub\">Наложите любой градиент на любое изображение</string>\n    <string name=\"camera\">Камера</string>\n    <string name=\"camera_sub\">Использует камеру для получения изображения, обратите внимание, что вы можете получить только одну фотографию, используя этот источник изображений</string>\n    <string name=\"repeat_watermark\">Повтор водяного знака</string>\n    <string name=\"offset_x\">Смещение Х</string>\n    <string name=\"watermarking_image_sub\">Это изображение будет использоваться в качестве шаблона для водяного знака</string>\n    <string name=\"watermarking\">Водяной знак</string>\n    <string name=\"repeat_watermark_sub\">Накладывает водяной знак на все изображение вместо заданной точки</string>\n    <string name=\"watermarking_sub\">Наложите водяные знаки на изображения в виде текста или других изображений</string>\n    <string name=\"offset_y\">Смещение У</string>\n    <string name=\"watermark_type\">Тип водяного знака</string>\n    <string name=\"text_color\">Цвет текста</string>\n    <string name=\"overlay_mode\">Режим наложения</string>\n    <string name=\"gif_tools_sub\">Конвертируйте изображения в GIF-картинку или извлекайте кадры из заданного GIF-изображения</string>\n    <string name=\"gif_type_to_gif\">Изображения в GIF</string>\n    <string name=\"select_gif_image_to_start\">Выберите GIF-изображение для начала</string>\n    <string name=\"use_size_of_first_frame\">Используйте размер первого кадра</string>\n    <string name=\"repeat_count\">Количество повторений</string>\n    <string name=\"frame_delay\">Задержка кадра</string>\n    <string name=\"millis\">мсек</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"gif_tools\">GIF инструменты</string>\n    <string name=\"gif_type_to_image_sub\">Преобразуйте GIF-файл в пакет изображений</string>\n    <string name=\"gif_type_to_gif_sub\">Преобразование пакета изображений в GIF-файл</string>\n    <string name=\"use_size_of_first_frame_sub\">Замените указанный размер размерами первого кадра</string>\n    <string name=\"gif_type_to_image\">GIF в изображения</string>\n    <string name=\"original_image_preview_alpha\">Прозрачность предпросмотра исходного изображения</string>\n    <string name=\"use_lasso\">Использовать Лассо</string>\n    <string name=\"use_lasso_sub\">Использует для стирания Лассо, как в режиме рисования</string>\n    <string name=\"secure_mode\">Приватный режим</string>\n    <string name=\"secure_mode_sub\">Скрывает контент при выходе, так же экран приложения не может быть захвачен или записан</string>\n    <string name=\"confetti\">Конфетти</string>\n    <string name=\"confetti_sub\">Конфетти будет показано при сохранении и других важных действиях</string>\n    <string name=\"exit\">Выйти</string>\n    <string name=\"preview_closing\">Если вы оставите предварительный просмотр сейчас, вам придется добавить изображения снова</string>\n    <string name=\"dithering\">Дизеринг</string>\n    <string name=\"quantizier\">Квантизатор</string>\n    <string name=\"gray_scale\">Серые тона</string>\n    <string name=\"bayer_two_dithering\">Дизеринг Байера два на два</string>\n    <string name=\"bayer_three_dithering\">Дизеринг Байера три на три</string>\n    <string name=\"bayer_four_dithering\">Дизеринг Байера четыре на четыре</string>\n    <string name=\"bayer_eight_dithering\">Дизеринг Байера восемь на восемь</string>\n    <string name=\"floyd_steinberg_dithering\">Дизеринг Флойда Стейнберга</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Дизеринг Джарвиса Джуди Нинке</string>\n    <string name=\"sierra_dithering\">Дизеринг Сиерры</string>\n    <string name=\"two_row_sierra_dithering\">Двухрядный дизеринг Сиерры</string>\n    <string name=\"sierra_lite_dithering\">Упрощенный дизеринг Сиерры</string>\n    <string name=\"atkinson_dithering\">Дизеринг Аткинсона</string>\n    <string name=\"stucki_dithering\">Дизеринг Стуки</string>\n    <string name=\"burkes_dithering\">Дизеринг Бёркса</string>\n    <string name=\"false_floyd_steinberg_dithering\">Ложный дизеринг Флойда Стейнберга</string>\n    <string name=\"left_to_right_dithering\">Дизеринг слева направо</string>\n    <string name=\"random_dithering\">Случайный дизеринг</string>\n    <string name=\"simple_threshold_dithering\">Простой пороговый дизеринг</string>\n    <string name=\"email\">Почта</string>\n    <string name=\"median_blur\">Медианное размытие</string>\n    <string name=\"sigma\">Сигма</string>\n    <string name=\"spatial_sigma\">Пространственная сигма</string>\n    <string name=\"native_stack_blur\">Нативное Размытие Стэком</string>\n    <string name=\"tilt_shift\">Наклон-смещение</string>\n    <string name=\"b_spline\">Би Сплайн</string>\n    <string name=\"b_spline_sub\">Использует кусочно-определенные функции бикубического полинома для плавной интерполяции и аппроксимации кривой или поверхности, гибкое и непрерывное представление формы</string>\n    <string name=\"shuffle\">Перемешивание</string>\n    <string name=\"glitch\">Сбой</string>\n    <string name=\"seed\">Зерно</string>\n    <string name=\"amount\">Количество</string>\n    <string name=\"anaglyph\">Анаглиф</string>\n    <string name=\"noise\">Шум</string>\n    <string name=\"pixel_sort\">Сортировка Пикселей</string>\n    <string name=\"channel_shift_x\">Сдвиг канала по X</string>\n    <string name=\"tent_blur\">Размытие тентом</string>\n    <string name=\"side_fade\">Боковое затухание</string>\n    <string name=\"side\">Сторона</string>\n    <string name=\"corruption_shift_y\">Сдвиг сбоя по У</string>\n    <string name=\"top\">Верх</string>\n    <string name=\"enhanced_glitch\">Улучшенный Сбой</string>\n    <string name=\"channel_shift_y\">Сдвиг канала по У</string>\n    <string name=\"corruption_shift_x\">Сдвиг сбоя по Х</string>\n    <string name=\"corruption_size\">Размер сбоя</string>\n    <string name=\"bottom\">Низ</string>\n    <string name=\"strength\">Сила</string>\n    <string name=\"anisotropic_diffusion\">Анизотропная диффузия</string>\n    <string name=\"horizontal_wind_stagger\">Горизонтальное колебание ветра</string>\n    <string name=\"erode\">Эрозия</string>\n    <string name=\"diffusion\">Диффузия</string>\n    <string name=\"conduction\">Проводимость</string>\n    <string name=\"aces_filmic_tone_mapping\">Кинематографичное отображение тонов ACES</string>\n    <string name=\"amplitude_x\">Амплитуда Х</string>\n    <string name=\"aces_hill_tone_mapping\">Холмистое отображение тонов ACES</string>\n    <string name=\"heji_burgess_tone_mapping\">Отображение тонов Хейла Берджесса</string>\n    <string name=\"fast_bilaterial_blur\">Быстрое двухстороннее размытие</string>\n    <string name=\"poisson_blur\">Пуассоновое размытие</string>\n    <string name=\"logarithmic_tone_mapping\">Логарифмическое отображение тонов</string>\n    <string name=\"crystallize\">Кристаллизация</string>\n    <string name=\"stroke_color\">Цвет обводки</string>\n    <string name=\"fractal_glass\">Фрактальное стекло</string>\n    <string name=\"turbulence\">Турбулентность</string>\n    <string name=\"amplitude\">Амплитуда</string>\n    <string name=\"marble\">Мрамор</string>\n    <string name=\"oil\">Масло</string>\n    <string name=\"water_effect\">Эффект воды</string>\n    <string name=\"just_size\">Размер</string>\n    <string name=\"frequency_y\">Частота У</string>\n    <string name=\"perlin_distortion\">Искажение Перлина</string>\n    <string name=\"frequency_x\">Частота Х</string>\n    <string name=\"amplitude_y\">Амплитуда У</string>\n    <string name=\"hable_filmic_tone_mapping\">Кинематографичное отображение тонов Хэйбла</string>\n    <string name=\"dehaze\">Удаление тумана</string>\n    <string name=\"speed\">Скорость</string>\n    <string name=\"omega\">Омега</string>\n    <string name=\"color_matrix_4x4\">Цветовая матрица 4х4</string>\n    <string name=\"simple_effects\">Простые эффекты</string>\n    <string name=\"tritonomaly\">Тритономалия</string>\n    <string name=\"deutaromaly\">Дейтераномалия</string>\n    <string name=\"browni\">Брауни</string>\n    <string name=\"cool\">Холод</string>\n    <string name=\"tritanopia\">Тританопия</string>\n    <string name=\"deutaronotopia\">Дейтаронотопия</string>\n    <string name=\"protanopia\">Протанопия</string>\n    <string name=\"achromatomaly\">Ахроматомалия</string>\n    <string name=\"color_matrix_3x3\">Цветовая матрица 3x3</string>\n    <string name=\"polaroid\">Полароид</string>\n    <string name=\"protonomaly\">Протаномалия</string>\n    <string name=\"vintage\">Винтаж</string>\n    <string name=\"night_vision\">Ночное видение</string>\n    <string name=\"coda_chrome\">Кода Хром</string>\n    <string name=\"achromatopsia\">Ахроматопсия</string>\n    <string name=\"warm\">Тепло</string>\n    <string name=\"pastel\">Пастель</string>\n    <string name=\"pink_dream\">Розовая мечта</string>\n    <string name=\"hot_summer\">Жаркое лето</string>\n    <string name=\"purple_mist\">Пурпурная струя</string>\n    <string name=\"sunrise\">Рассвет</string>\n    <string name=\"soft_spring_light\">Мягкая весна</string>\n    <string name=\"lavender_dream\">Лавандовые мечты</string>\n    <string name=\"cyberpunk\">Киберпанк</string>\n    <string name=\"lemonade_light\">Светлый лимонад</string>\n    <string name=\"night_magic\">Ночная Магия</string>\n    <string name=\"color_explosion\">Цветной взрыв</string>\n    <string name=\"electric_gradient\">Электрический градиент</string>\n    <string name=\"caramel_darkness\">Карамельная тьма</string>\n    <string name=\"futuristic_gradient\">Футуристичный градиент</string>\n    <string name=\"green_sun\">Зеленое Солнце</string>\n    <string name=\"rainbow_world\">Радужный мир</string>\n    <string name=\"space_portal\">Космический портал</string>\n    <string name=\"digital_code\">Цифровой код</string>\n    <string name=\"grain\">Зернистость</string>\n    <string name=\"unsharp\">Анти резкость</string>\n    <string name=\"orange_haze\">Оранжевый туман</string>\n    <string name=\"golden_hour\">Золотой час</string>\n    <string name=\"colorful_swirl\">Цветной вихрь</string>\n    <string name=\"autumn_tones\">Осенние тона</string>\n    <string name=\"spectral_fire\">Спектральный огонь</string>\n    <string name=\"fantasy_landscape\">Фантастический пейзаж</string>\n    <string name=\"deep_purple\">Глубокий фиолетовый</string>\n    <string name=\"red_swirl\">Красный вихрь</string>\n    <string name=\"bokeh\">Боке</string>\n    <string name=\"emoji_selection_error\">Невозможно выбрать эмодзи, пока включен их случайный выбор</string>\n    <string name=\"random_emojis_sub\">Эмодзи будет постоянно меняться случайным образом, а не использовать выбранный</string>\n    <string name=\"random_emojis\">Случайные эмодзи</string>\n    <string name=\"random_emojis_error\">Невозможно использовать случайный выбор эмодзи, пока они отключены</string>\n    <string name=\"old_tv\">Старый телевизор</string>\n    <string name=\"shuffle_blur\">Размытие перемешиванием</string>\n    <string name=\"no_favorite_filters\">Избранные фильтры пока не добавлены</string>\n    <string name=\"favorite\">Избранное</string>\n    <string name=\"image_format\">Формат Изображения</string>\n    <string name=\"icon_shape_sub\">Добавляет контейнер с выбранной фигурой под ведущие значки карточек</string>\n    <string name=\"icon_shape\">Форма иконки</string>\n    <string name=\"uchimura\">Учимура</string>\n    <string name=\"mobius\">Мобиус</string>\n    <string name=\"peak\">Вершина</string>\n    <string name=\"aldridge\">Олдридж</string>\n    <string name=\"cutoff\">Обрезка</string>\n    <string name=\"transition\">Переход</string>\n    <string name=\"color_anomaly\">Цветовая аномалия</string>\n    <string name=\"drago\">Драго</string>\n    <string name=\"emoji_as_color_scheme\">Эмодзи в качестве цветовой схемы</string>\n    <string name=\"images_overwritten\">Изображения перезаписаны в исходном месте назначения</string>\n    <string name=\"cannot_change_image_format\">Невозможно изменить формат изображения, если включена опция перезаписи файлов</string>\n    <string name=\"emoji_as_color_scheme_sub\">Использует основной цвет эмодзи в качестве цветовой схемы приложения вместо заданной вручную</string>\n    <string name=\"dark_colors\">Темные цвета</string>\n    <string name=\"copy_as_compose_code\">Скопировать в Jetpack Compose</string>\n    <string name=\"material_you_sub\">Создает Material You палитру из изображения</string>\n    <string name=\"dark_colors_sub\">Использует цветовую схему ночного режима вместо светлого варианта</string>\n    <string name=\"cross_blur\">Перекрестное размытие</string>\n    <string name=\"star_blur\">Размытие звездами</string>\n    <string name=\"linear_tilt_shift\">Линейный сдвиг наклона</string>\n    <string name=\"ring_blur\">Размытие кольцами</string>\n    <string name=\"circle_blur\">Размытие кругами</string>\n    <string name=\"tags_to_remove\">Тэги для удаления</string>\n    <string name=\"apng_tools\">APNG инструменты</string>\n    <string name=\"select_apng_image_to_start\">Выберите APNG, чтобы начать</string>\n    <string name=\"apng_type_to_apng_sub\">Конвертация изображений в файл APNG</string>\n    <string name=\"motion_blur\">Размытие движением</string>\n    <string name=\"apng_tools_sub\">Преобразование изображений в APNG или извлечение кадров из APNG</string>\n    <string name=\"apng_type_to_image\">APNG в изображения</string>\n    <string name=\"apng_type_to_image_sub\">Преобразование файла APNG в изображения</string>\n    <string name=\"apng_type_to_apng\">Изображения в APNG</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Создать Zip-файл из заданных файлов или изображений</string>\n    <string name=\"drag_handle_width\">Ширина перетаскиваемой ручки</string>\n    <string name=\"explode\">Взрыв</string>\n    <string name=\"rain\">Дождь</string>\n    <string name=\"confetti_type\">Тип конфетти</string>\n    <string name=\"festive\">Праздничный</string>\n    <string name=\"corners\">Углы</string>\n    <string name=\"jxl_type_to_jpeg\">JXL в JPEG</string>\n    <string name=\"select_jxl_image_to_start\">Выберите изображение JXL чтобы начать</string>\n    <string name=\"jxl_tools\">JXL инструменты</string>\n    <string name=\"jxl_tools_sub\">Выполняйте перекодирование JXL ~ JPEG без потери качества или конвертируйте GIF/APNG в анимацию JXL</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Выполните перекодирование без потерь из JXL в JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Выполните перекодирование без потерь из JPEG в JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG в JXL</string>\n    <string name=\"fast_gaussian_blur_2d\">Быстрое размытие по Гауссу 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Быстрое размытие по Гауссу 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Быстрое размытие по Гауссу 4D</string>\n    <string name=\"harmonization_level\">Уровень гармонизации</string>\n    <string name=\"auto_paste\">Авто-вставка</string>\n    <string name=\"harmonization_color\">Цвет гармонизации</string>\n    <string name=\"auto_paste_sub\">Разрешить приложению автоматически вставлять данные из буфера обмена, чтобы они появились на главном экране, и вы смогли их обработать</string>\n    <string name=\"lanczos_bessel\">Ланцош Бессель</string>\n    <string name=\"gif_type_to_jxl\">GIF в JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Конвертируйте изображения GIF в анимированные изображения JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG в JXL</string>\n    <string name=\"jxl_type_to_images\">JXL в изображения</string>\n    <string name=\"jxl_type_to_images_sub\">Преобразование анимации JXL в пакет изображений</string>\n    <string name=\"jxl_type_to_jxl\">Изображения в JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Преобразование пакета изображений в анимацию JXL</string>\n    <string name=\"behavior\">Поведение</string>\n    <string name=\"generate_previews\">Создание превью</string>\n    <string name=\"lossy_compression\">Сжатие с потерями</string>\n    <string name=\"lossy_compression_sub\">Использует сжатие с потерями для уменьшения размера файла вместо сжатия без потерь</string>\n    <string name=\"lanczos_bessel_sub\">Метод повторной выборки, который поддерживает высококачественную интерполяцию за счет применения функции Бесселя (jinc) к значениям пикселей</string>\n    <string name=\"apng_type_to_jxl_sub\">Конвертируйте изображения APNG в анимированные изображения JXL</string>\n    <string name=\"skip_file_picking\">Пропустить выбор файла</string>\n    <string name=\"skip_file_picking_sub\">Средство выбора файла будет показано немедленно, если это возможно, на выбранном экране</string>\n    <string name=\"generate_previews_sub\">Включает создание предварительного просмотра, это может помочь избежать сбоев на некоторых устройствах, это также отключает некоторые функции редактирования в рамках одной опции редактирования</string>\n    <string name=\"compression_type\">Тип Сжатия</string>\n    <string name=\"speed_sub\">Управляет скоростью декодирования результирующего изображения. Это должно помочь быстрее открыть полученное изображение. Значение %1$s означает самое медленное декодирование, тогда как %2$s — самое быстрое, этот параметр может увеличить размер выходного изображения</string>\n    <string name=\"sort_by_date\">Сортировать по дате</string>\n    <string name=\"sort_by_name\">Сортировать по имени</string>\n    <string name=\"sorting\">Сортировка</string>\n    <string name=\"sort_by_date_reversed\">Сортировать по дате (наоборот)</string>\n    <string name=\"sort_by_name_reversed\">Сортировать по имени (наоборот)</string>\n    <string name=\"try_again\">Попробовать снова</string>\n    <string name=\"show_settings_in_landscape\">Показать настройки в альбомной ориентации</string>\n    <string name=\"switch_type\">Тип переключателя</string>\n    <string name=\"compose\">Композ</string>\n    <string name=\"pick_multiple_media\">Множественный выбор медиа</string>\n    <string name=\"pick_single_media\">Выбор медиа</string>\n    <string name=\"pick\">Выбрать</string>\n    <string name=\"material_you_switch_sub\">Использует переключатель на основе View, он выглядит лучше других и имеет приятную анимацию</string>\n    <string name=\"compose_switch_sub\">Использует переключатель из Jetpack Compose, он не так красив, как на основе View</string>\n    <string name=\"pixel_switch\">Пиксель</string>\n    <string name=\"fluent_switch\">Флюент</string>\n    <string name=\"cupertino_switch\">Купертино</string>\n    <string name=\"show_settings_in_landscape_sub\">Если это отключено, то в ландшафтном режиме настройки будут открываться по кнопке в верхней панели приложения, как всегда, вместо постоянной видимой опции</string>\n    <string name=\"fullscreen_settings\">Полноэкранные настройки</string>\n    <string name=\"fullscreen_settings_sub\">Включите его, и страница настроек всегда будет открываться в полноэкранном режиме, а не в выдвижном ящике</string>\n    <string name=\"max\">Максимум</string>\n    <string name=\"resize_anchor\">Привязка к размеру</string>\n    <string name=\"fluent_switch_sub\">Использует переключатель в стиле Windows 11 на основе системы дизайна Fluent</string>\n    <string name=\"cupertino_switch_sub\">Использует iOS-подобный переключатель на основе системы дизайна Купертино</string>\n    <string name=\"channels_configuration\">Конфигурация каналов</string>\n    <string name=\"header_today\">Сегодня</string>\n    <string name=\"header_yesterday\">Вчера</string>\n    <string name=\"embedded_picker\">Встроенное средство выбора</string>\n    <string name=\"embedded_picker_sub\">Использует собственный инструмент выбора изображения Image Toolbox вместо предопределенных системой</string>\n    <string name=\"no_permissions\">Нет разрешений</string>\n    <string name=\"request\">Запросить</string>\n    <string name=\"svg_warning\">Использование этого инструмента для отслеживания больших изображений без уменьшения масштаба не рекомендуется, это может привести к сбою и увеличению времени обработки</string>\n    <string name=\"images_to_svg\">Изображения в SVG</string>\n    <string name=\"images_to_svg_sub\">Трассировка данных изображений в изображения SVG</string>\n    <string name=\"use_sampled_palette\">Использовать выборочную палитру</string>\n    <string name=\"use_sampled_palette_sub\">Палитра квантования будет выбрана, если эта опция включена</string>\n    <string name=\"path_omit\">Пропуск пути</string>\n    <string name=\"downscale_image\">Уменьшение изображения</string>\n    <string name=\"default_line_width\">Толщина линии по умолчанию</string>\n    <string name=\"engine_mode\">Режим двигателя</string>\n    <string name=\"legacy\">Старый</string>\n    <string name=\"lstm_network\">Сеть LSTM</string>\n    <string name=\"legacy_and_lstm\">Старый &amp; LSTM</string>\n    <string name=\"reset_properties\">Сбросить свойства</string>\n    <string name=\"downscale_image_sub\">Перед обработкой изображение будет уменьшено до меньших размеров, это поможет инструменту работать быстрее и безопаснее</string>\n    <string name=\"min_color_ratio\">Минимальное соотношение цветов</string>\n    <string name=\"lines_threshold\">Порог линий</string>\n    <string name=\"quadratic_threshold\">Квадратичный порог</string>\n    <string name=\"coordinates_rounding_tolerance\">Допуск округления координат</string>\n    <string name=\"path_scale\">Масштаб пути</string>\n    <string name=\"reset_properties_sub\">Для всех свойств будут установлены значения по умолчанию. Обратите внимание, что это действие невозможно отменить</string>\n    <string name=\"detailed\">Подробный</string>\n    <string name=\"convert\">Конвертировать</string>\n    <string name=\"convert_sub\">Преобразование пакетов изображений в заданный формат</string>\n    <string name=\"tag_planar_configuration\">Планарная конфигурация</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr сабсемплинг</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Позиционирование</string>\n    <string name=\"tag_x_resolution\">X Разрешение</string>\n    <string name=\"tag_y_resolution\">Y Разрешение</string>\n    <string name=\"tag_resolution_unit\">Еденица разрешения</string>\n    <string name=\"tag_strip_offsets\">Обрезать офсеты</string>\n    <string name=\"tag_strip_byte_counts\">Стрип байтов число</string>\n    <string name=\"tag_jpeg_interchange_format\">Формат обмена JPEG</string>\n    <string name=\"tag_transfer_function\">Трансферная функция</string>\n    <string name=\"tag_white_point\">Белая точка</string>\n    <string name=\"tag_primary_chromaticities\">Первичная цветность</string>\n    <string name=\"tag_model\">Модель</string>\n    <string name=\"tag_make\">Производитель</string>\n    <string name=\"tag_datetime\">Время</string>\n    <string name=\"tag_artist\">Художник</string>\n    <string name=\"tag_maker_note\">Примечание создателя</string>\n    <string name=\"tag_user_comment\">Пользовательский комментарий</string>\n    <string name=\"tag_gamma\">Гамма</string>\n    <string name=\"tag_datetime_original\">Оригинальное время</string>\n    <string name=\"tag_exposure_time\">Время задержки</string>\n    <string name=\"tag_spectral_sensitivity\">Спектральная чувствительность</string>\n    <string name=\"tag_sensitivity_type\">Тип чувствительности</string>\n    <string name=\"tag_iso_speed\">ISO скорость</string>\n    <string name=\"tag_aperture_value\">Значение диафрагмы</string>\n    <string name=\"tag_brightness_value\">Значение яркости</string>\n    <string name=\"tag_flash\">Вспышка</string>\n    <string name=\"tag_file_source\">Файловый источник</string>\n    <string name=\"tag_white_balance\">Баланс белого</string>\n    <string name=\"tag_contrast\">Контраст</string>\n    <string name=\"tag_saturation\">Насыщение</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"add_new_folder\">Добавить новую папку</string>\n    <string name=\"tag_bits_per_sample\">Битов на семпл</string>\n    <string name=\"tag_compression\">Компрессия</string>\n    <string name=\"tag_photometric_interpretation\">Фотометрическая интерпретация</string>\n    <string name=\"tag_samples_per_pixel\">Семплов на пиксель</string>\n    <string name=\"tag_rows_per_strip\">Линий на стрип</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Формат обмена JPEG длина</string>\n    <string name=\"tag_copyright\">Авторские права</string>\n    <string name=\"tag_software\">ПО</string>\n    <string name=\"tag_image_description\">Описание изображения</string>\n    <string name=\"tag_related_sound_file\">Соответсвующий звуковой файл</string>\n    <string name=\"tag_max_aperture_value\">Максимальное значение диафрагмы</string>\n    <string name=\"tag_flash_energy\">Энергия вспышки</string>\n    <string name=\"tag_dng_version\">Версия DNG</string>\n    <string name=\"tag_datetime_digitized\">Время оцифрования</string>\n    <string name=\"tag_photographic_sensitivity\">Фотографическая чувствительность</string>\n    <string name=\"draw_text_sub\">Нарисовать текст по пути с заданным шрифтом и цветом</string>\n    <string name=\"tag_standard_output_sensitivity\">Чувствительность стандартного вывода</string>\n    <string name=\"font_size\">Размер шрифта</string>\n    <string name=\"watermark_size\">Размер водного знака</string>\n    <string name=\"tag_camera_owner_name\">Имя владельца камеры</string>\n    <string name=\"tag_sharpness\">Резкость</string>\n    <string name=\"tag_exif_version\">Версия Exif</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Коэффициенты Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">Ссылка Черный Белый</string>\n    <string name=\"tag_flashpix_version\">Версия Flashpix</string>\n    <string name=\"tag_color_space\">Цветовое пространство</string>\n    <string name=\"tag_pixel_x_dimension\">Размер X в пикселях</string>\n    <string name=\"tag_pixel_y_dimension\">Размер Y в пикселях</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Сжатые биты на пиксель</string>\n    <string name=\"tag_offset_time\">Время смещения</string>\n    <string name=\"tag_offset_time_original\">Смещение исходного времени</string>\n    <string name=\"tag_offset_time_digitized\">Время смещения в цифровом формате</string>\n    <string name=\"tag_subsec_time\">Время в секундах</string>\n    <string name=\"tag_subsec_time_original\">Оригинал, длительность менее секунды</string>\n    <string name=\"tag_subsec_time_digitized\">Оцифрованное время в секундах</string>\n    <string name=\"tag_f_number\">Номер F</string>\n    <string name=\"tag_exposure_program\">Программа воздействия</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_recommended_exposure_index\">Рекомендуемый индекс воздействия</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Широта скорости ISO yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Скорость ISO Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Значение скорости затвора</string>\n    <string name=\"tag_exposure_bias_value\">Значение смещения экспозиции</string>\n    <string name=\"tag_subject_distance\">Расстояние до объекта</string>\n    <string name=\"tag_metering_mode\">Режим измерения</string>\n    <string name=\"tag_subject_area\">Тематическая область</string>\n    <string name=\"tag_focal_length\">Фокусное расстояние</string>\n    <string name=\"tag_spatial_frequency_response\">Пространственная частотная характеристика</string>\n    <string name=\"tag_focal_plane_x_resolution\">Разрешение по X в фокальной плоскости</string>\n    <string name=\"tag_focal_plane_y_resolution\">Разрешение по Y в фокальной плоскости</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Единица разрешения фокальной плоскости</string>\n    <string name=\"tag_subject_location\">Местоположение объекта</string>\n    <string name=\"tag_exposure_index\">Индекс воздействия</string>\n    <string name=\"tag_sensing_method\">Метод обнаружения</string>\n    <string name=\"tag_cfa_pattern\">Шаблон CFA</string>\n    <string name=\"tag_custom_rendered\">Пользовательская визуализация</string>\n    <string name=\"tag_exposure_mode\">Режим экспозиции</string>\n    <string name=\"tag_digital_zoom_ratio\">Коэффициент цифрового масштабирования</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Фокусное расстояние на пленке 35 мм</string>\n    <string name=\"tag_scene_capture_type\">Тип захвата сцены</string>\n    <string name=\"tag_gain_control\">Управление усилением</string>\n    <string name=\"tag_device_setting_description\">Описание настройки устройства</string>\n    <string name=\"tag_subject_distance_range\">Диапазон расстояний до объекта</string>\n    <string name=\"tag_image_unique_id\">Уникальный идентификатор изображения</string>\n    <string name=\"tag_body_serial_number\">Серийный номер корпуса</string>\n    <string name=\"tag_lens_specification\">Спецификация объектива</string>\n    <string name=\"tag_lens_make\">Производитель объектива</string>\n    <string name=\"tag_lens_model\">Модель объектива</string>\n    <string name=\"tag_lens_serial_number\">Серийный номер объектива</string>\n    <string name=\"tag_gps_version_id\">Идентификатор версии GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Ссылка на широту GPS</string>\n    <string name=\"tag_gps_latitude\">Широта GPS</string>\n    <string name=\"tag_gps_longitude_ref\">Ссылка на долготу GPS</string>\n    <string name=\"tag_gps_longitude\">Долгота GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Ссылка на высоту по GPS</string>\n    <string name=\"tag_gps_altitude\">Высота по GPS</string>\n    <string name=\"tag_gps_timestamp\">Отметка времени GPS</string>\n    <string name=\"tag_gps_satellites\">Спутники GPS</string>\n    <string name=\"tag_gps_status\">Состояние GPS</string>\n    <string name=\"tag_gps_measure_mode\">Режим измерения GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Ссылка на скорость GPS</string>\n    <string name=\"tag_gps_speed\">Скорость GPS</string>\n    <string name=\"tag_gps_track_ref\">Ссылка на GPS-трек</string>\n    <string name=\"tag_gps_track\">GPS-трек</string>\n    <string name=\"tag_gps_img_direction_ref\">Ссылка на направление GPS-изображения</string>\n    <string name=\"tag_gps_img_direction\">Направление GPS-изображения</string>\n    <string name=\"tag_gps_map_datum\">Система координат GPS-карты</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Ссылка на широту места назначения по GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Широта пункта назначения GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Ссылка на долготу пункта назначения по GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Долгота назначения по GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Ссылка на конечный пеленг GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Назначение GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Ссылка на конечное расстояние по GPS</string>\n    <string name=\"tag_gps_dest_distance\">Расстояние назначения GPS</string>\n    <string name=\"tag_gps_processing_method\">Метод обработки GPS</string>\n    <string name=\"tag_gps_area_information\">Информация о районе GPS</string>\n    <string name=\"tag_gps_datestamp\">Отметка даты GPS</string>\n    <string name=\"tag_gps_differential\">Дифференциал GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Ошибка позиционирования GPS H</string>\n    <string name=\"tag_interoperability_index\">Индекс совместимости</string>\n    <string name=\"tag_default_crop_size\">Размер обрезки по умолчанию</string>\n    <string name=\"tag_orf_preview_image_start\">Начало предварительного просмотра изображения</string>\n    <string name=\"tag_orf_preview_image_length\">Длина изображения для предварительного просмотра</string>\n    <string name=\"tag_orf_aspect_frame\">Кадр аспекта</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Нижняя граница датчика</string>\n    <string name=\"tag_rw2_sensor_left_border\">Левая граница датчика</string>\n    <string name=\"tag_rw2_sensor_right_border\">Правая граница датчика</string>\n    <string name=\"tag_rw2_sensor_top_border\">Верхняя граница датчика</string>\n    <string name=\"repeat_text\">Повторять текст</string>\n    <string name=\"repeat_text_sub\">Текущий текст будет повторяться до конца пути вместо однократного рисования</string>\n    <string name=\"dash_size\">Размер штриха</string>\n    <string name=\"draw_mode_image_sub\">Использовать выбранное изображение, чтобы нарисовать его по заданному пути</string>\n    <string name=\"draw_image_sub\">Это изображение будет использоваться в качестве повторяющейся записи нарисованного пути</string>\n    <string name=\"outlined_triangle_sub\">Рисует очерченный треугольник от начальной точки до конечной точки</string>\n    <string name=\"triangle_sub\">Рисует очерченный треугольник от начальной точки до конечной точки</string>\n    <string name=\"outlined_triangle\">Очерченный треугольник</string>\n    <string name=\"triangle\">Треугольник</string>\n    <string name=\"polygon_sub\">Рисует многоугольник от начальной точки до конечной точки</string>\n    <string name=\"polygon\">Многоугольник</string>\n    <string name=\"outlined_polygon\">Контурный многоугольник</string>\n    <string name=\"outlined_polygon_sub\">Рисует контурный многоугольник от начальной точки до конечной точки</string>\n    <string name=\"vertices\">Вершины</string>\n    <string name=\"draw_regular_polygon\">Рисовать правильный многоугольник</string>\n    <string name=\"draw_regular_polygon_sub\">Нарисуйте многоугольник правильной формы, а не произвольной формы</string>\n    <string name=\"star_sub\">Рисует звезду от начальной точки до конечной точки</string>\n    <string name=\"star\">Звезда</string>\n    <string name=\"outlined_star\">Обведенная звезда</string>\n    <string name=\"outlined_star_sub\">Рисует контурную звезду от начальной точки до конечной точки</string>\n    <string name=\"inner_radius_ratio\">Отношение внутреннего радиуса</string>\n    <string name=\"draw_regular_star\">Рисовать правильную звезду</string>\n    <string name=\"draw_regular_star_sub\">Нарисуйте звезду правильной формы, а не свободной</string>\n    <string name=\"antialias\">Сглаживание</string>\n    <string name=\"antialias_sub\">Включает сглаживание для предотвращения острых краев</string>\n    <string name=\"open_edit_instead_of_preview\">Открывать редактирование вместо предварительного просмотра</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Когда вы выбираете изображение для открытия (предварительного просмотра) в ImageToolbox, вместо предварительного просмотра откроется лист редактирования выбора</string>\n    <string name=\"document_scanner\">Сканер документов</string>\n    <string name=\"document_scanner_sub\">Сканируйте документы и создавайте из них PDF или отдельные изображения</string>\n    <string name=\"click_to_start_scanning\">Нажмите, чтобы начать сканирование</string>\n    <string name=\"start_scanning\">Начать сканирование</string>\n    <string name=\"save_as_pdf\">Сохранить как PDF</string>\n    <string name=\"share_as_pdf\">Поделиться в формате PDF</string>\n    <string name=\"options_below_is_for_images\">Параметры ниже предназначены для сохранения изображений, а не PDF</string>\n    <string name=\"equalize_histogram_hsv\">Выровнять HSV гистограмму</string>\n    <string name=\"equalize_histogram\">Выровнять гистограмму</string>\n    <string name=\"enter_percentage\">Введите процент</string>\n    <string name=\"allow_enter_by_text_field\">Разрешить ввод по текстовому полю</string>\n    <string name=\"scale_color_space\">Цветовое пространство увеличения</string>\n    <string name=\"linear\">Линейное</string>\n    <string name=\"equalize_histogram_pixelation\">Выравнивание гистограммы пикселизации</string>\n    <string name=\"grid_size_x\">Размер сетки X</string>\n    <string name=\"grid_size_y\">Размер сетки Y</string>\n    <string name=\"equalize_histogram_adaptive\">Адаптивное выравнивание гистограммы</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Адаптивное выравнивание гистограммы LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Адаптивное выравнивание гистограммы LAB</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Обрезать по содержимому</string>\n    <string name=\"frame_color\">Цвет рамки</string>\n    <string name=\"color_to_ignore\">Цвет для игнорирования</string>\n    <string name=\"template\">Шаблон</string>\n    <string name=\"no_template_filters\">Нет добавленных шаблонных фильтров</string>\n    <string name=\"create_new\">Создать новый</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Сканированный QR-код не является допустимым шаблоном фильтра</string>\n    <string name=\"scan_qr_code\">Сканировать QR-код</string>\n    <string name=\"opened_file_have_no_filter_template\">Выбранный файл не содержит данных шаблона фильтра</string>\n    <string name=\"create_template\">Создать шаблон</string>\n    <string name=\"template_name\">Имя шаблона</string>\n    <string name=\"select_template_preview\">Это изображение будет использоваться для предварительного просмотра этого шаблона фильтра</string>\n    <string name=\"template_filter\">Фильтр шаблона</string>\n    <string name=\"as_qr_code\">Как изображение QR-кода</string>\n    <string name=\"as_file\">Как файл</string>\n    <string name=\"save_as_file\">Сохранить как файл</string>\n    <string name=\"save_as_qr_code_image\">Сохранить как изображение QR-кода</string>\n    <string name=\"delete_template\">Удалить шаблон</string>\n    <string name=\"delete_template_warn\">Вы собираетесь удалить выбранный фильтр шаблона. Эта операция не может быть отменена</string>\n    <string name=\"added_filter_template\">Добавлен фильтр шаблона с именем \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Предварительный просмотр фильтра</string>\n    <string name=\"qr_code\">QR и баркоды</string>\n    <string name=\"qr_code_sub\">Сканируйте QR-код, чтобы получить его содержимое, или вставьте свою строку для генерации нового кода</string>\n    <string name=\"code_content\">Содержимое кода</string>\n    <string name=\"scan_qr_code_to_replace_content\">Сканируйте любой баркод, чтобы заменить содержимое в поле, или введите что-нибудь для генерации нового баркода выбранного типа</string>\n    <string name=\"qr_description\">Описание QR</string>\n    <string name=\"min\">Мин</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Разрешите доступ к камере в настройках для сканирования QR-кода</string>\n    <string name=\"cubic\">Кубический</string>\n    <string name=\"bspline\">Би-Сплайн</string>\n    <string name=\"hamming\">Хэмминг</string>\n    <string name=\"hanning\">Хэннинг</string>\n    <string name=\"blackman\">Блэкман</string>\n    <string name=\"welch\">Уэлч</string>\n    <string name=\"quadric\">Квадратический</string>\n    <string name=\"gaussian\">Гауссовский</string>\n    <string name=\"sphinx\">Сфинкс</string>\n    <string name=\"bartlett\">Бартлетт</string>\n    <string name=\"robidoux\">Робиду</string>\n    <string name=\"robidoux_sharp\">Робиду Шарп</string>\n    <string name=\"spline16\">Сплайн 16</string>\n    <string name=\"spline36\">Сплайн 36</string>\n    <string name=\"spline64\">Сплайн 64</string>\n    <string name=\"kaiser\">Кайзер</string>\n    <string name=\"bartlett_hann\">Бартлетт-Ханн</string>\n    <string name=\"box\">Блочный</string>\n    <string name=\"bohman\">Боман</string>\n    <string name=\"lanczos2\">Ланцош 2</string>\n    <string name=\"lanczos3\">Ланцош 3</string>\n    <string name=\"lanczos4\">Ланцош 4</string>\n    <string name=\"lanczos2_jinc\">Ланцош 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Ланцош 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Ланцош 4 Jinc</string>\n    <string name=\"cubic_sub\">Кубическая интерполяция обеспечивает более гладкое масштабирование, учитывая ближайшие 16 пикселей, давая лучшие результаты, чем билинейная</string>\n    <string name=\"bspline_sub\">Использует кусочно-определенные полиномиальные функции для плавной интерполяции и аппроксимации кривой или поверхности, гибкое и непрерывное представление формы</string>\n    <string name=\"hamming_sub\">Оконная функция, используемая для уменьшения спектральных утечек путем сужения краев сигнала, полезна в обработке сигналов</string>\n    <string name=\"hanning_sub\">Вариант окна Ханна, обычно используемый для уменьшения спектральных утечек в приложениях обработки сигналов</string>\n    <string name=\"blackman_sub\">Оконная функция, обеспечивающая хорошее частотное разрешение за счет минимизации спектральных утечек, часто используемая в обработке сигналов</string>\n    <string name=\"welch_sub\">Оконная функция, разработанная для обеспечения хорошего частотного разрешения с уменьшенными спектральными утечками, часто используемая в приложениях обработки сигналов</string>\n    <string name=\"quadric_sub\">Метод, использующий квадратическую функцию для интерполяции, обеспечивая плавные и непрерывные результаты</string>\n    <string name=\"gaussian_sub\">Метод интерполяции, применяющий гауссовскую функцию, полезный для сглаживания и уменьшения шума в изображениях</string>\n    <string name=\"sphinx_sub\">Продвинутый метод пересэмплирования, обеспечивающий высококачественную интерполяцию с минимальными артефактами</string>\n    <string name=\"bartlett_sub\">Треугольная оконная функция, используемая в обработке сигналов для уменьшения спектральных утечек</string>\n    <string name=\"robidoux_sub\">Высококачественный метод интерполяции, оптимизированный для изменения размера естественных изображений, балансирующий резкость и гладкость</string>\n    <string name=\"robidoux_sharp_sub\">Более резкий вариант метода Робиду, оптимизированный для четкого изменения размера изображений</string>\n    <string name=\"spline16_sub\">Метод интерполяции на основе сплайнов, обеспечивающий плавные результаты с использованием 16-кратного фильтра</string>\n    <string name=\"spline36_sub\">Метод интерполяции на основе сплайнов, обеспечивающий плавные результаты с использованием 36-кратного фильтра</string>\n    <string name=\"spline64_sub\">Метод интерполяции на основе сплайнов, обеспечивающий плавные результаты с использованием 64-кратного фильтра</string>\n    <string name=\"kaiser_sub\">Метод интерполяции, использующий окно Кайзера, обеспечивающий хороший контроль над компромиссом между шириной главного лепестка и уровнем бокового лепестка</string>\n    <string name=\"bartlett_hann_sub\">Гибридная оконная функция, объединяющая окна Бартлетта и Ханна, используемая для уменьшения спектральных утечек в обработке сигналов</string>\n    <string name=\"box_sub\">Простой метод пересэмплирования, использующий среднее значение ближайших значений пикселей, часто приводящий к блочному виду</string>\n    <string name=\"bohman_sub\">Оконная функция, используемая для уменьшения спектральных утечек, обеспечивающая хорошее частотное разрешение в приложениях обработки сигналов</string>\n    <string name=\"lanczos2_sub\">Метод пересэмплирования, использующий 2-лепестковый фильтр Ланцоша для высококачественной интерполяции с минимальными артефактами</string>\n    <string name=\"lanczos3_sub\">Метод пересэмплирования, использующий 3-лепестковый фильтр Ланцоша для высококачественной интерполяции с минимальными артефактами</string>\n    <string name=\"lanczos4_sub\">Метод пересэмплирования, использующий 4-лепестковый фильтр Ланцоша для высококачественной интерполяции с минимальными артефактами</string>\n    <string name=\"lanczos2_jinc_sub\">Вариант фильтра Ланцош 2, использующий функцию джинка, обеспечивающий высококачественную интерполяцию с минимальными артефактами</string>\n    <string name=\"lanczos3_jinc_sub\">Вариант фильтра Ланцош 3, использующий функцию джинка, обеспечивающий высококачественную интерполяцию с минимальными артефактами</string>\n    <string name=\"lanczos4_jinc_sub\">Вариант фильтра Ланцош 4, использующий функцию джинка, обеспечивающий высококачественную интерполяцию с минимальными артефактами</string>\n    <string name=\"allow_enter_by_text_field_sub\">Включает текстовое поле за выбором пресетов, чтобы вводить их на лету</string>\n    <string name=\"ewa_hanning\">Ханнинг EWA</string>\n    <string name=\"ewa_hanning_sub\">Вариант фильтра Ханнинг с эллиптическим взвешенным средним (EWA) для плавной интерполяции и ресемплинга</string>\n    <string name=\"ewa_robidoux\">Робиду EWA</string>\n    <string name=\"ewa_robidoux_sub\">Вариант фильтра Робиду с эллиптическим взвешенным средним (EWA) для высококачественного ресемплинга</string>\n    <string name=\"ewa_blackman\">Блэкман EWA</string>\n    <string name=\"ewa_blackman_sub\">Вариант фильтра Блэкман с эллиптическим взвешенным средним (EWA) для минимизации артефактов звона</string>\n    <string name=\"ewa_quadric\">Квадратический EWA</string>\n    <string name=\"ewa_quadric_sub\">Вариант квадратического фильтра с эллиптическим взвешенным средним (EWA) для плавной интерполяции</string>\n    <string name=\"ewa_robidoux_sharp\">Робиду Шарп EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Вариант фильтра Робиду Шарп с эллиптическим взвешенным средним (EWA) для более четких результатов</string>\n    <string name=\"ewa_lanczos3_jinc\">Ланцош 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Вариант фильтра Ланцош 3 Jinc с эллиптическим взвешенным средним (EWA) для высококачественного ресемплинга с уменьшением алиасинга</string>\n    <string name=\"ginseng\">Женьшень</string>\n    <string name=\"ginseng_sub\">Фильтр ресемплинга, разработанный для высококачественной обработки изображений с хорошим балансом резкости и плавности</string>\n    <string name=\"ewa_ginseng\">Женьшень EWA</string>\n    <string name=\"ewa_ginseng_sub\">Вариант фильтра Женьшень с эллиптическим взвешенным средним (EWA) для улучшенного качества изображения</string>\n    <string name=\"ewa_lanczos_sharp\">Ланцош Резкий EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Вариант фильтра Ланцош Резкий с эллиптическим взвешенным средним (EWA) для достижения резких результатов с минимальными артефактами</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Ланцош 4 Самый Резкий EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Вариант фильтра Ланцош 4 Самый Резкий с эллиптическим взвешенным средним (EWA) для крайне резкого ресемплинга изображений</string>\n    <string name=\"ewa_lanczos_soft\">Ланцош Мягкий EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Вариант фильтра Ланцош Мягкий с эллиптическим взвешенным средним (EWA) для более плавного ресемплинга изображений</string>\n    <string name=\"haasn_soft\">Хаасн Мягкий</string>\n    <string name=\"haasn_soft_sub\">Фильтр ресемплинга, разработанный Хаасн для плавного масштабирования изображений без артефактов</string>\n    <string name=\"format_conversion\">Конвертация формата</string>\n    <string name=\"dismiss_forever\">Не показывать</string>\n    <string name=\"image_stacking_sub\">Накладывайте изображения друг на друга с выбранными режимами смешивания</string>\n    <string name=\"add_image\">Добавить изображение</string>\n    <string name=\"format_conversion_sub\">Конвертируйте набор изображений из одного формата в другой</string>\n    <string name=\"image_stacking\">Наложение изображений</string>\n    <string name=\"bins_count\">Количество ячеек</string>\n    <string name=\"clahe_hsl\">Клахе HSL</string>\n    <string name=\"clahe_hsv\">Клахе HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Адаптивное выравнивание гистограммы HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Адаптивное выравнивание гистограммы HSV</string>\n    <string name=\"edge_mode\">Режим краев</string>\n    <string name=\"clip\">Обрезка</string>\n    <string name=\"wrap\">Обтекание</string>\n    <string name=\"color_blind_scheme\">Схема для дальтоников</string>\n    <string name=\"color_blind_scheme_sub\">Выберите режим для адаптации цветов темы для данного варианта дальтонизма</string>\n    <string name=\"protanomaly_sub\">Трудности в различении красных и зеленых оттенков</string>\n    <string name=\"deuteranomaly_sub\">Трудности в различении зеленых и красных оттенков</string>\n    <string name=\"tritanomaly_sub\">Трудности в различении синих и желтых оттенков</string>\n    <string name=\"protanopia_sub\">Неспособность воспринимать красные оттенки</string>\n    <string name=\"deuteranopia_sub\">Неспособность воспринимать зеленые оттенки</string>\n    <string name=\"tritanopia_sub\">Неспособность воспринимать синие оттенки</string>\n    <string name=\"achromatomaly_sub\">Сниженная чувствительность ко всем цветам</string>\n    <string name=\"achromatopsia_sub\">Полная цветовая слепота, восприятие только оттенков серого</string>\n    <string name=\"lagrange_2\">Лагранж 2</string>\n    <string name=\"lagrange_2_sub\">Интерполяционный фильтр Лагранжа порядка 2, подходящий для высококачественного масштабирования изображений с плавными переходами</string>\n    <string name=\"lagrange_3\">Лагранж 3</string>\n    <string name=\"lagrange_3_sub\">Интерполяционный фильтр Лагранжа порядка 3, обеспечивающий лучшую точность и более плавные результаты при масштабировании изображений</string>\n    <string name=\"lanczos_6\">Ланцош 6</string>\n    <string name=\"lanczos_6_sub\">Фильтр ресемплинга Ланцоша с более высоким порядком 6, обеспечивающий более резкое и точное масштабирование изображений</string>\n    <string name=\"lanczos_6_jinc\">Ланцош 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Вариант фильтра Ланцоша 6, использующий функцию Jinc для улучшения качества ресемплинга изображений</string>\n    <string name=\"not_use_color_blind_scheme\">Не использовать схему дальтонизма</string>\n    <string name=\"sigmoidal\">Сигмоидальное</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Цвета будут такими же как в теме</string>\n    <string name=\"linear_box_blur\">Линейное размытие прямоугольником</string>\n    <string name=\"linear_tent_blur\">Линейное размытие тентом</string>\n    <string name=\"linear_gaussian_box_blur\">Линейное размытие прямоугольником по Гауссу</string>\n    <string name=\"linear_stack_blur\">Линейное размытие стеком</string>\n    <string name=\"gaussian_box_blur\">Размытие прямоугольником по Гауссу</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Следующее быстрое линейное размытие по Гауссу</string>\n    <string name=\"linear_fast_gaussian_blur\">Линейное быстрое размытие по Гауссу</string>\n    <string name=\"draw_filter_sub\">Выберите один фильтр, чтобы использовать его в качестве краски</string>\n    <string name=\"linear_gaussian_blur\">Линейное размытие по Гауссу</string>\n    <string name=\"replace_filter\">Заменить фильтр</string>\n    <string name=\"pick_filter_info\">Выберите фильтр ниже, чтобы использовать его в качестве кисти в своем наброске</string>\n    <string name=\"tiff_compression_scheme\">Схема компрессии TIFF</string>\n    <string name=\"low_poly\">Низкая полигональность</string>\n    <string name=\"sand_painting\">Рисование песком</string>\n    <string name=\"image_splitting\">Разделение изображения</string>\n    <string name=\"image_splitting_sub\">Разделите изображение по строкам или столбцам</string>\n    <string name=\"center\">Центр</string>\n    <string name=\"top_left\">Верхний левый</string>\n    <string name=\"top_right\">Верхний правый</string>\n    <string name=\"bottom_left\">Нижний левый</string>\n    <string name=\"bottom_right\">Нижний правый</string>\n    <string name=\"top_center\">Верхний центр</string>\n    <string name=\"center_right\">Правый центр</string>\n    <string name=\"bottom_center\">Нижний центр</string>\n    <string name=\"center_left\">Левый центр</string>\n    <string name=\"import_word\">Импорт</string>\n    <string name=\"fit_to_bounds\">Вписать в границы</string>\n    <string name=\"fit_to_bounds_sub\">Объедините режим изменения размера обрезки с этим параметром для достижения желаемого поведения (обрезка/подгонка по соотношению сторон)</string>\n    <string name=\"languages_imported\">Языки успешно импортированы</string>\n    <string name=\"backup_ocr_models\">Резервное копирование моделей OCR</string>\n    <string name=\"export\">Экспорт</string>\n    <string name=\"position\">Расположение</string>\n    <string name=\"target_image\">Целевое изображение</string>\n    <string name=\"palette_transfer\">Перенос палитры</string>\n    <string name=\"enhanced_oil\">Улучшенное масло</string>\n    <string name=\"simple_old_tv\">Простой старый телевизор</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Готэм</string>\n    <string name=\"simple_sketch\">Простой эскиз</string>\n    <string name=\"soft_glow\">Мягкое свечение</string>\n    <string name=\"color_poster\">Цветной постер</string>\n    <string name=\"tri_tone\">Три тона</string>\n    <string name=\"third_color\">Третий цвет</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">В горошек</string>\n    <string name=\"clustered_2x2_dithering\">Кластерное 2x2 дизерирование</string>\n    <string name=\"clustered_4x4_dithering\">Кластерное 4x4 дизерирование</string>\n    <string name=\"clustered_8x8_dithering\">Кластерное 8x8 дизерирование</string>\n    <string name=\"yililoma_dithering\">Дизерирование Yililoma</string>\n    <string name=\"no_favorite_options_selected\">Не выбрано ни одной из любимых опций, добавьте их на странице инструментов</string>\n    <string name=\"add_favorites\">Добавить в избранное</string>\n    <string name=\"harmony_complementary\">Комплементарная</string>\n    <string name=\"harmony_analogous\">Аналоговая</string>\n    <string name=\"harmony_triadic\">Триадная</string>\n    <string name=\"harmony_split_complementary\">Разделенная комплементарная</string>\n    <string name=\"harmony_tetradic\">Тетрадная</string>\n    <string name=\"harmony_square\">Квадратная</string>\n    <string name=\"harmony_analogous_complementary\">Аналоговая + комплементарная</string>\n    <string name=\"color_tools\">Инструменты цвета</string>\n    <string name=\"color_tools_sub\">Смешивание, создание оттенков и многое другое</string>\n    <string name=\"color_harmonies\">Цветовые гармонии</string>\n    <string name=\"color_shading\">Тонирование цвета</string>\n    <string name=\"variation\">Вариация</string>\n    <string name=\"tints\">Оттенки</string>\n    <string name=\"tones\">Тоны</string>\n    <string name=\"shades\">Тени</string>\n    <string name=\"color_mixing\">Смешивание цветов</string>\n    <string name=\"color_info\">Информация о цвете</string>\n    <string name=\"selected_color\">Выбранный цвет</string>\n    <string name=\"color_to_mix\">Цвет для смешивания</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Невозможно использовать monet при включенных динамических цветах</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Целевое изображение LUT</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"soft_elegance\">Мягкая элегантность</string>\n    <string name=\"soft_elegance_variant\">Вариант мягкой элегантности</string>\n    <string name=\"palette_transfer_variant\">Вариант переноса палитры</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Целевой 3D LUT файл (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Свет свечи</string>\n    <string name=\"drop_blues\">Понижение синих</string>\n    <string name=\"edgy_amber\">Острый янтарь</string>\n    <string name=\"fall_colors\">Осенние цвета</string>\n    <string name=\"film_stock_50\">Пленочный материал 50</string>\n    <string name=\"foggy_night\">Туманная ночь</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Получить нейтральное изображение LUT</string>\n    <string name=\"save_empty_lut_sub\">Сначала используйте ваше любимое приложение для редактирования фото, чтобы применить фильтр к нейтральному LUT, который вы можете получить здесь. Чтобы это работало правильно, цвет каждого пикселя не должен зависеть от других пикселей (например, размытие не сработает). Как только будете готовы, используйте ваше новое изображение LUT в качестве ввода для 512*512 фильтра LUT</string>\n    <string name=\"pop_art\">Поп-арт</string>\n    <string name=\"celluloid\">Целлулоид</string>\n    <string name=\"coffee\">Кофе</string>\n    <string name=\"golden_forest\">Золотой лес</string>\n    <string name=\"greenish\">Зеленоватый</string>\n    <string name=\"retro_yellow\">Ретро-желтый</string>\n    <string name=\"manage_storage_extra_types\">Нет полного доступа к файлам</string>\n    <string name=\"enable_timestamps_to_format_them\">Включите временные метки, чтобы выбрать их формат</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Предоставьте доступ к камере в настройках для сканирования сканера документов</string>\n    <string name=\"links\">Ссылки</string>\n    <string name=\"links_preview_sub\">Позволяет предварительно просматривать ссылки в местах, где можно получить текст (QR-код, OCR и т. д.)</string>\n    <string name=\"ico_size_warning\">Файлы Ico можно сохранять только с максимальным размером 256*256, большие значения будут принудительно уменьшены в конечном изображении</string>\n    <string name=\"webp_type_to_image\">WEBP в изображения</string>\n    <string name=\"webp_type_to_image_sub\">Конвертировать файл WEBP в пакет изображений</string>\n    <string name=\"webp_type_to_webp_sub\">Конвертировать пакет изображений в файл WEBP</string>\n    <string name=\"webp_type_to_webp\">Изображения в WEBP</string>\n    <string name=\"select_webp_image_to_start\">Выберите изображение WEBP, чтобы начать</string>\n    <string name=\"default_draw_color\">Цвет рисования по умолчанию</string>\n    <string name=\"manage_storage_extra_types_sub\">Разрешите доступ ко всем файлам для просмотра JXL, QOI и других изображений, которые не распознаются системой Android как файлы изображений. Без предоставления разрешения вы не сможете увидеть эти изображения здесь</string>\n    <string name=\"default_draw_path_mode\">Режим рисования пути по умолчанию</string>\n    <string name=\"add_timestamp_sub\">Включает добавление временной метки к имени выходного файла</string>\n    <string name=\"add_timestamp\">Добавить временную метку</string>\n    <string name=\"formatted_timestamp\">Форматированная временная метка</string>\n    <string name=\"formatted_timestamp_sub\">Включить форматирование временной метки в имени выходного файла вместо базовых миллисекунд</string>\n    <string name=\"links_preview\">Предпросмотр ссылок</string>\n    <string name=\"gif_type_to_webp\">GIF в WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Конвертируйте GIF-изображения в анимированные WEBP-изображения</string>\n    <string name=\"webp_tools\">WEBP Инструменты</string>\n    <string name=\"webp_tools_sub\">Конвертируйте изображения в анимированные изображения WEBP или извлекайте кадры из заданной анимации WEBP</string>\n    <string name=\"one_time_save_location\">Однократное сохранение местоположения</string>\n    <string name=\"recently_used\">Недавно использовано</string>\n    <string name=\"one_time_save_location_sub\">Просмотр и редактирование мест одноразового сохранения, которые можно использовать с помощью длительного нажатия кнопки сохранения практически во всех вариантах</string>\n    <string name=\"ci_channel\">CI-канал</string>\n    <string name=\"group\">Группа</string>\n    <string name=\"image_toolbox_in_telegram\">ImageToolbox в Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Присоединяйтесь к нашему чату, где вы можете обсудить все, что вы хотите, а также можете зайти в канал CI, где я публикую бета-версии и объявления</string>\n    <string name=\"ci_channel_sub\">Получайте уведомления о новых версиях приложения и читайте объявления</string>\n    <string name=\"custom_options\">Пользовательские параметры</string>\n    <string name=\"custom_params_info\">Параметры следует вводить по следующему шаблону: \\\"--{название_опции} {значение}\\\"</string>\n    <string name=\"auto_crop\">Автоматическая обрезка</string>\n    <string name=\"free_corners\">Свободные углы</string>\n    <string name=\"coerce_points_to_image_bounds\">Приведение точек к границам изображения</string>\n    <string name=\"spot_heal\">Восстанавливающая кисть</string>\n    <string name=\"use_circle_kernel\">Использовать ядро круга</string>\n    <string name=\"opening\">Открытие</string>\n    <string name=\"closing\">Закрытие</string>\n    <string name=\"morphological_gradient\">Морфологический градиент</string>\n    <string name=\"top_hat\">Цилиндр</string>\n    <string name=\"black_hat\">Черная шляпа</string>\n    <string name=\"fit_description\">Вписывает изображение в заданный размер и добавляет блюр/цвет на задний фон</string>\n    <string name=\"tools_arrangement\">Расположение инструментов</string>\n    <string name=\"group_tools_by_type\">Группировать инструменты по типу</string>\n    <string name=\"group_tools_by_type_sub\">Группирует инструменты на главном экране на основе их типа вместо пользовательского расположения</string>\n    <string name=\"default_values\">Значения по умолчанию</string>\n    <string name=\"system_bars_visibility\">Видимость системных панелей</string>\n    <string name=\"show_system_bars_by_swipe\">Показывать системные панели по свайпу</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Включает возможность показать скрытые системные панели по свайпу</string>\n    <string name=\"auto\">Авто</string>\n    <string name=\"hide_all\">Скрыть все</string>\n    <string name=\"show_all\">Показать все</string>\n    <string name=\"hide_nav_bar\">Скрыть панель навигации</string>\n    <string name=\"hide_status_bar\">Скрыть панель уведомлений</string>\n    <string name=\"noise_generation\">Генерация шума</string>\n    <string name=\"noise_generation_sub\">Создание различных шумов, таких как Perlin или других типов</string>\n    <string name=\"frequency\">Частота</string>\n    <string name=\"noise_type\">Тип шума</string>\n    <string name=\"rotation_type\">Тип вращения</string>\n    <string name=\"fractal_type\">Тип фрактала</string>\n    <string name=\"octaves\">Октавы</string>\n    <string name=\"lacunarity\">Лакунарность</string>\n    <string name=\"gain\">Прирост</string>\n    <string name=\"weighted_strength\">Взвешенная сила</string>\n    <string name=\"ping_pong_strength\">Сила пинг-понга</string>\n    <string name=\"return_type\">Тип возврата</string>\n    <string name=\"jitter\">Джиттер</string>\n    <string name=\"domain_warp\">Деформация домена</string>\n    <string name=\"alignment\">Выравнивание</string>\n    <string name=\"saved_to_custom\">Сохранено в папке с пользовательским именем</string>\n    <string name=\"tone_curves\">Тоновые кривые</string>\n    <string name=\"reset_curves\">Сбросить кривые</string>\n    <string name=\"reset_curves_sub\">Кривые будут возвращены к значениям по умолчанию</string>\n    <string name=\"line_style\">Стиль линии</string>\n    <string name=\"gap_size\">Размер зазора</string>\n    <string name=\"dashed\">Пунктир</string>\n    <string name=\"dot_dashed\">Точка-пунктир</string>\n    <string name=\"dot_dashed_sub\">Рисует точка-пунктирную линию по заданному пути</string>\n    <string name=\"defaultt_sub\">Просто обычные прямые линии</string>\n    <string name=\"stamped_sub\">Рисует выбранные фигуры вдоль контура с указанным интервалом</string>\n    <string name=\"zigzag_sub\">Рисует волнистый зигзаг вдоль пути</string>\n    <string name=\"zigzag_ratio\">Отношение зигзага</string>\n    <string name=\"create_shortcut\">Создать ярлык</string>\n    <string name=\"create_shortcut_title\">Выберите инструмент для закрепления</string>\n    <string name=\"create_shortcut_subtitle\">Инструмент будет добавлен на главный экран вашего лаунчера в качестве ярлыка. Используйте его в сочетании с настройкой «Пропустить выбор файла» для достижения необходимого поведения</string>\n    <string name=\"dont_stack_frames\">Не складывайте кадры друг на друга</string>\n    <string name=\"dont_stack_frames_sub\">Позволяет удалять предыдущие кадры, чтобы они не накладывались друг на друга</string>\n    <string name=\"crossfade_sub\">Кадры будут плавно переходить друг в друга</string>\n    <string name=\"crossfade\">Плавный переход</string>\n    <string name=\"crossfade_count\">Количество кадров перехода</string>\n    <string name=\"collage_maker\">Создание коллажей</string>\n    <string name=\"collage_type\">Тип коллажа</string>\n    <string name=\"threshold_one\">Первый порог</string>\n    <string name=\"threshold_two\">Второй порог</string>\n    <string name=\"canny\">Кэнни</string>\n    <string name=\"mirror_101\">Зеркало 101</string>\n    <string name=\"sobel_simple\">Простой Собель</string>\n    <string name=\"helper_grid\">Вспомогательная сетка</string>\n    <string name=\"grid_color\">Цвет сетки</string>\n    <string name=\"cell_width\">Ширина ячейки</string>\n    <string name=\"cell_height\">Высота ячейки</string>\n    <string name=\"compact_selectors\">Компактные селекторы</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Предоставьте камере разрешение в настройках на захват изображения</string>\n    <string name=\"layout\">Макет</string>\n    <string name=\"main_screen_title\">Заголовок главного экрана</string>\n    <string name=\"custom_filename_sub\">Выберите местоположение и имя файла, которые будут использоваться для сохранения текущего изображения</string>\n    <string name=\"distance_function\">Функция дистанции</string>\n    <string name=\"custom_filename\">Пользовательское имя файла</string>\n    <string name=\"collage_maker_sub\">Создавайте различные коллажи до 20 изображений</string>\n    <string name=\"tesseract_options\">Параметры Tesseract</string>\n    <string name=\"tesseract_options_sub\">Применить некоторые входные переменные для Tesseract</string>\n    <string name=\"free_corners_sub\">Обрезайте изображение по полигону, это также исправляет перспективу</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Точки не будут ограничены границами изображения, это полезно для более точной коррекции перспективы</string>\n    <string name=\"mask\">Маска</string>\n    <string name=\"spot_heal_sub\">Заливка с учетом содержимого под нарисованным контуром</string>\n    <string name=\"zigzag\">Зигзаг</string>\n    <string name=\"stamped\">Штамповка</string>\n    <string name=\"dashed_sub\">Рисует пунктирную линию вдоль нарисованного пути с указанным размером зазора</string>\n    <string name=\"enhanced_zoom_blur\">Улучшенное размытие приближением</string>\n    <string name=\"compact_selectors_sub\">Некоторые элементы управления выбором будут использовать компактную компоновку, чтобы занимать меньше места</string>\n    <string name=\"laplacian_simple\">Простой Лапласиан</string>\n    <string name=\"helper_grid_sub\">Отображает вспомогательную сетку над областью рисования, помогающую выполнять точные манипуляции</string>\n    <string name=\"collages_info\">Удерживайте изображение, чтобы поменять местами, перемещайте и масштабируйте для регулировки положения</string>\n    <string name=\"histogram\">Гистограмма</string>\n    <string name=\"histogram_sub\">Гистограмма изображения RGB или яркости, которая поможет вам внести коррективы</string>\n    <string name=\"image_for_histogram\">Это изображение будет использовано для создания гистограмм RGB и яркости</string>\n    <string name=\"constant_rate_factor\">Фактор постоянной скорости (CRF)</string>\n    <string name=\"lut_library_update_sub\">Обновление коллекции LUT (в очередь будут поставлены только новые), которые можно применить после загрузки</string>\n    <string name=\"filter_preview_image\">Предварительный просмотр изображения</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"material_2_sub\">Слайдер на основе Material 2, не современный, простой и понятный</string>\n    <string name=\"material_you_slider_sub\">Современный слайдер Material You, футуристический, свежий, доступный</string>\n    <string name=\"crf_sub\">Значение %1$s означает медленное сжатие, приводящее к относительно небольшому размеру файла. %2$s означает более быстрое сжатие, приводящее к большому размеру файла</string>\n    <string name=\"lut_library\">Библиотека LUT</string>\n    <string name=\"lut_library_sub\">Загрузите коллекцию LUT, которую вы сможете применить после загрузки</string>\n    <string name=\"filter_preview_image_sub\">Изменить предварительный просмотр изображения по умолчанию для фильтров</string>\n    <string name=\"slider_type\">Тип слайдера</string>\n    <string name=\"fancy\">Изысканный</string>\n    <string name=\"fancy_sub\">Пользовательский слайдер с красивым дизайном и анимацией, это слайдер по умолчанию для этого приложения</string>\n    <string name=\"hide\">Скрыть</string>\n    <string name=\"show\">Показать</string>\n    <string name=\"center_align_dialog_buttons_sub\">Кнопки диалогов будут располагаться по центру, а не слева, если это возможно</string>\n    <string name=\"open_source_licenses\">Лицензии с открытым исходным кодом</string>\n    <string name=\"open_source_licenses_sub\">Просмотр лицензий библиотек с открытым исходным кодом, используемых в этом приложении</string>\n    <string name=\"area\">Область</string>\n    <string name=\"area_sub\">Повторная выборка с использованием отношения площади пикселя. Это может быть предпочтительным методом для прореживания изображений, поскольку он дает результаты без муара. Но когда изображение увеличено, это похоже на метод \\\"Nearest\\\"</string>\n    <string name=\"enable_tonemapping\">Включить Tonemapping</string>\n    <string name=\"enter_percent\">Введите %</string>\n    <string name=\"unknown_host\">Невозможно получить доступ к сайту, попробуйте использовать VPN или проверьте правильность URL</string>\n    <string name=\"markup_layers\">Слои разметки</string>\n    <string name=\"markup_layers_sub\">Режим слоев с возможностью свободного размещения изображений, текста и многого другого</string>\n    <string name=\"edit_layer\">Редактировать слой</string>\n    <string name=\"layers_on_image\">Слои на изображении</string>\n    <string name=\"layers_on_image_sub\">Использовать изображение в качестве фона и добавлять различные слои поверх него</string>\n    <string name=\"layers_on_background\">Слои на фон</string>\n    <string name=\"layers_on_background_sub\">То же, что и первый вариант, но с цветом вместо изображения</string>\n    <string name=\"beta\">Бета</string>\n    <string name=\"fast_settings_side\">Сторона быстрых настроек</string>\n    <string name=\"fast_settings_side_sub\">Добавить плавающую полосу на выбранной стороне при редактировании изображений, которая откроет быстрые настройки при нажатии</string>\n    <string name=\"clear_selection\">Очистить выделение</string>\n    <string name=\"settings_group_visibility_hidden\">Группа настроек \\\"%1$s\\\" будет свернута по умолчанию</string>\n    <string name=\"settings_group_visibility_visible\">Группа настроек \\\"%1$s\\\" будет развернута по умолчанию</string>\n    <string name=\"base_64_tools\">Инструменты Base64</string>\n    <string name=\"base_64_tools_sub\">Декодировать Строка Base64 в изображение или кодирование изображения в формат Base64</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">Предоставленное значение не является допустимой строкой Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">Невозможно скопировать пустую или недопустимую строку Base64</string>\n    <string name=\"paste_base_64\">Вставить Base64</string>\n    <string name=\"copy_base_64\">Копировать Base64</string>\n    <string name=\"base_64_tips\">Загрузите изображение, чтобы скопировать или сохранить строку Base64. Если у вас есть сама строка, вы можете вставить ее выше, чтобы получить изображение</string>\n    <string name=\"save_base_64\">Сохранить Base64</string>\n    <string name=\"share_base_64\">Поделиться Base64</string>\n    <string name=\"options\">Параметры</string>\n    <string name=\"actions\">Действия</string>\n    <string name=\"import_base_64\">Импортировать Base64</string>\n    <string name=\"base_64_actions\">Действия Base64</string>\n    <string name=\"add_outline\">Добавить обводку</string>\n    <string name=\"add_outline_sub\">Добавляет обводку вокруг текста с указанным цветом и шириной</string>\n    <string name=\"outline_color\">Цвет контура</string>\n    <string name=\"outline_size\">Размер контура</string>\n    <string name=\"rotation\">Вращение</string>\n    <string name=\"checksum_as_filename\">Контрольная сумма как имя файла</string>\n    <string name=\"checksum_as_filename_sub\">Выходные изображения будут иметь имя, соответствующее их контрольной сумме</string>\n    <string name=\"center_align_dialog_buttons\">Центрирование диалоговых кнопок</string>\n    <string name=\"apply\">Применить</string>\n    <string name=\"free_software_partner\">Бесплатное ПО (Партнер)</string>\n    <string name=\"free_software_partner_sub\">Больше полезного ПО в партнерском канале приложений Android</string>\n    <string name=\"checksum\">Контрольная сумма</string>\n    <string name=\"checksum_tools\">Инструменты контрольной суммы</string>\n    <string name=\"checksum_tools_sub\">Сравнивайте контрольные суммы, вычисляйте хеши, создавайте шестнадцатеричные строки из файлов, используя различные алгоритмы хеширования</string>\n    <string name=\"calculate\">Рассчитать</string>\n    <string name=\"algorithms\">Алгоритм</string>\n    <string name=\"text_hash\">Текстовый хэш</string>\n    <string name=\"enter_text_to_checksum\">Введите текст для расчета его контрольной суммы на основе выбранного алгоритма</string>\n    <string name=\"checksum_to_compare\">Контрольная сумма для сравнения</string>\n    <string name=\"source_checksum\">Исходная контрольная сумма</string>\n    <string name=\"difference\">Различие</string>\n    <string name=\"match_sub\">Контрольные суммы равны, это может быть безопасно</string>\n    <string name=\"pick_file_to_checksum\">Выберите файл для расчета его контрольной суммы на основе выбранного алгоритма</string>\n    <string name=\"match\">Совпадение!</string>\n    <string name=\"difference_sub\">Контрольные суммы не равны, файл может быть небезопасен!</string>\n    <string name=\"batch_compare\">Пакетное сравнение</string>\n    <string name=\"pick_files_to_checksum\">Выберите файл/файлы для расчета его контрольной суммы на основе выбранного алгоритма</string>\n    <string name=\"mesh_gradients\">Сеточные градиенты</string>\n    <string name=\"mesh_gradients_sub\">Создание градиентной сетки с заданным количеством узлов и разрешением</string>\n    <string name=\"collection_mesh_gradients_sub\">Посмотрите Онлайн коллекцию сеточных градиентов</string>\n    <string name=\"error_while_saving\">Ошибка во время попытки сохранения, попробуйте изменить директорию сохранения в настройках</string>\n    <string name=\"pick_files\">Выберите файлы</string>\n    <string name=\"pick_directory\">Выберите директорию</string>\n    <string name=\"edit_exif_screen\">Редактировать EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Изменить метаданные одного изображения без повторного сжатия</string>\n    <string name=\"edit_exif_tag\">Нажмите, чтобы редактировать доступные теги</string>\n    <string name=\"change_sticker\">Изменить наклейку</string>\n    <string name=\"head_length_scale\">Коэффицент длины наконечника</string>\n    <string name=\"stamp\">Штамп</string>\n    <string name=\"timestamp\">Временная метка</string>\n    <string name=\"format_pattern\">Шаблон форматирования</string>\n    <string name=\"padding\">Отступ</string>\n    <string name=\"import_font\">Импортировать шрифт (TTF/OTF)</string>\n    <string name=\"export_fonts\">Экспорт шрифтов</string>\n    <string name=\"wrong_font\">Только TTF шрифты могут быть импортированы</string>\n    <string name=\"imported_fonts\">Импортированные шрифты</string>\n    <string name=\"filename_is_not_set\">Имя файла не задано</string>\n    <string name=\"fit_width\">Вписать ширину</string>\n    <string name=\"fit_height\">Вписать высоту</string>\n    <string name=\"none\">Ничего</string>\n    <string name=\"custom_pages\">Пользовательские страницы</string>\n    <string name=\"pages_selection\">Выбор страниц</string>\n    <string name=\"tool_exit_confirmation\">Подтверждение закрытия инструмента</string>\n    <string name=\"tool_exit_confirmation_sub\">Если у вас есть несохраненные изменения при использовании определенных инструментов и вы пытаетесь закрыть их, то будет показано диалоговое окно подтверждения</string>\n    <string name=\"image_cutting\">Вырезание</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"image_cutting_sub\">Вырезать часть изображения и объединить левые части (можно инвертировать) вертикальными или горизонтальными линиями</string>\n    <string name=\"vertical_pivot_line\">Вертикальная линия поворота</string>\n    <string name=\"horizontal_pivot_line\">Горизонтальная линия поворота</string>\n    <string name=\"inverse_selection\">Инвертировать выделение</string>\n    <string name=\"inverse_vertical_selection_sub\">Вертикальная часть будет оставлена, вместо объединения частей вокруг области вырезания</string>\n    <string name=\"inverse_horizontal_selection_sub\">Горизонтальная часть будет оставлена, вместо объединения частей вокруг области вырезания</string>\n    <string name=\"collection_mesh_gradients\">Коллекция сеточных градиентов</string>\n    <string name=\"gradient_maker_type_image_mesh\">Наложение сеточного градиента</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Наложить сеточный градиент на заданные изображения</string>\n    <string name=\"points_customization\">Настройка точек</string>\n    <string name=\"grid_size\">Размер сетки</string>\n    <string name=\"resolution_x\">Разрешение X</string>\n    <string name=\"resolution_y\">Разрешение Y</string>\n    <string name=\"resolution\">Разрешение</string>\n    <string name=\"pixel_by_pixel\">Попиксельно</string>\n    <string name=\"highlight_color\">Цвет подсветки</string>\n    <string name=\"pixel_comparison_type\">Сравнение пикселей Тип</string>\n    <string name=\"scan_barcode\">Отсканируйте штрихкод</string>\n    <string name=\"height_ratio\">Соотношение высоты</string>\n    <string name=\"barcode_type\">Тип штрихкода</string>\n    <string name=\"enforce_bw\">Принудительно ч/б</string>\n    <string name=\"enforce_bw_sub\">Изображение штрихкода будет полностью чёрно-белым и не будет раскрашено темой приложения</string>\n    <string name=\"barcodes_sub\">Отсканируйте любой штрихкод (QR, EAN, AZTEC и т.д.) и получите его содержимое или вставьте свой текст для создания нового</string>\n    <string name=\"no_barcode_found\">Штрихкод не найден</string>\n    <string name=\"generated_barcode_will_be_here\">Сгенерированный штрихкод будет здесь</string>\n    <string name=\"audio_cover_extractor\">Аудиообложки</string>\n    <string name=\"audio_cover_extractor_sub\">Извлечение обложек альбомов из аудиофайлов. Поддерживаются большинство распространённых форматов</string>\n    <string name=\"pick_audio_to_start\">Выберите аудио для начала</string>\n    <string name=\"pick_audio\">Выберите аудио</string>\n    <string name=\"no_covers_found\">Обложки не найдены</string>\n    <string name=\"send_logs\">Отправить логи</string>\n    <string name=\"send_logs_sub\">Нажмите, чтобы поделиться файлом журнала приложения. Это поможет мне выявить и устранить проблему</string>\n    <string name=\"crash_title\">Упс… Что-то пошло не так</string>\n    <string name=\"crash_subtitle\">Вы можете связаться со мной, используя указанные ниже способы, и я постараюсь найти решение\\n(Не забудьте прикрепить логи)</string>\n    <string name=\"ocr_write_to_file\">Записать в файл</string>\n    <string name=\"ocr_write_to_file_sub\">Извлечение текста из пакета изображений и сохранение его в одном текстовом файле</string>\n    <string name=\"ocr_write_to_metadata\">Запись в метаданные</string>\n    <string name=\"ocr_write_to_metadata_sub\">Извлечение теsкста из каждого изображения и его размещение в EXIF-данных соответствующих фотографий</string>\n    <string name=\"invisible_mode\">Невидимый режим</string>\n    <string name=\"invisible_mode_sub\">Использование стеганографии для создания невидимых глазу водяных знаков внутри байтов ваших изображений</string>\n    <string name=\"use_lsb\">Использование LSB</string>\n    <string name=\"use_lsb_sub\">Будет использоваться метод стеганографии LSB (младший значащий бит), в противном случае — FD (частотная область)</string>\n    <string name=\"auto_remove_red_eyes\">Автоматическое удаление красного Глаза</string>\n    <string name=\"password\">Пароль</string>\n    <string name=\"unlock\">Разблокировать</string>\n    <string name=\"pdf_is_protected\">PDF-файл защищён</string>\n    <string name=\"operation_almost_complete\">Операция почти завершена. Если вы отмените сейчас, потребуется начать сначала</string>\n    <string name=\"sort_by_date_modified\">Дата изменения</string>\n    <string name=\"sort_by_date_modified_reversed\">Дата изменения (наоборот)</string>\n    <string name=\"sort_by_size\">Размер</string>\n    <string name=\"sort_by_size_reversed\">Размер (наоборот)</string>\n    <string name=\"sort_by_mime_type\">Тип MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Тип MIME (наоборот)</string>\n    <string name=\"sort_by_extension\">Расширение</string>\n    <string name=\"sort_by_extension_reversed\">Расширение (наоборот)</string>\n    <string name=\"sort_by_date_added\">Дата добавления</string>\n    <string name=\"sort_by_date_added_reversed\">Дата добавления (наоборот)</string>\n    <string name=\"left_to_right\">Слева направо</string>\n    <string name=\"right_to_left\">Справа налево</string>\n    <string name=\"top_to_bottom\">Сверху вниз</string>\n    <string name=\"bottom_to_top\">Снизу вверх</string>\n    <string name=\"liquid_glass\">Жидкое стекло</string>\n    <string name=\"liquid_glass_sub\">Переключатель на основе недавно анонсированной iOS 26 и её системы дизайна «жидкое стекло»</string>\n    <string name=\"pick_image_or_base64\">Выберите изображение или вставьте/импортируйте данные Base64 ниже</string>\n    <string name=\"type_image_link\">Введите ссылку на изображение, чтобы начать</string>\n    <string name=\"paste_link\">Вставить ссылку</string>\n    <string name=\"kaleidoscope\">Калейдоскоп</string>\n    <string name=\"secondary_angle\">Дополнительный угол</string>\n    <string name=\"sides\">Стороны</string>\n    <string name=\"channel_mix\">Микс каналов</string>\n    <string name=\"blue_green\">Сине-зелёный</string>\n    <string name=\"red_blue\">Красный-синий</string>\n    <string name=\"green_red\">Зелёный-красный</string>\n    <string name=\"into_red\">В красный</string>\n    <string name=\"into_green\">В зелёный</string>\n    <string name=\"into_blue\">В синий</string>\n    <string name=\"cyan\">Голубой</string>\n    <string name=\"magenta\">Пурпурный</string>\n    <string name=\"yellow\">Жёлтый</string>\n    <string name=\"color_halftone\">Цветной полутон</string>\n    <string name=\"contour\">Контур</string>\n    <string name=\"levels\">Уровни</string>\n    <string name=\"offset\">Смещение</string>\n    <string name=\"voronoi_crystallize\">Кристаллизация Вороного</string>\n    <string name=\"shape\">Форма</string>\n    <string name=\"stretch\">Растяжение</string>\n    <string name=\"randomness\">Случайность</string>\n    <string name=\"despeckle\">Устранение спеклов</string>\n    <string name=\"diffuse\">Рассеивание</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Второй радиус</string>\n    <string name=\"equalize\">Выровнять</string>\n    <string name=\"glow\">Свечение</string>\n    <string name=\"whirl_and_pinch\">Вихрь и сжатие</string>\n    <string name=\"pointillize\">Пунктирование</string>\n    <string name=\"border_color\">Цвет границы</string>\n    <string name=\"polar_coordinates\">Полярные координаты</string>\n    <string name=\"rect_to_polar\">Прямоугольная в полярную</string>\n    <string name=\"polar_to_rect\">Полярная в прямоугольную</string>\n    <string name=\"invert_in_circle\">Инвертировать в круг</string>\n    <string name=\"reduce_noise\">Уменьшить шум</string>\n    <string name=\"simple_solarize\">Простая Соляризация</string>\n    <string name=\"weave\">Плетение</string>\n    <string name=\"x_gap\">Зазор по оси X</string>\n    <string name=\"y_gap\">Зазор по оси Y</string>\n    <string name=\"x_width\">Ширина по оси X</string>\n    <string name=\"y_wdth\">Ширина по оси Y</string>\n    <string name=\"twirl\">Закручивание</string>\n    <string name=\"rubber_stmp\">Резиновый штамп</string>\n    <string name=\"smear\">Размазывание</string>\n    <string name=\"density\">Плотность</string>\n    <string name=\"mix\">Смешивание</string>\n    <string name=\"sphere_lensh_distortion\">Искажение сферической линзы</string>\n    <string name=\"refraction_index\">Показатель преломления</string>\n    <string name=\"arc\">Дуга</string>\n    <string name=\"spread_angle\">Угол рассеивания</string>\n    <string name=\"sparkle\">Блеск</string>\n    <string name=\"rays\">Лучи</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Градиент</string>\n    <string name=\"moire\">Муар</string>\n    <string name=\"autumn\">Осень</string>\n    <string name=\"bone\">Кость</string>\n    <string name=\"jet\">Струйный</string>\n    <string name=\"winter\">Зима</string>\n    <string name=\"ocean\">Океан</string>\n    <string name=\"summer\">Лето</string>\n    <string name=\"spring\">Весна</string>\n    <string name=\"cool_variant\">Прохладный вариант</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Розовый</string>\n    <string name=\"hot\">Горячий</string>\n    <string name=\"parula\">Парула</string>\n    <string name=\"magma\">Магма</string>\n    <string name=\"inferno\">Инферно</string>\n    <string name=\"plasma\">Плазма</string>\n    <string name=\"viridis\">Зелёный</string>\n    <string name=\"cividis\">Цивидис</string>\n    <string name=\"twilight\">Сумерки</string>\n    <string name=\"twilight_shifted\">Сумерки со смещением</string>\n    <string name=\"auto_perspective\">Автоперспектива</string>\n    <string name=\"deskew\">Выравнивание</string>\n    <string name=\"allow_crop\">Разрешить кадрирование</string>\n    <string name=\"crop_or_perspective\">Кадрирование или перспектива</string>\n    <string name=\"absolute\">Абсолютный</string>\n    <string name=\"turbo\">Турбо</string>\n    <string name=\"deep_green\">Темно-зелёный</string>\n    <string name=\"lens_correction\">Коррекция объектива</string>\n    <string name=\"target_lens_profile\">Целевой файл профиля объектива в формате JSON</string>\n    <string name=\"download_ready_lens_profiles\">Скачать готовые профили</string>\n    <string name=\"part_percents\">Проценты частей</string>\n    <string name=\"export_as_json\">Экспортировать в JSON</string>\n    <string name=\"home_screen\">Рабочий стол</string>\n    <string name=\"lock_screen\">Экран блокировки</string>\n    <string name=\"built_in\">Встроенные</string>\n    <string name=\"wallpapers_export\">Экспорт обоев</string>\n    <string name=\"refresh\">Обновить</string>\n    <string name=\"wallpapers_export_sub\">Получите актуальные обои рабочего стола, экрана блокировки и встроенные обои</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Разрешите доступ ко всем файлам, это необходимо для получения обоев</string>\n    <string name=\"security\">Безопасность</string>\n    <string name=\"wifi_configuration\">Конфигурация Wi-Fi</string>\n    <string name=\"edit_barcode\">Изменить баркод</string>\n    <string name=\"create_barcode\">Создать баркод</string>\n    <string name=\"longitude\">Долгота</string>\n    <string name=\"latitude\">Широта</string>\n    <string name=\"status\">Статус</string>\n    <string name=\"end_date\">Дата окончания</string>\n    <string name=\"start_date\">Дата начала</string>\n    <string name=\"organizer\">Организатор</string>\n    <string name=\"location\">Местоположение</string>\n    <string name=\"description\">Описание</string>\n    <string name=\"addresses\">Адреса</string>\n    <string name=\"urls\">Ссылки</string>\n    <string name=\"emails\">Электронные почты</string>\n    <string name=\"phones\">Номера телефонов</string>\n    <string name=\"title\">Заголовок</string>\n    <string name=\"organization\">Организация</string>\n    <string name=\"name\">Имя</string>\n    <string name=\"address\">Адрес</string>\n    <string name=\"message\">Сообщение</string>\n    <string name=\"phone\">Номер телефона</string>\n    <string name=\"ssid\">Название сети</string>\n    <string name=\"not_specified\">Н/Д</string>\n    <string name=\"open_network\">Открытая сеть</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"qr_type_url\">Ссылка</string>\n    <string name=\"qr_type_sms\">СМС</string>\n    <string name=\"qr_type_plain\">Текст</string>\n    <string name=\"qr_type_phone\">Номер телефона</string>\n    <string name=\"qr_type_geo_point\">Местоположение</string>\n    <string name=\"qr_type_email\">Электронная почта</string>\n    <string name=\"qr_type_contact_info\">Контакт</string>\n    <string name=\"qr_type_calendar_event\">Мероприятие</string>\n    <string name=\"ascii_art\">Ascii арт</string>\n    <string name=\"ascii_art_sub\">Преобразование изображения в текст ascii, который будет выглядеть как картинка</string>\n    <string name=\"grant_contact_permission\">Выдайте разрешение на доступ к контактам а настройках чтобы автозаполнять используя выбранный контакт</string>\n    <string name=\"pick_contact\">Выбрать контакт</string>\n    <string name=\"allow_skip_if_larger_sub\">Некоторые инструменты будут позволять не сохранять изображения, если размер получившегося файла будет больше исходного</string>\n    <string name=\"allow_skip_if_larger\">Разрешить пропускать если больше</string>\n    <string name=\"skipped_saving_multiple\">%1$s файлов пропущено</string>\n    <string name=\"screenshot_not_captured_try_again\">Снимок экрана не сделан, попробуйте еще раз</string>\n    <string name=\"processing_screenshot\">Обработка снимка экрана</string>\n    <string name=\"invert_colors_ascii_sub\">Применяет негативный фильтр к изображению для получения лучшего результата в некоторых случаях</string>\n    <string name=\"params\">Параметры</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Добавляет к имени файла изображения суффикс с выбранным режимом масштабирования изображения</string>\n    <string name=\"add_image_scale_mode_to_filename\">Добавить режим масштабирования изображения в имя файла</string>\n    <string name=\"summary\">Название</string>\n    <string name=\"body\">Тело</string>\n    <string name=\"subject\">Тема</string>\n    <string name=\"skipped_saving\">Сохранение пропущено</string>\n    <string name=\"allow_read_media_images_for_wp\">Разрешить управление внешним хранилищем недостаточно, нужно разрешить доступ к изображениям, убедитесь, что выбрали \\\"Разрешить все\\\"</string>\n    <string name=\"seam_carving\">Резьба по швам</string>\n    <string name=\"export_as_json_sub\">Копировать строку с данными палитры в виде json</string>\n    <string name=\"enable_snapping_to_borders_sub\">После перемещения или масштабирования изображения будут привязаны к краям кадра</string>\n    <string name=\"enable_snapping_to_borders\">Включить привязку к границам</string>\n    <string name=\"disable_rotation_sub\">Предотвращение поворота изображений с помощью жестов двумя пальцами</string>\n    <string name=\"disable_rotation\">Отключить вращение</string>\n    <string name=\"add_preset_to_filename\">Добавить пресет в имя файла</string>\n    <string name=\"add_preset_to_filename_sub\">Добавляет к имени файла изображения суффикс с выбранной пресетом</string>\n    <string name=\"contact_info\">Информация о контакте</string>\n    <string name=\"first_name\">Имя</string>\n    <string name=\"middle_name\">Отчество</string>\n    <string name=\"last_name\">Фамилия</string>\n    <string name=\"pronunciation\">Произношение</string>\n    <string name=\"add_phone\">Добавить номер телефона</string>\n    <string name=\"add_email\">Добавить электронную почту</string>\n    <string name=\"add_address\">Добавить адрес</string>\n    <string name=\"website\">Вебсайт</string>\n    <string name=\"add_website\">Добавить вебсайт</string>\n    <string name=\"formatted_name\">Форматированное имя</string>\n    <string name=\"qr_code_top_image\">Это изображение будет использоваться для размещения над баркодом</string>\n    <string name=\"code_customization\">Кастомизация кода</string>\n    <string name=\"qr_logo_image\">Это изображение будет использоваться в качестве логотипа в центре QR-кода</string>\n    <string name=\"logo\">Логотип</string>\n    <string name=\"logo_padding\">Отступы логотипа</string>\n    <string name=\"logo_size\">Размер логотипа</string>\n    <string name=\"logo_corners\">Углы логотипа</string>\n    <string name=\"pixel_shape\">Форма пикселя</string>\n    <string name=\"frame_shape\">Форма рамки</string>\n    <string name=\"ball_shape\">Форма круга</string>\n    <string name=\"error_correction_level\">Уровень коррекции ошибок</string>\n    <string name=\"dark_color\">Тёмный цвет</string>\n    <string name=\"light_color\">Светлый цвет</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Стиль как в Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Шаблон маски</string>\n    <string name=\"fourth_eye\">Четвертая метка</string>\n    <string name=\"fourth_eye_description\">Добавляет симметрию меток для QR кода с помощью добавления четвертой метки в правом нижнем углу</string>\n    <string name=\"code_may_be_not_scannable\">Этот код может быть нечитаемым для сканера. Измените параметры внешнего вида, чтобы он считывался на всех устройствах</string>\n    <string name=\"not_scannable\">Не подлежит сканированию</string>\n    <string name=\"launcher_mode_sub\">Инструменты будут выглядеть как панель запуска приложений на главном экране, что сделает их более компактными</string>\n    <string name=\"launcher_mode\">Режим лаунчера</string>\n    <string name=\"flood_fill_sub\">Заполняет область выбранным цветом и стилем</string>\n    <string name=\"flood_fill\">Заливка</string>\n    <string name=\"spray\">Спрей</string>\n    <string name=\"spray_sub\">Рисует путь в виде граффити</string>\n    <string name=\"square_particles\">Квадртаные частицы</string>\n    <string name=\"square_particles_sub\">Частицы спрея будут квадратными, а не круглыми</string>\n    <string name=\"palette_tools\">Инструменты палитры</string>\n    <string name=\"palette_tools_sub\">Создайте базовую/материальную палитру из изображения или импортируйте/экспортируйте палитры в различные форматы</string>\n    <string name=\"edit_palette\">Редактирование палитры</string>\n    <string name=\"edit_palette_sub\">Экспорт/импорт палитры в различных форматах</string>\n    <string name=\"color_name\">Название цвета</string>\n    <string name=\"palette_name\">Название палитры</string>\n    <string name=\"palette_format\">Формат палитры</string>\n    <string name=\"export_palette_sub\">Экспорт сгенерированной палитры в различные форматы</string>\n    <string name=\"add_color_palette_sub\">Добавляет новый цвет в существующую палитру</string>\n    <string name=\"palette_name_not_supported\">Формат %1$s не поддерживает указание имени палитры</string>\n    <string name=\"wallpapers_export_not_avaialbe\">В соответствии с политикой Play Store, эта функция не может быть включена в текущую сборку. Для доступа к этой функциональности, пожалуйста, загрузите ImageToolbox из альтернативного источника. Доступные сборки можно найти на GitHub ниже</string>\n    <string name=\"open_github_page\">Открыть на Github</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s цвет</item>\n        <item quantity=\"few\">%1$s цвета</item>\n        <item quantity=\"many\">%1$s цветов</item>\n        <item quantity=\"other\">%1$s цветов</item>\n    </plurals>\n    <string name=\"overwrite_files_sub_short\">Исходный файл будет заменен новым, а не сохранен в выбранной папке</string>\n    <string name=\"hidden_watermark_text_detected\">Обнаружен скрытый текст водяного знака</string>\n    <string name=\"hidden_watermark_image_detected\">Обнаружено скрытое изображение водяного знака</string>\n    <string name=\"this_image_was_hidden\">Это изображение было скрыто</string>\n    <string name=\"generative_inpaint\">Генеративная закраска</string>\n    <string name=\"generative_inpaint_sub\">Позволяет удалять объекты на изображении с помощью модели ИИ, не полагаясь на OpenCV. Для использования этой функции приложение загрузит необходимую модель (~200 МБ) с GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Позволяет удалять объекты на изображении с помощью модели ИИ, не полагаясь на OpenCV. Это может быть длительная операция</string>\n    <string name=\"error_level_analysis\">Анализ уровня ошибок</string>\n    <string name=\"luminance_gradient\">Градиент яркости</string>\n    <string name=\"average_distance\">Среднее расстояние</string>\n    <string name=\"copy_move_detection\">Обнаружение копирования и перемещения</string>\n    <string name=\"retain\">Удержание</string>\n    <string name=\"coefficent\">Коэффицент</string>\n    <string name=\"clipboard_data_is_too_large\">Объем данных в буфере обмена слишком велик</string>\n    <string name=\"data_is_too_large_to_copy\">Данные слишком велики для копирования</string>\n    <string name=\"simple_weave_pixelization\">Простая плетенная пикселизация</string>\n    <string name=\"staggered_pixelization\">Шахматная пикселизация</string>\n    <string name=\"cross_pixelization\">Крестовая пикселизация</string>\n    <string name=\"micro_macro_pixelization\">Микро макро пикселизация</string>\n    <string name=\"orbital_pixelization\">Орбитальная пикселизация</string>\n    <string name=\"vortex_pixelization\">Вихревая пикселизация</string>\n    <string name=\"pulse_grid_pixelization\">Пикселизация пульсирующей сетки</string>\n    <string name=\"nucleus_pixelization\">Ядровая пикселизация</string>\n    <string name=\"radial_weave_pixelization\">Пикселизация радиального плетения</string>\n    <string name=\"cannot_open_uri\">Невозможно открыть ссылку \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Режим снегопада</string>\n    <string name=\"enabled\">Включено</string>\n    <string name=\"border_frame\">Рамка</string>\n    <string name=\"glitch_variant\">Вариант сбоя</string>\n    <string name=\"channel_shift\">Сдвиг канала</string>\n    <string name=\"max_offset\">Максимальное смещение</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Блочный сбой</string>\n    <string name=\"block_size\">Размер блока</string>\n    <string name=\"crt_curvature\">ЭЛТ изгиб</string>\n    <string name=\"curvature\">Изгиб</string>\n    <string name=\"chroma\">Цветность</string>\n    <string name=\"pixel_melt\">Плавление пикселей</string>\n    <string name=\"max_drop\">Максимальное падение</string>\n    <string name=\"ai_tools\">ИИ инструменты</string>\n    <string name=\"ai_tools_sub\">Различные инструменты для обработки изображений с помощью моделей искусственного интеллекта, такие как удаление артефактов или шумоподавление</string>\n    <string name=\"model_anime_undeint\">Сжатие, рваные линии</string>\n    <string name=\"model_broadcast\">Мультфильмы, сжатие трансляций</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Общее сжатие, общий шум</string>\n    <string name=\"model_wb_denoise\">Бесцветный мультяшный шум</string>\n    <string name=\"model_span_anime_pretrain\">Быстрое, общее сжатие, общий шум, анимация/комиксы/аниме</string>\n    <string name=\"model_book_scan\">Cканирование книг</string>\n    <string name=\"model_overexposure\">Коррекция экспозиции</string>\n    <string name=\"model_fbcnn_color_fp16\">Лучше всего подходит для общего сжатия, цветных изображений</string>\n    <string name=\"model_fbcnn_gray_fp16\">Лучше всего подходит для общего сжатия, изображений в оттенках серого</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Общее сжатие, изображения в оттенках серого, более сильное</string>\n    <string name=\"model_scunet_color_gan_fp16\">Общий шум, цветные изображения</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Общий уровень шума, цветные изображения, улучшенная детализация</string>\n    <string name=\"model_scunet_gray_15_fp16\">Общий шум, изображения в оттенках серого</string>\n    <string name=\"model_scunet_gray_25_fp16\">Общий шум, изображения в оттенках серого, более сильный</string>\n    <string name=\"model_scunet_gray_50_fp16\">Общий шум, изображения в оттенках серого, самый сильный</string>\n    <string name=\"model_jpeg_destroyer\">Общее сжатие</string>\n    <string name=\"model_jaywreck\">Общее сжатие</string>\n    <string name=\"model_h264\">Texturization, h264 compression</string>\n    <string name=\"model_vhs\">Сжатие VHS</string>\n    <string name=\"model_cinepak\">Нестандартное сжатие (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Сжатие Bink, лучше для геометрии</string>\n    <string name=\"model_debink_v5\">Сжатие Bink, более сильное</string>\n    <string name=\"model_debink_v6\">Сжатие Bink, мягкое, сохраняет детали</string>\n    <string name=\"model_antialias\">Устранение эффекта лесенки, сглаживание</string>\n    <string name=\"model_kdm_scans\">Отсканированные изображения/рисунки, легкое сжатие, муар</string>\n    <string name=\"model_bandage\">Цветовая маркировка</string>\n    <string name=\"model_halftone\">Медленно, удаляет полутона</string>\n    <string name=\"model_colorizer\">Универсальный раскрашиватель для черно-белых изображений; для достижения лучших результатов используйте DDColor</string>\n    <string name=\"model_deedge\">Удаление краев</string>\n    <string name=\"model_desharpen\">Удаляет чрезмерную резкость</string>\n    <string name=\"model_dither\">Медленно, дизеринг</string>\n    <string name=\"model_gainres\">Сглаживание, общие артефакты, компьютерная графика</string>\n    <string name=\"model_kdm003_scans\">Обработка сканирований KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Облегченная модель улучшения изображения</string>\n    <string name=\"model_spongecolor_lite\">Простая и быстрая раскраска, мультфильмы, не идеальный вариант</string>\n    <string name=\"model_bcgone_detailed_v2\">Удаление артефактов сжатия</string>\n    <string name=\"model_bcgone_smooth\">Гладкое удаление артефактов сжатия</string>\n    <string name=\"model_bandage_smooth\">Удаление связей с гладкими результатами</string>\n    <string name=\"model_bendel_halftone\">Обработка полутоновых изображений</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Удаление шаблона дизеринга</string>\n    <string name=\"model_jpeg_destroyer_v2\">Удаление артефактов JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Улучшение текстуры H.264</string>\n    <string name=\"model_vhs_sharpen\">Улучшение и повышение резкости VHS-видео</string>\n    <string name=\"merging\">Слияние</string>\n    <string name=\"chunk_size\">Размер фрагмента</string>\n    <string name=\"overlap_size\">Размер перекрытия</string>\n    <string name=\"note_chunk_info\">Изображения размером более %1$s пикселей будут разрезаны и обработаны по частям, а функция перекрытия смешивает их, чтобы предотвратить видимые швы</string>\n    <string name=\"large_chunk_warning\">Большие размеры могут вызывать нестабильность в работе устройств низкого ценового сегмента</string>\n    <string name=\"select_one_to_start\">Выберите один из вариантов для начала</string>\n    <string name=\"delete_model_sub\">Вы хотите удалить модель %1$s? Вам потребуется загрузить её заново</string>\n    <string name=\"confirm\">Подтвердить</string>\n    <string name=\"models\">Модели</string>\n    <string name=\"downloaded_models\">Загруженные модели</string>\n    <string name=\"available_models\">Доступные модели</string>\n    <string name=\"preparing\">Подготовка</string>\n    <string name=\"active_model\">Активная модель</string>\n    <string name=\"failed_to_open_session\">Не удалось открыть сессию</string>\n    <string name=\"type_dejpeg\">DeJPEG</string>\n    <string name=\"type_denoise\">Шумоподавление</string>\n    <string name=\"type_colorize\">Раскрашивание</string>\n    <string name=\"type_artifacts\">Артефакты</string>\n    <string name=\"type_enhance\">Улучшение</string>\n    <string name=\"type_anime\">Аниме</string>\n    <string name=\"type_scans\">Сканы</string>\n    <string name=\"only_onnx_models\">Импортировать можно только модели в форматах .onnx/.ort</string>\n    <string name=\"import_model\">Импортировать модель</string>\n    <string name=\"import_model_sub\">Импортируйте пользовательскую модель ONNX для дальнейшего использования; принимаются только модели ONNX/ORT, поддерживаются почти все варианты, подобные ESRGAN</string>\n    <string name=\"imported_models\">Импортированные модели</string>\n    <string name=\"model_scunet_color_15_fp16\">Общий шум, цветные изображения</string>\n    <string name=\"model_scunet_color_25_fp16\">Общий шум, цветные изображения, более интенсивный</string>\n    <string name=\"model_scunet_color_50_fp16\">Общий шум, цветные изображения, самый сильный</string>\n    <string name=\"model_artifacts_dithering_alsa\">Уменьшает артефакты дизеринга и полосы цвета, улучшая плавность градиентов и плоские цветовые области</string>\n    <string name=\"model_nmkd_brighten_redux\">Улучшает яркость и контрастность изображения, обеспечивая сбалансированное освещение светлых участков и сохраняя естественные цвета</string>\n    <string name=\"model_nmkd_brighten\">Осветляет темные изображения, сохраняя при этом детали и избегая переэкспозиции</string>\n    <string name=\"model_nmkd_detoon\">Устраняет избыточное тонирование и восстанавливает более нейтральный и естественный цветовой баланс</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Применяет шумоподавление на основе распределения Пуассона с акцентом на сохранение мелких деталей и текстур</string>\n    <string name=\"model_noise_toner_poisson_soft\">Применяет мягкий пуассоновский шум для получения более плавных и менее агрессивных визуальных результатов</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Равномерное шумоподавление, направленное на сохранение деталей и четкости изображения</string>\n    <string name=\"model_noise_toner_uniform_soft\">Мягкое равномерное шумоподавление для создания тонкой текстуры и гладкой поверхности</string>\n    <string name=\"model_repainter\">Восстанавливает поврежденные или неровные участки путем перекрашивания артефактов и улучшения согласованности изображения</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Облегченная модель устранения полос, которая удаляет цветовые полосы с минимальными потерями производительности</string>\n    <string name=\"model_jpeg_0_20\">Оптимизирует изображения с очень сильными артефактами сжатия (качество 0-20%) для повышения четкости</string>\n    <string name=\"model_jpeg_20_40\">Улучшает изображения с сильными артефактами сжатия (качество 20-40%), восстанавливая детали и уменьшая шум</string>\n    <string name=\"model_jpeg_40_60\">Улучшает изображения за счет умеренного сжатия (качество 40-60%), обеспечивая баланс между резкостью и плавностью</string>\n    <string name=\"model_jpeg_60_80\">Улучшение качества изображений с легким сжатием (60-80%) для выделения тонких деталей и текстур</string>\n    <string name=\"model_jpeg_80_100\">Слегка улучшает изображения практически без потерь качества (80-100%), сохраняя при этом естественный вид и детали</string>\n    <string name=\"model_deblr\">Немного уменьшает размытие изображения, повышая резкость без появления артефактов</string>\n    <string name=\"processing_channel\">Долгосрочные операции</string>\n    <string name=\"processing_image\">Обработка изображения</string>\n    <string name=\"processing\">Обработка</string>\n    <string name=\"model_artifacts_jpg_0_20\">Удаляет сильные артефакты сжатия JPEG на изображениях очень низкого качества (0-20%)</string>\n    <string name=\"model_artifacts_jpg_20_40\">Уменьшает сильные артефакты JPEG в сильно сжатых изображениях (на 20-40%)</string>\n    <string name=\"model_artifacts_jpg_40_60\">Устраняет умеренные артефакты JPEG, сохраняя при этом детали изображения (40-60%)</string>\n    <string name=\"model_artifacts_jpg_60_80\">Улучшает качество изображений JPEG на достаточно высоком уровне (60-80%)</string>\n    <string name=\"model_artifacts_jpg_80_100\">Незаметно уменьшает незначительные артефакты JPEG в изображениях практически без потерь качества (80-100%)</string>\n    <string name=\"model_redetail_v2\">Улучшает детализацию и текстуры, повышая воспринимаемую резкость без существенных артефактов</string>\n    <string name=\"processing_finished\">Обработка завершена</string>\n    <string name=\"processing_failed\">Обработка не удалась</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Улучшает текстуру и детали кожи, сохраняя при этом естественный вид, оптимизировано для высокой скорости</string>\n    <string name=\"model_sbdv_dejpeg\">Удаляет артефакты сжатия JPEG и восстанавливает качество изображения для сжатых фотографий</string>\n    <string name=\"model_iso_denoise_v1\">Уменьшает уровень шума ISO на фотографиях, сделанных в условиях недостаточного освещения, сохраняя при этом детали</string>\n    <string name=\"model_dejumbo\">Корректирует переэкспонированные или «гиперэкспонированные» участки и восстанавливает лучший тональный баланс</string>\n    <string name=\"model_ddcolor_tiny\">Легкая и быстрая модель цветокоррекции, добавляющая естественные цвета к изображениям в оттенках серого</string>\n    <string name=\"type_upscale\">Апскейл</string>\n    <string name=\"model_realesrgan_x4v3\">Масштабирование X4 для обычных изображений; миниатюрная модель, использующая меньше ресурсов графического процессора и времени, с умеренным устранением размытия и шумоподавлением</string>\n    <string name=\"model_realesrgan_x2plus\">Масштабирование X2 для обычных изображений с сохранением текстур и естественных деталей</string>\n    <string name=\"model_realesrgan_x4plus\">Масштабирование X4 для обычных изображений с улучшенными текстурами и реалистичными результатами</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Оптимизированный для аниме-изображений масштабировщик X4; 6 блоков RRDB для более четких линий и деталей</string>\n    <string name=\"model_realesrnet_x4plus\">Масштабирование X4 с использованием функции потерь MSE обеспечивает более плавные результаты и уменьшает артефакты для обычных изображений</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler, оптимизированный для аниме-изображений; вариант 4B32F с более четкой детализацией и плавными линиями</string>\n    <string name=\"model_ultrasharp_v2_x4\">Модель предназначена для съемки изображений общего назначения; акцент делается на резкость и четкость</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">Быстрее и компактнее, сохраняет детализацию, используя при этом меньше памяти графического процессора</string>\n    <string name=\"model_rmbg_1_4\">Легкая модель для быстрого удаления фона. Сбалансированная производительность и точность. Работает с портретами, объектами и сценами. Рекомендуется для большинства случаев использования</string>\n    <string name=\"type_removebg\">Удаление фона</string>\n    <string name=\"horizontal_border_thickness\">Толщина горизонтальной границы</string>\n    <string name=\"vertical_border_thickness\">Толщина вертикальной границы</string>\n    <string name=\"current_model_not_chunkable\">Текущая модель не поддерживает фрагментацию, изображение будет обработано в исходных размерах, это может привести к высокому потреблению памяти и проблемам с устройствами низкого уровня.</string>\n    <string name=\"chunking_disabled\">Фрагментация отключена, изображение будет обрабатываться в исходных размерах. Это может привести к высокому потреблению памяти и проблемам с устройствами низкого уровня, но может дать лучшие результаты при выводе.</string>\n    <string name=\"chunking\">Фрагментация</string>\n    <string name=\"model_u2net\">Высокоточная модель сегментации изображения для удаления фона</string>\n    <string name=\"model_u2netp\">Облегченная версия U2Net для более быстрого удаления фона с меньшим использованием памяти.</string>\n    <string name=\"model_ddcolor\">Модель Full DDColor обеспечивает высококачественную раскраску обычных изображений с минимальными артефактами. Лучший выбор из всех моделей раскрашивания.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Обученные и частные художественные наборы данных; дает разнообразные и художественные результаты раскрашивания с меньшим количеством нереалистичных цветовых артефактов.</string>\n    <string name=\"model_birefnet\">Легкая модель BiRefNet на основе Swin Transformer для точного удаления фона.</string>\n    <string name=\"model_inspyrenet\">Качественное удаление фона с острыми краями и отличным сохранением деталей, особенно на сложных объектах и сложном фоне.</string>\n    <string name=\"model_isnet\">Модель удаления фона, которая создает точные маски с гладкими краями, подходящую для обычных объектов и умеренного сохранения деталей.</string>\n    <string name=\"model_already_downloaded\">Модель уже скачана</string>\n    <string name=\"model_successfully_imported\">Модель успешно импортирована</string>\n    <string name=\"type\">Тип</string>\n    <string name=\"keyword\">Ключевое слово</string>\n    <string name=\"very_fast\">Очень быстро</string>\n    <string name=\"normal\">Нормально</string>\n    <string name=\"slow\">Медленно</string>\n    <string name=\"very_slow\">Очень медленно</string>\n    <string name=\"warp_mode_move\">Движение</string>\n    <string name=\"warp_mode_grow\">Рост</string>\n    <string name=\"warp_mode_shrink\">Сжатие</string>\n    <string name=\"warp_mode_swirl_cw\">Вихрь (→)</string>\n    <string name=\"warp_mode_swirl_ccw\">Вихрь (←)</string>\n    <string name=\"compute_percents\">Вычисление процентов</string>\n    <string name=\"minimum_value_is\">Минимальное значение: %1$s</string>\n    <string name=\"warp_sub\">Искажайте изображение, рисуя пальцами</string>\n    <string name=\"warp\">Деформация</string>\n    <string name=\"hardness\">Твердость</string>\n    <string name=\"warp_mode\">Режим деформации</string>\n    <string name=\"fade_strength\">Сила исчезновения</string>\n    <string name=\"top_drop\">Верхняя обрезка</string>\n    <string name=\"bottom_drop\">Нижняя обрезка</string>\n    <string name=\"start_drop\">Левая обрезка</string>\n    <string name=\"end_drop\">Правая обрезка</string>\n    <string name=\"downloading\">Загрузка</string>\n    <string name=\"smooth_shapes\">Гладкие формы</string>\n    <string name=\"smooth_shapes_sub\">Используйте суперэллипсы вместо стандартных закругленных прямоугольников для получения более плавных и естественных форм.</string>\n    <string name=\"shape_type\">Тип формы</string>\n    <string name=\"cut\">Обрезанная</string>\n    <string name=\"rounded\">Закругленная</string>\n    <string name=\"smooth\">Гладкая</string>\n    <string name=\"cut_shapes_sub\">Острые края без закруглений</string>\n    <string name=\"rounded_shapes_sub\">Классические закругленные углы.</string>\n    <string name=\"shapes_type\">Тип фигуры</string>\n    <string name=\"corners_size\">Размер углов</string>\n    <string name=\"squircle\">Сквиркл</string>\n    <string name=\"squircle_shapes_sub\">Элегантные закругленные элементы пользовательского интерфейса</string>\n    <string name=\"filename_format\">Формат имени файла</string>\n    <string name=\"prefix_pattern_description\">Пользовательский текст, размещаемый в самом начале имени файла, идеально подходит для названий проектов, брендов или личных тегов.</string>\n    <string name=\"original_filename_pattern_description\">Использует исходное имя файла без расширения, что помогает сохранить идентификацию источника без изменений.</string>\n    <string name=\"width_pattern_description\">Ширина изображения в пикселях, полезная для отслеживания изменений разрешения или масштабирования результатов.</string>\n    <string name=\"height_pattern_description\">Высота изображения в пикселях, полезная при работе с пропорциями или экспорте.</string>\n    <string name=\"random_numbers_pattern_description\">Генерирует случайные цифры, чтобы гарантировать уникальные имена файлов; добавьте больше цифр для дополнительной защиты от дубликатов.</string>\n    <string name=\"sequence_number_pattern_description\">Автоматически увеличивающийся счетчик для пакетного экспорта идеален при сохранении нескольких изображений за один сеанс.</string>\n    <string name=\"preset_info_pattern_description\">Вставляет имя примененной предустановки в имя файла, чтобы вы могли легко запомнить, как было обработано изображение.</string>\n    <string name=\"scale_mode_pattern_description\">Отображает режим масштабирования изображения, используемый во время обработки, помогая различать изображения с измененным размером, обрезанные или подогнанные.</string>\n    <string name=\"suffix_pattern_description\">Пользовательский текст, помещаемый в конце имени файла, полезный для управления версиями, например _v2, _edited или _final.</string>\n    <string name=\"extension_pattern_description\">Расширение файла (png, jpg, webp и т. д.) автоматически соответствует фактическому сохраненному формату.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Настраиваемая временная метка, позволяющая определить собственный формат по спецификации Java для идеальной сортировки.</string>\n    <string name=\"fling_type\">Тип броска</string>\n    <string name=\"android_native\">Android</string>\n    <string name=\"ios_style\">Стиль iOS</string>\n    <string name=\"smooth_curve\">Гладкая кривая</string>\n    <string name=\"quick_stop\">Быстрая остановка</string>\n    <string name=\"bouncy\">Надувной</string>\n    <string name=\"floaty\">Плавучий</string>\n    <string name=\"snappy\">Шустрый</string>\n    <string name=\"ultra_smooth\">Ультра гладкий</string>\n    <string name=\"adaptive\">Адаптивный</string>\n    <string name=\"accessibility_aware\">Доступность</string>\n    <string name=\"reduced_motion\">Уменьшенное движение</string>\n    <string name=\"android_native_sub\">Встроенная физика прокрутки Android</string>\n    <string name=\"smooth_sub\">Сбалансированная, плавная прокрутка для общего использования.</string>\n    <string name=\"ios_style_sub\">Поведение прокрутки, подобное iOS, с повышенным трением</string>\n    <string name=\"smooth_curve_sub\">Уникальная кривая сплайна для четкого ощущения прокрутки</string>\n    <string name=\"quick_stop_sub\">Точная прокрутка с быстрой остановкой</string>\n    <string name=\"bouncy_sub\">Игривая, отзывчивая, упругая прокрутка</string>\n    <string name=\"floaty_sub\">Длинная скользящая прокрутка для просмотра контента</string>\n    <string name=\"snappy_sub\">Быстрая и отзывчивая прокрутка для интерактивных интерфейсов.</string>\n    <string name=\"ultra_smooth_sub\">Плавная прокрутка премиум-класса с увеличенным импульсом</string>\n    <string name=\"adaptive_sub\">Регулирует физику в зависимости от скорости броска.</string>\n    <string name=\"accessibility_aware_sub\">Соблюдает настройки специальных возможностей системы</string>\n    <string name=\"reduced_motion_sub\">Минимальное движение для обеспечения доступности</string>\n    <string name=\"primary_lines\">Первичные линии</string>\n    <string name=\"primary_lines_sub\">Добавляет более толстую линию каждую пятую строку.</string>\n    <string name=\"fill_color\">Цвет заливки</string>\n    <string name=\"hidden_tools\">Скрытые инструменты</string>\n    <string name=\"hidden_for_share\">Инструменты, скрытые для общего доступа</string>\n    <string name=\"color_library\">Библиотека цветов</string>\n    <string name=\"color_library_sub\">Просмотрите обширную коллекцию цветов</string>\n    <string name=\"model_fatality_deblur\">Увеличивает резкость и устраняет размытие изображений, сохраняя при этом естественные детали, что идеально подходит для исправления расфокусированных фотографий.</string>\n    <string name=\"model_unresize_v3\">Интеллектуальное восстановление изображений, размер которых ранее был изменен, восстанавливая потерянные детали и текстуры.</string>\n    <string name=\"model_liveaction_v1_span\">Оптимизирован для контента с живыми актерами, уменьшает артефакты сжатия и улучшает мелкие детали в кадрах фильмов/телешоу.</string>\n    <string name=\"model_vhs2hd_realplksr\">Преобразует отснятый материал с качеством VHS в HD, удаляя шум ленты и повышая разрешение, сохраняя при этом ощущение винтажности.</string>\n    <string name=\"model_text2hd_v1\">Специально предназначен для изображений и снимков экрана с большим количеством текста, повышает резкость символов и улучшает читаемость.</string>\n    <string name=\"model_frankendata_pretrainer\">Расширенное масштабирование, обученное на различных наборах данных, отлично подходит для общего улучшения фотографий.</string>\n    <string name=\"model_realwebphoto_v2\">Оптимизирован для фотографий, сжатых через Интернет, удаляет артефакты JPEG и восстанавливает естественный вид.</string>\n    <string name=\"model_realwebphoto_v4\">Улучшенная версия для веб-фотографий с лучшим сохранением текстур и уменьшением артефактов.</string>\n    <string name=\"model_dat_2x\">Двукратное масштабирование с помощью технологии Dual Aggregation Transformer обеспечивает четкость и естественные детали.</string>\n    <string name=\"model_dat_3x\">3-кратное масштабирование с использованием усовершенствованной архитектуры трансформатора, идеально подходящее для умеренных потребностей в расширении.</string>\n    <string name=\"model_dat_4x\">Четырехкратное высококачественное масштабирование с использованием современной трансформаторной сети сохраняет мелкие детали в больших масштабах.</string>\n    <string name=\"model_nafnet_deblurring\">Удаляет размытие/шум и дрожание фотографий. Общего назначения, но лучше всего на фотографиях.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Восстанавливает изображения низкого качества с помощью преобразователя Swin2SR, оптимизированного для деградации BSRGAN. Отлично подходит для исправления сильных артефактов сжатия и улучшения деталей в 4-кратном масштабе.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4-кратное масштабирование с помощью преобразователя SwinIR, обученного ухудшению BSRGAN. Использует GAN для получения более четких текстур и более естественных деталей на фотографиях и сложных сценах.</string>\n    <string name=\"path\">Путь</string>\n    <string name=\"merge_pdf\">Объединить PDF</string>\n    <string name=\"merge_pdf_sub\">Объединение нескольких PDF-файлов в один документ</string>\n    <string name=\"files_order\">Порядок файлов</string>\n    <string name=\"pages_short\">стр.</string>\n    <string name=\"split_pdf\">Разделить PDF</string>\n    <string name=\"split_pdf_sub\">Извлечь определенные страницы из PDF-документа</string>\n    <string name=\"rotate_pdf\">Повернуть PDF</string>\n    <string name=\"rotate_pdf_sub\">Исправить ориентацию страницы навсегда</string>\n    <string name=\"pages\">Страницы</string>\n    <string name=\"rearrange_pdf\">Переупорядочить PDF</string>\n    <string name=\"rearrange_pdf_sub\">Перетаскивайте страницы, чтобы изменить их порядок</string>\n    <string name=\"hold_drag_drop\">Удерживайте и перетащите страницы</string>\n    <string name=\"page_numbers\">Номера страниц</string>\n    <string name=\"page_numbers_sub\">Добавляйте нумерацию к вашим документам автоматически</string>\n    <string name=\"label_format\">Формат этикетки</string>\n    <string name=\"pdf_to_text\">PDF в текст (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Извлекайте простой текст из ваших PDF-документов</string>\n    <string name=\"watermark_pdf_sub\">Наложение пользовательского текста для брендинга или безопасности</string>\n    <string name=\"signature\">Подпись</string>\n    <string name=\"signature_sub\">Добавьте свою электронную подпись к любому документу</string>\n    <string name=\"will_be_for_signature\">Это будет использоваться в качестве подписи</string>\n    <string name=\"unlock_pdf\">Разблокировать PDF</string>\n    <string name=\"unlock_pdf_sub\">Удалите пароли из ваших защищенных файлов</string>\n    <string name=\"protect_pdf\">Защитить PDF</string>\n    <string name=\"protect_pdf_sub\">Защитите свои документы надежным шифрованием</string>\n    <string name=\"success\">Успех</string>\n    <string name=\"pdf_unlocked\">PDF-файл разблокирован, вы можете сохранить его или поделиться им.</string>\n    <string name=\"repair_pdf\">Восстановить PDF</string>\n    <string name=\"repair_pdf_sub\">Попытайтесь исправить поврежденные или нечитаемые документы.</string>\n    <string name=\"grayscale\">Оттенки серого</string>\n    <string name=\"grayscale_pdf_sub\">Преобразование всех встроенных изображений документа в оттенки серого</string>\n    <string name=\"compress_pdf\">Сжать PDF</string>\n    <string name=\"compress_pdf_sub\">Оптимизируйте размер файла документа для упрощения обмена</string>\n    <string name=\"repair_info\">ImageToolbox перестраивает внутреннюю таблицу перекрестных ссылок и восстанавливает структуру файла с нуля. Это может восстановить доступ ко многим файлам, которые «нельзя открыть».</string>\n    <string name=\"grayscale_info\">Этот инструмент преобразует все изображения документов в оттенки серого. Лучше всего подходит для печати и уменьшения размера файла.</string>\n    <string name=\"metadata\">Метаданные</string>\n    <string name=\"metadata_pdf_sub\">Редактируйте свойства документа для большей конфиденциальности</string>\n    <string name=\"tags\">Теги</string>\n    <string name=\"producer\">Продюсер</string>\n    <string name=\"author\">Автор</string>\n    <string name=\"keywords\">Ключевые слова</string>\n    <string name=\"creator\">Создатель</string>\n    <string name=\"privacy_deep_clean\">Глубокая очистка</string>\n    <string name=\"privacy_deep_clean_sub\">Удалите все доступные метаданные для этого документа</string>\n    <string name=\"page\">Страница</string>\n    <string name=\"deep_ocr\">Глубокое распознавание текста</string>\n    <string name=\"deep_ocr_sub\">Извлеките текст из документа и сохраните его в одном текстовом файле с помощью механизма Tesseract.</string>\n    <string name=\"cant_remove_all\">Невозможно удалить все страницы</string>\n    <string name=\"remove_pages_pdf\">Удалить страницы PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Удалить определенные страницы из PDF-документа</string>\n    <string name=\"tap_to_remove\">Нажмите, чтобы удалить</string>\n    <string name=\"manually\">Вручную</string>\n    <string name=\"crop_pdf\">Обрезать PDF</string>\n    <string name=\"crop_pdf_sub\">Обрежьте страницы документа до любых границ</string>\n    <string name=\"flatten_pdf\">Свести PDF</string>\n    <string name=\"flatten_pdf_sub\">Сделайте PDF неизменяемым, растрируя страницы документа</string>\n    <string name=\"camera_failed_to_open\">Не удалось запустить камеру. Пожалуйста, проверьте разрешения и убедитесь, что она не используется другим приложением.</string>\n    <string name=\"extract_images\">Извлечь изображения</string>\n    <string name=\"extract_images_sub\">Извлекайте изображения, встроенные в PDF-файлы, в исходном разрешении.</string>\n    <string name=\"pdf_no_embedded\">Этот PDF-файл не содержит встроенных изображений.</string>\n    <string name=\"extract_images_info\">Этот инструмент сканирует каждую страницу и восстанавливает исходные изображения в полном качестве — идеально подходит для сохранения оригиналов из документов.</string>\n    <string name=\"draw_signature\">Нарисовать подпись</string>\n    <string name=\"pen_params\">Параметры пера</string>\n    <string name=\"draw_signature_sub\">Использовать собственную подпись в качестве изображения для размещения на документах</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Разделить документ с заданным интервалом и упаковать новые документы в zip-архив.</string>\n    <string name=\"interval\">Интервал</string>\n    <string name=\"print_pdf\">Распечатать PDF</string>\n    <string name=\"print_pdf_sub\">Подготовьте документ к печати с нестандартным размером страницы.</string>\n    <string name=\"pages_per_sheet\">Страниц на листе</string>\n    <string name=\"orientation\">Ориентация</string>\n    <string name=\"page_size\">Размер страницы</string>\n    <string name=\"margin\">Допуск</string>\n    <string name=\"bloom\">Цвести</string>\n    <string name=\"soft_knee\">Мягкое колено</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Оптимизирован для аниме и мультфильмов. Быстрое масштабирование с улучшенными естественными цветами и меньшим количеством артефактов.</string>\n    <string name=\"one_ui_sub\">Стиль Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Введите здесь основные математические символы, чтобы вычислить желаемое значение (например, (5+5)*10).</string>\n    <string name=\"math_expression\">Математическое выражение</string>\n    <string name=\"pick_up_to_n_collage_images\">Выберите до %1$s изображений</string>\n    <string name=\"keep_date_time\">Сохраняйте дату и время</string>\n    <string name=\"keep_date_time_sub\">Всегда сохранять теги exif, связанные с датой и временем, работает независимо от опции сохранения exif.</string>\n    <string name=\"background_color_for_alpha_formats\">Цвет фона для альфа-форматов</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Добавляет возможность устанавливать цвет фона для каждого формата изображения с поддержкой альфа-канала, при отключении это доступно только для не-альфа-форматов.</string>\n    <string name=\"open_markup_project\">Открыть проект</string>\n    <string name=\"open_markup_project_sub\">Продолжить редактирование ранее сохраненного проекта Image Toolbox</string>\n    <string name=\"markup_project_open_failed\">Невозможно открыть проект Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">В проекте Image Toolbox отсутствуют данные проекта</string>\n    <string name=\"markup_project_corrupted\">Проект Image Toolbox поврежден.</string>\n    <string name=\"unsupported_markup_project_version\">Неподдерживаемая версия проекта Image Toolbox: %1$d.</string>\n    <string name=\"save_markup_project\">Сохранить проект</string>\n    <string name=\"save_markup_project_sub\">Храните слои, фон и историю редактирования в редактируемом файле проекта.</string>\n    <string name=\"failed_to_open\">Не удалось открыть</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Запись в PDF с возможностью поиска</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Распознавайте текст из пакета изображений и сохраняйте PDF с возможностью поиска с изображением и выбираемым текстовым слоем.</string>\n    <string name=\"layer_alpha\">Прозрачность слоя</string>\n    <string name=\"horizontal_flip\">Горизонтальный флип</string>\n    <string name=\"vertical_flip\">Вертикальный флип</string>\n    <string name=\"lock\">Замок</string>\n    <string name=\"add_shadow\">Добавить тень</string>\n    <string name=\"shadow_color\">Цвет тени</string>\n    <string name=\"text_geometry\">Текстовая геометрия</string>\n    <string name=\"text_geometry_sub\">Растяните или наклоните текст для более четкой стилизации.</string>\n    <string name=\"scale_x\">Масштаб X</string>\n    <string name=\"skew_x\">Наклон X</string>\n    <string name=\"remove_annotations\">Удаление аннотаций</string>\n    <string name=\"remove_annotations_sub\">Удаление выбранных типов аннотаций, таких как ссылки, комментарии, выделение, фигуры или поля форм, со страниц PDF.</string>\n    <string name=\"annotation_link\">Гиперссылки</string>\n    <string name=\"annotation_file_attachment\">Вложения файлов</string>\n    <string name=\"annotation_line\">Линии</string>\n    <string name=\"annotation_popup\">Всплывающие окна</string>\n    <string name=\"annotation_stamp\">Марки</string>\n    <string name=\"annotation_shapes\">Формы</string>\n    <string name=\"annotation_text\">Текстовые заметки</string>\n    <string name=\"annotation_text_markup\">Текстовая разметка</string>\n    <string name=\"annotation_widget\">Поля формы</string>\n    <string name=\"annotation_markup\">Разметка</string>\n    <string name=\"annotation_unknown\">Неизвестный</string>\n    <string name=\"annotations\">Аннотации</string>\n    <string name=\"ungroup\">Разгруппировать</string>\n    <string name=\"add_shadow_sub\">Добавьте размытую тень за слоем с настраиваемым цветом и смещениями.</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-si/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">ගැටලුවක් පවතී: %1$s</string>\n    <string name=\"size\">ප්‍රමාණය %1$s</string>\n    <string name=\"loading\">මොහොතක් සිටින්න…</string>\n    <string name=\"image_too_large_preview\">ඡායාරූපය විශාල බැවින් පෙරදසුනක් ඉදිරිපත් කිරීමට නොහැක, නමුත් සේව් කිරීම මගින් නැවත උත්සහ කළ හැක</string>\n    <string name=\"pick_image\">පටන් ගැනීමට ඡායාරූපයක් තෝරන්න</string>\n    <string name=\"width\">පළල %1$s</string>\n    <string name=\"height\">උස %1$s</string>\n    <string name=\"close\">වහන්න</string>\n    <string name=\"stay\">ඉන්න</string>\n    <string name=\"app_closing_sub\">ඔයාට ඇප් එක ක්ලෝස් කරන්න ඕනමද ?</string>\n    <string name=\"reset_image\">රූපය යළි පිහිටුවන්න</string>\n    <string name=\"reset_image_sub\">රූප වෙනස් කිරීම් මුල් අගයන් වෙත පෙරළෙනු ඇත</string>\n    <string name=\"values_reset\">අගයන් නිවැරදිව නැවත සකසන්න</string>\n    <string name=\"reset\">යළි පිහිටුවන්න</string>\n    <string name=\"something_went_wrong\">වැරදීමක් සිදුවී ඇත</string>\n    <string name=\"restart_app\">ඇප් එක රීස්ටාට් කරන්න</string>\n    <string name=\"edit_exif\">EXIF සංස්කරණය කරන්න</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">හරි</string>\n    <string name=\"no_exif\">EXIF දත්ත හමු නොවීය</string>\n    <string name=\"save\">සේව් කරන්න</string>\n    <string name=\"clear_exif\">EXIF ඉවත් කරන්න</string>\n    <string name=\"resize_type\">ප්‍රමාණය වෙනස් කරන්න</string>\n    <string name=\"quality\">ඡායාරූපයේ ගුණාත්මක භාවය</string>\n    <string name=\"pick_image_alt\">ඡායාරූපයක් තෝරන්න</string>\n    <string name=\"app_closing\">ඇප් එක වසා දැමෙමින්</string>\n    <string name=\"copied\">ක්ලිප්බෝඩ් එකට පිටපත් කර ඇත</string>\n    <string name=\"add_tag\">ටැගය එක් කරන්න</string>\n    <string name=\"clear\">හිස් කරන්න</string>\n    <string name=\"cancel\">අවලංගු කරන්න</string>\n    <string name=\"clear_exif_sub\">\"සියලුම පින්තූර EXIF දත්ත මැකෙනු ඇත.  මෙම ක්‍රියාව නැවත සිදුකළ නොහැක!\"</string>\n    <string name=\"device_storage\">උපාංග ගබඩාව</string>\n    <string name=\"unspecified\">නිශ්චිතව දක්වා නැත</string>\n    <string name=\"by_bytes_resize\">බර අනුව ප්‍රමාණය වෙනස් කරන්න</string>\n    <string name=\"max_bytes\">උපරිම ප්‍රමාණය KB වලින්</string>\n    <string name=\"by_bytes_resize_sub\">KB වලින් ලබා දී ඇති ප්‍රමාණයෙන් රූපයේ ප්‍රමාණය වෙනස් කරන්න</string>\n    <string name=\"compare\">සසඳන්න</string>\n    <string name=\"compare_sub\">ලබා දී ඇති පින්තූර දෙකක් සසඳන්න</string>\n    <string name=\"pick_two_images\">ආරම්භ කිරීමට පින්තූර දෙකක් තෝරන්න</string>\n    <string name=\"pick_images\">පින්තූර තෝරන්න</string>\n    <string name=\"settings\">සැකසුම්</string>\n    <string name=\"night_mode\">අඳුරු තේමාව</string>\n    <string name=\"light\">ලයිට්</string>\n    <string name=\"dark\">ඩාක්</string>\n    <string name=\"language\">භාෂාව</string>\n    <string name=\"system\">පද්ධති</string>\n    <string name=\"allow_image_monet_sub\">ඔන් කර ඇත්නම්, ඔබ සංස්කරණය කිරීමට රූපයක් තෝරන විට, යෙදුම් වර්ණ මෙම රූපයට අනුගත වනු ඇත</string>\n    <string name=\"extension\">දිගු කිරීම</string>\n    <string name=\"explicit\">පැහැදිලිය</string>\n    <string name=\"flexible\">නම්යශීලී</string>\n    <string name=\"exception\">ව්යතිරේක</string>\n    <string name=\"presets\">පෙරසිටුවීම්</string>\n    <string name=\"crop\">බෝග</string>\n    <string name=\"image_not_saved\">ඉතිරි කිරීම</string>\n    <string name=\"image_not_saved_sub\">ඔබ දැන් පිටවන්නේ නම්, නොසුරකින ලද සියලුම වෙනස් කිරීම් අහිමි වනු ඇත</string>\n    <string name=\"check_source_code\">මූලාශ්ර කේතය</string>\n    <string name=\"check_source_code_sub\">නවතම යාවත්කාලීන ලබා ගන්න, ගැටළු සාකච්ඡා කරන්න සහ තවත් දේ</string>\n    <string name=\"single_edit\">තනි සංස්කරණය</string>\n    <string name=\"single_edit_sub\">එක් රූපයක් වෙනස් කරන්න, ප්‍රමාණය වෙනස් කරන්න සහ සංස්කරණය කරන්න</string>\n    <string name=\"pick_color\">වර්ණ පිකර්</string>\n    <string name=\"pick_color_sub\">රූපයෙන් වර්ණය තෝරන්න, පිටපත් කරන්න හෝ බෙදාගන්න</string>\n    <string name=\"image\">රූපය</string>\n    <string name=\"color\">වර්ණය</string>\n    <string name=\"color_copied\">වර්ණ පිටපත් කර ඇත</string>\n    <string name=\"crop_sub\">රූපය ඕනෑම සීමාවකට කපන්න</string>\n    <string name=\"version\">අනුවාදය</string>\n    <string name=\"keep_exif\">EXIF තබා ගන්න</string>\n    <string name=\"images\">පින්තූර: %d</string>\n    <string name=\"change_preview\">පෙරදසුන වෙනස් කරන්න</string>\n    <string name=\"remove\">ඉවත් කරන්න</string>\n    <string name=\"palette_sub\">දී ඇති රූපයෙන් වර්ණාලේප කට්ටලයක් ජනනය කරන්න</string>\n    <string name=\"generate_palette\">පැලට් ජනනය කරන්න</string>\n    <string name=\"palette\">පැලට්</string>\n    <string name=\"update\">යාවත්කාලීන කරන්න</string>\n    <string name=\"new_version\">නව අනුවාදය %1$s</string>\n    <string name=\"unsupported_type\">සහාය නොදක්වන වර්ගය: %1$s</string>\n    <string name=\"no_palette\">ලබා දී ඇති රූපය සඳහා palette ජනනය කළ නොහැක</string>\n    <string name=\"original\">මුල්</string>\n    <string name=\"folder\">ප්රතිදාන ෆෝල්ඩරය</string>\n    <string name=\"def\">පෙරනිමිය</string>\n    <string name=\"custom\">අභිරුචි</string>\n    <string name=\"dynamic_colors\">ගතික වර්ණ</string>\n    <string name=\"customization\">අභිරුචිකරණය</string>\n    <string name=\"allow_image_monet\">රූප මුදල් ඉඩ දෙන්න</string>\n    <string name=\"amoled_mode\">Amoled මාදිලිය</string>\n    <string name=\"amoled_mode_sub\">සබල කර ඇත්නම් මතුපිට වර්ණය රාත්‍රී ප්‍රකාරයේදී නිරපේක්ෂ අඳුරු ලෙස සකසනු ඇත</string>\n    <string name=\"color_scheme\">වර්ණ පටිපාටිය</string>\n    <string name=\"color_red\">රතු</string>\n    <string name=\"color_green\">කොළ පාටයි</string>\n    <string name=\"color_blue\">නිල්</string>\n    <string name=\"clipboard_paste_invalid_color_code\">වලංගු aRGB වර්ණ කේතයක් අලවන්න</string>\n    <string name=\"clipboard_paste_invalid_empty\">ඇලවීමට කිසිවක් නැත</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">ගතික වර්ණ ක්‍රියාත්මක කර ඇති අතර යෙදුමේ වර්ණ පටිපාටිය වෙනස් කළ නොහැක</string>\n    <string name=\"pick_accent_color\">යෙදුම් තේමාව තෝරාගත් වර්ණය මත පදනම් වනු ඇත</string>\n    <string name=\"about_app\">යෙදුම ගැන</string>\n    <string name=\"no_updates\">යාවත්කාලීන කිසිවක් හමු නොවීය</string>\n    <string name=\"issue_tracker\">නිකුත් කිරීමේ ට්රැකර්</string>\n    <string name=\"issue_tracker_sub\">දෝෂ වාර්තා සහ විශේෂාංග ඉල්ලීම් මෙහි යවන්න</string>\n    <string name=\"help_translate\">පරිවර්තනයට උදව් කරන්න</string>\n    <string name=\"help_translate_sub\">පරිවර්තන දෝෂ නිවැරදි කරන්න හෝ වෙනත් භාෂාවකට ව්‍යාපෘතිය ස්ථානගත කරන්න</string>\n    <string name=\"nothing_found_by_search\">ඔබගේ විමසුමෙන් කිසිවක් සොයා ගත්තේ නැත</string>\n    <string name=\"search_here\">මෙහි සොයන්න</string>\n    <string name=\"dynamic_colors_sub\">සබල කර ඇත්නම්, පසුව යෙදුම් වර්ණ බිතුපත් වර්ණවලට අනුගත වනු ඇත</string>\n    <string name=\"failed_to_save\">%d රූප(ය) සුරැකීමට අසමත් විය</string>\n    <string name=\"email\">ඊමේල් කරන්න</string>\n    <string name=\"primary\">ප්රාථමික</string>\n    <string name=\"tertiary\">තෘතියික</string>\n    <string name=\"secondary\">ද්විතියික</string>\n    <string name=\"border_thickness\">මායිම් ඝණකම</string>\n    <string name=\"surface\">මතුපිට</string>\n    <string name=\"values\">වටිනාකම්</string>\n    <string name=\"add\">එකතු කරන්න</string>\n    <string name=\"permission\">අවසරය</string>\n    <string name=\"grant\">ප්‍රදානය කරන්න</string>\n    <string name=\"permission_sub\">වැඩ කිරීමට පින්තූර සුරැකීමට යෙදුමට ඔබේ ගබඩාවට ප්‍රවේශය අවශ්‍ය වේ, එය අවශ්‍ය වේ. කරුණාකර ඊළඟ සංවාද කොටුවේ අවසරය ලබා දෙන්න.</string>\n    <string name=\"grant_permission_manual\">යෙදුමට ක්‍රියා කිරීමට මෙම අවසරය අවශ්‍යයි, කරුණාකර එය අතින් ලබා දෙන්න</string>\n    <string name=\"external_storage\">බාහිර ගබඩාව</string>\n    <string name=\"monet_colors\">Monet වර්ණ</string>\n    <string name=\"donation_sub\">මෙම යෙදුම සම්පූර්ණයෙන්ම නොමිලේ, නමුත් ඔබට ව්‍යාපෘති සංවර්ධනයට සහාය වීමට අවශ්‍ය නම්, ඔබට මෙහි ක්ලික් කළ හැකිය</string>\n    <string name=\"fab_alignment\">FAB පෙළගැස්ම</string>\n    <string name=\"check_updates\">යාවත්කාලීන සඳහා පරීක්ෂා කරන්න</string>\n    <string name=\"check_updates_sub\">සබල කර ඇත්නම්, යෙදුම් ආරම්භයේදී යාවත්කාලීන සංවාදය ඔබට පෙන්වනු ඇත</string>\n    <string name=\"zoom\">රූප විශාලනය</string>\n    <string name=\"share\">බෙදාගන්න</string>\n    <string name=\"prefix\">උපසර්ගය</string>\n    <string name=\"filename\">ගොනු නාමය</string>\n    <string name=\"emoji\">ඉමොජි</string>\n    <string name=\"emoji_sub\">ප්‍රධාන තිරයේ පෙන්විය යුතු ඉමොජි තෝරන්න</string>\n    <string name=\"add_file_size\">ගොනු ප්රමාණය එකතු කරන්න</string>\n    <string name=\"add_file_size_sub\">සබල කර ඇත්නම්, ප්‍රතිදාන ගොනුවේ නමට සුරකින ලද රූපයේ පළල සහ උස එක් කරයි</string>\n    <string name=\"delete_exif\">EXIF මකන්න</string>\n    <string name=\"delete_exif_sub\">ඕනෑම රූප සමූහයකින් EXIF ​​පාර-දත්ත මකන්න</string>\n    <string name=\"image_preview\">රූප පෙරදසුන</string>\n    <string name=\"image_preview_sub\">ඕනෑම ආකාරයක රූප පෙරදසුන් කරන්න: GIF, SVG, සහ යනාදිය</string>\n    <string name=\"image_source\">රූප මූලාශ්රය</string>\n    <string name=\"photo_picker\">ඡායාරූප පිකර්</string>\n    <string name=\"gallery_picker\">ගැලරිය</string>\n    <string name=\"file_explorer_picker\">ගොනු ගවේෂකය</string>\n    <string name=\"photo_picker_sub\">තිරයේ පහළින් දිස්වන Android නවීන ඡායාරූප පිකර්, ක්‍රියා කළ හැක්කේ android 12+ මත පමණි. EXIF පාර-දත්ත ලබා ගැනීමේ ගැටළු තිබේ</string>\n    <string name=\"gallery_picker_sub\">සරල ගැලරි රූප පිකර්. එය ක්‍රියා කරන්නේ ඔබට මාධ්‍ය තෝරා ගැනීම සපයන යෙදුමක් තිබේ නම් පමණි</string>\n    <string name=\"file_explorer_picker_sub\">රූපය තෝරා ගැනීමට GetContent අභිප්‍රාය භාවිතා කරන්න. සෑම තැනකම ක්‍රියා කරයි, නමුත් සමහර උපාංගවල තෝරාගත් පින්තූර ලැබීමේ ගැටලු ඇති බව දන්නා කරුණකි. ඒක මගේ වරදක් නෙවෙයි.</string>\n    <string name=\"options_arrangement\">විකල්ප සැකැස්ම</string>\n    <string name=\"edit\">සංස්කරණය කරන්න</string>\n    <string name=\"order\">ඇණවුම් කරන්න</string>\n    <string name=\"order_sub\">ප්‍රධාන තිරයේ ඇති මෙවලම් අනුපිළිවෙල තීරණය කරයි</string>\n    <string name=\"emojis_count\">ඉමෝජි ගණන්</string>\n    <string name=\"sequence_num\">අනුක්‍රමික අංකය</string>\n    <string name=\"original_filename\">මුල් ගොනු නාමය</string>\n    <string name=\"add_original_filename\">මුල් ගොනු නාමය එක් කරන්න</string>\n    <string name=\"add_original_filename_sub\">සබල කර ඇත්නම් ප්‍රතිදාන රූපයේ නමට මුල් ගොනු නාමය එක් කරයි</string>\n    <string name=\"replace_sequence_number\">අනුක්‍රමික අංකය ප්‍රතිස්ථාපනය කරන්න</string>\n    <string name=\"replace_sequence_number_sub\">සක්‍රීය කර ඇත්නම්, ඔබ කණ්ඩායම් සැකසීම භාවිතා කරන්නේ නම් සම්මත වේලා මුද්‍රාව රූප අනුක්‍රමික අංකයට ප්‍රතිස්ථාපනය කරයි</string>\n    <string name=\"filename_not_work_with_photopicker\">ෆොටෝ පිකර් පිංතූර මූලාශ්‍රය තේරුවහොත් මුල් ගොනු නාමය එකතු කිරීම ක්‍රියා නොකරයි</string>\n    <string name=\"load_image_from_net\">වෙබ් පින්තූර පූරණය</string>\n    <string name=\"load_image_from_net_sub\">ඔබට අවශ්‍ය නම් එය පෙරදසුන් කිරීමට, විශාලනය කිරීමට, සංස්කරණය කිරීමට සහ සුරැකීමට අන්තර්ජාලයෙන් ඕනෑම රූපයක් පූරණය කරන්න.</string>\n    <string name=\"no_image\">රූපයක් නැත</string>\n    <string name=\"image_link\">රූප සබැඳිය</string>\n    <string name=\"fill\">පුරවන්න</string>\n    <string name=\"fit\">සුදුසුයි</string>\n    <string name=\"content_scale\">අන්තර්ගත පරිමාණය</string>\n    <string name=\"explicit_description\">ලබා දී ඇති උස සහ පළලට රූප ප්‍රතිප්‍රමාණ කරයි. රූපවල දර්ශන අනුපාතය වෙනස් විය හැක.</string>\n    <string name=\"flexible_description\">දී ඇති උසට හෝ පළලට දිගු පැත්තක් සහිත රූප ප්‍රතිප්‍රමාණ කරයි. සියලුම ප්‍රමාණයේ ගණනය කිරීම් සුරැකීමෙන් පසුව සිදු කෙරේ. රූපවල දර්ශන අනුපාතය සුරැකෙනු ඇත.</string>\n    <string name=\"brightness\">දීප්තිය</string>\n    <string name=\"contrast\">පරස්පරතාව</string>\n    <string name=\"hue\">පැහැය</string>\n    <string name=\"saturation\">සන්තෘප්තිය</string>\n    <string name=\"add_filter\">පෙරහන එකතු කරන්න</string>\n    <string name=\"filter\">පෙරහන</string>\n    <string name=\"filter_sub\">පින්තූර සඳහා පෙරහන් දාම යොදන්න</string>\n    <string name=\"filters\">පෙරහන්</string>\n    <string name=\"light_aka_illumination\">ආලෝකය</string>\n    <string name=\"color_filter\">වර්ණ පෙරහන</string>\n    <string name=\"alpha\">ඇල්ෆා</string>\n    <string name=\"exposure\">නිරාවරණය</string>\n    <string name=\"white_balance\">සුදු සමබරතාවය</string>\n    <string name=\"temperature\">උෂ්ණත්වය</string>\n    <string name=\"tint\">ටින්ට්</string>\n    <string name=\"monochrome\">ඒකවර්ණ</string>\n    <string name=\"gamma\">ගැමා</string>\n    <string name=\"highlights_shadows\">ඉස්මතු කිරීම් සහ සෙවනැලි</string>\n    <string name=\"highlights\">ඉස්මතු කිරීම්</string>\n    <string name=\"shadows\">සෙවනැලි</string>\n    <string name=\"haze\">මීදුම</string>\n    <string name=\"effect\">බලපෑම</string>\n    <string name=\"distance\">දුර</string>\n    <string name=\"slope\">බෑවුම</string>\n    <string name=\"sharpen\">තියුණු කරන්න</string>\n    <string name=\"sepia\">සේපියා</string>\n    <string name=\"negative\">සෘණාත්මකයි</string>\n    <string name=\"solarize\">Solarize</string>\n    <string name=\"vibrance\">කම්පනය</string>\n    <string name=\"black_and_white\">කළු සහ සුදු</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">පරතරය</string>\n    <string name=\"line_width\">රේඛා පළල</string>\n    <string name=\"sobel_edge\">සෝබෙල් දාරය</string>\n    <string name=\"blur\">බොඳ කරන්න</string>\n    <string name=\"halftone\">අර්ධ ස්වරය</string>\n    <string name=\"cga_colorspace\">CGA වර්ණ අවකාශය</string>\n    <string name=\"gaussian_blur\">Gaussian බොඳවීම</string>\n    <string name=\"box_blur\">පෙට්ටිය බොඳ වීම</string>\n    <string name=\"bilaterial_blur\">ද්විපාර්ශ්වික බොඳවීම</string>\n    <string name=\"emboss\">එම්බොස් කරන්න</string>\n    <string name=\"laplacian\">ලැප්ලැසියන්</string>\n    <string name=\"vignette\">විග්නෙට්</string>\n    <string name=\"start\">ආරම්භ කරන්න</string>\n    <string name=\"end\">අවසානය</string>\n    <string name=\"kuwahara\">කුවහර සුමටනය</string>\n    <string name=\"stack_blur\">ස්ටැක් බොඳවීම</string>\n    <string name=\"radius\">අරය</string>\n    <string name=\"scale\">පරිමාණය</string>\n    <string name=\"distortion\">විකෘතිය</string>\n    <string name=\"angle\">කෝණය</string>\n    <string name=\"swirl\">කරකැවිල්ල</string>\n    <string name=\"bulge\">බල්ජ්</string>\n    <string name=\"dilation\">විස්තාරණය</string>\n    <string name=\"sphere_refraction\">ගෝල වර්තනය</string>\n    <string name=\"refractive_index\">වර්තන දර්ශකය</string>\n    <string name=\"glass_sphere_refraction\">වීදුරු ගෝල වර්තනය</string>\n    <string name=\"color_matrix\">වර්ණ අනුකෘතිය</string>\n    <string name=\"opacity\">පාරාන්ධතාව</string>\n    <string name=\"limits_resize\">සීමාවන් අනුව ප්‍රමාණය වෙනස් කරන්න</string>\n    <string name=\"limits_resize_sub\">දර්ශන අනුපාතය තබා ගනිමින් ලබා දී ඇති උස සහ පළලට රූප ප්‍රතිප්‍රමාණ කරන්න</string>\n    <string name=\"sketch\">ස්කීච්</string>\n    <string name=\"threshold\">එළිපත්ත</string>\n    <string name=\"quantizationLevels\">ප්‍රමාණකරණ මට්ටම්</string>\n    <string name=\"smooth_toon\">සිනිඳු ටූන්</string>\n    <string name=\"toon\">ටූන්</string>\n    <string name=\"posterize\">පෝස්ටර් කරන්න</string>\n    <string name=\"non_maximum_suppression\">උපරිම නොවන මර්දනය</string>\n    <string name=\"weak_pixel_inclusion\">දුර්වල පික්සල් ඇතුළත් කිරීම</string>\n    <string name=\"lookup\">සොයන්න</string>\n    <string name=\"convolution3x3\">Convolution 3x3</string>\n    <string name=\"rgb_filter\">RGB පෙරහන</string>\n    <string name=\"false_color\">බොරු පාට</string>\n    <string name=\"first_color\">පළමු වර්ණය</string>\n    <string name=\"second_color\">දෙවන වර්ණය</string>\n    <string name=\"reorder\">නැවත ඇණවුම් කරන්න</string>\n    <string name=\"fast_blur\">වේගවත් නොපැහැදිලි</string>\n    <string name=\"blur_size\">බොඳ ප්‍රමාණය</string>\n    <string name=\"blur_center_x\">නොපැහැදිලි කේන්ද්‍රය x</string>\n    <string name=\"blur_center_y\">බොඳ මධ්‍යස්ථානය y</string>\n    <string name=\"zoom_blur\">විශාලනය බොඳ කිරීම</string>\n    <string name=\"color_balance\">වර්ණ ශේෂය</string>\n    <string name=\"luminance_threshold\">දීප්තිය එළිපත්ත</string>\n    <string name=\"activate_files\">ඔබ ගොනු යෙදුම අබල කර ඇත, මෙම විශේෂාංගය භාවිතා කිරීමට එය සක්‍රිය කරන්න</string>\n    <string name=\"draw\">අඳින්න</string>\n    <string name=\"draw_sub\">ස්කීච් පොතක මෙන් රූපය මත අඳින්න, නැතහොත් පසුබිම මතම අඳින්න</string>\n    <string name=\"paint_color\">තීන්ත වර්ණය</string>\n    <string name=\"paint_alpha\">ඇල්ෆා තීන්ත ආලේප කරන්න</string>\n    <string name=\"draw_on_image\">රූපය මත අඳින්න</string>\n    <string name=\"draw_on_image_sub\">රූපයක් තෝරා එය මත යමක් අඳින්න</string>\n    <string name=\"draw_on_background\">පසුබිම මත ඇඳීම</string>\n    <string name=\"draw_on_background_sub\">පසුබිම් වර්ණය තෝරා එය මත අඳින්න</string>\n    <string name=\"background_color\">පසුබිම් වර්ණය</string>\n    <string name=\"cipher\">කේතාංකය</string>\n    <string name=\"cipher_sub\">පවතින විවිධ ක්‍රිප්ටෝ ඇල්ගොරිතම මත පදනම්ව ඕනෑම ගොනුවක් (රූපය පමණක් නොව) සංකේතනය කර විකේතනය කරන්න</string>\n    <string name=\"pick_file\">ගොනුව තෝරන්න</string>\n    <string name=\"encrypt\">සංකේතනය කරන්න</string>\n    <string name=\"decrypt\">විකේතනය කරන්න</string>\n    <string name=\"pick_file_to_start\">ආරම්භ කිරීමට ගොනුව තෝරන්න</string>\n    <string name=\"decryption\">විකේතනය</string>\n    <string name=\"encryption\">සංකේතනය</string>\n    <string name=\"key\">යතුර</string>\n    <string name=\"file_proceed\">ගොනුව සකසා ඇත</string>\n    <string name=\"store_file_desc\">මෙම ගොනුව ඔබගේ උපාංගයේ ගබඩා කරන්න නැතහොත් ඔබට අවශ්‍ය ඕනෑම තැනක තැබීමට බෙදාගැනීමේ ක්‍රියාව භාවිතා කරන්න</string>\n    <string name=\"features\">විශේෂාංග</string>\n    <string name=\"implementation\">ක්රියාත්මක කිරීම</string>\n    <string name=\"compatibility\">ගැළපුම</string>\n    <string name=\"features_sub\">මුරපදය මත පදනම් වූ ගොනු සංකේතනය කිරීම. ලබාගත් ගොනු තෝරාගත් නාමාවලියෙහි ගබඩා කර හෝ බෙදාගත හැක. විකේතනය කරන ලද ගොනු ද කෙලින්ම විවෘත කළ හැකිය.</string>\n    <string name=\"implementation_sub\">AES-256, GCM මාදිලිය, පිරවුමක් නැත, පෙරනිමියෙන් බයිට් 12 අහඹු IVs. ඔබට අවශ්ය ඇල්ගොරිතම තෝරාගත හැක. යතුරු 256-bit SHA-3 හැෂ් ලෙස භාවිතා කරයි</string>\n    <string name=\"file_size\">ගොනු විශාලත්වය</string>\n    <string name=\"file_size_sub\">උපරිම ගොනු ප්‍රමාණය Android OS සහ පවතින මතකය මගින් සීමා කර ඇත, එය උපාංගය මත රඳා පවතී.\n\\nකරුණාකර සලකන්න: මතකය ගබඩා කිරීම නොවේ.</string>\n    <string name=\"compatibility_sub\">වෙනත් ගොනු සංකේතාංකන මෘදුකාංග හෝ සේවාවන් සඳහා ගැළපුම සහතික නොවන බව කරුණාවෙන් සලකන්න. තරමක් වෙනස් යතුරු ප්‍රතිකාරයක් හෝ කේතාංක වින්‍යාසයක් නොගැලපීම ඇති කළ හැකිය.</string>\n    <string name=\"invalid_password_or_not_encrypted\">වලංගු නොවන මුරපදයක් හෝ තෝරාගත් ගොනුවක් සංකේතනය කර නොමැත</string>\n    <string name=\"image_size_warning\">ලබා දී ඇති පළල සහ උස සමඟ රූපය සුරැකීමට උත්සාහ කිරීම මතකයේ දෝෂයක් ඇති විය හැක. මෙය ඔබේම අවදානමකින් කරන්න.</string>\n    <string name=\"cache\">හැඹිලිය</string>\n    <string name=\"cache_size\">හැඹිලි ප්රමාණය</string>\n    <string name=\"found_s\">%1$s හමු විය</string>\n    <string name=\"auto_cache_clearing\">ස්වයංක්‍රීය හැඹිලි ඉවත් කිරීම</string>\n    <string name=\"auto_cache_clearing_sub\">සබල කර ඇත්නම් යෙදුම් හැඹිලිය යෙදුම් ආරම්භයේදී හිස් කරනු ඇත</string>\n    <string name=\"create\">නිර්මාණය කරන්න</string>\n    <string name=\"tools\">මෙවලම්</string>\n    <string name=\"group_options_by_type\">වර්ගය අනුව කණ්ඩායම් විකල්ප</string>\n    <string name=\"group_options_by_type_sub\">අභිරුචි ලැයිස්තු සැකැස්මක් වෙනුවට ඒවායේ වර්ගය අනුව ප්‍රධාන තිරය මත කණ්ඩායම් විකල්ප</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">විකල්ප සමූහකරණය සබල කර ඇති අතර විධිවිධාන වෙනස් කළ නොහැක</string>\n    <string name=\"edit_screenshot\">තිර රුවක් සංස්කරණය කරන්න</string>\n    <string name=\"secondary_customization\">ද්විතියික අභිරුචිකරණය</string>\n    <string name=\"screenshot\">තිර රුවක්</string>\n    <string name=\"fallback_option\">ආපසු හැරීමේ විකල්පය</string>\n    <string name=\"skip\">මඟ හරින්න</string>\n    <string name=\"copy\">පිටපත් කරන්න</string>\n    <string name=\"warning_bytes\">%1$s මාදිලියේ සුරැකීම අස්ථායී විය හැක, මන්ද එය පාඩු රහිත ආකෘතියකි</string>\n    <string name=\"presets_sub\">ඔබ පෙරසිටූ 125 තෝරාගෙන තිබේ නම්, රූපය මුල් රූපයේ 125% ප්‍රමාණය ලෙස සුරකිනු ඇත. ඔබ පෙරසිටූ 50 තෝරා ගන්නේ නම්, එවිට රූපය 50% ප්‍රමාණයෙන් සුරකිනු ඇත</string>\n    <string name=\"presets_sub_bytes\">මෙහි පෙරසිටීම මඟින් ප්‍රතිදාන ගොනුවේ % තීරණය කරයි, එනම් ඔබ 5 MB රූපයේ පෙරසිටූ 50 තෝරා ගන්නේ නම්, සුරැකීමෙන් පසු ඔබට 2,5 MB රූපයක් ලැබෙනු ඇත.</string>\n    <string name=\"randomize_filename\">ගොනු නාමය සසම්භාවී කරන්න</string>\n    <string name=\"randomize_filename_sub\">සබල කර ඇත්නම් ප්‍රතිදාන ගොනු නාමය සම්පූර්ණයෙන්ම අහඹු වේ</string>\n    <string name=\"saved_to\">%2$s නම සහිත %1$s ෆෝල්ඩරය වෙත සුරකින ලදී</string>\n    <string name=\"saved_to_without_filename\">%1$s ෆෝල්ඩරය වෙත සුරකින ලදී</string>\n    <string name=\"tg_chat\">ටෙලිග්‍රාම් කතාබස්</string>\n    <string name=\"tg_chat_sub\">යෙදුම ගැන සාකච්ඡා කර වෙනත් පරිශීලකයින්ගෙන් ප්‍රතිපෝෂණ ලබා ගන්න. ඔබට එහි බීටා යාවත්කාලීන සහ විදසුන් ද ලබා ගත හැක.</string>\n    <string name=\"crop_mask\">බෝග මාස්ක්</string>\n    <string name=\"aspect_ratio\">දර්ශන අනුපාතය</string>\n    <string name=\"image_crop_mask_sub\">ලබා දී ඇති රූපයෙන් වෙස් මුහුණු සෑදීමට මෙම ආවරණ වර්ගය භාවිතා කරන්න, එහි ඇල්ෆා නාලිකාව තිබිය යුතු බව සලකන්න</string>\n    <string name=\"backup_and_restore\">උපස්ථ සහ ප්රතිෂ්ඨාපනය</string>\n    <string name=\"backup\">උපස්ථ</string>\n    <string name=\"restore\">ප්‍රතිෂ්ඨාපනය කරන්න</string>\n    <string name=\"backup_sub\">ඔබගේ යෙදුම් සැකසීම් ගොනුවකට උපස්ථ කරන්න</string>\n    <string name=\"restore_sub\">කලින් ජනනය කළ ගොනුවෙන් යෙදුම් සැකසුම් ප්‍රතිසාධනය කරන්න</string>\n    <string name=\"corrupted_file_or_not_a_backup\">දූෂිත ගොනුවක් හෝ උපස්ථයක් නොවේ</string>\n    <string name=\"settings_restored\">සැකසීම් සාර්ථකව ප්‍රතිසාධනය කරන ලදී</string>\n    <string name=\"contact_me\">මාව සම්බන්ධ කරගන්න</string>\n    <string name=\"reset_settings_sub\">මෙය ඔබගේ සැකසුම් පෙරනිමි අගයන් වෙත පෙරළනු ඇත. ඉහත සඳහන් කළ උපස්ථ ගොනුවක් නොමැතිව මෙය පසුගමනය කළ නොහැකි බව සලකන්න.</string>\n    <string name=\"delete\">මකන්න</string>\n    <string name=\"delete_color_scheme_warn\">ඔබ තෝරාගත් වර්ණ පටිපාටිය මකා දැමීමට සූදානම් වේ. මෙම මෙහෙයුම පසුගමනය කළ නොහැක</string>\n    <string name=\"delete_color_scheme_title\">යෝජනා ක්රමය මකන්න</string>\n    <string name=\"font\">අකුරු</string>\n    <string name=\"text\">පෙළ</string>\n    <string name=\"font_scale\">අකුරු පරිමාණය</string>\n    <string name=\"defaultt\">පෙරනිමිය</string>\n    <string name=\"using_large_fonts_warn\">විශාල අකුරු පරිමාණයන් භාවිතා කිරීමෙන් UI දෝෂ සහ ගැටළු ඇති විය හැක, ඒවා නිවැරදි නොවනු ඇත. පරිස්සමෙන් භාවිතා කරන්න.</string>\n    <string name=\"alphabet_and_numbers\">අ ආ ඇ ඈ ඉ ඊ උ ඌ එ ඒ ඔ ඕ ක ග ච ජ ට ඩ ත ද න ප බ ම ය ර ල ව ස හ 0123456789 !?</string>\n    <string name=\"emotions\">හැඟීම්</string>\n    <string name=\"food_and_drink\">ආහාර සහ බීම</string>\n    <string name=\"nature_and_animals\">සොබාදහම සහ සතුන්</string>\n    <string name=\"objects\">වස්තු</string>\n    <string name=\"symbols\">සංකේත</string>\n    <string name=\"enable_emoji\">ඉමොජි සබල කරන්න</string>\n    <string name=\"travels_and_places\">සංචාර සහ ස්ථාන</string>\n    <string name=\"activities\">ක්රියාකාරකම්</string>\n    <string name=\"background_remover\">පසුබිම් ඉවත් කරන්නා</string>\n    <string name=\"background_remover_sub\">චිත්‍ර ඇඳීමෙන් හෝ ස්වයංක්‍රීය විකල්පය භාවිතා කිරීමෙන් රූපයෙන් පසුබිම ඉවත් කරන්න</string>\n    <string name=\"trim_image\">රූපය කපා දමන්න</string>\n    <string name=\"keep_exif_sub\">මුල් රූප පාරදත්ත තබා ගනු ඇත</string>\n    <string name=\"trim_image_sub\">රූපය වටා ඇති විනිවිද පෙනෙන අවකාශයන් කපා හරිනු ලැබේ</string>\n    <string name=\"auto_erase_background\">පසුබිම ස්වයංක්‍රීයව මකා දැමීම</string>\n    <string name=\"restore_image\">රූපය ප්‍රතිසාධනය කරන්න</string>\n    <string name=\"erase_mode\">මකන ආකාරය</string>\n    <string name=\"erase_background\">පසුබිම මකන්න</string>\n    <string name=\"restore_background\">පසුබිම ප්‍රතිසාධනය කරන්න</string>\n    <string name=\"blur_radius\">බොඳ අරය</string>\n    <string name=\"pipette\">පයිප්පෙට්</string>\n    <string name=\"draw_mode\">ඇඳීම් මාදිලිය</string>\n    <string name=\"create_issue\">ගැටලුවක් සාදන්න</string>\n    <string name=\"something_went_wrong_emphasis\">අපොයි… යමක් වැරදී ඇත. පහත විකල්ප භාවිතයෙන් ඔබට මට ලිවිය හැකි අතර මම විසඳුමක් සෙවීමට උත්සාහ කරමි</string>\n    <string name=\"resize_and_convert\">ප්‍රමාණය වෙනස් කර පරිවර්තනය කරන්න</string>\n    <string name=\"resize_and_convert_sub\">ලබා දී ඇති පින්තූරවල ප්‍රමාණය වෙනස් කරන්න හෝ ඒවා වෙනත් ආකෘතිවලට පරිවර්තනය කරන්න. තනි රූපයක් තෝරා ගන්නේ නම් EXIF ​​පාරදත්ත ද මෙහි සංස්කරණය කළ හැක.</string>\n    <string name=\"max_colors_count\">උපරිම වර්ණ ගණන</string>\n    <string name=\"crashlytics_sub\">මෙය යෙදුමට බිඳ වැටීම් වාර්තා ස්වයංක්‍රීයව රැස් කිරීමට ඉඩ සලසයි</string>\n    <string name=\"analytics\">විශ්ලේෂණ</string>\n    <string name=\"analytics_sub\">නිර්නාමික යෙදුම් භාවිත සංඛ්‍යාලේඛන එකතු කිරීමට ඉඩ දෙන්න</string>\n    <string name=\"image_exif_warning\">දැනට, %1$s ආකෘතියෙන් ඉඩ දෙන්නේ android මත EXIF ​​පාරදත්ත කියවීමට පමණි. ප්‍රතිදාන රූපය සුරකින විට පාරදත්ත කිසිසේත්ම නොතිබෙනු ඇත.</string>\n    <string name=\"effort\">උත්සාහය</string>\n    <string name=\"effort_sub\">%1$s අගයක් යනු වේගවත් සම්පීඩනයක්, ප්‍රතිඵලයක් ලෙස සාපේක්ෂ විශාල ගොනු ප්‍රමාණයකි. %2$s යනු මන්දගාමී සම්පීඩනය, කුඩා ගොනුවක් ඇති කරයි.</string>\n    <string name=\"wait\">ඉන්න</string>\n    <string name=\"saving_almost_complete\">සුරැකීම බොහෝ දුරට සම්පූර්ණයි. දැන් අවලංගු කිරීමට නැවත සුරැකීමට අවශ්‍ය වනු ඇත.</string>\n    <string name=\"updates\">යාවත්කාලීන</string>\n    <string name=\"allow_betas\">බීටා වලට ඉඩ දෙන්න</string>\n    <string name=\"allow_betas_sub\">යාවත්කාලීන පරීක්ෂාව සබල කර ඇත්නම් බීටා යෙදුම් අනුවාද ඇතුළත් වේ</string>\n    <string name=\"draw_arrows\">ඊතල අඳින්න</string>\n    <string name=\"draw_arrows_sub\">සබල කර ඇත්නම් ඇඳීමේ මාර්ගය යොමු ඊතලයක් ලෙස නිරූපණය කෙරේ</string>\n    <string name=\"brush_softness\">බුරුසු මෘදු බව</string>\n    <string name=\"crop_description\">පින්තූර ඇතුල් කළ ප්‍රමාණයට මැදට කපා ඇත. ඇතුළු කළ මානයන්ට වඩා රූපය කුඩා නම්, ලබා දී ඇති පසුබිම් වර්ණය සමඟ කැන්වසය පුළුල් කෙරේ.</string>\n    <string name=\"donation\">පරිත්යාග කිරීම</string>\n    <string name=\"image_stitching\">රූප මැසීම</string>\n    <string name=\"image_stitching_sub\">එක් විශාල එකක් ලබා ගැනීමට ලබා දී ඇති පින්තූර ඒකාබද්ධ කරන්න</string>\n    <string name=\"pick_at_least_two_images\">අවම වශයෙන් පින්තූර 2ක්වත් තෝරන්න</string>\n    <string name=\"output_image_scale\">ප්රතිදාන රූප පරිමාණය</string>\n    <string name=\"image_orientation\">රූප දිශානතිය</string>\n    <string name=\"horizontal\">තිරස්</string>\n    <string name=\"vertical\">සිරස් අතට</string>\n    <string name=\"scale_small_images_to_large\">කුඩා පින්තූර විශාල කිරීමට පරිමාණය කරන්න</string>\n    <string name=\"scale_small_images_to_large_sub\">සක්රිය කළහොත් කුඩා පින්තූර අනුපිළිවෙලෙහි විශාලතම එක දක්වා පරිමාණය කරනු ලැබේ</string>\n    <string name=\"images_order\">පින්තූර අනුපිළිවෙල</string>\n    <string name=\"regular\">නිතිපතා</string>\n    <string name=\"blur_edges\">දාර බොඳ කරන්න</string>\n    <string name=\"blur_edges_sub\">සබල කර ඇත්නම් තනි වර්ණයක් වෙනුවට අවට අවකාශය පිරවීමට මුල් රූපය යටතේ බොඳ වූ දාර අඳින්න</string>\n    <string name=\"pixelation\">පික්සලේෂන්</string>\n    <string name=\"enhanced_pixelation\">වැඩි දියුණු කළ පික්සලේෂන්</string>\n    <string name=\"stroke_pixelation\">ආඝාත පික්සලේෂන්</string>\n    <string name=\"enhanced_diamond_pixelation\">වැඩිදියුණු කළ දියමන්ති පික්සලේෂන්</string>\n    <string name=\"diamond_pixelation\">දියමන්ති පික්සලේෂන්</string>\n    <string name=\"circle_pixelation\">Circle Pixelation</string>\n    <string name=\"enhanced_circle_pixelation\">වැඩිදියුණු කළ කව පික්සලේෂන්</string>\n    <string name=\"replace_color\">වර්ණය ප්රතිස්ථාපනය කරන්න</string>\n    <string name=\"tolerance\">ඉවසීම</string>\n    <string name=\"color_to_replace\">ප්‍රතිස්ථාපනය කිරීමට වර්ණය</string>\n    <string name=\"target_color\">ඉලක්ක වර්ණය</string>\n    <string name=\"color_to_remove\">ඉවත් කිරීමට වර්ණය</string>\n    <string name=\"remove_color\">වර්ණය ඉවත් කරන්න</string>\n    <string name=\"recode\">Recode කරන්න</string>\n    <string name=\"pixel_size\">පික්සල් ප්‍රමාණය</string>\n    <string name=\"lock_draw_orientation\">අගුළු ඇඳීම දිශානතිය</string>\n    <string name=\"lock_draw_orientation_sub\">ඇඳීම් ආකාරයෙන් සබල කර ඇත්නම්, තිරය භ්‍රමණය නොවේ</string>\n    <string name=\"check_for_updates\">යාවත්කාලීන සඳහා පරීක්ෂා කරන්න</string>\n    <string name=\"palette_style\">පැලට් විලාසය</string>\n    <string name=\"tonal_spot\">ටෝනල් ස්පෝට්</string>\n    <string name=\"neutral\">මධ්යස්ථ</string>\n    <string name=\"vibrant\">කම්පිත</string>\n    <string name=\"expressive\">ප්රකාශිත</string>\n    <string name=\"rainbow\">දේදුනු</string>\n    <string name=\"fruit_salad\">පළතුරු සලාද</string>\n    <string name=\"fidelity\">විශ්වාසවන්තකම</string>\n    <string name=\"content\">අන්තර්ගතය</string>\n    <string name=\"tonal_spot_sub\">පෙරනිමි පැලට් විලාසය, එය වර්ණ හතරම අභිරුචිකරණය කිරීමට ඉඩ සලසයි, අනෙක් ඒවා ඔබට ප්‍රධාන වර්ණය පමණක් සැකසීමට ඉඩ දෙයි</string>\n    <string name=\"neutral_sub\">ඒකවර්ණයට වඩා තරමක් වර්ණවත් මෝස්තරයක්</string>\n    <string name=\"vibrant_sub\">ඝෝෂාකාරී තේමාවක්, ප්‍රාථමික තලය සඳහා වර්ණවත් බව උපරිම වේ, අනෙක් අයට වැඩි වේ</string>\n    <string name=\"playful_scheme\">සෙල්ලක්කාර තේමාවක් - මූලාශ්‍ර වර්ණයෙහි පැහැය තේමාව තුළ දිස් නොවේ</string>\n    <string name=\"monochrome_sub\">ඒකවර්ණ තේමාවක්, වර්ණ සම්පූර්ණයෙන්ම කළු / සුදු / අළු වේ</string>\n    <string name=\"content_sub\">Scheme.primaryContainer හි මූලාශ්‍ර වර්ණය ස්ථානගත කරන යෝජනා ක්‍රමයක්</string>\n    <string name=\"fidelity_sub\">අන්තර්ගත යෝජනා ක්‍රමයට බෙහෙවින් සමාන යෝජනා ක්‍රමයක්</string>\n    <string name=\"foss_update_checker_warning\">මෙම යාවත්කාලීන පරීක්ෂකය GitHub වෙත සම්බන්ධ වන්නේ නව යාවත්කාලීනයක් තිබේ දැයි පරීක්ෂා කිරීම සඳහා ය</string>\n    <string name=\"attention\">අවධානය</string>\n    <string name=\"fading_edges\">වියැකී යන දාර</string>\n    <string name=\"disabled\">ආබාධිතයි</string>\n    <string name=\"both\">දෙකම</string>\n    <string name=\"invert_colors\">වර්ණ පෙරළන්න</string>\n    <string name=\"invert_colors_sub\">සබල කර ඇත්නම් තේමා වර්ණ සෘණ ඒවාට ප්‍රතිස්ථාපනය කරයි</string>\n    <string name=\"search_option\">සොයන්න</string>\n    <string name=\"search_option_sub\">ප්‍රධාන තිරයේ ඇති සියලුම මෙවලම් හරහා සෙවීමේ හැකියාව සබල කරයි</string>\n    <string name=\"pdf_tools\">PDF මෙවලම්</string>\n    <string name=\"pdf_tools_sub\">PDF ගොනු සමඟ ක්‍රියා කරන්න: පෙරදසුන්, රූප සමූහයට පරිවර්තනය කරන්න හෝ ලබා දී ඇති පින්තූරවලින් එකක් සාදන්න</string>\n    <string name=\"preview_pdf\">PDF පෙරදසුන් කරන්න</string>\n    <string name=\"pdf_to_images\">පින්තූර වෙත PDF</string>\n    <string name=\"images_to_pdf\">පින්තූර PDF වෙත</string>\n    <string name=\"preview_pdf_sub\">සරල PDF පෙරදසුන</string>\n    <string name=\"pdf_to_images_sub\">ලබා දී ඇති ප්‍රතිදාන ආකෘතියෙන් පින්තූර PDF බවට පරිවර්තනය කරන්න</string>\n    <string name=\"images_to_pdf_sub\">ලබා දී ඇති පින්තූර PDF ගොනුවකට අසුරන්න</string>\n    <string name=\"mask_filter\">මාස්ක් ෆිල්ටරය</string>\n    <string name=\"mask_filter_sub\">ලබා දී ඇති මාස්ක් ප්‍රදේශ මත පෙරහන් දාම යොදන්න, සෑම වෙස් මුහුණු ප්‍රදේශයකටම තමන්ගේම පෙරහන් කට්ටලයක් තීරණය කළ හැකිය</string>\n    <string name=\"masks\">වෙස් මුහුණු</string>\n    <string name=\"add_mask\">මාස්ක් එකතු කරන්න</string>\n    <string name=\"mask_indexed\">වෙස්මුහුණ %d</string>\n    <string name=\"mask_color\">මාස්ක් වර්ණය</string>\n    <string name=\"mask_preview\">මාස්ක් පෙරදසුන</string>\n    <string name=\"mask_preview_sub\">ඔබට ආසන්න ප්‍රතිඵලය පෙන්වීමට ඇද ගන්නා ලද පෙරහන් වෙස් මුහුණ විදහා දක්වනු ඇත</string>\n    <string name=\"inverse_fill_type\">ප්රතිලෝම පිරවුම් වර්ගය</string>\n    <string name=\"inverse_fill_type_sub\">සබල කර ඇත්නම්, පෙරනිමි හැසිරීම වෙනුවට වෙස්මුහුණු නොවන ප්‍රදේශ සියල්ලම පෙරීම සිදු කෙරේ</string>\n    <string name=\"delete_mask_warn\">ඔබ තෝරන ලද පෙරහන් ආවරණය මැකීමට සූදානම් වේ. මෙම මෙහෙයුම පසුගමනය කළ නොහැක</string>\n    <string name=\"delete_mask\">වෙස් මුහුණ මකන්න</string>\n    <string name=\"full_filter\">සම්පූර්ණ පෙරහන</string>\n    <string name=\"full_filter_sub\">ලබා දී ඇති පින්තූර හෝ තනි රූපයට ඕනෑම පෙරහන් දාමයක් යොදන්න</string>\n    <string name=\"start_position\">ආරම්භ කරන්න</string>\n    <string name=\"center_position\">මධ්යස්ථානය</string>\n    <string name=\"end_position\">අවසානය</string>\n    <string name=\"simple_variants\">සරල ප්රභේද</string>\n    <string name=\"highlighter\">උද්දීපනය කරන්නා</string>\n    <string name=\"neon\">නියොන්</string>\n    <string name=\"pen\">පෑන</string>\n    <string name=\"privacy_blur\">රහස්‍යතා බොඳවීම</string>\n    <string name=\"highlighter_sub\">අර්ධ පාරදෘශ්‍ය තියුණු කරන ලද උද්දීපන මාර්ග අඳින්න</string>\n    <string name=\"neon_sub\">ඔබේ චිත්‍රවලට දීප්තිමත් බලපෑමක් එක් කරන්න</string>\n    <string name=\"pen_sub\">පෙරනිමි එක, සරලම - වර්ණය පමණි</string>\n    <string name=\"privacy_blur_sub\">ඔබට සැඟවීමට අවශ්‍ය ඕනෑම දෙයක් සුරක්ෂිත කිරීමට ඇඳ ඇති මාර්ගය යටතේ රූපය බොඳ කරයි</string>\n    <string name=\"pixelation_sub\">රහස්‍යතා බොඳ කිරීමට සමාන, නමුත් බොඳ කිරීම වෙනුවට පික්සලේට්</string>\n    <string name=\"containers_shadow\">බහාලුම්</string>\n    <string name=\"containers_shadow_sub\">බහාලුම් පිටුපස සෙවනැල්ලක් අඳින්න</string>\n    <string name=\"sliders_shadow\">ස්ලයිඩර්</string>\n    <string name=\"switches_shadow\">ස්විචයන්</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">බොත්තම්</string>\n    <string name=\"sliders_shadow_sub\">ස්ලයිඩර් පිටුපස සෙවනැල්ලක් අඳින්න</string>\n    <string name=\"switches_shadow_sub\">ස්විචයන් පිටුපස සෙවනැල්ලක් අඳින්න</string>\n    <string name=\"fabs_shadow_sub\">පාවෙන ක්‍රියා බොත්තම් පිටුපස සෙවනැල්ලක් අඳින්න</string>\n    <string name=\"buttons_shadow_sub\">බොත්තම් පිටුපස සෙවනැල්ලක් අඳින්න</string>\n    <string name=\"app_bars_shadow\">යෙදුම් තීරු</string>\n    <string name=\"app_bars_shadow_sub\">යෙදුම් තීරු පිටුපස සෙවනැල්ලක් අඳින්න</string>\n    <string name=\"value_in_range\">%1$s - %2$s පරාසයේ අගය</string>\n    <string name=\"auto_rotate_limits\">ස්වයංක්‍රීය කරකවන්න</string>\n    <string name=\"auto_rotate_limits_sub\">රූප දිශානතිය සඳහා සීමා පෙට්ටිය භාවිතා කිරීමට ඉඩ දෙයි</string>\n    <string name=\"draw_path_mode\">මාර්ග මාදිලිය අඳින්න</string>\n    <string name=\"double_line_arrow\">ද්විත්ව රේඛා ඊතලය</string>\n    <string name=\"free_drawing\">නොමිලේ ඇඳීම</string>\n    <string name=\"double_arrow\">ද්විත්ව ඊතලය</string>\n    <string name=\"line_arrow\">රේඛා ඊතලය</string>\n    <string name=\"arrow\">ඊතලය</string>\n    <string name=\"line\">රේඛාව</string>\n    <string name=\"free_drawing_sub\">ආදාන අගය ලෙස මාර්ගය අඳින්න</string>\n    <string name=\"line_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා මාර්ගය රේඛාවක් ලෙස අඳින්න</string>\n    <string name=\"line_arrow_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා ඉරක් ලෙස යොමු කරන ඊතල අඳින්න</string>\n    <string name=\"arrow_sub\">දී ඇති මාර්ගයකින් යොමු ඊතලයක් අඳින්න</string>\n    <string name=\"double_line_arrow_sub\">රේඛාවක් ලෙස ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා ද්විත්ව යොමු ඊතලය අඳින්න</string>\n    <string name=\"double_arrow_sub\">දී ඇති මාර්ගයකින් ද්විත්ව යොමු ඊතලයක් අඳින්න</string>\n    <string name=\"outlined_oval\">දළ සටහන් ඕවල්</string>\n    <string name=\"outlined_rect\">දක්වා ඇති Rect</string>\n    <string name=\"oval\">ඕවලාකාර</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා සෘජුව අඳින්න</string>\n    <string name=\"oval_sub\">ආරම්භක ස්ථානයේ සිට අවසන් ස්ථානය දක්වා ඕවලාකාර අඳින්න</string>\n    <string name=\"outlined_oval_sub\">ආරම්භක ස්ථානයේ සිට අවසාන ලක්ෂ්‍යය දක්වා ගෙනහැර දක්වන ලද ඕවලාකාර අඳින්න</string>\n    <string name=\"outlined_rect_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසන් ස්ථානය දක්වා ගෙනහැර දක්වන ලද සෘජුකෝණාස්‍රය අඳින්න</string>\n    <string name=\"lasso\">ලස්සෝ</string>\n    <string name=\"lasso_sub\">ලබා දී ඇති මාර්ගය අනුව වසා දැමූ පිරවූ මාර්ගය අඳින්න</string>\n    <string name=\"free\">නොමිලේ</string>\n    <string name=\"horizontal_grid\">තිරස් ජාලකය</string>\n    <string name=\"vertical_grid\">සිරස් ජාලකය</string>\n    <string name=\"stitch_mode\">මැහුම් මාදිලිය</string>\n    <string name=\"rows_count\">පේළි ගණන</string>\n    <string name=\"columns_count\">තීරු ගණන</string>\n    <string name=\"no_such_directory\">\\\"%1$s\\\" නාමාවලියක් හමු නොවීය, අපි එය පෙරනිමි එකට මාරු කළෙමු, කරුණාකර ගොනුව නැවත සුරකින්න</string>\n    <string name=\"clipboard\">පසුරු පුවරුව</string>\n    <string name=\"auto_pin\">ස්වයංක්‍රීය පින්</string>\n    <string name=\"auto_pin_sub\">සබල කර ඇත්නම් ස්වයංක්‍රීයව සුරකින ලද රූපය පසුරු පුවරුවට එක් කරයි</string>\n    <string name=\"vibration\">කම්පනය</string>\n    <string name=\"vibration_strength\">කම්පන ශක්තිය</string>\n    <string name=\"overwrite_file_requirements\">ගොනු උඩින් ලිවීම සඳහා ඔබට \\\"Explorer\\\" රූප මූලාශ්‍රය භාවිතා කිරීමට අවශ්‍ය වේ, පින්තූර නැවත කිරීමට උත්සාහ කරන්න, අපි අවශ්‍ය එක වෙත රූප මූලාශ්‍රය වෙනස් කර ඇත.</string>\n    <string name=\"overwrite_files\">ගොනු උඩින් ලියන්න</string>\n    <string name=\"overwrite_files_sub\">තෝරාගත් ෆෝල්ඩරය තුළ සුරැකීම වෙනුවට මුල් ගොනුව අලුත් එකක් සමඟ ප්‍රතිස්ථාපනය වනු ඇත, මෙම විකල්පය රූප මූලාශ්‍රය \\\"Explorer\\\" හෝ GetContent විය යුතුය, මෙය ටොගල් කරන විට, එය ස්වයංක්‍රීයව සකසනු ඇත.</string>\n    <string name=\"empty\">හිස්</string>\n    <string name=\"suffix\">උපසර්ගය</string>\n    <string name=\"scale_mode\">පරිමාණ මාදිලිය</string>\n    <string name=\"bilinear\">බිලීනියර්</string>\n    <string name=\"catmull\">කැට්මුල්</string>\n    <string name=\"bicubic\">බයිකුබික්</string>\n    <string name=\"hann\">ඔහු</string>\n    <string name=\"hermite\">අසපුව</string>\n    <string name=\"lanczos\">ලැන්සෝස්</string>\n    <string name=\"mitchell\">මිචෙල්</string>\n    <string name=\"nearest\">ආසන්නතම</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">මූලික</string>\n    <string name=\"default_value\">පෙරනිමි අගය</string>\n    <string name=\"bilinear_sub\">රේඛීය (හෝ ද්විපාර්ශ්වික, මාන දෙකකින්) මැදිහත්වීම රූපයේ ප්‍රමාණය වෙනස් කිරීම සඳහා සාමාන්‍යයෙන් හොඳ වේ, නමුත් සමහර අනවශ්‍ය ලෙස විස්තර මෘදු කිරීමට හේතු වන අතර එය තවමත් තරමක් හකුරු විය හැක.</string>\n    <string name=\"bicubic_sub\">වඩා හොඳ පරිමාණ කිරීමේ ක්‍රමවලට Lanczos resampling සහ Mitchell-Netravali ෆිල්ටර් ඇතුළත් වේ</string>\n    <string name=\"nearest_sub\">සෑම පික්සලයක්ම එකම වර්ණයෙන් පික්සල ගණනාවක් සමඟ ප්‍රතිස්ථාපනය කරමින් ප්‍රමාණය වැඩි කිරීමේ සරල ක්‍රමවලින් එකකි</string>\n    <string name=\"basic_sub\">සියලුම යෙදුම්වල පාහේ භාවිතා කරන සරලම ඇන්ඩ්‍රොයිඩ් පරිමාණ ප්‍රකාරය</string>\n    <string name=\"catmull_sub\">සුමට වක්‍ර නිර්මාණය කිරීම සඳහා පරිගණක ග්‍රැෆික්ස් වල බහුලව භාවිතා වන පාලන ලක්ෂ්‍ය කට්ටලයක් සුමට ලෙස අන්තර් සම්බන්ධ කිරීම සහ නැවත නියැදීම සඳහා ක්‍රමය</string>\n    <string name=\"hann_sub\">වර්ණාවලි කාන්දු වීම අවම කිරීමට සහ සංඥාවක දාර පටිගත කිරීමෙන් සංඛ්‍යාත විශ්ලේෂණයේ නිරවද්‍යතාවය වැඩි දියුණු කිරීමට සංඥා සැකසීමේදී කවුළු ශ්‍රිතය බොහෝ විට යෙදේ.</string>\n    <string name=\"hermite_sub\">සුමට හා අඛණ්ඩ වක්‍රයක් උත්පාදනය කිරීම සඳහා වක්‍ර කොටසක අවසාන ලක්ෂ්‍යවල අගයන් සහ ව්‍යුත්පන්නයන් භාවිතා කරන ගණිතමය මැදිහත්වීමේ ක්‍රමය</string>\n    <string name=\"lanczos_sub\">පික්සල් අගයන් වෙත බරිත සින්ක් ශ්‍රිතයක් යෙදීමෙන් උසස් තත්ත්වයේ අන්තර් ක්‍රියාකාරිත්වය පවත්වා ගෙන යන නැවත නියැදීමේ ක්‍රමය</string>\n    <string name=\"mitchell_sub\">පරිමාණය කළ රූපයේ තියුණු බව සහ ප්‍රති-අන්වර්ථනය අතර සමතුලිතතාවයක් ලබා ගැනීම සඳහා වෙනස් කළ හැකි පරාමිති සහිත පෙරළීමේ පෙරහනක් භාවිතා කරන නැවත නියැදීමේ ක්‍රමය</string>\n    <string name=\"spline_sub\">නම්‍යශීලී සහ අඛණ්ඩ හැඩ නිරූපණය සපයන වක්‍රයක් හෝ මතුපිටක් සුමට ලෙස අන්තර් සම්බන්ධ කිරීමට සහ ආසන්න කිරීමට කොටස් වශයෙන්-නිර්වචනය කරන ලද බහුපද ශ්‍රිත භාවිත කරයි.</string>\n    <string name=\"only_clip\">Clip පමණයි</string>\n    <string name=\"only_clip_sub\">ආචයනය වෙත සුරැකීම සිදු නොකරන අතර, රූපය පසුරු පුවරුවට පමණක් තැබීමට උත්සාහ කරනු ඇත</string>\n    <string name=\"restore_background_sub\">බුරුසුව මැකීම වෙනුවට පසුබිම ප්‍රතිසාධනය කරයි</string>\n    <string name=\"recognize_text\">OCR (පෙළ හඳුනා ගන්න)</string>\n    <string name=\"recognize_text_sub\">ලබා දී ඇති රූපයෙන් පෙළ හඳුනා ගන්න, භාෂා 120+ සහය දක්වයි</string>\n    <string name=\"picture_has_no_text\">පින්තූරයේ පෙළක් නැත, නැතහොත් යෙදුම එය සොයා ගත්තේ නැත</string>\n    <string name=\"accuracy\">\\\"නිරවද්‍යතාව: %1$s\\\"</string>\n    <string name=\"recognition_type\">හඳුනාගැනීමේ වර්ගය</string>\n    <string name=\"fast\">වේගවත්</string>\n    <string name=\"standard\">සම්මතය</string>\n    <string name=\"best\">හොඳම</string>\n    <string name=\"no_data\">දත්ත නැත</string>\n    <string name=\"download_description\">Tesseract OCR හි නිසි ක්‍රියාකාරීත්වය සඳහා අමතර පුහුණු දත්ත (%1$s) ඔබගේ උපාංගයට බාගැනීමට අවශ්‍ය වේ.\\nඔබට %2$s දත්ත බාගැනීමට අවශ්‍යද?</string>\n    <string name=\"download\">බාගන්න</string>\n    <string name=\"no_connection\">සම්බන්ධතාවයක් නැත, එය පරීක්ෂා කර දුම්රිය ආකෘති බාගැනීම සඳහා නැවත උත්සාහ කරන්න</string>\n    <string name=\"downloaded_languages\">බාගත කළ භාෂා</string>\n    <string name=\"available_languages\">පවතින භාෂා</string>\n    <string name=\"segmentation_mode\">ඛණ්ඩන මාදිලිය</string>\n    <string name=\"use_pixel_switch\">Pixel Switch භාවිතා කරන්න</string>\n    <string name=\"use_pixel_switch_sub\">Google Pixel වැනි ස්විචයක් භාවිතා කරයි</string>\n    <string name=\"saved_to_original\">මුල් ගමනාන්තයේ %1$s නම සහිත උඩින් ලියන ලද ගොනුව</string>\n    <string name=\"magnifier\">විශාලනය</string>\n    <string name=\"magnifier_sub\">වඩා හොඳ ප්‍රවේශ්‍යතාවක් සඳහා ඇඳීම් ක්‍රමවල ඇඟිල්ලේ ඉහළින් ඇති විශාලනය සබල කරයි</string>\n    <string name=\"force_exif_widget_initial_value\">ආරම්භක අගය බල කරන්න</string>\n    <string name=\"force_exif_widget_initial_value_sub\">exif widget මුලදී පරීක්ෂා කිරීමට බල කරයි</string>\n    <string name=\"allow_multiple_languages\">බහු භාෂාවලට ඉඩ දෙන්න</string>\n    <string name=\"slide\">ස්ලයිඩය</string>\n    <string name=\"side_by_side\">පසෙකින්</string>\n    <string name=\"toggle_tap\">ටොගල් ටැප්</string>\n    <string name=\"transparency\">විනිවිදභාවය</string>\n    <string name=\"rate_app\">යෙදුම අගයන්න</string>\n    <string name=\"rate\">අගය කරන්න</string>\n    <string name=\"rate_app_sub\">මෙම යෙදුම සම්පූර්ණයෙන්ම නොමිලේ, ඔබට එය විශාල වීමට අවශ්‍ය නම්, කරුණාකර Github හි ව්‍යාපෘතිය තරු කරන්න 😄</string>\n    <string name=\"segmentation_mode_osd_only\">දිශානතිය සහ ස්ක්‍රිප්ට් අනාවරණය පමණි</string>\n    <string name=\"segmentation_mode_auto_osd\">ස්වයංක්‍රීය දිශානතිය සහ ස්ක්‍රිප්ට් හඳුනාගැනීම</string>\n    <string name=\"segmentation_mode_auto_only\">ඔටෝ විතරයි</string>\n    <string name=\"segmentation_mode_auto\">ඔටෝ</string>\n    <string name=\"segmentation_mode_single_column\">තනි තීරුව</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">තනි වාරණ සිරස් පෙළ</string>\n    <string name=\"segmentation_mode_single_block\">තනි බ්ලොක්</string>\n    <string name=\"segmentation_mode_single_line\">තනි රේඛාව</string>\n    <string name=\"segmentation_mode_single_word\">තනි වචනයක්</string>\n    <string name=\"segmentation_mode_circle_word\">කව වචනය</string>\n    <string name=\"segmentation_mode_single_char\">තනි අක්ෂරය</string>\n    <string name=\"segmentation_mode_sparse_text\">විරල පෙළ</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">විරල පෙළ දිශානතිය සහ ස්ක්‍රිප්ට් හඳුනාගැනීම</string>\n    <string name=\"segmentation_mode_raw_line\">අමු රේඛාව</string>\n    <string name=\"delete_language_sub\">ඔබට භාෂා \\\"%1$s\\\" OCR පුහුණු දත්ත සියලු හඳුනාගැනීම් වර්ග සඳහා මැකීමට අවශ්‍යද, නැතහොත් තෝරාගත් එකක් සඳහා පමණක් (%2$s)?</string>\n    <string name=\"current\">වත්මන්</string>\n    <string name=\"all\">සියල්ල</string>\n    <string name=\"gradient_maker\">Gradient Maker</string>\n    <string name=\"gradient_maker_sub\">අභිරුචිකරණය කළ වර්ණ සහ පෙනුම වර්ගය සමඟ ලබා දී ඇති ප්‍රතිදාන ප්‍රමාණයේ අනුක්‍රමණය සාදන්න</string>\n    <string name=\"gradient_type_linear\">රේඛීය</string>\n    <string name=\"gradient_type_radial\">රේඩියල්</string>\n    <string name=\"gradient_type_sweep\">අතුගාන්න</string>\n    <string name=\"gradient_type\">Gradient වර්ගය</string>\n    <string name=\"center_x\">මධ්‍යස්ථානය X</string>\n    <string name=\"center_y\">මධ්යස්ථානය Y</string>\n    <string name=\"tile_mode\">ටයිල් මාදිලිය</string>\n    <string name=\"tile_mode_repeated\">නැවත නැවතත්</string>\n    <string name=\"tile_mode_mirror\">කැඩපත</string>\n    <string name=\"tile_mode_clamp\">කලම්ප</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"color_stops\">වර්ණ නැවතුම්</string>\n    <string name=\"add_color\">වර්ණ එකතු කරන්න</string>\n    <string name=\"properties\">දේපල</string>\n    <string name=\"brightness_enforcement\">දීප්තිය බලාත්මක කිරීම</string>\n    <string name=\"screen\">තිරය</string>\n    <string name=\"gradient_maker_type_image\">අනුක්‍රමික ආවරණයක්</string>\n    <string name=\"gradient_maker_type_image_sub\">ලබා දී ඇති පින්තූරවල මුදුනේ ඕනෑම අනුක්‍රමයක් සම්පාදනය කරන්න</string>\n    <string name=\"transformations\">පරිවර්තනයන්</string>\n    <string name=\"camera\">කැමරාව</string>\n    <string name=\"camera_sub\">කැමරාවකින් පින්තූරයක් ගන්න. මෙම රූප මූලාශ්‍රයෙන් ලබා ගත හැක්කේ එක් රූපයක් පමණක් බව සලකන්න</string>\n    <string name=\"watermarking\">ජල සලකුණු කිරීම</string>\n    <string name=\"watermarking_sub\">අභිරුචිකරණය කළ හැකි පෙළ/රූප ජල සලකුණු සහිත පින්තූර ආවරණය කරන්න</string>\n    <string name=\"repeat_watermark\">දිය සලකුණ නැවත කරන්න</string>\n    <string name=\"repeat_watermark_sub\">ලබා දී ඇති ස්ථානයේ තනි වෙනුවට රූපය මත ජල සලකුණ නැවත නැවත සිදු කරයි</string>\n    <string name=\"offset_x\">ඕෆ්සෙට් X</string>\n    <string name=\"offset_y\">ඕෆ්සෙට් වයි</string>\n    <string name=\"watermark_type\">ජල සලකුණු වර්ගය</string>\n    <string name=\"watermarking_image_sub\">මෙම රූපය ජල සලකුණු සඳහා රටාවක් ලෙස භාවිතා කරනු ඇත</string>\n    <string name=\"text_color\">පෙළ වර්ණය</string>\n    <string name=\"overlay_mode\">උඩැතිරි මාදිලිය</string>\n    <string name=\"gif_tools\">GIF මෙවලම්</string>\n    <string name=\"gif_tools_sub\">පින්තූර GIF පින්තූරයට පරිවර්තනය කරන්න හෝ ලබා දී ඇති GIF රූපයෙන් රාමු උපුටා ගන්න</string>\n    <string name=\"gif_type_to_image\">පින්තූර සඳහා GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF ගොනුව පින්තූර සමූහයකට පරිවර්තනය කරන්න</string>\n    <string name=\"gif_type_to_gif_sub\">පින්තූර සමූහය GIF ගොනුවකට පරිවර්තනය කරන්න</string>\n    <string name=\"gif_type_to_gif\">පින්තූර GIF වෙත</string>\n    <string name=\"select_gif_image_to_start\">ආරම්භ කිරීමට GIF රූපය තෝරන්න</string>\n    <string name=\"use_size_of_first_frame\">පළමු රාමුවේ විශාලත්වය භාවිතා කරන්න</string>\n    <string name=\"use_size_of_first_frame_sub\">නිශ්චිත ප්‍රමාණය පළමු රාමු මානයන් සමඟ ප්‍රතිස්ථාපනය කරන්න</string>\n    <string name=\"repeat_count\">නැවත නැවත ගණනය කරන්න</string>\n    <string name=\"frame_delay\">රාමු ප්රමාදය</string>\n    <string name=\"millis\">මිලි</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Lasso භාවිතා කරන්න</string>\n    <string name=\"use_lasso_sub\">මැකීම සිදු කිරීම සඳහා ඇඳීම් මාදිලියේ මෙන් Lasso භාවිතා කරයි</string>\n    <string name=\"original_image_preview_alpha\">මුල් රූප පෙරදසුන ඇල්ෆා</string>\n    <string name=\"confetti\">කොන්ෆෙට්ටි</string>\n    <string name=\"confetti_sub\">කොන්ෆෙට්ටි සුරැකීම, බෙදාගැනීම සහ අනෙකුත් මූලික ක්‍රියා මත පෙන්වනු ඇත</string>\n    <string name=\"secure_mode\">ආරක්ෂිත මාදිලිය</string>\n    <string name=\"secure_mode_sub\">මෑත යෙදුම්වල යෙදුම් අන්තර්ගතය සඟවයි. එය අල්ලා ගැනීමට හෝ පටිගත කිරීමට නොහැකිය.</string>\n    <string name=\"exit\">පිටවෙන්න</string>\n    <string name=\"preview_closing\">ඔබ දැන් පෙරදසුන හැර ගියහොත්, ඔබට නැවත පින්තූර එක් කිරීමට අවශ්‍ය වනු ඇත</string>\n    <string name=\"dithering\">ඩිදරින්</string>\n    <string name=\"quantizier\">Quantizier</string>\n    <string name=\"gray_scale\">අළු පරිමාණය</string>\n    <string name=\"bayer_two_dithering\">බේයර් ටූ බයි ටූ ඩිදරින්</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"bayer_eight_dithering\">බේයර් එයිට් බයි එයිට් ඩිදරින්</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis විනිසුරු Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">පේළි දෙකක් Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">ඇට්කින්සන් ඩිතෙරින්</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">බර්ක්ස් ඩිදරින්</string>\n    <string name=\"false_floyd_steinberg_dithering\">බොරු Floyd Steinberg Dithering</string>\n    <string name=\"left_to_right_dithering\">වමේ සිට දකුණට දික්කසාද වීම</string>\n    <string name=\"random_dithering\">අහඹු ඩයිදරින්</string>\n    <string name=\"simple_threshold_dithering\">සරල ත්‍රෙෂෝල්ඩ් ඩිදරින්</string>\n    <string name=\"sigma\">සිග්මා</string>\n    <string name=\"spatial_sigma\">අවකාශීය සිග්මා</string>\n    <string name=\"median_blur\">මධ්යන්ය බොඳවීම</string>\n    <string name=\"b_spline\">බී ස්ප්ලයින්</string>\n    <string name=\"b_spline_sub\">වක්‍රයක් හෝ මතුපිටක්, නම්‍යශීලී සහ අඛණ්ඩ හැඩ නිරූපණයක් සුමට ලෙස අන්තර් සම්බන්ධ කිරීමට සහ ආසන්න කිරීමට කොටස් වශයෙන්-නිර්වචනය කරන ලද ද්විපද බහුපද ශ්‍රිත භාවිතා කරයි.</string>\n    <string name=\"native_stack_blur\">දේශීය තොග බොඳවීම</string>\n    <string name=\"tilt_shift\">ටිල්ට් ෂිෆ්ට්</string>\n    <string name=\"glitch\">දෝෂය</string>\n    <string name=\"amount\">මුදල</string>\n    <string name=\"seed\">බීජ</string>\n    <string name=\"anaglyph\">ඇනග්ලිෆ්</string>\n    <string name=\"noise\">ශබ්දය</string>\n    <string name=\"pixel_sort\">පික්සල් අනුපිළිවෙල</string>\n    <string name=\"shuffle\">කලවම් කරන්න</string>\n    <string name=\"enhanced_glitch\">වැඩි දියුණු කළ දෝෂය</string>\n    <string name=\"channel_shift_x\">චැනල් Shift X</string>\n    <string name=\"channel_shift_y\">චැනල් Shift Y</string>\n    <string name=\"corruption_size\">දූෂණ ප්රමාණය</string>\n    <string name=\"corruption_shift_x\">දූෂණ මාරුව X</string>\n    <string name=\"corruption_shift_y\">දූෂණ මාරුව වයි</string>\n    <string name=\"tent_blur\">කූඩාරම් බොඳවීම</string>\n    <string name=\"side_fade\">සයිඩ් ෆේඩ්</string>\n    <string name=\"side\">පැත්ත</string>\n    <string name=\"top\">ඉහළ</string>\n    <string name=\"bottom\">පහළ</string>\n    <string name=\"strength\">ශක්තිය</string>\n    <string name=\"erode\">ඊරෝඩ්</string>\n    <string name=\"anisotropic_diffusion\">ඇනිසොට්‍රොපික් විසරණය</string>\n    <string name=\"diffusion\">විසරණය</string>\n    <string name=\"conduction\">සන්නයනය</string>\n    <string name=\"horizontal_wind_stagger\">තිරස් සුළං ස්ටැගර්</string>\n    <string name=\"fast_bilaterial_blur\">වේගවත් ද්විපාර්ශ්වික බොඳවීම</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">ලඝුගණක නාද සිතියම්කරණය</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"crystallize\">ස්ඵටික කරන්න</string>\n    <string name=\"stroke_color\">ආඝාත වර්ණය</string>\n    <string name=\"fractal_glass\">ෆ්රැක්ටල් වීදුරු</string>\n    <string name=\"amplitude\">විස්තාරය</string>\n    <string name=\"marble\">කිරිගරුඬ</string>\n    <string name=\"turbulence\">කැළඹීම</string>\n    <string name=\"oil\">තෙල්</string>\n    <string name=\"water_effect\">ජල බලපෑම</string>\n    <string name=\"just_size\">ප්රමාණය</string>\n    <string name=\"frequency_x\">සංඛ්යාත X</string>\n    <string name=\"frequency_y\">සංඛ්යාත Y</string>\n    <string name=\"amplitude_x\">විස්තාරය X</string>\n    <string name=\"amplitude_y\">විස්තාරය Y</string>\n    <string name=\"perlin_distortion\">පර්ලින් විකෘති කිරීම</string>\n    <string name=\"aces_hill_tone_mapping\">ACES හිල් ටෝන් සිතියම්කරණය</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Tone සිතියම්ගත කිරීම</string>\n    <string name=\"speed\">වේගය</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">ඔමේගා</string>\n    <string name=\"color_matrix_4x4\">වර්ණ Matrix 4x4</string>\n    <string name=\"color_matrix_3x3\">වර්ණ Matrix 3x3</string>\n    <string name=\"simple_effects\">සරල බලපෑම්</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">ට්රයිටනොමලි</string>\n    <string name=\"deutaromaly\">ඩියුටරනොමාලි</string>\n    <string name=\"protonomaly\">Protanomaly</string>\n    <string name=\"vintage\">වින්ටේජ්</string>\n    <string name=\"browni\">බ්රවුන්ගේ</string>\n    <string name=\"coda_chrome\">කෝඩා ක්‍රෝම්</string>\n    <string name=\"night_vision\">රාත්රී දර්ශනය</string>\n    <string name=\"warm\">උණුසුම්</string>\n    <string name=\"cool\">සිසිල්</string>\n    <string name=\"tritanopia\">ට්රයිටනෝපියාව</string>\n    <string name=\"deutaronotopia\">ඩියුටරොනොටෝපියාව</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">වර්ණදේහ</string>\n    <string name=\"achromatopsia\">ඇක්රොමැටොප්සියාව</string>\n    <string name=\"grain\">ධාන්ය</string>\n    <string name=\"unsharp\">තියුණු කරන්න</string>\n    <string name=\"pastel\">පැස්ටල්</string>\n    <string name=\"orange_haze\">තැඹිලි හේස්</string>\n    <string name=\"pink_dream\">රෝස සිහිනය</string>\n    <string name=\"golden_hour\">ස්වර්ණමය හෝරාව</string>\n    <string name=\"hot_summer\">උණුසුම් ගිම්හානය</string>\n    <string name=\"purple_mist\">දම් පාට මීදුම</string>\n    <string name=\"sunrise\">හිරු උදාව</string>\n    <string name=\"colorful_swirl\">වර්ණවත් සුළිය</string>\n    <string name=\"soft_spring_light\">මෘදු වසන්ත ආලෝකය</string>\n    <string name=\"autumn_tones\">සරත් සෘතුවේ නාද</string>\n    <string name=\"lavender_dream\">ලැවෙන්ඩර් සිහිනය</string>\n    <string name=\"cyberpunk\">සයිබර්පන්ක්</string>\n    <string name=\"lemonade_light\">ලෙමනේඩ් ආලෝකය</string>\n    <string name=\"spectral_fire\">වර්ණාවලි ගින්න</string>\n    <string name=\"night_magic\">රාත්රී මැජික්</string>\n    <string name=\"fantasy_landscape\">ෆැන්ටසි භූ දර්ශනය</string>\n    <string name=\"color_explosion\">වර්ණ පිපිරීම</string>\n    <string name=\"electric_gradient\">විදුලි අනුක්‍රමය</string>\n    <string name=\"caramel_darkness\">කැරමල් අන්ධකාරය</string>\n    <string name=\"futuristic_gradient\">අනාගත අනුක්‍රමණය</string>\n    <string name=\"green_sun\">හරිත හිරු</string>\n    <string name=\"rainbow_world\">දේදුනු ලෝකය</string>\n    <string name=\"deep_purple\">තද දම් පාට</string>\n    <string name=\"space_portal\">අභ්යවකාශ ද්වාරය</string>\n    <string name=\"red_swirl\">රතු සුළිය</string>\n    <string name=\"digital_code\">ඩිජිටල් කේතය</string>\n    <string name=\"bokeh\">බොකේ</string>\n    <string name=\"random_emojis_sub\">යෙදුම් තීරු ඉමොජි අහඹු ලෙස වෙනස් වනු ඇත</string>\n    <string name=\"random_emojis\">අහඹු ඉමෝජි</string>\n    <string name=\"random_emojis_error\">ඉමෝජි අබල කර ඇති අතර ඔබට අහඹු ඉමෝජි භාවිතා කළ නොහැක</string>\n    <string name=\"emoji_selection_error\">අහඹු ඉමෝජි සබල කර ඇති අතර ඔබට ඉමොජියක් තෝරාගත නොහැක</string>\n    <string name=\"old_tv\">පැරණි රූපවාහිනිය</string>\n    <string name=\"shuffle_blur\">බොඳ කිරීම කලවම් කරන්න</string>\n    <string name=\"favorite\">ප්රියතම</string>\n    <string name=\"no_favorite_filters\">ප්‍රියතම පෙරහන් තවම එක් කර නැත</string>\n    <string name=\"image_format\">රූප ආකෘතිය</string>\n    <string name=\"icon_shape_sub\">අයිකන යටතේ තෝරාගත් හැඩය සහිත කන්ටේනරයක් එක් කරයි</string>\n    <string name=\"icon_shape\">අයිකන හැඩය</string>\n    <string name=\"drago\">ඩ්රැගෝ</string>\n    <string name=\"aldridge\">ඕල්ඩ්රිජ්</string>\n    <string name=\"cutoff\">විසන්ධි කරනවා</string>\n    <string name=\"uchimura\">ඔබ අවදි වන්න</string>\n    <string name=\"mobius\">මොබියස්</string>\n    <string name=\"transition\">සංක්රමණය</string>\n    <string name=\"peak\">උච්ච</string>\n    <string name=\"color_anomaly\">වර්ණ විෂමතාව</string>\n    <string name=\"images_overwritten\">මුල් ගමනාන්තයේ උඩින් ලියන ලද පින්තූර</string>\n    <string name=\"cannot_change_image_format\">ගොනු උඩින් ලිවීමේ විකල්පය සක්‍රීය කර ඇති අතරතුර රූප ආකෘතිය වෙනස් කළ නොහැක</string>\n    <string name=\"emoji_as_color_scheme\">Emoji වර්ණ පටිපාටියක් ලෙස</string>\n    <string name=\"emoji_as_color_scheme_sub\">අතින් නිර්වචනය කරන ලද එකක් වෙනුවට යෙදුම් වර්ණ පටිපාටියක් ලෙස ඉමොජි ප්‍රාථමික වර්ණය භාවිත කරයි</string>\n    <string name=\"material_you_sub\">රූපයේ සිට Material You palette නිර්මාණය කරයි</string>\n    <string name=\"dark_colors\">අඳුරු වර්ණ</string>\n    <string name=\"dark_colors_sub\">ආලෝක ප්‍රභේදය වෙනුවට රාත්‍රී මාදිලියේ වර්ණ පටිපාටිය භාවිතා කරයි</string>\n    <string name=\"copy_as_compose_code\">Jetpack Compose code ලෙස පිටපත් කරන්න</string>\n    <string name=\"ring_blur\">මුදු නොපැහැදිලි</string>\n    <string name=\"cross_blur\">හරස් බොඳවීම</string>\n    <string name=\"circle_blur\">කවය බොඳවීම</string>\n    <string name=\"star_blur\">තරු බොඳවීම</string>\n    <string name=\"linear_tilt_shift\">රේඛීය ඇල-මාරුව</string>\n    <string name=\"tags_to_remove\">ඉවත් කිරීමට ටැග්</string>\n    <string name=\"apng_tools\">APNG මෙවලම්</string>\n    <string name=\"apng_tools_sub\">පින්තූර APNG පින්තූරයට පරිවර්තනය කරන්න හෝ ලබා දී ඇති APNG රූපයෙන් රාමු උපුටා ගන්න</string>\n    <string name=\"apng_type_to_image\">පින්තූර සඳහා APNG</string>\n    <string name=\"apng_type_to_image_sub\">APNG ගොනුව පින්තූර සමූහයකට පරිවර්තනය කරන්න</string>\n    <string name=\"apng_type_to_apng_sub\">පින්තූර සමූහය APNG ගොනුවකට පරිවර්තනය කරන්න</string>\n    <string name=\"apng_type_to_apng\">පින්තූර APNG වෙත</string>\n    <string name=\"select_apng_image_to_start\">ආරම්භ කිරීමට APNG රූපය තෝරන්න</string>\n    <string name=\"motion_blur\">චලන බොඳවීම</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">ලබා දී ඇති ගොනු හෝ පින්තූර වලින් Zip ගොනුවක් සාදන්න</string>\n    <string name=\"drag_handle_width\">හැන්ඩ්ල් පළල අදින්න</string>\n    <string name=\"confetti_type\">කොන්ෆෙට්ටි වර්ගය</string>\n    <string name=\"festive\">උත්සව</string>\n    <string name=\"explode\">පුපුරන්න</string>\n    <string name=\"rain\">වැස්ස</string>\n    <string name=\"corners\">කොන්</string>\n    <string name=\"jxl_tools\">JXL මෙවලම්</string>\n    <string name=\"jxl_tools_sub\">ගුණාත්මක අලාභයකින් තොරව JXL ~ JPEG ට්‍රාන්ස්කෝඩින් සිදු කරන්න, නැතහොත් GIF/APNG JXL සජීවිකරණයට පරිවර්තනය කරන්න</string>\n    <string name=\"jxl_type_to_jpeg\">JXL සිට JPEG දක්වා</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL සිට JPEG දක්වා පාඩු රහිත ට්‍රාන්ස්කෝඩින් සිදු කරන්න</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG සිට JXL දක්වා පාඩු රහිත ට්‍රාන්ස්කෝඩින් සිදු කරන්න</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG සිට JXL</string>\n    <string name=\"select_jxl_image_to_start\">ආරම්භ කිරීමට JXL රූපය තෝරන්න</string>\n    <string name=\"fast_gaussian_blur_2d\">Fast Gaussian Blur 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Fast Gaussian Blur 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Fast Gaussian Blur 4D</string>\n    <string name=\"auto_paste\">කාර් පාස්කු</string>\n    <string name=\"auto_paste_sub\">ක්ලිප්බෝඩ් දත්ත ස්වයංක්‍රීයව ඇලවීමට යෙදුමට අවසර දෙන්න, එබැවින් එය ප්‍රධාන තිරයේ දිස්වන අතර ඔබට එය සැකසීමට හැකි වනු ඇත</string>\n    <string name=\"harmonization_color\">සමීකරණ වර්ණය</string>\n    <string name=\"harmonization_level\">එකඟතා මට්ටම</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">පික්සල් අගයන් සඳහා Bessel (jinc) ශ්‍රිතයක් යෙදීමෙන් උසස් තත්ත්වයේ අන්තර් ක්‍රියාකාරිත්වය පවත්වා ගෙන යන නැවත නියැදීමේ ක්‍රමය</string>\n    <string name=\"gif_type_to_jxl\">GIF සිට JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF පින්තූර JXL සජීවිකරණ පින්තූර බවට පරිවර්තනය කරන්න</string>\n    <string name=\"apng_type_to_jxl\">APNG සිට JXL දක්වා</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG පින්තූර JXL සජීවිකරණ පින්තූර බවට පරිවර්තනය කරන්න</string>\n    <string name=\"jxl_type_to_images\">JXL සිට පින්තූර දක්වා</string>\n    <string name=\"jxl_type_to_images_sub\">JXL සජීවිකරණය පින්තූර සමූහයකට පරිවර්තනය කරන්න</string>\n    <string name=\"jxl_type_to_jxl\">JXL වෙත පින්තූර</string>\n    <string name=\"jxl_type_to_jxl_sub\">පින්තූර සමූහය JXL සජීවිකරණයට පරිවර්තනය කරන්න</string>\n    <string name=\"behavior\">හැසිරීම</string>\n    <string name=\"skip_file_picking\">ගොනු තේරීම මඟ හරින්න</string>\n    <string name=\"skip_file_picking_sub\">තෝරන ලද තිරය මත මෙය හැකි නම් ගොනු පිකර් වහාම පෙන්වනු ඇත</string>\n    <string name=\"generate_previews\">පෙරදසුන් උත්පාදනය කරන්න</string>\n    <string name=\"generate_previews_sub\">පෙරදසුන් උත්පාදනය සක්‍රීය කරයි, මෙය සමහර උපාංගවල බිඳ වැටීම් වලක්වා ගැනීමට උදවු විය හැක, මෙය තනි සංස්කරණ විකල්පය තුළ සමහර සංස්කරණ ක්‍රියාකාරකම් ද අබල කරයි</string>\n    <string name=\"lossy_compression\">ලොසි සම්පීඩනය</string>\n    <string name=\"lossy_compression_sub\">ලොස්ලස් වෙනුවට ගොනු ප්‍රමාණය අඩු කිරීමට පාඩු සහිත සම්පීඩනය භාවිතා කරයි</string>\n    <string name=\"compression_type\">සම්පීඩන වර්ගය</string>\n    <string name=\"speed_sub\">ප්‍රතිඵලයක් ලෙස ලැබෙන රූප විකේතන වේගය පාලනය කරයි, මෙය ප්‍රතිඵලයක් ලෙස ලැබෙන රූපය ඉක්මනින් විවෘත කිරීමට උදවු විය යුතුය, %1$s හි අගය යනු මන්දගාමී විකේතනය වේ, නමුත් %2$s - වේගවත්ම, මෙම සැකසීම ප්‍රතිදාන රූප ප්‍රමාණය වැඩි කළ හැක</string>\n    <string name=\"sorting\">වර්ග කිරීම</string>\n    <string name=\"sort_by_date\">දිනය</string>\n    <string name=\"sort_by_date_reversed\">දිනය (ප්‍රතිලෝම)</string>\n    <string name=\"sort_by_name\">නම</string>\n    <string name=\"sort_by_name_reversed\">නම (ප්‍රතිලෝම)</string>\n    <string name=\"channels_configuration\">නාලිකා වින්‍යාසය</string>\n    <string name=\"header_today\">අද</string>\n    <string name=\"header_yesterday\">ඊයේ</string>\n    <string name=\"embedded_picker\">Embedded Picker</string>\n    <string name=\"embedded_picker_sub\">රූප මෙවලම් පෙට්ටියේ රූප පිකර්</string>\n    <string name=\"no_permissions\">අවසර නැත</string>\n    <string name=\"request\">ඉල්ලීම</string>\n    <string name=\"pick_multiple_media\">බහු මාධ්‍ය තෝරන්න</string>\n    <string name=\"pick_single_media\">තනි මාධ්‍ය තෝරන්න</string>\n    <string name=\"pick\">තෝරාගන්න</string>\n    <string name=\"try_again\">නැවත උත්සාහ කරන්න</string>\n    <string name=\"show_settings_in_landscape\">භූ දර්ශනය තුළ සැකසුම් පෙන්වන්න</string>\n    <string name=\"show_settings_in_landscape_sub\">මෙය අක්‍රිය කර ඇත්නම්, ස්ථිර දෘශ්‍ය විකල්පය වෙනුවට, භූ දර්ශන ප්‍රකාරයේ සැකසීම් සෑම විටම ඉහළ යෙදුම් තීරුවේ බොත්තම මත විවෘත වනු ඇත.</string>\n    <string name=\"fullscreen_settings\">සම්පූර්ණ තිර සැකසුම්</string>\n    <string name=\"fullscreen_settings_sub\">එය සක්‍රිය කරන්න, ස්ලයිඩ කළ හැකි ලාච්චු පත්‍රය වෙනුවට සැකසීම් පිටුව සැමවිටම පූර්ණ තිරය ලෙස විවෘත වේ</string>\n    <string name=\"switch_type\">ස්විච් වර්ගය</string>\n    <string name=\"compose\">රචනා කරන්න</string>\n    <string name=\"compose_switch_sub\">ඔබ මාරු කරන Jetpack Compose Material එකක්</string>\n    <string name=\"material_you_switch_sub\">ඔබ මාරු කරන ද්‍රව්‍යයක්</string>\n    <string name=\"max\">උපරිම</string>\n    <string name=\"resize_anchor\">නැංගුරම ප්‍රමාණය වෙනස් කරන්න</string>\n    <string name=\"pixel_switch\">පික්සල</string>\n    <string name=\"fluent_switch\">චතුර</string>\n    <string name=\"fluent_switch_sub\">\\\"Fluent\\\" සැලසුම් පද්ධතිය මත පදනම් වූ ස්විචයක්</string>\n    <string name=\"cupertino_switch\">කුපර්ටිනෝ</string>\n    <string name=\"cupertino_switch_sub\">\\\"Cupertino\\\" සැලසුම් පද්ධතිය මත පදනම් වූ ස්විචයක්</string>\n    <string name=\"images_to_svg\">SVG වෙත පින්තූර</string>\n    <string name=\"images_to_svg_sub\">ලබා දී ඇති පින්තූර SVG පින්තූර වෙත ලුහුබඳින්න</string>\n    <string name=\"use_sampled_palette\">නියැදි පැලට් භාවිතා කරන්න</string>\n    <string name=\"use_sampled_palette_sub\">මෙම විකල්පය සක්‍රීය කර ඇත්නම් ප්‍රමාණකරණ තලය සාම්පල කරනු ලැබේ</string>\n    <string name=\"path_omit\">මග හැරිය</string>\n    <string name=\"svg_warning\">විශාල රූප අඩු කිරීමකින් තොරව ලුහුබැඳීම සඳහා මෙම මෙවලම භාවිතා කිරීම නිර්දේශ නොකරයි, එය බිඳ වැටීමට සහ සැකසුම් කාලය වැඩි කිරීමට හේතු විය හැක.</string>\n    <string name=\"downscale_image\">පහත් පරිමාණ රූපය</string>\n    <string name=\"downscale_image_sub\">සැකසීමට පෙර රූපය අඩු මානයන් දක්වා පහත හෙලනු ඇත, මෙය මෙවලම වේගයෙන් සහ ආරක්ෂිතව වැඩ කිරීමට උපකාරී වේ</string>\n    <string name=\"min_color_ratio\">අවම වර්ණ අනුපාතය</string>\n    <string name=\"lines_threshold\">රේඛා එළිපත්ත</string>\n    <string name=\"quadratic_threshold\">චතුරස්රාකාර සීමාව</string>\n    <string name=\"coordinates_rounding_tolerance\">වටකුරු ඉවසීම සම්බන්ධීකරණය කරයි</string>\n    <string name=\"path_scale\">මාර්ග පරිමාණය</string>\n    <string name=\"reset_properties\">ගුණාංග යළි පිහිටුවන්න</string>\n    <string name=\"reset_properties_sub\">සියලුම ගුණාංග පෙරනිමි අගයන් වෙත සකසනු ඇත, මෙම ක්‍රියාව පසුගමනය කළ නොහැකි බව සලකන්න</string>\n    <string name=\"detailed\">සවිස්තරාත්මක</string>\n    <string name=\"default_line_width\">පෙරනිමි රේඛා පළල</string>\n    <string name=\"engine_mode\">එන්ජින් මාදිලිය</string>\n    <string name=\"legacy\">උරුමය</string>\n    <string name=\"lstm_network\">LSTM ජාලය</string>\n    <string name=\"legacy_and_lstm\">උරුමය සහ LSTM</string>\n    <string name=\"convert\">පරිවර්තනය කරන්න</string>\n    <string name=\"convert_sub\">රූප කාණ්ඩ ලබා දී ඇති ආකෘතියට පරිවර්තනය කරන්න</string>\n    <string name=\"add_new_folder\">නව ෆෝල්ඩරය එක් කරන්න</string>\n    <string name=\"tag_bits_per_sample\">නියැදියකට බිටු</string>\n    <string name=\"tag_compression\">සම්පීඩනය</string>\n    <string name=\"tag_photometric_interpretation\">ඡායාරූපමිතික අර්ථ නිරූපණය</string>\n    <string name=\"tag_samples_per_pixel\">පික්සලයකට සාම්පල</string>\n    <string name=\"tag_planar_configuration\">ප්ලැනර් වින්යාසය</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr උප නියැදීම</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr ස්ථානගත කිරීම</string>\n    <string name=\"tag_x_resolution\">X විභේදනය</string>\n    <string name=\"tag_y_resolution\">Y විභේදනය</string>\n    <string name=\"tag_resolution_unit\">විභේදන ඒකකය</string>\n    <string name=\"tag_strip_offsets\">තීරු ඕෆ්සෙට්</string>\n    <string name=\"tag_rows_per_strip\">තීරුවකට පේළි</string>\n    <string name=\"tag_strip_byte_counts\">තීරු බයිට් ගණන</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG අන්තර් හුවමාරු ආකෘතිය</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG අන්තර් හුවමාරු ආකෘතියේ දිග</string>\n    <string name=\"tag_transfer_function\">මාරු කිරීමේ කාර්යය</string>\n    <string name=\"tag_white_point\">වයිට් පොයින්ට්</string>\n    <string name=\"tag_primary_chromaticities\">ප්‍රාථමික වර්ණදේහ</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr සංගුණක</string>\n    <string name=\"tag_reference_black_white\">යොමු කළු සුදු</string>\n    <string name=\"tag_datetime\">දිනය වේලාව</string>\n    <string name=\"tag_image_description\">රූප විස්තරය</string>\n    <string name=\"tag_make\">හදන්න</string>\n    <string name=\"tag_model\">ආකෘතිය</string>\n    <string name=\"tag_software\">මෘදුකාංග</string>\n    <string name=\"tag_artist\">කලාකරුවා</string>\n    <string name=\"tag_copyright\">ප්‍රකාශන හිමිකම</string>\n    <string name=\"tag_exif_version\">Exif අනුවාදය</string>\n    <string name=\"tag_flashpix_version\">ෆ්ලෑෂ්පික්ස් අනුවාදය</string>\n    <string name=\"tag_color_space\">වර්ණ අවකාශය</string>\n    <string name=\"tag_gamma\">ගැමා</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">පික්සල් Y මානය</string>\n    <string name=\"tag_compressed_bits_per_pixel\">පික්සලයකට සම්පීඩිත බිටු</string>\n    <string name=\"tag_maker_note\">සාදන්නා සටහන</string>\n    <string name=\"tag_user_comment\">පරිශීලක අදහස්</string>\n    <string name=\"tag_related_sound_file\">අදාළ ශබ්ද ගොනුව</string>\n    <string name=\"tag_datetime_original\">දිනය වේලාව මුල්</string>\n    <string name=\"tag_datetime_digitized\">දිනය වේලාව ඩිජිටල්කරණය</string>\n    <string name=\"tag_offset_time\">ඕෆ්සෙට් කාලය</string>\n    <string name=\"tag_offset_time_original\">ඕෆ්සෙට් වේලාව ඔරිජිනල්</string>\n    <string name=\"tag_offset_time_digitized\">ඕෆ්සෙට් කාලය ඩිජිටල්කරණය</string>\n    <string name=\"tag_subsec_time\">උප තත්පර කාලය</string>\n    <string name=\"tag_subsec_time_original\">උප තත්පර කාලය මුල් පිටපත</string>\n    <string name=\"tag_subsec_time_digitized\">උප තත්පර කාලය ඩිජිටල්කරණය</string>\n    <string name=\"tag_exposure_time\">නිරාවරණ කාලය</string>\n    <string name=\"tag_f_number\">එෆ් අංකය</string>\n    <string name=\"tag_exposure_program\">නිරාවරණ වැඩසටහන</string>\n    <string name=\"tag_spectral_sensitivity\">වර්ණාවලි සංවේදීතාව</string>\n    <string name=\"tag_photographic_sensitivity\">ඡායාරූප සංවේදීතාව</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">සංවේදීතා වර්ගය</string>\n    <string name=\"tag_standard_output_sensitivity\">සම්මත ප්රතිදාන සංවේදීතාව</string>\n    <string name=\"tag_recommended_exposure_index\">නිර්දේශිත නිරාවරණ දර්ශකය</string>\n    <string name=\"tag_iso_speed\">ISO වේගය</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Speed ​​Latitude yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO ස්පීඩ් අක්ෂාංශ zzz</string>\n    <string name=\"tag_shutter_speed_value\">ෂටර වේග අගය</string>\n    <string name=\"tag_aperture_value\">විවරය අගය</string>\n    <string name=\"tag_brightness_value\">දීප්තියේ අගය</string>\n    <string name=\"tag_exposure_bias_value\">නිරාවරණ පක්ෂග්‍රාහී අගය</string>\n    <string name=\"tag_max_aperture_value\">උපරිම විවරය අගය</string>\n    <string name=\"tag_subject_distance\">විෂය දුර</string>\n    <string name=\"tag_metering_mode\">මිනුම් මාදිලිය</string>\n    <string name=\"tag_flash\">ෆ්ලෑෂ්</string>\n    <string name=\"tag_subject_area\">විෂය ප්රදේශය</string>\n    <string name=\"tag_focal_length\">නාභි දුර</string>\n    <string name=\"tag_flash_energy\">ෆ්ලෑෂ් බලශක්ති</string>\n    <string name=\"tag_spatial_frequency_response\">අවකාශීය සංඛ්යාත ප්රතිචාරය</string>\n    <string name=\"tag_focal_plane_x_resolution\">නාභීය තලය X විභේදනය</string>\n    <string name=\"tag_focal_plane_y_resolution\">නාභීය තලය Y විභේදනය</string>\n    <string name=\"tag_focal_plane_resolution_unit\">නාභීය තල විභේදන ඒකකය</string>\n    <string name=\"tag_subject_location\">විෂය ස්ථානය</string>\n    <string name=\"tag_exposure_index\">නිරාවරණ දර්ශකය</string>\n    <string name=\"tag_sensing_method\">සංවේදන ක්‍රමය</string>\n    <string name=\"tag_file_source\">ගොනු මූලාශ්රය</string>\n    <string name=\"tag_cfa_pattern\">CFA රටාව</string>\n    <string name=\"tag_custom_rendered\">අභිරුචි විදැහුම්කරණය</string>\n    <string name=\"tag_exposure_mode\">නිරාවරණ මාදිලිය</string>\n    <string name=\"tag_white_balance\">සුදු ශේෂය</string>\n    <string name=\"tag_digital_zoom_ratio\">ඩිජිටල් විශාලන අනුපාතය</string>\n    <string name=\"tag_focal_length_in_35mm_film\">නාභීය දිග 35mm ෆිල්ම්</string>\n    <string name=\"tag_scene_capture_type\">දර්ශන ග්‍රහණ වර්ගය</string>\n    <string name=\"tag_gain_control\">පාලනය ලබාගන්න</string>\n    <string name=\"tag_contrast\">පරස්පරතාව</string>\n    <string name=\"tag_saturation\">සන්තෘප්තිය</string>\n    <string name=\"tag_sharpness\">තියුණු බව</string>\n    <string name=\"tag_device_setting_description\">උපාංග සැකසුම් විස්තරය</string>\n    <string name=\"tag_subject_distance_range\">විෂය දුර පරාසය</string>\n    <string name=\"tag_image_unique_id\">රූපයේ අනන්‍ය ID</string>\n    <string name=\"tag_camera_owner_name\">කැමරා හිමිකරුගේ නම</string>\n    <string name=\"tag_body_serial_number\">ශරීර අනුක්‍රමික අංකය</string>\n    <string name=\"tag_lens_specification\">කාච පිරිවිතර</string>\n    <string name=\"tag_lens_make\">Lens Make</string>\n    <string name=\"tag_lens_model\">කාච ආකෘතිය</string>\n    <string name=\"tag_lens_serial_number\">කාච අනුක්‍රමික අංකය</string>\n    <string name=\"tag_gps_version_id\">GPS අනුවාද ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS අක්ෂාංශ</string>\n    <string name=\"tag_gps_longitude_ref\">GPS දේශාංශ Ref</string>\n    <string name=\"tag_gps_longitude\">GPS දේශාංශ</string>\n    <string name=\"tag_gps_altitude_ref\">GPS උන්නතාංශය Ref</string>\n    <string name=\"tag_gps_altitude\">GPS උන්නතාංශය</string>\n    <string name=\"tag_gps_timestamp\">GPS කාල මුද්දරය</string>\n    <string name=\"tag_gps_satellites\">GPS චන්ද්‍රිකා</string>\n    <string name=\"tag_gps_status\">GPS තත්ත්වය</string>\n    <string name=\"tag_gps_measure_mode\">GPS මිනුම් මාදිලිය</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS වේගය Ref</string>\n    <string name=\"tag_gps_speed\">GPS වේගය</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS ධාවන පථය</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img දිශාව Ref</string>\n    <string name=\"tag_gps_img_direction\">GPS Img දිශාව</string>\n    <string name=\"tag_gps_map_datum\">GPS සිතියම් දත්ත</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS ඩෙස්ට් අක්ෂාංශ</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS ඩෙස්ට් දේශාංශ Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS ඩෙස්ට් දේශාංශ</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS ඩෙස්ට් බෙයාරිං</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS Dest දුර</string>\n    <string name=\"tag_gps_processing_method\">GPS සැකසුම් ක්‍රමය</string>\n    <string name=\"tag_gps_area_information\">GPS ප්‍රදේශයේ තොරතුරු</string>\n    <string name=\"tag_gps_datestamp\">GPS දින මුද්දරය</string>\n    <string name=\"tag_gps_differential\">GPS අවකලනය</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H ස්ථානගත කිරීමේ දෝෂය</string>\n    <string name=\"tag_interoperability_index\">අන්තර් ක්රියාකාරීත්ව දර්ශකය</string>\n    <string name=\"tag_dng_version\">DNG අනුවාදය</string>\n    <string name=\"tag_default_crop_size\">පෙරනිමි බෝග ප්‍රමාණය</string>\n    <string name=\"tag_orf_preview_image_start\">පෙරදසුන් රූප ආරම්භය</string>\n    <string name=\"tag_orf_preview_image_length\">රූපයේ දිග පෙරදසුන් කරන්න</string>\n    <string name=\"tag_orf_aspect_frame\">දර්ශන රාමුව</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">සංවේදකය පහළ මායිම</string>\n    <string name=\"tag_rw2_sensor_left_border\">සංවේදක වම් මායිම</string>\n    <string name=\"tag_rw2_sensor_right_border\">සංවේදක දකුණු මායිම</string>\n    <string name=\"tag_rw2_sensor_top_border\">සංවේදකය ඉහළ මායිම</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">ලබා දී ඇති අකුරු සහ වර්ණය සමඟ මාර්ගයේ පෙළ අඳින්න</string>\n    <string name=\"font_size\">අකුරු ප්රමාණය</string>\n    <string name=\"watermark_size\">ජල සලකුණු ප්‍රමාණය</string>\n    <string name=\"repeat_text\">නැවත නැවත පෙළ</string>\n    <string name=\"repeat_text_sub\">එක් වරක් ඇඳීම වෙනුවට මාර්ගය අවසන් වන තෙක් වත්මන් පාඨය පුනරාවර්තනය වේ</string>\n    <string name=\"dash_size\">ඩෑෂ් ප්‍රමාණය</string>\n    <string name=\"draw_mode_image_sub\">දී ඇති මාර්ගය ඔස්සේ එය ඇඳීමට තෝරාගත් රූපය භාවිතා කරන්න</string>\n    <string name=\"draw_image_sub\">මෙම රූපය අඳින ලද මාර්ගයේ පුනරාවර්තන ඇතුළත් කිරීමක් ලෙස භාවිතා කරනු ඇත</string>\n    <string name=\"outlined_triangle_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා ගෙනහැර දක්වන ලද ත්‍රිකෝණයක් අඳින්න</string>\n    <string name=\"triangle_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා ගෙනහැර දක්වන ලද ත්‍රිකෝණයක් අඳින්න</string>\n    <string name=\"outlined_triangle\">ලුහුඬු ත්‍රිකෝණය</string>\n    <string name=\"triangle\">ත්රිකෝණය</string>\n    <string name=\"polygon_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා බහුඅස්‍රය ඇද දමයි</string>\n    <string name=\"polygon\">බහුඅස්රය</string>\n    <string name=\"outlined_polygon\">ගෙනහැර දක්වන ලද බහුඅස්රය</string>\n    <string name=\"outlined_polygon_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා ගෙනහැර දක්වන ලද බහුඅස්‍ර අඳින්න</string>\n    <string name=\"vertices\">සිරස්</string>\n    <string name=\"draw_regular_polygon\">නිතිපතා බහුඅස්රය අඳින්න</string>\n    <string name=\"draw_regular_polygon_sub\">නිදහස් ආකෘතිය වෙනුවට සාමාන්‍ය බහුඅස්‍රය අඳින්න</string>\n    <string name=\"star_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා තරු අඳිනවා</string>\n    <string name=\"star\">තරුව</string>\n    <string name=\"outlined_star\">ලුහුඬු තරුව</string>\n    <string name=\"outlined_star_sub\">ආරම්භක ලක්ෂ්‍යයේ සිට අවසාන ලක්ෂ්‍යය දක්වා ගෙනහැර දක්වන ලද තරුව අඳියි</string>\n    <string name=\"inner_radius_ratio\">අභ්යන්තර අරය අනුපාතය</string>\n    <string name=\"draw_regular_star\">සාමාන්‍ය තරුව අඳින්න</string>\n    <string name=\"draw_regular_star_sub\">නිදහස් පෝරමය වෙනුවට නිත්‍ය වන තරුව අඳින්න</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">තියුණු දාර වලක්වා ගැනීමට antialiasing සක්රීය කරයි</string>\n    <string name=\"open_edit_instead_of_preview\">පෙරදසුන වෙනුවට සංස්කරණය විවෘත කරන්න</string>\n    <string name=\"open_edit_instead_of_preview_sub\">ImageToolbox තුළ ඔබ රූපය විවෘත කිරීමට (පෙරදසුන) තේරූ විට, පෙරදසුන් වෙනුවට සංස්කරණ තේරීම් පත්‍රය විවෘත වේ</string>\n    <string name=\"document_scanner\">ලේඛන ස්කෑනරය</string>\n    <string name=\"document_scanner_sub\">ලේඛන පරිලෝකනය කර PDF සාදන්න හෝ ඒවායින් වෙනම පින්තූර සාදන්න</string>\n    <string name=\"click_to_start_scanning\">ස්කෑන් කිරීම ආරම්භ කිරීමට ක්ලික් කරන්න</string>\n    <string name=\"start_scanning\">ස්කෑන් කිරීම ආරම්භ කරන්න</string>\n    <string name=\"save_as_pdf\">Pdf ලෙස සුරකින්න</string>\n    <string name=\"share_as_pdf\">Pdf ලෙස බෙදා ගන්න</string>\n    <string name=\"options_below_is_for_images\">පහත විකල්ප PDF නොව පින්තූර සුරැකීම සඳහා වේ</string>\n    <string name=\"equalize_histogram_hsv\">Histogram HSV සමාන කරන්න</string>\n    <string name=\"equalize_histogram\">හිස්ටෝග්‍රෑම් සමාන කරන්න</string>\n    <string name=\"enter_percentage\">ප්‍රතිශතය ඇතුලත් කරන්න</string>\n    <string name=\"allow_enter_by_text_field\">Text Field මගින් ඇතුල් වීමට ඉඩ දෙන්න</string>\n    <string name=\"allow_enter_by_text_field_sub\">පෙරසිටුවීම් තේරීම පිටුපස පෙළ ක්ෂේත්‍රය, පියාසර කරන විට ඒවා ඇතුළු කිරීමට සබල කරයි</string>\n    <string name=\"scale_color_space\">වර්ණ අවකාශය පරිමාණය කරන්න</string>\n    <string name=\"linear\">රේඛීය</string>\n    <string name=\"equalize_histogram_pixelation\">හිස්ටෝග්‍රෑම් පික්සලේෂන් සමාන කරන්න</string>\n    <string name=\"grid_size_x\">ජාලක ප්‍රමාණය X</string>\n    <string name=\"grid_size_y\">ජාල ප්‍රමාණය Y</string>\n    <string name=\"equalize_histogram_adaptive\">හිස්ටෝග්‍රෑම් අනුවර්තනය සමාන කරන්න</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Histogram Adaptive LUV සමාන කරන්න</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Histogram Adaptive LAB සමාන කරන්න</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE රසායනාගාරය</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">අන්තර්ගතයට කප්පාදු කරන්න</string>\n    <string name=\"frame_color\">රාමු වර්ණය</string>\n    <string name=\"color_to_ignore\">නොසලකා හැරීමට වර්ණය</string>\n    <string name=\"template\">සැකිල්ල</string>\n    <string name=\"no_template_filters\">අච්චු පෙරහන් එකතු කර නැත</string>\n    <string name=\"create_new\">නව නිර්මාණය කරන්න</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">ස්කෑන් කරන ලද QR කේතය වලංගු පෙරහන් අච්චුවක් නොවේ</string>\n    <string name=\"scan_qr_code\">QR කේතය පරිලෝකනය කරන්න</string>\n    <string name=\"opened_file_have_no_filter_template\">තෝරාගත් ගොනුවේ පෙරහන් අච්චු දත්ත නොමැත</string>\n    <string name=\"create_template\">සැකිල්ල සාදන්න</string>\n    <string name=\"template_name\">සැකිල්ල නම</string>\n    <string name=\"select_template_preview\">මෙම පෙරහන් අච්චුව පෙරදසුන් කිරීමට මෙම රූපය භාවිතා කරනු ඇත</string>\n    <string name=\"template_filter\">සැකිලි පෙරහන</string>\n    <string name=\"as_qr_code\">QR කේත රූපයක් ලෙස</string>\n    <string name=\"as_file\">ගොනුවක් ලෙස</string>\n    <string name=\"save_as_file\">ගොනුවක් ලෙස සුරකින්න</string>\n    <string name=\"save_as_qr_code_image\">QR කේත රූපයක් ලෙස සුරකින්න</string>\n    <string name=\"delete_template\">අච්චුව මකන්න</string>\n    <string name=\"delete_template_warn\">ඔබ තෝරාගත් අච්චු පෙරහන මැකීමට සූදානම් වේ. මෙම මෙහෙයුම පසුගමනය කළ නොහැක</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) නම සහිත පෙරහන් අච්චුව එක් කරන ලදී</string>\n    <string name=\"filter_preview\">පෙරහන් පෙරදසුන</string>\n    <string name=\"qr_code\">QR සහ තීරු කේතය</string>\n    <string name=\"qr_code_sub\">QR කේතය පරිලෝකනය කර එහි අන්තර්ගතය ලබා ගන්න හෝ අලුත් එකක් ජනනය කිරීමට ඔබේ තන්තුව අලවන්න</string>\n    <string name=\"code_content\">කේත අන්තර්ගතය</string>\n    <string name=\"scan_qr_code_to_replace_content\">ක්ෂේත්‍රයේ අන්තර්ගතය ප්‍රතිස්ථාපනය කිරීමට ඕනෑම තීරු කේතයක් පරිලෝකනය කරන්න, නැතහොත් තෝරාගත් වර්ගය සමඟ නව තීරු කේතය ජනනය කිරීමට යමක් ටයිප් කරන්න</string>\n    <string name=\"qr_description\">QR විස්තරය</string>\n    <string name=\"min\">අවම</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR කේතය පරිලෝකනය කිරීමට සැකසීම් තුළ කැමරා අවසරය ලබා දෙන්න</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">ලේඛන ස්කෑනරය පරිලෝකනය කිරීමට සැකසීම් තුළ කැමරා අවසරය ලබා දෙන්න</string>\n    <string name=\"cubic\">ඝනක</string>\n    <string name=\"bspline\">B-ස්ප්ලයින්</string>\n    <string name=\"hamming\">හම්මිං</string>\n    <string name=\"hanning\">හැනිං</string>\n    <string name=\"blackman\">බ්ලැක්මන්</string>\n    <string name=\"welch\">වෙල්ච්</string>\n    <string name=\"quadric\">හතරැස්</string>\n    <string name=\"gaussian\">ගවුසියන්</string>\n    <string name=\"sphinx\">ස්පින්ක්ස්</string>\n    <string name=\"bartlett\">බාර්ට්ලට්</string>\n    <string name=\"robidoux\">රොබිඩොක්ස්</string>\n    <string name=\"robidoux_sharp\">රොබිඩොක්ස් ෂාප්</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">ස්ප්ලයින් 36</string>\n    <string name=\"spline64\">ස්ප්ලයින් 64</string>\n    <string name=\"kaiser\">කයිසර්</string>\n    <string name=\"bartlett_hann\">බාර්ට්ලට්-ඔහු</string>\n    <string name=\"box\">පෙට්ටිය</string>\n    <string name=\"bohman\">බෝමන්</string>\n    <string name=\"lanczos2\">ලැන්සෝස් 2</string>\n    <string name=\"lanczos3\">ලැන්සෝස් 3</string>\n    <string name=\"lanczos4\">ලැන්සෝස් 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">cubic interpolation bilinear වලට වඩා හොඳ ප්‍රතිඵල ලබා දෙමින් ආසන්නතම පික්සල 16 සලකා බැලීමෙන් සුමට පරිමාණයක් සපයයි.</string>\n    <string name=\"bspline_sub\">වක්‍රයක් හෝ මතුපිටක්, නම්‍යශීලී සහ අඛණ්ඩ හැඩ නිරූපණයක් සුමට ලෙස අන්තර් සම්බන්ධ කිරීමට සහ ආසන්න කිරීමට කොටස් වශයෙන්-නිර්වචනය කරන ලද බහුපද ශ්‍රිත භාවිතා කරයි.</string>\n    <string name=\"hamming_sub\">සංඥා සැකසීමේදී ප්‍රයෝජනවත් වන සංඥාවක දාර පටිගත කිරීමෙන් වර්ණාවලි කාන්දු වීම අඩු කිරීමට භාවිතා කරන කවුළු ශ්‍රිතයකි</string>\n    <string name=\"hanning_sub\">හෑන් කවුළුවේ ප්‍රභේදයක්, සංඥා සැකසුම් යෙදුම්වල වර්ණාවලි කාන්දු වීම අඩු කිරීමට බහුලව භාවිතා වේ</string>\n    <string name=\"blackman_sub\">බොහෝ විට සංඥා සැකසීමේදී භාවිතා කරන වර්ණාවලි කාන්දු වීම අවම කිරීම මගින් හොඳ සංඛ්‍යාත විභේදනයක් සපයන කවුළු ශ්‍රිතයක්</string>\n    <string name=\"welch_sub\">අඩු වර්ණාවලි කාන්දුවක් සමඟ හොඳ සංඛ්‍යාත විභේදනයක් ලබා දීමට නිර්මාණය කර ඇති කවුළු ශ්‍රිතයක්, බොහෝ විට සංඥා සැකසුම් යෙදුම්වල භාවිතා වේ</string>\n    <string name=\"quadric_sub\">සුමට හා අඛණ්ඩ ප්‍රතිඵල ලබා දෙමින් අන්තර් ක්‍රියාකාරිත්වය සඳහා චතුරස්‍ර ශ්‍රිතයක් භාවිතා කරන ක්‍රමයකි</string>\n    <string name=\"gaussian_sub\">රූපවල ඝෝෂාව සුමට කිරීමට සහ අඩු කිරීමට ප්‍රයෝජනවත් වන Gaussian ශ්‍රිතයක් යොදන අන්තර් බන්ධන ක්‍රමයක්</string>\n    <string name=\"sphinx_sub\">අවම කෞතුක වස්තු සහිත උසස් තත්ත්වයේ අන්තර් බන්ධනය සපයන උසස් නැවත නියැදීමේ ක්‍රමයක්</string>\n    <string name=\"bartlett_sub\">වර්ණාවලි කාන්දු වීම අවම කිරීම සඳහා සංඥා සැකසීමේදී භාවිතා කරන ත්‍රිකෝණාකාර කවුළු ශ්‍රිතයක්</string>\n    <string name=\"robidoux_sub\">ස්වභාවික රූපයේ ප්‍රතිප්‍රමාණය වෙනස් කිරීම, තියුණු බව සහ සුමට බව සමතුලිත කිරීම සඳහා ප්‍රශස්ත කරන ලද උසස් තත්ත්වයේ අන්තර් ක්‍රියා ක්‍රමයක්</string>\n    <string name=\"robidoux_sharp_sub\">Robidoux ක්‍රමයේ තියුණු ප්‍රභේදයක්, හැපෙනසුළු රූපය ප්‍රතිප්‍රමාණ කිරීම සඳහා ප්‍රශස්ත කර ඇත</string>\n    <string name=\"spline16_sub\">16-ටැප් ෆිල්ටරයක් ​​භාවිතයෙන් සුමට ප්‍රතිඵල ලබා දෙන spline-පාදක අන්තර් සම්බන්ධීකරණ ක්‍රමයක්</string>\n    <string name=\"spline36_sub\">36-ටැප් ෆිල්ටරයක් ​​භාවිතයෙන් සුමට ප්‍රතිඵල ලබා දෙන ස්ප්ලයින්-පදනම් ඉන්ටර්පෝලේෂන් ක්‍රමයක්</string>\n    <string name=\"spline64_sub\">64-ටැප් ෆිල්ටරයක් ​​භාවිතයෙන් සුමට ප්‍රතිඵල ලබා දෙන ස්ප්ලයින්-පදනම් ඉන්ටර්පෝලේෂන් ක්‍රමයක්</string>\n    <string name=\"kaiser_sub\">ප්‍රධාන-ලොබ් පළල සහ පැති-ලොබ් මට්ටම අතර වෙළඳාම පිළිබඳ හොඳ පාලනයක් සපයන, කයිසර් කවුළුව භාවිතා කරන අන්තර් ක්‍රියා ක්‍රමයක්</string>\n    <string name=\"bartlett_hann_sub\">සංඥා සැකසීමේදී වර්ණාවලි කාන්දු වීම අවම කිරීම සඳහා බාට්ලට් සහ හැන් කවුළු ඒකාබද්ධ කරන දෙමුහුන් කවුළු ශ්‍රිතයක්</string>\n    <string name=\"box_sub\">බොහෝ විට අවහිර පෙනුමක් ඇති කරන, ආසන්නතම පික්සල් අගයන්හි සාමාන්‍යය භාවිතා කරන සරල නැවත නියැදීමේ ක්‍රමයක්</string>\n    <string name=\"bohman_sub\">සංඥා සැකසුම් යෙදුම්වල හොඳ සංඛ්‍යාත විභේදනය සපයන, වර්ණාවලි කාන්දු වීම අඩු කිරීමට භාවිතා කරන කවුළු ශ්‍රිතයක්</string>\n    <string name=\"lanczos2_sub\">අවම කෞතුක වස්තු සහිත උසස් තත්ත්වයේ අන්තර් සම්බන්ධනය සඳහා 2-lobe Lanczos පෙරහන භාවිතා කරන නැවත නියැදීමේ ක්‍රමයක්</string>\n    <string name=\"lanczos3_sub\">අවම කෞතුක වස්තු සහිත උසස්-ගුණාත්මක මැදිහත්වීම සඳහා 3-lobe Lanczos පෙරහන භාවිතා කරන නැවත නියැදීමේ ක්‍රමයක්</string>\n    <string name=\"lanczos4_sub\">අවම කෞතුක වස්තු සහිත උසස් තත්ත්වයේ අන්තර් සම්බන්ධනය සඳහා 4-lobe Lanczos පෙරහන භාවිතා කරන නැවත නියැදීමේ ක්‍රමයක්</string>\n    <string name=\"lanczos2_jinc_sub\">ජින්ක් ශ්‍රිතය භාවිතා කරන Lanczos 2 ෆිල්ටරයේ ප්‍රභේදයක්, අවම කෞතුක වස්තු සමඟ උසස් තත්ත්වයේ අන්තර් සම්බන්ධනය සපයයි</string>\n    <string name=\"lanczos3_jinc_sub\">ජින්ක් ශ්‍රිතය භාවිතා කරන Lanczos 3 ෆිල්ටරයේ ප්‍රභේදයක්, අවම කෞතුක වස්තු සමඟ උසස් තත්ත්වයේ අන්තර් සම්බන්ධනය සපයයි</string>\n    <string name=\"lanczos4_jinc_sub\">ජින්ක් ශ්‍රිතය භාවිතා කරන Lanczos 4 ෆිල්ටරයේ ප්‍රභේදයක්, අවම කෞතුක වස්තු සමඟ උසස් තත්ත්වයේ අන්තර් බන්ධනය සපයයි</string>\n    <string name=\"ewa_hanning\">හැනිං EWA</string>\n    <string name=\"ewa_hanning_sub\">ඉලිප්සීය බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය සුමට මැදිහත්වීම සහ නැවත නියැදීම සඳහා Hanning පෙරහන</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">උසස් තත්ත්වයේ නැවත සකස් කිරීම සඳහා Robidoux ෆිල්ටරයේ ඉලිප්සීය බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">නාද කරන කෞතුක වස්තු අවම කිරීම සඳහා Blackman ෆිල්ටරයේ ඉලිප්සීය බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">සිනිඳු අන්තර් හුවමාරුව සඳහා චතුරස්රාකාර පෙරහනෙහි ඉලිප්සීය බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">තියුණු ප්‍රතිඵල සඳහා Robidoux Sharp ෆිල්ටරයේ ඉලිප්සාකාර බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">අඩු අන්වර්ථය සමඟ උසස් තත්ත්වයේ නැවත නියැදීම සඳහා Lanczos 3 Jinc පෙරහනෙහි Elliptical Weighted Average (EWA) ප්‍රභේදය</string>\n    <string name=\"ginseng\">ජින්සෙන්ග්</string>\n    <string name=\"ginseng_sub\">තියුණු බවේ සහ සුමටතාවයේ හොඳ සමතුලිතතාවයක් සහිත උසස් තත්ත්වයේ රූප සැකසීම සඳහා නිර්මාණය කර ඇති නැවත සාම්පල පෙරහනක්</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">වැඩි දියුණු කළ රූපයේ ගුණාත්මක භාවය සඳහා Ginseng ෆිල්ටරයේ ඉලිප්සීය බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">අවම කෞතුක වස්තු සමඟ තියුණු ප්‍රතිඵල ලබා ගැනීම සඳහා Lanczos Sharp ෆිල්ටරයේ ඉලිප්සාකාර බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 තියුණු EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">අතිශය තියුණු රූප නැවත නියැදීම සඳහා Lanczos 4 Sharpest ෆිල්ටරයේ Elliptical Weighted Average (EWA) ප්‍රභේදය</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">සුමට රූප නැවත සකස් කිරීම සඳහා Lanczos Soft ෆිල්ටරයේ ඉලිප්සීය බර සහිත සාමාන්‍ය (EWA) ප්‍රභේදය</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">සුමට සහ කෞතුක වස්තු-රහිත රූප පරිමාණය සඳහා Haasn විසින් නිර්මාණය කරන ලද නැවත සාම්පල පෙරහනක්</string>\n    <string name=\"format_conversion\">ආකෘති පරිවර්තනය</string>\n    <string name=\"format_conversion_sub\">රූප සමූහය එක් ආකෘතියකින් තවත් ආකෘතියකට පරිවර්තනය කරන්න</string>\n    <string name=\"dismiss_forever\">සදහටම ඉවත් කරන්න</string>\n    <string name=\"image_stacking\">රූප ගොඩගැසීම</string>\n    <string name=\"image_stacking_sub\">තෝරාගත් මිශ්‍ර ක්‍රම සමඟින් පින්තූර එකින් එක අට්ටි කරන්න</string>\n    <string name=\"add_image\">රූපය එකතු කරන්න</string>\n    <string name=\"bins_count\">බඳුන් ගණන්</string>\n    <string name=\"clahe_hsl\">ක්ලේ එච්එස්එල්</string>\n    <string name=\"clahe_hsv\">ක්ලේ එච්එස්වී</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Histogram Adaptive HSL සමාන කරන්න</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Histogram Adaptive HSV සමාන කරන්න</string>\n    <string name=\"edge_mode\">Edge Mode</string>\n    <string name=\"clip\">ක්ලිප්</string>\n    <string name=\"wrap\">ඔතා</string>\n    <string name=\"color_blind_scheme\">වර්ණ අන්ධභාවය</string>\n    <string name=\"color_blind_scheme_sub\">තෝරාගත් වර්ණ අන්ධතා ප්‍රභේදය සඳහා තේමා වර්ණ අනුවර්තනය කිරීමට මාදිලිය තෝරන්න</string>\n    <string name=\"protanomaly_sub\">රතු සහ කොළ වර්ණ අතර වෙනස හඳුනාගැනීමේ අපහසුතාව</string>\n    <string name=\"deuteranomaly_sub\">කොළ සහ රතු වර්ණ අතර වෙනස හඳුනාගැනීමේ අපහසුතාව</string>\n    <string name=\"tritanomaly_sub\">නිල් සහ කහ වර්ණ අතර වෙනස හඳුනාගැනීමේ අපහසුතාව</string>\n    <string name=\"protanopia_sub\">රතු පැහැයන් වටහා ගැනීමට නොහැකි වීම</string>\n    <string name=\"deuteranopia_sub\">හරිත වර්ණ තේරුම් ගැනීමට නොහැකි වීම</string>\n    <string name=\"tritanopia_sub\">නිල් පැහැයන් වටහා ගැනීමට නොහැකි වීම</string>\n    <string name=\"achromatomaly_sub\">සියලුම වර්ණ සඳහා සංවේදීතාව අඩු කිරීම</string>\n    <string name=\"achromatopsia_sub\">සම්පූර්ණ වර්ණ අන්ධභාවය, අළු වර්ණ පමණක් දැකීම</string>\n    <string name=\"not_use_color_blind_scheme\">වර්ණ අන්ධ යෝජනා ක්රමය භාවිතා නොකරන්න</string>\n    <string name=\"not_use_color_blind_scheme_sub\">වර්ණ හරියටම තේමාව තුළ සකසා ඇත</string>\n    <string name=\"sigmoidal\">සිග්මොයිඩල්</string>\n    <string name=\"lagrange_2\">ලග්රංගේ 2</string>\n    <string name=\"lagrange_2_sub\">සුමට සංක්‍රාන්ති සමඟ උසස් තත්ත්වයේ රූප පරිමාණය සඳහා සුදුසු 2 වන අනුපිළිවෙලෙහි Lagrange interpolation ෆිල්ටරයක්</string>\n    <string name=\"lagrange_3\">ලග්රංගේ 3</string>\n    <string name=\"lagrange_3_sub\">රූප පරිමාණය සඳහා වඩා හොඳ නිරවද්‍යතාවයක් සහ සුමට ප්‍රතිඵල ලබා දෙමින්, 3 වන අනුපිළිවෙලෙහි Lagrange interpolation filter එකක්</string>\n    <string name=\"lanczos_6\">ලැන්සෝස් 6</string>\n    <string name=\"lanczos_6_sub\">6 හි ඉහළ අනුපිළිවෙලක් සහිත Lanczos නැවත සාම්පල පෙරහනක්, තියුණු සහ වඩාත් නිවැරදි රූප පරිමාණයක් සපයයි</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 ජින්ක්</string>\n    <string name=\"lanczos_6_jinc_sub\">වැඩිදියුණු කළ රූප නැවත නියැදීමේ ගුණාත්මක භාවය සඳහා Jinc ශ්‍රිතයක් භාවිතා කරන Lanczos 6 පෙරහනෙහි ප්‍රභේදයකි</string>\n    <string name=\"linear_box_blur\">රේඛීය පෙට්ටිය බොඳවීම</string>\n    <string name=\"linear_tent_blur\">රේඛීය කූඩාරම් බොඳවීම</string>\n    <string name=\"linear_gaussian_box_blur\">රේඛීය Gaussian පෙට්ටිය බොඳවීම</string>\n    <string name=\"linear_stack_blur\">රේඛීය ස්ටැක් බොඳවීම</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">රේඛීය වේගවත් Gaussian Blur Next</string>\n    <string name=\"linear_fast_gaussian_blur\">රේඛීය වේගවත් ගවුසියන් බොඳවීම</string>\n    <string name=\"linear_gaussian_blur\">රේඛීය Gaussian Blur</string>\n    <string name=\"draw_filter_sub\">තීන්තයක් ලෙස භාවිතා කිරීමට එක් පෙරහනක් තෝරන්න</string>\n    <string name=\"replace_filter\">පෙරහන ප්රතිස්ථාපනය කරන්න</string>\n    <string name=\"pick_filter_info\">ඔබගේ ඇඳීමේ බුරුසුවක් ලෙස භාවිතා කිරීමට පහත පෙරහන තෝරන්න</string>\n    <string name=\"tiff_compression_scheme\">TIFF සම්පීඩන යෝජනා ක්රමය</string>\n    <string name=\"low_poly\">අඩු පොලි</string>\n    <string name=\"sand_painting\">වැලි පින්තාරු කිරීම</string>\n    <string name=\"image_splitting\">රූපය බෙදීම</string>\n    <string name=\"image_splitting_sub\">තනි රූපය පේළි හෝ තීරු අනුව බෙදන්න</string>\n    <string name=\"fit_to_bounds\">සීමාවන්ට ගැලපේ</string>\n    <string name=\"fit_to_bounds_sub\">අපේක්ෂිත හැසිරීම් සාක්ෂාත් කර ගැනීම සඳහා මෙම පරාමිතිය සමඟ බෝග ප්‍රමාණය වෙනස් කිරීමේ මාදිලිය ඒකාබද්ධ කරන්න (ක්‍රෝප්/ෆිට් සිට දර්ශන අනුපාතය)</string>\n    <string name=\"languages_imported\">භාෂා සාර්ථකව ආනයනය කරන ලදී</string>\n    <string name=\"backup_ocr_models\">උපස්ථ OCR ආකෘති</string>\n    <string name=\"import_word\">ආනයනය කරන්න</string>\n    <string name=\"export\">අපනයනය කරන්න</string>\n    <string name=\"position\">තනතුර</string>\n    <string name=\"center\">මධ්යස්ථානය</string>\n    <string name=\"top_left\">ඉහළ වම්</string>\n    <string name=\"top_right\">ඉහළ දකුණ</string>\n    <string name=\"bottom_left\">පහළ වම්</string>\n    <string name=\"bottom_right\">පහළ දකුණ</string>\n    <string name=\"top_center\">ඉහළ මධ්යස්ථානය</string>\n    <string name=\"center_right\">දකුණු මැද</string>\n    <string name=\"bottom_center\">පහළ මධ්යස්ථානය</string>\n    <string name=\"center_left\">වම් මැද</string>\n    <string name=\"target_image\">ඉලක්ක රූපය</string>\n    <string name=\"palette_transfer\">පැලට් මාරු කිරීම</string>\n    <string name=\"enhanced_oil\">වැඩි දියුණු කළ තෙල්</string>\n    <string name=\"simple_old_tv\">සරල පැරණි රූපවාහිනිය</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">ගෝතම්</string>\n    <string name=\"simple_sketch\">සරල ස්කීච්</string>\n    <string name=\"soft_glow\">මෘදු දිලිසීම</string>\n    <string name=\"color_poster\">වර්ණ පෝස්ටර්</string>\n    <string name=\"tri_tone\">ට්‍රයි ටෝන්</string>\n    <string name=\"third_color\">තෙවන වර්ණය</string>\n    <string name=\"clahe_oklab\">ක්ලේ ඔක්ලාබ්</string>\n    <string name=\"clahe_oklch\">ක්ලාරා ඔල්ච්</string>\n    <string name=\"clahe_jzazbz\">ක්ලේ ඡාස්බ්ස්</string>\n    <string name=\"polka_dot\">පොල්කා ඩොට්</string>\n    <string name=\"clustered_2x2_dithering\">පොකුරු 2x2 ඩයිටරින්</string>\n    <string name=\"clustered_4x4_dithering\">පොකුරු 4x4 ඩයිදරින්</string>\n    <string name=\"clustered_8x8_dithering\">පොකුරු 8x8 ඩයිටරින්</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">ප්‍රියතම විකල්ප තෝරාගෙන නැත, ඒවා මෙවලම් පිටුවට එක් කරන්න</string>\n    <string name=\"add_favorites\">ප්රියතම එකතු කරන්න</string>\n    <string name=\"harmony_complementary\">අනුපූරක</string>\n    <string name=\"harmony_analogous\">සමානයි</string>\n    <string name=\"harmony_triadic\">ත්රිත්ව</string>\n    <string name=\"harmony_split_complementary\">අනුපූරක බෙදීම</string>\n    <string name=\"harmony_tetradic\">ටෙට්රාඩික්</string>\n    <string name=\"harmony_square\">චතුරස්රය</string>\n    <string name=\"harmony_analogous_complementary\">සමාන + අනුපූරක</string>\n    <string name=\"color_tools\">වර්ණ මෙවලම්</string>\n    <string name=\"color_tools_sub\">මිශ්‍ර කරන්න, නාද සාදන්න, සෙවන ජනනය කරන්න සහ තවත් දේ</string>\n    <string name=\"color_harmonies\">වර්ණ එකඟතා</string>\n    <string name=\"color_shading\">වර්ණ සෙවන</string>\n    <string name=\"variation\">විචලනය</string>\n    <string name=\"tints\">ටින්ට්ස්</string>\n    <string name=\"tones\">නාද</string>\n    <string name=\"shades\">සෙවනැලි</string>\n    <string name=\"color_mixing\">වර්ණ මිශ්ර කිරීම</string>\n    <string name=\"color_info\">වර්ණ තොරතුරු</string>\n    <string name=\"selected_color\">තෝරාගත් වර්ණය</string>\n    <string name=\"color_to_mix\">මිශ්ර කිරීමට වර්ණය</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">ගතික වර්ණ සක්‍රීය කර ඇති අතර මුදල් භාවිතා කළ නොහැක</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">ඉලක්ක LUT රූපය</string>\n    <string name=\"amatorka\">ආධුනිකයෙක්</string>\n    <string name=\"miss_etikate\">එටිකට් මෙනවිය</string>\n    <string name=\"soft_elegance\">මෘදු අලංකාරය</string>\n    <string name=\"soft_elegance_variant\">මෘදු අලංකාර ප්රභේදය</string>\n    <string name=\"palette_transfer_variant\">පැලට් මාරු ප්රභේදය</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">ඉලක්ක 3D LUT ගොනුව (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">බ්ලීච් බයිපාස්</string>\n    <string name=\"candlelight\">ඉටිපන්දම් ආලෝකය</string>\n    <string name=\"drop_blues\">ඩ්‍රොප් බ්ලූස්</string>\n    <string name=\"edgy_amber\">එඩ්ජි ඇම්බර්</string>\n    <string name=\"fall_colors\">පතන වර්ණ</string>\n    <string name=\"film_stock_50\">චිත්‍රපට කොටස් 50</string>\n    <string name=\"foggy_night\">මීදුම සහිත රාත්‍රිය</string>\n    <string name=\"kodak\">කොඩැක්</string>\n    <string name=\"save_empty_lut\">උදාසීන LUT රූපය ලබා ගන්න</string>\n    <string name=\"save_empty_lut_sub\">පළමුව, ඔබට මෙතැනින් ලබාගත හැකි උදාසීන LUT වෙත පෙරහනක් යෙදීමට ඔබේ ප්‍රියතම ඡායාරූප සංස්කරණ යෙදුම භාවිත කරන්න. මෙය නිසියාකාරව ක්‍රියා කිරීම සඳහා සෑම පික්සෙල් වර්ණයක්ම වෙනත් පික්සල මත රඳා නොසිටිය යුතුය (උදා: බොඳවීම ක්‍රියා නොකරයි). සූදානම් වූ පසු, 512*512 LUT පෙරහන සඳහා ආදානය ලෙස ඔබේ නව LUT රූපය භාවිත කරන්න</string>\n    <string name=\"pop_art\">පොප් කලාව</string>\n    <string name=\"celluloid\">සෙලියුලොයිඩ්</string>\n    <string name=\"coffee\">කෝපි</string>\n    <string name=\"golden_forest\">රන් වනාන්තරය</string>\n    <string name=\"greenish\">කොළ පාටයි</string>\n    <string name=\"retro_yellow\">රෙට්රෝ කහ</string>\n    <string name=\"links_preview\">සබැඳි පෙරදසුන</string>\n    <string name=\"links_preview_sub\">ඔබට පෙළ ලබා ගත හැකි ස්ථාන (QRCode, OCR ආදිය) සබැඳි පෙරදසුන ලබා ගැනීම සබල කරයි</string>\n    <string name=\"links\">සබැඳි</string>\n    <string name=\"ico_size_warning\">ICO ගොනු සුරැකිය හැක්කේ 256 x 256 උපරිම ප්‍රමාණයෙන් පමණි</string>\n    <string name=\"gif_type_to_webp\">GIF සිට WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">GIF පින්තූර WEBP සජීවිකරණ පින්තූර බවට පරිවර්තනය කරන්න</string>\n    <string name=\"webp_tools\">WEBP මෙවලම්</string>\n    <string name=\"webp_tools_sub\">පින්තූර WEBP සජීවිකරණ පින්තූරයට පරිවර්තනය කරන්න හෝ ලබා දී ඇති WEBP සජීවිකරණයෙන් රාමු උපුටා ගන්න</string>\n    <string name=\"webp_type_to_image\">පින්තූර වෙත WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP ගොනුව පින්තූර සමූහයකට පරිවර්තනය කරන්න</string>\n    <string name=\"webp_type_to_webp_sub\">පින්තූර සමූහය WEBP ගොනුවට පරිවර්තනය කරන්න</string>\n    <string name=\"webp_type_to_webp\">පින්තූර WEBP වෙත</string>\n    <string name=\"select_webp_image_to_start\">ආරම්භ කිරීමට WEBP රූපය තෝරන්න</string>\n    <string name=\"manage_storage_extra_types\">ගොනු වෙත සම්පූර්ණ ප්‍රවේශයක් නොමැත</string>\n    <string name=\"manage_storage_extra_types_sub\">Android මත පින්තූර ලෙස හඳුනා නොගත් JXL, QOI සහ අනෙකුත් පින්තූර බැලීමට සියලුම ගොනුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න. අවසරයකින් තොරව රූප මෙවලම් පෙට්ටියට එම පින්තූර පෙන්වීමට නොහැක</string>\n    <string name=\"default_draw_color\">පෙරනිමි ඇඳීමේ වර්ණය</string>\n    <string name=\"default_draw_path_mode\">Default Draw Path Mode</string>\n    <string name=\"add_timestamp\">කාල මුද්‍රාව එක් කරන්න</string>\n    <string name=\"add_timestamp_sub\">ප්‍රතිදාන ගොනු නාමයට කාල මුද්‍රාව එක් කිරීම සබල කරයි</string>\n    <string name=\"formatted_timestamp\">ෆෝමැට් කල වේලා මුද්දරය</string>\n    <string name=\"formatted_timestamp_sub\">මූලික මිලි වෙනුවට ප්‍රතිදාන ගොනු නාමයෙන් කාල මුද්‍රා හැඩතල ගැන්වීම සබල කරන්න</string>\n    <string name=\"enable_timestamps_to_format_them\">ඒවායේ ආකෘතිය තේරීමට කාල මුද්දර සබල කරන්න</string>\n    <string name=\"one_time_save_location\">එක් වරක් ඉතිරි කිරීමේ ස්ථානය</string>\n    <string name=\"one_time_save_location_sub\">බොහෝ විට සියලුම විකල්පවල සුරකින්න බොත්තම දිගු එබීමෙන් ඔබට භාවිතා කළ හැකි එක් වරක් සුරැකීමේ ස්ථාන බලන්න සහ සංස්කරණය කරන්න</string>\n    <string name=\"recently_used\">මෑතකදී භාවිතා කරන ලදී</string>\n    <string name=\"ci_channel\">CI නාලිකාව</string>\n    <string name=\"group\">කණ්ඩායම</string>\n    <string name=\"image_toolbox_in_telegram\">Telegram හි රූප මෙවලම් පෙට්ටිය 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">ඔබට අවශ්‍ය ඕනෑම දෙයක් සාකච්ඡා කළ හැකි අපගේ කතාබහට සම්බන්ධ වන්න සහ මා බීටා සහ නිවේදන පළ කරන CI නාලිකාව දෙස බලන්න.</string>\n    <string name=\"ci_channel_sub\">යෙදුමේ නව අනුවාද ගැන දැනුම් දෙන්න, සහ නිවේදන කියවන්න</string>\n    <string name=\"fit_description\">ලබා දී ඇති මානයන්ට රූපයක් සවි කර පසුබිමට නොපැහැදිලි හෝ වර්ණය යොදන්න</string>\n    <string name=\"tools_arrangement\">මෙවලම් සකස් කිරීම</string>\n    <string name=\"group_tools_by_type\">වර්ගය අනුව මෙවලම් කණ්ඩායම් කරන්න</string>\n    <string name=\"group_tools_by_type_sub\">අභිරුචි ලැයිස්තු සැකැස්මක් වෙනුවට ඒවායේ වර්ගය අනුව ප්‍රධාන තිරයේ මෙවලම් කණ්ඩායම් කරන්න</string>\n    <string name=\"default_values\">පෙරනිමි අගයන්</string>\n    <string name=\"system_bars_visibility\">පද්ධති තීරු දෘශ්‍යතාව</string>\n    <string name=\"show_system_bars_by_swipe\">ස්වයිප් මගින් පද්ධති තීරු පෙන්වන්න</string>\n    <string name=\"show_system_bars_by_swipe_sub\">පද්ධති තීරු සැඟවී ඇත්නම් ඒවා පෙන්වීමට ස්වයිප් කිරීම සබල කරයි</string>\n    <string name=\"auto\">ඔටෝ</string>\n    <string name=\"hide_all\">සියල්ල සඟවන්න</string>\n    <string name=\"show_all\">සියල්ල පෙන්වන්න</string>\n    <string name=\"hide_nav_bar\">නව තීරුව සඟවන්න</string>\n    <string name=\"hide_status_bar\">තත්ව තීරුව සඟවන්න</string>\n    <string name=\"noise_generation\">ශබ්ද උත්පාදනය</string>\n    <string name=\"noise_generation_sub\">පර්ලින් හෝ වෙනත් වර්ග වැනි විවිධ ශබ්ද උත්පාදනය කරන්න</string>\n    <string name=\"frequency\">සංඛ්යාතය</string>\n    <string name=\"noise_type\">ශබ්ද වර්ගය</string>\n    <string name=\"rotation_type\">භ්රමණ වර්ගය</string>\n    <string name=\"fractal_type\">ෆ්රැක්ටල් වර්ගය</string>\n    <string name=\"octaves\">අෂ්ටක</string>\n    <string name=\"lacunarity\">ලැකුනාරිටි</string>\n    <string name=\"gain\">ලබාගන්න</string>\n    <string name=\"weighted_strength\">බරැති ශක්තිය</string>\n    <string name=\"ping_pong_strength\">පිං පොං ශක්තිය</string>\n    <string name=\"distance_function\">දුරස්ථ කාර්යය</string>\n    <string name=\"return_type\">ආපසු එන වර්ගය</string>\n    <string name=\"jitter\">ජිටර්</string>\n    <string name=\"domain_warp\">වසම් Warp</string>\n    <string name=\"alignment\">පෙළගැස්වීම</string>\n    <string name=\"custom_filename\">අභිරුචි ගොනු නාමය</string>\n    <string name=\"custom_filename_sub\">වත්මන් රූපය සුරැකීමට භාවිතා කරන ස්ථානය සහ ගොනු නාමය තෝරන්න</string>\n    <string name=\"saved_to_custom\">අභිරුචි නම සහිත ෆෝල්ඩරයට සුරකින ලදී</string>\n    <string name=\"collage_maker\">කොලෙජ් සාදන්නා</string>\n    <string name=\"collage_maker_sub\">රූප 20ක් දක්වා කොලෙජ් සාදන්න</string>\n    <string name=\"collage_type\">කොලෙජ් වර්ගය</string>\n    <string name=\"collages_info\">ස්ථානය සීරුමාරු කිරීමට, මාරු කිරීමට සහ විශාලනය කිරීමට රූපය අල්ලාගෙන සිටින්න</string>\n    <string name=\"disable_rotation\">භ්රමණය අක්රිය කරන්න</string>\n    <string name=\"disable_rotation_sub\">ඇඟිලි දෙකේ අභිනයන් සමඟ රූප භ්‍රමණය වීම වළක්වයි</string>\n    <string name=\"enable_snapping_to_borders\">මායිම් වෙත ස්නැප් කිරීම සබල කරන්න</string>\n    <string name=\"enable_snapping_to_borders_sub\">චලනය කිරීමෙන් හෝ විශාලනය කිරීමෙන් පසු, රාමු දාර පිරවීම සඳහා පින්තූර කඩා වැටෙනු ඇත</string>\n    <string name=\"histogram\">හිස්ටෝග්රෑම්</string>\n    <string name=\"histogram_sub\">ඔබට ගැලපීම් කිරීමට උදවු කිරීමට RGB හෝ Brightness image histogram</string>\n    <string name=\"image_for_histogram\">මෙම රූපය RGB සහ Brightness histograms ජනනය කිරීමට භාවිතා කරනු ඇත</string>\n    <string name=\"tesseract_options\">Tesseract විකල්ප</string>\n    <string name=\"tesseract_options_sub\">ටෙසරැක්ට් එන්ජිම සඳහා ආදාන විචල්‍ය කිහිපයක් යොදන්න</string>\n    <string name=\"custom_options\">අභිරුචි විකල්ප</string>\n    <string name=\"custom_params_info\">මෙම රටාව අනුව විකල්ප ඇතුළත් කළ යුතුය: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">ස්වයංක්‍රීය බෝග</string>\n    <string name=\"free_corners\">නිදහස් කෝනර්</string>\n    <string name=\"free_corners_sub\">බහුඅස්‍රයෙන් රූපය කපන්න, මෙය ද ඉදිරිදර්ශනය නිවැරදි කරයි</string>\n    <string name=\"coerce_points_to_image_bounds\">රූප සීමාවන්ට බලහත්කාරයෙන් ලකුණු කරන්න</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">රූප සීමාවන් මගින් ලකුණු සීමා නොවනු ඇත, මෙය වඩාත් නිවැරදි ඉදිරිදර්ශන නිවැරදි කිරීම සඳහා ප්‍රයෝජනවත් වේ</string>\n    <string name=\"mask\">මාස්ක්</string>\n    <string name=\"spot_heal_sub\">අඳින ලද මාර්ගය යටතේ අන්තර්ගත දැනුවත් පුරවන්න</string>\n    <string name=\"spot_heal\">හීල් ස්පෝට්</string>\n    <string name=\"use_circle_kernel\">Circle Kernel භාවිතා කරන්න</string>\n    <string name=\"opening\">විවෘත කිරීම</string>\n    <string name=\"closing\">වසා දැමීම</string>\n    <string name=\"morphological_gradient\">රූප විද්‍යාත්මක අනුක්‍රමණය</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">කළු තොප්පිය</string>\n    <string name=\"tone_curves\">නාද වක්‍ර</string>\n    <string name=\"reset_curves\">වක්‍ර යළි පිහිටුවන්න</string>\n    <string name=\"reset_curves_sub\">වක්‍ර පෙරනිමි අගයට පෙරළෙනු ඇත</string>\n    <string name=\"line_style\">රේඛා විලාසය</string>\n    <string name=\"gap_size\">පරතරය ප්රමාණය</string>\n    <string name=\"dashed\">ඉරි තැලීය</string>\n    <string name=\"dot_dashed\">තිත් කඩයි</string>\n    <string name=\"stamped\">මුද්දර දමා ඇත</string>\n    <string name=\"zigzag\">සිග්සැග්</string>\n    <string name=\"dashed_sub\">නියමිත පරතරය ප්‍රමාණයෙන් අඳින ලද මාර්ගය දිගේ ඉරි සහිත රේඛාවක් අඳින්න</string>\n    <string name=\"dot_dashed_sub\">දී ඇති මාර්ගය දිගේ තිත් සහ ඉරි අඳින්න</string>\n    <string name=\"defaultt_sub\">පෙරනිමි සරල රේඛා පමණි</string>\n    <string name=\"stamped_sub\">නියමිත පරතරය සහිත මාර්ගය ඔස්සේ තෝරාගත් හැඩ අඳින්න</string>\n    <string name=\"zigzag_sub\">මාර්ගය දිගේ රැලි සහිත සිග්සැග් අඳින්න</string>\n    <string name=\"zigzag_ratio\">සිග්සැග් අනුපාතය</string>\n    <string name=\"create_shortcut\">කෙටිමං සාදන්න</string>\n    <string name=\"create_shortcut_title\">පින් කිරීමට මෙවලම තෝරන්න</string>\n    <string name=\"create_shortcut_subtitle\">මෙවලම කෙටිමඟ ලෙස ඔබේ දියත් කිරීමේ මුල් තිරයට එක් කරනු ඇත, අවශ්‍ය හැසිරීම් සාක්ෂාත් කර ගැනීම සඳහා \\\"ගොනු තේරීම මඟ හරින්න\\\" සැකසීම සමඟ එය භාවිතා කරන්න.</string>\n    <string name=\"dont_stack_frames\">රාමු ගොඩ නොගසන්න</string>\n    <string name=\"dont_stack_frames_sub\">පෙර රාමු බැහැර කිරීම සක්‍රීය කරයි, එබැවින් ඒවා එකිනෙක ගොඩ ගැසෙන්නේ නැත</string>\n    <string name=\"crossfade\">හරස්කඩ</string>\n    <string name=\"crossfade_sub\">රාමු එකිනෙකට හරස් අතට හැරෙනු ඇත</string>\n    <string name=\"crossfade_count\">Crossfade රාමු ගණන්</string>\n    <string name=\"threshold_one\">එළිපත්ත එක</string>\n    <string name=\"threshold_two\">එළිපත්ත දෙක</string>\n    <string name=\"canny\">කැනී</string>\n    <string name=\"mirror_101\">කැඩපත 101</string>\n    <string name=\"enhanced_zoom_blur\">වැඩි දියුණු කළ විශාලන බොඳ කිරීම</string>\n    <string name=\"laplacian_simple\">Laplacian සරල</string>\n    <string name=\"sobel_simple\">සෝබෙල් සරල</string>\n    <string name=\"helper_grid\">උපකාරක ජාලය</string>\n    <string name=\"helper_grid_sub\">නිරවද්‍ය උපාමාරු සඳහා උපකාර කිරීම සඳහා ඇඳීම් ප්‍රදේශයට ඉහළින් ආධාරක ජාලකය පෙන්වයි</string>\n    <string name=\"grid_color\">ජාලක වර්ණය</string>\n    <string name=\"cell_width\">සෛල පළල</string>\n    <string name=\"cell_height\">සෛල උස</string>\n    <string name=\"compact_selectors\">සංයුක්ත තේරීම්</string>\n    <string name=\"compact_selectors_sub\">සමහර තේරීම් පාලන අඩු ඉඩක් ගැනීමට සංයුක්ත පිරිසැලසුමක් භාවිතා කරයි</string>\n    <string name=\"grant_camera_permission_to_capture_image\">රූපය ලබා ගැනීමට සැකසීම් තුළ කැමරා අවසරය ලබා දෙන්න</string>\n    <string name=\"layout\">පිරිසැලසුම</string>\n    <string name=\"main_screen_title\">ප්රධාන තිර මාතෘකාව</string>\n    <string name=\"constant_rate_factor\">නියත අනුපාත සාධකය (CRF)</string>\n    <string name=\"crf_sub\">%1$s අගයක් යනු මන්දගාමී සම්පීඩනයකි, ප්‍රතිඵලයක් ලෙස සාපේක්ෂව කුඩා ගොනු ප්‍රමාණයකි. %2$s යනු විශාල ගොනුවක් ඇති කරන වේගවත් සම්පීඩනයකි.</string>\n    <string name=\"lut_library\">ලූට් පුස්තකාලය</string>\n    <string name=\"lut_library_sub\">ඔබට බාගත කිරීමෙන් පසු අයදුම් කළ හැකි LUT එකතුව බාගන්න</string>\n    <string name=\"lut_library_update_sub\">ඔබට බාගත කිරීමෙන් පසු අයදුම් කළ හැකි LUT එකතුව යාවත්කාලීන කරන්න (නව ඒවා පමණක් පෝලිම් වේ).</string>\n    <string name=\"filter_preview_image_sub\">පෙරහන් සඳහා පෙරනිමි රූප පෙරදසුන වෙනස් කරන්න</string>\n    <string name=\"filter_preview_image\">රූපය පෙරදසුන් කරන්න</string>\n    <string name=\"hide\">සඟවන්න</string>\n    <string name=\"show\">පෙන්වන්න</string>\n    <string name=\"slider_type\">ස්ලයිඩර් වර්ගය</string>\n    <string name=\"fancy\">විසිතුරු</string>\n    <string name=\"material_2\">ද්රව්ය 2</string>\n    <string name=\"fancy_sub\">විසිතුරු පෙනුමක් ඇති ස්ලයිඩරයක්. මෙය පෙරනිමි විකල්පයයි</string>\n    <string name=\"material_2_sub\">ද්රව්ය 2 ස්ලයිඩරයක්</string>\n    <string name=\"material_you_slider_sub\">ඔබ ස්ලයිඩරය සඳහා ද්‍රව්‍යයක්</string>\n    <string name=\"apply\">අයදුම් කරන්න</string>\n    <string name=\"center_align_dialog_buttons\">මධ්‍ය සංවාද බොත්තම්</string>\n    <string name=\"center_align_dialog_buttons_sub\">හැකි නම්, සංවාද බොත්තම් වම් පැත්ත වෙනුවට මධ්‍යයේ ස්ථානගත කෙරේ</string>\n    <string name=\"open_source_licenses\">විවෘත මූලාශ්ර බලපත්ර</string>\n    <string name=\"open_source_licenses_sub\">මෙම යෙදුමේ භාවිතා කරන විවෘත මූලාශ්‍ර පුස්තකාලවල බලපත්‍ර බලන්න</string>\n    <string name=\"area\">ප්රදේශය</string>\n    <string name=\"area_sub\">පික්සල් ප්‍රදේශ සම්බන්ධය භාවිතයෙන් නැවත නියැදීම. එය moire\\'-නිදහස් ප්‍රතිඵල ලබා දෙන බැවින්, රූප විනාශය සඳහා වඩාත් කැමති ක්‍රමයක් විය හැක. නමුත් රූපය විශාලනය කළ විට එය \\\"ළඟම \\\" ක්‍රමයට සමාන වේ.</string>\n    <string name=\"enable_tonemapping\">Tonemapping සබල කරන්න</string>\n    <string name=\"enter_percent\">% ඇතුලත් කරන්න</string>\n    <string name=\"unknown_host\">වෙබ් අඩවියට පිවිසිය නොහැක, VPN භාවිතා කිරීමට උත්සාහ කරන්න හෝ url එක නිවැරදිදැයි පරීක්ෂා කරන්න</string>\n    <string name=\"markup_layers\">සලකුණු ස්ථර</string>\n    <string name=\"markup_layers_sub\">පින්තූර, පෙළ සහ තවත් දේ නිදහසේ තැබීමේ හැකියාව සහිත ස්ථර මාදිලිය</string>\n    <string name=\"edit_layer\">ස්තරය සංස්කරණය කරන්න</string>\n    <string name=\"layers_on_image\">රූපය මත ස්ථර</string>\n    <string name=\"layers_on_image_sub\">පින්තූරයක් පසුබිමක් ලෙස භාවිතා කර එය මත විවිධ ස්ථර එකතු කරන්න</string>\n    <string name=\"layers_on_background\">පසුබිම මත ස්ථර</string>\n    <string name=\"layers_on_background_sub\">පළමු විකල්පයට සමාන නමුත් රූපය වෙනුවට වර්ණය සමඟ</string>\n    <string name=\"beta\">බීටා</string>\n    <string name=\"fast_settings_side\">වේගවත් සැකසුම් පැත්ත</string>\n    <string name=\"fast_settings_side_sub\">පින්තූර සංස්කරණය කරන අතරතුර තෝරාගත් පැත්තේ පාවෙන තීරුවක් එක් කරන්න, එය ක්ලික් කළ විට වේගවත් සැකසුම් විවෘත වේ</string>\n    <string name=\"clear_selection\">පැහැදිලි තේරීම</string>\n    <string name=\"settings_group_visibility_hidden\">\\\"%1$s\\\" කණ්ඩායම සැකසීම පෙරනිමියෙන් හකුළනු ඇත</string>\n    <string name=\"settings_group_visibility_visible\">\\\"%1$s\\\" කණ්ඩායම සැකසීම පෙරනිමියෙන් පුළුල් වනු ඇත</string>\n    <string name=\"base_64_tools\">Base64 මෙවලම්</string>\n    <string name=\"base_64_tools_sub\">Base64 තන්තුව රූපයට විකේතනය කරන්න, නැතහොත් රූපය Base64 ආකෘතියට සංකේතනය කරන්න</string>\n    <string name=\"base_64\">පදනම64</string>\n    <string name=\"not_a_valid_base_64\">සපයා ඇති අගය වලංගු Base64 තන්තුවක් නොවේ</string>\n    <string name=\"copy_not_a_valid_base_64\">හිස් හෝ වලංගු නොවන Base64 තන්තුව පිටපත් කළ නොහැක</string>\n    <string name=\"paste_base_64\">Base64 අලවන්න</string>\n    <string name=\"copy_base_64\">Base64 පිටපත් කරන්න</string>\n    <string name=\"base_64_tips\">Base64 තන්තුව පිටපත් කිරීමට හෝ සුරැකීමට රූපය පූරණය කරන්න. ඔබට තන්තුවම තිබේ නම්, ඔබට රූපය ලබා ගැනීමට එය ඉහත ඇලවිය හැක</string>\n    <string name=\"save_base_64\">Base64 සුරකින්න</string>\n    <string name=\"share_base_64\">Share Base64</string>\n    <string name=\"options\">විකල්ප</string>\n    <string name=\"actions\">ක්රියාවන්</string>\n    <string name=\"import_base_64\">ආයාත Base64</string>\n    <string name=\"base_64_actions\">Base64 ක්‍රියා</string>\n    <string name=\"add_outline\">දළ සටහන් එකතු කරන්න</string>\n    <string name=\"add_outline_sub\">නිශ්චිත වර්ණය සහ පළල සමඟ පෙළ වටා දළ සටහනක් එක් කරන්න</string>\n    <string name=\"outline_color\">දළ සටහන් වර්ණය</string>\n    <string name=\"outline_size\">දළ සටහන් ප්‍රමාණය</string>\n    <string name=\"rotation\">භ්රමණය</string>\n    <string name=\"checksum_as_filename\">ගොනු නාමය ලෙස චෙක්සම්</string>\n    <string name=\"checksum_as_filename_sub\">ප්‍රතිදාන රූපවලට ඒවායේ දත්ත පිරික්සුමට අනුරූප නමක් ඇත</string>\n    <string name=\"free_software_partner\">නිදහස් මෘදුකාංග (හවුල්කරු)</string>\n    <string name=\"free_software_partner_sub\">Android යෙදුම්වල හවුල්කාර නාලිකාවේ වඩාත් ප්‍රයෝජනවත් මෘදුකාංග</string>\n    <string name=\"algorithms\">ඇල්ගොරිතම</string>\n    <string name=\"checksum_tools\">චෙක්සම් මෙවලම්</string>\n    <string name=\"checksum_tools_sub\">චෙක්සම් සංසන්දනය කරන්න, හෑෂ් ගණනය කරන්න හෝ විවිධ හැෂිං ඇල්ගොරිතම භාවිතයෙන් ගොනු වලින් හෙක්ස් තන්තු සාදන්න</string>\n    <string name=\"calculate\">ගණනය කරන්න</string>\n    <string name=\"text_hash\">හැෂ් වෙත කෙටි පණිවිඩයක් යවන්න</string>\n    <string name=\"checksum\">චෙක්සම්</string>\n    <string name=\"pick_file_to_checksum\">තෝරාගත් ඇල්ගොරිතම මත පදනම්ව එහි චෙක්සම් ගණනය කිරීමට ගොනුව තෝරන්න</string>\n    <string name=\"enter_text_to_checksum\">තෝරාගත් ඇල්ගොරිතම මත පදනම්ව එහි චෙක්සම් ගණනය කිරීමට පෙළ ඇතුළත් කරන්න</string>\n    <string name=\"source_checksum\">මූලාශ්ර චෙක්සම්</string>\n    <string name=\"checksum_to_compare\">සංසන්දනය කිරීමට චෙක්සම්</string>\n    <string name=\"match\">තරගය!</string>\n    <string name=\"difference\">වෙනස</string>\n    <string name=\"match_sub\">චෙක්සම් සමාන වේ, එය ආරක්ෂිත විය හැකිය</string>\n    <string name=\"difference_sub\">චෙක්සම් සමාන නොවේ, ගොනුව අනාරක්ෂිත විය හැක!</string>\n    <string name=\"mesh_gradients\">Mesh Gradients</string>\n    <string name=\"collection_mesh_gradients_sub\">Mesh Gradients හි මාර්ගගත එකතුව බලන්න</string>\n    <string name=\"wrong_font\">ආනයනය කළ හැක්කේ TTF සහ OTF අකුරු පමණි</string>\n    <string name=\"import_font\">අකුරු ආයාත කරන්න (TTF/OTF)</string>\n    <string name=\"export_fonts\">අකුරු අපනයනය කරන්න</string>\n    <string name=\"imported_fonts\">ආනයනික අකුරු</string>\n    <string name=\"error_while_saving\">උත්සාහය සුරැකීමේදී දෝෂයකි, ප්‍රතිදාන ෆෝල්ඩරය වෙනස් කිරීමට උත්සාහ කරන්න</string>\n    <string name=\"filename_is_not_set\">ගොනු නාමය සකසා නැත</string>\n    <string name=\"none\">කිසිවක් නැත</string>\n    <string name=\"custom_pages\">අභිරුචි පිටු</string>\n    <string name=\"pages_selection\">පිටු තේරීම</string>\n    <string name=\"tool_exit_confirmation\">මෙවලම් පිටවීම තහවුරු කිරීම</string>\n    <string name=\"tool_exit_confirmation_sub\">විශේෂිත මෙවලම් භාවිතා කරන අතරතුර ඔබට නොසුරකින ලද වෙනස්කම් තිබේ නම් සහ එය වසා දැමීමට උත්සාහ කරන්නේ නම්, පසුව තහවුරු කිරීමේ සංවාදය පෙන්වනු ඇත</string>\n    <string name=\"edit_exif_screen\">EXIF සංස්කරණය කරන්න</string>\n    <string name=\"edit_exif_screen_sub\">නැවත සම්පීඩනයකින් තොරව තනි රූපයේ පාර-දත්ත වෙනස් කරන්න</string>\n    <string name=\"edit_exif_tag\">පවතින ටැග් සංස්කරණය කිරීමට තට්ටු කරන්න</string>\n    <string name=\"change_sticker\">ස්ටිකරය වෙනස් කරන්න</string>\n    <string name=\"fit_width\">Fit පළල</string>\n    <string name=\"fit_height\">සුදුසු උස</string>\n    <string name=\"batch_compare\">කණ්ඩායම් සංසන්දනය</string>\n    <string name=\"pick_files_to_checksum\">තෝරාගත් ඇල්ගොරිතම මත පදනම්ව එහි චෙක්සම් ගණනය කිරීමට ගොනුව/ගොනු තෝරන්න</string>\n    <string name=\"pick_files\">ගොනු තෝරන්න</string>\n    <string name=\"pick_directory\">නාමාවලිය තෝරන්න</string>\n    <string name=\"head_length_scale\">හිස දිග පරිමාණය</string>\n    <string name=\"stamp\">මුද්දර</string>\n    <string name=\"timestamp\">වේලා මුද්රාව</string>\n    <string name=\"format_pattern\">ආකෘති රටා</string>\n    <string name=\"padding\">පෑඩිං</string>\n    <string name=\"image_cutting\">රූප කැපීම</string>\n    <string name=\"image_cutting_sub\">රූප කොටස කපා වම් ඒවා සිරස් හෝ තිරස් රේඛා මගින් ඒකාබද්ධ කරන්න (ප්‍රතිලෝම විය හැක)</string>\n    <string name=\"vertical_pivot_line\">සිරස් විවර්තන රේඛාව</string>\n    <string name=\"horizontal_pivot_line\">තිරස් විවර්තන රේඛාව</string>\n    <string name=\"inverse_selection\">ප්රතිලෝම තේරීම</string>\n    <string name=\"inverse_vertical_selection_sub\">කැපූ ප්‍රදේශය වටා කොටස් ඒකාබද්ධ කිරීම වෙනුවට සිරස් කැපූ කොටස ඉතිරි වේ</string>\n    <string name=\"inverse_horizontal_selection_sub\">කැපූ ප්‍රදේශය වටා කොටස් ඒකාබද්ධ කිරීම වෙනුවට තිරස් කැපූ කොටස ඉතිරි වනු ඇත</string>\n    <string name=\"collection_mesh_gradients\">Mesh Gradients එකතුව</string>\n    <string name=\"mesh_gradients_sub\">අභිරුචි ගැට ප්‍රමාණය සහ විභේදනය සමඟ දැල් අනුක්‍රමය සාදන්න</string>\n    <string name=\"gradient_maker_type_image_mesh\">දැල් ශ්‍රේණියේ උඩැතිරිය</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">ලබා දී ඇති රූපවල ඉහලින් දැල් අනුක්‍රමණය සම්පාදනය කරන්න</string>\n    <string name=\"points_customization\">ලකුණු අභිරුචිකරණය</string>\n    <string name=\"grid_size\">ජාලක ප්‍රමාණය</string>\n    <string name=\"resolution_x\">විභේදනය X</string>\n    <string name=\"resolution_y\">යෝජනාව Y</string>\n    <string name=\"resolution\">විභේදනය</string>\n    <string name=\"pixel_by_pixel\">Pixel විසින් Pixel</string>\n    <string name=\"highlight_color\">වර්ණ උද්දීපනය කරන්න</string>\n    <string name=\"pixel_comparison_type\">පික්සල් සංසන්දන වර්ගය</string>\n    <string name=\"scan_barcode\">තීරු කේතය පරිලෝකනය කරන්න</string>\n    <string name=\"height_ratio\">උස අනුපාතය</string>\n    <string name=\"barcode_type\">තීරු කේතය වර්ගය</string>\n    <string name=\"enforce_bw\">B/W බලාත්මක කරන්න</string>\n    <string name=\"enforce_bw_sub\">තීරු කේත රූපය සම්පූර්ණයෙන්ම කළු සහ සුදු වන අතර යෙදුමේ තේමාවෙන් වර්ණවත් නොවේ</string>\n    <string name=\"barcodes_sub\">ඕනෑම තීරු කේතයක් (QR, EAN, AZTEC, …) ස්කෑන් කර එහි අන්තර්ගතය ලබා ගන්න හෝ නව එකක් උත්පාදනය කිරීමට ඔබේ පෙළ අලවන්න</string>\n    <string name=\"no_barcode_found\">තීරු කේතයක් හමු නොවිණි</string>\n    <string name=\"generated_barcode_will_be_here\">ජනනය කළ තීරු කේතය මෙහි වනු ඇත</string>\n    <string name=\"audio_cover_extractor\">ශ්රව්ය ආවරණ</string>\n    <string name=\"audio_cover_extractor_sub\">ශ්‍රව්‍ය ගොනු වලින් ඇල්බම ආවරණ රූප උපුටා ගන්න, බොහෝ පොදු ආකෘති සඳහා සහය දක්වයි</string>\n    <string name=\"pick_audio_to_start\">ආරම්භ කිරීමට ශ්‍රව්‍ය තෝරන්න</string>\n    <string name=\"pick_audio\">ශ්රව්ය උපකරණ තෝරන්න</string>\n    <string name=\"no_covers_found\">කවරයක් හමු නොවීය</string>\n    <string name=\"send_logs\">ලඝු-සටහන් යවන්න</string>\n    <string name=\"send_logs_sub\">යෙදුම් ලොග් ගොනුව බෙදා ගැනීමට ක්ලික් කරන්න, මෙය මට ගැටලුව හඳුනා ගැනීමට සහ ගැටලු විසඳීමට උදවු කළ හැක</string>\n    <string name=\"crash_title\">අපොයි… යමක් වැරදී ඇත</string>\n    <string name=\"crash_subtitle\">පහත විකල්ප භාවිතයෙන් ඔබට මා හා සම්බන්ධ විය හැකි අතර මම විසඳුමක් සෙවීමට උත්සාහ කරමි.\\n(ලඝු-සටහන් අමුණන්න අමතක කරන්න එපා)</string>\n    <string name=\"ocr_write_to_file\">ගොනු කිරීමට ලියන්න</string>\n    <string name=\"ocr_write_to_file_sub\">පින්තූර සමූහයකින් පෙළ උපුටා ගෙන එය එක් පෙළ ගොනුවක ගබඩා කරන්න</string>\n    <string name=\"ocr_write_to_metadata\">පාරදත්ත වෙත ලියන්න</string>\n    <string name=\"ocr_write_to_metadata_sub\">සෑම රූපයකින්ම පෙළ උපුටා ගෙන එය සාපේක්ෂ ඡායාරූපවල EXIF ​​තොරතුරු තුළ තබන්න</string>\n    <string name=\"invisible_mode\">නොපෙනෙන මාදිලිය</string>\n    <string name=\"invisible_mode_sub\">ඔබේ රූපවල බයිට් ඇතුළත ඇසට නොපෙනෙන ජල සලකුණු නිර්මාණය කිරීමට ස්ටෙගනොග්‍රැෆි භාවිතා කරන්න</string>\n    <string name=\"use_lsb\">LSB භාවිතා කරන්න</string>\n    <string name=\"use_lsb_sub\">LSB (Lessignificant Bit) steganography ක්‍රමය භාවිතා කරනු ඇත, FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">රතු ඇස් ස්වයංක්‍රීයව ඉවත් කරන්න</string>\n    <string name=\"password\">මුරපදය</string>\n    <string name=\"unlock\">අගුළු හරින්න</string>\n    <string name=\"pdf_is_protected\">PDF ආරක්ෂිතයි</string>\n    <string name=\"operation_almost_complete\">මෙහෙයුම බොහෝ දුරට අවසන්. දැන් අවලංගු කිරීමට එය නැවත ආරම්භ කිරීම අවශ්‍ය වේ</string>\n    <string name=\"sort_by_date_modified\">දිනය වෙනස් කරන ලදී</string>\n    <string name=\"sort_by_date_modified_reversed\">වෙනස් කළ දිනය (ආපසු හැර)</string>\n    <string name=\"sort_by_size\">ප්රමාණය</string>\n    <string name=\"sort_by_size_reversed\">ප්‍රමාණය (ප්‍රතිලෝම)</string>\n    <string name=\"sort_by_mime_type\">MIME වර්ගය</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME වර්ගය (ප්‍රතිලෝම)</string>\n    <string name=\"sort_by_extension\">දිගු කිරීම</string>\n    <string name=\"sort_by_extension_reversed\">දිගුව (ප්‍රතිලෝම)</string>\n    <string name=\"sort_by_date_added\">එකතු කළ දිනය</string>\n    <string name=\"sort_by_date_added_reversed\">එකතු කළ දිනය (ආපසු හැර)</string>\n    <string name=\"left_to_right\">වමේ සිට දකුණට</string>\n    <string name=\"right_to_left\">දකුණේ සිට වමට</string>\n    <string name=\"top_to_bottom\">ඉහළ සිට පහළට</string>\n    <string name=\"bottom_to_top\">පහළ සිට ඉහළට</string>\n    <string name=\"liquid_glass\">දියර වීදුරු</string>\n    <string name=\"liquid_glass_sub\">මෑතකදී නිවේදනය කරන ලද IOS 26 මත පදනම් වූ ස්විචයක් සහ එහි ද්‍රව වීදුරු සැලසුම් පද්ධතිය</string>\n    <string name=\"pick_image_or_base64\">රූපය තෝරන්න හෝ පහත Base64 දත්ත අලවන්න/ආයාත කරන්න</string>\n    <string name=\"type_image_link\">ආරම්භ කිරීමට රූප සබැඳිය ටයිප් කරන්න</string>\n    <string name=\"paste_link\">සබැඳිය අලවන්න</string>\n    <string name=\"kaleidoscope\">කැලිඩෝස්කෝප්</string>\n    <string name=\"secondary_angle\">ද්විතියික කෝණය</string>\n    <string name=\"sides\">පැති</string>\n    <string name=\"channel_mix\">නාලිකා මිශ්‍රණය</string>\n    <string name=\"blue_green\">නිල් කොළ</string>\n    <string name=\"red_blue\">රතු නිල්</string>\n    <string name=\"green_red\">කොළ රතු</string>\n    <string name=\"into_red\">රතු පාටට</string>\n    <string name=\"into_green\">කොළ පාටට</string>\n    <string name=\"into_blue\">නිල් පාටට</string>\n    <string name=\"cyan\">සියන්</string>\n    <string name=\"magenta\">මැජෙන්ටා</string>\n    <string name=\"yellow\">කහ</string>\n    <string name=\"color_halftone\">පාට Halftone</string>\n    <string name=\"contour\">සමෝච්ඡය</string>\n    <string name=\"levels\">මට්ටම්</string>\n    <string name=\"offset\">ඕෆ්සෙට්</string>\n    <string name=\"voronoi_crystallize\">Voronoi Crystallize</string>\n    <string name=\"shape\">හැඩය</string>\n    <string name=\"stretch\">දිගු කරන්න</string>\n    <string name=\"randomness\">අහඹු බව</string>\n    <string name=\"despeckle\">ඩෙස්පෙකල්</string>\n    <string name=\"diffuse\">විසරණය</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">දෙවන අරය</string>\n    <string name=\"equalize\">සම කරන්න</string>\n    <string name=\"glow\">දිලිසෙනවා</string>\n    <string name=\"whirl_and_pinch\">වර්ල් සහ පින්ච්</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">මායිම් වර්ණය</string>\n    <string name=\"polar_coordinates\">ධ්රැවීය ඛණ්ඩාංක</string>\n    <string name=\"rect_to_polar\">ධ්‍රැවීය දක්වා</string>\n    <string name=\"polar_to_rect\">ධ්‍රැවීය සිට සෘජු දක්වා</string>\n    <string name=\"invert_in_circle\">රවුමට පෙරළන්න</string>\n    <string name=\"reduce_noise\">ශබ්දය අඩු කරන්න</string>\n    <string name=\"simple_solarize\">සරල Solarize</string>\n    <string name=\"weave\">වියන්න</string>\n    <string name=\"x_gap\">X පරතරය</string>\n    <string name=\"y_gap\">Y පරතරය</string>\n    <string name=\"x_width\">X පළල</string>\n    <string name=\"y_wdth\">Y පළල</string>\n    <string name=\"twirl\">කරකවන්න</string>\n    <string name=\"rubber_stmp\">රබර් මුද්දරය</string>\n    <string name=\"smear\">ස්මියර්</string>\n    <string name=\"density\">ඝනත්වය</string>\n    <string name=\"mix\">මිශ්ර කරන්න</string>\n    <string name=\"sphere_lensh_distortion\">Sphere Lens Distortion</string>\n    <string name=\"refraction_index\">වර්තන දර්ශකය</string>\n    <string name=\"arc\">චාප</string>\n    <string name=\"spread_angle\">පැතිරීමේ කෝණය</string>\n    <string name=\"sparkle\">දීප්තිය</string>\n    <string name=\"rays\">කිරණ</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">මරියා</string>\n    <string name=\"autumn\">සරත් ඍතුව</string>\n    <string name=\"bone\">අස්ථි</string>\n    <string name=\"jet\">ජෙට්</string>\n    <string name=\"winter\">ශීත ඍතුව</string>\n    <string name=\"ocean\">සාගරය</string>\n    <string name=\"summer\">ගිම්හානය</string>\n    <string name=\"spring\">වසන්තය</string>\n    <string name=\"cool_variant\">සිසිල් ප්රභේදය</string>\n    <string name=\"hsv\">එච්.එස්.වී</string>\n    <string name=\"pink\">රෝස</string>\n    <string name=\"hot\">උණුසුම්</string>\n    <string name=\"parula\">වචනය</string>\n    <string name=\"magma\">මැග්මා</string>\n    <string name=\"inferno\">අපාය</string>\n    <string name=\"plasma\">ප්ලාස්මා</string>\n    <string name=\"viridis\">විරිඩිස්</string>\n    <string name=\"cividis\">පුරවැසියන්</string>\n    <string name=\"twilight\">ට්විලයිට්</string>\n    <string name=\"twilight_shifted\">Twilight මාරු විය</string>\n    <string name=\"auto_perspective\">Perspective Auto</string>\n    <string name=\"deskew\">ඩෙස්ක්ව්</string>\n    <string name=\"allow_crop\">වගා කිරීමට ඉඩ දෙන්න</string>\n    <string name=\"crop_or_perspective\">බෝග හෝ ඉදිරිදර්ශනය</string>\n    <string name=\"absolute\">නිරපේක්ෂ</string>\n    <string name=\"turbo\">ටර්බෝ</string>\n    <string name=\"deep_green\">ගැඹුරු කොළ</string>\n    <string name=\"lens_correction\">කාච නිවැරදි කිරීම</string>\n    <string name=\"target_lens_profile\">JSON ආකෘතියෙන් ඉලක්කගත කාච පැතිකඩ ගොනුව</string>\n    <string name=\"download_ready_lens_profiles\">සූදානම් කාච පැතිකඩ බාගන්න</string>\n    <string name=\"part_percents\">කොටස් සියයට</string>\n    <string name=\"export_as_json\">JSON ලෙස නිර්යාත කරන්න</string>\n    <string name=\"export_as_json_sub\">json නියෝජනය ලෙස palette දත්ත සමඟ තන්තුව පිටපත් කරන්න</string>\n    <string name=\"seam_carving\">මැහුම් කැටයම්</string>\n    <string name=\"home_screen\">මුල් තිරය</string>\n    <string name=\"lock_screen\">අගුළු තිරය</string>\n    <string name=\"built_in\">බිල්ට්-ඉන්</string>\n    <string name=\"wallpapers_export\">Wallpapers අපනයනය</string>\n    <string name=\"refresh\">නැවුම් කරන්න</string>\n    <string name=\"wallpapers_export_sub\">වත්මන් නිවස, අගුලු දැමීම සහ බිල්ට්-ඉන් බිතුපත් ලබා ගන්න</string>\n    <string name=\"allow_access_to_all_files_for_wp\">සියලුම ගොනු වෙත ප්‍රවේශ වීමට ඉඩ දෙන්න, බිතුපත් ලබා ගැනීමට මෙය අවශ්‍ය වේ</string>\n    <string name=\"allow_read_media_images_for_wp\">බාහිර ගබඩා අවසරය කළමනාකරණය කිරීම ප්‍රමාණවත් නොවේ, ඔබ ඔබේ පින්තූර වෙත ප්‍රවේශ වීමට ඉඩ දිය යුතුය, \\\"සියල්ලට ඉඩ දෙන්න\\\" තේරීමට වග බලා ගන්න</string>\n    <string name=\"add_preset_to_filename\">ගොනු නාමයට පෙරසිටුව එක් කරන්න</string>\n    <string name=\"add_preset_to_filename_sub\">පින්තූර ගොනු නාමයට තෝරාගත් පෙරසිටුවක් සමඟ උපසර්ගය එකතු කරයි</string>\n    <string name=\"add_image_scale_mode_to_filename\">ගොනු නාමයට රූප පරිමාණ මාදිලිය එක් කරන්න</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">රූප ගොනු නාමයට තෝරාගත් රූප පරිමාණ මාදිලිය සමඟ උපසර්ගය එකතු කරයි</string>\n    <string name=\"ascii_art\">Ascii කලාව</string>\n    <string name=\"ascii_art_sub\">පින්තූරයක් ලෙස පෙනෙන ascii පෙළට පින්තූරය පරිවර්තනය කරන්න</string>\n    <string name=\"params\">පරාමිති</string>\n    <string name=\"invert_colors_ascii_sub\">සමහර අවස්ථාවලදී වඩා හොඳ ප්‍රතිඵලයක් සඳහා රූපයට සෘණ පෙරහන යොදන්න</string>\n    <string name=\"processing_screenshot\">තිර රුවක් සකසමින්</string>\n    <string name=\"screenshot_not_captured_try_again\">තිර රුවක් ග්‍රහණය කර නැත, නැවත උත්සාහ කරන්න</string>\n    <string name=\"skipped_saving\">සුරැකීම මඟ හැරිණි</string>\n    <string name=\"skipped_saving_multiple\">%1$s ගොනු මඟ හරින ලදී</string>\n    <string name=\"allow_skip_if_larger\">විශාල නම් මඟ හැරීමට ඉඩ දෙන්න</string>\n    <string name=\"allow_skip_if_larger_sub\">ප්‍රතිඵලයක් ලෙස ලැබෙන ගොනු ප්‍රමාණය මුල් ප්‍රමාණයට වඩා විශාල නම් සමහර මෙවලම්වලට පින්තූර සුරැකීම මඟ හැරීමට ඉඩ දෙනු ලැබේ</string>\n    <string name=\"qr_type_calendar_event\">දින දර්ශන සිදුවීම</string>\n    <string name=\"qr_type_contact_info\">අමතන්න</string>\n    <string name=\"qr_type_email\">ඊමේල් කරන්න</string>\n    <string name=\"qr_type_geo_point\">ස්ථානය</string>\n    <string name=\"qr_type_phone\">දුරකථනය</string>\n    <string name=\"qr_type_plain\">පෙළ</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wifi</string>\n    <string name=\"open_network\">ජාලය විවෘත කරන්න</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">දුරකථනය</string>\n    <string name=\"message\">පණිවිඩය</string>\n    <string name=\"address\">ලිපිනය</string>\n    <string name=\"subject\">විෂය</string>\n    <string name=\"body\">ශරීරය</string>\n    <string name=\"name\">නම</string>\n    <string name=\"organization\">සංවිධානය</string>\n    <string name=\"title\">මාතෘකාව</string>\n    <string name=\"phones\">දුරකථන</string>\n    <string name=\"emails\">ඊමේල්</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">ලිපිනයන්</string>\n    <string name=\"summary\">සාරාංශය</string>\n    <string name=\"description\">විස්තරය</string>\n    <string name=\"location\">ස්ථානය</string>\n    <string name=\"organizer\">සංවිධායක</string>\n    <string name=\"start_date\">ආරම්භක දිනය</string>\n    <string name=\"end_date\">අවසන් දිනය</string>\n    <string name=\"status\">තත්ත්වය</string>\n    <string name=\"latitude\">අක්ෂාංශ</string>\n    <string name=\"longitude\">දේශාංශ</string>\n    <string name=\"create_barcode\">තීරු කේතය සාදන්න</string>\n    <string name=\"edit_barcode\">තීරු කේතය සංස්කරණය කරන්න</string>\n    <string name=\"wifi_configuration\">Wi-Fi වින්යාසය</string>\n    <string name=\"security\">ආරක්ෂාව</string>\n    <string name=\"pick_contact\">සම්බන්ධතාවය තෝරන්න</string>\n    <string name=\"grant_contact_permission\">තෝරාගත් සම්බන්ධතා භාවිතයෙන් ස්වයංක්‍රීයව පිරවීම සඳහා සැකසීම් තුළ සම්බන්ධතා අවසර ලබා දෙන්න</string>\n    <string name=\"contact_info\">සම්බන්ධතා තොරතුරු</string>\n    <string name=\"first_name\">මුල් නම</string>\n    <string name=\"middle_name\">මැද නම</string>\n    <string name=\"last_name\">අවසන් නම</string>\n    <string name=\"pronunciation\">උච්චාරණය</string>\n    <string name=\"add_phone\">දුරකථනය එක් කරන්න</string>\n    <string name=\"add_email\">ඊමේල් එකතු කරන්න</string>\n    <string name=\"add_address\">ලිපිනය එකතු කරන්න</string>\n    <string name=\"website\">වෙබ් අඩවිය</string>\n    <string name=\"add_website\">වෙබ් අඩවිය එක් කරන්න</string>\n    <string name=\"formatted_name\">ආකෘතිගත නම</string>\n    <string name=\"qr_code_top_image\">මෙම රූපය තීරු කේතයට ඉහළින් තැබීමට භාවිතා කරනු ඇත</string>\n    <string name=\"code_customization\">කේත අභිරුචිකරණය</string>\n    <string name=\"qr_logo_image\">මෙම රූපය QR කේතයේ මධ්‍යයේ ලාංඡනය ලෙස භාවිත කෙරේ</string>\n    <string name=\"logo\">ලාංඡනය</string>\n    <string name=\"logo_padding\">ලාංඡන පිරවීම</string>\n    <string name=\"logo_size\">ලාංඡන ප්රමාණය</string>\n    <string name=\"logo_corners\">ලාංඡන කොන්</string>\n    <string name=\"fourth_eye\">හතරවන ඇස</string>\n    <string name=\"fourth_eye_description\">පහළ කෙළවරේ සිව්වන ඇස එක් කිරීමෙන් qr කේතයට අක්ෂි සමමිතිය එක් කරයි</string>\n    <string name=\"pixel_shape\">පික්සල් හැඩය</string>\n    <string name=\"frame_shape\">රාමු හැඩය</string>\n    <string name=\"ball_shape\">බෝල හැඩය</string>\n    <string name=\"error_correction_level\">දෝෂ නිවැරදි කිරීමේ මට්ටම</string>\n    <string name=\"dark_color\">අඳුරු වර්ණය</string>\n    <string name=\"light_color\">සැහැල්ලු වර්ණය</string>\n    <string name=\"hyper_os\">අධි මෙහෙයුම් පද්ධතිය</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS වැනි ශෛලිය</string>\n    <string name=\"mask_pattern\">මාස්ක් රටාව</string>\n    <string name=\"code_may_be_not_scannable\">මෙම කේතය ස්කෑන් කළ නොහැකි විය හැක, සියලු උපාංග සමඟ එය කියවිය හැකි කිරීමට පෙනුම පරාමිතීන් වෙනස් කරන්න</string>\n    <string name=\"not_scannable\">ස්කෑන් කළ නොහැක</string>\n    <string name=\"launcher_mode_sub\">මෙවලම් වඩාත් සංයුක්ත වීමට මුල් තිරයේ යෙදුම් දියත් කිරීමක් මෙන් පෙනෙනු ඇත</string>\n    <string name=\"launcher_mode\">දියත් කිරීමේ මාදිලිය</string>\n    <string name=\"flood_fill_sub\">තෝරාගත් බුරුසුවක් සහ මෝස්තරයක් සහිත ප්රදේශයක් පුරවයි</string>\n    <string name=\"flood_fill\">ගංවතුර පිරවීම</string>\n    <string name=\"spray\">ඉසින්න</string>\n    <string name=\"spray_sub\">ග්‍රැෆිටි හැඩැති මාර්ගය අඳිනවා</string>\n    <string name=\"square_particles\">හතරැස් අංශු</string>\n    <string name=\"square_particles_sub\">ඉසින අංශු රවුම් වෙනුවට හතරැස් හැඩැති වනු ඇත</string>\n    <string name=\"palette_tools\">පැලට් මෙවලම්</string>\n    <string name=\"palette_tools_sub\">රූපයෙන් මූලික/ද්‍රව්‍ය ජනනය කරන්න, නැතහොත් විවිධ පැලට් ආකෘති හරහා ආනයනය/අපනයනය කරන්න</string>\n    <string name=\"edit_palette\">පලත් සංස්කරණය කරන්න</string>\n    <string name=\"edit_palette_sub\">විවිධ ආකෘති හරහා අපනයන/ආනයන palette</string>\n    <string name=\"color_name\">වර්ණ නම</string>\n    <string name=\"palette_name\">පැලට් නම</string>\n    <string name=\"palette_format\">පැලට් ආකෘතිය</string>\n    <string name=\"export_palette_sub\">ජනනය කරන ලද තලය විවිධ ආකෘති වෙත අපනයනය කරන්න</string>\n    <string name=\"add_color_palette_sub\">වත්මන් තලයට නව වර්ණයක් එක් කරයි</string>\n    <string name=\"palette_name_not_supported\">%1$s ආකෘතිය පැලට් නම සැපයීමට සහාය නොදක්වයි</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store ප්‍රතිපත්ති හේතුවෙන්, මෙම විශේෂාංගය වත්මන් ගොඩනැගීමට ඇතුළත් කළ නොහැක. මෙම ක්‍රියාකාරීත්වයට ප්‍රවේශ වීමට, කරුණාකර විකල්ප මූලාශ්‍රයකින් ImageToolbox බාගන්න. ඔබට පහතින් GitHub හි පවතින ගොඩනැගීම් සොයා ගත හැක.</string>\n    <string name=\"open_github_page\">Github පිටුව විවෘත කරන්න</string>\n    <string name=\"overwrite_files_sub_short\">තෝරාගත් ෆෝල්ඩරයේ සුරැකීම වෙනුවට මුල් ගොනුව අලුත් එකක් සමඟ ප්‍රතිස්ථාපනය වේ</string>\n    <string name=\"hidden_watermark_text_detected\">සැඟවුණු දිය සලකුණු පෙළ අනාවරණය විය</string>\n    <string name=\"hidden_watermark_image_detected\">සැඟවුණු දිය සලකුණු රූපයක් අනාවරණය විය</string>\n    <string name=\"this_image_was_hidden\">මෙම රූපය සඟවා ඇත</string>\n    <string name=\"generative_inpaint\">උත්පාදක පින්තාරු කිරීම</string>\n    <string name=\"generative_inpaint_sub\">OpenCV මත රඳා නොසිට, AI ආකෘතියක් භාවිතයෙන් රූපයක ඇති වස්තූන් ඉවත් කිරීමට ඔබට ඉඩ සලසයි. මෙම විශේෂාංගය භාවිතා කිරීමට, යෙදුම GitHub වෙතින් අවශ්‍ය ආකෘතිය (~200 MB) බාගනු ඇත</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV මත රඳා නොසිට, AI ආකෘතියක් භාවිතයෙන් රූපයක ඇති වස්තූන් ඉවත් කිරීමට ඔබට ඉඩ සලසයි. මෙය දිගුකාලීන මෙහෙයුමක් විය හැකිය</string>\n    <string name=\"error_level_analysis\">දෝෂ මට්ටම විශ්ලේෂණය</string>\n    <string name=\"luminance_gradient\">දීප්තිය අනුක්‍රමණය</string>\n    <string name=\"average_distance\">සාමාන්ය දුර</string>\n    <string name=\"copy_move_detection\">චලනය හඳුනාගැනීම පිටපත් කරන්න</string>\n    <string name=\"retain\">රඳවා ගන්න</string>\n    <string name=\"coefficent\">සංගුණක</string>\n    <string name=\"clipboard_data_is_too_large\">ක්ලිප්බෝඩ් දත්ත විශාල වැඩිය</string>\n    <string name=\"data_is_too_large_to_copy\">දත්ත පිටපත් කිරීමට විශාල වැඩිය</string>\n    <string name=\"simple_weave_pixelization\">සරල වියමන පික්සලකරණය</string>\n    <string name=\"staggered_pixelization\">එකතැන පල්වෙන පික්සලකරණය</string>\n    <string name=\"cross_pixelization\">හරස් පික්සලකරණය</string>\n    <string name=\"micro_macro_pixelization\">ක්ෂුද්‍ර මැක්‍රෝ පික්සලීකරණය</string>\n    <string name=\"orbital_pixelization\">කක්ෂීය පික්සලකරණය</string>\n    <string name=\"vortex_pixelization\">Vortex Pixelization</string>\n    <string name=\"pulse_grid_pixelization\">Pulse Grid Pixelization</string>\n    <string name=\"nucleus_pixelization\">න්යෂ්ටිය පික්සලීකරණය</string>\n    <string name=\"radial_weave_pixelization\">රේඩියල් වීව් පික්සලීකරණය</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\" විවෘත කළ නොහැක</string>\n    <string name=\"snowfall_mode\">හිම පතන මාදිලිය</string>\n    <string name=\"enabled\">සබල කර ඇත</string>\n    <string name=\"border_frame\">මායිම් රාමුව</string>\n    <string name=\"glitch_variant\">Glitch ප්රභේදය</string>\n    <string name=\"channel_shift\">නාලිකා මාරුව</string>\n    <string name=\"max_offset\">උපරිම ඕෆ්සෙට්</string>\n    <string name=\"vhs\">වීඑච්එස්</string>\n    <string name=\"block_glitch\">අවහිර ග්ලිච්</string>\n    <string name=\"block_size\">බ්ලොක් ප්රමාණය</string>\n    <string name=\"crt_curvature\">CRT වක්‍රය</string>\n    <string name=\"curvature\">වක්රය</string>\n    <string name=\"chroma\">ක්රෝමා</string>\n    <string name=\"pixel_melt\">පික්සල් දියවීම</string>\n    <string name=\"max_drop\">මැක්ස් ඩ්‍රොප්</string>\n    <string name=\"ai_tools\">AI මෙවලම්</string>\n    <string name=\"ai_tools_sub\">කෞතුක වස්තු ඉවත් කිරීම හෝ denoising වැනි AI ආකෘති හරහා රූප සැකසීමට විවිධ මෙවලම්</string>\n    <string name=\"model_anime_undeint\">සම්පීඩනය, හකුරු රේඛා</string>\n    <string name=\"model_broadcast\">කාටූන්, විකාශන සම්පීඩනය</string>\n    <string name=\"model_rgb_max_denoise_fp16\">සාමාන්ය සම්පීඩනය, සාමාන්ය ශබ්දය</string>\n    <string name=\"model_wb_denoise\">වර්ණ රහිත කාටූන් ශබ්දය</string>\n    <string name=\"model_span_anime_pretrain\">වේගවත්, සාමාන්‍ය සම්පීඩනය, සාමාන්‍ය ශබ්දය, සජීවිකරණ/විකට/ඇනිමේ</string>\n    <string name=\"model_book_scan\">පොත් ස්කෑන් කිරීම</string>\n    <string name=\"model_overexposure\">නිරාවරණ නිවැරදි කිරීම</string>\n    <string name=\"model_fbcnn_color_fp16\">සාමාන්ය සම්පීඩනය, වර්ණ රූපවල හොඳම</string>\n    <string name=\"model_fbcnn_gray_fp16\">සාමාන්‍ය සම්පීඩනයේදී හොඳම, අළු පරිමාණ රූප</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">සාමාන්‍ය සම්පීඩනය, අළු පරිමාණ රූප, වඩා ශක්තිමත්</string>\n    <string name=\"model_scunet_color_gan_fp16\">සාමාන්ය ශබ්දය, වර්ණ රූප</string>\n    <string name=\"model_scunet_color_psnr_fp16\">සාමාන්ය ශබ්දය, වර්ණ රූප, වඩා හොඳ විස්තර</string>\n    <string name=\"model_scunet_gray_15_fp16\">සාමාන්‍ය ශබ්දය, අළු පරිමාණ රූප</string>\n    <string name=\"model_scunet_gray_25_fp16\">සාමාන්‍ය ඝෝෂාව, අළු පරිමාණ රූප, ශක්තිමත්</string>\n    <string name=\"model_scunet_gray_50_fp16\">සාමාන්‍ය ශබ්දය, අළු පරිමාණ රූප, ශක්තිමත්ම</string>\n    <string name=\"model_jpeg_destroyer\">සාමාන්ය සම්පීඩනය</string>\n    <string name=\"model_jaywreck\">සාමාන්ය සම්පීඩනය</string>\n    <string name=\"model_h264\">Texturization, h264 සම්පීඩනය</string>\n    <string name=\"model_vhs\">VHS සම්පීඩනය</string>\n    <string name=\"model_cinepak\">සම්මත නොවන සම්පීඩනය (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">බින්ක් සම්පීඩනය, ජ්යාමිතිය මත වඩා හොඳය</string>\n    <string name=\"model_debink_v5\">බින්ක් සම්පීඩනය, වඩා ශක්තිමත්</string>\n    <string name=\"model_debink_v6\">බින්ක් සම්පීඩනය, මෘදු, විස්තර රඳවා තබා ගනී</string>\n    <string name=\"model_antialias\">පඩිපෙළ-පියවර ආචරණය ඉවත් කිරීම, සිනිඳු කිරීම</string>\n    <string name=\"model_kdm_scans\">ස්කෑන් කළ චිත්‍ර/ඇඳීම්, මෘදු සම්පීඩනය, මෝයර්</string>\n    <string name=\"model_bandage\">වර්ණ පටිය</string>\n    <string name=\"model_halftone\">මන්දගාමී, අර්ධ ටෝන ඉවත් කිරීම</string>\n    <string name=\"model_colorizer\">අළු පරිමාණ/bw රූප සඳහා සාමාන්‍ය වර්ණ කාරකය, වඩා හොඳ ප්‍රතිඵල සඳහා DDColor භාවිතා කරන්න</string>\n    <string name=\"model_deedge\">දාර ඉවත් කිරීම</string>\n    <string name=\"model_desharpen\">අධික මුවහත් වීම ඉවත් කරයි</string>\n    <string name=\"model_dither\">මන්දගාමී, දිරාපත් වීම</string>\n    <string name=\"model_gainres\">Anti-aliasing, general artifacts, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 පරිලෝකනය සැකසීම</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">සැහැල්ලු රූප වැඩිදියුණු කිරීමේ ආකෘතිය</string>\n    <string name=\"model_bcgone_detailed_v2\">සම්පීඩන පුරාවස්තු ඉවත් කිරීම</string>\n    <string name=\"model_bcgone_smooth\">සම්පීඩන පුරාවස්තු ඉවත් කිරීම</string>\n    <string name=\"model_bandage_smooth\">සුමට ප්රතිඵල සමඟ වෙළුම් පටියක් ඉවත් කිරීම</string>\n    <string name=\"model_bendel_halftone\">Halftone රටා සැකසීම</string>\n    <string name=\"model_dither_deleter_v3_smooth\">ඩිතර් රටා ඉවත් කිරීම V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG කෞතුක භාණ්ඩ ඉවත් කිරීම V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 වයනය වැඩි දියුණු කිරීම</string>\n    <string name=\"model_vhs_sharpen\">VHS තියුණු කිරීම සහ වැඩිදියුණු කිරීම</string>\n    <string name=\"merging\">ඒකාබද්ධ කිරීම</string>\n    <string name=\"chunk_size\">කුට්ටි ප්රමාණය</string>\n    <string name=\"overlap_size\">අතිච්ඡාදනය වන ප්‍රමාණය</string>\n    <string name=\"note_chunk_info\">%1$s px ට වැඩි පින්තූර කැබලිවලට කපා සකසනු ලැබේ, දෘශ්‍ය මැහුම් වැළැක්වීම සඳහා මේවා අතිච්ඡාදනය කරයි.</string>\n    <string name=\"large_chunk_warning\">විශාල ප්රමාණවලින් අඩු-අන්ත උපාංග සමඟ අස්ථාවරත්වය ඇති විය හැක</string>\n    <string name=\"select_one_to_start\">ආරම්භ කිරීමට එකක් තෝරන්න</string>\n    <string name=\"delete_model_sub\">ඔබට %1$s මාදිලිය මැකීමට අවශ්‍යද? ඔබ එය නැවත බාගත කිරීමට අවශ්ය වනු ඇත</string>\n    <string name=\"confirm\">තහවුරු කරන්න</string>\n    <string name=\"models\">ආකෘති</string>\n    <string name=\"downloaded_models\">බාගත කළ මාදිලි</string>\n    <string name=\"available_models\">පවතින මාදිලි</string>\n    <string name=\"preparing\">සූදානම් කිරීම</string>\n    <string name=\"active_model\">ක්රියාකාරී ආකෘතිය</string>\n    <string name=\"failed_to_open_session\">සැසිය විවෘත කිරීමට අසමත් විය</string>\n    <string name=\"only_onnx_models\">ආනයනය කළ හැක්කේ .onnx/.ort මාදිලි පමණි</string>\n    <string name=\"import_model\">ආයාත ආකෘතිය</string>\n    <string name=\"import_model_sub\">වැඩිදුර භාවිතය සඳහා අභිරුචි onnx ආකෘතිය ආයාත කරන්න, onnx/ort ආකෘති පමණක් පිළිගනු ලැබේ, esrgan වැනි ප්‍රභේද සියල්ලටම පාහේ සහය දක්වයි</string>\n    <string name=\"imported_models\">ආනයනික මාදිලි</string>\n    <string name=\"model_scunet_color_15_fp16\">සාමාන්ය ශබ්දය, වර්ණ රූප</string>\n    <string name=\"model_scunet_color_25_fp16\">සාමාන්‍ය ඝෝෂාව, වර්ණවත් රූප, ශක්තිමත්</string>\n    <string name=\"model_scunet_color_50_fp16\">සාමාන්ය ශබ්දය, වර්ණ රූප, ශක්තිමත්ම</string>\n    <string name=\"model_artifacts_dithering_alsa\">දිරාපත්වන කෞතුක වස්තු සහ වර්ණ පටිය අඩු කරයි, සුමට අනුක්‍රමණය සහ පැතලි වර්ණ ප්‍රදේශ වැඩි දියුණු කරයි.</string>\n    <string name=\"model_nmkd_brighten_redux\">ස්වභාවික වර්ණ සංරක්ෂණය කරමින් සමබර උද්දීපනයන් සමඟ රූපයේ දීප්තිය සහ වෙනස වැඩි දියුණු කරයි.</string>\n    <string name=\"model_nmkd_brighten\">විස්තර තබා ගැනීම සහ අධික ලෙස නිරාවරණය වීම වළක්වා ගනිමින් අඳුරු රූප දීප්තිමත් කරයි.</string>\n    <string name=\"model_nmkd_detoon\">අධික වර්ණ ටොනිං ඉවත් කිරීම සහ වඩාත් මධ්යස්ථ සහ ස්වභාවික වර්ණ සමතුලිතතාවයක් ප්රතිස්ථාපනය කරයි.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">සියුම් විස්තර සහ වයනය සංරක්ෂණය කිරීම අවධාරණය කරමින් Poisson-පාදක ශබ්ද ටෝනිං යොදයි.</string>\n    <string name=\"model_noise_toner_poisson_soft\">සුමට සහ අඩු ආක්‍රමණශීලී දෘශ්‍ය ප්‍රතිඵල සඳහා මෘදු Poisson ශබ්ද ටෝනිං යොදයි.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">ඒකාකාර ශබ්ද ටෝනිං විස්තර සංරක්ෂණය සහ රූපයේ පැහැදිලිකම කෙරෙහි අවධානය යොමු කරයි.</string>\n    <string name=\"model_noise_toner_uniform_soft\">සියුම් වයනය සහ සුමට පෙනුම සඳහා මෘදු ඒකාකාර ශබ්ද ටෝනිං.</string>\n    <string name=\"model_repainter\">කෞතුක භාණ්ඩ නැවත පින්තාරු කිරීමෙන් සහ රූපයේ අනුකූලතාව වැඩි දියුණු කිරීමෙන් හානියට පත් හෝ අසමාන ප්‍රදේශ අලුත්වැඩියා කරයි.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">අවම කාර්ය සාධන පිරිවැයක් සහිත වර්ණ පටිය ඉවත් කරන සැහැල්ලු ඩිබෑන්ඩ් මාදිලිය.</string>\n    <string name=\"model_jpeg_0_20\">වැඩි දියුණු කළ පැහැදිලිකම සඳහා ඉතා ඉහළ සම්පීඩන කෞතුක වස්තු (0-20% ගුණාත්මක) සහිත රූප ප්‍රශස්ත කරයි.</string>\n    <string name=\"model_jpeg_20_40\">ඉහළ සම්පීඩන කෞතුක වස්තු (20-40% ගුණාත්මක) සමඟ රූප වැඩි දියුණු කරයි, විස්තර ප්‍රතිස්ථාපනය කිරීම සහ ශබ්දය අඩු කිරීම.</string>\n    <string name=\"model_jpeg_40_60\">මධ්‍යස්ථ සම්පීඩනය (40-60% ගුණාත්මක), තියුණු බව සහ සුමට බව සමතුලිත කිරීම සමඟ රූප වැඩි දියුණු කරයි.</string>\n    <string name=\"model_jpeg_60_80\">සියුම් විස්තර සහ වයනය වැඩි දියුණු කිරීම සඳහා සැහැල්ලු සම්පීඩනය (60-80% ගුණාත්මක) සමඟ රූප පිරිපහදු කරයි.</string>\n    <string name=\"model_jpeg_80_100\">ස්වාභාවික පෙනුම සහ විස්තර ආරක්ෂා කරන අතරම, ආසන්න පාඩු රහිත රූප (80-100% ගුණත්වය) තරමක් වැඩි දියුණු කරයි.</string>\n    <string name=\"model_spongecolor_lite\">සරල හා වේගවත් වර්ණ ගැන්වීම, කාටූන්, සුදුසු නොවේ</string>\n    <string name=\"model_deblr\">කෞතුක වස්තු හඳුන්වාදීමකින් තොරව තියුණු බව වැඩිදියුණු කිරීම, රූපය නොපැහැදිලි කිරීම තරමක් අඩු කරයි.</string>\n    <string name=\"processing_channel\">දිගුකාලීන මෙහෙයුම්</string>\n    <string name=\"processing_image\">රූපය සැකසීම</string>\n    <string name=\"processing\">සැකසීම</string>\n    <string name=\"model_artifacts_jpg_0_20\">ඉතා අඩු ගුණාත්මක රූපවල (0-20%) බර JPEG සම්පීඩන කෞතුක වස්තු ඉවත් කරයි.</string>\n    <string name=\"model_artifacts_jpg_20_40\">අතිශයින් සම්පීඩිත රූපවල (20-40%) ශක්තිමත් JPEG කෞතුක වස්තු අඩු කරයි.</string>\n    <string name=\"model_artifacts_jpg_40_60\">පින්තූර විස්තර (40-60%) සංරක්ෂණය කරමින් මධ්‍යස්ථ JPEG කෞතුක වස්තු පිරිසිදු කරයි.</string>\n    <string name=\"model_artifacts_jpg_60_80\">තරමක් උසස් තත්ත්වයේ රූප (60-80%) තුළ සැහැල්ලු JPEG කෞතුක භාණ්ඩ පිරිපහදු කරයි.</string>\n    <string name=\"model_artifacts_jpg_80_100\">අලාභ රහිත රූපවල (80-100%) කුඩා JPEG කෞතුක වස්තු සියුම් ලෙස අඩු කරයි.</string>\n    <string name=\"model_redetail_v2\">සියුම් විස්තර සහ වයනය වැඩි දියුණු කරයි, බර කෞතුක වස්තු නොමැතිව දැනෙන තියුණු බව වැඩි දියුණු කරයි.</string>\n    <string name=\"processing_finished\">සැකසීම අවසන්</string>\n    <string name=\"processing_failed\">සැකසීම අසාර්ථක විය</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">වේගය සඳහා ප්‍රශස්ත ස්වභාවික පෙනුමක් තබා ගනිමින් සමේ වයනය සහ විස්තර වැඩි දියුණු කරයි.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG සම්පීඩන කෞතුක වස්තු ඉවත් කර සම්පීඩිත ඡායාරූප සඳහා රූපයේ ගුණාත්මකභාවය ප්‍රතිසාධනය කරයි.</string>\n    <string name=\"model_iso_denoise_v1\">අඩු ආලෝක තත්ත්ව යටතේ ගන්නා ලද ඡායාරූපවල ISO ශබ්දය අඩු කරයි, විස්තර සංරක්ෂණය කරයි.</string>\n    <string name=\"model_dejumbo\">අධික ලෙස නිරාවරණය වූ හෝ \\\"ජම්බෝ\\\" උද්දීපනය නිවැරදි කර වඩා හොඳ ටෝනල් සමතුලිතතාවය යථා තත්වයට පත් කරයි.</string>\n    <string name=\"model_ddcolor_tiny\">අළු පරිමාණ රූපවලට ස්වභාවික වර්ණ එකතු කරන සැහැල්ලු සහ වේගවත් වර්ණ ගැන්වීමේ ආකෘතිය.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">ඩෙනොයිස්</string>\n    <string name=\"type_colorize\">වර්ණ ගන්වන්න</string>\n    <string name=\"type_artifacts\">පුරාවස්තු</string>\n    <string name=\"type_enhance\">වැඩි දියුණු කරන්න</string>\n    <string name=\"type_anime\">ඇනිමෙ</string>\n    <string name=\"type_scans\">ස්කෑන්</string>\n    <string name=\"type_upscale\">ඉහළ මට්ටමේ</string>\n    <string name=\"model_realesrgan_x4v3\">සාමාන්‍ය රූප සඳහා X4 upscaler; මධ්යස්ථ deblur සහ denoise සමඟ අඩු GPU සහ කාලය භාවිතා කරන කුඩා ආකෘතිය.</string>\n    <string name=\"model_realesrgan_x2plus\">සාමාන්‍ය රූප, වයනය සහ ස්වභාවික විස්තර සංරක්ෂණය කිරීම සඳහා X2 ඉහළට.</string>\n    <string name=\"model_realesrgan_x4plus\">වැඩි දියුණු කළ වයනය සහ යථාර්ථවාදී ප්‍රතිඵල සහිත සාමාන්‍ය රූප සඳහා X4 ඉහළ පරිමාණය.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler සජීවිකරණ රූප සඳහා ප්‍රශස්ත කර ඇත; තියුණු රේඛා සහ විස්තර සඳහා RRDB කුට්ටි 6 ක්.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE අලාභය සහිත X4 upscaler, සාමාන්‍ය රූප සඳහා සුමට ප්‍රතිඵල සහ අඩු කරන ලද කෞතුක භාණ්ඩ නිෂ්පාදනය කරයි.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler සජීවිකරණ රූප සඳහා ප්‍රශස්ත කර ඇත; තියුණු විස්තර සහ සුමට රේඛා සහිත 4B32F ප්‍රභේදය.</string>\n    <string name=\"model_ultrasharp_v2_x4\">සාමාන්ය රූප සඳහා X4 UltraSharp V2 ආකෘතිය; තියුණු බව සහ පැහැදිලි බව අවධාරණය කරයි.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; වේගවත් හා කුඩා, අඩු GPU මතකයක් භාවිතා කරන අතරතුර විස්තර ආරක්ෂා කරයි.</string>\n    <string name=\"model_rmbg_1_4\">ඉක්මන් පසුබිම ඉවත් කිරීම සඳහා සැහැල්ලු ආකෘතිය. සමබර කාර්ය සාධනය සහ නිරවද්යතාව. ආලේඛ්‍ය චිත්‍ර, වස්තු සහ දර්ශන සමඟ ක්‍රියා කරයි. බොහෝ භාවිත අවස්ථා සඳහා නිර්දේශ කෙරේ.</string>\n    <string name=\"type_removebg\">BG ඉවත් කරන්න</string>\n    <string name=\"horizontal_border_thickness\">තිරස් මායිම් ඝණකම</string>\n    <string name=\"vertical_border_thickness\">සිරස් මායිම් ඝණකම</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s වර්ණය</item>\n        <item quantity=\"other\">%1$s වර්ණ</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">වත්මන් ආකෘතිය කුට්ටි කිරීමට සහය නොදක්වයි, රූපය මුල් මානයන්ගෙන් සකසනු ඇත, මෙය ඉහළ මතක පරිභෝජනයක් සහ අඩු-අන්ත උපාංග සමඟ ගැටලු ඇති කළ හැකිය</string>\n    <string name=\"chunking_disabled\">කුට්ටි කිරීම අක්‍රියයි, රූපය මුල් මානයන්ගෙන් සකසනු ඇත, මෙය ඉහළ මතක පරිභෝජනයක් සහ අඩු-අන්ත උපාංග සමඟ ගැටලු ඇති කළ හැකි නමුත් අනුමාන මත වඩා හොඳ ප්‍රතිඵල ලබා දිය හැකිය</string>\n    <string name=\"chunking\">කුට්ටි කිරීම</string>\n    <string name=\"model_u2net\">පසුබිම ඉවත් කිරීම සඳහා ඉහළ නිරවද්‍ය රූප ඛණ්ඩන ආකෘතිය</string>\n    <string name=\"model_u2netp\">කුඩා මතක භාවිතය සමඟ වේගවත් පසුබිම ඉවත් කිරීම සඳහා U2Net හි සැහැල්ලු අනුවාදය.</string>\n    <string name=\"model_ddcolor\">සම්පූර්ණ DDColor ආකෘතිය අවම කෞතුක වස්තු සහිත සාමාන්‍ය රූප සඳහා උසස් තත්ත්වයේ වර්ණ ගැන්වීම ලබා දෙයි. සියලුම වර්ණ ගැන්වීමේ මාදිලියේ හොඳම තේරීම.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor පුහුණු සහ පුද්ගලික කලාත්මක දත්ත කට්ටල; අඩු යථාර්ථවාදී නොවන වර්ණ කෞතුක වස්තු සමඟ විවිධ සහ කලාත්මක වර්ණ ගැන්වීමේ ප්‍රතිඵල නිපදවයි.</string>\n    <string name=\"model_birefnet\">නිවැරදි පසුබිම ඉවත් කිරීම සඳහා Swin Transformer මත පදනම් වූ සැහැල්ලු BiRefNet ආකෘතිය.</string>\n    <string name=\"model_inspyrenet\">තියුණු දාර සහිත උසස් තත්ත්වයේ පසුබිම ඉවත් කිරීම සහ විශිෂ්ට විස්තර සංරක්ෂණය, විශේෂයෙන් සංකීර්ණ වස්තූන් සහ උපක්‍රමශීලී පසුබිම් මත.</string>\n    <string name=\"model_isnet\">සාමාන්‍ය වස්තූන් සහ මධ්‍යස්ථ විස්තර සංරක්ෂණය සඳහා සුදුසු සුමට දාර සහිත නිවැරදි වෙස් මුහුණු නිපදවන පසුබිම් ඉවත් කිරීමේ ආකෘතිය.</string>\n    <string name=\"model_already_downloaded\">ආකෘතිය දැනටමත් බාගත කර ඇත</string>\n    <string name=\"model_successfully_imported\">ආකෘතිය සාර්ථකව ආනයනය කරන ලදී</string>\n    <string name=\"type\">ටයිප් කරන්න</string>\n    <string name=\"keyword\">මූල පදය</string>\n    <string name=\"very_fast\">ඉතා වේගවත්</string>\n    <string name=\"normal\">සාමාන්යයි</string>\n    <string name=\"slow\">මන්දගාමී</string>\n    <string name=\"very_slow\">ඉතා මන්දගාමී</string>\n    <string name=\"compute_percents\">ප්රතිශතය ගණනය කරන්න</string>\n    <string name=\"minimum_value_is\">අවම අගය %1$s වේ</string>\n    <string name=\"warp_sub\">ඇඟිලි වලින් ඇඳීමෙන් රූපය විකෘති කරන්න</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">දැඩි බව</string>\n    <string name=\"warp_mode\">Warp මාදිලිය</string>\n    <string name=\"warp_mode_move\">චලනය කරන්න</string>\n    <string name=\"warp_mode_grow\">වැඩෙන්න</string>\n    <string name=\"warp_mode_shrink\">හැකිලෙන්න</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Swirl CCW</string>\n    <string name=\"fade_strength\">දුර්වල ශක්තිය</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">පහළ වැටීම</string>\n    <string name=\"start_drop\">වැටීම ආරම්භ කරන්න</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">බාගත කිරීම</string>\n    <string name=\"smooth_shapes\">සිනිඳු හැඩතල</string>\n    <string name=\"smooth_shapes_sub\">සිනිඳු, වඩාත් ස්වාභාවික හැඩතල සඳහා සම්මත වටකුරු සෘජුකෝණාස්‍ර වෙනුවට සුපිරි ඉලිප්සාකාර භාවිතා කරන්න</string>\n    <string name=\"shape_type\">හැඩ වර්ගය</string>\n    <string name=\"cut\">කපනවා</string>\n    <string name=\"rounded\">වටකුරු</string>\n    <string name=\"smooth\">සිනිඳුයි</string>\n    <string name=\"cut_shapes_sub\">වටකුරු තොරව තියුණු දාර</string>\n    <string name=\"rounded_shapes_sub\">සම්භාව්ය වටකුරු කොන්</string>\n    <string name=\"shapes_type\">හැඩතල වර්ගය</string>\n    <string name=\"corners_size\">කෝනර් ප්රමාණය</string>\n    <string name=\"squircle\">ලේනා</string>\n    <string name=\"squircle_shapes_sub\">අලංකාර වටකුරු UI මූලද්‍රව්‍ය</string>\n    <string name=\"filename_format\">ගොනු නාමය ආකෘතිය</string>\n    <string name=\"prefix_pattern_description\">ව්‍යාපෘති නම්, වෙළඳ නාම, හෝ පුද්ගලික ටැග් සඳහා පරිපූර්ණ, ගොනු නාමයේ ආරම්භයේම තබා ඇති අභිරුචි පෙළ.</string>\n    <string name=\"original_filename_pattern_description\">මුල් ගොනු නාමය දිගුවකින් තොරව භාවිත කරයි, මූලාශ්‍ර හඳුනාගැනීම නොවෙනස්ව තබා ගැනීමට ඔබට උදවු කරයි.</string>\n    <string name=\"width_pattern_description\">පික්සලවල රූපයේ පළල, විභේදන වෙනස්කම් හඹා යාමට හෝ ප්‍රතිඵල පරිමාණය කිරීමට ප්‍රයෝජනවත් වේ.</string>\n    <string name=\"height_pattern_description\">පික්සලවල රූපයේ උස, දර්ශන අනුපාත හෝ අපනයන සමඟ වැඩ කිරීමේදී උපකාරී වේ.</string>\n    <string name=\"random_numbers_pattern_description\">අද්විතීය ගොනු නාම සහතික කිරීම සඳහා අහඹු ඉලක්කම් ජනනය කරයි; අනුපිටපත් වලට එරෙහිව අමතර ආරක්ෂාවක් සඳහා තවත් ඉලක්කම් එකතු කරන්න.</string>\n    <string name=\"sequence_number_pattern_description\">කණ්ඩායම් නිර්යාත සඳහා ස්වයංක්‍රීය වර්ධක කවුන්ටරය, එක් සැසියක පින්තූර කිහිපයක් සුරැකීමේදී වඩාත් සුදුසුය.</string>\n    <string name=\"preset_info_pattern_description\">රූපය සැකසූ ආකාරය ඔබට පහසුවෙන් මතක තබා ගත හැකි වන පරිදි ගොනු නාමයට යොදන ලද පෙරසැකසුම් නාමය ඇතුළත් කරයි.</string>\n    <string name=\"scale_mode_pattern_description\">ප්‍රතිප්‍රමාණ කළ, කපන ලද, හෝ සවි කළ රූප වෙන්කර හඳුනා ගැනීමට උදවු කරමින්, සැකසීමේදී භාවිත කරන ලද රූප පරිමාණ ප්‍රකාරය සංදර්ශන කරයි.</string>\n    <string name=\"suffix_pattern_description\">අභිරුචි පෙළ ගොනු නාමයේ අවසානයේ තබා ඇත, _v2, _edited, හෝ _final වැනි අනුවාද සඳහා ප්‍රයෝජනවත් වේ.</string>\n    <string name=\"extension_pattern_description\">ගොනු දිගුව (png, jpg, webp, ආදිය), සත්‍ය සුරැකි ආකෘතියට ස්වයංක්‍රීයව ගැලපේ.</string>\n    <string name=\"formatted_timestamp_pattern_description\">පරිපූර්ණ වර්ග කිරීම සඳහා java පිරිවිතර මගින් ඔබේම ආකෘතිය නිර්වචනය කිරීමට ඔබට ඉඩ සලසන අභිරුචිකරණය කළ හැකි වේලා මුද්දරයක්.</string>\n    <string name=\"fling_type\">ෆ්ලින්ග් වර්ගය</string>\n    <string name=\"android_native\">Android ස්වදේශීය</string>\n    <string name=\"ios_style\">iOS විලාසය</string>\n    <string name=\"smooth_curve\">Smooth Curve</string>\n    <string name=\"quick_stop\">ඉක්මන් නැවතුම</string>\n    <string name=\"bouncy\">බූන්සි</string>\n    <string name=\"floaty\">පාවෙන</string>\n    <string name=\"snappy\">කපටි</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">අනුවර්තනය</string>\n    <string name=\"accessibility_aware\">ප්‍රවේශ්‍යතා දැනුවත්</string>\n    <string name=\"reduced_motion\">අඩු කළ චලනය</string>\n    <string name=\"android_native_sub\">මූලික සංසන්දනය සඳහා දේශීය Android අනුචලන භෞතික විද්‍යාව</string>\n    <string name=\"smooth_sub\">සාමාන්‍ය භාවිතය සඳහා සමබර, සුමට අනුචලනය</string>\n    <string name=\"ios_style_sub\">ඉහළ ඝර්ෂණ iOS වැනි අනුචලන හැසිරීම</string>\n    <string name=\"smooth_curve_sub\">වෙනස් අනුචලන හැඟීම සඳහා අද්විතීය spline වක්රය</string>\n    <string name=\"quick_stop_sub\">ඉක්මන් නැවතුම් සමග නිවැරදි අනුචලනය</string>\n    <string name=\"bouncy_sub\">සෙල්ලක්කාර, ප්‍රතිචාරාත්මක බූන්සි අනුචලනය</string>\n    <string name=\"floaty_sub\">අන්තර්ගත බ්‍රවුස් කිරීම සඳහා දිගු, ලිස්සා යන අනුචලන</string>\n    <string name=\"snappy_sub\">අන්තර්ක්‍රියාකාරී UI සඳහා ඉක්මන්, ප්‍රතිචාරාත්මක අනුචලනය</string>\n    <string name=\"ultra_smooth_sub\">විස්තීරණ ගම්‍යතාවයක් සහිත වාරික සුමට අනුචලනය</string>\n    <string name=\"adaptive_sub\">ප්‍රවේගය මත පදනම්ව භෞතික විද්‍යාව සීරුමාරු කරයි</string>\n    <string name=\"accessibility_aware_sub\">පද්ධති ප්‍රවේශ්‍යතා සැකසීම් වලට ගරු කරයි</string>\n    <string name=\"reduced_motion_sub\">ප්රවේශ්යතා අවශ්යතා සඳහා අවම චලනය</string>\n    <string name=\"primary_lines\">ප්රාථමික රේඛා</string>\n    <string name=\"primary_lines_sub\">සෑම පස්වන පේළියකම ඝන රේඛාවක් එකතු කරයි</string>\n    <string name=\"fill_color\">වර්ණ පුරවන්න</string>\n    <string name=\"hidden_tools\">සැඟවුණු මෙවලම්</string>\n    <string name=\"hidden_for_share\">බෙදාගැනීම සඳහා සැඟවුණු මෙවලම්</string>\n    <string name=\"color_library\">වර්ණ පුස්තකාලය</string>\n    <string name=\"color_library_sub\">විශාල වර්ණ එකතුවක් පිරික්සන්න</string>\n    <string name=\"model_fatality_deblur\">ස්වාභාවික විස්තර පවත්වා ගනිමින් රූපවලින් මුවහත් කර නොපැහැදිලි ඉවත් කරයි, අවධානයෙන් බැහැර ඡායාරූප සවි කිරීම සඳහා වඩාත් සුදුසුය.</string>\n    <string name=\"model_unresize_v3\">කලින් ප්‍රතිප්‍රමාණ කර ඇති පින්තූර බුද්ධිමත්ව ප්‍රතිසාධනය කරයි, නැතිවූ විස්තර සහ වයනය ප්‍රතිසාධනය කරයි.</string>\n    <string name=\"model_liveaction_v1_span\">සජීවී-ක්‍රියාකාරී අන්තර්ගතයන් සඳහා ප්‍රශස්ත කර ඇත, සම්පීඩන කෞතුක වස්තු අඩු කරයි සහ චිත්‍රපට/රූපවාහිනී සංදර්ශන රාමු තුළ සියුම් විස්තර වැඩි දියුණු කරයි.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS-ගුණාත්මක දර්ශන HD බවට පරිවර්තනය කරයි, ටේප් ශබ්දය ඉවත් කිරීම සහ වින්ටේජ් හැඟීම ආරක්ෂා කරමින් විභේදනය වැඩි දියුණු කරයි.</string>\n    <string name=\"model_text2hd_v1\">පෙළ බර රූප සහ තිරපිටපත් සඳහා විශේෂිත, අක්ෂර මුවහත් කර කියවීමේ හැකියාව වැඩි දියුණු කරයි.</string>\n    <string name=\"model_frankendata_pretrainer\">විවිධ දත්ත කට්ටල මත පුහුණු කරන ලද උසස් ඉහළ නැංවීම, සාමාන්‍ය කාර්ය ඡායාරූප වැඩිදියුණු කිරීම සඳහා විශිෂ්ටයි.</string>\n    <string name=\"model_realwebphoto_v2\">වෙබ් සම්පීඩිත ඡායාරූප සඳහා ප්‍රශස්ත කර ඇත, JPEG කෞතුක වස්තු ඉවත් කර ස්වභාවික පෙනුම යථා තත්වයට පත් කරයි.</string>\n    <string name=\"model_realwebphoto_v4\">වඩා හොඳ වයනය සංරක්ෂණය සහ කෞතුක වස්තු අඩු කිරීම සමඟ වෙබ් ඡායාරූප සඳහා වැඩිදියුණු කළ අනුවාදය.</string>\n    <string name=\"model_dat_2x\">ද්විත්ව එකතු කිරීමේ ට්‍රාන්ස්ෆෝමර් තාක්‍ෂණය සමඟ 2x ඉහළ නැංවීම, තියුණු බව සහ ස්වාභාවික විස්තර පවත්වා ගනී.</string>\n    <string name=\"model_dat_3x\">උසස් ට්‍රාන්ස්ෆෝමර් ගෘහ නිර්මාණ ශිල්පය භාවිතයෙන් 3x ඉහළ නැංවීම, මධ්‍යස්ථ විශාල කිරීමේ අවශ්‍යතා සඳහා වඩාත් සුදුසුය.</string>\n    <string name=\"model_dat_4x\">අති නවීන ට්‍රාන්ස්ෆෝමර් ජාලය සමඟ 4x උසස් තත්ත්වයේ ඉහළ නැංවීම, විශාල පරිමාණයෙන් සියුම් තොරතුරු ආරක්ෂා කරයි.</string>\n    <string name=\"model_nafnet_deblurring\">ඡායාරූප වලින් නොපැහැදිලි/ශබ්ද සහ සෙලවීම් ඉවත් කරයි. සාමාන්‍ය අරමුණ නමුත් ඡායාරූප මත හොඳම.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Swin2SR ට්‍රාන්ස්ෆෝමරය භාවිතයෙන් අඩු ගුණාත්මක රූප ප්‍රතිසාධනය කරයි, BSRGAN හායනය සඳහා ප්‍රශස්ත කර ඇත. බර සම්පීඩන කෞතුක වස්තු සවි කිරීම සහ 4x පරිමාණයෙන් විස්තර වැඩි දියුණු කිරීම සඳහා විශිෂ්ටයි.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN හායනය පිළිබඳ පුහුණු කරන ලද SwinIR ට්‍රාන්ස්ෆෝමරය සමඟ 4x ඉහළ නැංවීම. ඡායාරූප සහ සංකීර්ණ දර්ශනවල තියුණු වයනය සහ වඩාත් ස්වාභාවික විස්තර සඳහා GAN භාවිතා කරයි.</string>\n    <string name=\"path\">මාර්ගය</string>\n    <string name=\"merge_pdf\">PDF ඒකාබද්ධ කරන්න</string>\n    <string name=\"merge_pdf_sub\">PDF ගොනු කිහිපයක් එක් ලේඛනයකට ඒකාබද්ධ කරන්න</string>\n    <string name=\"files_order\">ගොනු ඇණවුම</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">PDF බෙදන්න</string>\n    <string name=\"split_pdf_sub\">PDF ලේඛනයෙන් නිශ්චිත පිටු උපුටා ගන්න</string>\n    <string name=\"rotate_pdf\">PDF කරකවන්න</string>\n    <string name=\"rotate_pdf_sub\">පිටු දිශානතිය ස්ථිරවම නිවැරදි කරන්න</string>\n    <string name=\"pages\">පිටු</string>\n    <string name=\"rearrange_pdf\">PDF නැවත සකස් කරන්න</string>\n    <string name=\"rearrange_pdf_sub\">නැවත ඇණවුම් කිරීමට පිටු ඇද දමන්න</string>\n    <string name=\"hold_drag_drop\">පිටු අල්ලාගෙන අදින්න</string>\n    <string name=\"page_numbers\">පිටු අංක</string>\n    <string name=\"page_numbers_sub\">ඔබගේ ලේඛනවලට ස්වයංක්‍රීයව අංකනය එක් කරන්න</string>\n    <string name=\"label_format\">ලේබල් ආකෘතිය</string>\n    <string name=\"pdf_to_text\">PDF සිට පෙළ (OCR)</string>\n    <string name=\"pdf_to_text_sub\">ඔබගේ PDF ලේඛන වලින් සරල පෙළ උපුටා ගන්න</string>\n    <string name=\"watermark_pdf_sub\">සන්නාමකරණය හෝ ආරක්ෂාව සඳහා අභිරුචි පෙළ ආවරණය කරන්න</string>\n    <string name=\"signature\">අත්සන</string>\n    <string name=\"signature_sub\">ඕනෑම ලේඛනයකට ඔබේ විද්‍යුත් අත්සන එක් කරන්න</string>\n    <string name=\"will_be_for_signature\">මෙය අත්සනක් ලෙස භාවිතා කරනු ඇත</string>\n    <string name=\"unlock_pdf\">PDF අගුළු හරින්න</string>\n    <string name=\"unlock_pdf_sub\">ඔබගේ ආරක්ෂිත ගොනු වලින් මුරපද ඉවත් කරන්න</string>\n    <string name=\"protect_pdf\">PDF ආරක්ෂා කරන්න</string>\n    <string name=\"protect_pdf_sub\">ශක්තිමත් සංකේතනයකින් ඔබේ ලේඛන සුරක්ෂිත කරන්න</string>\n    <string name=\"success\">සාර්ථකත්වය</string>\n    <string name=\"pdf_unlocked\">PDF අගුළු හැර ඇත, ඔබට එය සුරැකීමට හෝ බෙදා ගැනීමට හැකිය</string>\n    <string name=\"repair_pdf\">PDF අලුත්වැඩියා කරන්න</string>\n    <string name=\"repair_pdf_sub\">දූෂිත හෝ කියවිය නොහැකි ලේඛන නිවැරදි කිරීමට උත්සාහ කිරීම</string>\n    <string name=\"grayscale\">අළු පරිමාණ</string>\n    <string name=\"grayscale_pdf_sub\">සියලුම ලේඛන කාවැද්දූ පින්තූර අළු පරිමාණයට පරිවර්තනය කරන්න</string>\n    <string name=\"compress_pdf\">PDF සම්පීඩනය කරන්න</string>\n    <string name=\"compress_pdf_sub\">පහසු බෙදාගැනීම සඳහා ඔබේ ලේඛන ගොනු ප්‍රමාණය ප්‍රශස්ත කරන්න</string>\n    <string name=\"repair_info\">ImageToolbox අභ්‍යන්තර හරස් යොමු වගුව නැවත ගොඩනඟන අතර මුල සිටම ගොනු ව්‍යුහය ප්‍රතිජනනය කරයි. මෙය \\\\\"විවෘත කළ නොහැකි\\\\\" බොහෝ ගොනු වෙත ප්‍රවේශය ප්‍රතිසාධනය කළ හැක.</string>\n    <string name=\"grayscale_info\">මෙම මෙවලම සියලුම ලේඛන රූප අළු පරිමාණයට පරිවර්තනය කරයි. ගොනු ප්රමාණය මුද්රණය කිරීම සහ අඩු කිරීම සඳහා හොඳම වේ</string>\n    <string name=\"metadata\">පාරදත්ත</string>\n    <string name=\"metadata_pdf_sub\">වඩා හොඳ පෞද්ගලිකත්වය සඳහා ලේඛන ගුණාංග සංස්කරණය කරන්න</string>\n    <string name=\"tags\">ටැග්</string>\n    <string name=\"producer\">නිෂ්පාදකයා</string>\n    <string name=\"author\">කර්තෘ</string>\n    <string name=\"keywords\">මූල පද</string>\n    <string name=\"creator\">නිර්මාතෘ</string>\n    <string name=\"privacy_deep_clean\">පෞද්ගලිකත්වය ගැඹුරු පිරිසිදු</string>\n    <string name=\"privacy_deep_clean_sub\">මෙම ලේඛනය සඳහා ලබා ගත හැකි සියලුම පාර-දත්ත හිස් කරන්න</string>\n    <string name=\"page\">පිටුව</string>\n    <string name=\"deep_ocr\">ගැඹුරු OCR</string>\n    <string name=\"deep_ocr_sub\">ලේඛනයෙන් පෙළ උපුටා ගෙන එය Tesseract එන්ජිම භාවිතයෙන් එක් පෙළ ගොනුවක ගබඩා කරන්න</string>\n    <string name=\"cant_remove_all\">සියලුම පිටු ඉවත් කළ නොහැක</string>\n    <string name=\"remove_pages_pdf\">PDF පිටු ඉවත් කරන්න</string>\n    <string name=\"remove_pages_pdf_sub\">PDF ලේඛනයෙන් නිශ්චිත පිටු ඉවත් කරන්න</string>\n    <string name=\"tap_to_remove\">ඉවත් කිරීමට තට්ටු කරන්න</string>\n    <string name=\"manually\">අතින්</string>\n    <string name=\"crop_pdf\">PDF කපන්න</string>\n    <string name=\"crop_pdf_sub\">ලේඛන පිටු ඕනෑම සීමාවකට කපන්න</string>\n    <string name=\"flatten_pdf\">PDF සමතලා කරන්න</string>\n    <string name=\"flatten_pdf_sub\">ලේඛන පිටු රාස්ටර් කිරීමෙන් PDF වෙනස් කළ නොහැකි කරන්න</string>\n    <string name=\"camera_failed_to_open\">කැමරාව ආරම්භ කිරීමට නොහැකි විය. කරුණාකර අවසර පරීක්ෂා කර එය වෙනත් යෙදුමක් විසින් භාවිතා නොකරන බවට වග බලා ගන්න.</string>\n    <string name=\"extract_images\">පින්තූර උපුටා ගන්න</string>\n    <string name=\"extract_images_sub\">PDF වල තැන්පත් කර ඇති පින්තූර ඒවායේ මුල් විභේදනයෙන් උපුටා ගන්න</string>\n    <string name=\"pdf_no_embedded\">මෙම PDF ගොනුවේ කිසිදු කාවැද්දූ පින්තූර අඩංගු නොවේ</string>\n    <string name=\"extract_images_info\">මෙම මෙවලම සෑම පිටුවක්ම පරිලෝකනය කර සම්පූර්ණ ගුණාත්මක මූලාශ්‍ර රූප ප්‍රතිසාධන කරයි - ලේඛනවලින් මුල් පිටපත් සුරැකීමට පරිපූර්ණයි</string>\n    <string name=\"draw_signature\">අත්සන අඳින්න</string>\n    <string name=\"pen_params\">පෑන් පරාමිති</string>\n    <string name=\"draw_signature_sub\">ලේඛනවල තැබීමට රූපයක් ලෙස තමන්ගේ අත්සන භාවිතා කරන්න</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">ලබා දී ඇති පරතරය සමඟ ලේඛනය වෙන් කර නව ලේඛන zip සංරක්ෂිතයට අසුරන්න</string>\n    <string name=\"interval\">අන්තරය</string>\n    <string name=\"print_pdf\">PDF මුද්‍රණය කරන්න</string>\n    <string name=\"print_pdf_sub\">අභිරුචි පිටු ප්‍රමාණය සමඟ මුද්‍රණය සඳහා ලේඛනය සකස් කරන්න</string>\n    <string name=\"pages_per_sheet\">පත්‍රයකට පිටු</string>\n    <string name=\"orientation\">දිශානතිය</string>\n    <string name=\"page_size\">පිටු ප්‍රමාණය</string>\n    <string name=\"margin\">ආන්තිකය</string>\n    <string name=\"bloom\">බ්ලූම්</string>\n    <string name=\"soft_knee\">මෘදු දණහිස</string>\n    <string name=\"model_realesr_animevideo_v3x4\">සජීවිකරණ සහ කාටූන් සඳහා ප්‍රශස්ත කර ඇත. වැඩි දියුණු කළ ස්වභාවික වර්ණ සහ අඩු කෞතුක වස්තු සමඟ වේගවත් ඉහළ නැංවීම</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 වැනි විලාසය</string>\n    <string name=\"calculate_hint\">අපේක්ෂිත අගය ගණනය කිරීමට මූලික ගණිත සංකේත මෙහි ඇතුළත් කරන්න (උදා. (5+5)*10)</string>\n    <string name=\"math_expression\">ගණිත ප්රකාශනය</string>\n    <string name=\"pick_up_to_n_collage_images\">පින්තූර %1$s දක්වා ගන්න</string>\n    <string name=\"background_color_for_alpha_formats\">ඇල්ෆා ආකෘති සඳහා පසුබිම් වර්ණය</string>\n    <string name=\"background_color_for_alpha_formats_sub\">ඇල්ෆා සහාය ඇතිව සෑම රූප ආකෘතියක් සඳහාම පසුබිම් වර්ණය සැකසීමේ හැකියාව එක් කරයි, අක්‍රිය කළ විට මෙය ඇල්ෆා නොවන ඒවා සඳහා පමණි</string>\n    <string name=\"keep_date_time\">දිනය වේලාව තබා ගන්න</string>\n    <string name=\"keep_date_time_sub\">සෑම විටම දිනය සහ වේලාවට අදාළ exif ටැග් සුරකින්න, Keep exif විකල්පයෙන් ස්වාධීනව ක්‍රියා කරයි</string>\n    <string name=\"open_markup_project\">විවෘත ව්යාපෘතිය</string>\n    <string name=\"open_markup_project_sub\">කලින් සුරකින ලද රූප මෙවලම් පෙට්ටි ව්‍යාපෘතියක් සංස්කරණය කිරීම දිගටම කරගෙන යන්න</string>\n    <string name=\"markup_project_open_failed\">රූප මෙවලම් පෙට්ටිය ව්‍යාපෘතිය විවෘත කළ නොහැක</string>\n    <string name=\"markup_project_missing_data\">රූප මෙවලම් පෙට්ටිය ව්‍යාපෘතියේ ව්‍යාපෘති දත්ත මඟ හැරී ඇත</string>\n    <string name=\"markup_project_corrupted\">රූප මෙවලම් පෙට්ටිය ව්‍යාපෘතිය දූෂිතයි</string>\n    <string name=\"unsupported_markup_project_version\">සහාය නොදක්වන රූප මෙවලම් පෙට්ටිය ව්‍යාපෘති අනුවාදය: %1$d</string>\n    <string name=\"save_markup_project\">ව්යාපෘතිය සුරකින්න</string>\n    <string name=\"save_markup_project_sub\">සංස්කරණය කළ හැකි ව්‍යාපෘති ගොනුවක ස්තර, පසුබිම සහ සංස්කරණ ඉතිහාසය ගබඩා කරන්න</string>\n    <string name=\"failed_to_open\">විවෘත කිරීමට අසමත් විය</string>\n    <string name=\"ocr_write_to_searchable_pdf\">සෙවිය හැකි PDF වෙත ලියන්න</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">පින්තූර කාණ්ඩයෙන් පෙළ හඳුනාගෙන සෙවිය හැකි PDF රූපය සහ තෝරාගත හැකි පෙළ ස්ථරය සමඟ සුරකින්න</string>\n    <string name=\"layer_alpha\">ඇල්ෆා ස්ථරය</string>\n    <string name=\"horizontal_flip\">තිරස් පෙරළීම</string>\n    <string name=\"vertical_flip\">සිරස් පෙරළීම</string>\n    <string name=\"lock\">අගුළු දමන්න</string>\n    <string name=\"add_shadow\">සෙවනැල්ල එකතු කරන්න</string>\n    <string name=\"shadow_color\">සෙවනැලි වර්ණය</string>\n    <string name=\"text_geometry\">පෙළ ජ්යාමිතිය</string>\n    <string name=\"text_geometry_sub\">තියුණු ශෛලීකරණය සඳහා පෙළ දිගු කරන්න හෝ ඇල කරන්න</string>\n    <string name=\"scale_x\">X පරිමාණය</string>\n    <string name=\"skew_x\">ස්කීව් X</string>\n    <string name=\"remove_annotations\">විවරණ ඉවත් කරන්න</string>\n    <string name=\"remove_annotations_sub\">PDF පිටුවලින් සබැඳි, අදහස්, උද්දීපනය, හැඩතල, හෝ පෝරම ක්ෂේත්‍ර වැනි තෝරාගත් විවරණ වර්ග ඉවත් කරන්න</string>\n    <string name=\"annotation_link\">අධි සබැඳි</string>\n    <string name=\"annotation_file_attachment\">ගොනු ඇමුණුම්</string>\n    <string name=\"annotation_line\">රේඛා</string>\n    <string name=\"annotation_popup\">උත්පතන</string>\n    <string name=\"annotation_stamp\">මුද්දර</string>\n    <string name=\"annotation_shapes\">හැඩතල</string>\n    <string name=\"annotation_text\">පෙළ සටහන්</string>\n    <string name=\"annotation_text_markup\">පෙළ සලකුණු කිරීම</string>\n    <string name=\"annotation_widget\">ආකෘති ක්ෂේත්ර</string>\n    <string name=\"annotation_markup\">සලකුණු කිරීම</string>\n    <string name=\"annotation_unknown\">නොදන්නා</string>\n    <string name=\"annotations\">විවරණ</string>\n    <string name=\"ungroup\">සමූහ ඉවත් කරන්න</string>\n    <string name=\"add_shadow_sub\">වින්‍යාසගත කළ හැකි වර්ණ සහ ඕෆ්සෙට් සහිත ස්ථරය පිටුපස බොඳ සෙවනැල්ල එක් කරන්න</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-sk/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"zoom\">Priblíženie obrázka</string>\n    <string name=\"smth_went_wrong\">Niečo sa pokazilo: %1$s</string>\n    <string name=\"size\">Veľkosť %1$s</string>\n    <string name=\"loading\">Načítava sa…</string>\n    <string name=\"image_too_large_preview\">Obrázok je príliš veľký na zobrazenie náhľadu, ale aj tak sa ho pokúsime uložiť</string>\n    <string name=\"pick_image\">Začnite výberom obrázka</string>\n    <string name=\"width\">Šírka %1$s</string>\n    <string name=\"height\">Výška %1$s</string>\n    <string name=\"quality\">Kvalita</string>\n    <string name=\"extension\">Rozšírenie</string>\n    <string name=\"resize_type\">Zmena typu veľkosti</string>\n    <string name=\"explicit\">Explicitné</string>\n    <string name=\"flexible\">Flexibilné</string>\n    <string name=\"pick_image_alt\">Vybrať obrázok</string>\n    <string name=\"app_closing_sub\">Naozaj chcete zatvoriť aplikáciu?</string>\n    <string name=\"app_closing\">Aplikácia sa zatvára</string>\n    <string name=\"stay\">Zostať</string>\n    <string name=\"close\">Zatvoriť</string>\n    <string name=\"reset_image\">Obnoviť obrázok</string>\n    <string name=\"reset_image_sub\">Zmeny obrázka sa vrátia na pôvodné hodnoty</string>\n    <string name=\"values_reset\">Hodnoty boli úspešne obnovené</string>\n    <string name=\"reset\">Obnovenie</string>\n    <string name=\"something_went_wrong\">Niečo sa pokazilo</string>\n    <string name=\"restart_app\">Reštartovať aplikáciu</string>\n    <string name=\"copied\">Skopírované do schránky</string>\n    <string name=\"exception\">Výnimka</string>\n    <string name=\"edit_exif\">Upraviť EXIF</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">Neboli nájdené žiadne údaje EXIF</string>\n    <string name=\"add_tag\">Pridať značku</string>\n    <string name=\"save\">Uložiť</string>\n    <string name=\"clear\">Vymazať</string>\n    <string name=\"clear_exif\">Vymazať EXIF</string>\n    <string name=\"cancel\">Zrušiť</string>\n    <string name=\"clear_exif_sub\">Všetky údaje EXIF obrázka budú vymazané. Túto akciu nie je možné vrátiť späť!</string>\n    <string name=\"presets\">Predvoľby</string>\n    <string name=\"crop\">Orezať</string>\n    <string name=\"image_not_saved\">Ukladanie</string>\n    <string name=\"image_not_saved_sub\">Všetky neuložené zmeny sa stratia, ak teraz skončíte</string>\n    <string name=\"check_source_code\">Zdrojový kód</string>\n    <string name=\"check_source_code_sub\">Získajte najnovšie aktualizácie, diskutujte o problémoch a ešte oveľa viac</string>\n    <string name=\"single_edit\">Jednotlivá úprava</string>\n    <string name=\"single_edit_sub\">Úprava, zmena veľkosti a editácia jedného obrázku</string>\n    <string name=\"pick_color\">Výber farieb</string>\n    <string name=\"pick_color_sub\">Vybrať farbu z obrázka, kopírovať alebo zdieľať</string>\n    <string name=\"image\">Obrázok</string>\n    <string name=\"color\">Farba</string>\n    <string name=\"color_copied\">Farba skopírovaná</string>\n    <string name=\"crop_sub\">Orezať obrázok na ľubovoľné rozmery</string>\n    <string name=\"version\">Verzia</string>\n    <string name=\"keep_exif\">Ponechať EXIF</string>\n    <string name=\"images\">Obrázky: %d</string>\n    <string name=\"change_preview\">Zmeniť náhľad</string>\n    <string name=\"remove\">Odstrániť</string>\n    <string name=\"palette_sub\">Vygenerovať vzorku farebnej palety z daného obrázka</string>\n    <string name=\"generate_palette\">Vytvoriť paletu</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"update\">Aktualizácia</string>\n    <string name=\"new_version\">Nová verzia %1$s</string>\n    <string name=\"unsupported_type\">Nepodporovaný typ: %1$s</string>\n    <string name=\"no_palette\">Nedá sa vygenerovať paleta pre daný obrázok</string>\n    <string name=\"original\">Originál</string>\n    <string name=\"folder\">Výstupný priečinok</string>\n    <string name=\"def\">Predvolené</string>\n    <string name=\"custom\">Vlastné</string>\n    <string name=\"unspecified\">Nešpecifikované</string>\n    <string name=\"device_storage\">Úložisko zariadenia</string>\n    <string name=\"by_bytes_resize\">Upraviť veľkosť</string>\n    <string name=\"max_bytes\">Maximálna veľkosť v KB</string>\n    <string name=\"by_bytes_resize_sub\">Zmena veľkosti obrázka podľa zadanej veľkosti v KB</string>\n    <string name=\"compare\">Porovnať</string>\n    <string name=\"compare_sub\">Porovnať dva dané obrázky</string>\n    <string name=\"pick_two_images\">Začnite výberom dvoch obrázkov</string>\n    <string name=\"pick_images\">Vybrať obrázky</string>\n    <string name=\"settings\">Nastavenia</string>\n    <string name=\"night_mode\">Nočný režim</string>\n    <string name=\"dark\">Tmavý</string>\n    <string name=\"light\">Svetlý</string>\n    <string name=\"system\">Systém</string>\n    <string name=\"dynamic_colors\">Dynamické farby</string>\n    <string name=\"customization\">Prispôsobenie</string>\n    <string name=\"allow_image_monet\">Povoliť monetizáciu obrázka</string>\n    <string name=\"allow_image_monet_sub\">Ak je táto možnosť povolená, farby aplikácie sa prispôsobia vybranému obrázku, ktorý upravujete</string>\n    <string name=\"language\">Jazyk</string>\n    <string name=\"amoled_mode\">Čierny tmavý režim</string>\n    <string name=\"amoled_mode_sub\">Ak je táto možnosť povolená, farba povrchov bude v nočnom režime nastavená na úplne tmavú</string>\n    <string name=\"color_scheme\">Farebná schéma</string>\n    <string name=\"color_red\">Červená</string>\n    <string name=\"color_green\">Zelená</string>\n    <string name=\"color_blue\">Modrá</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Vložte platný kód farby aRGB</string>\n    <string name=\"clipboard_paste_invalid_empty\">Nič na vloženie</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Farebnú schému aplikácie nie je možné zmeniť, keď sú zapnuté dynamické farby</string>\n    <string name=\"pick_accent_color\">Téma aplikácie bude založená na zvolenej farbe</string>\n    <string name=\"about_app\">O aplikácii</string>\n    <string name=\"no_updates\">Nenašli sa žiadne aktualizácie</string>\n    <string name=\"issue_tracker\">Sledovanie problémov</string>\n    <string name=\"issue_tracker_sub\">Sem posielajte hlásenia o chybách a návrhy na nové funkcie</string>\n    <string name=\"help_translate\">Pomôžte s prekladom</string>\n    <string name=\"help_translate_sub\">Opravte chyby v preklade alebo lokalizujte projekt do iných jazykov</string>\n    <string name=\"nothing_found_by_search\">Podľa vášho dotazu sa nič nenašlo</string>\n    <string name=\"search_here\">Hľadať tu</string>\n    <string name=\"dynamic_colors_sub\">Ak je táto možnosť povolená, farby aplikácie sa prispôsobia farbám tapety</string>\n    <string name=\"failed_to_save\">Nepodarilo sa uložiť %d obrázok (obrázkov)</string>\n    <string name=\"primary\">Primárne</string>\n    <string name=\"tertiary\">Terciárne</string>\n    <string name=\"secondary\">Sekundárne</string>\n    <string name=\"border_thickness\">Hrúbka okraja</string>\n    <string name=\"surface\">Povrch</string>\n    <string name=\"values\">Hodnoty</string>\n    <string name=\"add\">Pridať</string>\n    <string name=\"permission\">Povolenie</string>\n    <string name=\"grant\">Grant</string>\n    <string name=\"permission_sub\">Aplikácia potrebuje prístup k vášmu úložisku na ukladanie obrázkov, je to nevyhnutné. Prosím, udeľte povolenie v nasledujúcom dialógovom okne.</string>\n    <string name=\"grant_permission_manual\">Aplikácia potrebuje toto povolenie na svoju funkčnosť, prosím, udeľte ho manuálne</string>\n    <string name=\"external_storage\">Externé úložisko</string>\n    <string name=\"monet_colors\">Monet farby</string>\n    <string name=\"donation_sub\">Táto aplikácia je úplne zadarmo, ale ak chcete podporiť vývoj projektu, môžete kliknúť sem</string>\n    <string name=\"fab_alignment\">Zarovnanie plávajúceho akčného tlačidla</string>\n    <string name=\"check_updates\">Kontrola aktualizácií</string>\n    <string name=\"check_updates_sub\">Ak je táto možnosť povolená, pri spustení aplikácie sa zobrazí dialógové okno s aktualizáciou</string>\n    <string name=\"share\">Zdieľať</string>\n    <string name=\"prefix\">Predpona</string>\n    <string name=\"filename\">Názov súboru</string>\n    <string name=\"brightness\">Jas</string>\n    <string name=\"exposure\">Expozícia</string>\n    <string name=\"white_balance\">vyváženie bielej</string>\n    <string name=\"temperature\">Teplota</string>\n    <string name=\"tint\">Odtieň</string>\n    <string name=\"monochrome\">Monochromatický</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"effect\">Effect</string>\n    <string name=\"distance\">Vzdialenosť</string>\n    <string name=\"vibrance\">Vibrancia</string>\n    <string name=\"black_and_white\">Čierna a biela</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">Medzery</string>\n    <string name=\"line_width\">Šírka čiary</string>\n    <string name=\"sobel_edge\">Okraj Sobel</string>\n    <string name=\"cga_colorspace\">farebný priestor GCA</string>\n    <string name=\"gaussian_blur\">Gaussovské rozostrenie</string>\n    <string name=\"box_blur\">Box rozostrenie</string>\n    <string name=\"emboss\">Embosovať</string>\n    <string name=\"delete_exif\">Odstrániť EXIF</string>\n    <string name=\"filter\">Filter</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"highlights\">Zvýraznenie</string>\n    <string name=\"shadows\">Tiene</string>\n    <string name=\"haze\">Haze</string>\n    <string name=\"blur\">Rozmazať</string>\n    <string name=\"limits_resize\">Zmeniť veľkosť s obmedzeniami</string>\n    <string name=\"limits_resize_sub\">Zmeňte veľkosť vybraných obrázkov na danú šírku a výšku pri zachovaní pomeru strán</string>\n    <string name=\"sketch\">Skica</string>\n    <string name=\"threshold\">Prah</string>\n    <string name=\"non_maximum_suppression\">Nie maximálne potlačenie</string>\n    <string name=\"weak_pixel_inclusion\">Slabé zahrnutie pixelov</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Vyberte, ktoré emotikony sa zobrazia na hlavnej obrazovke</string>\n    <string name=\"stack_blur\">Rozmazanie zásobníka</string>\n    <string name=\"convolution3x3\">Konvolúcia 3x3</string>\n    <string name=\"rgb_filter\">RGB filter</string>\n    <string name=\"false_color\">Falošná farba</string>\n    <string name=\"first_color\">Prvá farba</string>\n    <string name=\"second_color\">Druhá farba</string>\n    <string name=\"fast_blur\">Rýchle rozostrenie</string>\n    <string name=\"blur_size\">Veľkosť rozmazania</string>\n    <string name=\"blur_center_x\">Rozmazať stred x</string>\n    <string name=\"blur_center_y\">Rozmazať stred y</string>\n    <string name=\"luminance_threshold\">Prahová hodnota jasu</string>\n    <string name=\"bilaterial_blur\">Obojstranné rozostrenie</string>\n    <string name=\"add_file_size\">Pridajte veľkosť súboru</string>\n    <string name=\"add_file_size_sub\">Ak je povolené, pridá k názvu výstupného súboru šírku a výšku uloženého obrázka</string>\n    <string name=\"delete_exif_sub\">Odstráňte metadáta EXIF z ľubovoľného páru obrázkov</string>\n    <string name=\"file_explorer_picker_sub\">Použite zámer GetContent na výber obrázka, funguje všade, ale môže mať problémy s prijímaním vybratých obrázkov na niektorých zariadeniach, nie je to moja chyba</string>\n    <string name=\"options_arrangement\">Usporiadanie možností</string>\n    <string name=\"edit\">Upraviť</string>\n    <string name=\"order\">objednať</string>\n    <string name=\"order_sub\">Určuje poradie nástrojov na hlavnej obrazovke</string>\n    <string name=\"sequence_num\">poradové číslo</string>\n    <string name=\"original_filename\">pôvodný názov súboru</string>\n    <string name=\"replace_sequence_number_sub\">Ak je povolené, nahradí štandardnú časovú pečiatku poradovým číslom obrázka, ak používate dávkové spracovanie</string>\n    <string name=\"load_image_from_net_sub\">Načítajte ľubovoľný obrázok z internetu, zobrazte jeho ukážku, priblížte ho a ak chcete, uložte ho alebo upravte</string>\n    <string name=\"image_link\">Odkaz na obrázok</string>\n    <string name=\"fill\">Vyplňte</string>\n    <string name=\"fit\">Fit</string>\n    <string name=\"flexible_description\">Zmení veľkosť obrázkov na obrázky s dlhou stranou danou parametrom Width alebo Height, všetky výpočty veľkosti sa vykonajú po uložení - zachováva pomer strán</string>\n    <string name=\"contrast\">Kontrast</string>\n    <string name=\"hue\">Hue</string>\n    <string name=\"saturation\">Sýtosť</string>\n    <string name=\"add_filter\">Pridajte filter</string>\n    <string name=\"filter_sub\">Na dané obrázky použite ľubovoľný reťazec filtrov</string>\n    <string name=\"filters\">Filtre</string>\n    <string name=\"light_aka_illumination\">Svetlo</string>\n    <string name=\"color_filter\">Farebný filter</string>\n    <string name=\"highlights_shadows\">Svetlá a tiene</string>\n    <string name=\"slope\">Svah</string>\n    <string name=\"sharpen\">Zostriť</string>\n    <string name=\"sepia\">Sépia</string>\n    <string name=\"negative\">Negatívne</string>\n    <string name=\"solarize\">Solarizovať</string>\n    <string name=\"halftone\">Poltón</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Ďialničná známka</string>\n    <string name=\"start\">Štart</string>\n    <string name=\"end\">Koniec</string>\n    <string name=\"kuwahara\">Kuwaharské vyhladenie</string>\n    <string name=\"radius\">Polomer</string>\n    <string name=\"scale\">Mierka</string>\n    <string name=\"distortion\">Skreslenie</string>\n    <string name=\"angle\">Uhol</string>\n    <string name=\"swirl\">Krúživým pohybom</string>\n    <string name=\"bulge\">Vydutie</string>\n    <string name=\"dilation\">Rozšírenie</string>\n    <string name=\"sphere_refraction\">Sférický lom</string>\n    <string name=\"refractive_index\">Index lomu</string>\n    <string name=\"glass_sphere_refraction\">Lom sklenenej gule</string>\n    <string name=\"color_matrix\">Farebná matrica</string>\n    <string name=\"opacity\">Nepriehľadnosť</string>\n    <string name=\"quantizationLevels\">Úrovne kvantovania</string>\n    <string name=\"smooth_toon\">Hladký toon</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterizovať</string>\n    <string name=\"lookup\">Vyhľadať</string>\n    <string name=\"reorder\">Zmeniť poradie</string>\n    <string name=\"zoom_blur\">Zoom rozostrenie</string>\n    <string name=\"color_balance\">Vyváženie farieb</string>\n    <string name=\"image_preview\">Ukážka obrázka</string>\n    <string name=\"image_preview_sub\">Ukážka akéhokoľvek typu obrázkov: GIF, SVG atď</string>\n    <string name=\"photo_picker_sub\">Moderný nástroj na výber fotografií pre Android, ktorý sa zobrazuje v spodnej časti obrazovky, môže fungovať iba v systéme Android 12+ a má tiež problémy s prijímaním metadát EXIF</string>\n    <string name=\"image_source\">Zdroj obrázka</string>\n    <string name=\"photo_picker\">Výber fotografií</string>\n    <string name=\"gallery_picker\">Galéria</string>\n    <string name=\"file_explorer_picker\">Prieskumník súborov</string>\n    <string name=\"gallery_picker_sub\">Jednoduchý výber obrázkov galérie, bude fungovať, iba ak máte túto aplikáciu</string>\n    <string name=\"load_image_from_net\">Načítať obrázok z internetu</string>\n    <string name=\"no_image\">Žiadny obrázok</string>\n    <string name=\"explicit_description\">Vynúti každý obrázok na obrázok daný parametrom Šírka a Výška – môže sa zmeniť pomer strán</string>\n    <string name=\"content_scale\">Obsahová mierka</string>\n    <string name=\"emojis_count\">Počet emodži</string>\n    <string name=\"add_original_filename\">Pridajte pôvodný názov súboru</string>\n    <string name=\"add_original_filename_sub\">Ak je povolené, pridá pôvodný názov súboru do názvu výstupného obrázka</string>\n    <string name=\"filename_not_work_with_photopicker\">Pridanie pôvodného názvu súboru nefunguje, ak je vybratý zdroj obrázka na výber fotografií</string>\n    <string name=\"replace_sequence_number\">Nahraďte poradové číslo</string>\n    <string name=\"draw_on_image\">Nakreslite na obrázok</string>\n    <string name=\"file_size\">Veľkosť súboru</string>\n    <string name=\"image_size_warning\">Pokus o uloženie obrázka so zadanou šírkou a výškou môže spôsobiť chybu nedostatku pamäte. Robíte to na vlastné riziko</string>\n    <string name=\"fallback_option\">Záložná možnosť</string>\n    <string name=\"skip\">Preskočiť</string>\n    <string name=\"warning_bytes\">Ukladanie v režime %1$s môže byť nestabilné, pretože ide o bezstratový formát</string>\n    <string name=\"activate_files\">Zakázali ste aplikáciu Súbory, aktivujte ju, aby ste mohli používať túto funkciu</string>\n    <string name=\"draw\">Kresliť</string>\n    <string name=\"draw_sub\">Nakreslite obrázok ako v skicári alebo nakreslite samotné pozadie</string>\n    <string name=\"draw_on_image_sub\">Vyberte si obrázok a niečo naň nakreslite</string>\n    <string name=\"background_color\">Farba pozadia</string>\n    <string name=\"decrypt\">Dešifrovať</string>\n    <string name=\"key\">kľúč</string>\n    <string name=\"store_file_desc\">Uložte tento súbor na svoje zariadenie alebo ho pomocou akcie zdieľania umiestnite kamkoľvek chcete</string>\n    <string name=\"features_sub\">Šifrovanie súborov na základe hesla. Pokračujúce súbory môžu byť uložené vo vybranom adresári alebo zdieľané. Dešifrované súbory je možné otvárať aj priamo.</string>\n    <string name=\"file_size_sub\">Maximálna veľkosť súboru je obmedzená operačným systémom Android a dostupnou pamäťou, čo samozrejme závisí od vášho zariadenia. \\nPoznámka: pamäť nie je úložisko.</string>\n    <string name=\"cache_size\">Veľkosť vyrovnávacej pamäte</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"found_s\">Nájdené %1$s</string>\n    <string name=\"auto_cache_clearing\">Automatické vymazanie vyrovnávacej pamäte</string>\n    <string name=\"auto_cache_clearing_sub\">Ak je povolená, vyrovnávacia pamäť aplikácie sa vymaže pri spustení aplikácie</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Nie je možné zmeniť usporiadanie, kým je povolené zoskupovanie možností</string>\n    <string name=\"edit_screenshot\">Upravte snímku obrazovky</string>\n    <string name=\"secondary_customization\">Sekundárne prispôsobenie</string>\n    <string name=\"screenshot\">Snímka obrazovky</string>\n    <string name=\"invalid_password_or_not_encrypted\">Neplatné heslo alebo zvolený súbor nie je zašifrovaný</string>\n    <string name=\"encrypt\">Šifrovať</string>\n    <string name=\"features\">Vlastnosti</string>\n    <string name=\"draw_on_background\">Kreslenie na pozadí</string>\n    <string name=\"draw_on_background_sub\">Vyberte farbu pozadia a nakreslite na ňu</string>\n    <string name=\"pick_file_to_start\">Začnite výberom súboru</string>\n    <string name=\"encryption\">Šifrovanie</string>\n    <string name=\"compatibility_sub\">Upozorňujeme, že kompatibilita s iným softvérom alebo službami na šifrovanie súborov nie je zaručená. Príčinou nekompatibility môže byť mierne odlišné spracovanie kľúča alebo konfigurácia šifry.</string>\n    <string name=\"copy\">Kopírovať</string>\n    <string name=\"paint_color\">Farba laku</string>\n    <string name=\"paint_alpha\">Farba alfa</string>\n    <string name=\"cipher\">Šifra</string>\n    <string name=\"cipher_sub\">Šifrovanie a dešifrovanie akéhokoľvek súboru (nielen obrázka) na základe rôznych dostupných šifrovacích algoritmov</string>\n    <string name=\"pick_file\">Vyberte súbor</string>\n    <string name=\"decryption\">Dešifrovanie</string>\n    <string name=\"implementation\">Implementácia</string>\n    <string name=\"compatibility\">Kompatibilita</string>\n    <string name=\"implementation_sub\">AES-256, režim GCM, bez vypĺňania (paddingu), predvolene 12-bajtové náhodné IV. Môžete si vybrať požadovaný algoritmus. Kľúče sa používajú ako 256-bitové SHA-3 hashe</string>\n    <string name=\"file_proceed\">Súbor spracovaný</string>\n    <string name=\"tools\">Nástroje</string>\n    <string name=\"group_options_by_type\">Zoskupte možnosti podľa typu</string>\n    <string name=\"group_options_by_type_sub\">Možnosti skupín na hlavnej obrazovke ich typu namiesto vlastného usporiadania zoznamu</string>\n    <string name=\"create\">Vytvorte</string>\n    <string name=\"email\">E-mail</string>\n    <string name=\"enhanced_pixelation\">Vylepšené pixelovanie</string>\n    <string name=\"stroke_pixelation\">Pixelizácia po ťahu</string>\n    <string name=\"enhanced_diamond_pixelation\">Vylepšená diamantová pixelizácia</string>\n    <string name=\"delete\">Vymazať</string>\n    <string name=\"crop_mask\">Maska strihu</string>\n    <string name=\"enhanced_glitch\">Vylepšená chyba</string>\n    <string name=\"channel_shift_y\">Posun kanála Y</string>\n    <string name=\"side\">Bočná strana</string>\n    <string name=\"bottom\">Dole</string>\n    <string name=\"nature_and_animals\">Príroda a zvieratá</string>\n    <string name=\"food_and_drink\">Jedlo a nápoje</string>\n    <string name=\"blur_radius\">Polomer rozostrenia</string>\n    <string name=\"background_remover_sub\">Odstráňte pozadie z obrázka kreslením alebo použite možnosť Auto.</string>\n    <string name=\"emotions\">Emócie</string>\n    <string name=\"updates\">Aktualizácie</string>\n    <string name=\"segmentation_mode_osd_only\">Iba orientácia a rozpoznávanie písma</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatická orientácia a rozpoznávanie písma</string>\n    <string name=\"segmentation_mode_auto_only\">Iba automaticky</string>\n    <string name=\"segmentation_mode_auto\">Auto</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Vertikálny text v jednom bloku</string>\n    <string name=\"segmentation_mode_circle_word\">Zakrúžkuj slovo</string>\n    <string name=\"segmentation_mode_single_char\">Jeden znak</string>\n    <string name=\"segmentation_mode_raw_line\">Surová linka</string>\n    <string name=\"glitch\">Chyba</string>\n    <string name=\"amount\">Suma</string>\n    <string name=\"seed\">Semená</string>\n    <string name=\"anaglyph\">Anaglyf</string>\n    <string name=\"noise\">Hluk</string>\n    <string name=\"pixel_sort\">Triedenie podľa pixelov</string>\n    <string name=\"shuffle\">Zamiešať</string>\n    <string name=\"delete_mask_warn\">Chystáte sa odstrániť vybranú masku filtra. Táto operácia nemôže byť vrátená späť</string>\n    <string name=\"delete_mask\">Odstrániť masku</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Odstrihnúť</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Prechod</string>\n    <string name=\"peak\">Vrchol</string>\n    <string name=\"color_anomaly\">Farebná anomália</string>\n    <string name=\"clipboard\">Schránka</string>\n    <string name=\"no_such_directory\">Nenašiel sa adresár „%1$s“, prešli sme na predvolený adresár. Uložte súbor prosím znovu.</string>\n    <string name=\"auto_pin\">Automatický pin</string>\n    <string name=\"auto_pin_sub\">Ak je táto funkcia zapnutá, uložený obrázok sa automaticky pridá do schránky</string>\n    <string name=\"vibration\">Vibrácie</string>\n    <string name=\"overwrite_files\">Prepísať súbory</string>\n    <string name=\"overwrite_files_sub\">Pôvodný súbor bude nahradený novým namiesto uloženia do vybranej zložky; táto možnosť vyžaduje, aby zdrojom obrázku bol „Explorer“ alebo „GetContent“; pri zapnutí tejto funkcie sa nastavenie vykoná automaticky</string>\n    <string name=\"empty\">Prázdny</string>\n    <string name=\"suffix\">Prípona</string>\n    <string name=\"search_option\">Hľadať</string>\n    <string name=\"search_option_sub\">Umožňuje vyhľadávať vo všetkých dostupných nástrojoch na hlavnej obrazovke</string>\n    <string name=\"free\">Voľne</string>\n    <string name=\"images_overwritten\">Obrázky boli prepísané v pôvodnom umiestnení</string>\n    <string name=\"cannot_change_image_format\">Pri zapnutej možnosti prepisovania súborov nie je možné zmeniť formát obrázku</string>\n    <string name=\"emoji_as_color_scheme\">Emoji ako farebná schéma</string>\n    <string name=\"emoji_as_color_scheme_sub\">Používa základnú farbu emodži ako farebnú schému aplikácie namiesto ručne definovanej</string>\n    <string name=\"saved_to_without_filename\">Uložené do priečinka %1$s</string>\n    <string name=\"aspect_ratio\">Pomer strán</string>\n    <string name=\"image_crop_mask_sub\">Tento typ masky použite na vytvorenie masky z daného obrázku, pričom je potrebné mať na pamäti, že by mala mať alfa kanál</string>\n    <string name=\"backup_and_restore\">Zálohovanie a obnovenie</string>\n    <string name=\"backup\">Záloha</string>\n    <string name=\"delete_color_scheme_warn\">Chystáte sa odstrániť vybranú farebnú schému. Táto operácia nemôže byť vrátená späť.</string>\n    <string name=\"restore\">Obnoviť</string>\n    <string name=\"backup_sub\">Zálohujte nastavenia aplikácie do súboru</string>\n    <string name=\"restore_sub\">Obnoviť nastavenia aplikácie z predtým vytvoreného súboru</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Poškodený súbor alebo chýbajúca záloha</string>\n    <string name=\"contact_me\">Kontaktujte ma</string>\n    <string name=\"reset_settings_sub\">Týmto sa vaše nastavenia vrátia na predvolené hodnoty. Upozorňujeme, že bez vyššie spomenutého záložného súboru nie je možné túto akciu vrátiť späť.</string>\n    <string name=\"delete_color_scheme_title\">Vymazať schému</string>\n    <string name=\"font\">Písmo</string>\n    <string name=\"text\">Text</string>\n    <string name=\"font_scale\">Veľkosť písma</string>\n    <string name=\"defaultt\">Predvolené nastavenie</string>\n    <string name=\"using_large_fonts_warn\">Použitie veľkých škál písma môže spôsobiť chyby a problémy v používateľskom rozhraní, ktoré nebudú opravené. Používajte opatrne.</string>\n    <string name=\"alphabet_and_numbers\">Aa Áá Ää Bb Cc Čč Dd Ďď Ee Éé Ff Gg Hh Ii Íí Jj Kk Ll Ĺĺ Ľľ Mm Nn Ňň Oo Óó Ôô Pp Qq Rr Ŕŕ Ss Šš Tt Ťť Uu Úú Vv Ww Xx Yy Zz Žž 0123456789 !?</string>\n    <string name=\"objects\">Objekty</string>\n    <string name=\"symbols\">Symboly</string>\n    <string name=\"travels_and_places\">Cesty a miesta</string>\n    <string name=\"activities\">Aktivity</string>\n    <string name=\"background_remover\">Odstránenie pozadia</string>\n    <string name=\"trim_image\">Orezanie obrázku</string>\n    <string name=\"keep_exif_sub\">Pôvodné metadáta obrázku zostanú zachované</string>\n    <string name=\"trim_image_sub\">Transparentné priestory okolo obrázku budú orezané.</string>\n    <string name=\"auto_erase_background\">Automatické vymazanie pozadia</string>\n    <string name=\"restore_image\">Obnoviť obrázok</string>\n    <string name=\"erase_mode\">Režim vymazania</string>\n    <string name=\"erase_background\">Vymazať pozadie</string>\n    <string name=\"pipette\">Pipeta</string>\n    <string name=\"draw_mode\">Režim kreslenia</string>\n    <string name=\"create_issue\">Vytvoriť problém</string>\n    <string name=\"something_went_wrong_emphasis\">Ups… Niečo sa pokazilo. Môžete mi napísať pomocou nižšie uvedených možností a ja sa pokúsim nájsť riešenie</string>\n    <string name=\"resize_and_convert_sub\">Zmeňte veľkosť daných obrázkov alebo ich konvertujte do iných formátov. Ak vyberiete jeden obrázok, môžete tu tiež upravovať metadáta EXIF.</string>\n    <string name=\"max_colors_count\">Maximálny počet farieb</string>\n    <string name=\"analytics_sub\">Povoliť zbieranie anonymných štatistík o používaní aplikácie</string>\n    <string name=\"image_exif_warning\">V súčasnosti formát %1$s umožňuje čítať metadáta EXIF iba v systéme Android. Výstupný obrázok nebude mať po uložení žiadne metadáta.</string>\n    <string name=\"effort_sub\">Hodnota %1$s znamená rýchlu kompresiu, čo má za následok relatívne veľkú veľkosť súboru. %2$s znamená pomalšiu kompresiu, čo má za následok menší súbor.</string>\n    <string name=\"allow_betas\">Povoliť beta verzie</string>\n    <string name=\"scale_small_images_to_large_sub\">Malé obrázky budú zväčšené na najväčší obrázok v sekvencii, ak je táto funkcia povolená</string>\n    <string name=\"diamond_pixelation\">Diamantová pixelizácia</string>\n    <string name=\"circle_pixelation\">Kruhová pixelizácia</string>\n    <string name=\"target_color\">Cieľová farba</string>\n    <string name=\"color_to_remove\">Farba k vymazaniu</string>\n    <string name=\"remove_color\">Odstrániť farbu</string>\n    <string name=\"vibrant_sub\">Hlasná téma, farebnosť je maximálna pre primárnu paletu, zvýšená pre ostatné</string>\n    <string name=\"playful_scheme\">Hravá téma – odtieň zdrojovej farby sa v téme nezobrazuje.</string>\n    <string name=\"monochrome_sub\">Monochromatická téma, farby sú čisto čierne / biele / sivé</string>\n    <string name=\"content_sub\">Schéma, ktorá umiestňuje zdrojovú farbu do Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Schéma, ktorá je veľmi podobná schéme obsahu</string>\n    <string name=\"images_to_pdf\">Obrázky do PDF</string>\n    <string name=\"pdf_to_images_sub\">Previesť PDF na obrázky v danom výstupnom formáte</string>\n    <string name=\"images_to_pdf_sub\">Zabaliť obrázky do výstupného súboru PDF</string>\n    <string name=\"simple_variants\">Jednoduché varianty</string>\n    <string name=\"highlighter\">Zvýrazňovač</string>\n    <string name=\"neon\">Neón</string>\n    <string name=\"pen\">Pero</string>\n    <string name=\"privacy_blur\">Rozmazanie pre súkromie</string>\n    <string name=\"neon_sub\">Pridajte svojim kresbám žiarivý efekt</string>\n    <string name=\"pen_sub\">Predvolené, najjednoduchšie – len farba</string>\n    <string name=\"pixelation_sub\">Podobné ako rozmazanie súkromia, ale namiesto rozmazania sa použije pixelizácia.</string>\n    <string name=\"auto_rotate_limits\">Automatické otáčanie</string>\n    <string name=\"auto_rotate_limits_sub\">Umožňuje použiť obmedzujúce pole pre orientáciu obrázku.</string>\n    <string name=\"double_arrow\">Dvojitá šípka</string>\n    <string name=\"line_arrow\">Čiara Šípka</string>\n    <string name=\"arrow\">Šípka</string>\n    <string name=\"line_arrow_sub\">Nakreslí šípku smerujúcu od počiatočného bodu k koncovému bodu ako čiaru.</string>\n    <string name=\"arrow_sub\">Nakreslí ukazovaciu šípku z danej cesty</string>\n    <string name=\"double_line_arrow_sub\">Nakreslí dvojitú šípku od počiatočného bodu do koncového bodu ako čiaru.</string>\n    <string name=\"double_arrow_sub\">Nakreslí dvojitú šípku z danej cesty</string>\n    <string name=\"outlined_oval_sub\">Nakreslí ohraničený ovál od počiatočného bodu po koncový bod</string>\n    <string name=\"outlined_rect_sub\">Nakreslí obdĺžnik s ohraničením od počiatočného bodu po koncový bod</string>\n    <string name=\"vibration_strength\">Intenzita vibrácií</string>\n    <string name=\"overwrite_file_requirements\">Ak chcete prepísať súbory, musíte použiť zdroj obrázkov „Explorer“. Skúste obrázky vybrať znovu – zdroj obrázkov sme zmenili na požadovaný.</string>\n    <string name=\"bicubic\">Bikubický</string>\n    <string name=\"bilinear_sub\">Lineárna (alebo v dvoch rozmeroch bilineárna) interpolácia sa zvyčajne hodí na zmenu veľkosti obrázku, spôsobuje však neželané zmäkčenie detailov a výsledok môže byť stále trochu zubatý</string>\n    <string name=\"bicubic_sub\">Medzi lepšie metódy škálovania patria Lanczosovo prevzorkovanie a filtre Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Jedným z jednoduchších spôsobov, ako zväčšiť obrázok, je nahradiť každý pixel viacerými pixelmi rovnakej farby</string>\n    <string name=\"basic_sub\">Najjednoduchší režim zmeny mierky v systéme Android, ktorý sa používa takmer vo všetkých aplikáciách</string>\n    <string name=\"catmull_sub\">Metóda plynulej interpolácie a prepočítania súboru kontrolných bodov, bežne používaná v počítačovej grafike na vytváranie plynulých kriviek</string>\n    <string name=\"hann_sub\">Funkcia okienkovania sa často používa pri spracovaní signálov na minimalizáciu spektrálneho úniku a zvýšenie presnosti frekvenčnej analýzy prostredníctvom zaoblenia okrajov signálu</string>\n    <string name=\"hermite_sub\">Matematická interpolačná technika, ktorá využíva hodnoty a derivácie v koncových bodoch úseku krivky na vytvorenie hladkej a spojitej krivky</string>\n    <string name=\"lanczos_sub\">Metóda prevzorkovania, ktorá zachováva vysokú kvalitu interpolácie pomocou aplikácie váhovej sincovej funkcie na hodnoty pixelov</string>\n    <string name=\"mitchell_sub\">Metóda prevzorkovania, ktorá využíva konvolučný filter s nastaviteľnými parametrami na dosiahnutie rovnováhy medzi ostrosťou a vyhladzovaním v zmenšenom obrázku</string>\n    <string name=\"spline_sub\">Využívajú po častiach definované polynómové funkcie na plynulú interpoláciu a aproximáciu krivky alebo plochy, čím poskytujú flexibilné a spojité znázornenie tvaru</string>\n    <string name=\"segmentation_mode_single_column\">Jeden stĺpec</string>\n    <string name=\"segmentation_mode_single_block\">Jeden blok</string>\n    <string name=\"segmentation_mode_single_line\">Jeden riadok</string>\n    <string name=\"segmentation_mode_single_word\">Jedno slovo</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Rozptýlený text – rozpoznávanie orientácie a písma</string>\n    <string name=\"segmentation_mode_sparse_text\">Riedky text</string>\n    <string name=\"delete_language_sub\">Chcete odstrániť trénovacie údaje OCR pre jazyk „%1$s“ pre všetky typy rozpoznávania, alebo len pre vybraný typ (%2$s)?</string>\n    <string name=\"all\">Všetko</string>\n    <string name=\"repeat_watermark\">Opakovať vodoznak</string>\n    <string name=\"repeat_watermark_sub\">Vzor sa opakuje po celom obrázku namiesto toho, aby sa zobrazoval len raz na určenej pozícii</string>\n    <string name=\"offset_x\">Posun X</string>\n    <string name=\"offset_y\">Posun Y</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Two Row Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"left_to_right_dithering\">Dithering zľava doprava</string>\n    <string name=\"random_dithering\">Náhodné rozmazávanie</string>\n    <string name=\"channel_shift_x\">Posun kanála X</string>\n    <string name=\"corruption_size\">Veľkosť korupcie</string>\n    <string name=\"corruption_shift_x\">Korupčný posun X</string>\n    <string name=\"corruption_shift_y\">Posun korupcie Y</string>\n    <string name=\"tent_blur\">Rozmazanie stanu</string>\n    <string name=\"side_fade\">Prechod stránok</string>\n    <string name=\"top\">Hore</string>\n    <string name=\"strength\">Sila</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Nočné videnie</string>\n    <string name=\"warm\">Teplý</string>\n    <string name=\"cool\">Studený</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"pink_dream\">Ružový sen</string>\n    <string name=\"golden_hour\">Zlatá hodinka</string>\n    <string name=\"hot_summer\">Horúce leto</string>\n    <string name=\"purple_mist\">Fialová hmla</string>\n    <string name=\"sunrise\">Východ slnka</string>\n    <string name=\"colorful_swirl\">Farebný vír</string>\n    <string name=\"soft_spring_light\">Jemné jarné svetlo</string>\n    <string name=\"autumn_tones\">Jesenné odtiene</string>\n    <string name=\"lavender_dream\">Levanduľový sen</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Limonádové svetlo</string>\n    <string name=\"electric_gradient\">Elektrický gradient</string>\n    <string name=\"deep_purple\">Deep Purple</string>\n    <string name=\"space_portal\">Vesmírny portál</string>\n    <string name=\"red_swirl\">Červený vír</string>\n    <string name=\"digital_code\">Digitálny kód</string>\n    <string name=\"randomize_filename_sub\">Ak je táto funkcia povolená, názov výstupného súboru bude úplne náhodný.</string>\n    <string name=\"saved_to\">Uložené do priečinka %1$s s názvom %2$s</string>\n    <string name=\"enable_emoji\">Povoliť emoji</string>\n    <string name=\"restore_background\">Obnoviť pozadie</string>\n    <string name=\"resize_and_convert\">Zmena veľkosti a konverzia</string>\n    <string name=\"crashlytics_sub\">Toto umožňuje aplikácii automaticky zbierať hlásenia o zlyhaniach</string>\n    <string name=\"analytics\">Analytika</string>\n    <string name=\"effort\">Úsilie</string>\n    <string name=\"brush_softness\">Mäkkosť štetca</string>\n    <string name=\"crop_description\">Obrázky budú orezané na stred na zadanú veľkosť. Plátno bude rozšírené o zadanú farbu pozadia, ak je obrázok menší ako zadané rozmery.</string>\n    <string name=\"donation\">Darcovstvo</string>\n    <string name=\"pixelation\">Pixelizácia</string>\n    <string name=\"enhanced_circle_pixelation\">Vylepšené kruhové rozostrenie</string>\n    <string name=\"replace_color\">Nahradiť farbu</string>\n    <string name=\"tolerance\">Tolerancia</string>\n    <string name=\"color_to_replace\">Farba k výmene</string>\n    <string name=\"recode\">Prekódovať</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anizotropná difúzia</string>\n    <string name=\"diffusion\">Difúzia</string>\n    <string name=\"conduction\">Vedenie</string>\n    <string name=\"horizontal_wind_stagger\">Horizontálne striedanie pri vetre</string>\n    <string name=\"fast_bilaterial_blur\">Rýchle obojstranné rozmazanie</string>\n    <string name=\"poisson_blur\">Poissonovo rozmazanie</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmické mapovanie tónov</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES filmové mapovanie tónov</string>\n    <string name=\"crystallize\">Kryštalizovať</string>\n    <string name=\"stroke_color\">Farba ťahu</string>\n    <string name=\"fractal_glass\">Fraktálne sklo</string>\n    <string name=\"amplitude\">Amplitúda</string>\n    <string name=\"marble\">Mramor</string>\n    <string name=\"turbulence\">Turbulencia</string>\n    <string name=\"oil\">Olej</string>\n    <string name=\"water_effect\">Vodný efekt</string>\n    <string name=\"just_size\">Veľkosť</string>\n    <string name=\"frequency_x\">Frekvencia X</string>\n    <string name=\"frequency_y\">Frekvencia Y</string>\n    <string name=\"amplitude_x\">Amplitúda X</string>\n    <string name=\"amplitude_y\">Amplitúda Y</string>\n    <string name=\"perlin_distortion\">Perlinovo skreslenie</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable – filmové tónové mapovanie</string>\n    <string name=\"heji_burgess_tone_mapping\">Tónové mapovanie podľa Hejiho-Burgessa</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill – mapovanie tónov</string>\n    <string name=\"current\">Aktuálny</string>\n    <string name=\"full_filter\">Úplný filter</string>\n    <string name=\"start_position\">Štart</string>\n    <string name=\"center_position\">Uprostred</string>\n    <string name=\"end_position\">Koniec</string>\n    <string name=\"full_filter_sub\">Použite ľubovoľné reťazce filtrov na dané obrázky alebo jeden obrázok</string>\n    <string name=\"pdf_tools_sub\">Práca s PDF súbormi: náhľad, konverzia na súbor obrázkov alebo vytvorenie obrázku z daných obrázkov</string>\n    <string name=\"preview_pdf\">Náhľad PDF</string>\n    <string name=\"pdf_to_images\">PDF do obrázkov</string>\n    <string name=\"preview_pdf_sub\">Jednoduchý náhľad PDF</string>\n    <string name=\"gradient_maker\">Nástroj na vytváranie prechodov</string>\n    <string name=\"gradient_maker_sub\">Vytvorte prechod s danou výstupnou veľkosťou s vlastnými farbami a typom vzhľadu</string>\n    <string name=\"speed\">Rýchlosť</string>\n    <string name=\"dehaze\">Odstrániť hmlu</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"pdf_tools\">PDF nástroje</string>\n    <string name=\"rate_app\">Ohodnoťte aplikáciu</string>\n    <string name=\"rate\">Hodnotiť</string>\n    <string name=\"rate_app_sub\">Táto aplikácia je úplne zadarmo. Ak chcete, aby sa ďalej rozvíjala, označte projekt na Githubu hviezdičkou 😄</string>\n    <string name=\"color_matrix_4x4\">Farebná matica 4x4</string>\n    <string name=\"color_matrix_3x3\">Farebná matica 3x3</string>\n    <string name=\"simple_effects\">Jednoduché efekty</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomália</string>\n    <string name=\"deutaromaly\">Deuteranomália</string>\n    <string name=\"protonomaly\">Protanomália</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Achromatomaly</string>\n    <string name=\"achromatopsia\">Achromatopsia</string>\n    <string name=\"gradient_type_linear\">Lineárny</string>\n    <string name=\"gradient_type_radial\">Radiálny</string>\n    <string name=\"gradient_type_sweep\">Zametanie</string>\n    <string name=\"gradient_type\">Typ gradientu</string>\n    <string name=\"center_x\">Stred X</string>\n    <string name=\"center_y\">Stred Y</string>\n    <string name=\"tile_mode\">Režim dlaždíc</string>\n    <string name=\"tile_mode_repeated\">Opakované</string>\n    <string name=\"tile_mode_mirror\">Zrkadlo</string>\n    <string name=\"tile_mode_clamp\">Svorka</string>\n    <string name=\"tile_mode_decal\">Nálepka</string>\n    <string name=\"color_stops\">Farebné prechody</string>\n    <string name=\"add_color\">Pridať farbu</string>\n    <string name=\"properties\">Vlastnosti</string>\n    <string name=\"lasso\">Laso</string>\n    <string name=\"lasso_sub\">Nakreslí uzavretú vyplnenú krivku podľa zadaného priebehu</string>\n    <string name=\"draw_path_mode\">Režim kreslenia cesty</string>\n    <string name=\"double_line_arrow\">Dvojitá čiara so šípkou</string>\n    <string name=\"free_drawing\">Voľné kreslenie</string>\n    <string name=\"line\">Čiara</string>\n    <string name=\"free_drawing_sub\">Nakreslí cestu ako vstupnú hodnotu</string>\n    <string name=\"line_sub\">Nakreslí cestu od počiatočného bodu do koncového bodu ako čiaru.</string>\n    <string name=\"outlined_oval\">Obrysovaný ovál</string>\n    <string name=\"outlined_rect\">Obrysovaný obdĺžnik</string>\n    <string name=\"oval\">Ovál</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Nakreslí obdĺžnik od počiatočného bodu po koncový bod</string>\n    <string name=\"oval_sub\">Nakreslí ovál od počiatočného bodu po koncový bod</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Kvantizér</string>\n    <string name=\"gray_scale\">Šedá stupnica</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falošný Floyd Steinberg Dithering</string>\n    <string name=\"simple_threshold_dithering\">Jednoduché prahové rozmazávanie</string>\n    <string name=\"tg_chat_sub\">Diskutujte o aplikácii a získajte spätnú väzbu od ostatných používateľov. Môžete tam tiež získať beta aktualizácie a zaujímavé informácie.</string>\n    <string name=\"settings_restored\">Nastavenia boli úspešne obnovené</string>\n    <string name=\"wait\">Počkajte</string>\n    <string name=\"saving_almost_complete\">Ukladanie je takmer dokončené. Ak teraz zrušíte, budete musieť ukladať znova.</string>\n    <string name=\"mask_color\">Farba masky</string>\n    <string name=\"mask_preview\">Náhľad masky</string>\n    <string name=\"mask_preview_sub\">Nakreslená maska filtra sa vykreslí, aby vám ukázala približný výsledok</string>\n    <string name=\"scale_mode\">Režim mierky</string>\n    <string name=\"bilinear\">Bilineárny</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Najbližší</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Základný</string>\n    <string name=\"default_value\">Predvolená hodnota</string>\n    <string name=\"value_in_range\">Hodnota v rozsahu %1$s - %2$s</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Priestorová Sigma</string>\n    <string name=\"median_blur\">Stredné rozostrenie</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"only_clip\">Len klip</string>\n    <string name=\"only_clip_sub\">Uloženie do úložiska sa neuskutoční a systém sa pokúsi iba vložiť obrázok do schránky</string>\n    <string name=\"icon_shape_sub\">Pridá pod ikony kontajner s vybraným tvarom</string>\n    <string name=\"icon_shape\">Tvar ikony</string>\n    <string name=\"image_stitching\">Spojenie obrázkov</string>\n    <string name=\"image_stitching_sub\">Spojte dané obrázky, aby ste získali jeden veľký obrázok.</string>\n    <string name=\"presets_sub\" formatted=\"false\">Ak ste vybrali predvoľbu 125, obrázok sa uloží vo veľkosti 125 % pôvodného obrázka. Ak zvolíte predvoľbu 50, obrázok sa uloží s veľkosťou 50 %.</string>\n    <string name=\"brightness_enforcement\">Vynútenie jasu</string>\n    <string name=\"screen\">Obrazovka</string>\n    <string name=\"gradient_maker_type_image\">Prekrývanie s prechodom</string>\n    <string name=\"gradient_maker_type_image_sub\">Vytvorte ľubovoľný farebný prechod na vrchnej časti daných obrázkov</string>\n    <string name=\"transformations\">Premeny</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Vyfoťte sa fotoaparátom. Upozorňujeme, že z tohto zdroja je možné získať len jeden obrázok</string>\n    <string name=\"pick_at_least_two_images\">Vyberte aspoň 2 obrázky</string>\n    <string name=\"output_image_scale\">Mierka výstupného obrázku</string>\n    <string name=\"image_orientation\">Orientácia obrázku</string>\n    <string name=\"horizontal\">Vodorovne</string>\n    <string name=\"grain\">Obilie</string>\n    <string name=\"unsharp\">Neostrý</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Oranžová hmla</string>\n    <string name=\"spectral_fire\">Spektrálny oheň</string>\n    <string name=\"night_magic\">Nočná mágia</string>\n    <string name=\"fantasy_landscape\">Fantastická krajina</string>\n    <string name=\"color_explosion\">Farebná explózia</string>\n    <string name=\"caramel_darkness\">Karamelová temnota</string>\n    <string name=\"futuristic_gradient\">Futuristický prechod</string>\n    <string name=\"green_sun\">Zelené slnko</string>\n    <string name=\"rainbow_world\">Dúhový svet</string>\n    <string name=\"watermarking\">Vodoznaky</string>\n    <string name=\"watermarking_sub\">Obrázky na obálke s prispôsobiteľnými textovými/obrazovými vodoznakmi</string>\n    <string name=\"watermark_type\">Typ vodoznaku</string>\n    <string name=\"watermarking_image_sub\">Tento obrázok sa použije ako vzor pre vodotlač</string>\n    <string name=\"text_color\">Farba textu</string>\n    <string name=\"overlay_mode\">Režim prekrývania</string>\n    <string name=\"pixel_size\">Veľkosť pixelu</string>\n    <string name=\"lock_draw_orientation\">Uzamknúť orientáciu kreslenia</string>\n    <string name=\"lock_draw_orientation_sub\">Ak je táto funkcia povolená v režime kreslenia, obrazovka sa nebude otáčať</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"gif_tools\">Nástroje pre GIF</string>\n    <string name=\"gif_tools_sub\">Previesť obrázky do formátu GIF alebo extrahovať snímky z daného obrázku vo formáte GIF</string>\n    <string name=\"gif_type_to_image\">GIF k obrázkom</string>\n    <string name=\"gif_type_to_image_sub\">Previesť súbor GIF na súbor obrázkov</string>\n    <string name=\"gif_type_to_gif_sub\">Previesť skupinu obrázkov do súboru GIF</string>\n    <string name=\"gif_type_to_gif\">Obrázky do formátu GIF</string>\n    <string name=\"select_gif_image_to_start\">Vyberte obrázok vo formáte GIF a začnite</string>\n    <string name=\"use_size_of_first_frame\">Použiť veľkosť prvého snímku</string>\n    <string name=\"use_size_of_first_frame_sub\">Nahraďte zadanú veľkosť rozmermi prvého snímku</string>\n    <string name=\"repeat_count\">Počet opakovaní</string>\n    <string name=\"frame_delay\">Oneskorenie snímky</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Použiť Lasso</string>\n    <string name=\"use_lasso_sub\">Používa nástroj Lasso podobne ako v režime kreslenia na vymazávanie</string>\n    <string name=\"original_image_preview_alpha\">Náhľad pôvodného obrázka Alpha</string>\n    <string name=\"mask_filter\">Filter masky</string>\n    <string name=\"mask_filter_sub\">Použiť reťazce filtrov na dané maskované oblasti, každá maskovaná oblasť môže určiť vlastnú sadu filtrov.</string>\n    <string name=\"masks\">Masky</string>\n    <string name=\"add_mask\">Pridať masku</string>\n    <string name=\"random_emojis_sub\">Emoji na paneli aplikácií sa budú náhodne meniť</string>\n    <string name=\"random_emojis\">Náhodné emodži</string>\n    <string name=\"random_emojis_error\">Keď sú emodži vypnuté, nemôžete používať náhodné emodži</string>\n    <string name=\"emoji_selection_error\">Ak je zapnutá funkcia náhodného výberu emodži, nemôžete si vybrať konkrétne emodži</string>\n    <string name=\"check_for_updates\">Skontrolujte aktualizácie</string>\n    <string name=\"presets_sub_bytes\">Predvoľba tu určuje % výstupného súboru, t.j. ak vyberiete predvoľbu 50 pri 5 MB obrázku, po uložení dostanete obrázok s veľkosťou 2,5 MB</string>\n    <string name=\"randomize_filename\">Náhodné pomenovanie súboru</string>\n    <string name=\"tg_chat\">Telegramový chat</string>\n    <string name=\"allow_betas_sub\">Kontrola aktualizácií bude zahŕňať beta verzie aplikácií, ak je táto funkcia povolená</string>\n    <string name=\"draw_arrows\">Kresliť šípky</string>\n    <string name=\"old_tv\">Stará televízia</string>\n    <string name=\"shuffle_blur\">Náhodné rozmazanie</string>\n    <string name=\"recognize_text\">OCR (rozpoznávanie textu)</string>\n    <string name=\"recognize_text_sub\">Rozpoznávanie textu z daného obrázku podporuje viac ako 120 jazykov</string>\n    <string name=\"picture_has_no_text\">Na obrázku nie je žiadny text alebo aplikácia ho nenašla</string>\n    <string name=\"accuracy\">Presnosť: %1$s</string>\n    <string name=\"recognition_type\">Typ rozpoznania</string>\n    <string name=\"fast\">Rýchlo</string>\n    <string name=\"standard\">Štandardne</string>\n    <string name=\"best\">Najlepšie</string>\n    <string name=\"no_data\">Žiadne údaje</string>\n    <string name=\"download_description\">Aby aplikácia Tesseract OCR správne fungovala, je potrebné do vášho zariadenia stiahnuť ďalšie trénovacie dáta (%1$s).\\nChcete stiahnuť dáta %2$s?</string>\n    <string name=\"download\">Stiahnuť</string>\n    <string name=\"no_connection\">Nie je pripojenie, skontrolujte ho a skúste to znova, aby ste mohli stiahnuť modely vlakov</string>\n    <string name=\"downloaded_languages\">Stiahnuté jazyky</string>\n    <string name=\"available_languages\">Dostupné jazyky</string>\n    <string name=\"segmentation_mode\">Režim segmentácie</string>\n    <string name=\"restore_background_sub\">Štetec obnoví pozadie namiesto toho, aby ho vymazal</string>\n    <string name=\"horizontal_grid\">Vodorovná mriežka</string>\n    <string name=\"vertical_grid\">Vertikálna mriežka</string>\n    <string name=\"stitch_mode\">Režim stehu</string>\n    <string name=\"rows_count\">Počet riadkov</string>\n    <string name=\"columns_count\">Počet stĺpcov</string>\n    <string name=\"use_pixel_switch\">Použiť prepínač Pixel</string>\n    <string name=\"use_pixel_switch_sub\">Používa prepínač podobný tomu v telefóne Google Pixel</string>\n    <string name=\"slide\">Sklz</string>\n    <string name=\"side_by_side\">Vedľa seba</string>\n    <string name=\"toggle_tap\">Prepnúť klepnutím</string>\n    <string name=\"transparency\">Transparentnosť</string>\n    <string name=\"saved_to_original\">Súbor s názvom %1$s v pôvodnom umiestnení bol prepísaný</string>\n    <string name=\"magnifier\">Lupa</string>\n    <string name=\"magnifier_sub\">V režimoch kreslenia aktivuje lupu na špičke prsta, čím sa zlepšuje prístupnosť</string>\n    <string name=\"force_exif_widget_initial_value\">Vynútiť počiatočnú hodnotu</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Vynúti počiatočné zaškrtnutie widgetu exif</string>\n    <string name=\"allow_multiple_languages\">Povoliť viacero jazykov</string>\n    <string name=\"favorite\">Obľúbené</string>\n    <string name=\"no_favorite_filters\">Zatiaľ neboli pridané žiadne obľúbené filtre</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Využíva po častiach definované bikubické polynómové funkcie na plynulú interpoláciu a aproximáciu krivky alebo plochy, čo umožňuje flexibilné a spojité znázornenie tvaru</string>\n    <string name=\"native_stack_blur\">Pôvodné rozostrenie</string>\n    <string name=\"tilt_shift\">Zmena sklonu</string>\n    <string name=\"regular\">Pravidelný</string>\n    <string name=\"blur_edges\">Rozmazané okraje</string>\n    <string name=\"inverse_fill_type\">Inverzné vyplnenie</string>\n    <string name=\"inverse_fill_type_sub\">Ak je táto funkcia povolená, všetky nemaskované oblasti budú filtrované namiesto predvoleného správania</string>\n    <string name=\"confetti\">Konfety</string>\n    <string name=\"confetti_sub\">Pri ukladaní, zdieľaní a ďalších základných akciách sa zobrazí konfety</string>\n    <string name=\"secure_mode\">Zabezpečený režim</string>\n    <string name=\"secure_mode_sub\">Skryje obsah aplikácie v zozname nedávno použitých aplikácií. Nedá sa zachytiť ani nahrať.</string>\n    <string name=\"draw_arrows_sub\">Ak je táto funkcia povolená, kresliaca dráha bude znázornená ako smerová šípka</string>\n    <string name=\"vertical\">Vertikálne</string>\n    <string name=\"scale_small_images_to_large\">Zväčšovanie malých obrázkov na veľké</string>\n    <string name=\"images_order\">Poradie obrázkov</string>\n    <string name=\"blur_edges_sub\">Ak je táto funkcia povolená, nakreslí rozmazané okraje pod pôvodným obrázkom, aby vyplnila priestor okolo neho namiesto jednoliatej farby</string>\n    <string name=\"mask_indexed\">Maska %d</string>\n    <string name=\"palette_style\">Paleta štýlu</string>\n    <string name=\"tonal_spot\">Tónový bod</string>\n    <string name=\"neutral\">Neutrálny</string>\n    <string name=\"vibrant\">Živý</string>\n    <string name=\"expressive\">Výrazový</string>\n    <string name=\"rainbow\">Dúha</string>\n    <string name=\"fruit_salad\">Ovocný šalát</string>\n    <string name=\"fidelity\">Vernosť</string>\n    <string name=\"content\">Obsah</string>\n    <string name=\"tonal_spot_sub\">Predvolený štýl palety, umožňuje prispôsobiť všetky štyri farby, ostatné umožňujú nastaviť len kľúčovú farbu</string>\n    <string name=\"neutral_sub\">Štýl, ktorý je o niečo farebnejší ako monochromatický</string>\n    <string name=\"highlighter_sub\">Nakreslite polopriehľadné ostro zvýraznené cesty zvýrazňovača</string>\n    <string name=\"privacy_blur_sub\">Rozmazáva obraz pod nakreslenou cestou, aby zabezpečil všetko, čo chcete skryť.</string>\n    <string name=\"containers_shadow\">Kontajnery</string>\n    <string name=\"containers_shadow_sub\">Nakresliť tieň za kontajnery</string>\n    <string name=\"sliders_shadow\">Posuvníky</string>\n    <string name=\"switches_shadow\">Prepínače</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">Tlačidlá</string>\n    <string name=\"sliders_shadow_sub\">Nakreslí tieň za posuvníkmi</string>\n    <string name=\"switches_shadow_sub\">Nakreslí tieň za prepínačmi</string>\n    <string name=\"fabs_shadow_sub\">Nakreslí tieň za plávajúce akčné tlačidlá</string>\n    <string name=\"buttons_shadow_sub\">Nakreslí tieň za tlačidlami</string>\n    <string name=\"app_bars_shadow\">Lišty aplikácií</string>\n    <string name=\"app_bars_shadow_sub\">Nakreslí tieň za lištami aplikácií</string>\n    <string name=\"foss_update_checker_warning\">Tento nástroj na kontrolu aktualizácií sa pripojí k GitHubu, aby skontroloval, či je k dispozícii nová aktualizácia.</string>\n    <string name=\"attention\">Pozor</string>\n    <string name=\"fading_edges\">Vyblednuté okraje</string>\n    <string name=\"disabled\">Vypnuté</string>\n    <string name=\"both\">Oboje</string>\n    <string name=\"invert_colors\">Invertovať farby</string>\n    <string name=\"invert_colors_sub\">Ak je táto funkcia povolená, nahradí farby motívu negatívnymi farbami</string>\n    <string name=\"exit\">Ukončiť</string>\n    <string name=\"preview_closing\">Ak teraz opustíte náhľad, budete musieť obrázky pridať znova</string>\n    <string name=\"image_format\">Formát obrázku</string>\n    <string name=\"material_you_sub\">Vytvorí paletu \\\"Material You\\\" na základe obrázku</string>\n    <string name=\"dark_colors\">Tmavé farby</string>\n    <string name=\"dark_colors_sub\">Používa farebnú schému nočného režimu namiesto svetelného variantu</string>\n    <string name=\"copy_as_compose_code\">Kopírovať ako kód \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Rozostrenie Prsteňa</string>\n    <string name=\"cross_blur\">Krížové rozostrenie</string>\n    <string name=\"circle_blur\">Rozmazanie kruhu</string>\n    <string name=\"star_blur\">Rozmazanie hviezd</string>\n    <string name=\"linear_tilt_shift\">Lineárny posun sklonu</string>\n    <string name=\"tags_to_remove\">Značky na odstránenie</string>\n    <string name=\"apng_tools\">Nástroje APNG</string>\n    <string name=\"apng_tools_sub\">Preveďte obrázky na obrázok APNG alebo extrahujte snímky z daného obrázka APNG</string>\n    <string name=\"apng_type_to_image_sub\">Previesť súbor APNG na dávku obrázkov</string>\n    <string name=\"apng_type_to_apng_sub\">Preveďte dávku obrázkov do súboru APNG</string>\n    <string name=\"apng_type_to_apng\">Obrázky do APNG</string>\n    <string name=\"motion_blur\">Pohybový efekt</string>\n    <string name=\"apng_type_to_image\">APNG k obrázkom</string>\n    <string name=\"select_apng_image_to_start\">Začnite výberom obrázka APNG</string>\n    <string name=\"zip\">PSČ</string>\n    <string name=\"zip_sub\">Vytvorte súbor zip z daných súborov alebo obrázkov</string>\n    <string name=\"drag_handle_width\">Šírka rukoväte ťahania</string>\n    <string name=\"confetti_type\">Typ konfety</string>\n    <string name=\"festive\">Slávnostné</string>\n    <string name=\"jxl_tools\">JXL nástroje</string>\n    <string name=\"embedded_picker\">Vstavaný výberový nástroj</string>\n    <string name=\"fullscreen_settings\">Nastavenia na celú obrazovku</string>\n    <string name=\"apng_type_to_jxl_sub\">Konvertujte APNG obrázky na animované JXL obrázky</string>\n    <string name=\"sort_by_date_reversed\">Dátum (obrátené poradie)</string>\n    <string name=\"sort_by_date\">Dátum</string>\n    <string name=\"pick_multiple_media\">Vybrať viacero médií</string>\n    <string name=\"material_you_switch_sub\">Používa prepínač Material You založený na View, tento vyzerá lepšie ako ostatné a má pekné animácie.</string>\n    <string name=\"fast_gaussian_blur_3d\">Rýchle Gaussovo rozostrenie 3D</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"embedded_picker_sub\">Používa vlastný nástroj Image Toolbox na výber obrázkov namiesto preddefinovaných v systéme</string>\n    <string name=\"no_permissions\">Žiadne povolenia</string>\n    <string name=\"request\">Žiadosť</string>\n    <string name=\"auto_paste_sub\">Umožňuje aplikácii automaticky prilepiť údaje zo schránky, takže sa zobrazia na hlavnej obrazovke a budete ich môcť spracovať</string>\n    <string name=\"jxl_type_to_jxl_sub\">Konvertujte dávku obrázkov na JXL animáciu</string>\n    <string name=\"speed_sub\">Ovláda rýchlosť dekódovania výsledného obrázka, čo by malo pomôcť rýchlejšiemu otvoreniu výsledného obrázka. Hodnota %1$s znamená najpomalšie dekódovanie, zatiaľ čo %2$s je najrýchlejšie. Toto nastavenie môže zvýšiť veľkosť výstupného obrázka</string>\n    <string name=\"generate_previews_sub\">Umožňuje generovanie náhľadov, čo môže pomôcť predísť zlyhaniu na niektorých zariadeniach. Taktiež to deaktivuje niektoré editačné funkcie v rámci jednej možnosti úprav</string>\n    <string name=\"header_yesterday\">Včera</string>\n    <string name=\"try_again\">Skúste to znova</string>\n    <string name=\"compose_switch_sub\">Používa prepínač Material You z Jetpack Compose, no nie je taký pekný ako ten založený na View</string>\n    <string name=\"sort_by_name\">Názov</string>\n    <string name=\"channels_configuration\">Konfigurácia kanálov</string>\n    <string name=\"sort_by_name_reversed\">Názov (obrátené poradie)</string>\n    <string name=\"header_today\">Dnes</string>\n    <string name=\"pick_single_media\">Vybrať jedno médium</string>\n    <string name=\"pick\">Vybrať</string>\n    <string name=\"show_settings_in_landscape\">Zobraziť nastavenia v režime na šírku</string>\n    <string name=\"show_settings_in_landscape_sub\">Ak je toto vypnuté, v režime na šírku sa nastavenia otvoria cez tlačidlo v hornej lište aplikácie ako zvyčajne, namiesto toho, aby boli trvalo viditeľné</string>\n    <string name=\"fullscreen_settings_sub\">Povoľte túto možnosť a stránka nastavení sa bude vždy otvárať na celú obrazovku namiesto posuvného panela</string>\n    <string name=\"switch_type\">Typ prepínača</string>\n    <string name=\"compose\">Zostaviť</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Zmena veľkosti kotvy</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Plynule</string>\n    <string name=\"fluent_switch_sub\">Používa prepínač v štýle Windows 11 založený na dizajnovom systéme „Fluent“</string>\n    <string name=\"images_to_svg\">Obrázky na SVG</string>\n    <string name=\"cupertino_switch_sub\">Používa prepínač podobný iOS, založený na dizajnovom systéme Cupertino</string>\n    <string name=\"explode\">Explodovať</string>\n    <string name=\"rain\">Dážď</string>\n    <string name=\"corners\">Rohy</string>\n    <string name=\"jxl_tools_sub\">Vykonajte transkódovanie JXL ~ JPEG bez straty kvality alebo konvertujte GIF/APNG na JXL animáciu</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Vykonajte bezstratové transkódovanie z JXL do JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Vykonajte bezstratové transkódovanie z JPEG do JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL na JPEG</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG na JXL</string>\n    <string name=\"select_jxl_image_to_start\">Vyberte JXL obrázok na začiatok</string>\n    <string name=\"fast_gaussian_blur_2d\">Rýchle Gaussovo rozostrenie 2D</string>\n    <string name=\"fast_gaussian_blur_4d\">Rýchle Gaussovo rozostrenie 4D</string>\n    <string name=\"auto_paste\">Automatické prilepenie</string>\n    <string name=\"harmonization_color\">Harmonizácia farieb</string>\n    <string name=\"harmonization_level\">Úroveň harmonizácie</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Metóda prevzorkovania, ktorá zachováva vysokokvalitnú interpoláciu použitím Besselovej (jinc) funkcie na hodnoty pixelov</string>\n    <string name=\"gif_type_to_jxl\">GIF na JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Konvertujte GIF obrázky na animované JXL obrázky</string>\n    <string name=\"apng_type_to_jxl\">APNG na JXL</string>\n    <string name=\"jxl_type_to_images\">JXL na obrázky</string>\n    <string name=\"jxl_type_to_images_sub\">Konvertujte JXL animáciu na dávku obrázkov</string>\n    <string name=\"jxl_type_to_jxl\">Obrázky na JXL</string>\n    <string name=\"behavior\">Správanie</string>\n    <string name=\"skip_file_picking\">Preskočiť výber súboru</string>\n    <string name=\"skip_file_picking_sub\">Výber súboru sa zobrazí okamžite, ak je to na zvolenej obrazovke možné</string>\n    <string name=\"generate_previews\">Generovať náhľady</string>\n    <string name=\"lossy_compression\">Stratová kompresia</string>\n    <string name=\"lossy_compression_sub\">Používa stratovú kompresiu na zmenšenie veľkosti súboru namiesto bezstratovej</string>\n    <string name=\"compression_type\">Typ kompresie</string>\n    <string name=\"sorting\">Triedenie</string>\n    <string name=\"images_to_svg_sub\">Preveďte zadané obrázky na SVG obrázky</string>\n    <string name=\"use_sampled_palette\">Použiť vzorkovanú paletu</string>\n    <string name=\"use_sampled_palette_sub\">Ak je táto možnosť zapnutá, kvantizačná paleta bude vzorkovaná</string>\n    <string name=\"path_omit\">Vynechať cestu</string>\n    <string name=\"svg_warning\">Použitie tohto nástroja na trasovanie veľkých obrázkov bez zmenšenia sa neodporúča, môže to spôsobiť zlyhanie a predĺžiť čas spracovania</string>\n    <string name=\"downscale_image\">Zmenšiť obrázok</string>\n    <string name=\"min_color_ratio\">Minimálny pomer farieb</string>\n    <string name=\"lines_threshold\">Prahové hodnoty čiar</string>\n    <string name=\"quadratic_threshold\">Kvadratický prah</string>\n    <string name=\"coordinates_rounding_tolerance\">Tolerancia zaokrúhľovania súradníc</string>\n    <string name=\"path_scale\">Mierka cesty</string>\n    <string name=\"reset_properties\">Obnoviť vlastnosti</string>\n    <string name=\"reset_properties_sub\">Všetky vlastnosti sa nastavia na predvolené hodnoty. Upozorňujeme, že túto akciu nemožno vrátiť späť</string>\n    <string name=\"detailed\">Podrobné</string>\n    <string name=\"default_line_width\">Predvolená šírka čiary</string>\n    <string name=\"engine_mode\">Režim motora</string>\n    <string name=\"lstm_network\">LSTM sieť</string>\n    <string name=\"legacy\">Zastarané</string>\n    <string name=\"legacy_and_lstm\">Zastarané a LSTM</string>\n    <string name=\"convert\">Konvertovať</string>\n    <string name=\"convert_sub\">Konvertovať dávky obrázkov do zadaného formátu</string>\n    <string name=\"add_new_folder\">Pridať nový priečinok</string>\n    <string name=\"downscale_image_sub\">Obrázok bude pred spracovaním zmenšený na menšie rozmery, čo pomáha nástroju pracovať rýchlejšie a bezpečnejšie</string>\n    <string name=\"tag_bits_per_sample\">Bitov na vzorku</string>\n    <string name=\"tag_compression\">Kompresia</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrická interpretácia</string>\n    <string name=\"tag_samples_per_pixel\">Vzorky na pixel</string>\n    <string name=\"tag_planar_configuration\">Planárna konfigurácia</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Podvzorkovanie</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Polohovanie</string>\n    <string name=\"tag_x_resolution\">Rozlíšenie X</string>\n    <string name=\"tag_y_resolution\">Rozlíšenie Y</string>\n    <string name=\"tag_resolution_unit\">Jednotka rozlíšenia</string>\n    <string name=\"tag_strip_offsets\">Posuny pásma</string>\n    <string name=\"tag_transfer_function\">Prenosová funkcia</string>\n    <string name=\"tag_white_point\">Biely bod</string>\n    <string name=\"tag_datetime\">Dátum Čas</string>\n    <string name=\"tag_image_description\">Popis obrázku</string>\n    <string name=\"tag_make\">Vytvoriť</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Softvér</string>\n    <string name=\"tag_artist\">Autor</string>\n    <string name=\"tag_copyright\">Autorské práva</string>\n    <string name=\"tag_exif_version\">Verzia Exif</string>\n    <string name=\"tag_flashpix_version\">Verzia Flashpix</string>\n    <string name=\"tag_color_space\">Farebný priestor</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Rozmer Pixel X</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y Rozmer</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Komprimované bity na pixel</string>\n    <string name=\"tag_maker_note\">Poznámka výrobcu</string>\n    <string name=\"tag_user_comment\">Komentár používateľa</string>\n    <string name=\"tag_related_sound_file\">Súvisiaci zvukový súbor</string>\n    <string name=\"tag_datetime_original\">Dátum Čas Originál</string>\n    <string name=\"tag_datetime_digitized\">Dátum Čas Digitalizované</string>\n    <string name=\"tag_offset_time\">Časový posun</string>\n    <string name=\"tag_offset_time_original\">Časový posun Pôvodný</string>\n    <string name=\"tag_offset_time_digitized\">Časový posun digitalizovaný</string>\n    <string name=\"tag_subsec_time\">Sub Sec Čas</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Čas Pôvodný</string>\n    <string name=\"tag_subsec_time_digitized\">Sub Sec Time Digitalizovný</string>\n    <string name=\"tag_exposure_time\">Doba expozície</string>\n    <string name=\"tag_f_number\">Číslo F</string>\n    <string name=\"tag_exposure_program\">Program vystavenia</string>\n    <string name=\"tag_spectral_sensitivity\">Spektrálna citlivosť</string>\n    <string name=\"tag_photographic_sensitivity\">Fotografická citlivosť</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Typ citlivosti</string>\n    <string name=\"tag_standard_output_sensitivity\">Štandardná výstupná citlivosť</string>\n    <string name=\"tag_recommended_exposure_index\">Odporúčaný index expozície</string>\n    <string name=\"tag_iso_speed\">Rýchlosť ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO rýchlosť Latitude yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Rýchlosť ISO Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Hodnota rýchlosti uzávierky</string>\n    <string name=\"tag_aperture_value\">Hodnota clony</string>\n    <string name=\"tag_flash_energy\">Flash Energy</string>\n    <string name=\"tag_spatial_frequency_response\">Priestorová frekvenčná charakteristika</string>\n    <string name=\"tag_focal_plane_x_resolution\">Rozlíšenie v ohniskovej rovine X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Rozlíšenie v ohniskovej rovine Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Jednotka rozlíšenia ohniskovej roviny</string>\n    <string name=\"tag_subject_location\">Názov Umiestnenie</string>\n    <string name=\"tag_sensing_method\">Metóda snímania</string>\n    <string name=\"tag_file_source\">Zdroj súboru</string>\n    <string name=\"tag_cfa_pattern\">Vzor CFA</string>\n    <string name=\"tag_custom_rendered\">Vlastné vykresľovanie</string>\n    <string name=\"tag_exposure_mode\">Režim expozície</string>\n    <string name=\"tag_white_balance\">Vyváženie bielej</string>\n    <string name=\"tag_digital_zoom_ratio\">Pomer digitálneho zoomu</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Ohnisková vzdialenosť v 35 mm filme</string>\n    <string name=\"tag_scene_capture_type\">Typ zachytenia scény</string>\n    <string name=\"tag_gain_control\">Ovládanie zosilnenia</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"tag_saturation\">Sýtosť</string>\n    <string name=\"tag_sharpness\">Ostrosť</string>\n    <string name=\"tag_subject_distance_range\">Subjekt Vzdialenosť Rozsah</string>\n    <string name=\"tag_image_unique_id\">Jedinečné ID obrázku</string>\n    <string name=\"tag_camera_owner_name\">Meno vlastníka fotoaparátu</string>\n    <string name=\"tag_body_serial_number\">Sériové číslo tela</string>\n    <string name=\"tag_lens_specification\">Špecifikácia objektívu</string>\n    <string name=\"tag_lens_make\">Výrobca objektívu</string>\n    <string name=\"tag_lens_model\">Model objektívu</string>\n    <string name=\"tag_lens_serial_number\">Sériové číslo objektívu</string>\n    <string name=\"tag_gps_version_id\">ID verzie GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Referenčná šírka GPS</string>\n    <string name=\"tag_gps_latitude\">GPS zemepisná šírka</string>\n    <string name=\"tag_gps_longitude_ref\">Referenčná dĺžka GPS</string>\n    <string name=\"tag_gps_longitude\">GPS dĺžka</string>\n    <string name=\"tag_gps_altitude_ref\">GPS referenčná nadmorská výška</string>\n    <string name=\"tag_gps_altitude\">GPS Nadmorská výška</string>\n    <string name=\"tag_gps_timestamp\">Časová pečiatka GPS</string>\n    <string name=\"tag_gps_satellites\">GPS satelity</string>\n    <string name=\"tag_gps_status\">Stav GPS</string>\n    <string name=\"tag_gps_measure_mode\">Režim merania GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS referenčná rýchlosť</string>\n    <string name=\"tag_gps_speed\">Rýchlosť GPS</string>\n    <string name=\"tag_rows_per_strip\">Počet riadkov na pásik</string>\n    <string name=\"tag_strip_byte_counts\">Počet bajtov pásika</string>\n    <string name=\"tag_jpeg_interchange_format\">Výmenný formát JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Dĺžka výmenného formátu JPEG</string>\n    <string name=\"tag_primary_chromaticities\">Primárne chromatickosti</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr koeficienty</string>\n    <string name=\"tag_reference_black_white\">Referenčná čierna biela</string>\n    <string name=\"tag_brightness_value\">Hodnota jasu</string>\n    <string name=\"tag_exposure_bias_value\">Hodnota skreslenia expozície</string>\n    <string name=\"tag_max_aperture_value\">Maximálna hodnota clony</string>\n    <string name=\"tag_subject_distance\">Vzdialenosť predmetu</string>\n    <string name=\"tag_metering_mode\">Režim merania</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Predmetná oblasť</string>\n    <string name=\"tag_focal_length\">Ohnisková vzdialenosť</string>\n    <string name=\"tag_exposure_index\">Index expozície</string>\n    <string name=\"tag_device_setting_description\">Popis nastavenia zariadenia</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS stopa</string>\n    <string name=\"tag_gps_img_direction_ref\">Smer obrazu GPS Ref</string>\n    <string name=\"tag_gps_img_direction\">Smer obrazu GPS</string>\n    <string name=\"tag_gps_map_datum\">Dátum mapy GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Ref. zemepisná šírka cieľa GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Cieľová zemepisná šírka GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Ref. zemepisná dĺžka cieľa GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Cieľová dĺžka GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Cieľový smer GPS Ref</string>\n    <string name=\"tag_gps_dest_bearing\">Cieľový smer GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Cieľová vzdialenosť GPS Ref</string>\n    <string name=\"tag_gps_dest_distance\">Cieľová vzdialenosť GPS</string>\n    <string name=\"tag_gps_processing_method\">Metóda spracovania GPS</string>\n    <string name=\"tag_gps_area_information\">Informácie o oblasti GPS</string>\n    <string name=\"tag_gps_datestamp\">Dátumová pečiatka GPS</string>\n    <string name=\"tag_gps_differential\">GPS diferenciál</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H Positioning Error</string>\n    <string name=\"tag_interoperability_index\">Index interoperability</string>\n    <string name=\"tag_dng_version\">Verzia DNG</string>\n    <string name=\"tag_default_crop_size\">Predvolená veľkosť orezania</string>\n    <string name=\"tag_orf_preview_image_start\">Spustiť náhľad obrázka</string>\n    <string name=\"tag_orf_preview_image_length\">Dĺžka ukážkového obrázka</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect Frame</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Spodný okraj snímača</string>\n    <string name=\"tag_rw2_sensor_left_border\">Ľavý okraj snímača</string>\n    <string name=\"tag_rw2_sensor_right_border\">Pravý okraj snímača</string>\n    <string name=\"tag_rw2_sensor_top_border\">Horný okraj snímača</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Nakreslite text na cestu s daným písmom a farbou</string>\n    <string name=\"font_size\">Veľkosť písma</string>\n    <string name=\"watermark_size\">Veľkosť vodoznaku</string>\n    <string name=\"repeat_text\">Opakujte text</string>\n    <string name=\"repeat_text_sub\">Aktuálny text sa bude opakovať až do konca cesty namiesto jedného kreslenia</string>\n    <string name=\"dash_size\">Veľkosť pomlčky</string>\n    <string name=\"draw_mode_image_sub\">Pomocou vybratého obrázka ho nakreslite pozdĺž danej cesty</string>\n    <string name=\"draw_image_sub\">Tento obrázok sa použije ako opakovaný záznam nakreslenej cesty</string>\n    <string name=\"outlined_triangle_sub\">Nakreslí načrtnutý trojuholník z počiatočného bodu do koncového bodu</string>\n    <string name=\"triangle_sub\">Nakreslí načrtnutý trojuholník z počiatočného bodu do koncového bodu</string>\n    <string name=\"outlined_triangle\">Obrysový trojuholník</string>\n    <string name=\"triangle\">Trojuholník</string>\n    <string name=\"polygon_sub\">Nakreslí mnohouholník od počiatočného bodu po koncový bod</string>\n    <string name=\"polygon\">Polygón</string>\n    <string name=\"outlined_polygon\">Obrysový mnohouholník</string>\n    <string name=\"outlined_polygon_sub\">Nakreslí obrysový mnohouholník od počiatočného bodu po koncový bod</string>\n    <string name=\"vertices\">Vertices</string>\n    <string name=\"draw_regular_polygon\">Nakreslite pravidelný mnohouholník</string>\n    <string name=\"draw_regular_polygon_sub\">Nakreslite mnohouholník, ktorý bude pravidelný namiesto voľného tvaru</string>\n    <string name=\"star_sub\">Kreslí hviezdu z počiatočného bodu do koncového bodu</string>\n    <string name=\"star\">Star</string>\n    <string name=\"outlined_star\">Obrysová hviezda</string>\n    <string name=\"outlined_star_sub\">Nakreslí obrysovú hviezdu od počiatočného bodu po koncový bod</string>\n    <string name=\"inner_radius_ratio\">Pomer vnútorného polomeru</string>\n    <string name=\"draw_regular_star\">Nakreslite pravidelnú hviezdu</string>\n    <string name=\"draw_regular_star_sub\">Nakreslite hviezdu, ktorá bude pravidelná namiesto voľnej formy</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Umožňuje antialiasing, aby sa zabránilo ostrým hranám</string>\n    <string name=\"open_edit_instead_of_preview\">Namiesto ukážky otvorte Upraviť</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Keď v ImageToolbox vyberiete obrázok na otvorenie (ukážka), namiesto náhľadu sa otvorí hárok s výberom úprav</string>\n    <string name=\"document_scanner\">Skener dokumentov</string>\n    <string name=\"document_scanner_sub\">Naskenujte dokumenty a vytvorte PDF alebo z nich oddeľte obrázky</string>\n    <string name=\"click_to_start_scanning\">Kliknutím spustíte skenovanie</string>\n    <string name=\"start_scanning\">Spustite skenovanie</string>\n    <string name=\"save_as_pdf\">Uložiť ako Pdf</string>\n    <string name=\"share_as_pdf\">Zdieľať ako Pdf</string>\n    <string name=\"options_below_is_for_images\">Možnosti nižšie slúžia na ukladanie obrázkov, nie PDF</string>\n    <string name=\"equalize_histogram_hsv\">Vyrovnajte histogram HSV</string>\n    <string name=\"equalize_histogram\">Vyrovnať histogram</string>\n    <string name=\"enter_percentage\">Zadajte percento</string>\n    <string name=\"allow_enter_by_text_field\">Povoliť zadávanie textovým poľom</string>\n    <string name=\"allow_enter_by_text_field_sub\">Povolí textové pole za výberom predvolieb, aby ste ich mohli zadávať za behu</string>\n    <string name=\"scale_color_space\">Mierka farebného priestoru</string>\n    <string name=\"linear\">Lineárne</string>\n    <string name=\"equalize_histogram_pixelation\">Vyrovnať pixeláciu histogramu</string>\n    <string name=\"grid_size_x\">Veľkosť mriežky X</string>\n    <string name=\"grid_size_y\">Veľkosť mriežky Y</string>\n    <string name=\"equalize_histogram_adaptive\">Vyrovnanie histogramu Adaptívne</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Equalize Histogram Adaptive LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Equalize Histogram Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Orezať na obsah</string>\n    <string name=\"frame_color\">Farba rámu</string>\n    <string name=\"color_to_ignore\">Farba na ignorovanie</string>\n    <string name=\"template\">Šablóna</string>\n    <string name=\"no_template_filters\">Neboli pridané žiadne filtre šablón</string>\n    <string name=\"create_new\">Vytvoriť nový</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Naskenovaný QR kód nie je platnou šablónou filtra</string>\n    <string name=\"scan_qr_code\">Naskenujte QR kód</string>\n    <string name=\"opened_file_have_no_filter_template\">Vybratý súbor nemá žiadne údaje šablóny filtra</string>\n    <string name=\"create_template\">Vytvoriť šablónu</string>\n    <string name=\"template_name\">Názov šablóny</string>\n    <string name=\"select_template_preview\">Tento obrázok sa použije na ukážku tejto šablóny filtra</string>\n    <string name=\"template_filter\">Filter šablóny</string>\n    <string name=\"as_qr_code\">Ako obrázok s QR kódom</string>\n    <string name=\"as_file\">Ako súbor</string>\n    <string name=\"save_as_file\">Uložiť ako súbor</string>\n    <string name=\"save_as_qr_code_image\">Uložiť ako obrázok s QR kódom</string>\n    <string name=\"delete_template\">Odstrániť šablónu</string>\n    <string name=\"delete_template_warn\">Chystáte sa odstrániť vybratý filter šablóny. Táto operácia sa nedá vrátiť späť</string>\n    <string name=\"added_filter_template\">Pridaná šablóna filtra s názvom \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Ukážka filtra</string>\n    <string name=\"qr_code\">QR a čiarový kód</string>\n    <string name=\"qr_code_sub\">Naskenujte QR kód a získajte jeho obsah alebo prilepte svoj reťazec a vygenerujte nový</string>\n    <string name=\"code_content\">Obsah kódu</string>\n    <string name=\"scan_qr_code_to_replace_content\">Naskenujte ľubovoľný čiarový kód, aby ste nahradili obsah v poli, alebo napíšte niečo a vygenerujte nový čiarový kód s vybraným typom</string>\n    <string name=\"qr_description\">Popis QR</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">V nastaveniach udeľte fotoaparátu povolenie na skenovanie QR kódu</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">V nastaveniach udeľte fotoaparátu povolenie na skenovanie skenera dokumentov</string>\n    <string name=\"cubic\">Kubický</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussovský</string>\n    <string name=\"sphinx\">Sfinga</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Box</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kubická interpolácia poskytuje plynulejšie škálovanie pri zohľadnení najbližších 16 pixelov, čo poskytuje lepšie výsledky ako bilineárne</string>\n    <string name=\"bspline_sub\">Využíva po častiach definované polynómové funkcie na hladkú interpoláciu a aproximáciu krivky alebo povrchu, flexibilné a súvislé znázornenie tvaru</string>\n    <string name=\"hamming_sub\">Funkcia okna používaná na zníženie spektrálneho úniku zúžením hrán signálu, užitočná pri spracovaní signálu</string>\n    <string name=\"hanning_sub\">Variant Hannovho okna, ktorý sa bežne používa na zníženie spektrálneho úniku v aplikáciách spracovania signálu</string>\n    <string name=\"blackman_sub\">Funkcia okna, ktorá poskytuje dobré frekvenčné rozlíšenie minimalizovaním spektrálneho úniku, často používaná pri spracovaní signálu</string>\n    <string name=\"welch_sub\">Funkcia okna navrhnutá tak, aby poskytovala dobré frekvenčné rozlíšenie so zníženým spektrálnym únikom, často používaná v aplikáciách spracovania signálu</string>\n    <string name=\"quadric_sub\">Metóda, ktorá využíva na interpoláciu kvadratickú funkciu, ktorá poskytuje hladké a súvislé výsledky</string>\n    <string name=\"gaussian_sub\">Interpolačná metóda, ktorá aplikuje Gaussovu funkciu, užitočnú na vyhladenie a zníženie šumu v obrazoch</string>\n    <string name=\"sphinx_sub\">Pokročilá metóda prevzorkovania poskytujúca vysokokvalitnú interpoláciu s minimálnymi artefaktmi</string>\n    <string name=\"bartlett_sub\">Funkcia trojuholníkového okna používaná pri spracovaní signálu na zníženie spektrálneho úniku</string>\n    <string name=\"robidoux_sub\">Vysokokvalitná interpolačná metóda optimalizovaná pre prirodzenú zmenu veľkosti obrazu, vyváženie ostrosti a plynulosti</string>\n    <string name=\"robidoux_sharp_sub\">Ostrejší variant metódy Robidoux, optimalizovaný pre ostrú zmenu veľkosti obrazu</string>\n    <string name=\"spline16_sub\">Metóda interpolácie založená na spline, ktorá poskytuje hladké výsledky pomocou filtra so 16 klepnutiami</string>\n    <string name=\"spline36_sub\">Metóda interpolácie založená na spline, ktorá poskytuje hladké výsledky pomocou filtra s 36 klepnutiami</string>\n    <string name=\"spline64_sub\">Metóda interpolácie založená na spline, ktorá poskytuje hladké výsledky pomocou filtra so 64 klepnutiami</string>\n    <string name=\"kaiser_sub\">Metóda interpolácie, ktorá využíva okno Kaiser, poskytuje dobrú kontrolu nad kompromisom medzi šírkou hlavného laloku a úrovňou bočného laloku</string>\n    <string name=\"bartlett_hann_sub\">Hybridná funkcia okien kombinujúca okná Bartlett a Hann, ktorá sa používa na zníženie spektrálneho úniku pri spracovaní signálu</string>\n    <string name=\"box_sub\">Jednoduchá metóda prevzorkovania, ktorá využíva priemer najbližších hodnôt pixelov, čo často vedie k blokovému vzhľadu</string>\n    <string name=\"bohman_sub\">Funkcia okna používaná na zníženie spektrálneho úniku poskytujúca dobré frekvenčné rozlíšenie v aplikáciách spracovania signálu</string>\n    <string name=\"lanczos2_sub\">Metóda prevzorkovania, ktorá využíva 2-lalokový Lanczosov filter pre vysokokvalitnú interpoláciu s minimálnymi artefaktmi</string>\n    <string name=\"lanczos3_sub\">Metóda prevzorkovania, ktorá využíva 3-lalokový Lanczosov filter pre vysokokvalitnú interpoláciu s minimálnymi artefaktmi</string>\n    <string name=\"lanczos4_sub\">Metóda prevzorkovania, ktorá využíva 4-lalokový Lanczosov filter pre vysokokvalitnú interpoláciu s minimálnymi artefaktmi</string>\n    <string name=\"lanczos2_jinc_sub\">Variant filtra Lanczos 2, ktorý využíva funkciu jinc a poskytuje vysokokvalitnú interpoláciu s minimálnymi artefaktmi</string>\n    <string name=\"lanczos3_jinc_sub\">Variant filtra Lanczos 3, ktorý využíva funkciu jinc a poskytuje vysokokvalitnú interpoláciu s minimálnymi artefaktmi</string>\n    <string name=\"lanczos4_jinc_sub\">Variant filtra Lanczos 4, ktorý využíva funkciu jinc a poskytuje vysokokvalitnú interpoláciu s minimálnymi artefaktmi</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Eliptický vážený priemer (EWA) variant Hanningovho filtra pre hladkú interpoláciu a prevzorkovanie</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Variant eliptického váženého priemeru (EWA) filtra Robidoux pre vysokokvalitné prevzorkovanie</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Variant eliptického váženého priemeru (EWA) filtra Blackman na minimalizáciu artefaktov zvonenia</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Variant eliptického váženého priemeru (EWA) filtra Quadric pre hladkú interpoláciu</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Variant eliptického váženého priemeru (EWA) filtra Robidoux Sharp pre ostrejšie výsledky</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Variant eliptického váženého priemeru (EWA) filtra Lanczos 3 Jinc pre vysokokvalitné prevzorkovanie so zníženým aliasingom</string>\n    <string name=\"ginseng\">Ženšen</string>\n    <string name=\"ginseng_sub\">Prevzorkovací filter určený na vysokokvalitné spracovanie obrazu s dobrým vyvážením ostrosti a plynulosti</string>\n    <string name=\"ewa_ginseng\">Ženšen EWA</string>\n    <string name=\"ewa_ginseng_sub\">Variant eliptického váženého priemeru (EWA) ženšenového filtra pre lepšiu kvalitu obrazu</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Variant eliptického váženého priemeru (EWA) filtra Lanczos Sharp na dosiahnutie ostrých výsledkov s minimálnymi artefaktmi</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 najostrejšie EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Variant eliptického váženého priemeru (EWA) filtra Lanczos 4 Sharpest pre extrémne ostré prevzorkovanie obrazu</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptical Weighted Average (EWA) variant filtra Lanczos Soft pre plynulejšie prevzorkovanie obrazu</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Prevzorkovací filter navrhnutý spoločnosťou Haasn pre plynulé škálovanie obrazu bez artefaktov</string>\n    <string name=\"format_conversion\">Konverzia formátu</string>\n    <string name=\"format_conversion_sub\">Preveďte dávku obrázkov z jedného formátu do druhého</string>\n    <string name=\"dismiss_forever\">Navždy zrušiť</string>\n    <string name=\"image_stacking\">Stohovanie obrázkov</string>\n    <string name=\"image_stacking_sub\">Skladanie obrázkov na seba pomocou zvolených režimov prelínania</string>\n    <string name=\"add_image\">Pridať obrázok</string>\n    <string name=\"bins_count\">Počet košov</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Equalize Histogram Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Equalize Histogram Adaptive HSV</string>\n    <string name=\"edge_mode\">Režim okraja</string>\n    <string name=\"clip\">Klip</string>\n    <string name=\"wrap\">Zabaliť</string>\n    <string name=\"color_blind_scheme\">Farebná slepota</string>\n    <string name=\"color_blind_scheme_sub\">Vyberte režim na prispôsobenie farieb témy pre vybraný variant farbosleposti</string>\n    <string name=\"protanomaly_sub\">Ťažkosti pri rozlišovaní medzi červenými a zelenými odtieňmi</string>\n    <string name=\"deuteranomaly_sub\">Ťažkosti pri rozlišovaní medzi zelenými a červenými odtieňmi</string>\n    <string name=\"tritanomaly_sub\">Ťažkosti pri rozlišovaní medzi modrými a žltými odtieňmi</string>\n    <string name=\"protanopia_sub\">Neschopnosť vnímať červené odtiene</string>\n    <string name=\"deuteranopia_sub\">Neschopnosť vnímať zelené odtiene</string>\n    <string name=\"tritanopia_sub\">Neschopnosť vnímať modré odtiene</string>\n    <string name=\"achromatomaly_sub\">Znížená citlivosť na všetky farby</string>\n    <string name=\"achromatopsia_sub\">Úplná farbosleposť, videnie len odtieňov sivej</string>\n    <string name=\"not_use_color_blind_scheme\">Nepoužívajte schému Color Blind</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Farby budú presne také, ako sú nastavené v téme</string>\n    <string name=\"sigmoidal\">Sigmoidálny</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Lagrangeov interpolačný filter rádu 2, vhodný pre vysokokvalitné škálovanie obrazu s plynulými prechodmi</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Lagrangeov interpolačný filter rádu 3, ktorý ponúka lepšiu presnosť a hladšie výsledky pre zmenu mierky obrazu</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Prevzorkovací filter Lanczos s vyšším rádom 6, ktorý poskytuje ostrejšie a presnejšie škálovanie obrazu</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Variant filtra Lanczos 6 využívajúci funkciu Jinc pre lepšiu kvalitu prevzorkovania obrazu</string>\n    <string name=\"linear_box_blur\">Lineárne rozmazanie rámčeka</string>\n    <string name=\"linear_tent_blur\">Lineárne rozmazanie stanu</string>\n    <string name=\"linear_gaussian_box_blur\">Lineárne rozmazanie Gaussovho poľa</string>\n    <string name=\"linear_stack_blur\">Lineárne rozmazanie stohu</string>\n    <string name=\"gaussian_box_blur\">Rozmazanie Gaussovho poľa</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Lineárne rýchle Gaussovské rozostrenie Ďalej</string>\n    <string name=\"linear_fast_gaussian_blur\">Lineárne rýchle Gaussovské rozostrenie</string>\n    <string name=\"linear_gaussian_blur\">Lineárne gaussovské rozostrenie</string>\n    <string name=\"draw_filter_sub\">Vyberte jeden filter, ktorý chcete použiť ako farbu</string>\n    <string name=\"replace_filter\">Vymeňte filter</string>\n    <string name=\"pick_filter_info\">Vyberte filter nižšie, aby ste ho mohli použiť ako štetec vo svojej kresbe</string>\n    <string name=\"tiff_compression_scheme\">Schéma kompresie TIFF</string>\n    <string name=\"low_poly\">Low Poly</string>\n    <string name=\"sand_painting\">Piesková maľba</string>\n    <string name=\"image_splitting\">Rozdelenie obrazu</string>\n    <string name=\"image_splitting_sub\">Rozdeľte jeden obrázok podľa riadkov alebo stĺpcov</string>\n    <string name=\"fit_to_bounds\">Fit To Bounds</string>\n    <string name=\"fit_to_bounds_sub\">Skombinujte režim zmeny veľkosti orezania s týmto parametrom, aby ste dosiahli požadované správanie (orezať/prispôsobiť pomeru strán)</string>\n    <string name=\"languages_imported\">Jazyky boli úspešne importované</string>\n    <string name=\"backup_ocr_models\">Záložné modely OCR</string>\n    <string name=\"import_word\">Importovať</string>\n    <string name=\"export\">Exportovať</string>\n    <string name=\"position\">pozícia</string>\n    <string name=\"center\">centrum</string>\n    <string name=\"top_left\">Vľavo hore</string>\n    <string name=\"top_right\">Vpravo hore</string>\n    <string name=\"bottom_left\">Vľavo dole</string>\n    <string name=\"bottom_right\">Vpravo dole</string>\n    <string name=\"top_center\">Stred hore</string>\n    <string name=\"center_right\">Stred vpravo</string>\n    <string name=\"bottom_center\">Stred dole</string>\n    <string name=\"center_left\">Stred vľavo</string>\n    <string name=\"target_image\">Cieľový obrázok</string>\n    <string name=\"palette_transfer\">Prenos palety</string>\n    <string name=\"enhanced_oil\">Vylepšený olej</string>\n    <string name=\"simple_old_tv\">Jednoduchý starý televízor</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Jednoduchá skica</string>\n    <string name=\"soft_glow\">Mäkká žiara</string>\n    <string name=\"color_poster\">Farebný plagát</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Tretia farba</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olchová</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Clustered 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Clustered 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">Clustered 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Nie sú vybraté žiadne obľúbené možnosti, pridajte ich na stránke nástrojov</string>\n    <string name=\"add_favorites\">Pridať obľúbené</string>\n    <string name=\"harmony_complementary\">Doplnkové</string>\n    <string name=\"harmony_analogous\">Analogické</string>\n    <string name=\"harmony_triadic\">Triadický</string>\n    <string name=\"harmony_split_complementary\">Doplnkové rozdelenie</string>\n    <string name=\"harmony_tetradic\">Tetradic</string>\n    <string name=\"harmony_square\">Štvorcový</string>\n    <string name=\"harmony_analogous_complementary\">Analogické + doplnkové</string>\n    <string name=\"color_tools\">Farebné nástroje</string>\n    <string name=\"color_tools_sub\">Miešajte, vytvárajte tóny, generujte odtiene a ďalšie</string>\n    <string name=\"color_harmonies\">Farebné harmónie</string>\n    <string name=\"color_shading\">Farebné tieňovanie</string>\n    <string name=\"variation\">Variácia</string>\n    <string name=\"tints\">Odtiene</string>\n    <string name=\"tones\">Tóny</string>\n    <string name=\"shades\">Odtiene</string>\n    <string name=\"color_mixing\">Miešanie farieb</string>\n    <string name=\"color_info\">Informácie o farbe</string>\n    <string name=\"selected_color\">Vybraná farba</string>\n    <string name=\"color_to_mix\">Farba na miešanie</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Keď sú zapnuté dynamické farby, nemožno použiť monet</string>\n    <string name=\"lut512x512\">512 x 512 2D LUT</string>\n    <string name=\"target_lut_image\">Cieľový obrázok LUT</string>\n    <string name=\"amatorka\">Amatér</string>\n    <string name=\"miss_etikate\">Slečna etiketa</string>\n    <string name=\"soft_elegance\">Mäkká elegancia</string>\n    <string name=\"soft_elegance_variant\">Variant Soft Elegance</string>\n    <string name=\"palette_transfer_variant\">Variant prenosu palety</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Cieľový súbor 3D LUT (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Svetlo sviečok</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Ostrý jantár</string>\n    <string name=\"fall_colors\">Farby jesene</string>\n    <string name=\"film_stock_50\">Filmový fond 50</string>\n    <string name=\"foggy_night\">Hmlistá noc</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Získajte neutrálny obraz LUT</string>\n    <string name=\"save_empty_lut_sub\">Najprv pomocou svojej obľúbenej aplikácie na úpravu fotografií aplikujte filter na neutrálne LUT, ktorý môžete získať tu. Aby to fungovalo správne, farba každého pixelu nesmie závisieť od iných pixelov (napr. rozmazanie nebude fungovať). Keď budete pripravený, použite svoj nový obrázok LUT ako vstup pre filter 512*512 LUT</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celuloid</string>\n    <string name=\"coffee\">Káva</string>\n    <string name=\"golden_forest\">Zlatý les</string>\n    <string name=\"greenish\">Nazelenalý</string>\n    <string name=\"retro_yellow\">Retro žltá</string>\n    <string name=\"links_preview\">Ukážka odkazov</string>\n    <string name=\"links_preview_sub\">Umožňuje načítanie ukážky odkazu na miestach, kde môžete získať text (QRCode, OCR atď.)</string>\n    <string name=\"links\">Odkazy</string>\n    <string name=\"ico_size_warning\">Súbory ICO je možné uložiť len v maximálnej veľkosti 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF na WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Prevod obrázkov GIF na animované obrázky WEBP</string>\n    <string name=\"webp_tools\">Nástroje WEBP</string>\n    <string name=\"webp_tools_sub\">Preveďte obrázky na animovaný obrázok WEBP alebo extrahujte snímky z danej animácie WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP na obrázky</string>\n    <string name=\"webp_type_to_image_sub\">Previesť súbor WEBP na dávku obrázkov</string>\n    <string name=\"webp_type_to_webp_sub\">Preveďte dávku obrázkov do súboru WEBP</string>\n    <string name=\"webp_type_to_webp\">Obrázky na WEBP</string>\n    <string name=\"select_webp_image_to_start\">Začnite výberom obrázka WEBP</string>\n    <string name=\"manage_storage_extra_types\">Žiadny úplný prístup k súborom</string>\n    <string name=\"manage_storage_extra_types_sub\">Povoľte prístup k všetkým súborom, aby ste mohli vidieť obrázky JXL, QOI a ďalšie obrázky, ktoré nie sú v systéme Android rozpoznané ako obrázky. Bez povolenia Image Toolbox nemôže zobraziť tieto obrázky</string>\n    <string name=\"default_draw_color\">Predvolená farba kreslenia</string>\n    <string name=\"default_draw_path_mode\">Predvolený režim cesty kreslenia</string>\n    <string name=\"add_timestamp\">Pridať časovú pečiatku</string>\n    <string name=\"add_timestamp_sub\">Povolí pridanie časovej pečiatky do výstupného súboru</string>\n    <string name=\"formatted_timestamp\">Formátovaná časová pečiatka</string>\n    <string name=\"formatted_timestamp_sub\">Povoliť formátovanie časovej pečiatky vo výstupnom súbore namiesto základných milis</string>\n    <string name=\"enable_timestamps_to_format_them\">Povoľte časové pečiatky a vyberte ich formát</string>\n    <string name=\"one_time_save_location\">Miesto na jednorazové uloženie</string>\n    <string name=\"one_time_save_location_sub\">Zobrazte a upravte miesta na jednorazové uloženie, ktoré môžete použiť dlhým stlačením tlačidla uloženia vo väčšine možností</string>\n    <string name=\"recently_used\">Nedávno použité</string>\n    <string name=\"ci_channel\">CI kanál</string>\n    <string name=\"group\">Skupina</string>\n    <string name=\"image_toolbox_in_telegram\">Súbor nástrojov obrázkov v telegrame 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Pripojte sa k nášmu chatu, kde môžete diskutovať o čomkoľvek, čo chcete, a tiež sa pozrieť na kanál CI, kde uverejňujem beta verzie a oznámenia</string>\n    <string name=\"ci_channel_sub\">Získajte upozornenia na nové verzie aplikácie a prečítajte si oznámenia</string>\n    <string name=\"fit_description\">Prispôsobte obrázok daným rozmerom a použite rozmazanie alebo farbu na pozadie</string>\n    <string name=\"tools_arrangement\">Usporiadanie nástrojov</string>\n    <string name=\"group_tools_by_type\">Zoskupte nástroje podľa typu</string>\n    <string name=\"group_tools_by_type_sub\">Zoskupuje nástroje na hlavnej obrazovke podľa ich typu namiesto vlastného usporiadania zoznamu</string>\n    <string name=\"default_values\">Predvolené hodnoty</string>\n    <string name=\"system_bars_visibility\">Viditeľnosť systémových pruhov</string>\n    <string name=\"show_system_bars_by_swipe\">Zobraziť systémové lišty potiahnutím prstom</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Umožňuje potiahnutím zobraziť systémové lišty, ak sú skryté</string>\n    <string name=\"auto\">Auto</string>\n    <string name=\"hide_all\">Skryť všetko</string>\n    <string name=\"show_all\">Zobraziť všetko</string>\n    <string name=\"hide_nav_bar\">Skryť navigačný panel</string>\n    <string name=\"hide_status_bar\">Skryť stavový riadok</string>\n    <string name=\"noise_generation\">Generovanie hluku</string>\n    <string name=\"noise_generation_sub\">Generujte rôzne zvuky ako Perlin alebo iné typy</string>\n    <string name=\"frequency\">Frekvencia</string>\n    <string name=\"noise_type\">Typ hluku</string>\n    <string name=\"rotation_type\">Typ rotácie</string>\n    <string name=\"fractal_type\">Fraktálny typ</string>\n    <string name=\"octaves\">Oktávy</string>\n    <string name=\"lacunarity\">Lacunárnosť</string>\n    <string name=\"gain\">Získať</string>\n    <string name=\"weighted_strength\">Vážená sila</string>\n    <string name=\"ping_pong_strength\">Sila ping pongu</string>\n    <string name=\"distance_function\">Funkcia vzdialenosti</string>\n    <string name=\"return_type\">Typ návratu</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Warp domén</string>\n    <string name=\"alignment\">Zarovnanie</string>\n    <string name=\"custom_filename\">Vlastný názov súboru</string>\n    <string name=\"custom_filename_sub\">Vyberte umiestnenie a názov súboru, ktorý sa použije na uloženie aktuálneho obrázka</string>\n    <string name=\"saved_to_custom\">Uložené do priečinka s vlastným názvom</string>\n    <string name=\"collage_maker\">Tvorba koláží</string>\n    <string name=\"collage_maker_sub\">Vytvorte koláže až z 20 obrázkov</string>\n    <string name=\"collage_type\">Typ koláže</string>\n    <string name=\"collages_info\">Podržaním obrázka ho môžete vymeniť, posunúť a priblížiť, aby ste upravili polohu</string>\n    <string name=\"disable_rotation\">Zakázať otáčanie</string>\n    <string name=\"disable_rotation_sub\">Zabraňuje otáčaniu obrázkov pomocou gest dvoch prstov</string>\n    <string name=\"enable_snapping_to_borders\">Povoliť prichytenie k okrajom</string>\n    <string name=\"enable_snapping_to_borders_sub\">Po presunutí alebo priblížení sa obrázky prichytia tak, aby vyplnili okraje rámu</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">Histogram obrazu RGB alebo jasu, ktorý vám pomôže vykonať úpravy</string>\n    <string name=\"image_for_histogram\">Tento obrázok sa použije na generovanie histogramov RGB a jasu</string>\n    <string name=\"tesseract_options\">Možnosti Tesseract</string>\n    <string name=\"tesseract_options_sub\">Použite niektoré vstupné premenné pre tesseract engine</string>\n    <string name=\"custom_options\">Vlastné možnosti</string>\n    <string name=\"custom_params_info\">Možnosti by sa mali zadať podľa tohto vzoru: \\\"--{názov_možnosti} {hodnota}\\\"</string>\n    <string name=\"auto_crop\">Automatické orezanie</string>\n    <string name=\"free_corners\">Voľné rohy</string>\n    <string name=\"free_corners_sub\">Orezať obrázok podľa mnohouholníka, tým sa opraví aj perspektíva</string>\n    <string name=\"coerce_points_to_image_bounds\">Násilné body na hranice obrázkov</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Body nebudú obmedzené hranicami obrázka, čo je užitočné na presnejšiu korekciu perspektívy</string>\n    <string name=\"mask\">Maska</string>\n    <string name=\"spot_heal_sub\">Výplň pod nakreslenou cestou podľa obsahu</string>\n    <string name=\"spot_heal\">Heal Spot</string>\n    <string name=\"use_circle_kernel\">Použite kruhové jadro</string>\n    <string name=\"opening\">Otvorenie</string>\n    <string name=\"closing\">Zatváranie</string>\n    <string name=\"morphological_gradient\">Morfologický gradient</string>\n    <string name=\"top_hat\">Cylindr</string>\n    <string name=\"black_hat\">Čierny klobúk</string>\n    <string name=\"tone_curves\">Tónové krivky</string>\n    <string name=\"reset_curves\">Resetovať krivky</string>\n    <string name=\"reset_curves_sub\">Krivky sa vrátia späť na predvolenú hodnotu</string>\n    <string name=\"line_style\">Štýl čiary</string>\n    <string name=\"gap_size\">Veľkosť medzery</string>\n    <string name=\"dashed\">Prerušovaná</string>\n    <string name=\"dot_dashed\">Bodka prerušovaná</string>\n    <string name=\"stamped\">Pečiatkované</string>\n    <string name=\"zigzag\">Cikcak</string>\n    <string name=\"dashed_sub\">Nakreslí prerušovanú čiaru pozdĺž nakreslenej cesty so špecifikovanou veľkosťou medzery</string>\n    <string name=\"dot_dashed_sub\">Nakreslí bodku a prerušovanú čiaru pozdĺž danej cesty</string>\n    <string name=\"defaultt_sub\">Len predvolené rovné čiary</string>\n    <string name=\"stamped_sub\">Nakreslí vybrané tvary pozdĺž cesty so zadanými medzerami</string>\n    <string name=\"zigzag_sub\">Kreslí vlnitý cikcak pozdĺž cesty</string>\n    <string name=\"zigzag_ratio\">Kľukatý pomer</string>\n    <string name=\"create_shortcut\">Vytvoriť skratku</string>\n    <string name=\"create_shortcut_title\">Vyberte nástroj na pripnutie</string>\n    <string name=\"create_shortcut_subtitle\">Nástroj sa pridá na domovskú obrazovku vášho spúšťača ako skratka, použite ho v kombinácii s nastavením \\\"Preskočiť výber súboru\\\" na dosiahnutie potrebného správania</string>\n    <string name=\"dont_stack_frames\">Neskladujte rámy</string>\n    <string name=\"dont_stack_frames_sub\">Umožňuje likvidáciu predchádzajúcich rámov, takže sa nebudú na seba naskladať</string>\n    <string name=\"crossfade\">Prelínanie</string>\n    <string name=\"crossfade_sub\">Rámy budú navzájom prelínané</string>\n    <string name=\"crossfade_count\">Počet snímok s prelínaním</string>\n    <string name=\"threshold_one\">Prah jedna</string>\n    <string name=\"threshold_two\">Prah dva</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Zrkadlo 101</string>\n    <string name=\"enhanced_zoom_blur\">Vylepšené rozostrenie zoomu</string>\n    <string name=\"laplacian_simple\">Laplaciánske jednoduché</string>\n    <string name=\"sobel_simple\">Sobel Jednoduché</string>\n    <string name=\"helper_grid\">Pomocná mriežka</string>\n    <string name=\"helper_grid_sub\">Zobrazuje podpornú mriežku nad oblasťou kreslenia, ktorá pomáha pri presnej manipulácii</string>\n    <string name=\"grid_color\">Farba mriežky</string>\n    <string name=\"cell_width\">Šírka bunky</string>\n    <string name=\"cell_height\">Výška bunky</string>\n    <string name=\"compact_selectors\">Kompaktné selektory</string>\n    <string name=\"compact_selectors_sub\">Niektoré ovládacie prvky výberu budú používať kompaktné rozloženie, aby zaberali menej miesta</string>\n    <string name=\"grant_camera_permission_to_capture_image\">V nastaveniach udeľte fotoaparátu povolenie na snímanie obrázka</string>\n    <string name=\"layout\">Rozloženie</string>\n    <string name=\"main_screen_title\">Názov hlavnej obrazovky</string>\n    <string name=\"constant_rate_factor\">Faktor konštantnej rýchlosti (CRF)</string>\n    <string name=\"crf_sub\">Hodnota %1$s znamená pomalú kompresiu, výsledkom čoho je relatívne malá veľkosť súboru. %2$s znamená rýchlejšiu kompresiu, výsledkom čoho je veľký súbor.</string>\n    <string name=\"lut_library\">Knižnica Lut</string>\n    <string name=\"lut_library_sub\">Stiahnite si kolekciu LUT, ktorú môžete použiť po stiahnutí</string>\n    <string name=\"lut_library_update_sub\">Aktualizujte kolekciu LUT (do fronty budú zaradené iba nové), ktoré môžete použiť po stiahnutí</string>\n    <string name=\"filter_preview_image_sub\">Zmeňte predvolený náhľad obrázka pre filtre</string>\n    <string name=\"filter_preview_image\">Obrázok ukážky</string>\n    <string name=\"hide\">Skryť</string>\n    <string name=\"show\">Zobraziť</string>\n    <string name=\"slider_type\">Typ posúvača</string>\n    <string name=\"fancy\">Fancy</string>\n    <string name=\"material_2\">Materiál 2</string>\n    <string name=\"fancy_sub\">Efektne vyzerajúci posúvač. Toto je predvolená možnosť</string>\n    <string name=\"material_2_sub\">Posuvník Materiál 2</string>\n    <string name=\"material_you_slider_sub\">Posuvník Material You</string>\n    <string name=\"apply\">Použiť</string>\n    <string name=\"center_align_dialog_buttons\">Stredové dialógové tlačidlá</string>\n    <string name=\"center_align_dialog_buttons_sub\">Tlačidlá dialógových okien budú podľa možnosti umiestnené v strede namiesto na ľavej strane</string>\n    <string name=\"open_source_licenses\">Licencie otvoreného zdroja</string>\n    <string name=\"open_source_licenses_sub\">Pozrite si licencie knižníc s otvoreným zdrojovým kódom používaných v tejto aplikácii</string>\n    <string name=\"area\">Oblasť</string>\n    <string name=\"area_sub\">Prevzorkovanie pomocou vzťahu plochy pixelov. Môže to byť preferovaná metóda na decimáciu obrazu, pretože poskytuje výsledky bez moaré. Ale keď sa obrázok priblíži, je to podobné ako pri metóde \\\"Najbližšie\\\".</string>\n    <string name=\"enable_tonemapping\">Povoliť mapovanie tónov</string>\n    <string name=\"enter_percent\">Zadajte %</string>\n    <string name=\"unknown_host\">Nemáte prístup na stránku, skúste použiť VPN alebo skontrolujte správnosť adresy URL</string>\n    <string name=\"markup_layers\">Vrstvy značiek</string>\n    <string name=\"markup_layers_sub\">Režim vrstiev s možnosťou voľne umiestňovať obrázky, text a ďalšie</string>\n    <string name=\"edit_layer\">Upraviť vrstvu</string>\n    <string name=\"layers_on_image\">Vrstvy na obrázku</string>\n    <string name=\"layers_on_image_sub\">Použite obrázok ako pozadie a pridajte naň rôzne vrstvy</string>\n    <string name=\"layers_on_background\">Vrstvy na pozadí</string>\n    <string name=\"layers_on_background_sub\">To isté ako prvá možnosť, ale s farbou namiesto obrázka</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Strana rýchlych nastavení</string>\n    <string name=\"fast_settings_side_sub\">Pri úprave obrázkov pridajte na vybranú stranu plávajúci pás, ktorý po kliknutí otvorí rýchle nastavenia</string>\n    <string name=\"clear_selection\">Vymazať výber</string>\n    <string name=\"settings_group_visibility_hidden\">Skupina nastavení \\\"%1$s\\\" bude predvolene zbalená</string>\n    <string name=\"settings_group_visibility_visible\">Skupina nastavení \\\"%1$s\\\" bude predvolene rozbalená</string>\n    <string name=\"base_64_tools\">Nástroje Base64</string>\n    <string name=\"base_64_tools_sub\">Dekódujte reťazec Base64 na obrázok alebo zakódujte obrázok do formátu Base64</string>\n    <string name=\"base_64\">Základ 64</string>\n    <string name=\"not_a_valid_base_64\">Poskytnutá hodnota nie je platný reťazec Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">Nie je možné skopírovať prázdny alebo neplatný reťazec Base64</string>\n    <string name=\"paste_base_64\">Prilepte základ 64</string>\n    <string name=\"copy_base_64\">Kopírovať základ 64</string>\n    <string name=\"base_64_tips\">Načítať obrázok na skopírovanie alebo uloženie reťazca Base64. Ak máte samotný reťazec, môžete ho vložiť vyššie, aby ste získali obrázok</string>\n    <string name=\"save_base_64\">Uložiť Base64</string>\n    <string name=\"share_base_64\">Zdieľať Base64</string>\n    <string name=\"options\">Možnosti</string>\n    <string name=\"actions\">Akcie</string>\n    <string name=\"import_base_64\">Importovať Base64</string>\n    <string name=\"base_64_actions\">Akcie Base64</string>\n    <string name=\"add_outline\">Pridať obrys</string>\n    <string name=\"add_outline_sub\">Pridajte obrys okolo textu s určenou farbou a šírkou</string>\n    <string name=\"outline_color\">Farba obrysu</string>\n    <string name=\"outline_size\">Veľkosť obrysu</string>\n    <string name=\"rotation\">Rotácia</string>\n    <string name=\"checksum_as_filename\">Kontrolný súčet ako názov súboru</string>\n    <string name=\"checksum_as_filename_sub\">Výstupné obrázky budú mať názov zodpovedajúci ich kontrolnému súčtu údajov</string>\n    <string name=\"free_software_partner\">Slobodný softvér (partner)</string>\n    <string name=\"free_software_partner_sub\">Užitočnejší softvér v partnerskom kanáli aplikácií pre Android</string>\n    <string name=\"algorithms\">Algoritmus</string>\n    <string name=\"checksum_tools\">Nástroje kontrolného súčtu</string>\n    <string name=\"checksum_tools_sub\">Porovnajte kontrolné súčty, vypočítajte hash alebo vytvorte hexadecimálne reťazce zo súborov pomocou rôznych hashovacích algoritmov</string>\n    <string name=\"calculate\">Vypočítajte</string>\n    <string name=\"text_hash\">Textový hash</string>\n    <string name=\"checksum\">Kontrolný súčet</string>\n    <string name=\"pick_file_to_checksum\">Vyberte súbor a vypočítajte jeho kontrolný súčet na základe zvoleného algoritmu</string>\n    <string name=\"enter_text_to_checksum\">Zadajte text na výpočet jeho kontrolného súčtu na základe zvoleného algoritmu</string>\n    <string name=\"source_checksum\">Kontrolný súčet zdroja</string>\n    <string name=\"checksum_to_compare\">Kontrolný súčet na porovnanie</string>\n    <string name=\"match\">Zápas!</string>\n    <string name=\"difference\">Rozdiel</string>\n    <string name=\"match_sub\">Kontrolné súčty sú rovnaké, môže to byť bezpečné</string>\n    <string name=\"difference_sub\">Kontrolné súčty nie sú rovnaké, súbor môže byť nebezpečný!</string>\n    <string name=\"mesh_gradients\">Sieťové prechody</string>\n    <string name=\"collection_mesh_gradients_sub\">Pozrite sa na online kolekciu sieťových prechodov</string>\n    <string name=\"wrong_font\">Importovať je možné iba písma TTF a OTF</string>\n    <string name=\"import_font\">Importovať písmo (TTF/OTF)</string>\n    <string name=\"export_fonts\">Exportujte písma</string>\n    <string name=\"imported_fonts\">Importované písma</string>\n    <string name=\"error_while_saving\">Chyba pri pokuse o ukladanie, skúste zmeniť výstupný priečinok</string>\n    <string name=\"filename_is_not_set\">Názov súboru nie je nastavený</string>\n    <string name=\"none\">žiadne</string>\n    <string name=\"custom_pages\">Vlastné stránky</string>\n    <string name=\"pages_selection\">Výber strán</string>\n    <string name=\"tool_exit_confirmation\">Potvrdenie ukončenia nástroja</string>\n    <string name=\"tool_exit_confirmation_sub\">Ak máte pri používaní určitých nástrojov neuložené zmeny a pokúsite sa ich zavrieť, zobrazí sa dialógové okno na potvrdenie</string>\n    <string name=\"edit_exif_screen\">Upraviť EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Zmeňte metadáta jedného obrázka bez opätovnej kompresie</string>\n    <string name=\"edit_exif_tag\">Klepnutím upravíte dostupné značky</string>\n    <string name=\"change_sticker\">Zmeniť nálepku</string>\n    <string name=\"fit_width\">Prispôsobiť šírku</string>\n    <string name=\"fit_height\">Prispôsobiť výšku</string>\n    <string name=\"batch_compare\">Dávkové porovnanie</string>\n    <string name=\"pick_files_to_checksum\">Vyberte súbor/súbory a vypočítajte ich kontrolný súčet na základe zvoleného algoritmu</string>\n    <string name=\"pick_files\">Vyberte súbory</string>\n    <string name=\"pick_directory\">Vyberte adresár</string>\n    <string name=\"head_length_scale\">Mierka dĺžky hlavy</string>\n    <string name=\"stamp\">Pečiatka</string>\n    <string name=\"timestamp\">Časová pečiatka</string>\n    <string name=\"format_pattern\">Vzor formátu</string>\n    <string name=\"padding\">Výplň</string>\n    <string name=\"image_cutting\">Rezanie obrazu</string>\n    <string name=\"image_cutting_sub\">Vystrihnite časť obrázka a spojte ľavé (môže byť inverzné) zvislými alebo vodorovnými čiarami</string>\n    <string name=\"vertical_pivot_line\">Vertikálna otočná čiara</string>\n    <string name=\"horizontal_pivot_line\">Horizontálna otočná čiara</string>\n    <string name=\"inverse_selection\">Inverzný výber</string>\n    <string name=\"inverse_vertical_selection_sub\">Zvislá časť rezu bude ponechaná namiesto zlúčenia častí okolo oblasti rezu</string>\n    <string name=\"inverse_horizontal_selection_sub\">Vodorovná časť rezu bude ponechaná namiesto zlúčenia častí okolo oblasti rezu</string>\n    <string name=\"collection_mesh_gradients\">Kolekcia sieťových prechodov</string>\n    <string name=\"mesh_gradients_sub\">Vytvorte sieťový gradient s vlastným množstvom uzlov a rozlíšením</string>\n    <string name=\"gradient_maker_type_image_mesh\">Prekrytie sieťovým prechodom</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Vytvorte sieťový gradient hornej časti daných obrázkov</string>\n    <string name=\"points_customization\">Prispôsobenie bodov</string>\n    <string name=\"grid_size\">Veľkosť mriežky</string>\n    <string name=\"resolution_x\">Rozlíšenie X</string>\n    <string name=\"resolution_y\">Uznesenie Y</string>\n    <string name=\"resolution\">Rozlíšenie</string>\n    <string name=\"pixel_by_pixel\">Pixel za pixelom</string>\n    <string name=\"highlight_color\">Farba zvýraznenia</string>\n    <string name=\"pixel_comparison_type\">Typ porovnania pixelov</string>\n    <string name=\"scan_barcode\">Naskenujte čiarový kód</string>\n    <string name=\"height_ratio\">Výškový pomer</string>\n    <string name=\"barcode_type\">Typ čiarového kódu</string>\n    <string name=\"enforce_bw\">Vynútiť Č/B</string>\n    <string name=\"enforce_bw_sub\">Obrázok čiarového kódu bude úplne čiernobiely a nebude zafarbený témou aplikácie</string>\n    <string name=\"barcodes_sub\">Naskenujte ľubovoľný čiarový kód (QR, EAN, AZTEC, …) a získajte jeho obsah alebo prilepte svoj text a vygenerujte nový</string>\n    <string name=\"no_barcode_found\">Nenašiel sa žiadny čiarový kód</string>\n    <string name=\"generated_barcode_will_be_here\">Vygenerovaný čiarový kód bude tu</string>\n    <string name=\"audio_cover_extractor\">Audio obaly</string>\n    <string name=\"audio_cover_extractor_sub\">Extrahujte obrázky obalu albumu zo zvukových súborov, väčšina bežných formátov je podporovaná</string>\n    <string name=\"pick_audio_to_start\">Začnite výberom zvuku</string>\n    <string name=\"pick_audio\">Vyberte Zvuk</string>\n    <string name=\"no_covers_found\">Nenašli sa žiadne obaly</string>\n    <string name=\"send_logs\">Odoslať denníky</string>\n    <string name=\"send_logs_sub\">Kliknutím zdieľajte súbor denníkov aplikácií, môže mi to pomôcť odhaliť problém a vyriešiť problémy</string>\n    <string name=\"crash_title\">Ojoj… Niečo sa pokazilo</string>\n    <string name=\"crash_subtitle\">Môžete ma kontaktovať pomocou možností nižšie a ja sa pokúsim nájsť riešenie.\\n(Nezabudnite priložiť protokoly)</string>\n    <string name=\"ocr_write_to_file\">Zápis do súboru</string>\n    <string name=\"ocr_write_to_file_sub\">Extrahujte text z dávky obrázkov a uložte ho do jedného textového súboru</string>\n    <string name=\"ocr_write_to_metadata\">Zápis do metadát</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extrahujte text z každého obrázka a umiestnite ho do EXIF ​​informácií o príbuzných fotografiách</string>\n    <string name=\"invisible_mode\">Neviditeľný režim</string>\n    <string name=\"invisible_mode_sub\">Použite steganografiu na vytvorenie okom neviditeľných vodoznakov vo vnútri bajtov vašich obrázkov</string>\n    <string name=\"use_lsb\">Použite LSB</string>\n    <string name=\"use_lsb_sub\">Použije sa metóda steganografie LSB (Menej významný bit), inak FD (Frequency Domain)</string>\n    <string name=\"auto_remove_red_eyes\">Automatické odstránenie červených očí</string>\n    <string name=\"password\">heslo</string>\n    <string name=\"unlock\">Odomknúť</string>\n    <string name=\"pdf_is_protected\">PDF je chránené</string>\n    <string name=\"operation_almost_complete\">Operácia takmer dokončená. Zrušenie teraz bude vyžadovať reštartovanie</string>\n    <string name=\"sort_by_date_modified\">Dátum zmeny</string>\n    <string name=\"sort_by_date_modified_reversed\">Dátum zmeny (obrátené)</string>\n    <string name=\"sort_by_size\">Veľkosť</string>\n    <string name=\"sort_by_size_reversed\">Veľkosť (obrátená)</string>\n    <string name=\"sort_by_mime_type\">Typ MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Typ MIME (obrátený)</string>\n    <string name=\"sort_by_extension\">Rozšírenie</string>\n    <string name=\"sort_by_extension_reversed\">Rozšírenie (obrátené)</string>\n    <string name=\"sort_by_date_added\">Dátum pridania</string>\n    <string name=\"sort_by_date_added_reversed\">Dátum pridania (obrátené)</string>\n    <string name=\"left_to_right\">Zľava doprava</string>\n    <string name=\"right_to_left\">Sprava doľava</string>\n    <string name=\"top_to_bottom\">Zhora nadol</string>\n    <string name=\"bottom_to_top\">Zdola nahor</string>\n    <string name=\"liquid_glass\">Tekuté sklo</string>\n    <string name=\"liquid_glass_sub\">Prepínač založený na nedávno ohlásenom IOS 26 a jeho dizajnovom systéme z tekutého skla</string>\n    <string name=\"pick_image_or_base64\">Nižšie vyberte obrázok alebo prilepte/importujte údaje Base64</string>\n    <string name=\"type_image_link\">Začnite zadaním odkazu na obrázok</string>\n    <string name=\"paste_link\">Prilepiť odkaz</string>\n    <string name=\"kaleidoscope\">Kaleidoskop</string>\n    <string name=\"secondary_angle\">Sekundárny uhol</string>\n    <string name=\"sides\">Strany</string>\n    <string name=\"channel_mix\">Mix kanálov</string>\n    <string name=\"blue_green\">Modrá zelená</string>\n    <string name=\"red_blue\">Červená modrá</string>\n    <string name=\"green_red\">Zelená červená</string>\n    <string name=\"into_red\">Do červena</string>\n    <string name=\"into_green\">Do zelena</string>\n    <string name=\"into_blue\">Do modra</string>\n    <string name=\"cyan\">azúrová</string>\n    <string name=\"magenta\">purpurová</string>\n    <string name=\"yellow\">Žltá</string>\n    <string name=\"color_halftone\">Farba Poltón</string>\n    <string name=\"contour\">Obrys</string>\n    <string name=\"levels\">Úrovne</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi kryštalizovať</string>\n    <string name=\"shape\">Tvar</string>\n    <string name=\"stretch\">Natiahnuť</string>\n    <string name=\"randomness\">Náhodnosť</string>\n    <string name=\"despeckle\">Odšpiniť</string>\n    <string name=\"diffuse\">Difúzne</string>\n    <string name=\"dog\">Pes</string>\n    <string name=\"second_radius\">Druhý polomer</string>\n    <string name=\"equalize\">Vyrovnať</string>\n    <string name=\"glow\">Žiariť</string>\n    <string name=\"whirl_and_pinch\">Vír a štipka</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">Farba okraja</string>\n    <string name=\"polar_coordinates\">Polárne súradnice</string>\n    <string name=\"rect_to_polar\">Rect to polárne</string>\n    <string name=\"polar_to_rect\">Polárne až pravouhlé</string>\n    <string name=\"invert_in_circle\">Invertovať v kruhu</string>\n    <string name=\"reduce_noise\">Znížte hluk</string>\n    <string name=\"simple_solarize\">Jednoduchá Solarizácia</string>\n    <string name=\"weave\">tkať</string>\n    <string name=\"x_gap\">X medzera</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X šírka</string>\n    <string name=\"y_wdth\">Y šírka</string>\n    <string name=\"twirl\">Točte sa</string>\n    <string name=\"rubber_stmp\">Pečiatka</string>\n    <string name=\"smear\">Namazať</string>\n    <string name=\"density\">Hustota</string>\n    <string name=\"mix\">Zmiešajte</string>\n    <string name=\"sphere_lensh_distortion\">Skreslenie sférickej šošovky</string>\n    <string name=\"refraction_index\">Index lomu</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">Uhol rozpätia</string>\n    <string name=\"sparkle\">Sparkle</string>\n    <string name=\"rays\">Lúče</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">Mary</string>\n    <string name=\"autumn\">jeseň</string>\n    <string name=\"bone\">Kosť</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Zima</string>\n    <string name=\"ocean\">oceán</string>\n    <string name=\"summer\">leto</string>\n    <string name=\"spring\">jar</string>\n    <string name=\"cool_variant\">Cool Variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Ružová</string>\n    <string name=\"hot\">Horúce</string>\n    <string name=\"parula\">Slovo</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plazma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Občania</string>\n    <string name=\"twilight\">Súmrak</string>\n    <string name=\"twilight_shifted\">Súmrak posunutý</string>\n    <string name=\"auto_perspective\">Perspektíva Auto</string>\n    <string name=\"deskew\">Zošikmenie</string>\n    <string name=\"allow_crop\">Povoliť orezanie</string>\n    <string name=\"crop_or_perspective\">Plodina alebo perspektíva</string>\n    <string name=\"absolute\">Absolútna</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Deep Green</string>\n    <string name=\"lens_correction\">Korekcia šošovky</string>\n    <string name=\"target_lens_profile\">Cieľový súbor profilu objektívu vo formáte JSON</string>\n    <string name=\"download_ready_lens_profiles\">Stiahnite si hotové profily šošoviek</string>\n    <string name=\"part_percents\">Čiastkové percentá</string>\n    <string name=\"export_as_json\">Exportovať ako JSON</string>\n    <string name=\"export_as_json_sub\">Skopírujte reťazec s údajmi palety ako reprezentáciu json</string>\n    <string name=\"seam_carving\">Vyrezávanie švíkov</string>\n    <string name=\"home_screen\">Domovská obrazovka</string>\n    <string name=\"lock_screen\">Uzamknúť obrazovku</string>\n    <string name=\"built_in\">Vstavaný</string>\n    <string name=\"wallpapers_export\">Export tapiet</string>\n    <string name=\"refresh\">Obnoviť</string>\n    <string name=\"wallpapers_export_sub\">Získajte aktuálne tapety Home, Lock a Built-in</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Povoľte prístup ku všetkým súborom, je to potrebné na načítanie tapiet</string>\n    <string name=\"allow_read_media_images_for_wp\">Povolenie na správu externého úložiska nestačí, musíte povoliť prístup k svojim obrázkom, nezabudnite vybrať možnosť \\\"Povoliť všetko\\\"</string>\n    <string name=\"add_preset_to_filename\">Pridať predvoľbu k názvu súboru</string>\n    <string name=\"add_preset_to_filename_sub\">K súboru obrázka pridá príponu s vybratou predvoľbou</string>\n    <string name=\"add_image_scale_mode_to_filename\">Pridať režim mierky obrázka k názvu súboru</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">K súboru obrázka pridá príponu s vybratým režimom mierky obrázka</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Preveďte obrázok na text vo formáte ASCII, ktorý bude vyzerať ako obrázok</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Aplikuje negatívny filter na obrázok pre lepší výsledok v niektorých prípadoch</string>\n    <string name=\"processing_screenshot\">Spracovanie snímky obrazovky</string>\n    <string name=\"screenshot_not_captured_try_again\">Snímka obrazovky nebola zachytená, skúste to znova</string>\n    <string name=\"skipped_saving\">Ukladanie bolo preskočené</string>\n    <string name=\"skipped_saving_multiple\">%1$s súbory boli preskočené</string>\n    <string name=\"allow_skip_if_larger\">Povoliť preskočenie, ak je väčšie</string>\n    <string name=\"allow_skip_if_larger_sub\">Niektoré nástroje budú môcť preskočiť ukladanie obrázkov, ak by výsledná veľkosť súboru bola väčšia ako originál</string>\n    <string name=\"qr_type_calendar_event\">Udalosť kalendára</string>\n    <string name=\"qr_type_contact_info\">Kontaktovať</string>\n    <string name=\"qr_type_email\">Email</string>\n    <string name=\"qr_type_geo_point\">Poloha</string>\n    <string name=\"qr_type_phone\">Telefón</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Otvorená sieť</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefón</string>\n    <string name=\"message\">Správa</string>\n    <string name=\"address\">Adresa</string>\n    <string name=\"subject\">Predmet</string>\n    <string name=\"body\">Telo</string>\n    <string name=\"name\">Meno</string>\n    <string name=\"organization\">Organizácia</string>\n    <string name=\"title\">Názov</string>\n    <string name=\"phones\">Telefóny</string>\n    <string name=\"emails\">E-maily</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">adresy</string>\n    <string name=\"summary\">Zhrnutie</string>\n    <string name=\"description\">Popis</string>\n    <string name=\"location\">Poloha</string>\n    <string name=\"organizer\">organizátor</string>\n    <string name=\"start_date\">Dátum začiatku</string>\n    <string name=\"end_date\">Dátum ukončenia</string>\n    <string name=\"status\">Stav</string>\n    <string name=\"latitude\">Zemepisná šírka</string>\n    <string name=\"longitude\">Zemepisná dĺžka</string>\n    <string name=\"create_barcode\">Vytvorte čiarový kód</string>\n    <string name=\"edit_barcode\">Upraviť čiarový kód</string>\n    <string name=\"wifi_configuration\">Konfigurácia Wi-Fi</string>\n    <string name=\"security\">Bezpečnosť</string>\n    <string name=\"pick_contact\">Vyberte kontakt</string>\n    <string name=\"grant_contact_permission\">Udeľte kontaktom v nastaveniach povolenie na automatické dopĺňanie pomocou vybratého kontaktu</string>\n    <string name=\"contact_info\">Kontaktné údaje</string>\n    <string name=\"first_name\">Krstné meno</string>\n    <string name=\"middle_name\">Stredné meno</string>\n    <string name=\"last_name\">Priezvisko</string>\n    <string name=\"pronunciation\">Výslovnosť</string>\n    <string name=\"add_phone\">Pridať telefón</string>\n    <string name=\"add_email\">Pridať e-mail</string>\n    <string name=\"add_address\">Pridať adresu</string>\n    <string name=\"website\">webové stránky</string>\n    <string name=\"add_website\">Pridať webovú stránku</string>\n    <string name=\"formatted_name\">Formátovaný názov</string>\n    <string name=\"qr_code_top_image\">Tento obrázok sa použije na umiestnenie nad čiarový kód</string>\n    <string name=\"code_customization\">Prispôsobenie kódu</string>\n    <string name=\"qr_logo_image\">Tento obrázok bude použitý ako logo v strede QR kódu</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Výplň loga</string>\n    <string name=\"logo_size\">Veľkosť loga</string>\n    <string name=\"logo_corners\">Rohy loga</string>\n    <string name=\"fourth_eye\">Štvrté oko</string>\n    <string name=\"fourth_eye_description\">Pridá do qr kódu symetriu oka pridaním štvrtého oka do dolného rohu</string>\n    <string name=\"pixel_shape\">Tvar pixelov</string>\n    <string name=\"frame_shape\">Tvar rámu</string>\n    <string name=\"ball_shape\">Tvar lopty</string>\n    <string name=\"error_correction_level\">Úroveň opravy chýb</string>\n    <string name=\"dark_color\">Tmavá farba</string>\n    <string name=\"light_color\">Svetlá farba</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Štýl podobný Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Vzor masky</string>\n    <string name=\"code_may_be_not_scannable\">Tento kód sa nemusí dať naskenovať, zmeňte parametre vzhľadu, aby bol čitateľný na všetkých zariadeniach</string>\n    <string name=\"not_scannable\">Nedá sa skenovať</string>\n    <string name=\"launcher_mode_sub\">Nástroje budú vyzerať ako spúšťač aplikácií na domovskej obrazovke, aby boli kompaktnejšie</string>\n    <string name=\"launcher_mode\">Režim spúšťača</string>\n    <string name=\"flood_fill_sub\">Vyplní oblasť vybraným štetcom a štýlom</string>\n    <string name=\"flood_fill\">Povodňová výplň</string>\n    <string name=\"spray\">Striekajte</string>\n    <string name=\"spray_sub\">Kreslí cestu v štýle graffity</string>\n    <string name=\"square_particles\">Štvorcové častice</string>\n    <string name=\"square_particles_sub\">Častice spreja budú mať štvorcový tvar namiesto kruhov</string>\n    <string name=\"palette_tools\">Paletové nástroje</string>\n    <string name=\"palette_tools_sub\">Vygenerujte základný materiál/materiál z palety z obrázka alebo importujte/exportujte cez rôzne formáty paliet</string>\n    <string name=\"edit_palette\">Upraviť paletu</string>\n    <string name=\"edit_palette_sub\">Export/import palety v rôznych formátoch</string>\n    <string name=\"color_name\">Názov farby</string>\n    <string name=\"palette_name\">Názov palety</string>\n    <string name=\"palette_format\">Formát palety</string>\n    <string name=\"export_palette_sub\">Exportujte vygenerovanú paletu do rôznych formátov</string>\n    <string name=\"add_color_palette_sub\">Pridá novú farbu do aktuálnej palety</string>\n    <string name=\"palette_name_not_supported\">Formát %1$s nepodporuje poskytnutie názvu palety</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Vzhľadom na pravidlá Obchodu Play túto funkciu nemožno zahrnúť do aktuálnej zostavy. Ak chcete získať prístup k tejto funkcii, stiahnite si ImageToolbox z alternatívneho zdroja. Dostupné zostavy na GitHub nájdete nižšie.</string>\n    <string name=\"open_github_page\">Otvorte stránku Github</string>\n    <string name=\"overwrite_files_sub_short\">Pôvodný súbor bude nahradený novým súborom namiesto uloženia do zvoleného priečinka</string>\n    <string name=\"hidden_watermark_text_detected\">Zistil sa skrytý text vodoznaku</string>\n    <string name=\"hidden_watermark_image_detected\">Zistil sa skrytý obrázok vodoznaku</string>\n    <string name=\"this_image_was_hidden\">Tento obrázok bol skrytý</string>\n    <string name=\"generative_inpaint\">Generatívne maľovanie</string>\n    <string name=\"generative_inpaint_sub\">Umožňuje vám odstrániť objekty z obrázka pomocou modelu AI bez spoliehania sa na OpenCV. Ak chcete použiť túto funkciu, aplikácia stiahne požadovaný model (~200 MB) z GitHubu</string>\n    <string name=\"generative_inpaint_ready_sub\">Umožňuje vám odstrániť objekty z obrázka pomocou modelu AI bez spoliehania sa na OpenCV. Môže ísť o dlhotrvajúcu operáciu</string>\n    <string name=\"error_level_analysis\">Analýza úrovne chýb</string>\n    <string name=\"luminance_gradient\">Gradient jasu</string>\n    <string name=\"average_distance\">Priemerná vzdialenosť</string>\n    <string name=\"copy_move_detection\">Detekcia pohybu kopírovania</string>\n    <string name=\"retain\">Zachovať</string>\n    <string name=\"coefficent\">Koeficient</string>\n    <string name=\"clipboard_data_is_too_large\">Údaje schránky sú príliš veľké</string>\n    <string name=\"data_is_too_large_to_copy\">Údaje sú príliš veľké na kopírovanie</string>\n    <string name=\"simple_weave_pixelization\">Jednoduchá Weave Pixelizácia</string>\n    <string name=\"staggered_pixelization\">Rozložená pixelizácia</string>\n    <string name=\"cross_pixelization\">Krížová pixelizácia</string>\n    <string name=\"micro_macro_pixelization\">Mikro makro pixelizácia</string>\n    <string name=\"orbital_pixelization\">Orbitálna pixelizácia</string>\n    <string name=\"vortex_pixelization\">Vortexová pixelizácia</string>\n    <string name=\"pulse_grid_pixelization\">Pixelizácia pulznej mriežky</string>\n    <string name=\"nucleus_pixelization\">Pixelizácia jadra</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave Pixelization</string>\n    <string name=\"cannot_open_uri\">Nedá sa otvoriť UR \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Režim sneženia</string>\n    <string name=\"enabled\">Povolené</string>\n    <string name=\"border_frame\">Hraničný rám</string>\n    <string name=\"glitch_variant\">Závadový variant</string>\n    <string name=\"channel_shift\">Posun kanálov</string>\n    <string name=\"max_offset\">Maximálny posun</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Bloková chyba</string>\n    <string name=\"block_size\">Veľkosť bloku</string>\n    <string name=\"crt_curvature\">CRT zakrivenie</string>\n    <string name=\"curvature\">Zakrivenie</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Maximálny pokles</string>\n    <string name=\"ai_tools\">Nástroje AI</string>\n    <string name=\"ai_tools_sub\">Rôzne nástroje na spracovanie obrázkov prostredníctvom modelov AI, ako je odstraňovanie artefaktov alebo odšumovanie</string>\n    <string name=\"model_anime_undeint\">Kompresia, zubaté línie</string>\n    <string name=\"model_broadcast\">Karikatúry, kompresia vysielania</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Všeobecná kompresia, všeobecný šum</string>\n    <string name=\"model_wb_denoise\">Bezfarebný kreslený zvuk</string>\n    <string name=\"model_span_anime_pretrain\">Rýchla, všeobecná kompresia, všeobecný šum, animácia/komiks/anime</string>\n    <string name=\"model_book_scan\">Skenovanie knihy</string>\n    <string name=\"model_overexposure\">Korekcia expozície</string>\n    <string name=\"model_fbcnn_color_fp16\">Najlepšie pri všeobecnej kompresii, farebné obrázky</string>\n    <string name=\"model_fbcnn_gray_fp16\">Najlepšie pri všeobecnej kompresii, obrázky v odtieňoch sivej</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Všeobecná kompresia, obrázky v odtieňoch šedej, silnejšie</string>\n    <string name=\"model_scunet_color_gan_fp16\">Všeobecný šum, farebné obrázky</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Všeobecný šum, farebné obrázky, lepšie detaily</string>\n    <string name=\"model_scunet_gray_15_fp16\">Všeobecný šum, obrázky v odtieňoch šedej</string>\n    <string name=\"model_scunet_gray_25_fp16\">Všeobecný šum, obrázky v odtieňoch šedej, silnejšie</string>\n    <string name=\"model_scunet_gray_50_fp16\">Všeobecný šum, obrázky v odtieňoch šedej, najsilnejší</string>\n    <string name=\"model_jpeg_destroyer\">Všeobecná kompresia</string>\n    <string name=\"model_jaywreck\">Všeobecná kompresia</string>\n    <string name=\"model_h264\">Texturizácia, kompresia h264</string>\n    <string name=\"model_vhs\">VHS kompresia</string>\n    <string name=\"model_cinepak\">Neštandardná kompresia (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink kompresia, lepšia na geometrii</string>\n    <string name=\"model_debink_v5\">Bink kompresia, silnejšia</string>\n    <string name=\"model_debink_v6\">Bink kompresia, mäkká, zachováva detaily</string>\n    <string name=\"model_antialias\">Eliminácia schodového efektu, vyhladenie</string>\n    <string name=\"model_kdm_scans\">Naskenované umenie/kresby, mierna kompresia, moaré</string>\n    <string name=\"model_bandage\">Farebné pruhovanie</string>\n    <string name=\"model_halftone\">Pomaly, odstraňuje poltóny</string>\n    <string name=\"model_colorizer\">Všeobecný kolorizér pre obrázky v odtieňoch šedej/č. pre lepšie výsledky použite DDColor</string>\n    <string name=\"model_deedge\">Odstránenie okrajov</string>\n    <string name=\"model_desharpen\">Odstraňuje nadmerné ostrenie</string>\n    <string name=\"model_dither\">Pomaly, váhavo</string>\n    <string name=\"model_gainres\">Anti-aliasing, všeobecné artefakty, CGI</string>\n    <string name=\"model_kdm003_scans\">Spracovanie skenov KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Ľahký model na vylepšenie obrazu</string>\n    <string name=\"model_bcgone_detailed_v2\">Odstránenie artefaktov kompresie</string>\n    <string name=\"model_bcgone_smooth\">Odstránenie artefaktov kompresie</string>\n    <string name=\"model_bandage_smooth\">Odstránenie obväzu s hladkým výsledkom</string>\n    <string name=\"model_bendel_halftone\">Spracovanie poltónového vzoru</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Odstránenie vzoru rozkladu V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Odstránenie artefaktov JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Vylepšenie textúry H.264</string>\n    <string name=\"model_vhs_sharpen\">Zostrenie a vylepšenie VHS</string>\n    <string name=\"merging\">Zlučovanie</string>\n    <string name=\"chunk_size\">Veľkosť kúska</string>\n    <string name=\"overlap_size\">Veľkosť prekrytia</string>\n    <string name=\"note_chunk_info\">Obrázky väčšie ako %1$s pixlov budú rozrezané a spracované na kúsky, pričom sa tieto prekrývajú, aby sa predišlo viditeľným švom.</string>\n    <string name=\"large_chunk_warning\">Veľké veľkosti môžu spôsobiť nestabilitu zariadení nižšej kategórie</string>\n    <string name=\"select_one_to_start\">Začnite výberom jedného</string>\n    <string name=\"delete_model_sub\">Chcete odstrániť %1$s model? Budete si ho musieť stiahnuť znova</string>\n    <string name=\"confirm\">Potvrďte</string>\n    <string name=\"models\">Modelky</string>\n    <string name=\"downloaded_models\">Stiahnuté modely</string>\n    <string name=\"available_models\">Dostupné modely</string>\n    <string name=\"preparing\">Príprava</string>\n    <string name=\"active_model\">Aktívny model</string>\n    <string name=\"failed_to_open_session\">Nepodarilo sa otvoriť reláciu</string>\n    <string name=\"only_onnx_models\">Importovať je možné iba modely .onnx/.ort</string>\n    <string name=\"import_model\">Importovať model</string>\n    <string name=\"import_model_sub\">Importujte vlastný model onnx na ďalšie použitie, akceptované sú iba modely onnx/ort, podporuje takmer všetky varianty podobné esrgan</string>\n    <string name=\"imported_models\">Importované modely</string>\n    <string name=\"model_scunet_color_15_fp16\">Všeobecný hluk, farebné obrázky</string>\n    <string name=\"model_scunet_color_25_fp16\">Všeobecný šum, farebné obrázky, silnejšie</string>\n    <string name=\"model_scunet_color_50_fp16\">Všeobecný šum, farebné obrázky, najsilnejší</string>\n    <string name=\"model_artifacts_dithering_alsa\">Znižuje artefakty rozkladu a farebné pruhy, zlepšuje hladké prechody a ploché farebné oblasti.</string>\n    <string name=\"model_nmkd_brighten_redux\">Zlepšuje jas a kontrast obrazu s vyváženými svetlami pri zachovaní prirodzených farieb.</string>\n    <string name=\"model_nmkd_brighten\">Zosvetlí tmavé obrázky a zároveň zachová detaily a zabráni preexponovaniu.</string>\n    <string name=\"model_nmkd_detoon\">Odstraňuje nadmerné farebné tónovanie a obnovuje neutrálnejšiu a prirodzenú rovnováhu farieb.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Aplikuje tónovanie šumu založené na Poissonovi s dôrazom na zachovanie jemných detailov a textúr.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Aplikuje jemné tónovanie Poissonovho šumu pre hladšie a menej agresívne vizuálne výsledky.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Jednotné tónovanie šumu zamerané na zachovanie detailov a čistotu obrazu.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Jemné rovnomerné tónovanie hluku pre jemnú textúru a hladký vzhľad.</string>\n    <string name=\"model_repainter\">Opravuje poškodené alebo nerovné oblasti premaľovaním artefaktov a zlepšením konzistencie obrazu.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Ľahký model na odstraňovanie pásov, ktorý odstraňuje farebné pruhy s minimálnymi nákladmi na výkon.</string>\n    <string name=\"model_jpeg_0_20\">Optimalizuje obrázky s veľmi vysokou kompresiou artefaktov (0-20% kvalita) pre lepšiu čistotu.</string>\n    <string name=\"model_jpeg_20_40\">Vylepšuje obrázky s vysoko kompresnými artefaktmi (20-40% kvalita), obnovuje detaily a znižuje šum.</string>\n    <string name=\"model_jpeg_40_60\">Zlepšuje obrázky s miernou kompresiou (40-60% kvalita), vyvážením ostrosti a plynulosti.</string>\n    <string name=\"model_jpeg_60_80\">Spresňuje obrázky pomocou ľahkej kompresie (60 – 80 % kvalita) na vylepšenie jemných detailov a textúr.</string>\n    <string name=\"model_jpeg_80_100\">Mierne vylepšuje takmer bezstratový obraz (80 – 100 % kvalita), pričom zachováva prirodzený vzhľad a detaily.</string>\n    <string name=\"model_spongecolor_lite\">Jednoduché a rýchle kolorovanie, kreslené, nie ideálne</string>\n    <string name=\"model_deblr\">Mierne znižuje rozmazanie obrazu a zlepšuje ostrosť bez vnášania artefaktov.</string>\n    <string name=\"processing_channel\">Dlhobežné operácie</string>\n    <string name=\"processing_image\">Spracovanie obrázka</string>\n    <string name=\"processing\">Spracovanie</string>\n    <string name=\"model_artifacts_jpg_0_20\">Odstraňuje ťažké artefakty kompresie JPEG na obrázkoch s veľmi nízkou kvalitou (0 – 20 %).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Znižuje silné JPEG artefakty vo vysoko komprimovaných obrázkoch (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Vyčistí mierne JPEG artefakty pri zachovaní detailov obrazu (40 – 60 %).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Zjemňuje svetlé JPEG artefakty v pomerne vysokej kvalite obrázkov (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Jemne redukuje drobné JPEG artefakty v takmer bezstratových obrázkoch (80 – 100 %).</string>\n    <string name=\"model_redetail_v2\">Zlepšuje jemné detaily a textúry a zlepšuje vnímanú ostrosť bez ťažkých artefaktov.</string>\n    <string name=\"processing_finished\">Spracovanie ukončené</string>\n    <string name=\"processing_failed\">Spracovanie zlyhalo</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Zlepšuje textúry a detaily pokožky, pričom zachováva prirodzený vzhľad, optimalizovaný pre rýchlosť.</string>\n    <string name=\"model_sbdv_dejpeg\">Odstraňuje artefakty kompresie JPEG a obnovuje kvalitu obrazu pre komprimované fotografie.</string>\n    <string name=\"model_iso_denoise_v1\">Znižuje šum ISO na fotografiách zhotovených pri slabom osvetlení, pričom zachováva detaily.</string>\n    <string name=\"model_dejumbo\">Opravuje preexponované alebo „jumbo“ zvýraznenia a obnovuje lepšie vyváženie tónov.</string>\n    <string name=\"model_ddcolor_tiny\">Ľahký a rýchly kolorizačný model, ktorý dodáva obrázkom v odtieňoch sivej prirodzené farby.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Odhlučniť</string>\n    <string name=\"type_colorize\">Zafarbiť</string>\n    <string name=\"type_artifacts\">Artefakty</string>\n    <string name=\"type_enhance\">Vylepšiť</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Skenuje</string>\n    <string name=\"type_upscale\">Upscale</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler pre všeobecné obrázky; malý model, ktorý využíva menej GPU a času, s miernym rozmazaním a odšumovaním.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler pre všeobecné obrázky, zachovanie textúr a prirodzených detailov.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 upscaler pre všeobecné obrázky s vylepšenými textúrami a realistickými výsledkami.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler optimalizovaný pre anime obrázky; 6 blokov RRDB pre ostrejšie línie a detaily.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 upscaler so stratou MSE poskytuje hladšie výsledky a znížené artefakty pre všeobecné obrázky.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimalizovaný pre anime obrázky; Variant 4B32F s ostrejšími detailmi a hladkými líniami.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Model X4 UltraSharp V2 pre všeobecné obrázky; zdôrazňuje ostrosť a jasnosť.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; rýchlejšie a menšie, zachováva detaily pri použití menšieho množstva pamäte GPU.</string>\n    <string name=\"model_rmbg_1_4\">Ľahký model pre rýchle odstránenie pozadia. Vyvážený výkon a presnosť. Pracuje s portrétmi, objektmi a scénami. Odporúča sa pre väčšinu prípadov použitia.</string>\n    <string name=\"type_removebg\">Odstráňte BG</string>\n    <string name=\"horizontal_border_thickness\">Hrúbka horizontálneho okraja</string>\n    <string name=\"vertical_border_thickness\">Hrúbka vertikálneho okraja</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"many\">%1$s dňa</item>\n        <item quantity=\"one\">%1$s farba</item>\n        <item quantity=\"few\">%1$s farieb</item>\n        <item quantity=\"other\">%1$s farieb</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Aktuálny model nepodporuje chunking, obraz bude spracovaný v pôvodných rozmeroch, čo môže spôsobiť vysokú spotrebu pamäte a problémy s low-end zariadeniami</string>\n    <string name=\"chunking_disabled\">Chunking deaktivovaný, obrázok bude spracovaný v pôvodných rozmeroch, čo môže spôsobiť vysokú spotrebu pamäte a problémy s lacnejšími zariadeniami, ale môže poskytnúť lepšie výsledky pri odvodzovaní</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">Vysoko presný model segmentácie obrazu na odstránenie pozadia</string>\n    <string name=\"model_u2netp\">Odľahčená verzia U2Net pre rýchlejšie odstraňovanie pozadia s menšou spotrebou pamäte.</string>\n    <string name=\"model_ddcolor\">Úplný model DDColor poskytuje vysokokvalitné zafarbenie pre bežné obrázky s minimálnymi artefaktmi. Najlepšia voľba zo všetkých farebných modelov.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor vyškolené a súkromné ​​​​umelecké súbory údajov; vytvára rôznorodé a umelecké výsledky sfarbenia s menším počtom nerealistických farebných artefaktov.</string>\n    <string name=\"model_birefnet\">Ľahký model BiRefNet založený na Swin Transformer pre presné odstránenie pozadia.</string>\n    <string name=\"model_inspyrenet\">Vysokokvalitné odstránenie pozadia s ostrými hranami a vynikajúcim zachovaním detailov, najmä na zložitých objektoch a zložitých pozadiach.</string>\n    <string name=\"model_isnet\">Model odstraňovania pozadia, ktorý vytvára presné masky s hladkými okrajmi, vhodné pre bežné objekty a miernym zachovaním detailov.</string>\n    <string name=\"model_already_downloaded\">Model je už stiahnutý</string>\n    <string name=\"model_successfully_imported\">Model bol úspešne importovaný</string>\n    <string name=\"type\">Typ</string>\n    <string name=\"keyword\">Kľúčové slovo</string>\n    <string name=\"very_fast\">Veľmi rýchly</string>\n    <string name=\"normal\">Normálne</string>\n    <string name=\"slow\">Pomaly</string>\n    <string name=\"very_slow\">Veľmi pomalé</string>\n    <string name=\"compute_percents\">Vypočítajte percentá</string>\n    <string name=\"minimum_value_is\">Minimálna hodnota je %1$s</string>\n    <string name=\"warp_sub\">Skreslenie obrazu kresbou prstami</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">Tvrdosť</string>\n    <string name=\"warp_mode\">Režim Warp</string>\n    <string name=\"warp_mode_move\">Pohybujte sa</string>\n    <string name=\"warp_mode_grow\">Rast</string>\n    <string name=\"warp_mode_shrink\">Zmenšiť</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Krúžte CCW</string>\n    <string name=\"fade_strength\">Sila slabnutia</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Spodná kvapka</string>\n    <string name=\"start_drop\">Spustite aplikáciu Drop</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">Sťahovanie</string>\n    <string name=\"smooth_shapes\">Hladké tvary</string>\n    <string name=\"smooth_shapes_sub\">Pre hladšie a prirodzenejšie tvary použite superelipsy namiesto štandardných zaoblených obdĺžnikov</string>\n    <string name=\"shape_type\">Typ tvaru</string>\n    <string name=\"cut\">Vystrihnúť</string>\n    <string name=\"rounded\">Zaoblené</string>\n    <string name=\"smooth\">Hladký</string>\n    <string name=\"cut_shapes_sub\">Ostré hrany bez zaoblenia</string>\n    <string name=\"rounded_shapes_sub\">Klasické zaoblené rohy</string>\n    <string name=\"shapes_type\">Tvary Typ</string>\n    <string name=\"corners_size\">Veľkosť rohov</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Elegantné zaoblené prvky používateľského rozhrania</string>\n    <string name=\"filename_format\">Formát názvu súboru</string>\n    <string name=\"prefix_pattern_description\">Vlastný text umiestnený na samom začiatku názvu súboru, ideálny pre názvy projektov, značky alebo osobné značky.</string>\n    <string name=\"original_filename_pattern_description\">Používa pôvodný názov súboru bez prípony, čo vám pomôže zachovať identifikáciu zdroja neporušenú.</string>\n    <string name=\"width_pattern_description\">Šírka obrázka v pixeloch, užitočná na sledovanie zmien rozlíšenia alebo škálovanie výsledkov.</string>\n    <string name=\"height_pattern_description\">Výška obrázka v pixeloch, užitočná pri práci s pomermi strán alebo pri exporte.</string>\n    <string name=\"random_numbers_pattern_description\">Generuje náhodné číslice na zaručenie jedinečných názvov súborov; pridajte viac číslic pre väčšiu bezpečnosť pred duplikátmi.</string>\n    <string name=\"sequence_number_pattern_description\">Automatické počítadlo pre dávkové exporty, ideálne pri ukladaní viacerých obrázkov v jednej relácii.</string>\n    <string name=\"preset_info_pattern_description\">Vloží použitý názov predvoľby do názvu súboru, aby ste si ľahko zapamätali, ako bol obrázok spracovaný.</string>\n    <string name=\"scale_mode_pattern_description\">Zobrazuje režim zmeny mierky obrazu použitý počas spracovania, čím pomáha rozlíšiť obrázky so zmenenou veľkosťou, orezané alebo prispôsobené.</string>\n    <string name=\"suffix_pattern_description\">Vlastný text umiestnený na konci názvu súboru, užitočný pri vytváraní verzií ako _v2, _edited alebo _final.</string>\n    <string name=\"extension_pattern_description\">Prípona súboru (png, jpg, webp atď.), ktorá sa automaticky zhoduje so skutočným uloženým formátom.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Prispôsobiteľná časová pečiatka, ktorá vám umožní definovať svoj vlastný formát podľa špecifikácie Java pre dokonalé triedenie.</string>\n    <string name=\"fling_type\">Typ flingu</string>\n    <string name=\"android_native\">Android Natívne</string>\n    <string name=\"ios_style\">Štýl iOS</string>\n    <string name=\"smooth_curve\">Hladká krivka</string>\n    <string name=\"quick_stop\">Rýchle zastavenie</string>\n    <string name=\"bouncy\">Skákanie</string>\n    <string name=\"floaty\">Plávajúce</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Ultra hladké</string>\n    <string name=\"adaptive\">Adaptívny</string>\n    <string name=\"accessibility_aware\">Prístupnosť Aware</string>\n    <string name=\"reduced_motion\">Znížený pohyb</string>\n    <string name=\"android_native_sub\">Natívna fyzika posúvania systému Android</string>\n    <string name=\"smooth_sub\">Vyvážené, plynulé rolovanie pre všeobecné použitie</string>\n    <string name=\"ios_style_sub\">Vyššie trenie pri posúvaní podobnému iOS</string>\n    <string name=\"smooth_curve_sub\">Jedinečná krivka spline pre zreteľný pocit rolovania</string>\n    <string name=\"quick_stop_sub\">Presné rolovanie s rýchlym zastavením</string>\n    <string name=\"bouncy_sub\">Hravé, pohotové skákacie rolovanie</string>\n    <string name=\"floaty_sub\">Dlhé, kĺzavé rolky na prehliadanie obsahu</string>\n    <string name=\"snappy_sub\">Rýchle a citlivé posúvanie pre interaktívne používateľské rozhrania</string>\n    <string name=\"ultra_smooth_sub\">Prémiové plynulé rolovanie s predĺženou dynamikou</string>\n    <string name=\"adaptive_sub\">Upravuje fyziku na základe rýchlosti odletu</string>\n    <string name=\"accessibility_aware_sub\">Rešpektuje nastavenia prístupnosti systému</string>\n    <string name=\"reduced_motion_sub\">Minimálny pohyb pre potreby dostupnosti</string>\n    <string name=\"primary_lines\">Primárne linky</string>\n    <string name=\"primary_lines_sub\">Každý piaty riadok pridá hrubší riadok</string>\n    <string name=\"fill_color\">Farba výplne</string>\n    <string name=\"hidden_tools\">Skryté nástroje</string>\n    <string name=\"hidden_for_share\">Nástroje skryté na zdieľanie</string>\n    <string name=\"color_library\">Farebná knižnica</string>\n    <string name=\"color_library_sub\">Prezrite si rozsiahlu kolekciu farieb</string>\n    <string name=\"model_fatality_deblur\">Zaostruje a odstraňuje rozmazanie z obrázkov pri zachovaní prirodzených detailov, čo je ideálne na opravu rozostrených fotografií.</string>\n    <string name=\"model_unresize_v3\">Inteligentne obnovuje obrázky, ktorých veľkosť bola predtým zmenená, a obnovuje stratené detaily a textúry.</string>\n    <string name=\"model_liveaction_v1_span\">Optimalizované pre obsah naživo, znižuje kompresné artefakty a vylepšuje jemné detaily v snímkach filmu/televíznej relácie.</string>\n    <string name=\"model_vhs2hd_realplksr\">Konvertuje záznam v kvalite VHS na HD, odstraňuje šum na páske a zvyšuje rozlíšenie pri zachovaní vintage nádychu.</string>\n    <string name=\"model_text2hd_v1\">Špecializovaný na obrázky a snímky obrazovky s vysokým obsahom textu, zaostruje znaky a zlepšuje čitateľnosť.</string>\n    <string name=\"model_frankendata_pretrainer\">Pokročilé upscaling trénované na rôznych súboroch údajov, vynikajúce pre všeobecné vylepšenie fotografií.</string>\n    <string name=\"model_realwebphoto_v2\">Optimalizované pre fotografie komprimované na webe, odstraňuje JPEG artefakty a obnovuje prirodzený vzhľad.</string>\n    <string name=\"model_realwebphoto_v4\">Vylepšená verzia pre webové fotografie s lepším zachovaním textúry a redukciou artefaktov.</string>\n    <string name=\"model_dat_2x\">2x upscaling s technológiou Dual Aggregation Transformer, zachováva ostrosť a prirodzené detaily.</string>\n    <string name=\"model_dat_3x\">3x upscaling pomocou pokročilej architektúry transformátora, ideálne pre potreby mierneho zväčšenia.</string>\n    <string name=\"model_dat_4x\">4x vysokokvalitný upscaling s najmodernejšou sieťou transformátorov, zachováva jemné detaily vo väčších mierkach.</string>\n    <string name=\"model_nafnet_deblurring\">Odstraňuje rozmazanie/šum a chvenie z fotografií. Všeobecný účel, ale najlepšie na fotografiách.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Obnovuje obrázky nízkej kvality pomocou transformátora Swin2SR, optimalizovaného pre degradáciu BSRGAN. Skvelé na opravu ťažkých kompresných artefaktov a vylepšenie detailov v 4-násobnej mierke.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x upscaling s transformátorom SwinIR vyškoleným na degradáciu BSRGAN. Používa GAN pre ostrejšie textúry a prirodzenejšie detaily na fotografiách a zložitých scénach.</string>\n    <string name=\"path\">Cesta</string>\n    <string name=\"merge_pdf\">Zlúčiť PDF</string>\n    <string name=\"merge_pdf_sub\">Skombinujte viacero súborov PDF do jedného dokumentu</string>\n    <string name=\"files_order\">Poradie súborov</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Rozdeliť PDF</string>\n    <string name=\"split_pdf_sub\">Extrahujte konkrétne strany z dokumentu PDF</string>\n    <string name=\"rotate_pdf\">Otočiť PDF</string>\n    <string name=\"rotate_pdf_sub\">Opravte orientáciu strany natrvalo</string>\n    <string name=\"pages\">Stránky</string>\n    <string name=\"rearrange_pdf\">Preusporiadať PDF</string>\n    <string name=\"rearrange_pdf_sub\">Presuňte stránky a zmeňte ich poradie</string>\n    <string name=\"hold_drag_drop\">Podržte a potiahnite stránky</string>\n    <string name=\"page_numbers\">Čísla strán</string>\n    <string name=\"page_numbers_sub\">Automaticky pridajte číslovanie do svojich dokumentov</string>\n    <string name=\"label_format\">Formát štítku</string>\n    <string name=\"pdf_to_text\">PDF na text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extrahujte obyčajný text z dokumentov PDF</string>\n    <string name=\"watermark_pdf_sub\">Prekrytie vlastného textu pre budovanie značky alebo zabezpečenie</string>\n    <string name=\"signature\">Podpis</string>\n    <string name=\"signature_sub\">Pridajte svoj elektronický podpis do akéhokoľvek dokumentu</string>\n    <string name=\"will_be_for_signature\">Toto sa použije ako podpis</string>\n    <string name=\"unlock_pdf\">Odomknúť PDF</string>\n    <string name=\"unlock_pdf_sub\">Odstráňte heslá z chránených súborov</string>\n    <string name=\"protect_pdf\">Chráňte PDF</string>\n    <string name=\"protect_pdf_sub\">Zabezpečte svoje dokumenty silným šifrovaním</string>\n    <string name=\"success\">Úspech</string>\n    <string name=\"pdf_unlocked\">PDF je odomknuté, môžete ho uložiť alebo zdieľať</string>\n    <string name=\"repair_pdf\">Oprava PDF</string>\n    <string name=\"repair_pdf_sub\">Pokúste sa opraviť poškodené alebo nečitateľné dokumenty</string>\n    <string name=\"grayscale\">Odtiene šedej</string>\n    <string name=\"grayscale_pdf_sub\">Previesť všetky obrázky vložené do dokumentu na odtiene sivej</string>\n    <string name=\"compress_pdf\">Komprimovať PDF</string>\n    <string name=\"compress_pdf_sub\">Optimalizujte veľkosť súboru dokumentu pre jednoduchšie zdieľanie</string>\n    <string name=\"repair_info\">ImageToolbox prestavuje internú tabuľku krížových odkazov a regeneruje štruktúru súborov od začiatku. To môže obnoviť prístup k mnohým súborom, ktoré \\\\\"nemožno otvoriť\\\\\"</string>\n    <string name=\"grayscale_info\">Tento nástroj skonvertuje všetky obrázky dokumentov do odtieňov sivej. Najlepšie na tlač a zmenšenie veľkosti súboru</string>\n    <string name=\"metadata\">Metadáta</string>\n    <string name=\"metadata_pdf_sub\">Upravte vlastnosti dokumentu pre lepšie súkromie</string>\n    <string name=\"tags\">Tagy</string>\n    <string name=\"producer\">Producent</string>\n    <string name=\"author\">Autor</string>\n    <string name=\"keywords\">Kľúčové slová</string>\n    <string name=\"creator\">Tvorca</string>\n    <string name=\"privacy_deep_clean\">Ochrana osobných údajov Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Vymažte všetky dostupné metadáta pre tento dokument</string>\n    <string name=\"page\">Stránka</string>\n    <string name=\"deep_ocr\">Hlboké OCR</string>\n    <string name=\"deep_ocr_sub\">Extrahujte text z dokumentu a uložte ho do jedného textového súboru pomocou nástroja Tesseract</string>\n    <string name=\"cant_remove_all\">Nie je možné odstrániť všetky stránky</string>\n    <string name=\"remove_pages_pdf\">Odstráňte stránky PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Odstráňte konkrétne strany z dokumentu PDF</string>\n    <string name=\"tap_to_remove\">Klepnite na Odstrániť</string>\n    <string name=\"manually\">Manuálne</string>\n    <string name=\"crop_pdf\">Orezať PDF</string>\n    <string name=\"crop_pdf_sub\">Orezať strany dokumentu na ľubovoľné hranice</string>\n    <string name=\"flatten_pdf\">Vyrovnať PDF</string>\n    <string name=\"flatten_pdf_sub\">Urobte PDF nezmeniteľný rastrovaním strán dokumentu</string>\n    <string name=\"camera_failed_to_open\">Nepodarilo sa spustiť fotoaparát. Skontrolujte povolenia a uistite sa, že ho nepoužíva iná aplikácia.</string>\n    <string name=\"extract_images\">Extrahovať obrázky</string>\n    <string name=\"extract_images_sub\">Extrahujte obrázky vložené do súborov PDF v pôvodnom rozlíšení</string>\n    <string name=\"pdf_no_embedded\">Tento súbor PDF neobsahuje žiadne vložené obrázky</string>\n    <string name=\"extract_images_info\">Tento nástroj naskenuje každú stránku a obnoví zdrojové obrázky v plnej kvalite – ideálne na ukladanie originálov z dokumentov</string>\n    <string name=\"draw_signature\">Nakreslite podpis</string>\n    <string name=\"pen_params\">Parametre pera</string>\n    <string name=\"draw_signature_sub\">Použite vlastný podpis ako obrázok, ktorý sa má umiestniť na dokumenty</string>\n    <string name=\"zip_pdf\">Zip vo formáte PDF</string>\n    <string name=\"zip_pdf_sub\">Rozdeľte dokument s daným intervalom a zabaľte nové dokumenty do zip archívu</string>\n    <string name=\"interval\">Interval</string>\n    <string name=\"print_pdf\">Tlač PDF</string>\n    <string name=\"print_pdf_sub\">Pripravte dokument na tlač s vlastnou veľkosťou strany</string>\n    <string name=\"pages_per_sheet\">Počet strán na hárok</string>\n    <string name=\"orientation\">Orientácia</string>\n    <string name=\"page_size\">Veľkosť strany</string>\n    <string name=\"margin\">Marža</string>\n    <string name=\"bloom\">Bloom</string>\n    <string name=\"soft_knee\">Mäkké koleno</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimalizované pre anime a kreslené filmy. Rýchle prevzorkovanie s vylepšenými prirodzenými farbami a menším počtom artefaktov</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 ako štýl</string>\n    <string name=\"calculate_hint\">Tu zadajte základné matematické symboly na výpočet požadovanej hodnoty (napr. (5+5)*10)</string>\n    <string name=\"math_expression\">Matematický výraz</string>\n    <string name=\"pick_up_to_n_collage_images\">Vyzdvihnite až %1$s obrázkov</string>\n    <string name=\"keep_date_time\">Ponechajte dátum a čas</string>\n    <string name=\"keep_date_time_sub\">Vždy zachovávajte značky exif súvisiace s dátumom a časom, funguje nezávisle od možnosti zachovať exif</string>\n    <string name=\"background_color_for_alpha_formats\">Farba pozadia pre formáty alfa</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Pridáva možnosť nastaviť farbu pozadia pre každý formát obrázka s podporou alfa kanálov, keď je táto možnosť zakázaná, je k dispozícii iba pre iné než alfa verzie</string>\n    <string name=\"open_markup_project\">Otvorte projekt</string>\n    <string name=\"open_markup_project_sub\">Pokračujte v úpravách predtým uloženého projektu Image Toolbox</string>\n    <string name=\"markup_project_open_failed\">Nie je možné otvoriť projekt Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">Projektu Image Toolbox chýbajú projektové údaje</string>\n    <string name=\"markup_project_corrupted\">Projekt Image Toolbox je poškodený</string>\n    <string name=\"unsupported_markup_project_version\">Nepodporovaná verzia projektu Image Toolbox: %1$d</string>\n    <string name=\"save_markup_project\">Uložiť projekt</string>\n    <string name=\"save_markup_project_sub\">Uložte vrstvy, pozadie a históriu úprav do upraviteľného súboru projektu</string>\n    <string name=\"failed_to_open\">Nepodarilo sa otvoriť</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Zápis do prehľadávateľného PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Rozpoznajte text z obrázkovej dávky a uložte prehľadávateľný PDF s obrázkom a voliteľnou textovou vrstvou</string>\n    <string name=\"layer_alpha\">Vrstva alfa</string>\n    <string name=\"horizontal_flip\">Horizontálne preklopenie</string>\n    <string name=\"vertical_flip\">Vertikálne preklopenie</string>\n    <string name=\"lock\">Zámok</string>\n    <string name=\"add_shadow\">Pridajte tieň</string>\n    <string name=\"shadow_color\">Farba tieňa</string>\n    <string name=\"text_geometry\">Geometria textu</string>\n    <string name=\"text_geometry_sub\">Roztiahnutím alebo zošikmením textu dosiahnete ostrejšiu štylizáciu</string>\n    <string name=\"scale_x\">Mierka X</string>\n    <string name=\"skew_x\">Skočiť X</string>\n    <string name=\"remove_annotations\">Odstráňte anotácie</string>\n    <string name=\"remove_annotations_sub\">Odstráňte vybraté typy anotácií, ako sú prepojenia, komentáre, zvýraznenia, tvary alebo polia formulárov zo stránok PDF</string>\n    <string name=\"annotation_link\">Hypertextové odkazy</string>\n    <string name=\"annotation_file_attachment\">Prílohy súborov</string>\n    <string name=\"annotation_line\">Čiary</string>\n    <string name=\"annotation_popup\">Vyskakovacie okná</string>\n    <string name=\"annotation_stamp\">Známky</string>\n    <string name=\"annotation_shapes\">Tvary</string>\n    <string name=\"annotation_text\">Textové poznámky</string>\n    <string name=\"annotation_text_markup\">Označenie textu</string>\n    <string name=\"annotation_widget\">Polia formulára</string>\n    <string name=\"annotation_markup\">značkovanie</string>\n    <string name=\"annotation_unknown\">Neznámy</string>\n    <string name=\"annotations\">Anotácie</string>\n    <string name=\"ungroup\">Zrušiť zoskupenie</string>\n    <string name=\"add_shadow_sub\">Pridajte tieň rozostrenia za vrstvu s konfigurovateľnou farbou a posunmi</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-sr/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"restart_app\">Restart app</string>\n    <string name=\"about_app\">About app</string>\n    <string name=\"no_updates\">No poboljšati pronađen</string>\n    <string name=\"add\">Dodati</string>\n    <string name=\"images\">Image: %d</string>\n    <string name=\"reset\">Reset</string>\n    <string name=\"something_went_wrong\">Nešto ići zabluda</string>\n    <string name=\"copied\">Prepisivati na clipboard</string>\n    <string name=\"exception\">Izuzetak</string>\n    <string name=\"edit_exif\">Edit EXIF.</string>\n    <string name=\"ok\">Ok</string>\n    <string name=\"no_exif\">No EXIF podatak pronađen</string>\n    <string name=\"add_tag\">Dodati tag</string>\n    <string name=\"save\">Spremati</string>\n    <string name=\"clear\">Čist</string>\n    <string name=\"clear_exif\">Čist EXIF.</string>\n    <string name=\"cancel\">Ukidati</string>\n    <string name=\"clear_exif_sub\">All EXIF podatak of image volja biti raščišćavati, this mjera limenka ne biti undo!</string>\n    <string name=\"presets\">Presets</string>\n    <string name=\"crop\">Urod</string>\n    <string name=\"image_not_saved\">Saving</string>\n    <string name=\"image_not_saved_sub\">All unsaved mijena volja biti izgubljen, li free leave sad</string>\n    <string name=\"check_source_code\">Izvor kôd</string>\n    <string name=\"check_source_code_sub\">Dobiti the nov poboljšati, raspraviti tema a više</string>\n    <string name=\"single_edit\">Single resize</string>\n    <string name=\"single_edit_sub\">Mijena specs of single dan image</string>\n    <string name=\"pick_color\">Izabrati color</string>\n    <string name=\"pick_color_sub\">Izabrati color from image, kopija ili dio</string>\n    <string name=\"image\">Image</string>\n    <string name=\"color\">Color</string>\n    <string name=\"color_copied\">Color prepisivati</string>\n    <string name=\"crop_sub\">Urod image na any bounds</string>\n    <string name=\"version\">Inačica</string>\n    <string name=\"keep_exif\">Tvrđava EXIF.</string>\n    <string name=\"change_preview\">Mijena preview</string>\n    <string name=\"remove\">Brisati</string>\n    <string name=\"palette_sub\">Generate color paleta swatch from dan image</string>\n    <string name=\"generate_palette\">Generate paleta</string>\n    <string name=\"palette\">Paleta</string>\n    <string name=\"update\">Poboljšati</string>\n    <string name=\"no_palette\">Limenka ne generate paleta for dan image</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Izlaz folder</string>\n    <string name=\"def\">Default</string>\n    <string name=\"custom\">Običaj</string>\n    <string name=\"unspecified\">Neodređen</string>\n    <string name=\"new_version\">New inačica %1$s</string>\n    <string name=\"unsupported_type\">Unsupported tip: %1$s</string>\n    <string name=\"device_storage\">Aparat spremište</string>\n    <string name=\"by_bytes_resize\">Resize by težina</string>\n    <string name=\"max_bytes\">Max broj in KB</string>\n    <string name=\"by_bytes_resize_sub\">Resize a image following dan broj in KB</string>\n    <string name=\"compare\">Uporediti</string>\n    <string name=\"compare_sub\">Uporediti dvojica dan image</string>\n    <string name=\"pick_two_images\">Izabrati dvojica image na početak</string>\n    <string name=\"pick_images\">Izabrati image</string>\n    <string name=\"settings\">Setting</string>\n    <string name=\"night_mode\">Noć mode</string>\n    <string name=\"dark\">Dark</string>\n    <string name=\"light\">Svjetlo</string>\n    <string name=\"system\">Sustav</string>\n    <string name=\"dynamic_colors\">Dinamičan colors</string>\n    <string name=\"customization\">Customization</string>\n    <string name=\"allow_image_monet\">Odobriti image monet</string>\n    <string name=\"allow_image_monet_sub\">Li omogućivati, kada free birati a image na edit, app colors volja biti usvojiti na this image</string>\n    <string name=\"language\">Jezik</string>\n    <string name=\"amoled_mode\">Amoled mode</string>\n    <string name=\"amoled_mode_sub\">Li omogućivati podloga color volja biti pribor na apsolutan dark in noć mode</string>\n    <string name=\"color_scheme\">Color scheme</string>\n    <string name=\"color_red\">Red</string>\n    <string name=\"color_green\">Green</string>\n    <string name=\"color_blue\">Modrina</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Pasta važeći ARGB-Kôd.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Ništica na pasta</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Limenka ne mijena app color scheme while dinamičan colors biti turn on</string>\n    <string name=\"pick_accent_color\">App tema volja biti bazirati on color, which free volja select</string>\n    <string name=\"issue_tracker\">Tema tracker</string>\n    <string name=\"issue_tracker_sub\">Slati tuda bug dojava a feature zamolba</string>\n    <string name=\"help_translate\">Pomoć prevoditi</string>\n    <string name=\"help_translate_sub\">Ispravan translation greška ili localize projekt na another jezik</string>\n    <string name=\"nothing_found_by_search\">Ništica pronađen by tvoj query</string>\n    <string name=\"search_here\">Potraga tuda</string>\n    <string name=\"dynamic_colors_sub\">Li omogućivati, tadašnji app colors volja biti usvojiti na wallpaper colors</string>\n    <string name=\"primary\">Osnovan</string>\n    <string name=\"tertiary\">Tertiary</string>\n    <string name=\"secondary\">Srednji</string>\n    <string name=\"border_thickness\">Granica debljina</string>\n    <string name=\"surface\">Podloga</string>\n    <string name=\"values\">Vrednota</string>\n    <string name=\"permission\">Dozvola</string>\n    <string name=\"grant\">Grant</string>\n    <string name=\"permission_sub\">App nužda pristup na tvoj spremište na spremati image, free i neodložan, without da free moći ne rad, naime please grant dozvola on the budući dialog</string>\n    <string name=\"failed_to_save\">Zakazati na spremati %d image(s)</string>\n    <string name=\"grant_permission_manual\">App nužda this dozvola na rad, please grant free manually</string>\n    <string name=\"external_storage\">Vanjski spremište</string>\n    <string name=\"monet_colors\">Monet colors</string>\n    <string name=\"donation_sub\">This prijava i sasvim free, ali li free want to pomoć the projekt razvoj, free limenka click tuda</string>\n    <string name=\"fab_alignment\">FAB alignment</string>\n    <string name=\"check_updates\">Pregled for poboljšati</string>\n    <string name=\"check_updates_sub\">Li omogućivati, poboljšati dialog volja biti pokazati na free after app startup</string>\n    <string name=\"zoom\">Image zoom</string>\n    <string name=\"share\">Dio</string>\n    <string name=\"prefix\">Prefiks</string>\n    <string name=\"filename\">Filename</string>\n    <string name=\"smth_went_wrong\">Nešto ići zabluda: %1$s</string>\n    <string name=\"size\">Broj %1$s</string>\n    <string name=\"loading\">Loading…</string>\n    <string name=\"image_too_large_preview\">Image i odveć veliko na preview, ali free volja biti kušati na spremati free anyway</string>\n    <string name=\"pick_image\">Izabrati image na početak</string>\n    <string name=\"quality\">Svojstvo</string>\n    <string name=\"extension\">Produživanje</string>\n    <string name=\"resize_type\">Resize tip</string>\n    <string name=\"explicit\">Explicit</string>\n    <string name=\"flexible\">Fleksibilan</string>\n    <string name=\"pick_image_alt\">Izabrati mage.</string>\n    <string name=\"app_closing_sub\">Biti free tada want to close the app?</string>\n    <string name=\"app_closing\">App zatvaranje</string>\n    <string name=\"stay\">Boravak</string>\n    <string name=\"close\">Close</string>\n    <string name=\"reset_image\">Reset image</string>\n    <string name=\"reset_image_sub\">Image mijena volja biti rollback na početak vrednota</string>\n    <string name=\"values_reset\">Vrednota properly reset</string>\n    <string name=\"width\">Širina %1$s</string>\n    <string name=\"height\">Kota %1$s</string>\n    <string name=\"white_balance\">баланс беле</string>\n    <string name=\"temperature\">Температура</string>\n    <string name=\"tint\">Нијанса</string>\n    <string name=\"monochrome\">Моноцхроме</string>\n    <string name=\"highlights\">Хигхлигхтс</string>\n    <string name=\"shadows\">Сенке</string>\n    <string name=\"vibrance\">Вибранце</string>\n    <string name=\"crosshatch\">Цроссхатцх</string>\n    <string name=\"sobel_edge\">Собел едге</string>\n    <string name=\"delete_exif\">Избриши ЕКСИФ</string>\n    <string name=\"options_arrangement\">Опције аранжмана</string>\n    <string name=\"edit\">Уредити</string>\n    <string name=\"fill\">Филл</string>\n    <string name=\"light_aka_illumination\">Светлост</string>\n    <string name=\"end\">Крај</string>\n    <string name=\"kuwahara\">Кувахара смоотхинг</string>\n    <string name=\"radius\">Радијус</string>\n    <string name=\"scale\">Скала</string>\n    <string name=\"limits_resize\">Ограничења промене величине</string>\n    <string name=\"sketch\">Скица</string>\n    <string name=\"threshold\">Праг</string>\n    <string name=\"quantizationLevels\">Нивои квантизације</string>\n    <string name=\"smooth_toon\">Смоотх тоон</string>\n    <string name=\"toon\">Тоон</string>\n    <string name=\"non_maximum_suppression\">Не максимално сузбијање</string>\n    <string name=\"emoji\">Емоји</string>\n    <string name=\"stack_blur\">Стацк блур</string>\n    <string name=\"convolution3x3\">Цонволутион 3к3</string>\n    <string name=\"luminance_threshold\">Праг осветљености</string>\n    <string name=\"emoji_sub\">Изаберите који емотикони ће бити приказани на главном екрану</string>\n    <string name=\"add_file_size\">Додајте величину датотеке</string>\n    <string name=\"add_file_size_sub\">Ако је омогућено, додаје ширину и висину сачуване слике имену излазне датотеке</string>\n    <string name=\"delete_exif_sub\">Избришите ЕКСИФ метаподатке са било које пар слика</string>\n    <string name=\"image_preview_sub\">Прегледајте било коју врсту слика: ГИФ, СВГ и тако даље</string>\n    <string name=\"file_explorer_picker\">Филе екплорер</string>\n    <string name=\"photo_picker_sub\">Андроид модерни бирач фотографија који се појављује на дну екрана, може да ради само на андроиду 12+ и такође има проблема са примањем ЕКСИФ метаподатака</string>\n    <string name=\"gallery_picker_sub\">Једноставан бирач слика у галерији, радиће само ако имате ту апликацију</string>\n    <string name=\"file_explorer_picker_sub\">Користите ГетЦонтент намеру да изаберете слику, ради свуда, али такође може имати проблема са пријемом изабраних слика на неким уређајима, то није моја грешка</string>\n    <string name=\"order\">Ред</string>\n    <string name=\"order_sub\">Одређује редослед опција на главном екрану</string>\n    <string name=\"replace_sequence_number\">Замените редни број</string>\n    <string name=\"replace_sequence_number_sub\">Ако је омогућено, стандардну временску ознаку замењује редним бројем слике ако користите групну обраду</string>\n    <string name=\"load_image_from_net\">Учитај слику са мреже</string>\n    <string name=\"load_image_from_net_sub\">Учитајте било коју слику са интернета, прегледајте је, зумирајте, а такође је сачувајте или уредите ако желите</string>\n    <string name=\"no_image\">Нема слике</string>\n    <string name=\"image_link\">Слика линк</string>\n    <string name=\"fit\">Фит</string>\n    <string name=\"explicit_description\">Присилно претвара сваку слику у слику дату параметром ширине и висине - може променити однос ширине и висине</string>\n    <string name=\"flexible_description\">Промена величине слика на слике са дугачком страном датом параметром ширине или висине, сви прорачуни величине ће се обавити након чувања - задржава однос ширине и висине</string>\n    <string name=\"brightness\">Осветљеност</string>\n    <string name=\"contrast\">Контраст</string>\n    <string name=\"hue\">Нијанса</string>\n    <string name=\"saturation\">Засићење</string>\n    <string name=\"add_filter\">Додајте филтер</string>\n    <string name=\"filter\">Филтер</string>\n    <string name=\"filter_sub\">Примените било који ланац филтера на дате слике</string>\n    <string name=\"filters\">Филтери</string>\n    <string name=\"color_filter\">Филтер у боји</string>\n    <string name=\"alpha\">Алпха</string>\n    <string name=\"exposure\">Изложеност</string>\n    <string name=\"gamma\">Гама</string>\n    <string name=\"highlights_shadows\">Нагласци и сенке</string>\n    <string name=\"haze\">Хазе</string>\n    <string name=\"effect\">Ефекат</string>\n    <string name=\"distance\">Удаљеност</string>\n    <string name=\"slope\">Нагиб</string>\n    <string name=\"sharpen\">Схарпен</string>\n    <string name=\"sepia\">Сепиа</string>\n    <string name=\"negative\">Негативно</string>\n    <string name=\"solarize\">Соларизуј</string>\n    <string name=\"black_and_white\">Црно и бело</string>\n    <string name=\"spacing\">Размак</string>\n    <string name=\"line_width\">Ширина линије</string>\n    <string name=\"blur\">Блур</string>\n    <string name=\"halftone\">Полутон</string>\n    <string name=\"cga_colorspace\">ГЦА простор боја</string>\n    <string name=\"gaussian_blur\">Гаусово замућење</string>\n    <string name=\"box_blur\">Замућење кутије</string>\n    <string name=\"bilaterial_blur\">Двострано замућење</string>\n    <string name=\"emboss\">Ембосс</string>\n    <string name=\"laplacian\">Лапласов</string>\n    <string name=\"vignette\">Вињета</string>\n    <string name=\"start\">Почетак</string>\n    <string name=\"distortion\">Дисторзија</string>\n    <string name=\"angle\">Угао</string>\n    <string name=\"swirl\">Свирл</string>\n    <string name=\"bulge\">Булге</string>\n    <string name=\"dilation\">Дилатација</string>\n    <string name=\"sphere_refraction\">Рефракција сфере</string>\n    <string name=\"refractive_index\">Индекс преламања</string>\n    <string name=\"glass_sphere_refraction\">Рефракција стаклене сфере</string>\n    <string name=\"color_matrix\">Матрица боја</string>\n    <string name=\"opacity\">Непрозирност</string>\n    <string name=\"limits_resize_sub\">Промените величину дате слике да бисте пратили дате границе ширине и висине уз чување односа ширине и висине</string>\n    <string name=\"posterize\">Постеризе</string>\n    <string name=\"weak_pixel_inclusion\">Слабо укључивање пиксела</string>\n    <string name=\"lookup\">Потражити</string>\n    <string name=\"rgb_filter\">РГБ филтер</string>\n    <string name=\"false_color\">Лажна боја</string>\n    <string name=\"first_color\">Прва боја</string>\n    <string name=\"second_color\">Друга боја</string>\n    <string name=\"reorder\">Реордер</string>\n    <string name=\"fast_blur\">Брзо замућење</string>\n    <string name=\"blur_size\">Величина замућења</string>\n    <string name=\"blur_center_x\">Центар замућења к</string>\n    <string name=\"blur_center_y\">Замагљивање центар и</string>\n    <string name=\"zoom_blur\">Зоом блур</string>\n    <string name=\"color_balance\">Баланс боја</string>\n    <string name=\"image_preview\">Преглед слике</string>\n    <string name=\"image_source\">Извор слике</string>\n    <string name=\"photo_picker\">Бирач фотографија</string>\n    <string name=\"gallery_picker\">Галерија</string>\n    <string name=\"content_scale\">Скала садржаја</string>\n    <string name=\"emojis_count\">Емоџији се рачунају</string>\n    <string name=\"sequence_num\">секвенцаНум</string>\n    <string name=\"original_filename\">оригиналФиленаме</string>\n    <string name=\"add_original_filename\">Додајте оригинално име датотеке</string>\n    <string name=\"add_original_filename_sub\">Ако је омогућено, додаје оригинално име датотеке у име излазне слике</string>\n    <string name=\"filename_not_work_with_photopicker\">Додавање оригиналног назива датотеке не функционише ако је изабран извор слике за бирач фотографија</string>\n    <string name=\"draw\">Драв</string>\n    <string name=\"file_size\">Величина фајла</string>\n    <string name=\"file_proceed\">Фајл обрађен</string>\n    <string name=\"file_size_sub\">Максимална величина датотеке је ограничена Андроид ОС-ом и доступном меморијом, што очигледно зависи од вашег уређаја. \\nИмајте на уму: меморија није складиште.</string>\n    <string name=\"cache\">Цацхе</string>\n    <string name=\"paint_color\">Боја боје</string>\n    <string name=\"paint_alpha\">Паинт алпха</string>\n    <string name=\"draw_on_image_sub\">Изаберите слику и нацртајте нешто на њој</string>\n    <string name=\"pick_file_to_start\">Изаберите датотеку за почетак</string>\n    <string name=\"encryption\">Шифровање</string>\n    <string name=\"key\">Кључ</string>\n    <string name=\"implementation\">Имплементација</string>\n    <string name=\"compatibility\">Компатибилност</string>\n    <string name=\"features_sub\">Шифровање датотека на основу лозинке. Настављене датотеке се могу чувати у изабраном директоријуму или делити. Дешифроване датотеке се такође могу директно отворити.</string>\n    <string name=\"cache_size\">Величина кеша</string>\n    <string name=\"found_s\">Пронађено %1$s</string>\n    <string name=\"tools\">Алати</string>\n    <string name=\"fallback_option\">Резервна опција</string>\n    <string name=\"skip\">Скип</string>\n    <string name=\"invalid_password_or_not_encrypted\">Неважећа лозинка или изабрана датотека није шифрована</string>\n    <string name=\"decryption\">Дешифровање</string>\n    <string name=\"screenshot\">Снимак екрана</string>\n    <string name=\"draw_sub\">Цртајте на слици као у књизи за цртање или цртајте по самој позадини</string>\n    <string name=\"compatibility_sub\">Имајте на уму да компатибилност са другим софтвером или услугама за шифровање датотека није загарантована. Нешто другачији третман кључа или конфигурација шифре могу бити разлози за некомпатибилност.</string>\n    <string name=\"draw_on_image\">Цртајте на слици</string>\n    <string name=\"draw_on_background\">Цртајте на позадини</string>\n    <string name=\"draw_on_background_sub\">Изаберите боју позадине и нацртајте на њој</string>\n    <string name=\"background_color\">Боја позадине</string>\n    <string name=\"cipher\">Ципхер</string>\n    <string name=\"auto_cache_clearing\">Аутоматско брисање кеша</string>\n    <string name=\"auto_cache_clearing_sub\">Ако је омогућена, кеш апликације ће бити обрисан при покретању апликације</string>\n    <string name=\"edit_screenshot\">Уредите снимак екрана</string>\n    <string name=\"secondary_customization\">Секундарно прилагођавање</string>\n    <string name=\"copy\">Копирај</string>\n    <string name=\"warning_bytes\">Чување у режиму %1$s може бити нестабилно, јер је формат без губитака</string>\n    <string name=\"image_size_warning\">Покушај да сачувате слику са датом ширином и висином може изазвати ООМ грешку, урадите то на сопствену одговорност и немојте рећи да вас нисам упозорио!</string>\n    <string name=\"group_options_by_type\">Групирајте опције по типу</string>\n    <string name=\"group_options_by_type_sub\">Групе опције на главном екрану њиховог типа уместо прилагођеног распореда листе</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Није могуће променити распоред док је груписање опција омогућено</string>\n    <string name=\"activate_files\">Онемогућили сте апликацију Датотеке, активирајте је да бисте користили ову функцију</string>\n    <string name=\"cipher_sub\">Шифрујте и дешифрујте било коју датотеку (не само слику) на основу АЕС крипто алгоритма</string>\n    <string name=\"pick_file\">Изаберите датотеку</string>\n    <string name=\"encrypt\">Шифруј</string>\n    <string name=\"decrypt\">Дешифрујте</string>\n    <string name=\"store_file_desc\">Сачувајте ову датотеку на свом уређају или користите акцију дељења да бисте је ставили где год желите</string>\n    <string name=\"features\">Карактеристике</string>\n    <string name=\"implementation_sub\">АЕС-256, ГЦМ режим, без допуна, 12 бајтова насумичних ИВ. Кључеви се користе као СХА-3 хеш (256 бита).</string>\n    <string name=\"create\">Креирај</string>\n    <string name=\"enhanced_pixelation\">Енханцед Пикелатион</string>\n    <string name=\"stroke_pixelation\">Строке Пикелатион</string>\n    <string name=\"enhanced_diamond_pixelation\">Побољшана дијамантска пикселација</string>\n    <string name=\"draw_mode\">Режим цртања</string>\n    <string name=\"channel_shift_x\">Померање канала Кс</string>\n    <string name=\"tent_blur\">Тент Блур</string>\n    <string name=\"email\">Емаил</string>\n    <string name=\"draw_arrows\">Цртање стрелица</string>\n    <string name=\"restore_image\">Врати слику</string>\n    <string name=\"auto_erase_background\">Аутоматско брисање позадине</string>\n    <string name=\"emotions\">Емоције</string>\n    <string name=\"pipette\">Пипета</string>\n    <string name=\"text\">Текст</string>\n    <string name=\"delete_color_scheme_title\">Избриши шему</string>\n    <string name=\"updates\">Ажурирања</string>\n    <string name=\"segmentation_mode_osd_only\">Оријентација &amp; Само откривање скрипте</string>\n    <string name=\"segmentation_mode_single_column\">Сингле Цолумн</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Вертикални текст у једном блоку</string>\n    <string name=\"segmentation_mode_single_word\">Једна реч</string>\n    <string name=\"segmentation_mode_raw_line\">Сирова линија</string>\n    <string name=\"glitch\">Квар</string>\n    <string name=\"amount\">Износ</string>\n    <string name=\"seed\">Семе</string>\n    <string name=\"anaglyph\">Анаглиф</string>\n    <string name=\"noise\">Бука</string>\n    <string name=\"pixel_sort\">Пикел Сорт</string>\n    <string name=\"drago\">Драго</string>\n    <string name=\"aldridge\">Алдридге</string>\n    <string name=\"cutoff\">Одрезати</string>\n    <string name=\"uchimura\">Уцхимура</string>\n    <string name=\"mobius\">Мобиус</string>\n    <string name=\"transition\">Прелаз</string>\n    <string name=\"peak\">Пеак</string>\n    <string name=\"color_anomaly\">Аномалија боја</string>\n    <string name=\"no_such_directory\">Није пронађен директоријум \\\"%1$s\\\", пребацили смо га на подразумевани, сачувајте датотеку поново</string>\n    <string name=\"clipboard\">Цлипбоард</string>\n    <string name=\"auto_pin\">Ауто пин</string>\n    <string name=\"auto_pin_sub\">Аутоматски додаје сачувану слику у међуспремник ако је омогућено</string>\n    <string name=\"overwrite_files\">Оверврите Филес</string>\n    <string name=\"overwrite_files_sub\">Оригинална датотека ће бити замењена новом уместо чувања у изабраном фолдеру, ова опција треба да извор слике буде \\\"Екплорер\\\" или ГетЦонтент, када ово пребаците, аутоматски ће бити подешена</string>\n    <string name=\"search_option\">Претрага</string>\n    <string name=\"free\">бесплатно</string>\n    <string name=\"create_issue\">Цреате Иссуе</string>\n    <string name=\"presets_sub\" formatted=\"false\">Ако сте изабрали унапред подешено 125, слика ће бити сачувана као 125% величине оригиналне слике са 100% квалитетом. Ако изаберете унапред подешено 50, слика ће бити сачувана са 50% величине и 50% квалитета.</string>\n    <string name=\"presets_sub_bytes\">Пресет овде одређује % излазне датотеке, тј. ако изаберете унапред подешено 50 на слици од 5мб онда ћете након чувања добити слику од 2,5мб</string>\n    <string name=\"randomize_filename_sub\">Ако је омогућено излазно име датотеке ће бити потпуно насумично</string>\n    <string name=\"saved_to\">Сачувано у фолдеру %1$s са именом %2$s</string>\n    <string name=\"saved_to_without_filename\">Сачувано у фолдеру %1$s</string>\n    <string name=\"tg_chat\">Телеграм ћаскање</string>\n    <string name=\"backup_and_restore\">Прављење резервних копија и враћање</string>\n    <string name=\"tg_chat_sub\">Разговарајте о апликацији и добијте повратне информације од других корисника. Такође можете добити бета ажурирања и увиде овде.</string>\n    <string name=\"crop_mask\">Цроп маск</string>\n    <string name=\"aspect_ratio\">Однос ширине и висине</string>\n    <string name=\"image_crop_mask_sub\">Користите овај тип маске да креирате маску од дате слике, приметите да ТРЕБА да има алфа канал</string>\n    <string name=\"backup\">Бацкуп</string>\n    <string name=\"restore\">Ресторе</string>\n    <string name=\"backup_sub\">Направите резервну копију подешавања апликације у датотеку</string>\n    <string name=\"restore_sub\">Вратите подешавања апликације из претходно генерисане датотеке</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Оштећена датотека или није резервна копија</string>\n    <string name=\"settings_restored\">Подешавања су успешно враћена</string>\n    <string name=\"contact_me\">Контактирај ме</string>\n    <string name=\"reset_settings_sub\">Ово ће вратити ваша подешавања на подразумеване вредности. Имајте на уму да ово не може да се поништи без горе поменуте резервне копије.</string>\n    <string name=\"delete\">Избриши</string>\n    <string name=\"delete_color_scheme_warn\">Спремате се да избришете изабрану шему боја. Ова операција се не може опозвати</string>\n    <string name=\"font\">Фонт</string>\n    <string name=\"font_scale\">Скала фонта</string>\n    <string name=\"defaultt\">Уобичајено</string>\n    <string name=\"using_large_fonts_warn\">Коришћење великих размера фонта може да изазове грешке у корисничком интерфејсу и проблеме, који се неће поправити. Користите опрезно.</string>\n    <string name=\"alphabet_and_numbers\">Аа Бб Вв Гг Дд Ђђ Ее Жж Зз Ии Јј Кк Лл Љљ Мм Нн Њњ Оо Пп Рр Сс Тт Ћћ Уу Фф Хх Цц Чч Џџ Шш 0123456789 !?</string>\n    <string name=\"food_and_drink\">Храна и пиће</string>\n    <string name=\"nature_and_animals\">Природа и животиње</string>\n    <string name=\"symbols\">Симболи</string>\n    <string name=\"enable_emoji\">Омогући емоџи</string>\n    <string name=\"travels_and_places\">Путовања и места</string>\n    <string name=\"activities\">Активности</string>\n    <string name=\"trim_image\">Трим имаге</string>\n    <string name=\"keep_exif_sub\">Оригинални метаподаци слике ће бити сачувани</string>\n    <string name=\"trim_image_sub\">Прозирни простори око слике ће бити исечени</string>\n    <string name=\"erase_mode\">Режим брисања</string>\n    <string name=\"erase_background\">Обриши позадину</string>\n    <string name=\"restore_background\">Врати позадину</string>\n    <string name=\"blur_radius\">Радијус замућења</string>\n    <string name=\"something_went_wrong_emphasis\">Упс… Нешто је пошло наопако. Можете ми писати користећи опције испод и ја ћу покушати да пронађем решење</string>\n    <string name=\"resize_and_convert_sub\">Промените величину датих слика или их конвертујте у друге формате. ЕКСИФ метаподаци се такође могу уређивати овде ако одаберете једну слику.</string>\n    <string name=\"crashlytics_sub\">Ово омогућава апликацији да ручно прикупља извештаје о паду</string>\n    <string name=\"analytics\">Аналитика</string>\n    <string name=\"analytics_sub\">Дозволи прикупљање анонимне статистике коришћења апликације</string>\n    <string name=\"image_exif_warning\">Тренутно формат %1$s дозвољава само читање ЕКСИФ метаподатака на андроид-у. Излазна слика уопште неће имати метаподатке када се сачува.</string>\n    <string name=\"effort\">Напор</string>\n    <string name=\"effort_sub\">Вредност %1$s значи брзу компресију, што резултира релативно великом величином датотеке. %2$s значи спорију компресију, што резултира мањом датотеком.</string>\n    <string name=\"saving_almost_complete\">Чување је скоро завршено. Ако сада откажете, поново ћете морати да сачувате.</string>\n    <string name=\"allow_betas\">Дозволи бета верзије</string>\n    <string name=\"draw_arrows_sub\">Ако је омогућено, путања за цртање ће бити представљена као показивачка стрелица</string>\n    <string name=\"allow_betas_sub\">Провера ажурирања ће укључити бета верзије апликације ако је омогућена</string>\n    <string name=\"brush_softness\">Мекоћа четкице</string>\n    <string name=\"donation\">Донација</string>\n    <string name=\"pick_at_least_two_images\">Изаберите најмање 2 слике</string>\n    <string name=\"output_image_scale\">Скала излазне слике</string>\n    <string name=\"image_orientation\">Оријентација слике</string>\n    <string name=\"horizontal\">Хоризонтално</string>\n    <string name=\"vertical\">Вертикала</string>\n    <string name=\"scale_small_images_to_large\">Скалирајте мале слике на велике</string>\n    <string name=\"scale_small_images_to_large_sub\">Мале слике ће бити скалиране на највећу у низу ако је омогућено</string>\n    <string name=\"images_order\">Редослед слика</string>\n    <string name=\"blur_edges\">Замагљивање ивица</string>\n    <string name=\"blur_edges_sub\">Црта замућене ивице испод оригиналне слике да попуни просторе око ње уместо једне боје ако је омогућено</string>\n    <string name=\"neutral\">Неутрално</string>\n    <string name=\"vibrant\">Вибрант</string>\n    <string name=\"pixelation\">Пикселација</string>\n    <string name=\"enhanced_circle_pixelation\">Побољшана кружна пикселација</string>\n    <string name=\"remove_color\">Уклони боју</string>\n    <string name=\"recode\">Рецоде</string>\n    <string name=\"palette_style\">Палетте стиле</string>\n    <string name=\"tonal_spot\">Тонал Спот</string>\n    <string name=\"expressive\">Експресивно</string>\n    <string name=\"rainbow\">Раинбов</string>\n    <string name=\"fruit_salad\">Воћна салата</string>\n    <string name=\"fidelity\">Верност</string>\n    <string name=\"tonal_spot_sub\">Подразумевани стил палете, омогућава прилагођавање све четири боје, друге вам омогућавају да подесите само кључну боју</string>\n    <string name=\"neutral_sub\">Стил који је мало више хроматичан од монохроматског</string>\n    <string name=\"content\">Садржај</string>\n    <string name=\"vibrant_sub\">Гласна тема, шареност је максимална за Примари палету, повећана за друге</string>\n    <string name=\"playful_scheme\">Разиграна тема - нијанса изворне боје се не појављује у теми</string>\n    <string name=\"highlighter\">Хигхлигхтер</string>\n    <string name=\"both\">И једно и друго</string>\n    <string name=\"search_option_sub\">Омогућава могућност претраживања свих доступних опција на главном екрану</string>\n    <string name=\"preview_pdf_sub\">Једноставан ПДФ преглед</string>\n    <string name=\"pdf_to_images_sub\">Претворите ПДФ у слике у датом излазном формату</string>\n    <string name=\"images_to_pdf_sub\">Спакујте дате слике у излазну ПДФ датотеку</string>\n    <string name=\"mask_filter\">Филтер маске</string>\n    <string name=\"mask_filter_sub\">Примените ланце филтера на дате маскиране области, свака област маске може да одреди сопствени сет филтера</string>\n    <string name=\"masks\">Маске</string>\n    <string name=\"add_mask\">Додајте маску</string>\n    <string name=\"mask_indexed\">маска %d</string>\n    <string name=\"delete_mask_warn\">Спремате се да избришете изабрану маску филтера. Ова операција се не може опозвати</string>\n    <string name=\"delete_mask\">Обриши маску</string>\n    <string name=\"end_position\">Крај</string>\n    <string name=\"simple_variants\">Једноставне варијанте</string>\n    <string name=\"neon\">Неон</string>\n    <string name=\"pen\">Хемијска оловка</string>\n    <string name=\"privacy_blur\">Приваци Блур</string>\n    <string name=\"neon_sub\">Додајте неки сјајни ефекат својим цртежима</string>\n    <string name=\"pen_sub\">Подразумевано, најједноставније - само боја</string>\n    <string name=\"privacy_blur_sub\">Замагљује слику испод нацртане путање да бисте заштитили све што желите да сакријете</string>\n    <string name=\"pixelation_sub\">Слично замућењу приватности, али пикселира уместо замагљивања</string>\n    <string name=\"sliders_shadow_sub\">Омогућава цртање сенке иза клизача</string>\n    <string name=\"switches_shadow_sub\">Омогућава цртање сенки иза прекидача</string>\n    <string name=\"fabs_shadow_sub\">Омогућава цртање сенке иза плутајућих акционих дугмади</string>\n    <string name=\"buttons_shadow_sub\">Омогућава цртање сенке иза подразумеваних дугмади</string>\n    <string name=\"app_bars_shadow_sub\">Омогућава цртање сенке иза трака апликације</string>\n    <string name=\"double_arrow\">Доубле Арров</string>\n    <string name=\"line_sub\">Црта путању од почетне до крајње тачке као права</string>\n    <string name=\"line_arrow_sub\">Црта стрелицу која показује од почетне до крајње тачке као линију</string>\n    <string name=\"vibration\">Вибрације</string>\n    <string name=\"vibration_strength\">Вибратион Стренгтх</string>\n    <string name=\"overwrite_file_requirements\">Да бисте заменили датотеке потребно је да користите извор слике \\\"Екплорер\\\", покушајте да поново изаберете слике, променили смо извор слике у потребан</string>\n    <string name=\"empty\">Празан</string>\n    <string name=\"suffix\">Суфикс</string>\n    <string name=\"catmull\">Цатмулл</string>\n    <string name=\"bicubic\">Бицубиц</string>\n    <string name=\"basic\">Басиц</string>\n    <string name=\"basic_sub\">Најједноставнији Андроид режим скалирања који се користи у скоро свим апликацијама</string>\n    <string name=\"catmull_sub\">Метода за глатку интерполацију и поновно узорковање скупа контролних тачака, који се обично користи у компјутерској графици за креирање глатких кривих</string>\n    <string name=\"bilinear_sub\">Линеарна (или билинеарна, у две димензије) интерполација је типично добра за промену величине слике, али узрокује неко нежељено омекшавање детаља и још увек може бити донекле назубљена</string>\n    <string name=\"bicubic_sub\">Боље методе скалирања укључују Ланчосово поновно узорковање и Митцхелл-Нетравали филтере</string>\n    <string name=\"nearest_sub\">Један од једноставнијих начина повећања величине, замена сваког пиксела са бројем пиксела исте боје</string>\n    <string name=\"hermite_sub\">Техника математичке интерполације која користи вредности и деривате на крајњим тачкама сегмента криве да генерише глатку и континуирану криву</string>\n    <string name=\"hann_sub\">Функција прозора се често примењује у обради сигнала да би се смањило спектрално цурење и побољшала тачност анализе фреквенције сужавањем ивица сигнала</string>\n    <string name=\"magnifier_sub\">Омогућава лупу на врху прста у режимима цртања ради боље приступачности</string>\n    <string name=\"lanczos_sub\">Метода поновног узорковања која одржава интерполацију високог квалитета применом пондерисане синк функције на вредности пиксела</string>\n    <string name=\"spline_sub\">Користи полиномске функције дефинисане по комадима за глатку интерполацију и апроксимацију криве или површине, флексибилно и континуирано представљање облика</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Форсира екиф виџет да се прво провери</string>\n    <string name=\"allow_multiple_languages\">Дозволи више језика</string>\n    <string name=\"segmentation_mode_auto_osd\">Аутоматска оријентација &amp; Детекција скрипте</string>\n    <string name=\"segmentation_mode_auto_only\">Само аутоматски</string>\n    <string name=\"segmentation_mode_auto\">Ауто</string>\n    <string name=\"segmentation_mode_single_block\">Појединачни блок</string>\n    <string name=\"segmentation_mode_single_line\">Једна линија</string>\n    <string name=\"segmentation_mode_circle_word\">Заокружи реч</string>\n    <string name=\"segmentation_mode_single_char\">Сингле цхар</string>\n    <string name=\"segmentation_mode_sparse_text\">Ретки текст</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Оријентација ретког текста &amp; Откривање скрипте</string>\n    <string name=\"delete_language_sub\">Да ли желите да избришете језик \\\"%1$s\\\" ОЦР податке о обуци за све типове препознавања или само за изабрани (%2$s)?</string>\n    <string name=\"tile_mode_decal\">Децал</string>\n    <string name=\"color_stops\">Боја зауставља</string>\n    <string name=\"add_color\">Додај боју</string>\n    <string name=\"properties\">Својства</string>\n    <string name=\"repeat_watermark_sub\">Понавља водени жиг преко слике уместо појединачног на датој позицији</string>\n    <string name=\"watermarking_sub\">Покријте слике са прилагодљивим воденим жиговима за текст/слику</string>\n    <string name=\"offset_x\">Оффсет Кс</string>\n    <string name=\"offset_y\">Оффсет И</string>\n    <string name=\"watermark_type\">Ватермарк Типе</string>\n    <string name=\"watermarking_image_sub\">Ова слика ће се користити као образац за водени жиг</string>\n    <string name=\"text_color\">Боја текста</string>\n    <string name=\"use_size_of_first_frame\">Користите величину првог кадра</string>\n    <string name=\"use_size_of_first_frame_sub\">Замените наведену величину димензијама првог оквира</string>\n    <string name=\"repeat_count\">Репеат Цоунт</string>\n    <string name=\"frame_delay\">Фраме Делаи</string>\n    <string name=\"millis\">миллис</string>\n    <string name=\"fps\">ФПС</string>\n    <string name=\"bayer_three_dithering\">Баиер Тхрее Би Тхрее Дитхеринг</string>\n    <string name=\"bayer_four_dithering\">Баиер Фоур Би Фоур Дитхеринг</string>\n    <string name=\"bayer_eight_dithering\">Баиер Еигхт Би Еигхт Дитхеринг</string>\n    <string name=\"floyd_steinberg_dithering\">Флоид Стеинберг Дитхеринг</string>\n    <string name=\"native_stack_blur\">Нативе Стацк Блур</string>\n    <string name=\"tilt_shift\">Тилт Схифт</string>\n    <string name=\"shuffle\">мешање</string>\n    <string name=\"enhanced_glitch\">Енханцед Глитцх</string>\n    <string name=\"channel_shift_y\">Померање канала И</string>\n    <string name=\"corruption_size\">Величина корупције</string>\n    <string name=\"corruption_shift_x\">Корупција Схифт Кс</string>\n    <string name=\"corruption_shift_y\">Корупција Схифт И</string>\n    <string name=\"side_fade\">Сиде Фаде</string>\n    <string name=\"side\">Сиде</string>\n    <string name=\"top\">Врх</string>\n    <string name=\"bottom\">Дно</string>\n    <string name=\"strength\">Снага</string>\n    <string name=\"marble\">Мермер</string>\n    <string name=\"turbulence\">Турбуленција</string>\n    <string name=\"frequency_y\">Учесталост И</string>\n    <string name=\"amplitude_x\">Амплитуда Кс</string>\n    <string name=\"aces_hill_tone_mapping\">АЦЕС Хилл Тоне Маппинг</string>\n    <string name=\"hable_filmic_tone_mapping\">Хабле Филмиц Тоне Маппинг</string>\n    <string name=\"heji_burgess_tone_mapping\">Хејл Бургесс Тоне Маппинг</string>\n    <string name=\"color_matrix_4x4\">Цолор Матрик 4к4</string>\n    <string name=\"color_matrix_3x3\">Цолор Матрик 3к3</string>\n    <string name=\"simple_effects\">Симпле Еффецтс</string>\n    <string name=\"vintage\">Берба</string>\n    <string name=\"coda_chrome\">Цода Цхроме</string>\n    <string name=\"polaroid\">Полароид</string>\n    <string name=\"tritonomaly\">Тритономалија</string>\n    <string name=\"deutaromaly\">Деутаромалија</string>\n    <string name=\"protonomaly\">Протономалија</string>\n    <string name=\"night_vision\">Ноћна визија</string>\n    <string name=\"warm\">Топло</string>\n    <string name=\"cool\">Хладан</string>\n    <string name=\"tritanopia\">Тританопиа</string>\n    <string name=\"unsharp\">Унсхарп</string>\n    <string name=\"pastel\">Пастел</string>\n    <string name=\"orange_haze\">Оранге Хазе</string>\n    <string name=\"pink_dream\">Пинк Дреам</string>\n    <string name=\"golden_hour\">Златни сат</string>\n    <string name=\"hot_summer\">Топло лето</string>\n    <string name=\"purple_mist\">Пурпле Мист</string>\n    <string name=\"sunrise\">излазак Сунца</string>\n    <string name=\"colorful_swirl\">Цолорфул Свирл</string>\n    <string name=\"soft_spring_light\">Софт Спринг Лигхт</string>\n    <string name=\"autumn_tones\">Аутумн Тонес</string>\n    <string name=\"lavender_dream\">Лаванда Дреам</string>\n    <string name=\"cyberpunk\">Циберпунк</string>\n    <string name=\"lemonade_light\">Лемонаде Лигхт</string>\n    <string name=\"spectral_fire\">Спецтрал Фире</string>\n    <string name=\"night_magic\">Нигхт Магиц</string>\n    <string name=\"fantasy_landscape\">Фантаси Ландсцапе</string>\n    <string name=\"color_explosion\">Експлозија боје</string>\n    <string name=\"electric_gradient\">Елецтриц Градиент</string>\n    <string name=\"caramel_darkness\">Царамел Даркнесс</string>\n    <string name=\"futuristic_gradient\">Футуристички градијент</string>\n    <string name=\"digital_code\">Дигитал Цоде</string>\n    <string name=\"icon_shape\">Облик иконе</string>\n    <string name=\"images_overwritten\">Слике су преписане на оригиналном одредишту</string>\n    <string name=\"cannot_change_image_format\">Није могуће променити формат слике док је омогућена опција преписивања датотека</string>\n    <string name=\"emoji_as_color_scheme\">Емоџи као шема боја</string>\n    <string name=\"emoji_as_color_scheme_sub\">Користи примарну боју емоџија као шему боја апликације уместо ручно дефинисане</string>\n    <string name=\"objects\">Објекти</string>\n    <string name=\"background_remover\">Уклањање позадине</string>\n    <string name=\"background_remover_sub\">Уклоните позадину са слике цртањем или користите опцију Ауто</string>\n    <string name=\"resize_and_convert\">Промени величину и претвори</string>\n    <string name=\"diamond_pixelation\">Диамонд Пикелатион</string>\n    <string name=\"circle_pixelation\">Цирцле Пикелатион</string>\n    <string name=\"replace_color\">Замените боју</string>\n    <string name=\"tolerance\">Толеранција</string>\n    <string name=\"color_to_replace\">Боја за замену</string>\n    <string name=\"target_color\">Таргет Цолор</string>\n    <string name=\"color_to_remove\">Боја за уклањање</string>\n    <string name=\"erode\">Ероде</string>\n    <string name=\"anisotropic_diffusion\">Анизотропна дифузија</string>\n    <string name=\"diffusion\">Дифузија</string>\n    <string name=\"conduction\">Спровођење</string>\n    <string name=\"horizontal_wind_stagger\">Хоризонтално тетурање ветра</string>\n    <string name=\"fast_bilaterial_blur\">Брзо двострано замућење</string>\n    <string name=\"poisson_blur\">Поиссон Блур</string>\n    <string name=\"logarithmic_tone_mapping\">Логаритамско пресликавање тонова</string>\n    <string name=\"crystallize\">Кристализуј</string>\n    <string name=\"stroke_color\">Строке Цолор</string>\n    <string name=\"fractal_glass\">Фрацтал Гласс</string>\n    <string name=\"amplitude\">Амплитуда</string>\n    <string name=\"oil\">уље</string>\n    <string name=\"water_effect\">Ватер Еффецт</string>\n    <string name=\"just_size\">Величина</string>\n    <string name=\"frequency_x\">Учесталост Кс</string>\n    <string name=\"amplitude_y\">Амплитуда И</string>\n    <string name=\"perlin_distortion\">Перлин Дистортион</string>\n    <string name=\"aces_filmic_tone_mapping\">АЦЕС Филмиц Тоне Маппинг</string>\n    <string name=\"current\">Тренутни</string>\n    <string name=\"all\">Све</string>\n    <string name=\"full_filter\">Фулл Филтер</string>\n    <string name=\"start_position\">Почетак</string>\n    <string name=\"center_position\">Центар</string>\n    <string name=\"full_filter_sub\">Примените све ланце филтера на дате слике или једну слику</string>\n    <string name=\"pdf_tools_sub\">Радите са ПДФ датотекама: Прегледајте, Конвертујте у групу слика или креирајте једну од датих слика</string>\n    <string name=\"preview_pdf\">Преглед ПДФ</string>\n    <string name=\"pdf_to_images\">ПДФ у слике</string>\n    <string name=\"images_to_pdf\">Слике у ПДФ</string>\n    <string name=\"gradient_maker\">Градиент Макер</string>\n    <string name=\"gradient_maker_sub\">Направите градијент задате излазне величине са прилагођеним бојама и типом изгледа</string>\n    <string name=\"speed\">Брзина</string>\n    <string name=\"dehaze\">Дехазе</string>\n    <string name=\"omega\">Омега</string>\n    <string name=\"pdf_tools\">ПДФ алати</string>\n    <string name=\"rate_app\">Рангирај апликацију</string>\n    <string name=\"rate\">Рате</string>\n    <string name=\"rate_app_sub\">Ова апликација је потпуно бесплатна, ако желите да постане већа, означите пројекат на Гитхуб-у 😄</string>\n    <string name=\"browni\">Бровни</string>\n    <string name=\"deutaronotopia\">Деутаронотопиа</string>\n    <string name=\"protanopia\">Протанопија</string>\n    <string name=\"achromatomaly\">Ахроматомалија</string>\n    <string name=\"achromatopsia\">Ахроматопсија</string>\n    <string name=\"gradient_type_linear\">Линеар</string>\n    <string name=\"gradient_type_radial\">Радиал</string>\n    <string name=\"gradient_type_sweep\">Свееп</string>\n    <string name=\"gradient_type\">Градиент Типе</string>\n    <string name=\"center_x\">Центар Кс</string>\n    <string name=\"center_y\">Центар И</string>\n    <string name=\"tile_mode\">Тиле Моде</string>\n    <string name=\"tile_mode_repeated\">Поновљено</string>\n    <string name=\"tile_mode_mirror\">Огледало</string>\n    <string name=\"tile_mode_clamp\">Стезаљка</string>\n    <string name=\"lasso\">Ласо</string>\n    <string name=\"lasso_sub\">Црта затворену попуњену путању датом путањом</string>\n    <string name=\"draw_path_mode\">Режим цртања путање</string>\n    <string name=\"double_line_arrow\">Двострука линијска стрелица</string>\n    <string name=\"free_drawing\">Бесплатно цртање</string>\n    <string name=\"line_arrow\">Лине Арров</string>\n    <string name=\"arrow\">Стрелац</string>\n    <string name=\"line\">Линија</string>\n    <string name=\"free_drawing_sub\">Црта путању као улазну вредност</string>\n    <string name=\"arrow_sub\">Црта стрелицу која показује са дате путање</string>\n    <string name=\"double_line_arrow_sub\">Црта двоструку стрелицу од почетне до крајње тачке као линију</string>\n    <string name=\"double_arrow_sub\">Црта двоструку стрелицу са дате путање</string>\n    <string name=\"outlined_oval\">Оутлинед Овал</string>\n    <string name=\"outlined_rect\">Оутлинед Рецт</string>\n    <string name=\"oval\">Овал</string>\n    <string name=\"rect\">Рецт</string>\n    <string name=\"rect_sub\">Црта правоугаоник од почетне до крајње тачке</string>\n    <string name=\"oval_sub\">Црта овално од почетне до крајње тачке</string>\n    <string name=\"outlined_oval_sub\">Црта оцртани овал од почетне до крајње тачке</string>\n    <string name=\"outlined_rect_sub\">Црта оцртани правоугаоник од почетне до крајње тачке</string>\n    <string name=\"dithering\">Дитхеринг</string>\n    <string name=\"quantizier\">Куантизиер</string>\n    <string name=\"gray_scale\">Граи Сцале</string>\n    <string name=\"bayer_two_dithering\">Баиер Тво Би Тво Дитхеринг</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Јарвис Јудице Нинке Дитхеринг</string>\n    <string name=\"sierra_dithering\">Сиерра Дитхеринг</string>\n    <string name=\"sierra_lite_dithering\">Сиерра Лите Дитхеринг</string>\n    <string name=\"two_row_sierra_dithering\">Тво Ров Сиерра Дитхеринг</string>\n    <string name=\"atkinson_dithering\">Аткинсон Дитхеринг</string>\n    <string name=\"stucki_dithering\">Стуцки Дитхеринг</string>\n    <string name=\"burkes_dithering\">Буркес Дитхеринг</string>\n    <string name=\"false_floyd_steinberg_dithering\">Фалсе Флоид Стеинберг Дитхеринг</string>\n    <string name=\"left_to_right_dithering\">Дитхеринг са лева на десно</string>\n    <string name=\"random_dithering\">Рандом Дитхеринг</string>\n    <string name=\"simple_threshold_dithering\">Симпле Тхресхолд Дитхеринг</string>\n    <string name=\"wait\">Чекати</string>\n    <string name=\"mask_color\">Боја маске</string>\n    <string name=\"mask_preview\">Преглед маске</string>\n    <string name=\"mask_preview_sub\">Нацртана маска филтера ће бити приказана да вам покаже приближан резултат</string>\n    <string name=\"scale_mode\">Сцале моде</string>\n    <string name=\"bilinear\">Билинеар</string>\n    <string name=\"hann\">Ханн</string>\n    <string name=\"hermite\">Хермите</string>\n    <string name=\"lanczos\">Ланцзос</string>\n    <string name=\"mitchell\">Митцхелл</string>\n    <string name=\"nearest\">Најближи</string>\n    <string name=\"spline\">Сплине</string>\n    <string name=\"default_value\">Задана вриједност</string>\n    <string name=\"value_in_range\">Вредност у опсегу %1$s - %2$s</string>\n    <string name=\"sigma\">Сигма</string>\n    <string name=\"spatial_sigma\">Спатиал Сигма</string>\n    <string name=\"median_blur\">Медиан Блур</string>\n    <string name=\"mitchell_sub\">Метода поновног узорковања која користи филтер конволуције са подесивим параметрима да би се постигао баланс између оштрине и анти-алиасинг-а на скалираној слици</string>\n    <string name=\"only_clip\">Онли Цлип</string>\n    <string name=\"only_clip_sub\">Чување у меморију неће бити извршено, а слика ће се покушати ставити само у међуспремник</string>\n    <string name=\"icon_shape_sub\">Додаје контејнер са изабраним обликом испод водећих икона картица</string>\n    <string name=\"image_stitching\">Имаге Ститцхинг</string>\n    <string name=\"image_stitching_sub\">Комбинујте дате слике да бисте добили једну велику</string>\n    <string name=\"randomize_filename\">Насумично подеси име датотеке</string>\n    <string name=\"brightness_enforcement\">Спровођење осветљености</string>\n    <string name=\"screen\">Екран</string>\n    <string name=\"gradient_maker_type_image\">Градиент Оверлаи</string>\n    <string name=\"gradient_maker_type_image_sub\">Направите било који градијент врха дате слике</string>\n    <string name=\"transformations\">Трансформације</string>\n    <string name=\"camera\">Камера</string>\n    <string name=\"camera_sub\">Користи камеру за снимање слике, имајте на уму да је могуће добити само једну слику са овог извора слике</string>\n    <string name=\"grain\">Зрно</string>\n    <string name=\"green_sun\">Греен Сун</string>\n    <string name=\"rainbow_world\">Раинбов Ворлд</string>\n    <string name=\"deep_purple\">Дееп Пурпле</string>\n    <string name=\"space_portal\">Свемирски портал</string>\n    <string name=\"red_swirl\">Ред Свирл</string>\n    <string name=\"watermarking\">Ватермаркинг</string>\n    <string name=\"repeat_watermark\">Поновите водени жиг</string>\n    <string name=\"overlay_mode\">Оверлаи Моде</string>\n    <string name=\"pixel_size\">Величина пиксела</string>\n    <string name=\"lock_draw_orientation\">Закључајте оријентацију цртања</string>\n    <string name=\"max_colors_count\">Максимални број боја</string>\n    <string name=\"lock_draw_orientation_sub\">Ако је омогућено у режиму цртања, екран се неће ротирати</string>\n    <string name=\"bokeh\">Бокех</string>\n    <string name=\"gif_tools\">ГИФ алати</string>\n    <string name=\"gif_tools_sub\">Претворите слике у ГИФ слику или издвојите оквире из дате ГИФ слике</string>\n    <string name=\"gif_type_to_image\">ГИФ за слике</string>\n    <string name=\"gif_type_to_image_sub\">Претворите ГИФ датотеку у групу слика</string>\n    <string name=\"gif_type_to_gif_sub\">Претворите серију слика у ГИФ датотеку</string>\n    <string name=\"gif_type_to_gif\">Слике у ГИФ</string>\n    <string name=\"select_gif_image_to_start\">Изаберите ГИФ слику за почетак</string>\n    <string name=\"use_lasso\">Користите ласо</string>\n    <string name=\"use_lasso_sub\">Користи Лассо као у режиму цртања за брисање</string>\n    <string name=\"original_image_preview_alpha\">Алфа преглед оригиналне слике</string>\n    <string name=\"random_emojis_sub\">Емоџи траке апликација ће се непрекидно мењати насумично уместо да се користе изабрани</string>\n    <string name=\"random_emojis\">Насумични емоџи</string>\n    <string name=\"random_emojis_error\">Не може да се користи насумично бирање емоџија док су емоџији онемогућени</string>\n    <string name=\"emoji_selection_error\">Не могу да изаберем емоџи док је омогућено насумично бирање</string>\n    <string name=\"check_for_updates\">Провери ажурирања</string>\n    <string name=\"old_tv\">Олд ТВ</string>\n    <string name=\"shuffle_blur\">Схуффле Блур</string>\n    <string name=\"recognize_text\">ОЦР (препознавање текста)</string>\n    <string name=\"recognize_text_sub\">Препознајте текст са дате слике, подржано је 120+ језика</string>\n    <string name=\"picture_has_no_text\">Слика нема текст или је апликација није нашла</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Рецогнитион Типе</string>\n    <string name=\"fast\">Фаст</string>\n    <string name=\"standard\">Стандард</string>\n    <string name=\"best\">Најбољи</string>\n    <string name=\"no_data\">Нема података</string>\n    <string name=\"download_description\">За правилно функционисање Тессерацт ОЦР-а потребно је да се на ваш уређај преузму додатни подаци за обуку (%1$s). \\nДа ли желите да преузмете %2$s податке?</string>\n    <string name=\"download\">Преузимање</string>\n    <string name=\"no_connection\">Нема везе, проверите и покушајте поново да бисте преузели моделе возова</string>\n    <string name=\"downloaded_languages\">Преузети језици</string>\n    <string name=\"available_languages\">Доступни језици</string>\n    <string name=\"segmentation_mode\">Режим сегментације</string>\n    <string name=\"restore_background_sub\">Четкица ће вратити позадину уместо брисања</string>\n    <string name=\"horizontal_grid\">Хоризонтал Грид</string>\n    <string name=\"vertical_grid\">Вертицал Грид</string>\n    <string name=\"stitch_mode\">Ститцх Моде</string>\n    <string name=\"rows_count\">Број редова</string>\n    <string name=\"columns_count\">Цолумнс Цоунт</string>\n    <string name=\"use_pixel_switch\">Користите Пикел Свитцх</string>\n    <string name=\"use_pixel_switch_sub\">Прекидач налик на пиксел ће се користити уместо гоогле материјала који сте базирали</string>\n    <string name=\"slide\">Тобоган</string>\n    <string name=\"side_by_side\">Раме уз раме</string>\n    <string name=\"toggle_tap\">Тоггле Тап</string>\n    <string name=\"transparency\">Транспарентност</string>\n    <string name=\"saved_to_original\">Замењена датотека са именом %1$s на оригиналном одредишту</string>\n    <string name=\"magnifier\">Лупа</string>\n    <string name=\"force_exif_widget_initial_value\">Присилна почетна вредност</string>\n    <string name=\"favorite\">Фаворите</string>\n    <string name=\"no_favorite_filters\">Још увек није додат ниједан омиљени филтер</string>\n    <string name=\"b_spline\">Б Сплине</string>\n    <string name=\"b_spline_sub\">Користи по комадима дефинисане бикубне полиномске функције за глатку интерполацију и апроксимацију криве или површине, флексибилно и континуирано представљање облика</string>\n    <string name=\"regular\">Редовно</string>\n    <string name=\"inverse_fill_type\">Инверзни тип попуњавања</string>\n    <string name=\"inverse_fill_type_sub\">Ако је омогућено, све немаскиране области ће бити филтриране уместо подразумеваног понашања</string>\n    <string name=\"confetti\">Конфети</string>\n    <string name=\"confetti_sub\">Конфете ће бити приказане приликом чувања, дељења и других примарних радњи</string>\n    <string name=\"secure_mode\">Сецуре Моде</string>\n    <string name=\"secure_mode_sub\">Сакрива садржај при изласку, такође се екран не може снимити или снимити</string>\n    <string name=\"crop_description\">Слике ће бити изрезане по средини на унету величину. Платно ће бити проширено датом бојом позадине ако је слика мања од унесених димензија.</string>\n    <string name=\"auto_rotate_limits\">Ауто Ротате</string>\n    <string name=\"auto_rotate_limits_sub\">Омогућава усвајање оквира ограничења за оријентацију слике</string>\n    <string name=\"monochrome_sub\">Монохромна тема, боје су чисто црне/беле/сиве</string>\n    <string name=\"content_sub\">Шема која поставља изворну боју у Сцхеме.примариЦонтаинер</string>\n    <string name=\"fidelity_sub\">Шема која је веома слична шеми садржаја</string>\n    <string name=\"highlighter_sub\">Нацртајте полупровидне изоштрене путање маркера</string>\n    <string name=\"containers_shadow\">Контејнери</string>\n    <string name=\"containers_shadow_sub\">Омогућава цртање сенке иза контејнера</string>\n    <string name=\"sliders_shadow\">Клизачи</string>\n    <string name=\"switches_shadow\">Прекидачи</string>\n    <string name=\"fabs_shadow\">ФАБс</string>\n    <string name=\"buttons_shadow\">Дугмад</string>\n    <string name=\"app_bars_shadow\">Апп Барс</string>\n    <string name=\"foss_update_checker_warning\">Овај алат за проверу ажурирања ће се повезати са ГитХуб-ом у циљу провере да ли је доступно ново ажурирање</string>\n    <string name=\"attention\">Пажња</string>\n    <string name=\"fading_edges\">Фадинг Едгес</string>\n    <string name=\"disabled\">Онемогућено</string>\n    <string name=\"invert_colors\">Инверт Цолорс</string>\n    <string name=\"invert_colors_sub\">Замењује боје теме негативним ако је омогућено</string>\n    <string name=\"exit\">Изађи</string>\n    <string name=\"preview_closing\">Ако сада напустите преглед, мораћете поново да додате слике</string>\n    <string name=\"image_format\">Формат слике</string>\n    <string name=\"material_you_sub\">Ствара палету \\\"Material You \\\" са слике</string>\n    <string name=\"dark_colors\">Тамне боје</string>\n    <string name=\"dark_colors_sub\">Користи шему боја ноћног режима уместо светле опције</string>\n    <string name=\"copy_as_compose_code\">Копирајте као код \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Замагљивање прстена</string>\n    <string name=\"cross_blur\">Унакрсно замућење</string>\n    <string name=\"circle_blur\">Замагљивање круга</string>\n    <string name=\"star_blur\">Звездана тачка</string>\n    <string name=\"linear_tilt_shift\">Линеарни помак нагиба</string>\n    <string name=\"tags_to_remove\">Ознаке за брисање</string>\n    <string name=\"apng_tools\">АПНГ алати</string>\n    <string name=\"apng_tools_sub\">Претворите слике у АПНГ слику или издвојите оквире из дате АПНГ слике</string>\n    <string name=\"apng_type_to_image\">АПНГ за слике</string>\n    <string name=\"select_apng_image_to_start\">Изаберите АПНГ слику за почетак</string>\n    <string name=\"apng_type_to_apng_sub\">Претворите серију слика у АПНГ датотеку</string>\n    <string name=\"apng_type_to_apng\">Слике у АПНГ</string>\n    <string name=\"motion_blur\">Мотион Блур</string>\n    <string name=\"apng_type_to_image_sub\">Претворите АПНГ датотеку у серију слика</string>\n    <string name=\"zip\">Зип</string>\n    <string name=\"zip_sub\">Креирајте Зип датотеку од датих датотека или слика</string>\n    <string name=\"drag_handle_width\">Ширина ручке превлачења</string>\n    <string name=\"confetti_type\">Цонфетти Типе</string>\n    <string name=\"festive\">Свечана</string>\n    <string name=\"explode\">Експлодирај</string>\n    <string name=\"rain\">Киша</string>\n    <string name=\"corners\">Углови</string>\n    <string name=\"jxl_tools\">ЈКСЛ Тоолс</string>\n    <string name=\"jxl_tools_sub\">Извршите ЈКСЛ ~ ЈПЕГ транскодирање без губитка квалитета или конвертујте ГИФ/АПНГ у ЈКСЛ анимацију</string>\n    <string name=\"jxl_type_to_jpeg\">ЈКСЛ у ЈПЕГ</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Извршите транскодирање без губитака из ЈКСЛ у ЈПЕГ</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Извршите транскодирање без губитака из ЈПЕГ у ЈКСЛ</string>\n    <string name=\"jpeg_type_to_jxl\">ЈПЕГ у ЈКСЛ</string>\n    <string name=\"select_jxl_image_to_start\">Изаберите ЈКСЛ слику за почетак</string>\n    <string name=\"fast_gaussian_blur_2d\">Фаст Гауссиан Блур 2Д</string>\n    <string name=\"fast_gaussian_blur_3d\">Фаст Гауссиан Блур 3Д</string>\n    <string name=\"fast_gaussian_blur_4d\">Фаст Гауссиан Блур 4Д</string>\n    <string name=\"auto_paste\">Ауто Ускрс</string>\n    <string name=\"auto_paste_sub\">Дозвољава апликацији да аутоматски налепи податке међумеморије, тако да ће се појавити на главном екрану и моћи ћете да их обрадите</string>\n    <string name=\"harmonization_color\">Хармонизатион Цолор</string>\n    <string name=\"harmonization_level\">Ниво хармонизације</string>\n    <string name=\"lanczos_bessel\">Ланцзос Бессел</string>\n    <string name=\"lanczos_bessel_sub\">Метода поновног узорковања која одржава интерполацију високог квалитета применом Беселове (јинц) функције на вредности пиксела</string>\n    <string name=\"gif_type_to_jxl\">ГИФ у ЈКСЛ</string>\n    <string name=\"gif_type_to_jxl_sub\">Претворите ГИФ слике у ЈКСЛ анимиране слике</string>\n    <string name=\"apng_type_to_jxl\">АПНГ у ЈКСЛ</string>\n    <string name=\"apng_type_to_jxl_sub\">Претворите АПНГ слике у ЈКСЛ анимиране слике</string>\n    <string name=\"jxl_type_to_images\">ЈКСЛ у слике</string>\n    <string name=\"jxl_type_to_images_sub\">Претворите ЈКСЛ анимацију у скуп слика</string>\n    <string name=\"jxl_type_to_jxl\">Слике у ЈКСЛ</string>\n    <string name=\"jxl_type_to_jxl_sub\">Претворите серију слика у ЈКСЛ анимацију</string>\n    <string name=\"behavior\">Понашање</string>\n    <string name=\"skip_file_picking\">Прескочи бирање датотека</string>\n    <string name=\"skip_file_picking_sub\">Бирач датотека ће се одмах приказати ако је то могуће на одабраном екрану</string>\n    <string name=\"generate_previews\">Генеришите прегледе</string>\n    <string name=\"generate_previews_sub\">Омогућава генерисање прегледа, ово може помоћи да се избегну рушења на неким уређајима, ово такође онемогућава неке функције уређивања унутар једне опције за уређивање</string>\n    <string name=\"lossy_compression\">Компресија са губитком</string>\n    <string name=\"lossy_compression_sub\">Користи компресију са губицима да смањи величину датотеке уместо без губитака</string>\n    <string name=\"compression_type\">Тип компресије</string>\n    <string name=\"speed_sub\">Контролише брзину декодирања резултујуће слике, ово би требало да помогне да се добијена слика брже отвори, вредност %1$s значи најспорије декодирање, док %2$s - најбрже, ово подешавање може повећати величину излазне слике</string>\n    <string name=\"sorting\">Сортирање</string>\n    <string name=\"sort_by_date\">Датум</string>\n    <string name=\"sort_by_date_reversed\">Датум (обрнуто)</string>\n    <string name=\"sort_by_name\">Име</string>\n    <string name=\"sort_by_name_reversed\">Име (обрнуто)</string>\n    <string name=\"channels_configuration\">Конфигурација канала</string>\n    <string name=\"header_today\">данас</string>\n    <string name=\"header_yesterday\">Јучер</string>\n    <string name=\"embedded_picker\">Уграђени бирач</string>\n    <string name=\"embedded_picker_sub\">Бирач слика Имаге Тоолбок-а</string>\n    <string name=\"no_permissions\">Нема дозвола</string>\n    <string name=\"request\">Захтев</string>\n    <string name=\"pick_multiple_media\">Изаберите више медија</string>\n    <string name=\"pick_single_media\">Изаберите Сингле Медиа</string>\n    <string name=\"pick\">Пицк</string>\n    <string name=\"try_again\">Покушајте поново</string>\n    <string name=\"show_settings_in_landscape\">Прикажи подешавања у пејзажу</string>\n    <string name=\"show_settings_in_landscape_sub\">Ако је ово онемогућено, у пејзажном режиму подешавања ће бити отворена на дугмету на горњој траци апликација као и увек, уместо трајно видљиве опције</string>\n    <string name=\"fullscreen_settings\">Подешавања целог екрана</string>\n    <string name=\"fullscreen_settings_sub\">Омогућите га и страница са подешавањима ће се увек отварати на целом екрану уместо листа фиоке који се може померати</string>\n    <string name=\"switch_type\">Тип прекидача</string>\n    <string name=\"compose\">Цомпосе</string>\n    <string name=\"compose_switch_sub\">Јетпацк Цомпосе Материјал који мењате</string>\n    <string name=\"material_you_switch_sub\">Материјал који мењате</string>\n    <string name=\"max\">Макс</string>\n    <string name=\"resize_anchor\">Промени величину сидра</string>\n    <string name=\"pixel_switch\">Пикел</string>\n    <string name=\"fluent_switch\">Течно</string>\n    <string name=\"fluent_switch_sub\">Прекидач заснован на систему дизајна \\\"Флуент\\\".</string>\n    <string name=\"cupertino_switch\">Цупертино</string>\n    <string name=\"cupertino_switch_sub\">Прекидач заснован на систему дизајна \\\"Цупертино\\\".</string>\n    <string name=\"images_to_svg\">Слике у СВГ</string>\n    <string name=\"images_to_svg_sub\">Пратите дате слике у СВГ слике</string>\n    <string name=\"use_sampled_palette\">Користите узорковану палету</string>\n    <string name=\"use_sampled_palette_sub\">Палета квантизације ће бити узоркована ако је ова опција омогућена</string>\n    <string name=\"path_omit\">Патх Изостави</string>\n    <string name=\"svg_warning\">Употреба овог алата за праћење великих слика без смањења скалирања се не препоручује, може изазвати пад и продужити време обраде</string>\n    <string name=\"downscale_image\">Смањење слике</string>\n    <string name=\"downscale_image_sub\">Слика ће бити смањена на мање димензије пре обраде, што помаже алату да ради брже и безбедније</string>\n    <string name=\"min_color_ratio\">Минимални однос боја</string>\n    <string name=\"lines_threshold\">Линије Праг</string>\n    <string name=\"quadratic_threshold\">Куадратиц Тхресхолд</string>\n    <string name=\"coordinates_rounding_tolerance\">Толеранција заокруживања координата</string>\n    <string name=\"path_scale\">Патх Сцале</string>\n    <string name=\"reset_properties\">Ресетујте својства</string>\n    <string name=\"reset_properties_sub\">Сва својства ће бити постављена на подразумеване вредности, приметите да се ова радња не може опозвати</string>\n    <string name=\"detailed\">Детаљно</string>\n    <string name=\"default_line_width\">Подразумевана ширина линије</string>\n    <string name=\"engine_mode\">Енгине Моде</string>\n    <string name=\"legacy\">Легаци</string>\n    <string name=\"lstm_network\">ЛСТМ мрежа</string>\n    <string name=\"legacy_and_lstm\">Легаци &amp;amp; ЛСТМ</string>\n    <string name=\"convert\">Цонверт</string>\n    <string name=\"convert_sub\">Конвертујте групе слика у дати формат</string>\n    <string name=\"add_new_folder\">Додај нову фасциклу</string>\n    <string name=\"tag_bits_per_sample\">Битс пер Сампле</string>\n    <string name=\"tag_compression\">Компресија</string>\n    <string name=\"tag_photometric_interpretation\">Пхотометриц Интерпретатион</string>\n    <string name=\"tag_samples_per_pixel\">Узорци по пикселу</string>\n    <string name=\"tag_planar_configuration\">Планарна конфигурација</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">И Цб Цр Подузорковање</string>\n    <string name=\"tag_y_cb_cr_positioning\">И Цб Цр Позиционирање</string>\n    <string name=\"tag_x_resolution\">Кс Резолуција</string>\n    <string name=\"tag_y_resolution\">И Ресолутион</string>\n    <string name=\"tag_resolution_unit\">Ресолутион Унит</string>\n    <string name=\"tag_strip_offsets\">Стрип Оффсетс</string>\n    <string name=\"tag_rows_per_strip\">Редови по траци</string>\n    <string name=\"tag_strip_byte_counts\">Стрип Бите Цоунтс</string>\n    <string name=\"tag_jpeg_interchange_format\">Формат за размену ЈПЕГ</string>\n    <string name=\"tag_jpeg_interchange_format_length\">ЈПЕГ Интерцханге Формат Дужина</string>\n    <string name=\"tag_transfer_function\">Трансфер Функција</string>\n    <string name=\"tag_white_point\">Вхите Поинт</string>\n    <string name=\"tag_primary_chromaticities\">Примари Цхроматицитиес</string>\n    <string name=\"tag_y_cb_cr_coefficients\">И Цб Цр коефицијенти</string>\n    <string name=\"tag_reference_black_white\">Референца Блацк Вхите</string>\n    <string name=\"tag_datetime\">Датум и време</string>\n    <string name=\"tag_image_description\">Опис слике</string>\n    <string name=\"tag_make\">Маке</string>\n    <string name=\"tag_model\">Модел</string>\n    <string name=\"tag_software\">софтвер</string>\n    <string name=\"tag_artist\">Уметник</string>\n    <string name=\"tag_copyright\">Цопиригхт</string>\n    <string name=\"tag_exif_version\">Екиф верзија</string>\n    <string name=\"tag_flashpix_version\">Фласхпик верзија</string>\n    <string name=\"tag_color_space\">Цолор Спаце</string>\n    <string name=\"tag_gamma\">Гама</string>\n    <string name=\"tag_pixel_x_dimension\">Пикел Кс димензија</string>\n    <string name=\"tag_pixel_y_dimension\">Пикел И димензија</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Компримовани битови по пикселу</string>\n    <string name=\"tag_maker_note\">Напомена произвођача</string>\n    <string name=\"tag_user_comment\">Коментар корисника</string>\n    <string name=\"tag_related_sound_file\">Повезана звучна датотека</string>\n    <string name=\"tag_datetime_original\">Датум Време Оригинал</string>\n    <string name=\"tag_datetime_digitized\">Датум и време дигитализовано</string>\n    <string name=\"tag_offset_time\">Оффсет Тиме</string>\n    <string name=\"tag_offset_time_original\">Оффсет Тиме Оригинал</string>\n    <string name=\"tag_offset_time_digitized\">Оффсет Тиме Дигитализед</string>\n    <string name=\"tag_subsec_time\">Суб Сец Тиме</string>\n    <string name=\"tag_subsec_time_original\">Суб Сец Време Оригинал</string>\n    <string name=\"tag_subsec_time_digitized\">Подсек Време Дигитализовано</string>\n    <string name=\"tag_exposure_time\">Време излагања</string>\n    <string name=\"tag_f_number\">Ф број</string>\n    <string name=\"tag_exposure_program\">Програм експозиције</string>\n    <string name=\"tag_spectral_sensitivity\">Спектрална осетљивост</string>\n    <string name=\"tag_photographic_sensitivity\">Пхотограпхиц Сенситивити</string>\n    <string name=\"tag_oecf\">Оецф</string>\n    <string name=\"tag_sensitivity_type\">Тип осетљивости</string>\n    <string name=\"tag_standard_output_sensitivity\">Стандардна излазна осетљивост</string>\n    <string name=\"tag_recommended_exposure_index\">Препоручени индекс изложености</string>\n    <string name=\"tag_iso_speed\">ИСО брзина</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ИСО брзина Латитуде иии</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ИСО брзина Латитуде ззз</string>\n    <string name=\"tag_shutter_speed_value\">Вредност брзине затварача</string>\n    <string name=\"tag_aperture_value\">Апертуре Валуе</string>\n    <string name=\"tag_brightness_value\">Бригхтнесс Валуе</string>\n    <string name=\"tag_exposure_bias_value\">Вредност пристраности експозиције</string>\n    <string name=\"tag_max_aperture_value\">Максимална вредност отвора бленде</string>\n    <string name=\"tag_subject_distance\">Субјецт Дистанце</string>\n    <string name=\"tag_metering_mode\">Режим мерења</string>\n    <string name=\"tag_flash\">Фласх</string>\n    <string name=\"tag_subject_area\">Предметна област</string>\n    <string name=\"tag_focal_length\">Фоцал Ленгтх</string>\n    <string name=\"tag_flash_energy\">Фласх Енерги</string>\n    <string name=\"tag_spatial_frequency_response\">Просторни фреквентни одзив</string>\n    <string name=\"tag_focal_plane_x_resolution\">Резолуција фокусне равни Кс</string>\n    <string name=\"tag_focal_plane_y_resolution\">Резолуција жаришне равни И</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Јединица резолуције фокусне равни</string>\n    <string name=\"tag_subject_location\">Локација предмета</string>\n    <string name=\"tag_exposure_index\">Индекс експозиције</string>\n    <string name=\"tag_sensing_method\">Сенсинг Метход</string>\n    <string name=\"tag_file_source\">Извор датотеке</string>\n    <string name=\"tag_cfa_pattern\">ЦФА Паттерн</string>\n    <string name=\"tag_custom_rendered\">Цустом Рендеред</string>\n    <string name=\"tag_exposure_mode\">Режим експозиције</string>\n    <string name=\"tag_white_balance\">Баланс белог</string>\n    <string name=\"tag_digital_zoom_ratio\">Однос дигиталног зума</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Фокална дужина у филму од 35 мм</string>\n    <string name=\"tag_scene_capture_type\">Тип снимања сцене</string>\n    <string name=\"tag_gain_control\">Гаин Цонтрол</string>\n    <string name=\"tag_contrast\">Контраст</string>\n    <string name=\"tag_saturation\">Сатуратион</string>\n    <string name=\"tag_sharpness\">Оштрина</string>\n    <string name=\"tag_device_setting_description\">Опис подешавања уређаја</string>\n    <string name=\"tag_subject_distance_range\">Опсег удаљености субјекта</string>\n    <string name=\"tag_image_unique_id\">Јединствени ИД слике</string>\n    <string name=\"tag_camera_owner_name\">Име власника камере</string>\n    <string name=\"tag_body_serial_number\">Серијски број тела</string>\n    <string name=\"tag_lens_specification\">Спецификација објектива</string>\n    <string name=\"tag_lens_make\">Ленс Маке</string>\n    <string name=\"tag_lens_model\">Модел објектива</string>\n    <string name=\"tag_lens_serial_number\">Серијски број објектива</string>\n    <string name=\"tag_gps_version_id\">ИД верзије ГПС-а</string>\n    <string name=\"tag_gps_latitude_ref\">ГПС Латитуде Реф</string>\n    <string name=\"tag_gps_latitude\">ГПС Латитуде</string>\n    <string name=\"tag_gps_longitude_ref\">ГПС дужина Реф</string>\n    <string name=\"tag_gps_longitude\">ГПС Лонгитуде</string>\n    <string name=\"tag_gps_altitude_ref\">ГПС висина Реф</string>\n    <string name=\"tag_gps_altitude\">ГПС Алтитуде</string>\n    <string name=\"tag_gps_timestamp\">ГПС временска ознака</string>\n    <string name=\"tag_gps_satellites\">ГПС сателити</string>\n    <string name=\"tag_gps_status\">ГПС статус</string>\n    <string name=\"tag_gps_measure_mode\">ГПС режим мерења</string>\n    <string name=\"tag_gps_dop\">ГПС ДОП</string>\n    <string name=\"tag_gps_speed_ref\">ГПС брзина Реф</string>\n    <string name=\"tag_gps_speed\">ГПС Спеед</string>\n    <string name=\"tag_gps_track_ref\">ГПС Трак Реф</string>\n    <string name=\"tag_gps_track\">ГПС Трацк</string>\n    <string name=\"tag_gps_img_direction_ref\">ГПС Имг Дирецтион Реф</string>\n    <string name=\"tag_gps_img_direction\">ГПС Имг Дирецтион</string>\n    <string name=\"tag_gps_map_datum\">ГПС Мап Датум</string>\n    <string name=\"tag_gps_dest_latitude_ref\">ГПС Дест Латитуде Реф</string>\n    <string name=\"tag_gps_dest_latitude\">ГПС Дест Латитуде</string>\n    <string name=\"tag_gps_dest_longitude_ref\">ГПС дужина одредишта Реф</string>\n    <string name=\"tag_gps_dest_longitude\">ГПС географска дужина одредишта</string>\n    <string name=\"tag_gps_dest_bearing_ref\">ГПС Дест Беаринг Реф</string>\n    <string name=\"tag_gps_dest_bearing\">ГПС одредиште</string>\n    <string name=\"tag_gps_dest_distance_ref\">ГПС одредишна удаљеност Реф</string>\n    <string name=\"tag_gps_dest_distance\">ГПС одредишна удаљеност</string>\n    <string name=\"tag_gps_processing_method\">Метода ГПС обраде</string>\n    <string name=\"tag_gps_area_information\">ГПС информације о подручју</string>\n    <string name=\"tag_gps_datestamp\">ГПС печат датума</string>\n    <string name=\"tag_gps_differential\">ГПС Дифферентиал</string>\n    <string name=\"tag_gps_h_positioning_error\">Грешка ГПС Х позиционирања</string>\n    <string name=\"tag_interoperability_index\">Индекс интероперабилности</string>\n    <string name=\"tag_dng_version\">ДНГ верзија</string>\n    <string name=\"tag_default_crop_size\">Подразумевана величина исецања</string>\n    <string name=\"tag_orf_preview_image_start\">Почетак прегледа слике</string>\n    <string name=\"tag_orf_preview_image_length\">Превиев Имаге Ленгтх</string>\n    <string name=\"tag_orf_aspect_frame\">Аспецт Фраме</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Доња ивица сензора</string>\n    <string name=\"tag_rw2_sensor_left_border\">Лева ивица сензора</string>\n    <string name=\"tag_rw2_sensor_right_border\">Десна ивица сензора</string>\n    <string name=\"tag_rw2_sensor_top_border\">Горња ивица сензора</string>\n    <string name=\"tag_rw2_iso\">ИСО</string>\n    <string name=\"draw_text_sub\">Нацртајте текст на путањи са датим фонтом и бојом</string>\n    <string name=\"font_size\">Величина фонта</string>\n    <string name=\"watermark_size\">Величина воденог жига</string>\n    <string name=\"repeat_text\">Поновите текст</string>\n    <string name=\"repeat_text_sub\">Тренутни текст ће се понављати до краја путање уместо једнократног цртања</string>\n    <string name=\"dash_size\">Дасх Сизе</string>\n    <string name=\"draw_mode_image_sub\">Користите изабрану слику да је нацртате дуж дате путање</string>\n    <string name=\"draw_image_sub\">Ова слика ће се користити као понављајући унос нацртане путање</string>\n    <string name=\"outlined_triangle_sub\">Црта оцртани троугао од почетне до крајње тачке</string>\n    <string name=\"triangle_sub\">Црта оцртани троугао од почетне до крајње тачке</string>\n    <string name=\"outlined_triangle\">Оцртани троугао</string>\n    <string name=\"triangle\">Троугао</string>\n    <string name=\"polygon_sub\">Црта полигон од почетне до крајње тачке</string>\n    <string name=\"polygon\">Полигон</string>\n    <string name=\"outlined_polygon\">Оцртани полигон</string>\n    <string name=\"outlined_polygon_sub\">Црта оцртани полигон од почетне до крајње тачке</string>\n    <string name=\"vertices\">Вертицес</string>\n    <string name=\"draw_regular_polygon\">Нацртајте правилан полигон</string>\n    <string name=\"draw_regular_polygon_sub\">Нацртајте полигон који ће бити правилан уместо слободног облика</string>\n    <string name=\"star_sub\">Црта звезду од почетне до крајње тачке</string>\n    <string name=\"star\">Звезда</string>\n    <string name=\"outlined_star\">Оутлинед Стар</string>\n    <string name=\"outlined_star_sub\">Црта оцртану звезду од почетне до крајње тачке</string>\n    <string name=\"inner_radius_ratio\">Однос унутрашњег радијуса</string>\n    <string name=\"draw_regular_star\">Нацртај редовну звезду</string>\n    <string name=\"draw_regular_star_sub\">Извуците звезду која ће бити регуларна уместо слободног облика</string>\n    <string name=\"antialias\">Антиалиас</string>\n    <string name=\"antialias_sub\">Омогућава антиалиасинг да спречи оштре ивице</string>\n    <string name=\"open_edit_instead_of_preview\">Отворите Уреди уместо прегледа</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Када изаберете слику за отварање (преглед) у ИмагеТоолбок-у, отвориће се листа за уређивање уместо прегледа</string>\n    <string name=\"document_scanner\">Скенер докумената</string>\n    <string name=\"document_scanner_sub\">Скенирајте документе и креирајте ПДФ или одвојене слике од њих</string>\n    <string name=\"click_to_start_scanning\">Кликните да бисте започели скенирање</string>\n    <string name=\"start_scanning\">Започните скенирање</string>\n    <string name=\"save_as_pdf\">Сачувај као ПДФ</string>\n    <string name=\"share_as_pdf\">Подели као ПДФ</string>\n    <string name=\"options_below_is_for_images\">Опције испод су за чување слика, а не ПДФ-а</string>\n    <string name=\"equalize_histogram_hsv\">Изједначите хистограм ХСВ</string>\n    <string name=\"equalize_histogram\">Изједначите хистограм</string>\n    <string name=\"enter_percentage\">Унесите проценат</string>\n    <string name=\"allow_enter_by_text_field\">Дозволите унос преко текстуалног поља</string>\n    <string name=\"allow_enter_by_text_field_sub\">Омогућава текстуално поље иза избора унапред подешених поставки да бисте их унели у ходу</string>\n    <string name=\"scale_color_space\">Сцале Цолор Спаце</string>\n    <string name=\"linear\">Линеар</string>\n    <string name=\"equalize_histogram_pixelation\">Изједначите пикселацију хистограма</string>\n    <string name=\"grid_size_x\">Величина мреже Кс</string>\n    <string name=\"grid_size_y\">Величина мреже И</string>\n    <string name=\"equalize_histogram_adaptive\">Екуализе Хистограм Адаптиве</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Екуализе Хистограм Адаптиве ЛУВ</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Екуализе Хистограм Адаптиве ЛАБ</string>\n    <string name=\"clahe\">ЦЛАХЕ</string>\n    <string name=\"clahe_lab\">ЦЛАХЕ ЛАБ</string>\n    <string name=\"clahe_luv\">ЦЛАХЕ ЛУВ</string>\n    <string name=\"crop_to_content\">Изрежите до садржаја</string>\n    <string name=\"frame_color\">Боја оквира</string>\n    <string name=\"color_to_ignore\">Боја за игнорисање</string>\n    <string name=\"template\">Темплате</string>\n    <string name=\"no_template_filters\">Нема додатих филтера шаблона</string>\n    <string name=\"create_new\">Цреате Нев</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Скенирани КР код није важећи шаблон филтера</string>\n    <string name=\"scan_qr_code\">Скенирајте КР код</string>\n    <string name=\"opened_file_have_no_filter_template\">Изабрана датотека нема податке шаблона филтера</string>\n    <string name=\"create_template\">Цреате Темплате</string>\n    <string name=\"template_name\">Име шаблона</string>\n    <string name=\"select_template_preview\">Ова слика ће се користити за преглед овог шаблона филтера</string>\n    <string name=\"template_filter\">Филтер шаблона</string>\n    <string name=\"as_qr_code\">Као слика КР кода</string>\n    <string name=\"as_file\">Као фајл</string>\n    <string name=\"save_as_file\">Сачувај као датотеку</string>\n    <string name=\"save_as_qr_code_image\">Сачувај као слику КР кода</string>\n    <string name=\"delete_template\">Избриши шаблон</string>\n    <string name=\"delete_template_warn\">Спремате се да избришете изабрани филтер шаблона. Ова операција се не може опозвати</string>\n    <string name=\"added_filter_template\">Додан шаблон филтера са именом \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Преглед филтера</string>\n    <string name=\"qr_code\">КР и бар код</string>\n    <string name=\"qr_code_sub\">Скенирајте КР код и преузмите његов садржај или налепите стринг да бисте генерисали нови</string>\n    <string name=\"code_content\">Садржај кода</string>\n    <string name=\"scan_qr_code_to_replace_content\">Скенирајте било који бар код да бисте заменили садржај у пољу или унесите нешто да бисте генерисали нови бар код са изабраним типом</string>\n    <string name=\"qr_description\">КР Десцриптион</string>\n    <string name=\"min\">Мин</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Дајте камери дозволу у подешавањима за скенирање КР кода</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Дајте камери дозволу у подешавањима за скенирање скенера докумената</string>\n    <string name=\"cubic\">Цубиц</string>\n    <string name=\"bspline\">Б-сплине</string>\n    <string name=\"hamming\">Хаминг</string>\n    <string name=\"hanning\">Ханнинг</string>\n    <string name=\"blackman\">Блацкман</string>\n    <string name=\"welch\">Велцх</string>\n    <string name=\"quadric\">Куадриц</string>\n    <string name=\"gaussian\">Гаусов</string>\n    <string name=\"sphinx\">Спхинк</string>\n    <string name=\"bartlett\">Бартлетт</string>\n    <string name=\"robidoux\">Робидоук</string>\n    <string name=\"robidoux_sharp\">Робидоук Схарп</string>\n    <string name=\"spline16\">Сплине 16</string>\n    <string name=\"spline36\">Сплине 36</string>\n    <string name=\"spline64\">Сплине 64</string>\n    <string name=\"kaiser\">Каисер</string>\n    <string name=\"bartlett_hann\">Бартлетт-Хе</string>\n    <string name=\"box\">Кутија</string>\n    <string name=\"bohman\">Бохман</string>\n    <string name=\"lanczos2\">Ланчош 2</string>\n    <string name=\"lanczos3\">Ланчош 3</string>\n    <string name=\"lanczos4\">Ланчош 4</string>\n    <string name=\"lanczos2_jinc\">Ланцзос 2 Јинц</string>\n    <string name=\"lanczos3_jinc\">Ланчош 3 Јинц</string>\n    <string name=\"lanczos4_jinc\">Ланцзос 4 Јинц</string>\n    <string name=\"cubic_sub\">Кубична интерполација обезбеђује глатко скалирање узимајући у обзир најближих 16 пиксела, дајући боље резултате од билинеарне</string>\n    <string name=\"bspline_sub\">Користи полиномске функције дефинисане по комадима за глатку интерполацију и апроксимацију криве или површине, флексибилно и континуирано представљање облика</string>\n    <string name=\"hamming_sub\">Функција прозора која се користи за смањење спектралног цурења сужавањем ивица сигнала, корисна у обради сигнала</string>\n    <string name=\"hanning_sub\">Варијанта Ханновог прозора, који се обично користи за смањење спектралног цурења у апликацијама за обраду сигнала</string>\n    <string name=\"blackman_sub\">Функција прозора која обезбеђује добру резолуцију фреквенције минимизирањем спектралног цурења, често се користи у обради сигнала</string>\n    <string name=\"welch_sub\">Функција прозора дизајнирана да даје добру резолуцију фреквенције са смањеним спектралним цурењем, која се често користи у апликацијама за обраду сигнала</string>\n    <string name=\"quadric_sub\">Метода која користи квадратну функцију за интерполацију, дајући глатке и континуиране резултате</string>\n    <string name=\"gaussian_sub\">Метода интерполације која примењује Гаусову функцију, корисна за изглађивање и смањење шума на сликама</string>\n    <string name=\"sphinx_sub\">Напредни метод поновног узорковања који обезбеђује висококвалитетну интерполацију са минималним артефактима</string>\n    <string name=\"bartlett_sub\">Функција троугластог прозора која се користи у обради сигнала за смањење спектралног цурења</string>\n    <string name=\"robidoux_sub\">Метода интерполације високог квалитета оптимизована за природну промену величине слике, балансирање оштрине и глаткоће</string>\n    <string name=\"robidoux_sharp_sub\">Оштрија варијанта Робидоук методе, оптимизована за оштру промену величине слике</string>\n    <string name=\"spline16_sub\">Метода интерполације заснована на сплине-у која даје глатке резултате користећи филтер са 16 тап</string>\n    <string name=\"spline36_sub\">Метода интерполације заснована на сплине-у која даје глатке резултате коришћењем филтера од 36 додира</string>\n    <string name=\"spline64_sub\">Метода интерполације заснована на сплине-у која даје глатке резултате користећи филтер са 64 додира</string>\n    <string name=\"kaiser_sub\">Метода интерполације која користи Кајзеров прозор, пружајући добру контролу над компромисом између ширине главног режња и нивоа бочног режња</string>\n    <string name=\"bartlett_hann_sub\">Хибридна функција прозора која комбинује прозоре Бартлетт и Ханн, која се користи за смањење спектралног цурења у обради сигнала</string>\n    <string name=\"box_sub\">Једноставан метод поновног узорковања који користи просек вредности најближих пиксела, што често доводи до блокираног изгледа</string>\n    <string name=\"bohman_sub\">Функција прозора која се користи за смањење спектралног цурења, пружајући добру резолуцију фреквенције у апликацијама за обраду сигнала</string>\n    <string name=\"lanczos2_sub\">Метода поновног узорковања која користи Ланчос филтер са 2 режња за висококвалитетну интерполацију са минималним артефактима</string>\n    <string name=\"lanczos3_sub\">Метода поновног узорковања која користи Ланцзос филтер са 3 режња за висококвалитетну интерполацију са минималним артефактима</string>\n    <string name=\"lanczos4_sub\">Метода поновног узорковања која користи Ланчос филтер са 4 режња за висококвалитетну интерполацију са минималним артефактима</string>\n    <string name=\"lanczos2_jinc_sub\">Варијанта Ланцзос 2 филтера која користи јинц функцију, пружајући висококвалитетну интерполацију са минималним артефактима</string>\n    <string name=\"lanczos3_jinc_sub\">Варијанта Ланцзос 3 филтера која користи јинц функцију, пружајући висококвалитетне интерполације са минималним артефактима</string>\n    <string name=\"lanczos4_jinc_sub\">Варијанта Ланцзос 4 филтера која користи јинц функцију, пружајући висококвалитетну интерполацију са минималним артефактима</string>\n    <string name=\"ewa_hanning\">Ханнинг ЕВА</string>\n    <string name=\"ewa_hanning_sub\">Елиптична пондерисана просек (ЕВА) варијанта Ханинговог филтера за глатку интерполацију и поновно узорковање</string>\n    <string name=\"ewa_robidoux\">Робидоук ЕВА</string>\n    <string name=\"ewa_robidoux_sub\">Еллиптицал Веигхтед Авераге (ЕВА) варијанта Робидоук филтера за висококвалитетно поновно узорковање</string>\n    <string name=\"ewa_blackman\">Блацкман ЕВЕ</string>\n    <string name=\"ewa_blackman_sub\">Еллиптицал Веигхтед Авераге (ЕВА) варијанта Блацкман филтера за минимизирање артефаката звоњења</string>\n    <string name=\"ewa_quadric\">Куадриц ЕВА</string>\n    <string name=\"ewa_quadric_sub\">Елиптични пондерисани просек (ЕВА) варијанта Куадриц филтера за глатку интерполацију</string>\n    <string name=\"ewa_robidoux_sharp\">Робидоук Схарп ЕВА</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Еллиптицал Веигхтед Авераге (ЕВА) варијанта Робидоук Схарп филтера за оштрије резултате</string>\n    <string name=\"ewa_lanczos3_jinc\">Ланцзос 3 Јинц ЕВА</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Еллиптицал Веигхтед Авераге (ЕВА) варијанта Ланцзос 3 Јинц филтера за висококвалитетно поновно узорковање са смањеним алиасингом</string>\n    <string name=\"ginseng\">Гинсенг</string>\n    <string name=\"ginseng_sub\">Филтер за поновно узорковање дизајниран за висококвалитетну обраду слике са добрим балансом оштрине и глаткоће</string>\n    <string name=\"ewa_ginseng\">Гинсенг ЕВА</string>\n    <string name=\"ewa_ginseng_sub\">Елиптична пондерисана просек (ЕВА) варијанта Гинсенг филтера за побољшани квалитет слике</string>\n    <string name=\"ewa_lanczos_sharp\">Ланцзос Схарп ЕВА</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Еллиптицал Веигхтед Авераге (ЕВА) варијанта Ланцзос Схарп филтера за постизање оштрих резултата уз минималне артефакте</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Ланцзос 4 Схарпест ЕВА</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Еллиптицал Веигхтед Авераге (ЕВА) варијанта филтера Ланцзос 4 Схарпест за изузетно оштро поновно узорковање слике</string>\n    <string name=\"ewa_lanczos_soft\">Ланцзос Софт ЕВА</string>\n    <string name=\"ewa_lanczos_soft_sub\">Еллиптицал Веигхтед Авераге (ЕВА) варијанта Ланцзос Софт филтера за глатко поновно узорковање слике</string>\n    <string name=\"haasn_soft\">Хаасн Софт</string>\n    <string name=\"haasn_soft_sub\">Филтер за поновно узорковање који је дизајнирао Хаасн за глатко скалирање слике без артефаката</string>\n    <string name=\"format_conversion\">Формат Цонверсион</string>\n    <string name=\"format_conversion_sub\">Претворите серију слика из једног формата у други</string>\n    <string name=\"dismiss_forever\">Дисмисс Форевер</string>\n    <string name=\"image_stacking\">Имаге Стацкинг</string>\n    <string name=\"image_stacking_sub\">Сложите слике једну на другу са изабраним режимима мешања</string>\n    <string name=\"add_image\">Додај слику</string>\n    <string name=\"bins_count\">Бинс цоунт</string>\n    <string name=\"clahe_hsl\">Цлахе ХСЛ</string>\n    <string name=\"clahe_hsv\">Цлахе ХСВ</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Екуализе Хистограм Адаптиве ХСЛ</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Екуализе Хистограм Адаптиве ХСВ</string>\n    <string name=\"edge_mode\">Едге Моде</string>\n    <string name=\"clip\">Цлип</string>\n    <string name=\"wrap\">Замотајте</string>\n    <string name=\"color_blind_scheme\">Далтонизам</string>\n    <string name=\"color_blind_scheme_sub\">Изаберите режим да бисте прилагодили боје теме за изабрану варијанту слепила за боје</string>\n    <string name=\"protanomaly_sub\">Потешкоће у разликовању црвене и зелене нијансе</string>\n    <string name=\"deuteranomaly_sub\">Потешкоће у разликовању зелених и црвених нијанси</string>\n    <string name=\"tritanomaly_sub\">Потешкоће у разликовању плавих и жутих нијанси</string>\n    <string name=\"protanopia_sub\">Немогућност опажања црвених нијанси</string>\n    <string name=\"deuteranopia_sub\">Немогућност опажања зелених нијанси</string>\n    <string name=\"tritanopia_sub\">Немогућност опажања плавих нијанси</string>\n    <string name=\"achromatomaly_sub\">Смањена осетљивост на све боје</string>\n    <string name=\"achromatopsia_sub\">Потпуно слепило за боје, види само нијансе сиве</string>\n    <string name=\"not_use_color_blind_scheme\">Не користите шему далтониста</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Боје ће бити тачно онако како су постављене у теми</string>\n    <string name=\"sigmoidal\">Сигмоидални</string>\n    <string name=\"lagrange_2\">Лагранж 2</string>\n    <string name=\"lagrange_2_sub\">Лагранжов интерполациони филтер реда 2, погодан за скалирање слике високог квалитета са глатким прелазима</string>\n    <string name=\"lagrange_3\">Лагранге 3</string>\n    <string name=\"lagrange_3_sub\">Лагранжов интерполациони филтер реда 3, који нуди бољу тачност и глаткије резултате за скалирање слике</string>\n    <string name=\"lanczos_6\">Ланчош 6</string>\n    <string name=\"lanczos_6_sub\">Ланчосов филтер за поновно узорковање са вишим редом од 6, пружајући оштрије и прецизније скалирање слике</string>\n    <string name=\"lanczos_6_jinc\">Ланцзос 6 Јинц</string>\n    <string name=\"lanczos_6_jinc_sub\">Варијанта Ланцзос 6 филтера који користи функцију Јинц за побољшани квалитет поновног узорковања слике</string>\n    <string name=\"linear_box_blur\">Линеар Бок Блур</string>\n    <string name=\"linear_tent_blur\">Линеар Тент Блур</string>\n    <string name=\"linear_gaussian_box_blur\">Линеар Гауссиан Бок Блур</string>\n    <string name=\"linear_stack_blur\">Линеар Стацк Блур</string>\n    <string name=\"gaussian_box_blur\">Гауссиан Бок Блур</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Линеар Фаст Гауссиан Блур Нект</string>\n    <string name=\"linear_fast_gaussian_blur\">Линеарно брзо Гаусово замућење</string>\n    <string name=\"linear_gaussian_blur\">Линеарно Гаусово замућење</string>\n    <string name=\"draw_filter_sub\">Изаберите један филтер да бисте га користили као боју</string>\n    <string name=\"replace_filter\">Замените филтер</string>\n    <string name=\"pick_filter_info\">Изаберите филтер испод да бисте га користили као четкицу на свом цртежу</string>\n    <string name=\"tiff_compression_scheme\">Шема компресије ТИФФ-а</string>\n    <string name=\"low_poly\">Лов Поли</string>\n    <string name=\"sand_painting\">Санд Паинтинг</string>\n    <string name=\"image_splitting\">Раздвајање слике</string>\n    <string name=\"image_splitting_sub\">Поделите једну слику по редовима или колонама</string>\n    <string name=\"fit_to_bounds\">Фит То Боундс</string>\n    <string name=\"fit_to_bounds_sub\">Комбинујте режим промене величине исецања са овим параметром да бисте постигли жељено понашање (Исецање/Уклапање у однос ширине и висине)</string>\n    <string name=\"languages_imported\">Језици су успешно увезени</string>\n    <string name=\"backup_ocr_models\">Резервна копија ОЦР модела</string>\n    <string name=\"import_word\">Увоз</string>\n    <string name=\"export\">Извоз</string>\n    <string name=\"position\">Положај</string>\n    <string name=\"center\">Центар</string>\n    <string name=\"top_left\">Горе лево</string>\n    <string name=\"top_right\">Горе десно</string>\n    <string name=\"bottom_left\">Доле лево</string>\n    <string name=\"bottom_right\">Доле десно</string>\n    <string name=\"top_center\">Топ Центер</string>\n    <string name=\"center_right\">Центар десно</string>\n    <string name=\"bottom_center\">Боттом Центер</string>\n    <string name=\"center_left\">Центар лево</string>\n    <string name=\"target_image\">Циљна слика</string>\n    <string name=\"palette_transfer\">Палетте Трансфер</string>\n    <string name=\"enhanced_oil\">Енханцед Оил</string>\n    <string name=\"simple_old_tv\">Једноставан стари ТВ</string>\n    <string name=\"hdr\">ХДР</string>\n    <string name=\"gotham\">Готхам</string>\n    <string name=\"simple_sketch\">Симпле Скетцх</string>\n    <string name=\"soft_glow\">Софт Глов</string>\n    <string name=\"color_poster\">Постер у боји</string>\n    <string name=\"tri_tone\">Три Тоне</string>\n    <string name=\"third_color\">Трећа боја</string>\n    <string name=\"clahe_oklab\">Цлахе Оклаб</string>\n    <string name=\"clahe_oklch\">Цлара Олцх</string>\n    <string name=\"clahe_jzazbz\">Цлахе Јзазбз</string>\n    <string name=\"polka_dot\">Полка Дот</string>\n    <string name=\"clustered_2x2_dithering\">Цлустеред 2к2 Дитхеринг</string>\n    <string name=\"clustered_4x4_dithering\">Груписани 4к4 Дитхеринг</string>\n    <string name=\"clustered_8x8_dithering\">Груписано 8к8 Дитхеринг</string>\n    <string name=\"yililoma_dithering\">Иилилома Дитхеринг</string>\n    <string name=\"no_favorite_options_selected\">Није изабрана ниједна омиљена опција, додајте их на страницу са алаткама</string>\n    <string name=\"add_favorites\">Додај фаворите</string>\n    <string name=\"harmony_complementary\">Комплементарно</string>\n    <string name=\"harmony_analogous\">Аналогно</string>\n    <string name=\"harmony_triadic\">Триадиц</string>\n    <string name=\"harmony_split_complementary\">Сплит Цомплементари</string>\n    <string name=\"harmony_tetradic\">Тетрадиц</string>\n    <string name=\"harmony_square\">Скуаре</string>\n    <string name=\"harmony_analogous_complementary\">Аналогно + комплементарно</string>\n    <string name=\"color_tools\">Цолор Тоолс</string>\n    <string name=\"color_tools_sub\">Мешајте, правите тонове, стварајте нијансе и још много тога</string>\n    <string name=\"color_harmonies\">Цолор Хармониес</string>\n    <string name=\"color_shading\">Сјенчање боја</string>\n    <string name=\"variation\">Варијација</string>\n    <string name=\"tints\">Нијансе</string>\n    <string name=\"tones\">Тонови</string>\n    <string name=\"shades\">Схадес</string>\n    <string name=\"color_mixing\">Мешање боја</string>\n    <string name=\"color_info\">Информације о боји</string>\n    <string name=\"selected_color\">Изабрана боја</string>\n    <string name=\"color_to_mix\">Боја за мешање</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Не може да се користи монет док су динамичке боје укључене</string>\n    <string name=\"lut512x512\">512к512 2Д ЛУТ</string>\n    <string name=\"target_lut_image\">Циљна ЛУТ слика</string>\n    <string name=\"amatorka\">Аматер</string>\n    <string name=\"miss_etikate\">Мисс Етикуетте</string>\n    <string name=\"soft_elegance\">Софт Елеганце</string>\n    <string name=\"soft_elegance_variant\">Варијанта меке елеганције</string>\n    <string name=\"palette_transfer_variant\">Варијанта преноса палете</string>\n    <string name=\"cube_lut\">3Д ЛУТ</string>\n    <string name=\"target_cube_lut_file\">Циљна 3Д ЛУТ датотека (.цубе / .ЦУБЕ)</string>\n    <string name=\"lut\">ЛУТ</string>\n    <string name=\"bleach_bypass\">Блеацх Бипасс</string>\n    <string name=\"candlelight\">Свећа</string>\n    <string name=\"drop_blues\">Дроп Блуес</string>\n    <string name=\"edgy_amber\">Едги Амбер</string>\n    <string name=\"fall_colors\">Фалл Цолорс</string>\n    <string name=\"film_stock_50\">Филмска залиха 50</string>\n    <string name=\"foggy_night\">Магловита ноћ</string>\n    <string name=\"kodak\">Кодак</string>\n    <string name=\"save_empty_lut\">Добијте неутралну ЛУТ слику</string>\n    <string name=\"save_empty_lut_sub\">Прво користите своју омиљену апликацију за уређивање фотографија да примените филтер на неутрални ЛУТ који можете добити овде. Да би ово исправно функционисало, свака боја пиксела не сме да зависи од других пиксела (нпр. замућење неће функционисати). Када будете спремни, користите своју нову ЛУТ слику као улаз за 512*512 ЛУТ филтер</string>\n    <string name=\"pop_art\">Поп Арт</string>\n    <string name=\"celluloid\">Целулоид</string>\n    <string name=\"coffee\">кафу</string>\n    <string name=\"golden_forest\">Златна шума</string>\n    <string name=\"greenish\">Зеленкасто</string>\n    <string name=\"retro_yellow\">Ретро Иеллов</string>\n    <string name=\"links_preview\">Преглед линкова</string>\n    <string name=\"links_preview_sub\">Омогућава преузимање прегледа линка на местима где можете да добијете текст (КРЦ код, ОЦР итд.)</string>\n    <string name=\"links\">Линкови</string>\n    <string name=\"ico_size_warning\">ИЦО датотеке се могу сачувати само у максималној величини од 256 к 256</string>\n    <string name=\"gif_type_to_webp\">ГИФ на ВЕБП</string>\n    <string name=\"gif_type_to_webp_sub\">Претворите ГИФ слике у ВЕБП анимиране слике</string>\n    <string name=\"webp_tools\">ВЕБП Тоолс</string>\n    <string name=\"webp_tools_sub\">Претворите слике у ВЕБП анимирану слику или издвојите оквире из дате ВЕБП анимације</string>\n    <string name=\"webp_type_to_image\">ВЕБП на слике</string>\n    <string name=\"webp_type_to_image_sub\">Претворите ВЕБП датотеку у групу слика</string>\n    <string name=\"webp_type_to_webp_sub\">Претворите серију слика у ВЕБП датотеку</string>\n    <string name=\"webp_type_to_webp\">Слике на ВЕБП</string>\n    <string name=\"select_webp_image_to_start\">Изаберите ВЕБП слику за почетак</string>\n    <string name=\"manage_storage_extra_types\">Нема пуног приступа датотекама</string>\n    <string name=\"manage_storage_extra_types_sub\">Дозволите приступ свим датотекама да бисте видели ЈКСЛ, КОИ и друге слике које нису препознате као слике на Андроид-у. Без дозволе Имаге Тоолбок не може да прикаже те слике</string>\n    <string name=\"default_draw_color\">Подразумевана боја цртања</string>\n    <string name=\"default_draw_path_mode\">Подразумевани режим цртања путање</string>\n    <string name=\"add_timestamp\">Додај временску ознаку</string>\n    <string name=\"add_timestamp_sub\">Омогућава додавање временске ознаке имену излазне датотеке</string>\n    <string name=\"formatted_timestamp\">Форматирана временска ознака</string>\n    <string name=\"formatted_timestamp_sub\">Омогућите форматирање временске ознаке у називу излазне датотеке уместо основних милиса</string>\n    <string name=\"enable_timestamps_to_format_them\">Омогућите временске ознаке да изаберете њихов формат</string>\n    <string name=\"one_time_save_location\">Локација за једнократну уштеду</string>\n    <string name=\"one_time_save_location_sub\">Прегледајте и уредите једнократне локације за чување које можете користити дугим притиском на дугме за чување углавном у свим опцијама</string>\n    <string name=\"recently_used\">Недавно коришћено</string>\n    <string name=\"ci_channel\">ЦИ канал</string>\n    <string name=\"group\">Група</string>\n    <string name=\"image_toolbox_in_telegram\">Кутија са алаткама за слике у Телеграму 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Придружите се нашем ћаскању где можете да разговарате о свему што желите и такође погледајте ЦИ канал где објављујем бета верзије и најаве</string>\n    <string name=\"ci_channel_sub\">Добијајте обавештења о новим верзијама апликације и читајте најаве</string>\n    <string name=\"fit_description\">Прилагодите слику датим димензијама и примените замућење или боју на позадину</string>\n    <string name=\"tools_arrangement\">Аранжман алата</string>\n    <string name=\"group_tools_by_type\">Групирајте алате по типу</string>\n    <string name=\"group_tools_by_type_sub\">Групише алате на главном екрану према њиховом типу уместо према прилагођеном распореду листе</string>\n    <string name=\"default_values\">Подразумеване вредности</string>\n    <string name=\"system_bars_visibility\">Видљивост системских трака</string>\n    <string name=\"show_system_bars_by_swipe\">Прикажи системске траке превлачењем</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Омогућава превлачење за приказ системских трака ако су скривене</string>\n    <string name=\"auto\">Ауто</string>\n    <string name=\"hide_all\">Сакриј све</string>\n    <string name=\"show_all\">Прикажи све</string>\n    <string name=\"hide_nav_bar\">Сакриј траку за навигацију</string>\n    <string name=\"hide_status_bar\">Сакриј статусну траку</string>\n    <string name=\"noise_generation\">Генерисање буке</string>\n    <string name=\"noise_generation_sub\">Генеришите различите звукове попут Перлина или других врста</string>\n    <string name=\"frequency\">Фреквенција</string>\n    <string name=\"noise_type\">Тип буке</string>\n    <string name=\"rotation_type\">Ротатион Типе</string>\n    <string name=\"fractal_type\">Фрактални тип</string>\n    <string name=\"octaves\">Октаве</string>\n    <string name=\"lacunarity\">Лакунарност</string>\n    <string name=\"gain\">Добитак</string>\n    <string name=\"weighted_strength\">Веигхтед Стренгтх</string>\n    <string name=\"ping_pong_strength\">Снага за пинг понг</string>\n    <string name=\"distance_function\">Функција удаљености</string>\n    <string name=\"return_type\">Ретурн Типе</string>\n    <string name=\"jitter\">Јиттер</string>\n    <string name=\"domain_warp\">Домаин Варп</string>\n    <string name=\"alignment\">Поравнање</string>\n    <string name=\"custom_filename\">Прилагођено име датотеке</string>\n    <string name=\"custom_filename_sub\">Изаберите локацију и назив датотеке који ће се користити за чување тренутне слике</string>\n    <string name=\"saved_to_custom\">Сачувано у фасциклу са прилагођеним именом</string>\n    <string name=\"collage_maker\">Цоллаге Макер</string>\n    <string name=\"collage_maker_sub\">Направите колаже од до 20 слика</string>\n    <string name=\"collage_type\">Цоллаге Типе</string>\n    <string name=\"collages_info\">Држите слику за замену, померање и зумирање да бисте подесили положај</string>\n    <string name=\"disable_rotation\">Онемогући ротацију</string>\n    <string name=\"disable_rotation_sub\">Спречава ротирање слика покретима са два прста</string>\n    <string name=\"enable_snapping_to_borders\">Омогућите спајање на ивице</string>\n    <string name=\"enable_snapping_to_borders_sub\">Након померања или зумирања, слике ће шкљоцнути да попуне ивице оквира</string>\n    <string name=\"histogram\">Хистограм</string>\n    <string name=\"histogram_sub\">РГБ или Бригхтнесс хистограм слике који ће вам помоћи да извршите подешавања</string>\n    <string name=\"image_for_histogram\">Ова слика ће се користити за генерисање РГБ и Бригхтнесс хистограма</string>\n    <string name=\"tesseract_options\">Тессерацт Оптионс</string>\n    <string name=\"tesseract_options_sub\">Примените неке улазне варијабле за тесеракт мотор</string>\n    <string name=\"custom_options\">Прилагођене опције</string>\n    <string name=\"custom_params_info\">Опције треба унети према овом шаблону: \\\"--{оптион_наме} {валуе}\\\"</string>\n    <string name=\"auto_crop\">Ауто Цроп</string>\n    <string name=\"free_corners\">Фрее Цорнерс</string>\n    <string name=\"free_corners_sub\">Изрежите слику по полигон, ово такође исправља перспективу</string>\n    <string name=\"coerce_points_to_image_bounds\">Присиљавање указује на границе слике</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Тачке неће бити ограничене границама слике, што је корисно за прецизније исправљање перспективе</string>\n    <string name=\"mask\">Маска</string>\n    <string name=\"spot_heal_sub\">Испуна под уцртаном путањом свесна садржаја</string>\n    <string name=\"spot_heal\">Хеал Спот</string>\n    <string name=\"use_circle_kernel\">Користите Цирцле Кернел</string>\n    <string name=\"opening\">Отварање</string>\n    <string name=\"closing\">Затварање</string>\n    <string name=\"morphological_gradient\">Морфолошки градијент</string>\n    <string name=\"top_hat\">Топ Хат</string>\n    <string name=\"black_hat\">Црни шешир</string>\n    <string name=\"tone_curves\">Тоне Цурвес</string>\n    <string name=\"reset_curves\">Ресетујте криве</string>\n    <string name=\"reset_curves_sub\">Криве ће бити враћене на подразумевану вредност</string>\n    <string name=\"line_style\">Стил линије</string>\n    <string name=\"gap_size\">Гап Сизе</string>\n    <string name=\"dashed\">Дасхед</string>\n    <string name=\"dot_dashed\">Дот Дасхед</string>\n    <string name=\"stamped\">Стампед</string>\n    <string name=\"zigzag\">цик-цак</string>\n    <string name=\"dashed_sub\">Црта испрекидану линију дуж нацртане путање са наведеном величином размака</string>\n    <string name=\"dot_dashed_sub\">Црта тачку и испрекидану линију дуж дате путање</string>\n    <string name=\"defaultt_sub\">Само подразумеване равне линије</string>\n    <string name=\"stamped_sub\">Црта изабране облике дуж путање са одређеним размаком</string>\n    <string name=\"zigzag_sub\">Црта таласасте цик-цак дуж стазе</string>\n    <string name=\"zigzag_ratio\">Цик-цак однос</string>\n    <string name=\"create_shortcut\">Креирајте пречицу</string>\n    <string name=\"create_shortcut_title\">Изаберите алатку за закачење</string>\n    <string name=\"create_shortcut_subtitle\">Алат ће бити додат на почетни екран вашег покретача као пречица, користите га у комбинацији са поставком „Прескочи бирање датотека“ да бисте постигли потребно понашање</string>\n    <string name=\"dont_stack_frames\">Немојте слагати оквире</string>\n    <string name=\"dont_stack_frames_sub\">Омогућава одлагање претходних оквира, тако да се неће слагати један на други</string>\n    <string name=\"crossfade\">Цроссфаде</string>\n    <string name=\"crossfade_sub\">Оквири ће бити укрштени један у други</string>\n    <string name=\"crossfade_count\">Број фрејмова са унакрсним бледењем</string>\n    <string name=\"threshold_one\">Праг један</string>\n    <string name=\"threshold_two\">Праг два</string>\n    <string name=\"canny\">Цанни</string>\n    <string name=\"mirror_101\">Огледало 101</string>\n    <string name=\"enhanced_zoom_blur\">Побољшано замућење зума</string>\n    <string name=\"laplacian_simple\">Лапласов Симпле</string>\n    <string name=\"sobel_simple\">Собел Симпле</string>\n    <string name=\"helper_grid\">Помоћна мрежа</string>\n    <string name=\"helper_grid_sub\">Приказује помоћну мрежу изнад области за цртање да би се помогло прецизним манипулацијама</string>\n    <string name=\"grid_color\">Боја мреже</string>\n    <string name=\"cell_width\">Целл Видтх</string>\n    <string name=\"cell_height\">Висина ћелије</string>\n    <string name=\"compact_selectors\">Компактни селектори</string>\n    <string name=\"compact_selectors_sub\">Неке контроле избора ће користити компактан распоред да заузму мање простора</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Дајте камери дозволу у подешавањима за снимање слике</string>\n    <string name=\"layout\">Лаиоут</string>\n    <string name=\"main_screen_title\">Наслов главног екрана</string>\n    <string name=\"constant_rate_factor\">Фактор константне стопе (ЦРФ)</string>\n    <string name=\"crf_sub\">Вредност %1$s значи спору компресију, што резултира релативно малом величином датотеке. %2$s значи бржу компресију, што резултира великом датотеком.</string>\n    <string name=\"lut_library\">Лут Либрари</string>\n    <string name=\"lut_library_sub\">Преузмите колекцију ЛУТ-ова, коју можете применити након преузимања</string>\n    <string name=\"lut_library_update_sub\">Ажурирајте колекцију ЛУТ-ова (само нови ће бити стављени у ред чекања), коју можете применити након преузимања</string>\n    <string name=\"filter_preview_image_sub\">Промените подразумевани преглед слике за филтере</string>\n    <string name=\"filter_preview_image\">Преглед слике</string>\n    <string name=\"hide\">Сакриј се</string>\n    <string name=\"show\">Схов</string>\n    <string name=\"slider_type\">Тип клизача</string>\n    <string name=\"fancy\">Фанци</string>\n    <string name=\"material_2\">Материјал 2</string>\n    <string name=\"fancy_sub\">Фантастичан клизач. Ово је подразумевана опција</string>\n    <string name=\"material_2_sub\">А Материал 2 клизач</string>\n    <string name=\"material_you_slider_sub\">Клизач за материјал</string>\n    <string name=\"apply\">Пријавите се</string>\n    <string name=\"center_align_dialog_buttons\">Централна дугмад за дијалог</string>\n    <string name=\"center_align_dialog_buttons_sub\">Дугмад дијалога ће бити позиционирана у средини уместо на левој страни ако је могуће</string>\n    <string name=\"open_source_licenses\">Лиценце отвореног кода</string>\n    <string name=\"open_source_licenses_sub\">Погледајте лиценце библиотека отвореног кода које се користе у овој апликацији</string>\n    <string name=\"area\">Подручје</string>\n    <string name=\"area_sub\">Поновно узорковање коришћењем односа површине пиксела. То може бити пожељан метод за децимацију слике, јер даје резултате без муара. Али када је слика зумирана, она је слична методи „Најближи“.</string>\n    <string name=\"enable_tonemapping\">Омогући мапирање тонова</string>\n    <string name=\"enter_percent\">Унесите %</string>\n    <string name=\"unknown_host\">Не можете да приступите сајту, покушајте да користите ВПН или проверите да ли је урл тачан</string>\n    <string name=\"markup_layers\">Маркуп Лаиерс</string>\n    <string name=\"markup_layers_sub\">Режим слојева са могућношћу слободног постављања слика, текста и још много тога</string>\n    <string name=\"edit_layer\">Уреди слој</string>\n    <string name=\"layers_on_image\">Слојеви на слици</string>\n    <string name=\"layers_on_image_sub\">Користите слику као позадину и додајте различите слојеве на њу</string>\n    <string name=\"layers_on_background\">Слојеви на позадини</string>\n    <string name=\"layers_on_background_sub\">Исто као и прва опција, али са бојом уместо слике</string>\n    <string name=\"beta\">Бета</string>\n    <string name=\"fast_settings_side\">Фаст Сеттингс Сиде</string>\n    <string name=\"fast_settings_side_sub\">Додајте плутајућу траку на изабрану страну док уређујете слике, која ће отворити брза подешавања када се кликне</string>\n    <string name=\"clear_selection\">Обриши избор</string>\n    <string name=\"settings_group_visibility_hidden\">Група подешавања \\\"%1$s\\\" ће подразумевано бити скупљена</string>\n    <string name=\"settings_group_visibility_visible\">Група подешавања \\\"%1$s\\\" ће подразумевано бити проширена</string>\n    <string name=\"base_64_tools\">Басе64 Тоолс</string>\n    <string name=\"base_64_tools_sub\">Декодирајте Басе64 стринг у слику или кодирајте слику у Басе64 формат</string>\n    <string name=\"base_64\">Басе64</string>\n    <string name=\"not_a_valid_base_64\">Наведена вредност није важећи Басе64 стринг</string>\n    <string name=\"copy_not_a_valid_base_64\">Није могуће копирати празан или неважећи низ Басе64</string>\n    <string name=\"paste_base_64\">Пасте Басе64</string>\n    <string name=\"copy_base_64\">Цопи Басе64</string>\n    <string name=\"base_64_tips\">Учитајте слику да бисте копирали или сачували Басе64 стринг. Ако имате сам низ, можете га налепити изнад да бисте добили слику</string>\n    <string name=\"save_base_64\">Саве Басе64</string>\n    <string name=\"share_base_64\">Схаре Басе64</string>\n    <string name=\"options\">Опције</string>\n    <string name=\"actions\">Акције</string>\n    <string name=\"import_base_64\">Импорт Басе64</string>\n    <string name=\"base_64_actions\">Басе64 Ацтионс</string>\n    <string name=\"add_outline\">Адд Оутлине</string>\n    <string name=\"add_outline_sub\">Додајте обрис око текста са наведеном бојом и ширином</string>\n    <string name=\"outline_color\">Боја контуре</string>\n    <string name=\"outline_size\">Оутлине Сизе</string>\n    <string name=\"rotation\">Ротација</string>\n    <string name=\"checksum_as_filename\">Контролна сума као име датотеке</string>\n    <string name=\"checksum_as_filename_sub\">Излазне слике ће имати назив који одговара њиховој контролној суми података</string>\n    <string name=\"free_software_partner\">Бесплатни софтвер (Партнер)</string>\n    <string name=\"free_software_partner_sub\">Још кориснији софтвер на партнерском каналу Андроид апликација</string>\n    <string name=\"algorithms\">Алгоритам</string>\n    <string name=\"checksum_tools\">Алати за проверу</string>\n    <string name=\"checksum_tools_sub\">Упоредите контролне суме, израчунајте хешове или креирајте хексадецималне низове из датотека користећи различите алгоритме хеширања</string>\n    <string name=\"calculate\">Израчунај</string>\n    <string name=\"text_hash\">Тект Хасх</string>\n    <string name=\"checksum\">Контролни збир</string>\n    <string name=\"pick_file_to_checksum\">Изаберите датотеку да бисте израчунали њен контролни збир на основу изабраног алгоритма</string>\n    <string name=\"enter_text_to_checksum\">Унесите текст да бисте израчунали његову контролну суму на основу изабраног алгоритма</string>\n    <string name=\"source_checksum\">Изворна контролна сума</string>\n    <string name=\"checksum_to_compare\">Контролни збир за поређење</string>\n    <string name=\"match\">Матцх!</string>\n    <string name=\"difference\">Разлика</string>\n    <string name=\"match_sub\">Контролне суме су једнаке, може бити безбедно</string>\n    <string name=\"difference_sub\">Контролне суме нису једнаке, датотека може бити несигурна!</string>\n    <string name=\"mesh_gradients\">Месх Градиентс</string>\n    <string name=\"collection_mesh_gradients_sub\">Погледајте онлајн колекцију Месх Градијената</string>\n    <string name=\"wrong_font\">Могу се увести само ТТФ и ОТФ фонтови</string>\n    <string name=\"import_font\">Увезите фонт (ТТФ/ОТФ)</string>\n    <string name=\"export_fonts\">Извези фонтове</string>\n    <string name=\"imported_fonts\">Увезени фонтови</string>\n    <string name=\"error_while_saving\">Грешка при покушају чувања, покушајте да промените излазну фасциклу</string>\n    <string name=\"filename_is_not_set\">Име датотеке није подешено</string>\n    <string name=\"none\">Ниједан</string>\n    <string name=\"custom_pages\">Прилагођене странице</string>\n    <string name=\"pages_selection\">Избор страница</string>\n    <string name=\"tool_exit_confirmation\">Потврда излаза из алатке</string>\n    <string name=\"tool_exit_confirmation_sub\">Ако имате несачуване промене док користите одређене алате и покушате да их затворите, тада ће се приказати дијалог за потврду</string>\n    <string name=\"edit_exif_screen\">Уреди ЕКСИФ</string>\n    <string name=\"edit_exif_screen_sub\">Промените метаподатке једне слике без поновне компресије</string>\n    <string name=\"edit_exif_tag\">Додирните да бисте изменили доступне ознаке</string>\n    <string name=\"change_sticker\">Цханге Стицкер</string>\n    <string name=\"fit_width\">Фит Видтх</string>\n    <string name=\"fit_height\">Фит Хеигхт</string>\n    <string name=\"batch_compare\">Батцх Цомпаре</string>\n    <string name=\"pick_files_to_checksum\">Изаберите датотеку/датотеке да бисте израчунали њен контролни збир на основу изабраног алгоритма</string>\n    <string name=\"pick_files\">Изаберите датотеке</string>\n    <string name=\"pick_directory\">Изаберите именик</string>\n    <string name=\"head_length_scale\">Скала дужине главе</string>\n    <string name=\"stamp\">Печат</string>\n    <string name=\"timestamp\">Временска ознака</string>\n    <string name=\"format_pattern\">Формат Паттерн</string>\n    <string name=\"padding\">Паддинг</string>\n    <string name=\"image_cutting\">Резање слике</string>\n    <string name=\"image_cutting_sub\">Изрежите део слике и спојите леве (може бити инверзне) вертикалним или хоризонталним линијама</string>\n    <string name=\"vertical_pivot_line\">Вертикална обртна линија</string>\n    <string name=\"horizontal_pivot_line\">Хоризонтална обртна линија</string>\n    <string name=\"inverse_selection\">Инверзна селекција</string>\n    <string name=\"inverse_vertical_selection_sub\">Вертикални исечени део ће бити остављен, уместо спајања делова око области реза</string>\n    <string name=\"inverse_horizontal_selection_sub\">Хоризонтални исечени део ће бити остављен, уместо спајања делова око области реза</string>\n    <string name=\"collection_mesh_gradients\">Збирка мрежастих градијента</string>\n    <string name=\"mesh_gradients_sub\">Направите градијент мреже са прилагођеном количином чворова и резолуцијом</string>\n    <string name=\"gradient_maker_type_image_mesh\">Месх Градиент Оверлаи</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Направи мрежасти градијент врха датих слика</string>\n    <string name=\"points_customization\">Поинтс Цустомизатион</string>\n    <string name=\"grid_size\">Величина мреже</string>\n    <string name=\"resolution_x\">Резолуција Кс</string>\n    <string name=\"resolution_y\">Резолуција И</string>\n    <string name=\"resolution\">Резолуција</string>\n    <string name=\"pixel_by_pixel\">Пикел Би Пикел</string>\n    <string name=\"highlight_color\">Хигхлигхт Цолор</string>\n    <string name=\"pixel_comparison_type\">Тип поређења пиксела</string>\n    <string name=\"scan_barcode\">Скенирајте бар код</string>\n    <string name=\"height_ratio\">Однос висине</string>\n    <string name=\"barcode_type\">Тип баркода</string>\n    <string name=\"enforce_bw\">Спровести црно-бело</string>\n    <string name=\"enforce_bw_sub\">Слика бар кода ће бити потпуно црно-бела и неће бити обојена темом апликације</string>\n    <string name=\"barcodes_sub\">Скенирајте било који бар код (КР, ЕАН, АЗТЕЦ,…) и преузмите његов садржај или налепите свој текст да бисте генерисали нови</string>\n    <string name=\"no_barcode_found\">Баркод није пронађен</string>\n    <string name=\"generated_barcode_will_be_here\">Генерисани бар код ће бити овде</string>\n    <string name=\"audio_cover_extractor\">Аудио омоти</string>\n    <string name=\"audio_cover_extractor_sub\">Извуците слике омота албума из аудио датотека, подржани су најчешћи формати</string>\n    <string name=\"pick_audio_to_start\">Изаберите аудио за почетак</string>\n    <string name=\"pick_audio\">Изаберите Аудио</string>\n    <string name=\"no_covers_found\">Но Цоверс Фоунд</string>\n    <string name=\"send_logs\">Пошаљи дневнике</string>\n    <string name=\"send_logs_sub\">Кликните да бисте поделили датотеку евиденције апликације, ово ми може помоћи да уочим проблем и решим проблеме</string>\n    <string name=\"crash_title\">Упс… Нешто је пошло наопако</string>\n    <string name=\"crash_subtitle\">Можете ме контактирати користећи опције испод и покушаћу да пронађем решење.\\н(Не заборавите да приложите евиденције)</string>\n    <string name=\"ocr_write_to_file\">Врите То Филе</string>\n    <string name=\"ocr_write_to_file_sub\">Извуците текст из серије слика и сачувајте га у једној текстуалној датотеци</string>\n    <string name=\"ocr_write_to_metadata\">Врите То Метадата</string>\n    <string name=\"ocr_write_to_metadata_sub\">Извуците текст из сваке слике и ставите га у ЕКСИФ информације релативних фотографија</string>\n    <string name=\"invisible_mode\">Невидљиви режим</string>\n    <string name=\"invisible_mode_sub\">Користите стеганографију да направите оку невидљиве водене жигове унутар бајтова ваших слика</string>\n    <string name=\"use_lsb\">Користите ЛСБ</string>\n    <string name=\"use_lsb_sub\">Метода стеганографије ЛСБ (мање значајног бита) ће се користити, у супротном ФД (фреквенцијски домен)</string>\n    <string name=\"auto_remove_red_eyes\">Аутоматско уклањање црвених очију</string>\n    <string name=\"password\">Лозинка</string>\n    <string name=\"unlock\">Откључај</string>\n    <string name=\"pdf_is_protected\">ПДФ је заштићен</string>\n    <string name=\"operation_almost_complete\">Операција је скоро завршена. Отказивање сада захтева поновно покретање</string>\n    <string name=\"sort_by_date_modified\">Датум измене</string>\n    <string name=\"sort_by_date_modified_reversed\">Датум измене (обрнуто)</string>\n    <string name=\"sort_by_size\">Величина</string>\n    <string name=\"sort_by_size_reversed\">Величина (обрнуто)</string>\n    <string name=\"sort_by_mime_type\">МИМЕ Типе</string>\n    <string name=\"sort_by_mime_type_reversed\">МИМЕ тип (обрнуто)</string>\n    <string name=\"sort_by_extension\">Продужетак</string>\n    <string name=\"sort_by_extension_reversed\">Продужетак (обрнуто)</string>\n    <string name=\"sort_by_date_added\">Датум додавања</string>\n    <string name=\"sort_by_date_added_reversed\">Датум додавања (обрнуто)</string>\n    <string name=\"left_to_right\">С лева на десно</string>\n    <string name=\"right_to_left\">Десно налево</string>\n    <string name=\"top_to_bottom\">Од врха до дна</string>\n    <string name=\"bottom_to_top\">Одоздо ка врху</string>\n    <string name=\"liquid_glass\">Течно стакло</string>\n    <string name=\"liquid_glass_sub\">Прекидач заснован на недавно најављеном ИОС 26 и његовом систему дизајна течног стакла</string>\n    <string name=\"pick_image_or_base64\">Изаберите слику или налепите/увезите Басе64 податке испод</string>\n    <string name=\"type_image_link\">Унесите везу за слику да бисте започели</string>\n    <string name=\"paste_link\">Налепите везу</string>\n    <string name=\"kaleidoscope\">Калеидосцопе</string>\n    <string name=\"secondary_angle\">Секундарни угао</string>\n    <string name=\"sides\">Сидес</string>\n    <string name=\"channel_mix\">Цханнел Мик</string>\n    <string name=\"blue_green\">Плаво зелено</string>\n    <string name=\"red_blue\">Црвено плаво</string>\n    <string name=\"green_red\">Зелено црвено</string>\n    <string name=\"into_red\">У црвено</string>\n    <string name=\"into_green\">У зелено</string>\n    <string name=\"into_blue\">У плаво</string>\n    <string name=\"cyan\">Циан</string>\n    <string name=\"magenta\">Магента</string>\n    <string name=\"yellow\">Жута</string>\n    <string name=\"color_halftone\">Цолоур Халфтоне</string>\n    <string name=\"contour\">Цонтоур</string>\n    <string name=\"levels\">Нивои</string>\n    <string name=\"offset\">Оффсет</string>\n    <string name=\"voronoi_crystallize\">Воронои Цристаллизе</string>\n    <string name=\"shape\">Облик</string>\n    <string name=\"stretch\">Стретцх</string>\n    <string name=\"randomness\">Случајност</string>\n    <string name=\"despeckle\">Деспецкле</string>\n    <string name=\"diffuse\">Дифузно</string>\n    <string name=\"dog\">ДоГ</string>\n    <string name=\"second_radius\">Други радијус</string>\n    <string name=\"equalize\">Изједначити</string>\n    <string name=\"glow\">Глов</string>\n    <string name=\"whirl_and_pinch\">Вртлог и штипање</string>\n    <string name=\"pointillize\">Поинтилизе</string>\n    <string name=\"border_color\">Боја ивице</string>\n    <string name=\"polar_coordinates\">Поларне координате</string>\n    <string name=\"rect_to_polar\">Рецт то полар</string>\n    <string name=\"polar_to_rect\">Поларни до правоугаони</string>\n    <string name=\"invert_in_circle\">Обрни у круг</string>\n    <string name=\"reduce_noise\">Редуце Ноисе</string>\n    <string name=\"simple_solarize\">Симпле Соларизе</string>\n    <string name=\"weave\">Веаве</string>\n    <string name=\"x_gap\">Кс Гап</string>\n    <string name=\"y_gap\">И Гап</string>\n    <string name=\"x_width\">Кс ширина</string>\n    <string name=\"y_wdth\">И Видтх</string>\n    <string name=\"twirl\">Твирл</string>\n    <string name=\"rubber_stmp\">Руббер Стамп</string>\n    <string name=\"smear\">Смеар</string>\n    <string name=\"density\">Густина</string>\n    <string name=\"mix\">Мик</string>\n    <string name=\"sphere_lensh_distortion\">Дисторзија сферног сочива</string>\n    <string name=\"refraction_index\">Индекс преламања</string>\n    <string name=\"arc\">Арц</string>\n    <string name=\"spread_angle\">Угао ширења</string>\n    <string name=\"sparkle\">Спаркле</string>\n    <string name=\"rays\">Раис</string>\n    <string name=\"ascii\">АСЦИИ</string>\n    <string name=\"gradient\">Градијент</string>\n    <string name=\"moire\">Мари</string>\n    <string name=\"autumn\">јесен</string>\n    <string name=\"bone\">Боне</string>\n    <string name=\"jet\">Јет</string>\n    <string name=\"winter\">Зима</string>\n    <string name=\"ocean\">Оцеан</string>\n    <string name=\"summer\">Лето</string>\n    <string name=\"spring\">пролеће</string>\n    <string name=\"cool_variant\">Цоол Вариант</string>\n    <string name=\"hsv\">ХСВ</string>\n    <string name=\"pink\">Пинк</string>\n    <string name=\"hot\">Хот</string>\n    <string name=\"parula\">Реч</string>\n    <string name=\"magma\">Магма</string>\n    <string name=\"inferno\">Инферно</string>\n    <string name=\"plasma\">Плазма</string>\n    <string name=\"viridis\">Виридис</string>\n    <string name=\"cividis\">Грађани</string>\n    <string name=\"twilight\">Твилигхт</string>\n    <string name=\"twilight_shifted\">Твилигхт Схифтед</string>\n    <string name=\"auto_perspective\">Перспецтиве Ауто</string>\n    <string name=\"deskew\">Дескев</string>\n    <string name=\"allow_crop\">Дозволи обрезивање</string>\n    <string name=\"crop_or_perspective\">Обрезивање или перспектива</string>\n    <string name=\"absolute\">Апсолутно</string>\n    <string name=\"turbo\">Турбо</string>\n    <string name=\"deep_green\">Дееп Греен</string>\n    <string name=\"lens_correction\">Ленс Цоррецтион</string>\n    <string name=\"target_lens_profile\">Датотека профила циљног сочива у ЈСОН формату</string>\n    <string name=\"download_ready_lens_profiles\">Преузмите спремне профиле сочива</string>\n    <string name=\"part_percents\">Део процената</string>\n    <string name=\"export_as_json\">Извези као ЈСОН</string>\n    <string name=\"export_as_json_sub\">Копирајте стринг са подацима о палети као јсон приказ</string>\n    <string name=\"seam_carving\">Сеам Царвинг</string>\n    <string name=\"home_screen\">Почетни екран</string>\n    <string name=\"lock_screen\">Закључавање екрана</string>\n    <string name=\"built_in\">Уграђени</string>\n    <string name=\"wallpapers_export\">Извоз позадина</string>\n    <string name=\"refresh\">Освежи</string>\n    <string name=\"wallpapers_export_sub\">Набавите тренутне позадине за дом, закључавање и уграђене позадине</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Дозволите приступ свим датотекама, ово је потребно за преузимање позадина</string>\n    <string name=\"allow_read_media_images_for_wp\">Дозвола за управљање спољним складиштем није довољна, потребно је да дозволите приступ својим сликама, обавезно изаберите „Дозволи све“</string>\n    <string name=\"add_preset_to_filename\">Додај унапред подешено име датотеке</string>\n    <string name=\"add_preset_to_filename_sub\">Додаје суфикс са изабраним унапред подешеним именом датотеке слике</string>\n    <string name=\"add_image_scale_mode_to_filename\">Додајте режим размере слике имену датотеке</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Додаје суфикс са изабраним режимом размера слике имену датотеке слике</string>\n    <string name=\"ascii_art\">Асции Арт</string>\n    <string name=\"ascii_art_sub\">Претворите слику у асции текст који ће изгледати као слика</string>\n    <string name=\"params\">Парамс</string>\n    <string name=\"invert_colors_ascii_sub\">Примењује негативни филтер на слику за бољи резултат у неким случајевима</string>\n    <string name=\"processing_screenshot\">Обрада снимка екрана</string>\n    <string name=\"screenshot_not_captured_try_again\">Снимак екрана није снимљен, покушајте поново</string>\n    <string name=\"skipped_saving\">Чување је прескочено</string>\n    <string name=\"skipped_saving_multiple\">%1$s датотека је прескочено</string>\n    <string name=\"allow_skip_if_larger\">Дозволи прескакање ако је веће</string>\n    <string name=\"allow_skip_if_larger_sub\">Неким алатима ће бити дозвољено да прескоче чување слика ако би резултујућа величина датотеке била већа од оригиналне</string>\n    <string name=\"qr_type_calendar_event\">Календарски догађај</string>\n    <string name=\"qr_type_contact_info\">Контакт</string>\n    <string name=\"qr_type_email\">Емаил</string>\n    <string name=\"qr_type_geo_point\">Локација</string>\n    <string name=\"qr_type_phone\">Телефон</string>\n    <string name=\"qr_type_plain\">Текст</string>\n    <string name=\"qr_type_sms\">СМС</string>\n    <string name=\"qr_type_url\">УРЛ</string>\n    <string name=\"qr_type_wifi\">Ви-Фи</string>\n    <string name=\"open_network\">Отворена мрежа</string>\n    <string name=\"not_specified\">Н/А</string>\n    <string name=\"ssid\">ССИД</string>\n    <string name=\"phone\">Телефон</string>\n    <string name=\"message\">Порука</string>\n    <string name=\"address\">Адреса</string>\n    <string name=\"subject\">Предмет</string>\n    <string name=\"body\">Тело</string>\n    <string name=\"name\">Име</string>\n    <string name=\"organization\">Организација</string>\n    <string name=\"title\">Наслов</string>\n    <string name=\"phones\">Телефони</string>\n    <string name=\"emails\">Емаилс</string>\n    <string name=\"urls\">УРЛ адресе</string>\n    <string name=\"addresses\">Аддрессес</string>\n    <string name=\"summary\">Резиме</string>\n    <string name=\"description\">Опис</string>\n    <string name=\"location\">Локација</string>\n    <string name=\"organizer\">Организатор</string>\n    <string name=\"start_date\">Датум почетка</string>\n    <string name=\"end_date\">Датум завршетка</string>\n    <string name=\"status\">Статус</string>\n    <string name=\"latitude\">Латитуде</string>\n    <string name=\"longitude\">Географска дужина</string>\n    <string name=\"create_barcode\">Креирајте бар код</string>\n    <string name=\"edit_barcode\">Уреди бар код</string>\n    <string name=\"wifi_configuration\">Ви-Фи конфигурација</string>\n    <string name=\"security\">Безбедност</string>\n    <string name=\"pick_contact\">Изаберите контакт</string>\n    <string name=\"grant_contact_permission\">Дајте контактима дозволу у подешавањима за аутоматско попуњавање помоћу изабраног контакта</string>\n    <string name=\"contact_info\">Контакт информације</string>\n    <string name=\"first_name\">Име</string>\n    <string name=\"middle_name\">Средње име</string>\n    <string name=\"last_name\">Презиме</string>\n    <string name=\"pronunciation\">Пронунциатион</string>\n    <string name=\"add_phone\">Додај телефон</string>\n    <string name=\"add_email\">Додајте е-пошту</string>\n    <string name=\"add_address\">Додајте адресу</string>\n    <string name=\"website\">Вебсите</string>\n    <string name=\"add_website\">Додајте веб локацију</string>\n    <string name=\"formatted_name\">Форматирано име</string>\n    <string name=\"qr_code_top_image\">Ова слика ће се користити за постављање изнад бар кода</string>\n    <string name=\"code_customization\">Прилагођавање кода</string>\n    <string name=\"qr_logo_image\">Ова слика ће се користити као лого у центру КР кода</string>\n    <string name=\"logo\">Лого</string>\n    <string name=\"logo_padding\">Лого паддинг</string>\n    <string name=\"logo_size\">Величина логотипа</string>\n    <string name=\"logo_corners\">Лого углови</string>\n    <string name=\"fourth_eye\">Четврто око</string>\n    <string name=\"fourth_eye_description\">Додаје симетрију ока кр коду додавањем четвртог ока у доњем крајњем углу</string>\n    <string name=\"pixel_shape\">Облик пиксела</string>\n    <string name=\"frame_shape\">Облик оквира</string>\n    <string name=\"ball_shape\">Облик лопте</string>\n    <string name=\"error_correction_level\">Ниво исправке грешке</string>\n    <string name=\"dark_color\">Тамна боја</string>\n    <string name=\"light_color\">Светла боја</string>\n    <string name=\"hyper_os\">Хипер ОС</string>\n    <string name=\"hyper_os_sub\">Стил попут Ксиаоми ХиперОС-а</string>\n    <string name=\"mask_pattern\">Узорак маске</string>\n    <string name=\"code_may_be_not_scannable\">Овај код се можда не може скенирати, промените параметре изгледа да бисте га учинили читљивим на свим уређајима</string>\n    <string name=\"not_scannable\">Није могуће скенирати</string>\n    <string name=\"launcher_mode_sub\">Алати ће изгледати као покретач апликација на почетном екрану да би били компактнији</string>\n    <string name=\"launcher_mode\">Лаунцхер Моде</string>\n    <string name=\"flood_fill_sub\">Испуњава област одабраном четком и стилом</string>\n    <string name=\"flood_fill\">Флоод Филл</string>\n    <string name=\"spray\">Спреј</string>\n    <string name=\"spray_sub\">Црта путању у стилу графита</string>\n    <string name=\"square_particles\">Скуаре Партицлес</string>\n    <string name=\"square_particles_sub\">Честице спреја ће бити квадратног облика уместо кругова</string>\n    <string name=\"palette_tools\">Палетте Тоолс</string>\n    <string name=\"palette_tools_sub\">Генеришите основни/материјал који палете са слике или увезите/извезите у различите формате палета</string>\n    <string name=\"edit_palette\">Уреди палету</string>\n    <string name=\"edit_palette_sub\">Извоз/увоз палете у различитим форматима</string>\n    <string name=\"color_name\">Назив боје</string>\n    <string name=\"palette_name\">Име палете</string>\n    <string name=\"palette_format\">Палетте Формат</string>\n    <string name=\"export_palette_sub\">Извезите генерисану палету у различите формате</string>\n    <string name=\"add_color_palette_sub\">Додаје нову боју тренутној палети</string>\n    <string name=\"palette_name_not_supported\">%1$s формат не подржава давање назива палете</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Због смерница Плаи продавнице, ова функција не може бити укључена у актуелну верзију. Да бисте приступили овој функцији, преузмите ИмагеТоолбок са алтернативног извора. Доступне верзије на ГитХуб-у можете пронаћи испод.</string>\n    <string name=\"open_github_page\">Отворите Гитхуб страницу</string>\n    <string name=\"overwrite_files_sub_short\">Оригинална датотека ће бити замењена новом уместо чувања у изабраном фолдеру</string>\n    <string name=\"hidden_watermark_text_detected\">Откривен је скривени текст воденог жига</string>\n    <string name=\"hidden_watermark_image_detected\">Откривена је скривена слика воденог жига</string>\n    <string name=\"this_image_was_hidden\">Ова слика је била скривена</string>\n    <string name=\"generative_inpaint\">Генеративе Инпаинтинг</string>\n    <string name=\"generative_inpaint_sub\">Омогућава вам да уклоните објекте са слике користећи АИ модел, без ослањања на ОпенЦВ. Да би користила ову функцију, апликација ће преузети потребни модел (~200 МБ) са ГитХуб-а</string>\n    <string name=\"generative_inpaint_ready_sub\">Омогућава вам да уклоните објекте са слике користећи АИ модел, без ослањања на ОпенЦВ. Ово би могла бити дуготрајна операција</string>\n    <string name=\"error_level_analysis\">Анализа нивоа грешке</string>\n    <string name=\"luminance_gradient\">Градијент осветљености</string>\n    <string name=\"average_distance\">Просечна удаљеност</string>\n    <string name=\"copy_move_detection\">Цопи Мове Детецтион</string>\n    <string name=\"retain\">Задржи</string>\n    <string name=\"coefficent\">Коефицијент</string>\n    <string name=\"clipboard_data_is_too_large\">Подаци међумеморије су превелики</string>\n    <string name=\"data_is_too_large_to_copy\">Подаци су превелики за копирање</string>\n    <string name=\"simple_weave_pixelization\">Једноставна пикселизација ткања</string>\n    <string name=\"staggered_pixelization\">Постепена пикселизација</string>\n    <string name=\"cross_pixelization\">Цросс Пикелизатион</string>\n    <string name=\"micro_macro_pixelization\">Микро Макро Пикселизација</string>\n    <string name=\"orbital_pixelization\">Орбитална пикселизација</string>\n    <string name=\"vortex_pixelization\">Вортек Пикелизатион</string>\n    <string name=\"pulse_grid_pixelization\">Пикселизација пулсне мреже</string>\n    <string name=\"nucleus_pixelization\">Нуцлеус Пикелизатион</string>\n    <string name=\"radial_weave_pixelization\">Пикселизација радијалног ткања</string>\n    <string name=\"cannot_open_uri\">Није могуће отворити ури \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Снежни режим</string>\n    <string name=\"enabled\">Омогућено</string>\n    <string name=\"border_frame\">Бордер Фраме</string>\n    <string name=\"glitch_variant\">Глитцх Вариант</string>\n    <string name=\"channel_shift\">Цханнел Схифт</string>\n    <string name=\"max_offset\">Мак Оффсет</string>\n    <string name=\"vhs\">ВХС</string>\n    <string name=\"block_glitch\">Блоцк Глитцх</string>\n    <string name=\"block_size\">Величина блока</string>\n    <string name=\"crt_curvature\">ЦРТ закривљеност</string>\n    <string name=\"curvature\">Закривљеност</string>\n    <string name=\"chroma\">Цхрома</string>\n    <string name=\"pixel_melt\">Пикел Мелт</string>\n    <string name=\"max_drop\">Мак Дроп</string>\n    <string name=\"ai_tools\">АИ Тоолс</string>\n    <string name=\"ai_tools_sub\">Различити алати за обраду слика кроз АИ моделе као што су уклањање артефаката или уклањање шума</string>\n    <string name=\"model_anime_undeint\">Компресија, назубљене линије</string>\n    <string name=\"model_broadcast\">Цртани филмови, компресија емитовања</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Општа компресија, општа бука</string>\n    <string name=\"model_wb_denoise\">Безбојна бука из цртаних филмова</string>\n    <string name=\"model_span_anime_pretrain\">Брза, општа компресија, општа бука, анимација/стрипови/аниме</string>\n    <string name=\"model_book_scan\">Скенирање књига</string>\n    <string name=\"model_overexposure\">Корекција експозиције</string>\n    <string name=\"model_fbcnn_color_fp16\">Најбољи у општој компресији, сликама у боји</string>\n    <string name=\"model_fbcnn_gray_fp16\">Најбољи у општој компресији, слике у сивим тоновима</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Општа компресија, слике у нијансама сиве, јаче</string>\n    <string name=\"model_scunet_color_gan_fp16\">Општи шум, слике у боји</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Општи шум, слике у боји, бољи детаљи</string>\n    <string name=\"model_scunet_gray_15_fp16\">Општи шум, слике у сивим тоновима</string>\n    <string name=\"model_scunet_gray_25_fp16\">Општи шум, слике у нијансама сиве, јачи</string>\n    <string name=\"model_scunet_gray_50_fp16\">Општи шум, слике у нијансама сиве, најјаче</string>\n    <string name=\"model_jpeg_destroyer\">Општа компресија</string>\n    <string name=\"model_jaywreck\">Општа компресија</string>\n    <string name=\"model_h264\">Текстуризација, компресија х264</string>\n    <string name=\"model_vhs\">ВХС компресија</string>\n    <string name=\"model_cinepak\">Нестандардна компресија (цинепак, мсвидео1, рок)</string>\n    <string name=\"model_debink_v4\">Бинк компресија, боља у геометрији</string>\n    <string name=\"model_debink_v5\">Бинк компресија, јача</string>\n    <string name=\"model_debink_v6\">Бинк компресија, мекана, задржава детаље</string>\n    <string name=\"model_antialias\">Уклањање ефекта степеница, заглађивање</string>\n    <string name=\"model_kdm_scans\">Скенирана уметност/цртежи, блага компресија, моар</string>\n    <string name=\"model_bandage\">Боја трака</string>\n    <string name=\"model_halftone\">Споро, уклањајући полутонове</string>\n    <string name=\"model_colorizer\">Општи колоризер за слике у нијансама сиве/црне боје, за боље резултате користите ДДЦолор</string>\n    <string name=\"model_deedge\">Уклањање ивица</string>\n    <string name=\"model_desharpen\">Уклања преоштрење</string>\n    <string name=\"model_dither\">Споро, немирно</string>\n    <string name=\"model_gainres\">Анти-алиасинг, општи артефакти, ЦГИ</string>\n    <string name=\"model_kdm003_scans\">КДМ003 обрада скенирања</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Лагани модел за побољшање слике</string>\n    <string name=\"model_bcgone_detailed_v2\">Уклањање артефакта компресије</string>\n    <string name=\"model_bcgone_smooth\">Уклањање артефакта компресије</string>\n    <string name=\"model_bandage_smooth\">Уклањање завоја са глатким резултатима</string>\n    <string name=\"model_bendel_halftone\">Обрада полутонског узорка</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Уклањање дитер шаблона В3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Уклањање ЈПЕГ артефаката В2</string>\n    <string name=\"model_nmkd_h264_texturize\">Х.264 побољшање текстуре</string>\n    <string name=\"model_vhs_sharpen\">ВХС изоштравање и побољшање</string>\n    <string name=\"merging\">Спајање</string>\n    <string name=\"chunk_size\">Величина комада</string>\n    <string name=\"overlap_size\">Величина преклапања</string>\n    <string name=\"note_chunk_info\">Слике веће од %1$s пк ће бити исечене и обрађене у деловима, преклапање их спаја да би се спречиле видљиве шавове.</string>\n    <string name=\"large_chunk_warning\">Велике величине могу узроковати нестабилност код уређаја ниске класе</string>\n    <string name=\"select_one_to_start\">Изаберите једну за почетак</string>\n    <string name=\"delete_model_sub\">Да ли желите да избришете %1$s модел? Мораћете поново да га преузмете</string>\n    <string name=\"confirm\">Потврди</string>\n    <string name=\"models\">Модели</string>\n    <string name=\"downloaded_models\">Преузети модели</string>\n    <string name=\"available_models\">Доступни модели</string>\n    <string name=\"preparing\">Припрема</string>\n    <string name=\"active_model\">Активни модел</string>\n    <string name=\"failed_to_open_session\">Отварање сесије није успело</string>\n    <string name=\"only_onnx_models\">Могу се увозити само .оннк/.орт модели</string>\n    <string name=\"import_model\">Увозни модел</string>\n    <string name=\"import_model_sub\">Увезите прилагођени оннк модел за даљу употребу, прихватају се само оннк/орт модели, подржава скоро све есрган варијанте</string>\n    <string name=\"imported_models\">Увезени модели</string>\n    <string name=\"model_scunet_color_15_fp16\">Општи шум, слике у боји</string>\n    <string name=\"model_scunet_color_25_fp16\">Општи шум, слике у боји, јачи</string>\n    <string name=\"model_scunet_color_50_fp16\">Општи шум, слике у боји, најјаче</string>\n    <string name=\"model_artifacts_dithering_alsa\">Смањује артефакте дитхеринга и траке боја, побољшавајући глатке нагибе и равне области боја.</string>\n    <string name=\"model_nmkd_brighten_redux\">Повећава осветљеност и контраст слике уравнотеженим светлима уз очување природних боја.</string>\n    <string name=\"model_nmkd_brighten\">Осветљава тамне слике, задржавајући детаље и избегавајући прекомерну експозицију.</string>\n    <string name=\"model_nmkd_detoon\">Уклања прекомерно тонирање боја и враћа неутралнији и природнији баланс боја.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Примењује тонирање буке засновано на Поиссону са нагласком на очувању финих детаља и текстура.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Примењује меку Поиссонову буку за глађе и мање агресивне визуелне резултате.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Уједначено тонирање шума фокусирано на очување детаља и јасноћу слике.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Нежно равномерно тонирање буке за суптилну текстуру и гладак изглед.</string>\n    <string name=\"model_repainter\">Поправља оштећена или неравна подручја префарбавањем артефаката и побољшањем конзистентности слике.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Лагани модел за уклањање трака који уклања траке у боји уз минималне трошкове перформанси.</string>\n    <string name=\"model_jpeg_0_20\">Оптимизује слике са веома високим артефактима компресије (0-20% квалитета) за побољшану јасноћу.</string>\n    <string name=\"model_jpeg_20_40\">Побољшава слике са високим артефактима компресије (20-40% квалитета), враћајући детаље и смањујући шум.</string>\n    <string name=\"model_jpeg_40_60\">Побољшава слике умереном компресијом (40-60% квалитета), балансирајући оштрину и глаткоћу.</string>\n    <string name=\"model_jpeg_60_80\">Рафинира слике лаганом компресијом (60-80% квалитета) како би побољшао суптилне детаље и текстуре.</string>\n    <string name=\"model_jpeg_80_100\">Мало побољшава слике скоро без губитака (80-100% квалитета) уз очување природног изгледа и детаља.</string>\n    <string name=\"model_spongecolor_lite\">Једноставна и брза колоризација, цртани, није идеално</string>\n    <string name=\"model_deblr\">Благо смањује замућење слике, побољшавајући оштрину без уношења артефаката.</string>\n    <string name=\"processing_channel\">Дуготрајне операције</string>\n    <string name=\"processing_image\">Обрада слике</string>\n    <string name=\"processing\">Обрада</string>\n    <string name=\"model_artifacts_jpg_0_20\">Уклања тешке артефакте ЈПЕГ компресије на сликама веома лошег квалитета (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Смањује јаке ЈПЕГ артефакте у високо компресованим сликама (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Чисти умерене ЈПЕГ артефакте уз очување детаља слике (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Рафинира лаке ЈПЕГ артефакте у сликама прилично високог квалитета (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Суптилно смањује мање ЈПЕГ артефакте у сликама скоро без губитака (80-100%).</string>\n    <string name=\"model_redetail_v2\">Побољшава фине детаље и текстуре, побољшавајући перципирану оштрину без тешких артефаката.</string>\n    <string name=\"processing_finished\">Обрада је завршена</string>\n    <string name=\"processing_failed\">Обрада није успела</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Побољшава текстуру и детаље коже, задржавајући природан изглед, оптимизован за брзину.</string>\n    <string name=\"model_sbdv_dejpeg\">Уклања артефакте ЈПЕГ компресије и враћа квалитет слике за компримоване фотографије.</string>\n    <string name=\"model_iso_denoise_v1\">Смањује ИСО шум на фотографијама снимљеним у условима слабог осветљења, чувајући детаље.</string>\n    <string name=\"model_dejumbo\">Коригује преекспониране или „џамбо“ светле делове и враћа бољу равнотежу тонова.</string>\n    <string name=\"model_ddcolor_tiny\">Лаган и брз модел колоризације који додаје природне боје сликама у сивим тоновима.</string>\n    <string name=\"type_dejpeg\">ДЕЈПЕГ</string>\n    <string name=\"type_denoise\">Деноисе</string>\n    <string name=\"type_colorize\">Цолоризе</string>\n    <string name=\"type_artifacts\">Артефакти</string>\n    <string name=\"type_enhance\">Енханце</string>\n    <string name=\"type_anime\">Аниме</string>\n    <string name=\"type_scans\">Скенирања</string>\n    <string name=\"type_upscale\">Упсцале</string>\n    <string name=\"model_realesrgan_x4v3\">Кс4 упсцалер за опште слике; мали модел који користи мање ГПУ-а и времена, са умереним замагљивањем и шумом.</string>\n    <string name=\"model_realesrgan_x2plus\">Кс2 упсцалер за опште слике, очување текстура и природних детаља.</string>\n    <string name=\"model_realesrgan_x4plus\">Кс4 упсцалер за опште слике са побољшаним текстурама и реалистичним резултатима.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Кс4 упсцалер оптимизован за аниме слике; 6 РРДБ блокова за оштрије линије и детаље.</string>\n    <string name=\"model_realesrnet_x4plus\">Кс4 упсцалер са губитком МСЕ, даје глаткије резултате и смањене артефакте за опште слике.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">Кс4 Упсцалер оптимизован за аниме слике; 4Б32Ф варијанта са оштријим детаљима и глатким линијама.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Кс4 УлтраСхарп В2 модел за опште слике; наглашава оштрину и јасноћу.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">Кс4 УлтраСхарп В2 Лите; бржи и мањи, чува детаље док користи мање ГПУ меморије.</string>\n    <string name=\"model_rmbg_1_4\">Лагани модел за брзо уклањање позадине. Уравнотежене перформансе и тачност. Ради са портретима, објектима и сценама. Препоручује се за већину случајева употребе.</string>\n    <string name=\"type_removebg\">Уклони БГ</string>\n    <string name=\"horizontal_border_thickness\">Хоризонтална дебљина ивице</string>\n    <string name=\"vertical_border_thickness\">Вертикална дебљина ивице</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s боја</item>\n        <item quantity=\"few\">%1$s боја</item>\n        <item quantity=\"other\">%1$s боја</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Тренутни модел не подржава ломљење, слика ће бити обрађена у оригиналним димензијама, што може узроковати велику потрошњу меморије и проблеме са уређајима ниске класе</string>\n    <string name=\"chunking_disabled\">Резање на комаде је онемогућено, слика ће бити обрађена у оригиналним димензијама, ово може узроковати велику потрошњу меморије и проблеме са нижим уређајима, али може дати боље резултате при закључивању</string>\n    <string name=\"chunking\">Цхункинг</string>\n    <string name=\"model_u2net\">Модел сегментације слике високе прецизности за уклањање позадине</string>\n    <string name=\"model_u2netp\">Лагана верзија У2Нета за брже уклањање позадине уз мању употребу меморије.</string>\n    <string name=\"model_ddcolor\">Пун модел ДДЦолор пружа висококвалитетну колоризацију за опште слике са минималним артефактима. Најбољи избор од свих модела колоризације.</string>\n    <string name=\"model_ddcolor_artistic\">ДДЦолор Обучени и приватни уметнички скупови података; производи разноврсне и уметничке резултате колоризације са мање нереалних артефаката у боји.</string>\n    <string name=\"model_birefnet\">Лагани БиРефНет модел заснован на Свин Трансформеру за прецизно уклањање позадине.</string>\n    <string name=\"model_inspyrenet\">Висококвалитетно уклањање позадине са оштрим ивицама и одличним очувањем детаља, посебно на сложеним објектима и лукавим позадинама.</string>\n    <string name=\"model_isnet\">Модел уклањања позадине који производи прецизне маске са глатким ивицама, погодне за опште објекте и умерено очување детаља.</string>\n    <string name=\"model_already_downloaded\">Модел је већ преузет</string>\n    <string name=\"model_successfully_imported\">Модел је успешно увезен</string>\n    <string name=\"type\">Тип</string>\n    <string name=\"keyword\">Кључна реч</string>\n    <string name=\"very_fast\">Врло брзо</string>\n    <string name=\"normal\">Нормално</string>\n    <string name=\"slow\">Споро</string>\n    <string name=\"very_slow\">Веома Споро</string>\n    <string name=\"compute_percents\">Израчунај проценте</string>\n    <string name=\"minimum_value_is\">Минимална вредност је __ПХ_0__</string>\n    <string name=\"warp_sub\">Искривите слику цртањем прстима</string>\n    <string name=\"warp\">Варп</string>\n    <string name=\"hardness\">Тврдоћа</string>\n    <string name=\"warp_mode\">Варп Моде</string>\n    <string name=\"warp_mode_move\">Помери се</string>\n    <string name=\"warp_mode_grow\">Расте</string>\n    <string name=\"warp_mode_shrink\">Смањи се</string>\n    <string name=\"warp_mode_swirl_cw\">Свирл ЦВ</string>\n    <string name=\"warp_mode_swirl_ccw\">Свирл ЦЦВ</string>\n    <string name=\"fade_strength\">Фаде Стренгтх</string>\n    <string name=\"top_drop\">Топ Дроп</string>\n    <string name=\"bottom_drop\">Боттом Дроп</string>\n    <string name=\"start_drop\">Старт Дроп</string>\n    <string name=\"end_drop\">Енд Дроп</string>\n    <string name=\"downloading\">Преузимање</string>\n    <string name=\"smooth_shapes\">Смоотх Схапес</string>\n    <string name=\"smooth_shapes_sub\">Користите суперелипсе уместо стандардних заобљених правоугаоника за глаткије, природније облике</string>\n    <string name=\"shape_type\">Облик облика</string>\n    <string name=\"cut\">Цут</string>\n    <string name=\"rounded\">Заобљен</string>\n    <string name=\"smooth\">Смоотх</string>\n    <string name=\"cut_shapes_sub\">Оштре ивице без заобљења</string>\n    <string name=\"rounded_shapes_sub\">Класични заобљени углови</string>\n    <string name=\"shapes_type\">Схапес Типе</string>\n    <string name=\"corners_size\">Цорнерс Сизе</string>\n    <string name=\"squircle\">Скуирцле</string>\n    <string name=\"squircle_shapes_sub\">Елегантни заобљени елементи корисничког интерфејса</string>\n    <string name=\"filename_format\">Формат имена датотеке</string>\n    <string name=\"prefix_pattern_description\">Прилагођени текст постављен на самом почетку назива датотеке, савршен за називе пројеката, брендове или личне ознаке.</string>\n    <string name=\"original_filename_pattern_description\">Користи оригинално име датотеке без екстензије, помажући вам да идентификацију извора сачувате нетакнутом.</string>\n    <string name=\"width_pattern_description\">Ширина слике у пикселима, корисна за праћење промена резолуције или скалирања резултата.</string>\n    <string name=\"height_pattern_description\">Висина слике у пикселима, корисна када радите са пропорцијама или извозима.</string>\n    <string name=\"random_numbers_pattern_description\">Генерише насумичне цифре да гарантује јединствена имена датотека; додајте још цифара за додатну сигурност од дупликата.</string>\n    <string name=\"sequence_number_pattern_description\">Бројач са аутоматским повећањем за групни извоз, идеалан за чување више слика у једној сесији.</string>\n    <string name=\"preset_info_pattern_description\">Умеће примењено унапред подешено име у назив датотеке тако да можете лако да запамтите како је слика обрађена.</string>\n    <string name=\"scale_mode_pattern_description\">Приказује режим скалирања слике који се користи током обраде, помажући у разликовању слика промењене величине, исечених или уклопљених слика.</string>\n    <string name=\"suffix_pattern_description\">Прилагођени текст постављен на крај назива датотеке, користан за верзионисање као што је _в2, _едитед или _финал.</string>\n    <string name=\"extension_pattern_description\">Екстензија датотеке (пнг, јпг, вебп, итд.), аутоматски се подудара са стварним сачуваним форматом.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Прилагодљива временска ознака која вам омогућава да дефинишете сопствени формат помоћу Јава спецификације за савршено сортирање.</string>\n    <string name=\"fling_type\">Флинг Типе</string>\n    <string name=\"android_native\">Андроид изворни</string>\n    <string name=\"ios_style\">иОС стил</string>\n    <string name=\"smooth_curve\">Смоотх Цурве</string>\n    <string name=\"quick_stop\">Куицк Стоп</string>\n    <string name=\"bouncy\">Боунци</string>\n    <string name=\"floaty\">Флоати</string>\n    <string name=\"snappy\">Снаппи</string>\n    <string name=\"ultra_smooth\">Ултра Смоотх</string>\n    <string name=\"adaptive\">Адаптиве</string>\n    <string name=\"accessibility_aware\">Аццессибилити Аваре</string>\n    <string name=\"reduced_motion\">Редуцед Мотион</string>\n    <string name=\"android_native_sub\">Природна физика Андроид скроловања за основно поређење</string>\n    <string name=\"smooth_sub\">Уравнотежено, глатко померање за општу употребу</string>\n    <string name=\"ios_style_sub\">Понашање померања попут иОС-а са већим трењем</string>\n    <string name=\"smooth_curve_sub\">Јединствена сплине крива за јасан осећај померања</string>\n    <string name=\"quick_stop_sub\">Прецизно померање са брзим заустављањем</string>\n    <string name=\"bouncy_sub\">Разиграни, покретни померајући се померај</string>\n    <string name=\"floaty_sub\">Дуги, клизећи скроловање за прегледање садржаја</string>\n    <string name=\"snappy_sub\">Брзо и брзо померање за интерактивни кориснички интерфејс</string>\n    <string name=\"ultra_smooth_sub\">Врхунско глатко померање са продуженим замахом</string>\n    <string name=\"adaptive_sub\">Подешава физику на основу брзине бацања</string>\n    <string name=\"accessibility_aware_sub\">Поштује подешавања приступачности система</string>\n    <string name=\"reduced_motion_sub\">Минимално кретање за потребе приступачности</string>\n    <string name=\"primary_lines\">Примари Линес</string>\n    <string name=\"primary_lines_sub\">Додаје дебљу линију сваке пете линије</string>\n    <string name=\"fill_color\">Филл Цолор</string>\n    <string name=\"hidden_tools\">Скривени алати</string>\n    <string name=\"hidden_for_share\">Алати скривени за дељење</string>\n    <string name=\"color_library\">Библиотека боја</string>\n    <string name=\"color_library_sub\">Прегледајте огромну колекцију боја</string>\n    <string name=\"model_fatality_deblur\">Изоштрава и уклања замућење са слика уз задржавање природних детаља, идеално за поправљање фотографија које нису у фокусу.</string>\n    <string name=\"model_unresize_v3\">Интелигентно враћа слике којима је претходно промењена величина, враћајући изгубљене детаље и текстуре.</string>\n    <string name=\"model_liveaction_v1_span\">Оптимизовано за садржај уживо, смањује артефакте компресије и побољшава фине детаље у кадровима филмова/ТВ емисија.</string>\n    <string name=\"model_vhs2hd_realplksr\">Конвертује снимке ВХС квалитета у ХД, уклањајући шум траке и побољшавајући резолуцију уз очување винтаге осећаја.</string>\n    <string name=\"model_text2hd_v1\">Специјализован за слике и снимке екрана са тешким текстом, изоштрава знакове и побољшава читљивост.</string>\n    <string name=\"model_frankendata_pretrainer\">Напредно повећање величине обучено на различитим скуповима података, одлично за побољшање фотографија опште намене.</string>\n    <string name=\"model_realwebphoto_v2\">Оптимизован за веб компресоване фотографије, уклања ЈПЕГ артефакте и враћа природан изглед.</string>\n    <string name=\"model_realwebphoto_v4\">Побољшана верзија за веб фотографије са бољим очувањем текстуре и смањењем артефаката.</string>\n    <string name=\"model_dat_2x\">2к повећање помоћу технологије Дуал Аггрегатион Трансформер, одржава оштрину и природне детаље.</string>\n    <string name=\"model_dat_3x\">3к повећање помоћу напредне трансформаторске архитектуре, идеално за умерене потребе повећања.</string>\n    <string name=\"model_dat_4x\">4к висококвалитетно повећање са најсавременијом мрежом трансформатора, чува фине детаље у већим размерама.</string>\n    <string name=\"model_nafnet_deblurring\">Уклања замућење/шум и подрхтавање фотографија. Опште намене, али најбоље на фотографијама.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Враћа слике ниског квалитета помоћу Свин2СР трансформатора, оптимизованог за БСРГАН деградацију. Одлично за поправљање артефаката тешке компресије и побољшање детаља на скали од 4к.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4к повећање са СвинИР трансформатором обученим за БСРГАН деградацију. Користи ГАН за оштрије текстуре и природније детаље на фотографијама и сложеним сценама.</string>\n    <string name=\"path\">Пут</string>\n    <string name=\"merge_pdf\">Споји ПДФ</string>\n    <string name=\"merge_pdf_sub\">Комбинујте више ПДФ датотека у један документ</string>\n    <string name=\"files_order\">Филес Ордер</string>\n    <string name=\"pages_short\">стр.</string>\n    <string name=\"split_pdf\">Сплит ПДФ</string>\n    <string name=\"split_pdf_sub\">Извуците одређене странице из ПДФ документа</string>\n    <string name=\"rotate_pdf\">Ротирајте ПДФ</string>\n    <string name=\"rotate_pdf_sub\">Трајно поправи оријентацију странице</string>\n    <string name=\"pages\">Пагес</string>\n    <string name=\"rearrange_pdf\">Преуредите ПДФ</string>\n    <string name=\"rearrange_pdf_sub\">Превуците и отпустите странице да бисте их променили</string>\n    <string name=\"hold_drag_drop\">Задржите и превуците странице</string>\n    <string name=\"page_numbers\">Бројеви страница</string>\n    <string name=\"page_numbers_sub\">Аутоматски додајте нумерацију у своје документе</string>\n    <string name=\"label_format\">Лабел Формат</string>\n    <string name=\"pdf_to_text\">ПДФ у текст (ОЦР)</string>\n    <string name=\"pdf_to_text_sub\">Извуците обичан текст из ваших ПДФ докумената</string>\n    <string name=\"watermark_pdf_sub\">Преклапање прилагођеног текста за брендирање или безбедност</string>\n    <string name=\"signature\">Потпис</string>\n    <string name=\"signature_sub\">Додајте свој електронски потпис на било који документ</string>\n    <string name=\"will_be_for_signature\">Ово ће се користити као потпис</string>\n    <string name=\"unlock_pdf\">Откључај ПДФ</string>\n    <string name=\"unlock_pdf_sub\">Уклоните лозинке из заштићених датотека</string>\n    <string name=\"protect_pdf\">Заштитите ПДФ</string>\n    <string name=\"protect_pdf_sub\">Осигурајте своје документе снажном енкрипцијом</string>\n    <string name=\"success\">Успех</string>\n    <string name=\"pdf_unlocked\">ПДФ је откључан, можете га сачувати или поделити</string>\n    <string name=\"repair_pdf\">Поправи ПДФ</string>\n    <string name=\"repair_pdf_sub\">Покушајте да поправите оштећене или нечитљиве документе</string>\n    <string name=\"grayscale\">Граисцале</string>\n    <string name=\"grayscale_pdf_sub\">Претворите све слике уграђене у документе у сивим тоновима</string>\n    <string name=\"compress_pdf\">Цомпресс ПДФ</string>\n    <string name=\"compress_pdf_sub\">Оптимизујте величину датотеке документа за лакше дељење</string>\n    <string name=\"repair_info\">ИмагеТоолбок поново гради интерну табелу унакрсних референци и регенерише структуру датотеке од нуле. Ово може да врати приступ многим датотекама које се „не могу отворити“</string>\n    <string name=\"grayscale_info\">Овај алат претвара све слике документа у сиве тонове. Најбоље за штампање и смањење величине датотеке</string>\n    <string name=\"metadata\">Метаподаци</string>\n    <string name=\"metadata_pdf_sub\">Уредите својства документа ради боље приватности</string>\n    <string name=\"tags\">Ознаке</string>\n    <string name=\"producer\">Произвођач</string>\n    <string name=\"author\">Аутор</string>\n    <string name=\"keywords\">Кључне речи</string>\n    <string name=\"creator\">Креатор</string>\n    <string name=\"privacy_deep_clean\">Приватност Дееп Цлеан</string>\n    <string name=\"privacy_deep_clean_sub\">Обришите све доступне метаподатке за овај документ</string>\n    <string name=\"page\">Страница</string>\n    <string name=\"deep_ocr\">Дубоки ОЦР</string>\n    <string name=\"deep_ocr_sub\">Извуците текст из документа и сачувајте га у једној текстуалној датотеци користећи Тессерацт енгине</string>\n    <string name=\"cant_remove_all\">Није могуће уклонити све странице</string>\n    <string name=\"remove_pages_pdf\">Уклоните ПДФ странице</string>\n    <string name=\"remove_pages_pdf_sub\">Уклоните одређене странице из ПДФ документа</string>\n    <string name=\"tap_to_remove\">Додирните За уклањање</string>\n    <string name=\"manually\">Ручно</string>\n    <string name=\"crop_pdf\">Изрежите ПДФ</string>\n    <string name=\"crop_pdf_sub\">Опсеците странице документа на било коју границу</string>\n    <string name=\"flatten_pdf\">Изравнајте ПДФ</string>\n    <string name=\"flatten_pdf_sub\">Учините ПДФ непромењивим растером страница документа</string>\n    <string name=\"camera_failed_to_open\">Није могуће покренути камеру. Проверите дозволе и уверите се да је не користи друга апликација.</string>\n    <string name=\"extract_images\">Ектрацт Имагес</string>\n    <string name=\"extract_images_sub\">Извуците слике уграђене у ПДФ-ове у њиховој оригиналној резолуцији</string>\n    <string name=\"pdf_no_embedded\">Ова ПДФ датотека не садржи уграђене слике</string>\n    <string name=\"extract_images_info\">Овај алат скенира сваку страницу и враћа изворне слике пуног квалитета — савршено за чување оригинала из докумената</string>\n    <string name=\"draw_signature\">Драв Сигнатуре</string>\n    <string name=\"pen_params\">Пен Парамс</string>\n    <string name=\"draw_signature_sub\">Користите сопствени потпис као слику која се поставља на документе</string>\n    <string name=\"zip_pdf\">Зип ПДФ</string>\n    <string name=\"zip_pdf_sub\">Поделите документ са датим интервалом и спакујте нове документе у зип архиву</string>\n    <string name=\"interval\">Интервал</string>\n    <string name=\"print_pdf\">Штампај ПДФ</string>\n    <string name=\"print_pdf_sub\">Припремите документ за штампање са прилагођеном величином странице</string>\n    <string name=\"pages_per_sheet\">Странице по листу</string>\n    <string name=\"orientation\">Оријентација</string>\n    <string name=\"page_size\">Величина странице</string>\n    <string name=\"margin\">Маргина</string>\n    <string name=\"bloom\">Блоом</string>\n    <string name=\"soft_knee\">Софт Кнее</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Оптимизовано за аниме и цртане филмове. Брзо повећање са побољшаним природним бојама и мање артефаката</string>\n    <string name=\"one_ui_sub\">Стил попут Самсунг Оне УИ 7</string>\n    <string name=\"calculate_hint\">Унесите основне математичке симболе овде да бисте израчунали жељену вредност (нпр. (5+5)*10)</string>\n    <string name=\"math_expression\">Математички израз</string>\n    <string name=\"pick_up_to_n_collage_images\">Покупите до __ПХ_0__ слика</string>\n    <string name=\"keep_date_time\">Задржите датум и време</string>\n    <string name=\"keep_date_time_sub\">Увек сачувајте екиф ознаке повезане са датумом и временом, ради независно од опције Кееп екиф</string>\n    <string name=\"background_color_for_alpha_formats\">Боја позадине за алфа формате</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Додаје могућност постављања боје позадине за сваки формат слике са алфа подршком, када је онемогућена ово је доступно само за оне које нису алфа</string>\n    <string name=\"open_markup_project\">Отворени пројекат</string>\n    <string name=\"open_markup_project_sub\">Наставите са уређивањем претходно сачуваног пројекта Имаге Тоолбок</string>\n    <string name=\"markup_project_open_failed\">Није могуће отворити пројекат Имаге Тоолбок</string>\n    <string name=\"markup_project_missing_data\">Пројекту Имаге Тоолбок недостају подаци о пројекту</string>\n    <string name=\"markup_project_corrupted\">Пројекат Имаге Тоолбок је оштећен</string>\n    <string name=\"unsupported_markup_project_version\">Неподржана верзија пројекта Имаге Тоолбок: __ПХ_0__</string>\n    <string name=\"save_markup_project\">Сачувај пројекат</string>\n    <string name=\"save_markup_project_sub\">Чувајте слојеве, позадину и историју уређивања у датотеци пројекта који се може уређивати</string>\n    <string name=\"failed_to_open\">Отварање није успело</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Врите То Сеарцхабле ПДФ</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Препознајте текст из групе слика и сачувајте претраживи ПДФ са сликом и слојем текста који се може изабрати</string>\n    <string name=\"layer_alpha\">Слој алфа</string>\n    <string name=\"horizontal_flip\">Хоризонтал Флип</string>\n    <string name=\"vertical_flip\">Вертицал Флип</string>\n    <string name=\"lock\">Закључај</string>\n    <string name=\"add_shadow\">Додај сенку</string>\n    <string name=\"shadow_color\">Схадов Цолор</string>\n    <string name=\"text_geometry\">Тект Геометри</string>\n    <string name=\"text_geometry_sub\">Растегните или искосите текст за оштрију стилизацију</string>\n    <string name=\"scale_x\">Скала Кс</string>\n    <string name=\"skew_x\">Скев Кс</string>\n    <string name=\"remove_annotations\">Уклоните напомене</string>\n    <string name=\"remove_annotations_sub\">Уклоните изабране типове напомена као што су везе, коментари, истакнути делови, облици или поља обрасца са ПДФ страница</string>\n    <string name=\"annotation_link\">Хипервезе</string>\n    <string name=\"annotation_file_attachment\">Филе Аттацхментс</string>\n    <string name=\"annotation_line\">Линије</string>\n    <string name=\"annotation_popup\">Попупс</string>\n    <string name=\"annotation_stamp\">Марке</string>\n    <string name=\"annotation_shapes\">Облици</string>\n    <string name=\"annotation_text\">Тект Нотес</string>\n    <string name=\"annotation_text_markup\">Означавање текста</string>\n    <string name=\"annotation_widget\">Форм Фиелдс</string>\n    <string name=\"annotation_markup\">Маркуп</string>\n    <string name=\"annotation_unknown\">Непознато</string>\n    <string name=\"annotations\">Напомене</string>\n    <string name=\"ungroup\">Разгрупиши</string>\n    <string name=\"add_shadow_sub\">Додајте замућену сенку иза слоја са подесивом бојом и офсетима</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-sv/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">Något gick fel: %1$s</string>\n    <string name=\"size\">Storlek %1$s</string>\n    <string name=\"loading\">Laddar…</string>\n    <string name=\"image_too_large_preview\">Bilden är för stor för att förhandsgranska, men sparandet kommer att provas ändå</string>\n    <string name=\"pick_image\">Välj bild för att börja</string>\n    <string name=\"width\">Bredd %1$s</string>\n    <string name=\"height\">Höjd %1$s</string>\n    <string name=\"quality\">Kvalitet</string>\n    <string name=\"extension\">Förlängning</string>\n    <string name=\"resize_type\">Typ av storleksförändring</string>\n    <string name=\"explicit\">Explicit</string>\n    <string name=\"flexible\">Flexibel</string>\n    <string name=\"pick_image_alt\">Välj bild</string>\n    <string name=\"app_closing_sub\">Vill Du avsluta appen?</string>\n    <string name=\"app_closing\">Appen avslutar</string>\n    <string name=\"stay\">Stanna kvar</string>\n    <string name=\"close\">Stäng</string>\n    <string name=\"reset_image\">Återställ bild</string>\n    <string name=\"reset_image_sub\">Bildändringar kommer att rulla tillbaka till initiala värden</string>\n    <string name=\"values_reset\">Värden korrekt återställda</string>\n    <string name=\"reset\">Återställ</string>\n    <string name=\"something_went_wrong\">Något gick fel</string>\n    <string name=\"restart_app\">Starta om appen</string>\n    <string name=\"copied\">Kopierad till urklipp</string>\n    <string name=\"exception\">Undantag</string>\n    <string name=\"edit_exif\">Redigera EXIF</string>\n    <string name=\"ok\">OK</string>\n    <string name=\"no_exif\">Ingen EXIF-data hittades</string>\n    <string name=\"add_tag\">Lägg till märkning</string>\n    <string name=\"save\">Spara</string>\n    <string name=\"clear\">Rensa</string>\n    <string name=\"clear_exif\">Rensa EXIF</string>\n    <string name=\"cancel\">Avbryt</string>\n    <string name=\"clear_exif_sub\">Alla bildEXIF-data kommer att raderas. Denna åtgärd kan inte ångras!</string>\n    <string name=\"presets\">Förinställningar</string>\n    <string name=\"crop\">Beskär</string>\n    <string name=\"image_not_saved\">Sparar</string>\n    <string name=\"image_not_saved_sub\">Alla osparade förändringar kommer att gå förlorade, om du lämnar nu</string>\n    <string name=\"check_source_code\">Källkod</string>\n    <string name=\"check_source_code_sub\">Få senaste uppdateringarna, diskutera frågor och mer</string>\n    <string name=\"single_edit\">En redigering</string>\n    <string name=\"single_edit_sub\">Modifiera, ändra storlek och redigera en bild</string>\n    <string name=\"pick_color\">Färg-väljare</string>\n    <string name=\"pick_color_sub\">Välj färg från bild, kopiera eller dela med</string>\n    <string name=\"image\">Bild</string>\n    <string name=\"color\">Färg</string>\n    <string name=\"color_copied\">Färg kopierad</string>\n    <string name=\"crop_sub\">Beskär bild till alla gränser</string>\n    <string name=\"version\">Version</string>\n    <string name=\"keep_exif\">Behåll EXIF</string>\n    <string name=\"images\">Bilder: %d</string>\n    <string name=\"change_preview\">Ändra förhandsgranskning</string>\n    <string name=\"remove\">Ta bort</string>\n    <string name=\"border_thickness\">Ram-tjocklek</string>\n    <string name=\"surface\">Yta</string>\n    <string name=\"values\">Värde</string>\n    <string name=\"add\">Lägg till</string>\n    <string name=\"permission\">Tillåtelse</string>\n    <string name=\"grant\">Tillåt</string>\n    <string name=\"permission_sub\">För att bilder ska fungera behöver appen tillgång till lagring, det är absolut nödvändigt. Vänligen bevilja behörighet i nästa dialogruta.</string>\n    <string name=\"grant_permission_manual\">Appen behöver denna behörighet för att fungera, vänligen bevilja manuellt</string>\n    <string name=\"external_storage\">Extern lagring</string>\n    <string name=\"monet_colors\">Monet-färger</string>\n    <string name=\"donation_sub\">Detta program är helt gratis, men om du vill stödja projektutvecklingen kan du klicka här</string>\n    <string name=\"fab_alignment\">FAB-anpassning</string>\n    <string name=\"check_updates\">Sök uppdatering</string>\n    <string name=\"check_updates_sub\">Om aktiverad visas uppdateringsrutan vid appstart</string>\n    <string name=\"zoom\">Bild-zoom</string>\n    <string name=\"share\">Dela</string>\n    <string name=\"prefix\">Prefix</string>\n    <string name=\"filename\">Filnamn</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Välj vilken emoji som ska visas på startskärmen</string>\n    <string name=\"add_file_size\">Lägg till fil-storlek</string>\n    <string name=\"add_file_size_sub\">Om aktiverad läggs bredd och höjd till i fil-namnet</string>\n    <string name=\"delete_exif\">Radera EXIF</string>\n    <string name=\"delete_exif_sub\">Ta bort EXIF-metadata från en uppsättning bilder</string>\n    <string name=\"image_preview\">Förhandsgranskning</string>\n    <string name=\"image_preview_sub\">Förhandsgranska bild: GIF, SVG, and so on</string>\n    <string name=\"image_source\">Bild-källa</string>\n    <string name=\"photo_picker\">Bild-väljare</string>\n    <string name=\"gallery_picker\">Galleri</string>\n    <string name=\"file_explorer_picker\">Filhanterare</string>\n    <string name=\"photo_picker_sub\">Androids moderna fotoväljare, vilket visas längst ner på skärmen, fungerar bara på Android 12+. Har problem med att ta emot EXIF-metadata</string>\n    <string name=\"gallery_picker_sub\">Enkel bildväljare i galleriet. Fungerar endast om du har en app som har mediaupplockning</string>\n    <string name=\"file_explorer_picker_sub\">Använd GetContent för att välja bild. Fungerar överallt men är känd för att ha problem med att ta emot valda bilder på vissa enheter. Det är inte mitt fel.</string>\n    <string name=\"options_arrangement\">Alternativa arrangemang</string>\n    <string name=\"edit\">Redigera</string>\n    <string name=\"order\">Ordning</string>\n    <string name=\"order_sub\">Bestämmer ordningen på verktygen på huvudskärmen</string>\n    <string name=\"emojis_count\">Antal Emoji\\'s</string>\n    <string name=\"replace_sequence_number\">Ersätt sekvens-nummer</string>\n    <string name=\"replace_sequence_number_sub\">Aktiverad ersätter tidsstämpeln i bildens sekvensnummer om du batch-processar</string>\n    <string name=\"filter\">Filter</string>\n    <string name=\"effect\">Effekt</string>\n    <string name=\"filters\">Filter</string>\n    <string name=\"light_aka_illumination\">Ljus</string>\n    <string name=\"color_filter\">Färg-filter</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"brightness\">Ljusstyrka</string>\n    <string name=\"contrast\">Kontrast</string>\n    <string name=\"hue\">Nyans</string>\n    <string name=\"saturation\">Mättnad</string>\n    <string name=\"add_filter\">Lägg till filter</string>\n    <string name=\"no_image\">Ingen bild</string>\n    <string name=\"image_link\">Bild-länk</string>\n    <string name=\"fill\">Ifyllnad</string>\n    <string name=\"fit\">Anpassa</string>\n    <string name=\"load_image_from_net\">Internet-bild laddar</string>\n    <string name=\"load_image_from_net_sub\">Ladda bild från internet för förhandsgranskning, zooma, redigera och spara den om du vill.</string>\n    <string name=\"filter_sub\">Använd filterkedjor på bilder</string>\n    <string name=\"exposure\">Exponering</string>\n    <string name=\"white_balance\">Vit-balans</string>\n    <string name=\"temperature\">Temperatur</string>\n    <string name=\"tint\">Ton</string>\n    <string name=\"monochrome\">Monokrom</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Ljusa partier och skuggor</string>\n    <string name=\"highlights\">Ljusa partier</string>\n    <string name=\"shadows\">Skuggor</string>\n    <string name=\"haze\">Dis</string>\n    <string name=\"distance\">Avstånd</string>\n    <string name=\"slope\">Lutning</string>\n    <string name=\"sharpen\">Skarpare</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">Negativ</string>\n    <string name=\"solarize\">Solariserad</string>\n    <string name=\"vibrance\">Intensitet</string>\n    <string name=\"black_and_white\">Svart och vitt</string>\n    <string name=\"crosshatch\">Korshatch</string>\n    <string name=\"spacing\">Avstånd</string>\n    <string name=\"line_width\">Linje-bredd</string>\n    <string name=\"sobel_edge\">Sobel-kant</string>\n    <string name=\"blur\">Oskärpa</string>\n    <string name=\"halftone\">Halv-ton</string>\n    <string name=\"cga_colorspace\">CGA färgyta</string>\n    <string name=\"gaussian_blur\">Gaussisk oskärpa</string>\n    <string name=\"palette_sub\">Generera färgpalett från bild</string>\n    <string name=\"generate_palette\">Generera palett</string>\n    <string name=\"palette\">Palett</string>\n    <string name=\"update\">Uppdatera</string>\n    <string name=\"new_version\">Ny version %1$s</string>\n    <string name=\"unsupported_type\">Ogiltig filtyp: %1$s</string>\n    <string name=\"no_palette\">Ej möjligt att generera palett från bild</string>\n    <string name=\"original\">Original</string>\n    <string name=\"folder\">Spara i mapp</string>\n    <string name=\"def\">Förinställt</string>\n    <string name=\"custom\">Anpassad</string>\n    <string name=\"unspecified\">Ospecifierat</string>\n    <string name=\"device_storage\">Enhetens lagringsutrymme</string>\n    <string name=\"by_bytes_resize\">Storleksändra i förhållande till vikt</string>\n    <string name=\"max_bytes\">Max storlek i KB</string>\n    <string name=\"compare\">Jämför</string>\n    <string name=\"compare_sub\">Jämför två bilder</string>\n    <string name=\"pick_two_images\">Börja med att välja två bilder</string>\n    <string name=\"pick_images\">Välj bilder</string>\n    <string name=\"settings\">Inställningar</string>\n    <string name=\"night_mode\">Natt-läge</string>\n    <string name=\"dark\">Mörk</string>\n    <string name=\"light\">Ljus</string>\n    <string name=\"system\">System</string>\n    <string name=\"dynamic_colors\">Dynamiska färger</string>\n    <string name=\"customization\">Egna inställningar</string>\n    <string name=\"language\">Språk</string>\n    <string name=\"amoled_mode\">Amoled-läge</string>\n    <string name=\"color_scheme\">Färgschema</string>\n    <string name=\"color_red\">Röd</string>\n    <string name=\"color_green\">Grön</string>\n    <string name=\"color_blue\">Blå</string>\n    <string name=\"screenshot_not_captured_try_again\">Att ta en skärmdump misslyckades, försök igen</string>\n    <string name=\"enable_snapping_to_borders_sub\">Efter flytt eller zoomning kommer bilderna att fästa för att fylla ramkanter</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"image_for_histogram\">Denna bild används för att generera RGB och Ljusstyrke-histogram</string>\n    <string name=\"tesseract_options\">Tesseract-val</string>\n    <string name=\"tesseract_options_sub\">Använd några inmatningsvariabler för tesseract-motorn</string>\n    <string name=\"custom_options\">Anpassade alternativ</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">Alternativen ska anges efter detta mönster: \\\"--{val_namn} {värde}\\\"</string>\n    <string name=\"auto_crop\">Automatisk beskärning</string>\n    <string name=\"free_corners\">Flytande hörn</string>\n    <string name=\"free_corners_sub\">Polygon-beskär bild, detta val korrigerar perspektiv</string>\n    <string name=\"coerce_points_to_image_bounds\">Tvinga punkter till bildens gränser</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Punkter kommer inte att begränsas av bildens gränser, är användbart för mer exakt perspektivkorrigering</string>\n    <string name=\"mask\">Dölj</string>\n    <string name=\"spot_heal_sub\">Innehållsmedveten fyllning under ritad bana</string>\n    <string name=\"spot_heal\">Läkningspunkt</string>\n    <string name=\"use_circle_kernel\">Använd rund kärna</string>\n    <string name=\"opening\">Öppning</string>\n    <string name=\"closing\">Stängning</string>\n    <string name=\"morphological_gradient\">Morfologisk gradient</string>\n    <string name=\"black_hat\">Svart hatt</string>\n    <string name=\"tone_curves\">Tonkurvor</string>\n    <string name=\"reset_curves\">Återställ kurvor</string>\n    <string name=\"reset_curves_sub\">Kurvor återställs till standard-värde</string>\n    <string name=\"line_style\">Linje-stil</string>\n    <string name=\"gap_size\">Avståndsstorlek</string>\n    <string name=\"dashed\">Streckad</string>\n    <string name=\"dot_dashed\">Punktstreckad</string>\n    <string name=\"stamped\">Stämplad</string>\n    <string name=\"zigzag\">Sicksack</string>\n    <string name=\"dashed_sub\">Ritar streckad linje längs ritade bana med angiven avståndsstorlek</string>\n    <string name=\"dot_dashed_sub\">Ritar punk och streckad linje längs given bana</string>\n    <string name=\"stamped_sub\">Ritar valda former längs banan med angivet mellanrum</string>\n    <string name=\"zigzag_sub\">Ritar en vågig sicksack längs banan</string>\n    <string name=\"zigzag_ratio\">Sicksack-förhållande</string>\n    <string name=\"create_shortcut\">Skapa genväg</string>\n    <string name=\"create_shortcut_title\">Välj verktyg att fästa</string>\n    <string name=\"create_shortcut_subtitle\">Verktyget kommer att läggas till på hemskärmen av din startprogram som en genväg. Använd det i kombination med inställningen \\'Hoppa över filval\\' för att uppnå önskat beteende</string>\n    <string name=\"dont_stack_frames\">Stapla inte ramar</string>\n    <string name=\"dont_stack_frames_sub\">Aktiverar borttagning av tidigare ramar, så att de inte staplas på varandra</string>\n    <string name=\"crossfade\">Korsblekna</string>\n    <string name=\"crossfade_sub\">Ramarna kommer att korsbleknas in i varandra</string>\n    <string name=\"threshold_one\">Tröskel Ett</string>\n    <string name=\"threshold_two\">Tröskel Två</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Spegel 101</string>\n    <string name=\"enhanced_zoom_blur\">Förstärk zoom-oskärpa</string>\n    <string name=\"laplacian_simple\">Enkel Laplacian</string>\n    <string name=\"sobel_simple\">Enkel Sobel</string>\n    <string name=\"helper_grid\">Hjälp-rutmönster</string>\n    <string name=\"helper_grid_sub\">Visar ett nätmönster ovanför ritområdet för att hjälpa med precis manipulering</string>\n    <string name=\"grid_color\">Nät-färg</string>\n    <string name=\"cell_width\">Cell-bredd</string>\n    <string name=\"cell_height\">Cell-höjd</string>\n    <string name=\"compact_selectors\">Kompakta valtillbehör</string>\n    <string name=\"by_bytes_resize_sub\">Ändra storlek på en bild enligt angiven storlek i KB</string>\n    <string name=\"allow_image_monet\">Tillåt bildmonet</string>\n    <string name=\"allow_image_monet_sub\">Om aktiverat, när du väljer en bild att redigera, kommer appens färger att anpassas till denna bild</string>\n    <string name=\"amoled_mode_sub\">Om aktiverat kommer ytfärgen att ställas in på absolut mörk i nattläge</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Klistra in en giltig aRGB-färgkod</string>\n    <string name=\"clipboard_paste_invalid_empty\">Inget att klistra in</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Appens färgschema kan inte ändras medan dynamiska färger är aktiverade</string>\n    <string name=\"pick_accent_color\">Appens tema baseras på vald färg</string>\n    <string name=\"about_app\">Om appen</string>\n    <string name=\"no_updates\">Inga uppdateringar hittades</string>\n    <string name=\"issue_tracker\">Problem-spårare</string>\n    <string name=\"issue_tracker_sub\">Skicka buggrapporter och funktionsförfrågningar här</string>\n    <string name=\"help_translate\">Hjälp till att översätta</string>\n    <string name=\"help_translate_sub\">Rätta översättningsfel eller lokalisera projektet till andra språk</string>\n    <string name=\"nothing_found_by_search\">Din fråga gav inga svar</string>\n    <string name=\"search_here\">Sök här</string>\n    <string name=\"dynamic_colors_sub\">Om aktiverad kommer appens färger att anpassas till bakgrundsbildens färger</string>\n    <string name=\"failed_to_save\">Lyckades inte spara %d bild(er)</string>\n    <string name=\"email\">Email</string>\n    <string name=\"primary\">Främsta</string>\n    <string name=\"tertiary\">I tredje hand</string>\n    <string name=\"secondary\">I andra hand</string>\n    <string name=\"add_original_filename\">Lägg till filens originalnamn</string>\n    <string name=\"add_original_filename_sub\">Om aktiverad läggs ursprungliga filnamnet till i namnet på utgående bild</string>\n    <string name=\"filename_not_work_with_photopicker\">Att lägga till ursprungligt filnamn fungerar inte om bildkällan för foto-väljaren är vald</string>\n    <string name=\"content_scale\">Innehållsskala</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Vignett</string>\n    <string name=\"start\">Börja</string>\n    <string name=\"end\">Slut</string>\n    <string name=\"explicit_description\">Ändrar storlek på bilder till angiven höjd och bredd. Bildens ratio kan ändras.</string>\n    <string name=\"flexible_description\">Ändrar storlek på bilder med en lång sida till den angiven höjd eller bredd. Alla storleksberäkningar kommer att göras efter att de har sparats. Bildens ratio kommer att bevaras.</string>\n    <string name=\"bilaterial_blur\">Bilaterial oskärpa</string>\n    <string name=\"emboss\">Skärpa</string>\n    <string name=\"kuwahara\">Kuwahara-utjämning</string>\n    <string name=\"stack_blur\">Stapeloskärpa</string>\n    <string name=\"radius\">Radie</string>\n    <string name=\"scale\">Skala</string>\n    <string name=\"distortion\">Distorsion</string>\n    <string name=\"angle\">Vinkel</string>\n    <string name=\"swirl\">Virvel</string>\n    <string name=\"bulge\">Utbuckning</string>\n    <string name=\"dilation\">Utvidgning</string>\n    <string name=\"sphere_refraction\">Sfärisk refraktion</string>\n    <string name=\"second_color\">Färg nummer två</string>\n    <string name=\"reorder\">Omordna</string>\n    <string name=\"fast_blur\">Snabb-oskärpa</string>\n    <string name=\"blur_size\">Storlek på oskärpa</string>\n    <string name=\"sequence_num\">sekvensNum</string>\n    <string name=\"original_filename\">originalfilnamn</string>\n    <string name=\"box_blur\">Box oskärpa</string>\n    <string name=\"refractive_index\">Brytningsindex</string>\n    <string name=\"glass_sphere_refraction\">Glassfärens brytning</string>\n    <string name=\"color_matrix\">Färgmatris</string>\n    <string name=\"opacity\">Opacitet</string>\n    <string name=\"limits_resize\">Ändra storlek efter gränser</string>\n    <string name=\"limits_resize_sub\">Ändra storlek på bilder till den angivna höjden och bredden samtidigt som bildförhållandet behålls</string>\n    <string name=\"sketch\">Skiss</string>\n    <string name=\"threshold\">Tröskel</string>\n    <string name=\"quantizationLevels\">Kvantiseringsnivåer</string>\n    <string name=\"smooth_toon\">Slät ton</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterisera</string>\n    <string name=\"non_maximum_suppression\">Icke maximal undertryckning</string>\n    <string name=\"weak_pixel_inclusion\">Svag pixelinkludering</string>\n    <string name=\"lookup\">Uppslag</string>\n    <string name=\"convolution3x3\">Convolution 3x3</string>\n    <string name=\"rgb_filter\">RGB-filter</string>\n    <string name=\"false_color\">Falsk färg</string>\n    <string name=\"first_color\">Första färgen</string>\n    <string name=\"blur_center_x\">Oskärpa mitten x</string>\n    <string name=\"blur_center_y\">Oskärpa mitten y</string>\n    <string name=\"zoom_blur\">Zoomoskärpa</string>\n    <string name=\"color_balance\">Färgbalans</string>\n    <string name=\"luminance_threshold\">Luminans tröskel</string>\n    <string name=\"activate_files\">Du inaktiverade appen Filer, aktivera den för att använda den här funktionen</string>\n    <string name=\"draw\">Dra</string>\n    <string name=\"draw_sub\">Rita på bild som i en skissbok, eller rita på själva bakgrunden</string>\n    <string name=\"paint_color\">Måla färg</string>\n    <string name=\"paint_alpha\">Måla alfa</string>\n    <string name=\"draw_on_image\">Rita på bild</string>\n    <string name=\"draw_on_image_sub\">Välj en bild och rita något på den</string>\n    <string name=\"draw_on_background\">Rita på bakgrund</string>\n    <string name=\"draw_on_background_sub\">Välj bakgrundsfärg och rita ovanpå den</string>\n    <string name=\"background_color\">Bakgrundsfärg</string>\n    <string name=\"cipher\">Chiffer</string>\n    <string name=\"cipher_sub\">Kryptera och dekryptera vilken fil som helst (inte bara bilden) baserat på olika tillgängliga kryptoalgoritmer</string>\n    <string name=\"pick_file\">Välj fil</string>\n    <string name=\"encrypt\">Kryptera</string>\n    <string name=\"decrypt\">Dekryptera</string>\n    <string name=\"pick_file_to_start\">Välj fil för att starta</string>\n    <string name=\"decryption\">Dekryptering</string>\n    <string name=\"encryption\">Kryptering</string>\n    <string name=\"key\">Nyckel</string>\n    <string name=\"file_proceed\">Filen behandlas</string>\n    <string name=\"store_file_desc\">Lagra den här filen på din enhet eller använd dela för att placera den var du vill</string>\n    <string name=\"features\">Drag</string>\n    <string name=\"implementation\">Genomförande</string>\n    <string name=\"compatibility\">Kompatibilitet</string>\n    <string name=\"features_sub\">Lösenordsbaserad kryptering av filer. Fortsatta filer kan lagras i den valda katalogen eller delas. Dekrypterade filer kan också öppnas direkt.</string>\n    <string name=\"implementation_sub\">AES-256, GCM-läge, ingen utfyllnad, 12 bytes slumpmässiga IVs som standard. Du kan välja den algoritm som behövs. Nycklar används som 256-bitars SHA-3-hashar</string>\n    <string name=\"file_size\">Fil-storlek</string>\n    <string name=\"file_size_sub\">Den maximala filstorleken begränsas av Android OS och tillgängligt minne, vilket är enhetsberoende.\n\\nObservera: minnet är inte lagringsutrymme.</string>\n    <string name=\"compatibility_sub\">Observera att kompatibilitet med annan filkrypteringsmjukvara eller tjänster inte garanteras. En något annorlunda nyckelbehandling eller chifferkonfiguration kan orsaka inkompatibilitet.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Ogiltigt lösenord eller vald fil är inte krypterad</string>\n    <string name=\"image_size_warning\">Om du försöker spara bilden med den angivna bredden och höjden kan det leda till att minnet är slut. Gör detta på egen risk.</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Cachestorlek</string>\n    <string name=\"found_s\">Hittade %1$s</string>\n    <string name=\"auto_cache_clearing\">Automatisk cacherensning</string>\n    <string name=\"auto_cache_clearing_sub\">Om aktiverat rensas appcachen vid start av appen</string>\n    <string name=\"create\">Skapa</string>\n    <string name=\"tools\">Verktyg</string>\n    <string name=\"group_options_by_type\">Gruppera alternativ efter typ</string>\n    <string name=\"group_options_by_type_sub\">Grupperar alternativ på huvudskärmen efter deras typ istället för ett anpassat listarrangemang</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Kan inte ändra arrangemang medan alternativgruppering är aktiverad</string>\n    <string name=\"edit_screenshot\">Redigera skärmdump</string>\n    <string name=\"secondary_customization\">Sekundär anpassning</string>\n    <string name=\"screenshot\">Skärmdump</string>\n    <string name=\"fallback_option\">Reservalternativ</string>\n    <string name=\"skip\">Hoppa</string>\n    <string name=\"copy\">Kopiera</string>\n    <string name=\"warning_bytes\">Att spara i läget %1$s kan vara instabilt eftersom det är ett förlustfritt format</string>\n    <string name=\"presets_sub\">Om du har valt förinställning 125, kommer bilden att sparas som 125 % av originalbilden. Om du väljer förinställning 50, kommer bilden att sparas med 50 % storlek</string>\n    <string name=\"presets_sub_bytes\">Förinställning här bestämmer % av utdatafilen, d.v.s. om du väljer förinställning 50 på 5 MB bild så får du en 2,5 MB bild efter att du har sparat</string>\n    <string name=\"randomize_filename\">Randomisera filnamn</string>\n    <string name=\"randomize_filename_sub\">Om det är aktiverat kommer filnamnet att vara helt slumpmässigt</string>\n    <string name=\"saved_to\">Sparad i mappen %1$s med namnet %2$s</string>\n    <string name=\"saved_to_without_filename\">Sparad i mappen %1$s</string>\n    <string name=\"tg_chat\">Telegram chatt</string>\n    <string name=\"tg_chat_sub\">Diskutera appen och få feedback från andra användare. Du kan också få betauppdateringar och insikter där.</string>\n    <string name=\"crop_mask\">Beskärningsmask</string>\n    <string name=\"aspect_ratio\">Bildförhållande</string>\n    <string name=\"image_crop_mask_sub\">Använd den här masktypen för att skapa mask från en given bild, lägg märke till att den SKA ha alfakanal</string>\n    <string name=\"backup_and_restore\">Säkerhetskopiera och återställa</string>\n    <string name=\"backup\">Säkerhetskopiering</string>\n    <string name=\"restore\">Återställ</string>\n    <string name=\"backup_sub\">Säkerhetskopiera appinställningar till en fil</string>\n    <string name=\"restore_sub\">Återställ appinställningar från tidigare genererad fil</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Skadad fil eller inte en säkerhetskopia</string>\n    <string name=\"settings_restored\">Inställningarna har återställts</string>\n    <string name=\"contact_me\">Kontakta mig</string>\n    <string name=\"reset_settings_sub\">Detta kommer att återställa dina inställningar till standardvärdena. Observera att detta inte kan ångras utan en säkerhetskopia som nämns ovan.</string>\n    <string name=\"delete\">Radera</string>\n    <string name=\"delete_color_scheme_warn\">Du håller på att ta bort det valda färgschemat. Denna operation kan inte ångras</string>\n    <string name=\"delete_color_scheme_title\">Ta bort schema</string>\n    <string name=\"font\">Font</string>\n    <string name=\"text\">Text</string>\n    <string name=\"font_scale\">Teckensnittsskala</string>\n    <string name=\"defaultt\">Standard</string>\n    <string name=\"using_large_fonts_warn\">Användning av stora teckensnittsskalor kan orsaka gränssnittsfel och problem som inte kommer att åtgärdas. Använd med försiktighet.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz Åå Ää Öö 0123456789 !?</string>\n    <string name=\"emotions\">Känslor</string>\n    <string name=\"food_and_drink\">Mat och dryck</string>\n    <string name=\"nature_and_animals\">Natur och djur</string>\n    <string name=\"objects\">Objekt</string>\n    <string name=\"symbols\">Symboler</string>\n    <string name=\"enable_emoji\">Aktivera emoji</string>\n    <string name=\"travels_and_places\">Resor och platser</string>\n    <string name=\"activities\">Aktiviteter</string>\n    <string name=\"background_remover\">Bakgrundsborttagare</string>\n    <string name=\"background_remover_sub\">Ta bort bakgrunden från bilden genom att rita eller använd alternativet Auto</string>\n    <string name=\"trim_image\">Beskär bild</string>\n    <string name=\"keep_exif_sub\">Originalbildens metadata kommer att behållas</string>\n    <string name=\"trim_image_sub\">Genomskinliga utrymmen runt bilden kommer att beskäras</string>\n    <string name=\"auto_erase_background\">Autoradera bakgrund</string>\n    <string name=\"restore_image\">Återställ bild</string>\n    <string name=\"erase_mode\">Raderings-läge</string>\n    <string name=\"erase_background\">Radera bakgrund</string>\n    <string name=\"restore_background\">Återställ bakgrund</string>\n    <string name=\"blur_radius\">Oskarphetsradie</string>\n    <string name=\"pipette\">Pipett</string>\n    <string name=\"draw_mode\">Ritläge</string>\n    <string name=\"create_issue\">Skapa problem</string>\n    <string name=\"something_went_wrong_emphasis\">Hoppsan… Något gick fel. Du kan skriva till mig med hjälp av alternativen nedan så ska jag försöka hitta en lösning</string>\n    <string name=\"resize_and_convert\">Storleksändra och konvertera</string>\n    <string name=\"resize_and_convert_sub\">Ändra storlek på givna bilder eller konvertera dem till andra format. EXIF-metadata kan också redigeras här om du väljer enskild bild.</string>\n    <string name=\"max_colors_count\">Max antal färger</string>\n    <string name=\"crashlytics_sub\">Detta gör att appen kan samla in kraschrapporter automatiskt</string>\n    <string name=\"analytics\">Analyser</string>\n    <string name=\"analytics_sub\">Tillåt anonym insamling av appanvändningsstatistik</string>\n    <string name=\"image_exif_warning\">För närvarande tillåter formatet %1$s endast läsning av EXIF-metadata på Android. Utdatabild kommer inte inkludera metadata när den sparas.</string>\n    <string name=\"effort\">Ansträngning</string>\n    <string name=\"effort_sub\">Ett värde på %1$s betyder snabb komprimering, vilket resulterar i en relativt stor filstorlek. %2$s betyder en långsammare komprimering, vilket resulterar i en mindre fil.</string>\n    <string name=\"wait\">Vänta</string>\n    <string name=\"saving_almost_complete\">Sparningen är nästan klar. Om du avbryter nu måste du spara igen.</string>\n    <string name=\"updates\">Uppdateringar</string>\n    <string name=\"allow_betas\">Tillåt betaversioner</string>\n    <string name=\"allow_betas_sub\">Uppdateringskontrollen kommer att inkludera betaappversioner om den är aktiverad</string>\n    <string name=\"draw_arrows\">Rita pilar</string>\n    <string name=\"draw_arrows_sub\">Om aktiverat kommer ritbanan att representeras som pekpil</string>\n    <string name=\"brush_softness\">Borsta mjukhet</string>\n    <string name=\"crop_description\">Bilderna kommer att beskäras i mitten till den angivna storleken. Canvas kommer att utökas med given bakgrundsfärg om bilden är mindre än angivna mått.</string>\n    <string name=\"donation\">Donation</string>\n    <string name=\"image_stitching\">Bildsömnad</string>\n    <string name=\"image_stitching_sub\">Kombinera de givna bilderna för att få en stor</string>\n    <string name=\"pick_at_least_two_images\">Välj minst 2 bilder</string>\n    <string name=\"output_image_scale\">Utdatabilds skala</string>\n    <string name=\"image_orientation\">Bildorientering</string>\n    <string name=\"horizontal\">Horisontell</string>\n    <string name=\"vertical\">Vertikal</string>\n    <string name=\"scale_small_images_to_large\">Skala små bilder till stora</string>\n    <string name=\"scale_small_images_to_large_sub\">Små bilder skalas till den största i sekvensen om det är aktiverat</string>\n    <string name=\"images_order\">Beställning av bilder</string>\n    <string name=\"regular\">Regelbunden</string>\n    <string name=\"blur_edges\">Sudda kanter</string>\n    <string name=\"blur_edges_sub\">Ritar suddiga kanter under originalbilden för att fylla utrymmen runt den istället för enfärgad om aktiverat</string>\n    <string name=\"pixelation\">Pixelering</string>\n    <string name=\"enhanced_pixelation\">Förbättrad pixelering</string>\n    <string name=\"stroke_pixelation\">Stroke Pixelation</string>\n    <string name=\"enhanced_diamond_pixelation\">Förbättrad diamantpixelering</string>\n    <string name=\"diamond_pixelation\">Diamond Pixelation</string>\n    <string name=\"circle_pixelation\">Cirkelpixelering</string>\n    <string name=\"enhanced_circle_pixelation\">Förbättrad cirkelpixelering</string>\n    <string name=\"replace_color\">Byt ut färg</string>\n    <string name=\"tolerance\">Tolerans</string>\n    <string name=\"color_to_replace\">Färg att ersätta</string>\n    <string name=\"target_color\">Målfärg</string>\n    <string name=\"color_to_remove\">Färg att ta bort</string>\n    <string name=\"remove_color\">Ta bort färg</string>\n    <string name=\"recode\">Koda om</string>\n    <string name=\"pixel_size\">Pixelstorlek</string>\n    <string name=\"lock_draw_orientation\">Lås ritriktning</string>\n    <string name=\"lock_draw_orientation_sub\">Om det är aktiverat i ritläge kommer skärmen inte att rotera</string>\n    <string name=\"check_for_updates\">Sök efter uppdateringar</string>\n    <string name=\"palette_style\">Palett stil</string>\n    <string name=\"tonal_spot\">Tonal punkt</string>\n    <string name=\"neutral\">Neutral</string>\n    <string name=\"vibrant\">Vibrerande</string>\n    <string name=\"expressive\">Uttrycksfull</string>\n    <string name=\"rainbow\">Regnbåge</string>\n    <string name=\"fruit_salad\">Fruktsallad</string>\n    <string name=\"fidelity\">Trohet</string>\n    <string name=\"content\">Innehåll</string>\n    <string name=\"tonal_spot_sub\">Standard palettstil, det tillåter att anpassa alla fyra färgerna, andra låter dig ställa in endast nyckelfärgen</string>\n    <string name=\"neutral_sub\">En stil som är något mer kromatisk än monokrom</string>\n    <string name=\"vibrant_sub\">Ett högljutt tema, färgglattheten är maximal för Primär palett, ökad för andra</string>\n    <string name=\"playful_scheme\">Ett lekfullt tema - källfärgens nyans visas inte i temat</string>\n    <string name=\"monochrome_sub\">Ett monokromt tema, färgerna är rent svart / vit / grå</string>\n    <string name=\"content_sub\">Ett schema som placerar källfärgen i Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Ett schema som är väldigt likt innehållsschemat</string>\n    <string name=\"foss_update_checker_warning\">Denna uppdateringskontroll kommer att ansluta till GitHub för att kontrollera om det finns en ny uppdatering tillgänglig</string>\n    <string name=\"attention\">Uppmärksamhet</string>\n    <string name=\"fading_edges\">Bleknade kanter</string>\n    <string name=\"disabled\">Inaktiverad</string>\n    <string name=\"both\">Både</string>\n    <string name=\"invert_colors\">Invertera färger</string>\n    <string name=\"invert_colors_sub\">Ersätter temafärger till negativa om det är aktiverat</string>\n    <string name=\"search_option\">Söka</string>\n    <string name=\"search_option_sub\">Möjliggör möjligheten att söka igenom alla tillgängliga verktyg på huvudskärmen</string>\n    <string name=\"pdf_tools\">PDF-verktyg</string>\n    <string name=\"pdf_tools_sub\">Arbeta med PDF-filer: Förhandsgranska, Konvertera till en grupp bilder eller skapa en från givna bilder</string>\n    <string name=\"preview_pdf\">Förhandsgranska PDF</string>\n    <string name=\"pdf_to_images\">PDF till bilder</string>\n    <string name=\"images_to_pdf\">Bilder till PDF</string>\n    <string name=\"preview_pdf_sub\">Enkel PDF-förhandsvisning</string>\n    <string name=\"pdf_to_images_sub\">Konvertera PDF till bilder i givet utdataformat</string>\n    <string name=\"images_to_pdf_sub\">Packa givna bilder till utdata-PDF-fil</string>\n    <string name=\"mask_filter\">Maskfilter</string>\n    <string name=\"mask_filter_sub\">Applicera filterkedjor på givna maskerade områden, varje maskområde kan bestämma sin egen uppsättning filter</string>\n    <string name=\"masks\">Masker</string>\n    <string name=\"add_mask\">Lägg till mask</string>\n    <string name=\"mask_indexed\">Mask %d</string>\n    <string name=\"mask_color\">Mask färg</string>\n    <string name=\"mask_preview\">Mask förhandsgranskning</string>\n    <string name=\"mask_preview_sub\">Ritad filtermask kommer att renderas för att visa dig det ungefärliga resultatet</string>\n    <string name=\"inverse_fill_type\">Omvänd fyllningstyp</string>\n    <string name=\"inverse_fill_type_sub\">Om aktiverat kommer alla icke-maskerade områden att filtreras istället för standardbeteende</string>\n    <string name=\"delete_mask_warn\">Du håller på att ta bort den valda filtermasken. Denna operation kan inte ångras</string>\n    <string name=\"delete_mask\">Ta bort mask</string>\n    <string name=\"full_filter\">Fullt filter</string>\n    <string name=\"full_filter_sub\">Använd eventuella filterkedjor på givna bilder eller enstaka bilder</string>\n    <string name=\"start_position\">Start</string>\n    <string name=\"center_position\">Centrum</string>\n    <string name=\"end_position\">Avsluta</string>\n    <string name=\"simple_variants\">Enkla varianter</string>\n    <string name=\"highlighter\">Highlighter</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Penna</string>\n    <string name=\"privacy_blur\">Sekretessoskärpa</string>\n    <string name=\"highlighter_sub\">Rita halvtransparenta vässade överstrykningspennor</string>\n    <string name=\"neon_sub\">Lägg till en glödande effekt på dina ritningar</string>\n    <string name=\"pen_sub\">Standard en, enklast - bara färgen</string>\n    <string name=\"privacy_blur_sub\">Gör bilden suddig under den ritade banan för att säkra allt du vill dölja</string>\n    <string name=\"pixelation_sub\">Liknar sekretessoskärpa, men pixlar istället för oskärpa</string>\n    <string name=\"containers_shadow\">Behållare</string>\n    <string name=\"containers_shadow_sub\">Rita en skugga bakom behållare</string>\n    <string name=\"sliders_shadow\">Reglage</string>\n    <string name=\"switches_shadow\">Växlar</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">Knappar</string>\n    <string name=\"sliders_shadow_sub\">Rita en skugga bakom reglagen</string>\n    <string name=\"switches_shadow_sub\">Rita en skugga bakom strömbrytare</string>\n    <string name=\"fabs_shadow_sub\">Rita en skugga bakom flytande actionknappar</string>\n    <string name=\"buttons_shadow_sub\">Rita en skugga bakom knappar</string>\n    <string name=\"app_bars_shadow\">App barer</string>\n    <string name=\"app_bars_shadow_sub\">Rita en skugga bakom appstaplar</string>\n    <string name=\"value_in_range\">Värde inom intervallet %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Autorotera</string>\n    <string name=\"auto_rotate_limits_sub\">Tillåter att gränsruta används för bildorientering</string>\n    <string name=\"draw_path_mode\">Rita sökvägsläge</string>\n    <string name=\"double_line_arrow\">Dubbel linjepil</string>\n    <string name=\"free_drawing\">Gratis ritning</string>\n    <string name=\"double_arrow\">Dubbel pil</string>\n    <string name=\"line_arrow\">Linjepil</string>\n    <string name=\"arrow\">Pil</string>\n    <string name=\"line\">Linje</string>\n    <string name=\"free_drawing_sub\">Ritar sökväg som indatavärde</string>\n    <string name=\"line_sub\">Ritar banan från startpunkt till slutpunkt som en linje</string>\n    <string name=\"line_arrow_sub\">Ritar pekpil från startpunkt till slutpunkt som en linje</string>\n    <string name=\"arrow_sub\">Ritar en pekande pil från en given bana</string>\n    <string name=\"double_line_arrow_sub\">Ritar dubbel pekande pil från startpunkt till slutpunkt som en linje</string>\n    <string name=\"double_arrow_sub\">Ritar dubbelpekande pil från en given bana</string>\n    <string name=\"outlined_oval\">Oval kontur</string>\n    <string name=\"outlined_rect\">Skisserad Rect</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Ritar rät från startpunkt till slutpunkt</string>\n    <string name=\"oval_sub\">Ritar oval från startpunkt till slutpunkt</string>\n    <string name=\"outlined_oval_sub\">Ritar en oval med kontur från startpunkt till slutpunkt</string>\n    <string name=\"outlined_rect_sub\">Ritar konturerade rekt från startpunkt till slutpunkt</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Ritar stängd fylld bana efter given bana</string>\n    <string name=\"free\">Gratis</string>\n    <string name=\"horizontal_grid\">Horisontellt rutnät</string>\n    <string name=\"vertical_grid\">Vertikalt rutnät</string>\n    <string name=\"stitch_mode\">Stygnläge</string>\n    <string name=\"rows_count\">Räknar rader</string>\n    <string name=\"columns_count\">Antal kolumner</string>\n    <string name=\"no_such_directory\">Ingen \\\"%1$s\\\"-katalog hittades, vi bytte den till standardmappen, spara filen igen</string>\n    <string name=\"clipboard\">Urklipp</string>\n    <string name=\"auto_pin\">Auto pin</string>\n    <string name=\"auto_pin_sub\">Lägger automatiskt till sparad bild till urklipp om aktiverat</string>\n    <string name=\"vibration\">Vibration</string>\n    <string name=\"vibration_strength\">Vibrationsstyrka</string>\n    <string name=\"overwrite_file_requirements\">För att skriva över filer måste du använda \\\"Utforskaren\\\" bildkälla, försök återplocka bilder, vi har ändrat bildkällan till den som behövs</string>\n    <string name=\"overwrite_files\">Skriv över filer</string>\n    <string name=\"overwrite_files_sub\">Originalfilen kommer att ersättas med en ny istället för att sparas i vald mapp, det här alternativet måste vara \\\"Explorer\\\" eller GetContent som bildkälla, när du växlar detta kommer det att ställas in automatiskt</string>\n    <string name=\"empty\">Tömma</string>\n    <string name=\"suffix\">Ändelse</string>\n    <string name=\"scale_mode\">Skalläge</string>\n    <string name=\"bilinear\">bilinjär</string>\n    <string name=\"catmull\">Kattmull</string>\n    <string name=\"bicubic\">Bikubisk</string>\n    <string name=\"hann\">Han</string>\n    <string name=\"hermite\">Eremit</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Närmast</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Grundläggande</string>\n    <string name=\"default_value\">Standardvärde</string>\n    <string name=\"bilinear_sub\">Linjär (eller bilinjär, i två dimensioner) interpolation är vanligtvis bra för att ändra storleken på en bild, men orsakar en oönskad uppmjukning av detaljer och kan fortfarande vara något ojämn</string>\n    <string name=\"bicubic_sub\">Bättre skalningsmetoder inkluderar Lanczos resampling och Mitchell-Netravali-filter</string>\n    <string name=\"nearest_sub\">Ett av de enklare sätten att öka storleken genom att ersätta varje pixel med ett antal pixlar av samma färg</string>\n    <string name=\"basic_sub\">Enklaste skalningsläget för Android som används i nästan alla appar</string>\n    <string name=\"catmull_sub\">Metod för att smidigt interpolera och omsampla en uppsättning kontrollpunkter, som vanligtvis används i datorgrafik för att skapa jämna kurvor</string>\n    <string name=\"hann_sub\">Fönsterfunktion används ofta i signalbehandling för att minimera spektralläckage och förbättra noggrannheten i frekvensanalys genom att avsmalna kanterna på en signal</string>\n    <string name=\"hermite_sub\">Matematisk interpolationsteknik som använder värden och derivator vid ändpunkterna av ett kurvsegment för att generera en jämn och kontinuerlig kurva</string>\n    <string name=\"lanczos_sub\">Omsamplingsmetod som upprätthåller interpolering av hög kvalitet genom att tillämpa en viktad sinc-funktion på pixelvärdena</string>\n    <string name=\"mitchell_sub\">Omsamplingsmetod som använder ett faltningsfilter med justerbara parametrar för att uppnå en balans mellan skärpa och kantutjämning i den skalade bilden</string>\n    <string name=\"spline_sub\">Använder bitvis definierade polynomfunktioner för att jämnt interpolera och approximera en kurva eller yta, vilket ger flexibel och kontinuerlig formrepresentation</string>\n    <string name=\"only_clip\">Endast klipp</string>\n    <string name=\"only_clip_sub\">Spara till lagring kommer inte att utföras, och bilden kommer endast att försöka läggas in i urklipp</string>\n    <string name=\"restore_background_sub\">Penseln återställer bakgrunden istället för att radera</string>\n    <string name=\"recognize_text\">OCR (känn igen text)</string>\n    <string name=\"recognize_text_sub\">Känn igen text från en given bild, 120+ språk stöds</string>\n    <string name=\"picture_has_no_text\">Bilden har ingen text, eller så hittade appen den inte</string>\n    <string name=\"accuracy\">\\\"Noggrannhet: %1$s\\\"</string>\n    <string name=\"recognition_type\">Typ av igenkänning</string>\n    <string name=\"fast\">Snabb</string>\n    <string name=\"standard\">Standard</string>\n    <string name=\"best\">Bäst</string>\n    <string name=\"no_data\">Inga data</string>\n    <string name=\"download_description\">För att Tesseract OCR ska fungera korrekt måste ytterligare träningsdata (%1$s) laddas ner till din enhet.\\nVill du ladda ner %2$s-data?</string>\n    <string name=\"download\">Ladda ner</string>\n    <string name=\"no_connection\">Ingen anslutning, kontrollera det och försök igen för att ladda ner tågmodeller</string>\n    <string name=\"downloaded_languages\">Nedladdade språk</string>\n    <string name=\"available_languages\">Tillgängliga språk</string>\n    <string name=\"segmentation_mode\">Segmenteringsläge</string>\n    <string name=\"use_pixel_switch\">Använd Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Använder en Google Pixel-liknande switch</string>\n    <string name=\"saved_to_original\">Överskriven fil med namnet %1$s vid den ursprungliga destinationen</string>\n    <string name=\"magnifier\">Förstoringsglas</string>\n    <string name=\"magnifier_sub\">Aktiverar förstoringsglas överst på fingret i ritlägen för bättre tillgänglighet</string>\n    <string name=\"force_exif_widget_initial_value\">Forcera initialt värde</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Tvingar exif-widgeten att kontrolleras initialt</string>\n    <string name=\"allow_multiple_languages\">Tillåt flera språk</string>\n    <string name=\"slide\">Glida</string>\n    <string name=\"side_by_side\">Sida vid sida</string>\n    <string name=\"toggle_tap\">Växla Tryck</string>\n    <string name=\"transparency\">Genomskinlighet</string>\n    <string name=\"rate_app\">Betygsätt App</string>\n    <string name=\"rate\">Hastighet</string>\n    <string name=\"rate_app_sub\">Denna app är helt gratis, om du vill att den ska bli större, vänligen stjärna projektet på Github 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Endast orientering och skriptdetektion</string>\n    <string name=\"segmentation_mode_auto_osd\">Automatisk orientering och skriptidentifiering</string>\n    <string name=\"segmentation_mode_auto_only\">Endast auto</string>\n    <string name=\"segmentation_mode_auto\">Bil</string>\n    <string name=\"segmentation_mode_single_column\">Enstaka kolumn</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Ett block vertikal text</string>\n    <string name=\"segmentation_mode_single_block\">Enkelt block</string>\n    <string name=\"segmentation_mode_single_line\">En rad</string>\n    <string name=\"segmentation_mode_single_word\">Ett enda ord</string>\n    <string name=\"segmentation_mode_circle_word\">Ringa in ord</string>\n    <string name=\"segmentation_mode_single_char\">Enstaka röding</string>\n    <string name=\"segmentation_mode_sparse_text\">Sparsam text</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Gles textorientering &amp;amp; skriptdetektion</string>\n    <string name=\"segmentation_mode_raw_line\">Rå linje</string>\n    <string name=\"delete_language_sub\">Vill du radera språket \\\"%1$s\\\" OCR-träningsdata för alla igenkänningstyper, eller bara för den valda (%2$s)?</string>\n    <string name=\"current\">Nuvarande</string>\n    <string name=\"all\">Alla</string>\n    <string name=\"gradient_maker\">Gradient Maker</string>\n    <string name=\"gradient_maker_sub\">Skapa gradient av given utdatastorlek med anpassade färger och utseendetyp</string>\n    <string name=\"gradient_type_linear\">Linjär</string>\n    <string name=\"gradient_type_radial\">Radiell</string>\n    <string name=\"gradient_type_sweep\">Sopa</string>\n    <string name=\"gradient_type\">Gradienttyp</string>\n    <string name=\"center_x\">Center X</string>\n    <string name=\"center_y\">Center Y</string>\n    <string name=\"tile_mode\">Kakelläge</string>\n    <string name=\"tile_mode_repeated\">Upprepad</string>\n    <string name=\"tile_mode_mirror\">Spegel</string>\n    <string name=\"tile_mode_clamp\">Klämma</string>\n    <string name=\"tile_mode_decal\">Dekal</string>\n    <string name=\"color_stops\">Färgen stannar</string>\n    <string name=\"add_color\">Lägg till färg</string>\n    <string name=\"properties\">Egenskaper</string>\n    <string name=\"brightness_enforcement\">Upprätthållande av ljusstyrka</string>\n    <string name=\"screen\">Skärm</string>\n    <string name=\"gradient_maker_type_image\">Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_sub\">Komponera valfri gradient av toppen av givna bilder</string>\n    <string name=\"transformations\">Transformationer</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Ta en bild med en kamera. Observera att det bara är möjligt att få en bild från denna bildkälla</string>\n    <string name=\"watermarking\">Vattenmärkning</string>\n    <string name=\"watermarking_sub\">Täck bilder med anpassningsbara text-/bildvattenstämplar</string>\n    <string name=\"repeat_watermark\">Upprepa vattenstämpel</string>\n    <string name=\"repeat_watermark_sub\">Upprepar vattenstämpel över bild istället för singel vid given position</string>\n    <string name=\"offset_x\">Offset X</string>\n    <string name=\"offset_y\">Offset Y</string>\n    <string name=\"watermark_type\">Typ av vattenstämpel</string>\n    <string name=\"watermarking_image_sub\">Den här bilden kommer att användas som mönster för vattenmärkning</string>\n    <string name=\"text_color\">Text färg</string>\n    <string name=\"overlay_mode\">Överlagringsläge</string>\n    <string name=\"gif_tools\">GIF-verktyg</string>\n    <string name=\"gif_tools_sub\">Konvertera bilder till GIF-bild eller extrahera ramar från given GIF-bild</string>\n    <string name=\"gif_type_to_image\">GIF till bilder</string>\n    <string name=\"gif_type_to_image_sub\">Konvertera GIF-fil till en serie bilder</string>\n    <string name=\"gif_type_to_gif_sub\">Konvertera parti bilder till GIF-fil</string>\n    <string name=\"gif_type_to_gif\">Bilder till GIF</string>\n    <string name=\"select_gif_image_to_start\">Välj GIF-bild för att starta</string>\n    <string name=\"use_size_of_first_frame\">Använd storleken på den första ramen</string>\n    <string name=\"use_size_of_first_frame_sub\">Ersätt specificerad storlek med första rammått</string>\n    <string name=\"repeat_count\">Upprepa räkning</string>\n    <string name=\"frame_delay\">Frame Delay</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Använd Lasso</string>\n    <string name=\"use_lasso_sub\">Använder lasso som i ritläge för att utföra radering</string>\n    <string name=\"original_image_preview_alpha\">Förhandsgranskning av originalbild Alpha</string>\n    <string name=\"confetti\">Konfetti</string>\n    <string name=\"confetti_sub\">Konfetti kommer att visas på sparande, delning och andra primära åtgärder</string>\n    <string name=\"secure_mode\">Säkert läge</string>\n    <string name=\"secure_mode_sub\">Döljer appinnehåll i de senaste apparna. Det går inte att fånga eller spela in.</string>\n    <string name=\"exit\">Utgång</string>\n    <string name=\"preview_closing\">Om du lämnar förhandsgranskningen nu måste du lägga till bilderna igen</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Kvantifierare</string>\n    <string name=\"gray_scale\">Gråskala</string>\n    <string name=\"bayer_two_dithering\">Bayer två och två dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer tre och tre dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer fyra vid fyra dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis domare Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Två rader Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">Falsk Floyd Steinberg Dithering</string>\n    <string name=\"left_to_right_dithering\">Vänster till höger dithering</string>\n    <string name=\"random_dithering\">Slumpmässig dithering</string>\n    <string name=\"simple_threshold_dithering\">Enkel tröskelvibrering</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Spatial Sigma</string>\n    <string name=\"median_blur\">Median oskärpa</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Använder bitvis definierade bikubiska polynomfunktioner för att smidigt interpolera och approximera en kurva eller yta, flexibel och kontinuerlig formrepresentation</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"glitch\">Glitch</string>\n    <string name=\"amount\">Belopp</string>\n    <string name=\"seed\">Utsäde</string>\n    <string name=\"anaglyph\">Anaglyph</string>\n    <string name=\"noise\">Buller</string>\n    <string name=\"pixel_sort\">Pixelsort</string>\n    <string name=\"shuffle\">Blanda</string>\n    <string name=\"enhanced_glitch\">Förbättrad glitch</string>\n    <string name=\"channel_shift_x\">Channel Shift X</string>\n    <string name=\"channel_shift_y\">Kanalskift Y</string>\n    <string name=\"corruption_size\">Korruptionsstorlek</string>\n    <string name=\"corruption_shift_x\">Korruption Shift X</string>\n    <string name=\"corruption_shift_y\">Korruptionsskift Y</string>\n    <string name=\"tent_blur\">Tältskärpa</string>\n    <string name=\"side_fade\">Sida blekna</string>\n    <string name=\"side\">Sida</string>\n    <string name=\"top\">Bästa</string>\n    <string name=\"bottom\">Botten</string>\n    <string name=\"strength\">Styrka</string>\n    <string name=\"erode\">Erodera</string>\n    <string name=\"anisotropic_diffusion\">Anisotropisk diffusion</string>\n    <string name=\"diffusion\">Diffusion</string>\n    <string name=\"conduction\">Ledning</string>\n    <string name=\"horizontal_wind_stagger\">Horisontell vindsvängning</string>\n    <string name=\"fast_bilaterial_blur\">Snabb bilateral oskärpa</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmisk tonmappning</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"crystallize\">Kristallisera</string>\n    <string name=\"stroke_color\">Slagfärg</string>\n    <string name=\"fractal_glass\">Fraktal glas</string>\n    <string name=\"amplitude\">Amplitud</string>\n    <string name=\"marble\">Marmor</string>\n    <string name=\"turbulence\">Turbulens</string>\n    <string name=\"oil\">Olja</string>\n    <string name=\"water_effect\">Vatteneffekt</string>\n    <string name=\"just_size\">Storlek</string>\n    <string name=\"frequency_x\">Frekvens X</string>\n    <string name=\"frequency_y\">Frekvens Y</string>\n    <string name=\"amplitude_x\">Amplitud X</string>\n    <string name=\"amplitude_y\">Amplitud Y</string>\n    <string name=\"perlin_distortion\">Perlin Distortion</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Tonkartläggning</string>\n    <string name=\"speed\">Hastighet</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Färgmatris 4x4</string>\n    <string name=\"color_matrix_3x3\">Färgmatris 3x3</string>\n    <string name=\"simple_effects\">Enkla effekter</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomali</string>\n    <string name=\"deutaromaly\">Deuteranomali</string>\n    <string name=\"protonomaly\">Protanomali</string>\n    <string name=\"vintage\">Årgång</string>\n    <string name=\"browni\">Browns</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Nattseende</string>\n    <string name=\"warm\">Värma</string>\n    <string name=\"cool\">Sval</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Akromatomali</string>\n    <string name=\"achromatopsia\">Achromatopsi</string>\n    <string name=\"grain\">Spannmål</string>\n    <string name=\"unsharp\">Oskarp</string>\n    <string name=\"pastel\">Pastell</string>\n    <string name=\"orange_haze\">Orange Haze</string>\n    <string name=\"pink_dream\">Rosa dröm</string>\n    <string name=\"golden_hour\">Gyllene timmen</string>\n    <string name=\"hot_summer\">Varm sommar</string>\n    <string name=\"purple_mist\">Purple Mist</string>\n    <string name=\"sunrise\">Soluppgång</string>\n    <string name=\"colorful_swirl\">Färgglad virvel</string>\n    <string name=\"soft_spring_light\">Mjukt fjäderljus</string>\n    <string name=\"autumn_tones\">Hösttoner</string>\n    <string name=\"lavender_dream\">Lavendel dröm</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Lemonad ljus</string>\n    <string name=\"spectral_fire\">Spektral eld</string>\n    <string name=\"night_magic\">Nattmagi</string>\n    <string name=\"fantasy_landscape\">Fantasilandskap</string>\n    <string name=\"color_explosion\">Färgexplosion</string>\n    <string name=\"electric_gradient\">Elektrisk gradient</string>\n    <string name=\"caramel_darkness\">Caramel Darkness</string>\n    <string name=\"futuristic_gradient\">Futuristisk gradient</string>\n    <string name=\"green_sun\">Grön sol</string>\n    <string name=\"rainbow_world\">Rainbow World</string>\n    <string name=\"deep_purple\">Deep Purple</string>\n    <string name=\"space_portal\">Rymdportal</string>\n    <string name=\"red_swirl\">Röd virvel</string>\n    <string name=\"digital_code\">Digital kod</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">Appfältets emoji kommer att ändras slumpmässigt</string>\n    <string name=\"random_emojis\">Slumpmässiga emojis</string>\n    <string name=\"random_emojis_error\">Du kan inte använda slumpmässiga emojis medan emojis är inaktiverade</string>\n    <string name=\"emoji_selection_error\">Du kan inte välja en emoji medan slumpmässiga emojis är aktiverade</string>\n    <string name=\"old_tv\">Gammal tv</string>\n    <string name=\"shuffle_blur\">Blanda oskärpa</string>\n    <string name=\"favorite\">Favorit</string>\n    <string name=\"no_favorite_filters\">Inga favoritfilter har lagts till ännu</string>\n    <string name=\"image_format\">Bildformat</string>\n    <string name=\"icon_shape_sub\">Lägger till en behållare med den valda formen under ikonerna</string>\n    <string name=\"icon_shape\">Ikon Form</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Cutoff</string>\n    <string name=\"uchimura\">Du vaknar</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Övergång</string>\n    <string name=\"peak\">Topp</string>\n    <string name=\"color_anomaly\">Färgavvikelse</string>\n    <string name=\"images_overwritten\">Bilder skrivna över vid den ursprungliga destinationen</string>\n    <string name=\"cannot_change_image_format\">Det går inte att ändra bildformat medan alternativet för överskrivning av filer är aktiverat</string>\n    <string name=\"emoji_as_color_scheme\">Emoji som färgschema</string>\n    <string name=\"emoji_as_color_scheme_sub\">Använder emoji primärfärg som appfärgschema istället för manuellt definierad</string>\n    <string name=\"material_you_sub\">Skapar material du palett från bild</string>\n    <string name=\"dark_colors\">Mörka färger</string>\n    <string name=\"dark_colors_sub\">Använder nattläges färgschema istället för ljusvariant</string>\n    <string name=\"copy_as_compose_code\">Kopiera som Jetpack Compose-kod</string>\n    <string name=\"ring_blur\">Ringoskärpa</string>\n    <string name=\"cross_blur\">Korsoskärpa</string>\n    <string name=\"circle_blur\">Cirkel oskärpa</string>\n    <string name=\"star_blur\">Stjärnoskärpa</string>\n    <string name=\"linear_tilt_shift\">Linjär Tilt-Shift</string>\n    <string name=\"tags_to_remove\">Taggar att ta bort</string>\n    <string name=\"apng_tools\">APNG-verktyg</string>\n    <string name=\"apng_tools_sub\">Konvertera bilder till APNG-bild eller extrahera ramar från given APNG-bild</string>\n    <string name=\"apng_type_to_image\">APNG till bilder</string>\n    <string name=\"apng_type_to_image_sub\">Konvertera APNG-fil till bildserie</string>\n    <string name=\"apng_type_to_apng_sub\">Konvertera parti bilder till APNG-fil</string>\n    <string name=\"apng_type_to_apng\">Bilder till APNG</string>\n    <string name=\"select_apng_image_to_start\">Välj APNG-bild för att starta</string>\n    <string name=\"motion_blur\">Rörelseoskärpa</string>\n    <string name=\"zip\">Blixtlås</string>\n    <string name=\"zip_sub\">Skapa zip-fil från givna filer eller bilder</string>\n    <string name=\"drag_handle_width\">Drahandtagsbredd</string>\n    <string name=\"confetti_type\">Typ av konfetti</string>\n    <string name=\"festive\">Festlig</string>\n    <string name=\"explode\">Explodera</string>\n    <string name=\"rain\">Regn</string>\n    <string name=\"corners\">Hörn</string>\n    <string name=\"jxl_tools\">JXL-verktyg</string>\n    <string name=\"jxl_tools_sub\">Utför JXL ~ JPEG-omkodning utan kvalitetsförlust, eller konvertera GIF/APNG till JXL-animation</string>\n    <string name=\"jxl_type_to_jpeg\">JXL till JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Utför förlustfri omkodning från JXL till JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Utför förlustfri omkodning från JPEG till JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG till JXL</string>\n    <string name=\"select_jxl_image_to_start\">Välj JXL-bild för att börja</string>\n    <string name=\"fast_gaussian_blur_2d\">Snabb Gaussisk oskärpa 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Snabb Gaussisk oskärpa 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Snabb Gaussisk oskärpa 4D</string>\n    <string name=\"auto_paste\">Bilpåsk</string>\n    <string name=\"auto_paste_sub\">Tillåter appen att automatiskt klistra in urklippsdata, så det kommer att visas på huvudskärmen och du kommer att kunna bearbeta det</string>\n    <string name=\"harmonization_color\">Harmoniseringsfärg</string>\n    <string name=\"harmonization_level\">Harmoniseringsnivå</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Omsamplingsmetod som upprätthåller interpolering av hög kvalitet genom att tillämpa en Bessel-funktion (jinc) på pixelvärdena</string>\n    <string name=\"gif_type_to_jxl\">GIF till JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Konvertera GIF-bilder till JXL-animerade bilder</string>\n    <string name=\"apng_type_to_jxl\">APNG till JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Konvertera APNG-bilder till JXL-animerade bilder</string>\n    <string name=\"jxl_type_to_images\">JXL till bilder</string>\n    <string name=\"jxl_type_to_images_sub\">Konvertera JXL-animation till en serie bilder</string>\n    <string name=\"jxl_type_to_jxl\">Bilder till JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Konvertera parti bilder till JXL-animation</string>\n    <string name=\"behavior\">Beteende</string>\n    <string name=\"skip_file_picking\">Hoppa över filval</string>\n    <string name=\"skip_file_picking_sub\">Filväljaren kommer att visas omedelbart om detta är möjligt på den valda skärmen</string>\n    <string name=\"generate_previews\">Skapa förhandsvisningar</string>\n    <string name=\"generate_previews_sub\">Aktiverar generering av förhandsgranskning, detta kan hjälpa till att undvika krascher på vissa enheter, detta inaktiverar också vissa redigeringsfunktioner inom ett enda redigeringsalternativ</string>\n    <string name=\"lossy_compression\">Förlustig kompression</string>\n    <string name=\"lossy_compression_sub\">Använder förlustfri komprimering för att minska filstorleken istället för förlustfri</string>\n    <string name=\"compression_type\">Kompressionstyp</string>\n    <string name=\"speed_sub\">Styr den resulterande bildavkodningshastigheten, detta bör hjälpa till att öppna den resulterande bilden snabbare, värdet %1$s betyder långsammaste avkodning, medan %2$s - snabbast, den här inställningen kan öka utdatabildens storlek</string>\n    <string name=\"sorting\">Sortering</string>\n    <string name=\"sort_by_date\">Datum</string>\n    <string name=\"sort_by_date_reversed\">Datum (omvänt)</string>\n    <string name=\"sort_by_name\">Namn</string>\n    <string name=\"sort_by_name_reversed\">Namn (omvänt)</string>\n    <string name=\"channels_configuration\">Kanalkonfiguration</string>\n    <string name=\"header_today\">I dag</string>\n    <string name=\"header_yesterday\">I går</string>\n    <string name=\"embedded_picker\">Inbäddad väljare</string>\n    <string name=\"embedded_picker_sub\">Image Toolboxs bildväljare</string>\n    <string name=\"no_permissions\">Inga behörigheter</string>\n    <string name=\"request\">Begäran</string>\n    <string name=\"pick_multiple_media\">Välj flera media</string>\n    <string name=\"pick_single_media\">Välj Single Media</string>\n    <string name=\"pick\">Plocka</string>\n    <string name=\"try_again\">Försök igen</string>\n    <string name=\"show_settings_in_landscape\">Visa inställningar i liggande</string>\n    <string name=\"show_settings_in_landscape_sub\">Om detta är inaktiverat kommer inställningarna i liggande läge att öppnas på knappen i övre appfältet som alltid, istället för permanent synligt alternativ</string>\n    <string name=\"fullscreen_settings\">Inställningar för helskärm</string>\n    <string name=\"fullscreen_settings_sub\">Aktivera det och inställningssidan kommer alltid att öppnas som helskärm istället för skjutbart lådblad</string>\n    <string name=\"switch_type\">Switch Typ</string>\n    <string name=\"compose\">Komponera</string>\n    <string name=\"compose_switch_sub\">Ett Jetpack Compose Material Du byter</string>\n    <string name=\"material_you_switch_sub\">Ett material du byter</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">Ändra storlek på ankare</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Flytande</string>\n    <string name=\"fluent_switch_sub\">En switch baserad på designsystemet \\\"Flytande\\\".</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">En switch baserad på designsystemet \\\"Cupertino\\\".</string>\n    <string name=\"images_to_svg\">Bilder till SVG</string>\n    <string name=\"images_to_svg_sub\">Spåra givna bilder till SVG-bilder</string>\n    <string name=\"use_sampled_palette\">Använd Sampled Palette</string>\n    <string name=\"use_sampled_palette_sub\">Kvantiseringspalett kommer att samplas om detta alternativ är aktiverat</string>\n    <string name=\"path_omit\">Väg utelämna</string>\n    <string name=\"svg_warning\">Användning av detta verktyg för att spåra stora bilder utan nedskalning rekommenderas inte, det kan orsaka kraschar och öka bearbetningstiden</string>\n    <string name=\"downscale_image\">Nedskalad bild</string>\n    <string name=\"downscale_image_sub\">Bilden kommer att skalas ner till lägre dimensioner innan bearbetning, detta hjälper verktyget att arbeta snabbare och säkrare</string>\n    <string name=\"min_color_ratio\">Minsta färgförhållande</string>\n    <string name=\"lines_threshold\">Linjer Tröskel</string>\n    <string name=\"quadratic_threshold\">Kvadratisk tröskel</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordinater avrundningstolerans</string>\n    <string name=\"path_scale\">Path Skala</string>\n    <string name=\"reset_properties\">Återställ egenskaper</string>\n    <string name=\"reset_properties_sub\">Alla egenskaper kommer att ställas in på standardvärden. Observera att denna åtgärd inte kan ångras</string>\n    <string name=\"detailed\">Detaljerad</string>\n    <string name=\"default_line_width\">Standardlinjebredd</string>\n    <string name=\"engine_mode\">Motorläge</string>\n    <string name=\"legacy\">Arv</string>\n    <string name=\"lstm_network\">LSTM-nätverk</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp;amp; LSTM</string>\n    <string name=\"convert\">Konvertera</string>\n    <string name=\"convert_sub\">Konvertera bildsatser till givet format</string>\n    <string name=\"add_new_folder\">Lägg till ny mapp</string>\n    <string name=\"tag_bits_per_sample\">Bitar per prov</string>\n    <string name=\"tag_compression\">Kompression</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrisk tolkning</string>\n    <string name=\"tag_samples_per_pixel\">Prover per pixel</string>\n    <string name=\"tag_planar_configuration\">Plan konfiguration</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Subsampling</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Positionering</string>\n    <string name=\"tag_x_resolution\">X Upplösning</string>\n    <string name=\"tag_y_resolution\">Y Upplösning</string>\n    <string name=\"tag_resolution_unit\">Upplösningsenhet</string>\n    <string name=\"tag_strip_offsets\">Strip Offsets</string>\n    <string name=\"tag_rows_per_strip\">Rader per remsa</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG Interchange Format</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG Interchange Format Längd</string>\n    <string name=\"tag_transfer_function\">Överföringsfunktion</string>\n    <string name=\"tag_white_point\">Vit punkt</string>\n    <string name=\"tag_primary_chromaticities\">Primär kromaticitet</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr-koefficienter</string>\n    <string name=\"tag_reference_black_white\">Referens Svart Vit</string>\n    <string name=\"tag_datetime\">Datum Tid</string>\n    <string name=\"tag_image_description\">Bildbeskrivning</string>\n    <string name=\"tag_make\">Göra</string>\n    <string name=\"tag_model\">Modell</string>\n    <string name=\"tag_software\">Programvara</string>\n    <string name=\"tag_artist\">Konstnär</string>\n    <string name=\"tag_copyright\">Upphovsrätt</string>\n    <string name=\"tag_exif_version\">Exif-version</string>\n    <string name=\"tag_flashpix_version\">Flashpix version</string>\n    <string name=\"tag_color_space\">Färgrymd</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X Dimension</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y-dimension</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Komprimerade bitar per pixel</string>\n    <string name=\"tag_maker_note\">Maker Note</string>\n    <string name=\"tag_user_comment\">Användarkommentar</string>\n    <string name=\"tag_related_sound_file\">Relaterad ljudfil</string>\n    <string name=\"tag_datetime_original\">Datum Tid Original</string>\n    <string name=\"tag_datetime_digitized\">Datum Tid Digitaliserad</string>\n    <string name=\"tag_offset_time\">Offsettid</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Offsettid digitaliserad</string>\n    <string name=\"tag_subsec_time\">Undersekundstid</string>\n    <string name=\"tag_subsec_time_original\">Undersek. Tid Original</string>\n    <string name=\"tag_subsec_time_digitized\">Undersek. Tid Digitaliserad</string>\n    <string name=\"tag_exposure_time\">Exponeringstid</string>\n    <string name=\"tag_f_number\">F-nummer</string>\n    <string name=\"tag_exposure_program\">Exponeringsprogram</string>\n    <string name=\"tag_spectral_sensitivity\">Spektral känslighet</string>\n    <string name=\"tag_photographic_sensitivity\">Fotografisk känslighet</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">Känslighetstyp</string>\n    <string name=\"tag_standard_output_sensitivity\">Standardutgångskänslighet</string>\n    <string name=\"tag_recommended_exposure_index\">Rekommenderat exponeringsindex</string>\n    <string name=\"tag_iso_speed\">ISO-hastighet</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Speed ​​Latitude ååå</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Speed ​​Latitude zzz</string>\n    <string name=\"tag_shutter_speed_value\">Slutarhastighetsvärde</string>\n    <string name=\"tag_aperture_value\">Bländarvärde</string>\n    <string name=\"tag_brightness_value\">Ljusstyrka värde</string>\n    <string name=\"tag_exposure_bias_value\">Exponeringsbiasvärde</string>\n    <string name=\"tag_max_aperture_value\">Max bländarvärde</string>\n    <string name=\"tag_subject_distance\">Ämnesavstånd</string>\n    <string name=\"tag_metering_mode\">Mätläge</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Ämnesområde</string>\n    <string name=\"tag_focal_length\">Brännvidd</string>\n    <string name=\"tag_flash_energy\">Flash energi</string>\n    <string name=\"tag_spatial_frequency_response\">Spatial Frequency Response</string>\n    <string name=\"tag_focal_plane_x_resolution\">Focal Plane X-upplösning</string>\n    <string name=\"tag_focal_plane_y_resolution\">Fokalplan Y-upplösning</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Focal Plane Resolution Unit</string>\n    <string name=\"tag_subject_location\">Ämnesplats</string>\n    <string name=\"tag_exposure_index\">Exponeringsindex</string>\n    <string name=\"tag_sensing_method\">Avkänningsmetod</string>\n    <string name=\"tag_file_source\">Filkälla</string>\n    <string name=\"tag_cfa_pattern\">CFA-mönster</string>\n    <string name=\"tag_custom_rendered\">Custom Rendered</string>\n    <string name=\"tag_exposure_mode\">Exponeringsläge</string>\n    <string name=\"tag_white_balance\">Vitbalans</string>\n    <string name=\"tag_digital_zoom_ratio\">Digitalt zoomförhållande</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Brännvidd i 35 mm film</string>\n    <string name=\"tag_scene_capture_type\">Sceninspelningstyp</string>\n    <string name=\"tag_gain_control\">Få kontroll</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"tag_saturation\">Mättnad</string>\n    <string name=\"tag_sharpness\">Skärpa</string>\n    <string name=\"tag_device_setting_description\">Beskrivning av enhetsinställning</string>\n    <string name=\"tag_subject_distance_range\">Ämnesavståndsområde</string>\n    <string name=\"tag_image_unique_id\">Bild unikt ID</string>\n    <string name=\"tag_camera_owner_name\">Kameraägarens namn</string>\n    <string name=\"tag_body_serial_number\">Kroppens serienummer</string>\n    <string name=\"tag_lens_specification\">Objektivspecifikation</string>\n    <string name=\"tag_lens_make\">Objektivfabrikat</string>\n    <string name=\"tag_lens_model\">Objektivmodell</string>\n    <string name=\"tag_lens_serial_number\">Linsens serienummer</string>\n    <string name=\"tag_gps_version_id\">GPS-versions-ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS-latitud</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Longitud Ref</string>\n    <string name=\"tag_gps_longitude\">GPS Longitud</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Höjd Ref</string>\n    <string name=\"tag_gps_altitude\">GPS-höjd</string>\n    <string name=\"tag_gps_timestamp\">GPS tidsstämpel</string>\n    <string name=\"tag_gps_satellites\">GPS-satelliter</string>\n    <string name=\"tag_gps_status\">GPS-status</string>\n    <string name=\"tag_gps_measure_mode\">GPS-mätläge</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS-hastighet Ref</string>\n    <string name=\"tag_gps_speed\">GPS-hastighet</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS-spår</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img Riktning Ref</string>\n    <string name=\"tag_gps_img_direction\">GPS-bildriktning</string>\n    <string name=\"tag_gps_map_datum\">GPS-karta datum</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitud Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Longitud</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS Dest Distance</string>\n    <string name=\"tag_gps_processing_method\">GPS-bearbetningsmetod</string>\n    <string name=\"tag_gps_area_information\">GPS-områdesinformation</string>\n    <string name=\"tag_gps_datestamp\">GPS datumstämpel</string>\n    <string name=\"tag_gps_differential\">GPS-differential</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H-positioneringsfel</string>\n    <string name=\"tag_interoperability_index\">Interoperabilitetsindex</string>\n    <string name=\"tag_dng_version\">DNG-version</string>\n    <string name=\"tag_default_crop_size\">Standard beskärningsstorlek</string>\n    <string name=\"tag_orf_preview_image_start\">Förhandsgranska bild Start</string>\n    <string name=\"tag_orf_preview_image_length\">Förhandsgranska bildlängd</string>\n    <string name=\"tag_orf_aspect_frame\">Aspektram</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Sensor bottenkant</string>\n    <string name=\"tag_rw2_sensor_left_border\">Sensor vänster kant</string>\n    <string name=\"tag_rw2_sensor_right_border\">Sensor höger kant</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sensor övre kant</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Rita text på banan med angivet teckensnitt och färg</string>\n    <string name=\"font_size\">Fontstorlek</string>\n    <string name=\"watermark_size\">Vattenstämpel storlek</string>\n    <string name=\"repeat_text\">Upprepa text</string>\n    <string name=\"repeat_text_sub\">Aktuell text kommer att upprepas tills sökvägen slutar istället för att rita en gång</string>\n    <string name=\"dash_size\">Dash storlek</string>\n    <string name=\"draw_mode_image_sub\">Använd den valda bilden för att rita den längs en given bana</string>\n    <string name=\"draw_image_sub\">Denna bild kommer att användas som upprepad inmatning av ritad bana</string>\n    <string name=\"outlined_triangle_sub\">Ritar en triangel med kontur från startpunkt till slutpunkt</string>\n    <string name=\"triangle_sub\">Ritar en triangel med kontur från startpunkt till slutpunkt</string>\n    <string name=\"outlined_triangle\">Konturerad triangel</string>\n    <string name=\"triangle\">Triangel</string>\n    <string name=\"polygon_sub\">Ritar polygon från startpunkt till slutpunkt</string>\n    <string name=\"polygon\">Polygon</string>\n    <string name=\"outlined_polygon\">Konturerad polygon</string>\n    <string name=\"outlined_polygon_sub\">Ritar polygon med kontur från startpunkt till slutpunkt</string>\n    <string name=\"vertices\">Vertices</string>\n    <string name=\"draw_regular_polygon\">Rita vanlig polygon</string>\n    <string name=\"draw_regular_polygon_sub\">Rita polygon som kommer att vara regelbunden istället för fri form</string>\n    <string name=\"star_sub\">Ritar stjärna från startpunkt till slutpunkt</string>\n    <string name=\"star\">Stjärna</string>\n    <string name=\"outlined_star\">Konturerad stjärna</string>\n    <string name=\"outlined_star_sub\">Ritar konturstjärna från startpunkt till slutpunkt</string>\n    <string name=\"inner_radius_ratio\">Inre radieförhållande</string>\n    <string name=\"draw_regular_star\">Rita vanlig stjärna</string>\n    <string name=\"draw_regular_star_sub\">Rita stjärna som kommer att vara vanlig istället för fri form</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">Möjliggör kantutjämning för att förhindra skarpa kanter</string>\n    <string name=\"open_edit_instead_of_preview\">Öppna Redigera istället för förhandsgranskning</string>\n    <string name=\"open_edit_instead_of_preview_sub\">När du väljer bild som ska öppnas (förhandsgranska) i ImageToolbox öppnas redigera urvalsark istället för att förhandsgranska</string>\n    <string name=\"document_scanner\">Dokumentskanner</string>\n    <string name=\"document_scanner_sub\">Skanna dokument och skapa PDF eller separera bilder från dem</string>\n    <string name=\"click_to_start_scanning\">Klicka för att börja skanna</string>\n    <string name=\"start_scanning\">Börja skanna</string>\n    <string name=\"save_as_pdf\">Spara som pdf</string>\n    <string name=\"share_as_pdf\">Dela som pdf</string>\n    <string name=\"options_below_is_for_images\">Alternativen nedan är för att spara bilder, inte PDF</string>\n    <string name=\"equalize_histogram_hsv\">Utjämna Histogram HSV</string>\n    <string name=\"equalize_histogram\">Utjämna histogram</string>\n    <string name=\"enter_percentage\">Ange procent</string>\n    <string name=\"allow_enter_by_text_field\">Tillåt inträde via textfält</string>\n    <string name=\"allow_enter_by_text_field_sub\">Aktiverar textfält bakom val av förinställningar, för att ange dem i farten</string>\n    <string name=\"scale_color_space\">Skala färgrymd</string>\n    <string name=\"linear\">Linjär</string>\n    <string name=\"equalize_histogram_pixelation\">Utjämna histogrampixelering</string>\n    <string name=\"grid_size_x\">Rutnätsstorlek X</string>\n    <string name=\"grid_size_y\">Rutnätsstorlek Y</string>\n    <string name=\"equalize_histogram_adaptive\">Utjämna Histogram Adaptive</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Utjämna Histogram Adaptive LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Utjämna Histogram Adaptive LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Beskär till innehåll</string>\n    <string name=\"frame_color\">Ram färg</string>\n    <string name=\"color_to_ignore\">Färg att ignorera</string>\n    <string name=\"template\">Mall</string>\n    <string name=\"no_template_filters\">Inga mallfilter har lagts till</string>\n    <string name=\"create_new\">Skapa nytt</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Den skannade QR-koden är inte en giltig filtermall</string>\n    <string name=\"scan_qr_code\">Skanna QR-koden</string>\n    <string name=\"opened_file_have_no_filter_template\">Den valda filen har inga filtermallsdata</string>\n    <string name=\"create_template\">Skapa mall</string>\n    <string name=\"template_name\">Mallnamn</string>\n    <string name=\"select_template_preview\">Den här bilden kommer att användas för att förhandsgranska filtermallen</string>\n    <string name=\"template_filter\">Mallfilter</string>\n    <string name=\"as_qr_code\">Som QR-kodbild</string>\n    <string name=\"as_file\">Som fil</string>\n    <string name=\"save_as_file\">Spara som fil</string>\n    <string name=\"save_as_qr_code_image\">Spara som QR-kodbild</string>\n    <string name=\"delete_template\">Ta bort mall</string>\n    <string name=\"delete_template_warn\">Du håller på att ta bort valt mallfilter. Denna operation kan inte ångras</string>\n    <string name=\"added_filter_template\">Lade till filtermall med namnet \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Förhandsgranska filter</string>\n    <string name=\"qr_code\">QR &amp;amp; streckkod</string>\n    <string name=\"qr_code_sub\">Skanna QR-koden och få dess innehåll eller klistra in din sträng för att skapa en ny</string>\n    <string name=\"code_content\">Kodinnehåll</string>\n    <string name=\"scan_qr_code_to_replace_content\">Skanna valfri streckkod för att ersätta innehållet i fältet, eller skriv något för att generera ny streckkod med vald typ</string>\n    <string name=\"qr_description\">QR Beskrivning</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Ge kameratillstånd i inställningarna för att skanna QR-kod</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Ge kameratillstånd i inställningarna för att skanna dokumentskanner</string>\n    <string name=\"cubic\">Kubisk</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussisk</string>\n    <string name=\"sphinx\">Sfinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Låda</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kubisk interpolering ger jämnare skalning genom att beakta de närmaste 16 pixlarna, vilket ger bättre resultat än bilinjär</string>\n    <string name=\"bspline_sub\">Använder bitvis definierade polynomfunktioner för att smidigt interpolera och approximera en kurva eller yta, flexibel och kontinuerlig formrepresentation</string>\n    <string name=\"hamming_sub\">En fönsterfunktion som används för att minska spektralläckage genom att avsmalna kanterna på en signal, användbar vid signalbehandling</string>\n    <string name=\"hanning_sub\">En variant av Hann-fönstret, som vanligtvis används för att minska spektralläckage i signalbehandlingsapplikationer</string>\n    <string name=\"blackman_sub\">En fönsterfunktion som ger bra frekvensupplösning genom att minimera spektralläckage, som ofta används vid signalbehandling</string>\n    <string name=\"welch_sub\">En fönsterfunktion designad för att ge bra frekvensupplösning med minskat spektralläckage, ofta använd i signalbehandlingsapplikationer</string>\n    <string name=\"quadric_sub\">En metod som använder en kvadratisk funktion för interpolation, vilket ger jämna och kontinuerliga resultat</string>\n    <string name=\"gaussian_sub\">En interpolationsmetod som använder en Gaussisk funktion, användbar för att jämna ut och minska brus i bilder</string>\n    <string name=\"sphinx_sub\">En avancerad omsamplingsmetod som ger högkvalitativ interpolering med minimala artefakter</string>\n    <string name=\"bartlett_sub\">En triangulär fönsterfunktion som används vid signalbehandling för att minska spektralläckage</string>\n    <string name=\"robidoux_sub\">En högkvalitativ interpolationsmetod optimerad för naturlig bildstorlek, balansering av skärpa och jämnhet</string>\n    <string name=\"robidoux_sharp_sub\">En skarpare variant av Robidoux-metoden, optimerad för skarp bildstorlek</string>\n    <string name=\"spline16_sub\">En spline-baserad interpolationsmetod som ger jämna resultat med ett 16-tapps filter</string>\n    <string name=\"spline36_sub\">En spline-baserad interpolationsmetod som ger jämna resultat med ett 36-tapps filter</string>\n    <string name=\"spline64_sub\">En spline-baserad interpolationsmetod som ger jämna resultat med ett 64-tapps filter</string>\n    <string name=\"kaiser_sub\">En interpolationsmetod som använder Kaiser-fönstret, vilket ger god kontroll över avvägningen mellan huvudlobens bredd och sidolobsnivån</string>\n    <string name=\"bartlett_hann_sub\">En hybridfönsterfunktion som kombinerar Bartlett- och Hann-fönstren, som används för att minska spektralläckage i signalbehandling</string>\n    <string name=\"box_sub\">En enkel omsamplingsmetod som använder genomsnittet av de närmaste pixelvärdena, vilket ofta resulterar i ett blockigt utseende</string>\n    <string name=\"bohman_sub\">En fönsterfunktion som används för att minska spektralt läckage, vilket ger bra frekvensupplösning i signalbehandlingsapplikationer</string>\n    <string name=\"lanczos2_sub\">En omsamplingsmetod som använder ett 2-lobs Lanczos-filter för högkvalitativ interpolering med minimala artefakter</string>\n    <string name=\"lanczos3_sub\">En omsamplingsmetod som använder ett 3-lobs Lanczos-filter för högkvalitativ interpolering med minimala artefakter</string>\n    <string name=\"lanczos4_sub\">En omsamplingsmetod som använder ett 4-lobs Lanczos-filter för högkvalitativ interpolering med minimala artefakter</string>\n    <string name=\"lanczos2_jinc_sub\">En variant av Lanczos 2-filtret som använder jinc-funktionen, ger högkvalitativ interpolering med minimala artefakter</string>\n    <string name=\"lanczos3_jinc_sub\">En variant av Lanczos 3-filtret som använder jinc-funktionen, vilket ger högkvalitativ interpolering med minimala artefakter</string>\n    <string name=\"lanczos4_jinc_sub\">En variant av Lanczos 4-filtret som använder jinc-funktionen, ger högkvalitativ interpolering med minimala artefakter</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Elliptical Weighted Average (EWA) variant av Hanning-filtret för smidig interpolering och omsampling</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elliptical Weighted Average (EWA) variant av Robidoux-filtret för högkvalitativ omsampling</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">Elliptical Weighted Average (EWA) variant av Blackman-filtret för att minimera ringsignalsartefakter</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">Elliptical Weighted Average (EWA) variant av Quadric-filtret för smidig interpolation</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Elliptical Weighted Average (EWA) variant av Robidoux Sharp-filtret för skarpare resultat</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Elliptical Weighted Average (EWA) variant av Lanczos 3 Jinc-filtret för högkvalitativ omsampling med reducerad aliasing</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Ett omsamplingsfilter designat för högkvalitativ bildbehandling med en bra balans mellan skärpa och jämnhet</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Elliptical Weighted Average (EWA) variant av ginsengfiltret för förbättrad bildkvalitet</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Elliptical Weighted Average (EWA) variant av Lanczos Sharp-filtret för att uppnå skarpa resultat med minimala artefakter</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Elliptical Weighted Average (EWA) variant av Lanczos 4 Sharpest-filtret för extremt skarp omsampling av bilder</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Elliptical Weighted Average (EWA) variant av Lanczos Soft-filtret för jämnare bildomsampling</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Ett omsamplingsfilter designat av Haasn för jämn och artefaktfri bildskalning</string>\n    <string name=\"format_conversion\">Formatkonvertering</string>\n    <string name=\"format_conversion_sub\">Konvertera partier av bilder från ett format till ett annat</string>\n    <string name=\"dismiss_forever\">Avvisa för alltid</string>\n    <string name=\"image_stacking\">Bildstapling</string>\n    <string name=\"image_stacking_sub\">Stapla bilder ovanpå varandra med valda blandningslägen</string>\n    <string name=\"add_image\">Lägg till bild</string>\n    <string name=\"bins_count\">Papperskorgar räknas</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Utjämna Histogram Adaptive HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Utjämna Histogram Adaptive HSV</string>\n    <string name=\"edge_mode\">Kantläge</string>\n    <string name=\"clip\">Klämma</string>\n    <string name=\"wrap\">Sjal</string>\n    <string name=\"color_blind_scheme\">Färgblindhet</string>\n    <string name=\"color_blind_scheme_sub\">Välj läge för att anpassa temafärger för den valda färgblindhetsvarianten</string>\n    <string name=\"protanomaly_sub\">Svårt att skilja mellan röda och gröna nyanser</string>\n    <string name=\"deuteranomaly_sub\">Svårt att skilja mellan gröna och röda nyanser</string>\n    <string name=\"tritanomaly_sub\">Svårt att skilja mellan blå och gula nyanser</string>\n    <string name=\"protanopia_sub\">Oförmåga att uppfatta röda nyanser</string>\n    <string name=\"deuteranopia_sub\">Oförmåga att uppfatta gröna nyanser</string>\n    <string name=\"tritanopia_sub\">Oförmåga att uppfatta blå nyanser</string>\n    <string name=\"achromatomaly_sub\">Minskad känslighet för alla färger</string>\n    <string name=\"achromatopsia_sub\">Fullständig färgblindhet, ser bara nyanser av grått</string>\n    <string name=\"not_use_color_blind_scheme\">Använd inte färgblindschema</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Färgerna kommer att vara exakt som inställda i temat</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Ett Lagrange-interpolationsfilter av ordning 2, lämpligt för högkvalitativ bildskalning med mjuka övergångar</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Ett Lagrange-interpolationsfilter av ordning 3, erbjuder bättre noggrannhet och jämnare resultat för bildskalning</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Ett Lanczos omsamplingsfilter med en högre ordning på 6, vilket ger skarpare och mer exakt bildskalning</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">En variant av Lanczos 6-filtret som använder en Jinc-funktion för förbättrad bildomsamplingskvalitet</string>\n    <string name=\"linear_box_blur\">Linjär Box oskärpa</string>\n    <string name=\"linear_tent_blur\">Linjär tältskärpa</string>\n    <string name=\"linear_gaussian_box_blur\">Linjär Gaussisk Box oskärpa</string>\n    <string name=\"linear_stack_blur\">Linjär stackoskärpa</string>\n    <string name=\"gaussian_box_blur\">Gaussisk boxoskärpa</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linjär Snabb Gaussisk oskärpa Nästa</string>\n    <string name=\"linear_fast_gaussian_blur\">Linjär snabb Gaussisk oskärpa</string>\n    <string name=\"linear_gaussian_blur\">Linjär Gaussisk oskärpa</string>\n    <string name=\"draw_filter_sub\">Välj ett filter för att använda det som färg</string>\n    <string name=\"replace_filter\">Byt ut filter</string>\n    <string name=\"pick_filter_info\">Välj filter nedan för att använda det som pensel i din ritning</string>\n    <string name=\"tiff_compression_scheme\">TIFF-komprimeringsschema</string>\n    <string name=\"low_poly\">Låg poly</string>\n    <string name=\"sand_painting\">Sandmålning</string>\n    <string name=\"image_splitting\">Bilddelning</string>\n    <string name=\"image_splitting_sub\">Dela en bild efter rader eller kolumner</string>\n    <string name=\"fit_to_bounds\">Fit To Bounds</string>\n    <string name=\"fit_to_bounds_sub\">Kombinera läget för beskärningsändring med denna parameter för att uppnå önskat beteende (Beskär/Anpassa till bildförhållande)</string>\n    <string name=\"languages_imported\">Språk har importerats</string>\n    <string name=\"backup_ocr_models\">Backup OCR-modeller</string>\n    <string name=\"import_word\">Importera</string>\n    <string name=\"export\">Exportera</string>\n    <string name=\"position\">Placera</string>\n    <string name=\"center\">Centrum</string>\n    <string name=\"top_left\">Överst till vänster</string>\n    <string name=\"top_right\">Överst till höger</string>\n    <string name=\"bottom_left\">Nederst till vänster</string>\n    <string name=\"bottom_right\">Nederst till höger</string>\n    <string name=\"top_center\">Top Center</string>\n    <string name=\"center_right\">Mitten höger</string>\n    <string name=\"bottom_center\">Nedre mitten</string>\n    <string name=\"center_left\">Mitten vänster</string>\n    <string name=\"target_image\">Målbild</string>\n    <string name=\"palette_transfer\">Palettöverföring</string>\n    <string name=\"enhanced_oil\">Förbättrad olja</string>\n    <string name=\"simple_old_tv\">Enkel gammal TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Enkel skiss</string>\n    <string name=\"soft_glow\">Mjuk glöd</string>\n    <string name=\"color_poster\">Färg affisch</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">Tredje färgen</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Clustered 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Clustered 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">Clustered 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">Inga favoritalternativ har valts, lägg till dem på verktygssidan</string>\n    <string name=\"add_favorites\">Lägg till favoriter</string>\n    <string name=\"harmony_complementary\">Komplementär</string>\n    <string name=\"harmony_analogous\">Analog</string>\n    <string name=\"harmony_triadic\">Triadisk</string>\n    <string name=\"harmony_split_complementary\">Dela Kompletterande</string>\n    <string name=\"harmony_tetradic\">Tetradisk</string>\n    <string name=\"harmony_square\">Fyrkant</string>\n    <string name=\"harmony_analogous_complementary\">Analog + Komplementär</string>\n    <string name=\"color_tools\">Färgverktyg</string>\n    <string name=\"color_tools_sub\">Mixa, skapa toner, generera nyanser och mer</string>\n    <string name=\"color_harmonies\">Färgharmonier</string>\n    <string name=\"color_shading\">Färgskuggning</string>\n    <string name=\"variation\">Variation</string>\n    <string name=\"tints\">Nyanser</string>\n    <string name=\"tones\">Toner</string>\n    <string name=\"shades\">Nyanser</string>\n    <string name=\"color_mixing\">Färgblandning</string>\n    <string name=\"color_info\">Färginformation</string>\n    <string name=\"selected_color\">Vald färg</string>\n    <string name=\"color_to_mix\">Färg att blanda</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Det går inte att använda monet när dynamiska färger är aktiverade</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Mål LUT-bild</string>\n    <string name=\"amatorka\">Amatör</string>\n    <string name=\"miss_etikate\">Fröken Etikett</string>\n    <string name=\"soft_elegance\">Mjuk elegans</string>\n    <string name=\"soft_elegance_variant\">Mjuk elegansvariant</string>\n    <string name=\"palette_transfer_variant\">Palettöverföringsvariant</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Mål 3D LUT-fil (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">Levande ljus</string>\n    <string name=\"drop_blues\">Drop Blues</string>\n    <string name=\"edgy_amber\">Edgy Amber</string>\n    <string name=\"fall_colors\">Höstfärger</string>\n    <string name=\"film_stock_50\">Filmlager 50</string>\n    <string name=\"foggy_night\">Dimmig natt</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Få neutral LUT-bild</string>\n    <string name=\"save_empty_lut_sub\">Använd först ditt favoritprogram för fotoredigering för att tillämpa ett filter på neutral LUT som du kan få här. För att detta ska fungera korrekt får varje pixelfärg inte bero på andra pixlar (t.ex. oskärpa fungerar inte). När du är klar använder du din nya LUT-bild som indata för 512*512 LUT-filter</string>\n    <string name=\"pop_art\">Popkonst</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"coffee\">Kaffe</string>\n    <string name=\"golden_forest\">Gyllene skogen</string>\n    <string name=\"greenish\">Grönaktig</string>\n    <string name=\"retro_yellow\">Retro gul</string>\n    <string name=\"links_preview\">Förhandsgranskning av länkar</string>\n    <string name=\"links_preview_sub\">Möjliggör länkförhandsvisning på platser där du kan hämta text (QRCode, OCR etc)</string>\n    <string name=\"links\">Länkar</string>\n    <string name=\"ico_size_warning\">ICO-filer kan endast sparas med en maximal storlek på 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF till WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Konvertera GIF-bilder till WEBP-animerade bilder</string>\n    <string name=\"webp_tools\">WEBP-verktyg</string>\n    <string name=\"webp_tools_sub\">Konvertera bilder till WEBP-animerade bilder eller extrahera ramar från given WEBP-animation</string>\n    <string name=\"webp_type_to_image\">WEBP till bilder</string>\n    <string name=\"webp_type_to_image_sub\">Konvertera WEBP-fil till bildserie</string>\n    <string name=\"webp_type_to_webp_sub\">Konvertera parti bilder till WEBP-fil</string>\n    <string name=\"webp_type_to_webp\">Bilder till WEBP</string>\n    <string name=\"select_webp_image_to_start\">Välj WEBP-bild för att starta</string>\n    <string name=\"manage_storage_extra_types\">Ingen fullständig åtkomst till filer</string>\n    <string name=\"manage_storage_extra_types_sub\">Tillåt alla filer åtkomst för att se JXL, QOI och andra bilder som inte känns igen som bilder på Android. Utan tillstånd kan Image Toolbox inte visa dessa bilder</string>\n    <string name=\"default_draw_color\">Standard ritfärg</string>\n    <string name=\"default_draw_path_mode\">Standardläge för ritningsväg</string>\n    <string name=\"add_timestamp\">Lägg till tidsstämpel</string>\n    <string name=\"add_timestamp_sub\">Aktiverar tidsstämpel tillägg till utdatafilnamnet</string>\n    <string name=\"formatted_timestamp\">Formaterad tidsstämpel</string>\n    <string name=\"formatted_timestamp_sub\">Aktivera tidsstämpelformatering i utdatafilnamn istället för grundläggande millis</string>\n    <string name=\"enable_timestamps_to_format_them\">Aktivera tidsstämplar för att välja format</string>\n    <string name=\"one_time_save_location\">Engångsspara plats</string>\n    <string name=\"one_time_save_location_sub\">Visa och redigera engångssparplatser som du kan använda genom att trycka länge på spara-knappen i de flesta alternativ</string>\n    <string name=\"recently_used\">Nyligen använd</string>\n    <string name=\"ci_channel\">CI-kanal</string>\n    <string name=\"group\">Grupp</string>\n    <string name=\"image_toolbox_in_telegram\">Bildverktygslåda i Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Gå med i vår chatt där du kan diskutera vad du vill och titta även in på CI-kanalen där jag lägger upp betaversioner och tillkännagivanden</string>\n    <string name=\"ci_channel_sub\">Få aviseringar om nya versioner av appen och läs meddelanden</string>\n    <string name=\"fit_description\">Anpassa en bild till givna mått och applicera oskärpa eller färg på bakgrunden</string>\n    <string name=\"tools_arrangement\">Verktygsarrangemang</string>\n    <string name=\"group_tools_by_type\">Gruppera verktyg efter typ</string>\n    <string name=\"group_tools_by_type_sub\">Grupperar verktyg på huvudskärmen efter deras typ istället för ett anpassat listarrangemang</string>\n    <string name=\"default_values\">Standardvärden</string>\n    <string name=\"system_bars_visibility\">Systembars synlighet</string>\n    <string name=\"show_system_bars_by_swipe\">Visa systemfält genom att svepa</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Aktiverar svepning för att visa systemfält om de är dolda</string>\n    <string name=\"auto\">Bil</string>\n    <string name=\"hide_all\">Göm alla</string>\n    <string name=\"show_all\">Visa alla</string>\n    <string name=\"hide_nav_bar\">Dölj navigeringsfältet</string>\n    <string name=\"hide_status_bar\">Dölj statusfältet</string>\n    <string name=\"noise_generation\">Bullergenerering</string>\n    <string name=\"noise_generation_sub\">Generera olika ljud som Perlin eller andra typer</string>\n    <string name=\"frequency\">Frekvens</string>\n    <string name=\"noise_type\">Bullertyp</string>\n    <string name=\"rotation_type\">Rotationstyp</string>\n    <string name=\"fractal_type\">Fraktal typ</string>\n    <string name=\"octaves\">Oktaver</string>\n    <string name=\"lacunarity\">Lacunaritet</string>\n    <string name=\"gain\">Få</string>\n    <string name=\"weighted_strength\">Viktad styrka</string>\n    <string name=\"ping_pong_strength\">Ping Pong Styrka</string>\n    <string name=\"distance_function\">Avståndsfunktion</string>\n    <string name=\"return_type\">Returtyp</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domän Warp</string>\n    <string name=\"alignment\">Inriktning</string>\n    <string name=\"custom_filename\">Anpassat filnamn</string>\n    <string name=\"custom_filename_sub\">Välj plats och filnamn som ska användas för att spara aktuell bild</string>\n    <string name=\"saved_to_custom\">Sparad i mapp med anpassat namn</string>\n    <string name=\"collage_maker\">Collage Maker</string>\n    <string name=\"collage_maker_sub\">Gör collage av upp till 20 bilder</string>\n    <string name=\"collage_type\">Collage typ</string>\n    <string name=\"collages_info\">Håll bilden för att byta, flytta och zooma för att justera position</string>\n    <string name=\"disable_rotation\">Inaktivera rotation</string>\n    <string name=\"disable_rotation_sub\">Förhindrar roterande bilder med tvåfingergester</string>\n    <string name=\"enable_snapping_to_borders\">Aktivera fästning till gränser</string>\n    <string name=\"histogram_sub\">RGB eller Ljusstyrka bildhistogram för att hjälpa dig att göra justeringar</string>\n    <string name=\"top_hat\">Hög hatt</string>\n    <string name=\"defaultt_sub\">Bara standard raka linjer</string>\n    <string name=\"crossfade_count\">Crossfade-ramar räknas</string>\n    <string name=\"compact_selectors_sub\">Vissa valkontroller använder en kompakt layout för att ta mindre plats</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Ge kameratillstånd i inställningarna för att ta bild</string>\n    <string name=\"layout\">Layout</string>\n    <string name=\"main_screen_title\">Huvudskärmens titel</string>\n    <string name=\"constant_rate_factor\">Konstant hastighetsfaktor (CRF)</string>\n    <string name=\"crf_sub\">Ett värde på %1$s betyder en långsam komprimering, vilket resulterar i en relativt liten filstorlek. %2$s betyder en snabbare komprimering, vilket resulterar i en stor fil.</string>\n    <string name=\"lut_library\">Lut bibliotek</string>\n    <string name=\"lut_library_sub\">Ladda ner samling av LUT, som du kan använda efter nedladdning</string>\n    <string name=\"lut_library_update_sub\">Uppdatera samling av LUT:er (endast nya kommer att stå i kö), som du kan använda efter nedladdning</string>\n    <string name=\"filter_preview_image_sub\">Ändra standardbildförhandsvisning för filter</string>\n    <string name=\"filter_preview_image\">Förhandsgranska bild</string>\n    <string name=\"hide\">Dölja</string>\n    <string name=\"show\">Visa</string>\n    <string name=\"slider_type\">Slider Typ</string>\n    <string name=\"fancy\">Lust</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy_sub\">En snygg reglage. Detta är standardalternativet</string>\n    <string name=\"material_2_sub\">Ett material 2-reglage</string>\n    <string name=\"material_you_slider_sub\">Ett material du reglage</string>\n    <string name=\"apply\">Tillämpas</string>\n    <string name=\"center_align_dialog_buttons\">Center dialogknappar</string>\n    <string name=\"center_align_dialog_buttons_sub\">Knappar för dialogrutor kommer att placeras i mitten istället för på vänster sida om möjligt</string>\n    <string name=\"open_source_licenses\">Licenser med öppen källkod</string>\n    <string name=\"open_source_licenses_sub\">Visa licenser för bibliotek med öppen källkod som används i den här appen</string>\n    <string name=\"area\">Område</string>\n    <string name=\"area_sub\">Omsampling med hjälp av pixelarearelation. Det kan vara en föredragen metod för bilddecimering, eftersom det ger moaréfria resultat. Men när bilden är zoomad liknar den metoden \\\"Närmast\\\".</string>\n    <string name=\"enable_tonemapping\">Aktivera tonmappning</string>\n    <string name=\"enter_percent\">Ange %</string>\n    <string name=\"unknown_host\">Kan inte komma åt sidan, försök använda VPN eller kontrollera om webbadressen är korrekt</string>\n    <string name=\"markup_layers\">Markeringslager</string>\n    <string name=\"markup_layers_sub\">Lagerläge med möjlighet att fritt placera bilder, text och mer</string>\n    <string name=\"edit_layer\">Redigera lager</string>\n    <string name=\"layers_on_image\">Lager på bilden</string>\n    <string name=\"layers_on_image_sub\">Använd en bild som bakgrund och lägg till olika lager ovanpå den</string>\n    <string name=\"layers_on_background\">Lager på bakgrund</string>\n    <string name=\"layers_on_background_sub\">Samma som första alternativet men med färg istället för bild</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Snabb inställningssida</string>\n    <string name=\"fast_settings_side_sub\">Lägg till en flytande remsa på den valda sidan medan du redigerar bilder, vilket öppnar snabba inställningar när du klickar på den</string>\n    <string name=\"clear_selection\">Rensa val</string>\n    <string name=\"settings_group_visibility_hidden\">Inställningsgruppen \\\"%1$s\\\" kommer att komprimeras som standard</string>\n    <string name=\"settings_group_visibility_visible\">Inställningsgruppen \\\"%1$s\\\" kommer att utökas som standard</string>\n    <string name=\"base_64_tools\">Base64-verktyg</string>\n    <string name=\"base_64_tools_sub\">Avkoda Base64-sträng till bild, eller koda bild till Base64-format</string>\n    <string name=\"base_64\">Bas 64</string>\n    <string name=\"not_a_valid_base_64\">Det angivna värdet är inte en giltig Base64-sträng</string>\n    <string name=\"copy_not_a_valid_base_64\">Kan inte kopiera tom eller ogiltig Base64-sträng</string>\n    <string name=\"paste_base_64\">Klistra in Base64</string>\n    <string name=\"copy_base_64\">Kopiera Base64</string>\n    <string name=\"base_64_tips\">Ladda bilden för att kopiera eller spara Base64-strängen. Om du har själva strängen kan du klistra in den ovan för att få en bild</string>\n    <string name=\"save_base_64\">Spara Base64</string>\n    <string name=\"share_base_64\">Aktiebas64</string>\n    <string name=\"options\">Alternativ</string>\n    <string name=\"actions\">Åtgärder</string>\n    <string name=\"import_base_64\">Import Base64</string>\n    <string name=\"base_64_actions\">Base64-åtgärder</string>\n    <string name=\"add_outline\">Lägg till disposition</string>\n    <string name=\"add_outline_sub\">Lägg till kontur runt text med angiven färg och bredd</string>\n    <string name=\"outline_color\">Konturfärg</string>\n    <string name=\"outline_size\">Konturstorlek</string>\n    <string name=\"rotation\">Rotation</string>\n    <string name=\"checksum_as_filename\">Kontrollsumma som filnamn</string>\n    <string name=\"checksum_as_filename_sub\">Utdatabilder kommer att ha ett namn som motsvarar deras datakontrollsumma</string>\n    <string name=\"free_software_partner\">Fri programvara (partner)</string>\n    <string name=\"free_software_partner_sub\">Mer användbar programvara i partnerkanalen för Android-applikationer</string>\n    <string name=\"algorithms\">Algoritm</string>\n    <string name=\"checksum_tools\">Kontrollsummeverktyg</string>\n    <string name=\"checksum_tools_sub\">Jämför kontrollsummor, beräkna hash eller skapa hexsträngar från filer med hjälp av olika hashalgoritmer</string>\n    <string name=\"calculate\">Kalkylera</string>\n    <string name=\"text_hash\">Text Hash</string>\n    <string name=\"checksum\">Kontrollsumma</string>\n    <string name=\"pick_file_to_checksum\">Välj fil för att beräkna dess kontrollsumma baserat på vald algoritm</string>\n    <string name=\"enter_text_to_checksum\">Skriv in text för att beräkna dess kontrollsumma baserat på vald algoritm</string>\n    <string name=\"source_checksum\">Källkontrollsumma</string>\n    <string name=\"checksum_to_compare\">Kontrollsumma att jämföra</string>\n    <string name=\"match\">Match!</string>\n    <string name=\"difference\">Skillnad</string>\n    <string name=\"match_sub\">Kontrollsummor är lika, det kan vara säkert</string>\n    <string name=\"difference_sub\">Kontrollsummor är inte lika, filen kan vara osäker!</string>\n    <string name=\"mesh_gradients\">Mesh Gradienter</string>\n    <string name=\"collection_mesh_gradients_sub\">Titta på online-samlingen av Mesh Gradients</string>\n    <string name=\"wrong_font\">Endast TTF- och OTF-teckensnitt kan importeras</string>\n    <string name=\"import_font\">Importera teckensnitt (TTF/OTF)</string>\n    <string name=\"export_fonts\">Exportera teckensnitt</string>\n    <string name=\"imported_fonts\">Importerade teckensnitt</string>\n    <string name=\"error_while_saving\">Fel när försöket skulle sparas, försök att ändra utdatamapp</string>\n    <string name=\"filename_is_not_set\">Filnamn är inte angivet</string>\n    <string name=\"none\">Ingen</string>\n    <string name=\"custom_pages\">Anpassade sidor</string>\n    <string name=\"pages_selection\">Sidval</string>\n    <string name=\"tool_exit_confirmation\">Bekräftelse av verktygsutgång</string>\n    <string name=\"tool_exit_confirmation_sub\">Om du har osparade ändringar medan du använder vissa verktyg och försöker stänga den, kommer bekräftelsedialogrutan att visas</string>\n    <string name=\"edit_exif_screen\">Redigera EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Ändra metadata för en enda bild utan omkomprimering</string>\n    <string name=\"edit_exif_tag\">Tryck för att redigera tillgängliga taggar</string>\n    <string name=\"change_sticker\">Byt klistermärke</string>\n    <string name=\"fit_width\">Passa bredd</string>\n    <string name=\"fit_height\">Passa höjd</string>\n    <string name=\"batch_compare\">Batchjämför</string>\n    <string name=\"pick_files_to_checksum\">Välj fil/filer för att beräkna dess kontrollsumma baserat på vald algoritm</string>\n    <string name=\"pick_files\">Välj filer</string>\n    <string name=\"pick_directory\">Välj katalog</string>\n    <string name=\"head_length_scale\">Skala för huvudlängd</string>\n    <string name=\"stamp\">Stämpel</string>\n    <string name=\"timestamp\">Tidsstämpel</string>\n    <string name=\"format_pattern\">Formatera mönster</string>\n    <string name=\"padding\">Stoppning</string>\n    <string name=\"image_cutting\">Bildskärning</string>\n    <string name=\"image_cutting_sub\">Klipp ut bilddelen och slå samman de vänstra (kan vara omvända) med vertikala eller horisontella linjer</string>\n    <string name=\"vertical_pivot_line\">Vertikal svänglinje</string>\n    <string name=\"horizontal_pivot_line\">Horisontell svänglinje</string>\n    <string name=\"inverse_selection\">Omvänt urval</string>\n    <string name=\"inverse_vertical_selection_sub\">Vertikal skuren del kommer att lämnas, istället för att slå samman delar runt klippområdet</string>\n    <string name=\"inverse_horizontal_selection_sub\">Horisontell skuren del kommer att lämnas, istället för att slå samman delar runt klippområdet</string>\n    <string name=\"collection_mesh_gradients\">Samling av meshgradienter</string>\n    <string name=\"mesh_gradients_sub\">Skapa meshgradient med anpassad mängd knutar och upplösning</string>\n    <string name=\"gradient_maker_type_image_mesh\">Mesh Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Komponera mesh-gradient av toppen av givna bilder</string>\n    <string name=\"points_customization\">Poänganpassning</string>\n    <string name=\"grid_size\">Rutnätsstorlek</string>\n    <string name=\"resolution_x\">Upplösning X</string>\n    <string name=\"resolution_y\">Upplösning Y</string>\n    <string name=\"resolution\">Upplösning</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">Markera färg</string>\n    <string name=\"pixel_comparison_type\">Pixeljämförelsetyp</string>\n    <string name=\"scan_barcode\">Skanna streckkoden</string>\n    <string name=\"height_ratio\">Höjdförhållande</string>\n    <string name=\"barcode_type\">Streckkodstyp</string>\n    <string name=\"enforce_bw\">Genomför svartvitt</string>\n    <string name=\"enforce_bw_sub\">Streckkodsbilden kommer att vara helt svartvit och inte färgad av appens tema</string>\n    <string name=\"barcodes_sub\">Skanna vilken streckkod som helst (QR, EAN, AZTEC, …) och hämta dess innehåll eller klistra in din text för att skapa en ny</string>\n    <string name=\"no_barcode_found\">Ingen streckkod hittades</string>\n    <string name=\"generated_barcode_will_be_here\">Genererad streckkod kommer att finnas här</string>\n    <string name=\"audio_cover_extractor\">Audio Covers</string>\n    <string name=\"audio_cover_extractor_sub\">Extrahera skivomslagsbilder från ljudfiler, de vanligaste formaten stöds</string>\n    <string name=\"pick_audio_to_start\">Välj ljud för att starta</string>\n    <string name=\"pick_audio\">Välj ljud</string>\n    <string name=\"no_covers_found\">Inga omslag hittades</string>\n    <string name=\"send_logs\">Skicka loggar</string>\n    <string name=\"send_logs_sub\">Klicka för att dela apploggfil, detta kan hjälpa mig att upptäcka problemet och åtgärda problem</string>\n    <string name=\"crash_title\">Hoppsan… Något gick fel</string>\n    <string name=\"crash_subtitle\">Du kan kontakta mig med hjälp av alternativen nedan så ska jag försöka hitta en lösning.\\n(Glöm inte att bifoga loggar)</string>\n    <string name=\"ocr_write_to_file\">Skriv till fil</string>\n    <string name=\"ocr_write_to_file_sub\">Extrahera text från en serie bilder och lagra den i en textfil</string>\n    <string name=\"ocr_write_to_metadata\">Skriv till metadata</string>\n    <string name=\"ocr_write_to_metadata_sub\">Extrahera text från varje bild och placera den i EXIF-info av relativa bilder</string>\n    <string name=\"invisible_mode\">Osynligt läge</string>\n    <string name=\"invisible_mode_sub\">Använd steganografi för att skapa osynliga vattenstämplar i dina bilder</string>\n    <string name=\"use_lsb\">Använd LSB</string>\n    <string name=\"use_lsb_sub\">LSB (Less Significant Bit) steganografimetod kommer att användas, FD (Frequency Domain) annars</string>\n    <string name=\"auto_remove_red_eyes\">Ta bort röda ögon automatiskt</string>\n    <string name=\"password\">Lösenord</string>\n    <string name=\"unlock\">Låsa upp</string>\n    <string name=\"pdf_is_protected\">PDF är skyddad</string>\n    <string name=\"operation_almost_complete\">Operation nästan klar. Om du avbryter nu måste du starta om den</string>\n    <string name=\"sort_by_date_modified\">Ändrad datum</string>\n    <string name=\"sort_by_date_modified_reversed\">Ändringsdatum (omvänt)</string>\n    <string name=\"sort_by_size\">Storlek</string>\n    <string name=\"sort_by_size_reversed\">Storlek (omvänd)</string>\n    <string name=\"sort_by_mime_type\">MIME-typ</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME-typ (omvänd)</string>\n    <string name=\"sort_by_extension\">Förlängning</string>\n    <string name=\"sort_by_extension_reversed\">Förlängning (omvänd)</string>\n    <string name=\"sort_by_date_added\">Datum tillagt</string>\n    <string name=\"sort_by_date_added_reversed\">Tillagt datum (omvänt)</string>\n    <string name=\"left_to_right\">Vänster till höger</string>\n    <string name=\"right_to_left\">Höger till vänster</string>\n    <string name=\"top_to_bottom\">Topp till botten</string>\n    <string name=\"bottom_to_top\">Botten till toppen</string>\n    <string name=\"liquid_glass\">Flytande glas</string>\n    <string name=\"liquid_glass_sub\">En switch baserad på nyligen tillkännagivna IOS 26 och dess designsystem för flytande glas</string>\n    <string name=\"pick_image_or_base64\">Välj bild eller klistra in/importera Base64-data nedan</string>\n    <string name=\"type_image_link\">Skriv bildlänk för att börja</string>\n    <string name=\"paste_link\">Klistra in länken</string>\n    <string name=\"kaleidoscope\">Kalejdoskop</string>\n    <string name=\"secondary_angle\">Sekundär vinkel</string>\n    <string name=\"sides\">Sidor</string>\n    <string name=\"channel_mix\">Kanalmix</string>\n    <string name=\"blue_green\">Blå grön</string>\n    <string name=\"red_blue\">Röd blå</string>\n    <string name=\"green_red\">Grön röd</string>\n    <string name=\"into_red\">Till rött</string>\n    <string name=\"into_green\">In i grönt</string>\n    <string name=\"into_blue\">Till blått</string>\n    <string name=\"cyan\">Cyan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">Gul</string>\n    <string name=\"color_halftone\">Färg Halvton</string>\n    <string name=\"contour\">Kontur</string>\n    <string name=\"levels\">Nivåer</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi kristallisera</string>\n    <string name=\"shape\">Form</string>\n    <string name=\"stretch\">Sträcka</string>\n    <string name=\"randomness\">Slumpmässighet</string>\n    <string name=\"despeckle\">Avfläcka</string>\n    <string name=\"diffuse\">Diffus</string>\n    <string name=\"dog\">Hund</string>\n    <string name=\"second_radius\">Andra radie</string>\n    <string name=\"equalize\">Utjämna</string>\n    <string name=\"glow\">Glöd</string>\n    <string name=\"whirl_and_pinch\">Virvla och nypa</string>\n    <string name=\"pointillize\">Pointillisera</string>\n    <string name=\"border_color\">Kantfärg</string>\n    <string name=\"polar_coordinates\">Polära koordinater</string>\n    <string name=\"rect_to_polar\">Rekta till polar</string>\n    <string name=\"polar_to_rect\">Polar till rät</string>\n    <string name=\"invert_in_circle\">Invertera i cirkel</string>\n    <string name=\"reduce_noise\">Minska brus</string>\n    <string name=\"simple_solarize\">Enkel solarisering</string>\n    <string name=\"weave\">Väva</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X bredd</string>\n    <string name=\"y_wdth\">Y Bredd</string>\n    <string name=\"twirl\">Snurra</string>\n    <string name=\"rubber_stmp\">Gummi stämpel</string>\n    <string name=\"smear\">Smeta</string>\n    <string name=\"density\">Densitet</string>\n    <string name=\"mix\">Blanda</string>\n    <string name=\"sphere_lensh_distortion\">Sphere Lens Distortion</string>\n    <string name=\"refraction_index\">Brytningsindex</string>\n    <string name=\"arc\">Båge</string>\n    <string name=\"spread_angle\">Spridningsvinkel</string>\n    <string name=\"sparkle\">Gnistra</string>\n    <string name=\"rays\">Strålar</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Lutning</string>\n    <string name=\"moire\">Mary</string>\n    <string name=\"autumn\">Höst</string>\n    <string name=\"bone\">Ben</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Vinter</string>\n    <string name=\"ocean\">Hav</string>\n    <string name=\"summer\">Sommar</string>\n    <string name=\"spring\">Fjädra</string>\n    <string name=\"cool_variant\">Cool variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Rosa</string>\n    <string name=\"hot\">Varm</string>\n    <string name=\"parula\">Ord</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">Plasma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Medborgare</string>\n    <string name=\"twilight\">Skymning</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspektiv Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">Tillåt beskärning</string>\n    <string name=\"crop_or_perspective\">Beskär eller perspektiv</string>\n    <string name=\"absolute\">Absolut</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Deep Green</string>\n    <string name=\"lens_correction\">Linskorrigering</string>\n    <string name=\"target_lens_profile\">Målobjektivprofilfil i JSON-format</string>\n    <string name=\"download_ready_lens_profiles\">Ladda ner färdiga linsprofiler</string>\n    <string name=\"part_percents\">Delprocent</string>\n    <string name=\"export_as_json\">Exportera som JSON</string>\n    <string name=\"export_as_json_sub\">Kopiera sträng med en palettdata som json-representation</string>\n    <string name=\"seam_carving\">Sömsnideri</string>\n    <string name=\"home_screen\">Hemskärmen</string>\n    <string name=\"lock_screen\">Låsskärm</string>\n    <string name=\"built_in\">Inbyggt</string>\n    <string name=\"wallpapers_export\">Bakgrundsexport</string>\n    <string name=\"refresh\">Uppdatera</string>\n    <string name=\"wallpapers_export_sub\">Skaffa aktuella hem-, lås- och inbyggda bakgrundsbilder</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Tillåt åtkomst till alla filer, detta behövs för att hämta bakgrundsbilder</string>\n    <string name=\"allow_read_media_images_for_wp\">Det räcker inte med behörighet att hantera extern lagring, du måste tillåta åtkomst till dina bilder, se till att välja \\\"Tillåt alla\\\"</string>\n    <string name=\"add_preset_to_filename\">Lägg till förinställning till filnamn</string>\n    <string name=\"add_preset_to_filename_sub\">Lägger till suffix med vald förinställning till bildfilnamn</string>\n    <string name=\"add_image_scale_mode_to_filename\">Lägg till bildskalningsläge till filnamn</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Lägger till suffix med valt bildskalningsläge till bildfilnamnet</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">Konvertera bild till ascii-text som kommer att se ut som en bild</string>\n    <string name=\"params\">Params</string>\n    <string name=\"invert_colors_ascii_sub\">Tillämpar negativt filter på bilden för bättre resultat i vissa fall</string>\n    <string name=\"processing_screenshot\">Bearbetar skärmdump</string>\n    <string name=\"skipped_saving\">Sparandet hoppades över</string>\n    <string name=\"skipped_saving_multiple\">%1$s filer hoppade över</string>\n    <string name=\"allow_skip_if_larger\">Tillåt Hoppa över om det är större</string>\n    <string name=\"allow_skip_if_larger_sub\">Vissa verktyg kommer att tillåtas att hoppa över att spara bilder om den resulterande filstorleken skulle vara större än originalet</string>\n    <string name=\"qr_type_calendar_event\">Kalenderhändelse</string>\n    <string name=\"qr_type_contact_info\">Kontakta</string>\n    <string name=\"qr_type_email\">E-post</string>\n    <string name=\"qr_type_geo_point\">Plats</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Text</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Öppet nätverk</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Meddelande</string>\n    <string name=\"address\">Adress</string>\n    <string name=\"subject\">Ämne</string>\n    <string name=\"body\">Kropp</string>\n    <string name=\"name\">Namn</string>\n    <string name=\"organization\">Organisation</string>\n    <string name=\"title\">Titel</string>\n    <string name=\"phones\">Telefoner</string>\n    <string name=\"emails\">E-postmeddelanden</string>\n    <string name=\"urls\">webbadresser</string>\n    <string name=\"addresses\">Adresser</string>\n    <string name=\"summary\">Sammanfattning</string>\n    <string name=\"description\">Beskrivning</string>\n    <string name=\"location\">Plats</string>\n    <string name=\"organizer\">Arrangör</string>\n    <string name=\"start_date\">Startdatum</string>\n    <string name=\"end_date\">Slutdatum</string>\n    <string name=\"status\">Status</string>\n    <string name=\"latitude\">Latitud</string>\n    <string name=\"longitude\">Longitud</string>\n    <string name=\"create_barcode\">Skapa streckkod</string>\n    <string name=\"edit_barcode\">Redigera streckkod</string>\n    <string name=\"wifi_configuration\">Wi-Fi-konfiguration</string>\n    <string name=\"security\">Säkerhet</string>\n    <string name=\"pick_contact\">Välj kontakt</string>\n    <string name=\"grant_contact_permission\">Ge kontakter behörighet i inställningarna att autofylla med vald kontakt</string>\n    <string name=\"contact_info\">Kontaktinformation</string>\n    <string name=\"first_name\">Förnamn</string>\n    <string name=\"middle_name\">Mellannamn</string>\n    <string name=\"last_name\">Efternamn</string>\n    <string name=\"pronunciation\">Uttal</string>\n    <string name=\"add_phone\">Lägg till telefon</string>\n    <string name=\"add_email\">Lägg till e-post</string>\n    <string name=\"add_address\">Lägg till adress</string>\n    <string name=\"website\">Webbplats</string>\n    <string name=\"add_website\">Lägg till webbplats</string>\n    <string name=\"formatted_name\">Formaterat namn</string>\n    <string name=\"qr_code_top_image\">Den här bilden kommer att användas för att placera ovan streckkoden</string>\n    <string name=\"code_customization\">Kodanpassning</string>\n    <string name=\"qr_logo_image\">Den här bilden kommer att användas som logotyp i mitten av QR-koden</string>\n    <string name=\"logo\">Logotyp</string>\n    <string name=\"logo_padding\">Logotyp stoppning</string>\n    <string name=\"logo_size\">Logotypstorlek</string>\n    <string name=\"logo_corners\">Logotyp hörn</string>\n    <string name=\"fourth_eye\">Fjärde ögat</string>\n    <string name=\"fourth_eye_description\">Lägger till ögonsymmetri till qr-koden genom att lägga till det fjärde ögat i det nedre hörnet</string>\n    <string name=\"pixel_shape\">Pixelform</string>\n    <string name=\"frame_shape\">Ramform</string>\n    <string name=\"ball_shape\">Kulform</string>\n    <string name=\"error_correction_level\">Felkorrigeringsnivå</string>\n    <string name=\"dark_color\">Mörk färg</string>\n    <string name=\"light_color\">Ljus färg</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS-liknande stil</string>\n    <string name=\"mask_pattern\">Maskmönster</string>\n    <string name=\"code_may_be_not_scannable\">Den här koden kanske inte går att skanna, ändra utseendeparametrar för att göra den läsbar med alla enheter</string>\n    <string name=\"not_scannable\">Kan inte skannas</string>\n    <string name=\"launcher_mode_sub\">Verktyg kommer att se ut som startskärmens appstartare för att vara mer kompakt</string>\n    <string name=\"launcher_mode\">Launcher-läge</string>\n    <string name=\"flood_fill_sub\">Fyller ett område med utvald pensel och stil</string>\n    <string name=\"flood_fill\">Översvämningsfyllning</string>\n    <string name=\"spray\">Spray</string>\n    <string name=\"spray_sub\">Ritar graffitistilad bana</string>\n    <string name=\"square_particles\">Fyrkantiga partiklar</string>\n    <string name=\"square_particles_sub\">Spraypartiklar kommer att vara kvadratiska istället för cirklar</string>\n    <string name=\"palette_tools\">Palettverktyg</string>\n    <string name=\"palette_tools_sub\">Generera bas/material du palett från bild, eller importera/exportera över olika palettformat</string>\n    <string name=\"edit_palette\">Redigera palett</string>\n    <string name=\"edit_palette_sub\">Exportera/importera palett i olika format</string>\n    <string name=\"color_name\">Färgnamn</string>\n    <string name=\"palette_name\">Palettnamn</string>\n    <string name=\"palette_format\">Palettformat</string>\n    <string name=\"export_palette_sub\">Exportera genererad palett till olika format</string>\n    <string name=\"add_color_palette_sub\">Lägger till ny färg till nuvarande palett</string>\n    <string name=\"palette_name_not_supported\">Formatet %1$s stöder inte att ange palettnamn</string>\n    <string name=\"wallpapers_export_not_avaialbe\">På grund av Play Butiks policyer kan den här funktionen inte inkluderas i den aktuella versionen. För att komma åt denna funktion, ladda ner ImageToolbox från en alternativ källa. Du kan hitta de tillgängliga versionerna på GitHub nedan.</string>\n    <string name=\"open_github_page\">Öppna Github-sidan</string>\n    <string name=\"overwrite_files_sub_short\">Originalfilen kommer att ersättas med en ny istället för att sparas i den valda mappen</string>\n    <string name=\"hidden_watermark_text_detected\">Upptäckt dold vattenstämpeltext</string>\n    <string name=\"hidden_watermark_image_detected\">Upptäckte dold vattenstämpelbild</string>\n    <string name=\"this_image_was_hidden\">Den här bilden var gömd</string>\n    <string name=\"generative_inpaint\">Generativ målning</string>\n    <string name=\"generative_inpaint_sub\">Låter dig ta bort objekt i en bild med hjälp av en AI-modell, utan att förlita dig på OpenCV. För att använda den här funktionen laddar appen ner den modell som krävs (~200 MB) från GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Låter dig ta bort objekt i en bild med hjälp av en AI-modell, utan att förlita dig på OpenCV. Detta kan vara en långvarig operation</string>\n    <string name=\"error_level_analysis\">Felnivåanalys</string>\n    <string name=\"luminance_gradient\">Luminansgradient</string>\n    <string name=\"average_distance\">Genomsnittligt avstånd</string>\n    <string name=\"copy_move_detection\">Kopiera rörelsedetektering</string>\n    <string name=\"retain\">Behålla</string>\n    <string name=\"coefficent\">Koefficient</string>\n    <string name=\"clipboard_data_is_too_large\">Urklippsdata är för stor</string>\n    <string name=\"data_is_too_large_to_copy\">Data är för stor för att kopieras</string>\n    <string name=\"simple_weave_pixelization\">Enkel vävpixelisering</string>\n    <string name=\"staggered_pixelization\">Förskjuten pixelisering</string>\n    <string name=\"cross_pixelization\">Korspixelisering</string>\n    <string name=\"micro_macro_pixelization\">Mikromakropixelisering</string>\n    <string name=\"orbital_pixelization\">Orbital pixelisering</string>\n    <string name=\"vortex_pixelization\">Vortexpixelisering</string>\n    <string name=\"pulse_grid_pixelization\">Pulsrutnätspixelisering</string>\n    <string name=\"nucleus_pixelization\">Kärnpixelisering</string>\n    <string name=\"radial_weave_pixelization\">Radiell vävpixelisering</string>\n    <string name=\"cannot_open_uri\">Kan inte öppna uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Snöfallsläge</string>\n    <string name=\"enabled\">Aktiverad</string>\n    <string name=\"border_frame\">Kantram</string>\n    <string name=\"glitch_variant\">Glitch-variant</string>\n    <string name=\"channel_shift\">Kanalskifte</string>\n    <string name=\"max_offset\">Max offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Block Glitch</string>\n    <string name=\"block_size\">Blockstorlek</string>\n    <string name=\"crt_curvature\">CRT-krökning</string>\n    <string name=\"curvature\">Krökning</string>\n    <string name=\"chroma\">Chroma</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">AI-verktyg</string>\n    <string name=\"ai_tools_sub\">Olika verktyg för att bearbeta bilder genom ai-modeller som att ta bort artefakter eller denoising</string>\n    <string name=\"model_anime_undeint\">Kompression, taggiga linjer</string>\n    <string name=\"model_broadcast\">Tecknad film, sändningskomprimering</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Allmän kompression, allmänt brus</string>\n    <string name=\"model_wb_denoise\">Färglöst tecknat brus</string>\n    <string name=\"model_span_anime_pretrain\">Snabb, allmän komprimering, allmänt brus, animation/serier/anime</string>\n    <string name=\"model_book_scan\">Bokskanning</string>\n    <string name=\"model_overexposure\">Exponeringskorrigering</string>\n    <string name=\"model_fbcnn_color_fp16\">Bäst på allmän komprimering, färgbilder</string>\n    <string name=\"model_fbcnn_gray_fp16\">Bäst på allmän komprimering, gråskalebilder</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Allmän komprimering, gråskalebilder, starkare</string>\n    <string name=\"model_scunet_color_gan_fp16\">Allmänt brus, färgbilder</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Allmänt brus, färgbilder, bättre detaljer</string>\n    <string name=\"model_scunet_gray_15_fp16\">Allmänt brus, bilder i gråskala</string>\n    <string name=\"model_scunet_gray_25_fp16\">Allmänt brus, gråskalebilder, starkare</string>\n    <string name=\"model_scunet_gray_50_fp16\">Allmänt brus, gråskalebilder, starkast</string>\n    <string name=\"model_jpeg_destroyer\">Allmän kompression</string>\n    <string name=\"model_jaywreck\">Allmän kompression</string>\n    <string name=\"model_h264\">Texturisering, h264-komprimering</string>\n    <string name=\"model_vhs\">VHS-komprimering</string>\n    <string name=\"model_cinepak\">Icke-standard komprimering (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Bink komprimering, bättre på geometri</string>\n    <string name=\"model_debink_v5\">Bink kompression, starkare</string>\n    <string name=\"model_debink_v6\">Bink kompression, mjuk, behåller detaljer</string>\n    <string name=\"model_antialias\">Eliminerar trappstegseffekten, utjämnar</string>\n    <string name=\"model_kdm_scans\">Skannad konst/teckningar, mild kompression, moaré</string>\n    <string name=\"model_bandage\">Färgband</string>\n    <string name=\"model_halftone\">Långsam, tar bort halvtoner</string>\n    <string name=\"model_colorizer\">Allmän färgsättare för gråskala/bw-bilder, för bättre resultat använd DDColor</string>\n    <string name=\"model_deedge\">Kantborttagning</string>\n    <string name=\"model_desharpen\">Tar bort överskärpning</string>\n    <string name=\"model_dither\">Långsamt, vibrerande</string>\n    <string name=\"model_gainres\">Kantutjämning, allmänna artefakter, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 skannar bearbetning</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Lätt modell för bildförbättring</string>\n    <string name=\"model_bcgone_detailed_v2\">Borttagning av kompressionsartefakter</string>\n    <string name=\"model_bcgone_smooth\">Ta bort kompressionsartefakter</string>\n    <string name=\"model_bandage_smooth\">Bandageborttagning med jämnt resultat</string>\n    <string name=\"model_bendel_halftone\">Halvtonsmönsterbearbetning</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Borttagning av rastermönster V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG-artefaktborttagning V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 texturförbättring</string>\n    <string name=\"model_vhs_sharpen\">VHS skärpa och förbättring</string>\n    <string name=\"merging\">Sammanslagning</string>\n    <string name=\"chunk_size\">Klumpstorlek</string>\n    <string name=\"overlap_size\">Överlappningsstorlek</string>\n    <string name=\"note_chunk_info\">Bilder över %1$s px kommer att skivas och bearbetas i bitar, överlappande blandar dessa för att förhindra synliga sömmar.</string>\n    <string name=\"large_chunk_warning\">Stora storlekar kan orsaka instabilitet med low-end enheter</string>\n    <string name=\"select_one_to_start\">Välj en för att starta</string>\n    <string name=\"delete_model_sub\">Vill du ta bort modellen %1$s? Du måste ladda ner den igen</string>\n    <string name=\"confirm\">Bekräfta</string>\n    <string name=\"models\">Modeller</string>\n    <string name=\"downloaded_models\">Nedladdade modeller</string>\n    <string name=\"available_models\">Tillgängliga modeller</string>\n    <string name=\"preparing\">Förbereder</string>\n    <string name=\"active_model\">Aktiv modell</string>\n    <string name=\"failed_to_open_session\">Det gick inte att öppna sessionen</string>\n    <string name=\"only_onnx_models\">Endast .onnx/.ort-modeller kan importeras</string>\n    <string name=\"import_model\">Importmodell</string>\n    <string name=\"import_model_sub\">Importera anpassad onnx-modell för vidare användning, endast onnx/ort-modeller accepteras, stöder nästan alla esrgan-liknande varianter</string>\n    <string name=\"imported_models\">Importerade modeller</string>\n    <string name=\"model_scunet_color_15_fp16\">Allmänt brus, färgade bilder</string>\n    <string name=\"model_scunet_color_25_fp16\">Allmänt brus, färgade bilder, starkare</string>\n    <string name=\"model_scunet_color_50_fp16\">Allmänt brus, färgade bilder, starkast</string>\n    <string name=\"model_artifacts_dithering_alsa\">Reducerar vibrerande artefakter och färgband, förbättrar jämna övertoningar och platta färgområden.</string>\n    <string name=\"model_nmkd_brighten_redux\">Förbättrar bildens ljusstyrka och kontrast med balanserade högdagrar samtidigt som naturliga färger bevaras.</string>\n    <string name=\"model_nmkd_brighten\">Gör mörka bilder ljusare samtidigt som du behåller detaljer och undviker överexponering.</string>\n    <string name=\"model_nmkd_detoon\">Tar bort överdriven färgtoning och återställer en mer neutral och naturlig färgbalans.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Applicerar Poisson-baserad brustoning med tonvikt på att bevara fina detaljer och texturer.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Applicerar mjuk Poisson-brustoning för mjukare och mindre aggressiva visuella resultat.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Enhetlig brustoning fokuserad på detaljbevarande och bildskärpa.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Mild enhetlig brustoning för subtil textur och mjukt utseende.</string>\n    <string name=\"model_repainter\">Reparerar skadade eller ojämna områden genom att måla om artefakter och förbättra bildens konsistens.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Lättviktsmodell som tar bort färgband med minimal prestandakostnad.</string>\n    <string name=\"model_jpeg_0_20\">Optimerar bilder med mycket höga komprimeringsartefakter (0-20 % kvalitet) för förbättrad skärpa.</string>\n    <string name=\"model_jpeg_20_40\">Förbättrar bilder med artefakter med hög komprimering (20-40 % kvalitet), återställer detaljer och minskar brus.</string>\n    <string name=\"model_jpeg_40_60\">Förbättrar bilder med måttlig komprimering (40-60 % kvalitet), balanserar skärpa och jämnhet.</string>\n    <string name=\"model_jpeg_60_80\">Förfinar bilder med lätt komprimering (60-80 % kvalitet) för att förbättra subtila detaljer och texturer.</string>\n    <string name=\"model_jpeg_80_100\">Förbättrar nästan förlustfria bilder något (80-100 % kvalitet) samtidigt som det naturliga utseendet och detaljerna bevaras.</string>\n    <string name=\"model_spongecolor_lite\">Enkel och snabb färgsättning, tecknade serier, inte idealiskt</string>\n    <string name=\"model_deblr\">Reducerar bildens oskärpa något, förbättrar skärpan utan att introducera artefakter.</string>\n    <string name=\"processing_channel\">Långa operationer</string>\n    <string name=\"processing_image\">Bearbetar bild</string>\n    <string name=\"processing\">Bearbetning</string>\n    <string name=\"model_artifacts_jpg_0_20\">Tar bort tunga JPEG-komprimeringsartefakter i bilder med mycket låg kvalitet (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Reducerar starka JPEG-artefakter i mycket komprimerade bilder (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Rensar upp måttliga JPEG-artefakter samtidigt som bilddetaljerna bevaras (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Förfinar lätta JPEG-artefakter i bilder av ganska hög kvalitet (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Reducerar subtilt mindre JPEG-artefakter i nästan förlustfria bilder (80-100%).</string>\n    <string name=\"model_redetail_v2\">Förbättrar fina detaljer och texturer, förbättrar upplevd skärpa utan tunga artefakter.</string>\n    <string name=\"processing_finished\">Bearbetningen avslutad</string>\n    <string name=\"processing_failed\">Bearbetningen misslyckades</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Förbättrar hudstrukturer och detaljer samtidigt som den behåller en naturlig look, optimerad för hastighet.</string>\n    <string name=\"model_sbdv_dejpeg\">Tar bort JPEG-komprimeringsartefakter och återställer bildkvaliteten för komprimerade foton.</string>\n    <string name=\"model_iso_denoise_v1\">Minskar ISO-brus i bilder tagna i svagt ljus och bevarar detaljer.</string>\n    <string name=\"model_dejumbo\">Korrigerar överexponerade eller \\\"jumbo\\\" högdagrar och återställer bättre tonbalans.</string>\n    <string name=\"model_ddcolor_tiny\">Lätt och snabb färgsättningsmodell som lägger till naturliga färger till gråskalebilder.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">Färglägg</string>\n    <string name=\"type_artifacts\">Artefakter</string>\n    <string name=\"type_enhance\">Öka</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Skanningar</string>\n    <string name=\"type_upscale\">Exklusivt</string>\n    <string name=\"model_realesrgan_x4v3\">X4 upscaler för allmänna bilder; liten modell som använder mindre GPU och tid, med måttlig suddighet och denoise.</string>\n    <string name=\"model_realesrgan_x2plus\">X2 upscaler för allmänna bilder, bevara texturer och naturliga detaljer.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 uppskalare för allmänna bilder med förbättrade texturer och realistiska resultat.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler optimerad för animebilder; 6 RRDB-block för skarpare linjer och detaljer.</string>\n    <string name=\"model_realesrnet_x4plus\">X4 uppskalare med MSE-förlust, ger jämnare resultat och minskade artefakter för allmänna bilder.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler optimerad för animebilder; 4B32F-variant med skarpare detaljer och mjuka linjer.</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2-modell för allmänna bilder; betonar skärpa och tydlighet.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; snabbare och mindre, bevarar detaljer samtidigt som du använder mindre GPU-minne.</string>\n    <string name=\"model_rmbg_1_4\">Lätt modell för snabb borttagning av bakgrund. Balanserad prestanda och noggrannhet. Fungerar med porträtt, objekt och scener. Rekommenderas för de flesta användningsfall.</string>\n    <string name=\"type_removebg\">Ta bort BG</string>\n    <string name=\"horizontal_border_thickness\">Horisontell kanttjocklek</string>\n    <string name=\"vertical_border_thickness\">Vertikal kanttjocklek</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s färg</item>\n        <item quantity=\"other\">%1$s färger</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Den nuvarande modellen stöder inte chunking, bilden kommer att bearbetas i originaldimensioner, detta kan orsaka hög minnesförbrukning och problem med low-end enheter</string>\n    <string name=\"chunking_disabled\">Chunking inaktiverad, bilden kommer att bearbetas i originaldimensioner, detta kan orsaka hög minnesförbrukning och problem med low-end enheter men kan ge bättre resultat vid slutledning</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">Högnoggrann bildsegmenteringsmodell för borttagning av bakgrund</string>\n    <string name=\"model_u2netp\">Lätt version av U2Net för snabbare borttagning av bakgrund med mindre minnesanvändning.</string>\n    <string name=\"model_ddcolor\">Full DDColor-modell ger högkvalitativ färgsättning för allmänna bilder med minimala artefakter. Bästa valet av alla färgsättningsmodeller.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Utbildade och privata konstnärliga datamängder; ger olika och konstnärliga färgningsresultat med färre orealistiska färgartefakter.</string>\n    <string name=\"model_birefnet\">Lätt BiRefNet-modell baserad på Swin Transformer för exakt bakgrundsborttagning.</string>\n    <string name=\"model_inspyrenet\">Högkvalitativ bakgrundsborttagning med skarpa kanter och utmärkt bevarande av detaljer, särskilt på komplexa föremål och knepiga bakgrunder.</string>\n    <string name=\"model_isnet\">Bakgrundsborttagningsmodell som ger exakta masker med släta kanter, lämplig för allmänna föremål och måttlig detaljbevarande.</string>\n    <string name=\"model_already_downloaded\">Modellen har redan laddats ned</string>\n    <string name=\"model_successfully_imported\">Modellen har importerats</string>\n    <string name=\"type\">Typ</string>\n    <string name=\"keyword\">Nyckelord</string>\n    <string name=\"very_fast\">Mycket snabb</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Långsam</string>\n    <string name=\"very_slow\">Mycket långsam</string>\n    <string name=\"compute_percents\">Beräkna procent</string>\n    <string name=\"minimum_value_is\">Minsta värde är %1$s</string>\n    <string name=\"warp_sub\">Förvräng bilden genom att rita med fingrar</string>\n    <string name=\"warp\">Varp</string>\n    <string name=\"hardness\">Hårdhet</string>\n    <string name=\"warp_mode\">Warp-läge</string>\n    <string name=\"warp_mode_move\">Flytta</string>\n    <string name=\"warp_mode_grow\">Växa</string>\n    <string name=\"warp_mode_shrink\">Krympa</string>\n    <string name=\"warp_mode_swirl_cw\">Virvla CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Snurra moturs</string>\n    <string name=\"fade_strength\">Tona styrka</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Nedre droppe</string>\n    <string name=\"start_drop\">Starta Drop</string>\n    <string name=\"end_drop\">Avsluta Drop</string>\n    <string name=\"downloading\">Laddar ner</string>\n    <string name=\"smooth_shapes\">Släta former</string>\n    <string name=\"smooth_shapes_sub\">Använd superellipser istället för vanliga rundade rektanglar för jämnare, mer naturliga former</string>\n    <string name=\"shape_type\">Form typ</string>\n    <string name=\"cut\">Skära</string>\n    <string name=\"rounded\">Avrundad</string>\n    <string name=\"smooth\">Jämna</string>\n    <string name=\"cut_shapes_sub\">Skarpa kanter utan avrundning</string>\n    <string name=\"rounded_shapes_sub\">Klassiska rundade hörn</string>\n    <string name=\"shapes_type\">Former Typ</string>\n    <string name=\"corners_size\">Hörnstorlek</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Eleganta rundade UI-element</string>\n    <string name=\"filename_format\">Filnamnsformat</string>\n    <string name=\"prefix_pattern_description\">Anpassad text placerad i början av filnamnet, perfekt för projektnamn, varumärken eller personliga taggar.</string>\n    <string name=\"original_filename_pattern_description\">Använder det ursprungliga filnamnet utan förlängning, vilket hjälper dig att hålla källidentifieringen intakt.</string>\n    <string name=\"width_pattern_description\">Bildbredden i pixlar, användbar för att spåra upplösningsändringar eller skalningsresultat.</string>\n    <string name=\"height_pattern_description\">Bildhöjden i pixlar, användbart när du arbetar med bildförhållanden eller exporter.</string>\n    <string name=\"random_numbers_pattern_description\">Genererar slumpmässiga siffror för att garantera unika filnamn; lägg till fler siffror för extra säkerhet mot dubbletter.</string>\n    <string name=\"sequence_number_pattern_description\">Automatisk inkrementerande räknare för batchexport, perfekt när du sparar flera bilder i en session.</string>\n    <string name=\"preset_info_pattern_description\">Infogar det använda förinställningsnamnet i filnamnet så att du enkelt kan komma ihåg hur bilden bearbetades.</string>\n    <string name=\"scale_mode_pattern_description\">Visar bildskalningsläget som används under bearbetningen, vilket hjälper till att särskilja bilder som har ändrats, beskurna eller anpassade.</string>\n    <string name=\"suffix_pattern_description\">Anpassad text placerad i slutet av filnamnet, användbar för versionshantering som _v2, _edited eller _final.</string>\n    <string name=\"extension_pattern_description\">Filtillägget (png, jpg, webp, etc.), matchar automatiskt det faktiska sparade formatet.</string>\n    <string name=\"formatted_timestamp_pattern_description\">En anpassningsbar tidsstämpel som låter dig definiera ditt eget format med java-specifikation för perfekt sortering.</string>\n    <string name=\"fling_type\">Släng typ</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">iOS-stil</string>\n    <string name=\"smooth_curve\">Jämn kurva</string>\n    <string name=\"quick_stop\">Snabbt stopp</string>\n    <string name=\"bouncy\">Studsande</string>\n    <string name=\"floaty\">Flytande</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Ultra Smidig</string>\n    <string name=\"adaptive\">Adaptiv</string>\n    <string name=\"accessibility_aware\">Tillgänglighetsmedveten</string>\n    <string name=\"reduced_motion\">Minskad rörelse</string>\n    <string name=\"android_native_sub\">Inbyggd Android rullningsfysik</string>\n    <string name=\"smooth_sub\">Balanserad, mjuk rullning för allmänt bruk</string>\n    <string name=\"ios_style_sub\">Högre friktion iOS-liknande rullningsbeteende</string>\n    <string name=\"smooth_curve_sub\">Unik splinekurva för distinkt rullkänsla</string>\n    <string name=\"quick_stop_sub\">Exakt rullning med snabb stopp</string>\n    <string name=\"bouncy_sub\">Lekfull, lyhörd studsande rullning</string>\n    <string name=\"floaty_sub\">Långa, glidande rullar för innehållssökning</string>\n    <string name=\"snappy_sub\">Snabb, lyhörd rullning för interaktiva användargränssnitt</string>\n    <string name=\"ultra_smooth_sub\">Premium mjuk rullning med utökat momentum</string>\n    <string name=\"adaptive_sub\">Justerar fysiken baserat på flinghastighet</string>\n    <string name=\"accessibility_aware_sub\">Respekterar systemtillgänglighetsinställningar</string>\n    <string name=\"reduced_motion_sub\">Minimal rörelse för tillgänglighetsbehov</string>\n    <string name=\"primary_lines\">Primära linjer</string>\n    <string name=\"primary_lines_sub\">Lägger till tjockare linje var femte rad</string>\n    <string name=\"fill_color\">Fyllningsfärg</string>\n    <string name=\"hidden_tools\">Dolda verktyg</string>\n    <string name=\"hidden_for_share\">Verktyg dolda för delning</string>\n    <string name=\"color_library\">Färgbibliotek</string>\n    <string name=\"color_library_sub\">Bläddra i en stor samling färger</string>\n    <string name=\"model_fatality_deblur\">Skärper och tar bort oskärpa från bilder med bibehållen naturliga detaljer, perfekt för att fixa ofokuserade bilder.</string>\n    <string name=\"model_unresize_v3\">Återställer intelligent bilder som tidigare har ändrats, och återställer förlorade detaljer och texturer.</string>\n    <string name=\"model_liveaction_v1_span\">Optimerad för live-action-innehåll, minskar komprimeringsartefakter och förbättrar fina detaljer i film-/TV-programramar.</string>\n    <string name=\"model_vhs2hd_realplksr\">Konverterar videomaterial av VHS-kvalitet till HD, tar bort bandbrus och förbättrar upplösningen samtidigt som vintagekänslan bevaras.</string>\n    <string name=\"model_text2hd_v1\">Specialiserad för texttunga bilder och skärmdumpar, skärper tecken och förbättrar läsbarheten.</string>\n    <string name=\"model_frankendata_pretrainer\">Avancerad uppskalning utbildad på olika datauppsättningar, utmärkt för allmänna fotoförbättringar.</string>\n    <string name=\"model_realwebphoto_v2\">Optimerad för webbkomprimerade foton, tar bort JPEG-artefakter och återställer det naturliga utseendet.</string>\n    <string name=\"model_realwebphoto_v4\">Förbättrad version för webbfoton med bättre texturbevarande och artefakterminskning.</string>\n    <string name=\"model_dat_2x\">2x uppskalning med Dual Aggregation Transformer-teknik, bibehåller skärpa och naturliga detaljer.</string>\n    <string name=\"model_dat_3x\">3x uppskalning med avancerad transformatorarkitektur, perfekt för måttliga förstoringsbehov.</string>\n    <string name=\"model_dat_4x\">4x högkvalitativ uppskalning med toppmodernt transformatornätverk, bevarar fina detaljer i större skala.</string>\n    <string name=\"model_nafnet_deblurring\">Tar bort oskärpa/brus och skakningar från foton. Allmänt men bäst på bilder.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Återställer bilder av låg kvalitet med Swin2SR-transformator, optimerad för BSRGAN-nedbrytning. Perfekt för att fixa tunga kompressionsartefakter och förbättra detaljer i 4x skala.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4x uppskalning med SwinIR-transformator utbildad på BSRGAN-nedbrytning. Använder GAN för skarpare texturer och mer naturliga detaljer i foton och komplexa scener.</string>\n    <string name=\"path\">Väg</string>\n    <string name=\"merge_pdf\">Slå samman PDF</string>\n    <string name=\"merge_pdf_sub\">Kombinera flera PDF-filer till ett dokument</string>\n    <string name=\"files_order\">Beställning av filer</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">Dela PDF</string>\n    <string name=\"split_pdf_sub\">Extrahera specifika sidor från PDF-dokument</string>\n    <string name=\"rotate_pdf\">Rotera PDF</string>\n    <string name=\"rotate_pdf_sub\">Fixa sidorienteringen permanent</string>\n    <string name=\"pages\">Sidor</string>\n    <string name=\"rearrange_pdf\">Ordna om PDF</string>\n    <string name=\"rearrange_pdf_sub\">Dra och släpp sidor för att ändra ordning på dem</string>\n    <string name=\"hold_drag_drop\">Håll och dra sidor</string>\n    <string name=\"page_numbers\">Sidnummer</string>\n    <string name=\"page_numbers_sub\">Lägg till numrering till dina dokument automatiskt</string>\n    <string name=\"label_format\">Etikettformat</string>\n    <string name=\"pdf_to_text\">PDF till text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Extrahera vanlig text från dina PDF-dokument</string>\n    <string name=\"watermark_pdf_sub\">Överlägg anpassad text för varumärkesbyggande eller säkerhet</string>\n    <string name=\"signature\">Signatur</string>\n    <string name=\"signature_sub\">Lägg till din elektroniska signatur i alla dokument</string>\n    <string name=\"will_be_for_signature\">Detta kommer att användas som signatur</string>\n    <string name=\"unlock_pdf\">Lås upp PDF</string>\n    <string name=\"unlock_pdf_sub\">Ta bort lösenord från dina skyddade filer</string>\n    <string name=\"protect_pdf\">Skydda PDF</string>\n    <string name=\"protect_pdf_sub\">Säkra dina dokument med stark kryptering</string>\n    <string name=\"success\">Framgång</string>\n    <string name=\"pdf_unlocked\">PDF upplåst, du kan spara eller dela den</string>\n    <string name=\"repair_pdf\">Reparera PDF</string>\n    <string name=\"repair_pdf_sub\">Försök att fixa korrupta eller oläsbara dokument</string>\n    <string name=\"grayscale\">Gråskala</string>\n    <string name=\"grayscale_pdf_sub\">Konvertera alla dokumentinbäddade bilder till gråskala</string>\n    <string name=\"compress_pdf\">Komprimera PDF</string>\n    <string name=\"compress_pdf_sub\">Optimera din dokumentfilstorlek för enklare delning</string>\n    <string name=\"repair_info\">ImageToolbox bygger om den interna korsreferenstabellen och regenererar filstrukturen från början. Detta kan återställa åtkomst till många filer som \\\\\"inte kan öppnas\\\\\"</string>\n    <string name=\"grayscale_info\">Detta verktyg konverterar alla dokumentbilder till gråskala. Bäst för att skriva ut och minska filstorleken</string>\n    <string name=\"metadata\">Metadata</string>\n    <string name=\"metadata_pdf_sub\">Redigera dokumentegenskaper för bättre sekretess</string>\n    <string name=\"tags\">Taggar</string>\n    <string name=\"producer\">Producent</string>\n    <string name=\"author\">Författare</string>\n    <string name=\"keywords\">Nyckelord</string>\n    <string name=\"creator\">Skapare</string>\n    <string name=\"privacy_deep_clean\">Sekretess Deep Clean</string>\n    <string name=\"privacy_deep_clean_sub\">Rensa all tillgänglig metadata för detta dokument</string>\n    <string name=\"page\">Sida</string>\n    <string name=\"deep_ocr\">Djup OCR</string>\n    <string name=\"deep_ocr_sub\">Extrahera text från dokument och lagra den i en textfil med hjälp av Tesseract-motorn</string>\n    <string name=\"cant_remove_all\">Kan inte ta bort alla sidor</string>\n    <string name=\"remove_pages_pdf\">Ta bort PDF-sidor</string>\n    <string name=\"remove_pages_pdf_sub\">Ta bort specifika sidor från PDF-dokument</string>\n    <string name=\"tap_to_remove\">Tryck för att ta bort</string>\n    <string name=\"manually\">Manuellt</string>\n    <string name=\"crop_pdf\">Beskär PDF</string>\n    <string name=\"crop_pdf_sub\">Beskär dokumentsidor till valfri gräns</string>\n    <string name=\"flatten_pdf\">Platta till PDF</string>\n    <string name=\"flatten_pdf_sub\">Gör PDF oföränderlig genom att rastra dokumentsidor</string>\n    <string name=\"camera_failed_to_open\">Kunde inte starta kameran. Kontrollera behörigheter och se till att den inte används av en annan app.</string>\n    <string name=\"extract_images\">Extrahera bilder</string>\n    <string name=\"extract_images_sub\">Extrahera bilder inbäddade i PDF-filer med sin ursprungliga upplösning</string>\n    <string name=\"pdf_no_embedded\">Denna PDF-fil innehåller inga inbäddade bilder</string>\n    <string name=\"extract_images_info\">Det här verktyget skannar varje sida och återställer källbilder i full kvalitet – perfekt för att spara original från dokument</string>\n    <string name=\"draw_signature\">Rita signatur</string>\n    <string name=\"pen_params\">Pen Params</string>\n    <string name=\"draw_signature_sub\">Använd egen signatur som bild som ska placeras på dokument</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Dela dokument med givet intervall och packa nya dokument i zip-arkivet</string>\n    <string name=\"interval\">Intervall</string>\n    <string name=\"print_pdf\">Skriv ut PDF</string>\n    <string name=\"print_pdf_sub\">Förbered dokument för utskrift med anpassad sidstorlek</string>\n    <string name=\"pages_per_sheet\">Sidor per ark</string>\n    <string name=\"orientation\">Orientering</string>\n    <string name=\"page_size\">Sidstorlek</string>\n    <string name=\"margin\">Marginal</string>\n    <string name=\"bloom\">Blomma</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Optimerad för anime och tecknade serier. Snabb uppskalning med förbättrade naturliga färger och färre artefakter</string>\n    <string name=\"soft_knee\">Mjukt knä</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 gillar stil</string>\n    <string name=\"calculate_hint\">Ange grundläggande matematiska symboler här för att beräkna önskat värde (t.ex. (5+5)*10)</string>\n    <string name=\"math_expression\">Matematiskt uttryck</string>\n    <string name=\"pick_up_to_n_collage_images\">Plocka upp till %1$s bilder</string>\n    <string name=\"keep_date_time\">Håll datum tid</string>\n    <string name=\"keep_date_time_sub\">Bevara alltid exif-taggar relaterade till datum och tid, fungerar oberoende av keep exif-alternativet</string>\n    <string name=\"background_color_for_alpha_formats\">Bakgrundsfärg För Alfaformat</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Lägger till möjlighet att ställa in bakgrundsfärg för varje bildformat med alfa-stöd, när det är inaktiverat är detta endast tillgängligt för icke-alfa-one</string>\n    <string name=\"open_markup_project_sub\">Fortsätt redigera ett tidigare sparat Image Toolbox-projekt</string>\n    <string name=\"markup_project_open_failed\">Det gick inte att öppna Image Toolbox-projektet</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox-projektet saknar projektdata</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox-projektet är skadat</string>\n    <string name=\"unsupported_markup_project_version\">Image Toolbox-projektversion som inte stöds: %1$d</string>\n    <string name=\"save_markup_project_sub\">Lagra lager, bakgrund och redigeringshistorik i en redigerbar projektfil</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Skriv till sökbar PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Känn igen text från bildbatch och spara sökbar PDF med bild och valbart textlager</string>\n    <string name=\"open_markup_project\">Öppet projekt</string>\n    <string name=\"save_markup_project\">Spara projekt</string>\n    <string name=\"failed_to_open\">Det gick inte att öppna</string>\n    <string name=\"layer_alpha\">Lager alfa</string>\n    <string name=\"horizontal_flip\">Horisontell Vänd</string>\n    <string name=\"vertical_flip\">Vertikal flip</string>\n    <string name=\"lock\">Låsa</string>\n    <string name=\"add_shadow\">Lägg till skugga</string>\n    <string name=\"shadow_color\">Skuggfärg</string>\n    <string name=\"text_geometry\">Textgeometri</string>\n    <string name=\"text_geometry_sub\">Sträck ut eller skeva text för skarpare stilisering</string>\n    <string name=\"scale_x\">Skala X</string>\n    <string name=\"skew_x\">Skev X</string>\n    <string name=\"remove_annotations\">Ta bort anteckningar</string>\n    <string name=\"remove_annotations_sub\">Ta bort valda anteckningstyper som länkar, kommentarer, markeringar, former eller formulärfält från PDF-sidorna</string>\n    <string name=\"annotation_link\">Hyperlänkar</string>\n    <string name=\"annotation_file_attachment\">Filbilagor</string>\n    <string name=\"annotation_line\">Rader</string>\n    <string name=\"annotation_popup\">Popup-fönster</string>\n    <string name=\"annotation_stamp\">Frimärken</string>\n    <string name=\"annotation_shapes\">Former</string>\n    <string name=\"annotation_text\">Textanteckningar</string>\n    <string name=\"annotation_text_markup\">Textuppmärkning</string>\n    <string name=\"annotation_widget\">Formulärfält</string>\n    <string name=\"annotation_markup\">Pålägg</string>\n    <string name=\"annotation_unknown\">Okänd</string>\n    <string name=\"annotations\">Anteckningar</string>\n    <string name=\"ungroup\">Dela upp gruppen</string>\n    <string name=\"add_shadow_sub\">Lägg till oskärpa bakom lagret med konfigurerbar färg och offset</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ta/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"pick_image\">தொடங்குவதற்கு படத்தைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"flexible\">நெகிழ்வான</string>\n    <string name=\"stay\">இருங்கள்</string>\n    <string name=\"reset_image\">படத்தை மீட்டமைக்கவும்</string>\n    <string name=\"cancel\">ரத்து செய்</string>\n    <string name=\"color_copied\">வண்ணம் நகலெடுக்கப்பட்டது</string>\n    <string name=\"color_blue\">நீலம்</string>\n    <string name=\"share\">பகிர்</string>\n    <string name=\"fast_blur\">வேகமான மங்கல்</string>\n    <string name=\"draw\">வரை</string>\n    <string name=\"cipher\">மறைக்குறியீடு</string>\n    <string name=\"group_options_by_type\">வகையின்படி குழு விருப்பங்கள்</string>\n    <string name=\"enable_emoji\">ஈமோஜியை இயக்கு</string>\n    <string name=\"effort\">முயற்சி</string>\n    <string name=\"color_to_replace\">மாற்ற வேண்டிய வண்ணம்</string>\n    <string name=\"lock_draw_orientation\">லாக் டிரா நோக்குநிலை</string>\n    <string name=\"palette_style\">தட்டு பாணி</string>\n    <string name=\"rainbow\">வானவில்</string>\n    <string name=\"fruit_salad\">பழ சாலட்</string>\n    <string name=\"attention\">கவனம்</string>\n    <string name=\"preview_pdf_sub\">எளிய PDF முன்னோட்டம்</string>\n    <string name=\"pen\">பேனா</string>\n    <string name=\"containers_shadow\">கொள்கலன்கள்</string>\n    <string name=\"arrow\">அம்பு</string>\n    <string name=\"tile_mode\">ஓடு முறை</string>\n    <string name=\"tile_mode_repeated\">மீண்டும்</string>\n    <string name=\"tile_mode_mirror\">கண்ணாடி</string>\n    <string name=\"tile_mode_clamp\">கிளாம்ப்</string>\n    <string name=\"tile_mode_decal\">டெக்கால்</string>\n    <string name=\"color_stops\">வண்ண நிறுத்தங்கள்</string>\n    <string name=\"offset_x\">ஆஃப்செட் எக்ஸ்</string>\n    <string name=\"exit\">வெளியேறு</string>\n    <string name=\"atkinson_dithering\">அட்கின்சன் டிதெரிங்</string>\n    <string name=\"just_size\">அளவு</string>\n    <string name=\"smth_went_wrong\">ஏதோ தவறாகிவிட்டது: %1$s</string>\n    <string name=\"size\">அளவு %1$s</string>\n    <string name=\"loading\">ஏற்றுகிறது…</string>\n    <string name=\"image_too_large_preview\">படம் முன்னோட்டமிட மிகப் பெரியது, ஆனால் சேமிப்பு எப்படியும் முயற்சிக்கப்படும்</string>\n    <string name=\"width\">அகலம் %1$s</string>\n    <string name=\"height\">உயரம் %1$s</string>\n    <string name=\"quality\">தரம்</string>\n    <string name=\"pick_image_alt\">படத்தை தேர்ந்தெடு</string>\n    <string name=\"extension\">நீட்டிப்பு</string>\n    <string name=\"resize_type\">மறுஅளவிடுதல் வகை</string>\n    <string name=\"explicit\">வெளிப்படையானது</string>\n    <string name=\"app_closing_sub\">பயன்பாட்டை மூட விரும்புகிறீர்களா?</string>\n    <string name=\"app_closing\">பயன்பாட்டை மூடுகிறது</string>\n    <string name=\"close\">நெருக்கமான</string>\n    <string name=\"reset_image_sub\">பட மாற்றங்கள் ஆரம்ப மதிப்புகளுக்கு திரும்பும்</string>\n    <string name=\"values_reset\">மதிப்புகள் சரியாக மீட்டமைக்கப்படுகின்றன</string>\n    <string name=\"reset\">மீட்டமை</string>\n    <string name=\"something_went_wrong\">ஏதோ தவறு நடந்துவிட்டது</string>\n    <string name=\"restart_app\">பயன்பாட்டை மறுதொடக்கம் செய்யுங்கள்</string>\n    <string name=\"copied\">கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது</string>\n    <string name=\"exception\">விதிவிலக்கு</string>\n    <string name=\"edit_exif\">EXIF ஐ திருத்து</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">சரி</string>\n    <string name=\"no_exif\">EXIF தரவு எதுவும் இல்லை</string>\n    <string name=\"add_tag\">குறியைச் சேர்க்கவும்</string>\n    <string name=\"save\">சேமிக்கவும்</string>\n    <string name=\"clear\">தெளிவு</string>\n    <string name=\"clear_exif\">EXIF ஐ அழிக்கவும்</string>\n    <string name=\"clear_exif_sub\">அனைத்து பட EXIF தரவும் அழிக்கப்படும். இந்தச் செயலைச் செயல்தவிர்க்க முடியாது!</string>\n    <string name=\"presets\">முன்னமைவுகள்</string>\n    <string name=\"crop\">பயிர்</string>\n    <string name=\"image_not_saved\">சேமிப்பு</string>\n    <string name=\"image_not_saved_sub\">நீங்கள் இப்போது வெளியேறினால், சேமிக்கப்படாத அனைத்து மாற்றங்களும் இழக்கப்படும்</string>\n    <string name=\"check_source_code\">மூல குறியீடு</string>\n    <string name=\"check_source_code_sub\">சமீபத்திய புதுப்பிப்புகளைப் பெறவும், சிக்கல்களைப் பற்றி விவாதிக்கவும் மற்றும் பல</string>\n    <string name=\"single_edit\">ஒற்றை திருத்து</string>\n    <string name=\"single_edit_sub\">ஒரு படத்தை மாற்றவும், மறுஅளவிடவும் திருத்தவும்</string>\n    <string name=\"pick_color\">வண்ண தேர்வாளர்</string>\n    <string name=\"pick_color_sub\">படத்திலிருந்து வண்ணத்தைத் தேர்ந்தெடுக்கவும், நகலெடுக்கவும் அல்லது பகிரவும்</string>\n    <string name=\"image\">படம்</string>\n    <string name=\"color\">நிறம்</string>\n    <string name=\"crop_sub\">எந்த எல்லைக்கும் படத்தை செதுக்குங்கள்</string>\n    <string name=\"version\">பதிப்பு</string>\n    <string name=\"keep_exif\">EXIF ஐ வைத்திருங்கள்</string>\n    <string name=\"images\">படங்கள்: %d</string>\n    <string name=\"change_preview\">முன்னோட்டத்தை மாற்றவும்</string>\n    <string name=\"remove\">அகற்று</string>\n    <string name=\"palette_sub\">கொடுக்கப்பட்ட படத்திலிருந்து வண்ணத் தட்டு ஸ்வாட்சை உருவாக்கவும்</string>\n    <string name=\"generate_palette\">தட்டு உருவாக்கு</string>\n    <string name=\"palette\">தட்டு</string>\n    <string name=\"update\">புதுப்பிக்கவும்</string>\n    <string name=\"new_version\">புதிய பதிப்பு %1$s</string>\n    <string name=\"unsupported_type\">ஆதரிக்கப்படாத வகை: %1$s</string>\n    <string name=\"no_palette\">கொடுக்கப்பட்ட படத்திற்கான தட்டு உருவாக்க முடியாது</string>\n    <string name=\"original\">அசல்</string>\n    <string name=\"folder\">வெளியீடு கோப்புறை</string>\n    <string name=\"unspecified\">குறிப்பிடப்படாதது</string>\n    <string name=\"device_storage\">சாதன சேமிப்பு</string>\n    <string name=\"def\">இயல்புநிலை</string>\n    <string name=\"custom\">தனிப்பயன்</string>\n    <string name=\"by_bytes_resize\">எடை மூலம் மறுஅளவிடுங்கள்</string>\n    <string name=\"max_bytes\">அதிகபட்ச அளவு KB இல்</string>\n    <string name=\"compare\">ஒப்பிடு</string>\n    <string name=\"by_bytes_resize_sub\">KB இல் கொடுக்கப்பட்ட அளவைத் தொடர்ந்து படத்தின் அளவை மாற்றவும்</string>\n    <string name=\"compare_sub\">கொடுக்கப்பட்ட இரண்டு படங்களை ஒப்பிடுக</string>\n    <string name=\"pick_two_images\">தொடங்குவதற்கு இரண்டு படங்களைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"pick_images\">படங்களைத் தேர்ந்தெடுங்கள்</string>\n    <string name=\"settings\">அமைப்புகள்</string>\n    <string name=\"dark\">இருள்</string>\n    <string name=\"night_mode\">இரவு நிலை</string>\n    <string name=\"light\">ஒளி</string>\n    <string name=\"system\">அமைப்பு</string>\n    <string name=\"dynamic_colors\">டைனமிக் நிறங்கள்</string>\n    <string name=\"customization\">தனிப்பயனாக்கம்</string>\n    <string name=\"allow_image_monet\">படத்தை மொனெட்டை அனுமதிக்கவும்</string>\n    <string name=\"language\">மொழி</string>\n    <string name=\"amoled_mode\">அமோல்ட் பயன்முறை</string>\n    <string name=\"allow_image_monet_sub\">இயக்கப்பட்டால், திருத்துவதற்குப் படத்தைத் தேர்ந்தெடுக்கும்போது, இந்தப் படத்திற்கு ஆப்ஸ் வண்ணங்கள் ஏற்றுக்கொள்ளப்படும்</string>\n    <string name=\"vibration_strength\">அதிர்வு வலிமை</string>\n    <string name=\"amoled_mode_sub\">இயக்கப்பட்டால், மேற்பரப்புகளின் நிறம் இரவு பயன்முறையில் முற்றிலும் இருட்டாக அமைக்கப்படும்</string>\n    <string name=\"color_scheme\">வண்ண திட்டம்</string>\n    <string name=\"color_red\">சிவப்பு</string>\n    <string name=\"color_green\">பச்சை</string>\n    <string name=\"clipboard_paste_invalid_color_code\">செல்லுபடியாகும் ARGB வண்ணக் குறியீட்டை ஒட்டவும்</string>\n    <string name=\"clipboard_paste_invalid_empty\">ஒட்டுவதற்கு ஒன்றுமில்லை</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">மாறும் வண்ணங்கள் இயக்கப்படும் போது பயன்பாட்டின் வண்ணத் திட்டத்தை மாற்ற முடியாது</string>\n    <string name=\"pick_accent_color\">ஆப்ஸ் தீம் தேர்ந்தெடுக்கப்பட்ட நிறத்தின் அடிப்படையில் இருக்கும்</string>\n    <string name=\"about_app\">பயன்பாட்டைப் பற்றி</string>\n    <string name=\"no_updates\">புதுப்பிப்புகள் எதுவும் இல்லை</string>\n    <string name=\"issue_tracker\">பிரச்சினை டிராக்கர்</string>\n    <string name=\"issue_tracker_sub\">பிழை அறிக்கைகள் மற்றும் அம்ச கோரிக்கைகளை இங்கு அனுப்பவும்</string>\n    <string name=\"help_translate\">மொழிபெயர்க்க உதவுங்கள்</string>\n    <string name=\"help_translate_sub\">மொழிபெயர்ப்புத் தவறுகளைச் சரிசெய்யவும் அல்லது திட்டத்தை வேறொரு மொழிக்கு மொழிபெயர்க்கவும்</string>\n    <string name=\"nothing_found_by_search\">உங்கள் வினவலில் எதுவும் கிடைக்கவில்லை</string>\n    <string name=\"search_here\">இங்கே தேடவும்</string>\n    <string name=\"dynamic_colors_sub\">இயக்கப்பட்டால், ஆப்ஸ் வண்ணங்கள் வால்பேப்பர் வண்ணங்களாக மாற்றப்படும்</string>\n    <string name=\"failed_to_save\">%d படத்தை(களை) சேமிக்க முடியவில்லை</string>\n    <string name=\"email\">மின்னஞ்சல்</string>\n    <string name=\"primary\">முதன்மை</string>\n    <string name=\"tertiary\">மூன்றாம் நிலை</string>\n    <string name=\"border_thickness\">பார்டர் தடிமன்</string>\n    <string name=\"secondary\">இரண்டாம் நிலை</string>\n    <string name=\"surface\">மேற்பரப்பு</string>\n    <string name=\"values\">மதிப்புகள்</string>\n    <string name=\"add\">கூட்டு</string>\n    <string name=\"permission\">அனுமதி</string>\n    <string name=\"grant\">மானியம்</string>\n    <string name=\"permission_sub\">பயன்பாட்டிற்கு படங்களைச் சேமிக்க உங்கள் சேமிப்பகத்திற்கான அணுகல் தேவை, அது அவசியம். அடுத்த உரையாடல் பெட்டியில் அனுமதி வழங்கவும்.</string>\n    <string name=\"grant_permission_manual\">பயன்பாட்டிற்கு வேலை செய்ய இந்த அனுமதி தேவை, அதை கைமுறையாக வழங்கவும்</string>\n    <string name=\"external_storage\">வெளிப்புற சேமிப்பு</string>\n    <string name=\"monet_colors\">மோனெட் நிறங்கள்</string>\n    <string name=\"donation_sub\">இந்த பயன்பாடு முற்றிலும் இலவசம், ஆனால் நீங்கள் திட்ட வளர்ச்சியை ஆதரிக்க விரும்பினால், நீங்கள் இங்கே கிளிக் செய்யலாம்</string>\n    <string name=\"fab_alignment\">FAB சீரமைப்பு</string>\n    <string name=\"check_updates\">புதுப்பிப்புகளைச் சரிபார்க்கவும்</string>\n    <string name=\"check_updates_sub\">இயக்கப்பட்டால், ஆப்ஸ் தொடக்கத்தில் புதுப்பிப்பு உரையாடல் உங்களுக்குக் காண்பிக்கப்படும்</string>\n    <string name=\"zoom\">படத்தை பெரிதாக்கவும்</string>\n    <string name=\"prefix\">முன்னொட்டு</string>\n    <string name=\"filename\">கோப்பு பெயர்</string>\n    <string name=\"emoji\">ஈமோஜி</string>\n    <string name=\"emoji_sub\">பிரதான திரையில் எந்த ஈமோஜியைக் காட்ட வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"add_file_size\">கோப்பு அளவைச் சேர்க்கவும்</string>\n    <string name=\"add_file_size_sub\">இயக்கப்பட்டால், சேமித்த படத்தின் அகலத்தையும் உயரத்தையும் வெளியீட்டு கோப்பின் பெயரில் சேர்க்கும்</string>\n    <string name=\"delete_exif\">EXIF ஐ நீக்கு</string>\n    <string name=\"delete_exif_sub\">எந்தவொரு படத்தொகுப்பிலிருந்தும் EXIF மெட்டாடேட்டாவை நீக்கவும்</string>\n    <string name=\"image_preview\">பட முன்னோட்டம்</string>\n    <string name=\"image_preview_sub\">எந்த வகையான படங்களையும் முன்னோட்டமிடவும்: GIF, SVG மற்றும் பல</string>\n    <string name=\"image_source\">படத்தின் ஆதாரம்</string>\n    <string name=\"photo_picker\">புகைப்படம் எடுப்பவர்</string>\n    <string name=\"gallery_picker\">கேலரி</string>\n    <string name=\"file_explorer_picker\">கோப்பு எக்ஸ்ப்ளோரர்</string>\n    <string name=\"gallery_picker_sub\">எளிய கேலரி படத் தேர்வி. மீடியா பிக்கிங் வழங்கும் ஆப்ஸ் உங்களிடம் இருந்தால் மட்டுமே அது வேலை செய்யும்</string>\n    <string name=\"photo_picker_sub\">திரையின் அடிப்பகுதியில் தோன்றும் Android நவீன புகைப்படத் தேர்வி, android 12+ இல் மட்டுமே வேலை செய்யும். EXIF மெட்டாடேட்டாவைப் பெறுவதில் சிக்கல்கள் உள்ளன</string>\n    <string name=\"file_explorer_picker_sub\">படத்தை எடுக்க GetContent நோக்கத்தைப் பயன்படுத்தவும். எல்லா இடங்களிலும் வேலை செய்யும், ஆனால் சில சாதனங்களில் தேர்ந்தெடுக்கப்பட்ட படங்களைப் பெறுவதில் சிக்கல்கள் இருப்பதாக அறியப்படுகிறது. அது என் தவறு அல்ல.</string>\n    <string name=\"options_arrangement\">விருப்பங்கள் ஏற்பாடு</string>\n    <string name=\"edit\">தொகு</string>\n    <string name=\"order\">ஆர்டர்</string>\n    <string name=\"order_sub\">பிரதான திரையில் உள்ள விருப்பங்களின் வரிசையை தீர்மானிக்கிறது</string>\n    <string name=\"emojis_count\">எமோஜிகள் எண்ணிக்கை</string>\n    <string name=\"sequence_num\">வரிசை எண்</string>\n    <string name=\"original_filename\">அசல் கோப்பு பெயர்</string>\n    <string name=\"replace_sequence_number_sub\">இயக்கப்பட்டால், நீங்கள் தொகுதி செயலாக்கத்தைப் பயன்படுத்தினால், நிலையான நேர முத்திரையை பட வரிசை எண்ணுக்கு மாற்றும்</string>\n    <string name=\"add_original_filename\">அசல் கோப்பு பெயரைச் சேர்க்கவும்</string>\n    <string name=\"add_original_filename_sub\">இயக்கப்பட்டால், வெளியீட்டுப் படத்தின் பெயரில் அசல் கோப்புப் பெயரைச் சேர்க்கும்</string>\n    <string name=\"replace_sequence_number\">வரிசை எண்ணை மாற்றவும்</string>\n    <string name=\"filename_not_work_with_photopicker\">ஃபோட்டோ பிக்கர் பட மூலத்தைத் தேர்ந்தெடுத்தால் அசல் கோப்புப் பெயரைச் சேர்ப்பது வேலை செய்யாது</string>\n    <string name=\"load_image_from_net\">வலை பட ஏற்றுதல்</string>\n    <string name=\"load_image_from_net_sub\">நீங்கள் விரும்பினால், முன்னோட்டம், பெரிதாக்க, திருத்த மற்றும் சேமிக்க இணையத்திலிருந்து எந்தப் படத்தையும் ஏற்றவும்.</string>\n    <string name=\"no_image\">உருவம் இல்லை</string>\n    <string name=\"image_link\">பட இணைப்பு</string>\n    <string name=\"fill\">நிரப்பவும்</string>\n    <string name=\"fit\">பொருத்தம்</string>\n    <string name=\"content_scale\">உள்ளடக்க அளவு</string>\n    <string name=\"explicit_description\">கொடுக்கப்பட்ட உயரத்திற்கும் அகலத்திற்கும் படத்தை மறுஅளவிடுங்கள். படங்களின் விகித விகிதம் மாறக்கூடும்.</string>\n    <string name=\"flexible_description\">கொடுக்கப்பட்ட உயரம் அல்லது அகலத்திற்கு நீண்ட பக்கத்துடன் படத்தை மறுஅளவிடுங்கள். சேமித்த பிறகு அனைத்து அளவுகள் கணக்கீடு செய்யப்படும். படங்களின் விகித விகிதம் பாதுகாக்கப்படும்.</string>\n    <string name=\"brightness\">பிரகாசம்</string>\n    <string name=\"contrast\">மாறுபாடு</string>\n    <string name=\"hue\">சாயல்</string>\n    <string name=\"saturation\">செறிவூட்டல்</string>\n    <string name=\"add_filter\">வடிகட்டி சேர்க்கவும்</string>\n    <string name=\"filter\">வடிகட்டி</string>\n    <string name=\"filter_sub\">படங்களுக்கு வடிகட்டி சங்கிலிகளைப் பயன்படுத்துங்கள்</string>\n    <string name=\"filters\">வடிப்பான்கள்</string>\n    <string name=\"exposure\">நேரிடுவது</string>\n    <string name=\"light_aka_illumination\">ஒளி</string>\n    <string name=\"color_filter\">வண்ண வடிகட்டி</string>\n    <string name=\"alpha\">ஆல்பா</string>\n    <string name=\"white_balance\">வெள்ளை சமநிலை</string>\n    <string name=\"temperature\">வெப்ப நிலை</string>\n    <string name=\"tint\">சாயல்</string>\n    <string name=\"monochrome\">ஒரே வண்ணமுடையது</string>\n    <string name=\"gamma\">காமா</string>\n    <string name=\"highlights_shadows\">சிறப்பம்சங்கள் மற்றும் நிழல்கள்</string>\n    <string name=\"highlights\">சிறப்பம்சங்கள்</string>\n    <string name=\"shadows\">நிழல்கள்</string>\n    <string name=\"haze\">மூடுபனி</string>\n    <string name=\"effect\">விளைவு</string>\n    <string name=\"distance\">தூரம்</string>\n    <string name=\"slope\">சாய்வு</string>\n    <string name=\"sharpen\">கூர்மைப்படுத்து</string>\n    <string name=\"sepia\">செபியா</string>\n    <string name=\"negative\">எதிர்மறை</string>\n    <string name=\"solarize\">சோலரைஸ்</string>\n    <string name=\"vibrance\">அதிர்வு</string>\n    <string name=\"black_and_white\">கருப்பு வெள்ளை</string>\n    <string name=\"crosshatch\">குறுக்குவெட்டு</string>\n    <string name=\"spacing\">இடைவெளி</string>\n    <string name=\"line_width\">கோட்டின் அளவு</string>\n    <string name=\"sobel_edge\">சோபல் விளிம்பு</string>\n    <string name=\"blur\">தெளிவின்மை</string>\n    <string name=\"halftone\">ஹால்ஃப்டோன்</string>\n    <string name=\"cga_colorspace\">CGA வண்ணவெளி</string>\n    <string name=\"gaussian_blur\">காஸியன் தெளிவின்மை</string>\n    <string name=\"box_blur\">பெட்டி மங்கலானது</string>\n    <string name=\"bilaterial_blur\">இருதரப்பு தெளிவின்மை</string>\n    <string name=\"emboss\">புடைப்பு</string>\n    <string name=\"laplacian\">லாப்லாசியன்</string>\n    <string name=\"vignette\">விக்னெட்</string>\n    <string name=\"start\">தொடங்கு</string>\n    <string name=\"end\">முடிவு</string>\n    <string name=\"kuwahara\">குவஹாரா மென்மையாக்குதல்</string>\n    <string name=\"stack_blur\">மங்கலான அடுக்கி</string>\n    <string name=\"radius\">ஆரம்</string>\n    <string name=\"scale\">அளவுகோல்</string>\n    <string name=\"distortion\">திரித்தல்</string>\n    <string name=\"angle\">கோணம்</string>\n    <string name=\"swirl\">சுழி</string>\n    <string name=\"bulge\">வீக்கம்</string>\n    <string name=\"dilation\">விரிவடைதல்</string>\n    <string name=\"sphere_refraction\">கோள ஒளிவிலகல்</string>\n    <string name=\"refractive_index\">ஒளிவிலகல்</string>\n    <string name=\"glass_sphere_refraction\">கண்ணாடி கோள ஒளிவிலகல்</string>\n    <string name=\"color_matrix\">வண்ண அணி</string>\n    <string name=\"opacity\">ஒளிபுகாநிலை</string>\n    <string name=\"limits_resize\">வரம்புகளால் மறுஅளவிடுங்கள்</string>\n    <string name=\"limits_resize_sub\">விகித விகிதத்தை வைத்திருக்கும் போது கொடுக்கப்பட்ட உயரத்திற்கும் அகலத்திற்கும் படங்களை மறுஅளவிடுங்கள்</string>\n    <string name=\"sketch\">ஓவியம்</string>\n    <string name=\"threshold\">வாசல்</string>\n    <string name=\"quantizationLevels\">அளவீட்டு நிலைகள்</string>\n    <string name=\"smooth_toon\">மென்மையான டூன்</string>\n    <string name=\"toon\">டூன்</string>\n    <string name=\"posterize\">போஸ்டரைடு</string>\n    <string name=\"non_maximum_suppression\">அதிகபட்ச அடக்கம் அல்ல</string>\n    <string name=\"weak_pixel_inclusion\">பலவீனமான பிக்சல் சேர்க்கை</string>\n    <string name=\"lookup\">தேடு</string>\n    <string name=\"convolution3x3\">கன்வல்யூஷன் 3x3</string>\n    <string name=\"rgb_filter\">RGB வடிகட்டி</string>\n    <string name=\"false_color\">தவறான நிறம்</string>\n    <string name=\"first_color\">முதல் நிறம்</string>\n    <string name=\"second_color\">இரண்டாவது நிறம்</string>\n    <string name=\"reorder\">மறுவரிசைப்படுத்து</string>\n    <string name=\"blur_size\">மங்கலான அளவு</string>\n    <string name=\"blur_center_x\">மங்கலான மையம் x</string>\n    <string name=\"blur_center_y\">மங்கலான மையம் y</string>\n    <string name=\"zoom_blur\">பெரிதாக்கு தெளிவின்மை</string>\n    <string name=\"color_balance\">வண்ண சமநிலை</string>\n    <string name=\"luminance_threshold\">ஒளிர்வு வாசல்</string>\n    <string name=\"activate_files\">கோப்புகள் பயன்பாட்டை முடக்கியுள்ளீர்கள், இந்த அம்சத்தைப் பயன்படுத்த அதைச் செயல்படுத்தவும்</string>\n    <string name=\"draw_sub\">ஸ்கெட்ச்புக்கில் உள்ளதைப் போல படத்தை வரையவும் அல்லது பின்னணியிலேயே வரையவும்</string>\n    <string name=\"paint_color\">பெயிண்ட் நிறம்</string>\n    <string name=\"paint_alpha\">பெயிண்ட் ஆல்பா</string>\n    <string name=\"draw_on_image\">படத்தை வரையவும்</string>\n    <string name=\"draw_on_image_sub\">ஒரு படத்தைத் தேர்ந்தெடுத்து அதில் ஏதாவது வரையவும்</string>\n    <string name=\"draw_on_background\">பின்னணியில் வரையவும்</string>\n    <string name=\"draw_on_background_sub\">பின்னணி நிறத்தைத் தேர்ந்தெடுத்து அதன் மேல் வரையவும்</string>\n    <string name=\"background_color\">பின்னணி நிறம்</string>\n    <string name=\"cipher_sub\">கிடைக்கக்கூடிய பல்வேறு மறையீட்டு வழிமுறைகளின் அடிப்படையில் எந்தவொரு கோப்பையும் (படம் மட்டுமல்ல) குறியாக்கவும் மறைகுறியாக்கவும்</string>\n    <string name=\"pick_file\">கோப்பைத் தேர்ந்தெடு</string>\n    <string name=\"encrypt\">குறியாக்கம்</string>\n    <string name=\"decrypt\">மறைகுறியாக்கம்</string>\n    <string name=\"pick_file_to_start\">தொடங்க கோப்பைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"decryption\">மறைகுறியாக்கம்</string>\n    <string name=\"encryption\">குறியாக்கம்</string>\n    <string name=\"key\">முக்கிய</string>\n    <string name=\"file_proceed\">கோப்பு செயலாக்கப்பட்டது</string>\n    <string name=\"store_file_desc\">இந்தக் கோப்பை உங்கள் சாதனத்தில் சேமிக்கவும் அல்லது நீங்கள் விரும்பும் இடத்தில் வைக்க, பகிர்வு செயலைப் பயன்படுத்தவும்</string>\n    <string name=\"features\">அம்சங்கள்</string>\n    <string name=\"implementation\">செயல்படுத்தல்</string>\n    <string name=\"compatibility\">இணக்கத்தன்மை</string>\n    <string name=\"features_sub\">கோப்புகளின் கடவுச்சொல் அடிப்படையிலான குறியாக்கம். தொடரப்பட்ட கோப்புகளை தேர்ந்தெடுக்கப்பட்ட கோப்பகத்தில் சேமிக்கலாம் அல்லது பகிரலாம். மறைகுறியாக்கப்பட்ட கோப்புகளையும் நேரடியாக திறக்க முடியும்.</string>\n    <string name=\"implementation_sub\">AES-256, GCM பயன்முறை, திணிப்பு இல்லை, 12 பைட்டுகள் சீரற்ற IV கள் இயல்பாகவே. தேவையான வழிமுறையை நீங்கள் தேர்ந்தெடுக்கலாம். விசைகள் 256-பிட் சா -3 ஆச்களாக பயன்படுத்தப்படுகின்றன</string>\n    <string name=\"file_size\">கோப்பின் அளவு</string>\n    <string name=\"file_size_sub\">அதிகபட்ச கோப்பு அளவு ஆண்ட்ராய்டு OS மற்றும் கிடைக்கக்கூடிய நினைவகத்தால் கட்டுப்படுத்தப்படுகிறது, இது சாதனம் சார்ந்தது.\\n தயவுசெய்து கவனிக்கவும்: நினைவகம் சேமிப்பு அல்ல.</string>\n    <string name=\"overwrite_files\">கோப்புகளை மேலெழுதவும்</string>\n    <string name=\"overwrite_file_requirements\">கோப்புகளை மேலெழுத நீங்கள் \\\"எக்ஸ்ப்ளோரர்\\\" பட மூலத்தைப் பயன்படுத்த வேண்டும், படங்களை மீண்டும் எடுக்க முயற்சிக்கவும், பட மூலத்தை தேவையானதாக மாற்றியுள்ளோம்.</string>\n    <string name=\"invalid_password_or_not_encrypted\">தவறான கடவுச்சொல் அல்லது தேர்ந்தெடுக்கப்பட்ட கோப்பு குறியாக்கம் செய்யப்படவில்லை</string>\n    <string name=\"compatibility_sub\">மற்ற கோப்பு குறியாக்க மென்பொருள் அல்லது சேவைகளுடன் இணக்கம் உத்தரவாதம் இல்லை என்பதை நினைவில் கொள்ளவும். சற்று வித்தியாசமான முக்கிய சிகிச்சை அல்லது சைஃபர் உள்ளமைவு இணக்கமின்மையை ஏற்படுத்தலாம்.</string>\n    <string name=\"image_size_warning\">கொடுக்கப்பட்ட அகலம் மற்றும் உயரத்துடன் படத்தை சேமிக்க முயற்சிப்பது நினைவக பிழையை ஏற்படுத்தக்கூடும். இதை உங்கள் சொந்த ஆபத்தில் செய்யுங்கள்.</string>\n    <string name=\"cache\">தற்காலிக சேமிப்பு</string>\n    <string name=\"cache_size\">கேச் அளவு</string>\n    <string name=\"found_s\">கிடைத்தது %1$s</string>\n    <string name=\"auto_cache_clearing\">தானியங்கு கேச் அழிக்கும்</string>\n    <string name=\"auto_cache_clearing_sub\">இயக்கப்பட்டால், ஆப்ஸ் துவக்கத்தில் ஆப் கேச் அழிக்கப்படும்</string>\n    <string name=\"create\">உருவாக்கு</string>\n    <string name=\"tools\">கருவிகள்</string>\n    <string name=\"group_options_by_type_sub\">தனிப்பயன் பட்டியல் ஏற்பாட்டிற்குப் பதிலாக முதன்மைத் திரையில் அவற்றின் வகையின்படி குழுக்கள் விருப்பங்கள்</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">விருப்பக் குழுவாக்கம் இயக்கப்பட்டிருக்கும் போது ஏற்பாட்டை மாற்ற முடியாது</string>\n    <string name=\"edit_screenshot\">ஸ்கிரீன்ஷாட்டைத் திருத்து</string>\n    <string name=\"secondary_customization\">இரண்டாம் நிலை தனிப்பயனாக்கம்</string>\n    <string name=\"screenshot\">ஸ்கிரீன்ஷாட்</string>\n    <string name=\"fallback_option\">ஃபால்பேக் விருப்பம்</string>\n    <string name=\"skip\">தவிர்க்கவும்</string>\n    <string name=\"copy\">நகலெடுக்கவும்</string>\n    <string name=\"warning_bytes\">%1$s பயன்முறையில் சேமிப்பது நிலையற்றதாக இருக்கலாம், ஏனெனில் இது இழப்பற்ற வடிவமாகும்</string>\n    <string name=\"presets_sub\" formatted=\"false\">நீங்கள் முன்னமைக்கப்பட்ட 125 ஐத் தேர்ந்தெடுத்திருந்தால், அசல் படத்தின் 125% அளவு 100% தரத்துடன் படம் சேமிக்கப்படும். நீங்கள் முன்னமைக்கப்பட்ட 50 ஐ தேர்வு செய்தால், படம் 50% அளவு மற்றும் 50% தரத்துடன் சேமிக்கப்படும்.</string>\n    <string name=\"presets_sub_bytes\">முன்னமைக்கப்பட்ட இங்கே வெளியீட்டு கோப்பின் % ஐ தீர்மானிக்கிறது, அதாவது 5 எம்பி படத்தில் 50 முன்னமைக்கப்பட்ட 50 ஐத் தேர்ந்தெடுத்தால், சேமித்த பிறகு 2,5 எம்பி படத்தைப் பெறுவீர்கள்</string>\n    <string name=\"randomize_filename\">கோப்பு பெயரை சீரற்றதாக்கு</string>\n    <string name=\"randomize_filename_sub\">இயக்கப்பட்டால், வெளியீட்டு கோப்பு பெயர் முற்றிலும் சீரற்றதாக இருக்கும்</string>\n    <string name=\"saved_to\">%2$s என்ற பெயருடன் %1$s கோப்புறையில் சேமிக்கப்பட்டது</string>\n    <string name=\"saved_to_without_filename\">%1$s கோப்புறையில் சேமிக்கப்பட்டது</string>\n    <string name=\"tg_chat\">தந்தி அரட்டை</string>\n    <string name=\"tg_chat_sub\">பயன்பாட்டைப் பற்றி விவாதித்து பிற பயனர்களிடமிருந்து கருத்துகளைப் பெறுங்கள். நீங்கள் பீட்டா புதுப்பிப்புகள் மற்றும் நுண்ணறிவுகளையும் அங்கு பெறலாம்.</string>\n    <string name=\"crop_mask\">பயிர் முகமூடி</string>\n    <string name=\"aspect_ratio\">விகிதம்</string>\n    <string name=\"image_crop_mask_sub\">கொடுக்கப்பட்ட படத்திலிருந்து முகமூடியை உருவாக்க இந்த மாஸ்க் வகையைப் பயன்படுத்தவும், அதில் ஆல்பா சேனல் இருக்க வேண்டும் என்பதைக் கவனியுங்கள்</string>\n    <string name=\"backup_and_restore\">காப்பு மற்றும் மீட்பு</string>\n    <string name=\"backup\">காப்புப்பிரதி</string>\n    <string name=\"restore\">மீட்டமை</string>\n    <string name=\"backup_sub\">உங்கள் பயன்பாட்டு அமைப்புகளை ஒரு கோப்பில் காப்புப் பிரதி எடுக்கவும்</string>\n    <string name=\"restore_sub\">முன்பு உருவாக்கப்பட்ட கோப்பிலிருந்து பயன்பாட்டு அமைப்புகளை மீட்டமைக்கவும்</string>\n    <string name=\"corrupted_file_or_not_a_backup\">சிதைந்த கோப்பு அல்லது காப்புப்பிரதி இல்லை</string>\n    <string name=\"settings_restored\">அமைப்புகள் வெற்றிகரமாக மீட்டெடுக்கப்பட்டன</string>\n    <string name=\"contact_me\">என்னை தொடர்பு கொள்</string>\n    <string name=\"reset_settings_sub\">இது உங்கள் அமைப்புகளை இயல்புநிலை மதிப்புகளுக்கு திரும்பும். மேலே குறிப்பிட்டுள்ள காப்பு கோப்பு இல்லாமல் இதை செயல்தவிர்க்க முடியாது என்பதைக் கவனியுங்கள்.</string>\n    <string name=\"delete\">அழி</string>\n    <string name=\"delete_color_scheme_warn\">தேர்ந்தெடுக்கப்பட்ட வண்ணத் திட்டத்தை நீக்க உள்ளீர்கள். இந்தச் செயல்பாட்டைச் செயல்தவிர்க்க முடியாது</string>\n    <string name=\"delete_color_scheme_title\">திட்டத்தை நீக்கு</string>\n    <string name=\"font\">எழுத்துரு</string>\n    <string name=\"text\">உரை</string>\n    <string name=\"font_scale\">எழுத்துரு அளவு</string>\n    <string name=\"defaultt\">இயல்புநிலை</string>\n    <string name=\"using_large_fonts_warn\">பெரிய எழுத்துரு அளவுகோல்களைப் பயன்படுத்துவது UI குறைபாடுகள் மற்றும் சிக்கல்களை ஏற்படுத்தலாம், அவை சரி செய்யப்படாது. எச்சரிக்கையுடன் பயன்படுத்தவும்.</string>\n    <string name=\"alphabet_and_numbers\">அ ஆ இ ஈ உ ஊ எ ஏ ஐ ஒ ஓ ஔ க ங ச ஞ ட ண த ந ப ம ய ர ல வ ழ ள ற ன ஃ 0123456789 !?</string>\n    <string name=\"emotions\">உணர்ச்சிகள்</string>\n    <string name=\"food_and_drink\">உணவு மற்றும் பானம்</string>\n    <string name=\"nature_and_animals\">இயற்கை மற்றும் விலங்குகள்</string>\n    <string name=\"objects\">பொருள்கள்</string>\n    <string name=\"symbols\">சின்னங்கள்</string>\n    <string name=\"travels_and_places\">பயணங்கள் மற்றும் இடங்கள்</string>\n    <string name=\"activities\">செயல்பாடுகள்</string>\n    <string name=\"background_remover\">பின்னணி நீக்கி</string>\n    <string name=\"background_remover_sub\">வரைவதன் மூலம் படத்திலிருந்து பின்னணியை அகற்றவும் அல்லது தானியங்கு விருப்பத்தைப் பயன்படுத்தவும்</string>\n    <string name=\"trim_image\">படத்தை ஒழுங்கமைக்கவும்</string>\n    <string name=\"keep_exif_sub\">அசல் பட மெட்டாடேட்டா வைக்கப்படும்</string>\n    <string name=\"trim_image_sub\">படத்தைச் சுற்றியுள்ள வெளிப்படையான இடைவெளிகள் குறைக்கப்படும்</string>\n    <string name=\"auto_erase_background\">பின்னணியை தானாக அழித்தல்</string>\n    <string name=\"restore_image\">படத்தை மீட்டமை</string>\n    <string name=\"erase_mode\">அழித்தல் முறை</string>\n    <string name=\"erase_background\">பின்னணியை அழிக்கவும்</string>\n    <string name=\"restore_background\">பின்னணியை மீட்டமை</string>\n    <string name=\"blur_radius\">மங்கலான ஆரம்</string>\n    <string name=\"pipette\">குழாய்</string>\n    <string name=\"draw_mode\">வரைதல் முறை</string>\n    <string name=\"create_issue\">சிக்கலை உருவாக்கவும்</string>\n    <string name=\"something_went_wrong_emphasis\">அச்சச்சோ… ஏதோ தவறாகிவிட்டது. கீழே உள்ள விருப்பங்களைப் பயன்படுத்தி நீங்கள் எனக்கு எழுதலாம், நான் தீர்வு காண முயற்சிப்பேன்</string>\n    <string name=\"resize_and_convert\">அளவை மாற்றி மாற்றவும்</string>\n    <string name=\"resize_and_convert_sub\">கொடுக்கப்பட்ட படங்களின் அளவை மாற்றவும் அல்லது வேறு வடிவங்களுக்கு மாற்றவும். ஒரு படத்தை எடுத்தால் EXIF மெட்டாடேட்டாவையும் இங்கே திருத்தலாம்.</string>\n    <string name=\"max_colors_count\">அதிகபட்ச வண்ண எண்ணிக்கை</string>\n    <string name=\"crashlytics_sub\">இது செயலிழப்பு அறிக்கைகளை தானாக சேகரிக்க பயன்பாட்டை அனுமதிக்கிறது</string>\n    <string name=\"analytics\">பகுப்பாய்வு</string>\n    <string name=\"analytics_sub\">அநாமதேய பயன்பாட்டு புள்ளிவிவரங்களைச் சேகரிக்க அனுமதிக்கவும்</string>\n    <string name=\"overwrite_files_sub\">தேர்ந்தெடுக்கப்பட்ட கோப்புறையில் சேமிப்பதற்குப் பதிலாக அசல் கோப்பு புதியதாக மாற்றப்படும், இந்த விருப்பத்திற்கு பட ஆதாரம் \\\"Explorer\\\" அல்லது GetContent ஆக இருக்க வேண்டும், இதை மாற்றும்போது, தானாகவே அமைக்கப்படும்</string>\n    <string name=\"empty\">காலியாக</string>\n    <string name=\"suffix\">பின்னொட்டு</string>\n    <string name=\"scale_mode\">அளவீட்டு முறை</string>\n    <string name=\"bilinear\">பிலினியர்</string>\n    <string name=\"catmull\">கேட்முல்</string>\n    <string name=\"bicubic\">பைகுபிக்</string>\n    <string name=\"hann\">ஹான்</string>\n    <string name=\"hermite\">துறவி</string>\n    <string name=\"lanczos\">லான்சோஸ்</string>\n    <string name=\"mitchell\">மிட்செல்</string>\n    <string name=\"nearest\">அருகில்</string>\n    <string name=\"spline\">ஸ்ப்லைன்</string>\n    <string name=\"basic\">அடிப்படை</string>\n    <string name=\"default_value\">இயல்புநிலை மதிப்பு</string>\n    <string name=\"bilinear_sub\">நேரியல் (அல்லது பிலினியர், இரு பரிமாணங்களில்) இடைக்கணிப்பு பொதுவாக ஒரு படத்தின் அளவை மாற்றுவதற்கு நல்லது, ஆனால் சில விரும்பத்தகாத விவரங்களை மென்மையாக்குகிறது மற்றும் இன்னும் ஓரளவு துண்டிக்கப்படலாம்.</string>\n    <string name=\"bicubic_sub\">சிறந்த அளவிடுதல் முறைகளில் லான்சோஸ் மறு மாதிரி மற்றும் மிட்செல்-நேத்ராவலி வடிகட்டிகள் அடங்கும்</string>\n    <string name=\"nearest_sub\">அளவை அதிகரிப்பதற்கான எளிய வழிகளில் ஒன்று, ஒவ்வொரு பிக்சலையும் ஒரே நிறத்தின் பல பிக்சல்களுடன் மாற்றுகிறது</string>\n    <string name=\"basic_sub\">கிட்டத்தட்ட எல்லா பயன்பாடுகளிலும் பயன்படுத்தப்படும் எளிமையான ஆண்ட்ராய்டு அளவிடுதல் பயன்முறை</string>\n    <string name=\"catmull_sub\">மென்மையான வளைவுகளை உருவாக்க கணினி வரைகலைகளில் பொதுவாகப் பயன்படுத்தப்படும் கட்டுப்பாட்டுப் புள்ளிகளின் தொகுப்பை சீராக இடைக்கணித்து மறு மாதிரியாக்குவதற்கான முறை</string>\n    <string name=\"hann_sub\">ஸ்பெக்ட்ரல் கசிவைக் குறைக்கவும், சிக்னலின் விளிம்புகளைத் தட்டுவதன் மூலம் அதிர்வெண் பகுப்பாய்வின் துல்லியத்தை மேம்படுத்தவும் சிக்னல் செயலாக்கத்தில் சாளர செயல்பாடு அடிக்கடி பயன்படுத்தப்படுகிறது.</string>\n    <string name=\"hermite_sub\">ஒரு மென்மையான மற்றும் தொடர்ச்சியான வளைவை உருவாக்க ஒரு வளைவுப் பிரிவின் இறுதிப் புள்ளிகளில் மதிப்புகள் மற்றும் வழித்தோன்றல்களைப் பயன்படுத்தும் கணித இடைக்கணிப்பு நுட்பம்</string>\n    <string name=\"lanczos_sub\">பிக்சல் மதிப்புகளுக்கு எடையுள்ள சின்க் செயல்பாட்டைப் பயன்படுத்துவதன் மூலம் உயர்தர இடைக்கணிப்பைப் பராமரிக்கும் மறு மாதிரி முறை</string>\n    <string name=\"mitchell_sub\">அளவிடப்பட்ட படத்தில் கூர்மை மற்றும் மாற்றுப்பெயர்ப்புக்கு இடையில் சமநிலையை அடைய சரிசெய்யக்கூடிய அளவுருக்கள் கொண்ட கன்வல்யூஷன் ஃபில்டரைப் பயன்படுத்தும் மறு மாதிரி முறை</string>\n    <string name=\"spline_sub\">ஒரு வளைவு அல்லது மேற்பரப்பை சீராக இடைக்கணிக்கவும் தோராயமாகவும், நெகிழ்வான மற்றும் தொடர்ச்சியான வடிவ பிரதிநிதித்துவத்தை வழங்குகிறது</string>\n    <string name=\"only_clip\">கிளிப் மட்டும்</string>\n    <string name=\"only_clip_sub\">சேமிப்பகத்தில் சேமிக்கப்படாது, மேலும் படம் கிளிப்போர்டில் மட்டும் வைக்க முயற்சிக்கும்</string>\n    <string name=\"restore_background_sub\">அழிப்பதற்கு பதிலாக பின்னணியை தூரிகை மீட்டெடுக்கும்</string>\n    <string name=\"recognize_text\">OCR (உரையை அங்கீகரிக்கவும்)</string>\n    <string name=\"recognize_text_sub\">கொடுக்கப்பட்ட படத்திலிருந்து உரையை அங்கீகரிக்கவும், 120+ மொழிகள் ஆதரிக்கப்படுகின்றன</string>\n    <string name=\"picture_has_no_text\">படத்தில் உரை இல்லை அல்லது ஆப்ஸ் அதைக் கண்டுபிடிக்கவில்லை</string>\n    <string name=\"accuracy\">துல்லியம்: %1$s</string>\n    <string name=\"recognition_type\">அங்கீகார வகை</string>\n    <string name=\"fast\">வேகமாக</string>\n    <string name=\"standard\">தரநிலை</string>\n    <string name=\"best\">சிறந்த</string>\n    <string name=\"no_data\">தகவல் இல்லை</string>\n    <string name=\"download_description\">Tesseract OCR சரியாகச் செயல்பட, கூடுதல் பயிற்சித் தரவு (%1$s) உங்கள் சாதனத்தில் பதிவிறக்கம் செய்யப்பட வேண்டும். \\nநீங்கள் %2$s தரவைப் பதிவிறக்க விரும்புகிறீர்களா?</string>\n    <string name=\"download\">பதிவிறக்க Tamil</string>\n    <string name=\"no_connection\">இணைப்பு இல்லை, அதைச் சரிபார்த்து, ரயில் மாடல்களைப் பதிவிறக்க மீண்டும் முயற்சிக்கவும்</string>\n    <string name=\"downloaded_languages\">பதிவிறக்கம் செய்யப்பட்ட மொழிகள்</string>\n    <string name=\"available_languages\">கிடைக்கும் மொழிகள்</string>\n    <string name=\"segmentation_mode\">பிரிவு முறை</string>\n    <string name=\"use_pixel_switch\">பிக்சல் சுவிட்சைப் பயன்படுத்தவும்</string>\n    <string name=\"use_pixel_switch_sub\">கூகிள் படப்புள்ளி போன்ற சுவிட்சைப் பயன்படுத்துகிறது</string>\n    <string name=\"saved_to_original\">அசல் இலக்கில் %1$s என்ற பெயரில் மேலெழுதப்பட்ட கோப்பு</string>\n    <string name=\"magnifier\">உருப்பெருக்கி</string>\n    <string name=\"magnifier_sub\">சிறந்த அணுகலுக்காக வரைதல் முறைகளில் விரலின் மேற்பகுதியில் உருப்பெருக்கியை இயக்குகிறது</string>\n    <string name=\"force_exif_widget_initial_value\">ஆரம்ப மதிப்பை கட்டாயப்படுத்தவும்</string>\n    <string name=\"force_exif_widget_initial_value_sub\">exif விட்ஜெட்டை முதலில் சரிபார்க்க வேண்டும்</string>\n    <string name=\"allow_multiple_languages\">பல மொழிகளை அனுமதிக்கவும்</string>\n    <string name=\"slide\">ஸ்லைடு</string>\n    <string name=\"side_by_side\">சைட் பை சைட்</string>\n    <string name=\"toggle_tap\">தட்டுவதை நிலைமாற்று</string>\n    <string name=\"transparency\">வெளிப்படைத்தன்மை</string>\n    <string name=\"rate_app\">பயன்பாட்டை மதிப்பிடவும்</string>\n    <string name=\"rate\">மதிப்பிடவும்</string>\n    <string name=\"rate_app_sub\">இந்த ஆப்ஸ் முற்றிலும் இலவசம், இது பெரியதாக மாற விரும்பினால், தயவுசெய்து கிதுப்பில் ப்ராஜெக்ட்டை நட்சத்திரமிடுங்கள் 😄</string>\n    <string name=\"segmentation_mode_osd_only\">ஓரியண்டேஷன் &amp; ஸ்கிரிப்ட் கண்டறிதல் மட்டும்</string>\n    <string name=\"segmentation_mode_auto_osd\">தானியங்கு நோக்குநிலை &amp; ஸ்கிரிப்ட் கண்டறிதல்</string>\n    <string name=\"segmentation_mode_auto_only\">ஆட்டோ மட்டும்</string>\n    <string name=\"segmentation_mode_auto\">ஆட்டோ</string>\n    <string name=\"segmentation_mode_single_column\">ஒற்றை நெடுவரிசை</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">ஒற்றைத் தொகுதி செங்குத்து உரை</string>\n    <string name=\"segmentation_mode_single_block\">ஒற்றைத் தொகுதி</string>\n    <string name=\"segmentation_mode_single_line\">ஒற்றை வரி</string>\n    <string name=\"segmentation_mode_single_word\">ஒற்றை வார்த்தை</string>\n    <string name=\"segmentation_mode_circle_word\">வட்டச் சொல்</string>\n    <string name=\"segmentation_mode_single_char\">ஒற்றை எழுத்து</string>\n    <string name=\"segmentation_mode_sparse_text\">அரிதான உரை</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">அரிதான உரை நோக்குநிலை &amp; ஸ்கிரிப்ட் கண்டறிதல்</string>\n    <string name=\"segmentation_mode_raw_line\">மூல வரி</string>\n    <string name=\"delete_language_sub\">அனைத்து அங்கீகார வகைகளுக்கான மொழி \\\"%1$s\\\" OCR பயிற்சி தரவை நீக்க விரும்புகிறீர்களா அல்லது தேர்ந்தெடுக்கப்பட்ட ஒன்றிற்கு மட்டும் (%2$s) நீக்க வேண்டுமா?</string>\n    <string name=\"current\">தற்போதைய</string>\n    <string name=\"all\">அனைத்து</string>\n    <string name=\"gradient_maker\">கிரேடியன்ட் மேக்கர்</string>\n    <string name=\"gradient_maker_sub\">தனிப்பயனாக்கப்பட்ட வண்ணங்கள் மற்றும் தோற்ற வகையுடன் கொடுக்கப்பட்ட வெளியீட்டு அளவின் சாய்வை உருவாக்கவும்</string>\n    <string name=\"gradient_type_linear\">நேரியல்</string>\n    <string name=\"gradient_type_radial\">ரேடியல்</string>\n    <string name=\"gradient_type_sweep\">துடைக்கவும்</string>\n    <string name=\"gradient_type\">சாய்வு வகை</string>\n    <string name=\"center_x\">மையம் எக்ஸ்</string>\n    <string name=\"center_y\">மையம் ஒய்</string>\n    <string name=\"add_color\">வண்ணத்தைச் சேர்க்கவும்</string>\n    <string name=\"properties\">பண்புகள்</string>\n    <string name=\"brightness_enforcement\">பிரகாசம் அமலாக்கம்</string>\n    <string name=\"screen\">திரை</string>\n    <string name=\"gradient_maker_type_image\">சாய்வு மேலடுக்கு</string>\n    <string name=\"gradient_maker_type_image_sub\">கொடுக்கப்பட்ட படங்களின் மேல் எந்த சாய்வையும் எழுதுங்கள்</string>\n    <string name=\"transformations\">உருமாற்றங்கள்</string>\n    <string name=\"camera\">புகைப்பட கருவி</string>\n    <string name=\"camera_sub\">கேமராவுடன் படம் எடுக்கவும். இந்த பட மூலத்திலிருந்து ஒரே ஒரு படத்தை மட்டுமே பெற முடியும் என்பதை நினைவில் கொள்க</string>\n    <string name=\"watermarking\">வாட்டர்மார்க்கிங்</string>\n    <string name=\"watermarking_sub\">தனிப்பயனாக்கக்கூடிய உரை/பட வாட்டர்மார்க்ஸுடன் படங்களை கவர்</string>\n    <string name=\"repeat_watermark\">வாட்டர்மார்க் செய்யவும்</string>\n    <string name=\"repeat_watermark_sub\">கொடுக்கப்பட்ட நிலையில் ஒற்றைக்கு பதிலாக படத்தின் மீது வாட்டர்மார்க் மீண்டும் செய்கிறது</string>\n    <string name=\"offset_y\">ஆஃப்செட் ஒய்</string>\n    <string name=\"watermark_type\">வாட்டர்மார்க் வகை</string>\n    <string name=\"watermarking_image_sub\">இந்தப் படம் வாட்டர்மார்க்கிங்கிற்கான மாதிரியாகப் பயன்படுத்தப்படும்</string>\n    <string name=\"text_color\">உரை நிறம்</string>\n    <string name=\"overlay_mode\">மேலடுக்கு முறை</string>\n    <string name=\"gif_tools\">GIF கருவிகள்</string>\n    <string name=\"gif_tools_sub\">படங்களை GIF படமாக மாற்றவும் அல்லது கொடுக்கப்பட்ட GIF படத்திலிருந்து பிரேம்களைப் பிரித்தெடுக்கவும்</string>\n    <string name=\"gif_type_to_image\">படங்களுக்கு GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF கோப்பை படங்களின் தொகுப்பாக மாற்றவும்</string>\n    <string name=\"gif_type_to_gif_sub\">படங்களின் தொகுப்பை GIF கோப்பாக மாற்றவும்</string>\n    <string name=\"gif_type_to_gif\">GIFக்கு படங்கள்</string>\n    <string name=\"select_gif_image_to_start\">தொடங்க GIF படத்தைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"use_size_of_first_frame\">முதல் சட்டத்தின் அளவைப் பயன்படுத்தவும்</string>\n    <string name=\"use_size_of_first_frame_sub\">குறிப்பிட்ட அளவை முதல் சட்ட பரிமாணங்களுடன் மாற்றவும்</string>\n    <string name=\"repeat_count\">மீண்டும் எண்ணிக்கை</string>\n    <string name=\"frame_delay\">பிரேம் தாமதம்</string>\n    <string name=\"millis\">மில்லி</string>\n    <string name=\"fps\">Fps</string>\n    <string name=\"use_lasso\">லாசோவைப் பயன்படுத்தவும்</string>\n    <string name=\"use_lasso_sub\">அழிப்பதைச் செய்ய வரைதல் முறையில் Lassoவைப் பயன்படுத்துகிறது</string>\n    <string name=\"original_image_preview_alpha\">அசல் பட முன்னோட்டம் ஆல்பா</string>\n    <string name=\"confetti\">கான்ஃபெட்டி</string>\n    <string name=\"confetti_sub\">கான்ஃபெட்டி சேமிப்பு, பகிர்தல் மற்றும் பிற முதன்மை செயல்களில் காட்டப்படும்</string>\n    <string name=\"secure_mode\">பாதுகாப்பான பயன்முறை</string>\n    <string name=\"secure_mode_sub\">அண்மைக் கால பயன்பாடுகளில் பயன்பாட்டு உள்ளடக்கத்தை மறைக்கிறது. அதை கைப்பற்றவோ பதிவு செய்யவோ முடியாது.</string>\n    <string name=\"preview_closing\">நீங்கள் இப்போது முன்னோட்டத்தை விட்டுவிட்டால், படங்களை மீண்டும் சேர்க்க வேண்டும்</string>\n    <string name=\"dithering\">டித்தரிங்</string>\n    <string name=\"quantizier\">குவாண்டிசியர்</string>\n    <string name=\"gray_scale\">கிரே ஸ்கேல்</string>\n    <string name=\"bayer_two_dithering\">பேயர் டூ பை டூ டித்தரிங்</string>\n    <string name=\"bayer_three_dithering\">பேயர் த்ரீ பை த்ரீ டித்தரிங்</string>\n    <string name=\"bayer_four_dithering\">பேயர் ஃபோர் பை ஃபோர் டித்தரிங்</string>\n    <string name=\"bayer_eight_dithering\">பேயர் எயிட் பை எய்ட் டித்தரிங்</string>\n    <string name=\"floyd_steinberg_dithering\">ஃபிலாய்ட் ஸ்டெய்ன்பெர்க் டித்தரிங்</string>\n    <string name=\"jarvis_judice_ninke_dithering\">ஜார்விஸ் ஜூடிஸ் நின்கே டிதெரிங்</string>\n    <string name=\"sierra_dithering\">சியரா டித்தரிங்</string>\n    <string name=\"two_row_sierra_dithering\">இரண்டு வரிசை சியரா டித்தரிங்</string>\n    <string name=\"sierra_lite_dithering\">சியரா லைட் டித்தரிங்</string>\n    <string name=\"stucki_dithering\">ஸ்டக்கி டித்தரிங்</string>\n    <string name=\"burkes_dithering\">பர்க்ஸ் டித்தரிங்</string>\n    <string name=\"false_floyd_steinberg_dithering\">தவறான ஃபிலாய்ட் ஸ்டீன்பெர்க் டித்தரிங்</string>\n    <string name=\"left_to_right_dithering\">லெஃப்ட் டு ரைட் டைதரிங்</string>\n    <string name=\"random_dithering\">ரேண்டம் டித்தரிங்</string>\n    <string name=\"simple_threshold_dithering\">எளிய த்ரெஷோல்ட் டித்தரிங்</string>\n    <string name=\"sigma\">சிக்மா</string>\n    <string name=\"spatial_sigma\">இடஞ்சார்ந்த சிக்மா</string>\n    <string name=\"median_blur\">சராசரி தெளிவின்மை</string>\n    <string name=\"b_spline\">பி ஸ்ப்லைன்</string>\n    <string name=\"native_stack_blur\">நேட்டிவ் ஸ்டாக் மங்கலானது</string>\n    <string name=\"b_spline_sub\">ஒரு வளைவு அல்லது மேற்பரப்பை, நெகிழ்வான மற்றும் தொடர்ச்சியான வடிவ பிரதிநிதித்துவத்தை சீராக இடைக்கணித்து தோராயமாக்க, துண்டு துண்டாக வரையறுக்கப்பட்ட பைகுபிக் பல்லுறுப்புக்கோவை செயல்பாடுகளைப் பயன்படுத்துகிறது.</string>\n    <string name=\"tilt_shift\">டில்ட் ஷிப்ட்</string>\n    <string name=\"glitch\">தடுமாற்றம்</string>\n    <string name=\"amount\">தொகை</string>\n    <string name=\"seed\">விதை</string>\n    <string name=\"anaglyph\">அனாக்லிஃப்</string>\n    <string name=\"noise\">சத்தம்</string>\n    <string name=\"pixel_sort\">பிக்சல் வரிசை</string>\n    <string name=\"shuffle\">கலக்கு</string>\n    <string name=\"enhanced_glitch\">மேம்படுத்தப்பட்ட தடுமாற்றம்</string>\n    <string name=\"channel_shift_x\">சேனல் ஷிப்ட் எக்ஸ்</string>\n    <string name=\"channel_shift_y\">சேனல் ஷிப்ட் ஒய்</string>\n    <string name=\"corruption_size\">ஊழல் அளவு</string>\n    <string name=\"corruption_shift_x\">ஊழல் மாற்றம் X</string>\n    <string name=\"corruption_shift_y\">ஊழல் மாற்றம் ஒய்</string>\n    <string name=\"tent_blur\">கூடாரம் மங்கலானது</string>\n    <string name=\"side_fade\">சைட் ஃபேட்</string>\n    <string name=\"side\">பக்கம்</string>\n    <string name=\"top\">மேல்</string>\n    <string name=\"bottom\">கீழே</string>\n    <string name=\"strength\">வலிமை</string>\n    <string name=\"erode\">ஈரோடு</string>\n    <string name=\"anisotropic_diffusion\">அனிசோட்ரோபிக் பரவல்</string>\n    <string name=\"diffusion\">பரவல்</string>\n    <string name=\"conduction\">நடத்துதல்</string>\n    <string name=\"horizontal_wind_stagger\">கிடைமட்ட காற்று ஸ்டாக்கர்</string>\n    <string name=\"fast_bilaterial_blur\">வேகமான இருதரப்பு மங்கலானது</string>\n    <string name=\"poisson_blur\">பாய்சன் மங்கலானது</string>\n    <string name=\"logarithmic_tone_mapping\">மடக்கை டோன் மேப்பிங்</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES ஃபிலிமிக் டோன் மேப்பிங்</string>\n    <string name=\"crystallize\">படிகமாக்கு</string>\n    <string name=\"stroke_color\">பக்கவாதம் நிறம்</string>\n    <string name=\"fractal_glass\">ஃப்ராக்டல் கண்ணாடி</string>\n    <string name=\"amplitude\">வீச்சு</string>\n    <string name=\"marble\">பளிங்கு</string>\n    <string name=\"turbulence\">கொந்தளிப்பு</string>\n    <string name=\"oil\">எண்ணெய்</string>\n    <string name=\"water_effect\">நீர் விளைவு</string>\n    <string name=\"frequency_x\">அதிர்வெண் X</string>\n    <string name=\"frequency_y\">அதிர்வெண் ஒய்</string>\n    <string name=\"amplitude_x\">அலைவீச்சு X</string>\n    <string name=\"amplitude_y\">அலைவீச்சு ஒய்</string>\n    <string name=\"perlin_distortion\">பெர்லின் சிதைவு</string>\n    <string name=\"aces_hill_tone_mapping\">ACES ஹில் டோன் மேப்பிங்</string>\n    <string name=\"hable_filmic_tone_mapping\">ஹேபிள் ஃபிலிமிக் டோன் மேப்பிங்</string>\n    <string name=\"heji_burgess_tone_mapping\">எசி-பர்கச் டோன் மேப்பிங்</string>\n    <string name=\"speed\">வேகம்</string>\n    <string name=\"dehaze\">டீஹேஸ்</string>\n    <string name=\"omega\">ஒமேகா</string>\n    <string name=\"color_matrix_4x4\">கலர் மேட்ரிக்ஸ் 4x4</string>\n    <string name=\"color_matrix_3x3\">கலர் மேட்ரிக்ஸ் 3x3</string>\n    <string name=\"simple_effects\">எளிய விளைவுகள்</string>\n    <string name=\"polaroid\">போலராய்டு</string>\n    <string name=\"tritonomaly\">டிரிடோனோமலி</string>\n    <string name=\"deutaromaly\">டியூடரோமலி</string>\n    <string name=\"protonomaly\">புரோட்டோனோமலி</string>\n    <string name=\"vintage\">விண்டேஜ்</string>\n    <string name=\"browni\">பிரவுனி</string>\n    <string name=\"coda_chrome\">கோடா குரோம்</string>\n    <string name=\"night_vision\">இரவு பார்வை</string>\n    <string name=\"warm\">சூடான</string>\n    <string name=\"cool\">குளிர்</string>\n    <string name=\"tritanopia\">டிரிடானோபியா</string>\n    <string name=\"deutaronotopia\">டியூட்டரனோபியா</string>\n    <string name=\"protanopia\">புரோட்டானோபியா</string>\n    <string name=\"achromatomaly\">அக்ரோமடோமலி</string>\n    <string name=\"achromatopsia\">அக்ரோமடோப்சியா</string>\n    <string name=\"grain\">தானியம்</string>\n    <string name=\"unsharp\">கூர்மை நீக்கவும்</string>\n    <string name=\"pastel\">வெளிர்</string>\n    <string name=\"orange_haze\">ஆரஞ்சு மூட்டம்</string>\n    <string name=\"pink_dream\">இளஞ்சிவப்பு கனவு</string>\n    <string name=\"golden_hour\">கோல்டன் ஹவர்</string>\n    <string name=\"hot_summer\">சூடான கோடை</string>\n    <string name=\"purple_mist\">ஊதா நிற மூடுபனி</string>\n    <string name=\"sunrise\">சூரிய உதயம்</string>\n    <string name=\"colorful_swirl\">வண்ணமயமான சுழல்</string>\n    <string name=\"soft_spring_light\">மென்மையான வசந்த ஒளி</string>\n    <string name=\"autumn_tones\">இலையுதிர் டோன்கள்</string>\n    <string name=\"lavender_dream\">லாவெண்டர் கனவு</string>\n    <string name=\"cyberpunk\">சைபர்பங்க்</string>\n    <string name=\"lemonade_light\">லெமனேட் விளக்கு</string>\n    <string name=\"spectral_fire\">ஸ்பெக்ட்ரல் தீ</string>\n    <string name=\"night_magic\">இரவு மந்திரம்</string>\n    <string name=\"fantasy_landscape\">பேண்டஸி நிலப்பரப்பு</string>\n    <string name=\"color_explosion\">வண்ண வெடிப்பு</string>\n    <string name=\"electric_gradient\">மின்சார சாய்வு</string>\n    <string name=\"caramel_darkness\">கேரமல் இருள்</string>\n    <string name=\"futuristic_gradient\">எதிர்கால சாய்வு</string>\n    <string name=\"green_sun\">பச்சை சூரியன்</string>\n    <string name=\"rainbow_world\">ரெயின்போ உலகம்</string>\n    <string name=\"deep_purple\">அடர் ஊதா</string>\n    <string name=\"space_portal\">விண்வெளி போர்டல்</string>\n    <string name=\"red_swirl\">சிவப்பு சுழல்</string>\n    <string name=\"digital_code\">டிஜிட்டல் குறியீடு</string>\n    <string name=\"bokeh\">பொக்கே</string>\n    <string name=\"random_emojis_sub\">ஆப் பார் ஈமோசி தோராயமாக மாறும்</string>\n    <string name=\"random_emojis\">சீரற்ற எமோஜிகள்</string>\n    <string name=\"random_emojis_error\">ஈமோசிகள் முடக்கப்பட்டிருக்கும் போது நீங்கள் சீரற்ற ஈமோசிகளைப் பயன்படுத்த முடியாது</string>\n    <string name=\"emoji_selection_error\">சீரற்ற ஈமோசிகள் இயக்கப்பட்டிருக்கும்போது நீங்கள் ஒரு ஈமோசியைத் தேர்ந்தெடுக்க முடியாது</string>\n    <string name=\"old_tv\">பழைய டி.வி</string>\n    <string name=\"shuffle_blur\">கலக்கு மங்கல்</string>\n    <string name=\"favorite\">பிடித்தது</string>\n    <string name=\"no_favorite_filters\">பிடித்த வடிப்பான்கள் எதுவும் இதுவரை சேர்க்கப்படவில்லை</string>\n    <string name=\"image_format\">பட வடிவம்</string>\n    <string name=\"icon_shape_sub\">ஐகான்களின் கீழ் தேர்ந்தெடுக்கப்பட்ட வடிவத்துடன் ஒரு கொள்கலனைச் சேர்க்கிறது</string>\n    <string name=\"icon_shape\">ஐகான் வடிவம்</string>\n    <string name=\"drago\">டிராகோ</string>\n    <string name=\"aldridge\">ஆல்ட்ரிட்ஜ்</string>\n    <string name=\"cutoff\">கட்ஆஃப்</string>\n    <string name=\"uchimura\">உச்சிமுரா</string>\n    <string name=\"mobius\">மொபியஸ்</string>\n    <string name=\"transition\">மாற்றம்</string>\n    <string name=\"peak\">உச்சம்</string>\n    <string name=\"color_anomaly\">வண்ண முரண்பாடு</string>\n    <string name=\"images_overwritten\">அசல் இலக்கில் மேலெழுதப்பட்ட படங்கள்</string>\n    <string name=\"cannot_change_image_format\">கோப்புகளை மேலெழுதும் விருப்பம் இயக்கப்பட்டிருக்கும் போது பட வடிவமைப்பை மாற்ற முடியாது</string>\n    <string name=\"emoji_as_color_scheme\">வண்ணத் திட்டமாக ஈமோஜி</string>\n    <string name=\"emoji_as_color_scheme_sub\">கைமுறையாக வரையறுக்கப்பட்டதற்குப் பதிலாக ஈமோஜி முதன்மை வண்ணத்தை பயன்பாட்டு வண்ணத் திட்டமாகப் பயன்படுத்துகிறது</string>\n    <string name=\"image_exif_warning\">தற்போது, ஆண்ட்ராய்டில் EXIF மெட்டாடேட்டாவைப் படிக்க மட்டுமே %1$s வடிவம் அனுமதிக்கிறது. அவுட்புட் படத்தில் சேமிக்கப்படும் போது மெட்டாடேட்டா இருக்காது.</string>\n    <string name=\"effort_sub\">%1$s இன் மதிப்பு என்பது வேகமான சுருக்கத்தைக் குறிக்கிறது, இதன் விளைவாக ஒப்பீட்டளவில் பெரிய கோப்பு அளவு இருக்கும். %2$s என்பது மெதுவான சுருக்கத்தைக் குறிக்கிறது, இதன் விளைவாக சிறிய கோப்பு கிடைக்கும்.</string>\n    <string name=\"wait\">காத்திரு</string>\n    <string name=\"saving_almost_complete\">சேமிப்பு கிட்டத்தட்ட முடிந்தது. இப்போது ரத்துசெய்ய மீண்டும் சேமிக்க வேண்டும்.</string>\n    <string name=\"updates\">புதுப்பிப்புகள்</string>\n    <string name=\"allow_betas\">பீட்டாக்களை அனுமதிக்கவும்</string>\n    <string name=\"allow_betas_sub\">இயக்கப்பட்டால், புதுப்பிப்புச் சரிபார்ப்பில் பீட்டா ஆப்ஸ் பதிப்புகள் இருக்கும்</string>\n    <string name=\"draw_arrows\">அம்புகளை வரையவும்</string>\n    <string name=\"draw_arrows_sub\">செயல்படுத்தப்பட்டால், வரைதல் பாதை சுட்டிக்காட்டும் அம்புக்குறியாகக் காட்டப்படும்</string>\n    <string name=\"brush_softness\">தூரிகை மென்மை</string>\n    <string name=\"crop_description\">உள்ளிடப்பட்ட அளவிற்கு படங்கள் மையச் செதுக்கப்படும். உள்ளிடப்பட்ட பரிமாணங்களை விட படம் சிறியதாக இருந்தால், கொடுக்கப்பட்ட பின்னணி வண்ணத்துடன் கேன்வாஸ் விரிவாக்கப்படும்.</string>\n    <string name=\"donation\">தானம்</string>\n    <string name=\"image_stitching\">பட தையல்</string>\n    <string name=\"image_stitching_sub\">ஒரு பெரிய படத்தைப் பெற கொடுக்கப்பட்ட படங்களை இணைக்கவும்</string>\n    <string name=\"pick_at_least_two_images\">குறைந்தது 2 படங்களைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"output_image_scale\">வெளியீட்டு பட அளவு</string>\n    <string name=\"image_orientation\">பட நோக்குநிலை</string>\n    <string name=\"horizontal\">கிடைமட்ட</string>\n    <string name=\"vertical\">செங்குத்து</string>\n    <string name=\"scale_small_images_to_large\">சிறிய படங்களை பெரியதாக அளவிடவும்</string>\n    <string name=\"scale_small_images_to_large_sub\">இயக்கப்பட்டால், சிறிய படங்கள் வரிசையில் பெரியதாக அளவிடப்படும்</string>\n    <string name=\"images_order\">படங்கள் வரிசை</string>\n    <string name=\"regular\">வழக்கமான</string>\n    <string name=\"blur_edges\">மங்கலான விளிம்புகள்</string>\n    <string name=\"blur_edges_sub\">இயக்கப்பட்டிருந்தால் ஒற்றை நிறத்திற்குப் பதிலாக அதைச் சுற்றியுள்ள இடைவெளிகளை நிரப்ப அசல் படத்தின் கீழ் மங்கலான விளிம்புகளை வரைகிறது</string>\n    <string name=\"pixelation\">பிக்ஸலேஷன்</string>\n    <string name=\"enhanced_pixelation\">மேம்படுத்தப்பட்ட பிக்சலேஷன்</string>\n    <string name=\"stroke_pixelation\">ஸ்ட்ரோக் பிக்ஸலேஷன்</string>\n    <string name=\"enhanced_diamond_pixelation\">மேம்படுத்தப்பட்ட டயமண்ட் பிக்ஸலேஷன்</string>\n    <string name=\"diamond_pixelation\">டயமண்ட் பிக்ஸலேஷன்</string>\n    <string name=\"circle_pixelation\">வட்டம் பிக்சலேஷன்</string>\n    <string name=\"enhanced_circle_pixelation\">மேம்படுத்தப்பட்ட வட்ட பிக்ஸலேஷன்</string>\n    <string name=\"replace_color\">நிறத்தை மாற்றவும்</string>\n    <string name=\"tolerance\">சகிப்புத்தன்மை</string>\n    <string name=\"target_color\">இலக்கு நிறம்</string>\n    <string name=\"color_to_remove\">நீக்க வேண்டிய வண்ணம்</string>\n    <string name=\"remove_color\">நிறத்தை அகற்று</string>\n    <string name=\"recode\">மறுகுறியீடு</string>\n    <string name=\"pixel_size\">பிக்சல் அளவு</string>\n    <string name=\"lock_draw_orientation_sub\">வரைதல் பயன்முறையில் இயக்கப்பட்டால், திரை சுழலாது</string>\n    <string name=\"check_for_updates\">புதுப்பிப்புகளைச் சரிபார்க்கவும்</string>\n    <string name=\"neutral\">நடுநிலை</string>\n    <string name=\"tonal_spot\">டோனல் ஸ்பாட்</string>\n    <string name=\"vibrant\">துடிப்பான</string>\n    <string name=\"expressive\">வெளிப்படுத்தும்</string>\n    <string name=\"fidelity\">விசுவாசம்</string>\n    <string name=\"content\">உள்ளடக்கம்</string>\n    <string name=\"tonal_spot_sub\">இயல்புநிலை தட்டு பாணி, இது நான்கு வண்ணங்களையும் தனிப்பயனாக்க அனுமதிக்கிறது, மற்றவை முக்கிய வண்ணத்தை மட்டுமே அமைக்க உங்களை அனுமதிக்கின்றன</string>\n    <string name=\"neutral_sub\">மோனோக்ரோமை விட சற்றே கூடுதலான நிறமுடைய ஒரு பாணி</string>\n    <string name=\"vibrant_sub\">உரத்த தீம், முதன்மை தட்டுக்கு வண்ணமயமானது அதிகபட்சம், மற்றவர்களுக்கு அதிகரித்தது</string>\n    <string name=\"playful_scheme\">ஒரு விளையாட்டுத்தனமான தீம் - மூல நிறத்தின் சாயல் தீமில் தோன்றாது</string>\n    <string name=\"monochrome_sub\">ஒரே வண்ணமுடைய தீம், நிறங்கள் முற்றிலும் கருப்பு / வெள்ளை / சாம்பல் ஆகும்</string>\n    <string name=\"content_sub\">Scheme.primaryContainer இல் மூல நிறத்தை வைக்கும் திட்டம்</string>\n    <string name=\"fidelity_sub\">உள்ளடக்கத் திட்டத்துடன் மிகவும் ஒத்த திட்டம்</string>\n    <string name=\"foss_update_checker_warning\">இந்த புதுப்பிப்பு சரிபார்ப்பு புதிய புதுப்பிப்பு உள்ளதா என்பதைச் சரிபார்க்கும் காரணத்திற்காக GitHub உடன் இணைக்கப்படும்</string>\n    <string name=\"fading_edges\">மங்கலான விளிம்புகள்</string>\n    <string name=\"disabled\">முடக்கப்பட்டது</string>\n    <string name=\"search_option\">தேடு</string>\n    <string name=\"both\">இரண்டும்</string>\n    <string name=\"invert_colors\">தலைகீழாக நிறங்கள்</string>\n    <string name=\"invert_colors_sub\">இயக்கப்பட்டிருந்தால் தீம் வண்ணங்களை எதிர்மறையாக மாற்றும்</string>\n    <string name=\"search_option_sub\">முதன்மைத் திரையில் கிடைக்கக்கூடிய அனைத்து விருப்பங்களையும் தேடும் திறனை செயல்படுத்துகிறது</string>\n    <string name=\"pdf_tools\">PDF கருவிகள்</string>\n    <string name=\"pdf_tools_sub\">PDF கோப்புகளுடன் இயக்கவும்: முன்னோட்டம், படங்களின் தொகுப்பாக மாற்றவும் அல்லது கொடுக்கப்பட்ட படங்களிலிருந்து ஒன்றை உருவாக்கவும்</string>\n    <string name=\"preview_pdf\">PDF மாதிரிக்காட்சி</string>\n    <string name=\"pdf_to_images\">படங்களுக்கு PDF</string>\n    <string name=\"images_to_pdf\">படங்கள் PDFக்கு</string>\n    <string name=\"pdf_to_images_sub\">கொடுக்கப்பட்ட வெளியீட்டு வடிவத்தில் PDF ஐ படங்களாக மாற்றவும்</string>\n    <string name=\"images_to_pdf_sub\">கொடுக்கப்பட்ட படங்களை அவுட்புட் PDF கோப்பில் தொகுக்கவும்</string>\n    <string name=\"mask_filter\">மாஸ்க் வடிகட்டி</string>\n    <string name=\"mask_filter_sub\">கொடுக்கப்பட்ட முகமூடி பகுதிகளில் வடிகட்டி சங்கிலிகளைப் பயன்படுத்துங்கள், ஒவ்வொரு முகமூடி பகுதியும் அதன் சொந்த வடிப்பான்களைத் தீர்மானிக்க முடியும்</string>\n    <string name=\"masks\">முகமூடிகள்</string>\n    <string name=\"add_mask\">முகமூடியைச் சேர்க்கவும்</string>\n    <string name=\"mask_indexed\">முகமூடி %d</string>\n    <string name=\"mask_color\">முகமூடி நிறம்</string>\n    <string name=\"mask_preview\">முகமூடி முன்னோட்டம்</string>\n    <string name=\"mask_preview_sub\">தோராயமான முடிவை உங்களுக்குக் காட்ட வரையப்பட்ட வடிகட்டி முகமூடி ரெண்டர் செய்யப்படும்</string>\n    <string name=\"inverse_fill_type\">தலைகீழ் நிரப்பு வகை</string>\n    <string name=\"inverse_fill_type_sub\">இயக்கப்பட்டால், முகமூடி இல்லாத பகுதிகள் அனைத்தும் இயல்பு நடத்தைக்குப் பதிலாக வடிகட்டப்படும்</string>\n    <string name=\"delete_mask_warn\">தேர்ந்தெடுக்கப்பட்ட வடிகட்டி முகமூடியை நீக்க உள்ளீர்கள். இந்தச் செயல்பாட்டைச் செயல்தவிர்க்க முடியாது</string>\n    <string name=\"delete_mask\">முகமூடியை நீக்கு</string>\n    <string name=\"full_filter\">முழு வடிகட்டி</string>\n    <string name=\"full_filter_sub\">கொடுக்கப்பட்ட படங்கள் அல்லது ஒற்றைப் படத்திற்கு ஏதேனும் வடிகட்டி சங்கிலிகளைப் பயன்படுத்தவும்</string>\n    <string name=\"start_position\">தொடங்கு</string>\n    <string name=\"center_position\">மையம்</string>\n    <string name=\"end_position\">முடிவு</string>\n    <string name=\"simple_variants\">எளிய மாறுபாடுகள்</string>\n    <string name=\"highlighter\">ஹைலைட்டர்</string>\n    <string name=\"neon\">நியான்</string>\n    <string name=\"privacy_blur\">தனியுரிமை மங்கல்</string>\n    <string name=\"highlighter_sub\">அரை-வெளிப்படையான கூர்மையான ஹைலைட்டர் பாதைகளை வரையவும்</string>\n    <string name=\"neon_sub\">உங்கள் வரைபடங்களில் சில ஒளிரும் விளைவைச் சேர்க்கவும்</string>\n    <string name=\"pen_sub\">இயல்புநிலை ஒன்று, எளிமையானது - நிறம் மட்டுமே</string>\n    <string name=\"privacy_blur_sub\">நீங்கள் மறைக்க விரும்பும் எதையும் பாதுகாக்க, வரையப்பட்ட பாதையின் கீழ் படத்தை மங்கலாக்கும்</string>\n    <string name=\"pixelation_sub\">தனியுரிமை மங்கலைப் போன்றது, ஆனால் மங்கலாக்குவதற்குப் பதிலாக பிக்சலேட்டுகள்</string>\n    <string name=\"containers_shadow_sub\">கொள்கலன்களுக்குப் பின்னால் ஒரு நிழலை வரையவும்</string>\n    <string name=\"sliders_shadow\">ஸ்லைடர்கள்</string>\n    <string name=\"switches_shadow\">மாறுகிறது</string>\n    <string name=\"fabs_shadow\">FABகள்</string>\n    <string name=\"buttons_shadow\">பொத்தான்கள்</string>\n    <string name=\"sliders_shadow_sub\">ச்லைடர்களுக்குப் பின்னால் ஒரு நிழலை வரையவும்</string>\n    <string name=\"switches_shadow_sub\">சுவிட்சுகளுக்குப் பின்னால் ஒரு நிழலை வரையவும்</string>\n    <string name=\"fabs_shadow_sub\">மிதக்கும் செயல் பொத்தான்களுக்குப் பின்னால் ஒரு நிழலை வரையவும்</string>\n    <string name=\"buttons_shadow_sub\">பொத்தான்களுக்குப் பின்னால் ஒரு நிழலை வரையவும்</string>\n    <string name=\"app_bars_shadow\">பயன்பாட்டு பார்கள்</string>\n    <string name=\"app_bars_shadow_sub\">பயன்பாட்டு பார்களுக்குப் பின்னால் ஒரு நிழலை வரையவும்</string>\n    <string name=\"value_in_range\">வரம்பில் உள்ள மதிப்பு %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">தானாக சுழற்று</string>\n    <string name=\"auto_rotate_limits_sub\">பட நோக்குநிலைக்கு வரம்புப் பெட்டியை ஏற்றுக்கொள்ள அனுமதிக்கிறது</string>\n    <string name=\"draw_path_mode\">பாதை பயன்முறையை வரையவும்</string>\n    <string name=\"double_line_arrow\">இரட்டை வரி அம்பு</string>\n    <string name=\"free_drawing\">இலவச வரைதல்</string>\n    <string name=\"double_arrow\">இரட்டை அம்பு</string>\n    <string name=\"line_arrow\">வரி அம்பு</string>\n    <string name=\"line\">வரி</string>\n    <string name=\"free_drawing_sub\">உள்ளீட்டு மதிப்பாக பாதையை வரைகிறது</string>\n    <string name=\"line_sub\">தொடக்கப் புள்ளியிலிருந்து இறுதிப் புள்ளி வரை பாதையை ஒரு கோடாக வரைகிறது</string>\n    <string name=\"line_arrow_sub\">தொடக்கப் புள்ளியிலிருந்து இறுதிப் புள்ளி வரை அம்புக்குறியை ஒரு கோட்டாக வரைகிறது</string>\n    <string name=\"arrow_sub\">கொடுக்கப்பட்ட பாதையிலிருந்து சுட்டிக்காட்டும் அம்புக்குறியை ஈர்க்கிறது</string>\n    <string name=\"double_line_arrow_sub\">தொடக்கப் புள்ளியிலிருந்து இறுதிப் புள்ளி வரை இரட்டைச் சுட்டி அம்புக்குறியை ஒரு கோட்டாக வரைகிறது</string>\n    <string name=\"outlined_oval\">கோடிட்ட ஓவல்</string>\n    <string name=\"double_arrow_sub\">கொடுக்கப்பட்ட பாதையிலிருந்து இரட்டை சுட்டி அம்புக்குறியை வரைகிறது</string>\n    <string name=\"outlined_rect\">கோடிட்ட ரெக்ட்</string>\n    <string name=\"oval\">ஓவல்</string>\n    <string name=\"rect\">ரெக்ட்</string>\n    <string name=\"rect_sub\">தொடக்கப் புள்ளியிலிருந்து இறுதிப் புள்ளி வரை நேராக வரைகிறது</string>\n    <string name=\"oval_sub\">தொடக்கப் புள்ளியிலிருந்து இறுதிப் புள்ளி வரை ஓவல் வரைகிறது</string>\n    <string name=\"outlined_oval_sub\">தொடக்கப் புள்ளியிலிருந்து இறுதிப் புள்ளி வரை கோடிட்ட ஓவல் வரைகிறது</string>\n    <string name=\"outlined_rect_sub\">தொடக்கப் புள்ளியிலிருந்து இறுதிப் புள்ளி வரை கோடிட்டுக் காட்டப்பட்ட வளைவை வரைகிறது</string>\n    <string name=\"lasso\">லாஸ்ஸோ</string>\n    <string name=\"lasso_sub\">கொடுக்கப்பட்ட பாதையின் மூலம் மூடிய நிரப்பப்பட்ட பாதையை வரைகிறது</string>\n    <string name=\"free\">இலவசம்</string>\n    <string name=\"horizontal_grid\">கிடைமட்ட கட்டம்</string>\n    <string name=\"vertical_grid\">செங்குத்து கட்டம்</string>\n    <string name=\"stitch_mode\">தையல் முறை</string>\n    <string name=\"rows_count\">வரிசைகளின் எண்ணிக்கை</string>\n    <string name=\"columns_count\">நெடுவரிசைகளின் எண்ணிக்கை</string>\n    <string name=\"no_such_directory\">\\\"%1$s\\\" கோப்பகம் இல்லை, அதை இயல்புநிலைக்கு மாற்றியுள்ளோம், கோப்பை மீண்டும் சேமிக்கவும்</string>\n    <string name=\"clipboard\">கிளிப்போர்டு</string>\n    <string name=\"auto_pin\">ஆட்டோ பின்</string>\n    <string name=\"auto_pin_sub\">இயக்கப்பட்டிருந்தால், தானாகவே சேமிக்கப்பட்ட படத்தை கிளிப்போர்டில் சேர்க்கும்</string>\n    <string name=\"vibration\">அதிர்வு</string>\n    <string name=\"material_you_sub\">படத்திலிருந்து \\\"Material You\\\" தட்டு உருவாக்குகிறது</string>\n    <string name=\"dark_colors\">இருண்ட நிறங்கள்</string>\n    <string name=\"dark_colors_sub\">ஒளி மாறுபாட்டிற்கு பதிலாக இரவு பயன்முறை வண்ணத் திட்டத்தைப் பயன்படுத்துகிறது</string>\n    <string name=\"copy_as_compose_code\">\\\"Jetpack Compose\\\" குறியீடாக நகலெடுக்கவும்</string>\n    <string name=\"ring_blur\">ரிங் மங்கலான</string>\n    <string name=\"cross_blur\">குறுக்கு மங்கலான</string>\n    <string name=\"circle_blur\">வட்டம் மங்கலானது</string>\n    <string name=\"star_blur\">நட்சத்திர மங்கலானது</string>\n    <string name=\"linear_tilt_shift\">நேரியல் சாய்வு-மாற்றம்</string>\n    <string name=\"tags_to_remove\">நீக்க குறிச்சொற்கள்</string>\n    <string name=\"apng_tools\">APNG கருவிகள்</string>\n    <string name=\"apng_tools_sub\">படங்களை APNG படமாக மாற்றவும் அல்லது கொடுக்கப்பட்ட APNG படத்திலிருந்து பிரேம்களைப் பிரித்தெடுக்கவும்</string>\n    <string name=\"apng_type_to_image\">படங்களுக்கு APNG</string>\n    <string name=\"apng_type_to_apng\">APNGக்கு படங்கள்</string>\n    <string name=\"apng_type_to_apng_sub\">படங்களின் தொகுப்பை APNG கோப்பாக மாற்றவும்</string>\n    <string name=\"apng_type_to_image_sub\">APNG கோப்பை படங்களின் தொகுப்பாக மாற்றவும்</string>\n    <string name=\"select_apng_image_to_start\">தொடங்குவதற்கு APNG படத்தைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"motion_blur\">மோஷன் மங்கல்</string>\n    <string name=\"zip\">ஜிப்</string>\n    <string name=\"zip_sub\">கொடுக்கப்பட்ட கோப்புகள் அல்லது படங்களிலிருந்து ஜிப் கோப்பை உருவாக்கவும்</string>\n    <string name=\"drag_handle_width\">கைப்பிடி அகலத்தை இழுக்கவும்</string>\n    <string name=\"kaiser\">கைசர்</string>\n    <string name=\"ewa_robidoux\">ராபிடோக்ச் ஈவா</string>\n    <string name=\"ewa_lanczos_soft\">லான்சோச் மென்மையான ஈவா</string>\n    <string name=\"protanopia_sub\">சிவப்பு சாயல்களை உணர இயலாமை</string>\n    <string name=\"not_use_color_blind_scheme\">வண்ண குருட்டுத் திட்டத்தைப் பயன்படுத்த வேண்டாம்</string>\n    <string name=\"enhanced_oil\">மேம்படுத்தப்பட்ட எண்ணெய்</string>\n    <string name=\"clahe_jzazbz\">கிளாஏ Jzazbz</string>\n    <string name=\"tones\">டோன்கள்</string>\n    <string name=\"shades\">நிழல்கள்</string>\n    <string name=\"color_mixing\">வண்ண கலவை</string>\n    <string name=\"lut\">Lut</string>\n    <string name=\"save_empty_lut\">நடுநிலை LUT படத்தைப் பெறுங்கள்</string>\n    <string name=\"target_image\">இலக்கு படம்</string>\n    <string name=\"default_draw_path_mode\">இயல்புநிலை டிரா பாதை பயன்முறை</string>\n    <string name=\"add_timestamp\">நேர முத்திரையைச் சேர்க்கவும்</string>\n    <string name=\"edge_mode\">விளிம்பு பயன்முறை</string>\n    <string name=\"color_blind_scheme\">வண்ண குருட்டுத்தன்மை</string>\n    <string name=\"lagrange_2\">லாக்ரேஞ்ச் 2</string>\n    <string name=\"lagrange_3\">லாக்ரேஞ்ச் 3</string>\n    <string name=\"lanczos_6\">லான்சோச் 6</string>\n    <string name=\"lanczos_6_jinc\">லான்சோச் 6 சின்க்</string>\n    <string name=\"lanczos_6_sub\">6 இன் உயர் வரிசையுடன் ஒரு லான்சோச் மறுசீரமைப்பு வடிகட்டியை, கூர்மையான மற்றும் துல்லியமான பட அளவிடுதல் வழங்குகிறது</string>\n    <string name=\"try_again\">மீண்டும் முயற்சிக்கவும்</string>\n    <string name=\"show_settings_in_landscape\">நிலப்பரப்பில் அமைப்புகளைக் காட்டு</string>\n    <string name=\"add_new_folder\">புதிய கோப்புறையைச் சேர்க்கவும்</string>\n    <string name=\"tag_color_space\">வண்ண இடம்</string>\n    <string name=\"tag_gamma\">காமா</string>\n    <string name=\"tag_pixel_x_dimension\">படப்புள்ளி ஃச் பரிமாணம்</string>\n    <string name=\"tag_pixel_y_dimension\">படப்புள்ளி ஒய் பரிமாணம்</string>\n    <string name=\"tag_maker_note\">தயாரிப்பாளர் குறிப்பு</string>\n    <string name=\"tag_subsec_time_digitized\">துணை நொடி நேரம் டிசிட்டல் மயமாக்கப்பட்டது</string>\n    <string name=\"tag_exposure_time\">நேரிடுதல் காலம்</string>\n    <string name=\"tag_aperture_value\">துளை மதிப்பு</string>\n    <string name=\"tag_file_source\">கோப்பு மூல</string>\n    <string name=\"tag_cfa_pattern\">சி.எஃப்.ஏ முறை</string>\n    <string name=\"tag_gain_control\">கட்டுப்பாட்டைப் பெறுங்கள்</string>\n    <string name=\"tag_image_unique_id\">படம் தனித்துவமான ஐடி</string>\n    <string name=\"tag_camera_owner_name\">கேமரா உரிமையாளர் பெயர்</string>\n    <string name=\"tag_body_serial_number\">உடல் வரிசை எண்</string>\n    <string name=\"tag_gps_speed\">சி.பி.எச் விரைவு</string>\n    <string name=\"tag_gps_track_ref\">சி.பி.எச் டிராக் ரெஃப்</string>\n    <string name=\"jxl_type_to_jpeg\">Jxl பெறுநர் jpeg</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL இலிருந்து JPEG க்கு இழப்பற்ற டிரான்ச்கோடிங்கைச் செய்யுங்கள்</string>\n    <string name=\"lanczos4_jinc_sub\">JINC செயல்பாட்டைப் பயன்படுத்தும் லான்சோச் 4 வடிப்பானின் மாறுபாடு, குறைந்தபட்ச கலைப்பொருட்களுடன் உயர்தர இடைக்கணிப்பை வழங்குகிறது</string>\n    <string name=\"ewa_robidoux_sub\">உயர்தர மறுசீரமைப்பிற்கான ராபிடோக்ச் வடிகட்டியின் நீள்வட்ட சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"ewa_blackman_sub\">ரிங்கிங் கலைப்பொருட்களைக் குறைப்பதற்கான பிளாக்மேன் வடிகட்டியின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"ewa_hanning_sub\">மென்மையான இடைக்கணிப்பு மற்றும் மறுசீரமைப்பிற்கான அன்னிங் வடிப்பானின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"ewa_robidoux_sharp\">ராபிடோக்ச் சார்ப் ஈவா</string>\n    <string name=\"ewa_robidoux_sharp_sub\">கூர்மையான முடிவுகளுக்காக ராபிடோக்ச் கூர்மையான வடிப்பானின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"ewa_lanczos3_jinc\">லான்சோச் 3 சின்க் ஈவா</string>\n    <string name=\"ginseng\">குணசிங்கி</string>\n    <string name=\"ginseng_sub\">கூர்மை மற்றும் மென்மையின் நல்ல சமநிலையுடன் உயர்தர பட செயலாக்கத்திற்காக வடிவமைக்கப்பட்ட ஒரு மறுசீரமைப்பு வடிகட்டி</string>\n    <string name=\"ewa_ginseng\">சின்செங் ஈவா</string>\n    <string name=\"ewa_ginseng_sub\">மேம்பட்ட பட தரத்திற்கான சின்செங் வடிகட்டியின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"ewa_lanczos_sharp\">லான்சோச் சார்ப் ஈவா</string>\n    <string name=\"ewa_lanczos_sharp_sub\">குறைந்தபட்ச கலைப்பொருட்களுடன் கூர்மையான முடிவுகளை அடைய லான்சோச் கூர்மையான வடிகட்டியின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"ewa_lanczos_4_sharpest\">லான்சோச் 4 கூர்மையான ஈவா</string>\n    <string name=\"format_conversion\">வடிவமைப்பு மாற்றம்</string>\n    <string name=\"ewa_lanczos_soft_sub\">மென்மையான பட மறுசீரமைப்பிற்கான லான்சோச் மென்மையான வடிகட்டியின் நீள்வட்ட எடை சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"haasn_soft_sub\">மென்மையான மற்றும் கலைப்பொருள் இல்லாத பட அளவிடுதலுக்காக HAASN ஆல் வடிவமைக்கப்பட்ட ஒரு மறுசீரமைப்பு வடிகட்டி</string>\n    <string name=\"dismiss_forever\">என்றென்றும் தள்ளுபடி செய்யுங்கள்</string>\n    <string name=\"image_stacking_sub\">தேர்ந்தெடுக்கப்பட்ட கலப்பு முறைகளுடன் ஒருவருக்கொருவர் மேல் படங்களை அடுக்கி வைக்கவும்</string>\n    <string name=\"clahe_hsl\">கிளாஏ எச்.எச்.எல்</string>\n    <string name=\"clahe_hsv\">கிளாஏ எச்.எச்.வி.</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">இச்டோகிராம் தகவமைப்பு HSV ஐ சமப்படுத்தவும்</string>\n    <string name=\"wrap\">மடக்கு</string>\n    <string name=\"color_blind_scheme_sub\">தேர்ந்தெடுக்கப்பட்ட வண்ண குருட்டுத்தன்மை மாறுபாட்டிற்கான கருப்பொருள் வண்ணங்களை மாற்றியமைக்க பயன்முறையைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"deuteranomaly_sub\">பச்சை மற்றும் சிவப்பு சாயல்களுக்கு இடையில் வேறுபடுவதில் தொல்லை</string>\n    <string name=\"tritanomaly_sub\">நீல மற்றும் மஞ்சள் நிறங்களுக்கு இடையில் வேறுபடுவதில் தொல்லை</string>\n    <string name=\"deuteranopia_sub\">பச்சை நிறங்களை உணர இயலாமை</string>\n    <string name=\"tritanopia_sub\">நீல நிற சாயல்களை உணர இயலாமை</string>\n    <string name=\"achromatomaly_sub\">எல்லா வண்ணங்களுக்கும் உணர்திறன் குறைக்கப்பட்டுள்ளது</string>\n    <string name=\"lagrange_3_sub\">ஆர்டர் 3 இன் லாக்ரேஞ்ச் இடைக்கணிப்பு வடிகட்டி, பட அளவிடுதலுக்கான சிறந்த துல்லியம் மற்றும் மென்மையான முடிவுகளை வழங்குகிறது</string>\n    <string name=\"lanczos_6_jinc_sub\">மேம்பட்ட பட மறுசீரமைப்பு தரத்திற்காக JINC செயல்பாட்டைப் பயன்படுத்தி லான்சோச் 6 வடிகட்டியின் மாறுபாடு</string>\n    <string name=\"linear_box_blur\">நேரியல் பெட்டி மங்கலானது</string>\n    <string name=\"linear_tent_blur\">நேரியல் கூடாரம் மங்கலானது</string>\n    <string name=\"linear_gaussian_box_blur\">நேரியல் காசியன் பெட்டி மங்கலானது</string>\n    <string name=\"linear_stack_blur\">நேரியல் அடுக்கு மங்கலானது</string>\n    <string name=\"gaussian_box_blur\">காசியன் பெட்டி மங்கலானது</string>\n    <string name=\"linear_fast_gaussian_blur_next\">நேரியல் ஃபாச்ட் காசியன் அடுத்து மங்கலானது</string>\n    <string name=\"linear_fast_gaussian_blur\">நேரியல் ஃபாச்ட் காசியன் மங்கலானது</string>\n    <string name=\"linear_gaussian_blur\">நேரியல் காசியன் மங்கலானது</string>\n    <string name=\"draw_filter_sub\">வண்ணப்பூச்சாகப் பயன்படுத்த ஒரு வடிப்பானைத் தேர்வுசெய்க</string>\n    <string name=\"replace_filter\">வடிகட்டியை மாற்றவும்</string>\n    <string name=\"pick_filter_info\">உங்கள் வரைபடத்தில் அதை தூரிகையாகப் பயன்படுத்த கீழே உள்ள வடிகட்டியைத் தேர்ந்தெடுங்கள்</string>\n    <string name=\"tiff_compression_scheme\">TIFF சுருக்க திட்டம்</string>\n    <string name=\"low_poly\">குறைந்த பாலி</string>\n    <string name=\"sand_painting\">மணல் ஓவியம்</string>\n    <string name=\"confetti_type\">கான்ஃபெட்டி வகை</string>\n    <string name=\"festive\">பண்டிகை</string>\n    <string name=\"explode\">வெடிக்கும்</string>\n    <string name=\"rain\">மழை</string>\n    <string name=\"corners\">மூலைகள்</string>\n    <string name=\"jxl_tools\">JXL கருவிகள்</string>\n    <string name=\"fit_to_bounds\">எல்லைக்கு பொருந்தும்</string>\n    <string name=\"backup_ocr_models\">காப்புப்பிரதி OCR மாதிரிகள்</string>\n    <string name=\"jxl_tools_sub\">தர இழப்பு இல்லாமல் JXL ~ JPEG டிரான்ச்கோடிங்கைச் செய்யுங்கள், அல்லது GIF/APNG ஐ JXL அனிமேசனாக மாற்றவும்</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG இலிருந்து JXL க்கு இழப்பற்ற டிரான்ச்கோடிங்கைச் செய்யுங்கள்</string>\n    <string name=\"jpeg_type_to_jxl\">Jpeg பெறுநர் jxl</string>\n    <string name=\"select_jxl_image_to_start\">தொடங்க JXL படத்தைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"fast_gaussian_blur_2d\">ஃபாச்ட் காசியன் மங்கலான 2 டி</string>\n    <string name=\"fast_gaussian_blur_3d\">ஃபாச்ட் காசியன் மங்கலான 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">ஃபாச்ட் காசியன் மங்கலான 4 டி</string>\n    <string name=\"auto_paste_sub\">இடைநிலைப்பலகை தரவை தானாக பேச்ட் செய்ய பயன்பாட்டை அனுமதிக்கிறது, எனவே இது முதன்மையான திரையில் தோன்றும், மேலும் நீங்கள் அதை செயலாக்க முடியும்</string>\n    <string name=\"lanczos_bessel\">லான்சோச் பெசெல்</string>\n    <string name=\"no_favorite_options_selected\">பிடித்த விருப்பங்கள் எதுவும் தேர்ந்தெடுக்கப்படவில்லை, அவற்றை கருவிகள் பக்கத்தில் சேர்க்கவும்</string>\n    <string name=\"add_favorites\">பிடித்தவைகளைச் சேர்க்கவும்</string>\n    <string name=\"harmony_complementary\">நிரப்பு</string>\n    <string name=\"harmony_analogous\">ஒப்பீட்டு</string>\n    <string name=\"harmony_triadic\">முக்கோண</string>\n    <string name=\"harmony_split_complementary\">நிறைவு</string>\n    <string name=\"harmony_square\">நாற்கை</string>\n    <string name=\"harmony_analogous_complementary\">ஒப்புமை + நிரப்பு</string>\n    <string name=\"color_tools\">வண்ண கருவிகள்</string>\n    <string name=\"color_tools_sub\">கலக்கவும், டோன்களை உருவாக்கவும், நிழல்களை உருவாக்கவும்</string>\n    <string name=\"color_harmonies\">வண்ண இணக்கங்கள்</string>\n    <string name=\"color_shading\">வண்ண நிழல்</string>\n    <string name=\"variation\">மாறுபாடு</string>\n    <string name=\"color_info\">வண்ண செய்தி</string>\n    <string name=\"selected_color\">தேர்ந்தெடுக்கப்பட்ட நிறம்</string>\n    <string name=\"color_to_mix\">கலக்க நிறம்</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">மாறும் வண்ணங்கள் இயக்கப்படும் போது மோனெட்டைப் பயன்படுத்த முடியாது</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">இலக்கு LUT படம்</string>\n    <string name=\"amatorka\">அமேட்டர்</string>\n    <string name=\"miss_etikate\">மிச் நெறிமுறைகள்</string>\n    <string name=\"soft_elegance\">மென்மையான நேர்த்தியானது</string>\n    <string name=\"soft_elegance_variant\">மென்மையான நேர்த்தியான மாறுபாடு</string>\n    <string name=\"palette_transfer_variant\">தட்டு பரிமாற்ற மாறுபாடு</string>\n    <string name=\"cube_lut\">வார்டு</string>\n    <string name=\"bleach_bypass\">ப்ளீச் பைபாச்</string>\n    <string name=\"film_stock_50\">ஃபிலிம் ச்டாக் 50</string>\n    <string name=\"candlelight\">மெழுகுவர்த்தி</string>\n    <string name=\"drop_blues\">ப்ளூச் கைவிடவும்</string>\n    <string name=\"kodak\">கோடக்</string>\n    <string name=\"enable_timestamps_to_format_them\">நேர முத்திரைகள் அவற்றின் வடிவமைப்பைத் தேர்ந்தெடுக்க இயக்கவும்</string>\n    <string name=\"one_time_save_location\">ஒரு முறை இருப்பிடத்தை சேமிக்கவும்</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">இந்த முறையைப் பின்பற்றி விருப்பங்கள் உள்ளிடப்பட வேண்டும்: \\\"-{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">வாகன பயிர்</string>\n    <string name=\"free_corners\">இலவச மூலைகள்</string>\n    <string name=\"free_corners_sub\">பலகோணத்தால் பயிர் படம், இது முன்னோக்கையும் சரிசெய்கிறது</string>\n    <string name=\"coerce_points_to_image_bounds\">பட எல்லைகளை CORCE சுட்டிக்காட்டுகிறது</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">பட வரம்புகளால் புள்ளிகள் மட்டுப்படுத்தப்படாது, இது மிகவும் துல்லியமான முன்னோக்குக்கு பயனுள்ளதாக இருக்கும்</string>\n    <string name=\"mask\">மறைப்பு</string>\n    <string name=\"spot_heal_sub\">உள்ளடக்க விழிப்புணர்வு வரையப்பட்ட பாதையின் கீழ் நிரப்பு</string>\n    <string name=\"spot_heal\">இடத்தை குணப்படுத்துங்கள்</string>\n    <string name=\"use_circle_kernel\">வட்டம் கர்னலைப் பயன்படுத்தவும்</string>\n    <string name=\"opening\">திறப்பு</string>\n    <string name=\"closing\">நிறைவு</string>\n    <string name=\"morphological_gradient\">உருவவியல் சாய்வு</string>\n    <string name=\"top_hat\">மேல் தொப்பி</string>\n    <string name=\"black_hat\">கருப்பு தொப்பி</string>\n    <string name=\"tone_curves\">தொனி வளைவுகள்</string>\n    <string name=\"reset_curves\">வளைவுகளை மீட்டமைக்கவும்</string>\n    <string name=\"reset_curves_sub\">வளைவுகள் இயல்புநிலை மதிப்புக்கு மீண்டும் உருட்டப்படும்</string>\n    <string name=\"stamped\">முத்திரையிடப்பட்டது</string>\n    <string name=\"gap_size\">இடைவெளி அளவு</string>\n    <string name=\"dot_dashed\">புள்ளி கோடு</string>\n    <string name=\"dot_dashed_sub\">கொடுக்கப்பட்ட பாதையில் புள்ளி மற்றும் கோடு கோட்டை ஈர்க்கிறது</string>\n    <string name=\"zigzag_sub\">அலை அலையான சிக்சாக் பாதையில் ஈர்க்கிறது</string>\n    <string name=\"create_shortcut\">குறுக்குவழியை உருவாக்கவும்</string>\n    <string name=\"create_shortcut_title\">முள் செய்ய கருவியைத் தேர்வுசெய்க</string>\n    <string name=\"lanczos_bessel_sub\">படப்புள்ளி மதிப்புகளுக்கு பெசல் (சின்க்) செயல்பாட்டைப் பயன்படுத்துவதன் மூலம் உயர்தர இடைக்கணிப்பை பராமரிக்கும் மறுசீரமைப்பு முறை</string>\n    <string name=\"gif_type_to_jxl\">Gif பெறுநர் jxl</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF படங்களை JXL அனிமேசன் படங்களாக மாற்றவும்</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG படங்களை JXL அனிமேசன் படங்களாக மாற்றவும்</string>\n    <string name=\"jxl_type_to_images\">படங்களுக்கு jxl</string>\n    <string name=\"jxl_type_to_images_sub\">JXL அனிமேசனை தொகுதி படங்களாக மாற்றவும்</string>\n    <string name=\"jxl_type_to_jxl\">படங்கள் JXL க்கு</string>\n    <string name=\"jxl_type_to_jxl_sub\">படங்களின் தொகுப்பை JXL அனிமேசனாக மாற்றவும்</string>\n    <string name=\"behavior\">நடத்தை</string>\n    <string name=\"skip_file_picking\">கோப்பு எடுப்பதைத் தவிர்க்கவும்</string>\n    <string name=\"skip_file_picking_sub\">தேர்ந்தெடுக்கப்பட்ட திரையில் இது முடிந்தால் கோப்பு எடுப்பவர் உடனடியாக காண்பிக்கப்படும்</string>\n    <string name=\"generate_previews\">முன்னோட்டங்களை உருவாக்கவும்</string>\n    <string name=\"generate_previews_sub\">முன்னோட்ட தலைமுறையை இயக்கவும், இது சில சாதனங்களில் விபத்துக்களைத் தவிர்க்க உதவக்கூடும், இது ஒற்றை திருத்து விருப்பத்திற்குள் சில திருத்துதல் செயல்பாடுகளையும் முடக்கியது</string>\n    <string name=\"lossy_compression\">இழப்பு சுருக்க</string>\n    <string name=\"lossy_compression_sub\">இழப்பற்ற தன்மைக்கு பதிலாக கோப்பு அளவைக் குறைக்க இழப்பு சுருக்கத்தைப் பயன்படுத்துகிறது</string>\n    <string name=\"tag_metering_mode\">அளவீட்டு முறை</string>\n    <string name=\"tag_flash\">ஃபிளாச்</string>\n    <string name=\"tag_focal_length\">குவிநீளம், குவியத் தொலைவு</string>\n    <string name=\"tag_flash_energy\">ஃபிளாச் ஆற்றல்</string>\n    <string name=\"tag_spatial_frequency_response\">இடஞ்சார்ந்த அதிர்வெண் பதில்</string>\n    <string name=\"tag_focal_plane_x_resolution\">குவிய வானூர்தி ஃச் தீர்மானம்</string>\n    <string name=\"tag_focal_plane_y_resolution\">குவிய வானூர்தி ஒய் தீர்மானம்</string>\n    <string name=\"tag_focal_plane_resolution_unit\">குவிய வானூர்தி தீர்மானம் பிரிவு</string>\n    <string name=\"tag_subject_location\">பொருள் இடம்</string>\n    <string name=\"tag_exposure_index\">வெளிப்பாடு அட்டவணை</string>\n    <string name=\"tag_scene_capture_type\">காட்சி பிடிப்பு வகை</string>\n    <string name=\"tag_contrast\">மாறுபாடு</string>\n    <string name=\"tag_saturation\">தெவிட்டல்</string>\n    <string name=\"tag_sharpness\">கூர்மையானது</string>\n    <string name=\"tag_device_setting_description\">சாதன அமைப்பு விளக்கம்</string>\n    <string name=\"tag_subject_distance_range\">பொருள் தூர வரம்பு</string>\n    <string name=\"tag_lens_specification\">லென்ச் விவரக்குறிப்பு</string>\n    <string name=\"tag_lens_make\">லென்ச் செய்யுங்கள்</string>\n    <string name=\"tag_lens_model\">லென்ச் மாதிரி</string>\n    <string name=\"tag_lens_serial_number\">லென்ச் வரிசை எண்</string>\n    <string name=\"tag_gps_version_id\">சி.பி.எச் பதிப்பு ஐடி</string>\n    <string name=\"tag_gps_latitude_ref\">சி.பி.எச் அட்சரேகை குறிப்பு</string>\n    <string name=\"tag_gps_longitude_ref\">சி.பி.எச் தீர்க்கரேகை குறிப்பு</string>\n    <string name=\"tag_gps_altitude\">சி.பி.எச் உயரம்</string>\n    <string name=\"tag_gps_timestamp\">சி.பி.எச் நேர முத்திரை</string>\n    <string name=\"tag_gps_latitude\">சி.பி.எச் அட்சரேகை</string>\n    <string name=\"tag_gps_satellites\">சி.பி.எச் செயற்கைக்கோள்கள்</string>\n    <string name=\"tag_gps_status\">சி.பி.எச் நிலை</string>\n    <string name=\"tag_gps_measure_mode\">சி.பி.எச் அளவீட்டு முறை</string>\n    <string name=\"tag_gps_speed_ref\">சி.பி.எச் விரைவு குறிப்பு</string>\n    <string name=\"tag_gps_track\">சி.பி.எச் டிராக்</string>\n    <string name=\"tag_gps_img_direction_ref\">சி.பி.எச் ஐ.எம்.சி திசை குறிப்பு</string>\n    <string name=\"tag_gps_img_direction\">சி.பி.எச் ஐ.எம்.சி திசை</string>\n    <string name=\"tag_gps_map_datum\">சி.பி.எச் வரைபட தரவு</string>\n    <string name=\"tag_gps_dest_latitude_ref\">சி.பி.எச்</string>\n    <string name=\"tag_gps_dest_latitude\">சி.பி.எச் டெச்ட் அட்சரேகை</string>\n    <string name=\"tag_gps_dest_longitude_ref\">சி.பி.எச்</string>\n    <string name=\"tag_gps_dest_longitude\">சி.பி.எச்</string>\n    <string name=\"tag_gps_dest_bearing_ref\">சி.பி.எச் டெச்ட் தாங்கி ref</string>\n    <string name=\"tag_gps_dest_distance\">சி.பி.எச்</string>\n    <string name=\"tag_gps_processing_method\">சி.பி.எச் செயலாக்க முறை</string>\n    <string name=\"tag_gps_area_information\">சி.பி.எச் பகுதி செய்தி</string>\n    <string name=\"tag_gps_dest_bearing\">சி.பி.எச் டெச்ட் தாங்கி</string>\n    <string name=\"tag_gps_dest_distance_ref\">சி.பி.எச்</string>\n    <string name=\"tag_gps_datestamp\">சி.பி.எச் தேதி முத்திரை</string>\n    <string name=\"tag_gps_differential\">சி.பி.எச் வேறுபாடு</string>\n    <string name=\"tag_gps_h_positioning_error\">சி.பி.எச் எச் பொருத்துதல் பிழை</string>\n    <string name=\"tag_interoperability_index\">இயங்குதன்மை குறியீடு</string>\n    <string name=\"tag_dng_version\">டி.என்.சி பதிப்பு</string>\n    <string name=\"tag_default_crop_size\">இயல்புநிலை பயிர் அளவு</string>\n    <string name=\"tag_orf_aspect_frame\">அம்ச சட்டகம்</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">சென்சார் கீழ் எல்லை</string>\n    <string name=\"tag_rw2_sensor_left_border\">சென்சார் இடது எல்லை</string>\n    <string name=\"tag_rw2_sensor_right_border\">சென்சார் வலது எல்லை</string>\n    <string name=\"tag_rw2_sensor_top_border\">சென்சார் மேல் எல்லை</string>\n    <string name=\"tag_rw2_iso\">ஐசோ</string>\n    <string name=\"dont_stack_frames\">பிரேம்களை அடுக்கி வைக்க வேண்டாம்</string>\n    <string name=\"crossfade\">கிராச்ஃபேட்</string>\n    <string name=\"crossfade_sub\">பிரேம்கள் ஒருவருக்கொருவர் குறுக்குவெட்டு செய்யப்படும்</string>\n    <string name=\"crossfade_count\">கிராச்ஃபேட் பிரேம்கள் எண்ணிக்கை</string>\n    <string name=\"threshold_one\">வாசல் ஒன்று</string>\n    <string name=\"threshold_two\">வாசல் இரண்டு</string>\n    <string name=\"mirror_101\">மிரர் 101</string>\n    <string name=\"font_size\">எழுத்துரு அளவு</string>\n    <string name=\"watermark_size\">வாட்டர்மார்க் அளவு</string>\n    <string name=\"repeat_text\">உரையை மீண்டும் செய்யவும்</string>\n    <string name=\"repeat_text_sub\">தற்போதைய உரை ஒரு முறை வரைபடத்திற்கு பதிலாகப் பாதை முடியும் வரை மறுநிகழ்வு செய்யப்படும்</string>\n    <string name=\"draw_mode_image_sub\">கொடுக்கப்பட்ட பாதையில் அதை வரைய தேர்ந்தெடுக்கப்பட்ட படத்தைப் பயன்படுத்தவும்</string>\n    <string name=\"draw_text_sub\">கொடுக்கப்பட்ட எழுத்துரு மற்றும் வண்ணத்துடன் பாதையில் உரையை வரையவும்</string>\n    <string name=\"enhanced_zoom_blur\">மேம்படுத்தப்பட்ட சூம் மங்கலானது</string>\n    <string name=\"laplacian_simple\">லாப்லாசியன் எளிமையானது</string>\n    <string name=\"sobel_simple\">சோபல் எளிமையானது</string>\n    <string name=\"helper_grid\">உதவி கட்டம்</string>\n    <string name=\"draw_image_sub\">இந்தப் படம் வரையப்பட்ட பாதையின் மறுநிகழ்வு நுழைவாகப் பயன்படுத்தப்படும்</string>\n    <string name=\"outlined_triangle_sub\">தொடக்க புள்ளியிலிருந்து இறுதி புள்ளி வரை கோடிட்டுள்ள முக்கோணத்தை ஈர்க்கிறது</string>\n    <string name=\"triangle_sub\">தொடக்க புள்ளியிலிருந்து இறுதி புள்ளி வரை கோடிட்டுள்ள முக்கோணத்தை ஈர்க்கிறது</string>\n    <string name=\"outlined_triangle\">கோடிட்டுக் காட்டப்பட்ட முக்கோணம்</string>\n    <string name=\"polygon_sub\">தொடக்க புள்ளியில் இருந்து இறுதி புள்ளி வரை பலகோணத்தை ஈர்க்கிறது</string>\n    <string name=\"polygon\">பலகோணம்</string>\n    <string name=\"vertices\">செங்குத்துகள்</string>\n    <string name=\"outlined_polygon_sub\">தொடக்க புள்ளியிலிருந்து இறுதி புள்ளி வரை அவுட்லைன் பலகோணத்தை வரையவும்</string>\n    <string name=\"draw_regular_polygon\">வழக்கமான பலகோணத்தை வரையவும்</string>\n    <string name=\"draw_regular_polygon_sub\">இலவச படிவத்திற்கு பதிலாக வழக்கமானதாக இருக்கும் பலகோணத்தை வரையவும்</string>\n    <string name=\"star_sub\">தொடக்க புள்ளியிலிருந்து இறுதி புள்ளி வரை நட்சத்திரத்தை ஈர்க்கிறது</string>\n    <string name=\"star\">விண்மீன்</string>\n    <string name=\"outlined_star\">கோடிட்டுக் காட்டப்பட்ட விண்மீன்</string>\n    <string name=\"outlined_star_sub\">தொடக்க புள்ளியிலிருந்து இறுதி புள்ளி வரை கோடிட்ட நட்சத்திரத்தை ஈர்க்கிறது</string>\n    <string name=\"inner_radius_ratio\">உள் ஆரம் விகிதம்</string>\n    <string name=\"document_scanner_sub\">ஆவணங்களை ச்கேன் செய்து அவற்றிலிருந்து PDF அல்லது தனி படங்களை உருவாக்கவும்</string>\n    <string name=\"click_to_start_scanning\">ச்கேனிங் தொடங்க சொடுக்கு செய்க</string>\n    <string name=\"options_below_is_for_images\">கீழே உள்ள விருப்பங்கள் PDF அல்ல, படங்களை சேமிப்பதற்காக</string>\n    <string name=\"equalize_histogram_hsv\">இச்டோகிராம் எச்.எச்.வி.</string>\n    <string name=\"equalize_histogram\">இச்டோகிராம் சமப்படுத்தவும்</string>\n    <string name=\"enter_percentage\">சதவீதத்தை உள்ளிடவும்</string>\n    <string name=\"allow_enter_by_text_field\">உரை புலத்தால் உள்ளிட அனுமதிக்கவும்</string>\n    <string name=\"allow_enter_by_text_field_sub\">முன்னமைவுகள் தேர்வுக்கு பின்னால் உரை புலத்தை செயல்படுத்துகிறது, அவற்றை பறக்கும்போது உள்ளிடவும்</string>\n    <string name=\"scale_color_space\">அளவிலான வண்ண இடம்</string>\n    <string name=\"linear\">நேரியல்</string>\n    <string name=\"grid_size_x\">கட்டம் அளவு ஃச்</string>\n    <string name=\"equalize_histogram_pixelation\">இச்டோகிராம் பிக்சலேசனை சமப்படுத்தவும்</string>\n    <string name=\"grid_size_y\">கட்டம் அளவு ஒய்</string>\n    <string name=\"equalize_histogram_adaptive\">இச்டோகிராம் தகவமைப்பை சமப்படுத்தவும்</string>\n    <string name=\"equalize_histogram_adaptive_luv\">இச்டோகிராம் தகவமைப்பு LUV ஐ சமப்படுத்தவும்</string>\n    <string name=\"equalize_histogram_adaptive_lab\">இச்டோகிராம் தகவமைப்பு ஆய்வகத்தை சமப்படுத்தவும்</string>\n    <string name=\"clahe_lab\">கிளாஏ ஆய்வகம்</string>\n    <string name=\"clahe_luv\">கிளாஏ லவ்</string>\n    <string name=\"color_to_ignore\">புறக்கணிக்க வண்ணம்</string>\n    <string name=\"opened_file_have_no_filter_template\">தேர்ந்தெடுக்கப்பட்ட கோப்பில் வடிகட்டி வார்ப்புரு தரவு இல்லை</string>\n    <string name=\"create_template\">வார்ப்புருவை உருவாக்கவும்</string>\n    <string name=\"template_name\">வார்ப்புரு பெயர்</string>\n    <string name=\"select_template_preview\">இந்த வடிகட்டி வார்ப்புருவை முன்னோட்டமிட இந்த படம் பயன்படுத்தப்படும்</string>\n    <string name=\"as_qr_code\">QR குறியீடு படமாக</string>\n    <string name=\"save_as_file\">கோப்பாக சேமிக்கவும்</string>\n    <string name=\"save_as_qr_code_image\">QR குறியீடு படமாக சேமிக்கவும்</string>\n    <string name=\"delete_template\">வார்ப்புருவை நீக்கு</string>\n    <string name=\"delete_template_warn\">நீங்கள் தேர்ந்தெடுக்கப்பட்ட வார்ப்புரு வடிப்பானை நீக்க உள்ளீர்கள். இந்த செயல்பாட்டை செயல்தவிர்க்க முடியாது</string>\n    <string name=\"blackman\">பிளாக்மேன்</string>\n    <string name=\"welch\">வெல்ச்</string>\n    <string name=\"quadric\">குவாட்ரிக்</string>\n    <string name=\"gaussian\">காசியன்</string>\n    <string name=\"sphinx\">சூரரிமாச்சிலை</string>\n    <string name=\"bartlett\">பார்ட்லெட்</string>\n    <string name=\"robidoux\">ராபிடோக்ச்</string>\n    <string name=\"robidoux_sharp\">ராபிடோக்ச் சார்ப்</string>\n    <string name=\"spline16\">ச்ப்லைன் 16</string>\n    <string name=\"spline36\">ச்ப்லைன் 36</string>\n    <string name=\"lanczos2_jinc\">லான்சோச் 2 சின்க்</string>\n    <string name=\"helper_grid_sub\">துல்லியமான கையாளுதல்களுக்கு உதவுவதற்காக வரைதல் பகுதிக்கு மேலே துணை கட்டத்தைக் காட்டுகிறது</string>\n    <string name=\"grid_color\">கட்டம் நிறம்</string>\n    <string name=\"cell_width\">செல் அகலம்</string>\n    <string name=\"cell_height\">செல் உயரம்</string>\n    <string name=\"compact_selectors_sub\">சில தேர்வுக் கட்டுப்பாடுகள் குறைந்த இடத்தை எடுக்க ஒரு சிறிய தளவமைப்பைப் பயன்படுத்தும்</string>\n    <string name=\"grant_camera_permission_to_capture_image\">படத்தைப் பிடிக்க அமைப்புகளில் கேமரா இசைவு வழங்கவும்</string>\n    <string name=\"layout\">மனையமைவு</string>\n    <string name=\"constant_rate_factor\">நிலையான வீத காரணி (சிஆர்எஃப்)</string>\n    <string name=\"crf_sub\">%1$s இன் மதிப்பு மெதுவான சுருக்கத்தைக் குறிக்கிறது, இதன் விளைவாக ஒப்பீட்டளவில் சிறிய கோப்பு அளவு ஏற்படுகிறது. %2$s என்பது வேகமான சுருக்கத்தைக் குறிக்கிறது, இதன் விளைவாக ஒரு பெரிய கோப்பு.</string>\n    <string name=\"lut_library\">LUT நூலகம்</string>\n    <string name=\"main_screen_title\">முதன்மையான திரை தலைப்பு</string>\n    <string name=\"lut_library_sub\">பதிவிறக்கிய பிறகு நீங்கள் விண்ணப்பிக்கக்கூடிய LUTS இன் சேகரிப்பைப் பதிவிறக்குக</string>\n    <string name=\"lut_library_update_sub\">LUTS இன் புதுப்பிப்பு சேகரிப்பு (புதியவை மட்டுமே வரிசையில் நிற்கப்படும்), பதிவிறக்கம் செய்த பிறகு நீங்கள் விண்ணப்பிக்கலாம்</string>\n    <string name=\"hide\">மறை</string>\n    <string name=\"show\">காட்டு</string>\n    <string name=\"filter_preview_image_sub\">வடிப்பான்களுக்கான இயல்புநிலை பட முன்னோட்டத்தை மாற்றவும்</string>\n    <string name=\"filter_preview_image\">படம் முன்னோட்டம்</string>\n    <string name=\"slider_type\">ச்லைடர் வகை</string>\n    <string name=\"material_2\">பொருள் 2</string>\n    <string name=\"fancy_sub\">ஒரு ஆடம்பரமான தோற்றமுடைய ச்லைடர். இது இயல்புநிலை விருப்பம்</string>\n    <string name=\"material_2_sub\">ஒரு பொருள் 2 ச்லைடர்</string>\n    <string name=\"material_you_slider_sub\">நீங்கள் ச்லைடர் ஒரு பொருள்</string>\n    <string name=\"apply\">இடு</string>\n    <string name=\"center_align_dialog_buttons\">மைய உரையாடல் பொத்தான்கள்</string>\n    <string name=\"center_align_dialog_buttons_sub\">முடிந்தால் இடது பக்கத்திற்கு பதிலாக உரையாடல்களின் பொத்தான்கள் மையத்தில் நிலைநிறுத்தப்படும்</string>\n    <string name=\"open_source_licenses\">திறந்த மூல உரிமங்கள்</string>\n    <string name=\"open_source_licenses_sub\">இந்த பயன்பாட்டில் பயன்படுத்தப்படும் திறந்த மூல நூலகங்களின் உரிமங்களைக் காண்க</string>\n    <string name=\"box\">பெட்டி</string>\n    <string name=\"lanczos2\">லான்சோச் 2</string>\n    <string name=\"lanczos3\">லான்சோச் 3</string>\n    <string name=\"lanczos4\">லான்சோச் 4</string>\n    <string name=\"cubic_sub\">க்யூபிக் இடைக்கணிப்பு மிக நெருக்கமான 16 பிக்சல்களைக் கருத்தில் கொண்டு மென்மையான அளவை வழங்குகிறது, இது பிலினியரை விட சிறந்த முடிவுகளை அளிக்கிறது</string>\n    <string name=\"welch_sub\">குறைக்கப்பட்ட நிறமாலை கசிவுடன் நல்ல அதிர்வெண் தெளிவுத்திறனைக் கொடுக்க வடிவமைக்கப்பட்ட ஒரு சாளர செயல்பாடு, பெரும்பாலும் சமிக்ஞை செயலாக்க பயன்பாடுகளில் பயன்படுத்தப்படுகிறது</string>\n    <string name=\"quadric_sub\">இடைக்கணிப்புக்கு இருபடி செயல்பாட்டைப் பயன்படுத்தும் ஒரு முறை, மென்மையான மற்றும் தொடர்ச்சியான முடிவுகளை வழங்கும்</string>\n    <string name=\"robidoux_sharp_sub\">ராபிடோக்ச் முறையின் கூர்மையான மாறுபாடு, மிருதுவான பட மறுஅளவிடுவதற்கு உகந்ததாகும்</string>\n    <string name=\"no_permissions\">அனுமதிகள் இல்லை</string>\n    <string name=\"images_to_svg\">எச்.வி.சி.க்கு படங்கள்</string>\n    <string name=\"tag_user_comment\">பயனர் கருத்து</string>\n    <string name=\"tag_subject_area\">பொருள் பகுதி</string>\n    <string name=\"tag_gps_dop\">சி.பி.எச் டாப்</string>\n    <string name=\"tag_orf_preview_image_length\">பட நீளத்தை முன்னோட்டமிடுங்கள்</string>\n    <string name=\"dash_size\">கோடு அளவு</string>\n    <string name=\"outlined_polygon\">கோடிட்டுள்ள பலகோணம்</string>\n    <string name=\"share_as_pdf\">PDF ஆக பகிரவும்</string>\n    <string name=\"crop_to_content\">உள்ளடக்கத்திற்கு பயிர்</string>\n    <string name=\"as_file\">கோப்பாக</string>\n    <string name=\"spline64\">ச்ப்லைன் 64</string>\n    <string name=\"bartlett_hann\">பார்ட்லெட் - அவர்</string>\n    <string name=\"haasn_soft\">Haasn மென்மையான</string>\n    <string name=\"sigmoidal\">சிக்மாய்டல்</string>\n    <string name=\"tints\">சாயல்கள்</string>\n    <string name=\"target_cube_lut_file\">இலக்கு 3D LUT கோப்பு (.cube / .cube)</string>\n    <string name=\"zigzag_ratio\">சிக்சாக் விகிதம்</string>\n    <string name=\"apng_type_to_jxl\">Apng பெறுநர் jxl</string>\n    <string name=\"code_content\">குறியீடு உள்ளடக்கம்</string>\n    <string name=\"foggy_night\">மூடுபனி இரவு</string>\n    <string name=\"zigzag\">சிக்சாக்</string>\n    <string name=\"coordinates_rounding_tolerance\">வட்டமான சகிப்புத்தன்மையை ஒருங்கிணைக்கிறது</string>\n    <string name=\"tag_brightness_value\">பிரகாசமான மதிப்பு</string>\n    <string name=\"tag_offset_time_digitized\">ஆஃப்செட் நேரம் டிசிட்டல் மயமாக்கப்பட்டது</string>\n    <string name=\"saved_to_custom\">தனிப்பயன் பெயருடன் கோப்புறையில் சேமிக்கப்பட்டது</string>\n    <string name=\"tag_gps_altitude_ref\">சி.பி.எச் உயரம் குறிப்பு</string>\n    <string name=\"tag_x_resolution\">ஃச் தீர்மானம்</string>\n    <string name=\"frame_color\">சட்ட நிறம்</string>\n    <string name=\"ewa_hanning\">ஆன் நிங் இ வா</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">லான்சோச் 3 சின்க் வடிகட்டியின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு குறைக்கப்பட்ட மாற்றியுடன் உயர்தர மறுசீரமைப்பிற்கு</string>\n    <string name=\"convert_sub\">கொடுக்கப்பட்ட வடிவத்திற்கு பட தொகுதிகளை மாற்றவும்</string>\n    <string name=\"header_yesterday\">நேற்று</string>\n    <string name=\"stamped_sub\">குறிப்பிட்ட இடைவெளியுடன் பாதையில் தேர்ந்தெடுக்கப்பட்ட வடிவங்களை ஈர்க்கிறது</string>\n    <string name=\"fancy\">ஆடம்பரமான</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">இச்டோகிராம் தகவமைப்பு HSL ஐ சமப்படுத்தவும்</string>\n    <string name=\"tag_gps_longitude\">சி.பி.எச் தீர்க்கரேகை</string>\n    <string name=\"harmony_tetradic\">டெட்ராடிக்</string>\n    <string name=\"start_scanning\">ச்கேன் செய்யத் தொடங்குங்கள்</string>\n    <string name=\"links_preview\">இணைப்புகள் முன்னோட்டம்</string>\n    <string name=\"ewa_quadric_sub\">மென்மையான இடைக்கணிப்புக்கான குவாட்ரிக் வடிகட்டியின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு</string>\n    <string name=\"image_stacking\">பட அடுக்கு</string>\n    <string name=\"request\">கோரிக்கை</string>\n    <string name=\"quadratic_threshold\">இருபடி வாசல்</string>\n    <string name=\"compression_type\">சுருக்க வகை</string>\n    <string name=\"default_line_width\">இயல்புநிலை வரி அகலம்</string>\n    <string name=\"image_splitting\">பட பிரித்தல்</string>\n    <string name=\"image_splitting_sub\">வரிசைகள் அல்லது நெடுவரிசைகளால் ஒற்றை படத்தை பிரிக்கவும்</string>\n    <string name=\"compose\">எழுதுங்கள்</string>\n    <string name=\"fluent_switch\">சரளமாக</string>\n    <string name=\"yililoma_dithering\">யிலிலோமா டிட்டரிங்</string>\n    <string name=\"tag_orf_preview_image_start\">முன்னோட்டம் படத் தொடங்கு</string>\n    <string name=\"area\">பகுதி</string>\n    <string name=\"clahe\">கிளாஏ</string>\n    <string name=\"engine_mode\">எஞ்சின் பயன்முறை</string>\n    <string name=\"fit_description\">கொடுக்கப்பட்ட பரிமாணங்களுக்கு ஒரு படத்தைப் பொருத்தி, பின்னணியில் மங்கல அல்லது வண்ணத்தைப் பயன்படுத்துங்கள்</string>\n    <string name=\"tools_arrangement\">கருவிகள் ஏற்பாடு</string>\n    <string name=\"group_tools_by_type\">வகை மூலம் குழு கருவிகள்</string>\n    <string name=\"hide_all\">அனைத்தையும் மறைக்கவும்</string>\n    <string name=\"show_all\">அனைத்தையும் காட்டு</string>\n    <string name=\"hide_nav_bar\">NAV பட்டியை மறைக்கவும்</string>\n    <string name=\"hide_status_bar\">நிலை பட்டியை மறைக்கவும்</string>\n    <string name=\"ping_pong_strength\">பிங் பாங் வலிமை</string>\n    <string name=\"distance_function\">தூர செயல்பாடு</string>\n    <string name=\"return_type\">திரும்ப வகை</string>\n    <string name=\"jitter\">நடுக்கம்</string>\n    <string name=\"domain_warp\">டொமைன் வார்ப்</string>\n    <string name=\"line_style\">வரி நடை</string>\n    <string name=\"dashed_sub\">குறிப்பிட்ட இடைவெளி அளவுடன் வரையப்பட்ட பாதையில் விடுபட்ட கோடு வரைதல்</string>\n    <string name=\"defaultt_sub\">இயல்புநிலை நேர் கோடுகள்</string>\n    <string name=\"fit_to_bounds_sub\">பயிர் மறுசீரமைப்பு பயன்முறையை இந்த அளவுருவுடன் இணைக்க விரும்பிய நடத்தை (பயிர்/அம்ச விகிதத்திற்கு பொருத்தம்)</string>\n    <string name=\"languages_imported\">மொழிகள் வெற்றிகரமாக இறக்குமதி செய்யப்பட்டன</string>\n    <string name=\"import_word\">இறக்குமதி</string>\n    <string name=\"checksum_as_filename_sub\">வெளியீட்டு படங்களுக்கு அவற்றின் தரவு செக்சமுக்கு ஒத்த பெயர் இருக்கும்</string>\n    <string name=\"share_base_64\">பகிர்வு BASE64</string>\n    <string name=\"options\">விருப்பங்கள்</string>\n    <string name=\"actions\">செயல்கள்</string>\n    <string name=\"import_base_64\">இறக்குமதி BASE64</string>\n    <string name=\"base_64_actions\">அடிப்படை 64 செயல்கள்</string>\n    <string name=\"add_outline\">அவுட்லைன் சேர்க்கவும்</string>\n    <string name=\"add_outline_sub\">குறிப்பிட்ட வண்ணம் மற்றும் அகலத்துடன் உரையைச் சுற்றி அவுட்லைன் சேர்க்கவும்</string>\n    <string name=\"outline_color\">அவுட்லைன் நிறம்</string>\n    <string name=\"outline_size\">அவுட்லைன் அளவு</string>\n    <string name=\"rotation\">சுழற்சி</string>\n    <string name=\"checksum_as_filename\">கோப்பு பெயராக செக்சம்</string>\n    <string name=\"auto_paste\">கார் பாச்தா</string>\n    <string name=\"harmonization_color\">ஒத்திசைவு நிறம்</string>\n    <string name=\"harmonization_level\">ஒத்திசைவு நிலை</string>\n    <string name=\"pick_multiple_media\">பல ஊடகங்களைத் தேர்ந்தெடுங்கள்</string>\n    <string name=\"pick\">தேர்ந்தெடு</string>\n    <string name=\"tag_shutter_speed_value\">சட்டர் வேக மதிப்பு</string>\n    <string name=\"tag_exposure_bias_value\">வெளிப்பாடு சார்பு மதிப்பு</string>\n    <string name=\"tag_max_aperture_value\">அதிகபட்ச துளை மதிப்பு</string>\n    <string name=\"tag_sensing_method\">உணர்திறன் முறை</string>\n    <string name=\"tag_custom_rendered\">தனிப்பயன் வழங்கப்பட்டது</string>\n    <string name=\"tag_exposure_mode\">வெளிப்பாடு பயன்முறை</string>\n    <string name=\"tag_white_balance\">வெள்ளை இருப்பு</string>\n    <string name=\"tag_digital_zoom_ratio\">டிசிட்டல் சூம் விகிதம்</string>\n    <string name=\"tag_focal_length_in_35mm_film\">35 மிமீ படத்தில் குவிய நீளம்</string>\n    <string name=\"triangle\">முக்கோணம்</string>\n    <string name=\"bohman\">போமன்</string>\n    <string name=\"robidoux_sub\">இயற்கையான பட மறுஅளவிடுதலுக்காக உகந்ததாக இருக்கும் உயர்தர இடைக்கணிப்பு முறை, கூர்மை மற்றும் மென்மையை சமநிலைப்படுத்துகிறது</string>\n    <string name=\"add_image\">படத்தைச் சேர்க்கவும்</string>\n    <string name=\"bins_count\">பின்கள் எண்ணிக்கை</string>\n    <string name=\"webp_type_to_image_sub\">Webp கோப்பை படங்களின் தொகுதிகளாக மாற்றவும்</string>\n    <string name=\"ci_channel\">தொஒ சேனல்</string>\n    <string name=\"histogram_sub\">மாற்றங்களைச் செய்ய உங்களுக்கு உதவும் RGB அல்லது பிரகாசமான பட இச்டோகிராம்</string>\n    <string name=\"image_for_histogram\">இந்த படம் RGB மற்றும் பிரகாசமான இச்டோகிராம்களை உருவாக்க பயன்படுத்தப்படும்</string>\n    <string name=\"dashed\">கோடு</string>\n    <string name=\"edit_layer\">அடுக்கு திருத்து</string>\n    <string name=\"base_64_tips\">BASE64 சரத்தை நகலெடுக்க அல்லது சேமிக்க படத்தை ஏற்றவும். உங்களிடம் சரம் இருந்தால், படத்தைப் பெற மேலே ஒட்டலாம்</string>\n    <string name=\"save_base_64\">BASE64 ஐ சேமிக்கவும்</string>\n    <string name=\"fluent_switch_sub\">\\\"சரளமாக\\\" வடிவமைப்பு அமைப்பின் அடிப்படையில் ஒரு சுவிட்ச்</string>\n    <string name=\"cupertino_switch\">குபெர்டினோ</string>\n    <string name=\"cupertino_switch_sub\">\\\"குப்பெர்டினோ\\\" வடிவமைப்பு அமைப்பை அடிப்படையாகக் கொண்ட ஒரு சுவிட்ச்</string>\n    <string name=\"min_color_ratio\">குறைந்தபட்ச வண்ண விகிதம்</string>\n    <string name=\"tag_resolution_unit\">தெளிவுத்திறன் அலகு</string>\n    <string name=\"tag_strip_offsets\">உரி ஆஃப்செட்டுகள்</string>\n    <string name=\"tag_rows_per_strip\">ஒரு துண்டுக்கு வரிசைகள்</string>\n    <string name=\"tag_strip_byte_counts\">உரி பைட் எண்ணிக்கைகள்</string>\n    <string name=\"tag_jpeg_interchange_format\">Jpeg பரிமாற்ற வடிவம்</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG பரிமாற்ற வடிவமைப்பு நீளம்</string>\n    <string name=\"tag_transfer_function\">மாற்றச் சார்பு</string>\n    <string name=\"tag_white_point\">வெள்ளை புள்ளி</string>\n    <string name=\"tag_primary_chromaticities\">முதன்மை வண்ணமயமாக்கல்கள்</string>\n    <string name=\"tag_reference_black_white\">குறிப்பு கருப்பு வெள்ளை</string>\n    <string name=\"tag_datetime\">தேதி நேரம்</string>\n    <string name=\"tag_image_description\">பட விவரம்</string>\n    <string name=\"tag_make\">உருவாக்கு</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">உணர்திறன் வகை</string>\n    <string name=\"tag_standard_output_sensitivity\">நிலையான வெளியீட்டு உணர்திறன்</string>\n    <string name=\"tag_recommended_exposure_index\">பரிந்துரைக்கப்பட்ட வெளிப்பாடு அட்டவணை</string>\n    <string name=\"tag_iso_speed\">ஐஎச்ஓ விரைவு</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ஐஎச்ஓ வேக அட்சரேகை YYY</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ஐஎச்ஓ வேக அட்சரேகை Zzz</string>\n    <string name=\"draw_regular_star\">வழக்கமான நட்சத்திரத்தை வரையவும்</string>\n    <string name=\"draw_regular_star_sub\">இலவச படிவத்திற்கு பதிலாக வழக்கமானதாக இருக்கும் நட்சத்திரத்தை வரையவும்</string>\n    <string name=\"antialias\">ஆன்டிஆசா</string>\n    <string name=\"antialias_sub\">கூர்மையான விளிம்புகளைத் தடுக்க ஆன்டிலியாசிங்கை செயல்படுத்துகிறது</string>\n    <string name=\"open_edit_instead_of_preview\">முன்னோட்டத்திற்கு பதிலாக திருத்து திறக்கவும்</string>\n    <string name=\"open_edit_instead_of_preview_sub\">இமேசெட்டூல் பாக்சில் திறக்க (முன்னோட்டம்) படத்தைத் தேர்ந்தெடுக்கும்போது, முன்னோட்டத்திற்கு பதிலாக தேர்வுத் தாள் திறக்கப்படும்</string>\n    <string name=\"document_scanner\">ஆவண ச்கேனர்</string>\n    <string name=\"save_as_pdf\">PDF ஆக சேமிக்கவும்</string>\n    <string name=\"template\">வார்ப்புரு</string>\n    <string name=\"no_template_filters\">வார்ப்புரு வடிப்பான்கள் எதுவும் சேர்க்கப்படவில்லை</string>\n    <string name=\"create_new\">புதியதை உருவாக்கவும்</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">வருடு செய்யப்பட்ட QR குறியீடு சரியான வடிகட்டி வார்ப்புரு அல்ல</string>\n    <string name=\"scan_qr_code\">QR குறியீட்டை வருடு செய்யுங்கள்</string>\n    <string name=\"template_filter\">வார்ப்புரு வடிகட்டி</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) என்ற பெயருடன் வடிகட்டி வார்ப்புரு சேர்க்கப்பட்டது</string>\n    <string name=\"filter_preview\">வடிகட்டி முன்னோட்டம்</string>\n    <string name=\"qr_code\">QR &amp; பார்கோடு</string>\n    <string name=\"qr_code_sub\">QR குறியீட்டை வருடு செய்து அதன் உள்ளடக்கத்தைப் பெறுங்கள் அல்லது புதிய ஒன்றை உருவாக்க உங்கள் சரத்தை ஒட்டவும்</string>\n    <string name=\"scan_qr_code_to_replace_content\">புலத்தில் உள்ளடக்கத்தை மாற்ற எந்த பார்கோடையும் வருடு செய்யுங்கள் அல்லது தேர்ந்தெடுக்கப்பட்ட வகையுடன் புதிய பார்கோடு உருவாக்க ஏதாவது தட்டச்சு செய்க</string>\n    <string name=\"qr_description\">QR விளக்கம்</string>\n    <string name=\"min\">மணித்துளி</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR குறியீட்டை ச்கேன் செய்ய அமைப்புகளில் கேமரா இசைவு வழங்கவும்</string>\n    <string name=\"cubic\">கன</string>\n    <string name=\"bspline\">பி-ச்பைன்</string>\n    <string name=\"hamming\">ஏமிங்</string>\n    <string name=\"hanning\">அன்னிங்</string>\n    <string name=\"lanczos3_jinc\">லான்சோச் 3 சின்க்</string>\n    <string name=\"lanczos4_jinc\">லான்சோச் 4 சின்க்</string>\n    <string name=\"bspline_sub\">ஒரு வளைவு அல்லது மேற்பரப்பு, நெகிழ்வான மற்றும் தொடர்ச்சியான வடிவ பிரதிநிதித்துவம்</string>\n    <string name=\"hamming_sub\">சமிக்ஞையின் விளிம்புகளைத் தட்டுவதன் மூலம் நிறமாலை கசிவைக் குறைக்கப் பயன்படுத்தப்படும் ஒரு சாளர செயல்பாடு, சமிக்ஞை செயலாக்கத்தில் பயனுள்ளதாக இருக்கும்</string>\n    <string name=\"hanning_sub\">சமிக்ஞை செயலாக்க பயன்பாடுகளில் நிறமாலை கசிவைக் குறைக்க பொதுவாகப் பயன்படுத்தப்படும் ஆன் சாளரத்தின் மாறுபாடு</string>\n    <string name=\"blackman_sub\">சமிக்ஞை செயலாக்கத்தில் பெரும்பாலும் பயன்படுத்தப்படும் ச்பெக்ட்ரல் கசிவைக் குறைப்பதன் மூலம் நல்ல அதிர்வெண் தெளிவுத்திறனை வழங்கும் சாளர செயல்பாடு</string>\n    <string name=\"lanczos2_jinc_sub\">JINC செயல்பாட்டைப் பயன்படுத்தும் லான்சோச் 2 வடிப்பானின் மாறுபாடு, குறைந்தபட்ச கலைப்பொருட்களுடன் உயர்தர இடைக்கணிப்பை வழங்குகிறது</string>\n    <string name=\"ewa_blackman\">பிளாக்மேன் ஈவா</string>\n    <string name=\"ewa_quadric\">குவாட்ரிக் ஈவா</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">லான்சோசின் நீள்வட்ட எடையுள்ள சராசரி (ஈ.டபிள்யூ.ஏ) மாறுபாடு 4 மிகவும் கூர்மையான பட மறுசீரமைப்பிற்கான கூர்மையான வடிகட்டி</string>\n    <string name=\"format_conversion_sub\">படங்களின் தொகுதிகளை ஒரு வடிவத்திலிருந்து இன்னொரு வடிவத்திற்கு மாற்றவும்</string>\n    <string name=\"clip\">கிளிப்</string>\n    <string name=\"protanomaly_sub\">சிவப்பு மற்றும் பச்சை நிறங்களுக்கு இடையில் வேறுபடுவதில் தொல்லை</string>\n    <string name=\"achromatopsia_sub\">முழுமையான வண்ண குருட்டுத்தன்மை, சாம்பல் நிற நிழல்களை மட்டுமே பார்க்கிறது</string>\n    <string name=\"not_use_color_blind_scheme_sub\">வண்ணங்கள் கருப்பொருளில் அமைக்கப்பட்டிருக்கும்</string>\n    <string name=\"lagrange_2_sub\">ஆர்டர் 2 இன் ஒரு லாக்ரேஞ்ச் இடைக்கணிப்பு வடிகட்டி, மென்மையான மாற்றங்களுடன் உயர்தர பட அளவிடலுக்கு ஏற்றது</string>\n    <string name=\"export\">ஏற்றுமதி</string>\n    <string name=\"position\">நிலை</string>\n    <string name=\"center\">நடுவண்</string>\n    <string name=\"top_left\">மேல் இடது</string>\n    <string name=\"top_right\">மேல் வலது</string>\n    <string name=\"bottom_left\">கீழே இடது</string>\n    <string name=\"bottom_right\">கீழே வலது</string>\n    <string name=\"top_center\">மேல் நடுவண்</string>\n    <string name=\"center_right\">நடுவண் சரியானது</string>\n    <string name=\"bottom_center\">கீழே நடுவண்</string>\n    <string name=\"center_left\">நடுவண் இடது</string>\n    <string name=\"palette_transfer\">தட்டு பரிமாற்றம்</string>\n    <string name=\"simple_old_tv\">எளிய பழைய டிவி</string>\n    <string name=\"hdr\">எச்.டி.ஆர்</string>\n    <string name=\"gotham\">கோதம்</string>\n    <string name=\"simple_sketch\">எளிய ச்கெட்ச்</string>\n    <string name=\"soft_glow\">மென்மையான பளபளப்பு</string>\n    <string name=\"color_poster\">வண்ண சுவரொட்டி</string>\n    <string name=\"tri_tone\">ட்ரை டோன்</string>\n    <string name=\"third_color\">மூன்றாவது நிறம்</string>\n    <string name=\"clahe_oklab\">கிளாஏ ஓக்லாப்</string>\n    <string name=\"clahe_oklch\">கிளாரா ஓல்ச்</string>\n    <string name=\"polka_dot\">போலந்து புள்ளி</string>\n    <string name=\"clustered_2x2_dithering\">கொத்து 2x2 டிதரிங்</string>\n    <string name=\"clustered_4x4_dithering\">கொத்தாக 4x4 ditering</string>\n    <string name=\"clustered_8x8_dithering\">கொத்து 8x8 டிதரிங்</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">ஆவண ச்கேனரை ச்கேன் செய்ய அமைப்புகளில் கேமரா இசைவு வழங்கவும்</string>\n    <string name=\"edgy_amber\">கசப்பான அம்பர்</string>\n    <string name=\"fall_colors\">வீழ்ச்சி வண்ணங்கள்</string>\n    <string name=\"octaves\">ஆக்டேவ்ச்</string>\n    <string name=\"lacunarity\">லாகுனாரிட்டி</string>\n    <string name=\"gain\">பெருக்கம்</string>\n    <string name=\"weighted_strength\">எடையுள்ள வலிமை</string>\n    <string name=\"alignment\">இருப்புவழி</string>\n    <string name=\"custom_filename\">தனிப்பயன் கோப்பு பெயர்</string>\n    <string name=\"custom_filename_sub\">தற்போதைய படத்தை சேமிக்க பயன்படுத்தப்படும் இடம் மற்றும் கோப்பு பெயரைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"collage_type\">படத்தொகுப்பு வகை</string>\n    <string name=\"compact_selectors\">சிறிய தேர்வாளர்கள்</string>\n    <string name=\"gif_type_to_webp\">Gif பெறுநர் webp</string>\n    <string name=\"tag_y_cb_cr_coefficients\">ஒய் cb சிஆர் குணகங்கள்</string>\n    <string name=\"create_shortcut_subtitle\">உங்கள் துவக்கத்தின் முகப்புத் திரையில் சார்ட்கட்டாக கருவி சேர்க்கப்படும், தேவையான நடத்தையை அடைய \\\"ச்கிப் கோப்பு எடுக்கும்\\\" அமைப்புடன் இதைப் பயன்படுத்தவும்</string>\n    <string name=\"dont_stack_frames_sub\">முந்தைய பிரேம்களை அப்புறப்படுத்த உதவுகிறது, எனவே அவை ஒருவருக்கொருவர் அடுக்கி வைக்காது</string>\n    <string name=\"canny\">கேனி</string>\n    <string name=\"beta\">பீட்டா</string>\n    <string name=\"tag_f_number\">எஃப் எண்</string>\n    <string name=\"tag_exposure_program\">வெளிப்பாடு திட்டம்</string>\n    <string name=\"tag_spectral_sensitivity\">நிறமாலை உணர்திறன்</string>\n    <string name=\"tag_photographic_sensitivity\">புகைப்பட உணர்திறன்</string>\n    <string name=\"speed_sub\">இதன் விளைவாக பட டிகோடிங் வேகத்தை கட்டுப்படுத்துகிறது, இது விளைந்த படத்தை வேகமாக திறக்க உதவும், %1$s இன் மதிப்பு மெதுவான டிகோடிங் என்று பொருள், அதேசமயம் %2$s - வேகமாக, இந்த அமைப்பு வெளியீட்டு பட அளவை அதிகரிக்கக்கூடும்</string>\n    <string name=\"sorting\">வரிசைப்படுத்துதல்</string>\n    <string name=\"sort_by_date\">திகதி</string>\n    <string name=\"sort_by_date_reversed\">தேதி (தலைகீழ்)</string>\n    <string name=\"sort_by_name\">பெயர்</string>\n    <string name=\"sort_by_name_reversed\">பெயர் (தலைகீழ்)</string>\n    <string name=\"channels_configuration\">சேனல்கள் உள்ளமைவு</string>\n    <string name=\"header_today\">இன்று</string>\n    <string name=\"embedded_picker\">உட்பொதிக்கப்பட்ட பிக்கர்</string>\n    <string name=\"embedded_picker_sub\">பட கருவிப்பெட்டியின் பட எடுப்பர்</string>\n    <string name=\"pick_single_media\">ஒற்றை ஊடகத்தைத் தேர்ந்தெடுங்கள்</string>\n    <string name=\"show_settings_in_landscape_sub\">இந்த முடக்கப்பட்டால், நிலப்பரப்பு பயன்முறையில் அமைப்புகள் எப்போதும் போல பயன்பாட்டுப் பட்டியில் உள்ள பொத்தானில் திறக்கப்படும், இது நிரந்தர புலப்படும் விருப்பத்திற்கு பதிலாக</string>\n    <string name=\"fullscreen_settings\">முழுத்திரை அமைப்புகள்</string>\n    <string name=\"fullscreen_settings_sub\">அதை இயக்கு மற்றும் அமைப்புகள் பக்கம் எப்போதும் ச்லிபிள் டிராயர் தாளுக்கு பதிலாக முழுத்திரையாக திறக்கப்படும்</string>\n    <string name=\"switch_type\">சுவிட்ச் வகை</string>\n    <string name=\"compose_switch_sub\">ஒரு செட் பேக் நீங்கள் மாறும் பொருளை உருவாக்குகிறது</string>\n    <string name=\"material_you_switch_sub\">நீங்கள் மாறும் ஒரு பொருள்</string>\n    <string name=\"max\">அதிகபட்சம்</string>\n    <string name=\"resize_anchor\">மறுஅளவிடுதல் நங்கூரம்</string>\n    <string name=\"pixel_switch\">படப்புள்ளி</string>\n    <string name=\"images_to_svg_sub\">எச்.வி.சி படங்களுக்கு கொடுக்கப்பட்ட படங்களை சுவடுங்கள்</string>\n    <string name=\"use_sampled_palette\">மாதிரி தட்டு பயன்படுத்தவும்</string>\n    <string name=\"use_sampled_palette_sub\">இந்த விருப்பம் இயக்கப்பட்டால் அளவீட்டு தட்டு மாதிரி செய்யப்படும்</string>\n    <string name=\"path_omit\">பாதை தவிர்க்கவும்</string>\n    <string name=\"tag_subject_distance\">பொருள் தூரம்</string>\n    <string name=\"svg_warning\">குறைவில்லாமல் பெரிய படங்களை கண்டுபிடிப்பதற்கான இந்த கருவியின் பயன்பாடு பரிந்துரைக்கப்படவில்லை, இது செயலிழப்பை ஏற்படுத்தும் மற்றும் செயலாக்க நேரத்தை அதிகரிக்கும்</string>\n    <string name=\"downscale_image\">கீழ்நிலை படம்</string>\n    <string name=\"downscale_image_sub\">செயலாக்கத்திற்கு முன் படம் குறைந்த பரிமாணங்களுக்கு குறைக்கப்படும், இது கருவி வேகமாகவும் பாதுகாப்பாகவும் செயல்பட உதவுகிறது</string>\n    <string name=\"lines_threshold\">கோடுகள் வாசல்</string>\n    <string name=\"path_scale\">பாதை அளவு</string>\n    <string name=\"reset_properties\">பண்புகளை மீட்டமை</string>\n    <string name=\"reset_properties_sub\">எல்லா பண்புகளும் இயல்புநிலை மதிப்புகளுக்கு அமைக்கப்படும், இந்த செயலை செயல்தவிர்க்க முடியாது என்பதைக் கவனியுங்கள்</string>\n    <string name=\"detailed\">விவரிக்கப்பட்ட</string>\n    <string name=\"legacy\">மரபு</string>\n    <string name=\"lstm_network\">எல்.எச்.டி.எம் பிணையம்</string>\n    <string name=\"legacy_and_lstm\">லெகசி &amp; எல்.எச்.டி.எம்</string>\n    <string name=\"convert\">மாற்றவும்</string>\n    <string name=\"tag_bits_per_sample\">ஒரு மாதிரிக்கு பிட்கள்</string>\n    <string name=\"tag_compression\">சுருக்க</string>\n    <string name=\"tag_photometric_interpretation\">ஃபோட்டோமெட்ரிக் விளக்கம்</string>\n    <string name=\"tag_samples_per_pixel\">பிக்சலுக்கு மாதிரிகள்</string>\n    <string name=\"tag_planar_configuration\">பிளானர் உள்ளமைவு</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">ஒய் cb சிஆர் துணை மாதிரி</string>\n    <string name=\"tag_y_cb_cr_positioning\">ஒய் cb சிஆர் பொருத்துதல்</string>\n    <string name=\"tag_y_resolution\">ஒய் தீர்மானம்</string>\n    <string name=\"tag_model\">மாதிரியுரு</string>\n    <string name=\"tag_software\">மென்பொருள்</string>\n    <string name=\"tag_artist\">கலைஞர்</string>\n    <string name=\"tag_copyright\">பதிப்புரிமை</string>\n    <string name=\"tag_exif_version\">Exif பதிப்பு</string>\n    <string name=\"tag_flashpix_version\">ஃப்ளாச்பிக்ச் பதிப்பு</string>\n    <string name=\"tag_compressed_bits_per_pixel\">பிக்சலுக்கு சுருக்கப்பட்ட பிட்கள்</string>\n    <string name=\"tag_related_sound_file\">தொடர்புடைய ஒலி கோப்பு</string>\n    <string name=\"tag_datetime_original\">தேதி நேரம் அசல்</string>\n    <string name=\"tag_datetime_digitized\">தேதி நேரம் டிசிட்டல் மயமாக்கப்பட்டது</string>\n    <string name=\"tag_offset_time\">நேரம் ஈடுசெய்யும் நேரம்</string>\n    <string name=\"tag_offset_time_original\">ஆஃப்செட் நேரம் அசல்</string>\n    <string name=\"tag_subsec_time\">துணை நொடி நேரம்</string>\n    <string name=\"tag_subsec_time_original\">துணை நொடி நேரம் அசல்</string>\n    <string name=\"gaussian_sub\">காசியன் செயல்பாட்டைப் பயன்படுத்தும் ஒரு இடைக்கணிப்பு முறை, படங்களில் சத்தத்தை மென்மையாக்குவதற்கும் குறைக்கவும் பயனுள்ளதாக இருக்கும்</string>\n    <string name=\"sphinx_sub\">குறைந்தபட்ச கலைப்பொருட்களுடன் உயர்தர இடைக்கணிப்பை வழங்கும் மேம்பட்ட மறுசீரமைப்பு முறை</string>\n    <string name=\"bartlett_sub\">நிறமாலை கசிவைக் குறைக்க சமிக்ஞை செயலாக்கத்தில் பயன்படுத்தப்படும் ஒரு முக்கோண சாளர செயல்பாடு</string>\n    <string name=\"spline16_sub\">16-TAP வடிப்பானைப் பயன்படுத்தி மென்மையான முடிவுகளை வழங்கும் ஒரு ச்ப்லைன் அடிப்படையிலான இடைக்கணிப்பு முறை</string>\n    <string name=\"spline36_sub\">36-TAP வடிப்பானைப் பயன்படுத்தி மென்மையான முடிவுகளை வழங்கும் ஒரு ச்ப்லைன் அடிப்படையிலான இடைக்கணிப்பு முறை</string>\n    <string name=\"spline64_sub\">64-TAP வடிப்பானைப் பயன்படுத்தி மென்மையான முடிவுகளை வழங்கும் ஒரு ச்ப்லைன் அடிப்படையிலான இடைக்கணிப்பு முறை</string>\n    <string name=\"kaiser_sub\">கைசர் சாளரத்தைப் பயன்படுத்தும் ஒரு இடைக்கணிப்பு முறை, பிரதான-லோப் அகலம் மற்றும் பக்க-லோப் நிலைக்கு இடையிலான வர்த்தகத்தின் மீது நல்ல கட்டுப்பாட்டை வழங்குகிறது</string>\n    <string name=\"bartlett_hann_sub\">சமிக்ஞை செயலாக்கத்தில் நிறமாலை கசிவைக் குறைக்கப் பயன்படும் பார்ட்லெட் மற்றும் ஆன் விண்டோசை இணைக்கும் ஒரு கலப்பின சாளர செயல்பாடு</string>\n    <string name=\"box_sub\">அருகிலுள்ள படப்புள்ளி மதிப்புகளின் சராசரியைப் பயன்படுத்தும் ஒரு எளிய மறுசீரமைப்பு முறை, பெரும்பாலும் தடுப்பு தோற்றத்தை ஏற்படுத்துகிறது</string>\n    <string name=\"bohman_sub\">சமிக்ஞை செயலாக்க பயன்பாடுகளில் நல்ல அதிர்வெண் தீர்மானத்தை வழங்கும் ச்பெக்ட்ரல் கசிவைக் குறைக்கப் பயன்படுத்தப்படும் ஒரு சாளர செயல்பாடு</string>\n    <string name=\"lanczos2_sub\">குறைந்தபட்ச கலைப்பொருட்களுடன் உயர்தர இடைக்கணிப்புக்கு 2-லோப் லான்சோச் வடிப்பானைப் பயன்படுத்தும் ஒரு மறுசீரமைப்பு முறை</string>\n    <string name=\"lanczos3_sub\">குறைந்தபட்ச கலைப்பொருட்களுடன் உயர்தர இடைக்கணிப்புக்கு 3-லோப் லான்சோச் வடிப்பானைப் பயன்படுத்தும் ஒரு மறுசீரமைப்பு முறை</string>\n    <string name=\"lanczos4_sub\">குறைந்தபட்ச கலைப்பொருட்களுடன் உயர்தர இடைக்கணிப்புக்கு 4-லோப் லான்சோச் வடிப்பானைப் பயன்படுத்தும் ஒரு மறுசீரமைப்பு முறை</string>\n    <string name=\"lanczos3_jinc_sub\">JINC செயல்பாட்டைப் பயன்படுத்தும் லான்சோச் 3 வடிப்பானின் மாறுபாடு, குறைந்தபட்ச கலைப்பொருட்களுடன் உயர்தர இடைக்கணிப்பை வழங்குகிறது</string>\n    <string name=\"save_empty_lut_sub\">முதலில், நீங்கள் இங்கே பெறக்கூடிய நடுநிலை LUT க்கு வடிகட்டியைப் பயன்படுத்த உங்களுக்கு பிடித்த புகைப்பட திருத்துதல் பயன்பாட்டைப் பயன்படுத்தவும். இது சரியாக வேலை செய்ய ஒவ்வொரு படப்புள்ளி நிறமும் மற்ற பிக்சல்களை சார்ந்து இருக்கக்கூடாது (எ.கா. மங்கலானது வேலை செய்யாது). தயாரானதும், உங்கள் புதிய LUT படத்தை 512*512 LUT வடிகட்டிக்கு உள்ளீடாகப் பயன்படுத்தவும்</string>\n    <string name=\"pop_art\">பாப் கலை</string>\n    <string name=\"celluloid\">செல்லுலாய்டு</string>\n    <string name=\"coffee\">காபி</string>\n    <string name=\"golden_forest\">கோல்டன் காடு</string>\n    <string name=\"greenish\">பச்சை</string>\n    <string name=\"retro_yellow\">ரெட்ரோ மஞ்சள்</string>\n    <string name=\"links_preview_sub\">நீங்கள் உரையைப் பெறக்கூடிய இடங்களில் இணைப்பு முன்னோட்டத்தை மீட்டெடுப்பதை இயக்குகிறது (QRCode, OCR போன்றவை)</string>\n    <string name=\"links\">இணைப்புகள்</string>\n    <string name=\"ico_size_warning\">ஐ.சி.ஓ கோப்புகளை அதிகபட்ச அளவு 256 ஃச் 256 இல் மட்டுமே சேமிக்க முடியும்</string>\n    <string name=\"gif_type_to_webp_sub\">GIF படங்களை வலை அனிமேசன் படங்களுக்கு மாற்றவும்</string>\n    <string name=\"webp_tools\">வலை கருவிகள்</string>\n    <string name=\"webp_tools_sub\">படங்களை வெப் அனிமேசன் படமாக மாற்றவும் அல்லது கொடுக்கப்பட்ட வெப்.பி அனிமேசனில் இருந்து பிரேம்களைப் பிரித்தெடுக்கவும்</string>\n    <string name=\"webp_type_to_image\">படங்களுக்கு வலை</string>\n    <string name=\"webp_type_to_webp_sub\">படங்களின் தொகுப்பை Webp கோப்பாக மாற்றவும்</string>\n    <string name=\"webp_type_to_webp\">வலைப்பக்கத்திற்கு படங்கள்</string>\n    <string name=\"select_webp_image_to_start\">தொடங்க வலை படத்தைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"manage_storage_extra_types\">கோப்புகளுக்கு முழு அணுகல் இல்லை</string>\n    <string name=\"manage_storage_extra_types_sub\">ஆண்ட்ராய்டு இல் படங்களாக அங்கீகரிக்கப்படாத JXL, QOI மற்றும் பிற படங்களை பார்க்க எல்லா கோப்புகளையும் அணுக அனுமதிக்கவும். இசைவு இல்லாமல் பட கருவிப்பெட்டியால் அந்த படங்களை காட்ட முடியவில்லை</string>\n    <string name=\"default_draw_color\">இயல்புநிலை டிரா நிறம்</string>\n    <string name=\"add_timestamp_sub\">வெளியீட்டு கோப்பு பெயரில் நேர முத்திரை சேர்க்க உதவுகிறது</string>\n    <string name=\"formatted_timestamp\">வடிவமைக்கப்பட்ட நேர முத்திரை</string>\n    <string name=\"formatted_timestamp_sub\">அடிப்படை மில்லிசுக்கு பதிலாக வெளியீட்டு கோப்பு பெயரில் நேர முத்திரை வடிவமைப்பை இயக்கவும்</string>\n    <string name=\"one_time_save_location_sub\">பெரும்பாலும் அனைத்து விருப்பங்களிலும் சேமி பொத்தானை நீண்ட நேரம் அழுத்துவதன் மூலம் நீங்கள் பயன்படுத்தக்கூடிய இடங்களை சேமிக்கவும் திருத்தவும்</string>\n    <string name=\"recently_used\">அண்மைக் காலத்தில் பயன்படுத்தப்பட்டது</string>\n    <string name=\"group\">குழு</string>\n    <string name=\"image_toolbox_in_telegram\">டெலிகிராமில் பட கருவிப்பெட்டி</string>\n    <string name=\"image_toolbox_in_telegram_sub\">எங்கள் அரட்டையில் சேருங்கள், அங்கு நீங்கள் விரும்பும் எதையும் விவாதிக்கலாம், மேலும் நான் பீட்டாக்கள் மற்றும் அறிவிப்புகளை இடுகையிடும் தொஒ சேனலையும் பாருங்கள்</string>\n    <string name=\"ci_channel_sub\">பயன்பாட்டின் புதிய பதிப்புகள் குறித்து அறிவிக்கப்பட்டு, அறிவிப்புகளைப் படியுங்கள்</string>\n    <string name=\"group_tools_by_type_sub\">தனிப்பயன் பட்டியல் ஏற்பாட்டிற்கு பதிலாக முதன்மையான திரையில் குழுக்கள் கருவிகள் அவற்றின் வகையால்</string>\n    <string name=\"default_values\">இயல்புநிலை மதிப்புகள்</string>\n    <string name=\"system_bars_visibility\">கணினி பார்கள் தெரிவுநிலை</string>\n    <string name=\"show_system_bars_by_swipe\">ச்வைப் மூலம் கணினி பார்களைக் காட்டு</string>\n    <string name=\"show_system_bars_by_swipe_sub\">கணினி பார்கள் மறைக்கப்பட்டால் அவற்றைக் காட்ட ச்வைப் செய்வதை செயல்படுத்துகிறது</string>\n    <string name=\"auto\">தானி</string>\n    <string name=\"noise_generation\">ஒலி உருவாக்கம்</string>\n    <string name=\"noise_generation_sub\">பெர்லின் அல்லது பிற வகைகள் போன்ற வெவ்வேறு சத்தங்களை உருவாக்குங்கள்</string>\n    <string name=\"frequency\">மீடிறன், மீள்திறன், நிகழ்வெண், நிகழ்வு</string>\n    <string name=\"noise_type\">இரைச்சல் வகை</string>\n    <string name=\"rotation_type\">சுழற்சி வகை</string>\n    <string name=\"fractal_type\">பின்னல் வகை</string>\n    <string name=\"collage_maker\">படத்தொகுப்பு தயாரிப்பாளர்</string>\n    <string name=\"collage_maker_sub\">20 படங்கள் வரை படத்தொகுப்புகளை உருவாக்குங்கள்</string>\n    <string name=\"collages_info\">நிலையை சரிசெய்ய இடமாற்றம், நகர்த்த மற்றும் பெரிதாக்க படத்தை வைத்திருங்கள்</string>\n    <string name=\"histogram\">செவ்வகப்படம்</string>\n    <string name=\"tesseract_options\">டெசராக்ட் விருப்பங்கள்</string>\n    <string name=\"tesseract_options_sub\">டெசராக்ட் எஞ்சினுக்கு சில உள்ளீட்டு மாறிகளைப் பயன்படுத்துங்கள்</string>\n    <string name=\"custom_options\">தனிப்பயன் விருப்பங்கள்</string>\n    <string name=\"area_sub\">படப்புள்ளி பகுதி உறவைப் பயன்படுத்தி மறுசீரமைத்தல். படத்தை அழிப்பதற்கான விருப்பமான முறையாக இது இருக்கலாம், ஏனெனில் இது மொயரின் இல்லாத முடிவுகளைத் தருகிறது. ஆனால் படம் பெரிதாக்கப்படும்போது, அது \\\"அருகிலுள்ள\\\" முறைக்கு ஒத்ததாகும்.</string>\n    <string name=\"enable_tonemapping\">டான்மாப்பிங் இயக்கவும்</string>\n    <string name=\"enter_percent\">% உள்ளிடவும்</string>\n    <string name=\"unknown_host\">தளத்தை அணுக முடியாது, VPN ஐப் பயன்படுத்த முயற்சிக்கவும் அல்லது முகவரி சரியானதா என்று சரிபார்க்கவும்</string>\n    <string name=\"markup_layers\">மார்க்அப் அடுக்குகள்</string>\n    <string name=\"markup_layers_sub\">படங்கள், உரை மற்றும் பலவற்றை சுதந்திரமாக வைக்கும் திறன் கொண்ட அடுக்குகள் பயன்முறை</string>\n    <string name=\"layers_on_image\">படத்தில் அடுக்குகள்</string>\n    <string name=\"layers_on_image_sub\">ஒரு படத்தை பின்னணியாகப் பயன்படுத்தவும், அதன் மேல் வெவ்வேறு அடுக்குகளைச் சேர்க்கவும்</string>\n    <string name=\"layers_on_background\">பின்னணியில் அடுக்குகள்</string>\n    <string name=\"layers_on_background_sub\">முதல் விருப்பத்திற்கு அதே ஆனால் படத்திற்கு பதிலாக வண்ணத்துடன்</string>\n    <string name=\"fast_settings_side\">வேகமான அமைப்புகள் பக்கம்</string>\n    <string name=\"fast_settings_side_sub\">படங்களைத் திருத்தும் போது தேர்ந்தெடுக்கப்பட்ட பக்கத்தில் ஒரு மிதக்கும் துண்டு சேர்க்கவும், இது சொடுக்கு செய்யும் போது வேகமான அமைப்புகளைத் திறக்கும்</string>\n    <string name=\"clear_selection\">தெளிவான தேர்வு</string>\n    <string name=\"settings_group_visibility_hidden\">குழு \\\"%1$s\\\" அமைப்பது இயல்பாகவே சரிந்துவிடும்</string>\n    <string name=\"settings_group_visibility_visible\">குழு \\\"%1$s\\\" அமைப்பது இயல்பாக விரிவாக்கப்படும்</string>\n    <string name=\"base_64_tools\">அடிப்படை 64 கருவிகள்</string>\n    <string name=\"base_64_tools_sub\">BASE64 சரத்தை படத்திற்கு டிகோட் செய்யுங்கள், அல்லது படத்தை BASE64 வடிவத்திற்கு குறியாக்கவும்</string>\n    <string name=\"base_64\">அடிப்படை 64</string>\n    <string name=\"not_a_valid_base_64\">வழங்கப்பட்ட மதிப்பு சரியான அடிப்படை 64 சரம் அல்ல</string>\n    <string name=\"copy_not_a_valid_base_64\">வெற்று அல்லது தவறான BASE64 சரத்தை நகலெடுக்க முடியாது</string>\n    <string name=\"paste_base_64\">பேச் 64 ஐ ஒட்டவும்</string>\n    <string name=\"copy_base_64\">BASE64 ஐ நகலெடுக்கவும்</string>\n    <string name=\"disable_rotation\">சுழற்சியை முடக்கு</string>\n    <string name=\"disable_rotation_sub\">இரண்டு விரல் சைகைகளுடன் சுழலும் படங்களைத் தடுக்கிறது</string>\n    <string name=\"enable_snapping_to_borders\">எல்லைகளுக்கு ஒடிப்பதை இயக்கவும்</string>\n    <string name=\"enable_snapping_to_borders_sub\">நகரும் அல்லது பெரிதாக்கிய பிறகு, பிரேம் விளிம்புகளை நிரப்ப படங்கள் ஒடிக்கும்</string>\n    <string name=\"free_software_partner\">இலவச மென்பொருள் (கூட்டாளர்)</string>\n    <string name=\"free_software_partner_sub\">ஆண்ட்ராய்டு பயன்பாடுகளின் கூட்டாளர் சேனலில் மிகவும் பயனுள்ள மென்பொருள்</string>\n    <string name=\"algorithms\">படிமுறை</string>\n    <string name=\"checksum_tools\">செக்சம் கருவிகள்</string>\n    <string name=\"checksum_tools_sub\">வெவ்வேறு ஆசிங் வழிமுறைகளைப் பயன்படுத்தி கோப்புகளிலிருந்து செக்சம்களை ஒப்பிட்டுப் பாருங்கள், ஆச்களைக் கணக்கிடுங்கள் அல்லது ஃச் சரங்களை உருவாக்கவும்</string>\n    <string name=\"calculate\">கணக்கிடுங்கள்</string>\n    <string name=\"text_hash\">உரை ஆச்</string>\n    <string name=\"checksum\">செக்சம்</string>\n    <string name=\"pick_file_to_checksum\">தேர்ந்தெடுக்கப்பட்ட வழிமுறையின் அடிப்படையில் அதன் செக்சமைக் கணக்கிட கோப்பைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"enter_text_to_checksum\">தேர்ந்தெடுக்கப்பட்ட வழிமுறையின் அடிப்படையில் அதன் செக்சமைக் கணக்கிட உரையை உள்ளிடவும்</string>\n    <string name=\"source_checksum\">மூல செக்சம்</string>\n    <string name=\"checksum_to_compare\">ஒப்பிடுவதற்கு செக்சம்</string>\n    <string name=\"match\">போட்டி!</string>\n    <string name=\"difference\">வேறுபாடு</string>\n    <string name=\"match_sub\">செக்சம்கள் சமம், அது பாதுகாப்பாக இருக்கும்</string>\n    <string name=\"difference_sub\">செக்சம்கள் சமமாக இல்லை, கோப்பு பாதுகாப்பற்றதாக இருக்கும்!</string>\n    <string name=\"mesh_gradients\">கண்ணி சாய்வு</string>\n    <string name=\"collection_mesh_gradients_sub\">கண்ணி சாய்வுகளின் நிகழ்நிலை தொகுப்பைப் பாருங்கள்</string>\n    <string name=\"wrong_font\">TTF மற்றும் OTF எழுத்துருக்களை மட்டுமே இறக்குமதி செய்ய முடியும்</string>\n    <string name=\"import_font\">இறக்குமதி எழுத்துரு (TTF/OTF)</string>\n    <string name=\"export_fonts\">எழுத்துருக்கள் ஏற்றுமதி</string>\n    <string name=\"imported_fonts\">இறக்குமதி செய்யப்பட்ட எழுத்துருக்கள்</string>\n    <string name=\"error_while_saving\">முயற்சியைச் சேமிக்கும் போது பிழை, வெளியீட்டு கோப்புறையை மாற்ற முயற்சிக்கவும்</string>\n    <string name=\"filename_is_not_set\">கோப்பு பெயர் அமைக்கப்படவில்லை</string>\n    <string name=\"none\">எதுவுமில்லை</string>\n    <string name=\"custom_pages\">தனிப்பயன் பக்கங்கள்</string>\n    <string name=\"pages_selection\">பக்கங்கள் தேர்வு</string>\n    <string name=\"tool_exit_confirmation\">கருவி வெளியேறும் உறுதிப்படுத்தல்</string>\n    <string name=\"tool_exit_confirmation_sub\">குறிப்பிட்ட கருவிகளைப் பயன்படுத்தும் போது நீங்கள் சேமிக்கப்படாத மாற்றங்கள் இருந்தால் அதை மூட முயற்சித்தால், உரையாடல் காண்பிக்கப்படும் என்பதை உறுதிப்படுத்தவும்</string>\n    <string name=\"edit_exif_screen\">Exif திருத்து</string>\n    <string name=\"edit_exif_screen_sub\">பின்னடைவு இல்லாமல் ஒற்றை படத்தின் மெட்டாடேட்டாவை மாற்றவும்</string>\n    <string name=\"edit_exif_tag\">கிடைக்கக்கூடிய குறிச்சொற்களைத் திருத்த தட்டவும்</string>\n    <string name=\"change_sticker\">ச்டிக்கரை மாற்றவும்</string>\n    <string name=\"fit_width\">பொருந்தக்கூடிய அகலம்</string>\n    <string name=\"fit_height\">பொருத்தமான உயரத்திற்கு</string>\n    <string name=\"batch_compare\">தொகுதி ஒப்பிடுக</string>\n    <string name=\"pick_files_to_checksum\">தேர்ந்தெடுக்கப்பட்ட வழிமுறையின் அடிப்படையில் அதன் செக்சமைக் கணக்கிட கோப்பு/கோப்புகளைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"pick_files\">கோப்புகளைத் தேர்ந்தெடுங்கள்</string>\n    <string name=\"pick_directory\">கோப்பகத்தைத் தேர்ந்தெடுங்கள்</string>\n    <string name=\"head_length_scale\">தலை நீள அளவு</string>\n    <string name=\"stamp\">முத்திரை</string>\n    <string name=\"timestamp\">நேர முத்திரை</string>\n    <string name=\"format_pattern\">வடிவமைப்பு முறை</string>\n    <string name=\"padding\">திணிப்பு</string>\n    <string name=\"image_cutting\">பட வெட்டுதல்</string>\n    <string name=\"image_cutting_sub\">பட பகுதியை வெட்டி, இடதுவற்றை செங்குத்து அல்லது கிடைமட்ட கோடுகளால் ஒன்றிணைக்கவும் (தலைகீழ் ஆகலாம்)</string>\n    <string name=\"vertical_pivot_line\">செங்குத்து பிவோட் வரி</string>\n    <string name=\"horizontal_pivot_line\">கிடைமட்ட பிவோட் வரி</string>\n    <string name=\"inverse_selection\">தலைகீழ் தேர்வு</string>\n    <string name=\"inverse_vertical_selection_sub\">வெட்டப்பட்ட பகுதியைச் சுற்றி பகுதிகளை இணைப்பதற்கு பதிலாக, செங்குத்து வெட்டு பகுதி பாயும்</string>\n    <string name=\"inverse_horizontal_selection_sub\">வெட்டப்பட்ட பகுதியைச் சுற்றி பகுதிகளை இணைப்பதற்கு பதிலாக, கிடைமட்ட வெட்டு பகுதி பாயும்</string>\n    <string name=\"collection_mesh_gradients\">கண்ணி சாய்வுகளின் தொகுப்பு</string>\n    <string name=\"mesh_gradients_sub\">தனிப்பயன் அளவு முடிச்சுகள் மற்றும் தெளிவுத்திறனுடன் கண்ணி சாய்வு உருவாக்கவும்</string>\n    <string name=\"gradient_maker_type_image_mesh\">கண்ணி சாய்வு மேலடுக்கு</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">கொடுக்கப்பட்ட படங்களின் மேல் கண்ணி சாய்வை எழுதுங்கள்</string>\n    <string name=\"points_customization\">புள்ளிகள் தனிப்பயனாக்கம்</string>\n    <string name=\"grid_size\">கட்டம் அளவு</string>\n    <string name=\"resolution_x\">தீர்மானம் ஃச்</string>\n    <string name=\"resolution_y\">தீர்மானம் ஒய்</string>\n    <string name=\"resolution\">பகுத்தல்</string>\n    <string name=\"pixel_by_pixel\">படப்புள்ளி படப்புள்ளியாக</string>\n    <string name=\"highlight_color\">வண்ணத்தை முன்னிலைப்படுத்தவும்</string>\n    <string name=\"pixel_comparison_type\">படப்புள்ளி ஒப்பீட்டு வகை</string>\n    <string name=\"scan_barcode\">வருடு பார்கோடு</string>\n    <string name=\"height_ratio\">உயர விகிதம்</string>\n    <string name=\"barcode_type\">பார்கோடு வகை</string>\n    <string name=\"enforce_bw\">B/w ஐ செயல்படுத்தவும்</string>\n    <string name=\"enforce_bw_sub\">பார்கோடு படம் முழுமையாக கருப்பு மற்றும் வெள்ளை நிறமாக இருக்கும், மேலும் பயன்பாட்டின் கருப்பொருளால் வண்ணமயமாக்காது</string>\n    <string name=\"barcodes_sub\">எந்த பார்கோடு (qr, ean, aztec,…) வருடு செய்து அதன் உள்ளடக்கத்தைப் பெறுங்கள் அல்லது புதிய ஒன்றை உருவாக்க உங்கள் உரையை ஒட்டவும்</string>\n    <string name=\"no_barcode_found\">பார்கோடு எதுவும் கிடைக்கவில்லை</string>\n    <string name=\"generated_barcode_will_be_here\">உருவாக்கப்பட்ட பார்கோடு இங்கே இருக்கும்</string>\n    <string name=\"audio_cover_extractor\">ஆடியோ கவர்கள்</string>\n    <string name=\"audio_cover_extractor_sub\">ஆடியோ கோப்புகளிலிருந்து ஆல்பம் கவர் படங்களை பிரித்தெடுக்கவும், மிகவும் பொதுவான வடிவங்கள் ஆதரிக்கப்படுகின்றன</string>\n    <string name=\"pick_audio_to_start\">தொடங்க ஆடியோவைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"pick_audio\">ஆடியோவைத் தேர்ந்தெடுங்கள்</string>\n    <string name=\"no_covers_found\">கவர்கள் எதுவும் கிடைக்கவில்லை</string>\n    <string name=\"send_logs\">பதிவுகள் அனுப்பவும்</string>\n    <string name=\"send_logs_sub\">பயன்பாட்டு பதிவுகள் கோப்பைப் பகிர சொடுக்கு செய்க, இது சிக்கலைக் கண்டறியவும் சிக்கல்களை சரிசெய்யவும் எனக்கு உதவும்</string>\n    <string name=\"crash_title\">அச்சச்சோ… ஏதோ தவறு நடந்தது</string>\n    <string name=\"crash_subtitle\">கீழே உள்ள விருப்பங்களைப் பயன்படுத்தி நீங்கள் என்னை தொடர்பு கொள்ளலாம், மேலும் தீர்வைக் கண்டுபிடிக்க முயற்சிப்பேன். \\n(பதிவுகளை இணைக்க மறக்காதீர்கள்)</string>\n    <string name=\"ocr_write_to_file\">கோப்புக்கு எழுதுங்கள்</string>\n    <string name=\"ocr_write_to_file_sub\">படங்களின் தொகுப்பிலிருந்து உரையை பிரித்தெடுத்து ஒரு உரை கோப்பில் சேமிக்கவும்</string>\n    <string name=\"ocr_write_to_metadata\">மெட்டாடேட்டாவுக்கு எழுதுங்கள்</string>\n    <string name=\"ocr_write_to_metadata_sub\">ஒவ்வொரு படத்திலிருந்தும் உரையைப் பிரித்தெடுத்து, உறவினர் புகைப்படங்களின் exif தகவலில் வைக்கவும்</string>\n    <string name=\"invisible_mode\">கண்ணுக்கு தெரியாத பயன்முறை</string>\n    <string name=\"invisible_mode_sub\">உங்கள் படங்களின் பைட்டுகளுக்குள் கண் கண்ணுக்கு தெரியாத வாட்டர்மார்க்சை உருவாக்க ச்டிகனோகிராஃபி பயன்படுத்தவும்</string>\n    <string name=\"use_lsb\">LSB ஐப் பயன்படுத்தவும்</string>\n    <string name=\"use_lsb_sub\">எல்.எச்.பி (குறைவான குறிப்பிடத்தக்க பிட்) ச்டிகனோகிராபி முறை பயன்படுத்தப்படும், இல்லையெனில், இல்லையெனில் பயன்படுத்தப்படும்</string>\n    <string name=\"auto_remove_red_eyes\">ஆட்டோ சிவப்பு கண்களை அகற்றவும்</string>\n    <string name=\"password\">கடவுச்சொல்</string>\n    <string name=\"unlock\">திறக்க</string>\n    <string name=\"pdf_is_protected\">PDF பாதுகாக்கப்படுகிறது</string>\n    <string name=\"operation_almost_complete\">செயல்பாடு கிட்டத்தட்ட முடிந்தது. இப்போது ரத்து செய்ய அதை மறுதொடக்கம் செய்ய வேண்டும்</string>\n    <string name=\"sort_by_date_modified\">தேதி மாற்றியமைக்கப்பட்டது</string>\n    <string name=\"sort_by_date_modified_reversed\">தேதி மாற்றியமைக்கப்பட்ட (தலைகீழ்)</string>\n    <string name=\"sort_by_size\">அளவு</string>\n    <string name=\"sort_by_size_reversed\">அளவு (தலைகீழ்)</string>\n    <string name=\"sort_by_mime_type\">மைம் வகை</string>\n    <string name=\"sort_by_mime_type_reversed\">மைம் வகை (தலைகீழ்)</string>\n    <string name=\"sort_by_extension\">நீட்டிப்பு</string>\n    <string name=\"sort_by_extension_reversed\">நீட்டிப்பு (தலைகீழ்)</string>\n    <string name=\"sort_by_date_added\">தேதி சேர்க்கப்பட்டது</string>\n    <string name=\"sort_by_date_added_reversed\">தேதி சேர்க்கப்பட்டது (தலைகீழ்)</string>\n    <string name=\"left_to_right\">இடமிருந்து வலமாக</string>\n    <string name=\"right_to_left\">வலமிருந்து இடமாக</string>\n    <string name=\"top_to_bottom\">மேலிருந்து கீழே</string>\n    <string name=\"bottom_to_top\">கீழே முதல்</string>\n    <string name=\"liquid_glass\">திரவ கண்ணாடி</string>\n    <string name=\"liquid_glass_sub\">அண்மைக் காலத்தில் அறிவிக்கப்பட்ட ஐஇமு 26 ஐ அடிப்படையாகக் கொண்ட ஒரு சுவிட்ச் மற்றும் இது திரவ கண்ணாடி வடிவமைப்பு அமைப்பு</string>\n    <string name=\"pick_image_or_base64\">கீழே படத்தைத் தேர்ந்தெடுக்கவும் அல்லது BASE64 தரவை கீழே எடுக்கவும்/இறக்குமதி செய்யவும்</string>\n    <string name=\"type_image_link\">தொடங்க பட இணைப்பைத் தட்டச்சு செய்க</string>\n    <string name=\"paste_link\">இணைப்பை ஒட்டவும்</string>\n    <string name=\"kaleidoscope\">கெலிடோச்கோப்</string>\n    <string name=\"secondary_angle\">இரண்டாம் நிலை கோணம்</string>\n    <string name=\"sides\">பக்கங்களும்</string>\n    <string name=\"channel_mix\">சேனல் கலவை</string>\n    <string name=\"blue_green\">நீல பச்சை</string>\n    <string name=\"red_blue\">சிவப்பு நீலம்</string>\n    <string name=\"green_red\">பச்சை சிவப்பு</string>\n    <string name=\"into_red\">சிவப்பு நிறத்தில்</string>\n    <string name=\"into_green\">பச்சை நிறத்தில்</string>\n    <string name=\"into_blue\">நீல நிறத்தில்</string>\n    <string name=\"cyan\">சியான்</string>\n    <string name=\"magenta\">மெசந்தா</string>\n    <string name=\"yellow\">மஞ்சள்</string>\n    <string name=\"color_halftone\">வண்ண ஆல்ஃபோன்</string>\n    <string name=\"contour\">விளிம்பு</string>\n    <string name=\"levels\">நிலைகள்</string>\n    <string name=\"offset\">ஈடுசெய்யும்</string>\n    <string name=\"voronoi_crystallize\">வோரோனோய் படிகமாக்குகிறார்</string>\n    <string name=\"shape\">வடிவம்</string>\n    <string name=\"stretch\">நீட்டிக்க</string>\n    <string name=\"randomness\">சீரற்ற தன்மை</string>\n    <string name=\"despeckle\">சர்வாதிகாரம்</string>\n    <string name=\"diffuse\">பரவுகிறது</string>\n    <string name=\"dog\">நாய்</string>\n    <string name=\"second_radius\">இரண்டாவது ஆரம்</string>\n    <string name=\"equalize\">சமப்படுத்தவும்</string>\n    <string name=\"glow\">பளபளப்பு</string>\n    <string name=\"whirl_and_pinch\">சுழல் மற்றும் பிஞ்ச்</string>\n    <string name=\"pointillize\">சுட்டிக்காட்டுங்கள்</string>\n    <string name=\"border_color\">எல்லை நிறம்</string>\n    <string name=\"polar_coordinates\">துருவ ஆயங்கள், முனை ஆயங்கள்</string>\n    <string name=\"rect_to_polar\">துருவத்திற்கு செவ்வகம்</string>\n    <string name=\"polar_to_rect\">செவ்வகத்திற்கு துருவ</string>\n    <string name=\"invert_in_circle\">வட்டத்தில் தலைகீழ்</string>\n    <string name=\"reduce_noise\">சத்தத்தைக் குறைக்கவும்</string>\n    <string name=\"simple_solarize\">எளிய சோலரைச்</string>\n    <string name=\"weave\">நெசவு</string>\n    <string name=\"x_gap\">ஃச் இடைவெளி</string>\n    <string name=\"y_gap\">ஒய் இடைவெளி</string>\n    <string name=\"x_width\">ஃச் அகலம்</string>\n    <string name=\"y_wdth\">ஒய் அகலம்</string>\n    <string name=\"twirl\">சுழல்</string>\n    <string name=\"rubber_stmp\">ரப்பர் முத்திரை</string>\n    <string name=\"smear\">ச்மியர்</string>\n    <string name=\"density\">அடர்த்தி</string>\n    <string name=\"mix\">கலக்க</string>\n    <string name=\"sphere_lensh_distortion\">கோள லென்ச் விலகல்</string>\n    <string name=\"refraction_index\">ஒளிவிலகல் அட்டவணை</string>\n    <string name=\"arc\">வில்</string>\n    <string name=\"spread_angle\">கோணத்தை பரப்பவும்</string>\n    <string name=\"sparkle\">சிறு தீப்பொறி</string>\n    <string name=\"rays\">கதிர்கள்</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">சரிவு</string>\n    <string name=\"moire\">மேரி</string>\n    <string name=\"autumn\">இலையுதிர் காலம்</string>\n    <string name=\"bone\">எலும்பு</string>\n    <string name=\"jet\">தாரைப் பறனை</string>\n    <string name=\"winter\">குளிர்காலம்</string>\n    <string name=\"ocean\">கடல்</string>\n    <string name=\"summer\">கோடை காலம்</string>\n    <string name=\"spring\">வேனில்</string>\n    <string name=\"cool_variant\">குளிர் மாறுபாடு</string>\n    <string name=\"hsv\">எச்.எச்.வி.</string>\n    <string name=\"pink\">இளஞ்சிவப்பு</string>\n    <string name=\"hot\">சூடான</string>\n    <string name=\"parula\">பேசுங்கள்</string>\n    <string name=\"magma\">கற்குழம்பு</string>\n    <string name=\"inferno\">இன்ஃபெர்னோ</string>\n    <string name=\"plasma\">மின்மம்</string>\n    <string name=\"viridis\">விரிடிச்</string>\n    <string name=\"cividis\">சிடிச்</string>\n    <string name=\"twilight\">அந்தி</string>\n    <string name=\"twilight_shifted\">அந்தி மாற்றப்பட்டது</string>\n    <string name=\"auto_perspective\">முன்னோக்கு ஆட்டோ</string>\n    <string name=\"deskew\">திட்டம்</string>\n    <string name=\"allow_crop\">பயிர் அனுமதிக்கவும்</string>\n    <string name=\"crop_or_perspective\">பயிர் அல்லது முன்னோக்கு</string>\n    <string name=\"absolute\">தனி, சார்பிலா</string>\n    <string name=\"turbo\">டர்போ</string>\n    <string name=\"deep_green\">ஆழமான பச்சை</string>\n    <string name=\"lens_correction\">லென்ச் திருத்தம்</string>\n    <string name=\"target_lens_profile\">சாதொபொகு வடிவத்தில் இலக்கு லென்ச் சுயவிவர கோப்பு</string>\n    <string name=\"download_ready_lens_profiles\">தயாராக லென்ச் சுயவிவரங்களைப் பதிவிறக்கவும்</string>\n    <string name=\"part_percents\">பகுதி பெர்சென்ட்</string>\n    <string name=\"export_as_json\">சாதொபொகு ஆக ஏற்றுமதி</string>\n    <string name=\"export_as_json_sub\">சாதொபொகு பிரதிநிதித்துவமாக ஒரு தட்டு தரவுடன் சரத்தை நகலெடுக்கவும்</string>\n    <string name=\"seam_carving\">மடிப்பு செதுக்குதல்</string>\n    <string name=\"home_screen\">முகப்புத் திரை</string>\n    <string name=\"lock_screen\">பூட்டுத் திரை</string>\n    <string name=\"built_in\">உள்ளமைக்கப்பட்ட</string>\n    <string name=\"wallpapers_export\">வால்பேப்பர்கள் ஏற்றுமதி</string>\n    <string name=\"refresh\">புதுப்பிப்பு</string>\n    <string name=\"wallpapers_export_sub\">தற்போதைய வீடு, பூட்டு மற்றும் உள்ளமைக்கப்பட்ட வால்பேப்பர்களைப் பெறுங்கள்</string>\n    <string name=\"allow_access_to_all_files_for_wp\">எல்லா கோப்புகளுக்கும் அணுகலை அனுமதிக்கவும், வால்பேப்பர்களை மீட்டெடுக்க இது தேவை</string>\n    <string name=\"allow_read_media_images_for_wp\">வெளிப்புற சேமிப்பக அனுமதியை நிர்வகித்தல் போதாது, உங்கள் படங்களை அணுக அனுமதிக்க வேண்டும், \\\"அனைத்தையும் அனுமதிக்கவும்\\\" என்பதைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"add_preset_to_filename\">கோப்பு பெயருக்கு முன்னமைவைச் சேர்க்கவும்</string>\n    <string name=\"add_preset_to_filename_sub\">பட கோப்பு பெயருக்கு தேர்ந்தெடுக்கப்பட்ட முன்னமைவுடன் பின்னொட்டைச் சேர்க்கிறது</string>\n    <string name=\"add_image_scale_mode_to_filename\">கோப்பு பெயருக்கு பட அளவிலான பயன்முறையைச் சேர்க்கவும்</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">தேர்ந்தெடுக்கப்பட்ட பட அளவுகோல் பயன்முறையுடன் பின்னொட்டு பட கோப்பு பெயருக்குச் சேர்க்கிறது</string>\n    <string name=\"ascii_art\">தபஅநிகு கலை</string>\n    <string name=\"ascii_art_sub\">படத்தைப் போல தோற்றமளிக்கும் படத்தை ASCII உரையாக மாற்றவும்</string>\n    <string name=\"params\">அளவுரு</string>\n    <string name=\"invert_colors_ascii_sub\">சில சந்தர்ப்பங்களில் சிறந்த முடிவுக்கு படத்திற்கு எதிர்மறை வடிகட்டியைப் பயன்படுத்துகிறது</string>\n    <string name=\"processing_screenshot\">திரைக்காட்சி செயலாக்க</string>\n    <string name=\"screenshot_not_captured_try_again\">திரைக்காட்சி பிடிக்கப்படவில்லை, மீண்டும் முயற்சிக்கவும்</string>\n    <string name=\"skipped_saving\">சேமிப்பு தவிர்க்கப்பட்டது</string>\n    <string name=\"skipped_saving_multiple\">%1$s கோப்புகள் தவிர்க்கப்பட்டன</string>\n    <string name=\"allow_skip_if_larger\">பெரியதாக இருந்தால் தவிர்க்க அனுமதிக்கவும்</string>\n    <string name=\"allow_skip_if_larger_sub\">இதன் விளைவாக கோப்பு அளவு அசலை விட பெரியதாக இருந்தால் சில கருவிகள் படங்களை சேமிப்பதைத் தவிர்க்க அனுமதிக்கப்படும்</string>\n    <string name=\"qr_type_calendar_event\">காலண்டர் நிகழ்வு</string>\n    <string name=\"qr_type_contact_info\">தொடர்பு</string>\n    <string name=\"qr_type_email\">மின்னஞ்சல்</string>\n    <string name=\"qr_type_geo_point\">இடம்</string>\n    <string name=\"qr_type_phone\">தொலைபேசி</string>\n    <string name=\"qr_type_plain\">உரை</string>\n    <string name=\"qr_type_sms\">எச்.எம்.எச்</string>\n    <string name=\"qr_type_url\">வலைமுகவரி</string>\n    <string name=\"qr_type_wifi\">இல்</string>\n    <string name=\"open_network\">திறந்த பிணையம்</string>\n    <string name=\"not_specified\">இதற்கில்லை</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">தொலைபேசி</string>\n    <string name=\"message\">செய்தி</string>\n    <string name=\"address\">முகவரி</string>\n    <string name=\"subject\">பொருள்</string>\n    <string name=\"body\">உடல்</string>\n    <string name=\"name\">பெயர்</string>\n    <string name=\"organization\">நிறுவனம்</string>\n    <string name=\"title\">தலைப்பு</string>\n    <string name=\"phones\">தொலைபேசிகள்</string>\n    <string name=\"emails\">மின்னஞ்சல்கள்</string>\n    <string name=\"urls\">URLகள்</string>\n    <string name=\"addresses\">முகவரிகள்</string>\n    <string name=\"summary\">சுருக்கம்</string>\n    <string name=\"description\">விவரம்</string>\n    <string name=\"location\">இடம்</string>\n    <string name=\"organizer\">அமைப்பாளர்</string>\n    <string name=\"start_date\">தொடக்க தேதி</string>\n    <string name=\"end_date\">முடிவு தேதி</string>\n    <string name=\"status\">நிலைமை</string>\n    <string name=\"latitude\">அகலாங்கு</string>\n    <string name=\"longitude\">நெட்டாங்கு</string>\n    <string name=\"create_barcode\">பார்கோடு உருவாக்கவும்</string>\n    <string name=\"edit_barcode\">பார்கோடு திருத்தவும்</string>\n    <string name=\"wifi_configuration\">வைஃபை உள்ளமைவு</string>\n    <string name=\"security\">பாதுகாப்பு</string>\n    <string name=\"pick_contact\">தொடர்பைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"grant_contact_permission\">தேர்ந்தெடுக்கப்பட்ட தொடர்பைப் பயன்படுத்தி தானாக நிரப்ப அமைப்புகளில் தொடர்புகளுக்கு இசைவு வழங்கவும்</string>\n    <string name=\"contact_info\">தொடர்பு செய்தி</string>\n    <string name=\"first_name\">முதல் பெயர்</string>\n    <string name=\"middle_name\">நடுத்தர பெயர்</string>\n    <string name=\"last_name\">கடைசி பெயர்</string>\n    <string name=\"pronunciation\">உச்சரிப்பு</string>\n    <string name=\"add_phone\">தொலைபேசியைச் சேர்க்கவும்</string>\n    <string name=\"add_email\">மின்னஞ்சலைச் சேர்க்கவும்</string>\n    <string name=\"add_address\">முகவரியைச் சேர்க்கவும்</string>\n    <string name=\"website\">இணையதளம்</string>\n    <string name=\"add_website\">இணையதளத்தைச் சேர்க்கவும்</string>\n    <string name=\"formatted_name\">வடிவமைக்கப்பட்ட பெயர்</string>\n    <string name=\"qr_code_top_image\">பார்கோடு மேலே வைக்க இந்தப் படம் பயன்படுத்தப்படும்</string>\n    <string name=\"code_customization\">குறியீடு தனிப்பயனாக்கம்</string>\n    <string name=\"qr_logo_image\">இந்தப் படம் QR குறியீட்டின் மையத்தில் லோகோவாகப் பயன்படுத்தப்படும்</string>\n    <string name=\"logo\">சின்னம்</string>\n    <string name=\"logo_padding\">லோகோ திணிப்பு</string>\n    <string name=\"logo_size\">லோகோ அளவு</string>\n    <string name=\"logo_corners\">லோகோ மூலைகள்</string>\n    <string name=\"fourth_eye\">நான்காவது கண்</string>\n    <string name=\"fourth_eye_description\">கீழ் முனை மூலையில் நான்காவது கண்ணைச் சேர்ப்பதன் மூலம் qr குறியீட்டில் கண் சமச்சீர் சேர்க்கிறது</string>\n    <string name=\"pixel_shape\">படப்புள்ளி வடிவம்</string>\n    <string name=\"frame_shape\">சட்ட வடிவம்</string>\n    <string name=\"ball_shape\">பந்து வடிவம்</string>\n    <string name=\"error_correction_level\">பிழை திருத்த நிலை</string>\n    <string name=\"dark_color\">அடர் நிறம்</string>\n    <string name=\"light_color\">வெளிர் நிறம்</string>\n    <string name=\"hyper_os\">ஐப்பர் ஓஎச்</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS போன்ற பாணி</string>\n    <string name=\"mask_pattern\">முகமூடி முறை</string>\n    <string name=\"code_may_be_not_scannable\">இந்தக் குறியீட்டை ஸ்கேன் செய்ய முடியாமல் போகலாம், எல்லாச் சாதனங்களிலும் இதைப் படிக்கக்கூடிய வகையில் தோற்ற அளவுருக்களை மாற்றவும்</string>\n    <string name=\"not_scannable\">ஸ்கேன் செய்ய முடியாது</string>\n    <string name=\"launcher_mode_sub\">கருவிகள் மிகவும் கச்சிதமாக இருக்க முகப்புத் திரை ஆப் லாஞ்சர் போல இருக்கும்</string>\n    <string name=\"launcher_mode\">துவக்கி பயன்முறை</string>\n    <string name=\"flood_fill_sub\">தேர்ந்தெடுக்கப்பட்ட தூரிகை மற்றும் பாணியுடன் ஒரு பகுதியை நிரப்புகிறது</string>\n    <string name=\"flood_fill\">வெள்ளம் நிரப்பு</string>\n    <string name=\"spray\">தெளிக்கவும்</string>\n    <string name=\"spray_sub\">கிராஃபிட்டி பாணியிலான பாதையை வரைகிறது</string>\n    <string name=\"square_particles\">சதுர துகள்கள்</string>\n    <string name=\"square_particles_sub\">ஸ்ப்ரே துகள்கள் வட்டங்களுக்கு பதிலாக சதுர வடிவில் இருக்கும்</string>\n    <string name=\"palette_tools\">தட்டு கருவிகள்</string>\n    <string name=\"palette_tools_sub\">படத்திலிருந்து அடிப்படை/பொருளை உருவாக்கவும் அல்லது வெவ்வேறு தட்டு வடிவங்களில் இறக்குமதி/ஏற்றுமதி</string>\n    <string name=\"edit_palette\">தட்டு திருத்தவும்</string>\n    <string name=\"edit_palette_sub\">பல்வேறு வடிவங்களில் ஏற்றுமதி/இறக்குமதி தட்டு</string>\n    <string name=\"color_name\">வண்ண பெயர்</string>\n    <string name=\"palette_name\">தட்டு பெயர்</string>\n    <string name=\"palette_format\">தட்டு வடிவம்</string>\n    <string name=\"export_palette_sub\">உருவாக்கப்பட்ட தட்டுகளை வெவ்வேறு வடிவங்களுக்கு ஏற்றுமதி செய்யவும்</string>\n    <string name=\"add_color_palette_sub\">தற்போதைய தட்டுக்கு புதிய வண்ணத்தைச் சேர்க்கிறது</string>\n    <string name=\"palette_name_not_supported\">%1$s வடிவம் தட்டுப் பெயரை வழங்குவதை ஆதரிக்காது</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store கொள்கைகள் காரணமாக, இந்த அம்சத்தை தற்போதைய கட்டமைப்பில் சேர்க்க முடியாது. இந்தச் செயல்பாட்டை அணுக, மாற்று மூலத்திலிருந்து ImageToolboxஐப் பதிவிறக்கவும். கீழே உள்ள GitHub இல் கிடைக்கும் உருவாக்கங்களைக் காணலாம்.</string>\n    <string name=\"open_github_page\">கிதுப் பக்கத்தைத் திறக்கவும்</string>\n    <string name=\"overwrite_files_sub_short\">தேர்ந்தெடுக்கப்பட்ட கோப்புறையில் சேமிப்பதற்குப் பதிலாக அசல் கோப்பு புதியதாக மாற்றப்படும்</string>\n    <string name=\"hidden_watermark_text_detected\">மறைக்கப்பட்ட வாட்டர்மார்க் உரை கண்டறியப்பட்டது</string>\n    <string name=\"hidden_watermark_image_detected\">மறைக்கப்பட்ட வாட்டர்மார்க் படம் கண்டறியப்பட்டது</string>\n    <string name=\"this_image_was_hidden\">இந்த படம் மறைக்கப்பட்டது</string>\n    <string name=\"generative_inpaint\">உருவாக்கும் ஓவியம்</string>\n    <string name=\"generative_inpaint_sub\">OpenCV ஐ நம்பாமல், AI மாதிரியைப் பயன்படுத்தி ஒரு படத்தில் உள்ள பொருட்களை அகற்ற உங்களை அனுமதிக்கிறது. இந்த அம்சத்தைப் பயன்படுத்த, ஆப்ஸ் GitHub இலிருந்து தேவையான மாதிரியை (~200 MB) பதிவிறக்கும்</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV ஐ நம்பாமல், AI மாதிரியைப் பயன்படுத்தி ஒரு படத்தில் உள்ள பொருட்களை அகற்ற உங்களை அனுமதிக்கிறது. இது நீண்ட கால நடவடிக்கையாக இருக்கலாம்</string>\n    <string name=\"error_level_analysis\">பிழை நிலை பகுப்பாய்வு</string>\n    <string name=\"luminance_gradient\">ஒளிர்வு சாய்வு</string>\n    <string name=\"average_distance\">சராசரி தூரம்</string>\n    <string name=\"copy_move_detection\">நகலெடு கண்டறிதல்</string>\n    <string name=\"retain\">தக்கவைத்துக்கொள்</string>\n    <string name=\"coefficent\">திறன்மிக்கது</string>\n    <string name=\"clipboard_data_is_too_large\">கிளிப்போர்டு தரவு மிகவும் பெரியதாக உள்ளது</string>\n    <string name=\"data_is_too_large_to_copy\">தரவு நகலெடுக்க மிகவும் பெரியது</string>\n    <string name=\"simple_weave_pixelization\">எளிய நெசவு பிக்சலைசேஷன்</string>\n    <string name=\"staggered_pixelization\">நிலைகுலைந்த பிக்சலைசேஷன்</string>\n    <string name=\"cross_pixelization\">குறுக்கு பிக்சலைசேஷன்</string>\n    <string name=\"micro_macro_pixelization\">மைக்ரோ மேக்ரோ பிக்சலைசேஷன்</string>\n    <string name=\"orbital_pixelization\">சுற்றுப்பாதை பிக்சலைசேஷன்</string>\n    <string name=\"vortex_pixelization\">சுழல் பிக்சலைசேஷன்</string>\n    <string name=\"pulse_grid_pixelization\">பல்ஸ் கிரிட் பிக்சலைசேஷன்</string>\n    <string name=\"nucleus_pixelization\">நியூக்ளியஸ் பிக்சலைசேஷன்</string>\n    <string name=\"radial_weave_pixelization\">ரேடியல் வீவ் பிக்சலைசேஷன்</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\" ஐ திறக்க முடியவில்லை</string>\n    <string name=\"snowfall_mode\">பனிப்பொழிவு முறை</string>\n    <string name=\"enabled\">இயக்கப்பட்டது</string>\n    <string name=\"border_frame\">பார்டர் ஃப்ரேம்</string>\n    <string name=\"glitch_variant\">தடுமாற்றம் மாறுபாடு</string>\n    <string name=\"channel_shift\">சேனல் ஷிப்ட்</string>\n    <string name=\"max_offset\">அதிகபட்ச ஆஃப்செட்</string>\n    <string name=\"vhs\">விஎச்எஸ்</string>\n    <string name=\"block_glitch\">தடுமாற்றம்</string>\n    <string name=\"block_size\">தொகுதி அளவு</string>\n    <string name=\"crt_curvature\">CRT வளைவு</string>\n    <string name=\"curvature\">வளைவு</string>\n    <string name=\"chroma\">குரோமா</string>\n    <string name=\"pixel_melt\">பிக்சல் உருகும்</string>\n    <string name=\"max_drop\">மேக்ஸ் டிராப்</string>\n    <string name=\"ai_tools\">AI கருவிகள்</string>\n    <string name=\"ai_tools_sub\">AI மாதிரிகள் மூலம் படங்களைச் செயலாக்க பல்வேறு கருவிகள் கலைப் பொருட்களை அகற்றுதல் அல்லது நீக்குதல் போன்றவை</string>\n    <string name=\"model_anime_undeint\">சுருக்க, துண்டிக்கப்பட்ட கோடுகள்</string>\n    <string name=\"model_broadcast\">கார்ட்டூன்கள், ஒளிபரப்பு சுருக்கம்</string>\n    <string name=\"model_rgb_max_denoise_fp16\">பொது சுருக்கம், பொது இரைச்சல்</string>\n    <string name=\"model_wb_denoise\">நிறமற்ற கார்ட்டூன் சத்தம்</string>\n    <string name=\"model_span_anime_pretrain\">வேகமான, பொதுவான சுருக்கம், பொது இரைச்சல், அனிமேஷன்/காமிக்ஸ்/அனிம்</string>\n    <string name=\"model_book_scan\">புத்தக ஸ்கேனிங்</string>\n    <string name=\"model_overexposure\">வெளிப்பாடு திருத்தம்</string>\n    <string name=\"model_fbcnn_color_fp16\">பொதுவான சுருக்க, வண்ணப் படங்களில் சிறந்தது</string>\n    <string name=\"model_fbcnn_gray_fp16\">பொதுவான சுருக்கம், கிரேஸ்கேல் படங்கள் ஆகியவற்றில் சிறந்தது</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">பொதுவான சுருக்கம், கிரேஸ்கேல் படங்கள், வலுவானது</string>\n    <string name=\"model_scunet_color_gan_fp16\">பொது இரைச்சல், வண்ண படங்கள்</string>\n    <string name=\"model_scunet_color_psnr_fp16\">பொது இரைச்சல், வண்ணப் படங்கள், சிறந்த விவரங்கள்</string>\n    <string name=\"model_scunet_gray_15_fp16\">பொது இரைச்சல், கிரேஸ்கேல் படங்கள்</string>\n    <string name=\"model_scunet_gray_25_fp16\">பொதுவான சத்தம், கிரேஸ்கேல் படங்கள், வலிமையானது</string>\n    <string name=\"model_scunet_gray_50_fp16\">பொதுவான சத்தம், கிரேஸ்கேல் படங்கள், வலிமையானது</string>\n    <string name=\"model_jpeg_destroyer\">பொது சுருக்கம்</string>\n    <string name=\"model_jaywreck\">பொது சுருக்கம்</string>\n    <string name=\"model_h264\">டெக்ஸ்டுரைசேஷன், h264 சுருக்கம்</string>\n    <string name=\"model_vhs\">VHS சுருக்கம்</string>\n    <string name=\"model_cinepak\">தரமற்ற சுருக்கம் (சினிபாக், எம்எஸ்வீடியோ1, ரோக்)</string>\n    <string name=\"model_debink_v4\">பிங்க் சுருக்கம், வடிவவியலில் சிறந்தது</string>\n    <string name=\"model_debink_v5\">பிங்க் சுருக்கம், வலுவானது</string>\n    <string name=\"model_debink_v6\">பிங்க் சுருக்க, மென்மையானது, விவரங்களைத் தக்கவைக்கிறது</string>\n    <string name=\"model_antialias\">படிக்கட்டு-படி விளைவை நீக்குதல், மென்மையாக்குதல்</string>\n    <string name=\"model_kdm_scans\">ஸ்கேன் செய்யப்பட்ட கலை/வரைபடங்கள், லேசான சுருக்கம், மோயர்</string>\n    <string name=\"model_bandage\">கலர் பேண்டிங்</string>\n    <string name=\"model_halftone\">மெதுவாக, ஹால்ஃப்டோன்களை நீக்குகிறது</string>\n    <string name=\"model_colorizer\">கிரேஸ்கேல்/பிடபிள்யூ படங்களுக்கான ஜெனரல் கலரைசர், சிறந்த முடிவுகளுக்கு DDColor ஐப் பயன்படுத்தவும்</string>\n    <string name=\"model_deedge\">விளிம்பு அகற்றுதல்</string>\n    <string name=\"model_desharpen\">அதிகப்படியான கூர்மையை நீக்குகிறது</string>\n    <string name=\"model_dither\">மெதுவான, சலிப்பு</string>\n    <string name=\"model_gainres\">மாற்று மாற்று, பொது கலைப்பொருட்கள், CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 செயலாக்கத்தை ஸ்கேன் செய்கிறது</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">இலகுரக படத்தை மேம்படுத்தும் மாதிரி</string>\n    <string name=\"model_bcgone_detailed_v2\">சுருக்க கலைப்பொருளை அகற்றுதல்</string>\n    <string name=\"model_bcgone_smooth\">சுருக்க கலைப்பொருளை அகற்றுதல்</string>\n    <string name=\"model_bandage_smooth\">மென்மையான முடிவுகளுடன் கட்டு அகற்றுதல்</string>\n    <string name=\"model_bendel_halftone\">ஹாஃப்டோன் மாதிரி செயலாக்கம்</string>\n    <string name=\"model_dither_deleter_v3_smooth\">டிதர் பேட்டர்ன் அகற்றுதல் V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG கலைப்பொருள் அகற்றுதல் V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 அமைப்பு விரிவாக்கம்</string>\n    <string name=\"model_vhs_sharpen\">VHS கூர்மைப்படுத்துதல் மற்றும் மேம்படுத்துதல்</string>\n    <string name=\"merging\">இணைத்தல்</string>\n    <string name=\"chunk_size\">துண்டு அளவு</string>\n    <string name=\"overlap_size\">ஒன்றுடன் ஒன்று அளவு</string>\n    <string name=\"note_chunk_info\">%1$s pxக்கு மேலான படங்கள் வெட்டப்பட்டு, துண்டுகளாகச் செயலாக்கப்படும், காணக்கூடிய சீம்களைத் தடுக்க இவற்றை ஒன்றுடன் ஒன்று இணைக்கும்.</string>\n    <string name=\"large_chunk_warning\">பெரிய அளவுகள் குறைந்த-இறுதி சாதனங்களுடன் உறுதியற்ற தன்மையை ஏற்படுத்தும்</string>\n    <string name=\"select_one_to_start\">தொடங்குவதற்கு ஒன்றைத் தேர்ந்தெடுக்கவும்</string>\n    <string name=\"delete_model_sub\">%1$s மாதிரியை நீக்க விரும்புகிறீர்களா? நீங்கள் அதை மீண்டும் பதிவிறக்கம் செய்ய வேண்டும்</string>\n    <string name=\"confirm\">உறுதிப்படுத்தவும்</string>\n    <string name=\"models\">மாதிரிகள்</string>\n    <string name=\"downloaded_models\">பதிவிறக்கம் செய்யப்பட்ட மாதிரிகள்</string>\n    <string name=\"available_models\">கிடைக்கும் மாதிரிகள்</string>\n    <string name=\"preparing\">தயாராகிறது</string>\n    <string name=\"active_model\">செயலில் உள்ள மாதிரி</string>\n    <string name=\"failed_to_open_session\">அமர்வைத் திறக்க முடியவில்லை</string>\n    <string name=\"only_onnx_models\">.onnx/.ort மாதிரிகளை மட்டுமே இறக்குமதி செய்ய முடியும்</string>\n    <string name=\"import_model\">இறக்குமதி மாதிரி</string>\n    <string name=\"import_model_sub\">மேலும் பயன்படுத்த தனிப்பயன் onnx மாதிரியை இறக்குமதி செய்யவும், onnx/ort மாதிரிகள் மட்டுமே ஏற்றுக்கொள்ளப்படும், கிட்டத்தட்ட அனைத்து esrgan போன்ற மாறுபாடுகளையும் ஆதரிக்கிறது</string>\n    <string name=\"imported_models\">இறக்குமதி செய்யப்பட்ட மாதிரிகள்</string>\n    <string name=\"model_scunet_color_15_fp16\">பொது இரைச்சல், வண்ண படங்கள்</string>\n    <string name=\"model_scunet_color_25_fp16\">பொதுவான சத்தம், வண்ணப் படங்கள், வலிமையானது</string>\n    <string name=\"model_scunet_color_50_fp16\">பொதுவான சத்தம், வண்ண படங்கள், வலிமையானது</string>\n    <string name=\"model_artifacts_dithering_alsa\">கலைப்பொருட்கள் மற்றும் வண்ணப் பிணைப்பைக் குறைக்கிறது, மென்மையான சாய்வு மற்றும் தட்டையான வண்ணப் பகுதிகளை மேம்படுத்துகிறது.</string>\n    <string name=\"model_nmkd_brighten_redux\">இயற்கையான வண்ணங்களைப் பாதுகாக்கும் போது சமநிலை சிறப்பம்சங்களுடன் படத்தின் பிரகாசம் மற்றும் மாறுபாட்டை மேம்படுத்துகிறது.</string>\n    <string name=\"model_nmkd_brighten\">இருண்ட படங்களைப் பிரகாசமாக்குகிறது, அதே நேரத்தில் விவரங்கள் மற்றும் அதிகப்படியான வெளிப்பாட்டைத் தவிர்க்கிறது.</string>\n    <string name=\"model_nmkd_detoon\">அதிகப்படியான வண்ண டோனிங்கை நீக்குகிறது மற்றும் மிகவும் நடுநிலை மற்றும் இயற்கையான வண்ண சமநிலையை மீட்டெடுக்கிறது.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">நுண்ணிய விவரங்கள் மற்றும் அமைப்புகளைப் பாதுகாப்பதில் முக்கியத்துவத்துடன் பாய்சன் அடிப்படையிலான இரைச்சல் டோனிங்கைப் பயன்படுத்துகிறது.</string>\n    <string name=\"model_noise_toner_poisson_soft\">மென்மையான மற்றும் குறைவான ஆக்ரோஷமான காட்சி முடிவுகளுக்கு மென்மையான பாய்சன் இரைச்சல் டோனிங்கைப் பயன்படுத்துகிறது.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">சீரான இரைச்சல் டோனிங் விவரம் பாதுகாப்பு மற்றும் படத்தின் தெளிவு ஆகியவற்றில் கவனம் செலுத்துகிறது.</string>\n    <string name=\"model_noise_toner_uniform_soft\">நுட்பமான அமைப்பு மற்றும் மென்மையான தோற்றத்திற்காக மென்மையான சீரான இரைச்சல் டோனிங்.</string>\n    <string name=\"model_repainter\">கலைப்பொருட்களை மீண்டும் வர்ணம் பூசுவதன் மூலமும், படத்தின் நிலைத்தன்மையை மேம்படுத்துவதன் மூலமும் சேதமடைந்த அல்லது சீரற்ற பகுதிகளை சரிசெய்கிறது.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">லைட்வெயிட் டிபாண்டிங் மாடல், இது குறைந்த செயல்திறன் செலவில் வண்ணப் பட்டையை நீக்குகிறது.</string>\n    <string name=\"model_jpeg_0_20\">மேம்பட்ட தெளிவுக்காக மிக உயர்ந்த சுருக்க கலைப்பொருட்கள் (0-20% தரம்) கொண்ட படங்களை மேம்படுத்துகிறது.</string>\n    <string name=\"model_jpeg_20_40\">உயர் சுருக்க கலைப்பொருட்கள் (20-40% தரம்) கொண்ட படங்களை மேம்படுத்துகிறது, விவரங்களை மீட்டமைக்கிறது மற்றும் சத்தத்தைக் குறைக்கிறது.</string>\n    <string name=\"model_jpeg_40_60\">மிதமான சுருக்கத்துடன் படங்களை மேம்படுத்துகிறது (40-60% தரம்), கூர்மை மற்றும் மென்மையை சமநிலைப்படுத்துகிறது.</string>\n    <string name=\"model_jpeg_60_80\">நுட்பமான விவரங்கள் மற்றும் அமைப்புகளை மேம்படுத்த, ஒளி சுருக்கத்துடன் (60-80% தரம்) படங்களைச் செம்மைப்படுத்துகிறது.</string>\n    <string name=\"model_jpeg_80_100\">இயற்கையான தோற்றத்தையும் விவரங்களையும் பாதுகாக்கும் அதே வேளையில் இழப்பற்ற படங்களை (80-100% தரம்) சற்று மேம்படுத்துகிறது.</string>\n    <string name=\"model_spongecolor_lite\">எளிய மற்றும் வேகமான வண்ணமயமாக்கல், கார்ட்டூன்கள், சிறந்தவை அல்ல</string>\n    <string name=\"model_deblr\">கலைப்பொருட்களை அறிமுகப்படுத்தாமல், பட மங்கலை சிறிது குறைக்கிறது, கூர்மையை மேம்படுத்துகிறது.</string>\n    <string name=\"processing_channel\">நீண்ட கால செயல்பாடுகள்</string>\n    <string name=\"processing_image\">படத்தை செயலாக்குகிறது</string>\n    <string name=\"processing\">செயலாக்கம்</string>\n    <string name=\"model_artifacts_jpg_0_20\">மிகக் குறைந்த தரமான படங்களில் (0-20%) கனமான JPEG சுருக்கக் கலைப்பொருட்களை நீக்குகிறது.</string>\n    <string name=\"model_artifacts_jpg_20_40\">மிகவும் சுருக்கப்பட்ட படங்களில் (20-40%) வலுவான JPEG கலைப்பொருட்களைக் குறைக்கிறது.</string>\n    <string name=\"model_artifacts_jpg_40_60\">பட விவரங்களை (40-60%) பாதுகாக்கும் போது மிதமான JPEG கலைப்பொருட்களை சுத்தம் செய்கிறது.</string>\n    <string name=\"model_artifacts_jpg_60_80\">ஒளி JPEG கலைப்பொருட்களை மிகவும் உயர்தர படங்களில் (60-80%) செம்மைப்படுத்துகிறது.</string>\n    <string name=\"model_artifacts_jpg_80_100\">சிறிய JPEG கலைப்பொருட்களை கிட்டத்தட்ட இழப்பற்ற படங்களில் (80-100%) நுட்பமாகக் குறைக்கிறது.</string>\n    <string name=\"model_redetail_v2\">சிறந்த விவரங்கள் மற்றும் அமைப்புகளை மேம்படுத்துகிறது, கனமான கலைப்பொருட்கள் இல்லாமல் உணரப்பட்ட கூர்மையை மேம்படுத்துகிறது.</string>\n    <string name=\"processing_finished\">செயலாக்கம் முடிந்தது</string>\n    <string name=\"processing_failed\">செயலாக்கம் தோல்வியடைந்தது</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">வேகத்திற்கு உகந்ததாக, இயற்கையான தோற்றத்தை வைத்து, தோல் அமைப்புகளையும் விவரங்களையும் மேம்படுத்துகிறது.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG சுருக்க கலைப்பொருட்களை நீக்குகிறது மற்றும் சுருக்கப்பட்ட புகைப்படங்களுக்கான படத்தின் தரத்தை மீட்டெடுக்கிறது.</string>\n    <string name=\"model_iso_denoise_v1\">குறைந்த வெளிச்சத்தில் எடுக்கப்பட்ட புகைப்படங்களில் ISO சத்தத்தைக் குறைக்கிறது, விவரங்களைப் பாதுகாக்கிறது.</string>\n    <string name=\"model_dejumbo\">அதிகப்படியான அல்லது \\\"ஜம்போ\\\" சிறப்பம்சங்களை சரிசெய்து சிறந்த டோனல் சமநிலையை மீட்டெடுக்கிறது.</string>\n    <string name=\"model_ddcolor_tiny\">கிரேஸ்கேல் படங்களுக்கு இயற்கையான வண்ணங்களைச் சேர்க்கும் இலகுரக மற்றும் வேகமான வண்ணமயமாக்கல் மாதிரி.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">டெனோயிஸ்</string>\n    <string name=\"type_colorize\">வண்ணமயமாக்கு</string>\n    <string name=\"type_artifacts\">கலைப்பொருட்கள்</string>\n    <string name=\"type_enhance\">மேம்படுத்து</string>\n    <string name=\"type_anime\">அசையும்</string>\n    <string name=\"type_scans\">ஸ்கேன் செய்கிறது</string>\n    <string name=\"type_upscale\">மேல்தட்டு</string>\n    <string name=\"model_realesrgan_x4v3\">பொதுப் படங்களுக்கான X4 அப்ஸ்கேலர்; குறைந்த GPU மற்றும் நேரத்தைப் பயன்படுத்தும் சிறிய மாடல், மிதமான தேய்மானம் மற்றும் denoise.</string>\n    <string name=\"model_realesrgan_x2plus\">பொதுவான படங்கள், இழைமங்களைப் பாதுகாத்தல் மற்றும் இயற்கையான விவரங்களுக்கு X2 அப்ஸ்கேலர்.</string>\n    <string name=\"model_realesrgan_x4plus\">மேம்படுத்தப்பட்ட இழைமங்கள் மற்றும் யதார்த்தமான முடிவுகளுடன் கூடிய பொதுவான படங்களுக்கான X4 அப்ஸ்கேலர்.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">அனிம் படங்களுக்கு உகந்ததாக X4 அப்ஸ்கேலர்; கூர்மையான கோடுகள் மற்றும் விவரங்களுக்கு 6 RRDB தொகுதிகள்.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE இழப்புடன் கூடிய X4 அப்ஸ்கேலர், மென்மையான முடிவுகளைத் தருகிறது மற்றும் பொதுவான படங்களுக்குக் குறைக்கப்பட்ட கலைப்பொருட்கள்.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler அனிம் படங்களுக்கு உகந்ததாக உள்ளது; கூர்மையான விவரங்கள் மற்றும் மென்மையான கோடுகள் கொண்ட 4B32F மாறுபாடு.</string>\n    <string name=\"model_ultrasharp_v2_x4\">பொதுப் படங்களுக்கான X4 UltraSharp V2 மாதிரி; கூர்மை மற்றும் தெளிவை வலியுறுத்துகிறது.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 அல்ட்ராஷார்ப் V2 லைட்; வேகமான மற்றும் சிறிய, குறைவான GPU நினைவகத்தைப் பயன்படுத்தும் போது விவரங்களைப் பாதுகாக்கிறது.</string>\n    <string name=\"model_rmbg_1_4\">விரைவான பின்னணியை அகற்றுவதற்கான இலகுரக மாதிரி. சீரான செயல்திறன் மற்றும் துல்லியம். உருவப்படங்கள், பொருள்கள் மற்றும் காட்சிகளுடன் வேலை செய்கிறது. பெரும்பாலான பயன்பாட்டு நிகழ்வுகளுக்கு பரிந்துரைக்கப்படுகிறது.</string>\n    <string name=\"type_removebg\">பிஜியை அகற்று</string>\n    <string name=\"horizontal_border_thickness\">கிடைமட்ட பார்டர் தடிமன்</string>\n    <string name=\"vertical_border_thickness\">செங்குத்து பார்டர் தடிமன்</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s நிறம்</item>\n        <item quantity=\"other\">%1$s வண்ணங்கள்</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">தற்போதைய மாடல் துண்டிப்பதை ஆதரிக்காது, படம் அசல் பரிமாணங்களில் செயலாக்கப்படும், இது அதிக நினைவக நுகர்வு மற்றும் குறைந்த-இறுதி சாதனங்களில் சிக்கல்களை ஏற்படுத்தலாம்</string>\n    <string name=\"chunking_disabled\">துண்டிப்பு முடக்கப்பட்டது, படம் அசல் பரிமாணங்களில் செயலாக்கப்படும், இது அதிக நினைவக நுகர்வு மற்றும் குறைந்த-இறுதி சாதனங்களில் சிக்கல்களை ஏற்படுத்தலாம் ஆனால் அனுமானத்தில் சிறந்த முடிவுகளை அளிக்கலாம்</string>\n    <string name=\"chunking\">துண்டித்தல்</string>\n    <string name=\"model_u2net\">பின்னணியை அகற்றுவதற்கான உயர் துல்லியமான படப் பிரிவு மாதிரி</string>\n    <string name=\"model_u2netp\">U2Net இன் இலகுரக பதிப்பு, சிறிய நினைவகப் பயன்பாட்டுடன் வேகமான பின்னணியை அகற்றும்.</string>\n    <string name=\"model_ddcolor\">முழு DDColor மாதிரியானது குறைந்தபட்ச கலைப்பொருட்கள் கொண்ட பொதுவான படங்களுக்கு உயர்தர வண்ணமயமாக்கலை வழங்குகிறது. அனைத்து வண்ணமயமாக்கல் மாதிரிகளின் சிறந்த தேர்வு.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor பயிற்சி பெற்ற மற்றும் தனிப்பட்ட கலை தரவுத்தொகுப்புகள்; குறைவான யதார்த்தமற்ற வண்ண கலைப்பொருட்களுடன் மாறுபட்ட மற்றும் கலை வண்ணமயமாக்கல் முடிவுகளை உருவாக்குகிறது.</string>\n    <string name=\"model_birefnet\">துல்லியமான பின்னணியை அகற்றுவதற்காக ஸ்வின் டிரான்ஸ்ஃபார்மரை அடிப்படையாகக் கொண்ட இலகுரக BiRefNet மாதிரி.</string>\n    <string name=\"model_inspyrenet\">குறிப்பாக சிக்கலான பொருள்கள் மற்றும் தந்திரமான பின்னணியில் கூர்மையான விளிம்புகள் மற்றும் சிறந்த விவரங்களைப் பாதுகாப்பதன் மூலம் உயர்தர பின்னணி நீக்கம்.</string>\n    <string name=\"model_isnet\">மென்மையான விளிம்புகள் கொண்ட துல்லியமான முகமூடிகளை உருவாக்கும் பின்னணி அகற்றும் மாதிரி, பொதுவான பொருள்கள் மற்றும் மிதமான விவரங்களைப் பாதுகாப்பதற்கு ஏற்றது.</string>\n    <string name=\"model_already_downloaded\">மாடல் ஏற்கனவே பதிவிறக்கம் செய்யப்பட்டுள்ளது</string>\n    <string name=\"model_successfully_imported\">மாடல் வெற்றிகரமாக இறக்குமதி செய்யப்பட்டது</string>\n    <string name=\"type\">வகை</string>\n    <string name=\"keyword\">முக்கிய வார்த்தை</string>\n    <string name=\"very_fast\">மிக வேகமாக</string>\n    <string name=\"normal\">இயல்பானது</string>\n    <string name=\"slow\">மெதுவாக</string>\n    <string name=\"very_slow\">மிக மெதுவாக</string>\n    <string name=\"compute_percents\">சதவீதங்களைக் கணக்கிடுங்கள்</string>\n    <string name=\"minimum_value_is\">குறைந்தபட்ச மதிப்பு %1$s</string>\n    <string name=\"warp_sub\">விரல்களால் வரைவதன் மூலம் படத்தை சிதைக்கவும்</string>\n    <string name=\"warp\">வார்ப்</string>\n    <string name=\"hardness\">கடினத்தன்மை</string>\n    <string name=\"warp_mode\">வார்ப் பயன்முறை</string>\n    <string name=\"warp_mode_move\">நகர்த்தவும்</string>\n    <string name=\"warp_mode_grow\">வளருங்கள்</string>\n    <string name=\"warp_mode_shrink\">சுருக்கு</string>\n    <string name=\"warp_mode_swirl_cw\">சுழி CW</string>\n    <string name=\"warp_mode_swirl_ccw\">சுழல் CCW</string>\n    <string name=\"fade_strength\">மங்கலான வலிமை</string>\n    <string name=\"top_drop\">டாப் டிராப்</string>\n    <string name=\"bottom_drop\">பாட்டம் டிராப்</string>\n    <string name=\"start_drop\">துளியைத் தொடங்கு</string>\n    <string name=\"end_drop\">என்ட் டிராப்</string>\n    <string name=\"downloading\">பதிவிறக்குகிறது</string>\n    <string name=\"smooth_shapes\">மென்மையான வடிவங்கள்</string>\n    <string name=\"smooth_shapes_sub\">மென்மையான, இயற்கையான வடிவங்களுக்கு நிலையான வட்டமான செவ்வகங்களுக்குப் பதிலாக சூப்பர் எலிப்ஸைப் பயன்படுத்தவும்</string>\n    <string name=\"shape_type\">வடிவ வகை</string>\n    <string name=\"cut\">வெட்டு</string>\n    <string name=\"rounded\">வட்டமானது</string>\n    <string name=\"smooth\">மென்மையானது</string>\n    <string name=\"cut_shapes_sub\">ரவுண்டிங் இல்லாமல் கூர்மையான விளிம்புகள்</string>\n    <string name=\"rounded_shapes_sub\">கிளாசிக் வட்டமான மூலைகள்</string>\n    <string name=\"shapes_type\">வடிவங்களின் வகை</string>\n    <string name=\"corners_size\">மூலைகளின் அளவு</string>\n    <string name=\"squircle\">அணில்</string>\n    <string name=\"squircle_shapes_sub\">நேர்த்தியான வட்டமான UI கூறுகள்</string>\n    <string name=\"filename_format\">கோப்பு பெயர் வடிவம்</string>\n    <string name=\"prefix_pattern_description\">திட்டப் பெயர்கள், பிராண்டுகள் அல்லது தனிப்பட்ட குறிச்சொற்களுக்கு ஏற்றவாறு, கோப்பின் பெயரின் தொடக்கத்திலேயே தனிப்பயன் உரை வைக்கப்பட்டுள்ளது.</string>\n    <string name=\"original_filename_pattern_description\">அசல் கோப்பு பெயரை நீட்டிப்பு இல்லாமல் பயன்படுத்துகிறது, இது மூல அடையாளத்தை அப்படியே வைத்திருக்க உதவுகிறது.</string>\n    <string name=\"width_pattern_description\">பிக்சல்களில் உள்ள படத்தின் அகலம், தெளிவுத்திறன் மாற்றங்கள் அல்லது அளவிடுதல் முடிவுகளைக் கண்காணிக்கப் பயன்படுகிறது.</string>\n    <string name=\"height_pattern_description\">பிக்சல்களில் உள்ள படத்தின் உயரம், விகிதங்கள் அல்லது ஏற்றுமதிகளுடன் பணிபுரியும் போது உதவியாக இருக்கும்.</string>\n    <string name=\"random_numbers_pattern_description\">தனிப்பட்ட கோப்புப் பெயர்களுக்கு உத்தரவாதம் அளிக்க சீரற்ற இலக்கங்களை உருவாக்குகிறது; நகல்களுக்கு எதிராக கூடுதல் பாதுகாப்பிற்காக அதிக இலக்கங்களைச் சேர்க்கவும்.</string>\n    <string name=\"sequence_number_pattern_description\">தொகுப்பு ஏற்றுமதிகளுக்கான தானியங்கு-அதிகரிப்பு கவுண்டர், ஒரு அமர்வில் பல படங்களைச் சேமிக்கும் போது சிறந்தது.</string>\n    <string name=\"preset_info_pattern_description\">பயன்படுத்தப்பட்ட முன்னமைக்கப்பட்ட பெயரை கோப்பு பெயரில் செருகும், இதன் மூலம் படம் எவ்வாறு செயலாக்கப்பட்டது என்பதை நீங்கள் எளிதாக நினைவில் கொள்ளலாம்.</string>\n    <string name=\"scale_mode_pattern_description\">செயலாக்கத்தின் போது பயன்படுத்தப்படும் பட அளவிடுதல் பயன்முறையைக் காட்டுகிறது, மறுஅளவிடப்பட்ட, செதுக்கப்பட்ட அல்லது பொருத்தப்பட்ட படங்களை வேறுபடுத்த உதவுகிறது.</string>\n    <string name=\"suffix_pattern_description\">_v2, _edited, அல்லது _final போன்ற பதிப்பிற்குப் பயன்படும், கோப்புப் பெயரின் இறுதியில் வைக்கப்படும் தனிப்பயன் உரை.</string>\n    <string name=\"extension_pattern_description\">கோப்பு நீட்டிப்பு (png, jpg, webp, முதலியன), உண்மையான சேமிக்கப்பட்ட வடிவத்துடன் தானாகவே பொருந்தும்.</string>\n    <string name=\"formatted_timestamp_pattern_description\">ஒரு தனிப்பயனாக்கக்கூடிய நேர முத்திரை, சரியான வரிசைப்படுத்துதலுக்கான ஜாவா விவரக்குறிப்பு மூலம் உங்கள் சொந்த வடிவமைப்பை வரையறுக்க உதவுகிறது.</string>\n    <string name=\"fling_type\">ஃபிளிங் வகை</string>\n    <string name=\"android_native\">ஆண்ட்ராய்டு நேட்டிவ்</string>\n    <string name=\"ios_style\">iOS உடை</string>\n    <string name=\"smooth_curve\">மென்மையான வளைவு</string>\n    <string name=\"quick_stop\">விரைவு நிறுத்து</string>\n    <string name=\"bouncy\">துள்ளல்</string>\n    <string name=\"floaty\">மிதக்கும்</string>\n    <string name=\"snappy\">ஸ்னாப்பி</string>\n    <string name=\"ultra_smooth\">அல்ட்ரா ஸ்மூத்</string>\n    <string name=\"adaptive\">தழுவல்</string>\n    <string name=\"accessibility_aware\">அணுகல் விழிப்புணர்வு</string>\n    <string name=\"reduced_motion\">குறைக்கப்பட்ட இயக்கம்</string>\n    <string name=\"android_native_sub\">நேட்டிவ் ஆண்ட்ராய்டு ஸ்க்ரோல் இயற்பியல்</string>\n    <string name=\"smooth_sub\">பொதுவான பயன்பாட்டிற்கு சீரான, மென்மையான ஸ்க்ரோலிங்</string>\n    <string name=\"ios_style_sub\">அதிக உராய்வு iOS போன்ற உருள் நடத்தை</string>\n    <string name=\"smooth_curve_sub\">தனித்துவமான ஸ்க்ரோல் ஃபீலுக்கு தனித்துவமான ஸ்ப்லைன் வளைவு</string>\n    <string name=\"quick_stop_sub\">விரைவான நிறுத்தத்துடன் துல்லியமான ஸ்க்ரோலிங்</string>\n    <string name=\"bouncy_sub\">விளையாட்டுத்தனமான, பதிலளிக்கக்கூடிய துள்ளல் உருள்</string>\n    <string name=\"floaty_sub\">உள்ளடக்க உலாவலுக்கான நீண்ட, சறுக்கும் சுருள்கள்</string>\n    <string name=\"snappy_sub\">ஊடாடும் UIகளுக்கான விரைவான, பதிலளிக்கக்கூடிய ஸ்க்ரோலிங்</string>\n    <string name=\"ultra_smooth_sub\">நீட்டிக்கப்பட்ட வேகத்துடன் பிரீமியம் மென்மையான ஸ்க்ரோலிங்</string>\n    <string name=\"adaptive_sub\">பறக்கும் வேகத்தின் அடிப்படையில் இயற்பியலைச் சரிசெய்கிறது</string>\n    <string name=\"accessibility_aware_sub\">கணினி அணுகல்தன்மை அமைப்புகளை மதிக்கிறது</string>\n    <string name=\"reduced_motion_sub\">அணுகல் தேவைகளுக்கான குறைந்தபட்ச இயக்கம்</string>\n    <string name=\"primary_lines\">முதன்மை கோடுகள்</string>\n    <string name=\"primary_lines_sub\">ஒவ்வொரு ஐந்தாவது வரியும் தடிமனான வரியைச் சேர்க்கிறது</string>\n    <string name=\"fill_color\">நிறத்தை நிரப்பவும்</string>\n    <string name=\"hidden_tools\">மறைக்கப்பட்ட கருவிகள்</string>\n    <string name=\"hidden_for_share\">பகிர்வுக்காக மறைக்கப்பட்ட கருவிகள்</string>\n    <string name=\"color_library\">வண்ண நூலகம்</string>\n    <string name=\"color_library_sub\">வண்ணங்களின் பரந்த தொகுப்பை உலாவவும்</string>\n    <string name=\"model_fatality_deblur\">இயற்கையான விவரங்களைப் பராமரிக்கும் போது படங்களிலிருந்து கூர்மையாக்குகிறது மற்றும் மங்கலை நீக்குகிறது, கவனம் செலுத்தாத புகைப்படங்களைச் சரிசெய்ய சிறந்தது.</string>\n    <string name=\"model_unresize_v3\">முன்னர் மறுஅளவிடப்பட்ட படங்களை புத்திசாலித்தனமாக மீட்டெடுக்கிறது, இழந்த விவரங்கள் மற்றும் அமைப்புகளை மீட்டெடுக்கிறது.</string>\n    <string name=\"model_liveaction_v1_span\">நேரடி-நடவடிக்கை உள்ளடக்கத்திற்கு உகந்ததாக, சுருக்க கலைப்பொருட்களைக் குறைக்கிறது மற்றும் திரைப்படம்/டிவி ஷோ பிரேம்களில் சிறந்த விவரங்களை மேம்படுத்துகிறது.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS-தரமான காட்சிகளை HD க்கு மாற்றுகிறது, டேப் இரைச்சலை நீக்குகிறது மற்றும் விண்டேஜ் உணர்வைப் பாதுகாக்கும் போது தெளிவுத்திறனை மேம்படுத்துகிறது.</string>\n    <string name=\"model_text2hd_v1\">உரை-கனமான படங்கள் மற்றும் ஸ்கிரீன்ஷாட்களுக்கு நிபுணத்துவம் வாய்ந்தது, எழுத்துக்களைக் கூர்மைப்படுத்துகிறது மற்றும் வாசிப்புத்திறனை மேம்படுத்துகிறது.</string>\n    <string name=\"model_frankendata_pretrainer\">பலதரப்பட்ட தரவுத்தொகுப்புகளில் பயிற்சியளிக்கப்பட்ட மேம்பட்ட மேம்பாடு, பொது நோக்கத்திற்கான புகைப்பட மேம்பாட்டிற்கு சிறந்தது.</string>\n    <string name=\"model_realwebphoto_v2\">இணைய சுருக்கப்பட்ட புகைப்படங்களுக்கு உகந்ததாக உள்ளது, JPEG கலைப்பொருட்களை நீக்குகிறது மற்றும் இயற்கையான தோற்றத்தை மீட்டெடுக்கிறது.</string>\n    <string name=\"model_realwebphoto_v4\">சிறந்த அமைப்புப் பாதுகாப்பு மற்றும் கலைப்பொருள் குறைப்பு ஆகியவற்றுடன் இணையப் புகைப்படங்களுக்கான மேம்படுத்தப்பட்ட பதிப்பு.</string>\n    <string name=\"model_dat_2x\">டூயல் அக்ரிகேஷன் டிரான்ஸ்ஃபார்மர் தொழில்நுட்பத்துடன் 2x அப்ஸ்கேலிங், கூர்மை மற்றும் இயற்கை விவரங்களை பராமரிக்கிறது.</string>\n    <string name=\"model_dat_3x\">மேம்பட்ட மின்மாற்றி கட்டமைப்பைப் பயன்படுத்தி 3x உயர்த்துதல், மிதமான விரிவாக்கத் தேவைகளுக்கு ஏற்றது.</string>\n    <string name=\"model_dat_4x\">அதிநவீன மின்மாற்றி நெட்வொர்க்குடன் 4x உயர்தர மேம்பாடு, பெரிய அளவுகளில் சிறந்த விவரங்களைப் பாதுகாக்கிறது.</string>\n    <string name=\"model_nafnet_deblurring\">படங்களிலிருந்து மங்கல்/சத்தம் மற்றும் குலுக்கல்களை நீக்குகிறது. பொதுவான நோக்கம் ஆனால் புகைப்படங்களில் சிறந்தது.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Swin2SR மின்மாற்றியைப் பயன்படுத்தி குறைந்த தரமான படங்களை மீட்டமைக்கிறது, BSRGAN சிதைவுக்கு உகந்தது. கனமான சுருக்க கலைப்பொருட்களை சரிசெய்வதற்கும், விவரங்களை 4x அளவில் மேம்படுத்துவதற்கும் சிறந்தது.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN சிதைவு குறித்து பயிற்சியளிக்கப்பட்ட SwinIR மின்மாற்றியுடன் 4x உயர்நிலை. புகைப்படங்கள் மற்றும் சிக்கலான காட்சிகளில் கூர்மையான அமைப்பு மற்றும் இயற்கையான விவரங்களுக்கு GAN ஐப் பயன்படுத்துகிறது.</string>\n    <string name=\"path\">பாதை</string>\n    <string name=\"merge_pdf\">PDF ஐ இணைக்கவும்</string>\n    <string name=\"merge_pdf_sub\">பல PDF கோப்புகளை ஒரு ஆவணத்தில் இணைக்கவும்</string>\n    <string name=\"files_order\">கோப்புகள் ஆர்டர்</string>\n    <string name=\"pages_short\">பக்.</string>\n    <string name=\"split_pdf\">PDF ஐப் பிரிக்கவும்</string>\n    <string name=\"split_pdf_sub\">PDF ஆவணத்திலிருந்து குறிப்பிட்ட பக்கங்களைப் பிரித்தெடுக்கவும்</string>\n    <string name=\"rotate_pdf\">PDF ஐ சுழற்று</string>\n    <string name=\"rotate_pdf_sub\">பக்க நோக்குநிலையை நிரந்தரமாக சரிசெய்யவும்</string>\n    <string name=\"pages\">பக்கங்கள்</string>\n    <string name=\"rearrange_pdf\">PDF ஐ மறுசீரமைக்கவும்</string>\n    <string name=\"rearrange_pdf_sub\">மறுவரிசைப்படுத்த பக்கங்களை இழுத்து விடவும்</string>\n    <string name=\"hold_drag_drop\">பக்கங்களைப் பிடித்து இழுக்கவும்</string>\n    <string name=\"page_numbers\">பக்க எண்கள்</string>\n    <string name=\"page_numbers_sub\">உங்கள் ஆவணங்களில் தானாக எண்ணைச் சேர்க்கவும்</string>\n    <string name=\"label_format\">லேபிள் வடிவம்</string>\n    <string name=\"pdf_to_text\">PDF to Text (OCR)</string>\n    <string name=\"pdf_to_text_sub\">உங்கள் PDF ஆவணங்களிலிருந்து எளிய உரையைப் பிரித்தெடுக்கவும்</string>\n    <string name=\"watermark_pdf_sub\">பிராண்டிங் அல்லது பாதுகாப்பிற்கான தனிப்பயன் உரை மேலடுக்கு</string>\n    <string name=\"signature\">கையெழுத்து</string>\n    <string name=\"signature_sub\">எந்த ஆவணத்திலும் உங்கள் மின்னணு கையொப்பத்தைச் சேர்க்கவும்</string>\n    <string name=\"will_be_for_signature\">இது கையொப்பமாக பயன்படுத்தப்படும்</string>\n    <string name=\"unlock_pdf\">PDF ஐ திறக்கவும்</string>\n    <string name=\"unlock_pdf_sub\">உங்கள் பாதுகாக்கப்பட்ட கோப்புகளிலிருந்து கடவுச்சொற்களை அகற்றவும்</string>\n    <string name=\"protect_pdf\">PDF ஐப் பாதுகாக்கவும்</string>\n    <string name=\"protect_pdf_sub\">வலுவான குறியாக்கத்துடன் உங்கள் ஆவணங்களைப் பாதுகாக்கவும்</string>\n    <string name=\"success\">வெற்றி</string>\n    <string name=\"pdf_unlocked\">PDF திறக்கப்பட்டது, நீங்கள் அதை சேமிக்கலாம் அல்லது பகிரலாம்</string>\n    <string name=\"repair_pdf\">PDF பழுது</string>\n    <string name=\"repair_pdf_sub\">சிதைந்த அல்லது படிக்க முடியாத ஆவணங்களைச் சரிசெய்யும் முயற்சி</string>\n    <string name=\"grayscale\">கிரேஸ்கேல்</string>\n    <string name=\"grayscale_pdf_sub\">அனைத்து ஆவண உட்பொதிக்கப்பட்ட படங்களையும் கிரேஸ்கேலுக்கு மாற்றவும்</string>\n    <string name=\"compress_pdf\">PDF ஐ சுருக்கவும்</string>\n    <string name=\"compress_pdf_sub\">எளிதாகப் பகிர உங்கள் ஆவணக் கோப்பின் அளவை மேம்படுத்தவும்</string>\n    <string name=\"repair_info\">ImageToolbox உள் குறுக்கு-குறிப்பு அட்டவணையை மீண்டும் உருவாக்குகிறது மற்றும் புதிதாக கோப்பு கட்டமைப்பை மீண்டும் உருவாக்குகிறது. இது \\\\\"திறக்க முடியாத\\\\\" பல கோப்புகளுக்கான அணுகலை மீட்டெடுக்கும்.</string>\n    <string name=\"grayscale_info\">இந்தக் கருவி அனைத்து ஆவணப் படங்களையும் கிரேஸ்கேலுக்கு மாற்றுகிறது. கோப்பு அளவை அச்சிடுவதற்கும் குறைப்பதற்கும் சிறந்தது</string>\n    <string name=\"metadata\">மெட்டாடேட்டா</string>\n    <string name=\"metadata_pdf_sub\">சிறந்த தனியுரிமைக்காக ஆவண பண்புகளைத் திருத்தவும்</string>\n    <string name=\"tags\">குறிச்சொற்கள்</string>\n    <string name=\"producer\">தயாரிப்பாளர்</string>\n    <string name=\"author\">ஆசிரியர்</string>\n    <string name=\"keywords\">முக்கிய வார்த்தைகள்</string>\n    <string name=\"creator\">படைப்பாளி</string>\n    <string name=\"privacy_deep_clean\">தனியுரிமை ஆழமான சுத்தம்</string>\n    <string name=\"privacy_deep_clean_sub\">இந்த ஆவணத்திற்கு கிடைக்கக்கூடிய அனைத்து மெட்டாடேட்டாவையும் அழிக்கவும்</string>\n    <string name=\"page\">பக்கம்</string>\n    <string name=\"deep_ocr\">ஆழமான OCR</string>\n    <string name=\"deep_ocr_sub\">ஆவணத்திலிருந்து உரையைப் பிரித்தெடுத்து டெஸராக்ட் என்ஜினைப் பயன்படுத்தி ஒரு உரை கோப்பில் சேமிக்கவும்</string>\n    <string name=\"cant_remove_all\">எல்லா பக்கங்களையும் அகற்ற முடியாது</string>\n    <string name=\"remove_pages_pdf\">PDF பக்கங்களை அகற்று</string>\n    <string name=\"remove_pages_pdf_sub\">PDF ஆவணத்திலிருந்து குறிப்பிட்ட பக்கங்களை அகற்றவும்</string>\n    <string name=\"tap_to_remove\">அகற்ற தட்டவும்</string>\n    <string name=\"manually\">கைமுறையாக</string>\n    <string name=\"crop_pdf\">செதுக்கு PDF</string>\n    <string name=\"crop_pdf_sub\">ஆவணப் பக்கங்களை எந்த எல்லைக்கும் செதுக்குங்கள்</string>\n    <string name=\"flatten_pdf\">PDF ஐத் தட்டவும்</string>\n    <string name=\"flatten_pdf_sub\">ஆவணப் பக்கங்களை மதிப்பாய்வு செய்வதன் மூலம் PDF ஐ மாற்ற முடியாததாக மாற்றவும்</string>\n    <string name=\"camera_failed_to_open\">கேமராவைத் தொடங்க முடியவில்லை. அனுமதிகளைச் சரிபார்த்து, அது வேறொரு ஆப்ஸால் பயன்படுத்தப்படவில்லை என்பதை உறுதிப்படுத்தவும்.</string>\n    <string name=\"extract_images\">படங்களை பிரித்தெடுக்கவும்</string>\n    <string name=\"extract_images_sub\">PDFகளில் உட்பொதிக்கப்பட்ட படங்களை அவற்றின் அசல் தெளிவுத்திறனில் பிரித்தெடுக்கவும்</string>\n    <string name=\"pdf_no_embedded\">இந்த PDF கோப்பில் உட்பொதிக்கப்பட்ட படங்கள் எதுவும் இல்லை</string>\n    <string name=\"extract_images_info\">இந்தக் கருவி ஒவ்வொரு பக்கத்தையும் ஸ்கேன் செய்து முழுத் தரமான மூலப் படங்களை மீட்டெடுக்கிறது - ஆவணங்களிலிருந்து அசலைச் சேமிப்பதற்கு ஏற்றது</string>\n    <string name=\"draw_signature\">கையொப்பத்தை வரையவும்</string>\n    <string name=\"pen_params\">பேனா பரம்ஸ்</string>\n    <string name=\"draw_signature_sub\">ஆவணங்களில் வைக்கப்படுவதற்கு சொந்த கையொப்பத்தை படமாக பயன்படுத்தவும்</string>\n    <string name=\"zip_pdf\">ஜிப் PDF</string>\n    <string name=\"zip_pdf_sub\">கொடுக்கப்பட்ட இடைவெளியுடன் ஆவணத்தைப் பிரித்து புதிய ஆவணங்களை ஜிப் காப்பகத்தில் பேக் செய்யவும்</string>\n    <string name=\"interval\">இடைவெளி</string>\n    <string name=\"print_pdf\">PDF ஐ அச்சிடவும்</string>\n    <string name=\"print_pdf_sub\">தனிப்பயன் பக்க அளவுடன் அச்சிடுவதற்கு ஆவணத்தைத் தயாரிக்கவும்</string>\n    <string name=\"pages_per_sheet\">ஒவ்வொரு தாளுக்கும் பக்கங்கள்</string>\n    <string name=\"orientation\">நோக்குநிலை</string>\n    <string name=\"page_size\">பக்க அளவு</string>\n    <string name=\"margin\">விளிம்பு</string>\n    <string name=\"bloom\">ப்ளூம்</string>\n    <string name=\"soft_knee\">மென்மையான முழங்கால்</string>\n    <string name=\"model_realesr_animevideo_v3x4\">அனிம் மற்றும் கார்ட்டூன்களுக்கு உகந்ததாக உள்ளது. மேம்படுத்தப்பட்ட இயற்கை வண்ணங்கள் மற்றும் குறைவான கலைப்பொருட்கள் மூலம் விரைவான மேம்பாடு</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 போன்ற பாணி</string>\n    <string name=\"calculate_hint\">விரும்பிய மதிப்பைக் கணக்கிட அடிப்படை கணிதக் குறியீடுகளை இங்கே உள்ளிடவும் (எ.கா. (5+5)*10)</string>\n    <string name=\"math_expression\">கணித வெளிப்பாடு</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s படங்கள் வரை எடுக்கவும்</string>\n    <string name=\"background_color_for_alpha_formats\">ஆல்பா வடிவங்களுக்கான பின்னணி நிறம்</string>\n    <string name=\"background_color_for_alpha_formats_sub\">ஆல்பா ஆதரவுடன் ஒவ்வொரு பட வடிவமைப்பிற்கும் பின்னணி வண்ணத்தை அமைக்கும் திறனைச் சேர்க்கிறது, இது முடக்கப்பட்டால் ஆல்பா அல்லாதவர்களுக்கு மட்டுமே கிடைக்கும்</string>\n    <string name=\"keep_date_time\">தேதி நேரத்தை வைத்திருங்கள்</string>\n    <string name=\"keep_date_time_sub\">எப்பொழுதும் தேதி மற்றும் நேரம் தொடர்பான exif குறிச்சொற்களை பாதுகாக்கவும், எக்ஸிஃப் விருப்பத்தை வைத்து சுயாதீனமாக செயல்படும்</string>\n    <string name=\"open_markup_project\">திட்டத்தைத் திறக்கவும்</string>\n    <string name=\"open_markup_project_sub\">முன்பு சேமித்த படக் கருவிப்பெட்டி திட்டப்பணியைத் தொடர்ந்து திருத்தவும்</string>\n    <string name=\"markup_project_open_failed\">பட கருவிப்பெட்டி திட்டத்தை திறக்க முடியவில்லை</string>\n    <string name=\"markup_project_missing_data\">படக் கருவிப்பெட்டி திட்டத்தில் திட்டத் தரவு இல்லை</string>\n    <string name=\"markup_project_corrupted\">பட கருவிப்பெட்டி திட்டம் சிதைந்துள்ளது</string>\n    <string name=\"unsupported_markup_project_version\">ஆதரிக்கப்படாத பட கருவிப்பெட்டி திட்டப் பதிப்பு: %1$d</string>\n    <string name=\"save_markup_project\">திட்டத்தை சேமிக்கவும்</string>\n    <string name=\"save_markup_project_sub\">திருத்தக்கூடிய திட்டக் கோப்பில் அடுக்குகள், பின்னணி மற்றும் திருத்த வரலாற்றை சேமிக்கவும்</string>\n    <string name=\"failed_to_open\">திறக்க முடியவில்லை</string>\n    <string name=\"ocr_write_to_searchable_pdf\">தேடக்கூடிய PDFக்கு எழுதவும்</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">படத் தொகுப்பிலிருந்து உரையை அங்கீகரித்து, படம் மற்றும் தேர்ந்தெடுக்கக்கூடிய உரை அடுக்குடன் தேடக்கூடிய PDF ஐச் சேமிக்கவும்</string>\n    <string name=\"layer_alpha\">அடுக்கு ஆல்பா</string>\n    <string name=\"horizontal_flip\">கிடைமட்ட திருப்பு</string>\n    <string name=\"vertical_flip\">செங்குத்து ஃபிளிப்</string>\n    <string name=\"lock\">பூட்டு</string>\n    <string name=\"add_shadow\">நிழலைச் சேர்க்கவும்</string>\n    <string name=\"shadow_color\">நிழல் நிறம்</string>\n    <string name=\"text_geometry\">உரை வடிவியல்</string>\n    <string name=\"text_geometry_sub\">கூர்மையான ஸ்டைலைசேஷன் செய்ய உரையை நீட்டவும் அல்லது வளைக்கவும்</string>\n    <string name=\"scale_x\">அளவு X</string>\n    <string name=\"skew_x\">ஸ்க்யூ எக்ஸ்</string>\n    <string name=\"remove_annotations\">சிறுகுறிப்புகளை அகற்று</string>\n    <string name=\"remove_annotations_sub\">PDF பக்கங்களிலிருந்து இணைப்புகள், கருத்துகள், சிறப்பம்சங்கள், வடிவங்கள் அல்லது படிவப் புலங்கள் போன்ற தேர்ந்தெடுக்கப்பட்ட சிறுகுறிப்பு வகைகளை அகற்றவும்</string>\n    <string name=\"annotation_link\">ஹைப்பர்லிங்க்கள்</string>\n    <string name=\"annotation_file_attachment\">கோப்பு இணைப்புகள்</string>\n    <string name=\"annotation_line\">கோடுகள்</string>\n    <string name=\"annotation_popup\">பாப்அப்கள்</string>\n    <string name=\"annotation_stamp\">முத்திரைகள்</string>\n    <string name=\"annotation_shapes\">வடிவங்கள்</string>\n    <string name=\"annotation_text\">உரை குறிப்புகள்</string>\n    <string name=\"annotation_text_markup\">உரை மார்க்அப்</string>\n    <string name=\"annotation_widget\">படிவ புலங்கள்</string>\n    <string name=\"annotation_markup\">மார்க்அப்</string>\n    <string name=\"annotation_unknown\">தெரியவில்லை</string>\n    <string name=\"annotations\">சிறுகுறிப்புகள்</string>\n    <string name=\"ungroup\">குழுவிலக்கு</string>\n    <string name=\"add_shadow_sub\">கட்டமைக்கக்கூடிய வண்ணம் மற்றும் ஆஃப்செட்களுடன் லேயருக்குப் பின்னால் மங்கலான நிழலைச் சேர்க்கவும்</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-te/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"size\">పరిమాణం %1$s</string>\n    <string name=\"app_closing\">యాప్‌ను మూసివేస్తోంది</string>\n    <string name=\"pick_image_alt\">చిత్రాన్ని ఎంచుకోండి</string>\n    <string name=\"reset_image\">చిత్రాన్ని రీసెట్ చేయండి</string>\n    <string name=\"height\">ఎత్తు %1$s</string>\n    <string name=\"app_closing_sub\">మీరు నిజంగా యాప్‌ను మూసివేయాలనుకుంటున్నారా?</string>\n    <string name=\"pick_image\">ప్రారంభించడానికి చిత్రాన్ని ఎంచుకోండి</string>\n    <string name=\"flexible\">అనువైన</string>\n    <string name=\"width\">వెడల్పు %1$s</string>\n    <string name=\"extension\">పొడిగింపు</string>\n    <string name=\"stay\">ఉండు</string>\n    <string name=\"smth_went_wrong\">ఏదో తప్పు జరిగింది: %1$s</string>\n    <string name=\"quality\">నాణ్యత</string>\n    <string name=\"image_too_large_preview\">ప్రివ్యూ చేయడానికి చిత్రం చాలా పెద్దదిగా ఉంది, అయితే దీన్ని ఎలాగైనా సేవ్ చేయడానికి ప్రయత్నించబడుతుంది</string>\n    <string name=\"resize_type\">రీసైజ్ రకం</string>\n    <string name=\"clear\">చెరిపి వేయి</string>\n    <string name=\"image_not_saved_sub\">మీరు ఇప్పుడు నిష్క్రమిస్తే, నిల్వ చేయని మార్పులు అన్నీ కోల్పోతారు</string>\n    <string name=\"single_edit\">ఏక సవరణ</string>\n    <string name=\"single_edit_sub\">ఇచ్చిన చిత్ర లక్షణాలు మార్చండి</string>\n    <string name=\"pick_color\">రంగు ఎంచుకోండి</string>\n    <string name=\"pick_color_sub\">చిత్రం నుంచి రంగు ఎంచుకోండి, నకలు చేయండి లేదా పంచుకోండి</string>\n    <string name=\"color\">రంగు</string>\n    <string name=\"color_copied\">రంగు నకలు చేయబడింది</string>\n    <string name=\"new_version\">కొత్త సంస్కరణ %1$s</string>\n    <string name=\"loading\">లోడవుతుంది…</string>\n    <string name=\"reset_image_sub\">చిత్ర మార్పులు యథా స్థానాలకు మార్చబడతాయి</string>\n    <string name=\"something_went_wrong\">ఏదో తప్పు జరిగింది</string>\n    <string name=\"restart_app\">అనువర్తనాన్ని పునఃప్రారంభించు</string>\n    <string name=\"by_bytes_resize_sub\">ఇచ్చిన KB పరిమాణం ఆధారంగా చిత్రాన్ని పరిమాణం చేస్తుంది</string>\n    <string name=\"compare_sub\">ఇచ్చిన రెండు చిత్రాలని సరిపోల్చి చూడండి</string>\n    <string name=\"pick_images\">చిత్రాలను ఎంచుకోండి</string>\n    <string name=\"settings\">అమరికలు</string>\n    <string name=\"pick_two_images\">మొదలు పెట్టడానికి రెండు చిత్రాలని ఎంచుకోండి</string>\n    <string name=\"allow_image_monet_sub\">ఇది ఎంచుకుంటే, మీరు సవరించడానికి చిత్రం ఎంచుకుంటే, ఈ చిత్ర రంగు అనువర్తననికి స్వీకరించబడుతుంది</string>\n    <string name=\"amoled_mode_sub\">ఇది ప్రారంభిస్తే ఉపరితల రంగు రాత్రి తీరు లో సంపూర్ణ చీకటికి అమర్చబడుతుంది</string>\n    <string name=\"color_blue\">నీలం</string>\n    <string name=\"clipboard_paste_invalid_color_code\">చెల్లుబాటు అయ్యే aRGB-కోడ్ ని అతికించండి.</string>\n    <string name=\"help_translate\">అనువదించడానికి సహాయపదండి</string>\n    <string name=\"help_translate_sub\">అనువాద తప్పులను సరిచేయండి లేదా అనువర్తనాన్ని మరొక భాషలోకి స్థానికరించండి</string>\n    <string name=\"failed_to_save\">%d చిత్రాలను నిల్వ ఉంచడం లో విఫలం</string>\n    <string name=\"border_thickness\">సరిహద్దు మందం</string>\n    <string name=\"grant_permission_manual\">సరిగ్గా పనిచేయుటకు అనువర్తననికి ఈ అనుమతి అవసరం, దయచేసి మానవీయంగా మంజూరు చేయండి</string>\n    <string name=\"check_updates\">నవీకరణల కోసం వెతకండి</string>\n    <string name=\"emoji\">ఏమోజీ</string>\n    <string name=\"share\">భాగస్వామ్యం</string>\n    <string name=\"add_file_size_sub\">ఇది ప్రారంభిస్తే, ఫైలు పేరుకు వెడల్పు మరియు పొడవు ను జోడిస్తుంది</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">అనువర్తన రంగు పథకాన్ని క్రియాశీలక రీతి లో ఉన్నప్పుడు మార్చడం సాధ్యం కాదు</string>\n    <string name=\"issue_tracker_sub\">బగ్ నివేదికలు మరియు ఫీచర్ అభ్యర్ధనలు ఇక్కడ పంపండి</string>\n    <string name=\"permission_sub\">మీ చిత్రాలను నిల్వ ఉంచడానికి అనువర్తననికి మీ నిల్వ అనుమతి కావాలి, ఇది అవశ్యం. దయచేసి తదుపరి పెట్టె లే అనుమతి మంజూరు చేయండి.</string>\n    <string name=\"close\">మూసివేయి</string>\n    <string name=\"values_reset\">విలువలు సరిగ్గా మార్చబడతాయి</string>\n    <string name=\"reset\">పూర్వ స్థితి</string>\n    <string name=\"copied\">క్లిప్ బోర్డుకు నకలు చేయండి</string>\n    <string name=\"exception\">మినహాయింపు</string>\n    <string name=\"edit_exif\">EXIFను సవరించండి</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">సరే</string>\n    <string name=\"no_exif\">EXIF సమాచారం దొరకలేదు</string>\n    <string name=\"add_tag\">గుర్తు జోడించండి</string>\n    <string name=\"save\">ఉంచు</string>\n    <string name=\"clear_exif\">EXIFను చెరిపి వేయి</string>\n    <string name=\"cancel\">రద్దు</string>\n    <string name=\"clear_exif_sub\">చిత్రం యొక్క EXIF సమాచారం చెరిపివేయబడుతుంది. ఈ చర్య రద్దు చేయబడదు!</string>\n    <string name=\"presets\">ముందే అమార్చబడినవి</string>\n    <string name=\"crop\">కత్తిరించు</string>\n    <string name=\"image_not_saved\">పొదుపు చేస్తోంది</string>\n    <string name=\"check_source_code\">కోడ్ మూలం</string>\n    <string name=\"check_source_code_sub\">సరికొత్త నవీకరణలు పొందండి, సమస్యలపై చర్చించండి, ఇంకా మరెన్నో</string>\n    <string name=\"image\">చిత్రం</string>\n    <string name=\"crop_sub\">చిత్రాన్ని ఏదైనా పరిమితులకు కత్తిరించండి</string>\n    <string name=\"version\">సంస్కరణ</string>\n    <string name=\"keep_exif\">EXIFను ఉంచండి</string>\n    <string name=\"images\">చిత్రాలు: %d</string>\n    <string name=\"change_preview\">పరిదృశ్యాన్ని మార్చు</string>\n    <string name=\"remove\">తొలగించు</string>\n    <string name=\"palette_sub\">ఇచ్చిన చిత్రం నుండి రంగుల ఫలకం రూపొందించండి</string>\n    <string name=\"generate_palette\">రంగుల ఫలకం</string>\n    <string name=\"palette\">ఫలకం</string>\n    <string name=\"update\">నవీకరించు</string>\n    <string name=\"unsupported_type\">మద్దతు లేని రకం: %1$s</string>\n    <string name=\"no_palette\">ఇచ్చిన చిత్రం నుంచి రంగుల ఫలకం రూపొందించడం సాధ్యం కాలేదు</string>\n    <string name=\"original\">అసలైనది</string>\n    <string name=\"folder\">అవుట్‌పుట్ ఫోల్డర్</string>\n    <string name=\"custom\">వ్యక్తిగతికరించబడినది</string>\n    <string name=\"unspecified\">అనిర్దిష్టమైనది</string>\n    <string name=\"device_storage\">పరికర నిల్వ</string>\n    <string name=\"by_bytes_resize\">బరువు ఆధారంగా పరిమాణం చేయండి</string>\n    <string name=\"max_bytes\">KB లో గరిష్ట పరిమాణం</string>\n    <string name=\"compare\">సరిపోల్చు</string>\n    <string name=\"night_mode\">చీకటి తీరు</string>\n    <string name=\"dark\">చీకటి</string>\n    <string name=\"light\">వెలుతురు</string>\n    <string name=\"system\">వ్యవస్థ</string>\n    <string name=\"dynamic_colors\">క్రియాశీల రంగులు</string>\n    <string name=\"customization\">వ్యక్తిగతికరించుట</string>\n    <string name=\"allow_image_monet\">చిత్రం మోనెట్‌ను అనుమతించండి</string>\n    <string name=\"language\">భాష</string>\n    <string name=\"amoled_mode\">Amoled విధానం</string>\n    <string name=\"color_scheme\">రంగు పథకం</string>\n    <string name=\"color_red\">ఎరుపు</string>\n    <string name=\"color_green\">పచ్చ</string>\n    <string name=\"clipboard_paste_invalid_empty\">అతికించడానికి ఏమి లేదు</string>\n    <string name=\"pick_accent_color\">అనువర్తన నేపథ్యం ఎంచుకున్న రంగు పైన ఆధారపడి ఉంటుంది</string>\n    <string name=\"about_app\">అనువర్తనం గురించి</string>\n    <string name=\"no_updates\">నవీకరణలు ఏమి దొరకలేదు</string>\n    <string name=\"issue_tracker\">సమస్యల జాడ</string>\n    <string name=\"nothing_found_by_search\">మీ ప్రశ్న ద్వారా ఏమీ కనుగొనబడలేదు</string>\n    <string name=\"search_here\">ఇక్కడ వెతకండి</string>\n    <string name=\"dynamic_colors_sub\">ఇది ప్రారంభిస్తే, అనువర్తన రంగులు వాల్ పేపర్ రంగులను స్వీకరిస్తాయి</string>\n    <string name=\"primary\">ప్రాధమిక</string>\n    <string name=\"tertiary\">తృతీయ</string>\n    <string name=\"secondary\">ద్వితీయ</string>\n    <string name=\"surface\">ఉపరితలం</string>\n    <string name=\"values\">విలువలు</string>\n    <string name=\"add\">జోడించు</string>\n    <string name=\"permission\">అనుమతి</string>\n    <string name=\"grant\">మంజూరు</string>\n    <string name=\"external_storage\">బాహ్య నిల్వ</string>\n    <string name=\"monet_colors\">మొనెట్ రంగులు</string>\n    <string name=\"donation_sub\">ఈ అనువర్తనం సంపూర్ణంగా ఉచితం, కానీ మీరు మద్దతు తెలపాలి అనుకుంటే, ఇక్కడ నొక్కండి</string>\n    <string name=\"fab_alignment\">FAB అమరిక</string>\n    <string name=\"check_updates_sub\">ఇది ప్రారంభిస్తే, అనువర్తనం తెరిచినప్పుడు నవీకరణ పేటిక చూపబడుతుంది</string>\n    <string name=\"zoom\">చిత్రాన్ని దగ్గర చేయి</string>\n    <string name=\"prefix\">ఉపసర్గ</string>\n    <string name=\"filename\">ఫైలు పేరు</string>\n    <string name=\"emoji_sub\">ప్రధాన తెర పై ఏ ఏమోజీ చూపలో ఎంచుకోండి</string>\n    <string name=\"add_file_size\">ఫైలు పరిమాణాన్ని జోడించండి</string>\n    <string name=\"delete_exif\">EXIF ను తొలగించు</string>\n    <string name=\"enhanced_pixelation\">మెరుగైన పిక్సెలేషన్</string>\n    <string name=\"stroke_pixelation\">స్ట్రోక్ పిక్సెలేషన్</string>\n    <string name=\"enhanced_diamond_pixelation\">మెరుగైన డైమండ్ పిక్సెలేషన్</string>\n    <string name=\"diamond_pixelation\">డైమండ్ పిక్సెలేషన్</string>\n    <string name=\"enhanced_glitch\">మెరుగైన గ్లిచ్</string>\n    <string name=\"segmentation_mode_osd_only\">ఓరియంటేషన్ &amp; స్క్రిప్ట్ డిటెక్షన్ మాత్రమే</string>\n    <string name=\"segmentation_mode_single_word\">ఒకే పదం</string>\n    <string name=\"segmentation_mode_circle_word\">సర్కిల్ పదం</string>\n    <string name=\"glitch\">గ్లిచ్</string>\n    <string name=\"amount\">మొత్తం</string>\n    <string name=\"seed\">విత్తనం</string>\n    <string name=\"delete_mask\">మాస్క్‌ని తొలగించండి</string>\n    <string name=\"no_such_directory\">\\\"%1$s\\\" డైరెక్టరీ కనుగొనబడలేదు, మేము దానిని డిఫాల్ట్‌గా మార్చాము, దయచేసి ఫైల్‌ని మళ్లీ సేవ్ చేయండి</string>\n    <string name=\"clipboard\">క్లిప్‌బోర్డ్</string>\n    <string name=\"auto_pin\">ఆటో పిన్</string>\n    <string name=\"empty\">ఖాళీ</string>\n    <string name=\"suffix\">ప్రత్యయం</string>\n    <string name=\"search_option\">వెతకండి</string>\n    <string name=\"search_option_sub\">ప్రధాన స్క్రీన్‌లో అందుబాటులో ఉన్న అన్ని ఎంపికల ద్వారా శోధించే సామర్థ్యాన్ని ప్రారంభిస్తుంది</string>\n    <string name=\"free\">ఉచిత</string>\n    <string name=\"image_preview\">చిత్రం ప్రివ్యూ</string>\n    <string name=\"image_preview_sub\">ఏ రకమైన చిత్రాలనైనా ప్రివ్యూ చేయండి: GIF, SVG మరియు మొదలైనవి</string>\n    <string name=\"image_source\">చిత్ర మూలం</string>\n    <string name=\"photo_picker_sub\">స్క్రీన్ దిగువన కనిపించే Android ఆధునిక ఫోటో పికర్, Android 12+లో మాత్రమే పని చేస్తుంది. EXIF మెటాడేటాను స్వీకరించడంలో సమస్యలు ఉన్నాయి</string>\n    <string name=\"gallery_picker_sub\">సాధారణ గ్యాలరీ ఇమేజ్ పికర్. మీ వద్ద మీడియా పికింగ్‌ను అందించే యాప్ ఉంటేనే ఇది పని చేస్తుంది</string>\n    <string name=\"edit\">సవరించు</string>\n    <string name=\"order\">ఆర్డర్ చేయండి</string>\n    <string name=\"order_sub\">ప్రధాన స్క్రీన్‌పై ఎంపికల క్రమాన్ని నిర్ణయిస్తుంది</string>\n    <string name=\"emojis_count\">ఎమోజీల లెక్క</string>\n    <string name=\"sequence_num\">క్రమం సంఖ్య</string>\n    <string name=\"original_filename\">అసలు ఫైల్ పేరు</string>\n    <string name=\"add_original_filename\">అసలు ఫైల్ పేరును జోడించండి</string>\n    <string name=\"replace_sequence_number\">క్రమం సంఖ్యను భర్తీ చేయండి</string>\n    <string name=\"add_original_filename_sub\">ప్రారంభించబడితే, అవుట్‌పుట్ చిత్రం పేరులో అసలు ఫైల్ పేరును జోడిస్తుంది</string>\n    <string name=\"replace_sequence_number_sub\">ప్రారంభించబడితే, మీరు బ్యాచ్ ప్రాసెసింగ్‌ని ఉపయోగిస్తే, స్టాండర్డ్ టైమ్‌స్టాంప్‌ని ఇమేజ్ సీక్వెన్స్ నంబర్‌కి భర్తీ చేస్తుంది</string>\n    <string name=\"filename_not_work_with_photopicker\">ఫోటో పికర్ ఇమేజ్ సోర్స్ ఎంచుకుంటే అసలు ఫైల్ పేరుని జోడించడం పని చేయదు</string>\n    <string name=\"load_image_from_net\">నెట్ నుండి చిత్రాన్ని లోడ్ చేయండి</string>\n    <string name=\"load_image_from_net_sub\">మీకు కావాలంటే ప్రివ్యూ చేయడానికి, జూమ్ చేయడానికి, సవరించడానికి మరియు సేవ్ చేయడానికి ఇంటర్నెట్ నుండి ఏదైనా చిత్రాన్ని లోడ్ చేయండి.</string>\n    <string name=\"no_image\">చిత్రం లేదు</string>\n    <string name=\"image_link\">చిత్రం లింక్</string>\n    <string name=\"fill\">పూరించండి</string>\n    <string name=\"fit\">ఫిట్</string>\n    <string name=\"content_scale\">కంటెంట్ స్కేల్</string>\n    <string name=\"explicit_description\">వెడల్పు మరియు ఎత్తు పరామితి ద్వారా అందించబడిన ఇమేజ్‌కి ప్రతి చిత్రాన్ని బలవంతం చేస్తుంది - కారక నిష్పత్తిని మార్చవచ్చు</string>\n    <string name=\"flexible_description\">వెడల్పు లేదా ఎత్తు పరామితి ద్వారా అందించబడిన పొడవాటి వైపు ఉన్న చిత్రాలకు చిత్రాల పరిమాణాన్ని మారుస్తుంది, సేవ్ చేసిన తర్వాత అన్ని పరిమాణ గణనలు చేయబడతాయి - కారక నిష్పత్తిని ఉంచుతుంది</string>\n    <string name=\"brightness\">ప్రకాశం</string>\n    <string name=\"contrast\">విరుద్ధంగా</string>\n    <string name=\"hue\">రంగు</string>\n    <string name=\"saturation\">సంతృప్తత</string>\n    <string name=\"add_filter\">ఫిల్టర్‌ని జోడించండి</string>\n    <string name=\"filter\">ఫిల్టర్ చేయండి</string>\n    <string name=\"filter_sub\">ఇచ్చిన చిత్రాలకు ఏదైనా ఫిల్టర్ చైన్‌ని వర్తింపజేయండి</string>\n    <string name=\"filters\">ఫిల్టర్లు</string>\n    <string name=\"light_aka_illumination\">కాంతి</string>\n    <string name=\"color_filter\">రంగు ఫిల్టర్</string>\n    <string name=\"alpha\">ఆల్ఫా</string>\n    <string name=\"exposure\">బహిరంగపరచడం</string>\n    <string name=\"white_balance\">తెలుపు సంతులనం</string>\n    <string name=\"temperature\">ఉష్ణోగ్రత</string>\n    <string name=\"tint\">లేతరంగు</string>\n    <string name=\"monochrome\">మోనోక్రోమ్</string>\n    <string name=\"gamma\">గామా</string>\n    <string name=\"highlights_shadows\">ముఖ్యాంశాలు మరియు నీడలు</string>\n    <string name=\"highlights\">ముఖ్యాంశాలు</string>\n    <string name=\"haze\">పొగమంచు</string>\n    <string name=\"effect\">ప్రభావం</string>\n    <string name=\"distance\">దూరం</string>\n    <string name=\"slope\">వాలు</string>\n    <string name=\"sharpen\">పదును పెట్టండి</string>\n    <string name=\"sepia\">సెపియా</string>\n    <string name=\"negative\">ప్రతికూలమైనది</string>\n    <string name=\"solarize\">సోలారైజ్ చేయండి</string>\n    <string name=\"vibrance\">కంపనం</string>\n    <string name=\"black_and_white\">నలుపు మరియు తెలుపు</string>\n    <string name=\"crosshatch\">క్రాస్‌షాచ్</string>\n    <string name=\"spacing\">అంతరం</string>\n    <string name=\"line_width\">లైన్ వెడల్పు</string>\n    <string name=\"sobel_edge\">సోబెల్ అంచు</string>\n    <string name=\"blur\">బ్లర్</string>\n    <string name=\"halftone\">హాఫ్టోన్</string>\n    <string name=\"cga_colorspace\">CGA కలర్స్పేస్</string>\n    <string name=\"gaussian_blur\">గాస్సియన్ బ్లర్</string>\n    <string name=\"box_blur\">బాక్స్ బ్లర్</string>\n    <string name=\"bilaterial_blur\">ద్వైపాక్షిక బ్లర్</string>\n    <string name=\"emboss\">ఎంబాస్</string>\n    <string name=\"laplacian\">లాప్లాసియన్</string>\n    <string name=\"radius\">వ్యాసార్థం</string>\n    <string name=\"vignette\">విగ్నేట్</string>\n    <string name=\"start\">ప్రారంభించండి</string>\n    <string name=\"end\">ముగింపు</string>\n    <string name=\"scale\">స్కేల్</string>\n    <string name=\"kuwahara\">కువహరా స్మూత్టింగ్</string>\n    <string name=\"stack_blur\">స్టాక్ బ్లర్</string>\n    <string name=\"distortion\">వక్రీకరణ</string>\n    <string name=\"angle\">కోణం</string>\n    <string name=\"swirl\">స్విర్ల్</string>\n    <string name=\"bulge\">ఉబ్బెత్తు</string>\n    <string name=\"dilation\">వ్యాకోచం</string>\n    <string name=\"sphere_refraction\">గోళ వక్రీభవనం</string>\n    <string name=\"refractive_index\">వక్రీభవన సూచిక</string>\n    <string name=\"glass_sphere_refraction\">గ్లాస్ స్పియర్ వక్రీభవనం</string>\n    <string name=\"color_matrix\">రంగు మాతృక</string>\n    <string name=\"opacity\">అస్పష్టత</string>\n    <string name=\"limits_resize\">పరిమితుల పరిమాణాన్ని మార్చండి</string>\n    <string name=\"sketch\">స్కెచ్</string>\n    <string name=\"threshold\">థ్రెషోల్డ్</string>\n    <string name=\"quantizationLevels\">పరిమాణీకరణ స్థాయిలు</string>\n    <string name=\"smooth_toon\">స్మూత్ టూన్</string>\n    <string name=\"toon\">టూన్</string>\n    <string name=\"posterize\">పోస్టరైజ్ చేయండి</string>\n    <string name=\"non_maximum_suppression\">నాన్ గరిష్ట అణచివేత</string>\n    <string name=\"weak_pixel_inclusion\">బలహీనమైన పిక్సెల్ చేరిక</string>\n    <string name=\"convolution3x3\">కన్వల్యూషన్ 3x3</string>\n    <string name=\"rgb_filter\">RGB ఫిల్టర్</string>\n    <string name=\"false_color\">తప్పుడు రంగు</string>\n    <string name=\"first_color\">మొదటి రంగు</string>\n    <string name=\"second_color\">రెండవ రంగు</string>\n    <string name=\"reorder\">క్రమాన్ని మార్చండి</string>\n    <string name=\"fast_blur\">వేగవంతమైన బ్లర్</string>\n    <string name=\"blur_size\">బ్లర్ సైజు</string>\n    <string name=\"blur_center_x\">బ్లర్ సెంటర్ x</string>\n    <string name=\"blur_center_y\">బ్లర్ సెంటర్ y</string>\n    <string name=\"zoom_blur\">జూమ్ బ్లర్</string>\n    <string name=\"color_balance\">రంగు సంతులనం</string>\n    <string name=\"luminance_threshold\">ప్రకాశం థ్రెషోల్డ్</string>\n    <string name=\"activate_files\">మీరు ఫైల్‌ల యాప్‌ని నిలిపివేసారు, ఈ ఫీచర్‌ని ఉపయోగించడానికి దాన్ని యాక్టివేట్ చేయండి</string>\n    <string name=\"draw\">గీయండి</string>\n    <string name=\"draw_sub\">స్కెచ్‌బుక్‌లో ఉన్నట్లుగా చిత్రంపై గీయండి లేదా నేపథ్యంపైనే గీయండి</string>\n    <string name=\"paint_color\">పెయింట్ రంగు</string>\n    <string name=\"paint_alpha\">ఆల్ఫాను పెయింట్ చేయండి</string>\n    <string name=\"draw_on_image\">చిత్రంపై గీయండి</string>\n    <string name=\"draw_on_image_sub\">ఒక చిత్రాన్ని ఎంచుకుని దానిపై ఏదైనా గీయండి</string>\n    <string name=\"draw_on_background\">నేపథ్యంలో గీయండి</string>\n    <string name=\"draw_on_background_sub\">నేపథ్య రంగును ఎంచుకుని, దాని పైన గీయండి</string>\n    <string name=\"background_color\">నేపథ్య రంగు</string>\n    <string name=\"cipher\">సాంకేతికలిపి</string>\n    <string name=\"cipher_sub\">AES క్రిప్టో అల్గోరిథం ఆధారంగా ఏదైనా ఫైల్ (చిత్రం మాత్రమే కాదు) ఎన్‌క్రిప్ట్ చేయండి మరియు డీక్రిప్ట్ చేయండి</string>\n    <string name=\"pick_file\">ఫైల్‌ని ఎంచుకోండి</string>\n    <string name=\"encrypt\">ఎన్‌క్రిప్ట్ చేయండి</string>\n    <string name=\"decrypt\">డీక్రిప్ట్ చేయండి</string>\n    <string name=\"pick_file_to_start\">ప్రారంభించడానికి ఫైల్‌ని ఎంచుకోండి</string>\n    <string name=\"decryption\">డిక్రిప్షన్</string>\n    <string name=\"encryption\">ఎన్క్రిప్షన్</string>\n    <string name=\"key\">కీ</string>\n    <string name=\"file_proceed\">ఫైల్ ప్రాసెస్ చేయబడింది</string>\n    <string name=\"store_file_desc\">ఈ ఫైల్‌ను మీ పరికరంలో నిల్వ చేయండి లేదా మీకు కావలసిన చోట ఉంచడానికి భాగస్వామ్య చర్యను ఉపయోగించండి</string>\n    <string name=\"features\">లక్షణాలు</string>\n    <string name=\"implementation\">అమలు</string>\n    <string name=\"compatibility\">అనుకూలత</string>\n    <string name=\"implementation_sub\">AES-256, GCM మోడ్, పాడింగ్ లేదు, 12 బైట్‌లు యాదృచ్ఛిక IVలు. కీలు SHA-3 హాష్‌లుగా ఉపయోగించబడతాయి (256 బిట్‌లు).</string>\n    <string name=\"file_size\">ఫైల్ పరిమాణం</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">ఇతర ఫైల్ ఎన్‌క్రిప్షన్ సాఫ్ట్‌వేర్ లేదా సేవలకు అనుకూలత హామీ ఇవ్వబడదని దయచేసి గమనించండి. కొద్దిగా భిన్నమైన కీ చికిత్స లేదా సాంకేతికలిపి కాన్ఫిగరేషన్ అననుకూలతకు కారణం కావచ్చు.</string>\n    <string name=\"invalid_password_or_not_encrypted\">చెల్లని పాస్‌వర్డ్ లేదా ఎంచుకున్న ఫైల్ ఎన్‌క్రిప్ట్ చేయబడలేదు</string>\n    <string name=\"image_size_warning\">ఇచ్చిన వెడల్పు మరియు ఎత్తుతో చిత్రాన్ని సేవ్ చేయడానికి ప్రయత్నిస్తే OOM లోపం సంభవించవచ్చు. దీన్ని మీ స్వంత పూచీతో చేయండి మరియు నేను మిమ్మల్ని హెచ్చరించలేదని చెప్పకండి!</string>\n    <string name=\"cache\">కాష్</string>\n    <string name=\"cache_size\">కాష్ పరిమాణం</string>\n    <string name=\"found_s\">కనుగొనబడింది %1$s</string>\n    <string name=\"auto_cache_clearing\">ఆటో కాష్ క్లియరింగ్</string>\n    <string name=\"auto_cache_clearing_sub\">ప్రారంభించబడితే యాప్ కాష్ యాప్ స్టార్టప్‌లో క్లియర్ చేయబడుతుంది</string>\n    <string name=\"create\">సృష్టించు</string>\n    <string name=\"tools\">ఉపకరణాలు</string>\n    <string name=\"group_options_by_type\">రకం ద్వారా సమూహ ఎంపికలు</string>\n    <string name=\"group_options_by_type_sub\">కస్టమ్ జాబితా అమరికకు బదులుగా వాటి రకాన్ని బట్టి ప్రధాన స్క్రీన్‌పై సమూహాల ఎంపికలు</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">ఎంపిక సమూహీకరణ ప్రారంభించబడినప్పుడు అమరికను మార్చలేరు</string>\n    <string name=\"edit_screenshot\">స్క్రీన్‌షాట్‌ని సవరించండి</string>\n    <string name=\"secondary_customization\">ద్వితీయ అనుకూలీకరణ</string>\n    <string name=\"screenshot\">స్క్రీన్షాట్</string>\n    <string name=\"fallback_option\">ఫాల్‌బ్యాక్ ఎంపిక</string>\n    <string name=\"skip\">దాటవేయి</string>\n    <string name=\"copy\">కాపీ చేయండి</string>\n    <string name=\"warning_bytes\">%1$s మోడ్‌లో సేవ్ చేయడం అస్థిరంగా ఉంటుంది, ఎందుకంటే ఇది లాస్‌లెస్ ఫార్మాట్</string>\n    <string name=\"presets_sub\" formatted=\"false\">మీరు ప్రీసెట్ 125ని ఎంచుకున్నట్లయితే, చిత్రం 100% నాణ్యతతో అసలు చిత్రం యొక్క 125% పరిమాణంగా సేవ్ చేయబడుతుంది. మీరు ప్రీసెట్ 50ని ఎంచుకుంటే, చిత్రం 50% పరిమాణం మరియు 50% నాణ్యతతో సేవ్ చేయబడుతుంది.</string>\n    <string name=\"randomize_filename\">ఫైల్ పేరును యాదృచ్ఛికంగా మార్చండి</string>\n    <string name=\"randomize_filename_sub\">ప్రారంభించబడితే, అవుట్‌పుట్ ఫైల్ పేరు పూర్తిగా యాదృచ్ఛికంగా ఉంటుంది</string>\n    <string name=\"saved_to\">%2$s పేరుతో %1$s ఫోల్డర్‌కి సేవ్ చేయబడింది</string>\n    <string name=\"saved_to_without_filename\">%1$s ఫోల్డర్‌లో సేవ్ చేయబడింది</string>\n    <string name=\"tg_chat_sub\">యాప్ గురించి చర్చించి, ఇతర వినియోగదారుల నుండి అభిప్రాయాన్ని పొందండి. మీరు ఇక్కడ బీటా అప్‌డేట్‌లు మరియు అంతర్దృష్టులను కూడా పొందవచ్చు.</string>\n    <string name=\"aspect_ratio\">కారక నిష్పత్తి</string>\n    <string name=\"image_crop_mask_sub\">ఇచ్చిన చిత్రం నుండి మాస్క్‌ని రూపొందించడానికి ఈ మాస్క్ రకాన్ని ఉపయోగించండి, దీనికి ఆల్ఫా ఛానెల్ ఉండాలని గమనించండి</string>\n    <string name=\"backup_and_restore\">బ్యాకప్ మరియు పునరుద్ధరించండి</string>\n    <string name=\"backup\">బ్యాకప్</string>\n    <string name=\"restore_sub\">మునుపు రూపొందించిన ఫైల్ నుండి యాప్ సెట్టింగ్‌లను పునరుద్ధరించండి</string>\n    <string name=\"corrupted_file_or_not_a_backup\">పాడైన ఫైల్ లేదా బ్యాకప్ కాదు</string>\n    <string name=\"reset_settings_sub\">ఇది మీ సెట్టింగ్‌లను డిఫాల్ట్ విలువలకు రోల్ బ్యాక్ చేస్తుంది. పైన పేర్కొన్న బ్యాకప్ ఫైల్ లేకుండా ఇది రద్దు చేయబడదని గమనించండి.</string>\n    <string name=\"settings_restored\">సెట్టింగ్‌లు విజయవంతంగా పునరుద్ధరించబడ్డాయి</string>\n    <string name=\"contact_me\">నన్ను సంప్రదించండి</string>\n    <string name=\"delete_color_scheme_warn\">మీరు ఎంచుకున్న రంగు పథకాన్ని తొలగించబోతున్నారు. ఈ ఆపరేషన్ రద్దు చేయబడదు</string>\n    <string name=\"font\">ఫాంట్</string>\n    <string name=\"font_scale\">ఫాంట్ స్కేల్</string>\n    <string name=\"defaultt\">డిఫాల్ట్</string>\n    <string name=\"using_large_fonts_warn\">పెద్ద ఫాంట్ స్కేల్‌లను ఉపయోగించడం వలన UI గ్లిచ్‌లు మరియు సమస్యలు ఏర్పడవచ్చు, అవి పరిష్కరించబడవు. జాగ్రత్తగా వాడండి.</string>\n    <string name=\"alphabet_and_numbers\">అ ఆ ఇ ఈ ఉ ఊ ఋ ఎ ఏ ఐ ఒ ఓ ఔ క ఖ గ ఘ ఙ చ ఛ జ ఝ ఞ ట ఠ డ ఢ ణ త థ ద ధ న ప ఫ బ భ మ య ర ల వ శ ష స హ 0123456789 !?</string>\n    <string name=\"food_and_drink\">ఆహారం మరియు పానీయం</string>\n    <string name=\"nature_and_animals\">ప్రకృతి మరియు జంతువులు</string>\n    <string name=\"objects\">వస్తువులు</string>\n    <string name=\"activities\">కార్యకలాపాలు</string>\n    <string name=\"background_remover\">బ్యాక్‌గ్రౌండ్ రిమూవర్</string>\n    <string name=\"background_remover_sub\">గీయడం ద్వారా చిత్రం నుండి నేపథ్యాన్ని తీసివేయండి లేదా ఆటో ఎంపికను ఉపయోగించండి</string>\n    <string name=\"keep_exif_sub\">ఒరిజినల్ ఇమేజ్ మెటాడేటా ఉంచబడుతుంది</string>\n    <string name=\"trim_image_sub\">చిత్రం చుట్టూ ఉన్న పారదర్శక ఖాళీలు కత్తిరించబడతాయి</string>\n    <string name=\"auto_erase_background\">నేపథ్యాన్ని స్వయంచాలకంగా తొలగించండి</string>\n    <string name=\"restore_image\">చిత్రాన్ని పునరుద్ధరించండి</string>\n    <string name=\"erase_mode\">ఎరేజ్ మోడ్</string>\n    <string name=\"erase_background\">నేపథ్యాన్ని తొలగించండి</string>\n    <string name=\"blur_radius\">బ్లర్ వ్యాసార్థం</string>\n    <string name=\"draw_mode\">డ్రా మోడ్</string>\n    <string name=\"create_issue\">సమస్యను సృష్టించండి</string>\n    <string name=\"something_went_wrong_emphasis\">అయ్యో… ఏదో తప్పు జరిగింది. దిగువ ఎంపికలను ఉపయోగించి మీరు నాకు వ్రాయవచ్చు మరియు నేను పరిష్కారాన్ని కనుగొనడానికి ప్రయత్నిస్తాను</string>\n    <string name=\"resize_and_convert\">పరిమాణాన్ని మార్చండి మరియు మార్చండి</string>\n    <string name=\"resize_and_convert_sub\">ఇచ్చిన చిత్రాల పరిమాణాన్ని మార్చండి లేదా వాటిని ఇతర ఫార్మాట్‌లకు మార్చండి. ఒకే చిత్రాన్ని ఎంచుకుంటే EXIF మెటాడేటా కూడా ఇక్కడ సవరించబడుతుంది.</string>\n    <string name=\"crashlytics_sub\">ఇది క్రాష్ నివేదికలను మాన్యువల్‌గా సేకరించడానికి యాప్‌ని అనుమతిస్తుంది</string>\n    <string name=\"analytics\">విశ్లేషణలు</string>\n    <string name=\"analytics_sub\">అనామక యాప్ వినియోగ గణాంకాలను సేకరించడాన్ని అనుమతించండి</string>\n    <string name=\"image_exif_warning\">ప్రస్తుతం, %1$s ఫార్మాట్ Androidలో EXIF మెటాడేటాను చదవడానికి మాత్రమే అనుమతిస్తుంది. అవుట్‌పుట్ ఇమేజ్ సేవ్ చేయబడినప్పుడు మెటాడేటాను కలిగి ఉండదు.</string>\n    <string name=\"effort\">ప్రయత్నం</string>\n    <string name=\"wait\">వేచి ఉండండి</string>\n    <string name=\"effort_sub\">%1$s విలువ అంటే వేగవంతమైన కుదింపు, దీని ఫలితంగా సాపేక్షంగా పెద్ద ఫైల్ పరిమాణం ఉంటుంది. %2$s అంటే నెమ్మదిగా కుదింపు, ఫలితంగా చిన్న ఫైల్ ఏర్పడుతుంది.</string>\n    <string name=\"saving_almost_complete\">సేవ్ చేయడం దాదాపు పూర్తయింది. ఇప్పుడు రద్దు చేస్తే మళ్లీ ఆదా చేయాల్సి ఉంటుంది.</string>\n    <string name=\"allow_betas_sub\">అప్‌డేట్ చెకింగ్ ప్రారంభించబడితే బీటా యాప్ వెర్షన్‌లను కలిగి ఉంటుంది</string>\n    <string name=\"brush_softness\">బ్రష్ మృదుత్వం</string>\n    <string name=\"crop_description\">చిత్రాలు ఎంటర్ చేసిన పరిమాణానికి మధ్యలో కత్తిరించబడతాయి. చిత్రం ఎంటర్ చేసిన కొలతల కంటే చిన్నగా ఉంటే, ఇచ్చిన నేపథ్య రంగుతో కాన్వాస్ విస్తరించబడుతుంది.</string>\n    <string name=\"image_stitching\">చిత్రం కుట్టడం</string>\n    <string name=\"image_stitching_sub\">ఒక పెద్దదాన్ని పొందడానికి ఇచ్చిన చిత్రాలను కలపండి</string>\n    <string name=\"pick_at_least_two_images\">కనీసం 2 చిత్రాలను ఎంచుకోండి</string>\n    <string name=\"output_image_scale\">అవుట్‌పుట్ ఇమేజ్ స్కేల్</string>\n    <string name=\"scale_small_images_to_large\">చిన్న చిత్రాలను పెద్దదిగా స్కేల్ చేయండి</string>\n    <string name=\"image_orientation\">చిత్రం ఓరియంటేషన్</string>\n    <string name=\"horizontal\">అడ్డంగా</string>\n    <string name=\"vertical\">నిలువుగా</string>\n    <string name=\"scale_small_images_to_large_sub\">ప్రారంభించబడితే, చిన్న చిత్రాలు వరుసగా పెద్దదానికి స్కేల్ చేయబడతాయి</string>\n    <string name=\"images_order\">చిత్రాల క్రమం</string>\n    <string name=\"circle_pixelation\">సర్కిల్ పిక్సెలేషన్</string>\n    <string name=\"replace_color\">రంగును భర్తీ చేయండి</string>\n    <string name=\"tolerance\">ఓరిమి</string>\n    <string name=\"color_to_replace\">భర్తీ చేయడానికి రంగు</string>\n    <string name=\"target_color\">లక్ష్య రంగు</string>\n    <string name=\"color_to_remove\">తీసివేయవలసిన రంగు</string>\n    <string name=\"fruit_salad\">పండ్ల ముక్కలు</string>\n    <string name=\"fidelity\">విశ్వసనీయత</string>\n    <string name=\"content\">విషయము</string>\n    <string name=\"tonal_spot_sub\">డిఫాల్ట్ పాలెట్ శైలి, ఇది నాలుగు రంగులను అనుకూలీకరించడానికి అనుమతిస్తుంది, ఇతరులు కీ రంగును మాత్రమే సెట్ చేయడానికి మిమ్మల్ని అనుమతిస్తారు</string>\n    <string name=\"neutral_sub\">మోనోక్రోమ్ కంటే కొంచెం ఎక్కువ క్రోమాటిక్ శైలి</string>\n    <string name=\"vibrant_sub\">బిగ్గరగా ఉండే థీమ్, ప్రాథమిక పాలెట్‌కు రంగుల రంగు గరిష్టంగా ఉంటుంది, ఇతరులకు పెరిగింది</string>\n    <string name=\"playful_scheme\">ఉల్లాసభరితమైన థీమ్ - మూలం రంగు యొక్క రంగు థీమ్‌లో కనిపించదు</string>\n    <string name=\"monochrome_sub\">మోనోక్రోమ్ థీమ్, రంగులు పూర్తిగా నలుపు / తెలుపు / బూడిద రంగులో ఉంటాయి</string>\n    <string name=\"images_to_pdf\">చిత్రాలు PDFకి</string>\n    <string name=\"content_sub\">Scheme.primaryContainerలో మూల రంగును ఉంచే పథకం</string>\n    <string name=\"fidelity_sub\">కంటెంట్ స్కీమ్‌కు చాలా పోలి ఉండే స్కీమ్</string>\n    <string name=\"pdf_tools_sub\">PDF ఫైల్‌లతో ఆపరేట్ చేయండి: ప్రివ్యూ, చిత్రాల బ్యాచ్‌గా మార్చండి లేదా ఇచ్చిన చిత్రాల నుండి ఒకదాన్ని సృష్టించండి</string>\n    <string name=\"preview_pdf\">ప్రివ్యూ PDF</string>\n    <string name=\"pdf_to_images\">చిత్రాలకు PDF</string>\n    <string name=\"preview_pdf_sub\">సాధారణ PDF ప్రివ్యూ</string>\n    <string name=\"pdf_to_images_sub\">ఇచ్చిన అవుట్‌పుట్ ఫార్మాట్‌లో PDFని ఇమేజ్‌లుగా మార్చండి</string>\n    <string name=\"images_to_pdf_sub\">ఇచ్చిన చిత్రాలను అవుట్‌పుట్ PDF ఫైల్‌లో ప్యాక్ చేయండి</string>\n    <string name=\"delete_mask_warn\">మీరు ఎంచుకున్న ఫిల్టర్ మాస్క్‌ని తొలగించబోతున్నారు. ఈ ఆపరేషన్ రద్దు చేయబడదు</string>\n    <string name=\"simple_variants\">సాధారణ రూపాంతరాలు</string>\n    <string name=\"highlighter\">హైలైటర్</string>\n    <string name=\"neon\">నియాన్</string>\n    <string name=\"pen\">పెన్</string>\n    <string name=\"privacy_blur\">గోప్యత బ్లర్</string>\n    <string name=\"highlighter_sub\">సెమీ పారదర్శక పదును ఉన్న హైలైటర్ మార్గాలను గీయండి</string>\n    <string name=\"neon_sub\">మీ డ్రాయింగ్‌లకు కొంత మెరుస్తున్న ప్రభావాన్ని జోడించండి</string>\n    <string name=\"pen_sub\">డిఫాల్ట్ ఒకటి, సరళమైనది - కేవలం రంగు</string>\n    <string name=\"privacy_blur_sub\">మీరు దాచాలనుకునే దేన్నైనా భద్రపరచడానికి గీసిన మార్గం క్రింద చిత్రాన్ని అస్పష్టం చేస్తుంది</string>\n    <string name=\"pixelation_sub\">గోప్యత బ్లర్ లాగానే ఉంటుంది, కానీ బ్లర్ చేయడానికి బదులుగా పిక్సెల్‌లు</string>\n    <string name=\"app_bars_shadow\">యాప్ బార్‌లు</string>\n    <string name=\"app_bars_shadow_sub\">యాప్ బార్‌ల వెనుక షాడో డ్రాయింగ్‌ను ప్రారంభిస్తుంది</string>\n    <string name=\"value_in_range\">%1$s - %2$s పరిధిలో విలువ</string>\n    <string name=\"auto_rotate_limits\">ఆటో రొటేట్</string>\n    <string name=\"auto_rotate_limits_sub\">ఇమేజ్ ఓరియంటేషన్ కోసం పరిమితి పెట్టెని స్వీకరించడానికి అనుమతిస్తుంది</string>\n    <string name=\"auto_pin_sub\">ప్రారంభించబడితే, స్వయంచాలకంగా సేవ్ చేయబడిన చిత్రాన్ని క్లిప్‌బోర్డ్‌కు జోడిస్తుంది</string>\n    <string name=\"vibration\">కంపనం</string>\n    <string name=\"vibration_strength\">కంపన బలం</string>\n    <string name=\"overwrite_file_requirements\">ఫైల్‌లను ఓవర్‌రైట్ చేయడానికి మీరు \\\"ఎక్స్‌ప్లోరర్\\\" ఇమేజ్ సోర్స్‌ని ఉపయోగించాలి, రిపిక్ ఇమేజ్‌లను ట్రై చేయండి, మేము ఇమేజ్ సోర్స్‌ని అవసరమైన దానికి మార్చాము</string>\n    <string name=\"overwrite_files\">ఫైల్‌లను ఓవర్‌రైట్ చేయండి</string>\n    <string name=\"overwrite_files_sub\">ఎంచుకున్న ఫోల్డర్‌లో సేవ్ చేయడానికి బదులుగా అసలు ఫైల్ కొత్త దానితో భర్తీ చేయబడుతుంది, ఈ ఎంపికకు ఇమేజ్ సోర్స్ \\\"Explorer\\\" లేదా GetContent ఉండాలి, దీన్ని టోగుల్ చేస్తున్నప్పుడు, ఇది స్వయంచాలకంగా సెట్ చేయబడుతుంది</string>\n    <string name=\"catmull\">క్యాట్ముల్</string>\n    <string name=\"bicubic\">బిక్యూబిక్</string>\n    <string name=\"hermite\">సన్యాసి</string>\n    <string name=\"lanczos\">లాంజోస్</string>\n    <string name=\"mitchell\">మిచెల్</string>\n    <string name=\"nearest\">సమీపంలోని</string>\n    <string name=\"spline\">స్ప్లైన్</string>\n    <string name=\"basic\">ప్రాథమిక</string>\n    <string name=\"bilinear_sub\">చిత్రం యొక్క పరిమాణాన్ని మార్చడానికి లీనియర్ (లేదా బైలీనియర్, రెండు కోణాలలో) ఇంటర్‌పోలేషన్ సాధారణంగా మంచిది, కానీ వివరాలు కొంత అవాంఛనీయమైన మృదుత్వం కలిగిస్తుంది మరియు ఇప్పటికీ కొంత బెల్లం ఉంటుంది.</string>\n    <string name=\"bicubic_sub\">మెరుగైన స్కేలింగ్ పద్ధతులలో లాంజోస్ రీసాంప్లింగ్ మరియు మిచెల్-నేట్రావాలి ఫిల్టర్‌లు ఉన్నాయి</string>\n    <string name=\"nearest_sub\">ప్రతి పిక్సెల్‌ని ఒకే రంగులోని అనేక పిక్సెల్‌లతో భర్తీ చేయడం ద్వారా పరిమాణాన్ని పెంచే సులభమైన మార్గాలలో ఒకటి</string>\n    <string name=\"basic_sub\">దాదాపు అన్ని యాప్‌లలో ఉపయోగించే సరళమైన ఆండ్రాయిడ్ స్కేలింగ్ మోడ్</string>\n    <string name=\"catmull_sub\">కంట్రోల్ పాయింట్ల సెట్‌ను సజావుగా ఇంటర్‌పోలేట్ చేయడానికి మరియు రీసాంప్లింగ్ చేయడానికి పద్ధతి, సాధారణంగా కంప్యూటర్ గ్రాఫిక్స్‌లో మృదువైన వక్రతలను సృష్టించడానికి ఉపయోగిస్తారు</string>\n    <string name=\"hann_sub\">వర్ణపట లీకేజీని తగ్గించడానికి మరియు సిగ్నల్ అంచులను తగ్గించడం ద్వారా ఫ్రీక్వెన్సీ విశ్లేషణ యొక్క ఖచ్చితత్వాన్ని మెరుగుపరచడానికి సిగ్నల్ ప్రాసెసింగ్‌లో విండో ఫంక్షన్ తరచుగా వర్తించబడుతుంది.</string>\n    <string name=\"hermite_sub\">గణిత ఇంటర్‌పోలేషన్ టెక్నిక్ ఒక మృదువైన మరియు నిరంతర వక్రతను రూపొందించడానికి ఒక వక్ర భాగపు ముగింపు బిందువుల వద్ద విలువలు మరియు ఉత్పన్నాలను ఉపయోగిస్తుంది</string>\n    <string name=\"lanczos_sub\">పిక్సెల్ విలువలకు వెయిటెడ్ సింక్ ఫంక్షన్‌ని వర్తింపజేయడం ద్వారా అధిక-నాణ్యత ఇంటర్‌పోలేషన్‌ను నిర్వహించే రీసాంప్లింగ్ పద్ధతి</string>\n    <string name=\"mitchell_sub\">స్కేల్ చేయబడిన ఇమేజ్‌లో షార్ప్‌నెస్ మరియు యాంటీ-అలియాసింగ్ మధ్య సమతుల్యతను సాధించడానికి సర్దుబాటు చేయగల పారామితులతో కన్వల్యూషన్ ఫిల్టర్‌ని ఉపయోగించే రీసాంప్లింగ్ పద్ధతి</string>\n    <string name=\"spline_sub\">వక్రరేఖ లేదా ఉపరితలం, అనువైన మరియు నిరంతర ఆకార ప్రాతినిధ్యాన్ని సజావుగా ఇంటర్‌పోలేట్ చేయడానికి మరియు అంచనా వేయడానికి పీస్‌వైస్-డిఫైన్డ్ పాలినోమియల్ ఫంక్షన్‌లను ఉపయోగిస్తుంది</string>\n    <string name=\"saved_to_original\">అసలు గమ్యస్థానంలో %1$s పేరుతో ఓవర్‌రైట్ చేయబడిన ఫైల్</string>\n    <string name=\"magnifier\">మాగ్నిఫైయర్</string>\n    <string name=\"magnifier_sub\">మెరుగైన ప్రాప్యత కోసం డ్రాయింగ్ మోడ్‌లలో వేలు ఎగువన మాగ్నిఫైయర్‌ని ప్రారంభిస్తుంది</string>\n    <string name=\"force_exif_widget_initial_value\">ప్రారంభ విలువను బలవంతం చేయండి</string>\n    <string name=\"force_exif_widget_initial_value_sub\">ఎక్సిఫ్ విడ్జెట్‌ని మొదట్లో తనిఖీ చేయమని బలవంతం చేస్తుంది</string>\n    <string name=\"allow_multiple_languages\">బహుళ భాషలను అనుమతించండి</string>\n    <string name=\"segmentation_mode_auto_osd\">ఆటో ఓరియంటేషన్ &amp; స్క్రిప్ట్ డిటెక్షన్</string>\n    <string name=\"segmentation_mode_auto_only\">ఆటో మాత్రమే</string>\n    <string name=\"segmentation_mode_auto\">దానంతట అదే</string>\n    <string name=\"segmentation_mode_single_column\">సింగిల్ కాలమ్</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">సింగిల్ బ్లాక్ నిలువు వచనం</string>\n    <string name=\"segmentation_mode_single_block\">సింగిల్ బ్లాక్</string>\n    <string name=\"segmentation_mode_single_line\">సింగిల్ లైన్</string>\n    <string name=\"segmentation_mode_single_char\">ఒకే అక్షరం</string>\n    <string name=\"segmentation_mode_sparse_text\">చిన్న వచనం</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">స్పేర్ టెక్స్ట్ ఓరియంటేషన్ &amp; స్క్రిప్ట్ డిటెక్షన్</string>\n    <string name=\"segmentation_mode_raw_line\">ముడి లైన్</string>\n    <string name=\"delete_language_sub\">మీరు అన్ని గుర్తింపు రకాల కోసం భాష \\\"%1$s\\\" OCR శిక్షణ డేటాను తొలగించాలనుకుంటున్నారా లేదా ఎంచుకున్న ఒక (%2$s) కోసం మాత్రమే?</string>\n    <string name=\"current\">ప్రస్తుత</string>\n    <string name=\"gradient_maker_sub\">అనుకూలీకరించిన రంగులు మరియు ప్రదర్శన రకంతో ఇచ్చిన అవుట్‌పుట్ పరిమాణం యొక్క ప్రవణతను సృష్టించండి</string>\n    <string name=\"tile_mode\">టైల్ మోడ్</string>\n    <string name=\"tile_mode_repeated\">పునరావృతమైంది</string>\n    <string name=\"tile_mode_mirror\">అద్దం</string>\n    <string name=\"tile_mode_clamp\">బిగింపు</string>\n    <string name=\"tile_mode_decal\">డెకాల్</string>\n    <string name=\"watermarking_sub\">అనుకూలీకరించదగిన టెక్స్ట్/ఇమేజ్ వాటర్‌మార్క్‌లతో చిత్రాలను కవర్ చేయండి</string>\n    <string name=\"repeat_watermark_sub\">ఇచ్చిన స్థానం వద్ద సింగిల్‌కు బదులుగా చిత్రంపై వాటర్‌మార్క్ పునరావృతమవుతుంది</string>\n    <string name=\"offset_x\">ఆఫ్‌సెట్ X</string>\n    <string name=\"offset_y\">ఆఫ్‌సెట్ Y</string>\n    <string name=\"text_color\">టెక్స్ట్ రంగు</string>\n    <string name=\"select_gif_image_to_start\">ప్రారంభించడానికి GIF చిత్రాన్ని ఎంచుకోండి</string>\n    <string name=\"use_size_of_first_frame\">మొదటి ఫ్రేమ్ పరిమాణాన్ని ఉపయోగించండి</string>\n    <string name=\"secure_mode_sub\">నిష్క్రమణలో కంటెంట్‌ను దాచిపెడుతుంది, స్క్రీన్ క్యాప్చర్ చేయబడదు లేదా రికార్డ్ చేయబడదు</string>\n    <string name=\"quantizier\">క్వాంటిజైయర్</string>\n    <string name=\"gray_scale\">గ్రే స్కేల్</string>\n    <string name=\"bayer_two_dithering\">బేయర్ టూ బై టూ డైథరింగ్</string>\n    <string name=\"floyd_steinberg_dithering\">ఫ్లాయిడ్ స్టెయిన్‌బర్గ్ డిథరింగ్</string>\n    <string name=\"jarvis_judice_ninke_dithering\">జార్విస్ జూడిస్ నింకే డిథరింగ్</string>\n    <string name=\"two_row_sierra_dithering\">రెండు వరుస సియెర్రా డిథరింగ్</string>\n    <string name=\"atkinson_dithering\">అట్కిన్సన్ డిథరింగ్</string>\n    <string name=\"false_floyd_steinberg_dithering\">ఫాల్స్ ఫ్లాయిడ్ స్టెయిన్‌బర్గ్ డిథరింగ్</string>\n    <string name=\"random_dithering\">రాండమ్ డిథరింగ్</string>\n    <string name=\"simple_threshold_dithering\">సాధారణ థ్రెషోల్డ్ డైథరింగ్</string>\n    <string name=\"b_spline_sub\">ఒక వక్రత లేదా ఉపరితలం, అనువైన మరియు నిరంతర ఆకార ప్రాతినిధ్యాన్ని సజావుగా ఇంటర్‌పోలేట్ చేయడానికి మరియు అంచనా వేయడానికి పీస్‌వైస్-డిఫైన్డ్ బైక్యూబిక్ బహుపది ఫంక్షన్‌లను ఉపయోగిస్తుంది</string>\n    <string name=\"native_stack_blur\">స్థానిక స్టాక్ బ్లర్</string>\n    <string name=\"tilt_shift\">టిల్ట్ షిఫ్ట్</string>\n    <string name=\"anaglyph\">అనాగ్లిఫ్</string>\n    <string name=\"noise\">శబ్దం</string>\n    <string name=\"pixel_sort\">పిక్సెల్ క్రమబద్ధీకరణ</string>\n    <string name=\"shuffle\">షఫుల్ చేయండి</string>\n    <string name=\"channel_shift_x\">ఛానల్ షిఫ్ట్ X</string>\n    <string name=\"channel_shift_y\">ఛానల్ షిఫ్ట్ వై</string>\n    <string name=\"corruption_size\">అవినీతి పరిమాణం</string>\n    <string name=\"corruption_shift_x\">అవినీతి షిఫ్ట్ X</string>\n    <string name=\"corruption_shift_y\">అవినీతి షిఫ్ట్ వై</string>\n    <string name=\"tent_blur\">టెంట్ బ్లర్</string>\n    <string name=\"side_fade\">సైడ్ ఫేడ్</string>\n    <string name=\"side\">వైపు</string>\n    <string name=\"top\">టాప్</string>\n    <string name=\"bottom\">దిగువన</string>\n    <string name=\"strength\">బలం</string>\n    <string name=\"crystallize\">స్ఫటికీకరించండి</string>\n    <string name=\"amplitude\">వ్యాప్తి</string>\n    <string name=\"marble\">మార్బుల్</string>\n    <string name=\"turbulence\">అల్లకల్లోలం</string>\n    <string name=\"oil\">నూనె</string>\n    <string name=\"color_matrix_4x4\">కలర్ మ్యాట్రిక్స్ 4x4</string>\n    <string name=\"color_matrix_3x3\">కలర్ మ్యాట్రిక్స్ 3x3</string>\n    <string name=\"polaroid\">పోలరాయిడ్</string>\n    <string name=\"tritonomaly\">ట్రిటోనోమలీ</string>\n    <string name=\"deutaromaly\">డ్యూటోరోమలీ</string>\n    <string name=\"protonomaly\">ప్రోటోనోమలీ</string>\n    <string name=\"vintage\">పాతకాలపు</string>\n    <string name=\"browni\">బ్రౌనీ</string>\n    <string name=\"coda_chrome\">కోడా క్రోమ్</string>\n    <string name=\"night_vision\">రాత్రి దృష్టి</string>\n    <string name=\"warm\">వెచ్చగా</string>\n    <string name=\"cool\">కూల్</string>\n    <string name=\"tritanopia\">ట్రిటానోపియా</string>\n    <string name=\"deutaronotopia\">డ్యూటారోనోటోపియా</string>\n    <string name=\"protanopia\">ప్రొటానోపియా</string>\n    <string name=\"achromatomaly\">అక్రోమటోమలీ</string>\n    <string name=\"achromatopsia\">అక్రోమాటోప్సియా</string>\n    <string name=\"unsharp\">పదును తీసివేయు</string>\n    <string name=\"pastel\">పాస్టెల్</string>\n    <string name=\"orange_haze\">ఆరెంజ్ హేజ్</string>\n    <string name=\"pink_dream\">పింక్ కల</string>\n    <string name=\"golden_hour\">గోల్డెన్ అవర్</string>\n    <string name=\"hot_summer\">వేడి వేసవి</string>\n    <string name=\"purple_mist\">పర్పుల్ మిస్ట్</string>\n    <string name=\"sunrise\">సూర్యోదయం</string>\n    <string name=\"soft_spring_light\">సాఫ్ట్ స్ప్రింగ్ లైట్</string>\n    <string name=\"autumn_tones\">ఆటం టోన్లు</string>\n    <string name=\"lavender_dream\">లావెండర్ డ్రీం</string>\n    <string name=\"cyberpunk\">సైబర్‌పంక్</string>\n    <string name=\"lemonade_light\">నిమ్మరసం లైట్</string>\n    <string name=\"spectral_fire\">స్పెక్ట్రల్ ఫైర్</string>\n    <string name=\"night_magic\">రాత్రి మేజిక్</string>\n    <string name=\"fantasy_landscape\">ఫాంటసీ ల్యాండ్‌స్కేప్</string>\n    <string name=\"color_explosion\">రంగు పేలుడు</string>\n    <string name=\"rainbow_world\">రెయిన్బో వరల్డ్</string>\n    <string name=\"deep_purple\">డీప్ పర్పుల్</string>\n    <string name=\"space_portal\">స్పేస్ పోర్టల్</string>\n    <string name=\"red_swirl\">రెడ్ స్విర్ల్</string>\n    <string name=\"digital_code\">డిజిటల్ కోడ్</string>\n    <string name=\"icon_shape_sub\">కార్డ్‌ల ప్రముఖ చిహ్నాల క్రింద ఎంచుకున్న ఆకారంతో కంటైనర్‌ను జోడిస్తుంది</string>\n    <string name=\"icon_shape\">ఐకాన్ ఆకారం</string>\n    <string name=\"drago\">డ్రాగో</string>\n    <string name=\"aldridge\">ఆల్డ్రిడ్జ్</string>\n    <string name=\"cutoff\">కత్తిరించిన</string>\n    <string name=\"uchimura\">ఉచిమురా</string>\n    <string name=\"mobius\">మోబియస్</string>\n    <string name=\"transition\">పరివర్తన</string>\n    <string name=\"peak\">శిఖరం</string>\n    <string name=\"color_anomaly\">రంగు క్రమరాహిత్యం</string>\n    <string name=\"images_overwritten\">చిత్రాలు అసలు గమ్యస్థానంలో భర్తీ చేయబడ్డాయి</string>\n    <string name=\"cannot_change_image_format\">ఓవర్‌రైట్ ఫైల్‌ల ఎంపిక ప్రారంభించబడినప్పుడు చిత్ర ఆకృతిని మార్చలేరు</string>\n    <string name=\"emoji_as_color_scheme\">రంగు పథకం వలె ఎమోజి</string>\n    <string name=\"emoji_as_color_scheme_sub\">మాన్యువల్‌గా నిర్వచించిన వాటికి బదులుగా ఎమోజి ప్రాథమిక రంగును యాప్ కలర్ స్కీమ్‌గా ఉపయోగిస్తుంది</string>\n    <string name=\"presets_sub_bytes\">ఇక్కడ ప్రీసెట్ అవుట్‌పుట్ ఫైల్ %ని నిర్ణయిస్తుంది, అనగా మీరు 5mb ఇమేజ్‌పై ప్రీసెట్ 50ని ఎంచుకుంటే, సేవ్ చేసిన తర్వాత మీరు 2.5mb ఇమేజ్‌ని పొందుతారు</string>\n    <string name=\"tg_chat\">టెలిగ్రామ్ చాట్</string>\n    <string name=\"crop_mask\">క్రాప్ మాస్క్</string>\n    <string name=\"restore\">పునరుద్ధరించు</string>\n    <string name=\"backup_sub\">మీ యాప్ సెట్టింగ్‌లను ఫైల్‌కి బ్యాకప్ చేయండి</string>\n    <string name=\"delete\">తొలగించు</string>\n    <string name=\"delete_color_scheme_title\">పథకాన్ని తొలగించండి</string>\n    <string name=\"text\">వచనం</string>\n    <string name=\"emotions\">భావోద్వేగాలు</string>\n    <string name=\"symbols\">చిహ్నాలు</string>\n    <string name=\"enable_emoji\">ఎమోజీని ప్రారంభించండి</string>\n    <string name=\"travels_and_places\">ప్రయాణాలు మరియు ప్రదేశాలు</string>\n    <string name=\"trim_image\">చిత్రాన్ని కత్తిరించండి</string>\n    <string name=\"restore_background\">నేపథ్యాన్ని పునరుద్ధరించండి</string>\n    <string name=\"pipette\">పైపెట్</string>\n    <string name=\"max_colors_count\">గరిష్ట రంగుల సంఖ్య</string>\n    <string name=\"updates\">నవీకరణలు</string>\n    <string name=\"allow_betas\">బీటాలను అనుమతించండి</string>\n    <string name=\"draw_arrows\">బాణాలు గీయండి</string>\n    <string name=\"draw_arrows_sub\">ప్రారంభించబడితే డ్రాయింగ్ మార్గం పాయింటింగ్ బాణం వలె సూచించబడుతుంది</string>\n    <string name=\"enhanced_circle_pixelation\">మెరుగైన సర్కిల్ పిక్సెలేషన్</string>\n    <string name=\"remove_color\">రంగును తీసివేయండి</string>\n    <string name=\"recode\">రీకోడ్ చేయండి</string>\n    <string name=\"erode\">ఈరోడ్</string>\n    <string name=\"conduction\">కండక్షన్</string>\n    <string name=\"anisotropic_diffusion\">అనిసోట్రోపిక్ వ్యాప్తి</string>\n    <string name=\"diffusion\">వ్యాప్తి</string>\n    <string name=\"horizontal_wind_stagger\">క్షితిజసమాంతర గాలి స్టాగర్</string>\n    <string name=\"fast_bilaterial_blur\">వేగవంతమైన ద్వైపాక్షిక బ్లర్</string>\n    <string name=\"poisson_blur\">పాయిజన్ బ్లర్</string>\n    <string name=\"logarithmic_tone_mapping\">లాగరిథమిక్ టోన్ మ్యాపింగ్</string>\n    <string name=\"stroke_color\">స్ట్రోక్ రంగు</string>\n    <string name=\"fractal_glass\">ఫ్రాక్టల్ గ్లాస్</string>\n    <string name=\"water_effect\">నీటి ప్రభావం</string>\n    <string name=\"just_size\">పరిమాణం</string>\n    <string name=\"frequency_x\">ఫ్రీక్వెన్సీ X</string>\n    <string name=\"frequency_y\">ఫ్రీక్వెన్సీ Y</string>\n    <string name=\"amplitude_x\">వ్యాప్తి X</string>\n    <string name=\"amplitude_y\">వ్యాప్తి Y</string>\n    <string name=\"perlin_distortion\">పెర్లిన్ వక్రీకరణ</string>\n    <string name=\"hable_filmic_tone_mapping\">హేబుల్ ఫిల్మిక్ టోన్ మ్యాపింగ్</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl బర్గెస్ టోన్ మ్యాపింగ్</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES ఫిల్మిక్ టోన్ మ్యాపింగ్</string>\n    <string name=\"aces_hill_tone_mapping\">ACES హిల్ టోన్ మ్యాపింగ్</string>\n    <string name=\"all\">అన్నీ</string>\n    <string name=\"full_filter\">పూర్తి ఫిల్టర్</string>\n    <string name=\"start_position\">ప్రారంభించండి</string>\n    <string name=\"center_position\">కేంద్రం</string>\n    <string name=\"end_position\">ముగింపు</string>\n    <string name=\"full_filter_sub\">ఇచ్చిన ఇమేజ్‌లు లేదా సింగిల్ ఇమేజ్‌కి ఏదైనా ఫిల్టర్ చైన్‌లను వర్తింపజేయండి</string>\n    <string name=\"pdf_tools\">PDF సాధనాలు</string>\n    <string name=\"gradient_maker\">గ్రేడియంట్ మేకర్</string>\n    <string name=\"speed\">వేగం</string>\n    <string name=\"dehaze\">డీహేజ్</string>\n    <string name=\"omega\">ఒమేగా</string>\n    <string name=\"rate_app\">యాప్‌ని రేట్ చేయండి</string>\n    <string name=\"rate\">రేట్ చేయండి</string>\n    <string name=\"rate_app_sub\">ఈ యాప్ పూర్తిగా ఉచితం, మీరు దీన్ని పెద్దదిగా చేయాలనుకుంటే, దయచేసి Github 😄లో ప్రాజెక్ట్‌కి నక్షత్రం వేయండి</string>\n    <string name=\"simple_effects\">సాధారణ ప్రభావాలు</string>\n    <string name=\"gradient_type_linear\">లీనియర్</string>\n    <string name=\"gradient_type_radial\">రేడియల్</string>\n    <string name=\"gradient_type_sweep\">స్వీప్ చేయండి</string>\n    <string name=\"gradient_type\">గ్రేడియంట్ రకం</string>\n    <string name=\"center_x\">సెంటర్ X</string>\n    <string name=\"center_y\">సెంటర్ Y</string>\n    <string name=\"color_stops\">రంగు స్టాప్స్</string>\n    <string name=\"add_color\">రంగును జోడించండి</string>\n    <string name=\"properties\">లక్షణాలు</string>\n    <string name=\"lasso\">లాస్సో</string>\n    <string name=\"lasso_sub\">ఇచ్చిన మార్గం ద్వారా మూసి నిండిన మార్గాన్ని గీస్తుంది</string>\n    <string name=\"draw_path_mode\">పాత్ మోడ్‌ని గీయండి</string>\n    <string name=\"double_line_arrow\">డబుల్ లైన్ బాణం</string>\n    <string name=\"free_drawing\">ఉచిత డ్రాయింగ్</string>\n    <string name=\"double_arrow\">డబుల్ బాణం</string>\n    <string name=\"line_arrow\">లైన్ బాణం</string>\n    <string name=\"arrow\">బాణం</string>\n    <string name=\"line\">లైన్</string>\n    <string name=\"free_drawing_sub\">ఇన్‌పుట్ విలువగా మార్గాన్ని గీస్తుంది</string>\n    <string name=\"line_sub\">ప్రారంభ స్థానం నుండి ముగింపు బిందువు వరకు మార్గాన్ని లైన్‌గా గీస్తుంది</string>\n    <string name=\"line_arrow_sub\">ప్రారంభ స్థానం నుండి ముగింపు బిందువు వరకు పాయింటింగ్ బాణాన్ని లైన్‌గా గీస్తుంది</string>\n    <string name=\"arrow_sub\">ఇచ్చిన మార్గం నుండి పాయింటింగ్ బాణాన్ని గీస్తుంది</string>\n    <string name=\"double_line_arrow_sub\">స్టార్ట్ పాయింట్ నుండి ఎండ్ పాయింట్ వరకు డబుల్ పాయింటింగ్ బాణాన్ని లైన్‌గా గీస్తుంది</string>\n    <string name=\"double_arrow_sub\">ఇచ్చిన మార్గం నుండి డబుల్ పాయింటింగ్ బాణాన్ని గీస్తుంది</string>\n    <string name=\"outlined_oval\">వివరించిన ఓవల్</string>\n    <string name=\"outlined_rect\">వివరించిన రెక్ట్</string>\n    <string name=\"oval\">ఓవల్</string>\n    <string name=\"rect\">రెక్ట్</string>\n    <string name=\"rect_sub\">ప్రారంభ స్థానం నుండి ముగింపు బిందువు వరకు నేరుగా గీస్తుంది</string>\n    <string name=\"oval_sub\">ప్రారంభ బిందువు నుండి ముగింపు బిందువు వరకు ఓవల్ గీస్తుంది</string>\n    <string name=\"outlined_oval_sub\">ప్రారంభ బిందువు నుండి ముగింపు బిందువు వరకు వివరించిన అండాకారాన్ని గీస్తుంది</string>\n    <string name=\"outlined_rect_sub\">ప్రారంభ స్థానం నుండి ముగింపు బిందువు వరకు వివరించిన రెక్ట్‌ను గీస్తుంది</string>\n    <string name=\"dithering\">డిథరింగ్</string>\n    <string name=\"bayer_three_dithering\">బేయర్ త్రీ బై త్రీ డైథరింగ్</string>\n    <string name=\"bayer_four_dithering\">బేయర్ ఫోర్ బై ఫోర్ డైథరింగ్</string>\n    <string name=\"bayer_eight_dithering\">బేయర్ ఎయిట్ బై ఎయిట్ డైథరింగ్</string>\n    <string name=\"sierra_dithering\">సియెర్రా డిథరింగ్</string>\n    <string name=\"sierra_lite_dithering\">సియెర్రా లైట్ డిథరింగ్</string>\n    <string name=\"stucki_dithering\">స్టకీ డిథరింగ్</string>\n    <string name=\"burkes_dithering\">బర్క్స్ డిథరింగ్</string>\n    <string name=\"left_to_right_dithering\">ఎడమ నుండి కుడికి డైథరింగ్</string>\n    <string name=\"mask_color\">మాస్క్ రంగు</string>\n    <string name=\"mask_preview\">మాస్క్ ప్రివ్యూ</string>\n    <string name=\"mask_preview_sub\">మీకు సుమారుగా ఫలితాన్ని చూపడానికి డ్రా ఫిల్టర్ మాస్క్ రెండర్ చేయబడుతుంది</string>\n    <string name=\"scale_mode\">స్కేల్ మోడ్</string>\n    <string name=\"bilinear\">బైలీనియర్</string>\n    <string name=\"hann\">హాన్</string>\n    <string name=\"default_value\">డిఫాల్ట్ విలువ</string>\n    <string name=\"sigma\">సిగ్మా</string>\n    <string name=\"spatial_sigma\">ప్రాదేశిక సిగ్మా</string>\n    <string name=\"median_blur\">మధ్యస్థ బ్లర్</string>\n    <string name=\"only_clip\">క్లిప్ మాత్రమే</string>\n    <string name=\"only_clip_sub\">నిల్వకు సేవ్ చేయడం అమలు చేయబడదు మరియు చిత్రం క్లిప్‌బోర్డ్‌లో మాత్రమే ఉంచడానికి ప్రయత్నించబడుతుంది</string>\n    <string name=\"brightness_enforcement\">ప్రకాశం అమలు</string>\n    <string name=\"screen\">స్క్రీన్</string>\n    <string name=\"gradient_maker_type_image\">గ్రేడియంట్ ఓవర్‌లే</string>\n    <string name=\"gradient_maker_type_image_sub\">ఇచ్చిన చిత్రం పైభాగంలో ఏదైనా గ్రేడియంట్‌ని కంపోజ్ చేయండి</string>\n    <string name=\"transformations\">రూపాంతరాలు</string>\n    <string name=\"camera\">కెమెరా</string>\n    <string name=\"camera_sub\">చిత్రాన్ని తీయడానికి కెమెరాను ఉపయోగిస్తుంది, ఈ ఇమేజ్ సోర్స్ నుండి ఒక చిత్రాన్ని మాత్రమే పొందడం సాధ్యమవుతుందని గమనించండి</string>\n    <string name=\"grain\">ధాన్యం</string>\n    <string name=\"colorful_swirl\">రంగుల స్విర్ల్</string>\n    <string name=\"electric_gradient\">ఎలక్ట్రిక్ గ్రేడియంట్</string>\n    <string name=\"caramel_darkness\">కారామెల్ డార్క్నెస్</string>\n    <string name=\"futuristic_gradient\">ఫ్యూచరిస్టిక్ గ్రేడియంట్</string>\n    <string name=\"green_sun\">ఆకుపచ్చ సూర్యుడు</string>\n    <string name=\"watermarking\">వాటర్‌మార్కింగ్</string>\n    <string name=\"repeat_watermark\">వాటర్‌మార్క్‌ని పునరావృతం చేయండి</string>\n    <string name=\"watermark_type\">వాటర్‌మార్క్ రకం</string>\n    <string name=\"watermarking_image_sub\">ఈ చిత్రం వాటర్‌మార్కింగ్ కోసం నమూనాగా ఉపయోగించబడుతుంది</string>\n    <string name=\"overlay_mode\">అతివ్యాప్తి మోడ్</string>\n    <string name=\"features_sub\">ఫైల్‌ల పాస్‌వర్డ్ ఆధారిత ఎన్‌క్రిప్షన్. కొనసాగించబడిన ఫైల్‌లు ఎంచుకున్న డైరెక్టరీలో నిల్వ చేయబడతాయి లేదా భాగస్వామ్యం చేయబడతాయి. డీక్రిప్ట్ చేసిన ఫైల్‌లను కూడా నేరుగా తెరవవచ్చు.</string>\n    <string name=\"file_explorer_picker_sub\">చిత్రాన్ని ఎంచుకోవడానికి GetContent ఉద్దేశాన్ని ఉపయోగించండి. ప్రతిచోటా పని చేస్తుంది, కానీ కొన్ని పరికరాలలో ఎంచుకున్న చిత్రాలను స్వీకరించడంలో సమస్యలు ఉన్నట్లు తెలిసింది. అది నా తప్పు కాదు.</string>\n    <string name=\"limits_resize_sub\">కారక నిష్పత్తిని సేవ్ చేస్తున్నప్పుడు ఇచ్చిన వెడల్పు మరియు ఎత్తు పరిమితులను అనుసరించడానికి ఎంచుకున్న చిత్రాల పరిమాణాన్ని మార్చండి</string>\n    <string name=\"pixel_size\">పిక్సెల్ పరిమాణం</string>\n    <string name=\"lock_draw_orientation\">లాక్ డ్రా ఓరియంటేషన్</string>\n    <string name=\"lock_draw_orientation_sub\">డ్రాయింగ్ మోడ్‌లో ప్రారంభించబడితే, స్క్రీన్ తిప్పబడదు</string>\n    <string name=\"bokeh\">బోకె</string>\n    <string name=\"gif_tools\">GIF సాధనాలు</string>\n    <string name=\"gif_tools_sub\">చిత్రాలను GIF చిత్రంగా మార్చండి లేదా ఇచ్చిన GIF చిత్రం నుండి ఫ్రేమ్‌లను సంగ్రహించండి</string>\n    <string name=\"gif_type_to_image\">చిత్రాలకు GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF ఫైల్‌ను చిత్రాల బ్యాచ్‌గా మార్చండి</string>\n    <string name=\"gif_type_to_gif_sub\">చిత్రాల బ్యాచ్‌ని GIF ఫైల్‌గా మార్చండి</string>\n    <string name=\"gif_type_to_gif\">GIFకి చిత్రాలు</string>\n    <string name=\"use_size_of_first_frame_sub\">పేర్కొన్న పరిమాణాన్ని మొదటి ఫ్రేమ్ కొలతలతో భర్తీ చేయండి</string>\n    <string name=\"repeat_count\">రిపీట్ కౌంట్</string>\n    <string name=\"frame_delay\">ఫ్రేమ్ ఆలస్యం</string>\n    <string name=\"millis\">మిల్లీస్</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">లాస్సో ఉపయోగించండి</string>\n    <string name=\"use_lasso_sub\">ఎరేసింగ్ చేయడానికి డ్రాయింగ్ మోడ్‌లో లాస్సోని ఉపయోగిస్తుంది</string>\n    <string name=\"original_image_preview_alpha\">ఒరిజినల్ ఇమేజ్ ప్రివ్యూ ఆల్ఫా</string>\n    <string name=\"masks\">ముసుగులు</string>\n    <string name=\"add_mask\">మాస్క్ జోడించండి</string>\n    <string name=\"mask_indexed\">మాస్క్ %d</string>\n    <string name=\"mask_filter\">మాస్క్ ఫిల్టర్</string>\n    <string name=\"mask_filter_sub\">ఇచ్చిన మాస్క్‌డ్ ఏరియాల్లో ఫిల్టర్ చైన్‌లను వర్తింపజేయండి, ప్రతి మాస్క్ ఏరియా దాని స్వంత ఫిల్టర్‌ల సెట్‌ను గుర్తించగలదు</string>\n    <string name=\"explicit\">స్పష్టమైన</string>\n    <string name=\"options_arrangement\">ఎంపికల అమరిక</string>\n    <string name=\"shadows\">నీడలు</string>\n    <string name=\"lookup\">పైకి చూడు</string>\n    <string name=\"donation\">దానం</string>\n    <string name=\"random_emojis_sub\">యాప్ బార్ ఎమోజి ఎంపిక చేసిన దాన్ని ఉపయోగించకుండా యాదృచ్ఛికంగా నిరంతరం మార్చబడుతుంది</string>\n    <string name=\"random_emojis\">యాదృచ్ఛిక ఎమోజీలు</string>\n    <string name=\"random_emojis_error\">ఎమోజీలు నిలిపివేయబడినప్పుడు యాదృచ్ఛిక ఎమోజి పికింగ్‌ని ఉపయోగించలేరు</string>\n    <string name=\"emoji_selection_error\">యాదృచ్ఛికంగా ప్రారంభించబడిన ఎమోజీని ఎంచుకునే సమయంలో ఎమోజీని ఎంచుకోలేరు</string>\n    <string name=\"check_for_updates\">తాజాకరణలకోసం ప్రయత్నించండి</string>\n    <string name=\"def\">డిఫాల్ట్</string>\n    <string name=\"email\">ఇమెయిల్</string>\n    <string name=\"delete_exif_sub\">ఏదైనా చిత్రాల సెట్ నుండి EXIF మెటాడేటాను తొలగించండి</string>\n    <string name=\"photo_picker\">ఫోటో పికర్</string>\n    <string name=\"gallery_picker\">గ్యాలరీ</string>\n    <string name=\"file_explorer_picker\">ఫైల్ ఎక్స్‌ప్లోరర్</string>\n    <string name=\"old_tv\">పాత టీవీ</string>\n    <string name=\"shuffle_blur\">బ్లర్ షఫుల్ చేయండి</string>\n    <string name=\"recognize_text\">OCR (వచనాన్ని గుర్తించండి)</string>\n    <string name=\"recognize_text_sub\">అందించిన చిత్రం నుండి వచనాన్ని గుర్తించండి, 120+ భాషలకు మద్దతు ఉంది</string>\n    <string name=\"picture_has_no_text\">చిత్రంలో వచనం లేదు లేదా యాప్ దానిని కనుగొనలేదు</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">గుర్తింపు రకం</string>\n    <string name=\"fast\">వేగంగా</string>\n    <string name=\"standard\">ప్రామాణికం</string>\n    <string name=\"best\">ఉత్తమమైనది</string>\n    <string name=\"no_data\">సమాచారం లేదు</string>\n    <string name=\"download_description\">Tesseract OCR యొక్క సరైన పనితీరు కోసం అదనపు శిక్షణ డేటా (%1$s) మీ పరికరానికి డౌన్‌లోడ్ చేయబడాలి. \\nమీరు %2$s డేటాను డౌన్‌లోడ్ చేయాలనుకుంటున్నారా?</string>\n    <string name=\"download\">డౌన్‌లోడ్ చేయండి</string>\n    <string name=\"no_connection\">కనెక్షన్ లేదు, రైలు నమూనాలను డౌన్‌లోడ్ చేయడానికి దాన్ని తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి</string>\n    <string name=\"downloaded_languages\">డౌన్‌లోడ్ చేయబడిన భాషలు</string>\n    <string name=\"available_languages\">అందుబాటులో ఉన్న భాషలు</string>\n    <string name=\"segmentation_mode\">సెగ్మెంటేషన్ మోడ్</string>\n    <string name=\"restore_background_sub\">బ్రష్ చెరిపివేయడానికి బదులుగా నేపథ్యాన్ని పునరుద్ధరిస్తుంది</string>\n    <string name=\"horizontal_grid\">క్షితిజసమాంతర గ్రిడ్</string>\n    <string name=\"vertical_grid\">నిలువు గ్రిడ్</string>\n    <string name=\"stitch_mode\">స్టిచ్ మోడ్</string>\n    <string name=\"rows_count\">వరుసల కౌంట్</string>\n    <string name=\"columns_count\">నిలువు వరుసల సంఖ్య</string>\n    <string name=\"use_pixel_switch\">పిక్సెల్ స్విచ్ ఉపయోగించండి</string>\n    <string name=\"use_pixel_switch_sub\">మీరు ఆధారితమైన Google మెటీరియల్‌కు బదులుగా పిక్సెల్ లాంటి స్విచ్ ఉపయోగించబడుతుంది</string>\n    <string name=\"slide\">స్లయిడ్</string>\n    <string name=\"side_by_side\">పక్కపక్కన</string>\n    <string name=\"toggle_tap\">టోగుల్ ట్యాప్</string>\n    <string name=\"transparency\">పారదర్శకత</string>\n    <string name=\"favorite\">ఇష్టమైన</string>\n    <string name=\"no_favorite_filters\">ఇంకా ఇష్టమైన ఫిల్టర్‌లు ఏవీ జోడించబడలేదు</string>\n    <string name=\"b_spline\">బి స్ప్లైన్</string>\n    <string name=\"regular\">రెగ్యులర్</string>\n    <string name=\"blur_edges\">అంచులను అస్పష్టం చేయండి</string>\n    <string name=\"blur_edges_sub\">ప్రారంభించబడితే దాని చుట్టూ ఉన్న ఖాళీలను ఒకే రంగుకు బదులుగా పూరించడానికి అసలైన చిత్రం కింద అస్పష్టమైన అంచులను గీస్తుంది</string>\n    <string name=\"pixelation\">పిక్సెలేషన్</string>\n    <string name=\"inverse_fill_type\">విలోమ పూరక రకం</string>\n    <string name=\"inverse_fill_type_sub\">ప్రారంభించబడితే, మాస్క్ లేని ప్రాంతాలన్నీ డిఫాల్ట్ ప్రవర్తనకు బదులుగా ఫిల్టర్ చేయబడతాయి</string>\n    <string name=\"confetti\">కాన్ఫెట్టి</string>\n    <string name=\"confetti_sub\">కాన్ఫెట్టి సేవ్ చేయడం, భాగస్వామ్యం చేయడం మరియు ఇతర ప్రాథమిక చర్యలపై చూపబడుతుంది</string>\n    <string name=\"secure_mode\">సురక్షిత మోడ్</string>\n    <string name=\"palette_style\">పాలెట్ శైలి</string>\n    <string name=\"tonal_spot\">టోనల్ స్పాట్</string>\n    <string name=\"neutral\">తటస్థ</string>\n    <string name=\"vibrant\">వైబ్రంట్</string>\n    <string name=\"expressive\">వ్యక్తీకరణ</string>\n    <string name=\"rainbow\">ఇంద్రధనస్సు</string>\n    <string name=\"containers_shadow\">కంటైనర్లు</string>\n    <string name=\"containers_shadow_sub\">కంటైనర్‌ల వెనుక షాడో డ్రాయింగ్‌ను ప్రారంభిస్తుంది</string>\n    <string name=\"sliders_shadow\">స్లయిడర్‌లు</string>\n    <string name=\"switches_shadow\">స్విచ్‌లు</string>\n    <string name=\"fabs_shadow\">FABలు</string>\n    <string name=\"buttons_shadow\">బటన్లు</string>\n    <string name=\"sliders_shadow_sub\">స్లయిడర్‌ల వెనుక షాడో డ్రాయింగ్‌ని ప్రారంభిస్తుంది</string>\n    <string name=\"switches_shadow_sub\">స్విచ్‌ల వెనుక షాడో డ్రాయింగ్‌ని ప్రారంభిస్తుంది</string>\n    <string name=\"fabs_shadow_sub\">ఫ్లోటింగ్ యాక్షన్ బటన్‌ల వెనుక షాడో డ్రాయింగ్‌ను ప్రారంభిస్తుంది</string>\n    <string name=\"buttons_shadow_sub\">డిఫాల్ట్ బటన్‌ల వెనుక షాడో డ్రాయింగ్‌ని ప్రారంభిస్తుంది</string>\n    <string name=\"foss_update_checker_warning\">కొత్త అప్‌డేట్ అందుబాటులో ఉందో లేదో తనిఖీ చేయడానికి ఈ అప్‌డేట్ చెకర్ GitHubకి కనెక్ట్ అవుతుంది</string>\n    <string name=\"attention\">శ్రద్ధ</string>\n    <string name=\"fading_edges\">ఫేడింగ్ ఎడ్జెస్</string>\n    <string name=\"disabled\">వికలాంగుడు</string>\n    <string name=\"both\">రెండు</string>\n    <string name=\"invert_colors\">విలోమ రంగులు</string>\n    <string name=\"invert_colors_sub\">ప్రారంభించబడితే, థీమ్ రంగులను ప్రతికూల వాటికి భర్తీ చేస్తుంది</string>\n    <string name=\"exit\">బయటకి దారి</string>\n    <string name=\"preview_closing\">మీరు ఇప్పుడు ప్రివ్యూను వదిలివేస్తే, మీరు మళ్లీ చిత్రాలను జోడించాలి</string>\n    <string name=\"image_format\">చిత్రం ఫార్మాట్</string>\n    <string name=\"material_you_sub\">చిత్రం నుండి \\\"Material You \\\" పాలెట్ సృష్టిస్తుంది</string>\n    <string name=\"dark_colors\">ముదురు రంగులు</string>\n    <string name=\"dark_colors_sub\">బదులుగా కాంతి వేరియంట్ రాత్రి మోడ్ రంగు పథకం ఉపయోగిస్తుంది</string>\n    <string name=\"copy_as_compose_code\">\\\"Jetpack Compose\\\" కోడ్గా కాపీ చేయండి</string>\n    <string name=\"ring_blur\">రింగ్ బ్లర్</string>\n    <string name=\"cross_blur\">క్రాస్ బ్లర్</string>\n    <string name=\"circle_blur\">సర్కిల్ అస్పష్టత</string>\n    <string name=\"star_blur\">నక్షత్ర అస్పష్టత</string>\n    <string name=\"linear_tilt_shift\">సరళ వంపు మార్పు</string>\n    <string name=\"tags_to_remove\">తొలగించు టాగ్లు</string>\n    <string name=\"motion_blur\">మోషన్ బ్లర్</string>\n    <string name=\"apng_type_to_apng\">APNGకి చిత్రాలు</string>\n    <string name=\"select_apng_image_to_start\">ప్రారంభించడానికి APNG చిత్రాన్ని ఎంచుకోండి</string>\n    <string name=\"apng_tools\">APNG సాధనాలు</string>\n    <string name=\"apng_tools_sub\">చిత్రాలను APNG చిత్రానికి మార్చండి లేదా ఇచ్చిన APNG చిత్రం నుండి ఫ్రేమ్‌లను సంగ్రహించండి</string>\n    <string name=\"apng_type_to_image\">చిత్రాలకు APNG</string>\n    <string name=\"apng_type_to_image_sub\">APNG ఫైల్‌ను చిత్రాల బ్యాచ్‌గా మార్చండి</string>\n    <string name=\"apng_type_to_apng_sub\">చిత్రాల బ్యాచ్‌ని APNG ఫైల్‌గా మార్చండి</string>\n    <string name=\"zip\">జిప్</string>\n    <string name=\"zip_sub\">ఇచ్చిన ఫైల్‌లు లేదా చిత్రాల నుండి జిప్ ఫైల్‌ను సృష్టించండి</string>\n    <string name=\"drag_handle_width\">హ్యాండిల్ వెడల్పును లాగండి</string>\n    <string name=\"confetti_type\">కాన్ఫెట్టి రకం</string>\n    <string name=\"festive\">పండుగ</string>\n    <string name=\"explode\">పేలుడు</string>\n    <string name=\"rain\">వర్షం</string>\n    <string name=\"corners\">మూలలు</string>\n    <string name=\"jxl_tools\">JXL సాధనాలు</string>\n    <string name=\"jxl_tools_sub\">నాణ్యత నష్టం లేకుండా JXL ~ JPEG ట్రాన్స్‌కోడింగ్ చేయండి లేదా GIF/APNGని JXL యానిమేషన్‌గా మార్చండి</string>\n    <string name=\"jxl_type_to_jpeg\">JXL నుండి JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL నుండి JPEGకి లాస్‌లెస్ ట్రాన్స్‌కోడింగ్‌ను అమలు చేయండి</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG నుండి JXL వరకు లాస్‌లెస్ ట్రాన్స్‌కోడింగ్‌ను అమలు చేయండి</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG నుండి JXL</string>\n    <string name=\"select_jxl_image_to_start\">ప్రారంభించడానికి JXL చిత్రాన్ని ఎంచుకోండి</string>\n    <string name=\"fast_gaussian_blur_2d\">ఫాస్ట్ గాస్సియన్ బ్లర్ 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">ఫాస్ట్ గాస్సియన్ బ్లర్ 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">ఫాస్ట్ గాస్సియన్ బ్లర్ 4D</string>\n    <string name=\"auto_paste\">కారు ఈస్టర్</string>\n    <string name=\"auto_paste_sub\">క్లిప్‌బోర్డ్ డేటాను ఆటోమేటిక్‌గా అతికించడానికి యాప్‌ని అనుమతిస్తుంది, కనుక ఇది ప్రధాన స్క్రీన్‌పై కనిపిస్తుంది మరియు మీరు దీన్ని ప్రాసెస్ చేయగలరు</string>\n    <string name=\"harmonization_color\">హార్మోనైజేషన్ రంగు</string>\n    <string name=\"harmonization_level\">హార్మోనైజేషన్ స్థాయి</string>\n    <string name=\"lanczos_bessel\">లాంజోస్ బెస్సెల్</string>\n    <string name=\"lanczos_bessel_sub\">పిక్సెల్ విలువలకు బెస్సెల్ (జింక్) ఫంక్షన్‌ని వర్తింపజేయడం ద్వారా అధిక-నాణ్యత ఇంటర్‌పోలేషన్‌ను నిర్వహించే రీసాంప్లింగ్ పద్ధతి</string>\n    <string name=\"gif_type_to_jxl\">GIF నుండి JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF చిత్రాలను JXL యానిమేటెడ్ చిత్రాలుగా మార్చండి</string>\n    <string name=\"apng_type_to_jxl\">APNG నుండి JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG చిత్రాలను JXL యానిమేటెడ్ చిత్రాలుగా మార్చండి</string>\n    <string name=\"jxl_type_to_images\">చిత్రాలకు JXL</string>\n    <string name=\"jxl_type_to_images_sub\">JXL యానిమేషన్‌ను చిత్రాల బ్యాచ్‌గా మార్చండి</string>\n    <string name=\"jxl_type_to_jxl\">JXLకి చిత్రాలు</string>\n    <string name=\"jxl_type_to_jxl_sub\">చిత్రాల బ్యాచ్‌ని JXL యానిమేషన్‌కి మార్చండి</string>\n    <string name=\"behavior\">ప్రవర్తన</string>\n    <string name=\"skip_file_picking\">ఫైల్ ఎంపికను దాటవేయి</string>\n    <string name=\"skip_file_picking_sub\">ఎంచుకున్న స్క్రీన్‌పై ఇది సాధ్యమైతే ఫైల్ పికర్ వెంటనే చూపబడుతుంది</string>\n    <string name=\"generate_previews\">ప్రివ్యూలను రూపొందించండి</string>\n    <string name=\"generate_previews_sub\">ప్రివ్యూ జనరేషన్‌ని ప్రారంభిస్తుంది, ఇది కొన్ని పరికరాల్లో క్రాష్‌లను నివారించడంలో సహాయపడవచ్చు, ఇది సింగిల్ ఎడిట్ ఆప్షన్‌లో కొన్ని ఎడిటింగ్ ఫంక్షనాలిటీని కూడా డిసేబుల్ చేస్తుంది</string>\n    <string name=\"lossy_compression\">లాస్సీ కంప్రెషన్</string>\n    <string name=\"lossy_compression_sub\">లాస్‌లెస్‌కి బదులుగా ఫైల్ పరిమాణాన్ని తగ్గించడానికి లాస్సీ కంప్రెషన్‌ని ఉపయోగిస్తుంది</string>\n    <string name=\"compression_type\">కుదింపు రకం</string>\n    <string name=\"speed_sub\">ఫలితంగా ఇమేజ్ డీకోడింగ్ వేగాన్ని నియంత్రిస్తుంది, ఇది ఫలిత చిత్రాన్ని వేగంగా తెరవడంలో సహాయపడుతుంది, %1$s విలువ అంటే నెమ్మదిగా డీకోడింగ్ అవుతుంది, అయితే %2$s - వేగంగా, ఈ సెట్టింగ్ అవుట్‌పుట్ చిత్ర పరిమాణాన్ని పెంచుతుంది</string>\n    <string name=\"sorting\">క్రమబద్ధీకరణ</string>\n    <string name=\"sort_by_date\">తేదీ</string>\n    <string name=\"sort_by_date_reversed\">తేదీ (రివర్స్డ్)</string>\n    <string name=\"sort_by_name\">పేరు</string>\n    <string name=\"sort_by_name_reversed\">పేరు (రివర్స్డ్)</string>\n    <string name=\"channels_configuration\">ఛానెల్‌ల కాన్ఫిగరేషన్</string>\n    <string name=\"header_today\">ఈరోజు</string>\n    <string name=\"header_yesterday\">నిన్న</string>\n    <string name=\"embedded_picker\">ఎంబెడెడ్ పికర్</string>\n    <string name=\"embedded_picker_sub\">ఇమేజ్ టూల్‌బాక్స్ యొక్క ఇమేజ్ పికర్</string>\n    <string name=\"no_permissions\">అనుమతులు లేవు</string>\n    <string name=\"request\">అభ్యర్థన</string>\n    <string name=\"pick_multiple_media\">బహుళ మీడియాను ఎంచుకోండి</string>\n    <string name=\"pick_single_media\">సింగిల్ మీడియాను ఎంచుకోండి</string>\n    <string name=\"pick\">ఎంచుకోండి</string>\n    <string name=\"try_again\">మళ్లీ ప్రయత్నించండి</string>\n    <string name=\"show_settings_in_landscape\">ల్యాండ్‌స్కేప్‌లో సెట్టింగ్‌లను చూపించు</string>\n    <string name=\"show_settings_in_landscape_sub\">ఇది నిలిపివేయబడితే, ల్యాండ్‌స్కేప్ మోడ్ సెట్టింగ్‌లలో శాశ్వతంగా కనిపించే ఎంపికకు బదులుగా ఎగువ యాప్ బార్‌లోని బటన్‌పై ఎప్పటిలాగే తెరవబడుతుంది</string>\n    <string name=\"fullscreen_settings\">పూర్తి స్క్రీన్ సెట్టింగ్‌లు</string>\n    <string name=\"fullscreen_settings_sub\">దీన్ని ప్రారంభించండి మరియు సెట్టింగ్‌ల పేజీ ఎల్లప్పుడూ స్లైడబుల్ డ్రాయర్ షీట్‌కు బదులుగా పూర్తి స్క్రీన్‌గా తెరవబడుతుంది</string>\n    <string name=\"switch_type\">స్విచ్ రకం</string>\n    <string name=\"compose\">కంపోజ్ చేయండి</string>\n    <string name=\"compose_switch_sub\">మీరు మారే జెట్‌ప్యాక్ కంపోజ్ మెటీరియల్</string>\n    <string name=\"material_you_switch_sub\">మీరు మార్చే మెటీరియల్</string>\n    <string name=\"max\">గరిష్టంగా</string>\n    <string name=\"resize_anchor\">యాంకర్ పరిమాణాన్ని మార్చండి</string>\n    <string name=\"pixel_switch\">పిక్సెల్</string>\n    <string name=\"fluent_switch\">నిష్ణాతులు</string>\n    <string name=\"fluent_switch_sub\">\\\"ఫ్లూయెంట్\\\" డిజైన్ సిస్టమ్ ఆధారంగా ఒక స్విచ్</string>\n    <string name=\"cupertino_switch\">కుపెర్టినో</string>\n    <string name=\"cupertino_switch_sub\">\\\"Cupertino\\\" డిజైన్ సిస్టమ్ ఆధారంగా ఒక స్విచ్</string>\n    <string name=\"images_to_svg\">SVGకి చిత్రాలు</string>\n    <string name=\"images_to_svg_sub\">ఇచ్చిన చిత్రాలను SVG చిత్రాలకు గుర్తించండి</string>\n    <string name=\"use_sampled_palette\">నమూనా పాలెట్ ఉపయోగించండి</string>\n    <string name=\"use_sampled_palette_sub\">ఈ ఎంపిక ప్రారంభించబడితే పరిమాణ పాలెట్ నమూనా చేయబడుతుంది</string>\n    <string name=\"path_omit\">మార్గం విస్మరించబడింది</string>\n    <string name=\"svg_warning\">డౌన్‌స్కేలింగ్ లేకుండా పెద్ద చిత్రాలను కనుగొనడం కోసం ఈ సాధనం యొక్క ఉపయోగం సిఫార్సు చేయబడదు, ఇది క్రాష్‌కు కారణమవుతుంది మరియు ప్రాసెసింగ్ సమయాన్ని పెంచుతుంది</string>\n    <string name=\"downscale_image\">తక్కువ స్థాయి చిత్రం</string>\n    <string name=\"downscale_image_sub\">ప్రాసెస్ చేయడానికి ముందు చిత్రం తక్కువ కొలతలకు తగ్గించబడుతుంది, ఇది సాధనం వేగంగా మరియు సురక్షితంగా పని చేయడానికి సహాయపడుతుంది</string>\n    <string name=\"min_color_ratio\">కనిష్ట రంగు నిష్పత్తి</string>\n    <string name=\"lines_threshold\">లైన్స్ థ్రెషోల్డ్</string>\n    <string name=\"quadratic_threshold\">క్వాడ్రాటిక్ థ్రెషోల్డ్</string>\n    <string name=\"coordinates_rounding_tolerance\">కోఆర్డినేట్ రౌండ్ టాలరెన్స్</string>\n    <string name=\"path_scale\">మార్గం స్కేల్</string>\n    <string name=\"reset_properties\">లక్షణాలను రీసెట్ చేయండి</string>\n    <string name=\"reset_properties_sub\">అన్ని లక్షణాలు డిఫాల్ట్ విలువలకు సెట్ చేయబడతాయి, ఈ చర్యను రద్దు చేయడం సాధ్యం కాదని గమనించండి</string>\n    <string name=\"detailed\">వివరంగా</string>\n    <string name=\"default_line_width\">డిఫాల్ట్ లైన్ వెడల్పు</string>\n    <string name=\"engine_mode\">ఇంజిన్ మోడ్</string>\n    <string name=\"legacy\">వారసత్వం</string>\n    <string name=\"lstm_network\">LSTM నెట్‌వర్క్</string>\n    <string name=\"legacy_and_lstm\">లెగసీ &amp;amp; LSTM</string>\n    <string name=\"convert\">మార్చు</string>\n    <string name=\"convert_sub\">ఇమేజ్ బ్యాచ్‌లను ఇచ్చిన ఆకృతికి మార్చండి</string>\n    <string name=\"add_new_folder\">కొత్త ఫోల్డర్‌ని జోడించండి</string>\n    <string name=\"tag_bits_per_sample\">ప్రతి నమూనాకు బిట్స్</string>\n    <string name=\"tag_compression\">కుదింపు</string>\n    <string name=\"tag_photometric_interpretation\">ఫోటోమెట్రిక్ ఇంటర్‌ప్రెటేషన్</string>\n    <string name=\"tag_samples_per_pixel\">ప్రతి పిక్సెల్‌కు నమూనాలు</string>\n    <string name=\"tag_planar_configuration\">ప్లానర్ కాన్ఫిగరేషన్</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr ఉప నమూనా</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr పొజిషనింగ్</string>\n    <string name=\"tag_x_resolution\">X రిజల్యూషన్</string>\n    <string name=\"tag_y_resolution\">Y రిజల్యూషన్</string>\n    <string name=\"tag_resolution_unit\">రిజల్యూషన్ యూనిట్</string>\n    <string name=\"tag_strip_offsets\">స్ట్రిప్ ఆఫ్‌సెట్‌లు</string>\n    <string name=\"tag_rows_per_strip\">ప్రతి స్ట్రిప్‌కి వరుసలు</string>\n    <string name=\"tag_strip_byte_counts\">స్ట్రిప్ బైట్ గణనలు</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG ఇంటర్‌చేంజ్ ఫార్మాట్</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG ఇంటర్‌చేంజ్ ఫార్మాట్ పొడవు</string>\n    <string name=\"tag_transfer_function\">బదిలీ ఫంక్షన్</string>\n    <string name=\"tag_white_point\">వైట్ పాయింట్</string>\n    <string name=\"tag_primary_chromaticities\">ప్రాథమిక క్రోమాటిటీస్</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr గుణకాలు</string>\n    <string name=\"tag_reference_black_white\">సూచన బ్లాక్ వైట్</string>\n    <string name=\"tag_datetime\">తేదీ సమయం</string>\n    <string name=\"tag_image_description\">చిత్ర వివరణ</string>\n    <string name=\"tag_make\">తయారు చేయండి</string>\n    <string name=\"tag_model\">మోడల్</string>\n    <string name=\"tag_software\">సాఫ్ట్‌వేర్</string>\n    <string name=\"tag_artist\">కళాకారుడు</string>\n    <string name=\"tag_copyright\">కాపీరైట్</string>\n    <string name=\"tag_exif_version\">ఎక్సిఫ్ వెర్షన్</string>\n    <string name=\"tag_flashpix_version\">Flashpix వెర్షన్</string>\n    <string name=\"tag_color_space\">కలర్ స్పేస్</string>\n    <string name=\"tag_gamma\">గామా</string>\n    <string name=\"tag_pixel_x_dimension\">పిక్సెల్ X డైమెన్షన్</string>\n    <string name=\"tag_pixel_y_dimension\">పిక్సెల్ Y డైమెన్షన్</string>\n    <string name=\"tag_compressed_bits_per_pixel\">పిక్సెల్‌కు కంప్రెస్డ్ బిట్స్</string>\n    <string name=\"tag_maker_note\">మేకర్ నోట్</string>\n    <string name=\"tag_user_comment\">వినియోగదారు వ్యాఖ్య</string>\n    <string name=\"tag_related_sound_file\">సంబంధిత సౌండ్ ఫైల్</string>\n    <string name=\"tag_datetime_original\">తేదీ సమయం అసలైనది</string>\n    <string name=\"tag_datetime_digitized\">తేదీ సమయం డిజిటైజ్ చేయబడింది</string>\n    <string name=\"tag_offset_time\">ఆఫ్‌సెట్ సమయం</string>\n    <string name=\"tag_offset_time_original\">ఆఫ్‌సెట్ టైమ్ ఒరిజినల్</string>\n    <string name=\"tag_offset_time_digitized\">ఆఫ్‌సెట్ టైమ్ డిజిటైజ్ చేయబడింది</string>\n    <string name=\"tag_subsec_time\">ఉప సెకను సమయం</string>\n    <string name=\"tag_subsec_time_original\">ఉప సెకను సమయం అసలైనది</string>\n    <string name=\"tag_subsec_time_digitized\">సబ్ సెక్షన్ టైమ్ డిజిటైజ్ చేయబడింది</string>\n    <string name=\"tag_exposure_time\">బహిర్గతం అయిన సమయం</string>\n    <string name=\"tag_f_number\">F సంఖ్య</string>\n    <string name=\"tag_exposure_program\">ఎక్స్పోజర్ ప్రోగ్రామ్</string>\n    <string name=\"tag_spectral_sensitivity\">స్పెక్ట్రల్ సెన్సిటివిటీ</string>\n    <string name=\"tag_photographic_sensitivity\">ఫోటోగ్రాఫిక్ సున్నితత్వం</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">సున్నితత్వం రకం</string>\n    <string name=\"tag_standard_output_sensitivity\">ప్రామాణిక అవుట్‌పుట్ సున్నితత్వం</string>\n    <string name=\"tag_recommended_exposure_index\">సిఫార్సు చేయబడిన ఎక్స్‌పోజర్ సూచిక</string>\n    <string name=\"tag_iso_speed\">ISO వేగం</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO స్పీడ్ అక్షాంశం yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO స్పీడ్ అక్షాంశం zzz</string>\n    <string name=\"tag_shutter_speed_value\">షట్టర్ స్పీడ్ విలువ</string>\n    <string name=\"tag_aperture_value\">ఎపర్చరు విలువ</string>\n    <string name=\"tag_brightness_value\">ప్రకాశం విలువ</string>\n    <string name=\"tag_exposure_bias_value\">ఎక్స్పోజర్ బయాస్ విలువ</string>\n    <string name=\"tag_max_aperture_value\">గరిష్ట ఎపర్చరు విలువ</string>\n    <string name=\"tag_subject_distance\">విషయం దూరం</string>\n    <string name=\"tag_metering_mode\">మీటరింగ్ మోడ్</string>\n    <string name=\"tag_flash\">ఫ్లాష్</string>\n    <string name=\"tag_subject_area\">సబ్జెక్ట్ ఏరియా</string>\n    <string name=\"tag_focal_length\">ఫోకల్ లెంగ్త్</string>\n    <string name=\"tag_flash_energy\">ఫ్లాష్ ఎనర్జీ</string>\n    <string name=\"tag_spatial_frequency_response\">స్పేషియల్ ఫ్రీక్వెన్సీ రెస్పాన్స్</string>\n    <string name=\"tag_focal_plane_x_resolution\">ఫోకల్ ప్లేన్ X రిజల్యూషన్</string>\n    <string name=\"tag_focal_plane_y_resolution\">ఫోకల్ ప్లేన్ Y రిజల్యూషన్</string>\n    <string name=\"tag_focal_plane_resolution_unit\">ఫోకల్ ప్లేన్ రిజల్యూషన్ యూనిట్</string>\n    <string name=\"tag_subject_location\">విషయం స్థానం</string>\n    <string name=\"tag_exposure_index\">ఎక్స్పోజర్ ఇండెక్స్</string>\n    <string name=\"tag_sensing_method\">సెన్సింగ్ పద్ధతి</string>\n    <string name=\"tag_file_source\">ఫైల్ మూలం</string>\n    <string name=\"tag_cfa_pattern\">CFA నమూనా</string>\n    <string name=\"tag_custom_rendered\">కస్టమ్ రెండర్ చేయబడింది</string>\n    <string name=\"tag_exposure_mode\">ఎక్స్పోజర్ మోడ్</string>\n    <string name=\"tag_white_balance\">వైట్ బ్యాలెన్స్</string>\n    <string name=\"tag_digital_zoom_ratio\">డిజిటల్ జూమ్ నిష్పత్తి</string>\n    <string name=\"tag_focal_length_in_35mm_film\">ఫోకల్ లెంగ్త్ 35mm ఫిల్మ్</string>\n    <string name=\"tag_scene_capture_type\">సీన్ క్యాప్చర్ రకం</string>\n    <string name=\"tag_gain_control\">నియంత్రణ పొందండి</string>\n    <string name=\"tag_contrast\">కాంట్రాస్ట్</string>\n    <string name=\"tag_saturation\">సంతృప్తత</string>\n    <string name=\"tag_sharpness\">పదును</string>\n    <string name=\"tag_device_setting_description\">పరికర సెట్టింగ్ వివరణ</string>\n    <string name=\"tag_subject_distance_range\">విషయ దూర పరిధి</string>\n    <string name=\"tag_image_unique_id\">చిత్రం ప్రత్యేక ID</string>\n    <string name=\"tag_camera_owner_name\">కెమెరా ఓనర్ పేరు</string>\n    <string name=\"tag_body_serial_number\">శరీర క్రమ సంఖ్య</string>\n    <string name=\"tag_lens_specification\">లెన్స్ స్పెసిఫికేషన్</string>\n    <string name=\"tag_lens_make\">లెన్స్ మేక్</string>\n    <string name=\"tag_lens_model\">లెన్స్ మోడల్</string>\n    <string name=\"tag_lens_serial_number\">లెన్స్ సీరియల్ నంబర్</string>\n    <string name=\"tag_gps_version_id\">GPS వెర్షన్ ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS అక్షాంశం Ref</string>\n    <string name=\"tag_gps_latitude\">GPS అక్షాంశం</string>\n    <string name=\"tag_gps_longitude_ref\">GPS లాంగిట్యూడ్ రెఫ్</string>\n    <string name=\"tag_gps_longitude\">GPS లాంగిట్యూడ్</string>\n    <string name=\"tag_gps_altitude_ref\">GPS ఎత్తు రెఫ్</string>\n    <string name=\"tag_gps_altitude\">GPS ఎత్తు</string>\n    <string name=\"tag_gps_timestamp\">GPS టైమ్ స్టాంప్</string>\n    <string name=\"tag_gps_satellites\">GPS ఉపగ్రహాలు</string>\n    <string name=\"tag_gps_status\">GPS స్థితి</string>\n    <string name=\"tag_gps_measure_mode\">GPS కొలత మోడ్</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS స్పీడ్ రెఫ్</string>\n    <string name=\"tag_gps_speed\">GPS వేగం</string>\n    <string name=\"tag_gps_track_ref\">GPS ట్రాక్ Ref</string>\n    <string name=\"tag_gps_track\">GPS ట్రాక్</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img దిశ రెఫ్</string>\n    <string name=\"tag_gps_img_direction\">GPS Img దిశ</string>\n    <string name=\"tag_gps_map_datum\">GPS మ్యాప్ డేటా</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS డెస్ట్ అక్షాంశం Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS డెస్ట్ అక్షాంశం</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS డెస్ట్ లాంగిట్యూడ్ రెఫ్</string>\n    <string name=\"tag_gps_dest_longitude\">GPS డెస్ట్ లాంగిట్యూడ్</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS డెస్ట్ బేరింగ్ Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS డెస్ట్ బేరింగ్</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS డెస్ట్ దూరం రెఫ్</string>\n    <string name=\"tag_gps_dest_distance\">GPS డెస్ట్ దూరం</string>\n    <string name=\"tag_gps_processing_method\">GPS ప్రాసెసింగ్ పద్ధతి</string>\n    <string name=\"tag_gps_area_information\">GPS ప్రాంత సమాచారం</string>\n    <string name=\"tag_gps_datestamp\">GPS తేదీ స్టాంప్</string>\n    <string name=\"tag_gps_differential\">GPS డిఫరెన్షియల్</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H స్థాన లోపం</string>\n    <string name=\"tag_interoperability_index\">ఇంటర్‌ఆపరేబిలిటీ ఇండెక్స్</string>\n    <string name=\"tag_dng_version\">DNG వెర్షన్</string>\n    <string name=\"tag_default_crop_size\">డిఫాల్ట్ క్రాప్ పరిమాణం</string>\n    <string name=\"tag_orf_preview_image_start\">ప్రివ్యూ చిత్రం ప్రారంభం</string>\n    <string name=\"tag_orf_preview_image_length\">ప్రివ్యూ చిత్రం పొడవు</string>\n    <string name=\"tag_orf_aspect_frame\">యాస్పెక్ట్ ఫ్రేమ్</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">సెన్సార్ బాటమ్ బోర్డర్</string>\n    <string name=\"tag_rw2_sensor_left_border\">సెన్సార్ లెఫ్ట్ బోర్డర్</string>\n    <string name=\"tag_rw2_sensor_right_border\">సెన్సార్ కుడి అంచు</string>\n    <string name=\"tag_rw2_sensor_top_border\">సెన్సార్ టాప్ బోర్డర్</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">ఇచ్చిన ఫాంట్ మరియు రంగుతో మార్గంలో వచనాన్ని గీయండి</string>\n    <string name=\"font_size\">ఫాంట్ పరిమాణం</string>\n    <string name=\"watermark_size\">వాటర్‌మార్క్ పరిమాణం</string>\n    <string name=\"repeat_text\">వచనాన్ని పునరావృతం చేయండి</string>\n    <string name=\"repeat_text_sub\">ఒక పర్యాయ డ్రాయింగ్‌కు బదులుగా పాత్ ముగిసే వరకు ప్రస్తుత వచనం పునరావృతమవుతుంది</string>\n    <string name=\"dash_size\">డాష్ పరిమాణం</string>\n    <string name=\"draw_mode_image_sub\">ఇచ్చిన మార్గంలో గీయడానికి ఎంచుకున్న చిత్రాన్ని ఉపయోగించండి</string>\n    <string name=\"draw_image_sub\">ఈ చిత్రం గీసిన మార్గం యొక్క పునరావృత ఎంట్రీగా ఉపయోగించబడుతుంది</string>\n    <string name=\"outlined_triangle_sub\">ప్రారంభ బిందువు నుండి ముగింపు బిందువు వరకు వివరించిన త్రిభుజాన్ని గీస్తుంది</string>\n    <string name=\"triangle_sub\">ప్రారంభ బిందువు నుండి ముగింపు బిందువు వరకు వివరించిన త్రిభుజాన్ని గీస్తుంది</string>\n    <string name=\"outlined_triangle\">వివరించిన త్రిభుజం</string>\n    <string name=\"triangle\">త్రిభుజం</string>\n    <string name=\"polygon_sub\">ప్రారంభ స్థానం నుండి ముగింపు బిందువు వరకు బహుభుజిని గీస్తుంది</string>\n    <string name=\"polygon\">బహుభుజి</string>\n    <string name=\"outlined_polygon\">వివరించిన బహుభుజి</string>\n    <string name=\"outlined_polygon_sub\">ప్రారంభ స్థానం నుండి ముగింపు బిందువు వరకు వివరించిన బహుభుజిని గీస్తుంది</string>\n    <string name=\"vertices\">శీర్షాలు</string>\n    <string name=\"draw_regular_polygon\">రెగ్యులర్ బహుభుజి గీయండి</string>\n    <string name=\"draw_regular_polygon_sub\">ఉచిత రూపానికి బదులుగా రెగ్యులర్‌గా ఉండే బహుభుజిని గీయండి</string>\n    <string name=\"star_sub\">స్టార్ట్ పాయింట్ నుండి ఎండ్ పాయింట్ వరకు నక్షత్రాన్ని గీస్తుంది</string>\n    <string name=\"star\">నక్షత్రం</string>\n    <string name=\"outlined_star\">వివరించిన నక్షత్రం</string>\n    <string name=\"outlined_star_sub\">ప్రారంభ స్థానం నుండి ముగింపు బిందువు వరకు వివరించిన నక్షత్రాన్ని గీస్తుంది</string>\n    <string name=\"inner_radius_ratio\">అంతర్గత వ్యాసార్థ నిష్పత్తి</string>\n    <string name=\"draw_regular_star\">రెగ్యులర్ స్టార్ గీయండి</string>\n    <string name=\"draw_regular_star_sub\">ఉచిత ఫారమ్‌కు బదులుగా రెగ్యులర్‌గా ఉండే నక్షత్రాన్ని గీయండి</string>\n    <string name=\"antialias\">యాంటిలియాస్</string>\n    <string name=\"antialias_sub\">పదునైన అంచులను నిరోధించడానికి యాంటీఅలియాసింగ్‌ని ప్రారంభిస్తుంది</string>\n    <string name=\"open_edit_instead_of_preview\">ప్రివ్యూకి బదులుగా సవరణను తెరవండి</string>\n    <string name=\"open_edit_instead_of_preview_sub\">మీరు ImageToolboxలో తెరవడానికి (ప్రివ్యూ) చిత్రాన్ని ఎంచుకున్నప్పుడు, ప్రివ్యూకి బదులుగా సవరణ ఎంపిక షీట్ తెరవబడుతుంది</string>\n    <string name=\"document_scanner\">డాక్యుమెంట్ స్కానర్</string>\n    <string name=\"document_scanner_sub\">పత్రాలను స్కాన్ చేయండి మరియు వాటి నుండి PDF లేదా ప్రత్యేక చిత్రాలను సృష్టించండి</string>\n    <string name=\"click_to_start_scanning\">స్కానింగ్ ప్రారంభించడానికి క్లిక్ చేయండి</string>\n    <string name=\"start_scanning\">స్కానింగ్ ప్రారంభించండి</string>\n    <string name=\"save_as_pdf\">Pdf గా సేవ్ చేయండి</string>\n    <string name=\"share_as_pdf\">Pdfగా షేర్ చేయండి</string>\n    <string name=\"options_below_is_for_images\">దిగువన ఉన్న ఎంపికలు చిత్రాలను సేవ్ చేయడం కోసం, PDF కాదు</string>\n    <string name=\"equalize_histogram_hsv\">హిస్టోగ్రాం HSVని సమం చేయండి</string>\n    <string name=\"equalize_histogram\">హిస్టోగ్రాంను సమం చేయండి</string>\n    <string name=\"enter_percentage\">శాతాన్ని నమోదు చేయండి</string>\n    <string name=\"allow_enter_by_text_field\">టెక్స్ట్ ఫీల్డ్ ద్వారా నమోదు చేయడానికి అనుమతించండి</string>\n    <string name=\"allow_enter_by_text_field_sub\">ప్రీసెట్‌ల ఎంపిక వెనుక ఉన్న టెక్స్ట్ ఫీల్డ్‌ను ఎనేబుల్ చేస్తుంది, వాటిని ఫ్లైలో నమోదు చేయండి</string>\n    <string name=\"scale_color_space\">స్కేల్ కలర్ స్పేస్</string>\n    <string name=\"linear\">లీనియర్</string>\n    <string name=\"equalize_histogram_pixelation\">హిస్టోగ్రాం పిక్సెలేషన్‌ను సమం చేయండి</string>\n    <string name=\"grid_size_x\">గ్రిడ్ పరిమాణం X</string>\n    <string name=\"grid_size_y\">గ్రిడ్ పరిమాణం Y</string>\n    <string name=\"equalize_histogram_adaptive\">హిస్టోగ్రాం అడాప్టివ్‌ను సమం చేయండి</string>\n    <string name=\"equalize_histogram_adaptive_luv\">హిస్టోగ్రాం అడాప్టివ్ LUVని సమం చేయండి</string>\n    <string name=\"equalize_histogram_adaptive_lab\">హిస్టోగ్రాం అడాప్టివ్ LABని సమం చేయండి</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE ల్యాబ్</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">కంటెంట్‌కి కత్తిరించండి</string>\n    <string name=\"frame_color\">ఫ్రేమ్ రంగు</string>\n    <string name=\"color_to_ignore\">విస్మరించాల్సిన రంగు</string>\n    <string name=\"template\">మూస</string>\n    <string name=\"no_template_filters\">టెంప్లేట్ ఫిల్టర్‌లు జోడించబడలేదు</string>\n    <string name=\"create_new\">క్రొత్తదాన్ని సృష్టించండి</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">స్కాన్ చేయబడిన QR కోడ్ చెల్లుబాటు అయ్యే ఫిల్టర్ టెంప్లేట్ కాదు</string>\n    <string name=\"scan_qr_code\">QR కోడ్‌ని స్కాన్ చేయండి</string>\n    <string name=\"opened_file_have_no_filter_template\">ఎంచుకున్న ఫైల్‌లో ఫిల్టర్ టెంప్లేట్ డేటా లేదు</string>\n    <string name=\"create_template\">టెంప్లేట్ సృష్టించండి</string>\n    <string name=\"template_name\">టెంప్లేట్ పేరు</string>\n    <string name=\"select_template_preview\">ఈ ఫిల్టర్ టెంప్లేట్‌ని ప్రివ్యూ చేయడానికి ఈ చిత్రం ఉపయోగించబడుతుంది</string>\n    <string name=\"template_filter\">టెంప్లేట్ ఫిల్టర్</string>\n    <string name=\"as_qr_code\">QR కోడ్ చిత్రం వలె</string>\n    <string name=\"as_file\">ఫైల్‌గా</string>\n    <string name=\"save_as_file\">ఫైల్‌గా సేవ్ చేయండి</string>\n    <string name=\"save_as_qr_code_image\">QR కోడ్ ఇమేజ్‌గా సేవ్ చేయండి</string>\n    <string name=\"delete_template\">టెంప్లేట్‌ను తొలగించండి</string>\n    <string name=\"delete_template_warn\">మీరు ఎంచుకున్న టెంప్లేట్ ఫిల్టర్‌ను తొలగించబోతున్నారు. ఈ ఆపరేషన్ రద్దు చేయబడదు</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) పేరుతో ఫిల్టర్ టెంప్లేట్ జోడించబడింది</string>\n    <string name=\"filter_preview\">ఫిల్టర్ ప్రివ్యూ</string>\n    <string name=\"qr_code\">QR &amp;amp; బార్‌కోడ్</string>\n    <string name=\"qr_code_sub\">QR కోడ్‌ని స్కాన్ చేయండి మరియు దాని కంటెంట్‌ను పొందండి లేదా కొత్తదాన్ని రూపొందించడానికి మీ స్ట్రింగ్‌ను అతికించండి</string>\n    <string name=\"code_content\">కోడ్ కంటెంట్</string>\n    <string name=\"scan_qr_code_to_replace_content\">ఫీల్డ్‌లోని కంటెంట్‌ని భర్తీ చేయడానికి ఏదైనా బార్‌కోడ్‌ని స్కాన్ చేయండి లేదా ఎంచుకున్న రకంతో కొత్త బార్‌కోడ్‌ను రూపొందించడానికి ఏదైనా టైప్ చేయండి</string>\n    <string name=\"qr_description\">QR వివరణ</string>\n    <string name=\"min\">కనిష్ట</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR కోడ్‌ని స్కాన్ చేయడానికి సెట్టింగ్‌లలో కెమెరా అనుమతిని మంజూరు చేయండి</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">డాక్యుమెంట్ స్కానర్‌ని స్కాన్ చేయడానికి సెట్టింగ్‌లలో కెమెరా అనుమతిని మంజూరు చేయండి</string>\n    <string name=\"cubic\">క్యూబిక్</string>\n    <string name=\"bspline\">బి-స్ప్లైన్</string>\n    <string name=\"hamming\">హామింగ్</string>\n    <string name=\"hanning\">హన్నింగ్</string>\n    <string name=\"blackman\">నల్ల మనిషి</string>\n    <string name=\"welch\">వెల్చ్</string>\n    <string name=\"quadric\">చతుర్భుజం</string>\n    <string name=\"gaussian\">గాస్సియన్</string>\n    <string name=\"sphinx\">సింహిక</string>\n    <string name=\"bartlett\">బార్ట్లెట్</string>\n    <string name=\"robidoux\">రాబిడౌక్స్</string>\n    <string name=\"robidoux_sharp\">రాబిడౌక్స్ షార్ప్</string>\n    <string name=\"spline16\">స్ప్లైన్ 16</string>\n    <string name=\"spline36\">స్ప్లైన్ 36</string>\n    <string name=\"spline64\">స్ప్లైన్ 64</string>\n    <string name=\"kaiser\">కైజర్</string>\n    <string name=\"bartlett_hann\">బార్ట్లెట్-అతను</string>\n    <string name=\"box\">పెట్టె</string>\n    <string name=\"bohman\">బోహ్మన్</string>\n    <string name=\"lanczos2\">లాంజోస్ 2</string>\n    <string name=\"lanczos3\">లాంజోస్ 3</string>\n    <string name=\"lanczos4\">లాంజోస్ 4</string>\n    <string name=\"lanczos2_jinc\">లాంజోస్ 2 జింక్</string>\n    <string name=\"lanczos3_jinc\">లాంజోస్ 3 జింక్</string>\n    <string name=\"lanczos4_jinc\">లాంజోస్ 4 జింక్</string>\n    <string name=\"cubic_sub\">క్యూబిక్ ఇంటర్‌పోలేషన్ దగ్గరి 16 పిక్సెల్‌లను పరిగణనలోకి తీసుకోవడం ద్వారా సున్నితమైన స్కేలింగ్‌ను అందిస్తుంది, ఇది బిలినియర్ కంటే మెరుగైన ఫలితాలను ఇస్తుంది</string>\n    <string name=\"bspline_sub\">వక్రరేఖ లేదా ఉపరితలం, అనువైన మరియు నిరంతర ఆకార ప్రాతినిధ్యాన్ని సజావుగా ఇంటర్‌పోలేట్ చేయడానికి మరియు అంచనా వేయడానికి పీస్‌వైస్-డిఫైన్డ్ బహుపది ఫంక్షన్‌లను ఉపయోగిస్తుంది</string>\n    <string name=\"hamming_sub\">సిగ్నల్ ప్రాసెసింగ్‌లో ఉపయోగపడే సిగ్నల్ అంచులను తగ్గించడం ద్వారా స్పెక్ట్రల్ లీకేజీని తగ్గించడానికి ఉపయోగించే విండో ఫంక్షన్</string>\n    <string name=\"hanning_sub\">సిగ్నల్ ప్రాసెసింగ్ అప్లికేషన్‌లలో స్పెక్ట్రల్ లీకేజీని తగ్గించడానికి సాధారణంగా ఉపయోగించే హాన్ విండో యొక్క వేరియంట్</string>\n    <string name=\"blackman_sub\">సిగ్నల్ ప్రాసెసింగ్‌లో తరచుగా ఉపయోగించే స్పెక్ట్రల్ లీకేజీని తగ్గించడం ద్వారా మంచి ఫ్రీక్వెన్సీ రిజల్యూషన్‌ను అందించే విండో ఫంక్షన్</string>\n    <string name=\"welch_sub\">తగ్గిన స్పెక్ట్రల్ లీకేజీతో మంచి ఫ్రీక్వెన్సీ రిజల్యూషన్‌ని అందించడానికి రూపొందించబడిన విండో ఫంక్షన్, తరచుగా సిగ్నల్ ప్రాసెసింగ్ అప్లికేషన్‌లలో ఉపయోగించబడుతుంది</string>\n    <string name=\"quadric_sub\">ఇంటర్‌పోలేషన్ కోసం క్వాడ్రాటిక్ ఫంక్షన్‌ను ఉపయోగించే ఒక పద్ధతి, మృదువైన మరియు నిరంతర ఫలితాలను అందిస్తుంది</string>\n    <string name=\"gaussian_sub\">గాస్సియన్ ఫంక్షన్‌ను వర్తింపజేసే ఇంటర్‌పోలేషన్ పద్ధతి, చిత్రాలలో శబ్దాన్ని సున్నితంగా మరియు తగ్గించడానికి ఉపయోగపడుతుంది</string>\n    <string name=\"sphinx_sub\">కనిష్ట కళాఖండాలతో అధిక-నాణ్యత ఇంటర్‌పోలేషన్‌ను అందించే అధునాతన రీసాంప్లింగ్ పద్ధతి</string>\n    <string name=\"bartlett_sub\">స్పెక్ట్రల్ లీకేజీని తగ్గించడానికి సిగ్నల్ ప్రాసెసింగ్‌లో ఉపయోగించే త్రిభుజాకార విండో ఫంక్షన్</string>\n    <string name=\"robidoux_sub\">సహజమైన ఇమేజ్ రీసైజింగ్, బ్యాలెన్సింగ్ షార్ప్‌నెస్ మరియు స్మూత్‌నెస్ కోసం ఆప్టిమైజ్ చేయబడిన అధిక-నాణ్యత ఇంటర్‌పోలేషన్ పద్ధతి</string>\n    <string name=\"robidoux_sharp_sub\">Robidoux పద్ధతి యొక్క పదునైన రూపాంతరం, స్ఫుటమైన చిత్రం పునఃపరిమాణం కోసం ఆప్టిమైజ్ చేయబడింది</string>\n    <string name=\"spline16_sub\">16-ట్యాప్ ఫిల్టర్‌ని ఉపయోగించి సున్నితమైన ఫలితాలను అందించే స్ప్లైన్-ఆధారిత ఇంటర్‌పోలేషన్ పద్ధతి</string>\n    <string name=\"spline36_sub\">36-ట్యాప్ ఫిల్టర్‌ని ఉపయోగించి సున్నితమైన ఫలితాలను అందించే స్ప్లైన్-ఆధారిత ఇంటర్‌పోలేషన్ పద్ధతి</string>\n    <string name=\"spline64_sub\">64-ట్యాప్ ఫిల్టర్‌ని ఉపయోగించి సున్నితమైన ఫలితాలను అందించే స్ప్లైన్-ఆధారిత ఇంటర్‌పోలేషన్ పద్ధతి</string>\n    <string name=\"kaiser_sub\">కైజర్ విండోను ఉపయోగించే ఇంటర్‌పోలేషన్ పద్ధతి, మెయిన్-లోబ్ వెడల్పు మరియు సైడ్-లోబ్ స్థాయి మధ్య ట్రేడ్-ఆఫ్‌పై మంచి నియంత్రణను అందిస్తుంది</string>\n    <string name=\"bartlett_hann_sub\">సిగ్నల్ ప్రాసెసింగ్‌లో స్పెక్ట్రల్ లీకేజీని తగ్గించడానికి ఉపయోగించే బార్ట్‌లెట్ మరియు హాన్ విండోలను కలిపి ఒక హైబ్రిడ్ విండో ఫంక్షన్</string>\n    <string name=\"box_sub\">సమీప పిక్సెల్ విలువల సగటును ఉపయోగించే సరళమైన రీసాంప్లింగ్ పద్ధతి, తరచుగా అడ్డంకిగా కనిపించేలా చేస్తుంది</string>\n    <string name=\"bohman_sub\">సిగ్నల్ ప్రాసెసింగ్ అప్లికేషన్‌లలో మంచి ఫ్రీక్వెన్సీ రిజల్యూషన్‌ని అందించడానికి స్పెక్ట్రల్ లీకేజీని తగ్గించడానికి ఉపయోగించే విండో ఫంక్షన్</string>\n    <string name=\"lanczos2_sub\">కనిష్ట కళాఖండాలతో అధిక-నాణ్యత ఇంటర్‌పోలేషన్ కోసం 2-లోబ్ లాంజోస్ ఫిల్టర్‌ని ఉపయోగించే రీసాంప్లింగ్ పద్ధతి</string>\n    <string name=\"lanczos3_sub\">కనిష్ట కళాఖండాలతో అధిక-నాణ్యత ఇంటర్‌పోలేషన్ కోసం 3-లోబ్ లాంక్జోస్ ఫిల్టర్‌ని ఉపయోగించే రీసాంప్లింగ్ పద్ధతి</string>\n    <string name=\"lanczos4_sub\">కనిష్ట కళాఖండాలతో అధిక-నాణ్యత ఇంటర్‌పోలేషన్ కోసం 4-లోబ్ లాంక్జోస్ ఫిల్టర్‌ని ఉపయోగించే రీసాంప్లింగ్ పద్ధతి</string>\n    <string name=\"lanczos2_jinc_sub\">జింక్ ఫంక్షన్‌ను ఉపయోగించే Lanczos 2 ఫిల్టర్ యొక్క రూపాంతరం, తక్కువ కళాఖండాలతో అధిక-నాణ్యత ఇంటర్‌పోలేషన్‌ను అందిస్తుంది</string>\n    <string name=\"lanczos3_jinc_sub\">జింక్ ఫంక్షన్‌ను ఉపయోగించే Lanczos 3 ఫిల్టర్ యొక్క రూపాంతరం, తక్కువ కళాఖండాలతో అధిక-నాణ్యత ఇంటర్‌పోలేషన్‌ను అందిస్తుంది</string>\n    <string name=\"lanczos4_jinc_sub\">జింక్ ఫంక్షన్‌ను ఉపయోగించే Lanczos 4 ఫిల్టర్ యొక్క వేరియంట్, కనిష్ట కళాఖండాలతో అధిక-నాణ్యత ఇంటర్‌పోలేషన్‌ను అందిస్తుంది</string>\n    <string name=\"ewa_hanning\">హన్నింగ్ EWA</string>\n    <string name=\"ewa_hanning_sub\">మృదువైన ఇంటర్‌పోలేషన్ మరియు రీసాంప్లింగ్ కోసం హన్నింగ్ ఫిల్టర్ యొక్క ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్</string>\n    <string name=\"ewa_robidoux\">రాబిడౌక్స్ EWA</string>\n    <string name=\"ewa_robidoux_sub\">అధిక నాణ్యత రీసాంప్లింగ్ కోసం Robidoux ఫిల్టర్ యొక్క ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్</string>\n    <string name=\"ewa_blackman\">బ్లాక్‌మ్యాన్ EVE</string>\n    <string name=\"ewa_blackman_sub\">రింగింగ్ కళాఖండాలను తగ్గించడానికి బ్లాక్‌మ్యాన్ ఫిల్టర్ యొక్క ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్</string>\n    <string name=\"ewa_quadric\">క్వాడ్రిక్ EWA</string>\n    <string name=\"ewa_quadric_sub\">మృదువైన ఇంటర్‌పోలేషన్ కోసం క్వాడ్రిక్ ఫిల్టర్ యొక్క ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux షార్ప్ EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">పదునైన ఫలితాల కోసం రాబిడౌక్స్ షార్ప్ ఫిల్టర్ యొక్క ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్</string>\n    <string name=\"ewa_lanczos3_jinc\">లాంజోస్ 3 జింక్ EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్ లాంక్జోస్ 3 జింక్ ఫిల్టర్ తగ్గిన మారుపేరుతో అధిక-నాణ్యత రీసాంప్లింగ్ కోసం</string>\n    <string name=\"ginseng\">జిన్సెంగ్</string>\n    <string name=\"ginseng_sub\">పదును మరియు సున్నితత్వం యొక్క మంచి బ్యాలెన్స్‌తో అధిక-నాణ్యత ఇమేజ్ ప్రాసెసింగ్ కోసం రూపొందించబడిన రీసాంప్లింగ్ ఫిల్టర్</string>\n    <string name=\"ewa_ginseng\">జిన్సెంగ్ EWA</string>\n    <string name=\"ewa_ginseng_sub\">మెరుగైన చిత్ర నాణ్యత కోసం జిన్‌సెంగ్ ఫిల్టర్ యొక్క ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్</string>\n    <string name=\"ewa_lanczos_sharp\">లాంజోస్ షార్ప్ EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్ లాంక్జోస్ షార్ప్ ఫిల్టర్ కనిష్ట కళాఖండాలతో పదునైన ఫలితాలను సాధించడం కోసం</string>\n    <string name=\"ewa_lanczos_4_sharpest\">లాంజోస్ 4 షార్పెస్ట్ EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్ లాంక్జోస్ 4 షార్పెస్ట్ ఫిల్టర్ చాలా షార్ప్ ఇమేజ్ రీసాంప్లింగ్ కోసం</string>\n    <string name=\"ewa_lanczos_soft\">లాంజోస్ సాఫ్ట్ EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">సున్నితమైన ఇమేజ్ రీసాంప్లింగ్ కోసం లాంక్జోస్ సాఫ్ట్ ఫిల్టర్ యొక్క ఎలిప్టికల్ వెయిటెడ్ యావరేజ్ (EWA) వేరియంట్</string>\n    <string name=\"haasn_soft\">హాసన్ సాఫ్ట్</string>\n    <string name=\"haasn_soft_sub\">స్మూత్ మరియు ఆర్టిఫాక్ట్-ఫ్రీ ఇమేజ్ స్కేలింగ్ కోసం హాస్న్ రూపొందించిన రీసాంప్లింగ్ ఫిల్టర్</string>\n    <string name=\"format_conversion\">ఫార్మాట్ మార్పిడి</string>\n    <string name=\"format_conversion_sub\">చిత్రాల బ్యాచ్‌ను ఒక ఫార్మాట్ నుండి మరొక ఫార్మాట్‌కి మార్చండి</string>\n    <string name=\"dismiss_forever\">ఎప్పటికీ తీసివేయండి</string>\n    <string name=\"image_stacking\">చిత్రం స్టాకింగ్</string>\n    <string name=\"image_stacking_sub\">ఎంచుకున్న బ్లెండ్ మోడ్‌లతో చిత్రాలను ఒకదానిపై ఒకటి పేర్చండి</string>\n    <string name=\"add_image\">చిత్రాన్ని జోడించండి</string>\n    <string name=\"bins_count\">డబ్బాలు లెక్కించబడతాయి</string>\n    <string name=\"clahe_hsl\">క్లాహే HSL</string>\n    <string name=\"clahe_hsv\">క్లాహే HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">హిస్టోగ్రాం అడాప్టివ్ HSLని సమం చేయండి</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">హిస్టోగ్రాం అడాప్టివ్ HSVని సమం చేయండి</string>\n    <string name=\"edge_mode\">ఎడ్జ్ మోడ్</string>\n    <string name=\"clip\">క్లిప్</string>\n    <string name=\"wrap\">చుట్టు</string>\n    <string name=\"color_blind_scheme\">వర్ణాంధత్వం</string>\n    <string name=\"color_blind_scheme_sub\">ఎంచుకున్న రంగు అంధత్వం వేరియంట్ కోసం థీమ్ రంగులను స్వీకరించడానికి మోడ్‌ను ఎంచుకోండి</string>\n    <string name=\"protanomaly_sub\">ఎరుపు మరియు ఆకుపచ్చ రంగుల మధ్య తేడాను గుర్తించడంలో ఇబ్బంది</string>\n    <string name=\"deuteranomaly_sub\">ఆకుపచ్చ మరియు ఎరుపు రంగుల మధ్య తేడాను గుర్తించడంలో ఇబ్బంది</string>\n    <string name=\"tritanomaly_sub\">నీలం మరియు పసుపు రంగుల మధ్య తేడాను గుర్తించడంలో ఇబ్బంది</string>\n    <string name=\"protanopia_sub\">ఎరుపు రంగులను గ్రహించలేకపోవడం</string>\n    <string name=\"deuteranopia_sub\">ఆకుపచ్చ రంగులను గ్రహించలేకపోవడం</string>\n    <string name=\"tritanopia_sub\">నీలం రంగులను గ్రహించలేకపోవడం</string>\n    <string name=\"achromatomaly_sub\">అన్ని రంగులకు తగ్గిన సున్నితత్వం</string>\n    <string name=\"achromatopsia_sub\">పూర్తి వర్ణాంధత్వం, బూడిద రంగు షేడ్స్ మాత్రమే చూడటం</string>\n    <string name=\"not_use_color_blind_scheme\">కలర్ బ్లైండ్ స్కీమ్‌ని ఉపయోగించవద్దు</string>\n    <string name=\"not_use_color_blind_scheme_sub\">రంగులు థీమ్‌లో సెట్ చేసిన విధంగానే ఉంటాయి</string>\n    <string name=\"sigmoidal\">సిగ్మోయిడల్</string>\n    <string name=\"lagrange_2\">లాగ్రాంజ్ 2</string>\n    <string name=\"lagrange_2_sub\">ఆర్డర్ 2 యొక్క లాగ్రాంజ్ ఇంటర్‌పోలేషన్ ఫిల్టర్, సున్నితమైన పరివర్తనతో అధిక-నాణ్యత ఇమేజ్ స్కేలింగ్‌కు అనుకూలం</string>\n    <string name=\"lagrange_3\">లాగ్రాంజ్ 3</string>\n    <string name=\"lagrange_3_sub\">ఆర్డర్ 3 యొక్క లాగ్రాంజ్ ఇంటర్‌పోలేషన్ ఫిల్టర్, ఇమేజ్ స్కేలింగ్ కోసం మెరుగైన ఖచ్చితత్వం మరియు సున్నితమైన ఫలితాలను అందిస్తుంది</string>\n    <string name=\"lanczos_6\">లాంజోస్ 6</string>\n    <string name=\"lanczos_6_sub\">6 అధిక ఆర్డర్‌తో లాంజోస్ రీసాంప్లింగ్ ఫిల్టర్, పదునైన మరియు మరింత ఖచ్చితమైన ఇమేజ్ స్కేలింగ్‌ను అందిస్తుంది</string>\n    <string name=\"lanczos_6_jinc\">లాంజోస్ 6 జింక్</string>\n    <string name=\"lanczos_6_jinc_sub\">మెరుగైన ఇమేజ్ రీసాంప్లింగ్ నాణ్యత కోసం జింక్ ఫంక్షన్‌ని ఉపయోగించి Lanczos 6 ఫిల్టర్ యొక్క వేరియంట్</string>\n    <string name=\"linear_box_blur\">లీనియర్ బాక్స్ బ్లర్</string>\n    <string name=\"linear_tent_blur\">లీనియర్ టెంట్ బ్లర్</string>\n    <string name=\"linear_gaussian_box_blur\">లీనియర్ గాస్సియన్ బాక్స్ బ్లర్</string>\n    <string name=\"linear_stack_blur\">లీనియర్ స్టాక్ బ్లర్</string>\n    <string name=\"gaussian_box_blur\">గాస్సియన్ బాక్స్ బ్లర్</string>\n    <string name=\"linear_fast_gaussian_blur_next\">లీనియర్ ఫాస్ట్ గాస్సియన్ బ్లర్ తదుపరి</string>\n    <string name=\"linear_fast_gaussian_blur\">లీనియర్ ఫాస్ట్ గాస్సియన్ బ్లర్</string>\n    <string name=\"linear_gaussian_blur\">లీనియర్ గాస్సియన్ బ్లర్</string>\n    <string name=\"draw_filter_sub\">పెయింట్‌గా ఉపయోగించడానికి ఒక ఫిల్టర్‌ని ఎంచుకోండి</string>\n    <string name=\"replace_filter\">ఫిల్టర్‌ని భర్తీ చేయండి</string>\n    <string name=\"pick_filter_info\">మీ డ్రాయింగ్‌లో బ్రష్‌గా ఉపయోగించడానికి దిగువ ఫిల్టర్‌ని ఎంచుకోండి</string>\n    <string name=\"tiff_compression_scheme\">TIFF కుదింపు పథకం</string>\n    <string name=\"low_poly\">తక్కువ పాలీ</string>\n    <string name=\"sand_painting\">ఇసుక పెయింటింగ్</string>\n    <string name=\"image_splitting\">చిత్రం విభజన</string>\n    <string name=\"image_splitting_sub\">ఒకే చిత్రాన్ని అడ్డు వరుసలు లేదా నిలువు వరుసల వారీగా విభజించండి</string>\n    <string name=\"fit_to_bounds\">హద్దులకు సరిపోతాయి</string>\n    <string name=\"fit_to_bounds_sub\">కావలసిన ప్రవర్తనను సాధించడానికి ఈ పరామితితో క్రాప్ రీసైజ్ మోడ్‌ను కలపండి (క్రాప్/ఫిట్ టు యాస్పెక్ట్ రేషియో)</string>\n    <string name=\"languages_imported\">భాషలు విజయవంతంగా దిగుమతి అయ్యాయి</string>\n    <string name=\"backup_ocr_models\">OCR మోడల్‌లను బ్యాకప్ చేయండి</string>\n    <string name=\"import_word\">దిగుమతి</string>\n    <string name=\"export\">ఎగుమతి చేయండి</string>\n    <string name=\"position\">స్థానం</string>\n    <string name=\"center\">కేంద్రం</string>\n    <string name=\"top_left\">ఎగువ ఎడమ</string>\n    <string name=\"top_right\">ఎగువ కుడి</string>\n    <string name=\"bottom_left\">దిగువ ఎడమ</string>\n    <string name=\"bottom_right\">దిగువ కుడి</string>\n    <string name=\"top_center\">టాప్ సెంటర్</string>\n    <string name=\"center_right\">కుడి మధ్యలో</string>\n    <string name=\"bottom_center\">దిగువ కేంద్రం</string>\n    <string name=\"center_left\">ఎడమవైపు మధ్యలో</string>\n    <string name=\"target_image\">లక్ష్య చిత్రం</string>\n    <string name=\"palette_transfer\">పాలెట్ బదిలీ</string>\n    <string name=\"enhanced_oil\">మెరుగైన నూనె</string>\n    <string name=\"simple_old_tv\">సాధారణ పాత టీవీ</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">గోతం</string>\n    <string name=\"simple_sketch\">సాధారణ స్కెచ్</string>\n    <string name=\"soft_glow\">సాఫ్ట్ గ్లో</string>\n    <string name=\"color_poster\">రంగు పోస్టర్</string>\n    <string name=\"tri_tone\">ట్రై టోన్</string>\n    <string name=\"third_color\">మూడవ రంగు</string>\n    <string name=\"clahe_oklab\">క్లాహే ఓక్లాబ్</string>\n    <string name=\"clahe_oklch\">క్లారా ఓల్క్స్</string>\n    <string name=\"clahe_jzazbz\">క్లాహే జ్జాజ్బ్జ్</string>\n    <string name=\"polka_dot\">పోల్కా డాట్</string>\n    <string name=\"clustered_2x2_dithering\">క్లస్టర్డ్ 2x2 డైథరింగ్</string>\n    <string name=\"clustered_4x4_dithering\">క్లస్టర్డ్ 4x4 డైథరింగ్</string>\n    <string name=\"clustered_8x8_dithering\">క్లస్టర్డ్ 8x8 డైథరింగ్</string>\n    <string name=\"yililoma_dithering\">యిలిలోమా డిథరింగ్</string>\n    <string name=\"no_favorite_options_selected\">ఇష్టమైన ఎంపికలు ఏవీ ఎంచుకోబడలేదు, వాటిని సాధనాల పేజీలో జోడించండి</string>\n    <string name=\"add_favorites\">ఇష్టమైనవి జోడించండి</string>\n    <string name=\"harmony_complementary\">కాంప్లిమెంటరీ</string>\n    <string name=\"harmony_analogous\">సారూప్యమైనది</string>\n    <string name=\"harmony_triadic\">త్రయోదశి</string>\n    <string name=\"harmony_split_complementary\">స్ప్లిట్ కాంప్లిమెంటరీ</string>\n    <string name=\"harmony_tetradic\">టెట్రాడిక్</string>\n    <string name=\"harmony_square\">చతురస్రం</string>\n    <string name=\"harmony_analogous_complementary\">సాదృశ్యం + కాంప్లిమెంటరీ</string>\n    <string name=\"color_tools\">రంగు సాధనాలు</string>\n    <string name=\"color_tools_sub\">కలపండి, టోన్‌లను తయారు చేయండి, షేడ్స్‌ని రూపొందించండి మరియు మరిన్ని చేయండి</string>\n    <string name=\"color_harmonies\">రంగు సామరస్యాలు</string>\n    <string name=\"color_shading\">రంగు షేడింగ్</string>\n    <string name=\"variation\">వైవిధ్యం</string>\n    <string name=\"tints\">టింట్స్</string>\n    <string name=\"tones\">టోన్లు</string>\n    <string name=\"shades\">షేడ్స్</string>\n    <string name=\"color_mixing\">కలర్ మిక్సింగ్</string>\n    <string name=\"color_info\">రంగు సమాచారం</string>\n    <string name=\"selected_color\">ఎంచుకున్న రంగు</string>\n    <string name=\"color_to_mix\">కలపడానికి రంగు</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">డైనమిక్ రంగులు ఆన్‌లో ఉన్నప్పుడు మోనెట్‌ని ఉపయోగించలేరు</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">లక్ష్యం LUT చిత్రం</string>\n    <string name=\"amatorka\">ఒక ఔత్సాహిక</string>\n    <string name=\"miss_etikate\">మిస్ మర్యాదలు</string>\n    <string name=\"soft_elegance\">సాఫ్ట్ గాంభీర్యం</string>\n    <string name=\"soft_elegance_variant\">సాఫ్ట్ గాంభీర్యం వేరియంట్</string>\n    <string name=\"palette_transfer_variant\">పాలెట్ బదిలీ వేరియంట్</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">టార్గెట్ 3D LUT ఫైల్ (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">బ్లీచ్ బైపాస్</string>\n    <string name=\"candlelight\">కొవ్వొత్తి వెలుగు</string>\n    <string name=\"drop_blues\">డ్రాప్ బ్లూస్</string>\n    <string name=\"edgy_amber\">ఎడ్జీ అంబర్</string>\n    <string name=\"fall_colors\">పతనం రంగులు</string>\n    <string name=\"film_stock_50\">ఫిల్మ్ స్టాక్ 50</string>\n    <string name=\"foggy_night\">పొగమంచు రాత్రి</string>\n    <string name=\"kodak\">కొడాక్</string>\n    <string name=\"save_empty_lut\">తటస్థ LUT చిత్రాన్ని పొందండి</string>\n    <string name=\"save_empty_lut_sub\">ముందుగా, మీరు ఇక్కడ పొందగలిగే తటస్థ LUTకి ఫిల్టర్‌ని వర్తింపజేయడానికి మీకు ఇష్టమైన ఫోటో ఎడిటింగ్ అప్లికేషన్‌ను ఉపయోగించండి. ఇది సరిగ్గా పని చేయడానికి ప్రతి పిక్సెల్ రంగు ఇతర పిక్సెల్‌లపై ఆధారపడకూడదు (ఉదా. బ్లర్ పని చేయదు). సిద్ధమైన తర్వాత, 512*512 LUT ఫిల్టర్ కోసం మీ కొత్త LUT చిత్రాన్ని ఇన్‌పుట్‌గా ఉపయోగించండి</string>\n    <string name=\"pop_art\">పాప్ ఆర్ట్</string>\n    <string name=\"celluloid\">సెల్యులాయిడ్</string>\n    <string name=\"coffee\">కాఫీ</string>\n    <string name=\"golden_forest\">గోల్డెన్ ఫారెస్ట్</string>\n    <string name=\"greenish\">పచ్చటి</string>\n    <string name=\"retro_yellow\">రెట్రో పసుపు</string>\n    <string name=\"links_preview\">లింక్‌ల ప్రివ్యూ</string>\n    <string name=\"links_preview_sub\">మీరు టెక్స్ట్ (QRCode, OCR మొదలైనవి) పొందగలిగే ప్రదేశాలలో లింక్ ప్రివ్యూను తిరిగి పొందడాన్ని ప్రారంభిస్తుంది</string>\n    <string name=\"links\">లింకులు</string>\n    <string name=\"ico_size_warning\">ICO ఫైల్‌లు గరిష్టంగా 256 x 256 పరిమాణంలో మాత్రమే సేవ్ చేయబడతాయి</string>\n    <string name=\"gif_type_to_webp\">GIF నుండి WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">GIF చిత్రాలను WEBP యానిమేటెడ్ చిత్రాలుగా మార్చండి</string>\n    <string name=\"webp_tools\">WEBP సాధనాలు</string>\n    <string name=\"webp_tools_sub\">చిత్రాలను WEBP యానిమేటెడ్ చిత్రానికి మార్చండి లేదా ఇచ్చిన WEBP యానిమేషన్ నుండి ఫ్రేమ్‌లను సంగ్రహించండి</string>\n    <string name=\"webp_type_to_image\">చిత్రాలకు WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP ఫైల్‌ను చిత్రాల బ్యాచ్‌గా మార్చండి</string>\n    <string name=\"webp_type_to_webp_sub\">చిత్రాల బ్యాచ్‌ని WEBP ఫైల్‌గా మార్చండి</string>\n    <string name=\"webp_type_to_webp\">WEBPకి చిత్రాలు</string>\n    <string name=\"select_webp_image_to_start\">ప్రారంభించడానికి WEBP చిత్రాన్ని ఎంచుకోండి</string>\n    <string name=\"manage_storage_extra_types\">ఫైల్‌లకు పూర్తి యాక్సెస్ లేదు</string>\n    <string name=\"manage_storage_extra_types_sub\">Androidలో చిత్రాలుగా గుర్తించబడని JXL, QOI మరియు ఇతర చిత్రాలను చూడటానికి అన్ని ఫైల్‌లను యాక్సెస్ చేయడానికి అనుమతించండి. అనుమతి లేకుండా ఇమేజ్ టూల్‌బాక్స్ ఆ చిత్రాలను చూపించదు</string>\n    <string name=\"default_draw_color\">డిఫాల్ట్ డ్రా రంగు</string>\n    <string name=\"default_draw_path_mode\">డిఫాల్ట్ డ్రా పాత్ మోడ్</string>\n    <string name=\"add_timestamp\">టైమ్‌స్టాంప్ జోడించండి</string>\n    <string name=\"add_timestamp_sub\">అవుట్‌పుట్ ఫైల్ పేరుకు టైమ్‌స్టాంప్ జోడించడాన్ని ప్రారంభిస్తుంది</string>\n    <string name=\"formatted_timestamp\">ఫార్మాట్ చేసిన టైమ్‌స్టాంప్</string>\n    <string name=\"formatted_timestamp_sub\">ప్రాథమిక మిల్లీలకు బదులుగా అవుట్‌పుట్ ఫైల్ పేరులో టైమ్‌స్టాంప్ ఫార్మాటింగ్‌ని ప్రారంభించండి</string>\n    <string name=\"enable_timestamps_to_format_them\">టైమ్‌స్టాంప్‌ల ఆకృతిని ఎంచుకోవడానికి వాటిని ప్రారంభించండి</string>\n    <string name=\"one_time_save_location\">వన్ టైమ్ సేవ్ లొకేషన్</string>\n    <string name=\"one_time_save_location_sub\">చాలా వరకు అన్ని ఎంపికలలో సేవ్ బటన్‌ను ఎక్కువసేపు నొక్కడం ద్వారా మీరు ఉపయోగించగల వన్ టైమ్ సేవ్ స్థానాలను వీక్షించండి మరియు సవరించండి</string>\n    <string name=\"recently_used\">ఇటీవల ఉపయోగించబడింది</string>\n    <string name=\"ci_channel\">CI ఛానల్</string>\n    <string name=\"group\">సమూహం</string>\n    <string name=\"image_toolbox_in_telegram\">టెలిగ్రామ్‌లో ఇమేజ్ టూల్‌బాక్స్ 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">మా చాట్‌లో చేరండి, ఇక్కడ మీరు మీకు కావలసిన ఏదైనా చర్చించవచ్చు మరియు నేను బీటాలు మరియు ప్రకటనలను పోస్ట్ చేసే CI ఛానెల్‌ని కూడా చూడండి</string>\n    <string name=\"ci_channel_sub\">యాప్ యొక్క కొత్త వెర్షన్‌ల గురించి నోటిఫికేషన్ పొందండి మరియు ప్రకటనలను చదవండి</string>\n    <string name=\"fit_description\">ఇచ్చిన కొలతలకు చిత్రాన్ని అమర్చండి మరియు నేపథ్యానికి బ్లర్ లేదా రంగును వర్తింపజేయండి</string>\n    <string name=\"tools_arrangement\">సాధనాల అమరిక</string>\n    <string name=\"group_tools_by_type\">రకం ద్వారా సమూహ సాధనాలు</string>\n    <string name=\"group_tools_by_type_sub\">కస్టమ్ జాబితా అమరికకు బదులుగా వాటి రకాన్ని బట్టి ప్రధాన స్క్రీన్‌పై సమూహ సాధనాలు</string>\n    <string name=\"default_values\">డిఫాల్ట్ విలువలు</string>\n    <string name=\"system_bars_visibility\">సిస్టమ్ బార్‌ల దృశ్యమానత</string>\n    <string name=\"show_system_bars_by_swipe\">స్వైప్ ద్వారా సిస్టమ్ బార్‌లను చూపించు</string>\n    <string name=\"show_system_bars_by_swipe_sub\">సిస్టమ్ బార్‌లు దాచబడి ఉంటే వాటిని చూపడానికి స్వైపింగ్‌ని ప్రారంభిస్తుంది</string>\n    <string name=\"auto\">ఆటో</string>\n    <string name=\"hide_all\">అన్నీ దాచు</string>\n    <string name=\"show_all\">అన్నీ చూపించు</string>\n    <string name=\"hide_nav_bar\">నవ్ బార్‌ను దాచండి</string>\n    <string name=\"hide_status_bar\">స్థితి పట్టీని దాచండి</string>\n    <string name=\"noise_generation\">నాయిస్ జనరేషన్</string>\n    <string name=\"noise_generation_sub\">పెర్లిన్ లేదా ఇతర రకాల వంటి విభిన్న శబ్దాలను రూపొందించండి</string>\n    <string name=\"frequency\">ఫ్రీక్వెన్సీ</string>\n    <string name=\"noise_type\">శబ్దం రకం</string>\n    <string name=\"rotation_type\">భ్రమణ రకం</string>\n    <string name=\"fractal_type\">ఫ్రాక్టల్ రకం</string>\n    <string name=\"octaves\">అష్టపదులు</string>\n    <string name=\"lacunarity\">లాకునారిటీ</string>\n    <string name=\"gain\">లాభం</string>\n    <string name=\"weighted_strength\">వెయిటెడ్ స్ట్రెంత్</string>\n    <string name=\"ping_pong_strength\">పింగ్ పాంగ్ బలం</string>\n    <string name=\"distance_function\">దూరం ఫంక్షన్</string>\n    <string name=\"return_type\">రిటర్న్ రకం</string>\n    <string name=\"jitter\">జిట్టర్</string>\n    <string name=\"domain_warp\">డొమైన్ వార్ప్</string>\n    <string name=\"alignment\">అమరిక</string>\n    <string name=\"custom_filename\">అనుకూల ఫైల్ పేరు</string>\n    <string name=\"custom_filename_sub\">ప్రస్తుత చిత్రాన్ని సేవ్ చేయడానికి ఉపయోగించే స్థానం మరియు ఫైల్ పేరును ఎంచుకోండి</string>\n    <string name=\"saved_to_custom\">అనుకూల పేరుతో ఫోల్డర్‌లో సేవ్ చేయబడింది</string>\n    <string name=\"collage_maker\">కోల్లెజ్ మేకర్</string>\n    <string name=\"collage_maker_sub\">గరిష్టంగా 20 చిత్రాల నుండి దృశ్య రూపకల్పనలను రూపొందించండి</string>\n    <string name=\"collage_type\">కోల్లెజ్ రకం</string>\n    <string name=\"collages_info\">స్థానాన్ని సర్దుబాటు చేయడానికి స్వాప్ చేయడానికి, తరలించడానికి మరియు జూమ్ చేయడానికి చిత్రాన్ని పట్టుకోండి</string>\n    <string name=\"disable_rotation\">భ్రమణాన్ని నిలిపివేయండి</string>\n    <string name=\"disable_rotation_sub\">రెండు వేళ్ల సంజ్ఞలతో చిత్రాలను తిప్పడాన్ని నిరోధిస్తుంది</string>\n    <string name=\"enable_snapping_to_borders\">సరిహద్దులకు స్నాపింగ్ చేయడాన్ని ప్రారంభించండి</string>\n    <string name=\"enable_snapping_to_borders_sub\">తరలించిన లేదా జూమ్ చేసిన తర్వాత, ఫ్రేమ్ అంచులను పూరించడానికి చిత్రాలు స్నాప్ అవుతాయి</string>\n    <string name=\"histogram\">హిస్టోగ్రాం</string>\n    <string name=\"histogram_sub\">మీకు సర్దుబాట్లు చేయడంలో సహాయపడటానికి RGB లేదా బ్రైట్‌నెస్ ఇమేజ్ హిస్టోగ్రాం</string>\n    <string name=\"image_for_histogram\">ఈ చిత్రం RGB మరియు బ్రైట్‌నెస్ హిస్టోగ్రామ్‌లను రూపొందించడానికి ఉపయోగించబడుతుంది</string>\n    <string name=\"tesseract_options\">టెసెరాక్ట్ ఎంపికలు</string>\n    <string name=\"tesseract_options_sub\">టెస్రాక్ట్ ఇంజిన్ కోసం కొన్ని ఇన్‌పుట్ వేరియబుల్స్‌ని వర్తింపజేయండి</string>\n    <string name=\"custom_options\">అనుకూల ఎంపికలు</string>\n    <string name=\"custom_params_info\">ఈ నమూనాను అనుసరించి ఎంపికలు నమోదు చేయాలి: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">ఆటో క్రాప్</string>\n    <string name=\"free_corners\">ఉచిత మూలలు</string>\n    <string name=\"free_corners_sub\">బహుభుజి ద్వారా చిత్రాన్ని కత్తిరించండి, ఇది దృక్కోణాన్ని కూడా సరిచేస్తుంది</string>\n    <string name=\"coerce_points_to_image_bounds\">చిత్ర సరిహద్దులకు బలవంతపు పాయింట్లు</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">పాయింట్లు ఇమేజ్ హద్దుల ద్వారా పరిమితం చేయబడవు, ఇది మరింత ఖచ్చితమైన దృక్పథం సరిదిద్దడానికి ఉపయోగపడుతుంది</string>\n    <string name=\"mask\">ముసుగు</string>\n    <string name=\"spot_heal_sub\">గీయబడిన మార్గం క్రింద కంటెంట్ అవగాహన నింపండి</string>\n    <string name=\"spot_heal\">హీల్ స్పాట్</string>\n    <string name=\"use_circle_kernel\">సర్కిల్ కెర్నల్ ఉపయోగించండి</string>\n    <string name=\"opening\">తెరవడం</string>\n    <string name=\"closing\">మూసివేయడం</string>\n    <string name=\"morphological_gradient\">పదనిర్మాణ ప్రవణత</string>\n    <string name=\"top_hat\">టాప్ టోపీ</string>\n    <string name=\"black_hat\">నల్ల టోపీ</string>\n    <string name=\"tone_curves\">టోన్ వక్రతలు</string>\n    <string name=\"reset_curves\">వక్రతలను రీసెట్ చేయండి</string>\n    <string name=\"reset_curves_sub\">వక్రతలు డిఫాల్ట్ విలువకు తిరిగి మార్చబడతాయి</string>\n    <string name=\"line_style\">లైన్ శైలి</string>\n    <string name=\"gap_size\">గ్యాప్ పరిమాణం</string>\n    <string name=\"dashed\">డాష్ చేయబడింది</string>\n    <string name=\"dot_dashed\">డాట్ డాష్ చేయబడింది</string>\n    <string name=\"stamped\">స్టాంప్ చేయబడింది</string>\n    <string name=\"zigzag\">జిగ్జాగ్</string>\n    <string name=\"dashed_sub\">పేర్కొన్న గ్యాప్ పరిమాణంతో గీసిన మార్గంలో డాష్ చేసిన గీతను గీస్తుంది</string>\n    <string name=\"dot_dashed_sub\">ఇచ్చిన మార్గంలో చుక్క మరియు చుక్కల గీతను గీస్తుంది</string>\n    <string name=\"defaultt_sub\">కేవలం డిఫాల్ట్ సరళ రేఖలు</string>\n    <string name=\"stamped_sub\">పేర్కొన్న అంతరంతో మార్గంలో ఎంచుకున్న ఆకృతులను గీస్తుంది</string>\n    <string name=\"zigzag_sub\">మార్గం వెంట ఉంగరాల జిగ్‌జాగ్‌ని గీస్తుంది</string>\n    <string name=\"zigzag_ratio\">జిగ్‌జాగ్ నిష్పత్తి</string>\n    <string name=\"create_shortcut\">సత్వరమార్గాన్ని సృష్టించండి</string>\n    <string name=\"create_shortcut_title\">పిన్ చేయడానికి సాధనాన్ని ఎంచుకోండి</string>\n    <string name=\"create_shortcut_subtitle\">సాధనం మీ లాంచర్ హోమ్ స్క్రీన్‌కు సత్వరమార్గంగా జోడించబడుతుంది, అవసరమైన ప్రవర్తనను సాధించడానికి \\\"ఫైల్ పికింగ్‌ను దాటవేయి\\\" సెట్టింగ్‌తో కలపడం ద్వారా దీన్ని ఉపయోగించండి</string>\n    <string name=\"dont_stack_frames\">ఫ్రేమ్‌లను పేర్చవద్దు</string>\n    <string name=\"dont_stack_frames_sub\">మునుపటి ఫ్రేమ్‌లను పారవేయడాన్ని ప్రారంభిస్తుంది, కాబట్టి అవి ఒకదానికొకటి పేర్చబడవు</string>\n    <string name=\"crossfade\">క్రాస్‌ఫేడ్</string>\n    <string name=\"crossfade_sub\">ఫ్రేమ్‌లు ఒకదానికొకటి క్రాస్‌ఫేడ్ చేయబడతాయి</string>\n    <string name=\"crossfade_count\">క్రాస్‌ఫేడ్ ఫ్రేమ్‌లు లెక్కించబడతాయి</string>\n    <string name=\"threshold_one\">థ్రెషోల్డ్ ఒకటి</string>\n    <string name=\"threshold_two\">థ్రెషోల్డ్ రెండు</string>\n    <string name=\"canny\">కానీ</string>\n    <string name=\"mirror_101\">అద్దం 101</string>\n    <string name=\"enhanced_zoom_blur\">మెరుగైన జూమ్ బ్లర్</string>\n    <string name=\"laplacian_simple\">లాప్లాసియన్ సింపుల్</string>\n    <string name=\"sobel_simple\">సోబెల్ సింపుల్</string>\n    <string name=\"helper_grid\">సహాయక గ్రిడ్</string>\n    <string name=\"helper_grid_sub\">ఖచ్చితమైన అవకతవకలతో సహాయం చేయడానికి డ్రాయింగ్ ఏరియా పైన సపోర్టింగ్ గ్రిడ్‌ని చూపుతుంది</string>\n    <string name=\"grid_color\">గ్రిడ్ రంగు</string>\n    <string name=\"cell_width\">సెల్ వెడల్పు</string>\n    <string name=\"cell_height\">సెల్ ఎత్తు</string>\n    <string name=\"compact_selectors\">కాంపాక్ట్ సెలెక్టర్లు</string>\n    <string name=\"compact_selectors_sub\">కొన్ని ఎంపిక నియంత్రణలు తక్కువ స్థలాన్ని తీసుకోవడానికి కాంపాక్ట్ లేఅవుట్‌ని ఉపయోగిస్తాయి</string>\n    <string name=\"grant_camera_permission_to_capture_image\">చిత్రాన్ని క్యాప్చర్ చేయడానికి సెట్టింగ్‌లలో కెమెరా అనుమతిని మంజూరు చేయండి</string>\n    <string name=\"layout\">లేఅవుట్</string>\n    <string name=\"main_screen_title\">ప్రధాన స్క్రీన్ శీర్షిక</string>\n    <string name=\"constant_rate_factor\">స్థిరమైన రేటు కారకం (CRF)</string>\n    <string name=\"crf_sub\">%1$s విలువ అంటే స్లో కంప్రెషన్, ఫలితంగా ఫైల్ పరిమాణం చాలా తక్కువగా ఉంటుంది. %2$s అంటే వేగవంతమైన కుదింపు, ఫలితంగా పెద్ద ఫైల్ ఏర్పడుతుంది.</string>\n    <string name=\"lut_library\">లట్ లైబ్రరీ</string>\n    <string name=\"lut_library_sub\">LUTల సేకరణను డౌన్‌లోడ్ చేయండి, మీరు డౌన్‌లోడ్ చేసిన తర్వాత దరఖాస్తు చేసుకోవచ్చు</string>\n    <string name=\"lut_library_update_sub\">LUTల సేకరణను నవీకరించండి (కొత్తవి మాత్రమే క్యూలో ఉంచబడతాయి), వీటిని డౌన్‌లోడ్ చేసిన తర్వాత మీరు దరఖాస్తు చేసుకోవచ్చు</string>\n    <string name=\"filter_preview_image_sub\">ఫిల్టర్‌ల కోసం డిఫాల్ట్ ఇమేజ్ ప్రివ్యూని మార్చండి</string>\n    <string name=\"filter_preview_image\">ప్రివ్యూ చిత్రం</string>\n    <string name=\"hide\">దాచు</string>\n    <string name=\"show\">చూపించు</string>\n    <string name=\"slider_type\">స్లైడర్ రకం</string>\n    <string name=\"fancy\">ఫ్యాన్సీ</string>\n    <string name=\"material_2\">పదార్థం 2</string>\n    <string name=\"fancy_sub\">ఫాన్సీగా కనిపించే స్లయిడర్. ఇది డిఫాల్ట్ ఎంపిక</string>\n    <string name=\"material_2_sub\">మెటీరియల్ 2 స్లయిడర్</string>\n    <string name=\"material_you_slider_sub\">ఒక మెటీరియల్ మీరు స్లయిడర్</string>\n    <string name=\"apply\">దరఖాస్తు చేసుకోండి</string>\n    <string name=\"center_align_dialog_buttons\">మధ్య డైలాగ్ బటన్లు</string>\n    <string name=\"center_align_dialog_buttons_sub\">వీలైతే డైలాగ్‌ల బటన్‌లు ఎడమ వైపుకు బదులుగా మధ్యలో ఉంచబడతాయి</string>\n    <string name=\"open_source_licenses\">ఓపెన్ సోర్స్ లైసెన్స్‌లు</string>\n    <string name=\"open_source_licenses_sub\">ఈ యాప్‌లో ఉపయోగించిన ఓపెన్ సోర్స్ లైబ్రరీల లైసెన్స్‌లను వీక్షించండి</string>\n    <string name=\"area\">ప్రాంతం</string>\n    <string name=\"area_sub\">పిక్సెల్ ఏరియా రిలేషన్ ఉపయోగించి రీసాంప్లింగ్. ఇమేజ్ డెసిమేషన్ కోసం ఇది ప్రాధాన్య పద్ధతి కావచ్చు, ఎందుకంటే ఇది మోయిర్\\'-ఫ్రీ ఫలితాలను ఇస్తుంది. కానీ చిత్రాన్ని జూమ్ చేసినప్పుడు, అది \\\"సమీప\\\" పద్ధతిని పోలి ఉంటుంది.</string>\n    <string name=\"enable_tonemapping\">టోన్‌మ్యాపింగ్‌ని ప్రారంభించండి</string>\n    <string name=\"enter_percent\">% నమోదు చేయండి</string>\n    <string name=\"unknown_host\">సైట్‌ను యాక్సెస్ చేయడం సాధ్యపడదు, VPNని ఉపయోగించి ప్రయత్నించండి లేదా url సరైనదేనా అని తనిఖీ చేయండి</string>\n    <string name=\"markup_layers\">మార్కప్ పొరలు</string>\n    <string name=\"markup_layers_sub\">చిత్రాలు, వచనం మరియు మరిన్నింటిని ఉచితంగా ఉంచగల సామర్థ్యంతో లేయర్‌ల మోడ్</string>\n    <string name=\"edit_layer\">లేయర్‌ని సవరించండి</string>\n    <string name=\"layers_on_image\">చిత్రంపై పొరలు</string>\n    <string name=\"layers_on_image_sub\">చిత్రాన్ని నేపథ్యంగా ఉపయోగించండి మరియు దాని పైన వివిధ లేయర్‌లను జోడించండి</string>\n    <string name=\"layers_on_background\">నేపథ్యంలో పొరలు</string>\n    <string name=\"layers_on_background_sub\">మొదటి ఎంపిక వలె ఉంటుంది కానీ చిత్రానికి బదులుగా రంగుతో ఉంటుంది</string>\n    <string name=\"beta\">బీటా</string>\n    <string name=\"fast_settings_side\">ఫాస్ట్ సెట్టింగుల వైపు</string>\n    <string name=\"fast_settings_side_sub\">ఇమేజ్‌లను ఎడిట్ చేస్తున్నప్పుడు ఎంచుకున్న వైపు ఫ్లోటింగ్ స్ట్రిప్‌ను జోడించండి, ఇది క్లిక్ చేసినప్పుడు ఫాస్ట్ సెట్టింగ్‌లను తెరుస్తుంది</string>\n    <string name=\"clear_selection\">ఎంపికను క్లియర్ చేయండి</string>\n    <string name=\"settings_group_visibility_hidden\">\\\"%1$s\\\" సమూహాన్ని సెట్ చేయడం డిఫాల్ట్‌గా కుదించబడుతుంది</string>\n    <string name=\"settings_group_visibility_visible\">\\\"%1$s\\\" సమూహాన్ని సెట్ చేయడం డిఫాల్ట్‌గా విస్తరించబడుతుంది</string>\n    <string name=\"base_64_tools\">Base64 సాధనాలు</string>\n    <string name=\"base_64_tools_sub\">Base64 స్ట్రింగ్‌ని ఇమేజ్‌కి డీకోడ్ చేయండి లేదా ఇమేజ్‌ని Base64 ఫార్మాట్‌కి ఎన్‌కోడ్ చేయండి</string>\n    <string name=\"base_64\">బేస్64</string>\n    <string name=\"not_a_valid_base_64\">అందించిన విలువ చెల్లుబాటు అయ్యే Base64 స్ట్రింగ్ కాదు</string>\n    <string name=\"copy_not_a_valid_base_64\">ఖాళీ లేదా చెల్లని Base64 స్ట్రింగ్‌ను కాపీ చేయడం సాధ్యపడదు</string>\n    <string name=\"paste_base_64\">బేస్ 64ని అతికించండి</string>\n    <string name=\"copy_base_64\">కాపీ బేస్ 64</string>\n    <string name=\"base_64_tips\">Base64 స్ట్రింగ్‌ను కాపీ చేయడానికి లేదా సేవ్ చేయడానికి చిత్రాన్ని లోడ్ చేయండి. మీరు స్ట్రింగ్‌ను కలిగి ఉన్నట్లయితే, చిత్రాన్ని పొందేందుకు మీరు దానిని పైన అతికించవచ్చు</string>\n    <string name=\"save_base_64\">బేస్ 64ని సేవ్ చేయండి</string>\n    <string name=\"share_base_64\">Share Base64</string>\n    <string name=\"options\">ఎంపికలు</string>\n    <string name=\"actions\">చర్యలు</string>\n    <string name=\"import_base_64\">దిగుమతి బేస్64</string>\n    <string name=\"base_64_actions\">బేస్ 64 చర్యలు</string>\n    <string name=\"add_outline\">అవుట్‌లైన్ జోడించండి</string>\n    <string name=\"add_outline_sub\">పేర్కొన్న రంగు మరియు వెడల్పుతో టెక్స్ట్ చుట్టూ అవుట్‌లైన్ జోడించండి</string>\n    <string name=\"outline_color\">అవుట్‌లైన్ రంగు</string>\n    <string name=\"outline_size\">అవుట్‌లైన్ పరిమాణం</string>\n    <string name=\"rotation\">భ్రమణం</string>\n    <string name=\"checksum_as_filename\">ఫైల్ పేరుగా చెక్సమ్</string>\n    <string name=\"checksum_as_filename_sub\">అవుట్‌పుట్ ఇమేజ్‌లు వాటి డేటా చెక్‌సమ్‌కు అనుగుణమైన పేరును కలిగి ఉంటాయి</string>\n    <string name=\"free_software_partner\">ఉచిత సాఫ్ట్‌వేర్ (భాగస్వామి)</string>\n    <string name=\"free_software_partner_sub\">Android అప్లికేషన్ల భాగస్వామి ఛానెల్‌లో మరింత ఉపయోగకరమైన సాఫ్ట్‌వేర్</string>\n    <string name=\"algorithms\">అల్గోరిథం</string>\n    <string name=\"checksum_tools\">చెక్సమ్ సాధనాలు</string>\n    <string name=\"checksum_tools_sub\">చెక్‌సమ్‌లను సరిపోల్చండి, హ్యాష్‌లను లెక్కించండి లేదా విభిన్న హ్యాషింగ్ అల్గారిథమ్‌లను ఉపయోగించి ఫైల్‌ల నుండి హెక్స్ స్ట్రింగ్‌లను సృష్టించండి</string>\n    <string name=\"calculate\">లెక్కించు</string>\n    <string name=\"text_hash\">టెక్స్ట్ హాష్</string>\n    <string name=\"checksum\">చెక్సమ్</string>\n    <string name=\"pick_file_to_checksum\">ఎంచుకున్న అల్గోరిథం ఆధారంగా దాని చెక్‌సమ్‌ను లెక్కించడానికి ఫైల్‌ను ఎంచుకోండి</string>\n    <string name=\"enter_text_to_checksum\">ఎంచుకున్న అల్గోరిథం ఆధారంగా దాని చెక్‌సమ్‌ను లెక్కించడానికి టెక్స్ట్‌ని నమోదు చేయండి</string>\n    <string name=\"source_checksum\">మూలం చెక్సమ్</string>\n    <string name=\"checksum_to_compare\">సరిపోల్చడానికి చెక్‌సమ్</string>\n    <string name=\"match\">మ్యాచ్!</string>\n    <string name=\"difference\">తేడా</string>\n    <string name=\"match_sub\">చెక్‌సమ్‌లు సమానంగా ఉంటాయి, ఇది సురక్షితంగా ఉంటుంది</string>\n    <string name=\"difference_sub\">చెక్‌సమ్‌లు సమానంగా ఉండవు, ఫైల్ సురక్షితం కాదు!</string>\n    <string name=\"mesh_gradients\">మెష్ గ్రేడియంట్స్</string>\n    <string name=\"collection_mesh_gradients_sub\">మెష్ గ్రేడియంట్స్ యొక్క ఆన్‌లైన్ సేకరణను చూడండి</string>\n    <string name=\"wrong_font\">TTF మరియు OTF ఫాంట్‌లను మాత్రమే దిగుమతి చేసుకోవచ్చు</string>\n    <string name=\"import_font\">ఫాంట్‌ను దిగుమతి చేయండి (TTF/OTF)</string>\n    <string name=\"export_fonts\">ఫాంట్‌లను ఎగుమతి చేయండి</string>\n    <string name=\"imported_fonts\">దిగుమతి చేసుకున్న ఫాంట్‌లు</string>\n    <string name=\"error_while_saving\">ప్రయత్నాన్ని సేవ్ చేస్తున్నప్పుడు లోపం, అవుట్‌పుట్ ఫోల్డర్‌ని మార్చడానికి ప్రయత్నించండి</string>\n    <string name=\"filename_is_not_set\">ఫైల్ పేరు సెట్ చేయబడలేదు</string>\n    <string name=\"none\">ఏదీ లేదు</string>\n    <string name=\"custom_pages\">అనుకూల పేజీలు</string>\n    <string name=\"pages_selection\">పేజీల ఎంపిక</string>\n    <string name=\"tool_exit_confirmation\">సాధనం నిష్క్రమణ నిర్ధారణ</string>\n    <string name=\"tool_exit_confirmation_sub\">మీరు నిర్దిష్ట సాధనాలను ఉపయోగిస్తున్నప్పుడు సేవ్ చేయని మార్పులను కలిగి ఉంటే మరియు దాన్ని మూసివేయడానికి ప్రయత్నిస్తే, కన్ఫర్మ్ డైలాగ్ చూపబడుతుంది</string>\n    <string name=\"edit_exif_screen\">EXIFని సవరించండి</string>\n    <string name=\"edit_exif_screen_sub\">రీకంప్రెషన్ లేకుండా ఒకే చిత్రం యొక్క మెటాడేటాను మార్చండి</string>\n    <string name=\"edit_exif_tag\">అందుబాటులో ఉన్న ట్యాగ్‌లను సవరించడానికి నొక్కండి</string>\n    <string name=\"change_sticker\">స్టిక్కర్‌ని మార్చండి</string>\n    <string name=\"fit_width\">ఫిట్ వెడల్పు</string>\n    <string name=\"fit_height\">ఫిట్ ఎత్తు</string>\n    <string name=\"batch_compare\">బ్యాచ్ సరిపోల్చండి</string>\n    <string name=\"pick_files_to_checksum\">ఎంచుకున్న అల్గోరిథం ఆధారంగా దాని చెక్‌సమ్‌ను లెక్కించడానికి ఫైల్/ఫైల్‌లను ఎంచుకోండి</string>\n    <string name=\"pick_files\">ఫైళ్లను ఎంచుకోండి</string>\n    <string name=\"pick_directory\">డైరెక్టరీని ఎంచుకోండి</string>\n    <string name=\"head_length_scale\">తల పొడవు స్కేల్</string>\n    <string name=\"stamp\">స్టాంప్</string>\n    <string name=\"timestamp\">సమయముద్ర</string>\n    <string name=\"format_pattern\">ఆకృతి నమూనా</string>\n    <string name=\"padding\">పాడింగ్</string>\n    <string name=\"image_cutting\">చిత్రం కట్టింగ్</string>\n    <string name=\"image_cutting_sub\">చిత్రం భాగాన్ని కత్తిరించండి మరియు నిలువు లేదా క్షితిజ సమాంతర రేఖల ద్వారా ఎడమ వాటిని (విలోమంగా ఉండవచ్చు) విలీనం చేయండి</string>\n    <string name=\"vertical_pivot_line\">నిలువు పివోట్ లైన్</string>\n    <string name=\"horizontal_pivot_line\">క్షితిజసమాంతర పివోట్ లైన్</string>\n    <string name=\"inverse_selection\">విలోమ ఎంపిక</string>\n    <string name=\"inverse_vertical_selection_sub\">కత్తిరించిన ప్రాంతం చుట్టూ భాగాలను విలీనం చేయడానికి బదులుగా నిలువుగా కత్తిరించిన భాగం వదిలివేయబడుతుంది</string>\n    <string name=\"inverse_horizontal_selection_sub\">కత్తిరించిన ప్రాంతం చుట్టూ భాగాలను విలీనం చేయడానికి బదులుగా క్షితిజసమాంతర కట్ భాగం వదిలివేయబడుతుంది</string>\n    <string name=\"collection_mesh_gradients\">మెష్ గ్రేడియంట్స్ యొక్క సేకరణ</string>\n    <string name=\"mesh_gradients_sub\">కస్టమ్ మొత్తం నాట్లు మరియు రిజల్యూషన్‌తో మెష్ గ్రేడియంట్‌ని సృష్టించండి</string>\n    <string name=\"gradient_maker_type_image_mesh\">మెష్ గ్రేడియంట్ ఓవర్‌లే</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">ఇచ్చిన చిత్రాల పైభాగంలో మెష్ గ్రేడియంట్‌ని కంపోజ్ చేయండి</string>\n    <string name=\"points_customization\">పాయింట్ల అనుకూలీకరణ</string>\n    <string name=\"grid_size\">గ్రిడ్ పరిమాణం</string>\n    <string name=\"resolution_x\">రిజల్యూషన్ X</string>\n    <string name=\"resolution_y\">రిజల్యూషన్ Y</string>\n    <string name=\"resolution\">రిజల్యూషన్</string>\n    <string name=\"pixel_by_pixel\">పిక్సెల్ ద్వారా పిక్సెల్</string>\n    <string name=\"highlight_color\">హైలైట్ రంగు</string>\n    <string name=\"pixel_comparison_type\">పిక్సెల్ పోలిక రకం</string>\n    <string name=\"scan_barcode\">బార్‌కోడ్‌ని స్కాన్ చేయండి</string>\n    <string name=\"height_ratio\">ఎత్తు నిష్పత్తి</string>\n    <string name=\"barcode_type\">బార్‌కోడ్ రకం</string>\n    <string name=\"enforce_bw\">B/W అమలు చేయండి</string>\n    <string name=\"enforce_bw_sub\">బార్‌కోడ్ చిత్రం పూర్తిగా నలుపు మరియు తెలుపు రంగులో ఉంటుంది మరియు యాప్ యొక్క థీమ్ ద్వారా రంగు వేయబడదు</string>\n    <string name=\"barcodes_sub\">ఏదైనా బార్‌కోడ్‌ని (QR, EAN, AZTEC, …) స్కాన్ చేయండి మరియు దాని కంటెంట్‌ను పొందండి లేదా కొత్తదాన్ని రూపొందించడానికి మీ వచనాన్ని అతికించండి</string>\n    <string name=\"no_barcode_found\">బార్‌కోడ్ కనుగొనబడలేదు</string>\n    <string name=\"generated_barcode_will_be_here\">రూపొందించిన బార్‌కోడ్ ఇక్కడ ఉంటుంది</string>\n    <string name=\"audio_cover_extractor\">ఆడియో కవర్లు</string>\n    <string name=\"audio_cover_extractor_sub\">ఆడియో ఫైల్‌ల నుండి ఆల్బమ్ కవర్ చిత్రాలను సంగ్రహించండి, అత్యంత సాధారణ ఫార్మాట్‌లకు మద్దతు ఉంది</string>\n    <string name=\"pick_audio_to_start\">ప్రారంభించడానికి ఆడియోను ఎంచుకోండి</string>\n    <string name=\"pick_audio\">ఆడియోను ఎంచుకోండి</string>\n    <string name=\"no_covers_found\">కవర్లు ఏవీ కనుగొనబడలేదు</string>\n    <string name=\"send_logs\">లాగ్లను పంపండి</string>\n    <string name=\"send_logs_sub\">యాప్ లాగ్‌ల ఫైల్‌ను షేర్ చేయడానికి క్లిక్ చేయండి, ఇది సమస్యను గుర్తించడంలో మరియు సమస్యలను పరిష్కరించడంలో నాకు సహాయపడుతుంది</string>\n    <string name=\"crash_title\">అయ్యో… ఏదో తప్పు జరిగింది</string>\n    <string name=\"crash_subtitle\">దిగువ ఎంపికలను ఉపయోగించి మీరు నన్ను సంప్రదించవచ్చు మరియు నేను పరిష్కారాన్ని కనుగొనడానికి ప్రయత్నిస్తాను.\\n(లాగ్‌లను జోడించడం మర్చిపోవద్దు)</string>\n    <string name=\"ocr_write_to_file\">ఫైల్‌కి వ్రాయండి</string>\n    <string name=\"ocr_write_to_file_sub\">చిత్రాల బ్యాచ్ నుండి వచనాన్ని సంగ్రహించి, దానిని ఒక టెక్స్ట్ ఫైల్‌లో నిల్వ చేయండి</string>\n    <string name=\"ocr_write_to_metadata\">మెటాడేటాకు వ్రాయండి</string>\n    <string name=\"ocr_write_to_metadata_sub\">ప్రతి చిత్రం నుండి వచనాన్ని సంగ్రహించి, సంబంధిత ఫోటోల EXIF ​​సమాచారంలో ఉంచండి</string>\n    <string name=\"invisible_mode\">అదృశ్య మోడ్</string>\n    <string name=\"invisible_mode_sub\">మీ చిత్రాల బైట్‌ల లోపల కంటికి కనిపించని వాటర్‌మార్క్‌లను సృష్టించడానికి స్టెగానోగ్రఫీని ఉపయోగించండి</string>\n    <string name=\"use_lsb\">LSBని ఉపయోగించండి</string>\n    <string name=\"use_lsb_sub\">LSB (తక్కువ ముఖ్యమైన బిట్) స్టెగానోగ్రఫీ పద్ధతి ఉపయోగించబడుతుంది, లేకపోతే FD (ఫ్రీక్వెన్సీ డొమైన్)</string>\n    <string name=\"auto_remove_red_eyes\">రెడ్ ఐస్ ను ఆటో రిమూవ్ చేయండి</string>\n    <string name=\"password\">పాస్వర్డ్</string>\n    <string name=\"unlock\">అన్‌లాక్ చేయండి</string>\n    <string name=\"pdf_is_protected\">PDF రక్షించబడింది</string>\n    <string name=\"operation_almost_complete\">ఆపరేషన్ దాదాపు పూర్తయింది. ఇప్పుడు రద్దు చేయడం వలన దానిని పునఃప్రారంభించవలసి ఉంటుంది</string>\n    <string name=\"sort_by_date_modified\">తేదీ సవరించబడింది</string>\n    <string name=\"sort_by_date_modified_reversed\">తేదీ సవరించబడింది (రివర్స్ చేయబడింది)</string>\n    <string name=\"sort_by_size\">పరిమాణం</string>\n    <string name=\"sort_by_size_reversed\">పరిమాణం (రివర్స్డ్)</string>\n    <string name=\"sort_by_mime_type\">MIME రకం</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME రకం (రివర్స్డ్)</string>\n    <string name=\"sort_by_extension\">పొడిగింపు</string>\n    <string name=\"sort_by_extension_reversed\">పొడిగింపు (రివర్స్డ్)</string>\n    <string name=\"sort_by_date_added\">తేదీ జోడించబడింది</string>\n    <string name=\"sort_by_date_added_reversed\">తేదీ జోడించబడింది (రివర్స్ చేయబడింది)</string>\n    <string name=\"left_to_right\">ఎడమ నుండి కుడికి</string>\n    <string name=\"right_to_left\">కుడి నుండి ఎడమ</string>\n    <string name=\"top_to_bottom\">ఎగువ నుండి దిగువ వరకు</string>\n    <string name=\"bottom_to_top\">దిగువ నుండి పైకి</string>\n    <string name=\"liquid_glass\">లిక్విడ్ గ్లాస్</string>\n    <string name=\"liquid_glass_sub\">ఇటీవల ప్రకటించిన IOS 26 మరియు దాని లిక్విడ్ గ్లాస్ డిజైన్ సిస్టమ్ ఆధారంగా ఒక స్విచ్</string>\n    <string name=\"pick_image_or_base64\">చిత్రాన్ని ఎంచుకోండి లేదా దిగువన Base64 డేటాను అతికించండి/దిగుమతి చేయండి</string>\n    <string name=\"type_image_link\">ప్రారంభించడానికి చిత్రం లింక్‌ని టైప్ చేయండి</string>\n    <string name=\"paste_link\">లింక్‌ని అతికించండి</string>\n    <string name=\"kaleidoscope\">కాలిడోస్కోప్</string>\n    <string name=\"secondary_angle\">ద్వితీయ కోణం</string>\n    <string name=\"sides\">వైపులా</string>\n    <string name=\"channel_mix\">ఛానెల్ మిక్స్</string>\n    <string name=\"blue_green\">నీలం ఆకుపచ్చ</string>\n    <string name=\"red_blue\">ఎరుపు నీలం</string>\n    <string name=\"green_red\">ఆకుపచ్చ ఎరుపు</string>\n    <string name=\"into_red\">ఎరుపు రంగులోకి</string>\n    <string name=\"into_green\">ఆకుపచ్చ రంగులోకి</string>\n    <string name=\"into_blue\">నీలం రంగులోకి</string>\n    <string name=\"cyan\">నీలవర్ణం</string>\n    <string name=\"magenta\">మెజెంటా</string>\n    <string name=\"yellow\">పసుపు</string>\n    <string name=\"color_halftone\">రంగు హాఫ్టోన్</string>\n    <string name=\"contour\">ఆకృతి</string>\n    <string name=\"levels\">స్థాయిలు</string>\n    <string name=\"offset\">ఆఫ్‌సెట్</string>\n    <string name=\"voronoi_crystallize\">వోరోనోయ్ స్ఫటికీకరణ</string>\n    <string name=\"shape\">ఆకారం</string>\n    <string name=\"stretch\">సాగదీయండి</string>\n    <string name=\"randomness\">యాదృచ్ఛికత</string>\n    <string name=\"despeckle\">డెస్పెకిల్</string>\n    <string name=\"diffuse\">ప్రసరించు</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">రెండవ వ్యాసార్థం</string>\n    <string name=\"equalize\">సమానం చేయండి</string>\n    <string name=\"glow\">గ్లో</string>\n    <string name=\"whirl_and_pinch\">గిరగిరా మరియు చిటికెడు</string>\n    <string name=\"pointillize\">సూచించు</string>\n    <string name=\"border_color\">అంచు రంగు</string>\n    <string name=\"polar_coordinates\">పోలార్ కోఆర్డినేట్స్</string>\n    <string name=\"rect_to_polar\">ధ్రువానికి రెక్ట్</string>\n    <string name=\"polar_to_rect\">పోలార్ నుండి రెక్ట్ వరకు</string>\n    <string name=\"invert_in_circle\">వృత్తంలో తిరగండి</string>\n    <string name=\"reduce_noise\">నాయిస్ తగ్గించండి</string>\n    <string name=\"simple_solarize\">సింపుల్ సోలారైజ్</string>\n    <string name=\"weave\">నేత</string>\n    <string name=\"x_gap\">X గ్యాప్</string>\n    <string name=\"y_gap\">Y గ్యాప్</string>\n    <string name=\"x_width\">X వెడల్పు</string>\n    <string name=\"y_wdth\">Y వెడల్పు</string>\n    <string name=\"twirl\">తిరుగుట</string>\n    <string name=\"rubber_stmp\">రబ్బరు స్టాంప్</string>\n    <string name=\"smear\">స్మెర్</string>\n    <string name=\"density\">సాంద్రత</string>\n    <string name=\"mix\">కలపండి</string>\n    <string name=\"sphere_lensh_distortion\">స్పియర్ లెన్స్ వక్రీకరణ</string>\n    <string name=\"refraction_index\">వక్రీభవన సూచిక</string>\n    <string name=\"arc\">ఆర్క్</string>\n    <string name=\"spread_angle\">స్ప్రెడ్ కోణం</string>\n    <string name=\"sparkle\">మెరుపు</string>\n    <string name=\"rays\">కిరణాలు</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">ప్రవణత</string>\n    <string name=\"moire\">మేరీ</string>\n    <string name=\"autumn\">శరదృతువు</string>\n    <string name=\"bone\">ఎముక</string>\n    <string name=\"jet\">జెట్</string>\n    <string name=\"winter\">శీతాకాలం</string>\n    <string name=\"ocean\">మహాసముద్రం</string>\n    <string name=\"summer\">వేసవి</string>\n    <string name=\"spring\">వసంతం</string>\n    <string name=\"cool_variant\">కూల్ వేరియంట్</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">పింక్</string>\n    <string name=\"hot\">వేడి</string>\n    <string name=\"parula\">మాట</string>\n    <string name=\"magma\">శిలాద్రవం</string>\n    <string name=\"inferno\">నరకయాతన</string>\n    <string name=\"plasma\">ప్లాస్మా</string>\n    <string name=\"viridis\">విరిడిస్</string>\n    <string name=\"cividis\">పౌరులు</string>\n    <string name=\"twilight\">ట్విలైట్</string>\n    <string name=\"twilight_shifted\">ట్విలైట్ మారింది</string>\n    <string name=\"auto_perspective\">పెర్స్పెక్టివ్ ఆటో</string>\n    <string name=\"deskew\">డెస్క్యూ</string>\n    <string name=\"allow_crop\">పంటను అనుమతించండి</string>\n    <string name=\"crop_or_perspective\">క్రాప్ లేదా పెర్స్పెక్టివ్</string>\n    <string name=\"absolute\">సంపూర్ణమైన</string>\n    <string name=\"turbo\">టర్బో</string>\n    <string name=\"deep_green\">లోతైన ఆకుపచ్చ</string>\n    <string name=\"lens_correction\">లెన్స్ కరెక్షన్</string>\n    <string name=\"target_lens_profile\">JSON ఫార్మాట్‌లో టార్గెట్ లెన్స్ ప్రొఫైల్ ఫైల్</string>\n    <string name=\"download_ready_lens_profiles\">సిద్ధంగా ఉన్న లెన్స్ ప్రొఫైల్‌లను డౌన్‌లోడ్ చేయండి</string>\n    <string name=\"part_percents\">పార్ట్ శాతాలు</string>\n    <string name=\"export_as_json\">JSONగా ఎగుమతి చేయండి</string>\n    <string name=\"export_as_json_sub\">json ప్రాతినిధ్యంగా పాలెట్ డేటాతో స్ట్రింగ్‌ను కాపీ చేయండి</string>\n    <string name=\"seam_carving\">సీమ్ కార్వింగ్</string>\n    <string name=\"home_screen\">హోమ్ స్క్రీన్</string>\n    <string name=\"lock_screen\">లాక్ స్క్రీన్</string>\n    <string name=\"built_in\">అంతర్నిర్మిత</string>\n    <string name=\"wallpapers_export\">వాల్‌పేపర్‌ల ఎగుమతి</string>\n    <string name=\"refresh\">రిఫ్రెష్ చేయండి</string>\n    <string name=\"wallpapers_export_sub\">ప్రస్తుత హోమ్, లాక్ మరియు అంతర్నిర్మిత వాల్‌పేపర్‌లను పొందండి</string>\n    <string name=\"allow_access_to_all_files_for_wp\">అన్ని ఫైల్‌లకు యాక్సెస్‌ను అనుమతించండి, వాల్‌పేపర్‌లను తిరిగి పొందడానికి ఇది అవసరం</string>\n    <string name=\"allow_read_media_images_for_wp\">బాహ్య నిల్వ అనుమతిని నిర్వహించడం సరిపోదు, మీరు మీ చిత్రాలకు ప్రాప్యతను అనుమతించాలి, \\\"అన్నీ అనుమతించు\\\"ని ఎంచుకున్నారని నిర్ధారించుకోండి</string>\n    <string name=\"add_preset_to_filename\">ఫైల్ పేరుకు ప్రీసెట్ జోడించండి</string>\n    <string name=\"add_preset_to_filename_sub\">ఇమేజ్ ఫైల్ పేరుకు ఎంచుకున్న ప్రీసెట్‌తో ప్రత్యయం జోడిస్తుంది</string>\n    <string name=\"add_image_scale_mode_to_filename\">ఫైల్ పేరుకు ఇమేజ్ స్కేల్ మోడ్‌ను జోడించండి</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">ఇమేజ్ ఫైల్ పేరుకు ఎంచుకున్న ఇమేజ్ స్కేల్ మోడ్‌తో ప్రత్యయాన్ని జోడిస్తుంది</string>\n    <string name=\"ascii_art\">Ascii ఆర్ట్</string>\n    <string name=\"ascii_art_sub\">చిత్రం వలె కనిపించే చిత్రాన్ని ascii టెక్స్ట్‌గా మార్చండి</string>\n    <string name=\"params\">పరములు</string>\n    <string name=\"invert_colors_ascii_sub\">కొన్ని సందర్భాల్లో మెరుగైన ఫలితం కోసం చిత్రానికి ప్రతికూల ఫిల్టర్‌ని వర్తింపజేస్తుంది</string>\n    <string name=\"processing_screenshot\">స్క్రీన్‌షాట్‌ను ప్రాసెస్ చేస్తోంది</string>\n    <string name=\"screenshot_not_captured_try_again\">స్క్రీన్‌షాట్ క్యాప్చర్ చేయబడలేదు, మళ్లీ ప్రయత్నించండి</string>\n    <string name=\"skipped_saving\">సేవ్ చేయడం దాటవేయబడింది</string>\n    <string name=\"skipped_saving_multiple\">%1$s ఫైల్‌లు దాటవేయబడ్డాయి</string>\n    <string name=\"allow_skip_if_larger\">పెద్దది అయితే దాటవేయడాన్ని అనుమతించండి</string>\n    <string name=\"allow_skip_if_larger_sub\">ఫలితంగా ఫైల్ పరిమాణం అసలైన దానికంటే పెద్దదిగా ఉంటే, కొన్ని సాధనాలు చిత్రాలను సేవ్ చేయడాన్ని దాటవేయడానికి అనుమతించబడతాయి</string>\n    <string name=\"qr_type_calendar_event\">క్యాలెండర్ ఈవెంట్</string>\n    <string name=\"qr_type_contact_info\">సంప్రదించండి</string>\n    <string name=\"qr_type_email\">ఇమెయిల్</string>\n    <string name=\"qr_type_geo_point\">స్థానం</string>\n    <string name=\"qr_type_phone\">ఫోన్</string>\n    <string name=\"qr_type_plain\">వచనం</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">నెట్‌వర్క్‌ని తెరవండి</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">ఫోన్</string>\n    <string name=\"message\">సందేశం</string>\n    <string name=\"address\">చిరునామా</string>\n    <string name=\"subject\">విషయం</string>\n    <string name=\"body\">శరీరం</string>\n    <string name=\"name\">పేరు</string>\n    <string name=\"organization\">సంస్థ</string>\n    <string name=\"title\">శీర్షిక</string>\n    <string name=\"phones\">ఫోన్లు</string>\n    <string name=\"emails\">ఇమెయిల్‌లు</string>\n    <string name=\"urls\">URLలు</string>\n    <string name=\"addresses\">చిరునామాలు</string>\n    <string name=\"summary\">సారాంశం</string>\n    <string name=\"description\">వివరణ</string>\n    <string name=\"location\">స్థానం</string>\n    <string name=\"organizer\">ఆర్గనైజర్</string>\n    <string name=\"start_date\">ప్రారంభ తేదీ</string>\n    <string name=\"end_date\">ముగింపు తేదీ</string>\n    <string name=\"status\">స్థితి</string>\n    <string name=\"latitude\">అక్షాంశం</string>\n    <string name=\"longitude\">రేఖాంశం</string>\n    <string name=\"create_barcode\">బార్‌కోడ్‌ని సృష్టించండి</string>\n    <string name=\"edit_barcode\">బార్‌కోడ్‌ని సవరించండి</string>\n    <string name=\"wifi_configuration\">Wi-Fi కాన్ఫిగరేషన్</string>\n    <string name=\"security\">భద్రత</string>\n    <string name=\"pick_contact\">పరిచయాన్ని ఎంచుకోండి</string>\n    <string name=\"grant_contact_permission\">ఎంచుకున్న పరిచయాన్ని ఉపయోగించి ఆటోఫిల్ చేయడానికి సెట్టింగ్‌లలో పరిచయాల అనుమతిని మంజూరు చేయండి</string>\n    <string name=\"contact_info\">సంప్రదింపు సమాచారం</string>\n    <string name=\"first_name\">మొదటి పేరు</string>\n    <string name=\"middle_name\">మధ్య పేరు</string>\n    <string name=\"last_name\">ఇంటిపేరు</string>\n    <string name=\"pronunciation\">ఉచ్చారణ</string>\n    <string name=\"add_phone\">ఫోన్ జోడించండి</string>\n    <string name=\"add_email\">ఇమెయిల్ జోడించండి</string>\n    <string name=\"add_address\">చిరునామాను జోడించండి</string>\n    <string name=\"website\">వెబ్సైట్</string>\n    <string name=\"add_website\">వెబ్‌సైట్‌ని జోడించండి</string>\n    <string name=\"formatted_name\">ఫార్మాట్ చేయబడిన పేరు</string>\n    <string name=\"qr_code_top_image\">బార్‌కోడ్ పైన ఉంచడానికి ఈ చిత్రం ఉపయోగించబడుతుంది</string>\n    <string name=\"code_customization\">కోడ్ అనుకూలీకరణ</string>\n    <string name=\"qr_logo_image\">ఈ చిత్రం QR కోడ్ మధ్యలో లోగోగా ఉపయోగించబడుతుంది</string>\n    <string name=\"logo\">లోగో</string>\n    <string name=\"logo_padding\">లోగో పాడింగ్</string>\n    <string name=\"logo_size\">లోగో పరిమాణం</string>\n    <string name=\"logo_corners\">లోగో మూలలు</string>\n    <string name=\"fourth_eye\">నాల్గవ కన్ను</string>\n    <string name=\"fourth_eye_description\">దిగువ చివర మూలలో నాల్గవ కన్ను జోడించడం ద్వారా qr కోడ్‌కు కంటి సమరూపతను జోడిస్తుంది</string>\n    <string name=\"pixel_shape\">పిక్సెల్ ఆకారం</string>\n    <string name=\"frame_shape\">ఫ్రేమ్ ఆకారం</string>\n    <string name=\"ball_shape\">బంతి ఆకారం</string>\n    <string name=\"error_correction_level\">లోపం దిద్దుబాటు స్థాయి</string>\n    <string name=\"dark_color\">ముదురు రంగు</string>\n    <string name=\"light_color\">లేత రంగు</string>\n    <string name=\"hyper_os\">హైపర్ OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS వంటి శైలి</string>\n    <string name=\"mask_pattern\">ముసుగు నమూనా</string>\n    <string name=\"code_may_be_not_scannable\">ఈ కోడ్ స్కాన్ చేయలేకపోవచ్చు, అన్ని పరికరాలతో చదవగలిగేలా రూపాన్ని మార్చండి</string>\n    <string name=\"not_scannable\">స్కాన్ చేయలేము</string>\n    <string name=\"launcher_mode_sub\">సాధనాలు మరింత కాంపాక్ట్‌గా ఉండటానికి హోమ్ స్క్రీన్ యాప్ లాంచర్ లాగా కనిపిస్తాయి</string>\n    <string name=\"launcher_mode\">లాంచర్ మోడ్</string>\n    <string name=\"flood_fill_sub\">ఎంచుకున్న బ్రష్ మరియు శైలితో ప్రాంతాన్ని నింపుతుంది</string>\n    <string name=\"flood_fill\">ఫ్లడ్ ఫిల్</string>\n    <string name=\"spray\">స్ప్రే</string>\n    <string name=\"spray_sub\">గ్రాఫిటీ శైలి మార్గాన్ని గీస్తుంది</string>\n    <string name=\"square_particles\">స్క్వేర్ పార్టికల్స్</string>\n    <string name=\"square_particles_sub\">స్ప్రే కణాలు సర్కిల్‌లకు బదులుగా చతురస్రాకారంలో ఉంటాయి</string>\n    <string name=\"palette_tools\">పాలెట్ సాధనాలు</string>\n    <string name=\"palette_tools_sub\">చిత్రం నుండి ప్రాథమిక/మెటీరియల్‌ని రూపొందించండి లేదా వివిధ పాలెట్ ఫార్మాట్‌లలో దిగుమతి/ఎగుమతి చేయండి</string>\n    <string name=\"edit_palette\">పాలెట్‌ని సవరించండి</string>\n    <string name=\"edit_palette_sub\">వివిధ ఫార్మాట్లలో ఎగుమతి/దిగుమతి ప్యాలెట్</string>\n    <string name=\"color_name\">రంగు పేరు</string>\n    <string name=\"palette_name\">పాలెట్ పేరు</string>\n    <string name=\"palette_format\">పాలెట్ ఫార్మాట్</string>\n    <string name=\"export_palette_sub\">విభిన్న ఫార్మాట్‌లకు ఉత్పత్తి చేయబడిన పాలెట్‌ను ఎగుమతి చేయండి</string>\n    <string name=\"add_color_palette_sub\">ప్రస్తుత పాలెట్‌కు కొత్త రంగును జోడిస్తుంది</string>\n    <string name=\"palette_name_not_supported\">%1$s ఫార్మాట్ పాలెట్ పేరును అందించడానికి మద్దతు ఇవ్వదు</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store విధానాల కారణంగా, ఈ ఫీచర్ ప్రస్తుత బిల్డ్‌లో చేర్చబడదు. ఈ కార్యాచరణను యాక్సెస్ చేయడానికి, దయచేసి ప్రత్యామ్నాయ మూలం నుండి ImageToolboxని డౌన్‌లోడ్ చేయండి. మీరు దిగువన GitHubలో అందుబాటులో ఉన్న బిల్డ్‌లను కనుగొనవచ్చు.</string>\n    <string name=\"open_github_page\">Github పేజీని తెరవండి</string>\n    <string name=\"overwrite_files_sub_short\">ఎంచుకున్న ఫోల్డర్‌లో సేవ్ చేయడానికి బదులుగా అసలు ఫైల్ కొత్త దానితో భర్తీ చేయబడుతుంది</string>\n    <string name=\"hidden_watermark_text_detected\">దాచిన వాటర్‌మార్క్ వచనం కనుగొనబడింది</string>\n    <string name=\"hidden_watermark_image_detected\">దాచిన వాటర్‌మార్క్ చిత్రం కనుగొనబడింది</string>\n    <string name=\"this_image_was_hidden\">ఈ చిత్రం దాచబడింది</string>\n    <string name=\"generative_inpaint\">జనరేటివ్ పెయింటింగ్</string>\n    <string name=\"generative_inpaint_sub\">OpenCVపై ఆధారపడకుండా, AI మోడల్‌ని ఉపయోగించి ఇమేజ్‌లోని వస్తువులను తీసివేయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఈ ఫీచర్‌ని ఉపయోగించడానికి, యాప్ GitHub నుండి అవసరమైన మోడల్‌ని (~200 MB) డౌన్‌లోడ్ చేస్తుంది</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCVపై ఆధారపడకుండా, AI మోడల్‌ని ఉపయోగించి ఇమేజ్‌లోని వస్తువులను తీసివేయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఇది సుదీర్ఘమైన ఆపరేషన్ కావచ్చు</string>\n    <string name=\"error_level_analysis\">లోపం స్థాయి విశ్లేషణ</string>\n    <string name=\"luminance_gradient\">ప్రకాశం గ్రేడియంట్</string>\n    <string name=\"average_distance\">సగటు దూరం</string>\n    <string name=\"copy_move_detection\">మూవ్ డిటెక్షన్‌ని కాపీ చేయండి</string>\n    <string name=\"retain\">నిలుపుకోండి</string>\n    <string name=\"coefficent\">కోఎఫిసెంట్</string>\n    <string name=\"clipboard_data_is_too_large\">క్లిప్‌బోర్డ్ డేటా చాలా పెద్దది</string>\n    <string name=\"data_is_too_large_to_copy\">కాపీ చేయడానికి డేటా చాలా పెద్దది</string>\n    <string name=\"simple_weave_pixelization\">సాధారణ నేత పిక్సలైజేషన్</string>\n    <string name=\"staggered_pixelization\">అస్థిరమైన పిక్సలైజేషన్</string>\n    <string name=\"cross_pixelization\">క్రాస్ పిక్సలైజేషన్</string>\n    <string name=\"micro_macro_pixelization\">మైక్రో మాక్రో పిక్సలైజేషన్</string>\n    <string name=\"orbital_pixelization\">ఆర్బిటల్ పిక్సలైజేషన్</string>\n    <string name=\"vortex_pixelization\">వోర్టెక్స్ పిక్సలైజేషన్</string>\n    <string name=\"pulse_grid_pixelization\">పల్స్ గ్రిడ్ పిక్సలైజేషన్</string>\n    <string name=\"nucleus_pixelization\">న్యూక్లియస్ పిక్సలైజేషన్</string>\n    <string name=\"radial_weave_pixelization\">రేడియల్ వీవ్ పిక్సలైజేషన్</string>\n    <string name=\"cannot_open_uri\">uri \\\"%1$s\\\"ని తెరవలేరు</string>\n    <string name=\"snowfall_mode\">హిమపాతం మోడ్</string>\n    <string name=\"enabled\">ప్రారంభించబడింది</string>\n    <string name=\"border_frame\">సరిహద్దు ఫ్రేమ్</string>\n    <string name=\"glitch_variant\">గ్లిచ్ వేరియంట్</string>\n    <string name=\"channel_shift\">ఛానెల్ షిఫ్ట్</string>\n    <string name=\"max_offset\">గరిష్ట ఆఫ్‌సెట్</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">బ్లాక్ గ్లిచ్</string>\n    <string name=\"block_size\">బ్లాక్ పరిమాణం</string>\n    <string name=\"crt_curvature\">CRT వక్రత</string>\n    <string name=\"curvature\">వక్రత</string>\n    <string name=\"chroma\">క్రోమా</string>\n    <string name=\"pixel_melt\">పిక్సెల్ మెల్ట్</string>\n    <string name=\"max_drop\">మాక్స్ డ్రాప్</string>\n    <string name=\"ai_tools\">AI సాధనాలు</string>\n    <string name=\"ai_tools_sub\">ఆర్టిఫ్యాక్ట్ రిమూవల్ లేదా డీనోయిజింగ్ వంటి AI మోడల్స్ ద్వారా ఇమేజ్‌లను ప్రాసెస్ చేయడానికి వివిధ సాధనాలు</string>\n    <string name=\"model_anime_undeint\">కుదింపు, బెల్లం పంక్తులు</string>\n    <string name=\"model_broadcast\">కార్టూన్లు, ప్రసార కుదింపు</string>\n    <string name=\"model_rgb_max_denoise_fp16\">సాధారణ కుదింపు, సాధారణ శబ్దం</string>\n    <string name=\"model_wb_denoise\">రంగులేని కార్టూన్ శబ్దం</string>\n    <string name=\"model_span_anime_pretrain\">వేగవంతమైన, సాధారణ కుదింపు, సాధారణ శబ్దం, యానిమేషన్/కామిక్స్/యానిమే</string>\n    <string name=\"model_book_scan\">బుక్ స్కానింగ్</string>\n    <string name=\"model_overexposure\">ఎక్స్పోజర్ దిద్దుబాటు</string>\n    <string name=\"model_fbcnn_color_fp16\">సాధారణ కుదింపు, రంగు చిత్రాలలో ఉత్తమమైనది</string>\n    <string name=\"model_fbcnn_gray_fp16\">సాధారణ కుదింపు, గ్రేస్కేల్ చిత్రాలలో ఉత్తమమైనది</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">సాధారణ కుదింపు, గ్రేస్కేల్ చిత్రాలు, బలమైనవి</string>\n    <string name=\"model_scunet_color_gan_fp16\">సాధారణ శబ్దం, రంగు చిత్రాలు</string>\n    <string name=\"model_scunet_color_psnr_fp16\">సాధారణ శబ్దం, రంగు చిత్రాలు, మెరుగైన వివరాలు</string>\n    <string name=\"model_scunet_gray_15_fp16\">సాధారణ శబ్దం, గ్రేస్కేల్ చిత్రాలు</string>\n    <string name=\"model_scunet_gray_25_fp16\">సాధారణ శబ్దం, గ్రేస్కేల్ చిత్రాలు, బలమైనవి</string>\n    <string name=\"model_scunet_gray_50_fp16\">సాధారణ శబ్దం, గ్రేస్కేల్ చిత్రాలు, బలమైనవి</string>\n    <string name=\"model_jpeg_destroyer\">సాధారణ కుదింపు</string>\n    <string name=\"model_jaywreck\">సాధారణ కుదింపు</string>\n    <string name=\"model_h264\">టెక్స్చరైజేషన్, h264 కుదింపు</string>\n    <string name=\"model_vhs\">VHS కుదింపు</string>\n    <string name=\"model_cinepak\">ప్రామాణికం కాని కుదింపు (సినిపాక్, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">బింక్ కంప్రెషన్, జ్యామితిపై ఉత్తమం</string>\n    <string name=\"model_debink_v5\">బింక్ కంప్రెషన్, బలమైనది</string>\n    <string name=\"model_debink_v6\">బింక్ కంప్రెషన్, మృదువైన, వివరాలను కలిగి ఉంటుంది</string>\n    <string name=\"model_antialias\">మెట్ల-దశ ప్రభావాన్ని తొలగించడం, సున్నితంగా చేయడం</string>\n    <string name=\"model_kdm_scans\">స్కాన్ చేసిన కళ/డ్రాయింగ్‌లు, తేలికపాటి కంప్రెషన్, మోయిర్</string>\n    <string name=\"model_bandage\">రంగు బ్యాండింగ్</string>\n    <string name=\"model_halftone\">నెమ్మదిగా, హాఫ్‌టోన్‌లను తొలగిస్తుంది</string>\n    <string name=\"model_colorizer\">గ్రేస్కేల్/బిడబ్ల్యు చిత్రాల కోసం సాధారణ కలర్‌రైజర్, మెరుగైన ఫలితాల కోసం DDColorని ఉపయోగించండి</string>\n    <string name=\"model_deedge\">అంచు తొలగింపు</string>\n    <string name=\"model_desharpen\">ఓవర్‌షార్పెనింగ్‌ను తొలగిస్తుంది</string>\n    <string name=\"model_dither\">నెమ్మది, క్షీణించడం</string>\n    <string name=\"model_gainres\">యాంటీ-అలియాసింగ్, సాధారణ కళాఖండాలు, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 స్కాన్ ప్రాసెసింగ్</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">తేలికపాటి ఇమేజ్ మెరుగుదల మోడల్</string>\n    <string name=\"model_bcgone_detailed_v2\">కంప్రెషన్ ఆర్టిఫాక్ట్ తొలగింపు</string>\n    <string name=\"model_bcgone_smooth\">కంప్రెషన్ ఆర్టిఫాక్ట్ తొలగింపు</string>\n    <string name=\"model_bandage_smooth\">మృదువైన ఫలితాలతో కట్టు తొలగింపు</string>\n    <string name=\"model_bendel_halftone\">హాఫ్టోన్ నమూనా ప్రాసెసింగ్</string>\n    <string name=\"model_dither_deleter_v3_smooth\">డిథర్ నమూనా తొలగింపు V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG ఆర్టిఫ్యాక్ట్ రిమూవల్ V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 ఆకృతి మెరుగుదల</string>\n    <string name=\"model_vhs_sharpen\">VHS పదునుపెట్టడం మరియు మెరుగుదల</string>\n    <string name=\"merging\">విలీనం</string>\n    <string name=\"chunk_size\">భాగం పరిమాణం</string>\n    <string name=\"overlap_size\">అతివ్యాప్తి పరిమాణం</string>\n    <string name=\"note_chunk_info\">%1$s px కంటే ఎక్కువ ఉన్న చిత్రాలు ముక్కలుగా చేసి, భాగాలుగా ప్రాసెస్ చేయబడతాయి, కనిపించే సీమ్‌లను నిరోధించడానికి వీటిని అతివ్యాప్తి చేస్తాయి.</string>\n    <string name=\"large_chunk_warning\">పెద్ద పరిమాణాలు తక్కువ-ముగింపు పరికరాలతో అస్థిరతను కలిగిస్తాయి</string>\n    <string name=\"select_one_to_start\">ప్రారంభించడానికి ఒకదాన్ని ఎంచుకోండి</string>\n    <string name=\"delete_model_sub\">మీరు %1$s మోడల్‌ను తొలగించాలనుకుంటున్నారా? మీరు దీన్ని మళ్లీ డౌన్‌లోడ్ చేసుకోవాలి</string>\n    <string name=\"confirm\">నిర్ధారించండి</string>\n    <string name=\"models\">మోడల్స్</string>\n    <string name=\"downloaded_models\">డౌన్‌లోడ్ చేసిన మోడల్స్</string>\n    <string name=\"available_models\">అందుబాటులో ఉన్న నమూనాలు</string>\n    <string name=\"preparing\">సిద్ధమౌతోంది</string>\n    <string name=\"active_model\">క్రియాశీల మోడల్</string>\n    <string name=\"failed_to_open_session\">సెషన్‌ను తెరవడం విఫలమైంది</string>\n    <string name=\"only_onnx_models\">.onnx/.ort మోడల్‌లను మాత్రమే దిగుమతి చేసుకోవచ్చు</string>\n    <string name=\"import_model\">దిగుమతి మోడల్</string>\n    <string name=\"import_model_sub\">మరింత ఉపయోగించడానికి అనుకూల onnx మోడల్‌ని దిగుమతి చేయండి, onnx/ort మోడల్‌లు మాత్రమే ఆమోదించబడతాయి, దాదాపు అన్ని esrgan వంటి వేరియంట్‌లకు మద్దతు ఇస్తుంది</string>\n    <string name=\"imported_models\">దిగుమతి చేసుకున్న మోడల్స్</string>\n    <string name=\"model_scunet_color_15_fp16\">సాధారణ శబ్దం, రంగు చిత్రాలు</string>\n    <string name=\"model_scunet_color_25_fp16\">సాధారణ శబ్దం, రంగుల చిత్రాలు, బలమైనవి</string>\n    <string name=\"model_scunet_color_50_fp16\">సాధారణ శబ్దం, రంగుల చిత్రాలు, బలమైనవి</string>\n    <string name=\"model_artifacts_dithering_alsa\">డిథరింగ్ ఆర్టిఫ్యాక్ట్‌లు మరియు కలర్ బ్యాండింగ్‌ను తగ్గిస్తుంది, స్మూత్ గ్రేడియంట్స్ మరియు ఫ్లాట్ కలర్ ఏరియాలను మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_nmkd_brighten_redux\">సహజ రంగులను సంరక్షించేటప్పుడు బ్యాలెన్స్‌డ్ హైలైట్‌లతో ఇమేజ్ బ్రైట్‌నెస్ మరియు కాంట్రాస్ట్‌ను మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_nmkd_brighten\">వివరాలను ఉంచేటప్పుడు మరియు ఓవర్ ఎక్స్‌పోజర్‌ను నివారించేటప్పుడు చీకటి చిత్రాలను ప్రకాశవంతం చేస్తుంది.</string>\n    <string name=\"model_nmkd_detoon\">అధిక రంగు టోనింగ్‌ను తొలగిస్తుంది మరియు మరింత తటస్థ మరియు సహజ రంగు సమతుల్యతను పునరుద్ధరిస్తుంది.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">పాయిజన్ ఆధారిత నాయిస్ టోనింగ్‌ను వర్తింపజేస్తుంది, ఇది చక్కటి వివరాలు మరియు అల్లికలను సంరక్షించడంపై దృష్టి పెడుతుంది.</string>\n    <string name=\"model_noise_toner_poisson_soft\">సున్నితమైన మరియు తక్కువ దూకుడు దృశ్య ఫలితాల కోసం సాఫ్ట్ పాయిసన్ నాయిస్ టోనింగ్‌ని వర్తింపజేస్తుంది.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">ఏకరీతి నాయిస్ టోనింగ్ వివరాల సంరక్షణ మరియు చిత్ర స్పష్టతపై దృష్టి పెట్టింది.</string>\n    <string name=\"model_noise_toner_uniform_soft\">సూక్ష్మ ఆకృతి మరియు మృదువైన ప్రదర్శన కోసం సున్నితమైన ఏకరీతి నాయిస్ టోనింగ్.</string>\n    <string name=\"model_repainter\">కళాఖండాలను మళ్లీ పెయింట్ చేయడం మరియు ఇమేజ్ స్థిరత్వాన్ని మెరుగుపరచడం ద్వారా దెబ్బతిన్న లేదా అసమాన ప్రాంతాలను రిపేర్ చేస్తుంది.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">కనిష్ట పనితీరు ఖర్చుతో కలర్ బ్యాండింగ్‌ను తీసివేసే తేలికపాటి డీబాండింగ్ మోడల్.</string>\n    <string name=\"model_jpeg_0_20\">మెరుగైన స్పష్టత కోసం చాలా ఎక్కువ కంప్రెషన్ ఆర్టిఫ్యాక్ట్‌లతో (0-20% నాణ్యత) చిత్రాలను ఆప్టిమైజ్ చేస్తుంది.</string>\n    <string name=\"model_jpeg_20_40\">అధిక కుదింపు కళాఖండాలతో చిత్రాలను మెరుగుపరుస్తుంది (20-40% నాణ్యత), వివరాలను పునరుద్ధరించడం మరియు శబ్దాన్ని తగ్గించడం.</string>\n    <string name=\"model_jpeg_40_60\">మోడరేట్ కంప్రెషన్ (40-60% నాణ్యత), బ్యాలెన్సింగ్ షార్ప్‌నెస్ మరియు స్మూత్‌నెస్‌తో ఇమేజ్‌లను మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_jpeg_60_80\">సూక్ష్మ వివరాలు మరియు అల్లికలను మెరుగుపరచడానికి లైట్ కంప్రెషన్ (60-80% నాణ్యత)తో చిత్రాలను మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_jpeg_80_100\">సహజమైన రూపాన్ని మరియు వివరాలను సంరక్షించేటప్పుడు నష్టం లేని చిత్రాలను (80-100% నాణ్యత) కొద్దిగా మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_spongecolor_lite\">సాధారణ మరియు వేగవంతమైన రంగులు, కార్టూన్లు, ఆదర్శం కాదు</string>\n    <string name=\"model_deblr\">చిత్ర అస్పష్టతను కొద్దిగా తగ్గిస్తుంది, కళాఖండాలను పరిచయం చేయకుండా పదును మెరుగుపరుస్తుంది.</string>\n    <string name=\"processing_channel\">దీర్ఘకాలిక కార్యకలాపాలు</string>\n    <string name=\"processing_image\">చిత్రాన్ని ప్రాసెస్ చేస్తోంది</string>\n    <string name=\"processing\">ప్రాసెసింగ్</string>\n    <string name=\"model_artifacts_jpg_0_20\">చాలా తక్కువ నాణ్యత గల చిత్రాలలో (0-20%) భారీ JPEG కంప్రెషన్ కళాఖండాలను తొలగిస్తుంది.</string>\n    <string name=\"model_artifacts_jpg_20_40\">అత్యంత కుదించబడిన చిత్రాలలో (20-40%) బలమైన JPEG కళాఖండాలను తగ్గిస్తుంది.</string>\n    <string name=\"model_artifacts_jpg_40_60\">ఇమేజ్ వివరాలను (40-60%) భద్రపరిచేటప్పుడు మోడరేట్ JPEG కళాఖండాలను శుభ్రపరుస్తుంది.</string>\n    <string name=\"model_artifacts_jpg_60_80\">తేలికపాటి JPEG కళాఖండాలను అధిక నాణ్యత గల చిత్రాలలో (60-80%) మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_artifacts_jpg_80_100\">దాదాపు నష్టం లేని చిత్రాలలో (80-100%) చిన్న JPEG కళాఖండాలను సూక్ష్మంగా తగ్గిస్తుంది.</string>\n    <string name=\"model_redetail_v2\">చక్కటి వివరాలు మరియు అల్లికలను మెరుగుపరుస్తుంది, భారీ కళాఖండాలు లేకుండా గ్రహించిన పదును మెరుగుపరుస్తుంది.</string>\n    <string name=\"processing_finished\">ప్రాసెసింగ్ పూర్తయింది</string>\n    <string name=\"processing_failed\">ప్రాసెసింగ్ విఫలమైంది</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">సహజమైన రూపాన్ని, వేగం కోసం ఆప్టిమైజ్‌గా ఉంచుతూ చర్మ ఆకృతిని మరియు వివరాలను మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG కంప్రెషన్ కళాఖండాలను తీసివేస్తుంది మరియు కంప్రెస్ చేయబడిన ఫోటోల కోసం చిత్ర నాణ్యతను పునరుద్ధరిస్తుంది.</string>\n    <string name=\"model_iso_denoise_v1\">తక్కువ-కాంతి పరిస్థితుల్లో తీసిన ఫోటోలలో ISO శబ్దాన్ని తగ్గిస్తుంది, వివరాలను భద్రపరుస్తుంది.</string>\n    <string name=\"model_dejumbo\">అతిగా బహిర్గతమైన లేదా \\\"జంబో\\\" హైలైట్‌లను సరిచేస్తుంది మరియు మెరుగైన టోనల్ బ్యాలెన్స్‌ని పునరుద్ధరిస్తుంది.</string>\n    <string name=\"model_ddcolor_tiny\">గ్రేస్కేల్ చిత్రాలకు సహజ రంగులను జోడించే తేలికపాటి మరియు వేగవంతమైన రంగుల నమూనా.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">డెనోయిస్</string>\n    <string name=\"type_colorize\">రంగులు వేయండి</string>\n    <string name=\"type_artifacts\">కళాఖండాలు</string>\n    <string name=\"type_enhance\">మెరుగుపరచండి</string>\n    <string name=\"type_anime\">అనిమే</string>\n    <string name=\"type_scans\">స్కాన్ చేస్తుంది</string>\n    <string name=\"type_upscale\">ఉన్నత స్థాయి</string>\n    <string name=\"model_realesrgan_x4v3\">సాధారణ చిత్రాల కోసం X4 అప్‌స్కేలర్; తక్కువ GPU మరియు సమయాన్ని ఉపయోగించే చిన్న మోడల్, మోడరేట్ డిబ్లర్ మరియు డెనోయిస్‌తో.</string>\n    <string name=\"model_realesrgan_x2plus\">సాధారణ చిత్రాల కోసం X2 అప్‌స్కేలర్, అల్లికలు మరియు సహజ వివరాలను సంరక్షించడం.</string>\n    <string name=\"model_realesrgan_x4plus\">మెరుగైన అల్లికలు మరియు వాస్తవిక ఫలితాలతో సాధారణ చిత్రాల కోసం X4 అప్‌స్కేలర్.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 అప్‌స్కేలర్ అనిమే చిత్రాల కోసం ఆప్టిమైజ్ చేయబడింది; పదునైన పంక్తులు మరియు వివరాల కోసం 6 RRDB బ్లాక్‌లు.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE నష్టంతో X4 అప్‌స్కేలర్, సాధారణ చిత్రాల కోసం సున్నితమైన ఫలితాలను మరియు తగ్గిన కళాఖండాలను ఉత్పత్తి చేస్తుంది.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 అప్‌స్కేలర్ అనిమే చిత్రాల కోసం ఆప్టిమైజ్ చేయబడింది; పదునైన వివరాలు మరియు మృదువైన గీతలతో 4B32F వేరియంట్.</string>\n    <string name=\"model_ultrasharp_v2_x4\">సాధారణ చిత్రాల కోసం X4 అల్ట్రాషార్ప్ V2 మోడల్; పదును మరియు స్పష్టతను నొక్కి చెబుతుంది.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 అల్ట్రాషార్ప్ V2 లైట్; వేగంగా మరియు చిన్నదిగా, తక్కువ GPU మెమరీని ఉపయోగిస్తున్నప్పుడు వివరాలను భద్రపరుస్తుంది.</string>\n    <string name=\"model_rmbg_1_4\">శీఘ్ర నేపథ్య తొలగింపు కోసం తేలికపాటి మోడల్. సమతుల్య పనితీరు మరియు ఖచ్చితత్వం. పోర్ట్రెయిట్‌లు, వస్తువులు మరియు దృశ్యాలతో పని చేస్తుంది. చాలా సందర్భాలలో ఉపయోగం కోసం సిఫార్సు చేయబడింది.</string>\n    <string name=\"type_removebg\">BGని తీసివేయండి</string>\n    <string name=\"horizontal_border_thickness\">క్షితిజసమాంతర అంచు మందం</string>\n    <string name=\"vertical_border_thickness\">నిలువు అంచు మందం</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s రంగు</item>\n        <item quantity=\"other\">%1$s రంగులు</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">ప్రస్తుత మోడల్ చంకింగ్‌కు మద్దతు ఇవ్వదు, చిత్రం అసలు కొలతలలో ప్రాసెస్ చేయబడుతుంది, ఇది అధిక మెమరీ వినియోగం మరియు తక్కువ-ముగింపు పరికరాలతో సమస్యలను కలిగిస్తుంది</string>\n    <string name=\"chunking_disabled\">చంకింగ్ డిజేబుల్ చేయబడింది, ఇమేజ్ అసలు కొలతల్లో ప్రాసెస్ చేయబడుతుంది, ఇది అధిక మెమరీ వినియోగం మరియు తక్కువ-ముగింపు పరికరాలతో సమస్యలకు కారణం కావచ్చు కానీ అనుమితిపై మెరుగైన ఫలితాలను ఇవ్వవచ్చు</string>\n    <string name=\"chunking\">చంకింగ్</string>\n    <string name=\"model_u2net\">బ్యాక్‌గ్రౌండ్ రిమూవల్ కోసం హై-కచ్చితత్వంతో కూడిన ఇమేజ్ సెగ్మెంటేషన్ మోడల్</string>\n    <string name=\"model_u2netp\">తక్కువ మెమరీ వినియోగంతో వేగవంతమైన నేపథ్య తొలగింపు కోసం U2Net యొక్క తేలికపాటి వెర్షన్.</string>\n    <string name=\"model_ddcolor\">పూర్తి DDColor మోడల్ కనీస కళాఖండాలతో సాధారణ చిత్రాల కోసం అధిక-నాణ్యత రంగులను అందిస్తుంది. అన్ని రంగుల నమూనాల ఉత్తమ ఎంపిక.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor శిక్షణ పొందిన మరియు ప్రైవేట్ కళాత్మక డేటాసెట్‌లు; తక్కువ అవాస్తవిక రంగు కళాఖండాలతో విభిన్న మరియు కళాత్మక రంగుల ఫలితాలను ఉత్పత్తి చేస్తుంది.</string>\n    <string name=\"model_birefnet\">ఖచ్చితమైన బ్యాక్‌గ్రౌండ్ రిమూవల్ కోసం స్విన్ ట్రాన్స్‌ఫార్మర్ ఆధారంగా తేలికైన BiRefNet మోడల్.</string>\n    <string name=\"model_inspyrenet\">పదునైన అంచులు మరియు అద్భుతమైన వివరాల సంరక్షణతో అధిక-నాణ్యత నేపథ్య తొలగింపు, ముఖ్యంగా సంక్లిష్ట వస్తువులు మరియు గమ్మత్తైన నేపథ్యాలపై.</string>\n    <string name=\"model_isnet\">సాధారణ వస్తువులు మరియు మితమైన వివరాల సంరక్షణకు అనువైన మృదువైన అంచులతో ఖచ్చితమైన మాస్క్‌లను ఉత్పత్తి చేసే బ్యాక్‌గ్రౌండ్ రిమూవల్ మోడల్.</string>\n    <string name=\"model_already_downloaded\">మోడల్ ఇప్పటికే డౌన్‌లోడ్ చేయబడింది</string>\n    <string name=\"model_successfully_imported\">మోడల్ విజయవంతంగా దిగుమతి చేయబడింది</string>\n    <string name=\"type\">టైప్ చేయండి</string>\n    <string name=\"keyword\">కీవర్డ్</string>\n    <string name=\"very_fast\">చాలా ఫాస్ట్</string>\n    <string name=\"normal\">సాధారణ</string>\n    <string name=\"slow\">నెమ్మదిగా</string>\n    <string name=\"very_slow\">చాలా స్లో</string>\n    <string name=\"compute_percents\">శాతాలను లెక్కించండి</string>\n    <string name=\"minimum_value_is\">కనిష్ట విలువ %1$s</string>\n    <string name=\"warp_sub\">వేళ్లతో గీయడం ద్వారా చిత్రాన్ని వక్రీకరించండి</string>\n    <string name=\"warp\">వార్ప్</string>\n    <string name=\"hardness\">కాఠిన్యం</string>\n    <string name=\"warp_mode\">వార్ప్ మోడ్</string>\n    <string name=\"warp_mode_move\">తరలించు</string>\n    <string name=\"warp_mode_grow\">పెరుగుతాయి</string>\n    <string name=\"warp_mode_shrink\">కుదించు</string>\n    <string name=\"warp_mode_swirl_cw\">స్విర్ల్ CW</string>\n    <string name=\"warp_mode_swirl_ccw\">స్విర్ల్ CCW</string>\n    <string name=\"fade_strength\">ఫేడ్ స్ట్రెంత్</string>\n    <string name=\"top_drop\">టాప్ డ్రాప్</string>\n    <string name=\"bottom_drop\">బాటమ్ డ్రాప్</string>\n    <string name=\"start_drop\">డ్రాప్ ప్రారంభించండి</string>\n    <string name=\"end_drop\">ఎండ్ డ్రాప్</string>\n    <string name=\"downloading\">డౌన్‌లోడ్ చేస్తోంది</string>\n    <string name=\"smooth_shapes\">స్మూత్ ఆకారాలు</string>\n    <string name=\"smooth_shapes_sub\">మృదువైన, మరింత సహజమైన ఆకారాల కోసం ప్రామాణిక గుండ్రని దీర్ఘచతురస్రాలకు బదులుగా సూపర్‌ఎల్లిప్స్‌లను ఉపయోగించండి</string>\n    <string name=\"shape_type\">ఆకార రకం</string>\n    <string name=\"cut\">కట్</string>\n    <string name=\"rounded\">గుండ్రంగా</string>\n    <string name=\"smooth\">మృదువైన</string>\n    <string name=\"cut_shapes_sub\">గుండ్రంగా లేకుండా పదునైన అంచులు</string>\n    <string name=\"rounded_shapes_sub\">క్లాసిక్ గుండ్రని మూలలు</string>\n    <string name=\"shapes_type\">ఆకారాల రకం</string>\n    <string name=\"corners_size\">మూలల పరిమాణం</string>\n    <string name=\"squircle\">ఉడుత</string>\n    <string name=\"squircle_shapes_sub\">సొగసైన గుండ్రని UI మూలకాలు</string>\n    <string name=\"filename_format\">ఫైల్ పేరు ఫార్మాట్</string>\n    <string name=\"prefix_pattern_description\">ప్రాజెక్ట్ పేర్లు, బ్రాండ్‌లు లేదా వ్యక్తిగత ట్యాగ్‌ల కోసం అనుకూలమైన వచనం ఫైల్ పేరు ప్రారంభంలోనే ఉంచబడుతుంది.</string>\n    <string name=\"original_filename_pattern_description\">పొడిగింపు లేకుండా అసలు ఫైల్ పేరును ఉపయోగిస్తుంది, సోర్స్ గుర్తింపును అలాగే ఉంచడంలో మీకు సహాయపడుతుంది.</string>\n    <string name=\"width_pattern_description\">పిక్సెల్‌లలో ఇమేజ్ వెడల్పు, రిజల్యూషన్ మార్పులు లేదా స్కేలింగ్ ఫలితాలను ట్రాక్ చేయడానికి ఉపయోగపడుతుంది.</string>\n    <string name=\"height_pattern_description\">పిక్సెల్‌లలో ఇమేజ్ ఎత్తు, కారక నిష్పత్తులు లేదా ఎగుమతులతో పని చేస్తున్నప్పుడు సహాయకరంగా ఉంటుంది.</string>\n    <string name=\"random_numbers_pattern_description\">ప్రత్యేకమైన ఫైల్ పేర్లకు హామీ ఇవ్వడానికి యాదృచ్ఛిక అంకెలను రూపొందిస్తుంది; నకిలీలకు వ్యతిరేకంగా అదనపు భద్రత కోసం మరిన్ని అంకెలను జోడించండి.</string>\n    <string name=\"sequence_number_pattern_description\">బ్యాచ్ ఎగుమతుల కోసం ఆటో-ఇంక్రిమెంటింగ్ కౌంటర్, ఒక సెషన్‌లో బహుళ చిత్రాలను సేవ్ చేసేటప్పుడు అనువైనది.</string>\n    <string name=\"preset_info_pattern_description\">ఫైల్ పేరులో వర్తింపజేయబడిన ప్రీసెట్ పేరును చొప్పిస్తుంది, తద్వారా చిత్రం ఎలా ప్రాసెస్ చేయబడిందో మీరు సులభంగా గుర్తుంచుకోగలరు.</string>\n    <string name=\"scale_mode_pattern_description\">ప్రాసెసింగ్ సమయంలో ఉపయోగించిన ఇమేజ్ స్కేలింగ్ మోడ్‌ను ప్రదర్శిస్తుంది, పరిమాణం మార్చబడిన, కత్తిరించిన లేదా అమర్చిన చిత్రాలను వేరు చేయడంలో సహాయపడుతుంది.</string>\n    <string name=\"suffix_pattern_description\">_v2, _edited లేదా _final వంటి సంస్కరణకు ఉపయోగపడే అనుకూల వచనం ఫైల్ పేరు చివరిలో ఉంచబడుతుంది.</string>\n    <string name=\"extension_pattern_description\">ఫైల్ పొడిగింపు (png, jpg, webp, మొదలైనవి), స్వయంచాలకంగా సేవ్ చేయబడిన వాస్తవ ఆకృతికి సరిపోలుతుంది.</string>\n    <string name=\"formatted_timestamp_pattern_description\">అనుకూలీకరించదగిన టైమ్‌స్టాంప్, ఇది ఖచ్చితమైన సార్టింగ్ కోసం జావా స్పెసిఫికేషన్ ద్వారా మీ స్వంత ఆకృతిని నిర్వచించటానికి మిమ్మల్ని అనుమతిస్తుంది.</string>\n    <string name=\"fling_type\">ఫ్లింగ్ రకం</string>\n    <string name=\"android_native\">Android స్థానిక</string>\n    <string name=\"ios_style\">iOS శైలి</string>\n    <string name=\"smooth_curve\">స్మూత్ కర్వ్</string>\n    <string name=\"quick_stop\">త్వరిత ఆపు</string>\n    <string name=\"bouncy\">ఎగిరి పడే</string>\n    <string name=\"floaty\">తేలియాడే</string>\n    <string name=\"snappy\">చురుకైన</string>\n    <string name=\"ultra_smooth\">అల్ట్రా స్మూత్</string>\n    <string name=\"adaptive\">అనుకూలమైనది</string>\n    <string name=\"accessibility_aware\">యాక్సెసిబిలిటీ అవేర్</string>\n    <string name=\"reduced_motion\">తగ్గిన చలనం</string>\n    <string name=\"android_native_sub\">స్థానిక ఆండ్రాయిడ్ స్క్రోల్ ఫిజిక్స్</string>\n    <string name=\"smooth_sub\">సాధారణ ఉపయోగం కోసం సమతుల్య, మృదువైన స్క్రోలింగ్</string>\n    <string name=\"ios_style_sub\">అధిక ఘర్షణ iOS-వంటి స్క్రోల్ ప్రవర్తన</string>\n    <string name=\"smooth_curve_sub\">ప్రత్యేకమైన స్క్రోల్ అనుభూతి కోసం ప్రత్యేకమైన స్ప్లైన్ కర్వ్</string>\n    <string name=\"quick_stop_sub\">త్వరిత స్టాపింగ్‌తో ఖచ్చితమైన స్క్రోలింగ్</string>\n    <string name=\"bouncy_sub\">ఉల్లాసభరితమైన, ప్రతిస్పందించే ఎగిరి పడే స్క్రోల్</string>\n    <string name=\"floaty_sub\">కంటెంట్ బ్రౌజింగ్ కోసం పొడవైన, గ్లైడింగ్ స్క్రోల్‌లు</string>\n    <string name=\"snappy_sub\">ఇంటరాక్టివ్ UIల కోసం త్వరిత, ప్రతిస్పందించే స్క్రోలింగ్</string>\n    <string name=\"ultra_smooth_sub\">పొడిగించిన మొమెంటంతో ప్రీమియం మృదువైన స్క్రోలింగ్</string>\n    <string name=\"adaptive_sub\">ఫ్లింగ్ వేగం ఆధారంగా భౌతిక శాస్త్రాన్ని సర్దుబాటు చేస్తుంది</string>\n    <string name=\"accessibility_aware_sub\">సిస్టమ్ యాక్సెసిబిలిటీ సెట్టింగ్‌లను గౌరవిస్తుంది</string>\n    <string name=\"reduced_motion_sub\">ప్రాప్యత అవసరాల కోసం కనీస చలనం</string>\n    <string name=\"primary_lines\">ప్రాథమిక పంక్తులు</string>\n    <string name=\"primary_lines_sub\">ప్రతి ఐదవ పంక్తికి మందమైన పంక్తిని జోడిస్తుంది</string>\n    <string name=\"fill_color\">రంగును పూరించండి</string>\n    <string name=\"hidden_tools\">దాచిన సాధనాలు</string>\n    <string name=\"hidden_for_share\">భాగస్వామ్యం కోసం దాచబడిన సాధనాలు</string>\n    <string name=\"color_library\">రంగు లైబ్రరీ</string>\n    <string name=\"color_library_sub\">రంగుల విస్తారమైన సేకరణను బ్రౌజ్ చేయండి</string>\n    <string name=\"model_fatality_deblur\">ఫోకస్ లేని ఫోటోలను ఫిక్సింగ్ చేయడానికి అనువైన సహజ వివరాలను నిర్వహించేటప్పుడు చిత్రాల నుండి పదును మరియు బ్లర్‌ను తొలగిస్తుంది.</string>\n    <string name=\"model_unresize_v3\">మునుపు పరిమాణం మార్చబడిన చిత్రాలను తెలివిగా పునరుద్ధరిస్తుంది, కోల్పోయిన వివరాలు మరియు అల్లికలను తిరిగి పొందుతుంది.</string>\n    <string name=\"model_liveaction_v1_span\">లైవ్-యాక్షన్ కంటెంట్ కోసం ఆప్టిమైజ్ చేయబడింది, కుదింపు కళాఖండాలను తగ్గిస్తుంది మరియు సినిమా/టీవీ షో ఫ్రేమ్‌లలో చక్కటి వివరాలను మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS-నాణ్యత ఫుటేజీని HDకి మారుస్తుంది, టేప్ శబ్దాన్ని తీసివేస్తుంది మరియు పాతకాలపు అనుభూతిని కాపాడుతూ రిజల్యూషన్‌ను మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_text2hd_v1\">టెక్స్ట్-హెవీ ఇమేజ్‌లు మరియు స్క్రీన్‌షాట్‌ల కోసం ప్రత్యేకించబడింది, అక్షరాలను పదునుపెడుతుంది మరియు రీడబిలిటీని మెరుగుపరుస్తుంది.</string>\n    <string name=\"model_frankendata_pretrainer\">విభిన్న డేటాసెట్‌లపై శిక్షణ పొందిన అధునాతన అప్‌స్కేలింగ్, సాధారణ ప్రయోజన ఫోటో మెరుగుదల కోసం అద్భుతమైనది.</string>\n    <string name=\"model_realwebphoto_v2\">వెబ్-కంప్రెస్ చేయబడిన ఫోటోల కోసం ఆప్టిమైజ్ చేయబడింది, JPEG కళాఖండాలను తీసివేస్తుంది మరియు సహజ రూపాన్ని పునరుద్ధరిస్తుంది.</string>\n    <string name=\"model_realwebphoto_v4\">మెరుగైన ఆకృతి సంరక్షణ మరియు కళాఖండాల తగ్గింపుతో వెబ్ ఫోటోల కోసం మెరుగైన సంస్కరణ.</string>\n    <string name=\"model_dat_2x\">డ్యూయల్ అగ్రిగేషన్ ట్రాన్స్‌ఫార్మర్ టెక్నాలజీతో 2x అప్‌స్కేలింగ్, పదును మరియు సహజ వివరాలను నిర్వహిస్తుంది.</string>\n    <string name=\"model_dat_3x\">ఆధునిక ట్రాన్స్‌ఫార్మర్ ఆర్కిటెక్చర్ ఉపయోగించి 3x అప్‌స్కేలింగ్, మితమైన విస్తరణ అవసరాలకు అనువైనది.</string>\n    <string name=\"model_dat_4x\">అత్యాధునిక ట్రాన్స్‌ఫార్మర్ నెట్‌వర్క్‌తో 4x అధిక-నాణ్యత అప్‌స్కేలింగ్, పెద్ద ప్రమాణాల వద్ద చక్కటి వివరాలను భద్రపరుస్తుంది.</string>\n    <string name=\"model_nafnet_deblurring\">ఫోటోల నుండి బ్లర్/నాయిస్ మరియు షేక్‌లను తొలగిస్తుంది. సాధారణ ప్రయోజనం కానీ ఫోటోలలో ఉత్తమమైనది.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Swin2SR ట్రాన్స్‌ఫార్మర్‌ని ఉపయోగించి తక్కువ-నాణ్యత చిత్రాలను పునరుద్ధరిస్తుంది, BSRGAN అధోకరణం కోసం ఆప్టిమైజ్ చేయబడింది. భారీ కుదింపు కళాఖండాలను ఫిక్సింగ్ చేయడానికి మరియు 4x స్కేల్‌లో వివరాలను మెరుగుపరచడానికి గొప్పది.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN క్షీణతపై శిక్షణ పొందిన SwinIR ట్రాన్స్‌ఫార్మర్‌తో 4x అప్‌స్కేలింగ్. ఫోటోలు మరియు సంక్లిష్ట దృశ్యాలలో పదునైన అల్లికలు మరియు మరింత సహజమైన వివరాల కోసం GANని ఉపయోగిస్తుంది.</string>\n    <string name=\"path\">మార్గం</string>\n    <string name=\"merge_pdf\">PDFని విలీనం చేయండి</string>\n    <string name=\"merge_pdf_sub\">బహుళ PDF ఫైల్‌లను ఒక పత్రంలో కలపండి</string>\n    <string name=\"files_order\">ఫైల్స్ ఆర్డర్</string>\n    <string name=\"pages_short\">పేజీలు</string>\n    <string name=\"split_pdf\">PDFని విభజించండి</string>\n    <string name=\"split_pdf_sub\">PDF పత్రం నుండి నిర్దిష్ట పేజీలను సంగ్రహించండి</string>\n    <string name=\"rotate_pdf\">PDFని తిప్పండి</string>\n    <string name=\"rotate_pdf_sub\">పేజీ విన్యాసాన్ని శాశ్వతంగా పరిష్కరించండి</string>\n    <string name=\"pages\">పేజీలు</string>\n    <string name=\"rearrange_pdf\">PDFని మళ్లీ అమర్చండి</string>\n    <string name=\"rearrange_pdf_sub\">వాటిని క్రమాన్ని మార్చడానికి పేజీలను లాగండి మరియు వదలండి</string>\n    <string name=\"hold_drag_drop\">పేజీలను పట్టుకుని లాగండి</string>\n    <string name=\"page_numbers\">పేజీ సంఖ్యలు</string>\n    <string name=\"page_numbers_sub\">మీ పత్రాలకు స్వయంచాలకంగా నంబరింగ్ జోడించండి</string>\n    <string name=\"label_format\">లేబుల్ ఫార్మాట్</string>\n    <string name=\"pdf_to_text\">PDF నుండి టెక్స్ట్ (OCR)</string>\n    <string name=\"pdf_to_text_sub\">మీ PDF పత్రాల నుండి సాదా వచనాన్ని సంగ్రహించండి</string>\n    <string name=\"watermark_pdf_sub\">బ్రాండింగ్ లేదా భద్రత కోసం అనుకూల వచనాన్ని అతివ్యాప్తి చేయండి</string>\n    <string name=\"signature\">సంతకం</string>\n    <string name=\"signature_sub\">ఏదైనా పత్రానికి మీ ఎలక్ట్రానిక్ సంతకాన్ని జోడించండి</string>\n    <string name=\"will_be_for_signature\">ఇది సంతకం వలె ఉపయోగించబడుతుంది</string>\n    <string name=\"unlock_pdf\">PDFని అన్‌లాక్ చేయండి</string>\n    <string name=\"unlock_pdf_sub\">మీ రక్షిత ఫైల్‌ల నుండి పాస్‌వర్డ్‌లను తీసివేయండి</string>\n    <string name=\"protect_pdf\">PDFని రక్షించండి</string>\n    <string name=\"protect_pdf_sub\">బలమైన ఎన్‌క్రిప్షన్‌తో మీ పత్రాలను భద్రపరచండి</string>\n    <string name=\"success\">విజయం</string>\n    <string name=\"pdf_unlocked\">PDF అన్‌లాక్ చేయబడింది, మీరు దీన్ని సేవ్ చేయవచ్చు లేదా భాగస్వామ్యం చేయవచ్చు</string>\n    <string name=\"repair_pdf\">PDFని రిపేర్ చేయండి</string>\n    <string name=\"repair_pdf_sub\">పాడైన లేదా చదవలేని పత్రాలను పరిష్కరించడానికి ప్రయత్నం</string>\n    <string name=\"grayscale\">గ్రేస్కేల్</string>\n    <string name=\"grayscale_pdf_sub\">అన్ని డాక్యుమెంట్ ఎంబెడెడ్ ఇమేజ్‌లను గ్రేస్కేల్‌కి మార్చండి</string>\n    <string name=\"compress_pdf\">PDFని కుదించుము</string>\n    <string name=\"compress_pdf_sub\">సులభంగా భాగస్వామ్యం చేయడానికి మీ డాక్యుమెంట్ ఫైల్ పరిమాణాన్ని ఆప్టిమైజ్ చేయండి</string>\n    <string name=\"repair_info\">ImageToolbox అంతర్గత క్రాస్-రిఫరెన్స్ పట్టికను పునర్నిర్మిస్తుంది మరియు మొదటి నుండి ఫైల్ నిర్మాణాన్ని పునరుత్పత్తి చేస్తుంది. ఇది \\\\\"తెరవలేని\\\\\" అనేక ఫైల్‌లకు యాక్సెస్‌ని పునరుద్ధరించగలదు</string>\n    <string name=\"grayscale_info\">ఈ సాధనం అన్ని డాక్యుమెంట్ చిత్రాలను గ్రేస్కేల్‌కి మారుస్తుంది. ఫైల్ పరిమాణాన్ని ముద్రించడానికి మరియు తగ్గించడానికి ఉత్తమమైనది</string>\n    <string name=\"metadata\">మెటాడేటా</string>\n    <string name=\"metadata_pdf_sub\">మెరుగైన గోప్యత కోసం డాక్యుమెంట్ ప్రాపర్టీలను సవరించండి</string>\n    <string name=\"tags\">ట్యాగ్‌లు</string>\n    <string name=\"producer\">నిర్మాత</string>\n    <string name=\"author\">రచయిత</string>\n    <string name=\"keywords\">కీలకపదాలు</string>\n    <string name=\"creator\">సృష్టికర్త</string>\n    <string name=\"privacy_deep_clean\">గోప్యత డీప్ క్లీన్</string>\n    <string name=\"privacy_deep_clean_sub\">ఈ పత్రం కోసం అందుబాటులో ఉన్న మొత్తం మెటాడేటాను క్లియర్ చేయండి</string>\n    <string name=\"page\">పేజీ</string>\n    <string name=\"deep_ocr\">లోతైన OCR</string>\n    <string name=\"deep_ocr_sub\">పత్రం నుండి వచనాన్ని సంగ్రహించి, టెసెరాక్ట్ ఇంజిన్‌ని ఉపయోగించి ఒక టెక్స్ట్ ఫైల్‌లో నిల్వ చేయండి</string>\n    <string name=\"cant_remove_all\">అన్ని పేజీలను తీసివేయలేరు</string>\n    <string name=\"remove_pages_pdf\">PDF పేజీలను తీసివేయండి</string>\n    <string name=\"remove_pages_pdf_sub\">PDF పత్రం నుండి నిర్దిష్ట పేజీలను తీసివేయండి</string>\n    <string name=\"tap_to_remove\">తీసివేయడానికి నొక్కండి</string>\n    <string name=\"manually\">మానవీయంగా</string>\n    <string name=\"crop_pdf\">PDFని కత్తిరించండి</string>\n    <string name=\"crop_pdf_sub\">డాక్యుమెంట్ పేజీలను ఏదైనా హద్దులకు కత్తిరించండి</string>\n    <string name=\"flatten_pdf\">PDFని చదును చేయండి</string>\n    <string name=\"flatten_pdf_sub\">డాక్యుమెంట్ పేజీలను రేస్టరింగ్ చేయడం ద్వారా PDFని సవరించలేనిదిగా చేయండి</string>\n    <string name=\"camera_failed_to_open\">కెమెరాను ప్రారంభించడం సాధ్యపడలేదు. దయచేసి అనుమతులను తనిఖీ చేయండి మరియు ఇది మరొక యాప్ ద్వారా ఉపయోగించబడటం లేదని నిర్ధారించుకోండి.</string>\n    <string name=\"extract_images\">చిత్రాలను సంగ్రహించండి</string>\n    <string name=\"extract_images_sub\">PDFలలో పొందుపరిచిన చిత్రాలను వాటి అసలు రిజల్యూషన్‌లో సంగ్రహించండి</string>\n    <string name=\"pdf_no_embedded\">ఈ PDF ఫైల్‌లో పొందుపరిచిన చిత్రాలు ఏవీ లేవు</string>\n    <string name=\"extract_images_info\">ఈ సాధనం ప్రతి పేజీని స్కాన్ చేస్తుంది మరియు పూర్తి-నాణ్యత మూలాధార చిత్రాలను తిరిగి పొందుతుంది - పత్రాల నుండి అసలైన వాటిని సేవ్ చేయడానికి సరైనది</string>\n    <string name=\"draw_signature\">సంతకాన్ని గీయండి</string>\n    <string name=\"pen_params\">పెన్ పారామ్స్</string>\n    <string name=\"draw_signature_sub\">పత్రాలపై ఉంచడానికి సొంత సంతకాన్ని చిత్రంగా ఉపయోగించండి</string>\n    <string name=\"zip_pdf\">జిప్ PDF</string>\n    <string name=\"zip_pdf_sub\">ఇచ్చిన విరామంతో పత్రాన్ని విభజించి, కొత్త పత్రాలను జిప్ ఆర్కైవ్‌లో ప్యాక్ చేయండి</string>\n    <string name=\"interval\">ఇంటర్వెల్</string>\n    <string name=\"print_pdf\">PDFని ముద్రించండి</string>\n    <string name=\"print_pdf_sub\">అనుకూల పేజీ పరిమాణంతో ప్రింటింగ్ కోసం పత్రాన్ని సిద్ధం చేయండి</string>\n    <string name=\"pages_per_sheet\">ప్రతి షీట్‌కి పేజీలు</string>\n    <string name=\"orientation\">ఓరియంటేషన్</string>\n    <string name=\"page_size\">పేజీ పరిమాణం</string>\n    <string name=\"margin\">మార్జిన్</string>\n    <string name=\"bloom\">బ్లూమ్</string>\n    <string name=\"soft_knee\">మృదువైన మోకాలి</string>\n    <string name=\"model_realesr_animevideo_v3x4\">అనిమే మరియు కార్టూన్‌ల కోసం ఆప్టిమైజ్ చేయబడింది. మెరుగైన సహజ రంగులు మరియు తక్కువ కళాఖండాలతో వేగవంతమైన అప్‌స్కేలింగ్</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 వంటి శైలి</string>\n    <string name=\"calculate_hint\">కావలసిన విలువను లెక్కించడానికి ఇక్కడ ప్రాథమిక గణిత చిహ్నాలను నమోదు చేయండి (ఉదా. (5+5)*10)</string>\n    <string name=\"math_expression\">గణిత వ్యక్తీకరణ</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s చిత్రాల వరకు ఎంచుకోండి</string>\n    <string name=\"keep_date_time\">తేదీ సమయాన్ని ఉంచండి</string>\n    <string name=\"keep_date_time_sub\">తేదీ మరియు సమయానికి సంబంధించిన ఎక్సిఫ్ ట్యాగ్‌లను ఎల్లప్పుడూ భద్రపరచండి, కీప్ ఎక్సిఫ్ ఎంపికతో సంబంధం లేకుండా స్వతంత్రంగా పనిచేస్తుంది</string>\n    <string name=\"background_color_for_alpha_formats\">ఆల్ఫా ఫార్మాట్‌ల కోసం నేపథ్య రంగు</string>\n    <string name=\"background_color_for_alpha_formats_sub\">ఆల్ఫా సపోర్ట్‌తో ప్రతి ఇమేజ్ ఫార్మాట్‌కి బ్యాక్‌గ్రౌండ్ కలర్ సెట్ చేసే సామర్థ్యాన్ని జోడిస్తుంది, డిసేబుల్ చేసినప్పుడు ఆల్ఫా కాని వాటికి మాత్రమే ఇది అందుబాటులో ఉంటుంది</string>\n    <string name=\"open_markup_project\">ప్రాజెక్ట్ తెరవండి</string>\n    <string name=\"open_markup_project_sub\">మునుపు సేవ్ చేసిన ఇమేజ్ టూల్‌బాక్స్ ప్రాజెక్ట్‌ని సవరించడం కొనసాగించండి</string>\n    <string name=\"markup_project_open_failed\">ఇమేజ్ టూల్‌బాక్స్ ప్రాజెక్ట్‌ను తెరవడం సాధ్యం కాలేదు</string>\n    <string name=\"markup_project_missing_data\">ఇమేజ్ టూల్‌బాక్స్ ప్రాజెక్ట్ ప్రాజెక్ట్ డేటా లేదు</string>\n    <string name=\"markup_project_corrupted\">ఇమేజ్ టూల్‌బాక్స్ ప్రాజెక్ట్ పాడైంది</string>\n    <string name=\"unsupported_markup_project_version\">మద్దతు లేని ఇమేజ్ టూల్‌బాక్స్ ప్రాజెక్ట్ వెర్షన్: %1$d</string>\n    <string name=\"save_markup_project\">ప్రాజెక్ట్‌ను సేవ్ చేయండి</string>\n    <string name=\"save_markup_project_sub\">సవరించగలిగే ప్రాజెక్ట్ ఫైల్‌లో లేయర్‌లు, నేపథ్యం మరియు సవరణ చరిత్రను నిల్వ చేయండి</string>\n    <string name=\"failed_to_open\">తెరవడంలో విఫలమైంది</string>\n    <string name=\"ocr_write_to_searchable_pdf\">శోధించదగిన PDFకి వ్రాయండి</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">ఇమేజ్ బ్యాచ్ నుండి వచనాన్ని గుర్తించి, శోధించదగిన PDFని ఇమేజ్ మరియు ఎంచుకోదగిన టెక్స్ట్ లేయర్‌తో సేవ్ చేయండి</string>\n    <string name=\"layer_alpha\">ఆల్ఫా పొర</string>\n    <string name=\"horizontal_flip\">క్షితిజసమాంతర ఫ్లిప్</string>\n    <string name=\"vertical_flip\">వర్టికల్ ఫ్లిప్</string>\n    <string name=\"lock\">తాళం వేయండి</string>\n    <string name=\"add_shadow\">షాడో జోడించండి</string>\n    <string name=\"shadow_color\">నీడ రంగు</string>\n    <string name=\"text_geometry\">టెక్స్ట్ జ్యామితి</string>\n    <string name=\"text_geometry_sub\">పదునైన స్టైలైజేషన్ కోసం వచనాన్ని సాగదీయండి లేదా వక్రంగా మార్చండి</string>\n    <string name=\"scale_x\">స్కేల్ X</string>\n    <string name=\"skew_x\">స్కేవ్ X</string>\n    <string name=\"remove_annotations\">ఉల్లేఖనాలను తీసివేయండి</string>\n    <string name=\"remove_annotations_sub\">PDF పేజీల నుండి లింక్‌లు, వ్యాఖ్యలు, ముఖ్యాంశాలు, ఆకారాలు లేదా ఫారమ్ ఫీల్డ్‌ల వంటి ఎంచుకున్న ఉల్లేఖన రకాలను తీసివేయండి</string>\n    <string name=\"annotation_link\">హైపర్‌లింక్‌లు</string>\n    <string name=\"annotation_file_attachment\">ఫైల్ జోడింపులు</string>\n    <string name=\"annotation_line\">లైన్లు</string>\n    <string name=\"annotation_popup\">పాపప్‌లు</string>\n    <string name=\"annotation_stamp\">స్టాంపులు</string>\n    <string name=\"annotation_shapes\">ఆకారాలు</string>\n    <string name=\"annotation_text\">టెక్స్ట్ నోట్స్</string>\n    <string name=\"annotation_text_markup\">టెక్స్ట్ మార్కప్</string>\n    <string name=\"annotation_widget\">ఫారమ్ ఫీల్డ్స్</string>\n    <string name=\"annotation_markup\">మార్కప్</string>\n    <string name=\"annotation_unknown\">తెలియదు</string>\n    <string name=\"annotations\">ఉల్లేఖనాలు</string>\n    <string name=\"ungroup\">సమూహాన్ని తీసివేయండి</string>\n    <string name=\"add_shadow_sub\">కాన్ఫిగర్ చేయగల రంగు మరియు ఆఫ్‌సెట్‌లతో లేయర్ వెనుక బ్లర్ షాడోని జోడించండి</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-th/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"app_closing\">การปิดแอป</string>\n    <string name=\"stay\">อยู่</string>\n    <string name=\"close\">ปิด</string>\n    <string name=\"reset_image\">รีเซ็ตภาพ</string>\n    <string name=\"add_tag\">เพิ่มแท็ก</string>\n    <string name=\"folder\">โฟลเดอร์เอาต์พุต</string>\n    <string name=\"def\">ค่าเริ่มต้น</string>\n    <string name=\"custom\">กำหนดเอง</string>\n    <string name=\"settings\">การตั้งค่า</string>\n    <string name=\"clipboard_paste_invalid_empty\">ไม่มีอะไรจะวาง</string>\n    <string name=\"primary\">หลัก</string>\n    <string name=\"tertiary\">ตติยภูมิ</string>\n    <string name=\"monet_colors\">สีโมเน่ต์</string>\n    <string name=\"donation_sub\">แอปพลิเคชันนี้ไม่มีค่าใช้จ่ายใด ๆ แต่ถ้าคุณต้องการสนับสนุนการพัฒนาโครงการ คุณสามารถคลิกที่นี่</string>\n    <string name=\"fab_alignment\">การจัดตำแหน่ง FAB</string>\n    <string name=\"check_updates\">ตรวจสอบสำหรับการอัพเดต</string>\n    <string name=\"check_updates_sub\">หากเปิดใช้งาน กล่องโต้ตอบการอัปเดตจะแสดงให้คุณเห็นหลังจากเริ่มต้นแอป</string>\n    <string name=\"zoom\">ซูมภาพ</string>\n    <string name=\"smth_went_wrong\">เกิดข้อผิดพลาด: %1$s</string>\n    <string name=\"size\">ขนาด %1$s</string>\n    <string name=\"loading\">กำลังโหลด…</string>\n    <string name=\"image_too_large_preview\">รูปภาพมีขนาดใหญ่เกินไปที่จะดูตัวอย่าง แต่จะพยายามบันทึกต่อไป</string>\n    <string name=\"pick_image\">เลือกรูปภาพเพื่อเริ่มต้น</string>\n    <string name=\"width\">ความกว้าง %1$s</string>\n    <string name=\"height\">ความสูง %1$s</string>\n    <string name=\"quality\">คุณภาพ</string>\n    <string name=\"extension\">ส่วนขยาย</string>\n    <string name=\"resize_type\">ประเภทการปรับขนาด</string>\n    <string name=\"explicit\">ชัดเจน</string>\n    <string name=\"flexible\">ยืดหยุ่นได้</string>\n    <string name=\"pick_image_alt\">เลือกรูปภาพ</string>\n    <string name=\"reset_image_sub\">การเปลี่ยนแปลงรูปภาพจะถูกย้อนกลับเป็นค่าเริ่มต้น</string>\n    <string name=\"app_closing_sub\">คุณต้องการปิดแอปจริงๆ หรือไม่?</string>\n    <string name=\"values_reset\">รีเซ็ตค่าอย่างถูกต้อง</string>\n    <string name=\"reset\">รีเซ็ต</string>\n    <string name=\"something_went_wrong\">บางอย่างผิดพลาด</string>\n    <string name=\"restart_app\">รีสตาร์ทแอป</string>\n    <string name=\"copied\">คัดลอกไปที่คลิปบอร์ดแล้ว</string>\n    <string name=\"exception\">ข้อยกเว้น</string>\n    <string name=\"edit_exif\">แก้ไข EXIF</string>\n    <string name=\"ok\">ตกลง</string>\n    <string name=\"no_exif\">ไม่พบข้อมูล EXIF</string>\n    <string name=\"save\">บันทึก</string>\n    <string name=\"clear\">ชัดเจน</string>\n    <string name=\"clear_exif\">ล้าง EXIF</string>\n    <string name=\"cancel\">ยกเลิก</string>\n    <string name=\"clear_exif_sub\">ข้อมูล EXIF ทั้งหมดของรูปภาพจะถูกล้าง การดำเนินการนี้ไม่สามารถยกเลิกได้!</string>\n    <string name=\"presets\">ค่าที่ตั้งไว้ล่วงหน้า</string>\n    <string name=\"crop\">ครอบตัด</string>\n    <string name=\"image_not_saved\">ประหยัด</string>\n    <string name=\"image_not_saved_sub\">การเปลี่ยนแปลงที่ไม่ได้บันทึกทั้งหมดจะหายไป หากคุณออกตอนนี้</string>\n    <string name=\"check_source_code\">รหัสแหล่งที่มา</string>\n    <string name=\"check_source_code_sub\">รับข้อมูลอัปเดตล่าสุด หารือเกี่ยวกับปัญหา และอื่นๆ</string>\n    <string name=\"single_edit\">ปรับขนาดเดียว</string>\n    <string name=\"single_edit_sub\">เปลี่ยนข้อกำหนดของภาพเดียวที่กำหนด</string>\n    <string name=\"pick_color\">เลือกสี</string>\n    <string name=\"pick_color_sub\">เลือกสีจากภาพ คัดลอกหรือแชร์</string>\n    <string name=\"image\">ภาพ</string>\n    <string name=\"color\">สี</string>\n    <string name=\"color_copied\">ทำสำเนาสีแล้ว</string>\n    <string name=\"crop_sub\">ครอบตัดรูปภาพไปยังขอบเขตใดก็ได้</string>\n    <string name=\"version\">รุ่น</string>\n    <string name=\"keep_exif\">เก็บ EXIF</string>\n    <string name=\"images\">ภาพ: %d</string>\n    <string name=\"change_preview\">เปลี่ยนการแสดงตัวอย่าง</string>\n    <string name=\"remove\">ลบ</string>\n    <string name=\"palette_sub\">สร้างแถบสีจากภาพที่กำหนด</string>\n    <string name=\"generate_palette\">สร้างจานสี</string>\n    <string name=\"palette\">จานสี</string>\n    <string name=\"update\">อัปเดต</string>\n    <string name=\"new_version\">รุ่นใหม่ %1$s</string>\n    <string name=\"unsupported_type\">ประเภทที่ไม่รองรับ: %1$s</string>\n    <string name=\"no_palette\">ไม่สามารถสร้างจานสีสำหรับภาพที่กำหนด</string>\n    <string name=\"original\">ต้นฉบับ</string>\n    <string name=\"unspecified\">ไม่ระบุ</string>\n    <string name=\"device_storage\">ที่เก็บข้อมูลอุปกรณ์</string>\n    <string name=\"by_bytes_resize\">ปรับขนาดตามน้ำหนัก</string>\n    <string name=\"max_bytes\">ขนาดสูงสุดเป็น KB</string>\n    <string name=\"by_bytes_resize_sub\">ปรับขนาดรูปภาพตามขนาดที่กำหนดเป็น KB</string>\n    <string name=\"compare\">เปรียบเทียบ</string>\n    <string name=\"compare_sub\">เปรียบเทียบสองภาพที่กำหนด</string>\n    <string name=\"pick_two_images\">เลือกสองภาพเพื่อเริ่มต้น</string>\n    <string name=\"pick_images\">เลือกภาพ</string>\n    <string name=\"night_mode\">โหมดกลางคืน</string>\n    <string name=\"dark\">มืด</string>\n    <string name=\"light\">แสงสว่าง</string>\n    <string name=\"system\">ระบบ</string>\n    <string name=\"dynamic_colors\">สีแบบไดนามิก</string>\n    <string name=\"customization\">การปรับแต่ง</string>\n    <string name=\"allow_image_monet\">อนุญาตภาพเงิน</string>\n    <string name=\"allow_image_monet_sub\">หากเปิดใช้งาน เมื่อคุณเลือกภาพที่จะแก้ไข สีของแอพจะถูกนำไปใช้กับภาพนี้</string>\n    <string name=\"language\">ภาษา</string>\n    <string name=\"amoled_mode\">โหมด Amoled</string>\n    <string name=\"amoled_mode_sub\">หากเปิดใช้งานสีพื้นผิวจะถูกตั้งค่าเป็นโหมดมืดสนิทในโหมดกลางคืน</string>\n    <string name=\"color_scheme\">รูปแบบสี</string>\n    <string name=\"color_red\">สีแดง</string>\n    <string name=\"color_green\">สีเขียว</string>\n    <string name=\"color_blue\">สีฟ้า</string>\n    <string name=\"clipboard_paste_invalid_color_code\">วางรหัส RGB ที่ถูกต้อง</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">ไม่สามารถเปลี่ยนรูปแบบสีของแอพได้ในขณะที่เปิดสีไดนามิก</string>\n    <string name=\"pick_accent_color\">ธีมของแอพจะขึ้นอยู่กับสีซึ่งคุณจะเลือก</string>\n    <string name=\"about_app\">เกี่ยวกับแอพ</string>\n    <string name=\"no_updates\">ไม่พบการอัปเดต</string>\n    <string name=\"issue_tracker\">ตัวติดตามปัญหา</string>\n    <string name=\"issue_tracker_sub\">ส่งรายงานข้อผิดพลาดและคำขอคุณสมบัติที่นี่</string>\n    <string name=\"help_translate\">ช่วยแปล</string>\n    <string name=\"help_translate_sub\">แก้ไขข้อผิดพลาดในการแปลหรือแปลโครงการเป็นภาษาอื่น</string>\n    <string name=\"nothing_found_by_search\">ไม่พบการค้นหาของคุณ</string>\n    <string name=\"search_here\">ค้นหาที่นี่</string>\n    <string name=\"dynamic_colors_sub\">หากเปิดใช้งาน สีของแอพจะถูกนำไปใช้กับสีวอลเปเปอร์</string>\n    <string name=\"failed_to_save\">บันทึกภาพ %d ไม่สำเร็จ</string>\n    <string name=\"secondary\">รอง</string>\n    <string name=\"border_thickness\">ความหนาของเส้นขอบ</string>\n    <string name=\"surface\">พื้นผิว</string>\n    <string name=\"values\">ค่า</string>\n    <string name=\"add\">เพิ่ม</string>\n    <string name=\"permission\">การอนุญาต</string>\n    <string name=\"grant\">ยินยอม</string>\n    <string name=\"permission_sub\">แอปจำเป็นต้องเข้าถึงพื้นที่เก็บข้อมูลของคุณเพื่อบันทึกภาพ ซึ่งจำเป็น หากไม่สามารถทำงานได้ ดังนั้นโปรดให้สิทธิ์ในกล่องโต้ตอบถัดไป</string>\n    <string name=\"grant_permission_manual\">แอปต้องการการอนุญาตนี้จึงจะทำงานได้ โปรดอนุญาตด้วยตนเอง</string>\n    <string name=\"external_storage\">จัดเก็บข้อมูลภายนอก</string>\n    <string name=\"share\">แบ่งปัน</string>\n    <string name=\"prefix\">คำนำหน้า</string>\n    <string name=\"filename\">ชื่อไฟล์</string>\n    <string name=\"exposure\">การรับสัมผัสเชื้อ</string>\n    <string name=\"white_balance\">สมดุลสีขาว</string>\n    <string name=\"temperature\">อุณหภูมิ</string>\n    <string name=\"gamma\">แกมมา</string>\n    <string name=\"highlights_shadows\">ไฮไลท์และเงา</string>\n    <string name=\"sharpen\">เหลา</string>\n    <string name=\"crosshatch\">ครอสแฮทช์</string>\n    <string name=\"spacing\">ระยะห่าง</string>\n    <string name=\"line_width\">ความกว้างของเส้น</string>\n    <string name=\"add_file_size\">เพิ่มขนาดไฟล์</string>\n    <string name=\"delete_exif\">ลบ EXIF</string>\n    <string name=\"load_image_from_net\">โหลดรูปจากเน็ต</string>\n    <string name=\"color_filter\">ฟิลเตอร์สี</string>\n    <string name=\"negative\">เชิงลบ</string>\n    <string name=\"vibrance\">ความสั่นสะเทือน</string>\n    <string name=\"black_and_white\">ดำและขาว</string>\n    <string name=\"sobel_edge\">ขอบโซเบล</string>\n    <string name=\"blur\">เบลอ</string>\n    <string name=\"laplacian\">ลาปลาเซียน</string>\n    <string name=\"distortion\">การบิดเบือน</string>\n    <string name=\"radius\">รัศมี</string>\n    <string name=\"scale\">มาตราส่วน</string>\n    <string name=\"limits_resize\">จำกัดการปรับขนาด</string>\n    <string name=\"emoji\">อีโมจิ</string>\n    <string name=\"fast_blur\">เบลออย่างรวดเร็ว</string>\n    <string name=\"blur_size\">ขนาดเบลอ</string>\n    <string name=\"blur_center_x\">ศูนย์เบลอ x</string>\n    <string name=\"blur_center_y\">ศูนย์เบลอ y</string>\n    <string name=\"zoom_blur\">ซูมเบลอ</string>\n    <string name=\"luminance_threshold\">เกณฑ์ความสว่าง</string>\n    <string name=\"add_file_size_sub\">หากเปิดใช้ ให้เพิ่มความกว้างและความสูงของภาพที่บันทึกไว้ในชื่อไฟล์ที่ส่งออก</string>\n    <string name=\"delete_exif_sub\">ลบข้อมูลเมตา EXIF ออกจากภาพสองสามภาพ</string>\n    <string name=\"file_explorer_picker\">ตัวสำรวจไฟล์</string>\n    <string name=\"photo_picker_sub\">เครื่องมือเลือกรูปภาพที่ทันสมัยของ Android ซึ่งปรากฏที่ด้านล่างของหน้าจอ อาจใช้งานได้กับ Android 12+ เท่านั้น และยังมีปัญหาเกี่ยวกับการรับข้อมูลเมตา EXIF</string>\n    <string name=\"gallery_picker_sub\">เครื่องมือเลือกรูปภาพในแกลเลอรีอย่างง่ายจะทำงานได้ก็ต่อเมื่อคุณมีแอปนั้น</string>\n    <string name=\"options_arrangement\">การจัดตัวเลือก</string>\n    <string name=\"edit\">แก้ไข</string>\n    <string name=\"order\">คำสั่ง</string>\n    <string name=\"order_sub\">กำหนดลำดับของตัวเลือกบนหน้าจอหลัก</string>\n    <string name=\"replace_sequence_number\">แทนที่หมายเลขลำดับ</string>\n    <string name=\"replace_sequence_number_sub\">หากเปิดใช้งาน จะแทนที่การประทับเวลามาตรฐานเป็นหมายเลขลำดับภาพ หากคุณใช้การประมวลผลเป็นชุด</string>\n    <string name=\"load_image_from_net_sub\">โหลดรูปภาพจากอินเทอร์เน็ต ดูตัวอย่าง ซูม และบันทึกหรือแก้ไขหากคุณต้องการ</string>\n    <string name=\"no_image\">ไม่มีรูป</string>\n    <string name=\"image_link\">ลิงค์รูปภาพ</string>\n    <string name=\"fill\">เติม</string>\n    <string name=\"fit\">พอดี</string>\n    <string name=\"explicit_description\">บังคับให้ทุกภาพเป็นภาพที่กำหนดโดยพารามิเตอร์ความกว้างและความสูง - อาจเปลี่ยนอัตราส่วนกว้างยาว</string>\n    <string name=\"flexible_description\">ปรับขนาดรูปภาพเป็นภาพที่มีด้านยาวที่กำหนดโดยพารามิเตอร์ความกว้างหรือความสูง การคำนวณขนาดทั้งหมดจะทำหลังจากบันทึก - คงอัตราส่วนไว้</string>\n    <string name=\"brightness\">ความสว่าง</string>\n    <string name=\"contrast\">ตัดกัน</string>\n    <string name=\"hue\">เว้</string>\n    <string name=\"saturation\">ความอิ่มตัว</string>\n    <string name=\"add_filter\">เพิ่มตัวกรอง</string>\n    <string name=\"filter\">กรอง</string>\n    <string name=\"filter_sub\">ใช้ห่วงโซ่ตัวกรองกับภาพที่กำหนด</string>\n    <string name=\"filters\">ตัวกรอง</string>\n    <string name=\"light_aka_illumination\">แสงสว่าง</string>\n    <string name=\"alpha\">อัลฟ่า</string>\n    <string name=\"tint\">สีอ่อน</string>\n    <string name=\"monochrome\">ขาวดำ</string>\n    <string name=\"highlights\">ไฮไลท์</string>\n    <string name=\"shadows\">เงา</string>\n    <string name=\"haze\">หมอกควัน</string>\n    <string name=\"effect\">ผล</string>\n    <string name=\"distance\">ระยะทาง</string>\n    <string name=\"slope\">ความลาดชัน</string>\n    <string name=\"sepia\">ซีเปีย</string>\n    <string name=\"solarize\">โซลาไรซ์</string>\n    <string name=\"halftone\">ฮาล์ฟโทน</string>\n    <string name=\"cga_colorspace\">GCA คัลเลอร์สเปซ</string>\n    <string name=\"gaussian_blur\">เกาส์เบลอ</string>\n    <string name=\"box_blur\">กล่องเบลอ</string>\n    <string name=\"bilaterial_blur\">เบลอแบบทวิภาคี</string>\n    <string name=\"emboss\">นูน</string>\n    <string name=\"vignette\">บทความสั้น</string>\n    <string name=\"start\">เริ่ม</string>\n    <string name=\"end\">จบ</string>\n    <string name=\"kuwahara\">คุวาฮาระปรับให้เรียบ</string>\n    <string name=\"angle\">มุม</string>\n    <string name=\"swirl\">หมุน</string>\n    <string name=\"bulge\">นูน</string>\n    <string name=\"dilation\">การขยาย</string>\n    <string name=\"sphere_refraction\">การหักเหของทรงกลม</string>\n    <string name=\"refractive_index\">ดัชนีหักเห</string>\n    <string name=\"glass_sphere_refraction\">การหักเหของทรงกลมแก้ว</string>\n    <string name=\"color_matrix\">เมทริกซ์สี</string>\n    <string name=\"opacity\">ความทึบ</string>\n    <string name=\"limits_resize_sub\">ปรับขนาดรูปภาพที่กำหนดตามขีดจำกัดความกว้างและความสูงที่กำหนดพร้อมบันทึกอัตราส่วนภาพ</string>\n    <string name=\"sketch\">ร่าง</string>\n    <string name=\"threshold\">เกณฑ์</string>\n    <string name=\"quantizationLevels\">ระดับปริมาณ</string>\n    <string name=\"smooth_toon\">ตูนเนียน</string>\n    <string name=\"toon\">ตูน</string>\n    <string name=\"posterize\">โปสเตอร์</string>\n    <string name=\"non_maximum_suppression\">การปราบปรามไม่สูงสุด</string>\n    <string name=\"weak_pixel_inclusion\">การรวมพิกเซลที่อ่อนแอ</string>\n    <string name=\"lookup\">ค้นหา</string>\n    <string name=\"emoji_sub\">เลือกอีโมจิที่จะแสดงบนหน้าจอหลัก</string>\n    <string name=\"stack_blur\">ซ้อนภาพเบลอ</string>\n    <string name=\"convolution3x3\">คอนโวลูชั่น 3x3</string>\n    <string name=\"rgb_filter\">ตัวกรอง RGB</string>\n    <string name=\"false_color\">สีเท็จ</string>\n    <string name=\"first_color\">สีแรก</string>\n    <string name=\"second_color\">สีที่สอง</string>\n    <string name=\"reorder\">จัดลำดับใหม่</string>\n    <string name=\"color_balance\">ความสมดุลของสี</string>\n    <string name=\"image_preview\">ภาพตัวอย่าง</string>\n    <string name=\"image_preview_sub\">ดูตัวอย่างรูปภาพประเภทใดก็ได้: GIF, SVG และอื่นๆ</string>\n    <string name=\"image_source\">ที่มาของภาพ</string>\n    <string name=\"photo_picker\">เครื่องมือเลือกรูปภาพ</string>\n    <string name=\"gallery_picker\">แกลลอรี่</string>\n    <string name=\"file_explorer_picker_sub\">ใช้ความตั้งใจของ GetContent ในการเลือกภาพ ทำงานได้ทุกที่ แต่อาจมีปัญหาในการรับภาพที่เลือกบนอุปกรณ์บางอย่าง นั่นไม่ใช่ความผิดของฉัน</string>\n    <string name=\"content_scale\">ขนาดเนื้อหา</string>\n    <string name=\"emojis_count\">อิโมจินับ</string>\n    <string name=\"sequence_num\">ลำดับหมายเลข</string>\n    <string name=\"original_filename\">ชื่อไฟล์ต้นฉบับ</string>\n    <string name=\"add_original_filename\">เพิ่มชื่อไฟล์ต้นฉบับ</string>\n    <string name=\"add_original_filename_sub\">หากเปิดใช้งาน ให้เพิ่มชื่อไฟล์ต้นฉบับในชื่อของภาพที่ส่งออก</string>\n    <string name=\"filename_not_work_with_photopicker\">การเพิ่มชื่อไฟล์ต้นฉบับไม่ทำงานหากเลือกแหล่งที่มาของรูปภาพในเครื่องมือเลือกรูปภาพ</string>\n    <string name=\"compatibility\">ความเข้ากันได้</string>\n    <string name=\"found_s\">พบ %1$s</string>\n    <string name=\"draw_sub\">วาดภาพเหมือนในสมุดสเก็ตช์หรือวาดบนพื้นหลังเอง</string>\n    <string name=\"paint_color\">สีเพ้นท์</string>\n    <string name=\"paint_alpha\">ทาสีอัลฟ่า</string>\n    <string name=\"draw_on_image\">วาดภาพ</string>\n    <string name=\"draw_on_image_sub\">เลือกภาพและวาดบางอย่างลงไป</string>\n    <string name=\"draw_on_background_sub\">เลือกสีพื้นหลังและวาดทับลงไป</string>\n    <string name=\"draw_on_background\">วาดบนพื้นหลัง</string>\n    <string name=\"background_color\">สีพื้นหลัง</string>\n    <string name=\"cipher\">รหัส</string>\n    <string name=\"decryption\">ถอดรหัส</string>\n    <string name=\"key\">สำคัญ</string>\n    <string name=\"cache_size\">ขนาดแคช</string>\n    <string name=\"auto_cache_clearing\">การล้างแคชอัตโนมัติ</string>\n    <string name=\"copy\">สำเนา</string>\n    <string name=\"skip\">ข้าม</string>\n    <string name=\"warning_bytes\">การบันทึกในโหมด %1$s อาจไม่เสถียร เนื่องจากเป็นรูปแบบที่ไม่สูญเสียข้อมูล</string>\n    <string name=\"cache\">แคช</string>\n    <string name=\"secondary_customization\">การปรับแต่งรอง</string>\n    <string name=\"activate_files\">คุณปิดใช้งานแอพ Files เปิดใช้งานเพื่อใช้คุณสมบัตินี้</string>\n    <string name=\"invalid_password_or_not_encrypted\">รหัสผ่านไม่ถูกต้องหรือไฟล์ที่เลือกไม่ถูกเข้ารหัส</string>\n    <string name=\"cipher_sub\">เข้ารหัสและถอดรหัสไฟล์ใด ๆ (ไม่ใช่เฉพาะรูปภาพ) ตามอัลกอริทึมการเข้ารหัส AES</string>\n    <string name=\"encryption\">การเข้ารหัส</string>\n    <string name=\"features\">คุณสมบัติ</string>\n    <string name=\"file_size_sub\">ขนาดไฟล์สูงสุดถูกจำกัดโดยระบบปฏิบัติการ Android และหน่วยความจำที่มี ซึ่งขึ้นอยู่กับอุปกรณ์ของคุณ \\nโปรดทราบ: หน่วยความจำไม่ใช่ที่เก็บข้อมูล</string>\n    <string name=\"image_size_warning\">การพยายามบันทึกรูปภาพด้วยความกว้างและความสูงที่กำหนดอาจทำให้เกิดข้อผิดพลาด OOM คุณต้องยอมรับความเสี่ยงเอง และอย่าหาว่าฉันไม่เตือนคุณ!</string>\n    <string name=\"auto_cache_clearing_sub\">หากเปิดใช้งานแคชของแอปจะถูกล้างเมื่อเริ่มต้นแอป</string>\n    <string name=\"screenshot\">ภาพหน้าจอ</string>\n    <string name=\"fallback_option\">ตัวเลือกสำรอง</string>\n    <string name=\"draw\">วาด</string>\n    <string name=\"pick_file\">เลือกไฟล์</string>\n    <string name=\"encrypt\">เข้ารหัส</string>\n    <string name=\"decrypt\">ถอดรหัส</string>\n    <string name=\"pick_file_to_start\">เลือกไฟล์เพื่อเริ่มต้น</string>\n    <string name=\"store_file_desc\">จัดเก็บไฟล์นี้บนอุปกรณ์ของคุณหรือใช้การดำเนินการแชร์เพื่อวางไว้ทุกที่ที่คุณต้องการ</string>\n    <string name=\"implementation\">การดำเนินการ</string>\n    <string name=\"implementation_sub\">AES-256, โหมด GCM, ไม่มีการเติม, IV แบบสุ่ม 12 ไบต์ คีย์ใช้เป็นแฮช SHA-3 (256 บิต)</string>\n    <string name=\"file_size\">ขนาดไฟล์</string>\n    <string name=\"compatibility_sub\">โปรดทราบว่าไม่รับประกันความเข้ากันได้กับซอฟต์แวร์หรือบริการเข้ารหัสไฟล์อื่นๆ การรักษาคีย์ที่แตกต่างกันเล็กน้อยหรือการกำหนดค่ารหัสอาจเป็นสาเหตุของความเข้ากันไม่ได้</string>\n    <string name=\"features_sub\">การเข้ารหัสไฟล์โดยใช้รหัสผ่าน ไฟล์ที่ดำเนินการแล้วสามารถเก็บไว้ในไดเร็กทอรีที่เลือกหรือใช้ร่วมกัน สามารถเปิดไฟล์ที่ถอดรหัสได้โดยตรง</string>\n    <string name=\"file_proceed\">ประมวลผลไฟล์แล้ว</string>\n    <string name=\"tools\">เครื่องมือ</string>\n    <string name=\"group_options_by_type\">จัดกลุ่มตัวเลือกตามประเภท</string>\n    <string name=\"group_options_by_type_sub\">ตัวเลือกการจัดกลุ่มบนหน้าจอหลักของประเภทแทนการจัดเรียงรายการแบบกำหนดเอง</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">ไม่สามารถเปลี่ยนการจัดเรียงในขณะที่เปิดใช้งานการจัดกลุ่มตัวเลือก</string>\n    <string name=\"create\">สร้าง</string>\n    <string name=\"edit_screenshot\">แก้ไขภาพหน้าจอ</string>\n    <string name=\"enhanced_pixelation\">พิกเซลที่ได้รับการปรับปรุง</string>\n    <string name=\"stroke_pixelation\">การเกิดพิกเซลแบบสโตรค</string>\n    <string name=\"defaultt\">ค่าเริ่มต้น</string>\n    <string name=\"enhanced_glitch\">ความผิดพลาดที่เพิ่มขึ้น</string>\n    <string name=\"channel_shift_y\">การเปลี่ยนช่อง Y</string>\n    <string name=\"side_fade\">ซีดข้าง</string>\n    <string name=\"draw_arrows\">วาดลูกศร</string>\n    <string name=\"brush_softness\">ความนุ่มนวลของแปรง</string>\n    <string name=\"analytics_sub\">อนุญาตให้รวบรวมสถิติการใช้งานแอปที่ไม่ระบุชื่อ</string>\n    <string name=\"saved_to\">บันทึกไปยัง %1$s โฟลเดอร์ชื่อ %2$s</string>\n    <string name=\"effort\">ความพยายาม</string>\n    <string name=\"randomize_filename\">สุ่มชื่อไฟล์</string>\n    <string name=\"objects\">วัตถุ</string>\n    <string name=\"using_large_fonts_warn\">การใช้ขนาดตัวอักษรขนาดใหญ่อาจทำให้เกิดข้อผิดพลาดและปัญหา UI ซึ่งจะไม่ได้รับการแก้ไข ใช้ด้วยความระมัดระวัง</string>\n    <string name=\"donation\">บริจาค</string>\n    <string name=\"travels_and_places\">การเดินทางและสถานที่</string>\n    <string name=\"updates\">อัพเดท</string>\n    <string name=\"segmentation_mode_osd_only\">การวางแนว &amp; การตรวจจับสคริปต์เท่านั้น</string>\n    <string name=\"segmentation_mode_auto_osd\">การวางแนวอัตโนมัติ &amp; การตรวจจับสคริปต์</string>\n    <string name=\"segmentation_mode_auto_only\">อัตโนมัติเท่านั้น</string>\n    <string name=\"segmentation_mode_auto\">อัตโนมัติ</string>\n    <string name=\"segmentation_mode_single_column\">คอลัมน์เดียว</string>\n    <string name=\"segmentation_mode_single_block\">บล็อคเดียว</string>\n    <string name=\"segmentation_mode_single_word\">คำเดียว</string>\n    <string name=\"segmentation_mode_sparse_text\">ข้อความกระจัดกระจาย</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">การวางแนวข้อความกระจัดกระจาย &amp; การตรวจจับสคริปต์</string>\n    <string name=\"segmentation_mode_raw_line\">เส้นดิบ</string>\n    <string name=\"glitch\">ความผิดพลาด</string>\n    <string name=\"amount\">จำนวน</string>\n    <string name=\"anaglyph\">แอนากลิฟ</string>\n    <string name=\"noise\">เสียงรบกวน</string>\n    <string name=\"pixel_sort\">การเรียงลำดับพิกเซล</string>\n    <string name=\"shuffle\">สับเปลี่ยน</string>\n    <string name=\"mobius\">โมเบียส</string>\n    <string name=\"no_such_directory\">ไม่พบไดเรกทอรี \\\"%1$s\\\" เราได้เปลี่ยนเป็นไดเรกทอรีเริ่มต้นแล้ว โปรดบันทึกไฟล์อีกครั้ง</string>\n    <string name=\"clipboard\">คลิปบอร์ด</string>\n    <string name=\"auto_pin\">พินอัตโนมัติ</string>\n    <string name=\"auto_pin_sub\">เพิ่มภาพที่บันทึกไว้ลงในคลิปบอร์ดโดยอัตโนมัติหากเปิดใช้งาน</string>\n    <string name=\"overwrite_file_requirements\">หากต้องการเขียนทับไฟล์ คุณต้องใช้แหล่งรูปภาพ \\\"Explorer\\\" ลองเลือกรูปภาพใหม่ เราได้เปลี่ยนแหล่งรูปภาพเป็นแหล่งที่ต้องการ</string>\n    <string name=\"overwrite_files\">เขียนทับไฟล์</string>\n    <string name=\"empty\">ว่างเปล่า</string>\n    <string name=\"suffix\">คำต่อท้าย</string>\n    <string name=\"search_option\">ค้นหา</string>\n    <string name=\"search_option_sub\">ช่วยให้สามารถค้นหาตัวเลือกที่มีอยู่ทั้งหมดบนหน้าจอหลักได้</string>\n    <string name=\"free\">ฟรี</string>\n    <string name=\"images_overwritten\">รูปภาพถูกเขียนทับที่ปลายทางเดิม</string>\n    <string name=\"emoji_as_color_scheme\">อิโมจิเป็นโครงร่างสี</string>\n    <string name=\"backup_sub\">สำรองการตั้งค่าแอปของคุณเป็นไฟล์</string>\n    <string name=\"presets_sub\" formatted=\"false\">หากคุณเลือกค่าที่ตั้งไว้ล่วงหน้า 125 รูปภาพจะถูกบันทึกเป็นขนาด 125% ของรูปภาพต้นฉบับพร้อมคุณภาพ 100% หากคุณเลือกค่าที่ตั้งล่วงหน้า 50 รูปภาพจะถูกบันทึกด้วยขนาด 50% และคุณภาพ 50%</string>\n    <string name=\"randomize_filename_sub\">หากเปิดใช้งานชื่อไฟล์เอาต์พุตจะเป็นการสุ่มอย่างสมบูรณ์</string>\n    <string name=\"presets_sub_bytes\">การตั้งค่าล่วงหน้าที่นี่จะกำหนด % ของไฟล์เอาต์พุต เช่น หากคุณเลือกการตั้งค่าล่วงหน้า 50 บนรูปภาพขนาด 5mb คุณจะได้รูปภาพขนาด 2.5mb หลังจากบันทึก</string>\n    <string name=\"backup\">สำรองข้อมูล</string>\n    <string name=\"restore_sub\">คืนค่าการตั้งค่าแอปจากไฟล์ที่สร้างไว้ก่อนหน้านี้</string>\n    <string name=\"corrupted_file_or_not_a_backup\">ไฟล์เสียหายหรือไม่ใช่ข้อมูลสำรอง</string>\n    <string name=\"settings_restored\">กู้คืนการตั้งค่าเรียบร้อยแล้ว</string>\n    <string name=\"contact_me\">ติดต่อฉัน</string>\n    <string name=\"font\">แบบอักษร</string>\n    <string name=\"text\">ข้อความ</string>\n    <string name=\"font_scale\">ขนาดตัวอักษร</string>\n    <string name=\"alphabet_and_numbers\">ก ข ฃ ค ฅ ฆ ง จ ฉ ช ซ ฌ ญ ฎ ฏ ฐ ฑ ฒ ณ ด ต ถ ท ธ น บ ป ผ ฝ พ ฟ ภ ม ย ร ล ว ศ ษ ส ห ฬ อ ฮ 0123456789 !?</string>\n    <string name=\"activities\">กิจกรรม</string>\n    <string name=\"background_remover\">เครื่องมือลบพื้นหลัง</string>\n    <string name=\"background_remover_sub\">ลบพื้นหลังออกจากภาพโดยการวาดหรือใช้ตัวเลือกอัตโนมัติ</string>\n    <string name=\"trim_image\">ตัดภาพ</string>\n    <string name=\"auto_erase_background\">ลบพื้นหลังอัตโนมัติ</string>\n    <string name=\"erase_mode\">โหมดลบ</string>\n    <string name=\"erase_background\">ลบพื้นหลัง</string>\n    <string name=\"restore_background\">คืนค่าพื้นหลัง</string>\n    <string name=\"blur_radius\">รัศมีเบลอ</string>\n    <string name=\"draw_mode\">โหมดการวาด</string>\n    <string name=\"create_issue\">สร้างประเด็น</string>\n    <string name=\"something_went_wrong_emphasis\">อ๊ะ… มีบางอย่างผิดพลาด คุณสามารถเขียนถึงฉันโดยใช้ตัวเลือกด้านล่าง แล้วฉันจะพยายามหาทางแก้ไข</string>\n    <string name=\"resize_and_convert_sub\">เปลี่ยนขนาดของรูปภาพที่กำหนดหรือแปลงเป็นรูปแบบอื่น ข้อมูลเมตา EXIF สามารถแก้ไขได้ที่นี่หากเลือกภาพเดียว</string>\n    <string name=\"max_colors_count\">จำนวนสีสูงสุด</string>\n    <string name=\"crashlytics_sub\">ซึ่งช่วยให้แอปรวบรวมรายงานข้อขัดข้องด้วยตนเอง</string>\n    <string name=\"analytics\">การวิเคราะห์</string>\n    <string name=\"image_exif_warning\">ปัจจุบัน รูปแบบ %1$s อนุญาตให้อ่านเฉพาะข้อมูลเมตา EXIF บน Android เท่านั้น รูปภาพที่ส่งออกจะไม่มีข้อมูลเมตาเลยเมื่อบันทึก</string>\n    <string name=\"effort_sub\">ค่า %1$s หมายถึงการบีบอัดที่รวดเร็ว ส่งผลให้ขนาดไฟล์ค่อนข้างใหญ่ %2$s หมายถึงการบีบอัดที่ช้าลง ส่งผลให้ไฟล์มีขนาดเล็กลง</string>\n    <string name=\"wait\">รอ</string>\n    <string name=\"saving_almost_complete\">ออมทรัพย์ใกล้จะสมบูรณ์แล้ว การยกเลิกตอนนี้จะต้องบันทึกอีกครั้ง</string>\n    <string name=\"allow_betas\">อนุญาตเบต้า</string>\n    <string name=\"allow_betas_sub\">การตรวจสอบการอัปเดตจะรวมแอปเวอร์ชันเบต้าด้วยหากเปิดใช้งาน</string>\n    <string name=\"draw_arrows_sub\">หากเปิดใช้งานเส้นทางการวาดภาพจะแสดงเป็นลูกศรชี้</string>\n    <string name=\"crop_description\">รูปภาพจะถูกครอบตัดตรงกลางตามขนาดที่ป้อน แคนวาสจะถูกขยายด้วยสีพื้นหลังที่กำหนดหากรูปภาพมีขนาดเล็กกว่าขนาดที่ป้อน</string>\n    <string name=\"scale_small_images_to_large\">ปรับขนาดภาพเล็กให้เป็นภาพใหญ่</string>\n    <string name=\"scale_small_images_to_large_sub\">รูปภาพขนาดเล็กจะถูกปรับขนาดให้ใหญ่ที่สุดตามลำดับหากเปิดใช้งาน</string>\n    <string name=\"target_color\">สีเป้าหมาย</string>\n    <string name=\"color_to_remove\">สีที่จะลบ</string>\n    <string name=\"remove_color\">ลบสี</string>\n    <string name=\"recode\">เข้ารหัสใหม่</string>\n    <string name=\"palette_style\">สไตล์พาเลท</string>\n    <string name=\"tonal_spot\">จุดวรรณยุกต์</string>\n    <string name=\"neutral\">เป็นกลาง</string>\n    <string name=\"vibrant\">มีชีวิตชีวา</string>\n    <string name=\"expressive\">แสดงออก</string>\n    <string name=\"rainbow\">รุ้ง</string>\n    <string name=\"fruit_salad\">สลัดผลไม้</string>\n    <string name=\"fidelity\">ความจงรักภักดี</string>\n    <string name=\"content\">เนื้อหา</string>\n    <string name=\"tonal_spot_sub\">รูปแบบจานสีเริ่มต้น อนุญาตให้ปรับแต่งสีทั้งสี่สี ส่วนสไตล์อื่นๆ อนุญาตให้คุณตั้งค่าเฉพาะสีหลักเท่านั้น</string>\n    <string name=\"neutral_sub\">สไตล์ที่มีสีมากกว่าสีเดียวเล็กน้อย</string>\n    <string name=\"vibrant_sub\">ธีมที่ดัง สีสันเป็นสูงสุดสำหรับจานสีหลัก และเพิ่มขึ้นสำหรับจานสีอื่นๆ</string>\n    <string name=\"playful_scheme\">ธีมที่สนุกสนาน - สีของต้นฉบับไม่ปรากฏในธีม</string>\n    <string name=\"monochrome_sub\">ธีมขาวดำ มีสีดำ / ขาว / เทาล้วนๆ</string>\n    <string name=\"content_sub\">แบบแผนที่วางสีต้นฉบับใน Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">รูปแบบที่คล้ายกับรูปแบบเนื้อหามาก</string>\n    <string name=\"preview_pdf_sub\">ดูตัวอย่าง PDF อย่างง่าย</string>\n    <string name=\"pdf_to_images_sub\">แปลง PDF เป็นรูปภาพในรูปแบบเอาต์พุตที่กำหนด</string>\n    <string name=\"images_to_pdf_sub\">แพ็ครูปภาพที่กำหนดลงในไฟล์ PDF เอาท์พุต</string>\n    <string name=\"delete_mask_warn\">คุณกำลังจะลบมาสก์ตัวกรองที่เลือก การดำเนินการนี้ไม่สามารถยกเลิกได้</string>\n    <string name=\"privacy_blur\">ความเป็นส่วนตัวเบลอ</string>\n    <string name=\"highlighter_sub\">วาดเส้นทางปากกาเน้นข้อความที่คมชัดแบบกึ่งโปร่งใส</string>\n    <string name=\"neon_sub\">เพิ่มเอฟเฟกต์เรืองแสงให้กับภาพวาดของคุณ</string>\n    <string name=\"pen_sub\">ค่าเริ่มต้น ง่ายที่สุด - แค่สี</string>\n    <string name=\"privacy_blur_sub\">เบลอภาพใต้เส้นทางที่วาดเพื่อรักษาความปลอดภัยสิ่งที่คุณต้องการซ่อน</string>\n    <string name=\"pixelation_sub\">คล้ายกับการเบลอความเป็นส่วนตัว แต่เป็นพิกเซลแทนที่จะเบลอ</string>\n    <string name=\"app_bars_shadow_sub\">เปิดใช้งานการวาดเงาด้านหลังแถบแอป</string>\n    <string name=\"auto_rotate_limits_sub\">อนุญาตให้ใช้กล่องจำกัดสำหรับการวางแนวรูปภาพ</string>\n    <string name=\"arrow\">ลูกศร</string>\n    <string name=\"outlined_oval_sub\">วาดวงรีที่มีโครงร่างจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"outlined_rect_sub\">วาดโครงร่างเป็นเส้นตรงจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"vibration\">การสั่นสะเทือน</string>\n    <string name=\"vibration_strength\">ความแรงของการสั่นสะเทือน</string>\n    <string name=\"overwrite_files_sub\">ไฟล์ต้นฉบับจะถูกแทนที่ด้วยไฟล์ใหม่แทนที่จะบันทึกในโฟลเดอร์ที่เลือก ตัวเลือกนี้จะต้องแหล่งที่มาของรูปภาพเป็น \\\"Explorer\\\" หรือ GetContent เมื่อสลับสิ่งนี้ มันจะถูกตั้งค่าโดยอัตโนมัติ</string>\n    <string name=\"bilinear_sub\">โดยทั่วไปการประมาณค่าเชิงเส้น (หรือแบบไบลิเนียร์ในสองมิติ) มักจะดีสำหรับการเปลี่ยนขนาดของรูปภาพ แต่จะทำให้รายละเอียดอ่อนลงอย่างไม่พึงประสงค์และยังสามารถเป็นรอยหยักได้บ้าง</string>\n    <string name=\"bicubic_sub\">วิธีการปรับขนาดที่ดีกว่า ได้แก่ การสุ่มตัวอย่าง Lanczos และตัวกรอง Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">หนึ่งในวิธีที่ง่ายกว่าในการเพิ่มขนาด โดยแทนที่ทุกพิกเซลด้วยจำนวนพิกเซลที่มีสีเดียวกัน</string>\n    <string name=\"basic_sub\">โหมดปรับขนาด Android ที่ง่ายที่สุดที่ใช้ในแอพเกือบทั้งหมด</string>\n    <string name=\"hann_sub\">ฟังก์ชัน Windowing มักใช้ในการประมวลผลสัญญาณเพื่อลดการรั่วไหลของสเปกตรัมและปรับปรุงความแม่นยำของการวิเคราะห์ความถี่โดยการลดขอบของสัญญาณ</string>\n    <string name=\"hermite_sub\">เทคนิคการประมาณค่าทางคณิตศาสตร์ที่ใช้ค่าและอนุพันธ์ที่จุดสิ้นสุดของส่วนของเส้นโค้งเพื่อสร้างเส้นโค้งที่ราบรื่นและต่อเนื่อง</string>\n    <string name=\"saved_to_original\">ไฟล์ที่ถูกเขียนทับด้วยชื่อ %1$s ที่ปลายทางเดิม</string>\n    <string name=\"magnifier\">แว่นขยาย</string>\n    <string name=\"magnifier_sub\">เปิดใช้งานแว่นขยายที่ด้านบนของนิ้วในโหมดการวาดภาพเพื่อให้เข้าถึงได้ดีขึ้น</string>\n    <string name=\"force_exif_widget_initial_value\">บังคับค่าเริ่มต้น</string>\n    <string name=\"force_exif_widget_initial_value_sub\">บังคับให้มีการตรวจสอบวิดเจ็ต exif ในขั้นต้น</string>\n    <string name=\"allow_multiple_languages\">อนุญาตให้มีหลายภาษา</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">ข้อความแนวตั้งบล็อกเดียว</string>\n    <string name=\"segmentation_mode_single_line\">แถวเดียว</string>\n    <string name=\"segmentation_mode_circle_word\">วงกลมคำว่า</string>\n    <string name=\"segmentation_mode_single_char\">ถ่านตัวเดียว</string>\n    <string name=\"current\">ปัจจุบัน</string>\n    <string name=\"all\">ทั้งหมด</string>\n    <string name=\"watermarking_sub\">ครอบคลุมรูปภาพด้วยลายน้ำข้อความ/รูปภาพที่ปรับแต่งได้</string>\n    <string name=\"repeat_watermark\">ใส่ลายน้ำซ้ำ</string>\n    <string name=\"repeat_watermark_sub\">ทำซ้ำลายน้ำบนรูปภาพแทนที่จะเป็นลายน้ำเดียวในตำแหน่งที่กำหนด</string>\n    <string name=\"offset_x\">ออฟเซ็ต X</string>\n    <string name=\"offset_y\">ออฟเซ็ต Y</string>\n    <string name=\"watermark_type\">ประเภทลายน้ำ</string>\n    <string name=\"watermarking_image_sub\">รูปภาพนี้จะถูกใช้เป็นรูปแบบสำหรับลายน้ำ</string>\n    <string name=\"frame_delay\">ความล่าช้าของเฟรม</string>\n    <string name=\"millis\">มิลลิวินาที</string>\n    <string name=\"fps\">เฟรมต่อวินาที</string>\n    <string name=\"bayer_two_dithering\">ไบเออร์สองต่อสอง Dithering</string>\n    <string name=\"bayer_three_dithering\">ไบเออร์สามต่อสาม Dithering</string>\n    <string name=\"bayer_four_dithering\">ไบเออร์โฟร์บายโฟร์ไดเทอร์ริ่ง</string>\n    <string name=\"bayer_eight_dithering\">ไบเออร์แปดโดยแปด Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">ฟลอยด์ สไตน์เบิร์ก ดิเธอริง</string>\n    <string name=\"jarvis_judice_ninke_dithering\">จาร์วิส จูดิซ นินเก้ ดิเธอริง</string>\n    <string name=\"sierra_dithering\">เซียร์รา ดิเธอริง</string>\n    <string name=\"two_row_sierra_dithering\">Sierra Dithering สองแถว</string>\n    <string name=\"sierra_lite_dithering\">เซียร์รา ไลต์ ดิเธอริง</string>\n    <string name=\"atkinson_dithering\">แอตกินสัน ไดเทอร์ริ่ง</string>\n    <string name=\"burkes_dithering\">เบิร์กส์ ดิเธอริง</string>\n    <string name=\"median_blur\">ค่ามัธยฐานเบลอ</string>\n    <string name=\"b_spline_sub\">ใช้ฟังก์ชันพหุนาม bicubic ที่กำหนดเป็นชิ้นๆ เพื่อประมาณค่าเส้นโค้งหรือพื้นผิวได้อย่างราบรื่น การแสดงรูปร่างที่ยืดหยุ่นและต่อเนื่อง</string>\n    <string name=\"seed\">เมล็ดพันธุ์</string>\n    <string name=\"channel_shift_x\">ช่อง Shift X</string>\n    <string name=\"corruption_size\">ขนาดคอร์รัปชั่น</string>\n    <string name=\"corruption_shift_x\">คอร์รัปชัน ชิฟท์ X</string>\n    <string name=\"corruption_shift_y\">การคอร์รัปชั่น Shift Y</string>\n    <string name=\"tent_blur\">เต็นท์เบลอ</string>\n    <string name=\"side\">ด้านข้าง</string>\n    <string name=\"top\">สูงสุด</string>\n    <string name=\"bottom\">ด้านล่าง</string>\n    <string name=\"strength\">ความแข็งแกร่ง</string>\n    <string name=\"aces_hill_tone_mapping\">การทำแผนที่ ACES Hill Tone</string>\n    <string name=\"hable_filmic_tone_mapping\">การทำแผนที่โทนสีภาพยนตร์ Hable</string>\n    <string name=\"color_matrix_4x4\">เมทริกซ์สี 4x4</string>\n    <string name=\"color_matrix_3x3\">เมทริกซ์สี 3x3</string>\n    <string name=\"simple_effects\">เอฟเฟกต์ง่าย ๆ</string>\n    <string name=\"polaroid\">โพลารอยด์</string>\n    <string name=\"tritonomaly\">ไทรโทโนมาลี</string>\n    <string name=\"deutaromaly\">ดิวทาโรมาลี</string>\n    <string name=\"protonomaly\">โปรโตโนมาลี</string>\n    <string name=\"vintage\">วินเทจ</string>\n    <string name=\"browni\">บราวนี่</string>\n    <string name=\"coda_chrome\">โคด้า โครม</string>\n    <string name=\"night_vision\">การมองเห็นตอนกลางคืน</string>\n    <string name=\"warm\">อบอุ่น</string>\n    <string name=\"cool\">เย็น</string>\n    <string name=\"tritanopia\">ทริตาโนเปีย</string>\n    <string name=\"deutaronotopia\">ดิวตาโรโนโทเปีย</string>\n    <string name=\"achromatopsia\">อาการอะโครมาโทเซีย</string>\n    <string name=\"autumn_tones\">โทนสีฤดูใบไม้ร่วง</string>\n    <string name=\"cyberpunk\">ไซเบอร์พังค์</string>\n    <string name=\"lemonade_light\">น้ำมะนาวไลท์</string>\n    <string name=\"spectral_fire\">สเปกตรัมไฟ</string>\n    <string name=\"night_magic\">ไนท์เมจิก</string>\n    <string name=\"fantasy_landscape\">ภูมิทัศน์แฟนตาซี</string>\n    <string name=\"color_explosion\">การระเบิดของสี</string>\n    <string name=\"electric_gradient\">ไล่ระดับไฟฟ้า</string>\n    <string name=\"caramel_darkness\">คาราเมลความมืด</string>\n    <string name=\"futuristic_gradient\">การไล่ระดับสีแห่งอนาคต</string>\n    <string name=\"icon_shape_sub\">เพิ่มคอนเทนเนอร์ที่มีรูปร่างที่เลือกไว้ใต้ไอคอนนำหน้าของการ์ด</string>\n    <string name=\"drago\">ดราโก้</string>\n    <string name=\"aldridge\">อัลดริดจ์</string>\n    <string name=\"cutoff\">ทางลัด</string>\n    <string name=\"uchimura\">อุจิมูระ</string>\n    <string name=\"transition\">การเปลี่ยนแปลง</string>\n    <string name=\"peak\">จุดสูงสุด</string>\n    <string name=\"color_anomaly\">ความผิดปกติของสี</string>\n    <string name=\"cannot_change_image_format\">ไม่สามารถเปลี่ยนรูปแบบภาพในขณะที่เปิดใช้งานตัวเลือกการเขียนทับไฟล์</string>\n    <string name=\"emoji_as_color_scheme_sub\">ใช้สีหลักของอีโมจิเป็นรูปแบบสีของแอป แทนที่จะกำหนดด้วยตนเอง</string>\n    <string name=\"tg_chat\">แชทโทรเลข</string>\n    <string name=\"saved_to_without_filename\">บันทึกลงในโฟลเดอร์ %1$s แล้ว</string>\n    <string name=\"tg_chat_sub\">หารือเกี่ยวกับแอปและรับคำติชมจากผู้ใช้รายอื่น คุณยังรับการอัปเดตและข้อมูลเชิงลึกรุ่นเบต้าได้ที่นี่</string>\n    <string name=\"crop_mask\">หน้ากากครอบตัด</string>\n    <string name=\"image_crop_mask_sub\">ใช้มาสก์ประเภทนี้เพื่อสร้างมาสก์จากรูปภาพที่กำหนด โปรดทราบว่าควรมีช่องอัลฟ่า</string>\n    <string name=\"backup_and_restore\">สำรองและเรียกคืน</string>\n    <string name=\"restore\">คืนค่า</string>\n    <string name=\"reset_settings_sub\">นี่จะย้อนกลับการตั้งค่าของคุณกลับเป็นค่าเริ่มต้น โปรดสังเกตว่าการดำเนินการนี้ไม่สามารถยกเลิกได้หากไม่มีไฟล์สำรองที่กล่าวถึงข้างต้น</string>\n    <string name=\"delete_color_scheme_title\">ลบแบบแผน</string>\n    <string name=\"emotions\">อารมณ์</string>\n    <string name=\"food_and_drink\">อาหารและเครื่องดื่ม</string>\n    <string name=\"nature_and_animals\">ธรรมชาติและสัตว์</string>\n    <string name=\"symbols\">สัญลักษณ์</string>\n    <string name=\"keep_exif_sub\">ข้อมูลเมตาของรูปภาพต้นฉบับจะถูกเก็บไว้</string>\n    <string name=\"trim_image_sub\">พื้นที่โปร่งใสรอบๆ รูปภาพจะถูกตัดออก</string>\n    <string name=\"restore_image\">คืนค่ารูปภาพ</string>\n    <string name=\"pipette\">ปิเปต</string>\n    <string name=\"resize_and_convert\">ปรับขนาดและแปลง</string>\n    <string name=\"images_order\">ลำดับภาพ</string>\n    <string name=\"enhanced_diamond_pixelation\">พิกเซลเพชรที่ได้รับการปรับปรุง</string>\n    <string name=\"diamond_pixelation\">พิกเซลเพชร</string>\n    <string name=\"tolerance\">ความอดทน</string>\n    <string name=\"color_to_replace\">สีที่จะแทนที่</string>\n    <string name=\"erode\">กัดเซาะ</string>\n    <string name=\"anisotropic_diffusion\">การแพร่กระจายแบบแอนไอโซทรอปิก</string>\n    <string name=\"diffusion\">การแพร่กระจาย</string>\n    <string name=\"conduction\">การนำ</string>\n    <string name=\"horizontal_wind_stagger\">ลมโซเซแนวนอน</string>\n    <string name=\"fast_bilaterial_blur\">เบลอทวิภาคีอย่างรวดเร็ว</string>\n    <string name=\"poisson_blur\">ปัวซองเบลอ</string>\n    <string name=\"logarithmic_tone_mapping\">การทำแผนที่โทนลอการิทึม</string>\n    <string name=\"crystallize\">ตกผลึก</string>\n    <string name=\"stroke_color\">สีเส้นโครงร่าง</string>\n    <string name=\"fractal_glass\">แก้วแฟร็กทัล</string>\n    <string name=\"amplitude\">แอมพลิจูด</string>\n    <string name=\"marble\">หินอ่อน</string>\n    <string name=\"turbulence\">ความปั่นป่วน</string>\n    <string name=\"oil\">น้ำมัน</string>\n    <string name=\"water_effect\">เอฟเฟกต์น้ำ</string>\n    <string name=\"just_size\">ขนาด</string>\n    <string name=\"frequency_x\">ความถี่ X</string>\n    <string name=\"frequency_y\">ความถี่ Y</string>\n    <string name=\"amplitude_x\">แอมพลิจูด X</string>\n    <string name=\"amplitude_y\">แอมพลิจูด Y</string>\n    <string name=\"perlin_distortion\">การบิดเบือนของเพอร์ลิน</string>\n    <string name=\"heji_burgess_tone_mapping\">การทำแผนที่โทนของ Hejl Burgess</string>\n    <string name=\"aces_filmic_tone_mapping\">การทำแผนที่โทนสีภาพยนตร์ ACES</string>\n    <string name=\"delete_language_sub\">คุณต้องการลบข้อมูลการฝึกอบรม OCR ภาษา \\\"%1$s\\\" สำหรับการจดจำทุกประเภท หรือเฉพาะประเภทที่เลือก (%2$s) หรือไม่?</string>\n    <string name=\"full_filter\">ตัวกรองแบบเต็ม</string>\n    <string name=\"start_position\">เริ่ม</string>\n    <string name=\"full_filter_sub\">ใช้กลุ่มตัวกรองกับรูปภาพที่กำหนดหรือรูปภาพเดี่ยว</string>\n    <string name=\"pdf_to_images\">PDF เป็นรูปภาพ</string>\n    <string name=\"images_to_pdf\">รูปภาพเป็น PDF</string>\n    <string name=\"gradient_maker\">เครื่องไล่ระดับสี</string>\n    <string name=\"gradient_maker_sub\">สร้างการไล่ระดับสีของขนาดเอาต์พุตที่กำหนดด้วยสีและประเภทลักษณะที่กำหนดเอง</string>\n    <string name=\"speed\">ความเร็ว</string>\n    <string name=\"dehaze\">ลดหมอกควัน</string>\n    <string name=\"omega\">โอเมก้า</string>\n    <string name=\"pdf_tools\">เครื่องมือ PDF</string>\n    <string name=\"rate_app\">ให้คะแนนแอพ</string>\n    <string name=\"rate\">ประเมิน</string>\n    <string name=\"rate_app_sub\">แอพนี้ไม่มีค่าใช้จ่ายใดๆ ทั้งสิ้น หากคุณต้องการให้มันใหญ่ขึ้น โปรดติดดาวโปรเจ็กต์บน Github 😄</string>\n    <string name=\"protanopia\">โพรโทเปีย</string>\n    <string name=\"achromatomaly\">ความผิดปกติ</string>\n    <string name=\"gradient_type_linear\">เชิงเส้น</string>\n    <string name=\"gradient_type_radial\">เรเดียล</string>\n    <string name=\"gradient_type_sweep\">กวาด</string>\n    <string name=\"gradient_type\">ประเภทการไล่ระดับสี</string>\n    <string name=\"center_x\">เซ็นเตอร์เอ็กซ์</string>\n    <string name=\"center_y\">เซ็นเตอร์ วาย</string>\n    <string name=\"tile_mode\">โหมดไทล์</string>\n    <string name=\"tile_mode_repeated\">ซ้ำแล้วซ้ำเล่า</string>\n    <string name=\"tile_mode_mirror\">กระจกเงา</string>\n    <string name=\"tile_mode_clamp\">ที่หนีบ</string>\n    <string name=\"tile_mode_decal\">รูปลอก</string>\n    <string name=\"color_stops\">หยุดสี</string>\n    <string name=\"add_color\">เพิ่มสี</string>\n    <string name=\"properties\">คุณสมบัติ</string>\n    <string name=\"email\">อีเมล</string>\n    <string name=\"lasso\">ลาสโซ</string>\n    <string name=\"lasso_sub\">ดึงเส้นทางที่ปิดสนิทตามเส้นทางที่กำหนด</string>\n    <string name=\"draw_path_mode\">วาดโหมดเส้นทาง</string>\n    <string name=\"double_line_arrow\">ลูกศรเส้นคู่</string>\n    <string name=\"free_drawing\">การวาดภาพฟรี</string>\n    <string name=\"double_arrow\">ลูกศรคู่</string>\n    <string name=\"line_arrow\">ลูกศรเส้น</string>\n    <string name=\"line\">เส้น</string>\n    <string name=\"free_drawing_sub\">วาดเส้นทางเป็นค่าอินพุต</string>\n    <string name=\"line_sub\">วาดเส้นทางจากจุดเริ่มต้นไปยังจุดสิ้นสุดเป็นเส้น</string>\n    <string name=\"line_arrow_sub\">วาดลูกศรชี้จากจุดเริ่มต้นไปยังจุดสิ้นสุดเป็นเส้น</string>\n    <string name=\"arrow_sub\">ดึงลูกศรชี้จากเส้นทางที่กำหนด</string>\n    <string name=\"double_line_arrow_sub\">วาดลูกศรชี้คู่จากจุดเริ่มต้นไปยังจุดสิ้นสุดเป็นเส้น</string>\n    <string name=\"double_arrow_sub\">ดึงลูกศรชี้คู่จากเส้นทางที่กำหนด</string>\n    <string name=\"outlined_oval\">วงรีที่ระบุไว้</string>\n    <string name=\"outlined_rect\">ร่างสี่เหลี่ยมผืนผ้า</string>\n    <string name=\"oval\">วงรี</string>\n    <string name=\"rect\">สี่เหลี่ยมผืนผ้า</string>\n    <string name=\"rect_sub\">ลากเส้นตรงจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"oval_sub\">วาดวงรีจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"dithering\">การทำสี</string>\n    <string name=\"quantizier\">ควอนติซิเออร์</string>\n    <string name=\"gray_scale\">ระดับสีเทา</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">False Floyd Steinberg Dithering</string>\n    <string name=\"left_to_right_dithering\">จากซ้ายไปขวา</string>\n    <string name=\"random_dithering\">การสุ่มตัวอย่าง</string>\n    <string name=\"simple_threshold_dithering\">Dithering เกณฑ์ง่าย ๆ</string>\n    <string name=\"mask_preview\">ดูตัวอย่างหน้ากาก</string>\n    <string name=\"mask_preview_sub\">หน้ากากตัวกรองที่วาดไว้จะแสดงผลเพื่อแสดงผลลัพธ์โดยประมาณ</string>\n    <string name=\"delete\">ลบ</string>\n    <string name=\"delete_color_scheme_warn\">คุณกำลังจะลบชุดสีที่เลือก การดำเนินการนี้ไม่สามารถยกเลิกได้</string>\n    <string name=\"scale_mode\">โหมดสเกล</string>\n    <string name=\"bilinear\">ไบลิเนียร์</string>\n    <string name=\"hann\">ฮัน</string>\n    <string name=\"hermite\">ฤาษี</string>\n    <string name=\"lanczos\">แลนโซส</string>\n    <string name=\"mitchell\">มิทเชล</string>\n    <string name=\"nearest\">ใกล้ที่สุด</string>\n    <string name=\"spline\">เส้นโค้ง</string>\n    <string name=\"basic\">ขั้นพื้นฐาน</string>\n    <string name=\"default_value\">ค่าเริ่มต้น</string>\n    <string name=\"value_in_range\">ค่าในช่วง %1$s - %2$s</string>\n    <string name=\"sigma\">ซิกมา</string>\n    <string name=\"spatial_sigma\">ซิกม่าเชิงพื้นที่</string>\n    <string name=\"catmull\">แคทมัล</string>\n    <string name=\"bicubic\">ไบคิวบิก</string>\n    <string name=\"catmull_sub\">วิธีการแก้ไขและสุ่มชุดจุดควบคุมใหม่อย่างราบรื่น ซึ่งใช้กันทั่วไปในคอมพิวเตอร์กราฟิกส์เพื่อสร้างเส้นโค้งที่ราบรื่น</string>\n    <string name=\"lanczos_sub\">วิธีการสุ่มตัวอย่างที่รักษาการประมาณค่าคุณภาพสูงโดยการใช้ฟังก์ชัน Weighted Sinc กับค่าพิกเซล</string>\n    <string name=\"mitchell_sub\">วิธีการสุ่มตัวอย่างที่ใช้ตัวกรองแบบบิดพร้อมพารามิเตอร์ที่ปรับได้เพื่อให้เกิดความสมดุลระหว่างความคมชัดและการลดรอยหยักในภาพที่ปรับขนาด</string>\n    <string name=\"spline_sub\">ใช้ฟังก์ชันพหุนามที่กำหนดเป็นชิ้นๆ เพื่อประมาณค่าเส้นโค้งหรือพื้นผิวได้อย่างราบรื่น การแสดงรูปร่างที่ยืดหยุ่นและต่อเนื่อง</string>\n    <string name=\"only_clip\">คลิปเท่านั้น</string>\n    <string name=\"only_clip_sub\">การบันทึกลงพื้นที่เก็บข้อมูลจะไม่ดำเนินการ และจะพยายามใส่รูปภาพลงในคลิปบอร์ดเท่านั้น</string>\n    <string name=\"icon_shape\">รูปร่างไอคอน</string>\n    <string name=\"image_stitching\">การต่อภาพ</string>\n    <string name=\"image_stitching_sub\">รวมภาพที่กำหนดเพื่อให้ได้ภาพใหญ่หนึ่งภาพ</string>\n    <string name=\"brightness_enforcement\">การบังคับใช้ความสว่าง</string>\n    <string name=\"screen\">หน้าจอ</string>\n    <string name=\"gradient_maker_type_image\">การซ้อนทับแบบไล่ระดับสี</string>\n    <string name=\"gradient_maker_type_image_sub\">เขียนการไล่ระดับสีที่ด้านบนของรูปภาพที่กำหนด</string>\n    <string name=\"transformations\">การเปลี่ยนแปลง</string>\n    <string name=\"camera\">กล้อง</string>\n    <string name=\"camera_sub\">ใช้กล้องในการถ่ายภาพ โปรดทราบว่าสามารถรับได้เพียงภาพเดียวจากแหล่งภาพนี้</string>\n    <string name=\"pick_at_least_two_images\">เลือกอย่างน้อย 2 ภาพ</string>\n    <string name=\"output_image_scale\">ขนาดภาพที่ส่งออก</string>\n    <string name=\"image_orientation\">การวางแนวรูปภาพ</string>\n    <string name=\"horizontal\">แนวนอน</string>\n    <string name=\"vertical\">แนวตั้ง</string>\n    <string name=\"grain\">ธัญพืช</string>\n    <string name=\"unsharp\">ไม่คมชัด</string>\n    <string name=\"pastel\">สีพาสเทล</string>\n    <string name=\"orange_haze\">หมอกสีส้ม</string>\n    <string name=\"pink_dream\">ความฝันสีชมพู</string>\n    <string name=\"golden_hour\">ชั่วโมงทอง</string>\n    <string name=\"hot_summer\">ฤดูร้อน</string>\n    <string name=\"purple_mist\">หมอกสีม่วง</string>\n    <string name=\"sunrise\">พระอาทิตย์ขึ้น</string>\n    <string name=\"colorful_swirl\">หมุนวนที่มีสีสัน</string>\n    <string name=\"soft_spring_light\">แสงสปริงอันนุ่มนวล</string>\n    <string name=\"lavender_dream\">ลาเวนเดอร์ดรีม</string>\n    <string name=\"green_sun\">กรีนซัน</string>\n    <string name=\"rainbow_world\">โลกสายรุ้ง</string>\n    <string name=\"deep_purple\">สีม่วงเข้ม</string>\n    <string name=\"space_portal\">พอร์ทัลอวกาศ</string>\n    <string name=\"red_swirl\">วงเวียนแดง</string>\n    <string name=\"digital_code\">รหัสดิจิทัล</string>\n    <string name=\"watermarking\">ลายน้ำ</string>\n    <string name=\"text_color\">สีข้อความ</string>\n    <string name=\"overlay_mode\">โหมดโอเวอร์เลย์</string>\n    <string name=\"pixel_size\">ขนาดพิกเซล</string>\n    <string name=\"lock_draw_orientation\">ล็อคการวางแนวการวาด</string>\n    <string name=\"lock_draw_orientation_sub\">หากเปิดใช้งานในโหมดการวาดภาพ หน้าจอจะไม่หมุน</string>\n    <string name=\"bokeh\">โบเก้</string>\n    <string name=\"gif_tools\">เครื่องมือ GIF</string>\n    <string name=\"gif_tools_sub\">แปลงรูปภาพเป็นรูปภาพ GIF หรือแยกเฟรมจากรูปภาพ GIF ที่กำหนด</string>\n    <string name=\"gif_type_to_image\">GIF เป็นรูปภาพ</string>\n    <string name=\"gif_type_to_image_sub\">แปลงไฟล์ GIF เป็นชุดรูปภาพ</string>\n    <string name=\"gif_type_to_gif_sub\">แปลงชุดรูปภาพเป็นไฟล์ GIF</string>\n    <string name=\"gif_type_to_gif\">รูปภาพเป็น GIF</string>\n    <string name=\"select_gif_image_to_start\">เลือกภาพ GIF เพื่อเริ่มต้น</string>\n    <string name=\"use_size_of_first_frame\">ใช้ขนาดของเฟรมแรก</string>\n    <string name=\"use_size_of_first_frame_sub\">แทนที่ขนาดที่ระบุด้วยขนาดเฟรมแรก</string>\n    <string name=\"repeat_count\">นับซ้ำ</string>\n    <string name=\"use_lasso\">ใช้ Lasso</string>\n    <string name=\"use_lasso_sub\">ใช้ Lasso เช่นเดียวกับในโหมดการวาดภาพเพื่อทำการลบ</string>\n    <string name=\"original_image_preview_alpha\">ภาพตัวอย่างต้นฉบับอัลฟ่า</string>\n    <string name=\"mask_filter\">แผ่นกรองหน้ากาก</string>\n    <string name=\"mask_filter_sub\">ใช้ห่วงโซ่ตัวกรองกับพื้นที่ที่มาสก์ที่กำหนด แต่ละพื้นที่ของมาส์กสามารถกำหนดชุดตัวกรองของตัวเองได้</string>\n    <string name=\"masks\">มาสก์</string>\n    <string name=\"add_mask\">เพิ่มมาส์ก</string>\n    <string name=\"mask_indexed\">หน้ากาก %d</string>\n    <string name=\"random_emojis_sub\">อิโมจิของแถบแอปจะถูกเปลี่ยนอย่างต่อเนื่องโดยการสุ่ม แทนที่จะใช้อันที่เลือก</string>\n    <string name=\"random_emojis\">อิโมจิแบบสุ่ม</string>\n    <string name=\"random_emojis_error\">ไม่สามารถใช้การเลือกอีโมจิแบบสุ่มในขณะที่ปิดใช้งานอีโมจิได้</string>\n    <string name=\"emoji_selection_error\">ไม่สามารถเลือกอิโมจิในขณะที่เปิดใช้งานการสุ่มเลือกได้</string>\n    <string name=\"check_for_updates\">ตรวจสอบสำหรับการอัพเดต</string>\n    <string name=\"aspect_ratio\">อัตราส่วนภาพ</string>\n    <string name=\"enable_emoji\">เปิดใช้งานอีโมจิ</string>\n    <string name=\"old_tv\">ทีวีเก่า</string>\n    <string name=\"shuffle_blur\">สุ่มเบลอ</string>\n    <string name=\"recognize_text\">OCR (จดจำข้อความ)</string>\n    <string name=\"recognize_text_sub\">จดจำข้อความจากรูปภาพที่กำหนด รองรับมากกว่า 120 ภาษา</string>\n    <string name=\"picture_has_no_text\">รูปภาพไม่มีข้อความ หรือแอปไม่พบ</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">ประเภทการรับรู้</string>\n    <string name=\"fast\">เร็ว</string>\n    <string name=\"standard\">มาตรฐาน</string>\n    <string name=\"best\">ดีที่สุด</string>\n    <string name=\"no_data\">ไม่มีข้อมูล</string>\n    <string name=\"download_description\">เพื่อให้การทำงานที่เหมาะสมของ Tesseract OCR ต้องดาวน์โหลดข้อมูลการฝึกอบรมเพิ่มเติม (%1$s) ลงในอุปกรณ์ของคุณ \\nคุณต้องการดาวน์โหลดข้อมูล %2$s หรือไม่?</string>\n    <string name=\"download\">ดาวน์โหลด</string>\n    <string name=\"no_connection\">ไม่มีการเชื่อมต่อ โปรดตรวจสอบแล้วลองอีกครั้งเพื่อดาวน์โหลดโมเดลรถไฟ</string>\n    <string name=\"downloaded_languages\">ภาษาที่ดาวน์โหลด</string>\n    <string name=\"available_languages\">ภาษาที่ใช้ได้</string>\n    <string name=\"segmentation_mode\">โหมดการแบ่งส่วน</string>\n    <string name=\"restore_background_sub\">แปรงจะคืนค่าพื้นหลังแทนการลบ</string>\n    <string name=\"horizontal_grid\">ตารางแนวนอน</string>\n    <string name=\"vertical_grid\">ตารางแนวตั้ง</string>\n    <string name=\"stitch_mode\">โหมดการเย็บร้อย</string>\n    <string name=\"rows_count\">จำนวนแถว</string>\n    <string name=\"columns_count\">จำนวนคอลัมน์</string>\n    <string name=\"use_pixel_switch\">ใช้สวิตช์พิกเซล</string>\n    <string name=\"use_pixel_switch_sub\">สวิตช์แบบพิกเซลจะถูกใช้แทนเนื้อหาของ Google ที่คุณใช้</string>\n    <string name=\"slide\">สไลด์</string>\n    <string name=\"side_by_side\">เคียงบ่าเคียงไหล่</string>\n    <string name=\"toggle_tap\">สลับการแตะ</string>\n    <string name=\"transparency\">ความโปร่งใส</string>\n    <string name=\"favorite\">ที่ชื่นชอบ</string>\n    <string name=\"no_favorite_filters\">ยังไม่มีการเพิ่มตัวกรองที่ชื่นชอบ</string>\n    <string name=\"b_spline\">บี สไปลน์</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">เอียงกะ</string>\n    <string name=\"regular\">ปกติ</string>\n    <string name=\"blur_edges\">ขอบเบลอ</string>\n    <string name=\"inverse_fill_type\">ประเภทการเติมผกผัน</string>\n    <string name=\"inverse_fill_type_sub\">หากเปิดใช้งาน พื้นที่ที่ไม่ปกปิดทั้งหมดจะถูกกรองแทนการทำงานเริ่มต้น</string>\n    <string name=\"confetti\">ลูกปา</string>\n    <string name=\"confetti_sub\">ลูกปาจะแสดงในการบันทึก การแชร์ และการดำเนินการหลักอื่นๆ</string>\n    <string name=\"secure_mode\">โหมดปลอดภัย</string>\n    <string name=\"secure_mode_sub\">ซ่อนเนื้อหาเมื่อออก และไม่สามารถจับภาพหรือบันทึกหน้าจอได้</string>\n    <string name=\"blur_edges_sub\">วาดขอบเบลอใต้รูปภาพต้นฉบับเพื่อเติมช่องว่างรอบๆ แทนที่จะเป็นสีเดียวหากเปิดใช้งาน</string>\n    <string name=\"pixelation\">พิกเซล</string>\n    <string name=\"circle_pixelation\">วงกลมพิกเซล</string>\n    <string name=\"enhanced_circle_pixelation\">พิกเซลวงกลมที่ได้รับการปรับปรุง</string>\n    <string name=\"replace_color\">เปลี่ยนสี</string>\n    <string name=\"disabled\">พิการ</string>\n    <string name=\"both\">ทั้งคู่</string>\n    <string name=\"pdf_tools_sub\">ดำเนินการกับไฟล์ PDF: ดูตัวอย่าง แปลงเป็นชุดรูปภาพ หรือสร้างจากรูปภาพที่กำหนด</string>\n    <string name=\"preview_pdf\">ดูตัวอย่าง PDF</string>\n    <string name=\"mask_color\">สีหน้ากาก</string>\n    <string name=\"delete_mask\">ลบมาสก์</string>\n    <string name=\"center_position\">ศูนย์</string>\n    <string name=\"end_position\">จบ</string>\n    <string name=\"simple_variants\">ตัวแปรที่เรียบง่าย</string>\n    <string name=\"highlighter\">ปากกาเน้นข้อความ</string>\n    <string name=\"neon\">นีออน</string>\n    <string name=\"pen\">ปากกา</string>\n    <string name=\"auto_rotate_limits\">หมุนอัตโนมัติ</string>\n    <string name=\"containers_shadow\">ตู้คอนเทนเนอร์</string>\n    <string name=\"containers_shadow_sub\">เปิดใช้งานการวาดเงาด้านหลังคอนเทนเนอร์</string>\n    <string name=\"sliders_shadow\">สไลเดอร์</string>\n    <string name=\"switches_shadow\">สวิตช์</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">ปุ่ม</string>\n    <string name=\"sliders_shadow_sub\">เปิดใช้งานการวาดเงาด้านหลังแถบเลื่อน</string>\n    <string name=\"switches_shadow_sub\">เปิดใช้งานการวาดเงาด้านหลังสวิตช์</string>\n    <string name=\"fabs_shadow_sub\">เปิดใช้งานการวาดเงาด้านหลังปุ่มการทำงานแบบลอย</string>\n    <string name=\"buttons_shadow_sub\">เปิดใช้งานการวาดเงาด้านหลังปุ่มเริ่มต้น</string>\n    <string name=\"app_bars_shadow\">แถบแอพ</string>\n    <string name=\"attention\">ความสนใจ</string>\n    <string name=\"fading_edges\">ขอบซีดจาง</string>\n    <string name=\"foss_update_checker_warning\">ตัวตรวจสอบการอัปเดตนี้จะเชื่อมต่อกับ GitHub เพื่อตรวจสอบว่ามีการอัปเดตใหม่หรือไม่</string>\n    <string name=\"invert_colors\">สลับสี</string>\n    <string name=\"invert_colors_sub\">เปลี่ยนสีของธีมเป็นสีเนกาทีฟหากเปิดใช้งาน</string>\n    <string name=\"exit\">ออก</string>\n    <string name=\"preview_closing\">หากคุณออกจากการแสดงตัวอย่างตอนนี้ คุณจะต้องเพิ่มรูปภาพอีกครั้ง</string>\n    <string name=\"image_format\">รูปแบบภาพ</string>\n    <string name=\"material_you_sub\">สร้าง\\\"Material You\\\"จานสีจากภาพ</string>\n    <string name=\"dark_colors\">สีเข้ม</string>\n    <string name=\"dark_colors_sub\">ใช้โทนสีโหมดกลางคืนแทนตัวแปรแสง</string>\n    <string name=\"copy_as_compose_code\">คัดลอกเป็น\\\"Jetpack Compose\\\"รหัส</string>\n    <string name=\"ring_blur\">แหวนเบลอ</string>\n    <string name=\"star_blur\">ดาวเบลอ</string>\n    <string name=\"linear_tilt_shift\">กะเอียงเชิงเส้น</string>\n    <string name=\"tags_to_remove\">แท็กที่จะลบ</string>\n    <string name=\"cross_blur\">ข้ามเบลอ</string>\n    <string name=\"circle_blur\">วงกลมเบลอ</string>\n    <string name=\"apng_tools\">เครื่องมือ APNG</string>\n    <string name=\"apng_tools_sub\">แปลงรูปภาพเป็นรูปภาพ APNG หรือแยกเฟรมจากรูปภาพ APNG ที่กำหนด</string>\n    <string name=\"apng_type_to_image\">APNG เป็นรูปภาพ</string>\n    <string name=\"apng_type_to_image_sub\">แปลงไฟล์ APNG เป็นชุดรูปภาพ</string>\n    <string name=\"apng_type_to_apng_sub\">แปลงชุดรูปภาพเป็นไฟล์ APNG</string>\n    <string name=\"apng_type_to_apng\">รูปภาพไปยัง APNG</string>\n    <string name=\"motion_blur\">โมชั่นเบลอ</string>\n    <string name=\"zip\">ซิป</string>\n    <string name=\"zip_sub\">สร้างไฟล์ Zip จากไฟล์หรือรูปภาพที่กำหนด</string>\n    <string name=\"select_apng_image_to_start\">เลือกรูปภาพ APNG เพื่อเริ่มต้น</string>\n    <string name=\"drag_handle_width\">ลากความกว้างของที่จับ</string>\n    <string name=\"confetti_type\">ประเภทกระดาษโปรย</string>\n    <string name=\"festive\">งานรื่นเริง</string>\n    <string name=\"explode\">ระเบิด</string>\n    <string name=\"rain\">ฝน</string>\n    <string name=\"corners\">มุม</string>\n    <string name=\"jxl_tools\">เครื่องมือ JXL</string>\n    <string name=\"jxl_tools_sub\">ดำเนินการแปลงรหัส JXL ~ JPEG โดยไม่สูญเสียคุณภาพ หรือแปลงภาพเคลื่อนไหว GIF/APNG เป็น JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL เป็น JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">ทำการแปลงรหัสแบบไม่สูญเสียจาก JXL เป็น JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">ทำการแปลงรหัสแบบไม่สูญเสียจาก JPEG เป็น JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG เป็น JXL</string>\n    <string name=\"select_jxl_image_to_start\">เลือกภาพ JXL เพื่อเริ่มต้น</string>\n    <string name=\"fast_gaussian_blur_2d\">เกาส์เซียนเบลอ 2D อย่างรวดเร็ว</string>\n    <string name=\"fast_gaussian_blur_3d\">เกาส์เซียนเบลอ 3 มิติอย่างรวดเร็ว</string>\n    <string name=\"fast_gaussian_blur_4d\">เกาส์เซียนเบลอ 4D อย่างรวดเร็ว</string>\n    <string name=\"auto_paste\">รถอีสเตอร์</string>\n    <string name=\"auto_paste_sub\">อนุญาตให้แอปวางข้อมูลคลิปบอร์ดโดยอัตโนมัติ ดังนั้นข้อมูลจะปรากฏบนหน้าจอหลักและคุณจะสามารถดำเนินการได้</string>\n    <string name=\"harmonization_color\">สีที่ประสานกัน</string>\n    <string name=\"harmonization_level\">ระดับการประสานกัน</string>\n    <string name=\"lanczos_bessel\">แลนซอส เบสเซล</string>\n    <string name=\"lanczos_bessel_sub\">วิธีการสุ่มตัวอย่างที่รักษาการประมาณค่าคุณภาพสูงโดยใช้ฟังก์ชัน Bessel (jinc) กับค่าพิกเซล</string>\n    <string name=\"gif_type_to_jxl\">GIF เป็น JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">แปลงภาพ GIF เป็นภาพเคลื่อนไหว JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG เป็น JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">แปลงภาพ APNG เป็นภาพเคลื่อนไหว JXL</string>\n    <string name=\"jxl_type_to_images\">JXL เป็นรูปภาพ</string>\n    <string name=\"jxl_type_to_images_sub\">แปลงภาพเคลื่อนไหว JXL เป็นชุดรูปภาพ</string>\n    <string name=\"jxl_type_to_jxl\">รูปภาพเป็น JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">แปลงชุดรูปภาพเป็นแอนิเมชั่น JXL</string>\n    <string name=\"behavior\">พฤติกรรม</string>\n    <string name=\"skip_file_picking\">ข้ามการเลือกไฟล์</string>\n    <string name=\"skip_file_picking_sub\">ตัวเลือกไฟล์จะแสดงทันทีหากเป็นไปได้บนหน้าจอที่เลือก</string>\n    <string name=\"generate_previews\">สร้างตัวอย่าง</string>\n    <string name=\"generate_previews_sub\">เปิดใช้งานการสร้างหน้าตัวอย่าง ซึ่งอาจช่วยหลีกเลี่ยงข้อขัดข้องในอุปกรณ์บางชนิด และยังปิดใช้ฟังก์ชันการแก้ไขบางอย่างภายในตัวเลือกการแก้ไขเดียวอีกด้วย</string>\n    <string name=\"lossy_compression\">การบีบอัดแบบสูญเสีย</string>\n    <string name=\"lossy_compression_sub\">ใช้การบีบอัดแบบ lossy เพื่อลดขนาดไฟล์แทนที่จะเป็นแบบ lossless</string>\n    <string name=\"compression_type\">ประเภทการบีบอัด</string>\n    <string name=\"speed_sub\">ควบคุมความเร็วในการถอดรหัสรูปภาพผลลัพธ์ ซึ่งจะช่วยให้เปิดรูปภาพผลลัพธ์ได้เร็วขึ้น ค่า %1$s หมายถึงการถอดรหัสช้าที่สุด ในขณะที่ %2$s - เร็วที่สุด การตั้งค่านี้อาจเพิ่มขนาดรูปภาพเอาต์พุต</string>\n    <string name=\"sorting\">การเรียงลำดับ</string>\n    <string name=\"sort_by_date\">วันที่</string>\n    <string name=\"sort_by_date_reversed\">วันที่ (กลับด้าน)</string>\n    <string name=\"sort_by_name\">ชื่อ</string>\n    <string name=\"sort_by_name_reversed\">ชื่อ (กลับรายการ)</string>\n    <string name=\"channels_configuration\">การกำหนดค่าช่องสัญญาณ</string>\n    <string name=\"header_today\">วันนี้</string>\n    <string name=\"header_yesterday\">เมื่อวาน</string>\n    <string name=\"embedded_picker\">เครื่องมือเลือกแบบฝัง</string>\n    <string name=\"embedded_picker_sub\">เครื่องมือเลือกรูปภาพของ Image Toolbox</string>\n    <string name=\"no_permissions\">ไม่มีสิทธิ์</string>\n    <string name=\"request\">ขอ</string>\n    <string name=\"pick_multiple_media\">เลือกสื่อหลายรายการ</string>\n    <string name=\"pick_single_media\">เลือกสื่อเดี่ยว</string>\n    <string name=\"pick\">เลือก</string>\n    <string name=\"try_again\">ลองอีกครั้ง</string>\n    <string name=\"show_settings_in_landscape\">แสดงการตั้งค่าในแนวนอน</string>\n    <string name=\"show_settings_in_landscape_sub\">หากปิดใช้งานการตั้งค่าโหมดแนวนอนจะเปิดขึ้นที่ปุ่มในแถบแอปด้านบนเช่นเคย แทนที่จะเป็นตัวเลือกที่มองเห็นได้อย่างถาวร</string>\n    <string name=\"fullscreen_settings\">การตั้งค่าเต็มหน้าจอ</string>\n    <string name=\"fullscreen_settings_sub\">เปิดใช้งานและหน้าการตั้งค่าจะเปิดเป็นแบบเต็มหน้าจอเสมอ แทนที่จะเป็นแผ่นลิ้นชักแบบเลื่อนได้</string>\n    <string name=\"switch_type\">ประเภทสวิตช์</string>\n    <string name=\"compose\">เขียน</string>\n    <string name=\"compose_switch_sub\">วัสดุการเขียน Jetpack ที่คุณเปลี่ยน</string>\n    <string name=\"material_you_switch_sub\">วัสดุที่คุณเปลี่ยน</string>\n    <string name=\"max\">สูงสุด</string>\n    <string name=\"resize_anchor\">ปรับขนาดจุดยึด</string>\n    <string name=\"pixel_switch\">พิกเซล</string>\n    <string name=\"fluent_switch\">คล่องแคล่ว</string>\n    <string name=\"fluent_switch_sub\">สวิตช์ที่ใช้ระบบการออกแบบ \\\"Fluent\\\"</string>\n    <string name=\"cupertino_switch\">คูเปอร์ติโน</string>\n    <string name=\"cupertino_switch_sub\">สวิตช์ที่ใช้ระบบการออกแบบ \\\"คูเปอร์ติโน\\\"</string>\n    <string name=\"images_to_svg\">รูปภาพเป็น SVG</string>\n    <string name=\"images_to_svg_sub\">ติดตามภาพที่กำหนดไปยังภาพ SVG</string>\n    <string name=\"use_sampled_palette\">ใช้จานสีตัวอย่าง</string>\n    <string name=\"use_sampled_palette_sub\">ระบบจะสุ่มตัวอย่างจานสีปริมาณหากเปิดใช้งานตัวเลือกนี้</string>\n    <string name=\"path_omit\">ละเว้นเส้นทาง</string>\n    <string name=\"svg_warning\">ไม่แนะนำให้ใช้เครื่องมือนี้ในการติดตามภาพขนาดใหญ่โดยไม่ต้องลดขนาด เนื่องจากอาจทำให้เกิดความผิดพลาดและเพิ่มเวลาในการประมวลผลได้</string>\n    <string name=\"downscale_image\">ลดขนาดรูปภาพ</string>\n    <string name=\"downscale_image_sub\">รูปภาพจะถูกลดขนาดลงเป็นขนาดที่ต่ำกว่าก่อนการประมวลผล ซึ่งจะช่วยให้เครื่องมือทำงานเร็วและปลอดภัยยิ่งขึ้น</string>\n    <string name=\"min_color_ratio\">อัตราส่วนสีขั้นต่ำ</string>\n    <string name=\"lines_threshold\">เกณฑ์บรรทัด</string>\n    <string name=\"quadratic_threshold\">เกณฑ์กำลังสอง</string>\n    <string name=\"coordinates_rounding_tolerance\">พิกัดความเผื่อการปัดเศษ</string>\n    <string name=\"path_scale\">ขนาดเส้นทาง</string>\n    <string name=\"reset_properties\">รีเซ็ตคุณสมบัติ</string>\n    <string name=\"reset_properties_sub\">คุณสมบัติทั้งหมดจะถูกตั้งค่าเป็นค่าเริ่มต้น โปรดทราบว่าการดำเนินการนี้ไม่สามารถยกเลิกได้</string>\n    <string name=\"detailed\">รายละเอียด</string>\n    <string name=\"default_line_width\">ความกว้างของเส้นเริ่มต้น</string>\n    <string name=\"engine_mode\">โหมดเครื่องยนต์</string>\n    <string name=\"legacy\">มรดก</string>\n    <string name=\"lstm_network\">เครือข่ายแอลเอสทีเอ็ม</string>\n    <string name=\"legacy_and_lstm\">มรดกและ LSTM</string>\n    <string name=\"convert\">แปลง</string>\n    <string name=\"convert_sub\">แปลงชุดรูปภาพเป็นรูปแบบที่กำหนด</string>\n    <string name=\"add_new_folder\">เพิ่มโฟลเดอร์ใหม่</string>\n    <string name=\"tag_bits_per_sample\">บิตต่อตัวอย่าง</string>\n    <string name=\"tag_compression\">การบีบอัด</string>\n    <string name=\"tag_photometric_interpretation\">การตีความโฟโตเมตริก</string>\n    <string name=\"tag_samples_per_pixel\">ตัวอย่างต่อพิกเซล</string>\n    <string name=\"tag_planar_configuration\">การกำหนดค่าระนาบ</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">การสุ่มตัวอย่างย่อย Y Cb Cr</string>\n    <string name=\"tag_y_cb_cr_positioning\">การวางตำแหน่ง Y Cb Cr</string>\n    <string name=\"tag_x_resolution\">ความละเอียด X</string>\n    <string name=\"tag_y_resolution\">Y ความละเอียด</string>\n    <string name=\"tag_resolution_unit\">หน่วยความละเอียด</string>\n    <string name=\"tag_strip_offsets\">สตริปออฟเซ็ต</string>\n    <string name=\"tag_rows_per_strip\">แถวต่อแถบ</string>\n    <string name=\"tag_strip_byte_counts\">สตริปไบต์นับ</string>\n    <string name=\"tag_jpeg_interchange_format\">รูปแบบการแลกเปลี่ยน JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">ความยาวรูปแบบการแลกเปลี่ยน JPEG</string>\n    <string name=\"tag_transfer_function\">ฟังก์ชั่นการถ่ายโอน</string>\n    <string name=\"tag_white_point\">จุดขาว</string>\n    <string name=\"tag_primary_chromaticities\">รงค์หลัก</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr สัมประสิทธิ์</string>\n    <string name=\"tag_reference_black_white\">อ้างอิงสีดำสีขาว</string>\n    <string name=\"tag_datetime\">วันที่ เวลา</string>\n    <string name=\"tag_image_description\">คำอธิบายรูปภาพ</string>\n    <string name=\"tag_make\">ทำ</string>\n    <string name=\"tag_model\">แบบอย่าง</string>\n    <string name=\"tag_software\">ซอฟต์แวร์</string>\n    <string name=\"tag_artist\">ศิลปิน</string>\n    <string name=\"tag_copyright\">ลิขสิทธิ์</string>\n    <string name=\"tag_exif_version\">เวอร์ชั่น เอ็กซิฟ</string>\n    <string name=\"tag_flashpix_version\">เวอร์ชั่นแฟลชพิกซ์</string>\n    <string name=\"tag_color_space\">พื้นที่สี</string>\n    <string name=\"tag_gamma\">แกมมา</string>\n    <string name=\"tag_pixel_x_dimension\">มิติพิกเซล X</string>\n    <string name=\"tag_pixel_y_dimension\">มิติพิกเซล Y</string>\n    <string name=\"tag_compressed_bits_per_pixel\">บิตที่ถูกบีบอัดต่อพิกเซล</string>\n    <string name=\"tag_maker_note\">หมายเหตุผู้สร้าง</string>\n    <string name=\"tag_user_comment\">ความคิดเห็นของผู้ใช้</string>\n    <string name=\"tag_related_sound_file\">ไฟล์เสียงที่เกี่ยวข้อง</string>\n    <string name=\"tag_datetime_original\">วันที่ เวลา ต้นฉบับ</string>\n    <string name=\"tag_datetime_digitized\">วันที่ เวลา แปลงเป็นดิจิทัล</string>\n    <string name=\"tag_offset_time\">เวลาออฟเซ็ต</string>\n    <string name=\"tag_offset_time_original\">เวลาออฟเซ็ต ต้นฉบับ</string>\n    <string name=\"tag_offset_time_digitized\">เวลาออฟเซ็ตแปลงเป็นดิจิทัล</string>\n    <string name=\"tag_subsec_time\">เวลาย่อยวินาที</string>\n    <string name=\"tag_subsec_time_original\">เวลาย่อยเป็นต้นฉบับ</string>\n    <string name=\"tag_subsec_time_digitized\">เวลาย่อยเป็นดิจิทัล</string>\n    <string name=\"tag_exposure_time\">เวลารับสัมผัสเชื้อ</string>\n    <string name=\"tag_f_number\">เอฟ นัมเบอร์</string>\n    <string name=\"tag_exposure_program\">โปรแกรมการสัมผัส</string>\n    <string name=\"tag_spectral_sensitivity\">ความไวแสงสเปกตรัม</string>\n    <string name=\"tag_photographic_sensitivity\">ความไวแสงของการถ่ายภาพ</string>\n    <string name=\"tag_oecf\">อฟ</string>\n    <string name=\"tag_sensitivity_type\">ประเภทความไว</string>\n    <string name=\"tag_standard_output_sensitivity\">ความไวเอาต์พุตมาตรฐาน</string>\n    <string name=\"tag_recommended_exposure_index\">ดัชนีการสัมผัสที่แนะนำ</string>\n    <string name=\"tag_iso_speed\">ความไวแสง ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ละติจูดความเร็ว ISO yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ละติจูดความเร็ว ISO zzz</string>\n    <string name=\"tag_shutter_speed_value\">ค่าความเร็วชัตเตอร์</string>\n    <string name=\"tag_aperture_value\">ค่ารูรับแสง</string>\n    <string name=\"tag_brightness_value\">ค่าความสว่าง</string>\n    <string name=\"tag_exposure_bias_value\">ค่าอคติของการสัมผัส</string>\n    <string name=\"tag_max_aperture_value\">ค่ารูรับแสงสูงสุด</string>\n    <string name=\"tag_subject_distance\">ระยะห่างของเรื่อง</string>\n    <string name=\"tag_metering_mode\">โหมดการวัดแสง</string>\n    <string name=\"tag_flash\">แฟลช</string>\n    <string name=\"tag_subject_area\">สาขาวิชา</string>\n    <string name=\"tag_focal_length\">ทางยาวโฟกัส</string>\n    <string name=\"tag_flash_energy\">พลังงานแฟลช</string>\n    <string name=\"tag_spatial_frequency_response\">การตอบสนองความถี่เชิงพื้นที่</string>\n    <string name=\"tag_focal_plane_x_resolution\">ความละเอียดระนาบโฟกัส X</string>\n    <string name=\"tag_focal_plane_y_resolution\">ความละเอียดระนาบโฟกัส Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">หน่วยความละเอียดระนาบโฟกัส</string>\n    <string name=\"tag_subject_location\">สถานที่ตั้งของเรื่อง</string>\n    <string name=\"tag_exposure_index\">ดัชนีการสัมผัส</string>\n    <string name=\"tag_sensing_method\">วิธีการตรวจจับ</string>\n    <string name=\"tag_file_source\">แหล่งที่มาของไฟล์</string>\n    <string name=\"tag_cfa_pattern\">รูปแบบ CFA</string>\n    <string name=\"tag_custom_rendered\">แสดงผลแบบกำหนดเอง</string>\n    <string name=\"tag_exposure_mode\">โหมดการรับแสง</string>\n    <string name=\"tag_white_balance\">สมดุลสีขาว</string>\n    <string name=\"tag_digital_zoom_ratio\">อัตราส่วนการซูมแบบดิจิตอล</string>\n    <string name=\"tag_focal_length_in_35mm_film\">ทางยาวโฟกัสในฟิล์ม 35 มม</string>\n    <string name=\"tag_scene_capture_type\">ประเภทการถ่ายภาพฉาก</string>\n    <string name=\"tag_gain_control\">ได้รับการควบคุม</string>\n    <string name=\"tag_contrast\">ตัดกัน</string>\n    <string name=\"tag_saturation\">ความอิ่มตัว</string>\n    <string name=\"tag_sharpness\">ความคม</string>\n    <string name=\"tag_device_setting_description\">คำอธิบายการตั้งค่าอุปกรณ์</string>\n    <string name=\"tag_subject_distance_range\">ช่วงระยะทางของวัตถุ</string>\n    <string name=\"tag_image_unique_id\">รหัสเฉพาะของรูปภาพ</string>\n    <string name=\"tag_camera_owner_name\">ชื่อเจ้าของกล้อง</string>\n    <string name=\"tag_body_serial_number\">หมายเลขซีเรียลของร่างกาย</string>\n    <string name=\"tag_lens_specification\">ข้อมูลจำเพาะของเลนส์</string>\n    <string name=\"tag_lens_make\">ยี่ห้อเลนส์</string>\n    <string name=\"tag_lens_model\">รุ่นเลนส์</string>\n    <string name=\"tag_lens_serial_number\">หมายเลขซีเรียลเลนส์</string>\n    <string name=\"tag_gps_version_id\">รหัสเวอร์ชัน GPS</string>\n    <string name=\"tag_gps_latitude_ref\">การอ้างอิงละติจูด GPS</string>\n    <string name=\"tag_gps_latitude\">ละติจูด GPS</string>\n    <string name=\"tag_gps_longitude_ref\">การอ้างอิงลองจิจูด GPS</string>\n    <string name=\"tag_gps_longitude\">ลองจิจูด GPS</string>\n    <string name=\"tag_gps_altitude_ref\">การอ้างอิงระดับความสูง GPS</string>\n    <string name=\"tag_gps_altitude\">ระดับความสูงของจีพีเอส</string>\n    <string name=\"tag_gps_timestamp\">ประทับเวลา GPS</string>\n    <string name=\"tag_gps_satellites\">ดาวเทียม GPS</string>\n    <string name=\"tag_gps_status\">สถานะ GPS</string>\n    <string name=\"tag_gps_measure_mode\">โหมดการวัด GPS</string>\n    <string name=\"tag_gps_dop\">จีพีเอส สปส</string>\n    <string name=\"tag_gps_speed_ref\">อ้างอิงความเร็ว GPS</string>\n    <string name=\"tag_gps_speed\">ความเร็วจีพีเอส</string>\n    <string name=\"tag_gps_track_ref\">อ้างอิง GPS Track</string>\n    <string name=\"tag_gps_track\">จีพีเอสติดตาม</string>\n    <string name=\"tag_gps_img_direction_ref\">อ้างอิงทิศทางภาพ GPS</string>\n    <string name=\"tag_gps_img_direction\">ทิศทางภาพ GPS</string>\n    <string name=\"tag_gps_map_datum\">ข้อมูลแผนที่ GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">การอ้างอิงละติจูดปลายทาง GPS</string>\n    <string name=\"tag_gps_dest_latitude\">ละติจูดปลายทาง GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">การอ้างอิงลองจิจูดปลายทาง GPS</string>\n    <string name=\"tag_gps_dest_longitude\">ลองจิจูดปลายทาง GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">อ้างอิงแบริ่งปลายทาง GPS</string>\n    <string name=\"tag_gps_dest_bearing\">แบริ่งปลายทาง GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">การอ้างอิงระยะทางปลายทาง GPS</string>\n    <string name=\"tag_gps_dest_distance\">ระยะทางปลายทาง GPS</string>\n    <string name=\"tag_gps_processing_method\">วิธีการประมวลผล GPS</string>\n    <string name=\"tag_gps_area_information\">ข้อมูลพื้นที่ GPS</string>\n    <string name=\"tag_gps_datestamp\">ประทับวันที่ GPS</string>\n    <string name=\"tag_gps_differential\">จีพีเอสดิฟเฟอเรนเชียล</string>\n    <string name=\"tag_gps_h_positioning_error\">ข้อผิดพลาดการวางตำแหน่ง GPS H</string>\n    <string name=\"tag_interoperability_index\">ดัชนีการทำงานร่วมกัน</string>\n    <string name=\"tag_dng_version\">เวอร์ชัน DNG</string>\n    <string name=\"tag_default_crop_size\">ขนาดครอบตัดเริ่มต้น</string>\n    <string name=\"tag_orf_preview_image_start\">ดูตัวอย่างภาพเริ่มต้น</string>\n    <string name=\"tag_orf_preview_image_length\">ดูตัวอย่างความยาวของภาพ</string>\n    <string name=\"tag_orf_aspect_frame\">กรอบมุมมอง</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">ขอบด้านล่างของเซนเซอร์</string>\n    <string name=\"tag_rw2_sensor_left_border\">เซ็นเซอร์ขอบด้านซ้าย</string>\n    <string name=\"tag_rw2_sensor_right_border\">ขอบขวาของเซนเซอร์</string>\n    <string name=\"tag_rw2_sensor_top_border\">ขอบด้านบนของเซ็นเซอร์</string>\n    <string name=\"tag_rw2_iso\">ไอเอสโอ</string>\n    <string name=\"draw_text_sub\">วาดข้อความบนเส้นทางด้วยแบบอักษรและสีที่กำหนด</string>\n    <string name=\"font_size\">ขนาดตัวอักษร</string>\n    <string name=\"watermark_size\">ขนาดลายน้ำ</string>\n    <string name=\"repeat_text\">ทำซ้ำข้อความ</string>\n    <string name=\"repeat_text_sub\">ข้อความปัจจุบันจะถูกทำซ้ำจนกว่าเส้นทางจะสิ้นสุดแทนที่จะวาดเพียงครั้งเดียว</string>\n    <string name=\"dash_size\">ขนาดเส้นประ</string>\n    <string name=\"draw_mode_image_sub\">ใช้รูปภาพที่เลือกเพื่อวาดตามเส้นทางที่กำหนด</string>\n    <string name=\"draw_image_sub\">รูปภาพนี้จะถูกใช้เป็นการป้อนข้อมูลซ้ำของเส้นทางที่วาด</string>\n    <string name=\"outlined_triangle_sub\">วาดรูปสามเหลี่ยมที่มีโครงร่างจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"triangle_sub\">วาดรูปสามเหลี่ยมที่มีโครงร่างจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"outlined_triangle\">สามเหลี่ยมที่มีโครงร่าง</string>\n    <string name=\"triangle\">สามเหลี่ยม</string>\n    <string name=\"polygon_sub\">วาดรูปหลายเหลี่ยมจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"polygon\">รูปหลายเหลี่ยม</string>\n    <string name=\"outlined_polygon\">รูปหลายเหลี่ยมที่สรุปไว้</string>\n    <string name=\"outlined_polygon_sub\">วาดรูปหลายเหลี่ยมที่มีโครงร่างจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"vertices\">จุดยอด</string>\n    <string name=\"draw_regular_polygon\">วาดรูปหลายเหลี่ยมปกติ</string>\n    <string name=\"draw_regular_polygon_sub\">วาดรูปหลายเหลี่ยมซึ่งจะเป็นรูปหลายเหลี่ยมปกติแทนที่จะเป็นรูปแบบอิสระ</string>\n    <string name=\"star_sub\">ดึงดาวจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"star\">ดาว</string>\n    <string name=\"outlined_star\">ดาวเด่น</string>\n    <string name=\"outlined_star_sub\">วาดดาวที่มีโครงร่างจากจุดเริ่มต้นไปยังจุดสิ้นสุด</string>\n    <string name=\"inner_radius_ratio\">อัตราส่วนรัศมีภายใน</string>\n    <string name=\"draw_regular_star\">วาดดาวปกติ</string>\n    <string name=\"draw_regular_star_sub\">วาดดาวซึ่งจะสม่ำเสมอแทนที่จะเป็นรูปแบบอิสระ</string>\n    <string name=\"antialias\">แอนติเลียส</string>\n    <string name=\"antialias_sub\">เปิดใช้งานการลดรอยหยักเพื่อป้องกันขอบคม</string>\n    <string name=\"open_edit_instead_of_preview\">เปิดแก้ไขแทนการแสดงตัวอย่าง</string>\n    <string name=\"open_edit_instead_of_preview_sub\">เมื่อคุณเลือกภาพที่จะเปิด (ดูตัวอย่าง) ใน ImageToolbox แผ่นแก้ไขการเลือกจะถูกเปิดแทนการดูตัวอย่าง</string>\n    <string name=\"document_scanner\">เครื่องสแกนเอกสาร</string>\n    <string name=\"document_scanner_sub\">สแกนเอกสารและสร้าง PDF หรือแยกรูปภาพจากเอกสารเหล่านั้น</string>\n    <string name=\"click_to_start_scanning\">คลิกเพื่อเริ่มการสแกน</string>\n    <string name=\"start_scanning\">เริ่มการสแกน</string>\n    <string name=\"save_as_pdf\">บันทึกเป็น PDF</string>\n    <string name=\"share_as_pdf\">แบ่งปันเป็น PDF</string>\n    <string name=\"options_below_is_for_images\">ตัวเลือกด้านล่างมีไว้สำหรับบันทึกรูปภาพ ไม่ใช่ PDF</string>\n    <string name=\"equalize_histogram_hsv\">ปรับฮิสโตแกรม HSV ให้เท่ากัน</string>\n    <string name=\"equalize_histogram\">ปรับฮิสโตแกรมให้เท่ากัน</string>\n    <string name=\"enter_percentage\">ป้อนเปอร์เซ็นต์</string>\n    <string name=\"allow_enter_by_text_field\">อนุญาตให้ป้อนโดยช่องข้อความ</string>\n    <string name=\"allow_enter_by_text_field_sub\">เปิดใช้งานช่องข้อความด้านหลังการเลือกค่าที่ตั้งล่วงหน้า เพื่อป้อนได้ทันที</string>\n    <string name=\"scale_color_space\">สเกลปริภูมิสี</string>\n    <string name=\"linear\">เชิงเส้น</string>\n    <string name=\"equalize_histogram_pixelation\">ปรับพิกเซลฮิสโตแกรมให้เท่ากัน</string>\n    <string name=\"grid_size_x\">ตารางขนาด X</string>\n    <string name=\"grid_size_y\">ตารางขนาด Y</string>\n    <string name=\"equalize_histogram_adaptive\">ปรับฮิสโตแกรมให้เท่ากัน</string>\n    <string name=\"equalize_histogram_adaptive_luv\">ปรับฮิสโตแกรม Adaptive LUV ให้เท่ากัน</string>\n    <string name=\"equalize_histogram_adaptive_lab\">ปรับฮิสโตแกรม Adaptive LAB ให้เท่ากัน</string>\n    <string name=\"clahe\">แคลเฮ</string>\n    <string name=\"clahe_lab\">แคลเฮ่ แล็บ</string>\n    <string name=\"clahe_luv\">คลาเฮ่ ลูฟ</string>\n    <string name=\"crop_to_content\">ครอบตัดเป็นเนื้อหา</string>\n    <string name=\"frame_color\">สีกรอบ</string>\n    <string name=\"color_to_ignore\">สีที่ควรละเว้น</string>\n    <string name=\"template\">แม่แบบ</string>\n    <string name=\"no_template_filters\">ไม่มีการเพิ่มตัวกรองเทมเพลต</string>\n    <string name=\"create_new\">สร้างใหม่</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">รหัส QR ที่สแกนไม่ใช่เทมเพลตตัวกรองที่ถูกต้อง</string>\n    <string name=\"scan_qr_code\">สแกนรหัส QR</string>\n    <string name=\"opened_file_have_no_filter_template\">ไฟล์ที่เลือกไม่มีข้อมูลเทมเพลตตัวกรอง</string>\n    <string name=\"create_template\">สร้างเทมเพลต</string>\n    <string name=\"template_name\">ชื่อเทมเพลต</string>\n    <string name=\"select_template_preview\">รูปภาพนี้จะถูกใช้เพื่อดูตัวอย่างเทมเพลตตัวกรองนี้</string>\n    <string name=\"template_filter\">ตัวกรองเทมเพลต</string>\n    <string name=\"as_qr_code\">เป็นภาพรหัส QR</string>\n    <string name=\"as_file\">เป็นไฟล์</string>\n    <string name=\"save_as_file\">บันทึกเป็นไฟล์</string>\n    <string name=\"save_as_qr_code_image\">บันทึกเป็นภาพรหัส QR</string>\n    <string name=\"delete_template\">ลบเทมเพลต</string>\n    <string name=\"delete_template_warn\">คุณกำลังจะลบตัวกรองเทมเพลตที่เลือก การดำเนินการนี้ไม่สามารถยกเลิกได้</string>\n    <string name=\"added_filter_template\">เพิ่มเทมเพลตตัวกรองชื่อ \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">ดูตัวอย่างตัวกรอง</string>\n    <string name=\"qr_code\">คิวอาร์และบาร์โค้ด</string>\n    <string name=\"qr_code_sub\">สแกนโค้ด QR และรับเนื้อหาหรือวางสตริงของคุณเพื่อสร้างโค้ดใหม่</string>\n    <string name=\"code_content\">เนื้อหาโค้ด</string>\n    <string name=\"scan_qr_code_to_replace_content\">สแกนบาร์โค้ดเพื่อแทนที่เนื้อหาในช่อง หรือพิมพ์บางอย่างเพื่อสร้างบาร์โค้ดใหม่ตามประเภทที่เลือก</string>\n    <string name=\"qr_description\">คำอธิบาย QR</string>\n    <string name=\"min\">นาที</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">ให้สิทธิ์กล้องในการตั้งค่าเพื่อสแกนโค้ด QR</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">ให้สิทธิ์กล้องในการตั้งค่าเพื่อสแกนเครื่องสแกนเอกสาร</string>\n    <string name=\"cubic\">คิวบิก</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">แฮมมิง</string>\n    <string name=\"hanning\">ฮันนิ่ง</string>\n    <string name=\"blackman\">แบล็คแมน</string>\n    <string name=\"welch\">เวลช์</string>\n    <string name=\"quadric\">สี่เหลี่ยม</string>\n    <string name=\"gaussian\">เกาส์เซียน</string>\n    <string name=\"sphinx\">สฟิงซ์</string>\n    <string name=\"bartlett\">บาร์ตเลตต์</string>\n    <string name=\"robidoux\">โรบิดูซ์</string>\n    <string name=\"robidoux_sharp\">โรบิดูซ์ ชาร์ป</string>\n    <string name=\"spline16\">เส้นโค้ง 16</string>\n    <string name=\"spline36\">สไปลน์ 36</string>\n    <string name=\"spline64\">สไปลน์ 64</string>\n    <string name=\"kaiser\">ไกเซอร์</string>\n    <string name=\"bartlett_hann\">บาร์ตเลตต์-เขา</string>\n    <string name=\"box\">กล่อง</string>\n    <string name=\"bohman\">โบห์แมน</string>\n    <string name=\"lanczos2\">ลันโซส 2</string>\n    <string name=\"lanczos3\">ลันโซส 3</string>\n    <string name=\"lanczos4\">ลันโซส 4</string>\n    <string name=\"lanczos2_jinc\">แลนซอส 2 จินซี</string>\n    <string name=\"lanczos3_jinc\">แลนซอส 3 จินซี</string>\n    <string name=\"lanczos4_jinc\">แลนซอส 4 จินซี</string>\n    <string name=\"cubic_sub\">การแก้ไขแบบลูกบาศก์ช่วยให้ปรับขนาดได้ราบรื่นขึ้นโดยพิจารณาจาก 16 พิกเซลที่ใกล้เคียงที่สุด ซึ่งให้ผลลัพธ์ที่ดีกว่าแบบไบลิเนียร์</string>\n    <string name=\"bspline_sub\">ใช้ฟังก์ชันพหุนามที่กำหนดเป็นชิ้นๆ เพื่อประมาณค่าเส้นโค้งหรือพื้นผิวได้อย่างราบรื่น การแสดงรูปร่างที่ยืดหยุ่นและต่อเนื่อง</string>\n    <string name=\"hamming_sub\">ฟังก์ชันหน้าต่างที่ใช้เพื่อลดการรั่วไหลของสเปกตรัมโดยการลดขอบของสัญญาณ ซึ่งมีประโยชน์ในการประมวลผลสัญญาณ</string>\n    <string name=\"hanning_sub\">รูปแบบหนึ่งของหน้าต่าง Hann ซึ่งใช้กันทั่วไปเพื่อลดการรั่วไหลของสเปกตรัมในแอปพลิเคชันการประมวลผลสัญญาณ</string>\n    <string name=\"blackman_sub\">ฟังก์ชั่นหน้าต่างที่ให้ความละเอียดความถี่ที่ดีโดยลดการรั่วไหลของสเปกตรัม ซึ่งมักใช้ในการประมวลผลสัญญาณ</string>\n    <string name=\"welch_sub\">ฟังก์ชันหน้าต่างที่ออกแบบมาเพื่อให้ความละเอียดความถี่ที่ดีพร้อมการลดการรั่วไหลของสเปกตรัม ซึ่งมักใช้ในการประมวลผลสัญญาณ</string>\n    <string name=\"quadric_sub\">วิธีการที่ใช้ฟังก์ชันสมการกำลังสองในการประมาณค่า เพื่อให้ได้ผลลัพธ์ที่ราบรื่นและต่อเนื่อง</string>\n    <string name=\"gaussian_sub\">วิธีการประมาณค่าที่ใช้ฟังก์ชัน Gaussian ซึ่งมีประโยชน์ในการปรับให้เรียบและลดสัญญาณรบกวนในภาพ</string>\n    <string name=\"sphinx_sub\">วิธีการสุ่มตัวอย่างขั้นสูงที่ให้การแก้ไขคุณภาพสูงโดยมีข้อผิดพลาดน้อยที่สุด</string>\n    <string name=\"bartlett_sub\">ฟังก์ชันหน้าต่างสามเหลี่ยมที่ใช้ในการประมวลผลสัญญาณเพื่อลดการรั่วไหลของสเปกตรัม</string>\n    <string name=\"robidoux_sub\">วิธีการแก้ไขคุณภาพสูงที่ปรับให้เหมาะสมสำหรับการปรับขนาดภาพที่เป็นธรรมชาติ ปรับสมดุลความคมชัดและความเรียบเนียน</string>\n    <string name=\"robidoux_sharp_sub\">รูปแบบที่คมชัดยิ่งขึ้นของวิธี Robidoux ซึ่งได้รับการปรับให้เหมาะสมเพื่อการปรับขนาดภาพที่คมชัด</string>\n    <string name=\"spline16_sub\">วิธีการประมาณค่าแบบ spline ที่ให้ผลลัพธ์ที่ราบรื่นโดยใช้ตัวกรอง 16-tap</string>\n    <string name=\"spline36_sub\">วิธีการประมาณค่าแบบ spline ที่ให้ผลลัพธ์ที่ราบรื่นโดยใช้ตัวกรอง 36-tap</string>\n    <string name=\"spline64_sub\">วิธีการประมาณค่าแบบ spline ที่ให้ผลลัพธ์ที่ราบรื่นโดยใช้ตัวกรอง 64-tap</string>\n    <string name=\"kaiser_sub\">วิธีการประมาณค่าที่ใช้หน้าต่าง Kaiser ช่วยให้สามารถควบคุมการแลกเปลี่ยนระหว่างความกว้างของกลีบหลักและระดับของกลีบด้านข้างได้ดี</string>\n    <string name=\"bartlett_hann_sub\">ฟังก์ชันหน้าต่างไฮบริดที่รวมหน้าต่าง Bartlett และ Hann ใช้เพื่อลดการรั่วไหลของสเปกตรัมในการประมวลผลสัญญาณ</string>\n    <string name=\"box_sub\">วิธีการสุ่มตัวอย่างแบบง่ายๆ ที่ใช้ค่าเฉลี่ยของค่าพิกเซลที่ใกล้ที่สุด ซึ่งมักส่งผลให้มีลักษณะเป็นบล็อก</string>\n    <string name=\"bohman_sub\">ฟังก์ชันหน้าต่างที่ใช้เพื่อลดการรั่วไหลของสเปกตรัม ให้ความละเอียดความถี่ที่ดีในการใช้งานการประมวลผลสัญญาณ</string>\n    <string name=\"lanczos2_sub\">วิธีการสุ่มตัวอย่างใหม่ที่ใช้ตัวกรอง Lanczos แบบ 2 กลีบเพื่อการประมาณค่าคุณภาพสูงโดยมีสิ่งแปลกปลอมน้อยที่สุด</string>\n    <string name=\"lanczos3_sub\">วิธีการสุ่มตัวอย่างใหม่ที่ใช้ตัวกรอง Lanczos แบบ 3 กลีบเพื่อการประมาณค่าคุณภาพสูงโดยมีสิ่งแปลกปลอมน้อยที่สุด</string>\n    <string name=\"lanczos4_sub\">วิธีการสุ่มตัวอย่างใหม่ที่ใช้ตัวกรอง Lanczos แบบ 4 กลีบเพื่อการประมาณค่าคุณภาพสูงโดยมีสิ่งแปลกปลอมน้อยที่สุด</string>\n    <string name=\"lanczos2_jinc_sub\">ตัวกรอง Lanczos 2 รุ่นหนึ่งที่ใช้ฟังก์ชัน Jinc ให้การแก้ไขคุณภาพสูงโดยมีสิ่งแปลกปลอมน้อยที่สุด</string>\n    <string name=\"lanczos3_jinc_sub\">ตัวกรอง Lanczos 3 รุ่นต่างๆ ที่ใช้ฟังก์ชัน Jinc ให้การแก้ไขคุณภาพสูงโดยมีสิ่งแปลกปลอมน้อยที่สุด</string>\n    <string name=\"lanczos4_jinc_sub\">ตัวกรอง Lanczos 4 รุ่นต่างๆ ที่ใช้ฟังก์ชัน Jinc ให้การแก้ไขคุณภาพสูงโดยมีสิ่งแปลกปลอมน้อยที่สุด</string>\n    <string name=\"ewa_hanning\">ฮานนิ่ง อีดับบลิวเอ</string>\n    <string name=\"ewa_hanning_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของตัวกรอง Hanning เพื่อการประมาณค่าและการสุ่มตัวอย่างใหม่อย่างราบรื่น</string>\n    <string name=\"ewa_robidoux\">โรบิดูซ์ อีดับเบิลยูเอ</string>\n    <string name=\"ewa_robidoux_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของตัวกรอง Robidoux เพื่อการสุ่มตัวอย่างคุณภาพสูง</string>\n    <string name=\"ewa_blackman\">แบล็คแมน อีฟ</string>\n    <string name=\"ewa_blackman_sub\">ตัวแปร Elliptical Weighted Average (EWA) ของตัวกรอง Blackman เพื่อลดปัญหาเสียงเรียกเข้า</string>\n    <string name=\"ewa_quadric\">EWA สี่เหลี่ยม</string>\n    <string name=\"ewa_quadric_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของตัวกรอง Quadric เพื่อการประมาณค่าที่ราบรื่น</string>\n    <string name=\"ewa_robidoux_sharp\">โรบิดูซ์ ชาร์ป EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของตัวกรอง Robidoux Sharp เพื่อผลลัพธ์ที่คมชัดยิ่งขึ้น</string>\n    <string name=\"ewa_lanczos3_jinc\">แลนซอส 3 จินค์ อีวา</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของตัวกรอง Lanczos 3 Jinc สำหรับการสุ่มตัวอย่างใหม่คุณภาพสูงด้วยนามแฝงที่ลดลง</string>\n    <string name=\"ginseng\">โสม</string>\n    <string name=\"ginseng_sub\">ฟิลเตอร์รีแซมปลิงที่ออกแบบมาเพื่อการประมวลผลภาพคุณภาพสูงโดยมีความสมดุลระหว่างความคมชัดและความนุ่มนวล</string>\n    <string name=\"ewa_ginseng\">โสม EWA</string>\n    <string name=\"ewa_ginseng_sub\">ตัวแปร Elliptical Weighted Average (EWA) ของฟิลเตอร์โสมเพื่อเพิ่มคุณภาพของภาพ</string>\n    <string name=\"ewa_lanczos_sharp\">แลนซอส ชาร์ป อีดับเบิลยูเอ</string>\n    <string name=\"ewa_lanczos_sharp_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของฟิลเตอร์ Lanczos Sharp เพื่อให้ได้ผลลัพธ์ที่คมชัดโดยมีจุดบกพร่องน้อยที่สุด</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA ที่คมชัดที่สุด</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของฟิลเตอร์ Lanczos 4 Sharpest สำหรับการสุ่มตัวอย่างภาพที่คมชัดอย่างยิ่ง</string>\n    <string name=\"ewa_lanczos_soft\">แลนซอส ซอฟท์ อีดับเบิลยูเอ</string>\n    <string name=\"ewa_lanczos_soft_sub\">รูปแบบ Elliptical Weighted Average (EWA) ของฟิลเตอร์ Lanczos Soft เพื่อการสุ่มตัวอย่างภาพที่นุ่มนวลยิ่งขึ้น</string>\n    <string name=\"haasn_soft\">ฮาซัน ซอฟท์</string>\n    <string name=\"haasn_soft_sub\">ตัวกรองการสุ่มตัวอย่างใหม่ซึ่งออกแบบโดย Haasn เพื่อการปรับขนาดภาพที่ราบรื่นและไม่มีข้อผิดพลาด</string>\n    <string name=\"format_conversion\">การแปลงรูปแบบ</string>\n    <string name=\"format_conversion_sub\">แปลงชุดรูปภาพจากรูปแบบหนึ่งเป็นอีกรูปแบบหนึ่ง</string>\n    <string name=\"dismiss_forever\">ยกเลิกตลอดไป</string>\n    <string name=\"image_stacking\">การซ้อนภาพ</string>\n    <string name=\"image_stacking_sub\">ซ้อนภาพซ้อนทับกันด้วยโหมดผสมผสานที่เลือก</string>\n    <string name=\"add_image\">เพิ่มรูปภาพ</string>\n    <string name=\"bins_count\">ถังขยะนับ</string>\n    <string name=\"clahe_hsl\">คลาห์ HSL</string>\n    <string name=\"clahe_hsv\">คลาห์ HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">ปรับ Histogram Adaptive HSL ให้เท่ากัน</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">ปรับ Histogram Adaptive HSV ให้เท่ากัน</string>\n    <string name=\"edge_mode\">โหมดขอบ</string>\n    <string name=\"clip\">คลิป</string>\n    <string name=\"wrap\">ห่อ</string>\n    <string name=\"color_blind_scheme\">ตาบอดสี</string>\n    <string name=\"color_blind_scheme_sub\">เลือกโหมดเพื่อปรับสีของธีมสำหรับตัวแปรตาบอดสีที่เลือก</string>\n    <string name=\"protanomaly_sub\">ความยากในการแยกแยะระหว่างเฉดสีแดงและสีเขียว</string>\n    <string name=\"deuteranomaly_sub\">ความยากในการแยกแยะระหว่างเฉดสีเขียวและสีแดง</string>\n    <string name=\"tritanomaly_sub\">ความยากในการแยกแยะระหว่างเฉดสีน้ำเงินและสีเหลือง</string>\n    <string name=\"protanopia_sub\">ไม่สามารถรับรู้สีแดงได้</string>\n    <string name=\"deuteranopia_sub\">ไม่สามารถรับรู้เฉดสีเขียวได้</string>\n    <string name=\"tritanopia_sub\">ไม่สามารถรับรู้เฉดสีฟ้าได้</string>\n    <string name=\"achromatomaly_sub\">ลดความไวต่อทุกสี</string>\n    <string name=\"achromatopsia_sub\">ตาบอดสีโดยสมบูรณ์เห็นแต่เฉดสีเทา</string>\n    <string name=\"not_use_color_blind_scheme\">อย่าใช้แผนตาบอดสี</string>\n    <string name=\"not_use_color_blind_scheme_sub\">สีจะตรงตามที่กำหนดไว้ในธีม</string>\n    <string name=\"sigmoidal\">ซิกมอยด์</string>\n    <string name=\"lagrange_2\">ลากรองจ์ 2</string>\n    <string name=\"lagrange_2_sub\">ฟิลเตอร์การแก้ไขลากรองจ์ลำดับที่ 2 เหมาะสำหรับการปรับขนาดภาพคุณภาพสูงพร้อมการเปลี่ยนภาพที่ราบรื่น</string>\n    <string name=\"lagrange_3\">ลากรองจ์ 3</string>\n    <string name=\"lagrange_3_sub\">ตัวกรองการแก้ไข Lagrange ในลำดับที่ 3 ให้ความแม่นยำที่ดีขึ้นและผลลัพธ์ที่ราบรื่นยิ่งขึ้นสำหรับการปรับขนาดภาพ</string>\n    <string name=\"lanczos_6\">ลันโซส 6</string>\n    <string name=\"lanczos_6_sub\">ตัวกรองการสุ่มตัวอย่าง Lanczos ที่มีลำดับสูงกว่าที่ 6 ช่วยให้ปรับขนาดภาพที่คมชัดและแม่นยำยิ่งขึ้น</string>\n    <string name=\"lanczos_6_jinc\">แลนซอส 6 จินซี</string>\n    <string name=\"lanczos_6_jinc_sub\">ตัวกรอง Lanczos 6 รูปแบบหนึ่งที่ใช้ฟังก์ชัน Jinc เพื่อปรับปรุงคุณภาพการสุ่มตัวอย่างรูปภาพ</string>\n    <string name=\"linear_box_blur\">กล่องเชิงเส้นเบลอ</string>\n    <string name=\"linear_tent_blur\">เชิงเส้นเต็นท์เบลอ</string>\n    <string name=\"linear_gaussian_box_blur\">กล่องลิเนียร์เกาส์เซียนเบลอ</string>\n    <string name=\"linear_stack_blur\">สแต็คเบลอเชิงเส้น</string>\n    <string name=\"gaussian_box_blur\">กล่องเกาส์เซียนเบลอ</string>\n    <string name=\"linear_fast_gaussian_blur_next\">ถัดไปเป็น Linear Fast Gaussian Blur</string>\n    <string name=\"linear_fast_gaussian_blur\">Linear Fast Gaussian Blur</string>\n    <string name=\"linear_gaussian_blur\">ลิเนียร์เกาส์เซียนเบลอ</string>\n    <string name=\"draw_filter_sub\">เลือกฟิลเตอร์หนึ่งอันเพื่อใช้เป็นสี</string>\n    <string name=\"replace_filter\">เปลี่ยนตัวกรอง</string>\n    <string name=\"pick_filter_info\">เลือกตัวกรองด้านล่างเพื่อใช้เป็นแปรงในภาพวาดของคุณ</string>\n    <string name=\"tiff_compression_scheme\">รูปแบบการบีบอัด TIFF</string>\n    <string name=\"low_poly\">โพลีต่ำ</string>\n    <string name=\"sand_painting\">จิตรกรรมทราย</string>\n    <string name=\"image_splitting\">การแยกภาพ</string>\n    <string name=\"image_splitting_sub\">แยกภาพเดี่ยวตามแถวหรือคอลัมน์</string>\n    <string name=\"fit_to_bounds\">พอดีกับขอบเขต</string>\n    <string name=\"fit_to_bounds_sub\">รวมโหมดการปรับขนาดครอบตัดเข้ากับพารามิเตอร์นี้เพื่อให้ได้ลักษณะการทำงานที่ต้องการ (ครอบตัด/ปรับให้พอดีกับอัตราส่วนภาพ)</string>\n    <string name=\"languages_imported\">นำเข้าภาษาเรียบร้อยแล้ว</string>\n    <string name=\"backup_ocr_models\">โมเดล OCR สำรอง</string>\n    <string name=\"import_word\">นำเข้า</string>\n    <string name=\"export\">ส่งออก</string>\n    <string name=\"position\">ตำแหน่ง</string>\n    <string name=\"center\">ศูนย์</string>\n    <string name=\"top_left\">ซ้ายบน</string>\n    <string name=\"top_right\">ขวาบน</string>\n    <string name=\"bottom_left\">ล่างซ้าย</string>\n    <string name=\"bottom_right\">ล่างขวา</string>\n    <string name=\"top_center\">ท็อปเซ็นเตอร์</string>\n    <string name=\"center_right\">ตรงกลางขวา</string>\n    <string name=\"bottom_center\">กลางล่าง</string>\n    <string name=\"center_left\">กลางซ้าย</string>\n    <string name=\"target_image\">รูปภาพเป้าหมาย</string>\n    <string name=\"palette_transfer\">การถ่ายโอนจานสี</string>\n    <string name=\"enhanced_oil\">น้ำมันเสริม</string>\n    <string name=\"simple_old_tv\">ทีวีเก่าที่เรียบง่าย</string>\n    <string name=\"hdr\">เอชดีอาร์</string>\n    <string name=\"gotham\">ก็อตแธม</string>\n    <string name=\"simple_sketch\">ร่างที่เรียบง่าย</string>\n    <string name=\"soft_glow\">โกลว์นุ่มนวล</string>\n    <string name=\"color_poster\">โปสเตอร์สี</string>\n    <string name=\"tri_tone\">ไตรโทน</string>\n    <string name=\"third_color\">สีที่สาม</string>\n    <string name=\"clahe_oklab\">คลาเฮอ โอแล็บ</string>\n    <string name=\"clahe_oklch\">คลารา โอลช์</string>\n    <string name=\"clahe_jzazbz\">คลาเฮ่ จาซบซ์</string>\n    <string name=\"polka_dot\">ลายจุด</string>\n    <string name=\"clustered_2x2_dithering\">การจัดกลุ่ม 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">การทำคลัสเตอร์ 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">การจัดกลุ่ม 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">ยีลิโลมา ไดเธอร์ริง</string>\n    <string name=\"no_favorite_options_selected\">ไม่ได้เลือกตัวเลือกที่ชื่นชอบ เพิ่มลงในหน้าเครื่องมือ</string>\n    <string name=\"add_favorites\">เพิ่มรายการโปรด</string>\n    <string name=\"harmony_complementary\">เสริม</string>\n    <string name=\"harmony_analogous\">คล้ายคลึงกัน</string>\n    <string name=\"harmony_triadic\">ไตรเอดิก</string>\n    <string name=\"harmony_split_complementary\">แยกส่วนเสริม</string>\n    <string name=\"harmony_tetradic\">เตตราดิก</string>\n    <string name=\"harmony_square\">สี่เหลี่ยม</string>\n    <string name=\"harmony_analogous_complementary\">อะนาล็อก + ส่วนเสริม</string>\n    <string name=\"color_tools\">เครื่องมือสี</string>\n    <string name=\"color_tools_sub\">ผสม สร้างโทนสี สร้างเฉดสี และอื่นๆ</string>\n    <string name=\"color_harmonies\">ความกลมกลืนของสี</string>\n    <string name=\"color_shading\">การแรเงาสี</string>\n    <string name=\"variation\">การเปลี่ยนแปลง</string>\n    <string name=\"tints\">โทนสี</string>\n    <string name=\"tones\">โทนเสียง</string>\n    <string name=\"shades\">เฉดสี</string>\n    <string name=\"color_mixing\">การผสมสี</string>\n    <string name=\"color_info\">ข้อมูลสี</string>\n    <string name=\"selected_color\">สีที่เลือก</string>\n    <string name=\"color_to_mix\">สีที่จะผสม</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">ไม่สามารถใช้ monet ในขณะที่เปิดสีไดนามิก</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">รูปภาพ LUT เป้าหมาย</string>\n    <string name=\"amatorka\">มือสมัครเล่น</string>\n    <string name=\"miss_etikate\">นางสาวมารยาท</string>\n    <string name=\"soft_elegance\">นุ่มนวลสง่างาม</string>\n    <string name=\"soft_elegance_variant\">รุ่น Soft Elegance</string>\n    <string name=\"palette_transfer_variant\">ตัวแปรการถ่ายโอนจานสี</string>\n    <string name=\"cube_lut\">3D ลุต</string>\n    <string name=\"target_cube_lut_file\">ไฟล์ 3D LUT เป้าหมาย (.cube / .CUBE)</string>\n    <string name=\"lut\">ลุต</string>\n    <string name=\"bleach_bypass\">สารฟอกขาวบายพาส</string>\n    <string name=\"candlelight\">แสงเทียน</string>\n    <string name=\"drop_blues\">วางบลูส์</string>\n    <string name=\"edgy_amber\">เอ็ดดี้ แอมเบอร์</string>\n    <string name=\"fall_colors\">สีฤดูใบไม้ร่วง</string>\n    <string name=\"film_stock_50\">สต็อกฟิล์ม 50</string>\n    <string name=\"foggy_night\">คืนหมอก</string>\n    <string name=\"kodak\">โกดัก</string>\n    <string name=\"save_empty_lut\">รับภาพ LUT ที่เป็นกลาง</string>\n    <string name=\"save_empty_lut_sub\">ขั้นแรก ใช้แอปพลิเคชันแก้ไขภาพที่คุณชื่นชอบเพื่อใช้ฟิลเตอร์กับ LUT ที่เป็นกลาง ซึ่งคุณสามารถหาได้ที่นี่ เพื่อให้ทำงานได้อย่างถูกต้อง แต่ละสีพิกเซลจะต้องไม่ขึ้นอยู่กับพิกเซลอื่นๆ (เช่น การเบลอจะไม่ทำงาน) เมื่อพร้อมแล้ว ให้ใช้อิมเมจ LUT ใหม่ของคุณเป็นอินพุตสำหรับตัวกรอง LUT 512*512</string>\n    <string name=\"pop_art\">ศิลปะป๊อป</string>\n    <string name=\"celluloid\">เซลลูลอยด์</string>\n    <string name=\"coffee\">กาแฟ</string>\n    <string name=\"golden_forest\">ป่าทอง</string>\n    <string name=\"greenish\">เขียว</string>\n    <string name=\"retro_yellow\">ย้อนยุคเหลือง</string>\n    <string name=\"links_preview\">ดูตัวอย่างลิงก์</string>\n    <string name=\"links_preview_sub\">เปิดใช้งานการดึงข้อมูลตัวอย่างลิงก์ในตำแหน่งที่คุณสามารถรับข้อความได้ (QRCode, OCR ฯลฯ)</string>\n    <string name=\"links\">ลิงค์</string>\n    <string name=\"ico_size_warning\">ไฟล์ ICO สามารถบันทึกได้ที่ขนาดสูงสุด 256 x 256 เท่านั้น</string>\n    <string name=\"gif_type_to_webp\">GIF เป็น WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">แปลงภาพ GIF เป็นภาพเคลื่อนไหว WEBP</string>\n    <string name=\"webp_tools\">เครื่องมือเว็บพี</string>\n    <string name=\"webp_tools_sub\">แปลงรูปภาพเป็นภาพเคลื่อนไหว WEBP หรือแยกเฟรมจากภาพเคลื่อนไหว WEBP ที่กำหนด</string>\n    <string name=\"webp_type_to_image\">WEBP เป็นรูปภาพ</string>\n    <string name=\"webp_type_to_image_sub\">แปลงไฟล์ WEBP เป็นชุดรูปภาพ</string>\n    <string name=\"webp_type_to_webp_sub\">แปลงชุดรูปภาพเป็นไฟล์ WEBP</string>\n    <string name=\"webp_type_to_webp\">รูปภาพไปยัง WEBP</string>\n    <string name=\"select_webp_image_to_start\">เลือกรูปภาพ WEBP เพื่อเริ่มต้น</string>\n    <string name=\"manage_storage_extra_types\">ไม่มีสิทธิ์เข้าถึงไฟล์โดยสมบูรณ์</string>\n    <string name=\"manage_storage_extra_types_sub\">อนุญาตให้เข้าถึงไฟล์ทั้งหมดเพื่อดู JXL, QOI และรูปภาพอื่น ๆ ที่ไม่ได้รับการยอมรับว่าเป็นรูปภาพบน Android หากไม่ได้รับอนุญาต Image Toolbox จะไม่สามารถแสดงภาพเหล่านั้นได้</string>\n    <string name=\"default_draw_color\">สีวาดเริ่มต้น</string>\n    <string name=\"default_draw_path_mode\">โหมดเส้นทางการวาดเริ่มต้น</string>\n    <string name=\"add_timestamp\">เพิ่มการประทับเวลา</string>\n    <string name=\"add_timestamp_sub\">เปิดใช้งานการประทับเวลาโดยเพิ่มชื่อไฟล์เอาต์พุต</string>\n    <string name=\"formatted_timestamp\">การประทับเวลาที่จัดรูปแบบ</string>\n    <string name=\"formatted_timestamp_sub\">เปิดใช้งานการจัดรูปแบบการประทับเวลาในชื่อไฟล์เอาต์พุตแทนมิลลิวินาทีพื้นฐาน</string>\n    <string name=\"enable_timestamps_to_format_them\">เปิดใช้งานการประทับเวลาเพื่อเลือกรูปแบบ</string>\n    <string name=\"one_time_save_location\">บันทึกตำแหน่งครั้งเดียว</string>\n    <string name=\"one_time_save_location_sub\">ดูและแก้ไขตำแหน่งบันทึกครั้งเดียวซึ่งคุณสามารถใช้งานได้โดยกดปุ่มบันทึกค้างไว้ในตัวเลือกส่วนใหญ่ทั้งหมด</string>\n    <string name=\"recently_used\">ใช้ล่าสุด</string>\n    <string name=\"ci_channel\">ช่องซีไอ</string>\n    <string name=\"group\">กลุ่ม</string>\n    <string name=\"image_toolbox_in_telegram\">กล่องเครื่องมือรูปภาพในโทรเลข 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">เข้าร่วมแชทของเราที่คุณสามารถพูดคุยอะไรก็ได้ที่คุณต้องการและดูที่ช่อง CI ที่ฉันโพสต์เบต้าและประกาศต่างๆ</string>\n    <string name=\"ci_channel_sub\">รับการแจ้งเตือนเกี่ยวกับแอปเวอร์ชันใหม่และอ่านประกาศ</string>\n    <string name=\"fit_description\">ปรับภาพให้พอดีกับขนาดที่กำหนด และใช้การเบลอหรือสีกับพื้นหลัง</string>\n    <string name=\"tools_arrangement\">การจัดเครื่องมือ</string>\n    <string name=\"group_tools_by_type\">จัดกลุ่มเครื่องมือตามประเภท</string>\n    <string name=\"group_tools_by_type_sub\">จัดกลุ่มเครื่องมือบนหน้าจอหลักตามประเภท แทนที่จะจัดเรียงรายการแบบกำหนดเอง</string>\n    <string name=\"default_values\">ค่าเริ่มต้น</string>\n    <string name=\"system_bars_visibility\">การมองเห็นแถบระบบ</string>\n    <string name=\"show_system_bars_by_swipe\">แสดงแถบระบบโดยการปัด</string>\n    <string name=\"show_system_bars_by_swipe_sub\">เปิดใช้งานการปัดเพื่อแสดงแถบระบบหากซ่อนอยู่</string>\n    <string name=\"auto\">อัตโนมัติ</string>\n    <string name=\"hide_all\">ซ่อนทั้งหมด</string>\n    <string name=\"show_all\">แสดงทั้งหมด</string>\n    <string name=\"hide_nav_bar\">ซ่อนแถบนำทาง</string>\n    <string name=\"hide_status_bar\">ซ่อนแถบสถานะ</string>\n    <string name=\"noise_generation\">การสร้างเสียงรบกวน</string>\n    <string name=\"noise_generation_sub\">สร้างเสียงต่างๆ เช่น เสียงเพอร์ลินหรือเสียงประเภทอื่นๆ</string>\n    <string name=\"frequency\">ความถี่</string>\n    <string name=\"noise_type\">ประเภทเสียงรบกวน</string>\n    <string name=\"rotation_type\">ประเภทการหมุน</string>\n    <string name=\"fractal_type\">ประเภทแฟร็กทัล</string>\n    <string name=\"octaves\">อ็อกเทฟ</string>\n    <string name=\"lacunarity\">ความไม่ชัดเจน</string>\n    <string name=\"gain\">ได้รับ</string>\n    <string name=\"weighted_strength\">ความแข็งแกร่งแบบถ่วงน้ำหนัก</string>\n    <string name=\"ping_pong_strength\">ความแรงของปิงปอง</string>\n    <string name=\"distance_function\">ฟังก์ชันระยะทาง</string>\n    <string name=\"return_type\">ประเภทการส่งคืน</string>\n    <string name=\"jitter\">กระวนกระวายใจ</string>\n    <string name=\"domain_warp\">โดเมนวาร์ป</string>\n    <string name=\"alignment\">การจัดตำแหน่ง</string>\n    <string name=\"custom_filename\">ชื่อไฟล์ที่กำหนดเอง</string>\n    <string name=\"custom_filename_sub\">เลือกตำแหน่งและชื่อไฟล์ที่จะใช้ในการบันทึกภาพปัจจุบัน</string>\n    <string name=\"saved_to_custom\">บันทึกลงในโฟลเดอร์ด้วยชื่อที่กำหนดเอง</string>\n    <string name=\"collage_maker\">เครื่องสร้างคอลลาจ</string>\n    <string name=\"collage_maker_sub\">สร้างภาพต่อกันจากภาพสูงสุด 20 ภาพ</string>\n    <string name=\"collage_type\">ประเภทคอลลาจ</string>\n    <string name=\"collages_info\">กดภาพค้างไว้เพื่อสลับ ย้าย และซูมเพื่อปรับตำแหน่ง</string>\n    <string name=\"disable_rotation\">ปิดการใช้งานการหมุน</string>\n    <string name=\"disable_rotation_sub\">ป้องกันการหมุนภาพด้วยท่าทางสองนิ้ว</string>\n    <string name=\"enable_snapping_to_borders\">เปิดใช้งานการจัดชิดขอบ</string>\n    <string name=\"enable_snapping_to_borders_sub\">หลังจากย้ายหรือซูม รูปภาพจะจัดชิดขอบเฟรม</string>\n    <string name=\"histogram\">ฮิสโตแกรม</string>\n    <string name=\"histogram_sub\">ฮิสโตแกรมภาพ RGB หรือความสว่างเพื่อช่วยคุณปรับแต่ง</string>\n    <string name=\"image_for_histogram\">รูปภาพนี้จะถูกนำมาใช้เพื่อสร้างฮิสโตแกรม RGB และความสว่าง</string>\n    <string name=\"tesseract_options\">ตัวเลือกเทสเซอร์แรค</string>\n    <string name=\"tesseract_options_sub\">ใช้ตัวแปรอินพุตบางตัวสำหรับเอ็นจิ้น tesseract</string>\n    <string name=\"custom_options\">ตัวเลือกที่กำหนดเอง</string>\n    <string name=\"custom_params_info\">ควรป้อนตัวเลือกตามรูปแบบนี้: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">ครอบตัดอัตโนมัติ</string>\n    <string name=\"free_corners\">มุมฟรี</string>\n    <string name=\"free_corners_sub\">ครอบตัดรูปภาพตามรูปหลายเหลี่ยม ซึ่งจะช่วยแก้ไขเปอร์สเปคทีฟด้วย</string>\n    <string name=\"coerce_points_to_image_bounds\">บังคับชี้ไปที่ขอบเขตของภาพ</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">จุดจะไม่ถูกจำกัดด้วยขอบเขตของภาพ ซึ่งมีประโยชน์สำหรับการแก้ไขเปอร์สเปคทีฟที่แม่นยำยิ่งขึ้น</string>\n    <string name=\"mask\">หน้ากาก</string>\n    <string name=\"spot_heal_sub\">เนื้อหารับรู้การเติมภายใต้เส้นทางที่วาด</string>\n    <string name=\"spot_heal\">จุดรักษา</string>\n    <string name=\"use_circle_kernel\">ใช้เคอร์เนลวงกลม</string>\n    <string name=\"opening\">กำลังเปิด</string>\n    <string name=\"closing\">ปิด</string>\n    <string name=\"morphological_gradient\">การไล่ระดับทางสัณฐานวิทยา</string>\n    <string name=\"top_hat\">หมวกทรงสูง</string>\n    <string name=\"black_hat\">หมวกดำ</string>\n    <string name=\"tone_curves\">เส้นโค้งโทน</string>\n    <string name=\"reset_curves\">รีเซ็ตเส้นโค้ง</string>\n    <string name=\"reset_curves_sub\">เส้นโค้งจะถูกย้อนกลับเป็นค่าเริ่มต้น</string>\n    <string name=\"line_style\">สไตล์เส้น</string>\n    <string name=\"gap_size\">ขนาดช่องว่าง</string>\n    <string name=\"dashed\">ประ</string>\n    <string name=\"dot_dashed\">ดอทแดช</string>\n    <string name=\"stamped\">ประทับตรา</string>\n    <string name=\"zigzag\">ซิกแซก</string>\n    <string name=\"dashed_sub\">วาดเส้นประตามเส้นทางที่วาดด้วยขนาดช่องว่างที่ระบุ</string>\n    <string name=\"dot_dashed_sub\">วาดจุดและเส้นประตามเส้นทางที่กำหนด</string>\n    <string name=\"defaultt_sub\">แค่เส้นตรงเริ่มต้น</string>\n    <string name=\"stamped_sub\">วาดรูปร่างที่เลือกไปตามเส้นทางโดยมีระยะห่างที่ระบุ</string>\n    <string name=\"zigzag_sub\">ดึงซิกแซกหยักไปตามเส้นทาง</string>\n    <string name=\"zigzag_ratio\">อัตราส่วนซิกแซก</string>\n    <string name=\"create_shortcut\">สร้างทางลัด</string>\n    <string name=\"create_shortcut_title\">เลือกเครื่องมือที่จะปักหมุด</string>\n    <string name=\"create_shortcut_subtitle\">เครื่องมือจะถูกเพิ่มลงในหน้าจอหลักของ Launcher ของคุณเป็นทางลัด โดยใช้ร่วมกับการตั้งค่า \\\"ข้ามการเลือกไฟล์\\\" เพื่อให้บรรลุการทำงานที่จำเป็น</string>\n    <string name=\"dont_stack_frames\">อย่าซ้อนเฟรม</string>\n    <string name=\"dont_stack_frames_sub\">ช่วยให้สามารถกำจัดเฟรมก่อนหน้าได้ ดังนั้นเฟรมเหล่านั้นจะไม่ซ้อนกัน</string>\n    <string name=\"crossfade\">ครอสเฟด</string>\n    <string name=\"crossfade_sub\">เฟรมจะถูกครอสเฟดเข้าหากัน</string>\n    <string name=\"crossfade_count\">จำนวนเฟรมครอสเฟด</string>\n    <string name=\"threshold_one\">เกณฑ์ที่หนึ่ง</string>\n    <string name=\"threshold_two\">เกณฑ์ที่สอง</string>\n    <string name=\"canny\">แคนนี่</string>\n    <string name=\"mirror_101\">กระจกเงา 101</string>\n    <string name=\"enhanced_zoom_blur\">ปรับปรุงการซูมเบลอ</string>\n    <string name=\"laplacian_simple\">ลาปลาเซียนธรรมดา</string>\n    <string name=\"sobel_simple\">โซเบล ซิมเพิล</string>\n    <string name=\"helper_grid\">ผู้ช่วยกริด</string>\n    <string name=\"helper_grid_sub\">แสดงตารางสนับสนุนเหนือพื้นที่วาดภาพเพื่อช่วยในการปรับแต่งที่แม่นยำ</string>\n    <string name=\"grid_color\">สีตาราง</string>\n    <string name=\"cell_width\">ความกว้างของเซลล์</string>\n    <string name=\"cell_height\">ความสูงของเซลล์</string>\n    <string name=\"compact_selectors\">ตัวเลือกขนาดกะทัดรัด</string>\n    <string name=\"compact_selectors_sub\">ตัวควบคุมการเลือกบางตัวจะใช้รูปแบบกะทัดรัดเพื่อใช้พื้นที่น้อยลง</string>\n    <string name=\"grant_camera_permission_to_capture_image\">ให้สิทธิ์กล้องในการตั้งค่าเพื่อจับภาพ</string>\n    <string name=\"layout\">เค้าโครง</string>\n    <string name=\"main_screen_title\">ชื่อหน้าจอหลัก</string>\n    <string name=\"constant_rate_factor\">ปัจจัยอัตราคงที่ (CRF)</string>\n    <string name=\"crf_sub\">ค่า %1$s หมายถึงการบีบอัดที่ช้า ส่งผลให้ขนาดไฟล์ค่อนข้างเล็ก %2$s หมายถึงการบีบอัดที่เร็วขึ้น ส่งผลให้ไฟล์มีขนาดใหญ่</string>\n    <string name=\"lut_library\">ห้องสมุดลุต</string>\n    <string name=\"lut_library_sub\">ดาวน์โหลดชุด LUT ซึ่งคุณสามารถสมัครได้หลังจากดาวน์โหลด</string>\n    <string name=\"lut_library_update_sub\">อัปเดตคอลเลกชันของ LUT (เฉพาะรายการใหม่เท่านั้นที่จะถูกจัดคิว) ซึ่งคุณสามารถใช้ได้หลังจากดาวน์โหลด</string>\n    <string name=\"filter_preview_image_sub\">เปลี่ยนการแสดงตัวอย่างรูปภาพเริ่มต้นสำหรับตัวกรอง</string>\n    <string name=\"filter_preview_image\">ดูตัวอย่างรูปภาพ</string>\n    <string name=\"hide\">ซ่อน</string>\n    <string name=\"show\">แสดง</string>\n    <string name=\"slider_type\">ประเภทสไลเดอร์</string>\n    <string name=\"fancy\">ไม่ธรรมดา</string>\n    <string name=\"material_2\">วัสดุ 2</string>\n    <string name=\"fancy_sub\">แถบเลื่อนที่ดูแฟนซี นี่คือตัวเลือกเริ่มต้น</string>\n    <string name=\"material_2_sub\">แถบเลื่อนวัสดุ 2</string>\n    <string name=\"material_you_slider_sub\">แถบเลื่อน Material You</string>\n    <string name=\"apply\">นำมาใช้</string>\n    <string name=\"center_align_dialog_buttons\">ปุ่มโต้ตอบตรงกลาง</string>\n    <string name=\"center_align_dialog_buttons_sub\">ปุ่มของกล่องโต้ตอบจะถูกวางตำแหน่งตรงกลางแทนที่จะเป็นด้านซ้ายหากเป็นไปได้</string>\n    <string name=\"open_source_licenses\">ใบอนุญาตโอเพ่นซอร์ส</string>\n    <string name=\"open_source_licenses_sub\">ดูใบอนุญาตของไลบรารีโอเพ่นซอร์สที่ใช้ในแอปนี้</string>\n    <string name=\"area\">พื้นที่</string>\n    <string name=\"area_sub\">การสุ่มตัวอย่างใหม่โดยใช้ความสัมพันธ์ของพื้นที่พิกเซล อาจเป็นวิธีที่นิยมใช้สำหรับการทำลายภาพ เนื่องจากให้ผลลัพธ์ที่ปราศจากรอยมัว แต่เมื่อซูมภาพ จะคล้ายกับวิธี \\\"ใกล้ที่สุด\\\"</string>\n    <string name=\"enable_tonemapping\">เปิดใช้งาน Tonemapping</string>\n    <string name=\"enter_percent\">เข้า %</string>\n    <string name=\"unknown_host\">ไม่สามารถเข้าถึงไซต์ได้ ลองใช้ VPN หรือตรวจสอบว่า URL ถูกต้องหรือไม่</string>\n    <string name=\"markup_layers\">เลเยอร์มาร์กอัป</string>\n    <string name=\"markup_layers_sub\">โหมดเลเยอร์ที่มีความสามารถในการวางรูปภาพ ข้อความ และอื่นๆ ได้อย่างอิสระ</string>\n    <string name=\"edit_layer\">แก้ไขเลเยอร์</string>\n    <string name=\"layers_on_image\">เลเยอร์บนภาพ</string>\n    <string name=\"layers_on_image_sub\">ใช้รูปภาพเป็นพื้นหลังและเพิ่มเลเยอร์ต่างๆ ไว้ด้านบน</string>\n    <string name=\"layers_on_background\">เลเยอร์บนพื้นหลัง</string>\n    <string name=\"layers_on_background_sub\">เช่นเดียวกับตัวเลือกแรก แต่มีสีแทนรูปภาพ</string>\n    <string name=\"beta\">เบต้า</string>\n    <string name=\"fast_settings_side\">ด้านการตั้งค่าด่วน</string>\n    <string name=\"fast_settings_side_sub\">เพิ่มแถบลอยที่ด้านที่เลือกขณะแก้ไขรูปภาพ ซึ่งจะเปิดการตั้งค่าที่รวดเร็วเมื่อคลิก</string>\n    <string name=\"clear_selection\">ล้างการเลือก</string>\n    <string name=\"settings_group_visibility_hidden\">การตั้งค่ากลุ่ม \\\"%1$s\\\" จะถูกยุบโดยค่าเริ่มต้น</string>\n    <string name=\"settings_group_visibility_visible\">การตั้งค่ากลุ่ม \\\"%1$s\\\" จะถูกขยายตามค่าเริ่มต้น</string>\n    <string name=\"base_64_tools\">เครื่องมือ Base64</string>\n    <string name=\"base_64_tools_sub\">ถอดรหัสสตริง Base64 เป็นรูปภาพ หรือเข้ารหัสรูปภาพเป็นรูปแบบ Base64</string>\n    <string name=\"base_64\">ฐาน64</string>\n    <string name=\"not_a_valid_base_64\">ค่าที่ระบุไม่ใช่สตริง Base64 ที่ถูกต้อง</string>\n    <string name=\"copy_not_a_valid_base_64\">ไม่สามารถคัดลอกสตริง Base64 ที่ว่างเปล่าหรือไม่ถูกต้อง</string>\n    <string name=\"paste_base_64\">วางฐาน64</string>\n    <string name=\"copy_base_64\">คัดลอก Base64</string>\n    <string name=\"base_64_tips\">โหลดรูปภาพเพื่อคัดลอกหรือบันทึกสตริง Base64 หากคุณมีสตริง คุณสามารถวางที่ด้านบนเพื่อรับรูปภาพได้</string>\n    <string name=\"save_base_64\">บันทึก Base64</string>\n    <string name=\"share_base_64\">แบ่งปัน Base64</string>\n    <string name=\"options\">ตัวเลือก</string>\n    <string name=\"actions\">การดำเนินการ</string>\n    <string name=\"import_base_64\">นำเข้า Base64</string>\n    <string name=\"base_64_actions\">การกระทำ Base64</string>\n    <string name=\"add_outline\">เพิ่มโครงร่าง</string>\n    <string name=\"add_outline_sub\">เพิ่มเค้าร่างรอบข้อความด้วยสีและความกว้างที่ระบุ</string>\n    <string name=\"outline_color\">สีเค้าร่าง</string>\n    <string name=\"outline_size\">ขนาดเค้าร่าง</string>\n    <string name=\"rotation\">การหมุน</string>\n    <string name=\"checksum_as_filename\">Checksum เป็นชื่อไฟล์</string>\n    <string name=\"checksum_as_filename_sub\">รูปภาพที่ส่งออกจะมีชื่อที่สอดคล้องกับผลรวมการตรวจสอบข้อมูล</string>\n    <string name=\"free_software_partner\">ซอฟต์แวร์ฟรี (พันธมิตร)</string>\n    <string name=\"free_software_partner_sub\">ซอฟต์แวร์ที่มีประโยชน์มากขึ้นในช่องพันธมิตรของแอปพลิเคชัน Android</string>\n    <string name=\"algorithms\">อัลกอริทึม</string>\n    <string name=\"checksum_tools\">เครื่องมือตรวจสอบผลรวม</string>\n    <string name=\"checksum_tools_sub\">เปรียบเทียบเช็คซัม คำนวณแฮช หรือสร้างสตริงเลขฐานสิบหกจากไฟล์โดยใช้อัลกอริธึมแฮชที่แตกต่างกัน</string>\n    <string name=\"calculate\">คำนวณ</string>\n    <string name=\"text_hash\">แฮชข้อความ</string>\n    <string name=\"checksum\">เช็คซัม</string>\n    <string name=\"pick_file_to_checksum\">เลือกไฟล์เพื่อคำนวณผลรวมตรวจสอบตามอัลกอริทึมที่เลือก</string>\n    <string name=\"enter_text_to_checksum\">ป้อนข้อความเพื่อคำนวณผลรวมตรวจสอบตามอัลกอริทึมที่เลือก</string>\n    <string name=\"source_checksum\">การตรวจสอบแหล่งที่มา</string>\n    <string name=\"checksum_to_compare\">เช็คซัมเพื่อเปรียบเทียบ</string>\n    <string name=\"match\">จับคู่!</string>\n    <string name=\"difference\">ความแตกต่าง</string>\n    <string name=\"match_sub\">เช็คซัมเท่ากันก็ปลอดภัยได้</string>\n    <string name=\"difference_sub\">เช็คซัมไม่เท่ากัน ไฟล์อาจไม่ปลอดภัย!</string>\n    <string name=\"mesh_gradients\">การไล่ระดับสีแบบตาข่าย</string>\n    <string name=\"collection_mesh_gradients_sub\">ดูคอลเลกชันออนไลน์ของการไล่ระดับสีแบบตาข่าย</string>\n    <string name=\"wrong_font\">สามารถนำเข้าได้เฉพาะแบบอักษร TTF และ OTF เท่านั้น</string>\n    <string name=\"import_font\">นำเข้าแบบอักษร (TTF/OTF)</string>\n    <string name=\"export_fonts\">ส่งออกแบบอักษร</string>\n    <string name=\"imported_fonts\">แบบอักษรที่นำเข้า</string>\n    <string name=\"error_while_saving\">เกิดข้อผิดพลาดขณะบันทึกความพยายาม พยายามเปลี่ยนโฟลเดอร์เอาต์พุต</string>\n    <string name=\"filename_is_not_set\">ไม่ได้ตั้งชื่อไฟล์</string>\n    <string name=\"none\">ไม่มี</string>\n    <string name=\"custom_pages\">หน้าที่กำหนดเอง</string>\n    <string name=\"pages_selection\">การเลือกหน้า</string>\n    <string name=\"tool_exit_confirmation\">การยืนยันการออกจากเครื่องมือ</string>\n    <string name=\"tool_exit_confirmation_sub\">หากคุณยังไม่ได้บันทึกการเปลี่ยนแปลงในขณะที่ใช้เครื่องมือเฉพาะและพยายามปิด กล่องโต้ตอบการยืนยันจะปรากฏขึ้น</string>\n    <string name=\"edit_exif_screen\">แก้ไข EXIF</string>\n    <string name=\"edit_exif_screen_sub\">เปลี่ยนข้อมูลเมตาของภาพเดียวโดยไม่ต้องบีบอัดใหม่</string>\n    <string name=\"edit_exif_tag\">แตะเพื่อแก้ไขแท็กที่มีอยู่</string>\n    <string name=\"change_sticker\">เปลี่ยนสติ๊กเกอร์</string>\n    <string name=\"fit_width\">พอดีความกว้าง</string>\n    <string name=\"fit_height\">พอดีกับความสูง</string>\n    <string name=\"batch_compare\">เปรียบเทียบแบทช์</string>\n    <string name=\"pick_files_to_checksum\">เลือกไฟล์/ไฟล์เพื่อคำนวณผลรวมตามอัลกอริทึมที่เลือก</string>\n    <string name=\"pick_files\">เลือกไฟล์</string>\n    <string name=\"pick_directory\">เลือกไดเรกทอรี</string>\n    <string name=\"head_length_scale\">สเกลความยาวศีรษะ</string>\n    <string name=\"stamp\">แสตมป์</string>\n    <string name=\"timestamp\">การประทับเวลา</string>\n    <string name=\"format_pattern\">รูปแบบรูปแบบ</string>\n    <string name=\"padding\">ช่องว่างภายใน</string>\n    <string name=\"image_cutting\">การตัดภาพ</string>\n    <string name=\"image_cutting_sub\">ตัดส่วนของรูปภาพและรวมส่วนด้านซ้าย (สามารถกลับด้านได้) ด้วยเส้นแนวตั้งหรือแนวนอน</string>\n    <string name=\"vertical_pivot_line\">เส้นเดือยแนวตั้ง</string>\n    <string name=\"horizontal_pivot_line\">เส้นหมุนแนวนอน</string>\n    <string name=\"inverse_selection\">การเลือกแบบผกผัน</string>\n    <string name=\"inverse_vertical_selection_sub\">ส่วนที่ตัดแนวตั้งจะปล่อยทิ้งไว้ แทนที่จะรวมส่วนที่ตัดไว้รอบๆ บริเวณที่ตัด</string>\n    <string name=\"inverse_horizontal_selection_sub\">ส่วนที่ตัดแนวนอนจะเหลือไว้ แทนที่จะรวมส่วนที่ตัดไว้รอบๆ บริเวณที่ตัด</string>\n    <string name=\"collection_mesh_gradients\">คอลเลกชันของเมชเกรเดียน</string>\n    <string name=\"mesh_gradients_sub\">สร้างการไล่ระดับสีแบบตาข่ายด้วยจำนวนนอตและความละเอียดที่กำหนดเอง</string>\n    <string name=\"gradient_maker_type_image_mesh\">การซ้อนทับแบบไล่ระดับแบบตาข่าย</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">เขียนการไล่ระดับสีแบบตาข่ายที่ด้านบนของรูปภาพที่กำหนด</string>\n    <string name=\"points_customization\">การปรับแต่งคะแนน</string>\n    <string name=\"grid_size\">ขนาดตาราง</string>\n    <string name=\"resolution_x\">ความละเอียด X</string>\n    <string name=\"resolution_y\">ความละเอียด Y</string>\n    <string name=\"resolution\">ปณิธาน</string>\n    <string name=\"pixel_by_pixel\">พิกเซลต่อพิกเซล</string>\n    <string name=\"highlight_color\">ไฮไลท์สี</string>\n    <string name=\"pixel_comparison_type\">ประเภทการเปรียบเทียบพิกเซล</string>\n    <string name=\"scan_barcode\">สแกนบาร์โค้ด</string>\n    <string name=\"height_ratio\">อัตราส่วนความสูง</string>\n    <string name=\"barcode_type\">ประเภทบาร์โค้ด</string>\n    <string name=\"enforce_bw\">บังคับใช้ขาวดำ</string>\n    <string name=\"enforce_bw_sub\">รูปภาพบาร์โค้ดจะเป็นสีขาวดำทั้งหมด และไม่มีสีตามธีมของแอป</string>\n    <string name=\"barcodes_sub\">สแกนบาร์โค้ด (QR, EAN, AZTEC, …) และรับเนื้อหาหรือวางข้อความของคุณเพื่อสร้างใหม่</string>\n    <string name=\"no_barcode_found\">ไม่พบบาร์โค้ด</string>\n    <string name=\"generated_barcode_will_be_here\">บาร์โค้ดที่สร้างขึ้นจะอยู่ที่นี่</string>\n    <string name=\"audio_cover_extractor\">ปกเสียง</string>\n    <string name=\"audio_cover_extractor_sub\">แยกภาพปกอัลบั้มออกจากไฟล์เสียง รองรับรูปแบบทั่วไปส่วนใหญ่</string>\n    <string name=\"pick_audio_to_start\">เลือกเสียงเพื่อเริ่มต้น</string>\n    <string name=\"pick_audio\">เลือกเสียง</string>\n    <string name=\"no_covers_found\">ไม่พบปก</string>\n    <string name=\"send_logs\">ส่งบันทึก</string>\n    <string name=\"send_logs_sub\">คลิกเพื่อแชร์ไฟล์บันทึกของแอป ซึ่งสามารถช่วยฉันระบุปัญหาและแก้ไขปัญหาได้</string>\n    <string name=\"crash_title\">อ๊ะ… มีบางอย่างผิดพลาด</string>\n    <string name=\"crash_subtitle\">คุณสามารถติดต่อฉันได้โดยใช้ตัวเลือกด้านล่าง แล้วฉันจะพยายามหาวิธีแก้ปัญหา\\n(อย่าลืมแนบบันทึก)</string>\n    <string name=\"ocr_write_to_file\">เขียนลงไฟล์</string>\n    <string name=\"ocr_write_to_file_sub\">แยกข้อความออกจากชุดรูปภาพและจัดเก็บไว้ในไฟล์ข้อความเดียว</string>\n    <string name=\"ocr_write_to_metadata\">เขียนถึงข้อมูลเมตา</string>\n    <string name=\"ocr_write_to_metadata_sub\">แยกข้อความจากแต่ละภาพและวางไว้ในข้อมูล EXIF ​​ของภาพถ่ายที่เกี่ยวข้อง</string>\n    <string name=\"invisible_mode\">โหมดที่มองไม่เห็น</string>\n    <string name=\"invisible_mode_sub\">ใช้การอำพรางเพื่อสร้างลายน้ำที่มองไม่เห็นด้วยตาภายในจำนวนไบต์ของรูปภาพของคุณ</string>\n    <string name=\"use_lsb\">ใช้ LSB</string>\n    <string name=\"use_lsb_sub\">จะใช้วิธี Steganography แบบ LSB (Less Significant Bit) มิฉะนั้น FD (โดเมนความถี่)</string>\n    <string name=\"auto_remove_red_eyes\">ลบตาแดงอัตโนมัติ</string>\n    <string name=\"password\">รหัสผ่าน</string>\n    <string name=\"unlock\">ปลดล็อค</string>\n    <string name=\"pdf_is_protected\">PDF ได้รับการคุ้มครอง</string>\n    <string name=\"operation_almost_complete\">ปฏิบัติการใกล้จะเสร็จสมบูรณ์แล้ว การยกเลิกตอนนี้จะต้องเริ่มต้นใหม่อีกครั้ง</string>\n    <string name=\"sort_by_date_modified\">วันที่แก้ไข</string>\n    <string name=\"sort_by_date_modified_reversed\">วันที่แก้ไข (กลับรายการ)</string>\n    <string name=\"sort_by_size\">ขนาด</string>\n    <string name=\"sort_by_size_reversed\">ขนาด (กลับด้าน)</string>\n    <string name=\"sort_by_mime_type\">ประเภทไมม์</string>\n    <string name=\"sort_by_mime_type_reversed\">ประเภท MIME (กลับด้าน)</string>\n    <string name=\"sort_by_extension\">ส่วนขยาย</string>\n    <string name=\"sort_by_extension_reversed\">ส่วนขยาย (กลับด้าน)</string>\n    <string name=\"sort_by_date_added\">วันที่เพิ่ม</string>\n    <string name=\"sort_by_date_added_reversed\">วันที่เพิ่ม (กลับรายการ)</string>\n    <string name=\"left_to_right\">จากซ้ายไปขวา</string>\n    <string name=\"right_to_left\">ขวาไปซ้าย</string>\n    <string name=\"top_to_bottom\">จากบนลงล่าง</string>\n    <string name=\"bottom_to_top\">จากล่างขึ้นบน</string>\n    <string name=\"liquid_glass\">แก้วน้ำ</string>\n    <string name=\"liquid_glass_sub\">สวิตช์ที่ใช้ระบบปฏิบัติการ iOS 26 ที่เพิ่งประกาศเมื่อเร็วๆ นี้ และระบบการออกแบบกระจกเหลว</string>\n    <string name=\"pick_image_or_base64\">เลือกรูปภาพหรือวาง/นำเข้าข้อมูล Base64 ด้านล่าง</string>\n    <string name=\"type_image_link\">พิมพ์ลิงค์รูปภาพเพื่อเริ่มต้น</string>\n    <string name=\"paste_link\">วางลิงก์</string>\n    <string name=\"kaleidoscope\">ลานตา</string>\n    <string name=\"secondary_angle\">มุมรอง</string>\n    <string name=\"sides\">ด้านข้าง</string>\n    <string name=\"channel_mix\">มิกซ์ช่อง</string>\n    <string name=\"blue_green\">ฟ้าเขียว</string>\n    <string name=\"red_blue\">แดงน้ำเงิน</string>\n    <string name=\"green_red\">เขียวแดง</string>\n    <string name=\"into_red\">เป็นสีแดง</string>\n    <string name=\"into_green\">กลายเป็นสีเขียว</string>\n    <string name=\"into_blue\">เป็นสีฟ้า</string>\n    <string name=\"cyan\">สีฟ้า</string>\n    <string name=\"magenta\">สีม่วงแดง</string>\n    <string name=\"yellow\">สีเหลือง</string>\n    <string name=\"color_halftone\">ฮาล์ฟโทนสี</string>\n    <string name=\"contour\">คอนทัวร์</string>\n    <string name=\"levels\">ระดับ</string>\n    <string name=\"offset\">ออฟเซ็ต</string>\n    <string name=\"voronoi_crystallize\">โวโรน้อย คริสตัลไลซ์</string>\n    <string name=\"shape\">รูปร่าง</string>\n    <string name=\"stretch\">ยืด</string>\n    <string name=\"randomness\">ความบังเอิญ</string>\n    <string name=\"despeckle\">เดสเปคเคิล</string>\n    <string name=\"diffuse\">กระจาย</string>\n    <string name=\"dog\">สุนัข</string>\n    <string name=\"second_radius\">รัศมีที่สอง</string>\n    <string name=\"equalize\">ทำให้เท่าเทียมกัน</string>\n    <string name=\"glow\">เรืองแสง</string>\n    <string name=\"whirl_and_pinch\">วนและหยิก</string>\n    <string name=\"pointillize\">ชี้นิ้ว</string>\n    <string name=\"border_color\">สีขอบ</string>\n    <string name=\"polar_coordinates\">พิกัดเชิงขั้ว</string>\n    <string name=\"rect_to_polar\">ตรงไปที่ขั้วโลก</string>\n    <string name=\"polar_to_rect\">ขั้วโลกเพื่อแก้ไข</string>\n    <string name=\"invert_in_circle\">พลิกกลับเป็นวงกลม</string>\n    <string name=\"reduce_noise\">ลดเสียงรบกวน</string>\n    <string name=\"simple_solarize\">โซลาไรซ์อย่างง่าย</string>\n    <string name=\"weave\">สาน</string>\n    <string name=\"x_gap\">เอ็กซ์ แกป</string>\n    <string name=\"y_gap\">วาย แกป</string>\n    <string name=\"x_width\">เอ็กซ์ กว้าง</string>\n    <string name=\"y_wdth\">ความกว้าง Y</string>\n    <string name=\"twirl\">หมุนวน</string>\n    <string name=\"rubber_stmp\">ตรายาง</string>\n    <string name=\"smear\">ละเลง</string>\n    <string name=\"density\">ความหนาแน่น</string>\n    <string name=\"mix\">ผสม</string>\n    <string name=\"sphere_lensh_distortion\">การบิดเบือนเลนส์ทรงกลม</string>\n    <string name=\"refraction_index\">ดัชนีการหักเหของแสง</string>\n    <string name=\"arc\">อาร์ค</string>\n    <string name=\"spread_angle\">มุมกระจาย</string>\n    <string name=\"sparkle\">สปาร์คเคิล</string>\n    <string name=\"rays\">รังสี</string>\n    <string name=\"ascii\">แอสกี</string>\n    <string name=\"gradient\">การไล่ระดับสี</string>\n    <string name=\"moire\">แมรี่</string>\n    <string name=\"autumn\">ฤดูใบไม้ร่วง</string>\n    <string name=\"bone\">กระดูก</string>\n    <string name=\"jet\">เจ็ต</string>\n    <string name=\"winter\">ฤดูหนาว</string>\n    <string name=\"ocean\">มหาสมุทร</string>\n    <string name=\"summer\">ฤดูร้อน</string>\n    <string name=\"spring\">ฤดูใบไม้ผลิ</string>\n    <string name=\"cool_variant\">ตัวแปรเด็ด</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">สีชมพู</string>\n    <string name=\"hot\">ร้อน</string>\n    <string name=\"parula\">คำ</string>\n    <string name=\"magma\">แม็กม่า</string>\n    <string name=\"inferno\">นรก</string>\n    <string name=\"plasma\">พลาสมา</string>\n    <string name=\"viridis\">วิริดิส</string>\n    <string name=\"cividis\">พลเมือง</string>\n    <string name=\"twilight\">ทไวไลท์</string>\n    <string name=\"twilight_shifted\">ทไวไลท์เปลี่ยนไป</string>\n    <string name=\"auto_perspective\">มุมมองอัตโนมัติ</string>\n    <string name=\"deskew\">เดซิว</string>\n    <string name=\"allow_crop\">อนุญาตให้ครอบตัด</string>\n    <string name=\"crop_or_perspective\">ครอบตัดหรือเปอร์สเปคทีฟ</string>\n    <string name=\"absolute\">แน่นอน</string>\n    <string name=\"turbo\">เทอร์โบ</string>\n    <string name=\"deep_green\">สีเขียวเข้ม</string>\n    <string name=\"lens_correction\">การแก้ไขเลนส์</string>\n    <string name=\"target_lens_profile\">ไฟล์โปรไฟล์เลนส์เป้าหมายในรูปแบบ JSON</string>\n    <string name=\"download_ready_lens_profiles\">ดาวน์โหลดโปรไฟล์เลนส์พร้อม</string>\n    <string name=\"part_percents\">เปอร์เซ็นต์ส่วนหนึ่ง</string>\n    <string name=\"export_as_json\">ส่งออกเป็น JSON</string>\n    <string name=\"export_as_json_sub\">คัดลอกสตริงที่มีข้อมูลจานสีเป็นตัวแทน json</string>\n    <string name=\"seam_carving\">การแกะสลักตะเข็บ</string>\n    <string name=\"home_screen\">หน้าจอหลัก</string>\n    <string name=\"lock_screen\">ล็อคหน้าจอ</string>\n    <string name=\"built_in\">บิวท์อิน</string>\n    <string name=\"wallpapers_export\">ส่งออกวอลเปเปอร์</string>\n    <string name=\"refresh\">รีเฟรช</string>\n    <string name=\"wallpapers_export_sub\">รับวอลเปเปอร์ Home, Lock และ Built-in ปัจจุบัน</string>\n    <string name=\"allow_access_to_all_files_for_wp\">อนุญาตให้เข้าถึงไฟล์ทั้งหมด ซึ่งจำเป็นสำหรับการดึงวอลเปเปอร์</string>\n    <string name=\"allow_read_media_images_for_wp\">สิทธิ์ในการจัดการที่จัดเก็บข้อมูลภายนอกไม่เพียงพอ คุณต้องอนุญาตการเข้าถึงรูปภาพของคุณ ตรวจสอบให้แน่ใจว่าได้เลือก \\\"อนุญาตทั้งหมด\\\"</string>\n    <string name=\"add_preset_to_filename\">เพิ่มค่าที่ตั้งไว้ล่วงหน้าในชื่อไฟล์</string>\n    <string name=\"add_preset_to_filename_sub\">เพิ่มส่วนต่อท้ายด้วยค่าที่ตั้งไว้ล่วงหน้าที่เลือกไว้กับชื่อไฟล์ภาพ</string>\n    <string name=\"add_image_scale_mode_to_filename\">เพิ่มโหมดมาตราส่วนรูปภาพในชื่อไฟล์</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">เพิ่มส่วนต่อท้ายด้วยโหมดขนาดภาพที่เลือกไว้ต่อท้ายชื่อไฟล์ภาพ</string>\n    <string name=\"ascii_art\">ศิลปะแอสกี้</string>\n    <string name=\"ascii_art_sub\">แปลงรูปภาพเป็นข้อความ ASCII ซึ่งจะมีลักษณะเหมือนรูปภาพ</string>\n    <string name=\"params\">พารามิเตอร์</string>\n    <string name=\"invert_colors_ascii_sub\">ใช้ตัวกรองเชิงลบกับรูปภาพเพื่อให้ได้ผลลัพธ์ที่ดีขึ้นในบางกรณี</string>\n    <string name=\"processing_screenshot\">กำลังประมวลผลภาพหน้าจอ</string>\n    <string name=\"screenshot_not_captured_try_again\">ไม่ได้จับภาพหน้าจอ โปรดลองอีกครั้ง</string>\n    <string name=\"skipped_saving\">ข้ามการบันทึกแล้ว</string>\n    <string name=\"skipped_saving_multiple\">%1$s ไฟล์ถูกข้าม</string>\n    <string name=\"allow_skip_if_larger\">อนุญาตให้ข้ามหากใหญ่กว่านี้</string>\n    <string name=\"allow_skip_if_larger_sub\">เครื่องมือบางอย่างจะได้รับอนุญาตให้ข้ามการบันทึกรูปภาพได้ หากขนาดไฟล์ที่ได้จะใหญ่กว่าต้นฉบับ</string>\n    <string name=\"qr_type_calendar_event\">กิจกรรมในปฏิทิน</string>\n    <string name=\"qr_type_contact_info\">ติดต่อ</string>\n    <string name=\"qr_type_email\">อีเมล</string>\n    <string name=\"qr_type_geo_point\">ที่ตั้ง</string>\n    <string name=\"qr_type_phone\">โทรศัพท์</string>\n    <string name=\"qr_type_plain\">ข้อความ</string>\n    <string name=\"qr_type_sms\">เอสเอ็มเอส</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">อินเตอร์เน็ตไร้สาย</string>\n    <string name=\"open_network\">เปิดเครือข่าย</string>\n    <string name=\"not_specified\">ไม่มี</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">โทรศัพท์</string>\n    <string name=\"message\">ข้อความ</string>\n    <string name=\"address\">ที่อยู่</string>\n    <string name=\"subject\">เรื่อง</string>\n    <string name=\"body\">ร่างกาย</string>\n    <string name=\"name\">ชื่อ</string>\n    <string name=\"organization\">องค์กร</string>\n    <string name=\"title\">ชื่อ</string>\n    <string name=\"phones\">โทรศัพท์</string>\n    <string name=\"emails\">อีเมล</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">ที่อยู่</string>\n    <string name=\"summary\">สรุป</string>\n    <string name=\"description\">คำอธิบาย</string>\n    <string name=\"location\">ที่ตั้ง</string>\n    <string name=\"organizer\">ออแกไนเซอร์</string>\n    <string name=\"start_date\">วันที่เริ่มต้น</string>\n    <string name=\"end_date\">วันที่สิ้นสุด</string>\n    <string name=\"status\">สถานะ</string>\n    <string name=\"latitude\">ละติจูด</string>\n    <string name=\"longitude\">ลองจิจูด</string>\n    <string name=\"create_barcode\">สร้างบาร์โค้ด</string>\n    <string name=\"edit_barcode\">แก้ไขบาร์โค้ด</string>\n    <string name=\"wifi_configuration\">การกำหนดค่า Wi-Fi</string>\n    <string name=\"security\">ความปลอดภัย</string>\n    <string name=\"pick_contact\">เลือกผู้ติดต่อ</string>\n    <string name=\"grant_contact_permission\">ให้สิทธิ์ผู้ติดต่อในการตั้งค่าเพื่อป้อนอัตโนมัติโดยใช้ผู้ติดต่อที่เลือก</string>\n    <string name=\"contact_info\">ข้อมูลการติดต่อ</string>\n    <string name=\"first_name\">ชื่อ</string>\n    <string name=\"middle_name\">ชื่อกลาง</string>\n    <string name=\"last_name\">นามสกุล</string>\n    <string name=\"pronunciation\">การออกเสียง</string>\n    <string name=\"add_phone\">เพิ่มโทรศัพท์</string>\n    <string name=\"add_email\">เพิ่มอีเมล</string>\n    <string name=\"add_address\">เพิ่มที่อยู่</string>\n    <string name=\"website\">เว็บไซต์</string>\n    <string name=\"add_website\">เพิ่มเว็บไซต์</string>\n    <string name=\"formatted_name\">ชื่อที่จัดรูปแบบ</string>\n    <string name=\"qr_code_top_image\">รูปภาพนี้จะถูกนำมาใช้เพื่อวางไว้เหนือบาร์โค้ด</string>\n    <string name=\"code_customization\">การปรับแต่งโค้ด</string>\n    <string name=\"qr_logo_image\">รูปภาพนี้จะใช้เป็นโลโก้ตรงกลางโค้ด QR</string>\n    <string name=\"logo\">โลโก้</string>\n    <string name=\"logo_padding\">การขยายโลโก้</string>\n    <string name=\"logo_size\">ขนาดโลโก้</string>\n    <string name=\"logo_corners\">มุมโลโก้</string>\n    <string name=\"fourth_eye\">ตาที่สี่</string>\n    <string name=\"fourth_eye_description\">เพิ่มความสมมาตรของดวงตาให้กับโค้ด QR โดยเพิ่มตาที่สี่ที่มุมล่างสุด</string>\n    <string name=\"pixel_shape\">รูปร่างพิกเซล</string>\n    <string name=\"frame_shape\">รูปร่างกรอบ</string>\n    <string name=\"ball_shape\">รูปร่างลูก</string>\n    <string name=\"error_correction_level\">ระดับการแก้ไขข้อผิดพลาด</string>\n    <string name=\"dark_color\">สีเข้ม</string>\n    <string name=\"light_color\">สีอ่อน</string>\n    <string name=\"hyper_os\">ไฮเปอร์ระบบปฏิบัติการ</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS ชอบสไตล์</string>\n    <string name=\"mask_pattern\">รูปแบบหน้ากาก</string>\n    <string name=\"code_may_be_not_scannable\">รหัสนี้อาจสแกนไม่ได้ โปรดเปลี่ยนพารามิเตอร์ลักษณะที่ปรากฏเพื่อให้สามารถอ่านได้กับทุกอุปกรณ์</string>\n    <string name=\"not_scannable\">สแกนไม่ได้.</string>\n    <string name=\"launcher_mode_sub\">เครื่องมือจะมีลักษณะเหมือนเครื่องเรียกใช้งานแอปบนหน้าจอหลักเพื่อให้มีขนาดกะทัดรัดมากขึ้น</string>\n    <string name=\"launcher_mode\">โหมดตัวเรียกใช้</string>\n    <string name=\"flood_fill_sub\">เติมพื้นที่ด้วยแปรงและสไตล์ที่เลือก</string>\n    <string name=\"flood_fill\">น้ำท่วม</string>\n    <string name=\"spray\">สเปรย์</string>\n    <string name=\"spray_sub\">วาดเส้นทางสไตล์กราฟิตี้</string>\n    <string name=\"square_particles\">อนุภาคสี่เหลี่ยม</string>\n    <string name=\"square_particles_sub\">อนุภาคสเปรย์จะเป็นรูปทรงสี่เหลี่ยมแทนที่จะเป็นวงกลม</string>\n    <string name=\"palette_tools\">เครื่องมือจานสี</string>\n    <string name=\"palette_tools_sub\">สร้างจานสีพื้นฐาน/วัสดุจากรูปภาพ หรือนำเข้า/ส่งออกในรูปแบบจานสีต่างๆ</string>\n    <string name=\"edit_palette\">แก้ไขจานสี</string>\n    <string name=\"edit_palette_sub\">ส่งออก/นำเข้าจานสีในรูปแบบต่างๆ</string>\n    <string name=\"color_name\">ชื่อสี</string>\n    <string name=\"palette_name\">ชื่อจานสี</string>\n    <string name=\"palette_format\">รูปแบบจานสี</string>\n    <string name=\"export_palette_sub\">ส่งออกจานสีที่สร้างขึ้นเป็นรูปแบบต่างๆ</string>\n    <string name=\"add_color_palette_sub\">เพิ่มสีใหม่ให้กับจานสีปัจจุบัน</string>\n    <string name=\"palette_name_not_supported\">รูปแบบ %1$s ไม่รองรับการระบุชื่อจานสี</string>\n    <string name=\"wallpapers_export_not_avaialbe\">เนื่องจากนโยบายของ Play Store ฟีเจอร์นี้จึงไม่สามารถรวมไว้ในรุ่นปัจจุบันได้ หากต้องการเข้าถึงฟังก์ชันนี้ โปรดดาวน์โหลด ImageToolbox จากแหล่งอื่น คุณสามารถค้นหารุ่นที่มีอยู่บน GitHub ด้านล่าง</string>\n    <string name=\"open_github_page\">เปิดหน้า Github</string>\n    <string name=\"overwrite_files_sub_short\">ไฟล์ต้นฉบับจะถูกแทนที่ด้วยไฟล์ใหม่แทนที่จะบันทึกในโฟลเดอร์ที่เลือก</string>\n    <string name=\"hidden_watermark_text_detected\">ตรวจพบข้อความลายน้ำที่ซ่อนอยู่</string>\n    <string name=\"hidden_watermark_image_detected\">ตรวจพบภาพลายน้ำที่ซ่อนอยู่</string>\n    <string name=\"this_image_was_hidden\">ภาพนี้ถูกซ่อนไว้</string>\n    <string name=\"generative_inpaint\">กำเนิด Inpainting</string>\n    <string name=\"generative_inpaint_sub\">ช่วยให้คุณสามารถลบวัตถุในรูปภาพโดยใช้โมเดล AI โดยไม่ต้องพึ่งพา OpenCV หากต้องการใช้ฟีเจอร์นี้ แอปจะดาวน์โหลดโมเดลที่ต้องการ (~200 MB) จาก GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">ช่วยให้คุณสามารถลบวัตถุในรูปภาพโดยใช้โมเดล AI โดยไม่ต้องพึ่งพา OpenCV นี่อาจเป็นการดำเนินการที่ใช้เวลานาน</string>\n    <string name=\"error_level_analysis\">การวิเคราะห์ระดับข้อผิดพลาด</string>\n    <string name=\"luminance_gradient\">การไล่ระดับความสว่าง</string>\n    <string name=\"average_distance\">ระยะทางเฉลี่ย</string>\n    <string name=\"copy_move_detection\">คัดลอกการตรวจจับการเคลื่อนไหว</string>\n    <string name=\"retain\">เก็บไว้</string>\n    <string name=\"coefficent\">ค่าสัมประสิทธิ์</string>\n    <string name=\"clipboard_data_is_too_large\">ข้อมูลคลิปบอร์ดมีขนาดใหญ่เกินไป</string>\n    <string name=\"data_is_too_large_to_copy\">ข้อมูลมีขนาดใหญ่เกินกว่าจะคัดลอกได้</string>\n    <string name=\"simple_weave_pixelization\">การสานพิกเซลอย่างง่าย</string>\n    <string name=\"staggered_pixelization\">การสลับพิกเซลแบบเซ</string>\n    <string name=\"cross_pixelization\">ข้ามพิกเซล</string>\n    <string name=\"micro_macro_pixelization\">ไมโครมาโครพิกเซล</string>\n    <string name=\"orbital_pixelization\">การทำให้เป็นพิกเซลของวงโคจร</string>\n    <string name=\"vortex_pixelization\">การทำให้เป็นพิกเซลของวอร์เท็กซ์</string>\n    <string name=\"pulse_grid_pixelization\">พิกเซลกริดพัลส์</string>\n    <string name=\"nucleus_pixelization\">การทำให้เป็นพิกเซลของนิวเคลียส</string>\n    <string name=\"radial_weave_pixelization\">การสร้างพิกเซลแบบสานเรเดียล</string>\n    <string name=\"cannot_open_uri\">ไม่สามารถเปิด uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">โหมดหิมะตก</string>\n    <string name=\"enabled\">เปิดใช้งานแล้ว</string>\n    <string name=\"border_frame\">เส้นขอบเฟรม</string>\n    <string name=\"glitch_variant\">ตัวแปรความผิดพลาด</string>\n    <string name=\"channel_shift\">การเปลี่ยนช่อง</string>\n    <string name=\"max_offset\">แม็กซ์ออฟเซ็ต</string>\n    <string name=\"vhs\">วีดิทัศน์</string>\n    <string name=\"block_glitch\">บล็อกความผิดพลาด</string>\n    <string name=\"block_size\">ขนาดบล็อก</string>\n    <string name=\"crt_curvature\">ความโค้งของซีอาร์ที</string>\n    <string name=\"curvature\">ความโค้ง</string>\n    <string name=\"chroma\">โครมา</string>\n    <string name=\"pixel_melt\">พิกเซลละลาย</string>\n    <string name=\"max_drop\">แม็กซ์ดรอป</string>\n    <string name=\"ai_tools\">เครื่องมือเอไอ</string>\n    <string name=\"ai_tools_sub\">เครื่องมือต่างๆ ในการประมวลผลภาพผ่านโมเดล AI เช่น การลบวัตถุหรือการลดสัญญาณรบกวน</string>\n    <string name=\"model_anime_undeint\">การบีบอัดเส้นหยัก</string>\n    <string name=\"model_broadcast\">การ์ตูนอัดรายการออกอากาศ</string>\n    <string name=\"model_rgb_max_denoise_fp16\">การบีบอัดทั่วไป, เสียงรบกวนทั่วไป</string>\n    <string name=\"model_wb_denoise\">เสียงการ์ตูนไม่มีสี</string>\n    <string name=\"model_span_anime_pretrain\">รวดเร็ว การบีบอัดทั่วไป สัญญาณรบกวนทั่วไป แอนิเมชั่น/การ์ตูน/อนิเมะ</string>\n    <string name=\"model_book_scan\">การสแกนหนังสือ</string>\n    <string name=\"model_overexposure\">การแก้ไขค่าแสง</string>\n    <string name=\"model_fbcnn_color_fp16\">ดีที่สุดสำหรับการบีบอัดภาพสีทั่วไป</string>\n    <string name=\"model_fbcnn_gray_fp16\">ดีที่สุดสำหรับการบีบอัดภาพระดับสีเทาทั่วไป</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">การบีบอัดทั่วไป ภาพระดับสีเทา เข้มขึ้น</string>\n    <string name=\"model_scunet_color_gan_fp16\">สัญญาณรบกวนทั่วไป, ภาพสี</string>\n    <string name=\"model_scunet_color_psnr_fp16\">สัญญาณรบกวนทั่วไป ภาพสี รายละเอียดดีขึ้น</string>\n    <string name=\"model_scunet_gray_15_fp16\">สัญญาณรบกวนทั่วไป, ภาพระดับสีเทา</string>\n    <string name=\"model_scunet_gray_25_fp16\">สัญญาณรบกวนทั่วไป ภาพระดับสีเทา เข้มกว่า</string>\n    <string name=\"model_scunet_gray_50_fp16\">สัญญาณรบกวนทั่วไป ภาพระดับสีเทา เข้มที่สุด</string>\n    <string name=\"model_jpeg_destroyer\">การบีบอัดทั่วไป</string>\n    <string name=\"model_jaywreck\">การบีบอัดทั่วไป</string>\n    <string name=\"model_h264\">การสร้างพื้นผิว การบีบอัด h264</string>\n    <string name=\"model_vhs\">การบีบอัดวีเอชเอส</string>\n    <string name=\"model_cinepak\">การบีบอัดที่ไม่ได้มาตรฐาน (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">การบีบอัด Bink ดีกว่าในเรขาคณิต</string>\n    <string name=\"model_debink_v5\">การบีบอัด Bink แข็งแกร่งขึ้น</string>\n    <string name=\"model_debink_v6\">การบีบอัด Bink นุ่มนวล คงรายละเอียด</string>\n    <string name=\"model_antialias\">ขจัดเอฟเฟกต์ขั้นบันไดให้เรียบ</string>\n    <string name=\"model_kdm_scans\">งานศิลปะ/ภาพวาดที่สแกน การบีบอัดแบบอ่อน ลายมัวร์</string>\n    <string name=\"model_bandage\">แถบสี</string>\n    <string name=\"model_halftone\">ช้า กำลังลบฮาล์ฟโทน</string>\n    <string name=\"model_colorizer\">โปรแกรมปรับสีทั่วไปสำหรับภาพระดับสีเทา/bw เพื่อผลลัพธ์ที่ดีกว่า ให้ใช้ DDColor</string>\n    <string name=\"model_deedge\">การกำจัดขอบ</string>\n    <string name=\"model_desharpen\">ลบการเหลามากเกินไป</string>\n    <string name=\"model_dither\">ช้า, น่าเบื่อ</string>\n    <string name=\"model_gainres\">การต่อต้านนามแฝง, สิ่งประดิษฐ์ทั่วไป, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 สแกนการประมวลผล</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">รุ่นปรับปรุงภาพน้ำหนักเบา</string>\n    <string name=\"model_bcgone_detailed_v2\">การกำจัดสิ่งประดิษฐ์การบีบอัด</string>\n    <string name=\"model_bcgone_smooth\">การกำจัดสิ่งประดิษฐ์การบีบอัด</string>\n    <string name=\"model_bandage_smooth\">การกำจัดผ้าพันแผลด้วยผลลัพธ์ที่ราบรื่น</string>\n    <string name=\"model_bendel_halftone\">การประมวลผลรูปแบบฮาล์ฟโทน</string>\n    <string name=\"model_dither_deleter_v3_smooth\">การลบรูปแบบ Dither V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">การลบสิ่งประดิษฐ์ JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">การปรับปรุงพื้นผิว H.264</string>\n    <string name=\"model_vhs_sharpen\">การเหลาและการเพิ่มประสิทธิภาพ VHS</string>\n    <string name=\"merging\">การผสาน</string>\n    <string name=\"chunk_size\">ขนาดก้อน</string>\n    <string name=\"overlap_size\">ขนาดที่ทับซ้อนกัน</string>\n    <string name=\"note_chunk_info\">รูปภาพที่มีขนาดเกิน %1$s พิกเซลจะถูกแบ่งและประมวลผลเป็นชิ้นๆ โดยจะซ้อนทับกันเพื่อป้องกันไม่ให้เกิดรอยต่อที่มองเห็นได้</string>\n    <string name=\"large_chunk_warning\">ขนาดใหญ่อาจทำให้เกิดความไม่เสถียรกับอุปกรณ์ระดับล่าง</string>\n    <string name=\"select_one_to_start\">เลือกหนึ่งรายการเพื่อเริ่มต้น</string>\n    <string name=\"delete_model_sub\">คุณต้องการลบโมเดล %1$s หรือไม่ คุณจะต้องดาวน์โหลดอีกครั้ง</string>\n    <string name=\"confirm\">ยืนยัน</string>\n    <string name=\"models\">โมเดล</string>\n    <string name=\"downloaded_models\">โมเดลที่ดาวน์โหลด</string>\n    <string name=\"available_models\">รุ่นที่มีจำหน่าย</string>\n    <string name=\"preparing\">กำลังเตรียมตัว</string>\n    <string name=\"active_model\">โมเดลที่ใช้งานอยู่</string>\n    <string name=\"failed_to_open_session\">ไม่สามารถเปิดเซสชันได้</string>\n    <string name=\"only_onnx_models\">สามารถนำเข้าได้เฉพาะรุ่น .onnx/.ort เท่านั้น</string>\n    <string name=\"import_model\">โมเดลนำเข้า</string>\n    <string name=\"import_model_sub\">นำเข้าโมเดล onnx ที่กำหนดเองเพื่อใช้งานต่อไป โดยยอมรับเฉพาะโมเดล onnx/ort เท่านั้น รองรับรูปแบบ esrgan เกือบทั้งหมด</string>\n    <string name=\"imported_models\">โมเดลนำเข้า</string>\n    <string name=\"model_scunet_color_15_fp16\">สัญญาณรบกวนทั่วไป, ภาพสี</string>\n    <string name=\"model_scunet_color_25_fp16\">สัญญาณรบกวนทั่วไป ภาพสี เข้มขึ้น</string>\n    <string name=\"model_scunet_color_50_fp16\">สัญญาณรบกวนทั่วไป ภาพสี แรงที่สุด</string>\n    <string name=\"model_artifacts_dithering_alsa\">ลดความผิดเพี้ยนของสีและแถบสี ปรับปรุงการไล่ระดับสีที่ราบรื่นและพื้นที่สีเรียบ</string>\n    <string name=\"model_nmkd_brighten_redux\">เพิ่มความสว่างและคอนทราสต์ของภาพด้วยไฮไลท์ที่สมดุลในขณะที่ยังคงสีที่เป็นธรรมชาติ</string>\n    <string name=\"model_nmkd_brighten\">ทำให้ภาพที่มืดสว่างขึ้นโดยยังคงรักษารายละเอียดและป้องกันไม่ให้ได้รับแสงมากเกินไป</string>\n    <string name=\"model_nmkd_detoon\">ลบโทนสีที่มากเกินไปและคืนความสมดุลของสีที่เป็นกลางและเป็นธรรมชาติมากขึ้น</string>\n    <string name=\"model_noise_toner_poisson_detailed\">ใช้การปรับสีสัญญาณรบกวนแบบปัวซอง โดยเน้นการรักษารายละเอียดและพื้นผิวที่ละเอียดอ่อน</string>\n    <string name=\"model_noise_toner_poisson_soft\">ใช้การปรับสีสัญญาณรบกวนปัวซองแบบนุ่มนวลเพื่อผลลัพธ์ภาพที่นุ่มนวลและรุนแรงน้อยลง</string>\n    <string name=\"model_noise_toner_uniform_detailed\">การปรับสีสัญญาณรบกวนที่สม่ำเสมอเน้นที่การรักษารายละเอียดและความคมชัดของภาพ</string>\n    <string name=\"model_noise_toner_uniform_soft\">การปรับสีเสียงรบกวนที่สม่ำเสมออย่างอ่อนโยนเพื่อเนื้อสัมผัสที่ละเอียดอ่อนและรูปลักษณ์ที่เรียบเนียน</string>\n    <string name=\"model_repainter\">ซ่อมแซมพื้นที่ที่เสียหายหรือไม่สม่ำเสมอด้วยการทาสีสิ่งประดิษฐ์ใหม่และปรับปรุงความสม่ำเสมอของภาพ</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">รุ่นลอกแถบน้ำหนักเบาที่ช่วยขจัดแถบสีโดยมีค่าใช้จ่ายด้านประสิทธิภาพน้อยที่สุด</string>\n    <string name=\"model_jpeg_0_20\">ปรับภาพให้เหมาะสมด้วยการบีบอัดที่สูงมาก (คุณภาพ 0-20%) เพื่อความชัดเจนที่ดีขึ้น</string>\n    <string name=\"model_jpeg_20_40\">ปรับปรุงภาพด้วยการบีบอัดข้อมูลสูง (คุณภาพ 20-40%) คืนรายละเอียดและลดสัญญาณรบกวน</string>\n    <string name=\"model_jpeg_40_60\">ปรับปรุงภาพด้วยการบีบอัดปานกลาง (คุณภาพ 40-60%) ปรับสมดุลความคมชัดและความเรียบเนียน</string>\n    <string name=\"model_jpeg_60_80\">ปรับแต่งภาพด้วยการบีบอัดแสง (คุณภาพ 60-80%) เพื่อเพิ่มรายละเอียดและพื้นผิวที่ละเอียดอ่อน</string>\n    <string name=\"model_jpeg_80_100\">ปรับปรุงภาพที่เกือบไม่มีการสูญเสียเล็กน้อย (คุณภาพ 80-100%) ในขณะที่ยังคงรูปลักษณ์และรายละเอียดที่เป็นธรรมชาติ</string>\n    <string name=\"model_spongecolor_lite\">การระบายสีการ์ตูนที่ง่ายและรวดเร็วไม่เหมาะ</string>\n    <string name=\"model_deblr\">ลดความเบลอของภาพลงเล็กน้อย ปรับปรุงความคมชัดโดยไม่ทำให้เกิดสิ่งแปลกปลอม</string>\n    <string name=\"processing_channel\">การดำเนินงานที่ยาวนาน</string>\n    <string name=\"processing_image\">กำลังประมวลผลภาพ</string>\n    <string name=\"processing\">กำลังประมวลผล</string>\n    <string name=\"model_artifacts_jpg_0_20\">ลบสิ่งแปลกปลอมในการบีบอัด JPEG จำนวนมากในภาพคุณภาพต่ำมาก (0-20%)</string>\n    <string name=\"model_artifacts_jpg_20_40\">ลดข้อผิดพลาด JPEG ที่แข็งแกร่งในภาพที่มีการบีบอัดสูง (20-40%)</string>\n    <string name=\"model_artifacts_jpg_40_60\">ทำความสะอาดสิ่งประดิษฐ์ JPEG ระดับปานกลางในขณะที่รักษารายละเอียดของภาพ (40-60%)</string>\n    <string name=\"model_artifacts_jpg_60_80\">ปรับแต่งสิ่งประดิษฐ์ JPEG แบบแสงในภาพคุณภาพสูงพอสมควร (60-80%)</string>\n    <string name=\"model_artifacts_jpg_80_100\">ลดขนาดภาพ JPEG เล็กน้อยในภาพที่ไม่มีการสูญเสียข้อมูล (80-100%) อย่างละเอียด</string>\n    <string name=\"model_redetail_v2\">ปรับปรุงรายละเอียดและพื้นผิวที่ละเอียดอ่อน ปรับปรุงความคมชัดในการรับรู้โดยไม่มีสิ่งแปลกปลอมที่หนักหน่วง</string>\n    <string name=\"processing_finished\">การประมวลผลเสร็จสิ้น</string>\n    <string name=\"processing_failed\">การประมวลผลล้มเหลว</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">ปรับปรุงพื้นผิวและรายละเอียดในขณะที่ยังคงรูปลักษณ์ที่เป็นธรรมชาติ ปรับให้เหมาะสมเพื่อความเร็ว</string>\n    <string name=\"model_sbdv_dejpeg\">ลบสิ่งแปลกปลอมในการบีบอัด JPEG และคืนคุณภาพของภาพสำหรับภาพถ่ายที่ถูกบีบอัด</string>\n    <string name=\"model_iso_denoise_v1\">ลดสัญญาณรบกวน ISO ในภาพที่ถ่ายในสภาพแสงน้อย โดยคงรายละเอียดไว้</string>\n    <string name=\"model_dejumbo\">แก้ไขการไฮไลท์ที่เปิดรับแสงมากเกินไปหรือ “จัมโบ้” และคืนสมดุลของโทนสีที่ดีขึ้น</string>\n    <string name=\"model_ddcolor_tiny\">โมเดลการปรับสีน้ำหนักเบาและรวดเร็วที่เพิ่มสีที่เป็นธรรมชาติให้กับภาพระดับสีเทา</string>\n    <string name=\"type_dejpeg\">เดเจเพ็ก</string>\n    <string name=\"type_denoise\">เดนัวส์</string>\n    <string name=\"type_colorize\">ปรับสี</string>\n    <string name=\"type_artifacts\">สิ่งประดิษฐ์</string>\n    <string name=\"type_enhance\">ยกระดับ</string>\n    <string name=\"type_anime\">อะนิเมะ</string>\n    <string name=\"type_scans\">สแกน</string>\n    <string name=\"type_upscale\">หรู</string>\n    <string name=\"model_realesrgan_x4v3\">ตัวเพิ่มสเกล X4 สำหรับรูปภาพทั่วไป รุ่นจิ๋วที่ใช้ GPU และเวลาน้อยกว่า โดยมีความเบลอและการลดทอนในระดับปานกลาง</string>\n    <string name=\"model_realesrgan_x2plus\">ตัวเพิ่มสเกล X2 สำหรับภาพทั่วไป รักษาพื้นผิวและรายละเอียดที่เป็นธรรมชาติ</string>\n    <string name=\"model_realesrgan_x4plus\">ตัวเพิ่มสเกล X4 สำหรับภาพทั่วไปพร้อมพื้นผิวที่ได้รับการปรับปรุงและผลลัพธ์ที่สมจริง</string>\n    <string name=\"model_realesrgan_x4plus_anime\">ตัวเพิ่มสเกล X4 ปรับให้เหมาะสมสำหรับภาพอนิเมะ 6 บล็อก RRDB เพื่อเส้นและรายละเอียดที่คมชัดยิ่งขึ้น</string>\n    <string name=\"model_realesrnet_x4plus\">ตัวอัปสเกล X4 พร้อมการสูญเสีย MSE ให้ผลลัพธ์ที่นุ่มนวลยิ่งขึ้น และลดข้อผิดพลาดสำหรับรูปภาพทั่วไป</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler ปรับให้เหมาะสมสำหรับภาพอนิเมะ รุ่น 4B32F ที่มีรายละเอียดคมชัดกว่าและเส้นเรียบ</string>\n    <string name=\"model_ultrasharp_v2_x4\">รุ่น X4 UltraSharp V2 สำหรับภาพทั่วไป เน้นความคมชัดและความคมชัด</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 อัลตร้าชาร์ป V2 Lite; เร็วขึ้นและเล็กลง รักษารายละเอียดในขณะที่ใช้หน่วยความจำ GPU น้อยลง</string>\n    <string name=\"model_rmbg_1_4\">รุ่นน้ำหนักเบาเพื่อการลบพื้นหลังอย่างรวดเร็ว ประสิทธิภาพและความแม่นยำที่สมดุล ใช้งานได้กับภาพบุคคล วัตถุ และฉาก แนะนำสำหรับกรณีการใช้งานส่วนใหญ่</string>\n    <string name=\"type_removebg\">ลบบีจี</string>\n    <string name=\"horizontal_border_thickness\">ความหนาของเส้นขอบแนวนอน</string>\n    <string name=\"vertical_border_thickness\">ความหนาของเส้นขอบแนวตั้ง</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s สี</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">รุ่นปัจจุบันไม่รองรับการรวมเป็นก้อน รูปภาพจะถูกประมวลผลในขนาดดั้งเดิม ซึ่งอาจทำให้เกิดการใช้หน่วยความจำสูงและมีปัญหากับอุปกรณ์ระดับล่าง</string>\n    <string name=\"chunking_disabled\">ปิดใช้งานการแบ่งส่วน รูปภาพจะถูกประมวลผลในขนาดดั้งเดิม ซึ่งอาจทำให้ใช้หน่วยความจำสูงและมีปัญหากับอุปกรณ์ระดับล่าง แต่อาจให้ผลลัพธ์ที่ดีกว่าในการอนุมาน</string>\n    <string name=\"chunking\">ก้อน</string>\n    <string name=\"model_u2net\">โมเดลการแบ่งส่วนภาพที่มีความแม่นยำสูงสำหรับการลบพื้นหลัง</string>\n    <string name=\"model_u2netp\">U2Net เวอร์ชันน้ำหนักเบาเพื่อการลบพื้นหลังที่รวดเร็วขึ้นโดยใช้หน่วยความจำน้อยลง</string>\n    <string name=\"model_ddcolor\">โมเดล DDColor เต็มรูปแบบมอบการปรับสีคุณภาพสูงสำหรับภาพทั่วไปที่มีจุดบกพร่องน้อยที่สุด ตัวเลือกที่ดีที่สุดของโมเดลการปรับสีทั้งหมด</string>\n    <string name=\"model_ddcolor_artistic\">ชุดข้อมูลศิลปะที่ได้รับการฝึกอบรมและส่วนตัวของ DDColor สร้างผลลัพธ์การให้สีที่หลากหลายและเป็นศิลปะโดยมีสิ่งเจือปนของสีที่ไม่สมจริงน้อยลง</string>\n    <string name=\"model_birefnet\">รุ่น BiRefNet น้ำหนักเบาที่ใช้ Swin Transformer เพื่อการลบพื้นหลังที่แม่นยำ</string>\n    <string name=\"model_inspyrenet\">การลบพื้นหลังคุณภาพสูงพร้อมขอบคมและการรักษารายละเอียดที่ยอดเยี่ยม โดยเฉพาะกับวัตถุที่ซับซ้อนและพื้นหลังที่ยุ่งยาก</string>\n    <string name=\"model_isnet\">โมเดลการลบพื้นหลังที่สร้างมาสก์ที่แม่นยำพร้อมขอบเรียบ เหมาะสำหรับวัตถุทั่วไปและการรักษารายละเอียดปานกลาง</string>\n    <string name=\"model_already_downloaded\">ดาวน์โหลดโมเดลแล้ว</string>\n    <string name=\"model_successfully_imported\">นำเข้าโมเดลเรียบร้อยแล้ว</string>\n    <string name=\"type\">พิมพ์</string>\n    <string name=\"keyword\">คำสำคัญ</string>\n    <string name=\"very_fast\">เร็วมาก</string>\n    <string name=\"normal\">ปกติ</string>\n    <string name=\"slow\">ช้า</string>\n    <string name=\"very_slow\">ช้ามาก</string>\n    <string name=\"compute_percents\">เปอร์เซ็นต์การคำนวณ</string>\n    <string name=\"minimum_value_is\">ค่าต่ำสุดคือ %1$s</string>\n    <string name=\"warp_sub\">บิดเบือนภาพด้วยการวาดภาพด้วยมือ</string>\n    <string name=\"warp\">วาร์ป</string>\n    <string name=\"hardness\">ความแข็ง</string>\n    <string name=\"warp_mode\">โหมดวาร์ป</string>\n    <string name=\"warp_mode_move\">เคลื่อนไหว</string>\n    <string name=\"warp_mode_grow\">เติบโต</string>\n    <string name=\"warp_mode_shrink\">หด</string>\n    <string name=\"warp_mode_swirl_cw\">หมุน CW</string>\n    <string name=\"warp_mode_swirl_ccw\">ทวนเข็มนาฬิกาหมุนวน</string>\n    <string name=\"fade_strength\">จางลงความแข็งแรง</string>\n    <string name=\"top_drop\">ดรอปยอดนิยม</string>\n    <string name=\"bottom_drop\">ดรอปล่าง</string>\n    <string name=\"start_drop\">เริ่มดรอป</string>\n    <string name=\"end_drop\">สิ้นสุดดรอป</string>\n    <string name=\"downloading\">กำลังดาวน์โหลด</string>\n    <string name=\"smooth_shapes\">รูปร่างเรียบเนียน</string>\n    <string name=\"smooth_shapes_sub\">ใช้ซูเปอร์รีลิปส์แทนสี่เหลี่ยมมนมาตรฐานเพื่อให้รูปทรงเรียบเนียนและเป็นธรรมชาติยิ่งขึ้น</string>\n    <string name=\"shape_type\">ประเภทรูปร่าง</string>\n    <string name=\"cut\">ตัด</string>\n    <string name=\"rounded\">โค้งมน</string>\n    <string name=\"smooth\">เรียบ</string>\n    <string name=\"cut_shapes_sub\">ขอบคมโดยไม่ต้องปัดเศษ</string>\n    <string name=\"rounded_shapes_sub\">มุมโค้งมนสุดคลาสสิก</string>\n    <string name=\"shapes_type\">ประเภทรูปร่าง</string>\n    <string name=\"corners_size\">ขนาดมุม</string>\n    <string name=\"squircle\">สควอเคิล</string>\n    <string name=\"squircle_shapes_sub\">องค์ประกอบ UI แบบโค้งมนที่หรูหรา</string>\n    <string name=\"filename_format\">รูปแบบชื่อไฟล์</string>\n    <string name=\"prefix_pattern_description\">ข้อความแบบกำหนดเองวางไว้ที่จุดเริ่มต้นของชื่อไฟล์ เหมาะสำหรับชื่อโปรเจ็กต์ แบรนด์ หรือแท็กส่วนตัว</string>\n    <string name=\"original_filename_pattern_description\">ใช้ชื่อไฟล์ต้นฉบับโดยไม่มีนามสกุล ช่วยให้การระบุแหล่งที่มาไม่เสียหาย</string>\n    <string name=\"width_pattern_description\">ความกว้างของภาพเป็นพิกเซล มีประโยชน์สำหรับการติดตามการเปลี่ยนแปลงความละเอียดหรือการปรับขนาดผลลัพธ์</string>\n    <string name=\"height_pattern_description\">ความสูงของรูปภาพเป็นพิกเซล ซึ่งมีประโยชน์เมื่อทำงานกับอัตราส่วนภาพหรือการส่งออก</string>\n    <string name=\"random_numbers_pattern_description\">สร้างตัวเลขสุ่มเพื่อรับประกันชื่อไฟล์ที่ไม่ซ้ำใคร เพิ่มตัวเลขเพิ่มเติมเพื่อความปลอดภัยเป็นพิเศษจากการซ้ำซ้อน</string>\n    <string name=\"sequence_number_pattern_description\">ตัวนับที่เพิ่มขึ้นอัตโนมัติสำหรับการส่งออกเป็นชุด เหมาะอย่างยิ่งเมื่อบันทึกหลายภาพในเซสชันเดียว</string>\n    <string name=\"preset_info_pattern_description\">แทรกชื่อที่ตั้งไว้ล่วงหน้าที่ใช้ลงในชื่อไฟล์ เพื่อให้คุณสามารถจดจำวิธีการประมวลผลภาพได้อย่างง่ายดาย</string>\n    <string name=\"scale_mode_pattern_description\">แสดงโหมดการปรับขนาดภาพที่ใช้ในระหว่างการประมวลผล ช่วยแยกแยะความแตกต่างของภาพที่ปรับขนาด ครอบตัด หรือพอดี</string>\n    <string name=\"suffix_pattern_description\">ข้อความที่กำหนดเองวางไว้ท้ายชื่อไฟล์ ซึ่งมีประโยชน์สำหรับการกำหนดเวอร์ชัน เช่น _v2, _edited หรือ _final</string>\n    <string name=\"extension_pattern_description\">นามสกุลไฟล์ (png, jpg, webp ฯลฯ) จะตรงกับรูปแบบที่บันทึกไว้จริงโดยอัตโนมัติ</string>\n    <string name=\"formatted_timestamp_pattern_description\">การประทับเวลาที่ปรับแต่งได้ซึ่งช่วยให้คุณกำหนดรูปแบบของคุณเองตามข้อกำหนดของ Java เพื่อการเรียงลำดับที่สมบูรณ์แบบ</string>\n    <string name=\"fling_type\">ประเภทพุ่ง</string>\n    <string name=\"android_native\">ระบบปฏิบัติการ Android</string>\n    <string name=\"ios_style\">iOS สไตล์</string>\n    <string name=\"smooth_curve\">เส้นโค้งเรียบ</string>\n    <string name=\"quick_stop\">หยุดด่วน</string>\n    <string name=\"bouncy\">เด้ง</string>\n    <string name=\"floaty\">ลอย</string>\n    <string name=\"snappy\">เร็ว</string>\n    <string name=\"ultra_smooth\">เรียบเนียนเป็นพิเศษ</string>\n    <string name=\"adaptive\">ปรับตัวได้</string>\n    <string name=\"accessibility_aware\">การรับรู้การเข้าถึง</string>\n    <string name=\"reduced_motion\">ลดการเคลื่อนไหว</string>\n    <string name=\"android_native_sub\">ฟิสิกส์การเลื่อน Android ดั้งเดิมสำหรับการเปรียบเทียบพื้นฐาน</string>\n    <string name=\"smooth_sub\">การเลื่อนที่สมดุลและราบรื่นสำหรับการใช้งานทั่วไป</string>\n    <string name=\"ios_style_sub\">พฤติกรรมการเลื่อนเหมือน iOS ที่มีแรงเสียดทานสูงขึ้น</string>\n    <string name=\"smooth_curve_sub\">เส้นโค้งที่ไม่ซ้ำใครเพื่อความรู้สึกในการเลื่อนที่แตกต่างกัน</string>\n    <string name=\"quick_stop_sub\">การเลื่อนที่แม่นยำพร้อมการหยุดอย่างรวดเร็ว</string>\n    <string name=\"bouncy_sub\">เลื่อนเด้งที่สนุกสนานและตอบสนอง</string>\n    <string name=\"floaty_sub\">การเลื่อนแบบเลื่อนยาวสำหรับการเรียกดูเนื้อหา</string>\n    <string name=\"snappy_sub\">การเลื่อนที่รวดเร็วและตอบสนองสำหรับ UI แบบโต้ตอบ</string>\n    <string name=\"ultra_smooth_sub\">การเลื่อนอย่างราบรื่นระดับพรีเมียมพร้อมโมเมนตัมที่ขยายออกไป</string>\n    <string name=\"adaptive_sub\">ปรับฟิสิกส์ตามความเร็วการเหวี่ยง</string>\n    <string name=\"accessibility_aware_sub\">เคารพการตั้งค่าการเข้าถึงระบบ</string>\n    <string name=\"reduced_motion_sub\">การเคลื่อนไหวน้อยที่สุดสำหรับความต้องการในการเข้าถึง</string>\n    <string name=\"primary_lines\">สายหลัก</string>\n    <string name=\"primary_lines_sub\">เพิ่มเส้นหนาทุกๆ บรรทัดที่ห้า</string>\n    <string name=\"fill_color\">เติมสี</string>\n    <string name=\"hidden_tools\">เครื่องมือที่ซ่อนอยู่</string>\n    <string name=\"hidden_for_share\">เครื่องมือที่ซ่อนอยู่เพื่อการแบ่งปัน</string>\n    <string name=\"color_library\">ห้องสมุดสี</string>\n    <string name=\"color_library_sub\">เรียกดูคอลเลกชันสีที่หลากหลาย</string>\n    <string name=\"model_fatality_deblur\">ปรับความคมชัดและลบความเบลอออกจากภาพโดยยังคงรายละเอียดที่เป็นธรรมชาติ เหมาะสำหรับการแก้ไขภาพที่อยู่นอกโฟกัส</string>\n    <string name=\"model_unresize_v3\">กู้คืนรูปภาพที่ได้รับการปรับขนาดก่อนหน้านี้อย่างชาญฉลาด โดยกู้คืนรายละเอียดและพื้นผิวที่สูญหาย</string>\n    <string name=\"model_liveaction_v1_span\">ปรับให้เหมาะสมสำหรับเนื้อหาไลฟ์แอ็กชั่น ลดปัญหาการบีบอัด และเพิ่มรายละเอียดเล็กๆ น้อยๆ ในเฟรมภาพยนตร์/รายการทีวี</string>\n    <string name=\"model_vhs2hd_realplksr\">แปลงฟุตเทจคุณภาพ VHS เป็น HD ช่วยขจัดสัญญาณรบกวนของเทปและเพิ่มความละเอียดในขณะที่ยังคงรักษาความรู้สึกแบบวินเทจ</string>\n    <string name=\"model_text2hd_v1\">ออกแบบมาสำหรับรูปภาพและภาพหน้าจอที่มีข้อความจำนวนมาก ปรับความคมชัดของตัวอักษร และปรับปรุงความสามารถในการอ่าน</string>\n    <string name=\"model_frankendata_pretrainer\">การลดขนาดขั้นสูงที่ได้รับการฝึกอบรมบนชุดข้อมูลที่หลากหลาย เหมาะอย่างยิ่งสำหรับการปรับปรุงภาพถ่ายทั่วไป</string>\n    <string name=\"model_realwebphoto_v2\">ปรับให้เหมาะสมสำหรับภาพถ่ายที่บีบอัดทางเว็บ ลบสิ่งประดิษฐ์ JPEG และคืนลักษณะที่เป็นธรรมชาติ</string>\n    <string name=\"model_realwebphoto_v4\">เวอร์ชันที่ได้รับการปรับปรุงสำหรับภาพถ่ายบนเว็บพร้อมการรักษาพื้นผิวและการลดสิ่งแปลกปลอมที่ดีขึ้น</string>\n    <string name=\"model_dat_2x\">เพิ่มสเกล 2 เท่าด้วยเทคโนโลยี Dual Aggregation Transformer รักษาความคมชัดและรายละเอียดที่เป็นธรรมชาติ</string>\n    <string name=\"model_dat_3x\">การขยายขนาด 3 เท่าโดยใช้สถาปัตยกรรมหม้อแปลงขั้นสูง เหมาะสำหรับความต้องการในการขยายระดับปานกลาง</string>\n    <string name=\"model_dat_4x\">การเพิ่มสเกลคุณภาพสูง 4 เท่าด้วยเครือข่ายหม้อแปลงที่ล้ำสมัย ช่วยรักษารายละเอียดเล็กๆ น้อยๆ ในสเกลที่ใหญ่ขึ้น</string>\n    <string name=\"model_nafnet_deblurring\">ลบภาพเบลอ/นอยส์ และความสั่นออกจากภาพถ่าย วัตถุประสงค์ทั่วไป แต่ดีที่สุดในภาพถ่าย</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">คืนค่าอิมเมจคุณภาพต่ำโดยใช้หม้อแปลง Swin2SR ซึ่งได้รับการปรับให้เหมาะสมสำหรับการย่อยสลาย BSRGAN เหมาะสำหรับการแก้ไขส่วนบีบอัดขนาดใหญ่และเพิ่มรายละเอียดในระดับ 4x</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">การเพิ่มสเกล 4 เท่าด้วยหม้อแปลง SwinIR ที่ได้รับการฝึกเรื่องการย่อยสลาย BSRGAN ใช้ GAN เพื่อให้พื้นผิวคมชัดขึ้นและรายละเอียดที่เป็นธรรมชาติมากขึ้นในภาพถ่ายและฉากที่ซับซ้อน</string>\n    <string name=\"path\">เส้นทาง</string>\n    <string name=\"merge_pdf\">รวม PDF</string>\n    <string name=\"merge_pdf_sub\">รวมไฟล์ PDF หลายไฟล์ไว้ในเอกสารเดียว</string>\n    <string name=\"files_order\">ลำดับไฟล์</string>\n    <string name=\"pages_short\">หน้า</string>\n    <string name=\"split_pdf\">แยก PDF</string>\n    <string name=\"split_pdf_sub\">แยกหน้าเฉพาะจากเอกสาร PDF</string>\n    <string name=\"rotate_pdf\">หมุน PDF</string>\n    <string name=\"rotate_pdf_sub\">แก้ไขการวางแนวหน้าอย่างถาวร</string>\n    <string name=\"pages\">หน้า</string>\n    <string name=\"rearrange_pdf\">จัดเรียง PDF ใหม่</string>\n    <string name=\"rearrange_pdf_sub\">ลากและวางหน้าเพื่อเรียงลำดับใหม่</string>\n    <string name=\"hold_drag_drop\">กดค้างและลากหน้า</string>\n    <string name=\"page_numbers\">หมายเลขหน้า</string>\n    <string name=\"page_numbers_sub\">เพิ่มการกำหนดหมายเลขให้กับเอกสารของคุณโดยอัตโนมัติ</string>\n    <string name=\"label_format\">รูปแบบฉลาก</string>\n    <string name=\"pdf_to_text\">PDF เป็นข้อความ (OCR)</string>\n    <string name=\"pdf_to_text_sub\">แยกข้อความธรรมดาออกจากเอกสาร PDF ของคุณ</string>\n    <string name=\"watermark_pdf_sub\">วางซ้อนข้อความที่กำหนดเองสำหรับการสร้างแบรนด์หรือความปลอดภัย</string>\n    <string name=\"signature\">ลายเซ็น</string>\n    <string name=\"signature_sub\">เพิ่มลายเซ็นอิเล็กทรอนิกส์ของคุณลงในเอกสารใดๆ</string>\n    <string name=\"will_be_for_signature\">ซึ่งจะใช้เป็นลายเซ็น</string>\n    <string name=\"unlock_pdf\">ปลดล็อค PDF</string>\n    <string name=\"unlock_pdf_sub\">ลบรหัสผ่านออกจากไฟล์ที่ได้รับการป้องกัน</string>\n    <string name=\"protect_pdf\">ป้องกัน PDF</string>\n    <string name=\"protect_pdf_sub\">รักษาความปลอดภัยเอกสารของคุณด้วยการเข้ารหัสที่รัดกุม</string>\n    <string name=\"success\">ความสำเร็จ</string>\n    <string name=\"pdf_unlocked\">ปลดล็อค PDF แล้ว คุณสามารถบันทึกหรือแชร์ได้</string>\n    <string name=\"repair_pdf\">ซ่อมแซม PDF</string>\n    <string name=\"repair_pdf_sub\">พยายามแก้ไขเอกสารที่เสียหายหรืออ่านไม่ได้</string>\n    <string name=\"grayscale\">ระดับสีเทา</string>\n    <string name=\"grayscale_pdf_sub\">แปลงรูปภาพที่ฝังในเอกสารทั้งหมดให้เป็นระดับสีเทา</string>\n    <string name=\"compress_pdf\">บีบอัด PDF</string>\n    <string name=\"compress_pdf_sub\">ปรับขนาดไฟล์เอกสารของคุณให้เหมาะสมเพื่อการแชร์ที่ง่ายขึ้น</string>\n    <string name=\"repair_info\">ImageToolbox สร้างตารางอ้างอิงโยงภายในใหม่ และสร้างโครงสร้างไฟล์ใหม่ตั้งแต่ต้น ซึ่งสามารถคืนค่าการเข้าถึงไฟล์จำนวนมากที่ \\\\\"ไม่สามารถเปิดได้\\\\\"</string>\n    <string name=\"grayscale_info\">เครื่องมือนี้แปลงรูปภาพเอกสารทั้งหมดเป็นโทนสีเทา เหมาะสำหรับการพิมพ์และลดขนาดไฟล์</string>\n    <string name=\"metadata\">ข้อมูลเมตา</string>\n    <string name=\"metadata_pdf_sub\">แก้ไขคุณสมบัติของเอกสารเพื่อความเป็นส่วนตัวที่ดีขึ้น</string>\n    <string name=\"tags\">แท็ก</string>\n    <string name=\"producer\">ผู้ผลิต</string>\n    <string name=\"author\">ผู้เขียน</string>\n    <string name=\"keywords\">คำหลัก</string>\n    <string name=\"creator\">ผู้สร้าง</string>\n    <string name=\"privacy_deep_clean\">ความเป็นส่วนตัวอย่างล้ำลึก</string>\n    <string name=\"privacy_deep_clean_sub\">ล้างข้อมูลเมตาที่มีอยู่ทั้งหมดสำหรับเอกสารนี้</string>\n    <string name=\"page\">หน้าหนังสือ</string>\n    <string name=\"deep_ocr\">OCR ลึก</string>\n    <string name=\"deep_ocr_sub\">แยกข้อความออกจากเอกสารและจัดเก็บไว้ในไฟล์ข้อความเดียวโดยใช้เครื่องมือ Tesseract</string>\n    <string name=\"cant_remove_all\">ไม่สามารถลบหน้าทั้งหมดได้</string>\n    <string name=\"remove_pages_pdf\">ลบหน้า PDF</string>\n    <string name=\"remove_pages_pdf_sub\">ลบหน้าเฉพาะออกจากเอกสาร PDF</string>\n    <string name=\"tap_to_remove\">แตะเพื่อลบ</string>\n    <string name=\"manually\">ด้วยตนเอง</string>\n    <string name=\"crop_pdf\">ครอบตัด PDF</string>\n    <string name=\"crop_pdf_sub\">ครอบตัดหน้าเอกสารเป็นขอบเขตใดก็ได้</string>\n    <string name=\"flatten_pdf\">แผ่ PDF</string>\n    <string name=\"flatten_pdf_sub\">ทำให้ PDF ไม่สามารถแก้ไขได้โดยการแรสเตอร์หน้าเอกสาร</string>\n    <string name=\"camera_failed_to_open\">ไม่สามารถสตาร์ทกล้องได้ โปรดตรวจสอบการอนุญาตและให้แน่ใจว่าแอปอื่นไม่ได้ใช้งานอยู่</string>\n    <string name=\"extract_images\">แยกรูปภาพ</string>\n    <string name=\"extract_images_sub\">แยกภาพที่ฝังอยู่ใน PDF ด้วยความละเอียดดั้งเดิม</string>\n    <string name=\"pdf_no_embedded\">ไฟล์ PDF นี้ไม่มีภาพที่ฝังอยู่</string>\n    <string name=\"extract_images_info\">เครื่องมือนี้จะสแกนทุกหน้าและกู้คืนรูปภาพต้นฉบับคุณภาพเต็ม ซึ่งเหมาะสำหรับการบันทึกต้นฉบับจากเอกสาร</string>\n    <string name=\"draw_signature\">วาดลายเซ็น</string>\n    <string name=\"pen_params\">ปากกา พาราม</string>\n    <string name=\"draw_signature_sub\">ใช้ลายเซ็นของตนเองเป็นรูปภาพเพื่อวางบนเอกสาร</string>\n    <string name=\"zip_pdf\">ซิป PDF</string>\n    <string name=\"zip_pdf_sub\">แยกเอกสารตามช่วงเวลาที่กำหนดและแพ็คเอกสารใหม่ลงในไฟล์ zip</string>\n    <string name=\"interval\">ช่วงเวลา</string>\n    <string name=\"print_pdf\">พิมพ์ PDF</string>\n    <string name=\"print_pdf_sub\">เตรียมเอกสารสำหรับการพิมพ์ด้วยขนาดหน้าที่กำหนดเอง</string>\n    <string name=\"pages_per_sheet\">จำนวนหน้าต่อแผ่น</string>\n    <string name=\"orientation\">ปฐมนิเทศ</string>\n    <string name=\"page_size\">ขนาดหน้า</string>\n    <string name=\"margin\">ขอบ</string>\n    <string name=\"bloom\">บลูม</string>\n    <string name=\"soft_knee\">เข่าอ่อน</string>\n    <string name=\"model_realesr_animevideo_v3x4\">ปรับให้เหมาะสมสำหรับอะนิเมะและการ์ตูน การลดขนาดอย่างรวดเร็วด้วยสีที่เป็นธรรมชาติที่ได้รับการปรับปรุงและส่วนแปลกปลอมน้อยลง</string>\n    <string name=\"one_ui_sub\">สไตล์เหมือน Samsung One UI 7</string>\n    <string name=\"calculate_hint\">ป้อนสัญลักษณ์ทางคณิตศาสตร์พื้นฐานที่นี่เพื่อคำนวณค่าที่ต้องการ (เช่น (5+5)*10)</string>\n    <string name=\"math_expression\">นิพจน์ทางคณิตศาสตร์</string>\n    <string name=\"pick_up_to_n_collage_images\">เลือกได้สูงสุด %1$s ภาพ</string>\n    <string name=\"keep_date_time\">เก็บวันที่และเวลา</string>\n    <string name=\"keep_date_time_sub\">เก็บแท็ก exif ที่เกี่ยวข้องกับวันที่และเวลาไว้เสมอ โดยทำงานโดยไม่ขึ้นอยู่กับตัวเลือก Keep exif</string>\n    <string name=\"background_color_for_alpha_formats\">สีพื้นหลังสำหรับรูปแบบอัลฟ่า</string>\n    <string name=\"background_color_for_alpha_formats_sub\">เพิ่มความสามารถในการตั้งค่าสีพื้นหลังสำหรับรูปแบบภาพทุกรูปแบบด้วยการรองรับอัลฟ่า เมื่อปิดใช้งานแล้วจะใช้ได้กับรูปแบบที่ไม่ใช่อัลฟ่าเท่านั้น</string>\n    <string name=\"open_markup_project\">เปิดโครงการ</string>\n    <string name=\"open_markup_project_sub\">แก้ไขโปรเจ็กต์ Image Toolbox ที่บันทึกไว้ก่อนหน้านี้ต่อไป</string>\n    <string name=\"markup_project_open_failed\">ไม่สามารถเปิดโปรเจ็กต์กล่องเครื่องมือรูปภาพได้</string>\n    <string name=\"markup_project_missing_data\">โครงการ Image Toolbox ไม่มีข้อมูลโครงการ</string>\n    <string name=\"markup_project_corrupted\">โครงการกล่องเครื่องมือรูปภาพเสียหาย</string>\n    <string name=\"unsupported_markup_project_version\">เวอร์ชันโปรเจ็กต์กล่องเครื่องมือรูปภาพที่ไม่รองรับ: %1$d</string>\n    <string name=\"save_markup_project\">บันทึกโครงการ</string>\n    <string name=\"save_markup_project_sub\">จัดเก็บเลเยอร์ พื้นหลัง และประวัติการแก้ไขในไฟล์โปรเจ็กต์ที่แก้ไขได้</string>\n    <string name=\"failed_to_open\">ไม่สามารถเปิดได้</string>\n    <string name=\"ocr_write_to_searchable_pdf\">เขียนเป็น PDF ที่ค้นหาได้</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">จดจำข้อความจากชุดรูปภาพและบันทึก PDF ที่ค้นหาได้ด้วยรูปภาพและเลเยอร์ข้อความที่เลือกได้</string>\n    <string name=\"layer_alpha\">เลเยอร์อัลฟ่า</string>\n    <string name=\"horizontal_flip\">พลิกแนวนอน</string>\n    <string name=\"vertical_flip\">พลิกแนวตั้ง</string>\n    <string name=\"lock\">ล็อค</string>\n    <string name=\"add_shadow\">เพิ่มเงา</string>\n    <string name=\"shadow_color\">สีเงา</string>\n    <string name=\"text_geometry\">เรขาคณิตข้อความ</string>\n    <string name=\"text_geometry_sub\">ยืดหรือเอียงข้อความเพื่อให้มีสไตล์ที่คมชัดยิ่งขึ้น</string>\n    <string name=\"scale_x\">สเกล X</string>\n    <string name=\"skew_x\">สกิว เอ็กซ์</string>\n    <string name=\"remove_annotations\">ลบคำอธิบายประกอบ</string>\n    <string name=\"remove_annotations_sub\">ลบประเภทคำอธิบายประกอบที่เลือก เช่น ลิงก์ ความคิดเห็น ไฮไลต์ รูปร่าง หรือฟิลด์แบบฟอร์มออกจากหน้า PDF</string>\n    <string name=\"annotation_link\">ไฮเปอร์ลิงก์</string>\n    <string name=\"annotation_file_attachment\">ไฟล์แนบ</string>\n    <string name=\"annotation_line\">เส้น</string>\n    <string name=\"annotation_popup\">ป๊อปอัป</string>\n    <string name=\"annotation_stamp\">แสตมป์</string>\n    <string name=\"annotation_shapes\">รูปร่าง</string>\n    <string name=\"annotation_text\">หมายเหตุข้อความ</string>\n    <string name=\"annotation_text_markup\">มาร์กอัปข้อความ</string>\n    <string name=\"annotation_widget\">ฟิลด์แบบฟอร์ม</string>\n    <string name=\"annotation_markup\">มาร์กอัป</string>\n    <string name=\"annotation_unknown\">ไม่ทราบ</string>\n    <string name=\"annotations\">คำอธิบายประกอบ</string>\n    <string name=\"ungroup\">ยกเลิกการจัดกลุ่ม</string>\n    <string name=\"add_shadow_sub\">เพิ่มเงาเบลอด้านหลังเลเยอร์ด้วยสีและออฟเซ็ตที่กำหนดค่าได้</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-tr/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">Bir şeyler ters gitti: %1$s</string>\n    <string name=\"size\">Boyut: %1$s</string>\n    <string name=\"loading\">Yükleniyor…</string>\n    <string name=\"image_too_large_preview\">Resim önizlemek için çok büyük, ancak yine de kaydedilmeye çalışılacak</string>\n    <string name=\"pick_image\">Başlamak için bir resim seçin</string>\n    <string name=\"width\">Genişlik: %1$s</string>\n    <string name=\"height\">Yükseklik: %1$s</string>\n    <string name=\"quality\">Kalite</string>\n    <string name=\"extension\">Uzantı</string>\n    <string name=\"resize_type\">Yeniden boyutlandırma türü</string>\n    <string name=\"explicit\">Belirgin</string>\n    <string name=\"flexible\">Esnek</string>\n    <string name=\"pick_image_alt\">Resim Seç</string>\n    <string name=\"app_closing_sub\">Uygulamayı kapatmak istediğinizden emin misiniz?</string>\n    <string name=\"app_closing\">Uygulama kapatılıyor</string>\n    <string name=\"stay\">Kal</string>\n    <string name=\"close\">Kapat</string>\n    <string name=\"reset_image\">Resmi sıfırla</string>\n    <string name=\"reset_image_sub\">Resimdeki değişiklikler başlangıç değerlerine geri alınacak</string>\n    <string name=\"values_reset\">Değerler başarıyla sıfırlandı</string>\n    <string name=\"reset\">Sıfırla</string>\n    <string name=\"something_went_wrong\">Bir şeyler ters gitti</string>\n    <string name=\"restart_app\">Uygulamayı yeniden başlat</string>\n    <string name=\"copied\">Panoya kopyalandı</string>\n    <string name=\"exception\">İstisna</string>\n    <string name=\"edit_exif\">EXIF Düzenle</string>\n    <string name=\"ok\">TAMAM</string>\n    <string name=\"no_exif\">EXIF verisi bulunamadı</string>\n    <string name=\"add_tag\">Etiket ekle</string>\n    <string name=\"save\">Kaydet</string>\n    <string name=\"clear\">Temizle</string>\n    <string name=\"clear_exif\">EXIF verilerini temizle</string>\n    <string name=\"cancel\">İptal</string>\n    <string name=\"clear_exif_sub\">Tüm resim EXIF verileri silinecektir. Bu işlem geri alınamaz!</string>\n    <string name=\"presets\">Ön Ayarlar</string>\n    <string name=\"crop\">Kırp</string>\n    <string name=\"image_not_saved\">Kaydediliyor</string>\n    <string name=\"image_not_saved_sub\">Şimdi çıkarsanız kaydedilmemiş tüm değişiklikler kaybolacak</string>\n    <string name=\"check_source_code\">Kaynak Kodu</string>\n    <string name=\"check_source_code_sub\">En son güncellemeleri alın, sorunları tartışın ve daha fazlası</string>\n    <string name=\"single_edit\">Tekli Düzenleme</string>\n    <string name=\"single_edit_sub\">Tek bir resmi değiştirin, yeniden boyutlandırın ve düzenleyin</string>\n    <string name=\"pick_color\">Renk Seçici</string>\n    <string name=\"pick_color_sub\">Resimden renk seçin, kopyalayın veya paylaşın</string>\n    <string name=\"image\">Resim</string>\n    <string name=\"color\">Renk</string>\n    <string name=\"color_copied\">Renk kopyalandı</string>\n    <string name=\"crop_sub\">Resmi herhangi bir sınıra göre kırpın</string>\n    <string name=\"version\">Sürüm</string>\n    <string name=\"keep_exif\">EXIF verilerini koru</string>\n    <string name=\"images\">Resimler: %d</string>\n    <string name=\"change_preview\">Önizlemeyi değiştir</string>\n    <string name=\"remove\">Kaldır</string>\n    <string name=\"palette_sub\">Verilen resimden bir renk paleti örneği oluşturun</string>\n    <string name=\"generate_palette\">Palet Oluştur</string>\n    <string name=\"palette\">Palet</string>\n    <string name=\"update\">Güncelle</string>\n    <string name=\"new_version\">Yeni sürüm %1$s</string>\n    <string name=\"unsupported_type\">Desteklenmeyen tür: %1$s</string>\n    <string name=\"no_palette\">Verilen resim için palet oluşturulamıyor</string>\n    <string name=\"original\">Orijinal</string>\n    <string name=\"folder\">Çıktı klasörü</string>\n    <string name=\"def\">Varsayılan</string>\n    <string name=\"custom\">Özel</string>\n    <string name=\"unspecified\">Belirtilmemiş</string>\n    <string name=\"device_storage\">Cihaz depolama alanı</string>\n    <string name=\"by_bytes_resize\">Ağırlığa Göre Yeniden Boyutlandır</string>\n    <string name=\"max_bytes\">KB cinsinden maksimum boyut</string>\n    <string name=\"by_bytes_resize_sub\">Bir resmi KB cinsinden verilen boyuta göre yeniden boyutlandırın</string>\n    <string name=\"compare\">Karşılaştır</string>\n    <string name=\"compare_sub\">Verilen iki resmi karşılaştırın</string>\n    <string name=\"pick_two_images\">Başlamak için iki resim seçin</string>\n    <string name=\"pick_images\">Resimleri seçin</string>\n    <string name=\"settings\">Ayarlar</string>\n    <string name=\"night_mode\">Gece Modu</string>\n    <string name=\"dark\">Karanlık</string>\n    <string name=\"light\">Aydınlık</string>\n    <string name=\"system\">Sistem</string>\n    <string name=\"dynamic_colors\">Dinamik renkler</string>\n    <string name=\"customization\">Özelleştirme</string>\n    <string name=\"allow_image_monet\">Resimden renk alımına izin ver</string>\n    <string name=\"allow_image_monet_sub\">Etkinleştirilirse, düzenlemek için bir resim seçtiğinizde uygulama renkleri bu resme uyarlanır</string>\n    <string name=\"language\">Dil</string>\n    <string name=\"amoled_mode\">Amoled modu</string>\n    <string name=\"amoled_mode_sub\">Etkinleştirilirse, yüzeylerin rengi gece modunda mutlak siyaha ayarlanır</string>\n    <string name=\"color_scheme\">Renk şeması</string>\n    <string name=\"color_red\">Kırmızı</string>\n    <string name=\"color_green\">Yeşil</string>\n    <string name=\"color_blue\">Mavi</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Geçerli bir aRGB renk kodu yapıştırın</string>\n    <string name=\"clipboard_paste_invalid_empty\">Yapıştırılacak bir şey yok</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Dinamik renkler açıkken uygulamanın renk şeması değiştirilemez</string>\n    <string name=\"pick_accent_color\">Uygulama teması seçilen renge göre oluşturulacaktır</string>\n    <string name=\"about_app\">Uygulama hakkında</string>\n    <string name=\"no_updates\">Güncelleme bulunamadı</string>\n    <string name=\"issue_tracker\">Sorun takipçisi</string>\n    <string name=\"issue_tracker_sub\">Hata raporlarını ve özellik isteklerini buraya gönderin</string>\n    <string name=\"help_translate\">Çeviriye yardım et</string>\n    <string name=\"help_translate_sub\">Çeviri hatalarını düzeltin veya projeyi başka dillere yerelleştirin</string>\n    <string name=\"nothing_found_by_search\">Sorgunuza göre hiçbir şey bulunamadı</string>\n    <string name=\"search_here\">Burada ara</string>\n    <string name=\"dynamic_colors_sub\">Etkinleştirilirse, uygulama renkleri duvar kağıdı renklerine uyarlanacaktır</string>\n    <string name=\"failed_to_save\">%d resim kaydedilemedi</string>\n    <string name=\"email\">E-posta</string>\n    <string name=\"primary\">Birincil</string>\n    <string name=\"tertiary\">Üçüncül</string>\n    <string name=\"secondary\">İkincil</string>\n    <string name=\"border_thickness\">Kenarlık kalınlığı</string>\n    <string name=\"surface\">Yüzey</string>\n    <string name=\"values\">Değerler</string>\n    <string name=\"add\">Ekle</string>\n    <string name=\"permission\">İzin</string>\n    <string name=\"grant\">İzin Ver</string>\n    <string name=\"permission_sub\">Uygulamanın çalışabilmesi için resimleri kaydetmek üzere depolama alanınıza erişmesi gerekir, bu zorunludur. Lütfen bir sonraki iletişim kutusunda izin verin.</string>\n    <string name=\"grant_permission_manual\">Uygulamanın çalışması için bu izne ihtiyacı var, lütfen manuel olarak izin verin</string>\n    <string name=\"external_storage\">Harici depolama</string>\n    <string name=\"monet_colors\">Monet renkleri</string>\n    <string name=\"donation_sub\">Bu uygulama tamamen ücretsizdir, ancak proje gelişimini desteklemek isterseniz buraya tıklayabilirsiniz</string>\n    <string name=\"fab_alignment\">FAB hizalaması</string>\n    <string name=\"check_updates\">Güncellemeleri kontrol et</string>\n    <string name=\"check_updates_sub\">Etkinleştirilirse, uygulama başlangıcında size güncelleme iletişim kutusu gösterilir</string>\n    <string name=\"zoom\">Resim yakınlaştırma</string>\n    <string name=\"share\">Paylaş</string>\n    <string name=\"prefix\">Ön Ek</string>\n    <string name=\"filename\">Dosya adı</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"emoji_sub\">Ana ekranda hangi emojinin gösterileceğini seçin</string>\n    <string name=\"add_file_size\">Dosya boyutu ekle</string>\n    <string name=\"add_file_size_sub\">Etkinleştirilirse, kaydedilen resmin genişliğini ve yüksekliğini çıktı dosyasının adına ekler</string>\n    <string name=\"delete_exif\">EXIF Sil</string>\n    <string name=\"delete_exif_sub\">Herhangi bir resim setinden EXIF meta verilerini silin</string>\n    <string name=\"image_preview\">Resim Önizleme</string>\n    <string name=\"image_preview_sub\">Her tür resmi önizleyin: GIF, SVG ve benzeri</string>\n    <string name=\"image_source\">Resim kaynağı</string>\n    <string name=\"photo_picker\">Fotoğraf seçici</string>\n    <string name=\"gallery_picker\">Galeri</string>\n    <string name=\"file_explorer_picker\">Dosya gezgini</string>\n    <string name=\"photo_picker_sub\">Ekranın altında görünen, yalnızca Android 12+ üzerinde çalışabilen modern Android fotoğraf seçicisi. EXIF meta verilerini almada sorunları var</string>\n    <string name=\"gallery_picker_sub\">Basit galeri resim seçici. Sadece medya seçimi sağlayan bir uygulamanız varsa çalışır</string>\n    <string name=\"file_explorer_picker_sub\">Resim seçmek için GetContent niyetini kullanın. Her yerde çalışır, ancak bazı cihazlarda seçilen resimleri almada sorunlar yaşadığı bilinmektedir. Bu benim hatam değil.</string>\n    <string name=\"options_arrangement\">Seçeneklerin düzenlenmesi</string>\n    <string name=\"edit\">Düzenle</string>\n    <string name=\"order\">Sıra</string>\n    <string name=\"order_sub\">Ana ekrandaki araçların sırasını belirler</string>\n    <string name=\"emojis_count\">Emoji sayısı</string>\n    <string name=\"sequence_num\">sıraNumarası</string>\n    <string name=\"original_filename\">orijinalDosyaAdı</string>\n    <string name=\"add_original_filename\">Orijinal dosya adını ekle</string>\n    <string name=\"add_original_filename_sub\">Etkinleştirilirse, çıktı resminin adına orijinal dosya adını ekler</string>\n    <string name=\"replace_sequence_number\">Sıra numarasını değiştir</string>\n    <string name=\"replace_sequence_number_sub\">Etkinleştirilirse, toplu işlem kullanıyorsanız standart zaman damgasını resim sıra numarasıyla değiştirir</string>\n    <string name=\"filename_not_work_with_photopicker\">Fotoğraf seçici resim kaynağı seçiliyken orijinal dosya adı ekleme çalışmaz</string>\n    <string name=\"load_image_from_net\">Web\\'den Resim Yükleme</string>\n    <string name=\"load_image_from_net_sub\">İnternetten herhangi bir resmi önizlemek, yakınlaştırmak, düzenlemek ve isterseniz kaydetmek için yükleyin.</string>\n    <string name=\"no_image\">Resim yok</string>\n    <string name=\"image_link\">Resim bağlantısı</string>\n    <string name=\"fill\">Doldur</string>\n    <string name=\"fit\">Sığdır</string>\n    <string name=\"content_scale\">İçerik ölçeği</string>\n    <string name=\"explicit_description\">Resimleri verilen yükseklik ve genişliğe göre yeniden boyutlandırır. Resimlerin en boy oranı değişebilir.</string>\n    <string name=\"flexible_description\">Resimleri uzun kenarı verilen yükseklik veya genişliğe göre yeniden boyutlandırır. Tüm boyut hesaplamaları kaydettikten sonra yapılacaktır. Resimlerin en boy oranı korunacaktır.</string>\n    <string name=\"brightness\">Parlaklık</string>\n    <string name=\"contrast\">Kontrast</string>\n    <string name=\"hue\">Ton</string>\n    <string name=\"saturation\">Doygunluk</string>\n    <string name=\"add_filter\">Filtre ekle</string>\n    <string name=\"filter\">Filtre</string>\n    <string name=\"filter_sub\">Resimlere filtre zincirleri uygulayın</string>\n    <string name=\"filters\">Filtreler</string>\n    <string name=\"light_aka_illumination\">Işık</string>\n    <string name=\"color_filter\">Renk filtresi</string>\n    <string name=\"alpha\">Alfa</string>\n    <string name=\"exposure\">Pozlama</string>\n    <string name=\"white_balance\">Beyaz dengesi</string>\n    <string name=\"temperature\">Sıcaklık</string>\n    <string name=\"tint\">Renk tonu</string>\n    <string name=\"monochrome\">Monokrom</string>\n    <string name=\"gamma\">Gama</string>\n    <string name=\"highlights_shadows\">Açık tonlar ve gölgeler</string>\n    <string name=\"highlights\">Açık Tonlar</string>\n    <string name=\"shadows\">Gölgeler</string>\n    <string name=\"haze\">Pus</string>\n    <string name=\"effect\">Efekt</string>\n    <string name=\"distance\">Mesafe</string>\n    <string name=\"slope\">Eğim</string>\n    <string name=\"sharpen\">Keskinleştir</string>\n    <string name=\"sepia\">Sepya</string>\n    <string name=\"negative\">Negatif</string>\n    <string name=\"solarize\">Solarizasyon</string>\n    <string name=\"vibrance\">Canlılık</string>\n    <string name=\"black_and_white\">Siyah Beyaz</string>\n    <string name=\"crosshatch\">Çapraz Tarama</string>\n    <string name=\"spacing\">Aralık</string>\n    <string name=\"line_width\">Çizgi genişliği</string>\n    <string name=\"sobel_edge\">Sobel kenar</string>\n    <string name=\"blur\">Bulanıklaştır</string>\n    <string name=\"halftone\">Yarım Ton</string>\n    <string name=\"cga_colorspace\">CGA renk uzayı</string>\n    <string name=\"gaussian_blur\">Gauss bulanıklığı</string>\n    <string name=\"box_blur\">Kutu bulanıklığı</string>\n    <string name=\"bilaterial_blur\">Bilateral bulanıklık</string>\n    <string name=\"emboss\">Kabartma</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Vinyet</string>\n    <string name=\"start\">Başlangıç</string>\n    <string name=\"end\">Bitiş</string>\n    <string name=\"kuwahara\">Kuwahara yumuşatma</string>\n    <string name=\"stack_blur\">Yığın bulanıklığı</string>\n    <string name=\"radius\">Yarıçap</string>\n    <string name=\"scale\">Ölçek</string>\n    <string name=\"distortion\">Bozulma</string>\n    <string name=\"angle\">Açı</string>\n    <string name=\"swirl\">Girdap</string>\n    <string name=\"bulge\">Şişirme</string>\n    <string name=\"dilation\">Genişleme</string>\n    <string name=\"sphere_refraction\">Küre kırılması</string>\n    <string name=\"refractive_index\">Kırılma indisi</string>\n    <string name=\"glass_sphere_refraction\">Cam küre kırılması</string>\n    <string name=\"color_matrix\">Renk matrisi</string>\n    <string name=\"opacity\">Opaklık</string>\n    <string name=\"limits_resize\">Sınırlara Göre Yeniden Boyutlandır</string>\n    <string name=\"limits_resize_sub\">En boy oranını koruyarak resimleri verilen yükseklik ve genişliğe göre yeniden boyutlandırın</string>\n    <string name=\"sketch\">Taslak</string>\n    <string name=\"threshold\">Eşik</string>\n    <string name=\"quantizationLevels\">Kuantalama seviyeleri</string>\n    <string name=\"smooth_toon\">Yumuşak çizgi film</string>\n    <string name=\"toon\">Çizgi film</string>\n    <string name=\"posterize\">Posterleştir</string>\n    <string name=\"non_maximum_suppression\">Maksimum olmayan bastırma</string>\n    <string name=\"weak_pixel_inclusion\">Zayıf piksel dahil etme</string>\n    <string name=\"lookup\">Arama Tablosu (Lookup)</string>\n    <string name=\"convolution3x3\">Konvolüsyon 3x3</string>\n    <string name=\"rgb_filter\">RGB filtresi</string>\n    <string name=\"false_color\">Yanlış Renk</string>\n    <string name=\"first_color\">İlk renk</string>\n    <string name=\"second_color\">İkinci renk</string>\n    <string name=\"reorder\">Yeniden sırala</string>\n    <string name=\"fast_blur\">Hızlı bulanıklık</string>\n    <string name=\"blur_size\">Bulanıklık boyutu</string>\n    <string name=\"blur_center_x\">Bulanıklık merkezi x</string>\n    <string name=\"blur_center_y\">Bulanıklık merkezi y</string>\n    <string name=\"zoom_blur\">Yakınlaştırma bulanıklığı</string>\n    <string name=\"color_balance\">Renk dengesi</string>\n    <string name=\"luminance_threshold\">Parlaklık eşiği</string>\n    <string name=\"activate_files\">Dosyalar uygulamasını devre dışı bıraktınız, bu özelliği kullanmak için etkinleştirin</string>\n    <string name=\"draw\">Çiz</string>\n    <string name=\"draw_sub\">Bir eskiz defterindeki gibi resmin üzerine çizin veya doğrudan arka planın üzerine çizin</string>\n    <string name=\"paint_color\">Boya rengi</string>\n    <string name=\"paint_alpha\">Boya alfa değeri</string>\n    <string name=\"draw_on_image\">Resim üzerine çiz</string>\n    <string name=\"draw_on_image_sub\">Bir resim seçin ve üzerine bir şeyler çizin</string>\n    <string name=\"draw_on_background\">Arka plan üzerine çiz</string>\n    <string name=\"draw_on_background_sub\">Bir arka plan rengi seçin ve üzerine çizin</string>\n    <string name=\"background_color\">Arka plan rengi</string>\n    <string name=\"cipher\">Şifreleme</string>\n    <string name=\"cipher_sub\">Mevcut çeşitli kripto algoritmalarına dayanarak herhangi bir dosyayı (sadece resmi değil) şifreleyin ve şifresini çözün</string>\n    <string name=\"pick_file\">Dosya Seç</string>\n    <string name=\"encrypt\">Şifrele</string>\n    <string name=\"decrypt\">Şifreyi Çöz</string>\n    <string name=\"pick_file_to_start\">Başlamak için bir dosya seçin</string>\n    <string name=\"decryption\">Şifre Çözme</string>\n    <string name=\"encryption\">Şifreleme</string>\n    <string name=\"key\">Anahtar</string>\n    <string name=\"file_proceed\">Dosya işlendi</string>\n    <string name=\"store_file_desc\">Bu dosyayı cihazınıza kaydedin veya istediğiniz yere koymak için paylaşma eylemini kullanın</string>\n    <string name=\"features\">Özellikler</string>\n    <string name=\"implementation\">Uygulama</string>\n    <string name=\"compatibility\">Uyumluluk</string>\n    <string name=\"features_sub\">Dosyaların parola tabanlı şifrelenmesi. İşlenen dosyalar seçilen dizinde saklanabilir veya paylaşılabilir. Şifresi çözülen dosyalar da doğrudan açılabilir.</string>\n    <string name=\"implementation_sub\">AES-256, GCM modu, dolgusuz, varsayılan olarak 12 bayt rastgele IV. İhtiyaç duyulan algoritmayı seçebilirsiniz. Anahtarlar 256-bit SHA-3 hash olarak kullanılır</string>\n    <string name=\"file_size\">Dosya boyutu</string>\n    <string name=\"file_size_sub\">Maksimum dosya boyutu Android işletim sistemi ve mevcut bellek tarafından kısıtlanmıştır ve cihaza bağlıdır. \\nLütfen unutmayın: bellek, depolama alanı değildir.</string>\n    <string name=\"compatibility_sub\">Lütfen diğer dosya şifreleme yazılımları veya hizmetleriyle uyumluluğun garanti edilmediğini unutmayın. Biraz farklı bir anahtar işlemi veya şifre yapılandırması uyumsuzluğa neden olabilir.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Geçersiz parola veya seçilen dosya şifrelenmemiş</string>\n    <string name=\"image_size_warning\">Resmi verilen genişlik ve yükseklikle kaydetmeye çalışmak bellek yetersizliği hatasına neden olabilir. Bunu kendi sorumluluğunuzda yapın.</string>\n    <string name=\"cache\">Önbellek</string>\n    <string name=\"cache_size\">Önbellek boyutu</string>\n    <string name=\"found_s\">%1$s bulundu</string>\n    <string name=\"auto_cache_clearing\">Otomatik önbellek temizleme</string>\n    <string name=\"auto_cache_clearing_sub\">Etkinleştirilirse uygulama önbelleği uygulama başlangıcında temizlenir</string>\n    <string name=\"create\">Oluştur</string>\n    <string name=\"tools\">Araçlar</string>\n    <string name=\"group_options_by_type\">Seçenekleri türe göre gruplandır</string>\n    <string name=\"group_options_by_type_sub\">Ana ekrandaki seçenekleri özel bir liste düzenlemesi yerine türlerine göre gruplandırır</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Seçenek gruplaması etkinken düzenleme değiştirilemez</string>\n    <string name=\"edit_screenshot\">Ekran görüntüsünü düzenle</string>\n    <string name=\"secondary_customization\">İkincil özelleştirme</string>\n    <string name=\"screenshot\">Ekran Görüntüsü</string>\n    <string name=\"fallback_option\">Yedek seçenek</string>\n    <string name=\"skip\">Atla</string>\n    <string name=\"copy\">Kopyala</string>\n    <string name=\"warning_bytes\">%1$s modunda kaydetme kararsız olabilir, çünkü bu kayıpsız bir formattır</string>\n    <string name=\"presets_sub\" formatted=\"false\">125 ön ayarını seçtiyseniz, resim orijinal resmin %125 boyutunda kaydedilecektir. Eğer 50 ön ayarını seçerseniz, resim %50 boyutunda kaydedilir</string>\n    <string name=\"presets_sub_bytes\">Buradaki ön ayar, çıktı dosyasının yüzdesini belirler, yani 5 MB\\'lık bir resimde %50 ön ayarını seçerseniz, kaydettikten sonra 2,5 MB\\'lık bir resim elde edersiniz</string>\n    <string name=\"randomize_filename\">Dosya adını rastgele yap</string>\n    <string name=\"randomize_filename_sub\">Etkinleştirilirse çıktı dosya adı tamamen rastgele olacaktır</string>\n    <string name=\"saved_to\">%1$s klasörüne %2$s adıyla kaydedildi</string>\n    <string name=\"saved_to_without_filename\">%1$s klasörüne kaydedildi</string>\n    <string name=\"tg_chat\">Telegram sohbeti</string>\n    <string name=\"tg_chat_sub\">Uygulamayı tartışın ve diğer kullanıcılardan geri bildirim alın. Ayrıca orada beta güncellemeleri ve bilgiler alabilirsiniz.</string>\n    <string name=\"crop_mask\">Kırpma maskesi</string>\n    <string name=\"aspect_ratio\">En Boy Oranı</string>\n    <string name=\"image_crop_mask_sub\">Verilen resimden maske oluşturmak için bu maske türünü kullanın, alfa kanalına sahip OLMASI gerektiğini unutmayın</string>\n    <string name=\"backup_and_restore\">Yedekle ve Geri Yükle</string>\n    <string name=\"backup\">Yedekle</string>\n    <string name=\"restore\">Geri Yükle</string>\n    <string name=\"backup_sub\">Uygulama ayarlarınızı bir dosyaya yedekleyin</string>\n    <string name=\"restore_sub\">Uygulama ayarlarını önceden oluşturulmuş bir dosyadan geri yükleyin</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Bozuk dosya veya yedekleme değil</string>\n    <string name=\"settings_restored\">Ayarlar başarıyla geri yüklendi</string>\n    <string name=\"contact_me\">Bana Ulaşın</string>\n    <string name=\"reset_settings_sub\">Bu, ayarlarınızı varsayılan değerlere geri döndürecektir. Yukarıda bahsedilen yedekleme dosyası olmadan bu işlemin geri alınamayacağını unutmayın.</string>\n    <string name=\"delete\">Sil</string>\n    <string name=\"delete_color_scheme_warn\">Seçili renk şemasını silmek üzeresiniz. Bu işlem geri alınamaz</string>\n    <string name=\"delete_color_scheme_title\">Şemayı sil</string>\n    <string name=\"font\">Yazı Tipi</string>\n    <string name=\"text\">Metin</string>\n    <string name=\"font_scale\">Yazı tipi ölçeği</string>\n    <string name=\"defaultt\">Varsayılan</string>\n    <string name=\"using_large_fonts_warn\">Büyük yazı tipi ölçekleri kullanmak, düzeltilmeyecek olan kullanıcı arayüzü hatalarına ve sorunlarına neden olabilir. Dikkatli kullanın.</string>\n    <string name=\"alphabet_and_numbers\">Aa Bb Cc Çç Dd Ee Ff Gg Ğğ Hh Ii İi Jj Kk Ll Mm Nn Oo Öö Pp Qq Rr Ss Şş Tt Uu Üü Vv Ww Xx Yy Zz 0123456789 !?</string>\n    <string name=\"emotions\">Duygular</string>\n    <string name=\"food_and_drink\">Yiyecek ve İçecek</string>\n    <string name=\"nature_and_animals\">Doğa ve Hayvanlar</string>\n    <string name=\"objects\">Nesneler</string>\n    <string name=\"symbols\">Semboller</string>\n    <string name=\"enable_emoji\">Emojiyi etkinleştir</string>\n    <string name=\"travels_and_places\">Seyahat ve Yerler</string>\n    <string name=\"activities\">Aktiviteler</string>\n    <string name=\"background_remover\">Arka Plan Temizleyici</string>\n    <string name=\"background_remover_sub\">Çizerek veya Otomatik seçeneğini kullanarak resimden arka planı kaldırın</string>\n    <string name=\"trim_image\">Resmi kırp</string>\n    <string name=\"keep_exif_sub\">Orijinal resim meta verileri korunacaktır</string>\n    <string name=\"trim_image_sub\">Resmin etrafındaki şeffaf boşluklar kırpılacaktır</string>\n    <string name=\"auto_erase_background\">Arka planı otomatik sil</string>\n    <string name=\"restore_image\">Resmi geri yükle</string>\n    <string name=\"erase_mode\">Silme modu</string>\n    <string name=\"erase_background\">Arka planı sil</string>\n    <string name=\"restore_background\">Arka planı geri yükle</string>\n    <string name=\"blur_radius\">Bulanıklık yarıçapı</string>\n    <string name=\"pipette\">Damlatıcı</string>\n    <string name=\"draw_mode\">Çizim modu</string>\n    <string name=\"create_issue\">Sorun Oluştur</string>\n    <string name=\"something_went_wrong_emphasis\">Hay aksi… Bir şeyler ters gitti. Aşağıdaki seçenekleri kullanarak bana yazabilirsiniz, bir çözüm bulmaya çalışacağım</string>\n    <string name=\"resize_and_convert\">Yeniden Boyutlandır ve Dönüştür</string>\n    <string name=\"resize_and_convert_sub\">Verilen resimlerin boyutunu değiştirin veya onları başka formatlara dönüştürün. Tek bir resim seçilirse EXIF meta verileri de burada düzenlenebilir.</string>\n    <string name=\"max_colors_count\">Maksimum renk sayısı</string>\n    <string name=\"crashlytics_sub\">Bu, uygulamanın çökme raporlarını otomatik olarak toplamasına olanak tanır</string>\n    <string name=\"analytics\">Analiz</string>\n    <string name=\"analytics_sub\">Anonim uygulama kullanım istatistiklerinin toplanmasına izin ver</string>\n    <string name=\"image_exif_warning\">Şu anda, %1$s formatı yalnızca Android\\'de EXIF meta verilerinin okunmasına izin vermektedir. Çıktı resmi kaydedildiğinde hiçbir meta veriye sahip olmayacaktır.</string>\n    <string name=\"effort\">Efor</string>\n    <string name=\"effort_sub\">%1$s değeri hızlı bir sıkıştırma anlamına gelir ve nispeten büyük bir dosya boyutuyla sonuçlanır. %2$s daha yavaş bir sıkıştırma anlamına gelir ve daha küçük bir dosyayla sonuçlanır.</string>\n    <string name=\"wait\">Bekle</string>\n    <string name=\"saving_almost_complete\">Kaydetme neredeyse tamamlandı. Şimdi iptal etmek yeniden kaydetmeyi gerektirecektir.</string>\n    <string name=\"updates\">Güncellemeler</string>\n    <string name=\"allow_betas\">Beta sürümlerine izin ver</string>\n    <string name=\"allow_betas_sub\">Etkinleştirilirse güncelleme kontrolü beta uygulama sürümlerini de içerecektir</string>\n    <string name=\"draw_arrows\">Ok Çiz</string>\n    <string name=\"draw_arrows_sub\">Etkinleştirilirse çizim yolu bir ok işareti olarak temsil edilecektir</string>\n    <string name=\"brush_softness\">Fırça yumuşaklığı</string>\n    <string name=\"crop_description\">Resimler, girilen boyuta göre merkezden kırpılacaktır. Resim girilen boyutlardan küçükse, tuval verilen arka plan rengiyle genişletilecektir.</string>\n    <string name=\"donation\">Bağış</string>\n    <string name=\"image_stitching\">Resim Birleştirme</string>\n    <string name=\"image_stitching_sub\">Verilen resimleri birleştirerek büyük bir resim elde edin</string>\n    <string name=\"pick_at_least_two_images\">En az 2 resim seçin</string>\n    <string name=\"output_image_scale\">Çıktı resmi ölçeği</string>\n    <string name=\"image_orientation\">Resim Yönü</string>\n    <string name=\"horizontal\">Yatay</string>\n    <string name=\"vertical\">Dikey</string>\n    <string name=\"scale_small_images_to_large\">Küçük resimleri büyüğe ölçekle</string>\n    <string name=\"scale_small_images_to_large_sub\">Etkinleştirilirse küçük resimler dizideki en büyük resme göre ölçeklenecektir</string>\n    <string name=\"images_order\">Resimlerin sırası</string>\n    <string name=\"regular\">Normal</string>\n    <string name=\"blur_edges\">Kenarları bulanıklaştır</string>\n    <string name=\"blur_edges_sub\">Etkinleştirilirse, resmin etrafındaki boşlukları doldurmak için tek bir renk yerine orijinal resmin altına bulanık kenarlar çizer</string>\n    <string name=\"pixelation\">Pikselleştirme</string>\n    <string name=\"enhanced_pixelation\">Gelişmiş Pikselleştirme</string>\n    <string name=\"stroke_pixelation\">Konturlu Pikselleştirme</string>\n    <string name=\"enhanced_diamond_pixelation\">Gelişmiş Elmas Pikselleştirme</string>\n    <string name=\"diamond_pixelation\">Elmas Pikselleştirme</string>\n    <string name=\"circle_pixelation\">Daire Pikselleştirme</string>\n    <string name=\"enhanced_circle_pixelation\">Gelişmiş Daire Pikselleştirme</string>\n    <string name=\"replace_color\">Rengi Değiştir</string>\n    <string name=\"tolerance\">Tolerans</string>\n    <string name=\"color_to_replace\">Değiştirilecek Renk</string>\n    <string name=\"target_color\">Hedef Renk</string>\n    <string name=\"color_to_remove\">Kaldırılacak Renk</string>\n    <string name=\"remove_color\">Rengi Kaldır</string>\n    <string name=\"recode\">Yeniden Kodla</string>\n    <string name=\"pixel_size\">Piksel Boyutu</string>\n    <string name=\"lock_draw_orientation\">Çizim yönünü kilitle</string>\n    <string name=\"lock_draw_orientation_sub\">Çizim modunda etkinleştirilirse ekran dönmez</string>\n    <string name=\"check_for_updates\">Güncellemeleri denetle</string>\n    <string name=\"palette_style\">Palet stili</string>\n    <string name=\"tonal_spot\">Tonal Nokta</string>\n    <string name=\"neutral\">Nötr</string>\n    <string name=\"vibrant\">Canlı</string>\n    <string name=\"expressive\">Etkileyici</string>\n    <string name=\"rainbow\">Gökkuşağı</string>\n    <string name=\"fruit_salad\">Meyve Salatası</string>\n    <string name=\"fidelity\">Sadakat</string>\n    <string name=\"content\">İçerik</string>\n    <string name=\"tonal_spot_sub\">Varsayılan palet stili, dört rengin tamamını özelleştirmenize olanak tanır, diğerleri yalnızca anahtar rengi ayarlamanıza izin verir</string>\n    <string name=\"neutral_sub\">Monokromdan biraz daha kromatik bir stil</string>\n    <string name=\"vibrant_sub\">Gürültülü bir tema, Birincil palet için renklilik maksimumdur, diğerleri için artırılmıştır</string>\n    <string name=\"playful_scheme\">Eğlenceli bir tema - kaynak rengin tonu temada görünmez</string>\n    <string name=\"monochrome_sub\">Monokrom bir tema, renkler tamamen siyah/beyaz/gri</string>\n    <string name=\"content_sub\">Kaynak rengi Scheme.primaryContainer\\'a yerleştiren bir şema</string>\n    <string name=\"fidelity_sub\">İçerik şemasına çok benzeyen bir şema</string>\n    <string name=\"foss_update_checker_warning\">Bu güncelleme denetleyicisi, yeni bir güncelleme olup olmadığını kontrol etmek amacıyla GitHub\\'a bağlanacaktır</string>\n    <string name=\"attention\">Dikkat</string>\n    <string name=\"fading_edges\">Solan Kenarlar</string>\n    <string name=\"disabled\">Devre Dışı</string>\n    <string name=\"both\">Her ikisi de</string>\n    <string name=\"invert_colors\">Renkleri Ters Çevir</string>\n    <string name=\"invert_colors_sub\">Etkinleştirilirse tema renklerini negatif olanlarla değiştirir</string>\n    <string name=\"search_option\">Ara</string>\n    <string name=\"search_option_sub\">Ana ekranda mevcut tüm araçlar arasında arama yapma yeteneğini etkinleştirir</string>\n    <string name=\"pdf_tools\">PDF Araçları</string>\n    <string name=\"pdf_tools_sub\">PDF dosyalarıyla çalışın: Önizleyin, bir grup resme dönüştürün veya verilen resimlerden bir tane oluşturun</string>\n    <string name=\"preview_pdf\">PDF Önizle</string>\n    <string name=\"pdf_to_images\">PDF\\'den Resimlere</string>\n    <string name=\"images_to_pdf\">Resimlerden PDF\\'e</string>\n    <string name=\"preview_pdf_sub\">Basit PDF önizlemesi</string>\n    <string name=\"pdf_to_images_sub\">PDF\\'yi verilen çıktı formatında Resimlere dönüştürün</string>\n    <string name=\"images_to_pdf_sub\">Verilen Resimleri çıktı PDF dosyasına paketleyin</string>\n    <string name=\"mask_filter\">Maske Filtresi</string>\n    <string name=\"mask_filter_sub\">Verilen maskelenmiş alanlara filtre zincirleri uygulayın, her maske alanı kendi filtre setini belirleyebilir</string>\n    <string name=\"masks\">Maskeler</string>\n    <string name=\"add_mask\">Maske Ekle</string>\n    <string name=\"mask_indexed\">Maske %d</string>\n    <string name=\"mask_color\">Maske Rengi</string>\n    <string name=\"mask_preview\">Maske önizlemesi</string>\n    <string name=\"mask_preview_sub\">Çizilen filtre maskesi, size yaklaşık sonucu göstermek için oluşturulacaktır</string>\n    <string name=\"inverse_fill_type\">Ters Doldurma Türü</string>\n    <string name=\"inverse_fill_type_sub\">Etkinleştirilirse, varsayılan davranış yerine maskelenmemiş alanların tümü filtrelenecektir</string>\n    <string name=\"delete_mask_warn\">Seçili filtre maskesini silmek üzeresiniz. Bu işlem geri alınamaz</string>\n    <string name=\"delete_mask\">Maskeyi sil</string>\n    <string name=\"full_filter\">Tam Filtre</string>\n    <string name=\"full_filter_sub\">Verilen resimlere veya tek bir resme herhangi bir filtre zinciri uygulayın</string>\n    <string name=\"start_position\">Başlangıç</string>\n    <string name=\"center_position\">Merkez</string>\n    <string name=\"end_position\">Bitiş</string>\n    <string name=\"simple_variants\">Basit Varyantlar</string>\n    <string name=\"highlighter\">Vurgulayıcı</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Kalem</string>\n    <string name=\"privacy_blur\">Gizlilik Bulanıklığı</string>\n    <string name=\"highlighter_sub\">Yarı saydam keskinleştirilmiş vurgulayıcı yolları çizin</string>\n    <string name=\"neon_sub\">Çizimlerinize parlayan bir efekt ekleyin</string>\n    <string name=\"pen_sub\">Varsayılan olan, en basiti - sadece renk</string>\n    <string name=\"privacy_blur_sub\">Gizlemek istediğiniz her şeyi güvence altına almak için çizilen yolun altındaki resmi bulanıklaştırır</string>\n    <string name=\"pixelation_sub\">Gizlilik bulanıklığına benzer, ancak bulanıklaştırmak yerine pikselleştirir</string>\n    <string name=\"containers_shadow\">Konteynerler</string>\n    <string name=\"containers_shadow_sub\">Konteynerlerin arkasına bir gölge çizin</string>\n    <string name=\"sliders_shadow\">Kaydırıcılar</string>\n    <string name=\"switches_shadow\">Anahtarlar</string>\n    <string name=\"fabs_shadow\">FAB\\'lar</string>\n    <string name=\"buttons_shadow\">Düğmeler</string>\n    <string name=\"sliders_shadow_sub\">Kaydırıcıların arkasına bir gölge çizin</string>\n    <string name=\"switches_shadow_sub\">Anahtarların arkasına bir gölge çizin</string>\n    <string name=\"fabs_shadow_sub\">Hareketli eylem düğmelerinin arkasına bir gölge çizin</string>\n    <string name=\"buttons_shadow_sub\">Düğmelerin arkasına bir gölge çizin</string>\n    <string name=\"app_bars_shadow\">Uygulama çubukları</string>\n    <string name=\"app_bars_shadow_sub\">Uygulama çubuklarının arkasına bir gölge çizin</string>\n    <string name=\"value_in_range\">%1$s - %2$s aralığında değer</string>\n    <string name=\"auto_rotate_limits\">Otomatik Döndür</string>\n    <string name=\"auto_rotate_limits_sub\">Sınır kutusunun resim yönüne uyarlanmasına izin verir</string>\n    <string name=\"draw_path_mode\">Çizim Yolu Modu</string>\n    <string name=\"double_line_arrow\">Çift Çizgili Ok</string>\n    <string name=\"free_drawing\">Serbest Çizim</string>\n    <string name=\"double_arrow\">Çift Ok</string>\n    <string name=\"line_arrow\">Çizgi Ok</string>\n    <string name=\"arrow\">Ok</string>\n    <string name=\"line\">Çizgi</string>\n    <string name=\"free_drawing_sub\">Yolu girdi değeri olarak çizer</string>\n    <string name=\"line_sub\">Başlangıç noktasından bitiş noktasına bir çizgi olarak yol çizer</string>\n    <string name=\"line_arrow_sub\">Başlangıç noktasından bitiş noktasına bir çizgi olarak işaret eden bir ok çizer</string>\n    <string name=\"arrow_sub\">Verilen bir yoldan işaret eden bir ok çizer</string>\n    <string name=\"double_line_arrow_sub\">Başlangıç noktasından bitiş noktasına bir çizgi olarak çift işaret eden bir ok çizer</string>\n    <string name=\"double_arrow_sub\">Verilen bir yoldan çift işaret eden bir ok çizer</string>\n    <string name=\"outlined_oval\">Dış Çizgili Oval</string>\n    <string name=\"outlined_rect\">Dış Çizgili Dikdörtgen</string>\n    <string name=\"oval\">Oval</string>\n    <string name=\"rect\">Dikdörtgen</string>\n    <string name=\"rect_sub\">Başlangıç noktasından bitiş noktasına dikdörtgen çizer</string>\n    <string name=\"oval_sub\">Başlangıç noktasından bitiş noktasına oval çizer</string>\n    <string name=\"outlined_oval_sub\">Başlangıç noktasından bitiş noktasına dış çizgili oval çizer</string>\n    <string name=\"outlined_rect_sub\">Başlangıç noktasından bitiş noktasına dış çizgili dikdörtgen çizer</string>\n    <string name=\"lasso\">Kement</string>\n    <string name=\"lasso_sub\">Verilen yolla kapalı, doldurulmuş bir yol çizer</string>\n    <string name=\"free\">Serbest</string>\n    <string name=\"horizontal_grid\">Yatay Izgara</string>\n    <string name=\"vertical_grid\">Dikey Izgara</string>\n    <string name=\"stitch_mode\">Birleştirme Modu</string>\n    <string name=\"rows_count\">Satır Sayısı</string>\n    <string name=\"columns_count\">Sütun Sayısı</string>\n    <string name=\"no_such_directory\">\\\"%1$s\\\" dizini bulunamadı, varsayılan dizine geçtik, lütfen dosyayı tekrar kaydedin</string>\n    <string name=\"clipboard\">Pano</string>\n    <string name=\"auto_pin\">Otomatik sabitle</string>\n    <string name=\"auto_pin_sub\">Etkinleştirilirse kaydedilen resmi otomatik olarak panoya ekler</string>\n    <string name=\"vibration\">Titreşim</string>\n    <string name=\"vibration_strength\">Titreşim Şiddeti</string>\n    <string name=\"overwrite_file_requirements\">Dosyaların üzerine yazmak için \\\"Gezgin\\\" resim kaynağını kullanmanız gerekir, resimleri yeniden seçmeyi deneyin, resim kaynağını gerekli olana değiştirdik</string>\n    <string name=\"overwrite_files\">Dosyaların Üzerine Yaz</string>\n    <string name=\"overwrite_files_sub\">Orijinal dosya, seçilen klasöre kaydetmek yerine yenisiyle değiştirilir, bu seçenek resim kaynağının \\\"Gezgin\\\" veya GetContent olmasını gerektirir, bu seçeneği değiştirdiğinizde otomatik olarak ayarlanacaktır</string>\n    <string name=\"empty\">Boş</string>\n    <string name=\"suffix\">Son Ek</string>\n    <string name=\"scale_mode\">Ölçekleme modu</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">En Yakın</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Temel</string>\n    <string name=\"default_value\">Varsayılan Değer</string>\n    <string name=\"bilinear_sub\">Doğrusal (veya iki boyutta bilinear) enterpolasyon genellikle bir resmin boyutunu değiştirmek için iyidir, ancak ayrıntıların istenmeyen bir şekilde yumuşamasına neden olur ve hala biraz pürüzlü olabilir</string>\n    <string name=\"bicubic_sub\">Daha iyi ölçekleme yöntemleri arasında Lanczos yeniden örnekleme ve Mitchell-Netravali filtreleri bulunur</string>\n    <string name=\"nearest_sub\">Boyutu artırmanın daha basit yollarından biri, her pikseli aynı renkteki bir dizi pikselle değiştirmektir</string>\n    <string name=\"basic_sub\">Hemen hemen tüm uygulamalarda kullanılan en basit Android ölçekleme modu</string>\n    <string name=\"catmull_sub\">Bir dizi kontrol noktasını düzgün bir şekilde enterpole etmek ve yeniden örneklemek için bir yöntem, genellikle bilgisayar grafiklerinde pürüzsüz eğriler oluşturmak için kullanılır</string>\n    <string name=\"hann_sub\">Spektral sızıntıyı en aza indirmek ve bir sinyalin kenarlarını daraltarak frekans analizinin doğruluğunu artırmak için sinyal işlemede sıklıkla uygulanan bir pencereleme fonksiyonu</string>\n    <string name=\"hermite_sub\">Pürüzsüz ve sürekli bir eğri oluşturmak için bir eğri segmentinin uç noktalarındaki değerleri ve türevleri kullanan matematiksel bir enterpolasyon tekniği</string>\n    <string name=\"lanczos_sub\">Piksel değerlerine ağırlıklı bir sinc fonksiyonu uygulayarak yüksek kaliteli enterpolasyonu koruyan bir yeniden örnekleme yöntemi</string>\n    <string name=\"mitchell_sub\">Ölçeklenmiş resimde keskinlik ve kenar yumuşatma arasında bir denge sağlamak için ayarlanabilir parametrelere sahip bir konvolüsyon filtresi kullanan bir yeniden örnekleme yöntemi</string>\n    <string name=\"spline_sub\">Esnek ve sürekli şekil temsili sağlayarak bir eğriyi veya yüzeyi pürüzsüz bir şekilde enterpole etmek ve yaklaştırmak için parçalı tanımlanmış polinom fonksiyonları kullanır</string>\n    <string name=\"only_clip\">Sadece Panoya Kopyala</string>\n    <string name=\"only_clip_sub\">Depolama alanına kaydetme yapılmayacak ve resim yalnızca panoya konulmaya çalışılacaktır</string>\n    <string name=\"restore_background_sub\">Fırça, silmek yerine arka planı geri yükleyecektir</string>\n    <string name=\"recognize_text\">OCR (metin tanıma)</string>\n    <string name=\"recognize_text_sub\">Verilen resimden metin tanıyın, 120+ dil desteklenir</string>\n    <string name=\"picture_has_no_text\">Resimde metin yok veya uygulama bulamadı</string>\n    <string name=\"accuracy\">Doğruluk: %1$s</string>\n    <string name=\"recognition_type\">Tanıma Türü</string>\n    <string name=\"fast\">Hızlı</string>\n    <string name=\"standard\">Standart</string>\n    <string name=\"best\">En İyi</string>\n    <string name=\"no_data\">Veri Yok</string>\n    <string name=\"download_description\">Tesseract OCR\\'nin düzgün çalışması için ek eğitim verilerinin (%1$s) cihazınıza indirilmesi gerekir.\\n%2$s verilerini indirmek istiyor musunuz?</string>\n    <string name=\"download\">İndir</string>\n    <string name=\"no_connection\">Bağlantı yok, kontrol edin ve eğitim modellerini indirmek için tekrar deneyin</string>\n    <string name=\"downloaded_languages\">İndirilen Diller</string>\n    <string name=\"available_languages\">Mevcut Diller</string>\n    <string name=\"segmentation_mode\">Segmentasyon Modu</string>\n    <string name=\"use_pixel_switch\">Piksel Anahtarı Kullan</string>\n    <string name=\"use_pixel_switch_sub\">Google Pixel benzeri bir anahtar kullanır</string>\n    <string name=\"saved_to_original\">Orijinal hedefe %1$s adıyla dosyanın üzerine yazıldı</string>\n    <string name=\"magnifier\">Büyüteç</string>\n    <string name=\"magnifier_sub\">Daha iyi erişilebilirlik için çizim modlarında parmağın üstünde büyüteci etkinleştirir</string>\n    <string name=\"force_exif_widget_initial_value\">Başlangıç değerini zorla</string>\n    <string name=\"force_exif_widget_initial_value_sub\">EXIF aracının başlangıçta işaretli olmasını zorlar</string>\n    <string name=\"allow_multiple_languages\">Çoklu Dil İzni</string>\n    <string name=\"slide\">Kaydır</string>\n    <string name=\"side_by_side\">Yan Yana</string>\n    <string name=\"toggle_tap\">Dokunarak Değiştir</string>\n    <string name=\"transparency\">Şeffaflık</string>\n    <string name=\"rate_app\">Uygulamayı Oyla</string>\n    <string name=\"rate\">Oyla</string>\n    <string name=\"rate_app_sub\">Bu uygulama tamamen ücretsizdir, daha da büyümesini isterseniz, lütfen projeyi Github\\'da yıldızlayın 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Sadece Yön ve Yazı Tipi Tespiti</string>\n    <string name=\"segmentation_mode_auto_osd\">Otomatik Yön ve Yazı Tipi Tespiti</string>\n    <string name=\"segmentation_mode_auto_only\">Sadece Otomatik</string>\n    <string name=\"segmentation_mode_auto\">Otomatik</string>\n    <string name=\"segmentation_mode_single_column\">Tek Sütun</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Tek blok dikey metin</string>\n    <string name=\"segmentation_mode_single_block\">Tek blok</string>\n    <string name=\"segmentation_mode_single_line\">Tek satır</string>\n    <string name=\"segmentation_mode_single_word\">Tek kelime</string>\n    <string name=\"segmentation_mode_circle_word\">Daire kelime</string>\n    <string name=\"segmentation_mode_single_char\">Tek karakter</string>\n    <string name=\"segmentation_mode_sparse_text\">Seyrek metin</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Seyrek metin Yön ve Yazı Tipi Tespiti</string>\n    <string name=\"segmentation_mode_raw_line\">Ham satır</string>\n    <string name=\"delete_language_sub\">\\\"%1$s\\\" dili OCR eğitim verilerini tüm tanıma türleri için mi, yoksa sadece seçili olan (%2$s) için mi silmek istiyorsunuz?</string>\n    <string name=\"current\">Mevcut</string>\n    <string name=\"all\">Tümü</string>\n    <string name=\"gradient_maker\">Gradyan Oluşturucu</string>\n    <string name=\"gradient_maker_sub\">Özelleştirilmiş renkler ve görünüm türü ile verilen çıktı boyutunda gradyan oluşturun</string>\n    <string name=\"gradient_type_linear\">Doğrusal</string>\n    <string name=\"gradient_type_radial\">Radyal</string>\n    <string name=\"gradient_type_sweep\">Süpürme</string>\n    <string name=\"gradient_type\">Gradyan Türü</string>\n    <string name=\"center_x\">Merkez X</string>\n    <string name=\"center_y\">Merkez Y</string>\n    <string name=\"tile_mode\">Döşeme Modu</string>\n    <string name=\"tile_mode_repeated\">Tekrarlanan</string>\n    <string name=\"tile_mode_mirror\">Ayna</string>\n    <string name=\"tile_mode_clamp\">Sıkıştır</string>\n    <string name=\"tile_mode_decal\">Çıkartma</string>\n    <string name=\"color_stops\">Renk Durakları</string>\n    <string name=\"add_color\">Renk Ekle</string>\n    <string name=\"properties\">Özellikler</string>\n    <string name=\"brightness_enforcement\">Parlaklık Zorlaması</string>\n    <string name=\"screen\">Ekran</string>\n    <string name=\"gradient_maker_type_image\">Gradyan Kaplaması</string>\n    <string name=\"gradient_maker_type_image_sub\">Verilen resimlerin üzerine herhangi bir gradyan oluşturun</string>\n    <string name=\"transformations\">Dönüşümler</string>\n    <string name=\"camera\">Kamera</string>\n    <string name=\"camera_sub\">Kamera ile bir fotoğraf çekin. Bu resim kaynağından yalnızca bir resim alınabileceğini unutmayın</string>\n    <string name=\"watermarking\">Filigran Ekleme</string>\n    <string name=\"watermarking_sub\">Resimleri özelleştirilebilir metin/resim filigranları ile kaplayın</string>\n    <string name=\"repeat_watermark\">Filigranı tekrarla</string>\n    <string name=\"repeat_watermark_sub\">Verilen konumda tek bir filigran yerine resim üzerinde tekrarlar</string>\n    <string name=\"offset_x\">Ofset X</string>\n    <string name=\"offset_y\">Ofset Y</string>\n    <string name=\"watermark_type\">Filigran Türü</string>\n    <string name=\"watermarking_image_sub\">Bu resim filigranlama için desen olarak kullanılacaktır</string>\n    <string name=\"text_color\">Metin Rengi</string>\n    <string name=\"overlay_mode\">Kaplama Modu</string>\n    <string name=\"gif_tools\">GIF Araçları</string>\n    <string name=\"gif_tools_sub\">Resimleri GIF resmine dönüştürün veya verilen GIF resminden kareler çıkarın</string>\n    <string name=\"gif_type_to_image\">GIF\\'den resimlere</string>\n    <string name=\"gif_type_to_image_sub\">GIF dosyasını bir dizi resme dönüştürün</string>\n    <string name=\"gif_type_to_gif_sub\">Bir dizi resmi GIF dosyasına dönüştürün</string>\n    <string name=\"gif_type_to_gif\">Resimlerden GIF\\'e</string>\n    <string name=\"select_gif_image_to_start\">Başlamak için GIF resmi seçin</string>\n    <string name=\"use_size_of_first_frame\">İlk karenin boyutunu kullan</string>\n    <string name=\"use_size_of_first_frame_sub\">Belirtilen boyutu ilk karenin boyutlarıyla değiştir</string>\n    <string name=\"repeat_count\">Tekrar Sayısı</string>\n    <string name=\"frame_delay\">Kare Gecikmesi</string>\n    <string name=\"millis\">milisaniye</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Kement kullan</string>\n    <string name=\"use_lasso_sub\">Silme işlemini gerçekleştirmek için çizim modundaki gibi Kement kullanır</string>\n    <string name=\"original_image_preview_alpha\">Orijinal Resim Önizleme Alfa Değeri</string>\n    <string name=\"confetti\">Konfeti</string>\n    <string name=\"confetti_sub\">Kaydetme, paylaşma ve diğer birincil eylemlerde konfeti gösterilecektir</string>\n    <string name=\"secure_mode\">Güvenli Mod</string>\n    <string name=\"secure_mode_sub\">Son uygulamalarda uygulama içeriğini gizler. Yakalanamaz veya kaydedilemez.</string>\n    <string name=\"exit\">Çıkış</string>\n    <string name=\"preview_closing\">Şimdi önizlemeden ayrılırsanız, resimleri yeniden eklemeniz gerekecek</string>\n    <string name=\"dithering\">Titreşim (Dithering)</string>\n    <string name=\"quantizier\">Kuantalayıcı</string>\n    <string name=\"gray_scale\">Gri Tonlama</string>\n    <string name=\"bayer_two_dithering\">Bayer 2x2 Titreşim</string>\n    <string name=\"bayer_three_dithering\">Bayer 3x3 Titreşim</string>\n    <string name=\"bayer_four_dithering\">Bayer 4x4 Titreşim</string>\n    <string name=\"bayer_eight_dithering\">Bayer 8x8 Titreşim</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Titreşim</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Titreşim</string>\n    <string name=\"sierra_dithering\">Sierra Titreşim</string>\n    <string name=\"two_row_sierra_dithering\">İki Sıralı Sierra Titreşim</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Titreşim</string>\n    <string name=\"atkinson_dithering\">Atkinson Titreşim</string>\n    <string name=\"stucki_dithering\">Stucki Titreşim</string>\n    <string name=\"burkes_dithering\">Burkes Titreşim</string>\n    <string name=\"false_floyd_steinberg_dithering\">Yanlış Floyd Steinberg Titreşim</string>\n    <string name=\"left_to_right_dithering\">Soldan Sağa Titreşim</string>\n    <string name=\"random_dithering\">Rastgele Titreşim</string>\n    <string name=\"simple_threshold_dithering\">Basit Eşik Titreşimi</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Mekansal Sigma</string>\n    <string name=\"median_blur\">Medyan Bulanıklığı</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">Esnek ve sürekli şekil temsili için bir eğriyi veya yüzeyi pürüzsüzce enterpole etmek ve yaklaştırmak için parçalı tanımlanmış iki küplü polinom fonksiyonları kullanır</string>\n    <string name=\"native_stack_blur\">Doğal Yığın Bulanıklığı</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"glitch\">Glitch (Bozulma)</string>\n    <string name=\"amount\">Miktar</string>\n    <string name=\"seed\">Tohum</string>\n    <string name=\"anaglyph\">Anaglif</string>\n    <string name=\"noise\">Gürültü</string>\n    <string name=\"pixel_sort\">Piksel Sıralama</string>\n    <string name=\"shuffle\">Karıştır</string>\n    <string name=\"enhanced_glitch\">Gelişmiş Glitch</string>\n    <string name=\"channel_shift_x\">Kanal Kaydırma X</string>\n    <string name=\"channel_shift_y\">Kanal Kaydırma Y</string>\n    <string name=\"corruption_size\">Bozulma Boyutu</string>\n    <string name=\"corruption_shift_x\">Bozulma Kaydırma X</string>\n    <string name=\"corruption_shift_y\">Bozulma Kaydırma Y</string>\n    <string name=\"tent_blur\">Çadır Bulanıklığı</string>\n    <string name=\"side_fade\">Yan Solma</string>\n    <string name=\"side\">Yan</string>\n    <string name=\"top\">Üst</string>\n    <string name=\"bottom\">Alt</string>\n    <string name=\"strength\">Güç</string>\n    <string name=\"erode\">Aşındırma</string>\n    <string name=\"anisotropic_diffusion\">Anizotropik Difüzyon</string>\n    <string name=\"diffusion\">Dağılım</string>\n    <string name=\"conduction\">İletim</string>\n    <string name=\"horizontal_wind_stagger\">Yatay Rüzgar Titremesi</string>\n    <string name=\"fast_bilaterial_blur\">Hızlı Bilateral Bulanıklık</string>\n    <string name=\"poisson_blur\">Poisson Bulanıklığı</string>\n    <string name=\"logarithmic_tone_mapping\">Logaritmik Ton Eşleme</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmik Ton Eşleme</string>\n    <string name=\"crystallize\">Kristalleştir</string>\n    <string name=\"stroke_color\">Kontur Rengi</string>\n    <string name=\"fractal_glass\">Fraktal Cam</string>\n    <string name=\"amplitude\">Genlik</string>\n    <string name=\"marble\">Mermer</string>\n    <string name=\"turbulence\">Türbülans</string>\n    <string name=\"oil\">Yağlı Boya</string>\n    <string name=\"water_effect\">Su Efekti</string>\n    <string name=\"just_size\">Boyut</string>\n    <string name=\"frequency_x\">Frekans X</string>\n    <string name=\"frequency_y\">Frekans Y</string>\n    <string name=\"amplitude_x\">Genlik X</string>\n    <string name=\"amplitude_y\">Genlik Y</string>\n    <string name=\"perlin_distortion\">Perlin Bozulması</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Ton Eşleme</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmik Ton Eşleme</string>\n    <string name=\"heji_burgess_tone_mapping\">Heji-Burgess Ton Eşleme</string>\n    <string name=\"speed\">Hız</string>\n    <string name=\"dehaze\">Pus Giderme</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Renk Matrisi 4x4</string>\n    <string name=\"color_matrix_3x3\">Renk Matrisi 3x3</string>\n    <string name=\"simple_effects\">Basit Efektler</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritanomali</string>\n    <string name=\"deutaromaly\">Döteranomali</string>\n    <string name=\"protonomaly\">Protanomali</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Krom</string>\n    <string name=\"night_vision\">Gece Görüşü</string>\n    <string name=\"warm\">Sıcak</string>\n    <string name=\"cool\">Soğuk</string>\n    <string name=\"tritanopia\">Tritanopi</string>\n    <string name=\"deutaronotopia\">Döteranotopi</string>\n    <string name=\"protanopia\">Protanopi</string>\n    <string name=\"achromatomaly\">Akromatopsi Anomalisi</string>\n    <string name=\"achromatopsia\">Akromatopsi</string>\n    <string name=\"grain\">Gren</string>\n    <string name=\"unsharp\">Bulanıklaştırmayı Geri Al</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">Turuncu Pus</string>\n    <string name=\"pink_dream\">Pembe Rüya</string>\n    <string name=\"golden_hour\">Altın Saat</string>\n    <string name=\"hot_summer\">Sıcak Yaz</string>\n    <string name=\"purple_mist\">Mor Sis</string>\n    <string name=\"sunrise\">Gün Doğumu</string>\n    <string name=\"colorful_swirl\">Renkli Girdap</string>\n    <string name=\"soft_spring_light\">Yumuşak Bahar Işığı</string>\n    <string name=\"autumn_tones\">Sonbahar Tonları</string>\n    <string name=\"lavender_dream\">Lavanta Rüyası</string>\n    <string name=\"cyberpunk\">Siberpunk</string>\n    <string name=\"lemonade_light\">Limonata Işığı</string>\n    <string name=\"spectral_fire\">Spektral Ateş</string>\n    <string name=\"night_magic\">Gece Büyüsü</string>\n    <string name=\"fantasy_landscape\">Fantastik Manzara</string>\n    <string name=\"color_explosion\">Renk Patlaması</string>\n    <string name=\"electric_gradient\">Elektrik Gradyanı</string>\n    <string name=\"caramel_darkness\">Karamel Karanlığı</string>\n    <string name=\"futuristic_gradient\">Fütüristik Gradyan</string>\n    <string name=\"green_sun\">Yeşil Güneş</string>\n    <string name=\"rainbow_world\">Gökkuşağı Dünyası</string>\n    <string name=\"deep_purple\">Derin Mor</string>\n    <string name=\"space_portal\">Uzay Portalı</string>\n    <string name=\"red_swirl\">Kırmızı Girdap</string>\n    <string name=\"digital_code\">Dijital Kod</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">Uygulama çubuğu emojisi rastgele değişecektir</string>\n    <string name=\"random_emojis\">Rastgele Emojiler</string>\n    <string name=\"random_emojis_error\">Emojiler devre dışı bırakılmışken rastgele emojileri kullanamazsınız</string>\n    <string name=\"emoji_selection_error\">Rastgele emojiler etkinken bir emoji seçemezsiniz</string>\n    <string name=\"old_tv\">Eski TV</string>\n    <string name=\"shuffle_blur\">Karıştırma Bulanıklığı</string>\n    <string name=\"favorite\">Favori</string>\n    <string name=\"no_favorite_filters\">Henüz favori filtre eklenmedi</string>\n    <string name=\"image_format\">Resim Formatı</string>\n    <string name=\"icon_shape_sub\">Simgelerin altına seçilen şekilde bir kap ekler</string>\n    <string name=\"icon_shape\">Simge Şekli</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Kesme</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Geçiş</string>\n    <string name=\"peak\">Zirve</string>\n    <string name=\"color_anomaly\">Renk Anomalisi</string>\n    <string name=\"images_overwritten\">Resimlerin üzerine orijinal hedeflerinde yazıldı</string>\n    <string name=\"cannot_change_image_format\">Dosyaların üzerine yazma seçeneği etkinken resim formatı değiştirilemez</string>\n    <string name=\"emoji_as_color_scheme\">Renk Şeması Olarak Emoji</string>\n    <string name=\"emoji_as_color_scheme_sub\">Manuel olarak tanımlanan yerine uygulamanın renk şeması olarak emojinin birincil rengini kullanır</string>\n    <string name=\"material_you_sub\">Resimden Material You paleti oluşturur</string>\n    <string name=\"dark_colors\">Koyu Renkler</string>\n    <string name=\"dark_colors_sub\">Aydınlık varyant yerine gece modu renk şemasını kullanır</string>\n    <string name=\"copy_as_compose_code\">Jetpack Compose kodu olarak kopyala</string>\n    <string name=\"ring_blur\">Halka Bulanıklığı</string>\n    <string name=\"cross_blur\">Çapraz Bulanıklık</string>\n    <string name=\"circle_blur\">Daire Bulanıklığı</string>\n    <string name=\"star_blur\">Yıldız Bulanıklığı</string>\n    <string name=\"linear_tilt_shift\">Doğrusal Tilt-Shift</string>\n    <string name=\"tags_to_remove\">Kaldırılacak Etiketler</string>\n    <string name=\"apng_tools\">APNG Araçları</string>\n    <string name=\"apng_tools_sub\">Resimleri APNG resmine dönüştürün veya verilen APNG resminden kareler ayıklayın</string>\n    <string name=\"apng_type_to_image\">APNG\\'den resimlere</string>\n    <string name=\"apng_type_to_image_sub\">APNG dosyasını bir dizi resme dönüştürün</string>\n    <string name=\"apng_type_to_apng_sub\">Bir dizi resmi APNG dosyasına dönüştürün</string>\n    <string name=\"apng_type_to_apng\">Resimlerden APNG\\'ye</string>\n    <string name=\"select_apng_image_to_start\">Başlamak için APNG resmi seçin</string>\n    <string name=\"motion_blur\">Hareket Bulanıklığı</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Verilen dosyalardan veya resimlerden Zip dosyası oluşturun</string>\n    <string name=\"drag_handle_width\">Sürükleme Kolu Genişliği</string>\n    <string name=\"confetti_type\">Konfeti Türü</string>\n    <string name=\"festive\">Şenlikli</string>\n    <string name=\"explode\">Patlama</string>\n    <string name=\"rain\">Yağmur</string>\n    <string name=\"corners\">Köşeler</string>\n    <string name=\"jxl_tools\">JXL Araçları</string>\n    <string name=\"jxl_tools_sub\">Kalite kaybı olmadan JXL ~ JPEG dönüştürme yapın veya GIF/APNG\\'yi JXL animasyonuna dönüştürün</string>\n    <string name=\"jxl_type_to_jpeg\">JXL\\'den JPEG\\'e</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL\\'den JPEG\\'e kayıpsız dönüştürme yapın</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG\\'den JXL\\'e kayıpsız dönüştürme yapın</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG\\'den JXL\\'e</string>\n    <string name=\"select_jxl_image_to_start\">Başlamak için JXL resmi seçin</string>\n    <string name=\"fast_gaussian_blur_2d\">Hızlı Gauss Bulanıklığı 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Hızlı Gauss Bulanıklığı 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Hızlı Gauss Bulanıklığı 4D</string>\n    <string name=\"auto_paste\">Otomatik Yapıştır</string>\n    <string name=\"auto_paste_sub\">Uygulamanın pano verilerini otomatik olarak yapıştırmasına izin verir, böylece ana ekranda görünür ve işleyebilirsiniz</string>\n    <string name=\"harmonization_color\">Uyumlaştırma Rengi</string>\n    <string name=\"harmonization_level\">Uyumlaştırma Seviyesi</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Piksel değerlerine bir Bessel (jinc) fonksiyonu uygulayarak yüksek kaliteli enterpolasyonu koruyan bir yeniden örnekleme yöntemi</string>\n    <string name=\"gif_type_to_jxl\">GIF\\'den JXL\\'e</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF resimlerini JXL animasyonlu resimlere dönüştürün</string>\n    <string name=\"apng_type_to_jxl\">APNG\\'den JXL\\'e</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG resimlerini JXL animasyonlu resimlere dönüştürün</string>\n    <string name=\"jxl_type_to_images\">JXL\\'den Resimlere</string>\n    <string name=\"jxl_type_to_images_sub\">JXL animasyonunu bir dizi resme dönüştürün</string>\n    <string name=\"jxl_type_to_jxl\">Resimlerden JXL\\'e</string>\n    <string name=\"jxl_type_to_jxl_sub\">Bir dizi resmi JXL animasyonuna dönüştürün</string>\n    <string name=\"behavior\">Davranış</string>\n    <string name=\"skip_file_picking\">Dosya Seçimini Atla</string>\n    <string name=\"skip_file_picking_sub\">Seçilen ekranda mümkünse dosya seçici hemen gösterilecektir</string>\n    <string name=\"generate_previews\">Önizlemeleri Oluştur</string>\n    <string name=\"generate_previews_sub\">Önizleme oluşturmayı etkinleştirir, bu bazı cihazlarda çökmeleri önlemeye yardımcı olabilir, ayrıca tekli düzenleme seçeneğinde bazı düzenleme işlevlerini devre dışı bırakır</string>\n    <string name=\"lossy_compression\">Kayıplı Sıkıştırma</string>\n    <string name=\"lossy_compression_sub\">Kayıpsız yerine dosya boyutunu azaltmak için kayıplı sıkıştırma kullanır</string>\n    <string name=\"compression_type\">Sıkıştırma Türü</string>\n    <string name=\"speed_sub\">Sonuçta ortaya çıkan resmin kod çözme hızını kontrol eder, bu, sonuç resminin daha hızlı açılmasına yardımcı olmalıdır, %1$s değeri en yavaş kod çözme anlamına gelirken, %2$s en hızlı anlamına gelir, bu ayar çıktı resminin boyutunu artırabilir</string>\n    <string name=\"sorting\">Sıralama</string>\n    <string name=\"sort_by_date\">Tarih</string>\n    <string name=\"sort_by_date_reversed\">Tarih (Ters)</string>\n    <string name=\"sort_by_name\">İsim</string>\n    <string name=\"sort_by_name_reversed\">İsim (Ters)</string>\n    <string name=\"channels_configuration\">Kanal Yapılandırması</string>\n    <string name=\"header_today\">Bugün</string>\n    <string name=\"header_yesterday\">Dün</string>\n    <string name=\"embedded_picker\">Gömülü Seçici</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox\\'ın resim seçicisi</string>\n    <string name=\"no_permissions\">İzin yok</string>\n    <string name=\"request\">Talep et</string>\n    <string name=\"pick_multiple_media\">Çoklu Medya Seç</string>\n    <string name=\"pick_single_media\">Tek Medya Seç</string>\n    <string name=\"pick\">Seç</string>\n    <string name=\"try_again\">Tekrar dene</string>\n    <string name=\"show_settings_in_landscape\">Ayarları Yatay Modda Göster</string>\n    <string name=\"show_settings_in_landscape_sub\">Bu devre dışı bırakılırsa, yatay modda ayarlar kalıcı olarak görünen bir seçenek yerine her zamanki gibi üst uygulama çubuğundaki düğmede açılır</string>\n    <string name=\"fullscreen_settings\">Tam Ekran Ayarları</string>\n    <string name=\"fullscreen_settings_sub\">Etkinleştirirseniz, ayarlar sayfası kaydırılabilir bir çekmece sayfası yerine her zaman tam ekran olarak açılır</string>\n    <string name=\"switch_type\">Anahtar Tipi</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"compose_switch_sub\">Bir Jetpack Compose Material You anahtarı</string>\n    <string name=\"material_you_switch_sub\">Bir Material You anahtarı</string>\n    <string name=\"max\">Maks</string>\n    <string name=\"resize_anchor\">Yeniden Boyutlandırma Çapası</string>\n    <string name=\"pixel_switch\">Piksel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"fluent_switch_sub\">Fluent tasarım sistemine dayalı bir anahtar</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Cupertino tasarım sistemine dayalı bir anahtar</string>\n    <string name=\"images_to_svg\">Resimleri SVG\\'ye Dönüştür</string>\n    <string name=\"images_to_svg_sub\">Verilen resimleri SVG resimlerine dönüştürün</string>\n    <string name=\"use_sampled_palette\">Örneklenmiş Palet Kullan</string>\n    <string name=\"use_sampled_palette_sub\">Bu seçenek etkinleştirilirse kuantalama paleti örneklenecektir</string>\n    <string name=\"path_omit\">Yol Atla</string>\n    <string name=\"svg_warning\">Bu aracın büyük resimleri küçültmeden izlemek için kullanılması önerilmez, çökme ve işlem süresinin artmasına neden olabilir</string>\n    <string name=\"downscale_image\">Resmi küçült</string>\n    <string name=\"downscale_image_sub\">Resim, işlemeden önce daha düşük boyutlara küçültülecektir, bu aracın daha hızlı ve daha güvenli çalışmasına yardımcı olur</string>\n    <string name=\"min_color_ratio\">Minimum Renk Oranı</string>\n    <string name=\"lines_threshold\">Çizgi Eşiği</string>\n    <string name=\"quadratic_threshold\">Kuadratik Eşik</string>\n    <string name=\"coordinates_rounding_tolerance\">Koordinat Yuvarlama Toleransı</string>\n    <string name=\"path_scale\">Yol Ölçeği</string>\n    <string name=\"reset_properties\">Özellikleri sıfırla</string>\n    <string name=\"reset_properties_sub\">Tüm özellikler varsayılan değerlere ayarlanacaktır, bu işlemin geri alınamayacağını unutmayın</string>\n    <string name=\"detailed\">Detaylı</string>\n    <string name=\"default_line_width\">Varsayılan Çizgi Genişliği</string>\n    <string name=\"engine_mode\">Motor Modu</string>\n    <string name=\"legacy\">Eski</string>\n    <string name=\"lstm_network\">LSTM ağı</string>\n    <string name=\"legacy_and_lstm\">Eski &amp; LSTM</string>\n    <string name=\"convert\">Dönüştür</string>\n    <string name=\"convert_sub\">Resim gruplarını verilen formata dönüştürün</string>\n    <string name=\"add_new_folder\">Yeni Klasör Ekle</string>\n    <string name=\"tag_bits_per_sample\">Örnek Başına Bit</string>\n    <string name=\"tag_compression\">Sıkıştırma</string>\n    <string name=\"tag_photometric_interpretation\">Fotometrik Yorumlama</string>\n    <string name=\"tag_samples_per_pixel\">Piksel Başına Örnek</string>\n    <string name=\"tag_planar_configuration\">Düzlemsel Yapılandırma</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Alt Örnekleme</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr Konumlandırma</string>\n    <string name=\"tag_x_resolution\">X Çözünürlüğü</string>\n    <string name=\"tag_y_resolution\">Y Çözünürlüğü</string>\n    <string name=\"tag_resolution_unit\">Çözünürlük Birimi</string>\n    <string name=\"tag_strip_offsets\">Şerit Ofsetleri</string>\n    <string name=\"tag_rows_per_strip\">Şerit Başına Satır</string>\n    <string name=\"tag_strip_byte_counts\">Şerit Bayt Sayıları</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG Değişim Formatı</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG Değişim Formatı Uzunluğu</string>\n    <string name=\"tag_transfer_function\">Aktarım Fonksiyonu</string>\n    <string name=\"tag_white_point\">Beyaz Nokta</string>\n    <string name=\"tag_primary_chromaticities\">Birincil Renklilikler</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr Katsayıları</string>\n    <string name=\"tag_reference_black_white\">Referans Siyah Beyaz</string>\n    <string name=\"tag_datetime\">Tarih Saat</string>\n    <string name=\"tag_image_description\">Resim Açıklaması</string>\n    <string name=\"tag_make\">Marka</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">Yazılım</string>\n    <string name=\"tag_artist\">Sanatçı</string>\n    <string name=\"tag_copyright\">Telif Hakkı</string>\n    <string name=\"tag_exif_version\">Exif Sürümü</string>\n    <string name=\"tag_flashpix_version\">Flashpix Sürümü</string>\n    <string name=\"tag_color_space\">Renk Uzayı</string>\n    <string name=\"tag_gamma\">Gama</string>\n    <string name=\"tag_pixel_x_dimension\">Piksel X Boyutu</string>\n    <string name=\"tag_pixel_y_dimension\">Piksel Y Boyutu</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Piksel Başına Sıkıştırılmış Bit</string>\n    <string name=\"tag_maker_note\">Üretici Notu</string>\n    <string name=\"tag_user_comment\">Kullanıcı Yorumu</string>\n    <string name=\"tag_related_sound_file\">İlgili Ses Dosyası</string>\n    <string name=\"tag_datetime_original\">Orijinal Tarih Saat</string>\n    <string name=\"tag_datetime_digitized\">Dijitalleştirilmiş Tarih Saat</string>\n    <string name=\"tag_offset_time\">Zaman Ofseti</string>\n    <string name=\"tag_offset_time_original\">Orijinal Zaman Ofseti</string>\n    <string name=\"tag_offset_time_digitized\">Dijitalleştirilmiş Zaman Ofseti</string>\n    <string name=\"tag_subsec_time\">Alt Saniye Zamanı</string>\n    <string name=\"tag_subsec_time_original\">Orijinal Alt Saniye Zamanı</string>\n    <string name=\"tag_subsec_time_digitized\">Dijitalleştirilmiş Alt Saniye Zamanı</string>\n    <string name=\"tag_exposure_time\">Pozlama Süresi</string>\n    <string name=\"tag_f_number\">F Numarası</string>\n    <string name=\"tag_exposure_program\">Pozlama Programı</string>\n    <string name=\"tag_spectral_sensitivity\">Spektral Hassasiyet</string>\n    <string name=\"tag_photographic_sensitivity\">Fotoğrafik Hassasiyet</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Hassasiyet Türü</string>\n    <string name=\"tag_standard_output_sensitivity\">Standart Çıkış Hassasiyeti</string>\n    <string name=\"tag_recommended_exposure_index\">Önerilen Pozlama İndeksi</string>\n    <string name=\"tag_iso_speed\">ISO Hızı</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO Hızı Enlem yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO Hızı Enlem zzz</string>\n    <string name=\"tag_shutter_speed_value\">Enstantane Hızı Değeri</string>\n    <string name=\"tag_aperture_value\">Diyafram Değeri</string>\n    <string name=\"tag_brightness_value\">Parlaklık Değeri</string>\n    <string name=\"tag_exposure_bias_value\">Pozlama Telafisi Değeri</string>\n    <string name=\"tag_max_aperture_value\">Maksimum Diyafram Değeri</string>\n    <string name=\"tag_subject_distance\">Konu Mesafesi</string>\n    <string name=\"tag_metering_mode\">Ölçüm Modu</string>\n    <string name=\"tag_flash\">Flaş</string>\n    <string name=\"tag_subject_area\">Konu Alanı</string>\n    <string name=\"tag_focal_length\">Odak Uzunluğu</string>\n    <string name=\"tag_flash_energy\">Flaş Enerjisi</string>\n    <string name=\"tag_spatial_frequency_response\">Mekansal Frekans Tepkisi</string>\n    <string name=\"tag_focal_plane_x_resolution\">Odak Düzlemi X Çözünürlüğü</string>\n    <string name=\"tag_focal_plane_y_resolution\">Odak Düzlemi Y Çözünürlüğü</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Odak Düzlemi Çözünürlük Birimi</string>\n    <string name=\"tag_subject_location\">Konu Konumu</string>\n    <string name=\"tag_exposure_index\">Pozlama İndeksi</string>\n    <string name=\"tag_sensing_method\">Algılama Yöntemi</string>\n    <string name=\"tag_file_source\">Dosya Kaynağı</string>\n    <string name=\"tag_cfa_pattern\">CFA Deseni</string>\n    <string name=\"tag_custom_rendered\">Özel İşlenmiş</string>\n    <string name=\"tag_exposure_mode\">Pozlama Modu</string>\n    <string name=\"tag_white_balance\">Beyaz Dengesi</string>\n    <string name=\"tag_digital_zoom_ratio\">Dijital Yakınlaştırma Oranı</string>\n    <string name=\"tag_focal_length_in_35mm_film\">35mm Filmdeki Odak Uzunluğu</string>\n    <string name=\"tag_scene_capture_type\">Sahne Yakalama Türü</string>\n    <string name=\"tag_gain_control\">Kazanç Kontrolü</string>\n    <string name=\"tag_contrast\">Kontrast</string>\n    <string name=\"tag_saturation\">Doygunluk</string>\n    <string name=\"tag_sharpness\">Keskinlik</string>\n    <string name=\"tag_device_setting_description\">Cihaz Ayar Açıklaması</string>\n    <string name=\"tag_subject_distance_range\">Konu Mesafe Aralığı</string>\n    <string name=\"tag_image_unique_id\">Resim Benzersiz Kimliği</string>\n    <string name=\"tag_camera_owner_name\">Kamera Sahibi Adı</string>\n    <string name=\"tag_body_serial_number\">Gövde Seri Numarası</string>\n    <string name=\"tag_lens_specification\">Lens Özellikleri</string>\n    <string name=\"tag_lens_make\">Lens Markası</string>\n    <string name=\"tag_lens_model\">Lens Modeli</string>\n    <string name=\"tag_lens_serial_number\">Lens Seri Numarası</string>\n    <string name=\"tag_gps_version_id\">GPS Sürüm Kimliği</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Enlem Referansı</string>\n    <string name=\"tag_gps_latitude\">GPS Enlem</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Boylam Referansı</string>\n    <string name=\"tag_gps_longitude\">GPS Boylam</string>\n    <string name=\"tag_gps_altitude_ref\">GPS İrtifa Referansı</string>\n    <string name=\"tag_gps_altitude\">GPS İrtifa</string>\n    <string name=\"tag_gps_timestamp\">GPS Zaman Damgası</string>\n    <string name=\"tag_gps_satellites\">GPS Uyduları</string>\n    <string name=\"tag_gps_status\">GPS Durumu</string>\n    <string name=\"tag_gps_measure_mode\">GPS Ölçüm Modu</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS Hız Referansı</string>\n    <string name=\"tag_gps_speed\">GPS Hızı</string>\n    <string name=\"tag_gps_track_ref\">GPS İz Referansı</string>\n    <string name=\"tag_gps_track\">GPS İzi</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Resim Yönü Referansı</string>\n    <string name=\"tag_gps_img_direction\">GPS Resim Yönü</string>\n    <string name=\"tag_gps_map_datum\">GPS Harita Datumu</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Hedef Enlem Referansı</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Hedef Enlem</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Hedef Boylam Referansı</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Hedef Boylam</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Hedef Kerteriz Referansı</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Hedef Kerteriz</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Hedef Mesafe Referansı</string>\n    <string name=\"tag_gps_dest_distance\">GPS Hedef Mesafe</string>\n    <string name=\"tag_gps_processing_method\">GPS İşleme Yöntemi</string>\n    <string name=\"tag_gps_area_information\">GPS Alan Bilgisi</string>\n    <string name=\"tag_gps_datestamp\">GPS Tarih Damgası</string>\n    <string name=\"tag_gps_differential\">GPS Diferansiyel</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS Y Konumlandırma Hatası</string>\n    <string name=\"tag_interoperability_index\">Birlikte Çalışabilirlik İndeksi</string>\n    <string name=\"tag_dng_version\">DNG Sürümü</string>\n    <string name=\"tag_default_crop_size\">Varsayılan Kırpma Boyutu</string>\n    <string name=\"tag_orf_preview_image_start\">Önizleme Resmi Başlangıcı</string>\n    <string name=\"tag_orf_preview_image_length\">Önizleme Resmi Uzunluğu</string>\n    <string name=\"tag_orf_aspect_frame\">En Boy Çerçevesi</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Sensör Alt Kenarlığı</string>\n    <string name=\"tag_rw2_sensor_left_border\">Sensör Sol Kenarlığı</string>\n    <string name=\"tag_rw2_sensor_right_border\">Sensör Sağ Kenarlığı</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sensör Üst Kenarlığı</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Verilen yazı tipi ve renkle yol üzerine Metin çizin</string>\n    <string name=\"font_size\">Yazı Tipi Boyutu</string>\n    <string name=\"watermark_size\">Filigran Boyutu</string>\n    <string name=\"repeat_text\">Metni Tekrarla</string>\n    <string name=\"repeat_text_sub\">Mevcut metin, tek seferlik çizim yerine yolun sonuna kadar tekrarlanacaktır</string>\n    <string name=\"dash_size\">Tire Boyutu</string>\n    <string name=\"draw_mode_image_sub\">Verilen yol boyunca çizmek için seçili resmi kullanın</string>\n    <string name=\"draw_image_sub\">Bu resim, çizilen yolun tekrar eden girişi olarak kullanılacaktır</string>\n    <string name=\"outlined_triangle_sub\">Başlangıç noktasından bitiş noktasına dış çizgili üçgen çizer</string>\n    <string name=\"triangle_sub\">Başlangıç noktasından bitiş noktasına üçgen çizer</string>\n    <string name=\"outlined_triangle\">Dış Çizgili Üçgen</string>\n    <string name=\"triangle\">Üçgen</string>\n    <string name=\"polygon_sub\">Başlangıç noktasından bitiş noktasına çokgen çizer</string>\n    <string name=\"polygon\">Çokgen</string>\n    <string name=\"outlined_polygon\">Dış Çizgili Çokgen</string>\n    <string name=\"outlined_polygon_sub\">Başlangıç noktasından bitiş noktasına dış çizgili çokgen çizer</string>\n    <string name=\"vertices\">Köşeler</string>\n    <string name=\"draw_regular_polygon\">Düzgün Çokgen Çiz</string>\n    <string name=\"draw_regular_polygon_sub\">Serbest form yerine düzgün olacak bir çokgen çizin</string>\n    <string name=\"star_sub\">Başlangıç noktasından bitiş noktasına yıldız çizer</string>\n    <string name=\"star\">Yıldız</string>\n    <string name=\"outlined_star\">Dış Çizgili Yıldız</string>\n    <string name=\"outlined_star_sub\">Başlangıç noktasından bitiş noktasına dış çizgili yıldız çizer</string>\n    <string name=\"inner_radius_ratio\">İç Yarıçap Oranı</string>\n    <string name=\"draw_regular_star\">Düzgün Yıldız Çiz</string>\n    <string name=\"draw_regular_star_sub\">Serbest form yerine düzgün olacak bir yıldız çizin</string>\n    <string name=\"antialias\">Kenar Yumuşatma</string>\n    <string name=\"antialias_sub\">Keskin kenarları önlemek için kenar yumuşatmayı etkinleştirir</string>\n    <string name=\"open_edit_instead_of_preview\">Önizleme Yerine Düzenlemeyi Aç</string>\n    <string name=\"open_edit_instead_of_preview_sub\">ImageToolbox\\'ta açmak (önizlemek) için bir resim seçtiğinizde, önizleme yerine düzenleme seçim sayfası açılacaktır</string>\n    <string name=\"document_scanner\">Belge Tarayıcı</string>\n    <string name=\"document_scanner_sub\">Belgeleri tarayın ve bunlardan PDF veya ayrı resimler oluşturun</string>\n    <string name=\"click_to_start_scanning\">Taramayı başlatmak için tıklayın</string>\n    <string name=\"start_scanning\">Taramayı Başlat</string>\n    <string name=\"save_as_pdf\">PDF Olarak Kaydet</string>\n    <string name=\"share_as_pdf\">PDF olarak paylaş</string>\n    <string name=\"options_below_is_for_images\">Aşağıdaki seçenekler PDF için değil, resimleri kaydetmek içindir</string>\n    <string name=\"equalize_histogram_hsv\">Histogram Eşitleme HSV</string>\n    <string name=\"equalize_histogram\">Histogram Eşitleme</string>\n    <string name=\"enter_percentage\">Yüzde Girin</string>\n    <string name=\"allow_enter_by_text_field\">Metin Alanı ile girişe izin ver</string>\n    <string name=\"allow_enter_by_text_field_sub\">Ön ayar seçiminin arkasında Metin Alanını etkinleştirir, böylece anında girebilirsiniz</string>\n    <string name=\"scale_color_space\">Renk Uzayını Ölçekle</string>\n    <string name=\"linear\">Doğrusal</string>\n    <string name=\"equalize_histogram_pixelation\">Histogram Eşitleme Pikselleştirme</string>\n    <string name=\"grid_size_x\">Izgara Boyutu X</string>\n    <string name=\"grid_size_y\">Izgara Boyutu Y</string>\n    <string name=\"equalize_histogram_adaptive\">Uyarlanabilir Histogram Eşitleme</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Uyarlanabilir Histogram Eşitleme LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Uyarlanabilir Histogram Eşitleme LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">İçeriğe Göre Kırp</string>\n    <string name=\"frame_color\">Çerçeve Rengi</string>\n    <string name=\"color_to_ignore\">Yoksayılacak Renk</string>\n    <string name=\"template\">Şablon</string>\n    <string name=\"no_template_filters\">Şablon filtresi eklenmemiş</string>\n    <string name=\"create_new\">Yeni Oluştur</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Taranan QR kodu geçerli bir filtre şablonu değil</string>\n    <string name=\"scan_qr_code\">QR kodu tara</string>\n    <string name=\"opened_file_have_no_filter_template\">Seçilen dosyanın filtre şablonu verisi yok</string>\n    <string name=\"create_template\">Şablon Oluştur</string>\n    <string name=\"template_name\">Şablon Adı</string>\n    <string name=\"select_template_preview\">Bu resim, bu filtre şablonunu önizlemek için kullanılacaktır</string>\n    <string name=\"template_filter\">Şablon Filtresi</string>\n    <string name=\"as_qr_code\">QR kodu resmi olarak</string>\n    <string name=\"as_file\">Dosya olarak</string>\n    <string name=\"save_as_file\">Dosya olarak kaydet</string>\n    <string name=\"save_as_qr_code_image\">QR kodu resmi olarak kaydet</string>\n    <string name=\"delete_template\">Şablonu Sil</string>\n    <string name=\"delete_template_warn\">Seçilen şablon filtresini silmek üzeresiniz. Bu işlem geri alınamaz</string>\n    <string name=\"added_filter_template\">\\\"%1$s\\\" (%2$s) adıyla filtre şablonu eklendi</string>\n    <string name=\"filter_preview\">Filtre Önizlemesi</string>\n    <string name=\"qr_code\">QR ve Barkod</string>\n    <string name=\"qr_code_sub\">QR kodunu tarayın ve içeriğini alın veya yeni bir tane oluşturmak için dizenizi yapıştırın</string>\n    <string name=\"code_content\">Kod İçeriği</string>\n    <string name=\"scan_qr_code_to_replace_content\">Alandaki içeriği değiştirmek için herhangi bir barkodu tarayın veya seçilen türle yeni bir barkod oluşturmak için bir şeyler yazın</string>\n    <string name=\"qr_description\">QR Açıklaması</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">QR kodunu taramak için ayarlardan kamera izni verin</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Belge Tarayıcıyı taramak için ayarlardan kamera izni verin</string>\n    <string name=\"cubic\">Kübik</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Kuadrik</string>\n    <string name=\"gaussian\">Gauss</string>\n    <string name=\"sphinx\">Sfenks</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Keskin</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"box\">Kutu</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Kübik enterpolasyon, en yakın 16 pikseli dikkate alarak daha pürüzsüz ölçekleme sağlar ve bilinear\\'den daha iyi sonuçlar verir</string>\n    <string name=\"bspline_sub\">Parçalı tanımlanmış polinom fonksiyonlarını kullanarak bir eğriyi veya yüzeyi pürüzsüzce enterpole eder ve yaklaştırır, esnek ve sürekli şekil temsili sağlar</string>\n    <string name=\"hamming_sub\">Sinyal işlemede spektral sızıntıyı azaltmak için bir sinyalin kenarlarını daraltan bir pencere fonksiyonu</string>\n    <string name=\"hanning_sub\">Sinyal işleme uygulamalarında spektral sızıntıyı azaltmak için yaygın olarak kullanılan Hann penceresinin bir varyantı</string>\n    <string name=\"blackman_sub\">Spektral sızıntıyı en aza indirerek iyi frekans çözünürlüğü sağlayan, sinyal işlemede sıklıkla kullanılan bir pencere fonksiyonu</string>\n    <string name=\"welch_sub\">Sinyal işleme uygulamalarında sıklıkla kullanılan, azaltılmış spektral sızıntı ile iyi frekans çözünürlüğü sağlamak için tasarlanmış bir pencere fonksiyonu</string>\n    <string name=\"quadric_sub\">Enterpolasyon için kuadratik bir fonksiyon kullanan, pürüzsüz ve sürekli sonuçlar sağlayan bir yöntem</string>\n    <string name=\"gaussian_sub\">Gauss fonksiyonu uygulayan, resimlerde gürültüyü azaltmak ve pürüzsüzleştirmek için kullanışlı bir enterpolasyon yöntemi</string>\n    <string name=\"sphinx_sub\">Minimum artefakt ile yüksek kaliteli enterpolasyon sağlayan gelişmiş bir yeniden örnekleme yöntemi</string>\n    <string name=\"bartlett_sub\">Sinyal işlemede spektral sızıntıyı azaltmak için kullanılan üçgen bir pencere fonksiyonu</string>\n    <string name=\"robidoux_sub\">Doğal resim yeniden boyutlandırması için optimize edilmiş, keskinlik ve pürüzsüzlüğü dengeleyen yüksek kaliteli bir enterpolasyon yöntemi</string>\n    <string name=\"robidoux_sharp_sub\">Net resim yeniden boyutlandırması için optimize edilmiş Robidoux yönteminin daha keskin bir varyantı</string>\n    <string name=\"spline16_sub\">16-tap filtre kullanarak pürüzsüz sonuçlar sağlayan spline tabanlı bir enterpolasyon yöntemi</string>\n    <string name=\"spline36_sub\">36-tap filtre kullanarak pürüzsüz sonuçlar sağlayan spline tabanlı bir enterpolasyon yöntemi</string>\n    <string name=\"spline64_sub\">64-tap filtre kullanarak pürüzsüz sonuçlar sağlayan spline tabanlı bir enterpolasyon yöntemi</string>\n    <string name=\"kaiser_sub\">Kaiser penceresini kullanan, ana lob genişliği ile yan lob seviyesi arasındaki denge üzerinde iyi kontrol sağlayan bir enterpolasyon yöntemi</string>\n    <string name=\"bartlett_hann_sub\">Bartlett ve Hann pencerelerini birleştiren, sinyal işlemede spektral sızıntıyı azaltmak için kullanılan hibrit bir pencere fonksiyonu</string>\n    <string name=\"box_sub\">En yakın piksel değerlerinin ortalamasını kullanan, genellikle bloklu bir görünüme neden olan basit bir yeniden örnekleme yöntemi</string>\n    <string name=\"bohman_sub\">Sinyal işleme uygulamalarında iyi frekans çözünürlüğü sağlayarak spektral sızıntıyı azaltmak için kullanılan bir pencere fonksiyonu</string>\n    <string name=\"lanczos2_sub\">Minimum artefakt ile yüksek kaliteli enterpolasyon için 2 loblu bir Lanczos filtresi kullanan bir yeniden örnekleme yöntemi</string>\n    <string name=\"lanczos3_sub\">Minimum artefakt ile yüksek kaliteli enterpolasyon için 3 loblu bir Lanczos filtresi kullanan bir yeniden örnekleme yöntemi</string>\n    <string name=\"lanczos4_sub\">Minimum artefakt ile yüksek kaliteli enterpolasyon için 4 loblu bir Lanczos filtresi kullanan bir yeniden örnekleme yöntemi</string>\n    <string name=\"lanczos2_jinc_sub\">Jinc fonksiyonunu kullanan, minimum artefakt ile yüksek kaliteli enterpolasyon sağlayan Lanczos 2 filtresinin bir varyantı</string>\n    <string name=\"lanczos3_jinc_sub\">Jinc fonksiyonunu kullanan, minimum artefakt ile yüksek kaliteli enterpolasyon sağlayan Lanczos 3 filtresinin bir varyantı</string>\n    <string name=\"lanczos4_jinc_sub\">Jinc fonksiyonunu kullanan, minimum artefakt ile yüksek kaliteli enterpolasyon sağlayan Lanczos 4 filtresinin bir varyantı</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Pürüzsüz enterpolasyon ve yeniden örnekleme için Hanning filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Yüksek kaliteli yeniden örnekleme için Robidoux filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_blackman_sub\">Zil sesini en aza indirmek için Blackman filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_quadric\">Kuadrik EWA</string>\n    <string name=\"ewa_quadric_sub\">Pürüzsüz enterpolasyon için Kuadrik filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Keskin EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Daha keskin sonuçlar için Robidoux Keskin filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Azaltılmış örtüşme ile yüksek kaliteli yeniden örnekleme için Lanczos 3 Jinc filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">Keskinlik ve pürüzsüzlük arasında iyi bir denge ile yüksek kaliteli resim işleme için tasarlanmış bir yeniden örnekleme filtresi</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Gelişmiş resim kalitesi için Ginseng filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Keskin EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Minimum artefakt ile keskin sonuçlar elde etmek için Lanczos Keskin filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 En Keskin EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Son derece keskin resim yeniden örnekleme için Lanczos 4 En Keskin filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Yumuşak EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Daha pürüzsüz resim yeniden örnekleme için Lanczos Yumuşak filtresinin Eliptik Ağırlıklı Ortalama (EWA) varyantı</string>\n    <string name=\"haasn_soft\">Haasn Yumuşak</string>\n    <string name=\"haasn_soft_sub\">Haasn tarafından pürüzsüz ve artefaktsız resim ölçekleme için tasarlanmış bir yeniden örnekleme filtresi</string>\n    <string name=\"format_conversion\">Format Dönüşümü</string>\n    <string name=\"format_conversion_sub\">Bir grup resmi bir formattan diğerine dönüştürün</string>\n    <string name=\"dismiss_forever\">Sonsuza Kadar Kapat</string>\n    <string name=\"image_stacking\">Resim Yığınlama</string>\n    <string name=\"image_stacking_sub\">Resimleri seçilen harmanlama modlarıyla üst üste yığınlayın</string>\n    <string name=\"add_image\">Resim Ekle</string>\n    <string name=\"bins_count\">Bölme sayısı</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Uyarlanabilir Histogram Eşitleme HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Uyarlanabilir Histogram Eşitleme HSV</string>\n    <string name=\"edge_mode\">Kenar Modu</string>\n    <string name=\"clip\">Kırp</string>\n    <string name=\"wrap\">Sarma</string>\n    <string name=\"color_blind_scheme\">Renk Körlüğü</string>\n    <string name=\"color_blind_scheme_sub\">Tema renklerini seçilen renk körlüğü varyantına uyarlamak için bir mod seçin</string>\n    <string name=\"protanomaly_sub\">Kırmızı ve yeşil tonlarını ayırt etmede zorluk</string>\n    <string name=\"deuteranomaly_sub\">Yeşil ve kırmızı tonlarını ayırt etmede zorluk</string>\n    <string name=\"tritanomaly_sub\">Mavi ve sarı tonlarını ayırt etmede zorluk</string>\n    <string name=\"protanopia_sub\">Kırmızı tonlarını algılayamama</string>\n    <string name=\"deuteranopia_sub\">Yeşil tonlarını algılayamama</string>\n    <string name=\"tritanopia_sub\">Mavi tonlarını algılayamama</string>\n    <string name=\"achromatomaly_sub\">Tüm renklere karşı azalmış hassasiyet</string>\n    <string name=\"achromatopsia_sub\">Tam renk körlüğü, sadece gri tonlarını görme</string>\n    <string name=\"not_use_color_blind_scheme\">Renk Körlüğü şeması kullanma</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Renkler temada ayarlandığı gibi olacaktır</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">Pürüzsüz geçişlerle yüksek kaliteli resim ölçekleme için uygun olan 2. dereceden bir Lagrange enterpolasyon filtresi</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">Daha iyi doğruluk ve daha pürüzsüz sonuçlar sunan 3. dereceden bir Lagrange enterpolasyon filtresi</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Daha keskin ve daha doğru resim ölçekleme sağlayan 6. dereceden daha yüksek bir Lanczos yeniden örnekleme filtresi</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Geliştirilmiş resim yeniden örnekleme kalitesi için Jinc fonksiyonu kullanan Lanczos 6 filtresinin bir varyantı</string>\n    <string name=\"linear_box_blur\">Doğrusal Kutu Bulanıklığı</string>\n    <string name=\"linear_tent_blur\">Doğrusal Çadır Bulanıklığı</string>\n    <string name=\"linear_gaussian_box_blur\">Doğrusal Gauss Kutu Bulanıklığı</string>\n    <string name=\"linear_stack_blur\">Doğrusal Yığın Bulanıklığı</string>\n    <string name=\"gaussian_box_blur\">Gauss Kutu Bulanıklığı</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Doğrusal Hızlı Gauss Bulanıklığı Sonraki</string>\n    <string name=\"linear_fast_gaussian_blur\">Doğrusal Hızlı Gauss Bulanıklığı</string>\n    <string name=\"linear_gaussian_blur\">Doğrusal Gauss Bulanıklığı</string>\n    <string name=\"draw_filter_sub\">Boya olarak kullanmak için bir filtre seçin</string>\n    <string name=\"replace_filter\">Filtreyi Değiştir</string>\n    <string name=\"pick_filter_info\">Çiziminizde fırça olarak kullanmak için aşağıdaki filtreyi seçin</string>\n    <string name=\"tiff_compression_scheme\">TIFF sıkıştırma şeması</string>\n    <string name=\"low_poly\">Düşük Poli</string>\n    <string name=\"sand_painting\">Kum Boyama</string>\n    <string name=\"image_splitting\">Resim Bölme</string>\n    <string name=\"image_splitting_sub\">Tek bir resmi satırlara veya sütunlara göre bölün</string>\n    <string name=\"fit_to_bounds\">Sınırlara Sığdır</string>\n    <string name=\"fit_to_bounds_sub\">İstenen davranışı elde etmek için kırpma yeniden boyutlandırma modunu bu parametreyle birleştirin (Kırp/En boy oranına sığdır)</string>\n    <string name=\"languages_imported\">Diller başarıyla içe aktarıldı</string>\n    <string name=\"backup_ocr_models\">OCR modellerini yedekle</string>\n    <string name=\"import_word\">İçe Aktar</string>\n    <string name=\"export\">Dışa Aktar</string>\n    <string name=\"position\">Konum</string>\n    <string name=\"center\">Merkez</string>\n    <string name=\"top_left\">Sol Üst</string>\n    <string name=\"top_right\">Sağ Üst</string>\n    <string name=\"bottom_left\">Sol Alt</string>\n    <string name=\"bottom_right\">Sağ Alt</string>\n    <string name=\"top_center\">Orta Üst</string>\n    <string name=\"center_right\">Orta Sağ</string>\n    <string name=\"bottom_center\">Orta Alt</string>\n    <string name=\"center_left\">Orta Sol</string>\n    <string name=\"target_image\">Hedef Resim</string>\n    <string name=\"palette_transfer\">Palet Aktarımı</string>\n    <string name=\"enhanced_oil\">Gelişmiş Yağlı Boya</string>\n    <string name=\"simple_old_tv\">Basit Eski TV</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Basit Taslak</string>\n    <string name=\"soft_glow\">Yumuşak Parıltı</string>\n    <string name=\"color_poster\">Renk Posteri</string>\n    <string name=\"tri_tone\">Üç Tonlu</string>\n    <string name=\"third_color\">Üçüncü renk</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Puantiye</string>\n    <string name=\"clustered_2x2_dithering\">Kümelenmiş 2x2 Titreşim</string>\n    <string name=\"clustered_4x4_dithering\">Kümelenmiş 4x4 Titreşim</string>\n    <string name=\"clustered_8x8_dithering\">Kümelenmiş 8x8 Titreşim</string>\n    <string name=\"yililoma_dithering\">Yililoma Titreşim</string>\n    <string name=\"no_favorite_options_selected\">Favori seçenek seçilmedi, araçlar sayfasından ekleyin</string>\n    <string name=\"add_favorites\">Favorilere Ekle</string>\n    <string name=\"harmony_complementary\">Tamamlayıcı</string>\n    <string name=\"harmony_analogous\">Analog</string>\n    <string name=\"harmony_triadic\">Üçlü</string>\n    <string name=\"harmony_split_complementary\">Ayrık Tamamlayıcı</string>\n    <string name=\"harmony_tetradic\">Dörtlü</string>\n    <string name=\"harmony_square\">Kare</string>\n    <string name=\"harmony_analogous_complementary\">Analog + Tamamlayıcı</string>\n    <string name=\"color_tools\">Renk Araçları</string>\n    <string name=\"color_tools_sub\">Karıştırın, tonlar oluşturun, gölgeler üretin ve daha fazlası</string>\n    <string name=\"color_harmonies\">Renk Uyumları</string>\n    <string name=\"color_shading\">Renk Gölgelendirme</string>\n    <string name=\"variation\">Varyasyon</string>\n    <string name=\"tints\">Açık Tonlar</string>\n    <string name=\"tones\">Tonlar</string>\n    <string name=\"shades\">Gölgeler</string>\n    <string name=\"color_mixing\">Renk Karıştırma</string>\n    <string name=\"color_info\">Renk Bilgisi</string>\n    <string name=\"selected_color\">Seçili Renk</string>\n    <string name=\"color_to_mix\">Karıştırılacak Renk</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Dinamik renkler açıkken monet kullanılamaz</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Hedef LUT resmi</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"soft_elegance\">Yumuşak Zarafet</string>\n    <string name=\"soft_elegance_variant\">Yumuşak Zarafet Varyantı</string>\n    <string name=\"palette_transfer_variant\">Palet Aktarım Varyantı</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Hedef 3D LUT Dosyası (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Ağartma Atlatma</string>\n    <string name=\"candlelight\">Mum Işığı</string>\n    <string name=\"drop_blues\">Mavileri Bırak</string>\n    <string name=\"edgy_amber\">Keskin Kehribar</string>\n    <string name=\"fall_colors\">Sonbahar Renkleri</string>\n    <string name=\"film_stock_50\">Film Stoğu 50</string>\n    <string name=\"foggy_night\">Sisli Gece</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Nötr LUT resmi al</string>\n    <string name=\"save_empty_lut_sub\">İlk olarak, favori fotoğraf düzenleme uygulamanızı kullanarak burada elde edebileceğiniz nötr LUT\\'a bir filtre uygulayın. Bunun düzgün çalışması için her piksel rengi diğer piksellere bağlı olmamalıdır (örneğin bulanıklık çalışmaz). Hazır olduğunda, yeni LUT resminizi 512*512 LUT filtresi için girdi olarak kullanın</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Selüloit</string>\n    <string name=\"coffee\">Kahve</string>\n    <string name=\"golden_forest\">Altın Orman</string>\n    <string name=\"greenish\">Yeşilimsi</string>\n    <string name=\"retro_yellow\">Retro Sarı</string>\n    <string name=\"links_preview\">Bağlantı Önizlemesi</string>\n    <string name=\"links_preview_sub\">Metin alabileceğiniz yerlerde (QRCode, OCR vb.) bağlantı önizlemesi almayı etkinleştirir</string>\n    <string name=\"links\">Bağlantılar</string>\n    <string name=\"ico_size_warning\">ICO dosyaları yalnızca maksimum 256 x 256 boyutunda kaydedilebilir</string>\n    <string name=\"gif_type_to_webp\">GIF\\'ten WEBP\\'ye</string>\n    <string name=\"gif_type_to_webp_sub\">GIF resimlerini WEBP animasyonlu resimlere dönüştürün</string>\n    <string name=\"webp_tools\">WEBP Araçları</string>\n    <string name=\"webp_tools_sub\">Resimleri WEBP animasyonlu resme dönüştürün veya verilen WEBP animasyonundan kareler ayıklayın</string>\n    <string name=\"webp_type_to_image\">WEBP\\'den resimlere</string>\n    <string name=\"webp_type_to_image_sub\">WEBP dosyasını bir dizi resme dönüştürün</string>\n    <string name=\"webp_type_to_webp_sub\">Bir dizi resmi WEBP dosyasına dönüştürün</string>\n    <string name=\"webp_type_to_webp\">Resimlerden WEBP\\'ye</string>\n    <string name=\"select_webp_image_to_start\">Başlamak için WEBP resmi seçin</string>\n    <string name=\"manage_storage_extra_types\">Dosyalara tam erişim yok</string>\n    <string name=\"manage_storage_extra_types_sub\">Android\\'de resim olarak tanınmayan JXL, QOI ve diğer resimleri görmek için tüm dosyalara erişime izin verin. İzin olmadan Image Toolbox bu resimleri gösteremez</string>\n    <string name=\"default_draw_color\">Varsayılan Çizim Rengi</string>\n    <string name=\"default_draw_path_mode\">Varsayılan Çizim Yolu Modu</string>\n    <string name=\"add_timestamp\">Zaman Damgası Ekle</string>\n    <string name=\"add_timestamp_sub\">Çıktı dosya adına Zaman Damgası eklemeyi etkinleştirir</string>\n    <string name=\"formatted_timestamp\">Biçimlendirilmiş Zaman Damgası</string>\n    <string name=\"formatted_timestamp_sub\">Temel milisaniye yerine çıktı dosya adında Zaman Damgası biçimlendirmesini etkinleştir</string>\n    <string name=\"enable_timestamps_to_format_them\">Biçimlerini seçmek için Zaman Damgalarını etkinleştirin</string>\n    <string name=\"one_time_save_location\">Tek Seferlik Kayıt Konumu</string>\n    <string name=\"one_time_save_location_sub\">Çoğu seçenekte kaydet düğmesine uzun basarak kullanabileceğiniz tek seferlik kayıt konumlarını görüntüleyin ve düzenleyin</string>\n    <string name=\"recently_used\">Son Kullanılanlar</string>\n    <string name=\"ci_channel\">CI kanalı</string>\n    <string name=\"group\">Grup</string>\n    <string name=\"image_toolbox_in_telegram\">Telegram\\'da Image Toolbox 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">İstediğiniz her şeyi tartışabileceğiniz sohbetimize katılın ve ayrıca betaları ve duyuruları yayınladığım CI kanalına göz atın</string>\n    <string name=\"ci_channel_sub\">Uygulamanın yeni sürümleri hakkında bildirim alın ve duyuruları okuyun</string>\n    <string name=\"fit_description\">Bir resmi verilen boyutlara sığdırın ve arka plana bulanıklık veya renk uygulayın</string>\n    <string name=\"tools_arrangement\">Araçların Düzenlenmesi</string>\n    <string name=\"group_tools_by_type\">Araçları türe göre gruplandır</string>\n    <string name=\"group_tools_by_type_sub\">Ana ekrandaki araçları özel bir liste düzenlemesi yerine türlerine göre gruplandırır</string>\n    <string name=\"default_values\">Varsayılan Değerler</string>\n    <string name=\"system_bars_visibility\">Sistem Çubukları Görünürlüğü</string>\n    <string name=\"show_system_bars_by_swipe\">Kaydırarak Sistem Çubuklarını Göster</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Gizliyse sistem çubuklarını göstermek için kaydırmayı etkinleştirir</string>\n    <string name=\"auto\">Otomatik</string>\n    <string name=\"hide_all\">Tümünü Gizle</string>\n    <string name=\"show_all\">Tümünü Göster</string>\n    <string name=\"hide_nav_bar\">Gezinme Çubuğunu Gizle</string>\n    <string name=\"hide_status_bar\">Durum Çubuğunu Gizle</string>\n    <string name=\"noise_generation\">Gürültü Üretimi</string>\n    <string name=\"noise_generation_sub\">Perlin veya diğer türler gibi farklı gürültüler üretin</string>\n    <string name=\"frequency\">Frekans</string>\n    <string name=\"noise_type\">Gürültü Türü</string>\n    <string name=\"rotation_type\">Döndürme Türü</string>\n    <string name=\"fractal_type\">Fraktal Türü</string>\n    <string name=\"octaves\">Oktavlar</string>\n    <string name=\"lacunarity\">Boşlukluluk</string>\n    <string name=\"gain\">Kazanç</string>\n    <string name=\"weighted_strength\">Ağırlıklı Güç</string>\n    <string name=\"ping_pong_strength\">Ping Pong Gücü</string>\n    <string name=\"distance_function\">Mesafe Fonksiyonu</string>\n    <string name=\"return_type\">Dönüş Türü</string>\n    <string name=\"jitter\">Titreklik</string>\n    <string name=\"domain_warp\">Alan Bükme</string>\n    <string name=\"alignment\">Hizalama</string>\n    <string name=\"custom_filename\">Özel Dosya Adı</string>\n    <string name=\"custom_filename_sub\">Geçerli resmi kaydetmek için kullanılacak konumu ve dosya adını seçin</string>\n    <string name=\"saved_to_custom\">Özel adla klasöre kaydedildi</string>\n    <string name=\"collage_maker\">Kolaj Oluşturucu</string>\n    <string name=\"collage_maker_sub\">20 resme kadar kolaj yapın</string>\n    <string name=\"collage_type\">Kolaj Türü</string>\n    <string name=\"collages_info\">Değiştirmek için resmi basılı tutun, konumu ayarlamak için taşıyın ve yakınlaştırın</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">Ayarlamalar yapmanıza yardımcı olacak RGB veya Parlaklık resim histogramı</string>\n    <string name=\"image_for_histogram\">Bu resim, RGB ve Parlaklık histogramları oluşturmak için kullanılacaktır</string>\n    <string name=\"tesseract_options\">Tesseract Seçenekleri</string>\n    <string name=\"tesseract_options_sub\">Tesseract motoru için bazı girdi değişkenleri uygulayın</string>\n    <string name=\"custom_options\">Özel Seçenekler</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">Seçenekler şu desene göre girilmelidir: \\\"--{seçenek_adı} {değer}\\\"</string>\n    <string name=\"auto_crop\">Otomatik Kırp</string>\n    <string name=\"free_corners\">Serbest Köşeler</string>\n    <string name=\"free_corners_sub\">Resmi çokgen ile kırpın, bu ayrıca perspektifi de düzeltir</string>\n    <string name=\"coerce_points_to_image_bounds\">Noktaları Resim Sınırlarına Zorla</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Noktalar resim sınırlarıyla sınırlı olmayacaktır, bu daha hassas perspektif düzeltme için kullanışlıdır</string>\n    <string name=\"mask\">Maske</string>\n    <string name=\"spot_heal_sub\">Çizilen yolun altında içeriğe duyarlı doldurma</string>\n    <string name=\"spot_heal\">Noktayı İyileştir</string>\n    <string name=\"use_circle_kernel\">Daire Çekirdeği Kullan</string>\n    <string name=\"opening\">Açma</string>\n    <string name=\"closing\">Kapama</string>\n    <string name=\"morphological_gradient\">Morfolojik Gradyan</string>\n    <string name=\"top_hat\">Üst Şapka</string>\n    <string name=\"black_hat\">Siyah Şapka</string>\n    <string name=\"tone_curves\">Ton Eğrileri</string>\n    <string name=\"reset_curves\">Eğrileri Sıfırla</string>\n    <string name=\"reset_curves_sub\">Eğriler varsayılan değere geri döndürülecektir</string>\n    <string name=\"line_style\">Çizgi Stili</string>\n    <string name=\"gap_size\">Boşluk Boyutu</string>\n    <string name=\"dashed\">Kesikli</string>\n    <string name=\"dot_dashed\">Noktalı Kesikli</string>\n    <string name=\"stamped\">Damgalı</string>\n    <string name=\"zigzag\">Zikzak</string>\n    <string name=\"dashed_sub\">Belirtilen boşluk boyutuyla çizilen yol boyunca kesikli çizgi çizer</string>\n    <string name=\"dot_dashed_sub\">Verilen yol boyunca noktalı ve kesikli çizgi çizer</string>\n    <string name=\"defaultt_sub\">Sadece varsayılan düz çizgiler</string>\n    <string name=\"stamped_sub\">Belirtilen aralıklarla yol boyunca seçilen şekilleri çizer</string>\n    <string name=\"zigzag_sub\">Yol boyunca dalgalı zikzak çizer</string>\n    <string name=\"zigzag_ratio\">Zikzak oranı</string>\n    <string name=\"create_shortcut\">Kısayol Oluştur</string>\n    <string name=\"create_shortcut_title\">Sabitlenecek aracı seçin</string>\n    <string name=\"create_shortcut_subtitle\">Araç, başlatıcınızın ana ekranına kısayol olarak eklenecektir, istenen davranışı elde etmek için \\\"Dosya seçimini atla\\\" ayarıyla birlikte kullanın</string>\n    <string name=\"dont_stack_frames\">Kareleri yığma</string>\n    <string name=\"dont_stack_frames_sub\">Önceki karelerin atılmasını sağlar, böylece birbirlerinin üzerine yığılmazlar</string>\n    <string name=\"crossfade\">Çapraz Geçiş</string>\n    <string name=\"crossfade_sub\">Kareler birbirine çapraz geçiş yapacak</string>\n    <string name=\"crossfade_count\">Çapraz geçiş kare sayısı</string>\n    <string name=\"threshold_one\">Eşik Bir</string>\n    <string name=\"threshold_two\">Eşik İki</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Ayna 101</string>\n    <string name=\"enhanced_zoom_blur\">Gelişmiş Yakınlaştırma Bulanıklığı</string>\n    <string name=\"laplacian_simple\">Laplacian Basit</string>\n    <string name=\"sobel_simple\">Sobel Basit</string>\n    <string name=\"helper_grid\">Yardımcı Izgara</string>\n    <string name=\"helper_grid_sub\">Hassas manipülasyonlara yardımcı olmak için çizim alanının üzerinde destekleyici bir ızgara gösterir</string>\n    <string name=\"grid_color\">Izgara Rengi</string>\n    <string name=\"cell_width\">Hücre Genişliği</string>\n    <string name=\"cell_height\">Hücre Yüksekliği</string>\n    <string name=\"compact_selectors\">Kompakt Seçiciler</string>\n    <string name=\"compact_selectors_sub\">Bazı seçim kontrolleri daha az yer kaplamak için kompakt bir düzen kullanacaktır</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Resim çekmek için ayarlardan kamera izni verin</string>\n    <string name=\"layout\">Düzen</string>\n    <string name=\"main_screen_title\">Ana Ekran Başlığı</string>\n    <string name=\"constant_rate_factor\">Sabit Oran Faktörü (CRF)</string>\n    <string name=\"crf_sub\">%1$s değeri yavaş bir sıkıştırma anlamına gelir ve nispeten küçük bir dosya boyutuyla sonuçlanır. %2$s daha hızlı bir sıkıştırma anlamına gelir ve büyük bir dosyayla sonuçlanır.</string>\n    <string name=\"lut_library\">Lut Kütüphanesi</string>\n    <string name=\"lut_library_sub\">İndirdikten sonra uygulayabileceğiniz LUT koleksiyonunu indirin</string>\n    <string name=\"lut_library_update_sub\">İndirdikten sonra uygulayabileceğiniz LUT koleksiyonunu güncelleyin (sadece yeniler sıraya alınacaktır)</string>\n    <string name=\"filter_preview_image_sub\">Filtreler için varsayılan resim önizlemesini değiştirin</string>\n    <string name=\"filter_preview_image\">Önizleme Resmi</string>\n    <string name=\"hide\">Gizle</string>\n    <string name=\"show\">Göster</string>\n    <string name=\"slider_type\">Kaydırıcı Tipi</string>\n    <string name=\"fancy\">Süslü</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy_sub\">Süslü görünümlü bir kaydırıcı. Bu varsayılan seçenektir</string>\n    <string name=\"material_2_sub\">Bir Material 2 kaydırıcısı</string>\n    <string name=\"material_you_slider_sub\">Bir Material You kaydırıcısı</string>\n    <string name=\"apply\">Uygula</string>\n    <string name=\"center_align_dialog_buttons\">Diyalog Düğmelerini Ortala</string>\n    <string name=\"center_align_dialog_buttons_sub\">Diyalogların düğmeleri mümkünse sol taraf yerine merkezde konumlandırılacaktır</string>\n    <string name=\"open_source_licenses\">Açık Kaynak Lisansları</string>\n    <string name=\"open_source_licenses_sub\">Bu uygulamada kullanılan açık kaynaklı kütüphanelerin lisanslarını görüntüleyin</string>\n    <string name=\"area\">Alan</string>\n    <string name=\"area_sub\">Piksel alan ilişkisi kullanarak yeniden örnekleme. Moire içermeyen sonuçlar verdiği için resim küçültme için tercih edilen bir yöntem olabilir. Ancak resim yakınlaştırıldığında, En Yakın yöntemine benzer.</string>\n    <string name=\"enable_tonemapping\">Ton Eşlemeyi Etkinleştir</string>\n    <string name=\"enter_percent\">Yüzde Gir</string>\n    <string name=\"unknown_host\">Siteye erişilemiyor, VPN kullanmayı veya URL\\'nin doğru olup olmadığını kontrol etmeyi deneyin</string>\n    <string name=\"markup_layers\">İşaretleme Katmanları</string>\n    <string name=\"markup_layers_sub\">Resimleri, metinleri ve daha fazlasını serbestçe yerleştirme yeteneğine sahip katmanlar modu</string>\n    <string name=\"edit_layer\">Katmanı düzenle</string>\n    <string name=\"layers_on_image\">Resim üzerindeki katmanlar</string>\n    <string name=\"layers_on_image_sub\">Arka plan olarak bir resim kullanın ve üzerine farklı katmanlar ekleyin</string>\n    <string name=\"layers_on_background\">Arka plan üzerindeki katmanlar</string>\n    <string name=\"layers_on_background_sub\">İlk seçenekle aynı ama resim yerine renkle</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">Hızlı Ayarlar Tarafı</string>\n    <string name=\"fast_settings_side_sub\">Resimleri düzenlerken seçilen tarafa, tıklandığında hızlı ayarları açacak bir kayan şerit ekleyin</string>\n    <string name=\"clear_selection\">Seçimi temizle</string>\n    <string name=\"settings_group_visibility_hidden\">\\\"%1$s\\\" ayar grubu varsayılan olarak daraltılmış olacaktır</string>\n    <string name=\"settings_group_visibility_visible\">\\\"%1$s\\\" ayar grubu varsayılan olarak genişletilmiş olacaktır</string>\n    <string name=\"base_64_tools\">Base64 Araçları</string>\n    <string name=\"base_64_tools_sub\">Base64 dizesini resme çözün veya resmi Base64 formatına kodlayın</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">Sağlanan değer geçerli bir Base64 dizesi değil</string>\n    <string name=\"copy_not_a_valid_base_64\">Boş veya geçersiz Base64 dizesi kopyalanamaz</string>\n    <string name=\"paste_base_64\">Base64 Yapıştır</string>\n    <string name=\"copy_base_64\">Base64 Kopyala</string>\n    <string name=\"base_64_tips\">Base64 dizesini kopyalamak veya kaydetmek için resim yükleyin. Dizenin kendisi varsa, resmi elde etmek için yukarıya yapıştırabilirsiniz</string>\n    <string name=\"save_base_64\">Base64 Kaydet</string>\n    <string name=\"share_base_64\">Base64 Paylaş</string>\n    <string name=\"options\">Seçenekler</string>\n    <string name=\"actions\">Eylemler</string>\n    <string name=\"import_base_64\">Base64 İçe Aktar</string>\n    <string name=\"base_64_actions\">Base64 Eylemleri</string>\n    <string name=\"add_outline\">Dış Çizgi Ekle</string>\n    <string name=\"add_outline_sub\">Metnin etrafına belirtilen renk ve genişlikte bir dış çizgi ekleyin</string>\n    <string name=\"outline_color\">Dış Çizgi Rengi</string>\n    <string name=\"outline_size\">Dış Çizgi Boyutu</string>\n    <string name=\"rotation\">Döndürme</string>\n    <string name=\"checksum_as_filename\">Dosya Adı Olarak Sağlama Toplamı</string>\n    <string name=\"checksum_as_filename_sub\">Çıktı resimleri, veri sağlama toplamlarına karşılık gelen bir ada sahip olacaktır</string>\n    <string name=\"free_software_partner\">Özgür Yazılım (Ortak)</string>\n    <string name=\"free_software_partner_sub\">Android uygulamalarının ortak kanalında daha fazla kullanışlı yazılım</string>\n    <string name=\"algorithms\">Algoritma</string>\n    <string name=\"checksum_tools\">Sağlama Toplamı Araçları</string>\n    <string name=\"checksum_tools_sub\">Sağlama toplamlarını karşılaştırın, hash hesaplayın veya farklı hash algoritmaları kullanarak dosyalardan hex dizeleri oluşturun</string>\n    <string name=\"calculate\">Hesapla</string>\n    <string name=\"text_hash\">Metin Hash</string>\n    <string name=\"checksum\">Sağlama Toplamı</string>\n    <string name=\"pick_file_to_checksum\">Seçilen algoritmaya göre sağlama toplamını hesaplamak için bir dosya seçin</string>\n    <string name=\"enter_text_to_checksum\">Seçilen algoritmaya göre sağlama toplamını hesaplamak için metin girin</string>\n    <string name=\"source_checksum\">Kaynak Sağlama Toplamı</string>\n    <string name=\"checksum_to_compare\">Karşılaştırılacak Sağlama Toplamı</string>\n    <string name=\"match\">Eşleşti!</string>\n    <string name=\"difference\">Farklılık</string>\n    <string name=\"match_sub\">Sağlama toplamları eşit, güvenli olabilir</string>\n    <string name=\"difference_sub\">Sağlama toplamları eşit değil, dosya güvensiz olabilir!</string>\n    <string name=\"mesh_gradients\">Ağ Gradyanları</string>\n    <string name=\"collection_mesh_gradients_sub\">Ağ Gradyanlarının çevrimiçi koleksiyonuna bakın</string>\n    <string name=\"wrong_font\">Yalnızca TTF ve OTF yazı tipleri içe aktarılabilir</string>\n    <string name=\"import_font\">Yazı tipi içe aktar (TTF/OTF)</string>\n    <string name=\"export_fonts\">Yazı tiplerini dışa aktar</string>\n    <string name=\"imported_fonts\">İçe aktarılan yazı tipleri</string>\n    <string name=\"error_while_saving\">Kaydetme denemesi sırasında hata, çıktı klasörünü değiştirmeyi deneyin</string>\n    <string name=\"filename_is_not_set\">Dosya adı ayarlanmadı</string>\n    <string name=\"none\">Hiçbiri</string>\n    <string name=\"custom_pages\">Özel Sayfalar</string>\n    <string name=\"pages_selection\">Sayfa Seçimi</string>\n    <string name=\"tool_exit_confirmation\">Araçtan Çıkış Onayı</string>\n    <string name=\"tool_exit_confirmation_sub\">Belirli araçları kullanırken kaydedilmemiş değişiklikleriniz varsa ve kapatmaya çalışırsanız, onay iletişim kutusu gösterilecektir</string>\n    <string name=\"edit_exif_screen\">EXIF Düzenle</string>\n    <string name=\"edit_exif_screen_sub\">Tek bir resmin meta verilerini yeniden sıkıştırma olmadan değiştirin</string>\n    <string name=\"edit_exif_tag\">Mevcut etiketleri düzenlemek için dokunun</string>\n    <string name=\"change_sticker\">Çıkartmayı Değiştir</string>\n    <string name=\"fit_width\">Genişliğe Sığdır</string>\n    <string name=\"fit_height\">Yüksekliğe Sığdır</string>\n    <string name=\"batch_compare\">Toplu Karşılaştırma</string>\n    <string name=\"pick_files_to_checksum\">Seçilen algoritmaya göre sağlama toplamını hesaplamak için dosya/dosyalar seçin</string>\n    <string name=\"pick_files\">Dosyaları Seç</string>\n    <string name=\"pick_directory\">Dizin Seç</string>\n    <string name=\"head_length_scale\">Baş Uzunluğu Ölçeği</string>\n    <string name=\"stamp\">Damga</string>\n    <string name=\"timestamp\">Zaman Damgası</string>\n    <string name=\"format_pattern\">Format Deseni</string>\n    <string name=\"padding\">İç boşluk</string>\n    <string name=\"image_cutting\">Resim Kesme</string>\n    <string name=\"image_cutting_sub\">Resim parçasını kesin ve kalanları dikey veya yatay çizgilerle birleştirin (tersi de olabilir)</string>\n    <string name=\"vertical_pivot_line\">Dikey Eksen Çizgisi</string>\n    <string name=\"horizontal_pivot_line\">Yatay Eksen Çizgisi</string>\n    <string name=\"inverse_selection\">Ters Seçim</string>\n    <string name=\"inverse_vertical_selection_sub\">Dikey kesim parçası, kesim alanı etrafındaki parçaları birleştirmek yerine bırakılacaktır</string>\n    <string name=\"inverse_horizontal_selection_sub\">Yatay kesim parçası, kesim alanı etrafındaki parçaları birleştirmek yerine bırakılacaktır</string>\n    <string name=\"collection_mesh_gradients\">Ağ Gradyanları Koleksiyonu</string>\n    <string name=\"mesh_gradients_sub\">Özel düğüm sayısı ve çözünürlük ile ağ gradyanı oluşturun</string>\n    <string name=\"gradient_maker_type_image_mesh\">Ağ Gradyanı Kaplaması</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Verilen resimlerin üzerine ağ gradyanı oluşturun</string>\n    <string name=\"points_customization\">Nokta Özelleştirme</string>\n    <string name=\"grid_size\">Izgara Boyutu</string>\n    <string name=\"resolution_x\">Çözünürlük X</string>\n    <string name=\"resolution_y\">Çözünürlük Y</string>\n    <string name=\"resolution\">Çözünürlük</string>\n    <string name=\"pixel_by_pixel\">Piksel Piksel</string>\n    <string name=\"highlight_color\">Vurgu Rengi</string>\n    <string name=\"pixel_comparison_type\">Piksel Karşılaştırma Türü</string>\n    <string name=\"scan_barcode\">Barkod tara</string>\n    <string name=\"height_ratio\">Yükseklik Oranı</string>\n    <string name=\"barcode_type\">Barkod Türü</string>\n    <string name=\"enforce_bw\">S/B Zorla</string>\n    <string name=\"enforce_bw_sub\">Barkod Resmi tamamen siyah beyaz olacak ve uygulamanın temasıyla renklendirilmeyecek</string>\n    <string name=\"barcodes_sub\">Herhangi bir Barkodu (QR, EAN, AZTEC, …) tarayın ve içeriğini alın veya yeni bir tane oluşturmak için metninizi yapıştırın</string>\n    <string name=\"no_barcode_found\">Barkod Bulunamadı</string>\n    <string name=\"generated_barcode_will_be_here\">Oluşturulan Barkod Burada Olacak</string>\n    <string name=\"audio_cover_extractor\">Ses Kapakları</string>\n    <string name=\"audio_cover_extractor_sub\">Ses dosyalarından albüm kapağı resimlerini ayıklayın, en yaygın formatlar desteklenir</string>\n    <string name=\"pick_audio_to_start\">Başlamak için bir ses seçin</string>\n    <string name=\"pick_audio\">Ses Seç</string>\n    <string name=\"no_covers_found\">Kapak Bulunamadı</string>\n    <string name=\"send_logs\">Günlükleri Gönder</string>\n    <string name=\"send_logs_sub\">Uygulama günlükleri dosyasını paylaşmak için tıklayın, bu sorunu tespit etmeme ve sorunları çözmeme yardımcı olabilir</string>\n    <string name=\"crash_title\">Hay aksi… Bir şeyler ters gitti</string>\n    <string name=\"crash_subtitle\">Aşağıdaki seçenekleri kullanarak benimle iletişime geçebilirsiniz ve bir çözüm bulmaya çalışacağım.\\n(Günlükleri eklemeyi unutmayın)</string>\n    <string name=\"ocr_write_to_file\">Dosyaya Yaz</string>\n    <string name=\"ocr_write_to_file_sub\">Bir grup resimden metin ayıklayın ve tek bir metin dosyasında saklayın</string>\n    <string name=\"ocr_write_to_metadata\">Meta Veriye Yaz</string>\n    <string name=\"ocr_write_to_metadata_sub\">Her resimden metin ayıklayın ve ilgili fotoğrafların EXIF bilgisine yerleştirin</string>\n    <string name=\"invisible_mode\">Görünmez Mod</string>\n    <string name=\"invisible_mode_sub\">Resimlerinizin baytları içinde gözle görünmeyen filigranlar oluşturmak için steganografi kullanın</string>\n    <string name=\"use_lsb\">LSB kullan</string>\n    <string name=\"use_lsb_sub\">LSB (En Az Anlamlı Bit) steganografi yöntemi kullanılacaktır, aksi takdirde FD (Frekans Alanı)</string>\n    <string name=\"auto_remove_red_eyes\">Kırmızı Gözleri Otomatik Kaldır</string>\n    <string name=\"password\">Parola</string>\n    <string name=\"unlock\">Kilidi Aç</string>\n    <string name=\"pdf_is_protected\">PDF korumalı</string>\n    <string name=\"operation_almost_complete\">İşlem neredeyse tamamlandı. Şimdi iptal etmek yeniden başlatmayı gerektirecektir</string>\n    <string name=\"sort_by_date_modified\">Değiştirilme Tarihi</string>\n    <string name=\"sort_by_date_modified_reversed\">Değiştirilme Tarihi (Ters)</string>\n    <string name=\"sort_by_size\">Boyut</string>\n    <string name=\"sort_by_size_reversed\">Boyut (Ters)</string>\n    <string name=\"sort_by_mime_type\">MIME Türü</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME Türü (Ters)</string>\n    <string name=\"sort_by_extension\">Uzantı</string>\n    <string name=\"sort_by_extension_reversed\">Uzantı (Ters)</string>\n    <string name=\"sort_by_date_added\">Eklenme Tarihi</string>\n    <string name=\"sort_by_date_added_reversed\">Eklenme Tarihi (Ters)</string>\n    <string name=\"left_to_right\">Soldan Sağa</string>\n    <string name=\"right_to_left\">Sağdan Sola</string>\n    <string name=\"top_to_bottom\">Yukarıdan Aşağıya</string>\n    <string name=\"bottom_to_top\">Aşağıdan Yukarıya</string>\n    <string name=\"liquid_glass\">Sıvı Cam</string>\n    <string name=\"liquid_glass_sub\">Yakın zamanda duyurulan IOS 26 ve onun sıvı cam tasarım sistemine dayalı bir anahtar</string>\n    <string name=\"pick_image_or_base64\">Bir resim seçin veya aşağıya Base64 verisi yapıştırın/içe aktarın</string>\n    <string name=\"type_image_link\">Başlamak için resim bağlantısı yazın</string>\n    <string name=\"paste_link\">Bağlantıyı yapıştır</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s renk</item>\n        <item quantity=\"other\">%1$s renk</item>\n    </plurals>\n    <string name=\"disable_rotation\">Dönmeyi kapat</string>\n    <string name=\"disable_rotation_sub\">İki parmak hareketiyle görüntülerin dönmesini engeller</string>\n    <string name=\"enable_snapping_to_borders\">Kenarlara yapıştırmayı etkinleştir</string>\n    <string name=\"enable_snapping_to_borders_sub\">Taşıma veya yakınlaştırmadan sonra görüntüler çerçeve kenarlarını doldurmak için otomatik olarak yerleştirilir</string>\n    <string name=\"kaleidoscope\">Kaleydoskop</string>\n    <string name=\"secondary_angle\">İkincil açı</string>\n    <string name=\"sides\">Yanlar</string>\n    <string name=\"channel_mix\">Kanal Karışımı</string>\n    <string name=\"blue_green\">Mavi yeşil</string>\n    <string name=\"red_blue\">Kırmızı mavi</string>\n    <string name=\"green_red\">Yeşil kırmızı</string>\n    <string name=\"into_red\">Kırmızıya</string>\n    <string name=\"into_green\">Yeşile</string>\n    <string name=\"into_blue\">Maviye</string>\n    <string name=\"cyan\">Camgöbeği</string>\n    <string name=\"magenta\">Eflatun</string>\n    <string name=\"yellow\">Sarı</string>\n    <string name=\"color_halftone\">Renkli Yarım Ton</string>\n    <string name=\"contour\">Kontur</string>\n    <string name=\"levels\">Seviyeler</string>\n    <string name=\"offset\">Çıkıntı</string>\n    <string name=\"voronoi_crystallize\">Voronoi Kristalleştirme</string>\n    <string name=\"shape\">Şekil</string>\n    <string name=\"stretch\">Esnetme</string>\n    <string name=\"randomness\">Rastgelelik</string>\n    <string name=\"despeckle\">Kusurları gider</string>\n    <string name=\"diffuse\">Dağıt</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">İkinci yarıçap</string>\n    <string name=\"equalize\">Eşitle</string>\n    <string name=\"glow\">Parıltı</string>\n    <string name=\"whirl_and_pinch\">Döndür ve Sıkıştır</string>\n    <string name=\"pointillize\">Noktalama</string>\n    <string name=\"border_color\">Kenar rengi</string>\n    <string name=\"polar_coordinates\">Kutup Koordinatları</string>\n    <string name=\"rect_to_polar\">Dikden kutupa</string>\n    <string name=\"polar_to_rect\">Kutupdan dike</string>\n    <string name=\"invert_in_circle\">Dairede ters çevir</string>\n    <string name=\"reduce_noise\">Gürültüyü Azalt</string>\n    <string name=\"simple_solarize\">Basit Soluluk</string>\n    <string name=\"weave\">Dokuma</string>\n    <string name=\"x_gap\">X Boşluğu</string>\n    <string name=\"y_gap\">Y Boşluğu</string>\n    <string name=\"x_width\">X Eni</string>\n    <string name=\"y_wdth\">Y Eni</string>\n    <string name=\"twirl\">Döndür</string>\n    <string name=\"rubber_stmp\">Istampa</string>\n    <string name=\"smear\">Karala</string>\n    <string name=\"density\">Yoğunluk</string>\n    <string name=\"mix\">Karışım</string>\n    <string name=\"sphere_lensh_distortion\">Küre Lens Bozulması</string>\n    <string name=\"refraction_index\">Kırılım indisi</string>\n    <string name=\"arc\">Ark</string>\n    <string name=\"spread_angle\">Yayılma açısı</string>\n    <string name=\"sparkle\">Işıltı</string>\n    <string name=\"rays\">Işınlar</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradyan</string>\n    <string name=\"moire\">Hare</string>\n    <string name=\"autumn\">Sonbahar</string>\n    <string name=\"bone\">Kemik</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">Kış</string>\n    <string name=\"ocean\">Okyanus</string>\n    <string name=\"summer\">Yaz</string>\n    <string name=\"spring\">İlkbahar</string>\n    <string name=\"cool_variant\">Serin Varyant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Pembe</string>\n    <string name=\"hot\">Sıcak</string>\n    <string name=\"parula\">Parula</string>\n    <string name=\"magma\">Mağma</string>\n    <string name=\"inferno\">Aşırı ısı</string>\n    <string name=\"plasma\">Plazma</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">Çivit mavisi</string>\n    <string name=\"twilight\">Alacakaranlık</string>\n    <string name=\"twilight_shifted\">Alacakaranlık kayması</string>\n    <string name=\"auto_perspective\">Oto Perspektif</string>\n    <string name=\"deskew\">Perspektif Düzeltme</string>\n    <string name=\"allow_crop\">Kırpmaya izin ver</string>\n    <string name=\"crop_or_perspective\">Kırpma veya Perspektif</string>\n    <string name=\"absolute\">Mutlak</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Derin Yeşil</string>\n    <string name=\"lens_correction\">Lens Düzeltme</string>\n    <string name=\"target_lens_profile\">JSON formatında hedef lens profili dosyası</string>\n    <string name=\"download_ready_lens_profiles\">Hazır lens profillerini indirin</string>\n    <string name=\"part_percents\">Parça yüzdeleri</string>\n    <string name=\"export_as_json\">JSON olarak dışarı aktar</string>\n    <string name=\"export_as_json_sub\">Palet verisini JSON olarak kopyala</string>\n    <string name=\"seam_carving\">Akıllı Ölçeklendirme</string>\n    <string name=\"home_screen\">Ana Ekran</string>\n    <string name=\"lock_screen\">Kilit Ekranı</string>\n    <string name=\"built_in\">Dahili</string>\n    <string name=\"wallpapers_export\">Duvar Kağıtları Dışa Aktar</string>\n    <string name=\"refresh\">Yenile</string>\n    <string name=\"wallpapers_export_sub\">Güncel Ana Sayfa, Kilit ve dahili duvar kağıtlarını edinin</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Tüm dosyalara erişim izni verin, bu duvar kağıtlarını almak için gereklidir.</string>\n    <string name=\"allow_read_media_images_for_wp\">Harici depolama iznini yönetmek yeterli değildir, resimlerinize erişime izin vermeniz gerekir, \\\"Tümüne izin ver\\\" seçeneğini seçtiğinizden emin olun.</string>\n    <string name=\"add_preset_to_filename\">Dosya Adına Ön Ayarı Ekle</string>\n    <string name=\"add_preset_to_filename_sub\">Seçilen ön ayar ile son eki görüntü dosya adına ekler</string>\n    <string name=\"add_image_scale_mode_to_filename\">Dosya Adına Görüntü Ölçek Modunu Ekle</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Seçilen görüntü ölçekleme modunu görüntü dosya adına son ek olarak ekler</string>\n    <string name=\"ascii_art\">ASCII Sanatı</string>\n    <string name=\"ascii_art_sub\">Resmi, görüntü gibi görünecek ASCII metnine dönüştür</string>\n    <string name=\"params\">Parametreler</string>\n    <string name=\"invert_colors_ascii_sub\">Bazı durumlarda daha iyi sonuç elde etmek için görüntüye negatif filtre uygular.</string>\n    <string name=\"processing_screenshot\">Ekran görüntüsü işleniyor</string>\n    <string name=\"screenshot_not_captured_try_again\">Ekran görüntüsü yakalanamadı, tekrar deneyin</string>\n    <string name=\"skipped_saving\">Kaydedilme atlandı</string>\n    <string name=\"skipped_saving_multiple\">%1$s dosya atlandı</string>\n    <string name=\"allow_skip_if_larger\">Eğer Büyükse Atlamaya İzin Ver</string>\n    <string name=\"allow_skip_if_larger_sub\">Bazı araçlar, sonuçta ortaya çıkan dosya boyutu orijinalinden daha büyük olacaksa görüntüleri kaydetmeyi atlayabilir.</string>\n    <string name=\"qr_type_calendar_event\">Takvim Etkinliği</string>\n    <string name=\"qr_type_contact_info\">İletişim</string>\n    <string name=\"qr_type_email\">Eposta</string>\n    <string name=\"qr_type_geo_point\">Konum</string>\n    <string name=\"qr_type_phone\">Telefon</string>\n    <string name=\"qr_type_plain\">Yazı</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Ağı aç</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Telefon</string>\n    <string name=\"message\">Mesaj</string>\n    <string name=\"address\">Adres</string>\n    <string name=\"subject\">Konu</string>\n    <string name=\"body\">Gövde</string>\n    <string name=\"name\">İsim</string>\n    <string name=\"organization\">Organizasyon</string>\n    <string name=\"title\">Başlık</string>\n    <string name=\"phones\">Telefonlar</string>\n    <string name=\"emails\">Epostalar</string>\n    <string name=\"urls\">URL\\'ler</string>\n    <string name=\"addresses\">Adresler</string>\n    <string name=\"summary\">Özet</string>\n    <string name=\"description\">Açıklama</string>\n    <string name=\"location\">Konum</string>\n    <string name=\"organizer\">Organizatör</string>\n    <string name=\"start_date\">Başlangıç tarihi</string>\n    <string name=\"end_date\">Bitiş tarihi</string>\n    <string name=\"status\">Durum</string>\n    <string name=\"latitude\">Enlem</string>\n    <string name=\"longitude\">Boylam</string>\n    <string name=\"create_barcode\">Barkod oluştur</string>\n    <string name=\"edit_barcode\">Barkod düzenle</string>\n    <string name=\"wifi_configuration\">Wi-Fi konfigürasyonu</string>\n    <string name=\"security\">Güvenlik</string>\n    <string name=\"pick_contact\">Kişi seçin</string>\n    <string name=\"grant_contact_permission\">Seçilen kişiyi kullanarak otomatik doldurma için ayarlardan kişilere izin ver</string>\n    <string name=\"contact_info\">Kişi bilgisi</string>\n    <string name=\"first_name\">İlk isim</string>\n    <string name=\"middle_name\">Orta isim</string>\n    <string name=\"last_name\">Son isim</string>\n    <string name=\"pronunciation\">Okunuş</string>\n    <string name=\"add_phone\">Telefon ekle</string>\n    <string name=\"add_email\">Eposta ekle</string>\n    <string name=\"add_address\">Adres ekle</string>\n    <string name=\"website\">Website</string>\n    <string name=\"add_website\">Website ekle</string>\n    <string name=\"formatted_name\">Formatlanmış isim</string>\n    <string name=\"qr_code_top_image\">Bu görüntü barkodun üzerine yerleştirilmek üzere kullanılacaktır</string>\n    <string name=\"code_customization\">Kod özelleştirmesi</string>\n    <string name=\"qr_logo_image\">Bu görüntü, QR kodunun ortasında logo olarak kullanılacaktır</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo iç boşluğu</string>\n    <string name=\"logo_size\">Logo boyutu</string>\n    <string name=\"logo_corners\">Logo köşeleri</string>\n    <string name=\"fourth_eye\">Dördüncü göz</string>\n    <string name=\"fourth_eye_description\">Alt köşeye dördüncü göz ekleyerek QR koduna göz simetrisi ekler</string>\n    <string name=\"pixel_shape\">Piksel şekli</string>\n    <string name=\"frame_shape\">Çerçeve şekli</string>\n    <string name=\"ball_shape\">Top şekli</string>\n    <string name=\"error_correction_level\">Hata düzeltme seviyesi</string>\n    <string name=\"dark_color\">Koyu renk</string>\n    <string name=\"light_color\">Açık renk</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Xiaomi HyperOS gibi stil</string>\n    <string name=\"mask_pattern\">Maske deseni</string>\n    <string name=\"code_may_be_not_scannable\">Bu kod taranamayabilir, tüm cihazlarda okunabilir hale getirmek için görünüm parametrelerini değiştirin.</string>\n    <string name=\"not_scannable\">Taranamıyor</string>\n    <string name=\"launcher_mode_sub\">Araçlar, daha kompakt olması için ana ekran uygulama başlatıcısı gibi görünecek</string>\n    <string name=\"launcher_mode\">Başlatıcı Modu</string>\n    <string name=\"flood_fill_sub\">Seçilen fırça ve stil ile bir alanı doldurur</string>\n    <string name=\"flood_fill\">Dolgu</string>\n    <string name=\"spray\">Sprey</string>\n    <string name=\"spray_sub\">Grafiti tarzı yol çizer</string>\n    <string name=\"square_particles\">Kare Parçacıklar</string>\n    <string name=\"square_particles_sub\">Sprey parçacıkları daire şeklinde değil kare şeklinde olacaktır</string>\n    <string name=\"palette_tools\">Palet Araçları</string>\n    <string name=\"palette_tools_sub\">Görüntüden temel/material you paleti oluşturun, veya farklı palet formatları arasında içe/dışa aktarın</string>\n    <string name=\"edit_palette\">Paleti düzenle</string>\n    <string name=\"edit_palette_sub\">Çeşitli formatlarda palet içe/dışa aktarma</string>\n    <string name=\"color_name\">Renk ismi</string>\n    <string name=\"palette_name\">Palet ismi</string>\n    <string name=\"palette_format\">Palet Formatı</string>\n    <string name=\"export_palette_sub\">Oluşturulan paleti farklı formatlara aktarın</string>\n    <string name=\"add_color_palette_sub\">Mevcut palete yeni renk ekler</string>\n    <string name=\"palette_name_not_supported\">%1$s formatı palet adı sağlamayı desteklemiyor</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store politikaları nedeniyle, bu özellik mevcut sürümde bulunmamaktadır. Bu özelliğe erişmek için lütfen ImageToolbox\\'ı alternatif bir kaynaktan indirin. Mevcut sürümleri aşağıdaki GitHub adresinde bulabilirsiniz.</string>\n    <string name=\"open_github_page\">GitHub sayfasını aç</string>\n    <string name=\"overwrite_files_sub_short\">Orijinal dosya, seçilen klasöre kaydedilmek yerine yenisiyle değiştirilecektir.</string>\n    <string name=\"hidden_watermark_text_detected\">Gizli filigran metni algılandı</string>\n    <string name=\"hidden_watermark_image_detected\">Gizli filigran görüntüsü algılandı</string>\n    <string name=\"this_image_was_hidden\">Bu resim gizlendi</string>\n    <string name=\"generative_inpaint\">Üretken İçboya</string>\n    <string name=\"generative_inpaint_sub\">OpenCV\\'ye bağlı kalmadan, bir AI modeli kullanarak görüntüdeki nesneleri kaldırmanıza olanak tanır. Bu özelliği kullanmak için, uygulama gerekli modeli (~200 MB) GitHub\\'dan indirecektir</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV\\'ye bağlı kalmadan, bir AI modeli kullanarak görüntüdeki nesneleri kaldırmanıza olanak tanır. Bu, uzun süren bir işlem olabilir</string>\n    <string name=\"error_level_analysis\">Hata Seviyesi Analizi</string>\n    <string name=\"luminance_gradient\">Parlaklık Gradyanı</string>\n    <string name=\"average_distance\">Ortalama Uzaklık</string>\n    <string name=\"copy_move_detection\">Kopyalama Hareket Algılama</string>\n    <string name=\"retain\">Sürdür</string>\n    <string name=\"coefficent\">Katsayı</string>\n    <string name=\"clipboard_data_is_too_large\">Pano verileri çok büyük</string>\n    <string name=\"data_is_too_large_to_copy\">Veriler kopyalanamayacak kadar büyük</string>\n    <string name=\"simple_weave_pixelization\">Basit Dokuma Pikselleştirme</string>\n    <string name=\"staggered_pixelization\">Kademeli Pikselleştirme</string>\n    <string name=\"cross_pixelization\">Çapraz Pikselleştirme</string>\n    <string name=\"micro_macro_pixelization\">Mikro Makro Pikselleştirme</string>\n    <string name=\"orbital_pixelization\">Orbital Pikselleştirme</string>\n    <string name=\"vortex_pixelization\">Vortex Pikselleştirme</string>\n    <string name=\"pulse_grid_pixelization\">Atım Izgara Pikselleştirmesi</string>\n    <string name=\"nucleus_pixelization\">Çekirdek Pikselleştirme</string>\n    <string name=\"radial_weave_pixelization\">Radyal Dokuma Pikselleştirme</string>\n    <string name=\"cannot_open_uri\">\\\"%1$s\\\" URI açılamıyor</string>\n    <string name=\"snowfall_mode\">Kar Yağışı Modu</string>\n    <string name=\"enabled\">Aktif</string>\n    <string name=\"border_frame\">Sınır Çerçevesi</string>\n    <string name=\"glitch_variant\">Glitch Varyantı</string>\n    <string name=\"channel_shift\">Kanal Değişimi</string>\n    <string name=\"max_offset\">Maks Çıkıntı</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Blok Glitch</string>\n    <string name=\"block_size\">Blok Boyutu</string>\n    <string name=\"crt_curvature\">CRT eğriliği</string>\n    <string name=\"curvature\">Eğrilik</string>\n    <string name=\"chroma\">Renk Parlaklığı</string>\n    <string name=\"pixel_melt\">Piksel Erime</string>\n    <string name=\"max_drop\">Maks Düşüş</string>\n    <string name=\"ai_tools\">AI Araçları</string>\n    <string name=\"ai_tools_sub\">Artefakt giderme veya gürültü giderme gibi yapay zeka modelleriyle görüntüleri işlemek için çeşitli araçlar</string>\n    <string name=\"model_anime_undeint\">Sıkıştırma, pürüzlü çizgiler</string>\n    <string name=\"model_broadcast\">Çizgi filmler, yayın sıkıştırma</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Genel sıkıştırma, genel gürültü</string>\n    <string name=\"model_wb_denoise\">Renksiz çizgi film gürültüsü</string>\n    <string name=\"model_span_anime_pretrain\">Hızlı, genel sıkıştırma, genel gürültü, animasyon/çizgi roman/anime</string>\n    <string name=\"model_book_scan\">Kitap tarama</string>\n    <string name=\"model_overexposure\">Pozlama düzeltmesi</string>\n    <string name=\"model_fbcnn_color_fp16\">Genel sıkıştırmada en iyisi, renkli görüntüler</string>\n    <string name=\"model_fbcnn_gray_fp16\">Genel sıkıştırmada en iyi, grisel görüntüler</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Genel sıkıştırma, grisel görüntüler, daha güçlü</string>\n    <string name=\"model_scunet_color_gan_fp16\">Genel gürültü, renkli görüntüler</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Genel gürültü, renkli görüntüler, daha iyi ayrıntılar</string>\n    <string name=\"model_scunet_gray_15_fp16\">Genel gürültü, grisel görüntüler</string>\n    <string name=\"model_scunet_gray_25_fp16\">Genel gürültü, grisel görüntüler, daha güçlü</string>\n    <string name=\"model_scunet_gray_50_fp16\">Genel gürültü, grisel görüntüler, en güçlü</string>\n    <string name=\"model_jpeg_destroyer\">Genel sıkıştırma</string>\n    <string name=\"model_jaywreck\">Genel sıkıştırma</string>\n    <string name=\"model_h264\">Tekstürleme, h264 sıkıştırma</string>\n    <string name=\"model_vhs\">VHS sıkıştırma</string>\n    <string name=\"model_cinepak\">Standart olmayan sıkıştırma (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Blink sıkıştırması, geometri için daha iyi</string>\n    <string name=\"model_debink_v5\">Blink sıkıştırma, daha güçlü</string>\n    <string name=\"model_debink_v6\">Blink sıkıştırma, yumuşak, ayrıntıları korur</string>\n    <string name=\"model_antialias\">Merdiven basamağı etkisini ortadan kaldırma, düzleştirme</string>\n    <string name=\"model_kdm_scans\">Taranmış çizimler, hafif sıkıştırma, muare</string>\n    <string name=\"model_bandage\">Renk bantlaması</string>\n    <string name=\"model_halftone\">Yavaş, yarı tonları kaldırma</string>\n    <string name=\"model_colorizer\">Grisel/siyah beyaz görüntüler için genel renklendirici, daha iyi sonuçlar için DDColor kullanın</string>\n    <string name=\"model_deedge\">Kenar kaldırma</string>\n    <string name=\"model_desharpen\">Aşırı keskinleştirmeyi kaldırır</string>\n    <string name=\"model_dither\">Yavaş, titreşimli</string>\n    <string name=\"model_gainres\">Kenar yumuşatma, genel artefaktlar, CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 tarama işlemleri</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Hafif görüntü iyileştirme modeli</string>\n    <string name=\"model_spongecolor_lite\">Basit ve hızlı renklendirme, çizgi filmler, ideal değil</string>\n    <string name=\"model_bcgone_detailed_v2\">Sıkıştırma artefaktı giderme</string>\n    <string name=\"model_bcgone_smooth\">Sıkıştırma artefaktı giderme</string>\n    <string name=\"model_bandage_smooth\">Pürüzsüz sonuçlarla bandaj çıkarma</string>\n    <string name=\"model_bendel_halftone\">Yarım ton desen işleme</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Titreşim deseni kaldırma V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG artefakt giderme V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 doku iyileştirme</string>\n    <string name=\"model_vhs_sharpen\">VHS keskinleştirme ve iyileştirme</string>\n    <string name=\"merging\">Birleştirme</string>\n    <string name=\"chunk_size\">Parça Boyutu</string>\n    <string name=\"overlap_size\">Örtüşme Boyutu</string>\n    <string name=\"note_chunk_info\">%1$s px\\'den büyük görüntüler dilimlenecek ve parçalar halinde işlenecek, üst üste binmeler görünür ek yerlerini önlemek için bunları karıştıracaktır.</string>\n    <string name=\"large_chunk_warning\">Büyük boyutlar, düşük kaliteli cihazlarda kararsızlığa neden olabilir.</string>\n    <string name=\"select_one_to_start\">Birini seçerek başla</string>\n    <string name=\"delete_model_sub\">%1$s modelini silmek istiyor musunuz? Tekrar indirmeniz gerekecektir.</string>\n    <string name=\"confirm\">Kabul</string>\n    <string name=\"models\">Modeller</string>\n    <string name=\"downloaded_models\">İndirilen Modeller</string>\n    <string name=\"available_models\">Mevcut Modeller</string>\n    <string name=\"preparing\">Hazırlanıyor</string>\n    <string name=\"active_model\">Aktif Model</string>\n    <string name=\"failed_to_open_session\">Oturum açılamadı</string>\n    <string name=\"only_onnx_models\">Yalnızca .onnx/.ort modelleri içe aktarılabilir</string>\n    <string name=\"import_model\">Model içe aktar</string>\n    <string name=\"import_model_sub\">Özel onnx modelini daha sonra kullanmak üzere içe aktarın, yalnızca onnx/ort modelleri kabul edilir, neredeyse tüm esrgan benzeri varyantları destekler</string>\n    <string name=\"imported_models\">İçeri Aktarılan Modeller</string>\n    <string name=\"model_scunet_color_15_fp16\">Genel gürültü, renkli görüntüler</string>\n    <string name=\"model_scunet_color_25_fp16\">Genel gürültü, renkli görüntüler, daha güçlü</string>\n    <string name=\"model_scunet_color_50_fp16\">Genel gürültü, renkli görüntüler, en güçlü</string>\n    <string name=\"model_artifacts_dithering_alsa\">Titreşim artefaktlarını ve renk bantlamasını azaltarak, yumuşak gradyanları ve düz renk alanlarını iyileştirir.</string>\n    <string name=\"model_nmkd_brighten_redux\">Doğal renkleri korurken, dengeli vurgularla görüntünün parlaklığını ve kontrastını artırır.</string>\n    <string name=\"model_nmkd_brighten\">Ayrıntıları koruyarak ve aşırı pozlamayı önleyerek karanlık görüntüleri aydınlatır.</string>\n    <string name=\"model_nmkd_detoon\">Aşırı renk tonlamasını giderir ve daha nötr ve doğal bir renk dengesi sağlar.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">İnce ayrıntıları ve dokuları korumaya önem vererek Poisson tabanlı gürültü tonlaması uygular.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Daha yumuşak ve daha az agresif görsel sonuçlar için yumuşak Poisson gürültü tonlaması uygular.</string>\n    <string name=\"type_removebg\">Kaldır</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Detayların korunması ve görüntü netliğine odaklanan tek tip gürültü tonlama.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Hafif ve düzgün bir doku ve pürüzsüz bir görünüm için hafif ve düzgün bir gürültü tonlaması.</string>\n    <string name=\"model_repainter\">Artefaktları yeniden boyayarak ve görüntü tutarlılığını iyileştirerek hasarlı veya düzensiz alanları onarır.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Performans maliyetini en aza indirerek renk bantlamasını ortadan kaldıran hafif debanding modeli.</string>\n    <string name=\"model_jpeg_0_20\">Görüntüleri çok yüksek sıkıştırma artefaktları (kalite %0-20) ile optimize ederek netliği artırır.</string>\n    <string name=\"model_jpeg_20_40\">Yüksek sıkıştırma artefaktları olan görüntüleri iyileştirir (kalite %20-40), ayrıntıları geri yükler ve gürültüyü azaltır.</string>\n    <string name=\"model_jpeg_40_60\">Görüntüleri orta düzeyde sıkıştırma (kalite %40-60) ile iyileştirir, keskinlik ve pürüzsüzlük arasında denge sağlar.</string>\n    <string name=\"model_jpeg_60_80\">Hafif sıkıştırma (kalite %60-80) ile görüntüleri iyileştirerek ince ayrıntıları ve dokuları güçlendirir.</string>\n    <string name=\"model_jpeg_80_100\">Doğal görünümü ve ayrıntıları korurken, neredeyse kayıpsız görüntüleri (kalite %80-100) hafifçe iyileştirir.</string>\n    <string name=\"model_deblr\">Görüntü bulanıklığını hafifçe azaltır, artefakt oluşturmadan keskinliği artırır.</string>\n    <string name=\"processing_channel\">Uzun süreli işlemler</string>\n    <string name=\"processing_image\">Resim işleniyor</string>\n    <string name=\"processing\">İşleniyor</string>\n    <string name=\"model_artifacts_jpg_0_20\">Çok düşük kaliteli görüntülerdeki (0-20%) ağır JPEG sıkıştırma artefaktlarını giderir.</string>\n    <string name=\"model_artifacts_jpg_20_40\">Yüksek oranda sıkıştırılmış görüntülerdeki güçlü JPEG artefaktlarını azaltır (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Görüntü ayrıntılarını korurken orta derecede JPEG artefaktlarını temizler (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Oldukça yüksek kaliteli görüntülerde (60-80%) hafif JPEG artefaktlarını iyileştirir.</string>\n    <string name=\"model_artifacts_jpg_80_100\">Neredeyse kayıpsız görüntülerdeki (80-100%) küçük JPEG artefaktlarını ince bir şekilde azaltır.</string>\n    <string name=\"model_redetail_v2\">İnce ayrıntıları ve dokuları geliştirerek, ağır yapaylık olmadan algılanan keskinliği artırır.</string>\n    <string name=\"processing_finished\">İşleme bitti</string>\n    <string name=\"processing_failed\">İşleme başarısız</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Cilt dokularını ve ayrıntılarını iyileştirirken doğal görünümü korur, hız için optimize edilmiştir.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG sıkıştırma artefaktlarını giderir ve sıkıştırılmış fotoğrafların görüntü kalitesini geri yükler.</string>\n    <string name=\"model_iso_denoise_v1\">Düşük ışık koşullarında çekilen fotoğraflardaki ISO gürültüsünü azaltır ve ayrıntıları korur.</string>\n    <string name=\"model_dejumbo\">Aşırı pozlanmış veya \\\"jumbo\\\" vurguları düzeltir ve daha iyi ton dengesi sağlar.</string>\n    <string name=\"model_ddcolor_tiny\">Gri tonlu görüntülere doğal renkler ekleyen hafif ve hızlı renklendirme modeli.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Gürültü giderme</string>\n    <string name=\"type_colorize\">Renklendirme</string>\n    <string name=\"type_artifacts\">Artefaktlar</string>\n    <string name=\"type_enhance\">Geliştir</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Tarama</string>\n    <string name=\"type_upscale\">Kaliteleştirme</string>\n    <string name=\"model_realesrgan_x4v3\">Genel görüntüler için X4 yükseltici; daha az GPU ve zaman kullanan, orta düzeyde bulanıklık giderme ve gürültü azaltma özelliğine sahip küçük model.</string>\n    <string name=\"model_realesrgan_x2plus\">Genel görüntüler için X2 yükseltici, dokuları ve doğal ayrıntıları korur.</string>\n    <string name=\"model_realesrgan_x4plus\">Gelişmiş dokular ve gerçekçi sonuçlar sunan genel görüntüler için X4 yükseltici.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Anime görüntüleri için optimize edilmiş X4 yükseltici; daha keskin çizgiler ve ayrıntılar için 6 RRDB bloğu.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE kaybı ile X4 yükseltici, genel görüntüler için daha pürüzsüz sonuçlar ve daha az artefakt üretir.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">Anime görüntüleri için optimize edilmiş X4 Upscaler; daha keskin ayrıntılar ve pürüzsüz çizgiler sunan 4B32F varyantı.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Genel görüntüler için X4 UltraSharp V2 modeli; keskinlik ve netliği vurgular.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; daha hızlı ve daha küçük, daha az GPU belleği kullanırken ayrıntıları korur.</string>\n    <string name=\"model_rmbg_1_4\">Hızlı arka plan kaldırma için hafif model. Dengeli performans ve doğruluk. Portreler, nesneler ve sahnelerle çalışır. Çoğu kullanım durumu için önerilir.</string>\n    <string name=\"horizontal_border_thickness\">Yatay Kenar Kalınlığı</string>\n    <string name=\"vertical_border_thickness\">Dikey Kenar Kalınlığı</string>\n    <string name=\"current_model_not_chunkable\">Mevcut model parçalamayı desteklemiyor, görüntü orijinal boyutlarda işlenecek, bu durum yüksek bellek tüketimine ve düşük kaliteli cihazlarda sorunlara neden olabilir</string>\n    <string name=\"chunking_disabled\">Parçalama devre dışı, görüntü orijinal boyutlarında işlenecek; bu, yüksek bellek tüketimine ve düşük kaliteli cihazlarda sorunlara neden olabilir ancak çıkarımda daha iyi sonuçlar verebilir</string>\n    <string name=\"chunking\">Parçalama</string>\n    <string name=\"model_u2net\">Arka planı kaldırmak için yüksek doğruluklu görüntü segmentasyon modeli</string>\n    <string name=\"model_u2netp\">Daha az bellek kullanımıyla daha hızlı arka plan kaldırma için U2Net\\'in hafif versiyonu.</string>\n    <string name=\"model_ddcolor\">Tam DDColor modeli, minimum düzeyde bozulmayla genel görüntüler için yüksek kaliteli renklendirme sunar. Tüm renklendirme modelleri arasında en iyi seçim.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Eğitimli ve özel sanatsal veri kümeleri; daha az gerçekçi olmayan renk yapısı ile çeşitli ve sanatsal renklendirme sonuçları üretir.</string>\n    <string name=\"model_birefnet\">Doğru arka plan kaldırma için Swin Transformer\\'ı temel alan hafif BiRefNet modeli.</string>\n    <string name=\"model_inspyrenet\">Özellikle karmaşık nesnelerde ve zorlu arka planlarda keskin kenarlar ve mükemmel ayrıntı korumasıyla yüksek kaliteli arka plan kaldırma.</string>\n    <string name=\"model_isnet\">Genel nesneler için uygun ve orta düzeyde ayrıntı korumasına sahip, pürüzsüz kenarlı doğru maskeler üreten arka plan kaldırma modeli.</string>\n    <string name=\"model_already_downloaded\">Model zaten indirildi</string>\n    <string name=\"model_successfully_imported\">Model başarıyla içe aktarıldı</string>\n    <string name=\"type\">Tip</string>\n    <string name=\"keyword\">Anahtar kelime</string>\n    <string name=\"very_fast\">Çok hızlı</string>\n    <string name=\"normal\">Normal</string>\n    <string name=\"slow\">Yavaş</string>\n    <string name=\"very_slow\">Çok Yavaş</string>\n    <string name=\"compute_percents\">Yüzdeleri Hesapla</string>\n    <string name=\"minimum_value_is\">Minimum değer %1$s\\'dir</string>\n    <string name=\"warp_sub\">Parmaklarınızla çizim yaparak görüntüyü deforme edin</string>\n    <string name=\"warp\">Çözgü</string>\n    <string name=\"hardness\">Sertlik</string>\n    <string name=\"warp_mode\">Çözgü Modu</string>\n    <string name=\"warp_mode_move\">Taşınmak</string>\n    <string name=\"warp_mode_grow\">Büyümek</string>\n    <string name=\"warp_mode_shrink\">Çekmek</string>\n    <string name=\"warp_mode_swirl_cw\">CW girdap</string>\n    <string name=\"warp_mode_swirl_ccw\">Girdap CCW</string>\n    <string name=\"fade_strength\">Solmaya Dayanım</string>\n    <string name=\"top_drop\">En İyi Düşüş</string>\n    <string name=\"bottom_drop\">Alttan Düşme</string>\n    <string name=\"start_drop\">Bırakmayı Başlat</string>\n    <string name=\"end_drop\">Bırakmayı Sonlandır</string>\n    <string name=\"downloading\">İndiriliyor</string>\n    <string name=\"smooth_shapes\">Pürüzsüz Şekiller</string>\n    <string name=\"smooth_shapes_sub\">Daha düzgün, daha doğal şekiller için standart yuvarlatılmış dikdörtgenler yerine süper elipsler kullanın</string>\n    <string name=\"shape_type\">Şekil Türü</string>\n    <string name=\"cut\">Kesmek</string>\n    <string name=\"rounded\">Yuvarlak</string>\n    <string name=\"smooth\">Düz</string>\n    <string name=\"cut_shapes_sub\">Yuvarlama olmadan keskin kenarlar</string>\n    <string name=\"rounded_shapes_sub\">Klasik yuvarlatılmış köşeler</string>\n    <string name=\"shapes_type\">Şekiller Türü</string>\n    <string name=\"corners_size\">Köşe Boyutu</string>\n    <string name=\"squircle\">sincap</string>\n    <string name=\"squircle_shapes_sub\">Zarif yuvarlak kullanıcı arayüzü öğeleri</string>\n    <string name=\"filename_format\">Dosya Adı Formatı</string>\n    <string name=\"prefix_pattern_description\">Dosya adının en başına yerleştirilen özel metin; proje adları, markalar veya kişisel etiketler için mükemmeldir.</string>\n    <string name=\"original_filename_pattern_description\">Orijinal dosya adını uzantısız olarak kullanarak kaynak kimliğini olduğu gibi korumanıza yardımcı olur.</string>\n    <string name=\"width_pattern_description\">Çözünürlük değişikliklerini izlemek veya sonuçları ölçeklendirmek için yararlı olan piksel cinsinden görüntü genişliği.</string>\n    <string name=\"height_pattern_description\">Görüntünün piksel cinsinden yüksekliği, en boy oranlarıyla veya dışa aktarmalarla çalışırken faydalıdır.</string>\n    <string name=\"random_numbers_pattern_description\">Benzersiz dosya adlarını garanti etmek için rastgele rakamlar üretir; kopyalara karşı ekstra güvenlik için daha fazla rakam ekleyin.</string>\n    <string name=\"sequence_number_pattern_description\">Toplu dışa aktarmalar için otomatik artan sayaç, tek oturumda birden fazla görüntüyü kaydederken idealdir.</string>\n    <string name=\"preset_info_pattern_description\">Uygulanan ön ayar adını dosya adına ekler, böylece görüntünün nasıl işlendiğini kolayca hatırlayabilirsiniz.</string>\n    <string name=\"scale_mode_pattern_description\">İşleme sırasında kullanılan görüntü ölçeklendirme modunu görüntüleyerek yeniden boyutlandırılan, kırpılan veya takılan görüntülerin ayırt edilmesine yardımcı olur.</string>\n    <string name=\"suffix_pattern_description\">Dosya adının sonuna yerleştirilen ve _v2, _edited veya _final gibi sürüm oluşturma için yararlı olan özel metin.</string>\n    <string name=\"extension_pattern_description\">Gerçek kaydedilen formatla otomatik olarak eşleşen dosya uzantısı (png, jpg, webp vb.).</string>\n    <string name=\"formatted_timestamp_pattern_description\">Mükemmel sıralama için Java spesifikasyonuna göre kendi formatınızı tanımlamanıza olanak tanıyan özelleştirilebilir bir zaman damgası.</string>\n    <string name=\"fling_type\">Fırlatma Türü</string>\n    <string name=\"android_native\">Android Yerel</string>\n    <string name=\"ios_style\">iOS Stili</string>\n    <string name=\"smooth_curve\">Pürüzsüz Eğri</string>\n    <string name=\"quick_stop\">Hızlı Durdurma</string>\n    <string name=\"bouncy\">kabarık</string>\n    <string name=\"floaty\">Yüzen</string>\n    <string name=\"snappy\">Hızlı</string>\n    <string name=\"ultra_smooth\">Ultra Pürüzsüz</string>\n    <string name=\"adaptive\">Uyarlanabilir</string>\n    <string name=\"accessibility_aware\">Erişilebilirlik Farkındalığı</string>\n    <string name=\"reduced_motion\">Azaltılmış Hareket</string>\n    <string name=\"android_native_sub\">Yerel Android kaydırma fiziği</string>\n    <string name=\"smooth_sub\">Genel kullanım için dengeli, düzgün kaydırma</string>\n    <string name=\"ios_style_sub\">Daha yüksek sürtünmeli iOS benzeri kaydırma davranışı</string>\n    <string name=\"smooth_curve_sub\">Farklı kaydırma hissi için benzersiz spline eğrisi</string>\n    <string name=\"quick_stop_sub\">Hızlı durdurmayla hassas kaydırma</string>\n    <string name=\"bouncy_sub\">Eğlenceli, hızlı tepki veren zıplayan kaydırma</string>\n    <string name=\"floaty_sub\">İçeriğe göz atmak için uzun, kayan kaydırmalar</string>\n    <string name=\"snappy_sub\">Etkileşimli kullanıcı arayüzleri için hızlı, duyarlı kaydırma</string>\n    <string name=\"ultra_smooth_sub\">Genişletilmiş momentumla birinci sınıf yumuşak kaydırma</string>\n    <string name=\"adaptive_sub\">Fırlatma hızına göre fiziği ayarlar</string>\n    <string name=\"accessibility_aware_sub\">Sistem erişilebilirlik ayarlarına saygı duyar</string>\n    <string name=\"reduced_motion_sub\">Erişilebilirlik ihtiyaçları için minimum hareket</string>\n    <string name=\"primary_lines\">Ana Hatlar</string>\n    <string name=\"primary_lines_sub\">Her beşinci satırda bir daha kalın çizgi ekler</string>\n    <string name=\"fill_color\">Dolgu Rengi</string>\n    <string name=\"hidden_tools\">Gizli Araçlar</string>\n    <string name=\"hidden_for_share\">Paylaşım İçin Gizlenen Araçlar</string>\n    <string name=\"color_library\">Renk Kitaplığı</string>\n    <string name=\"color_library_sub\">Geniş bir renk koleksiyonuna göz atın</string>\n    <string name=\"model_fatality_deblur\">Odak dışı fotoğrafları düzeltmek için ideal olan, doğal ayrıntıları korurken görüntülerdeki bulanıklığı keskinleştirir ve ortadan kaldırır.</string>\n    <string name=\"model_unresize_v3\">Daha önce yeniden boyutlandırılmış görüntüleri akıllıca geri yükleyerek kayıp ayrıntıları ve dokuları kurtarır.</string>\n    <string name=\"model_liveaction_v1_span\">Canlı aksiyon içeriği için optimize edilmiştir, sıkıştırma bozulmalarını azaltır ve film/TV şovu karelerindeki ince ayrıntıları geliştirir.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS kalitesinde çekimi HD\\'ye dönüştürerek bant gürültüsünü ortadan kaldırır ve çözünürlüğü artırırken aynı zamanda vintage hissi korur.</string>\n    <string name=\"model_text2hd_v1\">Metin ağırlıklı görüntüler ve ekran görüntüleri için özel olarak tasarlanmıştır, karakterleri keskinleştirir ve okunabilirliği artırır.</string>\n    <string name=\"model_frankendata_pretrainer\">Genel amaçlı fotoğraf geliştirme için mükemmel olan, çeşitli veri kümeleri üzerinde eğitilmiş gelişmiş yükseltme.</string>\n    <string name=\"model_realwebphoto_v2\">Web\\'de sıkıştırılmış fotoğraflar için optimize edilmiştir, JPEG bozulmalarını kaldırır ve doğal görünümü geri kazandırır.</string>\n    <string name=\"model_realwebphoto_v4\">Web fotoğrafları için daha iyi doku koruması ve artefakt azaltma özellikleriyle geliştirilmiş sürüm.</string>\n    <string name=\"model_dat_2x\">Çift Toplama Transformatörü teknolojisiyle 2 kat yükseltme, keskinliği ve doğal ayrıntıları korur.</string>\n    <string name=\"model_dat_3x\">Orta düzeydeki genişletme ihtiyaçları için ideal olan gelişmiş transformatör mimarisini kullanan 3 kat ölçeklendirme.</string>\n    <string name=\"model_dat_4x\">Son teknoloji trafo ağıyla 4 kat yüksek kalite yükseltme, daha büyük ölçeklerde ince ayrıntıları korur.</string>\n    <string name=\"model_nafnet_deblurring\">Fotoğraflardan bulanıklığı/gürültüyü ve titremeyi giderir. Genel amaçlı ama fotoğraflarda en iyisi.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">BSRGAN bozulması için optimize edilmiş Swin2SR transformatörünü kullanarak düşük kaliteli görüntüleri geri yükler. Ağır sıkıştırma bozukluklarını düzeltmek ve ayrıntıları 4x ölçekte geliştirmek için idealdir.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN bozulması konusunda eğitilmiş SwinIR transformatörüyle 4 kat yükseltme. Fotoğraflar ve karmaşık sahnelerde daha keskin dokular ve daha doğal ayrıntılar için GAN\\'ı kullanır.</string>\n    <string name=\"path\">Yol</string>\n    <string name=\"merge_pdf\">PDF\\'yi birleştir</string>\n    <string name=\"merge_pdf_sub\">Birden fazla PDF dosyasını tek bir belgede birleştirin</string>\n    <string name=\"files_order\">Dosya Sırası</string>\n    <string name=\"pages_short\">s.</string>\n    <string name=\"split_pdf\">PDF\\'yi böl</string>\n    <string name=\"split_pdf_sub\">PDF belgesinden belirli sayfaları çıkarın</string>\n    <string name=\"rotate_pdf\">PDF\\'yi döndür</string>\n    <string name=\"rotate_pdf_sub\">Sayfa yönlendirmesini kalıcı olarak düzeltin</string>\n    <string name=\"pages\">Sayfalar</string>\n    <string name=\"rearrange_pdf\">PDF\\'yi yeniden düzenle</string>\n    <string name=\"rearrange_pdf_sub\">Sayfaları yeniden sıralamak için sürükleyip bırakın</string>\n    <string name=\"hold_drag_drop\">Sayfaları Tut ve Sürükle</string>\n    <string name=\"page_numbers\">Sayfa Numaraları</string>\n    <string name=\"page_numbers_sub\">Belgelerinize otomatik olarak numaralandırma ekleyin</string>\n    <string name=\"label_format\">Etiket Formatı</string>\n    <string name=\"pdf_to_text\">PDF\\'den Metne (OCR)</string>\n    <string name=\"pdf_to_text_sub\">PDF belgelerinizden düz metin çıkarın</string>\n    <string name=\"watermark_pdf_sub\">Marka bilinci oluşturma veya güvenlik için özel metni katmanlayın</string>\n    <string name=\"signature\">İmza</string>\n    <string name=\"signature_sub\">Elektronik imzanızı herhangi bir belgeye ekleyin</string>\n    <string name=\"will_be_for_signature\">Bu imza olarak kullanılacaktır</string>\n    <string name=\"unlock_pdf\">PDF\\'nin kilidini aç</string>\n    <string name=\"unlock_pdf_sub\">Korunan dosyalarınızdan şifreleri kaldırın</string>\n    <string name=\"protect_pdf\">PDF\\'yi koruyun</string>\n    <string name=\"protect_pdf_sub\">Belgelerinizi güçlü şifrelemeyle koruyun</string>\n    <string name=\"success\">Başarı</string>\n    <string name=\"pdf_unlocked\">PDF\\'nin kilidi açıldı, kaydedebilir veya paylaşabilirsiniz</string>\n    <string name=\"repair_pdf\">PDF\\'yi onar</string>\n    <string name=\"repair_pdf_sub\">Bozuk veya okunamayan belgeleri düzeltmeye çalışın</string>\n    <string name=\"grayscale\">Gri tonlamalı</string>\n    <string name=\"grayscale_pdf_sub\">Tüm belgeye gömülü görüntüleri gri tonlamaya dönüştürün</string>\n    <string name=\"compress_pdf\">PDF\\'yi sıkıştır</string>\n    <string name=\"compress_pdf_sub\">Daha kolay paylaşım için belgenizin dosya boyutunu optimize edin</string>\n    <string name=\"repair_info\">ImageToolbox dahili çapraz referans tablosunu yeniden oluşturur ve dosya yapısını sıfırdan yeniden oluşturur. Bu, \\\\\"açılamayan\\\\\" birçok dosyaya erişimi geri yükleyebilir</string>\n    <string name=\"grayscale_info\">Bu araç, tüm belge resimlerini gri tonlamaya dönüştürür. Dosya boyutunu yazdırmak ve küçültmek için en iyisi</string>\n    <string name=\"metadata\">Meta veriler</string>\n    <string name=\"metadata_pdf_sub\">Daha iyi gizlilik için belge özelliklerini düzenleyin</string>\n    <string name=\"tags\">Etiketler</string>\n    <string name=\"producer\">yapımcı</string>\n    <string name=\"author\">Yazar</string>\n    <string name=\"keywords\">Anahtar Kelimeler</string>\n    <string name=\"creator\">Yaratıcı</string>\n    <string name=\"privacy_deep_clean\">Gizlilik Derinlemesine Temizlik</string>\n    <string name=\"privacy_deep_clean_sub\">Bu belge için mevcut tüm meta verileri temizle</string>\n    <string name=\"page\">Sayfa</string>\n    <string name=\"deep_ocr\">Derin OCR</string>\n    <string name=\"deep_ocr_sub\">Tesseract motorunu kullanarak belgeden metni çıkarın ve tek bir metin dosyasında saklayın</string>\n    <string name=\"cant_remove_all\">Tüm sayfalar kaldırılamıyor</string>\n    <string name=\"remove_pages_pdf\">PDF sayfalarını kaldır</string>\n    <string name=\"remove_pages_pdf_sub\">PDF belgesinden belirli sayfaları kaldırın</string>\n    <string name=\"tap_to_remove\">Kaldırmak İçin Dokunun</string>\n    <string name=\"manually\">Manuel olarak</string>\n    <string name=\"crop_pdf\">PDF\\'yi kırp</string>\n    <string name=\"crop_pdf_sub\">Belge sayfalarını istediğiniz sınırlara göre kırpın</string>\n    <string name=\"flatten_pdf\">PDF\\'yi düzleştir</string>\n    <string name=\"flatten_pdf_sub\">Belge sayfalarını tarayarak PDF\\'yi değiştirilemez hale getirin</string>\n    <string name=\"camera_failed_to_open\">Kamera başlatılamadı. Lütfen izinleri kontrol edin ve başka bir uygulama tarafından kullanılmadığından emin olun.</string>\n    <string name=\"extract_images\">Görüntüleri Çıkart</string>\n    <string name=\"extract_images_sub\">PDF\\'lere gömülü görüntüleri orijinal çözünürlüklerinde çıkarın</string>\n    <string name=\"pdf_no_embedded\">Bu PDF dosyası herhangi bir gömülü resim içermiyor</string>\n    <string name=\"extract_images_info\">Bu araç her sayfayı tarar ve tam kalitede kaynak görüntüleri kurtarır; belgelerdeki orijinalleri kaydetmek için mükemmeldir</string>\n    <string name=\"draw_signature\">İmza Çek</string>\n    <string name=\"pen_params\">Kalem Parametreleri</string>\n    <string name=\"draw_signature_sub\">Belgelere yerleştirilecek resim olarak kendi imzanızı kullanın</string>\n    <string name=\"zip_pdf\">PDF\\'yi sıkıştır</string>\n    <string name=\"zip_pdf_sub\">Belgeyi belirli aralıklarla bölün ve yeni belgeleri zip arşivine paketleyin</string>\n    <string name=\"interval\">Aralık</string>\n    <string name=\"print_pdf\">PDF\\'yi yazdır</string>\n    <string name=\"print_pdf_sub\">Belgeyi özel sayfa boyutunda yazdırmaya hazırlayın</string>\n    <string name=\"pages_per_sheet\">Sayfa Başına Sayfa</string>\n    <string name=\"orientation\">Oryantasyon</string>\n    <string name=\"page_size\">Sayfa Boyutu</string>\n    <string name=\"margin\">Marj</string>\n    <string name=\"bloom\">Çiçek açmak</string>\n    <string name=\"soft_knee\">Yumuşak Diz</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Anime ve çizgi filmler için optimize edilmiştir. İyileştirilmiş doğal renkler ve daha az yapaylık ile hızlı ölçeklendirme</string>\n    <string name=\"one_ui_sub\">Samsung One UI 7 benzeri tarz</string>\n    <string name=\"calculate_hint\">İstenilen değeri hesaplamak için temel matematik sembollerini buraya girin (örn. (5+5)*10)</string>\n    <string name=\"math_expression\">Matematik ifadesi</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s adede kadar resim alın</string>\n    <string name=\"keep_date_time\">Tarih Saati Tut</string>\n    <string name=\"keep_date_time_sub\">Tarih ve saate ilişkin exif etiketlerini her zaman koruyun, exif\\'i sakla seçeneğinden bağımsız olarak çalışır</string>\n    <string name=\"background_color_for_alpha_formats\">Alfa Formatları İçin Arka Plan Rengi</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Alfa desteğiyle her görüntü formatı için arka plan rengini ayarlama olanağı ekler; devre dışı bırakıldığında bu yalnızca alfa olmayanlar için geçerlidir</string>\n    <string name=\"open_markup_project\">Projeyi aç</string>\n    <string name=\"open_markup_project_sub\">Önceden kaydedilmiş bir Image Toolbox projesini düzenlemeye devam edin</string>\n    <string name=\"markup_project_open_failed\">Image Toolbox projesi açılamıyor</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox projesinde proje verileri eksik</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox projesi bozuk</string>\n    <string name=\"unsupported_markup_project_version\">Desteklenmeyen Image Toolbox proje sürümü: %1$d</string>\n    <string name=\"save_markup_project\">Projeyi kaydet</string>\n    <string name=\"save_markup_project_sub\">Katmanları, arka planı ve düzenleme geçmişini düzenlenebilir bir proje dosyasında saklayın</string>\n    <string name=\"failed_to_open\">Açılamadı</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Aranabilir PDF\\'ye Yaz</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Görüntü kümesindeki metni tanıyın ve görüntü ve seçilebilir metin katmanıyla aranabilir PDF\\'yi kaydedin</string>\n    <string name=\"layer_alpha\">Katman alfa</string>\n    <string name=\"horizontal_flip\">Yatay Çevirme</string>\n    <string name=\"vertical_flip\">Dikey Çevirme</string>\n    <string name=\"lock\">Kilit</string>\n    <string name=\"add_shadow\">Gölge Ekle</string>\n    <string name=\"shadow_color\">Gölge Rengi</string>\n    <string name=\"text_geometry\">Metin Geometrisi</string>\n    <string name=\"text_geometry_sub\">Daha keskin stilizasyon için metni uzatın veya eğriltin</string>\n    <string name=\"scale_x\">Ölçek X</string>\n    <string name=\"skew_x\">X\\'i Eğikleştir</string>\n    <string name=\"remove_annotations\">Ek açıklamaları kaldır</string>\n    <string name=\"remove_annotations_sub\">Bağlantılar, yorumlar, vurgular, şekiller veya form alanları gibi seçili ek açıklama türlerini PDF sayfalarından kaldırın</string>\n    <string name=\"annotation_link\">Köprüler</string>\n    <string name=\"annotation_file_attachment\">Dosya Ekleri</string>\n    <string name=\"annotation_line\">çizgiler</string>\n    <string name=\"annotation_popup\">Pop-up\\'lar</string>\n    <string name=\"annotation_stamp\">Pullar</string>\n    <string name=\"annotation_shapes\">Şekiller</string>\n    <string name=\"annotation_text\">Metin Notları</string>\n    <string name=\"annotation_text_markup\">Metin İşaretleme</string>\n    <string name=\"annotation_widget\">Form Alanları</string>\n    <string name=\"annotation_markup\">İşaretleme</string>\n    <string name=\"annotation_unknown\">Bilinmiyor</string>\n    <string name=\"annotations\">Ek açıklamalar</string>\n    <string name=\"ungroup\">Grubu çöz</string>\n    <string name=\"add_shadow_sub\">Yapılandırılabilir renk ve ofsetlerle katmanın arkasına bulanıklık gölgesi ekleyin</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-ug/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"image_too_large_preview\">سۈرەت بەك چوڭ، ئالدىن كۆرگىلى بولمايدۇ، لېكىن يەنىلا ساقلاشنى سىناپ باقىمىز</string>\n    <string name=\"pick_image\">رەسىمنى تاللاپ باشلاڭ</string>\n    <string name=\"height\">ئېگىزلىك %1$s</string>\n    <string name=\"quality\">سۈپىتى</string>\n    <string name=\"extension\">فورماتى</string>\n    <string name=\"resize_type\">تارايتىش تىپى</string>\n    <string name=\"explicit\">مەجبۇر</string>\n    <string name=\"flexible\">ئۆزى ماسلىشىش</string>\n    <string name=\"reset_image\">قايتا ئۆزگەرتىش</string>\n    <string name=\"reset_image_sub\">رەسىمنى دەسلەپكى ھالىتىگە قايتۇرۇش</string>\n    <string name=\"values_reset\">دەسلەپكى ھالىتىگە قايىتتى</string>\n    <string name=\"reset\">قايتا كىلەي</string>\n    <string name=\"something_went_wrong\">ۋايجان~بىريەلىرى بىرقاندايا بۇنىڭ</string>\n    <string name=\"restart_app\">ئەپنى ئەسلى ھالىتىگە قايتۇرۇش</string>\n    <string name=\"copied\">چاپلاق تاختىسىغا كۆچۈرۈلدى</string>\n    <string name=\"exception\">نەزەردىن ساقىت قىلىش تۈرى</string>\n    <string name=\"edit_exif\">EXIFئۇچۇرىنى ئۆزگەرتىش</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">مۇقۇملاشتۇرۇش</string>\n    <string name=\"no_exif\">EXIFئۇچۇرى يوقكەن</string>\n    <string name=\"add_tag\">بەلگە قوشۇش</string>\n    <string name=\"save\">ساقلاش</string>\n    <string name=\"clear\">قۇرقداش</string>\n    <string name=\"clear_exif\">EXIFئۇچۇرىنى قۇرۇقداش</string>\n    <string name=\"cancel\">بولدىلا</string>\n    <string name=\"clear_exif_sub\">بارلىق رەسىم EXIF سانلىق مەلۇماتلىرى ئۆچۈرۈلىدۇ. بۇ ھەرىكەتنى ئەمەلدىن قالدۇرغىلى بولمايدۇ!</string>\n    <string name=\"smth_went_wrong\">چاتاق چىقتى: %1$s</string>\n    <string name=\"size\">چوڭلۇقى %1$s</string>\n    <string name=\"loading\">يۈكلىنىۋاتىدۇ…</string>\n    <string name=\"width\">كەڭلىك %1$s</string>\n    <string name=\"pick_image_alt\">رەسىم تاللاش</string>\n    <string name=\"close\">ئۆچۈرۈش</string>\n    <string name=\"app_closing_sub\">راستىنلا چېكىنەمسىز؟</string>\n    <string name=\"app_closing\">ئەپتىن چېكىنىش</string>\n    <string name=\"stay\">بولدىلا</string>\n    <string name=\"presets\">ئالدىن تەسىس قىلىش</string>\n    <string name=\"crop\">كىسىش</string>\n    <string name=\"image_not_saved\">ساقلاش</string>\n    <string name=\"image_not_saved_sub\">ئەگەر ھازىر چېكىنىپ چىقسا، بارلىق ساقلانمىغان ئۆزگىرىشلەر يوقاپ كېتىدۇ</string>\n    <string name=\"check_source_code\">ئەسلى كود</string>\n    <string name=\"check_source_code_sub\">ئەڭ يېڭى يېڭىلاش، مەسىلىلەرنى مۇزاكىرە قىلىش قاتارلىقلارغا ئېرىشىش</string>\n    <string name=\"single_edit\">بىر پارچە رەسىمنى چوڭايتىش</string>\n    <string name=\"pick_color\">رەڭ تاللىغۇچ</string>\n    <string name=\"pick_color_sub\">رەسىمدىن رەڭ تاللاش، ھەمدە كۆپەيتىش ياكى ئورتاقلىشىش</string>\n    <string name=\"image\">رەسىم</string>\n    <string name=\"color\">رەڭ</string>\n    <string name=\"crop_sub\">رەسىمنى ھەر قانداق چوڭلۇقتا كېسىش</string>\n    <string name=\"version\">نۇسخا نومۇرى</string>\n    <string name=\"images\">رەسىم سانى :%d</string>\n    <string name=\"change_preview\">ئالدىن كۆرۈش رەسىمىنى ئالماشتۇرش</string>\n    <string name=\"remove\">چىقىرىۋېتىش</string>\n    <string name=\"generate_palette\">رەڭ ئۇسلۇبى</string>\n    <string name=\"palette\">رەڭ ئۇسلۇبى</string>\n    <string name=\"update\">يېڭىلاش</string>\n    <string name=\"new_version\">يېڭى نەشىرى %1$s</string>\n    <string name=\"unsupported_type\">قوللىمايدىغان تىپ : %1$s</string>\n    <string name=\"no_palette\">بەلگىلەنگەن رەسىمنىڭ رەڭ ئۇسلۇبىنى ھاسىل قىلغىلى بولمىدى</string>\n    <string name=\"original\">ئەسلى رەسىم</string>\n    <string name=\"def\">كۆڭۈلدىكى</string>\n    <string name=\"custom\">ئۆز ئالدىغا ئېنىقلىما بېرىش</string>\n    <string name=\"device_storage\">ئۈسكۈنە ساقلاش ئورنى</string>\n    <string name=\"single_edit_sub\">بىر پارچە رەسىمنىڭ ئۆلچىمىنى ئۆزگەرتىش</string>\n    <string name=\"color_copied\">رەڭ كودى كۆپەيتىلدى</string>\n    <string name=\"keep_exif\">EXIF ئۇچۇرىنى ساقلاپ قېلىش</string>\n    <string name=\"palette_sub\">بەلگىلەنگەن رەسىمنىڭ رەڭ ئۇسلۇبىنى ھاسىل قىلىش</string>\n    <string name=\"folder\">چىقىرىش مۇندەرىجىسى</string>\n    <string name=\"unspecified\">بەلگىلەنمىگەن</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Cutoff</string>\n    <string name=\"amoled_mode\">Amoled mode</string>\n    <string name=\"amoled_mode_sub\">ئەگەر قوزغىتىلغان يۈزلەرنىڭ رەڭگى كېچىدە مۇتلەق قاراڭغۇ قىلىپ تەڭشىلىدۇ</string>\n    <string name=\"color_scheme\">رەڭ لايىھىسى</string>\n    <string name=\"color_red\">قىزىل</string>\n    <string name=\"color_green\">يېشىل</string>\n    <string name=\"color_blue\">كۆك</string>\n    <string name=\"clipboard_paste_invalid_color_code\">ئىناۋەتلىك aRGB- كود چاپلاڭ.</string>\n    <string name=\"clipboard_paste_invalid_empty\">چاپلاشقا ھېچنېمە يوق</string>\n    <string name=\"about_app\">ئەپ ھەققىدە</string>\n    <string name=\"no_updates\">ھېچقانداق يېڭىلانما تېپىلمىدى</string>\n    <string name=\"issue_tracker\">ئىز قوغلىغۇچى</string>\n    <string name=\"issue_tracker_sub\">بۇ يەرگە خاتالىق دوكلاتى ۋە ئىقتىدار تەلەپلىرىنى ئەۋەتىڭ</string>\n    <string name=\"help_translate\">تەرجىمە قىلىشقا ياردەم قىلىڭ</string>\n    <string name=\"help_translate_sub\">تەرجىمە خاتالىقىنى تۈزىتىڭ ياكى تۈرنى باشقا تىللارغا يەرلىكلەشتۈرۈڭ</string>\n    <string name=\"nothing_found_by_search\">سوئالىڭىزدىن ھېچ نەرسە تېپىلمىدى</string>\n    <string name=\"search_here\">بۇ يەردىن ئىزدەڭ</string>\n    <string name=\"dynamic_colors_sub\">ئەگەر قوزغىتىلغان بولسا ، ئەپ رەڭلىرى تام قەغىزىنىڭ رەڭگىگە قوللىنىلىدۇ</string>\n    <string name=\"failed_to_save\">%d رەسىم (لەر) نى ساقلىيالمىدى</string>\n    <string name=\"primary\">Primary</string>\n    <string name=\"tertiary\">Tertiary</string>\n    <string name=\"secondary\">Secondary</string>\n    <string name=\"border_thickness\">چېگرا قېلىنلىقى</string>\n    <string name=\"surface\">Surface</string>\n    <string name=\"values\">قىممەت</string>\n    <string name=\"add\">قوش</string>\n    <string name=\"permission\">ئىجازەت</string>\n    <string name=\"grant\">Grant</string>\n    <string name=\"permission_sub\">قوللىنىشچان پروگراممىلارنى ساقلاش ئۈچۈن ساقلاش بوشلۇقىڭىزغا كىرىشى كېرەك ، ئۇ زۆرۈر. كېيىنكى سۆزلىشىش رامكىسىغا ئىجازەت بېرىڭ.</string>\n    <string name=\"external_storage\">سىرتقى ساقلاش</string>\n    <string name=\"grant_permission_manual\">ئەپ ئىشلەش ئۈچۈن بۇ ئىجازەتكە موھتاج ، قولدا بېرىڭ</string>\n    <string name=\"monet_colors\">مون رەڭلىرى</string>\n    <string name=\"donation_sub\">بۇ پروگرامما پۈتۈنلەي ھەقسىز ، ئەمما تۈر تەرەققىياتىنى قوللىماقچى بولسىڭىز ، بۇ يەرنى چېكىڭ</string>\n    <string name=\"fab_alignment\">FAB توغرىلاش</string>\n    <string name=\"check_updates\">يېڭىلانمىلارنى تەكشۈرۈڭ</string>\n    <string name=\"check_updates_sub\">ئەگەر قوزغىتىلسا ، ئەپ قوزغالغاندا يېڭىلاش دىئالوگى سىزگە كۆرسىتىلىدۇ</string>\n    <string name=\"zoom\">رەسىم چوڭايتىش</string>\n    <string name=\"share\">ھەمبەھىرلەش</string>\n    <string name=\"prefix\">Prefix</string>\n    <string name=\"filename\">ھۆججەت ئىسمى</string>\n    <string name=\"emoji\">Emoji</string>\n    <string name=\"add_file_size_sub\">ئەگەر قوزغىتىلسا ، چىقىرىلغان ھۆججەتنىڭ نامىغا ساقلانغان رەسىمنىڭ كەڭلىكى ۋە ئېگىزلىكىنى قوشىدۇ</string>\n    <string name=\"emoji_sub\">ئاساسلىق ئېكراندا قايسى emoji نى كۆرسىتىشنى تاللاڭ</string>\n    <string name=\"add_file_size\">ھۆججەت چوڭلۇقى قوشۇڭ</string>\n    <string name=\"delete_exif\">EXIF نى ئۆچۈرۈڭ</string>\n    <string name=\"delete_exif_sub\">ھەر قانداق رەسىمدىن EXIF مېتا سانلىق مەلۇماتلىرىنى ئۆچۈرۈڭ</string>\n    <string name=\"image_preview\">رەسىم ئالدىن كۆرۈش</string>\n    <string name=\"image_preview_sub\">ھەر خىل رەسىملەرنى ئالدىن كۆرۈڭ: GIF ، SVG قاتارلىقلار</string>\n    <string name=\"image_source\">رەسىم مەنبەسى</string>\n    <string name=\"photo_picker\">رەسىم تاللىغۇچ</string>\n    <string name=\"gallery_picker\">Gallery</string>\n    <string name=\"file_explorer_picker\">ھۆججەت ئىزدىگۈچى</string>\n    <string name=\"gallery_picker_sub\">ئاددىي رەسىمخانا رەسىم تاللىغۇچ. مېدىيا تاللاش بىلەن تەمىنلەيدىغان ئەپ بولسىلا ئىشلەيدۇ</string>\n    <string name=\"photo_picker_sub\">ئېكراننىڭ ئاستىدا كۆرۈنگەن ئاندىرويىد زامانىۋى رەسىم تاللىغۇچ پەقەت ئاندىرويىد 12+ دە ئىشلەيدۇ. EXIF مېتا سانلىق مەلۇماتلىرىنى قوبۇل قىلىش مەسىلىسى بار</string>\n    <string name=\"file_explorer_picker_sub\">GetContent نى ئىشلىتىپ رەسىم تاللاڭ. ھەممە يەردە ئىشلەيدۇ ، ئەمما بەزى ئۈسكۈنىلەردە تاللانغان رەسىملەرنى قوبۇل قىلىش مەسىلىسى بارلىقى مەلۇم. بۇ مېنىڭ خاتالىقىم ئەمەس.</string>\n    <string name=\"options_arrangement\">تاللانما ئورۇنلاشتۇرۇش</string>\n    <string name=\"edit\">تەھرىر</string>\n    <string name=\"order\">زاكاز</string>\n    <string name=\"order_sub\">ئاساسىي ئېكراندىكى تاللاشلارنىڭ تەرتىپىنى بەلگىلەيدۇ</string>\n    <string name=\"emojis_count\">Emojis count</string>\n    <string name=\"sequence_num\">sequNum</string>\n    <string name=\"original_filename\">originalFilename</string>\n    <string name=\"add_original_filename_sub\">قوزغىتىلغان بولسا چىقىرىش سۈرىتىنىڭ نامىغا ئەسلى ھۆججەت نامىنى قوشىدۇ</string>\n    <string name=\"add_original_filename\">ئەسلى ھۆججەت نامىنى قوشۇڭ</string>\n    <string name=\"replace_sequence_number\">تەرتىپ نومۇرىنى ئالماشتۇرۇڭ</string>\n    <string name=\"replace_sequence_number_sub\">ئەگەر قوزغىتىلغان بولسا تۈركۈملەپ بىر تەرەپ قىلىشنى ئىشلەتسىڭىز ئۆلچەملىك ۋاقىت تامغىسىنى رەسىم رەت نومۇرىغا ئالماشتۇرىدۇ</string>\n    <string name=\"filename_not_work_with_photopicker\">ئەگەر رەسىم تاللىغۇچى رەسىم مەنبەسى تاللانغان بولسا ئەسلى ھۆججەت نامىنى قوشۇش ئىشلىمەيدۇ</string>\n    <string name=\"load_image_from_net\">توردىن رەسىم يۈكلەڭ</string>\n    <string name=\"load_image_from_net_sub\">خالىغان رەسىمنى توردىن ئالدىن كۆرۈش ، چوڭايتىش ، تەھرىرلەش ۋە ساقلاش ئۈچۈن يۈكلەڭ.</string>\n    <string name=\"no_image\">رەسىم يوق</string>\n    <string name=\"image_link\">رەسىم ئۇلىنىشى</string>\n    <string name=\"fill\">تولدۇر</string>\n    <string name=\"fit\">Fit</string>\n    <string name=\"content_scale\">مەزمۇن كۆلىمى</string>\n    <string name=\"explicit_description\">ھەر بىر رەسىمنى كەڭلىك ۋە ئېگىزلىك پارامېتىرى بەرگەن رەسىمگە زورلايدۇ - تەرەپ نىسبىتىنى ئۆزگەرتىشى مۇمكىن</string>\n    <string name=\"flexible_description\">كەڭلىك ياكى ئېگىزلىك پارامېتىرى بەرگەن ئۇزۇن تەرىپى بىلەن رەسىملەرنىڭ چوڭ-كىچىكلىكىنى چوڭايتىدۇ ، بارلىق چوڭ-كىچىك ھېسابلاشلار تېجەپ بولغاندىن كېيىن ئېلىپ بېرىلىدۇ - تەرەپ نىسبىتىنى ساقلايدۇ.</string>\n    <string name=\"brightness\">Brightness</string>\n    <string name=\"contrast\">سېلىشتۇرما</string>\n    <string name=\"hue\">Hue</string>\n    <string name=\"saturation\">Saturation</string>\n    <string name=\"add_filter\">سۈزگۈچ قوشۇڭ</string>\n    <string name=\"filter\">سۈزگۈچ</string>\n    <string name=\"filter_sub\">بېرىلگەن رەسىملەرگە سۈزگۈچ زەنجىرىنى ئىشلىتىڭ</string>\n    <string name=\"filters\">سۈزگۈچ</string>\n    <string name=\"light_aka_illumination\">نۇر</string>\n    <string name=\"color_filter\">رەڭ سۈزگۈچ</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"exposure\">ئاشكارىلاش</string>\n    <string name=\"white_balance\">ئاق تەڭپۇڭلۇق</string>\n    <string name=\"temperature\">تېمپېراتۇرا</string>\n    <string name=\"tint\">Tint</string>\n    <string name=\"monochrome\">Monochrome</string>\n    <string name=\"gamma\">گامما</string>\n    <string name=\"highlights_shadows\">يارقىن نۇقتىلار ۋە سايە</string>\n    <string name=\"highlights\">يارقىن نۇقتىلار</string>\n    <string name=\"shadows\">سايە</string>\n    <string name=\"haze\">تۇمان</string>\n    <string name=\"effect\">ئۈنۈم</string>\n    <string name=\"distance\">ئارىلىق</string>\n    <string name=\"slope\">يانتۇ</string>\n    <string name=\"sharpen\">Sharpen</string>\n    <string name=\"sepia\">Sepia</string>\n    <string name=\"negative\">سەلبىي</string>\n    <string name=\"solarize\">Solarize</string>\n    <string name=\"vibrance\">تەۋرىنىش</string>\n    <string name=\"black_and_white\">قارا ۋە ئاق</string>\n    <string name=\"crosshatch\">Crosshatch</string>\n    <string name=\"spacing\">بوشلۇق</string>\n    <string name=\"line_width\">قۇر كەڭلىكى</string>\n    <string name=\"sobel_edge\">Sobel edge</string>\n    <string name=\"blur\">Blur</string>\n    <string name=\"halftone\">Halftone</string>\n    <string name=\"cga_colorspace\">CGA رەڭ بوشلۇقى</string>\n    <string name=\"gaussian_blur\">Gaussian blur</string>\n    <string name=\"bilaterial_blur\">Bilaterial blur</string>\n    <string name=\"box_blur\">Box blur</string>\n    <string name=\"emboss\">Emboss</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Vignette</string>\n    <string name=\"start\">باشلاش</string>\n    <string name=\"end\">ئاخىر</string>\n    <string name=\"stack_blur\">Stack blur</string>\n    <string name=\"kuwahara\">Kuwahara سىلىقلاش</string>\n    <string name=\"radius\">Radius</string>\n    <string name=\"scale\">تارازا</string>\n    <string name=\"distortion\">بۇرمىلاش</string>\n    <string name=\"angle\">Angle</string>\n    <string name=\"swirl\">Swirl</string>\n    <string name=\"bulge\">Bulge</string>\n    <string name=\"dilation\">Dilation</string>\n    <string name=\"sphere_refraction\">دائىرە سۇندۇرۇش</string>\n    <string name=\"refractive_index\">سۇندۇرۇش كۆرسەتكۈچى</string>\n    <string name=\"sketch\">Sketch</string>\n    <string name=\"glass_sphere_refraction\">ئەينەك دائىرىسىنى سۇندۇرۇش</string>\n    <string name=\"color_matrix\">رەڭلىك ماترىسسا</string>\n    <string name=\"opacity\">Opacity</string>\n    <string name=\"limits_resize\">چەكلىمىنىڭ چوڭ-كىچىكلىكى</string>\n    <string name=\"limits_resize_sub\">تاللانغان رەسىملەرنىڭ چوڭ-كىچىكلىكى ۋە كەڭلىك چەكلىمىسى بويىچە ئەگىشىڭ</string>\n    <string name=\"threshold\">Threshold</string>\n    <string name=\"quantizationLevels\">مىقدارلاشتۇرۇش دەرىجىسى</string>\n    <string name=\"smooth_toon\">يۇمىلاق چىش</string>\n    <string name=\"toon\">Toon</string>\n    <string name=\"posterize\">Posterize</string>\n    <string name=\"non_maximum_suppression\">ئەڭ چوڭ باستۇرۇش</string>\n    <string name=\"weak_pixel_inclusion\">ئاجىز پىكسېلنى ئۆز ئىچىگە ئالىدۇ</string>\n    <string name=\"lookup\">ئىزدەش</string>\n    <string name=\"convolution3x3\">Convolution 3x3</string>\n    <string name=\"reorder\">Reorder</string>\n    <string name=\"rgb_filter\">RGB سۈزگۈچ</string>\n    <string name=\"false_color\">خاتا رەڭ</string>\n    <string name=\"first_color\">بىرىنچى رەڭ</string>\n    <string name=\"fast_blur\">تېز تۇتۇق</string>\n    <string name=\"second_color\">ئىككىنچى رەڭ</string>\n    <string name=\"blur_size\">چوڭ-كىچىكلىكى</string>\n    <string name=\"blur_center_x\">Blur center x</string>\n    <string name=\"blur_center_y\">Blur center y</string>\n    <string name=\"zoom_blur\">چوڭايتىش</string>\n    <string name=\"color_balance\">رەڭ تەڭپۇڭلۇقى</string>\n    <string name=\"luminance_threshold\">يورۇقلۇق دەرىجىسى</string>\n    <string name=\"activate_files\">سىز ھۆججەت دېتالىنى چەكلىدىڭىز ، ئۇنى بۇ ئىقتىدارنى ئىشلىتىش ئۈچۈن قوزغىتىڭ</string>\n    <string name=\"draw\">سىزىش</string>\n    <string name=\"draw_sub\">سىزما دەپتىرىگە ئوخشاش رەسىمنى سىزىڭ ياكى تەگلىكنىڭ ئۆزىدە سىزىڭ</string>\n    <string name=\"paint_color\">رەڭگى</string>\n    <string name=\"paint_alpha\">رەڭدار ئالفا</string>\n    <string name=\"draw_on_image\">رەسىمگە سىزىڭ</string>\n    <string name=\"draw_on_image_sub\">رەسىم تاللاڭ ۋە ئۇنىڭغا بىر نەرسە سىزىڭ</string>\n    <string name=\"draw_on_background\">تەگلىك سىزىڭ</string>\n    <string name=\"draw_on_background_sub\">تەگلىك رەڭگىنى تاللاڭ ۋە ئۇنىڭ ئۈستىگە سىزىڭ</string>\n    <string name=\"background_color\">تەگلىك رەڭگى</string>\n    <string name=\"cipher\">Cipher</string>\n    <string name=\"cipher_sub\">AES crypto algorithm ئاساسىدىكى ھەرقانداق ھۆججەتنى (رەسىمنىلا ئەمەس) شىفىرلاش ۋە شىفىرلاش</string>\n    <string name=\"pick_file\">ھۆججەت تاللاڭ</string>\n    <string name=\"encrypt\">شىفىرلاش</string>\n    <string name=\"decrypt\">يېشىش</string>\n    <string name=\"pick_file_to_start\">باشلاش ئۈچۈن ھۆججەت تاللاڭ</string>\n    <string name=\"decryption\">شىفىر يېشىش</string>\n    <string name=\"encryption\">شىفىرلاش</string>\n    <string name=\"key\">ئاچقۇچ</string>\n    <string name=\"file_proceed\">ھۆججەت بىر تەرەپ قىلىندى</string>\n    <string name=\"store_file_desc\">بۇ ھۆججەتنى ئۈسكۈنىڭىزگە ساقلاڭ ياكى ئورتاقلىشىش ھەرىكىتىنى ئىشلىتىپ خالىغان يەرگە قويۇڭ</string>\n    <string name=\"features\">Features</string>\n    <string name=\"implementation\">ئەمەلىيلەشتۈرۈش</string>\n    <string name=\"compatibility\">ماسلىشىشچانلىقى</string>\n    <string name=\"features_sub\">ھۆججەتلەرنى مەخپىي شىفىرلاش. ئىشلەنگەن ھۆججەتلەرنى تاللانغان مۇندەرىجىدە ساقلىغىلى ياكى ئورتاقلىشقىلى بولىدۇ. شىفىرلانغان ھۆججەتلەرنىمۇ بىۋاسىتە ئاچقىلى بولىدۇ.</string>\n    <string name=\"implementation_sub\">AES-256 ، GCM ھالىتى ، تاختا يوق ، 12 بايىت ئىختىيارى IV. ئاچقۇچ SHA-3 hashes (256 bit) سۈپىتىدە ئىشلىتىلىدۇ.</string>\n    <string name=\"file_size\">ھۆججەت چوڭلۇقى</string>\n    <string name=\"file_size_sub\">The maximum file size is restricted by the Android OS and available memory, which is device dependent. \\nPlease note: memory is not storage.</string>\n    <string name=\"compatibility_sub\">شۇنىڭغا دىققەت قىلىڭكى ، باشقا ھۆججەت مەخپىيلەشتۈرۈش يۇمشاق دېتالى ياكى مۇلازىمىتىگە ماسلىشىشچانلىقى كاپالەتكە ئىگە ئەمەس. سەل ئوخشىمايدىغان ئاچقۇچلۇق داۋالاش ياكى سىفىرلىق سەپلىمە ماسلاشماسلىقنى كەلتۈرۈپ چىقىرىشى مۇمكىن.</string>\n    <string name=\"invalid_password_or_not_encrypted\">ئىناۋەتسىز مەخپىي نومۇر ياكى تاللانغان ھۆججەت شىفىرلانمايدۇ</string>\n    <string name=\"image_size_warning\">بېرىلگەن كەڭلىك ۋە ئېگىزلىكتىكى رەسىمنى ساقلىماقچى بولسىڭىز OOM خاتالىقىنى كەلتۈرۈپ چىقىرىشى مۇمكىن. بۇنى ئۆزىڭىزنىڭ خەتىرىگە ئاساسەن قىلىڭ ، مەن سىزنى ئاگاھلاندۇرمىدىم دېمەڭ!</string>\n    <string name=\"cache\">Cache</string>\n    <string name=\"cache_size\">Cache size</string>\n    <string name=\"found_s\">تېپىلدى %1$s</string>\n    <string name=\"auto_cache_clearing\">ئاپتوماتىك ساقلىغۇچ تازىلاش</string>\n    <string name=\"auto_cache_clearing_sub\">ئەگەر قوزغىتىلغان ئەپ غەملەكلىرى قوزغالغاندا تازىلىنىدۇ</string>\n    <string name=\"create\">قۇر</string>\n    <string name=\"tools\">قوراللار</string>\n    <string name=\"group_options_by_type\">گۇرۇپپا تاللانمىلىرى</string>\n    <string name=\"group_options_by_type_sub\">گۇرۇپپا تاللاشلىرى ئاساسلىق تىزىملىكتىكى تۈرلەر بويىچە ئۇلارنىڭ تىزىملىكى بويىچە بولىدۇ</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">تاللاش گۇرۇپپىلىرى قوزغىتىلغان ۋاقىتتا ئورۇنلاشتۇرۇشنى ئۆزگەرتەلمەيدۇ</string>\n    <string name=\"edit_screenshot\">ئېكران رەسىمىنى تەھرىرلەش</string>\n    <string name=\"secondary_customization\">ئىككىلەمچى خاسلاشتۇرۇش</string>\n    <string name=\"screenshot\">ئېكران رەسىمى</string>\n    <string name=\"fallback_option\">خاتالىق تاللاش</string>\n    <string name=\"skip\">ئاتلاش</string>\n    <string name=\"copy\">كۆچۈرۈڭ</string>\n    <string name=\"warning_bytes\">%1$s ھالەتتە تېجەش تۇراقسىز بولىدۇ ، چۈنكى ئۇ زىيانسىز فورمات</string>\n    <string name=\"presets_sub\" formatted=\"false\">ئالدىن بېكىتىلگەن 125 نى تاللىغان بولسىڭىز ، رەسىم 100% سۈپەتلىك ئەسلى رەسىمنىڭ% 125 چوڭلۇقىدا ساقلىنىدۇ. ئەگەر ئالدىن بېكىتىلگەن 50 نى تاللىسىڭىز ، ئۇنداقتا رەسىم% 50 چوڭلۇق ۋە% 50 سۈپەتلىك ساقلىنىدۇ.</string>\n    <string name=\"presets_sub_bytes\">بۇ يەردىكى ئالدىن بەلگىلەش چىقىرىش ھۆججىتىنىڭ%% نى بەلگىلەيدۇ ، يەنى 5mb لىق رەسىمگە ئالدىن 50 نى تاللىسىڭىز ، ساقلىغاندىن كېيىن 2.5mb لىق رەسىمگە ئېرىشىسىز</string>\n    <string name=\"randomize_filename\">ھۆججەت نامىنى ئىختىيارىي قىلىڭ</string>\n    <string name=\"randomize_filename_sub\">قوزغىتىلغان چىقىرىش ھۆججەت ئىسمى تولۇق ئىختىيارى بولىدۇ</string>\n    <string name=\"saved_to\">تم الحفظ في المجلد %1$s بالاسم %2$s</string>\n    <string name=\"saved_to_without_filename\">%1$s ھۆججەت قىسقۇچىغا ساقلاندى</string>\n    <string name=\"tg_chat\">تېلېگرامما پاراڭ</string>\n    <string name=\"tg_chat_sub\">بۇ دېتالنى مۇلاھىزە قىلىپ ، باشقا ئىشلەتكۈچىلەرنىڭ تەكلىپ-پىكىرلىرىگە ئېرىشىڭ. بۇ يەردىن سىناق يېڭىلانمىلىرى ۋە چۈشەنچىلىرىگە ئېرىشەلەيسىز.</string>\n    <string name=\"crop_mask\">زىرائەت ماسكىسى</string>\n    <string name=\"aspect_ratio\">نىسبەت نىسبىتى</string>\n    <string name=\"image_crop_mask_sub\">بۇ ماسكا تۈرىنى ئىشلىتىپ بېرىلگەن رەسىمدىن ماسكا ھاسىل قىلىڭ ، ئۇنىڭ ئالفا قانىلى بولۇشى كېرەكلىكىگە دىققەت قىلىڭ</string>\n    <string name=\"backup_and_restore\">زاپاسلاش ۋە ئەسلىگە كەلتۈرۈش</string>\n    <string name=\"backup\">زاپاسلاش</string>\n    <string name=\"restore\">ئەسلىگە كەلتۈرۈش</string>\n    <string name=\"backup_sub\">ئەپ تەڭشەكلىرىڭىزنى ھۆججەتكە زاپاسلاڭ</string>\n    <string name=\"restore_sub\">ئىلگىرى ھاسىل قىلىنغان ھۆججەتتىن ئەپ تەڭشىكىنى ئەسلىگە كەلتۈرۈڭ</string>\n    <string name=\"corrupted_file_or_not_a_backup\">بۇزۇلغان ھۆججەت ياكى زاپاسلاش ئەمەس</string>\n    <string name=\"settings_restored\">تەڭشەك مۇۋەپپەقىيەتلىك ئەسلىگە كەلدى</string>\n    <string name=\"contact_me\">مەن بىلەن ئالاقىلىشىڭ</string>\n    <string name=\"reset_settings_sub\">بۇ تەڭشەكلىرىڭىزنى سۈكۈتتىكى قىممەتكە قايتۇرىدۇ. دىققەت ، يۇقىرىدا تىلغا ئېلىنغان زاپاس ھۆججەت بولمىسا ، بۇنى ئەمەلدىن قالدۇرغىلى بولمايدۇ.</string>\n    <string name=\"delete\">ئۆچۈرۈش</string>\n    <string name=\"delete_color_scheme_warn\">تاللانغان رەڭ لايىھىسىنى ئۆچۈرمەكچى بولۇۋاتىسىز. بۇ مەشغۇلاتنى ئەمەلدىن قالدۇرغىلى بولمايدۇ</string>\n    <string name=\"delete_color_scheme_title\">لايىھەنى ئۆچۈرۈڭ</string>\n    <string name=\"font\">خەت نۇسخىسى</string>\n    <string name=\"text\">تېكىست</string>\n    <string name=\"font_scale\">خەت نۇسخىسى</string>\n    <string name=\"defaultt\">سۈكۈتتىكى</string>\n    <string name=\"using_large_fonts_warn\">چوڭ خەت نۇسخىسىنى ئىشلىتىش UI كاشىلا ۋە مەسىلىلەرنى كەلتۈرۈپ چىقىرىشى مۇمكىن ، بۇ ئوڭشالمايدۇ. ئېھتىيات بىلەن ئىشلىتىڭ.</string>\n    <string name=\"alphabet_and_numbers\">ا ە ب پ ت ج چ خ د ر ز ژ س ش غ ف ق ك گ ڭ ل م ن ھ و ۇ ۆ ۈ ۋ ی 0123456789 !؟</string>\n    <string name=\"emotions\">ھېسسىيات</string>\n    <string name=\"food_and_drink\">يېمەكلىك ۋە ئىچىملىك</string>\n    <string name=\"nature_and_animals\">تەبىئەت ۋە ھايۋانلار</string>\n    <string name=\"objects\">ئوبيېكت</string>\n    <string name=\"symbols\">بەلگىلەر</string>\n    <string name=\"enable_emoji\">Emoji نى قوزغىتىڭ</string>\n    <string name=\"travels_and_places\">ساياھەت ۋە ئورۇن</string>\n    <string name=\"activities\">پائالىيەت</string>\n    <string name=\"background_remover\">تەگلىك ئۆچۈرۈش</string>\n    <string name=\"background_remover_sub\">رەسىم ئارقىلىق تەگلىكنى ئۆچۈرۈڭ ياكى ئاپتوماتىك تاللاشنى ئىشلىتىڭ</string>\n    <string name=\"trim_image\">Trim image</string>\n    <string name=\"keep_exif_sub\">ئەسلى رەسىم مېتا سانلىق مەلۇماتلىرى ساقلىنىدۇ</string>\n    <string name=\"trim_image_sub\">رەسىم ئەتراپىدىكى سۈزۈك بوشلۇقلار رەتلىنىدۇ</string>\n    <string name=\"auto_erase_background\">تەگلىكنى ئاپتوماتىك ئۆچۈرۈڭ</string>\n    <string name=\"restore_image\">رەسىمنى ئەسلىگە كەلتۈرۈش</string>\n    <string name=\"erase_mode\">ئۆچۈرۈش ھالىتى</string>\n    <string name=\"erase_background\">تەگلىكنى ئۆچۈرۈڭ</string>\n    <string name=\"restore_background\">تەگلىكنى ئەسلىگە كەلتۈرۈش</string>\n    <string name=\"blur_radius\">رادىئاتسىيە</string>\n    <string name=\"pipette\">Pipette</string>\n    <string name=\"draw_mode\">سىزىش ھالىتى</string>\n    <string name=\"create_issue\">مەسىلە قۇرۇش</string>\n    <string name=\"something_went_wrong_emphasis\">ئوۋ… بىر نەرسە خاتا بولدى. تۆۋەندىكى تاللاشلارنى ئىشلىتىپ ماڭا خەت يازسىڭىز بولىدۇ ، مەن ھەل قىلىش چارىسى تېپىشقا تىرىشىمەن</string>\n    <string name=\"resize_and_convert\">رازمېرى ۋە ئايلاندۇرۇش</string>\n    <string name=\"resize_and_convert_sub\">بېرىلگەن رەسىملەرنىڭ چوڭ-كىچىكلىكىنى ئۆزگەرتىڭ ياكى باشقا فورماتلارغا ئۆزگەرتىڭ. EXIF مېتا سانلىق مەلۇماتلىرىنى بۇ يەردە تەھرىرلىگىلى بولىدۇ.</string>\n    <string name=\"max_colors_count\">ئەڭ چوڭ رەڭ سانى</string>\n    <string name=\"crashlytics_sub\">بۇ ئەپنىڭ كاشىلا دوكلاتىنى قولدا توپلىشىغا يول قويىدۇ</string>\n    <string name=\"analytics\">Analytics</string>\n    <string name=\"analytics_sub\">نامسىز ئەپ ئىشلىتىش ستاتىستىكىسىنى توپلاشقا يول قويۇڭ</string>\n    <string name=\"image_exif_warning\">ھازىر %1$s فورماتى پەقەت ئاندىرويىدتا EXIF مېتا سانلىق مەلۇماتلىرىنى ئوقۇشقا يول قويىدۇ. چىقىرىلغان رەسىم ساقلانغان ۋاقىتتا مېتا سانلىق مەلۇماتقا ئېرىشەلمەيدۇ.</string>\n    <string name=\"effort\">تىرىشچانلىق</string>\n    <string name=\"effort_sub\">القيمة %1$s تعني ضغطًا سريعًا، مما يؤدي إلى حجم ملف كبير نسبيًا. %2$s يعني ضغطًا أبطأ، مما يؤدي إلى ملف أصغر.</string>\n    <string name=\"wait\">ساقلاپ تۇرۇڭ</string>\n    <string name=\"saving_almost_complete\">تېجەش ئاساسەن تاماملاندى. ھازىر ئەمەلدىن قالدۇرۇش قايتا تېجەشنى تەلەپ قىلىدۇ.</string>\n    <string name=\"updates\">يېڭىلانمىلار</string>\n    <string name=\"allow_betas\">Betas غا يول قويۇڭ</string>\n    <string name=\"allow_betas_sub\">يېڭىلاش تەكشۈرۈش قوزغىتىلغان بولسا beta ئەپ نۇسخىسىنى ئۆز ئىچىگە ئالىدۇ</string>\n    <string name=\"draw_arrows\">يا ئوق سىزىش</string>\n    <string name=\"draw_arrows_sub\">ئەگەر قوزغىتىلغان سىزىش يولى كۆرسەتكۈچ يا ئوق سۈپىتىدە ئىپادىلىنىدۇ</string>\n    <string name=\"brush_softness\">چوتكىلاش يۇمشاق</string>\n    <string name=\"crop_description\">رەسىملەر چوڭ-كىچىكلىكى بويىچە كېسىلىدۇ. ئەگەر رەسىم كىرگۈزۈلگەن ئۆلچەمدىن كىچىك بولسا ، Canvas بېرىلگەن تەگلىك رەڭگى بىلەن كېڭەيتىلىدۇ.</string>\n    <string name=\"donation\">ئىئانە</string>\n    <string name=\"image_stitching\">رەسىم تىكىش</string>\n    <string name=\"image_stitching_sub\">بېرىلگەن رەسىملەرنى بىرلەشتۈرۈپ بىر چوڭ رەسىمگە ئېرىشىڭ</string>\n    <string name=\"pick_at_least_two_images\">كەم دېگەندە 2 پارچە رەسىم تاللاڭ</string>\n    <string name=\"output_image_scale\">چىقىرىش سۈرىتى</string>\n    <string name=\"image_orientation\">رەسىم يۆنىلىشى</string>\n    <string name=\"horizontal\">توغرىسىغا</string>\n    <string name=\"vertical\">ۋېرتىكال</string>\n    <string name=\"scale_small_images_to_large\">كىچىك رەسىملەرنى چوڭايتىڭ</string>\n    <string name=\"scale_small_images_to_large_sub\">كىچىك رەسىملەر قوزغىتىلسا تەرتىپ بويىچە ئەڭ چوڭ رەسىمگە تارتىلىدۇ</string>\n    <string name=\"images_order\">رەسىم تەرتىپى</string>\n    <string name=\"regular\">دائىملىق</string>\n    <string name=\"blur_edges\">قىرغاق</string>\n    <string name=\"blur_edges_sub\">ئەسلى رەسىمنىڭ ئاستىدا تۇتۇق گىرۋەكلەرنى سىزىپ ، قوزغىتىلسا ئەتراپىدىكى بوشلۇقنى تاق رەڭنىڭ ئورنىغا تولدۇرىدۇ</string>\n    <string name=\"pixelation\">Pixelation</string>\n    <string name=\"enhanced_pixelation\">كۈچەيتىلگەن Pixelation</string>\n    <string name=\"stroke_pixelation\">سەكتە Pixelation</string>\n    <string name=\"enhanced_diamond_pixelation\">كۈچەيتىلگەن ئالماس پىكسېل</string>\n    <string name=\"diamond_pixelation\">Diamond Pixelation</string>\n    <string name=\"circle_pixelation\">Circle Pixelation</string>\n    <string name=\"enhanced_circle_pixelation\">كۈچەيتىلگەن چەمبەر پىكسېل</string>\n    <string name=\"replace_color\">رەڭنى ئالماشتۇرۇڭ</string>\n    <string name=\"tolerance\">كەڭ قورساقلىق</string>\n    <string name=\"color_to_replace\">ئالماشتۇرۇشنىڭ رەڭگى</string>\n    <string name=\"target_color\">نىشان رەڭ</string>\n    <string name=\"color_to_remove\">ئۆچۈرۈش ئۈچۈن رەڭ</string>\n    <string name=\"remove_color\">رەڭنى ئۆچۈرۈڭ</string>\n    <string name=\"recode\">Recode</string>\n    <string name=\"pixel_size\">Pixel Size</string>\n    <string name=\"lock_draw_orientation\">قۇلۇپ سىزىش يۆنىلىشى</string>\n    <string name=\"lock_draw_orientation_sub\">ئەگەر رەسىم سىزىش شەكلىدە قوزغىتىلسا ، ئېكران ئايلانمايدۇ</string>\n    <string name=\"check_for_updates\">يېڭىلانمىلارنى تەكشۈرۈڭ</string>\n    <string name=\"palette_style\">Palette style</string>\n    <string name=\"tonal_spot\">Tonal Spot</string>\n    <string name=\"neutral\">بىتەرەپ</string>\n    <string name=\"vibrant\">جۇشقۇن</string>\n    <string name=\"expressive\">ئىپادىلەش</string>\n    <string name=\"rainbow\">Rainbow</string>\n    <string name=\"fruit_salad\">مېۋە سالات</string>\n    <string name=\"fidelity\">Fidelity</string>\n    <string name=\"content\">مەزمۇن</string>\n    <string name=\"tonal_spot_sub\">سۈكۈتتىكى پالتا ئۇسلۇبى ، ئۇ تۆت خىل رەڭنىڭ ھەممىسىنى خاسلاشتۇرالايدۇ ، باشقىلار پەقەت ئاچقۇچلۇق رەڭنى تەڭشىيەلەيدۇ</string>\n    <string name=\"neutral_sub\">يەككە ئۇسلۇبقا قارىغاندا سەل خىروم ئۇسلۇب</string>\n    <string name=\"vibrant_sub\">يۇقىرى ئاۋازلىق باشتېما ، رەڭدارلىقى ئەڭ چوڭ بولۇپ ، باشقىلار ئۈچۈن كۆپەيتىلگەن</string>\n    <string name=\"playful_scheme\">ئوينايدىغان تېما - ئەسلى رەڭنىڭ رەڭگى باشتېمىدا كۆرۈنمەيدۇ</string>\n    <string name=\"monochrome_sub\">يەككە ئۇسلۇب ، رەڭلەر پۈتۈنلەي قارا / ئاق / كۈلرەڭ</string>\n    <string name=\"content_sub\">مەنبە رەڭنى Scheme.primaryContainer غا ئورۇنلاشتۇرىدىغان لايىھە</string>\n    <string name=\"fidelity_sub\">مەزمۇن پىلانىغا ناھايىتى ئوخشايدىغان لايىھە</string>\n    <string name=\"foss_update_checker_warning\">بۇ يېڭىلاش تەكشۈرگۈچى يېڭى يېڭىلانمىنىڭ بار-يوقلۇقىنى تەكشۈرۈش سەۋەبىدىن GitHub غا ئۇلىنىدۇ</string>\n    <string name=\"attention\">دىققەت</string>\n    <string name=\"fading_edges\">Fading Edges</string>\n    <string name=\"disabled\">چەكلەنگەن</string>\n    <string name=\"both\">ھەر ئىككىلىسى</string>\n    <string name=\"invert_colors\">رەڭلەرنى ئۆزگەرتىش</string>\n    <string name=\"invert_colors_sub\">قوزغىتىلسا ئۇسلۇب رەڭلىرىنى مەنپىي رەڭگە ئالماشتۇرىدۇ</string>\n    <string name=\"search_option\">ئىزدەش</string>\n    <string name=\"search_option_sub\">ئاساسىي ئېكراندىكى بارلىق تاللاشلارنى ئىزدەش ئىقتىدارىنى قوزغىتىدۇ</string>\n    <string name=\"pdf_tools\">PDF قوراللىرى</string>\n    <string name=\"pdf_tools_sub\">PDF ھۆججىتى بىلەن مەشغۇلات قىلىڭ: ئالدىن كۆرۈش ، بىر تۈركۈم رەسىملەرگە ئايلاندۇرۇش ياكى بېرىلگەن رەسىملەردىن بىرنى قۇرۇش</string>\n    <string name=\"preview_pdf\">PDF ئالدىن كۆرۈش</string>\n    <string name=\"pdf_to_images\">رەسىملەرگە PDF</string>\n    <string name=\"images_to_pdf\">رەسىملەر PDF</string>\n    <string name=\"pdf_to_images_sub\">بېرىلگەن چىقىرىش فورماتىدا PDF نى رەسىمگە ئايلاندۇرۇڭ</string>\n    <string name=\"preview_pdf_sub\">ئاددىي PDF ئالدىن كۆرۈش</string>\n    <string name=\"images_to_pdf_sub\">بېرىلگەن رەسىملەرنى PDF ھۆججىتىگە قاچىلاڭ</string>\n    <string name=\"mask_filter\">ماسكا سۈزگۈچ</string>\n    <string name=\"mask_filter_sub\">بېرىلگەن نىقابلانغان رايونلارغا سۈزگۈچ زەنجىر ئىشلىتىڭ ، ھەر بىر ماسكا رايونى ئۇنىڭ ئۆزىنىڭ سۈزگۈچنى بەلگىلىيەلەيدۇ</string>\n    <string name=\"masks\">ماسكا</string>\n    <string name=\"add_mask\">ماسكا قوشۇڭ</string>\n    <string name=\"mask_indexed\">ماسكا %d</string>\n    <string name=\"mask_color\">ماسكا رەڭگى</string>\n    <string name=\"mask_preview\">ماسكا ئالدىن كۆرۈش</string>\n    <string name=\"mask_preview_sub\">سىزىلغان سۈزگۈچ نىقاب سىزگە تەخمىنىي نەتىجىنى كۆرسىتىپ بېرىدۇ</string>\n    <string name=\"inverse_fill_type\">تەتۈر تولدۇرۇش تىپى</string>\n    <string name=\"inverse_fill_type_sub\">ئەگەر قوزغىتىلغان بولسا نىقابلانمىغان رايونلارنىڭ ھەممىسى سۈكۈتتىكى ھەرىكەتنىڭ ئورنىغا سۈزۈلىدۇ</string>\n    <string name=\"delete_mask_warn\">تاللانغان سۈزگۈچ نىقابىنى ئۆچۈرمەكچى بولۇۋاتىسىز. بۇ مەشغۇلاتنى ئەمەلدىن قالدۇرغىلى بولمايدۇ</string>\n    <string name=\"delete_mask\">ماسكىنى ئۆچۈرۈڭ</string>\n    <string name=\"full_filter\">تولۇق سۈزگۈچ</string>\n    <string name=\"full_filter_sub\">بېرىلگەن رەسىم ياكى يەككە رەسىمگە سۈزگۈچ زەنجىرىنى ئىشلىتىڭ</string>\n    <string name=\"start_position\">باشلاش</string>\n    <string name=\"center_position\">Center</string>\n    <string name=\"end_position\">ئاخىر</string>\n    <string name=\"simple_variants\">ئاددىي ۋارىيانتلار</string>\n    <string name=\"highlighter\">Highlighter</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">قەلەم</string>\n    <string name=\"privacy_blur\">مەخپىيەتلىك بىلوگى</string>\n    <string name=\"highlighter_sub\">يېرىم سۈزۈك ئۆتكۈر يورۇتۇش يولىنى سىزىڭ</string>\n    <string name=\"neon_sub\">رەسىملىرىڭىزگە ئازراق پارقىراق ئۈنۈم قوشۇڭ</string>\n    <string name=\"pen_sub\">سۈكۈتتىكىسى ، ئەڭ ئاددىي - پەقەت رەڭ</string>\n    <string name=\"privacy_blur_sub\">سىز يوشۇرماقچى بولغان ھەر قانداق نەرسىگە كاپالەتلىك قىلىش ئۈچۈن سىزىلغان يولنىڭ ئاستىدىكى رەسىمنى خىرەلەشتۈرۈڭ</string>\n    <string name=\"pixelation_sub\">مەخپىيەتلىكنى قالايمىقانلاشتۇرۇۋەتكەنگە ئوخشاش ، ئەمما پېكسىللاشنىڭ ئورنىغا</string>\n    <string name=\"containers_shadow\">كونتېينېر</string>\n    <string name=\"containers_shadow_sub\">قاچىلارنىڭ ئارقىسىدا سايە سىزىشنى قوزغىتىدۇ</string>\n    <string name=\"sliders_shadow\">سىيرىلغۇچ</string>\n    <string name=\"switches_shadow\">ئالماشتۇرغۇچ</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">كۇنۇپكىلار</string>\n    <string name=\"sliders_shadow_sub\">سىيرىلغۇچنىڭ ئارقىسىدا سايە سىزىشنى قوزغىتىدۇ</string>\n    <string name=\"switches_shadow_sub\">ئالماشتۇرغۇچنىڭ ئارقىسىدا سايە سىزىشنى قوزغىتىدۇ</string>\n    <string name=\"fabs_shadow_sub\">لەيلىمە ھەرىكەت كۇنۇپكىلىرىنىڭ ئارقىسىدا سايە سىزىشنى قوزغىتىدۇ</string>\n    <string name=\"buttons_shadow_sub\">سۈكۈتتىكى كۇنۇپكىلارنىڭ ئارقىسىدا سايە سىزىشنى قوزغىتىدۇ</string>\n    <string name=\"app_bars_shadow\">App Bars</string>\n    <string name=\"app_bars_shadow_sub\">ئەپ بالدىقىنىڭ ئارقىسىدا سايە سىزىشنى قوزغىتىدۇ</string>\n    <string name=\"value_in_range\">دائىرە قىممىتى %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Auto Rotate</string>\n    <string name=\"auto_rotate_limits_sub\">رەسىم يۆنىلىشى ئۈچۈن چەك ساندۇقىنىڭ قوللىنىلىشىغا يول قويىدۇ</string>\n    <string name=\"draw_path_mode\">يول ھالىتىنى سىزىڭ</string>\n    <string name=\"double_line_arrow\">قوش سىزىقلىق ئوق</string>\n    <string name=\"free_drawing\">ھەقسىز رەسىم سىزىش</string>\n    <string name=\"double_arrow\">قوش ئوق</string>\n    <string name=\"line_arrow\">Line Arrow</string>\n    <string name=\"arrow\">يا ئوق</string>\n    <string name=\"line\">Line</string>\n    <string name=\"free_drawing_sub\">كىرگۈزۈش قىممىتى سۈپىتىدە يول سىزىدۇ</string>\n    <string name=\"line_sub\">باشلىنىش نۇقتىسىدىن ئاخىرىغىچە بىر سىزىق سۈپىتىدە يول سىزىدۇ</string>\n    <string name=\"line_arrow_sub\">ئوقنى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە بىر قۇر قىلىپ سىزىدۇ</string>\n    <string name=\"arrow_sub\">بېرىلگەن يولدىن ئوقنى كۆرسىتىدۇ</string>\n    <string name=\"double_line_arrow_sub\">قوش يۆنىلىشلىك ئوقنى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىق قىلىپ سىزىدۇ</string>\n    <string name=\"double_arrow_sub\">بېرىلگەن يولدىن قوش يۆنىلىشلىك يا ئوق سىزىدۇ</string>\n    <string name=\"outlined_oval\">البيضاوي المبين</string>\n    <string name=\"outlined_rect\">كۆرسىتىلگەن تۈز</string>\n    <string name=\"oval\">بيضاوي</string>\n    <string name=\"rect\">تۈز</string>\n    <string name=\"rect_sub\">باشلىنىش نۇقتىسىدىن ئاخىرقى نۇقتىغا توغرىلىنىدۇ</string>\n    <string name=\"oval_sub\">تۇخۇمنى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىدۇ</string>\n    <string name=\"free\">ھەقسىز</string>\n    <string name=\"horizontal_grid\">Horizontal Grid</string>\n    <string name=\"vertical_grid\">Vertical Grid</string>\n    <string name=\"outlined_oval_sub\">تۇخۇمنى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىدۇ</string>\n    <string name=\"outlined_rect_sub\">سىزىقنى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىدۇ</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">بېرىلگەن يول بىلەن تولغان يولنى سىزىدۇ</string>\n    <string name=\"stitch_mode\">تىكىش ھالىتى</string>\n    <string name=\"rows_count\">قۇر سانى</string>\n    <string name=\"columns_count\">ستون سانى</string>\n    <string name=\"no_such_directory\">لم يتم العثور على دليل \\\"%1$s\\\"، لقد قمنا بتحويله إلى الدليل الافتراضي، يرجى حفظ الملف مرة أخرى</string>\n    <string name=\"auto_pin\">Auto pin</string>\n    <string name=\"clipboard\">چاپلاش تاختىسى</string>\n    <string name=\"auto_pin_sub\">قوزغىتىلغان بولسا ئاپتوماتىك ھالدا ساقلانغان رەسىمنى چاپلاش تاختىسىغا قوشىدۇ</string>\n    <string name=\"vibration\">تەۋرىنىش</string>\n    <string name=\"vibration_strength\">تەۋرىنىش كۈچى</string>\n    <string name=\"overwrite_file_requirements\">Explorer \\\" رەسىم مەنبەسىنى ئىشلىتىشكە ئېھتىياجلىق ھۆججەتلەرنى قاپلىۋېلىش ئۈچۈن ، رەسىملەرنى قايتا سىناپ بېقىڭ ، بىز رەسىم مەنبەسىنى لازىملىق ھۆججەتكە ئۆزگەرتتۇق.</string>\n    <string name=\"overwrite_files\">ھۆججەتلەرنى قاپلىۋېتىڭ</string>\n    <string name=\"overwrite_files_sub\">سيتم استبدال الملف الأصلي بملف جديد بدلاً من حفظه في المجلد المحدد، ويجب أن يكون هذا الخيار مصدر الصورة هو Explorer أو GetContent، وعند تبديل هذا، سيتم تعيينه تلقائيًا</string>\n    <string name=\"empty\">قۇرۇق</string>\n    <string name=\"suffix\">Suffix</string>\n    <string name=\"scale_mode\">كۆلەم ھالىتى</string>\n    <string name=\"bilinear\">Bilinear</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">مىچىل</string>\n    <string name=\"nearest\">ئەڭ يېقىن</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">Basic</string>\n    <string name=\"default_value\">كۆڭۈلدىكى قىممەت</string>\n    <string name=\"bilinear_sub\">سىزىقلىق (ياكى قوش يۆنىلىشلىك ، ئىككى ئۆلچەملىك) ئارىلىشىش ئادەتتە رەسىمنىڭ چوڭ-كىچىكلىكىنى ئۆزگەرتىشكە پايدىلىق ، ئەمما بەزى ئىنچىكە ھالقىلارنىڭ يۇمشىشىنى كەلتۈرۈپ چىقىرىدۇ ، يەنىلا مەلۇم دەرىجىدە چېتىلىپ قالىدۇ.</string>\n    <string name=\"bicubic_sub\">تېخىمۇ ياخشى كۆلەملەشتۈرۈش ئۇسۇللىرى Lanczos قايتا قۇرۇش ۋە Mitchell-Netravali سۈزگۈچنى ئۆز ئىچىگە ئالىدۇ</string>\n    <string name=\"nearest_sub\">چوڭ-كىچىكلىكىنى ئاشۇرۇشنىڭ ئەڭ ئاددىي ئۇسۇللىرىنىڭ بىرى ، ھەر بىر پېكسىلنى ئوخشاش رەڭدىكى بىر قانچە پېكسىلغا ئالماشتۇرۇش</string>\n    <string name=\"basic_sub\">بارلىق ئەپلەردە دېگۈدەك ئىشلىتىلىدىغان ئەڭ ئاددىي ئاندىرويىد كىچىكلىتىش ھالىتى</string>\n    <string name=\"catmull_sub\">بىر يۈرۈش كونترول نۇقتىلىرىنى ئوڭۇشلۇق ئۆزئارا باغلاش ۋە قايتا قۇرۇش ئۇسۇلى ، ئادەتتە كومپيۇتېر گرافىكىدا سىلىق ئەگرى سىزىق ھاسىل قىلىشقا ئىشلىتىلىدۇ</string>\n    <string name=\"hann_sub\">كۆزنەك ئىقتىدارى دائىم سىگنال بىر تەرەپ قىلىشتا قوللىنىلىپ ، سپېكترا ئېقىپ كېتىشنى ئەڭ تۆۋەن چەككە چۈشۈرۈپ ، سىگنالنىڭ گىرۋىكىنى چېكىش ئارقىلىق چاستوتا ئانالىزىنىڭ توغرىلىقىنى ئۆستۈرىدۇ.</string>\n    <string name=\"hermite_sub\">ماتېماتىكىلىق ئۆزئارا بىرلەشتۈرۈش تېخنىكىسى ئەگرى سىزىقنىڭ ئاخىرقى نۇقتىسىدىكى قىممەت ۋە تۇغۇندى مەھسۇلاتلارنى ئىشلىتىپ سىلىق ۋە ئۈزلۈكسىز ئەگرى سىزىق ھاسىل قىلىدۇ.</string>\n    <string name=\"lanczos_sub\">پىكسېل قىممىتىگە ئېغىر دەرىجىدىكى سىنك فۇنكسىيەسىنى قوللىنىش ئارقىلىق يۇقىرى سۈپەتلىك ئۆزئارا ماسلىشىشنى ساقلايدىغان ئۇسۇل</string>\n    <string name=\"mitchell_sub\">تەڭشىگىلى بولىدىغان پارامېتىرلار ئارقىلىق تەۋرىنىش سۈزگۈچنى ئىشلىتىپ ، كىچىكلىتىلگەن رەسىمدىكى ئۆتكۈرلۈك ۋە قارشىلىشىشقا قارشى تەڭپۇڭلۇقنى ئەمەلگە ئاشۇرۇش.</string>\n    <string name=\"spline_sub\">ئوخشاش ئېنىقلىما بېرىلگەن كۆپ قۇتۇپلۇق ئىقتىداردىن پايدىلىنىپ ئەگرى سىزىق ياكى يۈزنى سىلىق ئۆز-ئارا ماسلاشتۇرىدۇ ۋە يېقىنلاشتۇرىدۇ ، جانلىق ۋە ئۈزلۈكسىز شەكىل ئىپادىلەيدۇ.</string>\n    <string name=\"only_clip\">پەقەت Clip</string>\n    <string name=\"only_clip_sub\">ساقلاشقا ساقلاش ئەمەلگە ئاشمايدۇ ، رەسىم پەقەت چاپلاش تاختىسىغا سېلىشقا ئۇرۇنىدۇ</string>\n    <string name=\"restore_background_sub\">چوتكا ئۆچۈرۈشنىڭ ئورنىغا تەگلىكنى ئەسلىگە كەلتۈرىدۇ</string>\n    <string name=\"recognize_text\">OCR (تېكىستنى تونۇش)</string>\n    <string name=\"recognize_text_sub\">بېرىلگەن رەسىمدىن تېكىستنى ئېتىراپ قىلىڭ ، 120+ تىل قوللايدۇ</string>\n    <string name=\"picture_has_no_text\">رەسىمنىڭ تېكىستى يوق ، ياكى ئەپ تاپالمىدى</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">تونۇش تىپى</string>\n    <string name=\"fast\">تېز</string>\n    <string name=\"standard\">ئۆلچەملىك</string>\n    <string name=\"best\">ئەڭ ياخشى</string>\n    <string name=\"no_data\">سانلىق مەلۇمات يوق</string>\n    <string name=\"download_description\">من أجل التشغيل السليم لـ Tesseract OCR، يجب تنزيل بيانات التدريب الإضافية (%1$s) على جهازك. \\nهل تريد تنزيل بيانات %2$s؟</string>\n    <string name=\"download\">چۈشۈرۈش</string>\n    <string name=\"no_connection\">ئۇلىنىش يوق ، ئۇنى تەكشۈرۈپ پويىز مودېللىرىنى چۈشۈرۈش ئۈچۈن قايتا سىناڭ</string>\n    <string name=\"downloaded_languages\">چۈشۈرۈلگەن تىللار</string>\n    <string name=\"available_languages\">ئىشلەتكىلى بولىدىغان تىللار</string>\n    <string name=\"segmentation_mode\">بۆلەك ھالىتى</string>\n    <string name=\"use_pixel_switch\">Pixel Switch نى ئىشلىتىڭ</string>\n    <string name=\"use_pixel_switch_sub\">Pixel غا ئوخشاش ئالماشتۇرغۇچ google نىڭ ماتېرىيالىنىڭ ئورنىغا ئىشلىتىلىدۇ</string>\n    <string name=\"saved_to_original\">ئەسلى مەنزىلدە {8 name ئىسمى يېزىلغان ھۆججەتتمت الكتابة فوق الملف بالاسم %1$s في الوجهة الأصلية</string>\n    <string name=\"magnifier\">Magnifier</string>\n    <string name=\"magnifier_sub\">تېخىمۇ ياخشى زىيارەت قىلىش ئۈچۈن رەسىم سىزىش شەكلىدە بارماقنىڭ ئۈستىدىكى چوڭايتىشنى قوزغىتىدۇ</string>\n    <string name=\"force_exif_widget_initial_value_sub\">كىچىك قوراللار دەسلەپتە تەكشۈرۈلىدۇ</string>\n    <string name=\"force_exif_widget_initial_value\">دەسلەپكى قىممەتنى زورلاڭ</string>\n    <string name=\"allow_multiple_languages\">كۆپ خىل تىللارغا يول قويۇڭ</string>\n    <string name=\"slide\">تام تەسۋىر</string>\n    <string name=\"side_by_side\">Side by Side</string>\n    <string name=\"toggle_tap\">Toggle Tap</string>\n    <string name=\"transparency\">Transparency</string>\n    <string name=\"rate_app\">Rate App</string>\n    <string name=\"rate\">باھا</string>\n    <string name=\"rate_app_sub\">بۇ دېتال پۈتۈنلەي ھەقسىز ، ئەگەر ئۇنىڭ تېخىمۇ چوڭ بولۇشىنى ئۈمىد قىلسىڭىز ، Github on تۈرىنى باشلاڭ</string>\n    <string name=\"segmentation_mode_osd_only\">يۆنىلىش &amp; قوليازما بايقاش</string>\n    <string name=\"segmentation_mode_auto_osd\">ئاپتوماتىك يۆنىلىش &amp; قوليازما بايقاش</string>\n    <string name=\"segmentation_mode_auto_only\">پەقەت ئاپتوماتىك</string>\n    <string name=\"segmentation_mode_auto\">ئاپتوماتىك</string>\n    <string name=\"segmentation_mode_single_column\">يەككە ئىستون</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">تاق بۆلەك تىك تېكىست</string>\n    <string name=\"segmentation_mode_single_block\">تاق بۆلەك</string>\n    <string name=\"segmentation_mode_single_line\">يەككە سىزىق</string>\n    <string name=\"segmentation_mode_single_word\">يەككە سۆز</string>\n    <string name=\"segmentation_mode_circle_word\">ئايلانما سۆز</string>\n    <string name=\"segmentation_mode_single_char\">Single char</string>\n    <string name=\"segmentation_mode_sparse_text\">قىسقا تېكىست</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">شالاڭ تېكىست يۆنىلىشى &amp; قوليازما بايقاش</string>\n    <string name=\"segmentation_mode_raw_line\">خام سىزىق</string>\n    <string name=\"delete_language_sub\">هل تريد حذف بيانات التدريب على التعرف الضوئي على الحروف الخاصة باللغة \\\"%1$s\\\" لجميع أنواع التعرف، أم للنوع المحدد فقط (%2$s)؟</string>\n    <string name=\"current\">نۆۋەتتىكى</string>\n    <string name=\"all\">ھەممىسى</string>\n    <string name=\"gradient_maker\">Gradient Maker</string>\n    <string name=\"gradient_maker_sub\">خاسلاشتۇرۇلغان رەڭ ۋە كۆرۈنۈش تىپى بىلەن بېرىلگەن چىقىرىش چوڭلۇقىنىڭ دەرىجىسىنى تەدرىجىي ھاسىل قىلىڭ</string>\n    <string name=\"gradient_type_linear\">Linear</string>\n    <string name=\"gradient_type_radial\">Radial</string>\n    <string name=\"gradient_type_sweep\">Sweep</string>\n    <string name=\"gradient_type\">Gradient Type</string>\n    <string name=\"center_x\">Center X.</string>\n    <string name=\"center_y\">Center Y.</string>\n    <string name=\"tile_mode\">Tile Mode</string>\n    <string name=\"tile_mode_repeated\">تەكرارلاندى</string>\n    <string name=\"tile_mode_mirror\">ئەينەك</string>\n    <string name=\"tile_mode_clamp\">Clamp</string>\n    <string name=\"tile_mode_decal\">Decal</string>\n    <string name=\"color_stops\">رەڭ توختايدۇ</string>\n    <string name=\"add_color\">رەڭ قوشۇڭ</string>\n    <string name=\"properties\">خاسلىقى</string>\n    <string name=\"brightness_enforcement\">يورۇقلۇقنى ئىجرا قىلىش</string>\n    <string name=\"screen\">ئېكران</string>\n    <string name=\"gradient_maker_type_image\">Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_sub\">بېرىلگەن رەسىمنىڭ ئۈستىدىكى ھەر قانداق گرادېنتنى تۈزۈڭ</string>\n    <string name=\"transformations\">ئۆزگەرتىش</string>\n    <string name=\"camera\">كامېرا</string>\n    <string name=\"camera_sub\">رەسىمگە تارتىش ئۈچۈن كامېرا ئىشلىتىپ ، بۇ رەسىم مەنبەسىدىن پەقەت بىرلا رەسىمگە ئېرىشكىلى بولىدىغانلىقىغا دىققەت قىلىڭ</string>\n    <string name=\"repeat_watermark\">سۇ بەلگىسىنى تەكرارلاڭ</string>\n    <string name=\"watermarking\">سۇ بەلگىسى</string>\n    <string name=\"watermarking_sub\">رەسىملەرنى خاسلاشتۇرغىلى بولىدىغان تېكىست / رەسىم سۇ بەلگىسى بىلەن يېپىش</string>\n    <string name=\"repeat_watermark_sub\">بېرىلگەن ئورۇنغا يەككە ئورنىدا رەسىم بەلگىسىنى تەكرارلايدۇ</string>\n    <string name=\"offset_x\">Offset X.</string>\n    <string name=\"offset_y\">Offset Y.</string>\n    <string name=\"watermarking_image_sub\">بۇ رەسىم سۇ بەلگىسى ئۈچۈن ئەندىزە سۈپىتىدە ئىشلىتىلىدۇ</string>\n    <string name=\"text_color\">تېكىست رەڭ</string>\n    <string name=\"overlay_mode\">قاپلاش ھالىتى</string>\n    <string name=\"gif_tools\">GIF قوراللىرى</string>\n    <string name=\"gif_tools_sub\">رەسىملەرنى GIF رەسىمىگە ئايلاندۇرۇڭ ياكى بېرىلگەن GIF رەسىمدىن رامكا ئېلىڭ</string>\n    <string name=\"gif_type_to_image\">رەسىملەرگە GIF</string>\n    <string name=\"gif_type_to_image_sub\">GIF ھۆججىتىنى بىر تۈركۈم رەسىملەرگە ئايلاندۇرۇڭ</string>\n    <string name=\"gif_type_to_gif_sub\">بىر تۈركۈم رەسىملەرنى GIF ھۆججىتىگە ئايلاندۇرۇڭ</string>\n    <string name=\"gif_type_to_gif\">GIF غا رەسىملەر</string>\n    <string name=\"select_gif_image_to_start\">باشلاش ئۈچۈن GIF رەسىمىنى تاللاڭ</string>\n    <string name=\"use_size_of_first_frame\">بىرىنچى رامكىنىڭ چوڭ-كىچىكلىكىنى ئىشلىتىڭ</string>\n    <string name=\"confetti\">Confetti</string>\n    <string name=\"use_size_of_first_frame_sub\">بەلگىلەنگەن چوڭلۇقنى بىرىنچى رامكا ئۆلچىمى بىلەن ئالماشتۇرۇڭ</string>\n    <string name=\"repeat_count\">قايتىلاش</string>\n    <string name=\"frame_delay\">Frame Delay</string>\n    <string name=\"millis\">millis</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Lasso نى ئىشلىتىڭ</string>\n    <string name=\"use_lasso_sub\">ئۆچۈرۈش ئۈچۈن Lasso نى رەسىم سىزىش ھالىتىگە ئوخشاش ئىشلىتىدۇ</string>\n    <string name=\"original_image_preview_alpha\">ئەسلى رەسىمنى كۆرۈش ئالفا</string>\n    <string name=\"confetti_sub\">Confetti تېجەش ، ئورتاقلىشىش ۋە باشقا دەسلەپكى ھەرىكەتلەردە كۆرسىتىلىدۇ</string>\n    <string name=\"secure_mode\">بىخەتەر ھالەت</string>\n    <string name=\"secure_mode_sub\">چىقىشتىكى مەزمۇننى يوشۇرىدۇ ، ئېكراننىمۇ خاتىرىلىگىلى ياكى خاتىرىلىگىلى بولمايدۇ</string>\n    <string name=\"exit\">چىقىش</string>\n    <string name=\"preview_closing\">ئەگەر ئالدىن كۆرۈشتىن ئايرىلسىڭىز ، رەسىملەرنى قايتا قوشۇشىڭىز كېرەك</string>\n    <string name=\"dithering\">Dithering</string>\n    <string name=\"quantizier\">Quantizier</string>\n    <string name=\"gray_scale\">كۈلرەڭ تارازا</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Sight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg Dithering</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke Dithering</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">ئىككى قاتار Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"atkinson_dithering\">Atkinson Dithering</string>\n    <string name=\"stucki_dithering\">Stucki Dithering</string>\n    <string name=\"burkes_dithering\">Burkes Dithering</string>\n    <string name=\"false_floyd_steinberg_dithering\">يالغان Floyd Steinberg Dithering</string>\n    <string name=\"left_to_right_dithering\">سولدىن ئوڭغا بۇرۇلۇش</string>\n    <string name=\"random_dithering\">Random Dithering</string>\n    <string name=\"simple_threshold_dithering\">ئاددىي بوسۇغا يۆلىنىش</string>\n    <string name=\"sigma\">سىگما</string>\n    <string name=\"spatial_sigma\">بوشلۇقتىكى سىگما</string>\n    <string name=\"median_blur\">Median Blur</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">ئايرىم ئېنىقلانغان ئىككى قۇتۇپلۇق كۆپ ئىقتىدارلىق فۇنكسىيەدىن پايدىلىنىپ ، ئەگرى سىزىق ياكى يۈزنى سىلىق ئۆز-ئارا ماسلاشتۇرىدۇ ۋە يېقىنلاشتۇرىدۇ ، جانلىق ۋە ئۈزلۈكسىز شەكىل ئىپادىلەيدۇ.</string>\n    <string name=\"native_stack_blur\">Native Stack Blur</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"glitch\">Glitch</string>\n    <string name=\"amount\">سومما</string>\n    <string name=\"seed\">ئۇرۇق</string>\n    <string name=\"anaglyph\">Anaglyph</string>\n    <string name=\"noise\">شاۋقۇن</string>\n    <string name=\"pixel_sort\">Pixel Sort</string>\n    <string name=\"shuffle\">Shuffle</string>\n    <string name=\"enhanced_glitch\">كۈچەيتىلگەن Glitch</string>\n    <string name=\"channel_shift_x\">Channel Shift X.</string>\n    <string name=\"channel_shift_y\">Channel Shift Y.</string>\n    <string name=\"corruption_size\">چىرىكلىك كۆلىمى</string>\n    <string name=\"corruption_shift_x\">چىرىكلىك Shift X.</string>\n    <string name=\"corruption_shift_y\">چىرىكلىك Shift Y.</string>\n    <string name=\"tent_blur\">Tent Blur</string>\n    <string name=\"side_fade\">Side Fade</string>\n    <string name=\"side\">يان تەرەپ</string>\n    <string name=\"top\">ئۈستى</string>\n    <string name=\"bottom\">ئاستى</string>\n    <string name=\"strength\">كۈچ</string>\n    <string name=\"erode\">Erode</string>\n    <string name=\"anisotropic_diffusion\">Anisotropic Diffusion</string>\n    <string name=\"diffusion\">Diffusion</string>\n    <string name=\"conduction\">Conduct</string>\n    <string name=\"horizontal_wind_stagger\">گورىزونتال شامال تەۋرىنىشى</string>\n    <string name=\"fast_bilaterial_blur\">Fast Bilaterial Blur</string>\n    <string name=\"poisson_blur\">Poisson Blur</string>\n    <string name=\"logarithmic_tone_mapping\">لوگارىزىملىق ئاۋاز خەرىتىسى</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES كىنو ئاۋاز خەرىتىسى</string>\n    <string name=\"crystallize\">Crystallize</string>\n    <string name=\"stroke_color\">سەكتە رەڭگى</string>\n    <string name=\"fractal_glass\">سۇنۇق ئەينەك</string>\n    <string name=\"amplitude\">Amplitude</string>\n    <string name=\"marble\">مەرمەر</string>\n    <string name=\"turbulence\">تۇراقسىزلىق</string>\n    <string name=\"oil\">نېفىت</string>\n    <string name=\"water_effect\">Water Effect</string>\n    <string name=\"just_size\">چوڭلۇقى</string>\n    <string name=\"frequency_x\">چاستوتا X.</string>\n    <string name=\"frequency_y\">Frequency Y.</string>\n    <string name=\"amplitude_x\">Amplitude X.</string>\n    <string name=\"amplitude_y\">Amplitude Y.</string>\n    <string name=\"perlin_distortion\">پېرلىن بۇرمىلىنىش</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone خەرىتىسى</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess Tone Mapping</string>\n    <string name=\"speed\">سۈرئەت</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">رەڭ Matrix 4x4</string>\n    <string name=\"color_matrix_3x3\">رەڭ Matrix 3x3</string>\n    <string name=\"simple_effects\">ئاددىي ئۈنۈم</string>\n    <string name=\"deutaromaly\">Deutaromaly</string>\n    <string name=\"protonomaly\">Protonomaly</string>\n    <string name=\"vintage\">Vintage</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Night Vision</string>\n    <string name=\"warm\">ئىللىق</string>\n    <string name=\"cool\">Cool</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"grain\">دان</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Achromatomaly</string>\n    <string name=\"achromatopsia\">Achromatopsia</string>\n    <string name=\"unsharp\">Unsharp</string>\n    <string name=\"pastel\">Pastel</string>\n    <string name=\"orange_haze\">ئاپېلسىن تۇمان</string>\n    <string name=\"pink_dream\">ھالرەڭ چۈش</string>\n    <string name=\"golden_hour\">ئالتۇن سائەت</string>\n    <string name=\"hot_summer\">ئىسسىق ياز</string>\n    <string name=\"purple_mist\">بىنەپشە تۇمان</string>\n    <string name=\"sunrise\">Sunrise</string>\n    <string name=\"colorful_swirl\">رەڭلىك سۋرەت</string>\n    <string name=\"soft_spring_light\">يۇمشاق بۇلاق نۇرى</string>\n    <string name=\"autumn_tones\">كۈزلۈك ئاھاڭ</string>\n    <string name=\"lavender_dream\">Lavender Dream</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">لىمون نۇرى</string>\n    <string name=\"spectral_fire\">Spectral Fire</string>\n    <string name=\"night_magic\">Night Magic</string>\n    <string name=\"fantasy_landscape\">فانتازىيىلىك مەنزىرە</string>\n    <string name=\"color_explosion\">رەڭ پارتىلاش</string>\n    <string name=\"electric_gradient\">Electric Gradient</string>\n    <string name=\"caramel_darkness\">Caramel Darkness</string>\n    <string name=\"futuristic_gradient\">Futuristic Gradient</string>\n    <string name=\"green_sun\">يېشىل قۇياش</string>\n    <string name=\"rainbow_world\">Rainbow World</string>\n    <string name=\"deep_purple\">Deep Purple</string>\n    <string name=\"space_portal\">ئالەم بوشلۇقى</string>\n    <string name=\"red_swirl\">Red Swirl</string>\n    <string name=\"digital_code\">رەقەملىك كود</string>\n    <string name=\"bokeh\">Bokeh</string>\n    <string name=\"random_emojis_sub\">ئەپ بالدىقى emoji تاللانغاننى ئىشلىتىشنىڭ ئورنىغا تاسادىپىي ئۆزگەرتىلىدۇ</string>\n    <string name=\"random_emojis\">ئىختىيارى Emojis</string>\n    <string name=\"random_emojis_error\">Emojis چەكلەنگەندە تاسادىپىي emoji تاللاشقا بولمايدۇ</string>\n    <string name=\"emoji_selection_error\">ئىختىيارىي تاللانغان ۋاقىتتا emoji نى تاللىيالمايدۇ</string>\n    <string name=\"old_tv\">Old Tv</string>\n    <string name=\"shuffle_blur\">Shuffle Blur</string>\n    <string name=\"favorite\">ئامراق</string>\n    <string name=\"no_favorite_filters\">ياقتۇرىدىغان سۈزگۈچلەر تېخى قوشۇلمىدى</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">ئۆتكۈنچى</string>\n    <string name=\"peak\">چوققا</string>\n    <string name=\"color_anomaly\">Color Anomaly</string>\n    <string name=\"images_overwritten\">ئەسلى مەنزىلگە يېزىلغان رەسىملەر</string>\n    <string name=\"cannot_change_image_format\">ھۆججەتلەرنى قايتا يېزىش ئىقتىدارى قوزغىتىلغاندا رەسىم فورماتىنى ئۆزگەرتەلمەيدۇ</string>\n    <string name=\"emoji_as_color_scheme\">Emoji رەڭ لايىھىسى سۈپىتىدە</string>\n    <string name=\"emoji_as_color_scheme_sub\">Emoji دەسلەپكى رەڭنى قولدا بېكىتىلگەن رەڭنىڭ ئورنىغا ئەپ رەڭ لايىھىسى سۈپىتىدە ئىشلىتىڭ</string>\n    <string name=\"icon_shape_sub\">كارتىنىڭ ئالدىنقى سىنبەلگىسى ئاستىدا تاللانغان شەكىلدىكى قاچا قوشىدۇ</string>\n    <string name=\"icon_shape\">سىنبەلگە شەكلى</string>\n    <string name=\"by_bytes_resize\">ئېغىرلىقى بويىچە چوڭايتىڭ</string>\n    <string name=\"max_bytes\">KB دىكى ئەڭ چوڭ چوڭلۇقى</string>\n    <string name=\"by_bytes_resize_sub\">KB دا بېرىلگەن چوڭلۇقتىكى رەسىمنىڭ چوڭ-كىچىكلىكىنى ئۆزگەرتىڭ</string>\n    <string name=\"compare\">سېلىشتۇرۇش</string>\n    <string name=\"compare_sub\">بېرىلگەن ئىككى رەسىمنى سېلىشتۇرۇڭ</string>\n    <string name=\"pick_two_images\">باشلاش ئۈچۈن ئىككى رەسىمنى تاللاڭ</string>\n    <string name=\"pick_images\">رەسىملەرنى تاللاڭ</string>\n    <string name=\"settings\">تەڭشەك</string>\n    <string name=\"night_mode\">كەچلىك ھالەت</string>\n    <string name=\"dark\">قاراڭغۇ</string>\n    <string name=\"light\">نۇر</string>\n    <string name=\"system\">سىستېما</string>\n    <string name=\"dynamic_colors\">ھەرىكەتچان رەڭلەر</string>\n    <string name=\"customization\">خاسلاشتۇرۇش</string>\n    <string name=\"allow_image_monet\">رەسىم پۇلغا يول قويۇڭ</string>\n    <string name=\"allow_image_monet_sub\">ئەگەر قوزغىتىلغان بولسا ، تەھرىرلەيدىغان رەسىمنى تاللىسىڭىز ، بۇ رەسىمگە ئەپ رەڭلىرى قوللىنىلىدۇ</string>\n    <string name=\"language\">تىل</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">ھەرىكەتچان رەڭلەر ئېچىلغاندا ئەپ رەڭ لايىھىسىنى ئۆزگەرتەلمەيدۇ</string>\n    <string name=\"pick_accent_color\">ئەپ تېمىسى تاللانغان رەڭنى ئاساس قىلىدۇ</string>\n    <string name=\"email\">ئېلخەت</string>\n    <string name=\"watermark_type\">سۇ بەلگىسى تىپى</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomaly</string>\n    <string name=\"image_format\">رەسىم فورماتى</string>\n    <string name=\"copy_as_compose_code\">«Jetpack Compose» كودى سۈپىتىدە كۆچۈرۈڭ</string>\n    <string name=\"material_you_sub\">رەسىمدىن «Material You » پالتىنى ھاسىل قىلىدۇ</string>\n    <string name=\"dark_colors\">قېنىق رەڭلەر</string>\n    <string name=\"dark_colors_sub\">يورۇقلۇق ۋارىيانتىنىڭ ئورنىغا كەچلىك ھالەت رەڭ لايىھىسىنى ئىشلىتىدۇ</string>\n    <string name=\"ring_blur\">ئۈزۈك تۇتۇق</string>\n    <string name=\"cross_blur\">كرېست تۇتۇق</string>\n    <string name=\"circle_blur\">چەمبىرەك تۇتۇق</string>\n    <string name=\"star_blur\">چولپان تۇتۇق</string>\n    <string name=\"linear_tilt_shift\">سىزىقلىق يانتۇ بۇرۇلۇش</string>\n    <string name=\"tags_to_remove\">ئۆچۈرۈش ئۈچۈن خەتكۈچلەر</string>\n    <string name=\"apng_tools\">APNG قوراللىرى</string>\n    <string name=\"apng_tools_sub\">رەسىملەرنى APNG رەسىمىگە ئايلاندۇرۇڭ ياكى بېرىلگەن APNG رەسىمدىن رامكا ئېلىڭ</string>\n    <string name=\"apng_type_to_image\">رەسىملەرگە APNG</string>\n    <string name=\"apng_type_to_apng\">APNG غا رەسىملەر</string>\n    <string name=\"select_apng_image_to_start\">باشلاش ئۈچۈن APNG رەسىمىنى تاللاڭ</string>\n    <string name=\"motion_blur\">ھەرىكەت</string>\n    <string name=\"apng_type_to_image_sub\">APNG ھۆججىتىنى بىر تۈركۈم رەسىملەرگە ئايلاندۇرۇڭ</string>\n    <string name=\"apng_type_to_apng_sub\">بىر تۈركۈم رەسىملەرنى APNG ھۆججىتىگە ئايلاندۇرۇڭ</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">بېرىلگەن ھۆججەت ياكى رەسىملەردىن Zip ھۆججىتى قۇرۇش</string>\n    <string name=\"drag_handle_width\">سۆرەش كەڭلىكى</string>\n    <string name=\"confetti_type\">Confetti Type</string>\n    <string name=\"festive\">بايرام</string>\n    <string name=\"explode\">پارتىلاش</string>\n    <string name=\"rain\">يامغۇر</string>\n    <string name=\"corners\">بۇلۇڭلار</string>\n    <string name=\"jxl_tools\">JXL قوراللىرى</string>\n    <string name=\"jxl_tools_sub\">سۈپەتسىز زىيانسىز JXL ~ JPEG كودلاشنى ئىجرا قىلىڭ ياكى GIF / APNG نى JXL كارتونغا ئايلاندۇرۇڭ</string>\n    <string name=\"jxl_type_to_jpeg\">JXL دىن JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">JXL دىن JPEG غا زىيانسىز كودلاشنى ئىجرا قىلىڭ</string>\n    <string name=\"jpeg_type_to_jxl_sub\">JPEG دىن JXL غا زىيانسىز كودلاشنى ئىجرا قىلىڭ</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG دىن JXL</string>\n    <string name=\"select_jxl_image_to_start\">باشلاش ئۈچۈن JXL رەسىمىنى تاللاڭ</string>\n    <string name=\"fast_gaussian_blur_2d\">Fast Gaussian Blur 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Fast Gaussian Blur 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Fast Gaussian Blur 4D</string>\n    <string name=\"auto_paste\">ماشىنا پاسخا بايرىمى</string>\n    <string name=\"auto_paste_sub\">ئەپنىڭ چاپلاش تاختىسى سانلىق مەلۇماتلىرىنى ئاپتوماتىك چاپلىشىغا يول قويىدۇ ، شۇڭا ئۇ ئاساسلىق ئېكراندا كۆرۈنىدۇ ھەمدە ئۇنى بىر تەرەپ قىلالايسىز</string>\n    <string name=\"harmonization_color\">ماسلاشتۇرۇش رەڭگى</string>\n    <string name=\"harmonization_level\">ماسلىشىش دەرىجىسى</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">پېكسىل قىممىتىگە Bessel (jinc) ئىقتىدارىنى قوللىنىش ئارقىلىق يۇقىرى سۈپەتلىك ئۆز-ئارا ماسلىشىشنى ساقلايدىغان قايتا ئىشلىتىش ئۇسۇلى</string>\n    <string name=\"gif_type_to_jxl\">GIF to JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">GIF رەسىملىرىنى JXL كارتون رەسىملىرىگە ئايلاندۇرۇڭ</string>\n    <string name=\"apng_type_to_jxl\">APNG دىن JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">APNG رەسىملىرىنى JXL كارتون رەسىمگە ئايلاندۇرۇڭ</string>\n    <string name=\"jxl_type_to_images\">JXL to Images</string>\n    <string name=\"jxl_type_to_images_sub\">JXL كارتوننى بىر تۈركۈم رەسىملەرگە ئايلاندۇرۇڭ</string>\n    <string name=\"jxl_type_to_jxl\">JXL غا رەسىملەر</string>\n    <string name=\"jxl_type_to_jxl_sub\">بىر تۈركۈم رەسىملەرنى JXL كارتونغا ئايلاندۇرۇڭ</string>\n    <string name=\"behavior\">Behavior</string>\n    <string name=\"skip_file_picking\">ھۆججەت تاللاشتىن ئاتلاش</string>\n    <string name=\"skip_file_picking_sub\">ئەگەر تاللانغان ئېكراندا مۇمكىن بولسا ھۆججەت تاللىغۇچ دەرھال كۆرسىتىلىدۇ</string>\n    <string name=\"generate_previews\">ئالدىن كۆرۈش ھاسىل قىلىڭ</string>\n    <string name=\"generate_previews_sub\">ئالدىن كۆرۈش ئەۋلادلىرىنى قوزغىتىدۇ ، بۇ بەلكىم بەزى ئۈسكۈنىلەردە سوقۇلۇشتىن ساقلىنىشى مۇمكىن ، بۇ يەككە تەھرىرلەش تاللانمىلىرى ئىچىدىكى بەزى تەھرىرلەش ئىقتىدارلىرىنىمۇ چەكلەيدۇ.</string>\n    <string name=\"lossy_compression\">Lossy Compression</string>\n    <string name=\"lossy_compression_sub\">زىيان تارتماي ، ھۆججەتنىڭ چوڭ-كىچىكلىكىنى ئازايتىش ئۈچۈن زىيانلىق پىرىسلاشنى ئىشلىتىدۇ</string>\n    <string name=\"compression_type\">پىرىسلاش تىپى</string>\n    <string name=\"speed_sub\">ھاسىل بولغان رەسىم يېشىش سۈرئىتىنى كونترول قىلىدۇ ، بۇ ھاسىل بولغان رەسىمنىڭ تېزرەك ئېچىلىشىغا ياردەم بېرىشى كېرەك ، %1$s نىڭ قىممىتى يېشىش سۈرئىتىنىڭ ئەڭ ئاستا ئىكەنلىكىنى بىلدۈرىدۇ ، ھالبۇكى %2$s - ئەڭ تېز ، بۇ تەڭشەك چىقىرىش رەسىمنىڭ چوڭ-كىچىكلىكىنى ئاشۇرۇشى مۇمكىن.</string>\n    <string name=\"sorting\">تەرتىپلەش</string>\n    <string name=\"sort_by_date\">چېسلا</string>\n    <string name=\"sort_by_date_reversed\">چېسلا (قايتۇرۇلغان)</string>\n    <string name=\"sort_by_name\">ئىسمى</string>\n    <string name=\"sort_by_name_reversed\">ئىسمى (قايتۇرۇلغان)</string>\n    <string name=\"channels_configuration\">قانال سەپلىمىسى</string>\n    <string name=\"header_today\">بۈگۈن</string>\n    <string name=\"header_yesterday\">تۈنۈگۈن</string>\n    <string name=\"embedded_picker\">قىستۇرما تاللىغۇچ</string>\n    <string name=\"embedded_picker_sub\">رەسىم قورال ساندۇقىنىڭ رەسىم تاللىغۇچ</string>\n    <string name=\"no_permissions\">رۇخسەت يوق</string>\n    <string name=\"request\">تەلەپ</string>\n    <string name=\"pick_multiple_media\">كۆپ مېدىيانى تاللاڭ</string>\n    <string name=\"pick_single_media\">يەككە مېدىيانى تاللاڭ</string>\n    <string name=\"pick\">تاللاڭ</string>\n    <string name=\"try_again\">قايتا سىناڭ</string>\n    <string name=\"show_settings_in_landscape\">مەنزىرە رايونىدا تەڭشەكلەرنى كۆرسەت</string>\n    <string name=\"show_settings_in_landscape_sub\">ئەگەر بۇ چەكلەنگەن بولسا ، مەنزىرە ھالىتى تەڭشىكىدە دائىم كۆرۈلىدىغان تاللاشنىڭ ئورنىغا ئۈستۈنكى ئەپ بالدىقىدىكى كۇنۇپكا ئېچىلىدۇ</string>\n    <string name=\"fullscreen_settings\">تولۇق ئېكران تەڭشىكى</string>\n    <string name=\"fullscreen_settings_sub\">ئۇنى قوزغىتىڭ ۋە تەڭشەك بېتى سىيرىلما تارتما جەدۋەلنىڭ ئورنىغا ھەمىشە تولۇق ئېكران سۈپىتىدە ئېچىلىدۇ</string>\n    <string name=\"switch_type\">ئالماشتۇرۇش تىپى</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"compose_switch_sub\">سىز ئالماشتۇرغان Jetpack بىرىكمە ماتېرىيال</string>\n    <string name=\"material_you_switch_sub\">سىز ئالماشتۇرىدىغان ماتېرىيال</string>\n    <string name=\"max\">Max</string>\n    <string name=\"resize_anchor\">لەڭگەرنىڭ چوڭ-كىچىكلىكى</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">راۋان</string>\n    <string name=\"fluent_switch_sub\">\\ \\\"راۋان \\\" لايىھىلەش سىستېمىسىنى ئاساس قىلغان ئالماشتۇرغۇچ</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">\\ \\\"Cupertino \\\" لايىھىلەش سىستېمىسىنى ئاساس قىلغان ئالماشتۇرغۇچ</string>\n    <string name=\"images_to_svg\">SVG غا رەسىملەر</string>\n    <string name=\"images_to_svg_sub\">SVG رەسىملىرىگە بېرىلگەن رەسىملەرنى ئىز قوغلاڭ</string>\n    <string name=\"use_sampled_palette\">Sampled Palette نى ئىشلىتىڭ</string>\n    <string name=\"use_sampled_palette_sub\">ئەگەر بۇ تاللاش قوزغىتىلسا مىقدارلاشتۇرۇش پالتىسى ئەۋرىشكە ئېلىنىدۇ</string>\n    <string name=\"path_omit\">Path Omit</string>\n    <string name=\"svg_warning\">بۇ قورالنى كىچىك رەسىملەرنى ئىز قوغلاشتا ئىشلىتىش تەۋسىيە قىلىنمايدۇ ، ئۇ كاشىلا پەيدا قىلىپ ، بىر تەرەپ قىلىش ۋاقتىنى ئاشۇرۇۋېتىدۇ</string>\n    <string name=\"downscale_image\">كىچىك رەسىم</string>\n    <string name=\"downscale_image_sub\">رەسىم بىر تەرەپ قىلىشتىن ئىلگىرى تۆۋەن ئۆلچەمگە چۈشۈرۈلىدۇ ، بۇ قورالنىڭ تېخىمۇ تېز ۋە بىخەتەر ئىشلىشىگە ياردەم بېرىدۇ</string>\n    <string name=\"min_color_ratio\">ئەڭ تۆۋەن رەڭ نىسبىتى</string>\n    <string name=\"lines_threshold\">Lines Threshold</string>\n    <string name=\"quadratic_threshold\">Quadratic Threshold</string>\n    <string name=\"coordinates_rounding_tolerance\">يۇمىلاق چىدامچانلىقنى ماسلاشتۇرىدۇ</string>\n    <string name=\"path_scale\">Path Scale</string>\n    <string name=\"reset_properties\">خاسلىقنى ئەسلىگە كەلتۈرۈش</string>\n    <string name=\"reset_properties_sub\">بارلىق خاسلىق سۈكۈتتىكى قىممەتكە تەڭشەلدى ، دىققەت قىلىڭ ، بۇ ھەرىكەتنى ئەمەلدىن قالدۇرغىلى بولمايدۇ</string>\n    <string name=\"detailed\">تەپسىلىي</string>\n    <string name=\"default_line_width\">كۆڭۈلدىكى سىزىق كەڭلىكى</string>\n    <string name=\"engine_mode\">ماتور ھالىتى</string>\n    <string name=\"legacy\">مىراس</string>\n    <string name=\"lstm_network\">LSTM تورى</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp;amp; LSTM</string>\n    <string name=\"convert\">ئايلاندۇرۇش</string>\n    <string name=\"convert_sub\">رەسىم گۇرۇپپىسىنى بېرىلگەن فورماتقا ئۆزگەرتىڭ</string>\n    <string name=\"add_new_folder\">يېڭى ھۆججەت قىسقۇچ قوشۇڭ</string>\n    <string name=\"tag_bits_per_sample\">ھەر بىر ئۈلگە</string>\n    <string name=\"tag_compression\">پىرىسلاش</string>\n    <string name=\"tag_photometric_interpretation\">Photometric Interpretation</string>\n    <string name=\"tag_samples_per_pixel\">Pixel نىڭ ئەۋرىشكىسى</string>\n    <string name=\"tag_planar_configuration\">پىلانلىق تەڭشەش</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Sub Sampling</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr ئورۇن بەلگىلەش</string>\n    <string name=\"tag_x_resolution\">X ئېنىقلىق</string>\n    <string name=\"tag_y_resolution\">Y قارار</string>\n    <string name=\"tag_resolution_unit\">ئېنىقلىق بىرلىكى</string>\n    <string name=\"tag_strip_offsets\">Strip Offsets</string>\n    <string name=\"tag_rows_per_strip\">ھەر بىر قۇر</string>\n    <string name=\"tag_strip_byte_counts\">Strip Byte Counts</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG ئالماشتۇرۇش فورماتى</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG ئالماشتۇرۇش فورماتىنىڭ ئۇزۇنلۇقى</string>\n    <string name=\"tag_transfer_function\">يۆتكەش ئىقتىدارى</string>\n    <string name=\"tag_white_point\">ئاق نۇقتا</string>\n    <string name=\"tag_primary_chromaticities\">Primary Chromaticities</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr كوئېففىتسېنتى</string>\n    <string name=\"tag_reference_black_white\">قارا ئاق</string>\n    <string name=\"tag_datetime\">چېسلا ۋاقتى</string>\n    <string name=\"tag_image_description\">رەسىم چۈشەندۈرۈشى</string>\n    <string name=\"tag_make\">ياساڭ</string>\n    <string name=\"tag_model\">Model</string>\n    <string name=\"tag_software\">يۇمشاق دېتال</string>\n    <string name=\"tag_artist\">سەنئەتكار</string>\n    <string name=\"tag_copyright\">نەشر ھوقۇقى</string>\n    <string name=\"tag_exif_version\">Exif نەشرى</string>\n    <string name=\"tag_flashpix_version\">Flashpix نەشرى</string>\n    <string name=\"tag_color_space\">رەڭ بوشلۇقى</string>\n    <string name=\"tag_gamma\">گامما</string>\n    <string name=\"tag_pixel_x_dimension\">Pixel X ئۆلچىمى</string>\n    <string name=\"tag_pixel_y_dimension\">Pixel Y ئۆلچىمى</string>\n    <string name=\"tag_compressed_bits_per_pixel\">پىكسېلغا پىرىسلانغان بىت</string>\n    <string name=\"tag_maker_note\">ياسىغۇچى ئەسكەرتىش</string>\n    <string name=\"tag_user_comment\">ئىشلەتكۈچى ئىنكاس</string>\n    <string name=\"tag_related_sound_file\">مۇناسىۋەتلىك ئاۋاز ھۆججىتى</string>\n    <string name=\"tag_datetime_original\">چېسلا ۋاقتى ئەسلى</string>\n    <string name=\"tag_datetime_digitized\">چېسلا ۋاقىت رەقەملەشتۈرۈلدى</string>\n    <string name=\"tag_offset_time\">Offset Time</string>\n    <string name=\"tag_offset_time_original\">Offset Time Original</string>\n    <string name=\"tag_offset_time_digitized\">Offset Time Digitized</string>\n    <string name=\"tag_subsec_time\">Sub Sec Time</string>\n    <string name=\"tag_subsec_time_original\">Sub Sec Time Original</string>\n    <string name=\"tag_subsec_time_digitized\">تارماق سېكۇنت ۋاقىت رەقەملەشتۈرۈلدى</string>\n    <string name=\"tag_exposure_time\">ئاشكارلىنىش ۋاقتى</string>\n    <string name=\"tag_f_number\">F نومۇرى</string>\n    <string name=\"tag_exposure_program\">ئاشكارىلاش پروگراممىسى</string>\n    <string name=\"tag_spectral_sensitivity\">Spectral Sensitivity</string>\n    <string name=\"tag_photographic_sensitivity\">سۈرەتتىكى سەزگۈرلۈك</string>\n    <string name=\"tag_oecf\">Oecf</string>\n    <string name=\"tag_sensitivity_type\">سەزگۈرلۈك تىپى</string>\n    <string name=\"tag_standard_output_sensitivity\">ئۆلچەملىك چىقىرىش سەزگۈرلۈكى</string>\n    <string name=\"tag_recommended_exposure_index\">تەۋسىيە قىلىنغان كۆرسەتكۈچ</string>\n    <string name=\"tag_iso_speed\">ISO سۈرئەت</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO سۈرئەت كەڭلىكى yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO سۈرئەت كەڭلىكى zzz</string>\n    <string name=\"tag_shutter_speed_value\">Shutter سۈرئەت قىممىتى</string>\n    <string name=\"tag_aperture_value\">Aperture Value</string>\n    <string name=\"tag_brightness_value\">يورۇقلۇق قىممىتى</string>\n    <string name=\"tag_exposure_bias_value\">ئاشكارىلاش بىر تەرەپ قىلىش قىممىتى</string>\n    <string name=\"tag_max_aperture_value\">Max Aperture Value</string>\n    <string name=\"tag_subject_distance\">تېما ئارىلىقى</string>\n    <string name=\"tag_metering_mode\">ئۆلچەش ھالىتى</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">تېما رايونى</string>\n    <string name=\"tag_focal_length\">فوكۇس ئۇزۇنلۇقى</string>\n    <string name=\"tag_flash_energy\">Flash Energy</string>\n    <string name=\"tag_spatial_frequency_response\">بوشلۇق چاستوتىسى ئىنكاسى</string>\n    <string name=\"tag_focal_plane_x_resolution\">فوكۇس ئايروپىلانى X ئېنىقلىق دەرىجىسى</string>\n    <string name=\"tag_focal_plane_y_resolution\">فوكۇس ئايروپىلانى Y قارارى</string>\n    <string name=\"tag_focal_plane_resolution_unit\">فوكۇس ئايروپىلانى ئېنىقلاش بىرلىكى</string>\n    <string name=\"tag_subject_location\">تېما ئورنى</string>\n    <string name=\"tag_exposure_index\">ئاشكارىلاش كۆرسەتكۈچى</string>\n    <string name=\"tag_sensing_method\">سېزىش ئۇسۇلى</string>\n    <string name=\"tag_file_source\">ھۆججەت مەنبەسى</string>\n    <string name=\"tag_cfa_pattern\">CFA Pattern</string>\n    <string name=\"tag_custom_rendered\">Custom Rendered</string>\n    <string name=\"tag_exposure_mode\">ئاشكارىلاش ھالىتى</string>\n    <string name=\"tag_white_balance\">White Balance</string>\n    <string name=\"tag_digital_zoom_ratio\">رەقەملىك چوڭلۇق نىسبىتى</string>\n    <string name=\"tag_focal_length_in_35mm_film\">فوكۇس ئۇزۇنلۇقى 35 مىللىمېتىرلىق فىلىم</string>\n    <string name=\"tag_scene_capture_type\">كۆرۈنۈشنى تۇتۇش تىپى</string>\n    <string name=\"tag_gain_control\">كونترول قىلىش</string>\n    <string name=\"tag_contrast\">سېلىشتۇرما</string>\n    <string name=\"tag_saturation\">Saturation</string>\n    <string name=\"tag_sharpness\">ئۆتكۈرلۈك</string>\n    <string name=\"tag_device_setting_description\">ئۈسكۈنىلەرنى تەڭشەش چۈشەندۈرۈشى</string>\n    <string name=\"tag_subject_distance_range\">تېما ئارىلىقى</string>\n    <string name=\"tag_image_unique_id\">رەسىم Unique ID</string>\n    <string name=\"tag_camera_owner_name\">كامېرا ئىگىسىنىڭ ئىسمى</string>\n    <string name=\"tag_body_serial_number\">بەدەن رەت نومۇرى</string>\n    <string name=\"tag_lens_specification\">لىنزا ئۆلچىمى</string>\n    <string name=\"tag_lens_make\">Lens Make</string>\n    <string name=\"tag_lens_model\">لىنزا مودېلى</string>\n    <string name=\"tag_lens_serial_number\">لىنزا رەت نومۇرى</string>\n    <string name=\"tag_gps_version_id\">GPS نەشرى كىملىكى</string>\n    <string name=\"tag_gps_latitude_ref\">GPS Latitude Ref</string>\n    <string name=\"tag_gps_latitude\">GPS كەڭلىكى</string>\n    <string name=\"tag_gps_longitude_ref\">GPS Longitude Ref</string>\n    <string name=\"tag_gps_longitude\">GPS ئۇزۇنلۇقى</string>\n    <string name=\"tag_gps_altitude_ref\">GPS Altitude Ref</string>\n    <string name=\"tag_gps_altitude\">GPS ئېگىزلىكى</string>\n    <string name=\"tag_gps_timestamp\">GPS ۋاقىت تامغىسى</string>\n    <string name=\"tag_gps_satellites\">GPS سۈنئىي ھەمراھى</string>\n    <string name=\"tag_gps_status\">GPS ھالىتى</string>\n    <string name=\"tag_gps_measure_mode\">GPS ئۆلچەش ھالىتى</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">GPS سۈرئەت Ref</string>\n    <string name=\"tag_gps_speed\">GPS سۈرئەت</string>\n    <string name=\"tag_gps_track_ref\">GPS Track Ref</string>\n    <string name=\"tag_gps_track\">GPS ئىز</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS Img Direction Ref</string>\n    <string name=\"tag_gps_img_direction\">GPS Img يۆنىلىشى</string>\n    <string name=\"tag_gps_map_datum\">GPS خەرىتە سانلىق مەلۇمات ئامبىرى</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS Dest Latitude Ref</string>\n    <string name=\"tag_gps_dest_latitude\">GPS Dest Latitude</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS Dest Longitude Ref</string>\n    <string name=\"tag_gps_dest_longitude\">GPS Dest Longitude</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS Dest Bearing Ref</string>\n    <string name=\"tag_gps_dest_bearing\">GPS Dest Bearing</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS Dest Distance Ref</string>\n    <string name=\"tag_gps_dest_distance\">GPS Dest Distance</string>\n    <string name=\"tag_gps_processing_method\">GPS بىر تەرەپ قىلىش ئۇسۇلى</string>\n    <string name=\"tag_gps_area_information\">GPS رايون ئۇچۇرى</string>\n    <string name=\"tag_gps_datestamp\">GPS چېسلا تامغىسى</string>\n    <string name=\"tag_gps_differential\">GPS پەرقى</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS H ئورۇن بەلگىلەش خاتالىقى</string>\n    <string name=\"tag_interoperability_index\">ئۆز-ئارا ماسلىشىش كۆرسەتكۈچى</string>\n    <string name=\"tag_dng_version\">DNG نەشرى</string>\n    <string name=\"tag_default_crop_size\">كۆڭۈلدىكى زىرائەت چوڭلۇقى</string>\n    <string name=\"tag_orf_preview_image_start\">رەسىم باشلاش</string>\n    <string name=\"tag_orf_preview_image_length\">رەسىم ئۇزۇنلۇقىنى ئالدىن كۆرۈش</string>\n    <string name=\"tag_orf_aspect_frame\">Aspect Frame</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">سېنزور تۆۋەن چېگرىسى</string>\n    <string name=\"tag_rw2_sensor_left_border\">سېنزور سول چېگرا</string>\n    <string name=\"tag_rw2_sensor_right_border\">سېنزور ئوڭ چېگراسى</string>\n    <string name=\"tag_rw2_sensor_top_border\">Sensor Top Border</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">بېرىلگەن خەت ۋە رەڭ بىلەن يولدا تېكىست سىزىڭ</string>\n    <string name=\"font_size\">خەت چوڭلۇقى</string>\n    <string name=\"watermark_size\">Watermark Size</string>\n    <string name=\"repeat_text\">تېكىستنى تەكرارلاش</string>\n    <string name=\"repeat_text_sub\">نۆۋەتتىكى تېكىست بىر قېتىم سىزىشنىڭ ئورنىغا يول ئاخىرلاشقۇچە تەكرارلىنىدۇ</string>\n    <string name=\"dash_size\">Dash Size</string>\n    <string name=\"draw_mode_image_sub\">تاللانغان رەسىمنى ئىشلىتىپ ئۇنى بېرىلگەن يولدا سىزىڭ</string>\n    <string name=\"draw_image_sub\">بۇ رەسىم سىزىلغان يولنىڭ تەكرارلىنىشى سۈپىتىدە ئىشلىتىلىدۇ</string>\n    <string name=\"outlined_triangle_sub\">باشلىنىش نۇقتىسىدىن ئاخىرىغىچە ئۈچبۇلۇڭنى سىزىدۇ</string>\n    <string name=\"triangle_sub\">باشلىنىش نۇقتىسىدىن ئاخىرىغىچە ئۈچبۇلۇڭنى سىزىدۇ</string>\n    <string name=\"outlined_triangle\">كۆرسىتىلگەن ئۈچبۇلۇڭ</string>\n    <string name=\"triangle\">ئۈچبۇلۇڭ</string>\n    <string name=\"polygon_sub\">كۆپ قۇتۇپنى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىدۇ</string>\n    <string name=\"polygon\">كۆپ گۈللۈك</string>\n    <string name=\"outlined_polygon\">كۆپ قۇتۇپلۇق</string>\n    <string name=\"outlined_polygon_sub\">كۆپ نۇقتىنى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىدۇ</string>\n    <string name=\"vertices\">Vertices</string>\n    <string name=\"draw_regular_polygon\">دائىملىق كۆپ قىرلىق رەسىم سىزىڭ</string>\n    <string name=\"draw_regular_polygon_sub\">ھەقسىز شەكىلنىڭ ئورنىغا دائىملىق بولىدىغان كۆپ قىرلىق سىزىڭ</string>\n    <string name=\"star_sub\">چولپاننى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىدۇ</string>\n    <string name=\"star\">Star</string>\n    <string name=\"outlined_star\">Outline Star</string>\n    <string name=\"outlined_star_sub\">چولپاننى باشلىنىش نۇقتىسىدىن ئاخىرىغىچە سىزىدۇ</string>\n    <string name=\"inner_radius_ratio\">ئىچكى رادىئاتسىيە نىسبىتى</string>\n    <string name=\"draw_regular_star\">دائىملىق چولپان سىزىڭ</string>\n    <string name=\"draw_regular_star_sub\">ھەقسىز شەكىلنىڭ ئورنىغا دائىملىق يۇلتۇز سىزىڭ</string>\n    <string name=\"antialias\">Antialias</string>\n    <string name=\"antialias_sub\">ئۆتكۈر قىرلارنىڭ ئالدىنى ئېلىش ئۈچۈن ئوكسىدلىنىشقا قارشى تۇرۇشنى قوزغىتىدۇ</string>\n    <string name=\"open_edit_instead_of_preview\">ئالدىن كۆرۈشنىڭ ئورنىغا تەھرىرلەشنى ئېچىڭ</string>\n    <string name=\"open_edit_instead_of_preview_sub\">ImageToolbox دا ئېچىش (ئالدىن كۆرۈش) ئۈچۈن رەسىم تاللىغاندا ، تەھرىرلەش تاللاش جەدۋىلى ئالدىن كۆرۈشنىڭ ئورنىغا ئېچىلىدۇ</string>\n    <string name=\"document_scanner\">ھۆججەت سايىلىغۇچ</string>\n    <string name=\"document_scanner_sub\">ھۆججەتلەرنى سايىلەپ ، PDF ياكى ئۇلاردىن ئايرىم رەسىم ھاسىل قىلىڭ</string>\n    <string name=\"click_to_start_scanning\">سىكانىرلاشنى باشلاڭ</string>\n    <string name=\"start_scanning\">سايىلەشنى باشلاڭ</string>\n    <string name=\"save_as_pdf\">Pdf نى ساقلاڭ</string>\n    <string name=\"share_as_pdf\">Pdf سۈپىتىدە ھەمبەھىرلەڭ</string>\n    <string name=\"options_below_is_for_images\">تۆۋەندىكى تاللاشلار PDF ئەمەس ، رەسىملەرنى ساقلاش ئۈچۈن</string>\n    <string name=\"equalize_histogram_hsv\">Histogram HSV نى تەڭلەشتۈرۈڭ</string>\n    <string name=\"equalize_histogram\">Histogram نى تەڭلەشتۈرۈڭ</string>\n    <string name=\"enter_percentage\">پىرسەنتنى كىرگۈزۈڭ</string>\n    <string name=\"allow_enter_by_text_field\">Text Field ئارقىلىق كىرىشكە يول قويۇڭ</string>\n    <string name=\"allow_enter_by_text_field_sub\">ئالدىن تاللاشنىڭ ئارقىسىدىكى Text Field نى قوزغىتىپ ، ئۇلارنى ئۇچۇشقا كىرگۈزۈڭ</string>\n    <string name=\"scale_color_space\">تارازا رەڭ بوشلۇقى</string>\n    <string name=\"linear\">Linear</string>\n    <string name=\"equalize_histogram_pixelation\">Histogram Pixelation نى تەڭلەشتۈرۈڭ</string>\n    <string name=\"grid_size_x\">Grid Size X.</string>\n    <string name=\"grid_size_y\">Grid Size Y.</string>\n    <string name=\"equalize_histogram_adaptive\">گىستوگرام ماسلىشىشچانلىقىنى تەڭلەشتۈرۈڭ</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Histogram Adaptive LUV نى تەڭلەشتۈرۈڭ</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Histogram Adaptive LAB نى تەڭلەشتۈرۈڭ</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Crop to Content</string>\n    <string name=\"frame_color\">رامكا رەڭگى</string>\n    <string name=\"color_to_ignore\">سەل قاراش</string>\n    <string name=\"template\">قېلىپ</string>\n    <string name=\"no_template_filters\">قېلىپ سۈزگۈچ قوشۇلمىدى</string>\n    <string name=\"create_new\">يېڭى قۇر</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">سايىلەنگەن QR كودى ئۈنۈملۈك سۈزگۈچ قېلىپى ئەمەس</string>\n    <string name=\"scan_qr_code\">QR كودىنى سايىلەڭ</string>\n    <string name=\"opened_file_have_no_filter_template\">تاللانغان ھۆججەتتە سۈزگۈچ قېلىپ سانلىق مەلۇماتلىرى يوق</string>\n    <string name=\"create_template\">قېلىپ قۇرۇش</string>\n    <string name=\"template_name\">قېلىپ ئىسمى</string>\n    <string name=\"select_template_preview\">بۇ رەسىم بۇ سۈزگۈچ قېلىپىنى ئالدىن كۆرۈشكە ئىشلىتىلىدۇ</string>\n    <string name=\"template_filter\">قېلىپ سۈزگۈچ</string>\n    <string name=\"as_qr_code\">QR كود سۈرىتى سۈپىتىدە</string>\n    <string name=\"as_file\">ھۆججەت سۈپىتىدە</string>\n    <string name=\"save_as_file\">ھۆججەت سۈپىتىدە ساقلاڭ</string>\n    <string name=\"save_as_qr_code_image\">QR كود رەسىمى سۈپىتىدە ساقلاڭ</string>\n    <string name=\"delete_template\">قېلىپنى ئۆچۈرۈڭ</string>\n    <string name=\"delete_template_warn\">تاللانغان قېلىپ سۈزگۈچنى ئۆچۈرمەكچى بولۇۋاتىسىز. بۇ مەشغۇلاتنى ئەمەلدىن قالدۇرغىلى بولمايدۇ</string>\n    <string name=\"added_filter_template\">ئىسمى \\ \\\"%1$s \\\" بىلەن سۈزگۈچ قېلىپى قوشۇلدى (%2$s)</string>\n    <string name=\"filter_preview\">سۈزگۈچ ئالدىن كۆرۈش</string>\n    <string name=\"qr_code\">QR &amp;amp; تاياقچە كودى</string>\n    <string name=\"qr_code_sub\">QR كودىنى سايىلەپ ئۇنىڭ مەزمۇنىغا ئېرىشىڭ ياكى تىزمىڭىزنى چاپلاپ يېڭى كود ھاسىل قىلىڭ</string>\n    <string name=\"code_content\">كود مەزمۇنى</string>\n    <string name=\"scan_qr_code_to_replace_content\">ساھەدىكى مەزمۇنلارنى ئالماشتۇرۇش ئۈچۈن ھەر قانداق تاياقچە كودنى سايىلەڭ ياكى تاللانغان تىپ بىلەن يېڭى تاياقچە كود ھاسىل قىلىدىغان نەرسە كىرگۈزۈڭ</string>\n    <string name=\"qr_description\">QR چۈشەندۈرۈش</string>\n    <string name=\"min\">Min</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">تەڭشەكلەردە QR كودىنى سايىلەش ئۈچۈن كامېرا ئىجازەتنامىسى بېرىڭ</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">تەڭشەكلەردە ھۆججەت سايىلىرىنى سايىلەش ئۈچۈن كامېرا ئىجازەتنامىسى بېرىڭ</string>\n    <string name=\"cubic\">Cubic</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">بولقا</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussian</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">64-نومۇر</string>\n    <string name=\"kaiser\">قەيسەر</string>\n    <string name=\"bartlett_hann\">Bartlett-He</string>\n    <string name=\"box\">Box</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">كۇب ئارىلىقى ئەڭ يېقىن 16 پىكسېلنى ئويلاش ئارقىلىق تېخىمۇ كىچىك كۆلەمدە تەمىنلەيدۇ ، بىليارتتىن ياخشى ئۈنۈم بېرىدۇ</string>\n    <string name=\"bspline_sub\">ئوخشاش ئېنىقلىما بېرىلگەن كۆپ قۇتۇپلۇق ئىقتىداردىن پايدىلىنىپ ئەگرى سىزىق ياكى يۈزنى سىلىق ئۆز-ئارا ماسلاشتۇرىدۇ ۋە يېقىنلاشتۇرىدۇ ، جانلىق ۋە ئۈزلۈكسىز شەكىل ئىپادىلەيدۇ.</string>\n    <string name=\"hamming_sub\">سىگنالنىڭ قىرلىرىنى چېكىش ئارقىلىق سپېكترا ئېقىپ كېتىشنى ئازايتىش ئۈچۈن ئىشلىتىلىدىغان كۆزنەك ئىقتىدارى ، سىگنال بىر تەرەپ قىلىشقا پايدىلىق</string>\n    <string name=\"hanning_sub\">Hann كۆزنىكىنىڭ بىر خىل ۋارىيانتى ، ئادەتتە سىگنال بىر تەرەپ قىلىش پروگراممىلىرىدا سپېكترا ئېقىپ كېتىشنى ئازايتىشتا ئىشلىتىلىدۇ</string>\n    <string name=\"blackman_sub\">سىگنال بىر تەرەپ قىلىشتا دائىم ئىشلىتىلىدىغان سپېكترا ئېقىپ كېتىشنى ئازايتىش ئارقىلىق ياخشى چاستوتا ئېنىقلىقى بىلەن تەمىنلەيدىغان كۆزنەك ئىقتىدارى</string>\n    <string name=\"welch_sub\">سىگنال بىر تەرەپ قىلىش پروگراممىلىرىدا دائىم ئىشلىتىلىدىغان سپېكترا ئېقىمى تۆۋەنلەپ ياخشى چاستوتا ئېنىقلىق دەرىجىسى ئۈچۈن لايىھەلەنگەن كۆزنەك ئىقتىدارى</string>\n    <string name=\"quadric_sub\">ئۆز-ئارا ماسلىشىش ئۈچۈن كۇئادرات فۇنكسىيەنى ئىشلىتىدىغان ئۇسۇل ، سىلىق ۋە ئۈزلۈكسىز ئۈنۈم بېرىدۇ</string>\n    <string name=\"gaussian_sub\">گاۋسىيىلىك ئىقتىدارنى قوللىنىدىغان ئىنتېرپوللاش ئۇسۇلى ، رەسىمدىكى شاۋقۇننى راۋانلاشتۇرۇش ۋە ئازايتىشقا پايدىلىق</string>\n    <string name=\"sphinx_sub\">ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئەلا سۈپەتلىك ئىنتېرپول بىلەن تەمىنلەيدىغان ئىلغار قايتا قۇرۇش ئۇسۇلى</string>\n    <string name=\"bartlett_sub\">سىگنال بىر تەرەپ قىلىشتا ئىشلىتىلىدىغان ئۈچبۇلۇڭلۇق كۆزنەك ئىقتىدارى سپېكترا ئېقىپ كېتىشنى ئازايتىدۇ</string>\n    <string name=\"robidoux_sub\">تەبىئىي سۈرەتنىڭ چوڭ-كىچىكلىكىنى تەڭشەش ، ئۆتكۈرلۈك ۋە سىلىقلىقنى تەڭپۇڭلاشتۇرۇش ئۈچۈن ئەلا سۈپەتلىك ئىنتېرپوللاش ئۇسۇلى ئەلالاشتۇرۇلدى</string>\n    <string name=\"robidoux_sharp_sub\">Robidoux ئۇسۇلىنىڭ تېخىمۇ ئۆتكۈر نۇسخىسى ، ئىنچىكە رەسىمنىڭ چوڭ-كىچىكلىكىنى ئەلالاشتۇردى</string>\n    <string name=\"spline16_sub\">16 چېكىش سۈزگۈچ ئارقىلىق سىلىق نەتىجىلەرنى تەمىنلەيدىغان يۇمىلاق شەكىللىك ئىنتېرپوللاش ئۇسۇلى</string>\n    <string name=\"spline36_sub\">36 چېكىش سۈزگۈچ ئارقىلىق سىلىق نەتىجىلەرنى تەمىنلەيدىغان يۇمىلاق شەكىللىك ئىنتېرپوللاش ئۇسۇلى</string>\n    <string name=\"spline64_sub\">64 چېكىش سۈزگۈچ ئارقىلىق سىلىق نەتىجىلەرنى تەمىنلەيدىغان يۇمىلاق شەكىللىك ئىنتېرپوللاش ئۇسۇلى</string>\n    <string name=\"kaiser_sub\">Kaiser كۆزنىكىنى ئىشلىتىدىغان ئۆز-ئارا باغلىنىش ئۇسۇلى ، ئاساسلىق كەڭلىك كەڭلىكى بىلەن يان تەرەپتىكى سەۋىيىدىكى سودىنى ياخشى كونترول قىلىدۇ.</string>\n    <string name=\"bartlett_hann_sub\">Bartlett بىلەن Hann كۆزنەكلىرىنى بىرلەشتۈرگەن ئارىلاشما كۆزنەك ئىقتىدارى سىگنال بىر تەرەپ قىلىشتا سپېكترا ئېقىپ كېتىشنى ئازايتىشقا ئىشلىتىلىدۇ</string>\n    <string name=\"box_sub\">ئەڭ يېقىن پېكسىل قىممەتنىڭ ئوتتۇرىچە قىممىتىنى ئىشلىتىدىغان ئاددىي قايتا ئۆزگەرتىش ئۇسۇلى ، دائىم توسۇلۇپ قېلىشنى كەلتۈرۈپ چىقىرىدۇ</string>\n    <string name=\"bohman_sub\">سپېكترا ئېقىپ كېتىشنى ئازايتىش ئۈچۈن ئىشلىتىلىدىغان كۆزنەك ئىقتىدارى ، سىگنال بىر تەرەپ قىلىش پروگراممىلىرىدا ياخشى چاستوتا ئېنىقلىق دەرىجىسى بىلەن تەمىنلەيدۇ</string>\n    <string name=\"lanczos2_sub\">ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئەلا سۈپەتلىك ئۆز-ئارا ماسلىشىش ئۈچۈن 2 لۆڭلىك Lanczos سۈزگۈچ ئىشلىتىدىغان قايتا قۇرۇش ئۇسۇلى</string>\n    <string name=\"lanczos3_sub\">ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئەلا سۈپەتلىك ئۆز-ئارا ماسلىشىش ئۈچۈن 3 لېتىرلىق Lanczos سۈزگۈچ ئىشلىتىدىغان قايتا قۇرۇش ئۇسۇلى</string>\n    <string name=\"lanczos4_sub\">ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئەلا سۈپەتلىك ئۆز-ئارا ماسلىشىش ئۈچۈن 4 لېتىرلىق Lanczos سۈزگۈچ ئىشلىتىدىغان قايتا قۇرۇش ئۇسۇلى</string>\n    <string name=\"lanczos2_jinc_sub\">Lanczos 2 سۈزگۈچنىڭ جىنس ئىقتىدارىنى ئىشلىتىدىغان بىر خىل ۋارىيانتى ، ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئەلا سۈپەتلىك ئىنتېرپول بىلەن تەمىنلەيدۇ.</string>\n    <string name=\"lanczos3_jinc_sub\">Lanczos 3 سۈزگۈچنىڭ جىنس ئىقتىدارىنى ئىشلىتىدىغان بىر خىل ۋارىيانتى ، ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئەلا سۈپەتلىك ئىنتېرپول بىلەن تەمىنلەيدۇ.</string>\n    <string name=\"lanczos4_jinc_sub\">Lanczos 4 سۈزگۈچنىڭ جىنك ئىقتىدارىنى ئىشلىتىدىغان بىر خىل ۋارىيانتى ، ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئەلا سۈپەتلىك ئىنتېرپول بىلەن تەمىنلەيدۇ.</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">سىلىق ئارىلىشىش ۋە قايتا قۇرۇش ئۈچۈن خەننىڭ سۈزگۈچىنىڭ ئېللىپتىك ئېغىرلىق ئوتتۇرىچە كۆرسەتكۈچى (EWA) ۋارىيانتى</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Elliptical Weight Average Average (EWA) variant of Robidoux filter for high quality resampling</string>\n    <string name=\"ewa_blackman\">Blackman EVE</string>\n    <string name=\"ewa_blackman_sub\">قوڭغۇراق بويۇملىرىنى ئەڭ تۆۋەن چەككە چۈشۈرۈش ئۈچۈن Blackman سۈزگۈچنىڭ ئېللىپتىك ئېغىرلىقتىكى ئوتتۇرىچە (EWA) ۋارىيانتى</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_quadric_sub\">سىلىق ئارىلىشىش ئۈچۈن Quadric سۈزگۈچنىڭ Elliptical Weight Average (EWA) ۋارىيانتى</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">تېخىمۇ كەسكىن نەتىجىگە ئېرىشىش ئۈچۈن Robidoux ئۆتكۈر سۈزگۈچنىڭ ئېللىپتىك ئېغىرلىق ئوتتۇرىچە كۆرسەتكۈچى (EWA)</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Lanczos 3 Jinc سۈزگۈچنىڭ Elliptical Weight Average Average (EWA) variant variant for high quality resampling with aliasing reduced</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">سۈزۈكلۈك ۋە سىلىقلىق تەڭپۇڭلۇقى بىلەن يۇقىرى سۈپەتلىك رەسىم بىر تەرەپ قىلىش ئۈچۈن لايىھەلەنگەن قايتا سۈزگۈچ</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">رەسىم سۈپىتىنى يۇقىرى كۆتۈرۈش ئۈچۈن جىنسېڭ سۈزگۈچنىڭ ئېللىپىس ئېغىرلىق ئوتتۇرىچە كۆرسەتكۈچى (EWA)</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئۆتكۈر نەتىجىگە ئېرىشىش ئۈچۈن Lanczos ئۆتكۈر سۈزگۈچنىڭ Elliptical Weight Average (EWA) ۋارىيانتى</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Lanczos 4 ئۆتكۈر سۈزگۈچنىڭ Elliptical Weight Average (EWA) ۋارىيانتى</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">رەسىمنى راۋانلاشتۇرۇش ئۈچۈن Lanczos يۇمشاق سۈزگۈچنىڭ Elliptical Weight Average (EWA) ۋارىيانتى</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">ھەسەن لايىھەلىگەن سۈزۈك ۋە سۈنئىي رەسىمسىز رەسىمنى كىچىكلىتىش ئۈچۈن لايىھەلەنگەن</string>\n    <string name=\"format_conversion\">فورمات ئۆزگەرتىش</string>\n    <string name=\"format_conversion_sub\">بىر تۈركۈم رەسىملەرنى بىر فورماتتىن يەنە بىر فورماتقا ئۆزگەرتىڭ</string>\n    <string name=\"dismiss_forever\">مەڭگۈ ئەمەلدىن قالدۇرۇڭ</string>\n    <string name=\"image_stacking\">رەسىم تىزىش</string>\n    <string name=\"image_stacking_sub\">تاللانغان ئارىلاشما ھالەتتىكى رەسىملەرنى بىر-بىرىنىڭ ئۈستىگە تىزىڭ</string>\n    <string name=\"add_image\">رەسىم قوشۇڭ</string>\n    <string name=\"bins_count\">Bins count</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Histogram Adaptive HSL نى تەڭلەشتۈرۈڭ</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Histogram Adaptive HSV نى تەڭلەشتۈرۈڭ</string>\n    <string name=\"edge_mode\">Edge Mode</string>\n    <string name=\"clip\">Clip</string>\n    <string name=\"wrap\">Wrap</string>\n    <string name=\"color_blind_scheme\">رەڭ قارىغۇ</string>\n    <string name=\"color_blind_scheme_sub\">تاللانغان رەڭ قارىغۇلار تىپىغا ئۇسلۇب رەڭلىرىنى ماسلاشتۇرۇش ھالىتىنى تاللاڭ</string>\n    <string name=\"protanomaly_sub\">قىزىل ۋە يېشىل رەڭلەرنى پەرقلەندۈرۈش قىيىن</string>\n    <string name=\"deuteranomaly_sub\">يېشىل ۋە قىزىل رەڭلەرنى پەرقلەندۈرۈش قىيىن</string>\n    <string name=\"tritanomaly_sub\">كۆك بىلەن سېرىق رەڭنى پەرقلەندۈرۈش قىيىن</string>\n    <string name=\"protanopia_sub\">قىزىل رەڭنى ھېس قىلالماسلىق</string>\n    <string name=\"deuteranopia_sub\">يېشىل رەڭلەرنى ھېس قىلالماسلىق</string>\n    <string name=\"tritanopia_sub\">كۆك رەڭنى ھېس قىلالماسلىق</string>\n    <string name=\"achromatomaly_sub\">بارلىق رەڭلەرگە بولغان سەزگۈرلۈكنى تۆۋەنلىتىدۇ</string>\n    <string name=\"achromatopsia_sub\">پۈتۈنلەي رەڭ قارىغۇسى ، پەقەت كۈلرەڭ رەڭلەرنىلا كۆرىدۇ</string>\n    <string name=\"not_use_color_blind_scheme\">رەڭ قارىغۇ پىلانىنى ئىشلەتمەڭ</string>\n    <string name=\"not_use_color_blind_scheme_sub\">رەڭلەر باشتېمىدا بېكىتىلگەندەك بولىدۇ</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_2_sub\">لاگېرانگ ئارىلىقىدىكى سۈزگۈچ 2-سۈزگۈچ ، سىلىق ئۆتۈشۈش ئارقىلىق ئەلا سۈپەتلىك رەسىم كۆلىمىگە ماس كېلىدۇ</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_3_sub\">3-نومۇرلۇق لاگېرانگ ئارىلىشىش سۈزگۈچ بولۇپ ، رەسىمنى كىچىكلىتىش ئۈچۈن تېخىمۇ ياخشى توغرىلىق ۋە تېخىمۇ راۋان نەتىجىلەرنى تەمىنلەيدۇ</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">Lanczos نىڭ سۈزگۈچ سۈزگۈچ سۈزگۈچ سۈزگۈچ دەرىجىسى 6 بولۇپ ، تېخىمۇ سۈزۈك ۋە تېخىمۇ توغرا بولغان سۈرەت بىلەن تەمىنلەيدۇ</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lanczos_6_jinc_sub\">Lanczos 6 سۈزگۈچنىڭ Jinc فۇنكسىيەسىنى ئىشلىتىپ رەسىمنى قايتا قۇرۇش سۈپىتىنى يۇقىرى كۆتۈرگەن</string>\n    <string name=\"linear_box_blur\">Linear Box Blur</string>\n    <string name=\"linear_tent_blur\">تۈز سىزىقلىق چېدىر</string>\n    <string name=\"linear_gaussian_box_blur\">Linear Gaussian Box Blur</string>\n    <string name=\"linear_stack_blur\">Linear Stack Blur</string>\n    <string name=\"gaussian_box_blur\">Gaussian Box Blur</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Linear Fast Gaussian Blur Next</string>\n    <string name=\"linear_fast_gaussian_blur\">سىزىقلىق تېز گاۋسىيىلىك تۇتۇق</string>\n    <string name=\"linear_gaussian_blur\">Linear Gaussian Blur</string>\n    <string name=\"draw_filter_sub\">بوياق قىلىپ ئىشلىتىش ئۈچۈن بىر سۈزگۈچنى تاللاڭ</string>\n    <string name=\"replace_filter\">سۈزگۈچنى ئالماشتۇرۇڭ</string>\n    <string name=\"pick_filter_info\">ئاستىدىكى سۈزگۈچنى تاللاڭ ، ئۇنى رەسىمىڭىزدە چوتكا قىلىپ ئىشلىتىڭ</string>\n    <string name=\"tiff_compression_scheme\">TIFF پىرىسلاش پىلانى</string>\n    <string name=\"low_poly\">تۆۋەن پول</string>\n    <string name=\"sand_painting\">قۇم رەسىم</string>\n    <string name=\"image_splitting\">رەسىم بۆلۈش</string>\n    <string name=\"image_splitting_sub\">يەككە رەسىمنى قۇر ياكى ستونغا بۆلۈڭ</string>\n    <string name=\"fit_to_bounds\">چەكلىمىگە ماس كېلىدۇ</string>\n    <string name=\"fit_to_bounds_sub\">بۇ پارامېتىر بىلەن زىرائەتنىڭ چوڭ-كىچىكلىكىنى تەڭشەش ھالىتىنى بىرلەشتۈرۈپ ، كۆڭۈلدىكىدەك ھەرىكەتكە ئېرىشىڭ (Crop / Fit to aspect ratio)</string>\n    <string name=\"languages_imported\">مۇۋەپپەقىيەتلىك ئىمپورت قىلىنغان تىللار</string>\n    <string name=\"backup_ocr_models\">OCR مودېللىرىنى زاپاسلاش</string>\n    <string name=\"import_word\">ئەكىرىش</string>\n    <string name=\"export\">ئېكسپورت</string>\n    <string name=\"position\">ئورنى</string>\n    <string name=\"center\">Center</string>\n    <string name=\"top_left\">سول ئۈستى</string>\n    <string name=\"top_right\">ئۈستى ئوڭ</string>\n    <string name=\"bottom_left\">ئاستى سول</string>\n    <string name=\"bottom_right\">ئاستى ئوڭ</string>\n    <string name=\"top_center\">Top Center</string>\n    <string name=\"center_right\">Center Right</string>\n    <string name=\"bottom_center\">Bottom Center</string>\n    <string name=\"center_left\">Center Left</string>\n    <string name=\"target_image\">نىشانلىق رەسىم</string>\n    <string name=\"palette_transfer\">Palette Transfer</string>\n    <string name=\"enhanced_oil\">كۈچەيتىلگەن نېفىت</string>\n    <string name=\"simple_old_tv\">ئاددىي كونا تېلېۋىزور</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">ئاددىي سىزما</string>\n    <string name=\"soft_glow\">Soft Glow</string>\n    <string name=\"color_poster\">رەڭلىك ئېلان</string>\n    <string name=\"tri_tone\">Tri Tone</string>\n    <string name=\"third_color\">ئۈچىنچى رەڭ</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olks</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">Polka Dot</string>\n    <string name=\"clustered_2x2_dithering\">Clustered 2x2 Dithering</string>\n    <string name=\"clustered_4x4_dithering\">Clxered 4x4 Dithering</string>\n    <string name=\"clustered_8x8_dithering\">توپلانغان 8x8 Dithering</string>\n    <string name=\"yililoma_dithering\">Yililoma Dithering</string>\n    <string name=\"no_favorite_options_selected\">ياقتۇرىدىغان تاللاشلار تاللانمىدى ، ئۇلارنى قوراللار بېتىگە قوشۇڭ</string>\n    <string name=\"add_favorites\">ياقتۇرىدىغانلارنى قوشۇڭ</string>\n    <string name=\"harmony_complementary\">تولۇقلىما</string>\n    <string name=\"harmony_analogous\">Analogous</string>\n    <string name=\"harmony_triadic\">Triadic</string>\n    <string name=\"harmony_split_complementary\">Split Complementary</string>\n    <string name=\"harmony_tetradic\">Tetradic</string>\n    <string name=\"harmony_square\">مەيدان</string>\n    <string name=\"harmony_analogous_complementary\">Analogous + Complementary</string>\n    <string name=\"color_tools\">رەڭ قوراللىرى</string>\n    <string name=\"color_tools_sub\">ئارىلاشتۇرۇش ، ئاھاڭ ياساش ، سايە ھاسىل قىلىش ۋە باشقىلار</string>\n    <string name=\"color_harmonies\">Color Harmonies</string>\n    <string name=\"color_shading\">رەڭ سايىسى</string>\n    <string name=\"variation\">Variation</string>\n    <string name=\"tints\">Tints</string>\n    <string name=\"tones\">ئاھاڭ</string>\n    <string name=\"shades\">سايە</string>\n    <string name=\"color_mixing\">رەڭ ئارىلاشتۇرۇش</string>\n    <string name=\"color_info\">رەڭ ئۇچۇرى</string>\n    <string name=\"selected_color\">تاللانغان رەڭ</string>\n    <string name=\"color_to_mix\">ئارىلاش رەڭ</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">ھەرىكەتچان رەڭلەر ئېچىلغاندا پۇل ئىشلەتكىلى بولمايدۇ</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">نىشان LUT رەسىم</string>\n    <string name=\"amatorka\">ھەۋەسكار</string>\n    <string name=\"miss_etikate\">Miss Etiquette</string>\n    <string name=\"soft_elegance\">Soft Elegance</string>\n    <string name=\"soft_elegance_variant\">يۇمشاق نەپىس ۋارىيانت</string>\n    <string name=\"palette_transfer_variant\">Palette Transfer Variant</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">نىشان 3D LUT ھۆججىتى (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bleach Bypass</string>\n    <string name=\"candlelight\">شام</string>\n    <string name=\"drop_blues\">كۆكنى تاشلاڭ</string>\n    <string name=\"edgy_amber\">Edgy Amber</string>\n    <string name=\"fall_colors\">Fall Colors</string>\n    <string name=\"film_stock_50\">Film Stock 50</string>\n    <string name=\"foggy_night\">تۇمان كېچىسى</string>\n    <string name=\"kodak\">كوداك</string>\n    <string name=\"save_empty_lut\">نېيترال LUT رەسىمگە ئېرىشىش</string>\n    <string name=\"save_empty_lut_sub\">ئالدى بىلەن ، ئۆزىڭىز ياقتۇرىدىغان رەسىم تەھرىرلەش پروگراممىسىنى ئىشلىتىپ ، بۇ يەردىن ئېرىشەلەيدىغان نېيترال LUT غا سۈزگۈچ ئىشلىتىڭ. بۇنىڭ نورمال ئىشلىشى ئۈچۈن ھەر بىر پېكسىل رەڭ باشقا پېكسىللارغا باغلىق بولماسلىقى كېرەك (مەسىلەن تۇتۇق ئىشلىمەيدۇ). تەييارلاپ بولغاندىن كېيىن ، يېڭى LUT رەسىمىڭىزنى 512 * 512 LUT سۈزگۈچكە كىرگۈزۈڭ</string>\n    <string name=\"pop_art\">Pop Art</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"coffee\">قەھۋە</string>\n    <string name=\"golden_forest\">ئالتۇن ئورمان</string>\n    <string name=\"greenish\">يېشىل</string>\n    <string name=\"retro_yellow\">Retro Yellow</string>\n    <string name=\"links_preview\">ئۇلىنىش ئالدىن كۆرۈش</string>\n    <string name=\"links_preview_sub\">تېكىست (QRCode, OCR قاتارلىقلار) غا ئېرىشەلەيدىغان ئورۇنلاردا ئۇلىنىشنى ئالدىن كۆرۈشنى قوزغىتىدۇ.</string>\n    <string name=\"links\">ئۇلىنىشلار</string>\n    <string name=\"ico_size_warning\">ICO ھۆججەتلىرىنى ئەڭ چوڭ بولغاندا 256 x 256 چوڭلۇقتا ساقلىغىلى بولىدۇ</string>\n    <string name=\"gif_type_to_webp\">WEBP غا سوۋغات</string>\n    <string name=\"gif_type_to_webp_sub\">GIF رەسىملىرىنى WEBP كارتون رەسىملىرىگە ئايلاندۇرۇڭ</string>\n    <string name=\"webp_tools\">WEBP قوراللىرى</string>\n    <string name=\"webp_tools_sub\">رەسىملەرنى WEBP كارتون رەسىمگە ئايلاندۇرۇش ياكى بېرىلگەن WEBP كارتوندىن رامكا ئېلىش</string>\n    <string name=\"webp_type_to_image\">رەسىملەرگە WEBP</string>\n    <string name=\"webp_type_to_image_sub\">WEBP ھۆججىتىنى بىر تۈركۈم رەسىملەرگە ئايلاندۇرۇڭ</string>\n    <string name=\"webp_type_to_webp_sub\">بىر تۈركۈم رەسىملەرنى WEBP ھۆججىتىگە ئايلاندۇرۇڭ</string>\n    <string name=\"webp_type_to_webp\">WEBP غا رەسىملەر</string>\n    <string name=\"select_webp_image_to_start\">باشلاش ئۈچۈن WEBP رەسىمىنى تاللاڭ</string>\n    <string name=\"manage_storage_extra_types\">ھۆججەتلەرنى تولۇق زىيارەت قىلىشقا بولمايدۇ</string>\n    <string name=\"manage_storage_extra_types_sub\">بارلىق ھۆججەتلەرنىڭ ئاندىرويىدتىكى رەسىم دەپ تونۇلمىغان JXL ، QOI ۋە باشقا رەسىملەرنى كۆرۈشىگە يول قويۇڭ. رۇخسەتسىز رەسىم قورال ساندۇقى بۇ رەسىملەرنى كۆرسىتەلمەيدۇ</string>\n    <string name=\"default_draw_color\">كۆڭۈلدىكى سىزىش رەڭگى</string>\n    <string name=\"default_draw_path_mode\">كۆڭۈلدىكى رەسىم سىزىش ھالىتى</string>\n    <string name=\"add_timestamp\">ۋاقىت جەدۋىلىنى قوشۇڭ</string>\n    <string name=\"add_timestamp_sub\">چىقىرىش ھۆججىتىگە Timestamp قوشۇشنى قوزغىتىدۇ</string>\n    <string name=\"formatted_timestamp\">فورماتلانغان ۋاقىت جەدۋىلى</string>\n    <string name=\"formatted_timestamp_sub\">ئاساسىي مىللىسنىڭ ئورنىغا چىقىرىش ھۆججەت نامىدا Timestamp فورماتىنى قوزغىتىڭ</string>\n    <string name=\"enable_timestamps_to_format_them\">ئۇلارنىڭ فورماتىنى تاللاش ئۈچۈن ۋاقىت تامغىسىنى قوزغىتىڭ</string>\n    <string name=\"one_time_save_location\">بىر قېتىم ئورۇننى ساقلاش</string>\n    <string name=\"one_time_save_location_sub\">بىر قېتىم ساقلاش ۋە تەھرىرلەش كۆپىنچە تاللاشلاردا ساقلاش كۇنۇپكىسىنى ئۇزۇن بېسىپ ئىشلەتسىڭىز بولىدۇ</string>\n    <string name=\"recently_used\">يېقىندا ئىشلىتىلدى</string>\n    <string name=\"ci_channel\">CI قانىلى</string>\n    <string name=\"group\">گۇرۇپپا</string>\n    <string name=\"image_toolbox_in_telegram\">تېلېگراممىدىكى رەسىم قورال ساندۇقى 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">ئۆزىڭىز خالىغان نەرسىنى مۇزاكىرە قىلالايدىغان پاراڭلىرىمىزغا قوشۇلۇڭ ، شۇنداقلا مەن beta ۋە ئېلانلارنى يوللايدىغان CI قانىلىغا قاراڭ</string>\n    <string name=\"ci_channel_sub\">ئەپنىڭ يېڭى نەشرى ھەققىدە خەۋەردار بولۇڭ ۋە ئېلانلارنى ئوقۇڭ</string>\n    <string name=\"fit_description\">رەسىمنى بېرىلگەن ئۆلچەمگە ماسلاشتۇرۇڭ ھەمدە تەگلىككە سۇس ياكى رەڭ ئىشلىتىڭ</string>\n    <string name=\"tools_arrangement\">قوراللارنى ئورۇنلاشتۇرۇش</string>\n    <string name=\"group_tools_by_type\">گۇرۇپپا قوراللىرى</string>\n    <string name=\"group_tools_by_type_sub\">گۇرۇپپا ئېكرانى ئاساسلىق ئېكراندىكى تۈرلەرنى ئىختىيارى تىزىملىكنىڭ ئورنىغا ئەمەس</string>\n    <string name=\"default_values\">كۆڭۈلدىكى قىممەت</string>\n    <string name=\"system_bars_visibility\">سىستېما بالداقلىرى</string>\n    <string name=\"show_system_bars_by_swipe\">سىيرىلما سىستېما بالدىقىنى كۆرسەت</string>\n    <string name=\"show_system_bars_by_swipe_sub\">ئەگەر يوشۇرۇن بولسا سىستېما بالدىقىنى كۆرسىتىش ئۈچۈن سۈرتۈشنى قوزغىتىدۇ</string>\n    <string name=\"auto\">ئاپتوماتىك</string>\n    <string name=\"hide_all\">ھەممىنى يوشۇر</string>\n    <string name=\"show_all\">ھەممىنى كۆرسەت</string>\n    <string name=\"hide_nav_bar\">Nav Bar نى يوشۇرۇش</string>\n    <string name=\"hide_status_bar\">ھالەت بالدىقىنى يوشۇرۇش</string>\n    <string name=\"noise_generation\">شاۋقۇن ئەۋلاد</string>\n    <string name=\"noise_generation_sub\">پېرلىن ياكى باشقا تىپلارغا ئوخشاش ئوخشىمىغان ئاۋازلارنى ھاسىل قىلىڭ</string>\n    <string name=\"frequency\">چاستوتىسى</string>\n    <string name=\"noise_type\">شاۋقۇن تىپى</string>\n    <string name=\"rotation_type\">ئايلىنىش تىپى</string>\n    <string name=\"fractal_type\">Fractal Type</string>\n    <string name=\"octaves\">Octaves</string>\n    <string name=\"lacunarity\">Lacunarity</string>\n    <string name=\"gain\">Gain</string>\n    <string name=\"weighted_strength\">ئېغىرلىق كۈچى</string>\n    <string name=\"ping_pong_strength\">Ping Pong Strength</string>\n    <string name=\"distance_function\">ئارىلىق ئىقتىدارى</string>\n    <string name=\"return_type\">قايتىش تىپى</string>\n    <string name=\"jitter\">Jitter</string>\n    <string name=\"domain_warp\">Domain Warp</string>\n    <string name=\"alignment\">توغرىلاش</string>\n    <string name=\"custom_filename\">خاس ھۆججەت ئىسمى</string>\n    <string name=\"custom_filename_sub\">نۆۋەتتىكى رەسىمنى ساقلاشقا ئىشلىتىلىدىغان ئورۇن ۋە ھۆججەت نامىنى تاللاڭ</string>\n    <string name=\"saved_to_custom\">خاس ئىسىم بىلەن ھۆججەت قىسقۇچقا ساقلاندى</string>\n    <string name=\"collage_maker\">Collage Maker</string>\n    <string name=\"collage_maker_sub\">20 پارچە رەسىمگە قەدەر كوللاگېن ياساڭ</string>\n    <string name=\"collage_type\">Collage Type</string>\n    <string name=\"collages_info\">ئورۇننى تەڭشەش ئۈچۈن رەسىمنى ئالماشتۇرۇش ، يۆتكەش ۋە چوڭايتىش</string>\n    <string name=\"disable_rotation\">ئايلىنىشنى چەكلەڭ</string>\n    <string name=\"disable_rotation_sub\">ئىككى بارماق ئىزى بىلەن رەسىمنىڭ ئايلىنىشىنىڭ ئالدىنى ئالىدۇ</string>\n    <string name=\"enable_snapping_to_borders\">چېگرانى تارتىۋېلىشنى قوزغىتىڭ</string>\n    <string name=\"enable_snapping_to_borders_sub\">يۆتكەلگەن ياكى چوڭايتقاندىن كېيىن ، رەسىملەر تارلىنىپ رامكا قىرلىرىنى تولدۇرىدۇ</string>\n    <string name=\"histogram\">Histogram</string>\n    <string name=\"histogram_sub\">RGB ياكى Brightness رەسىم گىستوگراممىسى سىزنىڭ تەڭشىشىڭىزگە ياردەم بېرىدۇ</string>\n    <string name=\"image_for_histogram\">بۇ رەسىم RGB ۋە Brightness histograms ھاسىل قىلىشقا ئىشلىتىلىدۇ</string>\n    <string name=\"tesseract_options\">سىناق تاللانمىلىرى</string>\n    <string name=\"tesseract_options_sub\">سىناق ماتورىغا بىر قىسىم كىرگۈزگۈچى ئۆزگەرگۈچى مىقدارلارنى ئىشلىتىڭ</string>\n    <string name=\"custom_options\">ئىختىيارى تاللانما</string>\n    <string name=\"custom_params_info\">بۇ ئەندىزە بويىچە تاللاشلار كىرگۈزۈلۈشى كېرەك: \\ \\\"- {option_name} {value} \\\"</string>\n    <string name=\"auto_crop\">Auto Crop</string>\n    <string name=\"free_corners\">ھەقسىز بۇلۇڭ</string>\n    <string name=\"free_corners_sub\">كۆپ قىرلىق رەسىمنى كېسىش ، بۇمۇ كۆز قاراشنى توغرىلايدۇ</string>\n    <string name=\"coerce_points_to_image_bounds\">رەسىم چەكلىمىسىگە مەجبۇرلاش نۇقتىلىرى</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">نۇقتا رەسىم چەكلىمىسى بىلەنلا چەكلەنمەيدۇ ، بۇ تېخىمۇ ئېنىق بولغان كۆز قاراشنى تۈزىتىشكە پايدىلىق</string>\n    <string name=\"mask\">ماسكا</string>\n    <string name=\"spot_heal_sub\">سىزىلغان يول ئاستىدا مەزمۇننى تولدۇرۇش</string>\n    <string name=\"spot_heal\">Heal Spot</string>\n    <string name=\"use_circle_kernel\">Circle Kernel نى ئىشلىتىڭ</string>\n    <string name=\"opening\">ئېچىش</string>\n    <string name=\"closing\">تاقاش</string>\n    <string name=\"morphological_gradient\">Morphological Gradient</string>\n    <string name=\"top_hat\">Top Hat</string>\n    <string name=\"black_hat\">Black Hat</string>\n    <string name=\"tone_curves\">تون ئەگرى سىزىق</string>\n    <string name=\"reset_curves\">ئەگرى سىزىقنى ئەسلىگە كەلتۈرۈش</string>\n    <string name=\"reset_curves_sub\">ئەگرى قىممەت سۈكۈتتىكى قىممەتكە قايتۇرۇلىدۇ</string>\n    <string name=\"line_style\">Line Style</string>\n    <string name=\"gap_size\">Gap Size</string>\n    <string name=\"dashed\">Dashed</string>\n    <string name=\"dot_dashed\">Dot Dashed</string>\n    <string name=\"stamped\">تامغا بېسىلغان</string>\n    <string name=\"zigzag\">Zigzag</string>\n    <string name=\"dashed_sub\">سىزىلغان يولنى بويلاپ سىزىقنىڭ سىزىقىنى سىزىپ چىقتى</string>\n    <string name=\"dot_dashed_sub\">بېرىلگەن يولنى بويلاپ چېكىت ۋە سىزىق سىزىدۇ</string>\n    <string name=\"defaultt_sub\">سۈكۈتتىكى تۈز سىزىقلار</string>\n    <string name=\"stamped_sub\">بەلگىلەنگەن ئارىلىق بىلەن يول بويى تاللانغان شەكىللەرنى سىزىدۇ</string>\n    <string name=\"zigzag_sub\">يول بويى دولقۇنسىمان زىگزا سىزىدۇ</string>\n    <string name=\"zigzag_ratio\">Zigzag نىسبىتى</string>\n    <string name=\"create_shortcut\">تېزلەتمە قۇرۇش</string>\n    <string name=\"create_shortcut_title\">مىخلاش قورالىنى تاللاڭ</string>\n    <string name=\"create_shortcut_subtitle\">قورال قوزغاتقۇچنىڭ باش ئېكرانىغا تېزلەتمە سۈپىتىدە قوشۇلىدۇ ، ئۇنى \\ \\\"ھۆججەت تاللاشتىن ئاتلاش \\\" تەڭشىكى بىلەن بىرلەشتۈرۈپ ، لازىملىق ھەرىكەتنى ئەمەلگە ئاشۇرۇڭ.</string>\n    <string name=\"dont_stack_frames\">رامكىنى دۆۋىلەپ قويماڭ</string>\n    <string name=\"dont_stack_frames_sub\">ئالدىنقى رامكىلارنى بىر تەرەپ قىلىشنى قوزغىتىدۇ ، شۇڭا ئۇلار بىر-بىرىگە چاپلاشمايدۇ</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">رامكىلار بىر-بىرىگە گىرەلىشىپ كېتىدۇ</string>\n    <string name=\"crossfade_count\">ھالقىما رامكا سانى</string>\n    <string name=\"threshold_one\">Threshold One</string>\n    <string name=\"threshold_two\">Threshold Two</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">Mirror 101</string>\n    <string name=\"enhanced_zoom_blur\">كۈچەيتىلگەن چوڭايتىش</string>\n    <string name=\"laplacian_simple\">Laplacian Simple</string>\n    <string name=\"sobel_simple\">Sobel Simple</string>\n    <string name=\"helper_grid\">Helper Grid</string>\n    <string name=\"helper_grid_sub\">رەسىم سىزىش ئۈستىدىكى تىرەك تورىنى كۆرسىتىپ ، ئېنىق كونترول قىلىشقا ياردەم بېرىدۇ</string>\n    <string name=\"grid_color\">Grid Color</string>\n    <string name=\"cell_width\">Cell Width</string>\n    <string name=\"cell_height\">Cell Height</string>\n    <string name=\"compact_selectors\">ئىخچام تاللىغۇچىلار</string>\n    <string name=\"compact_selectors_sub\">بەزى تاللاش كونتروللىرى ئىخچام ئورۇنلاشتۇرۇش ئارقىلىق ئازراق بوشلۇق ئالىدۇ</string>\n    <string name=\"grant_camera_permission_to_capture_image\">رەسىمگە تارتىش ئۈچۈن تەڭشەكلەردە كامېرا ئىجازەتنامىسى بېرىڭ</string>\n    <string name=\"layout\">Layout</string>\n    <string name=\"main_screen_title\">ئاساسلىق ئېكران ئىسمى</string>\n    <string name=\"constant_rate_factor\">تۇراقلىق باھا ئامىلى (CRF)</string>\n    <string name=\"crf_sub\">%1$s نىڭ قىممىتى ئاستا پىرىسلاشنى كۆرسىتىدۇ ، نەتىجىدە ھۆججەت چوڭلۇقى بىر قەدەر كىچىك بولىدۇ. %2$s تېخىمۇ تېز پىرىسلاشنى كۆرسىتىدۇ ، نەتىجىدە چوڭ ھۆججەت چىقىدۇ.</string>\n    <string name=\"lut_library\">لۇت كۇتۇپخانىسى</string>\n    <string name=\"lut_library_sub\">چۈشۈرگەندىن كېيىن قوللانسىڭىز بولىدىغان LUTs توپلىمىنى چۈشۈرۈڭ</string>\n    <string name=\"lut_library_update_sub\">LUTs توپلىمىنى يېڭىلاڭ (پەقەت يېڭىلىرى ئۆچرەتتە تۇرىدۇ) ، چۈشۈرگەندىن كېيىن ئىلتىماس قىلسىڭىز بولىدۇ</string>\n    <string name=\"filter_preview_image_sub\">سۈزگۈچلەرنىڭ سۈكۈتتىكى سۈرىتىنى ئۆزگەرتىڭ</string>\n    <string name=\"filter_preview_image\">رەسىمنى ئالدىن كۆرۈش</string>\n    <string name=\"hide\">يوشۇر</string>\n    <string name=\"show\">Show</string>\n    <string name=\"slider_type\">سىيرىلما تىپى</string>\n    <string name=\"fancy\">Fancy</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"fancy_sub\">ئېسىل كۆرۈنىدىغان سىيرىلغۇچ. بۇ سۈكۈتتىكى تاللاش</string>\n    <string name=\"material_2_sub\">ماتېرىيال 2 سىيرىلغۇچ</string>\n    <string name=\"material_you_slider_sub\">سىيرىلما ماتېرىيال</string>\n    <string name=\"apply\">ئىلتىماس قىلىڭ</string>\n    <string name=\"center_align_dialog_buttons\">مەركىزى دىئالوگ كۇنۇپكىسى</string>\n    <string name=\"center_align_dialog_buttons_sub\">دىئالوگ كۇنۇپكىلىرى مۇمكىن بولسا سول تەرەپنىڭ ئورنىغا مەركەزگە ئورۇنلاشتۇرۇلىدۇ</string>\n    <string name=\"open_source_licenses\">ئوچۇق كود ئىجازەتنامىسى</string>\n    <string name=\"open_source_licenses_sub\">بۇ ئەپتە ئىشلىتىلگەن ئوچۇق كود كۈتۈپخانىلىرىنىڭ ئىجازەتنامىسىنى كۆرۈڭ</string>\n    <string name=\"area\">رايون</string>\n    <string name=\"area_sub\">پېكسىل رايون مۇناسىۋىتىنى ئىشلىتىپ قايتا قۇرۇش. ئۇ رەسىمنى يوقىتىشنىڭ ياقتۇرىدىغان ئۇسۇلى بولۇشى مۇمكىن ، چۈنكى ئۇ moire \\ \\'- ھەقسىز نەتىجىنى بېرىدۇ. ئەمما رەسىمنى چوڭايتقاندا ، ئۇ \\ \\\"ئەڭ يېقىن \\\" ئۇسۇلىغا ئوخشايدۇ.</string>\n    <string name=\"enable_tonemapping\">Tonemapping نى قوزغىتىڭ</string>\n    <string name=\"enter_percent\">% نى كىرگۈزۈڭ</string>\n    <string name=\"unknown_host\">تور بېكەتنى زىيارەت قىلالمايدۇ ، VPN ئىشلىتىپ سىناپ بېقىڭ ياكى url نىڭ توغرا ياكى ئەمەسلىكىنى تەكشۈرۈڭ</string>\n    <string name=\"markup_layers\">Markup Layers</string>\n    <string name=\"markup_layers_sub\">رەسىم ، تېكىست ۋە باشقىلارنى ئەركىن قويۇش ئىقتىدارىغا ئىگە قەۋەت ھالىتى</string>\n    <string name=\"edit_layer\">قەۋەتنى تەھرىرلەش</string>\n    <string name=\"layers_on_image\">رەسىمدىكى قەۋەت</string>\n    <string name=\"layers_on_image_sub\">رەسىمنى تەگلىك قىلىپ ئىشلىتىڭ ھەمدە ئۇنىڭ ئۈستىگە ئوخشىمىغان قاتلاملارنى قوشۇڭ</string>\n    <string name=\"layers_on_background\">تەگلىكتىكى قەۋەت</string>\n    <string name=\"layers_on_background_sub\">بىرىنچى تاللاش بىلەن ئوخشاش ، ئەمما رەسىمنىڭ ئورنىغا رەڭ بىلەن</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">تېز تەڭشەكلەر</string>\n    <string name=\"fast_settings_side_sub\">رەسىملەرنى تەھرىرلەۋاتقاندا تاللانغان تەرەپكە لەيلىمە بەلۋاغ قوشۇڭ ، چەككەندە تېز تەڭشەكلەر ئېچىلىدۇ</string>\n    <string name=\"clear_selection\">تاللاشنى تازىلاش</string>\n    <string name=\"settings_group_visibility_hidden\">\"گۇرۇپپا تەڭشەش  \\\"%1$s \\\" سۈكۈتتىكى ھالەتتە يىمىرىلىدۇ\"</string>\n    <string name=\"settings_group_visibility_visible\">\"گۇرۇپپا تەڭشەش  \\\"%1$s \\\" سۈكۈتتىكى ھالەتتە كېڭەيتىلىدۇ\"</string>\n    <string name=\"base_64_tools\">Base64 قوراللىرى</string>\n    <string name=\"base_64_tools_sub\">Base64 تىزمىسىنى رەسىمگە يېشىش ياكى رەسىمنى Base64 فورماتىغا كودلاش</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">تەمىنلەنگەن قىممەت ئىناۋەتلىك Base64 تىزمىسى ئەمەس</string>\n    <string name=\"copy_not_a_valid_base_64\">قۇرۇق ياكى ئىناۋەتسىز Base64 تىزمىسىنى كۆچۈرگىلى بولمايدۇ</string>\n    <string name=\"paste_base_64\">Paste Base64</string>\n    <string name=\"copy_base_64\">Base64 نى كۆچۈرۈڭ</string>\n    <string name=\"base_64_tips\">Base64 تىزمىسىنى كۆچۈرۈش ياكى ساقلاش ئۈچۈن رەسىم يۈكلەڭ. ئەگەر سىزدە بۇ تىزمىنىڭ ئۆزى بولسا ، ئۇنى چاپلاپ رەسىمگە ئېرىشسىڭىز بولىدۇ</string>\n    <string name=\"save_base_64\">Base64 نى ساقلاڭ</string>\n    <string name=\"share_base_64\">Base64 نى ئورتاقلىشىش</string>\n    <string name=\"options\">تاللانما</string>\n    <string name=\"actions\">ھەرىكەتلەر</string>\n    <string name=\"import_base_64\">Base64 نى ئەكىرىش</string>\n    <string name=\"base_64_actions\">Base64 Actions</string>\n    <string name=\"add_outline\">Outline نى قوشۇڭ</string>\n    <string name=\"add_outline_sub\">بەلگىلەنگەن رەڭ ۋە كەڭلىكتىكى تېكىست ئەتراپىغا سىزىق قوشۇڭ</string>\n    <string name=\"outline_color\">سىزىق رەڭ</string>\n    <string name=\"outline_size\">سىزىق چوڭلۇقى</string>\n    <string name=\"rotation\">ئايلىنىش</string>\n    <string name=\"checksum_as_filename\">ھۆججەت ئىسمى</string>\n    <string name=\"checksum_as_filename_sub\">چىقىرىلغان رەسىملەرنىڭ سانلىق مەلۇمات تەكشۈرۈشىگە ماس كېلىدىغان ئىسمى بولىدۇ</string>\n    <string name=\"free_software_partner\">ھەقسىز يۇمشاق دېتال (ھەمكارلاشقۇچى)</string>\n    <string name=\"free_software_partner_sub\">ئاندىرويىد قوللىنىشچان پروگراممىلىرىنىڭ ھەمكارلىق قانىلىدىكى تېخىمۇ پايدىلىق يۇمشاق دېتاللار</string>\n    <string name=\"algorithms\">ئالگورىزىم</string>\n    <string name=\"checksum_tools\">تەكشۈرۈش قوراللىرى</string>\n    <string name=\"checksum_tools_sub\">تەكشۈرۈشنى سېلىشتۇرۇڭ ، ھەش-پەش دېگۈچە ھېسابلاڭ ياكى ئوخشىمىغان ئالدىراش ھېسابلاش ئۇسۇلى ئارقىلىق ھۆججەتلەردىن ئالتە تال سىزىق ھاسىل قىلىڭ</string>\n    <string name=\"calculate\">ھېسابلاپ بېقىڭ</string>\n    <string name=\"text_hash\">Text Hash</string>\n    <string name=\"checksum\">Checksum</string>\n    <string name=\"pick_file_to_checksum\">تاللانغان ئالگورىزىمغا ئاساسەن تەكشۈرۈشنى ھېسابلاش ئۈچۈن ھۆججەت تاللاڭ</string>\n    <string name=\"enter_text_to_checksum\">تاللانغان ئالگورىزىمغا ئاساسەن تېكىستنى كىرگۈزۈڭ</string>\n    <string name=\"source_checksum\">Source Checksum</string>\n    <string name=\"checksum_to_compare\">سېلىشتۇرۇش ئۈچۈن تەكشۈرۈش</string>\n    <string name=\"match\">ماس!</string>\n    <string name=\"difference\">پەرقى</string>\n    <string name=\"match_sub\">تەكشۈرۈش باراۋەر ، بىخەتەر بولىدۇ</string>\n    <string name=\"difference_sub\">تەكشۈرۈش باراۋەر ئەمەس ، ھۆججەت بىخەتەر ئەمەس!</string>\n    <string name=\"mesh_gradients\">Mesh Gradients</string>\n    <string name=\"collection_mesh_gradients_sub\">Mesh Gradients نىڭ تور توپلىمىغا قاراڭ</string>\n    <string name=\"wrong_font\">پەقەت TTF ۋە OTF خەت نۇسخىسىنىلا ئىمپورتلىغىلى بولىدۇ</string>\n    <string name=\"import_font\">خەت نۇسخىسىنى ئەكىرىش (TTF / OTF)</string>\n    <string name=\"export_fonts\">خەت نۇسخىسىنى چىقىرىش</string>\n    <string name=\"imported_fonts\">ئىمپورت قىلىنغان خەت نۇسخىسى</string>\n    <string name=\"error_while_saving\">ساقلاشنى ساقلاش جەريانىدا خاتالىق ، چىقىرىش قىسقۇچىنى ئۆزگەرتىشكە تىرىشىڭ</string>\n    <string name=\"filename_is_not_set\">ھۆججەت ئىسمى بېكىتىلمىگەن</string>\n    <string name=\"none\">ياق</string>\n    <string name=\"custom_pages\">ئىختىيارى بەتلەر</string>\n    <string name=\"pages_selection\">بەت تاللاش</string>\n    <string name=\"tool_exit_confirmation\">قورالدىن چىقىشنى جەزملەشتۈرۈش</string>\n    <string name=\"tool_exit_confirmation_sub\">ئەگەر ئالاھىدە قوراللارنى ئىشلەتكەندە ساقلانمىغان ئۆزگىرىشلەر بولۇپ ، ئۇنى تاقاپ سىناپ بېقىڭ ، ئۇنداقتا سۆزلىشىشنىڭ كۆرسىتىلىدىغانلىقىنى جەزملەشتۈرۈڭ</string>\n    <string name=\"edit_exif_screen\">EXIF نى تەھرىرلەڭ</string>\n    <string name=\"edit_exif_screen_sub\">يەككە رەسىمنىڭ مېتا سانلىق مەلۇماتلىرىنى قايتا-قايتا ئۆزگەرتمەي ئۆزگەرتىڭ</string>\n    <string name=\"edit_exif_tag\">ئىشلەتكىلى بولىدىغان خەتكۈچلەرنى تەھرىرلەش ئۈچۈن چېكىڭ</string>\n    <string name=\"change_sticker\">Sticker نى ئۆزگەرتىڭ</string>\n    <string name=\"fit_width\">Fit Width</string>\n    <string name=\"fit_height\">Fit Height</string>\n    <string name=\"batch_compare\">Batch Compare</string>\n    <string name=\"pick_files_to_checksum\">تاللانغان ئالگورىزىمغا ئاساسەن ھۆججەت / ھۆججەتلەرنى تاللاڭ</string>\n    <string name=\"pick_files\">ھۆججەتلەرنى تاللاڭ</string>\n    <string name=\"pick_directory\">مۇندەرىجىنى تاللاڭ</string>\n    <string name=\"head_length_scale\">باش ئۇزۇنلۇقى</string>\n    <string name=\"stamp\">تامغا</string>\n    <string name=\"timestamp\">Timestamp</string>\n    <string name=\"format_pattern\">فورمات ئۈلگىسى</string>\n    <string name=\"padding\">Padding</string>\n    <string name=\"image_cutting\">رەسىم كېسىش</string>\n    <string name=\"image_cutting_sub\">رەسىم قىسمىنى كېسىپ ، تىك ياكى توغرىسىغا سىزىق ئارقىلىق سول تەرەپلەرنى (تەتۈر يۆنىلىشتە) بىرلەشتۈرۈڭ</string>\n    <string name=\"vertical_pivot_line\">Vertical Pivot Line</string>\n    <string name=\"horizontal_pivot_line\">توغرىسىغا توغرىلاش لىنىيىسى</string>\n    <string name=\"inverse_selection\">تەتۈر تاللاش</string>\n    <string name=\"inverse_vertical_selection_sub\">كېسىلگەن رايون ئەتراپىدىكى زاپچاسلارنى بىرلەشتۈرۈشنىڭ ئورنىغا تىك كېسىلگەن قىسمى قالدۇرۇلىدۇ</string>\n    <string name=\"inverse_horizontal_selection_sub\">كېسىلگەن رايون ئەتراپىدىكى بۆلەكلەرنى بىرلەشتۈرۈشنىڭ ئورنىغا ، توغرىسىغا كېسىلگەن قىسمى قالدۇرۇلىدۇ</string>\n    <string name=\"collection_mesh_gradients\">Mesh Gradients توپلىمى</string>\n    <string name=\"mesh_gradients_sub\">خاس مىقداردىكى تۈگۈن ۋە ئېنىقلىق دەرىجىسى بىلەن تور دەرىجىسىنى ھاسىل قىلىڭ</string>\n    <string name=\"gradient_maker_type_image_mesh\">Mesh Gradient Overlay</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">بېرىلگەن رەسىملەرنىڭ ئۈستىگە تور دەرىجىسىنى تەدرىجىي تۈزۈڭ</string>\n    <string name=\"points_customization\">نۇقتىنى خاسلاشتۇرۇش</string>\n    <string name=\"grid_size\">Grid Size</string>\n    <string name=\"resolution_x\">ئېنىقلىق X.</string>\n    <string name=\"resolution_y\">قارار Y.</string>\n    <string name=\"resolution\">قارار</string>\n    <string name=\"pixel_by_pixel\">Pixel By Pixel</string>\n    <string name=\"highlight_color\">رەڭنى گەۋدىلەندۈرۈش</string>\n    <string name=\"pixel_comparison_type\">Pixel سېلىشتۇرۇش تىپى</string>\n    <string name=\"scan_barcode\">تاياقچە كودىنى سايىلەڭ</string>\n    <string name=\"height_ratio\">ئېگىزلىك نىسبىتى</string>\n    <string name=\"barcode_type\">تاياقچە كود تىپى</string>\n    <string name=\"enforce_bw\">B / W.</string>\n    <string name=\"enforce_bw_sub\">تاياقچە كودى رەسىمى پۈتۈنلەي قارا ۋە ئاق بولىدۇ ، ئەپنىڭ تېمىسى رەڭدار بولمايدۇ</string>\n    <string name=\"barcodes_sub\">ھەر قانداق تاياقچە كودنى سايىلاڭ (QR, EAN, AZTEC,…) ۋە ئۇنىڭ مەزمۇنىغا ئېرىشىڭ ياكى تېكىستىڭىزنى چاپلاپ يېڭى ھاسىل قىلىڭ</string>\n    <string name=\"no_barcode_found\">تاياقچە كودى تېپىلمىدى</string>\n    <string name=\"generated_barcode_will_be_here\">ھاسىل قىلىنغان تاياقچە كودى بۇ يەردە بولىدۇ</string>\n    <string name=\"audio_cover_extractor\">Audio Covers</string>\n    <string name=\"audio_cover_extractor_sub\">ئاۋاز ھۆججىتىدىن پىلاستىنكا مۇقاۋا رەسىملىرىنى چىقىرىڭ ، كۆپ ئۇچرايدىغان فورماتلارنى قوللايدۇ</string>\n    <string name=\"pick_audio_to_start\">باشلاش ئۈچۈن ئاۋاز تاللاڭ</string>\n    <string name=\"pick_audio\">ئاۋازنى تاللاڭ</string>\n    <string name=\"no_covers_found\">Covers تېپىلمىدى</string>\n    <string name=\"send_logs\">خاتىرە ئەۋەتىڭ</string>\n    <string name=\"send_logs_sub\">ئەپ خاتىرىسىنى ئورتاقلىشىش ئۈچۈن چېكىڭ ، بۇ مېنىڭ مەسىلىنى بايقىشىم ۋە مەسىلىلەرنى ھەل قىلىشىمغا ياردەم بېرەلەيدۇ</string>\n    <string name=\"crash_title\">ئاپلا… چاتاق چىقتى</string>\n    <string name=\"crash_subtitle\">تۆۋەندىكى تاللاشلار ئارقىلىق مەن بىلەن ئالاقىلاشسىڭىز بولىدۇ ، مەن ھەل قىلىش چارىسى تېپىشقا تىرىشىمەن. \\ N (خاتىرە باغلاشنى ئۇنتۇپ قالماڭ)</string>\n    <string name=\"ocr_write_to_file\">ھۆججەتكە يېزىڭ</string>\n    <string name=\"ocr_write_to_file_sub\">بىر تۈركۈم رەسىملەردىن تېكىستنى چىقىرىپ بىر تېكىست ھۆججىتىگە ساقلاڭ</string>\n    <string name=\"ocr_write_to_metadata\">Metadata غا يېزىڭ</string>\n    <string name=\"ocr_write_to_metadata_sub\">ھەر بىر رەسىمدىن تېكىست چىقىرىپ ، مۇناسىۋەتلىك رەسىملەرنىڭ EXIF ​​ئۇچۇرىغا قويۇڭ</string>\n    <string name=\"invisible_mode\">كۆرۈنمەيدىغان ھالەت</string>\n    <string name=\"invisible_mode_sub\">Steganography ئارقىلىق رەسىملىرىڭىزنىڭ بايتلىرى ئىچىدە كۆزگە كۆرۈنمەيدىغان سۇ بەلگىسى ھاسىل قىلىڭ</string>\n    <string name=\"use_lsb\">LSB نى ئىشلىتىڭ</string>\n    <string name=\"use_lsb_sub\">LSB (ئانچە مۇھىم بولمىغان Bit) ستېگانوگرافىيە ئۇسۇلى قوللىنىلىدۇ ، FD (چاستوتا دائىرە)</string>\n    <string name=\"auto_remove_red_eyes\">قىزىل كۆزنى ئاپتوماتىك ئۆچۈرۈڭ</string>\n    <string name=\"password\">پارول</string>\n    <string name=\"unlock\">قۇلۇپ ئېچىش</string>\n    <string name=\"pdf_is_protected\">PDF قوغدالدى</string>\n    <string name=\"operation_almost_complete\">مەشغۇلات ئاساسەن دېگۈدەك تاماملاندى. ھازىر ئەمەلدىن قالدۇرۇش ئۇنى قايتا قوزغىتىشنى تەلەپ قىلىدۇ</string>\n    <string name=\"sort_by_date_modified\">چېسلا ئۆزگەرتىلدى</string>\n    <string name=\"sort_by_date_modified_reversed\">ئۆزگەرتىلگەن ۋاقىت (قايتۇرۇلغان)</string>\n    <string name=\"sort_by_size\">چوڭلۇقى</string>\n    <string name=\"sort_by_size_reversed\">چوڭلۇقى (قايتۇرۇلغان)</string>\n    <string name=\"sort_by_mime_type\">MIME تىپى</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME تىپى (قايتۇرۇلغان)</string>\n    <string name=\"sort_by_extension\">كېڭەيتىش</string>\n    <string name=\"sort_by_extension_reversed\">كېڭەيتىش (قايتۇرۇلغان)</string>\n    <string name=\"sort_by_date_added\">چېسلا قوشۇلدى</string>\n    <string name=\"sort_by_date_added_reversed\">قوشۇلغان ۋاقىت (قايتۇرۇلغان)</string>\n    <string name=\"left_to_right\">سولدىن ئوڭغا</string>\n    <string name=\"right_to_left\">ئوڭدىن سولغا</string>\n    <string name=\"top_to_bottom\">ئۈستىدىن ئاستىغا</string>\n    <string name=\"bottom_to_top\">ئاستىدىن يۇقىرىغا</string>\n    <string name=\"liquid_glass\">سۇيۇق ئەينەك</string>\n    <string name=\"liquid_glass_sub\">يېقىندا ئېلان قىلىنغان IOS 26 نى ئاساس قىلغان ئالماشتۇرغۇچ ۋە ئۇنىڭ سۇيۇق ئەينەك لايىھىلەش سىستېمىسى</string>\n    <string name=\"pick_image_or_base64\">تۆۋەندىكى رەسىم 64 نى تاللاڭ ياكى چاپلاڭ / ئىمپورت قىلىڭ</string>\n    <string name=\"type_image_link\">باشلاش ئۈچۈن رەسىم ئۇلانمىسىنى كىرگۈزۈڭ</string>\n    <string name=\"paste_link\">ئۇلىنىشنى چاپلاڭ</string>\n    <string name=\"kaleidoscope\">Kaleidoscope</string>\n    <string name=\"secondary_angle\">ئىككىلەمچى بۇلۇڭ</string>\n    <string name=\"sides\">يان تەرەپ</string>\n    <string name=\"channel_mix\">Channel Mix</string>\n    <string name=\"blue_green\">كۆك يېشىل</string>\n    <string name=\"red_blue\">قىزىل كۆك</string>\n    <string name=\"green_red\">يېشىل قىزىل</string>\n    <string name=\"into_red\">قىزىل رەڭگە</string>\n    <string name=\"into_green\">يېشىل رەڭدە</string>\n    <string name=\"into_blue\">كۆك رەڭدە</string>\n    <string name=\"cyan\">Cyan</string>\n    <string name=\"magenta\">Magenta</string>\n    <string name=\"yellow\">سېرىق</string>\n    <string name=\"color_halftone\">رەڭ Halftone</string>\n    <string name=\"contour\">Contour</string>\n    <string name=\"levels\">Levels</string>\n    <string name=\"offset\">Offset</string>\n    <string name=\"voronoi_crystallize\">Voronoi Crystallize</string>\n    <string name=\"shape\">شەكىل</string>\n    <string name=\"stretch\">Stretch</string>\n    <string name=\"randomness\">تاسادىپىيلىق</string>\n    <string name=\"despeckle\">Despeckle</string>\n    <string name=\"diffuse\">Diffuse</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">ئىككىنچى رادىئو</string>\n    <string name=\"equalize\">تەڭگە</string>\n    <string name=\"glow\">پارقىراق</string>\n    <string name=\"whirl_and_pinch\">Whirl and Pinch</string>\n    <string name=\"pointillize\">Pointillize</string>\n    <string name=\"border_color\">چېگرا رەڭگى</string>\n    <string name=\"polar_coordinates\">قۇتۇپ كوردىناتى</string>\n    <string name=\"rect_to_polar\">قۇتۇپقا توغرىلاڭ</string>\n    <string name=\"polar_to_rect\">قۇتۇپ تۈز</string>\n    <string name=\"invert_in_circle\">چەمبەرگە ئايلاندۇرۇش</string>\n    <string name=\"reduce_noise\">شاۋقۇننى ئازايتىش</string>\n    <string name=\"simple_solarize\">ئاددىي Solarize</string>\n    <string name=\"weave\">توقۇمىچىلىق</string>\n    <string name=\"x_gap\">X Gap</string>\n    <string name=\"y_gap\">Y Gap</string>\n    <string name=\"x_width\">X Width</string>\n    <string name=\"y_wdth\">Y Width</string>\n    <string name=\"twirl\">Twirl</string>\n    <string name=\"rubber_stmp\">كاۋچۇك تامغىسى</string>\n    <string name=\"smear\">Smear</string>\n    <string name=\"density\">زىچلىقى</string>\n    <string name=\"mix\">Mix</string>\n    <string name=\"sphere_lensh_distortion\">دائىرە لىنزىسىنى بۇرمىلاش</string>\n    <string name=\"refraction_index\">سۇندۇرۇش كۆرسەتكۈچى</string>\n    <string name=\"arc\">Arc</string>\n    <string name=\"spread_angle\">بۇلۇڭ</string>\n    <string name=\"sparkle\">Sparkle</string>\n    <string name=\"rays\">نۇر</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Gradient</string>\n    <string name=\"moire\">مەريەم</string>\n    <string name=\"autumn\">كۈز</string>\n    <string name=\"bone\">سۆڭەك</string>\n    <string name=\"jet\">Jet</string>\n    <string name=\"winter\">قىش</string>\n    <string name=\"ocean\">Ocean</string>\n    <string name=\"summer\">ياز</string>\n    <string name=\"spring\">باھار</string>\n    <string name=\"cool_variant\">Cool Variant</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">ھالرەڭ</string>\n    <string name=\"hot\">قىزىق</string>\n    <string name=\"parula\">سۆز</string>\n    <string name=\"magma\">Magma</string>\n    <string name=\"inferno\">Inferno</string>\n    <string name=\"plasma\">پلازما</string>\n    <string name=\"viridis\">Viridis</string>\n    <string name=\"cividis\">پۇقرالار</string>\n    <string name=\"twilight\">Twilight</string>\n    <string name=\"twilight_shifted\">Twilight Shifted</string>\n    <string name=\"auto_perspective\">Perspective Auto</string>\n    <string name=\"deskew\">Deskew</string>\n    <string name=\"allow_crop\">زىرائەتلەرگە يول قويۇڭ</string>\n    <string name=\"crop_or_perspective\">زىرائەت ياكى ئىستىقبال</string>\n    <string name=\"absolute\">مۇتلەق</string>\n    <string name=\"turbo\">Turbo</string>\n    <string name=\"deep_green\">Deep Green</string>\n    <string name=\"lens_correction\">لىنزا تۈزىتىش</string>\n    <string name=\"target_lens_profile\">JSON فورماتىدىكى لىنزا ئارخىپى ھۆججىتى</string>\n    <string name=\"download_ready_lens_profiles\">تەييار كامېرا ئارخىپىنى چۈشۈرۈڭ</string>\n    <string name=\"part_percents\">قىسمەن پىرسەنت</string>\n    <string name=\"export_as_json\">JSON قىلىپ چىقىرىش</string>\n    <string name=\"export_as_json_sub\">Json نىڭ ئىپادىسى سۈپىتىدە پالتا سانلىق مەلۇماتلىرى بىلەن تىزمىنى كۆچۈرۈڭ</string>\n    <string name=\"seam_carving\">Seam Carving</string>\n    <string name=\"home_screen\">باش ئېكران</string>\n    <string name=\"lock_screen\">قۇلۇپ ئېكرانى</string>\n    <string name=\"built_in\">ئىچىگە قاچىلانغان</string>\n    <string name=\"wallpapers_export\">تام قەغەز ئېكسپورتى</string>\n    <string name=\"refresh\">يېڭىلاش</string>\n    <string name=\"wallpapers_export_sub\">ھازىرقى ئۆي ، قۇلۇپ ۋە ئىچىگە سېلىنغان تام قەغىزىگە ئېرىشىڭ</string>\n    <string name=\"allow_access_to_all_files_for_wp\">بارلىق ھۆججەتلەرنى زىيارەت قىلىشقا يول قويۇڭ ، بۇ تام قەغىزىنى ئەسلىگە كەلتۈرۈش ئۈچۈن كېرەك</string>\n    <string name=\"allow_read_media_images_for_wp\">سىرتقى ساقلاش ئىجازەتنامىسىنى باشقۇرۇش يېتەرلىك ئەمەس ، رەسىملىرىڭىزنى زىيارەت قىلىشىڭىزغا رۇخسەت قىلىشىڭىز ، \\ \\\"ھەممىگە يول قويۇش\\\" نى جەزملەشتۈرۈڭ.</string>\n    <string name=\"add_preset_to_filename\">ھۆججەت نامىغا ئالدىن بەلگىلەڭ</string>\n    <string name=\"add_preset_to_filename_sub\">رەسىم ھۆججىتىنىڭ نامىغا تاللانغان ئالدىن بەلگىلەش قوشۇلىدۇ</string>\n    <string name=\"add_image_scale_mode_to_filename\">ھۆججەت نامىغا رەسىم چوڭلۇقى ھالىتىنى قوشۇڭ</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">رەسىم ھۆججەت نامىغا تاللانغان رەسىم ئۆلچىمى ھالىتى بىلەن قوشۇمچە ھۆججەت قوشۇلىدۇ</string>\n    <string name=\"ascii_art\">Ascii Art</string>\n    <string name=\"ascii_art_sub\">رەسىمنى رەسىمگە ئوخشايدىغان ascii تېكىستىگە ئايلاندۇرۇڭ</string>\n    <string name=\"params\">پاراملار</string>\n    <string name=\"invert_colors_ascii_sub\">بەزى ئەھۋاللاردا تېخىمۇ ياخشى نەتىجىگە ئېرىشىش ئۈچۈن رەسىمگە پاسسىپ سۈزگۈچ قوللىنىدۇ</string>\n    <string name=\"processing_screenshot\">ئېكران رەسىمىنى بىر تەرەپ قىلىش</string>\n    <string name=\"screenshot_not_captured_try_again\">ئېكران رەسىمى تۇتۇلمىدى ، قايتا سىناڭ</string>\n    <string name=\"skipped_saving\">تېجەپ قالدى</string>\n    <string name=\"skipped_saving_multiple\">%1$s ھۆججەتلىرى ئاتلاپ كەتتى</string>\n    <string name=\"allow_skip_if_larger\">ئەگەر چوڭ بولسا ئاتلاشقا يول قويۇڭ</string>\n    <string name=\"allow_skip_if_larger_sub\">بەزى قوراللارنىڭ ساقلانغان ھۆججەتنىڭ سىغىمى ئەسلىدىكىدىن چوڭ بولسا ، تېجەشلىك رەسىملەرنى ئاتلاپ ئۆتۈپ كېتىشىگە رۇخسەت قىلىنىدۇ</string>\n    <string name=\"qr_type_calendar_event\">كالېندار پائالىيىتى</string>\n    <string name=\"qr_type_contact_info\">ئالاقىلىشىڭ</string>\n    <string name=\"qr_type_email\">ئېلخەت</string>\n    <string name=\"qr_type_geo_point\">ئورنى</string>\n    <string name=\"qr_type_phone\">تېلېفون</string>\n    <string name=\"qr_type_plain\">تېكىست</string>\n    <string name=\"qr_type_sms\">قىسقا ئۇچۇر</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">تورنى ئېچىڭ</string>\n    <string name=\"not_specified\">N / A.</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">تېلېفون</string>\n    <string name=\"message\">ئۇچۇر</string>\n    <string name=\"address\">ئادرېس</string>\n    <string name=\"subject\">تېما</string>\n    <string name=\"body\">بەدەن</string>\n    <string name=\"name\">ئىسمى</string>\n    <string name=\"organization\">تەشكىلات</string>\n    <string name=\"title\">ماۋزۇ</string>\n    <string name=\"phones\">تېلېفون</string>\n    <string name=\"emails\">Email</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">ئادرېس</string>\n    <string name=\"summary\">خۇلاسە</string>\n    <string name=\"description\">چۈشەندۈرۈش</string>\n    <string name=\"location\">ئورنى</string>\n    <string name=\"organizer\">تەشكىللىگۈچى</string>\n    <string name=\"start_date\">باشلىنىش ۋاقتى</string>\n    <string name=\"end_date\">ئاخىرلىشىش ۋاقتى</string>\n    <string name=\"status\">ھالەت</string>\n    <string name=\"latitude\">كەڭلىك</string>\n    <string name=\"longitude\">ئۇزۇنلۇق</string>\n    <string name=\"create_barcode\">تاياقچە كود قۇرۇش</string>\n    <string name=\"edit_barcode\">تاياقچە كودىنى تەھرىرلەڭ</string>\n    <string name=\"wifi_configuration\">Wi-Fi سەپلىمىسى</string>\n    <string name=\"security\">بىخەتەرلىك</string>\n    <string name=\"pick_contact\">ئالاقىنى تاللاڭ</string>\n    <string name=\"grant_contact_permission\">تاللانغان ئالاقىلىشىش ئارقىلىق ئاپتوماتىك تولدۇرۇش ئۈچۈن تەڭشەكلەردە ئالاقىلىشىش ئىجازەتنامىسى بېرىڭ</string>\n    <string name=\"contact_info\">ئالاقىلىشىش ئۇچۇرلىرى</string>\n    <string name=\"first_name\">ئىسمى</string>\n    <string name=\"middle_name\">ئوتتۇرا ئىسمى</string>\n    <string name=\"last_name\">فامىلىسى</string>\n    <string name=\"pronunciation\">تەلەپپۇز</string>\n    <string name=\"add_phone\">تېلېفون قوشۇڭ</string>\n    <string name=\"add_email\">ئېلېكترونلۇق خەت قوشۇڭ</string>\n    <string name=\"add_address\">ئادرېس قوشۇڭ</string>\n    <string name=\"website\">تور بېكەت</string>\n    <string name=\"add_website\">توربېكەت قوشۇڭ</string>\n    <string name=\"formatted_name\">فورماتلانغان ئىسىم</string>\n    <string name=\"qr_code_top_image\">بۇ رەسىم تاياقچە كودنىڭ ئۈستىگە قويۇشقا ئىشلىتىلىدۇ</string>\n    <string name=\"code_customization\">كودنى خاسلاشتۇرۇش</string>\n    <string name=\"qr_logo_image\">بۇ رەسىم QR كودىنىڭ مەركىزىدە بەلگە سۈپىتىدە ئىشلىتىلىدۇ</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">بەلگە چاپلاش</string>\n    <string name=\"logo_size\">Logo size</string>\n    <string name=\"logo_corners\">بەلگە بۇلۇڭ</string>\n    <string name=\"fourth_eye\">تۆتىنچى كۆز</string>\n    <string name=\"fourth_eye_description\">تۆۋەنكى بۇلۇڭغا تۆتىنچى كۆز قوشۇش ئارقىلىق qr كودىغا كۆز سىممېترىكلىكى قوشىدۇ</string>\n    <string name=\"pixel_shape\">Pixel شەكلى</string>\n    <string name=\"frame_shape\">رامكا شەكلى</string>\n    <string name=\"ball_shape\">توپ شەكلى</string>\n    <string name=\"error_correction_level\">خاتالىق تۈزىتىش دەرىجىسى</string>\n    <string name=\"dark_color\">قېنىق رەڭ</string>\n    <string name=\"light_color\">سۇس رەڭ</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">شياۋمى HyperOS ئۇسلۇبنى ياخشى كۆرىدۇ</string>\n    <string name=\"mask_pattern\">ماسكا ئەندىزىسى</string>\n    <string name=\"code_may_be_not_scannable\">بۇ كودنى سىكانېرلىغىلى بولمايدۇ ، كۆرۈنۈش پارامېتىرلىرىنى ئۆزگەرتىپ بارلىق ئۈسكۈنىلەر بىلەن ئوقۇغىلى بولىدۇ</string>\n    <string name=\"not_scannable\">سايىلىگىلى بولمايدۇ</string>\n    <string name=\"launcher_mode_sub\">قوراللار تېخىمۇ ئىخچام بولۇش ئۈچۈن ئائىلە ئېكرانى ئەپ ئاچقۇچىغا ئوخشايدۇ</string>\n    <string name=\"launcher_mode\">قوزغىتىش ھالىتى</string>\n    <string name=\"flood_fill_sub\">تاللانغان چوتكا ۋە ئۇسلۇب بىلەن رايوننى تولدۇرىدۇ</string>\n    <string name=\"flood_fill\">كەلكۈن</string>\n    <string name=\"spray\">پۈركۈش</string>\n    <string name=\"spray_sub\">تارتىش كۈچى ئۇسلۇبتىكى يولنى سىزىدۇ</string>\n    <string name=\"square_particles\">Square Particles</string>\n    <string name=\"square_particles_sub\">پۈركۈش زەررىچىلىرى چەمبەرنىڭ ئورنىغا چاسا شەكىللىك بولىدۇ</string>\n    <string name=\"palette_tools\">Palette Tools</string>\n    <string name=\"palette_tools_sub\">رەسىمدىن سىزغان ئاساسىي / ماتېرىيال ھاسىل قىلىڭ ياكى ئوخشىمىغان پالتا فورماتىدا ئىمپورت-ئېكىسپورت قىلىڭ</string>\n    <string name=\"edit_palette\">Palette نى تەھرىرلەڭ</string>\n    <string name=\"edit_palette_sub\">ھەر خىل فورماتتىكى پالتىنى چىقىرىش / ئىمپورت قىلىش</string>\n    <string name=\"color_name\">رەڭ ئىسمى</string>\n    <string name=\"palette_name\">Palette name</string>\n    <string name=\"palette_format\">Palette Format</string>\n    <string name=\"export_palette_sub\">ھاسىل قىلىنغان پالتىنى ئوخشىمىغان فورماتلارغا چىقىرىش</string>\n    <string name=\"add_color_palette_sub\">ھازىرقى پالتىغا يېڭى رەڭ قوشىدۇ</string>\n    <string name=\"palette_name_not_supported\">%1$s فورماتى palette نامىنى تەمىنلەشنى قوللىمايدۇ</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Play Store سىياسىتى سەۋەبىدىن ، بۇ ئىقتىدارنى ھازىرقى قۇرۇلۇشقا كىرگۈزگىلى بولمايدۇ. بۇ ئىقتىدارنى زىيارەت قىلىش ئۈچۈن ImageToolbox نى باشقا مەنبەدىن چۈشۈرۈڭ. تۆۋەندىكى GitHub دا بار بولغان قۇرۇلۇشلارنى تاپالايسىز.</string>\n    <string name=\"open_github_page\">Github بېتىنى ئېچىڭ</string>\n    <string name=\"overwrite_files_sub_short\">ئەسلى ھۆججەت تاللانغان ھۆججەت قىسقۇچتا ساقلاشنىڭ ئورنىغا يېڭى ھۆججەتكە ئالماشتۇرۇلىدۇ</string>\n    <string name=\"hidden_watermark_text_detected\">يوشۇرۇن سۇ بەلگىسى تېكىستى بايقالدى</string>\n    <string name=\"hidden_watermark_image_detected\">يوشۇرۇن سۇ بەلگىسى رەسىمى بايقالدى</string>\n    <string name=\"this_image_was_hidden\">بۇ رەسىم يوشۇرۇنغان</string>\n    <string name=\"generative_inpaint\">Generative Inpainting</string>\n    <string name=\"generative_inpaint_sub\">OpenCV غا تايانماي ، سۈنئىي ئەقىل مودېلى ئارقىلىق رەسىمدىكى نەرسىلەرنى ئۆچۈرۈشىڭىزگە يول قويىدۇ. بۇ ئىقتىدارنى ئىشلىتىش ئۈچۈن ، ئەپ GitHub دىن لازىملىق مودېلنى (~ 200 MB) چۈشۈرۈۋالىدۇ</string>\n    <string name=\"generative_inpaint_ready_sub\">OpenCV غا تايانماي ، سۈنئىي ئەقىل مودېلى ئارقىلىق رەسىمدىكى نەرسىلەرنى ئۆچۈرۈشىڭىزگە يول قويىدۇ. بۇ ئۇزۇنغا سوزۇلغان مەشغۇلات بولۇشى مۇمكىن</string>\n    <string name=\"error_level_analysis\">خاتالىق دەرىجىسىنى تەھلىل قىلىش</string>\n    <string name=\"luminance_gradient\">Luminance Gradient</string>\n    <string name=\"average_distance\">ئوتتۇرىچە ئارىلىق</string>\n    <string name=\"copy_move_detection\">كۆچۈرۈشنى كۆچۈرۈش</string>\n    <string name=\"retain\">ساقلاپ قېلىش</string>\n    <string name=\"coefficent\">Coefficent</string>\n    <string name=\"clipboard_data_is_too_large\">چاپلاش تاختىسى سانلىق مەلۇماتلىرى بەك چوڭ</string>\n    <string name=\"data_is_too_large_to_copy\">كۆچۈرگىلى بولىدىغان سانلىق مەلۇمات بەك چوڭ</string>\n    <string name=\"simple_weave_pixelization\">ئاددىي توقۇمىچىلىق</string>\n    <string name=\"staggered_pixelization\">Staggered Pixelization</string>\n    <string name=\"cross_pixelization\">Cross Pixelization</string>\n    <string name=\"micro_macro_pixelization\">Micro Macro Pixelization</string>\n    <string name=\"orbital_pixelization\">Orbital Pixelization</string>\n    <string name=\"vortex_pixelization\">Vortex Pixelization</string>\n    <string name=\"pulse_grid_pixelization\">Pulse Grid Pixelization</string>\n    <string name=\"nucleus_pixelization\">Nucleus Pixelization</string>\n    <string name=\"radial_weave_pixelization\">Radial Weave Pixelization</string>\n    <string name=\"cannot_open_uri\">\"Uri  \\\"%1$s \\\" نى ئاچقىلى بولمايدۇ\"</string>\n    <string name=\"snowfall_mode\">قار يېغىش ھالىتى</string>\n    <string name=\"enabled\">قوزغىتىلدى</string>\n    <string name=\"border_frame\">چېگرا رامكىسى</string>\n    <string name=\"glitch_variant\">Glitch Variant</string>\n    <string name=\"channel_shift\">Channel Shift</string>\n    <string name=\"max_offset\">Max Offset</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Block Glitch</string>\n    <string name=\"block_size\">چوڭلۇقنى چەكلەش</string>\n    <string name=\"crt_curvature\">CRT ئەگرى سىزىقى</string>\n    <string name=\"curvature\">ئەگرى سىزىق</string>\n    <string name=\"chroma\">خىروم</string>\n    <string name=\"pixel_melt\">Pixel Melt</string>\n    <string name=\"max_drop\">Max Drop</string>\n    <string name=\"ai_tools\">AI قوراللىرى</string>\n    <string name=\"ai_tools_sub\">سۈنئىي ئۇسۇلدا ئېلىۋېتىش ياكى رەتلەش قاتارلىق ئاي مودېللىرى ئارقىلىق رەسىملەرنى بىر تەرەپ قىلىدىغان ھەر خىل قوراللار</string>\n    <string name=\"model_anime_undeint\">پىرىسلاش ، باغلانغان سىزىقلار</string>\n    <string name=\"model_broadcast\">كارتون ، تارقىتىش پىرىسلاش</string>\n    <string name=\"model_rgb_max_denoise_fp16\">ئادەتتىكى پىرىسلاش ، ئادەتتىكى شاۋقۇن</string>\n    <string name=\"model_wb_denoise\">رەڭسىز كارتون شاۋقۇنى</string>\n    <string name=\"model_span_anime_pretrain\">تېز ، ئادەتتىكى پىرىسلاش ، ئادەتتىكى شاۋقۇن ، كارتون / يۇمۇر / كارتون</string>\n    <string name=\"model_book_scan\">كىتاب سايىلەش</string>\n    <string name=\"model_overexposure\">ئاشكارىلاش تۈزىتىش</string>\n    <string name=\"model_fbcnn_color_fp16\">ئادەتتىكى پىرىسلاش ، رەڭلىك رەسىملەر ئەڭ ياخشى</string>\n    <string name=\"model_fbcnn_gray_fp16\">ئادەتتىكى پىرىسلاش ، كۈلرەڭ رەسىملەر</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">ئادەتتىكى پىرىسلاش ، كۈلرەڭ رەسىملەر تېخىمۇ كۈچلۈك</string>\n    <string name=\"model_scunet_color_gan_fp16\">ئادەتتىكى شاۋقۇن ، رەڭلىك رەسىملەر</string>\n    <string name=\"model_scunet_color_psnr_fp16\">ئادەتتىكى شاۋقۇن ، رەڭلىك رەسىملەر ، تېخىمۇ ياخشى تەپسىلاتلار</string>\n    <string name=\"model_scunet_gray_15_fp16\">ئادەتتىكى شاۋقۇن ، كۈلرەڭ رەسىملەر</string>\n    <string name=\"model_scunet_gray_25_fp16\">ئادەتتىكى شاۋقۇن ، كۈلرەڭ رەسىملەر تېخىمۇ كۈچلۈك</string>\n    <string name=\"model_scunet_gray_50_fp16\">ئادەتتىكى شاۋقۇن ، كۈلرەڭ رەسىملەر ، ئەڭ كۈچلۈك</string>\n    <string name=\"model_jpeg_destroyer\">ئادەتتىكى پىرىسلاش</string>\n    <string name=\"model_jaywreck\">ئادەتتىكى پىرىسلاش</string>\n    <string name=\"model_h264\">تېكىستلەشتۈرۈش ، h264 پىرىسلاش</string>\n    <string name=\"model_vhs\">VHS پىرىسلاش</string>\n    <string name=\"model_cinepak\">ئۆلچەملىك پىرىسلاش (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">بىنەپشە پىرىسلاش ، گېئومېتىرىيەدىن ياخشى</string>\n    <string name=\"model_debink_v5\">بىنەپشە پىرىسلاش تېخىمۇ كۈچلۈك</string>\n    <string name=\"model_debink_v6\">بىنەپشە پىرىسلاش ، يۇمشاق ، تەپسىلاتنى ساقلاپ قالىدۇ</string>\n    <string name=\"model_antialias\">پەلەمپەيسىمان ئۈنۈمنى يوقىتىش ، راۋانلاشتۇرۇش</string>\n    <string name=\"model_kdm_scans\">سكاننېرلانغان سەنئەت / سىزمىلار ، يېنىك پىرىسلاش ، نەملىك</string>\n    <string name=\"model_bandage\">رەڭ باغلاش</string>\n    <string name=\"model_halftone\">ئاستا ، يېرىم تاشنى ئېلىۋېتىش</string>\n    <string name=\"model_colorizer\">كۈلرەڭ / bw رەسىملەرنىڭ ئادەتتىكى رەڭدار ، تېخىمۇ ياخشى ئۈنۈمگە ئېرىشىش ئۈچۈن DDColor نى ئىشلىتىڭ</string>\n    <string name=\"model_deedge\">قىرلارنى ئېلىۋېتىش</string>\n    <string name=\"model_desharpen\">چەكتىن ئاشۇرۇۋېتىشنى يوقىتىدۇ</string>\n    <string name=\"model_dither\">ئاستا ، يۆنىلىش</string>\n    <string name=\"model_gainres\">چەتئەلگە قارشى تۇرۇش ، ئادەتتىكى بۇيۇملار ، CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 بىر تەرەپ قىلىشنى سايىلەيدۇ</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">يېنىك دەرىجىدىكى رەسىمنى ئاشۇرۇش ئەندىزىسى</string>\n    <string name=\"model_bcgone_detailed_v2\">پىرىسلاش بۇيۇملىرىنى ئېلىۋېتىش</string>\n    <string name=\"model_bcgone_smooth\">پىرىسلاش بۇيۇملىرىنى ئېلىۋېتىش</string>\n    <string name=\"model_bandage_smooth\">ئوڭۇشلۇق بولغان بەلۋاغنى ئېلىۋېتىش</string>\n    <string name=\"model_bendel_halftone\">Halftone ئەندىزىسىنى بىر تەرەپ قىلىش</string>\n    <string name=\"model_dither_deleter_v3_smooth\">ئەندىزە ئېلىۋېتىش V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG ئاسارە-ئەتىقىلەرنى يوقىتىش V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 تېكىستنى ئاشۇرۇش</string>\n    <string name=\"model_vhs_sharpen\">VHS ئۆتكۈرلەشتۈرۈش ۋە كۈچەيتىش</string>\n    <string name=\"merging\">بىرلەشتۈرۈش</string>\n    <string name=\"chunk_size\">Chunk Size</string>\n    <string name=\"overlap_size\">چوڭ-كىچىكلىكى</string>\n    <string name=\"note_chunk_info\">%1$s px ئۈستىدىكى رەسىملەر ئۇششاق-چۈششەك ۋە ئۇششاق-چۈششەك پىششىقلاپ ئىشلىنىدۇ ، بۇلارنى بىر-بىرىگە ئارىلاشتۇرۇپ ، كۆرۈنەرلىك يوچۇقلارنىڭ ئالدىنى ئالىدۇ.</string>\n    <string name=\"large_chunk_warning\">چوڭ رازمېر تۆۋەن ئۈسكۈنىلەر بىلەن مۇقىمسىزلىقنى كەلتۈرۈپ چىقىرىدۇ</string>\n    <string name=\"select_one_to_start\">باشلاش ئۈچۈن بىرنى تاللاڭ</string>\n    <string name=\"delete_model_sub\">%1$s مودېلىنى ئۆچۈرمەكچىمۇ؟ ئۇنى قايتا چۈشۈرۈشىڭىز كېرەك</string>\n    <string name=\"confirm\">جەزملەشتۈرۈڭ</string>\n    <string name=\"models\">مودېللار</string>\n    <string name=\"downloaded_models\">چۈشۈرۈلگەن مودېللار</string>\n    <string name=\"available_models\">ئىشلەتكىلى بولىدىغان مودېللار</string>\n    <string name=\"preparing\">تەييارلىق قىلىش</string>\n    <string name=\"active_model\">ئاكتىپ مودېل</string>\n    <string name=\"failed_to_open_session\">يىغىن ئېچىلمىدى</string>\n    <string name=\"only_onnx_models\">پەقەت .onnx / .ort تىپلىرىنىلا ئىمپورتلىغىلى بولىدۇ</string>\n    <string name=\"import_model\">ئىمپورت ئەندىزىسى</string>\n    <string name=\"import_model_sub\">تېخىمۇ كۆپ ئىشلىتىش ئۈچۈن خاسلاشتۇرۇلغان onnx مودېلىنى ئەكىرىڭ ، پەقەت onnx / ort تىپلىرىلا قوبۇل قىلىنىدۇ ، ۋارىيانتلارغا ئوخشاش بارلىق esrgan نى قوللايدۇ.</string>\n    <string name=\"imported_models\">ئىمپورت قىلىنغان مودېللار</string>\n    <string name=\"model_scunet_color_15_fp16\">ئادەتتىكى شاۋقۇن ، رەڭلىك رەسىملەر</string>\n    <string name=\"model_scunet_color_25_fp16\">ئادەتتىكى شاۋقۇن ، رەڭلىك رەسىملەر تېخىمۇ كۈچلۈك</string>\n    <string name=\"model_scunet_color_50_fp16\">ئادەتتىكى شاۋقۇن ، رەڭلىك رەسىملەر ، ئەڭ كۈچلۈك</string>\n    <string name=\"model_artifacts_dithering_alsa\">بويالغان بۇيۇملار ۋە رەڭ باغلاشنى ئازايتىدۇ ، سىلىق رېشاتكىلار ۋە تەكشى رەڭلىك رايونلارنى ياخشىلايدۇ.</string>\n    <string name=\"model_nmkd_brighten_redux\">تەبىئىي رەڭلەرنى ساقلاش بىلەن بىر ۋاقىتتا ، سۈرەتنىڭ يورۇقلۇقى ۋە تەڭپۇڭلۇق يارقىن نۇقتىلار بىلەن سېلىشتۇرۇشنى كۈچەيتىدۇ.</string>\n    <string name=\"model_nmkd_brighten\">تەپسىلاتلارنى ساقلاش ۋە ھەددىدىن زىيادە كۆپ بولۇپ كېتىشتىن ساقلىنىش بىلەن بىرگە قاراڭغۇ رەسىملەرنى يورۇق قىلىدۇ.</string>\n    <string name=\"model_nmkd_detoon\">ھەددىدىن زىيادە رەڭنى يوقىتىشنى يوقىتىپ ، تېخىمۇ نېيترال ۋە تەبىئىي رەڭ تەڭپۇڭلۇقىنى ئەسلىگە كەلتۈرىدۇ.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">ئىنچىكە تەپسىلاتلار ۋە توقۇلمىلارنى ساقلاشقا ئەھمىيەت بېرىپ ، پويسوننى ئاساس قىلغان شاۋقۇننى تەڭشەشنى قوللىنىدۇ.</string>\n    <string name=\"model_noise_toner_poisson_soft\">يۇمىلاق ۋە تاجاۋۇزچىلىق كۆرۈش ئۈنۈمى ئۈچۈن يۇمشاق پويسون شاۋقۇنىنى تەڭشەشنى قوللىنىدۇ.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">بىرلىككە كەلگەن شاۋقۇن ئاۋازى ئىنچىكە قوغداش ۋە سۈرەتنىڭ سۈزۈكلۈكىگە مەركەزلەشتى.</string>\n    <string name=\"model_noise_toner_uniform_soft\">نازۇك توقۇلمىلار ۋە سىلىق كۆرۈنۈش ئۈچۈن مۇلايىم بىرلىككە كەلگەن شاۋقۇن ئاۋازى.</string>\n    <string name=\"model_repainter\">ئاسارە-ئەتىقىلەرنى بوياش ۋە رەسىمنىڭ بىردەكلىكىنى ياخشىلاش ئارقىلىق بۇزۇلغان ياكى تەكشى بولمىغان رايونلارنى رېمونت قىلىدۇ.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">ئەڭ تۆۋەن ئىقتىدار تەننەرخى بىلەن رەڭلىك بەلۋاغنى چىقىرىپ تاشلايدىغان يېنىك دەرىجىدىكى مودېل.</string>\n    <string name=\"model_jpeg_0_20\">سۈزۈكلۈك دەرىجىسى يۇقىرى بولغان پىرىسلاش بۇيۇملىرى (% 0-% 20) بولغان رەسىملەرنى ئەلالاشتۇرىدۇ.</string>\n    <string name=\"model_jpeg_20_40\">يۇقىرى پىرىسلاش بۇيۇملىرى (% 20-40% سۈپەت) ئارقىلىق سۈرەتنى ياخشىلايدۇ ، تەپسىلاتلارنى ئەسلىگە كەلتۈرىدۇ ۋە شاۋقۇننى پەسەيتىدۇ.</string>\n    <string name=\"model_jpeg_40_60\">ئوتتۇراھال پىرىسلاش (% 40-% 60 سۈپەت) ئارقىلىق سۈرەتنى ياخشىلايدۇ ، ئۆتكۈرلۈك ۋە سىلىقلىقنى تەڭپۇڭلاشتۇرىدۇ.</string>\n    <string name=\"model_jpeg_60_80\">نۇرنى پىرىسلاش (60-80% سۈپەتلىك) رەسىملەرنى ئىنچىكە پىششىقلاپ ، ئىنچىكە تەپسىلاتلار ۋە توقۇلمىلارنى ئۆستۈرىدۇ.</string>\n    <string name=\"model_jpeg_80_100\">تەبىئىي كۆرۈنۈش ۋە ئىنچىكە ھالقىلارنى ساقلاپ قېلىش بىلەن بىللە ، زىيانسىز رەسىملەرنى (% 80-100 سۈپەت) ئازراق ئۆستۈرىدۇ.</string>\n    <string name=\"model_spongecolor_lite\">ئاددىي ۋە تېز رەڭلەش ، كارتون ، كۆڭۈلدىكىدەك ئەمەس</string>\n    <string name=\"model_deblr\">رەسىمنىڭ سۇسلىقىنى ئازراق تۆۋەنلىتىدۇ ، ئاسارە-ئەتىقىلەرنى تونۇشتۇرماي ئۆتكۈرلۈكنى ئۆستۈرىدۇ.</string>\n    <string name=\"processing_channel\">ئۇزۇن مەشغۇلات</string>\n    <string name=\"processing_image\">رەسىم بىر تەرەپ قىلىش</string>\n    <string name=\"processing\">بىر تەرەپ قىلىش</string>\n    <string name=\"model_artifacts_jpg_0_20\">ئىنتايىن تۆۋەن سۈپەتلىك رەسىمدىكى ئېغىر JPEG پىرىسلاش بۇيۇملىرىنى چىقىرىپ تاشلايدۇ (% 0-20).</string>\n    <string name=\"model_artifacts_jpg_20_40\">يۇقىرى پرېسلانغان رەسىملەردە كۈچلۈك JPEG ئاسارە-ئەتىقىلەرنى ئازايتىدۇ (% 20-40).</string>\n    <string name=\"model_artifacts_jpg_40_60\">رەسىم تەپسىلاتلىرىنى ساقلاش بىلەن بىللە ئوتتۇراھال JPEG ئاسارە-ئەتىقىلەرنى تازىلايدۇ (% 40-60).</string>\n    <string name=\"model_artifacts_jpg_60_80\">بىر قەدەر يۇقىرى سۈپەتلىك رەسىملەردە يېنىك JPEG ئاسارە-ئەتىقىلەرنى ساپلاشتۇرىدۇ (% 60-80).</string>\n    <string name=\"model_artifacts_jpg_80_100\">زىيانسىز رەسىملەردە كىچىك JPEG ئاسارە-ئەتىقىلەرنى ئەپچىللىك بىلەن ئازايتىدۇ (% 80-100).</string>\n    <string name=\"model_redetail_v2\">ئىنچىكە تەپسىلاتلار ۋە توقۇلمىلارنى كۈچەيتىدۇ ، ئېغىر ئاسارە-ئەتىقىلەر بولماي تۇرۇپ ھېس قىلىنغان ئۆتكۈرلۈكنى ئۆستۈرىدۇ.</string>\n    <string name=\"processing_finished\">بىر تەرەپ قىلىش تاماملاندى</string>\n    <string name=\"processing_failed\">بىر تەرەپ قىلىش مەغلۇب بولدى</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">تەبىئىي كۆرۈنۈشنى ساقلاش بىلەن بىللە تېرىنىڭ تۈزۈلۈشى ۋە تەپسىلاتلىرىنى كۈچەيتىدۇ ، سۈرئەتنى ئەلالاشتۇرىدۇ.</string>\n    <string name=\"model_sbdv_dejpeg\">JPEG پىرىسلاش بۇيۇملىرىنى چىقىرىپ تاشلاپ ، پىرىسلانغان رەسىملەرنىڭ رەسىم سۈپىتىنى ئەسلىگە كەلتۈرىدۇ.</string>\n    <string name=\"model_iso_denoise_v1\">تۆۋەن يورۇقلۇق شارائىتىدا تارتىلغان سۈرەتلەردە ISO شاۋقۇنىنى تۆۋەنلىتىدۇ ، تەپسىلاتلارنى ساقلايدۇ.</string>\n    <string name=\"model_dejumbo\">ھەددىدىن زىيادە كۆپ ياكى «جۇمۇ» يارقىن نۇقتىلىرىنى تۈزىتىپ ، تېخىمۇ ياخشى ئاۋاز تەڭپۇڭلۇقىنى ئەسلىگە كەلتۈرىدۇ.</string>\n    <string name=\"model_ddcolor_tiny\">كۈلرەڭ رەسىملەرگە تەبىئىي رەڭ قوشىدىغان يېنىك ۋە تېز رەڭلەش ئەندىزىسى.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Denoise</string>\n    <string name=\"type_colorize\">رەڭگى</string>\n    <string name=\"type_artifacts\">ئاسارە-ئەتىقىلەر</string>\n    <string name=\"type_enhance\">كۈچەيتىڭ</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">سايىلەش</string>\n    <string name=\"type_upscale\">Upscale</string>\n    <string name=\"model_realesrgan_x4v3\">ئادەتتىكى رەسىملەر ئۈچۈن X4 يۇقىرى كۆتۈرگۈچ كىچىك تىپتىكى GPU ۋە ۋاقىتنى ئىشلىتىدىغان كىچىك تىپتىكى مودېل ، ئوتتۇراھال چۈشۈش ۋە ئېنىقلىق دەرىجىسى بار.</string>\n    <string name=\"model_realesrgan_x2plus\">ئادەتتىكى رەسىملەر ئۈچۈن X2 يۇقىرى كۆتۈرۈلۈش ، تۈزۈلۈش ۋە تەبىئىي تەپسىلاتلارنى ساقلاش.</string>\n    <string name=\"model_realesrgan_x4plus\">X4 يۇقىرى كۆتۈرۈلگەن تېكىستلەر ۋە ئەمەلىي ئۈنۈمگە ئىگە.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 يۇقىرى كۆتۈرۈلۈش كارتون رەسىملىرى ئۈچۈن ئەلالاشتۇرۇلغان ئۆتكۈر سىزىق ۋە تەپسىلاتلار ئۈچۈن 6 RRDB توسىدۇ.</string>\n    <string name=\"model_realesrnet_x4plus\">MSE زىيىنى بىلەن X4 يۇقىرى كۆتۈرگۈچى ، تېخىمۇ راۋان نەتىجىلەرنى يارىتىدۇ ۋە ئادەتتىكى رەسىملەر ئۈچۈن ئاسارە-ئەتىقىلەرنى ئازايتىدۇ.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler كارتون رەسىملەر ئۈچۈن ئەلالاشتۇرۇلغان. تېخىمۇ ئىنچىكە ھالقىلار ۋە سىلىق سىزىقلىق 4B32F تىپى.</string>\n    <string name=\"model_ultrasharp_v2_x4\">ئادەتتىكى رەسىملەر ئۈچۈن X4 UltraSharp V2 مودېلى ئۆتكۈرلۈك ۋە ئېنىقلىقنى تەكىتلەيدۇ.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; تېخىمۇ تېز ۋە كىچىكرەك ، GPU ئىچكى ساقلىغۇچنى ئاز ئىشلەتكەندە تەپسىلاتلارنى ساقلايدۇ.</string>\n    <string name=\"model_rmbg_1_4\">تەگلىكنى تېز ئۆچۈرۈۋېتىشنىڭ يېنىك مودېلى. تەڭپۇڭلۇق ئىقتىدار ۋە توغرىلىق. سۈرەت ، ئوبيېكت ۋە كۆرۈنۈشلەر بىلەن ئىشلەيدۇ. كۆپ ئىشلىتىلىدىغان ئەھۋاللارغا تەۋسىيە قىلىنىدۇ.</string>\n    <string name=\"type_removebg\">BG نى ئۆچۈرۈڭ</string>\n    <string name=\"horizontal_border_thickness\">توغرىسىغا چېگرا قېلىنلىقى</string>\n    <string name=\"vertical_border_thickness\">تىك چېگرا قېلىنلىقى</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s رەڭلەر</item>\n        <item quantity=\"other\">%1$s رەڭلەر</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">ھازىرقى مودېل چۇۋۇشنى قوللىمايدۇ ، رەسىم ئەسلى ئۆلچەمدە بىر تەرەپ قىلىنىدۇ ، بۇ بەلكىم ئىچكى ساقلىغۇچ سەرپىياتى ۋە تۆۋەن سەپلىمىلىك ئۈسكۈنىلەردە مەسىلە پەيدا قىلىشى مۇمكىن</string>\n    <string name=\"chunking_disabled\">چۇۋۇش چەكلەنگەن ، رەسىم ئەسلى ئۆلچەمدە بىر تەرەپ قىلىنىدۇ ، بۇ بەلكىم ئىچكى ساقلىغۇچنىڭ يۇقىرى سەرپىياتىنى ۋە تۆۋەن سەپلىمىلىك ئۈسكۈنىلەردە مەسىلە پەيدا قىلىشى مۇمكىن ، ئەمما يەكۈن چىقىرىشتا تېخىمۇ ياخشى ئۈنۈم بېرىشى مۇمكىن</string>\n    <string name=\"chunking\">Chunking</string>\n    <string name=\"model_u2net\">تەگلىكنى ئۆچۈرۈش ئۈچۈن يۇقىرى ئېنىقلىقتىكى رەسىم بۆلەك مودېلى</string>\n    <string name=\"model_u2netp\">كىچىكرەك ئىچكى ساقلىغۇچ ئىشلىتىش ئارقىلىق تېخىمۇ تېز تەگلىك ئۆچۈرۈش ئۈچۈن U2Net نىڭ يېنىك نۇسخىسى.</string>\n    <string name=\"model_ddcolor\">تولۇق DDColor مودېلى ئەڭ تۆۋەن ئاسارە-ئەتىقىلەر بىلەن ئادەتتىكى رەسىملەرگە يۇقىرى سۈپەتلىك رەڭ بېرىدۇ. بارلىق رەڭلەش مودېللىرىنىڭ ئەڭ ياخشى تاللىشى.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor تەربىيەلەنگەن ۋە شەخسىي سەنئەت سانلىق مەلۇماتلىرى ئاز بولمىغان رېئال سەنئەت بۇيۇملىرى بىلەن كۆپ خىل ۋە بەدىئىي رەڭلەش نەتىجىسىنى ھاسىل قىلىدۇ.</string>\n    <string name=\"model_birefnet\">ئارقا كۆرۈنۈشنى ئېلىۋېتىش ئۈچۈن Swin Transformer نى ئاساس قىلغان يېنىك تىپتىكى BiRefNet مودېلى.</string>\n    <string name=\"model_inspyrenet\">ئۆتكۈر گىرۋەك ۋە ئېسىل تەپسىلاتلارنى ساقلاش بىلەن ئەلا سۈپەتلىك تەگلىك ئېلىۋېتىش ، بولۇپمۇ مۇرەككەپ جىسىملار ۋە مۇرەككەپ ئارقا كۆرۈنۈشلەردە.</string>\n    <string name=\"model_isnet\">تەگلىك ئېلىۋېتىش ئەندىزىسى ، گىرۋەكلىرى سىلىق ماسكا ھاسىل قىلىپ ، ئادەتتىكى جىسىملارغا ۋە مۇۋاپىق تەپسىلاتلارنى ساقلاشقا ماس كېلىدۇ.</string>\n    <string name=\"model_already_downloaded\">مودېل ئاللىبۇرۇن چۈشۈرۈلدى</string>\n    <string name=\"model_successfully_imported\">مودېل مۇۋەپپەقىيەتلىك ئىمپورت قىلىندى</string>\n    <string name=\"type\">تىپ</string>\n    <string name=\"keyword\">ئاچقۇچلۇق سۆز</string>\n    <string name=\"very_fast\">Very Fast</string>\n    <string name=\"normal\">نورمال</string>\n    <string name=\"slow\">ئاستا</string>\n    <string name=\"very_slow\">Very Slow</string>\n    <string name=\"compute_percents\">ھېسابلاش نىسبىتى</string>\n    <string name=\"minimum_value_is\">ئەڭ تۆۋەن قىممىتى %1$s</string>\n    <string name=\"warp_sub\">بارماق بىلەن رەسىم سىزىش ئارقىلىق رەسىمنى بۇرمىلاش</string>\n    <string name=\"warp\">Warp</string>\n    <string name=\"hardness\">قاتتىقلىق</string>\n    <string name=\"warp_mode\">Warp Mode</string>\n    <string name=\"warp_mode_move\">يۆتكەڭ</string>\n    <string name=\"warp_mode_grow\">ئۆسۈڭ</string>\n    <string name=\"warp_mode_shrink\">كىچىكلىتىش</string>\n    <string name=\"warp_mode_swirl_cw\">Swirl CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Swirl CCW</string>\n    <string name=\"fade_strength\">Fade Strength</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">ئاستى تامچە</string>\n    <string name=\"start_drop\">باشلاش</string>\n    <string name=\"end_drop\">ئاخىرلىشىش</string>\n    <string name=\"downloading\">چۈشۈرۈش</string>\n    <string name=\"smooth_shapes\">سىلىق شەكىللەر</string>\n    <string name=\"smooth_shapes_sub\">تېخىمۇ يۇمىلاق ، تەبىئىي شەكىللەر ئۈچۈن ئۆلچەملىك يۇمىلاق شەكىللىك تىك تۆت بۇلۇڭنىڭ ئورنىغا ئادەتتىن تاشقىرى تېز سۈرئەتلىك نۇر ئىشلىتىڭ</string>\n    <string name=\"shape_type\">شەكىل تىپى</string>\n    <string name=\"cut\">كېسىڭ</string>\n    <string name=\"rounded\">يۇمىلاق ئۈستەل</string>\n    <string name=\"smooth\">سىلىق</string>\n    <string name=\"cut_shapes_sub\">يۇمىلاق قىرلار يۇمىلاق ئەمەس</string>\n    <string name=\"rounded_shapes_sub\">كلاسسىك يۇمىلاق بۇلۇڭ</string>\n    <string name=\"shapes_type\">شەكىل تىپى</string>\n    <string name=\"corners_size\">بۇلۇڭ چوڭلۇقى</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">نەپىس يۇمىلاق UI ئېلېمېنتلىرى</string>\n    <string name=\"filename_format\">ھۆججەت ئىسمى فورماتى</string>\n    <string name=\"prefix_pattern_description\">ھۆججەت نامىنىڭ بېشىدا قويۇلغان ئىختىيارى تېكىست ، تۈر ئىسمى ، ماركا ياكى شەخسىي خەتكۈچلەرگە ماس كېلىدۇ.</string>\n    <string name=\"original_filename_pattern_description\">ئەسلى ھۆججەت نامىنى كېڭەيتمەي ئىشلىتىڭ ، مەنبە پەرقلەندۈرۈشنى ساقلىشىڭىزغا ياردەم بېرىدۇ.</string>\n    <string name=\"width_pattern_description\">پىكسېلدىكى رەسىم كەڭلىكى ، ئېنىقلىق دەرىجىسىنى ئۆزگەرتىش ياكى ئۆلچەش نەتىجىسىنى ئىز قوغلاشقا پايدىلىق.</string>\n    <string name=\"height_pattern_description\">رەسىمنىڭ ئېگىزلىكى پېكسىل بولۇپ ، تەرەپ نىسبىتى ياكى ئېكسپورتى بىلەن ئىشلىگەندە پايدىلىق.</string>\n    <string name=\"random_numbers_pattern_description\">ئۆزگىچە ھۆججەت نامىغا كاپالەتلىك قىلىش ئۈچۈن ئىختىيارى سان ھاسىل قىلىدۇ. كۆپەيتىلگەنگە قارشى قوشۇمچە بىخەتەرلىك ئۈچۈن تېخىمۇ كۆپ رەقەم قوشۇڭ.</string>\n    <string name=\"sequence_number_pattern_description\">تۈركۈملەپ ئېكسپورت قىلىش ئۈچۈن ئاپتوماتىك كۆپەيتىش ھېساباتى ، بىر بۆلەكتە كۆپ رەسىمنى ساقلىغاندا كۆڭۈلدىكىدەك.</string>\n    <string name=\"preset_info_pattern_description\">قوللىنىشچان ئالدىن بېكىتىلگەن ئىسىمنى ھۆججەت نامىغا قىستۇرۇڭ ، بۇنداق بولغاندا رەسىمنىڭ قانداق بىر تەرەپ قىلىنغانلىقىنى ئاسانلا ئەستە ساقلىيالايسىز.</string>\n    <string name=\"scale_mode_pattern_description\">بىر تەرەپ قىلىش جەريانىدا ئىشلىتىلگەن رەسىمنى كىچىكلىتىش ھالىتىنى كۆرسىتىدۇ ، چوڭ-كىچىكلىكى ، كېسىلگەن ياكى ماسلاشتۇرۇلغان رەسىملەرنى پەرقلەندۈرۈشكە ياردەم بېرىدۇ.</string>\n    <string name=\"suffix_pattern_description\">ھۆججەت نامىنىڭ ئاخىرىغا قويۇلغان ئىختىيارى تېكىست ، _v2 ، _edited ياكى _final غا ئوخشاش نەشىر قىلىشقا پايدىلىق.</string>\n    <string name=\"extension_pattern_description\">ھۆججەت كېڭەيتىلمىسى (png, jpg ، webp قاتارلىقلار) ، ئاپتوماتىك ساقلانغان فورماتقا ئاپتوماتىك ماس كېلىدۇ.</string>\n    <string name=\"formatted_timestamp_pattern_description\">مۇكەممەل تەرتىپلەش ئۈچۈن java ئۆلچىمى ئارقىلىق ئۆزىڭىزنىڭ فورماتىنى بەلگىلىيەلەيدىغان خاسلاشتۇرغىلى بولىدىغان ۋاقىت تامغىسى.</string>\n    <string name=\"fling_type\">Fling Type</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">iOS ئۇسلۇبى</string>\n    <string name=\"smooth_curve\">يۇمىلاق ئەگرى سىزىق</string>\n    <string name=\"quick_stop\">Quick Stop</string>\n    <string name=\"bouncy\">Bouncy</string>\n    <string name=\"floaty\">Floaty</string>\n    <string name=\"snappy\">Snappy</string>\n    <string name=\"ultra_smooth\">Ultra Smooth</string>\n    <string name=\"adaptive\">ماسلىشىشچان</string>\n    <string name=\"accessibility_aware\">Accessibility Aware</string>\n    <string name=\"reduced_motion\">ھەرىكەتنى ئازايتتى</string>\n    <string name=\"android_native_sub\">يەرلىك ئاندىرويىد دومىلىما فىزىكىسى</string>\n    <string name=\"smooth_sub\">ئادەتتىكى ئىشلىتىش ئۈچۈن تەڭپۇڭ ، سىلىق ئۆرۈش</string>\n    <string name=\"ios_style_sub\">تېخىمۇ يۇقىرى سۈركىلىش iOS كە ئوخشاش سىيرىلما ھەرىكەت</string>\n    <string name=\"smooth_curve_sub\">روشەن سىيرىلىش تۇيغۇسى ئۈچۈن ئۆزگىچە ئەگرى سىزىق</string>\n    <string name=\"quick_stop_sub\">تېز توختاش بىلەن توغرا سىيرىلىش</string>\n    <string name=\"bouncy_sub\">ئوينايدىغان ، ئىنكاس قايتۇرىدىغان قاڭقىش</string>\n    <string name=\"floaty_sub\">مەزمۇن كۆرۈش ئۈچۈن ئۇزۇن ، سىيرىلما دومىلىما</string>\n    <string name=\"snappy_sub\">ئۆز-ئارا تەسىر كۆرسىتىدىغان UI ئۈچۈن تېز ، ئىنكاس قايتۇرۇش</string>\n    <string name=\"ultra_smooth_sub\">ئۇزارتىلغان ھەرىكەتلەندۈرگۈچ كۈچ بىلەن ئەلا سۈپەتلىك سىيرىلىش</string>\n    <string name=\"adaptive_sub\">فىزىكىنى تەڭشەش سۈرئىتىگە ئاساسەن تەڭشەيدۇ</string>\n    <string name=\"accessibility_aware_sub\">سىستېمىنىڭ زىيارەت قىلىش تەڭشىكىگە ھۆرمەت قىلىدۇ</string>\n    <string name=\"reduced_motion_sub\">زىيارەت قىلىش ئېھتىياجى ئۈچۈن ئەڭ تۆۋەن ھەرىكەت</string>\n    <string name=\"primary_lines\">Primary Line</string>\n    <string name=\"primary_lines_sub\">ھەر بەشىنچى قۇرغا قېلىن سىزىق قوشىدۇ</string>\n    <string name=\"fill_color\">رەڭنى تولدۇرۇڭ</string>\n    <string name=\"hidden_tools\">يوشۇرۇن قوراللار</string>\n    <string name=\"hidden_for_share\">ئورتاقلىشىش ئۈچۈن يوشۇرۇنغان قوراللار</string>\n    <string name=\"color_library\">رەڭلىك كۇتۇپخانا</string>\n    <string name=\"color_library_sub\">كەڭ رەڭلەرنى كۆرۈڭ</string>\n    <string name=\"model_fatality_deblur\">تەبىئىي تەپسىلاتلارنى ساقلاش بىلەن بىر ۋاقىتتا سۈرەتتىكى تۇتۇقلىقنى ئۆتكۈرلەشتۈرۈۋېتىدۇ ۋە چىقىرىپ تاشلايدۇ ، فوكۇس سىرتىدىكى سۈرەتلەرنى ئوڭشاشقا ماس كېلىدۇ.</string>\n    <string name=\"model_unresize_v3\">ئەقلىي ئىقتىدار ئىلگىرى چوڭايتىلغان رەسىملەرنى ئەسلىگە كەلتۈرۈپ ، يوقاپ كەتكەن تەپسىلاتلار ۋە توقۇلمىلارنى ئەسلىگە كەلتۈرىدۇ.</string>\n    <string name=\"model_liveaction_v1_span\">نەق مەيدان ھەرىكەت مەزمۇنىغا ئەلالاشتۇرۇلغان ، پىرىسلاش بۇيۇملىرىنى ئازايتىدۇ ۋە كىنو / تېلېۋىزىيە پروگرامما رامكىلىرىدىكى ئىنچىكە ھالقىلارنى ئۆستۈرىدۇ.</string>\n    <string name=\"model_vhs2hd_realplksr\">VHS سۈپەتلىك كۆرۈنۈشلەرنى HD غا ئايلاندۇرىدۇ ، لېنتا شاۋقۇنىنى چىقىرىپ تاشلايدۇ ۋە ئۈزۈم تۇيغۇسىنى ساقلايدۇ.</string>\n    <string name=\"model_text2hd_v1\">تېكىست ئېغىر رەسىم ۋە ئېكران كۆرۈنۈشلىرى ئۈچۈن مەخسۇس ، ھەرپلەرنى ئۆتكۈرلەشتۈرۈپ ، ئوقۇشچانلىقىنى ئۆستۈرىدۇ.</string>\n    <string name=\"model_frankendata_pretrainer\">كۆپ خىل سانلىق مەلۇمات سانلىق مەلۇماتلىرى بويىچە تەربىيىلەنگەن ئىلغار دەرىجىگە كۆتۈرۈش ، ئادەتتىكى مەقسەتلىك رەسىمنى ئاشۇرۇش ئۈچۈن ناھايىتى ياخشى.</string>\n    <string name=\"model_realwebphoto_v2\">تور بېسىلغان رەسىملەر ئۈچۈن ئەلالاشتۇرۇلغان ، JPEG ئاسارە-ئەتىقىلەرنى چىقىرىپ تاشلاپ ، تەبىئىي كۆرۈنۈشنى ئەسلىگە كەلتۈرىدۇ.</string>\n    <string name=\"model_realwebphoto_v4\">تېخىمۇ ياخشى توقۇلمىلارنى قوغداش ۋە ئاسارە-ئەتىقىلەرنى ئازايتىش بىلەن تور رەسىملىرىنىڭ نەشىرى ياخشىلاندى.</string>\n    <string name=\"model_dat_2x\">قوش يىغىلىش تىرانسفورموتور تېخنىكىسى بىلەن 2x يۇقىرى كۆتۈرۈلۈپ ، ئۆتكۈرلۈك ۋە تەبىئىي تەپسىلاتلارنى ساقلايدۇ.</string>\n    <string name=\"model_dat_3x\">ئىلغار تىرانسفورموتور قۇرۇلمىسىنى ئىشلىتىپ 3x يۇقىرى كۆتۈرۈش ، ئوتتۇراھال چوڭايتىش ئېھتىياجىغا ماس كېلىدۇ.</string>\n    <string name=\"model_dat_4x\">زامانىۋى تىرانسفورموتور تورى بىلەن 4x يۇقىرى سۈپەتلىك يۇقىرى كۆتۈرۈلۈش ، تېخىمۇ چوڭ كۆلەمدە ئىنچىكە تەپسىلاتلارنى ساقلايدۇ.</string>\n    <string name=\"model_nafnet_deblurring\">سۈرەتتىكى تۇتۇق / شاۋقۇننى ۋە تەۋرىنىشنى يوقىتىدۇ. ئومۇمىي مەقسەت ئەمما سۈرەتتىكى ئەڭ ياخشى.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">BSRGAN نىڭ ناچارلىشىشىغا ئەلالاشتۇرۇلغان Swin2SR تىرانسفورموتور ئارقىلىق تۆۋەن سۈپەتلىك رەسىملەرنى ئەسلىگە كەلتۈرىدۇ. ئېغىر دەرىجىدىكى پىرىسلاش بۇيۇملىرىنى ئوڭشاش ۋە 4x ئۆلچەمدە تەپسىلاتلارنى ئاشۇرۇشقا ناھايىتى ماس كېلىدۇ.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">BSRGAN نىڭ ناچارلىشىشى توغرىسىدا تەربىيەلەنگەن SwinIR تىرانسفورموتور بىلەن 4x يۇقىرى كۆتۈرۈلگەن. رەسىم ۋە مۇرەككەپ كۆرۈنۈشلەردە تېخىمۇ ئۆتكۈر توقۇلمىلار ۋە تېخىمۇ تەبىئىي تەپسىلاتلار ئۈچۈن GAN نى ئىشلىتىڭ.</string>\n    <string name=\"path\">Path</string>\n    <string name=\"merge_pdf\">PDF نى بىرلەشتۈرۈش</string>\n    <string name=\"merge_pdf_sub\">بىر نەچچە PDF ھۆججىتىنى بىر ھۆججەتكە بىرلەشتۈرۈڭ</string>\n    <string name=\"files_order\">Files Order</string>\n    <string name=\"pages_short\">pp.</string>\n    <string name=\"split_pdf\">PDF نى پارچىلاش</string>\n    <string name=\"split_pdf_sub\">PDF ھۆججىتىدىن كونكرېت بەتلەرنى چىقىرىڭ</string>\n    <string name=\"rotate_pdf\">PDF نى ئايلاندۇرۇش</string>\n    <string name=\"rotate_pdf_sub\">بەت يۆنىلىشىنى مەڭگۈلۈك ئوڭشاڭ</string>\n    <string name=\"pages\">بەتلەر</string>\n    <string name=\"rearrange_pdf\">PDF نى قايتا رەتلەڭ</string>\n    <string name=\"rearrange_pdf_sub\">بەتلەرنى سۆرەپ تاشلاڭ</string>\n    <string name=\"hold_drag_drop\">بەتلەرنى تۇتۇش ۋە سۆرەش</string>\n    <string name=\"page_numbers\">بەت سانى</string>\n    <string name=\"page_numbers_sub\">ھۆججەتلىرىڭىزگە ئاپتوماتىك نومۇر قوشۇڭ</string>\n    <string name=\"label_format\">بەلگە فورماتى</string>\n    <string name=\"pdf_to_text\">PDF دىن تېكىست (OCR)</string>\n    <string name=\"pdf_to_text_sub\">PDF ھۆججىتىڭىزدىن ئاددىي تېكىستنى ئېلىڭ</string>\n    <string name=\"watermark_pdf_sub\">ماركا ياكى بىخەتەرلىك ئۈچۈن خاس تېكىستنى قاپلاڭ</string>\n    <string name=\"signature\">ئىمزا</string>\n    <string name=\"signature_sub\">ھەر قانداق ھۆججەتكە ئېلېكترونلۇق ئىمزاسىڭىزنى قوشۇڭ</string>\n    <string name=\"will_be_for_signature\">بۇ ئىمزا سۈپىتىدە ئىشلىتىلىدۇ</string>\n    <string name=\"unlock_pdf\">PDF قۇلۇپىنى ئېچىڭ</string>\n    <string name=\"unlock_pdf_sub\">قوغدىلىدىغان ھۆججەتلىرىڭىزدىن پارولنى ئۆچۈرۈڭ</string>\n    <string name=\"protect_pdf\">PDF نى قوغداش</string>\n    <string name=\"protect_pdf_sub\">كۈچلۈك مەخپىيلەشتۈرۈش ئارقىلىق ھۆججەتلىرىڭىزنى بىخەتەر قىلىڭ</string>\n    <string name=\"success\">مۇۋەپپەقىيەت</string>\n    <string name=\"pdf_unlocked\">PDF قۇلۇپ ئېچىلدى ، ئۇنى ساقلىسىڭىز ياكى ئورتاقلىشالايسىز</string>\n    <string name=\"repair_pdf\">PDF نى رېمونت قىلىڭ</string>\n    <string name=\"repair_pdf_sub\">بۇزۇلغان ياكى ئوقۇغىلى بولمايدىغان ھۆججەتلەرنى ئوڭشاشقا ئۇرۇنۇش</string>\n    <string name=\"grayscale\">كۈلرەڭ</string>\n    <string name=\"grayscale_pdf_sub\">بارلىق ھۆججەت قىستۇرۇلغان رەسىملەرنى كۈلرەڭگە ئۆزگەرتىڭ</string>\n    <string name=\"compress_pdf\">PDF نى بېسىڭ</string>\n    <string name=\"compress_pdf_sub\">ئورتاقلىشىش ئۈچۈن ھۆججەت ھۆججىتىنىڭ چوڭ-كىچىكلىكىنى ئەلالاشتۇرۇڭ</string>\n    <string name=\"repair_info\">ImageToolbox ئىچكى ھالقىما پايدىلىنىش جەدۋىلىنى قايتا قۇرۇپ ، ھۆججەت قۇرۇلمىسىنى باشتىن-ئاخىر ئەسلىگە كەلتۈرىدۇ. بۇ \\ \\\"ئاچقىلى بولمايدىغان \\\\\" نۇرغۇن ھۆججەتلەرنى زىيارەت قىلىشنى ئەسلىگە كەلتۈرەلەيدۇ.</string>\n    <string name=\"grayscale_info\">بۇ قورال بارلىق ھۆججەت رەسىملىرىنى كۈلرەڭگە ئايلاندۇرىدۇ. ھۆججەتنىڭ چوڭ-كىچىكلىكىنى بېسىپ چىقىرىش ۋە ئازايتىشتا ئەڭ ياخشى</string>\n    <string name=\"metadata\">Metadata</string>\n    <string name=\"metadata_pdf_sub\">تېخىمۇ ياخشى مەخپىيەتلىك ئۈچۈن ھۆججەت خاسلىقىنى تەھرىرلەڭ</string>\n    <string name=\"tags\">خەتكۈچ</string>\n    <string name=\"producer\">ئىشلەپچىقارغۇچى</string>\n    <string name=\"author\">ئاپتور</string>\n    <string name=\"keywords\">ئاچقۇچلۇق سۆزلەر</string>\n    <string name=\"creator\">ياراتقۇچى</string>\n    <string name=\"privacy_deep_clean\">مەخپىيەتلىك چوڭقۇر</string>\n    <string name=\"privacy_deep_clean_sub\">بۇ ھۆججەتنىڭ بارلىق ئىشلەتكىلى بولىدىغان مېتا سانلىق مەلۇماتلىرىنى تازىلاڭ</string>\n    <string name=\"page\">بەت</string>\n    <string name=\"deep_ocr\">چوڭقۇر OCR</string>\n    <string name=\"deep_ocr_sub\">ھۆججەتتىن تېكىست چىقىرىپ ، Tesseract ماتورى ئارقىلىق بىر تېكىست ھۆججىتىگە ساقلاڭ</string>\n    <string name=\"cant_remove_all\">بارلىق بەتلەرنى ئۆچۈرەلمەيدۇ</string>\n    <string name=\"remove_pages_pdf\">PDF بەتلىرىنى ئۆچۈرۈڭ</string>\n    <string name=\"remove_pages_pdf_sub\">PDF ھۆججىتىدىن ئالاھىدە بەتلەرنى ئۆچۈرۈڭ</string>\n    <string name=\"tap_to_remove\">ئۆچۈرۈشنى چېكىڭ</string>\n    <string name=\"manually\">قولدا</string>\n    <string name=\"crop_pdf\">Crop PDF</string>\n    <string name=\"crop_pdf_sub\">ھۆججەت بەتلىرىنى خالىغانچە كېسىڭ</string>\n    <string name=\"flatten_pdf\">تەكشى PDF</string>\n    <string name=\"flatten_pdf_sub\">ھۆججەت بەتلىرىنى رەتلەش ئارقىلىق PDF نى ئۆزگەرتكىلى بولمايدۇ</string>\n    <string name=\"camera_failed_to_open\">كامېرانى قوزغىتالمىدى. ئىجازەتنى تەكشۈرۈپ ، ئۇنىڭ باشقا بىر دېتال تەرىپىدىن ئىشلىتىلمىگەنلىكىنى جەزملەشتۈرۈڭ.</string>\n    <string name=\"extract_images\">رەسىملەرنى چىقىرىڭ</string>\n    <string name=\"extract_images_sub\">ئەسلى ئېنىقلىقتىكى PDF لارغا قىستۇرۇلغان رەسىملەرنى چىقىرىڭ</string>\n    <string name=\"pdf_no_embedded\">بۇ PDF ھۆججىتىدە ھېچقانداق قىستۇرما رەسىم يوق</string>\n    <string name=\"extract_images_info\">بۇ قورال ھەر بىر بەتنى سايىلەپ ، تولۇق سۈپەتلىك رەسىملەرنى ئەسلىگە كەلتۈرىدۇ - ئەسلى ھۆججەتلەرنى ھۆججەتلەردىن ساقلاشقا ماس كېلىدۇ</string>\n    <string name=\"draw_signature\">ئىمزا سىزىش</string>\n    <string name=\"pen_params\">قەلەم پاراملىرى</string>\n    <string name=\"draw_signature_sub\">ھۆججەتلەرگە قويماقچى بولغان رەسىمنى رەسىم سۈپىتىدە ئىشلىتىڭ</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">بېرىلگەن ئارىلىق بىلەن ھۆججەتنى پارچىلاپ ، يېڭى ھۆججەتلەرنى zip ئارخىپىغا قاچىلاڭ</string>\n    <string name=\"interval\">ئارىلىق</string>\n    <string name=\"print_pdf\">PDF نى بېسىڭ</string>\n    <string name=\"print_pdf_sub\">ئىختىيارى بەت چوڭلۇقى بىلەن بېسىپ چىقىرىش ئۈچۈن ھۆججەت تەييارلاڭ</string>\n    <string name=\"pages_per_sheet\">ھەر بىر بەت</string>\n    <string name=\"orientation\">يۆنىلىش</string>\n    <string name=\"page_size\">بەت چوڭلۇقى</string>\n    <string name=\"margin\">Margin</string>\n    <string name=\"bloom\">بلۇم</string>\n    <string name=\"soft_knee\">يۇمشاق تىز</string>\n    <string name=\"model_realesr_animevideo_v3x4\">كارتون ۋە كارتون ئۈچۈن ئەلالاشتۇرۇلغان. ياخشىلانغان تەبىئىي رەڭلەر ۋە ئاسارە-ئەتىقىلەر ئاز</string>\n    <string name=\"one_ui_sub\">سامسۇڭ One UI 7 ئۇسلۇبىنى ياقتۇرىدۇ</string>\n    <string name=\"calculate_hint\">لازىملىق قىممەتنى ھېسابلاش ئۈچۈن بۇ يەرگە ئاساسىي ماتېماتىكا بەلگىسىنى كىرگۈزۈڭ (مەسىلەن (5 + 5) * 10)</string>\n    <string name=\"math_expression\">ماتېماتىكا ئىپادىلەش</string>\n    <string name=\"pick_up_to_n_collage_images\">%1$s رەسىملەرنى تاللاڭ</string>\n    <string name=\"background_color_for_alpha_formats\">ئالفا فورماتىنىڭ تەگلىك رەڭگى</string>\n    <string name=\"background_color_for_alpha_formats_sub\">ھەر بىر رەسىم فورماتىغا ئالفا قوللىشى بىلەن تەگلىك رەڭ بەلگىلەش ئىقتىدارى قوشىدۇ ، بۇنى پەقەت ئالفا بولمىغانلارلا ئىشلىتەلەيدۇ</string>\n    <string name=\"keep_date_time\">چېسلا ۋاقتىنى ساقلاڭ</string>\n    <string name=\"keep_date_time_sub\">چېسلا ۋە ۋاقىتقا مۇناسىۋەتلىك exif خەتكۈچلىرىنى ھەر ۋاقىت ساقلاپ قويۇڭ ، exif تاللاشنى ساقلاپ قېلىشتىن مۇستەقىل ئىشلەيدۇ</string>\n    <string name=\"open_markup_project\">تۈرنى ئېچىڭ</string>\n    <string name=\"open_markup_project_sub\">ئىلگىرى ساقلانغان رەسىم قورال ساندۇقى تۈرىنى تەھرىرلەشنى داۋاملاشتۇرۇڭ</string>\n    <string name=\"markup_project_open_failed\">رەسىم قورال ساندۇقى تۈرىنى ئاچالمىدى</string>\n    <string name=\"markup_project_missing_data\">رەسىم قورال ساندۇقى تۈرى تۈر سانلىق مەلۇماتلىرىنى كەملەپ قالدى</string>\n    <string name=\"markup_project_corrupted\">رەسىم قورال ساندۇقى تۈرى بۇزۇلغان</string>\n    <string name=\"unsupported_markup_project_version\">قوللىمايدىغان رەسىم قورال ساندۇقى تۈر نۇسخىسى: %1$d</string>\n    <string name=\"save_markup_project\">تۈرنى ساقلاش</string>\n    <string name=\"save_markup_project_sub\">تەھرىرلىگىلى بولىدىغان تۈر ھۆججىتىدە قەۋەت ، تەگلىك ۋە تەھرىرلەش تارىخىنى ساقلاڭ</string>\n    <string name=\"failed_to_open\">ئېچىلمىدى</string>\n    <string name=\"ocr_write_to_searchable_pdf\">ئىزدەشكە بولىدىغان PDF غا يېزىڭ</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">رەسىم گۇرۇپپىسىدىكى تېكىستنى تونۇپ ، رەسىم ۋە تاللىغىلى بولىدىغان تېكىست قەۋىتى بىلەن ئىزدەشكە بولىدىغان PDF نى ساقلاڭ</string>\n    <string name=\"layer_alpha\">قەۋەت ئالفا</string>\n    <string name=\"horizontal_flip\">توغرىسىغا توغرىلاش</string>\n    <string name=\"vertical_flip\">Vertical Flip</string>\n    <string name=\"lock\">قۇلۇپ</string>\n    <string name=\"add_shadow\">سايە قوشۇڭ</string>\n    <string name=\"shadow_color\">سايە رەڭگى</string>\n    <string name=\"text_geometry\">Text Geometry</string>\n    <string name=\"text_geometry_sub\">ئۆتكۈر ئۇسلۇب ئۈچۈن تېكىستنى سوزۇش ياكى ئېغىش</string>\n    <string name=\"scale_x\">Scale X.</string>\n    <string name=\"skew_x\">Skew X.</string>\n    <string name=\"remove_annotations\">ئىزاھلارنى ئۆچۈرۈڭ</string>\n    <string name=\"remove_annotations_sub\">ئۇلىنىش ، باھا ، يارقىن نۇقتا ، شەكىل ياكى شەكىل بۆلەكلىرى قاتارلىق تاللانغان ئىزاھات تىپلىرىنى PDF بېتىدىن ئۆچۈرۈڭ</string>\n    <string name=\"annotation_link\">Hyperlinks</string>\n    <string name=\"annotation_file_attachment\">ھۆججەت قوشۇمچە ھۆججەتلىرى</string>\n    <string name=\"annotation_line\">قۇرلار</string>\n    <string name=\"annotation_popup\">پوپلار</string>\n    <string name=\"annotation_stamp\">ماركا</string>\n    <string name=\"annotation_shapes\">شەكىللەر</string>\n    <string name=\"annotation_text\">تېكىست ئىزاھلىرى</string>\n    <string name=\"annotation_text_markup\">Text Markup</string>\n    <string name=\"annotation_widget\">شەكىل مەيدانى</string>\n    <string name=\"annotation_markup\">Markup</string>\n    <string name=\"annotation_unknown\">نامەلۇم</string>\n    <string name=\"annotations\">ئىزاھلار</string>\n    <string name=\"ungroup\">Ungroup</string>\n    <string name=\"add_shadow_sub\">سەپلىگىلى بولىدىغان رەڭ ۋە سىزىقلار بىلەن قەۋەتنىڭ ئارقىسىغا تۇتۇق سايە قوشۇڭ</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-uk/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"image_too_large_preview\">Зображення завелике для попереднього перегляду, але спроба збереження все одно буде здійснена</string>\n    <string name=\"pick_image\">Виберіть зображення для початку</string>\n    <string name=\"resize_type\">Тип масштабування</string>\n    <string name=\"app_closing_sub\">Ви впевнені, що хочете закрити програму?</string>\n    <string name=\"app_closing\">Застосунок закривається</string>\n    <string name=\"values_reset\">Скинуто</string>\n    <string name=\"reset\">Перезавантаження</string>\n    <string name=\"copied\">Скопійовано до буфера</string>\n    <string name=\"edit_exif\">Редагувати EXIF</string>\n    <string name=\"no_exif\">EXIF не знайдено</string>\n    <string name=\"clear_exif\">Очистити EXIF</string>\n    <string name=\"crop\">Обрізати</string>\n    <string name=\"image_not_saved_sub\">Всі незбережені зміни будуть втрачені, якщо ви підете зараз</string>\n    <string name=\"color_copied\">Колір скопійовано</string>\n    <string name=\"crop_sub\">Довільно обрізати зображення</string>\n    <string name=\"keep_exif\">Зберегти EXIF</string>\n    <string name=\"remove\">Вилучити</string>\n    <string name=\"palette_sub\">Створити зразок палітри кольорів із заданого зображення</string>\n    <string name=\"generate_palette\">Згенерувати палітру</string>\n    <string name=\"new_version\">Нова версія %1$s</string>\n    <string name=\"def\">За замовчуванням</string>\n    <string name=\"custom\">Власний</string>\n    <string name=\"unspecified\">Не визначено</string>\n    <string name=\"device_storage\">Пам\\'ять пристрою</string>\n    <string name=\"by_bytes_resize\">Змінити розмір за вагою</string>\n    <string name=\"max_bytes\">Максимальний розмір в КБ</string>\n    <string name=\"by_bytes_resize_sub\">Змінити розмір зображення відповідно до заданого розміру в КБ</string>\n    <string name=\"smth_went_wrong\">Щось пішло не так: %1$s</string>\n    <string name=\"height\">Висота %1$s</string>\n    <string name=\"size\">Розмір %1$s</string>\n    <string name=\"loading\">Завантаження…</string>\n    <string name=\"extension\">Розширення</string>\n    <string name=\"width\">Ширина %1$s</string>\n    <string name=\"quality\">Якість</string>\n    <string name=\"close\">Закрити</string>\n    <string name=\"pick_image_alt\">Оберіть зображення</string>\n    <string name=\"explicit\">Точний</string>\n    <string name=\"reset_image\">Скинути зображення</string>\n    <string name=\"flexible\">Гнучкий</string>\n    <string name=\"stay\">Залишитися</string>\n    <string name=\"add_tag\">Додати тег</string>\n    <string name=\"cancel\">Скасувати</string>\n    <string name=\"check_source_code\">Вихідний код</string>\n    <string name=\"reset_image_sub\">Зображення будуть повернуті до початкового вигляду</string>\n    <string name=\"exception\">Виняток</string>\n    <string name=\"something_went_wrong\">Щось пішло не так</string>\n    <string name=\"restart_app\">Перезапустити застосунок</string>\n    <string name=\"ok\">Гаразд</string>\n    <string name=\"presets\">Пресети</string>\n    <string name=\"single_edit_sub\">Змінити, змінити розмір та відредагувати одне зображення</string>\n    <string name=\"clear\">Очистити</string>\n    <string name=\"save\">Зберегти</string>\n    <string name=\"clear_exif_sub\">Всі EXIF-дані зображення будуть очищені, цю дію неможливо скасувати!</string>\n    <string name=\"image_not_saved\">Збереження</string>\n    <string name=\"check_source_code_sub\">Отримуйте останні оновлення, обговорюйте проблеми та багато іншого</string>\n    <string name=\"single_edit\">Одинарне редагування</string>\n    <string name=\"pick_color_sub\">Виберіть колір із зображення, скопіюйте або поділіться ним</string>\n    <string name=\"pick_color\">Вибір кольору</string>\n    <string name=\"image\">Зображення</string>\n    <string name=\"color\">Колір</string>\n    <string name=\"version\">Версія</string>\n    <string name=\"images\">Зображення: %d</string>\n    <string name=\"change_preview\">Попередній перегляд змін</string>\n    <string name=\"palette\">Палітра</string>\n    <string name=\"unsupported_type\">Непідтримуваний тип: %1$s</string>\n    <string name=\"update\">Оновити</string>\n    <string name=\"original\">Оригінал</string>\n    <string name=\"folder\">Вихідна папка</string>\n    <string name=\"no_palette\">Не вдається згенерувати палітру для заданого зображення</string>\n    <string name=\"compare\">Порівняти</string>\n    <string name=\"compare_sub\">Порівняння двох наведених зображень</string>\n    <string name=\"pick_two_images\">Виберіть два зображення для початку</string>\n    <string name=\"pick_images\">Виберіть зображення</string>\n    <string name=\"settings\">Налаштування</string>\n    <string name=\"night_mode\">Нічний режим</string>\n    <string name=\"dark\">Темний</string>\n    <string name=\"light\">Світлий</string>\n    <string name=\"system\">Як у системі</string>\n    <string name=\"dynamic_colors\">Динамічні кольори</string>\n    <string name=\"allow_image_monet\">Увімкнути Monet</string>\n    <string name=\"language\">Мова</string>\n    <string name=\"allow_image_monet_sub\">Якщо ввімкнено, кольори застосунку будуть підлаштовуватися під вибране зображення в режимі редагування</string>\n    <string name=\"customization\">Налаштування</string>\n    <string name=\"amoled_mode\">Режим amoled</string>\n    <string name=\"color_red\">Червоний</string>\n    <string name=\"color_green\">Зелений</string>\n    <string name=\"color_blue\">Синій</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Вставте дійсний aRGB код кольору</string>\n    <string name=\"color_scheme\">Колірна гамма</string>\n    <string name=\"amoled_mode_sub\">Якщо ввімкнути, колір поверхонь буде встановлено на абсолютну темряву в нічному режимі</string>\n    <string name=\"clipboard_paste_invalid_empty\">Нічого вставляти</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Колірну схему програми не можна змінити, якщо ввімкнено динамічні кольори</string>\n    <string name=\"pick_accent_color\">Тема застосунку базуватиметься на кольорі, який ви виберете</string>\n    <string name=\"no_updates\">Оновлень не знайдено</string>\n    <string name=\"about_app\">Про застосунок</string>\n    <string name=\"issue_tracker\">Відстеження проблем</string>\n    <string name=\"issue_tracker_sub\">Надсилайте сюди звіти про помилки та запити щодо функцій</string>\n    <string name=\"help_translate\">Допоможіть перекласти</string>\n    <string name=\"search_here\">Шукайте тут</string>\n    <string name=\"help_translate_sub\">Виправте помилки перекладу або перекладіть проєкт іншими мовами</string>\n    <string name=\"nothing_found_by_search\">За вашим запитом нічого не знайдено</string>\n    <string name=\"dynamic_colors_sub\">Якщо ввімкнено, то кольори додатку підлаштуються під шпалери</string>\n    <string name=\"failed_to_save\">Не вдалося зберегти %d зображення</string>\n    <string name=\"primary\">Первинний</string>\n    <string name=\"tertiary\">Третинний</string>\n    <string name=\"secondary\">Вторинний</string>\n    <string name=\"surface\">Поверхня</string>\n    <string name=\"border_thickness\">Товщина рамки</string>\n    <string name=\"values\">Значення</string>\n    <string name=\"add\">Додати</string>\n    <string name=\"permission\">Дозвіл</string>\n    <string name=\"grant\">Дозволити</string>\n    <string name=\"permission_sub\">Застосунку потрібен доступ до вашого сховища для збереження зображень. Будь ласка, надайте дозвіл у наступному діалоговому вікні</string>\n    <string name=\"grant_permission_manual\">Застосунку потрібен цей дозвіл для роботи, будь ласка, надайте його вручну</string>\n    <string name=\"external_storage\">Зовнішня пам\\'ять</string>\n    <string name=\"monet_colors\">Кольори Monet</string>\n    <string name=\"donation_sub\">Цей застосунок є абсолютно безплатним, але якщо ви хочете підтримати розвиток проєкту, ви можете натиснути тут</string>\n    <string name=\"fab_alignment\">Вирівнювання FAB</string>\n    <string name=\"check_updates_sub\">Якщо увімкнено, після запуску застосунку буде показано діалогове вікно оновлення</string>\n    <string name=\"zoom\">Масштабування зображення</string>\n    <string name=\"check_updates\">Перевірка наявності оновлення</string>\n    <string name=\"prefix\">Префікс</string>\n    <string name=\"filename\">Ім\\'я файлу</string>\n    <string name=\"share\">Поділитися</string>\n    <string name=\"emoji_sub\">Виберіть, який смайл буде відображатися на головному екрані</string>\n    <string name=\"emoji\">Смайли</string>\n    <string name=\"add_file_size\">Додати розмір файлу</string>\n    <string name=\"delete_exif\">Видалити EXIF</string>\n    <string name=\"delete_exif_sub\">Видалення метаданих EXIF з будь-якої пари зображень</string>\n    <string name=\"add_file_size_sub\">Якщо увімкнено, додає ширину та висоту збереженого зображення до назви вихідного файлу</string>\n    <string name=\"image_preview\">Попередній перегляд зображення</string>\n    <string name=\"image_preview_sub\">Переглядайте будь-які типи зображень: GIF, SVG тощо</string>\n    <string name=\"image_source\">Джерело зображення</string>\n    <string name=\"photo_picker\">Вибір фотографій</string>\n    <string name=\"gallery_picker\">Галерея</string>\n    <string name=\"file_explorer_picker\">Файловий провідник</string>\n    <string name=\"photo_picker_sub\">Сучасний вибір фото в Android (знизу екрана), працює лише на Android 12+. Має проблеми з отриманням метаданих EXIF.</string>\n    <string name=\"file_explorer_picker_sub\">Використовувати GetContent для отримання зображення, працює скрізь, але на деяких пристроях можуть виникати проблеми з отриманням вибраних зображень, це не моя провина.</string>\n    <string name=\"gallery_picker_sub\">Простий вибір зображень галереї, він працюватиме, лише якщо у вас є цей застосунок</string>\n    <string name=\"options_arrangement\">Розташування опцій</string>\n    <string name=\"edit\">Редагувати</string>\n    <string name=\"order\">Порядок</string>\n    <string name=\"order_sub\">Визначає порядок інструментів на головному екрані</string>\n    <string name=\"emojis_count\">Кількість смайлів</string>\n    <string name=\"replace_sequence_number\">Додати порядковий номер</string>\n    <string name=\"sequence_num\">порядковий номер</string>\n    <string name=\"add_original_filename\">Додати оригінальне ім\\'я файлу</string>\n    <string name=\"replace_sequence_number_sub\">Якщо ввімкнено, замінює стандартну мітку часу на порядковий номер зображення, якщо ви використовуєте пакетну обробку</string>\n    <string name=\"original_filename\">оригінальне ім\\'я файлу</string>\n    <string name=\"add_original_filename_sub\">Якщо ввімкнено, додає назву оригінального файлу до назви вихідного зображення</string>\n    <string name=\"filename_not_work_with_photopicker\">Додавання оригінальної назви файлу не працює, якщо вибрано джерело зображення за допомогою фотопікселя</string>\n    <string name=\"load_image_from_net\">Завантаження веб-зображення</string>\n    <string name=\"load_image_from_net_sub\">Завантажуйте будь-яке зображення з Інтернету, переглядайте його, масштабуйте, а також зберігайте або редагуйте його за бажанням</string>\n    <string name=\"no_image\">Немає зображення</string>\n    <string name=\"image_link\">Посилання на зображення</string>\n    <string name=\"fill\">Заповнити</string>\n    <string name=\"fit\">Адаптувати</string>\n    <string name=\"explicit_description\">Змінює розмір зображень до заданої висоти та ширини. Співвідношення сторін зображень може змінюватися.</string>\n    <string name=\"content_scale\">Масштаб змісту</string>\n    <string name=\"crosshatch\">Перехресне штрихування</string>\n    <string name=\"spacing\">Інтервал</string>\n    <string name=\"brightness\">Яскравість</string>\n    <string name=\"contrast\">Контраст</string>\n    <string name=\"hue\">Відтінок</string>\n    <string name=\"saturation\">Насиченість</string>\n    <string name=\"add_filter\">Додати фільтр</string>\n    <string name=\"color_filter\">Кольоровий фільтр</string>\n    <string name=\"alpha\">Альфа</string>\n    <string name=\"white_balance\">Баланс білого</string>\n    <string name=\"temperature\">Температура</string>\n    <string name=\"line_width\">Ширина лінії</string>\n    <string name=\"sobel_edge\">Кромка Собель</string>\n    <string name=\"flexible_description\">Змінює розмір зображень з довгою стороною до заданої висоти або ширини. Усі розрахунки розміру будуть виконані після збереження. Співвідношення сторін зображень буде збережено.</string>\n    <string name=\"filters\">Фільтри</string>\n    <string name=\"filter\">Фільтр</string>\n    <string name=\"filter_sub\">Застосування ланцюжків фільтрів до зображень</string>\n    <string name=\"light_aka_illumination\">Світлий</string>\n    <string name=\"exposure\">Експозиція</string>\n    <string name=\"halftone\">Напівтон</string>\n    <string name=\"blur\">Розмиття</string>\n    <string name=\"cga_colorspace\">Колірний простір GCA</string>\n    <string name=\"gaussian_blur\">Гаусове розмиття</string>\n    <string name=\"box_blur\">Розмиття поля</string>\n    <string name=\"tint\">Тонування</string>\n    <string name=\"monochrome\">Монохромний</string>\n    <string name=\"gamma\">Гамма</string>\n    <string name=\"highlights_shadows\">Відблиски і тіні</string>\n    <string name=\"highlights\">Відблиски</string>\n    <string name=\"shadows\">Тіні</string>\n    <string name=\"haze\">Туман</string>\n    <string name=\"effect\">Ефект</string>\n    <string name=\"distance\">Відстань</string>\n    <string name=\"bulge\">Опуклість</string>\n    <string name=\"radius\">Радіус</string>\n    <string name=\"scale\">Масштаб</string>\n    <string name=\"limits_resize_sub\">Змінити розмір зображень до заданої висоти та ширини, зберігаючи співвідношення сторін</string>\n    <string name=\"sketch\">Ескіз</string>\n    <string name=\"threshold\">Поріг</string>\n    <string name=\"quantizationLevels\">Рівні квантування</string>\n    <string name=\"smooth_toon\">Гладкий мультфільм</string>\n    <string name=\"toon\">Мультфільм</string>\n    <string name=\"posterize\">Постеризувати</string>\n    <string name=\"non_maximum_suppression\">Не максимальне придушення</string>\n    <string name=\"weak_pixel_inclusion\">Слабке включення пікселів</string>\n    <string name=\"lookup\">Пошук</string>\n    <string name=\"stack_blur\">Стек розмиття</string>\n    <string name=\"convolution3x3\">Згортка 3х3</string>\n    <string name=\"rgb_filter\">RGB фільтр</string>\n    <string name=\"fast_blur\">Швидке розмиття</string>\n    <string name=\"blur_size\">Розмір розмиття</string>\n    <string name=\"luminance_threshold\">Поріг яскравості</string>\n    <string name=\"slope\">Нахил</string>\n    <string name=\"sharpen\">Різкість</string>\n    <string name=\"sepia\">Сепія</string>\n    <string name=\"negative\">Негатив</string>\n    <string name=\"solarize\">Соляризація</string>\n    <string name=\"vibrance\">Вібранс</string>\n    <string name=\"black_and_white\">Чорний і білий</string>\n    <string name=\"bilaterial_blur\">Двостороннє розмиття</string>\n    <string name=\"emboss\">Тиснення</string>\n    <string name=\"laplacian\">Лапласіан</string>\n    <string name=\"vignette\">Віньєтка</string>\n    <string name=\"start\">Старт</string>\n    <string name=\"end\">Кінець</string>\n    <string name=\"kuwahara\">Згладжування Кувахара</string>\n    <string name=\"distortion\">Спотворення</string>\n    <string name=\"angle\">Кут</string>\n    <string name=\"swirl\">Вир</string>\n    <string name=\"dilation\">Розширення</string>\n    <string name=\"sphere_refraction\">Заломлення сфери</string>\n    <string name=\"refractive_index\">Показник заломлення</string>\n    <string name=\"glass_sphere_refraction\">Рефракція скляної сфери</string>\n    <string name=\"color_matrix\">Кольорова матриця</string>\n    <string name=\"opacity\">Непрозорість</string>\n    <string name=\"limits_resize\">Змінити розмір за лімітами</string>\n    <string name=\"false_color\">Фальшивий колір</string>\n    <string name=\"first_color\">Перший колір</string>\n    <string name=\"second_color\">Другий колір</string>\n    <string name=\"reorder\">Змінити порядок</string>\n    <string name=\"blur_center_x\">Розмиття по центру x</string>\n    <string name=\"blur_center_y\">Центр розмиття y</string>\n    <string name=\"zoom_blur\">Збільшити розмиття</string>\n    <string name=\"color_balance\">Колірний баланс</string>\n    <string name=\"draw\">Малювати</string>\n    <string name=\"draw_sub\">Малюйте на зображенні, як в альбомі, або малюйте на самому фоні</string>\n    <string name=\"activate_files\">Ви вимкнули застосунок \\\"Файли\\\", ввімкніть його, щоб скористатися цією функцією</string>\n    <string name=\"draw_on_image_sub\">Виберіть зображення та намалюйте щось на ньому</string>\n    <string name=\"draw_on_background\">Малювати на фоні</string>\n    <string name=\"background_color\">Колір фону</string>\n    <string name=\"draw_on_image\">Малювати на зображенні</string>\n    <string name=\"paint_color\">Колір фарби</string>\n    <string name=\"draw_on_background_sub\">Виберіть колір фону і малюйте поверх нього</string>\n    <string name=\"paint_alpha\">Прозорість</string>\n    <string name=\"decrypt\">Розшифрувати</string>\n    <string name=\"pick_file_to_start\">Виберіть файл для запуску</string>\n    <string name=\"decryption\">Розшифровка</string>\n    <string name=\"features\">Функції</string>\n    <string name=\"cipher\">Шифр</string>\n    <string name=\"cipher_sub\">Зашифрувати та розшифрувати будь-який файл (не тільки зображення) на основі різних криптоалгоритмів</string>\n    <string name=\"compatibility\">Сумісність</string>\n    <string name=\"file_size_sub\">Максимальний розмір файлу обмежений операційною системою Android і доступною пам\\'яттю, яка, очевидно, залежить від вашого пристрою. \\nЗверніть увагу: пам\\'ять - це не сховище.</string>\n    <string name=\"pick_file\">Виберіть файл</string>\n    <string name=\"key\">Ключ</string>\n    <string name=\"store_file_desc\">Збережіть цей файл на своєму пристрої або скористайтеся \\\"Поділитися\\\", щоб розмістити його де завгодно</string>\n    <string name=\"implementation\">Реалізація</string>\n    <string name=\"features_sub\">Шифрування файлів на основі пароля. Отримані файли можна зберігати у вибраному каталозі або надавати спільний доступ. Розшифровані файли також можна безпосередньо відкрити.</string>\n    <string name=\"implementation_sub\">AES-256, режим GCM, без доповнення, 12 байт випадкових IV за замовчуванням. Ви можете вибрати потрібний алгоритм. Ключі використовуються як 256-бітні SHA-3 хеші.</string>\n    <string name=\"encrypt\">Шифрувати</string>\n    <string name=\"file_proceed\">Файл оброблено</string>\n    <string name=\"file_size\">Розмір файлу</string>\n    <string name=\"encryption\">Шифрування</string>\n    <string name=\"compatibility_sub\">Зверніть увагу, що сумісність з іншими програмами або сервісами для шифрування файлів не гарантується. Причиною несумісності може бути дещо інша обробка ключів або конфігурація шифру.</string>\n    <string name=\"group_options_by_type_sub\">Групує параметри на головному екрані за їхнім типом, а не за власним розташуванням списків</string>\n    <string name=\"invalid_password_or_not_encrypted\">Неправильний пароль або вибраний файл не зашифровано</string>\n    <string name=\"image_size_warning\">Спроба зберегти зображення із заданою шириною та висотою може призвести до нестачі пам\\'яті.</string>\n    <string name=\"cache\">Кеш</string>\n    <string name=\"cache_size\">Розмір кешу</string>\n    <string name=\"found_s\">Знайдено %1$s</string>\n    <string name=\"auto_cache_clearing\">Автоматичне очищення кешу</string>\n    <string name=\"auto_cache_clearing_sub\">Якщо ввімкнено, кеш застосунку буде очищено під час запуску застосунку</string>\n    <string name=\"tools\">Інструменти</string>\n    <string name=\"group_options_by_type\">Групування параметрів за типом</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Неможливо змінити розташування, якщо ввімкнено групування параметрів</string>\n    <string name=\"create\">Створити</string>\n    <string name=\"edit_screenshot\">Редагувати знімок екрана</string>\n    <string name=\"secondary_customization\">Вторинне налаштування</string>\n    <string name=\"screenshot\">Знімок екрана</string>\n    <string name=\"fallback_option\">Запасний варіант</string>\n    <string name=\"skip\">Пропустити</string>\n    <string name=\"copy\">Копіювати</string>\n    <string name=\"warning_bytes\">Збереження в режимі %1$s може бути нестабільним, оскільки це формат без втрат</string>\n    <string name=\"presets_sub\" formatted=\"false\">Якщо ви вибрали пресет 125, зображення буде збережено у розмірі 125% від оригінального зображення. Якщо ви вибрали пресет 50, зображення буде збережено у розмірі 50%.</string>\n    <string name=\"presets_sub_bytes\">Попереднє налаштування визначає відсоток вихідного файлу, тобто якщо ви оберете попереднє налаштування 50 для зображення розміром 5 МБ, то після збереження ви отримаєте зображення розміром 2,5 МБ.</string>\n    <string name=\"saved_to_without_filename\">Збережено до теки %1$s</string>\n    <string name=\"tg_chat_sub\">Обговоріть додаток та отримайте відгуки від інших користувачів. Ви також можете отримати там бета-оновлення та аналітику.</string>\n    <string name=\"randomize_filename\">Випадкова назва файла</string>\n    <string name=\"randomize_filename_sub\">Якщо ввімкнено, назва файлу буде повністю випадковою</string>\n    <string name=\"saved_to\">Збережено в теки %1$s з назвою %2$s</string>\n    <string name=\"tg_chat\">Чат Telegram</string>\n    <string name=\"crop_mask\">Маска для обрізання</string>\n    <string name=\"aspect_ratio\">Співвідношення сторін</string>\n    <string name=\"image_crop_mask_sub\">Використовуйте цей тип маски для створення маски з даного зображення, зверніть увагу, що вона ПОВИННА мати альфа-канал</string>\n    <string name=\"backup_and_restore\">Резервне копіювання та відновлення</string>\n    <string name=\"backup\">Резервна копія</string>\n    <string name=\"backup_sub\">Резервне копіювання налаштувань застосунку до файлу</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Пошкоджений файл або відсутня резервна копія</string>\n    <string name=\"settings_restored\">Налаштування успішно відновлено</string>\n    <string name=\"contact_me\">Зв’язатися зі мною</string>\n    <string name=\"restore\">Відновлення</string>\n    <string name=\"restore_sub\">Відновлення налаштувань застосунку з раніше створеного файлу</string>\n    <string name=\"reset_settings_sub\">Це поверне ваші налаштування до значень за замовчуванням. Зверніть увагу, що це неможливо скасувати без резервної копії, згаданої вище.</string>\n    <string name=\"delete\">Видалити</string>\n    <string name=\"delete_color_scheme_warn\">Ви збираєтеся видалити вибрану колірну схему. Цю дію неможливо скасувати.</string>\n    <string name=\"delete_color_scheme_title\">Видалити схему</string>\n    <string name=\"font\">Шрифт</string>\n    <string name=\"text\">Текст</string>\n    <string name=\"font_scale\">Розмір тексту</string>\n    <string name=\"defaultt\">За замовчуванням</string>\n    <string name=\"emotions\">Емоції</string>\n    <string name=\"food_and_drink\">Їжа та напої</string>\n    <string name=\"nature_and_animals\">Природа і тварини</string>\n    <string name=\"objects\">Об\\'єкти</string>\n    <string name=\"symbols\">Символи</string>\n    <string name=\"enable_emoji\">Увімкнути емодзі</string>\n    <string name=\"travels_and_places\">Подорожі та місця</string>\n    <string name=\"activities\">Активності</string>\n    <string name=\"background_remover\">Вилучення фону</string>\n    <string name=\"background_remover_sub\">Видаліть фон із зображення, намалювавши або скориставшись опцією Auto</string>\n    <string name=\"trim_image\">Обрізати зображення</string>\n    <string name=\"auto_erase_background\">Автоматичне видалення фону</string>\n    <string name=\"using_large_fonts_warn\">Використання більшого розміру тексту призведе до проблем з інтерфейсом, які неможливо вирішити. Використовуйте лише на свій розсуд</string>\n    <string name=\"keep_exif_sub\">Оригінальні метадані зображення будуть збережені</string>\n    <string name=\"restore_image\">Відновити зображення</string>\n    <string name=\"trim_image_sub\">Прозорий простір навколо зображення буде обрізано</string>\n    <string name=\"something_went_wrong_emphasis\">Упс… Щось пішло не так. Ви можете написати мені, використовуючи опції нижче, і я спробую знайти рішення.</string>\n    <string name=\"max_colors_count\">Максимальна кількість кольорів</string>\n    <string name=\"image_exif_warning\">Наразі формат %1$s на android дозволяє лише читати exif, а не змінювати/зберігати його, це означає, що вихідне зображення взагалі не матиме метаданих</string>\n    <string name=\"analytics_sub\">Дозволити збирати анонімну статистику використання програми</string>\n    <string name=\"draw_mode\">Режим малювання</string>\n    <string name=\"erase_background\">Стерти фон</string>\n    <string name=\"blur_radius\">Ступінь розмиття</string>\n    <string name=\"crashlytics_sub\">Це дозволяє програмі автоматично збирати звіти про збої</string>\n    <string name=\"create_issue\">Повідомити про помилку</string>\n    <string name=\"pipette\">Піпетка</string>\n    <string name=\"analytics\">Аналітика</string>\n    <string name=\"resize_and_convert\">Змінити розмір і конвертувати</string>\n    <string name=\"restore_background\">Відновити фон</string>\n    <string name=\"resize_and_convert_sub\">Змініть розмір заданих зображень або конвертуйте їх в інші формати, також там ви можете редагувати метадані EXIF, якщо ви вибрали одне зображення</string>\n    <string name=\"erase_mode\">Режим стирання</string>\n    <string name=\"updates\">Оновлення</string>\n    <string name=\"wait\">Зачекайте</string>\n    <string name=\"effort_sub\">Значення %1$s означає швидке стиснення, що призводить до відносно великого розміру файлу. %2$s означає витрачати більше часу на стиснення, в результаті чого менший файл</string>\n    <string name=\"allow_betas\">Дозволити бета-версії</string>\n    <string name=\"alphabet_and_numbers\">Аа Бб Вв Гг Ґґ Дд Ее Єє Жж Зз Ии Іі Її Йй Кк Лл Мм Нн Оо Пп Рр Сс Тт Уу Фф Хх Цц Чч Шш Щщ Ьь Юю Яя 0123456789 !?</string>\n    <string name=\"saving_almost_complete\">Збереження майже завершено, якщо ви скасуєте, що тепер вам потрібно буде почати збереження знову</string>\n    <string name=\"effort\">Зусилля</string>\n    <string name=\"allow_betas_sub\">Перевірка оновлень включатиме бета-версії застосунків, якщо ввімкнено</string>\n    <string name=\"horizontal\">Горизонтальна</string>\n    <string name=\"recode\">Перекодування</string>\n    <string name=\"tolerance\">Допущення</string>\n    <string name=\"both\">Обидва</string>\n    <string name=\"images_order\">Порядок зображень</string>\n    <string name=\"invert_colors_sub\">Змінює кольори теми на негативні, якщо увімкнено</string>\n    <string name=\"fidelity\">Точність</string>\n    <string name=\"brush_softness\">М\\'якість пензлика</string>\n    <string name=\"blur_edges\">Розмиття країв</string>\n    <string name=\"rainbow\">Веселка</string>\n    <string name=\"playful_scheme\">Грайлива тема: відтінок вихідного кольору не зображається в темі</string>\n    <string name=\"fading_edges\">Зникання країв</string>\n    <string name=\"vibrant_sub\">Яскрава тема, барвистість максимальна для Основної палітри і підвищена для інших</string>\n    <string name=\"image_stitching\">Об\\'єднання зображень</string>\n    <string name=\"pixelation\">Пікселізація</string>\n    <string name=\"pdf_tools\">Інструменти PDF</string>\n    <string name=\"neutral_sub\">Стиль, який трохи більш хроматичний, ніж монохромний</string>\n    <string name=\"enhanced_pixelation\">Покращена пікселізація</string>\n    <string name=\"target_color\">Цільовий колір</string>\n    <string name=\"draw_arrows\">Намалювати стрілки</string>\n    <string name=\"pick_at_least_two_images\">Виберіть мінімум 2 зображення</string>\n    <string name=\"foss_update_checker_warning\">Перевірка оновлень буде підключатися до GitHub, щоб перевірити, чи доступне нове оновлення</string>\n    <string name=\"pixel_size\">Розмір Пікселя</string>\n    <string name=\"content_sub\">Схема, яка поміщає вихідний колір у Scheme.primaryContainer</string>\n    <string name=\"tonal_spot\">Тональна пляма</string>\n    <string name=\"search_option\">Пошук</string>\n    <string name=\"replace_color\">Змінити колір</string>\n    <string name=\"diamond_pixelation\">Діамантова пікселізація</string>\n    <string name=\"blur_edges_sub\">Малює розмиті краї під вихідним зображенням, щоб заповнити простір навколо нього, а не одним кольором, якщо ввімкнено.</string>\n    <string name=\"remove_color\">Вилучити колір</string>\n    <string name=\"images_to_pdf\">Зображення до PDF</string>\n    <string name=\"draw_arrows_sub\">Якщо ввімкнено, то на кінці лінії буде домальовуватися стрілка</string>\n    <string name=\"monochrome_sub\">Монохромна тема, кольори суто чорний/білий/сірий.</string>\n    <string name=\"scale_small_images_to_large_sub\">Якщо увімкнено, маленькі зображення будуть масштабовані до найбільшого в послідовності</string>\n    <string name=\"fruit_salad\">Фруктовий салат</string>\n    <string name=\"enhanced_diamond_pixelation\">Покращена діамантова пікселізація</string>\n    <string name=\"circle_pixelation\">Кругова пікселізація</string>\n    <string name=\"lock_draw_orientation\">Блокування орієнтації малювання</string>\n    <string name=\"image_stitching_sub\">Об\\'єднати вхідні зображення в одне велике</string>\n    <string name=\"preview_pdf\">Передперегляд PDF</string>\n    <string name=\"fidelity_sub\">Схема, яка дуже схожа на схему вмісту</string>\n    <string name=\"check_for_updates\">Перевірити оновлення</string>\n    <string name=\"search_option_sub\">Дозволяє шукати серед усіх доступних інструментів на головному екрані</string>\n    <string name=\"image_orientation\">Орієнтація зображення</string>\n    <string name=\"content\">Вміст</string>\n    <string name=\"disabled\">Вимкнуто</string>\n    <string name=\"vertical\">Вертикальна</string>\n    <string name=\"pdf_to_images\">PDF на зображення</string>\n    <string name=\"expressive\">Виразний</string>\n    <string name=\"neutral\">Нейтральний</string>\n    <string name=\"color_to_remove\">Колір для видалення</string>\n    <string name=\"tonal_spot_sub\">Стиль типової палітри дозволяє налаштувати всі чотири кольори, інші дозволяють встановити лише ключовий колір</string>\n    <string name=\"color_to_replace\">Колір для заміни</string>\n    <string name=\"images_to_pdf_sub\">Пакування заданих зображень у файл PDF</string>\n    <string name=\"crop_description\">Зображення будуть обрізані по центру до введеного розміру. Полотно буде розширене із заданим кольором фону, якщо зображення менше введених розмірів.</string>\n    <string name=\"donation\">Пожертвування</string>\n    <string name=\"preview_pdf_sub\">Простий переглядач PDF</string>\n    <string name=\"output_image_scale\">Масштаб вихідного зображення</string>\n    <string name=\"lock_draw_orientation_sub\">Якщо ввімкнено в режимі малювання, екран не обертатиметься</string>\n    <string name=\"palette_style\">Стиль палітри</string>\n    <string name=\"invert_colors\">Інвертувати кольори</string>\n    <string name=\"vibrant\">Яскравий</string>\n    <string name=\"stroke_pixelation\">Штрихова пікселізація</string>\n    <string name=\"regular\">Звичайний</string>\n    <string name=\"pdf_tools_sub\">Опрацювання файлів PDF: Попередній перегляд, перетворення на пакет зображень або створення із заданих зображень</string>\n    <string name=\"enhanced_circle_pixelation\">Покращена кругова пікселізація</string>\n    <string name=\"attention\">Застереження</string>\n    <string name=\"scale_small_images_to_large\">Масштабування маленьких зображень до великих</string>\n    <string name=\"pdf_to_images_sub\">Перетворення PDF на зображення в заданому форматі</string>\n    <string name=\"vibration\">Вібрація</string>\n    <string name=\"clipboard\">Буфер обміну</string>\n    <string name=\"vibration_strength\">Сила вібрації</string>\n    <string name=\"recognize_text_sub\">Розпізнавайте текст із заданого зображення, підтримується понад 120 мов</string>\n    <string name=\"picture_has_no_text\">На зображенні немає тексту або застосунок не знайшов його</string>\n    <string name=\"auto_pin_sub\">Автоматично додає збережене зображення до буфера обміну, якщо ввімкнено</string>\n    <string name=\"only_clip_sub\">Збереження в сховищі не буде виконано, і зображення за можливості буде поміщене в буфер обміну</string>\n    <string name=\"value_in_range\">Значення в діапазоні %1$s - %2$s</string>\n    <string name=\"only_clip\">Тільки натискання</string>\n    <string name=\"recognize_text\">OCR (розпізнавання тексту)</string>\n    <string name=\"app_bars_shadow\">Панелі програм</string>\n    <string name=\"app_bars_shadow_sub\">Намалюйте тінь за панелями програм</string>\n    <string name=\"enhanced_glitch\">Покращений глюк</string>\n    <string name=\"channel_shift_x\">Зсув каналу X</string>\n    <string name=\"channel_shift_y\">Зсув каналу Y</string>\n    <string name=\"corruption_size\">Розмір корупції</string>\n    <string name=\"corruption_shift_x\">Корупційний зсув X</string>\n    <string name=\"corruption_shift_y\">Корупційний зсув Ю</string>\n    <string name=\"tent_blur\">Розмиття намету</string>\n    <string name=\"side_fade\">Бічне вицвітання</string>\n    <string name=\"side\">сторона</string>\n    <string name=\"top\">Топ</string>\n    <string name=\"segmentation_mode_osd_only\">Орієнтація &amp; Лише виявлення сценарію</string>\n    <string name=\"segmentation_mode_auto_osd\">Автоматична орієнтація &amp; Виявлення сценарію</string>\n    <string name=\"segmentation_mode_auto_only\">Тільки авто</string>\n    <string name=\"segmentation_mode_auto\">Авто</string>\n    <string name=\"glitch\">Глюк</string>\n    <string name=\"amount\">Сума</string>\n    <string name=\"pixel_sort\">Сортування пікселів</string>\n    <string name=\"shuffle\">Перетасувати</string>\n    <string name=\"drago\">Драго</string>\n    <string name=\"cutoff\">Відрізати</string>\n    <string name=\"mobius\">Мебіус</string>\n    <string name=\"no_such_directory\">Каталог \\\"%1$s\\\" не знайдено, ми змінили його на стандартний, збережіть файл ще раз</string>\n    <string name=\"auto_pin\">Автоматична шпилька</string>\n    <string name=\"overwrite_file_requirements\">Щоб перезаписати файли, потрібно використовувати джерело зображень \\\"Провідник\\\", спробуйте повторно вибрати зображення, ми змінили джерело зображень на потрібне</string>\n    <string name=\"overwrite_files\">Перезаписати файли</string>\n    <string name=\"overwrite_files_sub\">Оригінальний файл буде замінено новим замість збереження у вибраній папці. Джерелом зображення для цієї опції має бути \\\"Провідник\\\" або GetContent, коли ввімкнути цю опцію, вона буде встановлена автоматично</string>\n    <string name=\"empty\">Порожній</string>\n    <string name=\"suffix\">Суфікс</string>\n    <string name=\"free\">безкоштовно</string>\n    <string name=\"emoji_as_color_scheme\">Емодзі як колірна схема</string>\n    <string name=\"email\">Електронна пошта</string>\n    <string name=\"mask_preview_sub\">Намальована маска фільтра буде відрендерена, щоб показати вам приблизний результат</string>\n    <string name=\"neon\">Неон</string>\n    <string name=\"privacy_blur\">Розмиття конфіденційності</string>\n    <string name=\"neon_sub\">Додайте сяючий ефект своїм малюнкам</string>\n    <string name=\"arrow\">Стрілка</string>\n    <string name=\"line\">лінія</string>\n    <string name=\"arrow_sub\">Малює вказівну стрілку від заданого шляху</string>\n    <string name=\"oval\">Овальний</string>\n    <string name=\"rect\">Rect</string>\n    <string name=\"rect_sub\">Малює прямокутник від початкової до кінцевої точки</string>\n    <string name=\"oval_sub\">Малює овал від початкової до кінцевої точки</string>\n    <string name=\"outlined_oval_sub\">Малює контурний овал від початкової до кінцевої точки</string>\n    <string name=\"outlined_rect_sub\">Малює окреслений прямокутник від початкової до кінцевої точки</string>\n    <string name=\"bilinear_sub\">Лінійна (або білінійна, у двох вимірах) інтерполяція зазвичай хороша для зміни розміру зображення, але спричиняє деяке небажане пом’якшення деталей і все ще може бути дещо нерівним</string>\n    <string name=\"basic_sub\">Найпростіший режим масштабування Android, який використовується майже у всіх програмах</string>\n    <string name=\"catmull_sub\">Метод плавної інтерполяції та повторної вибірки набору контрольних точок, який зазвичай використовується в комп’ютерній графіці для створення плавних кривих</string>\n    <string name=\"hann_sub\">Функція вікон, яка часто застосовується в обробці сигналу, щоб мінімізувати спектральний витік і підвищити точність частотного аналізу шляхом звуження країв сигналу</string>\n    <string name=\"hermite_sub\">Техніка математичної інтерполяції, яка використовує значення та похідні в кінцевих точках сегмента кривої для створення гладкої та безперервної кривої</string>\n    <string name=\"lanczos_sub\">Метод повторної дискретизації, який підтримує високоякісну інтерполяцію шляхом застосування зваженої функції sinc до значень пікселів</string>\n    <string name=\"mitchell_sub\">Метод передискретизації, який використовує фільтр згортки з регульованими параметрами для досягнення балансу між різкістю та згладжуванням у масштабованому зображенні</string>\n    <string name=\"spline_sub\">Використовує кусково-визначені поліноміальні функції для плавної інтерполяції та апроксимації кривої або поверхні, забезпечуючи гнучке та безперервне представлення форми</string>\n    <string name=\"segmentation_mode_single_column\">Одна колонка</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Одноблоковий вертикальний текст</string>\n    <string name=\"segmentation_mode_single_block\">Одиночний блок</string>\n    <string name=\"segmentation_mode_single_line\">Одна лінія</string>\n    <string name=\"segmentation_mode_single_word\">Одне слово</string>\n    <string name=\"segmentation_mode_circle_word\">Обведіть слово</string>\n    <string name=\"segmentation_mode_single_char\">Один символ</string>\n    <string name=\"segmentation_mode_sparse_text\">Розріджений текст</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Орієнтація розрідженого тексту &amp; Виявлення сценарію</string>\n    <string name=\"segmentation_mode_raw_line\">Необроблена лінія</string>\n    <string name=\"delete_language_sub\">Ви бажаєте видалити навчальні дані оптичного розпізнавання мови \\\"%1$s\\\" для всіх типів розпізнавання чи лише для вибраного (%2$s)?</string>\n    <string name=\"all\">все</string>\n    <string name=\"offset_x\">Зсув X</string>\n    <string name=\"offset_y\">Зсув Y</string>\n    <string name=\"watermark_type\">Тип водяного знака</string>\n    <string name=\"repeat_count\">Повторити підрахунок</string>\n    <string name=\"millis\">мілі</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Джарвіс Джудіс Нінке Дітерінг</string>\n    <string name=\"atkinson_dithering\">Аткінсон Дітерінг</string>\n    <string name=\"burkes_dithering\">Беркс Дізерінг</string>\n    <string name=\"false_floyd_steinberg_dithering\">False Floyd Steinberg Dithering</string>\n    <string name=\"simple_threshold_dithering\">Просте порогове згладжування</string>\n    <string name=\"seed\">насіння</string>\n    <string name=\"anaglyph\">Анагліф</string>\n    <string name=\"noise\">Шум</string>\n    <string name=\"bottom\">Дно</string>\n    <string name=\"strength\">Сила</string>\n    <string name=\"logarithmic_tone_mapping\">Логарифмічне відображення тонів</string>\n    <string name=\"crystallize\">Кристалізуватися</string>\n    <string name=\"stroke_color\">Колір обведення</string>\n    <string name=\"perlin_distortion\">Спотворення Перліна</string>\n    <string name=\"deutaromaly\">Дейтераномалія</string>\n    <string name=\"protonomaly\">Протаномалія</string>\n    <string name=\"vintage\">Вінтаж</string>\n    <string name=\"browni\">Брауні</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Нічне бачення</string>\n    <string name=\"warm\">Теплий</string>\n    <string name=\"cool\">круто</string>\n    <string name=\"tritanopia\">Тританопія</string>\n    <string name=\"deutaronotopia\">Деутаронотопія</string>\n    <string name=\"protanopia\">Протанопія</string>\n    <string name=\"achromatomaly\">Ахроматомалія</string>\n    <string name=\"golden_hour\">Золота година</string>\n    <string name=\"hot_summer\">Спекотне літо</string>\n    <string name=\"purple_mist\">Фіолетовий туман</string>\n    <string name=\"sunrise\">Схід сонця</string>\n    <string name=\"color_explosion\">Кольоровий вибух</string>\n    <string name=\"electric_gradient\">Електричний градієнт</string>\n    <string name=\"icon_shape_sub\">Додає контейнер із вибраною фігурою під значками</string>\n    <string name=\"aldridge\">Олдрідж</string>\n    <string name=\"uchimura\">Учімура</string>\n    <string name=\"transition\">Перехід</string>\n    <string name=\"peak\">пік</string>\n    <string name=\"color_anomaly\">Колірна аномалія</string>\n    <string name=\"images_overwritten\">Зображення перезаписано в оригінальному місці призначення</string>\n    <string name=\"cannot_change_image_format\">Неможливо змінити формат зображення, якщо ввімкнено параметр перезапису файлів</string>\n    <string name=\"emoji_as_color_scheme_sub\">Використовує основний колір емодзі як колірну схему програми замість визначеної вручну</string>\n    <string name=\"erode\">Роз’їдати</string>\n    <string name=\"anisotropic_diffusion\">Анізотропна дифузія</string>\n    <string name=\"diffusion\">дифузія</string>\n    <string name=\"conduction\">Проведення</string>\n    <string name=\"horizontal_wind_stagger\">Горизонтальний вітер</string>\n    <string name=\"fast_bilaterial_blur\">Швидке двостороннє розмиття</string>\n    <string name=\"poisson_blur\">Розмиття Пуассона</string>\n    <string name=\"fractal_glass\">Фрактальне скло</string>\n    <string name=\"amplitude\">Амплітуда</string>\n    <string name=\"marble\">Мармур</string>\n    <string name=\"turbulence\">Турбулентність</string>\n    <string name=\"oil\">олія</string>\n    <string name=\"water_effect\">Ефект води</string>\n    <string name=\"just_size\">Розмір</string>\n    <string name=\"frequency_x\">Частота X</string>\n    <string name=\"frequency_y\">Частота Y</string>\n    <string name=\"amplitude_x\">Амплітуда X</string>\n    <string name=\"amplitude_y\">Амплітуда Y</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable Filmic Tone Mapping</string>\n    <string name=\"heji_burgess_tone_mapping\">Тонове відображення Хеджі-Берджеса</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES Filmic Tone Mapping</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill Tone Mapping</string>\n    <string name=\"current\">поточний</string>\n    <string name=\"full_filter\">Повний фільтр</string>\n    <string name=\"start_position\">старт</string>\n    <string name=\"center_position\">центр</string>\n    <string name=\"end_position\">Кінець</string>\n    <string name=\"full_filter_sub\">Застосуйте будь-які ланцюжки фільтрів до заданих зображень або окремого зображення</string>\n    <string name=\"gradient_maker\">Створення градієнта</string>\n    <string name=\"gradient_maker_sub\">Створіть градієнт заданого вихідного розміру з налаштованими кольорами та типом вигляду</string>\n    <string name=\"speed\">швидкість</string>\n    <string name=\"dehaze\">Розтушовувати</string>\n    <string name=\"omega\">Омега</string>\n    <string name=\"rate_app\">Оцініть додаток</string>\n    <string name=\"rate\">Оцінка</string>\n    <string name=\"rate_app_sub\">Ця програма абсолютно безкоштовна, якщо ви хочете, щоб вона стала більшою, позначте проект зірочкою на Github 😄</string>\n    <string name=\"color_matrix_4x4\">Кольорова матриця 4х4</string>\n    <string name=\"color_matrix_3x3\">Кольорова матриця 3х3</string>\n    <string name=\"simple_effects\">Прості ефекти</string>\n    <string name=\"polaroid\">Полароїд</string>\n    <string name=\"tritonomaly\">Тританомалія</string>\n    <string name=\"achromatopsia\">Ахроматопсія</string>\n    <string name=\"gradient_type_linear\">Лінійний</string>\n    <string name=\"gradient_type_radial\">Радіальний</string>\n    <string name=\"gradient_type_sweep\">підмітати</string>\n    <string name=\"gradient_type\">Тип градієнта</string>\n    <string name=\"center_x\">Центр X</string>\n    <string name=\"center_y\">Центр Ю</string>\n    <string name=\"tile_mode\">Режим плитки</string>\n    <string name=\"tile_mode_repeated\">Повторюється</string>\n    <string name=\"tile_mode_mirror\">Дзеркало</string>\n    <string name=\"tile_mode_clamp\">Затискач</string>\n    <string name=\"tile_mode_decal\">Декаль</string>\n    <string name=\"color_stops\">Кольорові зупинки</string>\n    <string name=\"add_color\">Додайте колір</string>\n    <string name=\"properties\">Властивості</string>\n    <string name=\"lasso\">Ласо</string>\n    <string name=\"lasso_sub\">Малює замкнутий контур із заливкою за заданим контуром</string>\n    <string name=\"draw_path_mode\">Режим малювання шляху</string>\n    <string name=\"double_line_arrow\">подвійна лінія стрілка</string>\n    <string name=\"free_drawing\">Безкоштовне малювання</string>\n    <string name=\"double_arrow\">Подвійна стрілка</string>\n    <string name=\"line_arrow\">Лінія стрілка</string>\n    <string name=\"free_drawing_sub\">Малює шлях як вхідне значення</string>\n    <string name=\"line_sub\">Малює шлях від початкової до кінцевої точки як лінію</string>\n    <string name=\"line_arrow_sub\">Малює вказівну стрілку від початкової до кінцевої точки як лінію</string>\n    <string name=\"double_line_arrow_sub\">Малює подвійну стрілку від початкової точки до кінцевої точки як лінію</string>\n    <string name=\"double_arrow_sub\">Малює подвійну стрілку від заданого шляху</string>\n    <string name=\"outlined_oval\">Контурований овал</string>\n    <string name=\"outlined_rect\">Окреслений Rect</string>\n    <string name=\"dithering\">Дизерінг</string>\n    <string name=\"quantizier\">Квантизер</string>\n    <string name=\"gray_scale\">Шкала сірого</string>\n    <string name=\"bayer_two_dithering\">Bayer Two By Two Dithering</string>\n    <string name=\"bayer_three_dithering\">Bayer Three By Three Dithering</string>\n    <string name=\"bayer_four_dithering\">Bayer Four By Four Dithering</string>\n    <string name=\"bayer_eight_dithering\">Bayer Eight By Eight Dithering</string>\n    <string name=\"floyd_steinberg_dithering\">Флойд Стайнберг Дітерінг</string>\n    <string name=\"sierra_dithering\">Sierra Dithering</string>\n    <string name=\"two_row_sierra_dithering\">Two Row Sierra Dithering</string>\n    <string name=\"sierra_lite_dithering\">Sierra Lite Dithering</string>\n    <string name=\"stucki_dithering\">Стукі Дізерінг</string>\n    <string name=\"left_to_right_dithering\">Змішування зліва направо</string>\n    <string name=\"random_dithering\">Випадкове згладжування</string>\n    <string name=\"mask_preview\">Попередній перегляд маски</string>\n    <string name=\"scale_mode\">Режим масштабування</string>\n    <string name=\"bilinear\">Білінійний</string>\n    <string name=\"hann\">Ханн</string>\n    <string name=\"hermite\">Ерміт</string>\n    <string name=\"lanczos\">Ланцош</string>\n    <string name=\"mitchell\">Мітчелл</string>\n    <string name=\"nearest\">Найближчий</string>\n    <string name=\"spline\">Сплайн</string>\n    <string name=\"basic\">Базовий</string>\n    <string name=\"default_value\">Значення за замовчуванням</string>\n    <string name=\"sigma\">Сигма</string>\n    <string name=\"spatial_sigma\">Просторова сигма</string>\n    <string name=\"median_blur\">Середнє розмиття</string>\n    <string name=\"catmull\">Кетмулл</string>\n    <string name=\"bicubic\">Бікубічний</string>\n    <string name=\"bicubic_sub\">Кращі методи масштабування включають перевибірку Ланцоша та фільтри Мітчелла-Нетравалі</string>\n    <string name=\"nearest_sub\">Один із найпростіших способів збільшення розміру, заміна кожного пікселя кількома пікселями одного кольору</string>\n    <string name=\"icon_shape\">Форма значка</string>\n    <string name=\"brightness_enforcement\">Максимальна яскравість</string>\n    <string name=\"screen\">Екран</string>\n    <string name=\"gradient_maker_type_image\">Градієнтне накладання</string>\n    <string name=\"gradient_maker_type_image_sub\">Створити будь-який градієнт верхньої частини заданих зображень</string>\n    <string name=\"transformations\">Трансформації</string>\n    <string name=\"camera\">Камера</string>\n    <string name=\"camera_sub\">Зробіть фотографію камерою. Зверніть увагу, що з цього джерела зображень можна отримати лише одне зображення.</string>\n    <string name=\"grain\">зерно</string>\n    <string name=\"unsharp\">Нерізкий</string>\n    <string name=\"pastel\">Пастель</string>\n    <string name=\"orange_haze\">Помаранчевий серпанок</string>\n    <string name=\"pink_dream\">Рожева мрія</string>\n    <string name=\"colorful_swirl\">Барвистий вир</string>\n    <string name=\"soft_spring_light\">М\\'яке весняне світло</string>\n    <string name=\"autumn_tones\">Осінні тони</string>\n    <string name=\"lavender_dream\">Лавандова мрія</string>\n    <string name=\"cyberpunk\">Кіберпанк</string>\n    <string name=\"lemonade_light\">Лимонад Light</string>\n    <string name=\"spectral_fire\">Спектральний вогонь</string>\n    <string name=\"night_magic\">Нічна магія</string>\n    <string name=\"fantasy_landscape\">Фантазійний пейзаж</string>\n    <string name=\"caramel_darkness\">Карамельна темрява</string>\n    <string name=\"futuristic_gradient\">Футуристичний градієнт</string>\n    <string name=\"green_sun\">Зелене сонечко</string>\n    <string name=\"rainbow_world\">Райдужний світ</string>\n    <string name=\"deep_purple\">Deep Purple</string>\n    <string name=\"space_portal\">Космічний портал</string>\n    <string name=\"red_swirl\">Червоний вир</string>\n    <string name=\"digital_code\">Цифровий код</string>\n    <string name=\"watermarking\">Водяний знак</string>\n    <string name=\"watermarking_sub\">Зображення на обкладинці з настроюваними текстовими/графічними водяними знаками</string>\n    <string name=\"repeat_watermark\">Повторіть водяний знак</string>\n    <string name=\"repeat_watermark_sub\">Повторює водяний знак поверх зображення замість одного в заданому місці</string>\n    <string name=\"watermarking_image_sub\">Це зображення буде використано як шаблон для водяних знаків</string>\n    <string name=\"text_color\">Колір тексту</string>\n    <string name=\"overlay_mode\">Режим накладання</string>\n    <string name=\"bokeh\">Боке</string>\n    <string name=\"gif_tools\">Інструменти GIF</string>\n    <string name=\"gif_tools_sub\">Перетворіть зображення на зображення GIF або витягніть кадри з заданого зображення GIF</string>\n    <string name=\"gif_type_to_image\">GIF до зображень</string>\n    <string name=\"gif_type_to_image_sub\">Перетворіть файл GIF на пакет зображень</string>\n    <string name=\"gif_type_to_gif_sub\">Перетворіть пакет зображень у файл GIF</string>\n    <string name=\"gif_type_to_gif\">Зображення в GIF</string>\n    <string name=\"select_gif_image_to_start\">Виберіть зображення GIF для початку</string>\n    <string name=\"use_size_of_first_frame\">Використовуйте розмір першого кадру</string>\n    <string name=\"use_size_of_first_frame_sub\">Замініть вказаний розмір першими розмірами кадру</string>\n    <string name=\"frame_delay\">Затримка кадру</string>\n    <string name=\"use_lasso\">Використовуйте ласо</string>\n    <string name=\"original_image_preview_alpha\">Оригінальний попередній перегляд зображення Альфа</string>\n    <string name=\"use_lasso_sub\">Використовує ласо, як у режимі малювання, для виконання стирання</string>\n    <string name=\"mask_filter\">Фільтр масок</string>\n    <string name=\"mask_filter_sub\">Застосовуйте ланцюжки фільтрів до заданих маскованих областей, кожна область маски може визначати свій власний набір фільтрів</string>\n    <string name=\"masks\">маски</string>\n    <string name=\"add_mask\">Додати маску</string>\n    <string name=\"mask_indexed\">Маска %d</string>\n    <string name=\"random_emojis_sub\">Емодзі панелі програм змінюватиметься випадковим чином</string>\n    <string name=\"random_emojis\">Випадкові емодзі</string>\n    <string name=\"random_emojis_error\">Ви не можете використовувати випадкові емодзі, поки емодзі вимкнено</string>\n    <string name=\"emoji_selection_error\">Ви не можете вибрати емодзі, коли ввімкнено випадкові емодзі</string>\n    <string name=\"old_tv\">Старий телевізор</string>\n    <string name=\"shuffle_blur\">Розмиття у випадковому порядку</string>\n    <string name=\"accuracy\">Accuracy: %1$s</string>\n    <string name=\"recognition_type\">Тип розпізнавання</string>\n    <string name=\"fast\">швидко</string>\n    <string name=\"standard\">Стандартний</string>\n    <string name=\"best\">Найкращий</string>\n    <string name=\"no_data\">Немає даних</string>\n    <string name=\"download_description\">Для належної роботи Tesseract OCR необхідно завантажити додаткові навчальні дані (%1$s) на ваш пристрій. \\nВи хочете завантажити дані %2$s?</string>\n    <string name=\"download\">Завантажити</string>\n    <string name=\"no_connection\">Немає з’єднання, перевірте його та повторіть спробу, щоб завантажити моделі поїздів</string>\n    <string name=\"downloaded_languages\">Завантажені мови</string>\n    <string name=\"available_languages\">Доступні мови</string>\n    <string name=\"segmentation_mode\">Режим сегментації</string>\n    <string name=\"restore_background_sub\">Пензель відновить фон замість стирання</string>\n    <string name=\"horizontal_grid\">Горизонтальна сітка</string>\n    <string name=\"vertical_grid\">Вертикальна сітка</string>\n    <string name=\"stitch_mode\">Режим стібка</string>\n    <string name=\"rows_count\">Підрахунок рядків</string>\n    <string name=\"columns_count\">Підрахунок стовпців</string>\n    <string name=\"use_pixel_switch\">Використовуйте Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Використовує перемикач, подібний до Google Pixel</string>\n    <string name=\"slide\">Слайд</string>\n    <string name=\"side_by_side\">Пліч-о-пліч</string>\n    <string name=\"toggle_tap\">Перемикач</string>\n    <string name=\"transparency\">Прозорість</string>\n    <string name=\"saved_to_original\">Перезаписаний файл із назвою %1$s у початковому місці призначення</string>\n    <string name=\"magnifier\">лупа</string>\n    <string name=\"magnifier_sub\">Вмикає лупу у верхній частині пальця в режимах малювання для кращої доступності</string>\n    <string name=\"force_exif_widget_initial_value\">Примусове початкове значення</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Примусово спочатку перевіряє віджет exif</string>\n    <string name=\"allow_multiple_languages\">Дозволити кілька мов</string>\n    <string name=\"favorite\">улюблений</string>\n    <string name=\"no_favorite_filters\">Вибраних фільтрів ще не додано</string>\n    <string name=\"b_spline\">Б Сплайн</string>\n    <string name=\"b_spline_sub\">Використовує кусково визначені бікубічні поліноміальні функції для плавної інтерполяції та апроксимації кривої або поверхні, гнучкого та безперервного представлення форми</string>\n    <string name=\"native_stack_blur\">Власне розмиття стека</string>\n    <string name=\"tilt_shift\">Tilt Shift</string>\n    <string name=\"inverse_fill_type\">Тип зворотного заповнення</string>\n    <string name=\"inverse_fill_type_sub\">Якщо ввімкнено, усі незамасковані області буде відфільтровано замість поведінки за замовчуванням</string>\n    <string name=\"confetti\">Конфетті</string>\n    <string name=\"confetti_sub\">Конфетті буде показано під час збереження, обміну та інших основних дій</string>\n    <string name=\"secure_mode\">Безпечний режим</string>\n    <string name=\"secure_mode_sub\">Приховує вміст нещодавно використаних програм. Його неможливо записати.</string>\n    <string name=\"mask_color\">Колір маски</string>\n    <string name=\"delete_mask_warn\">Ви збираєтеся видалити вибрану маску фільтра. Цю операцію не можна скасувати</string>\n    <string name=\"delete_mask\">Видалити маску</string>\n    <string name=\"simple_variants\">Прості варіанти</string>\n    <string name=\"highlighter\">Хайлайтер</string>\n    <string name=\"pen\">Перо</string>\n    <string name=\"pen_sub\">За замовчуванням один, найпростіший - тільки колір</string>\n    <string name=\"privacy_blur_sub\">Розмиває зображення під намальованим контуром, щоб захистити все, що ви хочете приховати</string>\n    <string name=\"pixelation_sub\">Подібно до розмиття конфіденційності, але пікселізує замість розмиття</string>\n    <string name=\"auto_rotate_limits\">Автоматичний поворот</string>\n    <string name=\"auto_rotate_limits_sub\">Дозволяє використовувати рамку обмеження для орієнтації зображення</string>\n    <string name=\"highlighter_sub\">Намалюйте напівпрозорі чіткі контури підсвічування</string>\n    <string name=\"containers_shadow\">Контейнери</string>\n    <string name=\"containers_shadow_sub\">Намалюйте тінь за контейнерами</string>\n    <string name=\"sliders_shadow\">Повзунки</string>\n    <string name=\"switches_shadow\">Перемикачі</string>\n    <string name=\"fabs_shadow\">FABs</string>\n    <string name=\"buttons_shadow\">кнопки</string>\n    <string name=\"sliders_shadow_sub\">Намалюйте тінь за повзунками</string>\n    <string name=\"switches_shadow_sub\">Намалюйте тінь за вимикачами</string>\n    <string name=\"fabs_shadow_sub\">Намалюйте тінь за плаваючими кнопками дій</string>\n    <string name=\"buttons_shadow_sub\">Намалюйте тінь за кнопками</string>\n    <string name=\"exit\">Вихід</string>\n    <string name=\"preview_closing\">Якщо ви покинете попередній перегляд зараз, вам потрібно буде знову додати зображення</string>\n    <string name=\"image_format\">Формат зображення</string>\n    <string name=\"material_you_sub\">Створює палітру \\\"Material You\\\" із зображення</string>\n    <string name=\"dark_colors\">Темні кольори</string>\n    <string name=\"dark_colors_sub\">Використовує колірну схему нічного режиму замість світлого варіанту</string>\n    <string name=\"copy_as_compose_code\">Скопіюйте як код \\\"Jetpack Compose\\\"</string>\n    <string name=\"ring_blur\">Розмиття кільця</string>\n    <string name=\"cross_blur\">Перехресне розмиття</string>\n    <string name=\"circle_blur\">Розмиття кола</string>\n    <string name=\"star_blur\">Розмиття зірками</string>\n    <string name=\"linear_tilt_shift\">Лінійний нахил-зсув</string>\n    <string name=\"tags_to_remove\">Ярлики для видалення</string>\n    <string name=\"apng_tools\">Інструменти APNG</string>\n    <string name=\"apng_type_to_image_sub\">Перетворіть файл APNG на пакет зображень</string>\n    <string name=\"motion_blur\">Рух Розмитість</string>\n    <string name=\"apng_type_to_apng\">Зображення в APNG</string>\n    <string name=\"select_apng_image_to_start\">Щоб почати, виберіть зображення APNG</string>\n    <string name=\"apng_type_to_image\">APNG до зображень</string>\n    <string name=\"apng_type_to_apng_sub\">Перетворіть пакет зображень у файл APNG</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Створіть файл Zip із заданих файлів або зображень</string>\n    <string name=\"apng_tools_sub\">Перетворіть зображення на зображення APNG або витягніть кадри з заданого зображення APNG</string>\n    <string name=\"drag_handle_width\">Ширина маркера перетягування</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Перекодування без втрат з JPEG у JXL</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Перекодування без втрат з JXL у JPEG</string>\n    <string name=\"festive\">Святковий</string>\n    <string name=\"sort_by_date_reversed\">Дата (у зворотному порядку)</string>\n    <string name=\"downscale_image_sub\">Перед обробкою зображення буде зменшено до менших розмірів, що допоможе інструменту працювати швидше та безпечніше</string>\n    <string name=\"images_to_svg\">Зображення у SVG</string>\n    <string name=\"detailed\">Детально</string>\n    <string name=\"downscale_image\">Зменшення зображення</string>\n    <string name=\"header_today\">Сьогодні</string>\n    <string name=\"explode\">Вибух</string>\n    <string name=\"gif_type_to_jxl\">GIF у JXL</string>\n    <string name=\"no_permissions\">Без дозволів</string>\n    <string name=\"request\">Запит</string>\n    <string name=\"try_again\">Спробуйте ще раз</string>\n    <string name=\"max\">Максимум</string>\n    <string name=\"pixel_switch\">Піксель</string>\n    <string name=\"cupertino_switch\">Купертіно</string>\n    <string name=\"min_color_ratio\">Мінімальне співвідношення кольорів</string>\n    <string name=\"lines_threshold\">Поріг ліній</string>\n    <string name=\"quadratic_threshold\">Квадратичний поріг</string>\n    <string name=\"reset_properties\">Скинути властивості</string>\n    <string name=\"reset_properties_sub\">Усі властивості будуть встановлені до значень за замовчуванням, зверніть увагу, що цю дію не можна скасувати</string>\n    <string name=\"engine_mode\">Режим двигуна</string>\n    <string name=\"cupertino_switch_sub\">Перемикач, заснований на системі проектування \\\"Купертіно\\\"</string>\n    <string name=\"rain\">Дощ</string>\n    <string name=\"corners\">Кути</string>\n    <string name=\"jxl_tools\">JXL інструменти</string>\n    <string name=\"jxl_type_to_jpeg\">JXL у JPEG</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG у JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG у JXL</string>\n    <string name=\"jxl_type_to_images\">JXL у зображення</string>\n    <string name=\"jxl_type_to_jxl\">Зображення у JXL</string>\n    <string name=\"behavior\">Поведінка</string>\n    <string name=\"sorting\">Сортування</string>\n    <string name=\"sort_by_date\">Дата</string>\n    <string name=\"sort_by_name\">Ім\\'я</string>\n    <string name=\"sort_by_name_reversed\">Ім\\'я (у зворотному порядку)</string>\n    <string name=\"channels_configuration\">Конфігурація каналів</string>\n    <string name=\"header_yesterday\">Вчора</string>\n    <string name=\"confetti_type\">Тип конфетті</string>\n    <string name=\"jxl_tools_sub\">Виконайте перекодування JXL ~ JPEG без втрати якості або конвертуйте анімацію GIF/APNG в JXL</string>\n    <string name=\"select_jxl_image_to_start\">Виберіть зображення JXL для початку</string>\n    <string name=\"fast_gaussian_blur_2d\">Швидке гауссове розмиття 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Швидке гауссове розмиття 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Швидке гауссове розмиття 4D</string>\n    <string name=\"auto_paste\">Великодній автомобіль</string>\n    <string name=\"auto_paste_sub\">Дозволяє програмі автоматично вставляти дані з буфера обміну, щоб вони відображалися на головному екрані, і ви могли їх обробити</string>\n    <string name=\"harmonization_color\">Гармонізація кольору</string>\n    <string name=\"harmonization_level\">Рівень гармонізації</string>\n    <string name=\"lanczos_bessel\">Ланцош Бессель</string>\n    <string name=\"lanczos_bessel_sub\">Метод передискретизації, який підтримує високоякісну інтерполяцію шляхом застосування функції Бесселя (JINC) до значень пікселів</string>\n    <string name=\"gif_type_to_jxl_sub\">Конвертувати зображення GIF в анімовані зображення JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Конвертувати зображення APNG в анімовані зображення JXL</string>\n    <string name=\"jxl_type_to_images_sub\">Конвертувати JXL-анімацію в пакет зображень</string>\n    <string name=\"jxl_type_to_jxl_sub\">Конвертувати пакет зображень в JXL-анімацію</string>\n    <string name=\"skip_file_picking\">Пропустити вибір файлів</string>\n    <string name=\"skip_file_picking_sub\">Вибір файлів буде відображено негайно, якщо це можливо, на вибраному екрані</string>\n    <string name=\"generate_previews\">Згенерувати попередній перегляд</string>\n    <string name=\"generate_previews_sub\">Увімкнення попереднього перегляду, що може допомогти уникнути збоїв на деяких пристроях, а також вимикання деяких функцій редагування в межах одного параметра редагування</string>\n    <string name=\"lossy_compression\">Стиснення з втратами</string>\n    <string name=\"lossy_compression_sub\">Використовує стиснення з втратами для зменшення розміру файлу замість стиснення без втрат</string>\n    <string name=\"compression_type\">Тип стиснення</string>\n    <string name=\"speed_sub\">Контролює швидкість декодування результуючого зображення, це має допомогти швидше відкрити результуюче зображення, значення %1$s означає найповільніше декодування, тоді як %2$s – найшвидше, цей параметр може збільшити розмір вихідного зображення</string>\n    <string name=\"embedded_picker\">Вбудований засіб вибору</string>\n    <string name=\"embedded_picker_sub\">Вибір зображень у Image Toolbox</string>\n    <string name=\"pick_multiple_media\">Виберіть кілька медіа</string>\n    <string name=\"pick_single_media\">Виберіть один медіафайл</string>\n    <string name=\"pick\">Вибрати</string>\n    <string name=\"show_settings_in_landscape\">Показати налаштування в альбомній орієнтації</string>\n    <string name=\"show_settings_in_landscape_sub\">Якщо це вимкнено, то в альбомному режимі налаштування відкриватимуться на кнопці у верхній панелі програми, як завжди, замість постійно видимої опції.</string>\n    <string name=\"fullscreen_settings\">Налаштування повноекранного режиму</string>\n    <string name=\"fullscreen_settings_sub\">Увімкніть цю функцію, і сторінка налаштувань завжди відкриватиметься на весь екран, а не у висувному списку.</string>\n    <string name=\"switch_type\">Тип перемикача</string>\n    <string name=\"compose\">Написати</string>\n    <string name=\"compose_switch_sub\">Матеріал для створення Jetpack. Ви перемикаєтесь.</string>\n    <string name=\"material_you_switch_sub\">Матеріал, який ви перемикаєте</string>\n    <string name=\"resize_anchor\">Змінити розмір якоря</string>\n    <string name=\"fluent_switch\">Вільне володіння</string>\n    <string name=\"fluent_switch_sub\">Перемикач на основі системи проектування \\\"Fluent\\\"</string>\n    <string name=\"images_to_svg_sub\">Трасування заданих зображень до зображень SVG</string>\n    <string name=\"use_sampled_palette\">Використовувати вибіркову палітру</string>\n    <string name=\"use_sampled_palette_sub\">Палітра квантування буде семплуватися, якщо ця опція увімкнена</string>\n    <string name=\"path_omit\">Пропустити шлях</string>\n    <string name=\"svg_warning\">Використання цього інструменту для трасування великих зображень без зменшення масштабу не рекомендується, це може призвести до збою та збільшення часу обробки.</string>\n    <string name=\"coordinates_rounding_tolerance\">Допуск округлення координат</string>\n    <string name=\"path_scale\">Масштаб шляху</string>\n    <string name=\"default_line_width\">Ширина лінії за замовчуванням</string>\n    <string name=\"legacy\">Спадщина</string>\n    <string name=\"lstm_network\">Мережа LSTM</string>\n    <string name=\"legacy_and_lstm\">Застарілі та LSTM</string>\n    <string name=\"convert\">Конвертувати</string>\n    <string name=\"convert_sub\">Конвертувати пакети зображень у заданий формат</string>\n    <string name=\"add_new_folder\">Додати нову папку</string>\n    <string name=\"tag_bits_per_sample\">Бітів на зразок</string>\n    <string name=\"tag_compression\">Стиснення</string>\n    <string name=\"tag_photometric_interpretation\">Фотометрична інтерпретація</string>\n    <string name=\"tag_samples_per_pixel\">Зразків на піксель</string>\n    <string name=\"tag_planar_configuration\">Плоска конфігурація</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr Субсемплінг</string>\n    <string name=\"tag_y_cb_cr_positioning\">Позиціонування Y Cb Cr</string>\n    <string name=\"tag_x_resolution\">Роздільна здатність X</string>\n    <string name=\"tag_y_resolution\">Роздільна здатність Y</string>\n    <string name=\"tag_resolution_unit\">Одиниця роздільної здатності</string>\n    <string name=\"tag_strip_offsets\">Зміщення смуги</string>\n    <string name=\"tag_rows_per_strip\">Рядків на смузі</string>\n    <string name=\"tag_strip_byte_counts\">Кількість байтів смуги</string>\n    <string name=\"tag_jpeg_interchange_format\">Формат обміну JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Довжина формату обміну JPEG</string>\n    <string name=\"tag_transfer_function\">Передаточна функція</string>\n    <string name=\"tag_white_point\">Вайт-Пойнт</string>\n    <string name=\"tag_primary_chromaticities\">Первинні хроматичні якості</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Коефіцієнти Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">Довідка Чорно-білий</string>\n    <string name=\"tag_datetime\">Дата Час</string>\n    <string name=\"tag_image_description\">Опис зображення</string>\n    <string name=\"tag_make\">Зробити</string>\n    <string name=\"tag_model\">Модель</string>\n    <string name=\"tag_software\">Програмне забезпечення</string>\n    <string name=\"tag_artist\">Художник</string>\n    <string name=\"tag_copyright\">Авторське право</string>\n    <string name=\"tag_exif_version\">Версія Exif</string>\n    <string name=\"tag_flashpix_version\">Версія Flashpix</string>\n    <string name=\"tag_color_space\">Колірний простір</string>\n    <string name=\"tag_gamma\">Гамма</string>\n    <string name=\"tag_pixel_x_dimension\">Розмір пікселя X</string>\n    <string name=\"tag_pixel_y_dimension\">Розмір пікселя Y</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Стиснутих бітів на піксель</string>\n    <string name=\"tag_maker_note\">Примітка виробника</string>\n    <string name=\"tag_user_comment\">Коментар користувача</string>\n    <string name=\"tag_related_sound_file\">Пов\\'язаний звуковий файл</string>\n    <string name=\"tag_datetime_original\">Дата Час Оригінал</string>\n    <string name=\"tag_datetime_digitized\">Дата та час оцифровані</string>\n    <string name=\"tag_offset_time\">Час зміщення</string>\n    <string name=\"tag_offset_time_original\">Оригінал часу зсуву</string>\n    <string name=\"tag_offset_time_digitized\">Оцифрований час зсуву</string>\n    <string name=\"tag_subsec_time\">Час у добі</string>\n    <string name=\"tag_subsec_time_original\">Оригінал субсекундного часу</string>\n    <string name=\"tag_subsec_time_digitized\">Оцифрований час субсекундного часу</string>\n    <string name=\"tag_exposure_time\">Час контакту</string>\n    <string name=\"tag_f_number\">Діафрагмове число</string>\n    <string name=\"tag_exposure_program\">Програма експозиції</string>\n    <string name=\"tag_spectral_sensitivity\">Спектральна чутливість</string>\n    <string name=\"tag_photographic_sensitivity\">Фотографічна чутливість</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Тип чутливості</string>\n    <string name=\"tag_standard_output_sensitivity\">Стандартна вихідна чутливість</string>\n    <string name=\"tag_recommended_exposure_index\">Рекомендований індекс експозиції</string>\n    <string name=\"tag_iso_speed\">Чутливість ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Чутливість ISO Широта yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Чутливість ISO Широта zzz</string>\n    <string name=\"tag_shutter_speed_value\">Значення витримки</string>\n    <string name=\"tag_aperture_value\">Значення діафрагми</string>\n    <string name=\"tag_brightness_value\">Значення яскравості</string>\n    <string name=\"tag_exposure_bias_value\">Значення зміщення експозиції</string>\n    <string name=\"tag_max_aperture_value\">Максимальне значення діафрагми</string>\n    <string name=\"tag_subject_distance\">Відстань до об\\'єкта</string>\n    <string name=\"tag_metering_mode\">Режим вимірювання</string>\n    <string name=\"tag_flash\">Спалах</string>\n    <string name=\"tag_subject_area\">Предметна область</string>\n    <string name=\"tag_focal_length\">Фокусна відстань</string>\n    <string name=\"tag_flash_energy\">Енергія спалаху</string>\n    <string name=\"tag_spatial_frequency_response\">Просторова частотна характеристика</string>\n    <string name=\"tag_focal_plane_x_resolution\">Роздільна здатність фокальної площини X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Роздільна здатність фокальної площини Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Блок роздільної здатності фокальної площини</string>\n    <string name=\"tag_subject_location\">Розташування суб\\'єкта</string>\n    <string name=\"tag_exposure_index\">Індекс експозиції</string>\n    <string name=\"tag_sensing_method\">Метод зондування</string>\n    <string name=\"tag_file_source\">Джерело файлу</string>\n    <string name=\"tag_cfa_pattern\">Шаблон CFA</string>\n    <string name=\"tag_custom_rendered\">Налаштований рендеринг</string>\n    <string name=\"tag_exposure_mode\">Режим експозиції</string>\n    <string name=\"tag_white_balance\">Баланс Білого</string>\n    <string name=\"tag_digital_zoom_ratio\">Коефіцієнт цифрового масштабування</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Фокусна відстань на плівці 35 мм</string>\n    <string name=\"tag_scene_capture_type\">Тип захоплення сцени</string>\n    <string name=\"tag_gain_control\">Контроль посилення</string>\n    <string name=\"tag_contrast\">Контраст</string>\n    <string name=\"tag_saturation\">Насиченість</string>\n    <string name=\"tag_sharpness\">Різкістю</string>\n    <string name=\"tag_device_setting_description\">Опис налаштувань пристрою</string>\n    <string name=\"tag_subject_distance_range\">Діапазон відстані до об\\'єкта</string>\n    <string name=\"tag_image_unique_id\">Унікальний ідентифікатор зображення</string>\n    <string name=\"tag_camera_owner_name\">Ім\\'я власника камери</string>\n    <string name=\"tag_body_serial_number\">Серійний номер кузова</string>\n    <string name=\"tag_lens_specification\">Специфікація об\\'єктива</string>\n    <string name=\"tag_lens_make\">Виробник об\\'єктива</string>\n    <string name=\"tag_lens_model\">Модель об\\'єктива</string>\n    <string name=\"tag_lens_serial_number\">Серійний номер об\\'єктива</string>\n    <string name=\"tag_gps_version_id\">Ідентифікатор версії GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Довідка широти GPS</string>\n    <string name=\"tag_gps_latitude\">GPS-широта</string>\n    <string name=\"tag_gps_longitude_ref\">Довідка довготи GPS</string>\n    <string name=\"tag_gps_longitude\">Довгота за GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Висота за GPS</string>\n    <string name=\"tag_gps_altitude\">Висота За GPS</string>\n    <string name=\"tag_gps_timestamp\">Мітка часу GPS</string>\n    <string name=\"tag_gps_satellites\">GPS-супутники</string>\n    <string name=\"tag_gps_status\">Стан GPS</string>\n    <string name=\"tag_gps_measure_mode\">Режим вимірювання GPS</string>\n    <string name=\"tag_gps_dop\">GPS DOP</string>\n    <string name=\"tag_gps_speed_ref\">Довідка швидкості GPS</string>\n    <string name=\"tag_gps_speed\">Швидкість GPS</string>\n    <string name=\"tag_gps_track_ref\">Довідка GPS-треку</string>\n    <string name=\"tag_gps_track\">GPS-треки</string>\n    <string name=\"tag_gps_img_direction_ref\">Довідка напрямку зображення GPS</string>\n    <string name=\"tag_gps_img_direction\">Напрямок зображення GPS</string>\n    <string name=\"tag_gps_map_datum\">Дата GPS-карта</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Довідкова широта пункту призначення GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Широта пункту призначення GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Довідкова довгота пункту призначення GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Довгота пункту призначення GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS-референтний пеленг</string>\n    <string name=\"tag_gps_dest_bearing\">Пеленг пункту призначення GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Відстань до пункту призначення GPS</string>\n    <string name=\"tag_gps_dest_distance\">Відстань до Пункту призначення GPS</string>\n    <string name=\"tag_gps_processing_method\">Метод обробки GPS</string>\n    <string name=\"tag_gps_area_information\">Інформація про GPS-локацію</string>\n    <string name=\"tag_gps_datestamp\">Штамп Дата GPS</string>\n    <string name=\"tag_gps_differential\">Диференціал GPS</string>\n    <string name=\"tag_gps_h_positioning_error\">Помилка горизонтального позиціонування GPS</string>\n    <string name=\"tag_interoperability_index\">Індекс сумісності</string>\n    <string name=\"tag_dng_version\">Версія DNG</string>\n    <string name=\"tag_default_crop_size\">Розмір кадрування за замовчуванням</string>\n    <string name=\"tag_orf_preview_image_start\">Початок попереднього перегляду зображення</string>\n    <string name=\"tag_orf_preview_image_length\">Довжина зображення попереднього перегляду</string>\n    <string name=\"tag_orf_aspect_frame\">Рамка співвідношення сторін</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Нижня межа датчика</string>\n    <string name=\"tag_rw2_sensor_left_border\">Ліва межа датчика</string>\n    <string name=\"tag_rw2_sensor_right_border\">Права межа датчика</string>\n    <string name=\"tag_rw2_sensor_top_border\">Верхня межа датчика</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Намалюйте текст на шляху заданим шрифтом і кольором</string>\n    <string name=\"font_size\">Розмір шрифту</string>\n    <string name=\"watermark_size\">Розмір водяного знака</string>\n    <string name=\"repeat_text\">Повторити текст</string>\n    <string name=\"repeat_text_sub\">Поточний текст буде повторюватися до кінця контуру, замість одноразового малювання</string>\n    <string name=\"dash_size\">Розмір тире</string>\n    <string name=\"draw_mode_image_sub\">Використати вибране зображення, щоб намалювати його вздовж заданого шляху</string>\n    <string name=\"draw_image_sub\">Це зображення буде використано як повторюваний запис намальованого шляху</string>\n    <string name=\"outlined_triangle_sub\">Малює контурний трикутник від початкової точки до кінцевої точки</string>\n    <string name=\"triangle_sub\">Малює контурний трикутник від початкової точки до кінцевої точки</string>\n    <string name=\"outlined_triangle\">Окреслений трикутник</string>\n    <string name=\"triangle\">Трикутник</string>\n    <string name=\"polygon_sub\">Малює багатокутник від початкової точки до кінцевої точки</string>\n    <string name=\"polygon\">Багатокутник</string>\n    <string name=\"outlined_polygon\">Окреслений багатокутник</string>\n    <string name=\"outlined_polygon_sub\">Малює окреслений полігон від початкової до кінцевої точки</string>\n    <string name=\"vertices\">Вершини</string>\n    <string name=\"draw_regular_polygon\">Намалюйте правильний багатокутник</string>\n    <string name=\"draw_regular_polygon_sub\">Намалюйте багатокутник, який буде правильної, а не вільної форми</string>\n    <string name=\"star_sub\">Малює зірку від початкової точки до кінцевої точки</string>\n    <string name=\"star\">Зірка</string>\n    <string name=\"outlined_star\">Зірка з контурами</string>\n    <string name=\"outlined_star_sub\">Малює контурну зірку від початкової до кінцевої точки</string>\n    <string name=\"inner_radius_ratio\">Співвідношення внутрішнього радіуса</string>\n    <string name=\"draw_regular_star\">Намалюйте звичайну зірку</string>\n    <string name=\"draw_regular_star_sub\">Намалюйте зірку правильної, а не вільної форми</string>\n    <string name=\"antialias\">Згладжування</string>\n    <string name=\"antialias_sub\">Увімкнення згладжування для запобігання різким краям</string>\n    <string name=\"open_edit_instead_of_preview\">Відкрити редагування замість попереднього перегляду</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Коли ви вибираєте зображення для відкриття (попереднього перегляду) в ImageToolbox, замість попереднього перегляду відкриється аркуш редагування вибору.</string>\n    <string name=\"document_scanner\">Сканер документів</string>\n    <string name=\"document_scanner_sub\">Скануйте документи та створюйте PDF-файли або окремі зображення з них</string>\n    <string name=\"click_to_start_scanning\">Натисніть, щоб розпочати сканування</string>\n    <string name=\"start_scanning\">Розпочати сканування</string>\n    <string name=\"save_as_pdf\">Зберегти як PDF</string>\n    <string name=\"share_as_pdf\">Поділитися як PDF</string>\n    <string name=\"options_below_is_for_images\">Наведені нижче опції призначені для збереження зображень, а не PDF-файлів.</string>\n    <string name=\"equalize_histogram_hsv\">Зрівняти гістограму HSV</string>\n    <string name=\"equalize_histogram\">Вирівняти гістограму</string>\n    <string name=\"enter_percentage\">Введіть відсоток</string>\n    <string name=\"allow_enter_by_text_field\">Дозволити введення за допомогою текстового поля</string>\n    <string name=\"allow_enter_by_text_field_sub\">Вмикає текстове поле за вибором пресетів, щоб вводити їх на льоту</string>\n    <string name=\"scale_color_space\">Шкала колірного простору</string>\n    <string name=\"linear\">Лінійний</string>\n    <string name=\"equalize_histogram_pixelation\">Вирівняти пікселізацію гістограми</string>\n    <string name=\"grid_size_x\">Розмір сітки X</string>\n    <string name=\"grid_size_y\">Розмір сітки Y</string>\n    <string name=\"equalize_histogram_adaptive\">Адаптивне вирівнювання гістограми</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Вирівнювання гістограми Адаптивна LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Адаптивний LAB для вирівнювання гістограми</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"crop_to_content\">Обрізати до вмісту</string>\n    <string name=\"frame_color\">Колір рамки</string>\n    <string name=\"color_to_ignore\">Колір, який потрібно ігнорувати</string>\n    <string name=\"template\">Шаблон</string>\n    <string name=\"no_template_filters\">Не додано фільтрів шаблонів</string>\n    <string name=\"create_new\">Створити нове</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Відсканований QR-код не є дійсним шаблоном фільтра</string>\n    <string name=\"scan_qr_code\">Відскануйте QR-код</string>\n    <string name=\"opened_file_have_no_filter_template\">Вибраний файл не містить даних шаблону фільтра</string>\n    <string name=\"create_template\">Створити шаблон</string>\n    <string name=\"template_name\">Назва шаблону</string>\n    <string name=\"select_template_preview\">Це зображення буде використано для попереднього перегляду цього шаблону фільтра</string>\n    <string name=\"template_filter\">Фільтр шаблонів</string>\n    <string name=\"as_qr_code\">Як зображення QR-коду</string>\n    <string name=\"as_file\">Як файл</string>\n    <string name=\"save_as_file\">Зберегти як файл</string>\n    <string name=\"save_as_qr_code_image\">Зберегти як зображення з QR-кодом</string>\n    <string name=\"delete_template\">Видалити шаблон</string>\n    <string name=\"delete_template_warn\">Ви збираєтеся видалити вибраний фільтр шаблону. Цю операцію не можна скасувати.</string>\n    <string name=\"added_filter_template\">Додано шаблон фільтра з назвою \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Попередній перегляд фільтра</string>\n    <string name=\"qr_code\">QR-код та штрих-код</string>\n    <string name=\"qr_code_sub\">Відскануйте QR-код та отримайте його вміст або вставте свій рядок, щоб створити новий</string>\n    <string name=\"code_content\">Вміст коду</string>\n    <string name=\"scan_qr_code_to_replace_content\">Відскануйте будь-який штрих-код, щоб замінити вміст у полі, або введіть щось, щоб створити новий штрих-код із вибраним типом</string>\n    <string name=\"qr_description\">Опис QR-коду</string>\n    <string name=\"min\">Хв</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Надайте камері дозвіл у налаштуваннях для сканування QR-коду</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Надайте камері дозвіл у налаштуваннях для сканування Сканера документів</string>\n    <string name=\"cubic\">Кубічний</string>\n    <string name=\"bspline\">B-сплайн</string>\n    <string name=\"hamming\">Хеммінг</string>\n    <string name=\"hanning\">Ганнінг</string>\n    <string name=\"blackman\">Блекмен</string>\n    <string name=\"welch\">Уелч</string>\n    <string name=\"quadric\">Квадрик</string>\n    <string name=\"gaussian\">Гаусівський</string>\n    <string name=\"sphinx\">Сфінкс</string>\n    <string name=\"bartlett\">Бартлетт</string>\n    <string name=\"robidoux\">Робіду</string>\n    <string name=\"robidoux_sharp\">Робіду Шарп</string>\n    <string name=\"spline16\">Сплайн 16</string>\n    <string name=\"spline36\">Сплайн 36</string>\n    <string name=\"spline64\">Сплайн 64</string>\n    <string name=\"kaiser\">Кайзер</string>\n    <string name=\"bartlett_hann\">Бартлетт-Ганн</string>\n    <string name=\"box\">Коробка</string>\n    <string name=\"bohman\">Бохман</string>\n    <string name=\"lanczos2\">Ланцош 2</string>\n    <string name=\"lanczos3\">Ланцош 3</string>\n    <string name=\"lanczos4\">Ланцош 4</string>\n    <string name=\"lanczos2_jinc\">Ланцош 2 Їнц</string>\n    <string name=\"lanczos3_jinc\">Ланцош 3 Їнц</string>\n    <string name=\"lanczos4_jinc\">Ланцош 4 Їнц</string>\n    <string name=\"cubic_sub\">Кубічна інтерполяція забезпечує плавніше масштабування, враховуючи найближчі 16 пікселів, даючи кращі результати, ніж білінійна</string>\n    <string name=\"bspline_sub\">Використовує кусково-визначені поліноміальні функції для плавної інтерполяції та апроксимації кривої або поверхні, гнучке та безперервне представлення форми</string>\n    <string name=\"hamming_sub\">Віконна функція, що використовується для зменшення спектрального витоку шляхом звуження країв сигналу, корисна при обробці сигналів.</string>\n    <string name=\"hanning_sub\">Варіант вікна Ханна, який зазвичай використовується для зменшення спектрального витоку в програмах обробки сигналів.</string>\n    <string name=\"blackman_sub\">Віконна функція, яка забезпечує хорошу роздільну здатність по частоті, мінімізуючи спектральний витік, часто використовується в обробці сигналів</string>\n    <string name=\"welch_sub\">Віконна функція, розроблена для забезпечення гарної роздільної здатності по частоті зі зменшеним спектральним витоком, часто використовується в програмах обробки сигналів.</string>\n    <string name=\"quadric_sub\">Метод, який використовує квадратичну функцію для інтерполяції, забезпечуючи плавні та безперервні результати</string>\n    <string name=\"gaussian_sub\">Метод інтерполяції, який застосовує функцію Гауса, корисний для згладжування та зменшення шуму на зображеннях</string>\n    <string name=\"sphinx_sub\">Удосконалений метод передискретизації, що забезпечує високоякісну інтерполяцію з мінімальними артефактами</string>\n    <string name=\"bartlett_sub\">Трикутна віконна функція, що використовується в обробці сигналів для зменшення спектрального витоку</string>\n    <string name=\"robidoux_sub\">Високоякісний метод інтерполяції, оптимізований для природного зміни розміру зображення, балансування різкості та плавності</string>\n    <string name=\"robidoux_sharp_sub\">Чіткіший варіант методу Робіду, оптимізований для чіткого зміни розміру зображення</string>\n    <string name=\"spline16_sub\">Метод інтерполяції на основі сплайнів, який забезпечує плавні результати з використанням 16-канального фільтра</string>\n    <string name=\"spline36_sub\">Метод інтерполяції на основі сплайнів, який забезпечує плавні результати з використанням 36-канального фільтра</string>\n    <string name=\"spline64_sub\">Метод інтерполяції на основі сплайнів, який забезпечує плавні результати з використанням 64-відбивного фільтра</string>\n    <string name=\"kaiser_sub\">Метод інтерполяції, що використовує вікно Кайзера, що забезпечує хороший контроль над компромісом між шириною головної пелюстки та рівнем бічних пелюсток.</string>\n    <string name=\"bartlett_hann_sub\">Гібридна віконна функція, що поєднує вікна Бартлетта та Ханна, що використовується для зменшення спектрального витоку під час обробки сигналів</string>\n    <string name=\"box_sub\">Простий метод передискретизації, який використовує середнє значення найближчих пікселів, що часто призводить до блокового вигляду</string>\n    <string name=\"bohman_sub\">Віконна функція, що використовується для зменшення спектрального витоку, що забезпечує хорошу роздільну здатність по частоті в програмах обробки сигналів</string>\n    <string name=\"lanczos2_sub\">Метод передискретизації, який використовує 2-пелюстковий фільтр Ланцоша для високоякісної інтерполяції з мінімальними артефактами</string>\n    <string name=\"lanczos3_sub\">Метод передискретизації, який використовує 3-пелюстковий фільтр Ланцоша для високоякісної інтерполяції з мінімальними артефактами</string>\n    <string name=\"lanczos4_sub\">Метод передискретизації, який використовує 4-пелюстковий фільтр Ланцоша для високоякісної інтерполяції з мінімальними артефактами</string>\n    <string name=\"lanczos2_jinc_sub\">Варіант фільтра Ланцоша 2, який використовує функцію jinc, забезпечуючи високоякісну інтерполяцію з мінімальними артефактами</string>\n    <string name=\"lanczos3_jinc_sub\">Варіант фільтра Ланцоша 3, який використовує функцію jinc, забезпечуючи високоякісну інтерполяцію з мінімальними артефактами</string>\n    <string name=\"lanczos4_jinc_sub\">Варіант фільтра Ланцоша 4, який використовує функцію jinc, забезпечуючи високоякісну інтерполяцію з мінімальними артефактами</string>\n    <string name=\"ewa_hanning\">Ханнінг ЕВА</string>\n    <string name=\"ewa_hanning_sub\">Варіант фільтра Ханнінга з еліптично зваженим середнім (EWA) для плавної інтерполяції та повторної дискретизації</string>\n    <string name=\"ewa_robidoux\">Робіду EWA</string>\n    <string name=\"ewa_robidoux_sub\">Варіант фільтра Робіду з еліптично зваженим середнім (EWA) для високоякісної передискретизації</string>\n    <string name=\"ewa_blackman\">Блекман, EWA</string>\n    <string name=\"ewa_blackman_sub\">Варіант фільтра Блекмана з еліптично зваженим середнім (EWA) для мінімізації артефактів дзвінка</string>\n    <string name=\"ewa_quadric\">Квадрик EWA</string>\n    <string name=\"ewa_quadric_sub\">Варіант еліптично зваженого середнього (EWA) квадричного фільтра для плавної інтерполяції</string>\n    <string name=\"ewa_robidoux_sharp\">Робіду Шарп EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Варіант фільтра Robidoux Sharp з еліптично зваженим середнім (EWA) для чіткіших результатів</string>\n    <string name=\"ewa_lanczos3_jinc\">Ланцош 3 Їнц EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Варіант фільтра Lanczos 3 Jinc з еліптично зваженим усередненням (EWA) для високоякісної передискретизації зі зменшеним аліасингом</string>\n    <string name=\"ginseng\">Женьшень</string>\n    <string name=\"ginseng_sub\">Фільтр передискретизації, розроблений для високоякісної обробки зображень з хорошим балансом різкості та плавності</string>\n    <string name=\"ewa_ginseng\">Женьшень EWA</string>\n    <string name=\"ewa_ginseng_sub\">Варіант фільтра женьшеню з еліптично зваженим усередненням (EWA) для покращеної якості зображення</string>\n    <string name=\"ewa_lanczos_sharp\">Ланцош Шарп EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Варіант фільтра Ланцоша Шарпа з еліптично зваженим середнім (EWA) для досягнення чітких результатів з мінімальними артефактами</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Ланцош 4 Sharpest EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Варіант еліптично зваженого середнього (EWA) фільтра Lanczos 4 Sharpest для надзвичайно чіткої передискретизації зображення</string>\n    <string name=\"ewa_lanczos_soft\">Ланцош М\\'який EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Варіант еліптично зваженого середнього (EWA) фільтра Lanczos Soft для плавнішої передискретизації зображення</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Фільтр передискретизації, розроблений Haasn, для плавного масштабування зображення без артефактів</string>\n    <string name=\"format_conversion\">Конвертація формату</string>\n    <string name=\"format_conversion_sub\">Конвертувати пакет зображень з одного формату в інший</string>\n    <string name=\"dismiss_forever\">Закрити назавжди</string>\n    <string name=\"image_stacking\">Стекування зображень</string>\n    <string name=\"image_stacking_sub\">Накладайте зображення одне на одне за допомогою вибраних режимів накладання</string>\n    <string name=\"add_image\">Додати зображення</string>\n    <string name=\"bins_count\">Кількість контейнерів</string>\n    <string name=\"clahe_hsl\">Клахе HSL</string>\n    <string name=\"clahe_hsv\">Клахе HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Вирівнювання гістограми Адаптивний HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Вирівнювання гістограми Адаптивний HSV</string>\n    <string name=\"edge_mode\">Режим краю</string>\n    <string name=\"clip\">Кліп</string>\n    <string name=\"wrap\">Обгортка</string>\n    <string name=\"color_blind_scheme\">Колір Дальтонізм</string>\n    <string name=\"color_blind_scheme_sub\">Виберіть режим для адаптації кольорів теми до вибраного варіанту дальтонізму</string>\n    <string name=\"protanomaly_sub\">Складність розрізнення червоних і зелених відтінків</string>\n    <string name=\"deuteranomaly_sub\">Складність розрізнення зелених і червоних відтінків</string>\n    <string name=\"tritanomaly_sub\">Складність розрізнення синього та жовтого відтінків</string>\n    <string name=\"protanopia_sub\">Нездатність сприймати червоні відтінки</string>\n    <string name=\"deuteranopia_sub\">Нездатність сприймати зелені відтінки</string>\n    <string name=\"tritanopia_sub\">Нездатність сприймати відтінки синього</string>\n    <string name=\"achromatomaly_sub\">Знижена чутливість до всіх кольорів</string>\n    <string name=\"achromatopsia_sub\">Повна дальтонізм, бачення лише відтінків сірого</string>\n    <string name=\"not_use_color_blind_scheme\">Не використовуйте схему для дальтоніків</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Кольори будуть точно такими, як встановлено в темі</string>\n    <string name=\"sigmoidal\">Сигмоїдальний</string>\n    <string name=\"lagrange_2\">Лагранж 2</string>\n    <string name=\"lagrange_2_sub\">Інтерполяційний фільтр Лагранжа 2-го порядку, придатний для високоякісного масштабування зображень з плавними переходами</string>\n    <string name=\"lagrange_3\">Лагранж 3</string>\n    <string name=\"lagrange_3_sub\">Інтерполяційний фільтр Лагранжа третього порядку, що забезпечує кращу точність та плавніші результати масштабування зображення</string>\n    <string name=\"lanczos_6\">Ланцош 6</string>\n    <string name=\"lanczos_6_sub\">Фільтр передискретизації Ланцоша вищого порядку 6, що забезпечує чіткіше та точніше масштабування зображення</string>\n    <string name=\"lanczos_6_jinc\">Ланцош 6 Їнц</string>\n    <string name=\"lanczos_6_jinc_sub\">Варіант фільтра Ланцоша 6, що використовує функцію Jinc для покращення якості передискретизації зображення</string>\n    <string name=\"linear_box_blur\">Лінійне розмиття рамки</string>\n    <string name=\"linear_tent_blur\">Лінійне розмиття намету</string>\n    <string name=\"linear_gaussian_box_blur\">Лінійне гауссове розмиття рамки</string>\n    <string name=\"linear_stack_blur\">Лінійне розмиття стеку</string>\n    <string name=\"gaussian_box_blur\">Гаусове розмиття рамки</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Лінійне швидке гауссове розмиття Далі</string>\n    <string name=\"linear_fast_gaussian_blur\">Лінійне швидке гаусове розмиття</string>\n    <string name=\"linear_gaussian_blur\">Лінійне гаусове розмиття</string>\n    <string name=\"draw_filter_sub\">Виберіть один фільтр, щоб використовувати його як фарбу</string>\n    <string name=\"replace_filter\">Замінити фільтр</string>\n    <string name=\"pick_filter_info\">Виберіть фільтр нижче, щоб використовувати його як пензель у своєму малюнку</string>\n    <string name=\"tiff_compression_scheme\">Схема стиснення TIFF</string>\n    <string name=\"low_poly\">Низький полігональний</string>\n    <string name=\"sand_painting\">Малювання на піску</string>\n    <string name=\"image_splitting\">Розділення зображення</string>\n    <string name=\"image_splitting_sub\">Розділити одне зображення за рядками або стовпцями</string>\n    <string name=\"fit_to_bounds\">Пристосувати до меж</string>\n    <string name=\"fit_to_bounds_sub\">Поєднайте режим зміни розміру кадрування з цим параметром, щоб досягти бажаної поведінки (Кадрування/Припасування до співвідношення сторін)</string>\n    <string name=\"languages_imported\">Мови успішно імпортовано</string>\n    <string name=\"backup_ocr_models\">Резервні копії моделей OCR</string>\n    <string name=\"import_word\">Імпорт</string>\n    <string name=\"export\">Експорт</string>\n    <string name=\"position\">Позиція</string>\n    <string name=\"center\">Центр</string>\n    <string name=\"top_left\">Зверху ліворуч</string>\n    <string name=\"top_right\">Угорі праворуч</string>\n    <string name=\"bottom_left\">Внизу ліворуч</string>\n    <string name=\"bottom_right\">Внизу праворуч</string>\n    <string name=\"top_center\">Верхній центр</string>\n    <string name=\"center_right\">Центр праворуч</string>\n    <string name=\"bottom_center\">Нижній центр</string>\n    <string name=\"center_left\">Центр лівий</string>\n    <string name=\"target_image\">Цільове зображення</string>\n    <string name=\"palette_transfer\">Перенесення палітри</string>\n    <string name=\"enhanced_oil\">Покращена олія</string>\n    <string name=\"simple_old_tv\">Простий старий телевізор</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Готем</string>\n    <string name=\"simple_sketch\">Простий ескіз</string>\n    <string name=\"soft_glow\">М\\'яке сяйво</string>\n    <string name=\"color_poster\">Кольоровий плакат</string>\n    <string name=\"tri_tone\">Тритон</string>\n    <string name=\"third_color\">Третій колір</string>\n    <string name=\"clahe_oklab\">Клей Оклаб</string>\n    <string name=\"clahe_oklch\">Клахе Оклч</string>\n    <string name=\"clahe_jzazbz\">Клахе Джзазбз</string>\n    <string name=\"polka_dot\">Горошок</string>\n    <string name=\"clustered_2x2_dithering\">Кластерне 2x2 згладжування</string>\n    <string name=\"clustered_4x4_dithering\">Кластерне 4x4 згладжування</string>\n    <string name=\"clustered_8x8_dithering\">Кластерне згладжування 8x8</string>\n    <string name=\"yililoma_dithering\">Згладжування Їліломи</string>\n    <string name=\"no_favorite_options_selected\">Не вибрано жодних улюблених опцій, додайте їх на сторінці інструментів</string>\n    <string name=\"add_favorites\">Додати до обраного</string>\n    <string name=\"harmony_complementary\">Доповнюючий</string>\n    <string name=\"harmony_analogous\">Аналогічний</string>\n    <string name=\"harmony_triadic\">Тріадний</string>\n    <string name=\"harmony_split_complementary\">Розділений додатковий</string>\n    <string name=\"harmony_tetradic\">Тетрадичний</string>\n    <string name=\"harmony_square\">Квадрат</string>\n    <string name=\"harmony_analogous_complementary\">Аналогічний + Доповнювальний</string>\n    <string name=\"color_tools\">Інструменти для роботи з кольором</string>\n    <string name=\"color_tools_sub\">Змішуйте, створюйте тони, генеруйте відтінки та багато іншого</string>\n    <string name=\"color_harmonies\">Колірні гармонії</string>\n    <string name=\"color_shading\">Затінення кольорів</string>\n    <string name=\"variation\">Варіація</string>\n    <string name=\"tints\">Відтінки</string>\n    <string name=\"tones\">Тони</string>\n    <string name=\"shades\">Відтінки\\'</string>\n    <string name=\"color_mixing\">Змішування кольорів</string>\n    <string name=\"color_info\">Інформація про колір</string>\n    <string name=\"selected_color\">Вибраний колір</string>\n    <string name=\"color_to_mix\">Колір для змішування</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Неможливо використовувати Monet, коли ввімкнено динамічні кольори</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Цільове зображення LUT</string>\n    <string name=\"amatorka\">Аматорка</string>\n    <string name=\"miss_etikate\">Міс Етікейт</string>\n    <string name=\"soft_elegance\">М\\'яка елегантність</string>\n    <string name=\"soft_elegance_variant\">Варіант м’якої елегантності</string>\n    <string name=\"palette_transfer_variant\">Варіант перенесення палітри</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">Цільовий 3D LUT-файл (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Обхід відбілювача</string>\n    <string name=\"candlelight\">Світло свічок</string>\n    <string name=\"drop_blues\">Падіння блюзу</string>\n    <string name=\"edgy_amber\">Зухвалий бурштин</string>\n    <string name=\"fall_colors\">Осінні кольори</string>\n    <string name=\"film_stock_50\">Плівка 50</string>\n    <string name=\"foggy_night\">Туманна ніч</string>\n    <string name=\"kodak\">Кодак</string>\n    <string name=\"save_empty_lut\">Отримати нейтральне зображення LUT</string>\n    <string name=\"save_empty_lut_sub\">Спочатку скористайтеся своїм улюбленим застосунком для редагування фотографій, щоб застосувати фільтр до нейтральної LUT-таблиці, який можна завантажити тут. Щоб це працювало належним чином, колір кожного пікселя не повинен залежати від інших пікселів (наприклад, розмиття не працюватиме). Після того, як ви будете готові, використовуйте нове зображення LUT як вхідні дані для фільтра LUT 512*512.</string>\n    <string name=\"pop_art\">Поп-арт</string>\n    <string name=\"celluloid\">Целулоїд</string>\n    <string name=\"coffee\">Кава</string>\n    <string name=\"golden_forest\">Золотий ліс</string>\n    <string name=\"greenish\">Зеленуватий</string>\n    <string name=\"retro_yellow\">Ретро жовтий</string>\n    <string name=\"links_preview\">Попередній перегляд посилань</string>\n    <string name=\"links_preview_sub\">Дозволяє переглядати посилання в місцях, де можна отримати текст (QR-код, OCR тощо)</string>\n    <string name=\"links\">Посилання</string>\n    <string name=\"ico_size_warning\">Файли ICO можна зберігати лише з максимальним розміром 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF у WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Конвертувати зображення GIF в анімовані зображення WEBP</string>\n    <string name=\"webp_tools\">Інструменти WEBP</string>\n    <string name=\"webp_tools_sub\">Конвертувати зображення в анімовану картинку WEBP або витягувати кадри з заданої анімації WEBP</string>\n    <string name=\"webp_type_to_image\">WEBP до зображень</string>\n    <string name=\"webp_type_to_image_sub\">Конвертувати файл WEBP у пакет зображень</string>\n    <string name=\"webp_type_to_webp_sub\">Конвертувати пакет зображень у файл WEBP</string>\n    <string name=\"webp_type_to_webp\">Зображення до WEBP</string>\n    <string name=\"select_webp_image_to_start\">Виберіть зображення WEBP для початку</string>\n    <string name=\"manage_storage_extra_types\">Немає повного доступу до файлів</string>\n    <string name=\"manage_storage_extra_types_sub\">Надайте доступ до всіх файлів, щоб переглядати JXL, QOI та інші зображення, які не розпізнаються як зображення на Android. Без дозволу Image Toolbox не зможе показати ці зображення.</string>\n    <string name=\"default_draw_color\">Колір малювання за замовчуванням</string>\n    <string name=\"default_draw_path_mode\">Режим малювання контуру за замовчуванням</string>\n    <string name=\"add_timestamp\">Додати позначку часу</string>\n    <string name=\"add_timestamp_sub\">Дозволяє додавати позначку часу до імені вихідного файлу</string>\n    <string name=\"formatted_timestamp\">Відформатована позначка часу</string>\n    <string name=\"formatted_timestamp_sub\">Увімкнути форматування позначки часу в назві вихідного файлу замість базового мілісику</string>\n    <string name=\"enable_timestamps_to_format_them\">Увімкнути формат позначок часу</string>\n    <string name=\"one_time_save_location\">Одноразове збереження місця розташування</string>\n    <string name=\"one_time_save_location_sub\">Переглядайте та редагуйте місця збереження для одного разу, які можна використовувати, довго натискаючи кнопку збереження майже у всіх опціях</string>\n    <string name=\"recently_used\">Нещодавно використані</string>\n    <string name=\"ci_channel\">Канал CI</string>\n    <string name=\"group\">Група</string>\n    <string name=\"image_toolbox_in_telegram\">Інструменти для роботи з зображеннями в Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Приєднуйтесь до нашого чату, де ви можете обговорити все, що забажаєте, а також загляньте в канал CI, де я публікую бета-версії та анонси.</string>\n    <string name=\"ci_channel_sub\">Отримуйте сповіщення про нові версії програми та читайте оголошення</string>\n    <string name=\"fit_description\">Підігнати зображення до заданих розмірів та застосувати розмиття або колір до фону</string>\n    <string name=\"tools_arrangement\">Розташування інструментів</string>\n    <string name=\"group_tools_by_type\">Групувати інструменти за типом</string>\n    <string name=\"group_tools_by_type_sub\">Групує інструменти на головному екрані за типом, а не за власним списком</string>\n    <string name=\"default_values\">Значення За замовчуванням</string>\n    <string name=\"system_bars_visibility\">Видимість системних панелей</string>\n    <string name=\"show_system_bars_by_swipe\">Відображати системні панелі за допомогою свайпу</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Дозволяє проводити пальцем, щоб показати системні панелі, якщо вони приховані</string>\n    <string name=\"auto\">Авто</string>\n    <string name=\"hide_all\">Приховати все</string>\n    <string name=\"show_all\">Показати все</string>\n    <string name=\"hide_nav_bar\">Приховати панель навігації</string>\n    <string name=\"hide_status_bar\">Приховати рядок стану</string>\n    <string name=\"noise_generation\">Генерація шуму</string>\n    <string name=\"noise_generation_sub\">Генеруйте різні шуми, такі як Перлін або інші типи</string>\n    <string name=\"frequency\">Частота</string>\n    <string name=\"noise_type\">Тип шуму</string>\n    <string name=\"rotation_type\">Тип обертання</string>\n    <string name=\"fractal_type\">Фрактальний тип</string>\n    <string name=\"octaves\">Октав</string>\n    <string name=\"lacunarity\">Лакунарність</string>\n    <string name=\"gain\">Посилення</string>\n    <string name=\"weighted_strength\">Зважена сила</string>\n    <string name=\"ping_pong_strength\">Сила в пінг-понгу</string>\n    <string name=\"distance_function\">Функція відстані</string>\n    <string name=\"return_type\">Тип повернення</string>\n    <string name=\"jitter\">Тремтіння</string>\n    <string name=\"domain_warp\">Деформація домену</string>\n    <string name=\"alignment\">Вирівнювання</string>\n    <string name=\"custom_filename\">Користувацьке ім\\'я файлу</string>\n    <string name=\"custom_filename_sub\">Виберіть місцезнаходження та ім\\'я файлу, які будуть використані для збереження поточного зображення</string>\n    <string name=\"saved_to_custom\">Збережено в папку з власною назвою</string>\n    <string name=\"collage_maker\">Конструктор колажів</string>\n    <string name=\"collage_maker_sub\">Створюйте колажі з максимум 20 зображень</string>\n    <string name=\"collage_type\">Тип колажу</string>\n    <string name=\"collages_info\">Утримуйте зображення для переміщення, переміщення та масштабування для налаштування положення</string>\n    <string name=\"histogram\">Гістограма</string>\n    <string name=\"histogram_sub\">Гістограма зображення RGB або яскравості, яка допоможе вам внести корективи</string>\n    <string name=\"image_for_histogram\">Це зображення буде використано для створення гістограм RGB та яскравості.</string>\n    <string name=\"tesseract_options\">Параметри Тессеракту</string>\n    <string name=\"tesseract_options_sub\">Застосуйте деякі вхідні змінні для двигуна Tesseract</string>\n    <string name=\"custom_options\">Налаштовані параметри</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">Параметри слід вводити за такою схемою: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Автоматичне обрізання</string>\n    <string name=\"free_corners\">Безкоштовні кути</string>\n    <string name=\"free_corners_sub\">Обрізати зображення за полігоном, це також виправляє перспективу</string>\n    <string name=\"coerce_points_to_image_bounds\">Приведення точок до меж зображення</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Точки не будуть обмежені межами зображення, що корисно для точнішої корекції перспективи.</string>\n    <string name=\"mask\">Маска</string>\n    <string name=\"spot_heal_sub\">Заповнення під намальованим контуром з урахуванням вмісту</string>\n    <string name=\"spot_heal\">Місце зцілення</string>\n    <string name=\"use_circle_kernel\">Використовуйте ядро Circle</string>\n    <string name=\"opening\">Відкриття</string>\n    <string name=\"closing\">Закриття</string>\n    <string name=\"morphological_gradient\">Морфологічний градієнт</string>\n    <string name=\"top_hat\">Циліндр</string>\n    <string name=\"black_hat\">Чорний капелюх</string>\n    <string name=\"tone_curves\">Тонові криві</string>\n    <string name=\"reset_curves\">Скинути криві</string>\n    <string name=\"reset_curves_sub\">Криві будуть повернуті до значень за замовчуванням</string>\n    <string name=\"line_style\">Стиль лінії</string>\n    <string name=\"gap_size\">Розмір зазору</string>\n    <string name=\"dashed\">Пунктирна</string>\n    <string name=\"dot_dashed\">Крапка-штрих</string>\n    <string name=\"stamped\">Штампований</string>\n    <string name=\"zigzag\">Зигзаг</string>\n    <string name=\"dashed_sub\">Малює пунктирну лінію вздовж намальованого шляху із заданим розміром проміжку</string>\n    <string name=\"dot_dashed_sub\">Малює крапку та пунктирну лінію вздовж заданого шляху</string>\n    <string name=\"defaultt_sub\">Просто прямі лінії за замовчуванням</string>\n    <string name=\"stamped_sub\">Малює вибрані фігури вздовж контуру із заданим інтервалом</string>\n    <string name=\"zigzag_sub\">Малює хвилястий зигзаг вздовж шляху</string>\n    <string name=\"zigzag_ratio\">Зигзагоподібне співвідношення</string>\n    <string name=\"create_shortcut\">Створити ярлик</string>\n    <string name=\"create_shortcut_title\">Виберіть інструмент для закріплення</string>\n    <string name=\"create_shortcut_subtitle\">Інструмент буде додано на головний екран вашої панелі запуску як ярлик, використовуйте його в поєднанні з налаштуванням \\\"Пропустити вибір файлів\\\", щоб досягти потрібної поведінки.</string>\n    <string name=\"dont_stack_frames\">Не складайте рамки один на одного</string>\n    <string name=\"dont_stack_frames_sub\">Дозволяє позбутися попередніх кадрів, щоб вони не складалися один на одного</string>\n    <string name=\"crossfade\">Кросфейд</string>\n    <string name=\"crossfade_sub\">Кадри будуть перетікатися один в одного</string>\n    <string name=\"crossfade_count\">Кількість кадрів кросфейду</string>\n    <string name=\"threshold_one\">Поріг один</string>\n    <string name=\"threshold_two\">Поріг другий</string>\n    <string name=\"canny\">Канні</string>\n    <string name=\"mirror_101\">Дзеркало 101</string>\n    <string name=\"enhanced_zoom_blur\">Покращене розмиття при збільшенні</string>\n    <string name=\"laplacian_simple\">Лапласова проста</string>\n    <string name=\"sobel_simple\">Собел Симпл</string>\n    <string name=\"helper_grid\">Допоміжна сітка</string>\n    <string name=\"helper_grid_sub\">Показує допоміжну сітку над областю малювання для полегшення точного виконання маніпуляцій</string>\n    <string name=\"grid_color\">Колір сітки</string>\n    <string name=\"cell_width\">Ширина комірки</string>\n    <string name=\"cell_height\">Висота комірки</string>\n    <string name=\"compact_selectors\">Компактні селектори</string>\n    <string name=\"compact_selectors_sub\">Деякі елементи керування виділенням використовуватимуть компактне розташування, щоб займати менше місця</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Надайте камері дозвіл на зйомку зображення в налаштуваннях</string>\n    <string name=\"layout\">Макет</string>\n    <string name=\"main_screen_title\">Заголовок головного екрана</string>\n    <string name=\"constant_rate_factor\">Коефіцієнт постійної ставки (CRF)</string>\n    <string name=\"crf_sub\">Значення %1$s означає повільне стиснення, що призводить до відносно невеликого розміру файлу. %2$s означає швидше стиснення, що призводить до великого файлу.</string>\n    <string name=\"lut_library\">Бібліотека Лут</string>\n    <string name=\"lut_library_sub\">Завантажте колекцію LUT, яку можна буде застосувати після завантаження</string>\n    <string name=\"lut_library_update_sub\">Оновлення колекції LUT (до черги будуть поставлені лише нові), яку можна застосувати після завантаження</string>\n    <string name=\"filter_preview_image_sub\">Змінити попередній перегляд зображення за замовчуванням для фільтрів</string>\n    <string name=\"filter_preview_image\">Попередній Перегляд зображення</string>\n    <string name=\"hide\">Приховати</string>\n    <string name=\"show\">Показати</string>\n    <string name=\"slider_type\">Тип слайдера</string>\n    <string name=\"fancy\">Фенсі</string>\n    <string name=\"material_2\">Матеріал 2</string>\n    <string name=\"fancy_sub\">Вишуканий слайдер. Це опція за замовчуванням.</string>\n    <string name=\"material_2_sub\">Слайдер «Матеріал 2»</string>\n    <string name=\"material_you_slider_sub\">Слайдер Material You</string>\n    <string name=\"apply\">Застосувати</string>\n    <string name=\"center_align_dialog_buttons\">Центральні кнопки діалогового вікна</string>\n    <string name=\"center_align_dialog_buttons_sub\">Кнопки діалогових вікон будуть розташовані по центру, а не ліворуч, якщо це можливо.</string>\n    <string name=\"open_source_licenses\">Ліцензії з відкритим кодом</string>\n    <string name=\"open_source_licenses_sub\">Переглянути ліцензії бібліотек з відкритим кодом, що використовуються в цьому додатку</string>\n    <string name=\"area\">Площа</string>\n    <string name=\"area_sub\">Передискретизація з використанням відношення площі пікселя. Це може бути кращим методом для проріджування зображення, оскільки він дає результати без муару. Але коли зображення масштабується, він схожий на метод \\\"Найближчий\\\".</string>\n    <string name=\"enable_tonemapping\">Увімкнути тонову схему</string>\n    <string name=\"enter_percent\">Введіть %</string>\n    <string name=\"unknown_host\">Не вдається отримати доступ до сайту, спробуйте скористатися VPN або перевірте правильність URL-адреси</string>\n    <string name=\"markup_layers\">Шари розмітки</string>\n    <string name=\"markup_layers_sub\">Режим шарів з можливістю вільного розміщення зображень, тексту тощо</string>\n    <string name=\"edit_layer\">Редагувати шар</string>\n    <string name=\"layers_on_image\">Шари на зображенні</string>\n    <string name=\"layers_on_image_sub\">Використовуйте зображення як фон і додайте поверх нього різні шари</string>\n    <string name=\"layers_on_background\">Шари на фоні</string>\n    <string name=\"layers_on_background_sub\">Те саме, що й перший варіант, але з кольором замість зображення</string>\n    <string name=\"beta\">Бета-версія</string>\n    <string name=\"fast_settings_side\">Швидкі налаштування збоку</string>\n    <string name=\"fast_settings_side_sub\">Додати плаваючу смугу з вибраного боку під час редагування зображень, яка відкриватиме швидкі налаштування після натискання</string>\n    <string name=\"clear_selection\">Очистити вибір</string>\n    <string name=\"settings_group_visibility_hidden\">Групу налаштувань \\\"%1$s\\\" буде згорнуто за замовчуванням</string>\n    <string name=\"settings_group_visibility_visible\">Групу налаштувань \\\"%1$s\\\" буде розгорнуто за замовчуванням</string>\n    <string name=\"base_64_tools\">Інструменти Base64</string>\n    <string name=\"base_64_tools_sub\">Декодувати рядок Base64 у зображення або кодувати зображення у формат Base64</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">Надане значення не є дійсним рядком Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">Неможливо скопіювати порожній або недійсний рядок Base64</string>\n    <string name=\"paste_base_64\">Вставити Base64</string>\n    <string name=\"copy_base_64\">Копіювати Base64</string>\n    <string name=\"base_64_tips\">Завантажте зображення, щоб скопіювати або зберегти рядок Base64. Якщо у вас є сам рядок, ви можете вставити його вище, щоб отримати зображення.</string>\n    <string name=\"save_base_64\">Зберегти Base64</string>\n    <string name=\"share_base_64\">Поділитися Base64</string>\n    <string name=\"options\">Опції</string>\n    <string name=\"actions\">Дії</string>\n    <string name=\"import_base_64\">Імпорт Base64</string>\n    <string name=\"base_64_actions\">Дії Base64</string>\n    <string name=\"add_outline\">Додати контур</string>\n    <string name=\"add_outline_sub\">Додати контур навколо тексту заданим кольором і шириною</string>\n    <string name=\"outline_color\">Колір контуру</string>\n    <string name=\"outline_size\">Розмір контуру</string>\n    <string name=\"rotation\">Обертання</string>\n    <string name=\"checksum_as_filename\">Контрольна сума як ім\\'я файлу</string>\n    <string name=\"checksum_as_filename_sub\">Вихідні зображення матимуть назву, що відповідає їхній контрольній сумі даних.</string>\n    <string name=\"free_software_partner\">Безкоштовне програмне забезпечення (партнер)</string>\n    <string name=\"free_software_partner_sub\">Більше корисного програмного забезпечення в партнерському каналі Android-додатків</string>\n    <string name=\"algorithms\">Алгоритм</string>\n    <string name=\"checksum_tools\">Інструменти для перевірки контрольних сум</string>\n    <string name=\"checksum_tools_sub\">Порівнюйте контрольні суми, обчислюйте хеші або створюйте шістнадцяткові рядки з файлів, використовуючи різні алгоритми хешування</string>\n    <string name=\"calculate\">Розрахувати</string>\n    <string name=\"text_hash\">Хеш тексту</string>\n    <string name=\"checksum\">Контрольна сума</string>\n    <string name=\"pick_file_to_checksum\">Виберіть файл для обчислення його контрольної суми на основі вибраного алгоритму</string>\n    <string name=\"enter_text_to_checksum\">Введіть текст для обчислення його контрольної суми на основі вибраного алгоритму</string>\n    <string name=\"source_checksum\">Контрольна сума джерела</string>\n    <string name=\"checksum_to_compare\">Контрольна сума для порівняння</string>\n    <string name=\"match\">Матч!</string>\n    <string name=\"difference\">Різниця</string>\n    <string name=\"match_sub\">Контрольні суми рівні, це може бути безпечно</string>\n    <string name=\"difference_sub\">Контрольні суми не рівні, файл може бути небезпечним!</string>\n    <string name=\"mesh_gradients\">Сітчасті градієнти</string>\n    <string name=\"collection_mesh_gradients_sub\">Перегляньте онлайн-колекцію сітчастих градієнтів</string>\n    <string name=\"wrong_font\">Можна імпортувати лише шрифти TTF та OTF</string>\n    <string name=\"import_font\">Імпорт шрифту (TTF/OTF)</string>\n    <string name=\"export_fonts\">Експорт шрифтів</string>\n    <string name=\"imported_fonts\">Імпортовані шрифти</string>\n    <string name=\"error_while_saving\">Помилка під час спроби збереження, спробуйте змінити папку виводу</string>\n    <string name=\"filename_is_not_set\">Ім\\'я файлу не встановлено</string>\n    <string name=\"none\">Жоден</string>\n    <string name=\"custom_pages\">Користувацькі сторінки</string>\n    <string name=\"pages_selection\">Вибір сторінок</string>\n    <string name=\"tool_exit_confirmation\">Підтвердження виходу інструменту</string>\n    <string name=\"tool_exit_confirmation_sub\">Якщо під час використання певних інструментів у вас є незбережені зміни, і ви намагаєтеся закрити їх, то з\\'явиться діалогове вікно підтвердження.</string>\n    <string name=\"edit_exif_screen\">Редагувати EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Зміна метаданих одного зображення без повторного стиснення</string>\n    <string name=\"edit_exif_tag\">Натисніть, щоб редагувати доступні теги</string>\n    <string name=\"change_sticker\">Змінити наклейку</string>\n    <string name=\"fit_width\">Ширина по висоті</string>\n    <string name=\"fit_height\">Висота, що підходить</string>\n    <string name=\"batch_compare\">Порівняння пакетів</string>\n    <string name=\"pick_files_to_checksum\">Виберіть файл/файли для обчислення контрольної суми на основі вибраного алгоритму</string>\n    <string name=\"pick_files\">Вибрати файли</string>\n    <string name=\"pick_directory\">Вибрати каталог</string>\n    <string name=\"head_length_scale\">Шкала довжини голови</string>\n    <string name=\"stamp\">Штамп</string>\n    <string name=\"timestamp\">Позначка часу</string>\n    <string name=\"format_pattern\">Шаблон форматування</string>\n    <string name=\"padding\">Заповнення</string>\n    <string name=\"image_cutting\">Обрізання зображення</string>\n    <string name=\"image_cutting_sub\">Вирізати частину зображення та об\\'єднати ліві частини (можна інвертувати) вертикальними або горизонтальними лініями</string>\n    <string name=\"vertical_pivot_line\">Вертикальна лінія повороту</string>\n    <string name=\"horizontal_pivot_line\">Горизонтальна лінія повороту</string>\n    <string name=\"inverse_selection\">Зворотний вибір</string>\n    <string name=\"inverse_vertical_selection_sub\">Вертикальна розрізана частина буде залишена, замість об\\'єднання частин навколо області розрізу.</string>\n    <string name=\"inverse_horizontal_selection_sub\">Горизонтально вирізана частина буде залишена, замість об\\'єднання частин навколо області вирізу.</string>\n    <string name=\"collection_mesh_gradients\">Колекція сітчастих градієнтів</string>\n    <string name=\"mesh_gradients_sub\">Створення сітчастого градієнта з власною кількістю вузлів та роздільною здатністю</string>\n    <string name=\"gradient_maker_type_image_mesh\">Сітчасте градієнтне накладання</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Створити сітчастий градієнт верхньої частини заданих зображень</string>\n    <string name=\"points_customization\">Налаштування балів</string>\n    <string name=\"grid_size\">Розмір сітки</string>\n    <string name=\"resolution_x\">Роздільна Здатність Х</string>\n    <string name=\"resolution_y\">Роздільна Здатність Y</string>\n    <string name=\"resolution\">Роздільна здатність</string>\n    <string name=\"pixel_by_pixel\">Піксель за пікселем</string>\n    <string name=\"highlight_color\">Колір виділення</string>\n    <string name=\"pixel_comparison_type\">Тип порівняння пікселів</string>\n    <string name=\"scan_barcode\">Скануйте штрих-код</string>\n    <string name=\"height_ratio\">Співвідношення висоти</string>\n    <string name=\"barcode_type\">Тип штрих-коду</string>\n    <string name=\"enforce_bw\">Забезпечити чорно-біле виконання</string>\n    <string name=\"enforce_bw_sub\">Зображення штрих-коду буде повністю чорно-білим, а не кольоровим за темою програми</string>\n    <string name=\"barcodes_sub\">Відскануйте будь-який штрих-код (QR, EAN, AZTEC тощо) та отримайте його вміст або вставте свій текст, щоб створити новий</string>\n    <string name=\"no_barcode_found\">Штрих-код не знайдено</string>\n    <string name=\"generated_barcode_will_be_here\">Згенерований штрих-код буде тут</string>\n    <string name=\"audio_cover_extractor\">Аудіообкладинки</string>\n    <string name=\"audio_cover_extractor_sub\">Вилучення зображень обкладинок альбомів з аудіофайлів, підтримуються найпоширеніші формати</string>\n    <string name=\"pick_audio_to_start\">Виберіть аудіо для початку</string>\n    <string name=\"pick_audio\">Вибрати аудіо</string>\n    <string name=\"no_covers_found\">Обкладинок не знайдено</string>\n    <string name=\"send_logs\">Надіслати журнали</string>\n    <string name=\"send_logs_sub\">Натисніть, щоб поділитися файлом журналів програми. Це може допомогти мені виявити проблему та виправити її.</string>\n    <string name=\"crash_title\">Ой… Щось пішло не так</string>\n    <string name=\"crash_subtitle\">Ви можете зв\\'язатися зі мною, використовуючи наведені нижче опції, і я спробую знайти рішення.\\n(Не забудьте додати логи)</string>\n    <string name=\"ocr_write_to_file\">Записати у файл</string>\n    <string name=\"ocr_write_to_file_sub\">Витяг тексту з пакету зображень та збереження його в одному текстовому файлі</string>\n    <string name=\"ocr_write_to_metadata\">Запис у метадані</string>\n    <string name=\"ocr_write_to_metadata_sub\">Витягніть текст з кожного зображення та помістіть його в EXIF-інформацію відповідних фотографій</string>\n    <string name=\"invisible_mode\">Невидимий режим</string>\n    <string name=\"invisible_mode_sub\">Використовуйте стеганографію для створення невидимих оком водяних знаків всередині байтів ваших зображень</string>\n    <string name=\"use_lsb\">Використовувати молодший біт (MLB)</string>\n    <string name=\"use_lsb_sub\">Буде використано метод стеганографії LSB (менш значущий біт), в іншому випадку - FD (частотна область).</string>\n    <string name=\"auto_remove_red_eyes\">Автоматичне вилучення ефекту червоних очей</string>\n    <string name=\"password\">Пароль</string>\n    <string name=\"unlock\">Розблокувати</string>\n    <string name=\"pdf_is_protected\">PDF-файл захищено</string>\n    <string name=\"operation_almost_complete\">Операцію майже завершено. Щоб скасувати зараз, потрібно буде перезапустити її.</string>\n    <string name=\"sort_by_date_modified\">Дата зміни</string>\n    <string name=\"sort_by_date_modified_reversed\">Дата зміни (скасування)</string>\n    <string name=\"sort_by_size\">Розмір</string>\n    <string name=\"sort_by_size_reversed\">Розмір (у зворотному напрямку)</string>\n    <string name=\"sort_by_mime_type\">Тип MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Тип MIME (зворотний)</string>\n    <string name=\"sort_by_extension\">Розширення\\'</string>\n    <string name=\"sort_by_extension_reversed\">Розширення (зворотне)</string>\n    <string name=\"sort_by_date_added\">Дата додавання</string>\n    <string name=\"sort_by_date_added_reversed\">Дата додавання (у зворотному порядку)</string>\n    <string name=\"left_to_right\">Зліва направо</string>\n    <string name=\"right_to_left\">Справа наліво</string>\n    <string name=\"top_to_bottom\">Зверху вниз</string>\n    <string name=\"bottom_to_top\">Знизу вгору</string>\n    <string name=\"liquid_glass\">Liquid Glass</string>\n    <string name=\"liquid_glass_sub\">Перемикач на базі нещодавно анонсованої iOS 26 та її системи дизайну з рідким склом</string>\n    <string name=\"pick_image_or_base64\">Виберіть зображення або вставте/імпортуйте дані Base64 нижче</string>\n    <string name=\"type_image_link\">Введіть посилання на зображення, щоб розпочати</string>\n    <string name=\"paste_link\">Вставити посилання</string>\n    <string name=\"kaleidoscope\">Калейдоскоп</string>\n    <string name=\"secondary_angle\">Вторинний кут</string>\n    <string name=\"sides\">Сторони</string>\n    <string name=\"channel_mix\">Мікс каналів</string>\n    <string name=\"blue_green\">Синьо-зелений</string>\n    <string name=\"red_blue\">Червоний синій</string>\n    <string name=\"green_red\">Зелений червоний</string>\n    <string name=\"into_red\">У червоний колір</string>\n    <string name=\"into_green\">У зелений</string>\n    <string name=\"into_blue\">У синій колір</string>\n    <string name=\"cyan\">Блакитний</string>\n    <string name=\"magenta\">Магента</string>\n    <string name=\"yellow\">Жовтий</string>\n    <string name=\"color_halftone\">Кольоровий півтон</string>\n    <string name=\"contour\">Контур</string>\n    <string name=\"levels\">Рівні</string>\n    <string name=\"offset\">Зсув</string>\n    <string name=\"voronoi_crystallize\">Кристалізація Вороного</string>\n    <string name=\"shape\">Форма</string>\n    <string name=\"stretch\">Розтягнути</string>\n    <string name=\"randomness\">Випадковість</string>\n    <string name=\"despeckle\">Видалити плями</string>\n    <string name=\"diffuse\">Дифузний</string>\n    <string name=\"dog\">DoG</string>\n    <string name=\"second_radius\">Другий радіус</string>\n    <string name=\"equalize\">Зрівняти</string>\n    <string name=\"glow\">Сяйво</string>\n    <string name=\"whirl_and_pinch\">Кружляти та щипати</string>\n    <string name=\"pointillize\">Пуантилізувати</string>\n    <string name=\"border_color\">Колір межі</string>\n    <string name=\"polar_coordinates\">Полярні координати</string>\n    <string name=\"rect_to_polar\">Від прямокутника до полярного</string>\n    <string name=\"polar_to_rect\">Полярний до прямокутного</string>\n    <string name=\"invert_in_circle\">Інвертувати по колу</string>\n    <string name=\"reduce_noise\">Зменшення шуму</string>\n    <string name=\"simple_solarize\">Проста соляризація</string>\n    <string name=\"weave\">Плетіння</string>\n    <string name=\"x_gap\">X-проміжок</string>\n    <string name=\"y_gap\">Y-проміжок</string>\n    <string name=\"x_width\">X Ширина</string>\n    <string name=\"y_wdth\">Y Ширина</string>\n    <string name=\"twirl\">Крутити</string>\n    <string name=\"rubber_stmp\">Гумовий штамп</string>\n    <string name=\"smear\">Мазок</string>\n    <string name=\"density\">Щільність</string>\n    <string name=\"mix\">Змішати</string>\n    <string name=\"sphere_lensh_distortion\">Спотворення сферичної лінзи</string>\n    <string name=\"refraction_index\">Показник Заломлення</string>\n    <string name=\"arc\">Дуга</string>\n    <string name=\"spread_angle\">Кут розкиду</string>\n    <string name=\"sparkle\">Блиск</string>\n    <string name=\"rays\">Промені</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Градієнт</string>\n    <string name=\"moire\">Мері</string>\n    <string name=\"autumn\">Осінь</string>\n    <string name=\"bone\">Кістка</string>\n    <string name=\"jet\">Джет</string>\n    <string name=\"winter\">Зима</string>\n    <string name=\"ocean\">Океан</string>\n    <string name=\"summer\">Літо</string>\n    <string name=\"spring\">Весна</string>\n    <string name=\"cool_variant\">Класний варіант</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Рожевий</string>\n    <string name=\"hot\">Гарячий</string>\n    <string name=\"parula\">Слово</string>\n    <string name=\"magma\">Магма</string>\n    <string name=\"inferno\">Пекло</string>\n    <string name=\"plasma\">Плазма</string>\n    <string name=\"viridis\">Віридіс</string>\n    <string name=\"cividis\">Чівідіс</string>\n    <string name=\"twilight\">Сутінки</string>\n    <string name=\"twilight_shifted\">Сутінковий зсув</string>\n    <string name=\"auto_perspective\">Перспективний авто</string>\n    <string name=\"deskew\">Вирівнювання\\'</string>\n    <string name=\"allow_crop\">Дозволити обрізання</string>\n    <string name=\"crop_or_perspective\">Обрізання або перспектива</string>\n    <string name=\"absolute\">Абсолютний</string>\n    <string name=\"turbo\">Турбо</string>\n    <string name=\"deep_green\">Глибоко зелений</string>\n    <string name=\"lens_correction\">Корекція об\\'єктива</string>\n    <string name=\"target_lens_profile\">Файл профілю цільової лінзи у форматі JSON</string>\n    <string name=\"download_ready_lens_profiles\">Завантажте готові профілі об\\'єктивів</string>\n    <string name=\"part_percents\">Частина відсотків</string>\n    <string name=\"disable_rotation\">Вимкнути обертання</string>\n    <string name=\"disable_rotation_sub\">Запобігає обертанню зображень жестами двома пальцями</string>\n    <string name=\"enable_snapping_to_borders\">Увімкнути прив\\'язку до меж</string>\n    <string name=\"enable_snapping_to_borders_sub\">Після переміщення або масштабування зображення будуть прив\\'язані до країв кадру</string>\n    <string name=\"export_as_json\">Експортувати як JSON</string>\n    <string name=\"export_as_json_sub\">Копіювати рядок з даними палітри у вигляді JSON-представлення</string>\n    <string name=\"seam_carving\">Різьблення швів</string>\n    <string name=\"home_screen\">Головний екран</string>\n    <string name=\"lock_screen\">Екран блокування</string>\n    <string name=\"built_in\">Вбудований</string>\n    <string name=\"wallpapers_export\">Експорт шпалер</string>\n    <string name=\"refresh\">Оновити</string>\n    <string name=\"wallpapers_export_sub\">Отримайте актуальні шпалери для головної сторінки, блокування та вбудованих екранів</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Дозволити доступ до всіх файлів, це потрібно для отримання шпалер</string>\n    <string name=\"allow_read_media_images_for_wp\">Дозволів на керування зовнішнім сховищем недостатньо, потрібно дозволити доступ до зображень, переконайтеся, що вибрано \\\"Дозволити всім\\\"</string>\n    <string name=\"add_preset_to_filename\">Додати пресет до назви файлу</string>\n    <string name=\"add_preset_to_filename_sub\">Додає суфікс із вибраним пресетом до назви файлу зображення</string>\n    <string name=\"add_image_scale_mode_to_filename\">Додати режим масштабування зображення до назви файлу</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Додає суфікс із вибраним режимом масштабування зображення до назви файлу зображення</string>\n    <string name=\"ascii_art\">ASCII Art</string>\n    <string name=\"ascii_art_sub\">Перетворити зображення на текст ASCII, який виглядатиме як зображення</string>\n    <string name=\"params\">Параметри</string>\n    <string name=\"invert_colors_ascii_sub\">Застосовує негативний фільтр до зображення для кращого результату в деяких випадках</string>\n    <string name=\"processing_screenshot\">Обробка знімка екрана</string>\n    <string name=\"screenshot_not_captured_try_again\">Знімок екрана не зроблено, спробуйте ще раз</string>\n    <string name=\"skipped_saving\">Збереження пропущено</string>\n    <string name=\"skipped_saving_multiple\">Пропущено %1$s файлів</string>\n    <string name=\"allow_skip_if_larger\">Дозволити пропуск, якщо більший</string>\n    <string name=\"allow_skip_if_larger_sub\">Деяким інструментам буде дозволено пропускати збереження зображень, якщо розмір отриманого файлу буде більшим за оригінал.</string>\n    <string name=\"qr_type_calendar_event\">Подія календаря</string>\n    <string name=\"qr_type_contact_info\">Контакти</string>\n    <string name=\"qr_type_email\">Електронна пошта</string>\n    <string name=\"qr_type_geo_point\">Розташування</string>\n    <string name=\"qr_type_phone\">Телефон</string>\n    <string name=\"qr_type_plain\">Текст</string>\n    <string name=\"qr_type_sms\">SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Відкрита мережа</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Телефон</string>\n    <string name=\"message\">Повідомлення</string>\n    <string name=\"address\">Адреса</string>\n    <string name=\"subject\">Тема</string>\n    <string name=\"body\">Тіло</string>\n    <string name=\"name\">Ім\\'я</string>\n    <string name=\"organization\">Організація</string>\n    <string name=\"title\">Назва</string>\n    <string name=\"phones\">Телефони</string>\n    <string name=\"emails\">Електронні листи</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">Адреси</string>\n    <string name=\"summary\">Короткий зміст</string>\n    <string name=\"description\">Опис</string>\n    <string name=\"location\">Розташування</string>\n    <string name=\"organizer\">Організатор</string>\n    <string name=\"start_date\">Дата початку</string>\n    <string name=\"end_date\">Дата завершення</string>\n    <string name=\"status\">Статус</string>\n    <string name=\"latitude\">Широта</string>\n    <string name=\"longitude\">Довгота</string>\n    <string name=\"create_barcode\">Створити штрих-код</string>\n    <string name=\"edit_barcode\">Редагувати штрих-код</string>\n    <string name=\"wifi_configuration\">Конфігурація Wi-Fi</string>\n    <string name=\"security\">Безпека</string>\n    <string name=\"pick_contact\">Вибрати контакт</string>\n    <string name=\"grant_contact_permission\">Надайте контактам у налаштуваннях дозвіл на автозаповнення за допомогою вибраного контакту</string>\n    <string name=\"contact_info\">Контактна інформація</string>\n    <string name=\"first_name\">Особисті Ім\\'я</string>\n    <string name=\"middle_name\">По батькові</string>\n    <string name=\"last_name\">Прізвище</string>\n    <string name=\"pronunciation\">Вимова</string>\n    <string name=\"add_phone\">Додати телефон</string>\n    <string name=\"add_email\">Додати електронну пошту</string>\n    <string name=\"add_address\">Додати адресу</string>\n    <string name=\"website\">Вебсайт</string>\n    <string name=\"add_website\">Додати веб-сайт</string>\n    <string name=\"formatted_name\">Форматоване ім\\'я</string>\n    <string name=\"qr_code_top_image\">Це зображення буде розміщено над штрих-кодом</string>\n    <string name=\"code_customization\">Налаштування коду</string>\n    <string name=\"qr_logo_image\">Це зображення буде використано як логотип у центрі QR-коду</string>\n    <string name=\"logo\">Логотип</string>\n    <string name=\"logo_padding\">Відступи логотипу</string>\n    <string name=\"logo_size\">Розмір логотипу</string>\n    <string name=\"logo_corners\">Куточки логотипу</string>\n    <string name=\"fourth_eye\">Четверте око</string>\n    <string name=\"fourth_eye_description\">Додає симетрію очей до QR-коду, додаючи четверте око в нижньому кутку</string>\n    <string name=\"pixel_shape\">Форма пікселя</string>\n    <string name=\"frame_shape\">Форма рами</string>\n    <string name=\"ball_shape\">Форма кулі</string>\n    <string name=\"error_correction_level\">Рівень корекції помилок</string>\n    <string name=\"dark_color\">Темний колір</string>\n    <string name=\"light_color\">Світлий колір</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">Стиль, схожий на Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Візерунок маски</string>\n    <string name=\"code_may_be_not_scannable\">Цей код може бути нечитабельним, змініть параметри зовнішнього вигляду, щоб зробити його читабельним на всіх пристроях.</string>\n    <string name=\"not_scannable\">Недоступно для сканування</string>\n    <string name=\"launcher_mode_sub\">Інструменти виглядатимуть як панель запуску програм на головному екрані, щоб бути компактнішими.</string>\n    <string name=\"launcher_mode\">Режим запуску</string>\n    <string name=\"flood_fill_sub\">Заповнює область вибраним пензлем та стилем</string>\n    <string name=\"flood_fill\">Заливка</string>\n    <string name=\"spray\">Спрей</string>\n    <string name=\"spray_sub\">Малює шлях у стилі графіті</string>\n    <string name=\"square_particles\">Квадратні частинки</string>\n    <string name=\"square_particles_sub\">Частинки розпилення будуть квадратними, а не круглими</string>\n    <string name=\"palette_tools\">Інструменти палітри</string>\n    <string name=\"palette_tools_sub\">Генеруйте основну/матеріальну палітру з зображення або імпортуйте/експортуйте її в різні формати палітр</string>\n    <string name=\"edit_palette\">Редагувати палітру</string>\n    <string name=\"edit_palette_sub\">Експорт/імпорт палітри в різних форматах</string>\n    <string name=\"color_name\">Назва кольору</string>\n    <string name=\"palette_name\">Назва палітри</string>\n    <string name=\"palette_format\">Формат палітри</string>\n    <string name=\"export_palette_sub\">Експорт згенерованої палітри в різні формати</string>\n    <string name=\"add_color_palette_sub\">Додає новий колір до поточної палітри</string>\n    <string name=\"palette_name_not_supported\">Формат %1$s не підтримує надання назви палітри</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Через політику Play Store цю функцію неможливо включити до поточної збірки. Щоб отримати доступ до цієї функції, завантажте ImageToolbox з альтернативного джерела. Ви можете знайти доступні збірки на GitHub нижче.</string>\n    <string name=\"open_github_page\">Відкрити сторінку Github</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"one\">%1$s колір</item>\n        <item quantity=\"few\">%1$s кольори</item>\n        <item quantity=\"many\">%1$s кольорів</item>\n        <item quantity=\"other\">%1$s кольорів</item>\n    </plurals>\n    <string name=\"overwrite_files_sub_short\">Оригінальний файл буде замінено новим, а не збережено у вибраній папці</string>\n    <string name=\"hidden_watermark_text_detected\">Виявлено прихований текст водяного знака</string>\n    <string name=\"hidden_watermark_image_detected\">Виявлено приховане зображення водяного знака</string>\n    <string name=\"this_image_was_hidden\">Це зображення було приховано</string>\n    <string name=\"generative_inpaint\">Генеративне інпайнінг</string>\n    <string name=\"generative_inpaint_sub\">Дозволяє видаляти об\\'єкти на зображенні за допомогою моделі штучного інтелекту, не покладаючись на OpenCV. Щоб скористатися цією функцією, програма завантажить необхідну модель (~200 МБ) з GitHub.</string>\n    <string name=\"generative_inpaint_ready_sub\">Дозволяє видаляти об\\'єкти на зображенні за допомогою моделі штучного інтелекту, не покладаючись на OpenCV. Це може бути тривалою операцією.</string>\n    <string name=\"error_level_analysis\">Аналіз рівня помилок</string>\n    <string name=\"luminance_gradient\">Градієнт яскравості</string>\n    <string name=\"average_distance\">Середня відстань</string>\n    <string name=\"copy_move_detection\">Виявлення переміщення копіювання</string>\n    <string name=\"retain\">Зберігати</string>\n    <string name=\"coefficent\">Коефіцієнт</string>\n    <string name=\"clipboard_data_is_too_large\">Дані буфера обміну занадто великі</string>\n    <string name=\"data_is_too_large_to_copy\">Дані занадто великі для копіювання</string>\n    <string name=\"simple_weave_pixelization\">Проста пікселізація переплетення</string>\n    <string name=\"staggered_pixelization\">Ступінчаста пікселізація</string>\n    <string name=\"cross_pixelization\">Крос-пікселізація</string>\n    <string name=\"micro_macro_pixelization\">Мікро-макро-пікселізація</string>\n    <string name=\"orbital_pixelization\">Орбітальна пікселізація</string>\n    <string name=\"vortex_pixelization\">Пікселізація вихрів</string>\n    <string name=\"pulse_grid_pixelization\">Пікселізація імпульсної сітки</string>\n    <string name=\"nucleus_pixelization\">Пікселізація ядра</string>\n    <string name=\"radial_weave_pixelization\">Пікселізація радіального переплетення</string>\n    <string name=\"cannot_open_uri\">Не вдається відкрити uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Режим снігопаду</string>\n    <string name=\"enabled\">Увімкнено</string>\n    <string name=\"border_frame\">Рамка кордону</string>\n    <string name=\"glitch_variant\">Варіант глюка</string>\n    <string name=\"channel_shift\">Зміна каналу</string>\n    <string name=\"max_offset\">Максимальне зміщення</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Збій блоку</string>\n    <string name=\"block_size\">Розмір блоку</string>\n    <string name=\"crt_curvature\">Кривизна ЕПТ</string>\n    <string name=\"curvature\">Кривизна</string>\n    <string name=\"chroma\">Хрома</string>\n    <string name=\"pixel_melt\">Розплавлення пікселів</string>\n    <string name=\"max_drop\">Макс. падіння</string>\n    <string name=\"ai_tools\">Інструменти штучного інтелекту</string>\n    <string name=\"ai_tools_sub\">Різні інструменти для обробки зображень за допомогою моделей штучного інтелекту, такі як видалення артефактів або шумозаглушення</string>\n    <string name=\"model_anime_undeint\">Стиснення, нерівні лінії</string>\n    <string name=\"model_broadcast\">Мультфільми, стиснення трансляцій</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Загальне стиснення, загальний шум</string>\n    <string name=\"model_wb_denoise\">Безбарвний мультяшний шум</string>\n    <string name=\"model_span_anime_pretrain\">Швидке, загальне стиснення, загальний шум, анімація/комікси/аніме</string>\n    <string name=\"model_book_scan\">Сканування книг</string>\n    <string name=\"model_overexposure\">Корекція експозиції</string>\n    <string name=\"model_fbcnn_color_fp16\">Найкраще підходить для загального стиснення, кольорові зображення</string>\n    <string name=\"model_fbcnn_gray_fp16\">Найкраще підходить для загального стиснення, зображення у градаціях сірого</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Загальне стиснення, зображення у градаціях сірого, сильніше</string>\n    <string name=\"model_scunet_color_gan_fp16\">Загальний шум, кольорові зображення</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Загальний шум, кольорові зображення, краща деталізація</string>\n    <string name=\"model_scunet_gray_15_fp16\">Загальний шум, зображення у градаціях сірого</string>\n    <string name=\"model_scunet_gray_25_fp16\">Загальний шум, зображення у відтінках сірого, сильніший</string>\n    <string name=\"model_scunet_gray_50_fp16\">Загальний шум, зображення у градаціях сірого, найсильніший</string>\n    <string name=\"model_jpeg_destroyer\">Загальне стиснення</string>\n    <string name=\"model_jaywreck\">Загальне стиснення</string>\n    <string name=\"model_h264\">Текстурування, стиснення h264</string>\n    <string name=\"model_vhs\">стиснення VHS</string>\n    <string name=\"model_cinepak\">Нестандартне стиснення (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Стиснення моргання, краще для геометрії</string>\n    <string name=\"model_debink_v5\">Стиснення моргання, сильніше</string>\n    <string name=\"model_debink_v6\">Стиснення моргання, м\\'яке, зберігає деталі</string>\n    <string name=\"model_antialias\">Усунення ефекту сходів, згладжування</string>\n    <string name=\"model_kdm_scans\">Відскановані ілюстрації/малюнки, легке стиснення, муар</string>\n    <string name=\"model_bandage\">Кольорове смугастість</string>\n    <string name=\"model_halftone\">Повільно, вилучення півтонів</string>\n    <string name=\"model_colorizer\">Загальний засіб для забарвлення зображень у градаціях сірого/чорно-білих, для кращих результатів використовуйте DDColor</string>\n    <string name=\"model_deedge\">Вилучення країв</string>\n    <string name=\"model_desharpen\">Вилучає надмірну різкість</string>\n    <string name=\"model_dither\">Повільно, тремтіння</string>\n    <string name=\"model_gainres\">Згладжування, загальні артефакти, CGI</string>\n    <string name=\"merging\">Злиття</string>\n    <string name=\"model_kdm003_scans\">Обробка сканів KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Легка модель покращення зображення</string>\n    <string name=\"model_spongecolor_lite\">Проста та швидка розфарбовка, мультфільми, не ідеально</string>\n    <string name=\"model_bcgone_detailed_v2\">Вилучення артефактів стиснення</string>\n    <string name=\"model_bcgone_smooth\">Вилучення артефактів стиснення</string>\n    <string name=\"model_bandage_smooth\">Зняття пов\\'язки з гладкими результатами</string>\n    <string name=\"model_bendel_halftone\">Обробка напівтонових візерунків</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Вилучення шаблону тремтіння V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Вилучення артефактів JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Покращення текстур H.264</string>\n    <string name=\"model_vhs_sharpen\">Підвищення різкості та покращення якості запису VHS</string>\n    <string name=\"chunk_size\">Розмір шматка</string>\n    <string name=\"overlap_size\">Розмір перекриття</string>\n    <string name=\"note_chunk_info\">Зображення розміром понад %1$s пікселів будуть нарізані та оброблені фрагментами, а перекриття об\\'єднує їх, щоб уникнути видимих швів.</string>\n    <string name=\"large_chunk_warning\">Великі розміри можуть спричинити нестабільність у роботі з низькоякісними пристроями</string>\n    <string name=\"select_one_to_start\">Виберіть один, щоб почати</string>\n    <string name=\"delete_model_sub\">Ви хочете видалити модель %1$s? Вам потрібно буде завантажити її знову.</string>\n    <string name=\"confirm\">Підтвердити</string>\n    <string name=\"models\">Моделі</string>\n    <string name=\"downloaded_models\">Завантажені моделі</string>\n    <string name=\"available_models\">Доступні моделі</string>\n    <string name=\"preparing\">Підготовка</string>\n    <string name=\"active_model\">Активна модель</string>\n    <string name=\"failed_to_open_session\">Не вдалося відкрити сеанс</string>\n    <string name=\"only_onnx_models\">Імпортувати можна лише моделі .onnx/.ort</string>\n    <string name=\"import_model\">Імпорт моделі</string>\n    <string name=\"import_model_sub\">Імпортуйте власну модель onnx для подальшого використання, приймаються лише моделі onnx/ort, підтримується майже всі варіанти, подібні до esrgan</string>\n    <string name=\"imported_models\">Імпортовані моделі</string>\n    <string name=\"model_scunet_color_15_fp16\">Загальний шум, кольорові зображення</string>\n    <string name=\"model_scunet_color_25_fp16\">Загальний шум, кольорові зображення, сильніший</string>\n    <string name=\"model_scunet_color_50_fp16\">Загальний шум, кольорові зображення, найсильніший</string>\n    <string name=\"model_artifacts_dithering_alsa\">Зменшує артефакти розмивання кольорів та кольорові смуги, покращуючи плавність градієнтів та рівні кольорові області.</string>\n    <string name=\"model_nmkd_brighten_redux\">Покращує яскравість і контрастність зображення зі збалансованими світлими ділянками, зберігаючи при цьому природні кольори.</string>\n    <string name=\"model_nmkd_brighten\">Освітлює темні зображення, зберігаючи деталі та уникаючи переекспонування.</string>\n    <string name=\"model_nmkd_detoon\">Видаляє надмірне тонування кольору та відновлює більш нейтральний і природний колірний баланс.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Застосовує пуассонівське тонування шуму з акцентом на збереженні дрібних деталей і текстур.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Застосовує м’яке тонування пуассонівським шумом для плавніших та менш агресивних візуальних результатів.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Рівномірне тонування шуму, зосереджене на збереженні деталей та чіткості зображення.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Ніжне рівномірне тонування шуму для витонченої текстури та гладкого вигляду.</string>\n    <string name=\"model_repainter\">Відновлює пошкоджені або нерівні ділянки, перефарбовуючи артефакти та покращуючи узгодженість зображення.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Легка модель для видалення кольорових смуг з мінімальними витратами на продуктивність.</string>\n    <string name=\"model_jpeg_0_20\">Оптимізує зображення з дуже високими артефактами стиснення (якість 0-20%) для покращення чіткості.</string>\n    <string name=\"model_jpeg_20_40\">Покращує зображення з артефактами високого стиснення (якість 20-40%), відновлюючи деталі та зменшуючи шум.</string>\n    <string name=\"model_jpeg_40_60\">Покращує зображення з помірним стисненням (якість 40-60%), балансуючи різкість та плавність.</string>\n    <string name=\"model_jpeg_60_80\">Удосконалює зображення за допомогою легкого стиснення (якість 60-80%) для покращення тонких деталей та текстур.</string>\n    <string name=\"model_jpeg_80_100\">Трохи покращує зображення майже без втрат якості (якість 80-100%), зберігаючи при цьому природний вигляд і деталі.</string>\n    <string name=\"model_deblr\">Трохи зменшує розмиття зображення, покращуючи різкість без появи артефактів.</string>\n    <string name=\"processing_channel\">Тривалі операції</string>\n    <string name=\"processing_image\">Обробка зображення</string>\n    <string name=\"processing\">Обробка</string>\n    <string name=\"model_artifacts_jpg_0_20\">Видаляє значні артефакти стиснення JPEG у зображеннях дуже низької якості (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Зменшує сильні артефакти JPEG у сильно стиснутих зображеннях (на 20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Видаляє помірні артефакти JPEG, зберігаючи деталі зображення (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Удосконалює світлі артефакти JPEG у зображеннях досить високої якості (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Незначно зменшує незначні артефакти JPEG у зображеннях майже без втрат якості (80-100%).</string>\n    <string name=\"model_redetail_v2\">Покращує дрібні деталі та текстури, покращуючи сприйняття різкості без значних артефактів.</string>\n    <string name=\"processing_finished\">Обробку завершено</string>\n    <string name=\"processing_failed\">Обробка не вдалася</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Покращує текстуру та деталі шкіри, зберігаючи природний вигляд, оптимізовано для швидкості.</string>\n    <string name=\"model_sbdv_dejpeg\">Видаляє артефакти стиснення JPEG та відновлює якість зображення для стиснутих фотографій.</string>\n    <string name=\"model_iso_denoise_v1\">Зменшує шум ISO на фотографіях, зроблених в умовах слабкого освітлення, зберігаючи деталі.</string>\n    <string name=\"model_dejumbo\">Виправляє переекспоновані або «надмірні» світлі ділянки та відновлює кращий тональний баланс.</string>\n    <string name=\"model_ddcolor_tiny\">Легка та швидка модель розфарбовування, яка додає природні кольори до зображень у градаціях сірого.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Знищення шуму</string>\n    <string name=\"type_colorize\">Розфарбувати</string>\n    <string name=\"type_artifacts\">Артефакти</string>\n    <string name=\"type_enhance\">Покращити</string>\n    <string name=\"type_anime\">Аніме</string>\n    <string name=\"type_scans\">Сканування</string>\n    <string name=\"type_upscale\">Висококласний</string>\n    <string name=\"model_realesrgan_x4v3\">X4 масштабування для загальних зображень; крихітна модель, яка використовує менше графічного процесора та часу, з помірним усуненням розмиття та шуму.</string>\n    <string name=\"model_realesrgan_x2plus\">X2-кратне масштабування для загальних зображень, зберігаючи текстури та природні деталі.</string>\n    <string name=\"model_realesrgan_x4plus\">Покращення масштабування X4 для загальних зображень з покращеними текстурами та реалістичними результатами.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4-модуль масштабування, оптимізований для аніме-зображень; 6 блоків RRDB для чіткіших ліній та деталей.</string>\n    <string name=\"model_realesrnet_x4plus\">Масштабування X4 з втратою MSE забезпечує плавніші результати та зменшує артефакти для загальних зображень.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler, оптимізований для зображень аніме; Варіант 4B32F із більш чіткими деталями та плавними лініями.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Модель X4 UltraSharp V2 для загальних зображень; підкреслює різкість і чіткість.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; швидший і менший, зберігає деталі, використовуючи менше пам’яті GPU.</string>\n    <string name=\"model_rmbg_1_4\">Легка модель для швидкого видалення фону. Збалансована продуктивність і точність. Працює з портретами, об’єктами та сценами. Рекомендовано для більшості випадків використання.</string>\n    <string name=\"type_removebg\">Видаліть BG</string>\n    <string name=\"horizontal_border_thickness\">Товщина горизонтальної межі</string>\n    <string name=\"vertical_border_thickness\">Товщина вертикальної межі</string>\n    <string name=\"current_model_not_chunkable\">Поточна модель не підтримує фрагментування, зображення буде оброблено в оригінальних розмірах, це може спричинити велике споживання пам’яті та проблеми з пристроями низького класу</string>\n    <string name=\"chunking_disabled\">Розбиття на фрагменти вимкнено, зображення буде оброблено в оригінальних розмірах, це може спричинити велике споживання пам’яті та проблеми з пристроями низького класу, але може дати кращі результати під час висновку</string>\n    <string name=\"chunking\">Чанкінг</string>\n    <string name=\"model_u2net\">Високоточна модель сегментації зображення для видалення фону</string>\n    <string name=\"model_u2netp\">Полегшена версія U2Net для швидшого видалення фону з меншим використанням пам’яті.</string>\n    <string name=\"model_ddcolor\">Модель Full DDColor забезпечує високоякісне розфарбовування загальних зображень із мінімальними артефактами. Найкращий вибір серед усіх моделей забарвлення.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Навчені та приватні художні набори даних; дає різноманітні та художні результати забарвлення з меншою кількістю нереалістичних кольорових артефактів.</string>\n    <string name=\"model_birefnet\">Легка модель BiRefNet на основі Swin Transformer для точного видалення фону.</string>\n    <string name=\"model_inspyrenet\">Високоякісне видалення фону з чіткими краями та чудовим збереженням деталей, особливо на складних об’єктах і складному фоні.</string>\n    <string name=\"model_isnet\">Модель видалення фону, яка створює точні маски з гладкими краями, придатні для звичайних об’єктів і помірне збереження деталей.</string>\n    <string name=\"model_already_downloaded\">Модель вже завантажено</string>\n    <string name=\"model_successfully_imported\">Модель успішно імпортовано</string>\n    <string name=\"type\">Тип</string>\n    <string name=\"keyword\">Ключове слово</string>\n    <string name=\"very_fast\">Дуже швидко</string>\n    <string name=\"normal\">нормальний</string>\n    <string name=\"slow\">Повільно</string>\n    <string name=\"very_slow\">Дуже повільно</string>\n    <string name=\"compute_percents\">Обчисліть відсотки</string>\n    <string name=\"minimum_value_is\">Мінімальне значення – %1$s</string>\n    <string name=\"warp_sub\">Спотворюйте зображення, малюючи пальцями</string>\n    <string name=\"warp\">Деформація</string>\n    <string name=\"hardness\">Твердість</string>\n    <string name=\"warp_mode\">Режим деформації</string>\n    <string name=\"warp_mode_move\">Перемістити</string>\n    <string name=\"warp_mode_grow\">Рости</string>\n    <string name=\"warp_mode_shrink\">Зменшити</string>\n    <string name=\"warp_mode_swirl_cw\">Вир CW</string>\n    <string name=\"warp_mode_swirl_ccw\">Вир CCW</string>\n    <string name=\"fade_strength\">Сила згасання</string>\n    <string name=\"top_drop\">Top Drop</string>\n    <string name=\"bottom_drop\">Нижня падіння</string>\n    <string name=\"start_drop\">Почати Drop</string>\n    <string name=\"end_drop\">End Drop</string>\n    <string name=\"downloading\">Завантажується</string>\n    <string name=\"smooth_shapes\">Плавні фігури</string>\n    <string name=\"smooth_shapes_sub\">Використовуйте супереліпси замість стандартних заокруглених прямокутників для більш гладких і природних форм</string>\n    <string name=\"shape_type\">Тип форми</string>\n    <string name=\"cut\">Вирізати</string>\n    <string name=\"rounded\">Округлі</string>\n    <string name=\"smooth\">Гладкий</string>\n    <string name=\"cut_shapes_sub\">Гострі краї без округлення</string>\n    <string name=\"rounded_shapes_sub\">Класичні закруглені кути</string>\n    <string name=\"shapes_type\">Тип форми</string>\n    <string name=\"corners_size\">Розмір кутів</string>\n    <string name=\"squircle\">Squircle</string>\n    <string name=\"squircle_shapes_sub\">Елегантні округлі елементи інтерфейсу користувача</string>\n    <string name=\"filename_format\">Формат імені файлу</string>\n    <string name=\"prefix_pattern_description\">Спеціальний текст, розміщений на самому початку назви файлу, ідеально підходить для назв проектів, брендів або особистих тегів.</string>\n    <string name=\"original_filename_pattern_description\">Використовує оригінальну назву файлу без розширення, що допомагає зберегти ідентифікацію джерела.</string>\n    <string name=\"width_pattern_description\">Ширина зображення в пікселях, корисна для відстеження змін роздільної здатності або масштабування результатів.</string>\n    <string name=\"height_pattern_description\">Висота зображення в пікселях, корисна під час роботи зі співвідношенням сторін або експорту.</string>\n    <string name=\"random_numbers_pattern_description\">Генерує випадкові цифри, щоб гарантувати унікальні імена файлів; додайте більше цифр для додаткового захисту від дублікатів.</string>\n    <string name=\"sequence_number_pattern_description\">Лічильник із автоматичним збільшенням для пакетного експорту, ідеальний під час збереження кількох зображень за один сеанс.</string>\n    <string name=\"preset_info_pattern_description\">Вставляє застосовану назву попереднього налаштування в назву файлу, щоб ви могли легко запам’ятати, як було оброблено зображення.</string>\n    <string name=\"scale_mode_pattern_description\">Відображає режим масштабування зображення, що використовується під час обробки, допомагаючи розрізняти зображення зі зміненим розміром, обрізані чи підібрані.</string>\n    <string name=\"suffix_pattern_description\">Спеціальний текст, розміщений у кінці назви файлу, корисний для керування версіями, наприклад _v2, _edited або _final.</string>\n    <string name=\"extension_pattern_description\">Розширення файлу (png, jpg, webp тощо), що автоматично відповідає дійсному збереженому формату.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Настроювана часова позначка, яка дозволяє визначити власний формат за специфікацією Java для ідеального сортування.</string>\n    <string name=\"fling_type\">Тип кидка</string>\n    <string name=\"android_native\">Android Native</string>\n    <string name=\"ios_style\">Стиль iOS</string>\n    <string name=\"smooth_curve\">Плавна крива</string>\n    <string name=\"quick_stop\">Швидка зупинка</string>\n    <string name=\"bouncy\">Стрибкий</string>\n    <string name=\"floaty\">Плаваючий</string>\n    <string name=\"snappy\">Стрімкий</string>\n    <string name=\"ultra_smooth\">Ультра гладкий</string>\n    <string name=\"adaptive\">Адаптивний</string>\n    <string name=\"accessibility_aware\">Спеціальні можливості</string>\n    <string name=\"reduced_motion\">Зменшений рух</string>\n    <string name=\"android_native_sub\">Вбудована фізика прокручування Android для базового порівняння</string>\n    <string name=\"smooth_sub\">Збалансована плавна прокрутка для загального використання</string>\n    <string name=\"ios_style_sub\">Поведінка прокручування, подібна до iOS, з підвищеним тертям</string>\n    <string name=\"smooth_curve_sub\">Унікальна сплайн-крива для чіткого відчуття прокручування</string>\n    <string name=\"quick_stop_sub\">Точне прокручування зі швидкою зупинкою</string>\n    <string name=\"bouncy_sub\">Грайливий, чуйний пружний сувій</string>\n    <string name=\"floaty_sub\">Довгі ковзаючі прокручування для перегляду вмісту</string>\n    <string name=\"snappy_sub\">Швидке, чутливе прокручування для інтерактивних інтерфейсів користувача</string>\n    <string name=\"ultra_smooth_sub\">Преміум плавне прокручування з розширеним імпульсом</string>\n    <string name=\"adaptive_sub\">Коригує фізику на основі швидкості метання</string>\n    <string name=\"accessibility_aware_sub\">Поважає налаштування доступності системи</string>\n    <string name=\"reduced_motion_sub\">Мінімальний рух для потреб у доступності</string>\n    <string name=\"primary_lines\">Первинні лінії</string>\n    <string name=\"primary_lines_sub\">Кожний п’ятий рядок додає товстішу лінію</string>\n    <string name=\"fill_color\">Колір заливки</string>\n    <string name=\"hidden_tools\">Приховані інструменти</string>\n    <string name=\"hidden_for_share\">Інструменти, приховані для спільного використання</string>\n    <string name=\"color_library\">Бібліотека кольорів</string>\n    <string name=\"color_library_sub\">Перегляньте величезну колекцію кольорів</string>\n    <string name=\"model_fatality_deblur\">Збільшує різкість і усуває розмитість зображень, зберігаючи природні деталі, що ідеально підходить для виправлення розфокусованих фотографій.</string>\n    <string name=\"model_unresize_v3\">Інтелектуально відновлює зображення, розмір яких раніше було змінено, відновлюючи втрачені деталі та текстури.</string>\n    <string name=\"model_liveaction_v1_span\">Оптимізовано для живого контенту, зменшує артефакти стиснення та покращує дрібні деталі в кадрах фільмів/телешоу.</string>\n    <string name=\"model_vhs2hd_realplksr\">Перетворює відзнятий матеріал із якістю VHS у HD, усуваючи шум стрічки та підвищуючи роздільну здатність, зберігаючи вінтажне відчуття.</string>\n    <string name=\"model_text2hd_v1\">Спеціалізується на зображеннях із великою кількістю тексту та скріншотах, підвищує різкість символів і покращує читабельність.</string>\n    <string name=\"model_frankendata_pretrainer\">Розширене масштабування, навчене на різноманітних наборах даних, чудово підходить для покращення фотографій загального призначення.</string>\n    <string name=\"model_realwebphoto_v2\">Оптимізовано для фотографій, стиснених у Інтернеті, видаляє артефакти JPEG і відновлює природний вигляд.</string>\n    <string name=\"model_realwebphoto_v4\">Покращена версія для веб-фотографій із кращим збереженням текстури та зменшенням артефактів.</string>\n    <string name=\"model_dat_2x\">2-кратне збільшення за допомогою технології Dual Aggregation Transformer, зберігає різкість і природні деталі.</string>\n    <string name=\"model_dat_3x\">3-кратне збільшення за допомогою вдосконаленої трансформаторної архітектури, що ідеально підходить для потреб помірного розширення.</string>\n    <string name=\"model_dat_4x\">4-кратне високоякісне збільшення за допомогою найсучаснішої трансформаторної мережі, зберігає дрібні деталі у великих масштабах.</string>\n    <string name=\"model_nafnet_deblurring\">Усуває розмиття/шуми та тремтіння фотографій. Загального призначення, але найкраще на фото.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Відновлює зображення низької якості за допомогою трансформатора Swin2SR, оптимізованого для деградації BSRGAN. Чудово підходить для виправлення важких артефактів стиснення та покращення деталей у 4-кратному масштабі.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">4-кратне збільшення за допомогою трансформатора SwinIR, навченого на деградацію BSRGAN. Використовує GAN для більш чітких текстур і більш природних деталей на фотографіях і складних сценах.</string>\n    <string name=\"path\">шлях</string>\n    <string name=\"merge_pdf\">Об’єднати PDF</string>\n    <string name=\"merge_pdf_sub\">Об’єднайте кілька файлів PDF в один документ</string>\n    <string name=\"files_order\">Порядок файлів</string>\n    <string name=\"pages_short\">пп.</string>\n    <string name=\"split_pdf\">Розділити PDF</string>\n    <string name=\"split_pdf_sub\">Витягніть певні сторінки з документа PDF</string>\n    <string name=\"rotate_pdf\">Повернути PDF</string>\n    <string name=\"rotate_pdf_sub\">Назавжди виправити орієнтацію сторінки</string>\n    <string name=\"pages\">сторінки</string>\n    <string name=\"rearrange_pdf\">Перевпорядкувати PDF</string>\n    <string name=\"rearrange_pdf_sub\">Перетягніть сторінки, щоб змінити їх порядок</string>\n    <string name=\"hold_drag_drop\">Утримуйте та перетягуйте сторінки</string>\n    <string name=\"page_numbers\">Номери сторінок</string>\n    <string name=\"page_numbers_sub\">Автоматично додавайте нумерацію до документів</string>\n    <string name=\"label_format\">Формат етикетки</string>\n    <string name=\"pdf_to_text\">PDF в текст (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Витягніть звичайний текст із PDF-документів</string>\n    <string name=\"watermark_pdf_sub\">Накладення спеціального тексту для брендингу або безпеки</string>\n    <string name=\"signature\">Підпис</string>\n    <string name=\"signature_sub\">Додайте свій електронний підпис до будь-якого документа</string>\n    <string name=\"will_be_for_signature\">Це буде використано як підпис</string>\n    <string name=\"unlock_pdf\">Розблокувати PDF</string>\n    <string name=\"unlock_pdf_sub\">Видаліть паролі з захищених файлів</string>\n    <string name=\"protect_pdf\">Захист PDF</string>\n    <string name=\"protect_pdf_sub\">Захистіть свої документи надійним шифруванням</string>\n    <string name=\"success\">Успіх</string>\n    <string name=\"pdf_unlocked\">PDF розблоковано, ви можете зберегти або поділитися ним</string>\n    <string name=\"repair_pdf\">Відремонтувати PDF</string>\n    <string name=\"repair_pdf_sub\">Спробуйте виправити пошкоджені або нечитабельні документи</string>\n    <string name=\"grayscale\">Відтінки сірого</string>\n    <string name=\"grayscale_pdf_sub\">Перетворення всіх зображень, вбудованих у документ, у відтінки сірого</string>\n    <string name=\"compress_pdf\">Стиснути PDF</string>\n    <string name=\"compress_pdf_sub\">Оптимізуйте розмір файлу документа, щоб простіше ділитися ним</string>\n    <string name=\"repair_info\">ImageToolbox перебудовує внутрішню таблицю перехресних посилань і генерує файлову структуру з нуля. Це може відновити доступ до багатьох файлів, які \\\\\"неможливо відкрити\\\\\"</string>\n    <string name=\"grayscale_info\">Цей інструмент перетворює всі зображення документів на градації сірого. Найкраще підходить для друку та зменшення розміру файлу</string>\n    <string name=\"metadata\">Метадані</string>\n    <string name=\"metadata_pdf_sub\">Відредагуйте властивості документа для кращої конфіденційності</string>\n    <string name=\"tags\">Теги</string>\n    <string name=\"producer\">Продюсер</string>\n    <string name=\"author\">Автор</string>\n    <string name=\"keywords\">Ключові слова</string>\n    <string name=\"creator\">Творець</string>\n    <string name=\"privacy_deep_clean\">Глибоке очищення конфіденційності</string>\n    <string name=\"privacy_deep_clean_sub\">Очистити всі доступні метадані для цього документа</string>\n    <string name=\"page\">Сторінка</string>\n    <string name=\"deep_ocr\">Глибоке OCR</string>\n    <string name=\"deep_ocr_sub\">Витягніть текст із документа та збережіть його в одному текстовому файлі за допомогою механізму Tesseract</string>\n    <string name=\"cant_remove_all\">Неможливо видалити всі сторінки</string>\n    <string name=\"remove_pages_pdf\">Видаліть сторінки PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Видалити певні сторінки з документа PDF</string>\n    <string name=\"tap_to_remove\">Натисніть, щоб видалити</string>\n    <string name=\"manually\">Вручну</string>\n    <string name=\"crop_pdf\">Обрізати PDF</string>\n    <string name=\"crop_pdf_sub\">Обрізайте сторінки документа до будь-яких меж</string>\n    <string name=\"flatten_pdf\">Звести PDF</string>\n    <string name=\"flatten_pdf_sub\">Зробіть файл PDF незмінним за допомогою растрування сторінок документа</string>\n    <string name=\"camera_failed_to_open\">Не вдалося запустити камеру. Будь ласка, перевірте дозволи та переконайтеся, що він не використовується іншою програмою.</string>\n    <string name=\"extract_images\">Видобуток зображень</string>\n    <string name=\"extract_images_sub\">Витягніть зображення, вбудовані в PDF-файли, з їх оригінальною роздільною здатністю</string>\n    <string name=\"pdf_no_embedded\">Цей PDF-файл не містить жодних вбудованих зображень</string>\n    <string name=\"extract_images_info\">Цей інструмент сканує кожну сторінку та відновлює повноякісні вихідні зображення — ідеально підходить для збереження оригіналів із документів</string>\n    <string name=\"draw_signature\">Намалювати підпис</string>\n    <string name=\"pen_params\">Параметри пера</string>\n    <string name=\"draw_signature_sub\">Використовуйте власний підпис як зображення для розміщення на документах</string>\n    <string name=\"zip_pdf\">Zip PDF</string>\n    <string name=\"zip_pdf_sub\">Розділіть документ із заданим інтервалом і запакуйте нові документи в zip-архів</string>\n    <string name=\"interval\">Інтервал</string>\n    <string name=\"print_pdf\">Роздрукувати PDF</string>\n    <string name=\"print_pdf_sub\">Підготуйте документ до друку з нестандартним розміром сторінки</string>\n    <string name=\"pages_per_sheet\">Сторінок на аркуші</string>\n    <string name=\"orientation\">Орієнтація</string>\n    <string name=\"page_size\">Розмір сторінки</string>\n    <string name=\"margin\">Маржа</string>\n    <string name=\"bloom\">цвітіння</string>\n    <string name=\"soft_knee\">М\\'яке коліно</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Оптимізовано для аніме та мультфільмів. Швидке масштабування з покращеними природними кольорами та меншою кількістю артефактів</string>\n    <string name=\"one_ui_sub\">Стиль, схожий на Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Введіть тут основні математичні символи, щоб обчислити потрібне значення (наприклад, (5+5)*10)</string>\n    <string name=\"math_expression\">Математичний вираз</string>\n    <string name=\"pick_up_to_n_collage_images\">Виберіть до %1$s зображень</string>\n    <string name=\"keep_date_time\">Зберегти дату та час</string>\n    <string name=\"keep_date_time_sub\">Завжди зберігати теги exif, пов’язані з датою та часом, працює незалежно від параметра keep exif</string>\n    <string name=\"background_color_for_alpha_formats\">Колір фону для альфа-форматів</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Додає можливість установлювати фоновий колір для кожного формату зображення з підтримкою альфа-версії, якщо вимкнено, це доступно лише для неальфа-версії</string>\n    <string name=\"open_markup_project\">Відкритий проект</string>\n    <string name=\"open_markup_project_sub\">Продовжити редагування раніше збереженого проекту Image Toolbox</string>\n    <string name=\"markup_project_open_failed\">Неможливо відкрити проект Image Toolbox</string>\n    <string name=\"markup_project_missing_data\">У проекті Image Toolbox відсутні дані проекту</string>\n    <string name=\"markup_project_corrupted\">Проект Image Toolbox пошкоджено</string>\n    <string name=\"unsupported_markup_project_version\">Непідтримувана версія проекту Image Toolbox: %1$d</string>\n    <string name=\"save_markup_project\">Зберегти проект</string>\n    <string name=\"save_markup_project_sub\">Зберігайте шари, фон і історію редагування у файлі проекту, який можна редагувати</string>\n    <string name=\"failed_to_open\">Не вдалося відкрити</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Запис у PDF з можливістю пошуку</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Розпізнавайте текст із пакету зображень і зберігайте файл PDF із можливістю пошуку із зображенням і текстовим шаром, який можна вибрати</string>\n    <string name=\"layer_alpha\">Шар альфа</string>\n    <string name=\"horizontal_flip\">Горизонтальний фліп</string>\n    <string name=\"vertical_flip\">Вертикальний фліп</string>\n    <string name=\"lock\">Замок</string>\n    <string name=\"add_shadow\">Додати тінь</string>\n    <string name=\"shadow_color\">Колір тіні</string>\n    <string name=\"text_geometry\">Геометрія тексту</string>\n    <string name=\"text_geometry_sub\">Розтягніть або перекосіть текст для чіткішої стилізації</string>\n    <string name=\"scale_x\">Шкала X</string>\n    <string name=\"skew_x\">Перекіс X</string>\n    <string name=\"remove_annotations\">Видаліть анотації</string>\n    <string name=\"remove_annotations_sub\">Видаліть зі сторінок PDF вибрані типи анотацій, як-от посилання, коментарі, виділення, фігури або поля форми</string>\n    <string name=\"annotation_link\">Гіперпосилання</string>\n    <string name=\"annotation_file_attachment\">Вкладення файлів</string>\n    <string name=\"annotation_line\">Лінії</string>\n    <string name=\"annotation_popup\">Спливаючі вікна</string>\n    <string name=\"annotation_stamp\">Марки</string>\n    <string name=\"annotation_shapes\">Фігури</string>\n    <string name=\"annotation_text\">Текстові примітки</string>\n    <string name=\"annotation_text_markup\">Розмітка тексту</string>\n    <string name=\"annotation_widget\">Поля форми</string>\n    <string name=\"annotation_markup\">Розмітка</string>\n    <string name=\"annotation_unknown\">Невідомий</string>\n    <string name=\"annotations\">Анотації</string>\n    <string name=\"ungroup\">Розгрупувати</string>\n    <string name=\"add_shadow_sub\">Додайте розмиту тінь за шаром із настроюваним кольором і зсувами</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-v26/bools.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <bool name=\"at_least_26\">true</bool>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-v31/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"primary\">@android:color/system_accent1_100</color>\n    <color name=\"onPrimary\">@android:color/system_accent1_700</color>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-vi/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"smth_went_wrong\">Có gì đó sai: %1$s</string>\n    <string name=\"size\">Kích thước %1$s</string>\n    <string name=\"loading\">Đang tải…</string>\n    <string name=\"image_too_large_preview\">Hình ảnh quá lớn để xem trước nhưng vẫn sẽ cố lưu lại</string>\n    <string name=\"pick_image\">Chọn hình ảnh để bắt đầu</string>\n    <string name=\"width\">Chiều rộng %1$s</string>\n    <string name=\"height\">Chiều cao %1$s</string>\n    <string name=\"quality\">Chất lượng</string>\n    <string name=\"extension\">Tiện ích mở rộng</string>\n    <string name=\"resize_type\">Kiểu thay đổi kích thước</string>\n    <string name=\"explicit\">Minh bạch</string>\n    <string name=\"flexible\">Linh hoạt</string>\n    <string name=\"pick_image_alt\">Chọn hình ảnh</string>\n    <string name=\"app_closing_sub\">Bạn có thực sự muốn đóng ứng dụng?</string>\n    <string name=\"app_closing\">Ứng dụng đang đóng</string>\n    <string name=\"stay\">Ở lại</string>\n    <string name=\"close\">Đóng</string>\n    <string name=\"reset_image\">Đặt lại hình ảnh</string>\n    <string name=\"reset_image_sub\">Các thay đổi về hình ảnh sẽ quay trở lại giá trị ban đầu</string>\n    <string name=\"values_reset\">Các giá trị được đặt lại chính xác</string>\n    <string name=\"reset\">Đặt lại</string>\n    <string name=\"something_went_wrong\">Đã xảy ra lỗi</string>\n    <string name=\"restart_app\">Khởi động lại ứng dụng</string>\n    <string name=\"copied\">Đã sao chép vào khay nhớ tạm</string>\n    <string name=\"exception\">Ngoại lệ</string>\n    <string name=\"edit_exif\">Chỉnh sửa EXIF</string>\n    <string name=\"ok\" tools:ignore=\"ButtonCase,Typos\">Ok</string>\n    <string name=\"no_exif\">Không tìm thấy dữ liệu EXIF</string>\n    <string name=\"add_tag\">Thêm thẻ</string>\n    <string name=\"save\">Lưu</string>\n    <string name=\"clear\">Xóa</string>\n    <string name=\"clear_exif\">Xóa EXIF</string>\n    <string name=\"cancel\">Hủy</string>\n    <string name=\"clear_exif_sub\">Tất cả dữ liệu EXIF hình ảnh sẽ bị xóa. Hành động này không thể hoàn tác được!</string>\n    <string name=\"presets\">Thiết đặt trước</string>\n    <string name=\"crop\">Cắt</string>\n    <string name=\"image_not_saved\">Đang lưu</string>\n    <string name=\"image_not_saved_sub\">Tất cả các thay đổi chưa được lưu sẽ bị mất nếu bạn thoát ngay bây giờ</string>\n    <string name=\"check_source_code\">Mã nguồn</string>\n    <string name=\"check_source_code_sub\">Nhận thông tin cập nhật mới nhất, thảo luận các vấn đề và hơn thế nữa</string>\n    <string name=\"single_edit\">Chỉnh sửa đơn</string>\n    <string name=\"single_edit_sub\">Thay đổi thông số kỹ thuật của một hình ảnh cụ thể</string>\n    <string name=\"pick_color\">Chọn màu</string>\n    <string name=\"pick_color_sub\">Chọn màu từ hình ảnh, sao chép hoặc chia sẻ</string>\n    <string name=\"image\">Hình ảnh</string>\n    <string name=\"color\">Màu</string>\n    <string name=\"color_copied\">Đã sao chép màu</string>\n    <string name=\"crop_sub\">Cắt hình ảnh theo bất kỳ giới hạn nào</string>\n    <string name=\"version\">Phiên bản</string>\n    <string name=\"keep_exif\">Giữ EXIF</string>\n    <string name=\"images\">Hình ảnh: %d</string>\n    <string name=\"change_preview\">Thay đổi bản xem trước</string>\n    <string name=\"remove\">Loại bỏ</string>\n    <string name=\"palette_sub\">Tạo bảng màu từ hình ảnh đã cho</string>\n    <string name=\"generate_palette\">Tạo bảng màu</string>\n    <string name=\"palette\">Bảng màu</string>\n    <string name=\"update\">Cập nhật</string>\n    <string name=\"new_version\">Phiên bản mới %1$s</string>\n    <string name=\"unsupported_type\">Loại không được hỗ trợ: %1$s</string>\n    <string name=\"no_palette\">Không thể tạo bảng màu cho hình ảnh đã cho</string>\n    <string name=\"original\">Bản gốc</string>\n    <string name=\"folder\">Thư mục đầu ra</string>\n    <string name=\"def\">Mặc định</string>\n    <string name=\"custom\">Tùy chỉnh</string>\n    <string name=\"unspecified\">Không xác định</string>\n    <string name=\"device_storage\">Bộ nhớ thiết bị</string>\n    <string name=\"by_bytes_resize\">Thay đổi kích thước theo dung lượng</string>\n    <string name=\"max_bytes\">Kích thước tối đa tính bằng KB</string>\n    <string name=\"by_bytes_resize_sub\">Thay đổi kích thước hình ảnh theo kích thước nhất định tính bằng KB</string>\n    <string name=\"compare\">So sánh</string>\n    <string name=\"compare_sub\">So sánh hai hình ảnh đã cho</string>\n    <string name=\"pick_two_images\">Chọn hai hình ảnh để bắt đầu</string>\n    <string name=\"pick_images\">Chọn hình ảnh</string>\n    <string name=\"settings\">Thiết đặt</string>\n    <string name=\"night_mode\">Chế độ đêm</string>\n    <string name=\"dark\">Tối</string>\n    <string name=\"light\">Sáng</string>\n    <string name=\"system\">Hệ thống</string>\n    <string name=\"dynamic_colors\">Màu sắc sống động</string>\n    <string name=\"customization\">Tùy chỉnh</string>\n    <string name=\"allow_image_monet\">Cho phép hình ảnh monet</string>\n    <string name=\"allow_image_monet_sub\">Nếu được bật, khi bạn chọn một hình ảnh để chỉnh sửa, màu ứng dụng sẽ được áp dụng giống hình ảnh này</string>\n    <string name=\"language\">Ngôn ngữ</string>\n    <string name=\"amoled_mode\">Chế độ Amoled</string>\n    <string name=\"amoled_mode_sub\">Nếu được bật, màu bề mặt sẽ được đặt thành tối tuyệt đối ở chế độ đêm</string>\n    <string name=\"color_scheme\">Cách phối màu</string>\n    <string name=\"color_red\">Đỏ</string>\n    <string name=\"color_green\">Lục</string>\n    <string name=\"color_blue\">Lam</string>\n    <string name=\"clipboard_paste_invalid_color_code\">Dán Mã aRGB hợp lệ.</string>\n    <string name=\"clipboard_paste_invalid_empty\">Không có gì để dán</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">Không thể thay đổi cách phối màu của ứng dụng khi bật màu động</string>\n    <string name=\"pick_accent_color\">Chủ đề ứng dụng sẽ dựa trên màu đã chọn</string>\n    <string name=\"about_app\">Giới thiệu về ứng dụng</string>\n    <string name=\"no_updates\">Không tìm thấy bản cập nhật nào</string>\n    <string name=\"issue_tracker\">Trình theo dõi vấn đề</string>\n    <string name=\"issue_tracker_sub\">Gửi báo cáo lỗi và yêu cầu tính năng tại đây</string>\n    <string name=\"help_translate\">Trợ giúp dịch</string>\n    <string name=\"help_translate_sub\">Sửa lỗi dịch thuật hoặc bản địa hóa dự án sang ngôn ngữ khác</string>\n    <string name=\"nothing_found_by_search\">Truy vấn của bạn không tìm thấy gì</string>\n    <string name=\"search_here\">Tìm kiếm ở đây</string>\n    <string name=\"dynamic_colors_sub\">Nếu được bật thì màu ứng dụng sẽ được áp dụng giống màu hình nền</string>\n    <string name=\"failed_to_save\">Không lưu được %d hình ảnh</string>\n    <string name=\"email\">Email</string>\n    <string name=\"primary\">Sơ cấp</string>\n    <string name=\"tertiary\">Cao cấp</string>\n    <string name=\"secondary\">Trung cấp</string>\n    <string name=\"border_thickness\">Độ dày viền</string>\n    <string name=\"surface\">Bề mặt</string>\n    <string name=\"values\">Giá trị</string>\n    <string name=\"add\">Thêm</string>\n    <string name=\"permission\">Quyền</string>\n    <string name=\"grant\">Cấp</string>\n    <string name=\"permission_sub\">Ứng dụng cần quyền truy cập vào bộ nhớ của bạn để lưu hình ảnh để hoạt động, điều đó là cần thiết. Vui lòng cấp quyền trong hộp thoại tiếp theo.</string>\n    <string name=\"grant_permission_manual\">Ứng dụng cần có quyền này để hoạt động, vui lòng cấp quyền này theo cách thủ công</string>\n    <string name=\"external_storage\">Bộ nhớ ngoài</string>\n    <string name=\"monet_colors\">Màu monet</string>\n    <string name=\"donation_sub\">Ứng dụng này hoàn toàn miễn phí, nhưng nếu bạn muốn hỗ trợ phát triển dự án, bạn có thể nhấp vào đây</string>\n    <string name=\"fab_alignment\">Căn chỉnh FAB</string>\n    <string name=\"check_updates\">Kiểm tra cập nhật</string>\n    <string name=\"check_updates_sub\">Nếu được bật, hộp thoại cập nhật sẽ được hiển thị cho bạn khi khởi động ứng dụng</string>\n    <string name=\"zoom\">Thu phóng hình ảnh</string>\n    <string name=\"share\">Chia sẻ</string>\n    <string name=\"prefix\">Tiền tố</string>\n    <string name=\"filename\">Tên tệp</string>\n    <string name=\"emoji\">Biểu tượng cảm xúc</string>\n    <string name=\"emoji_sub\">Chọn biểu tượng cảm xúc nào sẽ hiển thị trên màn hình chính</string>\n    <string name=\"add_file_size\">Thêm kích thước tập tin</string>\n    <string name=\"add_file_size_sub\">Nếu được bật, sẽ thêm chiều rộng và chiều cao của hình ảnh đã lưu vào tên tệp đầu ra</string>\n    <string name=\"delete_exif\">Xóa EXIF</string>\n    <string name=\"delete_exif_sub\">Xóa siêu dữ liệu EXIF khỏi bất kỳ bộ hình ảnh nào</string>\n    <string name=\"image_preview\">Xem trước hình ảnh</string>\n    <string name=\"image_preview_sub\">Xem trước mọi loại hình ảnh: GIF, SVG, v.v.</string>\n    <string name=\"image_source\">Nguồn hình ảnh</string>\n    <string name=\"photo_picker\">Bộ chọn ảnh</string>\n    <string name=\"gallery_picker\">Thư viện</string>\n    <string name=\"file_explorer_picker\">Trình khám phá tệp</string>\n    <string name=\"photo_picker_sub\">Bộ chọn ảnh hiện đại của Android xuất hiện ở cuối màn hình, chỉ có thể hoạt động trên Android 12+. Có vấn đề khi nhận siêu dữ liệu EXIF</string>\n    <string name=\"gallery_picker_sub\">Bộ chọn hình ảnh thư viện đơn giản. Nó sẽ chỉ hoạt động nếu bạn có ứng dụng cung cấp tính năng chọn phương tiện</string>\n    <string name=\"file_explorer_picker_sub\">Sử dụng mục đích GetContent để chọn hình ảnh. Hoạt động ở mọi nơi nhưng được biết là có vấn đề khi nhận hình ảnh được chọn trên một số thiết bị. Đó không phải lỗi của tôi.</string>\n    <string name=\"options_arrangement\">Sắp xếp tùy chọn</string>\n    <string name=\"edit\">Chỉnh sửa</string>\n    <string name=\"order\">Thứ tự</string>\n    <string name=\"order_sub\">Xác định thứ tự các tùy chọn trên màn hình chính</string>\n    <string name=\"emojis_count\">Số lượng biểu tượng cảm xúc</string>\n    <string name=\"sequence_num\">số thứ tự</string>\n    <string name=\"original_filename\">tên tập tin gốc</string>\n    <string name=\"add_original_filename\">Thêm tên tệp gốc</string>\n    <string name=\"add_original_filename_sub\">Nếu được bật, sẽ thêm tên tệp gốc vào tên của hình ảnh đầu ra</string>\n    <string name=\"replace_sequence_number\">Thay thế số thứ tự</string>\n    <string name=\"replace_sequence_number_sub\">Nếu được bật sẽ thay thế dấu thời gian tiêu chuẩn thành số thứ tự hình ảnh nếu bạn sử dụng xử lý hàng loạt</string>\n    <string name=\"filename_not_work_with_photopicker\">Việc thêm tên tệp gốc không hoạt động nếu nguồn hình ảnh của bộ chọn ảnh được chọn</string>\n    <string name=\"load_image_from_net\">Tải hình ảnh từ mạng</string>\n    <string name=\"load_image_from_net_sub\">Tải bất kỳ hình ảnh nào từ internet để xem trước, thu phóng, chỉnh sửa và lưu nó nếu bạn muốn.</string>\n    <string name=\"no_image\">Không có hình ảnh</string>\n    <string name=\"image_link\">Liên kết hình ảnh</string>\n    <string name=\"fill\">Lấp đầy</string>\n    <string name=\"fit\">Phù hợp</string>\n    <string name=\"content_scale\">Tỷ lệ nội dung</string>\n    <string name=\"explicit_description\">Buộc mọi hình ảnh vào một hình ảnh được cung cấp bởi tham số Chiều rộng và Chiều cao - có thể thay đổi tỷ lệ khung hình</string>\n    <string name=\"flexible_description\">Thay đổi kích thước hình ảnh thành hình ảnh có cạnh dài được cung cấp bởi tham số Chiều rộng hoặc Chiều cao, mọi tính toán kích thước sẽ được thực hiện sau khi lưu - giữ nguyên tỷ lệ khung hình</string>\n    <string name=\"brightness\">Độ sáng</string>\n    <string name=\"contrast\">Độ tương phản</string>\n    <string name=\"hue\">Sắc độ</string>\n    <string name=\"saturation\">Độ bão hòa</string>\n    <string name=\"add_filter\">Thêm bộ lọc</string>\n    <string name=\"filter\">Bộ lọc</string>\n    <string name=\"filter_sub\">Áp dụng bất kỳ chuỗi bộ lọc nào cho hình ảnh nhất định</string>\n    <string name=\"filters\">Bộ lọc</string>\n    <string name=\"light_aka_illumination\">Ánh sáng</string>\n    <string name=\"color_filter\">Bộ lọc màu</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"exposure\">Tiếp xúc</string>\n    <string name=\"white_balance\">Cân bằng trắng</string>\n    <string name=\"temperature\">Nhiệt độ</string>\n    <string name=\"tint\">Pha màu</string>\n    <string name=\"monochrome\">Đơn sắc</string>\n    <string name=\"gamma\">Gamma</string>\n    <string name=\"highlights_shadows\">Tô sáng và đổ bóng</string>\n    <string name=\"highlights\">Tô sáng</string>\n    <string name=\"shadows\">Đổ bóng</string>\n    <string name=\"haze\">Sương mù</string>\n    <string name=\"effect\">Hiệu ứng</string>\n    <string name=\"distance\">Khoảng cách</string>\n    <string name=\"slope\">Độ dốc</string>\n    <string name=\"sharpen\">Làm sắc nét</string>\n    <string name=\"sepia\">Màu nâu đỏ</string>\n    <string name=\"negative\">Phủ định</string>\n    <string name=\"solarize\">Năng lượng mặt trời</string>\n    <string name=\"vibrance\">Rung động</string>\n    <string name=\"black_and_white\">Đen và Trắng</string>\n    <string name=\"crosshatch\">Chữ thập</string>\n    <string name=\"spacing\">Cách khoảng</string>\n    <string name=\"line_width\">Độ rộng dòng</string>\n    <string name=\"sobel_edge\">Cạnh Sobel</string>\n    <string name=\"blur\">Làm mờ</string>\n    <string name=\"halftone\">Bán âm</string>\n    <string name=\"cga_colorspace\">Không gian màu CGA</string>\n    <string name=\"gaussian_blur\">Làm mờ Gaussian</string>\n    <string name=\"box_blur\">Làm mờ hộp</string>\n    <string name=\"bilaterial_blur\">Làm mờ song phương</string>\n    <string name=\"emboss\">Chạm nổi</string>\n    <string name=\"laplacian\">Laplacian</string>\n    <string name=\"vignette\">Họa tiết</string>\n    <string name=\"start\">Bắt đầu</string>\n    <string name=\"end\">Kết thúc</string>\n    <string name=\"kuwahara\">Làm mịn Kuwahara</string>\n    <string name=\"stack_blur\">Làm mờ ngăn xếp</string>\n    <string name=\"radius\">Bán kính</string>\n    <string name=\"scale\">Tỷ lệ</string>\n    <string name=\"distortion\">Biến dạng</string>\n    <string name=\"angle\">Góc</string>\n    <string name=\"swirl\">Xoáy</string>\n    <string name=\"bulge\">Phồng lên</string>\n    <string name=\"dilation\">Sự giãn nở</string>\n    <string name=\"sphere_refraction\">Khúc xạ hình cầu</string>\n    <string name=\"refractive_index\">Chỉ số khúc xạ</string>\n    <string name=\"glass_sphere_refraction\">Khúc xạ cầu thủy tinh</string>\n    <string name=\"color_matrix\">Ma trận màu</string>\n    <string name=\"opacity\">Độ trong suốt</string>\n    <string name=\"limits_resize\">Giới hạn thay đổi kích thước</string>\n    <string name=\"limits_resize_sub\">Thay đổi kích thước hình ảnh đã chọn để tuân theo giới hạn chiều rộng và chiều cao nhất định trong khi lưu tỷ lệ khung hình</string>\n    <string name=\"sketch\">Phác thảo</string>\n    <string name=\"threshold\">Ngưỡng</string>\n    <string name=\"quantizationLevels\">Mức độ lượng tử hóa</string>\n    <string name=\"smooth_toon\">Hoạt hình mượt mà</string>\n    <string name=\"toon\">hoạt hình</string>\n    <string name=\"posterize\">Poster hóa</string>\n    <string name=\"non_maximum_suppression\">Ngăn chặn không tối đa</string>\n    <string name=\"weak_pixel_inclusion\">Bao gồm pixel yếu</string>\n    <string name=\"lookup\">Tra cứu</string>\n    <string name=\"convolution3x3\">Tích chập 3x3</string>\n    <string name=\"rgb_filter\">Bộ lọc RGB</string>\n    <string name=\"false_color\">Màu sai</string>\n    <string name=\"first_color\">Màu đầu tiên</string>\n    <string name=\"second_color\">Màu thứ hai</string>\n    <string name=\"reorder\">Sắp xếp lại</string>\n    <string name=\"fast_blur\">Làm mờ nhanh</string>\n    <string name=\"blur_size\">Kích thước mờ</string>\n    <string name=\"blur_center_x\">Làm mờ trung tâm x</string>\n    <string name=\"blur_center_y\">Làm mờ trung tâm y</string>\n    <string name=\"zoom_blur\">Thu phóng mờ</string>\n    <string name=\"color_balance\">Cân bằng màu sắc</string>\n    <string name=\"luminance_threshold\">Ngưỡng độ chói</string>\n    <string name=\"activate_files\">Bạn đã tắt ứng dụng Tệp, hãy kích hoạt ứng dụng này để sử dụng tính năng này</string>\n    <string name=\"draw\">Vẽ</string>\n    <string name=\"draw_sub\">Vẽ trên hình ảnh như trong sổ phác thảo hoặc vẽ trên nền</string>\n    <string name=\"paint_color\">Màu sơn</string>\n    <string name=\"paint_alpha\">Sơn alpha</string>\n    <string name=\"draw_on_image\">Vẽ lên hình ảnh</string>\n    <string name=\"draw_on_image_sub\">Chọn một hình ảnh và vẽ thứ gì đó lên nó</string>\n    <string name=\"draw_on_background\">Vẽ trên nền</string>\n    <string name=\"draw_on_background_sub\">Chọn màu nền và vẽ lên trên nó</string>\n    <string name=\"background_color\">Màu nền</string>\n    <string name=\"cipher\">Mật mã</string>\n    <string name=\"cipher_sub\">Mã hóa và Giải mã bất kỳ tập tệp nào (không chỉ hình ảnh) dựa trên nhiều thuật toán mã hóa khả dụng</string>\n    <string name=\"pick_file\">Chọn tập tin</string>\n    <string name=\"encrypt\">Mã hóa</string>\n    <string name=\"decrypt\">Giải mã</string>\n    <string name=\"pick_file_to_start\">Chọn tập tin để bắt đầu</string>\n    <string name=\"decryption\">Giải mã</string>\n    <string name=\"encryption\">Mã hóa</string>\n    <string name=\"key\">Chìa khóa</string>\n    <string name=\"file_proceed\">Tệp đã được xử lý</string>\n    <string name=\"store_file_desc\">Lưu trữ tệp này trên thiết bị của bạn hoặc sử dụng tác vụ chia sẻ để đặt nó ở bất cứ đâu bạn muốn</string>\n    <string name=\"features\">Tính năng</string>\n    <string name=\"implementation\">Triển khai</string>\n    <string name=\"compatibility\">Khả năng tương thích</string>\n    <string name=\"features_sub\">Mã hóa tập tin dựa trên mật khẩu. Các tập tin đã xử lý có thể được lưu trữ trong thư mục đã chọn hoặc được chia sẻ. Các tập tin được giải mã cũng có thể được mở trực tiếp.</string>\n    <string name=\"implementation_sub\">AES-256, chế độ GCM, không có phần đệm, IV ngẫu nhiên 12 byte. Các khóa được sử dụng làm hàm băm SHA-3 (256 bit).</string>\n    <string name=\"file_size\">Kích thước tệp</string>\n    <string name=\"file_size_sub\">Kích thước tệp tối đa bị giới hạn bởi hệ điều hành Android và bộ nhớ khả dụng, tùy thuộc vào thiết bị. \\nXin lưu ý: bộ nhớ không phải là nơi lưu trữ.</string>\n    <string name=\"compatibility_sub\">Xin lưu ý rằng khả năng tương thích với các phần mềm hoặc dịch vụ mã hóa tệp khác không được đảm bảo. Cách xử lý khóa hoặc cấu hình mật mã hơi khác một chút có thể gây ra sự không tương thích.</string>\n    <string name=\"invalid_password_or_not_encrypted\">Mật khẩu không hợp lệ hoặc tập tin đã chọn không được mã hóa</string>\n    <string name=\"image_size_warning\">Cố gắng lưu hình ảnh với chiều rộng và chiều cao đã cho có thể gây ra một lỗi hết bộ nhớ. Thực hiện điều này với rủi ro của riêng bạn</string>\n    <string name=\"cache\">Bộ đệm</string>\n    <string name=\"cache_size\">Kích thước bộ đệm</string>\n    <string name=\"found_s\">Đã tìm thấy %1$s</string>\n    <string name=\"auto_cache_clearing\">Tự động xóa bộ nhớ đệm</string>\n    <string name=\"auto_cache_clearing_sub\">Nếu được bật bộ đệm ứng dụng sẽ bị xóa khi khởi động ứng dụng</string>\n    <string name=\"create\">Tạo</string>\n    <string name=\"tools\">Công cụ</string>\n    <string name=\"group_options_by_type\">Nhóm tùy chọn theo loại</string>\n    <string name=\"group_options_by_type_sub\">Nhóm các tùy chọn trên màn hình chính theo loại thay vì sắp xếp danh sách tùy chỉnh</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">Không thể thay đổi cách sắp xếp khi nhóm tùy chọn được bật</string>\n    <string name=\"edit_screenshot\">Chỉnh sửa ảnh chụp màn hình</string>\n    <string name=\"secondary_customization\">Tùy chỉnh phụ</string>\n    <string name=\"screenshot\">Ảnh chụp màn hình</string>\n    <string name=\"fallback_option\">Tùy chọn dự phòng</string>\n    <string name=\"skip\">Bỏ qua</string>\n    <string name=\"copy\">Sao chép</string>\n    <string name=\"warning_bytes\">Việc lưu ở chế độ %1$s có thể không ổn định vì đây là định dạng không mất dữ liệu</string>\n    <string name=\"presets_sub\" formatted=\"false\">Nếu bạn đã chọn thiết đặt trước 125, ảnh sẽ được lưu ở kích thước 125% của ảnh gốc với chất lượng 100%. Nếu bạn chọn thiết đặt trước 50 thì ảnh sẽ được lưu với kích thước 50% và chất lượng 50%.</string>\n    <string name=\"presets_sub_bytes\">Thiết đặt trước ở đây xác định % của file đầu ra, tức là nếu bạn chọn thiết đặt trước 50 trên ảnh 5mb thì sau khi lưu bạn sẽ nhận được ảnh 2,5mb</string>\n    <string name=\"randomize_filename\">Chọn ngẫu nhiên tên tệp</string>\n    <string name=\"randomize_filename_sub\">Nếu được bật, tên tệp đầu ra sẽ hoàn toàn ngẫu nhiên</string>\n    <string name=\"saved_to\">Đã lưu vào thư mục %1$s có tên %2$s</string>\n    <string name=\"saved_to_without_filename\">Đã lưu vào thư mục %1$s</string>\n    <string name=\"tg_chat\">Trò chuyện Telegram</string>\n    <string name=\"tg_chat_sub\">Thảo luận về ứng dụng và nhận phản hồi từ những người dùng khác. Bạn cũng có thể nhận thông tin cập nhật và thông tin chi tiết về phiên bản beta tại đây.</string>\n    <string name=\"crop_mask\">Cắt mặt nạ</string>\n    <string name=\"aspect_ratio\">Tỷ lệ khung hình</string>\n    <string name=\"image_crop_mask_sub\">Sử dụng loại mặt nạ này để tạo mặt nạ từ hình ảnh đã cho, lưu ý rằng nó PHẢI có kênh alpha</string>\n    <string name=\"backup_and_restore\">Sao lưu và khôi phục</string>\n    <string name=\"backup\">Sao lưu</string>\n    <string name=\"restore\">Khôi phục</string>\n    <string name=\"backup_sub\">Sao lưu thiết đặt ứng dụng của bạn vào một tệp</string>\n    <string name=\"restore_sub\">Khôi phục thiết đặt ứng dụng từ tệp được tạo trước đó</string>\n    <string name=\"corrupted_file_or_not_a_backup\">Tệp bị hỏng hoặc không phải là bản sao lưu</string>\n    <string name=\"settings_restored\">Đã khôi phục thiết đặt thành công</string>\n    <string name=\"contact_me\">Liên hệ với tôi</string>\n    <string name=\"reset_settings_sub\">Điều này sẽ khôi phục cài đặt của bạn về giá trị mặc định. Lưu ý rằng thao tác này không thể hoàn tác nếu không có tệp sao lưu được đề cập ở trên.</string>\n    <string name=\"delete\">Xóa</string>\n    <string name=\"delete_color_scheme_warn\">Bạn sắp xóa bảng màu đã chọn. Thao tác này không thể hoàn tác được</string>\n    <string name=\"delete_color_scheme_title\">Xóa bảng màu</string>\n    <string name=\"font\">Phông chữ</string>\n    <string name=\"text\">Văn bản</string>\n    <string name=\"font_scale\">Tỷ lệ phông chữ</string>\n    <string name=\"defaultt\">Mặc định</string>\n    <string name=\"using_large_fonts_warn\">Việc sử dụng tỷ lệ phông chữ lớn có thể gây ra trục trặc và sự cố về giao diện người dùng mà sẽ không thể khắc phục được. Sử dụng thận trọng.</string>\n    <string name=\"alphabet_and_numbers\">Aa Ăă Ââ Bb Cc Dd Đđ Ee Êê Gg Hh Ii Kk Ll Mm Nn Oo Ôô Ơơ Pp Qq Rr Ss Tt Uu Ưư Vv Xx Yy 0123456789 !?</string>\n    <string name=\"emotions\">Cảm xúc</string>\n    <string name=\"food_and_drink\">Thức ăn và đồ uống</string>\n    <string name=\"nature_and_animals\">Thiên nhiên và Động vật</string>\n    <string name=\"objects\">Đối tượng</string>\n    <string name=\"symbols\">Ký hiệu</string>\n    <string name=\"enable_emoji\">Bật biểu tượng cảm xúc</string>\n    <string name=\"travels_and_places\">Du lịch và Địa điểm</string>\n    <string name=\"activities\">Hoạt động</string>\n    <string name=\"background_remover\">Xóa nền</string>\n    <string name=\"background_remover_sub\">Xóa nền khỏi hình ảnh bằng cách vẽ hoặc sử dụng tùy chọn Tự động</string>\n    <string name=\"trim_image\">Cắt hình ảnh</string>\n    <string name=\"keep_exif_sub\">Siêu dữ liệu hình ảnh gốc sẽ được giữ lại</string>\n    <string name=\"trim_image_sub\">Các khoảng trống trong suốt xung quanh hình ảnh sẽ bị cắt bớt</string>\n    <string name=\"auto_erase_background\">Tự động xóa nền</string>\n    <string name=\"restore_image\">Khôi phục hình ảnh</string>\n    <string name=\"erase_mode\">Chế độ xóa</string>\n    <string name=\"erase_background\">Xóa nền</string>\n    <string name=\"restore_background\">Khôi phục nền</string>\n    <string name=\"blur_radius\">Bán kính mờ</string>\n    <string name=\"pipette\">Pipet</string>\n    <string name=\"draw_mode\">Chế độ vẽ</string>\n    <string name=\"create_issue\">Tạo vấn đề</string>\n    <string name=\"something_went_wrong_emphasis\">Rất tiếc… Đã xảy ra lỗi. Bạn có thể viết thư cho tôi bằng các tùy chọn bên dưới và tôi sẽ cố gắng tìm giải pháp</string>\n    <string name=\"resize_and_convert\">Thay đổi kích thước và chuyển đổi</string>\n    <string name=\"resize_and_convert_sub\">Thay đổi kích thước của hình ảnh nhất định hoặc chuyển đổi chúng sang các định dạng khác. Siêu dữ liệu EXIF cũng có thể được chỉnh sửa tại đây nếu chọn một hình ảnh.</string>\n    <string name=\"max_colors_count\">Số màu tối đa</string>\n    <string name=\"crashlytics_sub\">Điều này cho phép ứng dụng thu thập báo cáo sự cố theo cách thủ công</string>\n    <string name=\"analytics\">Phân tích</string>\n    <string name=\"analytics_sub\">Cho phép thu thập số liệu thống kê sử dụng ứng dụng ẩn danh</string>\n    <string name=\"image_exif_warning\">Hiện tại, định dạng %1$s chỉ cho phép đọc siêu dữ liệu EXIF trên Android. Hình ảnh đầu ra sẽ không có siêu dữ liệu nào khi được lưu.</string>\n    <string name=\"effort\">Lực nén</string>\n    <string name=\"effort_sub\">Giá trị %1$s có nghĩa là nén nhanh, dẫn đến kích thước tệp tương đối lớn. %2$s có nghĩa là nén chậm hơn, dẫn đến tệp nhỏ hơn.</string>\n    <string name=\"wait\">Đợi</string>\n    <string name=\"saving_almost_complete\">Việc lưu gần như hoàn tất. Việc hủy bây giờ sẽ yêu cầu lưu lại.</string>\n    <string name=\"updates\">Cập nhật</string>\n    <string name=\"allow_betas\">Cho phép beta</string>\n    <string name=\"allow_betas_sub\">Kiểm tra cập nhật sẽ bao gồm các phiên bản ứng dụng beta nếu được bật</string>\n    <string name=\"draw_arrows\">Vẽ mũi tên</string>\n    <string name=\"draw_arrows_sub\">Nếu kích hoạt đường vẽ sẽ được biểu diễn dưới dạng mũi tên trỏ</string>\n    <string name=\"brush_softness\">Độ mềm của cọ</string>\n    <string name=\"crop_description\">Hình ảnh sẽ được cắt ở giữa theo kích thước đã nhập. Canvas sẽ được mở rộng với màu nền nhất định nếu hình ảnh nhỏ hơn kích thước đã nhập.</string>\n    <string name=\"donation\">Quyên góp</string>\n    <string name=\"image_stitching\">Ghép ảnh</string>\n    <string name=\"image_stitching_sub\">Kết hợp các hình ảnh đã cho để có được một hình ảnh lớn</string>\n    <string name=\"pick_at_least_two_images\">Chọn ít nhất 2 hình ảnh</string>\n    <string name=\"output_image_scale\">Tỷ lệ hình ảnh đầu ra</string>\n    <string name=\"image_orientation\">Hướng hình ảnh</string>\n    <string name=\"horizontal\">Ngang</string>\n    <string name=\"vertical\">Dọc</string>\n    <string name=\"scale_small_images_to_large\">Chia tỷ lệ hình ảnh nhỏ thành lớn</string>\n    <string name=\"scale_small_images_to_large_sub\">Hình ảnh nhỏ sẽ được phóng to thành hình ảnh lớn nhất trong chuỗi nếu được bật</string>\n    <string name=\"images_order\">Thứ tự hình ảnh</string>\n    <string name=\"regular\">Thông thường</string>\n    <string name=\"blur_edges\">Làm mờ các cạnh</string>\n    <string name=\"blur_edges_sub\">Vẽ các cạnh mờ bên dưới ảnh gốc để lấp đầy khoảng trống xung quanh nó thay vì một màu nếu được bật</string>\n    <string name=\"pixelation\">Pixel hóa</string>\n    <string name=\"enhanced_pixelation\">Pixel nâng cao</string>\n    <string name=\"stroke_pixelation\">Pixel hóa nét</string>\n    <string name=\"enhanced_diamond_pixelation\">Điểm ảnh kim cương nâng cao</string>\n    <string name=\"diamond_pixelation\">Pixel kim cương</string>\n    <string name=\"circle_pixelation\">Pixel hóa vòng tròn</string>\n    <string name=\"enhanced_circle_pixelation\">Pixel hóa vòng tròn nâng cao</string>\n    <string name=\"replace_color\">Thay thế màu</string>\n    <string name=\"tolerance\">Dung sai</string>\n    <string name=\"color_to_replace\">Màu cần thay thế</string>\n    <string name=\"target_color\">Màu mục tiêu</string>\n    <string name=\"color_to_remove\">Màu cần xóa</string>\n    <string name=\"remove_color\">Xóa màu</string>\n    <string name=\"recode\">Mã hóa lại</string>\n    <string name=\"pixel_size\">Kích thước pixel</string>\n    <string name=\"lock_draw_orientation\">Khóa hướng vẽ</string>\n    <string name=\"lock_draw_orientation_sub\">Nếu được bật ở chế độ vẽ, màn hình sẽ không xoay</string>\n    <string name=\"check_for_updates\">Kiểm tra cập nhật</string>\n    <string name=\"palette_style\">Kiểu bảng màu</string>\n    <string name=\"tonal_spot\">Điểm tông màu</string>\n    <string name=\"neutral\">Trung lập</string>\n    <string name=\"vibrant\">Sống động</string>\n    <string name=\"expressive\">Biểu cảm</string>\n    <string name=\"rainbow\">Cầu vồng</string>\n    <string name=\"fruit_salad\">Salad trái cây</string>\n    <string name=\"fidelity\">Sự trung thực</string>\n    <string name=\"content\">Nội dung</string>\n    <string name=\"tonal_spot_sub\">Kiểu bảng màu mặc định, nó cho phép tùy chỉnh tất cả bốn màu, những màu khác cho phép bạn chỉ đặt màu chính</string>\n    <string name=\"neutral_sub\">Một phong cách có nhiều màu sắc hơn một chút</string>\n    <string name=\"vibrant_sub\">Chủ đề ồn ào, màu sắc tối đa cho bảng màu Chính, tăng cho các bảng màu khác</string>\n    <string name=\"playful_scheme\">Một chủ đề vui nhộn - sắc thái của màu nguồn không xuất hiện trong chủ đề</string>\n    <string name=\"monochrome_sub\">Chủ đề đơn sắc, màu sắc hoàn toàn là đen / trắng / xám</string>\n    <string name=\"content_sub\">Một cơ chế đặt màu nguồn vào Scheme.primaryContainer</string>\n    <string name=\"fidelity_sub\">Một cơ chế rất giống với cơ chế nội dung</string>\n    <string name=\"foss_update_checker_warning\">Trình kiểm tra cập nhật này sẽ kết nối với GitHub để kiểm tra xem có bản cập nhật mới hay không</string>\n    <string name=\"attention\">Chú ý</string>\n    <string name=\"fading_edges\">Các cạnh mờ dần</string>\n    <string name=\"disabled\">Đã tắt</string>\n    <string name=\"both\">Cả hai</string>\n    <string name=\"invert_colors\">Đảo ngược màu</string>\n    <string name=\"invert_colors_sub\">Thay thế màu chủ đề thành màu âm nếu được bật</string>\n    <string name=\"search_option\">Tìm kiếm</string>\n    <string name=\"search_option_sub\">Cho phép khả năng tìm kiếm thông qua tất cả các tùy chọn có sẵn trên màn hình chính</string>\n    <string name=\"pdf_tools\">Công cụ PDF</string>\n    <string name=\"pdf_tools_sub\">Hoạt động với các tệp PDF: Xem trước, Chuyển đổi sang hàng loạt hình ảnh hoặc tạo một hình ảnh từ các hình ảnh nhất định</string>\n    <string name=\"preview_pdf\">Xem trước PDF</string>\n    <string name=\"pdf_to_images\">PDF sang hình ảnh</string>\n    <string name=\"images_to_pdf\">Hình ảnh sang PDF</string>\n    <string name=\"preview_pdf_sub\">Xem trước bản PDF đơn giản</string>\n    <string name=\"pdf_to_images_sub\">Chuyển đổi PDF thành hình ảnh ở định dạng đầu ra nhất định</string>\n    <string name=\"images_to_pdf_sub\">Đóng gói các hình ảnh đã cho vào tệp PDF đầu ra</string>\n    <string name=\"mask_filter\">Bộ lọc mặt nạ</string>\n    <string name=\"mask_filter_sub\">Áp dụng chuỗi bộ lọc lên các vùng được che phủ đã cho; mỗi vùng che phủ có thể tự xác định bộ lọc riêng của mình</string>\n    <string name=\"masks\">Mặt nạ</string>\n    <string name=\"add_mask\">Thêm mặt nạ</string>\n    <string name=\"mask_indexed\">Mặt nạ %d</string>\n    <string name=\"mask_color\">Màu mặt nạ</string>\n    <string name=\"mask_preview\">Xem trước mặt nạ</string>\n    <string name=\"mask_preview_sub\">Mặt nạ lọc đã vẽ sẽ được hiển thị để hiển thị cho bạn kết quả gần đúng</string>\n    <string name=\"inverse_fill_type\">Đảo ngược kiểu lấp đầy</string>\n    <string name=\"inverse_fill_type_sub\">Nếu được bật, tất cả các khu vực không bị che sẽ được lọc thay vì hoạt động mặc định</string>\n    <string name=\"delete_mask_warn\">Bạn sắp xóa mặt nạ lọc đã chọn. Thao tác này không thể hoàn tác được</string>\n    <string name=\"delete_mask\">Xóa mặt nạ</string>\n    <string name=\"full_filter\">Bộ lọc đầy đủ</string>\n    <string name=\"full_filter_sub\">Áp dụng bất kỳ chuỗi bộ lọc nào cho hình ảnh nhất định hoặc hình ảnh đơn lẻ</string>\n    <string name=\"start_position\">Bắt đầu</string>\n    <string name=\"center_position\">Trung tâm</string>\n    <string name=\"end_position\">Kết thúc</string>\n    <string name=\"simple_variants\">Các biến thể đơn giản</string>\n    <string name=\"highlighter\">Bút đánh dấu</string>\n    <string name=\"neon\">Neon</string>\n    <string name=\"pen\">Bút</string>\n    <string name=\"privacy_blur\">Làm mờ quyền riêng tư</string>\n    <string name=\"highlighter_sub\">Vẽ các đường tô sáng được làm sắc nét bán trong suốt</string>\n    <string name=\"neon_sub\">Thêm một số hiệu ứng phát sáng vào bản vẽ của bạn</string>\n    <string name=\"pen_sub\">Mặc định, đơn giản nhất - chỉ là màu sắc</string>\n    <string name=\"privacy_blur_sub\">Làm mờ hình ảnh theo đường dẫn đã vẽ để bảo mật mọi thứ bạn muốn ẩn</string>\n    <string name=\"pixelation_sub\">Tương tự như làm mờ quyền riêng tư, nhưng tạo pixel thay vì làm mờ</string>\n    <string name=\"containers_shadow\">Vùng chứa</string>\n    <string name=\"containers_shadow_sub\">Cho phép vẽ bóng phía sau vùng chứa</string>\n    <string name=\"sliders_shadow\">Thanh trượt</string>\n    <string name=\"switches_shadow\">Công tắc</string>\n    <string name=\"fabs_shadow\">FAB</string>\n    <string name=\"buttons_shadow\">Các nút</string>\n    <string name=\"sliders_shadow_sub\">Cho phép vẽ bóng phía sau thanh trượt</string>\n    <string name=\"switches_shadow_sub\">Cho phép vẽ bóng phía sau công tắc</string>\n    <string name=\"fabs_shadow_sub\">Cho phép vẽ bóng phía sau các nút hành động nổi</string>\n    <string name=\"buttons_shadow_sub\">Cho phép vẽ bóng phía sau các nút mặc định</string>\n    <string name=\"app_bars_shadow\">Thanh ứng dụng</string>\n    <string name=\"app_bars_shadow_sub\">Cho phép vẽ bóng phía sau thanh ứng dụng</string>\n    <string name=\"value_in_range\">Giá trị trong phạm vi %1$s - %2$s</string>\n    <string name=\"auto_rotate_limits\">Tự động xoay</string>\n    <string name=\"auto_rotate_limits_sub\">Cho phép sử dụng hộp giới hạn để định hướng hình ảnh</string>\n    <string name=\"draw_path_mode\">Chế độ vẽ đường dẫn</string>\n    <string name=\"double_line_arrow\">Mũi tên đường đôi</string>\n    <string name=\"free_drawing\">Vẽ tự do</string>\n    <string name=\"double_arrow\">Mũi tên đôi</string>\n    <string name=\"line_arrow\">Mũi tên dòng</string>\n    <string name=\"arrow\">Mũi tên</string>\n    <string name=\"line\">Dòng</string>\n    <string name=\"free_drawing_sub\">Vẽ đường dẫn làm giá trị đầu vào</string>\n    <string name=\"line_sub\">Vẽ đường đi từ điểm bắt đầu đến điểm kết thúc dưới dạng một dòng</string>\n    <string name=\"line_arrow_sub\">Vẽ mũi tên trỏ từ điểm đầu đến điểm cuối dưới dạng một dòng</string>\n    <string name=\"arrow_sub\">Vẽ mũi tên trỏ từ một đường dẫn nhất định</string>\n    <string name=\"double_line_arrow_sub\">Vẽ mũi tên chỉ kép từ điểm bắt đầu đến điểm kết thúc dưới dạng một dòng</string>\n    <string name=\"double_arrow_sub\">Vẽ mũi tên chỉ kép từ một đường dẫn nhất định</string>\n    <string name=\"outlined_oval\">Hình bầu dục có viền ngoài</string>\n    <string name=\"outlined_rect\">Hình chữ nhật được phác thảo</string>\n    <string name=\"oval\">Hình bầu dục</string>\n    <string name=\"rect\">Hình chữ nhật</string>\n    <string name=\"rect_sub\">Vẽ hình chữ nhật từ điểm đầu đến điểm cuối</string>\n    <string name=\"oval_sub\">Vẽ hình bầu dục từ điểm đầu đến điểm cuối</string>\n    <string name=\"outlined_oval_sub\">Vẽ đường viền hình bầu dục từ điểm đầu đến điểm cuối</string>\n    <string name=\"outlined_rect_sub\">Vẽ đường viền hình chữ nhật từ điểm đầu đến điểm cuối</string>\n    <string name=\"lasso\">Lasso</string>\n    <string name=\"lasso_sub\">Vẽ đường dẫn đã đóng theo đường dẫn đã cho</string>\n    <string name=\"free\">Tự do</string>\n    <string name=\"horizontal_grid\">Lưới ngang</string>\n    <string name=\"vertical_grid\">Lưới dọc</string>\n    <string name=\"stitch_mode\">Chế độ khâu</string>\n    <string name=\"rows_count\">Số hàng</string>\n    <string name=\"columns_count\">Số cột</string>\n    <string name=\"no_such_directory\">Không tìm thấy thư mục \\\"%1$s\\\" nào, chúng tôi đã chuyển nó về thư mục mặc định, vui lòng lưu lại tệp</string>\n    <string name=\"clipboard\">Clipboard</string>\n    <string name=\"auto_pin\">Tự động ghim</string>\n    <string name=\"auto_pin_sub\">Tự động thêm hình ảnh đã lưu vào clipboard nếu được bật</string>\n    <string name=\"vibration\">Rung</string>\n    <string name=\"vibration_strength\">Cường độ rung</string>\n    <string name=\"overwrite_file_requirements\">Để ghi đè lên tập tin, bạn cần sử dụng nguồn hình ảnh \\\"Explorer\\\", hãy thử chọn lại hình ảnh, chúng tôi đã thay đổi nguồn hình ảnh thành nguồn cần thiết</string>\n    <string name=\"overwrite_files\">Ghi đè tập tin</string>\n    <string name=\"overwrite_files_sub\">Tệp gốc sẽ được thay thế bằng tệp mới thay vì lưu vào thư mục đã chọn, tùy chọn này cần nguồn hình ảnh là \\\"Explorer\\\" hoặc GetContent, khi chuyển đổi tùy chọn này, nó sẽ được đặt tự động</string>\n    <string name=\"empty\">Trống</string>\n    <string name=\"suffix\">Hậu tố</string>\n    <string name=\"scale_mode\">Chế độ tỷ lệ</string>\n    <string name=\"bilinear\">Song tuyến tính</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"hermite\">Ẩn sĩ</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"nearest\">Gần nhất</string>\n    <string name=\"spline\">Đường cong</string>\n    <string name=\"basic\">Cơ bản</string>\n    <string name=\"default_value\">Giá trị mặc định</string>\n    <string name=\"bilinear_sub\">Nội suy tuyến tính (hoặc song tuyến tính, trong hai chiều) thường tốt cho việc thay đổi kích thước của hình ảnh, nhưng gây ra một số chi tiết bị mềm đi không mong muốn và vẫn có thể bị lởm chởm một chút</string>\n    <string name=\"bicubic_sub\">Các phương pháp mở rộng quy mô tốt hơn bao gồm lấy mẫu lại Lanczos và bộ lọc Mitchell-Netravali</string>\n    <string name=\"nearest_sub\">Một trong những cách tăng kích thước đơn giản hơn là thay thế từng pixel bằng một số pixel cùng màu</string>\n    <string name=\"basic_sub\">Chế độ chia tỷ lệ Android đơn giản nhất được sử dụng trong hầu hết các ứng dụng</string>\n    <string name=\"catmull_sub\">Phương pháp nội suy và lấy mẫu lại một cách trơn tru một tập hợp các điểm kiểm soát, thường được sử dụng trong đồ họa máy tính để tạo các đường cong mượt mà</string>\n    <string name=\"hann_sub\">Chức năng cửa sổ thường được áp dụng trong xử lý tín hiệu để giảm thiểu rò rỉ quang phổ và cải thiện độ chính xác của phân tích tần số bằng cách làm thon dần các cạnh của tín hiệu</string>\n    <string name=\"hermite_sub\">Kỹ thuật nội suy toán học sử dụng các giá trị và đạo hàm tại điểm cuối của một đoạn đường cong để tạo ra một đường cong trơn tru và liên tục</string>\n    <string name=\"lanczos_sub\">Phương pháp lấy mẫu lại duy trì phép nội suy chất lượng cao bằng cách áp dụng hàm chân trọng có trọng số cho các giá trị pixel</string>\n    <string name=\"mitchell_sub\">Phương pháp lấy mẫu lại sử dụng bộ lọc tích chập với các tham số có thể điều chỉnh để đạt được sự cân bằng giữa độ sắc nét và khử răng cưa trong hình ảnh được chia tỷ lệ</string>\n    <string name=\"spline_sub\">Sử dụng các hàm đa thức được xác định theo từng phần để nội suy và xấp xỉ một cách mượt mà một đường cong hoặc bề mặt, biểu diễn hình dạng linh hoạt và liên tục</string>\n    <string name=\"only_clip\">Chỉ Clip</string>\n    <string name=\"only_clip_sub\">Việc lưu vào bộ nhớ sẽ không được thực hiện và hình ảnh sẽ chỉ được cố gắng đưa vào clipboard</string>\n    <string name=\"restore_background_sub\">Brush sẽ khôi phục nền thay vì xóa</string>\n    <string name=\"recognize_text\">OCR (Nhận dạng văn bản)</string>\n    <string name=\"recognize_text_sub\">Nhận dạng văn bản từ hình ảnh nhất định, hỗ trợ hơn 120 ngôn ngữ</string>\n    <string name=\"picture_has_no_text\">Ảnh không có văn bản hoặc ứng dụng không tìm thấy nó</string>\n    <string name=\"accuracy\">Độ chính xác: %1$s</string>\n    <string name=\"recognition_type\">Loại nhận dạng</string>\n    <string name=\"fast\">Nhanh</string>\n    <string name=\"standard\">Tiêu chuẩn</string>\n    <string name=\"best\">Tốt nhất</string>\n    <string name=\"no_data\">Không có dữ liệu</string>\n    <string name=\"download_description\">Để Tesseract OCR hoạt động bình thường, dữ liệu đào tạo bổ sung (%1$s) cần được tải xuống thiết bị của bạn.\\nBạn có muốn tải xuống dữ liệu %2$s không?</string>\n    <string name=\"download\">Tải xuống</string>\n    <string name=\"no_connection\">Không có kết nối, hãy kiểm tra và thử lại để tải xuống mô hình đào tạo</string>\n    <string name=\"downloaded_languages\">Ngôn ngữ đã tải xuống</string>\n    <string name=\"available_languages\">Ngôn ngữ có sẵn</string>\n    <string name=\"segmentation_mode\">Chế độ phân đoạn</string>\n    <string name=\"use_pixel_switch\">Sử dụng Pixel Switch</string>\n    <string name=\"use_pixel_switch_sub\">Công tắc giống pixel sẽ được sử dụng thay cho tài liệu của Google mà bạn dựa trên</string>\n    <string name=\"saved_to_original\">Tệp bị ghi đè có tên %1$s tại đích ban đầu</string>\n    <string name=\"magnifier\">Kính lúp</string>\n    <string name=\"magnifier_sub\">Bật kính lúp ở đầu ngón tay trong chế độ vẽ để có khả năng truy cập tốt hơn</string>\n    <string name=\"force_exif_widget_initial_value\">Buộc giá trị ban đầu</string>\n    <string name=\"force_exif_widget_initial_value_sub\">Buộc kiểm tra tiện ích Exif ban đầu</string>\n    <string name=\"allow_multiple_languages\">Cho phép nhiều ngôn ngữ</string>\n    <string name=\"slide\">Trượt</string>\n    <string name=\"side_by_side\">Bên cạnh nhau</string>\n    <string name=\"toggle_tap\">Chuyển đổi Nhấn</string>\n    <string name=\"transparency\">Trong suốt</string>\n    <string name=\"rate_app\">Xếp hạng ứng dụng</string>\n    <string name=\"rate\">Xếp hạng</string>\n    <string name=\"rate_app_sub\">Ứng dụng này hoàn toàn miễn phí, nếu bạn muốn nó lớn mạnh, hãy đánh dấu sao cho dự án trên Github 😄</string>\n    <string name=\"segmentation_mode_osd_only\">Định hướng &amp; Chỉ phát hiện tập lệnh</string>\n    <string name=\"segmentation_mode_auto_osd\">Tự động định hướng &amp; Phát hiện tập lệnh</string>\n    <string name=\"segmentation_mode_auto_only\">Chỉ tự động</string>\n    <string name=\"segmentation_mode_auto\">Tự động</string>\n    <string name=\"segmentation_mode_single_column\">Cột đơn</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">Văn bản dọc khối đơn</string>\n    <string name=\"segmentation_mode_single_block\">Khối đơn</string>\n    <string name=\"segmentation_mode_single_line\">Dòng đơn</string>\n    <string name=\"segmentation_mode_single_word\">Từ đơn</string>\n    <string name=\"segmentation_mode_circle_word\">Vòng tròn từ</string>\n    <string name=\"segmentation_mode_single_char\">Ký tự đơn</string>\n    <string name=\"segmentation_mode_sparse_text\">Văn bản thưa thớt</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">Định hướng văn bản thưa thớt &amp; Phát hiện tập lệnh</string>\n    <string name=\"segmentation_mode_raw_line\">Dòng thô</string>\n    <string name=\"delete_language_sub\">Bạn muốn xóa dữ liệu đào tạo OCR ngôn ngữ \\\"%1$s\\\" cho tất cả các loại nhận dạng hay chỉ cho một loại đã chọn (%2$s)?</string>\n    <string name=\"current\">Hiện tại</string>\n    <string name=\"all\">Tất cả</string>\n    <string name=\"gradient_maker\">Trình tạo chuyển màu</string>\n    <string name=\"gradient_maker_sub\">Tạo độ dốc của kích thước đầu ra nhất định với màu sắc và kiểu hiển thị tùy chỉnh</string>\n    <string name=\"gradient_type_linear\">Tuyến tính</string>\n    <string name=\"gradient_type_radial\">Bán kính</string>\n    <string name=\"gradient_type_sweep\">Quét</string>\n    <string name=\"gradient_type\">Loại chuyển màu</string>\n    <string name=\"center_x\">Trung tâm X</string>\n    <string name=\"center_y\">Trung tâm Y</string>\n    <string name=\"tile_mode\">Chế độ xếp ô</string>\n    <string name=\"tile_mode_repeated\">Đã lặp lại</string>\n    <string name=\"tile_mode_mirror\">Gương</string>\n    <string name=\"tile_mode_clamp\">Kẹp</string>\n    <string name=\"tile_mode_decal\">Đề can</string>\n    <string name=\"color_stops\">Điểm dừng màu</string>\n    <string name=\"add_color\">Thêm màu</string>\n    <string name=\"properties\">Thuộc tính</string>\n    <string name=\"brightness_enforcement\">Thực thi độ sáng</string>\n    <string name=\"screen\">Màn hình</string>\n    <string name=\"gradient_maker_type_image\">Lớp phủ chuyển màu</string>\n    <string name=\"gradient_maker_type_image_sub\">Soạn bất kỳ độ dốc nào ở trên cùng của hình ảnh đã cho</string>\n    <string name=\"transformations\">Sự biến đổi</string>\n    <string name=\"camera\">Máy ảnh</string>\n    <string name=\"camera_sub\">Sử dụng camera để chụp ảnh, lưu ý rằng chỉ có thể lấy một hình ảnh từ nguồn hình ảnh này</string>\n    <string name=\"watermarking\">Watermark</string>\n    <string name=\"watermarking_sub\">Che ảnh bằng watermark văn bản/hình ảnh có thể tùy chỉnh</string>\n    <string name=\"repeat_watermark\">Lặp lại watermark</string>\n    <string name=\"repeat_watermark_sub\">Lặp lại watermark trên hình ảnh thay vì một watermark ở vị trí nhất định</string>\n    <string name=\"offset_x\">Bù đắp X</string>\n    <string name=\"offset_y\">Bù đắp Y</string>\n    <string name=\"watermark_type\">Loại watermark</string>\n    <string name=\"watermarking_image_sub\">Hình ảnh này sẽ được sử dụng làm mẫu cho watermark</string>\n    <string name=\"text_color\">Màu văn bản</string>\n    <string name=\"overlay_mode\">Chế độ lớp phủ</string>\n    <string name=\"gif_tools\">Công cụ GIF</string>\n    <string name=\"gif_tools_sub\">Chuyển đổi hình ảnh thành ảnh GIF hoặc trích xuất khung hình từ ảnh GIF đã cho</string>\n    <string name=\"gif_type_to_image\">GIF thành hình ảnh</string>\n    <string name=\"gif_type_to_image_sub\">Chuyển đổi tập tin GIF thành hàng loạt ảnh</string>\n    <string name=\"gif_type_to_gif_sub\">Chuyển đổi hàng loạt hình ảnh thành tệp GIF</string>\n    <string name=\"gif_type_to_gif\">Hình ảnh thành GIF</string>\n    <string name=\"select_gif_image_to_start\">Chọn ảnh GIF để bắt đầu</string>\n    <string name=\"use_size_of_first_frame\">Sử dụng kích thước của khung hình đầu tiên</string>\n    <string name=\"use_size_of_first_frame_sub\">Thay thế kích thước được chỉ định bằng kích thước khung đầu tiên</string>\n    <string name=\"repeat_count\">Số lần lặp lại</string>\n    <string name=\"frame_delay\">Độ trễ khung hình</string>\n    <string name=\"millis\">mili giây</string>\n    <string name=\"fps\">FPS</string>\n    <string name=\"use_lasso\">Sử dụng Lasso</string>\n    <string name=\"use_lasso_sub\">Sử dụng Lasso giống như trong chế độ vẽ để thực hiện xóa</string>\n    <string name=\"original_image_preview_alpha\">Bản xem trước ảnh gốc Alpha</string>\n    <string name=\"confetti\">Hoa giấy</string>\n    <string name=\"confetti_sub\">Hoa giấy sẽ được hiển thị khi lưu, chia sẻ và các hành động chính khác</string>\n    <string name=\"secure_mode\">Chế độ bảo mật</string>\n    <string name=\"secure_mode_sub\">Ẩn nội dung khi thoát, đồng thời không thể chụp hoặc ghi lại màn hình</string>\n    <string name=\"exit\">Thoát</string>\n    <string name=\"preview_closing\">Nếu bây giờ bạn để chế độ xem trước, bạn sẽ cần thêm lại hình ảnh</string>\n    <string name=\"dithering\">Phối màu</string>\n    <string name=\"quantizier\">Bộ lượng tử hóa</string>\n    <string name=\"gray_scale\">Thang màu xám</string>\n    <string name=\"bayer_two_dithering\">Phối màu Bayer Two By Two</string>\n    <string name=\"bayer_three_dithering\">Phối màu Bayer Three By Three</string>\n    <string name=\"bayer_four_dithering\">Phối màu Bayer Four By Four</string>\n    <string name=\"bayer_eight_dithering\">Phối màu Bayer Eight By Eight</string>\n    <string name=\"floyd_steinberg_dithering\">Phối màu Floyd Steinberg</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Phối màu Jarvis Judice Ninke</string>\n    <string name=\"sierra_dithering\">Phối màu Sierra</string>\n    <string name=\"two_row_sierra_dithering\">Phối màu Two Row Sierra</string>\n    <string name=\"sierra_lite_dithering\">Phối màu Sierra Lite</string>\n    <string name=\"atkinson_dithering\">Phối màu Atkinson</string>\n    <string name=\"stucki_dithering\">Phối màu Stucki</string>\n    <string name=\"burkes_dithering\">Phối màu Burkes</string>\n    <string name=\"false_floyd_steinberg_dithering\">Phối màu False Floyd Steinberg</string>\n    <string name=\"left_to_right_dithering\">Phối màu Left To Right</string>\n    <string name=\"random_dithering\">Phối màu Random</string>\n    <string name=\"simple_threshold_dithering\">Phối màu Simple Threshold</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">Sigma không gian</string>\n    <string name=\"median_blur\">Độ mờ trung bình</string>\n    <string name=\"b_spline\">Đường trục B</string>\n    <string name=\"b_spline_sub\">Sử dụng các hàm đa thức hai khối được xác định từng phần để nội suy và xấp xỉ một cách mượt mà một đường cong hoặc bề mặt, biểu diễn hình dạng linh hoạt và liên tục</string>\n    <string name=\"native_stack_blur\">Làm mờ ngăn xếp gốc</string>\n    <string name=\"tilt_shift\">Dịch chuyển nghiêng</string>\n    <string name=\"glitch\">Trục trặc</string>\n    <string name=\"amount\">Số lượng</string>\n    <string name=\"seed\">Hạt giống</string>\n    <string name=\"anaglyph\">Anaglyph</string>\n    <string name=\"noise\">Tiếng ồn</string>\n    <string name=\"pixel_sort\">Sắp xếp pixel</string>\n    <string name=\"shuffle\">Xáo trộn</string>\n    <string name=\"enhanced_glitch\">Trục trặc nâng cao</string>\n    <string name=\"channel_shift_x\">Dịch chuyển kênh X</string>\n    <string name=\"channel_shift_y\">Dịch chuyển kênh Y</string>\n    <string name=\"corruption_size\">Kích thước sai lệch</string>\n    <string name=\"corruption_shift_x\">Dịch chuyển sai lệch X</string>\n    <string name=\"corruption_shift_y\">Dịch chuyển sai lệch Y</string>\n    <string name=\"tent_blur\">Lều mờ</string>\n    <string name=\"side_fade\">Làm mờ bên</string>\n    <string name=\"side\">Bên</string>\n    <string name=\"top\">Trên đầu</string>\n    <string name=\"bottom\">Dưới cùng</string>\n    <string name=\"strength\">Cường độ</string>\n    <string name=\"erode\">Bào mòn</string>\n    <string name=\"anisotropic_diffusion\">Khuếch tán dị hướng</string>\n    <string name=\"diffusion\">Khuếch tán</string>\n    <string name=\"conduction\">Truyền dẫn</string>\n    <string name=\"horizontal_wind_stagger\">Gió giật ngang</string>\n    <string name=\"fast_bilaterial_blur\">Làm mờ song phương nhanh</string>\n    <string name=\"poisson_blur\">Làm mờ Poisson</string>\n    <string name=\"logarithmic_tone_mapping\">Ánh xạ giai điệu logarit</string>\n    <string name=\"aces_filmic_tone_mapping\">Ánh xạ giai điệu phim ACES</string>\n    <string name=\"crystallize\">Kết tinh</string>\n    <string name=\"stroke_color\">Màu nét</string>\n    <string name=\"fractal_glass\">Kính Fractal</string>\n    <string name=\"amplitude\">Biên độ</string>\n    <string name=\"marble\">Đá cẩm thạch</string>\n    <string name=\"turbulence\">Sự hỗn loạn</string>\n    <string name=\"oil\">Dầu</string>\n    <string name=\"water_effect\">Hiệu ứng nước</string>\n    <string name=\"just_size\">Kích thước</string>\n    <string name=\"frequency_x\">Tần số X</string>\n    <string name=\"frequency_y\">Tần số Y</string>\n    <string name=\"amplitude_x\">Biên độ X</string>\n    <string name=\"amplitude_y\">Biên độ Y</string>\n    <string name=\"perlin_distortion\">Biến dạng Perlin</string>\n    <string name=\"aces_hill_tone_mapping\">Bản đồ giai điệu đồi ACES</string>\n    <string name=\"hable_filmic_tone_mapping\">Bản đồ giai điệu phim Hable</string>\n    <string name=\"heji_burgess_tone_mapping\">Bản đồ giai điệu Hejl Burgess</string>\n    <string name=\"speed\">Tốc độ</string>\n    <string name=\"dehaze\">Khử khói</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_4x4\">Ma trận màu 4x4</string>\n    <string name=\"color_matrix_3x3\">Ma trận màu 3x3</string>\n    <string name=\"simple_effects\">Hiệu ứng đơn giản</string>\n    <string name=\"polaroid\">Polaroid</string>\n    <string name=\"tritonomaly\">Tritonomaly</string>\n    <string name=\"deutaromaly\">Deutaromaly</string>\n    <string name=\"protonomaly\">Protonomaly</string>\n    <string name=\"vintage\">Cổ điển</string>\n    <string name=\"browni\">Browni</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">Tầm nhìn ban đêm</string>\n    <string name=\"warm\">Ấm</string>\n    <string name=\"cool\">Lạnh</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"deutaronotopia\">Deutaronotopia</string>\n    <string name=\"protanopia\">Protanopia</string>\n    <string name=\"achromatomaly\">Bệnh sắc tố</string>\n    <string name=\"achromatopsia\">Achromatopsia</string>\n    <string name=\"grain\">Ngũ cốc</string>\n    <string name=\"unsharp\">Không sắc nét</string>\n    <string name=\"pastel\">Phấn màu</string>\n    <string name=\"orange_haze\">Sương mù màu cam</string>\n    <string name=\"pink_dream\">Giấc mơ hồng</string>\n    <string name=\"golden_hour\">Giờ vàng</string>\n    <string name=\"hot_summer\">Mùa hè nóng nực</string>\n    <string name=\"purple_mist\">Sương tím</string>\n    <string name=\"sunrise\">Bình minh</string>\n    <string name=\"colorful_swirl\">Vòng xoáy đầy màu sắc</string>\n    <string name=\"soft_spring_light\">Ánh Xuân êm dịu</string>\n    <string name=\"autumn_tones\">Giai điệu mùa thu</string>\n    <string name=\"lavender_dream\">Giấc mơ hoa oải hương</string>\n    <string name=\"cyberpunk\">Cyberpunk</string>\n    <string name=\"lemonade_light\">Nước chanh nhẹ</string>\n    <string name=\"spectral_fire\">Ngọn lửa quang phổ</string>\n    <string name=\"night_magic\">Phép thuật bóng đêm</string>\n    <string name=\"fantasy_landscape\">Phong cảnh huyền ảo</string>\n    <string name=\"color_explosion\">Bùng nổ màu sắc</string>\n    <string name=\"electric_gradient\">Độ dốc điện</string>\n    <string name=\"caramel_darkness\">Bóng tối caramel</string>\n    <string name=\"futuristic_gradient\">Độ dốc tương lai</string>\n    <string name=\"green_sun\">Mặt Trời Xanh</string>\n    <string name=\"rainbow_world\">Thế giới cầu vồng</string>\n    <string name=\"deep_purple\">Màu tím đậm</string>\n    <string name=\"space_portal\">Cổng không gian</string>\n    <string name=\"red_swirl\">Vòng xoáy đỏ</string>\n    <string name=\"digital_code\">Mã kỹ thuật số</string>\n    <string name=\"bokeh\">Hiệu ứng mờ</string>\n    <string name=\"random_emojis_sub\">Biểu tượng cảm xúc trên thanh ứng dụng sẽ liên tục được thay đổi ngẫu nhiên thay vì sử dụng biểu tượng đã chọn</string>\n    <string name=\"random_emojis\">Biểu tượng cảm xúc ngẫu nhiên</string>\n    <string name=\"random_emojis_error\">Không thể sử dụng tính năng chọn biểu tượng cảm xúc ngẫu nhiên khi biểu tượng cảm xúc bị tắt</string>\n    <string name=\"emoji_selection_error\">Không thể chọn biểu tượng cảm xúc trong khi chọn biểu tượng cảm xúc ngẫu nhiên đã bật</string>\n    <string name=\"old_tv\">Tivi cũ</string>\n    <string name=\"shuffle_blur\">Làm mờ ngẫu nhiên</string>\n    <string name=\"favorite\">Yêu thích</string>\n    <string name=\"no_favorite_filters\">Chưa có bộ lọc yêu thích nào được thêm vào</string>\n    <string name=\"image_format\">Định dạng hình ảnh</string>\n    <string name=\"icon_shape_sub\">Thêm vùng chứa có hình dạng đã chọn bên dưới các biểu tượng hàng đầu của thẻ</string>\n    <string name=\"icon_shape\">Hình dạng biểu tượng</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"cutoff\">Cutoff</string>\n    <string name=\"uchimura\">Uchimura</string>\n    <string name=\"mobius\">Mobius</string>\n    <string name=\"transition\">Chuyển tiếp</string>\n    <string name=\"peak\">Đỉnh</string>\n    <string name=\"color_anomaly\">Màu sắc bất thường</string>\n    <string name=\"images_overwritten\">Hình ảnh bị ghi đè ở đích ban đầu</string>\n    <string name=\"cannot_change_image_format\">Không thể thay đổi định dạng hình ảnh khi bật tùy chọn ghi đè tệp</string>\n    <string name=\"emoji_as_color_scheme\">Biểu tượng cảm xúc dưới dạng bảng màu</string>\n    <string name=\"emoji_as_color_scheme_sub\">Sử dụng màu chính của biểu tượng cảm xúc làm bảng màu ứng dụng thay vì màu được xác định thủ công</string>\n    <string name=\"material_you_sub\">Tạo bảng màu Material You từ hình ảnh</string>\n    <string name=\"dark_colors\">Màu tối</string>\n    <string name=\"dark_colors_sub\">Sử dụng bảng màu của chế độ ban đêm thay vì biến thể sáng</string>\n    <string name=\"copy_as_compose_code\">Sao chép dưới dạng Jetpack Soạn mã</string>\n    <string name=\"ring_blur\">Làm mờ vòng</string>\n    <string name=\"cross_blur\">Làm mờ chéo</string>\n    <string name=\"circle_blur\">Làm mờ vòng tròn</string>\n    <string name=\"star_blur\">Sao mờ</string>\n    <string name=\"linear_tilt_shift\">Dịch chuyển nghiêng tuyến tính</string>\n    <string name=\"tags_to_remove\">Thẻ cần xóa</string>\n    <string name=\"apng_tools\">Công cụ APNG</string>\n    <string name=\"apng_tools_sub\">Chuyển đổi hình ảnh thành ảnh APNG hoặc trích xuất khung hình từ hình ảnh APNG đã cho</string>\n    <string name=\"apng_type_to_image\">APNG vào hình ảnh</string>\n    <string name=\"apng_type_to_image_sub\">Chuyển đổi tập tin APNG thành hàng loạt ảnh</string>\n    <string name=\"apng_type_to_apng_sub\">Chuyển đổi hàng loạt hình ảnh sang tệp APNG</string>\n    <string name=\"apng_type_to_apng\">Hình ảnh sang APNG</string>\n    <string name=\"select_apng_image_to_start\">Chọn hình ảnh APNG để bắt đầu</string>\n    <string name=\"motion_blur\">Làm mờ chuyển động</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">Tạo tệp Zip từ các tệp hoặc hình ảnh nhất định</string>\n    <string name=\"drag_handle_width\">Chiều rộng tay cầm kéo</string>\n    <string name=\"confetti_type\">Loại hoa giấy</string>\n    <string name=\"festive\">Lễ hội</string>\n    <string name=\"explode\">Nổ tung</string>\n    <string name=\"rain\">Mưa</string>\n    <string name=\"corners\">Các góc</string>\n    <string name=\"jxl_tools\">Công cụ JXL</string>\n    <string name=\"jxl_tools_sub\">Thực hiện chuyển mã JXL ~ JPEG mà không làm giảm chất lượng hoặc chuyển đổi hoạt ảnh GIF/APNG sang JXL</string>\n    <string name=\"jxl_type_to_jpeg\">JXL sang JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">Thực hiện chuyển mã không mất dữ liệu từ JXL sang JPEG</string>\n    <string name=\"jpeg_type_to_jxl_sub\">Thực hiện chuyển mã không mất dữ liệu từ JPEG sang JXL</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG sang JXL</string>\n    <string name=\"select_jxl_image_to_start\">Chọn hình ảnh JXL để bắt đầu</string>\n    <string name=\"fast_gaussian_blur_2d\">Làm mờ Gaussian nhanh 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">Làm mờ Gaussian nhanh 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">Làm mờ Gaussian nhanh 4D</string>\n    <string name=\"auto_paste\">Tự động dán</string>\n    <string name=\"auto_paste_sub\">Cho phép ứng dụng tự động dán dữ liệu clipboard để nó sẽ xuất hiện trên màn hình chính và bạn có thể xử lý nó</string>\n    <string name=\"harmonization_color\">Màu hài hòa</string>\n    <string name=\"harmonization_level\">Mức độ hài hòa</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"lanczos_bessel_sub\">Phương pháp lấy mẫu lại duy trì phép nội suy chất lượng cao bằng cách áp dụng hàm Bessel (jinc) cho các giá trị pixel</string>\n    <string name=\"gif_type_to_jxl\">GIF sang JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">Chuyển đổi ảnh GIF thành ảnh động JXL</string>\n    <string name=\"apng_type_to_jxl\">APNG tới JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">Chuyển đổi hình ảnh APNG thành hình ảnh động JXL</string>\n    <string name=\"jxl_type_to_images\">JXL sang hình ảnh</string>\n    <string name=\"jxl_type_to_images_sub\">Chuyển đổi hình ảnh động JXL thành hàng loạt hình ảnh</string>\n    <string name=\"jxl_type_to_jxl\">Hình ảnh tới JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">Chuyển đổi hàng loạt hình ảnh sang hoạt hình JXL</string>\n    <string name=\"behavior\">Hành vi</string>\n    <string name=\"skip_file_picking\">Bỏ qua việc chọn tập tin</string>\n    <string name=\"skip_file_picking_sub\">Bộ chọn tệp sẽ được hiển thị ngay lập tức nếu có thể trên màn hình đã chọn</string>\n    <string name=\"generate_previews\">Tạo bản xem trước</string>\n    <string name=\"generate_previews_sub\">Cho phép tạo bản xem trước, điều này có thể giúp tránh sự cố trên một số thiết bị, điều này cũng vô hiệu hóa một số chức năng chỉnh sửa trong tùy chọn chỉnh sửa duy nhất</string>\n    <string name=\"lossy_compression\">Nén mất mát</string>\n    <string name=\"lossy_compression_sub\">Sử dụng tính năng nén có mất dữ liệu để giảm kích thước tệp thay vì không mất dữ liệu</string>\n    <string name=\"compression_type\">Kiểu nén</string>\n    <string name=\"speed_sub\">Kiểm soát tốc độ giải mã hình ảnh thu được, điều này sẽ giúp mở hình ảnh thu được nhanh hơn, giá trị %1$s có nghĩa là giải mã chậm nhất, trong khi %2$s - nhanh nhất, cài đặt này có thể tăng kích thước hình ảnh đầu ra</string>\n    <string name=\"sorting\">Sắp xếp</string>\n    <string name=\"sort_by_date\">Sắp xếp theo ngày</string>\n    <string name=\"sort_by_date_reversed\">Sắp xếp theo ngày (Đảo ngược)</string>\n    <string name=\"sort_by_name\">Sắp xếp theo tên</string>\n    <string name=\"sort_by_name_reversed\">Sắp xếp theo tên (Đảo ngược)</string>\n    <string name=\"channels_configuration\">Cấu hình kênh</string>\n    <string name=\"header_today\">Hôm nay</string>\n    <string name=\"header_yesterday\">Hôm qua</string>\n    <string name=\"embedded_picker\">Bộ chọn nhúng</string>\n    <string name=\"embedded_picker_sub\">Sử dụng bộ chọn hình ảnh riêng của Hộp công cụ Hình ảnh thay vì bộ chọn hình ảnh được hệ thống xác định trước</string>\n    <string name=\"no_permissions\">Không có quyền</string>\n    <string name=\"request\">Yêu cầu</string>\n    <string name=\"pick_multiple_media\">Chọn nhiều phương tiện</string>\n    <string name=\"pick_single_media\">Chọn một phương tiện</string>\n    <string name=\"pick\">Chọn</string>\n    <string name=\"try_again\">Thử lại</string>\n    <string name=\"show_settings_in_landscape\">Hiển thị cài đặt theo chiều ngang</string>\n    <string name=\"show_settings_in_landscape_sub\">Nếu tính năng này bị tắt thì cài đặt ở chế độ ngang sẽ được mở trên nút ở thanh ứng dụng trên cùng như mọi khi, thay vì tùy chọn hiển thị vĩnh viễn</string>\n    <string name=\"fullscreen_settings\">Cài đặt toàn màn hình</string>\n    <string name=\"fullscreen_settings_sub\">Kích hoạt nó và trang cài đặt sẽ luôn được mở ở dạng toàn màn hình thay vì trang ngăn kéo có thể trượt</string>\n    <string name=\"switch_type\">Loại chuyển đổi</string>\n    <string name=\"compose\">Soạn</string>\n    <string name=\"compose_switch_sub\">Sử dụng tài liệu Jetpack Compose mà bạn chuyển đổi, nó không đẹp bằng chế độ xem</string>\n    <string name=\"material_you_switch_sub\">Sử dụng tài liệu dựa trên Chế độ xem mà bạn chuyển đổi, tài liệu này trông đẹp hơn những tài liệu khác và có hình ảnh động đẹp mắt</string>\n    <string name=\"max\">Tối đa</string>\n    <string name=\"resize_anchor\">Thay đổi kích thước mẩu neo</string>\n    <string name=\"pixel_switch\">Điểm ảnh</string>\n    <string name=\"fluent_switch\">Thông thạo</string>\n    <string name=\"fluent_switch_sub\">Sử dụng công tắc kiểu Windows 11 dựa trên hệ thống thiết kế \\\"Fluent\\\"</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">Một công tắc dựa trên hệ thống thiết kế \\\"Cupertino\\\"</string>\n    <string name=\"images_to_svg\">Hình ảnh thành SVG</string>\n    <string name=\"images_to_svg_sub\">Theo dõi hình ảnh đã cho thành hình ảnh SVG</string>\n    <string name=\"use_sampled_palette\">Sử dụng Bảng màu được lấy mẫu</string>\n    <string name=\"use_sampled_palette_sub\">Bảng lượng tử hóa sẽ được lấy mẫu nếu tùy chọn này được bật</string>\n    <string name=\"path_omit\">Bỏ qua đường dẫn</string>\n    <string name=\"svg_warning\">Không nên sử dụng công cụ này để theo dõi các hình ảnh lớn mà không thu nhỏ kích thước, nó có thể gây ra sự cố và tăng thời gian xử lý</string>\n    <string name=\"downscale_image\">Thu nhỏ hình ảnh</string>\n    <string name=\"downscale_image_sub\">Hình ảnh sẽ được giảm kích thước xuống kích thước thấp hơn trước khi xử lý, điều này giúp công cụ hoạt động nhanh hơn và an toàn hơn</string>\n    <string name=\"min_color_ratio\">Tỷ lệ màu tối thiểu</string>\n    <string name=\"lines_threshold\">Ngưỡng dòng</string>\n    <string name=\"quadratic_threshold\">Ngưỡng bậc hai</string>\n    <string name=\"coordinates_rounding_tolerance\">Dung sai làm tròn tọa độ</string>\n    <string name=\"path_scale\">Tỷ lệ đường dẫn</string>\n    <string name=\"reset_properties\">Đặt lại thuộc tính</string>\n    <string name=\"reset_properties_sub\">Tất cả các thuộc tính sẽ được đặt thành giá trị mặc định, lưu ý rằng hành động này không thể hoàn tác</string>\n    <string name=\"detailed\">Chi tiết</string>\n    <string name=\"default_line_width\">Độ rộng dòng mặc định</string>\n    <string name=\"engine_mode\">Chế độ động cơ</string>\n    <string name=\"legacy\">Di sản</string>\n    <string name=\"lstm_network\">Mạng LSTM</string>\n    <string name=\"legacy_and_lstm\">Legacy &amp; LSTM</string>\n    <string name=\"convert\">Chuyển đổi</string>\n    <string name=\"convert_sub\">Chuyển đổi hàng loạt hình ảnh sang định dạng nhất định</string>\n    <string name=\"add_new_folder\">Thêm thư mục mới</string>\n    <string name=\"tag_bits_per_sample\">Số bit trên mỗi mẫu</string>\n    <string name=\"tag_compression\">Nén</string>\n    <string name=\"tag_photometric_interpretation\">Giải thích trắc quang</string>\n    <string name=\"tag_samples_per_pixel\">Mẫu trên mỗi pixel</string>\n    <string name=\"tag_planar_configuration\">Cấu hình phẳng</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Lấy mẫu phụ Y Cb Cr</string>\n    <string name=\"tag_y_cb_cr_positioning\">Định vị Y Cb Cr</string>\n    <string name=\"tag_x_resolution\">Độ phân giải X</string>\n    <string name=\"tag_y_resolution\">Độ phân giải Y</string>\n    <string name=\"tag_resolution_unit\">Đơn vị độ phân giải</string>\n    <string name=\"tag_strip_offsets\">Dải bù trừ</string>\n    <string name=\"tag_rows_per_strip\">Hàng trên mỗi dải</string>\n    <string name=\"tag_strip_byte_counts\">Loại bỏ số byte</string>\n    <string name=\"tag_jpeg_interchange_format\">Định dạng trao đổi JPEG</string>\n    <string name=\"tag_jpeg_interchange_format_length\">Độ dài định dạng trao đổi JPEG</string>\n    <string name=\"tag_transfer_function\">Hàm truyền</string>\n    <string name=\"tag_white_point\">Điểm trắng</string>\n    <string name=\"tag_primary_chromaticities\">Màu sắc cơ bản</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Hệ số Y Cb Cr</string>\n    <string name=\"tag_reference_black_white\">Tham khảo Đen Trắng</string>\n    <string name=\"tag_datetime\">Ngày Giờ</string>\n    <string name=\"tag_image_description\">Mô tả hình ảnh</string>\n    <string name=\"tag_make\">Cấu tạo</string>\n    <string name=\"tag_model\">Người mẫu</string>\n    <string name=\"tag_software\">Phần mềm</string>\n    <string name=\"tag_artist\">Nghệ sĩ</string>\n    <string name=\"tag_copyright\">Bản quyền</string>\n    <string name=\"tag_exif_version\">Phiên bản Exif</string>\n    <string name=\"tag_flashpix_version\">Phiên bản Flashpix</string>\n    <string name=\"tag_color_space\">Không gian màu</string>\n    <string name=\"tag_gamma\">Gamma</string>\n    <string name=\"tag_pixel_x_dimension\">Kích thước pixel X</string>\n    <string name=\"tag_pixel_y_dimension\">Kích thước pixel Y</string>\n    <string name=\"tag_compressed_bits_per_pixel\">Số bit được nén trên mỗi pixel</string>\n    <string name=\"tag_maker_note\">Ghi chú của nhà sản xuất</string>\n    <string name=\"tag_user_comment\">Bình luận của người dùng</string>\n    <string name=\"tag_related_sound_file\">Tệp âm thanh liên quan</string>\n    <string name=\"tag_datetime_original\">Ngày Giờ Bản gốc</string>\n    <string name=\"tag_datetime_digitized\">Ngày Giờ Số hóa</string>\n    <string name=\"tag_offset_time\">Thời gian bù trừ</string>\n    <string name=\"tag_offset_time_original\">Thời gian bù trừ gốc</string>\n    <string name=\"tag_offset_time_digitized\">Số hóa thời gian bù trừ</string>\n    <string name=\"tag_subsec_time\">Thời gian phụ giây</string>\n    <string name=\"tag_subsec_time_original\">Thời gian phụ giây gốc</string>\n    <string name=\"tag_subsec_time_digitized\">Số giây phụ Thời gian được số hóa</string>\n    <string name=\"tag_exposure_time\">Thời gian phơi sáng</string>\n    <string name=\"tag_f_number\">Số F</string>\n    <string name=\"tag_exposure_program\">Chương trình tiếp xúc</string>\n    <string name=\"tag_spectral_sensitivity\">Độ nhạy quang phổ</string>\n    <string name=\"tag_photographic_sensitivity\">Độ nhạy chụp ảnh</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_sensitivity_type\">Loại độ nhạy</string>\n    <string name=\"tag_standard_output_sensitivity\">Độ nhạy đầu ra tiêu chuẩn</string>\n    <string name=\"tag_recommended_exposure_index\">Chỉ số phơi nhiễm được đề xuất</string>\n    <string name=\"tag_iso_speed\">Tốc độ ISO</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">Vĩ độ tốc độ ISO yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">Vĩ độ tốc độ ISO zzz</string>\n    <string name=\"tag_shutter_speed_value\">Giá trị tốc độ màn trập</string>\n    <string name=\"tag_aperture_value\">Giá trị khẩu độ</string>\n    <string name=\"tag_brightness_value\">Giá trị độ sáng</string>\n    <string name=\"tag_exposure_bias_value\">Giá trị thiên vị phơi sáng</string>\n    <string name=\"tag_max_aperture_value\">Giá trị khẩu độ tối đa</string>\n    <string name=\"tag_subject_distance\">Khoảng cách chủ đề</string>\n    <string name=\"tag_metering_mode\">Chế độ đo sáng</string>\n    <string name=\"tag_flash\">Flash</string>\n    <string name=\"tag_subject_area\">Lĩnh vực chủ đề</string>\n    <string name=\"tag_focal_length\">Tiêu cự</string>\n    <string name=\"tag_flash_energy\">Năng lượng chớp nhoáng</string>\n    <string name=\"tag_spatial_frequency_response\">Đáp ứng tần số không gian</string>\n    <string name=\"tag_focal_plane_x_resolution\">Độ phân giải mặt phẳng tiêu điểm X</string>\n    <string name=\"tag_focal_plane_y_resolution\">Độ phân giải mặt phẳng tiêu điểm Y</string>\n    <string name=\"tag_focal_plane_resolution_unit\">Đơn vị độ phân giải mặt phẳng tiêu điểm</string>\n    <string name=\"tag_subject_location\">Vị trí chủ đề</string>\n    <string name=\"tag_exposure_index\">Chỉ số phơi nhiễm</string>\n    <string name=\"tag_sensing_method\">Phương pháp cảm biến</string>\n    <string name=\"tag_file_source\">Nguồn tập tin</string>\n    <string name=\"tag_cfa_pattern\">Mẫu CFA</string>\n    <string name=\"tag_custom_rendered\">Hiển thị tùy chỉnh</string>\n    <string name=\"tag_exposure_mode\">Chế độ phơi sáng</string>\n    <string name=\"tag_white_balance\">Cân bằng trắng</string>\n    <string name=\"tag_digital_zoom_ratio\">Tỷ lệ thu phóng kỹ thuật số</string>\n    <string name=\"tag_focal_length_in_35mm_film\">Tiêu cự phim 35mm</string>\n    <string name=\"tag_scene_capture_type\">Kiểu chụp cảnh</string>\n    <string name=\"tag_gain_control\">Giành quyền kiểm soát</string>\n    <string name=\"tag_contrast\">Độ tương phản</string>\n    <string name=\"tag_saturation\">Độ bão hòa</string>\n    <string name=\"tag_sharpness\">Độ sắc nét</string>\n    <string name=\"tag_device_setting_description\">Mô tả thiết đặt thiết bị</string>\n    <string name=\"tag_subject_distance_range\">Phạm vi khoảng cách chủ thể</string>\n    <string name=\"tag_image_unique_id\">ID duy nhất của hình ảnh</string>\n    <string name=\"tag_camera_owner_name\">Tên chủ sở hữu máy ảnh</string>\n    <string name=\"tag_body_serial_number\">Số sê-ri cơ thể</string>\n    <string name=\"tag_lens_specification\">Thông số ống kính</string>\n    <string name=\"tag_lens_make\">Cấu tạo ống kính</string>\n    <string name=\"tag_lens_model\">Mẫu ống kính</string>\n    <string name=\"tag_lens_serial_number\">Số sê-ri ống kính</string>\n    <string name=\"tag_gps_version_id\">ID phiên bản GPS</string>\n    <string name=\"tag_gps_latitude_ref\">Tham chiếu Vĩ độ GPS</string>\n    <string name=\"tag_gps_latitude\">Vĩ độ GPS</string>\n    <string name=\"tag_gps_longitude_ref\">Tham chiếu kinh độ GPS</string>\n    <string name=\"tag_gps_longitude\">Kinh độ GPS</string>\n    <string name=\"tag_gps_altitude_ref\">Tham chiếu độ cao GPS</string>\n    <string name=\"tag_gps_altitude\">Độ cao GPS</string>\n    <string name=\"tag_gps_timestamp\">Dấu thời gian GPS</string>\n    <string name=\"tag_gps_satellites\">Vệ tinh GPS</string>\n    <string name=\"tag_gps_status\">Trạng thái GPS</string>\n    <string name=\"tag_gps_measure_mode\">Chế độ đo GPS</string>\n    <string name=\"tag_gps_dop\">DOP GPS</string>\n    <string name=\"tag_gps_speed_ref\">Tham chiếu tốc độ GPS</string>\n    <string name=\"tag_gps_speed\">Tốc độ GPS</string>\n    <string name=\"tag_gps_track_ref\">Tham chiếu đường đi GPS</string>\n    <string name=\"tag_gps_track\">Đường đi GPS</string>\n    <string name=\"tag_gps_img_direction_ref\">Tham chiếu hướng hình ảnh GPS</string>\n    <string name=\"tag_gps_img_direction\">Hướng hình ảnh GPS</string>\n    <string name=\"tag_gps_map_datum\">Dữ liệu bản đồ GPS</string>\n    <string name=\"tag_gps_dest_latitude_ref\">Tham chiếu Vĩ độ Đích GPS</string>\n    <string name=\"tag_gps_dest_latitude\">Vĩ độ đích của GPS</string>\n    <string name=\"tag_gps_dest_longitude_ref\">Tham chiếu kinh độ đích GPS</string>\n    <string name=\"tag_gps_dest_longitude\">Kinh độ đích GPS</string>\n    <string name=\"tag_gps_dest_bearing_ref\">Tham chiếu vòng bi đích GPS</string>\n    <string name=\"tag_gps_dest_bearing\">Vòng bi đích GPS</string>\n    <string name=\"tag_gps_dest_distance_ref\">Tham chiếu khoảng cách đích GPS</string>\n    <string name=\"tag_gps_dest_distance\">Khoảng cách đích GPS</string>\n    <string name=\"tag_gps_processing_method\">Phương pháp xử lý GPS</string>\n    <string name=\"tag_gps_area_information\">Thông tin khu vực GPS</string>\n    <string name=\"tag_gps_datestamp\">Dấu ngày GPS</string>\n    <string name=\"tag_gps_differential\">GPS vi sai</string>\n    <string name=\"tag_gps_h_positioning_error\">Lỗi định vị GPS H</string>\n    <string name=\"tag_interoperability_index\">Chỉ số khả năng tương tác</string>\n    <string name=\"tag_dng_version\">Phiên bản DNG</string>\n    <string name=\"tag_default_crop_size\">Kích thước cắt mặc định</string>\n    <string name=\"tag_orf_preview_image_start\">Xem trước hình ảnh bắt đầu</string>\n    <string name=\"tag_orf_preview_image_length\">Xem trước độ dài hình ảnh</string>\n    <string name=\"tag_orf_aspect_frame\">Khung khía cạnh</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">Viền dưới cảm biến</string>\n    <string name=\"tag_rw2_sensor_left_border\">Cảm biến viền trái</string>\n    <string name=\"tag_rw2_sensor_right_border\">Cảm biến viền phải</string>\n    <string name=\"tag_rw2_sensor_top_border\">Đường viền trên cùng của cảm biến</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"draw_text_sub\">Vẽ văn bản trên đường dẫn với phông chữ và màu sắc nhất định</string>\n    <string name=\"font_size\">Cỡ chữ</string>\n    <string name=\"watermark_size\">Kích thước watermark</string>\n    <string name=\"repeat_text\">Lặp lại văn bản</string>\n    <string name=\"repeat_text_sub\">Văn bản hiện tại sẽ được lặp lại cho đến khi kết thúc đường dẫn thay vì vẽ một lần</string>\n    <string name=\"dash_size\">Kích thước dấu gạch ngang</string>\n    <string name=\"draw_mode_image_sub\">Sử dụng hình ảnh đã chọn để vẽ nó dọc theo đường dẫn đã cho</string>\n    <string name=\"draw_image_sub\">Hình ảnh này sẽ được sử dụng làm mục nhập lặp đi lặp lại của đường dẫn đã vẽ</string>\n    <string name=\"outlined_triangle_sub\">Vẽ đường viền tam giác từ điểm đầu đến điểm cuối</string>\n    <string name=\"triangle_sub\">Vẽ đường viền tam giác từ điểm đầu đến điểm cuối</string>\n    <string name=\"outlined_triangle\">Tam giác viền ngoài</string>\n    <string name=\"triangle\">Tam giác</string>\n    <string name=\"polygon_sub\">Vẽ đa giác từ điểm đầu đến điểm cuối</string>\n    <string name=\"polygon\">Đa giác</string>\n    <string name=\"outlined_polygon\">Đa giác viền</string>\n    <string name=\"outlined_polygon_sub\">Vẽ đa giác có đường viền từ điểm đầu đến điểm cuối</string>\n    <string name=\"vertices\">Các đỉnh</string>\n    <string name=\"draw_regular_polygon\">Vẽ đa giác đều</string>\n    <string name=\"draw_regular_polygon_sub\">Vẽ đa giác sẽ có dạng thông thường thay vì dạng tự do</string>\n    <string name=\"star_sub\">Vẽ ngôi sao từ điểm đầu đến điểm cuối</string>\n    <string name=\"star\">Ngôi sao</string>\n    <string name=\"outlined_star\">Ngôi sao có viền</string>\n    <string name=\"outlined_star_sub\">Vẽ ngôi sao có đường viền từ điểm đầu đến điểm cuối</string>\n    <string name=\"inner_radius_ratio\">Tỷ lệ bán kính bên trong</string>\n    <string name=\"draw_regular_star\">Vẽ ngôi sao thông thường</string>\n    <string name=\"draw_regular_star_sub\">Vẽ ngôi sao sẽ có dạng thông thường thay vì dạng tự do</string>\n    <string name=\"antialias\">Khử răng cưa</string>\n    <string name=\"antialias_sub\">Cho phép khử răng cưa để tránh các cạnh sắc nét</string>\n    <string name=\"open_edit_instead_of_preview\">Mở Chỉnh sửa thay vì Xem trước</string>\n    <string name=\"open_edit_instead_of_preview_sub\">Khi bạn chọn hình ảnh để mở (xem trước) trong ImageToolbox, bảng lựa chọn chỉnh sửa sẽ được mở thay vì xem trước</string>\n    <string name=\"document_scanner\">Máy quét tài liệu</string>\n    <string name=\"document_scanner_sub\">Quét tài liệu và tạo PDF hoặc tách hình ảnh khỏi chúng</string>\n    <string name=\"click_to_start_scanning\">Nhấp để bắt đầu quét</string>\n    <string name=\"start_scanning\">Bắt đầu quét</string>\n    <string name=\"save_as_pdf\">Lưu dưới dạng PDF</string>\n    <string name=\"share_as_pdf\">Chia sẻ như PDF</string>\n    <string name=\"options_below_is_for_images\">Các tùy chọn bên dưới là để lưu hình ảnh chứ không phải PDF</string>\n    <string name=\"equalize_histogram_hsv\">Cân bằng biểu đồ HSV</string>\n    <string name=\"equalize_histogram\">Cân bằng biểu đồ</string>\n    <string name=\"enter_percentage\">Nhập phần trăm</string>\n    <string name=\"allow_enter_by_text_field\">Cho phép nhập theo trường văn bản</string>\n    <string name=\"allow_enter_by_text_field_sub\">Bật Trường văn bản phía sau lựa chọn đặt trước để nhập chúng nhanh chóng</string>\n    <string name=\"scale_color_space\">Không gian màu tỷ lệ</string>\n    <string name=\"linear\">Tuyến tính</string>\n    <string name=\"equalize_histogram_pixelation\">Cân bằng pixel biểu đồ</string>\n    <string name=\"grid_size_x\">Kích thước lưới X</string>\n    <string name=\"grid_size_y\">Kích thước lưới Y</string>\n    <string name=\"equalize_histogram_adaptive\">Cân bằng biểu đồ Thích ứng</string>\n    <string name=\"equalize_histogram_adaptive_luv\">Cân bằng biểu đồ LUV thích ứng</string>\n    <string name=\"equalize_histogram_adaptive_lab\">Cân bằng biểu đồ LAB thích ứng</string>\n    <string name=\"clahe\">Clahe</string>\n    <string name=\"clahe_lab\">Clahe LAB</string>\n    <string name=\"clahe_luv\">Clahe LUV</string>\n    <string name=\"crop_to_content\">Cắt theo nội dung</string>\n    <string name=\"frame_color\">Màu khung</string>\n    <string name=\"color_to_ignore\">Màu cần bỏ qua</string>\n    <string name=\"template\">Mẫu</string>\n    <string name=\"no_template_filters\">Không có bộ lọc mẫu nào được thêm vào</string>\n    <string name=\"create_new\">Tạo mới</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">Mã QR được quét không phải là mẫu bộ lọc hợp lệ</string>\n    <string name=\"scan_qr_code\">Quét mã QR</string>\n    <string name=\"opened_file_have_no_filter_template\">Tệp đã chọn không có dữ liệu mẫu bộ lọc</string>\n    <string name=\"create_template\">Tạo mẫu</string>\n    <string name=\"template_name\">Tên mẫu</string>\n    <string name=\"select_template_preview\">Hình ảnh này sẽ được sử dụng để xem trước mẫu bộ lọc này</string>\n    <string name=\"template_filter\">Bộ lọc mẫu</string>\n    <string name=\"as_qr_code\">Dưới dạng hình ảnh mã QR</string>\n    <string name=\"as_file\">Dưới dạng tệp</string>\n    <string name=\"save_as_file\">Lưu dưới dạng tệp</string>\n    <string name=\"save_as_qr_code_image\">Lưu dưới dạng hình ảnh mã QR</string>\n    <string name=\"delete_template\">Xóa mẫu</string>\n    <string name=\"delete_template_warn\">Bạn sắp xóa bộ lọc mẫu đã chọn. Thao tác này không thể hoàn tác được</string>\n    <string name=\"added_filter_template\">Đã thêm mẫu bộ lọc có tên \\\"%1$s\\\" (%2$s)</string>\n    <string name=\"filter_preview\">Xem trước bộ lọc</string>\n    <string name=\"qr_code\">Mã QR</string>\n    <string name=\"qr_code_sub\">Quét mã QR và lấy nội dung hoặc dán chuỗi của bạn để tạo mã mới</string>\n    <string name=\"code_content\">Nội dung mã</string>\n    <string name=\"scan_qr_code_to_replace_content\">Quét bất kỳ mã vạch nào để thay thế nội dung trong trường, hoặc nhập nội dung để tạo mã vạch mới với loại đã chọn</string>\n    <string name=\"qr_description\">Mô tả QR</string>\n    <string name=\"min\">Tối thiểu</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">Cấp quyền cho máy ảnh trong cài đặt để quét mã QR</string>\n    <string name=\"cubic\">Cubic</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"gaussian\">Gaussian</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"box\">Box</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"cubic_sub\">Nội suy khối giúp chia tỷ lệ mượt mà hơn bằng cách xem xét 16 pixel gần nhất, cho kết quả tốt hơn so với nội suy song tuyến tính</string>\n    <string name=\"bspline_sub\">Sử dụng các hàm đa thức được xác định theo từng phần để nội suy và xấp xỉ một cách mượt mà một đường cong hoặc bề mặt, biểu diễn hình dạng linh hoạt và liên tục</string>\n    <string name=\"hamming_sub\">Một chức năng cửa sổ được sử dụng để giảm rò rỉ quang phổ bằng cách làm thon dần các cạnh của tín hiệu, hữu ích trong việc xử lý tín hiệu</string>\n    <string name=\"hanning_sub\">Một biến thể của cửa sổ Hann, thường được sử dụng để giảm rò rỉ quang phổ trong các ứng dụng xử lý tín hiệu</string>\n    <string name=\"blackman_sub\">Chức năng cửa sổ cung cấp độ phân giải tần số tốt bằng cách giảm thiểu rò rỉ quang phổ, thường được sử dụng trong xử lý tín hiệu</string>\n    <string name=\"welch_sub\">Một chức năng cửa sổ được thiết kế để mang lại độ phân giải tần số tốt và giảm rò rỉ quang phổ, thường được sử dụng trong các ứng dụng xử lý tín hiệu</string>\n    <string name=\"quadric_sub\">Một phương pháp sử dụng hàm bậc hai để nội suy, mang lại kết quả mượt mà và liên tục</string>\n    <string name=\"gaussian_sub\">Một phương pháp nội suy áp dụng hàm Gaussian, hữu ích cho việc làm mịn và giảm nhiễu trong hình ảnh</string>\n    <string name=\"sphinx_sub\">Một phương pháp lấy mẫu lại nâng cao cung cấp phép nội suy chất lượng cao với lượng tạo tác tối thiểu</string>\n    <string name=\"bartlett_sub\">Chức năng cửa sổ tam giác được sử dụng trong xử lý tín hiệu để giảm rò rỉ quang phổ</string>\n    <string name=\"robidoux_sub\">Phương pháp nội suy chất lượng cao được tối ưu hóa để thay đổi kích thước hình ảnh một cách tự nhiên, cân bằng độ sắc nét và độ mịn</string>\n    <string name=\"robidoux_sharp_sub\">Một biến thể sắc nét hơn của phương pháp Robidoux, được tối ưu hóa để thay đổi kích thước hình ảnh sắc nét</string>\n    <string name=\"spline16_sub\">Phương pháp nội suy dựa trên spline mang lại kết quả mượt mà bằng bộ lọc 16 lần nhấn</string>\n    <string name=\"spline36_sub\">Phương pháp nội suy dựa trên spline mang lại kết quả mượt mà bằng bộ lọc 36 lần nhấn</string>\n    <string name=\"spline64_sub\">Phương pháp nội suy dựa trên spline mang lại kết quả mượt mà bằng bộ lọc 64 lần nhấn</string>\n    <string name=\"kaiser_sub\">Một phương pháp nội suy sử dụng cửa sổ Kaiser, cung cấp khả năng kiểm soát tốt sự cân bằng giữa chiều rộng thùy chính và mức thùy bên</string>\n    <string name=\"bartlett_hann_sub\">Chức năng cửa sổ lai kết hợp cửa sổ Bartlett và Hann, được sử dụng để giảm rò rỉ quang phổ trong xử lý tín hiệu</string>\n    <string name=\"box_sub\">Một phương pháp lấy mẫu lại đơn giản sử dụng giá trị trung bình của các giá trị pixel gần nhất, thường dẫn đến hình dạng khối</string>\n    <string name=\"bohman_sub\">Chức năng cửa sổ được sử dụng để giảm rò rỉ quang phổ, cung cấp độ phân giải tần số tốt trong các ứng dụng xử lý tín hiệu</string>\n    <string name=\"lanczos2_sub\">Phương pháp lấy mẫu lại sử dụng bộ lọc Lanczos 2 thùy để nội suy chất lượng cao với lượng tạo tác tối thiểu</string>\n    <string name=\"lanczos3_sub\">Phương pháp lấy mẫu lại sử dụng bộ lọc Lanczos 3 thùy để nội suy chất lượng cao với lượng tạo tác tối thiểu</string>\n    <string name=\"lanczos4_sub\">Phương pháp lấy mẫu lại sử dụng bộ lọc Lanczos 4 thùy để nội suy chất lượng cao với lượng tạo tác tối thiểu</string>\n    <string name=\"lanczos2_jinc_sub\">Một biến thể của bộ lọc Lanczos 2 sử dụng hàm jinc, cung cấp phép nội suy chất lượng cao với lượng tạo tác tối thiểu</string>\n    <string name=\"lanczos3_jinc_sub\">Một biến thể của bộ lọc Lanczos 3 sử dụng hàm jinc, cung cấp phép nội suy chất lượng cao với lượng tạo tác tối thiểu</string>\n    <string name=\"lanczos4_jinc_sub\">Một biến thể của bộ lọc Lanczos 4 sử dụng hàm jinc, cung cấp phép nội suy chất lượng cao với lượng tạo tác tối thiểu</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Hanning để nội suy và lấy mẫu lại mượt mà</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Robidoux để lấy mẫu lại chất lượng cao</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_blackman_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Blackman để giảm thiểu hiện tượng đổ chuông</string>\n    <string name=\"ewa_quadric\">EWA bậc hai</string>\n    <string name=\"ewa_quadric_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Quadric để nội suy mượt mà</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Robidoux Sharp cho kết quả sắc nét hơn</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Lanczos 3 Jinc để lấy mẫu lại chất lượng cao với giảm răng cưa</string>\n    <string name=\"ginseng\">Nhân sâm</string>\n    <string name=\"ginseng_sub\">Bộ lọc lấy mẫu lại được thiết kế để xử lý hình ảnh chất lượng cao với sự cân bằng tốt giữa độ sắc nét và độ mịn</string>\n    <string name=\"ewa_ginseng\">Nhân sâm EWA</string>\n    <string name=\"ewa_ginseng_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Nhân sâm để nâng cao chất lượng hình ảnh</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Biến thể trung bình có trọng số hình elip (EWA) của bộ lọc Lanczos Sharp để đạt được kết quả sắc nét với ít tạo tác nhất</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 EWA sắc nét nhất</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Biến thể Trung bình Trọng số Hình elip (EWA) của bộ lọc Lanczos 4 Sharpest để lấy mẫu lại hình ảnh cực kỳ sắc nét</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_soft_sub\">Biến thể Trung bình Trọng số Hình elip (EWA) của bộ lọc Lanczos Soft để lấy mẫu lại hình ảnh mượt mà hơn</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">Bộ lọc lấy mẫu lại được thiết kế bởi Haasn để chia tỷ lệ hình ảnh mượt mà và không có hiện tượng giả</string>\n    <string name=\"format_conversion\">Chuyển đổi định dạng</string>\n    <string name=\"format_conversion_sub\">Chuyển đổi hàng loạt hình ảnh từ định dạng này sang định dạng khác</string>\n    <string name=\"dismiss_forever\">Loại bỏ vĩnh viễn</string>\n    <string name=\"image_stacking\">Xếp chồng hình ảnh</string>\n    <string name=\"image_stacking_sub\">Xếp chồng các hình ảnh lên nhau với các chế độ hòa trộn đã chọn</string>\n    <string name=\"add_image\">Thêm hình ảnh</string>\n    <string name=\"bins_count\">Số thùng</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">Cân bằng biểu đồ HSL thích ứng</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">Cân bằng biểu đồ HSV thích ứng</string>\n    <string name=\"edge_mode\">Chế độ cạnh</string>\n    <string name=\"clip\">Đoạn phim</string>\n    <string name=\"wrap\">Cuộn</string>\n    <string name=\"color_blind_scheme\">Sơ đồ mù màu</string>\n    <string name=\"color_blind_scheme_sub\">Chọn chế độ để điều chỉnh màu chủ đề cho biến thể mù màu nhất định</string>\n    <string name=\"protanomaly_sub\">Khó phân biệt giữa màu đỏ và màu lục</string>\n    <string name=\"deuteranomaly_sub\">Khó phân biệt giữa màu lục và màu đỏ</string>\n    <string name=\"tritanomaly_sub\">Khó phân biệt giữa màu lam và màu vàng</string>\n    <string name=\"protanopia_sub\">Không có khả năng nhận biết màu đỏ</string>\n    <string name=\"deuteranopia_sub\">Không có khả năng nhận biết màu lục</string>\n    <string name=\"tritanopia_sub\">Không có khả năng nhận biết màu lam</string>\n    <string name=\"achromatomaly_sub\">Giảm độ nhạy với tất cả các màu</string>\n    <string name=\"achromatopsia_sub\">Mù màu hoàn toàn, chỉ nhìn thấy các sắc thái màu xám</string>\n    <string name=\"not_use_color_blind_scheme\">Không sử dụng sơ đồ mù màu</string>\n    <string name=\"not_use_color_blind_scheme_sub\">Màu sắc sẽ chính xác như được đặt trong chủ đề</string>\n    <string name=\"sigmoidal\">Sigmoidal</string>\n    <string name=\"lagrange_2_sub\">Bộ lọc nội suy Lagrange bậc 2, thích hợp cho việc chia tỷ lệ hình ảnh chất lượng cao với các chuyển tiếp mượt mà</string>\n    <string name=\"lagrange_3_sub\">Bộ lọc nội suy Lagrange bậc 3, mang lại độ chính xác cao hơn và kết quả mượt mà hơn cho việc chia tỷ lệ hình ảnh</string>\n    <string name=\"lanczos_6_sub\">Bộ lọc lấy mẫu lại Lanczos với bậc 6 cao hơn, mang lại tỷ lệ hình ảnh sắc nét và chính xác hơn</string>\n    <string name=\"lanczos_6_jinc_sub\">Một biến thể của bộ lọc Lanczos 6 sử dụng chức năng Jinc để cải thiện chất lượng lấy mẫu lại hình ảnh</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">Cấp quyền cho máy ảnh trong cài đặt để quét Máy quét tài liệu</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"linear_box_blur\">Làm mờ hộp tuyến tính</string>\n    <string name=\"linear_tent_blur\">Làm mờ lều tuyến tính</string>\n    <string name=\"linear_gaussian_box_blur\">Làm mờ hộp Gaussian tuyến tính</string>\n    <string name=\"linear_stack_blur\">Làm mờ ngăn xếp tuyến tính</string>\n    <string name=\"gaussian_box_blur\">Làm mờ hộp Gaussian</string>\n    <string name=\"linear_fast_gaussian_blur_next\">Làm mờ Gaussian nhanh tuyến tính Tiếp theo</string>\n    <string name=\"linear_fast_gaussian_blur\">Làm mờ Gaussian nhanh tuyến tính</string>\n    <string name=\"linear_gaussian_blur\">Làm mờ Gaussian tuyến tính</string>\n    <string name=\"draw_filter_sub\">Chọn một bộ lọc để sử dụng nó làm sơn</string>\n    <string name=\"replace_filter\">Thay thế bộ lọc</string>\n    <string name=\"pick_filter_info\">Chọn bộ lọc bên dưới để sử dụng nó làm cọ vẽ trong bản vẽ của bạn</string>\n    <string name=\"tiff_compression_scheme\">Sơ đồ nén TIFF</string>\n    <string name=\"low_poly\">Poly thấp</string>\n    <string name=\"sand_painting\">Tranh cát</string>\n    <string name=\"image_splitting\">Tách ảnh</string>\n    <string name=\"image_splitting_sub\">Tách một hình ảnh theo hàng hoặc cột</string>\n    <string name=\"fit_to_bounds\">Phù hợp với giới hạn</string>\n    <string name=\"fit_to_bounds_sub\">Kết hợp chế độ thay đổi kích thước cắt xén với tham số này để đạt được hành vi mong muốn (Cắt/Vừa với tỷ lệ khung hình)</string>\n    <string name=\"languages_imported\">Ngôn ngữ được nhập thành công</string>\n    <string name=\"backup_ocr_models\">Sao lưu mô hình OCR</string>\n    <string name=\"import_word\">Nhập khẩu</string>\n    <string name=\"export\">Xuất khẩu</string>\n    <string name=\"position\">Chức vụ</string>\n    <string name=\"center\">Trung tâm</string>\n    <string name=\"top_left\">Trên cùng bên trái</string>\n    <string name=\"top_right\">Trên cùng bên phải</string>\n    <string name=\"bottom_left\">Dưới cùng bên trái</string>\n    <string name=\"bottom_right\">Dưới cùng bên phải</string>\n    <string name=\"top_center\">Trung tâm hàng đầu</string>\n    <string name=\"center_right\">Giữa bên phải</string>\n    <string name=\"bottom_center\">Trung tâm dưới cùng</string>\n    <string name=\"center_left\">Giữa bên trái</string>\n    <string name=\"target_image\">Hình ảnh mục tiêu</string>\n    <string name=\"palette_transfer\">Chuyển bảng màu</string>\n    <string name=\"enhanced_oil\">Dầu tăng cường</string>\n    <string name=\"simple_old_tv\">TV cũ đơn giản</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">Gotham</string>\n    <string name=\"simple_sketch\">Phác thảo đơn giản</string>\n    <string name=\"soft_glow\">Ánh sáng mềm mại</string>\n    <string name=\"color_poster\">Áp phích màu</string>\n    <string name=\"tri_tone\">Tri giai điệu</string>\n    <string name=\"third_color\">Màu thứ ba</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clara Olks</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">chấm bi</string>\n    <string name=\"clustered_2x2_dithering\">Phối màu 2x2 theo cụm</string>\n    <string name=\"clustered_4x4_dithering\">Phối màu theo cụm 4x4</string>\n    <string name=\"clustered_8x8_dithering\">Phối màu 8x8 theo cụm</string>\n    <string name=\"yililoma_dithering\">Phối màu Yililoma</string>\n    <string name=\"no_favorite_options_selected\">Không có tùy chọn yêu thích nào được chọn, hãy thêm chúng vào trang công cụ</string>\n    <string name=\"add_favorites\">Thêm yêu thích</string>\n    <string name=\"harmony_complementary\">bổ sung</string>\n    <string name=\"harmony_analogous\">Tương tự</string>\n    <string name=\"harmony_triadic\">bộ ba</string>\n    <string name=\"harmony_split_complementary\">Chia bổ sung</string>\n    <string name=\"harmony_tetradic\">tứ giác</string>\n    <string name=\"harmony_square\">Quảng trường</string>\n    <string name=\"harmony_analogous_complementary\">Tương tự + Bổ sung</string>\n    <string name=\"color_tools\">Công cụ màu sắc</string>\n    <string name=\"color_tools_sub\">Trộn, tạo tông màu, tạo sắc thái và hơn thế nữa</string>\n    <string name=\"color_harmonies\">Màu sắc hài hòa</string>\n    <string name=\"color_shading\">Màu bóng</string>\n    <string name=\"variation\">Biến thể</string>\n    <string name=\"tints\">Sắc thái</string>\n    <string name=\"tones\">Âm</string>\n    <string name=\"shades\">sắc thái</string>\n    <string name=\"color_mixing\">Trộn màu</string>\n    <string name=\"color_info\">Thông tin màu sắc</string>\n    <string name=\"selected_color\">Màu đã chọn</string>\n    <string name=\"color_to_mix\">Màu để trộn</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">Không thể sử dụng tiền khi bật màu động</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"target_lut_image\">Hình ảnh LUT mục tiêu</string>\n    <string name=\"amatorka\">Một người nghiệp dư</string>\n    <string name=\"miss_etikate\">nghi thức hoa hậu</string>\n    <string name=\"soft_elegance\">Thanh lịch mềm mại</string>\n    <string name=\"soft_elegance_variant\">Biến thể thanh lịch mềm mại</string>\n    <string name=\"palette_transfer_variant\">Biến thể chuyển bảng màu</string>\n    <string name=\"cube_lut\">LUT 3D</string>\n    <string name=\"target_cube_lut_file\">Nhắm mục tiêu tệp LUT 3D (.cube / .CUBE)</string>\n    <string name=\"lut\">LUT</string>\n    <string name=\"bleach_bypass\">Bỏ qua thuốc tẩy</string>\n    <string name=\"candlelight\">Dưới ánh nến</string>\n    <string name=\"drop_blues\">Thả nhạc blues</string>\n    <string name=\"edgy_amber\">Hổ phách sắc sảo</string>\n    <string name=\"fall_colors\">Màu sắc mùa thu</string>\n    <string name=\"film_stock_50\">Kho phim 50</string>\n    <string name=\"foggy_night\">Đêm sương mù</string>\n    <string name=\"kodak\">Kodak</string>\n    <string name=\"save_empty_lut\">Nhận hình ảnh LUT trung tính</string>\n    <string name=\"save_empty_lut_sub\">Trước tiên, hãy sử dụng ứng dụng chỉnh sửa ảnh yêu thích của bạn để áp dụng bộ lọc cho LUT trung tính mà bạn có thể lấy tại đây. Để tính năng này hoạt động bình thường, mỗi màu pixel không được phụ thuộc vào các pixel khác (ví dụ: độ mờ sẽ không hoạt động). Sau khi sẵn sàng, hãy sử dụng hình ảnh LUT mới của bạn làm đầu vào cho bộ lọc LUT 512*512</string>\n    <string name=\"pop_art\">Nghệ thuật đại chúng</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"coffee\">Cà phê</string>\n    <string name=\"golden_forest\">Rừng Vàng</string>\n    <string name=\"greenish\">Hơi xanh</string>\n    <string name=\"retro_yellow\">Màu vàng cổ điển</string>\n    <string name=\"links_preview\">Xem trước liên kết</string>\n    <string name=\"links_preview_sub\">Cho phép truy xuất bản xem trước liên kết ở những nơi bạn có thể lấy văn bản (QRCode, OCR, v.v.)</string>\n    <string name=\"links\">Liên kết</string>\n    <string name=\"ico_size_warning\">Các tệp ICO chỉ có thể được lưu ở kích thước tối đa 256 x 256</string>\n    <string name=\"gif_type_to_webp\">GIF sang WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">Chuyển đổi ảnh GIF thành ảnh động WEBP</string>\n    <string name=\"webp_tools\">Công cụ WEBP</string>\n    <string name=\"webp_tools_sub\">Chuyển đổi hình ảnh thành ảnh động WEBP hoặc trích xuất khung hình từ hoạt ảnh WEBP nhất định</string>\n    <string name=\"webp_type_to_image\">WEBP vào hình ảnh</string>\n    <string name=\"webp_type_to_image_sub\">Chuyển đổi tập tin WEBP thành hàng loạt hình ảnh</string>\n    <string name=\"webp_type_to_webp_sub\">Chuyển đổi hàng loạt hình ảnh thành tệp WEBP</string>\n    <string name=\"webp_type_to_webp\">Hình ảnh tới WEBP</string>\n    <string name=\"select_webp_image_to_start\">Chọn hình ảnh WEBP để bắt đầu</string>\n    <string name=\"manage_storage_extra_types\">Không có quyền truy cập đầy đủ vào các tập tin</string>\n    <string name=\"manage_storage_extra_types_sub\">Cho phép tất cả các tệp truy cập để xem JXL, QOI và các hình ảnh khác không được nhận dạng là hình ảnh trên Android. Nếu không có sự cho phép Hộp công cụ hình ảnh không thể hiển thị những hình ảnh đó</string>\n    <string name=\"default_draw_color\">Màu vẽ mặc định</string>\n    <string name=\"default_draw_path_mode\">Chế độ đường vẽ mặc định</string>\n    <string name=\"add_timestamp\">Thêm dấu thời gian</string>\n    <string name=\"add_timestamp_sub\">Cho phép thêm Dấu thời gian vào tên tệp đầu ra</string>\n    <string name=\"formatted_timestamp\">Dấu thời gian được định dạng</string>\n    <string name=\"formatted_timestamp_sub\">Bật định dạng Dấu thời gian trong tên tệp đầu ra thay vì mili cơ bản</string>\n    <string name=\"enable_timestamps_to_format_them\">Bật Dấu thời gian để chọn định dạng của chúng</string>\n    <string name=\"one_time_save_location\">Vị trí lưu một lần</string>\n    <string name=\"one_time_save_location_sub\">Xem và chỉnh sửa các vị trí lưu một lần mà bạn có thể sử dụng bằng cách nhấn và giữ nút lưu trong hầu hết tất cả các tùy chọn</string>\n    <string name=\"recently_used\">Được sử dụng gần đây</string>\n    <string name=\"ci_channel\">kênh CI</string>\n    <string name=\"group\">Nhóm</string>\n    <string name=\"image_toolbox_in_telegram\">Hộp công cụ hình ảnh trong Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">Tham gia cuộc trò chuyện của chúng tôi, nơi bạn có thể thảo luận bất cứ điều gì bạn muốn và cũng có thể xem kênh CI nơi tôi đăng bản beta và thông báo</string>\n    <string name=\"ci_channel_sub\">Nhận thông báo về các phiên bản mới của ứng dụng và đọc thông báo</string>\n    <string name=\"fit_description\">Điều chỉnh hình ảnh theo kích thước nhất định và áp dụng độ mờ hoặc màu cho nền</string>\n    <string name=\"tools_arrangement\">Sắp xếp công cụ</string>\n    <string name=\"group_tools_by_type\">Nhóm công cụ theo loại</string>\n    <string name=\"group_tools_by_type_sub\">Nhóm các công cụ trên màn hình chính theo loại thay vì sắp xếp danh sách tùy chỉnh</string>\n    <string name=\"default_values\">Giá trị mặc định</string>\n    <string name=\"system_bars_visibility\">Hiển thị thanh hệ thống</string>\n    <string name=\"show_system_bars_by_swipe\">Hiển thị thanh hệ thống bằng cách vuốt</string>\n    <string name=\"show_system_bars_by_swipe_sub\">Cho phép vuốt để hiển thị thanh hệ thống nếu chúng bị ẩn</string>\n    <string name=\"auto\">Tự động</string>\n    <string name=\"hide_all\">Ẩn tất cả</string>\n    <string name=\"show_all\">Hiển thị tất cả</string>\n    <string name=\"hide_nav_bar\">Ẩn thanh điều hướng</string>\n    <string name=\"hide_status_bar\">Ẩn thanh trạng thái</string>\n    <string name=\"noise_generation\">Tạo tiếng ồn</string>\n    <string name=\"noise_generation_sub\">Tạo ra các tiếng ồn khác nhau như Perlin hoặc các loại khác</string>\n    <string name=\"frequency\">Tính thường xuyên</string>\n    <string name=\"noise_type\">Loại tiếng ồn</string>\n    <string name=\"rotation_type\">Kiểu xoay</string>\n    <string name=\"fractal_type\">Loại phân dạng</string>\n    <string name=\"octaves\">Quãng tám</string>\n    <string name=\"lacunarity\">Thiếu sót</string>\n    <string name=\"gain\">Nhận được</string>\n    <string name=\"weighted_strength\">Sức mạnh có trọng số</string>\n    <string name=\"ping_pong_strength\">Sức mạnh bóng bàn</string>\n    <string name=\"distance_function\">Hàm khoảng cách</string>\n    <string name=\"return_type\">Kiểu trả về</string>\n    <string name=\"jitter\">Giật giật</string>\n    <string name=\"domain_warp\">Biến dạng tên miền</string>\n    <string name=\"alignment\">Căn chỉnh</string>\n    <string name=\"custom_filename\">Tên tệp tùy chỉnh</string>\n    <string name=\"custom_filename_sub\">Chọn vị trí và tên tệp sẽ được sử dụng để lưu hình ảnh hiện tại</string>\n    <string name=\"saved_to_custom\">Đã lưu vào thư mục có tên tùy chỉnh</string>\n    <string name=\"collage_maker\">Trình tạo ảnh ghép</string>\n    <string name=\"collage_maker_sub\">Tạo ảnh ghép từ tối đa 20 hình ảnh</string>\n    <string name=\"collage_type\">Loại ảnh ghép</string>\n    <string name=\"collages_info\">Giữ hình ảnh để hoán đổi, di chuyển và thu phóng để điều chỉnh vị trí</string>\n    <string name=\"disable_rotation\">Vô hiệu hóa xoay</string>\n    <string name=\"disable_rotation_sub\">Ngăn chặn xoay hình ảnh bằng cử chỉ hai ngón tay</string>\n    <string name=\"enable_snapping_to_borders\">Cho phép chụp nhanh vào đường viền</string>\n    <string name=\"enable_snapping_to_borders_sub\">Sau khi di chuyển hoặc zoom, hình ảnh sẽ chụp nhanh để lấp đầy các cạnh khung</string>\n    <string name=\"histogram\">biểu đồ</string>\n    <string name=\"histogram_sub\">Biểu đồ hình ảnh RGB hoặc Độ sáng để giúp bạn điều chỉnh</string>\n    <string name=\"image_for_histogram\">Hình ảnh này sẽ được sử dụng để tạo biểu đồ RGB và Độ sáng</string>\n    <string name=\"tesseract_options\">Tùy chọn Tesseract</string>\n    <string name=\"tesseract_options_sub\">Áp dụng một số biến đầu vào cho công cụ tesseract</string>\n    <string name=\"custom_options\">Tùy chọn tùy chỉnh</string>\n    <string name=\"custom_params_info\">Các tùy chọn phải được nhập theo mẫu sau: \\\"--{option_name} {value}\\\"</string>\n    <string name=\"auto_crop\">Tự động cắt</string>\n    <string name=\"free_corners\">Góc miễn phí</string>\n    <string name=\"free_corners_sub\">Cắt hình ảnh theo đa giác, điều này cũng điều chỉnh phối cảnh</string>\n    <string name=\"coerce_points_to_image_bounds\">Buộc trỏ vào giới hạn hình ảnh</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">Các điểm sẽ không bị giới hạn bởi giới hạn hình ảnh, điều này hữu ích để điều chỉnh phối cảnh chính xác hơn</string>\n    <string name=\"mask\">Mặt nạ</string>\n    <string name=\"spot_heal_sub\">Nội dung nhận biết điền vào đường dẫn đã vẽ</string>\n    <string name=\"spot_heal\">Chữa lành vết thương</string>\n    <string name=\"use_circle_kernel\">Sử dụng hạt nhân vòng tròn</string>\n    <string name=\"opening\">Khai mạc</string>\n    <string name=\"closing\">Đóng cửa</string>\n    <string name=\"morphological_gradient\">Độ dốc hình thái</string>\n    <string name=\"top_hat\">Mũ chóp</string>\n    <string name=\"black_hat\">Mũ đen</string>\n    <string name=\"tone_curves\">Đường cong giai điệu</string>\n    <string name=\"reset_curves\">Đặt lại đường cong</string>\n    <string name=\"reset_curves_sub\">Đường cong sẽ được khôi phục về giá trị mặc định</string>\n    <string name=\"line_style\">Kiểu đường</string>\n    <string name=\"gap_size\">Kích thước khoảng cách</string>\n    <string name=\"dashed\">nét đứt</string>\n    <string name=\"dot_dashed\">Dấu chấm đứt nét</string>\n    <string name=\"stamped\">đóng dấu</string>\n    <string name=\"zigzag\">ngoằn ngoèo</string>\n    <string name=\"dashed_sub\">Vẽ đường đứt nét dọc theo đường dẫn đã vẽ với kích thước khoảng cách được chỉ định</string>\n    <string name=\"dot_dashed_sub\">Vẽ dấu chấm và đường đứt nét dọc theo đường dẫn đã cho</string>\n    <string name=\"defaultt_sub\">Chỉ mặc định đường thẳng</string>\n    <string name=\"stamped_sub\">Vẽ các hình đã chọn dọc theo đường dẫn với khoảng cách được chỉ định</string>\n    <string name=\"zigzag_sub\">Vẽ đường ngoằn ngoèo lượn sóng dọc theo đường dẫn</string>\n    <string name=\"zigzag_ratio\">Tỷ lệ ngoằn ngoèo</string>\n    <string name=\"create_shortcut\">Tạo lối tắt</string>\n    <string name=\"create_shortcut_title\">Chọn công cụ để ghim</string>\n    <string name=\"create_shortcut_subtitle\">Công cụ sẽ được thêm vào màn hình chính của trình khởi chạy dưới dạng lối tắt, hãy sử dụng công cụ này kết hợp với cài đặt \\\"Bỏ qua việc chọn tệp\\\" để đạt được hành vi cần thiết</string>\n    <string name=\"dont_stack_frames\">Đừng xếp chồng các khung</string>\n    <string name=\"dont_stack_frames_sub\">Cho phép loại bỏ các khung hình trước đó để chúng không xếp chồng lên nhau</string>\n    <string name=\"crossfade\">Crossfade</string>\n    <string name=\"crossfade_sub\">Các khung hình sẽ được lồng vào nhau</string>\n    <string name=\"crossfade_count\">Số lượng khung hình chéo</string>\n    <string name=\"threshold_one\">Ngưỡng một</string>\n    <string name=\"threshold_two\">Ngưỡng hai</string>\n    <string name=\"canny\">Khôn ngoan</string>\n    <string name=\"mirror_101\">Gương 101</string>\n    <string name=\"enhanced_zoom_blur\">Làm mờ thu phóng nâng cao</string>\n    <string name=\"laplacian_simple\">Laplacian đơn giản</string>\n    <string name=\"sobel_simple\">Sobel đơn giản</string>\n    <string name=\"helper_grid\">Lưới trợ giúp</string>\n    <string name=\"helper_grid_sub\">Hiển thị lưới hỗ trợ phía trên vùng vẽ để giúp thao tác chính xác</string>\n    <string name=\"grid_color\">Màu lưới</string>\n    <string name=\"cell_width\">Chiều rộng ô</string>\n    <string name=\"cell_height\">Chiều cao tế bào</string>\n    <string name=\"compact_selectors\">Bộ chọn nhỏ gọn</string>\n    <string name=\"compact_selectors_sub\">Một số điều khiển lựa chọn sẽ sử dụng bố cục nhỏ gọn để chiếm ít không gian hơn</string>\n    <string name=\"grant_camera_permission_to_capture_image\">Cấp quyền cho máy ảnh trong cài đặt để chụp ảnh</string>\n    <string name=\"layout\">Cách trình bày</string>\n    <string name=\"main_screen_title\">Tiêu đề màn hình chính</string>\n    <string name=\"constant_rate_factor\">Hệ số tỷ lệ không đổi (CRF)</string>\n    <string name=\"crf_sub\">Giá trị %1$s có nghĩa là nén chậm, dẫn đến kích thước tệp tương đối nhỏ. %2$s có nghĩa là nén nhanh hơn, tạo ra tệp lớn.</string>\n    <string name=\"lut_library\">Thư viện Lut</string>\n    <string name=\"lut_library_sub\">Tải xuống bộ sưu tập LUT mà bạn có thể áp dụng sau khi tải xuống</string>\n    <string name=\"lut_library_update_sub\">Cập nhật bộ sưu tập LUT (chỉ những cái mới sẽ được xếp hàng đợi) mà bạn có thể áp dụng sau khi tải xuống</string>\n    <string name=\"filter_preview_image_sub\">Thay đổi bản xem trước hình ảnh mặc định cho các bộ lọc</string>\n    <string name=\"filter_preview_image\">Xem trước hình ảnh</string>\n    <string name=\"hide\">Trốn</string>\n    <string name=\"show\">Trình diễn</string>\n    <string name=\"slider_type\">Loại thanh trượt</string>\n    <string name=\"fancy\">Si mê</string>\n    <string name=\"material_2\">Chất liệu 2</string>\n    <string name=\"fancy_sub\">Một thanh trượt trông lạ mắt. Đây là tùy chọn mặc định</string>\n    <string name=\"material_2_sub\">Thanh trượt Vật liệu 2</string>\n    <string name=\"material_you_slider_sub\">Thanh trượt Chất liệu của bạn</string>\n    <string name=\"apply\">Áp dụng</string>\n    <string name=\"center_align_dialog_buttons\">Nút hộp thoại ở giữa</string>\n    <string name=\"center_align_dialog_buttons_sub\">Các nút hộp thoại sẽ được đặt ở giữa thay vì ở bên trái nếu có thể</string>\n    <string name=\"open_source_licenses\">Giấy phép nguồn mở</string>\n    <string name=\"open_source_licenses_sub\">Xem giấy phép của các thư viện nguồn mở được sử dụng trong ứng dụng này</string>\n    <string name=\"area\">Khu vực</string>\n    <string name=\"area_sub\">Lấy mẫu lại bằng cách sử dụng quan hệ vùng pixel. Đây có thể là một phương pháp ưa thích để giảm số thập phân hình ảnh vì nó mang lại kết quả không có hiện tượng moire. Nhưng khi phóng to hình ảnh, nó tương tự như phương pháp \\\"Gần nhất\\\".</string>\n    <string name=\"enable_tonemapping\">Bật bản đồ giai điệu</string>\n    <string name=\"enter_percent\">Đi vào %</string>\n    <string name=\"unknown_host\">Không thể truy cập trang web, hãy thử sử dụng VPN hoặc kiểm tra xem url có chính xác không</string>\n    <string name=\"markup_layers\">Lớp đánh dấu</string>\n    <string name=\"markup_layers_sub\">Chế độ lớp với khả năng tự do đặt hình ảnh, văn bản và hơn thế nữa</string>\n    <string name=\"edit_layer\">Chỉnh sửa lớp</string>\n    <string name=\"layers_on_image\">Lớp trên hình ảnh</string>\n    <string name=\"layers_on_image_sub\">Sử dụng hình ảnh làm nền và thêm các lớp khác nhau lên trên nó</string>\n    <string name=\"layers_on_background\">Các lớp trên nền</string>\n    <string name=\"layers_on_background_sub\">Tương tự như tùy chọn đầu tiên nhưng có màu sắc thay vì hình ảnh</string>\n    <string name=\"beta\">bản thử nghiệm</string>\n    <string name=\"fast_settings_side\">Bên cài đặt nhanh</string>\n    <string name=\"fast_settings_side_sub\">Thêm dải nổi ở phía đã chọn trong khi chỉnh sửa hình ảnh, thao tác này sẽ mở cài đặt nhanh khi nhấp vào</string>\n    <string name=\"clear_selection\">Xóa lựa chọn</string>\n    <string name=\"settings_group_visibility_hidden\">Nhóm cài đặt \\\"%1$s\\\" sẽ được thu gọn theo mặc định</string>\n    <string name=\"settings_group_visibility_visible\">Nhóm cài đặt \\\"%1$s\\\" sẽ được mở rộng theo mặc định</string>\n    <string name=\"base_64_tools\">Công cụ Base64</string>\n    <string name=\"base_64_tools_sub\">Giải mã chuỗi Base64 thành hình ảnh hoặc mã hóa hình ảnh sang định dạng Base64</string>\n    <string name=\"base_64\">cơ sở64</string>\n    <string name=\"not_a_valid_base_64\">Giá trị được cung cấp không phải là chuỗi Base64 hợp lệ</string>\n    <string name=\"copy_not_a_valid_base_64\">Không thể sao chép chuỗi Base64 trống hoặc không hợp lệ</string>\n    <string name=\"paste_base_64\">Dán Base64</string>\n    <string name=\"copy_base_64\">Sao chép Base64</string>\n    <string name=\"base_64_tips\">Tải hình ảnh để sao chép hoặc lưu chuỗi Base64. Nếu bạn có chính chuỗi đó, bạn có thể dán nó lên trên để có được hình ảnh</string>\n    <string name=\"save_base_64\">Lưu Base64</string>\n    <string name=\"share_base_64\">Chia sẻ Base64</string>\n    <string name=\"options\">Tùy chọn</string>\n    <string name=\"actions\">hành động</string>\n    <string name=\"import_base_64\">Cơ sở nhập khẩu64</string>\n    <string name=\"base_64_actions\">Hành động Base64</string>\n    <string name=\"add_outline\">Thêm Đề cương</string>\n    <string name=\"add_outline_sub\">Thêm đường viền xung quanh văn bản với màu sắc và chiều rộng được chỉ định</string>\n    <string name=\"outline_color\">Màu phác thảo</string>\n    <string name=\"outline_size\">Kích thước phác thảo</string>\n    <string name=\"rotation\">Xoay</string>\n    <string name=\"checksum_as_filename\">Tổng kiểm tra dưới dạng tên tệp</string>\n    <string name=\"checksum_as_filename_sub\">Hình ảnh đầu ra sẽ có tên tương ứng với tổng kiểm tra dữ liệu của chúng</string>\n    <string name=\"free_software_partner\">Phần mềm miễn phí (Đối tác)</string>\n    <string name=\"free_software_partner_sub\">Thêm nhiều phần mềm hữu ích trên kênh đối tác ứng dụng Android</string>\n    <string name=\"algorithms\">Thuật toán</string>\n    <string name=\"checksum_tools\">Công cụ kiểm tra tổng</string>\n    <string name=\"checksum_tools_sub\">So sánh tổng kiểm tra, tính toán giá trị băm hoặc tạo chuỗi hex từ các tệp bằng các thuật toán băm khác nhau</string>\n    <string name=\"calculate\">Tính toán</string>\n    <string name=\"text_hash\">Băm văn bản</string>\n    <string name=\"checksum\">Tổng kiểm tra</string>\n    <string name=\"pick_file_to_checksum\">Chọn tệp để tính tổng kiểm tra dựa trên thuật toán đã chọn</string>\n    <string name=\"enter_text_to_checksum\">Nhập văn bản để tính tổng kiểm tra dựa trên thuật toán đã chọn</string>\n    <string name=\"source_checksum\">Tổng kiểm tra nguồn</string>\n    <string name=\"checksum_to_compare\">Tổng kiểm tra để so sánh</string>\n    <string name=\"match\">Cuộc thi đấu!</string>\n    <string name=\"difference\">Sự khác biệt</string>\n    <string name=\"match_sub\">Tổng kiểm tra bằng nhau, nó có thể an toàn</string>\n    <string name=\"difference_sub\">Tổng kiểm tra không bằng nhau, tệp có thể không an toàn!</string>\n    <string name=\"mesh_gradients\">Độ dốc lưới</string>\n    <string name=\"collection_mesh_gradients_sub\">Xem bộ sưu tập trực tuyến của Mesh Gradents</string>\n    <string name=\"wrong_font\">Chỉ có thể nhập phông chữ TTF và OTF</string>\n    <string name=\"import_font\">Nhập phông chữ (TTF/OTF)</string>\n    <string name=\"export_fonts\">Xuất phông chữ</string>\n    <string name=\"imported_fonts\">Phông chữ đã nhập</string>\n    <string name=\"error_while_saving\">Lỗi khi lưu lần thử, hãy thử thay đổi thư mục đầu ra</string>\n    <string name=\"filename_is_not_set\">Tên tệp chưa được đặt</string>\n    <string name=\"none\">Không có</string>\n    <string name=\"custom_pages\">Trang tùy chỉnh</string>\n    <string name=\"pages_selection\">Lựa chọn trang</string>\n    <string name=\"tool_exit_confirmation\">Xác nhận thoát công cụ</string>\n    <string name=\"tool_exit_confirmation_sub\">Nếu bạn có những thay đổi chưa được lưu trong khi sử dụng các công cụ cụ thể và cố gắng đóng nó, thì hộp thoại xác nhận sẽ hiện</string>\n    <string name=\"edit_exif_screen\">Chỉnh sửa EXIF</string>\n    <string name=\"edit_exif_screen_sub\">Thay đổi siêu dữ liệu của một hình ảnh mà không cần nén lại</string>\n    <string name=\"edit_exif_tag\">Nhấn để chỉnh sửa các thẻ có sẵn</string>\n    <string name=\"change_sticker\">Thay đổi nhãn dán</string>\n    <string name=\"fit_width\">Vừa chiều rộng</string>\n    <string name=\"fit_height\">Chiều cao phù hợp</string>\n    <string name=\"batch_compare\">So sánh hàng loạt</string>\n    <string name=\"pick_files_to_checksum\">Chọn tệp/các tệp để tính tổng kiểm tra dựa trên thuật toán đã chọn</string>\n    <string name=\"pick_files\">Chọn tập tin</string>\n    <string name=\"pick_directory\">Chọn thư mục</string>\n    <string name=\"head_length_scale\">Thang đo chiều dài đầu</string>\n    <string name=\"stamp\">Con tem</string>\n    <string name=\"timestamp\">Dấu thời gian</string>\n    <string name=\"format_pattern\">Mẫu định dạng</string>\n    <string name=\"padding\">Phần đệm</string>\n    <string name=\"image_cutting\">Cắt ảnh</string>\n    <string name=\"image_cutting_sub\">Cắt phần ảnh và ghép phần bên trái (có thể nghịch đảo) theo đường dọc hoặc ngang</string>\n    <string name=\"vertical_pivot_line\">Đường trục dọc</string>\n    <string name=\"horizontal_pivot_line\">Đường trục ngang</string>\n    <string name=\"inverse_selection\">Lựa chọn nghịch đảo</string>\n    <string name=\"inverse_vertical_selection_sub\">Phần cắt dọc sẽ được tách rời, thay vì ghép các phần xung quanh vùng cắt</string>\n    <string name=\"inverse_horizontal_selection_sub\">Phần cắt ngang sẽ được tách rời, thay vì ghép các phần xung quanh vùng cắt</string>\n    <string name=\"collection_mesh_gradients\">Bộ sưu tập các gradient lưới</string>\n    <string name=\"mesh_gradients_sub\">Tạo gradient lưới với số lượng nút thắt và độ phân giải tùy chỉnh</string>\n    <string name=\"gradient_maker_type_image_mesh\">Lớp phủ gradient lưới</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">Soạn gradient lưới ở trên cùng của hình ảnh đã cho</string>\n    <string name=\"points_customization\">Tùy chỉnh điểm</string>\n    <string name=\"grid_size\">Kích thước lưới</string>\n    <string name=\"resolution_x\">Độ phân giải X</string>\n    <string name=\"resolution_y\">Độ phân giải Y</string>\n    <string name=\"resolution\">Nghị quyết</string>\n    <string name=\"pixel_by_pixel\">Pixel theo pixel</string>\n    <string name=\"highlight_color\">Màu nổi bật</string>\n    <string name=\"pixel_comparison_type\">Loại so sánh pixel</string>\n    <string name=\"scan_barcode\">Quét mã vạch</string>\n    <string name=\"height_ratio\">Tỷ lệ chiều cao</string>\n    <string name=\"barcode_type\">Loại mã vạch</string>\n    <string name=\"enforce_bw\">Thực thi B/W</string>\n    <string name=\"enforce_bw_sub\">Hình ảnh mã vạch sẽ có màu đen trắng hoàn toàn và không được tô màu theo chủ đề của ứng dụng</string>\n    <string name=\"barcodes_sub\">Quét bất kỳ Mã vạch nào (QR, EAN, AZTEC, …) và lấy nội dung của nó hoặc dán văn bản của bạn để tạo mã mới</string>\n    <string name=\"no_barcode_found\">Không tìm thấy mã vạch</string>\n    <string name=\"generated_barcode_will_be_here\">Mã vạch được tạo sẽ ở đây</string>\n    <string name=\"audio_cover_extractor\">Bìa âm thanh</string>\n    <string name=\"audio_cover_extractor_sub\">Trích xuất ảnh bìa album từ file âm thanh, hỗ trợ hầu hết các định dạng phổ biến</string>\n    <string name=\"pick_audio_to_start\">Chọn âm thanh để bắt đầu</string>\n    <string name=\"pick_audio\">Chọn âm thanh</string>\n    <string name=\"no_covers_found\">Không tìm thấy bìa</string>\n    <string name=\"send_logs\">Gửi nhật ký</string>\n    <string name=\"send_logs_sub\">Nhấp để chia sẻ tệp nhật ký ứng dụng, điều này có thể giúp tôi phát hiện sự cố và khắc phục sự cố</string>\n    <string name=\"crash_title\">Rất tiếc… Đã xảy ra lỗi</string>\n    <string name=\"crash_subtitle\">Bạn có thể liên hệ với tôi bằng các tùy chọn bên dưới và tôi sẽ cố gắng tìm giải pháp.\\n(Đừng quên đính kèm nhật ký)</string>\n    <string name=\"ocr_write_to_file\">Viết vào tập tin</string>\n    <string name=\"ocr_write_to_file_sub\">Trích xuất văn bản từ hàng loạt hình ảnh và lưu trữ nó trong một tệp văn bản</string>\n    <string name=\"ocr_write_to_metadata\">Ghi vào siêu dữ liệu</string>\n    <string name=\"ocr_write_to_metadata_sub\">Trích xuất văn bản từ mỗi hình ảnh và đặt nó vào thông tin EXIF của các bức ảnh tương ứng</string>\n    <string name=\"invisible_mode\">Chế độ ẩn</string>\n    <string name=\"invisible_mode_sub\">Sử dụng kỹ thuật steganography để tạo hình mờ vô hình trong mắt bên trong byte hình ảnh của bạn</string>\n    <string name=\"use_lsb\">Sử dụng LSB</string>\n    <string name=\"use_lsb_sub\">Phương pháp steganography LSB (Ít quan trọng hơn) sẽ được sử dụng, FD (Miền tần số) nếu không</string>\n    <string name=\"auto_remove_red_eyes\">Tự động loại bỏ mắt đỏ</string>\n    <string name=\"password\">Mật khẩu</string>\n    <string name=\"unlock\">Mở khóa</string>\n    <string name=\"pdf_is_protected\">PDF được bảo vệ</string>\n    <string name=\"operation_almost_complete\">Hoạt động gần như hoàn tất. Việc hủy bây giờ sẽ yêu cầu khởi động lại nó</string>\n    <string name=\"sort_by_date_modified\">Ngày sửa đổi</string>\n    <string name=\"sort_by_date_modified_reversed\">Ngày sửa đổi (Đảo ngược)</string>\n    <string name=\"sort_by_size\">Kích cỡ</string>\n    <string name=\"sort_by_size_reversed\">Kích thước (Đảo ngược)</string>\n    <string name=\"sort_by_mime_type\">Loại MIME</string>\n    <string name=\"sort_by_mime_type_reversed\">Loại MIME (Đảo ngược)</string>\n    <string name=\"sort_by_extension\">Sự mở rộng</string>\n    <string name=\"sort_by_extension_reversed\">Phần mở rộng (Đảo ngược)</string>\n    <string name=\"sort_by_date_added\">Ngày thêm</string>\n    <string name=\"sort_by_date_added_reversed\">Ngày thêm (Đảo ngược)</string>\n    <string name=\"left_to_right\">Trái sang Phải</string>\n    <string name=\"right_to_left\">Phải sang trái</string>\n    <string name=\"top_to_bottom\">Từ trên xuống dưới</string>\n    <string name=\"bottom_to_top\">Từ dưới lên trên</string>\n    <string name=\"liquid_glass\">Thủy tinh lỏng</string>\n    <string name=\"liquid_glass_sub\">Một switch dựa trên iOS 26 được công bố gần đây và hệ thống thiết kế kính lỏng của nó</string>\n    <string name=\"pick_image_or_base64\">Chọn hình ảnh hoặc dán/nhập dữ liệu Base64 bên dưới</string>\n    <string name=\"type_image_link\">Nhập liên kết hình ảnh để bắt đầu</string>\n    <string name=\"paste_link\">Dán liên kết</string>\n    <string name=\"kaleidoscope\">kính vạn hoa</string>\n    <string name=\"secondary_angle\">Góc phụ</string>\n    <string name=\"sides\">bên</string>\n    <string name=\"channel_mix\">Trộn kênh</string>\n    <string name=\"blue_green\">Lục lam</string>\n    <string name=\"red_blue\">Đỏ xanh</string>\n    <string name=\"green_red\">Xanh đỏ</string>\n    <string name=\"into_red\">Vào màu đỏ</string>\n    <string name=\"into_green\">Vào màu xanh lá cây</string>\n    <string name=\"into_blue\">Vào màu xanh</string>\n    <string name=\"cyan\">lục lam</string>\n    <string name=\"magenta\">Màu đỏ tươi</string>\n    <string name=\"yellow\">Màu vàng</string>\n    <string name=\"color_halftone\">Bán sắc màu</string>\n    <string name=\"contour\">đường viền</string>\n    <string name=\"levels\">Cấp độ</string>\n    <string name=\"offset\">Bù lại</string>\n    <string name=\"voronoi_crystallize\">Kết tinh Voronoi</string>\n    <string name=\"shape\">Hình dạng</string>\n    <string name=\"stretch\">Kéo dài</string>\n    <string name=\"randomness\">Tính ngẫu nhiên</string>\n    <string name=\"despeckle\">lốm đốm</string>\n    <string name=\"diffuse\">khuếch tán</string>\n    <string name=\"dog\">Chó</string>\n    <string name=\"second_radius\">Bán kính thứ hai</string>\n    <string name=\"equalize\">Cân bằng</string>\n    <string name=\"glow\">Ánh sáng</string>\n    <string name=\"whirl_and_pinch\">Xoay và véo</string>\n    <string name=\"pointillize\">Chấm điểm</string>\n    <string name=\"border_color\">Màu viền</string>\n    <string name=\"polar_coordinates\">tọa độ cực</string>\n    <string name=\"rect_to_polar\">Trực tràng sang cực</string>\n    <string name=\"polar_to_rect\">Cực để chỉnh lưu</string>\n    <string name=\"invert_in_circle\">Đảo ngược trong vòng tròn</string>\n    <string name=\"reduce_noise\">Giảm tiếng ồn</string>\n    <string name=\"simple_solarize\">Năng lượng mặt trời đơn giản</string>\n    <string name=\"weave\">Dệt</string>\n    <string name=\"x_gap\">Khoảng cách X</string>\n    <string name=\"y_gap\">Khoảng cách Y</string>\n    <string name=\"x_width\">Chiều rộng X</string>\n    <string name=\"y_wdth\">Chiều rộng Y</string>\n    <string name=\"twirl\">Xoay tròn</string>\n    <string name=\"rubber_stmp\">Con dấu cao su</string>\n    <string name=\"smear\">bôi nhọ</string>\n    <string name=\"density\">Tỉ trọng</string>\n    <string name=\"mix\">Trộn</string>\n    <string name=\"sphere_lensh_distortion\">Biến dạng thấu kính hình cầu</string>\n    <string name=\"refraction_index\">chỉ số khúc xạ</string>\n    <string name=\"arc\">vòng cung</string>\n    <string name=\"spread_angle\">Góc trải rộng</string>\n    <string name=\"sparkle\">lấp lánh</string>\n    <string name=\"rays\">Tia</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">Độ dốc</string>\n    <string name=\"moire\">Mary</string>\n    <string name=\"autumn\">Mùa thu</string>\n    <string name=\"bone\">Xương</string>\n    <string name=\"jet\">Máy bay phản lực</string>\n    <string name=\"winter\">Mùa đông</string>\n    <string name=\"ocean\">Đại dương</string>\n    <string name=\"summer\">Mùa hè</string>\n    <string name=\"spring\">Mùa xuân</string>\n    <string name=\"cool_variant\">Biến thể thú vị</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"pink\">Hồng</string>\n    <string name=\"hot\">Nóng</string>\n    <string name=\"parula\">Từ</string>\n    <string name=\"magma\">dung nham</string>\n    <string name=\"inferno\">địa ngục</string>\n    <string name=\"plasma\">Huyết tương</string>\n    <string name=\"viridis\">viridis</string>\n    <string name=\"cividis\">Công dân</string>\n    <string name=\"twilight\">Chạng vạng</string>\n    <string name=\"twilight_shifted\">Hoàng hôn đã thay đổi</string>\n    <string name=\"auto_perspective\">Phối cảnh tự động</string>\n    <string name=\"deskew\">nghiêng</string>\n    <string name=\"allow_crop\">Cho phép cắt</string>\n    <string name=\"crop_or_perspective\">Cắt xén hoặc phối cảnh</string>\n    <string name=\"absolute\">tuyệt đối</string>\n    <string name=\"turbo\">tăng áp</string>\n    <string name=\"deep_green\">Màu xanh đậm</string>\n    <string name=\"lens_correction\">Hiệu chỉnh ống kính</string>\n    <string name=\"target_lens_profile\">Tệp hồ sơ ống kính mục tiêu ở định dạng JSON</string>\n    <string name=\"download_ready_lens_profiles\">Tải xuống hồ sơ ống kính sẵn sàng</string>\n    <string name=\"part_percents\">Phần phần trăm</string>\n    <string name=\"export_as_json\">Xuất dưới dạng JSON</string>\n    <string name=\"export_as_json_sub\">Sao chép chuỗi có dữ liệu bảng màu dưới dạng biểu diễn json</string>\n    <string name=\"seam_carving\">Khắc đường may</string>\n    <string name=\"home_screen\">Màn hình chính</string>\n    <string name=\"lock_screen\">Màn hình khóa</string>\n    <string name=\"built_in\">Tích hợp sẵn</string>\n    <string name=\"wallpapers_export\">Xuất hình nền</string>\n    <string name=\"refresh\">Làm cho khỏe lại</string>\n    <string name=\"wallpapers_export_sub\">Lấy hình nền Home, Lock và Built-in hiện tại</string>\n    <string name=\"allow_access_to_all_files_for_wp\">Cho phép truy cập vào tất cả các tập tin, điều này là cần thiết để lấy hình nền</string>\n    <string name=\"allow_read_media_images_for_wp\">Quyền quản lý bộ nhớ ngoài là chưa đủ, bạn cần cho phép truy cập vào hình ảnh của mình, đảm bảo chọn \\\"Cho phép tất cả\\\"</string>\n    <string name=\"add_preset_to_filename\">Thêm cài đặt sẵn vào tên tệp</string>\n    <string name=\"add_preset_to_filename_sub\">Nối hậu tố với giá trị đặt trước đã chọn vào tên tệp hình ảnh</string>\n    <string name=\"add_image_scale_mode_to_filename\">Thêm chế độ tỷ lệ hình ảnh vào tên tệp</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">Nối hậu tố với chế độ tỷ lệ hình ảnh đã chọn vào tên tệp hình ảnh</string>\n    <string name=\"ascii_art\">Nghệ thuật ASCII</string>\n    <string name=\"ascii_art_sub\">Chuyển đổi hình ảnh thành văn bản ASCII trông giống như hình ảnh</string>\n    <string name=\"params\">Thông số</string>\n    <string name=\"invert_colors_ascii_sub\">Áp dụng bộ lọc âm cho hình ảnh để có kết quả tốt hơn trong một số trường hợp</string>\n    <string name=\"processing_screenshot\">Đang xử lý ảnh chụp màn hình</string>\n    <string name=\"screenshot_not_captured_try_again\">Chưa chụp được ảnh màn hình, hãy thử lại</string>\n    <string name=\"skipped_saving\">Đã bỏ qua quá trình lưu</string>\n    <string name=\"skipped_saving_multiple\">%1$s tệp bị bỏ qua</string>\n    <string name=\"allow_skip_if_larger\">Cho phép bỏ qua nếu lớn hơn</string>\n    <string name=\"allow_skip_if_larger_sub\">Một số công cụ sẽ được phép bỏ qua việc lưu hình ảnh nếu kích thước tệp kết quả lớn hơn bản gốc</string>\n    <string name=\"qr_type_calendar_event\">Sự kiện lịch</string>\n    <string name=\"qr_type_contact_info\">Liên hệ</string>\n    <string name=\"qr_type_email\">E-mail</string>\n    <string name=\"qr_type_geo_point\">Vị trí</string>\n    <string name=\"qr_type_phone\">Điện thoại</string>\n    <string name=\"qr_type_plain\">Chữ</string>\n    <string name=\"qr_type_sms\">tin nhắn SMS</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"open_network\">Mạng mở</string>\n    <string name=\"not_specified\">không áp dụng</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">Điện thoại</string>\n    <string name=\"message\">Tin nhắn</string>\n    <string name=\"address\">Địa chỉ</string>\n    <string name=\"subject\">Chủ thể</string>\n    <string name=\"body\">Thân hình</string>\n    <string name=\"name\">Tên</string>\n    <string name=\"organization\">Tổ chức</string>\n    <string name=\"title\">Tiêu đề</string>\n    <string name=\"phones\">Điện thoại</string>\n    <string name=\"emails\">Email</string>\n    <string name=\"urls\">URL</string>\n    <string name=\"addresses\">Địa chỉ</string>\n    <string name=\"summary\">Bản tóm tắt</string>\n    <string name=\"description\">Sự miêu tả</string>\n    <string name=\"location\">Vị trí</string>\n    <string name=\"organizer\">Người tổ chức</string>\n    <string name=\"start_date\">Ngày bắt đầu</string>\n    <string name=\"end_date\">Ngày kết thúc</string>\n    <string name=\"status\">Trạng thái</string>\n    <string name=\"latitude\">Vĩ độ</string>\n    <string name=\"longitude\">Kinh độ</string>\n    <string name=\"create_barcode\">Tạo mã vạch</string>\n    <string name=\"edit_barcode\">Chỉnh sửa mã vạch</string>\n    <string name=\"wifi_configuration\">cấu hình Wi-Fi</string>\n    <string name=\"security\">Bảo vệ</string>\n    <string name=\"pick_contact\">Chọn liên hệ</string>\n    <string name=\"grant_contact_permission\">Cấp quyền cho liên hệ trong cài đặt để tự động điền bằng liên hệ đã chọn</string>\n    <string name=\"contact_info\">Thông tin liên hệ</string>\n    <string name=\"first_name\">Tên</string>\n    <string name=\"middle_name\">Tên đệm</string>\n    <string name=\"last_name\">Họ</string>\n    <string name=\"pronunciation\">Cách phát âm</string>\n    <string name=\"add_phone\">Thêm điện thoại</string>\n    <string name=\"add_email\">Thêm email</string>\n    <string name=\"add_address\">Thêm địa chỉ</string>\n    <string name=\"website\">Trang web</string>\n    <string name=\"add_website\">Thêm trang web</string>\n    <string name=\"formatted_name\">Tên được định dạng</string>\n    <string name=\"qr_code_top_image\">Hình ảnh này sẽ được sử dụng để đặt phía trên mã vạch</string>\n    <string name=\"code_customization\">Tùy chỉnh mã</string>\n    <string name=\"qr_logo_image\">Hình ảnh này sẽ được dùng làm logo ở giữa mã QR</string>\n    <string name=\"logo\">biểu tượng</string>\n    <string name=\"logo_padding\">Phần đệm logo</string>\n    <string name=\"logo_size\">Kích thước biểu tượng</string>\n    <string name=\"logo_corners\">Góc logo</string>\n    <string name=\"fourth_eye\">Con mắt thứ tư</string>\n    <string name=\"fourth_eye_description\">Thêm tính đối xứng của mắt vào mã qr bằng cách thêm con mắt thứ tư ở góc cuối cùng</string>\n    <string name=\"pixel_shape\">Hình dạng pixel</string>\n    <string name=\"frame_shape\">Hình dạng khung</string>\n    <string name=\"ball_shape\">Hình dạng quả bóng</string>\n    <string name=\"error_correction_level\">Mức độ sửa lỗi</string>\n    <string name=\"dark_color\">Màu tối</string>\n    <string name=\"light_color\">Màu sáng</string>\n    <string name=\"hyper_os\">siêu hệ điều hành</string>\n    <string name=\"hyper_os_sub\">Phong cách giống Xiaomi HyperOS</string>\n    <string name=\"mask_pattern\">Mẫu mặt nạ</string>\n    <string name=\"code_may_be_not_scannable\">Mã này có thể không quét được, hãy thay đổi các thông số về giao diện để có thể đọc được trên tất cả các thiết bị</string>\n    <string name=\"not_scannable\">Không thể quét được</string>\n    <string name=\"launcher_mode_sub\">Công cụ sẽ trông giống như trình khởi chạy ứng dụng trên màn hình chính để nhỏ gọn hơn</string>\n    <string name=\"launcher_mode\">Chế độ trình khởi chạy</string>\n    <string name=\"flood_fill_sub\">Đổ đầy vùng bằng cọ và kiểu đã chọn</string>\n    <string name=\"flood_fill\">Lũ lụt</string>\n    <string name=\"spray\">Xịt</string>\n    <string name=\"spray_sub\">Vẽ đường dẫn theo phong cách graffity</string>\n    <string name=\"square_particles\">hạt vuông</string>\n    <string name=\"square_particles_sub\">Hạt phun sẽ có hình vuông thay vì hình tròn</string>\n    <string name=\"palette_tools\">Công cụ bảng màu</string>\n    <string name=\"palette_tools_sub\">Tạo bảng màu cơ bản/chất liệu từ hình ảnh hoặc nhập/xuất trên các định dạng bảng màu khác nhau</string>\n    <string name=\"edit_palette\">Chỉnh sửa bảng màu</string>\n    <string name=\"edit_palette_sub\">Xuất/nhập bảng màu trên nhiều định dạng khác nhau</string>\n    <string name=\"color_name\">Tên màu</string>\n    <string name=\"palette_name\">Tên bảng màu</string>\n    <string name=\"palette_format\">Định dạng bảng màu</string>\n    <string name=\"export_palette_sub\">Xuất bảng màu được tạo sang các định dạng khác nhau</string>\n    <string name=\"add_color_palette_sub\">Thêm màu mới vào bảng màu hiện tại</string>\n    <string name=\"palette_name_not_supported\">Định dạng %1$s không hỗ trợ cung cấp tên bảng màu</string>\n    <string name=\"wallpapers_export_not_avaialbe\">Do chính sách của Cửa hàng Play, tính năng này không thể được đưa vào bản dựng hiện tại. Để truy cập chức năng này, vui lòng tải xuống ImageToolbox từ một nguồn thay thế. Bạn có thể tìm thấy các bản dựng có sẵn trên GitHub bên dưới.</string>\n    <string name=\"open_github_page\">Mở trang Github</string>\n    <string name=\"overwrite_files_sub_short\">Tệp gốc sẽ được thay thế bằng tệp mới thay vì lưu vào thư mục đã chọn</string>\n    <string name=\"hidden_watermark_text_detected\">Đã phát hiện văn bản hình mờ ẩn</string>\n    <string name=\"hidden_watermark_image_detected\">Đã phát hiện hình ảnh mờ ẩn</string>\n    <string name=\"this_image_was_hidden\">Hình ảnh này đã bị ẩn</string>\n    <string name=\"generative_inpaint\">Inpainting sáng tạo</string>\n    <string name=\"generative_inpaint_sub\">Cho phép bạn xóa các đối tượng trong hình ảnh bằng mô hình AI mà không cần dựa vào OpenCV. Để sử dụng tính năng này, ứng dụng sẽ tải xuống mô hình cần thiết (~200 MB) từ GitHub</string>\n    <string name=\"generative_inpaint_ready_sub\">Cho phép bạn xóa các đối tượng trong hình ảnh bằng mô hình AI mà không cần dựa vào OpenCV. Đây có thể là một hoạt động kéo dài</string>\n    <string name=\"error_level_analysis\">Phân tích mức độ lỗi</string>\n    <string name=\"luminance_gradient\">Độ sáng độ sáng</string>\n    <string name=\"average_distance\">Khoảng cách trung bình</string>\n    <string name=\"copy_move_detection\">Sao chép phát hiện di chuyển</string>\n    <string name=\"retain\">Giữ lại</string>\n    <string name=\"coefficent\">hệ số</string>\n    <string name=\"clipboard_data_is_too_large\">Dữ liệu bảng nhớ tạm quá lớn</string>\n    <string name=\"data_is_too_large_to_copy\">Dữ liệu quá lớn để sao chép</string>\n    <string name=\"simple_weave_pixelization\">Pixel hóa dệt đơn giản</string>\n    <string name=\"staggered_pixelization\">Pixelization so le</string>\n    <string name=\"cross_pixelization\">Pixel hóa chéo</string>\n    <string name=\"micro_macro_pixelization\">Pixel hóa vi mô</string>\n    <string name=\"orbital_pixelization\">Pixel hóa quỹ đạo</string>\n    <string name=\"vortex_pixelization\">Pixel hóa xoáy</string>\n    <string name=\"pulse_grid_pixelization\">Pixel hóa lưới xung</string>\n    <string name=\"nucleus_pixelization\">Pixel hóa hạt nhân</string>\n    <string name=\"radial_weave_pixelization\">Pixel hóa xuyên tâm</string>\n    <string name=\"cannot_open_uri\">Không thể mở uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">Chế độ tuyết rơi</string>\n    <string name=\"enabled\">Đã bật</string>\n    <string name=\"border_frame\">Khung viền</string>\n    <string name=\"glitch_variant\">Biến thể trục trặc</string>\n    <string name=\"channel_shift\">Chuyển kênh</string>\n    <string name=\"max_offset\">Bù tối đa</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"block_glitch\">Chặn trục trặc</string>\n    <string name=\"block_size\">Kích thước khối</string>\n    <string name=\"crt_curvature\">độ cong CRT</string>\n    <string name=\"curvature\">độ cong</string>\n    <string name=\"chroma\">sắc độ</string>\n    <string name=\"pixel_melt\">Điểm ảnh tan chảy</string>\n    <string name=\"max_drop\">Giảm tối đa</string>\n    <string name=\"ai_tools\">Công cụ AI</string>\n    <string name=\"ai_tools_sub\">Nhiều công cụ khác nhau để xử lý hình ảnh thông qua các mô hình ai như loại bỏ hoặc khử nhiễu</string>\n    <string name=\"model_anime_undeint\">Đường nén, răng cưa</string>\n    <string name=\"model_broadcast\">Phim hoạt hình, nén phát sóng</string>\n    <string name=\"model_rgb_max_denoise_fp16\">Nén chung, nhiễu chung</string>\n    <string name=\"model_wb_denoise\">Tiếng ồn hoạt hình không màu</string>\n    <string name=\"model_span_anime_pretrain\">Nhanh, nén chung, nhiễu chung, hoạt hình/truyện tranh/anime</string>\n    <string name=\"model_book_scan\">Quét sách</string>\n    <string name=\"model_overexposure\">Chỉnh sửa phơi sáng</string>\n    <string name=\"model_fbcnn_color_fp16\">Tốt nhất ở khả năng nén chung, hình ảnh màu</string>\n    <string name=\"model_fbcnn_gray_fp16\">Tốt nhất ở khả năng nén chung, hình ảnh thang độ xám</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">Nén chung, hình ảnh thang độ xám, mạnh hơn</string>\n    <string name=\"model_scunet_color_gan_fp16\">Nhiễu chung, hình ảnh màu</string>\n    <string name=\"model_scunet_color_psnr_fp16\">Nhiễu chung, hình ảnh màu sắc, chi tiết tốt hơn</string>\n    <string name=\"model_scunet_gray_15_fp16\">Nhiễu chung, hình ảnh thang độ xám</string>\n    <string name=\"model_scunet_gray_25_fp16\">Nhiễu chung, hình ảnh thang độ xám, mạnh hơn</string>\n    <string name=\"model_scunet_gray_50_fp16\">Nhiễu chung, hình ảnh thang độ xám, mạnh nhất</string>\n    <string name=\"model_jpeg_destroyer\">Nén chung</string>\n    <string name=\"model_jaywreck\">Nén chung</string>\n    <string name=\"model_h264\">Kết cấu, nén h264</string>\n    <string name=\"model_vhs\">nén VHS</string>\n    <string name=\"model_cinepak\">Nén không chuẩn (cinepak, msvideo1, roq)</string>\n    <string name=\"model_debink_v4\">Nén Bink, tốt hơn về hình học</string>\n    <string name=\"model_debink_v5\">Nén Bink, mạnh mẽ hơn</string>\n    <string name=\"model_debink_v6\">Nén Bink, mềm mại, giữ lại chi tiết</string>\n    <string name=\"model_antialias\">Loại bỏ hiệu ứng bậc thang, làm mịn</string>\n    <string name=\"model_kdm_scans\">Nghệ thuật/bản vẽ được quét, nén nhẹ, moire</string>\n    <string name=\"model_bandage\">Dải màu</string>\n    <string name=\"model_halftone\">Chậm, loại bỏ ảnh bán sắc</string>\n    <string name=\"model_colorizer\">Bộ tạo màu chung cho hình ảnh thang độ xám/bw, để có kết quả tốt hơn, hãy sử dụng DDColor</string>\n    <string name=\"model_deedge\">Loại bỏ cạnh</string>\n    <string name=\"model_desharpen\">Loại bỏ hiện tượng sắc nét quá mức</string>\n    <string name=\"model_dither\">Chậm, phối màu</string>\n    <string name=\"model_gainres\">Khử răng cưa, tạo tác chung, CGI</string>\n    <string name=\"model_kdm003_scans\">Xử lý quét KDM003</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">Mô hình nâng cao hình ảnh nhẹ</string>\n    <string name=\"model_bcgone_detailed_v2\">Loại bỏ tạo tác nén</string>\n    <string name=\"model_bcgone_smooth\">Loại bỏ tạo tác nén</string>\n    <string name=\"model_bandage_smooth\">Loại bỏ băng với kết quả mịn màng</string>\n    <string name=\"model_bendel_halftone\">Xử lý mẫu bán sắc</string>\n    <string name=\"model_dither_deleter_v3_smooth\">Loại bỏ mô hình hoà sắc V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">Loại bỏ tạo tác JPEG V2</string>\n    <string name=\"model_nmkd_h264_texturize\">Cải tiến kết cấu H.264</string>\n    <string name=\"model_vhs_sharpen\">Làm sắc nét và nâng cao VHS</string>\n    <string name=\"merging\">Sáp nhập</string>\n    <string name=\"chunk_size\">Kích thước đoạn</string>\n    <string name=\"overlap_size\">Kích thước chồng chéo</string>\n    <string name=\"note_chunk_info\">Hình ảnh trên %1$s px sẽ được cắt và xử lý thành nhiều phần, chồng chéo các phần này để tránh nhìn thấy các đường nối.</string>\n    <string name=\"large_chunk_warning\">Kích thước lớn có thể gây mất ổn định với thiết bị cấp thấp</string>\n    <string name=\"select_one_to_start\">Chọn một để bắt đầu</string>\n    <string name=\"delete_model_sub\">Bạn có muốn xóa mô hình %1$s không? Bạn sẽ cần phải tải xuống lại</string>\n    <string name=\"confirm\">Xác nhận</string>\n    <string name=\"models\">Người mẫu</string>\n    <string name=\"downloaded_models\">Mô hình đã tải xuống</string>\n    <string name=\"available_models\">Các mẫu có sẵn</string>\n    <string name=\"preparing\">Chuẩn bị</string>\n    <string name=\"active_model\">Mô hình hoạt động</string>\n    <string name=\"failed_to_open_session\">Không mở được phiên</string>\n    <string name=\"only_onnx_models\">Chỉ có thể nhập các mô hình .onnx/.ort</string>\n    <string name=\"import_model\">Mô hình nhập khẩu</string>\n    <string name=\"import_model_sub\">Nhập mô hình onnx tùy chỉnh để sử dụng tiếp, chỉ các mô hình onnx/ort mới được chấp nhận, hỗ trợ hầu hết tất cả các biến thể giống như esrgan</string>\n    <string name=\"imported_models\">Model nhập khẩu</string>\n    <string name=\"model_scunet_color_15_fp16\">Tiếng ồn chung, hình ảnh màu</string>\n    <string name=\"model_scunet_color_25_fp16\">Nhiễu chung, hình ảnh có màu sắc, mạnh mẽ hơn</string>\n    <string name=\"model_scunet_color_50_fp16\">Nhiễu chung, hình ảnh màu, mạnh nhất</string>\n    <string name=\"model_artifacts_dithering_alsa\">Giảm hiện tượng phối màu và dải màu, cải thiện độ chuyển màu mượt mà và vùng màu phẳng.</string>\n    <string name=\"model_nmkd_brighten_redux\">Tăng cường độ sáng và độ tương phản của hình ảnh với các điểm sáng cân bằng trong khi vẫn giữ được màu sắc tự nhiên.</string>\n    <string name=\"model_nmkd_brighten\">Làm sáng hình ảnh tối trong khi vẫn giữ được chi tiết và tránh phơi sáng quá mức.</string>\n    <string name=\"model_nmkd_detoon\">Loại bỏ tông màu quá mức và khôi phục lại sự cân bằng màu sắc trung tính và tự nhiên hơn.</string>\n    <string name=\"model_noise_toner_poisson_detailed\">Áp dụng giảm nhiễu dựa trên Poisson với sự nhấn mạnh vào việc giữ nguyên các chi tiết và kết cấu đẹp.</string>\n    <string name=\"model_noise_toner_poisson_soft\">Áp dụng giảm nhiễu Poisson mềm mại để mang lại kết quả hình ảnh mượt mà hơn và ít hung hãn hơn.</string>\n    <string name=\"model_noise_toner_uniform_detailed\">Giảm nhiễu đồng đều tập trung vào việc bảo toàn chi tiết và độ rõ nét của hình ảnh.</string>\n    <string name=\"model_noise_toner_uniform_soft\">Giảm tiếng ồn đồng đều nhẹ nhàng cho kết cấu tinh tế và vẻ ngoài mịn màng.</string>\n    <string name=\"model_repainter\">Sửa chữa các khu vực bị hư hỏng hoặc không bằng phẳng bằng cách sơn lại các đồ tạo tác và cải thiện tính nhất quán của hình ảnh.</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">Mô hình tháo gỡ nhẹ giúp loại bỏ dải màu với chi phí hiệu suất tối thiểu.</string>\n    <string name=\"model_jpeg_0_20\">Tối ưu hóa hình ảnh có độ nén rất cao (chất lượng 0-20%) để cải thiện độ rõ nét.</string>\n    <string name=\"model_jpeg_20_40\">Nâng cao hình ảnh với các tạo tác nén cao (chất lượng 20-40%), khôi phục chi tiết và giảm nhiễu.</string>\n    <string name=\"model_jpeg_40_60\">Cải thiện hình ảnh với độ nén vừa phải (chất lượng 40-60%), cân bằng độ sắc nét và mượt mà.</string>\n    <string name=\"model_jpeg_60_80\">Tinh chỉnh hình ảnh bằng cách nén nhẹ (chất lượng 60-80%) để nâng cao các chi tiết và kết cấu tinh tế.</string>\n    <string name=\"model_jpeg_80_100\">Tăng cường một chút hình ảnh gần như không bị mất chất lượng (chất lượng 80-100%) trong khi vẫn giữ được vẻ tự nhiên và chi tiết.</string>\n    <string name=\"model_spongecolor_lite\">Tô màu đơn giản và nhanh chóng, phim hoạt hình, không lý tưởng</string>\n    <string name=\"model_deblr\">Giảm nhẹ độ mờ của hình ảnh, cải thiện độ sắc nét mà không gây hiện tượng giả tạo.</string>\n    <string name=\"processing_channel\">Hoạt động chạy dài</string>\n    <string name=\"processing_image\">Đang xử lý hình ảnh</string>\n    <string name=\"processing\">Xử lý</string>\n    <string name=\"model_artifacts_jpg_0_20\">Loại bỏ các thành phần nén JPEG nặng ở hình ảnh có chất lượng rất thấp (0-20%).</string>\n    <string name=\"model_artifacts_jpg_20_40\">Giảm hiện vật JPEG mạnh ở hình ảnh có độ nén cao (20-40%).</string>\n    <string name=\"model_artifacts_jpg_40_60\">Dọn dẹp các hiện vật JPEG vừa phải trong khi vẫn giữ được chi tiết hình ảnh (40-60%).</string>\n    <string name=\"model_artifacts_jpg_60_80\">Tinh chỉnh các tạo tác JPEG nhẹ ở hình ảnh chất lượng khá cao (60-80%).</string>\n    <string name=\"model_artifacts_jpg_80_100\">Giảm một cách tinh tế các hiện vật JPEG nhỏ trong hình ảnh gần như không mất dữ liệu (80-100%).</string>\n    <string name=\"model_redetail_v2\">Tăng cường các chi tiết và kết cấu đẹp mắt, cải thiện độ sắc nét cảm nhận được mà không tạo ra hiện tượng giả tạo nặng nề.</string>\n    <string name=\"processing_finished\">Xử lý xong</string>\n    <string name=\"processing_failed\">Xử lý không thành công</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">Tăng cường kết cấu và chi tiết da trong khi vẫn giữ vẻ tự nhiên, tối ưu hóa tốc độ.</string>\n    <string name=\"model_sbdv_dejpeg\">Loại bỏ các thành phần nén JPEG và khôi phục chất lượng hình ảnh cho ảnh nén.</string>\n    <string name=\"model_iso_denoise_v1\">Giảm nhiễu ISO trong ảnh chụp trong điều kiện ánh sáng yếu, giữ nguyên chi tiết.</string>\n    <string name=\"model_dejumbo\">Chỉnh sửa các điểm nổi bật bị phơi sáng quá mức hoặc “jumbo” và khôi phục lại sự cân bằng tông màu tốt hơn.</string>\n    <string name=\"model_ddcolor_tiny\">Mô hình tô màu nhẹ và nhanh giúp bổ sung màu sắc tự nhiên cho hình ảnh thang độ xám.</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">Khử nhiễu</string>\n    <string name=\"type_colorize\">Tô màu</string>\n    <string name=\"type_artifacts\">Hiện vật</string>\n    <string name=\"type_enhance\">Nâng cao</string>\n    <string name=\"type_anime\">Anime</string>\n    <string name=\"type_scans\">Quét</string>\n    <string name=\"type_upscale\">cao cấp</string>\n    <string name=\"model_realesrgan_x4v3\">Trình nâng cấp X4 cho hình ảnh chung; mô hình nhỏ sử dụng ít GPU và thời gian hơn, với khả năng khử nhiễu và làm mờ vừa phải.</string>\n    <string name=\"model_realesrgan_x2plus\">Bộ nâng cấp X2 cho hình ảnh tổng thể, giữ nguyên kết cấu và chi tiết tự nhiên.</string>\n    <string name=\"model_realesrgan_x4plus\">Trình nâng cấp X4 cho hình ảnh chung với kết cấu nâng cao và kết quả chân thực.</string>\n    <string name=\"model_realesrgan_x4plus_anime\">Trình nâng cấp X4 được tối ưu hóa cho hình ảnh anime; 6 khối RRDB cho đường nét và chi tiết sắc nét hơn.</string>\n    <string name=\"model_realesrnet_x4plus\">Bộ nâng cấp X4 với tính năng mất MSE, tạo ra kết quả mượt mà hơn và giảm hiện vật giả cho hình ảnh thông thường.</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler được tối ưu hóa cho hình ảnh anime; Biến thể 4B32F với các chi tiết sắc nét hơn và đường nét mượt mà hơn.</string>\n    <string name=\"model_ultrasharp_v2_x4\">Model X4 UltraSharp V2 cho hình ảnh thông thường; nhấn mạnh độ sắc nét và rõ ràng.</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite; nhanh hơn và nhỏ hơn, bảo toàn chi tiết trong khi sử dụng ít bộ nhớ GPU hơn.</string>\n    <string name=\"model_rmbg_1_4\">Mô hình nhẹ để loại bỏ nền nhanh chóng. Hiệu suất cân bằng và độ chính xác. Hoạt động với chân dung, đồ vật và cảnh. Được đề xuất cho hầu hết các trường hợp sử dụng.</string>\n    <string name=\"type_removebg\">Xóa BG</string>\n    <string name=\"horizontal_border_thickness\">Độ dày viền ngang</string>\n    <string name=\"vertical_border_thickness\">Độ dày viền dọc</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s màu sắc</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">Model hiện tại không hỗ trợ chunking, hình ảnh sẽ được xử lý ở kích thước gốc, điều này có thể gây ra mức tiêu thụ bộ nhớ cao và sự cố với các thiết bị cấp thấp</string>\n    <string name=\"chunking_disabled\">Tính năng phân đoạn bị tắt, hình ảnh sẽ được xử lý ở kích thước ban đầu, điều này có thể gây ra mức tiêu thụ bộ nhớ cao và sự cố với các thiết bị cấp thấp nhưng có thể cho kết quả suy luận tốt hơn</string>\n    <string name=\"chunking\">Cắt nhỏ</string>\n    <string name=\"model_u2net\">Mô hình phân đoạn hình ảnh có độ chính xác cao để loại bỏ nền</string>\n    <string name=\"model_u2netp\">Phiên bản nhẹ của U2Net giúp xóa nền nhanh hơn với mức sử dụng bộ nhớ nhỏ hơn.</string>\n    <string name=\"model_ddcolor\">Mô hình DDColor đầy đủ mang lại màu sắc chất lượng cao cho hình ảnh thông thường với ít hiện tượng giả mạo nhất. Sự lựa chọn tốt nhất trong tất cả các mô hình tô màu.</string>\n    <string name=\"model_ddcolor_artistic\">DDColor Bộ dữ liệu nghệ thuật riêng tư và được đào tạo; tạo ra kết quả tô màu đa dạng và nghệ thuật với ít hiện vật màu phi thực tế hơn.</string>\n    <string name=\"model_birefnet\">Mô hình BiRefNet nhẹ dựa trên Swin Transformer để loại bỏ nền chính xác.</string>\n    <string name=\"model_inspyrenet\">Loại bỏ nền chất lượng cao với các cạnh sắc nét và bảo toàn chi tiết tuyệt vời, đặc biệt là trên các đối tượng phức tạp và nền phức tạp.</string>\n    <string name=\"model_isnet\">Mô hình xóa nền tạo ra mặt nạ chính xác với các cạnh mịn, phù hợp với các đối tượng thông thường và bảo toàn chi tiết vừa phải.</string>\n    <string name=\"model_already_downloaded\">Mô hình đã được tải xuống</string>\n    <string name=\"model_successfully_imported\">Đã nhập mô hình thành công</string>\n    <string name=\"type\">Kiểu</string>\n    <string name=\"keyword\">Từ khóa</string>\n    <string name=\"very_fast\">Rất nhanh</string>\n    <string name=\"normal\">Bình thường</string>\n    <string name=\"slow\">Chậm</string>\n    <string name=\"very_slow\">Rất chậm</string>\n    <string name=\"compute_percents\">Tính phần trăm</string>\n    <string name=\"minimum_value_is\">Giá trị tối thiểu là %1$s</string>\n    <string name=\"warp_sub\">Làm biến dạng hình ảnh bằng cách vẽ bằng ngón tay</string>\n    <string name=\"warp\">Làm cong vênh</string>\n    <string name=\"hardness\">độ cứng</string>\n    <string name=\"warp_mode\">Chế độ dọc</string>\n    <string name=\"warp_mode_move\">Di chuyển</string>\n    <string name=\"warp_mode_grow\">Phát triển</string>\n    <string name=\"warp_mode_shrink\">Thu nhỏ</string>\n    <string name=\"warp_mode_swirl_cw\">Xoáy CW</string>\n    <string name=\"warp_mode_swirl_ccw\">xoáy CCW</string>\n    <string name=\"fade_strength\">Sức mạnh phai nhạt</string>\n    <string name=\"top_drop\">Thả hàng đầu</string>\n    <string name=\"bottom_drop\">Thả dưới cùng</string>\n    <string name=\"start_drop\">Bắt đầu thả</string>\n    <string name=\"end_drop\">Thả cuối</string>\n    <string name=\"downloading\">Đang tải xuống</string>\n    <string name=\"smooth_shapes\">Hình dạng mượt mà</string>\n    <string name=\"smooth_shapes_sub\">Sử dụng hình siêu elip thay vì hình chữ nhật bo tròn tiêu chuẩn để có hình dạng mượt mà, tự nhiên hơn</string>\n    <string name=\"shape_type\">Loại hình dạng</string>\n    <string name=\"cut\">Cắt</string>\n    <string name=\"rounded\">làm tròn</string>\n    <string name=\"smooth\">Trơn tru</string>\n    <string name=\"cut_shapes_sub\">Các cạnh sắc nét mà không làm tròn</string>\n    <string name=\"rounded_shapes_sub\">Các góc bo tròn cổ điển</string>\n    <string name=\"shapes_type\">Loại hình dạng</string>\n    <string name=\"corners_size\">Kích thước góc</string>\n    <string name=\"squircle\">hình tròn</string>\n    <string name=\"squircle_shapes_sub\">Các thành phần UI được bo tròn trang nhã</string>\n    <string name=\"filename_format\">Định dạng tên tệp</string>\n    <string name=\"prefix_pattern_description\">Văn bản tùy chỉnh được đặt ở đầu tên tệp, hoàn hảo cho tên dự án, nhãn hiệu hoặc thẻ cá nhân.</string>\n    <string name=\"original_filename_pattern_description\">Sử dụng tên tệp gốc không có phần mở rộng, giúp bạn giữ nguyên nhận dạng nguồn.</string>\n    <string name=\"width_pattern_description\">Chiều rộng hình ảnh tính bằng pixel, hữu ích để theo dõi các thay đổi về độ phân giải hoặc kết quả chia tỷ lệ.</string>\n    <string name=\"height_pattern_description\">Chiều cao hình ảnh tính bằng pixel, hữu ích khi làm việc với tỷ lệ khung hình hoặc xuất.</string>\n    <string name=\"random_numbers_pattern_description\">Tạo các chữ số ngẫu nhiên để đảm bảo tên tệp duy nhất; thêm nhiều chữ số để tăng cường an toàn chống lại sự trùng lặp.</string>\n    <string name=\"sequence_number_pattern_description\">Bộ đếm tăng tự động để xuất hàng loạt, lý tưởng khi lưu nhiều hình ảnh trong một phiên.</string>\n    <string name=\"preset_info_pattern_description\">Chèn tên đặt trước đã áp dụng vào tên tệp để bạn có thể dễ dàng nhớ cách xử lý hình ảnh.</string>\n    <string name=\"scale_mode_pattern_description\">Hiển thị chế độ chia tỷ lệ hình ảnh được sử dụng trong quá trình xử lý, giúp phân biệt hình ảnh đã thay đổi kích thước, cắt xén hoặc vừa vặn.</string>\n    <string name=\"suffix_pattern_description\">Văn bản tùy chỉnh được đặt ở cuối tên tệp, hữu ích cho việc lập phiên bản như _v2, _edited hoặc _final.</string>\n    <string name=\"extension_pattern_description\">Phần mở rộng tệp (png, jpg, webp, v.v.), tự động khớp với định dạng đã lưu thực tế.</string>\n    <string name=\"formatted_timestamp_pattern_description\">Một dấu thời gian có thể tùy chỉnh cho phép bạn xác định định dạng riêng theo đặc tả Java để sắp xếp hoàn hảo.</string>\n    <string name=\"fling_type\">Loại ném</string>\n    <string name=\"android_native\">Android gốc</string>\n    <string name=\"ios_style\">Phong cách iOS</string>\n    <string name=\"smooth_curve\">Đường cong mượt mà</string>\n    <string name=\"quick_stop\">Dừng nhanh</string>\n    <string name=\"bouncy\">nảy</string>\n    <string name=\"floaty\">nổi</string>\n    <string name=\"snappy\">nhanh nhẹn</string>\n    <string name=\"ultra_smooth\">siêu mịn</string>\n    <string name=\"adaptive\">Thích ứng</string>\n    <string name=\"accessibility_aware\">Nhận thức về khả năng truy cập</string>\n    <string name=\"reduced_motion\">Giảm chuyển động</string>\n    <string name=\"android_native_sub\">Vật lý cuộn Android gốc</string>\n    <string name=\"smooth_sub\">Cuộn cân bằng, mượt mà để sử dụng chung</string>\n    <string name=\"ios_style_sub\">Hành vi cuộn giống iOS có độ ma sát cao hơn</string>\n    <string name=\"smooth_curve_sub\">Đường cong spline độc đáo cho cảm giác cuộn khác biệt</string>\n    <string name=\"quick_stop_sub\">Cuộn chính xác với tính năng dừng nhanh</string>\n    <string name=\"bouncy_sub\">Cuộn nảy vui tươi, nhạy bén</string>\n    <string name=\"floaty_sub\">Cuộn dài, lướt để duyệt nội dung</string>\n    <string name=\"snappy_sub\">Cuộn nhanh, nhạy cho giao diện người dùng tương tác</string>\n    <string name=\"ultra_smooth_sub\">Cuộn mượt mà cao cấp với động lượng kéo dài</string>\n    <string name=\"adaptive_sub\">Điều chỉnh vật lý dựa trên tốc độ ném</string>\n    <string name=\"accessibility_aware_sub\">Tôn trọng cài đặt khả năng truy cập của hệ thống</string>\n    <string name=\"reduced_motion_sub\">Chuyển động tối thiểu cho nhu cầu tiếp cận</string>\n    <string name=\"primary_lines\">Dòng chính</string>\n    <string name=\"primary_lines_sub\">Thêm dòng dày hơn vào mỗi dòng thứ năm</string>\n    <string name=\"fill_color\">Tô màu</string>\n    <string name=\"hidden_tools\">Công cụ ẩn</string>\n    <string name=\"hidden_for_share\">Công cụ ẩn để chia sẻ</string>\n    <string name=\"color_library\">Thư viện màu</string>\n    <string name=\"color_library_sub\">Duyệt qua một bộ sưu tập lớn các màu sắc</string>\n    <string name=\"model_fatality_deblur\">Làm sắc nét và xóa mờ khỏi hình ảnh trong khi vẫn duy trì các chi tiết tự nhiên, lý tưởng để sửa ảnh mất nét.</string>\n    <string name=\"model_unresize_v3\">Khôi phục thông minh các hình ảnh đã được thay đổi kích thước trước đó, khôi phục các chi tiết và kết cấu bị mất.</string>\n    <string name=\"model_liveaction_v1_span\">Được tối ưu hóa cho nội dung người thật đóng, giảm hiện tượng nén giả và tăng cường chi tiết đẹp trong khung hình phim/chương trình truyền hình.</string>\n    <string name=\"model_vhs2hd_realplksr\">Chuyển đổi cảnh quay chất lượng VHS thành HD, loại bỏ nhiễu băng và nâng cao độ phân giải trong khi vẫn giữ được cảm giác cổ điển.</string>\n    <string name=\"model_text2hd_v1\">Chuyên dùng cho hình ảnh và ảnh chụp màn hình có nhiều văn bản, làm sắc nét các ký tự và cải thiện khả năng đọc.</string>\n    <string name=\"model_frankendata_pretrainer\">Nâng cấp nâng cao được đào tạo trên các bộ dữ liệu đa dạng, tuyệt vời để cải thiện ảnh cho mục đích chung.</string>\n    <string name=\"model_realwebphoto_v2\">Tối ưu hóa cho ảnh nén trên web, loại bỏ các thành phần giả JPEG và khôi phục hình thức tự nhiên.</string>\n    <string name=\"model_realwebphoto_v4\">Phiên bản cải tiến dành cho ảnh trên web với khả năng bảo toàn kết cấu và giảm hiện vật tốt hơn.</string>\n    <string name=\"model_dat_2x\">Nâng cấp gấp 2 lần với công nghệ Biến áp tập hợp kép, duy trì độ sắc nét và chi tiết tự nhiên.</string>\n    <string name=\"model_dat_3x\">Nâng kích thước 3x sử dụng kiến trúc biến áp tiên tiến, lý tưởng cho nhu cầu phóng to vừa phải.</string>\n    <string name=\"model_dat_4x\">Nâng cấp chất lượng cao gấp 4 lần với mạng biến áp hiện đại, bảo toàn các chi tiết đẹp ở quy mô lớn hơn.</string>\n    <string name=\"model_nafnet_deblurring\">Loại bỏ hiện tượng mờ/nhiễu và rung lắc khỏi ảnh. Mục đích chung nhưng tốt nhất trên ảnh.</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">Khôi phục hình ảnh chất lượng thấp bằng biến áp Swin2SR, được tối ưu hóa cho sự suy giảm BSRGAN. Tuyệt vời để sửa các hiện vật nén nặng và nâng cao chi tiết ở tỷ lệ 4x.</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">Nâng cấp gấp 4 lần với máy biến áp SwinIR được đào tạo về suy giảm BSRGAN. Sử dụng GAN để có kết cấu sắc nét hơn và nhiều chi tiết tự nhiên hơn trong ảnh và cảnh phức tạp.</string>\n    <string name=\"path\">Con đường</string>\n    <string name=\"merge_pdf\">Hợp nhất PDF</string>\n    <string name=\"merge_pdf_sub\">Kết hợp nhiều tệp PDF vào một tài liệu</string>\n    <string name=\"files_order\">Thứ tự tập tin</string>\n    <string name=\"pages_short\">trang.</string>\n    <string name=\"split_pdf\">Tách PDF</string>\n    <string name=\"split_pdf_sub\">Trích xuất các trang cụ thể từ tài liệu PDF</string>\n    <string name=\"rotate_pdf\">Xoay PDF</string>\n    <string name=\"rotate_pdf_sub\">Sửa hướng trang vĩnh viễn</string>\n    <string name=\"pages\">Trang</string>\n    <string name=\"rearrange_pdf\">Sắp xếp lại PDF</string>\n    <string name=\"rearrange_pdf_sub\">Kéo và thả các trang để sắp xếp lại chúng</string>\n    <string name=\"hold_drag_drop\">Giữ và kéo trang</string>\n    <string name=\"page_numbers\">Số trang</string>\n    <string name=\"page_numbers_sub\">Tự động thêm đánh số vào tài liệu của bạn</string>\n    <string name=\"label_format\">Định dạng nhãn</string>\n    <string name=\"pdf_to_text\">PDF sang văn bản (OCR)</string>\n    <string name=\"pdf_to_text_sub\">Trích xuất văn bản thuần túy từ tài liệu PDF của bạn</string>\n    <string name=\"watermark_pdf_sub\">Lớp phủ văn bản tùy chỉnh để xây dựng thương hiệu hoặc bảo mật</string>\n    <string name=\"signature\">Chữ ký</string>\n    <string name=\"signature_sub\">Thêm chữ ký điện tử của bạn vào bất kỳ tài liệu nào</string>\n    <string name=\"will_be_for_signature\">Điều này sẽ được sử dụng làm chữ ký</string>\n    <string name=\"unlock_pdf\">Mở khóa PDF</string>\n    <string name=\"unlock_pdf_sub\">Xóa mật khẩu khỏi các tệp được bảo vệ của bạn</string>\n    <string name=\"protect_pdf\">Bảo vệ PDF</string>\n    <string name=\"protect_pdf_sub\">Bảo mật tài liệu của bạn bằng mã hóa mạnh mẽ</string>\n    <string name=\"success\">Thành công</string>\n    <string name=\"pdf_unlocked\">Đã mở khóa PDF, bạn có thể lưu hoặc chia sẻ nó</string>\n    <string name=\"repair_pdf\">Sửa chữa PDF</string>\n    <string name=\"repair_pdf_sub\">Cố gắng sửa các tài liệu bị hỏng hoặc không thể đọc được</string>\n    <string name=\"grayscale\">Thang độ xám</string>\n    <string name=\"grayscale_pdf_sub\">Chuyển đổi tất cả các hình ảnh được nhúng trong tài liệu sang thang độ xám</string>\n    <string name=\"compress_pdf\">Nén PDF</string>\n    <string name=\"compress_pdf_sub\">Tối ưu hóa kích thước tệp tài liệu của bạn để chia sẻ dễ dàng hơn</string>\n    <string name=\"repair_info\">ImageToolbox xây dựng lại bảng tham chiếu chéo nội bộ và tạo lại cấu trúc tệp từ đầu. Điều này có thể khôi phục quyền truy cập vào nhiều tệp \\\\\"không thể mở được\\\\\"</string>\n    <string name=\"grayscale_info\">Công cụ này chuyển đổi tất cả hình ảnh tài liệu sang thang độ xám. Tốt nhất để in và giảm kích thước tập tin</string>\n    <string name=\"metadata\">Siêu dữ liệu</string>\n    <string name=\"metadata_pdf_sub\">Chỉnh sửa thuộc tính tài liệu để bảo mật tốt hơn</string>\n    <string name=\"tags\">Thẻ</string>\n    <string name=\"producer\">Nhà sản xuất</string>\n    <string name=\"author\">Tác giả</string>\n    <string name=\"keywords\">Từ khóa</string>\n    <string name=\"creator\">Người sáng tạo</string>\n    <string name=\"privacy_deep_clean\">Quyền riêng tư Sạch sâu</string>\n    <string name=\"privacy_deep_clean_sub\">Xóa tất cả siêu dữ liệu có sẵn cho tài liệu này</string>\n    <string name=\"page\">Trang</string>\n    <string name=\"deep_ocr\">OCR sâu</string>\n    <string name=\"deep_ocr_sub\">Trích xuất văn bản từ tài liệu và lưu trữ nó trong một tệp văn bản bằng công cụ Tesseract</string>\n    <string name=\"cant_remove_all\">Không thể xóa tất cả các trang</string>\n    <string name=\"remove_pages_pdf\">Xóa các trang PDF</string>\n    <string name=\"remove_pages_pdf_sub\">Xóa các trang cụ thể khỏi tài liệu PDF</string>\n    <string name=\"tap_to_remove\">Nhấn để xóa</string>\n    <string name=\"manually\">thủ công</string>\n    <string name=\"crop_pdf\">Cắt PDF</string>\n    <string name=\"crop_pdf_sub\">Cắt các trang tài liệu theo bất kỳ giới hạn nào</string>\n    <string name=\"flatten_pdf\">Làm phẳng PDF</string>\n    <string name=\"flatten_pdf_sub\">Làm cho PDF không thể sửa đổi bằng cách rastering các trang tài liệu</string>\n    <string name=\"camera_failed_to_open\">Không thể khởi động máy ảnh. Vui lòng kiểm tra quyền và đảm bảo rằng nó không được ứng dụng khác sử dụng.</string>\n    <string name=\"extract_images\">Trích xuất hình ảnh</string>\n    <string name=\"extract_images_sub\">Trích xuất hình ảnh được nhúng trong tệp PDF ở độ phân giải gốc</string>\n    <string name=\"pdf_no_embedded\">Tệp PDF này không chứa bất kỳ hình ảnh nhúng nào</string>\n    <string name=\"extract_images_info\">Công cụ này quét mọi trang và khôi phục hình ảnh nguồn có chất lượng đầy đủ — hoàn hảo để lưu bản gốc từ tài liệu</string>\n    <string name=\"draw_signature\">Vẽ chữ ký</string>\n    <string name=\"pen_params\">Thông số bút</string>\n    <string name=\"draw_signature_sub\">Sử dụng chữ ký của chính mình làm hình ảnh để đặt trên tài liệu</string>\n    <string name=\"zip_pdf\">Nén PDF</string>\n    <string name=\"zip_pdf_sub\">Chia tài liệu theo khoảng thời gian nhất định và đóng gói tài liệu mới vào kho lưu trữ zip</string>\n    <string name=\"interval\">Khoảng thời gian</string>\n    <string name=\"print_pdf\">In PDF</string>\n    <string name=\"print_pdf_sub\">Chuẩn bị tài liệu để in với kích thước trang tùy chỉnh</string>\n    <string name=\"pages_per_sheet\">Số trang trên mỗi tờ</string>\n    <string name=\"orientation\">Định hướng</string>\n    <string name=\"page_size\">Kích thước trang</string>\n    <string name=\"margin\">Lề</string>\n    <string name=\"bloom\">Hoa</string>\n    <string name=\"soft_knee\">Đầu gối mềm</string>\n    <string name=\"model_realesr_animevideo_v3x4\">Tối ưu hóa cho anime và phim hoạt hình. Nâng cấp nhanh chóng với màu sắc tự nhiên được cải thiện và ít hiện vật hơn</string>\n    <string name=\"one_ui_sub\">Phong cách giống Samsung One UI 7</string>\n    <string name=\"calculate_hint\">Nhập các ký hiệu toán học cơ bản vào đây để tính giá trị mong muốn (ví dụ: (5+5)*10)</string>\n    <string name=\"math_expression\">biểu thức toán học</string>\n    <string name=\"pick_up_to_n_collage_images\">Chọn tối đa %1$s hình ảnh</string>\n    <string name=\"keep_date_time\">Giữ ngày giờ</string>\n    <string name=\"keep_date_time_sub\">Luôn lưu giữ các thẻ Exif liên quan đến ngày và giờ, hoạt động độc lập với tùy chọn giữ nguyên</string>\n    <string name=\"background_color_for_alpha_formats\">Màu nền cho định dạng Alpha</string>\n    <string name=\"background_color_for_alpha_formats_sub\">Thêm khả năng đặt màu nền cho mọi định dạng hình ảnh có hỗ trợ alpha, khi bị tắt, tính năng này chỉ khả dụng cho những định dạng không phải alpha</string>\n    <string name=\"open_markup_project\">Dự án mở</string>\n    <string name=\"open_markup_project_sub\">Tiếp tục chỉnh sửa dự án Hộp công cụ Hình ảnh đã lưu trước đó</string>\n    <string name=\"markup_project_open_failed\">Không thể mở dự án Hộp công cụ hình ảnh</string>\n    <string name=\"markup_project_missing_data\">Dự án Hộp công cụ hình ảnh thiếu dữ liệu dự án</string>\n    <string name=\"markup_project_corrupted\">Dự án Hộp công cụ Hình ảnh bị hỏng</string>\n    <string name=\"unsupported_markup_project_version\">Phiên bản dự án Hộp công cụ Hình ảnh không được hỗ trợ: %1$d</string>\n    <string name=\"save_markup_project\">Lưu dự án</string>\n    <string name=\"save_markup_project_sub\">Lưu trữ các lớp, nền và lịch sử chỉnh sửa trong một tệp dự án có thể chỉnh sửa</string>\n    <string name=\"failed_to_open\">Không thể mở được</string>\n    <string name=\"ocr_write_to_searchable_pdf\">Viết vào PDF có thể tìm kiếm</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">Nhận dạng văn bản từ hàng loạt hình ảnh và lưu tệp PDF có thể tìm kiếm bằng hình ảnh và lớp văn bản có thể chọn</string>\n    <string name=\"layer_alpha\">Lớp alpha</string>\n    <string name=\"horizontal_flip\">Lật ngang</string>\n    <string name=\"vertical_flip\">Lật dọc</string>\n    <string name=\"lock\">Khóa</string>\n    <string name=\"add_shadow\">Thêm bóng</string>\n    <string name=\"shadow_color\">Màu bóng</string>\n    <string name=\"text_geometry\">Hình học văn bản</string>\n    <string name=\"text_geometry_sub\">Kéo dài hoặc nghiêng văn bản để cách điệu sắc nét hơn</string>\n    <string name=\"scale_x\">Thang đo X</string>\n    <string name=\"skew_x\">nghiêng X</string>\n    <string name=\"remove_annotations\">Xóa chú thích</string>\n    <string name=\"remove_annotations_sub\">Xóa các loại chú thích đã chọn như liên kết, nhận xét, đánh dấu, hình dạng hoặc trường biểu mẫu khỏi trang PDF</string>\n    <string name=\"annotation_link\">Siêu liên kết</string>\n    <string name=\"annotation_file_attachment\">Tệp đính kèm</string>\n    <string name=\"annotation_line\">dòng</string>\n    <string name=\"annotation_popup\">Cửa sổ bật lên</string>\n    <string name=\"annotation_stamp\">Tem</string>\n    <string name=\"annotation_shapes\">Hình dạng</string>\n    <string name=\"annotation_text\">Ghi chú văn bản</string>\n    <string name=\"annotation_text_markup\">Đánh dấu văn bản</string>\n    <string name=\"annotation_widget\">Trường biểu mẫu</string>\n    <string name=\"annotation_markup\">Đánh dấu</string>\n    <string name=\"annotation_unknown\">Không xác định</string>\n    <string name=\"annotations\">Chú thích</string>\n    <string name=\"ungroup\">Ungroup</string>\n    <string name=\"add_shadow_sub\">Thêm bóng mờ phía sau lớp với màu sắc và độ lệch có thể định cấu hình</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-zh-rCN/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"something_went_wrong\">发生错误</string>\n    <string name=\"pick_image\">选择图片以开始</string>\n    <string name=\"close\">关闭</string>\n    <string name=\"smth_went_wrong\">发生错误：%1$s</string>\n    <string name=\"size\">大小%1$s</string>\n    <string name=\"loading\">正在加载……</string>\n    <string name=\"image_too_large_preview\">图片太大，无法预览，但仍然会尝试保存</string>\n    <string name=\"width\">宽%1$s</string>\n    <string name=\"quality\">质量</string>\n    <string name=\"extension\">格式</string>\n    <string name=\"resize_type\">缩放类型</string>\n    <string name=\"explicit\">强制</string>\n    <string name=\"flexible\">自适应</string>\n    <string name=\"app_closing\">关闭应用</string>\n    <string name=\"app_closing_sub\">您确定要关闭本应用吗？</string>\n    <string name=\"stay\">取消</string>\n    <string name=\"reset_image\">重置更改</string>\n    <string name=\"reset\">重置</string>\n    <string name=\"copied\">已复制到剪贴板</string>\n    <string name=\"exception\">排除项</string>\n    <string name=\"edit_exif\">编辑EXIF信息</string>\n    <string name=\"ok\">确定</string>\n    <string name=\"no_exif\">未找到EXIF信息</string>\n    <string name=\"add_tag\">添加标签</string>\n    <string name=\"save\">保存</string>\n    <string name=\"clear_exif\">清空EXIF信息</string>\n    <string name=\"values_reset\">更改已重置</string>\n    <string name=\"cancel\">取消</string>\n    <string name=\"clear_exif_sub\">图片的全部EXIF信息都将被擦除，此操作无法撤销！</string>\n    <string name=\"presets\">预设</string>\n    <string name=\"crop\">裁剪</string>\n    <string name=\"image_not_saved\">保存</string>\n    <string name=\"image_not_saved_sub\">如果现在退出，所有未保存的更改都将丢失</string>\n    <string name=\"check_source_code\">源代码</string>\n    <string name=\"check_source_code_sub\">获得最新更新、讨论问题等</string>\n    <string name=\"single_edit\">编辑</string>\n    <string name=\"single_edit_sub\">修改、调整大小和编辑一张图片</string>\n    <string name=\"pick_color\">取色器</string>\n    <string name=\"pick_color_sub\">从图片中选取颜色，并复制或分享</string>\n    <string name=\"image\">图片</string>\n    <string name=\"color\">颜色</string>\n    <string name=\"color_copied\">颜色代码已复制</string>\n    <string name=\"crop_sub\">将图片裁剪至任意大小</string>\n    <string name=\"version\">版本号</string>\n    <string name=\"keep_exif\">保留EXIF信息</string>\n    <string name=\"images\">图片数量：%d</string>\n    <string name=\"change_preview\">更换预览图片</string>\n    <string name=\"remove\">移除</string>\n    <string name=\"palette_sub\">生成指定图片的颜色风格</string>\n    <string name=\"generate_palette\">生成调色板</string>\n    <string name=\"palette\">颜色风格</string>\n    <string name=\"update\">更新</string>\n    <string name=\"new_version\">新版本%1$s</string>\n    <string name=\"unsupported_type\">不支持的类型：%1$s</string>\n    <string name=\"no_palette\">无法生成指定图片的颜色风格</string>\n    <string name=\"original\">原图</string>\n    <string name=\"folder\">输出目录</string>\n    <string name=\"def\">默认</string>\n    <string name=\"custom\">自定义</string>\n    <string name=\"unspecified\">未指定</string>\n    <string name=\"device_storage\">设备存储</string>\n    <string name=\"by_bytes_resize\">按占用大小缩放</string>\n    <string name=\"max_bytes\">最大大小（KB）</string>\n    <string name=\"by_bytes_resize_sub\">按指定大小（KB）缩放图片</string>\n    <string name=\"compare\">对比</string>\n    <string name=\"compare_sub\">对比两张指定的图片</string>\n    <string name=\"pick_two_images\">选择两张图片以开始</string>\n    <string name=\"pick_images\">选择图片</string>\n    <string name=\"height\">高%1$s</string>\n    <string name=\"pick_image_alt\">选择图片</string>\n    <string name=\"reset_image_sub\">图片更改将回到初始值</string>\n    <string name=\"restart_app\">重启应用</string>\n    <string name=\"clear\">清空</string>\n    <string name=\"settings\">设置</string>\n    <string name=\"night_mode\">夜间模式</string>\n    <string name=\"dark\">深色</string>\n    <string name=\"light\">浅色</string>\n    <string name=\"system\">跟随系统</string>\n    <string name=\"customization\">自定义</string>\n    <string name=\"allow_image_monet\">允许来自图片的莫奈颜色</string>\n    <string name=\"allow_image_monet_sub\">如果启用，当你选择一张要编辑的图片时，应用程序的颜色将根据此图片改变</string>\n    <string name=\"language\">语言</string>\n    <string name=\"dynamic_colors\">动态颜色</string>\n    <string name=\"amoled_mode\">Amoled模式</string>\n    <string name=\"amoled_mode_sub\">如果启用，在夜间模式下背景色将设为纯黑</string>\n    <string name=\"color_red\">红色</string>\n    <string name=\"color_green\">绿色</string>\n    <string name=\"color_blue\">蓝色</string>\n    <string name=\"clipboard_paste_invalid_color_code\">粘贴一个有效的aRGB颜色代码</string>\n    <string name=\"color_scheme\">配色方案</string>\n    <string name=\"clipboard_paste_invalid_empty\">无可粘贴的图片</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">在开启动态颜色时，无法更改应用程序的颜色方案</string>\n    <string name=\"pick_accent_color\">应用程序的主题将基于选择的颜色</string>\n    <string name=\"no_updates\">未找到更新</string>\n    <string name=\"issue_tracker\">问题跟踪器</string>\n    <string name=\"help_translate\">帮助翻译</string>\n    <string name=\"about_app\">关于应用</string>\n    <string name=\"issue_tracker_sub\">在这里发送错误报告和功能请求</string>\n    <string name=\"search_here\">在此搜索</string>\n    <string name=\"help_translate_sub\">纠正翻译错误或将项目本地化为其他语言</string>\n    <string name=\"nothing_found_by_search\">没有发现您所查询的内容</string>\n    <string name=\"dynamic_colors_sub\">如果启用，则应用颜色将更改为壁纸颜色</string>\n    <string name=\"failed_to_save\">无法保存%d张图片</string>\n    <string name=\"add\">添加</string>\n    <string name=\"values\">值</string>\n    <string name=\"permission\">权限</string>\n    <string name=\"grant\">授予</string>\n    <string name=\"permission_sub\">应用程序必须访问您的存储来保存图片。请在接下来的对话框中授予权限</string>\n    <string name=\"grant_permission_manual\">应用程序需要此权限才能工作，请手动授权</string>\n    <string name=\"border_thickness\">边框宽度</string>\n    <string name=\"surface\">表面</string>\n    <string name=\"donation_sub\">该应用程序完全免费。如果你想支持该项目开发，你可以点击这里</string>\n    <string name=\"fab_alignment\">FAB对齐方式</string>\n    <string name=\"check_updates\">检查更新</string>\n    <string name=\"check_updates_sub\">如果启用，更新对话框将在应用程序启动时显示</string>\n    <string name=\"primary\">主色</string>\n    <string name=\"tertiary\">第三色</string>\n    <string name=\"secondary\">辅助色</string>\n    <string name=\"zoom\">图片缩放</string>\n    <string name=\"prefix\">前缀</string>\n    <string name=\"filename\">文件名</string>\n    <string name=\"share\">分享</string>\n    <string name=\"external_storage\">外部存储</string>\n    <string name=\"monet_colors\">莫奈取色</string>\n    <string name=\"emoji_sub\">在主屏幕上选择要显示的表情符号。</string>\n    <string name=\"emoji\">表情符号</string>\n    <string name=\"add_file_size_sub\">如果启用，会将保存图片的宽度和高度添加到输出文件的名称中。</string>\n    <string name=\"add_file_size\">添加文件尺寸</string>\n    <string name=\"delete_exif\">删除EXIF信息</string>\n    <string name=\"delete_exif_sub\">删除任意一组图片的EXIF元数据</string>\n    <string name=\"image_preview\">预览图片</string>\n    <string name=\"image_preview_sub\">预览任何类型的图片：GIF、SVG等等</string>\n    <string name=\"color_filter\">颜色滤镜</string>\n    <string name=\"alpha\">Alpha 值</string>\n    <string name=\"vibrance\">色相</string>\n    <string name=\"crosshatch\">扫描线</string>\n    <string name=\"sobel_edge\">线框</string>\n    <string name=\"start\">左侧</string>\n    <string name=\"end\">右侧</string>\n    <string name=\"box_blur\">方框模糊</string>\n    <string name=\"bilaterial_blur\">双边模糊</string>\n    <string name=\"options_arrangement\">功能管理</string>\n    <string name=\"load_image_from_net\">加载网络图片</string>\n    <string name=\"image_link\">图片链接</string>\n    <string name=\"brightness\">亮度</string>\n    <string name=\"glass_sphere_refraction\">玻璃球面折射</string>\n    <string name=\"kuwahara\">桑原平滑</string>\n    <string name=\"radius\">半径</string>\n    <string name=\"scale\">强度</string>\n    <string name=\"limits_resize\">按限制缩放</string>\n    <string name=\"limits_resize_sub\">在保持纵横比的同时将图片调整为给定的高度和宽度</string>\n    <string name=\"posterize\">色调分离</string>\n    <string name=\"non_maximum_suppression\">非极大值抑制（NMS）</string>\n    <string name=\"weak_pixel_inclusion\">弱像素包含（WPI）</string>\n    <string name=\"lookup\">抬头</string>\n    <string name=\"stack_blur\">堆叠模糊</string>\n    <string name=\"second_color\">第二种颜色</string>\n    <string name=\"reorder\">重新排序</string>\n    <string name=\"fast_blur\">快速模糊</string>\n    <string name=\"blur_size\">模糊大小</string>\n    <string name=\"photo_picker_sub\">出现在屏幕底部的安卓新版照片选择器可能只适用于安卓12+系统，它接收EXIF元数据时有问题</string>\n    <string name=\"file_explorer_picker_sub\">使用 GetContent 意图选择图片。它无论在何处都可用，但已知在某些设备上接收选择的图片时会出现问题。这与本APP无关。</string>\n    <string name=\"edit\">编辑</string>\n    <string name=\"order\">顺序</string>\n    <string name=\"order_sub\">确定主屏幕上工具的顺序</string>\n    <string name=\"emojis_count\">表情符号数</string>\n    <string name=\"replace_sequence_number\">替换序号</string>\n    <string name=\"replace_sequence_number_sub\">如果启用，则在使用批处理功能时将标准时间戳替换为图片序号</string>\n    <string name=\"filename_not_work_with_photopicker\">如果选择照片选择器作为图片源，则添加原始文件名不可用</string>\n    <string name=\"fill\">填充</string>\n    <string name=\"fit\">适合</string>\n    <string name=\"explicit_description\">将图片调整为给定的高度和宽度。图片的纵横比可能会改变。</string>\n    <string name=\"flexible_description\">将长边符合给定高度或宽度的图片调整尺寸。所有尺寸计算将在保存后完成。图片的纵横比将保持不变。</string>\n    <string name=\"contrast\">对比度</string>\n    <string name=\"hue\">色调</string>\n    <string name=\"saturation\">饱和度</string>\n    <string name=\"add_filter\">添加滤镜</string>\n    <string name=\"filter\">滤镜</string>\n    <string name=\"filter_sub\">应用滤镜链于图像</string>\n    <string name=\"filters\">滤镜</string>\n    <string name=\"light_aka_illumination\">光照</string>\n    <string name=\"exposure\">曝光</string>\n    <string name=\"white_balance\">白平衡</string>\n    <string name=\"temperature\">色温</string>\n    <string name=\"tint\">着色</string>\n    <string name=\"monochrome\">单色</string>\n    <string name=\"gamma\">伽马</string>\n    <string name=\"highlights_shadows\">高光和阴影</string>\n    <string name=\"highlights\">高光</string>\n    <string name=\"shadows\">阴影</string>\n    <string name=\"haze\">雾气</string>\n    <string name=\"effect\">效果</string>\n    <string name=\"distance\">距离</string>\n    <string name=\"slope\">坡度</string>\n    <string name=\"sharpen\">锐化</string>\n    <string name=\"sepia\">做旧</string>\n    <string name=\"negative\">反色</string>\n    <string name=\"solarize\">曝光</string>\n    <string name=\"black_and_white\">黑白</string>\n    <string name=\"spacing\">间距</string>\n    <string name=\"line_width\">线宽</string>\n    <string name=\"blur\">模糊</string>\n    <string name=\"halftone\">半色调</string>\n    <string name=\"cga_colorspace\">GCA 色彩空间</string>\n    <string name=\"gaussian_blur\">高斯模糊</string>\n    <string name=\"emboss\">浮雕</string>\n    <string name=\"laplacian\">拉普拉斯过滤</string>\n    <string name=\"vignette\">晕光</string>\n    <string name=\"distortion\">失真</string>\n    <string name=\"angle\">角度</string>\n    <string name=\"swirl\">漩涡扭曲</string>\n    <string name=\"bulge\">凸起扭曲</string>\n    <string name=\"dilation\">扩张</string>\n    <string name=\"sphere_refraction\">球面折射</string>\n    <string name=\"refractive_index\">折射率</string>\n    <string name=\"color_matrix\">颜色矩阵</string>\n    <string name=\"opacity\">不透明度</string>\n    <string name=\"sketch\">草图</string>\n    <string name=\"threshold\">临界点</string>\n    <string name=\"quantizationLevels\">量化级别</string>\n    <string name=\"smooth_toon\">平滑色调</string>\n    <string name=\"toon\">卡通化</string>\n    <string name=\"convolution3x3\">3x3 卷积矩阵</string>\n    <string name=\"rgb_filter\">RGB 滤镜</string>\n    <string name=\"false_color\">伪色</string>\n    <string name=\"first_color\">第一种颜色</string>\n    <string name=\"blur_center_x\">模糊中心 x</string>\n    <string name=\"blur_center_y\">模糊中心 y</string>\n    <string name=\"zoom_blur\">中心模糊</string>\n    <string name=\"color_balance\">色彩平衡</string>\n    <string name=\"luminance_threshold\">亮度阈值</string>\n    <string name=\"load_image_from_net_sub\">从互联网加载任何图片进行预览，缩放，保存或进一步编辑</string>\n    <string name=\"image_source\">图片来源</string>\n    <string name=\"photo_picker\">照片选择器</string>\n    <string name=\"gallery_picker\">图库</string>\n    <string name=\"file_explorer_picker\">文件管理器</string>\n    <string name=\"gallery_picker_sub\">简单的图库图片选取器。它仅在你有可提供媒体选择的应用程序时可用。</string>\n    <string name=\"no_image\">没有图片</string>\n    <string name=\"content_scale\">内容缩放</string>\n    <string name=\"sequence_num\">序号</string>\n    <string name=\"original_filename\">原始文件名</string>\n    <string name=\"add_original_filename\">添加原始文件名</string>\n    <string name=\"add_original_filename_sub\">如果启用，则在输出图片的文件名中添加原始文件名</string>\n    <string name=\"draw\">画板</string>\n    <string name=\"activate_files\">你禁用了“文件”应用，请先激活该应用以使用该功能。</string>\n    <string name=\"draw_sub\">在图片上素描，或者在纯色背景上绘制</string>\n    <string name=\"paint_color\">颜料颜色</string>\n    <string name=\"draw_on_image\">在图片上绘画</string>\n    <string name=\"draw_on_image_sub\">选择一张图片并在上面绘画</string>\n    <string name=\"paint_alpha\">水印透明度</string>\n    <string name=\"draw_on_background\">在纯色背景上绘制</string>\n    <string name=\"draw_on_background_sub\">选择背景色并在该背景上进行绘制</string>\n    <string name=\"background_color\">背景色</string>\n    <string name=\"pick_file\">选择文件</string>\n    <string name=\"encrypt\">加密</string>\n    <string name=\"decrypt\">解密</string>\n    <string name=\"pick_file_to_start\">选择文件以开始</string>\n    <string name=\"decryption\">解密</string>\n    <string name=\"encryption\">加密</string>\n    <string name=\"key\">密钥</string>\n    <string name=\"features\">功能</string>\n    <string name=\"implementation\">执行</string>\n    <string name=\"compatibility\">兼容性</string>\n    <string name=\"implementation_sub\">AES-256，GCM模式，无填充，默认使用12字节随机IV。您可以选择所需的算法。密钥以256位SHA-3哈希形式使用</string>\n    <string name=\"file_size\">文件大小</string>\n    <string name=\"compatibility_sub\">请注意，我们不保证与其他文件加密软件或服务的兼容性，密钥处理或密码配置稍有不同可能会不兼容。</string>\n    <string name=\"cipher\">加密</string>\n    <string name=\"features_sub\">在这里您可以进行基于密码的文件加密。加密完成的文件可以存储在选定的目录或直接共享，解密后的文件也可以直接打开。</string>\n    <string name=\"invalid_password_or_not_encrypted\">密码无效或选中的文件未加密</string>\n    <string name=\"file_proceed\">已完成的文件</string>\n    <string name=\"image_size_warning\">尝试以指定的宽度和高度保存图片可能会导致内存溢出错误。请自行承担风险操作</string>\n    <string name=\"cache\">缓存</string>\n    <string name=\"cache_size\">缓存区大小</string>\n    <string name=\"found_s\">已发现%1$s缓存</string>\n    <string name=\"auto_cache_clearing\">自动清理缓存</string>\n    <string name=\"auto_cache_clearing_sub\">如果开启该选项，应用缓存将会在应用启动时自动清理</string>\n    <string name=\"tools\">工具</string>\n    <string name=\"group_options_by_type\">根据功能类型将功能分组</string>\n    <string name=\"group_options_by_type_sub\">对主屏幕上的选项按选项类型分组，代替按自定义列表排列</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">启用功能分组时无法更改排列</string>\n    <string name=\"create\">创作</string>\n    <string name=\"cipher_sub\">基于各种可用的加密算法对任何文件（不限于图片）进行加密和解密</string>\n    <string name=\"store_file_desc\">将此文件存储在您的设备上，或使用共享操作将其传送至任何位置</string>\n    <string name=\"file_size_sub\">最大文件大小受 Android 系统和可用内存的限制，这取决于您的设备。 \\n请注意：内存 (RAM) 不是存储 (ROM)。</string>\n    <string name=\"screenshot\">截屏</string>\n    <string name=\"skip\">跳过</string>\n    <string name=\"secondary_customization\">二次定制</string>\n    <string name=\"fallback_option\">后备选项</string>\n    <string name=\"copy\">复制</string>\n    <string name=\"warning_bytes\">以%1$s模式保存可能不稳定，因为它是无损格式</string>\n    <string name=\"edit_screenshot\">编辑截图</string>\n    <string name=\"aspect_ratio\">纵横比</string>\n    <string name=\"image_crop_mask_sub\">使用这个遮罩类型从给定的图片创建遮罩，注意它应该有alpha通道</string>\n    <string name=\"backup_and_restore\">备份和恢复</string>\n    <string name=\"crop_mask\">裁剪遮罩</string>\n    <string name=\"backup\">备份</string>\n    <string name=\"restore\">恢复</string>\n    <string name=\"backup_sub\">将应用程序设置备份到一个文件中</string>\n    <string name=\"restore_sub\">从以前生成的文件中恢复应用程序设置</string>\n    <string name=\"corrupted_file_or_not_a_backup\">文件已损坏或不是备份文件</string>\n    <string name=\"reset_settings_sub\">这将把你的设置恢复到默认值。注意，如果之前没有备份文件，则不能撤销。</string>\n    <string name=\"delete\">删除</string>\n    <string name=\"delete_color_scheme_warn\">您即将删除所选配色方案。此操作无法撤消</string>\n    <string name=\"delete_color_scheme_title\">删除方案</string>\n    <string name=\"font\">字体</string>\n    <string name=\"text\">文本</string>\n    <string name=\"settings_restored\">恢复设置成功</string>\n    <string name=\"contact_me\">联系我</string>\n    <string name=\"font_scale\">字体大小</string>\n    <string name=\"defaultt\">默认</string>\n    <string name=\"using_large_fonts_warn\">使用大字体可能会导致 UI 故障和问题，这是无法修复的。谨慎使用。</string>\n    <string name=\"randomize_filename\">随机文件名</string>\n    <string name=\"randomize_filename_sub\">如果启用，输出文件名将是完全随机的</string>\n    <string name=\"presets_sub\" formatted=\"false\">如果选择预设值125，图片将保存为原始图片大小的125%。如果选择预设值50，图片将保存为原始图片大小的50%</string>\n    <string name=\"presets_sub_bytes\">此处的预设决定输出文件的百分比，例如如果你在5MB的图片上选择预设50，则保存后将得到一张2.5MB的图片</string>\n    <string name=\"saved_to\">已使用名称%2$s保存到%1$s文件夹</string>\n    <string name=\"saved_to_without_filename\">已保存到%1$s文件夹</string>\n    <string name=\"tg_chat\">Telegram 聊天</string>\n    <string name=\"tg_chat_sub\">讨论这款应用程序并从其他用户那里获得反馈。你也可以在那里获得beta版更新和见解。</string>\n    <string name=\"erase_mode\">擦除模式</string>\n    <string name=\"restore_image\">恢复图片</string>\n    <string name=\"emotions\">表情</string>\n    <string name=\"food_and_drink\">食物和饮料</string>\n    <string name=\"nature_and_animals\">自然与动物</string>\n    <string name=\"objects\">物体</string>\n    <string name=\"travels_and_places\">旅游和地方</string>\n    <string name=\"activities\">活动</string>\n    <string name=\"background_remover\">移除背景</string>\n    <string name=\"background_remover_sub\">通过绘图或使用自动选项从图片中删除背景</string>\n    <string name=\"symbols\">符号</string>\n    <string name=\"enable_emoji\">启用表情</string>\n    <string name=\"erase_background\">擦除背景</string>\n    <string name=\"keep_exif_sub\">原始图片元数据将被保留</string>\n    <string name=\"trim_image\">修剪图片</string>\n    <string name=\"trim_image_sub\">图片周围的透明空间将被修剪</string>\n    <string name=\"auto_erase_background\">自动擦除背景</string>\n    <string name=\"restore_background\">恢复背景</string>\n    <string name=\"blur_radius\">模糊半径</string>\n    <string name=\"pipette\">吸管</string>\n    <string name=\"draw_mode\">绘画模式</string>\n    <string name=\"create_issue\">创建问题</string>\n    <string name=\"something_went_wrong_emphasis\">哎呀……软件出错了。你可以使用下面的选项给我留言，我会尽力找到解决办法。</string>\n    <string name=\"resize_and_convert\">调整大小和转换</string>\n    <string name=\"resize_and_convert_sub\">更改给定图片的大小或将其转换为其他格式。如果选择单个图片，还可以编辑EXIF元数据</string>\n    <string name=\"alphabet_and_numbers\">汉字示例 0123456789 !?</string>\n    <string name=\"updates\">更新</string>\n    <string name=\"max_colors_count\">最大颜色数</string>\n    <string name=\"wait\">等待</string>\n    <string name=\"image_exif_warning\">目前，%1$s格式在Android上只允许读取EXIF元数据。在保存时，输出图片将完全没有元数据。</string>\n    <string name=\"effort_sub\">值为%1$s意味着快速压缩，导致文件大小相对较大。 %2$s表示压缩速度较慢，文件较小。</string>\n    <string name=\"analytics_sub\">允许收集匿名应用使用统计数据</string>\n    <string name=\"allow_betas\">允许接收测试版</string>\n    <string name=\"crashlytics_sub\">这允许此应用程序自动收集崩溃报告</string>\n    <string name=\"saving_almost_complete\">保存快要完成了。现在取消将需要重新开始保存</string>\n    <string name=\"analytics\">分析</string>\n    <string name=\"effort\">压缩尝试次数</string>\n    <string name=\"allow_betas_sub\">如果启用，更新检查时将包括测试版</string>\n    <string name=\"horizontal\">横向</string>\n    <string name=\"recode\">重新编码</string>\n    <string name=\"images_order\">图片顺序</string>\n    <string name=\"blur_edges\">模糊边缘</string>\n    <string name=\"image_stitching\">图片拼接</string>\n    <string name=\"pixelation\">像素化</string>\n    <string name=\"enhanced_pixelation\">增强像素化</string>\n    <string name=\"target_color\">目标颜色</string>\n    <string name=\"draw_arrows\">绘制箭头</string>\n    <string name=\"pick_at_least_two_images\">选择至少 2 张图片</string>\n    <string name=\"pixel_size\">像素大小</string>\n    <string name=\"replace_color\">替换颜色</string>\n    <string name=\"blur_edges_sub\">如果启用，在原始图片下绘制模糊边缘以填充周围的空间，而不是使用单一颜色</string>\n    <string name=\"remove_color\">移除颜色</string>\n    <string name=\"draw_arrows_sub\">如果启用，绘制路径将表示为指向箭头</string>\n    <string name=\"scale_small_images_to_large_sub\">如果启用，小图片将被缩放到序列中最大的图片</string>\n    <string name=\"lock_draw_orientation\">锁定绘制方向</string>\n    <string name=\"image_stitching_sub\">将给定的图片组合成一个大的图片</string>\n    <string name=\"check_for_updates\">检查更新</string>\n    <string name=\"image_orientation\">图片方向</string>\n    <string name=\"vertical\">纵向</string>\n    <string name=\"color_to_remove\">要去除的颜色</string>\n    <string name=\"color_to_replace\">要更换的颜色</string>\n    <string name=\"crop_description\">图片将被中间裁剪到输入的大小。如果图片小于输入的尺寸，画布将以给定的背景颜色展开。</string>\n    <string name=\"donation\">捐赠</string>\n    <string name=\"output_image_scale\">输出图片缩放</string>\n    <string name=\"lock_draw_orientation_sub\">如果在绘图模式下启用，屏幕将不会旋转</string>\n    <string name=\"scale_small_images_to_large\">将小尺寸的图片放大至大尺寸</string>\n    <string name=\"tolerance\">容错度</string>\n    <string name=\"both\">两个都</string>\n    <string name=\"invert_colors_sub\">如果启用，将主题颜色替换为负值</string>\n    <string name=\"fidelity\">富达</string>\n    <string name=\"brush_softness\">刷子柔软度</string>\n    <string name=\"rainbow\">彩虹</string>\n    <string name=\"playful_scheme\">有趣的主题 - 源颜色的色调不会出现在主题中</string>\n    <string name=\"fading_edges\">边缘褪色</string>\n    <string name=\"vibrant_sub\">响亮的主题，主要调色板的色彩度最大，其他调色板的色彩度增加</string>\n    <string name=\"neutral_sub\">色彩比单色稍多的风格</string>\n    <string name=\"foss_update_checker_warning\">此更新检查器将连接到 GitHub，以检查是否有可用的新更新</string>\n    <string name=\"content_sub\">将源颜色放置在Scheme.primaryContainer中的方案</string>\n    <string name=\"tonal_spot\">色调点</string>\n    <string name=\"diamond_pixelation\">钻石像素化</string>\n    <string name=\"monochrome_sub\">单色主题，颜色纯黑/白/灰</string>\n    <string name=\"fruit_salad\">水果沙拉</string>\n    <string name=\"enhanced_diamond_pixelation\">增强钻石像素化</string>\n    <string name=\"circle_pixelation\">圆形像素化</string>\n    <string name=\"fidelity_sub\">与内容方案非常相似的方案</string>\n    <string name=\"content\">内容</string>\n    <string name=\"disabled\">禁用</string>\n    <string name=\"expressive\">富有表现力</string>\n    <string name=\"neutral\">中性的</string>\n    <string name=\"tonal_spot_sub\">默认调色板样式，它允许自定义所有四种颜色，其他允许您仅设置关键颜色</string>\n    <string name=\"palette_style\">调色板风格</string>\n    <string name=\"invert_colors\">反转颜色</string>\n    <string name=\"vibrant\">充满活力</string>\n    <string name=\"stroke_pixelation\">笔画像素化</string>\n    <string name=\"regular\">常规</string>\n    <string name=\"enhanced_circle_pixelation\">增强圆形像素化</string>\n    <string name=\"attention\">注意力</string>\n    <string name=\"pdf_tools\">PDF工具</string>\n    <string name=\"search_option\">搜索</string>\n    <string name=\"images_to_pdf\">图片转PDF</string>\n    <string name=\"preview_pdf\">预览PDF</string>\n    <string name=\"search_option_sub\">允许在主屏幕上搜索所有可用工具</string>\n    <string name=\"pdf_to_images\">PDF转图片</string>\n    <string name=\"images_to_pdf_sub\">打包所选图片输出为PDF文件</string>\n    <string name=\"preview_pdf_sub\">简单PDF预览</string>\n    <string name=\"pdf_tools_sub\">操作PDF文件：预览、转换成一系列图片或使用所选图片创建PDF文件</string>\n    <string name=\"pdf_to_images_sub\">设定输出格式的PDF转图片</string>\n    <string name=\"rows_count\">行数</string>\n    <string name=\"double_line_arrow\">双线箭头</string>\n    <string name=\"neon_sub\">为您的绘图添加一些发光效果</string>\n    <string name=\"stitch_mode\">切换模式</string>\n    <string name=\"neon\">荧光</string>\n    <string name=\"switches_shadow_sub\">在开关后方绘制阴影</string>\n    <string name=\"double_line_arrow_sub\">将从起点到终点的双箭头绘制成一条线</string>\n    <string name=\"fabs_shadow\">悬浮按钮</string>\n    <string name=\"arrow_sub\">从给定路径绘制一个指示箭头</string>\n    <string name=\"auto_rotate_limits\">自动旋转</string>\n    <string name=\"delete_mask\">删除遮罩</string>\n    <string name=\"free_drawing\">自由绘制</string>\n    <string name=\"horizontal_grid\">水平网格</string>\n    <string name=\"outlined_oval\">椭圆形轮廓</string>\n    <string name=\"pen\">笔</string>\n    <string name=\"line\">线</string>\n    <string name=\"vertical_grid\">垂直网格</string>\n    <string name=\"sliders_shadow\">滑块</string>\n    <string name=\"containers_shadow_sub\">在容器后方绘制阴影</string>\n    <string name=\"oval\">椭圆形</string>\n    <string name=\"mask_filter\">遮罩滤镜</string>\n    <string name=\"rect\">矩形</string>\n    <string name=\"columns_count\">列数</string>\n    <string name=\"outlined_rect_sub\">绘制从起点到终点的矩形轮廓</string>\n    <string name=\"auto_rotate_limits_sub\">允许采用限制框来调整图片方向</string>\n    <string name=\"lasso\">套索</string>\n    <string name=\"privacy_blur_sub\">模糊绘制路径下的图片，以确保任何您想要隐藏的内容</string>\n    <string name=\"pen_sub\">最简单的默认设置 - 仅颜色</string>\n    <string name=\"mask_filter_sub\">允许在给定的遮蔽区域使用滤镜链，每个遮蔽区域可自行决定滤镜集</string>\n    <string name=\"line_arrow\">直线箭头</string>\n    <string name=\"inverse_fill_type\">反转填充类型</string>\n    <string name=\"containers_shadow\">容器</string>\n    <string name=\"line_sub\">用一条线绘制从起点到终点的路径</string>\n    <string name=\"mask_preview\">滤镜预览</string>\n    <string name=\"masks\">滤镜</string>\n    <string name=\"delete_mask_warn\">您将删除选中的滤镜遮罩。此操作无法撤销</string>\n    <string name=\"outlined_oval_sub\">绘制从起点到终点的椭圆形轮廓图</string>\n    <string name=\"app_bars_shadow\">应用程序栏</string>\n    <string name=\"highlighter_sub\">绘制半透明锐化荧光笔路径</string>\n    <string name=\"lasso_sub\">按给定路径绘制封闭填充路径</string>\n    <string name=\"free\">自由</string>\n    <string name=\"double_arrow\">双箭头</string>\n    <string name=\"arrow\">箭头</string>\n    <string name=\"full_filter_sub\">对给定的单张或多张图片应用任意滤镜链</string>\n    <string name=\"free_drawing_sub\">绘制路径作为输入值</string>\n    <string name=\"inverse_fill_type_sub\">如果启用，将过滤掉所有非屏蔽区域并代替默认行为</string>\n    <string name=\"start_position\">左侧</string>\n    <string name=\"highlighter\">概要</string>\n    <string name=\"buttons_shadow\">按钮</string>\n    <string name=\"rect_sub\">绘制从起点到终点的矩形</string>\n    <string name=\"mask_color\">滤镜颜色</string>\n    <string name=\"sliders_shadow_sub\">在滑块后方绘制阴影</string>\n    <string name=\"switches_shadow\">开关按钮</string>\n    <string name=\"app_bars_shadow_sub\">在应用栏后方绘制阴影</string>\n    <string name=\"value_in_range\">%1$s - %2$s范围内的值</string>\n    <string name=\"line_arrow_sub\">将起点到终点的指向箭头绘制成一条线</string>\n    <string name=\"simple_variants\">简单变体</string>\n    <string name=\"pixelation_sub\">与隐私模糊相似，但像素化而非模糊化</string>\n    <string name=\"full_filter\">全滤镜</string>\n    <string name=\"double_arrow_sub\">从给定路径绘制双箭头</string>\n    <string name=\"add_mask\">添加滤镜</string>\n    <string name=\"end_position\">右侧</string>\n    <string name=\"outlined_rect\">轮廓图</string>\n    <string name=\"mask_preview_sub\">绘制的滤镜遮罩将进行渲染，以显示大致效果</string>\n    <string name=\"privacy_blur\">隐私模糊</string>\n    <string name=\"fabs_shadow_sub\">在悬浮操作按钮后方绘制阴影</string>\n    <string name=\"oval_sub\">从起点到终点绘制椭圆形</string>\n    <string name=\"mask_indexed\">遮罩%d</string>\n    <string name=\"center_position\">居中</string>\n    <string name=\"buttons_shadow_sub\">在按钮后方绘制阴影</string>\n    <string name=\"draw_path_mode\">绘制路径模式</string>\n    <string name=\"vibration\">震动</string>\n    <string name=\"overwrite_file_requirements\">要覆盖文件，您需要使用 \\\"资源管理器 \\\"图片源，请尝试重新提供图片，我们已将图片源更改为所需的图片源</string>\n    <string name=\"auto_pin_sub\">如果启用，自动将保存的图片添加至剪贴板</string>\n    <string name=\"no_such_directory\">未找到 \\\"%1$s\\\"目录，我们已将其切换至默认目录，请重新保存文件</string>\n    <string name=\"clipboard\">剪切板</string>\n    <string name=\"overwrite_files_sub\">原始文件将被新文件替换，而不是保存在选定的文件夹中。此选项要求图片源为「资源管理器」或 GetContent，当切换此选项时，它将自动设置。</string>\n    <string name=\"vibration_strength\">震动强度</string>\n    <string name=\"overwrite_files\">覆写文件</string>\n    <string name=\"empty\">空</string>\n    <string name=\"suffix\">后缀</string>\n    <string name=\"auto_pin\">自动复制</string>\n    <string name=\"scale_mode\">缩放模式</string>\n    <string name=\"bilinear\">双线性</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"nearest\">近似像素式</string>\n    <string name=\"spline\">花键式</string>\n    <string name=\"basic\">基本式</string>\n    <string name=\"default_value\">默认值</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"bicubic_sub\">更好的缩放方法包括 Lanczos 重采样和 Mitchell-Netravali 滤波器</string>\n    <string name=\"hermite_sub\">利用曲线段端点的数值和导数生成平滑连续曲线的数学插值技术</string>\n    <string name=\"bilinear_sub\">线性插值（或二维双线性插值）通常可以很好地改变图片的大小，但会导致一些不理想的细节弱化，而且仍会有些锯齿状的效果。</string>\n    <string name=\"nearest_sub\">其中一种更简单的增大尺寸的方法是，用相同颜色的像素替换每个像素</string>\n    <string name=\"basic_sub\">最简单的安卓缩放模式，几乎适用于所有应用程序</string>\n    <string name=\"hann_sub\">信号处理中经常使用的渐变函数，通过渐变信号的边缘，最大限度地减少频谱泄漏，提高频率分析的准确性</string>\n    <string name=\"catmull_sub\">对一组控制点进行平滑插值和重采样的方法，常用于计算机制图，以创建平滑曲线</string>\n    <string name=\"lanczos_sub\">通过对像素值应用加权 sinc 函数来保持高质量插值的重采样方法</string>\n    <string name=\"mitchell_sub\">重采样方法，使用参数可调的卷积滤波器，在缩放图片的清晰度和抗锯齿之间取得平衡</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"spline_sub\">使用分段定义的多项式函数对曲线或曲面进行平滑插值和近似，提供灵活且连续的形状表示</string>\n    <string name=\"only_clip\">仅剪切</string>\n    <string name=\"only_clip_sub\">不会将图片保存到本地存储，只会尝试将图片放入剪贴板中</string>\n    <string name=\"recognize_text\">OCR（文本识别）</string>\n    <string name=\"accuracy\">精确度： %1$s</string>\n    <string name=\"recognition_type\">识别类型</string>\n    <string name=\"fast\">快速</string>\n    <string name=\"best\">最优</string>\n    <string name=\"no_data\">无数据</string>\n    <string name=\"download\">下载</string>\n    <string name=\"downloaded_languages\">已下载的语言</string>\n    <string name=\"segmentation_mode\">分割模式</string>\n    <string name=\"restore_background_sub\">刷子将会还原背景，而不是擦除</string>\n    <string name=\"recognize_text_sub\">从给定图片识别文字，支持120多种语言</string>\n    <string name=\"picture_has_no_text\">图片中不含文字，或者应用程序没有找到</string>\n    <string name=\"standard\">标准</string>\n    <string name=\"download_description\">为使 Tesseract OCR 正常运行，将需要下载额外的训练数据 (%1$s) 到您的设备。 \\n您要下载%2$s数据吗？</string>\n    <string name=\"no_connection\">无网络连接，请检查并重试，以便下载训练模型</string>\n    <string name=\"available_languages\">可用语言</string>\n    <string name=\"use_pixel_switch_sub\">使用类似谷歌Pixel的开关</string>\n    <string name=\"use_pixel_switch\">使用 Pixel 开关</string>\n    <string name=\"saved_to_original\">在原始目标位置覆盖了名称为%1$s的文件</string>\n    <string name=\"magnifier_sub\">在绘图模式下，在手指顶部启用放大镜，以提高易用性</string>\n    <string name=\"force_exif_widget_initial_value_sub\">强制初始检查EXIF部件</string>\n    <string name=\"slide\">滑动</string>\n    <string name=\"side_by_side\">并排</string>\n    <string name=\"toggle_tap\">切换轻触</string>\n    <string name=\"transparency\">透明度</string>\n    <string name=\"magnifier\">放大镜</string>\n    <string name=\"force_exif_widget_initial_value\">强制初始值</string>\n    <string name=\"allow_multiple_languages\">允许多种语言</string>\n    <string name=\"rate_app\">给应用程序评分</string>\n    <string name=\"rate\">评分</string>\n    <string name=\"rate_app_sub\">此应用程序完全免费，如果您希望它变得更加强大，请在 Github 上为项目加星😄。</string>\n    <string name=\"segmentation_mode_single_line\">单行文本</string>\n    <string name=\"segmentation_mode_single_char\">单个字符</string>\n    <string name=\"segmentation_mode_circle_word\">环形词语</string>\n    <string name=\"segmentation_mode_raw_line\">原始行</string>\n    <string name=\"current\">当前</string>\n    <string name=\"all\">所有</string>\n    <string name=\"segmentation_mode_osd_only\">仅检测文本及其方向</string>\n    <string name=\"segmentation_mode_auto_only\">仅自动</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">单段纵向文本</string>\n    <string name=\"segmentation_mode_single_block\">单段文本</string>\n    <string name=\"segmentation_mode_auto\">自动</string>\n    <string name=\"segmentation_mode_single_word\">单个词语</string>\n    <string name=\"segmentation_mode_single_column\">单列文本</string>\n    <string name=\"segmentation_mode_sparse_text\">松散文本</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">检测松散文本及其方向</string>\n    <string name=\"segmentation_mode_auto_osd\">自动检测文本及其方向</string>\n    <string name=\"delete_language_sub\">您要删除所有识别类型的语言 \\\"%1$s\\\" OCR 训练数据，还是只删除选定类型 (%2$s) 的数据？</string>\n    <string name=\"gradient_maker\">渐变制作器</string>\n    <string name=\"gradient_maker_sub\">创建指定输出尺寸的渐变效果，并自定义颜色和外观类型</string>\n    <string name=\"gradient_type_linear\">线性</string>\n    <string name=\"gradient_type_radial\">放射式</string>\n    <string name=\"gradient_type_sweep\">平扫式</string>\n    <string name=\"gradient_type\">渐变类型</string>\n    <string name=\"center_x\">中心 X</string>\n    <string name=\"center_y\">中心 Y</string>\n    <string name=\"tile_mode\">平铺模式</string>\n    <string name=\"tile_mode_repeated\">重复</string>\n    <string name=\"tile_mode_clamp\">固定</string>\n    <string name=\"tile_mode_decal\">贴纸</string>\n    <string name=\"add_color\">添加颜色</string>\n    <string name=\"properties\">属性</string>\n    <string name=\"color_stops\">颜色终止点</string>\n    <string name=\"brightness_enforcement\">亮度强制</string>\n    <string name=\"tile_mode_mirror\">镜像</string>\n    <string name=\"screen\">屏幕</string>\n    <string name=\"gradient_maker_type_image\">渐变叠加</string>\n    <string name=\"transformations\">转换</string>\n    <string name=\"camera\">相机</string>\n    <string name=\"camera_sub\">用相机拍摄一张照片。请注意，从此图片源只能获取一张图片</string>\n    <string name=\"gradient_maker_type_image_sub\">合成给定图片顶部的任意梯度</string>\n    <string name=\"watermarking_sub\">用自定义文字/图片水印覆盖图片</string>\n    <string name=\"offset_y\">偏移 Y</string>\n    <string name=\"watermark_type\">水印类型</string>\n    <string name=\"text_color\">文本颜色</string>\n    <string name=\"watermarking\">水印</string>\n    <string name=\"repeat_watermark\">重复水印</string>\n    <string name=\"repeat_watermark_sub\">在图片上重复水印，而不是在给定位置重复单个水印</string>\n    <string name=\"offset_x\">偏移 X</string>\n    <string name=\"overlay_mode\">叠加模式</string>\n    <string name=\"watermarking_image_sub\">该图片将作为水印图案使用</string>\n    <string name=\"gif_tools\">GIF工具</string>\n    <string name=\"gif_type_to_image\">GIF转换为图片</string>\n    <string name=\"gif_type_to_image_sub\">GIF文件转换为一组图片</string>\n    <string name=\"gif_type_to_gif\">图片转换为GIF</string>\n    <string name=\"select_gif_image_to_start\">选择 GIF 图片以开始</string>\n    <string name=\"use_size_of_first_frame\">使用第一帧的尺寸</string>\n    <string name=\"use_size_of_first_frame_sub\">用第一帧尺寸替换指定尺寸</string>\n    <string name=\"repeat_count\">重复次数</string>\n    <string name=\"frame_delay\">帧延迟</string>\n    <string name=\"fps\">帧率</string>\n    <string name=\"millis\">毫秒</string>\n    <string name=\"use_lasso_sub\">像在绘图模式中一样使用套索来执行擦除操作</string>\n    <string name=\"original_image_preview_alpha\">原始图片预览 Alpha</string>\n    <string name=\"gif_tools_sub\">将图片转换为GIF图片，或从给定的GIF图片中提取帧</string>\n    <string name=\"gif_type_to_gif_sub\">将一组图片转换为GIF文件</string>\n    <string name=\"use_lasso\">使用套索</string>\n    <string name=\"confetti_sub\">在保存、分享和其他主要操作时会显示纸屑特效</string>\n    <string name=\"secure_mode\">安全模式</string>\n    <string name=\"confetti\">纸屑特效</string>\n    <string name=\"secure_mode_sub\">在最近使用的应用中隐藏应用内容，无法被捕获或录制。</string>\n    <string name=\"exit\">退出</string>\n    <string name=\"preview_closing\">如果现在离开预览，则需要重新添加图片</string>\n    <string name=\"email\">电子邮件</string>\n    <string name=\"quantizier\">量化器</string>\n    <string name=\"gray_scale\">灰阶</string>\n    <string name=\"dithering\">抖动</string>\n    <string name=\"bayer_four_dithering\">Bayer 四对四抖动算法</string>\n    <string name=\"sierra_dithering\">Sierra 抖动算法</string>\n    <string name=\"two_row_sierra_dithering\">双列 Sierra 抖动算法</string>\n    <string name=\"false_floyd_steinberg_dithering\">假 Floyd Steinberg 抖动算法</string>\n    <string name=\"left_to_right_dithering\">从左到右抖动</string>\n    <string name=\"random_dithering\">随机抖动</string>\n    <string name=\"simple_threshold_dithering\">简单阈值抖动</string>\n    <string name=\"bayer_eight_dithering\">Bayer 八对八抖动算法</string>\n    <string name=\"bayer_two_dithering\">Bayer 二对二抖动算法</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke 抖动算法</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg 抖动算法</string>\n    <string name=\"bayer_three_dithering\">Bayer 三对三抖动算法</string>\n    <string name=\"sierra_lite_dithering\">Sierra 轻型抖动算法</string>\n    <string name=\"atkinson_dithering\">Atkinson 抖动算法</string>\n    <string name=\"stucki_dithering\">Stucki 抖动算法</string>\n    <string name=\"burkes_dithering\">Burkes 抖动算法</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">空间 Sigma</string>\n    <string name=\"median_blur\">中值模糊</string>\n    <string name=\"b_spline\">B 样条</string>\n    <string name=\"b_spline_sub\">利用片断定义的双三次多项式函数平滑插值和近似曲线或曲面，灵活且连续地表示形状</string>\n    <string name=\"native_stack_blur\">原生堆栈模糊</string>\n    <string name=\"tilt_shift\">倾斜移位</string>\n    <string name=\"pixel_sort\">像素排序</string>\n    <string name=\"glitch\">毛刺</string>\n    <string name=\"amount\">数量</string>\n    <string name=\"seed\">种子</string>\n    <string name=\"noise\">噪音</string>\n    <string name=\"anaglyph\">浮雕</string>\n    <string name=\"shuffle\">随机播放</string>\n    <string name=\"channel_shift_x\">通道偏移 X</string>\n    <string name=\"channel_shift_y\">通道偏移 Y</string>\n    <string name=\"corruption_size\">故障规模</string>\n    <string name=\"corruption_shift_x\">故障转移 X</string>\n    <string name=\"tent_blur\">帐篷模糊</string>\n    <string name=\"side_fade\">侧面淡化</string>\n    <string name=\"side\">侧边</string>\n    <string name=\"top\">顶部</string>\n    <string name=\"enhanced_glitch\">增强毛刺</string>\n    <string name=\"corruption_shift_y\">故障转移 Y</string>\n    <string name=\"bottom\">底部</string>\n    <string name=\"strength\">强度</string>\n    <string name=\"diffusion\">扩散</string>\n    <string name=\"conduction\">传导</string>\n    <string name=\"poisson_blur\">泊松模糊</string>\n    <string name=\"logarithmic_tone_mapping\">对数色调映射</string>\n    <string name=\"crystallize\">晶体化</string>\n    <string name=\"amplitude\">幅度</string>\n    <string name=\"marble\">大理石</string>\n    <string name=\"turbulence\">湍流</string>\n    <string name=\"oil\">油脂</string>\n    <string name=\"just_size\">尺寸</string>\n    <string name=\"amplitude_x\">幅度 X</string>\n    <string name=\"amplitude_y\">幅度 Y</string>\n    <string name=\"perlin_distortion\">柏林失真</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable 胶片色调映射</string>\n    <string name=\"aces_hill_tone_mapping\">ACES 山峰色调映射</string>\n    <string name=\"erode\">侵蚀</string>\n    <string name=\"anisotropic_diffusion\">各向异性扩散</string>\n    <string name=\"fast_bilaterial_blur\">快速双色模糊</string>\n    <string name=\"horizontal_wind_stagger\">水平风向交错</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES 胶片色调映射</string>\n    <string name=\"stroke_color\">笔画颜色</string>\n    <string name=\"fractal_glass\">分形玻璃</string>\n    <string name=\"water_effect\">水纹效果</string>\n    <string name=\"frequency_x\">频率 X</string>\n    <string name=\"frequency_y\">频率 Y</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess 色调映射</string>\n    <string name=\"dehaze\">Dehaze</string>\n    <string name=\"speed\">速度</string>\n    <string name=\"omega\">Omega</string>\n    <string name=\"color_matrix_3x3\">颜色矩阵 3x3</string>\n    <string name=\"simple_effects\">简单效果</string>\n    <string name=\"polaroid\">宝丽来</string>\n    <string name=\"protonomaly\">红色弱</string>\n    <string name=\"browni\">布朗尼</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">夜视</string>\n    <string name=\"cool\">凉爽</string>\n    <string name=\"tritanopia\">蓝色盲</string>\n    <string name=\"protanopia\">红色盲</string>\n    <string name=\"achromatopsia\">全色盲</string>\n    <string name=\"unsharp\">非锐化</string>\n    <string name=\"pastel\">粉彩</string>\n    <string name=\"color_matrix_4x4\">颜色矩阵 4x4</string>\n    <string name=\"tritonomaly\">蓝色弱</string>\n    <string name=\"deutaromaly\">绿色弱</string>\n    <string name=\"vintage\">复古</string>\n    <string name=\"warm\">温暖</string>\n    <string name=\"deutaronotopia\">绿色盲</string>\n    <string name=\"achromatomaly\">不全色盲</string>\n    <string name=\"grain\">微粒</string>\n    <string name=\"fantasy_landscape\">奇幻风景</string>\n    <string name=\"pink_dream\">粉红之梦</string>\n    <string name=\"golden_hour\">黄金时刻</string>\n    <string name=\"hot_summer\">炎热夏季</string>\n    <string name=\"purple_mist\">紫色薄雾</string>\n    <string name=\"sunrise\">日出之时</string>\n    <string name=\"colorful_swirl\">彩色漩涡</string>\n    <string name=\"soft_spring_light\">柔美春光</string>\n    <string name=\"autumn_tones\">秋日色调</string>\n    <string name=\"lavender_dream\">薰衣草之梦</string>\n    <string name=\"cyberpunk\">赛博朋克</string>\n    <string name=\"lemonade_light\">柠檬水光</string>\n    <string name=\"night_magic\">黑夜魔法</string>\n    <string name=\"color_explosion\">色彩爆炸</string>\n    <string name=\"electric_gradient\">电流渐变</string>\n    <string name=\"caramel_darkness\">焦糖黑暗</string>\n    <string name=\"futuristic_gradient\">未来渐变</string>\n    <string name=\"green_sun\">绿色太阳</string>\n    <string name=\"rainbow_world\">彩虹世界</string>\n    <string name=\"deep_purple\">幽深紫色</string>\n    <string name=\"red_swirl\">红色漩涡</string>\n    <string name=\"digital_code\">数字代码</string>\n    <string name=\"orange_haze\">橙色迷雾</string>\n    <string name=\"spectral_fire\">光谱火焰</string>\n    <string name=\"space_portal\">空间传送</string>\n    <string name=\"bokeh\">虚化</string>\n    <string name=\"random_emojis\">随机表情符号</string>\n    <string name=\"random_emojis_error\">当表情符号功能被禁用时，你无法使用随机表情符号</string>\n    <string name=\"emoji_selection_error\">当启用随机表情符号时，你无法选择单个表情符号</string>\n    <string name=\"random_emojis_sub\">应用栏表情符号将会随机变化</string>\n    <string name=\"old_tv\">老式电视</string>\n    <string name=\"shuffle_blur\">随机模糊</string>\n    <string name=\"favorite\">收藏夹</string>\n    <string name=\"no_favorite_filters\">尚未添加收藏夹过滤器</string>\n    <string name=\"image_format\">图片格式</string>\n    <string name=\"icon_shape_sub\">在图标下方添加一个具有所选形状的容器</string>\n    <string name=\"icon_shape\">图标形状</string>\n    <string name=\"uchimura\">内村</string>\n    <string name=\"mobius\">莫比乌斯</string>\n    <string name=\"peak\">峰值</string>\n    <string name=\"drago\">Drago</string>\n    <string name=\"aldridge\">Aldridge</string>\n    <string name=\"color_anomaly\">色彩异常</string>\n    <string name=\"transition\">过渡</string>\n    <string name=\"cutoff\">截止</string>\n    <string name=\"images_overwritten\">在原位置覆盖图片</string>\n    <string name=\"cannot_change_image_format\">启用覆盖文件选项时无法更改图片格式</string>\n    <string name=\"emoji_as_color_scheme\">使用表情符号作为配色方案</string>\n    <string name=\"emoji_as_color_scheme_sub\">使用表情符号的主色调作为应用程序配色方案，代替手动定义的配色方案</string>\n    <string name=\"dark_colors\">暗色</string>\n    <string name=\"copy_as_compose_code\">作为 Jetpack Compose 代码复制</string>\n    <string name=\"material_you_sub\">从图片创建 Material You 调色板</string>\n    <string name=\"dark_colors_sub\">采用夜间模式配色方案，代替灯光变体</string>\n    <string name=\"cross_blur\">交叉模糊</string>\n    <string name=\"circle_blur\">圆圈模糊</string>\n    <string name=\"star_blur\">星光模糊</string>\n    <string name=\"ring_blur\">环形模糊</string>\n    <string name=\"linear_tilt_shift\">线性倾角移位</string>\n    <string name=\"tags_to_remove\">要移除的标签</string>\n    <string name=\"select_apng_image_to_start\">选择 APNG 图片以开始</string>\n    <string name=\"apng_tools\">APNG工具</string>\n    <string name=\"apng_tools_sub\">将图片转换为APNG图片，或从给定的APNG图片中提取帧</string>\n    <string name=\"apng_type_to_image_sub\">批量将APNG文件转换为图片</string>\n    <string name=\"apng_type_to_apng_sub\">将一系列图片转换为APNG文件</string>\n    <string name=\"apng_type_to_apng\">图片转换为APNG</string>\n    <string name=\"apng_type_to_image\">APNG转换为图片</string>\n    <string name=\"motion_blur\">动态模糊</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"zip_sub\">根据给定文件或图片创建Zip压缩包文件</string>\n    <string name=\"drag_handle_width\">拖动手柄宽度</string>\n    <string name=\"confetti_type\">彩纸类型</string>\n    <string name=\"festive\">节日</string>\n    <string name=\"explode\">爆炸</string>\n    <string name=\"rain\">下雨</string>\n    <string name=\"corners\">边角</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG转JXL</string>\n    <string name=\"select_jxl_image_to_start\">选择 JXL 图片以开始</string>\n    <string name=\"jxl_type_to_jpeg_sub\">将JXL无损转码为JPEG</string>\n    <string name=\"jxl_tools\">JXL工具</string>\n    <string name=\"jpeg_type_to_jxl_sub\">将JPEG无损转码为JXL</string>\n    <string name=\"jxl_tools_sub\">无质量损失地执行JXL ~ JPEG转码，或将GIF/APNG转换为JXL动画</string>\n    <string name=\"jxl_type_to_jpeg\">JXL转JPEG</string>\n    <string name=\"fast_gaussian_blur_3d\">快速高斯模糊 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">快速高斯模糊 4D</string>\n    <string name=\"fast_gaussian_blur_2d\">快速高斯模糊 2D</string>\n    <string name=\"auto_paste\">自动粘贴</string>\n    <string name=\"auto_paste_sub\">允许应用程序自动粘贴剪贴板数据，这样它就会出现在主屏幕上，可以做进一步处理了</string>\n    <string name=\"harmonization_color\">调和颜色</string>\n    <string name=\"harmonization_level\">调和等级</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"gif_type_to_jxl\">GIF转JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">将GIF图片转换为JXL动画图片</string>\n    <string name=\"apng_type_to_jxl\">APNG转JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">将APNG图片转换为JXL动画图片</string>\n    <string name=\"jxl_type_to_images\">JXL转为图片</string>\n    <string name=\"jxl_type_to_images_sub\">将JXL动画转换为系列图片</string>\n    <string name=\"jxl_type_to_jxl\">图片转为JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">将一组图片转换为JXL动画</string>\n    <string name=\"behavior\">行为</string>\n    <string name=\"skip_file_picking\">跳过文件选取</string>\n    <string name=\"skip_file_picking_sub\">如果可以，文件选择器将立即显示在所选屏幕上</string>\n    <string name=\"generate_previews\">生成预览</string>\n    <string name=\"lossy_compression\">有损压缩</string>\n    <string name=\"lossy_compression_sub\">使用有损压缩代替无损压缩来减少文件大小</string>\n    <string name=\"generate_previews_sub\">启用预览生成，这可能有助于避免在某些设备上出现崩溃，同时也会禁用单个编辑选项中的某些编辑功能</string>\n    <string name=\"lanczos_bessel_sub\">通过对像素值应用贝塞尔（jinc）函数来保持高质量插值的重采样方法</string>\n    <string name=\"compression_type\">压缩方式</string>\n    <string name=\"speed_sub\">控制生成图片的解码速度，这将有助于更快地打开生成图片，%1$s表示最慢的解码速度，而%2$s表示最快的解码速度，此设置可能会增加输出图片的大小</string>\n    <string name=\"sorting\">筛选</string>\n    <string name=\"sort_by_date\">日期</string>\n    <string name=\"sort_by_date_reversed\">日期（反向）</string>\n    <string name=\"sort_by_name\">名称</string>\n    <string name=\"sort_by_name_reversed\">名称（反向）</string>\n    <string name=\"pick_multiple_media\">选择多种媒体</string>\n    <string name=\"pick\">选取</string>\n    <string name=\"pick_single_media\">选择单一媒体</string>\n    <string name=\"channels_configuration\">通道配置</string>\n    <string name=\"header_today\">今日</string>\n    <string name=\"header_yesterday\">昨日</string>\n    <string name=\"embedded_picker\">嵌入式选取器</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox的图片选择器</string>\n    <string name=\"no_permissions\">无权限</string>\n    <string name=\"request\">请求</string>\n    <string name=\"show_settings_in_landscape\">横向显示设置</string>\n    <string name=\"try_again\">再试一次</string>\n    <string name=\"show_settings_in_landscape_sub\">如果禁用，则在横向模式下，设置将始终在顶部应用栏的按钮上打开，而不是永久可见选项</string>\n    <string name=\"switch_type\">开关类型</string>\n    <string name=\"fullscreen_settings\">全屏设置</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"fullscreen_settings_sub\">将“启用”设置为“总是以全屏打开设置页面，而不是可滑动抽屉页”。</string>\n    <string name=\"material_you_switch_sub\">一个Material You风格的开关</string>\n    <string name=\"compose_switch_sub\">一个使用Jetpack Compose实现的Material You风格开关。</string>\n    <string name=\"max\">最大</string>\n    <string name=\"resize_anchor\">调整锚点大小</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">一个基于“Cupertino”设计系统的开关</string>\n    <string name=\"fluent_switch_sub\">一个基于“Fluent”设计系统的开关</string>\n    <string name=\"images_to_svg_sub\">将给定图片追踪为SVG图片</string>\n    <string name=\"use_sampled_palette_sub\">如果启用该选项，将对量化调色板进行采样</string>\n    <string name=\"path_omit\">路径省略</string>\n    <string name=\"downscale_image\">缩放图片</string>\n    <string name=\"downscale_image_sub\">图片将在处理前缩放为较小的尺寸，这有助于此工具更快、更安全地工作</string>\n    <string name=\"min_color_ratio\">最小色比</string>\n    <string name=\"lines_threshold\">线条阈值</string>\n    <string name=\"path_scale\">路径标度</string>\n    <string name=\"reset_properties\">重置属性</string>\n    <string name=\"images_to_svg\">图片转SVG</string>\n    <string name=\"use_sampled_palette\">使用采样调色板</string>\n    <string name=\"svg_warning\">不建议使用该工具在不缩放的情况下追踪大型图片，否则会导致崩溃并增加处理时间</string>\n    <string name=\"reset_properties_sub\">所有属性都将设置为默认值，注意此操作无法撤销</string>\n    <string name=\"coordinates_rounding_tolerance\">协调宽容</string>\n    <string name=\"quadratic_threshold\">二次阈值</string>\n    <string name=\"detailed\">详细</string>\n    <string name=\"default_line_width\">默认线宽</string>\n    <string name=\"engine_mode\">引擎模式</string>\n    <string name=\"legacy\">传统</string>\n    <string name=\"lstm_network\">LSTM 网络</string>\n    <string name=\"legacy_and_lstm\">传统和LSTM</string>\n    <string name=\"convert\">转换</string>\n    <string name=\"convert_sub\">将批量图片转换为给定格式</string>\n    <string name=\"add_new_folder\">添加新文件夹</string>\n    <string name=\"tag_bits_per_sample\">每个采样比特</string>\n    <string name=\"tag_samples_per_pixel\">每像素样本数</string>\n    <string name=\"tag_planar_configuration\">数据排列方式</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">色度抽样</string>\n    <string name=\"tag_y_cb_cr_positioning\">色度抽样位置</string>\n    <string name=\"tag_x_resolution\">X 分辨率</string>\n    <string name=\"tag_y_resolution\">Y 分辨率</string>\n    <string name=\"tag_strip_offsets\">数据块偏移量</string>\n    <string name=\"tag_rows_per_strip\">每条带行数</string>\n    <string name=\"tag_strip_byte_counts\">条带字节数</string>\n    <string name=\"tag_transfer_function\">传输功能</string>\n    <string name=\"tag_white_point\">白点</string>\n    <string name=\"tag_primary_chromaticities\">主色调</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr 系数</string>\n    <string name=\"tag_datetime\">日期时间</string>\n    <string name=\"tag_image_description\">图片描述</string>\n    <string name=\"tag_compression\">压缩方法</string>\n    <string name=\"tag_photometric_interpretation\">光度解释</string>\n    <string name=\"tag_resolution_unit\">分辨率单位</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG 交换格式</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG 交换格式长度</string>\n    <string name=\"tag_reference_black_white\">参考黑白色阶</string>\n    <string name=\"tag_model\">型号</string>\n    <string name=\"tag_exif_version\">Exif版本</string>\n    <string name=\"tag_color_space\">色彩空间</string>\n    <string name=\"tag_gamma\">伽马</string>\n    <string name=\"tag_make\">制造商</string>\n    <string name=\"tag_compressed_bits_per_pixel\">压缩每像素位数</string>\n    <string name=\"tag_maker_note\">制造商注释</string>\n    <string name=\"tag_user_comment\">用户备注</string>\n    <string name=\"tag_pixel_y_dimension\">Y轴像素尺寸</string>\n    <string name=\"tag_pixel_x_dimension\">X轴像素尺寸</string>\n    <string name=\"watermark_size\">水印体积</string>\n    <string name=\"tag_software\">软件</string>\n    <string name=\"tag_artist\">艺术家</string>\n    <string name=\"tag_copyright\">版权</string>\n    <string name=\"tag_flashpix_version\">Flashpix 版本</string>\n    <string name=\"tag_related_sound_file\">关联的音频文件</string>\n    <string name=\"tag_datetime_original\">原始日期时间</string>\n    <string name=\"tag_offset_time_original\">原始时间偏移量</string>\n    <string name=\"tag_offset_time_digitized\">数字化时间偏移量</string>\n    <string name=\"tag_subsec_time\">秒内细分时间</string>\n    <string name=\"tag_f_number\">F值</string>\n    <string name=\"tag_exposure_program\">曝光模式</string>\n    <string name=\"tag_spectral_sensitivity\">光谱灵敏度</string>\n    <string name=\"tag_photographic_sensitivity\">感光度（ISO感光度）</string>\n    <string name=\"tag_sensing_method\">图片传感器类型</string>\n    <string name=\"tag_cfa_pattern\">CFA模式</string>\n    <string name=\"tag_custom_rendered\">自定义图片处理</string>\n    <string name=\"tag_exposure_mode\">曝光模式</string>\n    <string name=\"tag_white_balance\">白平衡</string>\n    <string name=\"tag_focal_length_in_35mm_film\">35毫米胶片焦距</string>\n    <string name=\"tag_scene_capture_type\">场景拍摄类型</string>\n    <string name=\"tag_gain_control\">场景控制</string>\n    <string name=\"tag_saturation\">饱和度</string>\n    <string name=\"tag_sharpness\">锐度</string>\n    <string name=\"tag_image_unique_id\">图片唯一ID</string>\n    <string name=\"tag_camera_owner_name\">设备拥有者名称</string>\n    <string name=\"tag_lens_specification\">镜头规格</string>\n    <string name=\"tag_lens_make\">镜头制造商</string>\n    <string name=\"tag_lens_serial_number\">镜头序列号</string>\n    <string name=\"tag_gps_version_id\">GPS版本ID</string>\n    <string name=\"tag_gps_latitude_ref\">GPS纬度参考</string>\n    <string name=\"tag_gps_timestamp\">GPS时间戳</string>\n    <string name=\"tag_gps_status\">GPS接收器状态</string>\n    <string name=\"tag_gps_measure_mode\">GPS测量模式</string>\n    <string name=\"tag_gps_dop\">GPS测量精度</string>\n    <string name=\"tag_gps_speed_ref\">GPS速度参考</string>\n    <string name=\"tag_gps_speed\">GPS接收器速度</string>\n    <string name=\"tag_gps_track\">GPS移动方位</string>\n    <string name=\"tag_gps_img_direction\">GPS图片方位</string>\n    <string name=\"tag_gps_dest_latitude\">GPS目标纬度坐标</string>\n    <string name=\"tag_gps_dest_distance\">GPS目标距离</string>\n    <string name=\"tag_gps_processing_method\">GPS处理方法</string>\n    <string name=\"tag_gps_area_information\">GPS区域信息</string>\n    <string name=\"tag_gps_datestamp\">GPS日期印记</string>\n    <string name=\"tag_gps_differential\">GPS差分改正</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS水平定位误差</string>\n    <string name=\"tag_dng_version\">DNG版本</string>\n    <string name=\"tag_default_crop_size\">默认裁剪尺寸</string>\n    <string name=\"tag_orf_preview_image_length\">预览图片长度</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">传感器下边框</string>\n    <string name=\"tag_rw2_sensor_right_border\">传感器右边框</string>\n    <string name=\"tag_rw2_sensor_top_border\">传感器上边框</string>\n    <string name=\"draw_text_sub\">在给定字体和颜色下沿路径绘制文本</string>\n    <string name=\"font_size\">字体大小</string>\n    <string name=\"dash_size\">虚线长度</string>\n    <string name=\"draw_image_sub\">此图片将作为绘制路径的重复元素使用</string>\n    <string name=\"tag_standard_output_sensitivity\">标准输出感光度</string>\n    <string name=\"tag_datetime_digitized\">数字化日期时间</string>\n    <string name=\"tag_offset_time\">时间偏移量</string>\n    <string name=\"tag_subsec_time_original\">原始秒内细分时间</string>\n    <string name=\"tag_exposure_time\">曝光时间</string>\n    <string name=\"tag_subsec_time_digitized\">数字化秒内细分时间</string>\n    <string name=\"tag_oecf\">光电转换函数(OECF)</string>\n    <string name=\"tag_sensitivity_type\">感光类型</string>\n    <string name=\"tag_brightness_value\">亮度值</string>\n    <string name=\"tag_exposure_bias_value\">曝光补偿值</string>\n    <string name=\"tag_recommended_exposure_index\">推荐曝光指数</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO速度宽容度zzz</string>\n    <string name=\"tag_iso_speed\">ISO速度</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO速度宽容度yyy</string>\n    <string name=\"tag_aperture_value\">光圈值</string>\n    <string name=\"tag_shutter_speed_value\">快门速度值</string>\n    <string name=\"tag_max_aperture_value\">最大光圈值</string>\n    <string name=\"tag_subject_distance\">拍摄距离</string>\n    <string name=\"tag_metering_mode\">测光模式</string>\n    <string name=\"tag_flash\">闪光灯状态</string>\n    <string name=\"tag_flash_energy\">闪光灯强度</string>\n    <string name=\"tag_subject_area\">主体区域</string>\n    <string name=\"tag_focal_length\">焦距</string>\n    <string name=\"tag_exposure_index\">曝光指数</string>\n    <string name=\"tag_spatial_frequency_response\">空间频率反应</string>\n    <string name=\"tag_focal_plane_x_resolution\">焦距平面X轴解析度</string>\n    <string name=\"tag_focal_plane_resolution_unit\">焦距平面解析度单位</string>\n    <string name=\"tag_focal_plane_y_resolution\">焦距平面Y轴解析度</string>\n    <string name=\"tag_subject_location\">主体位置</string>\n    <string name=\"tag_file_source\">源文件</string>\n    <string name=\"tag_digital_zoom_ratio\">数字变焦</string>\n    <string name=\"tag_lens_model\">镜头型号</string>\n    <string name=\"tag_contrast\">对比度</string>\n    <string name=\"tag_device_setting_description\">设备设定描述</string>\n    <string name=\"tag_subject_distance_range\">主体距离范围</string>\n    <string name=\"tag_body_serial_number\">机身序列号</string>\n    <string name=\"tag_gps_latitude\">GPS纬度</string>\n    <string name=\"tag_gps_longitude_ref\">GPS经度参考</string>\n    <string name=\"tag_gps_longitude\">GPS经度</string>\n    <string name=\"tag_gps_altitude_ref\">GPS海拔参照值</string>\n    <string name=\"tag_gps_altitude\">GPS海拔</string>\n    <string name=\"tag_gps_satellites\">GPS接收卫星</string>\n    <string name=\"tag_gps_track_ref\">GPS移动方位参照</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS图片方位参照</string>\n    <string name=\"tag_gps_map_datum\">GPS地图基准面</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS目标纬度参考方向</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS目标经度参考方向</string>\n    <string name=\"tag_gps_dest_longitude\">GPS目标经度坐标</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS到达目标方向参考</string>\n    <string name=\"tag_orf_aspect_frame\">纵横比框架</string>\n    <string name=\"tag_gps_dest_bearing\">GPS到达目标方位角</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS目标距离参考</string>\n    <string name=\"tag_interoperability_index\">互操作性指数</string>\n    <string name=\"tag_orf_preview_image_start\">预览图片起始位置</string>\n    <string name=\"tag_rw2_sensor_left_border\">传感器左边框</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"repeat_text\">重复文本</string>\n    <string name=\"repeat_text_sub\">当前文本将会沿着路径重复绘制，直到路径结束，而非仅绘制一次。</string>\n    <string name=\"draw_mode_image_sub\">使用选中的图片沿给定路径绘制</string>\n    <string name=\"triangle_sub\">绘制从起点到终点的三角形轮廓线</string>\n    <string name=\"outlined_triangle\">三角形轮廓</string>\n    <string name=\"triangle\">三角形</string>\n    <string name=\"outlined_triangle_sub\">绘制从起点到终点的三角形轮廓线</string>\n    <string name=\"polygon\">多边形</string>\n    <string name=\"outlined_polygon\">多边形轮廓</string>\n    <string name=\"vertices\">节点</string>\n    <string name=\"polygon_sub\">绘制从起点到终点的多边形</string>\n    <string name=\"outlined_polygon_sub\">绘制从起点到终点的多边形轮廓</string>\n    <string name=\"draw_regular_polygon\">绘制正多边形</string>\n    <string name=\"draw_regular_polygon_sub\">绘制规则多边形，而不是自由形状的多边形</string>\n    <string name=\"star_sub\">从起点到终点绘制星形</string>\n    <string name=\"star\">星形</string>\n    <string name=\"outlined_star\">星形轮廓</string>\n    <string name=\"outlined_star_sub\">绘制从起点到终点的星形轮廓图</string>\n    <string name=\"inner_radius_ratio\">内部半径比</string>\n    <string name=\"draw_regular_star_sub\">绘制规则而非自由形状的星星</string>\n    <string name=\"draw_regular_star\">绘制规则星形</string>\n    <string name=\"antialias\">抗锯齿</string>\n    <string name=\"antialias_sub\">启用抗锯齿功能以防止出现尖锐边缘</string>\n    <string name=\"open_edit_instead_of_preview\">打开编辑而不是预览</string>\n    <string name=\"open_edit_instead_of_preview_sub\">在 ImageToolbox 中选择要打开（预览）的图片时，将打开编辑选择表，而不是预览</string>\n    <string name=\"document_scanner\">文档扫描器</string>\n    <string name=\"click_to_start_scanning\">点击开始扫描</string>\n    <string name=\"equalize_histogram_hsv\">均衡直方图 HSV</string>\n    <string name=\"equalize_histogram\">均衡直方图</string>\n    <string name=\"document_scanner_sub\">扫描文档并创建PDF或单独的图片</string>\n    <string name=\"share_as_pdf\">以PDF格式分享</string>\n    <string name=\"options_below_is_for_images\">以下选项用于保存图片，而非PDF文件</string>\n    <string name=\"start_scanning\">开始扫描</string>\n    <string name=\"save_as_pdf\">保存为PDF</string>\n    <string name=\"enter_percentage\">输入百分数</string>\n    <string name=\"allow_enter_by_text_field\">允许通过文本字段输入</string>\n    <string name=\"allow_enter_by_text_field_sub\">启用预设选择后面的文本字段，以便即时输入预设</string>\n    <string name=\"equalize_histogram_pixelation\">均衡直方图像素化</string>\n    <string name=\"scale_color_space\">比例色彩空间</string>\n    <string name=\"linear\">线性</string>\n    <string name=\"grid_size_y\">网格大小 Y</string>\n    <string name=\"equalize_histogram_adaptive_luv\">均衡直方图自适应 LUV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">均衡直方图自适应 LAB</string>\n    <string name=\"clahe\">CLAHE</string>\n    <string name=\"clahe_lab\">CLAHE LAB</string>\n    <string name=\"clahe_luv\">CLAHE LUV</string>\n    <string name=\"frame_color\">边框颜色</string>\n    <string name=\"color_to_ignore\">忽略颜色</string>\n    <string name=\"grid_size_x\">网格大小 X</string>\n    <string name=\"equalize_histogram_adaptive\">均衡直方图自适应</string>\n    <string name=\"crop_to_content\">裁剪为内容</string>\n    <string name=\"create_new\">新建</string>\n    <string name=\"opened_file_have_no_filter_template\">所选文件无过滤模板数据</string>\n    <string name=\"create_template\">创建模板</string>\n    <string name=\"template_name\">模板名称</string>\n    <string name=\"select_template_preview\">该图片将用于预览该滤镜模板</string>\n    <string name=\"as_qr_code\">作为二维码图片</string>\n    <string name=\"as_file\">作为文件</string>\n    <string name=\"save_as_file\">保存为文件</string>\n    <string name=\"save_as_qr_code_image\">另存为二维码图片</string>\n    <string name=\"delete_template\">删除模板</string>\n    <string name=\"filter_preview\">滤镜预览</string>\n    <string name=\"qr_code\">二维码&amp;条形码</string>\n    <string name=\"qr_code_sub\">扫描二维码并获取其内容，或粘贴字符串以生成新的二维码</string>\n    <string name=\"code_content\">代码内容</string>\n    <string name=\"scan_qr_code_to_replace_content\">扫描任意条形码以替换字段中的内容，或输入内容以使用所选类型生成新条形码</string>\n    <string name=\"qr_description\">QR 说明</string>\n    <string name=\"delete_template_warn\">您将删除选定的模板滤镜。 此操作无法撤销</string>\n    <string name=\"template_filter\">模板滤镜</string>\n    <string name=\"no_template_filters\">未添加模板滤镜</string>\n    <string name=\"template\">模板</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">扫描的二维码不是有效的滤镜模板</string>\n    <string name=\"scan_qr_code\">扫描二维码</string>\n    <string name=\"added_filter_template\">已添加滤镜模板，名称为\\\"%1$s\\\" (%2$s)</string>\n    <string name=\"min\">最小</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">在设置中授予相机扫描二维码的权限</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">在设置中授予相机文档扫描器的权限</string>\n    <string name=\"cubic\">立方体</string>\n    <string name=\"gaussian\">高斯型</string>\n    <string name=\"sphinx\">斯芬克斯</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">样条16</string>\n    <string name=\"spline36\">样条36</string>\n    <string name=\"spline64\">样条64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"box\">盒</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"cubic_sub\">立方插值法通过考虑最近的 16 个像素来实现更平滑的缩放，比双线性插值法效果更好。</string>\n    <string name=\"bspline_sub\">利用分段定义的多项式函数平滑插值和近似曲线或曲面，灵活、连续地表示形状</string>\n    <string name=\"hamming_sub\">一种窗口函数，用于通过渐变信号边缘来减少频谱泄漏，在信号处理中非常有用</string>\n    <string name=\"hanning_sub\">Hann 窗口的一种变体，常用于减少信号处理应用中的频谱泄漏</string>\n    <string name=\"blackman_sub\">一种窗口函数，通过最大限度地减少频谱泄漏来提供良好的频率分辨率，常用于信号处理中</string>\n    <string name=\"gaussian_sub\">一种应用高斯函数的插值方法，可用于平滑和减少图片中的噪音</string>\n    <string name=\"bartlett_sub\">信号处理中用于减少频谱泄漏的三角窗函数</string>\n    <string name=\"robidoux_sub\">高质量的插值方法经过优化，可自然调整图片大小，兼顾清晰度和平滑度</string>\n    <string name=\"robidoux_sharp_sub\">Robidoux方法的一个更清晰的变体，针对清晰的图片大小调整进行了优化</string>\n    <string name=\"spline16_sub\">基于样条线的插值方法，使用 16 抽头滤镜提供平滑结果</string>\n    <string name=\"spline36_sub\">基于样条线的插值方法，使用 36 抽头滤镜提供平滑结果</string>\n    <string name=\"spline64_sub\">基于样条线的插值方法，使用 64 抽头滤镜提供平滑结果</string>\n    <string name=\"bartlett_hann_sub\">一种结合了Bartlett窗和Hann窗的混合窗函数，用于减少信号处理中的频谱泄漏</string>\n    <string name=\"box_sub\">一种简单的重取样方法，使用最近像素值的平均值，通常会产生块状外观</string>\n    <string name=\"bohman_sub\">一种窗口函数，用于减少频谱泄漏，在信号处理应用中提供良好的频率分辨率</string>\n    <string name=\"lanczos2_sub\">一种使用双叶 Lanczos 滤镜的重采样方法，可实现最小伪影的高质量插值</string>\n    <string name=\"lanczos2_jinc_sub\">Lanczos 2 滤镜的变体，使用 jinc 函数，可提供高质量的插值，并将伪影降至最低</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_hanning_sub\">Hanning 滤镜的椭圆加权平均 (EWA) 变体，用于平滑插值和重采样</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"bspline\">B样条</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"quadric\">四面体</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"welch_sub\">一种窗口函数，旨在提供良好的频率分辨率，减少频谱泄漏，常用于信号处理应用中</string>\n    <string name=\"quadric_sub\">一种使用二次函数进行插值的方法，可提供平滑、连续的结果</string>\n    <string name=\"lanczos4_sub\">一种重采样方法，使用 4叶 Lanczos 滤镜进行高质量插值，将伪影降到最低</string>\n    <string name=\"sphinx_sub\">先进的重采样方法可提供高质量的插值，并将人工痕迹降至最低</string>\n    <string name=\"lanczos3_jinc_sub\">Lanczos 3 滤镜的变体，使用 jinc 函数，可提供高质量的插值，并将伪影降至最低</string>\n    <string name=\"kaiser_sub\">使用 Kaiser 窗口的插值方法，能很好地控制主叶宽度和侧叶水平之间的权衡</string>\n    <string name=\"lanczos3_sub\">使用三叶 Lanczos 滤镜进行高质量插值的重采样方法，将伪影降到最低</string>\n    <string name=\"lanczos4_jinc_sub\">Lanczos 4 滤镜的变体，使用 jinc 函数，可提供高质量的插值，并将伪影降至最低</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Robidoux Sharp 滤镜的椭圆加权平均 (EWA) 变体，效果更清晰</string>\n    <string name=\"ewa_quadric_sub\">用于平滑插值的四元滤镜椭圆加权平均 (EWA) 变体</string>\n    <string name=\"ewa_blackman_sub\">Blackman 滤镜的椭圆加权平均 (EWA) 变体，用于尽量减少振铃伪影</string>\n    <string name=\"ewa_ginseng_sub\">Ginseng 滤镜的椭圆加权平均 (EWA) 变体，提高图片质量</string>\n    <string name=\"ginseng_sub\">重采样滤镜专为高质量图片处理而设计，在清晰度和平滑度之间取得了良好的平衡</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Lanczos 3 Jinc 滤镜的椭圆加权平均 (EWA) 变体，用于减少混叠的高质量重采样</string>\n    <string name=\"format_conversion\">格式转换</string>\n    <string name=\"dismiss_forever\">永久忽略</string>\n    <string name=\"image_stacking\">图片堆叠</string>\n    <string name=\"image_stacking_sub\">使用选定的混合模式将图片堆叠在一起</string>\n    <string name=\"add_image\">添加图片</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Lanczos Sharp 滤镜的椭圆加权平均 (EWA) 变体，以最小的伪影获得清晰的效果</string>\n    <string name=\"ewa_lanczos_soft_sub\">椭圆加权平均 (EWA) Lanczos Soft 滤镜变体，用于更平滑的图片重采样</string>\n    <string name=\"format_conversion_sub\">将批量图片从一种格式转换为另一种格式</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Lanczos 4 Sharpest 滤镜的椭圆加权平均 (EWA) 变体，用于对图片进行极其清晰的重采样</string>\n    <string name=\"haasn_soft_sub\">由 Haasn 设计的重采样滤镜，可实现平滑、无伪影的图片缩放</string>\n    <string name=\"ewa_robidoux_sub\">用于高质量重采样的 Robidoux 滤镜椭圆加权平均（EWA）变体</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"bins_count\">箱数</string>\n    <string name=\"edge_mode\">边缘模式</string>\n    <string name=\"clip\">剪切</string>\n    <string name=\"wrap\">缠绕</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">均衡直方图自适应 HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">均衡直方图自适应 HSV</string>\n    <string name=\"color_blind_scheme\">色盲</string>\n    <string name=\"color_blind_scheme_sub\">选择模式以为所选色盲类型适配主题颜色</string>\n    <string name=\"protanomaly_sub\">难以区分红色和绿色色调</string>\n    <string name=\"deuteranomaly_sub\">难以区分绿色和红色色调</string>\n    <string name=\"tritanomaly_sub\">难以区分蓝色和黄色色调</string>\n    <string name=\"lagrange_2\">拉格朗日 2</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"lagrange_2_sub\">阶数为 2 的拉格朗日插值滤波器，适用于平滑过渡的高质量图片缩放</string>\n    <string name=\"lagrange_3\">拉格朗日 3</string>\n    <string name=\"lanczos_6_sub\">阶数为 6 的 Lanczos 重采样滤波器，可提供更清晰、更准确的图片缩放效果</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_jinc_sub\">使用 Jinc 函数改进图片重采样质量的Lanczos 6 滤波器变体</string>\n    <string name=\"protanopia_sub\">无法感知红色色调</string>\n    <string name=\"deuteranopia_sub\">无法感知绿色色调</string>\n    <string name=\"tritanopia_sub\">无法感知蓝色色调</string>\n    <string name=\"achromatopsia_sub\">完全色盲，只能看到灰色阴影</string>\n    <string name=\"achromatomaly_sub\">对所有颜色的敏感度降低</string>\n    <string name=\"not_use_color_blind_scheme\">不要使用色盲方案</string>\n    <string name=\"not_use_color_blind_scheme_sub\">颜色将与主题中的设置完全一致</string>\n    <string name=\"sigmoidal\">乙字形</string>\n    <string name=\"lagrange_3_sub\">阶数为 3 的拉格朗日插值滤波器，可为图片缩放提供更高的精度和更平滑的结果</string>\n    <string name=\"linear_tent_blur\">线性帐篷模糊</string>\n    <string name=\"linear_fast_gaussian_blur_next\">线性快速高斯 Next</string>\n    <string name=\"linear_box_blur\">线性盒状模糊</string>\n    <string name=\"gaussian_box_blur\">高斯盒状模糊</string>\n    <string name=\"linear_fast_gaussian_blur\">线性快速高斯</string>\n    <string name=\"linear_gaussian_blur\">线性高斯</string>\n    <string name=\"linear_gaussian_box_blur\">线性高斯盒状模糊</string>\n    <string name=\"linear_stack_blur\">线性叠加模糊</string>\n    <string name=\"draw_filter_sub\">选择一个滤镜，将其作为颜料使用</string>\n    <string name=\"replace_filter\">替换滤镜</string>\n    <string name=\"pick_filter_info\">选择以下滤镜，将其用作绘图中的笔刷</string>\n    <string name=\"tiff_compression_scheme\">TIFF 压缩方案</string>\n    <string name=\"low_poly\">低多边形</string>\n    <string name=\"sand_painting\">沙画</string>\n    <string name=\"image_splitting\">图片分割</string>\n    <string name=\"image_splitting_sub\">按行或列分割单张图片</string>\n    <string name=\"backup_ocr_models\">备份OCR模型</string>\n    <string name=\"export\">导出</string>\n    <string name=\"position\">位置</string>\n    <string name=\"top_left\">左上</string>\n    <string name=\"top_right\">右上</string>\n    <string name=\"bottom_left\">左下</string>\n    <string name=\"bottom_right\">右下</string>\n    <string name=\"top_center\">中上</string>\n    <string name=\"center_right\">右中</string>\n    <string name=\"bottom_center\">中下</string>\n    <string name=\"center_left\">左中</string>\n    <string name=\"fit_to_bounds_sub\">将裁剪调整大小模式与该参数相结合，以实现所需的行为（裁剪/适应宽高比）。</string>\n    <string name=\"fit_to_bounds\">适应边界</string>\n    <string name=\"import_word\">导入</string>\n    <string name=\"languages_imported\">语言导入成功</string>\n    <string name=\"center\">中心</string>\n    <string name=\"palette_transfer\">调色板转换</string>\n    <string name=\"enhanced_oil\">油画效果增强</string>\n    <string name=\"target_image\">目标图片</string>\n    <string name=\"simple_old_tv\">简易老式电视</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"gotham\">哥谭</string>\n    <string name=\"simple_sketch\">简易素描</string>\n    <string name=\"soft_glow\">柔光</string>\n    <string name=\"color_poster\">彩色海报</string>\n    <string name=\"third_color\">第三色</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"tri_tone\">三原色</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"polka_dot\">波尔卡圆点</string>\n    <string name=\"clustered_2x2_dithering\">集群式 2x2 抖动</string>\n    <string name=\"clustered_4x4_dithering\">集群式 4x4 抖动</string>\n    <string name=\"clustered_8x8_dithering\">集群式 8x8 抖动</string>\n    <string name=\"yililoma_dithering\">Yililoma 抖动</string>\n    <string name=\"add_favorites\">添加收藏夹</string>\n    <string name=\"harmony_complementary\">互补</string>\n    <string name=\"color_tools\">色彩工具</string>\n    <string name=\"harmony_square\">方型色</string>\n    <string name=\"harmony_analogous_complementary\">临近色 + 互补色</string>\n    <string name=\"color_tools_sub\">混合、制作色调、生成色调等</string>\n    <string name=\"color_harmonies\">色彩调和</string>\n    <string name=\"color_shading\">色彩阴影</string>\n    <string name=\"variation\">变体</string>\n    <string name=\"shades\">阴影</string>\n    <string name=\"tones\">色调</string>\n    <string name=\"tints\">淡色</string>\n    <string name=\"selected_color\">已选择颜色</string>\n    <string name=\"color_info\">颜色信息</string>\n    <string name=\"color_mixing\">颜色混合</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">开启动态色彩时无法使用莫奈取色</string>\n    <string name=\"target_lut_image\">目标 LUT 图片</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"candlelight\">烛光</string>\n    <string name=\"no_favorite_options_selected\">未选择收藏夹选项，请在工具页面添加这些选项</string>\n    <string name=\"harmony_analogous\">临近色</string>\n    <string name=\"harmony_split_complementary\">分割互补色</string>\n    <string name=\"harmony_triadic\">三角色</string>\n    <string name=\"harmony_tetradic\">四方色</string>\n    <string name=\"color_to_mix\">要混合的颜色</string>\n    <string name=\"soft_elegance_variant\">柔美优雅变体</string>\n    <string name=\"target_cube_lut_file\">目标 3D LUT 文件 (.cube / .CUBE)</string>\n    <string name=\"lut\">色彩查找表（LUT）</string>\n    <string name=\"bleach_bypass\">漂白旁路</string>\n    <string name=\"palette_transfer_variant\">调色板转移变体</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"soft_elegance\">柔美优雅</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"foggy_night\">雾夜朦胧</string>\n    <string name=\"film_stock_50\">50号胶片</string>\n    <string name=\"fall_colors\">金秋色彩</string>\n    <string name=\"edgy_amber\">锐利琥珀</string>\n    <string name=\"save_empty_lut\">获取中性 LUT 图片</string>\n    <string name=\"drop_blues\">沉寂蓝调</string>\n    <string name=\"save_empty_lut_sub\">首先，使用你最喜欢的图片编辑应用将一个滤镜应用于中性LUT（颜色查找表），你可以在这里获取它。为了使这个操作正常工作，每个像素的颜色不能依赖于其他像素（例如，模糊效果是不行的）。一旦准备就绪，将你的新LUT图片作为输入用于512x512 LUT滤镜。</string>\n    <string name=\"kodak\">柯达胶卷</string>\n    <string name=\"pop_art\">流行艺术</string>\n    <string name=\"golden_forest\">金色森林</string>\n    <string name=\"coffee\">咖啡</string>\n    <string name=\"celluloid\">Celluloid</string>\n    <string name=\"greenish\">青翠之影</string>\n    <string name=\"retro_yellow\">时光黄影</string>\n    <string name=\"links_preview\">链接预览</string>\n    <string name=\"links\">链接</string>\n    <string name=\"links_preview_sub\">在可获取文本（二维码、OCR 等）的地方启用链接预览检索功能</string>\n    <string name=\"ico_size_warning\">ICO文件只能以最大256×256的尺寸保存</string>\n    <string name=\"gif_type_to_webp\">GIF 转为 WEBP</string>\n    <string name=\"webp_type_to_image_sub\">将WEBP文件转换为一批图片</string>\n    <string name=\"webp_type_to_webp_sub\">将一批图片转换为WEBP文件</string>\n    <string name=\"webp_type_to_webp\">图片转为WEBP</string>\n    <string name=\"gif_type_to_webp_sub\">将GIF图片转换为WEBP动画图片</string>\n    <string name=\"webp_tools\">WEBP工具</string>\n    <string name=\"webp_type_to_image\">WEBP转为多张图片</string>\n    <string name=\"select_webp_image_to_start\">选取 WEBP 图片以开始</string>\n    <string name=\"webp_tools_sub\">将图片转换为WEBP动画图片，或从给定的WEBP动画中提取帧</string>\n    <string name=\"default_draw_color\">默认绘图颜色</string>\n    <string name=\"default_draw_path_mode\">默认绘制路径模式</string>\n    <string name=\"add_timestamp\">添加时间戳</string>\n    <string name=\"formatted_timestamp_sub\">在输出文件名中启用时间戳格式，代替基本的毫秒数</string>\n    <string name=\"manage_storage_extra_types\">无法完全访问文件</string>\n    <string name=\"manage_storage_extra_types_sub\">允许所有文件访问以查看JXL、QOI和其他在Android上未被识别为图片的图片。如果没有此权限，Image Toolbox将无法显示这些图片</string>\n    <string name=\"add_timestamp_sub\">启用在输出文件名中添加时间戳</string>\n    <string name=\"formatted_timestamp\">格式化时间戳</string>\n    <string name=\"enable_timestamps_to_format_them\">启用时间戳以选择其格式</string>\n    <string name=\"recently_used\">最近使用</string>\n    <string name=\"ci_channel_sub\">获取应用程序新版本的通知并阅读公告</string>\n    <string name=\"ci_channel\">自动构建（CI）频道</string>\n    <string name=\"one_time_save_location\">单次保存位置</string>\n    <string name=\"group\">Telegram群组</string>\n    <string name=\"one_time_save_location_sub\">查看和编辑单次保存位置，您可以在大多数选项中长按保存按钮来使用这些位置</string>\n    <string name=\"image_toolbox_in_telegram\">Image Toolbox 在 Telegram 🎉</string>\n    <string name=\"image_toolbox_in_telegram_sub\">加入我们的聊天室，在这里你可以讨论任何你想讨论的问题，还可以查看 CI 频道，我将在这里发布测试版和公告。</string>\n    <string name=\"fit_description\">根据给定尺寸调整图片，并为背景添加模糊效果或颜色</string>\n    <string name=\"tools_arrangement\">工具排列</string>\n    <string name=\"group_tools_by_type\">按类型分组工具</string>\n    <string name=\"group_tools_by_type_sub\">在主屏幕上按工具类型分组，代替按自定义列表排列</string>\n    <string name=\"default_values\">默认值</string>\n    <string name=\"system_bars_visibility\">系统栏可见性</string>\n    <string name=\"show_system_bars_by_swipe\">通过轻划显示系统栏</string>\n    <string name=\"show_system_bars_by_swipe_sub\">如果系统栏被隐藏，则启用轻划以显示系统栏</string>\n    <string name=\"auto\">自动</string>\n    <string name=\"hide_all\">隐藏全部</string>\n    <string name=\"show_all\">显示全部</string>\n    <string name=\"hide_nav_bar\">隐藏导航栏</string>\n    <string name=\"hide_status_bar\">隐藏状态栏</string>\n    <string name=\"noise_generation\">噪点生成</string>\n    <string name=\"frequency\">频率</string>\n    <string name=\"noise_type\">噪点类型</string>\n    <string name=\"noise_generation_sub\">产生不同的噪点，如柏林或其他类型的噪点</string>\n    <string name=\"rotation_type\">旋转类型</string>\n    <string name=\"octaves\">八分音符</string>\n    <string name=\"lacunarity\">Lacunarity</string>\n    <string name=\"gain\">增益</string>\n    <string name=\"weighted_strength\">加权强度</string>\n    <string name=\"ping_pong_strength\">乒乓强度</string>\n    <string name=\"distance_function\">距离功能</string>\n    <string name=\"return_type\">返回类型</string>\n    <string name=\"fractal_type\">分形类型</string>\n    <string name=\"jitter\">抖动</string>\n    <string name=\"alignment\">对齐</string>\n    <string name=\"domain_warp\">领域扭曲</string>\n    <string name=\"custom_filename\">自定义文件名</string>\n    <string name=\"custom_filename_sub\">选择用于保存当前图片的位置和文件名</string>\n    <string name=\"saved_to_custom\">保存到以自定义名称的文件夹中</string>\n    <string name=\"collage_maker\">拼贴画制作器</string>\n    <string name=\"collage_type\">拼贴画类型</string>\n    <string name=\"collage_maker_sub\">用最多20张图片制作拼贴画</string>\n    <string name=\"collages_info\">按住图片进行交换、移动和缩放以调整位置</string>\n    <string name=\"image_for_histogram\">该图片将用于生成 RGB 和亮度直方图</string>\n    <string name=\"histogram\">直方图</string>\n    <string name=\"histogram_sub\">RGB 或亮度图片直方图来帮助您进行调整</string>\n    <string name=\"tesseract_options\">魔方选项</string>\n    <string name=\"tesseract_options_sub\">为 tesseract 引擎应用一些输入变量</string>\n    <string name=\"custom_options\">自定义选项</string>\n    <string name=\"custom_params_info\">应按照以下模式输入选项 \\\"--{选项名} {值}\\\"</string>\n    <string name=\"free_corners\">自由圆角</string>\n    <string name=\"mask\">滤镜</string>\n    <string name=\"spot_heal_sub\">在绘制的路径下进行内容感知填充</string>\n    <string name=\"spot_heal\">修复斑点</string>\n    <string name=\"auto_crop\">自动裁剪</string>\n    <string name=\"coerce_points_to_image_bounds\">强制点到图片边界</string>\n    <string name=\"free_corners_sub\">按多边形裁剪图片，这也可以修正透视</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">点将不受图片边界的限制，这有助于进行更精确的透视校正</string>\n    <string name=\"morphological_gradient\">形态渐变</string>\n    <string name=\"use_circle_kernel\">使用圆形内核</string>\n    <string name=\"opening\">正在开启</string>\n    <string name=\"closing\">正在关闭</string>\n    <string name=\"top_hat\">顶帽</string>\n    <string name=\"black_hat\">黑帽</string>\n    <string name=\"line_style\">线条风格</string>\n    <string name=\"gap_size\">间隙大小</string>\n    <string name=\"dashed\">虚线</string>\n    <string name=\"dot_dashed\">圆点虚线</string>\n    <string name=\"stamped\">盖章</string>\n    <string name=\"zigzag\">之字形</string>\n    <string name=\"dashed_sub\">以指定的间隙大小沿绘制路径绘制虚线</string>\n    <string name=\"dot_dashed_sub\">沿指定路径绘制点和虚线</string>\n    <string name=\"defaultt_sub\">仅默认直线</string>\n    <string name=\"stamped_sub\">按指定间距沿路径绘制选定图形</string>\n    <string name=\"zigzag_sub\">沿着路径画出波浪之字形</string>\n    <string name=\"zigzag_ratio\">之字形比率</string>\n    <string name=\"create_shortcut\">创建快捷方式</string>\n    <string name=\"create_shortcut_title\">选择要固定的工具</string>\n    <string name=\"create_shortcut_subtitle\">该工具将作为快捷方式添加到启动器的主屏幕上，结合 “跳过文件拾取”设置使用，即可实现所需的功能</string>\n    <string name=\"dont_stack_frames\">不要堆叠帧</string>\n    <string name=\"dont_stack_frames_sub\">处理预留帧，使其不会相互堆叠</string>\n    <string name=\"crossfade\">交叉渐变</string>\n    <string name=\"crossfade_sub\">帧与帧之间会交叉淡入淡出</string>\n    <string name=\"crossfade_count\">交叉渐变帧数</string>\n    <string name=\"tone_curves\">色调曲线</string>\n    <string name=\"reset_curves_sub\">曲线将回滚到默认值</string>\n    <string name=\"reset_curves\">重置曲线</string>\n    <string name=\"threshold_one\">阈值一</string>\n    <string name=\"threshold_two\">阈值二</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"mirror_101\">镜子 101</string>\n    <string name=\"enhanced_zoom_blur\">增强缩放模糊</string>\n    <string name=\"laplacian_simple\">简易拉普拉斯</string>\n    <string name=\"helper_grid\">辅助网格</string>\n    <string name=\"helper_grid_sub\">在绘图区域上方显示辅助网格，以帮助进行精确操作。</string>\n    <string name=\"sobel_simple\">简易索贝尔</string>\n    <string name=\"grid_color\">网格颜色</string>\n    <string name=\"cell_width\">单元格宽度</string>\n    <string name=\"cell_height\">单元格高度</string>\n    <string name=\"compact_selectors\">紧凑型选择器</string>\n    <string name=\"compact_selectors_sub\">一些选择控件将使用紧凑型布局以占用更少的空间。</string>\n    <string name=\"grant_camera_permission_to_capture_image\">在设置中授予相机权限以捕获图片。</string>\n    <string name=\"layout\">布局</string>\n    <string name=\"main_screen_title\">主屏幕标题</string>\n    <string name=\"constant_rate_factor\">恒定比率系数 (CRF)</string>\n    <string name=\"crf_sub\">%1$s表示压缩速度较慢，因此文件相对较小。%2$s表示压缩速度较快，因此文件较大。</string>\n    <string name=\"filter_preview_image\">预览图片</string>\n    <string name=\"lut_library\">Lut 库</string>\n    <string name=\"lut_library_sub\">下载 LUT 集合，你可以在下载后应用它们</string>\n    <string name=\"filter_preview_image_sub\">更改滤镜的默认图片预览</string>\n    <string name=\"lut_library_update_sub\">更新 LUT 集合（只有新的 LUT 会被加入队列），你可以在下载后应用它们</string>\n    <string name=\"hide\">隐藏</string>\n    <string name=\"show\">显示</string>\n    <string name=\"fancy\">精致</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"slider_type\">滑块类型</string>\n    <string name=\"material_2_sub\">一个Material 2风格的滑块</string>\n    <string name=\"fancy_sub\">一个外观精美的滑块。此为默认选项</string>\n    <string name=\"material_you_slider_sub\">一个Material You风格的滑块</string>\n    <string name=\"apply\">接受</string>\n    <string name=\"center_align_dialog_buttons\">居中对话框按钮</string>\n    <string name=\"open_source_licenses\">开源许可证</string>\n    <string name=\"open_source_licenses_sub\">查看此应用中所使用的开源库的许可证</string>\n    <string name=\"center_align_dialog_buttons_sub\">如果可能的话，对话框的按钮将被置于居中位置，而非左侧。</string>\n    <string name=\"area\">区域</string>\n    <string name=\"enable_tonemapping\">启用色调映射</string>\n    <string name=\"area_sub\">使用像素面积关系进行重采样。这可能是图片抽取的一种首选方法，因为它能产生无摩尔纹的结果。但当对图片进行放大时，它与最近邻法类似 。</string>\n    <string name=\"enter_percent\">输入%</string>\n    <string name=\"unknown_host\">无法连接到此网站，请尝试使用VPN或检查URL是否正确</string>\n    <string name=\"edit_layer\">编辑图层</string>\n    <string name=\"layers_on_image_sub\">使用一张图片作为背景，并在其上添加不同的图层</string>\n    <string name=\"layers_on_background_sub\">与第一个选项相同，但用颜色代替图片</string>\n    <string name=\"markup_layers\">标记图层</string>\n    <string name=\"markup_layers_sub\">图层模式，可自由放置图片、文本等内容</string>\n    <string name=\"layers_on_image\">图片上的图层</string>\n    <string name=\"layers_on_background\">背景图层</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"fast_settings_side\">快速设置边栏</string>\n    <string name=\"fast_settings_side_sub\">编辑图片时，在选定的侧边添加一个浮动条，点击该浮动条会打开快速设置</string>\n    <string name=\"clear_selection\">清除选择项</string>\n    <string name=\"settings_group_visibility_hidden\">设置组 \\\"%1$s\\\" 将默认折叠</string>\n    <string name=\"settings_group_visibility_visible\">设置组“%1$s”将默认展开</string>\n    <string name=\"base_64_tools\">Base64工具</string>\n    <string name=\"base_64_tools_sub\">将Base64字符串解码为图片，或将图片编码为Base64格式</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"not_a_valid_base_64\">提供的值不是有效的Base64字符串</string>\n    <string name=\"paste_base_64\">粘贴Base64</string>\n    <string name=\"save_base_64\">保存Base64</string>\n    <string name=\"options\">选项</string>\n    <string name=\"import_base_64\">导入Base64</string>\n    <string name=\"copy_not_a_valid_base_64\">无法复制空的或无效的Base64字符串</string>\n    <string name=\"copy_base_64\">复制Base64</string>\n    <string name=\"base_64_tips\">加载图片以复制或保存Base64字符串。如果您已有Base64字符串，可以粘贴到上方以获取图片</string>\n    <string name=\"share_base_64\">分享Base64</string>\n    <string name=\"actions\">操作</string>\n    <string name=\"base_64_actions\">Base64 操作</string>\n    <string name=\"add_outline\">添加大纲</string>\n    <string name=\"add_outline_sub\">在特殊颜色和边框文字添加大纲</string>\n    <string name=\"outline_color\">大纲颜色</string>\n    <string name=\"outline_size\">大纲字体</string>\n    <string name=\"rotation\">旋转</string>\n    <string name=\"checksum_as_filename\">校验和作为文件名</string>\n    <string name=\"checksum_as_filename_sub\">输出图片将采用与其数据校验和相对应的名称</string>\n    <string name=\"calculate\">计算</string>\n    <string name=\"checksum\">校验和</string>\n    <string name=\"text_hash\">文本哈希</string>\n    <string name=\"enter_text_to_checksum\">输入文本，根据所选算法来计算其校验和</string>\n    <string name=\"source_checksum\">源校验和</string>\n    <string name=\"checksum_to_compare\">用于比较的校验和</string>\n    <string name=\"difference\">不同</string>\n    <string name=\"difference_sub\">校验和不相等，文件可能不安全！</string>\n    <string name=\"match\">匹配！</string>\n    <string name=\"free_software_partner_sub\">安卓应用合作伙伴渠道中有更多实用软件</string>\n    <string name=\"free_software_partner\">免费软件（合作伙伴）</string>\n    <string name=\"checksum_tools_sub\">使用不同的哈希算法比较校验和、计算哈希值或从文件创建十六进制字符串。</string>\n    <string name=\"pick_file_to_checksum\">选择文件，根据所选算法来计算其校验和</string>\n    <string name=\"match_sub\">校验和相等，可能是安全的</string>\n    <string name=\"algorithms\">算法</string>\n    <string name=\"checksum_tools\">校验和工具</string>\n    <string name=\"mesh_gradients\">网格渐变</string>\n    <string name=\"collection_mesh_gradients_sub\">查看网格渐变在线收藏</string>\n    <string name=\"import_font\">导入字体（TTF/OTF）</string>\n    <string name=\"imported_fonts\">已导入的字体</string>\n    <string name=\"wrong_font\">只有TTF和OTF字体可以被导入</string>\n    <string name=\"export_fonts\">导出字体</string>\n    <string name=\"filename_is_not_set\">未设置文件名</string>\n    <string name=\"error_while_saving\">尝试保存时出错，请尝试更改输出文件夹</string>\n    <string name=\"none\">无</string>\n    <string name=\"custom_pages\">自定义页面</string>\n    <string name=\"tool_exit_confirmation\">工具退出确认</string>\n    <string name=\"tool_exit_confirmation_sub\">如果在使用特定工具时存在未保存的更改，而您尝试关闭该工具，系统将弹出确认对话框</string>\n    <string name=\"pages_selection\">页面选择</string>\n    <string name=\"edit_exif_screen\">编辑EXIF</string>\n    <string name=\"edit_exif_screen_sub\">无需重新压缩即可更改单张图片的元数据</string>\n    <string name=\"edit_exif_tag\">点击编辑可用标签</string>\n    <string name=\"change_sticker\">更改贴纸</string>\n    <string name=\"pick_files_to_checksum\">选择文件以根据所选算法计算其校验和</string>\n    <string name=\"batch_compare\">批量比较</string>\n    <string name=\"fit_width\">适应宽度</string>\n    <string name=\"fit_height\">适应高度</string>\n    <string name=\"pick_files\">选取文件</string>\n    <string name=\"pick_directory\">选取目录</string>\n    <string name=\"head_length_scale\">头部长度缩放</string>\n    <string name=\"format_pattern\">格式化模式</string>\n    <string name=\"padding\">填充</string>\n    <string name=\"stamp\">印章</string>\n    <string name=\"timestamp\">时间戳</string>\n    <string name=\"vertical_pivot_line\">垂直枢轴线</string>\n    <string name=\"horizontal_pivot_line\">水平枢轴线</string>\n    <string name=\"inverse_selection\">反向选择</string>\n    <string name=\"inverse_vertical_selection_sub\">将保留垂直切割部分，而不是合并切割区域周围的部分</string>\n    <string name=\"inverse_horizontal_selection_sub\">将保留水平切割部分，而不是合并切割区域周围的部分。</string>\n    <string name=\"image_cutting\">图片裁剪</string>\n    <string name=\"image_cutting_sub\">裁剪图片部分，并通过垂直线或水平线合并左侧部分（可反向操作）</string>\n    <string name=\"mesh_gradients_sub\">自定义网格渐变的节点数量和分辨率</string>\n    <string name=\"grid_size\">网格大小</string>\n    <string name=\"collection_mesh_gradients\">网格渐变集合</string>\n    <string name=\"gradient_maker_type_image_mesh\">网格渐变叠加</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">在给定图片的顶部合成网格渐变</string>\n    <string name=\"points_customization\">自定义点</string>\n    <string name=\"resolution_x\">X 轴分辨率</string>\n    <string name=\"resolution_y\">Y 轴分辨率</string>\n    <string name=\"resolution\">分辨率</string>\n    <string name=\"pixel_by_pixel\">逐个像素</string>\n    <string name=\"highlight_color\">突出显示颜色</string>\n    <string name=\"pixel_comparison_type\">像素比较类型</string>\n    <string name=\"scan_barcode\">扫描条形码</string>\n    <string name=\"enforce_bw\">强制使用黑白色</string>\n    <string name=\"enforce_bw_sub\">条形码图片将完全为黑白色，不会因应用程序的主题而带有颜色</string>\n    <string name=\"height_ratio\">高度比</string>\n    <string name=\"barcode_type\">条形码类型</string>\n    <string name=\"barcodes_sub\">扫描任何条形码（二维码、欧洲商品编码、阿兹特克码等）并获取其内容，或者粘贴你的文本以生成新的条形码</string>\n    <string name=\"generated_barcode_will_be_here\">生成的条形码将显示在此处</string>\n    <string name=\"no_barcode_found\">未找到条形码</string>\n    <string name=\"audio_cover_extractor_sub\">从音频文件中提取专辑封面图片，支持大多数常见的音频格式</string>\n    <string name=\"audio_cover_extractor\">音频封面</string>\n    <string name=\"pick_audio_to_start\">选择音频以开始</string>\n    <string name=\"pick_audio\">选择音频</string>\n    <string name=\"no_covers_found\">未找到专辑封面</string>\n    <string name=\"send_logs\">发送日志</string>\n    <string name=\"send_logs_sub\">点击分享应用程序日志文件，这可以帮助我发现问题并解决问题</string>\n    <string name=\"crash_title\">哎呀……出错了</string>\n    <string name=\"crash_subtitle\">你可以使用下面的选项与我联系，我会尽力找到解决方案。\\n（别忘了附上日志文件）</string>\n    <string name=\"ocr_write_to_file\">写入文件</string>\n    <string name=\"ocr_write_to_metadata\">写入元数据</string>\n    <string name=\"ocr_write_to_metadata_sub\">从每张图片中提取文本，并将其放置在相应图片的EXIF信息中。</string>\n    <string name=\"ocr_write_to_file_sub\">从一批图片中提取文本，并将其存储在一个文本文件中</string>\n    <string name=\"invisible_mode\">隐写模式</string>\n    <string name=\"invisible_mode_sub\">使用隐写术在你的图片字节内创建肉眼不可见的水印</string>\n    <string name=\"use_lsb\">使用LSB</string>\n    <string name=\"use_lsb_sub\">将使用最低有效位（LSB）隐写术方法，否则将使用频域（FD）方法</string>\n    <string name=\"auto_remove_red_eyes\">自动去除红眼</string>\n    <string name=\"password\">密码</string>\n    <string name=\"unlock\">解锁</string>\n    <string name=\"pdf_is_protected\">PDF已受保护</string>\n    <string name=\"sort_by_size\">大小</string>\n    <string name=\"sort_by_size_reversed\">大小（反向）</string>\n    <string name=\"sort_by_mime_type\">MIME 类型</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME 类型（反向）</string>\n    <string name=\"sort_by_date_added\">添加日期</string>\n    <string name=\"sort_by_date_added_reversed\">添加日期（反向）</string>\n    <string name=\"sort_by_extension\">扩展名</string>\n    <string name=\"operation_almost_complete\">操作基本完成。现在取消需要重新启动</string>\n    <string name=\"sort_by_extension_reversed\">扩展名这（反向）</string>\n    <string name=\"sort_by_date_modified\">修改日期</string>\n    <string name=\"sort_by_date_modified_reversed\">修改日期（反向）</string>\n    <string name=\"left_to_right\">从左到右</string>\n    <string name=\"right_to_left\">从右到左</string>\n    <string name=\"top_to_bottom\">从上到下</string>\n    <string name=\"bottom_to_top\">从下到上</string>\n    <string name=\"liquid_glass\">液态玻璃</string>\n    <string name=\"liquid_glass_sub\">一个基于近期发布的iOS 26及其液态玻璃设计系统的开关</string>\n    <string name=\"paste_link\">粘贴链接</string>\n    <string name=\"pick_image_or_base64\">选取图片或粘贴/导入下面的Base64数据</string>\n    <string name=\"type_image_link\">输入图片链接以开始</string>\n    <string name=\"kaleidoscope\">万花筒</string>\n    <string name=\"secondary_angle\">辅助角</string>\n    <string name=\"sides\">边</string>\n    <string name=\"channel_mix\">通道混合</string>\n    <string name=\"blue_green\">蓝绿色</string>\n    <string name=\"red_blue\">红蓝色</string>\n    <string name=\"green_red\">绿红色</string>\n    <string name=\"magenta\">品红色</string>\n    <string name=\"into_red\">融入红色</string>\n    <string name=\"into_green\">融入绿色</string>\n    <string name=\"into_blue\">融入蓝色</string>\n    <string name=\"cyan\">青色</string>\n    <string name=\"yellow\">黄色</string>\n    <string name=\"color_halftone\">彩色半色调</string>\n    <string name=\"contour\">轮廓</string>\n    <string name=\"levels\">等级</string>\n    <string name=\"offset\">偏移</string>\n    <string name=\"voronoi_crystallize\">沃罗诺伊结晶化</string>\n    <string name=\"shape\">形状</string>\n    <string name=\"stretch\">拉伸</string>\n    <string name=\"randomness\">随机性</string>\n    <string name=\"despeckle\">去斑点</string>\n    <string name=\"diffuse\">扩散</string>\n    <string name=\"dog\">高斯差分</string>\n    <string name=\"second_radius\">第二半径</string>\n    <string name=\"equalize\">均衡化</string>\n    <string name=\"glow\">发光</string>\n    <string name=\"whirl_and_pinch\">旋转与挤压</string>\n    <string name=\"pointillize\">点阵化</string>\n    <string name=\"border_color\">边框颜色</string>\n    <string name=\"polar_coordinates\">极坐标</string>\n    <string name=\"rect_to_polar\">直角坐标转极坐标</string>\n    <string name=\"polar_to_rect\">极坐标转直角坐标</string>\n    <string name=\"invert_in_circle\">圆形内反相</string>\n    <string name=\"reduce_noise\">减少噪点</string>\n    <string name=\"simple_solarize\">简易曝光过度</string>\n    <string name=\"weave\">交织纹理</string>\n    <string name=\"x_gap\">X 轴间距</string>\n    <string name=\"y_gap\">Y 轴间距</string>\n    <string name=\"x_width\">X 轴宽度</string>\n    <string name=\"y_wdth\">Y 轴宽度</string>\n    <string name=\"twirl\">漩涡效果</string>\n    <string name=\"rubber_stmp\">橡皮图章</string>\n    <string name=\"smear\">涂抹</string>\n    <string name=\"density\">密度</string>\n    <string name=\"mix\">混合</string>\n    <string name=\"sphere_lensh_distortion\">球面镜头畸变</string>\n    <string name=\"refraction_index\">折射率</string>\n    <string name=\"arc\">弧线</string>\n    <string name=\"spread_angle\">扩散角度</string>\n    <string name=\"rays\">光束</string>\n    <string name=\"gradient\">渐变</string>\n    <string name=\"sparkle\">闪烁</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"moire\">摩尔纹</string>\n    <string name=\"autumn\">秋色</string>\n    <string name=\"bone\">骨色</string>\n    <string name=\"jet\">伪彩色</string>\n    <string name=\"winter\">冬色</string>\n    <string name=\"ocean\">海色</string>\n    <string name=\"summer\">夏色</string>\n    <string name=\"spring\">春色</string>\n    <string name=\"cool_variant\">冷色变体</string>\n    <string name=\"pink\">粉红色</string>\n    <string name=\"hot\">热色</string>\n    <string name=\"magma\">熔岩</string>\n    <string name=\"inferno\">炼狱</string>\n    <string name=\"plasma\">等离子</string>\n    <string name=\"viridis\">翠绿</string>\n    <string name=\"turbo\">涡轮</string>\n    <string name=\"twilight\">暮光</string>\n    <string name=\"twilight_shifted\">暮光（偏移）</string>\n    <string name=\"auto_perspective\">自动透视校正</string>\n    <string name=\"deskew\">自动扶正</string>\n    <string name=\"allow_crop\">允许裁剪</string>\n    <string name=\"crop_or_perspective\">裁剪或透视校正</string>\n    <string name=\"absolute\">绝对</string>\n    <string name=\"deep_green\">深绿</string>\n    <string name=\"lens_correction\">镜头校正</string>\n    <string name=\"target_lens_profile\">目标镜头配置文件（JSON 格式）</string>\n    <string name=\"download_ready_lens_profiles\">下载预设镜头配置文件</string>\n    <string name=\"part_percents\">区域百分比</string>\n    <string name=\"hsv\">HSV</string>\n    <string name=\"cividis\">Cividis</string>\n    <string name=\"parula\">Parula</string>\n    <string name=\"disable_rotation\">禁用旋转</string>\n    <string name=\"disable_rotation_sub\">防止用双指手势旋转图片</string>\n    <string name=\"enable_snapping_to_borders\">启用贴靠到边缘</string>\n    <string name=\"enable_snapping_to_borders_sub\">移动或缩放后，图像将自动贴靠以填满帧边缘</string>\n    <string name=\"export_as_json\">导出为JSON格式</string>\n    <string name=\"export_as_json_sub\">将包含调色板数据的字符串以JSON格式表示并复制</string>\n    <string name=\"seam_carving\">内容感知缩放</string>\n    <string name=\"home_screen\">主屏幕</string>\n    <string name=\"lock_screen\">锁屏</string>\n    <string name=\"built_in\">内置</string>\n    <string name=\"wallpapers_export\">壁纸导出</string>\n    <string name=\"refresh\">刷新</string>\n    <string name=\"wallpapers_export_sub\">获取当前的主屏幕、锁屏及内置壁纸</string>\n    <string name=\"allow_access_to_all_files_for_wp\">允许访问所有文件，此操作是获取壁纸所必需的</string>\n    <string name=\"allow_read_media_images_for_wp\">仅管理外部存储权限是不够的，您需要允许访问您的图片，请务必选择 “全部允许”</string>\n    <string name=\"add_preset_to_filename\">将预设添加到文件名中</string>\n    <string name=\"add_preset_to_filename_sub\">将带有选定预设的后缀添加到图片文件名中</string>\n    <string name=\"add_image_scale_mode_to_filename\">将图像缩放模式添加到文件名中</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">将带有选定图像缩放模式的后缀添加到图片文件名中</string>\n    <string name=\"ascii_art\">ASCII艺术</string>\n    <string name=\"ascii_art_sub\">将图片转换为外观与原图相似的ASCII文本</string>\n    <string name=\"params\">参数</string>\n    <string name=\"invert_colors_ascii_sub\">对图像应用负片滤镜，以在某些情况下获得更好的效果</string>\n    <string name=\"processing_screenshot\">处理截图</string>\n    <string name=\"screenshot_not_captured_try_again\">截图未捕获，请再试一次</string>\n    <string name=\"skipped_saving\">跳过保存</string>\n    <string name=\"skipped_saving_multiple\">%1$s 个文件已跳过</string>\n    <string name=\"allow_skip_if_larger\">若文件过大，允许跳过</string>\n    <string name=\"allow_skip_if_larger_sub\">某些工具在生成的文件大小超过原文件时，将被允许跳过图像保存步骤</string>\n    <string name=\"qr_type_plain\">文本</string>\n    <string name=\"qr_type_sms\">短信</string>\n    <string name=\"qr_type_phone\">电话</string>\n    <string name=\"qr_type_geo_point\">位置</string>\n    <string name=\"qr_type_email\">电子邮箱</string>\n    <string name=\"qr_type_contact_info\">联系人</string>\n    <string name=\"qr_type_wifi\">Wi-Fi</string>\n    <string name=\"qr_type_calendar_event\">日历事件</string>\n    <string name=\"not_specified\">N/A</string>\n    <string name=\"qr_type_url\">URL</string>\n    <string name=\"open_network\">开放网络</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">手机</string>\n    <string name=\"message\">信息</string>\n    <string name=\"address\">地址</string>\n    <string name=\"subject\">主题</string>\n    <string name=\"body\">正文</string>\n    <string name=\"name\">名称</string>\n    <string name=\"organization\">组织</string>\n    <string name=\"title\">职位</string>\n    <string name=\"phones\">手机</string>\n    <string name=\"emails\">电子邮箱</string>\n    <string name=\"urls\">URLs</string>\n    <string name=\"addresses\">地址</string>\n    <string name=\"summary\">摘要</string>\n    <string name=\"description\">描述</string>\n    <string name=\"location\">位置</string>\n    <string name=\"organizer\">组织者</string>\n    <string name=\"start_date\">开始日期</string>\n    <string name=\"end_date\">结束日期</string>\n    <string name=\"status\">状态</string>\n    <string name=\"create_barcode\">创建条形码</string>\n    <string name=\"edit_barcode\">编辑条形码</string>\n    <string name=\"security\">安全</string>\n    <string name=\"wifi_configuration\">Wi-Fi配置</string>\n    <string name=\"latitude\">纬度</string>\n    <string name=\"longitude\">经度</string>\n    <string name=\"pronunciation\">发音</string>\n    <string name=\"add_phone\">添加手机</string>\n    <string name=\"add_email\">添加电子邮箱</string>\n    <string name=\"add_address\">添加地址</string>\n    <string name=\"website\">网站</string>\n    <string name=\"add_website\">添加网站</string>\n    <string name=\"formatted_name\">格式化名称</string>\n    <string name=\"pick_contact\">选择联系人</string>\n    <string name=\"grant_contact_permission\">在设置中授予联系人权限，以使用选定的联系人自动填充</string>\n    <string name=\"contact_info\">联系人信息</string>\n    <string name=\"first_name\">姓氏</string>\n    <string name=\"middle_name\">中间名</string>\n    <string name=\"last_name\">名字</string>\n    <string name=\"dark_color\">深色</string>\n    <string name=\"light_color\">浅色</string>\n    <string name=\"hyper_os\">Hyper OS</string>\n    <string name=\"hyper_os_sub\">小米澎湃OS风格</string>\n    <string name=\"mask_pattern\">掩码图案</string>\n    <string name=\"qr_code_top_image\">此图像将用于放置在条形码上方</string>\n    <string name=\"code_customization\">代码定制</string>\n    <string name=\"qr_logo_image\">此图像将用作二维码中心的logo</string>\n    <string name=\"logo\">Logo</string>\n    <string name=\"logo_padding\">Logo内边距</string>\n    <string name=\"logo_size\">Logo大小</string>\n    <string name=\"logo_corners\">Logo角部</string>\n    <string name=\"fourth_eye\">第四只眼</string>\n    <string name=\"fourth_eye_description\">通过在底端角落添加第四只眼，为二维码增加眼睛对称性</string>\n    <string name=\"pixel_shape\">像素形状</string>\n    <string name=\"frame_shape\">框形</string>\n    <string name=\"ball_shape\">球形</string>\n    <string name=\"error_correction_level\">纠错等级</string>\n    <string name=\"code_may_be_not_scannable\">此二维码可能无法扫描，请调整外观参数，确保所有设备均可识别</string>\n    <string name=\"not_scannable\">不可扫描的</string>\n    <string name=\"launcher_mode_sub\">工具将呈现为桌面应用启动器样式，以更简洁紧凑</string>\n    <string name=\"launcher_mode\">启动器模式</string>\n    <string name=\"flood_fill_sub\">用所选画笔和样式填充指定区域</string>\n    <string name=\"flood_fill\">油漆桶填充</string>\n    <string name=\"spray\">喷雾</string>\n    <string name=\"spray_sub\">绘制涂鸦风格路径</string>\n    <string name=\"square_particles\">方形粒子</string>\n    <string name=\"square_particles_sub\">喷雾粒子将呈现方形，而不是圆形</string>\n    <string name=\"palette_tools\">调色板工具</string>\n    <string name=\"palette_tools_sub\">从图片中生成基础配色方案或Material You动态配色方案，也可在不同配色格式间导入或导出配色</string>\n    <string name=\"edit_palette\">编辑调色板</string>\n    <string name=\"edit_palette_sub\">跨多种格式导入/导出调色板</string>\n    <string name=\"color_name\">颜色名称</string>\n    <string name=\"palette_name\">调色板名称</string>\n    <string name=\"palette_format\">调色板格式</string>\n    <string name=\"export_palette_sub\">将生成的调色板导出为多种格式</string>\n    <string name=\"add_color_palette_sub\">向当前调色板添加新颜色</string>\n    <string name=\"palette_name_not_supported\">%1$s 格式不支持提供调色板名称</string>\n    <string name=\"wallpapers_export_not_avaialbe\">由于应用商店政策限制，当前版本无法包含此功能。如需使用该功能，请从其他渠道下载ImageToolbox。你可在下方的GitHub上获取可用版本。</string>\n    <string name=\"open_github_page\">打开GitHub页面</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s 颜色</item>\n    </plurals>\n    <string name=\"overwrite_files_sub_short\">原始文件将被新文件替换，而不是保存到所选文件夹中</string>\n    <string name=\"hidden_watermark_text_detected\">检测到隐藏水印文本</string>\n    <string name=\"hidden_watermark_image_detected\">检测到隐藏水印图像</string>\n    <string name=\"this_image_was_hidden\">该图像已被隐藏</string>\n    <string name=\"generative_inpaint\">生成式修复</string>\n    <string name=\"generative_inpaint_sub\">可通过AI模型移除图像中的物体，无需依赖OpenCV。使用此功能前，应用将从GitHub下载所需模型（约200MB）</string>\n    <string name=\"generative_inpaint_ready_sub\">可通过人工智能模型移除图像中的物体，无需依赖OpenCV，此操作可能耗时较久</string>\n    <string name=\"error_level_analysis\">错误等级分析</string>\n    <string name=\"luminance_gradient\">亮度梯度</string>\n    <string name=\"average_distance\">平均距离</string>\n    <string name=\"copy_move_detection\">复制移动检测</string>\n    <string name=\"retain\">保留</string>\n    <string name=\"coefficent\">系数</string>\n    <string name=\"clipboard_data_is_too_large\">剪贴板数据过大</string>\n    <string name=\"data_is_too_large_to_copy\">数据过大，无法复制</string>\n    <string name=\"simple_weave_pixelization\">简单编织像素化</string>\n    <string name=\"staggered_pixelization\">交错像素化</string>\n    <string name=\"cross_pixelization\">交叉像素化</string>\n    <string name=\"micro_macro_pixelization\">微观宏观像素化</string>\n    <string name=\"orbital_pixelization\">轨道像素化</string>\n    <string name=\"vortex_pixelization\">涡旋像素化</string>\n    <string name=\"pulse_grid_pixelization\">脉冲网格像素化</string>\n    <string name=\"nucleus_pixelization\">核心像素化</string>\n    <string name=\"radial_weave_pixelization\">径向编织像素化</string>\n    <string name=\"cannot_open_uri\">无法打开URI“%1$s”</string>\n    <string name=\"snowfall_mode\">降雪模式</string>\n    <string name=\"enabled\">启用</string>\n    <string name=\"border_frame\">边框框架</string>\n    <string name=\"glitch_variant\">故障变体</string>\n    <string name=\"channel_shift\">通道偏移</string>\n    <string name=\"max_offset\">最大偏移量</string>\n    <string name=\"block_glitch\">方块故障</string>\n    <string name=\"block_size\">方块大小</string>\n    <string name=\"crt_curvature\">CRT曲率</string>\n    <string name=\"curvature\">曲率</string>\n    <string name=\"chroma\">色度</string>\n    <string name=\"pixel_melt\">像素融解</string>\n    <string name=\"max_drop\">最大落差</string>\n    <string name=\"vhs\">VHS</string>\n    <string name=\"ai_tools\">AI工具</string>\n    <string name=\"ai_tools_sub\">通过AI模型处理图像的各类工具，例如伪影去除或降噪</string>\n    <string name=\"model_anime_undeint\">压缩，锯齿线</string>\n    <string name=\"model_broadcast\">卡通，广播压缩</string>\n    <string name=\"model_rgb_max_denoise_fp16\">通用压缩，通用噪声</string>\n    <string name=\"model_wb_denoise\">无色卡通噪点</string>\n    <string name=\"model_span_anime_pretrain\">快速、通用压缩、通用噪声、动画/漫画/动漫</string>\n    <string name=\"model_book_scan\">书籍扫描</string>\n    <string name=\"model_overexposure\">曝光校正</string>\n    <string name=\"model_fbcnn_color_fp16\">擅长通用压缩、彩色图像</string>\n    <string name=\"model_fbcnn_gray_fp16\">擅长通用压缩、灰度图像</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">通用压缩、灰度图像、增强型</string>\n    <string name=\"model_scunet_color_gan_fp16\">通用噪声、彩色图像</string>\n    <string name=\"model_scunet_color_psnr_fp16\">通用噪声、彩色图像、细节优化</string>\n    <string name=\"model_scunet_gray_15_fp16\">通用噪声、灰度图像</string>\n    <string name=\"model_scunet_gray_25_fp16\">通用噪声、灰度图像、增强型</string>\n    <string name=\"model_scunet_gray_50_fp16\">通用噪声、灰度图像、强效型</string>\n    <string name=\"model_jpeg_destroyer\">通用压缩</string>\n    <string name=\"model_jaywreck\">通用压缩</string>\n    <string name=\"model_h264\">纹理化、H.264压缩</string>\n    <string name=\"model_vhs\">VHS压缩</string>\n    <string name=\"model_cinepak\">非标准压缩（Cinepak、MSVideo1、RoQ）</string>\n    <string name=\"model_debink_v4\">宾克压缩，几何形状更好</string>\n    <string name=\"model_debink_v5\">宾克压缩，增强型</string>\n    <string name=\"model_debink_v6\">宾克压缩，柔和，保留细节</string>\n    <string name=\"model_antialias\">消除阶梯效应，实现平滑处理</string>\n    <string name=\"model_kdm_scans\">扫描艺术品/画作，轻度压缩，摩尔纹</string>\n    <string name=\"model_bandage\">色带失真</string>\n    <string name=\"model_halftone\">慢速、去除半色调网点</string>\n    <string name=\"model_colorizer\">灰度/黑白图像通用着色器，使用DDColor可获得更佳效果</string>\n    <string name=\"model_deedge\">边缘去除–</string>\n    <string name=\"model_desharpen\">去除过度锐化</string>\n    <string name=\"model_dither\">慢速、抖动处理</string>\n    <string name=\"model_gainres\">抗锯齿、通用伪影、计算机生成图像</string>\n    <string name=\"merging\">合并</string>\n    <string name=\"model_kdm003_scans\">KDM003扫描处理中</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">轻量级图像增强模型</string>\n    <string name=\"model_spongecolor_lite\">简易快速着色，适用于卡通图像，效果欠佳</string>\n    <string name=\"model_bcgone_detailed_v2\">压缩伪影去除</string>\n    <string name=\"model_bcgone_smooth\">压缩伪影消除</string>\n    <string name=\"model_bandage_smooth\">平滑效果的伪影消除</string>\n    <string name=\"model_bendel_halftone\">半色调图案处理</string>\n    <string name=\"model_dither_deleter_v3_smooth\">抖动图案去除V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG伪影去除V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264纹理增强</string>\n    <string name=\"model_vhs_sharpen\">VHS画质锐化与增强</string>\n    <string name=\"chunk_size\">块大小</string>\n    <string name=\"overlap_size\">重叠大小</string>\n    <string name=\"note_chunk_info\">超过 %1$s 像素的图像将被切片并分块处理，重叠区域会进行融合以避免出现明显接缝。</string>\n    <string name=\"large_chunk_warning\">大尺寸图像会导致低端设备运行不稳定</string>\n    <string name=\"select_one_to_start\">选择一个以开始</string>\n    <string name=\"delete_model_sub\">你是否要删除 %1$s 模型？删除后你需要重新下载该模型</string>\n    <string name=\"confirm\">确认</string>\n    <string name=\"models\">模型</string>\n    <string name=\"downloaded_models\">已下载的模型</string>\n    <string name=\"available_models\">可用模型</string>\n    <string name=\"preparing\">准备中</string>\n    <string name=\"active_model\">启用模型</string>\n    <string name=\"failed_to_open_session\">会话打开失败</string>\n    <string name=\"only_onnx_models\">仅支持导入.onnx/.ort格式的模型</string>\n    <string name=\"import_model\">导入模型</string>\n    <string name=\"import_model_sub\">导入自定义ONNX模型以进一步使用，仅支持ONNX/ORT格式的模型，兼容几乎所有类ESRGAN变体</string>\n    <string name=\"imported_models\">已导入的模型</string>\n    <string name=\"model_scunet_color_15_fp16\">通用噪点，彩色图像</string>\n    <string name=\"model_scunet_color_25_fp16\">通用噪点，彩色图像，强度更高</string>\n    <string name=\"model_scunet_color_50_fp16\">一般噪声，彩色图像，最强</string>\n    <string name=\"model_artifacts_dithering_alsa\">减少抖动伪影和色彩带状，提升平滑渐变和纯色区域的显示效果。</string>\n    <string name=\"model_nmkd_brighten_redux\">增强图像亮度和对比度，同时保持自然色彩平衡。</string>\n    <string name=\"model_nmkd_brighten\">使暗部图像变亮，同时保留细节并避免过度曝光。</string>\n    <string name=\"model_nmkd_detoon\">去除过度的色彩调色，恢复更中性和自然的色彩平衡。</string>\n    <string name=\"model_noise_toner_poisson_detailed\">应用基于泊松的噪声调色，强调保留精细细节和纹理。</string>\n    <string name=\"model_noise_toner_poisson_soft\">应用柔和的泊松噪声调色，使视觉效果更平滑且不那么激进。</string>\n    <string name=\"model_noise_toner_uniform_detailed\">均匀噪声调色专注于细节保留和图像清晰度。</string>\n    <string name=\"model_noise_toner_uniform_soft\">温和的均匀噪声调色，使纹理更细腻，外观更平滑。</string>\n    <string name=\"model_repainter\">通过重新绘制瑕疵并改善图像一致性来修复损坏或不均匀的区域。</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">轻量级去色带模型，以最小的性能成本去除色带。</string>\n    <string name=\"model_jpeg_0_20\">优化具有非常高的压缩伪影（0-20%质量）的图像，以提高清晰度。</string>\n    <string name=\"model_jpeg_20_40\">优化具有较高压缩伪影（20-40%质量）的图像，恢复细节并减少噪声。</string>\n    <string name=\"model_jpeg_40_60\">优化中等压缩（40-60%质量）的图像，平衡清晰度和平滑度。</string>\n    <string name=\"model_jpeg_60_80\">优化轻度压缩（60-80%质量）的图像，以增强细微细节和纹理。</string>\n    <string name=\"model_jpeg_80_100\">优化接近无损图像（质量 80-100%），同时保留自然外观和细节。</string>\n    <string name=\"model_deblr\">略微减少图像模糊，提高清晰度而不引入伪影。</string>\n    <string name=\"processing_channel\">长时间运行的操作</string>\n    <string name=\"processing_image\">处理图像</string>\n    <string name=\"processing\">处理中</string>\n    <string name=\"model_artifacts_jpg_0_20\">去除在极低质量图像（0-20%）中存在的严重JPEG压缩伪影。</string>\n    <string name=\"model_artifacts_jpg_20_40\">减少高度压缩图像（20-40%）中的强烈JPEG伪影。</string>\n    <string name=\"model_artifacts_jpg_40_60\">清除中等程度的JPEG伪影，同时保留图像细节（40-60%）。</string>\n    <string name=\"model_artifacts_jpg_60_80\">优化60-80%质量图像中的轻微JPEG伪影。</string>\n    <string name=\"model_artifacts_jpg_80_100\">略微减少近乎无损图像（80-100%）中的轻微JPEG伪影。</string>\n    <string name=\"model_redetail_v2\">增强精细细节和纹理，提升感知清晰度，同时避免严重的伪影。</string>\n    <string name=\"processing_finished\">处理完成</string>\n    <string name=\"processing_failed\">处理失败</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">增强皮肤纹理和细节，同时保持自然外观，优化速度。</string>\n    <string name=\"model_sbdv_dejpeg\">去除JPEG压缩伪影并恢复压缩照片的图像质量。</string>\n    <string name=\"model_iso_denoise_v1\">降低在低光条件下拍摄的照片中的ISO噪点，同时保留细节。</string>\n    <string name=\"model_dejumbo\">修正曝光过度或“巨大”的高光，并恢复更好的色调平衡。</string>\n    <string name=\"model_ddcolor_tiny\">轻量级且快速的着色模型，为灰度图像添加自然色彩。</string>\n    <string name=\"type_dejpeg\">DeJPEG</string>\n    <string name=\"type_denoise\">降噪</string>\n    <string name=\"type_colorize\">着色</string>\n    <string name=\"type_artifacts\">伪影</string>\n    <string name=\"type_enhance\">增强</string>\n    <string name=\"type_anime\">动漫</string>\n    <string name=\"type_scans\">扫描</string>\n    <string name=\"type_upscale\">放大</string>\n    <string name=\"model_realesrgan_x4v3\">适用于大多数图像的 X4 放大器；体积小巧的模型，使用更少的 GPU 和更短的时间，具有适度的去模糊和去噪功能。</string>\n    <string name=\"model_realesrgan_x2plus\">适用于大多数图像的 X2 放大器，保留纹理和自然细节。</string>\n    <string name=\"model_realesrgan_x4plus\">适用于大多数图像的 X4 放大器，有着增强的纹理和逼真的效果。</string>\n    <string name=\"model_realesrgan_x4plus_anime\">为动漫图像优化的 X4 放大器；具有6个RRDB块，使线条更清晰，细节更丰富。</string>\n    <string name=\"model_realesrnet_x4plus\">带有 MSE 损失的 X4 放大器，为普通图像生成更平滑的结果并减少伪影。</string>\n    <string name=\"type_removebg\">抠图</string>\n    <string name=\"horizontal_border_thickness\">水平边框厚度</string>\n    <string name=\"vertical_border_thickness\">垂直边框厚度</string>\n    <string name=\"model_rmbg_1_4\">轻量级模型，可快速去除背景。平衡速度与效果。适用于肖像、物体和场景­。大多数图像皆可使用。</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite；更快且更小，在使用更少显存的同时保留细节。</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 模型，适用于一般图像；强调锐度和清晰度。</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">针对动漫图像进行了优化的 X4 放大器；4B32F 变体，细节更清晰，线条流畅。</string>\n    <string name=\"current_model_not_chunkable\">当前模型不支持分块，图像将以原始尺寸处理，这可能会导致高内存消耗并且在低性能设备上产生问题</string>\n    <string name=\"chunking_disabled\">禁用分块，图像将以原始尺寸进行处理，这可能会导致高内存消耗并在低性能设备上产生问题，但可能会给出更好的推理结果</string>\n    <string name=\"chunking\">分块</string>\n    <string name=\"model_u2net\">高精度抠图用图像分割模型</string>\n    <string name=\"model_u2netp\">U2Net 的轻量级版本，使用更少内存并更快地去除背景。</string>\n    <string name=\"model_ddcolor\">完整的 DDColor 模型可以很高的质量为大多数图像上色，且伪影最少。它是所有着色模型的最佳选择。</string>\n    <string name=\"model_ddcolor_artistic\">DDColor 训练有素的私人艺术数据集；产生多样化和艺术化的色彩结果，减少不切实际的色彩伪影。</string>\n    <string name=\"model_birefnet\">基于 Swin Transformer 的轻量级 BiRefNet 模型，可实现准确的抠图效果。</string>\n    <string name=\"model_inspyrenet\">高质量的抠图效果，具有锐利的边缘和出色的细节保留能力，尤其对于复杂的物体和棘手的背景。</string>\n    <string name=\"model_isnet\">抠图模型，可生成平滑的边缘与精确的蒙版，适用于一般物体并能适度保留细节。</string>\n    <string name=\"model_already_downloaded\">模型已下载</string>\n    <string name=\"model_successfully_imported\">模型导入成功</string>\n    <string name=\"type\">类型</string>\n    <string name=\"keyword\">关键词</string>\n    <string name=\"very_fast\">很快</string>\n    <string name=\"normal\">正常</string>\n    <string name=\"slow\">慢</string>\n    <string name=\"very_slow\">很慢</string>\n    <string name=\"compute_percents\">计算百分比</string>\n    <string name=\"minimum_value_is\">最小值为 %1$s</string>\n    <string name=\"warp_sub\">用手指绘图扭曲图像</string>\n    <string name=\"warp\">扭曲</string>\n    <string name=\"hardness\">硬度</string>\n    <string name=\"warp_mode\">扭曲模式</string>\n    <string name=\"warp_mode_move\">移动</string>\n    <string name=\"warp_mode_grow\">扩大</string>\n    <string name=\"warp_mode_shrink\">收缩</string>\n    <string name=\"warp_mode_swirl_cw\">顺时针漩涡</string>\n    <string name=\"warp_mode_swirl_ccw\">逆时针漩涡</string>\n    <string name=\"fade_strength\">褪色强度</string>\n    <string name=\"top_drop\">顶部掉落</string>\n    <string name=\"bottom_drop\">底部掉落</string>\n    <string name=\"start_drop\">开始掉落</string>\n    <string name=\"end_drop\">结束掉落</string>\n    <string name=\"downloading\">下载中</string>\n    <string name=\"smooth_shapes\">光滑的形状</string>\n    <string name=\"smooth_shapes_sub\">使用超椭圆代替标准圆角矩形以获得更平滑、更自然的形状</string>\n    <string name=\"shape_type\">形状类型</string>\n    <string name=\"cut\">切角</string>\n    <string name=\"rounded\">圆角</string>\n    <string name=\"smooth\">光滑</string>\n    <string name=\"cut_shapes_sub\">边缘锐利，无圆角</string>\n    <string name=\"rounded_shapes_sub\">经典圆角</string>\n    <string name=\"shapes_type\">形状类型</string>\n    <string name=\"corners_size\">边角大小</string>\n    <string name=\"squircle\">方圆形</string>\n    <string name=\"squircle_shapes_sub\">雅致的圆角UI元素</string>\n    <string name=\"filename_format\">文件名格式</string>\n    <string name=\"prefix_pattern_description\">自定义文本放置在文件名的开头，非常适合项目名称、品牌或个人标签。</string>\n    <string name=\"original_filename_pattern_description\">使用不带扩展名的原始文件名，帮助您保持源标识完整。</string>\n    <string name=\"width_pattern_description\">图像宽度（以像素为单位），可用于跟踪分辨率变化或缩放结果。</string>\n    <string name=\"height_pattern_description\">图像高度（以像素为单位），在处理宽高比或导出时很有帮助。</string>\n    <string name=\"random_numbers_pattern_description\">生成随机数字以保证唯一的文件名；添加更多数字以提高安全性，防止重复。</string>\n    <string name=\"sequence_number_pattern_description\">用于批量导出的自动递增计数器，非常适合在一个会话中保存多个图像时。</string>\n    <string name=\"preset_info_pattern_description\">将应用的预设名称插入文件名中，以便您可以轻松记住图像的处理方式。</string>\n    <string name=\"scale_mode_pattern_description\">显示处理过程中使用的图像缩放模式，帮助区分调整大小、裁剪或拟合的图像。</string>\n    <string name=\"suffix_pattern_description\">放置在文件名末尾的自定义文本，对于 _v2、_edited 或 _final 等版本控制很有用。</string>\n    <string name=\"extension_pattern_description\">文件扩展名（png、jpg、webp等），自动匹配实际保存格式。</string>\n    <string name=\"formatted_timestamp_pattern_description\">可自定义的时间戳，让您可以通过 Java 规范定义自己的格式以实现完美排序。</string>\n    <string name=\"fling_type\">滑动类型</string>\n    <string name=\"android_native\">安卓原生</string>\n    <string name=\"ios_style\">iOS风格</string>\n    <string name=\"smooth_curve\">平滑曲线</string>\n    <string name=\"quick_stop\">快速停止</string>\n    <string name=\"bouncy\">弹力</string>\n    <string name=\"floaty\">飘逸</string>\n    <string name=\"snappy\">活泼</string>\n    <string name=\"ultra_smooth\">超光滑</string>\n    <string name=\"adaptive\">自适应</string>\n    <string name=\"accessibility_aware\">无障碍意识</string>\n    <string name=\"reduced_motion\">减少运动</string>\n    <string name=\"android_native_sub\">原生 Android 滚动物理</string>\n    <string name=\"smooth_sub\">平衡、平滑的滚动，适合一般用途</string>\n    <string name=\"ios_style_sub\">更高的摩擦力，类似 iOS 的滚动行为</string>\n    <string name=\"smooth_curve_sub\">独特的样条曲线带来独特的滚动感觉</string>\n    <string name=\"quick_stop_sub\">精确滚动并快速停止</string>\n    <string name=\"bouncy_sub\">有趣、反应灵敏的弹性滚动</string>\n    <string name=\"floaty_sub\">用于内容浏览的长滑动卷轴</string>\n    <string name=\"snappy_sub\">交互式 UI 的快速、响应式滚动</string>\n    <string name=\"ultra_smooth_sub\">优质平滑滚动，动力强劲</string>\n    <string name=\"adaptive_sub\">根据投掷速度调整物理</string>\n    <string name=\"accessibility_aware_sub\">尊重系统辅助功能设置</string>\n    <string name=\"reduced_motion_sub\">满足无障碍需求的最小运动</string>\n    <string name=\"primary_lines\">主要线路</string>\n    <string name=\"primary_lines_sub\">每五行添加较粗的线</string>\n    <string name=\"fill_color\">填充颜色</string>\n    <string name=\"hidden_tools\">隐藏工具</string>\n    <string name=\"hidden_for_share\">隐藏共享工具</string>\n    <string name=\"color_library\">颜色库</string>\n    <string name=\"color_library_sub\">浏览海量颜色集合</string>\n    <string name=\"model_fatality_deblur\">锐化并消除图像模糊，同时保持自然细节，是修复失焦照片的理想选择。</string>\n    <string name=\"model_unresize_v3\">智能恢复之前调整过大小的图像，恢复丢失的细节和纹理。</string>\n    <string name=\"model_liveaction_v1_span\">针对真人内容进行了优化，减少了压缩伪影并增强了电影/电视节目帧中的精细细节。</string>\n    <string name=\"model_vhs2hd_realplksr\">将 VHS 质量的素材转换为高清，消除磁带噪音并提高分辨率，同时保留复古感。</string>\n    <string name=\"model_text2hd_v1\">专门用于文本较多的图像和屏幕截图，锐化字符并提高可读性。</string>\n    <string name=\"model_frankendata_pretrainer\">在不同数据集上进行高级升级训练，非常适合通用照片增强。</string>\n    <string name=\"model_realwebphoto_v2\">针对网络压缩照片进行了优化，消除了 JPEG 伪影并恢复自然外观。</string>\n    <string name=\"model_realwebphoto_v4\">网页照片的改进版本，具有更好的纹理保留和伪影减少。</string>\n    <string name=\"model_dat_2x\">使用双聚合变压器技术进行 2 倍升级，保持清晰度和自然细节。</string>\n    <string name=\"model_dat_3x\">使用先进的变压器架构进行 3 倍放大，非常适合中等放大需求。</string>\n    <string name=\"model_dat_4x\">通过最先进的变压器网络进行 4 倍高质量放大，在更大的尺度上保留精细细节。</string>\n    <string name=\"model_nafnet_deblurring\">消除照片中的模糊/噪点和抖动。通用但最适合照片。</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">使用 Swin2SR 转换器恢复低质量图像，并针对 BSRGAN 退化进行了优化。非常适合修复严重的压缩伪影并以 4 倍比例增强细节。</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">使用经过 BSRGAN 退化训练的 SwinIR 变压器进行 4 倍升级。使用 GAN 在照片和复杂场景中获得更清晰的纹理和更自然的细节。</string>\n    <string name=\"path\">小路</string>\n    <string name=\"merge_pdf\">合并PDF</string>\n    <string name=\"merge_pdf_sub\">将多个PDF文件合并为一个文档</string>\n    <string name=\"files_order\">文件顺序</string>\n    <string name=\"pages_short\">页数</string>\n    <string name=\"split_pdf\">分割PDF</string>\n    <string name=\"split_pdf_sub\">从PDF文档中提取特定页面</string>\n    <string name=\"rotate_pdf\">旋转PDF</string>\n    <string name=\"rotate_pdf_sub\">永久修复页面方向</string>\n    <string name=\"pages\">页数</string>\n    <string name=\"rearrange_pdf\">重新排列PDF</string>\n    <string name=\"rearrange_pdf_sub\">拖放页面以重新排序</string>\n    <string name=\"hold_drag_drop\">按住并拖动页面</string>\n    <string name=\"page_numbers\">页码</string>\n    <string name=\"page_numbers_sub\">自动为您的文档添加编号</string>\n    <string name=\"label_format\">标签格式</string>\n    <string name=\"pdf_to_text\">PDF转文本 (OCR)</string>\n    <string name=\"pdf_to_text_sub\">从PDF文档中提取纯文本</string>\n    <string name=\"watermark_pdf_sub\">叠加自定义文字，用于品牌标识或安全防护</string>\n    <string name=\"signature\">签名</string>\n    <string name=\"signature_sub\">将您的电子签名添加到任何文档中</string>\n    <string name=\"will_be_for_signature\">这将用作签名</string>\n    <string name=\"unlock_pdf\">解锁PDF</string>\n    <string name=\"unlock_pdf_sub\">从受保护的文件中删除密码</string>\n    <string name=\"protect_pdf\">保护PDF</string>\n    <string name=\"protect_pdf_sub\">通过强大的加密保护您的文档</string>\n    <string name=\"success\">成功</string>\n    <string name=\"pdf_unlocked\">PDF已解锁，您可以保存或分享</string>\n    <string name=\"repair_pdf\">修复PDF</string>\n    <string name=\"repair_pdf_sub\">尝试修复损坏或无法读取的文档</string>\n    <string name=\"grayscale\">灰度</string>\n    <string name=\"grayscale_pdf_sub\">将所有文档嵌入图像转换为灰度</string>\n    <string name=\"compress_pdf\">压缩PDF</string>\n    <string name=\"compress_pdf_sub\">优化文档文件大小以方便共享</string>\n    <string name=\"repair_info\">ImageToolbox 重建内部交叉引用表并从头开始重新生成文件结构。这可以恢复对许多“无法打开”文件的访问</string>\n    <string name=\"grayscale_info\">该工具将所有文档图像转换为灰度。最适合打印和减小文件大小</string>\n    <string name=\"metadata\">元数据</string>\n    <string name=\"metadata_pdf_sub\">编辑文档属性以获得更好的隐私</string>\n    <string name=\"tags\">标签</string>\n    <string name=\"producer\">制作人</string>\n    <string name=\"author\">作者</string>\n    <string name=\"keywords\">关键词</string>\n    <string name=\"creator\">创作者</string>\n    <string name=\"privacy_deep_clean\">隐私深度清洁</string>\n    <string name=\"privacy_deep_clean_sub\">清除该文档的所有可用元数据</string>\n    <string name=\"page\">页</string>\n    <string name=\"deep_ocr\">深度OCR</string>\n    <string name=\"deep_ocr_sub\">使用 Tesseract 引擎从文档中提取文本并将其存储在一个文本文件中</string>\n    <string name=\"cant_remove_all\">无法删除所有页面</string>\n    <string name=\"remove_pages_pdf\">删除PDF页面</string>\n    <string name=\"remove_pages_pdf_sub\">从PDF文档中删除特定页面</string>\n    <string name=\"tap_to_remove\">点击删除</string>\n    <string name=\"manually\">手动</string>\n    <string name=\"crop_pdf\">裁剪PDF</string>\n    <string name=\"crop_pdf_sub\">将文档页面裁剪到任意范围</string>\n    <string name=\"flatten_pdf\">拼合PDF</string>\n    <string name=\"flatten_pdf_sub\">通过光栅化文档页面使PDF不可修改</string>\n    <string name=\"camera_failed_to_open\">无法启动相机。请检查权限并确保它未被其他应用程序使用。</string>\n    <string name=\"extract_images\">提取图像</string>\n    <string name=\"extract_images_sub\">以原始分辨率提取PDF中嵌入的图像</string>\n    <string name=\"pdf_no_embedded\">此PDF文件不包含任何嵌入图像</string>\n    <string name=\"extract_images_info\">该工具扫描每一页并恢复全质量源图像 - 非常适合保存文档中的原件</string>\n    <string name=\"draw_signature\">绘制签名</string>\n    <string name=\"pen_params\">笔参数</string>\n    <string name=\"draw_signature_sub\">使用自己的签名作为图像放置在文档上</string>\n    <string name=\"zip_pdf\">压缩PDF</string>\n    <string name=\"zip_pdf_sub\">以给定的间隔分割文档并将新文档打包到zip存档中</string>\n    <string name=\"interval\">间隔</string>\n    <string name=\"print_pdf\">打印PDF</string>\n    <string name=\"print_pdf_sub\">准备用于使用自定义页面尺寸打印的文档</string>\n    <string name=\"pages_per_sheet\">每张页数</string>\n    <string name=\"orientation\">方向</string>\n    <string name=\"page_size\">页面尺寸</string>\n    <string name=\"margin\">利润</string>\n    <string name=\"bloom\">盛开</string>\n    <string name=\"soft_knee\">软膝</string>\n    <string name=\"model_realesr_animevideo_v3x4\">针对动漫和卡通进行了优化。快速升级，改善自然色彩并减少伪影</string>\n    <string name=\"one_ui_sub\">类似三星 One UI 7 的风格</string>\n    <string name=\"calculate_hint\">在此输入基本数学符号以计算所需的值（例如（5+5）*10）</string>\n    <string name=\"math_expression\">数学表达式</string>\n    <string name=\"pick_up_to_n_collage_images\">选取最多 %1$s 张图片</string>\n    <string name=\"keep_date_time\">保留日期时间</string>\n    <string name=\"keep_date_time_sub\">始终保留与日期和时间相关的 exif 标签，独立于 keep exif 选项</string>\n    <string name=\"background_color_for_alpha_formats\">Alpha 格式的背景颜色</string>\n    <string name=\"background_color_for_alpha_formats_sub\">增加了为每种具有 Alpha 支持的图像格式设置背景颜色的功能，禁用后，此功能仅适用于非 Alpha 格式</string>\n    <string name=\"open_markup_project\">打开项目</string>\n    <string name=\"open_markup_project_sub\">继续编辑之前保存的 Image Toolbox 项目</string>\n    <string name=\"markup_project_open_failed\">无法打开 Image Toolbox 项目</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox 项目缺少项目数据</string>\n    <string name=\"markup_project_corrupted\">Image Toolbox 项目已损坏</string>\n    <string name=\"unsupported_markup_project_version\">不受支持的 Image Toolbox 项目版本：%1$d</string>\n    <string name=\"save_markup_project\">保存项目</string>\n    <string name=\"save_markup_project_sub\">将图层、背景和编辑历史记录存储在可编辑的项目文件中</string>\n    <string name=\"failed_to_open\">打开失败</string>\n    <string name=\"ocr_write_to_searchable_pdf\">写入可搜索的 PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">从图像批次中识别文本并保存带有图像和可选文本层的可搜索 PDF</string>\n    <string name=\"layer_alpha\">阿尔法层</string>\n    <string name=\"horizontal_flip\">水平翻转</string>\n    <string name=\"vertical_flip\">垂直翻转</string>\n    <string name=\"lock\">锁</string>\n    <string name=\"add_shadow\">添加阴影</string>\n    <string name=\"shadow_color\">阴影颜色</string>\n    <string name=\"text_geometry\">文本几何</string>\n    <string name=\"text_geometry_sub\">拉伸或倾斜文本以获得更清晰的风格</string>\n    <string name=\"scale_x\">规模 X</string>\n    <string name=\"skew_x\">倾斜 X</string>\n    <string name=\"remove_annotations\">删除注释</string>\n    <string name=\"remove_annotations_sub\">从 PDF 页面中删除选定的注释类型，例如链接、注释、突出显示、形状或表单字段</string>\n    <string name=\"annotation_link\">超链接</string>\n    <string name=\"annotation_file_attachment\">文件附件</string>\n    <string name=\"annotation_line\">线路</string>\n    <string name=\"annotation_popup\">弹出窗口</string>\n    <string name=\"annotation_stamp\">邮票</string>\n    <string name=\"annotation_shapes\">形状</string>\n    <string name=\"annotation_text\">文字注释</string>\n    <string name=\"annotation_text_markup\">文本标记</string>\n    <string name=\"annotation_widget\">表单字段</string>\n    <string name=\"annotation_markup\">标记</string>\n    <string name=\"annotation_unknown\">未知</string>\n    <string name=\"annotations\">注释</string>\n    <string name=\"ungroup\">取消分组</string>\n    <string name=\"add_shadow_sub\">使用可配置的颜色和偏移在图层后面添加模糊阴影</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/values-zh-rTW/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"size\">大小 %1$s</string>\n    <string name=\"loading\">載入中…</string>\n    <string name=\"no_exif\">沒有發現 EXIF 資料</string>\n    <string name=\"pick_image\">選取圖片以開始</string>\n    <string name=\"close\">關閉</string>\n    <string name=\"reset_image\">重置圖片</string>\n    <string name=\"quality\">品質</string>\n    <string name=\"height\">高度 %1$s</string>\n    <string name=\"something_went_wrong\">發生了一些錯誤</string>\n    <string name=\"edit_exif\">編輯 EXIF</string>\n    <string name=\"clear\">清除</string>\n    <string name=\"check_source_code\">原始碼</string>\n    <string name=\"color_blue\">藍色</string>\n    <string name=\"smth_went_wrong\">發生了一些錯誤：%1$s</string>\n    <string name=\"width\">寬度 %1$s</string>\n    <string name=\"pick_image_alt\">選取圖片</string>\n    <string name=\"image_too_large_preview\">圖片太大以致無法預覽，但無論如何都會嘗試儲存它</string>\n    <string name=\"copied\">已複製到剪貼簿</string>\n    <string name=\"reset\">重置</string>\n    <string name=\"clear_exif\">清除 EXIF</string>\n    <string name=\"save\">儲存</string>\n    <string name=\"add_tag\">新增標籤</string>\n    <string name=\"cancel\">取消</string>\n    <string name=\"presets\">預設集</string>\n    <string name=\"crop\">裁切</string>\n    <string name=\"clear_exif_sub\">所有圖片的 EXIF 資料將會被清除，此動作無法被復原！</string>\n    <string name=\"image_not_saved_sub\">如果您現在離開，將會遺失所有未儲存的變更</string>\n    <string name=\"image_not_saved\">儲存</string>\n    <string name=\"check_source_code_sub\">取得最新的更新，討論問題等</string>\n    <string name=\"pick_color_sub\">從圖片選取色彩，並複製或分享</string>\n    <string name=\"color\">色彩</string>\n    <string name=\"pick_color\">選取色彩</string>\n    <string name=\"image\">圖片</string>\n    <string name=\"color_copied\">色彩已複製複製</string>\n    <string name=\"version\">版本</string>\n    <string name=\"crop_sub\">裁切圖片到任何尺寸</string>\n    <string name=\"remove\">移除</string>\n    <string name=\"new_version\">新版本 %1$s</string>\n    <string name=\"keep_exif\">保留 EXIF</string>\n    <string name=\"change_preview\">更換預覽圖</string>\n    <string name=\"images\">圖片：%d</string>\n    <string name=\"update\">更新</string>\n    <string name=\"unsupported_type\">未支援類型：%1$s</string>\n    <string name=\"amoled_mode\">純黑深色模式</string>\n    <string name=\"def\">預設</string>\n    <string name=\"unspecified\">未指定</string>\n    <string name=\"folder\">輸出資料夾</string>\n    <string name=\"pick_images\">選取圖片</string>\n    <string name=\"custom\">自訂</string>\n    <string name=\"max_bytes\">最大大小（KB）</string>\n    <string name=\"device_storage\">裝置儲存區</string>\n    <string name=\"system\">系統</string>\n    <string name=\"compare\">比較</string>\n    <string name=\"night_mode\">夜間模式</string>\n    <string name=\"light\">淺色</string>\n    <string name=\"dark\">深色</string>\n    <string name=\"pick_two_images\">選取兩張圖片以開始</string>\n    <string name=\"settings\">設定</string>\n    <string name=\"dynamic_colors\">動態色彩</string>\n    <string name=\"customization\">自訂</string>\n    <string name=\"color_red\">紅色</string>\n    <string name=\"color_green\">綠色</string>\n    <string name=\"color_scheme\">色彩方案</string>\n    <string name=\"language\">語言</string>\n    <string name=\"reset_image_sub\">圖片變更將會被退回到初始狀態</string>\n    <string name=\"clipboard_paste_invalid_empty\">沒有任何東西可以貼上</string>\n    <string name=\"cannot_change_palette_while_dynamic_colors_applied\">當動態顏色被啟用時，無法變更應用程式色彩方案</string>\n    <string name=\"no_updates\">未發現更新</string>\n    <string name=\"pick_accent_color\">應用程式主題將會以選擇的顏色為基礎</string>\n    <string name=\"about_app\">關於應用程式</string>\n    <string name=\"issue_tracker\">問題追蹤器</string>\n    <string name=\"issue_tracker_sub\">在此發送錯誤報告與功能請求</string>\n    <string name=\"help_translate\">幫助翻譯</string>\n    <string name=\"help_translate_sub\">更正翻譯錯誤或在地化專案至另一種語言</string>\n    <string name=\"search_here\">在此搜尋</string>\n    <string name=\"extension\">格式</string>\n    <string name=\"explicit\">強制</string>\n    <string name=\"nothing_found_by_search\">沒有發現任何您查詢的內容</string>\n    <string name=\"allow_image_monet_sub\">如果啟用，當您選擇一個圖片以編輯，將會採用此圖片色彩為應用程式色彩</string>\n    <string name=\"dynamic_colors_sub\">如果啟用，則將會採用桌布色彩為應用程式色彩</string>\n    <string name=\"by_bytes_resize_sub\">依選取的檔案大小（KB）調整圖片尺寸</string>\n    <string name=\"amoled_mode_sub\">如果啟用，在夜間模式下背景色彩將會被設定為純黑</string>\n    <string name=\"clipboard_paste_invalid_color_code\">貼上有效的色碼</string>\n    <string name=\"resize_type\">調整尺寸方式</string>\n    <string name=\"by_bytes_resize\">依檔案大小調整尺寸</string>\n    <string name=\"ok\">確定</string>\n    <string name=\"no_palette\">無法從選取的圖片產生調色盤</string>\n    <string name=\"flexible\">彈性</string>\n    <string name=\"generate_palette\">產生調色盤</string>\n    <string name=\"palette\">調色盤</string>\n    <string name=\"original\">原始</string>\n    <string name=\"compare_sub\">比較兩個選取的圖片</string>\n    <string name=\"app_closing\">關閉應用程式</string>\n    <string name=\"allow_image_monet\">允許圖片莫內</string>\n    <string name=\"app_closing_sub\">您確定要關閉此應用程式嗎？</string>\n    <string name=\"restart_app\">重新啟動應用程式</string>\n    <string name=\"stay\">取消</string>\n    <string name=\"single_edit_sub\">編輯單一圖片</string>\n    <string name=\"values_reset\">變更已重置</string>\n    <string name=\"exception\">例外</string>\n    <string name=\"single_edit\">編輯單一圖片</string>\n    <string name=\"palette_sub\">從選取的圖片產生調色盤樣本</string>\n    <string name=\"failed_to_save\">無法儲存 %d 圖片</string>\n    <string name=\"border_thickness\">邊框厚度</string>\n    <string name=\"surface\">表面</string>\n    <string name=\"donation_sub\">這個應用程式是完全免費的，但如果您想支持專案開發，您可以點擊這裡</string>\n    <string name=\"permission_sub\">應用程式需要存取您的儲存區以儲存圖片，這是必要的。請在下一個對話框中授予權限</string>\n    <string name=\"fab_alignment\">懸浮動作按鈕對齊</string>\n    <string name=\"check_updates\">檢查更新</string>\n    <string name=\"check_updates_sub\">如果啟用，更新對話框將在應用程式啟動時顯示給您</string>\n    <string name=\"values\">設定值</string>\n    <string name=\"add\">加入</string>\n    <string name=\"primary\">初级</string>\n    <string name=\"tertiary\">三级</string>\n    <string name=\"secondary\">次級</string>\n    <string name=\"permission\">權限</string>\n    <string name=\"grant\">授予</string>\n    <string name=\"zoom\">圖片縮放</string>\n    <string name=\"prefix\">前置詞</string>\n    <string name=\"filename\">檔案名稱</string>\n    <string name=\"grant_permission_manual\">應用程式需要這個權限才能工作，請手動授予它</string>\n    <string name=\"share\">分享</string>\n    <string name=\"external_storage\">外部儲存區</string>\n    <string name=\"monet_colors\">莫內色彩</string>\n    <string name=\"emoji\">表情符號</string>\n    <string name=\"emoji_sub\">選擇將在主介面上顯示的表情符號</string>\n    <string name=\"add_file_size\">加入檔案大小</string>\n    <string name=\"add_file_size_sub\">如果啟用，將儲存圖片的寬度和高度插入到輸出檔案的名稱</string>\n    <string name=\"delete_exif\">刪除 EXIF</string>\n    <string name=\"delete_exif_sub\">從任意一組圖片中刪除 EXIF 詮釋資料</string>\n    <string name=\"image_preview\">圖片預覽</string>\n    <string name=\"image_preview_sub\">預覽任何類型的圖片：GIF、SVG 等</string>\n    <string name=\"image_source\">圖片來源</string>\n    <string name=\"photo_picker\">照片選擇器</string>\n    <string name=\"gallery_picker\">圖片庫</string>\n    <string name=\"photo_picker_sub\">出現在畫面底部的 Android 現代照片選擇器可能僅適用於 Adnroid 12+，並且在接收 EXIF 詮釋資料時也存在問題</string>\n    <string name=\"options_arrangement\">選項排列</string>\n    <string name=\"edit\">編輯</string>\n    <string name=\"order\">順序</string>\n    <string name=\"order_sub\">確定主介面上工具的順序</string>\n    <string name=\"emojis_count\">表情符號數量</string>\n    <string name=\"sequence_num\">序號</string>\n    <string name=\"original_filename\">原始檔案名稱</string>\n    <string name=\"add_original_filename\">加入原始檔案名稱</string>\n    <string name=\"add_original_filename_sub\">如果啟用，則在輸出圖片的檔案名稱中插入原始檔名</string>\n    <string name=\"filename_not_work_with_photopicker\">如果選擇了照片選擇器圖片來源，加入原始檔案名稱將不起作用</string>\n    <string name=\"file_explorer_picker\">檔案管理器</string>\n    <string name=\"gallery_picker_sub\">簡易的圖片選取器，只有當您有任何提供媒體選取的應用程式時，它才能工作。</string>\n    <string name=\"file_explorer_picker_sub\">使用 GetContent 隨時隨地選取圖片，但已知在某些裝置上接收選取的圖片時也存在問題，這不是我的錯。</string>\n    <string name=\"brightness\">亮度</string>\n    <string name=\"gamma\">伽馬</string>\n    <string name=\"highlights_shadows\">高亮與陰影</string>\n    <string name=\"fit\">適合</string>\n    <string name=\"add_filter\">新增濾鏡</string>\n    <string name=\"color_filter\">色彩濾鏡</string>\n    <string name=\"white_balance\">白平衡</string>\n    <string name=\"temperature\">色溫</string>\n    <string name=\"monochrome\">單色</string>\n    <string name=\"highlights\">高亮</string>\n    <string name=\"shadows\">陰影</string>\n    <string name=\"distance\">強度</string>\n    <string name=\"sharpen\">銳利化</string>\n    <string name=\"replace_sequence_number_sub\">如果啟用，則在使用批次處哩時會取代標準時間戳記為圖片序號</string>\n    <string name=\"replace_sequence_number\">取代序號</string>\n    <string name=\"load_image_from_net\">從網路載入圖片</string>\n    <string name=\"load_image_from_net_sub\">從網際網路載入任何圖片以預覽、縮放、編輯與儲存，如果您想要的話。</string>\n    <string name=\"image_link\">圖片連結</string>\n    <string name=\"explicit_description\">調整圖片尺寸至指定的寬度與高度。可能會改變寬高比。</string>\n    <string name=\"filter\">濾鏡</string>\n    <string name=\"saturation\">飽和度</string>\n    <string name=\"filter_sub\">應用濾鏡至圖片</string>\n    <string name=\"filters\">濾鏡</string>\n    <string name=\"flexible_description\">使用長邊為準由指定的寬度或高度調整圖片尺寸，所有的尺寸計算將在儲存之後完成 - 維持寬高比例</string>\n    <string name=\"no_image\">沒有圖片</string>\n    <string name=\"fill\">填滿</string>\n    <string name=\"contrast\">對比</string>\n    <string name=\"vibrance\">自然飽和度</string>\n    <string name=\"vignette\">暈影</string>\n    <string name=\"start\">開始</string>\n    <string name=\"hue\">色相</string>\n    <string name=\"light_aka_illumination\">光線</string>\n    <string name=\"exposure\">曝光</string>\n    <string name=\"tint\">著色</string>\n    <string name=\"effect\">效果</string>\n    <string name=\"alpha\">Alpha</string>\n    <string name=\"haze\">霧度</string>\n    <string name=\"slope\">變化量</string>\n    <string name=\"box_blur\">方框模糊</string>\n    <string name=\"sepia\">棕褐色調</string>\n    <string name=\"negative\">負片</string>\n    <string name=\"solarize\">曝光過度</string>\n    <string name=\"black_and_white\">黑白色</string>\n    <string name=\"halftone\">半色調</string>\n    <string name=\"cga_colorspace\">GCA 色彩空間</string>\n    <string name=\"line_width\">線條寬度</string>\n    <string name=\"spacing\">間距</string>\n    <string name=\"sobel_edge\">索伯運算子</string>\n    <string name=\"emboss\">浮雕</string>\n    <string name=\"end\">結束</string>\n    <string name=\"laplacian\">拉普拉斯運算子</string>\n    <string name=\"bulge\">凹凸鏡</string>\n    <string name=\"sphere_refraction\">球面折射</string>\n    <string name=\"dilation\">膨脹</string>\n    <string name=\"kuwahara\">Kuwahara 平滑化</string>\n    <string name=\"radius\">半徑</string>\n    <string name=\"scale\">強度</string>\n    <string name=\"distortion\">扭曲化</string>\n    <string name=\"angle\">角度</string>\n    <string name=\"swirl\">漩渦</string>\n    <string name=\"opacity\">不透明度</string>\n    <string name=\"limits_resize\">限制性調整尺寸</string>\n    <string name=\"limits_resize_sub\">調整選擇的圖片的尺寸至指定寬高度並維持寬高比例</string>\n    <string name=\"sketch\">素描</string>\n    <string name=\"threshold\">閾值</string>\n    <string name=\"quantizationLevels\">量化等級</string>\n    <string name=\"posterize\">色調分離</string>\n    <string name=\"toon\">卡通化</string>\n    <string name=\"smooth_toon\">細緻卡通化</string>\n    <string name=\"non_maximum_suppression\">非極大值抑制（NMS）</string>\n    <string name=\"crosshatch\">交叉底紋</string>\n    <string name=\"blur\">模糊化</string>\n    <string name=\"gaussian_blur\">高斯模糊</string>\n    <string name=\"bilaterial_blur\">雙邊模糊</string>\n    <string name=\"glass_sphere_refraction\">玻璃球折射</string>\n    <string name=\"refractive_index\">折射率</string>\n    <string name=\"color_matrix\">色彩矩陣</string>\n    <string name=\"content_scale\">內容縮放</string>\n    <string name=\"weak_pixel_inclusion\">弱像素包含（WPI）</string>\n    <string name=\"lookup\">抬頭</string>\n    <string name=\"stack_blur\">堆疊模糊</string>\n    <string name=\"convolution3x3\">卷積 3x3</string>\n    <string name=\"rgb_filter\">RGB 濾鏡</string>\n    <string name=\"false_color\">假色</string>\n    <string name=\"first_color\">第一種顏色</string>\n    <string name=\"second_color\">第二種顏色</string>\n    <string name=\"reorder\">重新排序</string>\n    <string name=\"fast_blur\">快速模糊</string>\n    <string name=\"blur_size\">模糊尺寸</string>\n    <string name=\"blur_center_x\">模糊中心 x</string>\n    <string name=\"blur_center_y\">模糊中心 y</string>\n    <string name=\"zoom_blur\">縮放模糊</string>\n    <string name=\"color_balance\">色彩平衡</string>\n    <string name=\"luminance_threshold\">亮度閾值</string>\n    <string name=\"activate_files\">您禁用了「檔案」應用程式，請將其啟用才能使用此功能</string>\n    <string name=\"draw\">繪畫</string>\n    <string name=\"draw_sub\">如同在素描本上一樣在圖片上繪畫，或在背景本身上繪畫</string>\n    <string name=\"paint_color\">顏料色彩</string>\n    <string name=\"paint_alpha\">顏料透明度</string>\n    <string name=\"draw_on_image\">在圖片上繪畫</string>\n    <string name=\"draw_on_image_sub\">選取一個圖片並在上面畫一些東西</string>\n    <string name=\"draw_on_background\">在背景上繪畫</string>\n    <string name=\"encryption\">加密</string>\n    <string name=\"implementation_sub\">AES-256，GCM 模式，無填充，12 位元組隨機 IV。密鑰將用作 SHA-3 雜湊值（256 位元）。</string>\n    <string name=\"file_proceed\">檔案已處裡</string>\n    <string name=\"image_size_warning\">嘗試以指定的寬度和高度儲存圖片可能會導致記憶體溢出錯誤，此風險將由您自行承擔。</string>\n    <string name=\"cache\">快取</string>\n    <string name=\"cache_size\">快取大小</string>\n    <string name=\"found_s\">已發現 %1$s</string>\n    <string name=\"auto_cache_clearing\">自動清除快取</string>\n    <string name=\"auto_cache_clearing_sub\">如果啟用，應用程式快取將在應用程式啟動時清除</string>\n    <string name=\"create\">創作</string>\n    <string name=\"draw_on_background_sub\">選擇背景顏色並在其上繪畫</string>\n    <string name=\"background_color\">背景顏色</string>\n    <string name=\"cipher\">加密</string>\n    <string name=\"cipher_sub\">基於各種可用的加密演算法進行加密與解密任何檔案（不僅是圖片）</string>\n    <string name=\"pick_file\">選擇檔案</string>\n    <string name=\"encrypt\">加密</string>\n    <string name=\"decrypt\">解密</string>\n    <string name=\"pick_file_to_start\">選擇檔案以開始</string>\n    <string name=\"decryption\">解密</string>\n    <string name=\"key\">密鑰</string>\n    <string name=\"store_file_desc\">將此檔案儲存在您的設備上或使用分享功能將其放在您想要的任何位置</string>\n    <string name=\"features\">功能</string>\n    <string name=\"implementation\">執行</string>\n    <string name=\"compatibility\">相容性</string>\n    <string name=\"file_size\">檔案大小</string>\n    <string name=\"file_size_sub\">Android 作業系統及裝置的可用記憶體會影響檔案大小的最大限制。 \\n提醒您：記憶體和儲存空間不是同一回事。</string>\n    <string name=\"compatibility_sub\">請注意，不保證與其他檔案加密軟體或服務的相容性。稍有不同的密鑰處理或密碼組態可能是不相容的原因。</string>\n    <string name=\"features_sub\">基於密碼的檔案加密。處理過的檔案可以儲存在選擇的目錄中或分享。解密後的檔案也可以直接開啟。</string>\n    <string name=\"invalid_password_or_not_encrypted\">密碼無效或選擇的檔案未加密</string>\n    <string name=\"tools\">工具</string>\n    <string name=\"group_options_by_type\">按類型對選項進行分組</string>\n    <string name=\"group_options_by_type_sub\">將主介面上的選項按類型分組，而不是自定義列表排列</string>\n    <string name=\"cannot_change_arrangement_while_options_grouping_enabled\">啟用選項分組時無法變更排列</string>\n    <string name=\"warning_bytes\">以 %1$s 模式儲存可能不穩定，因為它是無損格式</string>\n    <string name=\"skip\">略過</string>\n    <string name=\"screenshot\">螢幕截圖</string>\n    <string name=\"copy\">複製</string>\n    <string name=\"fallback_option\">後備選項</string>\n    <string name=\"edit_screenshot\">編輯螢幕截圖</string>\n    <string name=\"secondary_customization\">二次自訂</string>\n    <string name=\"aspect_ratio\">寬高比</string>\n    <string name=\"backup_and_restore\">備份與還原</string>\n    <string name=\"crop_mask\">裁切遮罩</string>\n    <string name=\"image_crop_mask_sub\">使用此遮罩類型以從選取圖片建立遮罩，注意：它應該有 alpha 通道</string>\n    <string name=\"restore_sub\">從之前產生的檔案還原應用程式設定</string>\n    <string name=\"corrupted_file_or_not_a_backup\">損壞的檔案或非備份檔</string>\n    <string name=\"settings_restored\">設定還原成功</string>\n    <string name=\"contact_me\">聯絡我</string>\n    <string name=\"backup\">備份</string>\n    <string name=\"restore\">還原</string>\n    <string name=\"backup_sub\">備份您的應用程式設定為檔案</string>\n    <string name=\"randomize_filename\">隨機化檔案名稱</string>\n    <string name=\"presets_sub\" formatted=\"false\">如果您選擇了預設值 125，影像會儲存為原始影像的 125%。如果您選擇預設值 50，則影像會儲存為原始影像的 50% 大小。</string>\n    <string name=\"presets_sub_bytes\">這裡的預設決定了輸出檔案的百分比，如果您選擇了預設 50 於 5MB 圖片，則在儲存後您將會獲得 2.5MB 的圖片</string>\n    <string name=\"randomize_filename_sub\">如果您啟用了，則輸出檔名將會是完全隨機的</string>\n    <string name=\"saved_to\">已儲存名為 %2$s 至 %1$s 資料夾</string>\n    <string name=\"saved_to_without_filename\">已儲存至 %1$s 資料夾</string>\n    <string name=\"tg_chat\">Telegram 聊天</string>\n    <string name=\"tg_chat_sub\">討論此應用程式與從其他使用者獲取意見回饋，您也可以在此獲得 beta 更新與見解。</string>\n    <string name=\"reset_settings_sub\">這將會恢復您的設定至預設值，請注意，如果沒有備份檔案，則無法復原動作。</string>\n    <string name=\"something_went_wrong_emphasis\">哎呀… 發生了一些錯誤，您可以使用以下的選項寫信給我，我將會嘗試尋找解決方案</string>\n    <string name=\"nature_and_animals\">自然與動物</string>\n    <string name=\"max_colors_count\">最大色彩數量</string>\n    <string name=\"activities\">活動</string>\n    <string name=\"image_exif_warning\">目前，%1$s 在 Android 上僅允許讀取 EXIF。這意味著輸出圖片完全不會有詮釋資料。</string>\n    <string name=\"food_and_drink\">飲食</string>\n    <string name=\"analytics_sub\">允許收集匿名應用程式使用統計資料</string>\n    <string name=\"font_scale\">字型大小</string>\n    <string name=\"draw_mode\">繪畫模式</string>\n    <string name=\"trim_image_sub\">圖片周圍的透明空間將會被修剪</string>\n    <string name=\"erase_background\">擦除背景</string>\n    <string name=\"restore_image\">還原圖片</string>\n    <string name=\"delete\">刪除</string>\n    <string name=\"blur_radius\">模糊半徑</string>\n    <string name=\"background_remover\">去除背景</string>\n    <string name=\"trim_image\">修剪圖片</string>\n    <string name=\"background_remover_sub\">通過繪圖或自動選項從圖片去除背景</string>\n    <string name=\"delete_color_scheme_warn\">您即將刪除選擇的色彩方案，此動作無法被復原。</string>\n    <string name=\"auto_erase_background\">自動擦除背景</string>\n    <string name=\"crashlytics_sub\">這允許應用程式自動地收集崩潰報告</string>\n    <string name=\"create_issue\">建立問題</string>\n    <string name=\"pipette\">吸管</string>\n    <string name=\"symbols\">符號</string>\n    <string name=\"analytics\">分析</string>\n    <string name=\"resize_and_convert\">調整尺寸與轉換</string>\n    <string name=\"objects\">物體</string>\n    <string name=\"text\">文字</string>\n    <string name=\"defaultt\">預設</string>\n    <string name=\"delete_color_scheme_title\">刪除方案</string>\n    <string name=\"restore_background\">還原背景</string>\n    <string name=\"font\">字型</string>\n    <string name=\"resize_and_convert_sub\">變更選取的圖片尺寸或轉換它們至其他格式。如果您選取了單一圖片，也可以在此編輯其 EXIF 詮釋資料</string>\n    <string name=\"using_large_fonts_warn\">使用大字型也許會導致 UI 故障與一些問題，這無法修復，請謹慎使用。</string>\n    <string name=\"keep_exif_sub\">圖片原始的詮釋資料將會被保留</string>\n    <string name=\"erase_mode\">擦除模式</string>\n    <string name=\"travels_and_places\">旅遊與地點</string>\n    <string name=\"updates\">軟體更新</string>\n    <string name=\"wait\">請稍候</string>\n    <string name=\"effort_sub\">值 %1$s 表示快速的壓縮，會產生相對較大的檔案大小；而值 %2$s 則是較慢的壓縮，可以得到較小的檔案。</string>\n    <string name=\"allow_betas\">允許接收測試版本</string>\n    <string name=\"alphabet_and_numbers\">漢字示例 0123456789 !?</string>\n    <string name=\"emotions\">情感模式</string>\n    <string name=\"saving_almost_complete\">儲存幾乎完成了。若您現在取消，將需要從頭開始儲存</string>\n    <string name=\"enable_emoji\">點擊以啟用表情符號</string>\n    <string name=\"effort\">壓縮選項</string>\n    <string name=\"allow_betas_sub\">若您選擇啟用，則在檢查更新時會包括測試版。</string>\n    <string name=\"brush_softness\">畫筆柔度</string>\n    <string name=\"draw_arrows\">繪製箭頭</string>\n    <string name=\"draw_arrows_sub\">若啟用，繪畫路徑將顯示為指向箭頭。</string>\n    <string name=\"crop_description\">圖片會根據輸入的大小進行中心裁剪。如果圖片小於輸入的尺寸，畫布會依指定的背景顏色進行擴展。</string>\n    <string name=\"donation\">捐款</string>\n    <string name=\"image_stitching\">圖片拼接</string>\n    <string name=\"image_stitching_sub\">將選取的圖片合成為一幅大圖片</string>\n    <string name=\"horizontal\">橫向</string>\n    <string name=\"images_order\">圖片排序</string>\n    <string name=\"pick_at_least_two_images\">請選取至少兩張圖片</string>\n    <string name=\"scale_small_images_to_large_sub\">若開啟此選項，小圖片將會放大至序列中最大的圖片大小</string>\n    <string name=\"image_orientation\">圖片定位</string>\n    <string name=\"vertical\">縱向</string>\n    <string name=\"output_image_scale\">輸出圖片縮放比例</string>\n    <string name=\"scale_small_images_to_large\">將小圖片放大至大尺寸</string>\n    <string name=\"recode\">重新編碼</string>\n    <string name=\"blur_edges\">模糊邊緣</string>\n    <string name=\"pixelation\">像素化</string>\n    <string name=\"enhanced_pixelation\">增強像素化</string>\n    <string name=\"target_color\">目標色彩</string>\n    <string name=\"replace_color\">替換色彩</string>\n    <string name=\"diamond_pixelation\">鑽石像素化</string>\n    <string name=\"remove_color\">移除色彩</string>\n    <string name=\"enhanced_diamond_pixelation\">增強鑽石像素化</string>\n    <string name=\"color_to_remove\">要刪除的色彩</string>\n    <string name=\"color_to_replace\">要取代的色彩</string>\n    <string name=\"stroke_pixelation\">筆畫像素化</string>\n    <string name=\"regular\">標準</string>\n    <string name=\"tolerance\">容錯度</string>\n    <string name=\"blur_edges_sub\">如果啟用，在原圖之下繪製模糊的邊界而不是單色，以填充其周圍的空間。</string>\n    <string name=\"circle_pixelation\">圓形像素化</string>\n    <string name=\"enhanced_circle_pixelation\">增強圓形像素化</string>\n    <string name=\"pixel_size\">像素大小</string>\n    <string name=\"lock_draw_orientation\">鎖定繪畫方向</string>\n    <string name=\"lock_draw_orientation_sub\">如果啟用，在繪畫模式中畫面將不會旋轉</string>\n    <string name=\"check_for_updates\">檢查更新</string>\n    <string name=\"fidelity\">忠實</string>\n    <string name=\"rainbow\">彩虹</string>\n    <string name=\"playful_scheme\">趣味主題 - 主題中不包含源顏色的色調</string>\n    <string name=\"vibrant_sub\">色彩豐富的主題，主要調色盤最為鮮艷，其他調色盤色彩也較為增加</string>\n    <string name=\"neutral_sub\">略帶彩色的單色風格</string>\n    <string name=\"content_sub\">將來源顏色置於 Scheme.primaryContainer 的配色方案</string>\n    <string name=\"tonal_spot\">色調點綴</string>\n    <string name=\"monochrome_sub\">純單色主題，顏色僅為黑／白／灰</string>\n    <string name=\"fruit_salad\">水果沙拉</string>\n    <string name=\"fidelity_sub\">與主題內容方案高度相似的方案</string>\n    <string name=\"content\">內容</string>\n    <string name=\"expressive\">富有表現力</string>\n    <string name=\"neutral\">中性</string>\n    <string name=\"tonal_spot_sub\">預設的調色盤風格，它允許自定義所有四個顏色，其他的只允許設定主要的顏色</string>\n    <string name=\"palette_style\">調色盤風格</string>\n    <string name=\"vibrant\">鮮豔</string>\n    <string name=\"both\">兩者</string>\n    <string name=\"invert_colors_sub\">若啟用，將會將主題顏色更換為相反顏色</string>\n    <string name=\"fading_edges\">邊緣淡化</string>\n    <string name=\"foss_update_checker_warning\">這個更新檢查功能會連線至 GitHub，以檢查是否有新版本的更新可供下載。</string>\n    <string name=\"disabled\">已停用</string>\n    <string name=\"invert_colors\">顏色反轉</string>\n    <string name=\"attention\">提醒</string>\n    <string name=\"search_option\">搜尋</string>\n    <string name=\"search_option_sub\">能夠搜尋主介面上的所有可用工具</string>\n    <string name=\"pdf_tools\">PDF 工具</string>\n    <string name=\"images_to_pdf\">圖像轉 PDF</string>\n    <string name=\"preview_pdf\">預覽 PDF</string>\n    <string name=\"pdf_to_images\">PDF 轉圖像</string>\n    <string name=\"images_to_pdf_sub\">將指定圖像打包成輸出 PDF 檔案</string>\n    <string name=\"preview_pdf_sub\">簡易 PDF 預覽</string>\n    <string name=\"pdf_tools_sub\">操作 PDF 檔案：預覽、轉換為一組圖像或從給定圖片中建立</string>\n    <string name=\"pdf_to_images_sub\">將 PDF 轉換為指定輸出格式的圖像</string>\n    <string name=\"mask_filter\">遮罩濾鏡</string>\n    <string name=\"mask_filter_sub\">在指定的遮罩區域應用濾鏡鏈，每個遮罩區域都可以確定其自己的濾鏡集</string>\n    <string name=\"masks\">遮罩</string>\n    <string name=\"add_mask\">新增遮罩</string>\n    <string name=\"mask_indexed\">遮罩 %d</string>\n    <string name=\"mask_preview\">遮罩預覽</string>\n    <string name=\"mask_color\">遮罩顏色</string>\n    <string name=\"mask_preview_sub\">所繪製的濾鏡遮罩會被渲染，以展示預期的效果大概是什麼樣子</string>\n    <string name=\"delete_mask\">刪除遮罩</string>\n    <string name=\"inverse_fill_type\">反向填充類型</string>\n    <string name=\"delete_mask_warn\">您即將刪除所選濾鏡遮罩。此操作無法復原</string>\n    <string name=\"full_filter_sub\">對給定的圖像或單張圖像應用任何濾鏡鏈</string>\n    <string name=\"inverse_fill_type_sub\">如果啟用，所有非遮罩區域將進行濾鏡處理，而不是預設行為</string>\n    <string name=\"start_position\">開始</string>\n    <string name=\"full_filter\">全濾鏡</string>\n    <string name=\"end_position\">結束</string>\n    <string name=\"center_position\">中心</string>\n    <string name=\"highlighter\">螢光筆</string>\n    <string name=\"pen\">筆</string>\n    <string name=\"privacy_blur\">隱私模糊</string>\n    <string name=\"auto_rotate_limits\">自動旋轉</string>\n    <string name=\"buttons_shadow\">按鈕</string>\n    <string name=\"app_bars_shadow\">應用程式列</string>\n    <string name=\"containers_shadow\">容器</string>\n    <string name=\"overwrite_files\">覆蓋檔案</string>\n    <string name=\"vibration\">震動</string>\n    <string name=\"vibration_strength\">震動強度</string>\n    <string name=\"clipboard\">剪貼簿</string>\n    <string name=\"auto_pin\">自動釘選</string>\n    <string name=\"auto_pin_sub\">如果啟用，自動地新增儲存的圖片至剪貼簿</string>\n    <string name=\"empty\">空</string>\n    <string name=\"suffix\">尾綴</string>\n    <string name=\"free\">自由</string>\n    <string name=\"stitch_mode\">拼接模式</string>\n    <string name=\"rate_app_sub\">此應用程式完全地免費，如果您想要它更加強大，請在 Github 上為此專案給星 😄</string>\n    <string name=\"horizontal_grid\">水平網格</string>\n    <string name=\"lasso_sub\">依給定的路徑繪製封閉填充路徑</string>\n    <string name=\"lasso\">套索</string>\n    <string name=\"draw_path_mode\">繪製路徑模式</string>\n    <string name=\"free_drawing_sub\">繪製路徑為輸入值</string>\n    <string name=\"arrow_sub\">從給定的路定繪製指向箭頭</string>\n    <string name=\"double_line_arrow_sub\">從起點至終點連為一線繪製雙指向箭頭</string>\n    <string name=\"oval\">橢圓形</string>\n    <string name=\"rect\">矩形</string>\n    <string name=\"rect_sub\">從起點至終點繪製矩形</string>\n    <string name=\"outlined_oval\">橢圓形外框</string>\n    <string name=\"outlined_rect\">矩形外框</string>\n    <string name=\"outlined_rect_sub\">從起點至終點繪製矩形外框</string>\n    <string name=\"download\">下載</string>\n    <string name=\"best\">最佳</string>\n    <string name=\"double_arrow\">雙箭頭</string>\n    <string name=\"free_drawing\">自由繪製</string>\n    <string name=\"double_line_arrow\">雙線箭頭</string>\n    <string name=\"arrow\">箭頭</string>\n    <string name=\"line\">線條</string>\n    <string name=\"line_sub\">從起點至終點連為一線繪製路徑</string>\n    <string name=\"line_arrow_sub\">從起點至終點連為一線繪製指向箭頭</string>\n    <string name=\"double_arrow_sub\">從給定的路徑繪製雙指向箭頭</string>\n    <string name=\"oval_sub\">從起點至終點繪製橢圓形</string>\n    <string name=\"outlined_oval_sub\">從起點至終點繪製橢圓形外框</string>\n    <string name=\"line_arrow\">直線箭頭</string>\n    <string name=\"scale_mode\">縮放模式</string>\n    <string name=\"default_value\">預設值</string>\n    <string name=\"recognize_text_sub\">從給定的圖片中辨識文字，支援 120 種以上的語言</string>\n    <string name=\"no_data\">沒有資料</string>\n    <string name=\"fast\">快速</string>\n    <string name=\"standard\">標準</string>\n    <string name=\"recognize_text\">OCR（文字辨識）</string>\n    <string name=\"picture_has_no_text\">圖片中沒有圖片或應用程式找不不到</string>\n    <string name=\"downloaded_languages\">已下載的語言</string>\n    <string name=\"available_languages\">可用的語言</string>\n    <string name=\"vertical_grid\">垂直網格</string>\n    <string name=\"columns_count\">欄數</string>\n    <string name=\"side_by_side\">並排</string>\n    <string name=\"transparency\">透明度</string>\n    <string name=\"allow_multiple_languages\">允許多種語言</string>\n    <string name=\"force_exif_widget_initial_value\">強制初始值</string>\n    <string name=\"saved_to_original\">在原始路徑覆蓋了名稱為 %1$s 的檔案</string>\n    <string name=\"magnifier\">放大鏡</string>\n    <string name=\"magnifier_sub\">在繪圖模式中，在手指頂端啟用放大鏡以達到更好可及性</string>\n    <string name=\"no_connection\">沒有網路連接，請檢查並再次嘗試，以便下載訓練模型</string>\n    <string name=\"rows_count\">列數</string>\n    <string name=\"highlighter_sub\">繪製半透明銳利化螢光筆路徑</string>\n    <string name=\"neon_sub\">為您的繪圖新增一些發光效果</string>\n    <string name=\"simple_variants\">簡單變體</string>\n    <string name=\"neon\">螢光</string>\n    <string name=\"privacy_blur_sub\">模糊繪製路線下的影像，以確保隱藏任何您想要的內容</string>\n    <string name=\"pixelation_sub\">類似隱私模糊，但是像素化而非模糊</string>\n    <string name=\"value_in_range\">在 %1$s - %2$s 範圍內的值</string>\n    <string name=\"switches_shadow\">切換按鈕</string>\n    <string name=\"download_description\">為使 Tesseract OCR 正常運作，須要將訓練資料（%1$s）下載至您的裝置中。 \\n您是否想要下載 %2$s 資料？</string>\n    <string name=\"no_such_directory\">找不到「%1$s」目錄，我們已經將其切換至預設目錄，請再次儲存檔案</string>\n    <string name=\"overwrite_file_requirements\">若需要覆蓋檔案，您需要使用「檔案管理器」圖片來源，嘗試重新選取圖片，我們已變更圖片來源至所需的來源</string>\n    <string name=\"overwrite_files_sub\">在選擇的資料夾中原始的檔案將被新的儲存所取代，此選項需要圖片來源為「檔案管理器」或 GetContent，當它開啟時，將被自動設定。</string>\n    <string name=\"rate_app\">給應用程式評分</string>\n    <string name=\"rate\">評分</string>\n    <string name=\"nearest_sub\">一種更簡單的增加尺寸的方法，取代每一個像素為多個相同顏色的像素</string>\n    <string name=\"only_clip_sub\">儲存至儲存空間將不會被執行，並且圖片將僅被嘗試放入剪貼簿中</string>\n    <string name=\"only_clip\">僅剪輯</string>\n    <string name=\"recognition_type\">辨識類型</string>\n    <string name=\"accuracy\">精確度：%1$s</string>\n    <string name=\"segmentation_mode\">分割模式</string>\n    <string name=\"restore_background_sub\">刷子將會復原背景，而不是擦除</string>\n    <string name=\"toggle_tap\">切換輕觸</string>\n    <string name=\"slide\">滑動</string>\n    <string name=\"basic_sub\">最簡單的 Android 縮放模式，用於幾乎所有的應用程式</string>\n    <string name=\"auto_rotate_limits_sub\">允許限制框採用圖片方向</string>\n    <string name=\"sliders_shadow\">滑動塊</string>\n    <string name=\"sliders_shadow_sub\">在滑動塊後方繪製陰影</string>\n    <string name=\"containers_shadow_sub\">在容器後方繪製陰影</string>\n    <string name=\"switches_shadow_sub\">在切換按鈕後方繪製陰影</string>\n    <string name=\"fabs_shadow_sub\">在懸浮動作按鈕後方繪製陰影</string>\n    <string name=\"fabs_shadow\">懸浮動作按鈕</string>\n    <string name=\"buttons_shadow_sub\">在預設按鈕後方繪製陰影</string>\n    <string name=\"app_bars_shadow_sub\">在應用程式列後方繪製陰影</string>\n    <string name=\"gradient_maker_type_image\">漸層疊加</string>\n    <string name=\"segmentation_mode_osd_only\">僅檢測文字及其方向</string>\n    <string name=\"segmentation_mode_auto_only\">僅自動</string>\n    <string name=\"segmentation_mode_auto\">自動</string>\n    <string name=\"segmentation_mode_single_column\">單列文字</string>\n    <string name=\"segmentation_mode_single_block_vert_text\">單段縱向文字</string>\n    <string name=\"segmentation_mode_single_block\">單段文字</string>\n    <string name=\"segmentation_mode_circle_word\">環形詞語</string>\n    <string name=\"segmentation_mode_single_char\">單個字元</string>\n    <string name=\"segmentation_mode_sparse_text\">鬆散文字</string>\n    <string name=\"segmentation_mode_raw_line\">原始行</string>\n    <string name=\"delete_language_sub\">要刪除「%1$s」語言所有辨識類型的 OCR 訓練資料，還是僅刪除選擇的(%2$s)？</string>\n    <string name=\"current\">目前</string>\n    <string name=\"all\">所有</string>\n    <string name=\"gradient_maker\">漸變製作器</string>\n    <string name=\"gradient_type_linear\">線性</string>\n    <string name=\"gradient_type_radial\">放射式</string>\n    <string name=\"gradient_type_sweep\">平掃式</string>\n    <string name=\"gradient_type\">漸變類型</string>\n    <string name=\"center_x\">中心 X</string>\n    <string name=\"center_y\">中心 Y</string>\n    <string name=\"tile_mode\">平鋪模式</string>\n    <string name=\"tile_mode_repeated\">重複</string>\n    <string name=\"tile_mode_mirror\">映象</string>\n    <string name=\"tile_mode_clamp\">固定</string>\n    <string name=\"tile_mode_decal\">貼紙</string>\n    <string name=\"color_stops\">顏色終止點</string>\n    <string name=\"add_color\">新增顏色</string>\n    <string name=\"properties\">屬性</string>\n    <string name=\"hann\">Hann</string>\n    <string name=\"nearest\">Nearest</string>\n    <string name=\"spline\">Spline</string>\n    <string name=\"basic\">基本</string>\n    <string name=\"catmull\">Catmull</string>\n    <string name=\"bilinear_sub\">線性插值（或二維雙線性插值）通常可以很好地改變影像的大小，但會導致一些不理想的細節弱化，而且仍會有些鋸齒狀的效果。</string>\n    <string name=\"bicubic_sub\">更好的縮放方法包括 Lanczos 重取樣和 Mitchell-Netravali 濾波器</string>\n    <string name=\"catmull_sub\">對一組控制點進行平滑插值和重取樣的方法，常用於計算機製圖，以建立平滑曲線</string>\n    <string name=\"hann_sub\">訊號處理中經常使用的漸變函數，通過漸變訊號的邊緣，最大限度地減少頻譜洩漏，提高頻率分析的準確性</string>\n    <string name=\"hermite_sub\">利用曲線段端點的數值和導數生成平滑連續曲線的數學插值技術</string>\n    <string name=\"mitchell_sub\">重取樣方法，使用參數可調的卷積濾波器，在縮放影像的清晰度和抗鋸齒之間取得平衡</string>\n    <string name=\"spline_sub\">利用分段定義的多項式函數平滑插值和近似曲線或曲面，靈活、連續地表示形狀</string>\n    <string name=\"brightness_enforcement\">亮度強制</string>\n    <string name=\"screen\">螢幕</string>\n    <string name=\"transformations\">轉換</string>\n    <string name=\"camera\">相機</string>\n    <string name=\"camera_sub\">使用相機拍照，注意該影像源只能獲取一張影像</string>\n    <string name=\"pen_sub\">最簡單的預設設定 - 僅顏色</string>\n    <string name=\"bilinear\">雙線性</string>\n    <string name=\"bicubic\">Bicubic</string>\n    <string name=\"lanczos\">Lanczos</string>\n    <string name=\"hermite\">Hermite</string>\n    <string name=\"mitchell\">Mitchell</string>\n    <string name=\"lanczos_sub\">通過對畫素值應用加權 sinc 函數來保持高質量插值的重取樣方法</string>\n    <string name=\"segmentation_mode_auto_osd\">自動檢測文字及其方向</string>\n    <string name=\"segmentation_mode_single_line\">單行文字</string>\n    <string name=\"segmentation_mode_single_word\">單個詞語</string>\n    <string name=\"segmentation_mode_sparse_text_osd\">檢測鬆散文字及其方向</string>\n    <string name=\"gradient_maker_sub\">建立指定輸出尺寸的漸變效果，並自定義顏色和外觀類型</string>\n    <string name=\"gradient_maker_type_image_sub\">合成給定圖像頂部的任意梯度</string>\n    <string name=\"use_pixel_switch\">使用 Pixel 開關</string>\n    <string name=\"use_pixel_switch_sub\">使用類似 Google Pixel 的開關</string>\n    <string name=\"force_exif_widget_initial_value_sub\">強制初始檢查 EXIF 部件</string>\n    <string name=\"repeat_watermark_sub\">在圖片上重複水印，而不是在給定位置重複單個水印</string>\n    <string name=\"offset_x\">偏移 X</string>\n    <string name=\"offset_y\">偏移 Y</string>\n    <string name=\"watermark_type\">水印類型</string>\n    <string name=\"text_color\">文字顏色</string>\n    <string name=\"overlay_mode\">疊加模式</string>\n    <string name=\"watermarking\">水印</string>\n    <string name=\"watermarking_sub\">用自定義文字／影像水印覆蓋圖片</string>\n    <string name=\"repeat_watermark\">重複水印</string>\n    <string name=\"watermarking_image_sub\">該圖片將作為水印圖案使用</string>\n    <string name=\"gif_tools\">GIF工具</string>\n    <string name=\"gif_tools_sub\">將影像轉換為 GIF 圖片，或從給定的 GIF 影像中提取幀</string>\n    <string name=\"gif_type_to_image\">GIF 轉換為影像</string>\n    <string name=\"gif_type_to_image_sub\">GIF 檔案轉換為批量圖片</string>\n    <string name=\"gif_type_to_gif_sub\">批量影像轉換為 GIF 檔案</string>\n    <string name=\"gif_type_to_gif\">影像轉換為 GIF</string>\n    <string name=\"select_gif_image_to_start\">選擇 GIF 影像以開始</string>\n    <string name=\"use_size_of_first_frame\">使用第一幀的尺寸</string>\n    <string name=\"use_size_of_first_frame_sub\">用第一幀尺寸替換指定尺寸</string>\n    <string name=\"repeat_count\">重複次數</string>\n    <string name=\"millis\">毫秒</string>\n    <string name=\"fps\">幀率</string>\n    <string name=\"use_lasso\">使用套索</string>\n    <string name=\"use_lasso_sub\">像在绘图模式中一样使用套索来执行擦除操作</string>\n    <string name=\"original_image_preview_alpha\">原始影像預覽 Alpha</string>\n    <string name=\"frame_delay\">幀延遲</string>\n    <string name=\"confetti\">五彩紙屑</string>\n    <string name=\"confetti_sub\">五彩紙屑將顯示在保存、分享和其他主要操作上</string>\n    <string name=\"secure_mode\">安全模式</string>\n    <string name=\"secure_mode_sub\">在最近的應用程式中隱藏內容，也無法進行擷取或錄製。</string>\n    <string name=\"exit\">退出</string>\n    <string name=\"preview_closing\">如果現在離開預覽，則需要重新新增影像</string>\n    <string name=\"burkes_dithering\">Burkes 抖動演算法</string>\n    <string name=\"glitch\">毛刺</string>\n    <string name=\"amount\">數量</string>\n    <string name=\"seed\">種子</string>\n    <string name=\"anaglyph\">浮雕</string>\n    <string name=\"noise\">噪音</string>\n    <string name=\"pixel_sort\">像素排序</string>\n    <string name=\"shuffle\">隨機播放</string>\n    <string name=\"email\">電子郵件</string>\n    <string name=\"dithering\">抖動</string>\n    <string name=\"quantizier\">量化器</string>\n    <string name=\"gray_scale\">灰階</string>\n    <string name=\"bayer_two_dithering\">Bayer 二對二抖動演算法</string>\n    <string name=\"bayer_three_dithering\">Bayer 三對三抖動演算法</string>\n    <string name=\"bayer_four_dithering\">Bayer 四對四抖動演算法</string>\n    <string name=\"bayer_eight_dithering\">Bayer 八對八抖動演算法</string>\n    <string name=\"two_row_sierra_dithering\">雙列 Sierra 抖動演算法</string>\n    <string name=\"atkinson_dithering\">Atkinson 抖動演算法</string>\n    <string name=\"false_floyd_steinberg_dithering\">假 Floyd Steinberg 抖動演算法</string>\n    <string name=\"left_to_right_dithering\">從左到右抖動</string>\n    <string name=\"random_dithering\">隨機抖動</string>\n    <string name=\"simple_threshold_dithering\">簡單閾值抖動</string>\n    <string name=\"sigma\">Sigma</string>\n    <string name=\"spatial_sigma\">空間 Sigma</string>\n    <string name=\"median_blur\">中位數模糊</string>\n    <string name=\"b_spline\">B Spline</string>\n    <string name=\"b_spline_sub\">利用片斷定義的雙三次多項式函數平滑插值和近似曲線或曲面，靈活且連續地表示形狀</string>\n    <string name=\"native_stack_blur\">原生堆疊模糊</string>\n    <string name=\"tilt_shift\">傾斜移位</string>\n    <string name=\"floyd_steinberg_dithering\">Floyd Steinberg 抖動演算法</string>\n    <string name=\"jarvis_judice_ninke_dithering\">Jarvis Judice Ninke 抖動演算法</string>\n    <string name=\"sierra_dithering\">Sierra 抖動演算法</string>\n    <string name=\"sierra_lite_dithering\">Sierra 輕型抖動演算法</string>\n    <string name=\"stucki_dithering\">Stucki 抖動演算法</string>\n    <string name=\"enhanced_glitch\">增強毛刺</string>\n    <string name=\"channel_shift_x\">通道偏移 X</string>\n    <string name=\"channel_shift_y\">通道偏移 Y</string>\n    <string name=\"corruption_shift_x\">色彩偏移 X</string>\n    <string name=\"corruption_shift_y\">色彩偏移 Y</string>\n    <string name=\"tent_blur\">三角形模糊</string>\n    <string name=\"side_fade\">側邊漸變</string>\n    <string name=\"side\">側邊</string>\n    <string name=\"top\">頂部</string>\n    <string name=\"bottom\">底部</string>\n    <string name=\"strength\">強度</string>\n    <string name=\"erode\">侵蝕</string>\n    <string name=\"anisotropic_diffusion\">各向異性擴散</string>\n    <string name=\"diffusion\">擴散</string>\n    <string name=\"conduction\">傳導</string>\n    <string name=\"horizontal_wind_stagger\">水平風移</string>\n    <string name=\"fast_bilaterial_blur\">快速雙邊模糊</string>\n    <string name=\"poisson_blur\">泊松模糊</string>\n    <string name=\"logarithmic_tone_mapping\">對數色調映射</string>\n    <string name=\"crystallize\">結晶化</string>\n    <string name=\"stroke_color\">描邊顏色</string>\n    <string name=\"fractal_glass\">分形噪聲</string>\n    <string name=\"amplitude\">幅度</string>\n    <string name=\"marble\">大理石</string>\n    <string name=\"turbulence\">湍流</string>\n    <string name=\"oil\">油畫</string>\n    <string name=\"just_size\">尺寸</string>\n    <string name=\"frequency_x\">頻率 X</string>\n    <string name=\"amplitude_x\">幅度 X</string>\n    <string name=\"amplitude_y\">幅度 Y</string>\n    <string name=\"perlin_distortion\">Perlin 扭曲</string>\n    <string name=\"hable_filmic_tone_mapping\">Hable 膠片式色調映射</string>\n    <string name=\"heji_burgess_tone_mapping\">Hejl Burgess 色調映射</string>\n    <string name=\"aces_filmic_tone_mapping\">ACES 膠片色調映射</string>\n    <string name=\"aces_hill_tone_mapping\">ACES Hill 色調映射</string>\n    <string name=\"speed\">速度</string>\n    <string name=\"dehaze\">去霧</string>\n    <string name=\"omega\">歐米茄</string>\n    <string name=\"color_matrix_4x4\">顏色矩陣 4x4</string>\n    <string name=\"color_matrix_3x3\">顏色矩陣 3x3</string>\n    <string name=\"simple_effects\">基礎效果</string>\n    <string name=\"polaroid\">拍立得</string>\n    <string name=\"tritonomaly\">三維空間</string>\n    <string name=\"browni\">棕褐色</string>\n    <string name=\"corruption_size\">色彩偏移程度</string>\n    <string name=\"frequency_y\">頻率 Y</string>\n    <string name=\"water_effect\">水紋效果</string>\n    <string name=\"protonomaly\">第一色盲</string>\n    <string name=\"deutaromaly\">第二色盲</string>\n    <string name=\"vintage\">復古</string>\n    <string name=\"coda_chrome\">Coda Chrome</string>\n    <string name=\"night_vision\">夜視</string>\n    <string name=\"warm\">溫暖</string>\n    <string name=\"cool\">涼爽</string>\n    <string name=\"pink_dream\">粉紅夢</string>\n    <string name=\"deutaronotopia\">綠色盲</string>\n    <string name=\"protanopia\">紅色盲</string>\n    <string name=\"achromatomaly\">不全色盲</string>\n    <string name=\"hot_summer\">炎熱的夏天</string>\n    <string name=\"icon_shape\">圖示形狀</string>\n    <string name=\"achromatopsia\">全色盲</string>\n    <string name=\"tritanopia\">Tritanopia</string>\n    <string name=\"golden_hour\">黃金時段</string>\n    <string name=\"purple_mist\">紫霧</string>\n    <string name=\"sunrise\">日出</string>\n    <string name=\"soft_spring_light\">柔和的春光</string>\n    <string name=\"colorful_swirl\">七彩漩渦</string>\n    <string name=\"autumn_tones\">秋天的色調</string>\n    <string name=\"lemonade_light\">檸檬水燈</string>\n    <string name=\"lavender_dream\">薰衣草之夢</string>\n    <string name=\"cyberpunk\">賽博朋克</string>\n    <string name=\"spectral_fire\">光譜火</string>\n    <string name=\"night_magic\">夜間魔法</string>\n    <string name=\"color_explosion\">色彩爆炸</string>\n    <string name=\"icon_shape_sub\">在卡片的前導圖示下方新增具有所選形狀的容器</string>\n    <string name=\"grain\">微粒</string>\n    <string name=\"unsharp\">非銳化</string>\n    <string name=\"pastel\">粉彩</string>\n    <string name=\"orange_haze\">橘色薄霧</string>\n    <string name=\"fantasy_landscape\">奇幻風景</string>\n    <string name=\"electric_gradient\">電梯度</string>\n    <string name=\"caramel_darkness\">焦糖黑度</string>\n    <string name=\"futuristic_gradient\">未來派漸變</string>\n    <string name=\"green_sun\">綠太陽</string>\n    <string name=\"rainbow_world\">彩虹世界</string>\n    <string name=\"deep_purple\">深紫色</string>\n    <string name=\"space_portal\">空間傳送</string>\n    <string name=\"red_swirl\">紅色漩渦</string>\n    <string name=\"digital_code\">數位代碼</string>\n    <string name=\"bokeh\">散景</string>\n    <string name=\"random_emojis_sub\">應用程式列表情符號將隨機變更</string>\n    <string name=\"random_emojis\">隨機表情符號</string>\n    <string name=\"random_emojis_error\">停用表情符號時無法使用隨機表情符號選擇</string>\n    <string name=\"emoji_selection_error\">啟用隨機選擇表情符號時無法選擇表情符號</string>\n    <string name=\"old_tv\">老式電視</string>\n    <string name=\"shuffle_blur\">隨機模糊</string>\n    <string name=\"favorite\">最喜歡的</string>\n    <string name=\"no_favorite_filters\">尚未新增最喜歡的濾鏡</string>\n    <string name=\"image_format\">影像格式</string>\n    <string name=\"drago\">德拉戈</string>\n    <string name=\"aldridge\">奧爾德里奇</string>\n    <string name=\"cutoff\">隔斷</string>\n    <string name=\"uchimura\">內村</string>\n    <string name=\"mobius\">莫比烏斯</string>\n    <string name=\"peak\">頂峰</string>\n    <string name=\"color_anomaly\">顏色異常</string>\n    <string name=\"transition\">過渡</string>\n    <string name=\"images_overwritten\">影像在原始目的地被覆蓋</string>\n    <string name=\"cannot_change_image_format\">啟用覆蓋檔案選項時無法變更影像格式</string>\n    <string name=\"emoji_as_color_scheme\">表情符號作為配色方案</string>\n    <string name=\"emoji_as_color_scheme_sub\">使用表情符號原色作為應用程式配色方案，而不是手動定義的配色方案</string>\n    <string name=\"material_you_sub\">從圖像創建「Material You」調色板</string>\n    <string name=\"dark_colors\">暗色</string>\n    <string name=\"dark_colors_sub\">使用夜間模式配色方案而不是燈光變體</string>\n    <string name=\"copy_as_compose_code\">複製為「Jetpack Compose」代碼</string>\n    <string name=\"ring_blur\">環形模糊</string>\n    <string name=\"cross_blur\">交叉模糊</string>\n    <string name=\"circle_blur\">圓圈模糊</string>\n    <string name=\"star_blur\">星光模糊</string>\n    <string name=\"linear_tilt_shift\">線性移軸</string>\n    <string name=\"tags_to_remove\">要刪除的標籤</string>\n    <string name=\"apng_tools\">APNG 工具</string>\n    <string name=\"apng_type_to_image\">APNG 轉圖片</string>\n    <string name=\"apng_type_to_apng_sub\">將一系列圖片轉換為 APNG 檔案</string>\n    <string name=\"apng_type_to_apng\">圖片轉 APNG</string>\n    <string name=\"apng_type_to_image_sub\">將 APNG 檔案轉換為一系列圖片</string>\n    <string name=\"select_apng_image_to_start\">選擇 APNG 圖片以開始</string>\n    <string name=\"apng_tools_sub\">將圖片轉換為 APNG 圖片或從給定的 APNG 圖片中提取幀</string>\n    <string name=\"motion_blur\">運動模糊</string>\n    <string name=\"zip_sub\">從給定的檔案或圖像創建 Zip 檔案</string>\n    <string name=\"zip\">Zip</string>\n    <string name=\"drag_handle_width\">拖曳手柄寬度</string>\n    <string name=\"confetti_type\">五彩紙屑類型</string>\n    <string name=\"festive\">節日</string>\n    <string name=\"explode\">霹靂</string>\n    <string name=\"rain\">雨</string>\n    <string name=\"corners\">邊角</string>\n    <string name=\"jxl_tools\">JXL 工具</string>\n    <string name=\"jxl_tools_sub\">無品質損失地執行 JXL ~ JPEG 轉碼，或將 GIF／APNG 轉換為 JXL 動畫</string>\n    <string name=\"jxl_type_to_jpeg\">JXL 轉 JPEG</string>\n    <string name=\"jxl_type_to_jpeg_sub\">執行從 JXL 到 JPEG 的無損轉碼</string>\n    <string name=\"jpeg_type_to_jxl_sub\">執行從 JPEG 到 JXL 的無損轉碼</string>\n    <string name=\"jpeg_type_to_jxl\">JPEG 轉 JXL</string>\n    <string name=\"select_jxl_image_to_start\">選擇 JXL 影像開始</string>\n    <string name=\"fast_gaussian_blur_2d\">快速高斯模糊 2D</string>\n    <string name=\"fast_gaussian_blur_3d\">快速高斯模糊 3D</string>\n    <string name=\"fast_gaussian_blur_4d\">快速高斯模糊 4D</string>\n    <string name=\"auto_paste\">自動貼上</string>\n    <string name=\"auto_paste_sub\">允許應用程式自動貼上剪貼簿資料，因此它將顯示在主介面上，您將能夠處理它</string>\n    <string name=\"harmonization_color\">協調顏色</string>\n    <string name=\"harmonization_level\">協調水平</string>\n    <string name=\"generate_previews\">生成預覽</string>\n    <string name=\"pick_multiple_media\">選擇多種媒體</string>\n    <string name=\"pick_single_media\">選擇單一媒體</string>\n    <string name=\"pick\">選取</string>\n    <string name=\"channels_configuration\">通道配置</string>\n    <string name=\"header_today\">今天</string>\n    <string name=\"header_yesterday\">昨天</string>\n    <string name=\"embedded_picker\">嵌入式選擇器</string>\n    <string name=\"embedded_picker_sub\">Image Toolbox 的圖片選取器</string>\n    <string name=\"no_permissions\">無權限</string>\n    <string name=\"request\">請求</string>\n    <string name=\"lanczos_bessel\">Lanczos Bessel</string>\n    <string name=\"gif_type_to_jxl\">GIF 轉 JXL</string>\n    <string name=\"gif_type_to_jxl_sub\">將 GIF 圖像轉換為 JXL 動畫圖片</string>\n    <string name=\"apng_type_to_jxl\">APNG 轉 JXL</string>\n    <string name=\"apng_type_to_jxl_sub\">將 APNG 圖像轉換為 JXL 動畫圖片</string>\n    <string name=\"jxl_type_to_images\">JXL 轉圖像</string>\n    <string name=\"jxl_type_to_images_sub\">將 JXL 動畫轉換為大量圖片</string>\n    <string name=\"jxl_type_to_jxl\">影像轉 JXL</string>\n    <string name=\"jxl_type_to_jxl_sub\">將大量圖片轉換為 JXL 動畫</string>\n    <string name=\"behavior\">行為</string>\n    <string name=\"skip_file_picking\">略過檔案選取</string>\n    <string name=\"skip_file_picking_sub\">如果可能的話，檔案選擇器將立即顯示在所選畫面上</string>\n    <string name=\"generate_previews_sub\">啟用預覽生成，這可能有助於避免在某些裝置上出現崩潰，同時也會停用單一編輯選項中的某些編輯功能</string>\n    <string name=\"lossy_compression\">有損壓縮</string>\n    <string name=\"lossy_compression_sub\">使用有損壓縮而不是無損壓縮來減少檔案大小</string>\n    <string name=\"lanczos_bessel_sub\">透過對像素值應用貝塞爾（jinc）函數來保持高品質插值的重採樣方法</string>\n    <string name=\"compression_type\">壓縮方式</string>\n    <string name=\"speed_sub\">控制生成圖像的解碼速度，這將有助於更快地打開生成圖像，%1$s 表示最慢的解碼速度，而%2$s 表示最快的解碼速度，此設定可能會增加輸出圖像的大小</string>\n    <string name=\"sorting\">篩選</string>\n    <string name=\"sort_by_date\">日期</string>\n    <string name=\"sort_by_date_reversed\">日期（反向）</string>\n    <string name=\"sort_by_name\">名稱</string>\n    <string name=\"sort_by_name_reversed\">名稱（反向）</string>\n    <string name=\"try_again\">再試一次</string>\n    <string name=\"show_settings_in_landscape\">橫向顯示設定</string>\n    <string name=\"show_settings_in_landscape_sub\">如果停用此選項，則在橫向模式下，設定將始終在頂部應用列中的按鈕上開啟，而不是始終可見的選項</string>\n    <string name=\"fullscreen_settings\">全螢幕設定</string>\n    <string name=\"switch_type\">開關類型</string>\n    <string name=\"compose\">Compose</string>\n    <string name=\"fullscreen_settings_sub\">將「啟用」設定為「設定頁面總是全螢幕開啟，而不是可滑動抽屜頁」。</string>\n    <string name=\"compose_switch_sub\">Jetpack Compose Material You 開關</string>\n    <string name=\"material_you_switch_sub\">Material You 開關</string>\n    <string name=\"max\">最大</string>\n    <string name=\"pixel_switch\">Pixel</string>\n    <string name=\"fluent_switch\">Fluent</string>\n    <string name=\"cupertino_switch\">Cupertino</string>\n    <string name=\"cupertino_switch_sub\">基於「Cupertino」設計系統的開關</string>\n    <string name=\"resize_anchor\">調整錨點大小</string>\n    <string name=\"fluent_switch_sub\">基於「Fluent」設計系統的開關</string>\n    <string name=\"default_line_width\">預設線寬</string>\n    <string name=\"images_to_svg\">影像轉 SVG</string>\n    <string name=\"images_to_svg_sub\">將給定圖像追蹤為 SVG 圖像</string>\n    <string name=\"use_sampled_palette\">使用取樣調色板</string>\n    <string name=\"use_sampled_palette_sub\">如果啟用此選項，將對量化調色板進行取樣</string>\n    <string name=\"path_omit\">路徑省略</string>\n    <string name=\"svg_warning\">不建議使用此工具在不縮小尺寸的情況下追蹤大圖像，它可能會導致崩潰並增加處理時間</string>\n    <string name=\"downscale_image\">縮小影像</string>\n    <string name=\"downscale_image_sub\">在處理之前圖像將被縮小到較低的尺寸，這有助於工具更快、更安全地工作</string>\n    <string name=\"min_color_ratio\">最小色彩比例</string>\n    <string name=\"lines_threshold\">線路閾值</string>\n    <string name=\"quadratic_threshold\">二次閾值</string>\n    <string name=\"coordinates_rounding_tolerance\">座標捨入容限</string>\n    <string name=\"path_scale\">路徑比例</string>\n    <string name=\"reset_properties\">重置屬性</string>\n    <string name=\"reset_properties_sub\">所有屬性將設定為預設值，請注意此動作無法復原</string>\n    <string name=\"detailed\">詳細</string>\n    <string name=\"add_new_folder\">新增資料夾</string>\n    <string name=\"tag_bits_per_sample\">每個樣本的位元數</string>\n    <string name=\"tag_photometric_interpretation\">光度測定解釋</string>\n    <string name=\"tag_samples_per_pixel\">每像素樣本數</string>\n    <string name=\"tag_planar_configuration\">平面配置</string>\n    <string name=\"tag_y_cb_cr_sub_sampling\">Y Cb Cr 子取樣</string>\n    <string name=\"tag_y_cb_cr_positioning\">Y Cb Cr 定位</string>\n    <string name=\"tag_x_resolution\">X 解析度</string>\n    <string name=\"tag_y_resolution\">Y 解析度</string>\n    <string name=\"tag_resolution_unit\">解析度單位</string>\n    <string name=\"tag_jpeg_interchange_format\">JPEG 交換格式</string>\n    <string name=\"tag_jpeg_interchange_format_length\">JPEG 交換格式長度</string>\n    <string name=\"tag_transfer_function\">轉移功能</string>\n    <string name=\"tag_white_point\">白點</string>\n    <string name=\"tag_primary_chromaticities\">主要色度</string>\n    <string name=\"tag_y_cb_cr_coefficients\">Y Cb Cr 系數</string>\n    <string name=\"tag_reference_black_white\">參考黑白色階</string>\n    <string name=\"tag_image_description\">圖片描述</string>\n    <string name=\"tag_model\">型號</string>\n    <string name=\"tag_software\">軟體</string>\n    <string name=\"tag_artist\">藝術家</string>\n    <string name=\"tag_copyright\">版權</string>\n    <string name=\"tag_exif_version\">Exif 版本</string>\n    <string name=\"tag_flashpix_version\">Flashpix 版本</string>\n    <string name=\"tag_gamma\">伽瑪</string>\n    <string name=\"tag_color_space\">色彩空間</string>\n    <string name=\"tag_user_comment\">使用者評論</string>\n    <string name=\"tag_related_sound_file\">相關的聲音檔案</string>\n    <string name=\"tag_datetime_original\">原始日期時間</string>\n    <string name=\"tag_datetime_digitized\">數位化日期時間</string>\n    <string name=\"tag_oecf\">OECF</string>\n    <string name=\"tag_flash\">閃光燈</string>\n    <string name=\"tag_contrast\">對比</string>\n    <string name=\"tag_saturation\">飽和度</string>\n    <string name=\"engine_mode\">引擎模式</string>\n    <string name=\"lstm_network\">LSTM 網絡</string>\n    <string name=\"tag_datetime\">日期時間</string>\n    <string name=\"convert\">轉換</string>\n    <string name=\"convert_sub\">將圖片批次轉換為給定的格式</string>\n    <string name=\"tag_compression\">壓縮方法</string>\n    <string name=\"tag_offset_time\">時間偏移</string>\n    <string name=\"tag_offset_time_original\">原始時間偏移</string>\n    <string name=\"tag_exposure_time\">曝光時間</string>\n    <string name=\"tag_f_number\">光圈（F 數值）</string>\n    <string name=\"tag_exposure_program\">曝光模式</string>\n    <string name=\"tag_iso_speed\">感光度（ISO值）</string>\n    <string name=\"tag_aperture_value\">光圈值</string>\n    <string name=\"legacy\">舊式</string>\n    <string name=\"legacy_and_lstm\">舊式與 LSTM</string>\n    <string name=\"tag_make\">製作</string>\n    <string name=\"tag_maker_note\">創作者備註</string>\n    <string name=\"tag_pixel_x_dimension\">X 軸尺寸(Pixel)</string>\n    <string name=\"tag_pixel_y_dimension\">Y 軸尺寸(Pixel)</string>\n    <string name=\"tag_photographic_sensitivity\">感光度</string>\n    <string name=\"tag_spectral_sensitivity\">光譜靈敏度</string>\n    <string name=\"tag_recommended_exposure_index\">建議曝光指數</string>\n    <string name=\"tag_brightness_value\">亮度</string>\n    <string name=\"tag_metering_mode\">測光模式</string>\n    <string name=\"tag_focal_length\">焦距</string>\n    <string name=\"tag_flash_energy\">閃光能量</string>\n    <string name=\"tag_exposure_index\">曝光指數</string>\n    <string name=\"tag_file_source\">檔案來源</string>\n    <string name=\"tag_cfa_pattern\">色彩濾波矩陣</string>\n    <string name=\"tag_subject_location\">主題位置</string>\n    <string name=\"tag_custom_rendered\">客製化渲染</string>\n    <string name=\"tag_exposure_mode\">曝光模式</string>\n    <string name=\"tag_white_balance\">白平衡</string>\n    <string name=\"tag_digital_zoom_ratio\">數位變焦比率</string>\n    <string name=\"tag_focal_length_in_35mm_film\">35mm 等效焦距</string>\n    <string name=\"tag_scene_capture_type\">場景類型</string>\n    <string name=\"tag_gain_control\">增益控制</string>\n    <string name=\"tag_sharpness\">銳利化</string>\n    <string name=\"tag_device_setting_description\">裝置設定描述</string>\n    <string name=\"tag_subject_distance_range\">主體距離範圍</string>\n    <string name=\"tag_image_unique_id\">圖像唯一識別碼</string>\n    <string name=\"tag_camera_owner_name\">相機擁有者</string>\n    <string name=\"tag_body_serial_number\">機身序號</string>\n    <string name=\"tag_lens_specification\">鏡頭資訊</string>\n    <string name=\"tag_lens_make\">鏡頭製造商</string>\n    <string name=\"tag_lens_model\">鏡頭型號</string>\n    <string name=\"tag_lens_serial_number\">鏡頭序號</string>\n    <string name=\"tag_gps_version_id\">GPS 版本</string>\n    <string name=\"tag_gps_latitude_ref\">GPS 緯度參考</string>\n    <string name=\"tag_gps_longitude_ref\">GPS 經度參考</string>\n    <string name=\"tag_gps_longitude\">GPS 經度</string>\n    <string name=\"tag_gps_altitude\">GPS 高度</string>\n    <string name=\"tag_gps_timestamp\">GPS 時間戳記</string>\n    <string name=\"tag_gps_satellites\">GPS 衛星</string>\n    <string name=\"tag_gps_status\">GPS 狀態</string>\n    <string name=\"tag_gps_measure_mode\">GPS 定位模式</string>\n    <string name=\"tag_gps_dop\">GPS DOP（經度衰減因子）</string>\n    <string name=\"tag_gps_speed_ref\">GPS速度參考值</string>\n    <string name=\"tag_gps_speed\">GPS速度</string>\n    <string name=\"ginseng\">Ginseng</string>\n    <string name=\"ginseng_sub\">一種設計給高品質影像的重新取樣濾鏡，可以在銳利度和平滑度之間取得美好的平衡</string>\n    <string name=\"dismiss_forever\">永遠講掰掰</string>\n    <string name=\"tag_gps_latitude\">GPS 緯度</string>\n    <string name=\"tag_gps_altitude_ref\">GPS 高度參考</string>\n    <string name=\"lanczos_6_jinc_sub\">Lanczos 6 濾波器的一種變體，使用 Jinc 函數來提升圖像重取樣的質品質。</string>\n    <string name=\"tag_shutter_speed_value\">快門速度</string>\n    <string name=\"tag_exposure_bias_value\">曝光偏差</string>\n    <string name=\"tag_max_aperture_value\">最大光圈值</string>\n    <string name=\"tag_standard_output_sensitivity\">標準輸出靈敏度</string>\n    <string name=\"tag_subject_distance\">拍攝距離</string>\n    <string name=\"document_scanner\">文件掃描器</string>\n    <string name=\"document_scanner_sub\">掃描文件並創建PDF或圖像</string>\n    <string name=\"start_scanning\">開始掃描</string>\n    <string name=\"save_as_pdf\">保存為PDF</string>\n    <string name=\"share_as_pdf\">以PDF分享</string>\n    <string name=\"antialias\">反鋸齒</string>\n    <string name=\"add_image\">新增圖像</string>\n    <string name=\"save_as_qr_code_image\">保存為QR Code</string>\n    <string name=\"delete_template\">刪除模板</string>\n    <string name=\"scanned_qr_code_isnt_filter_template\">掃描的 QR Code 不是有效的濾鏡範本</string>\n    <string name=\"scan_qr_code\">掃描 QR Code</string>\n    <string name=\"create_template\">建立模板</string>\n    <string name=\"template_name\">模板名稱</string>\n    <string name=\"template_filter\">濾鏡模板</string>\n    <string name=\"create_new\">新建</string>\n    <string name=\"save_as_file\">儲存為檔案</string>\n    <string name=\"delete_template_warn\">您將刪除此模板。此操作無法復原</string>\n    <string name=\"filter_preview\">濾鏡預覽</string>\n    <string name=\"qr_code\">QR Code</string>\n    <string name=\"tag_strip_offsets\">剝離偏移</string>\n    <string name=\"tag_rows_per_strip\">每條帶行數</string>\n    <string name=\"tag_strip_byte_counts\">剝離位元組計數</string>\n    <string name=\"tag_subsec_time_original\">原始秒內細分時間</string>\n    <string name=\"tag_subsec_time_digitized\">數位化秒內細分時間</string>\n    <string name=\"tag_sensitivity_type\">靈敏度類型</string>\n    <string name=\"tag_iso_speed_latitude_yyy\">ISO 感光度 緯度 yyy</string>\n    <string name=\"tag_iso_speed_latitude_zzz\">ISO 感光度 緯度 zzz</string>\n    <string name=\"tag_subject_area\">主體領域</string>\n    <string name=\"tag_spatial_frequency_response\">空間頻率響應</string>\n    <string name=\"tag_focal_plane_x_resolution\">焦平面 X 分辨率</string>\n    <string name=\"tag_focal_plane_y_resolution\">焦平面 Y 分辨率</string>\n    <string name=\"tag_focal_plane_resolution_unit\">焦平面解析度單元</string>\n    <string name=\"tag_sensing_method\">感測方式</string>\n    <string name=\"tag_gps_track\">GPS軌跡</string>\n    <string name=\"tag_gps_track_ref\">GPS 軌跡參考</string>\n    <string name=\"tag_gps_map_datum\">GPS 地圖日期</string>\n    <string name=\"tag_compressed_bits_per_pixel\">每像素壓縮位數</string>\n    <string name=\"tag_offset_time_digitized\">偏移時間數位化</string>\n    <string name=\"tag_subsec_time\">秒內細分時間</string>\n    <string name=\"tag_gps_img_direction_ref\">GPS 影像方向參考</string>\n    <string name=\"tag_gps_img_direction\">GPS 影像方向</string>\n    <string name=\"tag_gps_dest_latitude_ref\">GPS 目標緯度參考</string>\n    <string name=\"languages_imported\">語言匯入成功</string>\n    <string name=\"backup_ocr_models\">備份 OCR 模型</string>\n    <string name=\"import_word\">匯入</string>\n    <string name=\"export\">匯出</string>\n    <string name=\"position\">位置</string>\n    <string name=\"target_image\">目標圖片</string>\n    <string name=\"palette_transfer\">調色盤轉移</string>\n    <string name=\"color_tools\">色彩工具</string>\n    <string name=\"color_harmonies\">色彩調和</string>\n    <string name=\"formatted_timestamp_sub\">啟用時間戳記格式替代檔案名稱中的基本毫秒</string>\n    <string name=\"enable_timestamps_to_format_them\">啟用時間戳以選擇其格式</string>\n    <string name=\"edge_mode\">邊緣模式</string>\n    <string name=\"deuteranomaly_sub\">難以區分綠色與紅色色調</string>\n    <string name=\"font_size\">字體大小</string>\n    <string name=\"watermark_size\">浮水印尺吋</string>\n    <string name=\"selected_color\">已選擇的顏色</string>\n    <string name=\"tag_gps_dest_longitude\">GPS 目標經度</string>\n    <string name=\"format_conversion_sub\">批次將圖片轉換至另一種格式</string>\n    <string name=\"tag_default_crop_size\">預設裁切尺吋</string>\n    <string name=\"tag_rw2_sensor_top_border\">感測器頂部邊框</string>\n    <string name=\"grant_camera_permission_to_scan_document_scanner\">在設定中授予相機權限給文件掃描器</string>\n    <string name=\"options_below_is_for_images\">以下選項用於儲存圖片，而非 PDF</string>\n    <string name=\"tag_gps_dest_distance_ref\">GPS 目標距離參考</string>\n    <string name=\"not_use_color_blind_scheme_sub\">色彩將與主題中的設定完全一致</string>\n    <string name=\"achromatomaly_sub\">降低對所有顏色的敏感度</string>\n    <string name=\"tag_gps_dest_longitude_ref\">GPS 目標經度參考</string>\n    <string name=\"tag_rw2_sensor_right_border\">感測器右邊框</string>\n    <string name=\"color_tools_sub\">混合、製作色調、產生色調等等</string>\n    <string name=\"qr_code_sub\">掃描 QR code 並獲取其內容，或貼上您的字串以產生新的 QR code</string>\n    <string name=\"auto\">自動</string>\n    <string name=\"cubic\">Cubic</string>\n    <string name=\"tiff_compression_scheme\">TIFF 壓縮方案</string>\n    <string name=\"replace_filter\">取代濾鏡</string>\n    <string name=\"outlined_star\">星形外框</string>\n    <string name=\"frame_color\">邊框顏色</string>\n    <string name=\"default_draw_color\">預設繪製顏色</string>\n    <string name=\"tag_gps_dest_latitude\">GPS 目標緯度</string>\n    <string name=\"image_splitting\">圖片分割</string>\n    <string name=\"image_splitting_sub\">依照行或列分割圖片</string>\n    <string name=\"draw_filter_sub\">選擇一個濾鏡以將其作為顏料</string>\n    <string name=\"one_time_save_location\">一次性儲存位置</string>\n    <string name=\"protanopia_sub\">無法感知紅色調</string>\n    <string name=\"color_to_mix\">要混合的顏色</string>\n    <string name=\"links_preview\">連結預覽</string>\n    <string name=\"links\">連結</string>\n    <string name=\"format_conversion\">格式轉換</string>\n    <string name=\"linear\">線性</string>\n    <string name=\"tag_orf_aspect_frame\">寬高比框架</string>\n    <string name=\"tag_rw2_sensor_bottom_border\">感測器底部邊框</string>\n    <string name=\"tag_rw2_sensor_left_border\">感測器左邊框</string>\n    <string name=\"repeat_text\">重複文字</string>\n    <string name=\"star\">星形</string>\n    <string name=\"click_to_start_scanning\">點擊以開始掃圖</string>\n    <string name=\"enter_percentage\">輸入百分比</string>\n    <string name=\"allow_enter_by_text_field\">允許由文字框輸入</string>\n    <string name=\"grid_size_x\">網格尺吋 X</string>\n    <string name=\"grid_size_y\">網格尺吋 Y</string>\n    <string name=\"crop_to_content\">裁切為內容</string>\n    <string name=\"color_to_ignore\">忽略顏色</string>\n    <string name=\"template\">範本</string>\n    <string name=\"no_template_filters\">沒有加入範本濾鏡</string>\n    <string name=\"opened_file_have_no_filter_template\">選擇的檔案沒有濾鏡範本資料</string>\n    <string name=\"select_template_preview\">該圖片將被用於預覽此濾鏡範本</string>\n    <string name=\"as_qr_code\">作為 QR Code 圖片</string>\n    <string name=\"as_file\">作為檔案</string>\n    <string name=\"added_filter_template\">新增了濾鏡範本，其名稱為「%1$s」(%2$s)</string>\n    <string name=\"qr_description\">QR 描述</string>\n    <string name=\"min\">最小</string>\n    <string name=\"grant_camera_permission_to_scan_qr_code\">在設定中授予相機權限以掃描 QR code</string>\n    <string name=\"image_stacking_sub\">使用選取的混合模式將圖片堆疊在一起</string>\n    <string name=\"color_blind_scheme\">色彩校正</string>\n    <string name=\"color_blind_scheme_sub\">選擇模式，為選擇的色盲變體調整主題顏色</string>\n    <string name=\"protanomaly_sub\">難以區分紅色與綠色色調</string>\n    <string name=\"tritanomaly_sub\">難以區分藍色與黃色色調</string>\n    <string name=\"deuteranopia_sub\">無法感知綠色色調</string>\n    <string name=\"tritanopia_sub\">無法感知藍色調</string>\n    <string name=\"achromatopsia_sub\">完全色盲，只能看到灰色陰影</string>\n    <string name=\"not_use_color_blind_scheme\">­不要使用色盲方案</string>\n    <string name=\"pick_filter_info\">選擇以下的濾鏡以將其作為繪畫中用的筆刷</string>\n    <string name=\"bottom_left\">左下</string>\n    <string name=\"bottom_right\">右下</string>\n    <string name=\"center_right\">中右</string>\n    <string name=\"bottom_center\">中下</string>\n    <string name=\"center_left\">中左</string>\n    <string name=\"add_favorites\">新增最愛</string>\n    <string name=\"no_favorite_options_selected\">未選擇最愛的選項，請在工具頁面中新增它們</string>\n    <string name=\"color_shading\">色彩陰影</string>\n    <string name=\"variation\">變體</string>\n    <string name=\"color_mixing\">顏色混合</string>\n    <string name=\"color_info\">顏色資訊</string>\n    <string name=\"save_empty_lut\">取得中性的 LUT 圖片</string>\n    <string name=\"webp_type_to_image_sub\">轉換 WEBP 檔案為一批圖片</string>\n    <string name=\"webp_type_to_webp_sub\">轉換一批圖片為 WEBP 檔案</string>\n    <string name=\"gif_type_to_webp_sub\">轉換 GIF 圖片為 WEBP 動畫圖片</string>\n    <string name=\"webp_tools\">WEBP 工具</string>\n    <string name=\"webp_tools_sub\">轉換圖片為 WEBP 動畫圖片，或者從給予的圖片提取影格</string>\n    <string name=\"select_webp_image_to_start\">選取 WEBP 圖片以開始</string>\n    <string name=\"manage_storage_extra_types\">無法完整的存取檔案</string>\n    <string name=\"default_draw_path_mode\">預設繪製路徑模式</string>\n    <string name=\"add_timestamp\">新增時間戳記</string>\n    <string name=\"add_timestamp_sub\">啟用在檔案名稱中加入時間戳記</string>\n    <string name=\"formatted_timestamp\">格式化時間戳記</string>\n    <string name=\"recently_used\">最近使用過</string>\n    <string name=\"ci_channel_sub\">取得關於應用程式的新版本，與閱讀公告的通知</string>\n    <string name=\"default_values\">預設值</string>\n    <string name=\"hide_all\">隱藏全部</string>\n    <string name=\"show_all\">顯示全部</string>\n    <string name=\"hide_nav_bar\">隱藏導覽列</string>\n    <string name=\"hide_status_bar\">隱藏狀態列</string>\n    <string name=\"noise_generation\">噪點產生</string>\n    <string name=\"frequency\">頻率</string>\n    <string name=\"noise_type\">噪點類型</string>\n    <string name=\"rotation_type\">旋轉類型</string>\n    <string name=\"distance_function\">距離功能</string>\n    <string name=\"return_type\">返回類型</string>\n    <string name=\"custom_filename\">自訂檔案名稱</string>\n    <string name=\"auto_crop\">自動裁切</string>\n    <string name=\"image_stacking\">圖片堆疊</string>\n    <string name=\"center\">中心</string>\n    <string name=\"top_left\">左上</string>\n    <string name=\"top_right\">右上</string>\n    <string name=\"top_center\">中上</string>\n    <string name=\"code_content\">代碼內容</string>\n    <string name=\"tag_gps_dest_distance\">GPS 目標距離</string>\n    <string name=\"tag_gps_area_information\">GPS 區域資訊</string>\n    <string name=\"tag_gps_h_positioning_error\">GPS 水平定位誤差</string>\n    <string name=\"tag_dng_version\">DNG 版本</string>\n    <string name=\"tag_orf_preview_image_length\">預覽圖片長度</string>\n    <string name=\"draw_text_sub\">使用給定字體和顏色沿路徑繪製文本</string>\n    <string name=\"repeat_text_sub\">當前文本將重複繪製直到路徑結束而非僅繪製一次</string>\n    <string name=\"dash_size\">虛線長度</string>\n    <string name=\"draw_mode_image_sub\">使用所選圖片沿著給定路徑繪製</string>\n    <string name=\"tag_orf_preview_image_start\">檢視圖片起始位置</string>\n    <string name=\"calculate\">計算</string>\n    <string name=\"checksum\">核對和</string>\n    <string name=\"text_hash\">文字雜湊</string>\n    <string name=\"pick_file_to_checksum\">選取檔案以計算它基於所選演算法的核對和</string>\n    <string name=\"enter_text_to_checksum\">輸入文字以計算它基於所選演算法的核對和</string>\n    <string name=\"checksum_to_compare\">要比較的核對和</string>\n    <string name=\"match\">符合！</string>\n    <string name=\"match_sub\">核對和不相同，檔案安全</string>\n    <string name=\"difference\">不符合</string>\n    <string name=\"difference_sub\">核對和不相同，檔案可能不安全！</string>\n    <string name=\"tag_rw2_iso\">ISO</string>\n    <string name=\"batch_compare\">批次比較</string>\n    <string name=\"pick_files_to_checksum\">選取一或多個檔案以計算它（們）基於所選演算法的核對和</string>\n    <string name=\"error_while_saving\">嘗試儲存時發生錯誤，請嘗試變更輸出資料夾</string>\n    <string name=\"filename_is_not_set\">未設定檔名</string>\n    <string name=\"polygon_sub\">從起點至終點繪製多邊形</string>\n    <string name=\"checksum_tools\">核對和工具</string>\n    <string name=\"algorithms\">演算法</string>\n    <string name=\"checksum_tools_sub\">比較核對和、計算雜湊值，或使用不同雜湊演算法從檔案建立十六進位字串</string>\n    <string name=\"not_a_valid_base_64\">提供的值不是有效的 Base64 字串</string>\n    <string name=\"gif_type_to_webp\">GIF 轉 WEBP</string>\n    <string name=\"outline_color\">外框顏色</string>\n    <string name=\"clear_selection\">清除選擇</string>\n    <string name=\"pick_files\">選取檔案</string>\n    <string name=\"pick_directory\">選取目錄</string>\n    <string name=\"copy_base_64\">複製 Base64</string>\n    <string name=\"enter_percent\">輸入 %</string>\n    <string name=\"layers_on_background_sub\">與第一個選項相同，但以顏色代替圖片</string>\n    <string name=\"custom_filename_sub\">選擇用於儲存目前圖片的位置與檔案名稱</string>\n    <string name=\"edit_exif_tag\">輕觸以編輯可用的標籤</string>\n    <string name=\"change_sticker\">變更貼紙</string>\n    <string name=\"edit_exif_screen\">編輯 EXIF</string>\n    <string name=\"edit_exif_screen_sub\">變更單一圖片的詮釋資料但不需要重新壓縮</string>\n    <string name=\"options\">選項</string>\n    <string name=\"actions\">動作</string>\n    <string name=\"share_base_64\">分享 Base64</string>\n    <string name=\"outlined_triangle_sub\">從起點至終點繪製三角形外框</string>\n    <string name=\"triangle_sub\">從起點至終點繪製三角形外框</string>\n    <string name=\"outlined_triangle\">三角形外框</string>\n    <string name=\"outlined_polygon\">多邊形外框</string>\n    <string name=\"triangle\">三角形</string>\n    <string name=\"polygon\">多邊形</string>\n    <string name=\"outlined_polygon_sub\">從起點至終點繪製多邊形外框</string>\n    <string name=\"draw_regular_polygon\">繪製正多邊形</string>\n    <string name=\"vertices\">頂點</string>\n    <string name=\"outlined_star_sub\">從起點至終點繪製星形外框</string>\n    <string name=\"star_sub\">從起點至終點繪製星形</string>\n    <string name=\"draw_regular_star\">繪製等邊星形</string>\n    <string name=\"inner_radius_ratio\">內部半徑比</string>\n    <string name=\"antialias_sub\">啟用反鋸齒以防止出現尖銳的邊緣</string>\n    <string name=\"open_edit_instead_of_preview\">開啟編輯而不是預覽</string>\n    <string name=\"fit_to_bounds\">適合邊界</string>\n    <string name=\"harmony_split_complementary\">分割互補色</string>\n    <string name=\"webp_type_to_image\">WEBP 轉（多個）圖片</string>\n    <string name=\"webp_type_to_webp\">（多個）圖片轉 WEBP</string>\n    <string name=\"manage_storage_extra_types_sub\">允許存取所有檔案以檢視 JXL、QOI 以及其它未被 Android 識為圖片檔案的其它圖片。若未授予權限您將無法在此檢視這些圖片</string>\n    <string name=\"one_time_save_location_sub\">檢視與編輯一次性儲存位置，您可以在大多數選項中通過長按儲存按鈕來使用它們</string>\n    <string name=\"system_bars_visibility\">系統列可見性</string>\n    <string name=\"show_system_bars_by_swipe\">通過滑動顯示系統列</string>\n    <string name=\"tools_arrangement\">工具排列</string>\n    <string name=\"group_tools_by_type\">依照類型分組工具</string>\n    <string name=\"group_tools_by_type_sub\">在主介面依照類型分組工具，而不是依自訂列表排列</string>\n    <string name=\"fit_description\">調整圖片以適合給定的尺寸，並使用模效果或色彩作為背景</string>\n    <string name=\"noise_generation_sub\">產生不同的噪點，例如 Perlin 或其他類型</string>\n    <string name=\"saved_to_custom\">儲存至自訂名稱的資料夾中</string>\n    <string name=\"collage_maker\">拼貼畫製作器</string>\n    <string name=\"collage_type\">拼貼類型</string>\n    <string name=\"collages_info\">按住圖片進行交換、移動與縮放以調整位置</string>\n    <string name=\"collage_maker_sub\">使用圖片製作拼貼畫</string>\n    <string name=\"alignment\">對齊</string>\n    <string name=\"custom_options\">自訂選項</string>\n    <string name=\"line_style\">線條樣式</string>\n    <string name=\"create_shortcut_title\">選擇要釘選的工具</string>\n    <string name=\"create_shortcut\">建立捷徑</string>\n    <string name=\"stamped_sub\">沿路徑以指定間距繪製選擇的圖形</string>\n    <string name=\"stamped\">蓋章</string>\n    <string name=\"layout\">佈局</string>\n    <string name=\"filter_preview_image\">預覽圖片</string>\n    <string name=\"hide\">隱藏</string>\n    <string name=\"show\">顯示</string>\n    <string name=\"slider_type\">滑動塊類型</string>\n    <string name=\"center_align_dialog_buttons\">置中對話框按鈕</string>\n    <string name=\"center_align_dialog_buttons_sub\">如果可能，對話框的按鈕將位於中間而不是左邊</string>\n    <string name=\"area\">區域</string>\n    <string name=\"markup_layers\">標記圖層</string>\n    <string name=\"edit_layer\">編輯圖層</string>\n    <string name=\"layers_on_image\">圖片上的圖層</string>\n    <string name=\"layers_on_background\">背景圖層</string>\n    <string name=\"fast_settings_side\">快速設定側邊欄</string>\n    <string name=\"base_64_tools\">Base64 工具</string>\n    <string name=\"base_64_tools_sub\">解碼 Base64 字串為圖片，或編碼圖片為 Base64 格式</string>\n    <string name=\"base_64\">Base64</string>\n    <string name=\"settings_group_visibility_hidden\">設定群組「%1$s」將被預設為摺疊</string>\n    <string name=\"settings_group_visibility_visible\">設定群組「%1$s」將被預設為展開</string>\n    <string name=\"paste_base_64\">貼上 Base64</string>\n    <string name=\"base_64_tips\">載入圖片以複製或儲存 Base64 字串。如果您已有 Base64 字串，您可以在上方貼上它以獲得圖片</string>\n    <string name=\"import_base_64\">匯入 Base64</string>\n    <string name=\"add_outline\">新增外框文字</string>\n    <string name=\"add_outline_sub\">新增具有指定顏色與寬度的外框文字</string>\n    <string name=\"save_base_64\">儲存 Base64</string>\n    <string name=\"outline_size\">外框大小</string>\n    <string name=\"checksum_as_filename\">核對和為檔名</string>\n    <string name=\"rotation\">旋轉</string>\n    <string name=\"create_shortcut_subtitle\">工具將會被新增至您的主畫面應用程式作為捷徑，使用它結合「略過檔案選取」設定來實現所需的行為</string>\n    <string name=\"timestamp\">時間戳記</string>\n    <string name=\"padding\">填充</string>\n    <string name=\"format_pattern\">格式化模式</string>\n    <string name=\"stamp\">印章</string>\n    <string name=\"fit_height\">適合高度</string>\n    <string name=\"none\">無</string>\n    <string name=\"custom_pages\">自訂頁面</string>\n    <string name=\"pages_selection\">頁面選擇</string>\n    <string name=\"inverse_selection\">反向選擇</string>\n    <string name=\"imported_fonts\">已匯入的字型</string>\n    <string name=\"fit_width\">適合寬度</string>\n    <string name=\"source_checksum\">來源核對和</string>\n    <string name=\"checksum_as_filename_sub\">輸出圖片將具有相對於它們資料核對和的名稱</string>\n    <string name=\"draw_regular_polygon_sub\">繪製等邊多邊形，而不是自由形式的形狀</string>\n    <string name=\"markup_layers_sub\">圖層模式，可自由放置圖片、文字等等</string>\n    <string name=\"layers_on_image_sub\">使用圖片作為背景，並且在其上新增不同的圖層</string>\n    <string name=\"import_font\">匯入字型（TTF／OTF）</string>\n    <string name=\"wrong_font\">僅限 TTF 與 OTF 字型可以被匯入</string>\n    <string name=\"export_fonts\">匯出字型</string>\n    <string name=\"copy_not_a_valid_base_64\">無法複製空或無效的 Base64 字串</string>\n    <string name=\"draw_regular_star_sub\">繪製等邊星形，而不是自由形式的形狀</string>\n    <string name=\"open_edit_instead_of_preview_sub\">當您在 ImageToolbox 中選擇圖片要開啟（預覽）時，將開啟編輯選單而不是預覽</string>\n    <string name=\"scan_qr_code_to_replace_content\">掃描 QR Code 以取代欄位中的內容，或輸入內容以產生新的 QR 代碼</string>\n    <string name=\"show_system_bars_by_swipe_sub\">啟用滑動以顯示系統列（如果它們被隱藏）</string>\n    <string name=\"tool_exit_confirmation\">工具退出確認</string>\n    <string name=\"tool_exit_confirmation_sub\">如果您在使用特定工具並嘗試關閉它時有未儲存的變更，將會顯示確認對話框</string>\n    <string name=\"tag_gps_datestamp\">GPS 日期戳記</string>\n    <string name=\"open_source_licenses\">開放原始碼授權</string>\n    <string name=\"low_poly\">低多邊形</string>\n    <string name=\"links_preview_sub\">在可以獲取文字的地方（QRCode,、OCR 等等）啟用連結預覽檢索</string>\n    <string name=\"group\">群組</string>\n    <string name=\"opening\">正在開啟</string>\n    <string name=\"closing\">正在關閉</string>\n    <string name=\"apply\">應用</string>\n    <string name=\"open_source_licenses_sub\">檢視在此應用程式中使用的開放原始碼函式庫的授權</string>\n    <string name=\"cannot_use_monet_while_dynamic_colors_applied\">當動態色彩開啟時無法使用莫內色彩</string>\n    <string name=\"free_software_partner_sub\">在 Android 合作夥伴頻道中有更多實用軟體</string>\n    <string name=\"fancy_sub\">精美滑動塊，這是預設選項</string>\n    <string name=\"material_2_sub\">Material 2 滑動塊</string>\n    <string name=\"material_you_slider_sub\">Material You 滑動塊</string>\n    <string name=\"fast_settings_side_sub\">當編輯圖片時，在所選的一邊加入懸浮條，當點擊後將開啟快速設定</string>\n    <string name=\"soft_glow\">柔光</string>\n    <string name=\"tri_tone\">三原色</string>\n    <string name=\"soft_elegance_variant\">柔和優雅變體</string>\n    <string name=\"hdr\">HDR</string>\n    <string name=\"color_poster\">彩色海報</string>\n    <string name=\"linear_box_blur\">線性方框模糊</string>\n    <string name=\"gaussian_box_blur\">高斯方框模糊</string>\n    <string name=\"linear_gaussian_blur\">線性高斯模糊</string>\n    <string name=\"dashed_sub\">以指定的間隙大小沿著繪製路徑繪製虛線</string>\n    <string name=\"zigzag_sub\">沿著路徑繪製波浪狀的鋸齒形</string>\n    <string name=\"reset_curves\">重置曲線</string>\n    <string name=\"gap_size\">間隙大小</string>\n    <string name=\"tag_gps_processing_method\">GPS 處理方法</string>\n    <string name=\"enable_tonemapping\">啟用色調映射</string>\n    <string name=\"draw_image_sub\">此圖片將被作為繪製路徑的重複元素使用</string>\n    <string name=\"linear_stack_blur\">線性堆疊模糊</string>\n    <string name=\"linear_fast_gaussian_blur_next\">線性快速高斯模糊 Next</string>\n    <string name=\"linear_fast_gaussian_blur\">線性快速高斯模糊</string>\n    <string name=\"sand_painting\">沙畫</string>\n    <string name=\"polka_dot\">波卡點</string>\n    <string name=\"harmony_complementary\">互補色</string>\n    <string name=\"tones\">色調</string>\n    <string name=\"soft_elegance\">柔和優雅</string>\n    <string name=\"palette_transfer_variant\">調色盤轉移變體</string>\n    <string name=\"coffee\">咖啡</string>\n    <string name=\"free_corners\">自由角</string>\n    <string name=\"free_corners_sub\">依多邊形裁切圖片，這也可以修正透視</string>\n    <string name=\"coerce_points_to_image_bounds\">強制點到圖片邊界</string>\n    <string name=\"dashed\">虛線</string>\n    <string name=\"dot_dashed\">點虛線</string>\n    <string name=\"zigzag\">鋸齒形</string>\n    <string name=\"zigzag_ratio\">鋸齒形比率</string>\n    <string name=\"dot_dashed_sub\">沿著指定的路徑繪製點與虛線</string>\n    <string name=\"tone_curves\">色調曲線</string>\n    <string name=\"reset_curves_sub\">曲線將回滾至預設值</string>\n    <string name=\"defaultt_sub\">僅預設直線</string>\n    <string name=\"constant_rate_factor\">恆定品質因子（CRF）</string>\n    <string name=\"main_screen_title\">主介面標題</string>\n    <string name=\"filter_preview_image_sub\">變更濾鏡的預設圖片預覽</string>\n    <string name=\"tag_interoperability_index\">互通性指標</string>\n    <string name=\"coerce_points_to_image_bounds_sub\">點將不受圖片邊界的限制，這有助於更精確的透視修正</string>\n    <string name=\"tag_gps_differential\">GPS 差分</string>\n    <string name=\"fall_colors\">秋色</string>\n    <string name=\"mask\">遮罩</string>\n    <string name=\"lanczos3\">Lanczos 3</string>\n    <string name=\"lanczos4\">Lanczos 4</string>\n    <string name=\"lanczos2_jinc\">Lanczos 2 Jinc</string>\n    <string name=\"ewa_quadric\">Quadric EWA</string>\n    <string name=\"third_color\">第三色</string>\n    <string name=\"clahe_oklab\">Clahe Oklab</string>\n    <string name=\"clahe_oklch\">Clahe Oklch</string>\n    <string name=\"clahe_jzazbz\">Clahe Jzazbz</string>\n    <string name=\"enhanced_oil\">增強的油畫</string>\n    <string name=\"harmony_analogous_complementary\">類似色 + 互補色</string>\n    <string name=\"harmony_square\">方形配色</string>\n    <string name=\"simple_old_tv\">簡易老式電視</string>\n    <string name=\"linear_tent_blur\">線性三角形模糊</string>\n    <string name=\"linear_gaussian_box_blur\">線性高斯方框模糊</string>\n    <string name=\"sigmoidal\">S 形</string>\n    <string name=\"lagrange_2\">Lagrange 2</string>\n    <string name=\"lagrange_3\">Lagrange 3</string>\n    <string name=\"lagrange_2_sub\">2 級的 Lagrange 插值濾鏡，適合用於平化過度的高品質圖片縮放</string>\n    <string name=\"lagrange_3_sub\">3 級的 Lagrange 插值濾鏡，對於圖片的縮放提供了更好的準確性與平滑效果</string>\n    <string name=\"quadric\">Quadric</string>\n    <string name=\"welch\">Welch</string>\n    <string name=\"gaussian\">高斯</string>\n    <string name=\"sphinx\">Sphinx</string>\n    <string name=\"lanczos3_jinc\">Lanczos 3 Jinc</string>\n    <string name=\"lanczos4_jinc\">Lanczos 4 Jinc</string>\n    <string name=\"bspline_sub\">利用分段定義的多項式函數平滑插值和近似曲線或曲面，靈活、連續地表示形狀</string>\n    <string name=\"hamming_sub\">一種窗函數，用於通過漸變訊號邊緣來減少頻譜洩漏，在訊號處理中非常有用</string>\n    <string name=\"blackman_sub\">一種窗函數，藉由最小化頻譜洩漏來提供良好的頻率解析度，通常用於訊號處理</string>\n    <string name=\"welch_sub\">一種窗函數，旨在提供良好的頻率解析度，減少頻譜洩漏，通常用於訊號處理應用</string>\n    <string name=\"robidoux_sub\">一種高品質插值方法，最佳化了自然圖片的調整尺寸、平衡清晰度與平滑度</string>\n    <string name=\"robidoux_sharp_sub\">一種 Robidoux 方法的更清晰的變體，最佳化了清晰圖片的調整尺寸</string>\n    <string name=\"wrap\">纏繞</string>\n    <string name=\"free_software_partner\">自由軟體（合作夥伴）</string>\n    <string name=\"ewa_hanning_sub\">Hanning 濾鏡的橢圓加權（EWA）變體，用於平滑插值和重新採樣</string>\n    <string name=\"ewa_lanczos_4_sharpest\">Lanczos 4 Sharpest EWA</string>\n    <string name=\"kodak\">柯達底片</string>\n    <string name=\"ewa_lanczos_soft\">Lanczos Soft EWA</string>\n    <string name=\"shades\">陰影</string>\n    <string name=\"lanczos2_jinc_sub\">使用 jinc 函數的 Lanczos 2 濾鏡變體，提供最小偽影的高品質插值</string>\n    <string name=\"equalize_histogram_adaptive_hsl\">等化直方圖自適應 HSL</string>\n    <string name=\"unknown_host\">無法存取此網站，請嘗試使用 VPN 或檢查 URL 是否正確</string>\n    <string name=\"fancy\">精緻</string>\n    <string name=\"area_sub\">使用像素面積關係進行重新取樣。這可能是圖片抽取的一種首選方法，因為它能產生無摩爾紋的結果。但當對圖片進行放大時，它與最近「Nearest」類似 。</string>\n    <string name=\"cell_height\">單元格高度</string>\n    <string name=\"equalize_histogram_pixelation\">等化直方圖像素化</string>\n    <string name=\"equalize_histogram_adaptive\">等化直方圖自適應</string>\n    <string name=\"equalize_histogram_adaptive_luv\">等化直方圖自適應 LUV</string>\n    <string name=\"equalize_histogram\">等化直方圖</string>\n    <string name=\"clahe\">Clahe</string>\n    <string name=\"clahe_lab\">Clahe LAB</string>\n    <string name=\"clahe_luv\">Clahe LUV</string>\n    <string name=\"hamming\">Hamming</string>\n    <string name=\"hanning\">Hanning</string>\n    <string name=\"bartlett\">Bartlett</string>\n    <string name=\"bspline\">B-Spline</string>\n    <string name=\"blackman\">Blackman</string>\n    <string name=\"robidoux\">Robidoux</string>\n    <string name=\"robidoux_sharp\">Robidoux Sharp</string>\n    <string name=\"spline16\">Spline 16</string>\n    <string name=\"spline36\">Spline 36</string>\n    <string name=\"spline64\">Spline 64</string>\n    <string name=\"kaiser\">Kaiser</string>\n    <string name=\"bartlett_hann\">Bartlett-Hann</string>\n    <string name=\"lanczos2\">Lanczos 2</string>\n    <string name=\"bohman\">Bohman</string>\n    <string name=\"box\">Box</string>\n    <string name=\"gaussian_sub\">一種應用高斯函數的插值方法，用於平滑化與減少圖片中的噪點</string>\n    <string name=\"sphinx_sub\">一種先進的重新取樣方法，提供最小偽影的高品質的插值</string>\n    <string name=\"bartlett_sub\">一種三角窗函數，用於訊號處理以減少頻譜洩漏</string>\n    <string name=\"bartlett_hann_sub\">一種結合了 Bartlett 與 Hann Windows 的混合窗函數，用於減少信號處理中的頻譜洩漏</string>\n    <string name=\"spline16_sub\">一種以 Spline 為基礎的插值方法，使用了 16-tap 濾鏡提供了平滑效果</string>\n    <string name=\"spline36_sub\">一種以 Spline 為基礎的插值方法，使用了 36-tap 濾鏡提供了平滑效果</string>\n    <string name=\"spline64_sub\">一種以 Spline 為基礎的插值方法，使用了 64-tap 濾鏡提供了平滑效果</string>\n    <string name=\"box_sub\">一種簡易重新取樣方法，使用鄰近像素值的平均，通常會產生塊狀外觀</string>\n    <string name=\"lanczos2_sub\">使用 2-lobe Lanczos 濾鏡的一種重新取樣方法，以獲得最小偽影的高品質插值</string>\n    <string name=\"lanczos3_sub\">使用 3-lobe Lanczos 濾鏡的一種重新取樣方法，以獲得最小偽影的高品質插值</string>\n    <string name=\"bohman_sub\">一種用於減少光譜洩漏的窗函數，在訊號處理應用中提供良好的頻率解析度</string>\n    <string name=\"lanczos4_sub\">使用 4-lobe Lanczos 濾鏡的一種重新取樣方法，以獲得最小偽影的高品質插值</string>\n    <string name=\"lanczos3_jinc_sub\">使用 jinc 函數的 Lanczos 3 濾鏡變體，提供最小偽影的高品質插值</string>\n    <string name=\"ewa_hanning\">Hanning EWA</string>\n    <string name=\"ewa_robidoux\">Robidoux EWA</string>\n    <string name=\"ewa_robidoux_sub\">Robidoux 濾鏡的橢圓加權平均（EWA）變體，以獲得高品量的重新取樣</string>\n    <string name=\"ewa_blackman\">Blackman EWA</string>\n    <string name=\"ewa_blackman_sub\">Blackman 濾鏡的橢圓加權平均（EWA）變體，以獲得最小化振鈴偽影</string>\n    <string name=\"ewa_lanczos3_jinc\">Lanczos 3 Jinc EWA</string>\n    <string name=\"ewa_robidoux_sharp\">Robidoux Sharp EWA</string>\n    <string name=\"ewa_robidoux_sharp_sub\">Robidoux Sharp 濾鏡的橢圓加權平均（EWA）變體，以獲得更清晰的效果</string>\n    <string name=\"ewa_quadric_sub\">Quadric 濾鏡的橢圓加權平均（EWA）變體，以獲得平滑的插值</string>\n    <string name=\"ewa_lanczos3_jinc_sub\">Lanczos 3 Jinc 濾鏡的橢圓加權平均（EWA）變體，以獲得減少混疊的高品質重新取樣</string>\n    <string name=\"ewa_lanczos_sharp\">Lanczos Sharp EWA</string>\n    <string name=\"ewa_ginseng\">Ginseng EWA</string>\n    <string name=\"ewa_ginseng_sub\">Ginseng 濾鏡的橢圓加權平均變體，以獲得增強的影像品質</string>\n    <string name=\"ewa_lanczos_sharp_sub\">Lanczos 3 Sharp 濾鏡的橢圓加權平均（EWA）變體，以實現最小偽影的清晰效果</string>\n    <string name=\"ewa_lanczos_4_sharpest_sub\">Lanczos 4 Sharpest 濾鏡的橢圓加權平均（EWA）變體，以獲得極其清晰的影像重新取樣</string>\n    <string name=\"ewa_lanczos_soft_sub\">Lanczos Soft 濾鏡的橢圓加權平均（EWA）變體，以獲得更平滑的影像重新取樣</string>\n    <string name=\"clahe_hsl\">Clahe HSL</string>\n    <string name=\"equalize_histogram_adaptive_hsv\">等化直方圖自適應 HSV</string>\n    <string name=\"clahe_hsv\">Clahe HSV</string>\n    <string name=\"lanczos_6\">Lanczos 6</string>\n    <string name=\"lanczos_6_sub\">6 級的 Lanczos 重新取樣濾鏡，提供更清晰與更加準確的圖片縮放</string>\n    <string name=\"lanczos_6_jinc\">Lanczos 6 Jinc</string>\n    <string name=\"simple_sketch\">簡易素描</string>\n    <string name=\"gotham\">高譚</string>\n    <string name=\"clustered_2x2_dithering\">群集式 2x2 抖動</string>\n    <string name=\"clustered_4x4_dithering\">群集式 4x4抖動</string>\n    <string name=\"yililoma_dithering\">Yililoma 抖動</string>\n    <string name=\"harmony_triadic\">三角配色</string>\n    <string name=\"harmony_analogous\">類似色</string>\n    <string name=\"harmony_tetradic\">四角配色</string>\n    <string name=\"tints\">淡色</string>\n    <string name=\"foggy_night\">霧夜</string>\n    <string name=\"bleach_bypass\">跳漂白</string>\n    <string name=\"candlelight\">燭光</string>\n    <string name=\"retro_yellow\">復古黃</string>\n    <string name=\"golden_forest\">金色森林</string>\n    <string name=\"pop_art\">流行藝術</string>\n    <string name=\"celluloid\">賽璐珞</string>\n    <string name=\"fractal_type\">分形類型</string>\n    <string name=\"weighted_strength\">加權強度</string>\n    <string name=\"ping_pong_strength\">乒乓強度</string>\n    <string name=\"jitter\">抖動</string>\n    <string name=\"domain_warp\">領域扭曲</string>\n    <string name=\"tesseract_options\">Tesseract 選項</string>\n    <string name=\"custom_params_info\" tools:ignore=\"TypographyDashes\">選項應照以下模式輸入： \\\"--{選項名稱} {值}\\\"</string>\n    <string name=\"tesseract_options_sub\">為 Tesseract 引擎應用一些輸入變數</string>\n    <string name=\"black_hat\">黑帽</string>\n    <string name=\"crossfade\">交叉淡入／出</string>\n    <string name=\"dont_stack_frames_sub\">處置預留影格，使其不會互相堆疊</string>\n    <string name=\"crossfade_sub\">影格之間將交叉淡入淡出</string>\n    <string name=\"crossfade_count\">交叉淡入／出影格數量</string>\n    <string name=\"threshold_one\">閾值一</string>\n    <string name=\"threshold_two\">閾值二</string>\n    <string name=\"grid_color\">網格顏色</string>\n    <string name=\"compact_selectors\">緊湊型選擇器</string>\n    <string name=\"compact_selectors_sub\">一些選擇控制元件將使用緊湊的佈局以減少佔用空間</string>\n    <string name=\"grant_camera_permission_to_capture_image\">在設定中授予相機權限以擷取圖片</string>\n    <string name=\"enhanced_zoom_blur\">增強的縮放模糊</string>\n    <string name=\"helper_grid\">輔助網格</string>\n    <string name=\"cell_width\">單元格寬度</string>\n    <string name=\"canny\">Canny</string>\n    <string name=\"laplacian_simple\">簡易拉普拉斯運算子</string>\n    <string name=\"sobel_simple\">簡易索伯運算子</string>\n    <string name=\"material_2\">Material 2</string>\n    <string name=\"dont_stack_frames\">不要堆疊影格</string>\n    <string name=\"clustered_8x8_dithering\">群集式 8x8 抖動</string>\n    <string name=\"grid_size\">網格尺寸</string>\n    <string name=\"resolution_x\">X 軸解析度</string>\n    <string name=\"histogram\">直方圖</string>\n    <string name=\"image_for_histogram\">此圖片將用於產生 RGB 與亮度直方圖</string>\n    <string name=\"resolution\">解析度</string>\n    <string name=\"tag_gps_dest_bearing\">GPS 目的地方位角</string>\n    <string name=\"tag_gps_dest_bearing_ref\">GPS 目的地方位角參考</string>\n    <string name=\"pixel_by_pixel\">點對點</string>\n    <string name=\"top_hat\">高帽</string>\n    <string name=\"cubic_sub\">Cubic 插值藉由考慮最接近的 16 像素來實現更平滑的縮放，給出比 Bilinear 更好的結果</string>\n    <string name=\"lanczos4_jinc_sub\">使用 jinc 函數的 Lanczos 4 濾鏡變體，提供最小偽影的高品質插值</string>\n    <string name=\"quadric_sub\">一種使用二次函數進行插值的方法，提供平滑與連續的效果</string>\n    <string name=\"hanning_sub\">Hann 窗函數的一種變體，通常用於減少訊號處理應用中的頻譜洩漏</string>\n    <string name=\"haasn_soft\">Haasn Soft</string>\n    <string name=\"haasn_soft_sub\">一種由 Haasn 設計的重新取樣濾鏡，以獲得平滑與無偽影的圖像縮放</string>\n    <string name=\"resolution_y\">Y 軸解析度</string>\n    <string name=\"histogram_sub\">RGB 或亮度圖片直方圖幫助您進行調整</string>\n    <string name=\"equalize_histogram_hsv\">等化直方圖 HSV</string>\n    <string name=\"equalize_histogram_adaptive_lab\">等化直方圖自適應 LAB</string>\n    <string name=\"beta\">Beta</string>\n    <string name=\"lut_library_sub\">下載 LUT 集合，您可以在下載之後應用它們</string>\n    <string name=\"lut_library\">LUT 函式庫</string>\n    <string name=\"helper_grid_sub\">在繪圖區域上方顯示輔助網格以協助精確繪畫操縱</string>\n    <string name=\"crf_sub\">%1$s 代表緩慢的壓縮，因而產生相對較小的檔案。%2$s 代表較快的壓縮，因而產生較大的檔案。</string>\n    <string name=\"lut_library_update_sub\">更新 LUT 集合（只有新的項目會被加入下載隊列），您可以在下載之後應用它們</string>\n    <string name=\"image_cutting\">圖片裁剪</string>\n    <string name=\"image_cutting_sub\">通過垂直或水平線剪除部分圖片並合併其餘部分（可逆向操作）</string>\n    <string name=\"vertical_pivot_line\">垂直樞軸線</string>\n    <string name=\"horizontal_pivot_line\">水平樞軸線</string>\n    <string name=\"inverse_vertical_selection_sub\">垂直剪下部分將被保留，而不是合併剪下區域周圍的部分</string>\n    <string name=\"inverse_horizontal_selection_sub\">水平剪下部分將被保留，而不是合併剪下區域周圍的部分</string>\n    <string name=\"pixel_comparison_type\">像素比較類型</string>\n    <string name=\"scan_barcode\">掃描條碼</string>\n    <string name=\"barcode_type\">條碼類型</string>\n    <string name=\"enforce_bw_sub\">條碼圖片將為完全黑白，而不是取決於應用程式主題彩色</string>\n    <string name=\"barcodes_sub\">掃描任何條碼（QR、EAN、AZTEC…）並獲得其內容，或貼上您的文字以產生新的條碼</string>\n    <string name=\"enforce_bw\">強制黑白</string>\n    <string name=\"allow_enter_by_text_field_sub\">啟用預設集後方的文字欄位，以便立即輸入</string>\n    <string name=\"bins_count\">箱數</string>\n    <string name=\"target_lut_image\">目標 LUT 圖片</string>\n    <string name=\"lut512x512\">512x512 2D LUT</string>\n    <string name=\"lut\">LUT（色彩查找表）</string>\n    <string name=\"cube_lut\">3D LUT</string>\n    <string name=\"target_cube_lut_file\">目標 3D LUT 檔案 (.cube / .CUBE)</string>\n    <string name=\"film_stock_50\">50 號底片</string>\n    <string name=\"ci_channel\">CI 頻道</string>\n    <string name=\"image_toolbox_in_telegram_sub\">加 入我們的聊天頻道，您可以討論任何想要的議題，還可以查看我發布 Beta 和公告的 CI 頻道。</string>\n    <string name=\"octaves\">八分音符</string>\n    <string name=\"spot_heal_sub\">在繪製路徑下進行內容感知填滿</string>\n    <string name=\"spot_heal\">點狀癒合</string>\n    <string name=\"highlight_color\">高亮顏色</string>\n    <string name=\"mesh_gradients_sub\">以自訂節點數量與解析度建立網格梯度</string>\n    <string name=\"mesh_gradients\">網格梯度</string>\n    <string name=\"clip\">剪輯</string>\n    <string name=\"scale_color_space\">比例色彩空間</string>\n    <string name=\"height_ratio\">高度比</string>\n    <string name=\"kaiser_sub\">一種使用 Kaiser 窗的插值方法，圖供良好控制主瓣寬度與旁瓣水平之間的權衡</string>\n    <string name=\"amatorka\">Amatorka</string>\n    <string name=\"miss_etikate\">Miss Etikate</string>\n    <string name=\"drop_blues\">藍色衰減</string>\n    <string name=\"edgy_amber\">銳利琥珀</string>\n    <string name=\"greenish\">淡綠</string>\n    <string name=\"ico_size_warning\">ICO 檔案的最大儲存尺寸僅為 256*256</string>\n    <string name=\"image_toolbox_in_telegram\">Telegram 中的 Image Toolbox 🎉</string>\n    <string name=\"lacunarity\">Lacunarity</string>\n    <string name=\"gain\">增益</string>\n    <string name=\"use_circle_kernel\">使用圓形內核</string>\n    <string name=\"morphological_gradient\">形態梯度</string>\n    <string name=\"base_64_actions\">Base64 動作</string>\n    <string name=\"head_length_scale\">頭部長度縮放</string>\n    <string name=\"gradient_maker_type_image_mesh\">網格梯度重疊</string>\n    <string name=\"fit_to_bounds_sub\">將裁切調整尺寸模式與此參數結合，以實現所需行為（裁切／適合寬高比）</string>\n    <string name=\"save_empty_lut_sub\">首先，使用您最愛的照片編輯應用軟體將一個濾鏡應用於中性 LUT，您可以在此獲取它。為此正常工作，每個像素顏色不能依賴於其它像素（例如，模糊化將無法正常工作）。一旦準備就緒，使用您新的 LUT 圖片作為輸入用於 512*512 LUT 濾鏡。</string>\n    <string name=\"mirror_101\">鏡子 101</string>\n    <string name=\"collection_mesh_gradients_sub\">檢視線上網格梯度集合</string>\n    <string name=\"gradient_maker_type_image_mesh_sub\">在給定圖片頂部合成網格梯度</string>\n    <string name=\"collection_mesh_gradients\">網格梯度集合</string>\n    <string name=\"points_customization\">自訂點</string>\n    <string name=\"no_barcode_found\">找不到條碼</string>\n    <string name=\"generated_barcode_will_be_here\">產生的條碼將展示在此處</string>\n    <string name=\"audio_cover_extractor_sub\">從音訊檔案匯出專輯封面圖片，支援大多數常見的格式</string>\n    <string name=\"audio_cover_extractor\">音訊封面匯出器</string>\n    <string name=\"pick_audio_to_start\">選取音訊以開始</string>\n    <string name=\"pick_audio\">選取音訊</string>\n    <string name=\"no_covers_found\">找不到封面</string>\n    <string name=\"send_logs\">傳送日誌</string>\n    <string name=\"send_logs_sub\">點擊以分享應用程式日誌檔案，這可以幫助我發現並解決問題</string>\n    <string name=\"crash_title\">哎呀…發生了一些錯誤</string>\n    <string name=\"crash_subtitle\">您可以使用下方的選項聯絡我，我將嘗試找到解決方案。（不要忘記附加日誌）</string>\n    <string name=\"ocr_write_to_file\">寫入檔案</string>\n    <string name=\"ocr_write_to_metadata\">寫入詮釋資料</string>\n    <string name=\"auto_remove_red_eyes\">自動移除紅眼</string>\n    <string name=\"use_lsb\">使用 LSB</string>\n    <string name=\"sort_by_date_modified\">修改日期</string>\n    <string name=\"sort_by_size\">大小</string>\n    <string name=\"sort_by_size_reversed\">大小（反向）</string>\n    <string name=\"sort_by_mime_type\">MIME 類型</string>\n    <string name=\"sort_by_mime_type_reversed\">MIME 類型（反向）</string>\n    <string name=\"sort_by_date_modified_reversed\">修改日期（反向）</string>\n    <string name=\"sort_by_extension\">副檔名</string>\n    <string name=\"sort_by_extension_reversed\">副檔名（反向）</string>\n    <string name=\"sort_by_date_added\">新增日期</string>\n    <string name=\"sort_by_date_added_reversed\">新增日期（反向）</string>\n    <string name=\"password\">密碼</string>\n    <string name=\"unlock\">解鎖</string>\n    <string name=\"pdf_is_protected\">PDF 已受保護</string>\n    <string name=\"left_to_right\">由左至右</string>\n    <string name=\"right_to_left\">由右至左</string>\n    <string name=\"top_to_bottom\">由上至下</string>\n    <string name=\"bottom_to_top\">由下至上</string>\n    <string name=\"disable_rotation\">禁用旋轉</string>\n    <string name=\"disable_rotation_sub\">防止用兩指手勢旋轉圖像</string>\n    <string name=\"enable_snapping_to_borders\">啟用對齊邊框</string>\n    <string name=\"enable_snapping_to_borders_sub\">移動或縮放後，圖像將對齊以填充框架邊緣</string>\n    <string name=\"ocr_write_to_file_sub\">從一批圖像中提取文字並將其儲存在一個文字檔案中</string>\n    <string name=\"ocr_write_to_metadata_sub\">從每張圖像中提取文字並將其放入相關照片的 EXIF 資訊中</string>\n    <string name=\"invisible_mode\">隱形模式</string>\n    <string name=\"invisible_mode_sub\">使用隱寫術在圖像字節內創建肉眼看不見的水印</string>\n    <string name=\"use_lsb_sub\">將使用 LSB（低有效位）隱寫術方法，否則使用 FD（頻域）</string>\n    <string name=\"operation_almost_complete\">操作即將完成。現在取消需要重新啟動</string>\n    <string name=\"liquid_glass\">液態玻璃</string>\n    <string name=\"liquid_glass_sub\">基於最近發佈的 IOS 26 及其液態玻璃設計系統的交換機</string>\n    <string name=\"pick_image_or_base64\">選擇下面的圖像或貼上/匯入 Base64 資料</string>\n    <string name=\"type_image_link\">輸入圖像連結以開始</string>\n    <string name=\"paste_link\">貼上連結</string>\n    <string name=\"kaleidoscope\">萬花筒</string>\n    <string name=\"secondary_angle\">次要角度</string>\n    <string name=\"sides\">側面</string>\n    <string name=\"channel_mix\">頻道組合</string>\n    <string name=\"blue_green\">藍綠色</string>\n    <string name=\"red_blue\">紅藍</string>\n    <string name=\"green_red\">綠紅</string>\n    <string name=\"into_red\">成紅色</string>\n    <string name=\"into_green\">走進綠色</string>\n    <string name=\"into_blue\">變成藍色</string>\n    <string name=\"cyan\">青色</string>\n    <string name=\"magenta\">品紅</string>\n    <string name=\"yellow\">黃色的</string>\n    <string name=\"color_halftone\">彩色半色調</string>\n    <string name=\"contour\">輪廓</string>\n    <string name=\"levels\">等級</string>\n    <string name=\"offset\">抵消</string>\n    <string name=\"voronoi_crystallize\">沃羅諾伊結晶</string>\n    <string name=\"shape\">形狀</string>\n    <string name=\"stretch\">拉緊</string>\n    <string name=\"randomness\">隨機性</string>\n    <string name=\"despeckle\">去斑</string>\n    <string name=\"diffuse\">擴散</string>\n    <string name=\"dog\">狗</string>\n    <string name=\"second_radius\">第二半徑</string>\n    <string name=\"equalize\">均衡</string>\n    <string name=\"glow\">輝光</string>\n    <string name=\"whirl_and_pinch\">旋轉和捏</string>\n    <string name=\"pointillize\">點化</string>\n    <string name=\"border_color\">邊框顏色</string>\n    <string name=\"polar_coordinates\">極座標</string>\n    <string name=\"rect_to_polar\">直角到極座標</string>\n    <string name=\"polar_to_rect\">極地到直角</string>\n    <string name=\"invert_in_circle\">翻轉成圓圈</string>\n    <string name=\"reduce_noise\">減少噪音</string>\n    <string name=\"simple_solarize\">簡單的日曬</string>\n    <string name=\"weave\">編織</string>\n    <string name=\"x_gap\">X 間隙</string>\n    <string name=\"y_gap\">Y 間隙</string>\n    <string name=\"x_width\">X 寬度</string>\n    <string name=\"y_wdth\">Y 寬度</string>\n    <string name=\"twirl\">捻</string>\n    <string name=\"rubber_stmp\">橡皮戳</string>\n    <string name=\"smear\">塗抹</string>\n    <string name=\"density\">密度</string>\n    <string name=\"mix\">混合</string>\n    <string name=\"sphere_lensh_distortion\">球面透鏡畸變</string>\n    <string name=\"refraction_index\">折射率</string>\n    <string name=\"arc\">弧</string>\n    <string name=\"spread_angle\">展開角</string>\n    <string name=\"sparkle\">火花</string>\n    <string name=\"rays\">射線</string>\n    <string name=\"ascii\">ASCII</string>\n    <string name=\"gradient\">坡度</string>\n    <string name=\"moire\">瑪麗</string>\n    <string name=\"autumn\">秋天</string>\n    <string name=\"bone\">骨</string>\n    <string name=\"jet\">噴射</string>\n    <string name=\"winter\">冬天</string>\n    <string name=\"ocean\">海洋</string>\n    <string name=\"summer\">夏天</string>\n    <string name=\"spring\">春天</string>\n    <string name=\"cool_variant\">酷變體</string>\n    <string name=\"hsv\">單純皰疹病毒</string>\n    <string name=\"pink\">粉色的</string>\n    <string name=\"hot\">熱的</string>\n    <string name=\"parula\">單詞</string>\n    <string name=\"magma\">岩漿</string>\n    <string name=\"inferno\">地獄</string>\n    <string name=\"plasma\">等離子體</string>\n    <string name=\"viridis\">維裡迪斯</string>\n    <string name=\"cividis\">公民</string>\n    <string name=\"twilight\">暮</string>\n    <string name=\"twilight_shifted\">暮光轉移</string>\n    <string name=\"auto_perspective\">透視自動</string>\n    <string name=\"deskew\">相差校正</string>\n    <string name=\"allow_crop\">允許裁切</string>\n    <string name=\"crop_or_perspective\">裁切或透視</string>\n    <string name=\"absolute\">絕對</string>\n    <string name=\"turbo\">渦輪</string>\n    <string name=\"deep_green\">深綠色</string>\n    <string name=\"lens_correction\">鏡頭校正</string>\n    <string name=\"target_lens_profile\">JSON 格式的目標鏡頭組態檔案</string>\n    <string name=\"download_ready_lens_profiles\">下載現成的鏡頭組態檔案</string>\n    <string name=\"part_percents\">零件百分比</string>\n    <string name=\"export_as_json\">匯出為 JSON</string>\n    <string name=\"export_as_json_sub\">將帶有調色盤資料的字串複製為 json 表示形式</string>\n    <string name=\"seam_carving\">縫雕</string>\n    <string name=\"home_screen\">主畫面</string>\n    <string name=\"lock_screen\">鎖定螢幕</string>\n    <string name=\"built_in\">內建</string>\n    <string name=\"wallpapers_export\">桌布匯出</string>\n    <string name=\"refresh\">重新整理</string>\n    <string name=\"wallpapers_export_sub\">獲取當前的主頁、鎖和內建桌布</string>\n    <string name=\"allow_access_to_all_files_for_wp\">允許存取所有檔案，這是檢索桌布所必需的</string>\n    <string name=\"allow_read_media_images_for_wp\">管理外部儲存權限還不夠，您需要允許存取您的圖像，請務必選擇「允許全部」</string>\n    <string name=\"add_preset_to_filename\">將預設添加到檔名</string>\n    <string name=\"add_preset_to_filename_sub\">將帶有所選預設的尾綴附加到圖像檔名</string>\n    <string name=\"add_image_scale_mode_to_filename\">將圖像縮放模式添加到檔名</string>\n    <string name=\"add_image_scale_mode_to_filename_sub\">將具有所選圖像縮放模式的尾綴附加到圖像檔名</string>\n    <string name=\"ascii_art\">ASCII 藝術</string>\n    <string name=\"ascii_art_sub\">將圖片轉換為 ascii 文字，看起來像圖像</string>\n    <string name=\"params\">參數</string>\n    <string name=\"invert_colors_ascii_sub\">在某些情況下對圖像應用負濾鏡以獲得更好的結果</string>\n    <string name=\"processing_screenshot\">處理截圖</string>\n    <string name=\"screenshot_not_captured_try_again\">截圖未捕獲，請重試</string>\n    <string name=\"skipped_saving\">跳過保存</string>\n    <string name=\"skipped_saving_multiple\">跳過 %1$s 檔案</string>\n    <string name=\"allow_skip_if_larger\">如果較大則允許跳過</string>\n    <string name=\"allow_skip_if_larger_sub\">如果生成的檔案大小大於原始檔案大小，某些工具將被允許跳過保存圖像</string>\n    <string name=\"qr_type_calendar_event\">日曆事件</string>\n    <string name=\"qr_type_contact_info\">聯絡人</string>\n    <string name=\"qr_type_email\">電子郵件</string>\n    <string name=\"qr_type_geo_point\">地點</string>\n    <string name=\"qr_type_phone\">電話</string>\n    <string name=\"qr_type_plain\">文字</string>\n    <string name=\"qr_type_sms\">簡訊</string>\n    <string name=\"qr_type_url\">網址</string>\n    <string name=\"qr_type_wifi\">無線上網</string>\n    <string name=\"open_network\">開放網路</string>\n    <string name=\"not_specified\">不適用</string>\n    <string name=\"ssid\">SSID</string>\n    <string name=\"phone\">電話</string>\n    <string name=\"message\">訊息</string>\n    <string name=\"address\">地址</string>\n    <string name=\"subject\">主題</string>\n    <string name=\"body\">身體</string>\n    <string name=\"name\">姓名</string>\n    <string name=\"organization\">組織</string>\n    <string name=\"title\">標題</string>\n    <string name=\"phones\">電話</string>\n    <string name=\"emails\">電子郵件</string>\n    <string name=\"urls\">網址</string>\n    <string name=\"addresses\">地址</string>\n    <string name=\"summary\">概括</string>\n    <string name=\"description\">描述</string>\n    <string name=\"location\">地點</string>\n    <string name=\"organizer\">組織者</string>\n    <string name=\"start_date\">開始日期</string>\n    <string name=\"end_date\">結束日期</string>\n    <string name=\"status\">地位</string>\n    <string name=\"latitude\">緯度</string>\n    <string name=\"longitude\">經度</string>\n    <string name=\"create_barcode\">創建條碼</string>\n    <string name=\"edit_barcode\">編輯條碼</string>\n    <string name=\"wifi_configuration\">無線網路組態</string>\n    <string name=\"security\">安全</string>\n    <string name=\"pick_contact\">選擇聯絡方式</string>\n    <string name=\"grant_contact_permission\">在設定中授予聯絡人使用所選聯絡人自動填充的權限</string>\n    <string name=\"contact_info\">聯絡方式</string>\n    <string name=\"first_name\">名</string>\n    <string name=\"middle_name\">中間名</string>\n    <string name=\"last_name\">姓</string>\n    <string name=\"pronunciation\">發音</string>\n    <string name=\"add_phone\">添加電話</string>\n    <string name=\"add_email\">添加電子郵件</string>\n    <string name=\"add_address\">添加地址</string>\n    <string name=\"website\">網站</string>\n    <string name=\"add_website\">添加網站</string>\n    <string name=\"formatted_name\">格式化名稱</string>\n    <string name=\"qr_code_top_image\">該圖像將用於放置在條碼上方</string>\n    <string name=\"code_customization\">代碼定製</string>\n    <string name=\"qr_logo_image\">該圖像將用作二維碼中心的徽標</string>\n    <string name=\"logo\">標識</string>\n    <string name=\"logo_padding\">徽標填充</string>\n    <string name=\"logo_size\">標誌尺寸</string>\n    <string name=\"logo_corners\">標誌角</string>\n    <string name=\"fourth_eye\">第四隻眼</string>\n    <string name=\"fourth_eye_description\">通過在底端角添加第四隻眼睛，為二維碼添加眼睛對稱性</string>\n    <string name=\"pixel_shape\">像素形狀</string>\n    <string name=\"frame_shape\">鏡框形狀</string>\n    <string name=\"ball_shape\">球形</string>\n    <string name=\"error_correction_level\">錯誤校正等級</string>\n    <string name=\"dark_color\">深色</string>\n    <string name=\"light_color\">淺色</string>\n    <string name=\"hyper_os\">超級操作系統</string>\n    <string name=\"hyper_os_sub\">類似小米 HyperOS 的風格</string>\n    <string name=\"mask_pattern\">面具圖案</string>\n    <string name=\"code_may_be_not_scannable\">此代碼可能無法掃描，請更改外觀參數以使其在所有裝置上都可讀</string>\n    <string name=\"not_scannable\">不可掃描</string>\n    <string name=\"launcher_mode_sub\">工具將看起來像主畫面應用程式啟動器，更加緊湊</string>\n    <string name=\"launcher_mode\">啟動器模式</string>\n    <string name=\"flood_fill_sub\">使用選定的畫筆和樣式填充區域</string>\n    <string name=\"flood_fill\">洪水填充</string>\n    <string name=\"spray\">噴</string>\n    <string name=\"spray_sub\">繪製塗鴉風格的路徑</string>\n    <string name=\"square_particles\">方形顆粒</string>\n    <string name=\"square_particles_sub\">噴霧顆粒將是方形而不是圓形</string>\n    <string name=\"palette_tools\">調色盤工具</string>\n    <string name=\"palette_tools_sub\">從圖像生成基本/材質調色盤，或跨不同調色盤格式匯入/匯出</string>\n    <string name=\"edit_palette\">編輯調色盤</string>\n    <string name=\"edit_palette_sub\">跨多種格式匯出/匯入調色盤</string>\n    <string name=\"color_name\">顏色名稱</string>\n    <string name=\"palette_name\">調色盤名稱</string>\n    <string name=\"palette_format\">調色盤格式</string>\n    <string name=\"export_palette_sub\">將生成的調色盤匯出為不同的格式</string>\n    <string name=\"add_color_palette_sub\">向當前調色盤添加新顏色</string>\n    <string name=\"palette_name_not_supported\">%1$s 格式不支持提供調色盤名稱</string>\n    <string name=\"wallpapers_export_not_avaialbe\">由於 Play 商店政策，此功能無法包含在當前版本中。要存取此功能，請從其他來源下載 ImageToolbox。您可以在下面的 GitHub 上找到可用的版本。</string>\n    <string name=\"open_github_page\">開啟Github頁面</string>\n    <string name=\"overwrite_files_sub_short\">原始檔案將被新檔案替換，而不是保存在所選檔案夾中</string>\n    <string name=\"hidden_watermark_text_detected\">檢測到隱藏水印文字</string>\n    <string name=\"hidden_watermark_image_detected\">檢測到隱藏水印圖像</string>\n    <string name=\"this_image_was_hidden\">該圖片已被隱藏</string>\n    <string name=\"generative_inpaint\">生成修復</string>\n    <string name=\"generative_inpaint_sub\">允許您使用 AI 模型刪除圖像中的對象，而無需依賴 OpenCV。要使用此功能，應用程式將從 GitHub 下載所需的模型（約 200 MB）</string>\n    <string name=\"generative_inpaint_ready_sub\">允許您使用 AI 模型刪除圖像中的對象，而無需依賴 OpenCV。這可能是一個長時間運行的操作</string>\n    <string name=\"error_level_analysis\">錯誤等級分析</string>\n    <string name=\"luminance_gradient\">亮度梯度</string>\n    <string name=\"average_distance\">平均距離</string>\n    <string name=\"copy_move_detection\">複製移動檢測</string>\n    <string name=\"retain\">保持</string>\n    <string name=\"coefficent\">係數</string>\n    <string name=\"clipboard_data_is_too_large\">剪貼板資料太大</string>\n    <string name=\"data_is_too_large_to_copy\">資料太大無法複製</string>\n    <string name=\"simple_weave_pixelization\">簡單的編織像素化</string>\n    <string name=\"staggered_pixelization\">交錯像素化</string>\n    <string name=\"cross_pixelization\">交叉像素化</string>\n    <string name=\"micro_macro_pixelization\">微觀宏觀像素化</string>\n    <string name=\"orbital_pixelization\">軌道像素化</string>\n    <string name=\"vortex_pixelization\">渦旋像素化</string>\n    <string name=\"pulse_grid_pixelization\">脈衝網格像素化</string>\n    <string name=\"nucleus_pixelization\">核像素化</string>\n    <string name=\"radial_weave_pixelization\">徑向編織像素化</string>\n    <string name=\"cannot_open_uri\">無法開啟 uri \\\"%1$s\\\"</string>\n    <string name=\"snowfall_mode\">降雪模式</string>\n    <string name=\"enabled\">啟用</string>\n    <string name=\"border_frame\">邊框</string>\n    <string name=\"glitch_variant\">故障變體</string>\n    <string name=\"channel_shift\">頻道轉換</string>\n    <string name=\"max_offset\">最大偏移量</string>\n    <string name=\"vhs\">錄像帶</string>\n    <string name=\"block_glitch\">塊故障</string>\n    <string name=\"block_size\">塊大小</string>\n    <string name=\"crt_curvature\">CRT曲率</string>\n    <string name=\"curvature\">曲率</string>\n    <string name=\"chroma\">色度</string>\n    <string name=\"pixel_melt\">像素融化</string>\n    <string name=\"max_drop\">最大落差</string>\n    <string name=\"ai_tools\">人工智能工具</string>\n    <string name=\"ai_tools_sub\">通過人工智能模型處理圖像的各種工具，例如偽影消除或去噪</string>\n    <string name=\"model_anime_undeint\">壓縮、鋸齒線</string>\n    <string name=\"model_broadcast\">卡通、廣播壓縮</string>\n    <string name=\"model_rgb_max_denoise_fp16\">一般壓縮、一般噪音</string>\n    <string name=\"model_wb_denoise\">無色卡通噪音</string>\n    <string name=\"model_span_anime_pretrain\">快速、一般壓縮、一般噪音、動畫/漫畫/動漫</string>\n    <string name=\"model_book_scan\">書籍掃描</string>\n    <string name=\"model_overexposure\">曝光校正</string>\n    <string name=\"model_fbcnn_color_fp16\">最擅長一般壓縮、彩色圖像</string>\n    <string name=\"model_fbcnn_gray_fp16\">最擅長一般壓縮、灰度圖像</string>\n    <string name=\"model_fbcnn_gray_double_fp16\">一般壓縮，灰度圖像，更強</string>\n    <string name=\"model_scunet_color_gan_fp16\">一般噪聲、彩色圖像</string>\n    <string name=\"model_scunet_color_psnr_fp16\">一般噪點、彩色圖像、更好的細節</string>\n    <string name=\"model_scunet_gray_15_fp16\">一般噪聲、灰度圖像</string>\n    <string name=\"model_scunet_gray_25_fp16\">一般噪點，灰度圖像，較強</string>\n    <string name=\"model_scunet_gray_50_fp16\">一般噪聲，灰度圖像，最強</string>\n    <string name=\"model_jpeg_destroyer\">一般壓縮</string>\n    <string name=\"model_jaywreck\">一般壓縮</string>\n    <string name=\"model_h264\">紋理化、h264 壓縮</string>\n    <string name=\"model_vhs\">VHS 壓縮</string>\n    <string name=\"model_cinepak\">非標準壓縮（cinepak、msvideo1、roq）</string>\n    <string name=\"model_debink_v4\">Bink 壓縮，幾何效果更好</string>\n    <string name=\"model_debink_v5\">Bink 壓縮，更強</string>\n    <string name=\"model_debink_v6\">Bink 壓縮，柔軟，保留細節</string>\n    <string name=\"model_antialias\">消除階梯效應，平滑</string>\n    <string name=\"model_kdm_scans\">掃描藝術品/圖紙、輕度壓縮、莫爾條紋</string>\n    <string name=\"model_bandage\">色帶</string>\n    <string name=\"model_halftone\">緩慢，消除半色調</string>\n    <string name=\"model_colorizer\">用於灰度/黑白圖像的通用著色器，為了獲得更好的結果，請使用 DDColor</string>\n    <string name=\"model_deedge\">邊緣去除</string>\n    <string name=\"model_desharpen\">消除過度銳化</string>\n    <string name=\"model_dither\">緩慢、抖動</string>\n    <string name=\"model_gainres\">抗鋸齒、一般偽像、CGI</string>\n    <string name=\"model_kdm003_scans\">KDM003 掃描處理</string>\n    <string name=\"model_nmkd_jaywreck3_lite\">輕量級圖像增強模型</string>\n    <string name=\"model_bcgone_detailed_v2\">壓縮偽影去除</string>\n    <string name=\"model_bcgone_smooth\">壓縮偽影去除</string>\n    <string name=\"model_bandage_smooth\">繃帶去除效果順利</string>\n    <string name=\"model_bendel_halftone\">半色調圖案處理</string>\n    <string name=\"model_dither_deleter_v3_smooth\">抖動模式去除 V3</string>\n    <string name=\"model_jpeg_destroyer_v2\">JPEG 偽影去除 V2</string>\n    <string name=\"model_nmkd_h264_texturize\">H.264 紋理增強</string>\n    <string name=\"model_vhs_sharpen\">VHS 銳化和增強</string>\n    <string name=\"merging\">合併</string>\n    <string name=\"chunk_size\">塊大小</string>\n    <string name=\"overlap_size\">重疊尺寸</string>\n    <string name=\"note_chunk_info\">超過 %1$s 像素的圖像將被切成塊進行切片和處理，重疊混合這些以防止可見的接縫。</string>\n    <string name=\"large_chunk_warning\">大尺寸可能會導致低階裝置不穩定</string>\n    <string name=\"select_one_to_start\">選擇一個開始</string>\n    <string name=\"delete_model_sub\">您想刪除 %1$s 模型嗎？您需要重新下載</string>\n    <string name=\"confirm\">確認</string>\n    <string name=\"models\">型號</string>\n    <string name=\"downloaded_models\">下載模型</string>\n    <string name=\"available_models\">可用型號</string>\n    <string name=\"preparing\">準備中</string>\n    <string name=\"active_model\">主動模型</string>\n    <string name=\"failed_to_open_session\">無法開啟會話</string>\n    <string name=\"only_onnx_models\">只能匯入 .onnx/.ort 模型</string>\n    <string name=\"import_model\">進口型號</string>\n    <string name=\"import_model_sub\">匯入自定義onnx模型以進一步使用，僅接受 onnx/ort 模型，支持幾乎所有 esrgan 之類的變體</string>\n    <string name=\"imported_models\">進口型號</string>\n    <string name=\"model_scunet_color_15_fp16\">一般噪聲、彩色圖像</string>\n    <string name=\"model_scunet_color_25_fp16\">一般噪點，彩色圖像，較強</string>\n    <string name=\"model_scunet_color_50_fp16\">一般噪聲、彩色圖像、最強</string>\n    <string name=\"model_artifacts_dithering_alsa\">減少抖動偽影和色帶，改善平滑的漸變和平坦的顏色區域。</string>\n    <string name=\"model_nmkd_brighten_redux\">通過平衡高光增強圖像亮度和對比度，同時保留自然色彩。</string>\n    <string name=\"model_nmkd_brighten\">提亮暗圖像，同時保留細節並避免過度曝光。</string>\n    <string name=\"model_nmkd_detoon\">消除過多的色調並恢復更加中性和自然的色彩平衡。</string>\n    <string name=\"model_noise_toner_poisson_detailed\">應用基於泊松的噪聲色調，重點是保留精細的細節和紋理。</string>\n    <string name=\"model_noise_toner_poisson_soft\">應用柔和的泊松噪點色調以獲得更平滑且不那麼激進的視覺效果。</string>\n    <string name=\"model_noise_toner_uniform_detailed\">均勻的噪點色調側重於細節保留和圖像清晰度。</string>\n    <string name=\"model_noise_toner_uniform_soft\">柔和均勻的噪音色調，帶來微妙的紋理和光滑的外觀。</string>\n    <string name=\"model_repainter\">通過重新繪製偽影並提高圖像一致性來修復損壞或不均勻的區域。</string>\n    <string name=\"model_debandurh_fs_ultra_lite\">輕量級去帶模型，以最小的性能成本消除色帶。</string>\n    <string name=\"model_jpeg_0_20\">最佳化具有非常高壓縮偽影（0-20% 品質）的圖像，以提高清晰度。</string>\n    <string name=\"model_jpeg_20_40\">增強具有高壓縮偽影（20-40% 品質）的圖像，恢復細節並減少噪點。</string>\n    <string name=\"model_jpeg_40_60\">通過適度壓縮（40-60% 品質）改進圖像，平衡清晰度和平滑度。</string>\n    <string name=\"model_jpeg_60_80\">通過輕度壓縮（60-80% 品質）細化圖像，以增強微妙的細節和紋理。</string>\n    <string name=\"model_jpeg_80_100\">稍微增強近乎無損的圖像（80-100% 品質），同時保留自然的外觀和細節。</string>\n    <string name=\"model_spongecolor_lite\">著色簡單快速，卡通，不理想</string>\n    <string name=\"model_deblr\">稍微減少圖像模糊，提高清晰度，而不會引入偽影。</string>\n    <string name=\"processing_channel\">長時間運行的操作</string>\n    <string name=\"processing_image\">處理圖像</string>\n    <string name=\"processing\">加工</string>\n    <string name=\"model_artifacts_jpg_0_20\">消除品質極低的圖像 (0-20%) 中嚴重的 JPEG 壓縮偽影。</string>\n    <string name=\"model_artifacts_jpg_20_40\">減少高度壓縮圖像中強烈的 JPEG 偽影 (20-40%)。</string>\n    <string name=\"model_artifacts_jpg_40_60\">清除中等程度的 JPEG 偽影，同時保留圖像細節 (40-60%)。</string>\n    <string name=\"model_artifacts_jpg_60_80\">改善相當高品質圖像 (60-80%) 中的輕微 JPEG 偽影。</string>\n    <string name=\"model_artifacts_jpg_80_100\">巧妙地減少近乎無損圖像中的輕微 JPEG 偽影 (80-100%)。</string>\n    <string name=\"model_redetail_v2\">增強精細細節和紋理，提高感知清晰度，而不會出現嚴重偽影。</string>\n    <string name=\"processing_finished\">加工完成</string>\n    <string name=\"processing_failed\">處理失敗</string>\n    <string name=\"model_itf_skin_diffdetail_lite\">增強皮膚紋理和細節，同時保持自然外觀，最佳化速度。</string>\n    <string name=\"model_sbdv_dejpeg\">消除 JPEG 壓縮偽影並恢復壓縮照片的圖像品質。</string>\n    <string name=\"model_iso_denoise_v1\">減少在弱光條件下拍攝的照片中的 ISO 噪點，保留細節。</string>\n    <string name=\"model_dejumbo\">糾正過度曝光或「巨型」高光並恢復更好的色調平衡。</string>\n    <string name=\"model_ddcolor_tiny\">輕量級快速著色模型，為灰度圖像添加自然色彩。</string>\n    <string name=\"type_dejpeg\">DEJPEG</string>\n    <string name=\"type_denoise\">去噪</string>\n    <string name=\"type_colorize\">著色</string>\n    <string name=\"type_artifacts\">文物</string>\n    <string name=\"type_enhance\">提高</string>\n    <string name=\"type_anime\">日本動畫片</string>\n    <string name=\"type_scans\">掃描</string>\n    <string name=\"type_upscale\">高檔</string>\n    <string name=\"model_realesrgan_x4v3\">用於一般圖像的 X4 升級器；使用較少 GPU 和時間的微型模型，具有適度的去模糊和降噪功能。</string>\n    <string name=\"model_realesrgan_x2plus\">X2 放大器適用於一般圖像，保留紋理和自然細節。</string>\n    <string name=\"model_realesrgan_x4plus\">X4 升級器，適用於具有增強紋理和逼真效果的一般圖像。</string>\n    <string name=\"model_realesrgan_x4plus_anime\">X4 upscaler 針對動漫圖像進行了最佳化； 6 個 RRDB 塊，線條和細節更清晰。</string>\n    <string name=\"model_realesrnet_x4plus\">具有 MSE 損失的 X4 升頻器可產生更平滑的結果並減少一般圖像的偽影。</string>\n    <string name=\"model_realesrgan_x4plus_anime_4b32f\">X4 Upscaler 針對動漫圖像進行了最佳化； 4B32F 型號具有更銳利的細節和流暢的線條。</string>\n    <string name=\"model_ultrasharp_v2_x4\">X4 UltraSharp V2 模型，適用於一般圖像；強調銳度和清晰度。</string>\n    <string name=\"model_ultrasharp_v2_lite_x4\">X4 UltraSharp V2 Lite；更快、更小，在使用更少 GPU 記憶體的同時保留細節。</string>\n    <string name=\"model_rmbg_1_4\">用於快速背景去除的輕量級模型。平衡的性能和準確性。適用於肖像、物體和場景。推薦用於大多數用例。</string>\n    <string name=\"type_removebg\">刪除背景</string>\n    <string name=\"horizontal_border_thickness\">水平邊框厚度</string>\n    <string name=\"vertical_border_thickness\">垂直邊框厚度</string>\n    <plurals name=\"color_count\">\n        <item quantity=\"other\">%1$s 顏色</item>\n    </plurals>\n    <string name=\"current_model_not_chunkable\">當前模型不支持分塊，圖像將以原始尺寸處理，這可能會導致高記憶體消耗和低階裝置問題</string>\n    <string name=\"chunking_disabled\">禁用分塊，圖像將以原始尺寸進行處理，這可能會導致高記憶體消耗和低階裝置的問題，但可能會給出更好的推理結果</string>\n    <string name=\"chunking\">分塊</string>\n    <string name=\"model_u2net\">高精度背景去除圖像分割模型</string>\n    <string name=\"model_u2netp\">U2Net 的輕量級版本，可以以更小的記憶體使用更快地去除背景。</string>\n    <string name=\"model_ddcolor\">完整的 DDColor 模型可為一般圖像提供高品質的彩色化，且偽影最少。所有著色模型的最佳選擇。</string>\n    <string name=\"model_ddcolor_artistic\">DDColor 訓練有素的私人藝術資料集；產生多樣化和藝術化的色彩結果，減少不切實際的色彩偽影。</string>\n    <string name=\"model_birefnet\">基於 Swin Transformer 的輕量級 BiRefNet 模型，可實現準確的背景去除。</string>\n    <string name=\"model_inspyrenet\">高品質的背景去除，具有銳利的邊緣和出色的細節保留，尤其是在複雜的物體和棘手的背景上。</string>\n    <string name=\"model_isnet\">背景去除模型可產生具有平滑邊緣的精確掩模，適用於一般物體和適度的細節保留。</string>\n    <string name=\"model_already_downloaded\">模型已下載</string>\n    <string name=\"model_successfully_imported\">模型匯入成功</string>\n    <string name=\"type\">類型</string>\n    <string name=\"keyword\">關鍵詞</string>\n    <string name=\"very_fast\">非常快</string>\n    <string name=\"normal\">普通的</string>\n    <string name=\"slow\">慢的</string>\n    <string name=\"very_slow\">非常慢</string>\n    <string name=\"compute_percents\">計算百分比</string>\n    <string name=\"minimum_value_is\">最小值為 %1$s</string>\n    <string name=\"warp_sub\">用手指繪圖扭曲圖像</string>\n    <string name=\"warp\">經</string>\n    <string name=\"hardness\">硬度</string>\n    <string name=\"warp_mode\">扭曲模式</string>\n    <string name=\"warp_mode_move\">移動</string>\n    <string name=\"warp_mode_grow\">生長</string>\n    <string name=\"warp_mode_shrink\">收縮</string>\n    <string name=\"warp_mode_swirl_cw\">旋流連續波</string>\n    <string name=\"warp_mode_swirl_ccw\">逆時針旋流</string>\n    <string name=\"fade_strength\">褪色強度</string>\n    <string name=\"top_drop\">頂部落差</string>\n    <string name=\"bottom_drop\">底部下降</string>\n    <string name=\"start_drop\">開始掉落</string>\n    <string name=\"end_drop\">結束掉落</string>\n    <string name=\"downloading\">正在下載</string>\n    <string name=\"smooth_shapes\">光滑的形狀</string>\n    <string name=\"smooth_shapes_sub\">使用超橢圓代替標準圓角矩形以獲得更平滑、更自然的形狀</string>\n    <string name=\"shape_type\">形狀類型</string>\n    <string name=\"cut\">切</string>\n    <string name=\"rounded\">圓形</string>\n    <string name=\"smooth\">光滑的</string>\n    <string name=\"cut_shapes_sub\">邊緣鋒利，無倒圓角</string>\n    <string name=\"rounded_shapes_sub\">經典圓角</string>\n    <string name=\"shapes_type\">形狀類型</string>\n    <string name=\"corners_size\">邊角尺寸</string>\n    <string name=\"squircle\">松鼠</string>\n    <string name=\"squircle_shapes_sub\">優雅的圓形 UI 元素</string>\n    <string name=\"filename_format\">檔名格式</string>\n    <string name=\"prefix_pattern_description\">自定義文字放置在檔名的開頭，非常適合項目名稱、品牌或個人標籤。</string>\n    <string name=\"original_filename_pattern_description\">使用不帶副檔名的原始檔名，幫助您保持源標識完整。</string>\n    <string name=\"width_pattern_description\">圖像寬度（以像素為單位），可用於跟蹤解析度變化或縮放結果。</string>\n    <string name=\"height_pattern_description\">圖像高度（以像素為單位），在處理寬高比或匯出時很有幫助。</string>\n    <string name=\"random_numbers_pattern_description\">生成隨機數字以保證唯一的檔名；添加更多數字以提高安全性，防止重複。</string>\n    <string name=\"sequence_number_pattern_description\">用於批量匯出的自動遞增計數器，非常適合在一個會話中保存多個圖像時。</string>\n    <string name=\"preset_info_pattern_description\">將應用的預設名稱插入檔名中，以便您可以輕鬆記住圖像的處理方式。</string>\n    <string name=\"scale_mode_pattern_description\">顯示處理過程中使用的圖像縮放模式，幫助區分調整大小、裁切或擬合的圖像。</string>\n    <string name=\"suffix_pattern_description\">放置在檔名末尾的自定義文字，對於 _v2、_edited 或 _final 等版本控制很有用。</string>\n    <string name=\"extension_pattern_description\">檔案副檔名（png、jpg、webp等），自動匹配實際保存格式。</string>\n    <string name=\"formatted_timestamp_pattern_description\">可自定義的時間戳，讓您可以通過 java 規範定義自己的格式以實現完美排序。</string>\n    <string name=\"quick_stop\">快速停止</string>\n    <string name=\"snappy\">活潑</string>\n    <string name=\"adaptive\">自適應</string>\n    <string name=\"android_native_sub\">原生 Android 滾動物理</string>\n    <string name=\"smooth_sub\">平衡、平滑的滾動，適合一般用途</string>\n    <string name=\"ios_style_sub\">更高的摩擦力，類似 iOS 的滾動行為</string>\n    <string name=\"smooth_curve_sub\">獨特的樣條曲線帶來獨特的滾動感覺</string>\n    <string name=\"quick_stop_sub\">精確滾動並快速停止</string>\n    <string name=\"bouncy_sub\">有趣、反應靈敏的彈性滾動</string>\n    <string name=\"floaty_sub\">用於內容瀏覽的長滑動卷軸</string>\n    <string name=\"snappy_sub\">交互式 UI 的快速、響應式滾動</string>\n    <string name=\"ultra_smooth_sub\">優質平滑滾動，動力強勁</string>\n    <string name=\"adaptive_sub\">根據投擲速度調整物理</string>\n    <string name=\"accessibility_aware_sub\">尊重系統輔助功能設定</string>\n    <string name=\"reduced_motion_sub\">滿足無障礙需求的最小運動</string>\n    <string name=\"fling_type\">投擲型</string>\n    <string name=\"android_native\">Android 原生</string>\n    <string name=\"ios_style\">iOS 風格</string>\n    <string name=\"smooth_curve\">平滑曲線</string>\n    <string name=\"bouncy\">彈力</string>\n    <string name=\"floaty\">飄逸</string>\n    <string name=\"ultra_smooth\">超光滑</string>\n    <string name=\"accessibility_aware\">無障礙意識</string>\n    <string name=\"reduced_motion\">減少運動</string>\n    <string name=\"primary_lines\">主要線路</string>\n    <string name=\"primary_lines_sub\">每五行添加較粗的線</string>\n    <string name=\"fill_color\">填充顏色</string>\n    <string name=\"hidden_tools\">隱藏工具</string>\n    <string name=\"hidden_for_share\">隱藏共享工具</string>\n    <string name=\"color_library\">顏色庫</string>\n    <string name=\"color_library_sub\">瀏覽大量顏色</string>\n    <string name=\"model_fatality_deblur\">銳化並消除圖像模糊，同時保持自然細節，是修復失焦照片的理想選擇。</string>\n    <string name=\"model_unresize_v3\">智能恢復之前調整過大小的圖像，恢復丟失的細節和紋理。</string>\n    <string name=\"model_liveaction_v1_span\">針對真人內容進行了最佳化，減少了壓縮偽影並增強了電影/電視節目幀中的精細細節。</string>\n    <string name=\"model_vhs2hd_realplksr\">將 VHS 品質的素材轉換為高清，消除磁帶噪音並提高解析度，同時保留復古感。</string>\n    <string name=\"model_text2hd_v1\">專門用於文字較多的圖像和屏幕截圖，銳化字符並提高可讀性。</string>\n    <string name=\"model_frankendata_pretrainer\">在不同資料集上進行高級升級訓練，非常適合通用照片增強。</string>\n    <string name=\"model_realwebphoto_v2\">針對網路壓縮照片進行了最佳化，消除了 JPEG 偽影並恢復自然外觀。</string>\n    <string name=\"model_realwebphoto_v4\">網頁照片的改進版本，具有更好的紋理保留和偽影減少。</string>\n    <string name=\"model_dat_2x\">使用雙聚合變壓器技術進行 2 倍升級，保持清晰度和自然細節。</string>\n    <string name=\"model_dat_3x\">使用先進的變壓器架構進行 3 倍放大，非常適合中等放大需求。</string>\n    <string name=\"model_dat_4x\">通過最先進的變壓器網路進行 4 倍高品質放大，在更大的尺度上保留精細細節。</string>\n    <string name=\"model_nafnet_deblurring\">消除照片中的模糊/噪點和抖動。通用但最適合照片。</string>\n    <string name=\"model_swin2sr_x4_bsrgan_psnr\">使用 Swin2SR 轉換器恢復低品質圖像，並針對 BSRGAN 退化進行了最佳化。非常適合修復嚴重的壓縮偽影並以 4 倍比例增強細節。</string>\n    <string name=\"model_bsrgan_swinir_m_x4_gan\">使用經過 BSRGAN 退化訓練的 SwinIR 變壓器進行 4 倍升級。使用 GAN 在照片和複雜場景中獲得更清晰的紋理和更自然的細節。</string>\n    <string name=\"path\">小路</string>\n    <string name=\"merge_pdf\">合併PDF</string>\n    <string name=\"merge_pdf_sub\">將多個 PDF 檔案合併為一個文件</string>\n    <string name=\"files_order\">檔案順序</string>\n    <string name=\"pages_short\">頁數</string>\n    <string name=\"split_pdf\">分割 PDF</string>\n    <string name=\"split_pdf_sub\">從 PDF 文件中提取特定頁面</string>\n    <string name=\"rotate_pdf\">旋轉 PDF</string>\n    <string name=\"rotate_pdf_sub\">永久修復頁面方向</string>\n    <string name=\"pages\">頁數</string>\n    <string name=\"rearrange_pdf\">重新排列 PDF</string>\n    <string name=\"rearrange_pdf_sub\">拖放頁面以重新排序</string>\n    <string name=\"hold_drag_drop\">按住並拖動頁面</string>\n    <string name=\"page_numbers\">頁碼</string>\n    <string name=\"page_numbers_sub\">自動為您的文件添加編號</string>\n    <string name=\"label_format\">標籤格式</string>\n    <string name=\"pdf_to_text\">PDF 轉文字 (OCR)</string>\n    <string name=\"pdf_to_text_sub\">從 PDF 文件中提取純文字</string>\n    <string name=\"watermark_pdf_sub\">覆蓋自定義文字以實現品牌或安全</string>\n    <string name=\"signature\">簽名</string>\n    <string name=\"signature_sub\">將您的電子簽名添加到任何文件中</string>\n    <string name=\"will_be_for_signature\">這將用作簽名</string>\n    <string name=\"unlock_pdf\">解鎖 PDF</string>\n    <string name=\"unlock_pdf_sub\">從受保護的檔案中刪除密碼</string>\n    <string name=\"protect_pdf\">保護 PDF</string>\n    <string name=\"protect_pdf_sub\">通過強大的加密保護您的文件</string>\n    <string name=\"success\">成功</string>\n    <string name=\"pdf_unlocked\">PDF 已解鎖，您可以保存或分享</string>\n    <string name=\"repair_pdf\">修復 PDF</string>\n    <string name=\"repair_pdf_sub\">嘗試修復損壞或無法讀取的文件</string>\n    <string name=\"grayscale\">灰度</string>\n    <string name=\"grayscale_pdf_sub\">將所有文件嵌入圖像轉換為灰度</string>\n    <string name=\"compress_pdf\">壓縮PDF</string>\n    <string name=\"compress_pdf_sub\">最佳化文件檔案大小以方便共享</string>\n    <string name=\"repair_info\">ImageToolbox 重建內部交叉引用表並從頭開始重新生成檔案結構。這可以恢復對許多「無法開啟」檔案的存取</string>\n    <string name=\"grayscale_info\">該工具將所有文件圖像轉換為灰度。最適合列印和減小檔案大小</string>\n    <string name=\"metadata\">詮釋資料</string>\n    <string name=\"metadata_pdf_sub\">編輯文件屬性以獲得更好的隱私</string>\n    <string name=\"tags\">標籤</string>\n    <string name=\"producer\">製片人</string>\n    <string name=\"author\">作者</string>\n    <string name=\"keywords\">關鍵詞</string>\n    <string name=\"creator\">創作者</string>\n    <string name=\"privacy_deep_clean\">隱私深度清潔</string>\n    <string name=\"privacy_deep_clean_sub\">清除該文件的所有可用詮釋資料</string>\n    <string name=\"page\">頁</string>\n    <string name=\"deep_ocr\">深度 OCR</string>\n    <string name=\"deep_ocr_sub\">使用 Tesseract 引擎從文件中提取文字並將其儲存在一個文字檔案中</string>\n    <string name=\"cant_remove_all\">無法刪除所有頁面</string>\n    <string name=\"remove_pages_pdf\">刪除 PDF 頁面</string>\n    <string name=\"remove_pages_pdf_sub\">從 PDF 文件中刪除特定頁面</string>\n    <string name=\"tap_to_remove\">點擊刪除</string>\n    <string name=\"manually\">手動</string>\n    <string name=\"crop_pdf\">裁切 PDF</string>\n    <string name=\"crop_pdf_sub\">將文件頁面裁切到任意範圍</string>\n    <string name=\"flatten_pdf\">拼合 PDF</string>\n    <string name=\"flatten_pdf_sub\">通過光柵化文件頁面使 PDF 不可修改</string>\n    <string name=\"camera_failed_to_open\">無法啟動相機。請檢查權限並確保它未被其他應用程式使用。</string>\n    <string name=\"extract_images\">提取圖像</string>\n    <string name=\"extract_images_sub\">以原始解析度提取 PDF 中嵌入的圖像</string>\n    <string name=\"pdf_no_embedded\">此 PDF 檔案不包含任何嵌入圖像</string>\n    <string name=\"extract_images_info\">該工具掃描每一頁並恢復全品質源圖像 - 非常適合保存文件中的原件</string>\n    <string name=\"draw_signature\">簽名</string>\n    <string name=\"pen_params\">筆參數</string>\n    <string name=\"draw_signature_sub\">使用自己的簽名作為圖像放置在文件上</string>\n    <string name=\"zip_pdf\">壓縮 PDF</string>\n    <string name=\"zip_pdf_sub\">以給定的間隔分割文件並將新文件打包到 zip 存檔中</string>\n    <string name=\"interval\">間隔</string>\n    <string name=\"print_pdf\">列印 PDF</string>\n    <string name=\"print_pdf_sub\">準備用於使用自定義頁面尺寸列印的文件</string>\n    <string name=\"pages_per_sheet\">每張頁數</string>\n    <string name=\"orientation\">方向</string>\n    <string name=\"page_size\">頁面尺寸</string>\n    <string name=\"margin\">利潤</string>\n    <string name=\"bloom\">盛開</string>\n    <string name=\"soft_knee\">軟膝</string>\n    <string name=\"model_realesr_animevideo_v3x4\">針對動漫和卡通進行了最佳化。快速升級，改善自然色彩並減少偽影</string>\n    <string name=\"one_ui_sub\">类似三星 One UI 7 的风格</string>\n    <string name=\"calculate_hint\">在此输入基本数学符号以计算所需的值（例如（5+5）*10）</string>\n    <string name=\"math_expression\">数学表达式</string>\n    <string name=\"pick_up_to_n_collage_images\">选取最多 %1$s 张图片</string>\n    <string name=\"keep_date_time\">保留日期时间</string>\n    <string name=\"keep_date_time_sub\">始终保留与日期和时间相关的 exif 标签，独立于 keep exif 选项</string>\n    <string name=\"background_color_for_alpha_formats\">Alpha 格式的背景颜色</string>\n    <string name=\"background_color_for_alpha_formats_sub\">增加了为每种具有 Alpha 支持的图像格式设置背景颜色的功能，禁用后，此功能仅适用于非 Alpha 格式</string>\n    <string name=\"open_markup_project\">打开项目</string>\n    <string name=\"open_markup_project_sub\">继续编辑之前保存的 Image Toolbox 项目</string>\n    <string name=\"markup_project_open_failed\">无法打开图像工具箱项目</string>\n    <string name=\"markup_project_missing_data\">Image Toolbox 项目缺少项目数据</string>\n    <string name=\"markup_project_corrupted\">图像工具箱项目已损坏</string>\n    <string name=\"unsupported_markup_project_version\">不受支持的 Image Toolbox 项目版本：%1$d</string>\n    <string name=\"save_markup_project\">保存项目</string>\n    <string name=\"save_markup_project_sub\">将图层、背景和编辑历史记录存储在可编辑的项目文件中</string>\n    <string name=\"failed_to_open\">打开失败</string>\n    <string name=\"ocr_write_to_searchable_pdf\">写入可搜索的 PDF</string>\n    <string name=\"ocr_write_to_searchable_pdf_sub\">从图像批次中识别文本并保存带有图像和可选文本层的可搜索 PDF</string>\n    <string name=\"layer_alpha\">阿尔法层</string>\n    <string name=\"horizontal_flip\">水平翻转</string>\n    <string name=\"vertical_flip\">垂直翻转</string>\n    <string name=\"lock\">锁</string>\n    <string name=\"add_shadow\">添加阴影</string>\n    <string name=\"shadow_color\">阴影颜色</string>\n    <string name=\"text_geometry\">文本几何</string>\n    <string name=\"text_geometry_sub\">拉伸或倾斜文本以获得更清晰的风格</string>\n    <string name=\"scale_x\">规模 X</string>\n    <string name=\"skew_x\">倾斜 X</string>\n    <string name=\"remove_annotations\">删除注释</string>\n    <string name=\"remove_annotations_sub\">从 PDF 页面中删除选定的注释类型，例如链接、注释、突出显示、形状或表单字段</string>\n    <string name=\"annotation_link\">超链接</string>\n    <string name=\"annotation_file_attachment\">文件附件</string>\n    <string name=\"annotation_line\">线路</string>\n    <string name=\"annotation_popup\">弹出窗口</string>\n    <string name=\"annotation_stamp\">邮票</string>\n    <string name=\"annotation_shapes\">形状</string>\n    <string name=\"annotation_text\">文字注释</string>\n    <string name=\"annotation_text_markup\">文本标记</string>\n    <string name=\"annotation_widget\">表单字段</string>\n    <string name=\"annotation_markup\">标记</string>\n    <string name=\"annotation_unknown\">未知</string>\n    <string name=\"annotations\">注释</string>\n    <string name=\"ungroup\">取消分组</string>\n    <string name=\"add_shadow_sub\">使用可配置的颜色和偏移在图层后面添加模糊阴影</string>\n</resources>"
  },
  {
    "path": "core/resources/src/main/res/xml/backup_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<!--\n   Sample backup rules file; uncomment and customize as necessary.\n   See https://developer.android.com/guide/topics/data/autobackup\n   for details.\n   Note: This file is ignored for devices older that API 31\n   See https://developer.android.com/about/versions/12/backup-restore\n-->\n<full-backup-content>\n    <include\n        domain=\"file\"\n        path=\"datastore/.\" />\n</full-backup-content>"
  },
  {
    "path": "core/resources/src/main/res/xml/data_extraction_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<!--\n   Sample data extraction rules file; uncomment and customize as necessary.\n   See https://developer.android.com/about/versions/12/backup-restore#xml-changes\n   for details.\n-->\n<data-extraction-rules>\n    <cloud-backup>\n        <!--\n        <include …/>\n        <exclude …/>\n        -->\n    </cloud-backup>\n    <!--\n    <device-transfer>\n        <include …/>\n        <exclude …/>\n    </device-transfer>\n    -->\n</data-extraction-rules>"
  },
  {
    "path": "core/resources/src/main/res/xml/file_paths.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <paths>\n        <cache-path\n            name=\"shared_images\"\n            path=\"/\" />\n        <files-path\n            name=\"files\"\n            path=\"/\" />\n    </paths>\n</resources>"
  },
  {
    "path": "core/settings/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/settings/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.settings\"\n\ndependencies {\n    implementation(libs.datastore.preferences.android)\n    implementation(libs.datastore.core.android)\n    implementation(libs.kotlinx.collections.immutable)\n    implementation(libs.coil)\n\n    implementation(projects.lib.dynamicTheme)\n    implementation(projects.core.domain)\n    implementation(projects.core.resources)\n    implementation(projects.core.di)\n}"
  },
  {
    "path": "core/settings/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/di/SettingsStateEntryPoint.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.di\n\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport dagger.hilt.EntryPoint\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\n\n@EntryPoint\n@InstallIn(SingletonComponent::class)\ninterface SettingsStateEntryPoint {\n    val settingsManager: SettingsManager\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/SettingsInteractor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.model.PerformanceClass\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ColorHarmonizer\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.DomainFontFamily\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.NightMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType\n\ninterface SettingsInteractor : SimpleSettingsInteractor {\n\n    suspend fun toggleAddSequenceNumber()\n\n    suspend fun toggleAddOriginalFilename()\n\n    suspend fun setEmojisCount(count: Int)\n\n    suspend fun setImagePickerMode(mode: Int)\n\n    suspend fun toggleAddFileSize()\n\n    suspend fun setEmoji(emoji: Int)\n\n    suspend fun setFilenamePrefix(name: String)\n\n    suspend fun toggleShowUpdateDialogOnStartup()\n\n    suspend fun setColorTuple(colorTuple: String)\n\n    suspend fun setPresets(newPresets: List<Int>)\n\n    suspend fun toggleDynamicColors()\n\n    override suspend fun setBorderWidth(width: Float)\n\n    suspend fun toggleAllowImageMonet()\n\n    suspend fun toggleAmoledMode()\n\n    suspend fun setNightMode(nightMode: NightMode)\n\n    suspend fun setSaveFolderUri(uri: String?)\n\n    suspend fun setColorTuples(colorTuples: String)\n\n    suspend fun setAlignment(align: Int)\n\n    suspend fun setScreenOrder(data: String)\n\n    suspend fun toggleClearCacheOnLaunch()\n\n    suspend fun toggleGroupOptionsByTypes()\n\n    suspend fun toggleRandomizeFilename()\n\n    suspend fun createBackupFile(): ByteArray\n\n    suspend fun restoreFromBackupFile(\n        backupFileUri: String,\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit,\n    )\n\n    suspend fun resetSettings()\n\n    fun createBackupFilename(): String\n\n    suspend fun setFont(font: DomainFontFamily)\n\n    suspend fun setFontScale(scale: Float)\n\n    suspend fun toggleAllowCrashlytics()\n\n    suspend fun toggleAllowAnalytics()\n\n    suspend fun toggleAllowBetas()\n\n    suspend fun toggleDrawContainerShadows()\n\n    suspend fun toggleDrawButtonShadows()\n\n    suspend fun toggleDrawSliderShadows()\n\n    suspend fun toggleDrawSwitchShadows()\n\n    suspend fun toggleDrawFabShadows()\n\n    suspend fun toggleLockDrawOrientation()\n\n    suspend fun setThemeStyle(value: Int)\n\n    suspend fun setThemeContrast(value: Double)\n\n    suspend fun toggleInvertColors()\n\n    suspend fun toggleScreensSearchEnabled()\n\n    suspend fun toggleDrawAppBarShadows()\n\n    suspend fun setCopyToClipboardMode(copyToClipboardMode: CopyToClipboardMode)\n\n    suspend fun setVibrationStrength(strength: Int)\n\n    suspend fun setFilenameSuffix(name: String)\n\n    suspend fun setDefaultImageScaleMode(imageScaleMode: ImageScaleMode)\n\n    suspend fun toggleExifWidgetInitialState()\n\n    suspend fun setInitialOCRLanguageCodes(list: List<String>)\n\n    suspend fun setScreensWithBrightnessEnforcement(data: List<Int>)\n\n    suspend fun toggleConfettiEnabled()\n\n    suspend fun toggleSecureMode()\n\n    suspend fun toggleUseRandomEmojis()\n\n    suspend fun setIconShape(iconShape: Int)\n\n    suspend fun toggleUseEmojiAsPrimaryColor()\n\n    suspend fun setDragHandleWidth(width: Int)\n\n    suspend fun setConfettiType(type: Int)\n\n    suspend fun toggleAllowAutoClipboardPaste()\n\n    suspend fun setConfettiHarmonizer(colorHarmonizer: ColorHarmonizer)\n\n    suspend fun setConfettiHarmonizationLevel(level: Float)\n\n    suspend fun toggleGeneratePreviews()\n\n    suspend fun toggleSkipImagePicking()\n\n    suspend fun toggleShowSettingsInLandscape()\n\n    suspend fun toggleUseFullscreenSettings()\n\n    suspend fun setSwitchType(type: SwitchType)\n\n    suspend fun setDefaultDrawLineWidth(value: Float)\n\n    suspend fun toggleOpenEditInsteadOfPreview()\n\n    suspend fun toggleCanEnterPresetsByTextField()\n\n    suspend fun adjustPerformance(performanceClass: PerformanceClass)\n\n    suspend fun registerDonateDialogOpen()\n\n    suspend fun setNotShowDonateDialogAgain()\n\n    suspend fun setColorBlindType(value: Int?)\n\n    suspend fun toggleFavoriteScreen(screenId: Int)\n\n    suspend fun toggleIsLinkPreviewEnabled()\n\n    suspend fun setDefaultDrawColor(color: ColorModel)\n\n    suspend fun setDefaultDrawPathMode(modeOrdinal: Int)\n\n    suspend fun toggleAddTimestampToFilename()\n\n    suspend fun toggleUseFormattedFilenameTimestamp()\n\n    suspend fun registerTelegramGroupOpen()\n\n    suspend fun setDefaultResizeType(resizeType: ResizeType)\n\n    suspend fun setSystemBarsVisibility(systemBarsVisibility: SystemBarsVisibility)\n\n    suspend fun toggleIsSystemBarsVisibleBySwipe()\n\n    suspend fun setInitialOcrMode(mode: Int)\n\n    suspend fun toggleUseCompactSelectorsLayout()\n\n    suspend fun setMainScreenTitle(title: String)\n\n    suspend fun setSliderType(type: SliderType)\n\n    suspend fun toggleIsCenterAlignDialogButtons()\n\n    suspend fun setFastSettingsSide(side: FastSettingsSide)\n\n    suspend fun setChecksumTypeForFilename(type: HashingType?)\n\n    suspend fun setCustomFonts(fonts: List<DomainFontFamily.Custom>)\n\n    suspend fun importCustomFont(uri: String): DomainFontFamily.Custom?\n\n    suspend fun removeCustomFont(font: DomainFontFamily.Custom)\n\n    suspend fun createCustomFontsExport(): String?\n\n    suspend fun toggleEnableToolExitConfirmation()\n\n    suspend fun createLogsExport(): String\n\n    suspend fun toggleAddPresetInfoToFilename()\n\n    suspend fun toggleAddImageScaleModeInfoToFilename()\n\n    suspend fun toggleAllowSkipIfLarger()\n\n    suspend fun toggleIsScreenSelectionLauncherMode()\n\n    suspend fun setSnowfallMode(snowfallMode: SnowfallMode)\n\n    suspend fun setDefaultImageFormat(imageFormat: ImageFormat?)\n\n    suspend fun setDefaultQuality(quality: Quality)\n\n    suspend fun setShapesType(shapeType: ShapeType)\n\n    suspend fun setFilenamePattern(pattern: String?)\n\n    suspend fun setFlingType(type: FlingType)\n\n    suspend fun setHiddenForShareScreens(data: List<Int>)\n\n    suspend fun toggleKeepDateTime()\n\n    suspend fun toggleEnableBackgroundColorForAlphaFormats()\n\n}\n\nfun SettingsInteractor.toSimpleSettingsInteractor(): SimpleSettingsInteractor =\n    object : SimpleSettingsInteractor by this {}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/SettingsManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain\n\ninterface SettingsManager : SettingsProvider, SettingsInteractor"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/SettingsProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain\n\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport kotlinx.coroutines.flow.StateFlow\n\ninterface SettingsProvider {\n\n    val settingsState: StateFlow<SettingsState>\n\n    suspend fun getSettingsState(): SettingsState\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/SimpleSettingsInteractor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation\n\ninterface SimpleSettingsInteractor {\n\n    suspend fun toggleMagnifierEnabled()\n\n    suspend fun setOneTimeSaveLocations(value: List<OneTimeSaveLocation>)\n\n    suspend fun toggleRecentColor(\n        color: ColorModel,\n        forceExclude: Boolean = false\n    )\n\n    suspend fun toggleFavoriteColor(\n        color: ColorModel,\n        forceExclude: Boolean = true\n    )\n\n    fun isInstalledFromPlayStore(): Boolean\n\n    suspend fun toggleSettingsGroupVisibility(\n        key: Int,\n        value: Boolean\n    )\n\n    suspend fun clearRecentColors()\n\n    suspend fun updateFavoriteColors(\n        colors: List<ColorModel>\n    )\n\n    suspend fun setBackgroundColorForNoAlphaFormats(\n        color: ColorModel\n    )\n\n    suspend fun toggleCustomAsciiGradient(gradient: String)\n\n    suspend fun toggleOverwriteFiles()\n\n    suspend fun setSpotHealMode(mode: Int)\n\n    suspend fun setBorderWidth(width: Float)\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/ColorHarmonizer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed class ColorHarmonizer(\n    val ordinal: Int\n) {\n    data class Custom(\n        val color: Int\n    ) : ColorHarmonizer(color)\n\n    data object Primary : ColorHarmonizer(1)\n    data object Secondary : ColorHarmonizer(2)\n    data object Tertiary : ColorHarmonizer(3)\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                Primary,\n                Secondary,\n                Tertiary,\n                Custom(0)\n            )\n        }\n\n        fun fromInt(ordinal: Int) = when (ordinal) {\n            1 -> Primary\n            2 -> Secondary\n            3 -> Tertiary\n            else -> Custom(ordinal)\n        }\n    }\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/CopyToClipboardMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed class CopyToClipboardMode(\n    open val value: Int\n) {\n\n    data object Disabled : CopyToClipboardMode(0)\n\n    sealed class Enabled(\n        override val value: Int\n    ) : CopyToClipboardMode(value) {\n        data object WithoutSaving : Enabled(1)\n        data object WithSaving : Enabled(2)\n    }\n\n    companion object {\n        fun fromInt(\n            value: Int\n        ): CopyToClipboardMode = when (value) {\n            1 -> Enabled.WithoutSaving\n            2 -> Enabled.WithSaving\n            else -> Disabled\n        }\n    }\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/DomainFontFamily.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"SpellCheckingInspection\")\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed class DomainFontFamily(val ordinal: Int) {\n    data object Montserrat : DomainFontFamily(1)\n    data object Caveat : DomainFontFamily(2)\n    data object Comfortaa : DomainFontFamily(3)\n    data object Handjet : DomainFontFamily(4)\n    data object YsabeauSC : DomainFontFamily(5)\n    data object Jura : DomainFontFamily(6)\n    data object Podkova : DomainFontFamily(7)\n    data object Tektur : DomainFontFamily(8)\n    data object DejaVu : DomainFontFamily(9)\n    data object BadScript : DomainFontFamily(10)\n    data object RuslanDisplay : DomainFontFamily(11)\n    data object Catterdale : DomainFontFamily(12)\n    data object FRM32 : DomainFontFamily(13)\n    data object TokeelyBrookings : DomainFontFamily(14)\n    data object Nunito : DomainFontFamily(15)\n    data object Nothing : DomainFontFamily(16)\n    data object WOPRTweaked : DomainFontFamily(17)\n    data object AlegreyaSans : DomainFontFamily(18)\n    data object MinecraftGnu : DomainFontFamily(19)\n    data object GraniteFixed : DomainFontFamily(20)\n    data object NokiaPixel : DomainFontFamily(21)\n    data object Ztivalia : DomainFontFamily(22)\n    data object Axotrel : DomainFontFamily(23)\n    data object LcdOctagon : DomainFontFamily(24)\n    data object LcdMoving : DomainFontFamily(25)\n    data object Unisource : DomainFontFamily(26)\n    data object System : DomainFontFamily(0)\n\n    class Custom(\n        val name: String?,\n        val filePath: String\n    ) : DomainFontFamily(-1) {\n        override fun asString(): String = \"$name:$filePath\"\n\n        override fun equals(other: Any?): Boolean {\n            if (other !is Custom) return false\n\n            return filePath == other.filePath\n        }\n\n        override fun hashCode(): Int {\n            return filePath.hashCode()\n        }\n\n        override fun toString(): String {\n            return \"Custom(name = $name, filePath = $filePath)\"\n        }\n    }\n\n    open fun asString(): String = ordinal.toString()\n\n    companion object {\n        fun fromString(string: String?): DomainFontFamily? {\n            val int = string?.toIntOrNull()\n\n            val family = when (int) {\n                0 -> System\n                1 -> Montserrat\n                2 -> Caveat\n                3 -> Comfortaa\n                4 -> Handjet\n                5 -> YsabeauSC\n                6 -> Jura\n                7 -> Podkova\n                8 -> Tektur\n                9 -> DejaVu\n                10 -> BadScript\n                11 -> RuslanDisplay\n                12 -> Catterdale\n                13 -> FRM32\n                14 -> TokeelyBrookings\n                15 -> Nunito\n                16 -> Nothing\n                17 -> WOPRTweaked\n                18 -> AlegreyaSans\n                19 -> MinecraftGnu\n                20 -> GraniteFixed\n                21 -> NokiaPixel\n                22 -> Ztivalia\n                23 -> Axotrel\n                24 -> LcdOctagon\n                25 -> LcdMoving\n                26 -> Unisource\n                else -> null\n            }\n\n            return family ?: string?.split(\":\")?.let {\n                Custom(\n                    name = it[0],\n                    filePath = it[1]\n                )\n            }\n        }\n    }\n}\n\nsealed interface FontType {\n    data class Resource(val resId: Int) : FontType\n    data class File(val path: String) : FontType\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/FastSettingsSide.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed class FastSettingsSide(\n    val ordinal: Int\n) {\n\n    data object None : FastSettingsSide(0)\n\n    data object CenterEnd : FastSettingsSide(1)\n\n    data object CenterStart : FastSettingsSide(2)\n\n    companion object {\n\n        val entries: List<FastSettingsSide> by lazy {\n            listOf(\n                None,\n                CenterEnd,\n                CenterStart\n            )\n        }\n\n        fun fromOrdinal(ordinal: Int?): FastSettingsSide? = ordinal?.let(entries::getOrNull)\n    }\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/FilenameBehavior.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\n\nsealed interface FilenameBehavior {\n    class None : FilenameBehavior\n\n    class Overwrite : FilenameBehavior\n\n    class Random : FilenameBehavior\n\n    data class Checksum(\n        val hashingType: HashingType\n    ) : FilenameBehavior\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/FlingType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nenum class FlingType {\n    DEFAULT,\n    SMOOTH,\n    IOS_STYLE,\n    SMOOTH_CURVE,\n    QUICK_STOP,\n    BOUNCY,\n    FLOATY,\n    SNAPPY,\n    ULTRA_SMOOTH,\n    ADAPTIVE,\n    ACCESSIBILITY_AWARE,\n    REDUCED_MOTION\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/NightMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed class NightMode(val ordinal: Int) {\n    data object Light : NightMode(0)\n    data object Dark : NightMode(1)\n    data object System : NightMode(2)\n\n    companion object {\n        fun fromOrdinal(int: Int?): NightMode? = when (int) {\n            0 -> Light\n            1 -> Dark\n            2 -> System\n            else -> null\n        }\n    }\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/OneTimeSaveLocation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\ndata class OneTimeSaveLocation(\n    val uri: String,\n    val date: Long?,\n    val count: Int\n) {\n\n    override fun toString(): String {\n        return listOf(uri, date, count).joinToString(delimiter)\n    }\n\n    companion object {\n        fun fromString(string: String): OneTimeSaveLocation? {\n            val data = string.split(delimiter)\n            val uri = data.getOrNull(0) ?: return null\n            val date = data.getOrNull(1)?.toLongOrNull()\n            val count = data.getOrNull(2)?.toIntOrNull() ?: 0\n\n            return OneTimeSaveLocation(uri, date, count)\n        }\n    }\n\n}\n\nprivate const val delimiter = \"\\n\""
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/SettingsState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset.Percentage\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.domain.utils.Flavor\n\ndata class SettingsState(\n    val nightMode: NightMode,\n    val isDynamicColors: Boolean,\n    val allowChangeColorByImage: Boolean,\n    val emojisCount: Int,\n    val isAmoledMode: Boolean,\n    val appColorTuple: String,\n    val borderWidth: Float,\n    val presets: List<Preset>,\n    val aspectRatios: List<DomainAspectRatio>,\n    val fabAlignment: Int,\n    val selectedEmoji: Int?,\n    val picturePickerModeInt: Int,\n    val clearCacheOnLaunch: Boolean,\n    val showUpdateDialogOnStartup: Boolean,\n    val groupOptionsByTypes: Boolean,\n    val screenList: List<Int>,\n    val colorTupleList: String?,\n    val addSequenceNumber: Boolean,\n    val saveFolderUri: String?,\n    val filenamePrefix: String,\n    val addSizeInFilename: Boolean,\n    val addOriginalFilename: Boolean,\n    val font: DomainFontFamily,\n    val fontScale: Float?,\n    val allowCollectCrashlytics: Boolean,\n    val allowCollectAnalytics: Boolean,\n    val allowBetas: Boolean,\n    val drawContainerShadows: Boolean,\n    val drawButtonShadows: Boolean,\n    val drawSliderShadows: Boolean,\n    val drawSwitchShadows: Boolean,\n    val drawFabShadows: Boolean,\n    val drawAppBarShadows: Boolean,\n    val appOpenCount: Int,\n    val lockDrawOrientation: Boolean,\n    val themeContrastLevel: Double,\n    val themeStyle: Int,\n    val isInvertThemeColors: Boolean,\n    val screensSearchEnabled: Boolean,\n    val copyToClipboardMode: CopyToClipboardMode,\n    val hapticsStrength: Int,\n    val filenameSuffix: String,\n    val defaultImageScaleMode: ImageScaleMode,\n    val magnifierEnabled: Boolean,\n    val exifWidgetInitialState: Boolean,\n    val initialOcrCodes: List<String>,\n    val screenListWithMaxBrightnessEnforcement: List<Int>,\n    val isConfettiEnabled: Boolean,\n    val isSecureMode: Boolean,\n    val useRandomEmojis: Boolean,\n    val iconShape: Int?,\n    val useEmojiAsPrimaryColor: Boolean,\n    val dragHandleWidth: Int,\n    val confettiType: Int,\n    val allowAutoClipboardPaste: Boolean,\n    val confettiColorHarmonizer: ColorHarmonizer,\n    val confettiHarmonizationLevel: Float,\n    val skipImagePicking: Boolean,\n    val generatePreviews: Boolean,\n    val showSettingsInLandscape: Boolean,\n    val useFullscreenSettings: Boolean,\n    val switchType: SwitchType,\n    val defaultDrawLineWidth: Float,\n    val oneTimeSaveLocations: List<OneTimeSaveLocation>,\n    val openEditInsteadOfPreview: Boolean,\n    val canEnterPresetsByTextField: Boolean,\n    val donateDialogOpenCount: Int,\n    val colorBlindType: Int?,\n    val favoriteScreenList: List<Int>,\n    val isLinkPreviewEnabled: Boolean,\n    val defaultDrawColor: ColorModel,\n    val defaultDrawPathMode: Int,\n    val addTimestampToFilename: Boolean,\n    val useFormattedFilenameTimestamp: Boolean,\n    val favoriteColors: List<ColorModel>,\n    val defaultResizeType: ResizeType,\n    val systemBarsVisibility: SystemBarsVisibility,\n    val isSystemBarsVisibleBySwipe: Boolean,\n    val isCompactSelectorsLayout: Boolean,\n    val mainScreenTitle: String,\n    val sliderType: SliderType,\n    val isCenterAlignDialogButtons: Boolean,\n    val fastSettingsSide: FastSettingsSide,\n    val settingGroupsInitialVisibility: Map<Int, Boolean>,\n    val customFonts: List<DomainFontFamily.Custom>,\n    val enableToolExitConfirmation: Boolean,\n    val recentColors: List<ColorModel>,\n    val backgroundForNoAlphaImageFormats: ColorModel,\n    val addPresetInfoToFilename: Boolean,\n    val addImageScaleModeInfoToFilename: Boolean,\n    val allowSkipIfLarger: Boolean,\n    val customAsciiGradients: Set<String>,\n    val isScreenSelectionLauncherMode: Boolean,\n    val isTelegramGroupOpened: Boolean,\n    val initialOcrMode: Int,\n    val spotHealMode: Int,\n    val snowfallMode: SnowfallMode,\n    val defaultImageFormat: ImageFormat?,\n    val defaultQuality: Quality,\n    val shapesType: ShapeType,\n    val filenamePattern: String?,\n    val filenameBehavior: FilenameBehavior,\n    val flingType: FlingType,\n    val hiddenForShareScreens: List<Int>,\n    val keepDateTime: Boolean,\n    val enableBackgroundColorForAlphaFormats: Boolean,\n) {\n\n    companion object {\n        val Default by lazy {\n            SettingsState(\n                nightMode = NightMode.System,\n                isDynamicColors = true,\n                allowChangeColorByImage = true,\n                emojisCount = 1,\n                isAmoledMode = false,\n                appColorTuple = \"\",\n                borderWidth = -1f,\n                presets = List(6) { Percentage(100 - it * 10) },\n                fabAlignment = 1,\n                selectedEmoji = 0,\n                picturePickerModeInt = 0,\n                clearCacheOnLaunch = false,\n                showUpdateDialogOnStartup = !Flavor.isFoss(),\n                groupOptionsByTypes = true,\n                screenList = emptyList(),\n                colorTupleList = null,\n                addSequenceNumber = true,\n                saveFolderUri = null,\n                filenamePrefix = \"ResizedImage\",\n                addSizeInFilename = false,\n                addOriginalFilename = false,\n                font = DomainFontFamily.System,\n                fontScale = 1f,\n                allowCollectCrashlytics = true,\n                allowCollectAnalytics = true,\n                allowBetas = !Flavor.isFoss(),\n                drawContainerShadows = true,\n                drawButtonShadows = true,\n                drawSwitchShadows = true,\n                drawSliderShadows = true,\n                drawFabShadows = true,\n                drawAppBarShadows = true,\n                appOpenCount = 0,\n                aspectRatios = DomainAspectRatio.defaultList,\n                lockDrawOrientation = false,\n                themeContrastLevel = 0.0,\n                themeStyle = 0,\n                isInvertThemeColors = false,\n                screensSearchEnabled = false,\n                hapticsStrength = 1,\n                filenameSuffix = \"\",\n                defaultImageScaleMode = ImageScaleMode.Default,\n                copyToClipboardMode = CopyToClipboardMode.Disabled,\n                magnifierEnabled = false,\n                exifWidgetInitialState = false,\n                initialOcrCodes = listOf(\"eng\"),\n                screenListWithMaxBrightnessEnforcement = emptyList(),\n                isConfettiEnabled = true,\n                isSecureMode = false,\n                useRandomEmojis = false,\n                iconShape = 0,\n                useEmojiAsPrimaryColor = false,\n                dragHandleWidth = 64,\n                confettiType = 0,\n                allowAutoClipboardPaste = false,\n                confettiColorHarmonizer = ColorHarmonizer.Primary,\n                confettiHarmonizationLevel = 0.5f,\n                skipImagePicking = false,\n                generatePreviews = true,\n                showSettingsInLandscape = true,\n                useFullscreenSettings = false,\n                switchType = SwitchType.Compose,\n                defaultDrawLineWidth = 20f,\n                oneTimeSaveLocations = emptyList(),\n                openEditInsteadOfPreview = false,\n                canEnterPresetsByTextField = false,\n                donateDialogOpenCount = 0,\n                colorBlindType = null,\n                favoriteScreenList = emptyList(),\n                isLinkPreviewEnabled = true,\n                defaultDrawColor = ColorModel(-0x1000000),\n                defaultDrawPathMode = 0,\n                addTimestampToFilename = true,\n                useFormattedFilenameTimestamp = true,\n                favoriteColors = emptyList(),\n                defaultResizeType = ResizeType.Explicit,\n                systemBarsVisibility = SystemBarsVisibility.Auto,\n                isSystemBarsVisibleBySwipe = true,\n                isCompactSelectorsLayout = false,\n                mainScreenTitle = \"\",\n                sliderType = SliderType.Fancy,\n                isCenterAlignDialogButtons = false,\n                fastSettingsSide = FastSettingsSide.CenterEnd,\n                settingGroupsInitialVisibility = emptyMap(),\n                customFonts = emptyList(),\n                enableToolExitConfirmation = true,\n                recentColors = emptyList(),\n                backgroundForNoAlphaImageFormats = ColorModel(-0x1000000),\n                addPresetInfoToFilename = false,\n                addImageScaleModeInfoToFilename = false,\n                allowSkipIfLarger = false,\n                customAsciiGradients = emptySet(),\n                isScreenSelectionLauncherMode = false,\n                isTelegramGroupOpened = false,\n                initialOcrMode = 1,\n                spotHealMode = 0,\n                snowfallMode = SnowfallMode.Auto,\n                defaultImageFormat = null,\n                defaultQuality = Quality.Base(),\n                shapesType = ShapeType.Rounded(),\n                filenamePattern = null,\n                filenameBehavior = FilenameBehavior.None(),\n                flingType = FlingType.DEFAULT,\n                hiddenForShareScreens = emptyList(),\n                keepDateTime = false,\n                enableBackgroundColorForAlphaFormats = false,\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/ShapeType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed interface ShapeType {\n    val ordinal: Int get() = entries.indexOf(this)\n\n    val strength: Float\n\n    fun copy(strength: Float): ShapeType = when (this) {\n        is Cut -> Cut(strength = strength)\n        is Rounded -> Rounded(strength = strength)\n        is Squircle -> Squircle(strength = strength)\n        is Smooth -> Smooth(strength = strength)\n    }\n\n    class Rounded(\n        override val strength: Float = 1f\n    ) : ShapeType\n\n    class Cut(\n        override val strength: Float = 1f\n    ) : ShapeType\n\n    class Squircle(\n        override val strength: Float = 1f\n    ) : ShapeType\n\n    class Smooth(\n        override val strength: Float = 1f\n    ) : ShapeType\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                Rounded(), Cut(), Squircle(), Smooth()\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/SliderType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed class SliderType(\n    val ordinal: Int\n) {\n\n    data object MaterialYou : SliderType(0)\n    data object Fancy : SliderType(1)\n    data object Material : SliderType(2)\n    data object HyperOS : SliderType(3)\n\n    companion object {\n        fun fromInt(ordinal: Int) = when (ordinal) {\n            1 -> Fancy\n            2 -> Material\n            3 -> HyperOS\n            else -> MaterialYou\n        }\n\n        val entries by lazy {\n            listOf(\n                MaterialYou, Fancy, Material, HyperOS\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/SnowfallMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed interface SnowfallMode {\n    val ordinal: Int get() = entries.indexOf(this)\n\n    data object Auto : SnowfallMode\n    data object Enabled : SnowfallMode\n    data object Disabled : SnowfallMode\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                Auto, Enabled, Disabled\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/domain/model/SwitchType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.domain.model\n\nsealed class SwitchType(val ordinal: Int) {\n\n    data object MaterialYou : SwitchType(0)\n    data object Compose : SwitchType(1)\n    data object Pixel : SwitchType(2)\n    data object Fluent : SwitchType(3)\n    data object Cupertino : SwitchType(4)\n    data object LiquidGlass : SwitchType(5)\n    data object HyperOS : SwitchType(6)\n    data object OneUI : SwitchType(7)\n\n    companion object {\n        fun fromInt(ordinal: Int) = when (ordinal) {\n            1 -> Compose\n            2 -> Pixel\n            3 -> Fluent\n            4 -> Cupertino\n            5 -> LiquidGlass\n            6 -> HyperOS\n            7 -> OneUI\n            else -> MaterialYou\n        }\n\n        val entries by lazy {\n            listOf(\n                MaterialYou, Compose, Pixel, Fluent, Cupertino, LiquidGlass, HyperOS, OneUI\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/model/EditPresetsController.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.model\n\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.Saver\n\nclass EditPresetsController(\n    initialVisibility: Boolean = false\n) {\n\n    private val _isVisible: MutableState<Boolean> = mutableStateOf(initialVisibility)\n    val isVisible by _isVisible\n\n\n    fun open() {\n        _isVisible.value = true\n    }\n\n    fun close() {\n        _isVisible.value = false\n    }\n\n    companion object {\n        val Saver: Saver<EditPresetsController, Boolean> = Saver(\n            save = {\n                it.isVisible\n            },\n            restore = {\n                EditPresetsController(it)\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/model/IconShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.model\n\nimport androidx.compose.foundation.shape.CutCornerShape\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.MaterialShapes\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.shapes.ArrowShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.BookmarkShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.BurgerShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.DropletShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.EggShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ExplosionShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.HeartShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.MapShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.OctagonShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.OvalShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.PentagonShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.PillShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ShieldShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ShurikenShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SimpleHeartShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SmallMaterialStarShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SquircleShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.utils.toShape\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.collections.immutable.toPersistentList\n\ndata class IconShape(\n    val shape: Shape,\n    val padding: Dp = 4.dp,\n    val iconSize: Dp = 24.dp\n) {\n    fun takeOrElseFrom(\n        iconShapesList: List<IconShape>\n    ): IconShape = if (this == Random) iconShapesList\n        .filter { it != Random }\n        .random()\n    else this\n\n    companion object {\n        val Random by lazy {\n            IconShape(\n                shape = RectangleShape,\n                padding = 0.dp,\n                iconSize = 0.dp\n            )\n        }\n\n        val entriesNoRandom: ImmutableList<IconShape> by lazy {\n            listOf(\n                IconShape(SquircleShape),\n                IconShape(RoundedCornerShape(15)),\n                IconShape(RoundedCornerShape(25)),\n                IconShape(RoundedCornerShape(35)),\n                IconShape(RoundedCornerShape(45)),\n                IconShape(CutCornerShape(25)),\n                IconShape(CutCornerShape(35), 8.dp, 22.dp),\n                IconShape(CutCornerShape(50), 10.dp, 18.dp),\n                IconShape(CloverShape),\n                IconShape(MaterialStarShape, 6.dp, 22.dp),\n                IconShape(SmallMaterialStarShape, 6.dp, 22.dp),\n                IconShape(BookmarkShape, 8.dp, 22.dp),\n                IconShape(PillShape, 10.dp, 22.dp),\n                IconShape(BurgerShape, 6.dp, 22.dp),\n                IconShape(OvalShape, 6.dp),\n                IconShape(ShieldShape, 8.dp, 20.dp),\n                IconShape(EggShape, 8.dp, 20.dp),\n                IconShape(DropletShape, 6.dp, 22.dp),\n                IconShape(ArrowShape, 10.dp, 20.dp),\n                IconShape(PentagonShape, 6.dp, 22.dp),\n                IconShape(OctagonShape, 6.dp, 22.dp),\n                IconShape(ShurikenShape, 8.dp, 22.dp),\n                IconShape(ExplosionShape, 6.dp),\n                IconShape(MapShape, 10.dp, 22.dp),\n                IconShape(HeartShape, 10.dp, 18.dp),\n                IconShape(SimpleHeartShape, 12.dp, 16.dp),\n            ).toMutableList().apply {\n                val shapes = listOf(\n                    MaterialShapes.Slanted,\n                    MaterialShapes.Arch,\n                    MaterialShapes.SemiCircle,\n                    MaterialShapes.Oval,\n                    MaterialShapes.Diamond,\n                    MaterialShapes.ClamShell,\n                    MaterialShapes.Gem,\n                    MaterialShapes.Sunny,\n                    MaterialShapes.VerySunny,\n                    MaterialShapes.Cookie4Sided,\n                    MaterialShapes.Cookie6Sided,\n                    MaterialShapes.Cookie9Sided,\n                    MaterialShapes.Cookie12Sided,\n                    MaterialShapes.Ghostish,\n                    MaterialShapes.Clover4Leaf,\n                    MaterialShapes.Clover8Leaf,\n                    MaterialShapes.Burst,\n                    MaterialShapes.SoftBurst,\n                    MaterialShapes.Boom,\n                    MaterialShapes.SoftBoom,\n                    MaterialShapes.Flower,\n                    MaterialShapes.Puffy,\n                    MaterialShapes.PuffyDiamond,\n                    MaterialShapes.PixelCircle,\n                    MaterialShapes.Bun\n                ).map {\n                    IconShape(it.toShape(), 10.dp, 20.dp)\n                }\n                addAll(shapes)\n            }.toPersistentList()\n        }\n\n        val entries: ImmutableList<IconShape> by lazy {\n            (entriesNoRandom + Random).toPersistentList()\n        }\n    }\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/model/PicturePickerMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.model\n\nimport android.os.Build\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PhotoCameraBack\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FolderImage\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageEmbedded\nimport com.t8rin.imagetoolbox.core.resources.icons.ImagesMode\nimport com.t8rin.imagetoolbox.core.resources.icons.PhotoPickerMobile\n\nsealed class PicturePickerMode(\n    val ordinal: Int,\n    val icon: ImageVector,\n    val title: Int,\n    val subtitle: Int\n) {\n    data object Embedded : PicturePickerMode(\n        ordinal = 0,\n        icon = Icons.Outlined.ImageEmbedded,\n        title = R.string.embedded_picker,\n        subtitle = R.string.embedded_picker_sub\n    )\n\n    data object PhotoPicker : PicturePickerMode(\n        ordinal = 1,\n        icon = Icons.Outlined.PhotoPickerMobile,\n        title = R.string.photo_picker,\n        subtitle = R.string.photo_picker_sub\n    )\n\n    data object Gallery : PicturePickerMode(\n        ordinal = 2,\n        icon = Icons.Outlined.ImagesMode,\n        title = R.string.gallery_picker,\n        subtitle = R.string.gallery_picker_sub\n    )\n\n    data object GetContent : PicturePickerMode(\n        ordinal = 3,\n        icon = Icons.Outlined.FolderImage,\n        title = R.string.file_explorer_picker,\n        subtitle = R.string.file_explorer_picker_sub\n    )\n\n    data object CameraCapture : PicturePickerMode(\n        ordinal = 4,\n        icon = Icons.Outlined.PhotoCameraBack,\n        title = R.string.camera,\n        subtitle = R.string.camera_sub\n    )\n\n    companion object {\n\n        val SafeEmbedded by lazy {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n                Embedded\n            } else PhotoPicker\n        }\n\n        fun fromInt(\n            ordinal: Int\n        ) = when (ordinal) {\n            0 -> SafeEmbedded\n            1 -> PhotoPicker\n            2 -> Gallery\n            3 -> GetContent\n            4 -> CameraCapture\n            else -> SafeEmbedded\n        }\n\n        val entries by lazy {\n            listOf(\n                SafeEmbedded, PhotoPicker, Gallery, GetContent, CameraCapture\n            ).distinct()\n        }\n    }\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/model/Setting.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.model\n\nimport com.t8rin.imagetoolbox.core.resources.R\n\nsealed class Setting(\n    val title: Int,\n    val subtitle: Int?,\n) {\n    data object AddFileSize : Setting(\n        title = R.string.add_file_size,\n        subtitle = R.string.add_file_size_sub\n    )\n\n    data object AddOriginalFilename : Setting(\n        title = R.string.add_original_filename,\n        subtitle = R.string.add_original_filename_sub\n    )\n\n    data object AllowBetas : Setting(\n        title = R.string.allow_betas,\n        subtitle = R.string.allow_betas_sub\n    )\n\n    data object AllowImageMonet : Setting(\n        title = R.string.allow_image_monet,\n        subtitle = R.string.allow_image_monet_sub\n    )\n\n    data object AmoledMode : Setting(\n        title = R.string.amoled_mode,\n        subtitle = R.string.amoled_mode_sub\n    )\n\n    data object Analytics : Setting(\n        title = R.string.analytics,\n        subtitle = R.string.analytics_sub\n    )\n\n    data object Author : Setting(\n        title = R.string.app_developer,\n        subtitle = R.string.app_developer_nick\n    )\n\n    data object AutoCacheClear : Setting(\n        title = R.string.auto_cache_clearing,\n        subtitle = R.string.auto_cache_clearing_sub\n    )\n\n    data object AutoCheckUpdates : Setting(\n        title = R.string.check_updates,\n        subtitle = R.string.check_updates_sub\n    )\n\n    data object Backup : Setting(\n        title = R.string.backup,\n        subtitle = R.string.backup_sub\n    )\n\n    data object BorderThickness : Setting(\n        title = R.string.border_thickness,\n        subtitle = null\n    )\n\n    data object ChangeFont : Setting(\n        title = R.string.font,\n        subtitle = null\n    )\n\n    data object ChangeLanguage : Setting(\n        title = R.string.language,\n        subtitle = null\n    )\n\n    data object CheckUpdatesButton : Setting(\n        title = R.string.check_updates,\n        subtitle = R.string.check_updates_sub\n    )\n\n    data object ClearCache : Setting(\n        title = R.string.cache,\n        subtitle = R.string.cache_size\n    )\n\n    data object ColorScheme : Setting(\n        title = R.string.color_scheme,\n        subtitle = R.string.color_scheme\n    )\n\n    data object Crashlytics : Setting(\n        title = R.string.crashlytics,\n        subtitle = R.string.crashlytics_sub\n    )\n\n    data object CurrentVersionCode : Setting(\n        title = R.string.app_name,\n        subtitle = R.string.version\n    )\n\n    data object Donate : Setting(\n        title = R.string.donation,\n        subtitle = R.string.donation_sub\n    )\n\n    data object DynamicColors : Setting(\n        title = R.string.dynamic_colors,\n        subtitle = R.string.dynamic_colors_sub\n    )\n\n    data object EmojisCount : Setting(\n        title = R.string.emojis_count,\n        subtitle = null\n    )\n\n    data object Emoji : Setting(\n        title = R.string.emoji,\n        subtitle = R.string.emoji_sub\n    )\n\n    data object ContainerShadows : Setting(\n        title = R.string.containers_shadow,\n        subtitle = R.string.containers_shadow_sub\n    )\n\n    data object AppBarShadows : Setting(\n        title = R.string.app_bars_shadow,\n        subtitle = R.string.app_bars_shadow_sub\n    )\n\n    data object SliderShadows : Setting(\n        title = R.string.sliders_shadow,\n        subtitle = R.string.sliders_shadow_sub\n    )\n\n    data object SwitchShadows : Setting(\n        title = R.string.switches_shadow,\n        subtitle = R.string.switches_shadow_sub\n    )\n\n    data object FABShadows : Setting(\n        title = R.string.fabs_shadow,\n        subtitle = R.string.fabs_shadow_sub\n    )\n\n    data object ButtonShadows : Setting(\n        title = R.string.buttons_shadow,\n        subtitle = R.string.buttons_shadow_sub\n    )\n\n    data object FabAlignment : Setting(\n        title = R.string.fab_alignment,\n        subtitle = null\n    )\n\n    data object FilenamePrefix : Setting(\n        title = R.string.prefix,\n        subtitle = null\n    )\n\n    data object FontScale : Setting(\n        title = R.string.font_scale,\n        subtitle = null\n    )\n\n    data object GroupOptions : Setting(\n        title = R.string.group_tools_by_type,\n        subtitle = R.string.group_tools_by_type_sub\n    )\n\n    data object HelpTranslate : Setting(\n        title = R.string.help_translate,\n        subtitle = R.string.help_translate_sub\n    )\n\n    data object ImagePickerMode : Setting(\n        title = R.string.photo_picker,\n        subtitle = R.string.photo_picker_sub\n    )\n\n    data object IssueTracker : Setting(\n        title = R.string.issue_tracker,\n        subtitle = R.string.issue_tracker_sub\n    )\n\n    data object LockDrawOrientation : Setting(\n        title = R.string.lock_draw_orientation,\n        subtitle = R.string.lock_draw_orientation_sub\n    )\n\n    data object NightMode : Setting(\n        title = R.string.night_mode,\n        subtitle = null\n    )\n\n    data object Presets : Setting(\n        title = R.string.presets,\n        subtitle = R.string.presets_sub\n    )\n\n    data object RandomizeFilename : Setting(\n        title = R.string.randomize_filename,\n        subtitle = R.string.randomize_filename_sub\n    )\n\n    data object ReplaceSequenceNumber : Setting(\n        title = R.string.replace_sequence_number,\n        subtitle = R.string.replace_sequence_number_sub\n    )\n\n    data object Reset : Setting(\n        title = R.string.reset,\n        subtitle = R.string.reset_settings_sub\n    )\n\n    data object Restore : Setting(\n        title = R.string.restore,\n        subtitle = R.string.restore_sub\n    )\n\n    data object SavingFolder : Setting(\n        title = R.string.folder,\n        subtitle = null\n    )\n\n    data object ScreenOrder : Setting(\n        title = R.string.order,\n        subtitle = R.string.order_sub\n    )\n\n    data object ScreenSearch : Setting(\n        title = R.string.search_option,\n        subtitle = R.string.search_option_sub\n    )\n\n    data object SourceCode : Setting(\n        title = R.string.check_source_code,\n        subtitle = R.string.check_source_code_sub\n    )\n\n    data object TelegramGroup : Setting(\n        title = R.string.tg_chat,\n        subtitle = R.string.tg_chat_sub\n    )\n\n    data object AutoPinClipboard : Setting(\n        title = R.string.auto_pin,\n        subtitle = R.string.auto_pin_sub\n    )\n\n    data object AutoPinClipboardOnlyClip : Setting(\n        title = R.string.only_clip,\n        subtitle = R.string.only_clip_sub\n    )\n\n    data object VibrationStrength : Setting(\n        title = R.string.vibration_strength,\n        subtitle = null\n    )\n\n    data object OverwriteFiles : Setting(\n        title = R.string.overwrite_files,\n        subtitle = R.string.overwrite_files_sub\n    )\n\n    data object FilenameSuffix : Setting(\n        title = R.string.suffix,\n        subtitle = null\n    )\n\n    data object DefaultScaleMode : Setting(\n        title = R.string.scale_mode,\n        subtitle = null\n    )\n\n    data object DefaultColorSpace : Setting(\n        title = R.string.tag_color_space,\n        subtitle = null\n    )\n\n    data object SwitchType : Setting(\n        title = R.string.switch_type,\n        subtitle = null\n    )\n\n    data object Magnifier : Setting(\n        title = R.string.magnifier,\n        subtitle = R.string.magnifier_sub\n    )\n\n    data object ExifWidgetInitialState : Setting(\n        title = R.string.force_exif_widget_initial_value,\n        subtitle = R.string.force_exif_widget_initial_value_sub\n    )\n\n    data object BrightnessEnforcement : Setting(\n        title = R.string.brightness_enforcement,\n        subtitle = null\n    )\n\n    data object Confetti : Setting(\n        title = R.string.confetti,\n        subtitle = R.string.confetti_sub\n    )\n\n    data object SecureMode : Setting(\n        title = R.string.secure_mode,\n        subtitle = R.string.secure_mode_sub\n    )\n\n    data object UseRandomEmojis : Setting(\n        title = R.string.random_emojis,\n        subtitle = R.string.random_emojis_sub\n    )\n\n    data object IconShape : Setting(\n        title = R.string.icon_shape,\n        subtitle = R.string.icon_shape_sub\n    )\n\n    data object DragHandleWidth : Setting(\n        title = R.string.drag_handle_width,\n        subtitle = null\n    )\n\n    data object ConfettiType : Setting(\n        title = R.string.confetti_type,\n        subtitle = null\n    )\n\n    data object AllowAutoClipboardPaste : Setting(\n        title = R.string.auto_paste,\n        subtitle = R.string.auto_paste_sub\n    )\n\n    data object ConfettiHarmonizer : Setting(\n        title = R.string.harmonization_color,\n        subtitle = null\n    )\n\n    data object ConfettiHarmonizationLevel : Setting(\n        title = R.string.harmonization_level,\n        subtitle = null\n    )\n\n    data object SkipFilePicking : Setting(\n        title = R.string.skip_file_picking,\n        subtitle = R.string.skip_file_picking_sub\n    )\n\n    data object GeneratePreviews : Setting(\n        title = R.string.generate_previews,\n        subtitle = R.string.generate_previews_sub\n    )\n\n    data object ShowSettingsInLandscape : Setting(\n        title = R.string.show_settings_in_landscape,\n        subtitle = R.string.show_settings_in_landscape_sub\n    )\n\n    data object UseFullscreenSettings : Setting(\n        title = R.string.fullscreen_settings,\n        subtitle = R.string.fullscreen_settings_sub\n    )\n\n    data object DefaultDrawLineWidth : Setting(\n        title = R.string.default_line_width,\n        subtitle = null\n    )\n\n    data object OpenEditInsteadOfPreview : Setting(\n        title = R.string.open_edit_instead_of_preview,\n        subtitle = R.string.open_edit_instead_of_preview_sub\n    )\n\n    data object CanEnterPresetsByTextField : Setting(\n        title = R.string.allow_enter_by_text_field,\n        subtitle = R.string.allow_enter_by_text_field_sub\n    )\n\n    data object ColorBlindScheme : Setting(\n        title = R.string.color_blind_scheme,\n        subtitle = R.string.color_blind_scheme_sub\n    )\n\n    data object EnableLinksPreview : Setting(\n        title = R.string.links_preview,\n        subtitle = R.string.links_preview_sub\n    )\n\n    data object DefaultDrawColor : Setting(\n        title = R.string.default_draw_color,\n        subtitle = null\n    )\n\n    data object DefaultDrawPathMode : Setting(\n        title = R.string.default_draw_path_mode,\n        subtitle = null\n    )\n\n    data object AddTimestampToFilename : Setting(\n        title = R.string.add_timestamp,\n        subtitle = R.string.add_timestamp_sub\n    )\n\n    data object UseFormattedFilenameTimestamp : Setting(\n        title = R.string.formatted_timestamp,\n        subtitle = R.string.formatted_timestamp_sub\n    )\n\n    data object OneTimeSaveLocation : Setting(\n        title = R.string.one_time_save_location,\n        subtitle = R.string.one_time_save_location_sub\n    )\n\n    data object TelegramChannel : Setting(\n        title = R.string.ci_channel,\n        subtitle = R.string.ci_channel_sub\n    )\n\n    data object FreeSoftwarePartner : Setting(\n        title = R.string.free_software_partner,\n        subtitle = R.string.free_software_partner_sub\n    )\n\n    data object DefaultResizeType : Setting(\n        title = R.string.resize_type,\n        subtitle = null\n    )\n\n    data object SystemBarsVisibility : Setting(\n        title = R.string.system_bars_visibility,\n        subtitle = null\n    )\n\n    data object ShowSystemBarsBySwipe : Setting(\n        title = R.string.show_system_bars_by_swipe,\n        subtitle = R.string.show_system_bars_by_swipe_sub\n    )\n\n    data object UseCompactSelectors : Setting(\n        title = R.string.compact_selectors,\n        subtitle = R.string.compact_selectors_sub\n    )\n\n    data object MainScreenTitle : Setting(\n        title = R.string.main_screen_title,\n        subtitle = null\n    )\n\n    data object SliderType : Setting(\n        title = R.string.slider_type,\n        subtitle = null\n    )\n\n    data object CenterAlignDialogButtons : Setting(\n        title = R.string.center_align_dialog_buttons,\n        subtitle = R.string.center_align_dialog_buttons_sub\n    )\n\n    data object OpenSourceLicenses : Setting(\n        title = R.string.open_source_licenses,\n        subtitle = R.string.open_source_licenses_sub\n    )\n\n    data object FastSettingsSide : Setting(\n        title = R.string.fast_settings_side,\n        subtitle = R.string.fast_settings_side_sub\n    )\n\n    data object ChecksumAsFilename : Setting(\n        title = R.string.checksum_as_filename,\n        subtitle = R.string.checksum_as_filename_sub\n    )\n\n    data object EnableToolExitConfirmation : Setting(\n        title = R.string.tool_exit_confirmation,\n        subtitle = R.string.tool_exit_confirmation_sub\n    )\n\n    data object SendLogs : Setting(\n        title = R.string.send_logs,\n        subtitle = R.string.send_logs_sub\n    )\n\n    data object AddPresetToFilename : Setting(\n        title = R.string.add_preset_to_filename,\n        subtitle = R.string.add_preset_to_filename_sub\n    )\n\n    data object AddImageScaleModeToFilename : Setting(\n        title = R.string.add_image_scale_mode_to_filename,\n        subtitle = R.string.add_image_scale_mode_to_filename_sub\n    )\n\n    data object AllowSkipIfLarger : Setting(\n        title = R.string.allow_skip_if_larger,\n        subtitle = R.string.allow_skip_if_larger_sub\n    )\n\n    data object EnableLauncherMode : Setting(\n        title = R.string.launcher_mode,\n        subtitle = R.string.launcher_mode_sub\n    )\n\n    data object SnowfallMode : Setting(\n        title = R.string.snowfall_mode,\n        subtitle = null\n    )\n\n    data object DefaultImageFormat : Setting(\n        title = R.string.image_format,\n        subtitle = null\n    )\n\n    data object DefaultQuality : Setting(\n        title = R.string.quality,\n        subtitle = null\n    )\n\n    data object ShapeType : Setting(\n        title = R.string.shapes_type,\n        subtitle = null\n    )\n\n    data object CornersSize : Setting(\n        title = R.string.corners_size,\n        subtitle = null\n    )\n\n    data object FilenamePattern : Setting(\n        title = R.string.filename_format,\n        subtitle = null\n    )\n\n    data object FlingType : Setting(\n        title = R.string.fling_type,\n        subtitle = null\n    )\n\n    data object ToolsHiddenForShare : Setting(\n        title = R.string.hidden_for_share,\n        subtitle = null\n    )\n\n    data object KeepDateTime : Setting(\n        title = R.string.keep_date_time,\n        subtitle = R.string.keep_date_time_sub\n    )\n\n    data object EnableBackgroundColorForAlphaFormats : Setting(\n        title = R.string.background_color_for_alpha_formats,\n        subtitle = R.string.background_color_for_alpha_formats_sub\n    )\n\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/model/SettingsGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"KotlinConstantConditions\")\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.model\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Celebration\nimport androidx.compose.material.icons.rounded.Description\nimport androidx.compose.material.icons.rounded.Info\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.domain.utils.Flavor\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ClipboardFile\nimport com.t8rin.imagetoolbox.core.resources.icons.Cool\nimport com.t8rin.imagetoolbox.core.resources.icons.Database\nimport com.t8rin.imagetoolbox.core.resources.icons.DesignServices\nimport com.t8rin.imagetoolbox.core.resources.icons.Draw\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.resources.icons.Firebase\nimport com.t8rin.imagetoolbox.core.resources.icons.FolderOpened\nimport com.t8rin.imagetoolbox.core.resources.icons.Glyphs\nimport com.t8rin.imagetoolbox.core.resources.icons.HardDrive\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageSearch\nimport com.t8rin.imagetoolbox.core.resources.icons.LabelPercent\nimport com.t8rin.imagetoolbox.core.resources.icons.Mobile\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileArrowDown\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileCast\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileLayout\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileVibrate\nimport com.t8rin.imagetoolbox.core.resources.icons.Psychology\nimport com.t8rin.imagetoolbox.core.resources.icons.ResponsiveLayout\nimport com.t8rin.imagetoolbox.core.resources.icons.Routine\nimport com.t8rin.imagetoolbox.core.resources.icons.Shadow\nimport com.t8rin.imagetoolbox.core.resources.icons.SquareFoot\n\nsealed class SettingsGroup(\n    val id: Int,\n    val titleId: Int,\n    val icon: ImageVector,\n    val settingsList: List<Setting>,\n    val initialState: Boolean,\n) {\n    data object ContactMe : SettingsGroup(\n        id = 0,\n        icon = Icons.Rounded.MobileCast,\n        titleId = R.string.contact_me,\n        settingsList = listOf(\n            Setting.Author,\n            Setting.SendLogs,\n            Setting.Donate\n        ),\n        initialState = true\n    )\n\n    data object PrimaryCustomization : SettingsGroup(\n        id = 1,\n        icon = Icons.Rounded.DesignServices,\n        titleId = R.string.customization,\n        settingsList = listOf(\n            Setting.ColorScheme,\n            Setting.DynamicColors,\n            Setting.AmoledMode,\n            Setting.IconShape\n        ),\n        initialState = true\n    )\n\n    data object SecondaryCustomization : SettingsGroup(\n        id = 2,\n        icon = Icons.TwoTone.DesignServices,\n        titleId = R.string.secondary_customization,\n        settingsList = listOf(\n            Setting.ColorBlindScheme,\n            Setting.AllowImageMonet,\n            Setting.BorderThickness,\n            Setting.MainScreenTitle\n        ),\n        initialState = false\n    )\n\n    data object Layout : SettingsGroup(\n        id = 3,\n        icon = Icons.Rounded.MobileLayout,\n        titleId = R.string.layout,\n        settingsList = listOf(\n            Setting.SwitchType,\n            Setting.SliderType,\n            Setting.ShapeType,\n            Setting.CornersSize,\n            Setting.FlingType,\n            Setting.UseCompactSelectors,\n            Setting.DragHandleWidth,\n            Setting.CenterAlignDialogButtons,\n            Setting.FabAlignment\n        ),\n        initialState = false\n    )\n\n    data object NightMode : SettingsGroup(\n        id = 4,\n        icon = Icons.Rounded.Routine,\n        titleId = R.string.night_mode,\n        settingsList = listOf(\n            Setting.NightMode\n        ),\n        initialState = false\n    )\n\n    data object Shadows : SettingsGroup(\n        id = 5,\n        icon = Icons.Outlined.Shadow,\n        titleId = R.string.shadows,\n        settingsList = listOf(\n            Setting.ContainerShadows,\n            Setting.AppBarShadows,\n            Setting.ButtonShadows,\n            Setting.FABShadows,\n            Setting.SwitchShadows,\n            Setting.SliderShadows\n        ),\n        initialState = false\n    )\n\n    data object Font : SettingsGroup(\n        id = 6,\n        icon = Icons.Outlined.Glyphs,\n        titleId = R.string.text,\n        settingsList = listOf(\n            Setting.ChangeLanguage,\n            Setting.ChangeFont,\n            Setting.FontScale\n        ),\n        initialState = false\n    )\n\n    data object ToolsArrangement : SettingsGroup(\n        id = 7,\n        icon = Icons.Rounded.ResponsiveLayout,\n        titleId = R.string.tools_arrangement,\n        settingsList = listOf(\n            Setting.ScreenOrder,\n            Setting.ScreenSearch,\n            Setting.EnableLauncherMode,\n            Setting.GroupOptions\n        ),\n        initialState = false\n    )\n\n    data object Presets : SettingsGroup(\n        id = 8,\n        icon = Icons.Rounded.LabelPercent,\n        titleId = R.string.presets,\n        settingsList = listOf(\n            Setting.Presets,\n            Setting.CanEnterPresetsByTextField\n        ),\n        initialState = false\n    )\n\n    data object DefaultValues : SettingsGroup(\n        id = 9,\n        icon = Icons.Rounded.SquareFoot,\n        titleId = R.string.default_values,\n        settingsList = listOf(\n            Setting.DefaultScaleMode,\n            Setting.DefaultColorSpace,\n            Setting.DefaultImageFormat,\n            Setting.DefaultQuality,\n            Setting.DefaultResizeType\n        ),\n        initialState = false\n    )\n\n    data object Draw : SettingsGroup(\n        id = 10,\n        icon = Icons.Rounded.Draw,\n        titleId = R.string.draw,\n        settingsList = listOf(\n            Setting.LockDrawOrientation,\n            Setting.DefaultDrawLineWidth,\n            Setting.DefaultDrawColor,\n            Setting.DefaultDrawPathMode,\n            Setting.Magnifier\n        ),\n        initialState = false\n    )\n\n    data object Exif : SettingsGroup(\n        id = 11,\n        icon = Icons.Rounded.Exif,\n        titleId = R.string.exif,\n        settingsList = listOf(\n            Setting.ExifWidgetInitialState,\n            Setting.KeepDateTime\n        ),\n        initialState = false\n    )\n\n    data object Folder : SettingsGroup(\n        id = 12,\n        icon = Icons.Rounded.FolderOpened,\n        titleId = R.string.folder,\n        settingsList = listOf(\n            Setting.SavingFolder,\n            Setting.OneTimeSaveLocation\n        ),\n        initialState = false\n    )\n\n    data object Filename : SettingsGroup(\n        id = 13,\n        icon = Icons.Rounded.Description,\n        titleId = R.string.filename,\n        settingsList = listOf(\n            Setting.FilenamePrefix,\n            Setting.FilenameSuffix,\n            Setting.FilenamePattern,\n            Setting.AddFileSize,\n            Setting.AddOriginalFilename,\n            Setting.ReplaceSequenceNumber,\n            Setting.AddTimestampToFilename,\n            Setting.UseFormattedFilenameTimestamp,\n            Setting.AddPresetToFilename,\n            Setting.AddImageScaleModeToFilename,\n            Setting.OverwriteFiles,\n            Setting.ChecksumAsFilename,\n            Setting.RandomizeFilename\n        ),\n        initialState = false\n    )\n\n    data object Cache : SettingsGroup(\n        id = 14,\n        icon = Icons.Rounded.Database,\n        titleId = R.string.cache,\n        settingsList = listOf(\n            Setting.ClearCache,\n            Setting.AutoCacheClear\n        ),\n        initialState = false\n    )\n\n    data object ImageSource : SettingsGroup(\n        id = 15,\n        icon = Icons.Rounded.ImageSearch,\n        titleId = R.string.image_source,\n        settingsList = listOf(\n            Setting.ImagePickerMode\n        ),\n        initialState = false\n    )\n\n    data object BackupRestore : SettingsGroup(\n        id = 16,\n        icon = Icons.Rounded.HardDrive,\n        titleId = R.string.backup_and_restore,\n        settingsList = listOf(\n            Setting.Backup,\n            Setting.Restore,\n            Setting.Reset\n        ),\n        initialState = false\n    )\n\n    data object Firebase : SettingsGroup(\n        id = 17,\n        icon = Icons.Outlined.Firebase,\n        titleId = R.string.firebase,\n        settingsList = listOf(\n            Setting.Crashlytics,\n            Setting.Analytics\n        ),\n        initialState = false\n    )\n\n    data object Updates : SettingsGroup(\n        id = 18,\n        icon = Icons.Rounded.MobileArrowDown,\n        titleId = R.string.updates,\n        settingsList = listOf(\n            Setting.AutoCheckUpdates,\n            Setting.AllowBetas,\n            Setting.CheckUpdatesButton\n        ),\n        initialState = false\n    )\n\n    data object AboutApp : SettingsGroup(\n        id = 19,\n        icon = Icons.Rounded.Info,\n        titleId = R.string.about_app,\n        settingsList = listOf(\n            Setting.CurrentVersionCode,\n            Setting.OpenSourceLicenses,\n            Setting.HelpTranslate,\n            Setting.IssueTracker,\n            Setting.FreeSoftwarePartner,\n            Setting.TelegramGroup,\n            Setting.TelegramChannel,\n            Setting.SourceCode\n        ),\n        initialState = true\n    )\n\n    data object Clipboard : SettingsGroup(\n        id = 20,\n        icon = Icons.Rounded.ClipboardFile,\n        titleId = R.string.clipboard,\n        settingsList = listOf(\n            Setting.AutoPinClipboard,\n            Setting.AutoPinClipboardOnlyClip,\n            Setting.AllowAutoClipboardPaste\n        ),\n        initialState = false\n    )\n\n    data object Haptics : SettingsGroup(\n        id = 21,\n        icon = Icons.Rounded.MobileVibrate,\n        titleId = R.string.vibration,\n        settingsList = listOf(\n            Setting.VibrationStrength\n        ),\n        initialState = false\n    )\n\n    data object Screen : SettingsGroup(\n        id = 22,\n        icon = Icons.Rounded.Mobile,\n        titleId = R.string.screen,\n        settingsList = listOf(\n            Setting.BrightnessEnforcement,\n            Setting.SecureMode,\n            Setting.SystemBarsVisibility,\n            Setting.ShowSystemBarsBySwipe\n        ),\n        initialState = false\n    )\n\n    data object Emoji : SettingsGroup(\n        id = 23,\n        icon = Icons.Rounded.Cool,\n        titleId = R.string.emoji,\n        settingsList = listOf(\n            Setting.Emoji,\n            Setting.EmojisCount,\n            Setting.UseRandomEmojis\n        ),\n        initialState = false\n    )\n\n    data object Confetti : SettingsGroup(\n        id = 24,\n        icon = Icons.Rounded.Celebration,\n        titleId = R.string.confetti,\n        settingsList = listOf(\n            Setting.Confetti,\n            Setting.ConfettiHarmonizer,\n            Setting.ConfettiHarmonizationLevel,\n            Setting.ConfettiType\n        ),\n        initialState = false\n    )\n\n    data object Behavior : SettingsGroup(\n        id = 25,\n        icon = Icons.Rounded.Psychology,\n        titleId = R.string.behavior,\n        settingsList = listOf(\n            Setting.SkipFilePicking,\n            Setting.AllowSkipIfLarger,\n            Setting.ToolsHiddenForShare,\n            Setting.EnableToolExitConfirmation,\n            Setting.EnableBackgroundColorForAlphaFormats,\n            Setting.ShowSettingsInLandscape,\n            Setting.UseFullscreenSettings,\n            Setting.FastSettingsSide,\n            Setting.OpenEditInsteadOfPreview,\n            Setting.SnowfallMode,\n            Setting.EnableLinksPreview,\n            Setting.GeneratePreviews\n        ),\n        initialState = false\n    )\n\n    companion object {\n        val entries: List<SettingsGroup> by lazy {\n            listOf(\n                ContactMe,\n                PrimaryCustomization,\n                SecondaryCustomization,\n                NightMode,\n                Layout,\n                Emoji,\n                Confetti,\n                Shadows,\n                Haptics,\n                Screen,\n                Font,\n                Behavior,\n                ToolsArrangement,\n                Presets,\n                DefaultValues,\n                Draw,\n                Exif,\n                Folder,\n                Filename,\n                Clipboard,\n                Cache,\n                ImageSource,\n                BackupRestore,\n                Firebase,\n                Updates,\n                AboutApp\n            ).filter {\n                !(it is Firebase && Flavor.isFoss())\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/model/UiFontFamily.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"MemberVisibilityCanBePrivate\")\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.model\n\nimport android.os.Build\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.text.font.Font\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.font.FontStyle\nimport androidx.compose.ui.text.font.FontVariation\nimport androidx.compose.ui.text.font.FontWeight\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.DomainFontFamily\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FontType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport java.io.File\n\nsealed class UiFontFamily(\n    val name: String?,\n    private val variable: Boolean,\n    val type: FontType? = null\n) {\n    val isVariable: Boolean?\n        get() = variable.takeIf {\n            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O\n        }\n\n    val fontFamily: FontFamily\n        get() = type?.let {\n            when (it) {\n                is FontType.File -> fontFamilyFromFile(file = File(it.path))\n                is FontType.Resource -> fontFamilyResource(resId = it.resId)\n            }\n        } ?: FontFamily.Default\n\n    constructor(\n        name: String?,\n        variable: Boolean,\n        fontRes: Int\n    ) : this(\n        name = name,\n        variable = variable,\n        type = FontType.Resource(fontRes)\n    )\n\n    constructor(\n        name: String?,\n        variable: Boolean,\n        filePath: String\n    ) : this(\n        name = name,\n        variable = variable,\n        type = FontType.File(filePath)\n    )\n\n    operator fun component1() = fontFamily\n    operator fun component2() = name\n    operator fun component3() = isVariable\n    operator fun component4() = type\n\n    data object Montserrat : UiFontFamily(\n        fontRes = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            R.font.montserrat_variable\n        } else R.font.montserrat_regular,\n        name = \"Montserrat\",\n        variable = true\n    )\n\n    data object Caveat : UiFontFamily(\n        fontRes = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            R.font.caveat_variable\n        } else R.font.caveat_regular,\n        name = \"Caveat\",\n        variable = true\n    )\n\n    data object System : UiFontFamily(\n        name = null,\n        variable = true\n    )\n\n    data object Comfortaa : UiFontFamily(\n        fontRes = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            R.font.comfortaa_varibale\n        } else R.font.comfortaa_regular,\n        name = \"Comfortaa\",\n        variable = true\n    )\n\n    data object Handjet : UiFontFamily(\n        fontRes = R.font.handjet_varibale,\n        name = \"Handjet\",\n        variable = true\n    )\n\n    data object YsabeauSC : UiFontFamily(\n        fontRes = R.font.ysabeau_sc_variable,\n        name = \"Ysabeau SC\",\n        variable = true\n    )\n\n    data object Jura : UiFontFamily(\n        fontRes = R.font.jura_variable,\n        name = \"Jura\",\n        variable = true\n    )\n\n    data object Tektur : UiFontFamily(\n        fontRes = R.font.tektur_variable,\n        name = \"Tektur\",\n        variable = true\n    )\n\n    data object Podkova : UiFontFamily(\n        fontRes = R.font.podkova_variable,\n        name = \"Podkova\",\n        variable = true\n    )\n\n    data object DejaVu : UiFontFamily(\n        fontRes = R.font.dejavu_regular,\n        name = \"Deja Vu\",\n        variable = false\n    )\n\n    data object BadScript : UiFontFamily(\n        fontRes = R.font.bad_script_regular,\n        name = \"Bad Script\",\n        variable = false\n    )\n\n    data object RuslanDisplay : UiFontFamily(\n        fontRes = R.font.ruslan_display_regular,\n        name = \"Ruslan Display\",\n        variable = false\n    )\n\n    data object Catterdale : UiFontFamily(\n        fontRes = R.font.cattedrale_regular,\n        name = \"Catterdale\",\n        variable = false\n    )\n\n    data object FRM32 : UiFontFamily(\n        fontRes = R.font.frm32_regular,\n        name = \"FRM32\",\n        variable = false\n    )\n\n    data object TokeelyBrookings : UiFontFamily(\n        fontRes = R.font.tokeely_brookings_regular,\n        name = \"Tokeely Brookings\",\n        variable = false\n    )\n\n    data object Nunito : UiFontFamily(\n        fontRes = R.font.nunito_variable,\n        name = \"Nunito\",\n        variable = true\n    )\n\n    data object Nothing : UiFontFamily(\n        fontRes = R.font.nothing_font_regular,\n        name = \"Nothing\",\n        variable = false\n    )\n\n    data object WOPRTweaked : UiFontFamily(\n        fontRes = R.font.wopr_tweaked_regular,\n        name = \"WOPR Tweaked\",\n        variable = false\n    )\n\n    data object AlegreyaSans : UiFontFamily(\n        fontRes = R.font.alegreya_sans_regular,\n        name = \"Alegreya Sans\",\n        variable = false\n    )\n\n    data object MinecraftGnu : UiFontFamily(\n        fontRes = R.font.minecraft_gnu_regular,\n        name = \"Minecraft GNU\",\n        variable = false\n    )\n\n    data object GraniteFixed : UiFontFamily(\n        fontRes = R.font.granite_fixed_regular,\n        name = \"Granite Fixed\",\n        variable = false\n    )\n\n    data object NokiaPixel : UiFontFamily(\n        fontRes = R.font.nokia_pixel_regular,\n        name = \"Nokia Pixel\",\n        variable = false\n    )\n\n    data object Ztivalia : UiFontFamily(\n        fontRes = R.font.ztivalia_regular,\n        name = \"Ztivalia\",\n        variable = false\n    )\n\n    data object Axotrel : UiFontFamily(\n        fontRes = R.font.axotrel_regular,\n        name = \"Axotrel\",\n        variable = false\n    )\n\n    data object LcdOctagon : UiFontFamily(\n        fontRes = R.font.lcd_octagon_regular,\n        name = \"LCD Octagon\",\n        variable = false\n    )\n\n    data object LcdMoving : UiFontFamily(\n        fontRes = R.font.lcd_moving_regular,\n        name = \"LCD Moving\",\n        variable = false\n    )\n\n    data object Unisource : UiFontFamily(\n        fontRes = R.font.unisource_regular,\n        name = \"Unisource\",\n        variable = false\n    )\n\n    class Custom(\n        name: String?,\n        val filePath: String\n    ) : UiFontFamily(\n        name = name,\n        variable = false,\n        filePath = filePath\n    ) {\n        override fun equals(other: Any?): Boolean {\n            if (other !is Custom) return false\n\n            return filePath == other.filePath\n        }\n\n        override fun hashCode(): Int {\n            return filePath.hashCode()\n        }\n\n        override fun toString(): String {\n            return \"Custom(name = $name, filePath = $filePath)\"\n        }\n    }\n\n    fun asDomain(): DomainFontFamily {\n        return when (this) {\n            Caveat -> DomainFontFamily.Caveat\n            Comfortaa -> DomainFontFamily.Comfortaa\n            System -> DomainFontFamily.System\n            Handjet -> DomainFontFamily.Handjet\n            Jura -> DomainFontFamily.Jura\n            Podkova -> DomainFontFamily.Podkova\n            Tektur -> DomainFontFamily.Tektur\n            YsabeauSC -> DomainFontFamily.YsabeauSC\n            Montserrat -> DomainFontFamily.Montserrat\n            DejaVu -> DomainFontFamily.DejaVu\n            BadScript -> DomainFontFamily.BadScript\n            RuslanDisplay -> DomainFontFamily.RuslanDisplay\n            Catterdale -> DomainFontFamily.Catterdale\n            FRM32 -> DomainFontFamily.FRM32\n            TokeelyBrookings -> DomainFontFamily.TokeelyBrookings\n            Nunito -> DomainFontFamily.Nunito\n            Nothing -> DomainFontFamily.Nothing\n            WOPRTweaked -> DomainFontFamily.WOPRTweaked\n            AlegreyaSans -> DomainFontFamily.AlegreyaSans\n            MinecraftGnu -> DomainFontFamily.MinecraftGnu\n            GraniteFixed -> DomainFontFamily.GraniteFixed\n            NokiaPixel -> DomainFontFamily.NokiaPixel\n            Ztivalia -> DomainFontFamily.Ztivalia\n            Axotrel -> DomainFontFamily.Axotrel\n            LcdMoving -> DomainFontFamily.LcdMoving\n            LcdOctagon -> DomainFontFamily.LcdOctagon\n            Unisource -> DomainFontFamily.Unisource\n            is Custom -> DomainFontFamily.Custom(name, filePath)\n        }\n    }\n\n    companion object {\n\n        val entries: List<UiFontFamily>\n            @Composable\n            get() = defaultEntries + customEntries\n\n        val defaultEntries: List<UiFontFamily> by lazy {\n            listOf(\n                Montserrat,\n                Caveat,\n                Comfortaa,\n                Handjet,\n                Jura,\n                Podkova,\n                Tektur,\n                YsabeauSC,\n                DejaVu,\n                BadScript,\n                RuslanDisplay,\n                Catterdale,\n                FRM32,\n                TokeelyBrookings,\n                Nunito,\n                Nothing,\n                WOPRTweaked,\n                AlegreyaSans,\n                MinecraftGnu,\n                GraniteFixed,\n                NokiaPixel,\n                Ztivalia,\n                Axotrel,\n                LcdOctagon,\n                LcdMoving,\n                Unisource,\n                System\n            ).sortedBy { it.name }\n        }\n\n        val customEntries: List<Custom>\n            @Composable\n            get() {\n                val customFonts = LocalSettingsState.current.customFonts\n\n                return remember(customFonts) {\n                    derivedStateOf {\n                        customFonts.sortedBy { it.name }\n                    }\n                }.value\n            }\n    }\n}\n\n@Composable\nfun FontType?.toUiFont(): UiFontFamily {\n    val entries = UiFontFamily.entries\n\n    return remember(entries, this) {\n        derivedStateOf {\n            when (this) {\n                is FontType.File -> UiFontFamily.Custom(\n                    name = File(path).nameWithoutExtension.replace(\"[:\\\\-_.,]\".toRegex(), \" \"),\n                    filePath = path\n                )\n\n                is FontType.Resource -> entries.find { it.type == this } ?: UiFontFamily.System\n                null -> UiFontFamily.System\n            }\n        }\n    }.value\n}\n\nfun FontType?.asUi(): UiFontFamily {\n    val entries = UiFontFamily.defaultEntries\n\n    return when (this) {\n        is FontType.File -> UiFontFamily.Custom(\n            name = File(path).nameWithoutExtension.replace(\"[:\\\\-_.,]\".toRegex(), \" \"),\n            filePath = path\n        )\n\n        is FontType.Resource -> entries.find { it.type == this } ?: UiFontFamily.System\n        null -> UiFontFamily.System\n    }\n}\n\nfun FontType?.asDomain(): DomainFontFamily = this?.asUi()?.asDomain() ?: DomainFontFamily.System\n\nfun DomainFontFamily?.asFontType(): FontType? = this?.toUiFont()?.type\n\nfun DomainFontFamily.toUiFont(): UiFontFamily = when (this) {\n    DomainFontFamily.Caveat -> UiFontFamily.Caveat\n    DomainFontFamily.Comfortaa -> UiFontFamily.Comfortaa\n    DomainFontFamily.System -> UiFontFamily.System\n    DomainFontFamily.Handjet -> UiFontFamily.Handjet\n    DomainFontFamily.Jura -> UiFontFamily.Jura\n    DomainFontFamily.Montserrat -> UiFontFamily.Montserrat\n    DomainFontFamily.Podkova -> UiFontFamily.Podkova\n    DomainFontFamily.Tektur -> UiFontFamily.Tektur\n    DomainFontFamily.YsabeauSC -> UiFontFamily.YsabeauSC\n    DomainFontFamily.DejaVu -> UiFontFamily.DejaVu\n    DomainFontFamily.BadScript -> UiFontFamily.BadScript\n    DomainFontFamily.RuslanDisplay -> UiFontFamily.RuslanDisplay\n    DomainFontFamily.Catterdale -> UiFontFamily.Catterdale\n    DomainFontFamily.FRM32 -> UiFontFamily.FRM32\n    DomainFontFamily.TokeelyBrookings -> UiFontFamily.TokeelyBrookings\n    DomainFontFamily.Nunito -> UiFontFamily.Nunito\n    DomainFontFamily.Nothing -> UiFontFamily.Nothing\n    DomainFontFamily.WOPRTweaked -> UiFontFamily.WOPRTweaked\n    DomainFontFamily.AlegreyaSans -> UiFontFamily.AlegreyaSans\n    DomainFontFamily.MinecraftGnu -> UiFontFamily.MinecraftGnu\n    DomainFontFamily.GraniteFixed -> UiFontFamily.GraniteFixed\n    DomainFontFamily.NokiaPixel -> UiFontFamily.NokiaPixel\n    DomainFontFamily.Ztivalia -> UiFontFamily.Ztivalia\n    DomainFontFamily.Axotrel -> UiFontFamily.Axotrel\n    DomainFontFamily.LcdMoving -> UiFontFamily.LcdMoving\n    DomainFontFamily.LcdOctagon -> UiFontFamily.LcdOctagon\n    DomainFontFamily.Unisource -> UiFontFamily.Unisource\n    is DomainFontFamily.Custom -> UiFontFamily.Custom(\n        name = name,\n        filePath = filePath\n    )\n}\n\nprivate fun fontFamilyResource(resId: Int) = FontFamily(\n    Font(\n        resId = resId,\n        weight = FontWeight.Light,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Light,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        resId = resId,\n        weight = FontWeight.Normal,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Normal,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        resId = resId,\n        weight = FontWeight.Medium,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Medium,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        resId = resId,\n        weight = FontWeight.SemiBold,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.SemiBold,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        resId = resId,\n        weight = FontWeight.Bold,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Bold,\n            style = FontStyle.Normal\n        )\n    )\n)\n\nprivate fun fontFamilyFromFile(file: File) = FontFamily(\n    Font(\n        file = file,\n        weight = FontWeight.Light,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Light,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        file = file,\n        weight = FontWeight.Normal,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Normal,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        file = file,\n        weight = FontWeight.Medium,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Medium,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        file = file,\n        weight = FontWeight.SemiBold,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.SemiBold,\n            style = FontStyle.Normal\n        )\n    ),\n    Font(\n        file = file,\n        weight = FontWeight.Bold,\n        variationSettings = FontVariation.Settings(\n            weight = FontWeight.Bold,\n            style = FontStyle.Normal\n        )\n    )\n)"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/model/UiSettingsState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.model\n\nimport android.net.Uri\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.isSystemInDarkTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.toBitmap\nimport com.t8rin.dynamic.theme.ColorBlindType\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.dynamic.theme.extractPrimaryColor\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.emoji.Emoji\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ColorHarmonizer\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.NightMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.coroutines.launch\n\n@Stable\ndata class UiSettingsState(\n    val isNightMode: Boolean,\n    val isDynamicColors: Boolean,\n    val allowChangeColorByImage: Boolean,\n    val emojisCount: Int,\n    val isAmoledMode: Boolean,\n    val appColorTuple: ColorTuple,\n    val borderWidth: Dp,\n    val presets: List<Int>,\n    val fabAlignment: Alignment,\n    val showUpdateDialogOnStartup: Boolean,\n    val selectedEmoji: Uri?,\n    val picturePickerMode: PicturePickerMode,\n    val clearCacheOnLaunch: Boolean,\n    val groupOptionsByTypes: Boolean,\n    val screenList: List<Int>,\n    val colorTupleList: List<ColorTuple>,\n    val addSequenceNumber: Boolean,\n    val saveFolderUri: Uri?,\n    val filenamePrefix: String,\n    val addSizeInFilename: Boolean,\n    val addOriginalFilename: Boolean,\n    val font: UiFontFamily,\n    val fontScale: Float?,\n    val allowCollectCrashlytics: Boolean,\n    val allowCollectAnalytics: Boolean,\n    val allowBetas: Boolean,\n    val drawContainerShadows: Boolean,\n    val drawButtonShadows: Boolean,\n    val drawSliderShadows: Boolean,\n    val drawSwitchShadows: Boolean,\n    val drawFabShadows: Boolean,\n    val drawAppBarShadows: Boolean,\n    val appOpenCount: Int,\n    val aspectRatios: List<DomainAspectRatio>,\n    val lockDrawOrientation: Boolean,\n    val themeContrastLevel: Double,\n    val themeStyle: PaletteStyle,\n    val isInvertThemeColors: Boolean,\n    val screensSearchEnabled: Boolean,\n    val copyToClipboardMode: CopyToClipboardMode,\n    val hapticsStrength: Int,\n    val filenameSuffix: String,\n    val defaultImageScaleMode: ImageScaleMode,\n    val magnifierEnabled: Boolean,\n    val exifWidgetInitialState: Boolean,\n    val screenListWithMaxBrightnessEnforcement: List<Int>,\n    val isConfettiEnabled: Boolean,\n    val isSecureMode: Boolean,\n    val useRandomEmojis: Boolean,\n    val iconShape: IconShape?,\n    val useEmojiAsPrimaryColor: Boolean,\n    val dragHandleWidth: Dp,\n    val confettiType: Int,\n    val allowAutoClipboardPaste: Boolean,\n    val confettiColorHarmonizer: ColorHarmonizer,\n    val confettiHarmonizationLevel: Float,\n    val skipImagePicking: Boolean,\n    val generatePreviews: Boolean,\n    val showSettingsInLandscape: Boolean,\n    val useFullscreenSettings: Boolean,\n    val switchType: SwitchType,\n    val defaultDrawLineWidth: Float,\n    val oneTimeSaveLocations: List<OneTimeSaveLocation>,\n    val openEditInsteadOfPreview: Boolean,\n    val canEnterPresetsByTextField: Boolean,\n    val donateDialogOpenCount: Int?,\n    val colorBlindType: ColorBlindType?,\n    val favoriteScreenList: List<Int>,\n    val isLinkPreviewEnabled: Boolean,\n    val defaultDrawColor: Color,\n    val defaultDrawPathMode: Int,\n    val addTimestampToFilename: Boolean,\n    val useFormattedFilenameTimestamp: Boolean,\n    val favoriteColors: List<Color>,\n    val defaultResizeType: ResizeType,\n    val systemBarsVisibility: SystemBarsVisibility,\n    val isSystemBarsVisibleBySwipe: Boolean,\n    val isCompactSelectorsLayout: Boolean,\n    val mainScreenTitle: String,\n    val sliderType: SliderType,\n    val isCenterAlignDialogButtons: Boolean,\n    val fastSettingsSide: FastSettingsSide,\n    val settingGroupsInitialVisibility: Map<Int, Boolean>,\n    val customFonts: List<UiFontFamily.Custom>,\n    val enableToolExitConfirmation: Boolean,\n    val recentColors: List<Color>,\n    val backgroundForNoAlphaImageFormats: Color,\n    val addPresetInfoToFilename: Boolean,\n    val addImageScaleModeInfoToFilename: Boolean,\n    val allowSkipIfLarger: Boolean,\n    val customAsciiGradients: Set<String>,\n    val isScreenSelectionLauncherMode: Boolean,\n    val spotHealMode: Int,\n    val snowfallMode: SnowfallMode,\n    val defaultImageFormat: ImageFormat?,\n    val defaultQuality: Quality,\n    val shapesType: ShapeType,\n    val filenamePattern: String?,\n    val filenameBehavior: FilenameBehavior,\n    val flingType: FlingType,\n    val hiddenForShareScreens: List<Int>,\n    val keepDateTime: Boolean,\n    val enableBackgroundColorForAlphaFormats: Boolean,\n)\n\nfun UiSettingsState.isFirstLaunch(\n    approximate: Boolean = true,\n) = if (approximate) {\n    appOpenCount <= 3\n} else appOpenCount <= 1\n\n@Composable\nfun SettingsState.toUiState(\n    randomEmojiKey: Any? = null,\n): UiSettingsState {\n    val allEmojis = Emoji.allIcons()\n    val allIconShapes: ImmutableList<IconShape> = IconShape.entries\n\n    val context = LocalContext.current\n    val scope = rememberCoroutineScope()\n\n    val isNightMode = nightMode.isNightMode()\n\n    val selectedEmojiIndex by remember(selectedEmoji, useRandomEmojis, randomEmojiKey) {\n        derivedStateOf {\n            selectedEmoji?.takeIf { it != -1 }?.let {\n                if (useRandomEmojis) allEmojis.indices.random()\n                else it\n            }\n        }\n    }\n\n    var emojiColorTuple: ColorTuple? by remember {\n        mutableStateOf(null)\n    }\n\n    val appColorTupleComposed by remember(\n        allEmojis,\n        selectedEmojiIndex,\n        appColorTuple,\n        useEmojiAsPrimaryColor\n    ) {\n        derivedStateOf {\n            if (useEmojiAsPrimaryColor) {\n                selectedEmojiIndex?.let { index ->\n                    scope.launch {\n                        context.imageLoader.execute(\n                            ImageRequest.Builder(context)\n                                .target {\n                                    emojiColorTuple =\n                                        ColorTuple(it.toBitmap().extractPrimaryColor())\n                                }\n                                .data(allEmojis[index].toString())\n                                .build()\n                        )\n                    }\n                }\n            } else {\n                emojiColorTuple = null\n            }\n            appColorTuple.asColorTuple()\n        }\n    }\n\n    val appColorTuple by remember(appColorTupleComposed, appColorTuple) {\n        derivedStateOf {\n            emojiColorTuple ?: appColorTupleComposed\n        }\n    }\n\n    val borderWidth by animateDpAsState(borderWidth.dp)\n\n    val presets by remember(presets) {\n        derivedStateOf {\n            presets.mapNotNull(Preset::value)\n        }\n    }\n\n    val selectedEmoji by remember(selectedEmojiIndex, allEmojis) {\n        derivedStateOf {\n            selectedEmojiIndex?.let(allEmojis::getOrNull)\n        }\n    }\n\n    val colorTupleList by remember(colorTupleList) {\n        derivedStateOf {\n            colorTupleList.toColorTupleList()\n        }\n    }\n\n    val saveFolderUri by remember(saveFolderUri) {\n        derivedStateOf {\n            saveFolderUri?.toUri()?.takeIf { it != Uri.EMPTY }\n        }\n    }\n\n    val font by remember(font) {\n        derivedStateOf {\n            font.toUiFont()\n        }\n    }\n\n    val themeStyle by remember(themeStyle) {\n        derivedStateOf {\n            PaletteStyle\n                .entries\n                .getOrNull(themeStyle) ?: PaletteStyle.TonalSpot\n        }\n    }\n\n    val iconShape by remember(iconShape) {\n        derivedStateOf {\n            iconShape?.let(allIconShapes::getOrNull)\n        }\n    }\n\n    val dragHandleWidth by animateDpAsState(dragHandleWidth.dp)\n\n    val colorBlindType by remember(colorBlindType) {\n        derivedStateOf {\n            colorBlindType?.let {\n                ColorBlindType.entries.getOrNull(it)\n            }\n        }\n    }\n\n    val favoriteColors by remember(favoriteColors) {\n        derivedStateOf {\n            favoriteColors.map { Color(it.colorInt) }\n        }\n    }\n\n    val recentColors by remember(recentColors) {\n        derivedStateOf {\n            recentColors.map { Color(it.colorInt) }\n        }\n    }\n\n    val mainScreenTitle = mainScreenTitle.ifEmpty { stringResource(R.string.app_name) }\n\n    val customFonts by remember(customFonts) {\n        derivedStateOf {\n            customFonts.map {\n                it.toUiFont() as UiFontFamily.Custom\n            }\n        }\n    }\n\n    return remember(this, selectedEmoji) {\n        derivedStateOf {\n            UiSettingsState(\n                isNightMode = isNightMode,\n                isDynamicColors = isDynamicColors,\n                allowChangeColorByImage = allowChangeColorByImage,\n                emojisCount = emojisCount,\n                isAmoledMode = isAmoledMode,\n                appColorTuple = appColorTuple,\n                borderWidth = borderWidth,\n                presets = presets,\n                fabAlignment = fabAlignment.toAlignment(),\n                showUpdateDialogOnStartup = showUpdateDialogOnStartup,\n                selectedEmoji = selectedEmoji,\n                picturePickerMode = PicturePickerMode.fromInt(picturePickerModeInt),\n                clearCacheOnLaunch = clearCacheOnLaunch,\n                groupOptionsByTypes = groupOptionsByTypes,\n                screenList = screenList,\n                colorTupleList = colorTupleList,\n                addSequenceNumber = addSequenceNumber,\n                saveFolderUri = saveFolderUri,\n                filenamePrefix = filenamePrefix,\n                addSizeInFilename = addSizeInFilename,\n                addOriginalFilename = addOriginalFilename,\n                font = font,\n                fontScale = fontScale?.takeIf { it > 0 },\n                allowCollectCrashlytics = allowCollectCrashlytics,\n                allowCollectAnalytics = allowCollectAnalytics,\n                allowBetas = allowBetas,\n                drawContainerShadows = drawContainerShadows,\n                drawButtonShadows = drawButtonShadows,\n                drawFabShadows = drawFabShadows,\n                drawSliderShadows = drawSliderShadows,\n                drawSwitchShadows = drawSwitchShadows,\n                drawAppBarShadows = drawAppBarShadows,\n                appOpenCount = appOpenCount,\n                aspectRatios = aspectRatios,\n                lockDrawOrientation = lockDrawOrientation,\n                themeContrastLevel = themeContrastLevel,\n                themeStyle = themeStyle,\n                isInvertThemeColors = isInvertThemeColors,\n                screensSearchEnabled = screensSearchEnabled,\n                copyToClipboardMode = copyToClipboardMode,\n                hapticsStrength = hapticsStrength,\n                filenameSuffix = filenameSuffix,\n                defaultImageScaleMode = defaultImageScaleMode,\n                magnifierEnabled = magnifierEnabled,\n                exifWidgetInitialState = exifWidgetInitialState,\n                screenListWithMaxBrightnessEnforcement = screenListWithMaxBrightnessEnforcement,\n                isConfettiEnabled = isConfettiEnabled,\n                isSecureMode = isSecureMode,\n                useRandomEmojis = useRandomEmojis,\n                iconShape = iconShape,\n                useEmojiAsPrimaryColor = useEmojiAsPrimaryColor,\n                dragHandleWidth = dragHandleWidth,\n                confettiType = confettiType,\n                allowAutoClipboardPaste = allowAutoClipboardPaste,\n                confettiColorHarmonizer = confettiColorHarmonizer,\n                confettiHarmonizationLevel = confettiHarmonizationLevel,\n                skipImagePicking = skipImagePicking,\n                generatePreviews = generatePreviews,\n                showSettingsInLandscape = showSettingsInLandscape,\n                useFullscreenSettings = useFullscreenSettings,\n                switchType = switchType,\n                defaultDrawLineWidth = defaultDrawLineWidth,\n                oneTimeSaveLocations = oneTimeSaveLocations,\n                openEditInsteadOfPreview = openEditInsteadOfPreview,\n                canEnterPresetsByTextField = canEnterPresetsByTextField,\n                donateDialogOpenCount = donateDialogOpenCount.takeIf { it >= 0 },\n                colorBlindType = colorBlindType,\n                favoriteScreenList = favoriteScreenList,\n                isLinkPreviewEnabled = isLinkPreviewEnabled,\n                defaultDrawColor = Color(defaultDrawColor.colorInt),\n                defaultDrawPathMode = defaultDrawPathMode,\n                addTimestampToFilename = addTimestampToFilename,\n                useFormattedFilenameTimestamp = useFormattedFilenameTimestamp,\n                favoriteColors = favoriteColors,\n                defaultResizeType = defaultResizeType,\n                systemBarsVisibility = systemBarsVisibility,\n                isSystemBarsVisibleBySwipe = isSystemBarsVisibleBySwipe,\n                isCompactSelectorsLayout = isCompactSelectorsLayout,\n                mainScreenTitle = mainScreenTitle,\n                sliderType = sliderType,\n                isCenterAlignDialogButtons = isCenterAlignDialogButtons,\n                fastSettingsSide = fastSettingsSide,\n                settingGroupsInitialVisibility = settingGroupsInitialVisibility,\n                customFonts = customFonts,\n                enableToolExitConfirmation = enableToolExitConfirmation,\n                recentColors = recentColors,\n                backgroundForNoAlphaImageFormats = Color(backgroundForNoAlphaImageFormats.colorInt),\n                addPresetInfoToFilename = addPresetInfoToFilename,\n                addImageScaleModeInfoToFilename = addImageScaleModeInfoToFilename,\n                allowSkipIfLarger = allowSkipIfLarger,\n                customAsciiGradients = customAsciiGradients,\n                isScreenSelectionLauncherMode = isScreenSelectionLauncherMode,\n                spotHealMode = spotHealMode,\n                snowfallMode = snowfallMode,\n                defaultImageFormat = defaultImageFormat,\n                defaultQuality = defaultQuality,\n                shapesType = shapesType,\n                filenamePattern = filenamePattern,\n                filenameBehavior = filenameBehavior,\n                flingType = flingType,\n                hiddenForShareScreens = hiddenForShareScreens,\n                keepDateTime = keepDateTime,\n                enableBackgroundColorForAlphaFormats = enableBackgroundColorForAlphaFormats,\n            )\n        }\n    }.value\n}\n\nprivate fun String?.toColorTupleList(): List<ColorTuple> {\n    val list = mutableListOf<ColorTuple>()\n    this?.split(\"*\")?.forEach { colorTuple ->\n        val temp = colorTuple.split(\"/\")\n        temp.getOrNull(0)?.toIntOrNull()?.toColor()?.let {\n            list.add(\n                ColorTuple(\n                    primary = it,\n                    secondary = temp.getOrNull(1)?.toIntOrNull()?.toColor(),\n                    tertiary = temp.getOrNull(2)?.toIntOrNull()?.toColor(),\n                    surface = temp.getOrNull(3)?.toIntOrNull()?.toColor()\n                )\n            )\n        }\n    }\n    if (list.isEmpty()) {\n        list.add(defaultColorTuple)\n    }\n    return list.toHashSet().toList()\n}\n\nprivate fun Int.toColor() = Color(this)\n\nfun String.asColorTuple(): ColorTuple {\n    val colorTuple = split(\"*\")\n    return ColorTuple(\n        primary = colorTuple.getOrNull(0)?.toIntOrNull()?.let { Color(it) }\n            ?: defaultColorTuple.primary,\n        secondary = colorTuple.getOrNull(1)?.toIntOrNull()?.let { Color(it) },\n        tertiary = colorTuple.getOrNull(2)?.toIntOrNull()?.let { Color(it) },\n        surface = colorTuple.getOrNull(3)?.toIntOrNull()?.let { Color(it) },\n    )\n}\n\nprivate fun Int.toAlignment() = when (this) {\n    0 -> Alignment.BottomStart\n    1 -> Alignment.BottomCenter\n    else -> Alignment.BottomEnd\n}\n\n@Composable\nprivate fun NightMode.isNightMode(): Boolean = when (this) {\n    NightMode.System -> isSystemInDarkTheme()\n    else -> this is NightMode.Dark\n}\n\nval defaultColorTuple = ColorTuple(\n    if (BuildConfig.DEBUG) Color(0xFF3ADBD6)\n    else Color(0xFF8FDB3A)\n)"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/provider/LocalSettingsState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.provider\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.core.settings.domain.SimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.EditPresetsController\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiSettingsState\n\nval LocalSettingsState =\n    compositionLocalOf<UiSettingsState> { error(\"UiSettingsState not present\") }\n\nval LocalSimpleSettingsInteractor =\n    compositionLocalOf<SimpleSettingsInteractor> { error(\"SimpleSettingInteractor not present\") }\n\nval LocalEditPresetsController =\n    compositionLocalOf<EditPresetsController> { error(\"EditPresetsController not present\") }\n\n@Composable\nfun rememberAppColorTuple(\n    settingsState: UiSettingsState = LocalSettingsState.current\n): ColorTuple = rememberAppColorTuple(\n    defaultColorTuple = settingsState.appColorTuple,\n    dynamicColor = settingsState.isDynamicColors,\n    darkTheme = settingsState.isNightMode\n)\n\n@Composable\nfun rememberEditPresetsController(\n    initialVisibility: Boolean = false\n) = rememberSaveable(initialVisibility, saver = EditPresetsController.Saver) {\n    EditPresetsController(initialVisibility)\n}"
  },
  {
    "path": "core/settings/src/main/java/com/t8rin/imagetoolbox/core/settings/presentation/utils/RoundedPolygonUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.settings.presentation.utils\n\nimport androidx.compose.foundation.shape.GenericShape\nimport androidx.compose.ui.graphics.Matrix\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.util.fastForEach\nimport androidx.graphics.shapes.Cubic\nimport androidx.graphics.shapes.RoundedPolygon\nimport kotlin.math.PI\nimport kotlin.math.atan2\n\nfun RoundedPolygon.toShape(startAngle: Int = 0): Shape {\n    return GenericShape { size, _ ->\n        rewind()\n        addPath(toPath(startAngle = startAngle))\n        val scaleMatrix = Matrix().apply { scale(x = size.width, y = size.height) }\n\n        transform(scaleMatrix)\n    }\n}\n\nfun RoundedPolygon.toPath(\n    path: Path = Path(),\n    startAngle: Int = 0,\n    repeatPath: Boolean = false,\n    closePath: Boolean = true,\n): Path {\n    pathFromCubics(\n        path = path,\n        startAngle = startAngle,\n        repeatPath = repeatPath,\n        closePath = closePath,\n        cubics = cubics,\n        rotationPivotX = centerX,\n        rotationPivotY = centerY\n    )\n    return path\n}\n\nprivate fun pathFromCubics(\n    path: Path,\n    startAngle: Int,\n    repeatPath: Boolean,\n    closePath: Boolean,\n    cubics: List<Cubic>,\n    rotationPivotX: Float,\n    rotationPivotY: Float\n) {\n    var first = true\n    var firstCubic: Cubic? = null\n    path.rewind()\n    cubics.fastForEach {\n        if (first) {\n            path.moveTo(it.anchor0X, it.anchor0Y)\n            if (startAngle != 0) {\n                firstCubic = it\n            }\n            first = false\n        }\n        path.cubicTo(\n            it.control0X,\n            it.control0Y,\n            it.control1X,\n            it.control1Y,\n            it.anchor1X,\n            it.anchor1Y\n        )\n    }\n    if (repeatPath) {\n        var firstInRepeat = true\n        cubics.fastForEach {\n            if (firstInRepeat) {\n                path.lineTo(it.anchor0X, it.anchor0Y)\n                firstInRepeat = false\n            }\n            path.cubicTo(\n                it.control0X,\n                it.control0Y,\n                it.control1X,\n                it.control1Y,\n                it.anchor1X,\n                it.anchor1Y\n            )\n        }\n    }\n\n    if (closePath) path.close()\n\n    if (startAngle != 0 && firstCubic != null) {\n        val angleToFirstCubic =\n            radiansToDegrees(\n                atan2(\n                    y = cubics[0].anchor0Y - rotationPivotY,\n                    x = cubics[0].anchor0X - rotationPivotX\n                )\n            )\n        // Rotate the Path to to start from the given angle.\n        path.transform(Matrix().apply { rotateZ(-angleToFirstCubic + startAngle) })\n    }\n}\n\nprivate fun radiansToDegrees(radians: Float): Float {\n    return (radians * 180.0 / PI).toFloat()\n}"
  },
  {
    "path": "core/ui/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/ui/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.ui\"\n\ndependencies {\n    api(projects.core.resources)\n    api(projects.core.domain)\n    api(projects.core.utils)\n    implementation(projects.core.di)\n    implementation(projects.core.settings)\n\n    // Navigation\n    api(libs.decompose)\n    api(libs.decomposeExtensions)\n\n    //AndroidX\n    api(libs.activityCompose)\n    api(libs.splashScreen)\n    api(libs.appCompat)\n    api(libs.androidx.documentfile)\n\n    //Konfetti\n    api(libs.konfetti.compose)\n\n    //Coil\n    api(libs.coil)\n    api(libs.coilCompose)\n    api(libs.coilGif)\n    api(libs.coilSvg)\n    api(libs.coilNetwork)\n    api(libs.ktor)\n\n    //Modules\n    api(libs.toolbox.uCrop)\n    api(projects.lib.cropper)\n    api(projects.lib.dynamicTheme)\n    api(projects.lib.colors)\n    api(projects.lib.gesture)\n    api(projects.lib.image)\n    api(projects.lib.modalsheet)\n    api(libs.logger)\n    api(projects.lib.zoomable)\n    api(projects.lib.snowfall)\n    api(libs.toolbox.histogram)\n\n    api(libs.reorderable)\n\n    api(libs.shadowGadgets)\n    api(libs.shadowsPlus)\n\n    api(libs.kotlinx.collections.immutable)\n\n    api(libs.fadingEdges)\n    api(libs.scrollbar)\n\n    implementation(libs.datastore.preferences.android)\n    implementation(libs.datastore.core.android)\n    api(libs.material)\n\n    \"marketImplementation\"(platform(libs.firebase.bom))\n    \"marketImplementation\"(libs.firebase.crashlytics)\n    \"marketImplementation\"(libs.firebase.analytics)\n    \"marketImplementation\"(libs.review.ktx)\n    \"marketImplementation\"(libs.app.update)\n    \"marketImplementation\"(libs.app.update.ktx)\n\n    \"marketImplementation\"(libs.mlkit.document.scanner)\n    \"fossImplementation\"(projects.lib.documentscanner)\n\n    \"marketImplementation\"(libs.quickie.bundled)\n    \"fossImplementation\"(libs.quickie.foss)\n    implementation(libs.zxing.core)\n\n    implementation(projects.lib.qrose)\n\n    implementation(libs.jsoup)\n\n    api(libs.androidliquidglass)\n    api(libs.capsule)\n    api(libs.squircle.shape)\n\n    api(libs.evaluator)\n\n    api(libs.flinger)\n}"
  },
  {
    "path": "core/ui/src/foss/java/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/DocumentScannerImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport android.Manifest\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.PackageManager\nimport android.provider.MediaStore\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.ActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CameraAlt\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.core.content.ContextCompat\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ScanResult\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.websitebeaver.documentscanner.DocumentScanner as DocumentScannerDelegate\n\nprivate class DocumentScannerImpl(\n    private val context: Context,\n    private val scanner: DocumentScannerDelegate,\n    private val scannerLauncher: ManagedActivityResultLauncher<Intent, ActivityResult>,\n    private val requestPermissionLauncher: ManagedActivityResultLauncher<String, Boolean>\n) : DocumentScanner {\n\n    override fun scan() {\n        if (ContextCompat.checkSelfPermission(\n                context,\n                Manifest.permission.CAMERA\n            ) == PackageManager.PERMISSION_GRANTED\n        ) {\n            scannerLauncher.launch(scanner.createDocumentScanIntent())\n        } else {\n            requestPermissionLauncher.launch(Manifest.permission.CAMERA)\n        }\n    }\n\n}\n\n@Composable\ninternal fun rememberDocumentScannerImpl(\n    onSuccess: (ScanResult) -> Unit\n): DocumentScanner {\n    val context = LocalComponentActivity.current\n\n    val scanner = remember(context) {\n        DocumentScannerDelegate(\n            activity = context,\n            successHandler = { imageUris ->\n                onSuccess(\n                    ScanResult(imageUris.map { it.toUri() })\n                )\n            },\n            errorHandler = {\n                if (it.contains(MediaStore.ACTION_IMAGE_CAPTURE)) {\n                    AppToastHost.showToast(\n                        message = context.getString(R.string.camera_failed_to_open),\n                        icon = Icons.Outlined.CameraAlt\n                    )\n                } else {\n                    AppToastHost.showFailureToast(it)\n                }\n            }\n        )\n    }\n\n    val scannerLauncher = rememberLauncherForActivityResult(\n        ActivityResultContracts.StartActivityForResult()\n    ) { result ->\n        scanner.handleDocumentScanIntentResult(result)\n    }\n\n    val requestPermissionLauncher = rememberLauncherForActivityResult(\n        ActivityResultContracts.RequestPermission()\n    ) { isGranted: Boolean ->\n        if (isGranted) {\n            scannerLauncher.launch(scanner.createDocumentScanIntent())\n        } else {\n            AppToastHost.showToast(\n                message = appContext.getString(R.string.grant_camera_permission_to_scan_document_scanner),\n                icon = Icons.Outlined.CameraAlt\n            )\n        }\n    }\n\n    return remember(context, scannerLauncher) {\n        DocumentScannerImpl(\n            context = context,\n            scanner = scanner,\n            scannerLauncher = scannerLauncher,\n            requestPermissionLauncher = requestPermissionLauncher\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/foss/java/com/t8rin/imagetoolbox/core/ui/utils/helper/ReviewHandlerImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.Intent\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.datastore.preferences.core.booleanPreferencesKey\nimport androidx.datastore.preferences.core.edit\nimport androidx.datastore.preferences.core.intPreferencesKey\nimport androidx.datastore.preferences.preferencesDataStore\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\n\ninternal object ReviewHandlerImpl : ReviewHandler() {\n\n    private val scope = CoroutineScope(Dispatchers.IO)\n\n    private val Context.dataStore by preferencesDataStore(\"saves_count\")\n\n    private val SAVES_COUNT = intPreferencesKey(\"SAVES_COUNT\")\n    private val NOT_SHOW_AGAIN = booleanPreferencesKey(\"NOT_SHOW_AGAIN\")\n\n    private val _showNotShowAgainButton = mutableStateOf(false)\n    override val showNotShowAgainButton: Boolean by _showNotShowAgainButton\n\n    override fun showReview(activity: Activity) {\n        scope.launch {\n            activity.dataStore.edit {\n                if (it[NOT_SHOW_AGAIN] != true) {\n                    val saves = it[SAVES_COUNT] ?: 0\n                    it[SAVES_COUNT] = saves + 1\n\n                    _showNotShowAgainButton.value = saves >= 30\n\n                    if (saves % 10 == 0) {\n                        activity.startActivity(\n                            Intent(activity, activity::class.java).apply {\n                                action = Intent.ACTION_BUG_REPORT\n                                flags = Intent.FLAG_ACTIVITY_SINGLE_TOP\n                            }\n                        )\n                    }\n                } else {\n                    _showNotShowAgainButton.value = false\n                }\n            }\n        }\n    }\n\n    override fun notShowReviewAgain() {\n        scope.launch {\n            appContext.dataStore.edit {\n                it[NOT_SHOW_AGAIN] = true\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/foss/java/com/t8rin/imagetoolbox/core/ui/widget/sheets/UpdateSheetImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport androidx.compose.runtime.Composable\n\n@Composable\ninternal fun UpdateSheetImpl(\n    changelog: String,\n    tag: String,\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    DefaultUpdateSheet(\n        changelog = changelog,\n        tag = tag,\n        visible = visible,\n        onDismiss = onDismiss\n    )\n}"
  },
  {
    "path": "core/ui/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/theme/Color.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.ui.theme\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalInspectionMode\nimport androidx.core.graphics.ColorUtils\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\n\nfun ColorScheme.outlineVariant(\n    luminance: Float = 0.3f,\n    onTopOf: Color = surfaceContainer\n) = onSecondaryContainer\n    .copy(alpha = luminance)\n    .compositeOver(onTopOf)\n\n@Composable\ninline fun takeColorFromScheme(\n    action: @Composable ColorScheme.(isNightMode: Boolean) -> Color\n) = animateColorAsState(\n    MaterialTheme.colorScheme.run {\n        action(\n            if (LocalInspectionMode.current) false else LocalSettingsState.current.isNightMode\n        )\n    }\n).value\n\n\nfun ColorScheme.suggestContainerColorBy(color: Color) = when (color) {\n    onPrimary -> primary\n    onSecondary -> secondary\n    onTertiary -> tertiary\n    onPrimaryContainer -> primaryContainer\n    onSecondaryContainer -> secondaryContainer\n    onTertiaryContainer -> tertiaryContainer\n    onError -> error\n    onErrorContainer -> errorContainer\n    onSurfaceVariant -> surfaceVariant\n    inverseOnSurface -> inverseSurface\n    else -> surface\n}\n\ninline val ColorScheme.mixedContainer: Color\n    @Composable get() = run {\n        tertiaryContainer.blend(\n            primaryContainer,\n            0.4f\n        )\n    }\n\ninline val ColorScheme.primaryContainerFixed: Color\n    @Composable get() = run {\n        if (LocalSettingsState.current.isNightMode) primaryContainer.copy(alpha = 0.6f)\n        else primary.copy(alpha = 0.6f)\n    }\n\ninline val ColorScheme.onPrimaryContainerFixed: Color\n    @Composable get() = run {\n        if (LocalSettingsState.current.isNightMode) onPrimaryContainer else onPrimary\n    }.blend(Color.White)\n\ninline val ColorScheme.secondaryContainerFixed: Color\n    @Composable get() = run {\n        if (LocalSettingsState.current.isNightMode) secondaryContainer.copy(alpha = 0.6f)\n        else secondary.copy(alpha = 0.6f)\n    }\n\ninline val ColorScheme.onSecondaryContainerFixed: Color\n    @Composable get() = run {\n        if (LocalSettingsState.current.isNightMode) onSecondaryContainer else onSecondary\n    }.blend(Color.White)\n\ninline val ColorScheme.tertiaryContainerFixed: Color\n    @Composable get() = run {\n        if (LocalSettingsState.current.isNightMode) tertiaryContainer.copy(alpha = 0.6f)\n        else tertiary.copy(alpha = 0.6f)\n    }\n\ninline val ColorScheme.onTertiaryContainerFixed: Color\n    @Composable get() = run {\n        if (LocalSettingsState.current.isNightMode) onTertiaryContainer else onTertiary\n    }.blend(Color.White)\n\ninline val ColorScheme.onMixedContainer: Color\n    @Composable get() = run {\n        onTertiaryContainer.blend(\n            onPrimaryContainer,\n            0.4f\n        )\n    }\n\ninline fun Color.takeIf(predicate: Boolean) = if (predicate) this else Color.Unspecified\n\ninline fun Color.takeUnless(predicate: Boolean) = takeIf(!predicate)\n\nfun Color.blend(\n    color: Color,\n    @FloatRange(from = 0.0, to = 1.0) fraction: Float = 0.2f\n): Color = Color(ColorUtils.blendARGB(this.toArgb(), color.toArgb(), fraction))\n\n@Composable\nfun Color.inverse(\n    fraction: (Boolean) -> Float = { 0.5f },\n    darkMode: Boolean = LocalSettingsState.current.isNightMode,\n): Color = if (darkMode) blend(Color.White, fraction(true))\nelse blend(Color.Black, fraction(false))\n\nfun Color.inverseByLuma(\n    fraction: (Boolean) -> Float = { 0.5f },\n): Color = if (luminance() < 0.3f) blend(Color.White, fraction(true))\nelse blend(Color.Black, fraction(false))\n\n@Composable\nfun Color.inverse(\n    fraction: (Boolean) -> Float = { 0.5f },\n    color: (Boolean) -> Color,\n    darkMode: Boolean = LocalSettingsState.current.isNightMode,\n): Color = if (darkMode) blend(color(true), fraction(true))\nelse blend(color(true), fraction(false))\n\n\nfun Int.blend(\n    color: Color,\n    @FloatRange(from = 0.0, to = 1.0) fraction: Float = 0.2f\n): Int = ColorUtils.blendARGB(this, color.toArgb(), fraction)\n\n@Composable\nfun Color.harmonizeWithPrimary(\n    @FloatRange(\n        from = 0.0,\n        to = 1.0\n    ) fraction: Float = 0.2f\n): Color = blend(MaterialTheme.colorScheme.primary, fraction)\n\n\nfun Int.toColor() = Color(this)\n\ninline val Green: Color\n    @Composable get() = Color(0xFFBADB94).harmonizeWithPrimary(0.2f)\n\ninline val Red: Color\n    @Composable get() = Color(0xFFE06565).harmonizeWithPrimary(0.2f)\n\ninline val Blue: Color\n    @Composable get() = Color(0xFF0088CC).harmonizeWithPrimary(0.2f)\n\ninline val Black: Color\n    @Composable get() = Color(0xFF142329).harmonizeWithPrimary(0.2f)\n\ninline val StrongBlack: Color\n    @Composable get() = Color(0xFF141414).harmonizeWithPrimary(0.07f)\n\ninline val White: Color\n    @Composable get() = Color(0xFFFFFFFF).harmonizeWithPrimary(0.07f)\n\ninline val BitcoinColor: Color\n    @Composable get() = Color(0xFFF7931A).harmonizeWithPrimary(0.2f)\n\ninline val USDTColor: Color\n    @Composable get() = Color(0xFF50AF95).harmonizeWithPrimary(0.2f)\n\ninline val TONSpaceColor: Color\n    @Composable get() = Color(0xFF232328).harmonizeWithPrimary(0.1f)\n\ninline val TONColor: Color\n    @Composable get() = Color(0xFF0098EA).harmonizeWithPrimary(0.2f)\n\ninline val BoostyColor: Color\n    @Composable get() = Color(0xFFF15F2C).harmonizeWithPrimary(0.2f)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/theme/Motion.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\", \"UNCHECKED_CAST\")\n\npackage com.t8rin.imagetoolbox.core.ui.theme\n\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.material3.MotionScheme\nimport com.t8rin.imagetoolbox.core.domain.utils.cast\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.FancyTransitionEasing\n\n\ninternal val CustomMotionScheme: MotionScheme = object : MotionScheme {\n    val SpringDefaultSpatialDamping = 0.8f\n    val SpringDefaultSpatialStiffness = 380.0f\n    val SpringDefaultEffectsDamping = 1.0f\n    val SpringDefaultEffectsStiffness = 1600.0f\n    val SpringFastSpatialDamping = 0.6f\n    val SpringFastSpatialStiffness = 800.0f\n    val SpringFastEffectsDamping = 1.0f\n    val SpringFastEffectsStiffness = 3800.0f\n    val SpringSlowSpatialDamping = 0.8f\n    val SpringSlowSpatialStiffness = 200.0f\n    val SpringSlowEffectsDamping = 1.0f\n    val SpringSlowEffectsStiffness = 800.0f\n\n    private val defaultSpatialSpec =\n        tween<Any>(\n            durationMillis = 400,\n            easing = FancyTransitionEasing\n        )\n\n    private val fastSpatialSpec =\n        spring<Any>(\n            dampingRatio = SpringFastSpatialDamping,\n            stiffness = SpringFastSpatialStiffness\n        )\n\n    private val slowSpatialSpec =\n        spring<Any>(\n            dampingRatio = SpringSlowSpatialDamping,\n            stiffness = SpringSlowSpatialStiffness\n        )\n\n    private val defaultEffectsSpec =\n        spring<Any>(\n            dampingRatio = SpringDefaultEffectsDamping,\n            stiffness = SpringDefaultEffectsStiffness\n        )\n\n    private val fastEffectsSpec =\n        tween<Any>(\n            durationMillis = 300,\n            easing = FancyTransitionEasing\n        )\n\n    private val slowEffectsSpec =\n        tween<Any>(\n            durationMillis = 500,\n            easing = FancyTransitionEasing\n        )\n\n    override fun <T> defaultSpatialSpec(): FiniteAnimationSpec<T> = defaultSpatialSpec.cast()\n\n    override fun <T> fastSpatialSpec(): FiniteAnimationSpec<T> = fastSpatialSpec.cast()\n\n    override fun <T> slowSpatialSpec(): FiniteAnimationSpec<T> = slowSpatialSpec.cast()\n\n    override fun <T> defaultEffectsSpec(): FiniteAnimationSpec<T> = defaultEffectsSpec.cast()\n\n    override fun <T> fastEffectsSpec(): FiniteAnimationSpec<T> = fastEffectsSpec.cast()\n\n    override fun <T> slowEffectsSpec(): FiniteAnimationSpec<T> = slowEffectsSpec.cast()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/theme/Theme.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.theme\n\nimport android.annotation.SuppressLint\nimport android.os.Build\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Shapes\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.dynamicDarkColorScheme\nimport androidx.compose.material3.dynamicLightColorScheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.DynamicTheme\nimport com.t8rin.dynamic.theme.rememberDynamicThemeState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.FancyTransitionEasing\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.DeviceInfo\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\n\n@SuppressLint(\"NewApi\")\n@Composable\nfun ImageToolboxTheme(\n    content: @Composable () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val context = LocalContext.current\n\n    DynamicTheme(\n        typography = rememberTypography(settingsState.font),\n        state = rememberDynamicThemeState(rememberAppColorTuple()),\n        colorBlindType = settingsState.colorBlindType,\n        defaultColorTuple = settingsState.appColorTuple,\n        dynamicColor = settingsState.isDynamicColors,\n        dynamicColorsOverride = { isNightMode ->\n            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.BAKLAVA && DeviceInfo.isPixel()) {\n                val colors = if (isNightMode) {\n                    dynamicDarkColorScheme(context)\n                } else {\n                    dynamicLightColorScheme(context)\n                }\n\n                ColorTuple(\n                    primary = colors.primary,\n                    secondary = colors.secondary,\n                    tertiary = colors.tertiary,\n                    surface = colors.surface\n                )\n            } else null\n        },\n        amoledMode = settingsState.isAmoledMode,\n        isDarkTheme = settingsState.isNightMode,\n        contrastLevel = settingsState.themeContrastLevel,\n        style = settingsState.themeStyle,\n        isInvertColors = settingsState.isInvertThemeColors,\n        colorAnimationSpec = tween(\n            durationMillis = 400,\n            easing = FancyTransitionEasing\n        ),\n        content = {\n            MaterialTheme(\n                motionScheme = CustomMotionScheme,\n                colorScheme = modifiedColorScheme(),\n                shapes = modifiedShapes(),\n                content = content\n            )\n        }\n    )\n}\n\n@Composable\nfun ImageToolboxThemeSurface(\n    content: @Composable BoxScope.() -> Unit\n) {\n    ImageToolboxTheme {\n        Surface(\n            modifier = Modifier.fillMaxSize(),\n            content = {\n                Box(\n                    modifier = Modifier.fillMaxSize(),\n                    content = content\n                )\n            }\n        )\n    }\n}\n\n@Composable\ninternal fun modifiedShapes(): Shapes {\n    val shapes = MaterialTheme.shapes\n    val shapesType = LocalSettingsState.current.shapesType\n\n    return remember(shapes, shapesType) {\n        derivedStateOf {\n            shapes.copy(\n                extraSmall = AutoCornersShape(\n                    topStart = shapes.extraSmall.topStart,\n                    topEnd = shapes.extraSmall.topEnd,\n                    bottomEnd = shapes.extraSmall.bottomEnd,\n                    bottomStart = shapes.extraSmall.bottomStart,\n                    shapesType = shapesType\n                ),\n                small = AutoCornersShape(\n                    topStart = shapes.small.topStart,\n                    topEnd = shapes.small.topEnd,\n                    bottomEnd = shapes.small.bottomEnd,\n                    bottomStart = shapes.small.bottomStart,\n                    shapesType = shapesType\n                ),\n                medium = AutoCornersShape(\n                    topStart = shapes.medium.topStart,\n                    topEnd = shapes.medium.topEnd,\n                    bottomEnd = shapes.medium.bottomEnd,\n                    bottomStart = shapes.medium.bottomStart,\n                    shapesType = shapesType\n                ),\n                large = AutoCornersShape(\n                    topStart = shapes.large.topStart,\n                    topEnd = shapes.large.topEnd,\n                    bottomEnd = shapes.large.bottomEnd,\n                    bottomStart = shapes.large.bottomStart,\n                    shapesType = shapesType\n                ),\n                extraLarge = AutoCornersShape(\n                    topStart = shapes.extraLarge.topStart,\n                    topEnd = shapes.extraLarge.topEnd,\n                    bottomEnd = shapes.extraLarge.bottomEnd,\n                    bottomStart = shapes.extraLarge.bottomStart,\n                    shapesType = shapesType\n                ),\n                largeIncreased = AutoCornersShape(\n                    topStart = shapes.largeIncreased.topStart,\n                    topEnd = shapes.largeIncreased.topEnd,\n                    bottomEnd = shapes.largeIncreased.bottomEnd,\n                    bottomStart = shapes.largeIncreased.bottomStart,\n                    shapesType = shapesType\n                ),\n                extraLargeIncreased = AutoCornersShape(\n                    topStart = shapes.extraLargeIncreased.topStart,\n                    topEnd = shapes.extraLargeIncreased.topEnd,\n                    bottomEnd = shapes.extraLargeIncreased.bottomEnd,\n                    bottomStart = shapes.extraLargeIncreased.bottomStart,\n                    shapesType = shapesType\n                ),\n                extraExtraLarge = AutoCornersShape(\n                    topStart = shapes.extraExtraLarge.topStart,\n                    topEnd = shapes.extraExtraLarge.topEnd,\n                    bottomEnd = shapes.extraExtraLarge.bottomEnd,\n                    bottomStart = shapes.extraExtraLarge.bottomStart,\n                    shapesType = shapesType\n                )\n            )\n        }\n    }.value\n}\n\n@Composable\ninternal fun modifiedColorScheme(): ColorScheme {\n    val scheme = MaterialTheme.colorScheme\n\n    return remember(scheme) {\n        derivedStateOf {\n            scheme.copy(\n                errorContainer = scheme.errorContainer.blend(\n                    color = scheme.primary,\n                    fraction = 0.15f\n                )\n            )\n        }\n    }.value\n}\n\nconst val DisabledAlpha = 0.38f"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/theme/ThemePreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.theme\n\nimport android.graphics.BlurMaskFilter\nimport android.graphics.Canvas\nimport android.graphics.LinearGradient\nimport android.graphics.Paint\nimport android.graphics.RadialGradient\nimport android.graphics.Shader\nimport androidx.compose.animation.core.snap\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.core.graphics.createBitmap\nimport coil3.asImage\nimport coil3.compose.AsyncImagePreviewHandler\nimport coil3.compose.LocalAsyncImagePreviewHandler\nimport coil3.request.ImageRequest\nimport coil3.size.pxOrElse\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.DynamicTheme\nimport com.t8rin.dynamic.theme.rememberDynamicThemeState\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.settings.domain.SimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.defaultColorTuple\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getStringLocalized\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberScreenSize\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.initAppContext\nimport java.util.Locale\nimport kotlin.math.max\n\n@Composable\nfun ImageToolboxThemeForPreview(\n    isDarkTheme: Boolean,\n    keyColor: Color? = defaultColorTuple.primary,\n    shapesType: ShapeType = ShapeType.Rounded(),\n    mapSettings: (SettingsState) -> SettingsState = { it },\n    content: @Composable () -> Unit\n) {\n    LocalContext.current.applicationContext.initAppContext()\n\n    FakeLoader(\n        ColorTuple(keyColor ?: Color.Transparent)\n    ) {\n        DynamicTheme(\n            state = rememberDynamicThemeState(\n                initialColorTuple = ColorTuple(keyColor ?: Color.Transparent)\n            ),\n            dynamicColor = keyColor == null,\n            isDarkTheme = isDarkTheme,\n            defaultColorTuple = ColorTuple(keyColor ?: Color.Transparent),\n            colorAnimationSpec = snap(),\n            content = {\n                CompositionLocalProvider(\n                    LocalSettingsState provides mapSettings(SettingsState.Default).toUiState().copy(\n                        shapesType = shapesType\n                    ),\n                    LocalSimpleSettingsInteractor provides FakeSettings,\n                    LocalResourceManager provides FakeRes,\n                    LocalScreenSize provides rememberScreenSize()\n                ) {\n                    MaterialTheme(\n                        motionScheme = CustomMotionScheme,\n                        colorScheme = modifiedColorScheme(),\n                        shapes = modifiedShapes(),\n                        content = {\n                            Surface {\n                                content()\n                            }\n                        }\n                    )\n                }\n            }\n        )\n    }\n}\n\n@Composable\nprivate fun FakeLoader(\n    tuple: ColorTuple,\n    content: @Composable () -> Unit\n) {\n    DynamicTheme(\n        state = rememberDynamicThemeState(tuple),\n        isDarkTheme = false,\n        defaultColorTuple = tuple\n    ) {\n        val colorScheme = MaterialTheme.colorScheme\n\n        val fakeLoader = remember(colorScheme) {\n            AsyncImagePreviewHandler(\n                image = { request: ImageRequest ->\n                    val size = request.sizeResolver.size()\n\n                    val width = size.width.pxOrElse { 800 }.coerceAtLeast(600) - 200\n                    val height = size.height.pxOrElse { 800 }.coerceAtLeast(600)\n\n                    val bitmap = createBitmap(width, height)\n                    val canvas = Canvas(bitmap)\n\n                    val base = LinearGradient(\n                        0f,\n                        0f,\n                        width.toFloat(),\n                        height.toFloat(),\n                        intArrayOf(\n                            colorScheme.primary.toArgb(),\n                            colorScheme.tertiary.toArgb(),\n                            colorScheme.secondary.toArgb(),\n                            colorScheme.error.toArgb(),\n                        ),\n                        floatArrayOf(0f, 0.3f, 0.7f, 1f),\n                        Shader.TileMode.CLAMP\n                    )\n\n                    canvas.drawRect(\n                        0f,\n                        0f,\n                        width.toFloat(),\n                        height.toFloat(),\n                        Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                            shader = base\n                        }\n                    )\n\n                    val blurPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                        color = colorScheme.primaryContainer.toArgb()\n                        maskFilter = BlurMaskFilter(height * 0.08f, BlurMaskFilter.Blur.NORMAL)\n                    }\n\n                    canvas.drawOval(\n                        width * 0.1f,\n                        height * 0.2f,\n                        width * 0.7f,\n                        height * 0.8f,\n                        blurPaint\n                    )\n\n                    canvas.drawOval(\n                        width * 0.5f,\n                        height * 0.1f,\n                        width * 0.95f,\n                        height * 0.6f,\n                        blurPaint\n                    )\n\n                    val noisePaint = Paint().apply {\n                        color = colorScheme.tertiaryContainer.copy(0.5f).toArgb()\n                    }\n\n                    repeat((width * height) / 6) {\n                        val x = (Math.random() * width).toFloat()\n                        val y = (Math.random() * height).toFloat()\n                        canvas.drawPoint(x, y, noisePaint)\n                    }\n\n                    val vignette = RadialGradient(\n                        width / 2f,\n                        height / 2f,\n                        max(width, height) * 0.9f,\n                        intArrayOf(\n                            Color.Transparent.toArgb(),\n                            colorScheme.tertiaryContainer.copy(0.5f).toArgb(),\n                            Color.Transparent.toArgb(),\n                        ),\n                        floatArrayOf(0.6f, 0.85f, 1f),\n                        Shader.TileMode.CLAMP\n                    )\n\n                    canvas.drawRect(\n                        0f,\n                        0f,\n                        width.toFloat(),\n                        height.toFloat(),\n                        Paint().apply { shader = vignette }\n                    )\n\n                    bitmap.asImage()\n                }\n            )\n        }\n\n        CompositionLocalProvider(\n            LocalAsyncImagePreviewHandler provides fakeLoader\n        ) {\n            content()\n        }\n    }\n}\n\nprivate val FakeSettings = object : SimpleSettingsInteractor {\n    override suspend fun toggleMagnifierEnabled() = Unit\n    override suspend fun setOneTimeSaveLocations(value: List<OneTimeSaveLocation>) =\n        Unit\n\n    override suspend fun toggleRecentColor(\n        color: ColorModel,\n        forceExclude: Boolean\n    ) = Unit\n\n    override suspend fun toggleFavoriteColor(\n        color: ColorModel,\n        forceExclude: Boolean\n    ) = Unit\n\n    override fun isInstalledFromPlayStore(): Boolean = false\n\n    override suspend fun toggleSettingsGroupVisibility(\n        key: Int,\n        value: Boolean\n    ) = Unit\n\n    override suspend fun clearRecentColors() = Unit\n\n    override suspend fun updateFavoriteColors(colors: List<ColorModel>) = Unit\n\n    override suspend fun setBackgroundColorForNoAlphaFormats(color: ColorModel) =\n        Unit\n\n    override suspend fun toggleCustomAsciiGradient(gradient: String) = Unit\n\n    override suspend fun toggleOverwriteFiles() = Unit\n\n    override suspend fun setSpotHealMode(mode: Int) = Unit\n    override suspend fun setBorderWidth(width: Float) = Unit\n}\n\nprivate val FakeRes = object : ResourceManager {\n    override fun getString(resId: Int): String = appContext.getString(resId)\n\n    override fun getString(\n        resId: Int,\n        vararg formatArgs: Any\n    ): String = appContext.getString(resId, formatArgs)\n\n    override fun getStringLocalized(\n        resId: Int,\n        language: String\n    ): String =\n        appContext.getStringLocalized(resId, Locale.forLanguageTag(language))\n\n    override fun getStringLocalized(\n        resId: Int,\n        language: String,\n        vararg formatArgs: Any\n    ): String =\n        appContext.getStringLocalized(resId, Locale.forLanguageTag(language))\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/theme/Type.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.theme\n\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Typography\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontSynthesis\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\n\n@Composable\nfun rememberTypography(\n    fontRes: UiFontFamily\n): Typography = remember(fontRes) {\n    derivedStateOf {\n        Typography(\n            displayLarge = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Normal,\n                fontSize = 57.sp,\n                lineHeight = 64.sp,\n                letterSpacing = (-0.25).sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            displayMedium = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Normal,\n                fontSize = 45.sp,\n                lineHeight = 52.sp,\n                letterSpacing = 0.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            displaySmall = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Normal,\n                fontSize = 36.sp,\n                lineHeight = 44.sp,\n                letterSpacing = 0.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            headlineLarge = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Normal,\n                fontSize = 32.sp,\n                lineHeight = 40.sp,\n                letterSpacing = 0.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            headlineMedium = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.SemiBold,\n                fontSize = 28.sp,\n                lineHeight = 36.sp,\n                letterSpacing = 0.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            headlineSmall = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.SemiBold,\n                fontSize = 24.sp,\n                lineHeight = 32.sp,\n                letterSpacing = 0.sp,\n                textAlign = TextAlign.Center,\n                fontSynthesis = FontSynthesis.All\n            ),\n            titleLarge = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.SemiBold,\n                fontSize = 22.sp,\n                lineHeight = 28.sp,\n                letterSpacing = 0.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            titleMedium = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Bold,\n                fontSize = 18.sp,\n                lineHeight = 24.sp,\n                letterSpacing = 0.1.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            titleSmall = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Medium,\n                fontSize = 14.sp,\n                lineHeight = 20.sp,\n                letterSpacing = 0.1.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            bodyLarge = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Normal,\n                fontSize = 16.sp,\n                lineHeight = 24.sp,\n                letterSpacing = 0.5.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            bodyMedium = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Normal,\n                fontSize = 14.sp,\n                lineHeight = 20.sp,\n                letterSpacing = 0.25.sp,\n                textAlign = TextAlign.Center,\n                fontSynthesis = FontSynthesis.All\n            ),\n            bodySmall = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Normal,\n                fontSize = 12.sp,\n                lineHeight = 16.sp,\n                letterSpacing = 0.4.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            labelLarge = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Medium,\n                fontSize = 14.sp,\n                lineHeight = 20.sp,\n                letterSpacing = 0.1.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            labelMedium = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.Medium,\n                fontSize = 12.sp,\n                lineHeight = 16.sp,\n                letterSpacing = 0.5.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n            labelSmall = TextStyle(\n                fontFamily = fontRes.fontFamily,\n                fontWeight = FontWeight.SemiBold,\n                fontSize = 10.sp,\n                lineHeight = 16.sp,\n                letterSpacing = 0.sp,\n                fontSynthesis = FontSynthesis.All\n            ),\n        )\n    }\n}.value\n\n@Composable\nfun ProvideTypography(\n    fontRes: UiFontFamily,\n    content: @Composable () -> Unit\n) {\n    MaterialTheme(\n        typography = rememberTypography(fontRes),\n        content = content\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/transformation/ImageInfoTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.transformation\n\nimport android.graphics.Bitmap\nimport coil3.size.Size\nimport coil3.size.pxOrElse\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.asCoil\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlin.math.roundToInt\nimport coil3.transform.Transformation as CoilTransformation\n\nclass ImageInfoTransformation @AssistedInject internal constructor(\n    @Assisted private val imageInfo: ImageInfo,\n    @Assisted private val preset: Preset,\n    @Assisted private val transformations: List<Transformation<Bitmap>>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>\n) : CoilTransformation(), Transformation<Bitmap> {\n\n    override val cacheKey: String\n        get() = Triple(imageInfo, preset, transformations).hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = transform(input, size.asCoil())\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: Size\n    ): Bitmap {\n        val transformedInput = imageScaler.scaleImage(\n            image = input,\n            width = size.width.pxOrElse { imageInfo.width },\n            height = size.height.pxOrElse { imageInfo.height },\n            resizeType = ResizeType.Flexible\n        )\n\n        val originalUri = shareProvider.cacheImage(\n            image = input,\n            imageInfo = ImageInfo(\n                width = input.width,\n                height = input.height\n            )\n        )\n\n        val presetValue = preset.value()\n        val presetInfo = imageTransformer.applyPresetBy(\n            image = transformedInput,\n            preset = preset,\n            currentInfo = imageInfo.copy(\n                originalUri = originalUri\n            )\n        )\n\n        val info = presetInfo.copy(\n            originalUri = originalUri,\n            resizeType = presetInfo.resizeType.withOriginalSizeIfCrop(\n                if (presetValue != null) {\n                    if (presetValue > 100) {\n                        IntegerSize(\n                            (transformedInput.width.toFloat() / (presetValue / 100f)).roundToInt(),\n                            (transformedInput.height.toFloat() / (presetValue / 100f)).roundToInt()\n                        )\n                    } else {\n                        IntegerSize(\n                            transformedInput.width,\n                            transformedInput.height\n                        )\n                    }\n                } else {\n                    IntegerSize(input.width, input.height)\n                }\n            )\n        )\n\n        return imagePreviewCreator.createPreview(\n            image = transformedInput,\n            imageInfo = info,\n            transformations = transformations,\n            onGetByteCount = {}\n        ) ?: input\n    }\n\n    @AssistedFactory\n    interface Factory {\n        operator fun invoke(\n            imageInfo: ImageInfo,\n            preset: Preset = Preset.Original,\n            transformations: List<Transformation<Bitmap>> = emptyList(),\n        ): ImageInfoTransformation\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/BaseComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.saving.track\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.SaveResultHandler\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.SaveResultHandlerImpl\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.coroutineScope\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.CoroutineExceptionHandler\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.CoroutineStart\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.ensureActive\nimport kotlin.coroutines.CoroutineContext\nimport kotlin.coroutines.EmptyCoroutineContext\nimport kotlinx.coroutines.launch as internalLaunch\n\n@Stable\n@Immutable\nabstract class BaseComponent(\n    private val dispatchersHolder: DispatchersHolder,\n    private val componentContext: ComponentContext\n) : ComponentContext by componentContext,\n    DispatchersHolder by dispatchersHolder,\n    SaveResultHandler by SaveResultHandlerImpl {\n\n    val componentScope = coroutineScope\n\n    protected open val _isImageLoading: MutableState<Boolean> = mutableStateOf(false)\n    open val isImageLoading: Boolean by _isImageLoading\n\n    private var imageCalculationJob: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    inline fun debounce(\n        time: Long = 150,\n        crossinline block: suspend () -> Unit\n    ) {\n        componentScope.launch {\n            delay(time)\n            block()\n        }\n    }\n\n    protected open val _haveChanges: MutableState<Boolean> = mutableStateOf(false)\n    open val haveChanges: Boolean by _haveChanges\n\n    fun trackProgress(\n        action: suspend KeepAliveService.() -> Unit\n    ): Job = componentScope.launch {\n        keepAliveService.track(\n            onFailure = { it.makeLog(\"CRITICAL\") },\n            action = action\n        )\n    }\n\n    protected fun registerSave() {\n        _haveChanges.update { false }\n    }\n\n    protected fun registerChangesCleared() {\n        _haveChanges.update { false }\n    }\n\n    protected fun registerChanges() {\n        _haveChanges.update { true }\n    }\n\n    private var resetJob by smartJob()\n\n    protected open fun debouncedImageCalculation(\n        onFinish: suspend () -> Unit = {},\n        delay: Long = 600L,\n        action: suspend () -> Unit\n    ) {\n        imageCalculationJob = componentScope.launch(\n            CoroutineExceptionHandler { _, t ->\n                t.makeLog()\n                _isImageLoading.update { false }\n            } + defaultDispatcher\n        ) {\n            _isImageLoading.update { true }\n            delay(delay)\n\n            ensureActive()\n\n            action()\n\n            ensureActive()\n\n            _isImageLoading.update { false }\n\n            onFinish()\n        }\n    }\n\n    private fun cancelResetState() {\n        resetJob?.cancel()\n        resetJob = null\n    }\n\n    private fun resetStateDelayed() {\n        resetJob = componentScope.launch {\n            delay(1500)\n            resetState()\n        }\n    }\n\n    @Composable\n    fun AttachLifecycle() {\n        DisposableEffect(Unit) {\n            cancelResetState()\n            onDispose {\n                resetStateDelayed()\n            }\n        }\n    }\n\n    fun cancelImageLoading() {\n        _isImageLoading.update { false }\n        imageCalculationJob?.cancel()\n        imageCalculationJob = null\n    }\n\n    open fun resetState(): Unit =\n        throw IllegalAccessException(\"Cannot reset state of ${this::class.simpleName}\")\n\n    fun CoroutineScope.launch(\n        context: CoroutineContext = EmptyCoroutineContext,\n        start: CoroutineStart = CoroutineStart.DEFAULT,\n        block: suspend CoroutineScope.() -> Unit\n    ): Job = internalLaunch(context, start) {\n        delay(50L)\n        block()\n    }\n\n    companion object {\n        internal var keepAliveService: KeepAliveService = object : KeepAliveService {\n            override fun updateOrStart(\n                title: String,\n                description: String,\n                progress: Float\n            ) = Unit\n\n            override fun stop(removeNotification: Boolean) = Unit\n        }\n\n        fun inject(keepAliveService: KeepAliveService) {\n            this.keepAliveService = keepAliveService\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/ComposeActivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils\n\nimport android.content.Context\nimport android.content.Intent\nimport android.content.res.Configuration\nimport android.os.Bundle\nimport android.view.WindowManager\nimport androidx.activity.enableEdgeToEdge\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen\nimport androidx.core.view.WindowCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.WindowInsetsControllerCompat\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.material.color.DynamicColors\nimport com.google.android.material.color.DynamicColorsOptions\nimport com.t8rin.imagetoolbox.core.di.entryPoint\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.domain.remote.AnalyticsManager\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController.Companion.toMetadataProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.settings.di.SettingsStateEntryPoint\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.domain.toSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.asColorTuple\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.utils.ComposeApplication.Companion.wrap\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.adjustFontSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ReviewHandler\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalKeepAliveService\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalMetadataProvider\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.setContentWithWindowSizeClass\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.AndroidEntryPoint\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.plus\nimport kotlinx.coroutines.runBlocking\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nabstract class ComposeActivity : AppCompatActivity() {\n\n    @Inject\n    lateinit var analyticsManager: AnalyticsManager\n\n    @Inject\n    lateinit var dispatchersHolder: DispatchersHolder\n\n    @Inject\n    lateinit var fileController: FileController\n\n    @Inject\n    lateinit var keepAliveService: KeepAliveService\n\n    @Inject\n    lateinit var resourceManager: ResourceManager\n\n    private lateinit var settingsManager: SettingsManager\n\n    private val activityScope: CoroutineScope\n        get() = lifecycleScope + dispatchersHolder.defaultDispatcher\n\n    private val windowInsetsController: WindowInsetsControllerCompat?\n        get() = window?.let {\n            WindowCompat.getInsetsController(it, it.decorView)\n        }\n\n    private val _settingsState = mutableStateOf(SettingsState.Default)\n    private val settingsState: SettingsState by _settingsState\n\n    @Composable\n    abstract fun Content()\n\n    open fun onFirstLaunch() = handleIntent(intent)\n\n    open fun handleIntent(intent: Intent) = Unit\n\n    override fun onNewIntent(intent: Intent) {\n        super.onNewIntent(intent)\n        handleIntent(intent)\n    }\n\n    override fun attachBaseContext(newBase: Context) {\n        newBase.entryPoint<SettingsStateEntryPoint> {\n            this@ComposeActivity.settingsManager = this.settingsManager\n            _settingsState.update {\n                runBlocking {\n                    settingsManager.getSettingsState()\n                }\n            }\n            handleSystemBarsBehavior()\n            handleSecureMode()\n        }\n        val newOverride = Configuration(newBase.resources?.configuration)\n        settingsState.fontScale?.let { newOverride.fontScale = it }\n        applyOverrideConfiguration(newOverride)\n        super.attachBaseContext(newBase)\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        installSplashScreen()\n        super.onCreate(savedInstanceState)\n        enableEdgeToEdge()\n        wrap(application)?.runSetup()\n\n        observeReview()\n\n        settingsManager\n            .settingsState\n            .onEach { state ->\n                _settingsState.update { state }\n                handleSystemBarsBehavior()\n                handleSecureMode()\n                updateFirebaseParams()\n                applyDynamicColors()\n            }\n            .launchIn(activityScope)\n\n        adjustFontSize(settingsState.fontScale)\n\n        updateFirebaseParams()\n\n        handleSystemBarsBehavior()\n\n        handleSecureMode()\n\n        if (savedInstanceState == null) onFirstLaunch()\n\n        setContentWithWindowSizeClass {\n            CompositionLocalProvider(\n                LocalSimpleSettingsInteractor provides settingsManager.toSimpleSettingsInteractor(),\n                LocalMetadataProvider provides fileController.toMetadataProvider(),\n                LocalKeepAliveService provides keepAliveService,\n                LocalResourceManager provides resourceManager,\n                content = ::Content\n            )\n        }\n    }\n\n    fun applyDynamicColors() {\n        val colorTuple = settingsState.appColorTuple.asColorTuple()\n        DynamicColors.applyToActivityIfAvailable(\n            this@ComposeActivity,\n            DynamicColorsOptions.Builder()\n                .setContentBasedSource(colorTuple.primary.toArgb())\n                .build()\n        )\n    }\n\n    private fun updateFirebaseParams() = analyticsManager.apply {\n        updateAllowCollectCrashlytics(settingsState.allowCollectCrashlytics)\n        updateAnalyticsCollectionEnabled(settingsState.allowCollectCrashlytics)\n    }\n\n    private var recreationJob: Job? by smartJob()\n\n    override fun recreate() {\n        recreationJob = activityScope.launch {\n            delay(200L)\n            runOnUiThread { super.recreate() }\n        }\n    }\n\n    override fun onWindowFocusChanged(hasFocus: Boolean) {\n        super.onWindowFocusChanged(hasFocus)\n        if (hasFocus) handleSystemBarsBehavior()\n        handleSecureMode()\n    }\n\n    override fun onAttachedToWindow() {\n        super.onAttachedToWindow()\n        handleSecureMode()\n    }\n\n    private fun handleSystemBarsBehavior() = runOnUiThread {\n        windowInsetsController?.apply {\n            when (settingsState.systemBarsVisibility) {\n                SystemBarsVisibility.Auto -> {\n                    val orientation = resources.configuration.orientation\n\n                    show(STATUS_BARS)\n\n                    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {\n                        hide(NAV_BARS)\n                    } else {\n                        show(NAV_BARS)\n                    }\n                }\n\n                SystemBarsVisibility.HideAll -> {\n                    hide(SYSTEM_BARS)\n                }\n\n                SystemBarsVisibility.ShowAll -> {\n                    show(SYSTEM_BARS)\n                }\n\n                SystemBarsVisibility.HideNavigationBar -> {\n                    show(STATUS_BARS)\n                    hide(NAV_BARS)\n                }\n\n                SystemBarsVisibility.HideStatusBar -> {\n                    show(NAV_BARS)\n                    hide(STATUS_BARS)\n                }\n            }\n\n            systemBarsBehavior = if (settingsState.isSystemBarsVisibleBySwipe) {\n                WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE\n            } else WindowInsetsControllerCompat.BEHAVIOR_DEFAULT\n        }\n    }\n\n    private fun handleSecureMode() = runOnUiThread {\n        if (settingsState.isSecureMode) {\n            window?.setFlags(\n                WindowManager.LayoutParams.FLAG_SECURE,\n                WindowManager.LayoutParams.FLAG_SECURE\n            )\n        } else {\n            window?.clearFlags(\n                WindowManager.LayoutParams.FLAG_SECURE\n            )\n        }\n    }\n\n    private fun observeReview() {\n        lifecycleScope.launch {\n            ReviewHandler.current.apply {\n                reviewRequests.collect {\n                    makeLog(\"collect reviewRequests\")\n                    showReview(this@ComposeActivity)\n                }\n            }\n        }\n    }\n\n    companion object {\n        private val NAV_BARS = WindowInsetsCompat.Type.navigationBars()\n        private val SYSTEM_BARS = WindowInsetsCompat.Type.systemBars()\n        private val STATUS_BARS = WindowInsetsCompat.Type.statusBars()\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/ComposeApplication.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils\n\nimport android.app.Application\n\nabstract class ComposeApplication : Application() {\n    abstract fun runSetup()\n\n    companion object {\n        fun wrap(application: Application): ComposeApplication? = application as? ComposeApplication\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/animation/Animate.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.animation\n\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.VisibilityThreshold\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.spring\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.unit.Dp\n\n@Composable\nfun Float.animate(\n    animationSpec: AnimationSpec<Float> = spring(),\n    visibilityThreshold: Float = 0.01f,\n    label: String = \"FloatAnimation\",\n    finishedListener: ((Float) -> Unit)? = null\n): Float = animateFloatAsState(\n    targetValue = this,\n    animationSpec = animationSpec,\n    visibilityThreshold = visibilityThreshold,\n    label = label,\n    finishedListener = finishedListener\n).value\n\n@Composable\nfun Dp.animate(\n    animationSpec: AnimationSpec<Dp> = spring(visibilityThreshold = Dp.VisibilityThreshold),\n    label: String = \"FloatAnimation\",\n    finishedListener: ((Dp) -> Unit)? = null\n): Dp = animateDpAsState(\n    targetValue = this,\n    animationSpec = animationSpec,\n    label = label,\n    finishedListener = finishedListener\n).value"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/animation/Animations.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.ui.utils.animation\n\nimport androidx.compose.animation.ContentTransform\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.slideInHorizontally\nimport androidx.compose.animation.slideOutHorizontally\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport com.arkivanov.decompose.extensions.compose.stack.animation.StackAnimation\nimport com.arkivanov.decompose.extensions.compose.stack.animation.fade\nimport com.arkivanov.decompose.extensions.compose.stack.animation.plus\nimport com.arkivanov.decompose.extensions.compose.stack.animation.predictiveback.androidPredictiveBackAnimatableV1\nimport com.arkivanov.decompose.extensions.compose.stack.animation.predictiveback.predictiveBackAnimation\nimport com.arkivanov.decompose.extensions.compose.stack.animation.scale\nimport com.arkivanov.decompose.extensions.compose.stack.animation.slide\nimport com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation\nimport com.arkivanov.essenty.backhandler.BackHandler\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\n\nfun fancySlideTransition(\n    isForward: Boolean,\n    screenWidthPx: Int,\n    duration: Int = 600\n): ContentTransform = if (isForward) {\n    slideInHorizontally(\n        animationSpec = tween(duration, easing = FancyTransitionEasing),\n        initialOffsetX = { screenWidthPx }) + fadeIn(\n        tween(300, 100)\n    ) togetherWith slideOutHorizontally(\n        animationSpec = tween(duration, easing = FancyTransitionEasing),\n        targetOffsetX = { -screenWidthPx }) + fadeOut(\n        tween(300, 100)\n    )\n} else {\n    slideInHorizontally(\n        animationSpec = tween(600, easing = FancyTransitionEasing),\n        initialOffsetX = { -screenWidthPx }) + fadeIn(\n        tween(300, 100)\n    ) togetherWith slideOutHorizontally(\n        animationSpec = tween(600, easing = FancyTransitionEasing),\n        targetOffsetX = { screenWidthPx }) + fadeOut(\n        tween(300, 100)\n    )\n}\n\nfun <NavigationChild : Any> toolboxPredictiveBackAnimation(\n    backHandler: BackHandler,\n    onBack: () -> Unit\n): StackAnimation<Screen, NavigationChild>? = predictiveBackAnimation(\n    backHandler = backHandler,\n    onBack = onBack,\n    fallbackAnimation = stackAnimation(\n        fade(\n            tween(\n                durationMillis = 300,\n                easing = AlphaEasing\n            )\n        ) + slide(\n            tween(\n                durationMillis = 400,\n                easing = FancyTransitionEasing\n            )\n        ) + scale(\n            tween(\n                durationMillis = 500,\n                easing = PointToPointEasing\n            )\n        )\n    ),\n    selector = { backEvent, _, _ -> androidPredictiveBackAnimatableV1(backEvent) },\n)\n\ninline fun <T> springySpec() = spring<T>(\n    dampingRatio = 0.35f,\n    stiffness = Spring.StiffnessLow\n)\n\ninline fun <T> lessSpringySpec() = spring<T>(\n    dampingRatio = 0.4f,\n    stiffness = Spring.StiffnessLow\n)\n\n@Composable\nfun animateFloatingRangeAsState(\n    range: ClosedFloatingPointRange<Float>,\n    animationSpec: AnimationSpec<Float> = spring()\n): State<ClosedFloatingPointRange<Float>> {\n    val start = animateFloatAsState(\n        targetValue = range.start,\n        animationSpec = animationSpec\n    )\n\n    val end = animateFloatAsState(\n        targetValue = range.endInclusive,\n        animationSpec = animationSpec\n    )\n\n    return remember(start, end) {\n        derivedStateOf {\n            start.value..end.value\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/animation/CombinedMutableInteractionSource.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.animation\n\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.merge\n\n@Stable\n@Immutable\nclass CombinedMutableInteractionSource(\n    private val sources: List<MutableInteractionSource>\n) : MutableInteractionSource {\n\n    constructor(vararg sources: MutableInteractionSource) : this(sources.toList())\n\n    override val interactions: Flow<Interaction> =\n        merge(*sources.map { it.interactions }.toTypedArray())\n\n    override suspend fun emit(interaction: Interaction) {\n        sources.forEach { it.emit(interaction) }\n    }\n\n    override fun tryEmit(interaction: Interaction): Boolean {\n        return sources.all { it.tryEmit(interaction) }\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/animation/Easing.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.animation\n\nimport androidx.compose.animation.core.CubicBezierEasing\n\nval FancyTransitionEasing = CubicBezierEasing(0.48f, 0.19f, 0.05f, 1.03f)\n\nval AlphaEasing = CubicBezierEasing(0.4f, 0.4f, 0.17f, 0.9f)\n\nval PointToPointEasing = CubicBezierEasing(0.55f, 0.55f, 0f, 1f)\n\nval FastInvokeEasing = CubicBezierEasing(0f, 0f, 0f, 1f)\n\nval OverslideEasing = CubicBezierEasing(0.5f, 0.5f, 1.0f, 0.25f)\n\nval RotationEasing = CubicBezierEasing(0.46f, 0.03f, 0.52f, 0.96f)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/capturable/Capturable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.capturable\n\nimport android.os.Build\nimport androidx.compose.ui.Modifier\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.impl.capturableNew\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.impl.capturableOld\n\n/**\n * Adds a capture-ability on the Composable which can draw Bitmap from the Composable component.\n *\n * Example usage:\n *\n * ```\n *  val captureController = rememberCaptureController()\n *  val uiScope = rememberCoroutineScope()\n *\n *  // The content to be captured in to Bitmap\n *  Column(\n *      modifier = Modifier.capturable(captureController),\n *  ) {\n *      // Composable content\n *  }\n *\n *  Button(onClick = {\n *      // Capture content\n *      val bitmapAsync = captureController.captureAsync()\n *      try {\n *          val bitmap = bitmapAsync.await()\n *          // Do something with `bitmap`.\n *      } catch (error: Throwable) {\n *          // Error occurred, do something.\n *      }\n *  }) { ... }\n * ```\n *\n * @param controller A [com.t8rin.imagetoolbox.core.ui.utils.capturable.CaptureController] which gives control to capture the Composable content.\n */\nfun Modifier.capturable(controller: CaptureController): Modifier {\n    val sdk = Build.VERSION.SDK_INT\n\n    return when {\n        sdk > Build.VERSION_CODES.N -> capturableNew(controller)\n        else -> capturableOld(controller)\n    }\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/capturable/CaptureController.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.capturable\n\nimport android.graphics.Bitmap\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.layer.GraphicsLayer\nimport androidx.compose.ui.graphics.rememberGraphicsLayer\nimport kotlinx.coroutines.CompletableDeferred\nimport kotlinx.coroutines.Deferred\nimport kotlinx.coroutines.channels.Channel\nimport kotlinx.coroutines.flow.receiveAsFlow\n\n/**\n * Controller for capturing [Composable] content.\n * @see capturable for implementation details.\n */\nclass CaptureController(internal val graphicsLayer: GraphicsLayer) {\n\n    /**\n     * Medium for providing capture requests\n     *\n     * Earlier, we were using `MutableSharedFlow` here but it was incapable of serving requests\n     * which are created as soon as composition starts because this flow was collected later\n     * underneath. So Channel with UNLIMITED capacity just works here and solves the issue as well.\n     * See issue: https://github.com/PatilShreyas/Capturable/issues/202\n     */\n    private val _captureRequests = Channel<CaptureRequest>(capacity = Channel.UNLIMITED)\n    internal val captureRequests = _captureRequests.receiveAsFlow()\n\n    /**\n     * Creates and requests for a Bitmap capture and returns\n     * an [ImageBitmap] asynchronously.\n     *\n     * This method is safe to be called from the \"main\" thread directly.\n     *\n     * Make sure to call this method as a part of callback function and not as a part of the\n     * [Composable] function itself.\n     *\n     */\n    fun captureAsync(): Deferred<ImageBitmap> {\n        val deferredImageBitmap = CompletableDeferred<ImageBitmap>()\n        return deferredImageBitmap.also {\n            _captureRequests.trySend(CaptureRequest(imageBitmapDeferred = it))\n        }\n    }\n\n    suspend fun bitmap(): Bitmap = captureAsync().await().asAndroidBitmap()\n\n    /**\n     * Holds information of capture request\n     */\n    internal class CaptureRequest(val imageBitmapDeferred: CompletableDeferred<ImageBitmap>)\n}\n\n/**\n * Creates [CaptureController] and remembers it.\n */\n@Composable\nfun rememberCaptureController(): CaptureController {\n    val graphicsLayer = rememberGraphicsLayer()\n    return remember(graphicsLayer) { CaptureController(graphicsLayer) }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/capturable/impl/CapturableNew.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.capturable.impl\n\nimport androidx.compose.ui.ExperimentalComposeUiApi\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.CacheDrawModifierNode\nimport androidx.compose.ui.graphics.drawscope.ContentDrawScope\nimport androidx.compose.ui.graphics.layer.drawLayer\nimport androidx.compose.ui.node.DrawModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.platform.InspectorInfo\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.CaptureController\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.launch\n\n/**\n * Adds a capture-ability on the Composable which can draw Bitmap from the Composable component.\n *\n * Example usage:\n *\n * ```\n *  val captureController = rememberCaptureController()\n *  val uiScope = rememberCoroutineScope()\n *\n *  // The content to be captured in to Bitmap\n *  Column(\n *      modifier = Modifier.capturable(captureController),\n *  ) {\n *      // Composable content\n *  }\n *\n *  Button(onClick = {\n *      // Capture content\n *      val bitmapAsync = captureController.captureAsync()\n *      try {\n *          val bitmap = bitmapAsync.await()\n *          // Do something with `bitmap`.\n *      } catch (error: Throwable) {\n *          // Error occurred, do something.\n *      }\n *  }) { ... }\n * ```\n *\n * @param controller A [com.t8rin.imagetoolbox.core.ui.utils.capturable.CaptureController] which gives control to capture the Composable content.\n */\n@ExperimentalComposeUiApi\nfun Modifier.capturableNew(controller: CaptureController): Modifier {\n    return this then CapturableModifierNodeElement(controller)\n}\n\n/**\n * Modifier implementation of Capturable\n */\nprivate data class CapturableModifierNodeElement(\n    private val controller: CaptureController\n) : ModifierNodeElement<CapturableModifierNode>() {\n    override fun create(): CapturableModifierNode {\n        return CapturableModifierNode(controller)\n    }\n\n    override fun update(node: CapturableModifierNode) {\n        node.updateController(controller)\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"capturable\"\n        properties[\"controller\"] = controller\n    }\n}\n\n/**\n * Capturable Modifier node which delegates task to the [CacheDrawModifierNode] for drawing in\n * runtime when content capture is requested\n * [CacheDrawModifierNode] is used for drawing Composable UI from Canvas to the Picture and then\n * this node converts picture into a Bitmap.\n *\n * @param controller A [CaptureController] which gives control to capture the Composable content.\n */\n@Suppress(\"unused\")\nprivate class CapturableModifierNode(\n    controller: CaptureController\n) : Modifier.Node(), DrawModifierNode {\n\n    /**\n     * State to hold the current [CaptureController] instance.\n     * This can be updated via [updateController] method.\n     */\n    private val currentController = MutableStateFlow(controller)\n\n    private val currentGraphicsLayer\n        get() = currentController.value.graphicsLayer\n\n    override fun onAttach() {\n        super.onAttach()\n        coroutineScope.launch {\n            observeCaptureRequestsAndServe()\n        }\n    }\n\n    /**\n     * Sets new [CaptureController]\n     */\n    fun updateController(newController: CaptureController) {\n        currentController.value = newController\n    }\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    private suspend fun observeCaptureRequestsAndServe() {\n        currentController\n            .flatMapLatest { it.captureRequests }\n            .collect { request ->\n                val completable = request.imageBitmapDeferred\n                try {\n                    completable.complete(currentGraphicsLayer.toImageBitmap())\n                } catch (error: Throwable) {\n                    completable.completeExceptionally(error)\n                }\n            }\n    }\n\n    // Ref:\n    // https://developer.android.com/develop/ui/compose/graphics/draw/modifiers#composable-to-bitmap\n    override fun ContentDrawScope.draw() {\n        currentGraphicsLayer.record {\n            // draw the contents of the composable into the graphics layer\n            this@draw.drawContent()\n        }\n        // draw the graphics layer on the visible canvas\n        drawLayer(currentGraphicsLayer)\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/capturable/impl/CapturableOld.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.capturable.impl\n\nimport android.annotation.SuppressLint\nimport android.graphics.Bitmap\nimport android.graphics.Color\nimport android.graphics.Picture\nimport android.os.Build\nimport androidx.compose.ui.ExperimentalComposeUiApi\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.CacheDrawModifierNode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.drawscope.draw\nimport androidx.compose.ui.graphics.drawscope.drawIntoCanvas\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.node.DelegatableNode\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.CaptureController\nimport kotlinx.coroutines.CompletableDeferred\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\n/**\n * Adds a capture-ability on the Composable which can draw Bitmap from the Composable component.\n *\n * Example usage:\n *\n * ```\n *  val captureController = rememberCaptureController()\n *  val uiScope = rememberCoroutineScope()\n *\n *  // The content to be captured in to Bitmap\n *  Column(\n *      modifier = Modifier.capturable(captureController),\n *  ) {\n *      // Composable content\n *  }\n *\n *  Button(onClick = {\n *      // Capture content\n *      val bitmapAsync = captureController.captureAsync()\n *      try {\n *          val bitmap = bitmapAsync.await()\n *          // Do something with `bitmap`.\n *      } catch (error: Throwable) {\n *          // Error occurred, do something.\n *      }\n *  }) { ... }\n * ```\n *\n * @param controller A [com.t8rin.imagetoolbox.core.ui.utils.capturable.CaptureController] which gives control to capture the Composable content.\n */\n@ExperimentalComposeUiApi\nfun Modifier.capturableOld(controller: CaptureController): Modifier {\n    return this then CapturableModifierNodeElementOld(controller)\n}\n\n/**\n * Modifier implementation of Capturable\n */\n@SuppressLint(\"ModifierNodeInspectableProperties\")\nprivate data class CapturableModifierNodeElementOld(\n    private val controller: CaptureController\n) : ModifierNodeElement<CapturableModifierNodeOld>() {\n    override fun create(): CapturableModifierNodeOld {\n        return CapturableModifierNodeOld(controller)\n    }\n\n    override fun update(node: CapturableModifierNodeOld) {\n        node.updateController(controller)\n    }\n}\n\n/**\n * Capturable Modifier node which delegates task to the [CacheDrawModifierNode] for drawing in\n * runtime when content capture is requested\n * [CacheDrawModifierNode] is used for drawing Composable UI from Canvas to the Picture and then\n * this node converts picture into a Bitmap.\n *\n * @param controller A [CaptureController] which gives control to capture the Composable content.\n */\n@Suppress(\"unused\")\nprivate class CapturableModifierNodeOld(\n    controller: CaptureController\n) : DelegatingNode(), DelegatableNode {\n\n    /**\n     * State to hold the current [CaptureController] instance.\n     * This can be updated via [updateController] method.\n     */\n    private val currentController = MutableStateFlow(controller)\n\n    override fun onAttach() {\n        super.onAttach()\n        coroutineScope.launch {\n            observeCaptureRequestsAndServe()\n        }\n    }\n\n    /**\n     * Sets new [CaptureController]\n     */\n    fun updateController(newController: CaptureController) {\n        currentController.value = newController\n    }\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    private suspend fun observeCaptureRequestsAndServe() {\n        currentController\n            .flatMapLatest { it.captureRequests }\n            .collect { request ->\n                val completable = request.imageBitmapDeferred\n                try {\n                    val picture = getCurrentContentAsPicture()\n                    val bitmap = withContext(Dispatchers.Default) {\n                        picture.asBitmap(Bitmap.Config.ARGB_8888)\n                    }\n                    completable.complete(bitmap.asImageBitmap())\n                } catch (error: Throwable) {\n                    completable.completeExceptionally(error)\n                }\n            }\n    }\n\n    private suspend fun getCurrentContentAsPicture(): Picture {\n        return Picture().apply { drawCanvasIntoPicture(this) }\n    }\n\n    /**\n     * Draws the current content into the provided [picture]\n     */\n    private suspend fun drawCanvasIntoPicture(picture: Picture) {\n        // CompletableDeferred to wait until picture is drawn from the Canvas content\n        val pictureDrawn = CompletableDeferred<Unit>()\n\n        // Delegate the task to draw the content into the picture\n        val delegatedNode = delegate(\n            CacheDrawModifierNode {\n                val width = this.size.width.toInt()\n                val height = this.size.height.toInt()\n\n                onDrawWithContent {\n                    val pictureCanvas = Canvas(picture.beginRecording(width, height))\n\n                    draw(this, this.layoutDirection, pictureCanvas, this.size) {\n                        this@onDrawWithContent.drawContent()\n                    }\n                    picture.endRecording()\n\n                    drawIntoCanvas { canvas ->\n                        canvas.nativeCanvas.drawPicture(picture)\n\n                        // Notify that picture is drawn\n                        pictureDrawn.complete(Unit)\n                    }\n                }\n            }\n        )\n        // Wait until picture is drawn\n        pictureDrawn.await()\n\n        // As task is accomplished, remove the delegation of node to prevent draw operations on UI\n        // updates or recompositions.\n        undelegate(delegatedNode)\n    }\n}\n\n/**\n * Creates a [Bitmap] from a [Picture] with provided [config]\n */\nprivate fun Picture.asBitmap(config: Bitmap.Config): Bitmap {\n    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {\n        Bitmap.createBitmap(this@asBitmap)\n    } else {\n        val bitmap = createBitmap(this@asBitmap.width, this@asBitmap.height, config)\n        val canvas = android.graphics.Canvas(bitmap)\n        canvas.drawColor(Color.WHITE)\n        canvas.drawPicture(this@asBitmap)\n        bitmap\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/confetti/ConfettiHostState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.confetti\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ColorHarmonizer\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastHostState\nimport nl.dionsegijn.konfetti.compose.KonfettiView\nimport nl.dionsegijn.konfetti.core.Party\n\n@Stable\n@Immutable\nclass ConfettiHostState : ToastHostState() {\n    suspend fun showConfetti(\n        duration: ToastDuration = ToastDuration(4500L)\n    ) = showToast(message = \"\", duration = duration)\n}\n\n@Composable\nfun ConfettiHost(\n    hostState: ConfettiHostState,\n    particles: @Composable (harmonizer: Color) -> List<Party>\n) {\n    ToastHost(\n        hostState = hostState,\n        transitionSpec = {\n            fadeIn() togetherWith fadeOut()\n        },\n        toast = {\n            val settingsState = LocalSettingsState.current\n            val colorScheme = MaterialTheme.colorScheme\n            val confettiHarmonizationLevel = settingsState.confettiHarmonizationLevel\n            val harmonizationColor = when (\n                val harmonizer = settingsState.confettiColorHarmonizer\n            ) {\n                is ColorHarmonizer.Custom -> Color(harmonizer.color)\n                ColorHarmonizer.Primary -> colorScheme.primary\n                ColorHarmonizer.Secondary -> colorScheme.secondary\n                ColorHarmonizer.Tertiary -> colorScheme.tertiary\n            }\n            KonfettiView(\n                modifier = Modifier.fillMaxSize(),\n                parties = particles(harmonizationColor.copy(confettiHarmonizationLevel))\n            )\n        },\n        enableSwipes = false\n    )\n}\n\n@Composable\nfun ConfettiHost() {\n    val settingsState = LocalSettingsState.current\n\n    AnimatedVisibility(settingsState.isConfettiEnabled) {\n        ConfettiHost(\n            hostState = AppToastHost.confettiState,\n            particles = { harmonizer ->\n                val particlesType by remember(settingsState.confettiType) {\n                    derivedStateOf {\n                        Particles.Type.entries.first {\n                            it.ordinal == settingsState.confettiType\n                        }\n                    }\n                }\n\n                remember {\n                    Particles(\n                        harmonizer = harmonizer\n                    ).build(particlesType)\n                }\n            }\n        )\n    }\n\n    if (!settingsState.isConfettiEnabled) {\n        SideEffect {\n            AppToastHost.confettiState.currentToastData?.dismiss()\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/confetti/Particles.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.confetti\n\nimport androidx.appcompat.content.res.AppCompatResources\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport nl.dionsegijn.konfetti.core.Angle\nimport nl.dionsegijn.konfetti.core.Party\nimport nl.dionsegijn.konfetti.core.Position\nimport nl.dionsegijn.konfetti.core.Spread\nimport nl.dionsegijn.konfetti.core.emitter.Emitter\nimport nl.dionsegijn.konfetti.core.models.Shape\nimport nl.dionsegijn.konfetti.xml.image.DrawableImage\nimport java.util.concurrent.TimeUnit\nimport kotlin.math.roundToInt\nimport kotlin.random.Random\n\n\nprivate val Color1 = Color(0xfffce18a)\nprivate val Color2 = Color(0xFF009688)\nprivate val Color3 = Color(0xfff4306d)\nprivate val Color4 = Color(0xffb48def)\nprivate val Color5 = Color(0xFF95FF82)\nprivate val Color6 = Color(0xFF82ECFF)\nprivate val Color7 = Color(0xFFFF9800)\nprivate val Color8 = Color(0xFF0E008A)\n\nprivate val defaultColors = listOf(\n    Color1, Color2, Color3, Color4, Color5, Color6, Color7, Color8\n)\n\nprivate fun List<Color>.mapToPrimary(primary: Color): List<Int> = map {\n    it.blend(primary.copy(1f), primary.alpha).toArgb()\n}\n\nprivate val defaultShapes by lazy {\n    listOf(Shape.Square, Shape.Circle, Shape.Rectangle(0.2f))\n}\n\nprivate val confettiCache = mutableMapOf<Color, MutableMap<Particles.Type, List<Party>>>()\n\n\n@Stable\nclass Particles(\n    private val harmonizer: Color\n) {\n    fun build(\n        type: Type\n    ): List<Party> = confettiCache[harmonizer]?.get(type) ?: when (type) {\n        Type.Default -> default(harmonizer)\n        Type.Festive -> festiveBottom(harmonizer)\n        Type.Explode -> explode(harmonizer)\n        Type.Rain -> rain(harmonizer)\n        Type.Side -> side(harmonizer)\n        Type.Corners -> festiveCorners(harmonizer)\n        Type.Toolbox -> toolbox(harmonizer)\n    }.also {\n        if (confettiCache[harmonizer]?.put(type, it) == null) {\n            confettiCache[harmonizer] = mutableMapOf(type to it)\n        }\n    }\n\n    companion object {\n\n        private fun festive(\n            primary: Color,\n            xPos: Double = 0.5,\n            yPos: Double = 1.0,\n            angle: Int = Angle.TOP,\n            duration: Long = 500,\n            delay: Int = 0,\n            spread: Int = 45\n        ): List<Party> = Party(\n            speed = 30f,\n            maxSpeed = 50f,\n            damping = 0.9f,\n            angle = angle,\n            spread = spread,\n            shapes = defaultShapes,\n            delay = delay,\n            timeToLive = 3000L,\n            colors = defaultColors.mapToPrimary(primary),\n            emitter = Emitter(duration = duration, TimeUnit.MILLISECONDS).max(30),\n            position = Position.Relative(xPos, yPos)\n        ).let { party ->\n            listOf(\n                party,\n                party.copy(\n                    speed = 55f,\n                    maxSpeed = 65f,\n                    spread = (spread * 0.22f).roundToInt(),\n                    emitter = Emitter(duration = duration, TimeUnit.MILLISECONDS).max(10),\n                ),\n                party.copy(\n                    speed = 50f,\n                    maxSpeed = 60f,\n                    spread = (spread * 2.67f).roundToInt(),\n                    emitter = Emitter(duration = duration, TimeUnit.MILLISECONDS).max(40),\n                ),\n                party.copy(\n                    speed = 65f,\n                    maxSpeed = 80f,\n                    spread = (spread * 0.22f).roundToInt(),\n                    emitter = Emitter(duration = duration, TimeUnit.MILLISECONDS).max(10),\n                )\n            )\n        }\n\n        fun default(\n            primary: Color\n        ): List<Party> = listOf(\n            Party(\n                speed = 0f,\n                maxSpeed = 15f,\n                damping = 0.9f,\n                angle = Angle.BOTTOM,\n                spread = Spread.ROUND,\n                colors = defaultColors.mapToPrimary(primary),\n                shapes = defaultShapes,\n                emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(100),\n                position = Position.Relative(0.0, 0.0).between(Position.Relative(1.0, 0.0))\n            ),\n            Party(\n                speed = 10f,\n                maxSpeed = 30f,\n                damping = 0.9f,\n                angle = Angle.RIGHT - 45,\n                spread = 60,\n                colors = defaultColors.mapToPrimary(primary),\n                shapes = defaultShapes,\n                emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(100),\n                position = Position.Relative(0.0, 1.0)\n            ),\n            Party(\n                speed = 10f,\n                maxSpeed = 30f,\n                damping = 0.9f,\n                angle = Angle.RIGHT - 135,\n                spread = 60,\n                colors = defaultColors.mapToPrimary(primary),\n                shapes = defaultShapes,\n                emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(100),\n                position = Position.Relative(1.0, 1.0)\n            )\n        )\n\n        fun festiveBottom(\n            primary: Color\n        ): List<Party> = festive(primary, 0.2)\n            .plus(festive(primary, 0.8))\n\n        fun explode(\n            primary: Color,\n            shape: Shape? = null,\n            initialDelay: Int = 0\n        ): List<Party> = Party(\n            speed = 0f,\n            maxSpeed = 30f,\n            damping = 0.9f,\n            spread = 360,\n            shapes = shape?.let { listOf(it) } ?: defaultShapes,\n            timeToLive = 3000,\n            colors = defaultColors.mapToPrimary(primary),\n            emitter = Emitter(duration = 200, TimeUnit.MILLISECONDS).max(100)\n        ).let { party ->\n            val (x1, y1) = Random.nextDouble(0.0, 0.3) to Random.nextDouble(0.0, 0.5)\n            val (x2, y2) = Random.nextDouble(0.0, 0.3) to Random.nextDouble(0.5, 1.0)\n            val (x3, y3) = Random.nextDouble(0.3, 0.7) to Random.nextDouble(0.0, 1.0)\n            val (x4, y4) = Random.nextDouble(0.7, 1.0) to Random.nextDouble(0.0, 0.5)\n            val (x5, y5) = Random.nextDouble(0.7, 1.0) to Random.nextDouble(0.5, 1.0)\n\n            listOf(\n                party.copy(\n                    position = Position.Relative(x1, y1),\n                    delay = initialDelay\n                ),\n                party.copy(\n                    position = Position.Relative(x2, y2),\n                    delay = initialDelay + 200\n                ),\n                party.copy(\n                    position = Position.Relative(x3, y3),\n                    delay = initialDelay + 400\n                ),\n                party.copy(\n                    position = Position.Relative(x4, y4),\n                    delay = initialDelay + 600\n                ),\n                party.copy(\n                    position = Position.Relative(x5, y5),\n                    delay = initialDelay + 800\n                )\n            )\n        }\n\n        fun rain(\n            primary: Color\n        ): List<Party> = Party(\n            speed = 10f,\n            maxSpeed = 30f,\n            damping = 0.9f,\n            shapes = defaultShapes,\n            colors = defaultColors.mapToPrimary(primary),\n            emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(100),\n        ).let { party ->\n            listOf(\n                party.copy(\n                    angle = 45,\n                    position = Position.Relative(0.0, 0.0),\n                    spread = 90,\n                ),\n                party.copy(\n                    angle = 90,\n                    position = Position.Relative(0.5, 0.0),\n                    spread = 360,\n                ),\n                party.copy(\n                    angle = 135,\n                    position = Position.Relative(1.0, 0.0),\n                    spread = 90,\n                )\n            )\n        }\n\n        fun side(\n            primary: Color\n        ): List<Party> = listOf(\n            festive(primary, 0.0, 0.0, Angle.RIGHT, 1000),\n            festive(primary, 1.0, 0.33, Angle.LEFT, 1000, 150),\n            festive(primary, 0.0, 0.66, Angle.RIGHT, 1000, 300),\n            festive(primary, 1.0, 1.0, Angle.LEFT, 1000, 450),\n        ).flatten()\n\n        fun festiveCorners(\n            primary: Color\n        ): List<Party> = listOf(\n            festive(primary, 0.0, 0.0, 45, 1000, 0, 25),\n            festive(primary, 1.0, 0.0, 135, 1000, 150, 25),\n            festive(primary, 0.0, 1.0, -45, 1000, 300, 25),\n            festive(primary, 1.0, 1.0, 225, 1000, 450, 25),\n        ).flatten()\n\n        fun toolbox(\n            primary: Color\n        ): List<Party> = Shape.DrawableShape(\n            AppCompatResources.getDrawable(\n                appContext,\n                R.drawable.ic_launcher_monochrome_24\n            )!!.let {\n                DrawableImage(\n                    drawable = it,\n                    width = it.intrinsicWidth,\n                    height = it.intrinsicHeight\n                )\n            }\n        ).let { shape ->\n            val delay = 400\n            explode(primary, shape) + explode(primary, shape, delay)\n        }\n\n    }\n\n    enum class Type {\n        Default, Festive, Explode, Rain, Side, Corners, Toolbox\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/BarcodeScanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CameraAlt\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.onPrimaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.theme.onTertiaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.theme.primaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.core.utils.toQrType\nimport com.t8rin.logger.makeLog\nimport io.github.g00fy2.quickie.QRResult\nimport io.github.g00fy2.quickie.ScanCustomCode\nimport io.github.g00fy2.quickie.config.BarcodeFormat\nimport io.github.g00fy2.quickie.config.ScannerConfig\n\nprivate class BarcodeScannerImpl(\n    private val tint: Color,\n    private val container: Color,\n    private val frame: Color,\n    private val frameHighlighted: Color,\n    private val topIcon: Color,\n    private val topText: Color,\n    private val scannerLauncher: ManagedActivityResultLauncher<ScannerConfig, QRResult>\n) : BarcodeScanner {\n\n    override fun scan() {\n        val config = ScannerConfig.build {\n            setBarcodeFormats(listOf(BarcodeFormat.ALL_FORMATS))\n            setOverlayStringRes(R.string.scan_barcode)\n            setOverlayDrawableRes(R.drawable.ic_24_barcode_scanner)\n            setHapticSuccessFeedback(true)\n            setShowTorchToggle(true)\n            setShowCloseButton(true)\n            setKeepScreenOn(true)\n            setColors(\n                buttonTint = tint.toArgb(),\n                buttonBackground = container.toArgb(),\n                frame = frame.toArgb(),\n                frameHighlighted = frameHighlighted.toArgb(),\n                topIcon = topIcon.toArgb(),\n                topText = topText.toArgb()\n            )\n        }.makeLog(\"Barcode Scanner\")\n\n        scannerLauncher.launch(config)\n    }\n\n}\n\n@Stable\n@Immutable\ninterface BarcodeScanner : Scanner\n\n@Composable\nfun rememberBarcodeScanner(\n    onSuccess: (QrType) -> Unit\n): BarcodeScanner {\n    val scannerLauncher = rememberLauncherForActivityResult(ScanCustomCode()) { result ->\n        result.makeLog(\"Barcode Scanner\")\n\n        when (result) {\n            is QRResult.QRError -> {\n                appContext.apply {\n                    val message = result.exception.localizedMessage ?: \"\"\n\n                    AppToastHost.showFailureToast(\n                        if (\"NotFound\" in message) {\n                            getString(R.string.no_barcode_found)\n                        } else {\n                            getString(R.string.smth_went_wrong, message)\n                        }\n                    )\n                }\n            }\n\n            QRResult.QRMissingPermission -> {\n                AppToastHost.showToast(\n                    message = getString(R.string.grant_camera_permission_to_scan_qr_code),\n                    icon = Icons.Outlined.CameraAlt\n                )\n            }\n\n            is QRResult.QRSuccess -> onSuccess(result.content.toQrType())\n\n            QRResult.QRUserCanceled -> Unit\n        }\n    }\n\n    val tint = MaterialTheme.colorScheme.onPrimaryContainerFixed\n    val container = MaterialTheme.colorScheme.primaryContainerFixed\n    val frame = MaterialTheme.colorScheme.onPrimaryContainerFixed\n    val frameHighlighted = MaterialTheme.colorScheme.onTertiaryContainerFixed\n    val topIcon = MaterialTheme.colorScheme.secondaryFixed\n    val topText = MaterialTheme.colorScheme.secondaryFixed\n\n    return remember(tint, container, frame, frameHighlighted, topIcon, topText, scannerLauncher) {\n        BarcodeScannerImpl(\n            tint = tint,\n            container = container,\n            frame = frame,\n            frameHighlighted = frameHighlighted,\n            topIcon = topIcon,\n            topText = topText,\n            scannerLauncher = scannerLauncher,\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/ContactPicker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport android.Manifest\nimport android.content.Context\nimport android.content.pm.PackageManager\nimport android.database.Cursor\nimport android.net.Uri\nimport android.provider.ContactsContract\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.activity.result.launch\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PersonOutline\nimport androidx.compose.material.icons.rounded.Person\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.core.content.ContextCompat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nprivate data class ContactPickerImpl(\n    val context: Context,\n    val pickContact: ManagedActivityResultLauncher<Void?, Uri?>,\n    val requestPermissionLauncher: ManagedActivityResultLauncher<String, Boolean>,\n    val onFailure: (Throwable) -> Unit\n) : ContactPicker {\n\n    override fun pickContact() {\n        \"Pick Contact Start\".makeLog()\n        runCatching {\n            if (ContextCompat.checkSelfPermission(\n                    context,\n                    Manifest.permission.READ_CONTACTS\n                ) == PackageManager.PERMISSION_GRANTED\n            ) {\n                pickContact.launch()\n            } else {\n                requestPermissionLauncher.launch(Manifest.permission.READ_CONTACTS)\n            }\n        }.onFailure {\n            it.makeLog(\"Pick Contact Failure\")\n            onFailure(it)\n        }.onSuccess {\n            \"Pick Contact Success\".makeLog()\n        }\n    }\n\n}\n\n\n@Stable\n@Immutable\ninterface ContactPicker : ResultLauncher {\n    fun pickContact()\n    override fun launch() = pickContact()\n}\n\n@Composable\nfun rememberContactPicker(\n    onFailure: () -> Unit = {},\n    onSuccess: (Contact) -> Unit,\n): ContactPicker {\n    val scope = rememberCoroutineScope()\n    val context = LocalComponentActivity.current\n\n    val pickContact = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.PickContact(),\n        onResult = { uri ->\n            uri?.takeIf {\n                it != Uri.EMPTY\n            }?.let {\n                scope.launch {\n                    delay(200)\n                    onSuccess(it.parseContact())\n                }\n            } ?: onFailure()\n        }\n    )\n\n    val requestPermissionLauncher = rememberLauncherForActivityResult(\n        ActivityResultContracts.RequestPermission()\n    ) { isGranted: Boolean ->\n        if (isGranted) {\n            pickContact.launch()\n        } else {\n            AppToastHost.showToast(\n                message = getString(R.string.grant_contact_permission),\n                icon = Icons.Outlined.PersonOutline\n            )\n        }\n    }\n\n    return remember(pickContact) {\n        derivedStateOf {\n            ContactPickerImpl(\n                context = context,\n                pickContact = pickContact,\n                requestPermissionLauncher = requestPermissionLauncher,\n                onFailure = {\n                    onFailure()\n                    AppToastHost.showFailureToast(it)\n                }\n            )\n        }\n    }.value\n}\n\n@Composable\nfun ContactPickerButton(onPicked: (Contact) -> Unit) {\n    val contactPicker = rememberContactPicker(onSuccess = onPicked)\n\n    EnhancedButton(\n        onClick = contactPicker::pickContact,\n        modifier = Modifier.fillMaxWidth(),\n        containerColor = MaterialTheme.colorScheme.mixedContainer,\n        contentColor = MaterialTheme.colorScheme.onMixedContainer\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.Person,\n                contentDescription = null\n            )\n            Spacer(Modifier.width(4.dp))\n            Text(\n                text = stringResource(R.string.pick_contact)\n            )\n        }\n    }\n}\n\ndata class Contact(\n    val addresses: List<Address>,\n    val emails: List<Email>,\n    val name: PersonName,\n    val organization: String,\n    val phones: List<Phone>,\n    val title: String,\n    val urls: List<String>\n) {\n    constructor() : this(\n        addresses = emptyList(),\n        emails = emptyList(),\n        name = PersonName(),\n        organization = \"\",\n        phones = emptyList(),\n        title = \"\",\n        urls = emptyList()\n    )\n\n    data class Address(\n        val addressLines: List<String>,\n        val type: Int\n    )\n\n    data class PersonName(\n        val first: String,\n        val formattedName: String,\n        val last: String,\n        val middle: String,\n        val prefix: String,\n        val pronunciation: String,\n        val suffix: String\n    ) {\n        constructor() : this(\n            first = \"\",\n            formattedName = \"\",\n            last = \"\",\n            middle = \"\",\n            prefix = \"\",\n            pronunciation = \"\",\n            suffix = \"\"\n        )\n\n        fun isEmpty() = first.isBlank() &&\n                formattedName.isBlank() &&\n                last.isBlank() &&\n                middle.isBlank() &&\n                prefix.isBlank() &&\n                pronunciation.isBlank() &&\n                suffix.isBlank()\n    }\n\n    data class Email(\n        val address: String,\n        val body: String,\n        val subject: String,\n        val type: Int\n    ) {\n        constructor() : this(\n            address = \"\",\n            body = \"\",\n            subject = \"\",\n            type = 0\n        )\n\n        fun isEmpty(): Boolean = address.isBlank() && body.isBlank() && subject.isBlank()\n    }\n\n    data class Phone(\n        val number: String,\n        val type: Int\n    ) {\n        constructor() : this(\n            number = \"\",\n            type = 0\n        )\n\n        fun isEmpty(): Boolean = number.isBlank()\n    }\n\n    fun isEmpty(): Boolean =\n        addresses.isEmpty() && emails.isEmpty() && name.isEmpty() && organization.isBlank() && phones.isEmpty() && title.isBlank() && urls.isEmpty()\n}\n\nprivate suspend fun Uri.parseContact(): Contact = withContext(Dispatchers.IO) {\n    val context = appContext\n    val resolver = context.contentResolver\n    var contactId: String? = null\n    var name = Contact.PersonName()\n    var organization = \"\"\n    var title = \"\"\n    val phones = mutableListOf<Contact.Phone>()\n    val emails = mutableListOf<Contact.Email>()\n    val addresses = mutableListOf<Contact.Address>()\n    val urls = mutableListOf<String>()\n\n    resolver.query(this@parseContact, null, null, null, null)?.use { cursor ->\n        if (cursor.moveToFirst()) {\n            contactId = cursor.getStringOrEmpty(ContactsContract.Contacts._ID)\n        }\n    }\n\n    contactId?.let { id ->\n        // StructuredName\n        resolver.query(\n            ContactsContract.Data.CONTENT_URI,\n            null,\n            \"${ContactsContract.Data.CONTACT_ID}=? AND ${ContactsContract.Data.MIMETYPE}=?\",\n            arrayOf(id, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE),\n            null\n        )?.use { c ->\n            if (c.moveToFirst()) {\n                name = Contact.PersonName(\n                    first = c.getStringOrEmpty(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME),\n                    formattedName = c.getStringOrEmpty(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME),\n                    last = c.getStringOrEmpty(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME),\n                    middle = c.getStringOrEmpty(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME),\n                    prefix = c.getStringOrEmpty(ContactsContract.CommonDataKinds.StructuredName.PREFIX),\n                    pronunciation = c.getStringOrEmpty(ContactsContract.Contacts.PHONETIC_NAME),\n                    suffix = c.getStringOrEmpty(ContactsContract.CommonDataKinds.StructuredName.SUFFIX)\n                )\n            }\n        }\n\n        // Phones\n        resolver.query(\n            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,\n            null,\n            \"${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} = ?\",\n            arrayOf(id),\n            null\n        )?.use { c ->\n            while (c.moveToNext()) {\n                phones.add(\n                    Contact.Phone(\n                        number = c.getStringOrEmpty(ContactsContract.CommonDataKinds.Phone.NUMBER),\n                        type = c.getIntOrZero(ContactsContract.CommonDataKinds.Phone.TYPE)\n                    )\n                )\n            }\n        }\n\n        // Emails\n        resolver.query(\n            ContactsContract.CommonDataKinds.Email.CONTENT_URI,\n            null,\n            \"${ContactsContract.CommonDataKinds.Email.CONTACT_ID} = ?\",\n            arrayOf(id),\n            null\n        )?.use { c ->\n            while (c.moveToNext()) {\n                emails.add(\n                    Contact.Email(\n                        address = c.getStringOrEmpty(ContactsContract.CommonDataKinds.Email.ADDRESS),\n                        body = \"\",\n                        subject = \"\",\n                        type = c.getIntOrZero(ContactsContract.CommonDataKinds.Email.TYPE)\n                    )\n                )\n            }\n        }\n\n        // Addresses\n        resolver.query(\n            ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,\n            null,\n            \"${ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID} = ?\",\n            arrayOf(id),\n            null\n        )?.use { c ->\n            while (c.moveToNext()) {\n                val address = c.getStringOrEmpty(\n                    ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS\n                )\n                if (address.isNotBlank()) {\n                    addresses.add(\n                        Contact.Address(\n                            addressLines = address.split(\"\\n\"),\n                            type = c.getIntOrZero(ContactsContract.CommonDataKinds.StructuredPostal.TYPE)\n                        )\n                    )\n                }\n            }\n        }\n\n        // Organization + Title\n        resolver.query(\n            ContactsContract.Data.CONTENT_URI,\n            null,\n            \"${ContactsContract.Data.CONTACT_ID}=? AND ${ContactsContract.Data.MIMETYPE}=?\",\n            arrayOf(id, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE),\n            null\n        )?.use { c ->\n            if (c.moveToFirst()) {\n                organization =\n                    c.getStringOrEmpty(ContactsContract.CommonDataKinds.Organization.COMPANY)\n                title = c.getStringOrEmpty(ContactsContract.CommonDataKinds.Organization.TITLE)\n            }\n        }\n\n        // Websites\n        resolver.query(\n            ContactsContract.Data.CONTENT_URI,\n            null,\n            \"${ContactsContract.Data.CONTACT_ID}=? AND ${ContactsContract.Data.MIMETYPE}=?\",\n            arrayOf(id, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE),\n            null\n        )?.use { c ->\n            while (c.moveToNext()) {\n                val url = c.getStringOrEmpty(ContactsContract.CommonDataKinds.Website.URL)\n                if (url.isNotBlank()) urls.add(url)\n            }\n        }\n    }\n\n    Contact(\n        addresses = addresses,\n        emails = emails,\n        name = name,\n        organization = organization,\n        phones = phones,\n        title = title,\n        urls = urls\n    )\n}\n\nprivate fun Cursor.getStringOrEmpty(column: String): String =\n    runCatching { getString(getColumnIndexOrThrow(column)) }.getOrNull() ?: \"\"\n\nprivate fun Cursor.getIntOrZero(column: String): Int =\n    runCatching { getInt(getColumnIndexOrThrow(column)) }.getOrNull() ?: 0"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/DocumentScanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ScanResult\n\n@Stable\n@Immutable\ninterface DocumentScanner : Scanner\n\n@Composable\nfun rememberDocumentScanner(\n    onSuccess: (ScanResult) -> Unit\n): DocumentScanner = rememberDocumentScannerImpl(onSuccess)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/FileMaker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport android.net.Uri\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n\nprivate data class FileMakerImpl(\n    val createDocument: ManagedActivityResultLauncher<String, Uri?>,\n    val onFailure: (Throwable) -> Unit\n) : FileMaker {\n\n    override fun make(name: String) {\n        \"File Make Start\".makeLog()\n        runCatching {\n            createDocument.launch(name)\n        }.onFailure {\n            it.makeLog(\"File Make Failure\")\n            onFailure(it)\n        }.onSuccess {\n            \"File Make Success\".makeLog()\n        }\n    }\n\n}\n\n\n@Stable\n@Immutable\ninterface FileMaker : ResultLauncher {\n    fun make(name: String)\n    override fun launch() = make(\"\")\n}\n\n@Composable\nfun rememberFileCreator(\n    mimeType: MimeType.Single = MimeType.All,\n    onFailure: () -> Unit = {},\n    onSuccess: (Uri) -> Unit,\n): FileMaker {\n    val scope = rememberCoroutineScope()\n    val createDocument = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.CreateDocument(mimeType.entry),\n        onResult = { uri ->\n            scope.launch {\n                delay(300)\n                uri?.takeIf {\n                    it != Uri.EMPTY\n                }?.let {\n                    onSuccess(it)\n                } ?: onFailure()\n            }\n        }\n    )\n\n    return remember(createDocument) {\n        derivedStateOf {\n            FileMakerImpl(\n                createDocument = createDocument,\n                onFailure = {\n                    onFailure()\n                    AppToastHost.handleFileSystemFailure(it)\n                }\n            )\n        }\n    }.value\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/FilePicker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport android.content.Context\nimport android.net.Uri\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.platform.LocalContext\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\nprivate data class FilePickerImpl(\n    val context: Context,\n    val type: FileType,\n    val mimeType: MimeType,\n    val openDocument: ManagedActivityResultLauncher<Array<String>, Uri?>,\n    val openDocumentMultiple: ManagedActivityResultLauncher<Array<String>, List<Uri>>,\n    val onFailure: (Throwable) -> Unit\n) : FilePicker {\n\n    override fun pickFile() {\n        (type to mimeType).makeLog(\"File Picker Start\")\n\n        runCatching {\n            when (type) {\n                FileType.Single -> openDocument.launch(mimeType.entries.toTypedArray())\n                FileType.Multiple -> openDocumentMultiple.launch(mimeType.entries.toTypedArray())\n            }\n        }.onFailure {\n            it.makeLog(\"File Picker Failure\")\n            onFailure(it)\n        }.onSuccess {\n            (type to mimeType).makeLog(\"File Picker Success\")\n        }\n    }\n\n}\n\n@Stable\n@Immutable\ninterface FilePicker : ResultLauncher {\n    fun pickFile()\n    override fun launch() = pickFile()\n}\n\nenum class FileType {\n    Single, Multiple\n}\n\n@Composable\nfun rememberFilePicker(\n    type: FileType,\n    mimeType: MimeType = MimeType.All,\n    onFailure: () -> Unit = {},\n    onSuccess: (List<Uri>) -> Unit,\n): FilePicker {\n    val context = LocalContext.current\n\n    val scope = rememberCoroutineScope()\n\n    val openDocument = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.OpenDocument(),\n        onResult = { uri ->\n            scope.launch {\n                delay(300)\n                uri?.takeIf {\n                    it != Uri.EMPTY\n                }?.let {\n                    onSuccess(listOf(it))\n                } ?: onFailure()\n            }\n        }\n    )\n    val openDocumentMultiple = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.OpenMultipleDocuments(),\n        onResult = { uris ->\n            scope.launch {\n                delay(300)\n                uris.takeIf { it.isNotEmpty() }?.let(onSuccess) ?: onFailure()\n            }\n        }\n    )\n\n    return remember(\n        type,\n        mimeType,\n        openDocument,\n        openDocumentMultiple\n    ) {\n        derivedStateOf {\n            FilePickerImpl(\n                context = context,\n                type = type,\n                mimeType = mimeType,\n                openDocument = openDocument,\n                openDocumentMultiple = openDocumentMultiple,\n                onFailure = {\n                    onFailure()\n                    AppToastHost.handleFileSystemFailure(it)\n                }\n            )\n        }\n    }.value\n}\n\n@JvmName(\"rememberMultipleFilePicker\")\n@Composable\nfun rememberFilePicker(\n    mimeType: MimeType = MimeType.All,\n    onFailure: () -> Unit = {},\n    onSuccess: (List<Uri>) -> Unit,\n): FilePicker = rememberFilePicker(\n    type = FileType.Multiple,\n    mimeType = mimeType,\n    onFailure = onFailure,\n    onSuccess = onSuccess\n)\n\n@JvmName(\"rememberSingleFilePicker\")\n@Composable\nfun rememberFilePicker(\n    mimeType: MimeType = MimeType.All,\n    onFailure: () -> Unit = {},\n    onSuccess: (Uri) -> Unit,\n): FilePicker = rememberFilePicker(\n    type = FileType.Single,\n    mimeType = mimeType,\n    onFailure = onFailure,\n    onSuccess = {\n        it.firstOrNull()?.let(onSuccess)\n    }\n)\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/FolderPicker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport android.net.Uri\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.takePersistablePermission\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n\nprivate data class FolderPickerImpl(\n    val openDocumentTree: ManagedActivityResultLauncher<Uri?, Uri?>,\n    val onFailure: (Throwable) -> Unit\n) : FolderPicker {\n\n    override fun pickFolder(initialLocation: Uri?) {\n        \"Folder Open Start\".makeLog()\n        runCatching {\n            openDocumentTree.launch(initialLocation)\n        }.onFailure {\n            it.makeLog(\"Folder Open Failure\")\n            onFailure(it)\n        }.onSuccess {\n            \"Folder Open Success\".makeLog()\n        }\n    }\n\n}\n\n\n@Stable\n@Immutable\ninterface FolderPicker : ResultLauncher {\n    fun pickFolder(initialLocation: Uri? = null)\n    override fun launch() = pickFolder()\n}\n\n@Composable\nfun rememberFolderPicker(\n    onFailure: () -> Unit = {},\n    onSuccess: (Uri) -> Unit,\n): FolderPicker {\n    val scope = rememberCoroutineScope()\n    val openDocumentTree = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.OpenDocumentTree(),\n        onResult = { uri ->\n            scope.launch {\n                delay(300)\n                uri?.takeIf {\n                    it != Uri.EMPTY\n                }?.let {\n                    onSuccess(uri.takePersistablePermission())\n                } ?: onFailure()\n            }\n        }\n    )\n\n    return remember(openDocumentTree) {\n        derivedStateOf {\n            FolderPickerImpl(\n                openDocumentTree = openDocumentTree,\n                onFailure = {\n                    onFailure()\n                    AppToastHost.handleFileSystemFailure(it)\n                }\n            )\n        }\n    }.value\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/ImagePicker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport android.Manifest\nimport android.content.Context\nimport android.content.Intent\nimport android.net.Uri\nimport android.provider.MediaStore\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.ActivityResult\nimport androidx.activity.result.PickVisualMediaRequest\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CameraAlt\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.graphics.Color\nimport androidx.core.content.FileProvider\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.PicturePickerMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.IntentUtils.parcelable\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.IntentUtils.parcelableArrayList\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.clipList\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.createMediaPickerIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport java.io.File\nimport kotlin.random.Random\n\n\nprivate class ImagePickerImpl(\n    private val context: Context,\n    private val mode: ImagePickerMode,\n    private val currentAccent: Color,\n    private val photoPickerSingle: ManagedActivityResultLauncher<PickVisualMediaRequest, Uri?>,\n    private val photoPickerMultiple: ManagedActivityResultLauncher<PickVisualMediaRequest, List<Uri>>,\n    private val getContent: ManagedActivityResultLauncher<Intent, ActivityResult>,\n    private val takePhoto: ManagedActivityResultLauncher<Uri, Boolean>,\n    private val onCreateTakePhotoUri: (Uri) -> Unit,\n    private val imageExtension: String,\n    private val onFailure: (Throwable) -> Unit,\n) : ImagePicker {\n    override fun pickImage() {\n        val cameraAction = {\n            val imagesFolder = File(context.cacheDir, \"images\")\n            runCatching {\n                imagesFolder.mkdirs()\n                val file = File(imagesFolder, \"${Random.nextLong()}.jpg\")\n                FileProvider.getUriForFile(\n                    context,\n                    context.getString(R.string.file_provider),\n                    file\n                )\n            }.onFailure {\n                it.makeLog(\"Image Picker\")\n            }.onSuccess {\n                onCreateTakePhotoUri(it)\n                takePhoto.launch(it)\n            }\n        }\n        val singlePhotoPickerAction = {\n            photoPickerSingle.launch(\n                PickVisualMediaRequest(\n                    ActivityResultContracts.PickVisualMedia.ImageOnly\n                )\n            )\n        }\n        val multiplePhotoPickerAction = {\n            photoPickerMultiple.launch(\n                PickVisualMediaRequest(\n                    ActivityResultContracts.PickVisualMedia.ImageOnly\n                )\n            )\n        }\n        val galleryAction = {\n            val intent = Intent(Intent.ACTION_PICK).apply {\n                setDataAndType(\n                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,\n                    \"image/$imageExtension\"\n                )\n                if (mode == ImagePickerMode.GalleryMultiple) {\n                    putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)\n                }\n            }\n            getContent.launch(\n                Intent.createChooser(\n                    intent,\n                    context.getString(R.string.pick_image)\n                )\n            )\n        }\n        val embeddedAction = {\n            getContent.launch(\n                createMediaPickerIntent(\n                    context = context,\n                    allowMultiple = mode == ImagePickerMode.EmbeddedMultiple,\n                    currentAccent = currentAccent,\n                    imageExtension = imageExtension\n                )\n            )\n        }\n        val getContentAction = {\n            val intent = Intent().apply {\n                type = \"image/$imageExtension\"\n                action = Intent.ACTION_OPEN_DOCUMENT\n                putExtra(\n                    Intent.EXTRA_ALLOW_MULTIPLE,\n                    mode == ImagePickerMode.GetContentMultiple\n                )\n            }\n            getContent.launch(\n                Intent.createChooser(\n                    intent,\n                    context.getString(R.string.pick_image)\n                )\n            )\n        }\n\n        mode.makeLog(\"Image Picker Start\")\n\n        runCatching {\n            when (mode) {\n                ImagePickerMode.PhotoPickerSingle -> singlePhotoPickerAction()\n                ImagePickerMode.PhotoPickerMultiple -> multiplePhotoPickerAction()\n                ImagePickerMode.CameraCapture -> cameraAction()\n\n                ImagePickerMode.GallerySingle,\n                ImagePickerMode.GalleryMultiple -> galleryAction()\n\n                ImagePickerMode.GetContentSingle,\n                ImagePickerMode.GetContentMultiple -> getContentAction()\n\n                ImagePickerMode.Embedded,\n                ImagePickerMode.EmbeddedMultiple -> embeddedAction()\n            }\n        }.onFailure {\n            it.makeLog(\"Image Picker Failure\")\n            if (it is SecurityException && mode == ImagePickerMode.CameraCapture) {\n                onFailure(CameraException())\n            } else onFailure(it)\n        }.onSuccess {\n            mode.makeLog(\"Image Picker Success\")\n        }\n    }\n\n    override fun pickImageWithMode(\n        picker: Picker,\n        picturePickerMode: PicturePickerMode\n    ) {\n        val multiple = picker == Picker.Multiple\n        val mode = when (picturePickerMode) {\n            PicturePickerMode.Embedded -> if (multiple) ImagePickerMode.EmbeddedMultiple else ImagePickerMode.Embedded\n            PicturePickerMode.PhotoPicker -> if (multiple) ImagePickerMode.PhotoPickerMultiple else ImagePickerMode.PhotoPickerSingle\n            PicturePickerMode.Gallery -> if (multiple) ImagePickerMode.GalleryMultiple else ImagePickerMode.GallerySingle\n            PicturePickerMode.GetContent -> if (multiple) ImagePickerMode.GetContentMultiple else ImagePickerMode.GetContentSingle\n            PicturePickerMode.CameraCapture -> ImagePickerMode.CameraCapture\n        }\n\n        val basePicker = ImagePickerImpl(\n            context = context,\n            mode = mode,\n            currentAccent = currentAccent,\n            photoPickerSingle = photoPickerSingle,\n            photoPickerMultiple = photoPickerMultiple,\n            getContent = getContent,\n            takePhoto = takePhoto,\n            onCreateTakePhotoUri = onCreateTakePhotoUri,\n            imageExtension = imageExtension,\n            onFailure = onFailure\n        )\n\n        basePicker.pickImage()\n    }\n}\n\n@Stable\n@Immutable\ninterface ImagePicker : ResultLauncher {\n\n    fun pickImage()\n\n    fun pickImageWithMode(\n        picker: Picker,\n        picturePickerMode: PicturePickerMode\n    )\n\n    override fun launch() = pickImage()\n\n}\n\nenum class ImagePickerMode {\n    Embedded,\n    EmbeddedMultiple,\n    PhotoPickerSingle,\n    PhotoPickerMultiple,\n    GallerySingle,\n    GalleryMultiple,\n    GetContentSingle,\n    GetContentMultiple,\n    CameraCapture\n}\n\nenum class Picker {\n    Single, Multiple\n}\n\n@Composable\nfun localImagePickerMode(\n    picker: Picker = Picker.Single,\n    mode: PicturePickerMode = LocalSettingsState.current.picturePickerMode,\n): ImagePickerMode {\n    return remember(mode, picker) {\n        derivedStateOf {\n            val multiple = picker == Picker.Multiple\n\n            when (mode) {\n                PicturePickerMode.Embedded -> if (multiple) ImagePickerMode.EmbeddedMultiple else ImagePickerMode.Embedded\n                PicturePickerMode.PhotoPicker -> if (multiple) ImagePickerMode.PhotoPickerMultiple else ImagePickerMode.PhotoPickerSingle\n                PicturePickerMode.Gallery -> if (multiple) ImagePickerMode.GalleryMultiple else ImagePickerMode.GallerySingle\n                PicturePickerMode.GetContent -> if (multiple) ImagePickerMode.GetContentMultiple else ImagePickerMode.GetContentSingle\n                PicturePickerMode.CameraCapture -> ImagePickerMode.CameraCapture\n            }\n        }\n    }.value\n}\n\n@Composable\nfun rememberImagePicker(\n    picker: Picker = Picker.Single,\n    imageExtension: String = DefaultExtension,\n    onFailure: () -> Unit = {},\n    onSuccess: (List<Uri>) -> Unit,\n): ImagePicker = rememberImagePicker(\n    mode = localImagePickerMode(picker = picker),\n    imageExtension = imageExtension,\n    onFailure = onFailure,\n    onSuccess = onSuccess\n)\n\n@JvmName(\"rememberSingleImagePicker\")\n@Composable\nfun rememberImagePicker(\n    imageExtension: String = DefaultExtension,\n    onFailure: () -> Unit = {},\n    onSuccess: (Uri) -> Unit,\n): ImagePicker = rememberImagePicker(\n    mode = localImagePickerMode(picker = Picker.Single),\n    imageExtension = imageExtension,\n    onFailure = onFailure,\n    onSuccess = {\n        it.firstOrNull()?.let(onSuccess)\n    }\n)\n\n@JvmName(\"rememberMultipleImagePicker\")\n@Composable\nfun rememberImagePicker(\n    imageExtension: String = DefaultExtension,\n    onFailure: () -> Unit = {},\n    onSuccess: (List<Uri>) -> Unit,\n): ImagePicker = rememberImagePicker(\n    mode = localImagePickerMode(picker = Picker.Multiple),\n    imageExtension = imageExtension,\n    onFailure = onFailure,\n    onSuccess = onSuccess\n)\n\n@Composable\nfun rememberImagePicker(\n    mode: ImagePickerMode,\n    imageExtension: String = DefaultExtension,\n    onFailure: () -> Unit = {},\n    onSuccess: (List<Uri>) -> Unit,\n): ImagePicker {\n    val scope = rememberCoroutineScope()\n    val context = LocalComponentActivity.current\n\n    val photoPickerSingle = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.PickVisualMedia(),\n        onResult = { uri ->\n            scope.launch {\n                delay(300)\n                uri?.takeIf {\n                    it != Uri.EMPTY\n                }?.let {\n                    onSuccess(listOf(it))\n                } ?: onFailure()\n            }\n        }\n    )\n    val photoPickerMultiple = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.PickMultipleVisualMedia(),\n        onResult = { uris ->\n            scope.launch {\n                delay(300)\n                uris.takeIf { it.isNotEmpty() }?.let(onSuccess) ?: onFailure()\n            }\n        }\n    )\n\n    val getContent = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.StartActivityForResult(),\n        onResult = { result ->\n            val intent = result.data\n            val data = intent?.data\n            val clipData = intent?.clipData\n\n            val resultList: List<Uri> = clipData?.clipList()\n                ?: if (data != null) {\n                    listOf(data)\n                } else if (intent?.action == Intent.ACTION_SEND_MULTIPLE) {\n                    intent.parcelableArrayList<Uri>(Intent.EXTRA_STREAM) ?: emptyList()\n                } else if (intent?.action == Intent.ACTION_SEND) {\n                    listOfNotNull(intent.parcelable<Uri>(Intent.EXTRA_STREAM))\n                } else {\n                    emptyList()\n                }\n\n            scope.launch {\n                delay(300)\n                resultList.takeIf { it.isNotEmpty() }?.let(onSuccess) ?: onFailure()\n            }\n        }\n    )\n\n    var takePhotoUri by rememberSaveable {\n        mutableStateOf<Uri?>(null)\n    }\n    val takePhoto = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.TakePicture(),\n        onResult = {\n            scope.launch {\n                val uri = takePhotoUri\n                delay(300)\n                if (it && uri != null && uri != Uri.EMPTY) {\n                    onSuccess(listOf(uri))\n                } else onFailure()\n                takePhotoUri = null\n            }\n        }\n    )\n\n    val currentAccent = LocalDynamicThemeState.current.colorTuple.value.primary\n\n    val requestPermissionLauncher = rememberLauncherForActivityResult(\n        ActivityResultContracts.RequestPermission()\n    ) { isGranted: Boolean ->\n        if (!isGranted) {\n            AppToastHost.showToast(\n                message = context.getString(R.string.grant_camera_permission_to_capture_image),\n                icon = Icons.Outlined.CameraAlt\n            )\n        }\n    }\n\n    return remember(\n        imageExtension,\n        currentAccent,\n        photoPickerSingle,\n        photoPickerMultiple,\n        getContent,\n        takePhoto,\n        mode\n    ) {\n        derivedStateOf {\n            ImagePickerImpl(\n                context = context,\n                mode = mode,\n                currentAccent = currentAccent,\n                photoPickerSingle = photoPickerSingle,\n                photoPickerMultiple = photoPickerMultiple,\n                getContent = getContent,\n                takePhoto = takePhoto,\n                onCreateTakePhotoUri = {\n                    takePhotoUri = it\n                },\n                imageExtension = imageExtension,\n                onFailure = {\n                    onFailure()\n\n                    when (it) {\n                        is CameraException -> requestPermissionLauncher.launch(Manifest.permission.CAMERA)\n                        else -> AppToastHost.handleFileSystemFailure(it)\n                    }\n                }\n            )\n        }\n    }.value\n}\n\nprivate class CameraException : Throwable(\"No Camera permission\")\n\nprivate const val DefaultExtension: String = \"*\""
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/ResultLauncher.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\n\n@Stable\n@Immutable\ninterface ResultLauncher {\n    fun launch()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/Scanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\n\n@Stable\n@Immutable\ninterface Scanner : ResultLauncher {\n    fun scan()\n    override fun launch() = scan()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/ActivityUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.Context\nimport android.content.Intent\nimport android.provider.MediaStore\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.utils.Flavor\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\n\nval AppActivityClass: Class<*> by lazy {\n    Class.forName(\n        \"com.t8rin.imagetoolbox.app.presentation.AppActivity\"\n    )\n}\n\nval MediaPickerActivityClass: Class<*> by lazy {\n    Class.forName(\n        \"com.t8rin.imagetoolbox.feature.media_picker.presentation.MediaPickerActivity\"\n    )\n}\n\nfun createMediaPickerIntent(\n    context: Context,\n    allowMultiple: Boolean,\n    currentAccent: Color,\n    imageExtension: String\n): Intent = Intent(\n    Intent.ACTION_PICK,\n    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,\n    context,\n    MediaPickerActivityClass\n).apply {\n    setDataAndType(\n        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,\n        \"image/$imageExtension\"\n    )\n    if (allowMultiple) {\n        putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)\n    }\n    putExtra(ColorSchemeName, currentAccent.toArgb())\n}\n\nval AppVersionPreRelease: String by lazy {\n    BuildConfig.VERSION_NAME\n        .replace(BuildConfig.FLAVOR, \"\")\n        .split(\"-\")\n        .takeIf { it.size > 1 }\n        ?.drop(1)?.first()\n        ?.takeWhile { it.isLetter() } ?: \"\"\n}\n\nval AppVersionPreReleaseFlavored: String by lazy {\n    if (!Flavor.isFoss()) {\n        AppVersionPreRelease\n    } else {\n        \"${BuildConfig.FLAVOR} $AppVersionPreRelease\"\n    }.uppercase()\n}\n\nval AppVersion: String by lazy {\n    BuildConfig.VERSION_NAME + if (Flavor.isFoss()) \"-foss\" else \"\"\n}\n\nconst val ColorSchemeName = \"scheme\""
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/AppToastHost.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.ActivityNotFoundException\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FolderOff\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.confetti.ConfettiHostState\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastHostState\nimport com.t8rin.imagetoolbox.core.ui.widget.other.showFailureToast\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlin.coroutines.CoroutineContext\n\ndata object AppToastHost {\n\n    private var context: CoroutineContext = Dispatchers.Unconfined\n    private val scope by lazy { CoroutineScope(context) }\n\n    val state = ToastHostState()\n\n    val confettiState = ConfettiHostState()\n\n    fun init(context: CoroutineContext) {\n        this.context = context\n    }\n\n    fun showToast(\n        message: String,\n        icon: ImageVector? = null,\n        duration: ToastDuration = ToastDuration.Short\n    ) {\n        scope.launch {\n            state.showToast(\n                message = message,\n                icon = icon,\n                duration = duration\n            )\n        }\n    }\n\n    fun showToast(\n        message: Int,\n        icon: ImageVector? = null,\n        duration: ToastDuration = ToastDuration.Short\n    ) {\n        scope.launch {\n            state.showToast(\n                message = getString(message),\n                icon = icon,\n                duration = duration\n            )\n        }\n    }\n\n    fun showFailureToast(throwable: Throwable) {\n        scope.launch {\n            state.showFailureToast(\n                context = appContext,\n                throwable = throwable\n            )\n        }\n    }\n\n    fun showFailureToast(message: String) {\n        scope.launch {\n            state.showFailureToast(\n                message = message\n            )\n        }\n    }\n\n    fun showFailureToast(res: Int) {\n        scope.launch {\n            state.showFailureToast(\n                message = appContext.getString(res)\n            )\n        }\n    }\n\n    fun dismissToasts() {\n        state.currentToastData?.dismiss()\n        confettiState.currentToastData?.dismiss()\n    }\n\n    fun showConfetti(\n        duration: ToastDuration\n    ) {\n        scope.launch {\n            confettiState.showConfetti(duration)\n        }\n    }\n\n    fun showConfetti() {\n        showConfetti(ToastDuration(4500L))\n    }\n\n    fun handleFileSystemFailure(throwable: Throwable) {\n        when (throwable) {\n            is ActivityNotFoundException -> showActivateFilesToast()\n            else -> showFailureToast(throwable)\n        }\n    }\n\n    const val PERMISSION = \"REQUEST_PERMISSION\"\n\n    private fun showActivateFilesToast() {\n        showToast(\n            message = appContext.getString(R.string.activate_files),\n            icon = Icons.Outlined.FolderOff,\n            duration = ToastDuration.Long\n        )\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/BlendingModeExt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.os.Build\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\n\nval BlendingMode.Companion.entries: List<BlendingMode>\n    get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n        newEntries\n    } else oldEntries"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/Clipboard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.ClipData\nimport android.content.ClipboardManager\nimport android.content.Context\nimport android.net.Uri\nimport android.os.Build\nimport androidx.annotation.StringRes\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CopyAll\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.ClipEntry\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\n\nobject Clipboard {\n\n    private val clipboard by lazy { AndroidClipboardManager() }\n\n    fun copy(\n        clipEntry: ClipEntry?,\n        onSuccess: () -> Unit = {}\n    ) {\n        runCatching {\n            clipboard.setClip(clipEntry)\n        }.onSuccess {\n            onSuccess()\n        }.onFailure {\n            AppToastHost.showFailureToast(getString(R.string.data_is_too_large_to_copy))\n        }\n    }\n\n    fun copy(\n        uri: Uri,\n        @StringRes message: Int = R.string.copied,\n        icon: ImageVector = Icons.Rounded.CopyAll\n    ) {\n        copy(\n            clipEntry = uri.asClip(appContext),\n            onSuccess = {\n                AppToastHost.showConfetti()\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {\n                    AppToastHost.showToast(\n                        message = getString(message),\n                        icon = icon\n                    )\n                }\n            }\n        )\n    }\n\n    fun copy(\n        text: CharSequence,\n        @StringRes message: Int = R.string.copied,\n        icon: ImageVector = Icons.Rounded.CopyAll\n    ) {\n        copy(\n            clipEntry = ClipEntry(text.toClipData()),\n            onSuccess = {\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {\n                    AppToastHost.showToast(\n                        message = getString(message),\n                        icon = icon\n                    )\n                }\n            }\n        )\n    }\n\n    fun getText(\n        onSuccess: (String) -> Unit\n    ) {\n        runCatching {\n            clipboard.getClip()\n                ?.clipData?.let { primaryClip ->\n                    if (primaryClip.itemCount > 0) {\n                        primaryClip.getItemAt(0)?.text\n                    } else {\n                        null\n                    }\n                }?.takeIf { it.isNotEmpty() }?.let {\n                    onSuccess(it.toString())\n                }\n        }.onFailure {\n            AppToastHost.showFailureToast(getString(R.string.clipboard_data_is_too_large))\n        }\n    }\n\n    fun clear() {\n        runCatching {\n            clipboard.setClip(null)\n        }\n    }\n\n}\n\nprivate class AndroidClipboardManager {\n    private val clipboardManager: ClipboardManager get() = appContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager\n\n    fun getClip(): ClipEntry? = clipboardManager.primaryClip?.let(::ClipEntry)\n\n    fun setClip(clipEntry: ClipEntry?) {\n        if (clipEntry == null) {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {\n                clipboardManager.clearPrimaryClip()\n            } else {\n                clipboardManager.setPrimaryClip(ClipData.newPlainText(\"\", \"\"))\n            }\n        } else {\n            clipboardManager.setPrimaryClip(clipEntry.clipData)\n        }\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/ClipboardUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.ClipData\nimport android.content.ClipDescription\nimport android.content.ClipboardManager\nimport android.content.Context\nimport android.net.Uri\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.platform.ClipEntry\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.core.content.getSystemService\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isFromAppFileProvider\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.moveToCache\n\n@Composable\nfun rememberClipboardData(): State<List<Uri>> {\n    val settingsState = LocalSettingsState.current\n    val allowPaste = settingsState.allowAutoClipboardPaste\n\n    val context = LocalContext.current\n    val clipboardManager = remember(context) {\n        context.getSystemService<ClipboardManager>()\n    }\n\n    val clip = remember {\n        mutableStateOf(\n            if (allowPaste) {\n                clipboardManager.clipList()\n            } else emptyList()\n        )\n    }.apply {\n        value = if (allowPaste) {\n            clipboardManager.clipList()\n        } else emptyList()\n    }\n\n    val callback = remember {\n        ClipboardManager.OnPrimaryClipChangedListener {\n            if (allowPaste) {\n                clip.value = clipboardManager.clipList()\n            }\n        }\n    }\n    DisposableEffect(clipboardManager, allowPaste) {\n        if (allowPaste) {\n            clipboardManager?.addPrimaryClipChangedListener(callback)\n        }\n        onDispose {\n            clipboardManager?.removePrimaryClipChangedListener(callback)\n        }\n    }\n    return clip\n}\n\n@Composable\nfun rememberClipboardText(): State<String> {\n    val settingsState = LocalSettingsState.current\n    val allowPaste = settingsState.allowAutoClipboardPaste\n\n    val context = LocalContext.current\n    val clipboardManager = remember(context) {\n        context.getSystemService<ClipboardManager>()\n    }\n\n    val clip = remember {\n        mutableStateOf(\n            if (allowPaste) {\n                clipboardManager.clipText()\n            } else \"\"\n        )\n    }.apply {\n        value = if (allowPaste) {\n            clipboardManager.clipText()\n        } else \"\"\n    }\n\n    val callback = remember {\n        ClipboardManager.OnPrimaryClipChangedListener {\n            if (allowPaste) {\n                clip.value = clipboardManager.clipText()\n            }\n        }\n    }\n    DisposableEffect(clipboardManager, allowPaste) {\n        if (allowPaste) {\n            clipboardManager?.addPrimaryClipChangedListener(callback)\n        }\n        onDispose {\n            clipboardManager?.removePrimaryClipChangedListener(callback)\n        }\n    }\n    return clip\n}\n\nfun ClipboardManager?.clipList(): List<Uri> = runCatching {\n    this?.primaryClip?.clipList()\n}.getOrNull() ?: emptyList()\n\nfun ClipboardManager?.clipText(): String = runCatching {\n    this?.primaryClip?.getItemAt(0)?.text?.toString()\n}.getOrNull() ?: \"\"\n\nfun ClipData.clipList() = List(\n    size = itemCount,\n    init = { index ->\n        getItemAt(index).uri?.let { uri ->\n            if (uri.isFromAppFileProvider()) uri else uri.moveToCache()\n        }\n    }\n).filterNotNull()\n\nfun List<Uri>.toClipData(\n    description: String = \"Images\",\n    mimeTypes: Array<String> = arrayOf(\"image/*\")\n): ClipData? {\n    if (this.isEmpty()) return null\n\n    return ClipData(\n        ClipDescription(\n            description,\n            mimeTypes\n        ),\n        ClipData.Item(this.first())\n    ).apply {\n        this@toClipData.drop(1).forEach {\n            addItem(ClipData.Item(it))\n        }\n    }\n}\n\nfun CharSequence.toClipData(\n    label: String = \"plain text\"\n): ClipData = ClipData.newPlainText(label, this)\n\nfun Uri.asClip(\n    context: Context,\n    label: String = \"Image\"\n): ClipEntry = ClipEntry(\n    ClipData.newUri(\n        context.contentResolver,\n        label,\n        this\n    )\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/CoilUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.graphics.Bitmap\nimport coil3.size.Size\nimport coil3.size.pxOrElse\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport coil3.transform.Transformation as CoilTransformation\n\nfun Size.asDomain(): IntegerSize = if (this == Size.ORIGINAL) IntegerSize.Undefined\nelse IntegerSize(width.pxOrElse { 1 }, height.pxOrElse { 1 })\n\nfun IntegerSize.asCoil(): Size = if (this == IntegerSize.Undefined) Size.ORIGINAL\nelse Size(width, height)\n\nfun Transformation<Bitmap>.toCoil(): CoilTransformation = object : CoilTransformation() {\n    private val instance = this@toCoil\n\n    override fun toString(): String = instance::class.simpleName.toString()\n\n    override val cacheKey: String\n        get() = instance.cacheKey\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: Size\n    ): Bitmap = instance.transform(input, size.asDomain())\n\n}\n\nfun CoilTransformation.asDomain(): Transformation<Bitmap> = object : Transformation<Bitmap> {\n    override val cacheKey: String\n        get() = this@asDomain.cacheKey\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = this@asDomain.transform(input, size.asCoil())\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/ColorUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\n\nfun Color.toHex(): String =\n    String.format(\"#%08X\", (0xFFFFFFFF and this.toArgb().toLong())).replace(\"#FF\", \"#\")\n\ninline fun ColorModel.toColor() = Color(colorInt)\n\ninline fun Color.toModel() = ColorModel(toArgb())\n\ninline val ColorModel.red: Float\n    get() = toColor().red\n\ninline val ColorModel.green: Float\n    get() = toColor().green\n\ninline val ColorModel.blue: Float\n    get() = toColor().blue\n\ninline val ColorModel.alpha: Float\n    get() = toColor().alpha\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/CompositionLocalUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport kotlin.reflect.KProperty\n\n@Composable\nfun <T> ProvidableCompositionLocal<T>.ProvidesValue(\n    value: T,\n    content: @Composable () -> Unit\n) = CompositionLocalProvider(value = this provides value, content)\n\n@Composable\noperator fun <T> ProvidableCompositionLocal<T>.getValue(\n    t: T?,\n    property: KProperty<*>\n): T = current"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/ContextUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.Manifest\nimport android.annotation.SuppressLint\nimport android.app.Activity\nimport android.app.ActivityManager\nimport android.content.ClipboardManager\nimport android.content.ContentResolver\nimport android.content.Context\nimport android.content.ContextWrapper\nimport android.content.Intent\nimport android.content.res.Configuration\nimport android.net.ConnectivityManager\nimport android.net.NetworkCapabilities\nimport android.net.Uri\nimport android.os.Build\nimport android.provider.Settings\nimport android.webkit.MimeTypeMap\nimport android.widget.Toast\nimport androidx.annotation.RequiresApi\nimport androidx.annotation.StringRes\nimport androidx.appcompat.app.AppCompatDelegate\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.unit.Density\nimport androidx.core.app.ActivityCompat\nimport androidx.core.app.PendingIntentCompat\nimport androidx.core.content.getSystemService\nimport androidx.core.content.pm.ShortcutInfoCompat\nimport androidx.core.content.pm.ShortcutManagerCompat\nimport androidx.core.graphics.drawable.IconCompat\nimport androidx.core.graphics.toColorInt\nimport androidx.core.net.toUri\nimport androidx.core.os.LocaleListCompat\nimport com.t8rin.imagetoolbox.core.domain.model.PerformanceClass\nimport com.t8rin.imagetoolbox.core.domain.utils.FileMode\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector.toImageBitmap\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionStatus\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.askUserToRequestPermissionExplicitly\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.checkPermissions\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.hasPermissionAllowed\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.setPermissionsAllowed\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.io.RandomAccessFile\nimport java.util.Locale\nimport kotlin.math.ceil\nimport kotlin.random.Random\n\n\nobject ContextUtils {\n\n    fun Activity.requestStoragePermission() = requestPermissions(\n        permissions = listOf(\n            Manifest.permission.WRITE_EXTERNAL_STORAGE,\n            Manifest.permission.READ_EXTERNAL_STORAGE\n        )\n    )\n\n    fun Activity.requestPermissions(permissions: List<String>) {\n        val state = checkPermissions(permissions)\n        when (state.permissionStatus.values.first()) {\n            PermissionStatus.NOT_GIVEN -> {\n                ActivityCompat.requestPermissions(\n                    this,\n                    permissions.toTypedArray(),\n                    0\n                )\n            }\n\n            PermissionStatus.DENIED_PERMANENTLY -> {\n                askUserToRequestPermissionExplicitly()\n                AppToastHost.showToast(\n                    message = R.string.grant_permission_manual,\n                    duration = ToastDuration.Long\n                )\n            }\n\n            PermissionStatus.ALLOWED -> Unit\n        }\n    }\n\n    fun Context.buildIntent(\n        clazz: Class<*>,\n        intentBuilder: Intent.() -> Unit,\n    ): Intent = Intent(applicationContext, clazz).apply(intentBuilder)\n\n    fun Context.postToast(\n        textRes: Int,\n        vararg formatArgs: Any,\n    ) {\n        mainLooperAction {\n            Toast.makeText(\n                applicationContext,\n                getString(\n                    textRes,\n                    *formatArgs\n                ),\n                Toast.LENGTH_SHORT\n            ).show()\n        }\n    }\n\n    fun Context.postToast(\n        textRes: Int,\n        isLong: Boolean = false,\n        vararg formatArgs: Any,\n    ) {\n        mainLooperAction {\n            Toast.makeText(\n                applicationContext,\n                getString(\n                    textRes,\n                    *formatArgs\n                ),\n                if (isLong) {\n                    Toast.LENGTH_LONG\n                } else Toast.LENGTH_SHORT\n            ).show()\n        }\n    }\n\n    fun Context.needToShowStoragePermissionRequest(): Boolean {\n        val permissions = listOf(\n            Manifest.permission.WRITE_EXTERNAL_STORAGE,\n            Manifest.permission.READ_EXTERNAL_STORAGE\n        )\n        val show = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) false\n        else !permissions.all { (this as Activity).hasPermissionAllowed(it) }\n\n        if (!show) setPermissionsAllowed(permissions)\n\n        return show\n    }\n\n    fun Context.adjustFontSize(\n        scale: Float?,\n    ): Context {\n        val configuration = resources.configuration\n        configuration.fontScale = scale ?: resources.configuration.fontScale\n        return createConfigurationContext(configuration)\n    }\n\n    fun Context.isInstalledFromPlayStore(): Boolean = verifyInstallerId(\n        listOf(\n            \"com.android.vending\",\n            \"com.google.android.feedback\"\n        )\n    )\n\n    private fun Context.verifyInstallerId(\n        validInstallers: List<String>,\n    ): Boolean = validInstallers.contains(getInstallerPackageName(packageName))\n\n    private fun Context.getInstallerPackageName(packageName: String): String? {\n        runCatching {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)\n                return packageManager.getInstallSourceInfo(packageName).installingPackageName\n            @Suppress(\"DEPRECATION\")\n            return packageManager.getInstallerPackageName(packageName)\n        }\n        return null\n    }\n\n    @Composable\n    fun rememberFilename(uri: Uri): String? {\n        return remember(uri) {\n            derivedStateOf {\n                uri.filename()\n            }\n        }.value\n    }\n\n    @Composable\n    fun rememberFileExtension(uri: Uri): String? {\n        return remember(uri) {\n            derivedStateOf {\n                uri.getExtension()\n            }\n        }.value\n    }\n\n\n    val Context.performanceClass: PerformanceClass\n        get() {\n            val androidVersion = Build.VERSION.SDK_INT\n            val cpuCount = Runtime.getRuntime().availableProcessors()\n            val memoryClass = getSystemService<ActivityManager>()!!.memoryClass\n            var totalCpuFreq = 0\n            var freqResolved = 0\n            for (i in 0 until cpuCount) {\n                runCatching {\n                    val reader = RandomAccessFile(\n                        String.format(\n                            Locale.ENGLISH,\n                            \"/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq\",\n                            i\n                        ), FileMode.Read.mode\n                    )\n                    val line = reader.readLine()\n                    if (line != null) {\n                        totalCpuFreq += line.toInt() / 1000\n                        freqResolved++\n                    }\n                    reader.close()\n                }\n            }\n            val maxCpuFreq =\n                if (freqResolved == 0) -1 else ceil((totalCpuFreq / freqResolved.toFloat()).toDouble())\n                    .toInt()\n\n            return if (androidVersion < 21 || cpuCount <= 2 || memoryClass <= 100 || cpuCount <= 4 && maxCpuFreq != -1 && maxCpuFreq <= 1250 || cpuCount <= 4 && maxCpuFreq <= 1600 && memoryClass <= 128 && androidVersion <= 21 || cpuCount <= 4 && maxCpuFreq <= 1300 && memoryClass <= 128 && androidVersion <= 24) {\n                PerformanceClass.Low\n            } else if (cpuCount < 8 || memoryClass <= 160 || maxCpuFreq != -1 && maxCpuFreq <= 2050 || maxCpuFreq == -1 && cpuCount == 8 && androidVersion <= 23) {\n                PerformanceClass.Average\n            } else {\n                PerformanceClass.High\n            }\n        }\n\n    @Suppress(\"unused\", \"MemberVisibilityCanBePrivate\")\n    tailrec fun Context.findActivity(): Activity? = when (this) {\n        is Activity -> this\n        is ContextWrapper -> baseContext.findActivity()\n        else -> null\n    }\n\n    fun Context.getStringLocalized(\n        @StringRes\n        resId: Int,\n        locale: Locale,\n    ): String = createConfigurationContext(\n        Configuration(resources.configuration).apply { setLocale(locale) }\n    ).getText(resId).toString()\n\n    fun Context.pasteColorFromClipboard(\n        onPastedColor: (Color) -> Unit,\n        onPastedColorFailure: (String) -> Unit,\n    ) {\n        val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager\n        val item = clipboard.primaryClip?.getItemAt(0)\n        val text = item?.text?.toString()\n        text?.let {\n            runCatching {\n                onPastedColor(Color(it.toColorInt()))\n            }.getOrElse {\n                onPastedColorFailure(getString(R.string.clipboard_paste_invalid_color_code))\n            }\n        } ?: run {\n            onPastedColorFailure(getString(R.string.clipboard_paste_invalid_empty))\n        }\n    }\n\n    fun Context.getLanguages(): Map<String, String> {\n        val languages = mutableListOf(\"\" to getString(R.string.system)).apply {\n            addAll(\n                LocaleConfigCompat(this@getLanguages)\n                    .supportedLocales!!.toList()\n                    .map {\n                        it.toLanguageTag() to it.getDisplayName(it)\n                            .replaceFirstChar(Char::uppercase)\n                    }\n            )\n        }\n\n        return languages.let { tags ->\n            listOf(tags.first()) + tags.drop(1).sortedBy { it.second }\n        }.toMap()\n    }\n\n    fun Context.getCurrentLocaleString(): String {\n        val locales = AppCompatDelegate.getApplicationLocales()\n        if (locales == LocaleListCompat.getEmptyLocaleList()) {\n            return getString(R.string.system)\n        }\n        return locales.getDisplayName()\n    }\n\n    fun LocaleListCompat.getDisplayName(): String = getDisplayName(toLanguageTags())\n\n    fun getDisplayName(\n        lang: String?,\n        useDefaultLocale: Boolean = false\n    ): String {\n        if (lang == null) {\n            return \"\"\n        }\n\n        val locale = when (lang) {\n            \"\" -> LocaleListCompat.getAdjustedDefault()[0]\n            else -> Locale.forLanguageTag(lang)\n        }\n        return locale!!.getDisplayName(\n            if (useDefaultLocale) Locale.getDefault()\n            else locale\n        ).replaceFirstChar { it.uppercase(locale) }\n    }\n\n    private const val SCREEN_ID_EXTRA = \"screen_id\"\n    const val SHORTCUT_OPEN_ACTION = \"shortcut\"\n\n    fun Intent?.getScreenExtra(): Screen? {\n        if (this?.hasExtra(SCREEN_ID_EXTRA) != true) return null\n\n        val screenIdExtra = getIntExtra(SCREEN_ID_EXTRA, -100).takeIf {\n            it != -100\n        } ?: return null\n\n        return Screen.entries.find {\n            it.id == screenIdExtra\n        }\n    }\n\n    fun Intent.putScreenExtra(screen: Screen?) = apply {\n        if (screen == null) {\n            removeExtra(SCREEN_ID_EXTRA)\n        } else {\n            putExtra(SCREEN_ID_EXTRA, screen.id)\n        }\n    }\n\n    fun Intent?.getScreenOpeningShortcut(\n        onNavigate: (Screen) -> Unit,\n    ): Boolean {\n        if (this == null) return false\n\n        val screenExtra = getScreenExtra()\n\n        if (action == SHORTCUT_OPEN_ACTION && screenExtra != null) {\n            onNavigate(screenExtra)\n\n            return true\n        }\n\n        return false\n    }\n\n    suspend fun Context.createScreenShortcut(\n        screen: Screen,\n        tint: Color = Color.Unspecified,\n        onFailure: (Throwable) -> Unit = {},\n    ) = withContext(Dispatchers.Main.immediate) {\n        runCatching {\n            val context = this@createScreenShortcut\n            if (context.canPinShortcuts() && screen.icon != null) {\n                val imageBitmap = screen.icon!!.toImageBitmap(\n                    context = context,\n                    width = 256,\n                    height = 256,\n                    tint = tint.takeOrElse { Color(0xFF5F823E) }\n                )\n\n                val info = ShortcutInfoCompat.Builder(context, screen.id.toString())\n                    .setShortLabel(getString(screen.title))\n                    .setLongLabel(getString(screen.subtitle))\n                    .setIcon(IconCompat.createWithBitmap(imageBitmap.asAndroidBitmap()))\n                    .setIntent(\n                        context.buildIntent(AppActivityClass) {\n                            action = SHORTCUT_OPEN_ACTION\n                            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK\n                            putScreenExtra(screen)\n                        }\n                    )\n                    .build()\n\n                val callbackIntent =\n                    ShortcutManagerCompat.createShortcutResultIntent(context, info)\n\n                val successCallback = PendingIntentCompat.getBroadcast(\n                    context, 0, callbackIntent, 0, false\n                )\n\n                ShortcutManagerCompat.requestPinShortcut(\n                    context,\n                    info,\n                    successCallback?.intentSender\n                )\n            } else {\n                onFailure(UnsupportedOperationException())\n            }\n        }.onFailure(onFailure)\n    }\n\n    fun Context.canPinShortcuts(): Boolean = runCatching {\n        ShortcutManagerCompat.isRequestPinShortcutSupported(this)\n    }.getOrNull() == true\n\n    @SuppressLint(\"MissingPermission\")\n    fun Context.isNetworkAvailable(): Boolean {\n        return getSystemService<ConnectivityManager>()?.run {\n            val capabilities = getNetworkCapabilities(\n                activeNetwork ?: return false\n            ) ?: return false\n\n            possibleCapabilities.any(capabilities::hasTransport)\n        } ?: false\n    }\n\n    private val possibleCapabilities = listOf(\n        NetworkCapabilities.TRANSPORT_WIFI,\n        NetworkCapabilities.TRANSPORT_CELLULAR,\n        NetworkCapabilities.TRANSPORT_ETHERNET,\n        NetworkCapabilities.TRANSPORT_BLUETOOTH\n    )\n\n    fun Context.shareText(value: String) {\n        val sendIntent = Intent().apply {\n            action = Intent.ACTION_SEND\n            type = \"text/plain\"\n            putExtra(Intent.EXTRA_TEXT, value)\n        }\n        val shareIntent = Intent.createChooser(sendIntent, getString(R.string.share))\n        shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        startActivity(shareIntent)\n    }\n\n    fun Context.shareUris(uris: List<Uri>) {\n        if (uris.isEmpty()) return\n\n        val sendIntent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {\n            putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(uris))\n            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)\n            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n            type = MimeTypeMap.getSingleton()\n                .getMimeTypeFromExtension(\n                    uris.first().getExtension()\n                ) ?: \"*/*\"\n        }\n        val shareIntent = Intent.createChooser(sendIntent, getString(R.string.share))\n        shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        startActivity(shareIntent)\n    }\n\n    fun Uri.getExtension(): String? = runCatching {\n        val filename = filename().orEmpty()\n        if (filename.endsWith(\".qoi\")) return \"qoi\"\n        if (filename.endsWith(\".jxl\")) return \"jxl\"\n        return if (ContentResolver.SCHEME_CONTENT == scheme) {\n            MimeTypeMap.getSingleton()\n                .getExtensionFromMimeType(\n                    appContext.contentResolver.getType(this@getExtension)\n                )\n        } else {\n            MimeTypeMap.getFileExtensionFromUrl(this@getExtension.toString())\n                .lowercase(Locale.getDefault())\n        }\n    }.getOrNull()\n\n    val Context.density: Density\n        get() = object : Density {\n            override val density: Float\n                get() = resources.displayMetrics.density\n            override val fontScale: Float\n                get() = resources.configuration.fontScale\n        }\n\n    @RequiresApi(Build.VERSION_CODES.R)\n    fun manageAllFilesIntent() = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)\n\n    @RequiresApi(Build.VERSION_CODES.R)\n    fun Context.manageAppAllFilesIntent(): Intent {\n        return Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)\n            .setData(\"package:${packageName}\".toUri())\n    }\n\n    fun Context.appSettingsIntent(): Intent {\n        return Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)\n            .setData(\"package:${packageName}\".toUri())\n    }\n\n    fun Uri.takePersistablePermission(): Uri = apply {\n        runCatching {\n            appContext.contentResolver.takePersistableUriPermission(\n                this,\n                Intent.FLAG_GRANT_READ_URI_PERMISSION or\n                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION\n            )\n        }.onFailure {\n            it.makeLog(\"takePersistablePermission\")\n        }\n    }\n\n    fun Uri.moveToCache(): Uri? = appContext.run {\n        contentResolver.openInputStream(this@moveToCache)?.use { stream ->\n            val file = File(\n                cacheDir,\n                filename() ?: \"cache_${Random.nextInt()}.tmp\"\n            ).apply { createNewFile() }\n\n            file.outputStream().use { stream.copyTo(it) }\n\n            file.toUri()\n        }\n    }\n\n    fun Uri.isFromAppFileProvider() = toString().run {\n        contains(\"content://media/external\") || contains(appContext.getString(R.string.file_provider))\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/DensityUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.TextUnit\nimport androidx.compose.ui.util.fastRoundToInt\n\n@Composable\nfun Dp.toSp(): TextUnit = with(LocalDensity.current) { toSp() }\n\n@Composable\nfun Dp.toPx(): Float = with(LocalDensity.current) { toPx() }\n\n@Composable\nfun Dp.roundToPx(): Int = toPx().fastRoundToInt()\n\n@Composable\nfun TextUnit.toPx(): Float = with(LocalDensity.current) { toPx() }\n\n@Composable\nfun TextUnit.roundToPx(): Int = toPx().fastRoundToInt()\n\n@Composable\nfun Int.toDp(): Dp = with(LocalDensity.current) { toDp() }\n\n@Composable\nfun Int.toSp(): TextUnit = toDp().toSp()\n\n@Composable\nfun Float.toDp(): Dp = with(LocalDensity.current) { toDp() }\n\n@Composable\nfun Float.toSp(): TextUnit = toDp().toSp()"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/DeviceInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.os.Build.BRAND\nimport android.os.Build.DEVICE\nimport android.os.Build.MODEL\nimport android.os.Build.VERSION.RELEASE\nimport android.os.Build.VERSION.SDK_INT\nimport androidx.appcompat.app.AppCompatDelegate\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig.FLAVOR\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig.VERSION_CODE\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getDisplayName\nimport com.t8rin.logger.makeLog\n\n@ConsistentCopyVisibility\ndata class DeviceInfo private constructor(\n    val device: String,\n    val sdk: String,\n    val appVersion: String,\n    val flavor: String,\n    val locale: String\n) {\n    companion object {\n        fun get(): DeviceInfo {\n            val device = \"$MODEL ($BRAND - $DEVICE)\"\n\n            val sdk = \"$SDK_INT (Android $RELEASE)\"\n\n            val appVersion = \"$AppVersion ($VERSION_CODE)\"\n\n            val flavor = FLAVOR\n\n            val locale = AppCompatDelegate.getApplicationLocales().getDisplayName()\n\n            return DeviceInfo(\n                device = device,\n                sdk = sdk,\n                appVersion = appVersion,\n                flavor = flavor,\n                locale = locale\n            )\n        }\n\n        fun getAsString(): String {\n            val (device, sdk, appVersion, flavor, locale) = get()\n\n            return listOf(\n                \"Device: $device\",\n                \"SDK: $sdk\",\n                \"App Version: $appVersion\",\n                \"Flavor: $flavor\",\n                \"Locale: $locale\"\n            ).joinToString(\"\\n\")\n        }\n\n        fun pushLog(extra: String? = null) {\n            getAsString().makeLog(\"DeviceInfo\".plus(extra?.let { \" $it\" }.orEmpty()))\n        }\n\n        fun isPixel() = getAsString().contains(\n            other = \"google\",\n            ignoreCase = true\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/DrawUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport kotlin.math.cos\nimport kotlin.math.sin\n\nfun Path.scaleToFitCanvas(\n    currentSize: IntegerSize,\n    oldSize: IntegerSize,\n    onGetScale: (Float, Float) -> Unit = { _, _ -> }\n): Path {\n    val sx = currentSize.width.toFloat() / oldSize.width\n    val sy = currentSize.height.toFloat() / oldSize.height\n    onGetScale(sx, sy)\n    return android.graphics.Path(this.asAndroidPath()).apply {\n        transform(\n            Matrix().apply {\n                setScale(sx, sy)\n            }\n        )\n    }.asComposePath()\n}\n\nfun Offset.rotate(\n    angle: Double\n): Offset = Offset(\n    x = (x * cos(Math.toRadians(angle)) - y * sin(Math.toRadians(angle))).toFloat(),\n    y = (x * sin(Math.toRadians(angle)) + y * cos(Math.toRadians(angle))).toFloat()\n)\n\nfun Path.moveTo(offset: Offset) = moveTo(offset.x, offset.y)\n\nfun Path.lineTo(offset: Offset) = lineTo(offset.x, offset.y)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/HandleDeeplinks.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.Intent\nimport android.net.Uri\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ErrorOutline\nimport com.t8rin.imagetoolbox.core.domain.BACKUP_FILE_EXT\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getScreenExtra\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getScreenOpeningShortcut\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.IntentUtils.parcelable\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.IntentUtils.parcelableArrayList\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.filename\n\nfun Intent?.handleDeeplinks(\n    onStart: () -> Unit,\n    onColdStart: () -> Unit,\n    onNavigate: (Screen) -> Unit,\n    onGetUris: (List<Uri>) -> Unit,\n    onHasExtraDataType: (ExtraDataType) -> Unit,\n    isHasUris: Boolean,\n    onWantGithubReview: () -> Unit,\n    isOpenEditInsteadOfPreview: Boolean,\n) {\n    val intent = this ?: return\n\n    onStart()\n    val type = intent.type\n    if (type != null && !isHasUris) onColdStart()\n\n    val action = intent.action\n\n    if (action == Intent.ACTION_BUG_REPORT) {\n        onWantGithubReview()\n        return\n    }\n\n    if (intent.getScreenOpeningShortcut(onNavigate)) return\n\n    val data = intent.data\n    val clipData = intent.clipData\n\n    runCatching {\n        fun String?.isMarkupProjectName(): Boolean {\n            val value = this?.lowercase().orEmpty()\n            return value.endsWith(\".itp\") || value.endsWith(\".itp.zip\")\n        }\n\n        fun Uri?.isMarkupProject(): Boolean = this?.toString().isMarkupProjectName() ||\n                this?.filename().isMarkupProjectName()\n\n        val startsWithImage = type?.startsWith(\"image/\") == true\n        val hasExtraFormats = clipData?.clipList()\n            ?.any {\n                it.toString().endsWith(\".jxl\") ||\n                        it.toString().endsWith(\".qoi\") ||\n                        it.toString().endsWith(\".itp\") ||\n                        it.toString().endsWith(\".itp.zip\")\n            } == true\n        val dataHasExtraFormats = data.toString().let {\n            it.endsWith(\".jxl\") || it.endsWith(\".qoi\") || it.endsWith(\".itp\") || it.endsWith(\".itp.zip\")\n        }\n\n        if (data.isMarkupProject()) {\n            onNavigate(Screen.MarkupLayers(data))\n        } else if ((startsWithImage || hasExtraFormats || dataHasExtraFormats)) {\n            when (action) {\n                Intent.ACTION_VIEW -> {\n                    val uris =\n                        clipData?.clipList() ?: data?.let { listOf(it) } ?: return@runCatching\n\n                    if (isOpenEditInsteadOfPreview) {\n                        onGetUris(uris)\n                    } else {\n                        onNavigate(Screen.ImagePreview(uris))\n                    }\n                }\n\n                Intent.ACTION_SEND -> {\n                    intent.parcelable<Uri>(Intent.EXTRA_STREAM)?.let {\n                        when (intent.getScreenExtra()) {\n                            is Screen.PickColorFromImage -> onNavigate(Screen.PickColorFromImage(it))\n                            is Screen.PaletteTools -> onNavigate(Screen.PaletteTools(it))\n                            else -> {\n                                if (type?.contains(\"gif\") == true) {\n                                    onHasExtraDataType(ExtraDataType.Gif)\n                                }\n                                onGetUris(listOf(it))\n                            }\n                        }\n                    }\n                }\n\n                Intent.ACTION_SEND_MULTIPLE -> {\n                    intent.parcelableArrayList<Uri>(Intent.EXTRA_STREAM)?.let {\n                        if (type?.contains(\"gif\") == true) {\n                            onHasExtraDataType(ExtraDataType.Gif)\n                            it.firstOrNull()?.let { uri ->\n                                onGetUris(listOf(uri))\n                            }\n                        } else onGetUris(it)\n                    }\n                }\n\n                Intent.ACTION_EDIT,\n                Intent.ACTION_INSERT,\n                Intent.ACTION_INSERT_OR_EDIT -> {\n                    val uris = clipData?.clipList() ?: data?.let { listOf(it) } ?: return@runCatching\n                    if (type?.contains(\"gif\") == true) {\n                        onHasExtraDataType(ExtraDataType.Gif)\n                    }\n                    onGetUris(uris)\n                }\n\n                else -> {\n                    data?.let {\n                        if (type?.contains(\"gif\") == true) {\n                            onHasExtraDataType(ExtraDataType.Gif)\n                        }\n                        onGetUris(listOf(it))\n                    }\n                }\n            }\n        } else if (type != null) {\n            val text = intent.getStringExtra(Intent.EXTRA_TEXT)\n\n            if (text != null) {\n                onHasExtraDataType(ExtraDataType.Text(text))\n                onGetUris(listOf())\n            } else {\n                val isPdf = type.contains(\"pdf\")\n                val isAudio = type.startsWith(\"audio/\")\n\n                when (action) {\n                    Intent.ACTION_SEND_MULTIPLE -> {\n                        intent.parcelableArrayList<Uri>(Intent.EXTRA_STREAM)?.let {\n                            when {\n                                isAudio -> {\n                                    onHasExtraDataType(ExtraDataType.Audio)\n                                    onGetUris(it)\n                                }\n\n                                isPdf -> {\n                                    onHasExtraDataType(ExtraDataType.Pdf)\n                                    onGetUris(it)\n                                }\n\n                                else -> onNavigate(Screen.Zip(it))\n                            }\n                        }\n                    }\n\n                    Intent.ACTION_SEND -> {\n                        intent.parcelable<Uri>(Intent.EXTRA_STREAM)?.let {\n                            if (it.isMarkupProject()) {\n                                onNavigate(Screen.MarkupLayers(it))\n                                return\n                            }\n                            if (it.toString().contains(BACKUP_FILE_EXT, true)) {\n                                onHasExtraDataType(ExtraDataType.Backup(it.toString()))\n                                return\n                            }\n                            when {\n                                isAudio -> onHasExtraDataType(ExtraDataType.Audio)\n                                isPdf -> onHasExtraDataType(ExtraDataType.Pdf)\n                                else -> onHasExtraDataType(ExtraDataType.File)\n                            }\n\n                            onGetUris(listOf(it))\n                        }\n                    }\n\n                    Intent.ACTION_VIEW -> {\n                        val uris =\n                            clipData?.clipList() ?: data?.let { listOf(it) }\n                            ?: listOfNotNull(intent.parcelable<Uri>(Intent.EXTRA_STREAM))\n\n                        if (uris.size == 1) {\n                            val uri = uris.first()\n\n                            if (uri.isMarkupProject()) {\n                                onNavigate(Screen.MarkupLayers(uri))\n                                return\n                            }\n\n                            if (uri.toString().contains(BACKUP_FILE_EXT, true)) {\n                                onHasExtraDataType(ExtraDataType.Backup(uri.toString()))\n                                return\n                            }\n\n                            when {\n                                isPdf -> {\n                                    onNavigate(Screen.PdfTools.Preview(uri))\n                                    return\n                                }\n\n                                isAudio -> {\n                                    onHasExtraDataType(ExtraDataType.Audio)\n                                }\n\n                                else -> {\n                                    onHasExtraDataType(ExtraDataType.File)\n                                }\n                            }\n\n                            onGetUris(uris)\n                        } else if (uris.isNotEmpty()) {\n                            when {\n                                isPdf -> {\n                                    onHasExtraDataType(ExtraDataType.Pdf)\n                                    onGetUris(uris)\n                                }\n\n                                isAudio -> {\n                                    onHasExtraDataType(ExtraDataType.Audio)\n                                    onGetUris(uris)\n                                }\n\n                                else -> {\n                                    onNavigate(Screen.Zip(uris))\n                                }\n                            }\n                        } else {\n                            Unit\n                        }\n                    }\n\n                    else -> null\n                } ?: AppToastHost.showToast(\n                    message = appContext.getString(R.string.unsupported_type, type),\n                    icon = Icons.Rounded.ErrorOutline\n                )\n            }\n        } else Unit\n    }.getOrNull() ?: AppToastHost.showToast(\n        message = appContext.getString(R.string.something_went_wrong),\n        icon = Icons.Rounded.ErrorOutline\n    )\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/HandlerUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.os.Handler\nimport android.os.Looper\n\n\nfun mainLooperDelayedAction(\n    delay: Long,\n    action: () -> Unit\n) = Handler(Looper.getMainLooper()).postDelayed(action, delay)\n\nfun mainLooperAction(\n    action: () -> Unit\n) = Handler(Looper.getMainLooper()).post(action)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/ImageUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\nimport android.graphics.pdf.PdfRenderer\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Build.VERSION.SDK_INT\nimport androidx.annotation.StringRes\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.produceState\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.core.graphics.BitmapCompat\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.drawable.toBitmap\nimport androidx.core.graphics.scale\nimport androidx.core.text.isDigitsOnly\nimport coil3.Image\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.utils.FileMode\nimport com.t8rin.imagetoolbox.core.domain.utils.humanFileSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getStringLocalized\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.fileSize\nimport java.util.Locale\n\n\nobject ImageUtils {\n\n    fun Drawable.toBitmap(): Bitmap = toBitmap(config = getSuitableConfig())\n\n    fun MetadataTag.localizedName(\n        context: Context,\n        locale: Locale? = null\n    ): String {\n        val resId = titleResId\n\n        return locale?.let {\n            context.getStringLocalized(\n                resId = resId,\n                locale = locale\n            )\n        } ?: context.getString(resId)\n    }\n\n    private val MetadataTag.titleResId: Int\n        @StringRes\n        get() = when (this) {\n            is MetadataTag.BitsPerSample -> R.string.tag_bits_per_sample\n            is MetadataTag.Compression -> R.string.tag_compression\n            is MetadataTag.PhotometricInterpretation -> R.string.tag_photometric_interpretation\n            is MetadataTag.SamplesPerPixel -> R.string.tag_samples_per_pixel\n            is MetadataTag.PlanarConfiguration -> R.string.tag_planar_configuration\n            is MetadataTag.YCbCrSubSampling -> R.string.tag_y_cb_cr_sub_sampling\n            is MetadataTag.YCbCrPositioning -> R.string.tag_y_cb_cr_positioning\n            is MetadataTag.XResolution -> R.string.tag_x_resolution\n            is MetadataTag.YResolution -> R.string.tag_y_resolution\n            is MetadataTag.ResolutionUnit -> R.string.tag_resolution_unit\n            is MetadataTag.StripOffsets -> R.string.tag_strip_offsets\n            is MetadataTag.RowsPerStrip -> R.string.tag_rows_per_strip\n            is MetadataTag.StripByteCounts -> R.string.tag_strip_byte_counts\n            is MetadataTag.JpegInterchangeFormat -> R.string.tag_jpeg_interchange_format\n            is MetadataTag.JpegInterchangeFormatLength -> R.string.tag_jpeg_interchange_format_length\n            is MetadataTag.TransferFunction -> R.string.tag_transfer_function\n            is MetadataTag.WhitePoint -> R.string.tag_white_point\n            is MetadataTag.PrimaryChromaticities -> R.string.tag_primary_chromaticities\n            is MetadataTag.YCbCrCoefficients -> R.string.tag_y_cb_cr_coefficients\n            is MetadataTag.ReferenceBlackWhite -> R.string.tag_reference_black_white\n            is MetadataTag.Datetime -> R.string.tag_datetime\n            is MetadataTag.ImageDescription -> R.string.tag_image_description\n            is MetadataTag.Make -> R.string.tag_make\n            is MetadataTag.Model -> R.string.tag_model\n            is MetadataTag.Software -> R.string.tag_software\n            is MetadataTag.Artist -> R.string.tag_artist\n            is MetadataTag.Copyright -> R.string.tag_copyright\n            is MetadataTag.ExifVersion -> R.string.tag_exif_version\n            is MetadataTag.FlashpixVersion -> R.string.tag_flashpix_version\n            is MetadataTag.ColorSpace -> R.string.tag_color_space\n            is MetadataTag.Gamma -> R.string.tag_gamma\n            is MetadataTag.PixelXDimension -> R.string.tag_pixel_x_dimension\n            is MetadataTag.PixelYDimension -> R.string.tag_pixel_y_dimension\n            is MetadataTag.CompressedBitsPerPixel -> R.string.tag_compressed_bits_per_pixel\n            is MetadataTag.MakerNote -> R.string.tag_maker_note\n            is MetadataTag.UserComment -> R.string.tag_user_comment\n            is MetadataTag.RelatedSoundFile -> R.string.tag_related_sound_file\n            is MetadataTag.DatetimeOriginal -> R.string.tag_datetime_original\n            is MetadataTag.DatetimeDigitized -> R.string.tag_datetime_digitized\n            is MetadataTag.OffsetTime -> R.string.tag_offset_time\n            is MetadataTag.OffsetTimeOriginal -> R.string.tag_offset_time_original\n            is MetadataTag.OffsetTimeDigitized -> R.string.tag_offset_time_digitized\n            is MetadataTag.SubsecTime -> R.string.tag_subsec_time\n            is MetadataTag.SubsecTimeOriginal -> R.string.tag_subsec_time_original\n            is MetadataTag.SubsecTimeDigitized -> R.string.tag_subsec_time_digitized\n            is MetadataTag.ExposureTime -> R.string.tag_exposure_time\n            is MetadataTag.FNumber -> R.string.tag_f_number\n            is MetadataTag.ExposureProgram -> R.string.tag_exposure_program\n            is MetadataTag.SpectralSensitivity -> R.string.tag_spectral_sensitivity\n            is MetadataTag.PhotographicSensitivity -> R.string.tag_photographic_sensitivity\n            is MetadataTag.Oecf -> R.string.tag_oecf\n            is MetadataTag.SensitivityType -> R.string.tag_sensitivity_type\n            is MetadataTag.StandardOutputSensitivity -> R.string.tag_standard_output_sensitivity\n            is MetadataTag.RecommendedExposureIndex -> R.string.tag_recommended_exposure_index\n            is MetadataTag.IsoSpeed -> R.string.tag_iso_speed\n            is MetadataTag.IsoSpeedLatitudeYyy -> R.string.tag_iso_speed_latitude_yyy\n            is MetadataTag.IsoSpeedLatitudeZzz -> R.string.tag_iso_speed_latitude_zzz\n            is MetadataTag.ShutterSpeedValue -> R.string.tag_shutter_speed_value\n            is MetadataTag.ApertureValue -> R.string.tag_aperture_value\n            is MetadataTag.BrightnessValue -> R.string.tag_brightness_value\n            is MetadataTag.ExposureBiasValue -> R.string.tag_exposure_bias_value\n            is MetadataTag.MaxApertureValue -> R.string.tag_max_aperture_value\n            is MetadataTag.SubjectDistance -> R.string.tag_subject_distance\n            is MetadataTag.MeteringMode -> R.string.tag_metering_mode\n            is MetadataTag.Flash -> R.string.tag_flash\n            is MetadataTag.SubjectArea -> R.string.tag_subject_area\n            is MetadataTag.FocalLength -> R.string.tag_focal_length\n            is MetadataTag.FlashEnergy -> R.string.tag_flash_energy\n            is MetadataTag.SpatialFrequencyResponse -> R.string.tag_spatial_frequency_response\n            is MetadataTag.FocalPlaneXResolution -> R.string.tag_focal_plane_x_resolution\n            is MetadataTag.FocalPlaneYResolution -> R.string.tag_focal_plane_y_resolution\n            is MetadataTag.FocalPlaneResolutionUnit -> R.string.tag_focal_plane_resolution_unit\n            is MetadataTag.SubjectLocation -> R.string.tag_subject_location\n            is MetadataTag.ExposureIndex -> R.string.tag_exposure_index\n            is MetadataTag.SensingMethod -> R.string.tag_sensing_method\n            is MetadataTag.FileSource -> R.string.tag_file_source\n            is MetadataTag.CfaPattern -> R.string.tag_cfa_pattern\n            is MetadataTag.CustomRendered -> R.string.tag_custom_rendered\n            is MetadataTag.ExposureMode -> R.string.tag_exposure_mode\n            is MetadataTag.WhiteBalance -> R.string.tag_white_balance\n            is MetadataTag.DigitalZoomRatio -> R.string.tag_digital_zoom_ratio\n            is MetadataTag.FocalLengthIn35mmFilm -> R.string.tag_focal_length_in_35mm_film\n            is MetadataTag.SceneCaptureType -> R.string.tag_scene_capture_type\n            is MetadataTag.GainControl -> R.string.tag_gain_control\n            is MetadataTag.Contrast -> R.string.tag_contrast\n            is MetadataTag.Saturation -> R.string.tag_saturation\n            is MetadataTag.Sharpness -> R.string.tag_sharpness\n            is MetadataTag.DeviceSettingDescription -> R.string.tag_device_setting_description\n            is MetadataTag.SubjectDistanceRange -> R.string.tag_subject_distance_range\n            is MetadataTag.ImageUniqueId -> R.string.tag_image_unique_id\n            is MetadataTag.CameraOwnerName -> R.string.tag_camera_owner_name\n            is MetadataTag.BodySerialNumber -> R.string.tag_body_serial_number\n            is MetadataTag.LensSpecification -> R.string.tag_lens_specification\n            is MetadataTag.LensMake -> R.string.tag_lens_make\n            is MetadataTag.LensModel -> R.string.tag_lens_model\n            is MetadataTag.LensSerialNumber -> R.string.tag_lens_serial_number\n            is MetadataTag.GpsVersionId -> R.string.tag_gps_version_id\n            is MetadataTag.GpsLatitudeRef -> R.string.tag_gps_latitude_ref\n            is MetadataTag.GpsLatitude -> R.string.tag_gps_latitude\n            is MetadataTag.GpsLongitudeRef -> R.string.tag_gps_longitude_ref\n            is MetadataTag.GpsLongitude -> R.string.tag_gps_longitude\n            is MetadataTag.GpsAltitudeRef -> R.string.tag_gps_altitude_ref\n            is MetadataTag.GpsAltitude -> R.string.tag_gps_altitude\n            is MetadataTag.GpsTimestamp -> R.string.tag_gps_timestamp\n            is MetadataTag.GpsSatellites -> R.string.tag_gps_satellites\n            is MetadataTag.GpsStatus -> R.string.tag_gps_status\n            is MetadataTag.GpsMeasureMode -> R.string.tag_gps_measure_mode\n            is MetadataTag.GpsDop -> R.string.tag_gps_dop\n            is MetadataTag.GpsSpeedRef -> R.string.tag_gps_speed_ref\n            is MetadataTag.GpsSpeed -> R.string.tag_gps_speed\n            is MetadataTag.GpsTrackRef -> R.string.tag_gps_track_ref\n            is MetadataTag.GpsTrack -> R.string.tag_gps_track\n            is MetadataTag.GpsImgDirectionRef -> R.string.tag_gps_img_direction_ref\n            is MetadataTag.GpsImgDirection -> R.string.tag_gps_img_direction\n            is MetadataTag.GpsMapDatum -> R.string.tag_gps_map_datum\n            is MetadataTag.GpsDestLatitudeRef -> R.string.tag_gps_dest_latitude_ref\n            is MetadataTag.GpsDestLatitude -> R.string.tag_gps_dest_latitude\n            is MetadataTag.GpsDestLongitudeRef -> R.string.tag_gps_dest_longitude_ref\n            is MetadataTag.GpsDestLongitude -> R.string.tag_gps_dest_longitude\n            is MetadataTag.GpsDestBearingRef -> R.string.tag_gps_dest_bearing_ref\n            is MetadataTag.GpsDestBearing -> R.string.tag_gps_dest_bearing\n            is MetadataTag.GpsDestDistanceRef -> R.string.tag_gps_dest_distance_ref\n            is MetadataTag.GpsDestDistance -> R.string.tag_gps_dest_distance\n            is MetadataTag.GpsProcessingMethod -> R.string.tag_gps_processing_method\n            is MetadataTag.GpsAreaInformation -> R.string.tag_gps_area_information\n            is MetadataTag.GpsDatestamp -> R.string.tag_gps_datestamp\n            is MetadataTag.GpsDifferential -> R.string.tag_gps_differential\n            is MetadataTag.GpsHPositioningError -> R.string.tag_gps_h_positioning_error\n            is MetadataTag.InteroperabilityIndex -> R.string.tag_interoperability_index\n            is MetadataTag.DngVersion -> R.string.tag_dng_version\n            is MetadataTag.DefaultCropSize -> R.string.tag_default_crop_size\n            is MetadataTag.OrfPreviewImageStart -> R.string.tag_orf_preview_image_start\n            is MetadataTag.OrfPreviewImageLength -> R.string.tag_orf_preview_image_length\n            is MetadataTag.OrfAspectFrame -> R.string.tag_orf_aspect_frame\n            is MetadataTag.Rw2SensorBottomBorder -> R.string.tag_rw2_sensor_bottom_border\n            is MetadataTag.Rw2SensorLeftBorder -> R.string.tag_rw2_sensor_left_border\n            is MetadataTag.Rw2SensorRightBorder -> R.string.tag_rw2_sensor_right_border\n            is MetadataTag.Rw2SensorTopBorder -> R.string.tag_rw2_sensor_top_border\n            is MetadataTag.Rw2Iso -> R.string.tag_rw2_iso\n        }\n\n    val MetadataTag.localizedName: String\n        @Composable\n        get() {\n            val context = LocalContext.current\n            return remember(this, context) {\n                localizedName(context)\n            }\n        }\n\n    private val possibleConfigs = mutableListOf<Bitmap.Config>().apply {\n        if (SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n            add(Bitmap.Config.RGBA_1010102)\n        }\n        if (SDK_INT >= Build.VERSION_CODES.O) {\n            add(Bitmap.Config.RGBA_F16)\n        }\n        add(Bitmap.Config.ARGB_8888)\n        add(Bitmap.Config.RGB_565)\n    }\n\n    fun getSuitableConfig(\n        image: Bitmap? = null\n    ): Bitmap.Config = image?.config?.takeIf {\n        it in possibleConfigs\n    } ?: Bitmap.Config.ARGB_8888\n\n    @Composable\n    fun rememberFileSize(uri: Uri?): Long {\n        return remember(uri) {\n            derivedStateOf {\n                uri?.fileSize() ?: 0L\n            }\n        }.value\n    }\n\n    @Composable\n    fun rememberHumanFileSize(uri: Uri): String {\n        val size = rememberFileSize(uri)\n\n        return remember(size, uri) {\n            derivedStateOf {\n                humanFileSize(size)\n            }\n        }.value\n    }\n\n    @Composable\n    fun rememberPdfPages(uri: Uri?): State<Int> = key(uri) {\n        produceState(0) {\n            if (uri == null) {\n                value = 0\n                return@produceState\n            }\n            val pageCount = runCatching {\n                appContext\n                    .contentResolver\n                    .openFileDescriptor(uri, FileMode.Read.mode)\n                    ?.use { fd ->\n                        PdfRenderer(fd).use { it.pageCount }\n                    } ?: 0\n            }.getOrDefault(0)\n\n            value = pageCount\n        }\n    }\n\n    @Composable\n    fun rememberHumanFileSize(\n        byteCount: Long\n    ): String {\n        return remember(byteCount) {\n            derivedStateOf {\n                humanFileSize(\n                    bytes = byteCount\n                )\n            }\n        }.value\n    }\n\n    object Dimens {\n        const val MAX_IMAGE_SIZE = 8388607 * 16\n    }\n\n    fun String.restrict(with: Int): String {\n        if (isEmpty()) return this\n\n        return if ((this.toIntOrNull() ?: 0) >= with) with.toString()\n        else if (this.isDigitsOnly() && (this.toIntOrNull() == null)) \"\"\n        else this.trim()\n            .filter {\n                !listOf('-', '.', ',', ' ', \"\\n\").contains(it)\n            }\n    }\n\n    fun Bitmap.createScaledBitmap(\n        width: Int,\n        height: Int\n    ): Bitmap {\n        if (width == this.width && height == this.height) return this\n\n        return if (width < this.width && height < this.height) {\n            BitmapCompat.createScaledBitmap(\n                this,\n                width,\n                height,\n                null,\n                true\n            )\n        } else {\n            this.scale(width, height)\n        }\n    }\n\n    fun ImageInfo.haveChanges(original: Bitmap?): Boolean {\n        if (original == null) return false\n        return quality.qualityValue != 100 || rotationDegrees != 0f || isFlipped || width != original.width || height != original.height\n    }\n\n    val Bitmap.aspectRatio: Float get() = width / height.toFloat()\n\n    val ImageBitmap.aspectRatio: Float get() = width / height.toFloat()\n\n    val Drawable.aspectRatio: Float get() = intrinsicWidth / intrinsicHeight.toFloat()\n\n    val Image.aspectRatio: Float get() = width / height.toFloat()\n\n    val Bitmap.safeAspectRatio: Float\n        get() = aspectRatio\n            .coerceAtLeast(0.005f)\n            .coerceAtMost(1000f)\n\n    val ImageBitmap.safeAspectRatio: Float\n        get() = aspectRatio\n            .coerceAtLeast(0.005f)\n            .coerceAtMost(1000f)\n\n    val Image.safeAspectRatio: Float\n        get() = aspectRatio\n            .coerceAtLeast(0.005f)\n            .coerceAtMost(1000f)\n\n    val Drawable.safeAspectRatio: Float\n        get() = aspectRatio\n            .coerceAtLeast(0.005f)\n            .coerceAtMost(1000f)\n\n    val Bitmap.Config.isHardware: Boolean\n        get() = SDK_INT >= 26 && this == Bitmap.Config.HARDWARE\n\n    fun Bitmap.Config?.toSoftware(): Bitmap.Config {\n        return if (this == null || isHardware) Bitmap.Config.ARGB_8888 else this\n    }\n\n    fun Bitmap.flexibleScale(\n        max: Int,\n        filter: Boolean = true\n    ): Bitmap {\n        return runCatching {\n            if (height >= width) {\n                val aspectRatio = aspectRatio\n                val targetWidth = (max * aspectRatio).toInt()\n                scale(targetWidth, max, filter)\n            } else {\n                val aspectRatio = 1f / aspectRatio\n                val targetHeight = (max * aspectRatio).toInt()\n                scale(max, targetHeight, filter)\n            }\n        }.getOrNull() ?: this\n    }\n\n    fun Bitmap.applyPadding(padding: Int, paddingColor: Color = Color.White): Bitmap {\n        val newWidth = this.width + padding * 2\n        val newHeight = this.height + padding * 2\n        return createBitmap(newWidth, newHeight, getSuitableConfig(this)).applyCanvas {\n            drawColor(paddingColor.toArgb())\n            drawBitmap(this@applyPadding, padding.toFloat(), padding.toFloat(), null)\n        }\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/IntentUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.Intent\nimport android.os.Parcelable\nimport androidx.core.content.IntentCompat\n\nobject IntentUtils {\n    inline fun <reified T : Parcelable> Intent.parcelable(key: String): T? = runCatching {\n        IntentCompat.getParcelableExtra(this, key, T::class.java)\n    }.getOrNull()\n\n    inline fun <reified T : Parcelable> Intent.parcelableArrayList(key: String): ArrayList<T>? =\n        runCatching {\n            IntentCompat.getParcelableArrayListExtra(this, key, T::class.java)\n        }.getOrNull()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/LazyUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\n\n@Composable\nfun LazyListState.isScrollingUp(): Boolean {\n    var previousIndex by remember(this) { mutableIntStateOf(firstVisibleItemIndex) }\n    var previousScrollOffset by remember(this) { mutableIntStateOf(firstVisibleItemScrollOffset) }\n    return remember(this) {\n        derivedStateOf {\n            if (previousIndex != firstVisibleItemIndex) {\n                previousIndex > firstVisibleItemIndex\n            } else {\n                previousScrollOffset >= firstVisibleItemScrollOffset\n            }.also {\n                previousIndex = firstVisibleItemIndex\n                previousScrollOffset = firstVisibleItemScrollOffset\n            }\n        }\n    }.value\n}\n\n@Composable\nfun ScrollState.isScrollingUp(enabled: Boolean = true): Boolean {\n    var previousScrollOffset by remember(this) { mutableIntStateOf(value) }\n    return remember(this, enabled) {\n        derivedStateOf {\n            if (enabled) {\n                (previousScrollOffset >= value).also {\n                    previousScrollOffset = value\n                }\n            } else true\n        }\n    }.value\n}\n\n@Composable\nfun LazyStaggeredGridState.isScrollingUp(enabled: Boolean = true): Boolean {\n    var previousIndex by remember(this) { mutableIntStateOf(firstVisibleItemIndex) }\n    var previousScrollOffset by remember(this) { mutableIntStateOf(firstVisibleItemScrollOffset) }\n    return remember(this, enabled) {\n        derivedStateOf {\n            if (enabled) {\n                if (previousIndex != firstVisibleItemIndex) {\n                    previousIndex > firstVisibleItemIndex\n                } else {\n                    previousScrollOffset >= firstVisibleItemScrollOffset\n                }.also {\n                    previousIndex = firstVisibleItemIndex\n                    previousScrollOffset = firstVisibleItemScrollOffset\n                }\n            } else true\n        }\n    }.value\n}\n\n@Composable\nfun rememberCurrentOffset(state: LazyStaggeredGridState): State<Int> {\n    val position = remember { derivedStateOf { state.firstVisibleItemIndex } }\n    val itemOffset = remember { derivedStateOf { state.firstVisibleItemScrollOffset } }\n    val lastPosition = rememberPrevious(position.value)\n    val lastItemOffset = rememberPrevious(itemOffset.value)\n    val currentOffset = remember { mutableIntStateOf(0) }\n\n    LaunchedEffect(position.value, itemOffset.value) {\n        if (lastPosition == null || position.value == 0) {\n            currentOffset.intValue = itemOffset.value\n        } else if (lastPosition == position.value) {\n            currentOffset.intValue += (itemOffset.value - (lastItemOffset ?: 0))\n        } else if (lastPosition > position.value) {\n            currentOffset.intValue -= (lastItemOffset ?: 0)\n        } else { // lastPosition.value < position.value\n            currentOffset.intValue += itemOffset.value\n        }\n    }\n\n    return currentOffset\n}\n\n@Composable\nfun <T> rememberPrevious(\n    current: T,\n    shouldUpdate: (prev: T?, curr: T) -> Boolean = { a: T?, b: T -> a != b },\n): T? {\n    val ref = rememberRef<T>()\n\n    // launched after render, so the current render will have the old value anyway\n    SideEffect {\n        if (shouldUpdate(ref.value, current)) {\n            ref.value = current\n        }\n    }\n\n    return ref.value\n}\n\n/**\n * Returns a dummy MutableState that does not cause render when setting it\n */\n@Composable\nfun <T> rememberRef(): MutableState<T?> {\n    // for some reason it always recreated the value with vararg keys,\n    // leaving out the keys as a parameter for remember for now\n    return remember {\n        object : MutableState<T?> {\n            override var value: T? = null\n\n            override fun component1(): T? = value\n\n            override fun component2(): (T?) -> Unit = { value = it }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/LinkUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport com.t8rin.imagetoolbox.core.domain.USER_AGENT\nimport com.t8rin.imagetoolbox.core.domain.remote.Cache\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport kotlinx.coroutines.withTimeoutOrNull\nimport org.jsoup.Jsoup\nimport kotlin.time.Duration.Companion.minutes\nimport kotlin.time.Duration.Companion.seconds\n\nobject LinkUtils {\n    fun parseLinks(text: String): Set<String> {\n        val regex = Regex(\"\"\"\\b(?:https?://|www\\.|http?://)\\S+\\b\"\"\")\n        val matches = regex.findAll(text)\n        return matches.map { it.value }.toSet()\n    }\n}\n\n@ConsistentCopyVisibility\ndata class LinkPreview internal constructor(\n    val title: String?,\n    val description: String?,\n    val image: String?,\n    val url: String?,\n    val link: String?\n) {\n    companion object {\n        fun empty(link: String) = LinkPreview(\n            link = link,\n            image = null,\n            title = null,\n            description = null,\n            url = null\n        )\n    }\n}\n\nsuspend fun fetchLinkPreview(\n    link: String\n): LinkPreview = linksCache.call(link) {\n    withContext(Dispatchers.IO) {\n        var image: String? = null\n        var title: String? = null\n        var description: String? = null\n        var url: String? = null\n\n\n        runSuspendCatching {\n            withTimeoutOrNull(30.seconds) {\n                Jsoup\n                    .connect(link)\n                    .userAgent(USER_AGENT)\n                    .execute()\n                    .parse()\n                    .getElementsByTag(\"meta\")\n                    .forEach { element ->\n                        when (element.attr(\"property\")) {\n                            \"og:image\" -> image = element.attr(\"content\")\n                            \"og:title\" -> title = element.attr(\"content\")\n                            \"og:description\" -> description = element.attr(\"content\")\n                            \"og:url\" -> url = element.attr(\"content\")\n                        }\n                    }\n            }\n        }\n\n\n        LinkPreview(\n            link = link,\n            image = image,\n            title = title,\n            description = description,\n            url = url\n        )\n    }\n}\n\nprivate val linksCache = Cache<String, LinkPreview>(1.minutes)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/LocalFilterPreviewModel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.graphics.Bitmap\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.flexibleScale\n\nval LocalFilterPreviewModelProvider =\n    compositionLocalOf<FilterPreviewProvider> { error(\"FilterPreviewProvider not present\") }\n\n@Composable\nfun rememberFilterPreviewProvider(\n    preview: ImageModel,\n    canSetDynamicFilterPreview: Boolean\n): FilterPreviewProvider {\n    return remember(preview) {\n        FilterPreviewProviderImpl(\n            default = preview,\n            canSetDynamicFilterPreview = canSetDynamicFilterPreview\n        )\n    }.also {\n        LaunchedEffect(it, canSetDynamicFilterPreview) {\n            it._canSetDynamicFilterPreview.value = canSetDynamicFilterPreview\n        }\n    }\n}\n\ninterface FilterPreviewProvider {\n    val canSetDynamicFilterPreview: Boolean\n\n    val preview: ImageModel\n\n    @Composable\n    fun ProvidePreview(preview: Any?)\n}\n\nprivate class FilterPreviewProviderImpl(\n    private val default: ImageModel,\n    canSetDynamicFilterPreview: Boolean\n) : FilterPreviewProvider {\n\n    private val _preview = mutableStateOf(default)\n\n    override val preview: ImageModel by _preview\n\n    val _canSetDynamicFilterPreview = mutableStateOf(canSetDynamicFilterPreview)\n\n    override val canSetDynamicFilterPreview by _canSetDynamicFilterPreview\n\n    private var updatesCount: Int = 0\n\n    override fun toString(): String {\n        return \"FilterPreviewProviderImpl(preview = $preview, canSetDynamicFilterPreview = $canSetDynamicFilterPreview, updatesCount = $updatesCount)\"\n    }\n\n    @Composable\n    override fun ProvidePreview(preview: Any?) {\n        DisposableEffect(Unit) {\n            onDispose {\n                _preview.value = default\n            }\n        }\n\n        LaunchedEffect(preview, canSetDynamicFilterPreview) {\n            updatesCount++\n\n            _preview.value = if (canSetDynamicFilterPreview) {\n                when (preview) {\n                    is ImageModel -> preview\n                    is Bitmap -> ImageModel(preview.flexibleScale(300))\n                    is Any -> ImageModel(preview)\n                    else -> default\n                }\n            } else {\n                default\n            }\n        }\n    }\n\n}\n\n@Composable\nfun ProvideFilterPreview(preview: Any?) {\n    LocalFilterPreviewModelProvider.current.ProvidePreview(preview)\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/LocaleConfigCompat.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.app.LocaleConfig\nimport android.content.Context\nimport android.content.res.XmlResourceParser\nimport android.os.Build\nimport androidx.annotation.RequiresApi\nimport androidx.annotation.XmlRes\nimport androidx.core.content.res.ResourcesCompat\nimport androidx.core.os.LocaleListCompat\nimport com.t8rin.logger.makeLog\nimport org.xmlpull.v1.XmlPullParser\nimport java.io.FileNotFoundException\nimport java.util.Locale\n\n/**\n * @see android.app.LocaleConfig\n */\nclass LocaleConfigCompat(context: Context) {\n    var status = 0\n        private set\n\n    var supportedLocales: LocaleListCompat? = null\n        private set\n\n    init {\n        val impl = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n            Api33Impl(context)\n        } else {\n            Api21Impl(context)\n        }\n        status = impl.status\n        supportedLocales = impl.supportedLocales\n    }\n\n    companion object {\n        /**\n         * Succeeded reading the LocaleConfig structure stored in an XML file.\n         */\n        const val STATUS_SUCCESS = 0\n\n        /**\n         * No android:localeConfig tag on <application>.\n         */\n        const val STATUS_NOT_SPECIFIED = 1\n\n        /**\n         * Malformed input in the XML file where the LocaleConfig was stored.\n         */\n        const val STATUS_PARSING_FAILED = 2\n    }\n\n    private abstract class Impl {\n        abstract val status: Int\n        abstract val supportedLocales: LocaleListCompat?\n    }\n\n    private class Api21Impl(context: Context) : Impl() {\n        override var status = 0\n\n        override var supportedLocales: LocaleListCompat? = null\n\n        init {\n            val resourceId = try {\n                getLocaleConfigResourceId(context)\n            } catch (e: Throwable) {\n                \"The resource file pointed to by the given resource ID isn't found.\".makeLog(TAG)\n\n                ResourcesCompat.ID_NULL\n            }\n            if (resourceId == ResourcesCompat.ID_NULL) {\n                status = STATUS_NOT_SPECIFIED\n            } else {\n                val resources = context.resources\n                try {\n                    supportedLocales = resources.getXml(resourceId).use { parseLocaleConfig(it) }\n                    status = STATUS_SUCCESS\n                } catch (e: Throwable) {\n                    val resourceEntryName = resources.getResourceEntryName(resourceId)\n                    \"Failed to parse XML configuration from $resourceEntryName\".makeLog(TAG)\n                    status = STATUS_PARSING_FAILED\n                }\n            }\n        }\n\n        // @see com.android.server.pm.pkg.parsing.ParsingPackageUtils\n        @XmlRes\n        private fun getLocaleConfigResourceId(context: Context): Int {\n            // Java cookies starts at 1, while passing 0 (invalid cookie for Java) makes\n            // AssetManager pick the last asset containing such a file name.\n            // We should go over all the assets containing AndroidManifest.xml, however there's no\n            // API to do that, so the best we can do is to start from the first asset and iterate\n            // until we can't find the next asset containing AndroidManifest.xml.\n            var cookie = 1\n            var isAndroidManifestFound = false\n            while (true) {\n                val parser = try {\n                    context.assets.openXmlResourceParser(cookie, FILE_NAME_ANDROID_MANIFEST)\n                } catch (_: FileNotFoundException) {\n                    if (!isAndroidManifestFound) {\n                        ++cookie\n                        continue\n                    } else {\n                        break\n                    }\n                }\n                isAndroidManifestFound = true\n                parser.use {\n                    do {\n                        if (parser.eventType != XmlPullParser.START_TAG) {\n                            continue\n                        }\n                        if (parser.name != TAG_MANIFEST) {\n                            parser.skipCurrentTag()\n                            continue\n                        }\n                        if (parser.getAttributeValue(null, ATTR_PACKAGE) != context.packageName) {\n                            break\n                        }\n                        while (parser.next() != XmlPullParser.END_TAG) {\n                            if (parser.eventType != XmlPullParser.START_TAG) {\n                                continue\n                            }\n                            if (parser.name != TAG_APPLICATION) {\n                                parser.skipCurrentTag()\n                                continue\n                            }\n                            return parser.getAttributeResourceValue(\n                                NAMESPACE_ANDROID, ATTR_LOCALE_CONFIG, ResourcesCompat.ID_NULL\n                            )\n                        }\n                    } while (parser.next() != XmlPullParser.END_DOCUMENT)\n                }\n                ++cookie\n            }\n            return ResourcesCompat.ID_NULL\n        }\n\n        private fun parseLocaleConfig(parser: XmlResourceParser): LocaleListCompat {\n            val localeNames = mutableSetOf<String>()\n            do {\n                if (parser.eventType != XmlPullParser.START_TAG) {\n                    continue\n                }\n                if (parser.name != TAG_LOCALE_CONFIG) {\n                    parser.skipCurrentTag()\n                    continue\n                }\n                while (parser.next() != XmlPullParser.END_TAG) {\n                    if (parser.eventType != XmlPullParser.START_TAG) {\n                        continue\n                    }\n                    if (parser.name != TAG_LOCALE) {\n                        parser.skipCurrentTag()\n                        continue\n                    }\n                    localeNames += parser.getAttributeValue(NAMESPACE_ANDROID, ATTR_NAME)\n                    parser.skipCurrentTag()\n                }\n            } while (parser.next() != XmlPullParser.END_DOCUMENT)\n            return LocaleListCompat.forLanguageTags(localeNames.joinToString(\",\"))\n        }\n\n        private fun XmlPullParser.skipCurrentTag() {\n            val outerDepth = depth\n            var type: Int\n            do {\n                type = next()\n            } while (type != XmlPullParser.END_DOCUMENT &&\n                (type != XmlPullParser.END_TAG || depth > outerDepth)\n            )\n        }\n\n        companion object {\n            private const val TAG = \"LocaleConfigCompat\"\n\n            private const val FILE_NAME_ANDROID_MANIFEST = \"AndroidManifest.xml\"\n\n            private const val TAG_APPLICATION = \"application\"\n            private const val TAG_LOCALE_CONFIG = \"locale-config\"\n            private const val TAG_LOCALE = \"locale\"\n            private const val TAG_MANIFEST = \"manifest\"\n\n            private const val NAMESPACE_ANDROID = \"http://schemas.android.com/apk/res/android\"\n\n            private const val ATTR_LOCALE_CONFIG = \"localeConfig\"\n            private const val ATTR_NAME = \"name\"\n            private const val ATTR_PACKAGE = \"package\"\n        }\n    }\n\n    @RequiresApi(Build.VERSION_CODES.TIRAMISU)\n    private class Api33Impl(context: Context) : Impl() {\n        override var status: Int = 0\n\n        override var supportedLocales: LocaleListCompat? = null\n\n        init {\n            val platformLocaleConfig = LocaleConfig(context)\n            status = platformLocaleConfig.status\n            supportedLocales = platformLocaleConfig.supportedLocales\n                ?.let { LocaleListCompat.wrap(it) }\n        }\n    }\n}\n\nfun LocaleListCompat.toList(): List<Locale> = List(size()) { this[it]!! }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/PaddingUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.content.res.Configuration\nimport androidx.compose.material3.windowsizeclass.WindowWidthSizeClass\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.platform.LocalConfiguration\nimport androidx.compose.ui.platform.LocalInspectionMode\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalWindowSizeClass\n\n@Composable\nfun isPortraitOrientationAsState(): State<Boolean> {\n    if (LocalInspectionMode.current) return remember { mutableStateOf(false) }\n\n    val configuration = LocalConfiguration.current\n    val sizeClass = LocalWindowSizeClass.current\n\n    return remember(configuration, sizeClass) {\n        derivedStateOf {\n            configuration.orientation != Configuration.ORIENTATION_LANDSCAPE || sizeClass.widthSizeClass == WindowWidthSizeClass.Compact\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/PredictiveBackObserver.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.activity.compose.PredictiveBackHandler\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.rememberCoroutineScope\nimport kotlinx.coroutines.launch\nimport kotlin.coroutines.cancellation.CancellationException\n\n@Composable\nfun PredictiveBackObserver(\n    onProgress: (Float) -> Unit,\n    onClean: suspend (isCompleted: Boolean) -> Unit,\n    enabled: Boolean = true\n) {\n    val scope = rememberCoroutineScope()\n\n    if (!enabled) return\n\n    PredictiveBackHandler { progress ->\n        try {\n            progress.collect { event ->\n                if (event.progress <= 0.05f) {\n                    onClean(false)\n                }\n                onProgress(event.progress)\n            }\n            scope.launch {\n                onClean(true)\n            }\n        } catch (_: CancellationException) {\n            onClean(false)\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/Preview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.compose.ui.tooling.preview.Preview\n\n@Preview(\n    name = \"Preview\",\n    locale = \"en\"\n)\nannotation class EnPreview\n\n@Preview(heightDp = 300, widthDp = 800, locale = \"en\")\nannotation class EnPreviewLandscape"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/Rect.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.compose.ui.geometry.Rect\nimport com.t8rin.imagetoolbox.core.domain.model.RectModel\n\nfun Rect.toModel() = RectModel(\n    left = left,\n    top = top,\n    right = right,\n    bottom = bottom\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/ReviewHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.app.Activity\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.channels.Channel\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.receiveAsFlow\n\nabstract class ReviewHandler {\n\n    private val _reviewRequests: Channel<Unit> = Channel(Channel.BUFFERED)\n    val reviewRequests: Flow<Unit> = _reviewRequests.receiveAsFlow()\n\n    fun requestReview() {\n        makeLog(\"requestReview\")\n        _reviewRequests.trySend(Unit)\n    }\n\n    open val showNotShowAgainButton: Boolean = false\n\n    open fun notShowReviewAgain() = Unit\n\n    abstract fun showReview(activity: Activity)\n\n    companion object {\n        val current: ReviewHandler = ReviewHandlerImpl\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/Ripple.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport androidx.compose.foundation.Indication\nimport androidx.compose.material.LocalContentColor\nimport androidx.compose.material3.ripple\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.unit.Dp\n\n@Composable\nfun rememberRipple(\n    bounded: Boolean = true,\n    radius: Dp = Dp.Unspecified,\n    contentColor: Color = Color.Unspecified\n): Indication {\n    val contentColor = contentColor.takeOrElse {\n        LocalContentColor.current\n    }\n\n    return remember(bounded, radius) {\n        ripple(\n            color = { contentColor },\n            bounded = bounded,\n            radius = radius\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/SafeUriHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.app.Activity\nimport android.content.Intent\nimport androidx.activity.compose.LocalActivity\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.platform.UriHandler\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun rememberSafeUriHandler(): UriHandler {\n    val activity = LocalActivity.current\n\n    return remember(activity) {\n        SafeUriHandler(\n            activity = activity\n        )\n    }\n}\n\n@Stable\n@Immutable\nprivate class SafeUriHandler(\n    private val activity: Activity?\n) : UriHandler {\n\n    override fun openUri(uri: String) {\n        tryActions(\n            first = { rawOpenUri(uri) },\n            second = {\n                val trimmed = uri.trim()\n\n                val modifiedUrl = when {\n                    trimmed.startsWith(WWW, ignoreCase = true) -> trimmed.replace(WWW, HTTPS)\n                    !trimmed.startsWith(HTTP) && !trimmed.startsWith(HTTPS) -> HTTPS + trimmed\n                    else -> trimmed\n                }\n\n                rawOpenUri(modifiedUrl)\n            },\n            onFailure = {\n                AppToastHost.showFailureToast(getString(R.string.cannot_open_uri, uri))\n            }\n        )\n    }\n\n    private fun rawOpenUri(uri: String) {\n        activity?.startActivity(\n            Intent(Intent.ACTION_VIEW, uri.toUri()).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        )\n    }\n\n    private fun tryActions(\n        first: () -> Unit,\n        second: () -> Unit,\n        onFailure: () -> Unit\n    ) {\n        runCatching(first).onSuccess { return }\n        runCatching(second).onSuccess { return }\n        onFailure()\n    }\n\n    fun asUnsafe(): UriHandler = object : UriHandler {\n        override fun openUri(uri: String) = rawOpenUri(uri)\n    }\n\n}\n\nfun UriHandler.asUnsafe(): UriHandler = if (this is SafeUriHandler) asUnsafe() else this\n\nprivate const val WWW = \"www.\"\nprivate const val HTTPS = \"https://\"\nprivate const val HTTP = \"http://\""
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/SaveResultHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:SuppressLint(\"StringFormatMatches\")\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.annotation.SuppressLint\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.rounded.Save\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.firstOfType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.logger.makeLog\n\ninterface SaveResultHandler {\n    fun parseSaveResult(saveResult: SaveResult)\n\n    fun parseFileSaveResult(saveResult: SaveResult)\n\n    fun parseSaveResults(results: List<SaveResult>)\n}\n\ninternal object SaveResultHandlerImpl : SaveResultHandler {\n    override fun parseSaveResult(saveResult: SaveResult) {\n        when (saveResult) {\n            is SaveResult.Error.Exception -> {\n                saveResult.throwable.makeLog(\"parseSaveResult\")\n                AppToastHost.showFailureToast(\n                    throwable = saveResult.throwable\n                )\n            }\n\n            is SaveResult.Skipped -> {\n                AppToastHost.showToast(\n                    message = getString(R.string.skipped_saving),\n                    icon = Icons.Outlined.Info,\n                    duration = ToastDuration.Short\n                )\n            }\n\n            is SaveResult.Success -> {\n                saveResult.message?.let {\n                    AppToastHost.showToast(\n                        message = it,\n                        icon = Icons.Rounded.Save,\n                        duration = ToastDuration.Long\n                    )\n                }\n                AppToastHost.showConfetti()\n                ReviewHandler.current.requestReview()\n            }\n\n            SaveResult.Error.MissingPermissions -> AppToastHost.showToast(AppToastHost.PERMISSION)\n        }\n    }\n\n    override fun parseFileSaveResult(saveResult: SaveResult) {\n        when (saveResult) {\n            is SaveResult.Error.Exception -> {\n                AppToastHost.showFailureToast(\n                    throwable = saveResult.throwable\n                )\n            }\n\n            is SaveResult.Skipped -> {\n                AppToastHost.showToast(\n                    message = getString(R.string.skipped_saving),\n                    icon = Icons.Outlined.Info\n                )\n            }\n\n            is SaveResult.Success -> {\n                AppToastHost.showToast(\n                    message = getString(R.string.saved_to_without_filename, \"\"),\n                    icon = Icons.Rounded.Save\n                )\n                AppToastHost.showConfetti()\n                ReviewHandler.current.requestReview()\n            }\n\n            SaveResult.Error.MissingPermissions -> AppToastHost.showToast(AppToastHost.PERMISSION)\n        }\n    }\n\n    override fun parseSaveResults(results: List<SaveResult>) {\n        if (results.size == 1) {\n            return parseSaveResult(\n                saveResult = results.first()\n            )\n        }\n\n        if (results.any { it == SaveResult.Error.MissingPermissions }) {\n            AppToastHost.showToast(AppToastHost.PERMISSION)\n            return\n        }\n\n        val skipped = results.count { it is SaveResult.Skipped }\n        val failed = results.count { it is SaveResult.Error }\n        val done = results.count { it is SaveResult.Success }\n\n        if (failed == 0 && done > 0) {\n            if (done == 1) {\n                val saveResult = results.firstOfType<SaveResult.Success>()\n                val savingPath = saveResult?.savingPath ?: getString(R.string.default_folder)\n                AppToastHost.showToast(\n                    message = saveResult?.message ?: getString(\n                        R.string.saved_to_without_filename,\n                        savingPath\n                    ),\n                    icon = Icons.Rounded.Save,\n                    duration = ToastDuration.Long\n                )\n            } else {\n                val saveResult = results.firstOfType<SaveResult.Success>()\n\n                if (saveResult?.isOverwritten == true) {\n                    AppToastHost.showToast(\n                        message = getString(R.string.images_overwritten),\n                        icon = Icons.Rounded.Save,\n                        duration = ToastDuration.Long\n                    )\n                } else {\n                    val savingPath = saveResult?.savingPath ?: getString(R.string.default_folder)\n\n                    AppToastHost.showToast(\n                        message = getString(\n                            R.string.saved_to_without_filename,\n                            savingPath\n                        ),\n                        icon = Icons.Rounded.Save,\n                        duration = ToastDuration.Long\n                    )\n                }\n            }\n\n            if (skipped > 0) {\n                AppToastHost.showToast(\n                    message = getString(R.string.skipped_saving_multiple, skipped),\n                    icon = Icons.Outlined.Info,\n                    duration = ToastDuration.Short\n                )\n            }\n\n            AppToastHost.showConfetti()\n            ReviewHandler.current.requestReview()\n            return\n        }\n\n        if (failed > 0) {\n            val saveResult = results.firstOfType<SaveResult.Success>()\n            val errorSaveResult = results.firstOfType<SaveResult.Error>()\n\n            if (done > 0) {\n                AppToastHost.showToast(\n                    message = saveResult?.message\n                        ?: getString(\n                            R.string.saved_to_without_filename,\n                            saveResult?.savingPath\n                        ),\n                    icon = Icons.Rounded.Save,\n                    duration = ToastDuration.Long\n                )\n            }\n            AppToastHost.showFailureToast(getString(R.string.failed_to_save, failed))\n            AppToastHost.showToast(\n                message = getString(\n                    R.string.smth_went_wrong,\n                    errorSaveResult?.throwable?.localizedMessage ?: \"\"\n                )\n            )\n\n            if (skipped > 0) {\n                AppToastHost.showToast(\n                    message = getString(R.string.skipped_saving_multiple, skipped),\n                    icon = Icons.Outlined.Info,\n                    duration = ToastDuration.Short\n                )\n            }\n            return\n        }\n\n        if (skipped > 0 && done == 0 && failed == 0) {\n            AppToastHost.showToast(\n                message = getString(R.string.skipped_saving_multiple, skipped),\n                icon = Icons.Outlined.Info,\n                duration = ToastDuration.Short\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/ScanResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.net.Uri\n\ndata class ScanResult(\n    val imageUris: List<Uri> = emptyList(),\n    val pdfUri: Uri? = null\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/image_vector/DrawCache.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector\n\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.ImageBitmapConfig\nimport androidx.compose.ui.graphics.drawscope.CanvasDrawScope\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.toSize\n\n/**\n * Creates a drawing environment that directs its drawing commands to an [ImageBitmap]\n * which can be drawn directly in another [DrawScope] instance. This is useful to cache\n * complicated drawing commands across frames especially if the content has not changed.\n * Additionally some drawing operations such as rendering paths are done purely in\n * software so it is beneficial to cache the result and render the contents\n * directly through a texture as done by [DrawScope.drawImage]\n */\ninternal class DrawCache {\n\n    @PublishedApi\n    internal var mCachedImage: ImageBitmap? = null\n    private var cachedCanvas: Canvas? = null\n    private var scopeDensity: Density? = null\n    private var layoutDirection: LayoutDirection = LayoutDirection.Ltr\n    private var size: IntSize = IntSize.Zero\n    private var config: ImageBitmapConfig = ImageBitmapConfig.Argb8888\n\n    private val cacheScope = CanvasDrawScope()\n\n    /**\n     * Draw the contents of the lambda with receiver scope into an [ImageBitmap] with the provided\n     * size. If the same size is provided across calls, the same [ImageBitmap] instance is\n     * re-used and the contents are cleared out before drawing content in it again\n     */\n    fun drawCachedImage(\n        config: ImageBitmapConfig,\n        size: IntSize,\n        density: Density,\n        layoutDirection: LayoutDirection,\n        block: DrawScope.() -> Unit\n    ) {\n        this.scopeDensity = density\n        this.layoutDirection = layoutDirection\n        var targetImage = mCachedImage\n        var targetCanvas = cachedCanvas\n        if (targetImage == null ||\n            targetCanvas == null ||\n            size.width > targetImage.width ||\n            size.height > targetImage.height ||\n            this.config != config\n        ) {\n            targetImage = ImageBitmap(size.width, size.height, config = config)\n            targetCanvas = Canvas(targetImage)\n\n            mCachedImage = targetImage\n            cachedCanvas = targetCanvas\n            this.config = config\n        }\n        this.size = size\n        cacheScope.draw(density, layoutDirection, targetCanvas, size.toSize()) {\n            clear()\n            block()\n        }\n        targetImage.prepareToDraw()\n    }\n\n    /**\n     * Draw the cached content into the provided [DrawScope] instance\n     */\n    fun drawInto(\n        target: DrawScope,\n        alpha: Float = 1.0f,\n        colorFilter: ColorFilter? = null\n    ) {\n        val targetImage = mCachedImage\n        require(targetImage != null) {\n            \"drawCachedImage must be invoked first before attempting to draw the result \" +\n                    \"into another destination\"\n        }\n        target.drawImage(targetImage, srcSize = size, alpha = alpha, colorFilter = colorFilter)\n    }\n\n    /**\n     * Helper method to clear contents of the draw environment from the given bounds of the\n     * DrawScope\n     */\n    private fun DrawScope.clear() {\n        drawRect(color = Color.Black, blendMode = BlendMode.Clear)\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/image_vector/GroupComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector\n\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Matrix\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.withTransform\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.graphics.isUnspecified\nimport androidx.compose.ui.graphics.vector.DefaultGroupName\nimport androidx.compose.ui.graphics.vector.DefaultPivotX\nimport androidx.compose.ui.graphics.vector.DefaultPivotY\nimport androidx.compose.ui.graphics.vector.DefaultRotation\nimport androidx.compose.ui.graphics.vector.DefaultScaleX\nimport androidx.compose.ui.graphics.vector.DefaultScaleY\nimport androidx.compose.ui.graphics.vector.DefaultTranslationX\nimport androidx.compose.ui.graphics.vector.DefaultTranslationY\nimport androidx.compose.ui.graphics.vector.EmptyPath\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.VectorGroup\nimport androidx.compose.ui.graphics.vector.VectorPath\nimport androidx.compose.ui.graphics.vector.toPath\nimport androidx.compose.ui.util.fastForEach\n\ninternal class GroupComponent : VNode() {\n    private var groupMatrix: Matrix? = null\n\n    private val children = mutableListOf<VNode>()\n\n    /**\n     * Flag to determine if the contents of this group can be rendered with a single color\n     * This is true if all the paths and groups within this group can be rendered with the\n     * same color\n     */\n    var isTintable = true\n        private set\n\n    /**\n     * Tint color to render all the contents of this group. This is configured only if all the\n     * contents within the group are the same color\n     */\n    var tintColor = Color.Unspecified\n        private set\n\n    /**\n     * Helper method to inspect whether the provided brush matches the current color of paths\n     * within the group in order to help determine if only an alpha channel bitmap can be allocated\n     * and tinted in order to save on memory overhead.\n     */\n    private fun markTintForBrush(brush: Brush?) {\n        if (!isTintable) {\n            return\n        }\n        if (brush != null) {\n            if (brush is SolidColor) {\n                markTintForColor(brush.value)\n            } else {\n                // If the brush is not a solid color then we require a explicit ARGB channels in the\n                // cached bitmap\n                markNotTintable()\n            }\n        }\n    }\n\n    /**\n     * Helper method to inspect whether the provided color matches the current color of paths\n     * within the group in order to help determine if only an alpha channel bitmap can be allocated\n     * and tinted in order to save on memory overhead.\n     */\n    private fun markTintForColor(color: Color) {\n        if (!isTintable) {\n            return\n        }\n\n        if (color.isSpecified) {\n            if (tintColor.isUnspecified) {\n                // Initial color has not been specified, initialize the target color to the\n                // one provided\n                tintColor = color\n            } else if (!tintColor.rgbEqual(color)) {\n                // The given color does not match the rgb channels if our previous color\n                // Therefore we require explicit ARGB channels in the cached bitmap\n                markNotTintable()\n            }\n        }\n    }\n\n    private fun markTintForVNode(node: VNode) {\n        if (node is PathComponent) {\n            markTintForBrush(node.fill)\n            markTintForBrush(node.stroke)\n        } else if (node is GroupComponent) {\n            if (node.isTintable && isTintable) {\n                markTintForColor(node.tintColor)\n            } else {\n                markNotTintable()\n            }\n        }\n    }\n\n    private fun markNotTintable() {\n        isTintable = false\n        tintColor = Color.Unspecified\n    }\n\n    var clipPathData = EmptyPath\n        set(value) {\n            field = value\n            isClipPathDirty = true\n            invalidate()\n        }\n\n    private val willClipPath: Boolean\n        get() = clipPathData.isNotEmpty()\n\n    private var isClipPathDirty = true\n\n    private var clipPath: Path? = null\n\n    override var invalidateListener: ((VNode) -> Unit)? = null\n\n    private val wrappedListener: (VNode) -> Unit = { node ->\n        markTintForVNode(node)\n        invalidateListener?.invoke(node)\n    }\n\n    private fun updateClipPath() {\n        if (willClipPath) {\n            var targetClip = clipPath\n            if (targetClip == null) {\n                targetClip = Path()\n                clipPath = targetClip\n            }\n\n            // toPath() will reset the path we send\n            clipPathData.toPath(targetClip)\n        }\n    }\n\n    // If the name changes we should re-draw as individual nodes could\n    // be modified based off of this name parameter.\n    var name = DefaultGroupName\n        set(value) {\n            field = value\n            invalidate()\n        }\n\n    var rotation = DefaultRotation\n        set(value) {\n            field = value\n            isMatrixDirty = true\n            invalidate()\n        }\n\n    var pivotX = DefaultPivotX\n        set(value) {\n            field = value\n            isMatrixDirty = true\n            invalidate()\n        }\n\n    var pivotY = DefaultPivotY\n        set(value) {\n            field = value\n            isMatrixDirty = true\n            invalidate()\n        }\n\n    var scaleX = DefaultScaleX\n        set(value) {\n            field = value\n            isMatrixDirty = true\n            invalidate()\n        }\n\n    var scaleY = DefaultScaleY\n        set(value) {\n            field = value\n            isMatrixDirty = true\n            invalidate()\n        }\n\n    var translationX = DefaultTranslationX\n        set(value) {\n            field = value\n            isMatrixDirty = true\n            invalidate()\n        }\n\n    var translationY = DefaultTranslationY\n        set(value) {\n            field = value\n            isMatrixDirty = true\n            invalidate()\n        }\n\n    private val numChildren: Int\n        get() = children.size\n\n    private var isMatrixDirty = true\n\n    private fun updateMatrix() {\n        val matrix: Matrix\n        val target = groupMatrix\n        if (target == null) {\n            matrix = Matrix()\n            groupMatrix = matrix\n        } else {\n            matrix = target\n            matrix.reset()\n        }\n        // M = T(translationX + pivotX, translationY + pivotY) *\n        //     R(rotation) * S(scaleX, scaleY) *\n        //     T(-pivotX, -pivotY)\n        matrix.translate(translationX + pivotX, translationY + pivotY)\n        matrix.rotateZ(degrees = rotation)\n        matrix.scale(scaleX, scaleY, 1f)\n        matrix.translate(-pivotX, -pivotY)\n    }\n\n    fun insertAt(\n        index: Int,\n        instance: VNode\n    ) {\n        if (index < numChildren) {\n            children[index] = instance\n        } else {\n            children.add(instance)\n        }\n\n        markTintForVNode(instance)\n\n        instance.invalidateListener = wrappedListener\n        invalidate()\n    }\n\n    fun remove(\n        index: Int,\n        count: Int\n    ) {\n        repeat(count) {\n            if (index < children.size) {\n                children[index].invalidateListener = null\n                children.removeAt(index)\n            }\n        }\n        invalidate()\n    }\n\n    override fun DrawScope.draw() {\n        if (isMatrixDirty) {\n            updateMatrix()\n            isMatrixDirty = false\n        }\n\n        if (isClipPathDirty) {\n            updateClipPath()\n            isClipPathDirty = false\n        }\n\n        withTransform({\n            groupMatrix?.let { transform(it) }\n            val targetClip = clipPath\n            if (willClipPath && targetClip != null) {\n                clipPath(targetClip)\n            }\n        }) {\n            children.fastForEach { node ->\n                with(node) {\n                    this@draw.draw()\n                }\n            }\n        }\n    }\n\n    override fun toString(): String {\n        val sb = StringBuilder().append(\"VGroup: \").append(name)\n        children.fastForEach { node ->\n            sb.append(\"\\t\").append(node.toString()).append(\"\\n\")\n        }\n        return sb.toString()\n    }\n}\n\n/**\n * statically create a a GroupComponent from the VectorGroup representation provided from\n * an [ImageVector] instance\n */\ninternal fun GroupComponent.createGroupComponent(currentGroup: VectorGroup): GroupComponent {\n    for (index in 0 until currentGroup.size) {\n        val vectorNode = currentGroup[index]\n        if (vectorNode is VectorPath) {\n            val pathComponent = PathComponent().apply {\n                pathData = vectorNode.pathData\n                pathFillType = vectorNode.pathFillType\n                name = vectorNode.name\n                fill = vectorNode.fill\n                fillAlpha = vectorNode.fillAlpha\n                stroke = vectorNode.stroke\n                strokeAlpha = vectorNode.strokeAlpha\n                strokeLineWidth = vectorNode.strokeLineWidth\n                strokeLineCap = vectorNode.strokeLineCap\n                strokeLineJoin = vectorNode.strokeLineJoin\n                strokeLineMiter = vectorNode.strokeLineMiter\n                trimPathStart = vectorNode.trimPathStart\n                trimPathEnd = vectorNode.trimPathEnd\n                trimPathOffset = vectorNode.trimPathOffset\n            }\n            insertAt(index, pathComponent)\n        } else if (vectorNode is VectorGroup) {\n            val groupComponent = GroupComponent().apply {\n                name = vectorNode.name\n                rotation = vectorNode.rotation\n                scaleX = vectorNode.scaleX\n                scaleY = vectorNode.scaleY\n                translationX = vectorNode.translationX\n                translationY = vectorNode.translationY\n                pivotX = vectorNode.pivotX\n                pivotY = vectorNode.pivotY\n                clipPathData = vectorNode.clipPathData\n                createGroupComponent(vectorNode)\n            }\n            insertAt(index, groupComponent)\n        }\n    }\n    return this\n}\n\n/**\n * helper method to verify if the rgb channels are equal excluding comparison of the alpha\n * channel\n */\nprivate fun Color.rgbEqual(other: Color) =\n    this.red == other.red &&\n            this.green == other.green &&\n            this.blue == other.blue"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/image_vector/ImageVectorUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector\n\nimport android.content.Context\nimport android.graphics.PorterDuff\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.drawscope.CanvasDrawScope\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.graphics.vector.RootGroupName\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.density\n\n@Composable\nfun imageVectorPainter(imageVector: ImageVector): Painter {\n    val density = LocalDensity.current\n\n    return remember(density, imageVector) {\n        derivedStateOf {\n            imageVector.toPainter(density)\n        }\n    }.value\n}\n\nfun ImageVector.toPainter(\n    density: Density\n): Painter = createVectorPainterFromImageVector(\n    density = density,\n    imageVector = this,\n    root = GroupComponent().apply {\n        createGroupComponent(root)\n    }\n)\n\nfun ImageVector.toPainter(\n    context: Context\n): Painter = toPainter(context.density)\n\nfun ImageVector.toImageBitmap(\n    context: Context,\n    width: Int,\n    height: Int,\n    tint: Color = Color.Unspecified,\n    backgroundColor: Color = Color.Transparent,\n    iconPadding: Int = 0\n): ImageBitmap {\n    val imageBitmap = ImageBitmap(width, height)\n    val density = context.density\n\n    val painter = toPainter(context)\n\n    val canvas = Canvas(imageBitmap).apply {\n        with(nativeCanvas) {\n            drawColor(Color.Transparent.toArgb(), PorterDuff.Mode.CLEAR)\n            drawColor(backgroundColor.toArgb())\n        }\n    }\n\n    CanvasDrawScope().draw(\n        density = density,\n        layoutDirection = LayoutDirection.Ltr,\n        canvas = canvas,\n        size = Size(width.toFloat(), height.toFloat())\n    ) {\n        translate(iconPadding.toFloat(), iconPadding.toFloat()) {\n            with(painter) {\n                draw(\n                    size = Size(\n                        width = (width - iconPadding * 2).toFloat(),\n                        height = (height - iconPadding * 2).toFloat()\n                    ),\n                    colorFilter = ColorFilter.tint(tint)\n                )\n            }\n        }\n    }\n\n    return imageBitmap\n}\n\n/**\n * Helper method to configure the properties of a VectorPainter that maybe re-used\n */\nprivate fun VectorPainter.configureVectorPainter(\n    defaultSize: Size,\n    viewportSize: Size,\n    name: String = RootGroupName,\n    intrinsicColorFilter: ColorFilter?,\n    autoMirror: Boolean = false,\n): VectorPainter = apply {\n    this.size = defaultSize\n    this.autoMirror = autoMirror\n    this.intrinsicColorFilter = intrinsicColorFilter\n    this.viewportSize = viewportSize\n    this.name = name\n}\n\n/**\n * Helper method to create a VectorPainter instance from an ImageVector\n */\nprivate fun createVectorPainterFromImageVector(\n    density: Density,\n    imageVector: ImageVector,\n    root: GroupComponent\n): VectorPainter {\n    val defaultSize = density.obtainSizePx(imageVector.defaultWidth, imageVector.defaultHeight)\n    val viewport = obtainViewportSize(\n        defaultSize,\n        imageVector.viewportWidth,\n        imageVector.viewportHeight\n    )\n    return VectorPainter(root).configureVectorPainter(\n        defaultSize = defaultSize,\n        viewportSize = viewport,\n        name = imageVector.name,\n        intrinsicColorFilter = createColorFilter(imageVector.tintColor, imageVector.tintBlendMode),\n        autoMirror = imageVector.autoMirror\n    )\n}\n\n/**\n * Helper method to conditionally create a ColorFilter to tint contents if [tintColor] is\n * specified, that is [Color.isSpecified] returns true\n */\nprivate fun createColorFilter(\n    tintColor: Color,\n    tintBlendMode: BlendMode\n): ColorFilter? = if (tintColor.isSpecified) {\n    ColorFilter.tint(tintColor, tintBlendMode)\n} else {\n    null\n}\n\n/**\n * Helper method to calculate the viewport size. If the viewport width/height are not specified\n * this falls back on the default size provided\n */\nprivate fun obtainViewportSize(\n    defaultSize: Size,\n    viewportWidth: Float,\n    viewportHeight: Float\n) = Size(\n    if (viewportWidth.isNaN()) defaultSize.width else viewportWidth,\n    if (viewportHeight.isNaN()) defaultSize.height else viewportHeight\n)\n\nprivate fun Density.obtainSizePx(\n    defaultWidth: Dp,\n    defaultHeight: Dp\n) = Size(defaultWidth.toPx(), defaultHeight.toPx())"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/image_vector/PathComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector\n\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathMeasure\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.vector.DefaultFillType\nimport androidx.compose.ui.graphics.vector.DefaultPathName\nimport androidx.compose.ui.graphics.vector.DefaultStrokeLineCap\nimport androidx.compose.ui.graphics.vector.DefaultStrokeLineJoin\nimport androidx.compose.ui.graphics.vector.DefaultStrokeLineMiter\nimport androidx.compose.ui.graphics.vector.DefaultStrokeLineWidth\nimport androidx.compose.ui.graphics.vector.DefaultTrimPathEnd\nimport androidx.compose.ui.graphics.vector.DefaultTrimPathOffset\nimport androidx.compose.ui.graphics.vector.DefaultTrimPathStart\nimport androidx.compose.ui.graphics.vector.EmptyPath\nimport androidx.compose.ui.graphics.vector.toPath\n\ninternal class PathComponent : VNode() {\n    var name = DefaultPathName\n        set(value) {\n            field = value\n            invalidate()\n        }\n\n    var fill: Brush? = null\n        set(value) {\n            field = value\n            invalidate()\n        }\n\n    var fillAlpha = 1.0f\n        set(value) {\n            field = value\n            invalidate()\n        }\n\n    var pathData = EmptyPath\n        set(value) {\n            field = value\n            isPathDirty = true\n            invalidate()\n        }\n\n    var pathFillType = DefaultFillType\n        set(value) {\n            field = value\n            renderPath.fillType = value\n            invalidate()\n        }\n\n    var strokeAlpha = 1.0f\n        set(value) {\n            field = value\n            invalidate()\n        }\n\n    var strokeLineWidth = DefaultStrokeLineWidth\n        set(value) {\n            field = value\n            isStrokeDirty = true\n            invalidate()\n        }\n\n    var stroke: Brush? = null\n        set(value) {\n            field = value\n            invalidate()\n        }\n\n    var strokeLineCap = DefaultStrokeLineCap\n        set(value) {\n            field = value\n            isStrokeDirty = true\n            invalidate()\n        }\n\n    var strokeLineJoin = DefaultStrokeLineJoin\n        set(value) {\n            field = value\n            isStrokeDirty = true\n            invalidate()\n        }\n\n    var strokeLineMiter = DefaultStrokeLineMiter\n        set(value) {\n            field = value\n            isStrokeDirty = true\n            invalidate()\n        }\n\n    var trimPathStart = DefaultTrimPathStart\n        set(value) {\n            field = value\n            isTrimPathDirty = true\n            invalidate()\n        }\n\n    var trimPathEnd = DefaultTrimPathEnd\n        set(value) {\n            field = value\n            isTrimPathDirty = true\n            invalidate()\n        }\n\n    var trimPathOffset = DefaultTrimPathOffset\n        set(value) {\n            field = value\n            isTrimPathDirty = true\n            invalidate()\n        }\n\n    private var isPathDirty = true\n    private var isStrokeDirty = true\n    private var isTrimPathDirty = false\n\n    private var strokeStyle: Stroke? = null\n\n    private val path = Path()\n    private var renderPath = path\n\n    private val pathMeasure: PathMeasure by lazy(LazyThreadSafetyMode.NONE) { PathMeasure() }\n\n    private fun updatePath() {\n        // The call below resets the path\n        pathData.toPath(path)\n        updateRenderPath()\n    }\n\n    private fun updateRenderPath() {\n        if (trimPathStart == DefaultTrimPathStart && trimPathEnd == DefaultTrimPathEnd) {\n            renderPath = path\n        } else {\n            if (renderPath == path) {\n                renderPath = Path()\n            } else {\n                // Rewind unsets the fill type so reset it here\n                val fillType = renderPath.fillType\n                renderPath.rewind()\n                renderPath.fillType = fillType\n            }\n\n            pathMeasure.setPath(path, false)\n            val length = pathMeasure.length\n            val start = ((trimPathStart + trimPathOffset) % 1f) * length\n            val end = ((trimPathEnd + trimPathOffset) % 1f) * length\n            if (start > end) {\n                pathMeasure.getSegment(start, length, renderPath, true)\n                pathMeasure.getSegment(0f, end, renderPath, true)\n            } else {\n                pathMeasure.getSegment(start, end, renderPath, true)\n            }\n        }\n    }\n\n    override fun DrawScope.draw() {\n        if (isPathDirty) {\n            updatePath()\n        } else if (isTrimPathDirty) {\n            updateRenderPath()\n        }\n        isPathDirty = false\n        isTrimPathDirty = false\n\n        fill?.let { drawPath(renderPath, brush = it, alpha = fillAlpha) }\n        stroke?.let {\n            var targetStroke = strokeStyle\n            if (isStrokeDirty || targetStroke == null) {\n                targetStroke =\n                    Stroke(strokeLineWidth, strokeLineMiter, strokeLineCap, strokeLineJoin)\n                strokeStyle = targetStroke\n                isStrokeDirty = false\n            }\n            drawPath(renderPath, brush = it, alpha = strokeAlpha, style = targetStroke)\n        }\n    }\n\n    override fun toString() = path.toString()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/image_vector/VNode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector\n\nimport androidx.compose.ui.graphics.drawscope.DrawScope\n\ninternal sealed class VNode {\n    /**\n     * Callback invoked whenever the node in the vector tree is modified in a way that would\n     * change the output of the Vector\n     */\n    internal open var invalidateListener: ((VNode) -> Unit)? = null\n\n    fun invalidate() {\n        invalidateListener?.invoke(this)\n    }\n\n    abstract fun DrawScope.draw()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/image_vector/VectorComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.BlendModeColorFilter\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.ImageBitmapConfig\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.scale\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.graphics.vector.DefaultGroupName\nimport androidx.compose.ui.unit.IntSize\nimport kotlin.math.ceil\n\ninternal class VectorComponent(val root: GroupComponent) : VNode() {\n\n    init {\n        root.invalidateListener = {\n            doInvalidate()\n        }\n    }\n\n    var name: String = DefaultGroupName\n\n    private fun doInvalidate() {\n        isDirty = true\n        invalidateCallback.invoke()\n    }\n\n    private var isDirty = true\n\n    private val cacheDrawScope = DrawCache()\n\n    private val cacheBitmapConfig: ImageBitmapConfig\n        get() = cacheDrawScope.mCachedImage?.config ?: ImageBitmapConfig.Argb8888\n\n    internal var invalidateCallback = {}\n\n    internal var intrinsicColorFilter: ColorFilter? by mutableStateOf(null)\n\n    // Conditional filter used if the vector is all one color. In this case we allocate a\n    // alpha8 channel bitmap and tint the result to the desired color\n    private var tintFilter: ColorFilter? = null\n\n    internal var viewportSize by mutableStateOf(Size.Zero)\n\n    private var previousDrawSize = Size.Unspecified\n\n    private var rootScaleX = 1f\n    private var rootScaleY = 1f\n\n    /**\n     * Cached lambda used to avoid allocating the lambda on each draw invocation\n     */\n    private val drawVectorBlock: DrawScope.() -> Unit = {\n        with(root) {\n            scale(rootScaleX, rootScaleY, pivot = Offset.Zero) {\n                draw()\n            }\n        }\n    }\n\n    fun DrawScope.draw(\n        alpha: Float,\n        colorFilter: ColorFilter?\n    ) {\n        // If the content of the vector has changed, or we are drawing a different size\n        // update the cached image to ensure we are scaling the vector appropriately\n        val isOneColor = root.isTintable && root.tintColor.isSpecified\n        val targetImageConfig = if (isOneColor && intrinsicColorFilter.tintableWithAlphaMask() &&\n            colorFilter.tintableWithAlphaMask()\n        ) {\n            ImageBitmapConfig.Alpha8\n        } else {\n            ImageBitmapConfig.Argb8888\n        }\n\n        if (isDirty || previousDrawSize != size || targetImageConfig != cacheBitmapConfig) {\n            tintFilter = if (targetImageConfig == ImageBitmapConfig.Alpha8) {\n                ColorFilter.tint(root.tintColor)\n            } else {\n                null\n            }\n            rootScaleX = size.width / viewportSize.width\n            rootScaleY = size.height / viewportSize.height\n            cacheDrawScope.drawCachedImage(\n                targetImageConfig,\n                IntSize(ceil(size.width).toInt(), ceil(size.height).toInt()),\n                this@draw,\n                layoutDirection,\n                drawVectorBlock\n            )\n            isDirty = false\n            previousDrawSize = size\n        }\n        val targetFilter = colorFilter\n            ?: if (intrinsicColorFilter != null) {\n                intrinsicColorFilter\n            } else {\n                tintFilter\n            }\n        cacheDrawScope.drawInto(this, alpha, targetFilter)\n    }\n\n    override fun DrawScope.draw() {\n        draw(1.0f, null)\n    }\n\n    override fun toString(): String {\n        return buildString {\n            append(\"Params: \")\n            append(\"\\tname: \").append(name).append(\"\\n\")\n            append(\"\\tviewportWidth: \").append(viewportSize.width).append(\"\\n\")\n            append(\"\\tviewportHeight: \").append(viewportSize.height).append(\"\\n\")\n        }\n    }\n\n    /**\n     * Helper method to determine if a particular ColorFilter will generate the same output\n     * if the bitmap has an Alpha8 or ARGB8888 configuration\n     */\n    private fun ColorFilter?.tintableWithAlphaMask() = if (this is BlendModeColorFilter) {\n        this.blendMode == BlendMode.SrcIn || this.blendMode == BlendMode.SrcOver\n    } else {\n        this == null\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/helper/image_vector/VectorPainter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper.image_vector\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.scale\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.unit.LayoutDirection\n\n/**\n * [Painter] implementation that abstracts the drawing of a Vector graphic.\n * This can be represented by either a [ImageVector] or a programmatic\n * composition of a vector\n */\ninternal class VectorPainter internal constructor(\n    root: GroupComponent = GroupComponent()\n) : Painter() {\n\n    internal var size by mutableStateOf(Size.Zero)\n\n    internal var autoMirror by mutableStateOf(false)\n\n    /**\n     * configures the intrinsic tint that may be defined on a VectorPainter\n     */\n    internal var intrinsicColorFilter: ColorFilter?\n        get() = vector.intrinsicColorFilter\n        set(value) {\n            vector.intrinsicColorFilter = value\n        }\n\n    internal var viewportSize: Size\n        get() = vector.viewportSize\n        set(value) {\n            vector.viewportSize = value\n        }\n\n    internal var name: String\n        get() = vector.name\n        set(value) {\n            vector.name = value\n        }\n\n    internal val vector = VectorComponent(root).apply {\n        invalidateCallback = {\n            if (drawCount == invalidateCount) {\n                invalidateCount++\n            }\n        }\n    }\n\n    private var invalidateCount by mutableIntStateOf(0)\n\n    private var currentAlpha: Float = 1.0f\n    private var currentColorFilter: ColorFilter? = null\n\n    override val intrinsicSize: Size\n        get() = size\n\n    private var drawCount = -1\n\n    override fun DrawScope.onDraw() {\n        with(vector) {\n            val filter = currentColorFilter ?: intrinsicColorFilter\n            if (autoMirror && layoutDirection == LayoutDirection.Rtl) {\n                mirror {\n                    draw(currentAlpha, filter)\n                }\n            } else {\n                draw(currentAlpha, filter)\n            }\n        }\n        // This assignment is necessary to obtain invalidation callbacks as the state is\n        // being read here which adds this callback to the snapshot observation\n        drawCount = invalidateCount\n    }\n\n    override fun applyAlpha(alpha: Float): Boolean {\n        currentAlpha = alpha\n        return true\n    }\n\n    override fun applyColorFilter(colorFilter: ColorFilter?): Boolean {\n        currentColorFilter = colorFilter\n        return true\n    }\n\n    private inline fun DrawScope.mirror(block: DrawScope.() -> Unit) {\n        scale(-1f, 1f, block = block)\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/navigation/Decompose.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.navigation\n\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.value.MutableValue\nimport com.arkivanov.decompose.value.Value\nimport com.arkivanov.decompose.value.updateAndGet\nimport com.arkivanov.essenty.lifecycle.Lifecycle\nimport com.arkivanov.essenty.lifecycle.LifecycleOwner\nimport com.arkivanov.essenty.lifecycle.doOnDestroy\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.CoroutineExceptionHandler\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.SupervisorJob\nimport kotlinx.coroutines.cancel\nimport kotlin.coroutines.CoroutineContext\nimport kotlin.reflect.KProperty\n\nval ComponentContext.coroutineScope: CoroutineScope\n    get() = coroutineScope()\n\n/**\n * Creates and returns a new [CoroutineScope] with the specified [context].\n * The returned [CoroutineScope] is automatically cancelled when the [Lifecycle] is destroyed.\n *\n * @param context a [CoroutineContext] to be used for creating the [CoroutineScope], default\n * is [Dispatchers.Main.immediate][kotlinx.coroutines.MainCoroutineDispatcher.immediate]\n * if available on the current platform, or [Dispatchers.Main] otherwise.\n */\nfun LifecycleOwner.coroutineScope(\n    context: CoroutineContext = Dispatchers.Main.immediate + SupervisorJob() + CoroutineExceptionHandler { _, t ->\n        t.makeLog(\n            \"Component CRITICAL ISSUE\"\n        )\n    },\n): CoroutineScope =\n    CoroutineScope(context = context).withLifecycle(lifecycle)\n\n/**\n * Automatically cancels this [CoroutineScope] when the specified [lifecycle] is destroyed.\n *\n * @return the same (this) [CoroutineScope].\n */\nfun CoroutineScope.withLifecycle(lifecycle: Lifecycle): CoroutineScope {\n    lifecycle.doOnDestroy(::cancel)\n\n    return this\n}\n\n@JvmInline\nvalue class Nullable<T>(\n    val value: T?\n) {\n    operator fun component1(): T? = value\n    operator fun getValue(\n        t: T?,\n        property: KProperty<*>\n    ): T? = value\n\n    fun copy(value: T?) = Nullable(value)\n}\n\nfun <T> T?.wrap(): Nullable<T> = Nullable(this)\n\nfun <T> MutableValue<Nullable<T>>.updateNullable(function: (T?) -> T?) {\n    updateAndGet {\n        function(this.value.value).wrap()\n    }\n}\n\ntypealias NullableValue<T> = Value<Nullable<T>>\n\ntypealias MutableNullableValue<T> = MutableValue<Nullable<T>>\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/navigation/Screen.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"PLUGIN_IS_NOT_ENABLED\")\n\npackage com.t8rin.imagetoolbox.core.ui.utils.navigation\n\nimport androidx.annotation.StringRes\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.AutoFixHigh\nimport androidx.compose.material.icons.outlined.FilePresent\nimport androidx.compose.material.icons.rounded.Animation\nimport androidx.compose.material.icons.rounded.Gif\nimport androidx.compose.material.icons.rounded.Texture\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Apng\nimport com.t8rin.imagetoolbox.core.resources.icons.ArtTrack\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.resources.icons.Jpg\nimport com.t8rin.imagetoolbox.core.resources.icons.Jxl\nimport com.t8rin.imagetoolbox.core.resources.icons.Pdf\nimport com.t8rin.imagetoolbox.core.resources.icons.TextSearch\nimport com.t8rin.imagetoolbox.core.resources.icons.Webp\nimport kotlinx.serialization.SerialName\nimport kotlinx.serialization.Serializable\n\n@Serializable\n@Stable\n@Immutable\nsealed class Screen(\n    open val id: Int,\n    @StringRes val title: Int,\n    @StringRes val subtitle: Int\n) {\n\n    val isBetaFeature: Boolean by lazy { isBetaFeature() }\n\n    val simpleName: String by lazy { simpleName() }\n\n    val icon: ImageVector? by lazy { icon() }\n\n    val twoToneIcon: ImageVector? by lazy { twoToneIcon() }\n\n    @Serializable\n    data class LibraryDetails(\n        val name: String,\n        val htmlDescription: String,\n        val link: String?\n    ) : Screen(\n        id = -5,\n        title = 0,\n        subtitle = 0\n    )\n\n    @Serializable\n    data object LibrariesInfo : Screen(\n        id = -4,\n        title = 0,\n        subtitle = 0\n    )\n\n    @Serializable\n    data class Settings(\n        val searchQuery: String = \"\"\n    ) : Screen(\n        id = -3,\n        title = 0,\n        subtitle = 0\n    )\n\n    @Serializable\n    data object EasterEgg : Screen(\n        id = -2,\n        title = 0,\n        subtitle = 0\n    )\n\n    @Serializable\n    data object Main : Screen(\n        id = -1,\n        title = 0,\n        subtitle = 0\n    )\n\n    @Serializable\n    data class SingleEdit(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 0,\n        title = R.string.single_edit,\n        subtitle = R.string.single_edit_sub\n    )\n\n    @Serializable\n    data class ResizeAndConvert(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 1,\n        title = R.string.resize_and_convert,\n        subtitle = R.string.resize_and_convert_sub\n    )\n\n    @Serializable\n    data class WeightResize(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 2,\n        title = R.string.by_bytes_resize,\n        subtitle = R.string.by_bytes_resize_sub\n    )\n\n    @Serializable\n    data class Crop(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 3,\n        title = R.string.crop,\n        subtitle = R.string.crop_sub\n    )\n\n    @Serializable\n    data class Filter(\n        @SerialName(\"dataType\") val type: Type? = null\n    ) : Screen(\n        id = 4,\n        title = R.string.filter,\n        subtitle = R.string.filter_sub\n    ) {\n        @Serializable\n        sealed class Type(\n            @StringRes val title: Int,\n            @StringRes val subtitle: Int\n        ) {\n\n            val icon: ImageVector\n                get() = when (this) {\n                    is Masking -> Icons.Rounded.Texture\n                    is Basic -> Icons.Outlined.AutoFixHigh\n                }\n\n            @Serializable\n            data class Masking(\n                val uri: Uri? = null\n            ) : Type(\n                title = R.string.mask_filter,\n                subtitle = R.string.mask_filter_sub\n            )\n\n            @Serializable\n            data class Basic(\n                val uris: List<Uri>? = null\n            ) : Type(\n                title = R.string.full_filter,\n                subtitle = R.string.full_filter_sub\n            )\n\n            companion object {\n                val entries by lazy {\n                    listOf(\n                        Basic(),\n                        Masking()\n                    )\n                }\n            }\n        }\n    }\n\n    @Serializable\n    data class Draw(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 5,\n        title = R.string.draw,\n        subtitle = R.string.draw_sub\n    )\n\n    @Serializable\n    data class Cipher(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 6,\n        title = R.string.cipher,\n        subtitle = R.string.cipher_sub\n    )\n\n    @Serializable\n    data class EraseBackground(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 7,\n        title = R.string.background_remover,\n        subtitle = R.string.background_remover_sub\n    )\n\n    @Serializable\n    data class ImagePreview(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 8,\n        title = R.string.image_preview,\n        subtitle = R.string.image_preview_sub\n    )\n\n    @Serializable\n    data class ImageStitching(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 9,\n        title = R.string.image_stitching,\n        subtitle = R.string.image_stitching_sub\n    )\n\n    @Serializable\n    data class LoadNetImage(\n        val url: String = \"\"\n    ) : Screen(\n        id = 10,\n        title = R.string.load_image_from_net,\n        subtitle = R.string.load_image_from_net_sub\n    )\n\n    @Serializable\n    data class PickColorFromImage(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 11,\n        title = R.string.pick_color,\n        subtitle = R.string.pick_color_sub\n    )\n\n    @Serializable\n    data class PaletteTools(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 12,\n        title = R.string.palette_tools,\n        subtitle = R.string.palette_tools_sub\n    )\n\n    @Serializable\n    data class DeleteExif(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 13,\n        title = R.string.delete_exif,\n        subtitle = R.string.delete_exif_sub\n    )\n\n    @Serializable\n    data class Compare(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 14,\n        title = R.string.compare,\n        subtitle = R.string.compare_sub\n    )\n\n    @Serializable\n    data class LimitResize(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 15,\n        title = R.string.limits_resize,\n        subtitle = R.string.limits_resize_sub\n    )\n\n    @Serializable\n    data object PdfTools : Screen(\n        id = 16,\n        title = R.string.pdf_tools,\n        subtitle = R.string.pdf_tools_sub\n    ) {\n        val options: List<Screen> by lazy {\n            listOf(\n                Preview(),\n                ImagesToPdf(),\n                ExtractPages(),\n                Merge(),\n                Split(),\n                RemovePages(),\n                Rotate(),\n                Rearrange(),\n                Crop(),\n                PageNumbers(),\n                Watermark(),\n                Signature(),\n                Compress(),\n                RemoveAnnotations(),\n                Flatten(),\n                Print(),\n                Grayscale(),\n                Repair(),\n                Protect(),\n                Unlock(),\n                Metadata(),\n                ExtractImages(),\n                OCR(),\n                ZipConvert(),\n            )\n        }\n\n        @Serializable\n        data class Merge(\n            val uris: List<Uri>? = null\n        ) : Screen(\n            id = 44,\n            title = R.string.merge_pdf,\n            subtitle = R.string.merge_pdf_sub\n        )\n\n        @Serializable\n        data class Split(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 45,\n            title = R.string.split_pdf,\n            subtitle = R.string.split_pdf_sub\n        )\n\n        @Serializable\n        data class Rotate(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 46,\n            title = R.string.rotate_pdf,\n            subtitle = R.string.rotate_pdf_sub\n        )\n\n        @Serializable\n        data class Rearrange(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 47,\n            title = R.string.rearrange_pdf,\n            subtitle = R.string.rearrange_pdf_sub\n        )\n\n        @Serializable\n        data class PageNumbers(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 48,\n            title = R.string.page_numbers,\n            subtitle = R.string.page_numbers_sub\n        )\n\n        @Serializable\n        data class OCR(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 49,\n            title = R.string.pdf_to_text,\n            subtitle = R.string.pdf_to_text_sub\n        )\n\n        @Serializable\n        data class Watermark(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 50,\n            title = R.string.watermarking,\n            subtitle = R.string.watermark_pdf_sub\n        )\n\n        @Serializable\n        data class Signature(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 51,\n            title = R.string.signature,\n            subtitle = R.string.signature_sub\n        )\n\n        @Serializable\n        data class Protect(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 52,\n            title = R.string.protect_pdf,\n            subtitle = R.string.protect_pdf_sub\n        )\n\n        @Serializable\n        data class Unlock(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 53,\n            title = R.string.unlock_pdf,\n            subtitle = R.string.unlock_pdf_sub\n        )\n\n        @Serializable\n        data class Compress(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 54,\n            title = R.string.compress_pdf,\n            subtitle = R.string.compress_pdf_sub\n        )\n\n        @Serializable\n        data class Grayscale(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 55,\n            title = R.string.grayscale,\n            subtitle = R.string.grayscale_pdf_sub\n        )\n\n        @Serializable\n        data class Repair(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 56,\n            title = R.string.repair_pdf,\n            subtitle = R.string.repair_pdf_sub\n        )\n\n        @Serializable\n        data class Metadata(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 57,\n            title = R.string.metadata,\n            subtitle = R.string.metadata_pdf_sub\n        )\n\n        @Serializable\n        data class RemovePages(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 58,\n            title = R.string.remove_pages_pdf,\n            subtitle = R.string.remove_pages_pdf_sub\n        )\n\n        @Serializable\n        data class Crop(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 59,\n            title = R.string.crop_pdf,\n            subtitle = R.string.crop_pdf_sub\n        )\n\n        @Serializable\n        data class Flatten(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 60,\n            title = R.string.flatten_pdf,\n            subtitle = R.string.flatten_pdf_sub\n        )\n\n        @Serializable\n        data class ExtractImages(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 61,\n            title = R.string.extract_images,\n            subtitle = R.string.extract_images_sub\n        )\n\n        @Serializable\n        data class ZipConvert(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 62,\n            title = R.string.zip_pdf,\n            subtitle = R.string.zip_pdf_sub\n        )\n\n        @Serializable\n        data class Print(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 63,\n            title = R.string.print_pdf,\n            subtitle = R.string.print_pdf_sub\n        )\n\n        @Serializable\n        data class Preview(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 64,\n            title = R.string.preview_pdf,\n            subtitle = R.string.preview_pdf_sub\n        )\n\n        @Serializable\n        data class ImagesToPdf(\n            val uris: List<Uri>? = null\n        ) : Screen(\n            id = 65,\n            title = R.string.images_to_pdf,\n            subtitle = R.string.images_to_pdf_sub\n        )\n\n        @Serializable\n        data class ExtractPages(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 66,\n            title = R.string.pdf_to_images,\n            subtitle = R.string.pdf_to_images_sub\n        )\n\n        @Serializable\n        data class RemoveAnnotations(\n            val uri: Uri? = null\n        ) : Screen(\n            id = 67,\n            title = R.string.remove_annotations,\n            subtitle = R.string.remove_annotations_sub\n        )\n    }\n\n    @Serializable\n    data class RecognizeText(\n        @SerialName(\"dataType\") val type: Type? = null\n    ) : Screen(\n        id = 17,\n        title = R.string.recognize_text,\n        subtitle = R.string.recognize_text_sub\n    ) {\n        @Serializable\n        sealed class Type(\n            @StringRes val title: Int,\n            @StringRes val subtitle: Int\n        ) {\n\n            val icon: ImageVector\n                get() = when (this) {\n                    is Extraction -> Icons.Outlined.TextSearch\n                    is WriteToFile -> Icons.Outlined.FilePresent\n                    is WriteToMetadata -> Icons.Outlined.Exif\n                    is WriteToSearchablePdf -> Icons.Outlined.Pdf\n                }\n\n            @Serializable\n            data class Extraction(\n                val uri: Uri? = null\n            ) : Type(\n                title = R.string.recognize_text,\n                subtitle = R.string.recognize_text_sub\n            )\n\n            @Serializable\n            data class WriteToFile(\n                val uris: List<Uri>? = null\n            ) : Type(\n                title = R.string.ocr_write_to_file,\n                subtitle = R.string.ocr_write_to_file_sub\n            )\n\n            @Serializable\n            data class WriteToMetadata(\n                val uris: List<Uri>? = null\n            ) : Type(\n                title = R.string.ocr_write_to_metadata,\n                subtitle = R.string.ocr_write_to_metadata_sub\n            )\n\n            @Serializable\n            data class WriteToSearchablePdf(\n                val uris: List<Uri>? = null\n            ) : Type(\n                title = R.string.ocr_write_to_searchable_pdf,\n                subtitle = R.string.ocr_write_to_searchable_pdf_sub\n            )\n\n            companion object {\n                val entries by lazy {\n                    listOf(\n                        Extraction(),\n                        WriteToFile(),\n                        WriteToMetadata(),\n                        WriteToSearchablePdf()\n                    )\n                }\n            }\n        }\n    }\n\n    @Serializable\n    data class GradientMaker(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 18,\n        title = R.string.gradient_maker,\n        subtitle = R.string.gradient_maker_sub,\n    )\n\n    @Serializable\n    data class Watermarking(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 19,\n        title = R.string.watermarking,\n        subtitle = R.string.watermarking_sub,\n    )\n\n    @Serializable\n    data class GifTools(\n        @SerialName(\"dataType\") val type: Type? = null\n    ) : Screen(\n        id = 20,\n        title = R.string.gif_tools,\n        subtitle = R.string.gif_tools_sub\n    ) {\n        @Serializable\n        sealed class Type(\n            @StringRes val title: Int,\n            @StringRes val subtitle: Int\n        ) {\n\n            val icon: ImageVector\n                get() = when (this) {\n                    is GifToImage -> Icons.Outlined.ArtTrack\n                    is GifToJxl -> Icons.Filled.Jxl\n                    is ImageToGif -> Icons.Rounded.Gif\n                    is GifToWebp -> Icons.Rounded.Webp\n                }\n\n            @Serializable\n            data class GifToImage(\n                val gifUri: Uri? = null\n            ) : Type(\n                title = R.string.gif_type_to_image,\n                subtitle = R.string.gif_type_to_image_sub\n            )\n\n            @Serializable\n            data class ImageToGif(\n                val imageUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.gif_type_to_gif,\n                subtitle = R.string.gif_type_to_gif_sub\n            )\n\n            @Serializable\n            data class GifToJxl(\n                val gifUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.gif_type_to_jxl,\n                subtitle = R.string.gif_type_to_jxl_sub\n            )\n\n            @Serializable\n            data class GifToWebp(\n                val gifUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.gif_type_to_webp,\n                subtitle = R.string.gif_type_to_webp_sub\n            )\n\n            companion object {\n                val entries by lazy {\n                    listOf(\n                        ImageToGif(),\n                        GifToImage(),\n                        GifToJxl(),\n                        GifToWebp()\n                    )\n                }\n            }\n        }\n    }\n\n    @Serializable\n    data class ApngTools(\n        @SerialName(\"dataType\") val type: Type? = null\n    ) : Screen(\n        id = 21,\n        title = R.string.apng_tools,\n        subtitle = R.string.apng_tools_sub\n    ) {\n        @Serializable\n        sealed class Type(\n            @StringRes val title: Int,\n            @StringRes val subtitle: Int\n        ) {\n\n            val icon: ImageVector\n                get() = when (this) {\n                    is ApngToImage -> Icons.Outlined.ArtTrack\n                    is ApngToJxl -> Icons.Filled.Jxl\n                    is ImageToApng -> Icons.Rounded.Apng\n                }\n\n            @Serializable\n            data class ApngToImage(\n                val apngUri: Uri? = null\n            ) : Type(\n                title = R.string.apng_type_to_image,\n                subtitle = R.string.apng_type_to_image_sub\n            )\n\n            @Serializable\n            data class ImageToApng(\n                val imageUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.apng_type_to_apng,\n                subtitle = R.string.apng_type_to_apng_sub\n            )\n\n            @Serializable\n            data class ApngToJxl(\n                val apngUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.apng_type_to_jxl,\n                subtitle = R.string.apng_type_to_jxl_sub\n            )\n\n            companion object {\n                val entries by lazy {\n                    listOf(\n                        ImageToApng(),\n                        ApngToImage(),\n                        ApngToJxl()\n                    )\n                }\n            }\n        }\n    }\n\n    @Serializable\n    data class Zip(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 22,\n        title = R.string.zip,\n        subtitle = R.string.zip_sub\n    )\n\n    @Serializable\n    data class JxlTools(\n        @SerialName(\"dataType\") val type: Type? = null\n    ) : Screen(\n        id = 23,\n        title = R.string.jxl_tools,\n        subtitle = R.string.jxl_tools_sub\n    ) {\n        @Serializable\n        sealed class Type(\n            @StringRes val title: Int,\n            @StringRes val subtitle: Int\n        ) {\n\n            val icon: ImageVector\n                get() = when (this) {\n                    is ImageToJxl -> Icons.Rounded.Animation\n                    is JpegToJxl -> Icons.Filled.Jxl\n                    is JxlToImage -> Icons.Outlined.ArtTrack\n                    is JxlToJpeg -> Icons.Outlined.Jpg\n                }\n\n            @Serializable\n            data class JxlToJpeg(\n                val jxlImageUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.jxl_type_to_jpeg,\n                subtitle = R.string.jxl_type_to_jpeg_sub\n            )\n\n            @Serializable\n            data class JpegToJxl(\n                val jpegImageUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.jpeg_type_to_jxl,\n                subtitle = R.string.jpeg_type_to_jxl_sub\n            )\n\n            @Serializable\n            data class JxlToImage(\n                val jxlUri: Uri? = null\n            ) : Type(\n                title = R.string.jxl_type_to_images,\n                subtitle = R.string.jxl_type_to_images_sub\n            )\n\n            @Serializable\n            data class ImageToJxl(\n                val imageUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.jxl_type_to_jxl,\n                subtitle = R.string.jxl_type_to_jxl_sub\n            )\n\n            companion object {\n                val entries by lazy {\n                    listOf(\n                        JpegToJxl(),\n                        JxlToJpeg(),\n                        JxlToImage(),\n                        ImageToJxl()\n                    )\n                }\n            }\n        }\n    }\n\n    @Serializable\n    data class SvgMaker(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 24,\n        title = R.string.images_to_svg,\n        subtitle = R.string.images_to_svg_sub\n    )\n\n    @Serializable\n    data class FormatConversion(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 25,\n        title = R.string.format_conversion,\n        subtitle = R.string.format_conversion_sub\n    )\n\n    @Serializable\n    data object DocumentScanner : Screen(\n        id = 26,\n        title = R.string.document_scanner,\n        subtitle = R.string.document_scanner_sub\n    )\n\n    @Serializable\n    data class ScanQrCode(\n        val qrCodeContent: String? = null,\n        val uriToAnalyze: Uri? = null\n    ) : Screen(\n        id = 27,\n        title = R.string.qr_code,\n        subtitle = R.string.barcodes_sub\n    )\n\n    @Serializable\n    data class ImageStacking(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 28,\n        title = R.string.image_stacking,\n        subtitle = R.string.image_stacking_sub\n    )\n\n    @Serializable\n    data class ImageSplitting(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 29,\n        title = R.string.image_splitting,\n        subtitle = R.string.image_splitting_sub\n    )\n\n    @Serializable\n    data object ColorTools : Screen(\n        id = 30,\n        title = R.string.color_tools,\n        subtitle = R.string.color_tools_sub\n    )\n\n    @Serializable\n    data class WebpTools(\n        @SerialName(\"dataType\") val type: Type? = null\n    ) : Screen(\n        id = 31,\n        title = R.string.webp_tools,\n        subtitle = R.string.webp_tools_sub\n    ) {\n        @Serializable\n        sealed class Type(\n            @StringRes val title: Int,\n            @StringRes val subtitle: Int\n        ) {\n\n            val icon: ImageVector\n                get() = when (this) {\n                    is WebpToImage -> Icons.Outlined.ArtTrack\n                    is ImageToWebp -> Icons.Rounded.Webp\n                }\n\n            @Serializable\n            data class WebpToImage(\n                val webpUri: Uri? = null\n            ) : Type(\n                title = R.string.webp_type_to_image,\n                subtitle = R.string.webp_type_to_image_sub\n            )\n\n            @Serializable\n            data class ImageToWebp(\n                val imageUris: List<Uri>? = null\n            ) : Type(\n                title = R.string.webp_type_to_webp,\n                subtitle = R.string.webp_type_to_webp_sub\n            )\n\n            companion object {\n                val entries by lazy {\n                    listOf(\n                        ImageToWebp(),\n                        WebpToImage()\n                    )\n                }\n            }\n        }\n    }\n\n    @Serializable\n    data object NoiseGeneration : Screen(\n        id = 32,\n        title = R.string.noise_generation,\n        subtitle = R.string.noise_generation_sub\n    )\n\n    @Serializable\n    data class CollageMaker(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 33,\n        title = R.string.collage_maker,\n        subtitle = R.string.collage_maker_sub\n    )\n\n    @Serializable\n    data class MarkupLayers(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 34,\n        title = R.string.markup_layers,\n        subtitle = R.string.markup_layers_sub\n    )\n\n    @Serializable\n    data class Base64Tools(\n        val uri: Uri? = null\n    ) : Screen(\n        id = 35,\n        title = R.string.base_64_tools,\n        subtitle = R.string.base_64_tools_sub\n    )\n\n    @Serializable\n    data class ChecksumTools(\n        val uri: Uri? = null,\n    ) : Screen(\n        id = 36,\n        title = R.string.checksum_tools,\n        subtitle = R.string.checksum_tools_sub\n    )\n\n    @Serializable\n    data object MeshGradients : Screen(\n        id = -5,\n        title = 0,\n        subtitle = 0\n    )\n\n    @Serializable\n    data class EditExif(\n        val uri: Uri? = null,\n    ) : Screen(\n        id = 37,\n        title = R.string.edit_exif_screen,\n        subtitle = R.string.edit_exif_screen_sub\n    )\n\n    @Serializable\n    data class ImageCutter(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 38,\n        title = R.string.image_cutting,\n        subtitle = R.string.image_cutting_sub\n    )\n\n    @Serializable\n    data class AudioCoverExtractor(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 39,\n        title = R.string.audio_cover_extractor,\n        subtitle = R.string.audio_cover_extractor_sub\n    )\n\n    @Serializable\n    data object WallpapersExport : Screen(\n        id = 40,\n        title = R.string.wallpapers_export,\n        subtitle = R.string.wallpapers_export_sub\n    )\n\n    @Serializable\n    data class AsciiArt(\n        val uri: Uri? = null,\n    ) : Screen(\n        id = 41,\n        title = R.string.ascii_art,\n        subtitle = R.string.ascii_art_sub\n    )\n\n    @Serializable\n    data class AiTools(\n        val uris: List<Uri>? = null\n    ) : Screen(\n        id = 42,\n        title = R.string.ai_tools,\n        subtitle = R.string.ai_tools_sub\n    )\n\n    @Serializable\n    data object ColorLibrary : Screen(\n        id = 43,\n        title = R.string.color_library,\n        subtitle = R.string.color_library_sub\n    )\n\n    companion object : ScreenConstants by ScreenConstants\n}\n\ndata class ScreenGroup(\n    val entries: List<Screen>,\n    @StringRes val title: Int,\n    val selectedIcon: ImageVector,\n    val baseIcon: ImageVector\n) {\n    fun icon(isSelected: Boolean) = if (isSelected) selectedIcon else baseIcon\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/navigation/ScreenUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.navigation\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Album\nimport androidx.compose.material.icons.outlined.AutoFixHigh\nimport androidx.compose.material.icons.outlined.ColorLens\nimport androidx.compose.material.icons.outlined.FilterBAndW\nimport androidx.compose.material.icons.outlined.FolderZip\nimport androidx.compose.material.icons.outlined.GifBox\nimport androidx.compose.material.icons.outlined.Gradient\nimport androidx.compose.material.icons.rounded.Tag\nimport androidx.compose.material.icons.twotone.Album\nimport androidx.compose.material.icons.twotone.AutoFixHigh\nimport androidx.compose.material.icons.twotone.ColorLens\nimport androidx.compose.material.icons.twotone.FilterBAndW\nimport androidx.compose.material.icons.twotone.FolderZip\nimport androidx.compose.material.icons.twotone.GifBox\nimport androidx.compose.material.icons.twotone.Gradient\nimport androidx.compose.material.icons.twotone.Preview\nimport androidx.compose.material.icons.twotone.Tag\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ApngBox\nimport com.t8rin.imagetoolbox.core.resources.icons.ArtTrack\nimport com.t8rin.imagetoolbox.core.resources.icons.Ascii\nimport com.t8rin.imagetoolbox.core.resources.icons.Base64\nimport com.t8rin.imagetoolbox.core.resources.icons.Bolt\nimport com.t8rin.imagetoolbox.core.resources.icons.BubbleDelete\nimport com.t8rin.imagetoolbox.core.resources.icons.Build\nimport com.t8rin.imagetoolbox.core.resources.icons.Collage\nimport com.t8rin.imagetoolbox.core.resources.icons.Compare\nimport com.t8rin.imagetoolbox.core.resources.icons.Counter\nimport com.t8rin.imagetoolbox.core.resources.icons.CropSmall\nimport com.t8rin.imagetoolbox.core.resources.icons.DeleteSweep\nimport com.t8rin.imagetoolbox.core.resources.icons.DocumentScanner\nimport com.t8rin.imagetoolbox.core.resources.icons.Draw\nimport com.t8rin.imagetoolbox.core.resources.icons.Encrypted\nimport com.t8rin.imagetoolbox.core.resources.icons.Eraser\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.resources.icons.ExifEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Eyedropper\nimport com.t8rin.imagetoolbox.core.resources.icons.FileImage\nimport com.t8rin.imagetoolbox.core.resources.icons.FindInPage\nimport com.t8rin.imagetoolbox.core.resources.icons.FormatPaintVariant\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageCombine\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageConvert\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageDownload\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageOverlay\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageResize\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageWeight\nimport com.t8rin.imagetoolbox.core.resources.icons.Jxl\nimport com.t8rin.imagetoolbox.core.resources.icons.KeyVariant\nimport com.t8rin.imagetoolbox.core.resources.icons.Landscape\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEditLarge\nimport com.t8rin.imagetoolbox.core.resources.icons.MultipleImageEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Neurology\nimport com.t8rin.imagetoolbox.core.resources.icons.NoiseAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.PaletteSwatch\nimport com.t8rin.imagetoolbox.core.resources.icons.Panorama\nimport com.t8rin.imagetoolbox.core.resources.icons.Pdf\nimport com.t8rin.imagetoolbox.core.resources.icons.Preview\nimport com.t8rin.imagetoolbox.core.resources.icons.Print\nimport com.t8rin.imagetoolbox.core.resources.icons.QrCode\nimport com.t8rin.imagetoolbox.core.resources.icons.Rotate90Cw\nimport com.t8rin.imagetoolbox.core.resources.icons.Scanner\nimport com.t8rin.imagetoolbox.core.resources.icons.ScissorsSmall\nimport com.t8rin.imagetoolbox.core.resources.icons.ServiceToolbox\nimport com.t8rin.imagetoolbox.core.resources.icons.ShieldLock\nimport com.t8rin.imagetoolbox.core.resources.icons.SplitAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.Stacks\nimport com.t8rin.imagetoolbox.core.resources.icons.Stylus\nimport com.t8rin.imagetoolbox.core.resources.icons.SwapVerticalCircle\nimport com.t8rin.imagetoolbox.core.resources.icons.TagText\nimport com.t8rin.imagetoolbox.core.resources.icons.TextSearch\nimport com.t8rin.imagetoolbox.core.resources.icons.Unarchive\nimport com.t8rin.imagetoolbox.core.resources.icons.VectorPolyline\nimport com.t8rin.imagetoolbox.core.resources.icons.WallpaperAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.WandShine\nimport com.t8rin.imagetoolbox.core.resources.icons.Watermark\nimport com.t8rin.imagetoolbox.core.resources.icons.WebpBox\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.AiTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ApngTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.AsciiArt\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.AudioCoverExtractor\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Base64Tools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ChecksumTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Cipher\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.CollageMaker\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ColorLibrary\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ColorTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Compare\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Crop\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.DeleteExif\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.DocumentScanner\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Draw\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.EasterEgg\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.EditExif\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.EraseBackground\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Filter\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.FormatConversion\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.GifTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.GradientMaker\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ImageCutter\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ImagePreview\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ImageSplitting\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ImageStacking\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ImageStitching\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.JxlTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.LibrariesInfo\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.LibraryDetails\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.LimitResize\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.LoadNetImage\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Main\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.MarkupLayers\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.MeshGradients\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.NoiseGeneration\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.PaletteTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.PdfTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.PickColorFromImage\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.RecognizeText\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ResizeAndConvert\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.ScanQrCode\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Settings\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.SingleEdit\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.SvgMaker\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.WallpapersExport\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Watermarking\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.WebpTools\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.WeightResize\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen.Zip\nimport kotlinx.serialization.KSerializer\nimport kotlinx.serialization.Serializable\nimport kotlinx.serialization.descriptors.PrimitiveKind\nimport kotlinx.serialization.descriptors.PrimitiveSerialDescriptor\nimport kotlinx.serialization.encoding.Decoder\nimport kotlinx.serialization.encoding.Encoder\nimport android.net.Uri as AndroidUri\n\n@Suppress(\"UnusedReceiverParameter\")\ninternal fun Screen.isBetaFeature(): Boolean = false\n\ninternal fun Screen.simpleName(): String = when (this) {\n    is ApngTools -> \"APNG_Tools\"\n    is Cipher -> \"Cipher\"\n    is Compare -> \"Compare\"\n    is Crop -> \"Crop\"\n    is DeleteExif -> \"Delete_Exif\"\n    is Draw -> \"Draw\"\n    is EasterEgg -> \"Easter_Egg\"\n    is EraseBackground -> \"Erase_Background\"\n    is Filter -> \"Filter\"\n    is PaletteTools -> \"Palette_Tools\"\n    is GifTools -> \"GIF_Tools\"\n    is GradientMaker -> \"Gradient_Maker\"\n    is ImagePreview -> \"Image_Preview\"\n    is ImageStitching -> \"Image_Stitching\"\n    is JxlTools -> \"JXL_Tools\"\n    is LimitResize -> \"Limit_Resize\"\n    is LoadNetImage -> \"Load_Net_Image\"\n    is Main -> \"Main\"\n    is PdfTools -> \"PDF_Tools\"\n    is PickColorFromImage -> \"Pick_Color_From_Image\"\n    is RecognizeText -> \"Recognize_Text\"\n    is ResizeAndConvert -> \"Resize_And_Convert\"\n    is WeightResize -> \"Resize_By_Bytes\"\n    is Settings -> \"Settings\"\n    is SingleEdit -> \"Single_Edit\"\n    is Watermarking -> \"Watermarking\"\n    is Zip -> \"Zip\"\n    is SvgMaker -> \"Svg\"\n    is FormatConversion -> \"Convert\"\n    is DocumentScanner -> \"Document_Scanner\"\n    is ScanQrCode -> \"QR_Code\"\n    is ImageStacking -> \"Image_Stacking\"\n    is ImageSplitting -> \"Image_Splitting\"\n    is ColorTools -> \"Color_Tools\"\n    is WebpTools -> \"WEBP_Tools\"\n    is NoiseGeneration -> \"Noise_Generation\"\n    is CollageMaker -> \"Collage_Maker\"\n    is LibrariesInfo -> \"Libraries_Info\"\n    is MarkupLayers -> \"Markup_Layers\"\n    is Base64Tools -> \"Base64_Tools\"\n    is ChecksumTools -> \"Checksum_Tools\"\n    is MeshGradients -> \"Mesh_Gradients\"\n    is EditExif -> \"Edit_EXIF\"\n    is ImageCutter -> \"Image_Cutting\"\n    is AudioCoverExtractor -> \"Audio_Cover_Extractor\"\n    is LibraryDetails -> \"Library_Details\"\n    is WallpapersExport -> \"Wallpapers_Export\"\n    is AsciiArt -> \"Ascii_Art\"\n    is AiTools -> \"Ai_Tools\"\n    is ColorLibrary -> \"ColorLibrary\"\n    is PdfTools.Merge -> \"PdfTools_Merge\"\n    is PdfTools.Split -> \"PdfTools_Split\"\n    is PdfTools.Rotate -> \"PdfTools_Rotate\"\n    is PdfTools.Rearrange -> \"PdfTools_Rearrange\"\n    is PdfTools.PageNumbers -> \"PdfTools_PageNumbers\"\n    is PdfTools.OCR -> \"PdfTools_OCR\"\n    is PdfTools.Watermark -> \"PdfTools_Watermark\"\n    is PdfTools.Signature -> \"PdfTools_Signature\"\n    is PdfTools.Protect -> \"PdfTools_Protect\"\n    is PdfTools.Unlock -> \"PdfTools_Unlock\"\n    is PdfTools.Compress -> \"PdfTools_Compress\"\n    is PdfTools.Grayscale -> \"PdfTools_Grayscale\"\n    is PdfTools.Repair -> \"PdfTools_Repair\"\n    is PdfTools.Metadata -> \"PdfTools_Metadata\"\n    is PdfTools.RemovePages -> \"PdfTools_RemovePages\"\n    is PdfTools.Crop -> \"PdfTools_Crop\"\n    is PdfTools.Flatten -> \"PdfTools_Flatten\"\n    is PdfTools.ExtractImages -> \"PdfTools_ExtractImages\"\n    is PdfTools.ZipConvert -> \"PdfTools_ZipConvert\"\n    is PdfTools.Print -> \"PdfTools_Print\"\n    is PdfTools.Preview -> \"PdfTools_Preview\"\n    is PdfTools.ImagesToPdf -> \"PdfTools_ImagesToPdf\"\n    is PdfTools.ExtractPages -> \"PdfTools_ExtractPages\"\n    is PdfTools.RemoveAnnotations -> \"PdfTools_RemoveAnnotations\"\n}\n\ninternal fun Screen.icon(): ImageVector? = when (this) {\n    is EasterEgg,\n    is Main,\n    is Settings,\n    is LibrariesInfo,\n    is MeshGradients,\n    is LibraryDetails -> null\n\n    is SingleEdit -> Icons.Outlined.ImageEdit\n    is ApngTools -> Icons.Outlined.ApngBox\n    is Cipher -> Icons.Outlined.Encrypted\n    is Compare -> Icons.Outlined.Compare\n    is Crop -> Icons.Rounded.CropSmall\n    is DeleteExif -> Icons.Outlined.Exif\n    is Draw -> Icons.Outlined.Draw\n    is EraseBackground -> Icons.Rounded.Eraser\n    is Filter -> Icons.Outlined.AutoFixHigh\n    is PaletteTools -> Icons.Outlined.PaletteSwatch\n    is GifTools -> Icons.Outlined.GifBox\n    is GradientMaker -> Icons.Outlined.Gradient\n    is ImagePreview -> Icons.Outlined.Landscape\n    is ImageStitching -> Icons.Rounded.ImageCombine\n    is JxlTools -> Icons.Filled.Jxl\n    is LimitResize -> Icons.Outlined.ImageResize\n    is LoadNetImage -> Icons.Outlined.ImageDownload\n    is PdfTools -> Icons.Outlined.Pdf\n    is PickColorFromImage -> Icons.Outlined.Eyedropper\n    is RecognizeText -> Icons.Outlined.TextSearch\n    is ResizeAndConvert -> Icons.Outlined.MultipleImageEdit\n    is WeightResize -> Icons.Outlined.ImageWeight\n    is Watermarking -> Icons.Outlined.Watermark\n    is Zip -> Icons.Outlined.FolderZip\n    is SvgMaker -> Icons.Outlined.VectorPolyline\n    is FormatConversion -> Icons.Outlined.ImageConvert\n    is DocumentScanner -> Icons.Outlined.DocumentScanner\n    is ScanQrCode -> Icons.Outlined.QrCode\n    is ImageStacking -> Icons.Outlined.ImageOverlay\n    is ImageSplitting -> Icons.Outlined.SplitAlt\n    is ColorTools -> Icons.Outlined.ColorLens\n    is WebpTools -> Icons.Outlined.WebpBox\n    is NoiseGeneration -> Icons.Outlined.NoiseAlt\n    is CollageMaker -> Icons.Outlined.Collage\n    is MarkupLayers -> Icons.Outlined.Stacks\n    is Base64Tools -> Icons.Outlined.Base64\n    is ChecksumTools -> Icons.Rounded.Tag\n    is EditExif -> Icons.Outlined.ExifEdit\n    is ImageCutter -> Icons.Outlined.ScissorsSmall\n    is AudioCoverExtractor -> Icons.Outlined.Album\n    is WallpapersExport -> Icons.Outlined.WallpaperAlt\n    is AsciiArt -> Icons.Outlined.Ascii\n    is AiTools -> Icons.Outlined.Neurology\n    is ColorLibrary -> Icons.Outlined.FormatPaintVariant\n    is PdfTools.Merge -> Icons.Rounded.ImageCombine\n    is PdfTools.Split -> Icons.Outlined.SplitAlt\n    is PdfTools.Rotate -> Icons.Outlined.Rotate90Cw\n    is PdfTools.Rearrange -> Icons.Outlined.SwapVerticalCircle\n    is PdfTools.PageNumbers -> Icons.Outlined.Counter\n    is PdfTools.OCR -> Icons.Outlined.FindInPage\n    is PdfTools.Watermark -> Icons.Outlined.Watermark\n    is PdfTools.Signature -> Icons.Outlined.Stylus\n    is PdfTools.Protect -> Icons.Outlined.ShieldLock\n    is PdfTools.Unlock -> Icons.Outlined.KeyVariant\n    is PdfTools.Compress -> Icons.Outlined.Bolt\n    is PdfTools.Grayscale -> Icons.Outlined.FilterBAndW\n    is PdfTools.Repair -> Icons.Outlined.Build\n    is PdfTools.Metadata -> Icons.Outlined.TagText\n    is PdfTools.RemovePages -> Icons.Outlined.DeleteSweep\n    is PdfTools.Crop -> Icons.Rounded.CropSmall\n    is PdfTools.Flatten -> Icons.Outlined.Panorama\n    is PdfTools.ExtractImages -> Icons.Outlined.Unarchive\n    is PdfTools.ZipConvert -> Icons.Outlined.FolderZip\n    is PdfTools.Print -> Icons.Outlined.Print\n    is PdfTools.Preview -> Icons.Outlined.Preview\n    is PdfTools.ImagesToPdf -> Icons.Outlined.Scanner\n    is PdfTools.ExtractPages -> Icons.Outlined.ArtTrack\n    is PdfTools.RemoveAnnotations -> Icons.Outlined.BubbleDelete\n}\n\ninternal fun Screen.twoToneIcon(): ImageVector? = when (this) {\n    is EasterEgg,\n    is Main,\n    is Settings,\n    is LibrariesInfo,\n    is MeshGradients,\n    is LibraryDetails -> null\n\n    is SingleEdit -> Icons.TwoTone.ImageEdit\n    is ApngTools -> Icons.TwoTone.ApngBox\n    is Cipher -> Icons.TwoTone.Encrypted\n    is Compare -> Icons.TwoTone.Compare\n    is Crop -> Icons.TwoTone.CropSmall\n    is DeleteExif -> Icons.TwoTone.Exif\n    is Draw -> Icons.TwoTone.Draw\n    is EraseBackground -> Icons.TwoTone.Eraser\n    is Filter -> Icons.TwoTone.AutoFixHigh\n    is PaletteTools -> Icons.TwoTone.PaletteSwatch\n    is GifTools -> Icons.TwoTone.GifBox\n    is GradientMaker -> Icons.TwoTone.Gradient\n    is ImagePreview -> Icons.TwoTone.Landscape\n    is ImageStitching -> Icons.TwoTone.ImageCombine\n    is JxlTools -> Icons.Filled.Jxl\n    is LimitResize -> Icons.TwoTone.ImageResize\n    is LoadNetImage -> Icons.TwoTone.ImageDownload\n    is PdfTools -> Icons.TwoTone.Pdf\n    is PickColorFromImage -> Icons.TwoTone.Eyedropper\n    is RecognizeText -> Icons.Outlined.TextSearch\n    is ResizeAndConvert -> Icons.TwoTone.MultipleImageEdit\n    is WeightResize -> Icons.TwoTone.ImageWeight\n    is Watermarking -> Icons.TwoTone.Watermark\n    is Zip -> Icons.TwoTone.FolderZip\n    is SvgMaker -> Icons.TwoTone.VectorPolyline\n    is FormatConversion -> Icons.TwoTone.ImageConvert\n    is DocumentScanner -> Icons.TwoTone.DocumentScanner\n    is ScanQrCode -> Icons.TwoTone.QrCode\n    is ImageStacking -> Icons.TwoTone.ImageOverlay\n    is ImageSplitting -> Icons.TwoTone.SplitAlt\n    is ColorTools -> Icons.TwoTone.ColorLens\n    is WebpTools -> Icons.TwoTone.WebpBox\n    is NoiseGeneration -> Icons.Outlined.NoiseAlt\n    is CollageMaker -> Icons.TwoTone.Collage\n    is MarkupLayers -> Icons.TwoTone.Stacks\n    is Base64Tools -> Icons.TwoTone.Base64\n    is ChecksumTools -> Icons.TwoTone.Tag\n    is EditExif -> Icons.TwoTone.ExifEdit\n    is ImageCutter -> Icons.TwoTone.ScissorsSmall\n    is AudioCoverExtractor -> Icons.TwoTone.Album\n    is WallpapersExport -> Icons.Outlined.WallpaperAlt\n    is AsciiArt -> Icons.Outlined.Ascii\n    is AiTools -> Icons.TwoTone.Neurology\n    is ColorLibrary -> Icons.TwoTone.FormatPaintVariant\n    is PdfTools.Merge -> Icons.TwoTone.ImageCombine\n    is PdfTools.Split -> Icons.TwoTone.SplitAlt\n    is PdfTools.Rotate -> Icons.TwoTone.Rotate90Cw\n    is PdfTools.Rearrange -> Icons.TwoTone.SwapVerticalCircle\n    is PdfTools.PageNumbers -> Icons.TwoTone.Counter\n    is PdfTools.OCR -> Icons.TwoTone.FindInPage\n    is PdfTools.Watermark -> Icons.TwoTone.Watermark\n    is PdfTools.Signature -> Icons.TwoTone.Stylus\n    is PdfTools.Protect -> Icons.TwoTone.ShieldLock\n    is PdfTools.Unlock -> Icons.TwoTone.KeyVariant\n    is PdfTools.Compress -> Icons.TwoTone.Bolt\n    is PdfTools.Grayscale -> Icons.TwoTone.FilterBAndW\n    is PdfTools.Repair -> Icons.TwoTone.Build\n    is PdfTools.Metadata -> Icons.TwoTone.TagText\n    is PdfTools.RemovePages -> Icons.TwoTone.DeleteSweep\n    is PdfTools.Crop -> Icons.TwoTone.CropSmall\n    is PdfTools.Flatten -> Icons.TwoTone.Panorama\n    is PdfTools.ExtractImages -> Icons.TwoTone.Unarchive\n    is PdfTools.ZipConvert -> Icons.TwoTone.FolderZip\n    is PdfTools.Print -> Icons.TwoTone.Print\n    is PdfTools.Preview -> Icons.TwoTone.Preview\n    is PdfTools.ImagesToPdf -> Icons.TwoTone.Scanner\n    is PdfTools.ExtractPages -> Icons.TwoTone.ArtTrack\n    is PdfTools.RemoveAnnotations -> Icons.TwoTone.BubbleDelete\n}\n\ninternal object UriSerializer : KSerializer<AndroidUri> {\n    override val descriptor = PrimitiveSerialDescriptor(\"Uri\", PrimitiveKind.STRING)\n\n    override fun deserialize(\n        decoder: Decoder\n    ): AndroidUri = decoder.decodeString().toUri()\n\n    override fun serialize(\n        encoder: Encoder,\n        value: AndroidUri\n    ) = encoder.encodeString(value.toString())\n}\n\ninternal typealias Uri = @Serializable(UriSerializer::class) AndroidUri\n\ninternal interface ScreenConstants {\n    val typedEntries: List<ScreenGroup>\n\n    val entries: List<Screen>\n\n    val FEATURES_COUNT: Int\n\n    companion object : ScreenConstants by ScreenConstantsImpl\n}\n\nprivate object ScreenConstantsImpl : ScreenConstants {\n    override val typedEntries by lazy {\n        listOf(\n            ScreenGroup(\n                entries = listOf(\n                    SingleEdit(),\n                    ResizeAndConvert(),\n                    FormatConversion(),\n                    Crop(),\n                    ImageCutter(),\n                    WeightResize(),\n                    LimitResize(),\n                    EditExif(),\n                    DeleteExif(),\n                ),\n                title = R.string.edit,\n                selectedIcon = Icons.Rounded.MiniEditLarge,\n                baseIcon = Icons.Outlined.MiniEditLarge\n            ),\n            ScreenGroup(\n                entries = listOf(\n                    Filter(),\n                    Draw(),\n                    EraseBackground(),\n                    MarkupLayers(),\n                    AiTools(),\n                    CollageMaker(),\n                    ImageStitching(),\n                    ImageStacking(),\n                    ImageSplitting(),\n                    Watermarking(),\n                    GradientMaker(),\n                    NoiseGeneration,\n                ),\n                title = R.string.create,\n                selectedIcon = Icons.Rounded.WandShine,\n                baseIcon = Icons.Outlined.WandShine\n            ),\n            ScreenGroup(\n                entries = listOf(\n                    PickColorFromImage(),\n                    RecognizeText(),\n                    Compare(),\n                    ImagePreview(),\n                    WallpapersExport,\n                    Base64Tools(),\n                    SvgMaker(),\n                    PaletteTools(),\n                    LoadNetImage(),\n                ),\n                title = R.string.image,\n                selectedIcon = Icons.Rounded.FileImage,\n                baseIcon = Icons.Outlined.FileImage\n            ),\n            ScreenGroup(\n                entries = listOf(\n                    PdfTools,\n                    DocumentScanner,\n                    ScanQrCode(),\n                    ColorTools,\n                    ColorLibrary,\n                    GifTools(),\n                    Cipher(),\n                    ChecksumTools(),\n                    Zip(),\n                    AsciiArt(),\n                    JxlTools(),\n                    ApngTools(),\n                    WebpTools(),\n                    AudioCoverExtractor()\n                ),\n                title = R.string.tools,\n                selectedIcon = Icons.Rounded.ServiceToolbox,\n                baseIcon = Icons.Outlined.ServiceToolbox\n            )\n        )\n    }\n\n    override val entries by lazy {\n        typedEntries.flatMap { it.entries }\n            .plus(PdfTools.options)\n            .distinctBy { it.id }\n            .sortedBy { it.id }\n    }\n\n    override val FEATURES_COUNT = 82 + PdfTools.options.size\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/painter/CenterCropPainter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.painter\n\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.clipRect\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.graphics.painter.Painter\n\nprivate class CenterCropPainter(\n    private val wrappedPainter: Painter\n) : Painter() {\n    override val intrinsicSize: Size\n        get() = wrappedPainter.intrinsicSize\n\n    override fun DrawScope.onDraw() {\n        val srcW = intrinsicSize.width\n        val srcH = intrinsicSize.height\n        val dstW = size.width\n        val dstH = size.height\n\n        val srcAspect = srcW / srcH\n        val dstAspect = dstW / dstH\n\n        val scale = if (srcAspect > dstAspect) {\n            dstH / srcH\n        } else {\n            dstW / srcW\n        }\n\n        val scaledW = (srcW * scale)\n        val scaledH = (srcH * scale)\n\n        val offsetX = (dstW - scaledW) / 2f\n        val offsetY = (dstH - scaledH) / 2f\n\n        clipRect {\n            translate(left = offsetX, top = offsetY) {\n                with(wrappedPainter) {\n                    draw(\n                        Size(scaledW, scaledH)\n                    )\n                }\n            }\n        }\n    }\n}\n\nfun Painter.centerCrop(): Painter = CenterCropPainter(this)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/painter/RoundCornersPainter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.painter\n\nimport androidx.compose.ui.geometry.CornerRadius\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.RoundRect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.clipPath\nimport androidx.compose.ui.graphics.painter.Painter\n\nprivate class RoundCornersPainter(\n    private val wrappedPainter: Painter,\n    private val cornerFactor: Float\n) : Painter() {\n\n    override val intrinsicSize: Size\n        get() = wrappedPainter.intrinsicSize\n\n    override fun DrawScope.onDraw() {\n        val cornerRadius = size.minDimension / 2f * cornerFactor.coerceIn(0f, 1f)\n        clipPath(\n            Path().apply {\n                addRoundRect(\n                    RoundRect(\n                        rect = Rect(Offset.Zero, size),\n                        cornerRadius = CornerRadius(cornerRadius, cornerRadius)\n                    )\n                )\n            }\n        ) {\n            with(wrappedPainter) {\n                draw(size)\n            }\n        }\n    }\n}\n\nfun Painter.roundCorners(size: Float): Painter = RoundCornersPainter(this, size)\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/permission/PermissionResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.permission\n\nclass PermissionResult {\n    var permissionStatus: HashMap<String, PermissionStatus> = hashMapOf()\n    var finalStatus: PermissionStatus = PermissionStatus.NOT_GIVEN\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/permission/PermissionStatus.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.permission\n\nenum class PermissionStatus {\n    ALLOWED,\n    NOT_GIVEN,\n    DENIED_PERMANENTLY\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/permission/PermissionUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.permission\n\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.PackageManager\nimport android.net.Uri\nimport android.provider.Settings\nimport androidx.core.content.ContextCompat\nimport androidx.datastore.preferences.core.Preferences\nimport androidx.datastore.preferences.core.edit\nimport androidx.datastore.preferences.core.intPreferencesKey\nimport androidx.datastore.preferences.preferencesDataStore\nimport kotlinx.coroutines.runBlocking\n\nobject PermissionUtils {\n\n    fun Context.checkPermissions(\n        permissions: List<String>\n    ): PermissionResult {\n\n        val permissionPreference = PermissionPreference(this)\n\n        val permissionResult = PermissionResult()\n\n        val permissionStatus: HashMap<String, PermissionStatus> = hashMapOf()\n\n        permissions.forEach { permission ->\n            permissionPreference.setPermissionRequested(permission)\n            if (hasPermissionAllowed(permission)) {\n                permissionPreference.setPermissionAllowed(permission)\n                permissionStatus[permission] = PermissionStatus.ALLOWED\n            } else {\n                val permissionRequestCount =\n                    permissionPreference.permissionRequestCount(permission)\n                when {\n                    permissionRequestCount > 2 -> {\n                        permissionStatus[permission] = PermissionStatus.DENIED_PERMANENTLY\n                    }\n\n                    else -> {\n                        permissionStatus[permission] = PermissionStatus.NOT_GIVEN\n                    }\n                }\n            }\n        }\n\n        permissionResult.permissionStatus = permissionStatus\n\n        val isAnyPermissionDeniedPermanently =\n            permissionStatus.values.any { it == PermissionStatus.DENIED_PERMANENTLY }\n\n        if (isAnyPermissionDeniedPermanently) {\n            permissionResult.finalStatus = PermissionStatus.DENIED_PERMANENTLY\n            return permissionResult\n        }\n\n        val isAnyPermissionNotGiven =\n            permissionStatus.values.any { it == PermissionStatus.NOT_GIVEN }\n\n        if (isAnyPermissionNotGiven) {\n            permissionResult.finalStatus = PermissionStatus.NOT_GIVEN\n            return permissionResult\n        }\n\n        permissionResult.finalStatus = PermissionStatus.ALLOWED\n        return permissionResult\n    }\n\n\n    fun Context.askUserToRequestPermissionExplicitly() {\n        val intent = Intent().apply {\n            action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS\n            data = Uri.fromParts(\"package\", packageName, null)\n        }\n        startActivity(intent)\n    }\n\n    fun Context.hasPermissionAllowed(permission: String): Boolean {\n        return ContextCompat.checkSelfPermission(\n            this,\n            permission\n        ) == PackageManager.PERMISSION_GRANTED\n    }\n\n    fun Context.setPermissionsAllowed(permissions: List<String>) {\n        permissions.forEach { permission ->\n            PermissionPreference(this).setPermissionAllowed(permission)\n        }\n    }\n\n}\n\n\nprivate val Context.dataStore by preferencesDataStore(\n    name = \"permissionPreference\"\n)\n\nprivate class PermissionPreference(private val context: Context) {\n\n    private fun <T> get(\n        key: Preferences.Key<T>,\n        default: T\n    ): T {\n        return runBlocking {\n            context.dataStore.edit {}[key] ?: default\n        }\n    }\n\n    fun permissionRequestCount(permission: String): Int {\n        return get(intPreferencesKey(permission), 0)\n    }\n\n    fun setPermissionRequested(permission: String) {\n        runBlocking {\n            context.dataStore.edit {\n                it[intPreferencesKey(permission)] = (it[intPreferencesKey(permission)] ?: 0) + 1\n            }\n        }\n    }\n\n    fun setPermissionAllowed(permission: String) {\n        runBlocking {\n            context.dataStore.edit {\n                it[intPreferencesKey(permission)] = 0\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/ImageToolboxCompositionLocals.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport androidx.compose.runtime.ProvidedValue\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalUriHandler\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalEditPresetsController\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberEditPresetsController\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeSurface\nimport com.t8rin.imagetoolbox.core.ui.utils.confetti.ConfettiHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LocalFilterPreviewModelProvider\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberFilterPreviewProvider\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberSafeUriHandler\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.rememberEnhancedHapticFeedback\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastHost\nimport kotlinx.coroutines.delay\n\n@Composable\nfun ImageToolboxCompositionLocals(\n    settingsState: UiSettingsState,\n    filterPreviewModel: ImageModel? = null,\n    canSetDynamicFilterPreview: Boolean = false,\n    currentScreen: Screen? = null,\n    content: @Composable BoxScope.() -> Unit\n) {\n    val editPresetsController = rememberEditPresetsController()\n    val customHapticFeedback = rememberEnhancedHapticFeedback(settingsState.hapticsStrength)\n    val screenSize = rememberScreenSize()\n    val previewProvider = filterPreviewModel?.let {\n        rememberFilterPreviewProvider(\n            preview = it,\n            canSetDynamicFilterPreview = canSetDynamicFilterPreview\n        )\n    }\n    val safeUriHandler = rememberSafeUriHandler()\n\n    val values = remember(\n        settingsState,\n        editPresetsController,\n        customHapticFeedback,\n        screenSize,\n        filterPreviewModel,\n        currentScreen,\n        safeUriHandler\n    ) {\n        derivedStateOf {\n            listOfNotNull(\n                LocalSettingsState provides settingsState,\n                LocalEditPresetsController provides editPresetsController,\n                LocalFilterPreviewModelProvider providesOrNull previewProvider,\n                LocalHapticFeedback provides customHapticFeedback,\n                LocalScreenSize provides screenSize,\n                LocalCurrentScreen provides currentScreen,\n                LocalUriHandler provides safeUriHandler\n            ).toTypedArray()\n        }\n    }\n\n    CompositionLocalProvider(\n        *values.value,\n        content = {\n            ImageToolboxThemeSurface {\n                content()\n\n                ConfettiHost()\n\n                ToastHost()\n            }\n        }\n    )\n}\n\nval LocalCurrentScreen =\n    compositionLocalOf<Screen?> { error(\"LocalCurrentScreen not present\") }\n\n@Composable\nfun currentScreenTwoToneIcon(\n    default: ImageVector\n): ImageVector {\n    val currentScreen = LocalCurrentScreen.current\n    val screenIcon = currentScreen?.twoToneIcon\n\n    var previous by rememberSaveable {\n        mutableStateOf(currentScreen?.simpleName)\n    }\n\n    var currentIcon by remember {\n        mutableStateOf(screenIcon ?: default)\n    }\n\n    LaunchedEffect(currentScreen) {\n        if (currentScreen?.simpleName != previous) delay(600)\n\n        previous = currentScreen?.simpleName\n        currentIcon = screenIcon ?: default\n    }\n\n    return currentIcon\n}\n\nprivate infix fun <T : Any> ProvidableCompositionLocal<T>.providesOrNull(\n    value: T?\n): ProvidedValue<T>? = if (value != null) provides(value) else null"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/LocalComponentActivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.LocalActivity\nimport androidx.compose.runtime.compositionLocalWithComputedDefaultOf\n\nval LocalComponentActivity =\n    compositionLocalWithComputedDefaultOf { LocalActivity.currentValue as ComponentActivity }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/LocalContainerShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.takeOrElse\n\nval LocalContainerShape = compositionLocalOf<Shape?> { null }\n\nval LocalContainerColor = compositionLocalOf<Color?> { null }\n\nval SafeLocalContainerColor\n    @Composable\n    get() = LocalContainerColor.current?.takeOrElse {\n        MaterialTheme.colorScheme.surfaceContainerLow\n    } ?: MaterialTheme.colorScheme.surfaceContainerLow\n\n@Composable\nfun ProvideContainerDefaults(\n    shape: Shape? = null,\n    color: Color? = null,\n    content: @Composable () -> Unit\n) = CompositionLocalProvider(\n    values = arrayOf(\n        LocalContainerShape provides shape,\n        LocalContainerColor provides color\n    ),\n    content = content\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/LocalKeepAliveService.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport androidx.compose.runtime.compositionLocalOf\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\n\nval LocalKeepAliveService = compositionLocalOf<KeepAliveService> { error(\"No KeepAlive\") }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/LocalMetadataProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport android.net.Uri\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.MetadataProvider\n\nval LocalMetadataProvider =\n    compositionLocalOf<MetadataProvider> { error(\"MetadataProvider not registered\") }\n\n@Composable\nfun rememberImageMetadataAsState(imageUri: Uri): State<Metadata?> {\n    val provider = LocalMetadataProvider.current\n    val metadata = remember {\n        mutableStateOf<Metadata?>(null)\n    }\n    LaunchedEffect(imageUri) {\n        metadata.value = provider.readMetadata(imageUri.toString())\n    }\n\n    return metadata\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/LocalResourceManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport androidx.compose.runtime.compositionLocalOf\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\n\nval LocalResourceManager = compositionLocalOf<ResourceManager> { error(\"ResourceManager\") }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/LocalScreenSize.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.unit.Dp\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.compose.LocalLifecycleOwner\nimport com.t8rin.dynamic.theme.observeAsState\n\nval LocalScreenSize = compositionLocalOf<ScreenSize> { error(\"ScreenSize not present\") }\n\n@ConsistentCopyVisibility\ndata class ScreenSize internal constructor(\n    val width: Dp,\n    val height: Dp,\n    val widthPx: Int,\n    val heightPx: Int\n)\n\n@Composable\nfun rememberScreenSize(): ScreenSize {\n    val windowInfo = LocalWindowInfo.current\n\n    return remember(windowInfo) {\n        derivedStateOf {\n            windowInfo.run {\n                ScreenSize(\n                    width = containerDpSize.width,\n                    height = containerDpSize.height,\n                    widthPx = containerSize.width,\n                    heightPx = containerSize.height\n                )\n            }\n        }\n    }.value\n}\n\n@Composable\nfun rememberCurrentLifecycleEvent(): Lifecycle.Event =\n    LocalLifecycleOwner.current.lifecycle.observeAsState().value"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/provider/LocalWindowSizeClass.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.provider\n\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.setContent\nimport androidx.compose.material3.windowsizeclass.WindowSizeClass\nimport androidx.compose.material3.windowsizeclass.calculateWindowSizeClass\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.compositionLocalOf\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\n\nval LocalWindowSizeClass = compositionLocalOf<WindowSizeClass> { error(\"SizeClass not present\") }\n\nfun ComponentActivity.setContentWithWindowSizeClass(\n    content: @Composable () -> Unit\n) = setContent {\n    LocalWindowSizeClass.ProvidesValue(\n        value = calculateWindowSizeClass(this),\n        content = content\n    )\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/state/ObjectSaverDelegate.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.state\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport com.t8rin.imagetoolbox.core.domain.saving.ObjectSaver\nimport com.t8rin.imagetoolbox.core.domain.utils.ReadWriteDelegate\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\nfun <O : Any> ObjectSaver.savable(\n    scope: CoroutineScope,\n    initial: O,\n    key: String = initial::class.simpleName.toString(),\n    delay: Long = 0,\n): ReadWriteDelegate<O> = ObjectSaverDelegate(\n    delay = delay,\n    saver = this,\n    scope = scope,\n    initial = initial,\n    key = key\n)\n\nprivate class ObjectSaverDelegate<O : Any>(\n    delay: Long,\n    private val saver: ObjectSaver,\n    private val scope: CoroutineScope,\n    initial: O,\n    private val key: String\n) : ReadWriteDelegate<O> {\n\n    private var value: O by mutableStateOf(initial)\n\n    init {\n        scope.launch {\n            if (delay > 0) delay(delay)\n            value = saver.restoreObject(\n                key = key,\n                kClass = initial::class\n            ) ?: initial\n        }\n    }\n\n    override fun set(value: O) {\n        this.value = value\n        scope.launch {\n            saver.saveObject(\n                key = key,\n                value = value\n            )\n        }\n    }\n\n    override fun get(): O = value\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/utils/state/Update.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.state\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\n\ninline fun <T> MutableState<T>.update(\n    transform: (T) -> T\n): T = run {\n    transform(this.value).also {\n        this.value = it\n    }\n}\n\ninline fun <T : Any> MutableState<T?>.updateNotNull(\n    transform: (T) -> T\n): T? = run {\n    this.value?.let { nonNull ->\n        transform(nonNull).also {\n            this.value = it\n        }\n    } ?: this.value\n}\n\ninline fun <T> MutableState<T>.update(\n    onValueChanged: () -> Unit,\n    transform: (T) -> T\n): T = run {\n    transform(this.value).also {\n        if (this.value != it) onValueChanged()\n        this.value = it\n    }\n}\n\ninline fun <T> MutableState<T>.updateIf(\n    predicate: (T) -> Boolean,\n    transform: (T) -> T\n): MutableState<T> = apply {\n    if (predicate(this.value)) {\n        this.value = transform(this.value)\n    }\n}\n\n@Composable\nfun <T> derivedValueOf(\n    vararg keys: Any?,\n    calculation: () -> T\n): T = remember(keys) {\n    derivedStateOf(calculation)\n}.value\n\n\n//fun <T> T.asFun(): Function1<T, T> {\n//    val value = this\n//    return { value }\n//}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/AdaptiveBottomScaffoldLayoutScreen.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.BottomSheetScaffold\nimport androidx.compose.material3.BottomSheetScaffoldState\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.rememberBottomSheetScaffoldState\nimport androidx.compose.material3.rememberStandardBottomSheetState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.fancySlideTransition\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitBackHandler\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.onSwipeDown\nimport kotlinx.coroutines.launch\n\n@Composable\nfun AdaptiveBottomScaffoldLayoutScreen(\n    title: @Composable () -> Unit,\n    onGoBack: () -> Unit,\n    shouldDisableBackHandler: Boolean,\n    actions: @Composable RowScope.(BottomSheetScaffoldState) -> Unit,\n    modifier: Modifier = Modifier,\n    topAppBarPersistentActions: @Composable RowScope.(BottomSheetScaffoldState) -> Unit = {},\n    mainContent: @Composable () -> Unit,\n    mainContentWeight: Float = 0.5f,\n    controls: @Composable ColumnScope.(BottomSheetScaffoldState) -> Unit,\n    buttons: @Composable (actions: @Composable RowScope.() -> Unit) -> Unit,\n    noDataControls: @Composable () -> Unit = {},\n    canShowScreenData: Boolean,\n    showActionsInTopAppBar: Boolean = true,\n    collapseTopAppBarWhenHaveData: Boolean = true,\n    autoClearFocus: Boolean = true,\n    enableNoDataScroll: Boolean = true\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    val screenWidthPx = LocalScreenSize.current.widthPx\n\n    val settingsState = LocalSettingsState.current\n\n    val scrollBehavior = if (collapseTopAppBarWhenHaveData && canShowScreenData) null\n    else TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n    val scaffoldState = rememberBottomSheetScaffoldState(\n        bottomSheetState = rememberStandardBottomSheetState(\n            confirmValueChange = {\n                when (it) {\n                    SheetValue.Hidden -> false\n                    else -> true\n                }\n            }\n        )\n    )\n\n    val focus = LocalFocusManager.current\n\n    LaunchedEffect(scaffoldState.bottomSheetState.currentValue) {\n        if (scaffoldState.bottomSheetState.currentValue != SheetValue.Expanded) {\n            focus.clearFocus()\n        }\n    }\n\n    val content: @Composable (PaddingValues) -> Unit = { paddingValues ->\n        Box(\n            Modifier\n                .fillMaxSize()\n                .padding(paddingValues)\n                .then(\n                    if (scrollBehavior != null) {\n                        Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)\n                    } else Modifier\n                )\n        ) {\n            Scaffold(\n                topBar = {\n                    EnhancedTopAppBar(\n                        type = if (collapseTopAppBarWhenHaveData && canShowScreenData) EnhancedTopAppBarType.Normal\n                        else EnhancedTopAppBarType.Large,\n                        scrollBehavior = scrollBehavior,\n                        title = title,\n                        navigationIcon = {\n                            EnhancedIconButton(\n                                onClick = onGoBack\n                            ) {\n                                Icon(\n                                    imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                    contentDescription = stringResource(R.string.exit)\n                                )\n                            }\n                        },\n                        actions = {\n                            if (!isPortrait && canShowScreenData && showActionsInTopAppBar) actions(\n                                scaffoldState\n                            )\n                            topAppBarPersistentActions(scaffoldState)\n                        },\n                    )\n                },\n                contentWindowInsets = WindowInsets()\n            ) { contentPadding ->\n                AnimatedContent(\n                    targetState = canShowScreenData,\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .padding(contentPadding),\n                    transitionSpec = {\n                        fancySlideTransition(\n                            isForward = targetState,\n                            screenWidthPx = screenWidthPx\n                        )\n                    }\n                ) { canShowScreenData ->\n                    if (canShowScreenData) {\n                        if (isPortrait) {\n                            mainContent()\n                        } else {\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically\n                            ) {\n                                Box(\n                                    Modifier\n                                        .zIndex(-100f)\n                                        .container(shape = RectangleShape, resultPadding = 0.dp)\n                                        .weight(0.8f)\n                                ) {\n                                    mainContent()\n                                }\n                                val scrollState = rememberScrollState()\n                                Column(\n                                    Modifier\n                                        .weight(mainContentWeight)\n                                        .enhancedVerticalScroll(scrollState)\n                                ) {\n                                    controls(scaffoldState)\n                                }\n                                buttons {\n                                    actions(scaffoldState)\n                                }\n                            }\n                        }\n                    } else {\n                        Column(\n                            modifier = Modifier\n                                .then(\n                                    if (enableNoDataScroll) {\n                                        val scrollState = rememberScrollState()\n                                        Modifier\n                                            .fillMaxSize()\n                                            .enhancedVerticalScroll(scrollState)\n                                            .padding(\n                                                bottom = 88.dp,\n                                                top = 20.dp,\n                                                start = 20.dp,\n                                                end = 20.dp\n                                            )\n                                            .windowInsetsPadding(\n                                                WindowInsets.navigationBars.union(\n                                                    WindowInsets.displayCutout.only(\n                                                        WindowInsetsSides.Horizontal\n                                                    )\n                                                )\n                                            )\n                                    } else Modifier\n                                ),\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            noDataControls()\n                        }\n                    }\n                }\n            }\n\n            if (!canShowScreenData) {\n                Box(\n                    modifier = Modifier.align(settingsState.fabAlignment)\n                ) {\n                    buttons {\n                        actions(scaffoldState)\n                    }\n                }\n            }\n        }\n    }\n\n    Surface(\n        color = MaterialTheme.colorScheme.background,\n        modifier = modifier.clearFocusOnTap(autoClearFocus)\n    ) {\n        AnimatedContent(\n            targetState = isPortrait && canShowScreenData,\n            transitionSpec = {\n                fancySlideTransition(\n                    isForward = targetState,\n                    screenWidthPx = screenWidthPx\n                )\n            },\n            modifier = Modifier.fillMaxSize()\n        ) { useScaffold ->\n            if (useScaffold) {\n                val screenHeight = LocalScreenSize.current.height\n                val sheetSwipeEnabled =\n                    scaffoldState.bottomSheetState.currentValue == SheetValue.PartiallyExpanded\n                            && !scaffoldState.bottomSheetState.isAnimationRunning\n\n                BottomSheetScaffold(\n                    modifier = Modifier.fillMaxSize(),\n                    scaffoldState = scaffoldState,\n                    sheetPeekHeight = 80.dp + WindowInsets.navigationBars.asPaddingValues()\n                        .calculateBottomPadding(),\n                    sheetDragHandle = null,\n                    sheetShape = RectangleShape,\n                    sheetSwipeEnabled = sheetSwipeEnabled,\n                    sheetContent = {\n                        Scaffold(\n                            modifier = Modifier\n                                .heightIn(max = screenHeight * 0.7f)\n                                .clearFocusOnTap(),\n                            topBar = {\n                                val scope = rememberCoroutineScope()\n                                Box(\n                                    modifier = Modifier.onSwipeDown(!sheetSwipeEnabled) {\n                                        scope.launch {\n                                            scaffoldState.bottomSheetState.partialExpand()\n                                        }\n                                    }\n                                ) {\n                                    buttons {\n                                        actions(scaffoldState)\n                                    }\n                                }\n                            },\n                            contentWindowInsets = WindowInsets()\n                        ) { contentPadding ->\n                            ProvideContainerDefaults(\n                                color = EnhancedBottomSheetDefaults.contentContainerColor\n                            ) {\n                                val scrollState = rememberScrollState()\n                                Column(\n                                    modifier = Modifier\n                                        .enhancedVerticalScroll(scrollState)\n                                        .padding(contentPadding)\n                                ) {\n                                    controls(scaffoldState)\n                                }\n                            }\n                        }\n                    },\n                    content = content\n                )\n            } else {\n                Box(\n                    modifier = Modifier.fillMaxSize()\n                ) {\n                    content(PaddingValues())\n                }\n            }\n        }\n    }\n\n    ExitBackHandler(\n        enabled = !shouldDisableBackHandler,\n        onBack = onGoBack\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/AdaptiveLayoutScreen.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.ime\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.rememberTopAppBarState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.fancySlideTransition\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitBackHandler\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.imageStickyHeader\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.isExpanded\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberAvailableHeight\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberImageState\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun AdaptiveLayoutScreen(\n    title: @Composable () -> Unit,\n    onGoBack: () -> Unit,\n    shouldDisableBackHandler: Boolean,\n    actions: @Composable RowScope.() -> Unit,\n    topAppBarPersistentActions: @Composable RowScope.() -> Unit = {},\n    imagePreview: @Composable () -> Unit,\n    controls: (@Composable ColumnScope.(LazyListState) -> Unit)?,\n    buttons: @Composable (actions: @Composable RowScope.() -> Unit) -> Unit,\n    noDataControls: @Composable () -> Unit = {},\n    canShowScreenData: Boolean,\n    forceImagePreviewToMax: Boolean = false,\n    contentPadding: Dp = 20.dp,\n    showImagePreviewAsStickyHeader: Boolean = true,\n    autoClearFocus: Boolean = true,\n    placeImagePreview: Boolean = true,\n    useRegularStickyHeader: Boolean = false,\n    addHorizontalCutoutPaddingIfNoPreview: Boolean = true,\n    showActionsInTopAppBar: Boolean = true,\n    underTopAppBarContent: (@Composable ColumnScope.() -> Unit)? = null,\n    insetsForNoData: WindowInsets = WindowInsets.navigationBars.union(\n        WindowInsets.displayCutout.only(\n            WindowInsetsSides.Horizontal\n        )\n    ),\n    listState: LazyListState = rememberLazyListState(),\n    placeControlsSeparately: Boolean = false,\n    portraitTopPadding: Dp = 0.dp\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    val settingsState = LocalSettingsState.current\n\n    var imageState by rememberImageState()\n\n    val topAppBarState = rememberTopAppBarState()\n    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(\n        state = topAppBarState, canScroll = { !imageState.isExpanded() && !forceImagePreviewToMax }\n    )\n\n    LaunchedEffect(imageState, forceImagePreviewToMax) {\n        if (imageState.isExpanded() || forceImagePreviewToMax) {\n            while (topAppBarState.heightOffset > topAppBarState.heightOffsetLimit) {\n                topAppBarState.heightOffset -= 5f\n                delay(1)\n            }\n        }\n    }\n\n    Surface(\n        color = MaterialTheme.colorScheme.background,\n        modifier = Modifier.clearFocusOnTap(autoClearFocus)\n    ) {\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) {\n            Scaffold(\n                modifier = Modifier.fillMaxSize(),\n                topBar = {\n                    Column {\n                        EnhancedTopAppBar(\n                            type = EnhancedTopAppBarType.Large,\n                            scrollBehavior = scrollBehavior,\n                            title = title,\n                            drawHorizontalStroke = underTopAppBarContent == null,\n                            navigationIcon = {\n                                EnhancedIconButton(\n                                    onClick = onGoBack\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit)\n                                    )\n                                }\n                            },\n                            actions = {\n                                if (!isPortrait && canShowScreenData && showActionsInTopAppBar) actions()\n                                topAppBarPersistentActions()\n                            }\n                        )\n                        underTopAppBarContent?.invoke(this)\n                    }\n                },\n                contentWindowInsets = WindowInsets()\n            ) { scaffoldPadding ->\n                val screenWidthPx = LocalScreenSize.current.widthPx\n                AnimatedContent(\n                    targetState = canShowScreenData,\n                    transitionSpec = {\n                        fancySlideTransition(\n                            isForward = targetState,\n                            screenWidthPx = screenWidthPx\n                        )\n                    },\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .padding(scaffoldPadding)\n                ) { canShowScreenData ->\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.Center,\n                    ) {\n                        val direction = LocalLayoutDirection.current\n                        if (!isPortrait && canShowScreenData && placeImagePreview) {\n                            Box(\n                                modifier = Modifier\n                                    .then(\n                                        if (controls != null) {\n                                            Modifier.container(\n                                                shape = RectangleShape,\n                                                color = MaterialTheme.colorScheme.surfaceContainerLow\n                                            )\n                                        } else Modifier\n                                    )\n                                    .fillMaxHeight()\n                                    .padding(\n                                        start = WindowInsets\n                                            .displayCutout\n                                            .asPaddingValues()\n                                            .calculateStartPadding(direction)\n                                    )\n                                    .weight(1.2f)\n                                    .padding(20.dp),\n                                contentAlignment = Alignment.Center\n                            ) {\n                                imagePreview()\n                            }\n                        }\n\n                        if (placeControlsSeparately && controls != null && canShowScreenData) {\n                            Column(\n                                modifier = Modifier\n                                    .weight(1f)\n                                    .fillMaxHeight()\n                                    .clipToBounds()\n                            ) {\n                                controls(listState)\n                            }\n                        } else {\n                            val internalHeight = rememberAvailableHeight(\n                                imageState = imageState,\n                                expanded = forceImagePreviewToMax\n                            )\n                            val cutout =\n                                if (!placeImagePreview && addHorizontalCutoutPaddingIfNoPreview) {\n                                    WindowInsets\n                                        .displayCutout\n                                        .asPaddingValues()\n                                        .calculateStartPadding(direction)\n                                } else 0.dp\n\n                            var isScrolled by rememberSaveable(canShowScreenData) {\n                                mutableStateOf(false)\n                            }\n                            val scope = rememberCoroutineScope {\n                                Dispatchers.Main.immediate\n                            }\n\n                            LazyColumn(\n                                state = listState,\n                                contentPadding = PaddingValues(\n                                    bottom = WindowInsets\n                                        .navigationBars\n                                        .union(WindowInsets.ime)\n                                        .asPaddingValues()\n                                        .calculateBottomPadding() + (if (!isPortrait && canShowScreenData) contentPadding else 100.dp),\n                                    top = if (!canShowScreenData || !isPortrait) contentPadding else portraitTopPadding,\n                                    start = contentPadding + cutout,\n                                    end = contentPadding\n                                ),\n                                modifier = Modifier\n                                    .weight(\n                                        if (controls == null) 0.01f\n                                        else 1f\n                                    )\n                                    .fillMaxHeight()\n                                    .clipToBounds(),\n                                flingBehavior = enhancedFlingBehavior()\n                            ) {\n                                if (useRegularStickyHeader && isPortrait && canShowScreenData && showImagePreviewAsStickyHeader && placeImagePreview) {\n                                    stickyHeader {\n                                        imagePreview()\n                                    }\n                                } else {\n                                    imageStickyHeader(\n                                        visible = isPortrait && canShowScreenData && showImagePreviewAsStickyHeader && placeImagePreview,\n                                        internalHeight = internalHeight,\n                                        imageState = imageState,\n                                        onStateChange = { imageState = it },\n                                        imageBlock = imagePreview,\n                                        onGloballyPositioned = {\n                                            if (!isScrolled) {\n                                                scope.launch {\n                                                    delay(200)\n                                                    listState.animateScrollToItem(0)\n                                                    isScrolled = true\n                                                }\n                                            }\n                                        }\n                                    )\n                                }\n                                item {\n                                    Column(\n                                        modifier = Modifier.fillMaxSize(),\n                                        verticalArrangement = Arrangement.Center,\n                                        horizontalAlignment = Alignment.CenterHorizontally\n                                    ) {\n                                        if (canShowScreenData) {\n                                            AnimatedVisibility(\n                                                visible = !showImagePreviewAsStickyHeader && isPortrait && placeImagePreview\n                                            ) {\n                                                imagePreview()\n                                            }\n                                            if (controls != null) controls(listState)\n                                        } else {\n                                            Box(\n                                                modifier = Modifier.windowInsetsPadding(\n                                                    insetsForNoData\n                                                )\n                                            ) {\n                                                noDataControls()\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        AnimatedVisibility(!isPortrait && canShowScreenData) {\n                            buttons(actions)\n                        }\n                    }\n                }\n            }\n\n            AnimatedVisibility(\n                visible = isPortrait || !canShowScreenData,\n                modifier = Modifier.align(settingsState.fabAlignment)\n            ) {\n                buttons(actions)\n            }\n\n            ExitBackHandler(\n                enabled = !shouldDisableBackHandler,\n                onBack = onGoBack\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/BottomButtonsBlock.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.consumeWindowInsets\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Save\nimport androidx.compose.material3.BottomAppBar\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButtonType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.ProvideFABType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\n\n@Composable\nfun BottomButtonsBlock(\n    isNoData: Boolean,\n    onSecondaryButtonClick: () -> Unit,\n    onSecondaryButtonLongClick: (() -> Unit)? = null,\n    secondaryButtonIcon: ImageVector = Icons.Rounded.AddPhotoAlt,\n    secondaryButtonText: String = stringResource(R.string.pick_image_alt),\n    onPrimaryButtonClick: () -> Unit,\n    onPrimaryButtonLongClick: (() -> Unit)? = null,\n    primaryButtonIcon: ImageVector = Icons.Rounded.Save,\n    primaryButtonText: String = \"\",\n    isPrimaryButtonVisible: Boolean = true,\n    isSecondaryButtonVisible: Boolean = true,\n    showNullDataButtonAsContainer: Boolean = false,\n    middleFab: (@Composable ColumnScope.() -> Unit)? = null,\n    actions: @Composable RowScope.() -> Unit,\n    isPrimaryButtonEnabled: Boolean = true,\n    showMiddleFabInRow: Boolean = false,\n    isScreenHaveNoDataContent: Boolean = false,\n    primaryButtonContainerColor: Color = MaterialTheme.colorScheme.primaryContainer,\n    primaryButtonContentColor: Color = contentColorFor(primaryButtonContainerColor),\n    enableHorizontalStroke: Boolean = true\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    val spacing = 8.dp\n\n    AnimatedContent(\n        targetState = Triple(isNoData, isPortrait, isScreenHaveNoDataContent),\n        transitionSpec = {\n            fadeIn() + slideInVertically { it / 2 } togetherWith fadeOut() + slideOutVertically { it / 2 }\n        }\n    ) { (isEmptyState, portrait, isHaveNoDataContent) ->\n        if (isEmptyState) {\n            val cutout = WindowInsets.displayCutout.only(\n                WindowInsetsSides.Horizontal\n            )\n\n            val button = @Composable {\n                Row(\n                    modifier = Modifier\n                        .windowInsetsPadding(\n                            WindowInsets.navigationBars.union(cutout)\n                        )\n                        .padding(16.dp),\n                    horizontalArrangement = Arrangement.spacedBy(spacing),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    val middle = @Composable {\n                        if (showMiddleFabInRow && middleFab != null) {\n                            ProvideFABType(EnhancedFloatingActionButtonType.SecondaryHorizontal) {\n                                Column(\n                                    content = middleFab\n                                )\n                            }\n                        }\n                    }\n\n                    if (!isPrimaryButtonVisible) middle()\n\n                    EnhancedFloatingActionButton(\n                        onClick = onSecondaryButtonClick,\n                        onLongClick = onSecondaryButtonLongClick,\n                        content = {\n                            Spacer(Modifier.width(16.dp))\n                            Icon(\n                                imageVector = secondaryButtonIcon,\n                                contentDescription = null\n                            )\n                            Spacer(Modifier.width(16.dp))\n                            Text(secondaryButtonText)\n                            Spacer(Modifier.width(16.dp))\n                        }\n                    )\n\n                    if (isPrimaryButtonVisible) middle()\n                }\n            }\n            if (showNullDataButtonAsContainer) {\n                if (!isPortrait && isHaveNoDataContent) {\n                    Column(\n                        modifier = Modifier\n                            .fillMaxHeight()\n                            .background(\n                                MaterialTheme.colorScheme.surfaceContainerLow\n                            )\n                            .consumeWindowInsets(cutout.only(WindowInsetsSides.Start)),\n                        verticalArrangement = Arrangement.Center,\n                        horizontalAlignment = Alignment.CenterHorizontally\n                    ) {\n                        button()\n                    }\n                } else {\n                    Row(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .drawHorizontalStroke(\n                                top = true,\n                                enabled = enableHorizontalStroke\n                            )\n                            .background(\n                                MaterialTheme.colorScheme.surfaceContainer\n                            ),\n                        horizontalArrangement = Arrangement.Center,\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        button()\n                    }\n                }\n            } else {\n                button()\n            }\n        } else if (portrait) {\n            BottomAppBar(\n                modifier = Modifier.drawHorizontalStroke(\n                    top = true,\n                    enabled = enableHorizontalStroke\n                ),\n                actions = actions,\n                floatingActionButton = {\n                    Row {\n                        val middle = @Composable {\n                            AnimatedVisibility(visible = showMiddleFabInRow) {\n                                middleFab?.let {\n                                    ProvideFABType(EnhancedFloatingActionButtonType.SecondaryHorizontal) {\n                                        Column(\n                                            modifier = Modifier.padding(end = spacing),\n                                            content = { it() }\n                                        )\n                                    }\n                                }\n                            }\n                        }\n                        if (!isPrimaryButtonVisible) middle()\n\n                        AnimatedVisibility(visible = isSecondaryButtonVisible) {\n                            EnhancedFloatingActionButton(\n                                onClick = onSecondaryButtonClick,\n                                onLongClick = onSecondaryButtonLongClick,\n                                containerColor = takeColorFromScheme {\n                                    if (isPrimaryButtonVisible) tertiaryContainer\n                                    else primaryContainer\n                                },\n                                type = if (isPrimaryButtonVisible) {\n                                    EnhancedFloatingActionButtonType.SecondaryHorizontal\n                                } else {\n                                    EnhancedFloatingActionButtonType.Primary\n                                },\n                                modifier = Modifier.padding(end = spacing)\n                            ) {\n                                Icon(\n                                    imageVector = secondaryButtonIcon,\n                                    contentDescription = null\n                                )\n                            }\n                        }\n\n                        if (isPrimaryButtonVisible) middle()\n\n                        AnimatedVisibility(visible = isPrimaryButtonVisible) {\n                            EnhancedFloatingActionButton(\n                                onClick = onPrimaryButtonClick.takeIf { isPrimaryButtonEnabled },\n                                onLongClick = onPrimaryButtonLongClick.takeIf { isPrimaryButtonEnabled },\n                                interactionSource = remember { MutableInteractionSource() }.takeIf { isPrimaryButtonEnabled },\n                                containerColor = takeColorFromScheme {\n                                    if (isPrimaryButtonEnabled) primaryButtonContainerColor\n                                    else surfaceContainerHighest\n                                },\n                                contentColor = takeColorFromScheme {\n                                    if (isPrimaryButtonEnabled) primaryButtonContentColor\n                                    else outline\n                                }\n                            ) {\n                                AnimatedContent(\n                                    targetState = primaryButtonIcon to primaryButtonText,\n                                    transitionSpec = { fadeIn() + scaleIn() togetherWith fadeOut() + scaleOut() }\n                                ) { (icon, text) ->\n                                    Row(\n                                        verticalAlignment = Alignment.CenterVertically,\n                                        horizontalArrangement = Arrangement.Center\n                                    ) {\n                                        if (text.isNotEmpty()) {\n                                            Spacer(Modifier.width(16.dp))\n                                        }\n                                        Icon(\n                                            imageVector = icon,\n                                            contentDescription = null\n                                        )\n                                        if (text.isNotEmpty()) {\n                                            Spacer(Modifier.width(16.dp))\n                                            Text(text)\n                                            Spacer(Modifier.width(16.dp))\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            )\n        } else {\n            val direction = LocalLayoutDirection.current\n            Column(\n                modifier = Modifier\n                    .fillMaxHeight()\n                    .container(\n                        shape = RectangleShape,\n                        color = MaterialTheme.colorScheme.surfaceContainerLow\n                    )\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(horizontal = 16.dp)\n                    .navigationBarsPadding()\n                    .padding(\n                        end = WindowInsets.displayCutout\n                            .asPaddingValues()\n                            .calculateEndPadding(direction)\n                    ),\n                verticalArrangement = Arrangement.Center,\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                val middle = @Composable {\n                    middleFab?.let {\n                        Spacer(Modifier.height(spacing))\n                        ProvideFABType(EnhancedFloatingActionButtonType.SecondaryVertical) {\n                            it()\n                        }\n                    }\n                }\n\n                Row { actions() }\n\n                if (!isPrimaryButtonVisible) middle()\n\n                Spacer(Modifier.height(spacing))\n\n                AnimatedVisibility(visible = isSecondaryButtonVisible) {\n                    EnhancedFloatingActionButton(\n                        onClick = onSecondaryButtonClick,\n                        onLongClick = onSecondaryButtonLongClick,\n                        containerColor = takeColorFromScheme {\n                            if (isPrimaryButtonVisible) tertiaryContainer\n                            else primaryContainer\n                        },\n                        type = if (isPrimaryButtonVisible) {\n                            EnhancedFloatingActionButtonType.SecondaryVertical\n                        } else {\n                            EnhancedFloatingActionButtonType.Primary\n                        }\n                    ) {\n                        Icon(\n                            imageVector = secondaryButtonIcon,\n                            contentDescription = null\n                        )\n                    }\n                }\n\n                if (isPrimaryButtonVisible) middle()\n\n                AnimatedVisibility(visible = isPrimaryButtonVisible) {\n                    EnhancedFloatingActionButton(\n                        onClick = onPrimaryButtonClick.takeIf { isPrimaryButtonEnabled },\n                        onLongClick = onPrimaryButtonLongClick.takeIf { isPrimaryButtonEnabled },\n                        interactionSource = remember { MutableInteractionSource() }.takeIf { isPrimaryButtonEnabled },\n                        containerColor = takeColorFromScheme {\n                            if (isPrimaryButtonEnabled) primaryButtonContainerColor\n                            else surfaceContainerHighest\n                        },\n                        contentColor = takeColorFromScheme {\n                            if (isPrimaryButtonEnabled) primaryButtonContentColor\n                            else outline\n                        },\n                        modifier = Modifier.padding(top = spacing)\n                    ) {\n                        AnimatedContent(\n                            targetState = primaryButtonIcon to primaryButtonText,\n                            transitionSpec = { fadeIn() + scaleIn() togetherWith fadeOut() + scaleOut() }\n                        ) { (icon, text) ->\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically,\n                                horizontalArrangement = Arrangement.Center\n                            ) {\n                                if (text.isNotEmpty()) {\n                                    Spacer(Modifier.width(16.dp))\n                                }\n                                Icon(\n                                    imageVector = icon,\n                                    contentDescription = null\n                                )\n                                if (text.isNotEmpty()) {\n                                    Spacer(Modifier.width(16.dp))\n                                    Text(text)\n                                    Spacer(Modifier.width(16.dp))\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/CompareButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Compare\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\n\n@Composable\nfun CompareButton(\n    onClick: () -> Unit,\n    visible: Boolean\n) {\n    AnimatedVisibility(\n        visible = visible,\n        enter = fadeIn() + scaleIn(),\n        exit = fadeOut() + scaleOut()\n    ) {\n        EnhancedIconButton(\n            onClick = onClick\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.Compare,\n                contentDescription = stringResource(R.string.compare)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/EraseModeButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Eraser\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\n\n\n@Composable\nfun EraseModeButton(\n    selected: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true\n) {\n    EnhancedIconButton(\n        modifier = modifier,\n        enabled = enabled,\n        containerColor = animateColorAsState(\n            if (selected) MaterialTheme.colorScheme.mixedContainer\n            else Color.Transparent\n        ).value,\n        contentColor = animateColorAsState(\n            if (selected) MaterialTheme.colorScheme.onMixedContainer\n            else MaterialTheme.colorScheme.onSurface\n        ).value,\n        borderColor = MaterialTheme.colorScheme.outlineVariant(\n            luminance = 0.1f\n        ),\n        onClick = onClick\n    ) {\n        Icon(\n            imageVector = Icons.Rounded.Eraser,\n            contentDescription = stringResource(R.string.erase_mode)\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/MediaCheckBox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.CheckCircle\nimport androidx.compose.material.icons.outlined.Circle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.suggestContainerColorBy\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun MediaCheckBox(\n    modifier: Modifier = Modifier,\n    isChecked: Boolean,\n    selectionIndex: Int = -1,\n    onCheck: (() -> Unit)? = null,\n    checkedIcon: ImageVector = Icons.Filled.CheckCircle,\n    checkedColor: Color = MaterialTheme.colorScheme.primary,\n    uncheckedColor: Color = MaterialTheme.colorScheme.onSurface,\n    addContainer: Boolean = false\n) {\n    val image = if (isChecked) {\n        checkedIcon\n    } else Icons.Outlined.Circle\n    val color by animateColorAsState(\n        if (isChecked) checkedColor\n        else uncheckedColor\n    )\n    if (onCheck != null) {\n        EnhancedIconButton(\n            onClick = onCheck,\n            modifier = modifier,\n            containerColor = animateColorAsState(\n                if (addContainer) MaterialTheme.colorScheme.suggestContainerColorBy(color)\n                else Color.Transparent\n            ).value\n        ) {\n            AnimatedContent(\n                targetState = image,\n                transitionSpec = {\n                    fadeIn() togetherWith fadeOut()\n                }\n            ) { icon ->\n                Icon(\n                    imageVector = icon,\n                    contentDescription = null,\n                    tint = color\n                )\n            }\n        }\n    } else {\n        AnimatedContent(\n            targetState = Triple(isChecked, image, selectionIndex),\n            transitionSpec = {\n                fadeIn() togetherWith fadeOut()\n            }\n        ) { (isChecked, image, selectionIndex) ->\n            if (selectionIndex >= 0) {\n                if (isChecked) {\n                    Box(\n                        modifier = modifier\n                            .size(24.dp)\n                            .padding(2.dp)\n                            .clip(ShapeDefaults.circle)\n                            .background(color),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        AutoSizeText(\n                            text = (selectionIndex + 1).toString(),\n                            color = contentColorFor(color),\n                            style = MaterialTheme.typography.bodySmall\n                        )\n                    }\n                } else {\n                    Icon(\n                        imageVector = image,\n                        modifier = modifier,\n                        contentDescription = null,\n                        tint = color\n                    )\n                }\n            } else {\n                Icon(\n                    imageVector = image,\n                    modifier = modifier,\n                    contentDescription = null,\n                    tint = color\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/PagerScrollPanel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.pager.PagerState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBackIos\nimport androidx.compose.material.icons.automirrored.rounded.ArrowForwardIos\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport kotlinx.coroutines.launch\n\n@Composable\nfun PagerScrollPanel(\n    pagerState: PagerState,\n    modifier: Modifier = Modifier\n) {\n    val scope = rememberCoroutineScope()\n\n    Row(\n        modifier = modifier.container(\n            shape = ShapeDefaults.circle,\n            resultPadding = 4.dp\n        ),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        EnhancedIconButton(\n            onClick = {\n                scope.launch {\n                    pagerState.animateScrollToPage(\n                        (pagerState.currentPage - 1).takeIf { it >= 0 }\n                            ?: (pagerState.pageCount - 1)\n                    )\n                }\n            },\n            containerColor = MaterialTheme.colorScheme.surface\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.ArrowBackIos,\n                contentDescription = null,\n                modifier = Modifier.size(20.dp)\n            )\n        }\n\n        Text(\n            text = \"${pagerState.currentPage + 1} / ${pagerState.pageCount}\",\n            modifier = Modifier.weight(1f),\n            fontWeight = FontWeight.Bold,\n            textAlign = TextAlign.Center,\n            fontSize = 18.sp\n        )\n\n        EnhancedIconButton(\n            onClick = {\n                scope.launch {\n                    pagerState.animateScrollToPage(\n                        (pagerState.currentPage + 1) % pagerState.pageCount\n                    )\n                }\n            },\n            containerColor = MaterialTheme.colorScheme.surface\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.ArrowForwardIos,\n                contentDescription = null,\n                modifier = Modifier.size(20.dp)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/PanModeButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FrontHand\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\n\n@Composable\nfun PanModeButton(\n    selected: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier\n) {\n    EnhancedIconButton(\n        modifier = modifier,\n        containerColor = animateColorAsState(\n            if (selected) MaterialTheme.colorScheme.primary\n            else Color.Transparent\n        ).value,\n        contentColor = animateColorAsState(\n            if (selected) MaterialTheme.colorScheme.onPrimary\n            else MaterialTheme.colorScheme.onSurface\n        ).value,\n        borderColor = MaterialTheme.colorScheme.outlineVariant(\n            luminance = 0.1f\n        ),\n        onClick = onClick\n    ) {\n        Icon(\n            imageVector = Icons.Rounded.FrontHand,\n            contentDescription = stringResource(R.string.draw)\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/ShareButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Image\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material.icons.rounded.Share\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\n\n@Composable\nfun ShareButton(\n    enabled: Boolean = true,\n    onShare: () -> Unit,\n    onEdit: (() -> Unit)? = null,\n    onCopy: (() -> Unit)? = null,\n    dialogTitle: String = stringResource(R.string.image),\n    dialogIcon: ImageVector = Icons.Outlined.Image\n) {\n    var showSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    EnhancedIconButton(\n        onClick = {\n            if (onCopy != null || onEdit != null) {\n                showSelectionDialog = true\n            } else {\n                onShare()\n            }\n        },\n        enabled = enabled\n    ) {\n        Icon(\n            imageVector = Icons.Rounded.Share,\n            contentDescription = stringResource(R.string.share)\n        )\n    }\n\n    EnhancedAlertDialog(\n        visible = showSelectionDialog && (onEdit != null || onCopy != null),\n        onDismissRequest = { showSelectionDialog = false },\n        confirmButton = {\n            EnhancedButton(\n                onClick = { showSelectionDialog = false },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(R.string.cancel))\n            }\n        },\n        title = {\n            Text(dialogTitle)\n        },\n        icon = {\n            Icon(\n                imageVector = dialogIcon,\n                contentDescription = null\n            )\n        },\n        text = {\n            val scrollState = rememberScrollState()\n            Column(\n                modifier = Modifier\n                    .fadingEdges(\n                        scrollableState = scrollState,\n                        isVertical = true\n                    )\n                    .enhancedVerticalScroll(scrollState),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                PreferenceItem(\n                    title = stringResource(R.string.share),\n                    shape = ShapeDefaults.top,\n                    startIcon = Icons.Rounded.Share,\n                    onClick = {\n                        showSelectionDialog = false\n                        onShare()\n                    },\n                    titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                )\n                if (onCopy != null) {\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        title = stringResource(R.string.copy),\n                        shape = if (onEdit == null) ShapeDefaults.bottom\n                        else ShapeDefaults.center,\n                        startIcon = Icons.Rounded.ContentCopy,\n                        onClick = {\n                            showSelectionDialog = false\n                            onCopy()\n                        },\n                        titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                    )\n                }\n                if (onEdit != null) {\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        title = stringResource(R.string.edit),\n                        shape = ShapeDefaults.bottom,\n                        startIcon = Icons.Rounded.MiniEdit,\n                        onClick = {\n                            showSelectionDialog = false\n                            onEdit()\n                        },\n                        titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                    )\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/ShowOriginalButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.History\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\n\n@Composable\nfun ShowOriginalButton(\n    canShow: Boolean = true,\n    onStateChange: (Boolean) -> Unit\n) {\n    val haptics = LocalHapticFeedback.current\n    val interactionSource = remember { MutableInteractionSource() }\n\n    val shape = shapeByInteraction(\n        shape = ShapeDefaults.circle,\n        pressedShape = ShapeDefaults.mini,\n        interactionSource = interactionSource\n    )\n\n    Box(\n        modifier = Modifier\n            .clip(shape)\n            .indication(\n                interactionSource = interactionSource,\n                indication = LocalIndication.current\n            )\n            .pointerInput(Unit) {\n                detectTapGestures(\n                    onPress = {\n                        haptics.longPress()\n                        val press = PressInteraction.Press(it)\n                        interactionSource.emit(press)\n                        if (canShow) onStateChange(true)\n\n                        tryAwaitRelease()\n                        onStateChange(false)\n                        interactionSource.emit(\n                            PressInteraction.Release(\n                                press\n                            )\n                        )\n                    }\n                )\n            }\n    ) {\n        Icon(\n            imageVector = Icons.Rounded.History,\n            contentDescription = stringResource(R.string.original),\n            tint = MaterialTheme.colorScheme.onSurfaceVariant,\n            modifier = Modifier\n                .align(Alignment.Center)\n                .padding(8.dp)\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/SupportingButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\n\n@Composable\nfun SupportingButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    icon: ImageVector = Icons.Outlined.Info,\n    containerColor: Color = MaterialTheme.colorScheme.secondaryContainer,\n    contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor),\n    style: TextStyle = LocalTextStyle.current,\n    shape: Shape = AutoCircleShape(),\n    iconPadding: Dp = 1.dp\n) {\n    val interactionSource = remember { MutableInteractionSource() }\n    val shape = shapeByInteraction(\n        shape = shape,\n        pressedShape = ShapeDefaults.extraSmall,\n        interactionSource = interactionSource\n    )\n\n    Icon(\n        imageVector = icon,\n        contentDescription = icon.name,\n        tint = contentColor,\n        modifier = modifier\n            .clip(shape)\n            .background(containerColor)\n            .hapticsClickable(\n                onClick = onClick,\n                interactionSource = interactionSource,\n                indication = LocalIndication.current\n            )\n            .padding(iconPadding)\n            .size(\n                with(LocalDensity.current) {\n                    style.fontSize.toDp()\n                }\n            )\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/buttons/ZoomButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.buttons\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ZoomIn\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\n\n@Composable\nfun ZoomButton(\n    onClick: () -> Unit,\n    visible: Boolean\n) {\n    AnimatedVisibility(\n        visible = visible,\n        enter = fadeIn() + scaleIn(),\n        exit = fadeOut() + scaleOut()\n    ) {\n        EnhancedIconButton(\n            onClick = onClick\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.ZoomIn,\n                contentDescription = stringResource(R.string.zoom)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/AvailableColorTuplesSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.GridItemSpan\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.EmojiEmotions\nimport androidx.compose.material.icons.rounded.AddCircleOutline\nimport androidx.compose.material.icons.rounded.Contrast\nimport androidx.compose.material.icons.rounded.InvertColors\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.ColorTupleItem\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.dynamic.theme.rememberColorScheme\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.nearestFor\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.EditAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.PaletteBox\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.defaultColorTuple\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedHorizontalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.palette_selection.PaletteStyleSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.delay\n\n@Composable\nfun AvailableColorTuplesSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    colorTupleList: List<ColorTuple>,\n    currentColorTuple: ColorTuple,\n    onOpenColorPicker: () -> Unit,\n    colorPicker: @Composable () -> Unit,\n    onPickTheme: (ColorTuple) -> Unit,\n    onUpdateThemeContrast: (Float) -> Unit,\n    onThemeStyleSelected: (PaletteStyle) -> Unit,\n    onToggleInvertColors: () -> Unit,\n    onToggleUseEmojiAsPrimaryColor: () -> Unit,\n    onUpdateColorTuples: (List<ColorTuple>) -> Unit,\n) {\n    var showEditColorPicker by rememberSaveable { mutableStateOf(false) }\n\n    val settingsState = LocalSettingsState.current\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        dragHandle = {\n            EnhancedModalSheetDragHandle {\n                Row(\n                    modifier = Modifier.fillMaxWidth(),\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.Center\n                ) {\n                    TitleItem(\n                        text = stringResource(R.string.color_scheme),\n                        icon = Icons.Outlined.PaletteBox\n                    )\n                }\n            }\n        },\n        title = {\n            var showConfirmDeleteDialog by remember { mutableStateOf(false) }\n\n            EnhancedAlertDialog(\n                visible = showConfirmDeleteDialog,\n                onDismissRequest = { showConfirmDeleteDialog = false },\n                confirmButton = {\n                    EnhancedButton(\n                        onClick = { showConfirmDeleteDialog = false }\n                    ) {\n                        Text(stringResource(R.string.cancel))\n                    }\n                },\n                dismissButton = {\n                    EnhancedButton(\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        onClick = {\n                            showConfirmDeleteDialog = false\n                            if ((colorTupleList - currentColorTuple).isEmpty()) {\n                                onPickTheme(defaultColorTuple)\n                            } else {\n                                colorTupleList.nearestFor(currentColorTuple)\n                                    ?.let { onPickTheme(it) }\n                            }\n                            onUpdateColorTuples(colorTupleList - currentColorTuple)\n                        }\n                    ) {\n                        Text(stringResource(R.string.delete))\n                    }\n                },\n                title = {\n                    Text(stringResource(R.string.delete_color_scheme_title))\n                },\n                icon = {\n                    Icon(\n                        imageVector = Icons.Outlined.Delete,\n                        contentDescription = stringResource(R.string.delete)\n                    )\n                },\n                text = {\n                    Column(\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        ColorTupleItem(\n                            colorTuple = currentColorTuple,\n                            modifier = Modifier\n                                .padding(2.dp)\n                                .size(64.dp)\n                                .container(\n                                    shape = MaterialStarShape,\n                                    color = rememberColorScheme(\n                                        isDarkTheme = settingsState.isNightMode,\n                                        amoledMode = settingsState.isAmoledMode,\n                                        colorTuple = currentColorTuple,\n                                        contrastLevel = settingsState.themeContrastLevel,\n                                        style = settingsState.themeStyle,\n                                        dynamicColor = false,\n                                        isInvertColors = settingsState.isInvertThemeColors\n                                    ).surfaceVariant.copy(alpha = 0.8f),\n                                    borderColor = MaterialTheme.colorScheme.outlineVariant(0.2f),\n                                    resultPadding = 0.dp\n                                )\n                                .padding(3.dp)\n                                .clip(ShapeDefaults.circle),\n                            backgroundColor = Color.Transparent\n                        )\n                        Spacer(modifier = Modifier.height(8.dp))\n                        Text(stringResource(R.string.delete_color_scheme_warn))\n                    }\n                }\n            )\n            Row {\n                AnimatedVisibility(\n                    visible = currentColorTuple !in ColorTupleDefaults.defaultColorTuples && !settingsState.useEmojiAsPrimaryColor\n                ) {\n                    Row {\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.errorContainer,\n                            contentColor = MaterialTheme.colorScheme.onErrorContainer,\n                            onClick = {\n                                showConfirmDeleteDialog = true\n                            },\n                            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                                onTopOf = MaterialTheme.colorScheme.errorContainer\n                            )\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Delete,\n                                contentDescription = stringResource(R.string.delete)\n                            )\n                        }\n                        Spacer(Modifier.width(8.dp))\n                    }\n                }\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    onClick = {\n                        showEditColorPicker = true\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.EditAlt,\n                        contentDescription = stringResource(R.string.edit)\n                    )\n                }\n            }\n        },\n        sheetContent = {\n            val isPortrait by isPortraitOrientationAsState()\n\n            val isPickersEnabled = !settingsState.useEmojiAsPrimaryColor\n\n            val palette = @Composable {\n                PaletteStyleSelection(\n                    onThemeStyleSelected = onThemeStyleSelected,\n                    shape = ShapeDefaults.top,\n                )\n            }\n            val invertColors = @Composable {\n                PreferenceRowSwitch(\n                    title = stringResource(R.string.invert_colors),\n                    subtitle = stringResource(R.string.invert_colors_sub),\n                    checked = settingsState.isInvertThemeColors,\n                    modifier = Modifier,\n                    startIcon = Icons.Rounded.InvertColors,\n                    shape = ShapeDefaults.center,\n                    onClick = { onToggleInvertColors() }\n                )\n            }\n            val emojiAsPrimary = @Composable {\n                PreferenceRowSwitch(\n                    title = stringResource(R.string.emoji_as_color_scheme),\n                    subtitle = stringResource(R.string.emoji_as_color_scheme_sub),\n                    checked = settingsState.useEmojiAsPrimaryColor,\n                    modifier = Modifier,\n                    startIcon = Icons.Outlined.EmojiEmotions,\n                    shape = ShapeDefaults.center,\n                    onClick = { onToggleUseEmojiAsPrimaryColor() }\n                )\n            }\n            val contrast = @Composable {\n                EnhancedSliderItem(\n                    value = settingsState.themeContrastLevel.toFloat().roundToTwoDigits(),\n                    icon = Icons.Rounded.Contrast,\n                    title = stringResource(id = R.string.contrast),\n                    valueRange = -1f..1f,\n                    shape = ShapeDefaults.bottom,\n                    onValueChange = { },\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    steps = 198,\n                    onValueChangeFinished = {\n                        onUpdateThemeContrast(it)\n                    },\n                    modifier = Modifier.padding(bottom = 4.dp)\n                )\n            }\n            val defaultValues = @Composable {\n                val listState = rememberScrollState()\n                val defList = ColorTupleDefaults.defaultColorTuples\n                val density = LocalDensity.current\n                val cellSize = 60.dp\n                LaunchedEffect(visible, isPickersEnabled) {\n                    delay(100) // delay for sheet init\n                    if (currentColorTuple in defList) {\n                        listState.scrollTo(defList.indexOf(currentColorTuple) * with(density) { cellSize.roundToPx() })\n                    }\n                }\n                Column(\n                    modifier = Modifier\n                        .padding(bottom = 16.dp)\n                        .container(ShapeDefaults.extraLarge)\n                ) {\n                    Row(\n                        modifier = Modifier.fillMaxWidth(),\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.Center\n                    ) {\n                        Text(\n                            fontWeight = FontWeight.Medium,\n                            text = stringResource(R.string.simple_variants),\n                            color = MaterialTheme.colorScheme.onSurface,\n                            modifier = Modifier.padding(top = 16.dp),\n                            fontSize = 18.sp\n                        )\n                    }\n                    Box {\n                        Row(\n                            modifier = Modifier\n                                .enhancedHorizontalScroll(listState)\n                                .padding(PaddingValues(16.dp)),\n                            horizontalArrangement = Arrangement.spacedBy(4.dp)\n                        ) {\n                            defList.forEach { colorTuple ->\n                                ColorTuplePreview(\n                                    isDefaultItem = true,\n                                    modifier = Modifier.size(cellSize),\n                                    colorTuple = colorTuple,\n                                    appColorTuple = currentColorTuple,\n                                    onClick = { onPickTheme(colorTuple) }\n                                )\n                            }\n                        }\n\n                        Box(\n                            modifier = Modifier\n                                .align(Alignment.CenterStart)\n                                .width(8.dp)\n                                .height(64.dp)\n                                .background(\n                                    brush = Brush.horizontalGradient(\n                                        0f to MaterialTheme.colorScheme.surfaceContainer,\n                                        1f to Color.Transparent\n                                    )\n                                )\n                        )\n                        Box(\n                            modifier = Modifier\n                                .align(Alignment.CenterEnd)\n                                .width(8.dp)\n                                .height(64.dp)\n                                .background(\n                                    brush = Brush.horizontalGradient(\n                                        0f to Color.Transparent,\n                                        1f to MaterialTheme.colorScheme.surfaceContainer\n                                    )\n                                )\n                        )\n                    }\n                }\n            }\n            Row(\n                horizontalArrangement = Arrangement.Center,\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                if (!isPortrait) {\n                    Column(\n                        modifier = Modifier\n                            .enhancedVerticalScroll(rememberScrollState())\n                            .weight(0.8f)\n                            .padding(16.dp),\n                        verticalArrangement = Arrangement.spacedBy(4.dp)\n                    ) {\n                        palette()\n                        invertColors()\n                        emojiAsPrimary()\n                        contrast()\n                    }\n                }\n                LazyVerticalGrid(\n                    modifier = Modifier.weight(1f),\n                    columns = GridCells.Adaptive(64.dp),\n                    contentPadding = PaddingValues(16.dp),\n                    horizontalArrangement = Arrangement.spacedBy(\n                        space = 4.dp,\n                        alignment = Alignment.CenterHorizontally\n                    ),\n                    verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    if (isPortrait) {\n                        item(\n                            span = { GridItemSpan(maxLineSpan) }\n                        ) {\n                            palette()\n                        }\n                        item(\n                            span = { GridItemSpan(maxLineSpan) }\n                        ) {\n                            invertColors()\n                        }\n                        item(\n                            span = { GridItemSpan(maxLineSpan) }\n                        ) {\n                            emojiAsPrimary()\n                        }\n                        item(\n                            span = { GridItemSpan(maxLineSpan) }\n                        ) {\n                            contrast()\n                        }\n                    }\n                    item(\n                        span = { GridItemSpan(maxLineSpan) }\n                    ) {\n                        DisableContainer(isPickersEnabled, defaultValues)\n                    }\n                    items(colorTupleList) { colorTuple ->\n                        DisableContainer(isPickersEnabled) {\n                            ColorTuplePreview(\n                                colorTuple = colorTuple,\n                                appColorTuple = currentColorTuple,\n                                onClick = { onPickTheme(colorTuple) }\n                            )\n                        }\n                    }\n                    item {\n                        DisableContainer(isPickersEnabled) {\n                            ColorTupleItem(\n                                colorTuple = ColorTuple(\n                                    primary = MaterialTheme.colorScheme.secondary,\n                                    secondary = MaterialTheme.colorScheme.secondary,\n                                    tertiary = MaterialTheme.colorScheme.secondary\n                                ),\n                                modifier = Modifier\n                                    .aspectRatio(1f)\n                                    .container(\n                                        shape = MaterialStarShape,\n                                        color = MaterialTheme.colorScheme.surfaceVariant,\n                                        borderColor = MaterialTheme.colorScheme.outlineVariant(0.2f),\n                                        resultPadding = 0.dp\n                                    )\n                                    .hapticsClickable(onClick = onOpenColorPicker)\n                                    .padding(3.dp)\n                                    .clip(ShapeDefaults.circle),\n                                backgroundColor = Color.Transparent\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.AddCircleOutline,\n                                    contentDescription = stringResource(R.string.add),\n                                    tint = MaterialTheme.colorScheme.onSecondary,\n                                    modifier = Modifier.size(24.dp)\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = onDismiss\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n    )\n    ColorTuplePicker(\n        visible = showEditColorPicker,\n        onDismiss = {\n            showEditColorPicker = false\n        },\n        colorTuple = currentColorTuple,\n        onColorChange = {\n            onUpdateColorTuples(colorTupleList + it - currentColorTuple)\n            onPickTheme(it)\n        }\n    )\n    colorPicker()\n\n    if (settingsState.isDynamicColors) onDismiss()\n}\n\n@Composable\nprivate fun DisableContainer(\n    enabled: Boolean,\n    content: @Composable () -> Unit\n) {\n    Box(\n        modifier = Modifier.alpha(\n            animateFloatAsState(\n                if (enabled) 1f else 0.5f\n            ).value\n        )\n    ) {\n        content()\n        if (!enabled) {\n            Surface(\n                color = Color.Transparent,\n                modifier = Modifier.matchParentSize()\n            ) {}\n        }\n    }\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Palette\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material.icons.rounded.ContentPaste\nimport androidx.compose.material.icons.rounded.Shuffle\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.CardDefaults\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.ColorUtil.colorToHex\nimport com.t8rin.colors.util.ColorUtil.colorToHexAlpha\nimport com.t8rin.colors.util.HexUtil\nimport com.t8rin.colors.util.HexVisualTransformation\nimport com.t8rin.colors.util.hexRegexSingleChar\nimport com.t8rin.colors.util.hexWithAlphaRegex\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.pasteColorFromClipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport kotlinx.coroutines.delay\nimport kotlin.random.Random\n\n@Composable\nfun ColorInfo(\n    color: Color,\n    onColorChange: (Color) -> Unit,\n    onSupportButtonClick: () -> Unit = {\n        onColorChange(\n            Color(Random.nextInt()).copy(alpha = color.alpha)\n        )\n    },\n    supportButtonIcon: ImageVector = Icons.Rounded.Shuffle,\n    modifier: Modifier = Modifier,\n    infoContainerColor: Color = Color.Unspecified,\n) {\n    val context = LocalContext.current\n    val colorPasteError = rememberSaveable { mutableStateOf<String?>(null) }\n    val onCopyCustomColor = {\n        Clipboard.copy(\n            text = getFormattedColor(color),\n            message = R.string.color_copied\n        )\n    }\n    val onPasteCustomColor = {\n        context.pasteColorFromClipboard(\n            onPastedColor = onColorChange,\n            onPastedColorFailure = { colorPasteError.value = it },\n        )\n    }\n    LaunchedEffect(colorPasteError.value) {\n        delay(1500)\n        colorPasteError.value = null\n    }\n\n    Row(\n        modifier = modifier.fillMaxWidth(),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Card(\n            modifier = Modifier\n                .size(56.dp)\n                .container(\n                    shape = MaterialTheme.shapes.medium,\n                    color = color,\n                    resultPadding = 0.dp\n                )\n                .transparencyChecker()\n                .background(\n                    color = color,\n                    shape = MaterialTheme.shapes.medium\n                ),\n            colors = CardDefaults.cardColors(\n                containerColor = Color.Transparent,\n                contentColor = MaterialTheme.colorScheme.onSurface\n            )\n        ) {\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedIconButton(\n                    onClick = onSupportButtonClick\n                ) {\n                    Icon(\n                        imageVector = supportButtonIcon,\n                        contentDescription = stringResource(R.string.edit),\n                        tint = animateColorAsState(\n                            color.inverse(\n                                fraction = { cond ->\n                                    if (cond) 0.8f\n                                    else 0.5f\n                                },\n                                darkMode = color.luminance() < 0.3f\n                            )\n                        ).value,\n                        modifier = Modifier\n                            .size(28.dp)\n                            .background(\n                                color = color.copy(alpha = 1f),\n                                shape = ShapeDefaults.mini\n                            )\n                            .padding(2.dp)\n                    )\n                }\n            }\n        }\n\n        Card(\n            modifier = Modifier\n                .height(60.dp)\n                .fillMaxWidth()\n                .padding(start = 16.dp)\n                .container(\n                    shape = MaterialTheme.shapes.medium,\n                    color = infoContainerColor\n                ),\n            colors = CardDefaults.cardColors(\n                containerColor = Color.Transparent,\n                contentColor = MaterialTheme.colorScheme.onSurface\n            )\n        ) {\n            AnimatedContent(\n                colorPasteError.value != null\n            ) { error ->\n                var expanded by remember { mutableStateOf(false) }\n                Row(\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .padding(start = 8.dp)\n                        .padding(end = 8.dp),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    if (error) {\n                        Text(\n                            modifier = Modifier.fillMaxWidth(),\n                            text = colorPasteError.value ?: \"\",\n                            style = MaterialTheme.typography.labelMedium,\n                            textAlign = TextAlign.Center\n                        )\n                    } else {\n                        Row(modifier = Modifier.weight(1f)) {\n                            AutoSizeText(\n                                text = getFormattedColor(color),\n                                style = MaterialTheme.typography.titleMedium,\n                                maxLines = 1,\n                                modifier = Modifier\n                                    .clip(ShapeDefaults.pressed)\n                                    .hapticsClickable {\n                                        expanded = true\n                                    }\n                                    .padding(4.dp)\n                            )\n                        }\n                        Row(Modifier.width(80.dp)) {\n                            EnhancedIconButton(\n                                onClick = onCopyCustomColor\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.ContentCopy,\n                                    contentDescription = stringResource(R.string.copy)\n                                )\n                            }\n                            EnhancedIconButton(\n                                onClick = onPasteCustomColor\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.ContentPaste,\n                                    contentDescription = stringResource(R.string.pastel)\n                                )\n                            }\n                        }\n                    }\n                }\n                var value by remember(expanded) { mutableStateOf(getFormattedColor(color)) }\n                EnhancedAlertDialog(\n                    visible = expanded,\n                    onDismissRequest = { expanded = false },\n                    icon = {\n                        val hexColorInt by remember(value) {\n                            derivedStateOf {\n                                if (hexWithAlphaRegex.matches(value)) {\n                                    HexUtil.hexToColor(value).toArgb()\n                                } else null\n                            }\n                        }\n                        AnimatedContent(hexColorInt) { colorFromHex ->\n                            if (colorFromHex != null) {\n                                Box(\n                                    modifier = Modifier\n                                        .size(28.dp)\n                                        .container(\n                                            shape = ShapeDefaults.circle,\n                                            color = Color(colorFromHex),\n                                            resultPadding = 0.dp\n                                        )\n                                )\n                            } else {\n                                Icon(\n                                    imageVector = Icons.Outlined.Palette,\n                                    contentDescription = null\n                                )\n                            }\n                        }\n\n                    },\n                    title = {\n                        Text(stringResource(R.string.color))\n                    },\n                    text = {\n                        Column(\n                            modifier = Modifier.fillMaxWidth(),\n                            horizontalAlignment = Alignment.CenterHorizontally,\n                            verticalArrangement = Arrangement.Center\n                        ) {\n                            val style =\n                                MaterialTheme.typography.titleMedium.copy(textAlign = TextAlign.Center)\n                            OutlinedTextField(\n                                shape = ShapeDefaults.default,\n                                textStyle = style,\n                                maxLines = 1,\n                                value = value.removePrefix(\"#\"),\n                                visualTransformation = HexVisualTransformation(true),\n                                onValueChange = {\n                                    val hex = it.replace(\"#\", \"\")\n\n                                    if (hex.length <= 8) {\n                                        var validHex = true\n\n                                        for (index in hex.indices) {\n                                            validHex =\n                                                hexRegexSingleChar.matches(hex[index].toString())\n                                            if (!validHex) break\n                                        }\n\n                                        if (validHex) {\n                                            value = \"#${hex.uppercase()}\"\n                                        }\n                                    }\n                                },\n                                placeholder = {\n                                    Text(\n                                        text = \"#AARRGGBB\",\n                                        style = style,\n                                        modifier = Modifier.fillMaxWidth()\n                                    )\n                                }\n                            )\n                        }\n                    },\n                    confirmButton = {\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            onClick = {\n                                if (hexWithAlphaRegex.matches(value)) {\n                                    onColorChange(HexUtil.hexToColor(value))\n                                }\n                                expanded = false\n                            }\n                        ) {\n                            Text(stringResource(R.string.apply))\n                        }\n                    }\n                )\n            }\n        }\n    }\n}\n\n/** Receive the clipboard data. */\nprivate fun getFormattedColor(color: Color): String {\n    return if (color.alpha == 1f) {\n        colorToHex(color)\n    } else {\n        colorToHexAlpha(color)\n    }.uppercase()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorPicker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.gestures.detectDragGestures\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.CornerRadius\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.toSize\nimport com.t8rin.colors.util.ColorUtil\nimport com.t8rin.gesture.detectMotionEvents\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\nfun ColorPicker(\n    selectedColor: Color,\n    onColorSelected: (Color) -> Unit,\n    containerColor: Color = Color.Unspecified,\n    modifier: Modifier = Modifier,\n    hueSliderConfig: HueSliderThumbConfig = HueSliderThumbConfig.Default,\n) {\n    var hue by remember { mutableFloatStateOf(0f) }\n    var saturation by remember { mutableFloatStateOf(0f) }\n    var value by remember { mutableFloatStateOf(0f) }\n    var alpha by remember { mutableFloatStateOf(1f) }\n\n    LaunchedEffect(selectedColor) {\n        val (h, s, v) = ColorUtil.colorToHSV(selectedColor)\n        hue = h\n        saturation = s\n        value = v\n        alpha = selectedColor.alpha\n    }\n\n    LaunchedEffect(hue, saturation, value, alpha) {\n        onColorSelected(\n            Color.hsv(\n                hue = hue,\n                saturation = saturation,\n                value = value,\n                alpha = alpha\n            )\n        )\n    }\n\n    Row(modifier = modifier) {\n        SelectorRectSaturationValueHSV(\n            modifier = Modifier\n                .weight(1f)\n                .fillMaxSize()\n                .container(\n                    shape = ShapeDefaults.pressed,\n                    resultPadding = 0.dp,\n                    color = containerColor,\n                    clip = false\n                ),\n            hue = hue,\n            saturation = saturation,\n            value = value\n        ) { s, v ->\n            saturation = s\n            value = v\n        }\n\n        Spacer(modifier = Modifier.width(8.dp))\n\n        HueSlider(\n            hue = hue,\n            onHueSelected = { hue = it },\n            thumbConfig = hueSliderConfig,\n            modifier = Modifier.width(36.dp),\n        )\n\n        if (hueSliderConfig.withAlpha) {\n            Spacer(modifier = Modifier.width(8.dp))\n\n            AlphaSlider(\n                alpha = alpha,\n                onAlphaSelected = { alpha = it },\n                color = selectedColor,\n                thumbConfig = hueSliderConfig,\n                modifier = Modifier.width(36.dp),\n            )\n        }\n    }\n}\n\n@Immutable\ndata class HueSliderThumbConfig(\n    val height: Dp = 12.dp,\n    val color: Color = Color.White,\n    val borderSize: Dp = 2.dp,\n    val borderRadius: Float = 100f,\n    val withAlpha: Boolean = false\n) {\n    companion object {\n        val Default = HueSliderThumbConfig()\n    }\n}\n\n@Composable\nprivate fun HueSlider(\n    hue: Float,\n    onHueSelected: (Float) -> Unit,\n    modifier: Modifier = Modifier,\n    thumbConfig: HueSliderThumbConfig = HueSliderThumbConfig.Default,\n) {\n    var sliderSize by remember { mutableStateOf(Size.Zero) }\n    val thumbHeightPx = with(LocalDensity.current) { thumbConfig.height.toPx() }\n\n    fun updateThumbByOffset(offsetY: Float) {\n        if (sliderSize.height <= 0f) return\n\n        val maxThumbY = sliderSize.height - thumbHeightPx\n        val clampedY = offsetY.coerceIn(0f, maxThumbY)\n\n        val newHue = ((clampedY / maxThumbY) * 359f).coerceIn(0f, 359f)\n        onHueSelected(newHue)\n    }\n\n    Box(\n        modifier = modifier\n            .fillMaxHeight()\n            .onSizeChanged { sliderSize = it.toSize() }\n            .pointerInput(Unit) {\n                detectTapGestures { offset -> updateThumbByOffset(offset.y) }\n            }\n            .pointerInput(Unit) {\n                detectDragGestures { change, _ -> updateThumbByOffset(change.position.y) }\n            }\n    ) {\n        Canvas(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(horizontal = thumbConfig.borderSize)\n                .clip(ShapeDefaults.extraSmall)\n        ) {\n            drawRect(brush = Brush.verticalGradient(Color.colorList))\n        }\n\n        if (sliderSize.height > 0f) {\n            Canvas(modifier = Modifier.fillMaxSize()) {\n                val thumbY = (hue / 359f) * (sliderSize.height - thumbHeightPx)\n                drawRoundRect(\n                    color = thumbConfig.color,\n                    topLeft = Offset(\n                        x = thumbConfig.borderSize.toPx() / 2,\n                        y = thumbY\n                    ),\n                    size = Size(\n                        width = sliderSize.width - thumbConfig.borderSize.toPx(),\n                        height = thumbHeightPx\n                    ),\n                    style = Stroke(width = thumbConfig.borderSize.toPx()),\n                    cornerRadius = CornerRadius(\n                        thumbConfig.borderRadius,\n                        thumbConfig.borderRadius\n                    )\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun AlphaSlider(\n    onAlphaSelected: (Float) -> Unit,\n    modifier: Modifier = Modifier,\n    alpha: Float,\n    color: Color,\n    thumbConfig: HueSliderThumbConfig = HueSliderThumbConfig.Default,\n) {\n    var sliderSize by remember { mutableStateOf(Size.Zero) }\n    val density = LocalDensity.current\n\n    val thumbHeightPx = with(density) { thumbConfig.height.toPx() }\n    val updateAlpha by rememberUpdatedState(onAlphaSelected)\n\n    fun onThumbPositionChange(newOffset: Offset) {\n        if (sliderSize.height <= 0f) return\n\n        val maxThumbY = sliderSize.height - thumbHeightPx\n        val clampedY = newOffset.y.coerceIn(0f, maxThumbY)\n\n        val newAlpha = ((maxThumbY - clampedY) / maxThumbY).coerceIn(0f, 1f)\n        updateAlpha(newAlpha)\n    }\n\n    Box(\n        modifier = modifier\n            .fillMaxHeight()\n            .onSizeChanged { sliderSize = it.toSize() }\n            .pointerInput(Unit) {\n                detectTapGestures { offset -> onThumbPositionChange(offset) }\n            }\n            .pointerInput(Unit) {\n                detectDragGestures { change, _ ->\n                    onThumbPositionChange(change.position)\n                    change.consume()\n                }\n            }\n    ) {\n        val check = if (sliderSize.width > 0f) {\n            with(density) { sliderSize.width.toDp() / 3.3f }\n        } else {\n            10.dp\n        }\n\n        Canvas(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(horizontal = thumbConfig.borderSize)\n                .clip(ShapeDefaults.extraSmall)\n                .transparencyChecker(\n                    checkerWidth = check,\n                    checkerHeight = check\n                )\n        ) {\n            drawRect(\n                Brush.verticalGradient(\n                    colors = listOf(\n                        color.copy(alpha = 1f),\n                        color.copy(alpha = 0f)\n                    )\n                )\n            )\n        }\n\n        if (!sliderSize.isEmpty()) {\n            Canvas(modifier = Modifier.fillMaxSize()) {\n                val thumbY = (1f - alpha) * (sliderSize.height - thumbHeightPx)\n                drawRoundRect(\n                    color = thumbConfig.color,\n                    topLeft = Offset(\n                        x = thumbConfig.borderSize.toPx() / 2f,\n                        y = thumbY\n                    ),\n                    size = Size(\n                        width = sliderSize.width - thumbConfig.borderSize.toPx(),\n                        height = thumbHeightPx\n                    ),\n                    style = Stroke(width = thumbConfig.borderSize.toPx()),\n                    cornerRadius = CornerRadius(thumbConfig.borderRadius, thumbConfig.borderRadius)\n                )\n            }\n        }\n    }\n}\n\nprivate val Color.Companion.colorList by lazy {\n    IntArray(359) { it }.map { deg ->\n        Color.hsv(\n            hue = deg.toFloat(),\n            saturation = 1f,\n            value = 0.8f\n        )\n    }\n}\n\n/**\n * Rectangle Saturation and Vale selector for\n * [HSV](https://en.wikipedia.org/wiki/HSL_and_HSV) color model\n * @param hue is in [0f..360f] of HSL color\n * @param value is in [0f..1f] of HSL color\n * @param selectionRadius radius of selection circle that moves based on touch position\n * @param onChange callback that returns [hue] and [value]\n *  when position of touch in this selector has changed.\n */\n@Composable\nprivate fun SelectorRectSaturationValueHSV(\n    modifier: Modifier = Modifier,\n    hue: Float,\n    saturation: Float = 0.5f,\n    value: Float = 0.5f,\n    selectionRadius: Dp = Dp.Unspecified,\n    onChange: (Float, Float) -> Unit\n) {\n\n    val valueGradient = valueGradient(hue)\n    val hueSaturation = saturationHSVGradient(hue)\n\n    SelectorRect(\n        modifier = modifier,\n        saturation = saturation,\n        property = value,\n        brushSrc = hueSaturation,\n        brushDst = valueGradient,\n        selectionRadius = selectionRadius,\n        onChange = onChange\n    )\n}\n\n@Composable\nprivate fun SelectorRect(\n    modifier: Modifier = Modifier,\n    saturation: Float = 0.5f,\n    property: Float = 0.5f,\n    brushSrc: Brush,\n    brushDst: Brush,\n    selectionRadius: Dp = Dp.Unspecified,\n    onChange: (Float, Float) -> Unit\n) {\n\n    BoxWithConstraints(modifier) {\n\n        val density = LocalDensity.current.density\n        val width = constraints.maxWidth.toFloat()\n        val height = constraints.maxHeight.toFloat()\n\n        // Center position of color picker\n        val center = Offset(width / 2, height / 2)\n\n        /**\n         * Circle selector radius for setting [saturation] and [property] by gesture\n         */\n        val selectorRadius =\n            if (selectionRadius != Dp.Unspecified) selectionRadius.value * density\n            else width.coerceAtMost(height) * .04f\n\n        var currentPosition by remember {\n            mutableStateOf(center)\n        }\n\n        val posX = saturation * width\n        val posY = (1 - property) * height\n        currentPosition = Offset(posX, posY)\n\n\n        val canvasModifier = Modifier\n            .fillMaxSize()\n            .pointerInput(Unit) {\n                detectMotionEvents(\n                    onDown = {\n                        val position = it.position\n                        val saturationChange = (position.x / width).coerceIn(0f, 1f)\n                        val valueChange = (1 - (position.y / height)).coerceIn(0f, 1f)\n                        onChange(saturationChange, valueChange)\n                        it.consume()\n\n                    },\n                    onMove = {\n                        val position = it.position\n                        val saturationChange = (position.x / width).coerceIn(0f, 1f)\n                        val valueChange = (1 - (position.y / height)).coerceIn(0f, 1f)\n                        onChange(saturationChange, valueChange)\n                        it.consume()\n                    },\n                    delayAfterDownInMillis = 20\n                )\n            }\n\n        SelectorRectImpl(\n            modifier = canvasModifier,\n            brushSrc = brushSrc,\n            brushDst = brushDst,\n            selectorPosition = currentPosition,\n            selectorRadius = selectorRadius\n        )\n    }\n}\n\n@Composable\nprivate fun SelectorRectImpl(\n    modifier: Modifier,\n    brushSrc: Brush,\n    brushDst: Brush,\n    selectorPosition: Offset,\n    selectorRadius: Float\n) {\n\n    Canvas(modifier = modifier) {\n        drawBlendingRectGradient(\n            dst = brushDst,\n            src = brushSrc,\n            blendMode = BlendMode.Multiply\n        )\n        drawHueSelectionCircle(\n            center = selectorPosition,\n            radius = selectorRadius\n        )\n    }\n}\n\nprivate fun saturationHSVGradient(\n    hue: Float,\n    value: Float = 1f,\n    alpha: Float = 1f,\n    start: Offset = Offset.Zero,\n    end: Offset = Offset(Float.POSITIVE_INFINITY, 0f)\n): Brush {\n    return Brush.linearGradient(\n        colors = listOf(\n            Color.hsv(hue = hue, saturation = 0f, value = value, alpha = alpha),\n            Color.hsv(hue = hue, saturation = 1f, value = value, alpha = alpha)\n        ),\n        start = start,\n        end = end\n    )\n}\n\n/**\n * Vertical gradient that goes from 1 value to 0 with 90 degree rotation by default.\n */\nfun valueGradient(\n    hue: Float,\n    alpha: Float = 1f,\n    start: Offset = Offset.Zero,\n    end: Offset = Offset(0f, Float.POSITIVE_INFINITY)\n): Brush {\n    return Brush.linearGradient(\n        colors = listOf(\n            Color.hsv(hue = hue, saturation = 0f, value = 1f, alpha = alpha),\n            Color.hsv(hue = hue, saturation = 0f, value = 0f, alpha = alpha)\n        ),\n        start = start,\n        end = end\n    )\n}\n\nprivate fun DrawScope.drawBlendingRectGradient(\n    dst: Brush,\n    dstTopLeft: Offset = Offset.Zero,\n    dstSize: Size = this.size,\n    src: Brush,\n    srcTopLeft: Offset = Offset.Zero,\n    srcSize: Size = this.size,\n    blendMode: BlendMode = BlendMode.Multiply\n) {\n    with(drawContext.canvas.nativeCanvas) {\n        val checkPoint = saveLayer(null, null)\n        drawRect(dst, dstTopLeft, dstSize)\n        drawRect(src, srcTopLeft, srcSize, blendMode = blendMode)\n        restoreToCount(checkPoint)\n    }\n}\n\nprivate fun DrawScope.drawHueSelectionCircle(\n    center: Offset,\n    radius: Float\n) {\n    drawCircle(\n        Color.White,\n        radius = radius,\n        center = center,\n        style = Stroke(width = radius / 4)\n    )\n\n    drawCircle(\n        Color.Black,\n        radius = radius + radius / 8,\n        center = center,\n        style = Stroke(width = radius / 8)\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorPickerSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Bookmark\nimport androidx.compose.material.icons.rounded.BookmarkRemove\nimport androidx.compose.material.icons.rounded.ColorLens\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.launch\n\n@Composable\nfun ColorPickerSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    color: Color?,\n    onColorSelected: (Color) -> Unit,\n    allowAlpha: Boolean\n) {\n    val scope = rememberCoroutineScope()\n    var tempColor by remember(visible) {\n        mutableStateOf(color ?: Color.Black)\n    }\n    val settingsState = LocalSettingsState.current\n\n    val simpleSettingsInteractor = LocalSimpleSettingsInteractor.current\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Box {\n                Column(\n                    modifier = Modifier\n                        .enhancedVerticalScroll(rememberScrollState(), reverseScrolling = true)\n                        .padding(24.dp)\n                ) {\n                    RecentAndFavoriteColorsCard(\n                        onRecentColorClick = { tempColor = it },\n                        onFavoriteColorClick = { tempColor = it }\n                    )\n\n                    ColorSelection(\n                        value = tempColor,\n                        onValueChange = { tempColor = it },\n                        withAlpha = allowAlpha\n                    )\n                }\n            }\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.color),\n                icon = Icons.Rounded.ColorLens\n            )\n        },\n        confirmButton = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                val favoriteColors = settingsState.favoriteColors\n\n                val inFavorite by remember(tempColor, favoriteColors) {\n                    derivedStateOf {\n                        tempColor in favoriteColors\n                    }\n                }\n\n                val containerColor by animateColorAsState(\n                    if (inFavorite) MaterialTheme.colorScheme.tertiaryContainer\n                    else MaterialTheme.colorScheme.surfaceContainer\n                )\n                val contentColor by animateColorAsState(\n                    if (inFavorite) MaterialTheme.colorScheme.onTertiaryContainer\n                    else MaterialTheme.colorScheme.onBackground\n                )\n\n                EnhancedIconButton(\n                    containerColor = containerColor,\n                    contentColor = contentColor,\n                    onClick = {\n                        scope.launch {\n                            simpleSettingsInteractor.toggleFavoriteColor(\n                                tempColor.toArgb().toColorModel()\n                            )\n                        }\n                    }\n                ) {\n                    Icon(\n                        imageVector = if (inFavorite) {\n                            Icons.Rounded.BookmarkRemove\n                        } else {\n                            Icons.Rounded.Bookmark\n                        },\n                        contentDescription = null\n                    )\n                }\n                EnhancedButton(\n                    onClick = {\n                        scope.launch {\n                            simpleSettingsInteractor.toggleRecentColor(\n                                tempColor.toArgb().toColorModel()\n                            )\n                        }\n                        onColorSelected(tempColor)\n                        onDismiss()\n                    }\n                ) {\n                    AutoSizeText(stringResource(R.string.ok))\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun ColorSelection(\n    value: Color,\n    onValueChange: (Color) -> Unit,\n    withAlpha: Boolean = false,\n    infoContainerColor: Color = Color.Unspecified,\n) {\n    Column {\n        ColorInfo(\n            color = value.let {\n                if (withAlpha) it else it.copy(1f)\n            },\n            onColorChange = onValueChange,\n            infoContainerColor = infoContainerColor\n        )\n        Spacer(Modifier.height(16.dp))\n        ColorPicker(\n            onColorSelected = onValueChange,\n            selectedColor = value,\n            containerColor = infoContainerColor,\n            modifier = Modifier\n                .fillMaxWidth()\n                .height(200.dp),\n            hueSliderConfig = HueSliderThumbConfig(\n                withAlpha = withAlpha\n            )\n        )\n        Spacer(Modifier.height(16.dp))\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorSelectionRow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Error\nimport androidx.compose.material.icons.rounded.Block\nimport androidx.compose.material.icons.rounded.DoneAll\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.pasteColorFromClipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport kotlinx.coroutines.delay\n\n@Composable\nfun ColorSelectionRow(\n    modifier: Modifier = Modifier,\n    defaultColors: List<Color> = ColorSelectionRowDefaults.colorList,\n    allowAlpha: Boolean = false,\n    allowScroll: Boolean = true,\n    value: Color?,\n    onValueChange: (Color) -> Unit,\n    contentPadding: PaddingValues = PaddingValues(),\n    onNullClick: (() -> Unit)? = null\n) {\n    val context = LocalContext.current\n    var customColor by remember { mutableStateOf<Color?>(null) }\n    var showColorPicker by remember { mutableStateOf(false) }\n    val listState = rememberLazyListState()\n\n    LaunchedEffect(value) {\n        if (value !in defaultColors) {\n            customColor = value\n        }\n    }\n\n    LaunchedEffect(Unit) {\n        delay(250)\n        if (value == customColor) {\n            listState.animateScrollToItem(0)\n        } else if (value in defaultColors) {\n            listState.animateScrollToItem(defaultColors.indexOf(value))\n        }\n    }\n\n    val itemSize = 42.dp\n\n    ProvideContainerDefaults(\n        color = LocalContainerColor.current\n    ) {\n        LazyRow(\n            state = listState,\n            modifier = modifier\n                .fillMaxWidth()\n                .height(64.dp)\n                .fadingEdges(listState),\n            userScrollEnabled = allowScroll,\n            contentPadding = contentPadding,\n            horizontalArrangement = Arrangement.spacedBy(8.dp),\n            verticalAlignment = Alignment.CenterVertically,\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            if (onNullClick != null) {\n                item {\n                    val background = MaterialTheme.colorScheme.surfaceVariant\n                    val isSelected = value == null\n                    val interactionSource = remember { MutableInteractionSource() }\n                    val shape = shapeByInteraction(\n                        shape = if (isSelected) ShapeDefaults.small else AutoCornersShape(itemSize / 2),\n                        pressedShape = ShapeDefaults.pressed,\n                        interactionSource = interactionSource\n                    )\n\n                    Box(\n                        modifier = Modifier\n                            .height(itemSize)\n                            .aspectRatio(\n                                ratio = animateFloatAsState(\n                                    targetValue = if (isSelected) 1.5f else 1f,\n                                    animationSpec = tween(400)\n                                ).value,\n                                matchHeightConstraintsFirst = true\n                            )\n                            .container(\n                                shape = shape,\n                                color = background,\n                                resultPadding = 0.dp\n                            )\n                            .transparencyChecker()\n                            .background(background, shape)\n                            .hapticsCombinedClickable(\n                                indication = LocalIndication.current,\n                                interactionSource = interactionSource,\n                                onClick = onNullClick\n                            ),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Block,\n                            contentDescription = null,\n                            tint = MaterialTheme.colorScheme.onSurfaceVariant,\n                            modifier = Modifier.size(24.dp)\n                        )\n                    }\n                }\n            }\n            item {\n                val background = customColor ?: MaterialTheme.colorScheme.primary\n                val isSelected = customColor != null\n                val interactionSource = remember { MutableInteractionSource() }\n                val shape = shapeByInteraction(\n                    shape = if (isSelected) ShapeDefaults.small else AutoCornersShape(itemSize / 2),\n                    pressedShape = ShapeDefaults.pressed,\n                    interactionSource = interactionSource\n                )\n\n                Box(\n                    modifier = Modifier\n                        .height(itemSize)\n                        .aspectRatio(\n                            ratio = animateFloatAsState(\n                                targetValue = if (isSelected) 1.5f else 1f,\n                                animationSpec = tween(400)\n                            ).value,\n                            matchHeightConstraintsFirst = true\n                        )\n                        .container(\n                            shape = shape,\n                            color = background,\n                            resultPadding = 0.dp\n                        )\n                        .transparencyChecker()\n                        .background(background, shape)\n                        .hapticsCombinedClickable(\n                            indication = LocalIndication.current,\n                            interactionSource = interactionSource,\n                            onLongClick = {\n                                context.pasteColorFromClipboard(\n                                    onPastedColor = {\n                                        val color = if (allowAlpha) it else it.copy(1f)\n\n                                        onValueChange(color)\n                                        customColor = color\n                                    },\n                                    onPastedColorFailure = { message ->\n                                        AppToastHost.showToast(\n                                            message = message,\n                                            icon = Icons.Outlined.Error\n                                        )\n                                    }\n                                )\n                            },\n                            onClick = {\n                                showColorPicker = true\n                            }\n                        ),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.Palette,\n                        contentDescription = null,\n                        tint = background.inverse(\n                            fraction = {\n                                if (it) 0.8f\n                                else 0.5f\n                            },\n                            darkMode = background.luminance() < 0.3f\n                        ),\n                        modifier = Modifier\n                            .size(32.dp)\n                            .background(\n                                color = background.copy(alpha = 1f),\n                                shape = shape\n                            )\n                            .padding(4.dp)\n                    )\n                }\n            }\n            items(\n                items = defaultColors,\n                key = { it.toArgb() }\n            ) { color ->\n                val isSelected = value == color && customColor == null\n                val interactionSource = remember { MutableInteractionSource() }\n                val shape = shapeByInteraction(\n                    shape = if (isSelected) ShapeDefaults.small else AutoCornersShape(itemSize / 2),\n                    pressedShape = ShapeDefaults.pressed,\n                    interactionSource = interactionSource\n                )\n\n                Box(\n                    modifier = Modifier\n                        .height(itemSize)\n                        .aspectRatio(\n                            ratio = animateFloatAsState(\n                                targetValue = if (isSelected) 1.5f else 1f,\n                                animationSpec = tween(400)\n                            ).value,\n                            matchHeightConstraintsFirst = true\n                        )\n                        .container(\n                            shape = shape,\n                            color = color,\n                            resultPadding = 0.dp\n                        )\n                        .transparencyChecker()\n                        .background(color, shape)\n                        .hapticsClickable(\n                            interactionSource = interactionSource,\n                            indication = LocalIndication.current,\n                            onClick = {\n                                onValueChange(color.copy(if (allowAlpha) color.alpha else 1f))\n                                customColor = null\n                            }\n                        ),\n                    contentAlignment = Alignment.Center\n                ) {\n                    AnimatedVisibility(\n                        visible = isSelected,\n                        modifier = Modifier.fillMaxSize()\n                    ) {\n                        Box(\n                            contentAlignment = Alignment.Center\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.DoneAll,\n                                contentDescription = null,\n                                tint = color.inverse(\n                                    fraction = {\n                                        if (it) 0.8f\n                                        else 0.5f\n                                    },\n                                    darkMode = color.luminance() < 0.3f\n                                ),\n                                modifier = Modifier.size(20.dp)\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    ColorPickerSheet(\n        visible = showColorPicker,\n        onDismiss = { showColorPicker = false },\n        color = customColor,\n        onColorSelected = {\n            val color = it.copy(if (allowAlpha) it.alpha else 1f)\n            onValueChange(color)\n            customColor = color\n        },\n        allowAlpha = allowAlpha\n    )\n}\n\n\nobject ColorSelectionRowDefaults {\n    val colorList by lazy {\n        listOf(\n            Color(0xFF7a000b),\n            Color(0xFF8a000b),\n            Color(0xFF97000c),\n            Color(0xFFa5000d),\n            Color(0xFFb2070d),\n            Color(0xFFbf100e),\n            Color(0xFFca120e),\n            Color(0xFFd8150e),\n            Color(0xFFf8130d),\n            Color(0xFFff3306),\n            Color(0xFFff4f05),\n            Color(0xFFff6b02),\n            Color(0xFFff7900),\n            Color(0xFFf89c08),\n            Color(0xFFf8b40c),\n            Color(0xFFfcf721),\n            Color(0xFFe0e11c),\n            Color(0xFFc9e11a),\n            Color(0xFFc0dc18),\n            Color(0xFFaee020),\n            Color(0xFF96df20),\n            Color(0xFF88dd20),\n            Color(0xFF50cbb5),\n            Color(0xFF36c0b3),\n            Color(0xFF1eb0b0),\n            Color(0xFF01a0a3),\n            Color(0xFF05bfc0),\n            Color(0xFF07cfd3),\n            Color(0xFF59cbf0),\n            Color(0xFF3b9df0),\n            Color(0xFF1c7fff),\n            Color(0xFF005FFF),\n            Color(0xFF034087),\n            Color(0xFF022b6d),\n            Color(0xFF2d1d9c),\n            Color(0xFF3f1f9a),\n            Color(0xFF642bec),\n            Color(0xFF7b2bec),\n            Color(0xFF8e36f4),\n            Color(0xFF9836f5),\n            Color(0xFFaa3ef8),\n            Color(0xFFb035f8),\n            Color(0xFFc78afe),\n            Color(0xFFd294fe),\n            Color(0xFFdb94fe),\n            Color(0xFFe76cd9),\n            Color(0xFFfa64e1),\n            Color(0xFFfc50a6),\n            Color(0xFFe10076),\n            Color(0xFFd7036a),\n            Color(0xFFFFFFFF),\n            Color(0xFF768484),\n            Color(0xFF333333),\n            Color(0xFF000000),\n        )\n    }\n\n    val colorListVariant by lazy {\n        colorList.takeLast(4) + colorList.dropLast(4)\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorTupleDefaults.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.calculateSecondaryColor\nimport com.t8rin.dynamic.theme.calculateSurfaceColor\nimport com.t8rin.dynamic.theme.calculateTertiaryColor\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\n\nobject ColorTupleDefaults {\n    val defaultColorTuples by lazy {\n        listOf(\n            Color(0xFFf8130d),\n            Color(0xFF7a000b),\n            Color(0xFF8a3a00),\n            Color(0xFFff7900),\n            Color(0xFFfcf721),\n            Color(0xFF88dd20),\n            Color(0xFF16B16E),\n            Color(0xFF01a0a3),\n            Color(0xFF005FFF),\n            Color(0xFFfa64e1),\n            Color(0xFFd7036a),\n            Color(0xFFdb94fe),\n            Color(0xFF7b2bec),\n            Color(0xFF022b6d),\n            Color(0xFFFFFFFF),\n            Color(0xFF000000),\n        ).map {\n            ColorTuple(\n                primary = it,\n                secondary = it.calculateSecondaryColor().toColor(),\n                tertiary = it.calculateTertiaryColor().toColor(),\n                surface = it.calculateSurfaceColor().toColor()\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorTuplePicker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.GridItemSpan\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Palette\nimport androidx.compose.material.icons.rounded.ContentPaste\nimport androidx.compose.material.icons.rounded.FormatColorFill\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.dynamic.theme.calculateSecondaryColor\nimport com.t8rin.dynamic.theme.calculateSurfaceColor\nimport com.t8rin.dynamic.theme.calculateTertiaryColor\nimport com.t8rin.dynamic.theme.rememberAppColorTuple\nimport com.t8rin.dynamic.theme.rememberColorScheme\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.delay\n\n@Composable\nfun ColorTuplePicker(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    colorTuple: ColorTuple,\n    title: String = stringResource(R.string.color_scheme),\n    onColorChange: (ColorTuple) -> Unit,\n) {\n    val settingsState = LocalSettingsState.current\n\n    var primary by rememberSaveable(colorTuple, stateSaver = ColorSaver) {\n        mutableStateOf(colorTuple.primary)\n    }\n    var secondary by rememberSaveable(colorTuple, stateSaver = ColorSaver) {\n        mutableStateOf(\n            colorTuple.secondary ?: colorTuple.primary.calculateSecondaryColor().toColor()\n        )\n    }\n    var tertiary by rememberSaveable(colorTuple, stateSaver = ColorSaver) {\n        mutableStateOf(\n            colorTuple.tertiary ?: colorTuple.primary.calculateTertiaryColor().toColor()\n        )\n    }\n\n    var surface by rememberSaveable(colorTuple, stateSaver = ColorSaver) {\n        mutableStateOf(\n            colorTuple.surface ?: colorTuple.primary.calculateSurfaceColor().toColor()\n        )\n    }\n\n    val appColorTuple = rememberAppColorTuple(\n        defaultColorTuple = settingsState.appColorTuple,\n        dynamicColor = true,\n        darkTheme = true\n    )\n\n    val scheme = rememberColorScheme(\n        amoledMode = false,\n        isDarkTheme = true,\n        colorTuple = appColorTuple,\n        contrastLevel = settingsState.themeContrastLevel,\n        style = settingsState.themeStyle,\n        dynamicColor = false,\n        isInvertColors = settingsState.isInvertThemeColors\n    )\n\n    LaunchedEffect(visible) {\n        if (!visible) {\n            delay(1000)\n            primary = colorTuple.primary\n            secondary = colorTuple.secondary\n                ?: colorTuple.primary.calculateSecondaryColor().toColor()\n            tertiary =\n                colorTuple.tertiary\n                    ?: colorTuple.primary.calculateTertiaryColor().toColor()\n            surface =\n                colorTuple.surface\n                    ?: colorTuple.primary.calculateSurfaceColor().toColor()\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = title,\n                icon = Icons.Outlined.Palette\n            )\n        },\n        sheetContent = {\n            Box {\n                LazyVerticalGrid(\n                    columns = GridCells.Adaptive(260.dp),\n                    horizontalArrangement = Arrangement.spacedBy(\n                        16.dp,\n                        Alignment.CenterHorizontally\n                    ),\n                    verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically),\n                    contentPadding = PaddingValues(16.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    item(\n                        span = {\n                            GridItemSpan(maxCurrentLineSpan)\n                        }\n                    ) {\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically,\n                            horizontalArrangement = Arrangement.Center,\n                            modifier = Modifier\n                                .container(ShapeDefaults.extraLarge)\n                                .padding(16.dp)\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.FormatColorFill,\n                                contentDescription = null\n                            )\n                            Spacer(Modifier.width(8.dp))\n                            Text(stringResource(R.string.monet_colors))\n                            Spacer(Modifier.width(8.dp))\n                            Spacer(Modifier.weight(1f))\n                            EnhancedButton(\n                                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                                onClick = {\n                                    scheme.apply {\n                                        primary = this.primary\n                                        if (settingsState.themeStyle == PaletteStyle.TonalSpot) {\n                                            secondary = this.secondary\n                                            tertiary = this.tertiary\n                                            surface = this.surface\n                                        }\n                                    }\n                                },\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.ContentPaste,\n                                    contentDescription = stringResource(R.string.pastel)\n                                )\n                            }\n                        }\n                    }\n                    item(\n                        span = {\n                            if (settingsState.themeStyle != PaletteStyle.TonalSpot) {\n                                GridItemSpan(\n                                    maxCurrentLineSpan\n                                )\n                            } else GridItemSpan(1)\n                        }\n                    ) {\n                        Column(\n                            horizontalAlignment = Alignment.CenterHorizontally,\n                            modifier = Modifier\n                                .container(ShapeDefaults.extraLarge)\n                                .padding(horizontal = 20.dp)\n                        ) {\n                            TitleItem(text = stringResource(R.string.primary))\n                            ColorSelection(\n                                value = primary,\n                                onValueChange = {\n                                    if (primary != it && settingsState.themeStyle == PaletteStyle.TonalSpot) {\n                                        secondary = it.calculateSecondaryColor().toColor()\n                                        tertiary = it.calculateTertiaryColor().toColor()\n                                        surface = it.calculateSurfaceColor().toColor()\n                                    }\n                                    primary = it\n                                },\n                                infoContainerColor = MaterialTheme.colorScheme.surface\n                            )\n                        }\n                    }\n                    if (settingsState.themeStyle == PaletteStyle.TonalSpot) {\n                        item {\n                            Column(\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                modifier = Modifier\n                                    .container(ShapeDefaults.extraLarge)\n                                    .padding(horizontal = 20.dp)\n                            ) {\n                                TitleItem(text = stringResource(R.string.secondary))\n                                ColorSelection(\n                                    value = secondary,\n                                    onValueChange = {\n                                        secondary = it\n                                    },\n                                    infoContainerColor = MaterialTheme.colorScheme.surface\n                                )\n                            }\n                        }\n                        item {\n                            Column(\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                modifier = Modifier\n                                    .container(ShapeDefaults.extraLarge)\n                                    .padding(horizontal = 20.dp)\n                            ) {\n                                TitleItem(text = stringResource(R.string.tertiary))\n                                ColorSelection(\n                                    value = tertiary,\n                                    onValueChange = {\n                                        tertiary = it\n                                    },\n                                    infoContainerColor = MaterialTheme.colorScheme.surface\n                                )\n                            }\n                        }\n                        item {\n                            Column(\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                modifier = Modifier\n                                    .container(ShapeDefaults.extraLarge)\n                                    .padding(horizontal = 20.dp)\n                            ) {\n                                TitleItem(text = stringResource(R.string.surface))\n                                ColorSelection(\n                                    value = surface,\n                                    onValueChange = {\n                                        surface = it\n                                    },\n                                    infoContainerColor = MaterialTheme.colorScheme.surface\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    onColorChange(\n                        ColorTuple(\n                            primary = primary,\n                            secondary = secondary,\n                            tertiary = tertiary,\n                            surface = surface\n                        )\n                    )\n                    onDismiss()\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.save))\n            }\n        },\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/ColorTuplePreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.ColorTupleItem\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.dynamic.theme.rememberColorScheme\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n\n@Composable\nfun ColorTuplePreview(\n    modifier: Modifier = Modifier,\n    isDefaultItem: Boolean = false,\n    colorTuple: ColorTuple,\n    appColorTuple: ColorTuple,\n    onClick: () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    ColorTupleItem(\n        colorTuple = remember(settingsState.themeStyle, colorTuple) {\n            derivedStateOf {\n                if (settingsState.themeStyle == PaletteStyle.TonalSpot) {\n                    colorTuple\n                } else colorTuple.run {\n                    copy(secondary = primary, tertiary = primary)\n                }\n            }\n        }.value,\n        modifier = modifier\n            .aspectRatio(1f)\n            .container(\n                shape = MaterialStarShape,\n                color = rememberColorScheme(\n                    isDarkTheme = settingsState.isNightMode,\n                    amoledMode = settingsState.isAmoledMode,\n                    colorTuple = colorTuple,\n                    contrastLevel = settingsState.themeContrastLevel,\n                    style = settingsState.themeStyle,\n                    dynamicColor = false,\n                    isInvertColors = settingsState.isInvertThemeColors\n                ).surfaceVariant.copy(alpha = 0.8f),\n                borderColor = MaterialTheme.colorScheme.outlineVariant(0.2f),\n                resultPadding = 0.dp\n            )\n            .hapticsClickable(onClick = onClick)\n            .padding(3.dp)\n            .clip(ShapeDefaults.circle),\n        backgroundColor = Color.Transparent\n    ) {\n        AnimatedContent(\n            targetState = (colorTuple == appColorTuple)\n                .and(\n                    if (colorTuple in ColorTupleDefaults.defaultColorTuples) {\n                        isDefaultItem\n                    } else true\n                )\n        ) { selected ->\n            BoxWithConstraints(\n                contentAlignment = Alignment.Center,\n                modifier = Modifier.fillMaxSize()\n            ) {\n                if (selected) {\n                    Box(\n                        modifier = Modifier\n                            .size(this.maxWidth * (5 / 9f))\n                            .background(\n                                color = animateColorAsState(\n                                    colorTuple.primary.inverse(\n                                        fraction = { cond ->\n                                            if (cond) 0.8f\n                                            else 0.5f\n                                        },\n                                        darkMode = colorTuple.primary.luminance() < 0.3f\n                                    )\n                                ).value,\n                                shape = ShapeDefaults.circle\n                            )\n                    )\n                    Icon(\n                        imageVector = Icons.Rounded.Done,\n                        contentDescription = stringResource(R.string.ok),\n                        tint = colorTuple.primary,\n                        modifier = Modifier.size(maxWidth * (1 / 3f))\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/color_picker/RecentAndFavoriteColorsCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.color_picker\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.History\nimport androidx.compose.material.icons.rounded.BookmarkBorder\nimport androidx.compose.material.icons.rounded.ContentPasteGo\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.DeleteSweep\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.launch\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\nimport kotlin.math.roundToInt\n\n@Composable\nfun RecentAndFavoriteColorsCard(\n    onFavoriteColorClick: (Color) -> Unit,\n    onRecentColorClick: (Color) -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val recentColors = settingsState.recentColors\n    val favoriteColors = settingsState.favoriteColors\n    val interactor = LocalSimpleSettingsInteractor.current\n    val scope = rememberCoroutineScope()\n\n    BoxAnimatedVisibility(\n        visible = recentColors.isNotEmpty() || favoriteColors.isNotEmpty()\n    ) {\n        val itemWidth = with(LocalDensity.current) { 48.dp.toPx() }\n\n        Column(\n            modifier = Modifier\n                .padding(bottom = 16.dp)\n                .container(\n                    shape = ShapeDefaults.extraLarge,\n                    resultPadding = 0.dp\n                )\n                .padding(16.dp),\n            verticalArrangement = Arrangement.spacedBy(16.dp)\n        ) {\n            BoxAnimatedVisibility(recentColors.isNotEmpty()) {\n                Column {\n                    TitleItem(\n                        text = stringResource(R.string.recently_used),\n                        icon = Icons.Outlined.History,\n                        modifier = Modifier,\n                        endContent = {\n                            EnhancedIconButton(\n                                onClick = {\n                                    scope.launch {\n                                        interactor.clearRecentColors()\n                                    }\n                                },\n                                modifier = Modifier.offset(x = 8.dp)\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Outlined.DeleteSweep,\n                                    contentDescription = null,\n                                    tint = takeColorFromScheme {\n                                        primary.blend(error, 0.8f)\n                                    }\n                                )\n                            }\n                        }\n                    )\n                    Spacer(Modifier.height(12.dp))\n                    val recentState = rememberLazyListState()\n                    val possibleCount by remember(recentState, itemWidth) {\n                        derivedStateOf {\n                            (recentState.layoutInfo.viewportSize.width / itemWidth).roundToInt()\n                        }\n                    }\n                    LazyRow(\n                        state = recentState,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .fadingEdges(recentState),\n                        horizontalArrangement = Arrangement.spacedBy(8.dp),\n                        verticalAlignment = Alignment.CenterVertically,\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        items(\n                            items = recentColors,\n                            key = { it.toArgb() }\n                        ) { color ->\n                            Box(\n                                modifier = Modifier\n                                    .size(40.dp)\n                                    .aspectRatio(1f)\n                                    .container(\n                                        shape = ShapeDefaults.circle,\n                                        color = color,\n                                        resultPadding = 0.dp\n                                    )\n                                    .transparencyChecker()\n                                    .background(color, ShapeDefaults.circle)\n                                    .hapticsClickable {\n                                        onRecentColorClick(color)\n                                    }\n                                    .animateItem(),\n                                contentAlignment = Alignment.Center\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.ContentPasteGo,\n                                    contentDescription = null,\n                                    tint = color.inverse(\n                                        fraction = {\n                                            if (it) 0.8f\n                                            else 0.5f\n                                        },\n                                        darkMode = color.luminance() < 0.3f\n                                    ),\n                                    modifier = Modifier\n                                        .size(24.dp)\n                                        .background(\n                                            color = color.copy(alpha = 1f),\n                                            shape = ShapeDefaults.circle\n                                        )\n                                        .padding(3.dp)\n                                )\n                            }\n                        }\n                        if (recentColors.size < possibleCount) {\n                            items(possibleCount - recentColors.size) {\n                                Box(\n                                    modifier = Modifier\n                                        .size(40.dp)\n                                        .clip(ShapeDefaults.circle)\n                                        .alpha(0.4f)\n                                        .transparencyChecker()\n                                        .animateItem()\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n            BoxAnimatedVisibility(favoriteColors.isNotEmpty()) {\n                Column {\n                    TitleItem(\n                        text = stringResource(R.string.favorite),\n                        icon = Icons.Rounded.BookmarkBorder,\n                        modifier = Modifier\n                    )\n                    Spacer(Modifier.height(12.dp))\n                    val favoriteState = rememberLazyListState()\n                    val possibleCount by remember(favoriteState, itemWidth) {\n                        derivedStateOf {\n                            (favoriteState.layoutInfo.viewportSize.width / itemWidth).roundToInt()\n                        }\n                    }\n                    val data = remember(favoriteColors) { mutableStateOf(favoriteColors) }\n                    val haptics = LocalHapticFeedback.current\n                    val reorderableState = rememberReorderableLazyListState(\n                        lazyListState = favoriteState,\n                        onMove = { from, to ->\n                            haptics.press()\n                            data.value = data.value.toMutableList().apply {\n                                add(to.index, removeAt(from.index))\n                            }\n                        }\n                    )\n                    LazyRow(\n                        state = favoriteState,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .fadingEdges(favoriteState),\n                        horizontalArrangement = Arrangement.spacedBy(8.dp),\n                        verticalAlignment = Alignment.CenterVertically,\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        items(\n                            items = data.value,\n                            key = { it.toArgb() }\n                        ) { color ->\n                            ReorderableItem(\n                                state = reorderableState,\n                                key = color.toArgb()\n                            ) { isDragging ->\n                                Box(\n                                    modifier = Modifier\n                                        .size(40.dp)\n                                        .aspectRatio(1f)\n                                        .scale(\n                                            animateFloatAsState(\n                                                if (!reorderableState.isAnyItemDragging || isDragging) 1f\n                                                else 0.8f\n                                            ).value\n                                        )\n                                        .container(\n                                            shape = ShapeDefaults.circle,\n                                            color = color,\n                                            resultPadding = 0.dp\n                                        )\n                                        .transparencyChecker()\n                                        .background(color, ShapeDefaults.circle)\n                                        .hapticsClickable {\n                                            onFavoriteColorClick(color)\n                                        }\n                                        .longPressDraggableHandle(\n                                            onDragStarted = {\n                                                haptics.longPress()\n                                            },\n                                            onDragStopped = {\n                                                scope.launch {\n                                                    interactor.updateFavoriteColors(data.value.map { it.toModel() })\n                                                }\n                                            }\n                                        )\n                                        .animateItem(),\n                                    contentAlignment = Alignment.Center\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.ContentPasteGo,\n                                        contentDescription = null,\n                                        tint = color.inverse(\n                                            fraction = {\n                                                if (it) 0.8f\n                                                else 0.5f\n                                            },\n                                            darkMode = color.luminance() < 0.3f\n                                        ),\n                                        modifier = Modifier\n                                            .size(24.dp)\n                                            .background(\n                                                color = color.copy(alpha = 1f),\n                                                shape = ShapeDefaults.circle\n                                            )\n                                            .padding(3.dp)\n                                    )\n                                }\n                            }\n                        }\n                        if (favoriteColors.size < possibleCount) {\n                            items(possibleCount - favoriteColors.size) {\n                                Box(\n                                    modifier = Modifier\n                                        .size(40.dp)\n                                        .clip(ShapeDefaults.circle)\n                                        .alpha(0.4f)\n                                        .transparencyChecker()\n                                        .animateItem()\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/FileReorderVerticalList.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport android.net.Uri\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Add\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.utils.sortedByType\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\nimport kotlin.random.Random\n\n\n@Composable\nfun FileReorderVerticalList(\n    files: List<Uri>?,\n    onReorder: (List<Uri>) -> Unit,\n    modifier: Modifier = Modifier\n        .container(\n            shape = ShapeDefaults.extraLarge,\n            clip = false\n        ),\n    onNeedToAddFile: () -> Unit,\n    onNeedToRemoveFileAt: (Int) -> Unit,\n    additionalInfo: (@Composable (Uri) -> String)? = {\n        val pages by rememberPdfPages(it)\n\n        \"$pages ${stringResource(R.string.pages_short)}\"\n    },\n    title: String = stringResource(R.string.files_order),\n    coerceHeight: Boolean = true\n) {\n    val data = remember { mutableStateOf(files ?: emptyList()) }\n\n    val haptics = LocalHapticFeedback.current\n    val listState = rememberLazyListState()\n\n    val state = rememberReorderableLazyListState(\n        lazyListState = listState,\n        onMove = { from, to ->\n            haptics.press()\n            data.value = data.value.toMutableList().apply {\n                add(to.index, removeAt(from.index))\n            }\n        }\n    )\n\n    LaunchedEffect(files) {\n        if (data.value.sorted() != files?.sorted()) {\n            data.value = files ?: emptyList()\n            listState.animateScrollToItem(data.value.lastIndex.coerceAtLeast(0))\n        }\n    }\n\n    Column(\n        modifier = modifier\n            .then(\n                if (coerceHeight) {\n                    Modifier\n                        .heightIn(\n                            max = LocalWindowInfo.current.containerDpSize.height * 0.7f\n                        )\n                } else {\n                    Modifier\n                }\n            ),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.Center,\n            modifier = Modifier\n                .padding(\n                    top = 16.dp,\n                    bottom = 8.dp,\n                    start = 16.dp,\n                    end = 8.dp\n                )\n        ) {\n            Text(\n                fontWeight = FontWeight.Medium,\n                text = title,\n                modifier = Modifier.weight(1f),\n                fontSize = 18.sp,\n            )\n            Spacer(Modifier.width(16.dp))\n            EnhancedIconButton(\n                onClick = onNeedToAddFile,\n                containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                contentColor = MaterialTheme.colorScheme.onSurfaceVariant,\n                forceMinimumInteractiveComponentSize = false,\n                modifier = Modifier\n                    .padding(start = 8.dp, end = 8.dp)\n                    .size(30.dp),\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Add,\n                    contentDescription = stringResource(R.string.add),\n                    modifier = Modifier.size(20.dp)\n                )\n            }\n\n            val scope = rememberCoroutineScope()\n            SortButton(\n                modifier = Modifier\n                    .padding(end = 8.dp)\n                    .size(30.dp),\n                onSortTypeSelected = { sortType ->\n                    scope.launch(Dispatchers.Default) {\n                        val newValue = files\n                            .orEmpty()\n                            .sortedByType(\n                                sortType = sortType\n                            )\n\n                        withContext(Dispatchers.Main.immediate) {\n                            data.value = newValue\n                            onReorder(newValue)\n                        }\n                    }\n                }\n            )\n        }\n        Box(\n            modifier = Modifier.weight(1f, false)\n        ) {\n            val showButton = (files?.size ?: 0) >= 2\n            LazyColumn(\n                state = listState,\n                modifier = Modifier\n                    .fadingEdges(\n                        scrollableState = listState,\n                        isVertical = true\n                    )\n                    .animateContentSizeNoClip(),\n                contentPadding = PaddingValues(12.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                itemsIndexed(\n                    items = data.value,\n                    key = { _, uri -> uri.toString() + uri.hashCode() }\n                ) { index, uri ->\n                    ReorderableItem(\n                        state = state,\n                        key = uri.toString() + uri.hashCode(),\n                    ) { isDragging ->\n                        val alpha by animateFloatAsState(if (isDragging) 0.3f else 0.6f)\n\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically,\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .scale(\n                                    animateFloatAsState(\n                                        if (isDragging) 1.05f\n                                        else 1f\n                                    ).value\n                                )\n                                .container(\n                                    color = MaterialTheme.colorScheme.surface,\n                                    resultPadding = 8.dp\n                                )\n                                .longPressDraggableHandle(\n                                    onDragStarted = {\n                                        haptics.longPress()\n                                    },\n                                    onDragStopped = {\n                                        onReorder(data.value)\n                                    }\n                                )\n                        ) {\n                            Box(\n                                modifier = Modifier\n                                    .height(80.dp)\n                                    .container(\n                                        shape = ShapeDefaults.small,\n                                        color = Color.Transparent,\n                                        resultPadding = 0.dp\n                                    )\n                                    .widthIn(max = 120.dp)\n                            ) {\n                                Picture(\n                                    model = uri,\n                                    modifier = Modifier\n                                        .fillMaxHeight()\n                                        .defaultMinSize(minWidth = 60.dp),\n                                    shape = RectangleShape,\n                                    contentScale = ContentScale.Fit\n                                )\n                                Box(\n                                    modifier = Modifier\n                                        .matchParentSize()\n                                        .background(\n                                            MaterialTheme.colorScheme\n                                                .surfaceContainer\n                                                .copy(alpha)\n                                        ),\n                                    contentAlignment = Alignment.Center\n                                ) {\n                                    Text(\n                                        text = \"${index + 1}\",\n                                        color = MaterialTheme.colorScheme.onSurface,\n                                        fontSize = 20.sp,\n                                        fontWeight = FontWeight.Bold\n                                    )\n                                }\n                            }\n                            Spacer(Modifier.width(16.dp))\n                            Column(\n                                modifier = Modifier.weight(1f)\n                            ) {\n                                Text(\n                                    text = rememberFilename(uri) ?: uri.toString(),\n                                    style = PreferenceItemDefaults.TitleFontStyle\n                                )\n                                Spacer(Modifier.height(4.dp))\n                                val size = rememberHumanFileSize(uri)\n                                Text(\n                                    text = additionalInfo?.let {\n                                        \"$size • ${additionalInfo(uri)}\"\n                                    } ?: size,\n                                    fontSize = 12.sp,\n                                    textAlign = TextAlign.Start,\n                                    fontWeight = FontWeight.Normal,\n                                    lineHeight = 14.sp,\n                                    color = LocalContentColor.current.copy(alpha = 0.5f)\n                                )\n                            }\n                            Spacer(Modifier.width(16.dp))\n                            BoxAnimatedVisibility(\n                                visible = showButton,\n                                enter = expandVertically(tween(300)) + fadeIn(),\n                                exit = shrinkVertically(tween(300)) + fadeOut()\n                            ) {\n                                EnhancedIconButton(\n                                    onClick = { onNeedToRemoveFileAt(index) },\n                                    containerColor = MaterialTheme.colorScheme.errorContainer.copy(\n                                        0.4f\n                                    ),\n                                    contentColor = MaterialTheme.colorScheme.onErrorContainer,\n                                    modifier = Modifier.padding(top = 4.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Outlined.Delete,\n                                        contentDescription = null\n                                    )\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\n@EnPreview\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    var files by remember {\n        mutableStateOf(\n            List(15) {\n                \"file:///uri_$it.pdf\".toUri()\n            }\n        )\n    }\n    LazyColumn {\n        item {\n            FileReorderVerticalList(\n                files = files,\n                onReorder = { files = it },\n                onNeedToAddFile = {\n                    files += \"file:///uri_TEST${Random.nextInt()}.pdf\".toUri()\n                },\n                additionalInfo = {\n                    \"30 pages\"\n                },\n                onNeedToRemoveFileAt = {\n                    files = files.toMutableList().apply { removeAt(it) }\n                }\n            )\n        }\n\n        items(30) {\n            Text(\"TEST $it\")\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/FormatExifWarning.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun FormatExifWarning(\n    imageFormat: ImageFormat?\n) {\n    AnimatedVisibility(\n        visible = imageFormat?.canWriteExif == false,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(12.dp)\n                .container(\n                    color = MaterialTheme.colorScheme.errorContainer.copy(\n                        alpha = 0.7f\n                    ),\n                    resultPadding = 0.dp,\n                    shape = ShapeDefaults.default\n                )\n        ) {\n            Text(\n                text = stringResource(R.string.image_exif_warning, imageFormat?.title ?: \"\"),\n                fontSize = 12.sp,\n                modifier = Modifier.padding(8.dp),\n                textAlign = TextAlign.Center,\n                fontWeight = FontWeight.SemiBold,\n                lineHeight = 14.sp,\n                color = MaterialTheme.colorScheme.onErrorContainer.copy(alpha = 0.5f)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/IcoSizeWarning.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun IcoSizeWarning(visible: Boolean) {\n    AnimatedVisibility(\n        visible = visible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Box(\n            modifier = Modifier\n                .padding(\n                    top = 12.dp\n                )\n                .container(\n                    color = MaterialTheme.colorScheme.secondaryContainer.copy(\n                        alpha = 0.7f\n                    ),\n                    resultPadding = 4.dp,\n                    shape = ShapeDefaults.default\n                )\n        ) {\n            Text(\n                text = stringResource(R.string.ico_size_warning),\n                fontSize = 12.sp,\n                modifier = Modifier.padding(8.dp),\n                textAlign = TextAlign.Center,\n                fontWeight = FontWeight.SemiBold,\n                lineHeight = 14.sp,\n                color = MaterialTheme.colorScheme.onSecondaryContainer.copy(alpha = 0.5f)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/ImageReorderCarousel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport android.net.Uri\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Add\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.shareUris\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagePager\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.utils.sortedByType\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\n\n@Composable\nfun ImageReorderCarousel(\n    images: List<Uri>?,\n    onReorder: (List<Uri>) -> Unit,\n    modifier: Modifier = Modifier\n        .container(ShapeDefaults.extraLarge),\n    onNeedToAddImage: () -> Unit,\n    onNeedToRemoveImageAt: (Int) -> Unit,\n    onNavigate: (Screen) -> Unit,\n    title: String = stringResource(R.string.images_order)\n) {\n    val data = remember { mutableStateOf(images ?: emptyList()) }\n\n    val context = LocalContext.current\n    val haptics = LocalHapticFeedback.current\n    val listState = rememberLazyListState()\n    val state = rememberReorderableLazyListState(\n        lazyListState = listState,\n        onMove = { from, to ->\n            haptics.press()\n            data.value = data.value.toMutableList().apply {\n                add(to.index, removeAt(from.index))\n            }\n        }\n    )\n\n    LaunchedEffect(images) {\n        if (data.value.sorted() != images?.sorted()) {\n            data.value = images ?: emptyList()\n            listState.animateScrollToItem(data.value.lastIndex.coerceAtLeast(0))\n        }\n    }\n\n    var previewUri by rememberSaveable {\n        mutableStateOf<Uri?>(null)\n    }\n\n    Column(\n        modifier = modifier,\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.Center,\n            modifier = Modifier.padding(top = 16.dp, bottom = 8.dp)\n        ) {\n            Text(\n                fontWeight = FontWeight.Medium,\n                text = title,\n                modifier = Modifier.padding(start = 8.dp),\n                fontSize = 18.sp\n            )\n            EnhancedIconButton(\n                onClick = onNeedToAddImage,\n                containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                contentColor = MaterialTheme.colorScheme.onSurfaceVariant,\n                forceMinimumInteractiveComponentSize = false,\n                modifier = Modifier\n                    .padding(start = 8.dp, end = 8.dp)\n                    .size(30.dp),\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Add,\n                    contentDescription = stringResource(R.string.add),\n                    modifier = Modifier.size(20.dp)\n                )\n            }\n\n            val scope = rememberCoroutineScope()\n            SortButton(\n                modifier = Modifier\n                    .padding(end = 8.dp)\n                    .size(30.dp),\n                onSortTypeSelected = { sortType ->\n                    scope.launch(Dispatchers.Default) {\n                        val newValue = images\n                            .orEmpty()\n                            .sortedByType(\n                                sortType = sortType\n                            )\n\n                        withContext(Dispatchers.Main.immediate) {\n                            data.value = newValue\n                            onReorder(newValue)\n                        }\n                    }\n                }\n            )\n        }\n        Box {\n            val showButton = (images?.size ?: 0) > 2 && !state.isAnyItemDragging\n            LazyRow(\n                state = listState,\n                modifier = Modifier\n                    .fadingEdges(scrollableState = listState)\n                    .animateContentSizeNoClip(),\n                contentPadding = PaddingValues(12.dp),\n                horizontalArrangement = Arrangement.spacedBy(8.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                itemsIndexed(\n                    items = data.value,\n                    key = { _, uri -> uri.toString() + uri.hashCode() }\n                ) { index, uri ->\n                    ReorderableItem(\n                        state = state,\n                        key = uri.toString() + uri.hashCode()\n                    ) { isDragging ->\n                        val alpha by animateFloatAsState(if (isDragging) 0.3f else 0.6f)\n                        val shape = animateShape(\n                            if (showButton) ShapeDefaults.top\n                            else ShapeDefaults.default\n                        )\n\n                        Column(\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            Box(\n                                modifier = Modifier\n                                    .size(120.dp)\n                                    .scale(\n                                        animateFloatAsState(\n                                            if (isDragging) 1.05f\n                                            else 1f\n                                        ).value\n                                    )\n                                    .container(\n                                        shape = shape,\n                                        color = Color.Transparent,\n                                        resultPadding = 0.dp\n                                    )\n                                    .hapticsClickable { previewUri = uri }\n                                    .longPressDraggableHandle(\n                                        onDragStarted = {\n                                            haptics.longPress()\n                                        },\n                                        onDragStopped = {\n                                            onReorder(data.value)\n                                        }\n                                    )\n                            ) {\n                                Picture(\n                                    model = uri,\n                                    modifier = Modifier.fillMaxSize(),\n                                    shape = RectangleShape,\n                                    contentScale = ContentScale.Fit\n                                )\n                                Box(\n                                    modifier = Modifier\n                                        .size(120.dp)\n                                        .background(\n                                            MaterialTheme.colorScheme\n                                                .surfaceContainer\n                                                .copy(alpha)\n                                        ),\n                                    contentAlignment = Alignment.Center\n                                ) {\n                                    Text(\n                                        text = \"${index + 1}\",\n                                        color = MaterialTheme.colorScheme.onSurface,\n                                        fontSize = 20.sp,\n                                        fontWeight = FontWeight.Bold\n                                    )\n                                }\n                            }\n                            BoxAnimatedVisibility(\n                                visible = showButton,\n                                enter = expandVertically(tween(300)) + fadeIn(),\n                                exit = shrinkVertically(tween(300)) + fadeOut(),\n                                modifier = Modifier.width(120.dp)\n                            ) {\n                                EnhancedButton(\n                                    contentPadding = PaddingValues(),\n                                    onClick = { onNeedToRemoveImageAt(index) },\n                                    containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(\n                                        0.5f\n                                    ),\n                                    contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                                    shape = ShapeDefaults.bottom,\n                                    modifier = Modifier\n                                        .padding(top = 4.dp)\n                                        .height(30.dp)\n                                        .width(120.dp)\n                                ) {\n                                    Text(stringResource(R.string.remove), fontSize = 11.sp)\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    ImagePager(\n        visible = previewUri != null,\n        selectedUri = previewUri,\n        uris = images,\n        onNavigate = onNavigate,\n        onUriSelected = { previewUri = it },\n        onShare = { context.shareUris(listOf(it)) },\n        onDismiss = { previewUri = null }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/ImageTransformBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateIntAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.RotateLeft\nimport androidx.compose.material.icons.automirrored.rounded.RotateRight\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.CropSmall\nimport com.t8rin.imagetoolbox.core.resources.icons.Curve\nimport com.t8rin.imagetoolbox.core.resources.icons.Draw\nimport com.t8rin.imagetoolbox.core.resources.icons.Eraser\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.resources.icons.Flip\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun ImageTransformBar(\n    onEditExif: () -> Unit = {},\n    imageFormat: ImageFormat? = null,\n    onRotateLeft: () -> Unit,\n    onFlip: () -> Unit,\n    onRotateRight: () -> Unit,\n    canRotate: Boolean = true,\n    leadingContent: @Composable RowScope.() -> Unit = {},\n) {\n    val shape = AutoCornersShape(\n        animateIntAsState(if (imageFormat?.canWriteExif == false) 20 else 50).value\n    )\n    Column(\n        modifier = Modifier\n            .container(shape)\n            .animateContentSizeNoClip()\n    ) {\n        Row(verticalAlignment = Alignment.CenterVertically) {\n            AnimatedVisibility(\n                visible = imageFormat != null,\n                modifier = Modifier.weight(1f, false)\n            ) {\n                Row {\n                    Spacer(Modifier.width(4.dp))\n                    EnhancedButton(\n                        modifier = Modifier.height(40.dp),\n                        containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                        contentPadding = PaddingValues(8.dp),\n                        onClick = onEditExif\n                    ) {\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically,\n                            horizontalArrangement = Arrangement.Center\n                        ) {\n                            Spacer(Modifier.width(4.dp))\n                            Icon(\n                                imageVector = Icons.Rounded.Exif,\n                                contentDescription = stringResource(R.string.edit_exif)\n                            )\n                            Spacer(Modifier.width(8.dp))\n                            Text(\n                                text = stringResource(R.string.edit_exif)\n                            )\n                            Spacer(Modifier.width(8.dp))\n                        }\n                    }\n                    Spacer(\n                        Modifier\n                            .weight(1f)\n                            .padding(4.dp)\n                    )\n                }\n            }\n\n            leadingContent()\n\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onRotateLeft,\n                enabled = canRotate\n            ) {\n                Icon(\n                    imageVector = Icons.AutoMirrored.Rounded.RotateLeft,\n                    contentDescription = \"Rotate Left\"\n                )\n            }\n\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onFlip\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.Flip,\n                    contentDescription = \"Flip\"\n                )\n            }\n\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onRotateRight,\n                enabled = canRotate\n            ) {\n                Icon(\n                    imageVector = Icons.AutoMirrored.Rounded.RotateRight,\n                    contentDescription = \"Rotate Right\"\n                )\n            }\n        }\n        FormatExifWarning(imageFormat)\n    }\n}\n\n@Composable\nfun ImageExtraTransformBar(\n    onCrop: () -> Unit,\n    onFilter: () -> Unit,\n    onDraw: () -> Unit,\n    onEraseBackground: () -> Unit,\n    onApplyCurves: () -> Unit\n) {\n    if (LocalSettingsState.current.generatePreviews) {\n        Row(Modifier.container(shape = ShapeDefaults.circle)) {\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.mixedContainer.copy(0.6f),\n                contentColor = MaterialTheme.colorScheme.onMixedContainer,\n                onClick = onCrop\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.CropSmall,\n                    contentDescription = stringResource(R.string.crop)\n                )\n            }\n\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.mixedContainer.copy(0.6f),\n                contentColor = MaterialTheme.colorScheme.onMixedContainer,\n                onClick = onApplyCurves\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.Curve,\n                    contentDescription = stringResource(R.string.tone_curves)\n                )\n            }\n\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.mixedContainer.copy(0.6f),\n                contentColor = MaterialTheme.colorScheme.onMixedContainer,\n                onClick = onFilter\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.AutoFixHigh,\n                    contentDescription = stringResource(R.string.filter)\n                )\n            }\n\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.mixedContainer.copy(0.6f),\n                contentColor = MaterialTheme.colorScheme.onMixedContainer,\n                onClick = onDraw\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Draw,\n                    contentDescription = stringResource(R.string.draw)\n                )\n            }\n\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.mixedContainer.copy(0.6f),\n                contentColor = MaterialTheme.colorScheme.onMixedContainer,\n                onClick = onEraseBackground\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Eraser,\n                    contentDescription = stringResource(R.string.erase_background)\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/OOMWarning.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun OOMWarning(\n    visible: Boolean,\n    modifier: Modifier = Modifier.padding(\n        top = 12.dp\n    )\n) {\n    AnimatedVisibility(\n        visible = visible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column(\n            modifier = modifier\n                .container(\n                    color = MaterialTheme.colorScheme.errorContainer.copy(\n                        alpha = 0.7f\n                    ),\n                    resultPadding = 0.dp,\n                    shape = ShapeDefaults.default\n                )\n        ) {\n            Text(\n                text = stringResource(R.string.image_size_warning),\n                fontSize = 12.sp,\n                modifier = Modifier.padding(8.dp),\n                textAlign = TextAlign.Center,\n                fontWeight = FontWeight.SemiBold,\n                lineHeight = 14.sp,\n                color = MaterialTheme.colorScheme.onErrorContainer.copy(alpha = 0.5f)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/ResizeImageField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsFocusedAsState\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Calculate\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.restrict\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.CalculatorDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\n\n@Composable\nfun ResizeImageField(\n    imageInfo: ImageInfo,\n    originalSize: IntegerSize?,\n    onWidthChange: (Int) -> Unit,\n    onHeightChange: (Int) -> Unit,\n    modifier: Modifier = Modifier,\n    showWarning: Boolean = false,\n    enabled: Boolean = true,\n) {\n    Column(\n        modifier = modifier\n            .container(shape = ShapeDefaults.extraLarge)\n            .padding(8.dp)\n            .animateContentSizeNoClip()\n    ) {\n        Row {\n            val widthField: @Composable RowScope.() -> Unit = {\n                ResizeImageFieldImpl(\n                    value = imageInfo.width.takeIf { it > 0 }\n                        .let { it ?: \"\" }\n                        .toString(),\n                    onValueChange = { value ->\n                        val maxValue = if (imageInfo.height > 0) {\n                            (ImageUtils.Dimens.MAX_IMAGE_SIZE / imageInfo.height).coerceAtMost(32768)\n                        } else 32768\n\n                        onWidthChange(\n                            value\n                                .restrict(maxValue)\n                                .toIntOrNull() ?: 0\n                        )\n                    },\n                    shape = ShapeDefaults.smallStart,\n                    label = {\n                        AutoSizeText(\n                            stringResource(\n                                R.string.width,\n                                originalSize?.width?.toString() ?: \"\"\n                            )\n                        )\n                    },\n                    modifier = Modifier.weight(1f),\n                    enabled = enabled\n                )\n            }\n            val heightField: @Composable RowScope.() -> Unit = {\n                ResizeImageFieldImpl(\n                    value = imageInfo.height.takeIf { it > 0 }\n                        .let { it ?: \"\" }\n                        .toString(),\n                    onValueChange = { value ->\n                        val maxValue = if (imageInfo.width > 0) {\n                            (ImageUtils.Dimens.MAX_IMAGE_SIZE / imageInfo.width).coerceAtMost(32768)\n                        } else 32768\n\n                        onHeightChange(\n                            value\n                                .restrict(maxValue)\n                                .toIntOrNull() ?: 0\n                        )\n                    },\n                    shape = ShapeDefaults.smallEnd,\n                    label = {\n                        AutoSizeText(\n                            stringResource(\n                                R.string.height,\n                                originalSize?.height?.toString()\n                                    ?: \"\"\n                            )\n                        )\n                    },\n                    modifier = Modifier.weight(1f),\n                    enabled = enabled\n                )\n            }\n\n            widthField()\n            Spacer(modifier = Modifier.width(4.dp))\n            heightField()\n        }\n        IcoSizeWarning(\n            visible = imageInfo.run {\n                imageFormat == ImageFormat.Ico && (width > 256 || height > 256)\n            }\n        )\n        OOMWarning(visible = showWarning)\n    }\n}\n\n@Composable\ninternal fun ResizeImageFieldImpl(\n    modifier: Modifier,\n    value: String,\n    onValueChange: (String) -> Unit,\n    label: @Composable () -> Unit,\n    shape: Shape,\n    enabled: Boolean\n) {\n    val interactionSource = remember { MutableInteractionSource() }\n    val isFocused by interactionSource.collectIsFocusedAsState()\n\n    var showCalculator by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    RoundedTextField(\n        value = value,\n        onValueChange = onValueChange,\n        shape = shape,\n        keyboardOptions = KeyboardOptions(\n            keyboardType = KeyboardType.Number\n        ),\n        label = label,\n        endIcon = {\n            AnimatedVisibility(\n                visible = isFocused,\n                enter = scaleIn() + fadeIn(),\n                exit = scaleOut() + fadeOut()\n            ) {\n                EnhancedIconButton(\n                    onClick = {\n                        showCalculator = true\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Calculate,\n                        contentDescription = null\n                    )\n                }\n            }\n        },\n        modifier = modifier,\n        interactionSource = interactionSource,\n        enabled = enabled\n    )\n\n    CalculatorDialog(\n        visible = showCalculator,\n        onDismiss = { showCalculator = false },\n        initialValue = value.toBigDecimalOrNull(),\n        onValueChange = { onValueChange(it.toInt().toString()) }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/SaveExifWidget.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun SaveExifWidget(\n    checked: Boolean,\n    imageFormat: ImageFormat,\n    onCheckedChange: (Boolean) -> Unit,\n    modifier: Modifier = Modifier,\n    backgroundColor: Color = Color.Unspecified\n) {\n    val settingsState = LocalSettingsState.current\n    LaunchedEffect(Unit) {\n        onCheckedChange(settingsState.exifWidgetInitialState)\n    }\n    PreferenceRowSwitch(\n        modifier = modifier,\n        title = stringResource(R.string.keep_exif),\n        subtitle = if (imageFormat.canWriteExif) {\n            stringResource(R.string.keep_exif_sub)\n        } else {\n            stringResource(\n                R.string.image_exif_warning,\n                imageFormat.title\n            )\n        },\n        checked = checked,\n        enabled = imageFormat.canWriteExif,\n        shape = ShapeDefaults.extraLarge,\n        containerColor = backgroundColor,\n        onClick = onCheckedChange,\n        startIcon = Icons.Outlined.Exif\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/ScaleSmallImagesToLargeToggle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.LinearScale\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ScaleSmallImagesToLargeToggle(\n    modifier: Modifier = Modifier,\n    checked: Boolean,\n    onCheckedChange: (Boolean) -> Unit\n) {\n    PreferenceRowSwitch(\n        modifier = modifier,\n        title = stringResource(R.string.scale_small_images_to_large),\n        subtitle = stringResource(R.string.scale_small_images_to_large_sub),\n        checked = checked,\n        containerColor = Color.Unspecified,\n        shape = ShapeDefaults.extraLarge,\n        onClick = onCheckedChange,\n        startIcon = Icons.Rounded.LinearScale\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/SortButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FilterAlt\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.SortType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun SortButton(\n    modifier: Modifier = Modifier,\n    iconSize: Dp = 20.dp,\n    containerColor: Color = MaterialTheme.colorScheme.surfaceContainerHighest,\n    contentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,\n    onSortTypeSelected: (SortType) -> Unit\n) {\n    var showSortTypeSelection by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    EnhancedIconButton(\n        onClick = {\n            showSortTypeSelection = true\n        },\n        containerColor = containerColor,\n        contentColor = contentColor,\n        forceMinimumInteractiveComponentSize = false,\n        modifier = modifier\n    ) {\n        Icon(\n            imageVector = Icons.Rounded.FilterAlt,\n            contentDescription = stringResource(R.string.sorting),\n            modifier = Modifier.size(iconSize)\n        )\n    }\n\n    EnhancedModalBottomSheet(\n        visible = showSortTypeSelection,\n        onDismiss = { showSortTypeSelection = it },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.sorting),\n                icon = Icons.Rounded.FilterAlt\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showSortTypeSelection = false\n                },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(8.dp),\n            verticalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            val items = SortType.entries\n\n            items.forEachIndexed { index, item ->\n                Column(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = items.size\n                            ),\n                            resultPadding = 0.dp\n                        )\n                        .hapticsClickable {\n                            onSortTypeSelected(item)\n                            showSortTypeSelection = false\n                        }\n                ) {\n                    TitleItem(text = item.title)\n                }\n            }\n        }\n    }\n}\n\nprivate val SortType.title: String\n    @Composable\n    get() = when (this) {\n        SortType.DateModified -> stringResource(R.string.sort_by_date_modified)\n        SortType.DateModifiedReversed -> stringResource(R.string.sort_by_date_modified_reversed)\n        SortType.Name -> stringResource(R.string.sort_by_name)\n        SortType.NameReversed -> stringResource(R.string.sort_by_name_reversed)\n        SortType.Size -> stringResource(R.string.sort_by_size)\n        SortType.SizeReversed -> stringResource(R.string.sort_by_size_reversed)\n        SortType.MimeType -> stringResource(R.string.sort_by_mime_type)\n        SortType.MimeTypeReversed -> stringResource(R.string.sort_by_mime_type_reversed)\n        SortType.Extension -> stringResource(R.string.sort_by_extension)\n        SortType.ExtensionReversed -> stringResource(R.string.sort_by_extension_reversed)\n        SortType.DateAdded -> stringResource(R.string.sort_by_date_added)\n        SortType.DateAddedReversed -> stringResource(R.string.sort_by_date_added_reversed)\n    }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/page/PageInputDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.page\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Pages\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\n\n@Composable\nfun PageInputDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    value: List<Int>?,\n    onValueChange: (List<Int>) -> Unit,\n    pagesCount: Int\n) {\n    var pages by rememberSaveable(visible) {\n        mutableStateOf(value ?: emptyList())\n    }\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        title = {\n            Text(stringResource(R.string.pages_selection))\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Rounded.Pages,\n                contentDescription = null\n            )\n        },\n        text = {\n            PageInputField(\n                selectedPages = pages,\n                onPagesChanged = { pages = it }\n            )\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    onValueChange(pages.filter { it < pagesCount })\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(R.string.apply))\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/page/PageInputField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.page\n\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\n\n@Composable\ninternal fun PageInputField(\n    selectedPages: List<Int>,\n    onPagesChanged: (List<Int>) -> Unit\n) {\n    var text by remember {\n        mutableStateOf(PagesSelectionParser.formatPageOutput(selectedPages))\n    }\n\n    RoundedTextField(\n        value = text,\n        onValueChange = {\n            text = it\n            val parsedPages = PagesSelectionParser.parsePageInput(it)\n            onPagesChanged(parsedPages)\n        },\n        textStyle = LocalTextStyle.current.copy(\n            textAlign = TextAlign.Start\n        ),\n        label = stringResource(R.string.custom_pages),\n        modifier = Modifier\n            .container(\n                shape = MaterialTheme.shapes.large,\n                resultPadding = 8.dp\n            ),\n        singleLine = false\n    )\n}\n\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/page/PageSelectionItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.page\n\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Pages\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun PageSelectionItem(\n    value: List<Int>?,\n    onValueChange: (List<Int>) -> Unit,\n    pageCount: Int\n) {\n    var showSelector by rememberSaveable {\n        mutableStateOf(false)\n    }\n    PreferenceItem(\n        title = stringResource(R.string.pages_selection),\n        subtitle = remember(value, pageCount) {\n            derivedStateOf {\n                value?.takeIf { it.isNotEmpty() }\n                    ?.let {\n                        if (it.size == pageCount) {\n                            getString(R.string.all)\n                        } else {\n                            PagesSelectionParser.formatPageOutput(it)\n                        }\n                    } ?: getString(R.string.none)\n            }\n        }.value,\n        onClick = {\n            showSelector = true\n        },\n        modifier = Modifier.fillMaxWidth(),\n        startIcon = Icons.Rounded.Pages,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n    PageInputDialog(\n        visible = showSelector,\n        onDismiss = { showSelector = false },\n        value = value,\n        onValueChange = onValueChange,\n        pagesCount = pageCount\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/page/PagesSelectionParser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.page\n\ninternal object PagesSelectionParser {\n\n    fun parsePageInput(input: String): List<Int> {\n        val pages = mutableSetOf<Int>()\n        val regex = \"\\\\d+(-\\\\d+)?\".toRegex()\n        regex.findAll(input).forEach { match ->\n            val rangeParts = match.value.split(\"-\").mapNotNull { it.toIntOrNull() }\n            when (rangeParts.size) {\n                1 -> pages.add(rangeParts[0] - 1)\n                2 -> if (rangeParts[0] <= rangeParts[1]) {\n                    pages.addAll((rangeParts[0] - 1)..<rangeParts[1])\n                }\n            }\n        }\n        return pages.sorted()\n    }\n\n    fun formatPageOutput(pages: List<Int>): String {\n        if (pages.isEmpty()) return \"\"\n        val pages = pages.sorted()\n        val result = mutableListOf<String>()\n        var start = pages[0]\n        var prev = pages[0]\n        for (i in 1 until pages.size) {\n            if (pages[i] != prev + 1) {\n                result.add(if (start == prev) \"${start + 1}\" else \"${start + 1}-${prev + 1}\")\n                start = pages[i]\n            }\n            prev = pages[i]\n        }\n        result.add(if (start == prev) \"${start + 1}\" else \"${start + 1}-${prev + 1}\")\n        return result.joinToString(\", \")\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/resize_group/ResizeTypeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeAnchor\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.state.derivedValueOf\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group.components.BlurRadiusSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group.components.UseBlurredBackgroundToggle\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PositionSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n\n@Composable\nfun ResizeTypeSelector(\n    modifier: Modifier = Modifier,\n    enabled: Boolean,\n    value: ResizeType,\n    onValueChange: (ResizeType) -> Unit,\n) {\n    var isSheetVisible by rememberSaveable { mutableStateOf(false) }\n    var canvasColor by rememberSaveable(stateSaver = ColorSaver) {\n        mutableStateOf(Color.Transparent)\n    }\n    var useBlurredBgInsteadOfColor by rememberSaveable {\n        mutableStateOf(true)\n    }\n    var blurRadius by rememberSaveable {\n        mutableIntStateOf(35)\n    }\n    var position by rememberSaveable {\n        mutableStateOf(Position.Center)\n    }\n\n    val centerCropResizeType by remember(\n        canvasColor,\n        useBlurredBgInsteadOfColor,\n        blurRadius,\n        position\n    ) {\n        derivedStateOf {\n            ResizeType.CenterCrop(\n                canvasColor = canvasColor.toArgb()\n                    .takeIf { !useBlurredBgInsteadOfColor },\n                blurRadius = blurRadius,\n                position = position\n            )\n        }\n    }\n    val updateCropResizeType = {\n        onValueChange(centerCropResizeType)\n    }\n\n    val fitResizeType by remember(\n        canvasColor,\n        useBlurredBgInsteadOfColor,\n        blurRadius,\n        position\n    ) {\n        derivedStateOf {\n            ResizeType.Fit(\n                canvasColor = canvasColor.toArgb()\n                    .takeIf { !useBlurredBgInsteadOfColor },\n                blurRadius = blurRadius,\n                position = position\n            )\n        }\n    }\n    val updateFitResizeType = {\n        onValueChange(fitResizeType)\n    }\n\n    Column(\n        modifier = modifier\n            .container(shape = ShapeDefaults.extraLarge)\n            .animateContentSizeNoClip(),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        EnhancedButtonGroup(\n            modifier = Modifier.padding(start = 3.dp, end = 2.dp),\n            enabled = enabled,\n            title = {\n                Column {\n                    Spacer(modifier = Modifier.height(8.dp))\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.Center\n                    ) {\n                        Text(\n                            text = stringResource(R.string.resize_type),\n                            textAlign = TextAlign.Center,\n                            fontWeight = FontWeight.Medium\n                        )\n                        Spacer(modifier = Modifier.width(8.dp))\n                        SupportingButton(\n                            onClick = {\n                                isSheetVisible = true\n                            }\n                        )\n                    }\n                    Spacer(modifier = Modifier.height(8.dp))\n                }\n            },\n            itemCount = ResizeType.entries.size,\n            selectedIndex = derivedValueOf(value) {\n                ResizeType.entries.indexOfFirst { it::class.isInstance(value) }\n            },\n            onIndexChange = {\n                onValueChange(\n                    when (it) {\n                        0 -> ResizeType.Explicit\n                        1 -> ResizeType.Flexible\n                        2 -> centerCropResizeType\n                        3 -> fitResizeType\n                        else -> ResizeType.Explicit\n                    }\n                )\n            },\n            itemContent = {\n                Text(stringResource(ResizeType.entries[it].getTitle()))\n            }\n        )\n        AnimatedVisibility(\n            visible = value is ResizeType.Flexible,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            val entries = remember {\n                ResizeAnchor.entries\n            }\n            val selectedIndex by remember(entries, value) {\n                derivedStateOf {\n                    entries.indexOfFirst {\n                        it == (value as? ResizeType.Flexible)?.resizeAnchor\n                    }\n                }\n            }\n            EnhancedButtonGroup(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(8.dp)\n                    .container(\n                        shape = ShapeDefaults.default,\n                        color = MaterialTheme.colorScheme.surface\n                    ),\n                itemCount = entries.size,\n                selectedIndex = selectedIndex,\n                itemContent = {\n                    Text(entries[it].title)\n                },\n                onIndexChange = {\n                    onValueChange(\n                        ResizeType.Flexible(entries[it])\n                    )\n                },\n                title = {\n                    Text(\n                        text = stringResource(R.string.resize_anchor),\n                        textAlign = TextAlign.Center,\n                        fontWeight = FontWeight.Medium,\n                        modifier = Modifier\n                            .weight(1f)\n                            .padding(8.dp)\n                    )\n                },\n                inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer\n            )\n        }\n        AnimatedVisibility(\n            visible = value is ResizeType.CenterCrop,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            Column(\n                modifier = Modifier.padding(8.dp)\n            ) {\n                PositionSelector(\n                    value = position,\n                    onValueChange = {\n                        position = it\n                        updateCropResizeType()\n                    },\n                    shape = ShapeDefaults.top,\n                    color = MaterialTheme.colorScheme.surface\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                UseBlurredBackgroundToggle(\n                    checked = useBlurredBgInsteadOfColor,\n                    onCheckedChange = {\n                        useBlurredBgInsteadOfColor = it\n                        updateCropResizeType()\n                    },\n                    shape = ShapeDefaults.center\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                AnimatedContent(targetState = useBlurredBgInsteadOfColor) { showBlurRadius ->\n                    if (showBlurRadius) {\n                        BlurRadiusSelector(\n                            modifier = Modifier,\n                            value = blurRadius,\n                            color = MaterialTheme.colorScheme.surface,\n                            onValueChange = {\n                                blurRadius = it\n                                updateCropResizeType()\n                            },\n                            shape = ShapeDefaults.bottom\n                        )\n                    } else {\n                        ColorRowSelector(\n                            modifier = Modifier\n                                .container(\n                                    shape = ShapeDefaults.bottom,\n                                    color = MaterialTheme.colorScheme.surface\n                                ),\n                            value = canvasColor,\n                            onValueChange = {\n                                canvasColor = it\n                                updateCropResizeType()\n                            }\n                        )\n                    }\n                }\n            }\n        }\n        AnimatedVisibility(\n            visible = value is ResizeType.Fit,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            Column(\n                modifier = Modifier.padding(8.dp)\n            ) {\n                PositionSelector(\n                    value = position,\n                    onValueChange = {\n                        position = it\n                        updateFitResizeType()\n                    },\n                    shape = ShapeDefaults.top,\n                    color = MaterialTheme.colorScheme.surface\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                UseBlurredBackgroundToggle(\n                    checked = useBlurredBgInsteadOfColor,\n                    onCheckedChange = {\n                        useBlurredBgInsteadOfColor = it\n                        updateFitResizeType()\n                    },\n                    shape = ShapeDefaults.center\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                AnimatedContent(targetState = useBlurredBgInsteadOfColor) { showBlurRadius ->\n                    if (showBlurRadius) {\n                        BlurRadiusSelector(\n                            modifier = Modifier,\n                            value = blurRadius,\n                            color = MaterialTheme.colorScheme.surface,\n                            onValueChange = {\n                                blurRadius = it\n                                updateFitResizeType()\n                            },\n                            shape = ShapeDefaults.bottom\n                        )\n                    } else {\n                        ColorRowSelector(\n                            modifier = Modifier\n                                .container(\n                                    shape = ShapeDefaults.bottom,\n                                    color = MaterialTheme.colorScheme.surface\n                                ),\n                            value = canvasColor,\n                            onValueChange = {\n                                canvasColor = it\n                                updateFitResizeType()\n                            }\n                        )\n                    }\n                }\n            }\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Column(\n                modifier = Modifier\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(8.dp),\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                ResizeType.entries.forEachIndexed { index, item ->\n                    Column(\n                        Modifier\n                            .fillMaxWidth()\n                            .container(\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = ResizeType.entries.size\n                                ),\n                                resultPadding = 0.dp\n                            )\n                    ) {\n                        TitleItem(text = stringResource(item.getTitle()))\n                        Text(\n                            text = stringResource(item.getSubtitle()),\n                            modifier = Modifier.padding(\n                                start = 16.dp,\n                                end = 16.dp,\n                                bottom = 16.dp\n                            ),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                }\n            }\n        },\n        visible = isSheetVisible,\n        onDismiss = {\n            isSheetVisible = it\n        },\n        title = {\n            TitleItem(text = stringResource(R.string.resize_type))\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { isSheetVisible = false }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}\n\nprivate val ResizeAnchor.title: String\n    @Composable\n    get() = when (this) {\n        ResizeAnchor.Min -> stringResource(R.string.min)\n        ResizeAnchor.Max -> stringResource(R.string.max)\n        ResizeAnchor.Width -> stringResource(R.string.width, \"\")\n        ResizeAnchor.Height -> stringResource(R.string.height, \"\")\n        ResizeAnchor.Default -> stringResource(R.string.basic, \"\")\n    }\n\nprivate fun ResizeType.getTitle(): Int = when (this) {\n    is ResizeType.CenterCrop -> R.string.crop\n    is ResizeType.Explicit -> R.string.explicit\n    is ResizeType.Flexible -> R.string.flexible\n    is ResizeType.Fit -> R.string.fit\n}\n\nprivate fun ResizeType.getSubtitle(): Int = when (this) {\n    is ResizeType.CenterCrop -> R.string.crop_description\n    is ResizeType.Explicit -> R.string.explicit_description\n    is ResizeType.Flexible -> R.string.flexible_description\n    is ResizeType.Fit -> R.string.fit_description\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/resize_group/components/BlurRadiusSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BlurCircular\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlin.math.roundToInt\n\n@Composable\nfun BlurRadiusSelector(\n    modifier: Modifier,\n    value: Int,\n    color: Color = MaterialTheme.colorScheme.surfaceContainer,\n    valueRange: ClosedFloatingPointRange<Float> = 5f..100f,\n    onValueChange: (Int) -> Unit,\n    shape: Shape = ShapeDefaults.default\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        title = stringResource(R.string.blur_radius),\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        icon = Icons.Rounded.BlurCircular,\n        valueRange = valueRange,\n        internalStateTransformation = {\n            it.roundToInt()\n        },\n        onValueChange = {\n            onValueChange(it.roundToInt())\n        },\n        shape = shape,\n        containerColor = color\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/resize_group/components/UseBlurredBackgroundToggle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BlurLinear\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun UseBlurredBackgroundToggle(\n    modifier: Modifier = Modifier,\n    checked: Boolean,\n    onCheckedChange: (Boolean) -> Unit,\n    shape: Shape = ShapeDefaults.default\n) {\n    PreferenceRowSwitch(\n        modifier = modifier,\n        title = stringResource(R.string.blur_edges),\n        subtitle = stringResource(R.string.blur_edges_sub),\n        checked = checked,\n        shape = shape,\n        containerColor = MaterialTheme.colorScheme.surface,\n        onClick = onCheckedChange,\n        startIcon = Icons.Rounded.BlurLinear\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/AlphaSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Opacity\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun AlphaSelector(\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    onValueChangeFinished: ((Float) -> Unit)? = null,\n    modifier: Modifier = Modifier,\n    color: Color = Color.Unspecified,\n    shape: Shape = ShapeDefaults.extraLarge,\n    title: String = stringResource(R.string.paint_alpha),\n    icon: ImageVector = Icons.Rounded.Opacity\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        icon = icon,\n        title = title,\n        sliderModifier = Modifier\n            .padding(top = 14.dp, start = 12.dp, end = 12.dp, bottom = 10.dp),\n        valueRange = 0f..1f,\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        onValueChange = {\n            onValueChange(it.roundToTwoDigits())\n        },\n        onValueChangeFinished = onValueChangeFinished,\n        shape = shape,\n        containerColor = color\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/BlendingModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Layers\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.entries\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun BlendingModeSelector(\n    value: BlendingMode,\n    onValueChange: (BlendingMode) -> Unit,\n    entries: List<BlendingMode> = remember {\n        mutableListOf<BlendingMode>().apply {\n            add(BlendingMode.SrcOver)\n            addAll(\n                BlendingMode\n                    .entries\n                    .toList() - listOf(\n                    BlendingMode.SrcOver,\n                    BlendingMode.Clear,\n                    BlendingMode.Src,\n                    BlendingMode.Dst\n                ).toSet()\n            )\n        }\n    },\n    modifier: Modifier = Modifier,\n    shape: Shape = ShapeDefaults.large,\n    color: Color = MaterialTheme.colorScheme.surface\n) {\n    DataSelector(\n        value = value,\n        onValueChange = onValueChange,\n        entries = entries,\n        title = stringResource(R.string.overlay_mode),\n        titleIcon = Icons.Outlined.Layers,\n        itemContentText = { it.toString() },\n        modifier = modifier,\n        shape = shape,\n        containerColor = color\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/ColorRowSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Palette\nimport androidx.compose.material.icons.outlined.PushPin\nimport androidx.compose.material.icons.rounded.Block\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.RichTooltip\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TooltipAnchorPosition\nimport androidx.compose.material3.TooltipBox\nimport androidx.compose.material3.TooltipDefaults\nimport androidx.compose.material3.rememberTooltipState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRow\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.launch\n\n@Composable\nfun ColorRowSelector(\n    value: Color?,\n    onValueChange: (Color) -> Unit,\n    modifier: Modifier = Modifier,\n    title: String = stringResource(R.string.background_color),\n    icon: ImageVector? = Icons.Outlined.Palette,\n    allowAlpha: Boolean = true,\n    allowScroll: Boolean = true,\n    defaultColors: List<Color> = ColorSelectionRowDefaults.colorListVariant,\n    topEndIcon: (@Composable () -> Unit)? = null,\n    contentHorizontalPadding: Dp = 12.dp,\n    onNullClick: (() -> Unit)? = null\n) {\n    val isCompactLayout = LocalSettingsState.current.isCompactSelectorsLayout\n    val tooltipState = rememberTooltipState()\n    val scope = rememberCoroutineScope()\n\n    Column(\n        modifier = modifier.then(\n            if (isCompactLayout && icon != null) {\n                Modifier.pointerInput(Unit) {\n                    detectTapGestures(\n                        onLongPress = {\n                            scope.launch {\n                                tooltipState.show()\n                            }\n                        }\n                    )\n                }\n            } else Modifier\n        ),\n    ) {\n        if (!isCompactLayout) {\n            TitleItem(\n                icon = icon,\n                text = title,\n                iconEndPadding = 14.dp,\n                modifier = Modifier.padding(\n                    top = if (topEndIcon == null) {\n                        12.dp\n                    } else {\n                        6.dp\n                    },\n                    start = contentHorizontalPadding,\n                    end = if (topEndIcon == null) {\n                        contentHorizontalPadding\n                    } else {\n                        (contentHorizontalPadding - 8.dp).coerceAtLeast(0.dp)\n                    }\n                ),\n                endContent = topEndIcon?.let {\n                    { it() }\n                }\n            )\n        }\n        Row(\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            if (isCompactLayout) {\n                Box {\n                    AnimatedContent(icon) { icon ->\n                        if (icon != null) {\n                            TooltipBox(\n                                positionProvider = TooltipDefaults.rememberTooltipPositionProvider(\n                                    TooltipAnchorPosition.Above\n                                ),\n                                tooltip = {\n                                    RichTooltip(\n                                        colors = TooltipDefaults.richTooltipColors(\n                                            containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                            contentColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(\n                                                0.5f\n                                            ),\n                                            titleContentColor = MaterialTheme.colorScheme.onTertiaryContainer\n                                        ),\n                                        title = { Text(title) },\n                                        text = {\n                                            if (value != null) {\n                                                Box(\n                                                    modifier = Modifier\n                                                        .size(24.dp)\n                                                        .container(\n                                                            shape = ShapeDefaults.circle,\n                                                            color = value,\n                                                            resultPadding = 0.dp\n                                                        )\n                                                )\n                                            } else {\n                                                Icon(\n                                                    imageVector = Icons.Rounded.Block,\n                                                    contentDescription = null,\n                                                    modifier = Modifier\n                                                        .size(24.dp)\n                                                        .container(\n                                                            shape = ShapeDefaults.circle,\n                                                            color = MaterialTheme.colorScheme.surfaceVariant,\n                                                            resultPadding = 0.dp\n                                                        ),\n                                                    tint = MaterialTheme.colorScheme.onSurfaceVariant\n                                                )\n                                            }\n                                        }\n                                    )\n                                },\n                                state = tooltipState,\n                                content = {\n                                    IconShapeContainer(\n                                        content = {\n                                            Icon(\n                                                imageVector = icon,\n                                                contentDescription = null\n                                            )\n                                        },\n                                        modifier = Modifier\n                                            .padding(\n                                                start = contentHorizontalPadding\n                                            )\n                                            .clip(\n                                                LocalSettingsState.current.iconShape?.shape\n                                                    ?: ShapeDefaults.circle\n                                            )\n                                            .hapticsCombinedClickable(\n                                                onLongClick = {\n                                                    scope.launch { tooltipState.show() }\n                                                },\n                                                onClick = {\n                                                    scope.launch { tooltipState.show() }\n                                                }\n                                            )\n                                    )\n                                }\n                            )\n                        }\n                    }\n                    BoxAnimatedVisibility(icon == null) {\n                        Text(\n                            text = title,\n                            modifier = Modifier\n                                .padding(\n                                    start = contentHorizontalPadding\n                                )\n                                .widthIn(max = 100.dp),\n                            style = MaterialTheme.typography.bodyMedium,\n                            lineHeight = 16.sp\n                        )\n                    }\n                }\n                Spacer(Modifier.width(12.dp))\n            }\n            ColorSelectionRow(\n                defaultColors = defaultColors,\n                allowAlpha = allowAlpha,\n                contentPadding = PaddingValues(\n                    start = if (isCompactLayout) 0.dp else contentHorizontalPadding,\n                    end = contentHorizontalPadding\n                ),\n                allowScroll = allowScroll,\n                value = value,\n                onValueChange = onValueChange,\n                modifier = Modifier.weight(1f),\n                onNullClick = onNullClick\n            )\n            if (isCompactLayout && topEndIcon != null) {\n                topEndIcon()\n            }\n        }\n    }\n}\n\n@Composable\n@Preview\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    var color by remember {\n        mutableStateOf<Color?>(null)\n    }\n\n    CompositionLocalProvider(\n        LocalSettingsState provides LocalSettingsState.current.copy(isCompactSelectorsLayout = true)\n    ) {\n        ColorRowSelector(\n            value = color,\n            onNullClick = {\n                color = null\n            },\n            onValueChange = { color = it },\n            modifier = Modifier\n                .padding(20.dp)\n                .padding(vertical = 100.dp)\n                .fillMaxWidth()\n                .container(\n                    shape = ShapeDefaults.large\n                ),\n            icon = Icons.Rounded.Palette,\n            title = stringResource(R.string.selected_color),\n            topEndIcon = {\n                EnhancedIconButton(\n                    onClick = {}\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.PushPin,\n                        contentDescription = null\n                    )\n                }\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/DataSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.delay\n\n@Composable\nfun <T : Any> DataSelector(\n    value: T,\n    onValueChange: (T) -> Unit,\n    entries: List<T>,\n    title: String?,\n    titleIcon: ImageVector?,\n    itemContentText: @Composable (T) -> String,\n    itemContentIcon: ((T, Boolean) -> ImageVector?)? = null,\n    itemEqualityDelegate: (T, T) -> Boolean = { t, o -> t == o },\n    spanCount: Int = 3,\n    modifier: Modifier = Modifier,\n    badgeContent: (@Composable RowScope.() -> Unit)? = null,\n    shape: Shape = ShapeDefaults.large,\n    containerColor: Color = Color.Unspecified,\n    selectedItemColor: Color = MaterialTheme.colorScheme.tertiary,\n    initialExpanded: Boolean = false,\n    canExpand: Boolean = true,\n    contentPadding: PaddingValues = PaddingValues(8.dp),\n    behaveAsContainer: Boolean = true,\n    titlePadding: PaddingValues = PaddingValues(\n        top = 12.dp,\n        start = 12.dp,\n        bottom = 8.dp\n    )\n) {\n    val realSpanCount = spanCount.coerceAtLeast(1)\n\n    Column(\n        modifier = modifier.then(\n            if (behaveAsContainer) {\n                Modifier.container(\n                    shape = shape,\n                    color = containerColor\n                )\n            } else Modifier\n        )\n    ) {\n        var expanded by rememberSaveable(initialExpanded, realSpanCount, canExpand) {\n            mutableStateOf(\n                if (canExpand) initialExpanded && realSpanCount > 1 else true\n            )\n        }\n\n        val showExpand = realSpanCount > 1 && canExpand\n        val showTitle = badgeContent != null || title != null\n\n        if (showExpand || showTitle) {\n            Row {\n                if (showTitle) {\n                    Row(\n                        modifier = Modifier.weight(1f),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        title?.let {\n                            TitleItem(\n                                text = title,\n                                icon = titleIcon,\n                                modifier = Modifier\n                                    .padding(\n                                        top = titlePadding.calculateTopPadding(),\n                                        start = titlePadding.calculateStartPadding(\n                                            LocalLayoutDirection.current\n                                        ),\n                                        bottom = titlePadding.calculateBottomPadding()\n                                    )\n                                    .weight(1f, false)\n                            )\n                        }\n                        badgeContent?.let {\n                            EnhancedBadge(\n                                content = badgeContent,\n                                containerColor = MaterialTheme.colorScheme.tertiary,\n                                contentColor = MaterialTheme.colorScheme.onTertiary,\n                                modifier = Modifier\n                                    .padding(horizontal = 2.dp)\n                                    .padding(bottom = titlePadding.calculateBottomPadding() + 4.dp)\n                                    .scaleOnTap {\n                                        AppToastHost.showConfetti()\n                                    }\n                            )\n                        }\n                    }\n                }\n\n                if (showExpand) {\n                    val rotation by animateFloatAsState(if (expanded) 180f else 0f)\n\n                    EnhancedIconButton(\n                        containerColor = Color.Transparent,\n                        onClick = { expanded = !expanded }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.KeyboardArrowDown,\n                            contentDescription = \"Expand\",\n                            modifier = Modifier.rotate(rotation)\n                        )\n                    }\n                }\n            }\n        }\n\n        if (canExpand) {\n            val state = rememberLazyStaggeredGridState()\n\n            LaunchedEffect(value, entries) {\n                delay(300)\n                val targetIndex = entries.indexOf(value).takeIf { it >= 0 } ?: 0\n                if (state.layoutInfo.visibleItemsInfo.all { it.index != targetIndex }) {\n                    state.scrollToItem(targetIndex)\n                }\n            }\n\n            LazyHorizontalStaggeredGrid(\n                verticalArrangement = Arrangement.spacedBy(\n                    space = 8.dp,\n                    alignment = Alignment.CenterVertically\n                ),\n                state = state,\n                horizontalItemSpacing = 8.dp,\n                rows = StaggeredGridCells.Adaptive(30.dp),\n                modifier = Modifier\n                    .heightIn(\n                        max = animateDpAsState(\n                            if (expanded) {\n                                52.dp * realSpanCount - 8.dp * (realSpanCount - 1)\n                            } else 52.dp\n                        ).value\n                    )\n                    .fadingEdges(\n                        scrollableState = state,\n                        isVertical = false,\n                        spanCount = realSpanCount\n                    ),\n                contentPadding = contentPadding,\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                items(entries) { item ->\n                    ChipItem(\n                        item = item,\n                        value = value,\n                        onValueChange = onValueChange,\n                        itemContentText = itemContentText,\n                        itemContentIcon = itemContentIcon,\n                        itemEqualityDelegate = itemEqualityDelegate,\n                        selectedItemColor = selectedItemColor\n                    )\n                }\n            }\n        } else {\n            FlowRow(\n                verticalArrangement = Arrangement.spacedBy(\n                    space = 8.dp,\n                    alignment = Alignment.CenterVertically\n                ),\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = 8.dp,\n                    alignment = Alignment.Start\n                ),\n                modifier = Modifier.padding(contentPadding)\n            ) {\n                entries.forEach { item ->\n                    ChipItem(\n                        item = item,\n                        value = value,\n                        onValueChange = onValueChange,\n                        itemContentText = itemContentText,\n                        itemContentIcon = itemContentIcon,\n                        itemEqualityDelegate = itemEqualityDelegate,\n                        selectedItemColor = selectedItemColor\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun <T> ChipItem(\n    item: T,\n    value: T,\n    onValueChange: (T) -> Unit,\n    itemContentText: @Composable (T) -> String,\n    itemContentIcon: ((T, Boolean) -> ImageVector?)?,\n    itemEqualityDelegate: (T, T) -> Boolean,\n    selectedItemColor: Color,\n) {\n    val selected by remember(item, value) {\n        derivedStateOf {\n            itemEqualityDelegate(value, item)\n        }\n    }\n    EnhancedChip(\n        selected = selected,\n        onClick = {\n            onValueChange(item)\n        },\n        selectedColor = selectedItemColor,\n        contentPadding = PaddingValues(\n            horizontal = 12.dp,\n            vertical = 8.dp\n        ),\n        modifier = Modifier.height(36.dp)\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            AnimatedContent(\n                targetState = itemContentIcon?.invoke(item, selected),\n                contentKey = { it == null }\n            ) { icon ->\n                icon?.let {\n                    Icon(\n                        imageVector = icon,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .padding(end = 8.dp)\n                            .size(18.dp)\n                    )\n                }\n            }\n            Text(\n                text = itemContentText(item)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/FontSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.TextFields\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.ui.theme.ProvideTypography\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun FontSelector(\n    value: UiFontFamily,\n    onValueChange: (UiFontFamily) -> Unit,\n    modifier: Modifier = Modifier,\n    title: String = stringResource(R.string.font),\n    containerColor: Color = MaterialTheme.colorScheme.surface,\n    shape: Shape = ShapeDefaults.large,\n    behaveAsContainer: Boolean = true\n) {\n    Column(\n        modifier = modifier.then(\n            if (behaveAsContainer) {\n                Modifier.container(\n                    shape = shape,\n                    color = containerColor\n                )\n            } else Modifier\n        )\n    ) {\n        val fonts = UiFontFamily.entries\n\n        var expanded by rememberSaveable { mutableStateOf(false) }\n        Row(verticalAlignment = Alignment.CenterVertically) {\n            val rotation by animateFloatAsState(if (expanded) 180f else 0f)\n            TitleItem(\n                text = title,\n                icon = if (behaveAsContainer) Icons.Outlined.TextFields else null,\n                modifier = Modifier.padding(top = 12.dp, start = 12.dp, bottom = 8.dp)\n            )\n            EnhancedBadge(\n                content = {\n                    Text(fonts.size.toString())\n                },\n                containerColor = MaterialTheme.colorScheme.tertiary,\n                contentColor = MaterialTheme.colorScheme.onTertiary,\n                modifier = Modifier\n                    .padding(horizontal = 2.dp)\n                    .padding(bottom = 12.dp)\n                    .scaleOnTap {\n                        AppToastHost.showConfetti()\n                    }\n            )\n            Spacer(modifier = Modifier.weight(1f))\n            EnhancedIconButton(\n                containerColor = Color.Transparent,\n                onClick = { expanded = !expanded }\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.KeyboardArrowDown,\n                    contentDescription = \"Expand\",\n                    modifier = Modifier.rotate(rotation)\n                )\n            }\n        }\n        val state = rememberLazyStaggeredGridState()\n        LazyHorizontalStaggeredGrid(\n            verticalArrangement = Arrangement.spacedBy(\n                space = 8.dp,\n                alignment = Alignment.CenterVertically\n            ),\n            state = state,\n            horizontalItemSpacing = 8.dp,\n            rows = StaggeredGridCells.Adaptive(30.dp),\n            modifier = Modifier\n                .heightIn(max = animateDpAsState(if (expanded) 140.dp else 52.dp).value)\n                .fadingEdges(\n                    scrollableState = state,\n                    isVertical = false,\n                    spanCount = 3\n                ),\n            contentPadding = PaddingValues(8.dp),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            items(fonts) { font ->\n                ProvideTypography(font) {\n                    EnhancedChip(\n                        selected = font == value,\n                        onClick = {\n                            onValueChange(font)\n                        },\n                        selectedColor = MaterialTheme.colorScheme.secondary,\n                        contentPadding = PaddingValues(\n                            horizontal = 12.dp,\n                            vertical = 8.dp\n                        ),\n                        modifier = Modifier.height(36.dp)\n                    ) {\n                        AutoSizeText(\n                            text = font.name\n                                ?: stringResource(id = R.string.system),\n                            maxLines = 1\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/HelperGridParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ColorLens\nimport androidx.compose.material.icons.outlined.LineWeight\nimport androidx.compose.material.icons.outlined.TableRows\nimport androidx.compose.material.icons.outlined.ViewColumn\nimport androidx.compose.material.icons.rounded.FormatLineSpacing\nimport androidx.compose.material.icons.rounded.GridOn\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun HelperGridParamsSelector(\n    value: HelperGridParams,\n    onValueChange: (HelperGridParams) -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = ShapeDefaults.extraLarge,\n) {\n    Column(\n        modifier = modifier.container(\n            shape = shape,\n            resultPadding = 0.dp\n        )\n    ) {\n        PreferenceRowSwitch(\n            modifier = Modifier.clip(shape),\n            startIcon = Icons.Rounded.GridOn,\n            drawContainer = false,\n            checked = value.enabled,\n            onClick = {\n                onValueChange(value.copy(enabled = it))\n            },\n            title = stringResource(R.string.helper_grid),\n            subtitle = stringResource(R.string.helper_grid_sub)\n        )\n        AnimatedVisibility(value.enabled) {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                Spacer(Modifier.height(4.dp))\n                ColorRowSelector(\n                    value = value.color.toColor(),\n                    onValueChange = {\n                        onValueChange(value.copy(color = it.toArgb()))\n                    },\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp)\n                        .container(\n                            shape = ShapeDefaults.top,\n                            color = MaterialTheme.colorScheme.surface,\n                            resultPadding = 0.dp\n                        )\n                        .padding(start = 4.dp),\n                    icon = Icons.Outlined.ColorLens,\n                    title = stringResource(R.string.grid_color)\n                )\n                EnhancedSliderItem(\n                    value = value.linesWidth,\n                    title = stringResource(R.string.line_width),\n                    icon = Icons.Outlined.LineWeight,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    valueSuffix = \" Pt\",\n                    shape = ShapeDefaults.center,\n                    onValueChange = {\n                        onValueChange(value.copy(linesWidth = it))\n                    },\n                    valueRange = 0f..1.5f,\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier.padding(horizontal = 8.dp)\n                )\n                EnhancedSliderItem(\n                    value = value.cellWidth,\n                    title = stringResource(R.string.cell_width),\n                    icon = Icons.Outlined.ViewColumn,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    valueSuffix = \" Pt\",\n                    shape = ShapeDefaults.center,\n                    onValueChange = {\n                        onValueChange(value.copy(cellWidth = it))\n                    },\n                    valueRange = 1f..100f,\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier.padding(horizontal = 8.dp)\n                )\n                EnhancedSliderItem(\n                    value = value.cellHeight,\n                    title = stringResource(R.string.cell_height),\n                    icon = Icons.Outlined.TableRows,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    valueSuffix = \" Pt\",\n                    shape = ShapeDefaults.center,\n                    onValueChange = {\n                        onValueChange(value.copy(cellHeight = it))\n                    },\n                    valueRange = 1f..100f,\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier.padding(horizontal = 8.dp)\n                )\n                PreferenceRowSwitch(\n                    startIcon = Icons.Rounded.FormatLineSpacing,\n                    drawContainer = true,\n                    shape = ShapeDefaults.bottom,\n                    checked = value.withPrimaryLines,\n                    onClick = {\n                        onValueChange(value.copy(withPrimaryLines = it))\n                    },\n                    title = stringResource(R.string.primary_lines),\n                    subtitle = stringResource(R.string.primary_lines_sub),\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier.padding(horizontal = 8.dp)\n                )\n                Spacer(Modifier.height(4.dp))\n            }\n        }\n    }\n}\n\n@Composable\n@Preview\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    var value by remember {\n        mutableStateOf(HelperGridParams(enabled = true))\n    }\n    HelperGridParamsSelector(\n        value = value,\n        onValueChange = { value = it }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/ImageFormatSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnnecessaryVariable\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport android.os.Build\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Architecture\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.alphaContainedEntries\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImagesearchRoller\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.Disableable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport kotlinx.coroutines.launch\n\n\n@Composable\nfun ImageFormatSelector(\n    modifier: Modifier = Modifier,\n    backgroundColor: Color = Color.Unspecified,\n    entries: List<ImageFormatGroup> = ImageFormatGroup.entries,\n    forceEnabled: Boolean = false,\n    value: ImageFormat?,\n    quality: Quality? = null,\n    onValueChange: (ImageFormat) -> Unit,\n    shape: Shape = ShapeDefaults.extraLarge,\n    enableItemsCardBackground: Boolean = true,\n    title: @Composable ColumnScope.() -> Unit = {\n        Text(\n            text = stringResource(R.string.image_format),\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(bottom = 4.dp),\n            textAlign = TextAlign.Center,\n            fontWeight = FontWeight.Medium\n        )\n    },\n    onAutoClick: (() -> Unit)? = null\n) {\n    val settingsState = LocalSettingsState.current\n\n    val cannotChangeFormat: () -> Unit = {\n        AppToastHost.showToast(\n            message = getString(R.string.cannot_change_image_format),\n            icon = Icons.Rounded.Architecture\n        )\n    }\n\n    val allFormats by remember(entries) {\n        derivedStateOf {\n            entries.flatMap { it.formats }\n        }\n    }\n\n    LaunchedEffect(value, allFormats) {\n        if (value != null && value !in allFormats) {\n            onValueChange(\n                if (ImageFormat.Png.Lossless in allFormats) {\n                    ImageFormat.Png.Lossless\n                } else {\n                    allFormats.first()\n                }\n            )\n        }\n    }\n\n    Column(\n        modifier = modifier\n            .container(\n                shape = shape,\n                color = backgroundColor\n            )\n            .animateContentSizeNoClip(),\n        horizontalAlignment = Alignment.CenterHorizontally,\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        val formats by remember(value) {\n            derivedStateOf {\n                entries.firstOrNull {\n                    value in it.formats\n                }?.formats ?: emptyList()\n            }\n        }\n        val filteredFormats = if (enableItemsCardBackground) {\n            formats.filteredFormats()\n        } else {\n            allFormats.filteredFormats()\n        }\n\n        val enableBackgroundColorForAlphaFormats =\n            settingsState.enableBackgroundColorForAlphaFormats\n        val isNonAlpha =\n            value !in ImageFormat.alphaContainedEntries || quality?.isNonAlpha() == true\n        val showBackgroundSelector =\n            value != null && (isNonAlpha || enableBackgroundColorForAlphaFormats)\n\n        val entriesSize = (if (filteredFormats.size > 1) 1 else 0)\n            .plus(if (showBackgroundSelector) 1 else 0)\n            .plus(1)\n\n        Disableable(\n            enabled = settingsState.filenameBehavior !is FilenameBehavior.Overwrite || forceEnabled,\n            onDisabledClick = cannotChangeFormat\n        ) {\n            Column(\n                modifier = Modifier.fillMaxWidth(),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                Spacer(Modifier.height(4.dp))\n                title(this)\n\n                AnimatedContent(\n                    targetState = entries.filtered(),\n                    modifier = Modifier.fillMaxWidth()\n                ) { items ->\n                    FlowRow(\n                        verticalArrangement = Arrangement.spacedBy(\n                            space = 8.dp,\n                            alignment = Alignment.CenterVertically\n                        ),\n                        horizontalArrangement = Arrangement.spacedBy(\n                            space = 8.dp,\n                            alignment = Alignment.CenterHorizontally\n                        ),\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .then(\n                                if (enableItemsCardBackground) {\n                                    Modifier\n                                        .padding(horizontal = 8.dp)\n                                        .container(\n                                            shape = ShapeDefaults.byIndex(0, entriesSize),\n                                            color = MaterialTheme.colorScheme.surface\n                                        )\n                                        .padding(horizontal = 8.dp, vertical = 12.dp)\n                                } else Modifier.padding(8.dp)\n                            )\n                    ) {\n                        onAutoClick?.let {\n                            EnhancedChip(\n                                onClick = onAutoClick,\n                                selected = value == null,\n                                label = {\n                                    Text(text = stringResource(R.string.auto))\n                                },\n                                selectedColor = MaterialTheme.colorScheme.tertiary,\n                                contentPadding = PaddingValues(\n                                    horizontal = 16.dp,\n                                    vertical = 6.dp\n                                )\n                            )\n                        }\n                        if (enableItemsCardBackground) {\n                            items.forEach {\n                                EnhancedChip(\n                                    onClick = {\n                                        onValueChange(it.formats[0])\n                                    },\n                                    selected = value in it.formats,\n                                    label = {\n                                        Text(text = it.title)\n                                    },\n                                    selectedColor = MaterialTheme.colorScheme.tertiary,\n                                    contentPadding = PaddingValues(\n                                        horizontal = 16.dp,\n                                        vertical = 6.dp\n                                    )\n                                )\n                            }\n                        } else {\n                            filteredFormats.forEach {\n                                EnhancedChip(\n                                    onClick = {\n                                        onValueChange(it)\n                                    },\n                                    selected = value == it,\n                                    label = {\n                                        Text(text = it.title)\n                                    },\n                                    selectedColor = MaterialTheme.colorScheme.tertiary,\n                                    contentPadding = PaddingValues(\n                                        horizontal = 16.dp,\n                                        vertical = 6.dp\n                                    )\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        AnimatedVisibility(\n            visible = filteredFormats.size > 1 && enableItemsCardBackground,\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp)\n                    .container(\n                        color = MaterialTheme.colorScheme.surface,\n                        resultPadding = 0.dp,\n                        shape = ShapeDefaults.byIndex(1, entriesSize),\n                    )\n                    .padding(horizontal = 16.dp, vertical = 12.dp),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                Text(\n                    text = stringResource(R.string.compression_type),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n                AnimatedContent(\n                    targetState = filteredFormats,\n                    modifier = Modifier.fillMaxWidth()\n                ) { items ->\n                    FlowRow(\n                        verticalArrangement = Arrangement.spacedBy(\n                            space = 8.dp,\n                            alignment = Alignment.CenterVertically\n                        ),\n                        horizontalArrangement = Arrangement.spacedBy(\n                            space = 8.dp,\n                            alignment = Alignment.CenterHorizontally\n                        ),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        items.forEach {\n                            EnhancedChip(\n                                onClick = {\n                                    onValueChange(it)\n                                },\n                                selected = value == it,\n                                label = {\n                                    Text(text = it.title)\n                                },\n                                selectedColor = MaterialTheme.colorScheme.tertiary,\n                                contentPadding = PaddingValues(\n                                    horizontal = 16.dp,\n                                    vertical = 6.dp\n                                )\n                            )\n                        }\n                    }\n                }\n            }\n        }\n\n        val scope = rememberCoroutineScope()\n        val simpleSettingsInteractor = LocalSimpleSettingsInteractor.current\n\n        var previousEnabled by rememberSaveable {\n            mutableStateOf(showBackgroundSelector)\n        }\n        LaunchedEffect(showBackgroundSelector, value) {\n            if (previousEnabled != showBackgroundSelector) {\n                val previous = value\n\n                previous?.let {\n                    onValueChange(\n                        ImageFormat.entries.run {\n                            rightFrom(indexOf(value))\n                        }\n                    )\n                    onValueChange(previous)\n                }\n                previousEnabled = showBackgroundSelector\n            }\n        }\n\n        AnimatedVisibility(\n            visible = showBackgroundSelector,\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            val index = if (filteredFormats.size > 1 && enableItemsCardBackground) 2 else 1\n            ColorRowSelector(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .then(\n                        if (enableItemsCardBackground) {\n                            Modifier\n                                .padding(horizontal = 8.dp)\n                                .container(\n                                    color = MaterialTheme.colorScheme.surface,\n                                    resultPadding = 0.dp,\n                                    shape = ShapeDefaults.byIndex(index, entriesSize),\n                                )\n                                .padding(8.dp)\n                        } else Modifier\n                    ),\n                value = settingsState.backgroundForNoAlphaImageFormats,\n                icon = Icons.Outlined.ImagesearchRoller,\n                onValueChange = {\n                    scope.launch {\n                        simpleSettingsInteractor.setBackgroundColorForNoAlphaFormats(\n                            color = it.toModel()\n                        )\n                        val previous = value\n\n                        previous?.let {\n                            onValueChange(\n                                ImageFormat.entries.run {\n                                    rightFrom(indexOf(value))\n                                }\n                            )\n                            onValueChange(previous)\n                        }\n                    }\n                },\n                allowAlpha = !isNonAlpha && enableBackgroundColorForAlphaFormats\n            )\n        }\n\n        if (enableItemsCardBackground) Spacer(Modifier.height(4.dp))\n    }\n}\n\n@Composable\nprivate fun List<ImageFormatGroup>.filtered(): List<ImageFormatGroup> = remember(this) {\n    if (Build.VERSION.SDK_INT <= 24) this - ImageFormatGroup.highLevelFormats.toSet()\n    else this\n}\n\n@Composable\nprivate fun List<ImageFormat>.filteredFormats(): List<ImageFormat> = remember(this) {\n    if (Build.VERSION.SDK_INT <= 24) this - ImageFormat.highLevelFormats.toSet()\n    else this\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/ImageSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport android.net.Uri\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.twotone.InsertDriveFile\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\n\n@Composable\nfun ImageSelector(\n    value: Any?,\n    onValueChange: (Uri) -> Unit,\n    title: String = stringResource(id = R.string.image),\n    subtitle: String?,\n    modifier: Modifier = Modifier,\n    autoShadowElevation: Dp = 1.dp,\n    color: Color = MaterialTheme.colorScheme.surfaceContainerLow,\n    shape: Shape = ShapeDefaults.large,\n    contentScale: ContentScale = ContentScale.Crop\n) {\n    val imagePicker = rememberImagePicker(onSuccess = onValueChange)\n\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItemOverload(\n        title = title,\n        subtitle = subtitle,\n        onClick = imagePicker::pickImage,\n        onLongClick = {\n            showOneTimeImagePickingDialog = true\n        },\n        autoShadowElevation = autoShadowElevation,\n        startIcon = {\n            Picture(\n                contentScale = contentScale,\n                model = value,\n                shape = CloverShape,\n                modifier = Modifier.size(48.dp),\n                error = {\n                    Icon(\n                        imageVector = Icons.TwoTone.AddPhotoAlt,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .clip(CloverShape)\n                            .background(\n                                color = MaterialTheme.colorScheme.secondaryContainer\n                                    .copy(0.5f)\n                                    .compositeOver(color)\n                            )\n                            .padding(8.dp)\n                    )\n                }\n            )\n        },\n        endIcon = {\n            Icon(\n                imageVector = Icons.Rounded.MiniEdit,\n                contentDescription = stringResource(R.string.edit)\n            )\n        },\n        modifier = modifier,\n        shape = shape,\n        containerColor = color,\n        drawStartIconContainer = false\n    )\n\n    OneTimeImagePickingDialog(\n        onDismiss = { showOneTimeImagePickingDialog = false },\n        picker = Picker.Single,\n        imagePicker = imagePicker,\n        visible = showOneTimeImagePickingDialog\n    )\n}\n\n@Composable\nfun FileSelector(\n    value: String?,\n    onValueChange: (Uri) -> Unit,\n    title: String = stringResource(id = R.string.pick_file),\n    subtitle: String?,\n    modifier: Modifier = Modifier,\n    autoShadowElevation: Dp = 1.dp,\n    color: Color = MaterialTheme.colorScheme.surfaceContainerLow,\n    shape: Shape = ShapeDefaults.large\n) {\n    val pickFileLauncher = rememberFilePicker(onSuccess = onValueChange)\n\n    PreferenceItemOverload(\n        title = title,\n        subtitle = if (subtitle == null && value != null) {\n            rememberFilename(value.toUri())\n        } else subtitle,\n        onClick = pickFileLauncher::pickFile,\n        autoShadowElevation = autoShadowElevation,\n        startIcon = {\n            Picture(\n                contentScale = ContentScale.Crop,\n                model = value,\n                shape = CloverShape,\n                modifier = Modifier.size(48.dp),\n                error = {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.TwoTone.InsertDriveFile,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .clip(CloverShape)\n                            .background(\n                                MaterialTheme.colorScheme.secondaryContainer\n                                    .copy(0.5f)\n                                    .compositeOver(color)\n                            )\n                            .padding(8.dp)\n                    )\n                }\n            )\n        },\n        endIcon = {\n            Icon(\n                imageVector = Icons.Rounded.MiniEdit,\n                contentDescription = stringResource(R.string.edit)\n            )\n        },\n        modifier = modifier,\n        shape = shape,\n        containerColor = color,\n        drawStartIconContainer = false\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/MagnifierEnabledSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ZoomIn\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport kotlinx.coroutines.launch\n\n@Composable\nfun MagnifierEnabledSelector(\n    modifier: Modifier = Modifier,\n    shape: Shape = ShapeDefaults.default,\n) {\n    val scope = rememberCoroutineScope()\n    val settingsState = LocalSettingsState.current\n    val settingsInteractor = LocalSimpleSettingsInteractor.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.magnifier),\n        subtitle = stringResource(R.string.magnifier_sub),\n        checked = settingsState.magnifierEnabled,\n        onClick = {\n            scope.launch {\n                settingsInteractor.toggleMagnifierEnabled()\n            }\n        },\n        startIcon = Icons.Outlined.ZoomIn\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/PositionSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Place\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun PositionSelector(\n    value: Position,\n    onValueChange: (Position) -> Unit,\n    entries: List<Position> = Position.entries,\n    modifier: Modifier = Modifier,\n    shape: Shape = ShapeDefaults.large,\n    color: Color = MaterialTheme.colorScheme.surface,\n    selectedItemColor: Color = MaterialTheme.colorScheme.tertiary,\n) {\n    DataSelector(\n        value = value,\n        onValueChange = onValueChange,\n        entries = entries,\n        spanCount = 2,\n        title = stringResource(R.string.position),\n        titleIcon = Icons.Outlined.Place,\n        itemContentText = { it.translatedName },\n        modifier = modifier,\n        shape = shape,\n        containerColor = color,\n        selectedItemColor = selectedItemColor\n    )\n}\n\nprivate val Position.translatedName: String\n    @Composable\n    get() = when (this) {\n        Position.Center -> stringResource(id = R.string.center)\n        Position.TopLeft -> stringResource(id = R.string.top_left)\n        Position.TopRight -> stringResource(id = R.string.top_right)\n        Position.BottomLeft -> stringResource(id = R.string.bottom_left)\n        Position.BottomRight -> stringResource(id = R.string.bottom_right)\n        Position.TopCenter -> stringResource(id = R.string.top_center)\n        Position.CenterRight -> stringResource(id = R.string.center_right)\n        Position.BottomCenter -> stringResource(id = R.string.bottom_center)\n        Position.CenterLeft -> stringResource(id = R.string.center_left)\n    }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/PresetSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FitScreen\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.rounded.AspectRatio\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.EditAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.Telegram\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalEditPresetsController\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.OOMWarning\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AspectRatioSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealDirection\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealValue\nimport com.t8rin.imagetoolbox.core.ui.widget.other.SwipeToReveal\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberRevealState\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextFieldColors\nimport kotlinx.coroutines.launch\n\n\n@Composable\nfun PresetSelector(\n    value: Preset,\n    includeTelegramOption: Boolean = false,\n    includeAspectRatioOption: Boolean = false,\n    isBytesResize: Boolean = false,\n    showWarning: Boolean = false,\n    onValueChange: (Preset) -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val editPresetsController = LocalEditPresetsController.current\n    val data by remember(settingsState.presets, value) {\n        derivedStateOf {\n            settingsState.presets.let {\n                val currentValue = value.value()\n                if (currentValue !in it && !value.isTelegram() && currentValue != null) {\n                    listOf(currentValue) + it\n                } else it\n            }\n        }\n    }\n\n    val state = rememberRevealState()\n    val scope = rememberCoroutineScope()\n\n    var showPresetInfoDialog by remember { mutableStateOf(false) }\n\n    val canEnterPresetsByTextField = settingsState.canEnterPresetsByTextField\n\n    SwipeToReveal(\n        directions = setOf(\n            RevealDirection.EndToStart\n        ),\n        maxRevealDp = 88.dp,\n        state = state,\n        swipeableContent = {\n            Column(\n                modifier = Modifier\n                    .container(shape = ShapeDefaults.extraLarge)\n                    .pointerInput(Unit) {\n                        detectTapGestures(\n                            onLongPress = {\n                                scope.launch {\n                                    state.animateTo(RevealValue.FullyRevealedStart)\n                                }\n                            },\n                            onDoubleTap = {\n                                scope.launch {\n                                    state.animateTo(RevealValue.FullyRevealedStart)\n                                }\n                            }\n                        )\n                    }\n                    .animateContentSizeNoClip(),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                Spacer(Modifier.height(8.dp))\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.Center\n                ) {\n                    Text(\n                        text = stringResource(R.string.presets),\n                        textAlign = TextAlign.Center,\n                        fontWeight = FontWeight.Medium\n                    )\n                    Spacer(modifier = Modifier.width(8.dp))\n                    SupportingButton(\n                        onClick = {\n                            showPresetInfoDialog = true\n                        }\n                    )\n                }\n                Spacer(Modifier.height(8.dp))\n\n                AnimatedVisibility(visible = value is Preset.AspectRatio && includeAspectRatioOption) {\n                    val aspectRatios = remember {\n                        DomainAspectRatio.defaultList.drop(3)\n                    }\n\n                    Column(\n                        modifier = Modifier.padding(horizontal = 8.dp)\n                    ) {\n                        AspectRatioSelector(\n                            modifier = Modifier.fillMaxWidth(),\n                            contentPadding = PaddingValues(8.dp),\n                            selectedAspectRatio = remember(value, aspectRatios) {\n                                derivedStateOf {\n                                    aspectRatios.firstOrNull {\n                                        it.value == (value as? Preset.AspectRatio)?.ratio\n                                    }\n                                }\n                            }.value,\n                            onAspectRatioChange = { domainAspectRatio, _ ->\n                                if (value is Preset.AspectRatio) {\n                                    onValueChange(\n                                        value.copy(ratio = domainAspectRatio.value)\n                                    )\n                                } else {\n                                    onValueChange(\n                                        Preset.AspectRatio(\n                                            ratio = domainAspectRatio.value,\n                                            isFit = false\n                                        )\n                                    )\n                                }\n                            },\n                            title = {},\n                            aspectRatios = aspectRatios,\n                            shape = ShapeDefaults.top,\n                            color = MaterialTheme.colorScheme.surface,\n                            unselectedCardColor = MaterialTheme.colorScheme.surfaceContainerHigh\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        PreferenceRowSwitch(\n                            modifier = Modifier.fillMaxWidth(),\n                            title = stringResource(R.string.fit_to_bounds),\n                            subtitle = stringResource(R.string.fit_to_bounds_sub),\n                            checked = (value as? Preset.AspectRatio)?.isFit == true,\n                            onClick = {\n                                if (value is Preset.AspectRatio) {\n                                    onValueChange(\n                                        value.copy(isFit = it)\n                                    )\n                                } else {\n                                    onValueChange(\n                                        Preset.AspectRatio(\n                                            ratio = 1f,\n                                            isFit = it\n                                        )\n                                    )\n                                }\n                            },\n                            startIcon = Icons.Outlined.FitScreen,\n                            shape = ShapeDefaults.bottom,\n                            containerColor = MaterialTheme.colorScheme.surface\n                        )\n                        Spacer(modifier = Modifier.height(8.dp))\n                    }\n                }\n\n                Box(\n                    contentAlignment = Alignment.Center,\n                    modifier = Modifier.padding(bottom = 8.dp)\n                ) {\n                    val listState = rememberLazyListState()\n                    LazyRow(\n                        state = listState,\n                        modifier = Modifier\n                            .fadingEdges(listState)\n                            .padding(vertical = 1.dp),\n                        horizontalArrangement = Arrangement.spacedBy(\n                            8.dp, Alignment.CenterHorizontally\n                        ),\n                        contentPadding = PaddingValues(horizontal = 8.dp),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        if (includeTelegramOption && settingsState.filenameBehavior !is FilenameBehavior.Overwrite) {\n                            item(key = \"tg\") {\n                                val selected = value.isTelegram()\n                                EnhancedChip(\n                                    selected = selected,\n                                    onClick = { onValueChange(Preset.Telegram) },\n                                    selectedColor = MaterialTheme.colorScheme.primary,\n                                    shape = MaterialTheme.shapes.medium\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Telegram,\n                                        contentDescription = stringResource(R.string.telegram)\n                                    )\n                                }\n                            }\n                        }\n                        if (includeAspectRatioOption) {\n                            item(key = \"aspect\") {\n                                val selected = value.isAspectRatio()\n                                EnhancedChip(\n                                    selected = selected,\n                                    onClick = {\n                                        onValueChange(\n                                            Preset.AspectRatio(\n                                                ratio = 1f,\n                                                isFit = false\n                                            )\n                                        )\n                                    },\n                                    selectedColor = MaterialTheme.colorScheme.primary,\n                                    shape = MaterialTheme.shapes.medium\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.AspectRatio,\n                                        contentDescription = stringResource(R.string.aspect_ratio)\n                                    )\n                                }\n                            }\n                        }\n                        items(\n                            items = data,\n                            key = { it }\n                        ) {\n                            val selected = value.value() == it\n                            EnhancedChip(\n                                selected = selected,\n                                onClick = { onValueChange(Preset.Percentage(it)) },\n                                selectedColor = MaterialTheme.colorScheme.primary,\n                                shape = MaterialTheme.shapes.medium\n                            ) {\n                                AutoSizeText(it.toString())\n                            }\n                        }\n                    }\n                }\n                AnimatedVisibility(canEnterPresetsByTextField) {\n                    var textValue by remember(value) {\n                        mutableStateOf(\n                            value.value()?.toString() ?: \"\"\n                        )\n                    }\n                    RoundedTextField(\n                        onValueChange = { targetText ->\n                            if (targetText.isEmpty()) {\n                                textValue = \"\"\n                                onValueChange(Preset.None)\n                            } else {\n                                val newValue = targetText.filter {\n                                    it.isDigit()\n                                }.toIntOrNull()?.coerceIn(0, 500)\n                                textValue = newValue?.toString() ?: \"\"\n\n                                newValue?.let {\n                                    onValueChange(\n                                        Preset.Percentage(it)\n                                    )\n                                } ?: onValueChange(Preset.None)\n                            }\n                        },\n                        value = textValue,\n                        keyboardOptions = KeyboardOptions(\n                            keyboardType = KeyboardType.Number\n                        ),\n                        label = stringResource(R.string.enter_percentage),\n                        modifier = Modifier.padding(bottom = 8.dp, start = 8.dp, end = 8.dp),\n                        colors = RoundedTextFieldColors(\n                            isError = false,\n                            containerColor = MaterialTheme.colorScheme.surface,\n                            focusedIndicatorColor = MaterialTheme.colorScheme.secondary\n                        ).let {\n                            it.copy(\n                                unfocusedIndicatorColor = it.unfocusedIndicatorColor.copy(0.5f)\n                                    .compositeOver(\n                                        it.unfocusedContainerColor\n                                    )\n                            )\n                        }\n                    )\n                }\n\n                OOMWarning(\n                    visible = showWarning,\n                    modifier = Modifier.padding(4.dp)\n                )\n            }\n        },\n        revealedContentEnd = {\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .container(\n                        color = MaterialTheme.colorScheme.surfaceContainerLowest,\n                        shape = ShapeDefaults.extraLarge,\n                        autoShadowElevation = 0.5.dp\n                    )\n            ) {\n                EnhancedIconButton(\n                    containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(10.dp),\n                    contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                    onClick = editPresetsController::open,\n                    modifier = Modifier\n                        .padding(16.dp)\n                        .align(Alignment.CenterEnd)\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.EditAlt,\n                        contentDescription = stringResource(R.string.edit)\n                    )\n                }\n            }\n        }\n    )\n\n    EnhancedAlertDialog(\n        visible = showPresetInfoDialog,\n        onDismissRequest = { showPresetInfoDialog = false },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { showPresetInfoDialog = false }\n            ) {\n                Text(stringResource(R.string.ok))\n            }\n        },\n        title = {\n            Text(stringResource(R.string.presets))\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.Info,\n                contentDescription = stringResource(R.string.about_app)\n            )\n        },\n        text = {\n            if (isBytesResize) Text(stringResource(R.string.presets_sub_bytes))\n            else Text(stringResource(R.string.presets_sub))\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/QualitySelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ColorLens\nimport androidx.compose.material.icons.outlined.Speed\nimport androidx.compose.material.icons.rounded.Stream\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.TiffCompressionScheme\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.QualityHigh\nimport com.t8rin.imagetoolbox.core.resources.icons.QualityLow\nimport com.t8rin.imagetoolbox.core.resources.icons.QualityMedium\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.OneTimeEffect\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlin.math.roundToInt\n\n@Composable\nfun QualitySelector(\n    imageFormat: ImageFormat,\n    quality: Quality,\n    onQualityChange: (Quality) -> Unit,\n    modifier: Modifier = Modifier,\n    icon: ImageVector? = null,\n    shape: Shape = ShapeDefaults.extraLarge,\n    inactiveButtonColor: Color = MaterialTheme.colorScheme.surfaceContainer,\n    activeButtonColor: Color = MaterialTheme.colorScheme.secondary,\n    autoCoerce: Boolean = true\n) {\n    val settingsState = LocalSettingsState.current\n    var actualImageFormat by remember {\n        mutableStateOf(imageFormat)\n    }\n\n    LaunchedEffect(imageFormat, quality) {\n        if (\n            actualImageFormat.canChangeCompressionValue == imageFormat.canChangeCompressionValue\n            || !actualImageFormat.canChangeCompressionValue\n        ) {\n            actualImageFormat = imageFormat\n        } else {\n            launch {\n                delay(1000)\n            }.invokeOnCompletion {\n                actualImageFormat = imageFormat\n            }\n        }\n        if (autoCoerce) {\n            onQualityChange(\n                quality.coerceIn(imageFormat)\n            )\n        }\n    }\n\n    AnimatedVisibility(\n        visible = imageFormat.canChangeCompressionValue,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically(),\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        if (autoCoerce) {\n            OneTimeEffect {\n                if (quality != settingsState.defaultQuality) {\n                    onQualityChange(settingsState.defaultQuality)\n                }\n            }\n        }\n\n        Column(\n            modifier = modifier.container(shape)\n        ) {\n            actualImageFormat.compressionTypes.forEach { type ->\n                val currentIcon by remember(quality, icon) {\n                    derivedStateOf {\n                        when {\n                            icon != null -> icon\n                            actualImageFormat.isHighQuality(quality.qualityValue) -> Icons.Outlined.QualityHigh\n                            actualImageFormat.isMidQuality(quality.qualityValue) -> Icons.Outlined.QualityMedium\n                            else -> Icons.Outlined.QualityLow\n                        }\n                    }\n                }\n\n                val isQuality = type is ImageFormat.CompressionType.Quality\n                val isEffort = type is ImageFormat.CompressionType.Effort\n\n                val compressingLiteral = if (isQuality) \"%\" else \"\"\n\n                EnhancedSliderItem(\n                    value = when (type) {\n                        is ImageFormat.CompressionType.Effort -> {\n                            when (quality) {\n                                is Quality.Base -> quality.qualityValue\n                                is Quality.Jxl -> quality.effort\n                                is Quality.PngLossy -> quality.compressionLevel\n                                is Quality.Avif -> quality.effort\n                                is Quality.Tiff -> quality.qualityValue\n                            }\n                        }\n\n                        is ImageFormat.CompressionType.Quality -> quality.qualityValue\n                    },\n                    title = if (isQuality) {\n                        stringResource(R.string.quality)\n                    } else stringResource(R.string.effort),\n                    icon = if (isQuality) currentIcon else Icons.Rounded.Stream,\n                    valueRange = type.compressionRange.let { it.first.toFloat()..it.last.toFloat() },\n                    steps = type.compressionRange.let { it.last - it.first - 1 },\n                    internalStateTransformation = {\n                        it.roundToInt().coerceIn(type.compressionRange).toFloat()\n                    },\n                    onValueChange = {\n                        when (type) {\n                            is ImageFormat.CompressionType.Effort -> {\n                                onQualityChange(\n                                    when (quality) {\n                                        is Quality.Base -> quality.copy(qualityValue = it.toInt())\n                                        is Quality.Jxl -> quality.copy(effort = it.toInt())\n                                        is Quality.PngLossy -> quality.copy(compressionLevel = it.toInt())\n                                        is Quality.Avif -> quality.copy(effort = it.toInt())\n                                        is Quality.Tiff -> quality.copy(compressionScheme = it.toInt())\n                                    }.coerceIn(actualImageFormat)\n                                )\n                            }\n\n                            is ImageFormat.CompressionType.Quality -> {\n                                onQualityChange(\n                                    when (quality) {\n                                        is Quality.Base -> quality.copy(qualityValue = it.toInt())\n                                        is Quality.Jxl -> quality.copy(qualityValue = it.toInt())\n                                        is Quality.PngLossy -> quality.copy(compressionLevel = it.toInt())\n                                        is Quality.Avif -> quality.copy(qualityValue = it.toInt())\n                                        is Quality.Tiff -> quality.copy(compressionScheme = it.toInt())\n                                    }.coerceIn(actualImageFormat)\n                                )\n                            }\n                        }\n                    },\n                    valueSuffix = \" $compressingLiteral\",\n                    behaveAsContainer = false,\n                    titleFontWeight = FontWeight.Medium\n                ) {\n                    AnimatedVisibility(isEffort) {\n                        Text(\n                            text = stringResource(\n                                R.string.effort_sub,\n                                type.compressionRange.first,\n                                type.compressionRange.last\n                            ),\n                            fontSize = 12.sp,\n                            textAlign = TextAlign.Center,\n                            lineHeight = 12.sp,\n                            color = LocalContentColor.current.copy(0.5f),\n                            modifier = Modifier\n                                .padding(4.dp)\n                                .container(\n                                    shape = ShapeDefaults.large,\n                                    color = MaterialTheme.colorScheme.surface\n                                )\n                                .padding(6.dp)\n                        )\n                    }\n                }\n            }\n            AnimatedVisibility(actualImageFormat is ImageFormat.Jxl) {\n                val jxlQuality = quality as? Quality.Jxl\n                Column {\n                    EnhancedSliderItem(\n                        value = jxlQuality?.speed ?: 0,\n                        title = stringResource(R.string.speed),\n                        icon = Icons.Outlined.Speed,\n                        valueRange = 0f..4f,\n                        steps = 3,\n                        internalStateTransformation = {\n                            it.roundToInt().coerceIn(0..4).toFloat()\n                        },\n                        onValueChange = {\n                            jxlQuality?.copy(\n                                speed = it.roundToInt()\n                            )?.coerceIn(actualImageFormat)?.let(onQualityChange)\n                        },\n                        behaveAsContainer = false\n                    ) {\n                        Text(\n                            text = stringResource(\n                                R.string.speed_sub,\n                                0, 4\n                            ),\n                            fontSize = 12.sp,\n                            textAlign = TextAlign.Center,\n                            lineHeight = 12.sp,\n                            color = LocalContentColor.current.copy(0.5f),\n                            modifier = Modifier\n                                .padding(4.dp)\n                                .container(\n                                    shape = ShapeDefaults.large,\n                                    color = MaterialTheme.colorScheme.surface\n                                )\n                                .padding(6.dp)\n                        )\n                    }\n                    val items = remember {\n                        Quality.Channels.entries\n                    }\n                    EnhancedButtonGroup(\n                        itemCount = items.size,\n                        itemContent = {\n                            Text(items[it].title)\n                        },\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(4.dp)\n                            .container(\n                                shape = ShapeDefaults.large,\n                                color = MaterialTheme.colorScheme.surface\n                            )\n                            .padding(4.dp),\n                        title = {\n                            Text(\n                                text = stringResource(R.string.channels_configuration),\n                                modifier = Modifier.padding(vertical = 4.dp)\n                            )\n                        },\n                        selectedIndex = items.indexOfFirst { it == jxlQuality?.channels },\n                        onIndexChange = {\n                            jxlQuality?.copy(\n                                channels = Quality.Channels.fromInt(it)\n                            )?.coerceIn(actualImageFormat)?.let(onQualityChange)\n                        },\n                        inactiveButtonColor = inactiveButtonColor,\n                        activeButtonColor = activeButtonColor\n                    )\n                }\n            }\n            AnimatedVisibility(actualImageFormat is ImageFormat.Png.Lossy) {\n                val pngLossyQuality = quality as? Quality.PngLossy\n                EnhancedSliderItem(\n                    value = pngLossyQuality?.maxColors ?: 0,\n                    title = stringResource(R.string.max_colors_count),\n                    icon = Icons.Outlined.ColorLens,\n                    valueRange = 2f..1024f,\n                    internalStateTransformation = {\n                        it.roundToInt().coerceIn(2..1024).toFloat()\n                    },\n                    onValueChange = {\n                        pngLossyQuality?.copy(\n                            maxColors = it.roundToInt()\n                        )?.coerceIn(actualImageFormat)?.let(onQualityChange)\n                    },\n                    behaveAsContainer = false\n                )\n            }\n            AnimatedVisibility(actualImageFormat is ImageFormat.Tiff || actualImageFormat is ImageFormat.Tif) {\n                val tiffQuality = quality as? Quality.Tiff\n                val compressionItems = TiffCompressionScheme.safeEntries\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    TitleItem(\n                        text = stringResource(R.string.tiff_compression_scheme),\n                        modifier = Modifier\n                            .padding(top = 12.dp, start = 12.dp, bottom = 8.dp, end = 12.dp)\n                    )\n                    Column(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(4.dp)\n                            .container(\n                                shape = ShapeDefaults.large,\n                                color = MaterialTheme.colorScheme.surface\n                            )\n                    ) {\n                        val state = rememberLazyStaggeredGridState()\n                        LazyHorizontalStaggeredGrid(\n                            verticalArrangement = Arrangement.spacedBy(\n                                space = 8.dp,\n                                alignment = Alignment.CenterVertically\n                            ),\n                            state = state,\n                            horizontalItemSpacing = 8.dp,\n                            rows = StaggeredGridCells.Adaptive(30.dp),\n                            modifier = Modifier\n                                .heightIn(max = 100.dp)\n                                .fadingEdges(\n                                    scrollableState = state,\n                                    isVertical = false,\n                                    spanCount = 2\n                                ),\n                            contentPadding = PaddingValues(8.dp),\n                            flingBehavior = enhancedFlingBehavior()\n                        ) {\n                            items(compressionItems) {\n                                val selected by remember(it, tiffQuality?.compressionScheme) {\n                                    derivedStateOf {\n                                        tiffQuality?.compressionScheme == it.ordinal\n                                    }\n                                }\n                                EnhancedChip(\n                                    selected = selected,\n                                    onClick = {\n                                        tiffQuality?.copy(\n                                            compressionScheme = it.ordinal\n                                        )?.coerceIn(actualImageFormat)?.let(onQualityChange)\n                                    },\n                                    selectedColor = MaterialTheme.colorScheme.tertiary,\n                                    contentPadding = PaddingValues(\n                                        horizontal = 12.dp,\n                                        vertical = 8.dp\n                                    ),\n                                    modifier = Modifier.height(36.dp)\n                                ) {\n                                    AutoSizeText(\n                                        text = compressionItems[it.ordinal].title,\n                                        maxLines = 1\n                                    )\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nprivate fun ImageFormat.isHighQuality(quality: Int): Boolean {\n    val range = compressionTypes[0].compressionRange.run { endInclusive - start }\n    return quality > range * (4 / 5f)\n}\n\nprivate fun ImageFormat.isMidQuality(quality: Int): Boolean {\n    val range = compressionTypes[0].compressionRange.run { endInclusive - start }\n    return quality > range * (2 / 5f)\n}\n\nprivate val TiffCompressionScheme.title: String\n    get() = when (this) {\n        TiffCompressionScheme.CCITTRLE -> \"RLE\"\n        TiffCompressionScheme.CCITTFAX3 -> \"FAX 3\"\n        TiffCompressionScheme.CCITTFAX4 -> \"FAX 4\"\n        TiffCompressionScheme.ADOBE_DEFLATE -> \"ADOBE DEFLATE\"\n        else -> this.name\n    }\n\nprivate val Quality.Channels.title\n    @Composable\n    get() = when (this) {\n        Quality.Channels.RGBA -> \"RGBA\"\n        Quality.Channels.RGB -> \"RGB\"\n        Quality.Channels.Monochrome -> stringResource(R.string.monochrome)\n    }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/controls/selection/ScaleModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.controls.selection\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ColorLens\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.ScaleColorSpace\nimport com.t8rin.imagetoolbox.core.domain.image.model.title\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun ScaleModeSelector(\n    value: ImageScaleMode,\n    onValueChange: (ImageScaleMode) -> Unit,\n    modifier: Modifier = Modifier,\n    backgroundColor: Color = Color.Unspecified,\n    shape: Shape = ShapeDefaults.extraLarge,\n    enableItemsCardBackground: Boolean = true,\n    titlePadding: PaddingValues = PaddingValues(top = 8.dp),\n    titleArrangement: Arrangement.Horizontal = Arrangement.Center,\n    entries: List<ImageScaleMode> = ImageScaleMode.defaultEntries(),\n    title: @Composable RowScope.() -> Unit = {\n        Row(verticalAlignment = Alignment.CenterVertically) {\n            Text(\n                text = stringResource(R.string.scale_mode),\n                textAlign = TextAlign.Center,\n                fontWeight = FontWeight.Medium,\n                modifier = Modifier.weight(1f, false)\n            )\n            EnhancedBadge(\n                content = {\n                    Text(entries.size.toString())\n                },\n                containerColor = MaterialTheme.colorScheme.tertiary,\n                contentColor = MaterialTheme.colorScheme.onTertiary,\n                modifier = Modifier\n                    .padding(horizontal = 2.dp)\n                    .padding(bottom = 12.dp)\n                    .scaleOnTap {\n                        AppToastHost.showConfetti()\n                    }\n            )\n        }\n    }\n) {\n    val isColorSpaceSelectionVisible = enableItemsCardBackground && value !is ImageScaleMode.Base\n    var showInfoSheet by rememberSaveable { mutableStateOf(false) }\n    val settingsState = LocalSettingsState.current\n\n    LaunchedEffect(settingsState) {\n        if (value != settingsState.defaultImageScaleMode) {\n            onValueChange(settingsState.defaultImageScaleMode)\n        }\n    }\n\n    Column(\n        modifier = modifier\n            .container(\n                shape = shape,\n                color = backgroundColor\n            ),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Row(\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(titlePadding),\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = titleArrangement\n        ) {\n            title()\n            Spacer(modifier = Modifier.width(8.dp))\n            SupportingButton(\n                onClick = {\n                    showInfoSheet = true\n                }\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n\n        val chipsModifier = Modifier\n            .fillMaxWidth()\n            .then(\n                if (enableItemsCardBackground) {\n                    Modifier\n                        .padding(horizontal = 8.dp)\n                        .container(\n                            color = MaterialTheme.colorScheme.surface,\n                            shape = animateShape(\n                                if (isColorSpaceSelectionVisible) {\n                                    ShapeDefaults.top\n                                } else ShapeDefaults.default\n                            )\n                        )\n                        .padding(horizontal = 8.dp, vertical = 12.dp)\n                } else Modifier.padding(8.dp)\n            )\n\n        val state = rememberLazyStaggeredGridState()\n        LazyHorizontalStaggeredGrid(\n            verticalArrangement = Arrangement.spacedBy(\n                space = 8.dp,\n                alignment = Alignment.CenterVertically\n            ),\n            state = state,\n            horizontalItemSpacing = 8.dp,\n            rows = StaggeredGridCells.Adaptive(30.dp),\n            modifier = Modifier\n                .heightIn(max = if (enableItemsCardBackground) 160.dp else 140.dp)\n                .then(chipsModifier)\n                .fadingEdges(\n                    scrollableState = state,\n                    isVertical = false,\n                    spanCount = 3\n                ),\n            contentPadding = PaddingValues(2.dp),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            items(entries) {\n                val selected by remember(value, it) {\n                    derivedStateOf {\n                        value::class.isInstance(it)\n                    }\n                }\n                EnhancedChip(\n                    onClick = {\n                        onValueChange(it.copy(value.scaleColorSpace))\n                    },\n                    selected = selected,\n                    label = {\n                        Text(text = stringResource(id = it.title))\n                    },\n                    contentPadding = PaddingValues(horizontal = 16.dp, vertical = 6.dp),\n                    selectedColor = MaterialTheme.colorScheme.outlineVariant(\n                        0.2f,\n                        MaterialTheme.colorScheme.tertiary\n                    ),\n                    selectedContentColor = MaterialTheme.colorScheme.onTertiary,\n                    unselectedContentColor = MaterialTheme.colorScheme.onSurface\n                )\n            }\n        }\n\n        AnimatedVisibility(\n            visible = isColorSpaceSelectionVisible,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            val items = remember {\n                ScaleColorSpace.entries\n            }\n            DataSelector(\n                value = value.scaleColorSpace,\n                onValueChange = {\n                    onValueChange(\n                        value.copy(it)\n                    )\n                },\n                spanCount = 2,\n                entries = items,\n                title = stringResource(R.string.tag_color_space),\n                titleIcon = Icons.Outlined.ColorLens,\n                itemContentText = {\n                    it.title\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                shape = ShapeDefaults.bottom,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(top = 4.dp)\n                    .padding(horizontal = 8.dp),\n                selectedItemColor = MaterialTheme.colorScheme.secondary\n            )\n        }\n\n        AnimatedVisibility(isColorSpaceSelectionVisible || enableItemsCardBackground) {\n            Spacer(Modifier.height(8.dp))\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            LazyColumn(\n                modifier = Modifier.fillMaxSize(),\n                contentPadding = PaddingValues(8.dp),\n                verticalArrangement = Arrangement.spacedBy(4.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                itemsIndexed(entries) { index, item ->\n                    val selected by remember(value, item) {\n                        derivedStateOf {\n                            value::class.isInstance(item)\n                        }\n                    }\n                    val containerColor = takeColorFromScheme {\n                        if (selected) secondaryContainer\n                        else SafeLocalContainerColor\n                    }\n                    val contentColor = takeColorFromScheme {\n                        if (selected) onSecondaryContainer\n                        else onSurface\n                    }\n\n                    Column(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .container(\n                                color = containerColor,\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = entries.size\n                                ),\n                                resultPadding = 0.dp\n                            )\n                            .hapticsClickable {\n                                onValueChange(item)\n                            }\n                    ) {\n                        TitleItem(text = stringResource(id = item.title))\n                        Text(\n                            text = stringResource(id = item.subtitle),\n                            modifier = Modifier.padding(\n                                start = 16.dp,\n                                end = 16.dp,\n                                bottom = 16.dp\n                            ),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp,\n                            color = contentColor\n                        )\n                    }\n                }\n            }\n        },\n        visible = showInfoSheet,\n        onDismiss = {\n            showInfoSheet = it\n        },\n        title = {\n            TitleItem(text = stringResource(R.string.scale_mode))\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { showInfoSheet = false }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}\n\n@Composable\nfun ImageScaleMode.Companion.defaultEntries(): List<ImageScaleMode> {\n    val context = LocalResourceManager.current\n    return remember {\n        listOf(ImageScaleMode.Base) + simpleEntries.sortedBy {\n            context.getString(it.title)\n        } + complexEntries.sortedBy {\n            context.getString(it.title)\n        }\n    }\n}\n\nval ScaleColorSpace.title: String\n    @Composable\n    get() = when (this) {\n        is ScaleColorSpace.Linear -> stringResource(R.string.linear)\n        is ScaleColorSpace.SRGB -> \"sRGB\"\n        is ScaleColorSpace.LAB -> \"LAB\"\n        is ScaleColorSpace.LUV -> \"LUV\"\n        is ScaleColorSpace.Sigmoidal -> stringResource(R.string.sigmoidal)\n        is ScaleColorSpace.XYZ -> \"XYZ\"\n        is ScaleColorSpace.F32Gamma22 -> \"${stringResource(R.string.gamma)} 2.2\"\n        is ScaleColorSpace.F32Gamma28 -> \"${stringResource(R.string.gamma)} 2.8\"\n        is ScaleColorSpace.F32Rec709 -> \"Rec.709\"\n        is ScaleColorSpace.F32sRGB -> \"F32 sRGB\"\n        is ScaleColorSpace.LCH -> \"LCH\"\n        is ScaleColorSpace.OklabGamma22 -> \"Oklab G2.2\"\n        is ScaleColorSpace.OklabGamma28 -> \"Oklab G2.8\"\n        is ScaleColorSpace.OklabRec709 -> \"Oklab Rec.709\"\n        is ScaleColorSpace.OklabSRGB -> \"Oklab sRGB\"\n        is ScaleColorSpace.JzazbzGamma22 -> \"Jzazbz ${stringResource(R.string.gamma)} 2.2\"\n        is ScaleColorSpace.JzazbzGamma28 -> \"Jzazbz ${stringResource(R.string.gamma)} 2.8\"\n        is ScaleColorSpace.JzazbzRec709 -> \"Jzazbz Rec.709\"\n        is ScaleColorSpace.JzazbzSRGB -> \"Jzazbz sRGB\"\n    }\n\nprivate val ImageScaleMode.subtitle: Int\n    get() = when (this) {\n        ImageScaleMode.Base,\n        ImageScaleMode.NotPresent -> R.string.basic_sub\n\n        is ImageScaleMode.Bilinear -> R.string.bilinear_sub\n        is ImageScaleMode.Nearest -> R.string.nearest_sub\n        is ImageScaleMode.Cubic -> R.string.cubic_sub\n        is ImageScaleMode.Mitchell -> R.string.mitchell_sub\n        is ImageScaleMode.Catmull -> R.string.catmull_sub\n        is ImageScaleMode.Hermite -> R.string.hermite_sub\n        is ImageScaleMode.BSpline -> R.string.bspline_sub\n        is ImageScaleMode.Hann -> R.string.hann_sub\n        is ImageScaleMode.Bicubic -> R.string.bicubic_sub\n        is ImageScaleMode.Hamming -> R.string.hamming_sub\n        is ImageScaleMode.Hanning -> R.string.hanning_sub\n        is ImageScaleMode.Blackman -> R.string.blackman_sub\n        is ImageScaleMode.Welch -> R.string.welch_sub\n        is ImageScaleMode.Quadric -> R.string.quadric_sub\n        is ImageScaleMode.Gaussian -> R.string.gaussian_sub\n        is ImageScaleMode.Sphinx -> R.string.sphinx_sub\n        is ImageScaleMode.Bartlett -> R.string.bartlett_sub\n        is ImageScaleMode.Robidoux -> R.string.robidoux_sub\n        is ImageScaleMode.RobidouxSharp -> R.string.robidoux_sharp_sub\n        is ImageScaleMode.Spline16 -> R.string.spline16_sub\n        is ImageScaleMode.Spline36 -> R.string.spline36_sub\n        is ImageScaleMode.Spline64 -> R.string.spline64_sub\n        is ImageScaleMode.Kaiser -> R.string.kaiser_sub\n        is ImageScaleMode.BartlettHann -> R.string.bartlett_hann_sub\n        is ImageScaleMode.Box -> R.string.box_sub\n        is ImageScaleMode.Bohman -> R.string.bohman_sub\n        is ImageScaleMode.Lanczos2 -> R.string.lanczos2_sub\n        is ImageScaleMode.Lanczos3 -> R.string.lanczos3_sub\n        is ImageScaleMode.Lanczos4 -> R.string.lanczos4_sub\n        is ImageScaleMode.Lanczos2Jinc -> R.string.lanczos2_jinc_sub\n        is ImageScaleMode.Lanczos3Jinc -> R.string.lanczos3_jinc_sub\n        is ImageScaleMode.Lanczos4Jinc -> R.string.lanczos4_jinc_sub\n        is ImageScaleMode.EwaHanning -> R.string.ewa_hanning_sub\n        is ImageScaleMode.EwaRobidoux -> R.string.ewa_robidoux_sub\n        is ImageScaleMode.EwaBlackman -> R.string.ewa_blackman_sub\n        is ImageScaleMode.EwaQuadric -> R.string.ewa_quadric_sub\n        is ImageScaleMode.EwaRobidouxSharp -> R.string.ewa_robidoux_sharp_sub\n        is ImageScaleMode.EwaLanczos3Jinc -> R.string.ewa_lanczos3_jinc_sub\n        is ImageScaleMode.Ginseng -> R.string.ginseng_sub\n        is ImageScaleMode.EwaGinseng -> R.string.ewa_ginseng_sub\n        is ImageScaleMode.EwaLanczosSharp -> R.string.ewa_lanczos_sharp_sub\n        is ImageScaleMode.EwaLanczos4Sharpest -> R.string.ewa_lanczos_4_sharpest_sub\n        is ImageScaleMode.EwaLanczosSoft -> R.string.ewa_lanczos_soft_sub\n        is ImageScaleMode.HaasnSoft -> R.string.haasn_soft_sub\n        is ImageScaleMode.Lagrange2 -> R.string.lagrange_2_sub\n        is ImageScaleMode.Lagrange3 -> R.string.lagrange_3_sub\n        is ImageScaleMode.Lanczos6 -> R.string.lanczos_6_sub\n        is ImageScaleMode.Lanczos6Jinc -> R.string.lanczos_6_jinc_sub\n        is ImageScaleMode.Area -> R.string.area_sub\n    }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/CalculatorDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Calculate\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport com.github.keelar.exprk.Expressions\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport java.math.BigDecimal\n\n@Composable\nfun CalculatorDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    initialValue: BigDecimal?,\n    onValueChange: (BigDecimal) -> Unit\n) {\n    var calculatorExpression by rememberSaveable(initialValue, visible) {\n        mutableStateOf(initialValue?.toString() ?: \"\")\n    }\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    runCatching {\n                        Expressions().eval(calculatorExpression)\n                    }.onFailure {\n                        AppToastHost.showFailureToast(it)\n                    }.onSuccess {\n                        onValueChange(it)\n                        onDismiss()\n                    }\n                }\n            ) {\n                Text(stringResource(R.string.apply))\n            }\n        },\n        title = {\n            Text(\n                text = stringResource(R.string.calculate)\n            )\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.Calculate,\n                contentDescription = null\n            )\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        text = {\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                OutlinedTextField(\n                    shape = ShapeDefaults.default,\n                    value = calculatorExpression,\n                    textStyle = MaterialTheme.typography.titleMedium.copy(\n                        textAlign = TextAlign.Center\n                    ),\n                    maxLines = 1,\n                    placeholder = {\n                        Text(\n                            text = stringResource(R.string.math_expression),\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                    },\n                    onValueChange = { expr ->\n                        calculatorExpression = expr.filter { !it.isWhitespace() }\n                    },\n                    supportingText = {\n                        Text(stringResource(R.string.calculate_hint))\n                    }\n                )\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/ExitWithoutSavingDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Save\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\n\n@Composable\nfun ExitWithoutSavingDialog(\n    onExit: () -> Unit,\n    onDismiss: () -> Unit,\n    visible: Boolean,\n    placeAboveAll: Boolean = false,\n    text: String = stringResource(R.string.image_not_saved_sub),\n    title: String = stringResource(R.string.image_not_saved),\n    icon: ImageVector = Icons.Outlined.Save\n) {\n    val settingsState = LocalSettingsState.current\n\n    if (!settingsState.enableToolExitConfirmation) {\n        LaunchedEffect(visible) {\n            if (visible) onExit()\n        }\n    } else {\n        EnhancedAlertDialog(\n            visible = visible,\n            onDismissRequest = onDismiss,\n            placeAboveAll = placeAboveAll,\n            dismissButton = {\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    onClick = {\n                        onDismiss()\n                        onExit()\n                    }\n                ) {\n                    Text(stringResource(R.string.exit))\n                }\n            },\n            confirmButton = {\n                EnhancedButton(\n                    onClick = onDismiss\n                ) {\n                    Text(stringResource(R.string.stay))\n                }\n            },\n            title = { Text(text = title) },\n            text = {\n                Text(\n                    text = text,\n                    textAlign = TextAlign.Center\n                )\n            },\n            icon = {\n                Icon(\n                    imageVector = icon,\n                    contentDescription = null\n                )\n            }\n        )\n    }\n}\n\n@Composable\nfun ExitBackHandler(\n    enabled: Boolean = true,\n    onBack: () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n\n    if (settingsState.enableToolExitConfirmation) {\n        BackHandler(\n            enabled = enabled,\n            onBack = onBack\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/LoadingDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.keepScreenOn\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.BasicEnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\n\n@Composable\nfun LoadingDialog(\n    visible: Boolean,\n    onCancelLoading: () -> Unit = {},\n    canCancel: Boolean = true,\n    isForSaving: Boolean = true\n) {\n    var showWantDismissDialog by remember(canCancel, visible) { mutableStateOf(false) }\n    BasicEnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = { showWantDismissDialog = canCancel },\n        modifier = Modifier.keepScreenOn()\n    ) {\n        val focus = LocalFocusManager.current\n        LaunchedEffect(focus) {\n            focus.clearFocus()\n        }\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .tappable {\n                    showWantDismissDialog = canCancel\n                },\n            contentAlignment = Alignment.Center,\n            content = {\n                EnhancedLoadingIndicator(modifier = Modifier.size(108.dp))\n            }\n        )\n    }\n    WantCancelLoadingDialog(\n        visible = showWantDismissDialog,\n        onCancelLoading = onCancelLoading,\n        onDismissDialog = {\n            showWantDismissDialog = false\n        },\n        isForSaving = isForSaving\n    )\n}\n\n@Composable\nfun LoadingDialog(\n    visible: Boolean,\n    done: Int,\n    left: Int,\n    onCancelLoading: () -> Unit,\n    canCancel: Boolean = true,\n) {\n    if (left < 0) {\n        LoadingDialog(\n            visible = visible,\n            onCancelLoading = onCancelLoading,\n            canCancel = canCancel && visible\n        )\n    } else {\n        ProgressLoadingDialog(\n            visible = visible,\n            done = done,\n            left = left,\n            onCancelLoading = onCancelLoading,\n            canCancel = canCancel && visible\n        )\n    }\n}\n\n@Composable\nfun LoadingDialog(\n    visible: Boolean,\n    progress: () -> Float,\n    onCancelLoading: () -> Unit = {},\n    canCancel: Boolean = true,\n    loaderSize: Dp = 60.dp,\n    switchToIndicator: Boolean = false,\n    isLayoutSwappable: Boolean = true,\n    additionalContent: @Composable (Dp) -> Unit = {}\n) {\n    val progress = progress()\n\n    if (progress == 1f && visible && isLayoutSwappable) {\n        LoadingDialog(\n            visible = true,\n            onCancelLoading = onCancelLoading,\n            canCancel = canCancel\n        )\n    } else {\n        var showWantDismissDialog by remember(canCancel, visible) { mutableStateOf(false) }\n        BasicEnhancedAlertDialog(\n            visible = visible,\n            onDismissRequest = { showWantDismissDialog = canCancel },\n            modifier = Modifier.keepScreenOn()\n        ) {\n            val focus = LocalFocusManager.current\n            LaunchedEffect(focus) {\n                focus.clearFocus()\n            }\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .tappable(Unit) {\n                        showWantDismissDialog = canCancel\n                    },\n                contentAlignment = Alignment.Center,\n                content = {\n                    AnimatedContent(\n                        targetState = switchToIndicator,\n                        modifier = Modifier\n                            .size(120.dp)\n                            .align(Alignment.Center)\n                    ) { isIndicator ->\n                        Box(\n                            modifier = Modifier.fillMaxSize(),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            if (isIndicator) {\n                                EnhancedLoadingIndicator(\n                                    modifier = Modifier.size(108.dp)\n                                )\n                            } else {\n                                EnhancedLoadingIndicator(\n                                    progress = progress(),\n                                    loaderSize = loaderSize,\n                                    additionalContent = additionalContent\n                                )\n                            }\n                        }\n                    }\n                }\n            )\n        }\n        WantCancelLoadingDialog(\n            visible = showWantDismissDialog,\n            onCancelLoading = onCancelLoading,\n            onDismissDialog = {\n                showWantDismissDialog = false\n            },\n            modifier = Modifier.keepScreenOn()\n        )\n    }\n}\n\n\n@Composable\nprivate fun ProgressLoadingDialog(\n    visible: Boolean,\n    done: Int,\n    left: Int,\n    onCancelLoading: () -> Unit,\n    canCancel: Boolean = true,\n) {\n    var showWantDismissDialog by remember(canCancel, visible) { mutableStateOf(false) }\n    BasicEnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = { showWantDismissDialog = canCancel },\n        modifier = Modifier.keepScreenOn()\n    ) {\n        val focus = LocalFocusManager.current\n        LaunchedEffect(focus) {\n            focus.clearFocus()\n        }\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .tappable(Unit) {\n                    showWantDismissDialog = canCancel\n                },\n            contentAlignment = Alignment.Center,\n            content = {\n                EnhancedLoadingIndicator(\n                    done = done,\n                    left = left\n                )\n            }\n        )\n    }\n    WantCancelLoadingDialog(\n        visible = showWantDismissDialog,\n        onCancelLoading = onCancelLoading,\n        onDismissDialog = {\n            showWantDismissDialog = false\n        },\n        modifier = Modifier.keepScreenOn()\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/OneTimeImagePickingDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ImageSearch\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.PicturePickerMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.PicturePickerModeSaver\n\n@Composable\nfun OneTimeImagePickingDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    picker: Picker,\n    imagePicker: ImagePicker\n) {\n    val settingsState = LocalSettingsState.current\n\n    var selectedPickerMode by rememberSaveable(stateSaver = PicturePickerModeSaver) {\n        mutableStateOf(settingsState.picturePickerMode)\n    }\n\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    onDismiss()\n                    imagePicker.pickImageWithMode(\n                        picker = picker,\n                        picturePickerMode = selectedPickerMode\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.primary\n            ) {\n                Text(text = stringResource(id = R.string.pick))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                onClick = onDismiss,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(text = stringResource(id = R.string.close))\n            }\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.ImageSearch,\n                contentDescription = stringResource(id = R.string.image_source)\n            )\n        },\n        title = {\n            Text(text = stringResource(id = R.string.image_source))\n        },\n        text = {\n            val scrollState = rememberScrollState()\n            ProvideTextStyle(LocalTextStyle.current.copy(textAlign = TextAlign.Start)) {\n                Column(\n                    modifier = Modifier\n                        .fadingEdges(\n                            scrollableState = scrollState,\n                            isVertical = true\n                        )\n                        .enhancedVerticalScroll(scrollState)\n                        .padding(vertical = 2.dp),\n                    verticalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    val data = remember {\n                        PicturePickerMode.entries\n                    }\n\n                    data.forEachIndexed { index, mode ->\n                        val selected = selectedPickerMode.ordinal == mode.ordinal\n\n                        val shape = ShapeDefaults.byIndex(\n                            index = index,\n                            size = data.size\n                        )\n                        PreferenceItem(\n                            shape = shape,\n                            onClick = { selectedPickerMode = mode },\n                            title = stringResource(mode.title),\n                            startIcon = mode.icon,\n                            containerColor = takeColorFromScheme {\n                                if (selected) secondaryContainer.copy(0.7f)\n                                else SafeLocalContainerColor\n                            },\n                            endIcon = if (selected) {\n                                Icons.Rounded.RadioButtonChecked\n                            } else Icons.Rounded.RadioButtonUnchecked,\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .padding(horizontal = 8.dp)\n                                .border(\n                                    width = settingsState.borderWidth,\n                                    color = animateColorAsState(\n                                        if (selected) {\n                                            MaterialTheme.colorScheme.onSecondaryContainer.copy(\n                                                0.5f\n                                            )\n                                        } else Color.Transparent\n                                    ).value,\n                                    shape = shape\n                                )\n                        )\n                    }\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/OneTimeSaveLocationSelectionDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CreateNewFolder\nimport androidx.compose.material.icons.outlined.DriveFileRenameOutline\nimport androidx.compose.material.icons.outlined.SaveAs\nimport androidx.compose.material.icons.rounded.Folder\nimport androidx.compose.material.icons.rounded.FolderOpen\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.FileReplace\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFolderPicker\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealDirection\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealValue\nimport com.t8rin.imagetoolbox.core.ui.widget.other.SwipeToReveal\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberRevealState\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.core.utils.uiPath\nimport kotlinx.coroutines.launch\n\n\n@Composable\nfun OneTimeSaveLocationSelectionDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onSaveRequest: ((String?) -> Unit)?,\n    formatForFilenameSelection: ImageFormat? = null\n) {\n    val settingsState = LocalSettingsState.current\n    val settingsInteractor = LocalSimpleSettingsInteractor.current\n    var tempSelectedSaveFolderUri by rememberSaveable(visible) {\n        mutableStateOf(settingsState.saveFolderUri?.toString())\n    }\n    var selectedSaveFolderUri by rememberSaveable(visible) {\n        mutableStateOf(settingsState.saveFolderUri?.toString())\n    }\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        confirmButton = {\n            onSaveRequest?.let {\n                EnhancedButton(\n                    onClick = {\n                        onDismiss()\n                        onSaveRequest(selectedSaveFolderUri)\n                    },\n                    containerColor = MaterialTheme.colorScheme.primary\n                ) {\n                    Text(text = stringResource(id = R.string.save))\n                }\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                onClick = onDismiss,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(text = stringResource(id = R.string.close))\n            }\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.SaveAs,\n                contentDescription = stringResource(id = R.string.folder)\n            )\n        },\n        title = {\n            Text(text = stringResource(id = R.string.folder))\n        },\n        text = {\n            val data by remember(settingsState.oneTimeSaveLocations, tempSelectedSaveFolderUri) {\n                derivedStateOf {\n                    settingsState.oneTimeSaveLocations.plus(\n                        tempSelectedSaveFolderUri?.let {\n                            OneTimeSaveLocation(\n                                uri = it,\n                                date = null,\n                                count = 0\n                            )\n                        }\n                    ).plus(\n                        settingsState.saveFolderUri?.toString()?.let {\n                            OneTimeSaveLocation(\n                                uri = it,\n                                date = null,\n                                count = 0\n                            )\n                        }\n                    ).distinctBy { it?.uri }\n                }\n            }\n\n            val scope = rememberCoroutineScope()\n\n            val scrollState = rememberScrollState()\n            Column(\n                modifier = Modifier\n                    .fadingEdges(\n                        scrollableState = scrollState,\n                        isVertical = true\n                    )\n                    .enhancedVerticalScroll(scrollState)\n            ) {\n                Spacer(Modifier.height(4.dp))\n                data.forEachIndexed { index, item ->\n                    val title by remember(item) {\n                        derivedStateOf {\n                            val default = getString(R.string.default_folder)\n                            item?.uri?.toUri()?.uiPath(default = default) ?: default\n                        }\n                    }\n                    val subtitle by remember(item) {\n                        derivedStateOf {\n                            if (item?.uri == settingsState.saveFolderUri?.toString()) {\n                                getString(R.string.default_value)\n                            } else {\n                                val time = item?.date?.let {\n                                    timestamp(\n                                        format = \"dd MMMM yyyy\",\n                                        date = it\n                                    )\n                                } ?: \"\"\n\n                                \"$time ${\n                                    item?.count?.takeIf { it > 0 }\n                                        ?.let { \"($it)\" } ?: \"\"\n                                }\".trim()\n                                    .takeIf { it.isNotEmpty() }\n                            }\n                        }\n                    }\n                    val selected = selectedSaveFolderUri == item?.uri\n                    val state = rememberRevealState()\n                    val interactionSource = remember {\n                        MutableInteractionSource()\n                    }\n                    val isDragged by interactionSource.collectIsDraggedAsState()\n                    val shape = ShapeDefaults.byIndex(\n                        index = index,\n                        size = data.size + 1,\n                        forceDefault = isDragged\n                    )\n                    val canDeleteItem by remember(item, settingsState) {\n                        derivedStateOf {\n                            item != null && item in settingsState.oneTimeSaveLocations\n                        }\n                    }\n\n                    SwipeToReveal(\n                        state = state,\n                        revealedContentEnd = {\n                            Box(\n                                modifier = Modifier\n                                    .fillMaxSize()\n                                    .container(\n                                        color = MaterialTheme.colorScheme.errorContainer,\n                                        shape = shape,\n                                        autoShadowElevation = 0.dp,\n                                        resultPadding = 0.dp\n                                    )\n                                    .hapticsClickable {\n                                        scope.launch {\n                                            state.animateTo(RevealValue.Default)\n                                        }\n                                        scope.launch {\n                                            settingsInteractor.setOneTimeSaveLocations((settingsState.oneTimeSaveLocations - item).filterNotNull())\n                                            if (item?.uri == selectedSaveFolderUri) {\n                                                selectedSaveFolderUri = null\n                                                tempSelectedSaveFolderUri = null\n                                            }\n                                        }\n                                    }\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Outlined.Delete,\n                                    contentDescription = stringResource(R.string.delete),\n                                    modifier = Modifier\n                                        .padding(16.dp)\n                                        .padding(end = 8.dp)\n                                        .align(Alignment.CenterEnd),\n                                    tint = MaterialTheme.colorScheme.onErrorContainer\n                                )\n                            }\n                        },\n                        directions = setOf(RevealDirection.EndToStart),\n                        swipeableContent = {\n                            PreferenceItem(\n                                title = title,\n                                subtitle = subtitle,\n                                shape = shape,\n                                titleFontStyle = PreferenceItemDefaults.TitleFontStyleSmall,\n                                onClick = {\n                                    if (item != null) {\n                                        tempSelectedSaveFolderUri = item.uri\n                                    }\n                                    selectedSaveFolderUri = item?.uri\n                                },\n                                onLongClick = if (item != null) {\n                                    {\n                                        scope.launch {\n                                            state.animateTo(RevealValue.FullyRevealedStart)\n                                        }\n                                    }\n                                } else null,\n                                enabled = settingsState.filenameBehavior !is FilenameBehavior.Overwrite,\n                                startIconTransitionSpec = {\n                                    fadeIn() togetherWith fadeOut()\n                                },\n                                modifier = Modifier.fillMaxWidth(),\n                                startIcon = if (selected) {\n                                    Icons.Rounded.Folder\n                                } else Icons.Rounded.FolderOpen,\n                                endIcon = if (selected) Icons.Rounded.RadioButtonChecked\n                                else Icons.Rounded.RadioButtonUnchecked,\n                                containerColor = takeColorFromScheme {\n                                    if (selected) surface\n                                    else surfaceContainer\n                                }\n                            )\n                        },\n                        enableSwipe = canDeleteItem && settingsState.filenameBehavior !is FilenameBehavior.Overwrite,\n                        interactionSource = interactionSource,\n                        modifier = Modifier\n                            .fadingEdges(\n                                scrollableState = null,\n                                length = 4.dp\n                            )\n                            .padding(horizontal = 4.dp, vertical = 2.dp)\n                    )\n                }\n                val currentFolderUri = selectedSaveFolderUri?.toUri() ?: settingsState.saveFolderUri\n                val launcher = rememberFolderPicker(\n                    onSuccess = { uri ->\n                        tempSelectedSaveFolderUri = uri.toString()\n                        selectedSaveFolderUri = uri.toString()\n                    }\n                )\n\n                PreferenceItem(\n                    title = stringResource(id = R.string.add_new_folder),\n                    startIcon = Icons.Outlined.CreateNewFolder,\n                    shape = ShapeDefaults.bottom,\n                    titleFontStyle = PreferenceItemDefaults.TitleFontStyleSmall,\n                    onClick = {\n                        launcher.pickFolder(currentFolderUri)\n                    },\n                    enabled = settingsState.filenameBehavior !is FilenameBehavior.Overwrite,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 4.dp, vertical = 2.dp),\n                    containerColor = MaterialTheme.colorScheme.surfaceContainer\n                )\n\n                if (formatForFilenameSelection != null) {\n                    val createLauncher = rememberFileCreator(\n                        mimeType = formatForFilenameSelection.mimeType,\n                        onSuccess = { uri ->\n                            onSaveRequest?.invoke(uri.toString())\n                            onDismiss()\n                        }\n                    )\n\n                    val imageString = stringResource(R.string.image)\n                    PreferenceItem(\n                        title = stringResource(id = R.string.custom_filename),\n                        subtitle = stringResource(id = R.string.custom_filename_sub),\n                        startIcon = Icons.Outlined.DriveFileRenameOutline,\n                        shape = ShapeDefaults.default,\n                        titleFontStyle = PreferenceItemDefaults.TitleFontStyleSmall,\n                        enabled = settingsState.filenameBehavior !is FilenameBehavior.Overwrite,\n                        onClick = {\n                            createLauncher.make(\"$imageString.${formatForFilenameSelection.extension}\")\n                        },\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(horizontal = 4.dp, vertical = 2.dp),\n                        containerColor = MaterialTheme.colorScheme.surfaceContainer\n                    )\n                }\n\n                PreferenceRowSwitch(\n                    title = stringResource(id = R.string.overwrite_files),\n                    subtitle = stringResource(id = R.string.overwrite_files_sub_short),\n                    startIcon = Icons.Outlined.FileReplace,\n                    enabled = settingsState.filenameBehavior is FilenameBehavior.Overwrite || settingsState.filenameBehavior is FilenameBehavior.None,\n                    shape = ShapeDefaults.default,\n                    titleFontStyle = PreferenceItemDefaults.TitleFontStyleSmall,\n                    checked = settingsState.filenameBehavior is FilenameBehavior.Overwrite,\n                    onClick = {\n                        scope.launch { settingsInteractor.toggleOverwriteFiles() }\n                    },\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 4.dp, vertical = 2.dp),\n                    containerColor = MaterialTheme.colorScheme.surfaceContainer\n                )\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/PasswordRequestDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Password\nimport androidx.compose.material.icons.outlined.Shield\nimport androidx.compose.material.icons.outlined.Visibility\nimport androidx.compose.material.icons.outlined.VisibilityOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.PasswordVisualTransformation\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\n\n@Composable\nfun PasswordRequestDialog(\n    isVisible: Boolean,\n    onDismiss: () -> Unit,\n    onFillPassword: (String) -> Unit\n) {\n    var password by remember(isVisible) {\n        mutableStateOf(\"\")\n    }\n    var hidePassword by remember(isVisible) {\n        mutableStateOf(true)\n    }\n\n    EnhancedAlertDialog(\n        visible = isVisible,\n        onDismissRequest = {},\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.Shield,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(stringResource(R.string.password))\n        },\n        text = {\n            RoundedTextField(\n                value = password,\n                onValueChange = {\n                    password = it\n                },\n                textStyle = LocalTextStyle.current.copy(\n                    textAlign = TextAlign.Center\n                ),\n                label = null,\n                modifier = Modifier\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp\n                    ),\n                singleLine = true,\n                visualTransformation = if (hidePassword) {\n                    PasswordVisualTransformation()\n                } else {\n                    VisualTransformation.None\n                },\n                hint = {\n                    Text(\n                        text = stringResource(R.string.pdf_is_protected),\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                },\n                startIcon = {\n                    Icon(\n                        imageVector = Icons.Filled.Password,\n                        contentDescription = null\n                    )\n                },\n                endIcon = {\n                    EnhancedIconButton(\n                        onClick = { hidePassword = !hidePassword }\n                    ) {\n                        Icon(\n                            imageVector = if (hidePassword) {\n                                Icons.Outlined.VisibilityOff\n                            } else {\n                                Icons.Outlined.Visibility\n                            },\n                            contentDescription = null\n                        )\n                    }\n                }\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                enabled = password.isNotEmpty(),\n                onClick = { onFillPassword(password) }\n            ) {\n                Text(stringResource(R.string.unlock))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/ResetDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.DoneOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun ResetDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onReset: () -> Unit,\n    title: String = stringResource(R.string.reset_image),\n    text: String = stringResource(R.string.reset_image_sub),\n    icon: ImageVector = Icons.Rounded.ImageReset\n) {\n    EnhancedAlertDialog(\n        visible = visible,\n        icon = {\n            Icon(\n                imageVector = icon,\n                contentDescription = title\n            )\n        },\n        title = { Text(title) },\n        text = {\n            Text(\n                text = text,\n                modifier = Modifier.fillMaxWidth()\n            )\n        },\n        onDismissRequest = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    onReset()\n                    onDismiss()\n                    AppToastHost.showToast(\n                        message = getString(R.string.values_reset),\n                        icon = Icons.Rounded.DoneOutline\n                    )\n                }\n            ) {\n                Text(stringResource(R.string.reset))\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/dialogs/WantCancelLoadingDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.dialogs\n\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCircularProgressIndicator\n\n@Composable\nfun WantCancelLoadingDialog(\n    visible: Boolean,\n    onCancelLoading: () -> Unit,\n    onDismissDialog: () -> Unit,\n    modifier: Modifier = Modifier,\n    isForSaving: Boolean = true,\n) {\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismissDialog,\n        confirmButton = {\n            EnhancedButton(\n                onClick = onDismissDialog\n            ) {\n                Text(stringResource(id = R.string.wait))\n            }\n        },\n        title = {\n            Text(stringResource(id = R.string.loading))\n        },\n        text = {\n            Text(\n                text = stringResource(\n                    if (isForSaving) R.string.saving_almost_complete\n                    else R.string.operation_almost_complete\n                )\n            )\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onCancelLoading\n            ) {\n                Text(stringResource(id = R.string.cancel))\n            }\n        },\n        icon = {\n            EnhancedCircularProgressIndicator(\n                modifier = Modifier.size(24.dp),\n                trackColor = MaterialTheme.colorScheme.primary.copy(0.2f),\n                strokeWidth = 3.dp\n            )\n        },\n        modifier = modifier\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedAlertDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.safeDrawingPadding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.material3.AlertDialogDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalInspectionMode\nimport androidx.compose.ui.semantics.paneTitle\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.window.Dialog\nimport androidx.compose.ui.window.DialogProperties\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.alertDialogBorder\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\nimport com.t8rin.modalsheet.FullscreenPopup\nimport kotlinx.coroutines.delay\n\n@Composable\nfun EnhancedAlertDialog(\n    visible: Boolean,\n    onDismissRequest: () -> Unit,\n    confirmButton: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    dismissButton: @Composable (() -> Unit)? = null,\n    icon: @Composable (() -> Unit)? = null,\n    title: @Composable (() -> Unit)? = null,\n    text: @Composable (() -> Unit)? = null,\n    placeAboveAll: Boolean = false,\n    shape: Shape = AlertDialogDefaults.shape,\n    containerColor: Color = AlertDialogDefaults.containerColor,\n    iconContentColor: Color = AlertDialogDefaults.iconContentColor,\n    titleContentColor: Color = AlertDialogDefaults.titleContentColor,\n    textContentColor: Color = AlertDialogDefaults.textContentColor,\n    tonalElevation: Dp = AlertDialogDefaults.TonalElevation\n) {\n    BasicEnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismissRequest,\n        placeAboveAll = placeAboveAll,\n        content = {\n            val isCenterAlignButtons = LocalSettingsState.current.isCenterAlignDialogButtons\n\n            EnhancedAlertDialogContent(\n                buttons = {\n                    FlowRow(\n                        modifier = Modifier.fillMaxWidth(),\n                        horizontalArrangement = Arrangement.spacedBy(\n                            space = ButtonsHorizontalSpacing,\n                            alignment = if (dismissButton != null && isCenterAlignButtons) {\n                                Alignment.CenterHorizontally\n                            } else Alignment.End\n                        ),\n                        verticalArrangement = Arrangement.spacedBy(\n                            space = ButtonsVerticalSpacing,\n                            alignment = if (dismissButton != null && isCenterAlignButtons) {\n                                Alignment.CenterVertically\n                            } else Alignment.Bottom\n                        ),\n                        itemVerticalAlignment = Alignment.CenterVertically\n                    ) {\n                        dismissButton?.invoke()\n                        confirmButton()\n                    }\n                },\n                icon = icon,\n                title = title,\n                text = text,\n                shape = shape,\n                containerColor = containerColor,\n                tonalElevation = tonalElevation,\n                // Note that a button content color is provided here from the dialog's token, but in\n                // most cases, TextButtons should be used for dismiss and confirm buttons.\n                // TextButtons will not consume this provided content color value, and will be used their\n                // own defined or default colors.\n                buttonContentColor = MaterialTheme.colorScheme.primary,\n                iconContentColor = iconContentColor,\n                titleContentColor = titleContentColor,\n                textContentColor = textContentColor,\n                modifier = modifier\n                    .alertDialogBorder()\n                    .sizeIn(\n                        minWidth = DialogMinWidth,\n                        maxWidth = DialogMaxWidth\n                    )\n                    .then(Modifier.semantics { paneTitle = \"Dialog\" })\n            )\n        }\n    )\n}\n\n@Composable\nfun BasicEnhancedAlertDialog(\n    visible: Boolean,\n    onDismissRequest: (() -> Unit)?,\n    modifier: Modifier = Modifier,\n    placeAboveAll: Boolean = false,\n    content: @Composable BoxScope.() -> Unit\n) {\n    var visibleAnimated by remember { mutableStateOf(false) }\n\n    var scale by remember {\n        mutableFloatStateOf(1f)\n    }\n    val animatedScale by animateFloatAsState(scale)\n\n    LaunchedEffect(visible) {\n        if (visible) {\n            scale = 1f\n            visibleAnimated = true\n        }\n    }\n\n    if (visibleAnimated) {\n        FullscreenPopupForPreview(placeAboveAll = placeAboveAll) {\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                var animateIn by rememberSaveable { mutableStateOf(false) }\n                LaunchedEffect(Unit) { animateIn = true }\n                AnimatedVisibility(\n                    visible = animateIn && visible,\n                    enter = fadeIn(),\n                    exit = fadeOut(),\n                ) {\n                    val alpha = 0.5f * animatedScale\n\n                    Box(\n                        modifier = Modifier\n                            .tappable { onDismissRequest?.invoke() }\n                            .background(MaterialTheme.colorScheme.scrim.copy(alpha = alpha))\n                            .fillMaxSize()\n                    )\n                }\n                AnimatedVisibility(\n                    visible = animateIn && visible,\n                    enter = fadeIn(tween(300)) + scaleIn(\n                        initialScale = .8f,\n                        animationSpec = spring(\n                            dampingRatio = Spring.DampingRatioMediumBouncy,\n                            stiffness = Spring.StiffnessMediumLow\n                        )\n                    ),\n                    exit = fadeOut(tween(300)) + scaleOut(\n                        targetScale = .8f,\n                        animationSpec = spring(\n                            dampingRatio = Spring.DampingRatioMediumBouncy,\n                            stiffness = Spring.StiffnessMediumLow\n                        )\n                    ),\n                    modifier = Modifier.scale(animatedScale)\n                ) {\n                    Box(\n                        modifier = modifier\n                            .safeDrawingPadding()\n                            .padding(horizontal = 48.dp, vertical = 24.dp),\n                        contentAlignment = Alignment.Center,\n                        content = content\n                    )\n                }\n            }\n\n            DisposableEffect(Unit) {\n                onDispose {\n                    visibleAnimated = false\n                }\n            }\n\n            if (onDismissRequest != null) {\n                PredictiveBackObserver(\n                    onProgress = { progress ->\n                        scale = (1f - progress / 6f).coerceAtLeast(0.85f)\n                    },\n                    onClean = { isCompleted ->\n                        if (isCompleted) {\n                            onDismissRequest()\n                            delay(400)\n                        }\n                        scale = 1f\n                    },\n                    enabled = visible\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun EnhancedAlertDialogContent(\n    buttons: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    icon: (@Composable () -> Unit)?,\n    title: (@Composable () -> Unit)?,\n    text: @Composable (() -> Unit)?,\n    shape: Shape,\n    containerColor: Color,\n    tonalElevation: Dp,\n    buttonContentColor: Color,\n    iconContentColor: Color,\n    titleContentColor: Color,\n    textContentColor: Color,\n) {\n    Surface(\n        modifier = modifier,\n        shape = shape,\n        color = containerColor,\n        tonalElevation = tonalElevation,\n    ) {\n        Column(modifier = Modifier.padding(DialogPadding)) {\n            icon?.let {\n                CompositionLocalProvider(LocalContentColor provides iconContentColor) {\n                    Box(\n                        Modifier\n                            .padding(IconPadding)\n                            .align(Alignment.CenterHorizontally)\n                    ) {\n                        IconShapeContainer(\n                            contentColor = iconContentColor,\n                            containerColor = MaterialTheme.colorScheme.surfaceContainerLow,\n                            content = {\n                                icon()\n                            }\n                        )\n                    }\n                }\n            }\n            title?.let {\n                ProvideContentColorTextStyle(\n                    contentColor = titleContentColor,\n                    textStyle = MaterialTheme.typography.headlineSmall\n                ) {\n                    Box(\n                        // Align the title to the center when an icon is present.\n                        Modifier\n                            .padding(TitlePadding)\n                            .align(\n                                if (icon == null) {\n                                    Alignment.Start\n                                } else {\n                                    Alignment.CenterHorizontally\n                                }\n                            )\n                    ) {\n                        title()\n                    }\n                }\n            }\n            text?.let {\n                val textStyle = MaterialTheme.typography.bodyMedium\n                ProvideContentColorTextStyle(\n                    contentColor = textContentColor,\n                    textStyle = textStyle\n                ) {\n                    Box(\n                        Modifier\n                            .weight(weight = 1f, fill = false)\n                            .padding(TextPadding)\n                            .align(Alignment.Start)\n                    ) {\n                        text()\n                    }\n                }\n            }\n            Box(modifier = Modifier.align(Alignment.End)) {\n                val textStyle = MaterialTheme.typography.labelLarge\n                ProvideContentColorTextStyle(\n                    contentColor = buttonContentColor,\n                    textStyle = textStyle,\n                    content = buttons\n                )\n            }\n        }\n    }\n}\n\n@Composable\nfun ProvideContentColorTextStyle(\n    contentColor: Color,\n    textStyle: TextStyle,\n    content: @Composable () -> Unit\n) {\n    val mergedStyle = LocalTextStyle.current.merge(textStyle)\n    CompositionLocalProvider(\n        LocalContentColor provides contentColor,\n        LocalTextStyle provides mergedStyle,\n        content = content\n    )\n}\n\nprivate val DialogMinWidth = 280.dp\nprivate val DialogMaxWidth = 480.dp\n\nprivate val ButtonsHorizontalSpacing = 8.dp\nprivate val ButtonsVerticalSpacing = 12.dp\n\n// Paddings for each of the dialog's parts.\nprivate val DialogPadding = PaddingValues(all = 24.dp)\nprivate val IconPadding = PaddingValues(bottom = 16.dp)\nprivate val TitlePadding = PaddingValues(bottom = 16.dp)\nprivate val TextPadding = PaddingValues(bottom = 24.dp)\n\n\n@Composable\nprivate fun FullscreenPopupForPreview(\n    onDismiss: (() -> Unit)? = null,\n    placeAboveAll: Boolean = false,\n    content: @Composable () -> Unit\n) {\n    if (LocalInspectionMode.current) {\n        Dialog(\n            properties = DialogProperties(usePlatformDefaultWidth = false),\n            onDismissRequest = { onDismiss?.invoke() }\n        ) {\n            content()\n        }\n    } else {\n        FullscreenPopup(\n            onDismiss = onDismiss,\n            placeAboveAll = placeAboveAll,\n            content = content\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedBadge.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.BadgeDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun EnhancedBadge(\n    modifier: Modifier = Modifier,\n    containerColor: Color = BadgeDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    shape: Shape = ShapeDefaults.circle,\n    content: @Composable (RowScope.() -> Unit)? = null,\n) {\n    val size = if (content != null) 16.dp else 6.dp\n\n    Row(\n        modifier = modifier\n            .defaultMinSize(minWidth = size, minHeight = size)\n            .background(color = containerColor, shape = shape)\n            .then(\n                if (content != null)\n                    Modifier.padding(horizontal = 4.dp)\n                else Modifier\n            ),\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.Center,\n    ) {\n        if (content != null) {\n            val mergedStyle = LocalTextStyle.current.merge(MaterialTheme.typography.labelSmall)\n            CompositionLocalProvider(\n                LocalContentColor provides contentColor,\n                LocalTextStyle provides mergedStyle,\n                content = {\n                    content()\n                }\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedButton\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalViewConfiguration\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.DisabledAlpha\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.materialShadow\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collectLatest\n\n@Composable\nfun EnhancedButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    onLongClick: (() -> Unit)? = null,\n    enabled: Boolean = true,\n    containerColor: Color = MaterialTheme.colorScheme.primary,\n    contentColor: Color = contentColor(containerColor),\n    borderColor: Color = MaterialTheme.colorScheme.outlineVariant(onTopOf = containerColor),\n    shape: Shape = AutoCircleShape(),\n    pressedShape: Shape = ButtonDefaults.pressedShape,\n    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    isShadowClip: Boolean = containerColor.alpha != 1f,\n    content: @Composable RowScope.() -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val haptics = LocalHapticFeedback.current\n    val focus = LocalFocusManager.current\n\n    LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n        Box {\n            if (onLongClick != null) {\n                val viewConfiguration = LocalViewConfiguration.current\n\n\n                LaunchedEffect(interactionSource) {\n                    var isLongClick = false\n\n                    interactionSource.interactions.collectLatest { interaction ->\n                        when (interaction) {\n                            is PressInteraction.Press -> {\n                                isLongClick = false\n                                delay(viewConfiguration.longPressTimeoutMillis)\n                                isLongClick = true\n                                onLongClick()\n                                focus.clearFocus()\n                                haptics.longPress()\n                            }\n\n                            is PressInteraction.Release -> {\n                                if (!isLongClick) {\n                                    onClick()\n                                    focus.clearFocus()\n                                    haptics.press()\n                                }\n                            }\n\n                            is PressInteraction.Cancel -> {\n                                isLongClick = false\n                            }\n                        }\n                    }\n                }\n            }\n\n            val animatedShape = shapeByInteraction(\n                shape = shape,\n                pressedShape = pressedShape,\n                interactionSource = interactionSource\n            )\n\n            OutlinedButton(\n                onClick = {\n                    if (onLongClick == null) {\n                        onClick()\n                        focus.clearFocus()\n                        haptics.longPress()\n                    }\n                },\n                modifier = modifier\n                    .materialShadow(\n                        shape = animatedShape,\n                        elevation = animateDpAsState(\n                            if (settingsState.borderWidth > 0.dp || !enabled) 0.dp else 0.5.dp\n                        ).value,\n                        enabled = LocalSettingsState.current.drawButtonShadows,\n                        isClipped = isShadowClip\n                    ),\n                shape = animatedShape,\n                colors = ButtonDefaults.buttonColors(\n                    contentColor = animateColorAsState(\n                        if (enabled) contentColor\n                        else MaterialTheme.colorScheme.onSurface.copy(DisabledAlpha)\n                    ).value,\n                    containerColor = animateColorAsState(\n                        if (enabled) containerColor\n                        else MaterialTheme.colorScheme.onSurface.copy(0.12f)\n                    ).value\n                ),\n                enabled = true,\n                border = BorderStroke(\n                    width = settingsState.borderWidth,\n                    color = borderColor\n                ),\n                contentPadding = contentPadding,\n                interactionSource = interactionSource,\n                content = content\n            )\n\n            if (!enabled) {\n                Surface(color = Color.Transparent, modifier = Modifier.matchParentSize()) {}\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun contentColor(\n    backgroundColor: Color\n) = MaterialTheme.colorScheme.contentColorFor(backgroundColor).takeOrElse {\n    if (backgroundColor == MaterialTheme.colorScheme.mixedContainer) MaterialTheme.colorScheme.onMixedContainer\n    else LocalContentColor.current\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedButtonGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.ButtonGroupDefaults\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.MotionScheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.ToggleButtonDefaults\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.DisabledAlpha\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\nfun EnhancedButtonGroup(\n    modifier: Modifier = defaultModifier,\n    enabled: Boolean = true,\n    items: List<String>,\n    selectedIndex: Int,\n    title: String? = null,\n    onIndexChange: (Int) -> Unit,\n    inactiveButtonColor: Color = MaterialTheme.colorScheme.surface\n) {\n    EnhancedButtonGroup(\n        enabled = enabled,\n        items = items,\n        selectedIndex = selectedIndex,\n        onIndexChange = onIndexChange,\n        modifier = modifier,\n        title = {\n            title?.let {\n                Text(\n                    text = it,\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium,\n                    modifier = Modifier.padding(vertical = 8.dp)\n                )\n            }\n        },\n        inactiveButtonColor = inactiveButtonColor\n    )\n}\n\n@Composable\nfun EnhancedButtonGroup(\n    modifier: Modifier = defaultModifier,\n    enabled: Boolean,\n    items: List<String>,\n    selectedIndex: Int,\n    title: @Composable RowScope.() -> Unit = {},\n    onIndexChange: (Int) -> Unit,\n    inactiveButtonColor: Color = MaterialTheme.colorScheme.surface\n) {\n    EnhancedButtonGroup(\n        modifier = modifier,\n        enabled = enabled,\n        itemCount = items.size,\n        selectedIndex = selectedIndex,\n        itemContent = {\n            AutoSizeText(\n                text = items[it],\n                style = LocalTextStyle.current.copy(\n                    fontSize = 13.sp\n                ),\n                maxLines = 1\n            )\n        },\n        onIndexChange = onIndexChange,\n        title = title,\n        inactiveButtonColor = inactiveButtonColor\n    )\n}\n\n@Composable\nfun <T : Any> EnhancedButtonGroup(\n    modifier: Modifier = defaultModifier,\n    enabled: Boolean = true,\n    entries: List<T>,\n    value: T,\n    itemContent: @Composable (item: T) -> Unit,\n    title: String?,\n    onValueChange: (T) -> Unit,\n    inactiveButtonColor: Color = MaterialTheme.colorScheme.surface,\n    activeButtonColor: Color = MaterialTheme.colorScheme.secondary,\n    isScrollable: Boolean = true,\n    contentPadding: PaddingValues = DefaultContentPadding,\n    useClassFinding: Boolean = false\n) {\n    EnhancedButtonGroup(\n        modifier = modifier,\n        enabled = enabled,\n        itemCount = entries.size,\n        selectedIndex = if (useClassFinding) {\n            entries.indexOfFirst { it::class.isInstance(value) }\n        } else {\n            entries.indexOf(value)\n        },\n        itemContent = {\n            itemContent(entries[it])\n        },\n        onIndexChange = {\n            onValueChange(\n                if (useClassFinding && value::class.isInstance(entries[it])) {\n                    value\n                } else {\n                    entries[it]\n                }\n            )\n        },\n        title = {\n            title?.let {\n                Text(\n                    text = title,\n                    style = PreferenceItemDefaults.TitleFontStyleCentered,\n                    modifier = Modifier\n                        .weight(1f)\n                        .padding(8.dp)\n                )\n            }\n        },\n        inactiveButtonColor = inactiveButtonColor,\n        activeButtonColor = activeButtonColor,\n        isScrollable = isScrollable,\n        contentPadding = contentPadding\n    )\n}\n\n@Composable\nfun EnhancedButtonGroup(\n    modifier: Modifier = defaultModifier,\n    enabled: Boolean = true,\n    itemCount: Int,\n    selectedIndex: Int,\n    itemContent: @Composable (item: Int) -> Unit,\n    title: @Composable RowScope.() -> Unit = {},\n    onIndexChange: (Int) -> Unit,\n    inactiveButtonColor: Color = MaterialTheme.colorScheme.surface,\n    activeButtonColor: Color = MaterialTheme.colorScheme.secondary,\n    isScrollable: Boolean = true,\n    contentPadding: PaddingValues = DefaultContentPadding\n) {\n    EnhancedButtonGroup(\n        modifier = modifier,\n        enabled = enabled,\n        itemCount = itemCount,\n        selectedIndices = setOf(selectedIndex),\n        itemContent = itemContent,\n        title = title,\n        onIndexChange = onIndexChange,\n        inactiveButtonColor = inactiveButtonColor,\n        activeButtonColor = activeButtonColor,\n        isScrollable = isScrollable,\n        contentPadding = contentPadding\n    )\n}\n\n@Composable\nfun <T> EnhancedButtonGroup(\n    modifier: Modifier = defaultModifier,\n    enabled: Boolean = true,\n    entries: List<T>,\n    values: List<T>,\n    itemContent: @Composable (item: T) -> Unit,\n    title: String?,\n    onValueChange: (T) -> Unit,\n    inactiveButtonColor: Color = MaterialTheme.colorScheme.surface,\n    activeButtonColor: Color = MaterialTheme.colorScheme.secondary,\n    isScrollable: Boolean = true,\n    contentPadding: PaddingValues = DefaultContentPadding\n) {\n    val selectedIndices by remember(values, entries) {\n        derivedStateOf {\n            values.mapTo(mutableSetOf()) { entries.indexOf(it) }\n        }\n    }\n\n    EnhancedButtonGroup(\n        modifier = modifier,\n        enabled = enabled,\n        itemCount = entries.size,\n        selectedIndices = selectedIndices,\n        itemContent = {\n            itemContent(entries[it])\n        },\n        onIndexChange = {\n            onValueChange(\n                entries[it]\n            )\n        },\n        title = {\n            title?.let {\n                Text(\n                    text = title,\n                    style = PreferenceItemDefaults.TitleFontStyleCentered,\n                    modifier = Modifier\n                        .weight(1f)\n                        .padding(8.dp)\n                )\n            }\n        },\n        inactiveButtonColor = inactiveButtonColor,\n        activeButtonColor = activeButtonColor,\n        isScrollable = isScrollable,\n        contentPadding = contentPadding\n    )\n}\n\n@Composable\nfun EnhancedButtonGroup(\n    modifier: Modifier = defaultModifier,\n    enabled: Boolean = true,\n    itemCount: Int,\n    selectedIndices: Set<Int>,\n    itemContent: @Composable (item: Int) -> Unit,\n    title: @Composable RowScope.() -> Unit = {},\n    onIndexChange: (Int) -> Unit,\n    inactiveButtonColor: Color = MaterialTheme.colorScheme.surface,\n    activeButtonColor: Color = MaterialTheme.colorScheme.secondary,\n    isScrollable: Boolean = true,\n    contentPadding: PaddingValues = DefaultContentPadding\n) {\n    val settingsState = LocalSettingsState.current\n\n    val disabledColor = MaterialTheme.colorScheme.onSurface\n        .copy(alpha = DisabledAlpha)\n        .compositeOver(MaterialTheme.colorScheme.surface)\n\n    ProvideTextStyle(\n        value = LocalTextStyle.current.copy(\n            color = if (!enabled) disabledColor\n            else Color.Unspecified\n        )\n    ) {\n        Column(\n            modifier = modifier,\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center,\n                content = title\n            )\n            val scrollState = rememberScrollState()\n            val elevation by animateDpAsState(\n                if (settingsState.borderWidth > 0.dp || !enabled) 0.dp else 0.5.dp\n            )\n\n            LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n                MaterialTheme(\n                    motionScheme = object : MotionScheme by MotionScheme.expressive() {\n                        override fun <T> fastSpatialSpec(): FiniteAnimationSpec<T> = tween(400)\n                    }\n                ) {\n                    Row(\n                        modifier = Modifier\n                            .height(IntrinsicSize.Max)\n                            .then(\n                                if (isScrollable) {\n                                    Modifier\n                                        .fadingEdges(scrollState)\n                                        .enhancedHorizontalScroll(scrollState)\n                                } else Modifier.fillMaxWidth()\n                            )\n                            .padding(contentPadding),\n                        horizontalArrangement = Arrangement.spacedBy(ButtonGroupDefaults.ConnectedSpaceBetween),\n                    ) {\n                        repeat(itemCount) { index ->\n                            val activeContainerColor = if (enabled) {\n                                activeButtonColor\n                            } else {\n                                MaterialTheme.colorScheme.surfaceContainer\n                            }\n\n                            val selected = index in selectedIndices\n\n                            val disableSmoothness =\n                                !selected && index == 0 || index == itemCount - 1\n\n                            val settingsState = LocalSettingsState.current\n\n                            LocalSettingsState.ProvidesValue(\n                                if (disableSmoothness && settingsState.shapesType is ShapeType.Smooth) {\n                                    settingsState.copy(\n                                        shapesType = ShapeType.Rounded()\n                                    )\n                                } else {\n                                    settingsState\n                                }\n                            ) {\n                                EnhancedToggleButton(\n                                    enabled = enabled,\n                                    onCheckedChange = {\n                                        onIndexChange(index)\n                                    },\n                                    border = BorderStroke(\n                                        width = settingsState.borderWidth,\n                                        color = MaterialTheme.colorScheme.outlineVariant(\n                                            onTopOf = if (selected) activeContainerColor\n                                            else inactiveButtonColor\n                                        )\n                                    ),\n                                    colors = ToggleButtonDefaults.toggleButtonColors(\n                                        containerColor = inactiveButtonColor,\n                                        contentColor = contentColorFor(inactiveButtonColor),\n                                        checkedContainerColor = activeContainerColor,\n                                        checkedContentColor = contentColorFor(activeContainerColor)\n                                    ),\n                                    checked = selected,\n                                    shapes = when (index) {\n                                        0 -> ButtonGroupDefaults.connectedLeadingButtonShapes(\n                                            shape = AutoCornersShape(\n                                                topStart = CornerFull,\n                                                bottomStart = CornerFull,\n                                                topEnd = CornerValueSmall,\n                                                bottomEnd = CornerValueSmall,\n                                            ),\n                                            pressedShape = ButtonDefaults.pressedShape,\n                                            checkedShape = AutoCircleShape()\n                                        )\n\n                                        itemCount - 1 -> ButtonGroupDefaults.connectedTrailingButtonShapes(\n                                            shape = AutoCornersShape(\n                                                topEnd = CornerFull,\n                                                bottomEnd = CornerFull,\n                                                topStart = CornerValueSmall,\n                                                bottomStart = CornerValueSmall,\n                                            ),\n                                            pressedShape = ButtonDefaults.pressedShape,\n                                            checkedShape = AutoCircleShape()\n                                        )\n\n                                        else -> ButtonGroupDefaults.connectedMiddleButtonShapes(\n                                            shape = ShapeDefaults.mini,\n                                            pressedShape = ButtonDefaults.pressedShape,\n                                            checkedShape = AutoCircleShape()\n                                        )\n                                    },\n                                    elevation = elevation,\n                                    modifier = Modifier.then(\n                                        if (isScrollable) Modifier\n                                        else Modifier.weight(1f)\n                                    )\n                                ) {\n                                    if (!isScrollable) {\n                                        Row(\n                                            modifier = Modifier.marquee()\n                                        ) {\n                                            itemContent(index)\n                                        }\n                                    } else {\n                                        itemContent(index)\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nprivate val defaultModifier = Modifier\n    .fillMaxWidth()\n    .padding(8.dp)\n\nprivate val DefaultContentPadding = PaddingValues(\n    start = 6.dp,\n    end = 6.dp,\n    bottom = 6.dp,\n    top = 8.dp\n)\n\nprivate val CornerFull: CornerSize = CornerSize(50)\nprivate val CornerValueSmall = CornerSize(8.0.dp)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedCheckbox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.material3.Checkbox\nimport androidx.compose.material3.CheckboxColors\nimport androidx.compose.material3.CheckboxDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport kotlin.math.floor\n\n@Composable\nfun EnhancedCheckbox(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: CheckboxColors = CheckboxDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null\n) {\n    val haptics = LocalHapticFeedback.current\n    val strokeWidthPx = with(LocalDensity.current) { floor(CheckboxDefaults.StrokeWidth.toPx()) }\n\n    val stroke = remember(strokeWidthPx) {\n        Stroke(\n            width = strokeWidthPx,\n            join = StrokeJoin.Round,\n            cap = StrokeCap.Round\n        )\n    }\n\n    Checkbox(\n        checked = checked,\n        onCheckedChange = if (onCheckedChange != null) {\n            {\n                haptics.longPress()\n                onCheckedChange(it)\n            }\n        } else null,\n        outlineStroke = stroke,\n        checkmarkStroke = stroke,\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        interactionSource = interactionSource\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedChip.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\n\n@Composable\nfun EnhancedChip(\n    selected: Boolean,\n    onClick: (() -> Unit)?,\n    modifier: Modifier = Modifier,\n    contentPadding: PaddingValues = PaddingValues(6.dp),\n    selectedColor: Color,\n    selectedContentColor: Color = MaterialTheme.colorScheme.contentColorFor(selectedColor),\n    unselectedColor: Color = MaterialTheme.colorScheme.surfaceContainerHigh,\n    unselectedContentColor: Color = MaterialTheme.colorScheme.onSurface,\n    shape: Shape = ShapeDefaults.small,\n    pressedShape: Shape = ShapeDefaults.extraSmall,\n    interactionSource: MutableInteractionSource? = null,\n    defaultMinSize: Dp = 36.dp,\n    label: @Composable () -> Unit\n) {\n    val color by animateColorAsState(\n        if (selected) selectedColor\n        else unselectedColor\n    )\n    val contentColor by animateColorAsState(\n        if (selected) selectedContentColor\n        else unselectedContentColor\n    )\n\n    val realInteractionSource = interactionSource ?: remember { MutableInteractionSource() }\n    val resultShape = shapeByInteraction(\n        shape = shape,\n        pressedShape = pressedShape,\n        interactionSource = realInteractionSource\n    )\n\n    CompositionLocalProvider(\n        LocalTextStyle provides MaterialTheme.typography.labelLarge.copy(\n            fontWeight = FontWeight.SemiBold,\n            color = contentColor\n        ),\n        LocalContentColor provides contentColor,\n        LocalContainerShape provides null\n    ) {\n        Box(\n            modifier = modifier\n                .defaultMinSize(defaultMinSize, defaultMinSize)\n                .container(\n                    color = color,\n                    resultPadding = 0.dp,\n                    borderColor = if (!selected) MaterialTheme.colorScheme.outlineVariant()\n                    else selectedColor\n                        .copy(alpha = 0.9f)\n                        .compositeOver(Color.Black),\n                    shape = resultShape,\n                    autoShadowElevation = 0.5.dp\n                )\n                .then(\n                    onClick?.let {\n                        Modifier.hapticsClickable(\n                            indication = LocalIndication.current,\n                            interactionSource = realInteractionSource,\n                            onClick = onClick\n                        )\n                    } ?: Modifier\n                ),\n            contentAlignment = Alignment.Center\n        ) {\n            Box(\n                modifier = Modifier.padding(contentPadding),\n                contentAlignment = Alignment.Center\n            ) {\n                label()\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedCircularProgressIndicator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.CircularWavyProgressIndicator\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProgressIndicatorDefaults\nimport androidx.compose.material3.WavyProgressIndicatorDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.icons.CancelSmall\n\n@Composable\nfun EnhancedCircularProgressIndicator(\n    modifier: Modifier = Modifier,\n    color: Color = ProgressIndicatorDefaults.circularColor,\n    strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,\n    trackColor: Color = ProgressIndicatorDefaults.circularIndeterminateTrackColor,\n    strokeCap: StrokeCap = StrokeCap.Round,\n    gapSize: Dp = ProgressIndicatorDefaults.CircularIndicatorTrackGapSize,\n    type: EnhancedCircularProgressIndicatorType = EnhancedCircularProgressIndicatorType.Wavy()\n) {\n    when (type) {\n        EnhancedCircularProgressIndicatorType.Normal -> {\n            CircularProgressIndicator(\n                modifier = modifier.background(Color.Red),\n                color = color,\n                strokeWidth = strokeWidth,\n                trackColor = trackColor,\n                strokeCap = strokeCap,\n                gapSize = gapSize\n            )\n        }\n\n        is EnhancedCircularProgressIndicatorType.Wavy -> {\n            CircularWavyProgressIndicator(\n                modifier = modifier,\n                color = color,\n                trackColor = trackColor,\n                gapSize = gapSize,\n                trackStroke = Stroke(\n                    width = with(LocalDensity.current) { strokeWidth.toPx() },\n                    cap = strokeCap\n                ),\n                stroke = Stroke(\n                    width = with(LocalDensity.current) { strokeWidth.toPx() },\n                    cap = strokeCap\n                ),\n                amplitude = type.amplitude(0.5f),\n                wavelength = type.wavelength,\n                waveSpeed = type.waveSpeed\n            )\n        }\n    }\n}\n\n@Composable\nfun EnhancedCircularProgressIndicator(\n    progress: () -> Float,\n    modifier: Modifier = Modifier,\n    color: Color = ProgressIndicatorDefaults.circularColor,\n    strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,\n    trackColor: Color = ProgressIndicatorDefaults.circularIndeterminateTrackColor,\n    strokeCap: StrokeCap = StrokeCap.Round,\n    gapSize: Dp = ProgressIndicatorDefaults.CircularIndicatorTrackGapSize,\n    type: EnhancedCircularProgressIndicatorType = EnhancedCircularProgressIndicatorType.Wavy()\n) {\n    when (type) {\n        EnhancedCircularProgressIndicatorType.Normal -> {\n            CircularProgressIndicator(\n                progress = progress,\n                modifier = modifier,\n                color = color,\n                strokeWidth = strokeWidth,\n                trackColor = trackColor,\n                strokeCap = strokeCap,\n                gapSize = gapSize\n            )\n        }\n\n        is EnhancedCircularProgressIndicatorType.Wavy -> {\n            CircularWavyProgressIndicator(\n                progress = progress,\n                modifier = modifier,\n                color = color,\n                trackColor = trackColor,\n                gapSize = gapSize,\n                trackStroke = Stroke(\n                    width = with(LocalDensity.current) { strokeWidth.toPx() },\n                    cap = strokeCap\n                ),\n                stroke = Stroke(\n                    width = with(LocalDensity.current) { strokeWidth.toPx() },\n                    cap = strokeCap\n                ),\n                amplitude = type.amplitude,\n                wavelength = type.wavelength,\n                waveSpeed = type.waveSpeed\n            )\n        }\n    }\n}\n\n@Composable\nfun EnhancedAutoCircularProgressIndicator(\n    progress: () -> Float,\n    modifier: Modifier = Modifier,\n    color: Color = ProgressIndicatorDefaults.circularColor,\n    strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,\n    trackColor: Color = ProgressIndicatorDefaults.circularIndeterminateTrackColor,\n    strokeCap: StrokeCap = StrokeCap.Round,\n    gapSize: Dp = ProgressIndicatorDefaults.CircularIndicatorTrackGapSize,\n    type: EnhancedCircularProgressIndicatorType = EnhancedCircularProgressIndicatorType.Wavy()\n) {\n    if (progress() > 0f) {\n        EnhancedCircularProgressIndicator(\n            progress = progress,\n            modifier = modifier,\n            color = color,\n            strokeWidth = strokeWidth,\n            trackColor = trackColor,\n            strokeCap = strokeCap,\n            gapSize = gapSize,\n            type = type\n        )\n    } else {\n        EnhancedCircularProgressIndicator(\n            modifier = modifier,\n            color = color,\n            strokeWidth = strokeWidth,\n            trackColor = trackColor,\n            strokeCap = strokeCap,\n            gapSize = gapSize,\n            type = type\n        )\n    }\n}\n\n@Composable\nfun EnhancedCancellableCircularProgressIndicator(\n    progress: () -> Float,\n    modifier: Modifier = Modifier,\n    color: Color = ProgressIndicatorDefaults.circularColor,\n    strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,\n    trackColor: Color = ProgressIndicatorDefaults.circularIndeterminateTrackColor,\n    strokeCap: StrokeCap = StrokeCap.Round,\n    cancelIconColor: Color = MaterialTheme.colorScheme.secondary.copy(0.7f),\n    onCancel: () -> Unit,\n    gapSize: Dp = ProgressIndicatorDefaults.CircularIndicatorTrackGapSize,\n    type: EnhancedCircularProgressIndicatorType = EnhancedCircularProgressIndicatorType.Wavy()\n) {\n    Box(\n        modifier = modifier\n            .pointerInput(onCancel) {\n                detectTapGestures {\n                    onCancel()\n                }\n            },\n        contentAlignment = Alignment.Center\n    ) {\n        Icon(\n            imageVector = Icons.Outlined.CancelSmall,\n            contentDescription = null,\n            tint = cancelIconColor,\n            modifier = Modifier.size(18.dp)\n        )\n        EnhancedAutoCircularProgressIndicator(\n            progress = progress,\n            modifier = Modifier.matchParentSize(),\n            color = color,\n            strokeWidth = strokeWidth,\n            trackColor = trackColor,\n            strokeCap = strokeCap,\n            gapSize = gapSize,\n            type = type\n        )\n    }\n}\n\nsealed class EnhancedCircularProgressIndicatorType {\n    data object Normal : EnhancedCircularProgressIndicatorType()\n\n    data class Wavy(\n        val amplitude: (progress: Float) -> Float = { progress ->\n            if (progress <= 0.1f || progress >= 0.95f) {\n                0f\n            } else {\n                1f\n            }\n        },\n        val wavelength: Dp = WavyProgressIndicatorDefaults.CircularWavelength,\n        val waveSpeed: Dp = wavelength,\n    ) : EnhancedCircularProgressIndicatorType()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedDatePickerDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.requiredWidth\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Keyboard\nimport androidx.compose.material.icons.outlined.Schedule\nimport androidx.compose.material3.AlertDialogDefaults\nimport androidx.compose.material3.DatePicker\nimport androidx.compose.material3.DatePickerColors\nimport androidx.compose.material3.DatePickerDefaults\nimport androidx.compose.material3.DatePickerFormatter\nimport androidx.compose.material3.DatePickerState\nimport androidx.compose.material3.DateRangePicker\nimport androidx.compose.material3.DateRangePickerDefaults\nimport androidx.compose.material3.DateRangePickerState\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TimeInput\nimport androidx.compose.material3.TimePicker\nimport androidx.compose.material3.TimePickerColors\nimport androidx.compose.material3.TimePickerDefaults\nimport androidx.compose.material3.TimePickerDialogDefaults\nimport androidx.compose.material3.TimePickerDisplayMode\nimport androidx.compose.material3.TimePickerLayoutType\nimport androidx.compose.material3.TimePickerState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.focus.FocusRequester\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.MeasurePolicy\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFirst\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.alertDialogBorder\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport kotlin.math.truncate\n\n@Composable\nfun EnhancedDatePickerDialog(\n    visible: Boolean,\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    placeAboveAll: Boolean = false,\n    state: DatePickerState,\n    onDatePicked: (Long) -> Unit,\n    colors: DatePickerColors = DatePickerDefaults.colors(\n        containerColor = AlertDialogDefaults.containerColor\n    ),\n    dateFormatter: DatePickerFormatter = remember { DatePickerDefaults.dateFormatter() },\n    title: (@Composable () -> Unit)? = {\n        DatePickerDefaults.DatePickerTitle(\n            displayMode = state.displayMode,\n            modifier = Modifier.padding(DatePickerTitlePadding),\n            contentColor = colors.titleContentColor,\n        )\n    },\n    headline: (@Composable () -> Unit)? = {\n        DatePickerDefaults.DatePickerHeadline(\n            selectedDateMillis = state.selectedDateMillis,\n            displayMode = state.displayMode,\n            dateFormatter = dateFormatter,\n            modifier = Modifier.padding(DatePickerHeadlinePadding),\n            contentColor = colors.headlineContentColor,\n        )\n    },\n    showModeToggle: Boolean = true,\n    focusRequester: FocusRequester? = remember { FocusRequester() },\n    shape: Shape = AlertDialogDefaults.shape,\n    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,\n) {\n    EnhancedDatePickerDialogContainer(\n        visible = visible,\n        onDismissRequest = onDismissRequest,\n        modifier = modifier,\n        placeAboveAll = placeAboveAll,\n        shape = shape,\n        tonalElevation = tonalElevation,\n        containerColor = colors.containerColor,\n        onConfirmClick = {\n            state.selectedDateMillis?.let {\n                onDatePicked(it)\n                onDismissRequest()\n            }\n        },\n        isConfirmEnabled = state.selectedDateMillis != null\n    ) {\n        val scrollState = rememberScrollState()\n\n        DatePicker(\n            modifier = Modifier\n                .fadingEdges(\n                    scrollableState = scrollState,\n                    isVertical = true\n                )\n                .enhancedVerticalScroll(scrollState),\n            state = state,\n            dateFormatter = dateFormatter,\n            colors = colors,\n            title = title,\n            headline = headline,\n            showModeToggle = showModeToggle,\n            focusRequester = focusRequester\n        )\n    }\n}\n\n@Composable\nfun EnhancedDateRangePickerDialog(\n    visible: Boolean,\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    placeAboveAll: Boolean = false,\n    state: DateRangePickerState,\n    onDatePicked: (start: Long, end: Long) -> Unit,\n    colors: DatePickerColors = DatePickerDefaults.colors(\n        containerColor = AlertDialogDefaults.containerColor\n    ),\n    dateFormatter: DatePickerFormatter = remember {\n        DatePickerDefaults.dateFormatter(selectedDateSkeleton = \"dd.MM.yy\")\n    },\n    title: (@Composable () -> Unit)? = {\n        DateRangePickerDefaults.DateRangePickerTitle(\n            displayMode = state.displayMode,\n            modifier = Modifier.padding(DatePickerTitlePadding),\n            contentColor = colors.titleContentColor,\n        )\n    },\n    headline: (@Composable () -> Unit)? = {\n        DateRangePickerDefaults.DateRangePickerHeadline(\n            selectedStartDateMillis = state.selectedStartDateMillis,\n            selectedEndDateMillis = state.selectedEndDateMillis,\n            displayMode = state.displayMode,\n            dateFormatter = dateFormatter,\n            modifier = Modifier.padding(DatePickerHeadlinePadding),\n            contentColor = colors.headlineContentColor,\n        )\n    },\n    showModeToggle: Boolean = true,\n    focusRequester: FocusRequester? = remember { FocusRequester() },\n    shape: Shape = AlertDialogDefaults.shape,\n    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,\n) {\n    EnhancedDatePickerDialogContainer(\n        visible = visible,\n        onDismissRequest = onDismissRequest,\n        modifier = modifier,\n        placeAboveAll = placeAboveAll,\n        shape = shape,\n        tonalElevation = tonalElevation,\n        containerColor = colors.containerColor,\n        onConfirmClick = {\n            val start = state.selectedStartDateMillis\n            val end = state.selectedEndDateMillis\n\n            if (start != null && end != null) {\n                onDatePicked(start, end)\n                onDismissRequest()\n            }\n        },\n        isConfirmEnabled = state.selectedStartDateMillis != null && state.selectedEndDateMillis != null\n    ) {\n        DateRangePicker(\n            modifier = Modifier\n                .fadingEdges(\n                    scrollableState = null,\n                    isVertical = true,\n                    length = 8.dp\n                ),\n            state = state,\n            dateFormatter = dateFormatter,\n            colors = colors,\n            title = title,\n            headline = headline,\n            showModeToggle = showModeToggle,\n            focusRequester = focusRequester\n        )\n    }\n}\n\n@Composable\nfun EnhancedTimePickerDialog(\n    visible: Boolean,\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    placeAboveAll: Boolean = false,\n    state: TimePickerState,\n    onTimePicked: (hour: Int, minute: Int) -> Unit,\n    colors: TimePickerColors = TimePickerDefaults.colors(\n        containerColor = AlertDialogDefaults.containerColor\n    ),\n    layoutType: TimePickerLayoutType = TimePickerDefaults.layoutType(),\n    shape: Shape = AlertDialogDefaults.shape,\n    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,\n) {\n    var displayMode by remember {\n        mutableStateOf(TimePickerDisplayMode.Picker)\n    }\n\n    EnhancedDatePickerDialogContainer(\n        visible = visible,\n        onDismissRequest = onDismissRequest,\n        modifier = modifier,\n        placeAboveAll = placeAboveAll,\n        shape = shape,\n        tonalElevation = tonalElevation,\n        containerColor = colors.containerColor,\n        onConfirmClick = {},\n        showButtons = false,\n        isConfirmEnabled = false\n    ) {\n        TimePickerCustomLayout(\n            title = { TimePickerDialogDefaults.Title(displayMode) },\n            actions = {\n                Row(\n                    modifier = Modifier.fillMaxWidth(),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    EnhancedIconButton(\n                        modifier = modifier,\n                        onClick = {\n                            displayMode = if (displayMode == TimePickerDisplayMode.Picker) {\n                                TimePickerDisplayMode.Input\n                            } else {\n                                TimePickerDisplayMode.Picker\n                            }\n                        }\n                    ) {\n                        val icon = if (displayMode == TimePickerDisplayMode.Picker) {\n                            Icons.Outlined.Keyboard\n                        } else {\n                            Icons.Outlined.Schedule\n                        }\n\n                        Icon(\n                            imageVector = icon,\n                            contentDescription = icon.name\n                        )\n                    }\n\n                    Spacer(modifier = Modifier.weight(1f))\n\n                    EnhancedButton(\n                        onClick = {\n                            onTimePicked(state.hour, state.minute)\n                            onDismissRequest()\n                        }\n                    ) {\n                        Text(stringResource(R.string.ok))\n                    }\n                }\n            },\n            content = {\n                AnimatedContent(displayMode) { mode ->\n                    if (mode == TimePickerDisplayMode.Picker) {\n                        TimePicker(\n                            state = state,\n                            colors = colors,\n                            layoutType = layoutType\n                        )\n                    } else {\n                        TimeInput(\n                            state = state,\n                            colors = colors\n                        )\n                    }\n                }\n            }\n        )\n    }\n}\n\n@Composable\nprivate fun EnhancedDatePickerDialogContainer(\n    visible: Boolean,\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    placeAboveAll: Boolean = false,\n    shape: Shape,\n    tonalElevation: Dp,\n    containerColor: Color,\n    onConfirmClick: () -> Unit,\n    isConfirmEnabled: Boolean,\n    showButtons: Boolean = true,\n    content: @Composable ColumnScope.() -> Unit\n) {\n    BasicEnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismissRequest,\n        modifier = modifier,\n        placeAboveAll = placeAboveAll,\n    ) {\n        Surface(\n            modifier = Modifier\n                .alertDialogBorder()\n                .then(\n                    if (showButtons) Modifier.requiredWidth(ContainerWidth)\n                    else Modifier\n                )\n                .heightIn(max = ContainerHeight),\n            shape = shape,\n            color = containerColor,\n            tonalElevation = tonalElevation,\n        ) {\n            Column(verticalArrangement = Arrangement.SpaceBetween) {\n                DatePickerContainer(content = content)\n\n                if (showButtons) {\n                    val isCenterAlignButtons = LocalSettingsState.current.isCenterAlignDialogButtons\n\n                    Row(\n                        modifier = Modifier\n                            .align(Alignment.End)\n                            .padding(DialogButtonsPadding)\n                    ) {\n                        FlowRow(\n                            modifier = Modifier.weight(1f),\n                            horizontalArrangement = Arrangement.spacedBy(\n                                space = ButtonsHorizontalSpacing,\n                                alignment = if (isCenterAlignButtons) {\n                                    Alignment.CenterHorizontally\n                                } else Alignment.End\n                            ),\n                            verticalArrangement = Arrangement.spacedBy(\n                                space = ButtonsVerticalSpacing,\n                                alignment = if (isCenterAlignButtons) {\n                                    Alignment.CenterVertically\n                                } else Alignment.Bottom\n                            ),\n                            itemVerticalAlignment = Alignment.CenterVertically\n                        ) {\n                            EnhancedButton(\n                                onClick = onDismissRequest,\n                                containerColor = MaterialTheme.colorScheme.secondaryContainer\n                            ) {\n                                Text(stringResource(R.string.close))\n                            }\n                            EnhancedButton(\n                                onClick = onConfirmClick,\n                                enabled = isConfirmEnabled\n                            ) {\n                                Text(stringResource(R.string.ok))\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun TimePickerCustomLayout(\n    title: @Composable () -> Unit,\n    actions: @Composable () -> Unit,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    val content =\n        @Composable {\n            Box(modifier = Modifier.layoutId(\"title\")) { title() }\n            Box(modifier = Modifier.layoutId(\"actions\")) { actions() }\n            Column(modifier = Modifier.layoutId(\"timePickerContent\"), content = content)\n        }\n\n    val measurePolicy = MeasurePolicy { measurables, constraints ->\n        val titleMeasurable = measurables.fastFirst { it.layoutId == \"title\" }\n        val contentMeasurable = measurables.fastFirst { it.layoutId == \"timePickerContent\" }\n        val actionsMeasurable = measurables.fastFirst { it.layoutId == \"actions\" }\n\n        val contentPadding = 24.dp.roundToPx()\n        val landMaxDialogHeight = 384.dp.roundToPx()\n        val landTitleTopPadding = 24.dp.roundToPx()\n        val landContentTopPadding = 16.dp.roundToPx()\n        val landContentActionsPadding = 4.dp.roundToPx()\n        val landActionsBottomPadding = 8.dp.roundToPx()\n\n        val portTitleTopPadding = 24.dp.roundToPx()\n        val portActionsBottomPadding = 24.dp.roundToPx()\n\n        val contentPlaceable = contentMeasurable.measure(constraints.copy(minHeight = 0))\n\n        // Input mode will be smaller than the smallest TimePickerContent (currently 200.dp)\n        // But will always use portrait layout for correctness.\n        val isLandscape =\n            contentPlaceable.width > contentPlaceable.height &&\n                    contentPlaceable.height >= truncate(ClockDialMinContainerSize.toPx())\n\n        val dialogWidth =\n            if (isLandscape) {\n                contentPlaceable.width + contentPadding * 2\n            } else {\n                contentPlaceable.width + contentPadding * 2\n            }\n\n        val actionsPlaceable =\n            actionsMeasurable.measure(\n                constraints.copy(minWidth = 0, minHeight = 0, maxWidth = contentPlaceable.width)\n            )\n\n        val titlePlaceable =\n            titleMeasurable.measure(\n                constraints.copy(minWidth = 0, minHeight = 0, maxWidth = contentPlaceable.width)\n            )\n\n        val layoutHeight =\n            if (isLandscape) {\n                val contentTotalHeight =\n                    contentPlaceable.height +\n                            actionsPlaceable.height +\n                            landActionsBottomPadding +\n                            landContentTopPadding +\n                            landContentActionsPadding\n                if (constraints.hasBoundedHeight) constraints.maxHeight else contentTotalHeight\n            } else {\n                portTitleTopPadding +\n                        titlePlaceable.height +\n                        contentPlaceable.height +\n                        actionsPlaceable.height +\n                        portActionsBottomPadding\n            }\n\n        layout(width = dialogWidth, height = layoutHeight) {\n            if (isLandscape) {\n                val contentHeight =\n                    landContentTopPadding +\n                            contentPlaceable.height +\n                            landContentActionsPadding +\n                            actionsPlaceable.height +\n                            landActionsBottomPadding\n                val remainingSpace = layoutHeight - contentHeight\n                val adjustedActionsBottomPadding =\n                    if (layoutHeight >= landMaxDialogHeight) {\n                        16.dp.roundToPx()\n                    } else {\n                        0\n                    }\n\n                titlePlaceable.place(x = landTitleTopPadding, y = landTitleTopPadding)\n                val timePickerContentX = contentPadding\n                val timePickerContentY = landContentTopPadding + remainingSpace / 2\n                contentPlaceable.place(x = timePickerContentX, y = timePickerContentY)\n                val actionsY =\n                    timePickerContentY + contentPlaceable.height + landContentActionsPadding -\n                            adjustedActionsBottomPadding + remainingSpace / 2\n                actionsPlaceable.place(x = timePickerContentX, y = actionsY)\n            } else {\n                val titleX = landTitleTopPadding\n                titlePlaceable.place(x = titleX, y = portTitleTopPadding)\n\n                val contentX = (dialogWidth - contentPlaceable.width) / 2\n                val contentY = portTitleTopPadding + titlePlaceable.height\n                contentPlaceable.place(x = contentX, y = contentY)\n\n                val actionsX = (dialogWidth - actionsPlaceable.width) / 2\n                val actionsY = contentY + contentPlaceable.height\n                actionsPlaceable.place(x = actionsX, y = actionsY)\n            }\n        }\n    }\n\n    Layout(content = content, measurePolicy = measurePolicy)\n}\n\n@Composable\nprivate fun ColumnScope.DatePickerContainer(\n    content: @Composable ColumnScope.() -> Unit\n) {\n    // Wrap the content with a Box and Modifier.weight(1f) to ensure that any \"confirm\"\n    // and \"dismiss\" buttons are not pushed out of view when running on small screens,\n    // or when nesting a DateRangePicker.\n    // Fill is false to support collapsing the dialog's height when switching to input\n    // mode.\n    Box(\n        modifier = Modifier.weight(1f, fill = false)\n    ) {\n        this@DatePickerContainer.content()\n    }\n}\n\nprivate val DialogButtonsPadding = PaddingValues(24.dp)\nprivate val ButtonsHorizontalSpacing = 8.dp\nprivate val ButtonsVerticalSpacing = 12.dp\nprivate val DatePickerTitlePadding = PaddingValues(start = 24.dp, end = 12.dp, top = 16.dp)\nprivate val DatePickerHeadlinePadding = PaddingValues(start = 24.dp, end = 12.dp, bottom = 12.dp)\nprivate val ContainerWidth = 360.dp\nprivate val ContainerHeight = 568.dp\n\nprivate val TimePickerMaxHeight = 384.dp\nprivate val TimePickerMidHeight = 330.dp\nprivate val ClockDialMidContainerSize = 238.dp\ninternal val ClockDialMinContainerSize = 200.dp"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedDropdownMenu.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.DropdownMenu\nimport androidx.compose.material3.LocalAbsoluteTonalElevation\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.DpOffset\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.window.PopupProperties\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\n\n@Composable\nfun EnhancedDropdownMenu(\n    expanded: Boolean,\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = MaterialTheme.shapes.medium,\n    containerColor: Color = MaterialTheme.colorScheme.surfaceContainerHighest,\n    offset: DpOffset = DpOffset(0.dp, 0.dp),\n    scrollState: ScrollState = rememberScrollState(),\n    properties: PopupProperties = PopupProperties(focusable = true),\n    enableAutoShadows: Boolean = true,\n    content: @Composable ColumnScope.() -> Unit\n) {\n    val settings = LocalSettingsState.current\n    CompositionLocalProvider(\n        LocalAbsoluteTonalElevation provides (-3).dp\n    ) {\n        DropdownMenu(\n            expanded = expanded,\n            onDismissRequest = onDismissRequest,\n            modifier = modifier,\n            offset = offset,\n            shape = shape,\n            scrollState = scrollState,\n            properties = properties,\n            content = content,\n            containerColor = containerColor,\n            tonalElevation = 0.dp,\n            shadowElevation = if (settings.drawContainerShadows && enableAutoShadows) 1.dp else 0.dp,\n            border = if (settings.borderWidth > 0.dp) {\n                BorderStroke(\n                    width = settings.borderWidth,\n                    color = MaterialTheme.colorScheme.outlineVariant()\n                )\n            } else null\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedFlingBehavior.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.OverscrollEffect\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.gestures.FlingBehavior\nimport androidx.compose.foundation.horizontalScroll\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport io.iamjosephmj.flinger.adaptive.AdaptiveMode\nimport io.iamjosephmj.flinger.behaviours.FlingPresets\n\n@Composable\nfun enhancedFlingBehavior(\n    flingType: FlingType = LocalSettingsState.current.flingType\n): FlingBehavior = when (flingType) {\n    FlingType.DEFAULT -> FlingPresets.androidNative()\n    FlingType.SMOOTH -> FlingPresets.smooth()\n    FlingType.IOS_STYLE -> FlingPresets.iOSStyle()\n    FlingType.SMOOTH_CURVE -> FlingPresets.smoothCurve()\n    FlingType.QUICK_STOP -> FlingPresets.quickStop()\n    FlingType.BOUNCY -> FlingPresets.bouncy()\n    FlingType.FLOATY -> FlingPresets.floaty()\n    FlingType.SNAPPY -> FlingPresets.snappy()\n    FlingType.ULTRA_SMOOTH -> FlingPresets.ultraSmooth()\n    FlingType.ADAPTIVE -> FlingPresets.adaptive(AdaptiveMode.Precision)\n    FlingType.ACCESSIBILITY_AWARE -> FlingPresets.accessibilityAware()\n    FlingType.REDUCED_MOTION -> FlingPresets.reducedMotion()\n}\n\nfun Modifier.enhancedVerticalScroll(\n    state: ScrollState,\n    enabled: Boolean = true,\n    flingBehavior: FlingBehavior? = null,\n    reverseScrolling: Boolean = false,\n) = this.composed {\n    Modifier.verticalScroll(\n        state = state,\n        enabled = enabled,\n        flingBehavior = flingBehavior ?: enhancedFlingBehavior(),\n        reverseScrolling = reverseScrolling,\n    )\n}\n\nfun Modifier.enhancedVerticalScroll(\n    state: ScrollState,\n    overscrollEffect: OverscrollEffect?,\n    enabled: Boolean = true,\n    flingBehavior: FlingBehavior? = null,\n    reverseScrolling: Boolean = false,\n) = this.composed {\n    Modifier.verticalScroll(\n        state = state,\n        enabled = enabled,\n        flingBehavior = flingBehavior ?: enhancedFlingBehavior(),\n        reverseScrolling = reverseScrolling,\n        overscrollEffect = overscrollEffect\n    )\n}\n\nfun Modifier.enhancedHorizontalScroll(\n    state: ScrollState,\n    enabled: Boolean = true,\n    flingBehavior: FlingBehavior? = null,\n    reverseScrolling: Boolean = false,\n) = this.composed {\n    Modifier.horizontalScroll(\n        state = state,\n        enabled = enabled,\n        flingBehavior = flingBehavior ?: enhancedFlingBehavior(),\n        reverseScrolling = reverseScrolling,\n    )\n}\n\nfun Modifier.enhancedHorizontalScroll(\n    state: ScrollState,\n    overscrollEffect: OverscrollEffect?,\n    enabled: Boolean = true,\n    flingBehavior: FlingBehavior? = null,\n    reverseScrolling: Boolean = false,\n) = this.composed {\n    Modifier.horizontalScroll(\n        state = state,\n        enabled = enabled,\n        flingBehavior = flingBehavior ?: enhancedFlingBehavior(),\n        reverseScrolling = reverseScrolling,\n        overscrollEffect = overscrollEffect\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedFloatingActionButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.material3.FloatingActionButton\nimport androidx.compose.material3.FloatingActionButtonDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalViewConfiguration\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.max\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.containerFabBorder\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collectLatest\n\n@Composable\nfun EnhancedFloatingActionButton(\n    onClick: (() -> Unit)?,\n    modifier: Modifier = Modifier,\n    onLongClick: (() -> Unit)? = null,\n    type: EnhancedFloatingActionButtonType = LocalFABType.current,\n    containerColor: Color = MaterialTheme.colorScheme.primaryContainer,\n    contentColor: Color = contentColor(containerColor),\n    autoElevation: Dp = 1.5.dp,\n    interactionSource: MutableInteractionSource? = remember { MutableInteractionSource() },\n    content: @Composable RowScope.() -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val width by animateDpAsState(type.width)\n    val height by animateDpAsState(type.height)\n    val haptics = LocalHapticFeedback.current\n    val focus = LocalFocusManager.current\n\n    val shape = shapeByInteraction(\n        shape = type.shape(),\n        pressedShape = AutoCornersShape(max(width, height) / 8),\n        interactionSource = interactionSource\n    )\n\n    val realInteractionSource = interactionSource ?: remember { MutableInteractionSource() }\n\n    LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n        if (onLongClick != null) {\n            val viewConfiguration = LocalViewConfiguration.current\n\n            LaunchedEffect(realInteractionSource) {\n                var isLongClick = false\n\n                realInteractionSource.interactions.collectLatest { interaction ->\n                    when (interaction) {\n                        is PressInteraction.Press -> {\n                            isLongClick = false\n                            delay(viewConfiguration.longPressTimeoutMillis)\n                            isLongClick = true\n                            onLongClick()\n                            focus.clearFocus()\n                            haptics.longPress()\n                        }\n\n                        is PressInteraction.Release -> {\n                            if (!isLongClick && onClick != null) {\n                                onClick()\n                                focus.clearFocus()\n                                haptics.press()\n                            }\n                        }\n\n                        is PressInteraction.Cancel -> {\n                            isLongClick = false\n                        }\n                    }\n                }\n            }\n        }\n\n        FloatingActionButton(\n            onClick = {\n                if (onLongClick == null && onClick != null) {\n                    onClick()\n                    focus.clearFocus()\n                    haptics.longPress()\n                }\n            },\n            modifier = modifier\n                .sizeIn(minWidth = width, minHeight = height)\n                .containerFabBorder(\n                    shape = shape,\n                    autoElevation = animateDpAsState(\n                        if (settingsState.drawFabShadows) autoElevation\n                        else 0.dp\n                    ).value\n                ),\n            elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation(),\n            contentColor = animateColorAsState(contentColor).value,\n            shape = shape,\n            containerColor = animateColorAsState(containerColor).value,\n            interactionSource = realInteractionSource,\n            content = {\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    content = content\n                )\n            }\n        )\n    }\n}\n\n@Composable\nprivate fun contentColor(\n    backgroundColor: Color\n) = MaterialTheme.colorScheme.contentColorFor(backgroundColor).takeOrElse {\n    if (backgroundColor == MaterialTheme.colorScheme.mixedContainer) MaterialTheme.colorScheme.onMixedContainer\n    else LocalContentColor.current\n}\n\n\nsealed class EnhancedFloatingActionButtonType(\n    val width: Dp,\n    val height: Dp,\n    val shape: @Composable () -> Shape\n) {\n    constructor(\n        size: Dp,\n        shape: @Composable () -> Shape\n    ) : this(\n        width = size,\n        height = size,\n        shape = shape\n    )\n\n    data object Small : EnhancedFloatingActionButtonType(\n        size = 40.dp,\n        shape = { ShapeDefaults.small }\n    )\n\n    data object Primary : EnhancedFloatingActionButtonType(\n        size = 56.dp,\n        shape = { ShapeDefaults.default }\n    )\n\n    data object SecondaryHorizontal : EnhancedFloatingActionButtonType(\n        width = 42.dp,\n        height = 56.dp,\n        shape = { ShapeDefaults.circle }\n    )\n\n    data object SecondaryVertical : EnhancedFloatingActionButtonType(\n        width = 56.dp,\n        height = 42.dp,\n        shape = { ShapeDefaults.circle }\n    )\n\n    data object Large : EnhancedFloatingActionButtonType(\n        size = 96.dp,\n        shape = { ShapeDefaults.extremeLarge }\n    )\n\n    class Custom(\n        size: Dp,\n        shape: Shape\n    ) : EnhancedFloatingActionButtonType(\n        size = size,\n        shape = { shape }\n    )\n}\n\nval LocalFABType = compositionLocalOf<EnhancedFloatingActionButtonType> {\n    EnhancedFloatingActionButtonType.Primary\n}\n\n@Composable\nfun ProvideFABType(\n    type: EnhancedFloatingActionButtonType,\n    content: @Composable () -> Unit\n) {\n    LocalFABType.ProvidesValue(\n        value = type,\n        content = content\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedHapticFeedback.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"DEPRECATION\")\n@file:SuppressLint(\"UnnecessaryComposedModifier\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.os.Build\nimport android.view.HapticFeedbackConstants\nimport android.view.View\nimport android.view.accessibility.AccessibilityManager\nimport androidx.compose.foundation.Indication\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.combinedClickable\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.hapticfeedback.HapticFeedback\nimport androidx.compose.ui.hapticfeedback.HapticFeedbackType\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalView\nimport androidx.compose.ui.semantics.Role\nimport androidx.core.content.getSystemService\nimport com.t8rin.logger.makeLog\n\nprivate fun View.vibrate() =\n    reallyPerformHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)\n\nprivate fun View.vibrateStrong() = reallyPerformHapticFeedback(HapticFeedbackConstants.LONG_PRESS)\n\nprivate fun View.reallyPerformHapticFeedback(feedbackConstant: Int) {\n    runCatching {\n        if (context.isTouchExplorationEnabled()) return\n\n        isHapticFeedbackEnabled = true\n\n        performHapticFeedback(feedbackConstant, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)\n    }.onFailure { it.makeLog(\"reallyPerformHapticFeedback feedbackConstant = $feedbackConstant\") }\n}\n\nprivate fun Context.isTouchExplorationEnabled(): Boolean =\n    getSystemService<AccessibilityManager>()?.isTouchExplorationEnabled == true\n\n@SuppressLint(\"InlinedApi\")\ninternal data class EnhancedHapticFeedback(\n    val hapticsStrength: Int,\n    val view: View\n) : HapticFeedback {\n\n    override fun performHapticFeedback(hapticFeedbackType: HapticFeedbackType) {\n        when (hapticFeedbackType) {\n            HapticFeedbackType.LongPress -> {\n                when (hapticsStrength) {\n                    1 -> view.vibrate()\n                    2 -> view.vibrateStrong()\n                }\n            }\n\n            HapticFeedbackType.TextHandleMove -> {\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {\n                    view.reallyPerformHapticFeedback(HapticFeedbackConstants.TEXT_HANDLE_MOVE)\n                } else view.reallyPerformHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)\n            }\n\n            HapticFeedbackType.Confirm ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.CONFIRM)\n\n            HapticFeedbackType.ContextClick ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)\n\n            HapticFeedbackType.GestureEnd ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.GESTURE_END)\n\n            HapticFeedbackType.GestureThresholdActivate ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.GESTURE_THRESHOLD_ACTIVATE)\n\n            HapticFeedbackType.Reject -> view.reallyPerformHapticFeedback(HapticFeedbackConstants.REJECT)\n            HapticFeedbackType.SegmentFrequentTick ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.SEGMENT_FREQUENT_TICK)\n\n            HapticFeedbackType.SegmentTick ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.SEGMENT_TICK)\n\n            HapticFeedbackType.ToggleOff ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.TOGGLE_OFF)\n\n            HapticFeedbackType.ToggleOn ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.TOGGLE_ON)\n\n            HapticFeedbackType.VirtualKey ->\n                view.reallyPerformHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)\n        }\n    }\n\n}\n\ninternal data object EmptyHaptics : HapticFeedback {\n    override fun performHapticFeedback(hapticFeedbackType: HapticFeedbackType) = Unit\n}\n\nfun HapticFeedback.press() = performHapticFeedback(HapticFeedbackType.TextHandleMove)\nfun HapticFeedback.longPress() = performHapticFeedback(HapticFeedbackType.LongPress)\n\n@Composable\nfun rememberEnhancedHapticFeedback(hapticsStrength: Int): HapticFeedback {\n    val view = LocalView.current\n\n    val haptics by remember(hapticsStrength) {\n        derivedStateOf {\n            if (hapticsStrength == 0) EmptyHaptics\n            else EnhancedHapticFeedback(\n                hapticsStrength = hapticsStrength,\n                view = view\n            )\n        }\n    }\n\n    return haptics\n}\n\nfun Modifier.hapticsClickable(\n    interactionSource: MutableInteractionSource?,\n    indication: Indication?,\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    enableHaptics: Boolean = true,\n    onClick: () -> Unit\n): Modifier = this.composed {\n    val haptics = LocalHapticFeedback.current\n\n    Modifier.clickable(\n        interactionSource = interactionSource,\n        indication = indication,\n        enabled = enabled,\n        onClickLabel = onClickLabel,\n        role = role,\n        onClick = {\n            if (enableHaptics) haptics.longPress()\n\n            onClick()\n        }\n    )\n}\n\nfun Modifier.hapticsClickable(\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onClick: () -> Unit\n): Modifier = this.composed {\n    hapticsClickable(\n        interactionSource = null,\n        indication = LocalIndication.current,\n        enabled = enabled,\n        onClickLabel = onClickLabel,\n        role = role,\n        onClick = onClick\n    )\n}\n\nfun Modifier.hapticsCombinedClickable(\n    interactionSource: MutableInteractionSource?,\n    indication: Indication?,\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onLongClickLabel: String? = null,\n    onLongClick: (() -> Unit)? = null,\n    onDoubleClick: (() -> Unit)? = null,\n    onClick: () -> Unit\n) = this.composed {\n    val haptics = LocalHapticFeedback.current\n\n    Modifier.combinedClickable(\n        interactionSource = interactionSource,\n        indication = indication,\n        enabled = enabled,\n        onClickLabel = onClickLabel,\n        role = role,\n        onLongClickLabel = onLongClickLabel,\n        onLongClick = if (onLongClick != null) {\n            {\n                haptics.longPress()\n                onLongClick()\n            }\n        } else null,\n        onDoubleClick = if (onDoubleClick != null) {\n            {\n                haptics.press()\n                haptics.longPress()\n                onDoubleClick()\n            }\n        } else null,\n        hapticFeedbackEnabled = false,\n        onClick = {\n            haptics.longPress()\n            onClick()\n        }\n    )\n}\n\nfun Modifier.hapticsCombinedClickable(\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onLongClickLabel: String? = null,\n    onLongClick: (() -> Unit)? = null,\n    onDoubleClick: (() -> Unit)? = null,\n    onClick: () -> Unit\n) = this.composed {\n    hapticsCombinedClickable(\n        interactionSource = null,\n        indication = LocalIndication.current,\n        enabled = enabled,\n        onClickLabel = onClickLabel,\n        role = role,\n        onLongClickLabel = onLongClickLabel,\n        onLongClick = onLongClick,\n        onDoubleClick = onDoubleClick,\n        onClick = onClick\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedIconButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.material.minimumInteractiveComponentSize\nimport androidx.compose.material3.IconButtonDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedIconButton\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalViewConfiguration\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.materialShadow\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collectLatest\n\n@Composable\nfun EnhancedIconButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    onLongClick: (() -> Unit)? = null,\n    enabled: Boolean = true,\n    containerColor: Color = Color.Transparent,\n    contentColor: Color = contentColor(containerColor),\n    borderColor: Color = MaterialTheme.colorScheme.outlineVariant(onTopOf = containerColor),\n    shape: Shape = AutoCircleShape(),\n    pressedShape: Shape = IconButtonDefaults.smallPressedShape,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    forceMinimumInteractiveComponentSize: Boolean = true,\n    enableAutoShadowAndBorder: Boolean = containerColor != Color.Transparent,\n    isShadowClip: Boolean = containerColor.alpha != 1f || !enabled,\n    content: @Composable () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val haptics = LocalHapticFeedback.current\n\n    LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n        if (onLongClick != null) {\n            val viewConfiguration = LocalViewConfiguration.current\n\n\n            LaunchedEffect(interactionSource) {\n                var isLongClick = false\n\n                interactionSource.interactions.collectLatest { interaction ->\n                    when (interaction) {\n                        is PressInteraction.Press -> {\n                            isLongClick = false\n                            delay(viewConfiguration.longPressTimeoutMillis)\n                            isLongClick = true\n                            onLongClick()\n                            haptics.longPress()\n                        }\n\n                        is PressInteraction.Release -> {\n                            if (!isLongClick) {\n                                onClick()\n                                haptics.press()\n                            }\n                        }\n\n                        is PressInteraction.Cancel -> {\n                            isLongClick = false\n                        }\n                    }\n                }\n            }\n        }\n        val animatedShape = shapeByInteraction(\n            shape = shape,\n            pressedShape = pressedShape,\n            interactionSource = interactionSource\n        )\n\n        OutlinedIconButton(\n            onClick = {\n                if (onLongClick == null) {\n                    onClick()\n                    haptics.longPress()\n                }\n            },\n            modifier = modifier\n                .then(\n                    if (forceMinimumInteractiveComponentSize) Modifier.minimumInteractiveComponentSize()\n                    else Modifier\n                )\n                .materialShadow(\n                    shape = animatedShape,\n                    isClipped = isShadowClip,\n                    enabled = LocalSettingsState.current.drawButtonShadows,\n                    elevation = if (settingsState.borderWidth > 0.dp || !enableAutoShadowAndBorder) 0.dp else 0.7.dp\n                ),\n            shape = animatedShape,\n            colors = IconButtonDefaults.iconButtonColors(\n                contentColor = contentColor,\n                containerColor = containerColor\n            ),\n            enabled = enabled,\n            border = BorderStroke(\n                width = animateDpAsState(\n                    if (enableAutoShadowAndBorder) settingsState.borderWidth\n                    else 0.dp\n                ).value,\n                color = animateColorAsState(\n                    if (enableAutoShadowAndBorder) borderColor\n                    else Color.Transparent\n                ).value\n            ),\n            interactionSource = interactionSource,\n            content = content\n        )\n    }\n}\n\n@Composable\nprivate fun contentColor(\n    backgroundColor: Color\n) = MaterialTheme.colorScheme.contentColorFor(backgroundColor).takeOrElse {\n    if (backgroundColor == MaterialTheme.colorScheme.mixedContainer) MaterialTheme.colorScheme.onMixedContainer\n    else LocalContentColor.current\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedLoadingIndicator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.infiniteRepeatable\nimport androidx.compose.animation.core.rememberInfiniteTransition\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.BoxWithConstraintsScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.LoadingIndicator\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.keepScreenOn\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.DpOffset\nimport androidx.compose.ui.unit.dp\nimport com.gigamole.composeshadowsplus.rsblur.rsBlurShadow\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.RotationEasing\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun EnhancedLoadingIndicator(modifier: Modifier = Modifier) {\n    EnhancedLoadingIndicatorContainer(\n        modifier = modifier\n            .then(\n                if (modifier == Modifier) {\n                    Modifier.sizeIn(maxWidth = 76.dp, maxHeight = 76.dp)\n                } else Modifier\n            )\n            .aspectRatio(1f),\n        content = {\n            LoadingIndicator(\n                modifier = Modifier.size(this.minHeight / 1.2f)\n            )\n        }\n    )\n}\n\n@Composable\nfun BoxScope.EnhancedLoadingIndicator(\n    progress: Float,\n    loaderSize: Dp = 60.dp,\n    additionalContent: @Composable (Dp) -> Unit = {}\n) {\n    EnhancedLoadingIndicatorContainer(\n        modifier = Modifier\n            .size(108.dp)\n            .align(Alignment.Center),\n        content = {\n            BoxWithConstraints(\n                modifier = Modifier.size(loaderSize),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedCircularProgressIndicator(\n                    modifier = Modifier.size(this.maxWidth),\n                    color = MaterialTheme.colorScheme.secondary.copy(0.3f),\n                    trackColor = MaterialTheme.colorScheme.surfaceContainer\n                )\n                val progressAnimated = animateFloatAsState(targetValue = progress)\n                EnhancedCircularProgressIndicator(\n                    modifier = Modifier.size(maxWidth),\n                    progress = { progressAnimated.value },\n                    color = MaterialTheme.colorScheme.primary,\n                    trackColor = Color.Transparent\n                )\n                additionalContent(maxWidth)\n            }\n        }\n    )\n}\n\n@Composable\nfun BoxScope.EnhancedLoadingIndicator(done: Int, left: Int) {\n    val progress = done / left.toFloat()\n\n    if (progress.isFinite() && progress >= 0 && left > 1) {\n        EnhancedLoadingIndicator(\n            progress = progress,\n            additionalContent = {\n                AutoSizeText(\n                    text = \"$done / $left\",\n                    maxLines = 1,\n                    fontWeight = FontWeight.Medium,\n                    modifier = Modifier.width(it * 0.7f),\n                    textAlign = TextAlign.Center\n                )\n            }\n        )\n    } else {\n        EnhancedLoadingIndicator(\n            modifier = Modifier\n                .align(Alignment.Center)\n                .size(108.dp)\n        )\n    }\n}\n\n@Composable\nprivate fun EnhancedLoadingIndicatorContainer(\n    modifier: Modifier,\n    content: @Composable BoxWithConstraintsScope.() -> Unit\n) {\n    val infiniteTransition = rememberInfiniteTransition()\n    val rotation by infiniteTransition.animateFloat(\n        initialValue = 0f,\n        targetValue = 360f,\n        animationSpec = infiniteRepeatable(\n            tween(\n                durationMillis = 1300,\n                easing = RotationEasing\n            )\n        )\n    )\n\n    BoxWithConstraints(\n        modifier = modifier.keepScreenOn(),\n        contentAlignment = Alignment.Center\n    ) {\n        val settingsState = LocalSettingsState.current\n        val borderWidth = settingsState.borderWidth\n        val backgroundColor = takeColorFromScheme {\n            surfaceContainerHighest.blend(\n                color = primaryContainer,\n                fraction = 0.1f\n            )\n        }\n\n        Spacer(\n            modifier = Modifier\n                .size(minHeight)\n                .rotate(rotation)\n                .then(\n                    if (borderWidth <= 0.dp && settingsState.drawContainerShadows) {\n                        Modifier.rsBlurShadow(\n                            radius = 1.05.dp,\n                            shape = MaterialStarShape,\n                            isAlphaContentClip = true,\n                            offset = DpOffset.Zero,\n                            spread = if (settingsState.isNightMode) 1.15.dp else 0.44.dp,\n                            color = MaterialTheme.colorScheme.scrim.copy(0.31f)\n                        )\n                    } else Modifier\n                )\n                .background(\n                    color = backgroundColor,\n                    shape = MaterialStarShape\n                )\n                .border(\n                    width = borderWidth,\n                    color = MaterialTheme.colorScheme.outlineVariant(\n                        luminance = 0.1f,\n                        onTopOf = backgroundColor\n                    ),\n                    shape = MaterialStarShape\n                )\n        )\n\n        content()\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedModalBottomSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.statusBarsPadding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ModalBottomSheet\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.GraphicsLayerScope\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.TransformOrigin\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalInspectionMode\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.FancyTransitionEasing\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.CornerSides\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.autoElevatedBorder\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.only\nimport com.t8rin.modalsheet.ModalBottomSheetValue\nimport com.t8rin.modalsheet.ModalSheet\nimport com.t8rin.modalsheet.rememberModalBottomSheetState\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun EnhancedModalBottomSheet(\n    nestedScrollEnabled: Boolean = false,\n    cancelable: Boolean = true,\n    dragHandle: @Composable ColumnScope.() -> Unit = { EnhancedModalSheetDragHandle() },\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    sheetContent: @Composable ColumnScope.() -> Unit,\n) {\n    EnhancedModalSheetImpl(\n        cancelable = cancelable,\n        nestedScrollEnabled = nestedScrollEnabled,\n        dragHandle = dragHandle,\n        visible = visible,\n        onVisibleChange = onDismiss,\n        content = sheetContent\n    )\n}\n\n@Composable\nfun EnhancedModalBottomSheet(\n    nestedScrollEnabled: Boolean,\n    cancelable: Boolean = true,\n    confirmButton: @Composable RowScope.() -> Unit,\n    dragHandle: @Composable ColumnScope.() -> Unit = { EnhancedModalSheetDragHandle() },\n    title: @Composable () -> Unit,\n    endConfirmButtonPadding: Dp = 12.dp,\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    enableBackHandler: Boolean = true,\n    sheetContent: @Composable ColumnScope.() -> Unit,\n) {\n    EnhancedModalSheetImpl(\n        cancelable = cancelable,\n        nestedScrollEnabled = nestedScrollEnabled,\n        dragHandle = dragHandle,\n        visible = visible,\n        onVisibleChange = onDismiss,\n        enableBackHandler = enableBackHandler,\n        content = {\n            Column(\n                modifier = Modifier.weight(1f, false),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                content = sheetContent\n            )\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .drawHorizontalStroke(true, autoElevation = 6.dp)\n                    .background(EnhancedBottomSheetDefaults.barContainerColor)\n                    .padding(8.dp)\n                    .navigationBarsPadding()\n                    .padding(end = endConfirmButtonPadding),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                title()\n                Spacer(modifier = Modifier.weight(1f))\n                confirmButton()\n            }\n        }\n    )\n}\n\n@Composable\nfun EnhancedModalBottomSheet(\n    nestedScrollEnabled: Boolean = false,\n    cancelable: Boolean = true,\n    confirmButton: (@Composable RowScope.() -> Unit)? = null,\n    dragHandle: @Composable ColumnScope.() -> Unit = { EnhancedModalSheetDragHandle() },\n    title: (@Composable RowScope.() -> Unit)? = null,\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    enableBackHandler: Boolean = true,\n    enableBottomContentWeight: Boolean = true,\n    sheetContent: @Composable ColumnScope.() -> Unit,\n) {\n    EnhancedModalSheetImpl(\n        cancelable = cancelable,\n        nestedScrollEnabled = nestedScrollEnabled,\n        dragHandle = dragHandle,\n        visible = visible,\n        onVisibleChange = onDismiss,\n        enableBackHandler = enableBackHandler,\n        content = {\n            Column(\n                modifier = Modifier.weight(1f, false),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                content = sheetContent\n            )\n            if (confirmButton != null && title != null) {\n                Row(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .drawHorizontalStroke(true, autoElevation = 6.dp)\n                        .background(EnhancedBottomSheetDefaults.barContainerColor)\n                        .navigationBarsPadding()\n                        .padding(8.dp)\n                        .then(\n                            if (enableBottomContentWeight) Modifier.padding(end = 12.dp)\n                            else Modifier\n                        ),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Row(\n                        modifier = Modifier.then(\n                            if (enableBottomContentWeight) {\n                                Modifier.weight(1f)\n                            } else Modifier\n                        )\n                    ) {\n                        title()\n                    }\n                    confirmButton()\n                }\n            }\n        }\n    )\n}\n\n\n@Composable\nprivate fun EnhancedModalSheetImpl(\n    visible: Boolean,\n    onVisibleChange: (Boolean) -> Unit,\n    modifier: Modifier = Modifier,\n    dragHandle: @Composable ColumnScope.() -> Unit = { EnhancedModalSheetDragHandle() },\n    nestedScrollEnabled: Boolean = false,\n    animationSpec: AnimationSpec<Float> = EnhancedBottomSheetDefaults.animationSpec,\n    sheetModifier: Modifier = Modifier,\n    cancelable: Boolean = true,\n    skipHalfExpanded: Boolean = true,\n    shape: Shape = EnhancedBottomSheetDefaults.shape,\n    elevation: Dp = 0.dp,\n    containerColor: Color = EnhancedBottomSheetDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    scrimColor: Color = EnhancedBottomSheetDefaults.scrimColor,\n    enableBackHandler: Boolean = true,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    if (LocalInspectionMode.current && visible) {\n        return ProvideContainerDefaults(\n            color = EnhancedBottomSheetDefaults.contentContainerColor\n        ) {\n            ModalBottomSheet(\n                onDismissRequest = { onVisibleChange(false) },\n                containerColor = containerColor,\n                contentColor = contentColor,\n                shape = shape,\n                sheetState = androidx.compose.material3.rememberModalBottomSheetState(\n                    skipPartiallyExpanded = skipHalfExpanded\n                ),\n                dragHandle = { Column(content = dragHandle) },\n                content = content\n            )\n        }\n    }\n\n    var predictiveBackProgress by remember {\n        mutableFloatStateOf(0f)\n    }\n    val animatedPredictiveBackProgress by animateFloatAsState(predictiveBackProgress)\n\n    val clean = {\n        predictiveBackProgress = 0f\n    }\n\n    LaunchedEffect(visible) {\n        if (!visible) {\n            delay(300L)\n            clean()\n        }\n    }\n\n    // Hold cancelable flag internally and set to true when modal sheet is dismissed via \"visible\" property in\n    // non-cancellable modal sheet. This ensures that \"confirmValueChange\" will return true when sheet is set to hidden\n    // state.\n    val internalCancelable = remember { mutableStateOf(cancelable) }\n    val sheetState = rememberModalBottomSheetState(\n        skipHalfExpanded = skipHalfExpanded,\n        initialValue = ModalBottomSheetValue.Hidden,\n        animationSpec = animationSpec,\n        confirmValueChange = {\n            // Intercept and disallow hide gesture / action\n            if (it == ModalBottomSheetValue.Hidden && !internalCancelable.value) {\n                return@rememberModalBottomSheetState false\n            }\n            true\n        },\n    )\n    val scope = rememberCoroutineScope()\n    var isAnimating by remember {\n        mutableStateOf(false)\n    }\n\n    LaunchedEffect(visible, cancelable) {\n        if (visible) {\n            internalCancelable.value = cancelable\n            isAnimating = true\n            scope.launch {\n                sheetState.show()\n                isAnimating = false\n            }\n        } else {\n            internalCancelable.value = true\n            isAnimating = true\n            scope.launch {\n                sheetState.hide()\n                isAnimating = false\n            }\n        }\n    }\n\n    LaunchedEffect(sheetState.currentValue, sheetState.targetValue, sheetState.progress) {\n        delay(600)\n        if (sheetState.progress == 1f && sheetState.currentValue == sheetState.targetValue) {\n            val newVisible = sheetState.isVisible\n            if (newVisible != visible) {\n                onVisibleChange(newVisible)\n            }\n        }\n    }\n\n    if (!visible && sheetState.currentValue == sheetState.targetValue && !sheetState.isVisible && !isAnimating) return\n\n    val settingsState = LocalSettingsState.current\n\n    val autoElevation by animateDpAsState(\n        if (settingsState.drawContainerShadows) 16.dp\n        else 0.dp\n    )\n\n    ProvideContainerDefaults(\n        color = EnhancedBottomSheetDefaults.contentContainerColor\n    ) {\n        ModalSheet(\n            sheetState = sheetState,\n            onDismiss = {\n                if (cancelable) {\n                    onVisibleChange(false)\n                }\n            },\n            dragHandle = dragHandle,\n            nestedScrollEnabled = nestedScrollEnabled,\n            sheetModifier = sheetModifier\n                .statusBarsPadding()\n                .graphicsLayer {\n                    val sheetOffset = 0f\n                    val sheetHeight = size.height\n                    if (!sheetOffset.isNaN() && !sheetHeight.isNaN() && sheetHeight != 0f) {\n                        val progress = animatedPredictiveBackProgress\n                        scaleX = calculatePredictiveBackScaleX(progress)\n                        scaleY = calculatePredictiveBackScaleY(progress)\n                        transformOrigin = TransformOrigin(\n                            pivotFractionX = 0.5f,\n                            pivotFractionY = (sheetOffset + sheetHeight) / sheetHeight\n                        )\n                    }\n                }\n                .offset(y = (settingsState.borderWidth + 1.dp))\n                .autoElevatedBorder(\n                    shape = shape,\n                    autoElevation = autoElevation\n                )\n                .autoElevatedBorder(\n                    height = 0.dp,\n                    shape = shape,\n                    autoElevation = autoElevation\n                )\n                .clip(shape)\n                .animateContentSizeNoClip(spring()),\n            modifier = modifier,\n            shape = shape,\n            elevation = elevation,\n            containerColor = containerColor,\n            contentColor = contentColor,\n            scrimColor = scrimColor,\n            content = {\n                PredictiveBackObserver(\n                    onProgress = { progress ->\n                        predictiveBackProgress = progress / 6f\n                    },\n                    onClean = { isCompleted ->\n                        if (isCompleted) {\n                            onVisibleChange(false)\n                            delay(400)\n                        }\n                        clean()\n                    },\n                    enabled = visible && enableBackHandler\n                )\n                content()\n            },\n        )\n    }\n}\n\nprivate fun GraphicsLayerScope.calculatePredictiveBackScaleX(progress: Float): Float {\n    val width = size.width\n    return if (width.isNaN() || width == 0f) {\n        1f\n    } else {\n        (1f - progress).coerceAtLeast(0.85f)\n    }\n}\n\nprivate fun GraphicsLayerScope.calculatePredictiveBackScaleY(progress: Float): Float {\n    val height = size.height\n    return if (height.isNaN() || height == 0f) {\n        1f\n    } else {\n        (1f - progress).coerceAtLeast(0.85f)\n    }\n}\n\nobject EnhancedBottomSheetDefaults {\n\n    val shape @Composable get() = ShapeDefaults.extremeLarge.only(CornerSides.Top)\n\n    val barContainerColor: Color\n        @Composable\n        get() = MaterialTheme.colorScheme.surfaceContainerHigh\n\n    val containerColor: Color\n        @Composable\n        get() = MaterialTheme.colorScheme.surfaceContainerLow\n\n    val contentContainerColor: Color\n        @Composable\n        get() = MaterialTheme.colorScheme.surfaceContainer\n\n    val scrimColor: Color\n        @Composable\n        get() = MaterialTheme.colorScheme.scrim.copy(0.32f)\n\n    val animationSpec: AnimationSpec<Float> = tween(\n        durationMillis = 400,\n        easing = FancyTransitionEasing\n    )\n\n    val dragHandleHeight: Dp = 4.dp\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedModalSheetDragHandle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport kotlin.math.tan\n\n\n@Composable\nfun EnhancedModalSheetDragHandle(\n    modifier: Modifier = Modifier,\n    color: Color = EnhancedBottomSheetDefaults.barContainerColor,\n    drawStroke: Boolean = true,\n    showDragHandle: Boolean = true,\n    bendAngle: Float = 0f,\n    strokeWidth: Dp = EnhancedBottomSheetDefaults.dragHandleHeight,\n    heightWhenDisabled: Dp = 0.dp,\n    content: @Composable ColumnScope.() -> Unit = {},\n) {\n    val dragHandleWidth = LocalSettingsState.current.dragHandleWidth\n    Column(\n        modifier\n            .then(\n                if (drawStroke) {\n                    Modifier\n                        .drawHorizontalStroke(autoElevation = 3.dp)\n                        .zIndex(Float.MAX_VALUE)\n                } else Modifier\n            )\n            .background(color),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        if (showDragHandle && dragHandleWidth > 0.dp) {\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(vertical = 22.dp),\n                horizontalArrangement = Arrangement.Center\n            ) {\n                BendableDragHandle(\n                    width = dragHandleWidth,\n                    angleDegrees = bendAngle,\n                    strokeWidth = strokeWidth,\n                    color = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.4f).compositeOver(\n                        MaterialTheme.colorScheme.surface\n                    )\n                )\n            }\n        } else {\n            Spacer(modifier = Modifier.height(heightWhenDisabled))\n        }\n\n        content()\n    }\n}\n\n@Composable\nprivate fun BendableDragHandle(\n    width: Dp,\n    angleDegrees: Float,\n    strokeWidth: Dp,\n    color: Color,\n    modifier: Modifier = Modifier\n) {\n    val density = LocalDensity.current\n    val stroke = with(density) { strokeWidth.toPx() }\n    val totalWidth = with(density) { width.toPx() }\n    val halfWidth = totalWidth / 2f\n    val halfStroke = stroke / 2f\n\n    val angleRadians =\n        Math.toRadians((angleDegrees * (64 / width.value).coerceAtMost(1f)).toDouble()).toFloat()\n    val height = tan(angleRadians) * halfWidth\n\n    Canvas(\n        modifier = modifier\n            .width(width)\n            .height(height.dp + strokeWidth)\n    ) {\n        val centerY = size.height / 2f\n        val centerX = size.width / 2f\n\n        val leftStart = Offset(0f, centerY)\n        val center = Offset(centerX, centerY + height)\n        val rightEnd = Offset(size.width, centerY)\n\n        drawLine(\n            color = color,\n            start = leftStart,\n            end = center,\n            strokeWidth = stroke,\n            cap = StrokeCap.Round\n        )\n\n        drawLine(\n            color = color,\n            start = center,\n            end = rightEnd,\n            strokeWidth = stroke,\n            cap = StrokeCap.Round\n        )\n\n        drawCircle(\n            color = color,\n            radius = halfStroke,\n            center = center\n        )\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedNavigationBarItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.NavigationBarItemColors\nimport androidx.compose.material3.NavigationBarItemDefaults\nimport androidx.compose.material3.ripple\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.clearAndSetSemantics\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.fastFirstOrNull\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport kotlin.math.roundToInt\n\n@Composable\nfun RowScope.EnhancedNavigationBarItem(\n    selected: Boolean,\n    onClick: () -> Unit,\n    icon: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    label: @Composable (() -> Unit)? = null,\n    alwaysShowLabel: Boolean = true,\n    colors: NavigationBarItemColors = NavigationBarItemDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    val colorAnimationSpec = MaterialTheme.motionScheme.defaultEffectsSpec<Color>()\n    val styledIcon =\n        @Composable {\n            val iconColor by\n            animateColorAsState(\n                targetValue = colors.iconColor(selected = selected, enabled = enabled),\n                animationSpec = colorAnimationSpec,\n            )\n            // If there's a label, don't have a11y services repeat the icon description.\n            val clearSemantics = label != null && (alwaysShowLabel || selected)\n            Box(modifier = if (clearSemantics) Modifier.clearAndSetSemantics {} else Modifier) {\n                CompositionLocalProvider(LocalContentColor provides iconColor, content = icon)\n            }\n        }\n\n    val styledLabel: @Composable (() -> Unit)? =\n        label?.let {\n            @Composable {\n                val style = NavigationBarTokens.LabelTextFont\n                val textColor by\n                animateColorAsState(\n                    targetValue = colors.textColor(selected = selected, enabled = enabled),\n                    animationSpec = colorAnimationSpec,\n                )\n                ProvideContentColorTextStyle(\n                    contentColor = textColor,\n                    textStyle = style,\n                    content = label,\n                )\n            }\n        }\n\n    var itemWidth by remember { mutableIntStateOf(0) }\n\n    Box(\n        modifier\n            .selectable(\n                selected = selected,\n                onClick = onClick,\n                enabled = enabled,\n                role = Role.Tab,\n                interactionSource = interactionSource,\n                indication = null,\n            )\n            .defaultMinSize(minHeight = NavigationBarHeight)\n            .weight(1f)\n            .onSizeChanged { itemWidth = it.width },\n        contentAlignment = Alignment.Center,\n        propagateMinConstraints = true,\n    ) {\n        val alphaAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                animationSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),\n            )\n        val sizeAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                animationSpec = MaterialTheme.motionScheme.fastSpatialSpec(),\n            )\n        // The entire item is selectable, but only the indicator pill shows the ripple. To achieve\n        // this, we re-map the coordinates of the item's InteractionSource into the coordinates of\n        // the indicator.\n        val density = LocalDensity.current\n        val calculateDeltaOffset = {\n            with(density) {\n                val indicatorWidth =\n                    NavigationBarVerticalItemTokens.ActiveIndicatorWidth.roundToPx()\n                Offset((itemWidth - indicatorWidth).toFloat() / 2, IndicatorVerticalOffset.toPx())\n            }\n        }\n        val offsetInteractionSource =\n            remember(interactionSource, calculateDeltaOffset) {\n                MappedInteractionSource(interactionSource, calculateDeltaOffset)\n            }\n\n        val indicatorShape = shapeByInteraction(\n            shape = NavigationBarTokens.ItemActiveIndicatorShape,\n            pressedShape = ShapeDefaults.pressed,\n            interactionSource = interactionSource\n        )\n\n        // The indicator has a width-expansion animation which interferes with the timing of the\n        // ripple, which is why they are separate composables\n        val indicatorRipple =\n            @Composable {\n                Box(\n                    Modifier\n                        .layoutId(IndicatorRippleLayoutIdTag)\n                        .clip(indicatorShape)\n                        .indication(offsetInteractionSource, ripple())\n                )\n            }\n        val indicator =\n            @Composable {\n                Box(\n                    Modifier\n                        .layoutId(IndicatorLayoutIdTag)\n                        .graphicsLayer { alpha = alphaAnimationProgress.value }\n                        .background(\n                            color = colors.selectedIndicatorColor,\n                            shape = indicatorShape\n                        )\n                )\n            }\n\n        NavigationBarItemLayout(\n            indicatorRipple = indicatorRipple,\n            indicator = indicator,\n            icon = styledIcon,\n            label = styledLabel,\n            alwaysShowLabel = alwaysShowLabel,\n            alphaAnimationProgress = { alphaAnimationProgress.value },\n            sizeAnimationProgress = { sizeAnimationProgress.value },\n        )\n    }\n}\n\n@Composable\nprivate fun NavigationBarItemLayout(\n    indicatorRipple: @Composable () -> Unit,\n    indicator: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    label: @Composable (() -> Unit)?,\n    alwaysShowLabel: Boolean,\n    alphaAnimationProgress: () -> Float,\n    sizeAnimationProgress: () -> Float,\n) {\n    Layout(\n        modifier = Modifier.badgeBounds(),\n        content = {\n            indicatorRipple()\n            indicator()\n\n            Box(Modifier.layoutId(IconLayoutIdTag)) { icon() }\n\n            if (label != null) {\n                Box(\n                    Modifier\n                        .layoutId(LabelLayoutIdTag)\n                        .graphicsLayer {\n                            alpha = if (alwaysShowLabel) 1f else alphaAnimationProgress()\n                        }\n                ) {\n                    label()\n                }\n            }\n        },\n    ) { measurables, constraints ->\n        @Suppress(\"NAME_SHADOWING\")\n        // Ensure that the progress is >= 0. It may be negative on bouncy springs, for example.\n        val animationProgress = sizeAnimationProgress().coerceAtLeast(0f)\n        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n        val iconPlaceable =\n            measurables.fastFirst { it.layoutId == IconLayoutIdTag }.measure(looseConstraints)\n\n        val totalIndicatorWidth = iconPlaceable.width + (IndicatorHorizontalPadding * 2).roundToPx()\n        val animatedIndicatorWidth = (totalIndicatorWidth * animationProgress).roundToInt()\n        val indicatorHeight = iconPlaceable.height + (IndicatorVerticalPadding * 2).roundToPx()\n        val indicatorRipplePlaceable =\n            measurables\n                .fastFirst { it.layoutId == IndicatorRippleLayoutIdTag }\n                .measure(Constraints.fixed(width = totalIndicatorWidth, height = indicatorHeight))\n        val indicatorPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == IndicatorLayoutIdTag }\n                ?.measure(\n                    Constraints.fixed(width = animatedIndicatorWidth, height = indicatorHeight)\n                )\n\n        val labelPlaceable =\n            label?.let {\n                measurables.fastFirst { it.layoutId == LabelLayoutIdTag }.measure(looseConstraints)\n            }\n\n        if (label == null) {\n            placeIcon(iconPlaceable, indicatorRipplePlaceable, indicatorPlaceable, constraints)\n        } else {\n            placeLabelAndIcon(\n                labelPlaceable!!,\n                iconPlaceable,\n                indicatorRipplePlaceable,\n                indicatorPlaceable,\n                constraints,\n                alwaysShowLabel,\n                animationProgress,\n            )\n        }\n    }\n}\n\n/** Places the provided [Placeable]s in the center of the provided [constraints]. */\nprivate fun MeasureScope.placeIcon(\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n): MeasureResult {\n    val width =\n        if (constraints.maxWidth == Constraints.Infinity) {\n            iconPlaceable.width + NavigationBarItemToIconMinimumPadding.roundToPx() * 2\n        } else {\n            constraints.maxWidth\n        }\n    val height = constraints.constrainHeight(NavigationBarHeight.roundToPx())\n\n    val iconX = (width - iconPlaceable.width) / 2\n    val iconY = (height - iconPlaceable.height) / 2\n\n    val rippleX = (width - indicatorRipplePlaceable.width) / 2\n    val rippleY = (height - indicatorRipplePlaceable.height) / 2\n\n    return layout(width, height) {\n        indicatorPlaceable?.let {\n            val indicatorX = (width - it.width) / 2\n            val indicatorY = (height - it.height) / 2\n            it.placeRelative(indicatorX, indicatorY)\n        }\n        iconPlaceable.placeRelative(iconX, iconY)\n        indicatorRipplePlaceable.placeRelative(rippleX, rippleY)\n    }\n}\n\n/**\n * Places the provided [Placeable]s in the correct position, depending on [alwaysShowLabel] and\n * [animationProgress].\n *\n * When [alwaysShowLabel] is true, the positions do not move. The [iconPlaceable] and\n * [labelPlaceable] will be placed together in the center with padding between them, according to\n * the spec.\n *\n * When [animationProgress] is 1 (representing the selected state), the positions will be the same\n * as above.\n *\n * Otherwise, when [animationProgress] is 0, [iconPlaceable] will be placed in the center, like in\n * [placeIcon], and [labelPlaceable] will not be shown.\n *\n * When [animationProgress] is animating between these values, [iconPlaceable] and [labelPlaceable]\n * will be placed at a corresponding interpolated position.\n *\n * [indicatorRipplePlaceable] and [indicatorPlaceable] will always be placed in such a way that to\n * share the same center as [iconPlaceable].\n *\n * @param labelPlaceable text label placeable inside this item\n * @param iconPlaceable icon placeable inside this item\n * @param indicatorRipplePlaceable indicator ripple placeable inside this item\n * @param indicatorPlaceable indicator placeable inside this item, if it exists\n * @param constraints constraints of the item\n * @param alwaysShowLabel whether to always show the label for this item. If true, icon and label\n *   positions will not change. If false, positions transition between 'centered icon with no label'\n *   and 'top aligned icon with label'.\n * @param animationProgress progress of the animation, where 0 represents the unselected state of\n *   this item and 1 represents the selected state. Values between 0 and 1 interpolate positions of\n *   the icon and label.\n */\nprivate fun MeasureScope.placeLabelAndIcon(\n    labelPlaceable: Placeable,\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n    alwaysShowLabel: Boolean,\n    animationProgress: Float,\n): MeasureResult {\n    val contentHeight =\n        iconPlaceable.height +\n                IndicatorVerticalPadding.toPx() +\n                NavigationBarIndicatorToLabelPadding.toPx() +\n                labelPlaceable.height\n    val contentVerticalPadding =\n        ((constraints.minHeight - contentHeight) / 2).coerceAtLeast(IndicatorVerticalPadding.toPx())\n    val height = contentHeight + contentVerticalPadding * 2\n\n    // Icon (when selected) should be `contentVerticalPadding` from top\n    val selectedIconY = contentVerticalPadding\n    val unselectedIconY =\n        if (alwaysShowLabel) selectedIconY else (height - iconPlaceable.height) / 2\n\n    // How far the icon needs to move between unselected and selected states.\n    val iconDistance = unselectedIconY - selectedIconY\n\n    // The interpolated fraction of iconDistance that all placeables need to move based on\n    // animationProgress.\n    val offset = iconDistance * (1 - animationProgress)\n\n    // Label should be fixed padding below icon\n    val labelY =\n        selectedIconY +\n                iconPlaceable.height +\n                IndicatorVerticalPadding.toPx() +\n                NavigationBarIndicatorToLabelPadding.toPx()\n\n    val containerWidth =\n        if (constraints.maxWidth == Constraints.Infinity) {\n            iconPlaceable.width + NavigationBarItemToIconMinimumPadding.roundToPx() * 2\n        } else {\n            constraints.maxWidth\n        }\n\n    val labelX = (containerWidth - labelPlaceable.width) / 2\n    val iconX = (containerWidth - iconPlaceable.width) / 2\n\n    val rippleX = (containerWidth - indicatorRipplePlaceable.width) / 2\n    val rippleY = selectedIconY - IndicatorVerticalPadding.toPx()\n\n    return layout(containerWidth, height.roundToInt()) {\n        indicatorPlaceable?.let {\n            val indicatorX = (containerWidth - it.width) / 2\n            val indicatorY = selectedIconY - IndicatorVerticalPadding.roundToPx()\n            it.placeRelative(indicatorX, (indicatorY + offset).roundToInt())\n        }\n        if (alwaysShowLabel || animationProgress != 0f) {\n            labelPlaceable.placeRelative(labelX, (labelY + offset).roundToInt())\n        }\n        iconPlaceable.placeRelative(iconX, (selectedIconY + offset).roundToInt())\n        indicatorRipplePlaceable.placeRelative(rippleX, (rippleY + offset).roundToInt())\n    }\n}\n\nprivate const val IndicatorRippleLayoutIdTag: String = \"indicatorRipple\"\n\nprivate const val IndicatorLayoutIdTag: String = \"indicator\"\n\nprivate const val IconLayoutIdTag: String = \"icon\"\n\nprivate const val LabelLayoutIdTag: String = \"label\"\n\nprivate val NavigationBarHeight: Dp = NavigationBarTokens.TallContainerHeight\n\n/*@VisibleForTesting*/\ninternal val NavigationBarIndicatorToLabelPadding: Dp = 4.dp\n\nprivate val IndicatorHorizontalPadding: Dp =\n    (NavigationBarVerticalItemTokens.ActiveIndicatorWidth -\n            NavigationBarVerticalItemTokens.IconSize) / 2\n\n/*@VisibleForTesting*/\ninternal val IndicatorVerticalPadding: Dp =\n    (NavigationBarVerticalItemTokens.ActiveIndicatorHeight -\n            NavigationBarVerticalItemTokens.IconSize) / 2\n\nprivate val IndicatorVerticalOffset: Dp = 12.dp\n\n/*@VisibleForTesting*/\ninternal val NavigationBarItemToIconMinimumPadding: Dp = 44.dp\n\ninternal object NavigationBarTokens {\n    val ItemActiveIndicatorShape @Composable get() = AutoCornersShape(16.dp)\n    val TallContainerHeight = 80.0.dp\n    val LabelTextFont @Composable get() = MaterialTheme.typography.labelMedium\n}\n\ninternal object NavigationBarVerticalItemTokens {\n    val ActiveIndicatorHeight = 32.0.dp\n    val ActiveIndicatorWidth = 56.0.dp\n    val IconSize = 24.0.dp\n}\n\n@Stable\ninternal fun NavigationBarItemColors.iconColor(selected: Boolean, enabled: Boolean): Color =\n    when {\n        !enabled -> disabledIconColor\n        selected -> selectedIconColor\n        else -> unselectedIconColor\n    }\n\n@Stable\ninternal fun NavigationBarItemColors.textColor(selected: Boolean, enabled: Boolean): Color =\n    when {\n        !enabled -> disabledTextColor\n        selected -> selectedTextColor\n        else -> unselectedTextColor\n    }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedNavigationRailItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ripple\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.layout.HorizontalRuler\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.VerticalRuler\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.clearAndSetSemantics\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.constrainWidth\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.fastFirstOrNull\nimport com.t8rin.imagetoolbox.core.ui.theme.DisabledAlpha\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport kotlinx.coroutines.flow.map\nimport kotlin.math.roundToInt\n\n@Composable\nfun EnhancedNavigationRailItem(\n    selected: Boolean,\n    onClick: () -> Unit,\n    icon: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    label: @Composable (() -> Unit)? = null,\n    alwaysShowLabel: Boolean = true,\n    colors: NavigationRailItemColors = NavigationRailItemDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    val colorAnimationSpec = MaterialTheme.motionScheme.defaultEffectsSpec<Color>()\n    val styledIcon =\n        @Composable {\n            val iconColor by\n            animateColorAsState(\n                targetValue = colors.iconColor(selected = selected, enabled = enabled),\n                animationSpec = colorAnimationSpec,\n            )\n            // If there's a label, don't have a11y services repeat the icon description.\n            val clearSemantics = label != null && (alwaysShowLabel || selected)\n            Box(modifier = if (clearSemantics) Modifier.clearAndSetSemantics {} else Modifier) {\n                CompositionLocalProvider(LocalContentColor provides iconColor, content = icon)\n            }\n        }\n\n    val styledLabel: @Composable (() -> Unit)? =\n        label?.let {\n            @Composable {\n                val style = NavigationRailVerticalItemTokens.LabelTextFont\n                val textColor by\n                animateColorAsState(\n                    targetValue = colors.textColor(selected = selected, enabled = enabled),\n                    animationSpec = colorAnimationSpec,\n                )\n                ProvideContentColorTextStyle(\n                    contentColor = textColor,\n                    textStyle = style,\n                    content = label,\n                )\n            }\n        }\n\n    Box(\n        modifier\n            .selectable(\n                selected = selected,\n                onClick = onClick,\n                enabled = enabled,\n                role = Role.Tab,\n                interactionSource = interactionSource,\n                indication = null,\n            )\n            .defaultMinSize(minHeight = NavigationRailItemHeight)\n            .widthIn(min = NavigationRailItemWidth),\n        contentAlignment = Alignment.Center,\n        propagateMinConstraints = true,\n    ) {\n        val alphaAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                animationSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),\n            )\n        val sizeAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                animationSpec = MaterialTheme.motionScheme.fastSpatialSpec(),\n            )\n\n        // The entire item is selectable, but only the indicator pill shows the ripple. To achieve\n        // this, we re-map the coordinates of the item's InteractionSource into the coordinates of\n        // the indicator.\n        val density = LocalDensity.current\n        val calculateDeltaOffset = {\n            with(density) {\n                val itemWidth = NavigationRailItemWidth.roundToPx()\n                val indicatorWidth =\n                    NavigationRailVerticalItemTokens.ActiveIndicatorWidth.roundToPx()\n                Offset((itemWidth - indicatorWidth).toFloat() / 2, 0f)\n            }\n        }\n        val offsetInteractionSource =\n            remember(interactionSource, calculateDeltaOffset) {\n                MappedInteractionSource(interactionSource, calculateDeltaOffset)\n            }\n\n        val indicatorShape = shapeByInteraction(\n            shape = NavigationRailBaselineItemTokens.ActiveIndicatorShape,\n            pressedShape = ShapeDefaults.pressed,\n            interactionSource = interactionSource\n        )\n\n        // The indicator has a width-expansion animation which interferes with the timing of the\n        // ripple, which is why they are separate composables\n        val indicatorRipple =\n            @Composable {\n                Box(\n                    Modifier\n                        .layoutId(IndicatorRippleLayoutIdTag)\n                        .clip(indicatorShape)\n                        .indication(offsetInteractionSource, ripple())\n                )\n            }\n        val indicator =\n            @Composable {\n                Box(\n                    Modifier\n                        .layoutId(IndicatorLayoutIdTag)\n                        .graphicsLayer { alpha = alphaAnimationProgress.value }\n                        .background(color = colors.indicatorColor, shape = indicatorShape)\n                )\n            }\n\n        NavigationRailItemLayout(\n            indicatorRipple = indicatorRipple,\n            indicator = indicator,\n            icon = styledIcon,\n            label = styledLabel,\n            alwaysShowLabel = alwaysShowLabel,\n            alphaAnimationProgress = { alphaAnimationProgress.value },\n            sizeAnimationProgress = { sizeAnimationProgress.value },\n        )\n    }\n}\n\nobject NavigationRailItemDefaults {\n    @Composable\n    fun colors(\n        selectedIconColor: Color = MaterialTheme.colorScheme.onSecondaryContainer,\n        selectedTextColor: Color = MaterialTheme.colorScheme.secondary,\n        indicatorColor: Color = MaterialTheme.colorScheme.secondaryContainer,\n        unselectedIconColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,\n        unselectedTextColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,\n        disabledIconColor: Color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = DisabledAlpha),\n        disabledTextColor: Color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = DisabledAlpha),\n    ): NavigationRailItemColors = NavigationRailItemColors(\n        selectedIconColor = selectedIconColor,\n        selectedTextColor = selectedTextColor,\n        selectedIndicatorColor = indicatorColor,\n        unselectedIconColor = unselectedIconColor,\n        unselectedTextColor = unselectedTextColor,\n        disabledIconColor = disabledIconColor,\n        disabledTextColor = disabledTextColor,\n    )\n\n}\n\n@Immutable\nclass NavigationRailItemColors(\n    val selectedIconColor: Color,\n    val selectedTextColor: Color,\n    val selectedIndicatorColor: Color,\n    val unselectedIconColor: Color,\n    val unselectedTextColor: Color,\n    val disabledIconColor: Color,\n    val disabledTextColor: Color,\n) {\n    /**\n     * Returns a copy of this NavigationRailItemColors, optionally overriding some of the values.\n     * This uses the Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        selectedIconColor: Color = this.selectedIconColor,\n        selectedTextColor: Color = this.selectedTextColor,\n        selectedIndicatorColor: Color = this.selectedIndicatorColor,\n        unselectedIconColor: Color = this.unselectedIconColor,\n        unselectedTextColor: Color = this.unselectedTextColor,\n        disabledIconColor: Color = this.disabledIconColor,\n        disabledTextColor: Color = this.disabledTextColor,\n    ) =\n        NavigationRailItemColors(\n            selectedIconColor.takeOrElse { this.selectedIconColor },\n            selectedTextColor.takeOrElse { this.selectedTextColor },\n            selectedIndicatorColor.takeOrElse { this.selectedIndicatorColor },\n            unselectedIconColor.takeOrElse { this.unselectedIconColor },\n            unselectedTextColor.takeOrElse { this.unselectedTextColor },\n            disabledIconColor.takeOrElse { this.disabledIconColor },\n            disabledTextColor.takeOrElse { this.disabledTextColor },\n        )\n\n    /**\n     * Represents the icon color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     * @param enabled whether the item is enabled\n     */\n    @Stable\n    internal fun iconColor(selected: Boolean, enabled: Boolean): Color =\n        when {\n            !enabled -> disabledIconColor\n            selected -> selectedIconColor\n            else -> unselectedIconColor\n        }\n\n    /**\n     * Represents the text color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     * @param enabled whether the item is enabled\n     */\n    @Stable\n    internal fun textColor(selected: Boolean, enabled: Boolean): Color =\n        when {\n            !enabled -> disabledTextColor\n            selected -> selectedTextColor\n            else -> unselectedTextColor\n        }\n\n    /** Represents the color of the indicator used for selected items. */\n    internal val indicatorColor: Color\n        get() = selectedIndicatorColor\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is NavigationRailItemColors) return false\n\n        if (selectedIconColor != other.selectedIconColor) return false\n        if (unselectedIconColor != other.unselectedIconColor) return false\n        if (selectedTextColor != other.selectedTextColor) return false\n        if (unselectedTextColor != other.unselectedTextColor) return false\n        if (selectedIndicatorColor != other.selectedIndicatorColor) return false\n        if (disabledIconColor != other.disabledIconColor) return false\n        if (disabledTextColor != other.disabledTextColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = selectedIconColor.hashCode()\n        result = 31 * result + unselectedIconColor.hashCode()\n        result = 31 * result + selectedTextColor.hashCode()\n        result = 31 * result + unselectedTextColor.hashCode()\n        result = 31 * result + selectedIndicatorColor.hashCode()\n        result = 31 * result + disabledIconColor.hashCode()\n        result = 31 * result + disabledTextColor.hashCode()\n\n        return result\n    }\n}\n\n@Composable\nprivate fun NavigationRailItemLayout(\n    indicatorRipple: @Composable () -> Unit,\n    indicator: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    label: @Composable (() -> Unit)?,\n    alwaysShowLabel: Boolean,\n    alphaAnimationProgress: () -> Float,\n    sizeAnimationProgress: () -> Float,\n) {\n    Layout(\n        modifier = Modifier.badgeBounds(),\n        content = {\n            indicatorRipple()\n            indicator()\n\n            Box(Modifier.layoutId(IconLayoutIdTag)) { icon() }\n\n            if (label != null) {\n                Box(\n                    Modifier\n                        .layoutId(LabelLayoutIdTag)\n                        .graphicsLayer {\n                            alpha = if (alwaysShowLabel) 1f else alphaAnimationProgress()\n                        }\n                ) {\n                    label()\n                }\n            }\n        },\n    ) { measurables, constraints ->\n        @Suppress(\"NAME_SHADOWING\")\n        // Ensure that the progress is >= 0. It may be negative on bouncy springs, for example.\n        val animationProgress = sizeAnimationProgress().coerceAtLeast(0f)\n        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n        val iconPlaceable =\n            measurables.fastFirst { it.layoutId == IconLayoutIdTag }.measure(looseConstraints)\n\n        val totalIndicatorWidth = iconPlaceable.width + (IndicatorHorizontalPadding * 2).roundToPx()\n        val animatedIndicatorWidth = (totalIndicatorWidth * animationProgress).roundToInt()\n        val indicatorVerticalPadding =\n            if (label == null) {\n                IndicatorVerticalPaddingNoLabel\n            } else {\n                IndicatorVerticalPaddingWithLabel\n            }\n        val indicatorHeight = iconPlaceable.height + (indicatorVerticalPadding * 2).roundToPx()\n\n        val indicatorRipplePlaceable =\n            measurables\n                .fastFirst { it.layoutId == IndicatorRippleLayoutIdTag }\n                .measure(Constraints.fixed(width = totalIndicatorWidth, height = indicatorHeight))\n        val indicatorPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == IndicatorLayoutIdTag }\n                ?.measure(\n                    Constraints.fixed(width = animatedIndicatorWidth, height = indicatorHeight)\n                )\n\n        val labelPlaceable =\n            label?.let {\n                measurables.fastFirst { it.layoutId == LabelLayoutIdTag }.measure(looseConstraints)\n            }\n\n        if (label == null) {\n            placeIcon(iconPlaceable, indicatorRipplePlaceable, indicatorPlaceable, constraints)\n        } else {\n            placeLabelAndIcon(\n                labelPlaceable!!,\n                iconPlaceable,\n                indicatorRipplePlaceable,\n                indicatorPlaceable,\n                constraints,\n                alwaysShowLabel,\n                animationProgress,\n            )\n        }\n    }\n}\n\n/** Places the provided [Placeable]s in the center of the provided [constraints]. */\nprivate fun MeasureScope.placeIcon(\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n): MeasureResult {\n    val width =\n        constraints.constrainWidth(\n            maxOf(\n                iconPlaceable.width,\n                indicatorRipplePlaceable.width,\n                indicatorPlaceable?.width ?: 0,\n            )\n        )\n    val height = constraints.constrainHeight(NavigationRailItemHeight.roundToPx())\n\n    val iconX = (width - iconPlaceable.width) / 2\n    val iconY = (height - iconPlaceable.height) / 2\n\n    val rippleX = (width - indicatorRipplePlaceable.width) / 2\n    val rippleY = (height - indicatorRipplePlaceable.height) / 2\n\n    return layout(width, height) {\n        indicatorPlaceable?.let {\n            val indicatorX = (width - it.width) / 2\n            val indicatorY = (height - it.height) / 2\n            it.placeRelative(indicatorX, indicatorY)\n        }\n        iconPlaceable.placeRelative(iconX, iconY)\n        indicatorRipplePlaceable.placeRelative(rippleX, rippleY)\n    }\n}\n\n/**\n * Places the provided [Placeable]s in the correct position, depending on [alwaysShowLabel] and\n * [animationProgress].\n *\n * When [alwaysShowLabel] is true, the positions do not move. The [iconPlaceable] and\n * [labelPlaceable] will be placed together in the center with padding between them, according to\n * the spec.\n *\n * When [animationProgress] is 1 (representing the selected state), the positions will be the same\n * as above.\n *\n * Otherwise, when [animationProgress] is 0, [iconPlaceable] will be placed in the center, like in\n * [placeIcon], and [labelPlaceable] will not be shown.\n *\n * When [animationProgress] is animating between these values, [iconPlaceable] and [labelPlaceable]\n * will be placed at a corresponding interpolated position.\n *\n * [indicatorRipplePlaceable] and [indicatorPlaceable] will always be placed in such a way that to\n * share the same center as [iconPlaceable].\n *\n * @param labelPlaceable text label placeable inside this item\n * @param iconPlaceable icon placeable inside this item\n * @param indicatorRipplePlaceable indicator ripple placeable inside this item\n * @param indicatorPlaceable indicator placeable inside this item, if it exists\n * @param constraints constraints of the item\n * @param alwaysShowLabel whether to always show the label for this item. If true, icon and label\n *   positions will not change. If false, positions transition between 'centered icon with no label'\n *   and 'top aligned icon with label'.\n * @param animationProgress progress of the animation, where 0 represents the unselected state of\n *   this item and 1 represents the selected state. Values between 0 and 1 interpolate positions of\n *   the icon and label.\n */\nprivate fun MeasureScope.placeLabelAndIcon(\n    labelPlaceable: Placeable,\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n    alwaysShowLabel: Boolean,\n    animationProgress: Float,\n): MeasureResult {\n    val contentHeight =\n        iconPlaceable.height +\n                IndicatorVerticalPaddingWithLabel.toPx() +\n                NavigationRailItemVerticalPadding.toPx() +\n                labelPlaceable.height\n    val contentVerticalPadding =\n        ((constraints.minHeight - contentHeight) / 2).coerceAtLeast(\n            IndicatorVerticalPaddingWithLabel.toPx()\n        )\n    val height = contentHeight + contentVerticalPadding * 2\n\n    // Icon (when selected) should be `contentVerticalPadding` from the top\n    val selectedIconY = contentVerticalPadding\n    val unselectedIconY =\n        if (alwaysShowLabel) selectedIconY else (height - iconPlaceable.height) / 2\n\n    // How far the icon needs to move between unselected and selected states\n    val iconDistance = unselectedIconY - selectedIconY\n\n    // The interpolated fraction of iconDistance that all placeables need to move based on\n    // animationProgress, since the icon is higher in the selected state.\n    val offset = iconDistance * (1 - animationProgress)\n\n    // Label should be fixed padding below icon\n    val labelY =\n        selectedIconY +\n                iconPlaceable.height +\n                IndicatorVerticalPaddingWithLabel.toPx() +\n                NavigationRailItemVerticalPadding.toPx()\n\n    val width =\n        constraints.constrainWidth(\n            maxOf(iconPlaceable.width, labelPlaceable.width, indicatorPlaceable?.width ?: 0)\n        )\n    val labelX = (width - labelPlaceable.width) / 2\n    val iconX = (width - iconPlaceable.width) / 2\n    val rippleX = (width - indicatorRipplePlaceable.width) / 2\n    val rippleY = selectedIconY - IndicatorVerticalPaddingWithLabel.toPx()\n\n    return layout(width, height.roundToInt()) {\n        indicatorPlaceable?.let {\n            val indicatorX = (width - it.width) / 2\n            val indicatorY = selectedIconY - IndicatorVerticalPaddingWithLabel.toPx()\n            it.placeRelative(indicatorX, (indicatorY + offset).roundToInt())\n        }\n        if (alwaysShowLabel || animationProgress != 0f) {\n            labelPlaceable.placeRelative(labelX, (labelY + offset).roundToInt())\n        }\n        iconPlaceable.placeRelative(iconX, (selectedIconY + offset).roundToInt())\n        indicatorRipplePlaceable.placeRelative(rippleX, (rippleY + offset).roundToInt())\n    }\n}\n\nprivate const val IndicatorRippleLayoutIdTag: String = \"indicatorRipple\"\n\nprivate const val IndicatorLayoutIdTag: String = \"indicator\"\n\nprivate const val IconLayoutIdTag: String = \"icon\"\n\nprivate const val LabelLayoutIdTag: String = \"label\"\n\ninternal val NavigationRailItemWidth: Dp = NavigationRailCollapsedTokens.NarrowContainerWidth\n\ninternal val NavigationRailItemHeight: Dp = NavigationRailVerticalItemTokens.ActiveIndicatorWidth\n\ninternal val NavigationRailItemVerticalPadding: Dp = 4.dp\n\nprivate val IndicatorHorizontalPadding: Dp =\n    (NavigationRailVerticalItemTokens.ActiveIndicatorWidth -\n            NavigationRailBaselineItemTokens.IconSize) / 2\n\nprivate val IndicatorVerticalPaddingWithLabel: Dp =\n    (NavigationRailVerticalItemTokens.ActiveIndicatorHeight -\n            NavigationRailBaselineItemTokens.IconSize) / 2\n\nprivate val IndicatorVerticalPaddingNoLabel: Dp =\n    (NavigationRailVerticalItemTokens.ActiveIndicatorWidth -\n            NavigationRailBaselineItemTokens.IconSize) / 2\n\ninternal val BadgeTopRuler = HorizontalRuler()\ninternal val BadgeEndRuler = VerticalRuler()\n\ninternal fun Modifier.badgeBounds() =\n    this.layout { measurable, constraints ->\n        val placeable = measurable.measure(constraints)\n        layout(\n            width = placeable.width,\n            height = placeable.height,\n            rulers = {\n                // use provides instead of provideRelative cause we will place relative\n                // in the badge code\n                BadgeEndRuler provides coordinates.size.width.toFloat()\n                BadgeTopRuler provides 0f\n            },\n        ) {\n            placeable.place(0, 0)\n        }\n    }\n\ninternal object NavigationRailVerticalItemTokens {\n    val ActiveIndicatorHeight = 32.0.dp\n    val ActiveIndicatorWidth = 56.0.dp\n    val LabelTextFont @Composable get() = MaterialTheme.typography.labelMedium\n}\n\ninternal object NavigationRailBaselineItemTokens {\n    val ActiveIndicatorShape @Composable get() = AutoCornersShape(16.dp)\n    val IconSize = 24.0.dp\n}\n\ninternal object NavigationRailCollapsedTokens {\n    val NarrowContainerWidth = 80.0.dp\n}\n\ninternal class MappedInteractionSource(\n    underlyingInteractionSource: InteractionSource,\n    private val calculateDelta: () -> Offset,\n) : InteractionSource {\n    private val mappedPresses = mutableMapOf<PressInteraction.Press, PressInteraction.Press>()\n\n    override val interactions =\n        underlyingInteractionSource.interactions.map { interaction ->\n            when (interaction) {\n                is PressInteraction.Press -> {\n                    val mappedPress = mapPress(interaction)\n                    mappedPresses[interaction] = mappedPress\n                    mappedPress\n                }\n\n                is PressInteraction.Cancel -> {\n                    val mappedPress = mappedPresses.remove(interaction.press)\n                    if (mappedPress == null) {\n                        interaction\n                    } else {\n                        PressInteraction.Cancel(mappedPress)\n                    }\n                }\n\n                is PressInteraction.Release -> {\n                    val mappedPress = mappedPresses.remove(interaction.press)\n                    if (mappedPress == null) {\n                        interaction\n                    } else {\n                        PressInteraction.Release(mappedPress)\n                    }\n                }\n\n                else -> interaction\n            }\n        }\n\n    private fun mapPress(press: PressInteraction.Press): PressInteraction.Press =\n        PressInteraction.Press(press.pressPosition - calculateDelta())\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedRadioButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.material3.RadioButton\nimport androidx.compose.material3.RadioButtonColors\nimport androidx.compose.material3.RadioButtonDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalHapticFeedback\n\n@Composable\nfun EnhancedRadioButton(\n    selected: Boolean,\n    onClick: (() -> Unit)?,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: RadioButtonColors = RadioButtonDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null\n) {\n    val haptics = LocalHapticFeedback.current\n    RadioButton(\n        selected = selected,\n        onClick = if (onClick != null) {\n            {\n                haptics.longPress()\n                onClick()\n            }\n        } else null,\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        interactionSource = interactionSource\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedRangeSliderItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.RichTooltip\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TooltipAnchorPosition\nimport androidx.compose.material3.TooltipBox\nimport androidx.compose.material3.TooltipDefaults\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.material3.rememberTooltipState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueText\nimport kotlinx.collections.immutable.ImmutableMap\nimport kotlinx.collections.immutable.persistentMapOf\nimport kotlinx.coroutines.launch\n\n@Composable\nfun EnhancedRangeSliderItem(\n    value: ClosedFloatingPointRange<Float>,\n    title: String,\n    modifier: Modifier = Modifier,\n    sliderModifier: Modifier = Modifier.padding(horizontal = 6.dp, vertical = 6.dp),\n    icon: ImageVector? = null,\n    valueRange: ClosedFloatingPointRange<Float>,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    onValueChangeFinished: ((ClosedFloatingPointRange<Float>) -> Unit)? = null,\n    steps: Int = 0,\n    topContentPadding: Dp = 8.dp,\n    valueSuffix: String = \"\",\n    internalStateTransformation: (ClosedFloatingPointRange<Float>) -> ClosedFloatingPointRange<Float> = { it },\n    visible: Boolean = true,\n    color: Color = Color.Unspecified,\n    contentColor: Color? = null,\n    shape: Shape = ShapeDefaults.default,\n    valueTextTapEnabled: Boolean = true,\n    behaveAsContainer: Boolean = true,\n    enabled: Boolean = true,\n    titleHorizontalPadding: Dp = if (behaveAsContainer) 16.dp\n    else 6.dp,\n    valuesPreviewMapping: ImmutableMap<Float, String> = remember { persistentMapOf() },\n    additionalContent: (@Composable () -> Unit)? = null,\n) {\n    val internalColor = contentColor\n        ?: if (color == MaterialTheme.colorScheme.surfaceContainer) {\n            contentColorFor(backgroundColor = MaterialTheme.colorScheme.surfaceVariant)\n        } else contentColorFor(backgroundColor = color)\n\n    var showStartValueDialog by rememberSaveable { mutableStateOf(false) }\n    var showEndValueDialog by rememberSaveable { mutableStateOf(false) }\n    val internalState = remember(value) { mutableStateOf(internalStateTransformation(value)) }\n\n    val isCompactLayout = LocalSettingsState.current.isCompactSelectorsLayout\n\n    val tooltipState = rememberTooltipState()\n    val scope = rememberCoroutineScope()\n\n    AnimatedVisibility(visible = visible) {\n        LocalContentColor.ProvidesValue(internalColor) {\n            Column(\n                modifier = modifier\n                    .then(\n                        if (behaveAsContainer) {\n                            Modifier.container(\n                                shape = shape,\n                                color = color\n                            )\n                        } else Modifier\n                    )\n                    .alpha(\n                        animateFloatAsState(if (enabled) 1f else 0.5f).value\n                    )\n                    .animateContentSizeNoClip()\n                    .then(\n                        if (isCompactLayout && icon != null) {\n                            Modifier.pointerInput(Unit) {\n                                detectTapGestures(\n                                    onLongPress = {\n                                        scope.launch {\n                                            tooltipState.show()\n                                        }\n                                    }\n                                )\n                            }\n                        } else Modifier\n                    ),\n                verticalArrangement = Arrangement.Center,\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                val slider = @Composable {\n                    AnimatedContent(\n                        targetState = Pair(\n                            valueRange,\n                            steps\n                        )\n                    ) { (valueRange, steps) ->\n                        EnhancedRangeSlider(\n                            modifier = if (isCompactLayout) {\n                                Modifier.padding(\n                                    top = topContentPadding,\n                                    start = 12.dp,\n                                    end = 12.dp\n                                )\n                            } else {\n                                sliderModifier\n                            },\n                            enabled = enabled,\n                            value = internalState.value,\n                            onValueChange = {\n                                internalState.value = internalStateTransformation(it)\n                                onValueChange(it)\n                            },\n                            onValueChangeFinished = onValueChangeFinished?.let {\n                                {\n                                    it(internalState.value)\n                                }\n                            },\n                            valueRange = valueRange,\n                            steps = steps\n                        )\n                    }\n                }\n                AnimatedContent(\n                    targetState = isCompactLayout,\n                    transitionSpec = { fadeIn() + expandVertically() togetherWith fadeOut() + shrinkVertically() }\n                ) { isCompactLayout ->\n                    Column {\n                        if (isCompactLayout) {\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically,\n                                modifier = Modifier.padding(bottom = 8.dp)\n                            ) {\n                                AnimatedContent(icon) { icon ->\n                                    if (icon != null) {\n                                        TooltipBox(\n                                            positionProvider = TooltipDefaults.rememberTooltipPositionProvider(\n                                                TooltipAnchorPosition.Above\n                                            ),\n                                            tooltip = {\n                                                RichTooltip(\n                                                    colors = TooltipDefaults.richTooltipColors(\n                                                        containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                                        contentColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(\n                                                            0.5f\n                                                        ),\n                                                        titleContentColor = MaterialTheme.colorScheme.onTertiaryContainer\n                                                    ),\n                                                    title = { Text(title) },\n                                                    text = {\n                                                        val trimmedStart =\n                                                            internalState.value.start.toString()\n                                                                .trimTrailingZero()\n                                                        val trimmedEnd =\n                                                            internalState.value.endInclusive.toString()\n                                                                .trimTrailingZero()\n                                                        val startPart =\n                                                            valuesPreviewMapping[internalState.value.start]\n                                                                ?: trimmedStart\n                                                        val endPart =\n                                                            valuesPreviewMapping[internalState.value.endInclusive]\n                                                                ?: trimmedEnd\n                                                        Text(\n                                                            \"$startPart..$endPart $valueSuffix\"\n                                                        )\n                                                    }\n                                                )\n                                            },\n                                            state = tooltipState,\n                                            content = {\n                                                IconShapeContainer(\n                                                    content = {\n                                                        Icon(\n                                                            imageVector = icon,\n                                                            contentDescription = null\n                                                        )\n                                                    },\n                                                    modifier = Modifier\n                                                        .padding(\n                                                            top = topContentPadding,\n                                                            start = 12.dp\n                                                        )\n                                                        .clip(\n                                                            LocalSettingsState.current.iconShape?.shape\n                                                                ?: ShapeDefaults.circle\n                                                        )\n                                                        .hapticsCombinedClickable(\n                                                            onLongClick = {\n                                                                scope.launch { tooltipState.show() }\n                                                            },\n                                                            onClick = {\n                                                                scope.launch { tooltipState.show() }\n                                                            }\n                                                        )\n                                                )\n                                            }\n                                        )\n                                    }\n                                }\n                                AnimatedVisibility(icon == null) {\n                                    Text(\n                                        text = title,\n                                        modifier = Modifier\n                                            .padding(\n                                                top = topContentPadding,\n                                                start = 12.dp\n                                            )\n                                            .widthIn(max = 100.dp),\n                                        style = MaterialTheme.typography.bodyMedium,\n                                        lineHeight = 16.sp\n                                    )\n                                }\n                                Row(\n                                    modifier = Modifier.weight(1f)\n                                ) {\n                                    slider()\n                                }\n                                Column(\n                                    horizontalAlignment = Alignment.CenterHorizontally,\n                                    modifier = Modifier.padding(\n                                        top = topContentPadding,\n                                        end = 8.dp\n                                    )\n                                ) {\n                                    ValueText(\n                                        enabled = valueTextTapEnabled && enabled,\n                                        value = internalStateTransformation(internalState.value).start,\n                                        valueSuffix = valueSuffix,\n                                        customText = valuesPreviewMapping[internalState.value.start],\n                                        modifier = Modifier.width(\n                                            if (valuesPreviewMapping.isNotEmpty()) 108.dp\n                                            else 72.dp\n                                        ),\n                                        onClick = {\n                                            showStartValueDialog = true\n                                        }\n                                    )\n                                    Text(\"··\")\n                                    ValueText(\n                                        enabled = valueTextTapEnabled && enabled,\n                                        value = internalStateTransformation(internalState.value).endInclusive,\n                                        valueSuffix = valueSuffix,\n                                        customText = valuesPreviewMapping[internalState.value.endInclusive],\n                                        modifier = Modifier.width(\n                                            if (valuesPreviewMapping.isNotEmpty()) 108.dp\n                                            else 72.dp\n                                        ),\n                                        onClick = {\n                                            showEndValueDialog = true\n                                        }\n                                    )\n                                }\n                            }\n                        } else {\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically,\n                                modifier = Modifier.padding(bottom = 8.dp)\n                            ) {\n                                AnimatedContent(icon) { icon ->\n                                    if (icon != null) {\n                                        IconShapeContainer(\n                                            content = {\n                                                Icon(\n                                                    imageVector = icon,\n                                                    contentDescription = null\n                                                )\n                                            },\n                                            modifier = Modifier.padding(\n                                                top = topContentPadding,\n                                                start = 12.dp\n                                            )\n                                        )\n                                    }\n                                }\n                                Text(\n                                    text = title,\n                                    modifier = Modifier\n                                        .padding(\n                                            top = topContentPadding,\n                                            end = titleHorizontalPadding,\n                                            start = titleHorizontalPadding\n                                        )\n                                        .weight(1f),\n                                    lineHeight = 18.sp,\n                                    fontWeight = if (behaveAsContainer) {\n                                        FontWeight.Medium\n                                    } else FontWeight.Normal\n                                )\n                                Row(\n                                    verticalAlignment = Alignment.CenterVertically,\n                                    modifier = Modifier\n                                        .height(IntrinsicSize.Max)\n                                        .padding(\n                                            top = topContentPadding,\n                                            end = 14.dp\n                                        )\n                                ) {\n                                    ValueText(\n                                        enabled = valueTextTapEnabled && enabled,\n                                        value = internalStateTransformation(internalState.value).start,\n                                        customText = valuesPreviewMapping[internalState.value.start],\n                                        valueSuffix = valueSuffix,\n                                        modifier = Modifier.fillMaxHeight(),\n                                        onClick = {\n                                            showStartValueDialog = true\n                                        }\n                                    )\n                                    Text(\"··\")\n                                    ValueText(\n                                        enabled = valueTextTapEnabled && enabled,\n                                        value = internalStateTransformation(internalState.value).endInclusive,\n                                        customText = valuesPreviewMapping[internalState.value.endInclusive],\n                                        valueSuffix = valueSuffix,\n                                        modifier = Modifier.fillMaxHeight(),\n                                        onClick = {\n                                            showEndValueDialog = true\n                                        }\n                                    )\n                                }\n\n                            }\n                            slider()\n                        }\n                    }\n                }\n                additionalContent?.invoke()\n            }\n        }\n    }\n\n    ValueDialog(\n        roundTo = null,\n        valueRange = valueRange.start..internalState.value.endInclusive,\n        valueState = internalState.value.start.toString(),\n        expanded = visible && showStartValueDialog,\n        onDismiss = { showStartValueDialog = false },\n        onValueUpdate = {\n            val range =\n                it.coerceAtMost(internalState.value.endInclusive)..internalState.value.endInclusive\n\n            onValueChange(range)\n            onValueChangeFinished?.invoke(range)\n        }\n    )\n    ValueDialog(\n        roundTo = null,\n        valueRange = internalState.value.start..valueRange.endInclusive,\n        valueState = internalState.value.endInclusive.toString(),\n        expanded = visible && showEndValueDialog,\n        onDismiss = { showEndValueDialog = false },\n        onValueUpdate = {\n            val range = internalState.value.start..it.coerceAtLeast(internalState.value.start)\n\n            onValueChange(range)\n            onValueChangeFinished?.invoke(range)\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedSlider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SliderColors\nimport androidx.compose.material3.SliderDefaults\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.FancyRangeSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.FancySlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.HyperOSRangeSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.HyperOSSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.M2RangeSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.M2Slider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.M3RangeSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.M3Slider\n\n@Composable\nfun EnhancedSlider(\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    modifier: Modifier = Modifier,\n    onValueChangeFinished: (() -> Unit)? = null,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int = 0,\n    enabled: Boolean = true,\n    colors: SliderColors? = null,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    drawContainer: Boolean = true,\n    isAnimated: Boolean = true\n) {\n    val settingsState = LocalSettingsState.current\n    val sliderType = settingsState.sliderType\n\n    val realColors = colors ?: when (sliderType) {\n        SliderType.Fancy -> {\n            SliderDefaults.colors(\n                activeTickColor = MaterialTheme.colorScheme.inverseSurface,\n                inactiveTickColor = MaterialTheme.colorScheme.surface,\n                activeTrackColor = MaterialTheme.colorScheme.primaryContainer,\n                inactiveTrackColor = SwitchDefaults.colors().disabledCheckedTrackColor,\n                disabledThumbColor = SliderDefaults.colors().disabledThumbColor,\n                disabledActiveTrackColor = SliderDefaults.colors().disabledActiveTrackColor,\n                thumbColor = MaterialTheme.colorScheme.onPrimaryContainer\n            )\n        }\n\n        SliderType.MaterialYou -> SliderDefaults.colors()\n        SliderType.Material -> SliderDefaults.colors()\n        SliderType.HyperOS -> SliderDefaults.colors()\n    }\n\n    if (steps != 0) {\n        var compositions by remember {\n            mutableIntStateOf(0)\n        }\n        val haptics = LocalHapticFeedback.current\n        val updatedValue by rememberUpdatedState(newValue = value)\n\n        LaunchedEffect(updatedValue) {\n            if (compositions > 0) haptics.press()\n\n            compositions++\n        }\n    }\n\n    val value = if (isAnimated) {\n        animateFloatAsState(\n            targetValue = value,\n            animationSpec = tween(100)\n        ).value\n    } else {\n        value\n    }\n\n    when (sliderType) {\n        SliderType.Fancy -> {\n            FancySlider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                interactionSource = interactionSource,\n                thumbShape = if (settingsState.shapesType is ShapeType.Cut) {\n                    AutoCircleShape(\n                        shapesType = settingsState.shapesType.copy(\n                            strength = settingsState.shapesType.strength.coerceAtLeast(0.5f)\n                        )\n                    )\n                } else {\n                    MaterialStarShape\n                },\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n\n        SliderType.MaterialYou -> {\n            M3Slider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                interactionSource = interactionSource,\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n\n        SliderType.Material -> {\n            M2Slider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                interactionSource = interactionSource,\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n\n        SliderType.HyperOS -> {\n            HyperOSSlider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                interactionSource = interactionSource,\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n    }\n}\n\n@Composable\nfun EnhancedRangeSlider(\n    value: ClosedFloatingPointRange<Float>,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    modifier: Modifier = Modifier,\n    onValueChangeFinished: (() -> Unit)? = null,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int = 0,\n    enabled: Boolean = true,\n    colors: SliderColors? = null,\n    startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    drawContainer: Boolean = true\n) {\n    val settingsState = LocalSettingsState.current\n    val sliderType = settingsState.sliderType\n\n    val realColors = colors ?: when (sliderType) {\n        SliderType.Fancy -> {\n            SliderDefaults.colors(\n                activeTickColor = MaterialTheme.colorScheme.inverseSurface,\n                inactiveTickColor = MaterialTheme.colorScheme.surface,\n                activeTrackColor = MaterialTheme.colorScheme.primaryContainer,\n                inactiveTrackColor = SwitchDefaults.colors().disabledCheckedTrackColor,\n                disabledThumbColor = SliderDefaults.colors().disabledThumbColor,\n                disabledActiveTrackColor = SliderDefaults.colors().disabledActiveTrackColor,\n                thumbColor = MaterialTheme.colorScheme.onPrimaryContainer\n            )\n        }\n\n        SliderType.MaterialYou -> SliderDefaults.colors()\n        SliderType.Material -> SliderDefaults.colors()\n        SliderType.HyperOS -> SliderDefaults.colors()\n    }\n\n    if (steps != 0) {\n        var compositions by remember {\n            mutableIntStateOf(0)\n        }\n        val haptics = LocalHapticFeedback.current\n        val updatedValue by rememberUpdatedState(newValue = value)\n\n        LaunchedEffect(updatedValue) {\n            if (compositions > 0) haptics.press()\n\n            compositions++\n        }\n    }\n\n    when (sliderType) {\n        SliderType.Fancy -> {\n            FancyRangeSlider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                startInteractionSource = startInteractionSource,\n                endInteractionSource = endInteractionSource,\n                thumbShape = if (settingsState.shapesType is ShapeType.Cut) {\n                    AutoCircleShape(\n                        shapesType = settingsState.shapesType.copy(\n                            strength = settingsState.shapesType.strength.coerceAtLeast(0.5f)\n                        )\n                    )\n                } else {\n                    MaterialStarShape\n                },\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n\n        SliderType.MaterialYou -> {\n            M3RangeSlider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                startInteractionSource = startInteractionSource,\n                endInteractionSource = endInteractionSource,\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n\n        SliderType.Material -> {\n            M2RangeSlider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                startInteractionSource = startInteractionSource,\n                endInteractionSource = endInteractionSource,\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n\n        SliderType.HyperOS -> {\n            HyperOSRangeSlider(\n                value = value,\n                enabled = enabled,\n                colors = realColors,\n                startInteractionSource = startInteractionSource,\n                endInteractionSource = endInteractionSource,\n                modifier = modifier,\n                onValueChange = onValueChange,\n                onValueChangeFinished = onValueChangeFinished,\n                valueRange = valueRange,\n                steps = steps,\n                drawContainer = drawContainer\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedSliderItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.RichTooltip\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TooltipAnchorPosition\nimport androidx.compose.material3.TooltipBox\nimport androidx.compose.material3.TooltipDefaults\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.material3.rememberTooltipState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueText\nimport kotlinx.collections.immutable.ImmutableMap\nimport kotlinx.collections.immutable.persistentMapOf\nimport kotlinx.coroutines.launch\n\n@Composable\nfun EnhancedSliderItem(\n    value: Number,\n    title: String,\n    modifier: Modifier = Modifier,\n    sliderModifier: Modifier = Modifier.padding(horizontal = 6.dp, vertical = 6.dp),\n    icon: ImageVector? = null,\n    valueRange: ClosedFloatingPointRange<Float>,\n    onValueChange: (Float) -> Unit,\n    onValueChangeFinished: ((Float) -> Unit)? = null,\n    steps: Int = 0,\n    topContentPadding: Dp = 8.dp,\n    valueSuffix: String = \"\",\n    internalStateTransformation: (Float) -> Number = { it },\n    visible: Boolean = true,\n    containerColor: Color = Color.Unspecified,\n    contentColor: Color? = null,\n    shape: Shape = ShapeDefaults.default,\n    valueTextTapEnabled: Boolean = true,\n    behaveAsContainer: Boolean = true,\n    enabled: Boolean = true,\n    titleHorizontalPadding: Dp = if (behaveAsContainer) 16.dp\n    else 6.dp,\n    valuesPreviewMapping: ImmutableMap<Float, String> = remember { persistentMapOf() },\n    titleFontWeight: FontWeight = if (behaveAsContainer) {\n        FontWeight.Medium\n    } else FontWeight.Normal,\n    isAnimated: Boolean = true,\n    canInputValue: Boolean = true,\n    additionalContent: (@Composable () -> Unit)? = null\n) {\n    val internalColor = contentColor\n        ?: if (containerColor == MaterialTheme.colorScheme.surfaceContainer) {\n            contentColorFor(backgroundColor = MaterialTheme.colorScheme.surfaceVariant)\n        } else contentColorFor(backgroundColor = containerColor)\n\n    var showValueDialog by rememberSaveable(canInputValue) { mutableStateOf(false) }\n    val internalState = remember(value) { mutableStateOf(value) }\n\n    val isCompactLayout = LocalSettingsState.current.isCompactSelectorsLayout\n\n    val tooltipState = rememberTooltipState()\n    val scope = rememberCoroutineScope()\n\n    AnimatedVisibility(visible = visible) {\n        LocalContentColor.ProvidesValue(internalColor) {\n            Column(\n                modifier = modifier\n                    .then(\n                        if (behaveAsContainer) {\n                            Modifier.container(\n                                shape = shape,\n                                color = containerColor\n                            )\n                        } else Modifier\n                    )\n                    .alpha(\n                        animateFloatAsState(if (enabled) 1f else 0.5f).value\n                    )\n                    .animateContentSizeNoClip()\n                    .then(\n                        if (isCompactLayout && icon != null) {\n                            Modifier.pointerInput(Unit) {\n                                detectTapGestures(\n                                    onLongPress = {\n                                        scope.launch {\n                                            tooltipState.show()\n                                        }\n                                    }\n                                )\n                            }\n                        } else Modifier\n                    ),\n                verticalArrangement = Arrangement.Center,\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                val slider = @Composable {\n                    val nonAnimated: @Composable (ClosedFloatingPointRange<Float>, Int) -> Unit =\n                        { valueRange, steps ->\n                            EnhancedSlider(\n                                modifier = if (isCompactLayout) {\n                                    Modifier.padding(\n                                        top = topContentPadding,\n                                        start = 12.dp,\n                                        end = 12.dp\n                                    )\n                                } else {\n                                    sliderModifier\n                                },\n                                enabled = enabled,\n                                value = internalState.value.toFloat(),\n                                onValueChange = {\n                                    internalState.value = internalStateTransformation(it)\n                                    onValueChange(it)\n                                },\n                                onValueChangeFinished = onValueChangeFinished?.let {\n                                    {\n                                        it(internalState.value.toFloat())\n                                    }\n                                },\n                                valueRange = valueRange,\n                                steps = steps,\n                                isAnimated = isAnimated\n                            )\n                        }\n\n                    if (isAnimated) {\n                        AnimatedContent(\n                            targetState = valueRange to steps\n                        ) { (valueRange, steps) ->\n                            nonAnimated(valueRange, steps)\n                        }\n                    } else {\n                        nonAnimated(valueRange, steps)\n                    }\n                }\n                AnimatedContent(\n                    targetState = isCompactLayout,\n                    transitionSpec = { fadeIn() + expandVertically() togetherWith fadeOut() + shrinkVertically() }\n                ) { isCompactLayout ->\n                    Column {\n                        if (isCompactLayout) {\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically,\n                                modifier = Modifier.padding(bottom = 8.dp)\n                            ) {\n                                AnimatedContent(icon) { icon ->\n                                    if (icon != null) {\n                                        TooltipBox(\n                                            positionProvider = TooltipDefaults.rememberTooltipPositionProvider(\n                                                TooltipAnchorPosition.Above\n                                            ),\n                                            tooltip = {\n                                                RichTooltip(\n                                                    colors = TooltipDefaults.richTooltipColors(\n                                                        containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                                        contentColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(\n                                                            0.5f\n                                                        ),\n                                                        titleContentColor = MaterialTheme.colorScheme.onTertiaryContainer\n                                                    ),\n                                                    title = { Text(title) },\n                                                    text = {\n                                                        val trimmed =\n                                                            internalState.value.toString()\n                                                                .trimTrailingZero()\n                                                        Text(\n                                                            valuesPreviewMapping[internalState.value.toFloat()]\n                                                                ?: \"$trimmed$valueSuffix\"\n                                                        )\n                                                    }\n                                                )\n                                            },\n                                            state = tooltipState,\n                                            content = {\n                                                IconShapeContainer(\n                                                    content = {\n                                                        Icon(\n                                                            imageVector = icon,\n                                                            contentDescription = null\n                                                        )\n                                                    },\n                                                    modifier = Modifier\n                                                        .padding(\n                                                            top = topContentPadding,\n                                                            start = 12.dp\n                                                        )\n                                                        .clip(\n                                                            LocalSettingsState.current.iconShape?.shape\n                                                                ?: ShapeDefaults.circle\n                                                        )\n                                                        .hapticsCombinedClickable(\n                                                            onLongClick = {\n                                                                scope.launch { tooltipState.show() }\n                                                            },\n                                                            onClick = {\n                                                                scope.launch { tooltipState.show() }\n                                                            }\n                                                        )\n                                                )\n                                            }\n                                        )\n                                    }\n                                }\n                                AnimatedVisibility(icon == null) {\n                                    Text(\n                                        text = title,\n                                        modifier = Modifier\n                                            .padding(\n                                                top = topContentPadding,\n                                                start = 12.dp\n                                            )\n                                            .widthIn(max = 100.dp),\n                                        style = MaterialTheme.typography.bodyMedium,\n                                        lineHeight = 16.sp\n                                    )\n                                }\n                                Row(\n                                    modifier = Modifier.weight(1f)\n                                ) {\n                                    slider()\n                                }\n                                ValueText(\n                                    enabled = valueTextTapEnabled && enabled,\n                                    value = internalStateTransformation(internalState.value.toFloat()),\n                                    valueSuffix = valueSuffix,\n                                    customText = valuesPreviewMapping[internalState.value.toFloat()],\n                                    modifier = Modifier\n                                        .width(108.dp)\n                                        .padding(\n                                            top = topContentPadding,\n                                            end = 8.dp\n                                        ),\n                                    onClick = if (canInputValue) {\n                                        { showValueDialog = true }\n                                    } else null\n                                )\n                            }\n                        } else {\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically,\n                                modifier = Modifier.padding(bottom = 8.dp)\n                            ) {\n                                AnimatedContent(icon) { icon ->\n                                    if (icon != null) {\n                                        IconShapeContainer(\n                                            content = {\n                                                Icon(\n                                                    imageVector = icon,\n                                                    contentDescription = null\n                                                )\n                                            },\n                                            modifier = Modifier.padding(\n                                                top = topContentPadding,\n                                                start = 12.dp\n                                            )\n                                        )\n                                    }\n                                }\n                                Text(\n                                    text = title,\n                                    modifier = Modifier\n                                        .padding(\n                                            top = topContentPadding,\n                                            end = titleHorizontalPadding,\n                                            start = titleHorizontalPadding\n                                        )\n                                        .weight(1f),\n                                    lineHeight = 18.sp,\n                                    fontWeight = titleFontWeight\n                                )\n                                ValueText(\n                                    enabled = valueTextTapEnabled && enabled,\n                                    value = internalStateTransformation(internalState.value.toFloat()),\n                                    customText = valuesPreviewMapping[internalState.value.toFloat()],\n                                    valueSuffix = valueSuffix,\n                                    modifier = Modifier.padding(\n                                        top = topContentPadding,\n                                        end = 14.dp\n                                    ),\n                                    onClick = if (canInputValue) {\n                                        { showValueDialog = true }\n                                    } else null\n                                )\n                            }\n                            slider()\n                        }\n                    }\n                }\n                additionalContent?.invoke()\n            }\n        }\n    }\n    ValueDialog(\n        roundTo = null,\n        valueRange = valueRange,\n        valueState = internalStateTransformation(value.toFloat()).toString(),\n        expanded = visible && showValueDialog,\n        onDismiss = { showValueDialog = false },\n        onValueUpdate = {\n            onValueChange(it)\n            onValueChangeFinished?.invoke(it)\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedSwitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.minimumInteractiveComponentSize\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Switch\nimport androidx.compose.material3.SwitchColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.CupertinoSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.CupertinoSwitchDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.FluentSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.HyperOSSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.LiquidGlassSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.M3Switch\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.OneUISwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.PixelSwitch\n\n@Composable\nfun EnhancedSwitch(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    thumbIcon: ImageVector? = null,\n    enabled: Boolean = true,\n    colors: SwitchColors? = null,\n    interactionSource: MutableInteractionSource? = null,\n    colorUnderSwitch: Color = Color.Unspecified\n) {\n    val switchColors = colors ?: SwitchDefaults.colors(\n        disabledUncheckedThumbColor = MaterialTheme.colorScheme.onSurface\n            .copy(alpha = 0.12f)\n            .compositeOver(MaterialTheme.colorScheme.surface)\n    )\n    val settingsState = LocalSettingsState.current\n    val haptics = LocalHapticFeedback.current\n    val focus = LocalFocusManager.current\n\n    LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n        val switchModifier = modifier\n            .minimumInteractiveComponentSize()\n            .container(\n                shape = ShapeDefaults.circle,\n                resultPadding = 0.dp,\n                autoShadowElevation = animateDpAsState(\n                    if (settingsState.drawSwitchShadows) 1.dp\n                    else 0.dp\n                ).value,\n                borderColor = Color.Transparent,\n                isShadowClip = true,\n                isStandaloneContainer = false,\n                color = Color.Transparent\n            )\n        val switchOnCheckedChange: ((Boolean) -> Unit)? = onCheckedChange?.let {\n            { boolean ->\n                onCheckedChange(boolean)\n                haptics.longPress()\n                focus.clearFocus()\n            }\n        }\n        val thumbContent: (@Composable () -> Unit)? = thumbIcon?.let {\n            {\n                AnimatedContent(thumbIcon) { thumbIcon ->\n                    Icon(\n                        imageVector = thumbIcon,\n                        contentDescription = null,\n                        modifier = Modifier.size(SwitchDefaults.IconSize)\n                    )\n                }\n            }\n        }\n\n        AnimatedContent(\n            targetState = settingsState.switchType,\n            transitionSpec = {\n                fadeIn() togetherWith fadeOut() using SizeTransform(false)\n            }\n        ) { switchType ->\n            when (switchType) {\n                is SwitchType.MaterialYou -> {\n                    M3Switch(\n                        modifier = modifier,\n                        internalModifier = switchModifier,\n                        colors = switchColors,\n                        checked = checked,\n                        enabled = enabled,\n                        onCheckedChange = switchOnCheckedChange,\n                        interactionSource = interactionSource\n                    )\n                }\n\n                is SwitchType.Compose -> {\n                    Switch(\n                        modifier = switchModifier,\n                        colors = switchColors,\n                        checked = checked,\n                        enabled = enabled,\n                        onCheckedChange = switchOnCheckedChange,\n                        interactionSource = interactionSource,\n                        thumbContent = thumbContent\n                    )\n                }\n\n                is SwitchType.Pixel -> {\n                    PixelSwitch(\n                        modifier = switchModifier,\n                        colors = switchColors,\n                        checked = checked,\n                        enabled = enabled,\n                        onCheckedChange = switchOnCheckedChange,\n                        interactionSource = interactionSource\n                    )\n                }\n\n                is SwitchType.Fluent -> {\n                    FluentSwitch(\n                        modifier = switchModifier,\n                        colors = switchColors,\n                        checked = checked,\n                        enabled = enabled,\n                        onCheckedChange = switchOnCheckedChange,\n                        interactionSource = interactionSource\n                    )\n                }\n\n                is SwitchType.Cupertino -> {\n                    CupertinoSwitch(\n                        checked = checked,\n                        onCheckedChange = switchOnCheckedChange,\n                        modifier = switchModifier,\n                        enabled = enabled,\n                        interactionSource = interactionSource,\n                        colors = CupertinoSwitchDefaults.colors()\n                    )\n                }\n\n                is SwitchType.LiquidGlass -> {\n                    LiquidGlassSwitch(\n                        checked = checked,\n                        onCheckedChange = switchOnCheckedChange,\n                        internalModifier = switchModifier,\n                        modifier = modifier,\n                        enabled = enabled,\n                        interactionSource = interactionSource,\n                        colors = CupertinoSwitchDefaults.colors(),\n                        backgroundColor = colorUnderSwitch\n                    )\n                }\n\n                is SwitchType.HyperOS -> {\n                    HyperOSSwitch(\n                        modifier = switchModifier,\n                        colors = switchColors.copy(\n                            uncheckedTrackColor = MaterialTheme.colorScheme.surfaceContainerHigh\n                        ),\n                        checked = checked,\n                        enabled = enabled,\n                        onCheckedChange = switchOnCheckedChange,\n                        interactionSource = interactionSource\n                    )\n                }\n\n                is SwitchType.OneUI -> {\n                    OneUISwitch(\n                        modifier = modifier\n                            .minimumInteractiveComponentSize(),\n                        colors = switchColors.copy(\n                            uncheckedTrackColor = MaterialTheme.colorScheme.surfaceContainerLow\n                        ),\n                        checked = checked,\n                        enabled = enabled,\n                        onCheckedChange = switchOnCheckedChange,\n                        interactionSource = interactionSource\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedToggleButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.ToggleButtonColors\nimport androidx.compose.material3.ToggleButtonDefaults\nimport androidx.compose.material3.ToggleButtonShapes\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun EnhancedToggleButton(\n    checked: Boolean,\n    onCheckedChange: (Boolean) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shapes: ToggleButtonShapes = ToggleButtonDefaults.shapesFor(ButtonDefaults.MinHeight),\n    colors: ToggleButtonColors = ToggleButtonDefaults.toggleButtonColors(),\n    elevation: Dp = 0.dp,\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.contentPaddingFor(ButtonDefaults.MinHeight),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit\n) {\n    val realInteractionSource = interactionSource ?: remember { MutableInteractionSource() }\n\n    val containerColor = colors.containerColor(enabled, checked)\n    val contentColor = colors.contentColor(enabled, checked)\n    val buttonShape = shapeByInteraction(\n        shape = if (checked) shapes.checkedShape else shapes.shape,\n        pressedShape = shapes.pressedShape,\n        interactionSource = realInteractionSource\n    )\n\n    val haptics = LocalHapticFeedback.current\n    val focus = LocalFocusManager.current\n\n    val scope = rememberCoroutineScope()\n\n    LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n        Surface(\n            checked = checked,\n            onCheckedChange = {\n                haptics.longPress()\n                onCheckedChange(it)\n\n                scope.launch {\n                    delay(200)\n                    focus.clearFocus()\n                }\n            },\n            modifier = modifier.semantics { role = Role.Checkbox },\n            enabled = enabled,\n            shape = buttonShape,\n            color = containerColor,\n            contentColor = contentColor,\n            shadowElevation = elevation,\n            border = border,\n            interactionSource = realInteractionSource\n        ) {\n            val mergedStyle = LocalTextStyle.current.merge(MaterialTheme.typography.labelLarge)\n\n            CompositionLocalProvider(\n                LocalContentColor provides contentColor,\n                LocalTextStyle provides mergedStyle\n            ) {\n                Row(\n                    modifier = Modifier\n                        .defaultMinSize(minHeight = ToggleButtonDefaults.MinHeight)\n                        .padding(contentPadding),\n                    horizontalArrangement = Arrangement.Center,\n                    verticalAlignment = Alignment.CenterVertically,\n                    content = content\n                )\n            }\n        }\n    }\n}\n\n@Stable\nprivate fun ToggleButtonColors.containerColor(enabled: Boolean, checked: Boolean): Color {\n    return when {\n        enabled && checked -> checkedContainerColor\n        enabled && !checked -> containerColor\n        else -> disabledContainerColor\n    }\n}\n\n@Stable\nprivate fun ToggleButtonColors.contentColor(enabled: Boolean, checked: Boolean): Color {\n    return when {\n        enabled && checked -> checkedContentColor\n        enabled && !checked -> contentColor\n        else -> disabledContentColor\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/EnhancedTopAppBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.safeDrawing\nimport androidx.compose.material3.CenterAlignedTopAppBar\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.MediumTopAppBar\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarColors\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\n\n@Composable\nfun EnhancedTopAppBar(\n    title: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    navigationIcon: @Composable () -> Unit = {},\n    actions: @Composable RowScope.() -> Unit = {},\n    windowInsets: WindowInsets = EnhancedTopAppBarDefaults.windowInsets,\n    colors: TopAppBarColors = EnhancedTopAppBarDefaults.colors(),\n    scrollBehavior: TopAppBarScrollBehavior? = null,\n    type: EnhancedTopAppBarType = EnhancedTopAppBarType.Normal,\n    drawHorizontalStroke: Boolean = true\n) {\n    AnimatedContent(\n        targetState = type,\n        transitionSpec = { fadeIn() togetherWith fadeOut() }\n    ) {\n        when (it) {\n            EnhancedTopAppBarType.Center -> {\n                CenterAlignedTopAppBar(\n                    title = title,\n                    modifier = modifier.drawHorizontalStroke(\n                        enabled = drawHorizontalStroke\n                    ),\n                    navigationIcon = navigationIcon,\n                    actions = actions,\n                    windowInsets = windowInsets,\n                    colors = colors,\n                    scrollBehavior = scrollBehavior\n                )\n            }\n\n            EnhancedTopAppBarType.Normal -> {\n                TopAppBar(\n                    title = title,\n                    modifier = modifier.drawHorizontalStroke(\n                        enabled = drawHorizontalStroke\n                    ),\n                    navigationIcon = navigationIcon,\n                    actions = actions,\n                    windowInsets = windowInsets,\n                    colors = colors,\n                    scrollBehavior = scrollBehavior\n                )\n            }\n\n            EnhancedTopAppBarType.Medium -> {\n                MediumTopAppBar(\n                    title = title,\n                    modifier = modifier.drawHorizontalStroke(\n                        enabled = drawHorizontalStroke\n                    ),\n                    navigationIcon = navigationIcon,\n                    actions = actions,\n                    windowInsets = windowInsets,\n                    colors = colors,\n                    scrollBehavior = scrollBehavior\n                )\n            }\n\n            EnhancedTopAppBarType.Large -> {\n                LargeTopAppBar(\n                    title = title,\n                    modifier = modifier.drawHorizontalStroke(\n                        enabled = drawHorizontalStroke\n                    ),\n                    navigationIcon = navigationIcon,\n                    actions = actions,\n                    windowInsets = windowInsets,\n                    colors = colors,\n                    scrollBehavior = scrollBehavior\n                )\n            }\n        }\n    }\n}\n\nenum class EnhancedTopAppBarType {\n    Center, Normal, Medium, Large\n}\n\nobject EnhancedTopAppBarDefaults {\n\n    val windowInsets: WindowInsets\n        @Composable\n        get() = WindowInsets.safeDrawing\n            .only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top)\n\n    @Composable\n    fun colors(\n        containerColor: Color = MaterialTheme.colorScheme.surfaceContainer,\n        scrolledContainerColor: Color = Color.Unspecified,\n        navigationIconContentColor: Color = Color.Unspecified,\n        titleContentColor: Color = Color.Unspecified,\n        actionIconContentColor: Color = Color.Unspecified,\n    ): TopAppBarColors = TopAppBarDefaults.topAppBarColors(\n        containerColor = containerColor,\n        scrolledContainerColor = scrolledContainerColor,\n        navigationIconContentColor = navigationIconContentColor,\n        titleContentColor = titleContentColor,\n        actionIconContentColor = actionIconContentColor\n    )\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/enhanced/derivative/OnlyAllowedSliderItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.enhanced.derivative\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlinx.collections.immutable.toPersistentMap\nimport kotlin.math.roundToInt\n\n@Composable\nfun OnlyAllowedSliderItem(\n    label: String,\n    icon: ImageVector,\n    value: Int,\n    allowed: Collection<Int>,\n    maxAllowed: Int = Int.MAX_VALUE,\n    onValueChange: (Int) -> Unit,\n    valueSuffix: String = \" px\",\n    shape: Shape = ShapeDefaults.large,\n) {\n    val availableAllowed = allowed.filter { it < maxAllowed }\n    val effectiveAllowed = availableAllowed.ifEmpty { listOf(allowed.first()) }\n    val clampedValue = value.coerceAtMost(effectiveAllowed.last())\n    var index by remember(clampedValue, effectiveAllowed) {\n        mutableIntStateOf(effectiveAllowed.indexOf(clampedValue).coerceAtLeast(0))\n    }\n    LaunchedEffect(maxAllowed) {\n        if (value >= maxAllowed && effectiveAllowed.isNotEmpty()) {\n            onValueChange(effectiveAllowed.last())\n        }\n    }\n\n    EnhancedSliderItem(\n        value = index,\n        internalStateTransformation = { it.roundToInt() },\n        onValueChange = {\n            val newIdx = it.roundToInt().coerceIn(effectiveAllowed.indices)\n            if (newIdx != index) {\n                index = newIdx\n                onValueChange(effectiveAllowed[newIdx])\n            }\n        },\n        valueRange = 0f..(effectiveAllowed.lastIndex.toFloat().coerceAtLeast(0f)),\n        steps = (effectiveAllowed.size - 2).coerceAtLeast(0),\n        enabled = effectiveAllowed.size > 1,\n        title = label,\n        valuesPreviewMapping = remember(effectiveAllowed) {\n            buildMap {\n                effectiveAllowed.forEachIndexed { index, value ->\n                    put(index.toFloat(), \"${value}${valueSuffix}\")\n                }\n            }.toPersistentMap()\n        },\n        icon = icon,\n        isAnimated = false,\n        canInputValue = false,\n        shape = shape,\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/icon_shape/IconShapeContainer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.icon_shape\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.shapes.ArrowShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.BookmarkShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.PentagonShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SimpleHeartShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.IconShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerShape\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\nobject IconShapeDefaults {\n\n    val contentColor: Color\n        @Composable\n        get() {\n            val colorScheme = MaterialTheme.colorScheme\n            val localContainer = SafeLocalContainerColor\n            val localContent = LocalContentColor.current\n            val container = containerColor\n            val settingsState = LocalSettingsState.current\n\n            return remember(colorScheme, localContainer, localContent, container, settingsState) {\n                derivedStateOf {\n                    val containerLuma = container.compositeOver(localContainer).luminance()\n\n                    val isLight = containerLuma > 0.2f\n\n                    val baseColor = if (isLight) {\n                        Color.Black.blend(\n                            color = colorScheme.onPrimaryContainer,\n                            fraction = 0.35f\n                        )\n                    } else {\n                        Color.White.blend(\n                            color = colorScheme.primary,\n                            fraction = 0.35f\n                        )\n                    }\n\n                    if (settingsState.isAmoledMode && settingsState.isNightMode) {\n                        baseColor.blend(Color.Black)\n                    } else {\n                        baseColor\n                    }\n                }\n            }.value\n        }\n\n    val containerColor: Color\n        @Composable\n        get() = takeColorFromScheme {\n            if (it) primary.blend(primaryContainer).copy(0.2f)\n            else primaryContainer.blend(primary).copy(0.35f)\n        }\n\n}\n\n@Composable\nfun IconShapeContainer(\n    enabled: Boolean = true,\n    modifier: Modifier = Modifier,\n    iconShape: IconShape? = LocalSettingsState.current.iconShape,\n    contentColor: Color = LocalIconShapeContentColor.current\n        ?: IconShapeDefaults.contentColor,\n    containerColor: Color = LocalIconShapeContainerColor.current\n        ?: IconShapeDefaults.containerColor,\n    content: @Composable (Boolean) -> Unit = {}\n) {\n    CompositionLocalProvider(\n        values = arrayOf(\n            LocalContainerShape provides null,\n            LocalContainerColor provides null,\n            LocalContentColor provides if (enabled && contentColor.isSpecified && iconShape != null) {\n                contentColor\n            } else LocalContentColor.current\n        )\n    ) {\n        AnimatedContent(\n            targetState = remember(iconShape) {\n                derivedStateOf {\n                    iconShape?.takeOrElseFrom(IconShape.entries)\n                }\n            }.value,\n            modifier = modifier\n        ) { iconShapeAnimated ->\n            Box(\n                modifier = if (enabled && iconShapeAnimated != null) {\n                    Modifier.container(\n                        shape = iconShapeAnimated.shape,\n                        color = containerColor,\n                        autoShadowElevation = 0.65.dp,\n                        resultPadding = iconShapeAnimated.padding,\n                        composeColorOnTopOfBackground = false,\n                        isShadowClip = true\n                    )\n                } else Modifier,\n                contentAlignment = Alignment.Center\n            ) {\n                Box(\n                    modifier = if (enabled && iconShapeAnimated != null) {\n                        Modifier\n                            .size(iconShapeAnimated.iconSize)\n                            .offset(\n                                y = when (iconShapeAnimated.shape) {\n                                    PentagonShape -> 2.dp\n                                    BookmarkShape -> (-1).dp\n                                    SimpleHeartShape -> (-1.5).dp\n                                    ArrowShape -> 2.dp\n                                    else -> 0.dp\n                                }\n                            )\n                    } else Modifier\n                ) {\n                    content(iconShapeAnimated == null)\n                }\n            }\n        }\n    }\n}\n\nval LocalIconShapeContentColor = compositionLocalOf<Color?> { null }\nval LocalIconShapeContainerColor = compositionLocalOf<Color?> { null }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/AspectRatioSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CropFree\nimport androidx.compose.material.icons.outlined.DashboardCustomize\nimport androidx.compose.material.icons.outlined.Image\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.model.CropAspectRatio\nimport com.t8rin.cropper.util.createRectShape\nimport com.t8rin.cropper.widget.AspectRatioSelectionCard\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.utils.ifCasts\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport kotlin.math.abs\n\n@Composable\nfun AspectRatioSelector(\n    modifier: Modifier = Modifier,\n    selectedAspectRatio: DomainAspectRatio? = DomainAspectRatio.Free,\n    unselectedCardColor: Color = MaterialTheme.colorScheme.surfaceContainerLowest,\n    contentPadding: PaddingValues = PaddingValues(\n        start = 16.dp,\n        top = 4.dp,\n        bottom = 16.dp,\n        end = 16.dp + WindowInsets\n            .navigationBars\n            .asPaddingValues()\n            .calculateEndPadding(LocalLayoutDirection.current)\n    ),\n    title: @Composable ColumnScope.() -> Unit = {\n        Text(\n            text = stringResource(id = R.string.aspect_ratio),\n            modifier = Modifier\n                .padding(\n                    start = 8.dp,\n                    end = 8.dp,\n                    top = 16.dp,\n                    bottom = 8.dp\n                ),\n            fontWeight = FontWeight.Medium\n        )\n    },\n    enableFadingEdges: Boolean = true,\n    onAspectRatioChange: (DomainAspectRatio, AspectRatio) -> Unit,\n    color: Color = Color.Unspecified,\n    shape: Shape = ShapeDefaults.extraLarge,\n    aspectRatios: List<DomainAspectRatio> = aspectRatios()\n) {\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally,\n        modifier = modifier\n            .container(\n                color = color,\n                shape = shape,\n                resultPadding = 0.dp\n            )\n            .clearFocusOnTap()\n    ) {\n        title()\n        val listState = rememberLazyListState()\n        LazyRow(\n            state = listState,\n            horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally),\n            contentPadding = contentPadding,\n            verticalAlignment = Alignment.CenterVertically,\n            modifier = Modifier.fadingEdges(\n                scrollableState = listState,\n                enabled = enableFadingEdges\n            ),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            itemsIndexed(\n                items = aspectRatios,\n                key = { _, a ->\n                    a.toCropAspectRatio(\n                        original = \"0\",\n                        free = \"1\",\n                        custom = \"2\"\n                    ).title\n                }\n            ) { index, item ->\n                val selected = (item == selectedAspectRatio)\n                    .or(\n                        item is DomainAspectRatio.Custom && selectedAspectRatio is DomainAspectRatio.Custom\n                    )\n                val cropAspectRatio = item.toCropAspectRatio(\n                    original = stringResource(R.string.original),\n                    free = stringResource(R.string.free),\n                    custom = stringResource(R.string.custom)\n                )\n                val isNumeric by remember(item) {\n                    derivedStateOf {\n                        item != DomainAspectRatio.Original && item != DomainAspectRatio.Free && item !is DomainAspectRatio.Custom\n                    }\n                }\n                if (isNumeric) {\n                    AspectRatioSelectionCard(\n                        modifier = Modifier\n                            .width(90.dp)\n                            .container(\n                                resultPadding = 0.dp,\n                                color = animateColorAsState(\n                                    targetValue = if (selected) {\n                                        MaterialTheme.colorScheme.primaryContainer\n                                    } else unselectedCardColor,\n                                ).value,\n                                borderColor = if (selected) MaterialTheme.colorScheme.onPrimaryContainer.copy(\n                                    0.7f\n                                )\n                                else MaterialTheme.colorScheme.outlineVariant()\n                            )\n                            .hapticsClickable {\n                                onAspectRatioChange(\n                                    aspectRatios[index],\n                                    cropAspectRatio.aspectRatio\n                                )\n                            }\n                            .padding(start = 12.dp, top = 12.dp, end = 12.dp, bottom = 2.dp),\n                        contentColor = Color.Transparent,\n                        color = MaterialTheme.colorScheme.onSurface,\n                        cropAspectRatio = cropAspectRatio\n                    )\n                } else {\n                    Box(\n                        modifier = Modifier\n                            .height(106.dp)\n                            .container(\n                                resultPadding = 0.dp,\n                                color = animateColorAsState(\n                                    targetValue = if (selected) {\n                                        MaterialTheme.colorScheme.primaryContainer\n                                    } else unselectedCardColor,\n                                ).value,\n                                borderColor = takeColorFromScheme {\n                                    if (selected) onPrimaryContainer.copy(0.7f)\n                                    else outlineVariant()\n                                }\n                            )\n                            .hapticsClickable {\n                                if (!item::class.isInstance(selectedAspectRatio)) {\n                                    onAspectRatioChange(\n                                        aspectRatios[index],\n                                        cropAspectRatio.aspectRatio\n                                    )\n                                }\n                            }\n                            .padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 8.dp),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        Column(\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            when (item) {\n                                is DomainAspectRatio.Original -> {\n                                    Icon(\n                                        imageVector = Icons.Outlined.Image,\n                                        contentDescription = null\n                                    )\n                                }\n\n                                is DomainAspectRatio.Free -> {\n                                    Icon(\n                                        imageVector = Icons.Outlined.CropFree,\n                                        contentDescription = null\n                                    )\n                                }\n\n                                else -> {\n                                    Icon(\n                                        imageVector = Icons.Outlined.DashboardCustomize,\n                                        contentDescription = null\n                                    )\n                                }\n                            }\n                            Text(\n                                text = cropAspectRatio.title,\n                                fontSize = 14.sp,\n                                lineHeight = 14.sp\n                            )\n                        }\n                    }\n                }\n            }\n        }\n        AnimatedVisibility(visible = selectedAspectRatio is DomainAspectRatio.Custom) {\n            Row(\n                Modifier\n                    .padding(8.dp)\n                    .container(\n                        shape = ShapeDefaults.extraLarge,\n                        color = unselectedCardColor\n                    )\n            ) {\n                var tempWidth by remember {\n                    mutableStateOf(selectedAspectRatio?.widthProportion?.toString() ?: \"1\")\n                }\n                var tempHeight by remember {\n                    mutableStateOf(selectedAspectRatio?.heightProportion?.toString() ?: \"1\")\n                }\n                RoundedTextField(\n                    value = tempWidth,\n                    onValueChange = { value ->\n                        tempWidth = value\n                        val width = abs(value.toFloatOrNull() ?: 0f).coerceAtLeast(1f)\n\n                        selectedAspectRatio.ifCasts<DomainAspectRatio.Custom> { aspect ->\n                            onAspectRatioChange(\n                                aspect.copy(\n                                    widthProportion = width\n                                ),\n                                AspectRatio(\n                                    (width / aspect.heightProportion).takeIf { !it.isNaN() }\n                                        ?: 1f\n                                )\n                            )\n                        }\n                    },\n                    shape = ShapeDefaults.smallStart,\n                    keyboardOptions = KeyboardOptions(\n                        keyboardType = KeyboardType.Number\n                    ),\n                    label = {\n                        Text(stringResource(R.string.width, \" \"))\n                    },\n                    supportingText = abs(tempWidth.toFloatOrNull() ?: 0f).takeIf { it < 1f }?.let {\n                        {\n                            Text(stringResource(R.string.minimum_value_is, 1))\n                        }\n                    },\n                    modifier = Modifier\n                        .weight(1f)\n                        .padding(\n                            start = 8.dp,\n                            top = 8.dp,\n                            bottom = 8.dp,\n                            end = 2.dp\n                        )\n                )\n                RoundedTextField(\n                    value = tempHeight,\n                    onValueChange = { value ->\n                        tempHeight = value\n                        val height = abs(value.toFloatOrNull() ?: 1f).coerceAtLeast(1f)\n\n                        selectedAspectRatio.ifCasts<DomainAspectRatio.Custom> { aspect ->\n                            onAspectRatioChange(\n                                aspect.copy(\n                                    heightProportion = height\n                                ),\n                                AspectRatio(\n                                    (aspect.widthProportion / height).takeIf { !it.isNaN() }\n                                        ?: 1f\n                                )\n                            )\n                        }\n                    },\n                    keyboardOptions = KeyboardOptions(\n                        keyboardType = KeyboardType.Number\n                    ),\n                    shape = ShapeDefaults.smallEnd,\n                    label = {\n                        Text(stringResource(R.string.height, \" \"))\n                    },\n                    supportingText = abs(tempHeight.toFloatOrNull() ?: 0f).takeIf { it < 1f }?.let {\n                        {\n                            Text(stringResource(R.string.minimum_value_is, 1))\n                        }\n                    },\n                    modifier = Modifier\n                        .weight(1f)\n                        .padding(\n                            start = 2.dp,\n                            top = 8.dp,\n                            bottom = 8.dp,\n                            end = 8.dp\n                        ),\n                )\n            }\n        }\n    }\n}\n\nfun DomainAspectRatio.toCropAspectRatio(\n    original: String,\n    free: String,\n    custom: String\n): CropAspectRatio = when (this) {\n    is DomainAspectRatio.Original -> {\n        CropAspectRatio(\n            title = original,\n            shape = createRectShape(AspectRatio.Original),\n            aspectRatio = AspectRatio.Original\n        )\n    }\n\n    is DomainAspectRatio.Free -> {\n        CropAspectRatio(\n            title = free,\n            shape = createRectShape(AspectRatio.Original),\n            aspectRatio = AspectRatio.Original\n        )\n    }\n\n    is DomainAspectRatio.Custom -> {\n        CropAspectRatio(\n            title = custom,\n            shape = createRectShape(AspectRatio(value)),\n            aspectRatio = AspectRatio(value)\n        )\n    }\n\n    else -> {\n        val width = widthProportion.toString()\n            .trimTrailingZero()\n        val height = heightProportion.toString()\n            .trimTrailingZero()\n        CropAspectRatio(\n            title = \"$width:$height\",\n            shape = createRectShape(AspectRatio(value)),\n            aspectRatio = AspectRatio(value)\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/AspectRatios.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\n\n@Composable\nfun aspectRatios() = remember {\n    DomainAspectRatio.defaultList\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/AutoFilePicker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\n\n@Composable\nfun AutoFilePicker(\n    onAutoPick: () -> Unit,\n    isPickedAlready: Boolean\n) {\n    val settingsState = LocalSettingsState.current\n\n    var picked by rememberSaveable(isPickedAlready) {\n        mutableStateOf(isPickedAlready)\n    }\n    LaunchedEffect(Unit) {\n        if (settingsState.skipImagePicking && !picked) {\n            runCatching {\n                onAutoPick()\n                picked = true\n            }.onFailure(AppToastHost::handleFileSystemFailure)\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/BadImageWidget.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun BadImageWidget() {\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally,\n        modifier = Modifier\n            .container()\n            .padding(16.dp)\n    ) {\n        Icon(\n            imageVector = Icons.Rounded.BrokenImageAlt,\n            contentDescription = null,\n            tint = MaterialTheme.colorScheme.onSurfaceVariant\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/HistogramChart.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.graphics.Bitmap\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.histogram.HistogramType\nimport com.t8rin.histogram.ImageHistogram\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun HistogramChart(\n    model: Any?,\n    modifier: Modifier,\n    initialType: HistogramType = HistogramType.RGB,\n    onSwapType: ((HistogramType) -> HistogramType)? = { type ->\n        when (type) {\n            HistogramType.RGB -> HistogramType.Brightness\n            HistogramType.Brightness -> HistogramType.Camera\n            HistogramType.Camera -> HistogramType.RGB\n        }\n    },\n    harmonizationColor: Color = MaterialTheme.colorScheme.primary,\n    linesThickness: Dp = 0.5.dp,\n    bordersColor: Color = MaterialTheme.colorScheme.outline,\n    bordersShape: Shape = ShapeDefaults.extraSmall\n) {\n    when (model) {\n        is Bitmap -> {\n            ImageHistogram(\n                image = model,\n                modifier = modifier,\n                initialType = initialType,\n                onSwapType = onSwapType,\n                harmonizationColor = harmonizationColor,\n                linesThickness = linesThickness,\n                bordersColor = bordersColor,\n                bordersShape = bordersShape\n            )\n        }\n\n        else -> {\n            ImageHistogram(\n                model = model,\n                modifier = modifier,\n                initialType = initialType,\n                onSwapType = onSwapType,\n                harmonizationColor = harmonizationColor,\n                linesThickness = linesThickness,\n                bordersColor = bordersColor,\n                bordersShape = bordersShape\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImageContainer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\n\n@Composable\nfun ImageContainer(\n    modifier: Modifier = Modifier,\n    imageInside: Boolean,\n    showOriginal: Boolean,\n    previewBitmap: Bitmap?,\n    originalBitmap: Bitmap?,\n    isLoading: Boolean,\n    shouldShowPreview: Boolean,\n    animatePreviewChange: Boolean = true,\n    containerModifier: Modifier = Modifier.fillMaxSize()\n) {\n    val generatePreviews = LocalSettingsState.current.generatePreviews\n    if (animatePreviewChange) {\n        AnimatedContent(\n            modifier = containerModifier,\n            targetState = remember(previewBitmap, isLoading, showOriginal) {\n                derivedStateOf {\n                    Triple(previewBitmap, isLoading, showOriginal)\n                }\n            }.value,\n            transitionSpec = { fadeIn() togetherWith fadeOut() using SizeTransform(false) }\n        ) { (bmp, loading, showOrig) ->\n            Box(\n                modifier = modifier,\n                contentAlignment = Alignment.Center\n            ) {\n                Box(\n                    contentAlignment = Alignment.Center,\n                    modifier = Modifier.then(\n                        if (!imageInside) {\n                            Modifier.padding(\n                                bottom = WindowInsets\n                                    .navigationBars\n                                    .asPaddingValues()\n                                    .calculateBottomPadding()\n                            )\n                        } else Modifier\n                    )\n                ) {\n                    if (showOrig) {\n                        SimplePicture(\n                            bitmap = originalBitmap,\n                            loading = loading\n                        )\n                    } else {\n                        SimplePicture(\n                            loading = loading,\n                            bitmap = bmp,\n                            visible = shouldShowPreview\n                        )\n                        if (!loading && (bmp == null || !shouldShowPreview) || !generatePreviews) {\n                            BadImageWidget()\n                        }\n                    }\n                    if (loading) EnhancedLoadingIndicator()\n                }\n            }\n        }\n    } else {\n        AnimatedContent(\n            modifier = containerModifier,\n            targetState = remember(isLoading, showOriginal) {\n                derivedStateOf {\n                    isLoading to showOriginal\n                }\n            }.value,\n            transitionSpec = { fadeIn() togetherWith fadeOut() using SizeTransform(false) }\n        ) { (loading, showOrig) ->\n            Box(\n                modifier = modifier,\n                contentAlignment = Alignment.Center\n            ) {\n                Column(horizontalAlignment = Alignment.CenterHorizontally) {\n                    Box(\n                        contentAlignment = Alignment.Center,\n                        modifier = Modifier.then(\n                            if (!imageInside) {\n                                Modifier.padding(\n                                    bottom = WindowInsets\n                                        .navigationBars\n                                        .asPaddingValues()\n                                        .calculateBottomPadding()\n                                )\n                            } else Modifier\n                        )\n                    ) {\n                        previewBitmap?.let {\n                            if (!showOrig) {\n                                SimplePicture(\n                                    bitmap = it,\n                                    loading = loading\n                                )\n                            } else {\n                                SimplePicture(\n                                    loading = loading,\n                                    bitmap = originalBitmap,\n                                    visible = true\n                                )\n                            }\n                        } ?: if (!generatePreviews) {\n                            BadImageWidget()\n                        } else Unit\n\n                        if (previewBitmap == null && loading) {\n                            EnhancedLoadingIndicator()\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImageCounter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ChangeCircle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun ImageCounter(\n    imageCount: Int?,\n    onRepick: () -> Unit,\n    modifier: Modifier = Modifier\n) {\n    AnimatedVisibility(\n        modifier = modifier.padding(bottom = 16.dp),\n        visible = imageCount != null,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically(),\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            modifier = Modifier\n                .container(shape = ShapeDefaults.circle)\n                .padding(start = 3.dp),\n            horizontalArrangement = Arrangement.spacedBy((-1).dp)\n        ) {\n            LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.tertiaryContainer.copy(0.3f),\n                    contentColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(0.9f),\n                    onClick = { if ((imageCount ?: 0) > 1) onRepick() },\n                    borderColor = MaterialTheme.colorScheme.outlineVariant(\n                        luminance = 0.1f,\n                        onTopOf = MaterialTheme\n                            .colorScheme\n                            .tertiaryContainer\n                            .copy(0.1f),\n                    ),\n                    isShadowClip = true,\n                    shape = AutoCornersShape(\n                        topStart = CornerSize(50),\n                        topEnd = CornerSize(4.dp),\n                        bottomStart = CornerSize(50),\n                        bottomEnd = CornerSize(4.dp),\n                    )\n                ) {\n                    Text(stringResource(R.string.images, imageCount ?: 0L))\n                }\n                EnhancedIconButton(\n                    onClick = { if ((imageCount ?: 0) > 1) onRepick() },\n                    borderColor = MaterialTheme.colorScheme.outlineVariant(\n                        luminance = 0.1f,\n                        onTopOf = MaterialTheme\n                            .colorScheme\n                            .tertiaryContainer\n                            .copy(0.1f),\n                    ),\n                    containerColor = MaterialTheme.colorScheme.tertiaryContainer.copy(0.3f),\n                    contentColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(0.9f),\n                    isShadowClip = true,\n                    shape = AutoCornersShape(\n                        topEnd = CornerSize(50),\n                        topStart = CornerSize(4.dp),\n                        bottomEnd = CornerSize(50),\n                        bottomStart = CornerSize(4.dp),\n                    )\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.ChangeCircle,\n                        contentDescription = stringResource(R.string.change_preview)\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImageHeaderState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\ndata class ImageHeaderState(\n    val position: Int = 1,\n    val isBlocked: Boolean = true\n)\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImageNotPickedWidget.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.twotone.FileOpen\nimport androidx.compose.material.icons.twotone.Image\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialShapes\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.min\nimport androidx.graphics.shapes.Morph\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.shapes.MorphShape\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.springySpec\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.currentScreenTwoToneIcon\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.filterIsInstance\n\n@Composable\nfun ImageNotPickedWidget(\n    onPickImage: () -> Unit,\n    modifier: Modifier = Modifier,\n    text: String = stringResource(R.string.pick_image),\n    containerColor: Color = Color.Unspecified,\n) {\n    SourceNotPickedWidget(\n        onClick = onPickImage,\n        modifier = modifier,\n        text = text,\n        icon = currentScreenTwoToneIcon(Icons.TwoTone.Image),\n        containerColor = containerColor\n    )\n}\n\n@Composable\nfun FileNotPickedWidget(\n    onPickFile: () -> Unit,\n    modifier: Modifier = Modifier,\n    text: String = stringResource(R.string.pick_file_to_start),\n    containerColor: Color = Color.Unspecified,\n) {\n    SourceNotPickedWidget(\n        onClick = onPickFile,\n        modifier = modifier,\n        text = text,\n        icon = currentScreenTwoToneIcon(Icons.TwoTone.FileOpen),\n        containerColor = containerColor\n    )\n}\n\n@Composable\nfun SourceNotPickedWidget(\n    modifier: Modifier = Modifier,\n    onClick: (() -> Unit)?,\n    text: String,\n    icon: ImageVector,\n    maxLines: Int = 3,\n    containerColor: Color = Color.Unspecified,\n) {\n    BoxWithConstraints(\n        contentAlignment = Alignment.Center\n    ) {\n        val targetSize = min(min(maxWidth, maxHeight), 300.dp)\n\n        Column(\n            modifier = modifier\n                .animateContentSizeNoClip()\n                .padding(0.5.dp)\n                .container(color = containerColor),\n            verticalArrangement = Arrangement.Center,\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Spacer(Modifier.height(16.dp))\n            ClickableActionIcon(\n                icon = icon,\n                onClick = onClick,\n                modifier = Modifier.size(targetSize / 3)\n            )\n            AutoSizeText(\n                text = text,\n                modifier = Modifier.padding(16.dp),\n                textAlign = TextAlign.Center,\n                color = MaterialTheme.colorScheme.onSurfaceVariant,\n                key = { it.length },\n                maxLines = maxLines\n            )\n        }\n    }\n}\n\n@Composable\nfun ClickableActionIcon(\n    icon: ImageVector,\n    onClick: (() -> Unit)?,\n    modifier: Modifier = Modifier\n) {\n    val interactionSource = remember { MutableInteractionSource() }\n    val pressed by interactionSource.collectIsPressedAsState()\n    val haptics = LocalHapticFeedback.current\n\n    LaunchedEffect(interactionSource, haptics) {\n        interactionSource.interactions.filterIsInstance<PressInteraction>().collectLatest {\n            haptics.longPress()\n        }\n    }\n\n    val percentage = animateFloatAsState(\n        targetValue = if (pressed) 1f else 0.2f,\n        animationSpec = springySpec()\n    )\n    val scale by animateFloatAsState(\n        if (pressed) 1f\n        else 1.1f\n    )\n    val morph = remember {\n        Morph(\n            start = MaterialShapes.Cookie4Sided,\n            end = MaterialShapes.Square\n        )\n    }\n    val shape = remember {\n        MorphShape(\n            morph = morph,\n            percentage = { percentage.value }\n        )\n    }\n\n    Box(\n        modifier = modifier\n            .size(100.dp)\n            .scale(scale)\n            .container(\n                shape = shape,\n                resultPadding = 0.dp,\n                color = MaterialTheme.colorScheme.mixedContainer.copy(0.8f)\n            )\n            .then(\n                if (onClick != null) {\n                    Modifier.hapticsClickable(\n                        onClick = onClick,\n                        interactionSource = interactionSource,\n                        indication = LocalIndication.current,\n                        enableHaptics = false\n                    )\n                } else Modifier\n            )\n            .scale(1f / scale)\n    ) {\n        AnimatedContent(\n            targetState = icon,\n            modifier = Modifier.fillMaxSize()\n        ) { imageVector ->\n            Icon(\n                imageVector = imageVector,\n                contentDescription = null,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(12.dp),\n                tint = MaterialTheme.colorScheme.onMixedContainer\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImagePager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.AnchoredDraggableDefaults\nimport androidx.compose.foundation.gestures.AnchoredDraggableState\nimport androidx.compose.foundation.gestures.DraggableAnchors\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.anchoredDraggable\nimport androidx.compose.foundation.gestures.snapTo\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.displayCutoutPadding\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.systemBars\nimport androidx.compose.foundation.layout.systemBarsPadding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.Share\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.utils.humanFileSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.EditAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.onPrimaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.theme.primaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.toShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withLayoutCorners\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.modalsheet.FullscreenPopup\nimport kotlinx.coroutines.delay\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.toggleScale\nimport net.engawapg.lib.zoomable.zoomable\nimport kotlin.math.roundToInt\n\n\n@Composable\nfun ImagePager(\n    visible: Boolean,\n    selectedUri: Uri?,\n    uris: List<Uri>?,\n    onNavigate: (Screen) -> Unit,\n    onUriSelected: (Uri?) -> Unit,\n    onShare: (Uri) -> Unit,\n    onDismiss: () -> Unit\n) {\n    FullscreenPopup {\n        var predictiveBackProgress by remember {\n            mutableFloatStateOf(0f)\n        }\n        val animatedPredictiveBackProgress by animateFloatAsState(predictiveBackProgress)\n        val scale = (1f - animatedPredictiveBackProgress).coerceAtLeast(0.75f)\n\n        LaunchedEffect(predictiveBackProgress, visible) {\n            if (!visible && predictiveBackProgress != 0f) {\n                delay(600)\n                predictiveBackProgress = 0f\n            }\n        }\n\n        AnimatedVisibility(\n            visible = visible,\n            modifier = Modifier.fillMaxSize(),\n            enter = fadeIn(tween(500)),\n            exit = fadeOut(tween(500))\n        ) {\n            val density = LocalDensity.current\n            val screenHeight =\n                LocalScreenSize.current.height + WindowInsets.systemBars.asPaddingValues()\n                    .let { it.calculateTopPadding() + it.calculateBottomPadding() }\n            val anchors = with(density) {\n                DraggableAnchors {\n                    true at 0f\n                    false at -screenHeight.toPx()\n                }\n            }\n\n            val draggableState = remember(anchors) {\n                AnchoredDraggableState(\n                    initialValue = true,\n                    anchors = anchors\n                )\n            }\n\n            LaunchedEffect(draggableState.settledValue) {\n                if (!draggableState.settledValue) {\n                    onDismiss()\n                    delay(600)\n                    draggableState.snapTo(true)\n                }\n            }\n\n            var wantToEdit by rememberSaveable {\n                mutableStateOf(false)\n            }\n            val pagerState = rememberPagerState(\n                initialPage = selectedUri?.let {\n                    uris?.indexOf(it)\n                }?.takeIf { it >= 0 } ?: 0,\n                pageCount = {\n                    uris?.size ?: 0\n                }\n            )\n            LaunchedEffect(pagerState.currentPage) {\n                onUriSelected(\n                    uris?.getOrNull(pagerState.currentPage)\n                )\n            }\n            val progress by remember(draggableState) {\n                derivedStateOf {\n                    draggableState.progress(\n                        from = false,\n                        to = true\n                    )\n                }\n            }\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .withLayoutCorners { corners ->\n                        graphicsLayer {\n                            scaleX = scale\n                            scaleY = scale\n                            shape = corners.toShape(animatedPredictiveBackProgress)\n                            clip = true\n                        }\n                    }\n                    .background(\n                        MaterialTheme.colorScheme.scrim.copy(alpha = 0.6f * progress)\n                    )\n            ) {\n                val imageErrorPages = remember {\n                    mutableStateListOf<Int>()\n                }\n                var hideControls by remember(animatedPredictiveBackProgress) {\n                    mutableStateOf(false)\n                }\n                HorizontalPager(\n                    state = pagerState,\n                    modifier = Modifier.fillMaxSize(),\n                    beyondViewportPageCount = 5,\n                    pageSpacing = if (pagerState.pageCount > 1) 16.dp\n                    else 0.dp\n                ) { page ->\n                    Box(\n                        modifier = Modifier.fillMaxSize()\n                    ) {\n                        val zoomState = rememberZoomState(20f)\n                        Picture(\n                            showTransparencyChecker = false,\n                            model = uris?.getOrNull(page),\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .clipToBounds()\n                                .systemBarsPadding()\n                                .displayCutoutPadding()\n                                .offset {\n                                    IntOffset(\n                                        x = 0,\n                                        y = -draggableState\n                                            .requireOffset()\n                                            .roundToInt(),\n                                    )\n                                }\n                                .anchoredDraggable(\n                                    state = draggableState,\n                                    enabled = zoomState.scale < 1.01f && !pagerState.isScrollInProgress,\n                                    orientation = Orientation.Vertical,\n                                    reverseDirection = true,\n                                    flingBehavior = AnchoredDraggableDefaults.flingBehavior(\n                                        animationSpec = tween(500),\n                                        state = draggableState\n                                    )\n                                )\n                                .zoomable(\n                                    zoomEnabled = !imageErrorPages.contains(page),\n                                    zoomState = zoomState,\n                                    onTap = {\n                                        hideControls = !hideControls\n                                    },\n                                    onDoubleTap = {\n                                        zoomState.toggleScale(\n                                            targetScale = 5f,\n                                            position = it\n                                        )\n                                    }\n                                ),\n                            enableUltraHDRSupport = true,\n                            contentScale = ContentScale.Fit,\n                            shape = RectangleShape,\n                            onSuccess = {\n                                imageErrorPages.remove(page)\n                            },\n                            onError = {\n                                imageErrorPages.add(page)\n                            },\n                            error = {\n                                Box(\n                                    contentAlignment = Alignment.Center,\n                                    modifier = Modifier.background(\n                                        takeColorFromScheme { isNightMode ->\n                                            errorContainer.copy(\n                                                if (isNightMode) 0.25f\n                                                else 1f\n                                            ).compositeOver(surface)\n                                        }\n                                    )\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.BrokenImageAlt,\n                                        contentDescription = null,\n                                        modifier = Modifier.fillMaxSize(0.5f),\n                                        tint = MaterialTheme.colorScheme.onErrorContainer.copy(0.8f)\n                                    )\n                                }\n                            }\n                        )\n                    }\n                }\n                val showTopBar by remember(draggableState, hideControls) {\n                    derivedStateOf {\n                        draggableState.offset == 0f && !hideControls\n                    }\n                }\n                val selectedUriFilename = selectedUri?.let { rememberFilename(it) }\n                val selectedUriFileSize = selectedUri?.let { rememberFileSize(it) }\n                val showBottomHist = pagerState.currentPage !in imageErrorPages\n                val showBottomBar by remember(draggableState, showBottomHist, hideControls) {\n                    derivedStateOf {\n                        draggableState.offset == 0f && showBottomHist && !hideControls\n                    }\n                }\n\n                AnimatedVisibility(\n                    visible = showTopBar,\n                    modifier = Modifier.fillMaxWidth(),\n                    enter = fadeIn() + slideInVertically(),\n                    exit = fadeOut() + slideOutVertically()\n                ) {\n                    EnhancedTopAppBar(\n                        colors = EnhancedTopAppBarDefaults.colors(\n                            containerColor = MaterialTheme.colorScheme.scrim.copy(alpha = 0.5f)\n                        ),\n                        type = EnhancedTopAppBarType.Center,\n                        drawHorizontalStroke = false,\n                        title = {\n                            uris?.size?.takeIf { it > 1 }?.let {\n                                Text(\n                                    text = \"${pagerState.currentPage + 1}/$it\",\n                                    modifier = Modifier\n                                        .padding(vertical = 4.dp, horizontal = 12.dp),\n                                    color = White\n                                )\n                            }\n                        },\n                        actions = {\n                            AnimatedVisibility(\n                                visible = !uris.isNullOrEmpty(),\n                                enter = fadeIn() + scaleIn(),\n                                exit = fadeOut() + scaleOut()\n                            ) {\n                                Row(verticalAlignment = Alignment.CenterVertically) {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            selectedUri?.let { onShare(it) }\n                                        }\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.Share,\n                                            contentDescription = stringResource(R.string.share),\n                                            tint = White\n                                        )\n                                    }\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            wantToEdit = true\n                                        }\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.EditAlt,\n                                            contentDescription = stringResource(R.string.edit),\n                                            tint = White\n                                        )\n                                    }\n                                }\n                            }\n                        },\n                        navigationIcon = {\n                            AnimatedVisibility(!uris.isNullOrEmpty()) {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        onDismiss()\n                                        onUriSelected(null)\n                                    }\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit),\n                                        tint = White\n                                    )\n                                }\n                            }\n                        }\n                    )\n                }\n\n                AnimatedVisibility(\n                    visible = showBottomBar,\n                    modifier = Modifier.align(Alignment.BottomEnd),\n                    enter = fadeIn() + slideInVertically { it / 2 },\n                    exit = fadeOut() + slideOutVertically { it / 2 }\n                ) {\n                    Row(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .background(MaterialTheme.colorScheme.scrim.copy(0.5f))\n                            .navigationBarsPadding()\n                            .padding(\n                                WindowInsets.displayCutout\n                                    .only(\n                                        WindowInsetsSides.Horizontal\n                                    )\n                                    .asPaddingValues()\n                            )\n                            .padding(16.dp),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        Row(\n                            modifier = Modifier.weight(1f),\n                            verticalAlignment = Alignment.CenterVertically\n                        ) {\n                            selectedUriFilename?.let {\n                                Text(\n                                    text = it,\n                                    modifier = Modifier\n                                        .animateContentSizeNoClip()\n                                        .weight(1f, false),\n                                    color = White,\n                                    style = MaterialTheme.typography.labelLarge,\n                                    fontSize = 13.sp\n                                )\n                            }\n                            selectedUriFileSize\n                                ?.takeIf { it > 0 }\n                                ?.let { size ->\n                                    Spacer(Modifier.width(8.dp))\n                                    Text(\n                                        text = rememberHumanFileSize(size),\n                                        modifier = Modifier\n                                            .animateContentSizeNoClip()\n                                            .background(\n                                                color = MaterialTheme.colorScheme.primaryContainerFixed,\n                                                shape = ShapeDefaults.circle\n                                            )\n                                            .padding(horizontal = 8.dp, vertical = 4.dp),\n                                        color = MaterialTheme.colorScheme.onPrimaryContainerFixed,\n                                        style = MaterialTheme.typography.labelMedium\n                                    )\n                                }\n                            MetadataPreviewButton(\n                                uri = selectedUri,\n                                name = { selectedUriFilename },\n                                fileSize = { selectedUriFileSize?.let { humanFileSize(it) } }\n                            )\n                        }\n                        Spacer(Modifier.width(16.dp))\n                        HistogramChart(\n                            model = uris?.getOrNull(pagerState.currentPage) ?: Uri.EMPTY,\n                            modifier = Modifier\n                                .height(50.dp)\n                                .width(90.dp),\n                            bordersColor = Color.White\n                        )\n                    }\n                }\n            }\n\n            ProcessImagesPreferenceSheet(\n                uris = listOfNotNull(selectedUri),\n                visible = wantToEdit,\n                onDismiss = {\n                    wantToEdit = false\n                },\n                onNavigate = onNavigate\n            )\n\n            PredictiveBackObserver(\n                onProgress = {\n                    predictiveBackProgress = it / 6f\n                },\n                onClean = { isCompleted ->\n                    if (isCompleted) {\n                        onDismiss()\n                        onUriSelected(null)\n                        delay(400)\n                    }\n                    predictiveBackProgress = 0f\n                },\n                enabled = visible\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImagePreviewGrid.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\n\n@Composable\nfun ImagePreviewGrid(\n    data: List<Uri>?,\n    onNavigate: (Screen) -> Unit,\n    imageFrames: ImageFrames?,\n    onFrameSelectionChange: (ImageFrames) -> Unit,\n    onAddImages: ((List<Uri>) -> Unit)?,\n    onShareImage: (Uri) -> Unit,\n    onRemove: ((Uri) -> Unit)?,\n    verticalCellSize: Dp = 120.dp,\n    horizontalCellSize: Dp = verticalCellSize,\n    contentPadding: PaddingValues? = null,\n    isSelectable: Boolean = false,\n    initialShowImagePreviewDialog: Boolean = false,\n    modifier: Modifier = Modifier\n) {\n    val imagePicker = rememberImagePicker { uriList: List<Uri> ->\n        val uris = (data ?: emptyList()).toMutableList()\n        uriList.forEach {\n            if (it !in uris) uris.add(it)\n        }\n        onAddImages?.invoke(uris)\n    }\n\n    var selectedUri by rememberSaveable(initialShowImagePreviewDialog) {\n        mutableStateOf(\n            if (initialShowImagePreviewDialog) data?.firstOrNull()?.toString()\n            else null\n        )\n    }\n\n    val cutout = WindowInsets.displayCutout.asPaddingValues()\n    val direction = LocalLayoutDirection.current\n\n    var isSelectionMode by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var isSelectionModePrevious by rememberSaveable {\n        mutableStateOf(false)\n    }\n    ImagesPreviewWithSelection(\n        imageUris = data.orEmpty(),\n        imageFrames = imageFrames ?: ImageFrames.ManualSelection(emptyList()),\n        modifier = modifier,\n        onFrameSelectionChange = {\n            if (it.isEmpty()) {\n                isSelectionMode = false\n            }\n            onFrameSelectionChange(it)\n        },\n        isPortrait = false,\n        isLoadingImages = false,\n        isAutoExpandLayout = false,\n        onError = {\n            onRemove?.invoke(it.toUri())\n        },\n        contentPadding = contentPadding ?: PaddingValues(\n            bottom = 88.dp + WindowInsets\n                .navigationBars\n                .asPaddingValues()\n                .calculateBottomPadding(),\n            top = 12.dp,\n            end = 12.dp + cutout.calculateEndPadding(direction),\n            start = 12.dp + cutout.calculateStartPadding(direction)\n        ),\n        isSelectionMode = isSelectionMode,\n        onItemClick = { index ->\n            if (!isSelectionModePrevious) {\n                data?.get(index)?.let {\n                    selectedUri = it.toString()\n                }\n            }\n            isSelectionModePrevious = isSelectionMode\n        },\n        onItemLongClick = {\n            isSelectionModePrevious = true\n            isSelectionMode = true\n        },\n        verticalCellSize = verticalCellSize,\n        horizontalCellSize = horizontalCellSize,\n        aboveImageContent = {},\n        isAboveImageScrimEnabled = isSelectionMode,\n        endAdditionalItem = if (!isSelectionMode && !data.isNullOrEmpty() && onAddImages != null) {\n            {\n                Box(\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .aspectRatio(1f)\n                        .container(\n                            shape = MaterialTheme.shapes.extraSmall,\n                            resultPadding = 0.dp,\n                            color = MaterialTheme.colorScheme.tertiaryContainer.copy(0.3f)\n                        )\n                        .hapticsClickable(onClick = imagePicker::pickImage),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.AddPhotoAlt,\n                        contentDescription = stringResource(R.string.pick_images),\n                        modifier = Modifier.fillMaxSize(0.4f),\n                        tint = MaterialTheme.colorScheme.onTertiaryContainer.copy(0.8f)\n                    )\n                }\n            }\n        } else null,\n        isContentAlignToCenter = false,\n        enableSelection = isSelectable\n    )\n\n    ImagePager(\n        visible = !selectedUri.isNullOrEmpty() && !data.isNullOrEmpty(),\n        selectedUri = selectedUri?.toUri(),\n        uris = data,\n        onUriSelected = {\n            selectedUri = it?.toString()\n        },\n        onShare = onShareImage,\n        onDismiss = { selectedUri = null },\n        onNavigate = {\n            selectedUri = null\n            onNavigate(it)\n        }\n    )\n\n    AutoContentBasedColors(\n        model = selectedUri\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImageStickyHeader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Lock\nimport androidx.compose.material.icons.rounded.LockOpen\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SliderDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.layout.LayoutCoordinates\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.layout.onGloballyPositioned\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.gigamole.composefadingedges.FadingEdgesGravity\nimport com.t8rin.gesture.PointerRequisite\nimport com.t8rin.gesture.detectPointerTransformGestures\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport kotlinx.coroutines.delay\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.snapBackZoomable\nimport kotlin.math.abs\n\n\nfun LazyListScope.imageStickyHeader(\n    visible: Boolean,\n    imageState: ImageHeaderState,\n    internalHeight: Dp,\n    onStateChange: (ImageHeaderState) -> Unit,\n    backgroundColor: Color = Color.Unspecified,\n    padding: Dp = 20.dp,\n    isControlsVisibleIndefinitely: Boolean = false,\n    onGloballyPositioned: (LayoutCoordinates) -> Unit = {},\n    imageModifier: Modifier = Modifier,\n    imageBlock: @Composable () -> Unit,\n) {\n    val content = @Composable {\n        var controlsVisible by rememberSaveable {\n            mutableStateOf(true)\n        }\n        val sliderInteractionSource = remember {\n            MutableInteractionSource()\n        }\n        val interactions by sliderInteractionSource.interactions.collectAsState(initial = null)\n\n        LaunchedEffect(controlsVisible, interactions) {\n            if (controlsVisible && !(interactions is DragInteraction.Start || interactions is PressInteraction.Press)) {\n                delay(2500)\n                controlsVisible = isControlsVisibleIndefinitely\n            }\n        }\n\n        val screenWidth = LocalScreenSize.current.width\n        val density = LocalDensity.current\n        Column(\n            modifier = Modifier\n                .layout { measurable, constraints ->\n                    val result =\n                        measurable.measure(\n                            constraints.copy(\n                                maxWidth = with(density) {\n                                    screenWidth.roundToPx()\n                                }.coerceAtLeast(constraints.minWidth)\n                            )\n                        )\n                    layout(result.measuredWidth, result.measuredHeight) {\n                        result.place(0, 0)\n                    }\n                }\n                .tappable(!isControlsVisibleIndefinitely) {\n                    controlsVisible = true\n                }\n                .onGloballyPositioned(onGloballyPositioned)\n                .animateContentSizeNoClip()\n        ) {\n            val color = if (backgroundColor.isSpecified) {\n                backgroundColor\n            } else MaterialTheme.colorScheme.surface.copy(alpha = 0.85f)\n\n            val settingsState = LocalSettingsState.current\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .height(internalHeight)\n                    .fadingEdges(\n                        scrollableState = null,\n                        isVertical = true,\n                        length = animateDpAsState(\n                            if (imageState.position == 4) 0.dp\n                            else 16.dp\n                        ).value,\n                        gravity = FadingEdgesGravity.End\n                    )\n                    .background(color)\n                    .padding(\n                        start = padding,\n                        end = padding,\n                        top = padding,\n                        bottom = animateDpAsState(\n                            if (controlsVisible) padding / 2\n                            else padding\n                        ).value\n                    ),\n                verticalArrangement = Arrangement.Center,\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                val zoomState = rememberZoomState()\n                Box(\n                    modifier = Modifier\n                        .weight(1f, false)\n                        .then(imageModifier)\n                        .then(\n                            if (!isControlsVisibleIndefinitely) {\n                                Modifier.pointerInput(Unit) {\n                                    var touchPointerOffset = Offset.Zero\n                                    detectPointerTransformGestures(\n                                        consume = false,\n                                        onGestureEnd = {\n                                            val diff = touchPointerOffset - it.position\n                                            if (abs(diff.x) < 10f && abs(diff.y) < 10f) {\n                                                controlsVisible = true\n                                                it.consume()\n                                            }\n                                        },\n                                        requisite = PointerRequisite.EqualTo,\n                                        onGestureStart = {\n                                            touchPointerOffset = it.position\n                                        },\n                                        onGesture = { _, _, _, _, _, _ -> }\n                                    )\n                                }\n                            } else Modifier\n                        )\n                        .snapBackZoomable(zoomState = zoomState)\n                ) {\n                    imageBlock()\n                }\n                BoxAnimatedVisibility(\n                    visible = controlsVisible,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    Row(\n                        modifier = Modifier\n                            .fillMaxWidth(0.7f)\n                            .padding(vertical = 12.dp),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        EnhancedSlider(\n                            interactionSource = sliderInteractionSource,\n                            modifier = Modifier\n                                .weight(1f)\n                                .padding(horizontal = 10.dp),\n                            value = imageState.position.toFloat(),\n                            onValueChange = {\n                                controlsVisible = true\n                                onStateChange(imageState.copy(position = it.toInt()))\n                            },\n                            colors = SliderDefaults.colors(\n                                inactiveTrackColor = MaterialTheme.colorScheme.outlineVariant(\n                                    onTopOf = MaterialTheme.colorScheme.tertiaryContainer\n                                ).copy(0.5f),\n                                activeTrackColor = MaterialTheme.colorScheme.tertiary.copy(0.5f),\n                                thumbColor = if (settingsState.sliderType == SliderType.Fancy) {\n                                    MaterialTheme.colorScheme.onTertiary\n                                } else MaterialTheme.colorScheme.tertiary,\n                                activeTickColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                inactiveTickColor = MaterialTheme.colorScheme.tertiary.copy(0.5f)\n                            ),\n                            steps = 3,\n                            valueRange = 0f..4f\n                        )\n                        EnhancedIconButton(\n                            onClick = {\n                                controlsVisible = true\n                                onStateChange(imageState.copy(isBlocked = !imageState.isBlocked))\n                            },\n                            containerColor = takeColorFromScheme {\n                                if (imageState.isBlocked) {\n                                    tertiary.copy(0.8f)\n                                } else {\n                                    surfaceVariant.copy(0.5f)\n                                }\n                            },\n                            contentColor = takeColorFromScheme {\n                                if (imageState.isBlocked) {\n                                    onTertiary\n                                } else {\n                                    onSurfaceVariant\n                                }\n                            }\n                        ) {\n                            AnimatedContent(targetState = imageState.isBlocked) { blocked ->\n                                if (blocked) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Lock,\n                                        contentDescription = \"Lock Image\"\n                                    )\n                                } else {\n                                    Icon(\n                                        imageVector = Icons.Rounded.LockOpen,\n                                        contentDescription = \"Unlock Image\"\n                                    )\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    if (!imageState.isBlocked) {\n        item(\n            key = \"stickyHeader\",\n            contentType = \"stickyHeader\"\n        ) {\n            AnimatedContent(\n                targetState = visible,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                if (it) content()\n                else Spacer(Modifier)\n            }\n        }\n    } else {\n        stickyHeader(\n            key = \"stickyHeader\",\n            contentType = \"stickyHeader\"\n        ) {\n            AnimatedContent(\n                targetState = visible,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                if (it) content()\n                else Spacer(Modifier)\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/ImagesPreviewWithSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateDp\nimport androidx.compose.animation.core.updateTransition\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyGridItemScope\nimport androidx.compose.foundation.lazy.grid.LazyHorizontalGrid\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.itemsIndexed\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.CheckCircle\nimport androidx.compose.material.icons.filled.RadioButtonUnchecked\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFileExtension\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.advancedShadow\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.dragHandler\n\n@Composable\nfun ImagesPreviewWithSelection(\n    imageUris: List<Any>,\n    imageFrames: ImageFrames,\n    onFrameSelectionChange: (ImageFrames) -> Unit,\n    isPortrait: Boolean,\n    isLoadingImages: Boolean,\n    spacing: Dp = 8.dp,\n    onError: (String) -> Unit = {},\n    isAutoExpandLayout: Boolean = true,\n    verticalCellSize: Dp = 90.dp,\n    horizontalCellSize: Dp = 120.dp,\n    contentPadding: PaddingValues = PaddingValues(12.dp),\n    isSelectionMode: Boolean = true,\n    isAboveImageScrimEnabled: Boolean = true,\n    onItemClick: (Int) -> Unit = {},\n    onItemLongClick: (Int) -> Unit = {},\n    aboveImageContent: @Composable BoxScope.(index: Int) -> Unit = { index ->\n        Text(\n            text = (index + 1).toString(),\n            color = Color.White,\n            fontSize = 24.sp,\n            fontWeight = FontWeight.Medium\n        )\n    },\n    showExtension: Boolean = true,\n    endAdditionalItem: (@Composable LazyGridItemScope.() -> Unit)? = null,\n    isContentAlignToCenter: Boolean = true,\n    contentScale: ContentScale = ContentScale.Crop,\n    enableSelection: Boolean = true,\n    modifier: Modifier? = null\n) {\n    val state = rememberLazyGridState()\n\n    val getUris: () -> Set<Int> = {\n        val indexes = imageFrames\n            .getFramePositions(imageUris.size)\n            .map { it - 1 }\n        imageUris.mapIndexedNotNull { index, _ ->\n            if (index in indexes) index + 1\n            else null\n        }.toSet()\n    }\n    val selectedItems by remember(imageUris, imageFrames) {\n        mutableStateOf(getUris())\n    }\n    val privateSelectedItems = remember {\n        mutableStateOf(selectedItems)\n    }\n\n    LaunchedEffect(imageFrames, selectedItems) {\n        if (imageFrames !is ImageFrames.ManualSelection || selectedItems.isEmpty()) {\n            privateSelectedItems.value = selectedItems\n        }\n    }\n\n    val screenWidth = LocalScreenSize.current.width\n    val gridModifier = modifier ?: if (isPortrait) {\n        Modifier.height(\n            (130.dp * imageUris.size).coerceAtMost(420.dp)\n        )\n    } else {\n        Modifier\n    }.then(\n        if (isAutoExpandLayout) {\n            Modifier.layout { measurable, constraints ->\n                val result =\n                    measurable.measure(\n                        if (isPortrait) {\n                            constraints.copy(\n                                maxWidth = screenWidth.roundToPx()\n                            )\n                        } else {\n                            constraints.copy(\n                                maxHeight = constraints.maxHeight + 48.dp.roundToPx()\n                            )\n                        }\n                    )\n                layout(result.measuredWidth, result.measuredHeight) {\n                    result.place(0, 0)\n                }\n            }\n        } else Modifier\n    )\n\n    Box(modifier = gridModifier) {\n        if (isPortrait) {\n            LazyHorizontalGrid(\n                rows = GridCells.Adaptive(horizontalCellSize),\n                state = state,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .dragHandler(\n                        key = enableSelection to imageUris,\n                        lazyGridState = state,\n                        isVertical = false,\n                        selectedItems = privateSelectedItems,\n                        onSelectionChange = {\n                            onFrameSelectionChange(ImageFrames.ManualSelection(it.toList()))\n                        },\n                        tapEnabled = isSelectionMode,\n                        onTap = onItemClick,\n                        onLongTap = onItemLongClick\n                    ),\n                verticalArrangement = Arrangement.spacedBy(\n                    space = spacing,\n                    alignment = if (isContentAlignToCenter) Alignment.CenterVertically\n                    else Alignment.Top\n                ),\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = spacing,\n                    alignment = if (isContentAlignToCenter) Alignment.CenterHorizontally\n                    else Alignment.Start\n                ),\n                contentPadding = contentPadding,\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                itemsIndexed(\n                    items = imageUris,\n                    key = { index, uri -> \"$uri-${index + 1}\" }\n                ) { index, uri ->\n                    val selected by remember(index, privateSelectedItems.value) {\n                        derivedStateOf {\n                            index + 1 in privateSelectedItems.value\n                        }\n                    }\n                    ImageItem(\n                        selected = selected,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .aspectRatio(1f),\n                        index = index,\n                        uri = uri,\n                        onError = onError,\n                        isAboveImageScrimEnabled = isAboveImageScrimEnabled,\n                        isSelectionMode = isSelectionMode,\n                        aboveImageContent = aboveImageContent,\n                        showExtension = showExtension,\n                        contentScale = contentScale\n                    )\n                }\n                endAdditionalItem?.let {\n                    item {\n                        endAdditionalItem()\n                    }\n                }\n                item {\n                    AnimatedVisibility(isLoadingImages) {\n                        Box(\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .aspectRatio(1f),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            EnhancedLoadingIndicator()\n                        }\n                    }\n                }\n            }\n        } else {\n            LazyVerticalGrid(\n                columns = GridCells.Adaptive(verticalCellSize),\n                state = state,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .dragHandler(\n                        key = enableSelection to imageUris,\n                        lazyGridState = state,\n                        isVertical = true,\n                        selectedItems = if (enableSelection) {\n                            privateSelectedItems\n                        } else {\n                            remember { mutableStateOf(emptySet()) }\n                        },\n                        onSelectionChange = {\n                            onFrameSelectionChange(ImageFrames.ManualSelection(it.toList()))\n                        },\n                        tapEnabled = isSelectionMode,\n                        onTap = onItemClick,\n                        onLongTap = {\n                            if (enableSelection) onItemLongClick(it) else onItemClick(it)\n                        }\n                    ),\n                verticalArrangement = Arrangement.spacedBy(\n                    space = spacing,\n                    alignment = if (isContentAlignToCenter) Alignment.CenterVertically\n                    else Alignment.Top\n                ),\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = spacing,\n                    alignment = if (isContentAlignToCenter) Alignment.CenterHorizontally\n                    else Alignment.Start\n                ),\n                contentPadding = contentPadding,\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                itemsIndexed(\n                    items = imageUris,\n                    key = { index, uri -> \"$uri-${index + 1}\" }\n                ) { index, uri ->\n                    val selected by remember(index, privateSelectedItems.value) {\n                        derivedStateOf {\n                            index + 1 in privateSelectedItems.value\n                        }\n                    }\n                    ImageItem(\n                        selected = selected,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .aspectRatio(1f),\n                        index = index,\n                        uri = uri,\n                        onError = onError,\n                        aboveImageContent = aboveImageContent,\n                        isSelectionMode = isSelectionMode,\n                        isAboveImageScrimEnabled = isAboveImageScrimEnabled,\n                        showExtension = showExtension,\n                        contentScale = contentScale\n                    )\n                }\n                endAdditionalItem?.let {\n                    item {\n                        endAdditionalItem()\n                    }\n                }\n                item {\n                    AnimatedVisibility(isLoadingImages) {\n                        Box(\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .aspectRatio(1f),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            EnhancedLoadingIndicator()\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun ImageItem(\n    modifier: Modifier,\n    uri: Any,\n    index: Int,\n    onError: (String) -> Unit,\n    selected: Boolean,\n    isSelectionMode: Boolean,\n    isAboveImageScrimEnabled: Boolean,\n    showExtension: Boolean,\n    aboveImageContent: @Composable BoxScope.(index: Int) -> Unit,\n    contentScale: ContentScale\n) {\n    val extracted = remember(uri) {\n        uri.extractUri()\n    }\n    val transition = updateTransition(selected)\n    val padding by transition.animateDp { s ->\n        if (s) 10.dp else 0.dp\n    }\n    val corners by transition.animateDp { s ->\n        if (s) 16.dp else 0.dp\n    }\n    val bgColor = MaterialTheme.colorScheme.secondaryContainer\n\n    val shape = AutoCornersShape(corners)\n\n    Box(\n        modifier\n            .clip(ShapeDefaults.extraSmall)\n            .background(bgColor)\n    ) {\n        Picture(\n            modifier = Modifier\n                .matchParentSize()\n                .padding(padding)\n                .clip(shape)\n                .background(MaterialTheme.colorScheme.surface),\n            onError = extracted?.let {\n                { onError(extracted.toString()) }\n            },\n            error = {\n                Box(\n                    contentAlignment = Alignment.Center,\n                    modifier = Modifier.background(\n                        takeColorFromScheme { isNightMode ->\n                            errorContainer.copy(\n                                if (isNightMode) 0.25f\n                                else 1f\n                            ).compositeOver(surface)\n                        }\n                    )\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.BrokenImageAlt,\n                        contentDescription = null,\n                        modifier = Modifier.fillMaxSize(0.5f),\n                        tint = MaterialTheme.colorScheme.onErrorContainer.copy(0.8f)\n                    )\n                }\n            },\n            filterQuality = FilterQuality.High,\n            shape = RectangleShape,\n            model = uri,\n            contentScale = contentScale\n        )\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(padding)\n                .clip(shape)\n                .then(\n                    if (isAboveImageScrimEnabled) {\n                        Modifier.background(MaterialTheme.colorScheme.scrim.copy(0.32f))\n                    } else Modifier\n                ),\n            contentAlignment = Alignment.Center,\n            content = {\n                aboveImageContent(index)\n\n                if (showExtension && extracted != null) {\n                    val extension = rememberFileExtension(extracted)?.uppercase()\n                    val humanFileSize = rememberHumanFileSize(extracted)\n\n                    extension?.let {\n                        Row(\n                            modifier = Modifier\n                                .align(Alignment.TopEnd)\n                                .padding(8.dp)\n                                .padding(vertical = 2.dp)\n                                .advancedShadow(\n                                    cornersRadius = 4.dp,\n                                    shadowBlurRadius = 6.dp,\n                                    alpha = 0.4f\n                                )\n                                .padding(horizontal = 2.dp),\n                            horizontalArrangement = Arrangement.End,\n                            verticalAlignment = Alignment.CenterVertically\n                        ) {\n                            Text(\n                                modifier = Modifier,\n                                text = it,\n                                style = MaterialTheme.typography.labelMedium,\n                                color = White\n                            )\n                        }\n                    }\n\n                    Row(\n                        modifier = Modifier\n                            .align(Alignment.BottomStart)\n                            .padding(8.dp)\n                            .padding(vertical = 2.dp)\n                            .advancedShadow(\n                                cornersRadius = 4.dp,\n                                shadowBlurRadius = 6.dp,\n                                alpha = 0.4f\n                            )\n                            .padding(horizontal = 2.dp),\n                        horizontalArrangement = Arrangement.End,\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        Text(\n                            modifier = Modifier,\n                            text = humanFileSize,\n                            style = MaterialTheme.typography.labelMedium,\n                            color = White\n                        )\n                    }\n                }\n            }\n        )\n        AnimatedContent(\n            targetState = selected to isSelectionMode,\n            transitionSpec = {\n                fadeIn() + scaleIn() togetherWith fadeOut() + scaleOut()\n            }\n        ) { (selected, isSelectionMode) ->\n            if (isSelectionMode) {\n                if (selected) {\n                    Icon(\n                        imageVector = Icons.Filled.CheckCircle,\n                        tint = MaterialTheme.colorScheme.primary,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .padding(4.dp)\n                            .border(2.dp, bgColor, ShapeDefaults.circle)\n                            .clip(ShapeDefaults.circle)\n                            .background(bgColor)\n                    )\n                } else {\n                    Icon(\n                        imageVector = Icons.Filled.RadioButtonUnchecked,\n                        tint = Color.White.copy(alpha = 0.7f),\n                        contentDescription = null,\n                        modifier = Modifier.padding(6.dp)\n                    )\n                }\n            }\n        }\n    }\n}\n\nprivate fun Any.extractUri() = (this as? String)?.toUri() ?: this as? Uri"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/MetadataPreviewButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.toMap\nimport com.t8rin.imagetoolbox.core.domain.utils.humanFileSize\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.theme.onSecondaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.theme.secondaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.localizedName\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberImageMetadataAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextFieldColors\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.dateAdded\nimport com.t8rin.imagetoolbox.core.utils.fileSize\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.core.utils.lastModified\nimport com.t8rin.imagetoolbox.core.utils.path\n\n@Composable\nfun MetadataPreviewButton(\n    uri: Uri?,\n    dateModified: (Uri) -> Long? = { it.lastModified() },\n    dateAdded: (Uri) -> Long? = { it.dateAdded() },\n    path: (Uri) -> String? = { it.path() },\n    name: (Uri) -> String? = { it.filename() },\n    fileSize: (Uri) -> String? = { humanFileSize(it.fileSize() ?: 0L) }\n) {\n    AnimatedContent(\n        targetState = uri\n    ) { uri ->\n        val metadata by rememberImageMetadataAsState(\n            uri ?: return@AnimatedContent\n        )\n        val tagMap by remember(metadata) {\n            derivedStateOf {\n                metadata?.toMap().orEmpty().toList()\n                    .filter { it.second.isNotBlank() }\n            }\n        }\n        val info by remember(uri, dateModified, dateAdded, path, name, fileSize) {\n            derivedStateOf {\n                UriInfo(\n                    dateModified = dateModified(uri),\n                    dateAdded = dateAdded(uri),\n                    path = path(uri),\n                    name = name(uri),\n                    fileSize = fileSize(uri)\n                )\n            }\n        }\n        if (tagMap.isNotEmpty() || info.data.isNotEmpty()) {\n            var showExif by rememberSaveable {\n                mutableStateOf(false)\n            }\n            SupportingButton(\n                onClick = { showExif = true },\n                contentColor = MaterialTheme.colorScheme.onSecondaryContainerFixed,\n                containerColor = MaterialTheme.colorScheme.secondaryContainerFixed,\n                style = MaterialTheme.typography.labelMedium,\n                modifier = Modifier\n                    .padding(start = 4.dp)\n                    .size(20.dp),\n                iconPadding = 2.dp\n            )\n            EnhancedModalBottomSheet(\n                visible = showExif,\n                onDismiss = { showExif = false },\n                title = {\n                    TitleItem(\n                        text = stringResource(R.string.exif),\n                        icon = Icons.Rounded.Exif\n                    )\n                },\n                confirmButton = {\n                    EnhancedButton(\n                        onClick = { showExif = false }\n                    ) {\n                        Text(text = stringResource(R.string.close))\n                    }\n                },\n            ) {\n                LazyColumn(\n                    contentPadding = PaddingValues(16.dp),\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    itemsIndexed(info.data) { index, (name, value) ->\n                        ValueField(\n                            label = stringResource(name),\n                            value = value,\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = info.data.size\n                            )\n                        )\n                    }\n\n                    if (info.data.isNotEmpty() && tagMap.isNotEmpty()) {\n                        item { Spacer(Modifier.height(4.dp)) }\n                    }\n\n                    itemsIndexed(tagMap) { index, (tag, value) ->\n                        ValueField(\n                            label = tag.localizedName,\n                            value = value,\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = tagMap.size\n                            )\n                        )\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun ValueField(\n    label: String,\n    value: String,\n    shape: Shape\n) {\n    RoundedTextField(\n        onValueChange = {},\n        readOnly = true,\n        value = value,\n        label = label,\n        textStyle = LocalTextStyle.current.copy(\n            fontSize = 16.sp,\n            fontWeight = FontWeight.Bold\n        ),\n        colors = RoundedTextFieldColors(\n            isError = false,\n            containerColor = EnhancedBottomSheetDefaults.contentContainerColor,\n            unfocusedIndicatorColor = Color.Transparent\n        ).copy(\n            unfocusedLabelColor = MaterialTheme.colorScheme\n                .surfaceVariant.inverse({ 0.3f })\n        ),\n        singleLine = false,\n        maxLines = Int.MAX_VALUE,\n        shape = shape,\n        modifier = Modifier\n            .fillMaxWidth()\n            .container(\n                color = EnhancedBottomSheetDefaults.contentContainerColor,\n                shape = shape,\n                resultPadding = 0.dp\n            )\n    )\n}\n\nprivate data class UriInfo(\n    val dateModified: Long?,\n    val dateAdded: Long?,\n    val path: String?,\n    val name: String?,\n    val fileSize: String?\n) {\n    val data: List<Pair<Int, String>> = buildList {\n        name?.takeIf { it.isNotBlank() }?.let {\n            add(R.string.filename to it)\n        }\n\n        fileSize?.takeIf { it.isNotBlank() }?.let {\n            add(R.string.file_size to it)\n        }\n\n        val dateAddedFormatted = dateAdded?.takeIf { it > 0 }?.let {\n            timestamp(\n                format = \"d MMMM, yyyy • HH:mm\",\n                date = it\n            )\n        }\n\n        val dateModifiedFormatted = dateModified?.takeIf { it > 0 }?.let {\n            timestamp(\n                format = \"d MMMM, yyyy • HH:mm\",\n                date = it\n            )\n        }\n\n        if (dateModifiedFormatted != dateAddedFormatted) {\n            dateModifiedFormatted?.let {\n                add(R.string.sort_by_date_modified to it)\n            }\n        }\n\n        dateAddedFormatted?.let {\n            add(R.string.sort_by_date_added to it)\n        }\n\n        path?.takeIf { it.isNotBlank() }\n            ?.removeSuffix(\"/$name\")\n            ?.removeSuffix(\"/${name?.substringBeforeLast('.')}\")\n            ?.let {\n                add(R.string.path to it)\n            }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/Picture.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.content.pm.ActivityInfo\nimport android.graphics.Bitmap\nimport android.os.Build\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.DefaultAlpha\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalInspectionMode\nimport coil3.SingletonImageLoader\nimport coil3.compose.AsyncImageModelEqualityDelegate\nimport coil3.compose.AsyncImagePainter\nimport coil3.compose.LocalAsyncImageModelEqualityDelegate\nimport coil3.compose.LocalPlatformContext\nimport coil3.compose.SubcomposeAsyncImage\nimport coil3.compose.SubcomposeAsyncImageScope\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.request.allowHardware\nimport coil3.request.crossfade\nimport coil3.request.transformations\nimport coil3.toBitmap\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.GenericTransformation\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.findActivity\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toCoil\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.withContext\n\n@Composable\nfun Picture(\n    model: Any?,\n    modifier: Modifier = Modifier,\n    transformations: List<Transformation>? = null,\n    contentDescription: String? = null,\n    shape: Shape = RectangleShape,\n    contentScale: ContentScale = if (model.isCompose()) ContentScale.Fit else ContentScale.Crop,\n    loading: @Composable (SubcomposeAsyncImageScope.(AsyncImagePainter.State.Loading) -> Unit)? = null,\n    success: @Composable (SubcomposeAsyncImageScope.(AsyncImagePainter.State.Success) -> Unit)? = null,\n    error: @Composable (SubcomposeAsyncImageScope.(AsyncImagePainter.State.Error) -> Unit)? = null,\n    onLoading: ((AsyncImagePainter.State.Loading) -> Unit)? = null,\n    onSuccess: ((AsyncImagePainter.State.Success) -> Unit)? = null,\n    onError: ((AsyncImagePainter.State.Error) -> Unit)? = null,\n    onState: ((AsyncImagePainter.State) -> Unit)? = null,\n    alignment: Alignment = Alignment.Center,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = if (model is ImageVector) {\n        ColorFilter.tint(LocalContentColor.current)\n    } else null,\n    filterQuality: FilterQuality = FilterQuality.None,\n    shimmerEnabled: Boolean = true,\n    crossfadeEnabled: Boolean = true,\n    allowHardware: Boolean = true,\n    showTransparencyChecker: Boolean = true,\n    isLoadingFromDifferentPlace: Boolean = false,\n    enableUltraHDRSupport: Boolean = false,\n    size: Int? = null,\n    contentPadding: PaddingValues = PaddingValues()\n) {\n    CompositionLocalProvider(\n        LocalAsyncImageModelEqualityDelegate provides AsyncImageModelEqualityDelegate.AllProperties\n    ) {\n        when (model) {\n            is ImageBitmap -> {\n                Image(\n                    bitmap = model,\n                    contentDescription = contentDescription,\n                    modifier = modifier,\n                    alignment = alignment,\n                    contentScale = contentScale,\n                    alpha = alpha,\n                    colorFilter = colorFilter,\n                    filterQuality = filterQuality\n                )\n            }\n\n            is Painter -> {\n                Image(\n                    painter = model,\n                    contentDescription = contentDescription,\n                    modifier = modifier,\n                    alignment = alignment,\n                    contentScale = contentScale,\n                    alpha = alpha,\n                    colorFilter = colorFilter\n                )\n            }\n\n            is ImageVector -> {\n                Image(\n                    imageVector = model,\n                    contentDescription = contentDescription ?: model.name,\n                    modifier = modifier,\n                    alignment = alignment,\n                    contentScale = contentScale,\n                    alpha = alpha,\n                    colorFilter = colorFilter\n                )\n            }\n\n            else -> {\n                CoilPicture(\n                    model = model,\n                    modifier = modifier,\n                    transformations = transformations,\n                    contentDescription = contentDescription,\n                    shape = shape,\n                    contentScale = contentScale,\n                    loading = loading,\n                    success = success,\n                    error = error,\n                    onLoading = onLoading,\n                    onSuccess = onSuccess,\n                    onError = onError,\n                    onState = onState,\n                    alignment = alignment,\n                    alpha = alpha,\n                    colorFilter = colorFilter,\n                    filterQuality = filterQuality,\n                    shimmerEnabled = shimmerEnabled,\n                    crossfadeEnabled = crossfadeEnabled,\n                    allowHardware = allowHardware,\n                    showTransparencyChecker = showTransparencyChecker,\n                    isLoadingFromDifferentPlace = isLoadingFromDifferentPlace,\n                    enableUltraHDRSupport = enableUltraHDRSupport,\n                    size = size,\n                    contentPadding = contentPadding\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun CoilPicture(\n    model: Any?,\n    modifier: Modifier,\n    transformations: List<Transformation>?,\n    contentDescription: String?,\n    shape: Shape,\n    contentScale: ContentScale,\n    loading: @Composable (SubcomposeAsyncImageScope.(AsyncImagePainter.State.Loading) -> Unit)?,\n    success: @Composable (SubcomposeAsyncImageScope.(AsyncImagePainter.State.Success) -> Unit)?,\n    error: @Composable (SubcomposeAsyncImageScope.(AsyncImagePainter.State.Error) -> Unit)?,\n    onLoading: ((AsyncImagePainter.State.Loading) -> Unit)?,\n    onSuccess: ((AsyncImagePainter.State.Success) -> Unit)?,\n    onError: ((AsyncImagePainter.State.Error) -> Unit)?,\n    onState: ((AsyncImagePainter.State) -> Unit)?,\n    alignment: Alignment,\n    alpha: Float,\n    colorFilter: ColorFilter?,\n    filterQuality: FilterQuality,\n    shimmerEnabled: Boolean,\n    crossfadeEnabled: Boolean,\n    allowHardware: Boolean,\n    showTransparencyChecker: Boolean,\n    isLoadingFromDifferentPlace: Boolean,\n    enableUltraHDRSupport: Boolean,\n    size: Int?,\n    contentPadding: PaddingValues = PaddingValues()\n) {\n    val context = LocalContext.current\n\n    var errorOccurred by rememberSaveable { mutableStateOf(false) }\n\n    var shimmerVisible by rememberSaveable { mutableStateOf(true) }\n\n    val imageLoader = context.imageLoader\n\n    val hdrTransformation = remember(context) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && enableUltraHDRSupport) {\n            listOf(\n                GenericTransformation<Bitmap> { bitmap ->\n                    withContext(Dispatchers.Main.immediate) {\n                        delay(1000)\n                        context.findActivity()?.window?.colorMode = if (bitmap.hasGainmap()) {\n                            ActivityInfo.COLOR_MODE_HDR\n                        } else ActivityInfo.COLOR_MODE_DEFAULT\n                    }\n                    bitmap\n                }.toCoil()\n            )\n        } else emptyList()\n    }\n\n    val request = model as? ImageRequest\n        ?: remember(\n            context,\n            model,\n            crossfadeEnabled,\n            allowHardware,\n            transformations,\n            hdrTransformation,\n            size\n        ) {\n            ImageRequest.Builder(context)\n                .data(model)\n                .crossfade(crossfadeEnabled)\n                .allowHardware(allowHardware)\n                .transformations(\n                    (transformations ?: emptyList()) + hdrTransformation\n                )\n                .apply {\n                    size?.let { size(it) }\n                }\n                .build()\n        }\n\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && enableUltraHDRSupport) {\n        DisposableEffect(model) {\n            onDispose {\n                context.findActivity()?.window?.colorMode = ActivityInfo.COLOR_MODE_DEFAULT\n            }\n        }\n    }\n\n    SubcomposeAsyncImage(\n        model = request,\n        imageLoader = if (LocalInspectionMode.current) {\n            SingletonImageLoader.get(LocalPlatformContext.current)\n        } else imageLoader,\n        contentDescription = contentDescription,\n        modifier = modifier\n            .clip(shape)\n            .then(\n                if (!LocalInspectionMode.current) {\n                    Modifier\n                        .then(if (showTransparencyChecker) Modifier.transparencyChecker() else Modifier)\n                        .then(if (shimmerEnabled) Modifier.shimmer(shimmerVisible || isLoadingFromDifferentPlace) else Modifier)\n                } else {\n                    Modifier\n                }\n            )\n            .padding(contentPadding),\n        contentScale = contentScale,\n        loading = {\n            if (loading != null) loading(it)\n            shimmerVisible = true\n        },\n        success = success,\n        error = error,\n        onSuccess = {\n            if (model is ImageRequest && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && enableUltraHDRSupport) {\n                context.findActivity()?.window?.colorMode =\n                    if (it.result.image.toBitmap(400, 400).hasGainmap()) {\n                        ActivityInfo.COLOR_MODE_HDR\n                    } else ActivityInfo.COLOR_MODE_DEFAULT\n            }\n            shimmerVisible = false\n            onSuccess?.invoke(it)\n            onState?.invoke(it)\n        },\n        onLoading = {\n            onLoading?.invoke(it)\n            onState?.invoke(it)\n        },\n        onError = {\n            if (error != null) shimmerVisible = false\n            onError?.invoke(it)\n            onState?.invoke(it)\n            errorOccurred = true\n        },\n        alignment = alignment,\n        alpha = alpha,\n        colorFilter = colorFilter,\n        filterQuality = filterQuality\n    )\n\n    //Needed for triggering recomposition\n    LaunchedEffect(errorOccurred) {\n        if (errorOccurred && error == null) {\n            shimmerVisible = false\n            shimmerVisible = true\n            errorOccurred = false\n        }\n    }\n}\n\nprivate fun Any?.isCompose(): Boolean =\n    this is Painter || this is ImageVector || this is ImageBitmap"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/SimplePicture.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\nfun SimplePicture(\n    bitmap: Bitmap?,\n    modifier: Modifier = Modifier,\n    scale: ContentScale = ContentScale.Fit,\n    boxModifier: Modifier = Modifier,\n    enableContainer: Boolean = true,\n    loading: Boolean = false,\n    visible: Boolean = true\n) {\n    bitmap?.asImageBitmap()\n        ?.takeIf { visible }\n        ?.let {\n            Box(\n                modifier = boxModifier\n                    .then(\n                        if (enableContainer) {\n                            Modifier\n                                .container()\n                                .padding(4.dp)\n                        } else Modifier\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                Picture(\n                    model = it,\n                    contentScale = scale,\n                    contentDescription = null,\n                    modifier = modifier\n                        .aspectRatio(\n                            it.safeAspectRatio\n                        )\n                        .clip(MaterialTheme.shapes.medium)\n                        .transparencyChecker()\n                        .shimmer(loading)\n                )\n            }\n        }\n}\n\n//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {\n//    val activity = LocalComponentActivity.current\n//    DisposableEffect(it) {\n//        activity.window.colorMode = if (bitmap.hasGainmap()) {\n//            ActivityInfo.COLOR_MODE_HDR\n//        } else ActivityInfo.COLOR_MODE_DEFAULT\n//        onDispose {\n//            activity.window.colorMode = ActivityInfo.COLOR_MODE_DEFAULT\n//        }\n//    }\n//}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/UrisCarousel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastForEach\nimport coil3.request.ImageRequest\nimport coil3.request.crossfade\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedHorizontalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport kotlin.math.roundToInt\nimport kotlin.random.Random\n\n@Composable\ninternal fun UrisCarousel(uris: List<Uri>) {\n    Row(\n        horizontalArrangement = Arrangement.spacedBy(\n            4.dp,\n            Alignment.CenterHorizontally\n        ),\n        verticalAlignment = Alignment.CenterVertically,\n        modifier = Modifier\n            .fillMaxWidth()\n            .layout { measurable, constraints ->\n                val placeable = measurable.measure(\n                    constraints.copy(\n                        maxWidth = constraints.maxWidth + 32.dp.roundToPx(),\n                        maxHeight = (constraints.maxWidth * 0.5f)\n                            .coerceAtLeast(100f)\n                            .coerceAtMost(constraints.maxHeight * 0.5f)\n                            .roundToInt()\n                    )\n                )\n\n                layout(\n                    placeable.width,\n                    placeable.height\n                ) {\n                    placeable.place(0, 0)\n                }\n            }\n            .enhancedHorizontalScroll(rememberScrollState())\n            .padding(\n                PaddingValues(\n                    start = 16.dp,\n                    end = 16.dp,\n                    bottom = 16.dp\n                )\n            )\n    ) {\n        uris.fastForEach { uri ->\n            val key = rememberSaveable(uri) { \"$uri${Random.nextInt()}\" }\n            var aspectRatio by rememberSaveable {\n                mutableFloatStateOf(0.5f)\n            }\n            Picture(\n                model = remember(uri, key) {\n                    ImageRequest.Builder(appContext)\n                        .data(uri)\n                        .size(1000)\n                        .crossfade(true)\n                        .memoryCacheKey(key)\n                        .diskCacheKey(key)\n                        .build()\n                },\n                onSuccess = {\n                    aspectRatio = it.result.image.safeAspectRatio\n                },\n                modifier = Modifier\n                    .animateContentSizeNoClip()\n                    .fillMaxHeight()\n                    .aspectRatio(\n                        ratio = aspectRatio,\n                        matchHeightConstraintsFirst = true\n                    )\n                    .container(\n                        shape = MaterialTheme.shapes.medium,\n                        resultPadding = 0.dp\n                    ),\n                shape = RectangleShape,\n                contentScale = ContentScale.Fit\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/image/UrisPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.image\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.InsertDriveFile\nimport androidx.compose.material.icons.automirrored.rounded.NoteAdd\nimport androidx.compose.material.icons.rounded.RemoveCircleOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.shareUris\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun UrisPreview(\n    modifier: Modifier = Modifier,\n    uris: List<Uri>,\n    isPortrait: Boolean,\n    onRemoveUri: ((Uri) -> Unit)?,\n    onAddUris: (() -> Unit)?,\n    isAddUrisVisible: Boolean = true,\n    addUrisContent: @Composable BoxScope.(width: Dp) -> Unit = { width ->\n        Icon(\n            imageVector = Icons.AutoMirrored.Rounded.NoteAdd,\n            contentDescription = stringResource(R.string.add),\n            modifier = Modifier.size(width / 3f)\n        )\n    },\n    onClickUri: ((Uri) -> Unit)? = null,\n    errorContent: @Composable BoxScope.(index: Int, width: Dp) -> Unit = { _, width ->\n        Icon(\n            imageVector = Icons.AutoMirrored.Outlined.InsertDriveFile,\n            contentDescription = null,\n            modifier = Modifier\n                .size(width / 3f)\n                .align(Alignment.Center),\n            tint = MaterialTheme.colorScheme.primary\n        )\n    },\n    showTransparencyChecker: Boolean = true,\n    showScrimForNonSuccess: Boolean = true,\n    filenameSource: (index: Int) -> Uri = { uris[it] },\n    onNavigate: ((Screen) -> Unit)? = null\n) {\n    var previewUri by rememberSaveable {\n        mutableStateOf<Uri?>(null)\n    }\n\n    BoxWithConstraints {\n        val size = uris.size + 1f\n\n        val count = if (isPortrait) {\n            size.coerceAtLeast(2f).coerceAtMost(3f)\n        } else {\n            size.coerceAtLeast(2f).coerceAtMost(8f)\n        }\n\n        val width = this.maxWidth / count - 4.dp * (count - 1)\n\n        FlowRow(\n            modifier = modifier,\n            horizontalArrangement = Arrangement.spacedBy(4.dp),\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n        ) {\n            uris.forEachIndexed { index, uri ->\n                if (uri != Uri.EMPTY) {\n                    Box(\n                        modifier = Modifier.container(\n                            shape = ShapeDefaults.extraSmall,\n                            resultPadding = 0.dp,\n                            color = MaterialTheme.colorScheme.surfaceContainerHighest\n                        )\n                    ) {\n                        var isLoaded by remember(uri) {\n                            mutableStateOf(false)\n                        }\n                        Picture(\n                            model = uri,\n                            error = {\n                                Box(\n                                    contentAlignment = Alignment.Center,\n                                    content = {\n                                        errorContent(index, width)\n                                    }\n                                )\n                            },\n                            onSuccess = { isLoaded = true },\n                            modifier = Modifier\n                                .then(\n                                    if (onClickUri != null) {\n                                        Modifier.hapticsClickable {\n                                            onClickUri(uri)\n                                        }\n                                    } else {\n                                        Modifier.hapticsClickable {\n                                            previewUri = uri\n                                        }\n                                    }\n                                )\n                                .width(width)\n                                .aspectRatio(1f),\n                            showTransparencyChecker = showTransparencyChecker\n                        )\n                        Box(\n                            modifier = Modifier\n                                .matchParentSize()\n                                .background(\n                                    takeColorFromScheme {\n                                        scrim.copy(\n                                            if (isLoaded || showScrimForNonSuccess) 0.5f\n                                            else 0f\n                                        )\n                                    }\n                                )\n                        ) {\n                            Text(\n                                text = (index + 1).toString(),\n                                color = Color.White,\n                                fontSize = 24.sp,\n                                fontWeight = FontWeight.Medium,\n                                modifier = Modifier\n                                    .padding(8.dp)\n                                    .align(Alignment.TopStart)\n                            )\n                            if (onRemoveUri != null) {\n                                Icon(\n                                    imageVector = Icons.Rounded.RemoveCircleOutline,\n                                    contentDescription = stringResource(R.string.remove),\n                                    modifier = Modifier\n                                        .padding(4.dp)\n                                        .clip(ShapeDefaults.circle)\n                                        .background(\n                                            MaterialTheme.colorScheme.scrim.copy(\n                                                animateFloatAsState(if (uris.size > 1) 0.2f else 0f).value\n                                            )\n                                        )\n                                        .hapticsClickable(\n                                            enabled = uris.size > 1\n                                        ) {\n                                            onRemoveUri(uri)\n                                        }\n                                        .padding(4.dp)\n                                        .align(Alignment.TopEnd),\n                                    tint = Color.White.copy(\n                                        animateFloatAsState(if (uris.size > 1) 0.7f else 0f).value\n                                    ),\n                                )\n                            }\n                            val filename = rememberFilename(filenameSource(index))\n\n                            filename?.let {\n                                AutoSizeText(\n                                    text = it,\n                                    style = LocalTextStyle.current.copy(\n                                        color = Color.White,\n                                        fontSize = 11.sp,\n                                        lineHeight = 12.sp,\n                                        fontWeight = FontWeight.Medium,\n                                        textAlign = TextAlign.End\n                                    ),\n                                    maxLines = 3,\n                                    modifier = Modifier\n                                        .padding(8.dp)\n                                        .align(Alignment.BottomEnd)\n                                )\n                            }\n                        }\n                    }\n                } else {\n                    AnimatedVisibility(visible = isAddUrisVisible) {\n                        Box(\n                            modifier = Modifier\n                                .container(\n                                    shape = ShapeDefaults.extraSmall,\n                                    resultPadding = 0.dp,\n                                    color = MaterialTheme.colorScheme.surfaceContainerHigh\n                                )\n                                .width(width)\n                                .aspectRatio(1f)\n                                .then(\n                                    if (onAddUris != null) {\n                                        Modifier.hapticsClickable(onClick = onAddUris)\n                                    } else Modifier\n                                ),\n                            contentAlignment = Alignment.Center,\n                            content = {\n                                addUrisContent(width)\n                            }\n                        )\n                    }\n                }\n            }\n        }\n    }\n\n    if (onClickUri == null && onNavigate != null) {\n        val context = LocalContext.current\n        ImagePager(\n            visible = previewUri != null,\n            selectedUri = previewUri,\n            uris = uris,\n            onNavigate = onNavigate,\n            onUriSelected = { previewUri = it },\n            onShare = { context.shareUris(listOf(it)) },\n            onDismiss = { previewUri = null }\n        )\n    }\n}\n\nfun Modifier.urisPreview(\n    scrollState: ScrollState? = null\n): Modifier = this.composed {\n    val isPortrait by isPortraitOrientationAsState()\n\n    if (!isPortrait) {\n        Modifier\n            .layout { measurable, constraints ->\n                val placeable = measurable.measure(\n                    constraints = constraints.copy(\n                        maxHeight = constraints.maxHeight + 48.dp.roundToPx()\n                    )\n                )\n                layout(placeable.width, placeable.height) {\n                    placeable.place(0, 0)\n                }\n            }\n            .enhancedVerticalScroll(scrollState ?: rememberScrollState())\n    } else {\n        Modifier\n    }.padding(vertical = 24.dp)\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/AdvancedShadow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.drawscope.drawIntoCanvas\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\n\nfun Modifier.advancedShadow(\n    color: Color = Color.Black,\n    alpha: Float = 1f,\n    cornersRadius: Dp = 0.dp,\n    shadowBlurRadius: Dp = 0.dp,\n    offsetY: Dp = 0.dp,\n    offsetX: Dp = 0.dp\n) = drawBehind {\n\n    val shadowColor = color.copy(alpha = alpha).toArgb()\n    val transparentColor = color.copy(alpha = 0f).toArgb()\n\n    drawIntoCanvas {\n        val paint = Paint()\n        val frameworkPaint = paint.nativePaint\n        frameworkPaint.color = transparentColor\n        frameworkPaint.setShadowLayer(\n            shadowBlurRadius.toPx(),\n            offsetX.toPx(),\n            offsetY.toPx(),\n            shadowColor\n        )\n        it.drawRoundRect(\n            0f,\n            0f,\n            this.size.width,\n            this.size.height,\n            cornersRadius.toPx(),\n            cornersRadius.toPx(),\n            paint\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/AlertDialogBorder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.material3.AlertDialogDefaults\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\n\nfun Modifier.alertDialogBorder() = this.composed {\n    Modifier\n        .autoElevatedBorder(\n            color = MaterialTheme.colorScheme.outlineVariant(\n                luminance = 0.15f,\n                onTopOf = MaterialTheme.colorScheme.surfaceContainerHigh\n            ),\n            shape = AlertDialogDefaults.shape,\n            autoElevation = animateDpAsState(\n                if (LocalSettingsState.current.drawContainerShadows) 16.dp\n                else 0.dp\n            ).value\n        )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/AnimateContentSizeNoClip.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationEndReason\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.AnimationVector2D\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.VectorConverter\nimport androidx.compose.animation.core.spring\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.layout.IntrinsicMeasurable\nimport androidx.compose.ui.layout.IntrinsicMeasureScope\nimport androidx.compose.ui.layout.LayoutModifier\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.node.LayoutModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.constrain\nimport kotlinx.coroutines.launch\n\n/**\n * This modifier animates its own size when its child modifier (or the child composable if it\n * is already at the tail of the chain) changes size. This allows the parent modifier to observe\n * a smooth size change, resulting in an overall continuous visual change.\n *\n * A [FiniteAnimationSpec] can be optionally specified for the size change animation. By default,\n * [spring] will be used.\n *\n * An optional [finishedListener] can be supplied to get notified when the size change animation is\n * finished. Since the content size change can be dynamic in many cases, both initial value and\n * target value (i.e. final size) will be passed to the [finishedListener]. __Note:__ if the\n * animation is interrupted, the initial value will be the size at the point of interruption. This\n * is intended to help determine the direction of the size change (i.e. expand or collapse in x and\n * y dimensions).\n *\n * @sample androidx.compose.animation.samples.AnimateContent\n *\n * @param animationSpec a finite animation that will be used to animate size change, [spring] by\n *                      default\n * @param finishedListener an optional listener to be called when the content change animation is\n *                         completed.\n */\nfun Modifier.animateContentSizeNoClip(\n    animationSpec: FiniteAnimationSpec<IntSize> = spring(\n        stiffness = Spring.StiffnessMediumLow\n    ),\n    alignment: Alignment = Alignment.TopCenter,\n    isClipped: Boolean = false,\n    finishedListener: ((initialValue: IntSize, targetValue: IntSize) -> Unit)? = null\n): Modifier = this\n    .then(\n        if (isClipped) Modifier.clipToBounds()\n        else Modifier\n    )\n    .then(\n        SizeAnimationModifierElement(\n            animationSpec = animationSpec,\n            alignment = alignment,\n            finishedListener = finishedListener\n        )\n    )\n\nfun Modifier.animateContentSizeNoClip(\n    animationSpec: FiniteAnimationSpec<IntSize> = spring(\n        stiffness = Spring.StiffnessMediumLow\n    ),\n    alignment: Alignment = Alignment.TopCenter,\n    finishedListener: ((initialValue: IntSize, targetValue: IntSize) -> Unit)? = null\n) = this\n    .clipToBounds()\n    .then(\n        SizeAnimationModifierElement(\n            animationSpec = animationSpec,\n            alignment = alignment,\n            finishedListener = finishedListener\n        )\n    )\n\nprivate data class SizeAnimationModifierElement(\n    val animationSpec: FiniteAnimationSpec<IntSize>,\n    val alignment: Alignment,\n    val finishedListener: ((initialValue: IntSize, targetValue: IntSize) -> Unit)?\n) : ModifierNodeElement<SizeAnimationModifierNode>() {\n    override fun create(): SizeAnimationModifierNode = SizeAnimationModifierNode(\n        animationSpec = animationSpec,\n        alignment = alignment,\n        listener = finishedListener\n    )\n\n    override fun update(node: SizeAnimationModifierNode) {\n        node.animationSpec = animationSpec\n        node.listener = finishedListener\n        node.alignment = alignment\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"animateContentSizeNoClip\"\n        properties[\"animationSpec\"] = animationSpec\n        properties[\"alignment\"] = alignment\n        properties[\"finishedListener\"] = finishedListener\n    }\n}\n\ninternal val InvalidSize = IntSize(Int.MIN_VALUE, Int.MIN_VALUE)\ninternal val IntSize.isValid: Boolean\n    get() = this != InvalidSize\n\n/**\n * This class creates a [LayoutModifier] that measures children, and responds to children's size\n * change by animating to that size. The size reported to parents will be the animated size.\n */\nprivate class SizeAnimationModifierNode(\n    var animationSpec: AnimationSpec<IntSize>,\n    var alignment: Alignment = Alignment.TopStart,\n    var listener: ((startSize: IntSize, endSize: IntSize) -> Unit)? = null\n) : LayoutModifierNodeWithPassThroughIntrinsics() {\n    private var lookaheadSize: IntSize = InvalidSize\n    private var lookaheadConstraints: Constraints = Constraints()\n        set(value) {\n            field = value\n            lookaheadConstraintsAvailable = true\n        }\n\n    private var lookaheadConstraintsAvailable: Boolean = false\n\n    private fun targetConstraints(default: Constraints) =\n        if (lookaheadConstraintsAvailable) {\n            lookaheadConstraints\n        } else {\n            default\n        }\n\n    data class AnimData(val anim: Animatable<IntSize, AnimationVector2D>, var startSize: IntSize)\n\n    var animData: AnimData? by mutableStateOf(null)\n\n    override fun onReset() {\n        super.onReset()\n        // Reset is an indication that the node may be re-used, in such case, animData becomes stale\n        animData = null\n    }\n\n    override fun onAttach() {\n        super.onAttach()\n        // When re-attached, we may be attached to a tree without lookahead scope.\n        lookaheadSize = InvalidSize\n        lookaheadConstraintsAvailable = false\n    }\n\n    override fun MeasureScope.measure(\n        measurable: Measurable,\n        constraints: Constraints\n    ): MeasureResult {\n        val placeable =\n            if (isLookingAhead) {\n                lookaheadConstraints = constraints\n                measurable.measure(constraints)\n            } else {\n                // Measure with lookahead constraints when available, to avoid unnecessary relayout\n                // in child during the lookahead animation.\n                measurable.measure(targetConstraints(constraints))\n            }\n        val measuredSize = IntSize(placeable.width, placeable.height)\n        val (width, height) =\n            if (isLookingAhead) {\n                lookaheadSize = measuredSize\n                measuredSize\n            } else {\n                animateTo(if (lookaheadSize.isValid) lookaheadSize else measuredSize).let {\n                    // Constrain the measure result to incoming constraints, so that parent doesn't\n                    // force center this layout.\n                    constraints.constrain(it)\n                }\n            }\n        return layout(width, height) {\n            val offset =\n                alignment.align(\n                    size = measuredSize,\n                    space = IntSize(width, height),\n                    layoutDirection = this@measure.layoutDirection\n                )\n            placeable.place(offset)\n        }\n    }\n\n    fun animateTo(targetSize: IntSize): IntSize {\n        val data =\n            animData?.apply {\n                // TODO(b/322878517): Figure out a way to seamlessly continue the animation after\n                //  re-attach. Note that in some cases restarting the animation is the correct\n                // behavior.\n                val wasInterrupted = (targetSize != anim.value && !anim.isRunning)\n\n                if (targetSize != anim.targetValue || wasInterrupted) {\n                    startSize = anim.value\n                    coroutineScope.launch {\n                        val result = anim.animateTo(targetSize, animationSpec)\n                        if (result.endReason == AnimationEndReason.Finished) {\n                            listener?.invoke(startSize, result.endState.value)\n                        }\n                    }\n                }\n            }\n                ?: AnimData(\n                    Animatable(targetSize, IntSize.VectorConverter, IntSize(1, 1)),\n                    targetSize\n                )\n\n        animData = data\n        return data.anim.value\n    }\n}\n\ninternal abstract class LayoutModifierNodeWithPassThroughIntrinsics :\n    LayoutModifierNode, Modifier.Node() {\n    override fun IntrinsicMeasureScope.minIntrinsicWidth(\n        measurable: IntrinsicMeasurable,\n        height: Int\n    ) = measurable.minIntrinsicWidth(height)\n\n    override fun IntrinsicMeasureScope.minIntrinsicHeight(\n        measurable: IntrinsicMeasurable,\n        width: Int\n    ) = measurable.minIntrinsicHeight(width)\n\n    override fun IntrinsicMeasureScope.maxIntrinsicWidth(\n        measurable: IntrinsicMeasurable,\n        height: Int\n    ) = measurable.maxIntrinsicWidth(height)\n\n    override fun IntrinsicMeasureScope.maxIntrinsicHeight(\n        measurable: IntrinsicMeasurable,\n        width: Int\n    ) = measurable.maxIntrinsicHeight(width)\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/AutoCornersShape.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n\n@file:SuppressLint(\"ComposableNaming\")\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport android.annotation.SuppressLint\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.foundation.shape.CornerBasedShape\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.foundation.shape.CutCornerShape\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.kyant.capsule.Continuity\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport sv.lib.squircleshape.CornerSmoothing\nimport sv.lib.squircleshape.SquircleShape\n\nprivate val continuity = Continuity.Default\nprivate val smoothing = CornerSmoothing.Medium\n\n@Stable\nfun AutoCornersShape(\n    corner: CornerSize,\n    shapesType: ShapeType\n) = AutoCornersShape(\n    topStart = corner,\n    topEnd = corner,\n    bottomEnd = corner,\n    bottomStart = corner,\n    shapesType = shapesType\n)\n\n@Stable\nfun AutoCornersShape(\n    size: Dp,\n    shapesType: ShapeType\n) = AutoCornersShape(\n    corner = CornerSize(size),\n    shapesType = shapesType\n)\n\n@Stable\nfun AutoCornersShape(\n    size: Float,\n    shapesType: ShapeType\n) = AutoCornersShape(\n    corner = CornerSize(size),\n    shapesType = shapesType\n)\n\n@Stable\nfun AutoCornersShape(\n    percent: Int,\n    shapesType: ShapeType\n) = AutoCornersShape(\n    corner = CornerSize(percent),\n    shapesType = shapesType\n)\n\n@Stable\nfun AutoCornersShape(\n    topStart: Dp = 0.dp,\n    topEnd: Dp = 0.dp,\n    bottomEnd: Dp = 0.dp,\n    bottomStart: Dp = 0.dp,\n    shapesType: ShapeType\n) = AutoCornersShape(\n    topStart = CornerSize(topStart),\n    topEnd = CornerSize(topEnd),\n    bottomEnd = CornerSize(bottomEnd),\n    bottomStart = CornerSize(bottomStart),\n    shapesType = shapesType\n)\n\n@Stable\nfun AutoCornersShape(\n    topStart: Float = 0.0f,\n    topEnd: Float = 0.0f,\n    bottomEnd: Float = 0.0f,\n    bottomStart: Float = 0.0f,\n    shapesType: ShapeType\n) = AutoCornersShape(\n    topStart = CornerSize(topStart),\n    topEnd = CornerSize(topEnd),\n    bottomEnd = CornerSize(bottomEnd),\n    bottomStart = CornerSize(bottomStart),\n    shapesType = shapesType\n)\n\n@Stable\nfun AutoCornersShape(\n    topStartPercent: Int = 0,\n    topEndPercent: Int = 0,\n    bottomEndPercent: Int = 0,\n    bottomStartPercent: Int = 0,\n    shapesType: ShapeType\n) = AutoCornersShape(\n    topStart = CornerSize(topStartPercent),\n    topEnd = CornerSize(topEndPercent),\n    bottomEnd = CornerSize(bottomEndPercent),\n    bottomStart = CornerSize(bottomStartPercent),\n    shapesType = shapesType\n)\n\n@Stable\nfun AutoCornersShape(\n    topStart: CornerSize,\n    topEnd: CornerSize,\n    bottomEnd: CornerSize,\n    bottomStart: CornerSize,\n    shapesType: ShapeType\n): CornerBasedShape {\n    if (shapesType.strength <= 0f) return CornerBasedRectangleShape\n\n    return when (shapesType) {\n        is ShapeType.Cut -> CutCornerShape(\n            topStart = topStart.toAuto(shapesType),\n            topEnd = topEnd.toAuto(shapesType),\n            bottomEnd = bottomEnd.toAuto(shapesType),\n            bottomStart = bottomStart.toAuto(shapesType),\n        )\n\n        is ShapeType.Rounded -> RoundedCornerShape(\n            topStart = topStart.toAuto(shapesType),\n            topEnd = topEnd.toAuto(shapesType),\n            bottomEnd = bottomEnd.toAuto(shapesType),\n            bottomStart = bottomStart.toAuto(shapesType),\n        )\n\n        is ShapeType.Smooth -> ContinuousRoundedRectangle(\n            topStart = topStart.toAuto(shapesType),\n            topEnd = topEnd.toAuto(shapesType),\n            bottomEnd = bottomEnd.toAuto(shapesType),\n            bottomStart = bottomStart.toAuto(shapesType),\n            continuity = continuity\n        )\n\n        is ShapeType.Squircle -> SquircleShape(\n            topStartCorner = topStart.toAuto(shapesType),\n            topEndCorner = topEnd.toAuto(shapesType),\n            bottomEndCorner = bottomEnd.toAuto(shapesType),\n            bottomStartCorner = bottomStart.toAuto(shapesType),\n            smoothing = smoothing\n        )\n    }\n}\n\n@Stable\nfun AutoCircleShape(shapesType: ShapeType) = when (shapesType) {\n    is ShapeType.Cut -> CutCircleShape\n    is ShapeType.Rounded -> CircleShape\n    is ShapeType.Smooth -> SmoothCircleShape\n    is ShapeType.Squircle -> SquircleCircleShape\n}.let { shape ->\n    if (shapesType.strength >= 1f) {\n        shape\n    } else {\n        shape.copy(shape.topStart.toAuto(shapesType))\n    }\n}\n\n@Stable\n@Composable\nfun AutoCornersShape(size: Dp) = rememberSettings(size) { shapesType ->\n    AutoCornersShape(\n        size = size,\n        shapesType = shapesType\n    )\n}\n\n@Stable\n@Composable\nfun AutoCornersShape(size: Float) = rememberSettings(size) { shapesType ->\n    AutoCornersShape(\n        size = size,\n        shapesType = shapesType\n    )\n}\n\n@Stable\n@Composable\nfun AutoCornersShape(percent: Int) = rememberSettings(percent) { shapesType ->\n    AutoCornersShape(\n        percent = percent,\n        shapesType = shapesType\n    )\n}\n\n@Stable\n@Composable\nfun AutoCornersShape(\n    topStart: Dp = 0.dp,\n    topEnd: Dp = 0.dp,\n    bottomEnd: Dp = 0.dp,\n    bottomStart: Dp = 0.dp,\n) = rememberSettings(topStart, topEnd, bottomEnd, bottomStart) { shapesType ->\n    AutoCornersShape(\n        topStart = topStart,\n        topEnd = topEnd,\n        bottomEnd = bottomEnd,\n        bottomStart = bottomStart,\n        shapesType = shapesType\n    )\n}\n\n@Stable\n@Composable\nfun AutoCornersShape(\n    topStart: Float = 0.0f,\n    topEnd: Float = 0.0f,\n    bottomEnd: Float = 0.0f,\n    bottomStart: Float = 0.0f,\n) = rememberSettings(topStart, topEnd, bottomEnd, bottomStart) { shapesType ->\n    AutoCornersShape(\n        topStart = topStart,\n        topEnd = topEnd,\n        bottomEnd = bottomEnd,\n        bottomStart = bottomStart,\n        shapesType = shapesType\n    )\n}\n\n@Stable\n@Composable\nfun AutoCornersShape(\n    topStartPercent: Int = 0,\n    topEndPercent: Int = 0,\n    bottomEndPercent: Int = 0,\n    bottomStartPercent: Int = 0,\n) = rememberSettings(\n    topStartPercent,\n    topEndPercent,\n    bottomEndPercent,\n    bottomStartPercent\n) { shapesType ->\n    AutoCornersShape(\n        topStartPercent = topStartPercent,\n        topEndPercent = topEndPercent,\n        bottomEndPercent = bottomEndPercent,\n        bottomStartPercent = bottomStartPercent,\n        shapesType = shapesType\n    )\n}\n\n@Stable\n@Composable\nfun AutoCornersShape(\n    topStart: CornerSize,\n    topEnd: CornerSize,\n    bottomEnd: CornerSize,\n    bottomStart: CornerSize,\n) = rememberSettings(topStart, topEnd, bottomEnd, bottomStart) { shapesType ->\n    AutoCornersShape(\n        topStart = topStart,\n        topEnd = topEnd,\n        bottomEnd = bottomEnd,\n        bottomStart = bottomStart,\n        shapesType = shapesType\n    )\n}\n\n@Stable\n@Composable\nfun AutoCircleShape() = rememberSettings { shapesType ->\n    AutoCircleShape(shapesType)\n}\n\n@Stable\nval SmoothCircleShape = ContinuousCapsule(continuity)\n\n@Stable\nval CutCircleShape = CutCornerShape(50)\n\n@Stable\nval SquircleCircleShape = SquircleShape(\n    percent = 50,\n    smoothing = smoothing\n)\n\n@Stable\nval CornerBasedRectangleShape = RoundedCornerShape(0.dp)\n\n@Stable\n@Composable\nprivate fun rememberSettings(\n    vararg keys: Any?,\n    calculation: (type: ShapeType) -> CornerBasedShape\n): CornerBasedShape {\n    val shapesType = LocalSettingsState.current.shapesType\n\n    return remember(*keys, shapesType) {\n        calculation(shapesType)\n    }\n}\n\n@Stable\nprivate fun CornerSize.toAuto(shapeType: ShapeType) = toAuto(shapeType.strength)\n\n@Stable\nprivate fun CornerSize.toAuto(strength: Float) =\n    if (strength == 1f) {\n        this\n    } else if (this is AutoCornerSize) {\n        copy(\n            strength = strength\n        )\n    } else {\n        AutoCornerSize(\n            parent = this,\n            strength = strength\n        )\n    }\n\n@Stable\n@Immutable\nprivate data class AutoCornerSize(\n    private val parent: CornerSize,\n    private val strength: Float\n) : CornerSize {\n\n    override fun toPx(shapeSize: Size, density: Density): Float =\n        (parent.toPx(shapeSize, density) * strength).coerceAtLeast(0f)\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/AutoElevatedBorder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.material3.FloatingActionButtonDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.isUnspecified\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.suggestContainerColorBy\n\nfun Modifier.autoElevatedBorder(\n    height: Dp = Dp.Unspecified,\n    shape: Shape? = null,\n    color: Color = Color.Unspecified,\n    autoElevation: Dp = 6.dp\n) = this.composed {\n    val h = if (height.isUnspecified) {\n        LocalSettingsState.current.borderWidth.takeIf { it > 0.dp }\n    } else null\n\n    val shape1 = shape ?: FloatingActionButtonDefaults.shape\n\n    if (h == null) {\n        Modifier\n    } else {\n        Modifier.border(\n            width = h,\n            color = if (color.isSpecified) color\n            else {\n                MaterialTheme.colorScheme.outlineVariant(\n                    luminance = 0.3f,\n                    onTopOf = MaterialTheme.colorScheme.suggestContainerColorBy(LocalContentColor.current)\n                )\n            },\n            shape = shape1\n        )\n    }.materialShadow(\n        elevation = animateDpAsState(if (h == null) autoElevation else 0.dp).value,\n        shape = shape1\n    )\n}\n\nfun Modifier.containerFabBorder(\n    autoElevation: Dp = 1.5.dp,\n    shape: Shape? = null\n) = autoElevatedBorder(\n    autoElevation = autoElevation,\n    shape = shape\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/Blink.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.Animatable\nimport androidx.compose.animation.core.tween\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.isUnspecified\n\nfun Modifier.blink(\n    key: Any? = Unit,\n    blinkColor: Color = Color.Unspecified,\n    iterations: Int = 2,\n    enabled: Boolean = true\n) = composed {\n    val animatable = remember(key) { Animatable(Color.Transparent) }\n\n    val color = if (blinkColor.isUnspecified) {\n        MaterialTheme.colorScheme.inverseSurface.copy(alpha = 0.4f)\n    } else blinkColor\n\n    LaunchedEffect(key) {\n        kotlinx.coroutines.delay(500L)\n        repeat(iterations) {\n            animatable.animateTo(color, animationSpec = tween(durationMillis = 1000))\n            animatable.animateTo(Color.Transparent, animationSpec = tween(durationMillis = 1000))\n        }\n    }\n\n    if (enabled) Modifier.drawWithContent {\n        drawContent()\n        drawRect(animatable.value, size = this.size)\n    }\n    else Modifier\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/Container.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"AnimateAsStateLabel\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.CornerBasedShape\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawWithCache\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.isUnspecified\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.takeOrElse\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerShape\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\n\nfun Modifier.container(\n    shape: Shape? = null,\n    color: Color = Color.Unspecified,\n    resultPadding: Dp = 4.dp,\n    borderWidth: Dp = Dp.Unspecified,\n    borderColor: Color? = null,\n    autoShadowElevation: Dp = if (color != Color.Transparent) 1.dp else 0.dp,\n    clip: Boolean = true,\n    composeColorOnTopOfBackground: Boolean = true,\n    isShadowClip: Boolean = color.alpha < 1f,\n    isStandaloneContainer: Boolean = color.alpha < 1f,\n    shadowColor: Color = Color.Black\n) = this.composed {\n    val localContainerShape = LocalContainerShape.current\n    val resultShape = localContainerShape ?: shape ?: ShapeDefaults.default\n    val settingsState = LocalSettingsState.current\n\n    val targetBorderWidth = borderWidth.takeOrElse {\n        settingsState.borderWidth\n    }\n\n    val colorScheme = MaterialTheme.colorScheme\n    val containerColor = if (color.isUnspecified) {\n        SafeLocalContainerColor\n    } else {\n        if (composeColorOnTopOfBackground) color.compositeOver(colorScheme.background)\n        else color\n    }\n\n    val density = LocalDensity.current\n\n    val genericModifier = Modifier.drawWithCache {\n        val outline = resultShape.createOutline(\n            size = size,\n            layoutDirection = layoutDirection,\n            density = density\n        )\n        onDrawWithContent {\n            drawOutline(\n                outline = outline,\n                color = containerColor\n            )\n            if (targetBorderWidth > 0.dp) {\n                drawOutline(\n                    outline = outline,\n                    color = borderColor ?: colorScheme.outlineVariant(0.1f, containerColor),\n                    style = Stroke(with(density) { targetBorderWidth.toPx() })\n                )\n            }\n            drawContent()\n        }\n    }\n\n    val cornerModifier = Modifier\n        .background(\n            color = containerColor,\n            shape = resultShape\n        )\n        .border(\n            width = targetBorderWidth,\n            color = borderColor ?: colorScheme.outlineVariant(0.1f, containerColor),\n            shape = resultShape\n        )\n\n    Modifier\n        .materialShadow(\n            shape = resultShape,\n            elevation = animateDpAsState(\n                if (targetBorderWidth > 0.dp) {\n                    0.dp\n                } else autoShadowElevation.coerceAtLeast(0.dp)\n            ).value,\n            enabled = if (isStandaloneContainer) {\n                settingsState.drawContainerShadows\n            } else true,\n            isClipped = isShadowClip,\n            color = shadowColor\n        )\n        .then(\n            if (resultShape is CornerBasedShape) cornerModifier\n            else genericModifier\n        )\n        .then(if (clip) Modifier.clip(resultShape) else Modifier)\n        .then(if (resultPadding > 0.dp) Modifier.padding(resultPadding) else Modifier)\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/ContiniousRoundedRectangle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.annotation.FloatRange\nimport androidx.annotation.IntRange\nimport androidx.compose.foundation.shape.CornerBasedShape\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.foundation.shape.ZeroCornerSize\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.geometry.toRect\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.LayoutDirection.Ltr\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastCoerceIn\nimport com.kyant.capsule.Continuity\nimport kotlin.math.min\n\n@Immutable\nopen class ContinuousRoundedRectangle(\n    topStart: CornerSize,\n    topEnd: CornerSize,\n    bottomEnd: CornerSize,\n    bottomStart: CornerSize,\n    open val continuity: Continuity = Continuity.Default\n) : CornerBasedShape(\n    topStart = topStart,\n    topEnd = topEnd,\n    bottomEnd = bottomEnd,\n    bottomStart = bottomStart\n) {\n\n    override fun createOutline(\n        size: Size,\n        topStart: Float,\n        topEnd: Float,\n        bottomEnd: Float,\n        bottomStart: Float,\n        layoutDirection: LayoutDirection\n    ): Outline {\n        if (topStart + topEnd + bottomEnd + bottomStart == 0f) {\n            return Outline.Rectangle(size.toRect())\n        }\n\n        val maxRadius = min(size.width, size.height) * 0.5f\n        val topLeft =\n            (if (layoutDirection == Ltr) topStart else topEnd).fastCoerceIn(0f, maxRadius)\n        val topRight =\n            (if (layoutDirection == Ltr) topEnd else topStart).fastCoerceIn(0f, maxRadius)\n        val bottomRight =\n            (if (layoutDirection == Ltr) bottomEnd else bottomStart).fastCoerceIn(0f, maxRadius)\n        val bottomLeft =\n            (if (layoutDirection == Ltr) bottomStart else bottomEnd).fastCoerceIn(0f, maxRadius)\n\n        return continuity.createRoundedRectangleOutline(\n            size = size,\n            topLeft = topLeft,\n            topRight = topRight,\n            bottomRight = bottomRight,\n            bottomLeft = bottomLeft\n        )\n    }\n\n    override fun copy(\n        topStart: CornerSize,\n        topEnd: CornerSize,\n        bottomEnd: CornerSize,\n        bottomStart: CornerSize\n    ): ContinuousRoundedRectangle {\n        return ContinuousRoundedRectangle(\n            topStart = topStart,\n            topEnd = topEnd,\n            bottomEnd = bottomEnd,\n            bottomStart = bottomStart,\n            continuity = continuity\n        )\n    }\n\n    fun copy(\n        topStart: CornerSize = this.topStart,\n        topEnd: CornerSize = this.topEnd,\n        bottomEnd: CornerSize = this.bottomEnd,\n        bottomStart: CornerSize = this.bottomStart,\n        continuity: Continuity = this.continuity\n    ): ContinuousRoundedRectangle {\n        return ContinuousRoundedRectangle(\n            topStart = topStart,\n            topEnd = topEnd,\n            bottomEnd = bottomEnd,\n            bottomStart = bottomStart,\n            continuity = continuity\n        )\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is ContinuousRoundedRectangle) return false\n\n        if (topStart != other.topStart) return false\n        if (topEnd != other.topEnd) return false\n        if (bottomEnd != other.bottomEnd) return false\n        if (bottomStart != other.bottomStart) return false\n        if (continuity != other.continuity) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = topStart.hashCode()\n        result = 31 * result + topEnd.hashCode()\n        result = 31 * result + bottomEnd.hashCode()\n        result = 31 * result + bottomStart.hashCode()\n        result = 31 * result + continuity.hashCode()\n        return result\n    }\n\n    override fun toString(): String {\n        return \"ContinuousRoundedRectangle(topStart=$topStart, topEnd=$topEnd, bottomEnd=$bottomEnd, \" +\n                \"bottomStart=$bottomStart, continuity=$continuity)\"\n    }\n}\n\n@Stable\nval ContinuousRectangle: ContinuousRoundedRectangle = ContinuousRectangleImpl()\n\n@Suppress(\"FunctionName\")\n@Stable\nfun ContinuousRectangle(continuity: Continuity = Continuity.Default): ContinuousRoundedRectangle =\n    ContinuousRectangleImpl(continuity)\n\n@Immutable\nprivate data class ContinuousRectangleImpl(\n    override val continuity: Continuity = Continuity.Default\n) : ContinuousRoundedRectangle(\n    topStart = ZeroCornerSize,\n    topEnd = ZeroCornerSize,\n    bottomEnd = ZeroCornerSize,\n    bottomStart = ZeroCornerSize,\n    continuity = continuity\n) {\n\n    override fun toString(): String {\n        return \"ContinuousRectangle(continuity=$continuity)\"\n    }\n}\n\nprivate val FullCornerSize = CornerSize(50)\n\n@Stable\nval ContinuousCapsule: ContinuousRoundedRectangle = ContinuousCapsule()\n\n@Suppress(\"FunctionName\")\n@Stable\nfun ContinuousCapsule(continuity: Continuity = Continuity.Default): ContinuousRoundedRectangle =\n    ContinuousCapsuleImpl(continuity)\n\n@Immutable\nprivate data class ContinuousCapsuleImpl(\n    override val continuity: Continuity = Continuity.Default\n) : ContinuousRoundedRectangle(\n    topStart = FullCornerSize,\n    topEnd = FullCornerSize,\n    bottomEnd = FullCornerSize,\n    bottomStart = FullCornerSize,\n    continuity = continuity\n) {\n\n    override fun createOutline(\n        size: Size,\n        topStart: Float,\n        topEnd: Float,\n        bottomEnd: Float,\n        bottomStart: Float,\n        layoutDirection: LayoutDirection\n    ): Outline = continuity.createCapsuleOutline(size)\n\n    override fun toString(): String {\n        return \"ContinuousCapsule(continuity=$continuity)\"\n    }\n}\n\n@Stable\nfun ContinuousRoundedRectangle(\n    corner: CornerSize,\n    continuity: Continuity = Continuity.Default\n): ContinuousRoundedRectangle =\n    ContinuousRoundedRectangle(\n        topStart = corner,\n        topEnd = corner,\n        bottomEnd = corner,\n        bottomStart = corner,\n        continuity = continuity\n    )\n\n@Stable\nfun ContinuousRoundedRectangle(\n    size: Dp,\n    continuity: Continuity = Continuity.Default\n): ContinuousRoundedRectangle =\n    ContinuousRoundedRectangle(\n        corner = CornerSize(size),\n        continuity = continuity\n    )\n\n@Stable\nfun ContinuousRoundedRectangle(\n    @FloatRange(from = 0.0) size: Float,\n    continuity: Continuity = Continuity.Default\n): ContinuousRoundedRectangle =\n    ContinuousRoundedRectangle(\n        corner = CornerSize(size),\n        continuity = continuity\n    )\n\n@Stable\nfun ContinuousRoundedRectangle(\n    @IntRange(from = 0, to = 100) percent: Int,\n    continuity: Continuity = Continuity.Default\n): ContinuousRoundedRectangle =\n    ContinuousRoundedRectangle(\n        corner = CornerSize(percent),\n        continuity = continuity\n    )\n\n@Stable\nfun ContinuousRoundedRectangle(\n    topStart: Dp = 0f.dp,\n    topEnd: Dp = 0f.dp,\n    bottomEnd: Dp = 0f.dp,\n    bottomStart: Dp = 0f.dp,\n    continuity: Continuity = Continuity.Default\n): ContinuousRoundedRectangle =\n    ContinuousRoundedRectangle(\n        topStart = CornerSize(topStart),\n        topEnd = CornerSize(topEnd),\n        bottomEnd = CornerSize(bottomEnd),\n        bottomStart = CornerSize(bottomStart),\n        continuity = continuity\n    )\n\n@Stable\nfun ContinuousRoundedRectangle(\n    @FloatRange(from = 0.0) topStart: Float = 0f,\n    @FloatRange(from = 0.0) topEnd: Float = 0f,\n    @FloatRange(from = 0.0) bottomEnd: Float = 0f,\n    @FloatRange(from = 0.0) bottomStart: Float = 0f,\n    continuity: Continuity = Continuity.Default\n): ContinuousRoundedRectangle =\n    ContinuousRoundedRectangle(\n        topStart = CornerSize(topStart),\n        topEnd = CornerSize(topEnd),\n        bottomEnd = CornerSize(bottomEnd),\n        bottomStart = CornerSize(bottomStart),\n        continuity = continuity\n    )\n\n@Stable\nfun ContinuousRoundedRectangle(\n    @IntRange(from = 0, to = 100) topStartPercent: Int = 0,\n    @IntRange(from = 0, to = 100) topEndPercent: Int = 0,\n    @IntRange(from = 0, to = 100) bottomEndPercent: Int = 0,\n    @IntRange(from = 0, to = 100) bottomStartPercent: Int = 0,\n    continuity: Continuity = Continuity.Default\n): ContinuousRoundedRectangle =\n    ContinuousRoundedRectangle(\n        topStart = CornerSize(topStartPercent),\n        topEnd = CornerSize(topEndPercent),\n        bottomEnd = CornerSize(bottomEndPercent),\n        bottomStart = CornerSize(bottomStartPercent),\n        continuity = continuity\n    )"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/DetectSwipe.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.foundation.gestures.detectHorizontalDragGestures\nimport androidx.compose.foundation.gestures.detectVerticalDragGestures\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.pointer.pointerInput\n\nfun Modifier.onSwipeLeft(onSwipe: () -> Unit): Modifier {\n    var dx = 0F\n\n    return this.pointerInput(Unit) {\n        detectHorizontalDragGestures(\n            onDragEnd = {\n                if (dx < 0) {\n                    dx = 0F\n                    onSwipe()\n                }\n            },\n            onHorizontalDrag = { _, dragAmount ->\n                dx = dragAmount\n            }\n        )\n    }\n}\n\nfun Modifier.onSwipeRight(onSwipe: () -> Unit): Modifier {\n    var dx = 0F\n\n    return this.pointerInput(Unit) {\n        detectHorizontalDragGestures(\n            onDragEnd = {\n                if (dx > 0) {\n                    dx = 0F\n                    onSwipe()\n                }\n            },\n            onHorizontalDrag = { _, dragAmount ->\n                dx = dragAmount\n            }\n        )\n    }\n}\n\nfun Modifier.onSwipeDown(\n    enabled: Boolean = true,\n    onSwipe: () -> Unit\n): Modifier {\n    if (!enabled) return this\n\n    var dy = 0F\n\n    return this.pointerInput(Unit) {\n        detectVerticalDragGestures(\n            onDragEnd = {\n                if (dy > 0) {\n                    dy = 0F\n                    onSwipe()\n                }\n            },\n            onVerticalDrag = { _, dragAmount ->\n                dy = dragAmount\n            }\n        )\n    }\n}\n\nfun Modifier.detectSwipes(\n    key: Any? = Unit,\n    onSwipeLeft: () -> Unit,\n    onSwipeRight: () -> Unit\n): Modifier {\n    var dx = 0F\n\n    return this.pointerInput(key) {\n        detectHorizontalDragGestures(\n            onDragEnd = {\n                if (dx > 0) {\n                    onSwipeRight()\n                } else {\n                    onSwipeLeft()\n                }\n                dx = 0F\n            },\n            onHorizontalDrag = { _, dragAmount ->\n                dx = dragAmount\n            }\n        )\n    }\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/DragHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport android.annotation.SuppressLint\nimport androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.gestures.scrollBy\nimport androidx.compose.foundation.lazy.grid.LazyGridState\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.round\nimport androidx.compose.ui.unit.toIntRect\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.isActive\n\n\n/**\n[Modifier] which helps you to implement google photos selection grid,\nto make it work pass item key which is should be \"[key]-index\"\n **/\n@SuppressLint(\"UnnecessaryComposedModifier\")\nfun Modifier.dragHandler(\n    key: Any?,\n    isVertical: Boolean,\n    lazyGridState: LazyGridState,\n    selectedItems: MutableState<Set<Int>>,\n    onSelectionChange: (Set<Int>) -> Unit = {},\n    enabled: Boolean = true,\n    onTap: (Int) -> Unit = {},\n    onLongTap: (Int) -> Unit = {},\n    shouldHandleLongTap: Boolean = true,\n    tapEnabled: Boolean = true\n): Modifier = this.composed {\n    val haptics = LocalHapticFeedback.current\n    val isRtl = !isVertical && LocalLayoutDirection.current == LayoutDirection.Rtl\n\n    val autoScrollThreshold = with(LocalDensity.current) { 40.dp.toPx() }\n    val autoScrollSpeed: MutableState<Float> = remember { mutableFloatStateOf(0f) }\n\n    LaunchedEffect(autoScrollSpeed.value) {\n        if (autoScrollSpeed.value != 0f) {\n            while (isActive) {\n                lazyGridState.scrollBy(autoScrollSpeed.value)\n                delay(10)\n            }\n        }\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    Modifier\n        .pointerInput(key, tapEnabled, enabled, isRtl, isPortrait) {\n            if (enabled) {\n                detectTapGestures { offset ->\n                    lazyGridState\n                        .gridItemKeyAtPosition(\n                            if (isRtl) offset.copy(x = size.width - offset.x) else offset\n                        )\n                        ?.let { key ->\n                            if (tapEnabled) {\n                                val newItems = if (selectedItems.value.contains(key)) {\n                                    selectedItems.value - key\n                                } else {\n                                    selectedItems.value + key\n                                }\n                                selectedItems.update { newItems }\n                                onSelectionChange(newItems)\n                            }\n                            haptics.longPress()\n                            onTap(key - 1)\n                        }\n                }\n            }\n        }\n        .pointerInput(key, shouldHandleLongTap, enabled, isRtl, isPortrait) {\n            if (enabled) {\n                var initialKey: Int? = null\n                var currentKey: Int? = null\n                detectDragGesturesAfterLongPress(\n                    onDragStart = { offset ->\n                        lazyGridState\n                            .gridItemKeyAtPosition(\n                                if (isRtl) offset.copy(x = size.width - offset.x) else offset\n                            )\n                            ?.let { key ->\n                                if (!selectedItems.value.contains(key) && shouldHandleLongTap) {\n                                    initialKey = key\n                                    currentKey = key\n                                    val newItems = selectedItems.value + key\n                                    selectedItems.update { newItems }\n                                    onSelectionChange(newItems)\n                                }\n                                haptics.longPress()\n                                onLongTap(key - 1)\n                            }\n                    },\n                    onDragCancel = {\n                        initialKey = null\n                        autoScrollSpeed.value = 0f\n                    },\n                    onDragEnd = {\n                        initialKey = null\n                        autoScrollSpeed.value = 0f\n                    },\n                    onDrag = { change, _ ->\n                        if (initialKey != null) {\n                            val position =\n                                if (isRtl) change.position.copy(x = size.width - change.position.x) else change.position\n\n                            val distFromBottom = if (isVertical) {\n                                lazyGridState.layoutInfo.viewportSize.height - position.y\n                            } else lazyGridState.layoutInfo.viewportSize.width - position.x\n                            val distFromTop = if (isVertical) {\n                                position.y\n                            } else position.x\n                            autoScrollSpeed.value = when {\n                                distFromBottom < autoScrollThreshold -> autoScrollThreshold - distFromBottom\n                                distFromTop < autoScrollThreshold -> -(autoScrollThreshold - distFromTop)\n                                else -> 0f\n                            }\n\n                            lazyGridState\n                                .gridItemKeyAtPosition(position)\n                                ?.let { key ->\n                                    if (currentKey != key) {\n                                        val newItems = selectedItems.value\n                                            .minus(initialKey!!..currentKey!!)\n                                            .minus(currentKey!!..initialKey!!)\n                                            .plus(initialKey!!..key)\n                                            .plus(key..initialKey!!)\n\n                                        selectedItems.update { newItems }\n                                        onSelectionChange(newItems)\n                                        currentKey = key\n                                    }\n                                }\n                        }\n                    }\n                )\n            }\n        }\n}\n\nprivate fun LazyGridState.gridItemKeyAtPosition(hitPoint: Offset): Int? {\n    val find = layoutInfo.visibleItemsInfo.find { itemInfo ->\n        itemInfo.size.toIntRect().contains(hitPoint.round() - itemInfo.offset)\n    }\n    val itemKey = find?.key\n    return itemKey?.toString()?.takeLastWhile { it != '-' }?.toIntOrNull()\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/DrawHorizontalStroke.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.isUnspecified\nimport androidx.compose.ui.zIndex\nimport com.gigamole.composeshadowsplus.softlayer.softLayerShadow\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\n\nfun Modifier.drawHorizontalStroke(\n    top: Boolean = false,\n    height: Dp = Dp.Unspecified,\n    autoElevation: Dp = 6.dp,\n    enabled: Boolean = true\n) = this.composed {\n    if (!enabled) return@composed Modifier\n\n    val settingsState = LocalSettingsState.current\n    val borderWidth = settingsState.borderWidth\n    val h = if (height.isUnspecified) {\n        borderWidth.takeIf { it > 0.dp }\n    } else height\n\n    val color = MaterialTheme.colorScheme.outlineVariant(\n        0.1f,\n        onTopOf = MaterialTheme.colorScheme.surfaceContainer\n    )\n\n\n    val shadow = Modifier\n        .softLayerShadow(\n            spread = (-2).dp,\n            shape = RectangleShape,\n            radius = animateDpAsState(\n                if (h == null && settingsState.drawAppBarShadows) {\n                    autoElevation\n                } else 0.dp\n            ).value\n        )\n        .zIndex(100f)\n\n    if (h == null) {\n        shadow\n    } else {\n        val heightPx = with(LocalDensity.current) { h.toPx() }\n        Modifier\n            .zIndex(100f)\n            .drawWithContent {\n                drawContent()\n                drawRect(\n                    color = color,\n                    topLeft = if (top) Offset(0f, 0f) else Offset(0f, this.size.height),\n                    size = Size(this.size.width, heightPx)\n                )\n            }\n            .then(shadow)\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/FadingEdges.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport android.annotation.SuppressLint\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.gestures.ScrollableState\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.lazy.grid.LazyGridState\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.gigamole.composefadingedges.FadingEdgesGravity\nimport com.gigamole.composefadingedges.content.FadingEdgesContentType\nimport com.gigamole.composefadingedges.content.scrollconfig.FadingEdgesScrollConfig\nimport com.gigamole.composefadingedges.fill.FadingEdgesFillType\nimport com.gigamole.composefadingedges.horizontalFadingEdges\nimport com.gigamole.composefadingedges.verticalFadingEdges\n\n\n@SuppressLint(\"UnnecessaryComposedModifier\")\nfun Modifier.fadingEdges(\n    scrollableState: ScrollableState? = null,\n    color: Color = Color.Unspecified,\n    isVertical: Boolean = false,\n    spanCount: Int? = null,\n    scrollFactor: Float = 1.25f,\n    enabled: Boolean = true,\n    length: Dp = 16.dp,\n    gravity: FadingEdgesGravity = FadingEdgesGravity.All\n) = this.composed {\n    if (!enabled) Modifier\n    else {\n        val fillType = if (color.isSpecified) {\n            FadingEdgesFillType.FadeColor(\n                color = color\n            )\n        } else {\n            FadingEdgesFillType.FadeClip()\n        }\n\n        val scrollConfig = FadingEdgesScrollConfig.Dynamic(\n            scrollFactor = scrollFactor\n        )\n\n        when (scrollableState) {\n            is ScrollState -> {\n                if (isVertical) {\n                    Modifier.verticalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Scroll(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                } else {\n                    Modifier.horizontalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Scroll(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                }\n            }\n\n            is LazyListState -> {\n                if (isVertical) {\n                    Modifier.verticalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Lazy.List(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                } else {\n                    Modifier.horizontalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Lazy.List(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                }\n            }\n\n            is LazyGridState -> {\n                if (isVertical) {\n                    Modifier.verticalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Lazy.Grid(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState,\n                            spanCount = spanCount ?: remember(scrollableState) {\n                                derivedStateOf {\n                                    scrollableState.layoutInfo.maxSpan\n                                }\n                            }.value\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                } else {\n                    Modifier.horizontalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Lazy.Grid(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState,\n                            spanCount = spanCount ?: remember(scrollableState) {\n                                derivedStateOf {\n                                    scrollableState.layoutInfo.maxSpan\n                                }\n                            }.value\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                }\n            }\n\n            is LazyStaggeredGridState -> {\n                require(spanCount != null)\n                if (isVertical) {\n                    Modifier.verticalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Lazy.StaggeredGrid(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState,\n                            spanCount = spanCount\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                } else {\n                    Modifier.horizontalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Dynamic.Lazy.StaggeredGrid(\n                            scrollConfig = scrollConfig,\n                            state = scrollableState,\n                            spanCount = spanCount\n                        ),\n                        fillType = fillType,\n                        length = length\n                    )\n                }\n            }\n\n            else -> {\n                if (isVertical) {\n                    Modifier.verticalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Static,\n                        fillType = fillType,\n                        length = length\n                    )\n                } else {\n                    Modifier.horizontalFadingEdges(\n                        gravity = gravity,\n                        contentType = FadingEdgesContentType.Static,\n                        fillType = fillType,\n                        length = length\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/HelperGrid.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawWithCache\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.tooling.preview.Preview\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\n\n@Stable\n@Immutable\ndata class HelperGridParams(\n    val color: Int = Color.Black.copy(0.5f).toArgb(),\n    val cellWidth: Float = 20f,\n    val cellHeight: Float = 20f,\n    val linesWidth: Float = 0f,\n    val enabled: Boolean = false,\n    val withPrimaryLines: Boolean = false\n)\n\nfun Modifier.drawHelperGrid(\n    params: HelperGridParams,\n) = drawWithCache {\n    with(params) {\n        val width = size.width\n        val height = size.height\n\n        val canvasSize = IntegerSize(\n            width = width.toInt(),\n            height = height.toInt()\n        )\n\n        val cellWidthPx = cellWidth.pt.toPx(canvasSize)\n        val cellHeightPx = cellHeight.pt.toPx(canvasSize)\n\n        val linesWidthPx = linesWidth.pt.toPx(canvasSize)\n\n        val horizontalSteps = (width / cellWidthPx).toInt()\n        val verticalSteps = (height / cellHeightPx).toInt()\n\n        val composeColor = color.toColor()\n\n        onDrawWithContent {\n            drawContent()\n\n            if (enabled) {\n                for (x in 0..horizontalSteps) {\n                    drawLine(\n                        color = composeColor,\n                        start = Offset(x = x * cellWidthPx, y = 0f),\n                        end = Offset(x = x * cellWidthPx, y = height),\n                        strokeWidth = if (x % 5 == 0 && x != 0 && withPrimaryLines) {\n                            if (linesWidthPx == 0f) 2f else linesWidthPx * 2\n                        } else {\n                            linesWidthPx\n                        }\n                    )\n                }\n\n                for (y in 0..verticalSteps) {\n                    drawLine(\n                        color = composeColor,\n                        start = Offset(x = 0f, y = y * cellHeightPx),\n                        end = Offset(x = width, y = y * cellHeightPx),\n                        strokeWidth = if (y % 5 == 0 && y != 0 && withPrimaryLines) {\n                            if (linesWidthPx == 0f) 2f else linesWidthPx * 2\n                        } else {\n                            linesWidthPx\n                        }\n                    )\n                }\n            }\n        }\n    }\n\n}\n\n\n@Composable\n@Preview\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    Surface(\n        modifier = Modifier\n            .fillMaxSize()\n            .drawHelperGrid(\n                HelperGridParams(\n                    enabled = true,\n                    withPrimaryLines = true\n                )\n            )\n    ) { }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/LayoutCorners.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport android.content.Context\nimport android.os.Build\nimport android.view.RoundedCorner\nimport android.view.View\nimport android.view.WindowManager\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.layout.boundsInRoot\nimport androidx.compose.ui.layout.onGloballyPositioned\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.platform.LocalView\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\n\nfun Modifier.withLayoutCorners(\n    block: Modifier.(LayoutCorners) -> Modifier\n): Modifier = composed {\n    val context = LocalContext.current\n    val density = LocalDensity.current\n    val screenInfo = remember(context) { context.getScreenInfo(density) }\n\n    if (screenInfo != null) {\n        val rootView = LocalView.current\n        val layoutDirection = LocalLayoutDirection.current\n        var positionOnScreen by remember { mutableStateOf<Rect?>(null) }\n        val corners = getLayoutCorners(screenInfo, positionOnScreen, layoutDirection)\n\n        onGloballyPositioned { cords ->\n            positionOnScreen =\n                getBoundsOnScreen(rootView = rootView, boundsInRoot = cords.boundsInRoot())\n        }.block(corners)\n    } else {\n        block(LayoutCorners())\n    }\n}\n\nprivate fun Context.getScreenInfo(density: Density): ScreenInfo? {\n    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {\n        return null\n    }\n\n    val windowMetrics =\n        getSystemService(WindowManager::class.java)?.maximumWindowMetrics ?: return null\n    val insets = windowMetrics.windowInsets\n\n    return with(density) {\n        ScreenInfo(\n            cornerRadii = CornerRadii(\n                topLeft = insets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT)?.radius?.toDp(),\n                topRight = insets.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT)?.radius?.toDp(),\n                bottomRight = insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT)?.radius?.toDp(),\n                bottomLeft = insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT)?.radius?.toDp(),\n            ),\n            width = windowMetrics.bounds.width(),\n            height = windowMetrics.bounds.height(),\n        )\n    }\n}\n\nprivate fun getLayoutCorners(\n    screenInfo: ScreenInfo,\n    positionOnScreen: Rect?,\n    layoutDirection: LayoutDirection,\n): LayoutCorners {\n    if (positionOnScreen == null) {\n        return LayoutCorners()\n    }\n\n    val (cornerRadius, screenWidth, screenHeight) = screenInfo\n    val (left, top, right, bottom) = positionOnScreen\n\n    val topLeft = getLayoutCorner(\n        radius = cornerRadius.topLeft,\n        isFixed = (left <= 0) && (top <= 0)\n    )\n    val topRight = getLayoutCorner(\n        radius = cornerRadius.topRight,\n        isFixed = (right >= screenWidth) && (top <= 0)\n    )\n    val bottomRight = getLayoutCorner(\n        radius = cornerRadius.bottomRight,\n        isFixed = (right >= screenWidth) && (bottom >= screenHeight)\n    )\n    val bottomLeft = getLayoutCorner(\n        radius = cornerRadius.bottomLeft,\n        isFixed = (left <= 0) && (bottom >= screenHeight)\n    )\n\n    return when (layoutDirection) {\n        LayoutDirection.Ltr -> LayoutCorners(\n            topStart = topLeft,\n            topEnd = topRight,\n            bottomEnd = bottomRight,\n            bottomStart = bottomLeft\n        )\n\n        LayoutDirection.Rtl -> LayoutCorners(\n            topStart = topRight,\n            topEnd = topLeft,\n            bottomEnd = bottomLeft,\n            bottomStart = bottomRight\n        )\n    }\n}\n\nprivate fun getLayoutCorner(\n    radius: Dp?,\n    isFixed: Boolean\n): LayoutCorner =\n    if (radius == null) {\n        LayoutCorner()\n    } else {\n        LayoutCorner(\n            radius = radius,\n            isFixed = isFixed\n        )\n    }\n\nprivate fun getBoundsOnScreen(\n    rootView: View,\n    boundsInRoot: Rect\n): Rect {\n    val rootViewLeftTopOnScreen = IntArray(2)\n    rootView.getLocationOnScreen(rootViewLeftTopOnScreen)\n    val (rootViewLeftOnScreen, rootViewTopOnScreen) = rootViewLeftTopOnScreen\n\n    return Rect(\n        left = rootViewLeftOnScreen + boundsInRoot.left,\n        top = rootViewTopOnScreen + boundsInRoot.top,\n        right = rootViewLeftOnScreen + boundsInRoot.right,\n        bottom = rootViewTopOnScreen + boundsInRoot.bottom,\n    )\n}\n\nprivate data class ScreenInfo(\n    val cornerRadii: CornerRadii,\n    val width: Int,\n    val height: Int,\n)\n\nprivate data class CornerRadii(\n    val topLeft: Dp? = null,\n    val topRight: Dp? = null,\n    val bottomRight: Dp? = null,\n    val bottomLeft: Dp? = null,\n)\n\ndata class LayoutCorners(\n    val topStart: LayoutCorner = LayoutCorner(),\n    val topEnd: LayoutCorner = LayoutCorner(),\n    val bottomEnd: LayoutCorner = LayoutCorner(),\n    val bottomStart: LayoutCorner = LayoutCorner(),\n)\n\ndata class LayoutCorner(\n    val radius: Dp = 16.dp,\n    val isFixed: Boolean = false,\n)\n\nfun LayoutCorners.toShape(progress: Float): RoundedCornerShape =\n    RoundedCornerShape(\n        topStart = topStart.getProgressRadius(progress),\n        topEnd = topEnd.getProgressRadius(progress),\n        bottomEnd = bottomEnd.getProgressRadius(progress),\n        bottomStart = bottomStart.getProgressRadius(progress),\n    )\n\nprivate fun LayoutCorner.getProgressRadius(progress: Float): Dp =\n    if (isFixed && progress > 0f) radius else radius * progress\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/Line.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport kotlin.math.abs\nimport kotlin.math.cos\nimport kotlin.math.sin\n\n@Stable\n@Immutable\ndata class Line(\n    val startX: Float,\n    val startY: Float,\n    val endX: Float,\n    val endY: Float\n) {\n\n    companion object {\n        val CenterVertical = Line(\n            startX = 0.5f,\n            startY = 0f,\n            endX = 0.5f,\n            endY = 1f\n        )\n\n        val CenterHorizontal = Line(\n            startX = 0f,\n            startY = 0.5f,\n            endX = 1f,\n            endY = 0.5f\n        )\n\n        @Suppress(\"FunctionName\")\n        fun Rotated(angle: Float): Line = if (abs(angle) % 360 != 0f) {\n            CenterVertical.rotate(angle)\n        } else {\n            CenterVertical\n        }\n\n        @Suppress(\"FunctionName\")\n        fun Bundle(size: Int): List<Line> = if (size > 0) {\n            List(size) {\n                Rotated(it * (360f / size))\n            }\n        } else {\n            listOf()\n        }\n    }\n\n    fun rotate(angle: Float): Line {\n        val centerX = (startX + endX) / 2\n        val centerY = (startY + endY) / 2\n\n        val radians = Math.toRadians(angle.toDouble()).toFloat()\n        val cosA = cos(radians)\n        val sinA = sin(radians)\n\n        fun rotatePoint(\n            x: Float,\n            y: Float\n        ): Pair<Float, Float> {\n            val dx = x - centerX\n            val dy = y - centerY\n            val newX = centerX + dx * cosA - dy * sinA\n            val newY = centerY + dx * sinA + dy * cosA\n            return newX to newY\n        }\n\n        val (newStartX, newStartY) = rotatePoint(startX, startY)\n        val (newEndX, newEndY) = rotatePoint(endX, endY)\n\n        return copy(startX = newStartX, startY = newStartY, endX = newEndX, endY = newEndY)\n    }\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/MaterialShadow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport android.os.Build\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.shadow\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.gigamole.composeshadowsplus.rsblur.rsBlurShadow\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.zedalpha.shadowgadgets.compose.clippedShadow\n\nfun Modifier.materialShadow(\n    shape: Shape,\n    elevation: Dp,\n    enabled: Boolean = true,\n    isClipped: Boolean = true,\n    color: Color = Color.Black\n) = composed {\n    val elev = animateDpAsState(if (enabled) elevation else 0.dp).value\n\n    if (elev > 0.dp) {\n        val shape by remember(shape) {\n            derivedStateOf {\n                if ((shape is AnimatedShape && shape.shapesType is ShapeType.Smooth)) {\n                    @Stable\n                    object : Shape by shape {\n                        override fun createOutline(\n                            size: Size,\n                            layoutDirection: LayoutDirection,\n                            density: Density\n                        ): Outline = shape.createOutline(\n                            size = size,\n                            layoutDirection = layoutDirection,\n                            density = density,\n                            shapesType = ShapeType.Rounded()\n                        )\n                    }\n                } else shape\n            }\n        }\n        val isConcavePath by remember(shape) {\n            derivedStateOf {\n                shape.createOutline(\n                    size = Size(1f, 1f),\n                    layoutDirection = LayoutDirection.Ltr,\n                    density = Density(1f)\n                ).let {\n                    it is Outline.Generic && !it.path.isConvex\n                }\n            }\n        }\n\n        when {\n            isConcavePath && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q -> {\n                val api21Shadow = Modifier.rsBlurShadow(\n                    shape = shape,\n                    radius = elev,\n                    isAlphaContentClip = isClipped,\n                    color = color\n                )\n\n                api21Shadow\n            }\n\n            else -> {\n                val api29Shadow = if (isClipped) {\n                    Modifier.clippedShadow(\n                        shape = shape,\n                        elevation = elev,\n                        ambientColor = color,\n                        spotColor = color\n                    )\n                } else {\n                    Modifier.shadow(\n                        shape = shape,\n                        elevation = elev,\n                        ambientColor = color,\n                        spotColor = color\n                    )\n                }\n\n                api29Shadow\n            }\n        }\n    } else Modifier\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/MeshGradient.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathMeasure\nimport androidx.compose.ui.graphics.PointMode\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.VertexMode\nimport androidx.compose.ui.graphics.Vertices\nimport androidx.compose.ui.graphics.drawscope.CanvasDrawScope\nimport androidx.compose.ui.graphics.drawscope.drawIntoCanvas\nimport androidx.compose.ui.graphics.drawscope.scale\nimport androidx.compose.ui.graphics.lerp\n\n@Composable\nfun Modifier.meshGradient(\n    points: List<List<Pair<Offset, Color>>>,\n    resolutionX: Int = 1,\n    resolutionY: Int = 1,\n    showPoints: Boolean = false,\n    indicesModifier: (List<Int>) -> List<Int> = { it },\n    alpha: Float = 1f\n): Modifier {\n    val pointData by remember(points, resolutionX, resolutionY) {\n        derivedStateOf {\n            PointData(points, resolutionX, resolutionY)\n        }\n    }\n\n    return drawBehind {\n        drawIntoCanvas { canvas ->\n            canvas.drawMeshGradient(\n                pointData = pointData,\n                showPoints = showPoints,\n                indicesModifier = indicesModifier,\n                size = size,\n                alpha = alpha\n            )\n        }\n    }\n}\n\n\nfun Canvas.drawMeshGradient(\n    pointData: PointData,\n    showPoints: Boolean = false,\n    indicesModifier: (List<Int>) -> List<Int> = { it },\n    size: Size,\n    alpha: Float\n) {\n    CanvasDrawScope().apply {\n        drawContext.canvas = this@drawMeshGradient\n        drawContext.size = size\n\n        with(drawContext.canvas) {\n            scale(\n                scaleX = size.width,\n                scaleY = size.height,\n                pivot = Offset.Zero\n            ) {\n                drawVertices(\n                    vertices = Vertices(\n                        vertexMode = VertexMode.Triangles,\n                        positions = pointData.offsets,\n                        textureCoordinates = pointData.offsets,\n                        colors = pointData.colors,\n                        indices = indicesModifier(pointData.indices)\n                    ),\n                    blendMode = BlendMode.Dst,\n                    paint = Paint().apply {\n                        this.alpha = alpha\n                    }\n                )\n            }\n\n\n            if (showPoints) {\n                val flattenedPaint = Paint()\n                flattenedPaint.color = Color.White.copy(alpha = .9f)\n                flattenedPaint.strokeWidth = 4f * .001f\n                flattenedPaint.strokeCap = StrokeCap.Round\n                flattenedPaint.blendMode = BlendMode.SrcOver\n\n                scale(\n                    scaleX = size.width,\n                    scaleY = size.height,\n                    pivot = Offset.Zero\n                ) {\n                    drawPoints(\n                        pointMode = PointMode.Points,\n                        points = pointData.offsets,\n                        paint = flattenedPaint\n                    )\n                }\n            }\n        }\n    }\n}\n\n\nclass PointData(\n    private val points: List<List<Pair<Offset, Color>>>,\n    private val stepsX: Int,\n    private val stepsY: Int,\n) {\n    val offsets: MutableList<Offset>\n    val colors: MutableList<Color>\n    val indices: List<Int>\n    private val xLength: Int = (points[0].size * stepsX) - (stepsX - 1)\n    private val yLength: Int = (points.size * stepsY) - (stepsY - 1)\n    private val measure = PathMeasure()\n\n    private val indicesBlocks: List<IndicesBlock>\n\n    init {\n        offsets = buildList {\n            repeat((xLength - 0) * (yLength - 0)) {\n                add(Offset(0f, 0f))\n            }\n        }.toMutableList()\n\n        colors = buildList {\n            repeat((xLength - 0) * (yLength - 0)) {\n                add(Color.Transparent)\n            }\n        }.toMutableList()\n\n        indicesBlocks =\n            buildList {\n                for (y in 0..yLength - 2) {\n                    for (x in 0..xLength - 2) {\n\n                        val a = (y * xLength) + x\n                        val b = a + 1\n                        val c = ((y + 1) * xLength) + x\n                        val d = c + 1\n\n                        add(\n                            IndicesBlock(\n                                indices = buildList {\n                                    add(a)\n                                    add(c)\n                                    add(d)\n\n                                    add(a)\n                                    add(b)\n                                    add(d)\n                                },\n                                x = x, y = y\n                            )\n                        )\n\n                    }\n                }\n            }\n\n        indices = indicesBlocks.flatMap { it.indices }\n        generateInterpolatedOffsets()\n    }\n\n    private fun generateInterpolatedOffsets() {\n        for (y in 0..points.lastIndex) {\n            for (x in 0..points[y].lastIndex) {\n                this[x * stepsX, y * stepsY] = points[y][x].first\n                this[x * stepsX, y * stepsY] = points[y][x].second\n\n                if (x != points[y].lastIndex) {\n                    val path = cubicPathX(\n                        point1 = points[y][x].first,\n                        point2 = points[y][x + 1].first,\n                        when (x) {\n                            0 -> 0\n                            points[y].lastIndex - 1 -> 2\n                            else -> 1\n                        }\n                    )\n                    measure.setPath(path, false)\n\n                    for (i in 1..<stepsX) {\n                        measure.getPosition(i / stepsX.toFloat() * measure.length).let {\n                            this[(x * stepsX) + i, (y * stepsY)] = Offset(it.x, it.y)\n                            this[(x * stepsX) + i, (y * stepsY)] =\n                                lerp(\n                                    points[y][x].second,\n                                    points[y][x + 1].second,\n                                    i / stepsX.toFloat(),\n                                )\n                        }\n                    }\n                }\n            }\n        }\n\n        for (y in 0..<points.lastIndex) {\n            for (x in 0..<this.xLength) {\n                val path = cubicPathY(\n                    point1 = this[x, y * stepsY].let { Offset(it.x, it.y) },\n                    point2 = this[x, (y + 1) * stepsY].let { Offset(it.x, it.y) },\n                    when (y) {\n                        0 -> 0\n                        points[y].lastIndex - 1 -> 2\n                        else -> 1\n                    }\n                )\n                measure.setPath(path, false)\n                for (i in (1..<stepsY)) {\n                    val point3 = measure.getPosition(i / stepsY.toFloat() * measure.length).let {\n                        Offset(it.x, it.y)\n                    }\n\n                    this[x, ((y * stepsY) + i)] = point3\n\n                    this[x, ((y * stepsY) + i)] = lerp(\n                        this.getColor(x, y * stepsY),\n                        this.getColor(x, (y + 1) * stepsY),\n                        i / stepsY.toFloat(),\n                    )\n\n                }\n            }\n        }\n    }\n\n    data class IndicesBlock(\n        val indices: List<Int>,\n        val x: Int,\n        val y: Int\n    )\n\n    operator fun get(\n        x: Int,\n        y: Int\n    ): Offset {\n        val index = (y * xLength) + x\n        return offsets[index]\n    }\n\n    private fun getColor(\n        x: Int,\n        y: Int\n    ): Color {\n        val index = (y * xLength) + x\n        return colors[index]\n    }\n\n    private operator fun set(\n        x: Int,\n        y: Int,\n        offset: Offset\n    ) {\n        val index = (y * xLength) + x\n        offsets[index] = Offset(offset.x, offset.y)\n    }\n\n    private operator fun set(\n        x: Int,\n        y: Int,\n        color: Color\n    ) {\n        val index = (y * xLength) + x\n        colors[index] = color\n    }\n}\n\nprivate fun cubicPathX(\n    point1: Offset,\n    point2: Offset,\n    position: Int\n): Path {\n    val path = Path().apply {\n        moveTo(point1.x, point1.y)\n        val delta = (point2.x - point1.x) * .5f\n        when (position) {\n            0 -> cubicTo(\n                point1.x, point1.y,\n                point2.x - delta, point2.y,\n                point2.x, point2.y\n            )\n\n            2 -> cubicTo(\n                point1.x + delta, point1.y,\n                point2.x, point2.y,\n                point2.x, point2.y\n            )\n\n            else -> cubicTo(\n                point1.x + delta, point1.y,\n                point2.x - delta, point2.y,\n                point2.x, point2.y\n            )\n        }\n\n        lineTo(point2.x, point2.y)\n    }\n    return path\n}\n\nprivate fun cubicPathY(\n    point1: Offset,\n    point2: Offset,\n    position: Int\n): Path {\n    val path = Path().apply {\n        moveTo(point1.x, point1.y)\n        val delta = (point2.y - point1.y) * .5f\n        when (position) {\n            0 -> cubicTo(\n                point1.x, point1.y,\n                point2.x, point2.y - delta,\n                point2.x, point2.y\n            )\n\n            2 -> cubicTo(\n                point1.x, point1.y + delta,\n                point2.x, point2.y,\n                point2.x, point2.y\n            )\n\n            else -> cubicTo(\n                point1.x, point1.y + delta,\n                point2.x, point2.y - delta,\n                point2.x, point2.y\n            )\n        }\n\n        lineTo(point2.x, point2.y)\n    }\n    return path\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/NegativePadding.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.offset\n\nfun Modifier.negativePadding(\n    paddingValues: PaddingValues\n): Modifier = this.layout { measurable, constraints ->\n    val horizontal = paddingValues.calculateLeftPadding(layoutDirection).roundToPx() +\n            paddingValues.calculateRightPadding(layoutDirection).roundToPx()\n    val vertical = paddingValues.calculateTopPadding().roundToPx() +\n            paddingValues.calculateBottomPadding().roundToPx()\n\n    val placeable = measurable.measure(constraints.offset(horizontal, vertical))\n\n    layout(\n        width = placeable.measuredWidth,\n        height = placeable.measuredHeight\n    ) {\n        placeable.place(0, 0)\n    }\n}\n\nfun Modifier.negativePadding(\n    all: Dp\n): Modifier = negativePadding(\n    PaddingValues(all)\n)\n\nfun Modifier.negativePadding(\n    horizontal: Dp = 0.dp,\n    vertical: Dp = 0.dp\n) = negativePadding(\n    PaddingValues(\n        horizontal = horizontal,\n        vertical = vertical\n    )\n)\n\nfun Modifier.negativePadding(\n    start: Dp = 0.dp,\n    top: Dp = 0.dp,\n    end: Dp = 0.dp,\n    bottom: Dp = 0.dp\n) = negativePadding(\n    PaddingValues(\n        start = start,\n        top = top,\n        end = end,\n        bottom = bottom\n    )\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/ObservePointersCount.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableLongStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.util.fastAny\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.isActive\nimport kotlin.coroutines.cancellation.CancellationException\n\n\nfun Modifier.observePointersCountWithOffset(\n    enabled: Boolean = true,\n    onChange: (Int, Offset) -> Unit\n) = this then if (enabled) Modifier.pointerInput(Unit) {\n    onEachGesture {\n        val context = currentCoroutineContext()\n        awaitPointerEventScope {\n            do {\n                val event = awaitPointerEvent()\n                onChange(\n                    event.changes.size,\n                    event.changes.firstOrNull()?.position ?: Offset.Unspecified\n                )\n            } while (event.changes.any { it.pressed } && context.isActive)\n            onChange(0, Offset.Unspecified)\n        }\n    }\n} else Modifier\n\nfun Modifier.observePointersCount(\n    enabled: Boolean = true,\n    onChange: (Int) -> Unit\n) = this.observePointersCountWithOffset(enabled) { size, _ ->\n    onChange(size)\n}\n\nsuspend fun PointerInputScope.onEachGesture(block: suspend PointerInputScope.() -> Unit) {\n    val currentContext = currentCoroutineContext()\n    while (currentContext.isActive) {\n        try {\n            block()\n\n            // Wait for all pointers to be up. Gestures start when a finger goes down.\n            awaitAllPointersUp()\n        } catch (e: CancellationException) {\n            if (currentContext.isActive) {\n                // The current gesture was canceled. Wait for all fingers to be \"up\" before looping\n                // again.\n                awaitAllPointersUp()\n            } else {\n                // forEachGesture was cancelled externally. Rethrow the cancellation exception to\n                // propagate it upwards.\n                throw e\n            }\n        }\n    }\n}\n\nprivate suspend fun PointerInputScope.awaitAllPointersUp() {\n    awaitPointerEventScope { awaitAllPointersUp() }\n}\n\nprivate suspend fun AwaitPointerEventScope.awaitAllPointersUp() {\n    if (!allPointersUp()) {\n        do {\n            val events = awaitPointerEvent(PointerEventPass.Final)\n        } while (events.changes.fastAny { it.pressed })\n    }\n}\n\nprivate fun AwaitPointerEventScope.allPointersUp(): Boolean =\n    !currentEvent.changes.fastAny { it.pressed }\n\n\n@Composable\nfun smartDelayAfterDownInMillis(pointersCount: Int): Long {\n    var delayAfterDownInMillis by remember {\n        mutableLongStateOf(20L)\n    }\n    var previousCount by remember {\n        mutableIntStateOf(pointersCount)\n    }\n    LaunchedEffect(pointersCount) {\n        delayAfterDownInMillis = if (pointersCount <= 1 && previousCount >= 2) 5L else 20L\n        previousCount = pointersCount\n    }\n\n    return delayAfterDownInMillis\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/Placholder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.InfiniteRepeatableSpec\nimport androidx.compose.animation.core.MutableTransitionState\nimport androidx.compose.animation.core.RepeatMode\nimport androidx.compose.animation.core.Transition\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.infiniteRepeatable\nimport androidx.compose.animation.core.rememberInfiniteTransition\nimport androidx.compose.animation.core.rememberTransition\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.geometry.toRect\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.drawIntoCanvas\nimport androidx.compose.ui.node.Ref\nimport androidx.compose.ui.platform.debugInspectorInfo\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.max\n\n/**\n * Contains default values used by [Modifier.placeholder] and [PlaceholderHighlight].\n */\nobject PlaceholderDefaults {\n    /**\n     * The default [InfiniteRepeatableSpec] to use for [fade].\n     */\n    val fadeAnimationSpec: InfiniteRepeatableSpec<Float> by lazy {\n        infiniteRepeatable(\n            animation = tween(delayMillis = 200, durationMillis = 600),\n            repeatMode = RepeatMode.Reverse,\n        )\n    }\n\n    /**\n     * The default [InfiniteRepeatableSpec] to use for [shimmer].\n     */\n    val shimmerAnimationSpec: InfiniteRepeatableSpec<Float> by lazy {\n        infiniteRepeatable(\n            animation = tween(durationMillis = 1700, delayMillis = 200),\n            repeatMode = RepeatMode.Restart\n        )\n    }\n}\n\n/**\n * Draws some skeleton UI which is typically used whilst content is 'loading'.\n *\n * A version of this modifier which uses appropriate values for Material themed apps is available\n * in the 'Placeholder Material' library.\n *\n * You can provide a [PlaceholderHighlight] which runs an highlight animation on the placeholder.\n * The [shimmer] and [fade] implementations are provided for easy usage.\n *\n * A cross-fade transition will be applied to the content and placeholder UI when the [visible]\n * value changes. The transition can be customized via the [contentFadeTransitionSpec] and\n * [placeholderFadeTransitionSpec] parameters.\n *\n * You can find more information on the pattern at the Material Theming\n * [Placeholder UI](https://material.io/design/communication/launch-screen.html#placeholder-ui)\n * guidelines.\n *\n * @param visible whether the placeholder should be visible or not.\n * @param color the color used to draw the placeholder UI.\n * @param shape desired shape of the placeholder. Defaults to [RectangleShape].\n * @param highlight optional highlight animation.\n * @param placeholderFadeTransitionSpec The transition spec to use when fading the placeholder\n * on/off screen. The boolean parameter defined for the transition is [visible].\n * @param contentFadeTransitionSpec The transition spec to use when fading the content\n * on/off screen. The boolean parameter defined for the transition is [visible].\n */\nfun Modifier.placeholder(\n    visible: Boolean,\n    color: Color,\n    shape: Shape = RectangleShape,\n    highlight: PlaceholderHighlight? = null,\n    placeholderFadeTransitionSpec: @Composable Transition.Segment<Boolean>.() -> FiniteAnimationSpec<Float> = { spring() },\n    contentFadeTransitionSpec: @Composable Transition.Segment<Boolean>.() -> FiniteAnimationSpec<Float> = { spring() },\n): Modifier = composed(\n    inspectorInfo = debugInspectorInfo {\n        name = \"placeholder\"\n        value = visible\n        properties[\"visible\"] = visible\n        properties[\"color\"] = color\n        properties[\"highlight\"] = highlight\n        properties[\"shape\"] = shape\n    }\n) {\n    // Values used for caching purposes\n    val lastSize = remember { Ref<Size>() }\n    val lastLayoutDirection = remember { Ref<LayoutDirection>() }\n    val lastOutline = remember { Ref<Outline>() }\n\n    // The current highlight animation progress\n    var highlightProgress: Float by remember { mutableFloatStateOf(0f) }\n\n    // This is our crossfade transition\n    val transitionState = remember { MutableTransitionState(visible) }.apply {\n        targetState = visible\n    }\n    val transition = rememberTransition(transitionState, \"placeholder_crossfade\")\n\n    val placeholderAlpha by transition.animateFloat(\n        transitionSpec = placeholderFadeTransitionSpec,\n        label = \"placeholder_fade\",\n        targetValueByState = { placeholderVisible -> if (placeholderVisible) 1f else 0f }\n    )\n    val contentAlpha by transition.animateFloat(\n        transitionSpec = contentFadeTransitionSpec,\n        label = \"content_fade\",\n        targetValueByState = { placeholderVisible -> if (placeholderVisible) 0f else 1f }\n    )\n\n    // Run the optional animation spec and update the progress if the placeholder is visible\n    val animationSpec = highlight?.animationSpec\n    if (animationSpec != null && (visible || placeholderAlpha >= 0.01f)) {\n        val infiniteTransition = rememberInfiniteTransition(label = \"\")\n        highlightProgress = infiniteTransition.animateFloat(\n            initialValue = 0f,\n            targetValue = 1f,\n            animationSpec = animationSpec, label = \"\",\n        ).value\n    }\n\n    val paint = remember { Paint() }\n    remember(color, shape, highlight) {\n        drawWithContent {\n            // Draw the composable content first\n            if (contentAlpha in 0.01f..0.99f) {\n                // If the content alpha is between 1% and 99%, draw it in a layer with\n                // the alpha applied\n                paint.alpha = contentAlpha\n                withLayer(paint) {\n                    with(this@drawWithContent) {\n                        drawContent()\n                    }\n                }\n            } else if (contentAlpha >= 0.99f) {\n                // If the content alpha is > 99%, draw it with no alpha\n                drawContent()\n            }\n\n            if (placeholderAlpha in 0.01f..0.99f) {\n                // If the placeholder alpha is between 1% and 99%, draw it in a layer with\n                // the alpha applied\n                paint.alpha = placeholderAlpha\n                withLayer(paint) {\n                    lastOutline.value = drawPlaceholder(\n                        shape = shape,\n                        color = color,\n                        highlight = highlight,\n                        progress = highlightProgress,\n                        lastOutline = lastOutline.value,\n                        lastLayoutDirection = lastLayoutDirection.value,\n                        lastSize = lastSize.value,\n                    )\n                }\n            } else if (placeholderAlpha >= 0.99f) {\n                // If the placeholder alpha is > 99%, draw it with no alpha\n                lastOutline.value = drawPlaceholder(\n                    shape = shape,\n                    color = color,\n                    highlight = highlight,\n                    progress = highlightProgress,\n                    lastOutline = lastOutline.value,\n                    lastLayoutDirection = lastLayoutDirection.value,\n                    lastSize = lastSize.value,\n                )\n            }\n\n            // Keep track of the last size & layout direction\n            lastSize.value = size\n            lastLayoutDirection.value = layoutDirection\n        }\n    }\n}\n\nprivate fun DrawScope.drawPlaceholder(\n    shape: Shape,\n    color: Color,\n    highlight: PlaceholderHighlight?,\n    progress: Float,\n    lastOutline: Outline?,\n    lastLayoutDirection: LayoutDirection?,\n    lastSize: Size?,\n): Outline? {\n    // shortcut to avoid Outline calculation and allocation\n    if (shape === RectangleShape) {\n        // Draw the initial background color\n        drawRect(color = color)\n\n        if (highlight != null) {\n            drawRect(\n                brush = highlight.brush(progress, size),\n                alpha = highlight.alpha(progress),\n            )\n        }\n        // We didn't create an outline so return null\n        return null\n    }\n\n    // Otherwise we need to create an outline from the shape\n    val outline = lastOutline.takeIf {\n        size == lastSize && layoutDirection == lastLayoutDirection\n    } ?: shape.createOutline(size, layoutDirection, this)\n\n    // Draw the placeholder color\n    drawOutline(outline = outline, color = color)\n\n    if (highlight != null) {\n        drawOutline(\n            outline = outline,\n            brush = highlight.brush(progress, size),\n            alpha = highlight.alpha(progress),\n        )\n    }\n\n    // Return the outline we used\n    return outline\n}\n\nprivate inline fun DrawScope.withLayer(\n    paint: Paint,\n    drawBlock: DrawScope.() -> Unit,\n) = drawIntoCanvas { canvas ->\n    canvas.saveLayer(size.toRect(), paint)\n    drawBlock()\n    canvas.restore()\n}\n\n/**\n * A class which provides a brush to paint placeholder based on progress.\n */\n@Stable\ninterface PlaceholderHighlight {\n    /**\n     * The optional [AnimationSpec] to use when running the animation for this highlight.\n     */\n    val animationSpec: InfiniteRepeatableSpec<Float>?\n\n    /**\n     * Return a [Brush] to draw for the given [progress] and [size].\n     *\n     * @param progress the current animated progress in the range of 0f..1f.\n     * @param size The size of the current layout to draw in.\n     */\n    fun brush(\n        @FloatRange(from = 0.0, to = 1.0) progress: Float,\n        size: Size\n    ): Brush\n\n    /**\n     * Return the desired alpha value used for drawing the [Brush] returned from [brush].\n     *\n     * @param progress the current animated progress in the range of 0f..1f.\n     */\n    @FloatRange(from = 0.0, to = 1.0)\n    fun alpha(progress: Float): Float\n\n    companion object\n}\n\n/**\n * Creates a [Fade] brush with the given initial and target colors.\n *\n * @param highlightColor the color of the highlight which is faded in/out.\n * @param animationSpec the [AnimationSpec] to configure the animation.\n */\nfun PlaceholderHighlight.Companion.fade(\n    highlightColor: Color,\n    animationSpec: InfiniteRepeatableSpec<Float> = PlaceholderDefaults.fadeAnimationSpec,\n): PlaceholderHighlight = Fade(\n    highlightColor = highlightColor,\n    animationSpec = animationSpec,\n)\n\n/**\n * Creates a [PlaceholderHighlight] which 'shimmers', using the given [highlightColor].\n *\n * The highlight starts at the top-start, and then grows to the bottom-end during the animation.\n * During that time it is also faded in, from 0f..progressForMaxAlpha, and then faded out from\n * progressForMaxAlpha..1f.\n *\n * @param highlightColor the color of the highlight 'shimmer'.\n * @param animationSpec the [AnimationSpec] to configure the animation.\n * @param progressForMaxAlpha The progress where the shimmer should be at it's peak opacity.\n * Defaults to 0.6f.\n */\nfun PlaceholderHighlight.Companion.shimmer(\n    highlightColor: Color,\n    animationSpec: InfiniteRepeatableSpec<Float> = PlaceholderDefaults.shimmerAnimationSpec,\n    @FloatRange(from = 0.0, to = 1.0) progressForMaxAlpha: Float = 0.6f,\n): PlaceholderHighlight = Shimmer(\n    highlightColor = highlightColor,\n    animationSpec = animationSpec,\n    progressForMaxAlpha = progressForMaxAlpha,\n)\n\nprivate data class Fade(\n    private val highlightColor: Color,\n    override val animationSpec: InfiniteRepeatableSpec<Float>,\n) : PlaceholderHighlight {\n    private val brush = SolidColor(highlightColor)\n\n    override fun brush(progress: Float, size: Size): Brush = brush\n    override fun alpha(progress: Float): Float = progress\n}\n\nprivate data class Shimmer(\n    private val highlightColor: Color,\n    override val animationSpec: InfiniteRepeatableSpec<Float>,\n    private val progressForMaxAlpha: Float = 0.6f,\n) : PlaceholderHighlight {\n    override fun brush(\n        progress: Float,\n        size: Size,\n    ): Brush = Brush.radialGradient(\n        colors = listOf(\n            highlightColor.copy(alpha = 0f),\n            highlightColor,\n            highlightColor.copy(alpha = 0f),\n        ),\n        center = Offset(x = 0f, y = 0f),\n        radius = (max(size.width, size.height) * progress * 2).coerceAtLeast(0.01f),\n    )\n\n    override fun alpha(progress: Float): Float = when {\n        // From 0f...ProgressForOpaqueAlpha we animate from 0..1\n        progress <= progressForMaxAlpha -> {\n            lerp(\n                start = 0f,\n                stop = 1f,\n                fraction = progress / progressForMaxAlpha\n            )\n        }\n        // From ProgressForOpaqueAlpha..1f we animate from 1..0\n        else -> {\n            lerp(\n                start = 1f,\n                stop = 0f,\n                fraction = (progress - progressForMaxAlpha) / (1f - progressForMaxAlpha)\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/PointerInput.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport kotlinx.coroutines.coroutineScope\n\nsuspend fun PointerInputScope.interceptTap(\n    pass: PointerEventPass = PointerEventPass.Initial,\n    onTap: ((Offset) -> Unit)? = null,\n) = coroutineScope {\n    if (onTap == null) return@coroutineScope\n\n    awaitEachGesture {\n        val down = awaitFirstDown(pass = pass)\n        val downTime = System.currentTimeMillis()\n        val tapTimeout = viewConfiguration.longPressTimeoutMillis\n        val tapPosition = down.position\n\n        do {\n            val event = awaitPointerEvent(pass)\n            val currentTime = System.currentTimeMillis()\n\n            if (event.changes.size != 1) break // More than one event: not a tap\n            if (currentTime - downTime >= tapTimeout) break // Too slow: not a tap\n\n            val change = event.changes[0]\n\n            if ((change.position - tapPosition).getDistance() > viewConfiguration.touchSlop) break\n\n            if (change.id == down.id && !change.pressed) {\n                change.consume()\n                onTap(change.position)\n            }\n        } while (event.changes.any { it.id == down.id && it.pressed })\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/Pulsate.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.RepeatMode\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.infiniteRepeatable\nimport androidx.compose.animation.core.rememberInfiniteTransition\nimport androidx.compose.animation.core.tween\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.scale\n\nfun Modifier.pulsate(\n    range: ClosedFloatingPointRange<Float> = 0.95f..1.05f,\n    duration: Int = 1000,\n    enabled: Boolean = true\n) = this.composed {\n    val infiniteTransition = rememberInfiniteTransition()\n\n    val scale by infiniteTransition.animateFloat(\n        initialValue = range.start,\n        targetValue = range.endInclusive,\n        animationSpec = infiniteRepeatable(\n            animation = tween(durationMillis = duration),\n            repeatMode = RepeatMode.Reverse\n        )\n    )\n\n    if (enabled) Modifier.scale(scale)\n    else this\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/RealisticSnowfall.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport android.annotation.SuppressLint\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.painter.Painter\nimport com.t8rin.snowfall.snowfall\nimport com.t8rin.snowfall.types.FlakeType\nimport kotlin.random.Random\n\n@SuppressLint(\"UnnecessaryComposedModifier\")\nfun Modifier.realisticSnowfall(\n    enabled: Boolean = true\n): Modifier = this.composed {\n    if (enabled) {\n        Modifier.snowfall(\n            type = FlakeType.Custom(flakes),\n            color = MaterialTheme.colorScheme.primary\n        )\n    } else Modifier\n}\n\nprivate val flakes = List(100) {\n    val size = (40 * Random.nextDouble(0.3, 1.0)).toFloat()\n    object : Painter() {\n        override val intrinsicSize: Size = Size(size, size)\n\n        override fun DrawScope.onDraw() {\n            drawCircle(\n                brush = Brush.radialGradient(\n                    listOf(\n                        Color.White,\n                        Color.Transparent,\n                    )\n                )\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/RotateAnimation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.RepeatMode\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.infiniteRepeatable\nimport androidx.compose.animation.core.rememberInfiniteTransition\nimport androidx.compose.animation.core.tween\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.rotate\n\nfun Modifier.rotateAnimation(\n    range: IntRange = 0..180,\n    duration: Int = 1000,\n    enabled: Boolean = true\n) = this.composed {\n    val infiniteTransition = rememberInfiniteTransition()\n\n    val rotation by infiniteTransition.animateFloat(\n        initialValue = range.first.toFloat(),\n        targetValue = range.last.toFloat(),\n        animationSpec = infiniteRepeatable(\n            animation = tween(durationMillis = duration),\n            repeatMode = RepeatMode.Reverse\n        )\n    )\n\n    if (enabled) Modifier.rotate(rotation)\n    else this\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/ScaleOnTap.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.springySpec\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport kotlinx.coroutines.delay\n\nfun Modifier.scaleOnTap(\n    initial: Float = 1f,\n    min: Float = 0.8f,\n    max: Float = 1.3f,\n    interactionSource: MutableInteractionSource? = null,\n    onHold: () -> Unit = {},\n    onRelease: (time: Long) -> Unit\n) = this.composed {\n    var scaleState by remember(initial) { mutableFloatStateOf(initial) }\n    val scale by animateFloatAsState(\n        targetValue = scaleState,\n        animationSpec = springySpec()\n    )\n    val haptics = LocalHapticFeedback.current\n\n    val onHoldState = rememberUpdatedState(onHold)\n    val onReleaseState = rememberUpdatedState(onRelease)\n\n    Modifier\n        .scale(scale)\n        .pointerInput(min, max, initial) {\n            detectTapGestures(\n                onPress = {\n                    val time = System.currentTimeMillis()\n                    scaleState = max\n                    haptics.longPress()\n\n                    val press = PressInteraction.Press(it)\n\n                    interactionSource?.emit(press)\n\n                    onHoldState.value()\n\n                    delay(200)\n\n                    tryAwaitRelease()\n\n                    onReleaseState.value(System.currentTimeMillis() - time)\n\n                    haptics.longPress()\n\n                    interactionSource?.emit(PressInteraction.Release(press))\n\n                    scaleState = min\n                    delay(200)\n                    scaleState = initial\n                }\n            )\n        }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/ShapeDefaults.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationVector1D\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.collectIsFocusedAsState\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.shape.CornerBasedShape\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastCoerceIn\nimport androidx.lifecycle.compose.LifecycleResumeEffect\nimport com.t8rin.imagetoolbox.core.domain.utils.autoCast\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.lessSpringySpec\nimport kotlinx.coroutines.channels.Channel\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.launch\n\nobject ShapeDefaults {\n\n    @Composable\n    fun byIndex(\n        index: Int,\n        size: Int,\n        forceDefault: Boolean = false,\n        vertical: Boolean = true\n    ): Shape {\n        val internalShape = when {\n            index == -1 || size == 1 || forceDefault -> default\n            index == 0 && size > 1 -> if (vertical) top else start\n            index == size - 1 -> if (vertical) bottom else end\n            else -> center\n        }\n\n        return AutoCornersShape(\n            topStart = internalShape.topStart.animate(),\n            topEnd = internalShape.topEnd.animate(),\n            bottomStart = internalShape.bottomStart.animate(),\n            bottomEnd = internalShape.bottomEnd.animate()\n        )\n    }\n\n    val top\n        @Composable get() = AutoCornersShape(\n            topStart = 16.dp,\n            topEnd = 16.dp,\n            bottomStart = 4.dp,\n            bottomEnd = 4.dp\n        )\n\n    val center\n        @Composable get() = AutoCornersShape(\n            topStart = 4.dp,\n            topEnd = 4.dp,\n            bottomStart = 4.dp,\n            bottomEnd = 4.dp\n        )\n\n    val bottom\n        @Composable get() = AutoCornersShape(\n            topStart = 4.dp,\n            topEnd = 4.dp,\n            bottomStart = 16.dp,\n            bottomEnd = 16.dp\n        )\n\n    val start\n        @Composable get() = AutoCornersShape(\n            topStart = 16.dp,\n            topEnd = 4.dp,\n            bottomStart = 16.dp,\n            bottomEnd = 4.dp\n        )\n\n    val end\n        @Composable get() = AutoCornersShape(\n            topStart = 4.dp,\n            topEnd = 16.dp,\n            bottomStart = 4.dp,\n            bottomEnd = 16.dp\n        )\n\n    val topEnd\n        @Composable get() = AutoCornersShape(\n            topEnd = 16.dp,\n            topStart = 4.dp,\n            bottomEnd = 4.dp,\n            bottomStart = 4.dp\n        )\n\n    val topStart\n        @Composable get() = AutoCornersShape(\n            topEnd = 4.dp,\n            topStart = 16.dp,\n            bottomEnd = 4.dp,\n            bottomStart = 4.dp\n        )\n\n    val bottomEnd\n        @Composable get() = AutoCornersShape(\n            topEnd = 4.dp,\n            topStart = 4.dp,\n            bottomEnd = 16.dp,\n            bottomStart = 4.dp\n        )\n\n    val smallTop\n        @Composable get() = AutoCornersShape(\n            topStart = 12.dp,\n            topEnd = 12.dp,\n            bottomStart = 4.dp,\n            bottomEnd = 4.dp\n        )\n\n    val smallBottom\n        @Composable get() = AutoCornersShape(\n            topStart = 4.dp,\n            topEnd = 4.dp,\n            bottomStart = 12.dp,\n            bottomEnd = 12.dp\n        )\n\n    val smallStart\n        @Composable get() = AutoCornersShape(\n            topStart = 12.dp,\n            topEnd = 4.dp,\n            bottomStart = 12.dp,\n            bottomEnd = 4.dp\n        )\n\n    val smallEnd\n        @Composable get() = AutoCornersShape(\n            topEnd = 12.dp,\n            topStart = 4.dp,\n            bottomEnd = 12.dp,\n            bottomStart = 4.dp\n        )\n\n    val extremeSmall @Composable get() = AutoCornersShape(2.dp)\n\n    val extraSmall @Composable get() = AutoCornersShape(4.dp)\n\n    val pressed @Composable get() = AutoCornersShape(6.dp)\n\n    val mini @Composable get() = AutoCornersShape(8.dp)\n\n    val smallMini @Composable get() = AutoCornersShape(10.dp)\n\n    val small @Composable get() = AutoCornersShape(12.dp)\n\n    val default @Composable get() = AutoCornersShape(16.dp)\n\n    val large @Composable get() = AutoCornersShape(20.dp)\n\n    val extraLarge @Composable get() = AutoCornersShape(24.dp)\n\n    val extremeLarge @Composable get() = AutoCornersShape(28.dp)\n\n    val circle @Composable get() = AutoCircleShape()\n\n    @Composable\n    private inline fun CornerSize.animate(): Dp = animateDpAsState(\n        targetValue = with(LocalDensity.current) {\n            toPx(\n                shapeSize = Size.Unspecified,\n                density = this\n            ).toDp()\n        },\n        animationSpec = lessSpringySpec()\n    ).value\n\n}\n\n@JvmInline\nvalue class CornerSides internal constructor(private val mask: Int) {\n    companion object {\n        val TopStart = CornerSides(1 shl 0)\n        val TopEnd = CornerSides(1 shl 1)\n        val BottomStart = CornerSides(1 shl 2)\n        val BottomEnd = CornerSides(1 shl 3)\n\n        val Top = TopStart + TopEnd\n        val Bottom = BottomStart + BottomEnd\n        val Start = TopStart + BottomStart\n        val End = TopEnd + BottomEnd\n\n        val All = Top + Bottom\n        val None = CornerSides(0)\n    }\n\n    operator fun plus(other: CornerSides): CornerSides = CornerSides(mask or other.mask)\n\n    operator fun contains(other: CornerSides): Boolean = (mask and other.mask) == other.mask\n\n    fun has(other: CornerSides): Boolean = contains(other)\n}\n\n\ninline fun <reified S : CornerBasedShape> S.only(\n    sides: CornerSides\n): S = autoCast {\n    copy(\n        topStart = if (sides.has(CornerSides.TopStart)) topStart else ZeroCornerSize,\n        topEnd = if (sides.has(CornerSides.TopEnd)) topEnd else ZeroCornerSize,\n        bottomEnd = if (sides.has(CornerSides.BottomEnd)) bottomEnd else ZeroCornerSize,\n        bottomStart = if (sides.has(CornerSides.BottomStart)) bottomStart else ZeroCornerSize,\n    )\n}\n\nval ZeroCornerSize: CornerSize = CornerSize(0f)\n\n@Stable\ninternal class AnimatedShape(\n    initialShape: CornerBasedShape,\n    val shapesType: ShapeType,\n    private val density: Density,\n    private val animationSpec: FiniteAnimationSpec<Float>,\n) : Shape {\n\n    private var size: Size = Size(\n        width = with(density) { 48.dp.toPx() },\n        height = with(density) { 48.dp.toPx() }\n    )\n\n    private val halfHeight: Float get() = size.height / 2f\n\n    private val topStart = Animatable(initialShape.topStart.toPx())\n    private val topEnd = Animatable(initialShape.topEnd.toPx())\n    private val bottomStart = Animatable(initialShape.bottomStart.toPx())\n    private val bottomEnd = Animatable(initialShape.bottomEnd.toPx())\n\n    private inline fun CornerSize.toPx() = toPx(size, density)\n\n    private suspend inline fun ShapeAnimatable.animateTo(\n        cornerSize: CornerSize\n    ) = animateTo(\n        targetValue = cornerSize.toPx(),\n        animationSpec = animationSpec\n    )\n\n    private inline fun ShapeAnimatable.boundedValue() = value.fastCoerceIn(0f, halfHeight)\n\n    suspend fun animateTo(targetShape: CornerBasedShape) = coroutineScope {\n        launch { topStart.animateTo(targetShape.topStart) }\n        launch { topEnd.animateTo(targetShape.topEnd) }\n        launch { bottomStart.animateTo(targetShape.bottomStart) }\n        launch { bottomEnd.animateTo(targetShape.bottomEnd) }\n    }\n\n    override fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density\n    ): Outline = createOutline(\n        size = size,\n        layoutDirection = layoutDirection,\n        density = density,\n        shapesType = shapesType\n    )\n\n    fun createOutline(\n        size: Size,\n        layoutDirection: LayoutDirection,\n        density: Density,\n        shapesType: ShapeType\n    ): Outline {\n        if (size.width > 1f && size.height > 1f) {\n            this.size = size\n        }\n\n        return AutoCornersShape(\n            topStart = CornerSize(topStart.boundedValue()),\n            topEnd = CornerSize(topEnd.boundedValue()),\n            bottomStart = CornerSize(bottomStart.boundedValue()),\n            bottomEnd = CornerSize(bottomEnd.boundedValue()),\n            shapesType = shapesType.copy(1f)\n        ).createOutline(\n            size = size,\n            layoutDirection = layoutDirection,\n            density = density\n        )\n    }\n\n}\n\ninternal typealias ShapeAnimatable = Animatable<Float, AnimationVector1D>\n\n@Composable\ninternal fun rememberAnimatedShape(\n    currentShape: CornerBasedShape,\n    animationSpec: FiniteAnimationSpec<Float> = lessSpringySpec(),\n): AnimatedShape {\n    val density = LocalDensity.current\n    val shapesType = LocalSettingsState.current.shapesType\n\n    val state = remember(animationSpec, density, shapesType) {\n        AnimatedShape(\n            shapesType = shapesType,\n            initialShape = currentShape,\n            animationSpec = animationSpec,\n            density = density\n        )\n    }\n\n    val channel = remember { Channel<CornerBasedShape>(Channel.CONFLATED) }\n\n    SideEffect { channel.trySend(currentShape) }\n\n    LifecycleResumeEffect(Unit) {\n        channel.trySend(currentShape)\n\n        onPauseOrDispose {\n            channel.trySend(currentShape)\n        }\n    }\n\n    LaunchedEffect(state, channel) {\n        for (target in channel) {\n            val newTarget = channel.tryReceive().getOrNull() ?: target\n            launch { state.animateTo(newTarget) }\n        }\n    }\n\n    return state\n}\n\n@Composable\nfun animateShape(\n    targetValue: CornerBasedShape,\n    animationSpec: FiniteAnimationSpec<Float> = lessSpringySpec(),\n): Shape = rememberAnimatedShape(\n    currentShape = targetValue,\n    animationSpec = animationSpec\n)\n\n@Composable\nfun shapeByInteraction(\n    shape: Shape,\n    pressedShape: Shape,\n    interactionSource: InteractionSource?,\n    animationSpec: FiniteAnimationSpec<Float> = lessSpringySpec(),\n    enabled: Boolean = true\n): Shape {\n    if (!enabled || interactionSource == null) return shape\n\n    val pressed by interactionSource.collectIsPressedAsState()\n    val focused by interactionSource.collectIsFocusedAsState()\n\n    val usePressedShape = pressed || focused\n\n    val targetShape = if (usePressedShape) pressedShape else shape\n\n    if (targetShape is CornerBasedShape) {\n        return animateShape(\n            targetValue = targetShape,\n            animationSpec = animationSpec,\n        )\n    }\n\n    return targetShape\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/Shimmer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.harmonizeWithPrimary\n\nfun Modifier.shimmer(\n    visible: Boolean,\n    color: Color = Color.Unspecified\n) = this.composed {\n    Modifier.placeholder(\n        visible = visible,\n        color = color.takeOrElse {\n            MaterialTheme.colorScheme.surfaceColorAtElevation(16.dp)\n        },\n        highlight = PlaceholderHighlight.shimmer(\n            highlightColor = color.harmonizeWithPrimary(0.5f)\n        )\n    )\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/Tappable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalFocusManager\n\nfun Modifier.tappable(\n    key1: Any? = Unit,\n    onTap: PointerInputScope.(Offset) -> Unit\n): Modifier = pointerInput(key1) {\n    detectTapGestures { onTap(it) }\n}\n\nfun Modifier.clearFocusOnTap(enabled: Boolean = true) = composed {\n    val focus = LocalFocusManager.current\n\n    if (enabled) {\n        Modifier.pointerInput(focus) {\n            detectTapGestures(\n                onTap = {\n                    focus.clearFocus()\n                }\n            )\n        }\n    } else {\n        Modifier\n    }\n}\n\n@Composable\nfun Disableable(\n    enabled: Boolean,\n    onDisabledClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    content: @Composable () -> Unit\n) {\n    Box(\n        modifier = modifier\n            .alpha(if (enabled) 1f else 0.5f)\n    ) {\n        content()\n        if (!enabled) {\n            Surface(\n                color = Color.Transparent,\n                modifier = Modifier\n                    .matchParentSize()\n                    .tappable(onDisabledClick) {\n                        onDisabledClick()\n                    }\n            ) {}\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/TransparencyChecker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.drawWithCache\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\n\n\nfun Modifier.transparencyChecker(\n    colorScheme: ColorScheme? = null,\n    checkerWidth: Dp = 10.dp,\n    checkerHeight: Dp = 10.dp,\n) = this.composed {\n    val scheme = colorScheme ?: MaterialTheme.colorScheme\n\n    Modifier.drawWithCache {\n        val width = this.size.width\n        val height = this.size.height\n\n        val checkerWidthPx = checkerWidth.toPx()\n        val checkerHeightPx = checkerHeight.toPx()\n\n        val horizontalSteps = (width / checkerWidthPx).toInt()\n        val verticalSteps = (height / checkerHeightPx).toInt()\n\n        onDrawBehind {\n            drawRect(\n                scheme.surfaceColorAtElevation(20.dp).blend(scheme.surface, 0.5f)\n            )\n            for (y in 0..verticalSteps) {\n                for (x in 0..horizontalSteps) {\n                    val isGrayTile = ((x + y) % 2 == 1)\n                    drawRect(\n                        color = if (isGrayTile) {\n                            scheme.surfaceColorAtElevation(20.dp)\n                        } else scheme.surface,\n                        topLeft = Offset(x * checkerWidthPx, y * checkerHeightPx),\n                        size = Size(checkerWidthPx, checkerHeightPx)\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/modifier/WithModifier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.modifier\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\n\n@Composable\nfun (@Composable () -> Unit).withModifier(\n    modifier: Modifier,\n    contentAlignment: Alignment = Alignment.Center\n) = Box(\n    modifier = modifier,\n    contentAlignment = contentAlignment\n) { this@withModifier() }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/AnimatedBorder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.core.LinearEasing\nimport androidx.compose.animation.core.RepeatMode\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.infiniteRepeatable\nimport androidx.compose.animation.core.rememberInfiniteTransition\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun AnimatedBorder(\n    modifier: Modifier,\n    alpha: Float,\n    scale: Float,\n    shape: Shape\n) {\n    val pathEffect = rememberAnimatedBorder()\n\n    val density = LocalDensity.current\n    val colorScheme = MaterialTheme.colorScheme\n\n    Canvas(modifier = modifier) {\n        val outline = shape.createOutline(\n            size = size,\n            layoutDirection = layoutDirection,\n            density = density\n        )\n        drawOutline(\n            outline = outline,\n            color = colorScheme.primary.copy(alpha),\n            style = Stroke(\n                width = 3.dp.toPx() * (1f / scale)\n            )\n        )\n        drawOutline(\n            outline = outline,\n            color = colorScheme.primaryContainer.copy(alpha),\n            style = Stroke(\n                width = 3.dp.toPx() * (1f / scale),\n                pathEffect = pathEffect\n            )\n        )\n    }\n}\n\n@Composable\nfun rememberAnimatedBorder(\n    intervals: FloatArray = floatArrayOf(20f, 20f),\n    phase: Float = 80f,\n    repeatDuration: Int = 1000\n): PathEffect = PathEffect.dashPathEffect(\n    intervals = intervals,\n    phase = rememberAnimatedBorderPhase(\n        phase = phase,\n        repeatDuration = repeatDuration\n    )\n)\n\n@Composable\nfun rememberAnimatedBorderPhase(\n    phase: Float = 80f,\n    repeatDuration: Int = 1000\n): Float {\n    val transition = rememberInfiniteTransition()\n\n    val animatedPhase by transition.animateFloat(\n        initialValue = 0f,\n        targetValue = phase,\n        animationSpec = infiniteRepeatable(\n            animation = tween(\n                durationMillis = repeatDuration,\n                easing = LinearEasing\n            ),\n            repeatMode = RepeatMode.Restart\n        )\n    )\n\n    return animatedPhase\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/BoxAnimatedVisibility.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.AnimatedVisibilityScope\nimport androidx.compose.animation.EnterTransition\nimport androidx.compose.animation.ExitTransition\nimport androidx.compose.animation.expandIn\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkOut\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\n\n@Composable\nfun BoxAnimatedVisibility(\n    visible: Boolean,\n    modifier: Modifier = Modifier,\n    enter: EnterTransition = fadeIn() + expandIn(),\n    exit: ExitTransition = shrinkOut() + fadeOut(),\n    label: String = \"AnimatedVisibility\",\n    content: @Composable AnimatedVisibilityScope.() -> Unit\n) = androidx.compose.animation.AnimatedVisibility(visible, modifier, enter, exit, label, content)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/ColorWithNameItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.BookmarkBorder\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.colors.parser.ColorNameParser\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BookmarkRemove\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.CombinedMutableInteractionSource\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport kotlinx.coroutines.runBlocking\n\n@Composable\nfun ColorWithNameItem(\n    color: Color,\n    name: String? = null,\n    isFavorite: Boolean = false,\n    onToggleFavorite: (() -> Unit)? = null,\n    onCopy: () -> Unit,\n    modifier: Modifier = Modifier,\n    containerShape: Shape = ShapeDefaults.default\n) {\n    val boxColor by animateColorAsState(color)\n    val contentColor = boxColor.inverse(\n        fraction = { cond ->\n            if (cond) 0.8f\n            else 0.5f\n        },\n        darkMode = boxColor.luminance() < 0.3f\n    )\n    val favoriteInteractionSource = remember { MutableInteractionSource() }\n    val copyInteractionSource = remember { MutableInteractionSource() }\n    val interactionSource = remember {\n        CombinedMutableInteractionSource(\n            favoriteInteractionSource,\n            copyInteractionSource\n        )\n    }\n\n    val shape = shapeByInteraction(\n        shape = containerShape,\n        pressedShape = ShapeDefaults.pressed,\n        interactionSource = interactionSource\n    )\n    val colorName = name ?: remember(color) {\n        ColorNameParser.parseColorName(color)\n    }\n\n    Column(\n        modifier = modifier\n            .heightIn(min = 100.dp)\n            .fillMaxWidth()\n            .clip(shape)\n            .then(\n                if (onToggleFavorite == null) {\n                    Modifier.hapticsClickable(\n                        indication = LocalIndication.current,\n                        interactionSource = copyInteractionSource,\n                        onClick = onCopy\n                    )\n                } else {\n                    Modifier\n                }\n            )\n            .then(\n                if (color.alpha < 1f) Modifier.transparencyChecker()\n                else Modifier\n            )\n            .background(boxColor),\n        verticalArrangement = Arrangement.SpaceBetween\n    ) {\n        Row(\n            modifier = Modifier.fillMaxWidth(),\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.SpaceBetween\n        ) {\n            AutoSizeText(\n                text = remember(color) { color.toHex() },\n                color = contentColor,\n                modifier = Modifier\n                    .weight(1f, false)\n                    .padding(\n                        start = 4.dp,\n                        top = 4.dp,\n                        bottom = 4.dp\n                    )\n                    .background(\n                        color = boxColor.copy(alpha = 1f),\n                        shape = ShapeDefaults.mini\n                    )\n                    .padding(4.dp),\n                style = LocalTextStyle.current.copy(\n                    fontSize = 12.sp,\n                    lineHeight = 12.5.sp\n                ),\n                key = {\n                    color to colorName\n                }\n            )\n\n            Icon(\n                imageVector = Icons.Rounded.ContentCopy,\n                contentDescription = stringResource(R.string.copy),\n                tint = contentColor.copy(0.8f),\n                modifier = Modifier\n                    .padding(\n                        end = 2.dp,\n                        top = 4.dp,\n                        bottom = 4.dp\n                    )\n                    .size(26.dp)\n                    .clip(ShapeDefaults.mini)\n                    .background(boxColor.copy(alpha = 1f))\n                    .hapticsClickable(\n                        indication = LocalIndication.current,\n                        interactionSource = copyInteractionSource,\n                        onClick = onCopy\n                    )\n                    .padding(4.dp)\n            )\n        }\n\n        Row(\n            modifier = Modifier.fillMaxWidth(),\n            verticalAlignment = Alignment.Bottom,\n            horizontalArrangement = Arrangement.SpaceBetween\n        ) {\n            if (onToggleFavorite != null) {\n                Icon(\n                    imageVector = if (isFavorite) {\n                        Icons.Rounded.BookmarkRemove\n                    } else {\n                        Icons.Outlined.BookmarkBorder\n                    },\n                    contentDescription = stringResource(R.string.favorite),\n                    tint = contentColor.copy(0.8f),\n                    modifier = Modifier\n                        .padding(\n                            start = 2.dp,\n                            top = 4.dp,\n                            bottom = 4.dp\n                        )\n                        .size(26.dp)\n                        .clip(ShapeDefaults.mini)\n                        .background(boxColor.copy(alpha = 1f))\n                        .hapticsClickable(\n                            indication = LocalIndication.current,\n                            interactionSource = favoriteInteractionSource,\n                            onClick = onToggleFavorite\n                        )\n                        .padding(4.dp)\n                )\n            } else {\n                Spacer(Modifier)\n            }\n\n            Text(\n                text = colorName,\n                color = contentColor,\n                modifier = Modifier\n                    .padding(\n                        end = 4.dp,\n                        top = 4.dp,\n                        bottom = 4.dp\n                    )\n                    .background(\n                        color = boxColor.copy(alpha = 1f),\n                        shape = ShapeDefaults.mini\n                    )\n                    .padding(4.dp),\n                fontSize = 12.sp,\n                lineHeight = 12.5.sp,\n                textAlign = TextAlign.End\n            )\n        }\n    }\n}\n\n@Preview\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    runBlocking {\n        ColorNameParser.init(appContext)\n    }\n\n    val colors = remember {\n        ColorNameParser.colorNames.values.sortedBy { it.name }.toList()\n    }\n\n    var fav by remember {\n        mutableStateOf(setOf<String>())\n    }\n\n    LazyVerticalGrid(\n        contentPadding = PaddingValues(12.dp),\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        horizontalArrangement = Arrangement.spacedBy(4.dp),\n        flingBehavior = enhancedFlingBehavior(),\n        columns = GridCells.Adaptive(150.dp)\n    ) {\n        items(colors) { colorWithName ->\n            ColorWithNameItem(\n                color = colorWithName.color,\n                name = colorWithName.name,\n                isFavorite = colorWithName.name in fav,\n                onToggleFavorite = { fav = fav.toggle(colorWithName.name) },\n                onCopy = {},\n                modifier = Modifier.animateItem()\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/DrawLockScreenOrientation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport android.app.Activity\nimport android.content.pm.ActivityInfo\nimport android.content.res.Configuration\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\n\n\n@Composable\nfun DrawLockScreenOrientation() {\n    if (!LocalSettingsState.current.lockDrawOrientation) return\n\n    val activity = LocalComponentActivity.current\n    DisposableEffect(activity) {\n        val originalOrientation = activity.requestedOrientation\n        activity.lockOrientation()\n        onDispose {\n            activity.requestedOrientation = originalOrientation\n        }\n    }\n}\n\n@Composable\nfun LockScreenOrientation(\n    mode: Int? = null\n) {\n    val activity = LocalComponentActivity.current\n    DisposableEffect(activity) {\n        val originalOrientation = activity.requestedOrientation\n        activity.lockOrientation(mode)\n        onDispose {\n            activity.requestedOrientation = originalOrientation\n        }\n    }\n}\n\nprivate fun Activity.lockOrientation(mode: Int? = null) {\n    val display = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\n        display\n    } else {\n        @Suppress(\"DEPRECATION\")\n        windowManager.defaultDisplay\n    }\n\n    val rotation = display?.rotation ?: 0\n    val orientation: Int = when (resources.configuration.orientation) {\n        Configuration.ORIENTATION_LANDSCAPE -> {\n            if (rotation == 0 || rotation == 90) {\n                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE\n            } else {\n                ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE\n            }\n        }\n\n        Configuration.ORIENTATION_PORTRAIT -> {\n            if (rotation == 0 || rotation == 270) {\n                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT\n            } else {\n                ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT\n            }\n        }\n\n        else -> 0\n    }\n    requestedOrientation = mode ?: orientation\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/EmojiItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.TextUnit\nimport androidx.compose.ui.unit.dp\nimport coil3.compose.rememberAsyncImagePainter\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.request.crossfade\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\nfun EmojiItem(\n    emoji: String?,\n    modifier: Modifier = Modifier,\n    fontSize: TextUnit = LocalTextStyle.current.fontSize,\n    fontScale: Float,\n    onNoEmoji: @Composable (size: Dp) -> Unit = {}\n) {\n    val dens = LocalDensity.current\n    val density by remember(dens, fontScale) {\n        derivedStateOf {\n            Density(\n                density = dens.density,\n                fontScale = fontScale\n            )\n        }\n    }\n    var shimmering by rememberSaveable { mutableStateOf(true) }\n    val painter = rememberAsyncImagePainter(\n        model = remember(emoji) {\n            derivedStateOf {\n                ImageRequest.Builder(appContext)\n                    .data(emoji)\n                    .memoryCacheKey(emoji)\n                    .diskCacheKey(emoji)\n                    .size(512)\n                    .listener(\n                        onStart = {\n                            shimmering = true\n                        },\n                        onSuccess = { _, _ ->\n                            shimmering = false\n                        }\n                    )\n                    .crossfade(true)\n                    .build()\n            }\n        }.value,\n        imageLoader = appContext.imageLoader,\n        filterQuality = FilterQuality.High\n    )\n\n    AnimatedContent(\n        targetState = emoji to fontSize,\n        modifier = modifier,\n        transitionSpec = {\n            fadeIn() + scaleIn(initialScale = 0.85f) togetherWith fadeOut() + scaleOut(targetScale = 0.85f)\n        }\n    ) { (emoji, fontSize) ->\n        val size by remember(fontSize, density) {\n            derivedStateOf {\n                with(density) {\n                    fontSize.toDp()\n                }\n            }\n        }\n        emoji?.let {\n            Box {\n                Icon(\n                    painter = painter,\n                    contentDescription = emoji,\n                    modifier = remember(size) {\n                        Modifier\n                            .size(size + 4.dp)\n                            .offset(1.dp, 1.dp)\n                            .padding(2.dp)\n                    },\n                    tint = Color(0, 0, 0, 40)\n                )\n                Icon(\n                    painter = painter,\n                    contentDescription = emoji,\n                    modifier = remember(size, shimmering) {\n                        Modifier\n                            .size(size + 4.dp)\n                            .clip(CloverShape)\n                            .shimmer(shimmering)\n                            .padding(2.dp)\n                    },\n                    tint = Color.Unspecified\n                )\n            }\n        } ?: onNoEmoji(size)\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/ExpandableItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.FancyTransitionEasing\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\n\n@Composable\nfun ExpandableItem(\n    modifier: Modifier = Modifier,\n    visibleContent: @Composable RowScope.(Boolean) -> Unit,\n    expandableContent: @Composable ColumnScope.(Boolean) -> Unit,\n    initialState: Boolean = false,\n    verticalArrangement: Arrangement.Vertical = Arrangement.Top,\n    shape: Shape = ShapeDefaults.large,\n    pressedShape: Shape = ShapeDefaults.pressed,\n    color: Color = Color.Unspecified,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    canExpand: Boolean = true,\n    onClick: () -> Unit = {},\n    onLongClick: (() -> Unit)? = null,\n    expansionIconContainerColor: Color = Color.Transparent\n) {\n    val animatedShape = shapeByInteraction(\n        shape = shape,\n        pressedShape = pressedShape,\n        interactionSource = interactionSource\n    )\n\n    Column(\n        modifier = Modifier\n            .then(modifier)\n            .container(\n                color = color,\n                resultPadding = 0.dp,\n                shape = animatedShape\n            )\n            .animateContentSizeNoClip(\n                animationSpec = spec(10)\n            )\n    ) {\n        var expanded by rememberSaveable(initialState) { mutableStateOf(initialState) }\n        val rotation by animateFloatAsState(if (expanded) 180f else 0f)\n        Row(\n            modifier = Modifier\n                .clip(animatedShape)\n                .hapticsCombinedClickable(\n                    interactionSource = interactionSource,\n                    indication = LocalIndication.current,\n                    onLongClick = onLongClick\n                ) {\n                    if (canExpand) {\n                        expanded = !expanded\n                    }\n                    onClick()\n                }\n                .padding(8.dp),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Row(Modifier.weight(1f)) {\n                visibleContent(expanded)\n            }\n            if (canExpand) {\n                EnhancedIconButton(\n                    containerColor = expansionIconContainerColor,\n                    onClick = { expanded = !expanded }\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.KeyboardArrowDown,\n                        contentDescription = \"Expand\",\n                        modifier = Modifier.rotate(rotation)\n                    )\n                }\n            }\n        }\n        BoxAnimatedVisibility(\n            visible = expanded,\n            enter = fadeIn(spec(500)) + expandVertically(spec(500)),\n            exit = fadeOut(spec(700)) + shrinkVertically(spec(700))\n        ) {\n            Column(verticalArrangement = verticalArrangement) {\n                Spacer(modifier = Modifier.height(8.dp))\n                expandableContent(expanded)\n                Spacer(modifier = Modifier.height(8.dp))\n            }\n        }\n    }\n}\n\nprivate fun <T> spec(duration: Int): FiniteAnimationSpec<T> = tween(\n    durationMillis = duration,\n    easing = FancyTransitionEasing\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/FeatureNotAvailableContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.FabPosition\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.APP_RELEASES\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Block\nimport com.t8rin.imagetoolbox.core.resources.icons.Github\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.Black\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.image.SourceNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun FeatureNotAvailableContent(\n    title: @Composable () -> Unit,\n    onGoBack: () -> Unit\n) {\n    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n    val linkHandler = LocalUriHandler.current\n    val settingsState = LocalSettingsState.current\n\n    Scaffold(\n        topBar = {\n            EnhancedTopAppBar(\n                type = EnhancedTopAppBarType.Large,\n                scrollBehavior = scrollBehavior,\n                title = title,\n                navigationIcon = {\n                    EnhancedIconButton(\n                        onClick = onGoBack\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                            contentDescription = stringResource(R.string.exit)\n                        )\n                    }\n                },\n                actions = {\n                    TopAppBarEmoji()\n                }\n            )\n        },\n        floatingActionButtonPosition = when (settingsState.fabAlignment) {\n            Alignment.BottomStart -> FabPosition.Start\n            Alignment.BottomCenter -> FabPosition.Center\n            else -> FabPosition.End\n        },\n        floatingActionButton = {\n            EnhancedFloatingActionButton(\n                onClick = {\n                    linkHandler.openUri(APP_RELEASES)\n                },\n                containerColor = Black,\n                contentColor = White,\n                content = {\n                    Spacer(Modifier.width(16.dp))\n                    Icon(\n                        imageVector = Icons.Rounded.Github,\n                        contentDescription = stringResource(R.string.restart_app)\n                    )\n                    Spacer(Modifier.width(16.dp))\n                    AutoSizeText(\n                        text = stringResource(R.string.open_github_page),\n                        maxLines = 1\n                    )\n                    Spacer(Modifier.width(16.dp))\n                }\n            )\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .nestedScroll(scrollBehavior.nestedScrollConnection)\n                .enhancedVerticalScroll(rememberScrollState())\n                .fillMaxSize()\n                .padding(it)\n                .padding(20.dp)\n        ) {\n            SourceNotPickedWidget(\n                onClick = {\n                    linkHandler.openUri(APP_RELEASES)\n                },\n                text = stringResource(R.string.wallpapers_export_not_avaialbe),\n                icon = Icons.TwoTone.Block,\n                maxLines = Int.MAX_VALUE\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/FontSelectionItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.ProvideTypography\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun FontSelectionItem(\n    font: UiFontFamily,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    onLongClick: (() -> Unit)? = null,\n    shape: Shape = ShapeDefaults.default\n) {\n    val settingsState = LocalSettingsState.current\n    val (_, name, isVariable) = font\n    val selected = font == settingsState.font\n    ProvideTypography(font) {\n        PreferenceItem(\n            onClick = onClick,\n            onLongClick = onLongClick,\n            title = (name ?: stringResource(id = R.string.system)) + isVariable.toVariable(),\n            subtitle = stringResource(R.string.alphabet_and_numbers),\n            containerColor = takeColorFromScheme {\n                if (selected) secondaryContainer\n                else SafeLocalContainerColor\n            },\n            modifier = modifier\n                .border(\n                    width = settingsState.borderWidth,\n                    color = animateColorAsState(\n                        if (selected) MaterialTheme\n                            .colorScheme\n                            .onSecondaryContainer\n                            .copy(alpha = 0.5f)\n                        else Color.Transparent\n                    ).value,\n                    shape = ShapeDefaults.default\n                ),\n            shape = shape,\n            endIcon = if (selected) Icons.Rounded.RadioButtonChecked else Icons.Rounded.RadioButtonUnchecked\n        )\n    }\n}\n\n@Composable\nprivate fun Boolean?.toVariable(): String {\n    if (this == null || this) return \"\"\n    return \" (${stringResource(R.string.regular)})\"\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/GradientEdge.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\n\n@Composable\nfun GradientEdge(\n    modifier: Modifier,\n    orientation: Orientation = Orientation.Vertical,\n    startColor: Color,\n    endColor: Color\n) {\n    when (orientation) {\n        Orientation.Vertical -> {\n            Box(\n                modifier = modifier\n                    .background(\n                        brush = Brush.verticalGradient(\n                            0f to startColor,\n                            0.7f to startColor,\n                            1f to endColor\n                        )\n                    )\n            )\n        }\n\n        Orientation.Horizontal -> {\n            Box(\n                modifier = modifier\n                    .background(\n                        brush = Brush.horizontalGradient(\n                            0f to startColor, 0.7f to startColor, 1f to endColor\n                        )\n                    )\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/InfoContainer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun InfoContainer(\n    text: String,\n    modifier: Modifier = Modifier,\n    containerColor: Color = MaterialTheme.colorScheme.secondaryContainer.copy(0.2f),\n    contentColor: Color = MaterialTheme.colorScheme.onSecondaryContainer.copy(alpha = 0.5f),\n    shape: Shape = ShapeDefaults.default,\n    icon: ImageVector? = Icons.Outlined.Info,\n    textAlign: TextAlign = TextAlign.Center\n) {\n    Row(\n        modifier = modifier\n            .container(\n                color = containerColor,\n                resultPadding = 0.dp,\n                shape = shape\n            )\n            .padding(12.dp),\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.Center\n    ) {\n        icon?.let {\n            Icon(\n                imageVector = icon,\n                contentDescription = null,\n                tint = contentColor\n            )\n            Spacer(modifier = Modifier.width(8.dp))\n        }\n\n        Text(\n            text = text,\n            fontSize = 12.sp,\n            textAlign = textAlign,\n            fontWeight = FontWeight.SemiBold,\n            lineHeight = 14.sp,\n            color = contentColor\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/LinkPreviewCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Language\nimport androidx.compose.material.icons.filled.Link\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LinkPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun LinkPreviewCard(\n    linkPreview: LinkPreview,\n    shape: Shape\n) {\n    val linkHandler = LocalUriHandler.current\n\n    Row(\n        modifier = Modifier\n            .fillMaxWidth()\n            .container(\n                shape = shape,\n                color = MaterialTheme.colorScheme.surface,\n                resultPadding = 0.dp\n            )\n            .hapticsCombinedClickable(\n                onClick = {\n                    linkPreview.link?.let(linkHandler::openUri)\n                },\n                onLongClick = {\n                    linkPreview.link?.let {\n                        Clipboard.copy(\n                            text = it,\n                            icon = Icons.Default.Link\n                        )\n                    }\n                },\n            ),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        var sizeOfRight by remember {\n            mutableStateOf(80.dp)\n        }\n        val density = LocalDensity.current\n        Picture(\n            model = linkPreview.image,\n            contentDescription = stringResource(R.string.image_link),\n            contentScale = ContentScale.Crop,\n            modifier = Modifier\n                .width(80.dp)\n                .height(sizeOfRight),\n            alignment = Alignment.Center,\n            error = {\n                Icon(\n                    imageVector = Icons.Default.Language,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .background(MaterialTheme.colorScheme.surface)\n                        .padding(12.dp)\n                        .clip(MaterialStarShape)\n                        .background(\n                            MaterialTheme.colorScheme.tertiaryContainer\n                                .copy(0.5f)\n                                .compositeOver(MaterialTheme.colorScheme.surface)\n                        )\n                        .padding(8.dp)\n                )\n            },\n            filterQuality = FilterQuality.High\n        )\n        Column(\n            modifier = Modifier\n                .weight(1f)\n                .onSizeChanged {\n                    sizeOfRight =\n                        if (linkPreview.title.isNullOrBlank() && linkPreview.description.isNullOrBlank()) {\n                            80.dp\n                        } else {\n                            with(density) { it.height.toDp() }\n                        }\n                }\n                .padding(12.dp),\n            verticalArrangement = Arrangement.Center,\n            horizontalAlignment = Alignment.Start\n        ) {\n            if (!linkPreview.title.isNullOrBlank()) {\n                Text(\n                    text = linkPreview.title,\n                    maxLines = 1,\n                    overflow = TextOverflow.Ellipsis,\n                    style = MaterialTheme.typography.titleMedium.copy(\n                        fontSize = 18.sp,\n                        fontWeight = FontWeight.SemiBold\n                    ),\n                    modifier = Modifier.padding(bottom = 6.dp)\n                )\n            }\n            if (!linkPreview.description.isNullOrBlank()) {\n                Text(\n                    text = linkPreview.description,\n                    maxLines = if (linkPreview.title.isNullOrBlank()) 3 else 2,\n                    overflow = TextOverflow.Ellipsis,\n                    style = MaterialTheme.typography.bodyMedium,\n                    textAlign = TextAlign.Start,\n                    lineHeight = 16.sp\n                )\n            }\n            if ((linkPreview.description.isNullOrBlank() || linkPreview.title.isNullOrBlank()) && (!linkPreview.url.isNullOrBlank() || !linkPreview.link.isNullOrBlank())) {\n                Text(\n                    text = linkPreview.url ?: linkPreview.link ?: \"\",\n                    maxLines = 2,\n                    overflow = TextOverflow.Ellipsis,\n                    style = MaterialTheme.typography.titleMedium.copy(\n                        fontSize = 18.sp,\n                        fontWeight = FontWeight.SemiBold\n                    )\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/LinkPreviewList.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material.icons.rounded.Link\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LinkPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.LinkUtils\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.fetchLinkPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.awaitAll\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun LinkPreviewList(\n    text: String,\n    externalLinks: List<String>? = null,\n    modifier: Modifier\n) {\n    val settingsState = LocalSettingsState.current\n    if (!settingsState.isLinkPreviewEnabled) return\n\n    var isLoading by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var linkPreviewList by remember {\n        mutableStateOf(emptyList<LinkPreview>())\n    }\n    var expanded by rememberSaveable { mutableStateOf(true) }\n    val rotation by animateFloatAsState(if (expanded) 180f else 0f)\n\n    LaunchedEffect(text, externalLinks) {\n        if (linkPreviewList.isNotEmpty() && text.isNotEmpty()) delay(500)\n\n        isLoading = true\n\n        val links = LinkUtils.parseLinks(text) + externalLinks.orEmpty()\n\n        linkPreviewList = links.map(LinkPreview::empty)\n\n        launch {\n            linkPreviewList = links.map { link ->\n                async {\n                    fetchLinkPreview(link)\n                }\n            }.awaitAll()\n        }\n\n        isLoading = false\n    }\n\n    val links = remember(expanded, linkPreviewList) {\n        if (linkPreviewList.size > 3 && expanded) {\n            linkPreviewList\n        } else linkPreviewList.take(3)\n    }\n\n    AnimatedVisibility(\n        modifier = Modifier.fillMaxWidth(),\n        visible = !isLoading && linkPreviewList.isNotEmpty()\n    ) {\n        Column(\n            modifier = Modifier\n                .then(modifier)\n                .container(\n                    shape = ShapeDefaults.large,\n                    resultPadding = 0.dp\n                )\n                .padding(8.dp)\n        ) {\n            Column {\n                TitleItem(\n                    text = stringResource(R.string.links),\n                    icon = Icons.Rounded.Link,\n                    modifier = Modifier.padding(8.dp),\n                    endContent = {\n                        AnimatedVisibility(\n                            visible = linkPreviewList.size > 3,\n                            modifier = Modifier.size(32.dp)\n                        ) {\n                            EnhancedIconButton(\n                                onClick = { expanded = !expanded }\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.KeyboardArrowDown,\n                                    contentDescription = \"Expand\",\n                                    modifier = Modifier.rotate(rotation)\n                                )\n                            }\n                        }\n                    }\n                )\n                Spacer(modifier = Modifier.padding(4.dp))\n                Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {\n                    links.forEachIndexed { index, link ->\n                        LinkPreviewCard(\n                            linkPreview = link,\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = links.size\n                            )\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/QrPainter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CutCornerShape\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.MaterialShapes\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.addOutline\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.painter.BitmapPainter\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.min\nimport androidx.core.graphics.createBitmap\nimport coil3.compose.asPainter\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport com.google.zxing.BarcodeFormat\nimport com.google.zxing.EncodeHintType\nimport com.google.zxing.MultiFormatWriter\nimport com.google.zxing.qrcode.decoder.ErrorCorrectionLevel\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.resources.shapes.ArrowShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.BookmarkShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.BurgerShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.DropletShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.EggShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ExplosionShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.MapShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.OctagonShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.OvalShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.PentagonShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.PillShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ShieldShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ShurikenShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SmallMaterialStarShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SquircleShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.IconShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.utils.toShape\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.applyPadding\nimport com.t8rin.imagetoolbox.core.ui.utils.painter.centerCrop\nimport com.t8rin.imagetoolbox.core.ui.utils.painter.roundCorners\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams.BallShape.Shaped\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport io.github.alexzhirkevich.qrose.QrCodePainter\nimport io.github.alexzhirkevich.qrose.options.Neighbors\nimport io.github.alexzhirkevich.qrose.options.QrBallShape\nimport io.github.alexzhirkevich.qrose.options.QrBrush\nimport io.github.alexzhirkevich.qrose.options.QrColors\nimport io.github.alexzhirkevich.qrose.options.QrErrorCorrectionLevel\nimport io.github.alexzhirkevich.qrose.options.QrFrameShape\nimport io.github.alexzhirkevich.qrose.options.QrLogo\nimport io.github.alexzhirkevich.qrose.options.QrLogoPadding\nimport io.github.alexzhirkevich.qrose.options.QrLogoShape\nimport io.github.alexzhirkevich.qrose.options.QrOptions\nimport io.github.alexzhirkevich.qrose.options.QrPixelShape\nimport io.github.alexzhirkevich.qrose.options.QrShapes\nimport io.github.alexzhirkevich.qrose.options.circle\nimport io.github.alexzhirkevich.qrose.options.cutCorners\nimport io.github.alexzhirkevich.qrose.options.horizontalLines\nimport io.github.alexzhirkevich.qrose.options.roundCorners\nimport io.github.alexzhirkevich.qrose.options.solid\nimport io.github.alexzhirkevich.qrose.options.square\nimport io.github.alexzhirkevich.qrose.options.verticalLines\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern\nimport io.github.alexzhirkevich.qrose.rememberQrCodePainter\nimport io.github.alexzhirkevich.qrose.toImageBitmap\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.withContext\n\n/**\n * Creates a [Painter] that draws a QR code for the given [content].\n * The [size] parameter defines the size of the QR code in dp.\n * The [padding] parameter defines the padding of the QR code in dp.\n */\n@Composable\nprivate fun rememberBarcodePainter(\n    content: String,\n    params: BarcodeParams,\n    onLoading: () -> Unit = {},\n    onSuccess: () -> Unit = {},\n    onFailure: (Throwable) -> Unit = {}\n): Painter = when (params) {\n    is BarcodeParams.Barcode -> {\n        val width = params.width\n        val height = params.height\n        val foregroundColor = params.foregroundColor\n        val backgroundColor = params.backgroundColor\n        val type = params.type\n\n        val density = LocalDensity.current\n        val widthPx = with(density) { width.roundToPx() }\n        val heightPx = with(density) { height.roundToPx() }\n        val paddingPx = with(density) { 0.dp.roundToPx() }\n\n        val bitmapState = remember(content) {\n            mutableStateOf<Bitmap?>(null)\n        }\n\n        // Use dependency on 'content' to re-trigger the effect when content changes\n        LaunchedEffect(\n            content,\n            type,\n            widthPx,\n            heightPx,\n            foregroundColor,\n            backgroundColor\n        ) {\n            onLoading()\n            delay(50)\n\n            if (content.isNotEmpty()) {\n                bitmapState.value = runSuspendCatching {\n                    generateQrBitmap(\n                        content = content,\n                        widthPx = widthPx,\n                        heightPx = heightPx,\n                        paddingPx = paddingPx,\n                        foregroundColor = foregroundColor,\n                        backgroundColor = backgroundColor,\n                        format = type.zxingFormat\n                    )\n                }.onFailure(onFailure).getOrNull()\n            } else {\n                bitmapState.value = null\n            }\n\n            if (bitmapState.value != null) onSuccess()\n        }\n\n        val bitmap = bitmapState.value ?: createDefaultBitmap(widthPx, heightPx)\n\n        remember(bitmap) {\n            bitmap?.asImageBitmap()?.let {\n                BitmapPainter(it)\n            } ?: EmptyPainter(widthPx, heightPx)\n        }\n    }\n\n    is BarcodeParams.Qr -> {\n        rememberQrCodePainter(\n            data = content,\n            options = params.options,\n            onSuccess = onSuccess,\n            onFailure = {\n                onLoading()\n                onFailure(it)\n            }\n        )\n    }\n}\n\n/**\n * Generates a QR code bitmap for the given [content].\n * The [widthPx] parameter defines the size of the QR code in pixels.\n * The [paddingPx] parameter defines the padding of the QR code in pixels.\n * Returns null if the QR code could not be generated.\n * This function is suspendable and should be called from a coroutine is thread-safe.\n */\nprivate suspend fun generateQrBitmap(\n    content: String,\n    widthPx: Int,\n    heightPx: Int,\n    paddingPx: Int,\n    foregroundColor: Color = Color.Black,\n    backgroundColor: Color = Color.White,\n    format: BarcodeFormat = BarcodeFormat.QR_CODE\n): Bitmap = withContext(Dispatchers.IO) {\n    val encodeHints = mutableMapOf<EncodeHintType, Any?>()\n        .apply {\n            this[EncodeHintType.CHARACTER_SET] = \"utf-8\"\n            if (format == BarcodeFormat.QR_CODE) {\n                this[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.L\n            }\n            this[EncodeHintType.MARGIN] = paddingPx\n        }\n\n    val bitmapMatrix =\n        MultiFormatWriter().encode(content, format, widthPx, heightPx, encodeHints)\n\n    val matrixWidth = bitmapMatrix.width\n    val matrixHeight = bitmapMatrix.height\n\n    val colors = IntArray(matrixWidth * matrixHeight) { index ->\n        val x = index % matrixWidth\n        val y = index / matrixWidth\n        val shouldColorPixel = bitmapMatrix.get(x, y)\n        if (shouldColorPixel) foregroundColor.toArgb() else backgroundColor.toArgb()\n    }\n\n    Bitmap.createBitmap(colors, matrixWidth, matrixHeight, Bitmap.Config.ARGB_8888)\n}\n\nprivate sealed interface BarcodeParams {\n    data class Qr(\n        val options: QrOptions\n    ) : BarcodeParams\n\n    data class Barcode(\n        val width: Dp = 150.dp,\n        val height: Dp = width,\n        val type: BarcodeType,\n        val foregroundColor: Color,\n        val backgroundColor: Color,\n    ) : BarcodeParams {\n        init {\n            check(width >= 0.dp && height >= 0.dp) { \"Size must be non negative\" }\n        }\n    }\n}\n\nprivate class EmptyPainter(\n    private val widthPx: Int,\n    private val heightPx: Int\n) : Painter() {\n    override val intrinsicSize: Size\n        get() = Size(widthPx.toFloat(), heightPx.toFloat())\n\n    override fun DrawScope.onDraw() = Unit\n}\n\n/**\n * Creates a default bitmap with the given [widthPx], [heightPx].\n * The bitmap is transparent.\n * This is used as a fallback if the QR code could not be generated.\n * The bitmap is created on the UI thread.\n */\nprivate fun createDefaultBitmap(\n    widthPx: Int,\n    heightPx: Int\n): Bitmap? {\n    return if (widthPx > 0 && heightPx > 0) {\n        createBitmap(widthPx, heightPx).apply {\n            eraseColor(Color.Transparent.toArgb())\n        }\n    } else null\n}\n\ndata class QrCodeParams(\n    val foregroundColor: Color? = null,\n    val backgroundColor: Color? = null,\n    val logo: Any? = null,\n    val logoPadding: Float = 0.25f,\n    val logoSize: Float = 0.2f,\n    val logoCorners: Float = 0f,\n    val pixelShape: PixelShape = PixelShape.Square,\n    val frameShape: FrameShape = FrameShape.Square,\n    val ballShape: BallShape = BallShape.Square,\n    val errorCorrectionLevel: ErrorCorrectionLevel = ErrorCorrectionLevel.Auto,\n    val maskPattern: MaskPattern = MaskPattern.Auto\n) {\n    sealed interface PixelShape {\n        sealed interface Predefined : PixelShape\n\n        data object Square : Predefined\n        data object RoundSquare : Predefined\n        data object Circle : Predefined\n        data object Vertical : Predefined\n        data object Horizontal : Predefined\n\n        data object Random : PixelShape\n        data class Shaped(val shape: Shape) : PixelShape\n\n        companion object {\n            val entries by lazy {\n                listOf(\n                    Random,\n                    Square,\n                    RoundSquare,\n                    Circle,\n                    Vertical,\n                    Horizontal,\n                ) + IconShape.entriesNoRandom.map { Shaped(it.shape) }\n            }\n        }\n    }\n\n    sealed interface FrameShape {\n        data class Corners(\n            val percent: Float,\n            val sides: List<CornerSide> = CornerSide.entries,\n            val isCut: Boolean = false\n        ) : FrameShape {\n            enum class CornerSide {\n                TopLeft, TopRight, BottomRight, BottomLeft\n            }\n\n            val topLeft = CornerSide.TopLeft in sides\n            val topRight = CornerSide.TopRight in sides\n            val bottomLeft = CornerSide.BottomLeft in sides\n            val bottomRight = CornerSide.BottomRight in sides\n        }\n\n        companion object {\n            val Square = Corners(0.00f)\n            val Circle = Corners(0.50f)\n\n            val entries: List<FrameShape> by lazy {\n                listOf(\n                    Square,\n                    Corners(0.25f),\n                    Circle,\n                    Corners(0.05f),\n                    Corners(0.10f),\n                    Corners(0.15f),\n                    Corners(0.20f),\n                    Corners(0.30f),\n                    Corners(0.35f),\n                    Corners(0.40f),\n                    Corners(0.45f),\n                    Corners(\n                        percent = 0.05f,\n                        isCut = true\n                    ),\n                    Corners(\n                        percent = 0.10f,\n                        isCut = true\n                    ),\n                    Corners(\n                        percent = 0.15f,\n                        isCut = true\n                    ),\n                    Corners(\n                        percent = 0.20f,\n                        isCut = true\n                    ),\n                    Corners(\n                        percent = 0.25f,\n                        isCut = true\n                    ),\n                    Corners(\n                        percent = 0.30f,\n                        isCut = true\n                    ),\n                    Corners(\n                        percent = 0.35f,\n                        isCut = true\n                    ),\n                )\n            }\n        }\n    }\n\n    sealed interface BallShape {\n        sealed interface Predefined : BallShape\n\n        data object Square : Predefined\n        data object Circle : Predefined\n\n        data class Shaped(val shape: Shape) : BallShape\n\n        companion object {\n            val entries by lazy {\n                listOf(\n                    Square,\n                    Circle,\n                ) + listOf(\n                    Shaped(SquircleShape),\n                    Shaped(CutCornerShape(25)),\n                    Shaped(CutCornerShape(35)),\n                    Shaped(CutCornerShape(50)),\n                    Shaped(RoundedCornerShape(15)),\n                    Shaped(RoundedCornerShape(25)),\n                    Shaped(RoundedCornerShape(35)),\n                    Shaped(RoundedCornerShape(45)),\n                    Shaped(CloverShape),\n                    Shaped(MaterialStarShape),\n                    Shaped(SmallMaterialStarShape),\n                    Shaped(BookmarkShape),\n                    Shaped(PillShape),\n                    Shaped(BurgerShape),\n                    Shaped(OvalShape),\n                    Shaped(ShieldShape),\n                    Shaped(EggShape),\n                    Shaped(DropletShape),\n                    Shaped(ArrowShape),\n                    Shaped(PentagonShape),\n                    Shaped(OctagonShape),\n                    Shaped(ShurikenShape),\n                    Shaped(ExplosionShape),\n                    Shaped(MapShape),\n                ) + listOf(\n                    MaterialShapes.Slanted,\n                    MaterialShapes.Arch,\n                    MaterialShapes.Oval,\n                    MaterialShapes.Diamond,\n                    MaterialShapes.Gem,\n                    MaterialShapes.Sunny,\n                    MaterialShapes.VerySunny,\n                    MaterialShapes.Cookie4Sided,\n                    MaterialShapes.Cookie6Sided,\n                    MaterialShapes.Cookie9Sided,\n                    MaterialShapes.Cookie12Sided,\n                    MaterialShapes.Ghostish,\n                    MaterialShapes.Clover4Leaf,\n                    MaterialShapes.Clover8Leaf,\n                    MaterialShapes.Burst,\n                    MaterialShapes.SoftBurst,\n                    MaterialShapes.SoftBoom,\n                    MaterialShapes.Flower,\n                    MaterialShapes.Puffy,\n                    MaterialShapes.PuffyDiamond,\n                    MaterialShapes.PixelCircle\n                ).map {\n                    Shaped(it.toShape())\n                }\n            }\n        }\n    }\n\n    enum class ErrorCorrectionLevel {\n        Auto, L, M, Q, H\n    }\n\n    enum class MaskPattern {\n        Auto,\n        P_000,\n        P_001,\n        P_010,\n        P_011,\n        P_100,\n        P_101,\n        P_110,\n        P_111\n    }\n}\n\n@Composable\nfun defaultQrColors(): Pair<Color, Color> {\n    val settingsState = LocalSettingsState.current\n\n    val backgroundColor = if (settingsState.isNightMode) {\n        MaterialTheme.colorScheme.onSurface\n    } else {\n        MaterialTheme.colorScheme.surfaceContainerHigh\n    }\n\n    val foregroundColor = if (settingsState.isNightMode) {\n        MaterialTheme.colorScheme.surfaceContainer\n    } else {\n        MaterialTheme.colorScheme.onSurface\n    }\n\n    return remember(backgroundColor, foregroundColor) {\n        backgroundColor to foregroundColor\n    }\n}\n\n@Composable\nfun QrCode(\n    content: String,\n    modifier: Modifier,\n    cornerRadius: Dp = 4.dp,\n    heightRatio: Float = 2f,\n    qrParams: QrCodeParams,\n    type: BarcodeType = BarcodeType.QR_CODE,\n    onFailure: (Throwable) -> Unit = {},\n    onSuccess: () -> Unit = {},\n) {\n    BoxWithConstraints(\n        modifier = modifier,\n        contentAlignment = Alignment.Center\n    ) {\n        val width = min(this.maxWidth, maxHeight)\n        val height = animateDpAsState(\n            if (type.isSquare && type != BarcodeType.DATA_MATRIX) width else width / heightRatio\n        ).value\n\n        val (bg, fg) = defaultQrColors()\n\n        val backgroundColor = qrParams.backgroundColor ?: bg\n\n        val foregroundColor = qrParams.foregroundColor ?: fg\n\n        var isLoading by remember {\n            mutableStateOf(true)\n        }\n\n        var logoPainterRaw by remember(qrParams.logo) {\n            mutableStateOf<Painter?>(null)\n        }\n\n        val logoPainter = remember(logoPainterRaw, qrParams.logoCorners) {\n            logoPainterRaw?.roundCorners(qrParams.logoCorners)\n        }\n\n        LaunchedEffect(qrParams.logo) {\n            logoPainterRaw = appContext.imageLoader.execute(\n                ImageRequest.Builder(appContext)\n                    .data(qrParams.logo)\n                    .size(1024)\n                    .build()\n            ).image?.asPainter(appContext)?.centerCrop()\n        }\n\n        val density = LocalDensity.current\n\n        val params by remember(\n            width,\n            height,\n            type,\n            foregroundColor,\n            backgroundColor,\n            qrParams,\n            logoPainter,\n            density\n        ) {\n            derivedStateOf {\n                when (type) {\n                    BarcodeType.QR_CODE -> {\n                        BarcodeParams.Qr(\n                            QrOptions(\n                                colors = QrColors(\n                                    dark = QrBrush.solid(foregroundColor),\n                                    light = QrBrush.solid(backgroundColor),\n                                    ball = QrBrush.solid(foregroundColor),\n                                    frame = QrBrush.solid(foregroundColor),\n                                    background = QrBrush.solid(backgroundColor),\n                                ),\n                                logo = logoPainter?.let {\n                                    QrLogo(\n                                        painter = logoPainter,\n                                        shape = QrLogoShape.roundCorners(qrParams.logoCorners),\n                                        padding = QrLogoPadding.Natural(qrParams.logoPadding),\n                                        size = qrParams.logoSize\n                                    )\n                                } ?: QrLogo(),\n                                shapes = QrShapes(\n                                    darkPixel = qrParams.pixelShape.toLib(density),\n                                    frame = qrParams.frameShape.toLib(),\n                                    ball = qrParams.ballShape.toLib(density)\n                                ),\n                                errorCorrectionLevel = qrParams.errorCorrectionLevel.toLib(),\n                                maskPattern = qrParams.maskPattern.toLib()\n                            )\n                        )\n                    }\n\n                    else -> {\n                        BarcodeParams.Barcode(\n                            width = width,\n                            height = height,\n                            foregroundColor = foregroundColor,\n                            backgroundColor = backgroundColor,\n                            type = type,\n                        )\n                    }\n                }\n            }\n        }\n\n        val painter = rememberBarcodePainter(\n            content = content,\n            params = params,\n            onLoading = {\n                isLoading = true\n            },\n            onSuccess = {\n                isLoading = false\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n\n        val padding = 16.dp\n\n        Picture(\n            model = painter,\n            modifier = Modifier\n                .size(\n                    width = width,\n                    height = height\n                )\n                .clip(AutoCornersShape(cornerRadius))\n                .background(backgroundColor)\n                .padding(padding)\n                .alpha(\n                    animateFloatAsState(\n                        targetValue = if (isLoading) 0f else 1f,\n                        animationSpec = tween(500)\n                    ).value\n                ),\n            contentDescription = null\n        )\n\n        Box(\n            modifier = Modifier\n                .size(\n                    width = width,\n                    height = height\n                )\n                .clip(AutoCornersShape((cornerRadius - 1.dp).coerceAtLeast(0.dp)))\n                .shimmer(isLoading)\n        )\n    }\n}\n\nsuspend fun QrCodeParams.renderAsQr(\n    content: String,\n    type: BarcodeType\n): Bitmap? = coroutineScope {\n    val widthPx = 1500\n    val heightPx = 1500\n    val paddingPx = 100\n\n    val logoPainter: Painter? = logo?.let {\n        appContext.imageLoader.execute(\n            ImageRequest.Builder(appContext)\n                .data(logo)\n                .size(1024)\n                .build()\n        ).image?.asPainter(appContext)?.centerCrop()?.roundCorners(logoCorners)\n    }\n\n    val options = QrOptions(\n        colors = QrColors(\n            dark = QrBrush.solid(foregroundColor ?: Color.Black),\n            light = QrBrush.solid(backgroundColor ?: Color.White),\n            ball = QrBrush.solid(foregroundColor ?: Color.Black),\n            frame = QrBrush.solid(foregroundColor ?: Color.Black),\n            background = QrBrush.solid(backgroundColor ?: Color.White),\n        ),\n        logo = logoPainter?.let {\n            QrLogo(\n                painter = logoPainter,\n                shape = QrLogoShape.roundCorners(logoCorners),\n                padding = QrLogoPadding.Natural(logoPadding),\n                size = logoSize\n            )\n        } ?: QrLogo(),\n        shapes = QrShapes(\n            darkPixel = pixelShape.toLib(Density(1f)),\n            frame = frameShape.toLib(),\n            ball = ballShape.toLib(Density(1f))\n        ),\n        errorCorrectionLevel = errorCorrectionLevel.toLib(),\n        maskPattern = maskPattern.toLib()\n    )\n\n    runSuspendCatching {\n        when (type) {\n            BarcodeType.QR_CODE -> {\n                QrCodePainter(\n                    data = content,\n                    options = options,\n                    onSuccess = {},\n                    onFailure = {}\n                ).toImageBitmap(widthPx, heightPx).asAndroidBitmap().applyPadding(paddingPx)\n            }\n\n            else -> {\n                generateQrBitmap(\n                    content = content,\n                    widthPx = widthPx,\n                    heightPx = heightPx,\n                    paddingPx = paddingPx,\n                    foregroundColor = foregroundColor ?: Color.Black,\n                    backgroundColor = backgroundColor ?: Color.White,\n                    format = type.zxingFormat\n                )\n            }\n        }\n    }.getOrNull()\n}\n\nprivate fun pixelShape(\n    density: Density,\n    shape: () -> Shape\n) = QrPixelShape { size, _ ->\n    apply {\n        addOutline(\n            shape().createOutline(\n                size = Size(size, size),\n                layoutDirection = LayoutDirection.Ltr,\n                density = density\n            )\n        )\n    }\n}\n\nprivate fun Shape.toBallShape(density: Density) = object : QrBallShape {\n    override fun Path.path(\n        size: Float,\n        neighbors: Neighbors\n    ): Path = apply {\n        addOutline(\n            createOutline(\n                size = Size(size, size),\n                layoutDirection = LayoutDirection.Ltr,\n                density = density\n            )\n        )\n    }\n}\n\nprivate fun QrCodeParams.BallShape.toLib(density: Density): QrBallShape = when (this) {\n    QrCodeParams.BallShape.Square -> QrBallShape.square()\n    QrCodeParams.BallShape.Circle -> QrBallShape.circle()\n    is Shaped -> shape.toBallShape(density)\n}\n\nprivate fun QrCodeParams.FrameShape.toLib(): QrFrameShape = when (this) {\n    is QrCodeParams.FrameShape.Corners -> {\n        if (isCut) {\n            QrFrameShape.cutCorners(\n                corner = percent,\n                topLeft = topLeft,\n                topRight = topRight,\n                bottomLeft = bottomLeft,\n                bottomRight = bottomRight\n            )\n        } else {\n            QrFrameShape.roundCorners(\n                corner = percent,\n                topLeft = topLeft,\n                topRight = topRight,\n                bottomLeft = bottomLeft,\n                bottomRight = bottomRight\n            )\n        }\n    }\n}\n\nprivate fun QrCodeParams.PixelShape.toLib(density: Density): QrPixelShape = when (this) {\n    QrCodeParams.PixelShape.Square -> QrPixelShape.square()\n    QrCodeParams.PixelShape.RoundSquare -> QrPixelShape.roundCorners()\n    QrCodeParams.PixelShape.Circle -> QrPixelShape.circle()\n    QrCodeParams.PixelShape.Vertical -> QrPixelShape.verticalLines()\n    QrCodeParams.PixelShape.Horizontal -> QrPixelShape.horizontalLines()\n    QrCodeParams.PixelShape.Random -> pixelShape(density) { IconShape.entriesNoRandom.random().shape }\n    is QrCodeParams.PixelShape.Shaped -> pixelShape(density) { shape }\n}\n\nprivate fun QrCodeParams.ErrorCorrectionLevel.toLib(): QrErrorCorrectionLevel = when (this) {\n    QrCodeParams.ErrorCorrectionLevel.Auto -> QrErrorCorrectionLevel.Auto\n    QrCodeParams.ErrorCorrectionLevel.L -> QrErrorCorrectionLevel.Low\n    QrCodeParams.ErrorCorrectionLevel.M -> QrErrorCorrectionLevel.Medium\n    QrCodeParams.ErrorCorrectionLevel.Q -> QrErrorCorrectionLevel.MediumHigh\n    QrCodeParams.ErrorCorrectionLevel.H -> QrErrorCorrectionLevel.High\n}\n\nprivate fun QrCodeParams.MaskPattern.toLib(): MaskPattern? = when (this) {\n    QrCodeParams.MaskPattern.Auto -> null\n    QrCodeParams.MaskPattern.P_000 -> MaskPattern.PATTERN000\n    QrCodeParams.MaskPattern.P_001 -> MaskPattern.PATTERN001\n    QrCodeParams.MaskPattern.P_010 -> MaskPattern.PATTERN010\n    QrCodeParams.MaskPattern.P_011 -> MaskPattern.PATTERN011\n    QrCodeParams.MaskPattern.P_100 -> MaskPattern.PATTERN100\n    QrCodeParams.MaskPattern.P_101 -> MaskPattern.PATTERN101\n    QrCodeParams.MaskPattern.P_110 -> MaskPattern.PATTERN110\n    QrCodeParams.MaskPattern.P_111 -> MaskPattern.PATTERN111\n}\n\n\nenum class BarcodeType(\n    internal val zxingFormat: BarcodeFormat,\n    val isSquare: Boolean\n) {\n    QR_CODE(BarcodeFormat.QR_CODE, true),\n    AZTEC(BarcodeFormat.AZTEC, true),\n    CODABAR(BarcodeFormat.CODABAR, false),\n    CODE_39(BarcodeFormat.CODE_39, false),\n    CODE_93(BarcodeFormat.CODE_93, false),\n    CODE_128(BarcodeFormat.CODE_128, false),\n    DATA_MATRIX(BarcodeFormat.DATA_MATRIX, true),\n    EAN_8(BarcodeFormat.EAN_8, false),\n    EAN_13(BarcodeFormat.EAN_13, false),\n    ITF(BarcodeFormat.ITF, false),\n    PDF_417(BarcodeFormat.PDF_417, false),\n    UPC_A(BarcodeFormat.UPC_A, false),\n    UPC_E(BarcodeFormat.UPC_E, false)\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/SearchBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.BasicTextField\nimport androidx.compose.foundation.text.KeyboardActions\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.focus.FocusRequester\nimport androidx.compose.ui.focus.focusRequester\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedHorizontalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.text.isKeyboardVisibleAsState\nimport kotlinx.coroutines.delay\n\n@Composable\nfun SearchBar(\n    searchString: String,\n    onValueChange: (String) -> Unit\n) {\n    val windowInfo = LocalWindowInfo.current\n    val focusRequester = remember { FocusRequester() }\n    val localFocusManager = LocalFocusManager.current\n    val state = rememberScrollState()\n\n    val isKeyboardVisible by isKeyboardVisibleAsState()\n    var isKeyboardWasVisible by rememberSaveable {\n        mutableStateOf<Boolean?>(null)\n    }\n    LaunchedEffect(isKeyboardVisible) {\n        if (!isKeyboardVisible) {\n            delay(600)\n            if (isKeyboardWasVisible == true) {\n                isKeyboardWasVisible = false\n            }\n        } else {\n            isKeyboardWasVisible = true\n        }\n    }\n\n    LaunchedEffect(windowInfo) {\n        snapshotFlow {\n            windowInfo.isWindowFocused\n        }.collect { isWindowFocused ->\n            if (isWindowFocused && isKeyboardWasVisible != false) {\n                delay(500)\n                focusRequester.requestFocus()\n                isKeyboardWasVisible = true\n            }\n        }\n    }\n    BasicTextField(\n        modifier = Modifier\n            .fillMaxWidth()\n            .fadingEdges(state)\n            .enhancedHorizontalScroll(state)\n            .focusRequester(focusRequester),\n        value = searchString,\n        textStyle = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.onBackground),\n        keyboardActions = KeyboardActions(\n            onDone = { localFocusManager.clearFocus() }\n        ),\n        singleLine = true,\n        cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),\n        onValueChange = onValueChange\n    )\n    if (searchString.isEmpty()) {\n        Text(\n            text = stringResource(R.string.search_here),\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(start = 8.dp),\n            style = LocalTextStyle.current.copy(\n                color = MaterialTheme.colorScheme.onBackground.copy(\n                    0.5f\n                )\n            )\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/SwipeToReveal.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"TYPEALIAS_EXPANSION_DEPRECATION\", \"DEPRECATION\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.core.Easing\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.material.FractionalThreshold\nimport androidx.compose.material.ResistanceConfig\nimport androidx.compose.material.SwipeableDefaults\nimport androidx.compose.material.SwipeableState\nimport androidx.compose.material.rememberSwipeableState\nimport androidx.compose.material.swipeable\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.AlphaEasing\nimport kotlin.math.absoluteValue\nimport kotlin.math.roundToInt\n\ntypealias RevealState = SwipeableState<RevealValue>\n\n@Composable\nfun SwipeToReveal(\n    modifier: Modifier = Modifier,\n    enableSwipe: Boolean = true,\n    alphaEasing: Easing = AlphaEasing,\n    maxRevealDp: Dp = 75.dp,\n    maxAmountOfOverflow: Dp = 250.dp,\n    directions: Set<RevealDirection> = setOf(\n        RevealDirection.StartToEnd,\n    ),\n    alphaTransformEnabled: Boolean = false,\n    interactionSource: MutableInteractionSource = remember {\n        MutableInteractionSource()\n    },\n    state: RevealState = rememberRevealState(),\n    revealedContentEnd: @Composable BoxScope.() -> Unit = {},\n    revealedContentStart: @Composable BoxScope.() -> Unit = {},\n    swipeableContent: @Composable () -> Unit,\n) {\n    Box(modifier) {\n        val maxRevealPx = with(LocalDensity.current) { maxRevealDp.toPx() }\n        val draggedRatio =\n            (state.offset.value.absoluteValue / maxRevealPx.absoluteValue).coerceIn(0f, 1f)\n\n        val alpha = if (alphaTransformEnabled) alphaEasing.transform(draggedRatio) else 1f\n\n        // non swipable with hidden content\n        Box(\n            modifier = Modifier.matchParentSize()\n        ) {\n            Row(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .alpha(alpha),\n                horizontalArrangement = Arrangement.End,\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                Box(\n                    modifier = Modifier\n                        .weight(1f)\n                        .fillMaxHeight(),\n                    contentAlignment = Alignment.CenterStart,\n                    content = revealedContentStart\n                )\n                Box(\n                    modifier = Modifier\n                        .weight(1f)\n                        .fillMaxHeight(),\n                    contentAlignment = Alignment.CenterEnd,\n                    content = revealedContentEnd\n                )\n            }\n        }\n\n        Box(\n            modifier = Modifier\n                .then(\n                    if (enableSwipe) {\n                        Modifier\n                            .offset {\n                                IntOffset(\n                                    state.offset.value.roundToInt(),\n                                    0\n                                )\n                            }\n                            .revealSwipeable(\n                                state = state,\n                                maxRevealPx = maxRevealPx,\n                                maxAmountOfOverflow = maxAmountOfOverflow,\n                                directions = directions,\n                                interactionSource = interactionSource\n                            )\n                    } else Modifier\n                )\n        ) {\n            swipeableContent()\n        }\n    }\n}\n\n\nfun Modifier.revealSwipeable(\n    maxRevealPx: Float,\n    maxAmountOfOverflow: Dp,\n    directions: Set<RevealDirection>,\n    state: RevealState,\n    enabled: Boolean = true,\n    interactionSource: MutableInteractionSource\n) = this.composed {\n\n    val maxAmountOfOverflowPx = with(LocalDensity.current) { maxAmountOfOverflow.toPx() }\n\n    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n\n    val anchors = mutableMapOf(0f to RevealValue.Default)\n\n    if (RevealDirection.StartToEnd in directions) anchors += maxRevealPx to RevealValue.FullyRevealedEnd\n    if (RevealDirection.EndToStart in directions) anchors += -maxRevealPx to RevealValue.FullyRevealedStart\n\n    val thresholds = { _: RevealValue, _: RevealValue ->\n        FractionalThreshold(0.5f)\n    }\n\n    val minFactor =\n        if (RevealDirection.EndToStart in directions) SwipeableDefaults.StandardResistanceFactor else SwipeableDefaults.StiffResistanceFactor\n    val maxFactor =\n        if (RevealDirection.StartToEnd in directions) SwipeableDefaults.StandardResistanceFactor else SwipeableDefaults.StiffResistanceFactor\n\n    Modifier.swipeable(\n        state = state,\n        anchors = anchors,\n        thresholds = thresholds,\n        orientation = Orientation.Horizontal,\n        enabled = enabled, // state.value == RevealValue.System,\n        reverseDirection = isRtl,\n        resistance = ResistanceConfig(\n            basis = maxAmountOfOverflowPx,\n            factorAtMin = minFactor,\n            factorAtMax = maxFactor\n        ),\n        interactionSource = interactionSource\n    )\n}\n\nenum class RevealDirection {\n    /**\n     * Can be dismissed by swiping in the reading direction.\n     */\n    StartToEnd,\n\n    /**\n     * Can be dismissed by swiping in the reverse of the reading direction.\n     */\n    EndToStart\n}\n\n/**\n * Possible values of [RevealState].\n */\nenum class RevealValue {\n    /**\n     * Indicates the component has not been revealed yet.\n     */\n    Default,\n\n    /**\n     * Fully revealed to end\n     */\n    FullyRevealedEnd,\n\n    /**\n     * Fully revealed to start\n     */\n    FullyRevealedStart,\n}\n\n/**\n * Create and [remember] a [RevealState] with the default animation clock.\n *\n * @param initialValue The initial value of the state.\n * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.\n */\n@Composable\nfun rememberRevealState(\n    initialValue: RevealValue = RevealValue.Default,\n    confirmStateChange: (RevealValue) -> Boolean = { true },\n): RevealState {\n    return rememberSwipeableState(\n        initialValue = initialValue,\n        confirmStateChange = confirmStateChange\n    )\n}\n\n/**\n * Reset the component to the default position, with an animation.\n */\nsuspend fun RevealState.reset() {\n    animateTo(\n        targetValue = RevealValue.Default,\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/ToastHost.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport android.content.Context\nimport androidx.activity.compose.LocalActivity\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.ContentTransform\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.gestures.detectHorizontalDragGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.imePadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.systemBarsPadding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ErrorOutline\nimport androidx.compose.material.icons.rounded.Folder\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.CardDefaults\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.CompositingStrategy\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.TransformOrigin\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.AccessibilityManager\nimport androidx.compose.ui.platform.LocalAccessibilityManager\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastCoerceIn\nimport androidx.compose.ui.util.lerp\nimport androidx.compose.ui.zIndex\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.harmonizeWithPrimary\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.lessSpringySpec\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.requestStoragePermission\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.autoElevatedBorder\nimport com.t8rin.imagetoolbox.core.utils.decodeEscaped\nimport com.t8rin.modalsheet.FullscreenPopup\nimport kotlinx.coroutines.CancellableContinuation\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.suspendCancellableCoroutine\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport kotlin.coroutines.resume\nimport kotlin.math.abs\n\n@Composable\nfun ToastHost(\n    hostState: ToastHostState = AppToastHost.state,\n    modifier: Modifier = Modifier.fillMaxSize(),\n    alignment: Alignment = Alignment.BottomCenter,\n    transitionSpec: AnimatedContentTransitionScope<ToastData?>.() -> ContentTransform = { ToastDefaults.transition },\n    toast: @Composable (ToastData) -> Unit = { Toast(it) },\n    enableSwipes: Boolean = true\n) {\n    val screenSize = LocalScreenSize.current\n    val sizeMin = screenSize.width.coerceAtMost(screenSize.height)\n\n    val currentToastData = hostState.currentToastData\n    val accessibilityManager = LocalAccessibilityManager.current\n    val activity = LocalActivity.current\n    LaunchedEffect(currentToastData) {\n        if (currentToastData != null) {\n            if (currentToastData.visuals.message == AppToastHost.PERMISSION) {\n                activity?.requestStoragePermission()\n                return@LaunchedEffect\n            }\n\n            val duration = currentToastData.visuals.duration.toMillis(accessibilityManager)\n            delay(duration)\n            currentToastData.dismiss()\n        }\n    }\n\n    val scope = rememberCoroutineScope()\n    val offsetX = remember { Animatable(0f) }\n    val alpha = remember { Animatable(1f) }\n    val threshold = 300f\n\n    FullscreenPopup(\n        placeAboveAll = true\n    ) {\n        AnimatedContent(\n            modifier = Modifier.zIndex(100f),\n            targetState = currentToastData,\n            transitionSpec = transitionSpec\n        ) { data ->\n            if (enableSwipes) {\n                val reset: CoroutineScope.() -> Unit = {\n                    launch {\n                        alpha.animateTo(\n                            targetValue = 1f,\n                            animationSpec = lessSpringySpec()\n                        )\n                    }\n                    launch {\n                        offsetX.animateTo(\n                            targetValue = 0f,\n                            animationSpec = lessSpringySpec()\n                        )\n                    }\n                }\n\n                LaunchedEffect(data) {\n                    reset()\n                }\n\n                Box(modifier = modifier) {\n                    data?.let { toastData ->\n                        Box(\n                            modifier = Modifier\n                                .align(alignment)\n                                .padding(\n                                    bottom = sizeMin * 0.2f,\n                                    top = 24.dp,\n                                    start = 12.dp,\n                                    end = 12.dp\n                                )\n                                .imePadding()\n                                .systemBarsPadding()\n                                .graphicsLayer {\n                                    compositingStrategy = CompositingStrategy.Offscreen\n                                    this.alpha = alpha.value\n                                    translationX = offsetX.value\n                                }\n                                .pointerInput(toastData) {\n                                    detectHorizontalDragGestures(\n                                        onHorizontalDrag = { _, drag ->\n                                            scope.launch {\n                                                val new = offsetX.value + drag\n\n                                                launch {\n                                                    offsetX.snapTo(\n                                                        targetValue = new\n                                                    )\n                                                }\n\n                                                launch {\n                                                    alpha.snapTo(\n                                                        targetValue = lerp(\n                                                            start = 1f,\n                                                            stop = 0.35f,\n                                                            fraction = (abs(new) / threshold).fastCoerceIn(\n                                                                0f,\n                                                                1f\n                                                            )\n                                                        )\n                                                    )\n                                                }\n                                            }\n                                        },\n                                        onDragEnd = {\n                                            scope.launch {\n                                                if (abs(offsetX.value) > threshold) {\n                                                    toastData.dismiss()\n                                                    reset()\n                                                } else {\n                                                    reset()\n                                                }\n                                            }\n                                        }\n                                    )\n                                }\n                        ) {\n                            toast(toastData)\n                        }\n                    }\n                }\n            } else {\n                Box(modifier = modifier) {\n                    Box(modifier = Modifier.align(alignment)) {\n                        data?.let { toast(it) }\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\nfun Toast(\n    toastData: ToastData,\n    modifier: Modifier = Modifier,\n    shape: Shape = ToastDefaults.shape,\n    containerColor: Color = ToastDefaults.color,\n    contentColor: Color = ToastDefaults.contentColor,\n) {\n    val screenSize = LocalScreenSize.current\n    val sizeMin = screenSize.width.coerceAtMost(screenSize.height)\n\n    Card(\n        colors = CardDefaults.cardColors(\n            containerColor = containerColor,\n            contentColor = contentColor\n        ),\n        modifier = modifier\n            .heightIn(min = 48.dp)\n            .widthIn(min = 0.dp, max = (sizeMin * 0.7f))\n            .autoElevatedBorder(\n                color = MaterialTheme.colorScheme\n                    .outlineVariant(0.3f, contentColor)\n                    .copy(alpha = 0.92f),\n                shape = shape,\n                autoElevation = animateDpAsState(\n                    if (LocalSettingsState.current.drawContainerShadows) 6.dp\n                    else 0.dp\n                ).value\n            )\n            .alpha(0.95f),\n        shape = shape\n    ) {\n        Row(\n            modifier = Modifier.padding(16.dp),\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.Center\n        ) {\n            toastData.visuals.icon?.let { icon ->\n                IconShapeContainer(\n                    containerColor = containerColor\n                        .blend(MaterialTheme.colorScheme.secondary, 0.5f)\n                        .blend(MaterialTheme.colorScheme.primaryContainer, 0.05f),\n                    contentColor = contentColor\n                ) {\n                    Icon(\n                        imageVector = icon,\n                        contentDescription = null\n                    )\n                }\n                Spacer(modifier = Modifier.width(8.dp))\n            }\n            Text(\n                style = MaterialTheme.typography.bodySmall,\n                text = toastData.visuals.message,\n                textAlign = TextAlign.Center\n            )\n        }\n    }\n}\n\n@EnPreview\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(\n    isDarkTheme = false,\n    keyColor = Color.Yellow,\n    mapSettings = {\n        it.copy(drawContainerShadows = false)\n    }\n) {\n    Toast(\n        object : ToastData {\n            override val visuals: ToastVisuals\n                get() = object : ToastVisuals {\n                    override val message: String\n                        get() = \"File successfully saved to Documents/ImageToolbox\"\n                    override val icon: ImageVector\n                        get() = Icons.Rounded.Folder\n                    override val duration: ToastDuration\n                        get() = ToastDuration.Long\n                }\n\n            override fun dismiss() = Unit\n        }\n    )\n}\n\n@Stable\n@Immutable\nopen class ToastHostState {\n\n    private val mutex = Mutex()\n\n    var currentToastData by mutableStateOf<ToastData?>(null)\n        private set\n\n    suspend fun showToast(\n        message: String,\n        icon: ImageVector? = null,\n        duration: ToastDuration = ToastDuration.Short\n    ) = showToast(ToastVisualsImpl(message, icon, duration))\n\n    suspend fun showToast(visuals: ToastVisuals) = mutex.withLock {\n        try {\n            suspendCancellableCoroutine { continuation ->\n                currentToastData = ToastDataImpl(visuals, continuation)\n            }\n        } finally {\n            currentToastData = null\n        }\n    }\n\n    private class ToastVisualsImpl(\n        override val message: String,\n        override val icon: ImageVector? = null,\n        override val duration: ToastDuration\n    ) : ToastVisuals {\n\n        override fun equals(other: Any?): Boolean {\n            if (this === other) return true\n            if (other == null || this::class != other::class) return false\n\n            other as ToastVisualsImpl\n\n            if (message != other.message) return false\n            if (icon != other.icon) return false\n            return duration == other.duration\n        }\n\n        override fun hashCode(): Int {\n            var result = message.hashCode()\n            result = 31 * result + icon.hashCode()\n            result = 31 * result + duration.hashCode()\n            return result\n        }\n    }\n\n    private class ToastDataImpl(\n        override val visuals: ToastVisuals,\n        private val continuation: CancellableContinuation<Unit>\n    ) : ToastData {\n\n        override fun dismiss() {\n            if (continuation.isActive) continuation.resume(Unit)\n        }\n\n        override fun equals(other: Any?): Boolean {\n            if (this === other) return true\n            if (other == null || this::class != other::class) return false\n\n            other as ToastDataImpl\n\n            if (visuals != other.visuals) return false\n            return continuation == other.continuation\n        }\n\n        override fun hashCode(): Int {\n            var result = visuals.hashCode()\n            result = 31 * result + continuation.hashCode()\n            return result\n        }\n    }\n}\n\n@Stable\n@Immutable\ninterface ToastData {\n    val visuals: ToastVisuals\n    fun dismiss()\n}\n\n@Stable\n@Immutable\ninterface ToastVisuals {\n    val message: String\n    val icon: ImageVector?\n    val duration: ToastDuration\n}\n\n@Stable\n@Immutable\nopen class ToastDuration(val time: kotlin.Long) {\n    object Short : ToastDuration(3500L)\n    object Long : ToastDuration(6500L)\n}\n\n@Stable\n@Immutable\nobject ToastDefaults {\n    val transition: ContentTransform\n        get() = fadeIn(tween(300)) + scaleIn(\n            animationSpec = spring(\n                dampingRatio = 0.65f,\n                stiffness = Spring.StiffnessMediumLow\n            ),\n            transformOrigin = TransformOrigin(0.5f, 1f)\n        ) + slideInVertically(\n            spring(\n                stiffness = Spring.StiffnessHigh\n            )\n        ) { it / 2 } togetherWith fadeOut(tween(250)) + slideOutVertically(\n            tween(500)\n        ) { it / 2 } + scaleOut(\n            animationSpec = spring(\n                dampingRatio = Spring.DampingRatioMediumBouncy,\n                stiffness = Spring.StiffnessMediumLow\n            ),\n            transformOrigin = TransformOrigin(0.5f, 1f)\n        )\n    val contentColor: Color\n        @Composable\n        get() = MaterialTheme.colorScheme.inverseOnSurface.harmonizeWithPrimary()\n\n    val color: Color\n        @Composable\n        get() = MaterialTheme.colorScheme.inverseSurface.harmonizeWithPrimary()\n\n    val shape: Shape @Composable get() = AutoCornersShape(32.dp)\n}\n\nprivate fun ToastDuration.toMillis(\n    accessibilityManager: AccessibilityManager?\n): Long {\n    val original = this.time\n    return accessibilityManager?.calculateRecommendedTimeoutMillis(\n        original,\n        containsIcons = true,\n        containsText = true\n    ) ?: original\n}\n\nsuspend fun ToastHostState.showFailureToast(\n    context: Context,\n    throwable: Throwable\n) = showFailureToast(\n    message = context.getString(\n        R.string.smth_went_wrong,\n        throwable.localizedMessage?.decodeEscaped() ?: \"\"\n    )\n)\n\nsuspend fun ToastHostState.showFailureToast(\n    message: String\n) = showToast(\n    message = message,\n    icon = Icons.Rounded.ErrorOutline,\n    duration = ToastDuration.Long\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/other/TopAppBarEmoji.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.other\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.slideInHorizontally\nimport androidx.compose.animation.slideOutHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\n\n@Composable\nfun TopAppBarEmoji() {\n    val settingsState = LocalSettingsState.current\n\n    Box(\n        modifier = Modifier\n            .padding(end = 12.dp)\n            .scaleOnTap {\n                AppToastHost.showConfetti()\n            }\n    ) {\n        Row(horizontalArrangement = Arrangement.spacedBy(2.dp)) {\n            repeat(5) {\n                AnimatedVisibility(\n                    visible = settingsState.emojisCount > it,\n                    enter = fadeIn() + slideInHorizontally(),\n                    exit = fadeOut() + slideOutHorizontally()\n                ) {\n                    EmojiItem(\n                        fontScale = LocalSettingsState.current.fontScale\n                            ?: LocalDensity.current.fontScale,\n                        emoji = settingsState.selectedEmoji?.toString(),\n                        fontSize = MaterialTheme.typography.headlineMedium.fontSize\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/palette_selection/PaletteMappings.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.palette_selection\n\nimport android.content.Context\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.imagetoolbox.core.resources.R\n\nfun PaletteStyle.getTitle(context: Context): String {\n    return when (this) {\n        PaletteStyle.TonalSpot -> context.getString(R.string.tonal_spot)\n        PaletteStyle.Neutral -> context.getString(R.string.neutral)\n        PaletteStyle.Vibrant -> context.getString(R.string.vibrant)\n        PaletteStyle.Expressive -> context.getString(R.string.expressive)\n        PaletteStyle.Rainbow -> context.getString(R.string.rainbow)\n        PaletteStyle.FruitSalad -> context.getString(R.string.fruit_salad)\n        PaletteStyle.Monochrome -> context.getString(R.string.monochrome)\n        PaletteStyle.Fidelity -> context.getString(R.string.fidelity)\n        PaletteStyle.Content -> context.getString(R.string.content)\n    }\n}\n\nfun PaletteStyle.getSubtitle(context: Context): String {\n    return when (this) {\n        PaletteStyle.TonalSpot -> context.getString(R.string.tonal_spot_sub)\n        PaletteStyle.Neutral -> context.getString(R.string.neutral_sub)\n        PaletteStyle.Vibrant -> context.getString(R.string.vibrant_sub)\n        PaletteStyle.Expressive -> context.getString(R.string.playful_scheme)\n        PaletteStyle.Rainbow -> context.getString(R.string.playful_scheme)\n        PaletteStyle.FruitSalad -> context.getString(R.string.playful_scheme)\n        PaletteStyle.Monochrome -> context.getString(R.string.monochrome_sub)\n        PaletteStyle.Fidelity -> context.getString(R.string.fidelity_sub)\n        PaletteStyle.Content -> context.getString(R.string.content_sub)\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/palette_selection/PaletteStyleSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.palette_selection\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Swatch\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\nfun PaletteStyleSelection(\n    onThemeStyleSelected: (PaletteStyle) -> Unit,\n    shape: Shape,\n    modifier: Modifier = Modifier,\n    color: Color = Color.Unspecified\n) {\n    val settingsState = LocalSettingsState.current\n    var showPaletteStyleSelectionSheet by rememberSaveable { mutableStateOf(false) }\n    PreferenceItem(\n        title = stringResource(R.string.palette_style),\n        subtitle = remember(settingsState.themeStyle) {\n            derivedStateOf {\n                settingsState.themeStyle.getTitle(appContext)\n            }\n        }.value,\n        shape = shape,\n        containerColor = color,\n        modifier = modifier,\n        startIcon = Icons.Rounded.Swatch,\n        endIcon = Icons.Rounded.MiniEdit,\n        onClick = {\n            showPaletteStyleSelectionSheet = true\n        }\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showPaletteStyleSelectionSheet,\n        onDismiss = {\n            showPaletteStyleSelectionSheet = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.palette_style),\n                icon = Icons.Rounded.Swatch\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = { showPaletteStyleSelectionSheet = false }\n            ) {\n                Text(text = stringResource(R.string.close))\n            }\n        },\n        sheetContent = {\n            LazyVerticalStaggeredGrid(\n                columns = StaggeredGridCells.Adaptive(250.dp),\n                contentPadding = PaddingValues(16.dp),\n                verticalItemSpacing = 8.dp,\n                horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                items(PaletteStyle.entries) { style ->\n                    PaletteStyleSelectionItem(\n                        style = style,\n                        onClick = {\n                            onThemeStyleSelected(style)\n                        }\n                    )\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/palette_selection/PaletteStyleSelectionItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.palette_selection\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\nfun PaletteStyleSelectionItem(\n    style: PaletteStyle,\n    onClick: () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val selected = settingsState.themeStyle == style\n\n    PreferenceItem(\n        onClick = onClick,\n        title = style.getTitle(appContext),\n        subtitle = style.getSubtitle(appContext),\n        containerColor = takeColorFromScheme {\n            if (selected) secondaryContainer\n            else SafeLocalContainerColor\n        },\n        modifier = Modifier\n            .fillMaxWidth()\n            .border(\n                width = settingsState.borderWidth,\n                color = animateColorAsState(\n                    if (selected) MaterialTheme.colorScheme\n                        .onSecondaryContainer\n                        .copy(alpha = 0.5f)\n                    else Color.Transparent\n                ).value,\n                shape = ShapeDefaults.default\n            ),\n        endIcon = if (selected) Icons.Rounded.RadioButtonChecked else Icons.Rounded.RadioButtonUnchecked\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/preferences/PreferenceItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.preferences\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.ContentTransform\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\nprivate val DefaultStartTransition: AnimatedContentTransitionScope<ImageVector>.() -> ContentTransform =\n    {\n        fadeIn() + scaleIn() + slideInVertically() togetherWith fadeOut() + scaleOut() + slideOutVertically() using SizeTransform(\n            clip = false\n        )\n    }\n\nprivate val DefaultEndTransition: AnimatedContentTransitionScope<ImageVector>.() -> ContentTransform =\n    {\n        fadeIn() + scaleIn() togetherWith fadeOut() + scaleOut() using SizeTransform(clip = false)\n    }\n\n\n@Composable\nfun PreferenceItem(\n    onClick: (() -> Unit)? = null,\n    onLongClick: (() -> Unit)? = null,\n    title: String,\n    enabled: Boolean = true,\n    subtitle: String? = null,\n    startIcon: ImageVector? = null,\n    endIcon: ImageVector? = null,\n    autoShadowElevation: Dp = 1.dp,\n    shape: Shape = ShapeDefaults.default,\n    pressedShape: Shape = ShapeDefaults.pressed,\n    containerColor: Color = Color.Unspecified,\n    contentColor: Color = contentColorFor(backgroundColor = containerColor),\n    overrideIconShapeContentColor: Boolean = false,\n    drawStartIconContainer: Boolean = true,\n    titleFontStyle: TextStyle = PreferenceItemDefaults.TitleFontStyle,\n    startIconTransitionSpec: AnimatedContentTransitionScope<ImageVector>.() -> ContentTransform = DefaultStartTransition,\n    endIconTransitionSpec: AnimatedContentTransitionScope<ImageVector>.() -> ContentTransform = DefaultEndTransition,\n    onDisabledClick: (() -> Unit)? = null,\n    placeBottomContentInside: Boolean = false,\n    bottomContent: (@Composable () -> Unit)? = null,\n    modifier: Modifier = Modifier\n        .fillMaxWidth()\n        .padding(horizontal = 12.dp)\n) {\n    val targetIcon: (@Composable () -> Unit)? = if (startIcon == null) null else {\n        {\n            AnimatedContent(\n                targetState = startIcon,\n                transitionSpec = startIconTransitionSpec\n            ) { icon ->\n                Icon(\n                    imageVector = icon,\n                    contentDescription = null\n                )\n            }\n        }\n    }\n    val targetEndIcon: (@Composable () -> Unit)? = if (endIcon == null) null else {\n        {\n            Box {\n                AnimatedContent(\n                    targetState = endIcon,\n                    transitionSpec = endIconTransitionSpec\n                ) { endIcon ->\n                    Icon(\n                        imageVector = endIcon,\n                        contentDescription = null\n                    )\n                }\n            }\n        }\n    }\n\n    PreferenceItemOverload(\n        autoShadowElevation = autoShadowElevation,\n        contentColor = contentColor,\n        onClick = onClick,\n        onLongClick = onLongClick,\n        enabled = enabled,\n        title = title,\n        subtitle = subtitle,\n        startIcon = targetIcon,\n        endIcon = targetEndIcon,\n        overrideIconShapeContentColor = overrideIconShapeContentColor,\n        shape = shape,\n        pressedShape = pressedShape,\n        containerColor = containerColor,\n        modifier = modifier,\n        titleFontStyle = titleFontStyle,\n        onDisabledClick = onDisabledClick,\n        drawStartIconContainer = drawStartIconContainer,\n        placeBottomContentInside = placeBottomContentInside,\n        bottomContent = bottomContent\n    )\n}\n\n\nobject PreferenceItemDefaults {\n\n    val TitleFontStyle: TextStyle\n        @Composable\n        get() = LocalTextStyle.current.copy(\n            fontSize = 16.sp,\n            fontWeight = FontWeight.Medium,\n            lineHeight = 18.sp\n        )\n\n    val TitleFontStyleCentered: TextStyle\n        @Composable\n        get() = TitleFontStyle.copy(\n            textAlign = TextAlign.Center\n        )\n\n    val TitleFontStyleCenteredSmall: TextStyle\n        @Composable\n        get() = TitleFontStyleSmall.copy(\n            textAlign = TextAlign.Center\n        )\n\n    val TitleFontStyleSmall: TextStyle\n        @Composable\n        get() = LocalTextStyle.current.copy(\n            fontSize = 14.sp,\n            fontWeight = FontWeight.Medium,\n            lineHeight = 16.sp,\n            textAlign = TextAlign.Start\n        )\n\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/preferences/PreferenceItemOverload.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.preferences\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.CardDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\n\n\n@Composable\nfun PreferenceItemOverload(\n    onClick: (() -> Unit)? = null,\n    onLongClick: (() -> Unit)? = null,\n    title: String,\n    enabled: Boolean = true,\n    subtitle: String? = null,\n    autoShadowElevation: Dp = 1.dp,\n    startIcon: (@Composable () -> Unit)? = null,\n    endIcon: (@Composable () -> Unit)? = null,\n    badge: (@Composable RowScope.() -> Unit)? = null,\n    shape: Shape = ShapeDefaults.default,\n    pressedShape: Shape = ShapeDefaults.pressed,\n    containerColor: Color = Color.Unspecified,\n    contentColor: Color = contentColorFor(backgroundColor = containerColor),\n    overrideIconShapeContentColor: Boolean = false,\n    resultModifier: Modifier = Modifier.padding(16.dp),\n    modifier: Modifier = Modifier\n        .fillMaxWidth()\n        .padding(horizontal = 12.dp),\n    titleFontStyle: TextStyle = PreferenceItemDefaults.TitleFontStyle,\n    onDisabledClick: (() -> Unit)? = null,\n    drawStartIconContainer: Boolean = true,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    placeBottomContentInside: Boolean = false,\n    bottomContent: (@Composable () -> Unit)? = null\n) {\n    CompositionLocalProvider(\n        LocalSettingsState provides LocalSettingsState.current.let {\n            if (!enabled) it.copy(\n                drawButtonShadows = false,\n                drawContainerShadows = false,\n                drawFabShadows = false,\n                drawSwitchShadows = false,\n                drawSliderShadows = false\n            ) else it\n        }\n    ) {\n        val animatedShape = shapeByInteraction(\n            shape = shape,\n            pressedShape = pressedShape,\n            interactionSource = interactionSource\n        )\n        Card(\n            shape = RectangleShape,\n            modifier = modifier\n                .container(\n                    shape = animatedShape,\n                    resultPadding = 0.dp,\n                    color = containerColor,\n                    autoShadowElevation = autoShadowElevation\n                )\n                .alpha(animateFloatAsState(targetValue = if (enabled) 1f else 0.5f).value),\n            colors = CardDefaults.cardColors(\n                containerColor = Color.Transparent,\n                contentColor = contentColor\n            )\n        ) {\n            val onClickModifier = onClick\n                ?.let {\n                    if (enabled) {\n                        Modifier.hapticsCombinedClickable(\n                            interactionSource = interactionSource,\n                            indication = LocalIndication.current,\n                            onClick = onClick,\n                            onLongClick = onLongClick\n                        )\n                    } else {\n                        if (onDisabledClick != null) {\n                            Modifier.hapticsClickable(onClick = onDisabledClick)\n                        } else Modifier\n                    }\n                } ?: Modifier\n\n            Column(\n                modifier = Modifier\n                    .then(\n                        onClickModifier.takeIf { placeBottomContentInside } ?: Modifier\n                    )\n            ) {\n                Row(\n                    modifier = Modifier\n                        .then(onClickModifier.takeIf { !placeBottomContentInside } ?: Modifier)\n                        .then(resultModifier),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    startIcon?.let {\n                        ProvideContainerDefaults(\n                            color = containerColor\n                        ) {\n                            Row {\n                                IconShapeContainer(\n                                    enabled = drawStartIconContainer,\n                                    contentColor = if (overrideIconShapeContentColor) {\n                                        Color.Unspecified\n                                    } else IconShapeDefaults.contentColor,\n                                    content = {\n                                        startIcon()\n                                    }\n                                )\n                                Spacer(modifier = Modifier.width(16.dp))\n                            }\n                        }\n                    }\n                    Column(\n                        Modifier\n                            .weight(1f)\n                            .padding(end = 16.dp)\n                    ) {\n                        Row {\n                            AnimatedContent(\n                                targetState = title,\n                                transitionSpec = { fadeIn() togetherWith fadeOut() },\n                                modifier = Modifier.weight(1f, fill = badge == null)\n                            ) { title ->\n                                Text(\n                                    text = title,\n                                    style = titleFontStyle\n                                )\n                            }\n                            badge?.invoke(this)\n                        }\n                        AnimatedContent(\n                            targetState = subtitle,\n                            transitionSpec = { fadeIn() togetherWith fadeOut() }\n                        ) { sub ->\n                            sub?.let {\n                                Column {\n                                    Spacer(modifier = Modifier.height(2.dp))\n                                    Text(\n                                        text = sub,\n                                        fontSize = 12.sp,\n                                        textAlign = TextAlign.Start,\n                                        fontWeight = FontWeight.Normal,\n                                        lineHeight = 14.sp,\n                                        color = LocalContentColor.current.copy(alpha = 0.5f)\n                                    )\n                                }\n                            }\n                        }\n                        if (placeBottomContentInside) bottomContent?.invoke()\n                    }\n                    ProvideContainerDefaults {\n                        endIcon?.invoke()\n                    }\n                }\n                if (!placeBottomContentInside) bottomContent?.invoke()\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/preferences/PreferenceRow.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.preferences\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\n\n@Composable\nfun PreferenceRow(\n    modifier: Modifier = Modifier,\n    title: String,\n    subtitle: String? = null,\n    containerColor: Color = Color.Unspecified,\n    enabled: Boolean = true,\n    shape: Shape = ShapeDefaults.default,\n    pressedShape: Shape = ShapeDefaults.pressed,\n    contentColor: Color? = null,\n    applyHorizontalPadding: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    startContent: (@Composable () -> Unit)? = null,\n    endContent: (@Composable () -> Unit)? = null,\n    titleFontStyle: TextStyle = PreferenceItemDefaults.TitleFontStyle,\n    resultModifier: Modifier = Modifier.padding(\n        horizontal = if (startContent != null) 0.dp else 16.dp,\n        vertical = 8.dp\n    ),\n    changeAlphaWhenDisabled: Boolean = true,\n    drawStartIconContainer: Boolean = false,\n    onClick: (() -> Unit)?,\n    onDisabledClick: (() -> Unit)? = null,\n    autoShadowElevation: Dp = 1.dp,\n    additionalContent: (@Composable () -> Unit)? = null,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    drawContainer: Boolean = true,\n) {\n    val animatedShape = shapeByInteraction(\n        shape = shape,\n        pressedShape = pressedShape,\n        interactionSource = interactionSource\n    )\n\n    val internalColor = contentColor\n        ?: contentColorFor(backgroundColor = containerColor)\n    CompositionLocalProvider(\n        LocalContentColor provides internalColor,\n        LocalSettingsState provides LocalSettingsState.current.let {\n            if (!enabled) it.copy(\n                drawButtonShadows = false,\n                drawContainerShadows = false,\n                drawFabShadows = false,\n                drawSwitchShadows = false,\n                drawSliderShadows = false\n            ) else it\n        }\n    ) {\n        val rowModifier = modifier\n            .then(\n                if (applyHorizontalPadding) {\n                    Modifier.padding(horizontal = 16.dp)\n                } else Modifier\n            )\n            .then(\n                if (drawContainer) {\n                    Modifier.container(\n                        color = containerColor,\n                        shape = animatedShape,\n                        resultPadding = 0.dp,\n                        autoShadowElevation = autoShadowElevation\n                    )\n                } else Modifier\n            )\n            .then(\n                onClick\n                    ?.let {\n                        if (enabled) {\n                            Modifier.hapticsClickable(\n                                interactionSource = interactionSource,\n                                indication = LocalIndication.current,\n                                onClick = onClick\n                            )\n                        } else Modifier.then(\n                            if (onDisabledClick != null) {\n                                Modifier.hapticsClickable(\n                                    interactionSource = interactionSource,\n                                    indication = LocalIndication.current,\n                                    onClick = onDisabledClick\n                                )\n                            } else Modifier\n                        )\n                    } ?: Modifier\n            )\n            .then(resultModifier)\n            .then(\n                if (changeAlphaWhenDisabled) Modifier.alpha(animateFloatAsState(targetValue = if (enabled) 1f else 0.5f).value)\n                else Modifier\n            )\n\n        val rowContent: @Composable (Modifier) -> Unit = { modifier ->\n            Row(\n                modifier = modifier,\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                startContent?.let { content ->\n                    ProvideContainerDefaults(\n                        color = containerColor\n                    ) {\n                        if (drawStartIconContainer) {\n                            IconShapeContainer(\n                                content = {\n                                    content()\n                                },\n                                modifier = Modifier.padding(end = 16.dp)\n                            )\n                        } else content()\n                    }\n                }\n                Column(modifier = Modifier.weight(1f)) {\n                    AnimatedContent(\n                        targetState = title,\n                        transitionSpec = {\n                            fadeIn().togetherWith(fadeOut())\n                        }\n                    ) {\n                        Text(\n                            text = it,\n                            maxLines = maxLines,\n                            style = titleFontStyle,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                    }\n                    Spacer(modifier = Modifier.height(2.dp))\n                    AnimatedContent(\n                        targetState = subtitle,\n                        transitionSpec = {\n                            fadeIn().togetherWith(fadeOut())\n                        }\n                    ) {\n                        it?.let {\n                            Text(\n                                text = it,\n                                fontSize = 12.sp,\n                                textAlign = TextAlign.Start,\n                                fontWeight = FontWeight.Normal,\n                                lineHeight = 14.sp,\n                                color = LocalContentColor.current.copy(alpha = 0.5f)\n                            )\n                        }\n                    }\n                }\n                Spacer(Modifier.width(8.dp))\n                ProvideContainerDefaults(null) {\n                    endContent?.invoke()\n                }\n            }\n        }\n\n        if (additionalContent != null) {\n            Column(rowModifier) {\n                rowContent(Modifier)\n                Column(\n                    modifier = Modifier.pointerInput(Unit) {\n                        detectTapGestures { }\n                    }\n                ) {\n                    additionalContent()\n                }\n            }\n        } else {\n            rowContent(rowModifier)\n        }\n    }\n}\n\n\n@Composable\nfun PreferenceRow(\n    modifier: Modifier = Modifier,\n    title: String,\n    enabled: Boolean = true,\n    subtitle: String? = null,\n    autoShadowElevation: Dp = 1.dp,\n    color: Color = Color.Unspecified,\n    drawStartIconContainer: Boolean = true,\n    onDisabledClick: (() -> Unit)? = null,\n    changeAlphaWhenDisabled: Boolean = true,\n    contentColor: Color? = null,\n    shape: Shape = ShapeDefaults.default,\n    titleFontStyle: TextStyle = PreferenceItemDefaults.TitleFontStyle,\n    startIcon: ImageVector?,\n    endContent: (@Composable () -> Unit)? = null,\n    additionalContent: (@Composable () -> Unit)? = null,\n    onClick: (() -> Unit)?,\n) {\n    PreferenceRow(\n        modifier = modifier,\n        title = title,\n        enabled = enabled,\n        subtitle = subtitle,\n        changeAlphaWhenDisabled = changeAlphaWhenDisabled,\n        autoShadowElevation = autoShadowElevation,\n        containerColor = color,\n        contentColor = contentColor,\n        shape = shape,\n        titleFontStyle = titleFontStyle,\n        onDisabledClick = onDisabledClick,\n        drawStartIconContainer = false,\n        startContent = startIcon?.let {\n            {\n                IconShapeContainer(\n                    enabled = drawStartIconContainer,\n                    content = {\n                        AnimatedContent(startIcon) { startIcon ->\n                            Icon(\n                                imageVector = startIcon,\n                                contentDescription = null\n                            )\n                        }\n                    },\n                    modifier = Modifier.padding(end = 16.dp)\n                )\n            }\n        },\n        endContent = endContent,\n        resultModifier = if (endContent != null) {\n            Modifier.padding(\n                top = 8.dp,\n                start = 16.dp,\n                bottom = 8.dp\n            )\n        } else Modifier.padding(16.dp),\n        applyHorizontalPadding = false,\n        onClick = onClick,\n        additionalContent = additionalContent\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/preferences/PreferenceRowSwitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.preferences\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Check\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun PreferenceRowSwitch(\n    modifier: Modifier = Modifier,\n    title: String,\n    enabled: Boolean = true,\n    subtitle: String? = null,\n    autoShadowElevation: Dp = 1.dp,\n    applyHorizontalPadding: Boolean = true,\n    checked: Boolean,\n    containerColor: Color = Color.Unspecified,\n    contentColor: Color? = null,\n    shape: Shape = ShapeDefaults.default,\n    startContent: (@Composable () -> Unit)? = null,\n    resultModifier: Modifier = Modifier.padding(\n        horizontal = if (startContent != null) 0.dp else 16.dp,\n        vertical = 8.dp\n    ),\n    drawStartIconContainer: Boolean = false,\n    onDisabledClick: (() -> Unit)? = null,\n    onClick: (Boolean) -> Unit,\n    additionalContent: (@Composable () -> Unit)? = null,\n    changeAlphaWhenDisabled: Boolean = true,\n    drawContainer: Boolean = true,\n    contentInsteadOfSwitch: (@Composable () -> Unit)? = null,\n    titleFontStyle: TextStyle = PreferenceItemDefaults.TitleFontStyle,\n) {\n    val interactionSource = remember { MutableInteractionSource() }\n    PreferenceRow(\n        autoShadowElevation = autoShadowElevation,\n        enabled = enabled,\n        modifier = modifier,\n        resultModifier = resultModifier,\n        applyHorizontalPadding = applyHorizontalPadding,\n        title = title,\n        contentColor = contentColor,\n        shape = shape,\n        changeAlphaWhenDisabled = changeAlphaWhenDisabled,\n        containerColor = containerColor,\n        subtitle = subtitle,\n        startContent = startContent,\n        onDisabledClick = onDisabledClick,\n        onClick = {\n            if (contentInsteadOfSwitch == null) {\n                onClick(!checked)\n            }\n        },\n        drawStartIconContainer = drawStartIconContainer,\n        endContent = {\n            AnimatedContent(\n                targetState = contentInsteadOfSwitch,\n                modifier = Modifier.padding(start = 8.dp),\n            ) { contentOfSwitch ->\n                contentOfSwitch?.invoke() ?: EnhancedSwitch(\n                    thumbIcon = if (checked) Icons.Rounded.Check else null,\n                    colors = SwitchDefaults.colors(\n                        uncheckedBorderColor = MaterialTheme.colorScheme.outline.blend(\n                            containerColor, 0.3f\n                        ),\n                        uncheckedThumbColor = MaterialTheme.colorScheme.outline.blend(\n                            containerColor, 0.3f\n                        ),\n                        uncheckedTrackColor = containerColor,\n                        disabledUncheckedThumbColor = MaterialTheme.colorScheme.onSurface\n                            .copy(alpha = 0.12f)\n                            .compositeOver(MaterialTheme.colorScheme.surface),\n                        checkedIconColor = MaterialTheme.colorScheme.primary\n                    ),\n                    enabled = enabled,\n                    checked = checked,\n                    onCheckedChange = onClick,\n                    interactionSource = interactionSource,\n                    colorUnderSwitch = containerColor.takeOrElse { SafeLocalContainerColor }\n                )\n            }\n        },\n        interactionSource = interactionSource,\n        drawContainer = drawContainer,\n        additionalContent = additionalContent,\n        titleFontStyle = titleFontStyle\n    )\n}\n\n@Composable\nfun PreferenceRowSwitch(\n    modifier: Modifier = Modifier,\n    title: String,\n    enabled: Boolean = true,\n    subtitle: String? = null,\n    autoShadowElevation: Dp = 1.dp,\n    checked: Boolean,\n    containerColor: Color = Color.Unspecified,\n    onDisabledClick: (() -> Unit)? = null,\n    changeAlphaWhenDisabled: Boolean = true,\n    contentColor: Color? = null,\n    shape: Shape = ShapeDefaults.default,\n    startIcon: ImageVector?,\n    onClick: (Boolean) -> Unit,\n    additionalContent: (@Composable () -> Unit)? = null,\n    drawContainer: Boolean = true,\n    resultModifier: Modifier = Modifier.padding(16.dp),\n    contentInsteadOfSwitch: (@Composable () -> Unit)? = null,\n    titleFontStyle: TextStyle = PreferenceItemDefaults.TitleFontStyle,\n) {\n    PreferenceRowSwitch(\n        modifier = modifier,\n        title = title,\n        enabled = enabled,\n        subtitle = subtitle,\n        changeAlphaWhenDisabled = changeAlphaWhenDisabled,\n        autoShadowElevation = autoShadowElevation,\n        checked = checked,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        shape = shape,\n        onDisabledClick = onDisabledClick,\n        drawStartIconContainer = true,\n        startContent = startIcon?.let {\n            {\n                Icon(\n                    imageVector = startIcon,\n                    contentDescription = null\n                )\n            }\n        },\n        resultModifier = resultModifier,\n        applyHorizontalPadding = false,\n        onClick = onClick,\n        additionalContent = additionalContent,\n        drawContainer = drawContainer,\n        contentInsteadOfSwitch = contentInsteadOfSwitch,\n        titleFontStyle = titleFontStyle\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/preferences/ScreenPreference.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.preferences\n\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\n\n@Composable\ninternal fun ScreenPreference(\n    screen: Screen,\n    navigate: (Screen) -> Unit\n) {\n    val basePreference = @Composable {\n        PreferenceItem(\n            onClick = { navigate(screen) },\n            startIcon = screen.icon,\n            title = stringResource(screen.title),\n            subtitle = stringResource(screen.subtitle),\n            modifier = Modifier.fillMaxWidth()\n        )\n    }\n    when (screen) {\n        is Screen.GifTools -> {\n            if (screen.type != null) {\n                PreferenceItem(\n                    onClick = { navigate(screen) },\n                    startIcon = screen.type.icon,\n                    title = stringResource(screen.type.title),\n                    subtitle = stringResource(screen.type.subtitle),\n                    modifier = Modifier.fillMaxWidth()\n                )\n            } else basePreference()\n        }\n\n        is Screen.Filter -> {\n            if (screen.type != null) {\n                PreferenceItem(\n                    onClick = { navigate(screen) },\n                    startIcon = screen.type.icon,\n                    title = stringResource(screen.type.title),\n                    subtitle = stringResource(screen.type.subtitle),\n                    modifier = Modifier.fillMaxWidth()\n                )\n            } else basePreference()\n        }\n\n        is Screen.ApngTools -> {\n            if (screen.type != null) {\n                PreferenceItem(\n                    onClick = { navigate(screen) },\n                    startIcon = screen.type.icon,\n                    title = stringResource(screen.type.title),\n                    subtitle = stringResource(screen.type.subtitle),\n                    modifier = Modifier.fillMaxWidth()\n                )\n            } else basePreference()\n        }\n\n        is Screen.JxlTools -> {\n            if (screen.type != null) {\n                PreferenceItem(\n                    onClick = { navigate(screen) },\n                    startIcon = screen.type.icon,\n                    title = stringResource(screen.type.title),\n                    subtitle = stringResource(screen.type.subtitle),\n                    modifier = Modifier.fillMaxWidth()\n                )\n            } else basePreference()\n        }\n\n        is Screen.WebpTools -> {\n            if (screen.type != null) {\n                PreferenceItem(\n                    onClick = { navigate(screen) },\n                    startIcon = screen.type.icon,\n                    title = stringResource(screen.type.title),\n                    subtitle = stringResource(screen.type.subtitle),\n                    modifier = Modifier.fillMaxWidth()\n                )\n            } else basePreference()\n        }\n\n        is Screen.RecognizeText -> {\n            if (screen.type != null) {\n                PreferenceItem(\n                    onClick = { navigate(screen) },\n                    startIcon = screen.type.icon,\n                    title = stringResource(screen.type.title),\n                    subtitle = stringResource(screen.type.subtitle),\n                    modifier = Modifier.fillMaxWidth()\n                )\n            } else basePreference()\n        }\n\n        else -> basePreference()\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/saver/OneTimeEffect.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.saver\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport kotlinx.coroutines.CoroutineScope\n\n@Composable\nfun OneTimeEffect(\n    block: suspend CoroutineScope.() -> Unit\n) {\n    var isPerformed by rememberSaveable {\n        mutableStateOf(false)\n    }\n    LaunchedEffect(Unit) {\n        if (!isPerformed) {\n            block()\n            isPerformed = true\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/saver/Savers.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.saver\n\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.listSaver\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.PicturePickerMode\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\n\nval ColorSaver: Saver<Color, Int> = Saver(\n    save = {\n        it.toArgb()\n    },\n    restore = {\n        it.toColor()\n    }\n)\n\nval DpSaver: Saver<Dp, Float> = Saver(\n    save = {\n        it.value\n    },\n    restore = {\n        it.dp\n    }\n)\n\nval PicturePickerModeSaver: Saver<PicturePickerMode, Int> = Saver(\n    save = {\n        PicturePickerMode.entries.indexOf(it)\n    },\n    restore = {\n        PicturePickerMode.entries[it]\n    }\n)\n\nval PtSaver: Saver<Pt, Float> = Saver(\n    save = {\n        it.value\n    },\n    restore = {\n        it.pt\n    }\n)\n\nval OffsetSaver: Saver<Offset?, Any> = listSaver<Offset?, Float>(\n    save = {\n        listOfNotNull(it?.x, it?.y)\n    },\n    restore = {\n        if (it.isEmpty()) null\n        else Offset(it[0], it[1])\n    }\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/AddExifSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.AddCircleOutline\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.RemoveCircleOutline\nimport androidx.compose.material.icons.rounded.Search\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.localizedName\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport java.util.Locale\n\n@Composable\nfun AddExifSheet(\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    selectedTags: List<MetadataTag>,\n    onTagSelected: (MetadataTag) -> Unit,\n    isTagsRemovable: Boolean = false\n) {\n    val tags by remember(selectedTags, isTagsRemovable) {\n        derivedStateOf {\n            if (isTagsRemovable) {\n                val addedTags = MetadataTag.entries.filter {\n                    it in selectedTags\n                }.sorted()\n                val notAddedTags = (MetadataTag.entries - addedTags.toSet()).sorted()\n\n                addedTags + notAddedTags\n            } else {\n                MetadataTag.entries.filter {\n                    it !in selectedTags\n                }.sorted()\n            }\n        }\n    }\n    if (tags.isEmpty()) {\n        SideEffect {\n            onDismiss(false)\n        }\n    }\n    var isSearching by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var searchKeyword by rememberSaveable(isSearching) {\n        mutableStateOf(\"\")\n    }\n    val list by remember(tags, searchKeyword) {\n        derivedStateOf {\n            tags.filter {\n                it.localizedName(appContext).contains(searchKeyword, true)\n                        || it.localizedName(appContext, Locale.ENGLISH)\n                    .contains(searchKeyword, true)\n            }\n        }\n    }\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = onDismiss,\n        confirmButton = {},\n        enableBottomContentWeight = false,\n        title = {\n            AnimatedContent(\n                targetState = isSearching\n            ) { searching ->\n                if (searching) {\n                    BackHandler {\n                        searchKeyword = \"\"\n                        isSearching = false\n                    }\n                    ProvideTextStyle(value = MaterialTheme.typography.bodyLarge) {\n                        RoundedTextField(\n                            maxLines = 1,\n                            hint = { Text(stringResource(id = R.string.search_here)) },\n                            keyboardOptions = KeyboardOptions.Default.copy(\n                                imeAction = ImeAction.Search,\n                                autoCorrectEnabled = null\n                            ),\n                            value = searchKeyword,\n                            onValueChange = {\n                                searchKeyword = it\n                            },\n                            startIcon = {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        searchKeyword = \"\"\n                                        isSearching = false\n                                    },\n                                    modifier = Modifier.padding(start = 4.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit),\n                                        tint = MaterialTheme.colorScheme.onSurface\n                                    )\n                                }\n                            },\n                            endIcon = {\n                                AnimatedVisibility(\n                                    visible = searchKeyword.isNotEmpty(),\n                                    enter = fadeIn() + scaleIn(),\n                                    exit = fadeOut() + scaleOut()\n                                ) {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            searchKeyword = \"\"\n                                        },\n                                        modifier = Modifier.padding(end = 4.dp)\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.Close,\n                                            contentDescription = stringResource(R.string.close),\n                                            tint = MaterialTheme.colorScheme.onSurface\n                                        )\n                                    }\n                                }\n                            },\n                            shape = ShapeDefaults.circle\n                        )\n                    }\n                } else {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.add_tag),\n                            icon = Icons.Rounded.Exif\n                        )\n                        Spacer(modifier = Modifier.weight(1f))\n                        EnhancedIconButton(\n                            onClick = { isSearching = true },\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Search,\n                                contentDescription = stringResource(R.string.search_here)\n                            )\n                        }\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            onClick = { onDismiss(false) }\n                        ) {\n                            AutoSizeText(stringResource(R.string.close))\n                        }\n                        Spacer(Modifier.width(8.dp))\n                    }\n                }\n            }\n        },\n        sheetContent = {\n            AnimatedContent(list.isNotEmpty()) { haveData ->\n                if (haveData) {\n                    LazyColumn(\n                        contentPadding = PaddingValues(8.dp),\n                        verticalArrangement = Arrangement.spacedBy(4.dp),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        itemsIndexed(\n                            items = list,\n                            key = { _, t -> t.key }\n                        ) { index, tag ->\n                            val isSelected by remember(isTagsRemovable, tag, selectedTags) {\n                                derivedStateOf {\n                                    isTagsRemovable && tag in selectedTags\n                                }\n                            }\n                            val endIcon by remember(isSelected) {\n                                derivedStateOf {\n                                    if (isSelected) {\n                                        Icons.Rounded.RemoveCircleOutline\n                                    } else Icons.Rounded.AddCircleOutline\n                                }\n                            }\n                            PreferenceItem(\n                                title = tag.localizedName,\n                                modifier = Modifier,\n                                endIcon = endIcon,\n                                containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(\n                                    animateFloatAsState(if (isSelected) 0.35f else 0.1f).value\n                                ),\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = list.size\n                                ),\n                                onClick = {\n                                    onTagSelected(tag)\n                                }\n                            )\n                        }\n                    }\n                } else {\n                    Column(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .fillMaxHeight(0.5f),\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        Spacer(Modifier.weight(1f))\n                        Text(\n                            text = stringResource(R.string.nothing_found_by_search),\n                            fontSize = 18.sp,\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier.padding(\n                                start = 24.dp,\n                                end = 24.dp,\n                                top = 8.dp,\n                                bottom = 8.dp\n                            )\n                        )\n                        Icon(\n                            imageVector = Icons.Rounded.SearchOff,\n                            contentDescription = null,\n                            modifier = Modifier\n                                .weight(2f)\n                                .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                                .fillMaxSize()\n                        )\n                        Spacer(Modifier.weight(1f))\n                    }\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/DefaultUpdateSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.NewReleases\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.APP_RELEASES\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.HtmlText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun DefaultUpdateSheet(\n    changelog: String,\n    tag: String,\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.new_version, tag),\n                icon = Icons.Rounded.NewReleases\n            )\n        },\n        sheetContent = {\n            ProvideTextStyle(value = MaterialTheme.typography.bodyMedium) {\n                HtmlText(\n                    html = changelog.trimIndent().trim(),\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .enhancedVerticalScroll(rememberScrollState())\n                        .padding(12.dp)\n                        .container(resultPadding = 0.dp)\n                        .padding(\n                            start = 16.dp,\n                            end = 16.dp,\n                            top = 8.dp,\n                            bottom = 2.dp\n                        )\n                        .offset(y = 8.dp)\n                )\n            }\n        },\n        confirmButton = {\n            val linkHandler = LocalUriHandler.current\n            EnhancedButton(\n                onClick = {\n                    linkHandler.openUri(\"$APP_RELEASES/tag/${tag}\")\n                }\n            ) {\n                AutoSizeText(stringResource(id = R.string.update))\n            }\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/EditExifSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AddCircleOutline\nimport androidx.compose.material.icons.rounded.RemoveCircleOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.image.toMap\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.DeleteSweep\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.localizedName\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun EditExifSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    exif: Metadata?,\n    onClearExif: () -> Unit,\n    onUpdateTag: (MetadataTag, String) -> Unit,\n    onRemoveTag: (MetadataTag) -> Unit\n) {\n    var showClearExifDialog by rememberSaveable { mutableStateOf(false) }\n    val showAddExifDialog = rememberSaveable { mutableStateOf(false) }\n\n    var exifMap by remember(exif) {\n        mutableStateOf(exif?.toMap())\n    }\n\n    EnhancedModalBottomSheet(\n        confirmButton = {\n            val count = remember(exifMap) {\n                MetadataTag.entries.count {\n                    it !in (exifMap?.keys ?: emptyList())\n                }\n            }\n            Row(\n                modifier = Modifier.offset(x = 8.dp),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                AnimatedVisibility(exifMap?.isEmpty() == false) {\n                    EnhancedIconButton(\n                        containerColor = MaterialTheme.colorScheme.errorContainer,\n                        onClick = {\n                            showClearExifDialog = true\n                        },\n                        forceMinimumInteractiveComponentSize = false\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.DeleteSweep,\n                            contentDescription = null\n                        )\n                    }\n                }\n                AnimatedVisibility(count > 0) {\n                    EnhancedIconButton(\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        onClick = { showAddExifDialog.value = true }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.AddCircleOutline,\n                            contentDescription = null\n                        )\n                    }\n                }\n                Spacer(Modifier.width(4.dp))\n                EnhancedButton(\n                    onClick = onDismiss\n                ) {\n                    AutoSizeText(stringResource(R.string.close))\n                }\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.edit_exif),\n                icon = Icons.Rounded.Exif,\n                modifier = Modifier.padding(top = 16.dp, bottom = 16.dp, start = 8.dp, end = 16.dp)\n            )\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        }\n    ) {\n        val data by remember(exifMap) {\n            derivedStateOf {\n                exifMap!!.toList()\n            }\n        }\n        if (exifMap?.isEmpty() == false) {\n            Box {\n                LazyColumn(\n                    contentPadding = PaddingValues(8.dp),\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    itemsIndexed(\n                        items = data,\n                        key = { _, t -> t.first.key }\n                    ) { index, (tag, value) ->\n                        Column(\n                            Modifier\n                                .fillMaxWidth()\n                                .container(\n                                    color = EnhancedBottomSheetDefaults.contentContainerColor,\n                                    shape = ShapeDefaults.byIndex(\n                                        index = index,\n                                        size = data.size\n                                    )\n                                )\n                        ) {\n                            Row {\n                                Text(\n                                    text = tag.localizedName,\n                                    fontSize = 16.sp,\n                                    modifier = Modifier\n                                        .padding(12.dp)\n                                        .weight(1f),\n                                    textAlign = TextAlign.Start\n                                )\n                                EnhancedIconButton(\n                                    onClick = {\n                                        onRemoveTag(tag)\n                                        exifMap = exifMap?.toMutableMap()\n                                            ?.apply { remove(tag) }\n                                    }\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.RemoveCircleOutline,\n                                        contentDescription = stringResource(R.string.remove)\n                                    )\n                                }\n                            }\n                            OutlinedTextField(\n                                onValueChange = {\n                                    onUpdateTag(tag, it)\n                                    exifMap = exifMap?.toMutableMap()\n                                        ?.apply {\n                                            this[tag] = it\n                                        }\n                                },\n                                value = value,\n                                textStyle = LocalTextStyle.current.copy(\n                                    fontSize = 16.sp,\n                                    fontWeight = FontWeight.Bold\n                                ),\n                                keyboardOptions = KeyboardOptions.Default.copy(\n                                    imeAction = ImeAction.Next,\n                                    autoCorrectEnabled = null\n                                ),\n                                modifier = Modifier\n                                    .fillMaxWidth()\n                                    .padding(8.dp)\n                            )\n                        }\n                    }\n                }\n            }\n        } else {\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .fillMaxHeight(0.5f),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                Spacer(Modifier.weight(1f))\n                Text(\n                    text = stringResource(R.string.no_exif),\n                    fontSize = 18.sp,\n                    textAlign = TextAlign.Center,\n                    modifier = Modifier.padding(\n                        start = 24.dp,\n                        end = 24.dp,\n                        top = 8.dp,\n                        bottom = 8.dp\n                    )\n                )\n                Icon(\n                    imageVector = Icons.Outlined.Exif,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .weight(2f)\n                        .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                        .fillMaxSize()\n                )\n                Spacer(Modifier.weight(1f))\n            }\n        }\n        AddExifSheet(\n            visible = showAddExifDialog.value,\n            onDismiss = {\n                showAddExifDialog.value = it\n            },\n            selectedTags = (exifMap?.keys?.toList() ?: emptyList()),\n            onTagSelected = { tag ->\n                onRemoveTag(tag)\n                exifMap = exifMap?.toMutableMap()\n                    ?.apply { this[tag] = \"\" }\n            }\n        )\n        EnhancedAlertDialog(\n            visible = showClearExifDialog,\n            onDismissRequest = { showClearExifDialog = false },\n            title = {\n                Text(stringResource(R.string.clear_exif))\n            },\n            icon = {\n                Icon(\n                    imageVector = Icons.Outlined.DeleteSweep,\n                    contentDescription = null\n                )\n            },\n            confirmButton = {\n                EnhancedButton(\n                    onClick = { showClearExifDialog = false }\n                ) {\n                    Text(stringResource(R.string.cancel))\n                }\n            },\n            dismissButton = {\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    onClick = {\n                        showClearExifDialog = false\n                        onClearExif()\n                        exifMap = emptyMap()\n                    }\n                ) {\n                    Text(stringResource(R.string.clear))\n                }\n            },\n            text = {\n                Text(stringResource(R.string.clear_exif_sub))\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/EmojiSelectionSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport android.net.Uri\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.GridItemSpan\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Face5\nimport androidx.compose.material.icons.outlined.Face6\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material.icons.rounded.Shuffle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.layout.onGloballyPositioned\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.emoji.Emoji\nimport com.t8rin.imagetoolbox.core.resources.emoji.EmojiData\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.other.EmojiItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.GradientEdge\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlin.random.Random\n\n@Composable\nfun EmojiSelectionSheet(\n    selectedEmojiIndex: Int?,\n    emojiWithCategories: ImmutableList<EmojiData> = Emoji.allIconsCategorized(),\n    allEmojis: ImmutableList<Uri> = Emoji.allIcons(),\n    onEmojiPicked: (Int) -> Unit,\n    visible: Boolean,\n    icon: ImageVector = Icons.Outlined.Face5,\n    onDismiss: () -> Unit\n) {\n    val state = rememberLazyGridState()\n\n    LaunchedEffect(visible) {\n        delay(600)\n        if ((selectedEmojiIndex ?: -1) >= 0) {\n            var count = 0\n            val item = emojiWithCategories.find { (_, _, emojis) ->\n                count = 0\n                emojis.forEach { emoji ->\n                    count++\n                    val index = allEmojis.indexOf(emoji)\n                    if (index == selectedEmojiIndex) return@find true\n                }\n                return@find false\n            } ?: return@LaunchedEffect\n            val index = emojiWithCategories.indexOf(item)\n\n            state.animateScrollToItem(\n                index = index,\n                scrollOffset = 60 * count / 6\n            )\n        }\n    }\n\n    val emojiEnabled by remember(selectedEmojiIndex) {\n        derivedStateOf {\n            selectedEmojiIndex != -1\n        }\n    }\n    val scope = rememberCoroutineScope()\n\n    EnhancedModalBottomSheet(\n        confirmButton = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                if (selectedEmojiIndex != null) {\n                    EnhancedIconButton(\n                        containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                        enabled = emojiEnabled,\n                        onClick = {\n                            onEmojiPicked(Random.nextInt(0, allEmojis.lastIndex))\n                            scope.launch {\n                                state.animateScrollToItem(selectedEmojiIndex)\n                            }\n                        },\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Shuffle,\n                            contentDescription = stringResource(R.string.shuffle)\n                        )\n                    }\n                }\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    onClick = onDismiss\n                ) {\n                    AutoSizeText(stringResource(R.string.close))\n                }\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.emoji),\n                icon = icon\n            )\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        }\n    ) {\n        val alphaState by remember(emojiEnabled) {\n            derivedStateOf {\n                if (emojiEnabled) 1f else 0.4f\n            }\n        }\n\n        Box {\n            val density = LocalDensity.current\n            var topPadding by remember {\n                mutableStateOf(0.dp)\n            }\n            val contentPadding by remember(topPadding) {\n                derivedStateOf {\n                    PaddingValues(\n                        start = 16.dp,\n                        end = 16.dp,\n                        bottom = 16.dp,\n                        top = topPadding\n                    )\n                }\n            }\n            var expandedCategories by rememberSaveable(visible) {\n                mutableStateOf(\n                    if ((selectedEmojiIndex ?: -1) >= 0) {\n                        emojiWithCategories.find { (_, _, emojis) ->\n                            emojis.forEach { emoji ->\n                                val index = allEmojis.indexOf(emoji)\n                                if (index == selectedEmojiIndex) return@find true\n                            }\n                            return@find false\n                        }?.title ?: \"\"\n                    } else \"\"\n                )\n            }\n\n            Column(\n                modifier = Modifier.fillMaxSize()\n            ) {\n                LazyVerticalGrid(\n                    state = state,\n                    columns = GridCells.Adaptive(55.dp),\n                    modifier = Modifier\n                        .weight(1f)\n                        .fillMaxWidth()\n                        .alpha(\n                            animateFloatAsState(alphaState).value\n                        ),\n                    userScrollEnabled = emojiEnabled,\n                    verticalArrangement = Arrangement.spacedBy(\n                        6.dp,\n                        Alignment.CenterVertically\n                    ),\n                    horizontalArrangement = Arrangement.spacedBy(\n                        6.dp,\n                        Alignment.CenterHorizontally\n                    ),\n                    contentPadding = contentPadding,\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    emojiWithCategories.forEach { (title, icon, emojis) ->\n                        item(\n                            span = { GridItemSpan(maxLineSpan) },\n                            key = icon.name\n                        ) {\n                            val expanded by remember(title, expandedCategories) {\n                                derivedStateOf {\n                                    title in expandedCategories\n                                }\n                            }\n                            val interactionSource = remember { MutableInteractionSource() }\n\n                            TitleItem(\n                                modifier = Modifier\n                                    .padding(\n                                        bottom = animateDpAsState(\n                                            if (expanded) 8.dp\n                                            else 0.dp\n                                        ).value\n                                    )\n                                    .container(\n                                        color = MaterialTheme.colorScheme.surfaceContainerHigh,\n                                        resultPadding = 0.dp,\n                                        shape = shapeByInteraction(\n                                            shape = ShapeDefaults.default,\n                                            pressedShape = ShapeDefaults.pressed,\n                                            interactionSource = interactionSource\n                                        )\n                                    )\n                                    .hapticsClickable(\n                                        interactionSource = interactionSource,\n                                        indication = LocalIndication.current\n                                    ) {\n                                        expandedCategories = if (expanded) {\n                                            expandedCategories.replace(title, \"\")\n                                        } else expandedCategories + title\n                                    }\n                                    .padding(16.dp),\n                                text = title,\n                                icon = icon,\n                                endContent = {\n                                    Icon(\n                                        imageVector = Icons.Rounded.KeyboardArrowDown,\n                                        contentDescription = null,\n                                        modifier = Modifier.rotate(\n                                            animateFloatAsState(\n                                                if (expanded) 180f\n                                                else 0f\n                                            ).value\n                                        )\n                                    )\n                                }\n                            )\n                        }\n                        if (title in expandedCategories) {\n                            emojis.forEach { emoji ->\n                                item(\n                                    key = emoji\n                                ) {\n                                    val index by remember(allEmojis, emoji) {\n                                        derivedStateOf {\n                                            allEmojis.indexOf(emoji)\n                                        }\n                                    }\n                                    val selected by remember(index, selectedEmojiIndex) {\n                                        derivedStateOf {\n                                            index == selectedEmojiIndex\n                                        }\n                                    }\n                                    val color by animateColorAsState(\n                                        if (selected) MaterialTheme.colorScheme.primaryContainer\n                                        else SafeLocalContainerColor\n                                    )\n                                    val borderColor by animateColorAsState(\n                                        if (selected) {\n                                            MaterialTheme.colorScheme.onPrimaryContainer.copy(0.7f)\n                                        } else MaterialTheme.colorScheme.onSecondaryContainer.copy(\n                                            alpha = 0.1f\n                                        )\n                                    )\n                                    Box(\n                                        modifier = Modifier\n                                            .animateItem()\n                                            .aspectRatio(1f)\n                                            .container(\n                                                color = color,\n                                                shape = CloverShape,\n                                                borderColor = borderColor,\n                                                resultPadding = 0.dp\n                                            )\n                                            .hapticsClickable {\n                                                onEmojiPicked(index)\n                                            },\n                                        contentAlignment = Alignment.Center\n                                    ) {\n                                        EmojiItem(\n                                            emoji = emoji.toString(),\n                                            fontSize = MaterialTheme.typography.headlineLarge.fontSize,\n                                            fontScale = 1f\n                                        )\n                                    }\n                                }\n                            }\n                            item(\n                                span = { GridItemSpan(maxLineSpan) }\n                            ) {\n                                Spacer(Modifier.height(2.dp))\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (selectedEmojiIndex != null) {\n                Column(\n                    modifier = Modifier.onGloballyPositioned {\n                        topPadding = with(density) {\n                            it.size.height.toDp()\n                        }\n                    }\n                ) {\n                    var toggleEmoji by remember {\n                        mutableIntStateOf(0)\n                    }\n                    var checked by remember {\n                        mutableStateOf(emojiEnabled)\n                    }\n\n                    LaunchedEffect(toggleEmoji) {\n                        if (toggleEmoji > 0) {\n                            if (checked) onEmojiPicked(Random.nextInt(0, allEmojis.lastIndex))\n                            else onEmojiPicked(-1)\n                        }\n                    }\n\n                    PreferenceRowSwitch(\n                        title = stringResource(R.string.enable_emoji),\n                        containerColor = animateColorAsState(\n                            if (emojiEnabled) MaterialTheme.colorScheme.primaryContainer\n                            else MaterialTheme.colorScheme.surfaceContainer\n                        ).value,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .background(EnhancedBottomSheetDefaults.containerColor)\n                            .padding(start = 16.dp, top = 20.dp, bottom = 8.dp, end = 16.dp),\n                        shape = ShapeDefaults.extremeLarge,\n                        checked = emojiEnabled,\n                        startIcon = Icons.Outlined.Face6,\n                        onClick = { checked = it; toggleEmoji++ }\n                    )\n                    GradientEdge(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .height(16.dp),\n                        startColor = EnhancedBottomSheetDefaults.containerColor,\n                        endColor = Color.Transparent\n                    )\n                }\n            } else {\n                LaunchedEffect(Unit) {\n                    topPadding = 16.dp\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/PickImageFromUrisSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport android.net.Uri\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.PhotoLibrary\nimport androidx.compose.material.icons.rounded.RemoveCircleOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.notNullAnd\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun PickImageFromUrisSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    transformations: List<Transformation>? = null,\n    uris: List<Uri>?,\n    selectedUri: Uri?,\n    onUriRemoved: (Uri) -> Unit,\n    columns: Int,\n    onUriPicked: (Uri) -> Unit\n) {\n    val hasUris = uris.notNullAnd { it.size >= 2 }\n    if (!hasUris) onDismiss()\n\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            val gridState = rememberLazyGridState()\n            LaunchedEffect(Unit) {\n                gridState.scrollToItem(\n                    uris?.indexOf(selectedUri) ?: 0\n                )\n            }\n            Box {\n                LazyVerticalGrid(\n                    columns = GridCells.Fixed(columns),\n                    contentPadding = PaddingValues(8.dp),\n                    state = gridState,\n                    verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),\n                    horizontalArrangement = Arrangement.spacedBy(\n                        8.dp,\n                        Alignment.CenterHorizontally\n                    ),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    uris?.let { uris ->\n                        items(\n                            items = uris,\n                            key = { it.toString() + it.hashCode() }\n                        ) { uri ->\n                            val selected = selectedUri == uri\n                            val color by animateColorAsState(\n                                if (selected) MaterialTheme.colorScheme.surface\n                                else MaterialTheme.colorScheme.surfaceContainerHigh\n                            )\n                            val padding by animateDpAsState(if (selected) 12.dp else 4.dp)\n                            val pictureShape = animateShape(\n                                if (selected) ShapeDefaults.large\n                                else ShapeDefaults.mini\n                            )\n                            val borderWidth by animateDpAsState(if (selected) 1.5.dp else (-1).dp)\n                            val borderColor by animateColorAsState(\n                                if (selected) MaterialTheme.colorScheme.primaryContainer\n                                else Color.Transparent\n                            )\n                            Box(\n                                modifier = Modifier\n                                    .container(\n                                        shape = ShapeDefaults.mini,\n                                        resultPadding = 0.dp,\n                                        color = color\n                                    )\n                                    .animateItem()\n                            ) {\n                                Picture(\n                                    transformations = transformations,\n                                    model = uri,\n                                    modifier = Modifier\n                                        .aspectRatio(1f)\n                                        .clip(pictureShape)\n                                        .padding(padding)\n                                        .clip(pictureShape)\n                                        .hapticsClickable {\n                                            onUriPicked(uri)\n                                            onDismiss()\n                                        }\n                                        .border(\n                                            width = borderWidth,\n                                            color = borderColor,\n                                            shape = pictureShape\n                                        ),\n                                    shape = RectangleShape,\n                                    contentScale = ContentScale.Fit\n                                )\n                                BoxAnimatedVisibility(\n                                    visible = selected,\n                                    modifier = Modifier.align(Alignment.TopEnd)\n                                ) {\n                                    Box {\n                                        Box(\n                                            modifier = Modifier\n                                                .padding(1.dp)\n                                                .size(36.dp)\n                                                .clip(\n                                                    AutoCornersShape(\n                                                        bottomStartPercent = 50\n                                                    )\n                                                )\n                                                .background(MaterialTheme.colorScheme.primaryContainer)\n                                        )\n                                        Box(\n                                            modifier = Modifier\n                                                .width(38.dp)\n                                                .height(padding)\n                                                .background(color)\n                                        )\n                                        Box(\n                                            modifier = Modifier\n                                                .align(Alignment.BottomEnd)\n                                                .width(padding)\n                                                .height(38.dp)\n                                                .background(color)\n                                        )\n                                    }\n                                }\n                                EnhancedIconButton(\n                                    onClick = {\n                                        onUriRemoved(uri)\n                                    },\n                                    forceMinimumInteractiveComponentSize = false,\n                                    containerColor = color,\n                                    enabled = hasUris,\n                                    modifier = Modifier\n                                        .size(36.dp)\n                                        .align(Alignment.TopEnd),\n                                    enableAutoShadowAndBorder = false,\n                                    shape = AutoCornersShape(\n                                        bottomStartPercent = 50\n                                    )\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.RemoveCircleOutline,\n                                        contentDescription = stringResource(R.string.remove)\n                                    )\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss,\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.change_preview),\n                icon = Icons.Rounded.PhotoLibrary\n            )\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/ProcessImagesPreferenceSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport android.net.Uri\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Image\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material.icons.rounded.Visibility\nimport androidx.compose.material.icons.rounded.VisibilityOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.LayersSearchOutline\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.ScreenPreference\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.screenList\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport java.util.Locale\n\n@Composable\nfun ProcessImagesPreferenceSheet(\n    uris: List<Uri>,\n    extraDataType: ExtraDataType? = null,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onNavigate: (Screen) -> Unit\n) {\n    val resourceManager = LocalResourceManager.current\n\n    var isSearching by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var searchKeyword by rememberSaveable(isSearching) {\n        mutableStateOf(\"\")\n    }\n\n    val (rawScreenList, hiddenScreenList) = uris.screenList(extraDataType).value\n\n    val urisCorrespondingScreens by remember(hiddenScreenList, rawScreenList, searchKeyword) {\n        derivedStateOf {\n            if (searchKeyword.isNotBlank()) {\n                (rawScreenList + hiddenScreenList).filter {\n                    val string =\n                        resourceManager.getString(it.title) + \" \" + resourceManager.getString(it.subtitle)\n                    val stringEn =\n                        resourceManager.getStringLocalized(it.title, Locale.ENGLISH.language)\n                            .plus(\" \")\n                            .plus(\n                                resourceManager.getStringLocalized(\n                                    it.subtitle,\n                                    Locale.ENGLISH.language\n                                )\n                            )\n                    stringEn.contains(other = searchKeyword, ignoreCase = true).or(\n                        string.contains(other = searchKeyword, ignoreCase = true)\n                    )\n                }\n            } else {\n                rawScreenList\n            }\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        title = {\n            AnimatedContent(\n                targetState = isSearching\n            ) { searching ->\n                if (searching) {\n                    BackHandler {\n                        searchKeyword = \"\"\n                        isSearching = false\n                    }\n                    ProvideTextStyle(value = MaterialTheme.typography.bodyLarge) {\n                        RoundedTextField(\n                            maxLines = 1,\n                            hint = { Text(stringResource(id = R.string.search_here)) },\n                            keyboardOptions = KeyboardOptions.Default.copy(\n                                imeAction = ImeAction.Search,\n                                autoCorrectEnabled = null\n                            ),\n                            value = searchKeyword,\n                            onValueChange = {\n                                searchKeyword = it\n                            },\n                            startIcon = {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        searchKeyword = \"\"\n                                        isSearching = false\n                                    },\n                                    modifier = Modifier.padding(start = 4.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit),\n                                        tint = MaterialTheme.colorScheme.onSurface\n                                    )\n                                }\n                            },\n                            endIcon = {\n                                AnimatedVisibility(\n                                    visible = searchKeyword.isNotEmpty(),\n                                    enter = fadeIn() + scaleIn(),\n                                    exit = fadeOut() + scaleOut()\n                                ) {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            searchKeyword = \"\"\n                                        },\n                                        modifier = Modifier.padding(end = 4.dp)\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.Close,\n                                            contentDescription = stringResource(R.string.close),\n                                            tint = MaterialTheme.colorScheme.onSurface\n                                        )\n                                    }\n                                }\n                            },\n                            shape = ShapeDefaults.circle\n                        )\n                    }\n                } else {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.image),\n                            icon = Icons.Rounded.Image\n                        )\n                        Spacer(modifier = Modifier.weight(1f))\n                        EnhancedIconButton(\n                            onClick = { isSearching = true },\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer\n                        ) {\n                            Icon(\n                                imageVector = Icons.Outlined.LayersSearchOutline,\n                                contentDescription = stringResource(R.string.search_here)\n                            )\n                        }\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            onClick = onDismiss\n                        ) {\n                            AutoSizeText(stringResource(R.string.close))\n                        }\n                        Spacer(Modifier.width(8.dp))\n                    }\n                }\n            }\n        },\n        sheetContent = {\n            val scope = rememberCoroutineScope()\n\n            AnimatedContent(\n                targetState = urisCorrespondingScreens.isNotEmpty(),\n                modifier = Modifier.fillMaxWidth()\n            ) { isNotEmpty ->\n                if (isNotEmpty) {\n                    var showHidden by rememberSaveable {\n                        mutableStateOf(false)\n                    }\n\n                    LazyVerticalStaggeredGrid(\n                        columns = StaggeredGridCells.Adaptive(250.dp),\n                        contentPadding = PaddingValues(16.dp),\n                        verticalItemSpacing = 8.dp,\n                        horizontalArrangement = Arrangement.spacedBy(8.dp),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        if (extraDataType == null || extraDataType == ExtraDataType.Gif) {\n                            item(\n                                span = StaggeredGridItemSpan.FullLine\n                            ) {\n                                UrisCarousel(uris)\n                            }\n                        }\n                        items(\n                            items = urisCorrespondingScreens,\n                            key = { it.toString() }\n                        ) { screen ->\n                            ScreenPreference(\n                                screen = screen,\n                                navigate = {\n                                    scope.launch {\n                                        onDismiss()\n                                        delay(200)\n                                        onNavigate(screen)\n                                    }\n                                }\n                            )\n                        }\n\n                        if (hiddenScreenList.isNotEmpty() && searchKeyword.isBlank()) {\n                            item(\n                                span = StaggeredGridItemSpan.FullLine\n                            ) {\n                                val interactionSource = remember { MutableInteractionSource() }\n\n                                TitleItem(\n                                    modifier = Modifier\n                                        .padding(\n                                            vertical = animateDpAsState(\n                                                if (showHidden) 8.dp\n                                                else 0.dp\n                                            ).value\n                                        )\n                                        .container(\n                                            color = MaterialTheme.colorScheme.surfaceContainerHigh,\n                                            resultPadding = 0.dp,\n                                            shape = shapeByInteraction(\n                                                shape = ShapeDefaults.default,\n                                                pressedShape = ShapeDefaults.pressed,\n                                                interactionSource = interactionSource\n                                            )\n                                        )\n                                        .hapticsClickable(\n                                            interactionSource = interactionSource,\n                                            indication = LocalIndication.current\n                                        ) {\n                                            showHidden = !showHidden\n                                        }\n                                        .padding(16.dp),\n                                    text = stringResource(R.string.hidden_tools),\n                                    icon = if (showHidden) {\n                                        Icons.Rounded.Visibility\n                                    } else {\n                                        Icons.Rounded.VisibilityOff\n                                    },\n                                    endContent = {\n                                        Icon(\n                                            imageVector = Icons.Rounded.KeyboardArrowDown,\n                                            contentDescription = null,\n                                            modifier = Modifier.rotate(\n                                                animateFloatAsState(\n                                                    if (showHidden) 180f\n                                                    else 0f\n                                                ).value\n                                            )\n                                        )\n                                    }\n                                )\n                            }\n\n                            if (showHidden) {\n                                items(\n                                    items = hiddenScreenList,\n                                    key = { it.toString() }\n                                ) { screen ->\n                                    ScreenPreference(\n                                        screen = screen,\n                                        navigate = {\n                                            scope.launch {\n                                                onDismiss()\n                                                delay(200)\n                                                onNavigate(screen)\n                                            }\n                                        }\n                                    )\n                                }\n                            }\n                        }\n                    }\n                } else {\n                    Column(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .fillMaxHeight(0.5f),\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        Spacer(Modifier.weight(1f))\n                        Text(\n                            text = stringResource(R.string.nothing_found_by_search),\n                            fontSize = 18.sp,\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier.padding(\n                                start = 24.dp,\n                                end = 24.dp,\n                                top = 8.dp,\n                                bottom = 8.dp\n                            )\n                        )\n                        Icon(\n                            imageVector = Icons.Rounded.SearchOff,\n                            contentDescription = null,\n                            modifier = Modifier\n                                .weight(2f)\n                                .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                                .fillMaxSize()\n                        )\n                        Spacer(Modifier.weight(1f))\n                    }\n                }\n            }\n        },\n        confirmButton = {},\n        enableBottomContentWeight = false,\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        }\n    )\n}\n\n@Preview\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    ProcessImagesPreferenceSheet(\n        uris = listOf(\"fff\".toUri()),\n        visible = true,\n        extraDataType = null,\n        onDismiss = {},\n        onNavigate = {}\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/UpdateSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport androidx.compose.runtime.Composable\n\n@Composable\nfun UpdateSheet(\n    changelog: String,\n    tag: String,\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    UpdateSheetImpl(\n        changelog = changelog,\n        tag = tag,\n        visible = visible,\n        onDismiss = onDismiss\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sheets/ZoomModalSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport android.content.res.Resources\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ZoomIn\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.asDrawable\nimport coil3.transform.Transformation\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n@Composable\nfun ZoomModalSheet(\n    data: Any?,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    transformations: List<Transformation> = emptyList()\n) {\n    val sheetContent: @Composable ColumnScope.() -> Unit = {\n        val zoomState = rememberZoomState(maxScale = 15f)\n        var aspectRatio by remember(data) {\n            mutableFloatStateOf(1f)\n        }\n        Column(\n            modifier = Modifier.navigationBarsPadding()\n        ) {\n            Box(\n                modifier = Modifier.weight(1f)\n            ) {\n                Box(\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .padding(horizontal = 16.dp)\n                        .container(\n                            shape = ShapeDefaults.extraSmall,\n                            color = MaterialTheme.colorScheme\n                                .outlineVariant()\n                                .copy(alpha = 0.1f),\n                            resultPadding = 0.dp\n                        )\n                        .transparencyChecker()\n                        .clipToBounds()\n                        .zoomable(\n                            zoomState = zoomState\n                        ),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Picture(\n                        model = data,\n                        contentDescription = null,\n                        onSuccess = {\n                            aspectRatio =\n                                it.result.image.asDrawable(Resources.getSystem()).safeAspectRatio\n                        },\n                        contentScale = ContentScale.FillBounds,\n                        showTransparencyChecker = false,\n                        transformations = transformations,\n                        shape = RectangleShape,\n                        modifier = Modifier.aspectRatio(aspectRatio)\n                    )\n                }\n                val zoomLevel = zoomState.scale\n                BoxAnimatedVisibility(\n                    visible = zoomLevel > 1f,\n                    modifier = Modifier\n                        .padding(\n                            horizontal = 24.dp,\n                            vertical = 8.dp\n                        )\n                        .align(Alignment.TopStart),\n                    enter = scaleIn() + fadeIn(),\n                    exit = scaleOut() + fadeOut()\n                ) {\n                    Text(\n                        text = stringResource(R.string.zoom) + \" ${zoomLevel.roundToTwoDigits()}x\",\n                        modifier = Modifier\n                            .background(\n                                MaterialTheme.colorScheme.scrim.copy(0.4f),\n                                ShapeDefaults.circle\n                            )\n                            .padding(horizontal = 8.dp, vertical = 4.dp),\n                        color = Color.White\n                    )\n                }\n            }\n            Row(\n                modifier = Modifier.padding(8.dp),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                TitleItem(text = stringResource(R.string.zoom), icon = Icons.Rounded.ZoomIn)\n                Spacer(Modifier.weight(1f))\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    onClick = onDismiss,\n                    modifier = Modifier.padding(horizontal = 12.dp)\n                ) {\n                    AutoSizeText(stringResource(R.string.close))\n                }\n            }\n        }\n    }\n\n    if (data != null) {\n        EnhancedModalBottomSheet(\n            sheetContent = sheetContent,\n            visible = visible,\n            onDismiss = {\n                if (!it) onDismiss()\n            },\n            dragHandle = {\n                EnhancedModalSheetDragHandle(\n                    color = Color.Transparent,\n                    drawStroke = false,\n                    heightWhenDisabled = 20.dp\n                )\n            }\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/FancySlider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.hoverable\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SliderColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.animateFloatingRangeAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberRipple\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.materialShadow\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomRangeSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSliderColors\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSliderDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSliderState\n\n@Composable\nfun FancySlider(\n    value: Float,\n    enabled: Boolean,\n    colors: SliderColors,\n    interactionSource: MutableInteractionSource,\n    thumbShape: Shape,\n    modifier: Modifier,\n    onValueChange: (Float) -> Unit,\n    onValueChangeFinished: (() -> Unit)?,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int,\n    drawContainer: Boolean = true\n) {\n    val thumbColor by animateColorAsState(\n        if (enabled) colors.thumbColor else colors.disabledThumbColor\n    )\n    val settingsState = LocalSettingsState.current\n\n    val thumb: @Composable (CustomSliderState) -> Unit = { sliderState ->\n        val sliderFraction by remember(value, sliderState) {\n            derivedStateOf {\n                (value - sliderState.valueRange.start) / (sliderState.valueRange.endInclusive - sliderState.valueRange.start)\n            }\n        }\n        Spacer(\n            Modifier\n                .zIndex(100f)\n                .rotate(1080f * sliderFraction)\n                .size(26.dp)\n                .indication(\n                    interactionSource = interactionSource,\n                    indication = rememberRipple(\n                        bounded = false,\n                        radius = 24.dp\n                    )\n                )\n                .hoverable(interactionSource = interactionSource)\n                .materialShadow(\n                    shape = thumbShape,\n                    elevation = 1.dp,\n                    enabled = settingsState.drawSliderShadows\n                )\n                .background(thumbColor, thumbShape)\n        )\n    }\n\n    LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n        CustomSlider(\n            interactionSource = interactionSource,\n            thumb = thumb,\n            enabled = enabled,\n            modifier = modifier\n                .then(\n                    if (drawContainer) {\n                        Modifier\n                            .container(\n                                shape = ShapeDefaults.circle,\n                                autoShadowElevation = animateDpAsState(\n                                    if (settingsState.drawSliderShadows) {\n                                        1.dp\n                                    } else 0.dp\n                                ).value,\n                                resultPadding = 0.dp,\n                                borderColor = MaterialTheme.colorScheme\n                                    .outlineVariant(\n                                        luminance = 0.1f,\n                                        onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                                    )\n                                    .copy(0.3f),\n                                color = SafeLocalContainerColor\n                                    .copy(0.5f)\n                                    .compositeOver(MaterialTheme.colorScheme.surface)\n                                    .copy(colors.activeTrackColor.alpha),\n                                composeColorOnTopOfBackground = false\n                            )\n                            .padding(horizontal = 6.dp)\n                    } else Modifier\n                ),\n            colors = colors.toCustom(),\n            value = value,\n            onValueChange = onValueChange,\n            onValueChangeFinished = onValueChangeFinished,\n            valueRange = valueRange,\n            steps = steps,\n            track = { sliderState ->\n                CustomSliderDefaults.Track(\n                    sliderState = sliderState,\n                    colors = colors.toCustom(),\n                    trackHeight = 38.dp,\n                    enabled = enabled\n                )\n            }\n        )\n    }\n}\n\n@Composable\nfun FancyRangeSlider(\n    value: ClosedFloatingPointRange<Float>,\n    enabled: Boolean,\n    colors: SliderColors,\n    startInteractionSource: MutableInteractionSource,\n    endInteractionSource: MutableInteractionSource,\n    thumbShape: Shape,\n    modifier: Modifier,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    onValueChangeFinished: (() -> Unit)?,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int,\n    drawContainer: Boolean = true\n) {\n    val thumbColor by animateColorAsState(\n        if (enabled) colors.thumbColor else colors.disabledThumbColor\n    )\n\n\n    val settingsState = LocalSettingsState.current\n    LocalMinimumInteractiveComponentSize.ProvidesValue(Dp.Unspecified) {\n        CustomRangeSlider(\n            startInteractionSource = startInteractionSource,\n            endInteractionSource = endInteractionSource,\n            enabled = enabled,\n            modifier = modifier\n                .then(\n                    if (drawContainer) {\n                        Modifier\n                            .container(\n                                shape = ShapeDefaults.circle,\n                                autoShadowElevation = animateDpAsState(\n                                    if (settingsState.drawSliderShadows) {\n                                        1.dp\n                                    } else 0.dp\n                                ).value,\n                                resultPadding = 0.dp,\n                                borderColor = MaterialTheme.colorScheme\n                                    .outlineVariant(\n                                        luminance = 0.1f,\n                                        onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                                    )\n                                    .copy(0.3f),\n                                color = SafeLocalContainerColor\n                                    .copy(0.5f)\n                                    .compositeOver(MaterialTheme.colorScheme.surface)\n                                    .copy(colors.activeTrackColor.alpha),\n                                composeColorOnTopOfBackground = false\n                            )\n                            .padding(horizontal = 6.dp)\n                    } else Modifier\n                ),\n            colors = colors.toCustom(),\n            value = animateFloatingRangeAsState(value).value,\n            onValueChange = onValueChange,\n            onValueChangeFinished = onValueChangeFinished,\n            valueRange = valueRange,\n            startThumb = {\n                Spacer(\n                    Modifier\n                        .zIndex(100f)\n                        .size(26.dp)\n                        .indication(\n                            interactionSource = startInteractionSource,\n                            indication = rememberRipple(\n                                bounded = false,\n                                radius = 24.dp\n                            )\n                        )\n                        .hoverable(interactionSource = startInteractionSource)\n                        .materialShadow(\n                            shape = thumbShape,\n                            elevation = 1.dp,\n                            enabled = LocalSettingsState.current.drawSliderShadows\n                        )\n                        .background(thumbColor, thumbShape)\n                )\n            },\n            endThumb = {\n                Spacer(\n                    Modifier\n                        .zIndex(100f)\n                        .size(26.dp)\n                        .indication(\n                            interactionSource = endInteractionSource,\n                            indication = rememberRipple(\n                                bounded = false,\n                                radius = 24.dp\n                            )\n                        )\n                        .hoverable(interactionSource = endInteractionSource)\n                        .materialShadow(\n                            shape = thumbShape,\n                            elevation = 1.dp,\n                            enabled = LocalSettingsState.current.drawSliderShadows\n                        )\n                        .background(thumbColor, thumbShape)\n                )\n            },\n            steps = steps,\n            track = { sliderState ->\n                CustomSliderDefaults.Track(\n                    rangeSliderState = sliderState,\n                    colors = colors.toCustom(),\n                    trackHeight = 38.dp,\n                    enabled = enabled\n                )\n            }\n        )\n    }\n}\n\n@Stable\ninternal fun SliderColors.toCustom(): CustomSliderColors = CustomSliderColors(\n    thumbColor = thumbColor,\n    activeTrackColor = activeTrackColor,\n    activeTickColor = activeTickColor,\n    inactiveTrackColor = inactiveTrackColor,\n    inactiveTickColor = inactiveTickColor,\n    disabledThumbColor = disabledThumbColor,\n    disabledActiveTrackColor = disabledActiveTrackColor,\n    disabledActiveTickColor = disabledActiveTickColor,\n    disabledInactiveTrackColor = disabledInactiveTrackColor,\n    disabledInactiveTickColor = disabledInactiveTickColor\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/HyperOSSlider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomRangeSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSliderDefaults\nimport androidx.compose.material3.SliderColors as M3SliderColors\nimport androidx.compose.material3.SliderDefaults as M3Defaults\n\n@Composable\nfun HyperOSSlider(\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    interactionSource: MutableInteractionSource? = null,\n    onValueChangeFinished: (() -> Unit)? = null,\n    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,\n    colors: M3SliderColors = M3Defaults.colors(),\n    steps: Int = 0,\n    drawContainer: Boolean = true\n) {\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    val shape = AutoCircleShape()\n    val settingsState = LocalSettingsState.current\n    val sliderColors = colors.toCustom()\n\n    CustomSlider(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier,\n        enabled = enabled,\n        onValueChangeFinished = onValueChangeFinished,\n        colors = sliderColors,\n        interactionSource = interactionSource,\n        steps = steps,\n        thumb = {},\n        track = { sliderState ->\n            CustomSliderDefaults.Track(\n                colors = sliderColors,\n                enabled = enabled,\n                sliderState = sliderState,\n                trackHeight = 30.dp,\n                modifier = Modifier.then(\n                    if (drawContainer) {\n                        Modifier.container(\n                            shape = shape,\n                            autoShadowElevation = animateDpAsState(\n                                if (settingsState.drawSliderShadows) 1.dp else 0.dp\n                            ).value,\n                            resultPadding = 0.dp,\n                            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                                luminance = 0.1f,\n                                onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                            ).copy(0.3f),\n                            color = SafeLocalContainerColor\n                                .copy(0.3f)\n                                .compositeOver(\n                                    takeColorFromScheme {\n                                        if (it) tertiaryContainer\n                                            .blend(secondaryContainer, 0.5f)\n                                            .copy(0.1f)\n                                        else secondaryContainer\n                                            .blend(tertiaryContainer, 0.3f)\n                                            .copy(0.2f)\n                                    }\n                                )\n                                .copy(sliderColors.activeTrackColor.alpha),\n                            composeColorOnTopOfBackground = false\n                        )\n                    } else Modifier\n                ),\n                strokeCap = StrokeCap.Butt\n            )\n        },\n        valueRange = valueRange\n    )\n}\n\n@Composable\nfun HyperOSRangeSlider(\n    value: ClosedFloatingPointRange<Float>,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    onValueChangeFinished: (() -> Unit)? = null,\n    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,\n    colors: M3SliderColors = M3Defaults.colors(),\n    steps: Int = 0,\n    drawContainer: Boolean = true,\n) {\n    val shape = AutoCircleShape()\n    val settingsState = LocalSettingsState.current\n    val sliderColors = colors.toCustom()\n\n    CustomRangeSlider(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier,\n        enabled = enabled,\n        onValueChangeFinished = onValueChangeFinished,\n        colors = sliderColors,\n        startInteractionSource = startInteractionSource,\n        endInteractionSource = endInteractionSource,\n        steps = steps,\n        startThumb = {},\n        endThumb = {},\n        track = { rangeSliderState ->\n            CustomSliderDefaults.Track(\n                colors = sliderColors,\n                enabled = enabled,\n                rangeSliderState = rangeSliderState,\n                trackHeight = 30.dp,\n                modifier = Modifier.then(\n                    if (drawContainer) {\n                        Modifier.container(\n                            shape = shape,\n                            autoShadowElevation = animateDpAsState(\n                                if (settingsState.drawSliderShadows) 1.dp else 0.dp\n                            ).value,\n                            resultPadding = 0.dp,\n                            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                                luminance = 0.1f,\n                                onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                            ).copy(0.3f),\n                            color = SafeLocalContainerColor\n                                .copy(0.3f)\n                                .compositeOver(\n                                    takeColorFromScheme {\n                                        if (it) tertiaryContainer\n                                            .blend(secondaryContainer, 0.5f)\n                                            .copy(0.1f)\n                                        else secondaryContainer\n                                            .blend(tertiaryContainer, 0.3f)\n                                            .copy(0.2f)\n                                    }\n                                )\n                                .copy(sliderColors.activeTrackColor.alpha),\n                            composeColorOnTopOfBackground = false\n                        )\n                    } else Modifier\n                ),\n                strokeCap = StrokeCap.Butt\n            )\n        },\n        valueRange = valueRange\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/M2Slider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SliderColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.animateFloatingRangeAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomRangeSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider.CustomSliderDefaults\n\n@Composable\nfun M2Slider(\n    value: Float,\n    enabled: Boolean,\n    colors: SliderColors,\n    interactionSource: MutableInteractionSource,\n    modifier: Modifier,\n    onValueChange: (Float) -> Unit,\n    onValueChangeFinished: (() -> Unit)?,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int,\n    drawContainer: Boolean = true\n) {\n    val settingsState = LocalSettingsState.current\n    CustomSlider(\n        interactionSource = interactionSource,\n        enabled = enabled,\n        modifier = modifier\n            .then(\n                if (drawContainer) {\n                    Modifier\n                        .container(\n                            shape = ShapeDefaults.circle,\n                            autoShadowElevation = animateDpAsState(\n                                if (settingsState.drawSliderShadows) {\n                                    1.dp\n                                } else 0.dp\n                            ).value,\n                            resultPadding = 0.dp,\n                            borderColor = MaterialTheme.colorScheme\n                                .outlineVariant(\n                                    luminance = 0.1f,\n                                    onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                                )\n                                .copy(0.3f),\n                            color = SafeLocalContainerColor\n                                .copy(0.3f)\n                                .compositeOver(\n                                    takeColorFromScheme {\n                                        if (it) {\n                                            tertiaryContainer\n                                                .blend(\n                                                    secondaryContainer,\n                                                    0.5f\n                                                )\n                                                .copy(0.1f)\n                                        } else {\n                                            secondaryContainer\n                                                .blend(\n                                                    tertiaryContainer,\n                                                    0.3f\n                                                )\n                                                .copy(0.2f)\n                                        }\n                                    }\n                                )\n                                .copy(colors.activeTrackColor.alpha),\n                            composeColorOnTopOfBackground = false\n                        )\n                        .padding(horizontal = 12.dp)\n                } else Modifier\n            ),\n        value = value,\n        colors = colors.toCustom(),\n        onValueChange = onValueChange,\n        onValueChangeFinished = onValueChangeFinished,\n        valueRange = valueRange,\n        steps = steps,\n        track = {\n            CustomSliderDefaults.Track(\n                sliderState = it,\n                colors = colors.toCustom(),\n                trackHeight = 4.dp,\n                enabled = enabled\n            )\n        }\n    )\n}\n\n@Composable\nfun M2RangeSlider(\n    value: ClosedFloatingPointRange<Float>,\n    enabled: Boolean,\n    colors: SliderColors,\n    startInteractionSource: MutableInteractionSource,\n    endInteractionSource: MutableInteractionSource,\n    modifier: Modifier,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    onValueChangeFinished: (() -> Unit)?,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int,\n    drawContainer: Boolean = true\n) {\n    val settingsState = LocalSettingsState.current\n    CustomRangeSlider(\n        startInteractionSource = startInteractionSource,\n        endInteractionSource = endInteractionSource,\n        enabled = enabled,\n        modifier = modifier\n            .then(\n                if (drawContainer) {\n                    Modifier\n                        .container(\n                            shape = ShapeDefaults.circle,\n                            autoShadowElevation = animateDpAsState(\n                                if (settingsState.drawSliderShadows) {\n                                    1.dp\n                                } else 0.dp\n                            ).value,\n                            resultPadding = 0.dp,\n                            borderColor = MaterialTheme.colorScheme\n                                .outlineVariant(\n                                    luminance = 0.1f,\n                                    onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                                )\n                                .copy(0.3f),\n                            color = SafeLocalContainerColor\n                                .copy(0.3f)\n                                .compositeOver(\n                                    takeColorFromScheme {\n                                        if (it) {\n                                            tertiaryContainer\n                                                .blend(\n                                                    secondaryContainer,\n                                                    0.5f\n                                                )\n                                                .copy(0.1f)\n                                        } else {\n                                            secondaryContainer\n                                                .blend(\n                                                    tertiaryContainer,\n                                                    0.3f\n                                                )\n                                                .copy(0.2f)\n                                        }\n                                    }\n                                )\n                                .copy(colors.activeTrackColor.alpha),\n                            composeColorOnTopOfBackground = false\n                        )\n                        .padding(horizontal = 12.dp)\n                } else Modifier\n            ),\n        value = animateFloatingRangeAsState(value).value,\n        colors = colors.toCustom(),\n        onValueChange = onValueChange,\n        onValueChangeFinished = onValueChangeFinished,\n        valueRange = valueRange,\n        steps = steps,\n        track = {\n            CustomSliderDefaults.Track(\n                rangeSliderState = it,\n                colors = colors.toCustom(),\n                trackHeight = 4.dp,\n                enabled = enabled\n            )\n        }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/M3Slider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.RangeSlider\nimport androidx.compose.material3.Slider\nimport androidx.compose.material3.SliderColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.animateFloatingRangeAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun M3Slider(\n    value: Float,\n    enabled: Boolean,\n    colors: SliderColors,\n    interactionSource: MutableInteractionSource,\n    modifier: Modifier,\n    onValueChange: (Float) -> Unit,\n    onValueChangeFinished: (() -> Unit)?,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int,\n    drawContainer: Boolean = true\n) {\n    val settingsState = LocalSettingsState.current\n    Slider(\n        interactionSource = interactionSource,\n        enabled = enabled,\n        modifier = modifier\n            .then(\n                if (drawContainer) {\n                    Modifier\n                        .padding(vertical = 2.dp)\n                        .container(\n                            shape = ShapeDefaults.small,\n                            autoShadowElevation = animateDpAsState(\n                                if (settingsState.drawSliderShadows) {\n                                    1.dp\n                                } else 0.dp\n                            ).value,\n                            resultPadding = 0.dp,\n                            borderColor = MaterialTheme.colorScheme\n                                .outlineVariant(\n                                    luminance = 0.1f,\n                                    onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                                )\n                                .copy(0.3f),\n                            color = SafeLocalContainerColor\n                                .copy(0.3f)\n                                .compositeOver(\n                                    takeColorFromScheme {\n                                        if (it) {\n                                            tertiaryContainer\n                                                .blend(\n                                                    secondaryContainer,\n                                                    0.5f\n                                                )\n                                                .copy(0.1f)\n                                        } else {\n                                            secondaryContainer\n                                                .blend(\n                                                    tertiaryContainer,\n                                                    0.3f\n                                                )\n                                                .copy(0.2f)\n                                        }\n                                    }\n                                )\n                                .copy(colors.activeTrackColor.alpha),\n                            composeColorOnTopOfBackground = false\n                        )\n                        .padding(horizontal = 12.dp, vertical = 6.dp)\n                } else Modifier\n            ),\n        value = value,\n        colors = colors,\n        onValueChange = onValueChange,\n        onValueChangeFinished = onValueChangeFinished,\n        valueRange = valueRange,\n        steps = steps,\n    )\n}\n\n@Composable\nfun M3RangeSlider(\n    value: ClosedFloatingPointRange<Float>,\n    enabled: Boolean,\n    colors: SliderColors,\n    startInteractionSource: MutableInteractionSource,\n    endInteractionSource: MutableInteractionSource,\n    modifier: Modifier,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    onValueChangeFinished: (() -> Unit)?,\n    valueRange: ClosedFloatingPointRange<Float>,\n    steps: Int,\n    drawContainer: Boolean = true\n) {\n    val settingsState = LocalSettingsState.current\n    RangeSlider(\n        startInteractionSource = startInteractionSource,\n        endInteractionSource = endInteractionSource,\n        enabled = enabled,\n        modifier = modifier\n            .then(\n                if (drawContainer) {\n                    Modifier\n                        .padding(vertical = 2.dp)\n                        .container(\n                            shape = ShapeDefaults.small,\n                            autoShadowElevation = animateDpAsState(\n                                if (settingsState.drawSliderShadows) {\n                                    1.dp\n                                } else 0.dp\n                            ).value,\n                            resultPadding = 0.dp,\n                            borderColor = MaterialTheme.colorScheme\n                                .outlineVariant(\n                                    luminance = 0.1f,\n                                    onTopOf = SwitchDefaults.colors().disabledCheckedTrackColor\n                                )\n                                .copy(0.3f),\n                            color = SafeLocalContainerColor\n                                .copy(0.3f)\n                                .compositeOver(\n                                    takeColorFromScheme {\n                                        if (it) {\n                                            tertiaryContainer\n                                                .blend(\n                                                    secondaryContainer,\n                                                    0.5f\n                                                )\n                                                .copy(0.1f)\n                                        } else {\n                                            secondaryContainer\n                                                .blend(\n                                                    tertiaryContainer,\n                                                    0.3f\n                                                )\n                                                .copy(0.2f)\n                                        }\n                                    }\n                                )\n                                .copy(colors.activeTrackColor.alpha),\n                            composeColorOnTopOfBackground = false\n                        )\n                        .padding(horizontal = 12.dp, vertical = 6.dp)\n                } else Modifier\n            ),\n        value = animateFloatingRangeAsState(value).value,\n        colors = colors,\n        onValueChange = onValueChange,\n        onValueChangeFinished = onValueChangeFinished,\n        valueRange = valueRange,\n        steps = steps,\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomRangeSlider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.annotation.IntRange\nimport androidx.compose.foundation.focusable\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.requiredSizeIn\nimport androidx.compose.foundation.progressSemantics\nimport androidx.compose.material3.minimumInteractiveComponentSize\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.disabled\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.semantics.setProgress\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.offset\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.abs\nimport kotlin.math.roundToInt\n\n/**\n * <a href=\"https://m3.material.io/components/sliders/overview\" class=\"external\" target=\"_blank\">Material Design Range slider</a>.\n *\n * Range Sliders expand upon [CustomSlider] using the same concepts but allow the user to select 2 values.\n *\n * The two values are still bounded by the value range but they also cannot cross each other.\n *\n * Use continuous Range Sliders to allow users to make meaningful selections that don’t\n * require a specific values:\n *\n *\n * You can allow the user to choose only between predefined set of values by specifying the amount\n * of steps between min and max values:\n *\n *\n * @param value current values of the RangeSlider. If either value is outside of [valueRange]\n * provided, it will be coerced to this range.\n * @param onValueChange lambda in which values should be updated\n * @param modifier modifiers for the Range Slider layout\n * @param enabled whether or not component is enabled and can we interacted with or not\n * @param valueRange range of values that Range Slider values can take. Passed [value] will be\n * coerced to this range\n * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed\n * between across the whole value range. If 0, range slider will behave as a continuous slider and\n * allow to choose any value from the range specified. Must not be negative.\n * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback\n * shouldn't be used to update the range slider values (use [onValueChange] for that), but rather to\n * know when the user has completed selecting a new value by ending a drag or a click.\n * @param colors [CustomSliderColors] that will be used to determine the color of the Range Slider\n * parts in different state. See [CustomSliderDefaults.colors] to customize.\n */\n@Composable\nfun CustomRangeSlider(\n    value: ClosedFloatingPointRange<Float>,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,\n    @IntRange(from = 0)\n    steps: Int = 0,\n    onValueChangeFinished: (() -> Unit)? = null,\n    colors: CustomSliderColors = CustomSliderDefaults.colors()\n) {\n    val startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n    val endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n\n    CustomRangeSlider(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier,\n        enabled = enabled,\n        valueRange = valueRange,\n        steps = steps,\n        onValueChangeFinished = onValueChangeFinished,\n        startInteractionSource = startInteractionSource,\n        endInteractionSource = endInteractionSource,\n        startThumb = {\n            CustomSliderDefaults.Thumb(\n                interactionSource = startInteractionSource,\n                colors = colors,\n                enabled = enabled\n            )\n        },\n        endThumb = {\n            CustomSliderDefaults.Thumb(\n                interactionSource = endInteractionSource,\n                colors = colors,\n                enabled = enabled\n            )\n        },\n        track = { rangeSliderState ->\n            CustomSliderDefaults.Track(\n                colors = colors,\n                enabled = enabled,\n                rangeSliderState = rangeSliderState\n            )\n        }\n    )\n}\n\n/**\n * <a href=\"https://m3.material.io/components/sliders/overview\" class=\"external\" target=\"_blank\">Material Design Range slider</a>.\n *\n * Range Sliders expand upon [CustomSlider] using the same concepts but allow the user to select 2 values.\n *\n * The two values are still bounded by the value range but they also cannot cross each other.\n *\n * It uses the provided startThumb for the slider's start thumb and endThumb for the\n * slider's end thumb. It also uses the provided track for the slider's track. If nothing is\n * passed for these parameters, it will use [CustomSliderDefaults.Thumb] and [CustomSliderDefaults.Track]\n * for the thumbs and track.\n *\n * Use continuous Range Sliders to allow users to make meaningful selections that don’t\n * require a specific values:\n *\n *\n * You can allow the user to choose only between predefined set of values by specifying the amount\n * of steps between min and max values:\n *\n * @param value current values of the RangeSlider. If either value is outside of [valueRange]\n * provided, it will be coerced to this range.\n * @param onValueChange lambda in which values should be updated\n * @param modifier modifiers for the Range Slider layout\n * @param enabled whether or not component is enabled and can we interacted with or not\n * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback\n * shouldn't be used to update the range slider values (use [onValueChange] for that), but rather to\n * know when the user has completed selecting a new value by ending a drag or a click.\n * @param colors [CustomSliderColors] that will be used to determine the color of the Range Slider\n * parts in different state. See [CustomSliderDefaults.colors] to customize.\n * @param startInteractionSource the [MutableInteractionSource] representing the stream of\n * [Interaction]s for the start thumb. You can create and pass in your own\n * `remember`ed instance to observe.\n * @param endInteractionSource the [MutableInteractionSource] representing the stream of\n * [Interaction]s for the end thumb. You can create and pass in your own\n * `remember`ed instance to observe.\n * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed\n * between across the whole value range. If 0, range slider will behave as a continuous slider and\n * allow to choose any value from the range specified. Must not be negative.\n * @param startThumb the start thumb to be displayed on the Range Slider. The lambda receives a\n * [CustomRangeSliderState] which is used to obtain the current active track.\n * @param endThumb the end thumb to be displayed on the Range Slider. The lambda receives a\n * [CustomRangeSliderState] which is used to obtain the current active track.\n * @param track the track to be displayed on the range slider, it is placed underneath the thumb.\n * The lambda receives a [CustomRangeSliderState] which is used to obtain the current active track.\n * @param valueRange range of values that Range Slider values can take. Passed [value] will be\n * coerced to this range.\n */\n@Composable\nfun CustomRangeSlider(\n    value: ClosedFloatingPointRange<Float>,\n    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,\n    onValueChangeFinished: (() -> Unit)? = null,\n    colors: CustomSliderColors = CustomSliderDefaults.colors(),\n    startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    startThumb: @Composable (CustomRangeSliderState) -> Unit = {\n        CustomSliderDefaults.Thumb(\n            interactionSource = startInteractionSource,\n            colors = colors,\n            enabled = enabled\n        )\n    },\n    endThumb: @Composable (CustomRangeSliderState) -> Unit = {\n        CustomSliderDefaults.Thumb(\n            interactionSource = endInteractionSource,\n            colors = colors,\n            enabled = enabled\n        )\n    },\n    track: @Composable (CustomRangeSliderState) -> Unit = { rangeSliderState ->\n        CustomSliderDefaults.Track(\n            colors = colors,\n            enabled = enabled,\n            rangeSliderState = rangeSliderState\n        )\n    },\n    @IntRange(from = 0)\n    steps: Int = 0\n) {\n    val state = remember(\n        steps,\n        valueRange,\n        onValueChangeFinished\n    ) {\n        CustomRangeSliderState(\n            value.start,\n            value.endInclusive,\n            steps,\n            onValueChangeFinished,\n            valueRange\n        )\n    }\n\n    state.onValueChange = { onValueChange(it.start..it.endInclusive) }\n    state.activeRangeStart = value.start\n    state.activeRangeEnd = value.endInclusive\n\n    CustomRangeSlider(\n        modifier = modifier,\n        state = state,\n        enabled = enabled,\n        startInteractionSource = startInteractionSource,\n        endInteractionSource = endInteractionSource,\n        startThumb = startThumb,\n        endThumb = endThumb,\n        track = track\n    )\n}\n\n/**\n * <a href=\"https://m3.material.io/components/sliders/overview\" class=\"external\" target=\"_blank\">Material Design Range slider</a>.\n *\n * Range Sliders expand upon [CustomSlider] using the same concepts but allow the user to select 2 values.\n *\n * The two values are still bounded by the value range but they also cannot cross each other.\n *\n * It uses the provided startThumb for the slider's start thumb and endThumb for the\n * slider's end thumb. It also uses the provided track for the slider's track. If nothing is\n * passed for these parameters, it will use [CustomSliderDefaults.Thumb] and [CustomSliderDefaults.Track]\n * for the thumbs and track.\n *\n * Use continuous Range Sliders to allow users to make meaningful selections that don’t\n * require a specific values:\n *\n * You can allow the user to choose only between predefined set of values by specifying the amount\n * of steps between min and max values:\n *\n * A custom start/end thumb and track can be provided:\n *\n * @param state [CustomRangeSliderState] which contains the current values of the RangeSlider.\n * @param modifier modifiers for the Range Slider layout\n * @param enabled whether or not component is enabled and can we interacted with or not\n * @param colors [CustomSliderColors] that will be used to determine the color of the Range Slider\n * parts in different state. See [CustomSliderDefaults.colors] to customize.\n * @param startInteractionSource the [MutableInteractionSource] representing the stream of\n * [Interaction]s for the start thumb. You can create and pass in your own\n * `remember`ed instance to observe.\n * @param endInteractionSource the [MutableInteractionSource] representing the stream of\n * [Interaction]s for the end thumb. You can create and pass in your own\n * `remember`ed instance to observe.\n * @param startThumb the start thumb to be displayed on the Range Slider. The lambda receives a\n * [CustomRangeSliderState] which is used to obtain the current active track.\n * @param endThumb the end thumb to be displayed on the Range Slider. The lambda receives a\n * [CustomRangeSliderState] which is used to obtain the current active track.\n * @param track the track to be displayed on the range slider, it is placed underneath the thumb.\n * The lambda receives a [CustomRangeSliderState] which is used to obtain the current active track.\n */\n@Composable\nfun CustomRangeSlider(\n    state: CustomRangeSliderState,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: CustomSliderColors = CustomSliderDefaults.colors(),\n    startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    startThumb: @Composable (CustomRangeSliderState) -> Unit = {\n        CustomSliderDefaults.Thumb(\n            interactionSource = startInteractionSource,\n            colors = colors,\n            enabled = enabled\n        )\n    },\n    endThumb: @Composable (CustomRangeSliderState) -> Unit = {\n        CustomSliderDefaults.Thumb(\n            interactionSource = endInteractionSource,\n            colors = colors,\n            enabled = enabled\n        )\n    },\n    track: @Composable (CustomRangeSliderState) -> Unit = { rangeSliderState ->\n        CustomSliderDefaults.Track(\n            colors = colors,\n            enabled = enabled,\n            rangeSliderState = rangeSliderState\n        )\n    }\n) {\n    require(state.steps >= 0) { \"steps should be >= 0\" }\n\n    CustomRangeSliderImpl(\n        modifier = modifier,\n        state = state,\n        enabled = enabled,\n        startInteractionSource = startInteractionSource,\n        endInteractionSource = endInteractionSource,\n        startThumb = startThumb,\n        endThumb = endThumb,\n        track = track\n    )\n}\n\n@Composable\nprivate fun CustomRangeSliderImpl(\n    modifier: Modifier,\n    state: CustomRangeSliderState,\n    enabled: Boolean,\n    startInteractionSource: MutableInteractionSource,\n    endInteractionSource: MutableInteractionSource,\n    startThumb: @Composable ((CustomRangeSliderState) -> Unit),\n    endThumb: @Composable ((CustomRangeSliderState) -> Unit),\n    track: @Composable ((CustomRangeSliderState) -> Unit)\n) {\n    state.isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n\n    val pressDrag = Modifier.rangeSliderPressDragModifier(\n        state,\n        startInteractionSource,\n        endInteractionSource,\n        enabled\n    )\n\n    val startThumbSemantics = Modifier.rangeSliderStartThumbSemantics(state, enabled)\n    val endThumbSemantics = Modifier.rangeSliderEndThumbSemantics(state, enabled)\n\n    Layout(\n        {\n            Box(\n                modifier = Modifier\n                    .layoutId(RangeSliderComponents.START_THUMB)\n                    .focusable(enabled, startInteractionSource)\n                    .then(startThumbSemantics)\n            ) { startThumb(state) }\n            Box(\n                modifier = Modifier\n                    .layoutId(RangeSliderComponents.END_THUMB)\n                    .focusable(enabled, endInteractionSource)\n                    .then(endThumbSemantics)\n            ) { endThumb(state) }\n            Box(modifier = Modifier.layoutId(RangeSliderComponents.TRACK)) {\n                track(state)\n            }\n        },\n        modifier = modifier\n            .minimumInteractiveComponentSize()\n            .requiredSizeIn(\n                minWidth = 20.dp,\n                minHeight = 20.dp\n            )\n            .then(pressDrag)\n    ) { measurables, constraints ->\n        val startThumbPlaceable = measurables.fastFirst {\n            it.layoutId == RangeSliderComponents.START_THUMB\n        }.measure(\n            constraints\n        )\n\n        val endThumbPlaceable = measurables.fastFirst {\n            it.layoutId == RangeSliderComponents.END_THUMB\n        }.measure(\n            constraints\n        )\n\n        val trackPlaceable = measurables.fastFirst {\n            it.layoutId == RangeSliderComponents.TRACK\n        }.measure(\n            constraints.offset(\n                horizontal = -(startThumbPlaceable.width + endThumbPlaceable.width) / 2\n            ).copy(minHeight = 0)\n        )\n\n        val sliderWidth = trackPlaceable.width +\n                (startThumbPlaceable.width + endThumbPlaceable.width) / 2\n        val sliderHeight = maxOf(\n            trackPlaceable.height,\n            startThumbPlaceable.height,\n            endThumbPlaceable.height\n        )\n\n        state.startThumbWidth = startThumbPlaceable.width.toFloat()\n        state.endThumbWidth = endThumbPlaceable.width.toFloat()\n        state.totalWidth = sliderWidth\n\n        state.updateMinMaxPx()\n\n        val trackOffsetX = startThumbPlaceable.width / 2\n        val startThumbOffsetX = (trackPlaceable.width * state.coercedActiveRangeStartAsFraction)\n            .roundToInt()\n        // When start thumb and end thumb have different widths,\n        // we need to add a correction for the centering of the slider.\n        val endCorrection = (startThumbPlaceable.width - endThumbPlaceable.width) / 2\n        val endThumbOffsetX =\n            (trackPlaceable.width * state.coercedActiveRangeEndAsFraction + endCorrection)\n                .roundToInt()\n        val trackOffsetY = (sliderHeight - trackPlaceable.height) / 2\n        val startThumbOffsetY = (sliderHeight - startThumbPlaceable.height) / 2\n        val endThumbOffsetY = (sliderHeight - endThumbPlaceable.height) / 2\n\n        layout(\n            sliderWidth,\n            sliderHeight\n        ) {\n            trackPlaceable.placeRelative(\n                trackOffsetX,\n                trackOffsetY\n            )\n            startThumbPlaceable.placeRelative(\n                startThumbOffsetX,\n                startThumbOffsetY\n            )\n            endThumbPlaceable.placeRelative(\n                endThumbOffsetX,\n                endThumbOffsetY\n            )\n        }\n    }\n}\n\nprivate fun Modifier.rangeSliderStartThumbSemantics(\n    state: CustomRangeSliderState,\n    enabled: Boolean\n): Modifier {\n    val valueRange = state.valueRange.start..state.activeRangeEnd\n\n    return semantics {\n\n        if (!enabled) disabled()\n        setProgress(\n            action = { targetValue ->\n                var newValue = targetValue.coerceIn(\n                    valueRange.start,\n                    valueRange.endInclusive\n                )\n                val originalVal = newValue\n                val resolvedValue = if (state.startSteps > 0) {\n                    var distance: Float = newValue\n                    for (i in 0..state.startSteps + 1) {\n                        val stepValue = lerp(\n                            valueRange.start,\n                            valueRange.endInclusive,\n                            i.toFloat() / (state.startSteps + 1)\n                        )\n                        if (abs(stepValue - originalVal) <= distance) {\n                            distance = abs(stepValue - originalVal)\n                            newValue = stepValue\n                        }\n                    }\n                    newValue\n                } else {\n                    newValue\n                }\n\n                // This is to keep it consistent with AbsSeekbar.java: return false if no\n                // change from current.\n                if (resolvedValue == state.activeRangeStart) {\n                    false\n                } else {\n                    val resolvedRange = CustomSliderRange(resolvedValue, state.activeRangeEnd)\n                    val activeRange =\n                        CustomSliderRange(state.activeRangeStart, state.activeRangeEnd)\n                    if (resolvedRange != activeRange) {\n                        if (state.onValueChange != null) {\n                            state.onValueChange?.let { it(resolvedRange) }\n                        } else {\n                            state.activeRangeStart = resolvedRange.start\n                            state.activeRangeEnd = resolvedRange.endInclusive\n                        }\n                    }\n                    state.onValueChangeFinished?.invoke()\n                    true\n                }\n            }\n        )\n    }.progressSemantics(\n        state.activeRangeStart,\n        valueRange,\n        state.startSteps\n    )\n}\n\nprivate fun Modifier.rangeSliderEndThumbSemantics(\n    state: CustomRangeSliderState,\n    enabled: Boolean\n): Modifier {\n    val valueRange = state.activeRangeStart..state.valueRange.endInclusive\n\n    return semantics {\n        if (!enabled) disabled()\n\n        setProgress(\n            action = { targetValue ->\n                var newValue = targetValue.coerceIn(valueRange.start, valueRange.endInclusive)\n                val originalVal = newValue\n                val resolvedValue = if (state.endSteps > 0) {\n                    var distance: Float = newValue\n                    for (i in 0..state.endSteps + 1) {\n                        val stepValue = lerp(\n                            valueRange.start,\n                            valueRange.endInclusive,\n                            i.toFloat() / (state.endSteps + 1)\n                        )\n                        if (abs(stepValue - originalVal) <= distance) {\n                            distance = abs(stepValue - originalVal)\n                            newValue = stepValue\n                        }\n                    }\n                    newValue\n                } else {\n                    newValue\n                }\n\n                // This is to keep it consistent with AbsSeekbar.java: return false if no\n                // change from current.\n                if (resolvedValue == state.activeRangeEnd) {\n                    false\n                } else {\n                    val resolvedRange = CustomSliderRange(state.activeRangeStart, resolvedValue)\n                    val activeRange =\n                        CustomSliderRange(state.activeRangeStart, state.activeRangeEnd)\n                    if (resolvedRange != activeRange) {\n                        if (state.onValueChange != null) {\n                            state.onValueChange?.let { it(resolvedRange) }\n                        } else {\n                            state.activeRangeStart = resolvedRange.start\n                            state.activeRangeEnd = resolvedRange.endInclusive\n                        }\n                    }\n                    state.onValueChangeFinished?.invoke()\n                    true\n                }\n            }\n        )\n    }.progressSemantics(\n        state.activeRangeEnd,\n        valueRange,\n        state.endSteps\n    )\n}\n\nprivate enum class RangeSliderComponents {\n    END_THUMB,\n    START_THUMB,\n    TRACK\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomRangeSliderState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.annotation.IntRange\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport kotlin.math.floor\nimport kotlin.math.max\nimport kotlin.math.min\n\n/**\n * Class that holds information about [CustomRangeSlider]'s active range.\n *\n * @param activeRangeStart [Float] that indicates the initial\n * start of the active range of the slider. If outside of [valueRange]\n * provided, value will be coerced to this range.\n * @param activeRangeEnd [Float] that indicates the initial\n * end of the active range of the slider. If outside of [valueRange]\n * provided, value will be coerced to this range.\n * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed\n * between across the whole value range. If 0, range slider will behave as a continuous slider and\n * allow to choose any value from the range specified. Must not be negative.\n * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback\n * shouldn't be used to update the range slider values (use [onValueChange] for that), but rather\n * to know when the user has completed selecting a new value by ending a drag or a click.\n * @param valueRange range of values that Range Slider values can take. [activeRangeStart]\n * and [activeRangeEnd] will be coerced to this range.\n */\n@Stable\nclass CustomRangeSliderState(\n    activeRangeStart: Float = 0f,\n    activeRangeEnd: Float = 1f,\n    @IntRange(from = 0)\n    val steps: Int = 0,\n    val onValueChangeFinished: (() -> Unit)? = null,\n    val valueRange: ClosedFloatingPointRange<Float> = 0f..1f\n) {\n    private var activeRangeStartState by mutableFloatStateOf(activeRangeStart)\n    private var activeRangeEndState by mutableFloatStateOf(activeRangeEnd)\n\n    /**\n     * [Float] that indicates the start of the current active range for the [CustomRangeSlider].\n     */\n    var activeRangeStart: Float\n        set(newVal) {\n            val coercedValue = newVal.coerceIn(valueRange.start, activeRangeEnd)\n            val snappedValue = snapValueToTick(\n                coercedValue,\n                tickFractions,\n                valueRange.start,\n                valueRange.endInclusive\n            )\n            activeRangeStartState = snappedValue\n        }\n        get() = activeRangeStartState\n\n    /**\n     * [Float] that indicates the end of the current active range for the [CustomRangeSlider].\n     */\n    var activeRangeEnd: Float\n        set(newVal) {\n            val coercedValue = newVal.coerceIn(activeRangeStart, valueRange.endInclusive)\n            val snappedValue = snapValueToTick(\n                coercedValue,\n                tickFractions,\n                valueRange.start,\n                valueRange.endInclusive\n            )\n            activeRangeEndState = snappedValue\n        }\n        get() = activeRangeEndState\n\n    internal var onValueChange: ((CustomSliderRange) -> Unit)? = null\n\n    internal val tickFractions = stepsToTickFractions(steps)\n\n    internal var startThumbWidth by mutableFloatStateOf(0f)\n    internal var endThumbWidth by mutableFloatStateOf(0f)\n    internal var totalWidth by mutableIntStateOf(0)\n    internal var rawOffsetStart by mutableFloatStateOf(0f)\n    internal var rawOffsetEnd by mutableFloatStateOf(0f)\n\n    internal var isRtl by mutableStateOf(false)\n\n    internal val gestureEndAction: (Boolean) -> Unit = {\n        onValueChangeFinished?.invoke()\n    }\n\n    private var maxPx by mutableFloatStateOf(0f)\n    private var minPx by mutableFloatStateOf(0f)\n\n    internal fun onDrag(\n        isStart: Boolean,\n        offset: Float\n    ) {\n        val offsetRange = if (isStart) {\n            rawOffsetStart = (rawOffsetStart + offset)\n            rawOffsetEnd = scaleToOffset(minPx, maxPx, activeRangeEnd)\n            val offsetEnd = rawOffsetEnd\n            var offsetStart = rawOffsetStart.coerceIn(minPx, offsetEnd)\n            offsetStart = snapValueToTick(offsetStart, tickFractions, minPx, maxPx)\n            CustomSliderRange(offsetStart, offsetEnd)\n        } else {\n            rawOffsetEnd = (rawOffsetEnd + offset)\n            rawOffsetStart = scaleToOffset(minPx, maxPx, activeRangeStart)\n            val offsetStart = rawOffsetStart\n            var offsetEnd = rawOffsetEnd.coerceIn(offsetStart, maxPx)\n            offsetEnd = snapValueToTick(offsetEnd, tickFractions, minPx, maxPx)\n            CustomSliderRange(offsetStart, offsetEnd)\n        }\n        val scaledUserValue = scaleToUserValue(minPx, maxPx, offsetRange)\n        if (scaledUserValue != CustomSliderRange(activeRangeStart, activeRangeEnd)) {\n            if (onValueChange != null) {\n                onValueChange?.let { it(scaledUserValue) }\n            } else {\n                this.activeRangeStart = scaledUserValue.start\n                this.activeRangeEnd = scaledUserValue.endInclusive\n            }\n        }\n    }\n\n    internal val coercedActiveRangeStartAsFraction\n        get() = calcFraction(\n            valueRange.start,\n            valueRange.endInclusive,\n            activeRangeStart\n        )\n\n    internal val coercedActiveRangeEndAsFraction\n        get() = calcFraction(\n            valueRange.start,\n            valueRange.endInclusive,\n            activeRangeEnd\n        )\n\n    internal val startSteps\n        get() = floor(steps * coercedActiveRangeEndAsFraction).toInt()\n\n    internal val endSteps\n        get() = floor(steps * (1f - coercedActiveRangeStartAsFraction)).toInt()\n\n    // scales range offset from within minPx..maxPx to within valueRange.start..valueRange.end\n    private fun scaleToUserValue(\n        minPx: Float,\n        maxPx: Float,\n        offset: CustomSliderRange\n    ) = scale(minPx, maxPx, offset, valueRange.start, valueRange.endInclusive)\n\n    // scales float userValue within valueRange.start..valueRange.end to within minPx..maxPx\n    private fun scaleToOffset(\n        minPx: Float,\n        maxPx: Float,\n        userValue: Float\n    ) =\n        scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)\n\n    internal fun updateMinMaxPx() {\n        val newMaxPx = max(totalWidth - endThumbWidth / 2, 0f)\n        val newMinPx = min(startThumbWidth / 2, newMaxPx)\n        if (minPx != newMinPx || maxPx != newMaxPx) {\n            minPx = newMinPx\n            maxPx = newMaxPx\n            rawOffsetStart = scaleToOffset(\n                minPx,\n                maxPx,\n                activeRangeStart\n            )\n            rawOffsetEnd = scaleToOffset(\n                minPx,\n                maxPx,\n                activeRangeEnd\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomRangeSliderUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.gestures.horizontalDrag\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerId\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.PointerType\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.input.pointer.positionChange\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.launch\nimport kotlin.math.abs\n\n@Stable\ninternal fun Modifier.rangeSliderPressDragModifier(\n    state: CustomRangeSliderState,\n    startInteractionSource: MutableInteractionSource,\n    endInteractionSource: MutableInteractionSource,\n    enabled: Boolean\n): Modifier = if (enabled) {\n    pointerInput(startInteractionSource, endInteractionSource, state) {\n        val rangeSliderLogic = RangeSliderLogic(\n            state,\n            startInteractionSource,\n            endInteractionSource\n        )\n        coroutineScope {\n            awaitEachGesture {\n                val event = awaitFirstDown(requireUnconsumed = false)\n                val interaction = DragInteraction.Start()\n                var posX = if (state.isRtl)\n                    state.totalWidth - event.position.x else event.position.x\n                val compare = rangeSliderLogic.compareOffsets(posX)\n                var draggingStart = if (compare != 0) {\n                    compare < 0\n                } else {\n                    state.rawOffsetStart > posX\n                }\n\n                awaitSlop(event.id, event.type)?.let {\n                    val slop = viewConfiguration.pointerSlop(event.type)\n                    val shouldUpdateCapturedThumb = abs(state.rawOffsetEnd - posX) < slop &&\n                            abs(state.rawOffsetStart - posX) < slop\n                    if (shouldUpdateCapturedThumb) {\n                        val dir = it.second\n                        draggingStart = if (state.isRtl) dir >= 0f else dir < 0f\n                        posX += it.first.positionChange().x\n                    }\n                }\n\n                rangeSliderLogic.captureThumb(\n                    draggingStart,\n                    posX,\n                    interaction,\n                    this@coroutineScope\n                )\n\n                val finishInteraction = try {\n                    val success = horizontalDrag(pointerId = event.id) {\n                        val deltaX = it.positionChange().x\n                        state.onDrag(draggingStart, if (state.isRtl) -deltaX else deltaX)\n                    }\n                    if (success) {\n                        DragInteraction.Stop(interaction)\n                    } else {\n                        DragInteraction.Cancel(interaction)\n                    }\n                } catch (_: CancellationException) {\n                    DragInteraction.Cancel(interaction)\n                }\n\n                state.gestureEndAction(draggingStart)\n                launch {\n                    rangeSliderLogic\n                        .activeInteraction(draggingStart)\n                        .emit(finishInteraction)\n                }\n            }\n        }\n    }\n} else {\n    this\n}\n\ninternal suspend fun AwaitPointerEventScope.awaitSlop(\n    id: PointerId,\n    type: PointerType\n): Pair<PointerInputChange, Float>? {\n    var initialDelta = 0f\n    val postPointerSlop = { pointerInput: PointerInputChange, offset: Float ->\n        pointerInput.consume()\n        initialDelta = offset\n    }\n    val afterSlopResult = awaitHorizontalPointerSlopOrCancellation(id, type, postPointerSlop)\n    return if (afterSlopResult != null) afterSlopResult to initialDelta else null\n}\n\ninternal class RangeSliderLogic(\n    val state: CustomRangeSliderState,\n    val startInteractionSource: MutableInteractionSource,\n    val endInteractionSource: MutableInteractionSource\n) {\n    fun activeInteraction(draggingStart: Boolean): MutableInteractionSource =\n        if (draggingStart) startInteractionSource else endInteractionSource\n\n    fun compareOffsets(eventX: Float): Int {\n        val diffStart = abs(state.rawOffsetStart - eventX)\n        val diffEnd = abs(state.rawOffsetEnd - eventX)\n        return diffStart.compareTo(diffEnd)\n    }\n\n    fun captureThumb(\n        draggingStart: Boolean,\n        posX: Float,\n        interaction: Interaction,\n        scope: CoroutineScope\n    ) {\n        state.onDrag(\n            draggingStart,\n            posX - if (draggingStart) state.rawOffsetStart else state.rawOffsetEnd\n        )\n        scope.launch {\n            activeInteraction(draggingStart).emit(interaction)\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomSlider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"SameParameterValue\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.annotation.IntRange\nimport androidx.compose.foundation.focusable\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.gestures.draggable\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.requiredSizeIn\nimport androidx.compose.foundation.progressSemantics\nimport androidx.compose.material3.minimumInteractiveComponentSize\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.disabled\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.semantics.setProgress\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.offset\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.abs\nimport kotlin.math.max\nimport kotlin.math.roundToInt\n\n\n/**\n * <a href=\"https://m3.material.io/components/sliders/overview\" class=\"external\" target=\"_blank\">Material Design slider</a>.\n *\n * Sliders allow users to make selections from a range of values.\n *\n * It uses [CustomSliderDefaults.Thumb] and [CustomSliderDefaults.Track] as the thumb and track.\n *\n * Sliders reflect a range of values along a bar, from which users may select a single value.\n * They are ideal for adjusting settings such as volume, brightness, or applying image filters.\n *\n * ![Sliders image](https://developer.android.com/images/reference/androidx/compose/material3/sliders.png)\n *\n * Use continuous sliders to allow users to make meaningful selections that don’t\n * require a specific value:\n *\n * You can allow the user to choose only between predefined set of values by specifying the amount\n * of steps between min and max values:\n *\n * @param value current value of the slider. If outside of [valueRange] provided, value will be\n * coerced to this range.\n * @param onValueChange callback in which value should be updated\n * @param modifier the [Modifier] to be applied to this slider\n * @param enabled controls the enabled state of this slider. When `false`, this component will not\n * respond to user input, and it will appear visually disabled and disabled to accessibility\n * services.\n * @param valueRange range of values that this slider can take. The passed [value] will be coerced\n * to this range.\n * @param steps if greater than 0, specifies the amount of discrete allowable values, evenly\n * distributed across the whole value range. If 0, the slider will behave continuously and allow any\n * value from the range specified. Must not be negative.\n * @param onValueChangeFinished called when value change has ended. This should not be used to\n * update the slider value (use [onValueChange] instead), but rather to know when the user has\n * completed selecting a new value by ending a drag or a click.\n * @param colors [CustomSliderColors] that will be used to resolve the colors used for this slider in\n * different states. See [CustomSliderDefaults.colors].\n * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s\n * for this slider. You can create and pass in your own `remember`ed instance to observe\n * [Interaction]s and customize the appearance / behavior of this slider in different states.\n */\n@Composable\nfun CustomSlider(\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,\n    @IntRange(from = 0)\n    steps: Int = 0,\n    onValueChangeFinished: (() -> Unit)? = null,\n    colors: CustomSliderColors = CustomSliderDefaults.colors(),\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n) {\n    CustomSlider(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier,\n        enabled = enabled,\n        onValueChangeFinished = onValueChangeFinished,\n        colors = colors,\n        interactionSource = interactionSource,\n        steps = steps,\n        thumb = {\n            CustomSliderDefaults.Thumb(\n                interactionSource = interactionSource,\n                colors = colors,\n                enabled = enabled\n            )\n        },\n        track = { sliderState ->\n            CustomSliderDefaults.Track(\n                colors = colors,\n                enabled = enabled,\n                sliderState = sliderState\n            )\n        },\n        valueRange = valueRange\n    )\n}\n\n/**\n * <a href=\"https://m3.material.io/components/sliders/overview\" class=\"external\" target=\"_blank\">Material Design slider</a>.\n *\n * Sliders allow users to make selections from a range of values.\n *\n * Sliders reflect a range of values along a bar, from which users may select a single value.\n * They are ideal for adjusting settings such as volume, brightness, or applying image filters.\n *\n * ![Sliders image](https://developer.android.com/images/reference/androidx/compose/material3/sliders.png)\n *\n * Use continuous sliders to allow users to make meaningful selections that don’t\n * require a specific value:\n *\n * You can allow the user to choose only between predefined set of values by specifying the amount\n * of steps between min and max values:\n *\n * @param value current value of the slider. If outside of [valueRange] provided, value will be\n * coerced to this range.\n * @param onValueChange callback in which value should be updated\n * @param modifier the [Modifier] to be applied to this slider\n * @param enabled controls the enabled state of this slider. When `false`, this component will not\n * respond to user input, and it will appear visually disabled and disabled to accessibility\n * services.\n * @param onValueChangeFinished called when value change has ended. This should not be used to\n * update the slider value (use [onValueChange] instead), but rather to know when the user has\n * completed selecting a new value by ending a drag or a click.\n * @param colors [CustomSliderColors] that will be used to resolve the colors used for this slider in\n * different states. See [CustomSliderDefaults.colors].\n * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s\n * for this slider. You can create and pass in your own `remember`ed instance to observe\n * [Interaction]s and customize the appearance / behavior of this slider in different states.\n * @param steps if greater than 0, specifies the amount of discrete allowable values, evenly\n * distributed across the whole value range. If 0, the slider will behave continuously and allow any\n * value from the range specified. Must not be negative.\n * @param thumb the thumb to be displayed on the slider, it is placed on top of the track. The\n * lambda receives a [CustomSliderState] which is used to obtain the current active track.\n * @param track the track to be displayed on the slider, it is placed underneath the thumb. The\n * lambda receives a [CustomSliderState] which is used to obtain the current active track.\n * @param valueRange range of values that this slider can take. The passed [value] will be coerced\n * to this range.\n */\n@Composable\nfun CustomSlider(\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    onValueChangeFinished: (() -> Unit)? = null,\n    colors: CustomSliderColors = CustomSliderDefaults.colors(),\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    @IntRange(from = 0)\n    steps: Int = 0,\n    thumb: @Composable (CustomSliderState) -> Unit = {\n        CustomSliderDefaults.Thumb(\n            interactionSource = interactionSource,\n            colors = colors,\n            enabled = enabled\n        )\n    },\n    track: @Composable (CustomSliderState) -> Unit = { sliderState ->\n        CustomSliderDefaults.Track(\n            colors = colors,\n            enabled = enabled,\n            sliderState = sliderState\n        )\n    },\n    valueRange: ClosedFloatingPointRange<Float> = 0f..1f\n) {\n    val state = remember(\n        steps,\n        valueRange\n    ) {\n        CustomSliderState(\n            value,\n            steps,\n            valueRange\n        )\n    }\n\n    state.onValueChangeFinished = onValueChangeFinished\n    state.onValueChange = onValueChange\n    state.value = value\n\n    CustomSlider(\n        state = state,\n        modifier = modifier,\n        enabled = enabled,\n        interactionSource = interactionSource,\n        thumb = thumb,\n        track = track\n    )\n}\n\n/**\n * <a href=\"https://m3.material.io/components/sliders/overview\" class=\"external\" target=\"_blank\">Material Design slider</a>.\n *\n * Sliders allow users to make selections from a range of values.\n *\n * Sliders reflect a range of values along a bar, from which users may select a single value.\n * They are ideal for adjusting settings such as volume, brightness, or applying image filters.\n *\n * ![Sliders image](https://developer.android.com/images/reference/androidx/compose/material3/sliders.png)\n *\n * Use continuous sliders to allow users to make meaningful selections that don’t\n * require a specific value:\n *\n *\n * You can allow the user to choose only between predefined set of values by specifying the amount\n * of steps between min and max values:\n *\n *\n * @param state [CustomSliderState] which contains the slider's current value.\n * @param modifier the [Modifier] to be applied to this slider\n * @param enabled controls the enabled state of this slider. When `false`, this component will not\n * respond to user input, and it will appear visually disabled and disabled to accessibility\n * services.\n * @param colors [CustomSliderColors] that will be used to resolve the colors used for this slider in\n * different states. See [CustomSliderDefaults.colors].\n * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s\n * for this slider. You can create and pass in your own `remember`ed instance to observe\n * [Interaction]s and customize the appearance / behavior of this slider in different states.\n * @param thumb the thumb to be displayed on the slider, it is placed on top of the track. The\n * lambda receives a [CustomSliderState] which is used to obtain the current active track.\n * @param track the track to be displayed on the slider, it is placed underneath the thumb. The\n * lambda receives a [CustomSliderState] which is used to obtain the current active track.\n */\n@Composable\nfun CustomSlider(\n    state: CustomSliderState,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: CustomSliderColors = CustomSliderDefaults.colors(),\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    thumb: @Composable (CustomSliderState) -> Unit = {\n        CustomSliderDefaults.Thumb(\n            interactionSource = interactionSource,\n            colors = colors,\n            enabled = enabled\n        )\n    },\n    track: @Composable (CustomSliderState) -> Unit = { sliderState ->\n        CustomSliderDefaults.Track(\n            colors = colors,\n            enabled = enabled,\n            sliderState = sliderState\n        )\n    }\n) {\n    require(state.steps >= 0) { \"steps should be >= 0\" }\n\n    CustomSliderImpl(\n        state = state,\n        modifier = modifier,\n        enabled = enabled,\n        interactionSource = interactionSource,\n        thumb = thumb,\n        track = track\n    )\n}\n\n\n@Composable\nprivate fun CustomSliderImpl(\n    modifier: Modifier,\n    state: CustomSliderState,\n    enabled: Boolean,\n    interactionSource: MutableInteractionSource,\n    thumb: @Composable (CustomSliderState) -> Unit,\n    track: @Composable (CustomSliderState) -> Unit\n) {\n    state.isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n    val press = Modifier.sliderTapModifier(\n        state,\n        interactionSource,\n        enabled\n    )\n    val drag = Modifier.draggable(\n        orientation = Orientation.Horizontal,\n        reverseDirection = state.isRtl,\n        enabled = enabled,\n        interactionSource = interactionSource,\n        onDragStopped = { state.gestureEndAction() },\n        startDragImmediately = state.isDragging,\n        state = state\n    )\n\n    Layout(\n        {\n            Box(modifier = Modifier.layoutId(SliderComponents.THUMB)) {\n                thumb(state)\n            }\n            Box(modifier = Modifier.layoutId(SliderComponents.TRACK)) {\n                track(state)\n            }\n        },\n        modifier = modifier\n            .minimumInteractiveComponentSize()\n            .requiredSizeIn(\n                minWidth = 20.dp,\n                minHeight = 20.dp\n            )\n            .sliderSemantics(\n                state,\n                enabled\n            )\n            .focusable(enabled, interactionSource)\n            .then(press)\n            .then(drag)\n    ) { measurables, constraints ->\n\n        val thumbPlaceable = measurables.fastFirst {\n            it.layoutId == SliderComponents.THUMB\n        }.measure(constraints)\n\n        val trackPlaceable = measurables.fastFirst {\n            it.layoutId == SliderComponents.TRACK\n        }.measure(\n            constraints.offset(\n                horizontal = -thumbPlaceable.width\n            ).copy(minHeight = 0)\n        )\n\n        val sliderWidth = thumbPlaceable.width + trackPlaceable.width\n        val sliderHeight = max(trackPlaceable.height, thumbPlaceable.height)\n\n        state.updateDimensions(\n            thumbPlaceable.width.toFloat(),\n            sliderWidth\n        )\n\n        val trackOffsetX = thumbPlaceable.width / 2\n        val thumbOffsetX = ((trackPlaceable.width) * state.coercedValueAsFraction).roundToInt()\n        val trackOffsetY = (sliderHeight - trackPlaceable.height) / 2\n        val thumbOffsetY = (sliderHeight - thumbPlaceable.height) / 2\n\n        layout(sliderWidth, sliderHeight) {\n            trackPlaceable.placeRelative(\n                trackOffsetX,\n                trackOffsetY\n            )\n            thumbPlaceable.placeRelative(\n                thumbOffsetX,\n                thumbOffsetY\n            )\n        }\n    }\n}\n\nprivate fun Modifier.sliderSemantics(\n    state: CustomSliderState,\n    enabled: Boolean\n): Modifier {\n    return semantics {\n        if (!enabled) disabled()\n        setProgress(\n            action = { targetValue ->\n                var newValue = targetValue.coerceIn(\n                    state.valueRange.start,\n                    state.valueRange.endInclusive\n                )\n                val originalVal = newValue\n                val resolvedValue = if (state.steps > 0) {\n                    var distance: Float = newValue\n                    for (i in 0..state.steps + 1) {\n                        val stepValue = lerp(\n                            state.valueRange.start,\n                            state.valueRange.endInclusive,\n                            i.toFloat() / (state.steps + 1)\n                        )\n                        if (abs(stepValue - originalVal) <= distance) {\n                            distance = abs(stepValue - originalVal)\n                            newValue = stepValue\n                        }\n                    }\n                    newValue\n                } else {\n                    newValue\n                }\n\n                // This is to keep it consistent with AbsSeekbar.java: return false if no\n                // change from current.\n                if (resolvedValue == state.value) {\n                    false\n                } else {\n                    if (resolvedValue != state.value) {\n                        if (state.onValueChange != null) {\n                            state.onValueChange?.let {\n                                it(resolvedValue)\n                            }\n                        } else {\n                            state.value = resolvedValue\n                        }\n                    }\n                    state.onValueChangeFinished?.invoke()\n                    true\n                }\n            }\n        )\n    }.progressSemantics(\n        state.value,\n        state.valueRange.start..state.valueRange.endInclusive,\n        state.steps\n    )\n}\n\n\n@Stable\nprivate fun Modifier.sliderTapModifier(\n    state: CustomSliderState,\n    interactionSource: MutableInteractionSource,\n    enabled: Boolean\n) = if (enabled) {\n    pointerInput(state, interactionSource) {\n        detectTapGestures(\n            onPress = { state.onPress(it) },\n            onTap = {\n                state.dispatchRawDelta(0f)\n                state.gestureEndAction()\n            }\n        )\n    }\n} else {\n    this\n}\n\nprivate enum class SliderComponents {\n    THUMB,\n    TRACK\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomSliderColors.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.takeOrElse\n\n@Immutable\nclass CustomSliderColors(\n    val thumbColor: Color,\n    val activeTrackColor: Color,\n    val activeTickColor: Color,\n    val inactiveTrackColor: Color,\n    val inactiveTickColor: Color,\n    val disabledThumbColor: Color,\n    val disabledActiveTrackColor: Color,\n    val disabledActiveTickColor: Color,\n    val disabledInactiveTrackColor: Color,\n    val disabledInactiveTickColor: Color\n) {\n\n    /**\n     * Returns a copy of this SelectableChipColors, optionally overriding some of the values.\n     * This uses the Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        thumbColor: Color = this.thumbColor,\n        activeTrackColor: Color = this.activeTrackColor,\n        activeTickColor: Color = this.activeTickColor,\n        inactiveTrackColor: Color = this.inactiveTrackColor,\n        inactiveTickColor: Color = this.inactiveTickColor,\n        disabledThumbColor: Color = this.disabledThumbColor,\n        disabledActiveTrackColor: Color = this.disabledActiveTrackColor,\n        disabledActiveTickColor: Color = this.disabledActiveTickColor,\n        disabledInactiveTrackColor: Color = this.disabledInactiveTrackColor,\n        disabledInactiveTickColor: Color = this.disabledInactiveTickColor,\n    ) = CustomSliderColors(\n        thumbColor.takeOrElse { this.thumbColor },\n        activeTrackColor.takeOrElse { this.activeTrackColor },\n        activeTickColor.takeOrElse { this.activeTickColor },\n        inactiveTrackColor.takeOrElse { this.inactiveTrackColor },\n        inactiveTickColor.takeOrElse { this.inactiveTickColor },\n        disabledThumbColor.takeOrElse { this.disabledThumbColor },\n        disabledActiveTrackColor.takeOrElse { this.disabledActiveTrackColor },\n        disabledActiveTickColor.takeOrElse { this.disabledActiveTickColor },\n        disabledInactiveTrackColor.takeOrElse { this.disabledInactiveTrackColor },\n        disabledInactiveTickColor.takeOrElse { this.disabledInactiveTickColor },\n    )\n\n    @Stable\n    internal fun thumbColor(enabled: Boolean): Color =\n        if (enabled) thumbColor else disabledThumbColor\n\n    @Stable\n    internal fun trackColor(\n        enabled: Boolean,\n        active: Boolean\n    ): Color =\n        if (enabled) {\n            if (active) activeTrackColor else inactiveTrackColor\n        } else {\n            if (active) disabledActiveTrackColor else disabledInactiveTrackColor\n        }\n\n    @Stable\n    internal fun tickColor(\n        enabled: Boolean,\n        active: Boolean\n    ): Color =\n        if (enabled) {\n            if (active) activeTickColor else inactiveTickColor\n        } else {\n            if (active) disabledActiveTickColor else disabledInactiveTickColor\n        }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is CustomSliderColors) return false\n\n        if (thumbColor != other.thumbColor) return false\n        if (activeTrackColor != other.activeTrackColor) return false\n        if (activeTickColor != other.activeTickColor) return false\n        if (inactiveTrackColor != other.inactiveTrackColor) return false\n        if (inactiveTickColor != other.inactiveTickColor) return false\n        if (disabledThumbColor != other.disabledThumbColor) return false\n        if (disabledActiveTrackColor != other.disabledActiveTrackColor) return false\n        if (disabledActiveTickColor != other.disabledActiveTickColor) return false\n        if (disabledInactiveTrackColor != other.disabledInactiveTrackColor) return false\n        return disabledInactiveTickColor == other.disabledInactiveTickColor\n    }\n\n    override fun hashCode(): Int {\n        var result = thumbColor.hashCode()\n        result = 31 * result + activeTrackColor.hashCode()\n        result = 31 * result + activeTickColor.hashCode()\n        result = 31 * result + inactiveTrackColor.hashCode()\n        result = 31 * result + inactiveTickColor.hashCode()\n        result = 31 * result + disabledThumbColor.hashCode()\n        result = 31 * result + disabledActiveTrackColor.hashCode()\n        result = 31 * result + disabledActiveTickColor.hashCode()\n        result = 31 * result + disabledInactiveTrackColor.hashCode()\n        result = 31 * result + disabledInactiveTickColor.hashCode()\n        return result\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomSliderDefaults.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.hoverable\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.lerp\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberRipple\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.materialShadow\n\n/**\n * Object to hold defaults used by [CustomSlider]\n */\n@Stable\nobject CustomSliderDefaults {\n\n    /**\n     * Creates a [CustomSliderColors] that represents the different colors used in parts of the\n     * [CustomSlider] in different states.\n     */\n    @Composable\n    fun colors() = colors(\n        activeTickColor = MaterialTheme.colorScheme.inverseSurface,\n        inactiveTickColor = MaterialTheme.colorScheme.surface,\n        activeTrackColor = MaterialTheme.colorScheme.primaryContainer,\n        inactiveTrackColor = SwitchDefaults.colors().disabledCheckedTrackColor,\n        disabledThumbColor = SwitchDefaults.colors().disabledCheckedThumbColor,\n        thumbColor = MaterialTheme.colorScheme.onPrimaryContainer\n    )\n\n    /**\n     * Creates a [CustomSliderColors] that represents the different colors used in parts of the\n     * [CustomSlider] in different states.\n     *\n     * For the name references below the words \"active\" and \"inactive\" are used. Active part of\n     * the slider is filled with progress, so if slider's progress is 30% out of 100%, left (or\n     * right in RTL) 30% of the track will be active, while the rest is inactive.\n     *\n     * @param thumbColor thumb color when enabled\n     * @param activeTrackColor color of the track in the part that is \"active\", meaning that the\n     * thumb is ahead of it\n     * @param activeTickColor colors to be used to draw tick marks on the active track, if `steps`\n     * is specified\n     * @param inactiveTrackColor color of the track in the part that is \"inactive\", meaning that the\n     * thumb is before it\n     * @param inactiveTickColor colors to be used to draw tick marks on the inactive track, if\n     * `steps` are specified on the Slider is specified\n     * @param disabledThumbColor thumb colors when disabled\n     * @param disabledActiveTrackColor color of the track in the \"active\" part when the Slider is\n     * disabled\n     * @param disabledActiveTickColor colors to be used to draw tick marks on the active track\n     * when Slider is disabled and when `steps` are specified on it\n     * @param disabledInactiveTrackColor color of the track in the \"inactive\" part when the\n     * Slider is disabled\n     * @param disabledInactiveTickColor colors to be used to draw tick marks on the inactive part\n     * of the track when Slider is disabled and when `steps` are specified on it\n     */\n    @Composable\n    fun colors(\n        thumbColor: Color = Color.Unspecified,\n        activeTrackColor: Color = Color.Unspecified,\n        activeTickColor: Color = Color.Unspecified,\n        inactiveTrackColor: Color = Color.Unspecified,\n        inactiveTickColor: Color = Color.Unspecified,\n        disabledThumbColor: Color = Color.Unspecified,\n        disabledActiveTrackColor: Color = Color.Unspecified,\n        disabledActiveTickColor: Color = Color.Unspecified,\n        disabledInactiveTrackColor: Color = Color.Unspecified,\n        disabledInactiveTickColor: Color = Color.Unspecified\n    ): CustomSliderColors = CustomSliderColors(\n        thumbColor = thumbColor,\n        activeTrackColor = activeTrackColor,\n        activeTickColor = activeTickColor,\n        inactiveTrackColor = inactiveTrackColor,\n        inactiveTickColor = inactiveTickColor,\n        disabledThumbColor = disabledThumbColor,\n        disabledActiveTrackColor = disabledActiveTrackColor,\n        disabledActiveTickColor = disabledActiveTickColor,\n        disabledInactiveTrackColor = disabledInactiveTrackColor,\n        disabledInactiveTickColor = disabledInactiveTickColor\n    )\n\n\n    /**\n     * The Default thumb for [CustomSlider] and [CustomRangeSlider]\n     *\n     * @param interactionSource the [MutableInteractionSource] representing the stream of\n     * [Interaction]s for this thumb. You can create and pass in your own `remember`ed\n     * instance to observe\n     * @param modifier the [Modifier] to be applied to the thumb.\n     * @param colors [CustomSliderColors] that will be used to resolve the colors used for this thumb in\n     * different states. See [CustomSliderDefaults.colors].\n     * @param enabled controls the enabled state of this slider. When `false`, this component will\n     * not respond to user input, and it will appear visually disabled and disabled to\n     * accessibility services.\n     */\n    @Composable\n    fun Thumb(\n        interactionSource: MutableInteractionSource,\n        modifier: Modifier = Modifier,\n        colors: CustomSliderColors = colors(),\n        enabled: Boolean = true,\n        thumbSize: DpSize = ThumbSize\n    ) {\n        val interactions = remember { mutableStateListOf<Interaction>() }\n        LaunchedEffect(interactionSource) {\n            interactionSource.interactions.collect { interaction ->\n                when (interaction) {\n                    is PressInteraction.Press -> interactions.add(interaction)\n                    is PressInteraction.Release -> interactions.remove(interaction.press)\n                    is PressInteraction.Cancel -> interactions.remove(interaction.press)\n                    is DragInteraction.Start -> interactions.add(interaction)\n                    is DragInteraction.Stop -> interactions.remove(interaction.start)\n                    is DragInteraction.Cancel -> interactions.remove(interaction.start)\n                }\n            }\n        }\n\n        val elevation = if (interactions.isNotEmpty()) {\n            ThumbPressedElevation\n        } else {\n            ThumbDefaultElevation\n        }\n        val shape = ShapeDefaults.circle\n\n        Spacer(\n            modifier\n                .size(thumbSize)\n                .indication(\n                    interactionSource = interactionSource,\n                    indication = rememberRipple(\n                        bounded = false,\n                        radius = 40.dp / 2\n                    )\n                )\n                .hoverable(interactionSource = interactionSource)\n                .materialShadow(\n                    shape = shape,\n                    elevation = if (enabled) elevation else 0.dp,\n                    isClipped = false\n                )\n                .background(colors.thumbColor(enabled), shape)\n        )\n    }\n\n    /**\n     * The Default track for [CustomSlider]\n     *\n     * @param sliderState [CustomSliderState] which is used to obtain the current active track.\n     * @param modifier the [Modifier] to be applied to the track.\n     * @param colors [CustomSliderColors] that will be used to resolve the colors used for this track in\n     * different states. See [CustomSliderDefaults.colors].\n     * @param enabled controls the enabled state of this slider. When `false`, this component will\n     * not respond to user input, and it will appear visually disabled and disabled to\n     * accessibility services.\n     */\n    @Composable\n    fun Track(\n        sliderState: CustomSliderState,\n        modifier: Modifier = Modifier,\n        colors: CustomSliderColors = colors(),\n        enabled: Boolean = true,\n        trackHeight: Dp = 32.dp,\n        strokeCap: StrokeCap = StrokeCap.Round\n    ) {\n        val inactiveTrackColor = colors.trackColor(enabled, active = false)\n        val activeTrackColor = colors.trackColor(enabled, active = true)\n        val inactiveTickColor = colors.tickColor(enabled, active = false)\n        val activeTickColor = colors.tickColor(enabled, active = true)\n        Canvas(\n            modifier\n                .fillMaxWidth()\n                .height(trackHeight)\n        ) {\n            drawTrack(\n                sliderState.tickFractions,\n                0f,\n                sliderState.coercedValueAsFraction,\n                inactiveTrackColor,\n                activeTrackColor,\n                inactiveTickColor,\n                activeTickColor,\n                trackHeight.toPx(),\n                strokeCap\n            )\n        }\n    }\n\n    /**\n     * The Default track for [CustomRangeSlider]\n     *\n     * @param rangeSliderState [CustomRangeSliderState] which is used to obtain the current active track.\n     * @param modifier the [Modifier] to be applied to the track.\n     * @param colors [CustomSliderColors] that will be used to resolve the colors used for this track in\n     * different states. See [CustomSliderDefaults.colors].\n     * @param enabled controls the enabled state of this slider. When `false`, this component will\n     * not respond to user input, and it will appear visually disabled and disabled to\n     * accessibility services.\n     */\n    @Composable\n    fun Track(\n        rangeSliderState: CustomRangeSliderState,\n        modifier: Modifier = Modifier,\n        colors: CustomSliderColors = colors(),\n        enabled: Boolean = true,\n        trackHeight: Dp = 32.dp,\n        strokeCap: StrokeCap = StrokeCap.Round\n    ) {\n        val inactiveTrackColor = colors.trackColor(enabled, active = false)\n        val activeTrackColor = colors.trackColor(enabled, active = true)\n        val inactiveTickColor = colors.tickColor(enabled, active = false)\n        val activeTickColor = colors.tickColor(enabled, active = true)\n        Canvas(\n            modifier\n                .fillMaxWidth()\n                .height(trackHeight)\n        ) {\n            drawTrack(\n                rangeSliderState.tickFractions,\n                rangeSliderState.coercedActiveRangeStartAsFraction,\n                rangeSliderState.coercedActiveRangeEndAsFraction,\n                inactiveTrackColor,\n                activeTrackColor,\n                inactiveTickColor,\n                activeTickColor,\n                trackHeight.toPx(),\n                strokeCap\n            )\n        }\n    }\n\n    private fun DrawScope.drawTrack(\n        tickFractions: FloatArray,\n        activeRangeStart: Float,\n        activeRangeEnd: Float,\n        inactiveTrackColor: Color,\n        activeTrackColor: Color,\n        inactiveTickColor: Color,\n        activeTickColor: Color,\n        trackHeight: Float,\n        strokeCap: StrokeCap\n    ) {\n        val isRtl = layoutDirection == LayoutDirection.Rtl\n        val sliderLeft = Offset(0f, center.y)\n        val sliderRight = Offset(size.width, center.y)\n        val sliderStart = if (isRtl) sliderRight else sliderLeft\n        val sliderEnd = if (isRtl) sliderLeft else sliderRight\n        val tickSize = TickSize.toPx()\n        drawLine(\n            inactiveTrackColor,\n            sliderStart,\n            sliderEnd,\n            trackHeight,\n            strokeCap\n        )\n        val sliderValueEnd = Offset(\n            sliderStart.x +\n                    (sliderEnd.x - sliderStart.x) * activeRangeEnd,\n            center.y\n        )\n\n        val sliderValueStart = Offset(\n            sliderStart.x +\n                    (sliderEnd.x - sliderStart.x) * activeRangeStart,\n            center.y\n        )\n\n        drawLine(\n            activeTrackColor,\n            sliderValueStart,\n            sliderValueEnd,\n            trackHeight,\n            strokeCap\n        )\n\n        for (tick in tickFractions) {\n            val outsideFraction = tick > activeRangeEnd || tick < activeRangeStart\n            drawCircle(\n                color = if (outsideFraction) inactiveTickColor else activeTickColor,\n                center = Offset(lerp(sliderStart, sliderEnd, tick).x, center.y),\n                radius = tickSize / 2f\n            )\n        }\n    }\n\n    private val ThumbWidth = 20.dp\n    private val ThumbHeight = 20.dp\n    private val ThumbSize = DpSize(ThumbWidth, ThumbHeight)\n    private val ThumbDefaultElevation = 1.dp\n    private val ThumbPressedElevation = 6.dp\n    private val TickSize = 2.dp\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomSliderRange.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.util.packFloats\nimport androidx.compose.ui.util.unpackFloat1\nimport androidx.compose.ui.util.unpackFloat2\n\n/**\n * Immutable float range for [CustomRangeSlider]\n *\n * Used in [CustomRangeSlider] to determine the active track range for the component.\n * The range is as follows: SliderRange.start..SliderRange.endInclusive.\n */\n@Immutable\n@JvmInline\ninternal value class CustomSliderRange(\n    val packedValue: Long\n) {\n    /**\n     * start of the [CustomSliderRange]\n     */\n    @Stable\n    val start: Float\n        get() {\n            // Explicitly compare against packed values to avoid auto-boxing of Size.Unspecified\n            check(this.packedValue != Unspecified.packedValue) {\n                \"SliderRange is unspecified\"\n            }\n            return unpackFloat1(packedValue)\n        }\n\n    /**\n     * End (inclusive) of the [CustomSliderRange]\n     */\n    @Stable\n    val endInclusive: Float\n        get() {\n            // Explicitly compare against packed values to avoid auto-boxing of Size.Unspecified\n            check(this.packedValue != Unspecified.packedValue) {\n                \"SliderRange is unspecified\"\n            }\n            return unpackFloat2(packedValue)\n        }\n\n    companion object {\n        /**\n         * Represents an unspecified [CustomSliderRange] value, usually a replacement for `null`\n         * when a primitive value is desired.\n         */\n        @Stable\n        val Unspecified = CustomSliderRange(Float.NaN, Float.NaN)\n    }\n\n    /**\n     * String representation of the [CustomSliderRange]\n     */\n    override fun toString() = if (isSpecified) {\n        \"$start..$endInclusive\"\n    } else {\n        \"FloatRange.Unspecified\"\n    }\n}\n\n/**\n * Creates a [CustomSliderRange] from a given start and endInclusive float.\n * It requires endInclusive to be >= start.\n *\n * @param start float that indicates the start of the range\n * @param endInclusive float that indicates the end of the range\n */\n@Stable\ninternal fun CustomSliderRange(\n    start: Float,\n    endInclusive: Float\n): CustomSliderRange {\n    val isUnspecified = start.isNaN() && endInclusive.isNaN()\n    require(isUnspecified || start <= endInclusive) {\n        \"start($start) must be <= endInclusive($endInclusive)\"\n    }\n    return CustomSliderRange(packFloats(start, endInclusive))\n}\n\n/**\n * Creates a [CustomSliderRange] from a given [ClosedFloatingPointRange].\n * It requires range.endInclusive >= range.start.\n *\n * @param range the ClosedFloatingPointRange<Float> for the range.\n */\n@Stable\ninternal fun CustomSliderRange(range: ClosedFloatingPointRange<Float>): CustomSliderRange {\n    val start = range.start\n    val endInclusive = range.endInclusive\n    val isUnspecified = start.isNaN() && endInclusive.isNaN()\n    require(isUnspecified || start <= endInclusive) {\n        \"ClosedFloatingPointRange<Float>.start($start) must be <= \" +\n                \"ClosedFloatingPoint.endInclusive($endInclusive)\"\n    }\n    return CustomSliderRange(packFloats(start, endInclusive))\n}\n\n/**\n * Check for if a given [CustomSliderRange] is not [CustomSliderRange.Unspecified].\n */\n@Stable\ninternal val CustomSliderRange.isSpecified: Boolean\n    get() =\n        packedValue != CustomSliderRange.Unspecified.packedValue"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomSliderState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"SameParameterValue\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.annotation.IntRange\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.MutatorMutex\nimport androidx.compose.foundation.gestures.DragScope\nimport androidx.compose.foundation.gestures.DraggableState\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport kotlinx.coroutines.coroutineScope\nimport kotlin.math.max\nimport kotlin.math.min\n\n/**\n * Class that holds information about [CustomSlider]'s active range.\n *\n * @param value [Float] that indicates the initial\n * position of the thumb. If outside of [valueRange]\n * provided, value will be coerced to this range.\n * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed\n * between across the whole value range. If 0, range slider will behave as a continuous slider and\n * allow to choose any value from the range specified. Must not be negative.\n * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback\n * shouldn't be used to update the range slider values (use [onValueChange] for that),\n * but rather to know when the user has completed selecting a new value by ending a drag or a click.\n * @param valueRange range of values that Slider values can take. [value] will be\n * coerced to this range.\n */\n@Stable\nclass CustomSliderState(\n    value: Float = 0f,\n    @IntRange(from = 0)\n    val steps: Int = 0,\n    val valueRange: ClosedFloatingPointRange<Float> = 0f..1f\n) : DraggableState {\n\n    private var valueState by mutableFloatStateOf(value)\n\n    /**\n     * [Float] that indicates the current value that the thumb\n     * currently is in respect to the track.\n     */\n    var value: Float\n        set(newVal) {\n            val coercedValue = newVal.coerceIn(valueRange.start, valueRange.endInclusive)\n            val snappedValue = snapValueToTick(\n                coercedValue,\n                tickFractions,\n                valueRange.start,\n                valueRange.endInclusive\n            )\n            valueState = snappedValue\n        }\n        get() = valueState\n\n    override suspend fun drag(\n        dragPriority: MutatePriority,\n        block: suspend DragScope.() -> Unit\n    ): Unit = coroutineScope {\n        isDragging = true\n        scrollMutex.mutateWith(dragScope, dragPriority, block)\n        isDragging = false\n    }\n\n    override fun dispatchRawDelta(delta: Float) {\n        val maxPx = max(totalWidth - thumbWidth / 2, 0f)\n        val minPx = min(thumbWidth / 2, maxPx)\n        rawOffset = (rawOffset + delta + pressOffset)\n        pressOffset = 0f\n        val offsetInTrack = snapValueToTick(rawOffset, tickFractions, minPx, maxPx)\n        val scaledUserValue = scaleToUserValue(minPx, maxPx, offsetInTrack)\n        if (scaledUserValue != this.value) {\n            if (onValueChange != null) {\n                onValueChange?.let { it(scaledUserValue) }\n            } else {\n                this.value = scaledUserValue\n            }\n        }\n    }\n\n    var onValueChangeFinished: (() -> Unit)? = null\n\n    /**\n     * callback in which value should be updated\n     */\n    internal var onValueChange: ((Float) -> Unit)? = null\n\n    internal val tickFractions = stepsToTickFractions(steps)\n    private var totalWidth by mutableIntStateOf(0)\n    internal var isRtl = false\n    private var thumbWidth by mutableFloatStateOf(0f)\n\n    internal val coercedValueAsFraction\n        get() = calcFraction(\n            valueRange.start,\n            valueRange.endInclusive,\n            value.coerceIn(valueRange.start, valueRange.endInclusive)\n        )\n\n    internal var isDragging by mutableStateOf(false)\n        private set\n\n    internal fun updateDimensions(\n        newThumbWidth: Float,\n        newTotalWidth: Int\n    ) {\n        thumbWidth = newThumbWidth\n        totalWidth = newTotalWidth\n    }\n\n    internal val gestureEndAction = {\n        if (!isDragging) {\n            // check isDragging in case the change is still in progress (touch -> drag case)\n            onValueChangeFinished?.invoke()\n        }\n    }\n\n    internal fun onPress(pos: Offset) {\n        val to = if (isRtl) totalWidth - pos.x else pos.x\n        pressOffset = to - rawOffset\n    }\n\n    private var rawOffset by mutableFloatStateOf(scaleToOffset(0f, 0f, value))\n    private var pressOffset by mutableFloatStateOf(0f)\n    private val dragScope: DragScope = object : DragScope {\n        override fun dragBy(pixels: Float): Unit = dispatchRawDelta(pixels)\n    }\n\n    private val scrollMutex = MutatorMutex()\n\n    private fun scaleToUserValue(\n        minPx: Float,\n        maxPx: Float,\n        offset: Float\n    ) = scale(minPx, maxPx, offset, valueRange.start, valueRange.endInclusive)\n\n    private fun scaleToOffset(\n        minPx: Float,\n        maxPx: Float,\n        userValue: Float\n    ) = scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/sliders/custom_slider/CustomSliderUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sliders.custom_slider\n\nimport androidx.compose.foundation.gestures.awaitTouchSlopOrCancellation\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEvent\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerId\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.PointerType\nimport androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed\nimport androidx.compose.ui.platform.ViewConfiguration\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFirstOrNull\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.abs\nimport kotlin.math.sign\n\n// Calculate the 0..1 fraction that `pos` value represents between `a` and `b`\ninternal fun calcFraction(\n    a: Float,\n    b: Float,\n    pos: Float\n) =\n    (if (b - a == 0f) 0f else (pos - a) / (b - a)).coerceIn(0f, 1f)\n\n// Scale x1 from a1..b1 range to a2..b2 range\ninternal fun scale(\n    a1: Float,\n    b1: Float,\n    x1: Float,\n    a2: Float,\n    b2: Float\n) =\n    lerp(a2, b2, calcFraction(a1, b1, x1))\n\n// Scale x.start, x.endInclusive from a1..b1 range to a2..b2 range\ninternal fun scale(\n    a1: Float,\n    b1: Float,\n    x: CustomSliderRange,\n    a2: Float,\n    b2: Float\n) = CustomSliderRange(\n    scale(a1 = a1, b1 = b1, x1 = x.start, a2 = a2, b2 = b2),\n    scale(a1, b1, x.endInclusive, a2, b2)\n)\n\nprivate val mouseSlop = 0.125.dp\nprivate val defaultTouchSlop = 18.dp // The default touch slop on Android devices\nprivate val mouseToTouchSlopRatio = mouseSlop / defaultTouchSlop\n\ninternal fun ViewConfiguration.pointerSlop(pointerType: PointerType): Float {\n    return when (pointerType) {\n        PointerType.Mouse -> touchSlop * mouseToTouchSlopRatio\n        else -> touchSlop\n    }\n}\n\n// Copy-paste version of DragGestureDetector.kt. Please don't change this file without changing\n// DragGestureDetector.kt\n\ninternal suspend fun AwaitPointerEventScope.awaitHorizontalPointerSlopOrCancellation(\n    pointerId: PointerId,\n    pointerType: PointerType,\n    onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit\n) = awaitPointerSlopOrCancellation(\n    pointerId = pointerId,\n    pointerType = pointerType,\n    onPointerSlopReached = onPointerSlopReached,\n    getDragDirectionValue = { it.x }\n)\n\n/**\n * Waits for drag motion along one axis based on [getDragDirectionValue] to pass pointer slop,\n * using [pointerId] as the pointer to examine. If [pointerId] is raised, another pointer\n * from those that are down will be chosen to lead the gesture, and if none are down,\n * `null` is returned. If [pointerId] is not down when [awaitPointerSlopOrCancellation] is called,\n * then `null` is returned.\n *\n * When pointer slop is detected, [onPointerSlopReached] is called with the change and the distance\n * beyond the pointer slop. [getDragDirectionValue] should return the position change in the\n * direction of the drag axis. If [onPointerSlopReached] does not consume the position change,\n * pointer slop will not have been considered detected and the detection will continue or,\n * if it is consumed, the [PointerInputChange] that was consumed will be returned.\n *\n * This works with [awaitTouchSlopOrCancellation] for the other axis to ensure that only horizontal\n * or vertical dragging is done, but not both.\n *\n * @return The [PointerInputChange] of the event that was consumed in [onPointerSlopReached] or\n * `null` if all pointers are raised or the position change was consumed by another gesture\n * detector.\n */\nprivate suspend inline fun AwaitPointerEventScope.awaitPointerSlopOrCancellation(\n    pointerId: PointerId,\n    pointerType: PointerType,\n    onPointerSlopReached: (PointerInputChange, Float) -> Unit,\n    getDragDirectionValue: (Offset) -> Float\n): PointerInputChange? {\n    if (currentEvent.isPointerUp(pointerId)) {\n        return null // The pointer has already been lifted, so the gesture is canceled\n    }\n    val touchSlop = viewConfiguration.pointerSlop(pointerType)\n    var pointer: PointerId = pointerId\n    var totalPositionChange = 0f\n\n    while (true) {\n        val event = awaitPointerEvent()\n        val dragEvent = event.changes.fastFirstOrNull { it.id == pointer }!!\n        if (dragEvent.isConsumed) {\n            return null\n        } else if (dragEvent.changedToUpIgnoreConsumed()) {\n            val otherDown = event.changes.fastFirstOrNull { it.pressed }\n            if (otherDown == null) {\n                // This is the last \"up\"\n                return null\n            } else {\n                pointer = otherDown.id\n            }\n        } else {\n            val currentPosition = dragEvent.position\n            val previousPosition = dragEvent.previousPosition\n            val positionChange = getDragDirectionValue(currentPosition) -\n                    getDragDirectionValue(previousPosition)\n            totalPositionChange += positionChange\n\n            val inDirection = abs(totalPositionChange)\n            if (inDirection < touchSlop) {\n                // verify that nothing else consumed the drag event\n                awaitPointerEvent(PointerEventPass.Final)\n                if (dragEvent.isConsumed) {\n                    return null\n                }\n            } else {\n                onPointerSlopReached(\n                    dragEvent,\n                    totalPositionChange - (sign(totalPositionChange) * touchSlop)\n                )\n                if (dragEvent.isConsumed) {\n                    return dragEvent\n                } else {\n                    totalPositionChange = 0f\n                }\n            }\n        }\n    }\n}\n\nprivate fun PointerEvent.isPointerUp(pointerId: PointerId): Boolean =\n    changes.fastFirstOrNull { it.id == pointerId }?.pressed != true\n\ninternal fun snapValueToTick(\n    current: Float,\n    tickFractions: FloatArray,\n    minPx: Float,\n    maxPx: Float\n): Float {\n    // target is a closest anchor to the `current`, if exists\n    return tickFractions\n        .minByOrNull { abs(lerp(minPx, maxPx, it) - current) }\n        ?.run { lerp(minPx, maxPx, this) }\n        ?: current\n}\n\ninternal fun stepsToTickFractions(steps: Int): FloatArray {\n    return if (steps == 0) floatArrayOf() else FloatArray(steps + 2) { it.toFloat() / (steps + 1) }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/switches/CupertinoSwitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"KDocUnresolvedReference\")\n\npackage com.t8rin.imagetoolbox.core.ui.widget.switches\n\nimport android.os.Build\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.draggable\nimport androidx.compose.foundation.gestures.rememberDraggableState\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.foundation.selection.toggleable\nimport androidx.compose.foundation.shape.CornerBasedShape\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.ReadOnlyComposable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.BiasAlignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.kyant.backdrop.backdrops.rememberCanvasBackdrop\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n/**\n * Cupertino Design Switch.\n *\n * Switches toggle the state of a single item on or off.\n *\n * @param checked whether or not this switch is checked\n * @param onCheckedChange called when this switch is clicked. If `null`, then this switch will not\n * be intractable, unless something else handles its input events and updates its state.\n * @param modifier the [Modifier] to be applied to this switch\n * @param enabled controls the enabled state of this switch. When `false`, this component will not\n * respond to user input, and it will appear visually disabled and disabled to accessibility\n * services.\n * @param colors [CupertinoSwitchColors] that will be used to resolve the colors used for this switch in\n * different states. See [CupertinoSwitchDefaults.colors].\n * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s\n * for this switch. You can create and pass in your own `remember`ed instance to observe\n * [Interaction]s and customize the appearance / behavior of this switch in different states.\n */\n@Composable\nfun CupertinoSwitch(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    colors: CupertinoSwitchColors = CupertinoSwitchDefaults.colors(),\n    enabled: Boolean = true,\n    interactionSource: MutableInteractionSource? = null\n) {\n    val realInteractionSource = interactionSource ?: remember { MutableInteractionSource() }\n\n    val isPressed by realInteractionSource.collectIsPressedAsState()\n    val isDragged by realInteractionSource.collectIsDraggedAsState()\n\n    val animatedAspectRatio by animateFloatAsState(\n        targetValue = if (isPressed || isDragged) 1.25f else 1f,\n        animationSpec = AspectRationAnimationSpec\n    )\n    val animatedBackground by animateColorAsState(\n        targetValue = colors.trackColor(enabled, checked).value,\n        animationSpec = ColorAnimationSpec\n    )\n\n    var alignment by remember(checked) {\n        mutableFloatStateOf(\n            if (checked) 1f else -1f\n        )\n    }\n\n    val state = rememberDraggableState {\n        alignment = (alignment + it).coerceIn(-1f, 1f)\n    }\n\n    val animatedAlignment by animateFloatAsState(\n        targetValue = alignment,\n        animationSpec = AlignmentAnimationSpec\n    )\n\n    Column(\n        modifier\n            .toggleable(\n                value = checked,\n                onValueChange = {\n                    onCheckedChange?.invoke(it)\n                },\n                enabled = enabled,\n                role = Role.Switch,\n                interactionSource = realInteractionSource,\n                indication = null\n            )\n            .draggable(\n                state = state,\n                orientation = Orientation.Horizontal,\n                interactionSource = realInteractionSource,\n                enabled = enabled,\n                onDragStopped = {\n                    if (alignment < 1 / 2f) {\n                        alignment = -1f\n                        if (checked) onCheckedChange?.invoke(false)\n                    } else {\n                        alignment = 1f\n                        if (!checked) onCheckedChange?.invoke(true)\n                    }\n                }\n            )\n            .wrapContentSize(Alignment.Center)\n            .requiredSize(CupertinoSwitchDefaults.Width, CupertinoSwitchDefaults.height)\n            .clip(CupertinoSwitchDefaults.Shape)\n            .background(animatedBackground)\n            .padding(2.dp),\n    ) {\n        Box(\n            Modifier\n                .fillMaxHeight()\n                .aspectRatio(animatedAspectRatio)\n                .align(BiasAlignment.Horizontal(animatedAlignment))\n                .container(\n                    shape = CupertinoSwitchDefaults.Shape,\n                    resultPadding = 0.dp,\n                    autoShadowElevation = animateDpAsState(\n                        if (enabled && LocalSettingsState.current.drawSwitchShadows) {\n                            CupertinoSwitchDefaults.EnabledThumbElevation\n                        } else 0.dp\n                    ).value,\n                    borderColor = Color.Transparent,\n                    isShadowClip = true,\n                    isStandaloneContainer = false,\n                    color = colors.thumbColor(enabled).value\n                )\n        )\n    }\n}\n\n@Composable\nfun LiquidGlassSwitch(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    internalModifier: Modifier = Modifier,\n    colors: CupertinoSwitchColors = CupertinoSwitchDefaults.colors(),\n    enabled: Boolean = true,\n    interactionSource: MutableInteractionSource? = null,\n    backgroundColor: Color\n) {\n    val realInteractionSource = interactionSource ?: remember { MutableInteractionSource() }\n\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n        Box(\n            contentAlignment = Alignment.Center\n        ) {\n            FallbackLiquidGlassSwitch(\n                checked = checked,\n                enabled = false,\n                onCheckedChange = null,\n                modifier = internalModifier,\n                colors = CupertinoSwitchDefaults.transparentColors(),\n                interactionSource = realInteractionSource\n            )\n\n            LiquidToggle(\n                checked = { checked },\n                onCheckedChange = onCheckedChange,\n                backdrop = rememberCanvasBackdrop { drawRect(backgroundColor) },\n                enabled = enabled,\n                colors = colors,\n                interactionSource = realInteractionSource,\n                modifier = modifier,\n            )\n        }\n    } else {\n        FallbackLiquidGlassSwitch(\n            checked = checked,\n            onCheckedChange = onCheckedChange,\n            modifier = internalModifier,\n            colors = colors,\n            enabled = enabled,\n            interactionSource = realInteractionSource\n        )\n    }\n}\n\n@Composable\nprivate fun FallbackLiquidGlassSwitch(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    colors: CupertinoSwitchColors = CupertinoSwitchDefaults.colors(),\n    enabled: Boolean = true,\n    interactionSource: MutableInteractionSource\n) {\n    val isPressed by interactionSource.collectIsPressedAsState()\n    val isDragged by interactionSource.collectIsDraggedAsState()\n\n    val animatedAspectRatio by animateFloatAsState(\n        targetValue = if (isPressed || isDragged) 1.8f else 1.6f,\n        animationSpec = AspectRationAnimationSpec\n    )\n    val animatedBackground by animateColorAsState(\n        targetValue = colors.trackColor(enabled, checked).value,\n        animationSpec = ColorAnimationSpec\n    )\n\n    var alignment by remember(checked) {\n        mutableFloatStateOf(\n            if (checked) 1f else -1f\n        )\n    }\n\n    val state = rememberDraggableState {\n        alignment = (alignment + it).coerceIn(-1f, 1f)\n    }\n\n    val animatedAlignment by animateFloatAsState(\n        targetValue = alignment,\n        animationSpec = AlignmentAnimationSpec\n    )\n\n    Column(\n        modifier\n            .toggleable(\n                value = checked,\n                onValueChange = {\n                    onCheckedChange?.invoke(it)\n                },\n                enabled = enabled,\n                role = Role.Switch,\n                interactionSource = interactionSource,\n                indication = null\n            )\n            .draggable(\n                state = state,\n                orientation = Orientation.Horizontal,\n                interactionSource = interactionSource,\n                enabled = enabled,\n                onDragStopped = {\n                    if (alignment < 1 / 2f) {\n                        alignment = -1f\n                        if (checked) onCheckedChange?.invoke(false)\n                    } else {\n                        alignment = 1f\n                        if (!checked) onCheckedChange?.invoke(true)\n                    }\n                }\n            )\n            .wrapContentSize(Alignment.Center)\n            .requiredSize(\n                width = CupertinoSwitchDefaults.LiquidWidth,\n                height = CupertinoSwitchDefaults.LiquidHeight\n            )\n            .clip(CupertinoSwitchDefaults.Shape)\n            .background(animatedBackground)\n            .padding(2.dp),\n    ) {\n        Box(\n            Modifier\n                .fillMaxHeight()\n                .aspectRatio(animatedAspectRatio)\n                .align(BiasAlignment.Horizontal(animatedAlignment))\n                .container(\n                    shape = CupertinoSwitchDefaults.Shape,\n                    resultPadding = 0.dp,\n                    autoShadowElevation = animateDpAsState(\n                        if (enabled && LocalSettingsState.current.drawSwitchShadows) {\n                            CupertinoSwitchDefaults.EnabledThumbElevation\n                        } else 0.dp\n                    ).value,\n                    borderColor = Color.Transparent,\n                    isShadowClip = true,\n                    isStandaloneContainer = false,\n                    color = colors.thumbColor(enabled).value\n                )\n        )\n    }\n}\n\n/**\n * Represents the colors used by a [CupertinoSwitch] in different states\n *\n * See [CupertinoSwitchDefaults.colors] for the default implementation that follows Material\n * specifications.\n */\n@Immutable\nclass CupertinoSwitchColors internal constructor(\n    private val thumbColor: Color,\n    private val disabledThumbColor: Color,\n    private val checkedTrackColor: Color,\n    private val checkedIconColor: Color,\n    private val uncheckedTrackColor: Color,\n    private val uncheckedIconColor: Color,\n    private val disabledCheckedTrackColor: Color,\n    private val disabledCheckedIconColor: Color,\n    private val disabledUncheckedTrackColor: Color,\n    private val disabledUncheckedIconColor: Color\n) {\n    /**\n     * Represents the color used for the switch's thumb, depending on [enabled] and [checked].\n     *\n     * @param enabled whether the Switch is enabled or not\n     */\n    @Composable\n    internal fun thumbColor(enabled: Boolean): State<Color> {\n        return animateColorAsState(\n            targetValue = if (enabled) {\n                thumbColor\n            } else {\n                disabledThumbColor\n            },\n            animationSpec = ColorAnimationSpec\n        )\n    }\n\n    /**\n     * Represents the color used for the switch's track, depending on [enabled] and [checked].\n     *\n     * @param enabled whether the Switch is enabled or not\n     * @param checked whether the Switch is checked or not\n     */\n    @Composable\n    internal fun trackColor(\n        enabled: Boolean,\n        checked: Boolean\n    ): State<Color> {\n        return animateColorAsState(\n            targetValue = if (enabled) {\n                if (checked) checkedTrackColor else uncheckedTrackColor\n            } else {\n                if (checked) disabledCheckedTrackColor else disabledUncheckedTrackColor\n            },\n            animationSpec = ColorAnimationSpec\n        )\n    }\n\n    /**\n     * Represents the content color passed to the icon if used\n     *\n     * @param enabled whether the Switch is enabled or not\n     * @param checked whether the Switch is checked or not\n     */\n    @Composable\n    internal fun iconColor(\n        enabled: Boolean,\n        checked: Boolean\n    ): State<Color> {\n        return animateColorAsState(\n            targetValue = if (enabled) {\n                if (checked) checkedIconColor else uncheckedIconColor\n            } else {\n                if (checked) disabledCheckedIconColor else disabledUncheckedIconColor\n            },\n            animationSpec = ColorAnimationSpec\n        )\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is CupertinoSwitchColors) return false\n\n        if (thumbColor != other.thumbColor) return false\n        if (checkedTrackColor != other.checkedTrackColor) return false\n        if (checkedIconColor != other.checkedIconColor) return false\n        if (uncheckedTrackColor != other.uncheckedTrackColor) return false\n        if (uncheckedIconColor != other.uncheckedIconColor) return false\n        if (disabledThumbColor != other.disabledThumbColor) return false\n        if (disabledCheckedTrackColor != other.disabledCheckedTrackColor) return false\n        if (disabledCheckedIconColor != other.disabledCheckedIconColor) return false\n        if (disabledUncheckedTrackColor != other.disabledUncheckedTrackColor) return false\n        if (disabledUncheckedIconColor != other.disabledUncheckedIconColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = thumbColor.hashCode()\n        result = 31 * result + checkedTrackColor.hashCode()\n        result = 31 * result + checkedIconColor.hashCode()\n        result = 31 * result + uncheckedTrackColor.hashCode()\n        result = 31 * result + uncheckedIconColor.hashCode()\n        result = 31 * result + disabledThumbColor.hashCode()\n        result = 31 * result + disabledCheckedTrackColor.hashCode()\n        result = 31 * result + disabledCheckedIconColor.hashCode()\n        result = 31 * result + disabledUncheckedTrackColor.hashCode()\n        result = 31 * result + disabledUncheckedIconColor.hashCode()\n        return result\n    }\n}\n\n@Immutable\nobject CupertinoSwitchDefaults {\n\n    internal val EnabledThumbElevation = 4.dp\n\n    val Width: Dp = 51.dp\n\n    val height: Dp = 31.dp\n\n    val LiquidWidth: Dp = 64.dp\n\n    val LiquidHeight: Dp = 28.dp\n\n    internal val Shape: CornerBasedShape @Composable get() = ShapeDefaults.circle\n\n    @Composable\n    @ReadOnlyComposable\n    fun colors(\n        thumbColor: Color = if (LocalSettingsState.current.isNightMode) {\n            MaterialTheme.colorScheme.onSurface\n        } else MaterialTheme.colorScheme.surfaceContainerLowest,\n        disabledThumbColor: Color = thumbColor,\n        checkedTrackColor: Color = if (LocalSettingsState.current.isNightMode) {\n            MaterialTheme.colorScheme.primary.blend(Color.Black, 0.5f)\n        } else MaterialTheme.colorScheme.primary,\n        checkedIconColor: Color = MaterialTheme.colorScheme.outlineVariant,\n        uncheckedTrackColor: Color = MaterialTheme.colorScheme.outline.copy(\n            alpha = .33f\n        ),\n        uncheckedIconColor: Color = checkedIconColor,\n        disabledCheckedTrackColor: Color = checkedTrackColor.copy(alpha = .33f),\n        disabledCheckedIconColor: Color = checkedIconColor,\n        disabledUncheckedTrackColor: Color = uncheckedTrackColor,\n        disabledUncheckedIconColor: Color = checkedIconColor,\n    ): CupertinoSwitchColors = CupertinoSwitchColors(\n        thumbColor = thumbColor,\n        disabledThumbColor = disabledThumbColor,\n        checkedTrackColor = checkedTrackColor,\n        checkedIconColor = checkedIconColor,\n        uncheckedTrackColor = uncheckedTrackColor,\n        uncheckedIconColor = uncheckedIconColor,\n        disabledCheckedTrackColor = disabledCheckedTrackColor,\n        disabledCheckedIconColor = disabledCheckedIconColor,\n        disabledUncheckedTrackColor = disabledUncheckedTrackColor,\n        disabledUncheckedIconColor = disabledUncheckedIconColor\n    )\n\n    @Composable\n    @ReadOnlyComposable\n    fun transparentColors() = colors(\n        thumbColor = Color.Transparent,\n        disabledThumbColor = Color.Transparent,\n        checkedTrackColor = Color.Transparent,\n        checkedIconColor = Color.Transparent,\n        uncheckedTrackColor = Color.Transparent,\n        uncheckedIconColor = Color.Transparent,\n        disabledCheckedTrackColor = Color.Transparent,\n        disabledCheckedIconColor = Color.Transparent,\n        disabledUncheckedTrackColor = Color.Transparent,\n        disabledUncheckedIconColor = Color.Transparent\n    )\n}\n\nprivate val AspectRationAnimationSpec = tween<Float>(durationMillis = 300)\nprivate val ColorAnimationSpec = tween<Color>(durationMillis = 300)\nprivate val AlignmentAnimationSpec = AspectRationAnimationSpec"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/switches/FluentSwitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.switches\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.draggable\nimport androidx.compose.foundation.gestures.rememberDraggableState\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.selection.toggleable\nimport androidx.compose.material3.SwitchColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.TransformOrigin\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.FastInvokeEasing\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.PointToPointEasing\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberRipple\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun FluentSwitch(\n    checked: Boolean,\n    modifier: Modifier = Modifier,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    enabled: Boolean = true,\n    colors: SwitchColors = SwitchDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null\n) {\n    val realInteractionSource = interactionSource ?: remember {\n        MutableInteractionSource()\n    }\n    val pressed by realInteractionSource.collectIsPressedAsState()\n    val dragged by realInteractionSource.collectIsDraggedAsState()\n\n    val height by animateDpAsState(\n        when {\n            pressed || dragged -> 14.dp\n            else -> 12.dp\n        },\n        tween(Duration, easing = FastInvokeEasing)\n    )\n\n    val width by animateDpAsState(\n        when {\n            pressed || dragged -> 17.dp\n            else -> 12.dp\n        },\n        tween(Duration, easing = FastInvokeEasing)\n    )\n\n    val maxValue = 32.dp - (width / 2)\n    val minValue = 2.dp\n\n    val density = LocalDensity.current\n    var offsetAnimated by remember(checked) {\n        mutableFloatStateOf(\n            with(density) {\n                if (checked) {\n                    maxValue\n                } else {\n                    minValue\n                }.toPx()\n            }\n        )\n    }\n\n    val state = rememberDraggableState {\n        offsetAnimated = with(density) {\n            (offsetAnimated + it).coerceIn(minValue.toPx(), maxValue.toPx())\n        }\n    }\n\n    val offset by animateFloatAsState(\n        targetValue = offsetAnimated,\n        animationSpec = tween(Duration, easing = PointToPointEasing)\n    )\n\n    Row(\n        modifier = modifier\n            .toggleable(\n                value = checked,\n                indication = null,\n                interactionSource = realInteractionSource,\n                role = Role.Switch,\n                onValueChange = {\n                    onCheckedChange?.invoke(it)\n                },\n                enabled = enabled\n            )\n            .draggable(\n                state = state,\n                orientation = Orientation.Horizontal,\n                interactionSource = realInteractionSource,\n                enabled = enabled,\n                onDragStopped = {\n                    with(density) {\n                        if (it < (maxValue.toPx() - minValue.toPx()) / 2f) {\n                            offsetAnimated = minValue.toPx()\n                            if (checked) onCheckedChange?.invoke(false)\n                        } else {\n                            offsetAnimated = maxValue.toPx()\n                            if (!checked) onCheckedChange?.invoke(true)\n                        }\n                    }\n                }\n            ),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        val trackColor by animateColorAsState(\n            targetValue = trackColor(enabled, checked, colors),\n            animationSpec = tween(Duration, easing = PointToPointEasing)\n        )\n        val thumbColor by animateColorAsState(\n            targetValue = thumbColor(enabled, checked, colors),\n            animationSpec = tween(Duration, easing = PointToPointEasing)\n        )\n        val borderColor by animateColorAsState(\n            targetValue = borderColor(enabled, checked, colors),\n            animationSpec = tween(Duration, easing = PointToPointEasing)\n        )\n\n        Box(\n            modifier = Modifier\n                .size(48.dp, 24.dp)\n                .border(\n                    width = 1.dp,\n                    color = borderColor,\n                    shape = ShapeDefaults.circle\n                )\n                .clip(ShapeDefaults.circle)\n                .background(trackColor)\n                .padding(horizontal = 4.dp),\n            contentAlignment = Alignment.CenterStart\n        ) {\n            Box(\n                modifier = Modifier\n                    .size(width, height)\n                    .graphicsLayer {\n                        translationX = offset\n                        transformOrigin = TransformOrigin.Center\n                    }\n                    .indication(\n                        interactionSource = realInteractionSource,\n                        indication = rememberRipple(\n                            bounded = false,\n                            radius = 16.dp\n                        )\n                    )\n                    .clip(ShapeDefaults.circle)\n                    .background(thumbColor)\n            )\n        }\n    }\n}\n\nprivate const val Duration = 600\n\n@Stable\nprivate fun trackColor(\n    enabled: Boolean,\n    checked: Boolean,\n    colors: SwitchColors\n): Color = if (enabled) {\n    if (checked) colors.checkedTrackColor else colors.uncheckedTrackColor\n} else {\n    if (checked) colors.disabledCheckedTrackColor else colors.disabledUncheckedTrackColor\n}\n\n@Stable\nprivate fun thumbColor(\n    enabled: Boolean,\n    checked: Boolean,\n    colors: SwitchColors\n): Color = if (enabled) {\n    if (checked) colors.checkedThumbColor else colors.uncheckedThumbColor\n} else {\n    if (checked) colors.disabledCheckedThumbColor else colors.disabledUncheckedThumbColor\n}\n\n@Stable\nprivate fun borderColor(\n    enabled: Boolean,\n    checked: Boolean,\n    colors: SwitchColors\n): Color = if (enabled) {\n    if (checked) colors.checkedBorderColor else colors.uncheckedBorderColor\n} else {\n    if (checked) colors.disabledCheckedBorderColor else colors.disabledUncheckedBorderColor\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/switches/HyperOSSwitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.switches\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation\nimport androidx.compose.foundation.gestures.detectHorizontalDragGestures\nimport androidx.compose.foundation.gestures.waitForUpOrCancellation\nimport androidx.compose.foundation.hoverable\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.interaction.collectIsHoveredAsState\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.foundation.selection.toggleable\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.PointToPointEasing\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlin.math.absoluteValue\nimport androidx.compose.material3.SwitchColors as M3SwitchColors\n\n\n@Composable\nfun HyperOSSwitch(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    colors: M3SwitchColors = SwitchDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n    enabled: Boolean = true\n) {\n    val interactionSource = interactionSource ?: remember {\n        MutableInteractionSource()\n    }\n\n    val colors = com.t8rin.imagetoolbox.core.ui.widget.switches.SwitchDefaults.switchColors(colors)\n\n    val isPressed by interactionSource.collectIsPressedAsState()\n    val isDragged by interactionSource.collectIsDraggedAsState()\n    val isHovered by interactionSource.collectIsHoveredAsState()\n\n    val springSpec = remember {\n        spring<Dp>(\n            dampingRatio = Spring.DampingRatioLowBouncy,\n            stiffness = Spring.StiffnessMedium\n        )\n    }\n\n    var dragOffset by remember { mutableFloatStateOf(0f) }\n    val thumbOffset by animateDpAsState(\n        targetValue = if (checked) {\n            if (!enabled) 26.dp else if (isPressed || isDragged || isHovered) 24.dp else 26.dp\n        } else {\n            if (!enabled) 4.dp else if (isPressed || isDragged || isHovered) 3.dp else 4.dp\n        } + dragOffset.dp,\n        animationSpec = tween(600, easing = PointToPointEasing)\n    )\n\n    val thumbSize by animateDpAsState(\n        targetValue = if (!enabled) 20.dp else if (isPressed || isDragged || isHovered) 23.dp else 20.dp,\n        animationSpec = springSpec\n    )\n\n    val thumbColor by animateColorAsState(\n        if (checked) colors.checkedThumbColor(enabled) else colors.uncheckedThumbColor(enabled)\n    )\n\n    val backgroundColor by animateColorAsState(\n        if (checked) colors.checkedTrackColor(enabled) else colors.uncheckedTrackColor(enabled),\n        animationSpec = tween(durationMillis = 200)\n    )\n\n    val toggleableModifier = if (onCheckedChange != null) {\n        Modifier.toggleable(\n            value = checked,\n            onValueChange = onCheckedChange,\n            enabled = enabled,\n            role = Role.Switch,\n            interactionSource = interactionSource,\n            indication = null\n        )\n    } else {\n        Modifier\n    }\n\n    val shape = AutoCircleShape()\n    val density = LocalDensity.current\n    Box(\n        modifier = modifier\n            .wrapContentSize(Alignment.Center)\n            .size(50.dp, 28.5.dp)\n            .requiredSize(50.dp, 28.5.dp)\n            .clip(shape)\n            .drawBehind {\n                drawRect(backgroundColor)\n            }\n            .hoverable(\n                interactionSource = interactionSource,\n                enabled = enabled\n            )\n            .then(toggleableModifier)\n    ) {\n        val scope = rememberCoroutineScope()\n        Box(\n            modifier = Modifier\n                .align(Alignment.CenterStart)\n                .offset(x = thumbOffset)\n                .size(thumbSize)\n                .drawBehind {\n                    drawOutline(\n                        outline = shape.createOutline(\n                            size = size,\n                            layoutDirection = layoutDirection,\n                            density = density\n                        ),\n                        color = thumbColor\n                    )\n                }\n                .pointerInput(checked, enabled) {\n                    if (!enabled) return@pointerInput\n                    awaitEachGesture {\n                        val pressInteraction: PressInteraction.Press\n                        val down = awaitFirstDown().also {\n                            pressInteraction = PressInteraction.Press(it.position)\n                            interactionSource.tryEmit(pressInteraction)\n                        }\n                        waitForUpOrCancellation().also {\n                            interactionSource.tryEmit(PressInteraction.Cancel(pressInteraction))\n                        }\n                        awaitVerticalTouchSlopOrCancellation(down.id) { _, _ ->\n                            interactionSource.tryEmit(PressInteraction.Cancel(pressInteraction))\n                        }\n                    }\n                }\n                .pointerInput(checked, enabled, onCheckedChange) {\n                    if (!enabled) return@pointerInput\n                    val dragInteraction: DragInteraction.Start = DragInteraction.Start()\n                    detectHorizontalDragGestures(\n                        onDragStart = {\n                            interactionSource.tryEmit(dragInteraction)\n                        },\n                        onDragEnd = {\n                            if (dragOffset.absoluteValue > 21f / 2) onCheckedChange?.invoke(!checked)\n                            interactionSource.tryEmit(DragInteraction.Stop(dragInteraction))\n                            scope.launch {\n                                delay(50)\n                                dragOffset = 0f\n                            }\n                        },\n                        onDragCancel = {\n                            interactionSource.tryEmit(DragInteraction.Cancel(dragInteraction))\n                            dragOffset = 0f\n                        }\n                    ) { _, dragAmount ->\n                        dragOffset = (dragOffset + dragAmount / 2).let {\n                            if (checked) it.coerceIn(-21f, 0f) else it.coerceIn(0f, 21f)\n                        }\n                    }\n                }\n        )\n    }\n}\n\nprivate object SwitchDefaults {\n\n    @Composable\n    fun switchColors(\n        switchColors: M3SwitchColors\n    ): SwitchColors = SwitchColors(\n        checkedThumbColor = switchColors.checkedThumbColor,\n        uncheckedThumbColor = switchColors.uncheckedThumbColor,\n        disabledCheckedThumbColor = switchColors.disabledCheckedThumbColor,\n        disabledUncheckedThumbColor = switchColors.disabledUncheckedThumbColor,\n        checkedTrackColor = switchColors.checkedTrackColor,\n        uncheckedTrackColor = switchColors.uncheckedTrackColor,\n        disabledCheckedTrackColor = switchColors.disabledCheckedTrackColor,\n        disabledUncheckedTrackColor = switchColors.disabledUncheckedTrackColor\n    )\n}\n\n@Immutable\nprivate class SwitchColors(\n    private val checkedThumbColor: Color,\n    private val uncheckedThumbColor: Color,\n    private val disabledCheckedThumbColor: Color,\n    private val disabledUncheckedThumbColor: Color,\n    private val checkedTrackColor: Color,\n    private val uncheckedTrackColor: Color,\n    private val disabledCheckedTrackColor: Color,\n    private val disabledUncheckedTrackColor: Color\n) {\n    @Stable\n    fun checkedThumbColor(enabled: Boolean): Color =\n        if (enabled) checkedThumbColor else disabledCheckedThumbColor\n\n    @Stable\n    fun uncheckedThumbColor(enabled: Boolean): Color =\n        if (enabled) uncheckedThumbColor else disabledUncheckedThumbColor\n\n    @Stable\n    fun checkedTrackColor(enabled: Boolean): Color =\n        if (enabled) checkedTrackColor else disabledCheckedTrackColor\n\n    @Stable\n    fun uncheckedTrackColor(enabled: Boolean): Color =\n        if (enabled) uncheckedTrackColor else disabledUncheckedTrackColor\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/switches/LiquidToggle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.switches\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.spring\nimport androidx.compose.foundation.MutatorMutex\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawscope.scale\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.graphics.lerp\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerId\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.input.pointer.positionChange\nimport androidx.compose.ui.input.pointer.util.VelocityTracker\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastCoerceIn\nimport androidx.compose.ui.util.fastFirstOrNull\nimport androidx.compose.ui.util.lerp\nimport com.kyant.backdrop.Backdrop\nimport com.kyant.backdrop.backdrops.layerBackdrop\nimport com.kyant.backdrop.backdrops.rememberBackdrop\nimport com.kyant.backdrop.backdrops.rememberCombinedBackdrop\nimport com.kyant.backdrop.backdrops.rememberLayerBackdrop\nimport com.kyant.backdrop.drawBackdrop\nimport com.kyant.backdrop.effects.blur\nimport com.kyant.backdrop.effects.lens\nimport com.kyant.backdrop.highlight.Highlight\nimport com.kyant.backdrop.shadow.InnerShadow\nimport com.kyant.backdrop.shadow.Shadow\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.android.awaitFrame\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.launch\nimport kotlin.math.abs\n\n@Composable\ninternal fun LiquidToggle(\n    checked: () -> Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    backdrop: Backdrop,\n    colors: CupertinoSwitchColors = CupertinoSwitchDefaults.colors(),\n    enabled: Boolean = true,\n    interactionSource: MutableInteractionSource,\n    modifier: Modifier = Modifier\n) {\n    val interactions by interactionSource.interactions.collectAsState(initial = null)\n\n    val accentColor by colors.trackColor(\n        enabled = enabled,\n        checked = true\n    )\n    val trackColor by colors.trackColor(\n        enabled = enabled,\n        checked = false\n    )\n    val thumbColor by colors.thumbColor(enabled)\n\n    val internalChange = remember { mutableStateOf(false) }\n    val density = LocalDensity.current\n    val isLtr = LocalLayoutDirection.current == LayoutDirection.Ltr\n    val dragWidth = with(density) { 20f.dp.toPx() }\n    val animationScope = rememberCoroutineScope()\n    var didDrag by remember { mutableStateOf(false) }\n    var fraction by remember { mutableFloatStateOf(if (checked()) 1f else 0f) }\n    var start by remember { mutableStateOf<DragInteraction.Start?>(null) }\n    val dampedDragAnimation = remember(animationScope, enabled, onCheckedChange) {\n        DampedDragAnimation(\n            enabled = enabled,\n            animationScope = animationScope,\n            initialValue = fraction,\n            valueRange = 0f..1f,\n            visibilityThreshold = 0.001f,\n            initialScale = 1f,\n            pressedScale = 1.5f,\n            onDragStarted = {\n                interactionSource.tryEmit(DragInteraction.Start().also { start = it })\n            },\n            onDragStopped = { isCancel ->\n                if (isCancel) {\n                    start?.let { interactionSource.tryEmit(DragInteraction.Cancel(it)) }\n\n                    fraction = if (checked()) 1f else 0f\n                } else {\n                    start?.let { interactionSource.tryEmit(DragInteraction.Stop(it)) }\n\n                    if (didDrag) {\n                        internalChange.value = true\n                        fraction = if (fraction >= 0.5f) 1f else 0f\n                        didDrag = false\n                    } else {\n                        internalChange.value = false\n                        fraction = if (checked()) 0f else 1f\n                    }\n                }\n            },\n            onDrag = { _, dragAmount ->\n                if (!didDrag) {\n                    didDrag = dragAmount.x != 0f\n                }\n                val delta = dragAmount.x / dragWidth\n                internalChange.value = false\n                fraction =\n                    if (isLtr) (fraction + delta).fastCoerceIn(0f, 1f)\n                    else (fraction - delta).fastCoerceIn(0f, 1f)\n            }\n        )\n    }\n\n    LaunchedEffect(dampedDragAnimation) {\n        snapshotFlow { fraction }\n            .collectLatest { newFraction ->\n                if (internalChange.value) {\n                    onCheckedChange?.invoke(newFraction == 1f)\n                }\n                dampedDragAnimation.updateValue(newFraction)\n            }\n    }\n\n    LaunchedEffect(checked()) {\n        val target = if (checked()) 1f else 0f\n        if (target != fraction) {\n            internalChange.value = false\n            fraction = target\n            dampedDragAnimation.animateToValue(target)\n        }\n    }\n\n    LaunchedEffect(dampedDragAnimation.value, onCheckedChange, checked(), interactions) {\n        delay(500)\n        val new = dampedDragAnimation.value >= 0.5f\n        if (new != checked() && dampedDragAnimation.pressProgress <= 0f && interactions == null) {\n            onCheckedChange?.invoke(new)\n        }\n    }\n\n    val trackBackdrop = rememberLayerBackdrop()\n\n    val shape = AutoCircleShape()\n    Box(\n        modifier = modifier,\n        contentAlignment = Alignment.CenterStart\n    ) {\n        Box(\n            Modifier\n                .layerBackdrop(trackBackdrop)\n                .clip(shape)\n                .drawBehind {\n                    val fraction = dampedDragAnimation.value\n                    drawRect(lerp(trackColor, accentColor, fraction))\n                }\n                .size(64f.dp, 28f.dp)\n        )\n\n        key(shape) {\n            Box(\n                Modifier\n                    .graphicsLayer {\n                        val fraction = dampedDragAnimation.value\n                        val padding = 2f.dp.toPx()\n                        translationX =\n                            if (isLtr) lerp(padding, padding + dragWidth, fraction)\n                            else lerp(-padding, -(padding + dragWidth), fraction)\n                    }\n                    .semantics {\n                        role = Role.Switch\n                    }\n                    .then(dampedDragAnimation.modifier)\n                    .drawBackdrop(\n                        backdrop = rememberCombinedBackdrop(\n                            backdrop,\n                            rememberBackdrop(trackBackdrop) { drawBackdrop ->\n                                val progress = dampedDragAnimation.pressProgress\n                                val scaleX = lerp(2f / 3f, 0.75f, progress)\n                                val scaleY = lerp(0f, 0.75f, progress)\n                                scale(scaleX, scaleY) {\n                                    drawBackdrop()\n                                }\n                            }\n                        ),\n                        shape = { shape },\n                        effects = {\n                            val progress = dampedDragAnimation.pressProgress\n                            blur(8f.dp.toPx() * (1f - progress))\n                            lens(\n                                5f.dp.toPx() * progress,\n                                10f.dp.toPx() * progress,\n                                chromaticAberration = true\n                            )\n                        },\n                        highlight = {\n                            val progress = dampedDragAnimation.pressProgress\n                            Highlight.Ambient.copy(\n                                width = Highlight.Ambient.width / 1.5f,\n                                blurRadius = Highlight.Ambient.blurRadius / 1.5f,\n                                alpha = progress\n                            )\n                        },\n                        shadow = {\n                            Shadow(\n                                radius = 4f.dp,\n                                color = Color.Black.copy(alpha = 0.05f)\n                            )\n                        },\n                        innerShadow = {\n                            val progress = dampedDragAnimation.pressProgress\n                            InnerShadow(\n                                radius = 4f.dp * progress,\n                                alpha = progress\n                            )\n                        },\n                        layerBlock = {\n                            scaleX = dampedDragAnimation.scaleX\n                            scaleY = dampedDragAnimation.scaleY\n                            val velocity = dampedDragAnimation.velocity / 50f\n                            scaleX /= 1f - (velocity * 0.75f).fastCoerceIn(-0.2f, 0.2f)\n                            scaleY *= 1f - (velocity * 0.25f).fastCoerceIn(-0.2f, 0.2f)\n                        },\n                        onDrawSurface = {\n                            val progress = dampedDragAnimation.pressProgress\n                            drawRect(thumbColor.copy(alpha = 1f - progress))\n                        }\n                    )\n                    .size(40f.dp, 24f.dp)\n            )\n        }\n    }\n}\n\n\nprivate class DampedDragAnimation(\n    enabled: Boolean,\n    private val animationScope: CoroutineScope,\n    val initialValue: Float,\n    val valueRange: ClosedRange<Float>,\n    val visibilityThreshold: Float,\n    val initialScale: Float,\n    val pressedScale: Float,\n    val onDragStarted: DampedDragAnimation.(position: Offset) -> Unit,\n    val onDragStopped: DampedDragAnimation.(isCancel: Boolean) -> Unit,\n    val onDrag: DampedDragAnimation.(size: IntSize, dragAmount: Offset) -> Unit,\n) {\n\n    private val valueAnimationSpec =\n        spring(1f, 1000f, visibilityThreshold)\n    private val velocityAnimationSpec =\n        spring(0.5f, 300f, visibilityThreshold * 10f)\n    private val pressProgressAnimationSpec =\n        spring(1f, 1000f, 0.001f)\n    private val scaleXAnimationSpec =\n        spring(0.6f, 250f, 0.001f)\n    private val scaleYAnimationSpec =\n        spring(0.7f, 250f, 0.001f)\n\n    private val valueAnimation =\n        Animatable(initialValue, visibilityThreshold)\n    private val velocityAnimation =\n        Animatable(0f, 5f)\n    private val pressProgressAnimation =\n        Animatable(0f, 0.001f)\n    private val scaleXAnimation =\n        Animatable(initialScale, 0.001f)\n    private val scaleYAnimation =\n        Animatable(initialScale, 0.001f)\n\n    private val mutatorMutex = MutatorMutex()\n\n    private val velocityTracker = VelocityTracker()\n\n    val value: Float get() = valueAnimation.value\n\n    //    val progress: Float get() = (value - valueRange.start) / (valueRange.endInclusive - valueRange.start)\n    val targetValue: Float get() = valueAnimation.targetValue\n    val pressProgress: Float get() = pressProgressAnimation.value\n    val scaleX: Float get() = scaleXAnimation.value\n    val scaleY: Float get() = scaleYAnimation.value\n    val velocity: Float get() = velocityAnimation.value\n\n    val modifier: Modifier = if (enabled) {\n        Modifier.pointerInput(Unit) {\n            inspectDragGestures(\n                onDragStart = { down ->\n                    onDragStarted(down.position)\n                    press()\n                },\n                onDragEnd = {\n                    onDragStopped(false)\n                    release()\n                },\n                onDragCancel = {\n                    onDragStopped(true)\n                    release()\n                }\n            ) { _, dragAmount ->\n                onDrag(size, dragAmount)\n            }\n        }\n    } else Modifier\n\n    fun press() {\n        velocityTracker.resetTracking()\n        animationScope.launch {\n            launch { pressProgressAnimation.animateTo(1f, pressProgressAnimationSpec) }\n            launch { scaleXAnimation.animateTo(pressedScale, scaleXAnimationSpec) }\n            launch { scaleYAnimation.animateTo(pressedScale, scaleYAnimationSpec) }\n        }\n    }\n\n    fun release() {\n        animationScope.launch {\n            awaitFrame()\n            if (value != targetValue) {\n                val threshold = (valueRange.endInclusive - valueRange.start) * 0.025f\n                snapshotFlow { valueAnimation.value }\n                    .filter { abs(it - valueAnimation.targetValue) < threshold }\n                    .first()\n            }\n            launch { pressProgressAnimation.animateTo(0f, pressProgressAnimationSpec) }\n            launch { scaleXAnimation.animateTo(initialScale, scaleXAnimationSpec) }\n            launch { scaleYAnimation.animateTo(initialScale, scaleYAnimationSpec) }\n        }\n    }\n\n    fun updateValue(value: Float) {\n        val targetValue = value.coerceIn(valueRange)\n        animationScope.launch {\n            launch {\n                valueAnimation.animateTo(\n                    targetValue,\n                    valueAnimationSpec\n                ) { updateVelocity() }\n            }\n        }\n    }\n\n    fun animateToValue(value: Float) {\n        animationScope.launch {\n            mutatorMutex.mutate {\n                press()\n                val targetValue = value.coerceIn(valueRange)\n                launch { valueAnimation.animateTo(targetValue, valueAnimationSpec) }\n                if (velocity != 0f) {\n                    launch { velocityAnimation.animateTo(0f, velocityAnimationSpec) }\n                }\n                release()\n            }\n        }\n    }\n\n    private fun updateVelocity() {\n        velocityTracker.addPosition(\n            System.currentTimeMillis(),\n            Offset(value, 0f)\n        )\n        val targetVelocity =\n            velocityTracker.calculateVelocity().x / (valueRange.endInclusive - valueRange.start)\n        animationScope.launch { velocityAnimation.animateTo(targetVelocity, velocityAnimationSpec) }\n    }\n}\n\nprivate suspend fun PointerInputScope.inspectDragGestures(\n    onDragStart: (down: PointerInputChange) -> Unit = {},\n    onDragEnd: (change: PointerInputChange) -> Unit = {},\n    onDragCancel: () -> Unit = {},\n    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit\n) {\n    awaitEachGesture {\n        val initialDown = awaitFirstDown(false, PointerEventPass.Initial)\n\n        val down = awaitFirstDown(false)\n\n        onDragStart(down)\n        onDrag(initialDown, Offset.Zero)\n        val upEvent =\n            drag(\n                pointerId = initialDown.id,\n                onDrag = { onDrag(it, it.positionChange()) }\n            )\n        if (upEvent == null) {\n            onDragCancel()\n        } else {\n            onDragEnd(upEvent)\n        }\n    }\n}\n\nprivate suspend inline fun AwaitPointerEventScope.drag(\n    pointerId: PointerId,\n    onDrag: (PointerInputChange) -> Unit\n): PointerInputChange? {\n    val isPointerUp = currentEvent.changes.fastFirstOrNull { it.id == pointerId }?.pressed != true\n    if (isPointerUp) {\n        return null\n    }\n    var pointer = pointerId\n    while (true) {\n        val change = awaitDragOrUp(pointer) ?: return null\n        if (change.isConsumed) {\n            return null\n        }\n        if (change.changedToUpIgnoreConsumed()) {\n            return change\n        }\n        onDrag(change)\n        pointer = change.id\n    }\n}\n\nprivate suspend inline fun AwaitPointerEventScope.awaitDragOrUp(\n    pointerId: PointerId\n): PointerInputChange? {\n    var pointer = pointerId\n    while (true) {\n        val event = awaitPointerEvent()\n        val dragEvent = event.changes.fastFirstOrNull { it.id == pointer } ?: return null\n        if (dragEvent.changedToUpIgnoreConsumed()) {\n            val otherDown = event.changes.fastFirstOrNull { it.pressed }\n            if (otherDown == null) {\n                return dragEvent\n            } else {\n                pointer = otherDown.id\n            }\n        } else {\n            val hasDragged = dragEvent.previousPosition != dragEvent.position\n            if (hasDragged) {\n                return dragEvent\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/switches/M3Switch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.switches\n\nimport android.annotation.SuppressLint\nimport android.content.res.ColorStateList\nimport android.view.MotionEvent\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.material3.Switch\nimport androidx.compose.material3.SwitchColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.viewinterop.AndroidView\nimport com.google.android.material.materialswitch.MaterialSwitch\nimport kotlinx.coroutines.launch\n\n\n@SuppressLint(\"ClickableViewAccessibility\")\n@Composable\nfun M3Switch(\n    checked: Boolean,\n    modifier: Modifier = Modifier,\n    internalModifier: Modifier = modifier,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    enabled: Boolean = true,\n    colors: SwitchColors = SwitchDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    val realInteractionSource = interactionSource ?: remember {\n        MutableInteractionSource()\n    }\n    val isPressed by realInteractionSource.collectIsPressedAsState()\n    var view by remember {\n        mutableStateOf<MaterialSwitch?>(null)\n    }\n\n    val scope = rememberCoroutineScope()\n\n    DisposableEffect(view, checked, onCheckedChange) {\n        view?.isChecked = checked\n        view?.setOnCheckedChangeListener { _, value ->\n            onCheckedChange?.let {\n                onCheckedChange(value)\n            }\n        }\n\n        onDispose {\n            view?.setOnCheckedChangeListener(null)\n        }\n    }\n    LaunchedEffect(view, isPressed) {\n        view?.isPressed = isPressed\n    }\n\n    Box {\n        Switch(\n            checked = false,\n            onCheckedChange = {},\n            modifier = internalModifier,\n            colors = SwitchDefaults.transparentColors()\n        )\n\n        var press by remember {\n            mutableStateOf<PressInteraction.Press?>(null)\n        }\n        var drag by remember {\n            mutableStateOf<DragInteraction.Start?>(null)\n        }\n\n        AndroidView(\n            modifier = modifier,\n            factory = { context ->\n                MaterialSwitch(context).apply {\n                    view = this\n                    isHapticFeedbackEnabled = false\n                    setOnTouchListener { _, event ->\n                        when (event.actionMasked) {\n                            MotionEvent.ACTION_DOWN -> {\n                                press = PressInteraction.Press(\n                                    Offset(event.x, event.y)\n                                ).also {\n                                    scope.launch {\n                                        realInteractionSource.emit(it)\n                                    }\n                                }\n                            }\n\n                            MotionEvent.ACTION_MOVE -> {\n                                drag = DragInteraction.Start().also {\n                                    scope.launch {\n                                        realInteractionSource.emit(it)\n                                    }\n                                }\n                            }\n\n                            MotionEvent.ACTION_UP -> {\n                                scope.launch {\n                                    press?.let {\n                                        realInteractionSource.emit(PressInteraction.Release(it))\n                                    }\n                                    drag?.let {\n                                        realInteractionSource.emit(DragInteraction.Stop(it))\n                                    }\n                                    press = null\n                                    drag = null\n                                }\n                            }\n\n                            MotionEvent.ACTION_CANCEL -> {\n                                scope.launch {\n                                    press?.let {\n                                        realInteractionSource.emit(PressInteraction.Cancel(it))\n                                    }\n                                    drag?.let {\n                                        realInteractionSource.emit(DragInteraction.Cancel(it))\n                                    }\n                                    press = null\n                                    drag = null\n                                }\n                            }\n\n                            else -> Unit\n                        }\n\n                        false\n                    }\n                }\n            },\n            update = {\n                it.isEnabled = enabled\n                val states = arrayOf(\n                    intArrayOf(-android.R.attr.state_checked),\n                    intArrayOf(-android.R.attr.state_enabled),\n                    intArrayOf(android.R.attr.state_checked)\n                )\n                val trackColors = intArrayOf(\n                    colors.uncheckedTrackColor.toArgb(),\n                    if (checked) {\n                        colors.disabledCheckedTrackColor\n                    } else {\n                        colors.disabledUncheckedTrackColor\n                    }.toArgb(),\n                    colors.checkedTrackColor.toArgb()\n                )\n                it.trackTintList = ColorStateList(states, trackColors)\n\n                val thumbColors = intArrayOf(\n                    colors.uncheckedThumbColor.toArgb(),\n                    if (checked) {\n                        colors.disabledCheckedThumbColor\n                    } else {\n                        colors.disabledUncheckedThumbColor\n                    }.toArgb(),\n                    colors.checkedThumbColor.toArgb()\n                )\n                it.thumbTintList = ColorStateList(states, thumbColors)\n\n                val borderColors = intArrayOf(\n                    colors.uncheckedBorderColor.toArgb(),\n                    if (checked) {\n                        colors.disabledCheckedBorderColor\n                    } else {\n                        colors.disabledUncheckedBorderColor\n                    }.toArgb(),\n                    colors.checkedBorderColor.toArgb()\n                )\n                it.trackDecorationTintList = ColorStateList(states, borderColors)\n            }\n        )\n    }\n}\n\n@Suppress(\"UnusedReceiverParameter\")\nprivate fun SwitchDefaults.transparentColors() = SwitchColors(\n    checkedThumbColor = Color.Transparent,\n    checkedTrackColor = Color.Transparent,\n    checkedBorderColor = Color.Transparent,\n    checkedIconColor = Color.Transparent,\n    uncheckedThumbColor = Color.Transparent,\n    uncheckedTrackColor = Color.Transparent,\n    uncheckedBorderColor = Color.Transparent,\n    uncheckedIconColor = Color.Transparent,\n    disabledCheckedThumbColor = Color.Transparent,\n    disabledCheckedTrackColor = Color.Transparent,\n    disabledCheckedBorderColor = Color.Transparent,\n    disabledCheckedIconColor = Color.Transparent,\n    disabledUncheckedThumbColor = Color.Transparent,\n    disabledUncheckedTrackColor = Color.Transparent,\n    disabledUncheckedBorderColor = Color.Transparent,\n    disabledUncheckedIconColor = Color.Transparent\n)"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/switches/OneUISwitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.switches\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.gestures.detectDragGestures\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.SwitchColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.switches.ActualSwitchColors.Companion.forConfig\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun OneUISwitch(\n    modifier: Modifier = Modifier,\n    colors: SwitchColors = SwitchDefaults.colors(),\n    onCheckedChange: ((Boolean) -> Unit)? = { },\n    enabled: Boolean = true,\n    checked: Boolean = false,\n    interactionSource: MutableInteractionSource? = null\n) {\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    var isAnimating by remember {\n        mutableStateOf(false)\n    }\n    val scope = rememberCoroutineScope()\n\n    val actualColors = colors.forConfig(enabled, checked)\n\n    val spec = tween<Color>(animDuration)\n    val thumbColor by animateColorAsState(\n        targetValue = actualColors.thumb,\n        label = \"Switch thumb color\",\n        animationSpec = spec\n    )\n    val track by animateColorAsState(\n        targetValue = actualColors.track,\n        label = \"Switch track color\",\n        animationSpec = spec\n    )\n    val stroke by animateColorAsState(\n        targetValue = actualColors.stroke,\n        label = \"Switch stroke color\",\n        animationSpec = spec\n    )\n    val rippleAlphaFactor by animateFloatAsState(\n        targetValue = if (isAnimating) 1F else 0F,\n        label = \"Switch ripple alpha\",\n        animationSpec = tween(animDuration)\n    )\n    val rippleRadius by animateDpAsState(\n        targetValue = if (isAnimating) rippleRadius else 0.dp,\n        label = \"Switch ripple radius\",\n        animationSpec = tween(animDuration)\n    )\n\n    val ripple = MaterialTheme.colorScheme.outline.copy(0.1f)\n\n    var dragProgress by remember { mutableStateOf<Float?>(null) }\n    val progress by animateFloatAsState(\n        targetValue = dragProgress ?: if (checked) 1f else 0f,\n        label = \"Switch progress\",\n        animationSpec = tween(animDuration)\n    )\n\n    val shape = ShapeDefaults.circle\n\n    Canvas(\n        modifier = modifier\n            .width(trackSize.width + (thumbOvershoot * 2))\n            .height(thumbSize.height)\n            .hapticsClickable(\n                enabled = enabled,\n                interactionSource = interactionSource,\n                indication = null,\n                role = Role.Switch,\n                onClick = {\n                    onCheckedChange?.invoke(!checked)\n                    isAnimating = true\n                    scope.launch {\n                        delay(animDuration.toLong())\n                        isAnimating = false\n                    }\n                }\n            )\n            .pointerInput(enabled, onCheckedChange) {\n                if (!enabled) return@pointerInput\n                var interaction: DragInteraction.Start? = null\n                detectDragGestures(\n                    onDragStart = {\n                        interaction = DragInteraction.Start().also(interactionSource::tryEmit)\n                        isAnimating = true\n                        dragProgress = progress\n                    },\n                    onDragEnd = {\n                        val newChecked = (dragProgress ?: progress) > 0.5f\n                        onCheckedChange?.invoke(newChecked)\n                        scope.launch {\n                            dragProgress = if (newChecked) 1f else 0f\n                            delay(animDuration.toLong())\n                            dragProgress = null\n                            isAnimating = false\n                        }\n                        interaction?.let {\n                            interactionSource.tryEmit(DragInteraction.Stop(it))\n                        }\n                    },\n                    onDragCancel = {\n                        val newChecked = (dragProgress ?: progress) > 0.5f\n                        onCheckedChange?.invoke(newChecked)\n                        scope.launch {\n                            dragProgress = if (newChecked) 1f else 0f\n                            delay(animDuration.toLong())\n                            dragProgress = null\n                        }\n                        isAnimating = false\n                        interaction?.let {\n                            interactionSource.tryEmit(DragInteraction.Cancel(it))\n                        }\n                    },\n                    onDrag = { change, dragAmount ->\n                        change.consume()\n                        dragProgress = ((dragProgress ?: progress) + dragAmount.x).coerceIn(0f, 1f)\n                    }\n                )\n            }\n    ) {\n        drawTrack(\n            color = track,\n            dpSize = trackSize,\n            spacingStart = thumbOvershoot,\n            shape = shape\n        )\n\n        val thumbPos = thumbPosition(\n            overshoot = thumbOvershoot,\n            progress = progress,\n            radius = thumbSize.width / 2,\n            size = size,\n            density = this\n        )\n\n        drawThumb(\n            color = thumbColor,\n            radius = thumbSize.width / 2,\n            position = thumbPos,\n            shape = shape\n        )\n\n        drawOutline(\n            color = stroke,\n            radius = (thumbSize.width + strokeWidth) / 2,\n            position = thumbPos,\n            strokeWidth = strokeWidth,\n            shape = shape\n        )\n\n        drawRipple(\n            color = ripple.copy(alpha = ripple.alpha * rippleAlphaFactor),\n            radius = rippleRadius,\n            position = thumbPos,\n            shape = shape\n        )\n    }\n}\n\nprivate fun DrawScope.drawTrack(\n    color: Color,\n    dpSize: DpSize,\n    spacingStart: Dp,\n    shape: Shape\n) {\n    val dif = size.height - dpSize.height.toPx()\n    val outline = shape.createOutline(\n        size = dpSize.toSize(),\n        layoutDirection = LayoutDirection.Ltr,\n        density = this\n    )\n    translate(\n        left = spacingStart.toPx(),\n        top = dif / 2\n    ) {\n        drawOutline(outline = outline, color = color)\n    }\n}\n\nprivate fun DrawScope.drawThumb(\n    color: Color,\n    radius: Dp,\n    position: Offset,\n    shape: Shape\n) {\n    val size = Size(radius.toPx() * 2, radius.toPx() * 2)\n    val outline = shape.createOutline(\n        size = size,\n        layoutDirection = LayoutDirection.Ltr,\n        density = this\n    )\n    translate(\n        left = position.x - radius.toPx(),\n        top = position.y - radius.toPx()\n    ) {\n        drawOutline(outline = outline, color = color)\n    }\n}\n\nprivate fun DrawScope.drawOutline(\n    color: Color,\n    radius: Dp,\n    position: Offset,\n    strokeWidth: Dp,\n    shape: Shape\n) {\n    val size = Size(radius.toPx() * 2, radius.toPx() * 2)\n    val outline = shape.createOutline(\n        size = size,\n        layoutDirection = LayoutDirection.Ltr,\n        density = this\n    )\n    translate(\n        left = position.x - radius.toPx(),\n        top = position.y - radius.toPx()\n    ) {\n        drawOutline(\n            outline = outline,\n            color = color,\n            style = Stroke(width = strokeWidth.toPx())\n        )\n    }\n}\n\nprivate fun DrawScope.drawRipple(\n    color: Color,\n    radius: Dp,\n    position: Offset,\n    shape: Shape\n) {\n    val size = Size(radius.toPx() * 2, radius.toPx() * 2)\n    val outline = shape.createOutline(\n        size = size,\n        layoutDirection = LayoutDirection.Ltr,\n        density = this\n    )\n    translate(\n        left = position.x - radius.toPx(),\n        top = position.y - radius.toPx()\n    ) {\n        drawOutline(outline = outline, color = color)\n    }\n}\n\nprivate fun thumbPosition(\n    overshoot: Dp,\n    progress: Float,\n    radius: Dp,\n    size: Size,\n    density: Density\n): Offset {\n    val yCenter = size.height / 2\n    val width = size.width\n    val start =\n        with(density) { thumbOvershoot.toPx() + (radius.toPx() - overshoot.toPx()) }\n    val end = width - start\n    val pos = mapRange(\n        value = progress,\n        targetStart = start,\n        targetEnd = end\n    )\n    return Offset(\n        x = pos,\n        y = yCenter\n    )\n}\n\nprivate fun mapRange(\n    value: Float,\n    origStart: Float = 0f,\n    origEnd: Float = 1f,\n    targetStart: Float,\n    targetEnd: Float\n): Float = (value - origStart) / (origEnd - origStart) * (targetEnd - targetStart) + targetStart\n\nprivate data class ActualSwitchColors(\n    val thumb: Color,\n    val track: Color,\n    val stroke: Color\n) {\n    companion object {\n        @Suppress(\"KotlinConstantConditions\")\n        fun SwitchColors.forConfig(\n            enabled: Boolean,\n            checked: Boolean\n        ): ActualSwitchColors = if (\n            enabled && checked\n        ) ActualSwitchColors(\n            thumb = checkedThumbColor,\n            track = checkedTrackColor,\n            stroke = checkedTrackColor\n        ) else if (\n            !enabled && checked\n        ) ActualSwitchColors(\n            thumb = disabledCheckedThumbColor,\n            track = disabledCheckedTrackColor,\n            stroke = disabledCheckedTrackColor\n        ) else if (\n            enabled && !checked\n        ) ActualSwitchColors(\n            thumb = uncheckedTrackColor.copy(1f),\n            track = uncheckedThumbColor.copy(1f),\n            stroke = uncheckedThumbColor.copy(1f),\n        ) else ActualSwitchColors(\n            thumb = disabledUncheckedTrackColor,\n            track = disabledUncheckedThumbColor,\n            stroke = disabledUncheckedThumbColor\n        )\n    }\n}\n\nprivate const val animDuration = 250\nprivate val strokeWidth = 2.dp\nprivate val thumbSize = DpSize(\n    width = 22.dp,\n    height = 22.dp\n)\nprivate val thumbOvershoot = 2.dp\nprivate val trackSize = DpSize(\n    width = 35.dp,\n    height = 18.5.dp\n)\nprivate val rippleRadius = 20.dp\n\n@Composable\n@EnPreview\nprivate fun Preview() = ImageToolboxThemeForPreview(true, keyColor = Color.Green) {\n    val colors = SwitchDefaults.colors(\n        disabledUncheckedThumbColor = MaterialTheme.colorScheme.onSurface\n            .copy(alpha = 0.12f)\n            .compositeOver(MaterialTheme.colorScheme.surface)\n    ).copy(\n        uncheckedTrackColor = MaterialTheme.colorScheme.surfaceContainerLow\n    )\n    Surface {\n        Column(\n            modifier = Modifier.padding(20.dp),\n            verticalArrangement = Arrangement.spacedBy(12.dp)\n        ) {\n            var checked by remember {\n                mutableStateOf(true)\n            }\n            OneUISwitch(\n                checked = checked,\n                colors = colors,\n                onCheckedChange = { checked = it }\n            )\n\n            OneUISwitch(\n                checked = false,\n                colors = colors\n            )\n\n            OneUISwitch(\n                checked = true,\n                enabled = false,\n                colors = colors\n            )\n\n            OneUISwitch(\n                checked = false,\n                enabled = false,\n                colors = colors\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/switches/PixelSwitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.switches\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.draggable\nimport androidx.compose.foundation.gestures.rememberDraggableState\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.SwitchColors\nimport androidx.compose.material3.SwitchDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.PointToPointEasing\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberRipple\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlin.math.roundToInt\n\n@Composable\nfun PixelSwitch(\n    checked: Boolean,\n    modifier: Modifier = Modifier,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    enabled: Boolean = true,\n    colors: SwitchColors = SwitchDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    val realInteractionSource = interactionSource ?: remember {\n        MutableInteractionSource()\n    }\n    val trackColor by animateColorAsState(\n        targetValue = trackColor(enabled, checked, colors),\n        animationSpec = tween(Duration, easing = PointToPointEasing)\n    )\n    val thumbColor by animateColorAsState(\n        targetValue = thumbColor(enabled, checked, colors),\n        animationSpec = tween(Duration, easing = PointToPointEasing)\n    )\n    val borderColor by animateColorAsState(\n        targetValue = borderColor(enabled, checked, colors),\n        animationSpec = tween(Duration, easing = PointToPointEasing)\n    )\n    val thumbSize by animateDpAsState(\n        targetValue = if (checked) SelectedHandleSize else UnselectedHandleSize,\n        animationSpec = tween(Duration, easing = PointToPointEasing)\n    )\n\n    val density = LocalDensity.current\n    var offsetAnimated by remember(checked) {\n        mutableFloatStateOf(\n            with(density) {\n                if (checked) {\n                    ThumbPaddingEnd\n                } else {\n                    ThumbPaddingStart\n                }.toPx()\n            }\n        )\n    }\n\n    val state = rememberDraggableState {\n        offsetAnimated = with(density) {\n            (offsetAnimated + it).coerceIn(ThumbPaddingStart.toPx(), ThumbPaddingEnd.toPx())\n        }\n    }\n\n    val thumbOffset by animateFloatAsState(\n        targetValue = offsetAnimated,\n        animationSpec = tween(Duration, easing = PointToPointEasing)\n    )\n\n    Box(\n        modifier = modifier\n            .hapticsClickable(\n                interactionSource = realInteractionSource,\n                indication = null,\n                enabled = enabled,\n                onClickLabel = null,\n                role = Role.Switch,\n                enableHaptics = false,\n                onClick = { onCheckedChange?.invoke(!checked) }\n            )\n            .draggable(\n                state = state,\n                orientation = Orientation.Horizontal,\n                interactionSource = realInteractionSource,\n                enabled = enabled,\n                onDragStopped = {\n                    with(density) {\n                        if (it < (ThumbPaddingEnd.toPx() - ThumbPaddingStart.toPx()) / 2f) {\n                            offsetAnimated = ThumbPaddingStart.toPx()\n                            if (checked) onCheckedChange?.invoke(false)\n                        } else {\n                            offsetAnimated = ThumbPaddingEnd.toPx()\n                            if (!checked) onCheckedChange?.invoke(true)\n                        }\n                    }\n                }\n            )\n            .background(trackColor, ShapeDefaults.circle)\n            .size(TrackWidth, TrackHeight)\n            .border(\n                width = TrackOutlineWidth,\n                color = borderColor,\n                shape = ShapeDefaults.circle\n            )\n    ) {\n        Box(\n            modifier = Modifier\n                .offset { IntOffset(x = thumbOffset.roundToInt(), y = 0) }\n                .indication(\n                    interactionSource = realInteractionSource,\n                    indication = rememberRipple(\n                        bounded = false,\n                        radius = 16.dp\n                    )\n                )\n                .align(Alignment.CenterStart)\n                .background(thumbColor, ShapeDefaults.circle)\n                .size(thumbSize)\n        )\n    }\n}\n\nprivate const val Duration = 500\n\n@Stable\nprivate fun trackColor(\n    enabled: Boolean,\n    checked: Boolean,\n    colors: SwitchColors\n): Color = if (enabled) {\n    if (checked) colors.checkedTrackColor else colors.uncheckedTrackColor\n} else {\n    if (checked) colors.disabledCheckedTrackColor else colors.disabledUncheckedTrackColor\n}\n\n@Stable\nprivate fun thumbColor(\n    enabled: Boolean,\n    checked: Boolean,\n    colors: SwitchColors\n): Color = if (enabled) {\n    if (checked) colors.checkedThumbColor else colors.uncheckedThumbColor\n} else {\n    if (checked) colors.disabledCheckedThumbColor else colors.disabledUncheckedThumbColor\n}\n\n@Stable\nprivate fun borderColor(\n    enabled: Boolean,\n    checked: Boolean,\n    colors: SwitchColors\n): Color = if (enabled) {\n    if (checked) colors.checkedBorderColor else colors.uncheckedBorderColor\n} else {\n    if (checked) colors.disabledCheckedBorderColor else colors.disabledUncheckedBorderColor\n}\n\nprivate val TrackWidth = 56.0.dp\nprivate val TrackHeight = 28.0.dp\nprivate val TrackOutlineWidth = 1.8.dp\nprivate val SelectedHandleSize = 20.0.dp\nprivate val UnselectedHandleSize = 20.0.dp\n\nprivate val ThumbPaddingStart = (TrackHeight - UnselectedHandleSize) / 2\nprivate val ThumbPaddingEnd = TrackWidth - SelectedHandleSize / 2 - TrackHeight / 2"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/AutoSizeText.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.font.FontStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.text.style.TextDecoration\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.TextUnit\n\n@Composable\nfun AutoSizeText(\n    text: String,\n    modifier: Modifier = Modifier,\n    color: Color = Color.Unspecified,\n    fontStyle: FontStyle? = null,\n    fontWeight: FontWeight? = null,\n    fontFamily: FontFamily? = null,\n    letterSpacing: TextUnit = TextUnit.Unspecified,\n    textDecoration: TextDecoration? = null,\n    textAlign: TextAlign? = null,\n    lineHeight: TextUnit = TextUnit.Unspecified,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = 1,\n    minLines: Int = 1,\n    style: TextStyle = LocalTextStyle.current,\n    key: (String) -> Any? = { it }\n) {\n    var sizedStyle by remember(style, key(text)) { mutableStateOf(style) }\n    var readyToDraw by remember(minLines, key(text)) { mutableStateOf(false) }\n\n    Text(\n        text = text,\n        color = color,\n        maxLines = maxLines,\n        fontStyle = fontStyle,\n        fontWeight = fontWeight,\n        fontFamily = fontFamily,\n        letterSpacing = letterSpacing,\n        textDecoration = textDecoration,\n        textAlign = textAlign,\n        lineHeight = lineHeight,\n        overflow = overflow,\n        softWrap = softWrap,\n        style = style,\n        fontSize = sizedStyle.fontSize,\n        minLines = minLines,\n        onTextLayout = {\n            if (it.didOverflowHeight) {\n                sizedStyle = sizedStyle.copy(fontSize = sizedStyle.fontSize * 0.9)\n            } else {\n                readyToDraw = true\n            }\n        },\n        modifier = modifier.drawWithContent { if (readyToDraw) drawContent() }\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/HtmlText.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.foundation.text.BasicText\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.text.AnnotatedString\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.TextLinkStyles\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.fromHtml\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.text.style.TextDecoration\nimport androidx.compose.ui.text.style.TextOverflow\n\n@Composable\nfun HtmlText(\n    html: String,\n    modifier: Modifier = Modifier,\n    style: TextStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Left)\n        .copy(color = MaterialTheme.colorScheme.onSurface),\n    hyperlinkStyle: TextStyle = style.copy(\n        color = MaterialTheme.colorScheme.primary,\n        textDecoration = TextDecoration.Underline,\n        fontWeight = style.fontWeight?.run {\n            FontWeight(weight + 100)\n        }\n    ),\n    softWrap: Boolean = true,\n    overflow: TextOverflow = TextOverflow.Ellipsis,\n    maxLines: Int = Int.MAX_VALUE,\n    onTextLayout: (TextLayoutResult) -> Unit = {}\n) {\n    BasicText(\n        text = remember(html) {\n            val linkStyle = TextLinkStyles(\n                style = hyperlinkStyle.toSpanStyle()\n            )\n\n            AnnotatedString.fromHtml(\n                htmlString = html,\n                linkStyles = linkStyle\n            ).linkify(linkStyle)\n        },\n        modifier = modifier,\n        style = style,\n        softWrap = softWrap,\n        overflow = overflow,\n        maxLines = maxLines,\n        onTextLayout = onTextLayout\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/IsKeyboardVisibleAsState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.ime\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalFocusManager\n\n@Composable\nfun isKeyboardVisibleAsState(): State<Boolean> {\n    val isImeVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0\n    return rememberUpdatedState(isImeVisible)\n}\n\n@Composable\nfun KeyboardFocusHandler() {\n    val focus = LocalFocusManager.current\n    val isKeyboardVisible by isKeyboardVisibleAsState()\n\n    LaunchedEffect(isKeyboardVisible) {\n        if (!isKeyboardVisible) focus.clearFocus()\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/Linkify.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.ui.text.AnnotatedString\nimport androidx.compose.ui.text.LinkAnnotation\nimport androidx.compose.ui.text.TextLinkStyles\nimport androidx.compose.ui.text.buildAnnotatedString\n\nfun AnnotatedString.linkify(\n    linkStyles: TextLinkStyles\n): AnnotatedString = buildAnnotatedString {\n    append(this@linkify)\n\n    val text = this@linkify.text\n    val matches = URL_PATTERN.findAll(text).toList()\n\n    for (match in matches) {\n        val url = match.value\n\n        if (url.contains(\"@\") && !url.startsWith(\"mailto:\")) {\n            continue\n        }\n\n        val start = match.range.first\n        val end = match.range.last + 1\n\n        val hasLinkAnnotation = this@linkify.getStringAnnotations(\n            tag = url,\n            start = start,\n            end = end\n        ).any { it.item == url }\n\n        if (!hasLinkAnnotation) {\n            addLink(\n                url = LinkAnnotation.Url(\n                    url = url,\n                    styles = linkStyles\n                ),\n                start = start,\n                end = end\n            )\n        }\n    }\n}\n\nprivate val URL_PATTERN =\n    Regex(\"(https?://(?:www\\\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\\\.\\\\S{2,}|www\\\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\\\.\\\\S{2,}|https?://(?:www\\\\.|(?!www))[a-zA-Z0-9]+\\\\.\\\\S{2,}|www\\\\.[a-zA-Z0-9]+\\\\.\\\\S{2,})\")\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/Marquee.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.foundation.basicMarquee\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.constrainWidth\nimport androidx.compose.ui.unit.dp\nimport com.gigamole.composefadingedges.fill.FadingEdgesFillType\nimport com.gigamole.composefadingedges.marqueeHorizontalFadingEdges\n\n\nfun Modifier.marquee(\n    edgesColor: Color = Color.Unspecified,\n) = this.composed {\n    var showMarquee by remember { mutableStateOf(false) }\n\n    Modifier\n        .clipToBounds()\n        .then(\n            if (showMarquee) {\n                Modifier.marqueeHorizontalFadingEdges(\n                    fillType = if (edgesColor.isSpecified) {\n                        FadingEdgesFillType.FadeColor(\n                            color = edgesColor\n                        )\n                    } else FadingEdgesFillType.FadeClip(),\n                    length = 10.dp,\n                    isMarqueeAutoLayout = false\n                ) {\n                    Modifier.basicMarquee(\n                        iterations = Int.MAX_VALUE,\n                        velocity = 48.dp,\n                        repeatDelayMillis = 1500\n                    )\n                }\n            } else Modifier\n        )\n        .layout { measurable, constraints ->\n            val childConstraints = constraints.copy(maxWidth = Constraints.Infinity)\n            val placeable = measurable.measure(childConstraints)\n            val containerWidth = constraints.constrainWidth(placeable.width)\n            val contentWidth = placeable.width\n            if (!showMarquee) {\n                showMarquee = contentWidth > containerWidth\n            }\n            layout(containerWidth, placeable.height) {\n                placeable.placeWithLayer(x = 0, y = 0)\n            }\n        }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/OutlinedText.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.semantics.hideFromAccessibility\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.font.FontStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.text.style.TextDecoration\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.TextUnit\n\n\n@Stable\n@Immutable\ndata class OutlineParams(\n    val stroke: Stroke,\n    val color: Color\n)\n\n@Composable\nfun OutlinedText(\n    text: String,\n    outlineParams: OutlineParams?,\n    modifier: Modifier = Modifier,\n    color: Color = Color.Unspecified,\n    fontSize: TextUnit = TextUnit.Unspecified,\n    fontStyle: FontStyle? = null,\n    fontWeight: FontWeight? = null,\n    fontFamily: FontFamily? = null,\n    letterSpacing: TextUnit = TextUnit.Unspecified,\n    textDecoration: TextDecoration? = null,\n    textAlign: TextAlign? = null,\n    lineHeight: TextUnit = TextUnit.Unspecified,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    minLines: Int = 1,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    style: TextStyle = LocalTextStyle.current\n) {\n    Box(modifier = modifier) {\n        outlineParams?.let { params ->\n            Text(\n                text = text,\n                modifier = Modifier.semantics { hideFromAccessibility() },\n                color = params.color,\n                fontSize = fontSize,\n                fontStyle = fontStyle,\n                fontWeight = fontWeight,\n                fontFamily = fontFamily,\n                letterSpacing = letterSpacing,\n                textDecoration = null,\n                textAlign = textAlign,\n                lineHeight = lineHeight,\n                overflow = overflow,\n                softWrap = softWrap,\n                maxLines = maxLines,\n                minLines = minLines,\n                style = style.copy(\n                    shadow = null,\n                    drawStyle = params.stroke,\n                ),\n            )\n        }\n\n        Text(\n            text = text,\n            color = color,\n            fontSize = fontSize,\n            fontStyle = fontStyle,\n            fontWeight = fontWeight,\n            fontFamily = fontFamily,\n            letterSpacing = letterSpacing,\n            textDecoration = textDecoration,\n            textAlign = textAlign,\n            lineHeight = lineHeight,\n            overflow = overflow,\n            softWrap = softWrap,\n            maxLines = maxLines,\n            minLines = minLines,\n            onTextLayout = onTextLayout,\n            style = style,\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/PatternHighlightTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.material3.TextField\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.text.AnnotatedString\nimport androidx.compose.ui.text.SpanStyle\nimport androidx.compose.ui.text.buildAnnotatedString\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.OffsetMapping\nimport androidx.compose.ui.text.input.TransformedText\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.tooling.preview.Preview\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\n\ndata class PatternHighlightTransformation(\n    private val mapping: Map<Regex, Color>\n) : VisualTransformation {\n\n    override fun filter(text: AnnotatedString): TransformedText {\n        val annotated = buildAnnotatedString {\n            append(text)\n\n            mapping.forEach { (re, color) ->\n                re.findAll(text).forEach { match ->\n                    addStyle(\n                        style = SpanStyle(\n                            color = color,\n                            fontWeight = FontWeight.SemiBold,\n                            background = color.copy(0.15f)\n                        ),\n                        start = match.range.first,\n                        end = match.range.last + 1\n                    )\n                }\n            }\n        }\n\n        return TransformedText(\n            text = annotated,\n            offsetMapping = OffsetMapping.Identity\n        )\n    }\n\n    companion object {\n        @Composable\n        fun default(): PatternHighlightTransformation {\n            val color = takeColorFromScheme {\n                primary.blend(primaryContainer, 0.1f)\n            }\n            val colorUpper = takeColorFromScheme {\n                tertiary.blend(tertiaryContainer, 0.1f)\n            }\n\n            return remember(color, colorUpper) {\n                PatternHighlightTransformation(\n                    mapOf(\n                        PATTERN_TOKENS to color,\n                        UPPER_PATTERN_TOKENS to colorUpper\n                    )\n                )\n            }\n        }\n    }\n\n}\n\nprivate val PATTERN_TOKENS = Regex(\n    \"\"\"\\\\[pwdhrcoimse](\\{[^}]*\\})?\"\"\"\n)\n\nprivate val UPPER_PATTERN_TOKENS = Regex(\n    \"\"\"\\\\[PDOIMSE](\\{[^}]*\\})?\"\"\"\n)\n\n@Preview\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(\n    isDarkTheme = true,\n    keyColor = Color.Blue\n) {\n    TextField(\n        value = FilenamePattern.Default + \"\\\\E\",\n        onValueChange = {},\n        visualTransformation = PatternHighlightTransformation.default()\n    )\n}\n\n@Preview\n@Composable\nprivate fun Preview1() = ImageToolboxThemeForPreview(\n    isDarkTheme = false,\n    keyColor = Color.Blue\n) {\n    TextField(\n        value = FilenamePattern.Default + \"\\\\E\",\n        onValueChange = {},\n        visualTransformation = PatternHighlightTransformation.default()\n    )\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/RoundedTextField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport android.annotation.SuppressLint\nimport androidx.compose.animation.Animatable\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsFocusedAsState\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.text.KeyboardActions\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.foundation.text.selection.TextSelectionColors\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TextField\nimport androidx.compose.material3.TextFieldColors\nimport androidx.compose.material3.TextFieldDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.focus.onFocusChanged\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport kotlinx.coroutines.cancel\nimport kotlinx.coroutines.launch\n\n@Composable\nfun RoundedTextField(\n    modifier: Modifier = Modifier,\n    onValueChange: (String) -> Unit,\n    label: String = \"\",\n    hint: String = \"\",\n    shape: Shape = ShapeDefaults.small,\n    startIcon: ImageVector? = null,\n    value: String,\n    isError: Boolean = false,\n    loading: Boolean = false,\n    supportingText: (@Composable (isError: Boolean) -> Unit)? = null,\n    supportingTextVisible: Boolean = true,\n    endIcon: (@Composable (Boolean) -> Unit)? = null,\n    formatText: String.() -> String = { this },\n    textStyle: TextStyle = LocalTextStyle.current,\n    onLoseFocusTransformation: String.() -> String = { this },\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = true,\n    readOnly: Boolean = false,\n    colors: TextFieldColors = RoundedTextFieldColors(isError),\n    enabled: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    minLines: Int = 1,\n    maxSymbols: Int = Int.MAX_VALUE\n) {\n    val labelImpl = @Composable {\n        Text(\n            text = label\n        )\n    }\n    val hintImpl = @Composable {\n        Text(text = hint, modifier = Modifier.padding(start = 4.dp))\n    }\n    val leadingIconImpl = @Composable {\n        Icon(\n            imageVector = startIcon!!,\n            contentDescription = null\n        )\n    }\n\n    RoundedTextField(\n        modifier = modifier,\n        value = value,\n        onValueChange = { onValueChange(it.formatText()) },\n        textStyle = textStyle,\n        colors = colors,\n        shape = shape,\n        singleLine = singleLine,\n        readOnly = readOnly,\n        keyboardOptions = keyboardOptions,\n        visualTransformation = visualTransformation,\n        endIcon = endIcon,\n        startIcon = if (startIcon != null) leadingIconImpl else null,\n        label = if (label.isNotEmpty()) labelImpl else null,\n        hint = if (hint.isNotEmpty()) hintImpl else null,\n        isError = isError,\n        loading = loading,\n        supportingText = supportingText,\n        supportingTextVisible = supportingTextVisible,\n        formatText = formatText,\n        onLoseFocusTransformation = onLoseFocusTransformation,\n        keyboardActions = keyboardActions,\n        enabled = enabled,\n        maxLines = maxLines,\n        interactionSource = interactionSource,\n        minLines = minLines,\n        maxSymbols = maxSymbols\n    )\n}\n\n@Composable\nfun RoundedTextField(\n    modifier: Modifier = Modifier,\n    onValueChange: (String) -> Unit,\n    label: (@Composable () -> Unit)? = null,\n    hint: (@Composable () -> Unit)? = null,\n    shape: Shape = ShapeDefaults.small,\n    startIcon: (@Composable () -> Unit)? = null,\n    value: String,\n    isError: Boolean = false,\n    loading: Boolean = false,\n    supportingText: (@Composable (isError: Boolean) -> Unit)? = null,\n    supportingTextVisible: Boolean = true,\n    endIcon: (@Composable (Boolean) -> Unit)? = null,\n    formatText: String.() -> String = { this },\n    textStyle: TextStyle = LocalTextStyle.current,\n    onLoseFocusTransformation: String.() -> String = { this },\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = true,\n    readOnly: Boolean = false,\n    colors: TextFieldColors = RoundedTextFieldColors(isError),\n    enabled: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    minLines: Int = 1,\n    maxSymbols: Int = Int.MAX_VALUE\n) {\n    val focus = LocalFocusManager.current\n    val focused = interactionSource.collectIsFocusedAsState().value\n\n    val colorScheme = MaterialTheme.colorScheme\n    val unfocusedColor = if (!enabled) colorScheme.outlineVariant(\n        onTopOf = colors.focusedContainerColor,\n        luminance = 0.2f\n    ) else colors.unfocusedIndicatorColor\n\n    val focusedColor = if (isError) {\n        colors.errorIndicatorColor\n    } else colors.focusedIndicatorColor\n\n    val borderColor by remember(focusedColor, enabled, focused) {\n        derivedStateOf {\n            Animatable(\n                initialValue = if (!focused) unfocusedColor\n                else focusedColor\n            )\n        }\n    }\n\n    val scope = rememberCoroutineScope()\n    LaunchedEffect(isError) {\n        borderColor.animateTo(if (focused) focusedColor else unfocusedColor)\n    }\n\n    val mergedModifier = Modifier\n        .fillMaxWidth()\n        .border(\n            width = animateDpAsState(\n                if (borderColor.value == unfocusedColor) 1.dp\n                else 2.dp\n            ).value,\n            color = borderColor.value,\n            shape = shape\n        )\n        .onFocusChanged {\n            scope.launch {\n                if (readOnly) {\n                    focus.clearFocus()\n                    cancel()\n                }\n                if (it.isFocused) borderColor.animateTo(focusedColor)\n                else {\n                    if (!isError) borderColor.animateTo(unfocusedColor)\n                    onValueChange(value.onLoseFocusTransformation())\n                }\n                cancel()\n            }\n        }\n        .animateContentSizeNoClip()\n\n    val supportingTextImpl = @Composable {\n        if (!loading && supportingText != null) {\n            supportingText(isError)\n        }\n    }\n\n    Column(\n        modifier = modifier.animateContentSizeNoClip()\n    ) {\n        val showSupportingText =\n            !loading && (isError || (supportingText != null && supportingTextVisible))\n        TextField(\n            modifier = mergedModifier.clip(shape),\n            value = value,\n            onValueChange = { onValueChange(it.take(maxSymbols).formatText()) },\n            textStyle = textStyle,\n            colors = colors,\n            shape = shape,\n            singleLine = singleLine,\n            readOnly = readOnly,\n            keyboardOptions = keyboardOptions,\n            visualTransformation = visualTransformation,\n            trailingIcon = endIcon?.let { { it(focused) } },\n            leadingIcon = startIcon,\n            label = label,\n            placeholder = hint,\n            keyboardActions = keyboardActions,\n            enabled = enabled,\n            maxLines = maxLines,\n            interactionSource = interactionSource,\n            minLines = minLines,\n        )\n        val showMaxSymbols = maxSymbols != Int.MAX_VALUE && value.isNotEmpty()\n\n        AnimatedVisibility(\n            visible = showSupportingText || showMaxSymbols,\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(top = 6.dp)\n                    .padding(horizontal = 8.dp)\n            ) {\n                if (showSupportingText) {\n                    ProvideTextStyle(\n                        LocalTextStyle.current.copy(\n                            color = MaterialTheme.colorScheme.error,\n                            fontSize = 12.sp,\n                            lineHeight = 12.sp,\n                        )\n                    ) {\n                        Row {\n                            supportingTextImpl()\n                            Spacer(modifier = Modifier.width(16.dp))\n                        }\n                    }\n                }\n                if (showMaxSymbols) {\n                    Text(\n                        text = \"${value.length} / $maxSymbols\",\n                        modifier = Modifier.weight(1f),\n                        textAlign = TextAlign.End,\n                        fontSize = 12.sp,\n                        lineHeight = 12.sp,\n                        color = borderColor.value\n                    )\n                }\n            }\n        }\n    }\n}\n\n@SuppressLint(\"ComposableNaming\")\n@Composable\nfun RoundedTextFieldColors(\n    isError: Boolean,\n    containerColor: Color = MaterialTheme.colorScheme.surfaceContainerHigh,\n    focusedIndicatorColor: Color = MaterialTheme.colorScheme.primary,\n    unfocusedIndicatorColor: Color = MaterialTheme.colorScheme.surfaceVariant.inverse({ 0.2f })\n): TextFieldColors =\n    MaterialTheme.colorScheme.run {\n        val containerColorNew = if (isError) {\n            containerColor.blend(error)\n        } else containerColor\n        TextFieldDefaults.colors(\n            focusedContainerColor = containerColorNew,\n            unfocusedContainerColor = containerColorNew,\n            disabledContainerColor = containerColorNew,\n            cursorColor = if (isError) error else focusedIndicatorColor,\n            focusedIndicatorColor = focusedIndicatorColor,\n            unfocusedIndicatorColor = unfocusedIndicatorColor,\n            focusedLeadingIconColor = if (isError) error else focusedIndicatorColor,\n            unfocusedLeadingIconColor = if (isError) error else surfaceVariant.inverse(),\n            focusedTrailingIconColor = if (isError) error else focusedIndicatorColor,\n            unfocusedTrailingIconColor = if (isError) error else surfaceVariant.inverse(),\n            focusedLabelColor = if (isError) error else focusedIndicatorColor,\n            unfocusedLabelColor = if (isError) error else MaterialTheme.colorScheme.onSurfaceVariant.copy(\n                0.9f\n            ),\n            selectionColors = TextSelectionColors(\n                handleColor = focusedIndicatorColor.copy(1f),\n                backgroundColor = focusedIndicatorColor.copy(0.4f)\n            )\n        )\n    }"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/TitleItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport android.annotation.SuppressLint\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.icons.Firebase\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\n\n@Composable\nfun TitleItem(\n    icon: ImageVector? = null,\n    text: String,\n    endContent: @Composable RowScope.() -> Unit,\n    @SuppressLint(\"ModifierParameter\")\n    modifier: Modifier = Modifier.padding(16.dp),\n) {\n    Row(\n        modifier = modifier,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        icon?.let { icon ->\n            IconShapeContainer(\n                content = {\n                    Icon(\n                        imageVector = icon,\n                        contentDescription = null\n                    )\n                }\n            )\n            Spacer(Modifier.width(8.dp))\n        }\n        Text(text = text, fontWeight = FontWeight.SemiBold, modifier = Modifier.weight(1f))\n        endContent.let {\n            Spacer(Modifier.width(8.dp))\n            it()\n        }\n    }\n}\n\n\n@Composable\nfun TitleItem(\n    icon: ImageVector? = null,\n    text: String,\n    modifier: Modifier = Modifier.padding(16.dp),\n    subtitle: String? = null,\n    iconEndPadding: Dp = 8.dp,\n    endContent: (@Composable RowScope.() -> Unit)? = null,\n    iconContainerColor: Color = IconShapeDefaults.containerColor,\n    iconContentColor: Color = IconShapeDefaults.contentColor,\n) {\n    Row(\n        modifier = modifier,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        icon?.let { icon ->\n            IconShapeContainer(\n                content = {\n                    Icon(\n                        imageVector = icon,\n                        contentDescription = null,\n                        tint = if (icon == Icons.TwoTone.Firebase) Color.Unspecified\n                        else LocalContentColor.current\n                    )\n                },\n                containerColor = iconContainerColor,\n                contentColor = iconContentColor\n            )\n            Spacer(Modifier.width(iconEndPadding))\n        }\n        Column(\n            modifier = Modifier.weight(1f, endContent != null)\n        ) {\n            Text(\n                text = text,\n                style = PreferenceItemDefaults.TitleFontStyle\n            )\n            subtitle?.let {\n                Spacer(modifier = Modifier.height(2.dp))\n                Text(\n                    text = subtitle,\n                    fontSize = 12.sp,\n                    textAlign = TextAlign.Start,\n                    fontWeight = FontWeight.Normal,\n                    lineHeight = 14.sp,\n                    color = LocalContentColor.current.copy(alpha = 0.5f)\n                )\n            }\n        }\n        endContent?.let {\n            Spacer(Modifier.width(8.dp))\n            it()\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/text/TopAppBarTitle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.text\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.buildAnnotatedString\nimport androidx.compose.ui.text.withStyle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.Green\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\n\n@Composable\nfun <T : Any> TopAppBarTitle(\n    title: String,\n    input: T?,\n    isLoading: Boolean,\n    size: Long?,\n    originalSize: Long? = null,\n    updateOnSizeChange: Boolean = true\n) {\n    if (updateOnSizeChange) {\n        AnimatedContent(\n            targetState = Triple(\n                input,\n                isLoading,\n                size\n            ),\n            transitionSpec = { fadeIn() togetherWith fadeOut() },\n            modifier = Modifier.marquee()\n        ) { (inp, loading, size) ->\n            if (loading) {\n                Text(\n                    stringResource(R.string.loading)\n                )\n            } else if (inp == null || size == null) {\n                AnimatedContent(targetState = title) {\n                    Text(it)\n                }\n            } else {\n                AnimatedContent(originalSize) { originalSize ->\n                    val readableOriginal = if ((originalSize ?: 0) > 0) {\n                        rememberHumanFileSize(originalSize ?: 0)\n                    } else {\n                        \"? B\"\n                    }\n                    val readableCompressed = if (size > 0) {\n                        rememberHumanFileSize(size)\n                    } else {\n                        \"(...)\"\n                    }\n                    val isSizesEqual =\n                        size == originalSize || readableCompressed == readableOriginal\n                    val color = takeColorFromScheme {\n                        when {\n                            isSizesEqual || originalSize == null -> onBackground\n                            size > originalSize -> error.blend(errorContainer)\n                            size <= 0 -> tertiary\n                            else -> Green\n                        }\n                    }\n\n                    val textStyle = LocalTextStyle.current\n                    val sizeString = stringResource(R.string.size, readableCompressed)\n\n                    val text by remember(\n                        originalSize,\n                        isSizesEqual,\n                        sizeString,\n                        readableOriginal,\n                        readableCompressed,\n                        textStyle\n                    ) {\n                        derivedStateOf {\n                            buildAnnotatedString {\n                                append(\n                                    if (originalSize == null || isSizesEqual) sizeString else \"\"\n                                )\n                                originalSize?.takeIf { !isSizesEqual }?.let {\n                                    append(readableOriginal)\n                                    append(\" -> \")\n                                    withStyle(textStyle.toSpanStyle().copy(color)) {\n                                        append(readableCompressed)\n                                    }\n                                }\n                            }\n                        }\n                    }\n\n                    Text(\n                        text = text\n                    )\n                }\n            }\n        }\n    } else {\n        AnimatedContent(\n            targetState = input to isLoading,\n            transitionSpec = { fadeIn() togetherWith fadeOut() },\n            modifier = Modifier.marquee()\n        ) { (inp, loading) ->\n            if (loading) {\n                Text(\n                    stringResource(R.string.loading)\n                )\n            } else if (inp == null || size == null || size <= 0) {\n                AnimatedContent(targetState = title) {\n                    Text(it)\n                }\n            } else {\n                val readableOriginal = rememberHumanFileSize(originalSize ?: 0)\n                val readableCompressed = rememberHumanFileSize(size)\n                val isSizesEqual =\n                    size == originalSize || readableCompressed == readableOriginal\n                val color = takeColorFromScheme {\n                    when {\n                        isSizesEqual || originalSize == null -> onBackground\n                        size > originalSize -> error.blend(errorContainer)\n                        else -> Green\n                    }\n                }\n\n                val textStyle = LocalTextStyle.current\n                val sizeString = stringResource(R.string.size, readableCompressed)\n\n                val text by remember(\n                    originalSize,\n                    isSizesEqual,\n                    sizeString,\n                    readableOriginal,\n                    readableCompressed,\n                    textStyle\n                ) {\n                    derivedStateOf {\n                        buildAnnotatedString {\n                            append(\n                                if (originalSize == null || isSizesEqual) sizeString else \"\"\n                            )\n                            originalSize?.takeIf { !isSizesEqual }?.let {\n                                append(readableOriginal)\n                                append(\" -> \")\n                                withStyle(textStyle.toSpanStyle().copy(color)) {\n                                    append(readableCompressed)\n                                }\n                            }\n                        }\n                    }\n                }\n\n                Text(\n                    text = text\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/utils/AutoContentBasedColors.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.utils\n\nimport android.graphics.Bitmap\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.isSpecified\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.toBitmap\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\nfun <T : Any> AutoContentBasedColors(\n    model: T?,\n    allowChangeColor: Boolean = true\n) {\n    AutoContentBasedColors(\n        model = model,\n        selector = {\n            appContext.imageLoader.execute(\n                ImageRequest.Builder(appContext).data(model).build()\n            ).image?.toBitmap()\n        },\n        allowChangeColor = allowChangeColor\n    )\n}\n\n@Composable\nfun <T : Any> AutoContentBasedColors(\n    model: T?,\n    selector: suspend (T) -> Bitmap?,\n    allowChangeColor: Boolean = true\n) {\n    val appColorTuple = rememberAppColorTuple()\n    val settingsState = LocalSettingsState.current\n    val themeState = LocalDynamicThemeState.current\n    val internalAllowChangeColor = settingsState.allowChangeColorByImage && allowChangeColor\n\n    LaunchedEffect(model, appColorTuple, internalAllowChangeColor) {\n        internalAllowChangeColor.takeIf { it }\n            ?.let {\n                model?.let { selector(it) }\n            }?.let {\n                themeState.updateColorByImage(it)\n            } ?: themeState.updateColorTuple(appColorTuple)\n    }\n}\n\n@Composable\nfun AutoContentBasedColors(\n    model: Bitmap?,\n    allowChangeColor: Boolean = true\n) {\n    AutoContentBasedColors(\n        model = model,\n        selector = { model },\n        allowChangeColor = allowChangeColor\n    )\n}\n\n@Composable\nfun AutoContentBasedColors(\n    model: Color,\n    allowChangeColor: Boolean = true\n) {\n    val appColorTuple = rememberAppColorTuple()\n    val settingsState = LocalSettingsState.current\n    val themeState = LocalDynamicThemeState.current\n    val internalAllowChangeColor = settingsState.allowChangeColorByImage && allowChangeColor\n\n    LaunchedEffect(model, appColorTuple, internalAllowChangeColor) {\n        internalAllowChangeColor.takeIf { it && model.isSpecified }\n            ?.let {\n                themeState.updateColor(model)\n            } ?: themeState.updateColorTuple(appColorTuple)\n    }\n}\n"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/utils/AvailableHeight.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.utils\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material3.BottomAppBar\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberCurrentLifecycleEvent\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageHeaderState\nimport com.t8rin.modalsheet.FullscreenPopup\n\n@Composable\nfun rememberAvailableHeight(\n    imageState: ImageHeaderState,\n    expanded: Boolean = false\n): Dp {\n    val fullHeight = rememberFullHeight()\n\n    return animateDpAsState(\n        targetValue = fullHeight.times(\n            when {\n                expanded || imageState.position == 4 -> 1f\n                imageState.position == 3 -> 0.7f\n                imageState.position == 2 -> 0.5f\n                imageState.position == 1 -> 0.35f\n                else -> 0.2f\n            }\n        )\n    ).value\n}\n\n@Composable\nfun rememberFullHeight(): Dp {\n    val screenSize = LocalScreenSize.current\n    val currentLifecycleEvent = rememberCurrentLifecycleEvent()\n    var fullHeight by remember(screenSize, currentLifecycleEvent) { mutableStateOf(0.dp) }\n\n    val density = LocalDensity.current\n\n    if (fullHeight == 0.dp) {\n        FullscreenPopup {\n            Column(\n                modifier = Modifier.fillMaxSize()\n            ) {\n                TopAppBar(\n                    title = { Text(\" \") },\n                    colors = EnhancedTopAppBarDefaults.colors(Color.Transparent)\n                )\n                Spacer(\n                    Modifier\n                        .weight(1f)\n                        .onSizeChanged {\n                            with(density) {\n                                fullHeight = it.height.toDp()\n                            }\n                        }\n                )\n                BottomAppBar(\n                    containerColor = Color.Transparent,\n                    floatingActionButton = {\n                        Spacer(Modifier.height(56.dp))\n                    },\n                    actions = {}\n                )\n            }\n        }\n    }\n\n    return fullHeight\n}\n\nfun ImageHeaderState.isExpanded() = this.position == 4 && isBlocked\n\nfun middleImageState() = ImageHeaderState()\n\n@Composable\nfun rememberImageState(): MutableState<ImageHeaderState> {\n    val settingsState = LocalSettingsState.current\n    return remember(settingsState.generatePreviews) {\n        mutableStateOf(\n            if (settingsState.generatePreviews) middleImageState()\n            else ImageHeaderState(0)\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/utils/RememberRetainedLazyListState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.utils\n\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.saveable.rememberSaveable\n\n/**\n * Static field, contains all scroll values\n */\nprivate val SaveMap = mutableMapOf<String, KeyParams>()\n\nprivate data class KeyParams(\n    val params: String,\n    val index: Int,\n    val scrollOffset: Int\n)\n\n/**\n * Save scroll state on all time.\n * @param key value for comparing screen\n * @param params arguments for find different between equals screen\n * @param initialFirstVisibleItemIndex see [LazyListState.firstVisibleItemIndex]\n * @param initialFirstVisibleItemScrollOffset see [LazyListState.firstVisibleItemScrollOffset]\n */\n@Composable\nfun rememberRetainedLazyListState(\n    key: String,\n    params: String = \"\",\n    initialFirstVisibleItemIndex: Int = 0,\n    initialFirstVisibleItemScrollOffset: Int = 0\n): LazyListState {\n    val scrollState = rememberSaveable(saver = LazyListState.Saver) {\n        var savedValue = SaveMap[key]\n        if (savedValue?.params != params) savedValue = null\n        val savedIndex = savedValue?.index ?: initialFirstVisibleItemIndex\n        val savedOffset = savedValue?.scrollOffset ?: initialFirstVisibleItemScrollOffset\n        LazyListState(\n            savedIndex,\n            savedOffset\n        )\n    }\n    DisposableEffect(Unit) {\n        onDispose {\n            val lastIndex = scrollState.firstVisibleItemIndex\n            val lastOffset = scrollState.firstVisibleItemScrollOffset\n            SaveMap[key] = KeyParams(params, lastIndex, lastOffset)\n        }\n    }\n    return scrollState\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/utils/ScreenList.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.utils\n\nimport android.net.Uri\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getExtension\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\n\n@Composable\ninternal fun List<Uri>.screenList(\n    extraDataType: ExtraDataType?\n): State<Pair<List<Screen>, List<Screen>>> {\n    val uris = this\n\n    fun Uri?.type(\n        vararg extensions: String\n    ): Boolean {\n        if (this == null) return false\n\n        val extension = getExtension() ?: return false\n\n        return extensions.any(extension::contains)\n    }\n\n    val filesAvailableScreens by remember(uris) {\n        derivedStateOf {\n            if (uris.size > 1) {\n                listOf(Screen.Zip(uris))\n            } else {\n                listOf(\n                    Screen.Cipher(uris.firstOrNull()),\n                    Screen.ChecksumTools(uris.firstOrNull()),\n                    Screen.Zip(uris)\n                )\n            }\n        }\n    }\n    val audioAvailableScreens by remember(uris) {\n        derivedStateOf {\n            listOf(\n                Screen.AudioCoverExtractor(uris)\n            ) + filesAvailableScreens\n        }\n    }\n    val gifAvailableScreens by remember(uris) {\n        derivedStateOf {\n            listOf(\n                Screen.GifTools(\n                    Screen.GifTools.Type.GifToImage(\n                        uris.firstOrNull()\n                    )\n                ),\n                Screen.GifTools(\n                    Screen.GifTools.Type.GifToJxl(uris)\n                ),\n                Screen.GifTools(\n                    Screen.GifTools.Type.GifToWebp(uris)\n                )\n            ) + filesAvailableScreens\n        }\n    }\n    val pdfAvailableScreens by remember(uris) {\n        derivedStateOf {\n            val multiplePdf = Screen.PdfTools.Merge(uris.takeIf { it.isNotEmpty() })\n\n            val pdfScreens = if (uris.size == 1) {\n                listOf(\n                    Screen.PdfTools.Preview(\n                        uris.firstOrNull()\n                    ),\n                    Screen.PdfTools.ExtractPages(\n                        uris.firstOrNull()\n                    ),\n                    multiplePdf,\n                    Screen.PdfTools.Split(uris.firstOrNull()),\n                    Screen.PdfTools.RemovePages(uris.firstOrNull()),\n                    Screen.PdfTools.Rotate(uris.firstOrNull()),\n                    Screen.PdfTools.Rearrange(uris.firstOrNull()),\n                    Screen.PdfTools.Crop(uris.firstOrNull()),\n                    Screen.PdfTools.PageNumbers(uris.firstOrNull()),\n                    Screen.PdfTools.Watermark(uris.firstOrNull()),\n                    Screen.PdfTools.Signature(uris.firstOrNull()),\n                    Screen.PdfTools.Compress(uris.firstOrNull()),\n                    Screen.PdfTools.RemoveAnnotations(uris.firstOrNull()),\n                    Screen.PdfTools.Flatten(uris.firstOrNull()),\n                    Screen.PdfTools.Print(uris.firstOrNull()),\n                    Screen.PdfTools.Grayscale(uris.firstOrNull()),\n                    Screen.PdfTools.Repair(uris.firstOrNull()),\n                    Screen.PdfTools.Protect(uris.firstOrNull()),\n                    Screen.PdfTools.Unlock(uris.firstOrNull()),\n                    Screen.PdfTools.Metadata(uris.firstOrNull()),\n                    Screen.PdfTools.ExtractImages(uris.firstOrNull()),\n                    Screen.PdfTools.OCR(uris.firstOrNull()),\n                    Screen.PdfTools.ZipConvert(uris.firstOrNull()),\n                )\n            } else {\n                listOf(multiplePdf)\n            }\n\n            pdfScreens + filesAvailableScreens\n        }\n    }\n    val singleImageScreens by remember(uris) {\n        derivedStateOf {\n            listOf(\n                Screen.SingleEdit(uris.firstOrNull()),\n                Screen.ResizeAndConvert(uris),\n                Screen.FormatConversion(uris),\n                Screen.WeightResize(uris),\n                Screen.Crop(uris.firstOrNull()),\n                Screen.Filter(\n                    type = Screen.Filter.Type.Basic(uris)\n                ),\n                Screen.Draw(uris.firstOrNull()),\n                Screen.RecognizeText(\n                    Screen.RecognizeText.Type.Extraction(uris.firstOrNull())\n                ),\n                Screen.EraseBackground(uris.firstOrNull()),\n                Screen.Filter(\n                    type = Screen.Filter.Type.Masking(uris.firstOrNull())\n                ),\n                Screen.AiTools(uris),\n                Screen.MarkupLayers(uris.firstOrNull()),\n                Screen.Watermarking(uris),\n                Screen.ImageStitching(uris),\n                Screen.ImageStacking(uris),\n                Screen.ImageSplitting(uris.firstOrNull()),\n                Screen.ImageCutter(uris),\n                Screen.ScanQrCode(uriToAnalyze = uris.firstOrNull()),\n                Screen.GradientMaker(uris),\n                Screen.PdfTools.ImagesToPdf(uris),\n                Screen.GifTools(\n                    Screen.GifTools.Type.ImageToGif(uris)\n                ),\n                Screen.Base64Tools(uris.firstOrNull()),\n                Screen.ImagePreview(uris),\n                Screen.PickColorFromImage(uris.firstOrNull()),\n                Screen.PaletteTools(uris.firstOrNull()),\n                Screen.AsciiArt(uris.firstOrNull()),\n                Screen.ApngTools(\n                    Screen.ApngTools.Type.ImageToApng(uris)\n                ),\n                Screen.JxlTools(\n                    Screen.JxlTools.Type.ImageToJxl(uris)\n                ),\n                Screen.SvgMaker(uris),\n                Screen.EditExif(uris.firstOrNull()),\n                Screen.DeleteExif(uris),\n                Screen.LimitResize(uris)\n            ).let { list ->\n                val mergedList = list + filesAvailableScreens\n\n                val uri = uris.firstOrNull()\n\n                if (uri.type(\"png\")) {\n                    mergedList + Screen.ApngTools(\n                        Screen.ApngTools.Type.ApngToImage(uris.firstOrNull())\n                    )\n                } else if (uri.type(\"jpg\", \"jpeg\")) {\n                    mergedList + Screen.JxlTools(\n                        Screen.JxlTools.Type.JpegToJxl(uris)\n                    )\n                } else if (uri.type(\"jxl\")) {\n                    mergedList + Screen.JxlTools(\n                        Screen.JxlTools.Type.JxlToJpeg(uris)\n                    ) + Screen.JxlTools(\n                        Screen.JxlTools.Type.JxlToImage(uris.firstOrNull())\n                    )\n                } else if (uri.type(\"webp\")) {\n                    mergedList + Screen.WebpTools(\n                        Screen.WebpTools.Type.WebpToImage(uris.firstOrNull())\n                    )\n                } else mergedList\n            }\n        }\n    }\n    val multipleImageScreens by remember(uris) {\n        derivedStateOf {\n            mutableListOf(\n                Screen.ResizeAndConvert(uris),\n                Screen.WeightResize(uris),\n                Screen.FormatConversion(uris),\n                Screen.Filter(\n                    type = Screen.Filter.Type.Basic(uris)\n                ),\n            ).apply {\n                add(Screen.ImageStitching(uris))\n                add(Screen.PdfTools.ImagesToPdf(uris))\n                if (uris.size == 2) add(Screen.Compare(uris))\n                if (uris.size in 1..20) {\n                    add(Screen.CollageMaker(uris))\n                }\n                add(Screen.AiTools(uris))\n                add(Screen.GradientMaker(uris))\n                add(\n                    Screen.RecognizeText(\n                        Screen.RecognizeText.Type.WriteToFile(uris)\n                    )\n                )\n                add(\n                    Screen.RecognizeText(\n                        Screen.RecognizeText.Type.WriteToMetadata(uris)\n                    )\n                )\n                add(\n                    Screen.RecognizeText(\n                        Screen.RecognizeText.Type.WriteToSearchablePdf(uris)\n                    )\n                )\n                add(Screen.Watermarking(uris))\n                add(\n                    Screen.GifTools(\n                        Screen.GifTools.Type.ImageToGif(uris)\n                    )\n                )\n                add(Screen.ImageStacking(uris))\n                add(Screen.ImageCutter(uris))\n                add(Screen.ImagePreview(uris))\n                add(Screen.LimitResize(uris))\n                addAll(filesAvailableScreens)\n                add(Screen.SvgMaker(uris))\n\n                var haveJpeg = false\n                var haveJxl = false\n\n                for (uri in uris) {\n                    if (uri.type(\"jpg\", \"jpeg\")) {\n                        haveJpeg = true\n                    } else if (uri.type(\"jxl\")) {\n                        haveJxl = true\n                    }\n                    if (haveJpeg && haveJxl) break\n                }\n\n                if (haveJpeg) {\n                    add(\n                        Screen.JxlTools(\n                            Screen.JxlTools.Type.JpegToJxl(uris)\n                        )\n                    )\n                } else if (haveJxl) {\n                    add(\n                        Screen.JxlTools(\n                            Screen.JxlTools.Type.JxlToJpeg(uris)\n                        )\n                    )\n                    add(\n                        Screen.JxlTools(\n                            Screen.JxlTools.Type.JxlToImage(uris.firstOrNull())\n                        )\n                    )\n                }\n                add(\n                    Screen.JxlTools(\n                        Screen.JxlTools.Type.ImageToJxl(uris)\n                    )\n                )\n                add(\n                    Screen.ApngTools(\n                        Screen.ApngTools.Type.ImageToApng(uris)\n                    )\n                )\n                add(\n                    Screen.WebpTools(\n                        Screen.WebpTools.Type.ImageToWebp(uris)\n                    )\n                )\n                add(Screen.DeleteExif(uris))\n            }\n        }\n    }\n    val imageScreens by remember(uris) {\n        derivedStateOf {\n            if (uris.size == 1) singleImageScreens\n            else multipleImageScreens\n        }\n    }\n\n    val textAvailableScreens by remember(extraDataType) {\n        derivedStateOf {\n            val text = (extraDataType as? ExtraDataType.Text)?.text ?: \"\"\n            listOf(\n                Screen.ScanQrCode(text),\n                Screen.LoadNetImage(text)\n            )\n        }\n    }\n\n    val settingsState = LocalSettingsState.current\n    val favoriteScreens = settingsState.favoriteScreenList\n    val hiddenForShareScreens = settingsState.hiddenForShareScreens\n    val screenOrder = settingsState.screenList\n\n    return remember(\n        favoriteScreens,\n        extraDataType,\n        uris,\n        pdfAvailableScreens,\n        audioAvailableScreens,\n        imageScreens,\n        hiddenForShareScreens\n    ) {\n        derivedStateOf {\n            val baseScreens = when (extraDataType) {\n                is ExtraDataType.Backup -> filesAvailableScreens\n                is ExtraDataType.Text -> textAvailableScreens\n                ExtraDataType.Audio -> audioAvailableScreens\n                ExtraDataType.File -> filesAvailableScreens\n                ExtraDataType.Gif -> gifAvailableScreens\n                ExtraDataType.Pdf -> pdfAvailableScreens\n                null -> imageScreens\n            }\n\n            val orderIndex = screenOrder.withIndex().associate { it.value to it.index }\n            val favSet = favoriteScreens.toSet()\n\n            val allScreens = baseScreens\n                .sortedWith(\n                    compareByDescending<Screen> { it.id in favSet }\n                        .thenBy { orderIndex[it.id] ?: Int.MAX_VALUE }\n                )\n\n            allScreens.partition { it.id !in hiddenForShareScreens }\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/value/ValueDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.value\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.text.style.TextAlign\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Counter\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport kotlin.math.pow\nimport kotlin.math.roundToInt\n\n@Composable\nfun ValueDialog(\n    roundTo: Int?,\n    valueRange: ClosedFloatingPointRange<Float>,\n    valueState: String,\n    expanded: Boolean,\n    onDismiss: () -> Unit,\n    onValueUpdate: (Float) -> Unit\n) {\n    var value by remember(valueState, expanded) { mutableStateOf(valueState.trimTrailingZero()) }\n    EnhancedAlertDialog(\n        visible = expanded,\n        modifier = Modifier.clearFocusOnTap(),\n        onDismissRequest = onDismiss,\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.Counter,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(\n                stringResource(\n                    R.string.value_in_range,\n                    valueRange.start.toString().trimTrailingZero(),\n                    valueRange.endInclusive.toString().trimTrailingZero()\n                )\n            )\n        },\n        text = {\n            Column(\n                modifier = Modifier.fillMaxWidth(),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                OutlinedTextField(\n                    shape = ShapeDefaults.default,\n                    value = value,\n                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),\n                    textStyle = MaterialTheme.typography.titleMedium.copy(textAlign = TextAlign.Center),\n                    maxLines = 1,\n                    onValueChange = { number ->\n                        value = number.filterDecimal()\n                    }\n                )\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    onDismiss()\n                    onValueUpdate(\n                        (value.toFloatOrNull() ?: 0f).roundTo(roundTo).coerceIn(valueRange)\n                    )\n                },\n            ) {\n                Text(stringResource(R.string.ok))\n            }\n        }\n    )\n}\n\nfun String.filterDecimal(): String {\n    var tempS = trim {\n        it !in listOf(\n            '1',\n            '2',\n            '3',\n            '4',\n            '5',\n            '6',\n            '7',\n            '8',\n            '9',\n            '0',\n            '.',\n            '-'\n        )\n    }\n    tempS = (if (tempS.firstOrNull() == '-') \"-\" else \"\").plus(\n        tempS.replace(\"-\", \"\")\n    )\n    val temp = tempS.split(\".\")\n    return when (temp.size) {\n        1 -> temp[0]\n        2 -> temp[0] + \".\" + temp[1]\n        else -> {\n            temp[0] + \".\" + temp[1] + temp.drop(2).joinToString(\"\")\n        }\n    }\n}\n\nprivate fun Float.roundTo(\n    digits: Int? = 2\n) = digits?.let {\n    (this * 10f.pow(digits)).roundToInt() / (10f.pow(digits))\n} ?: this"
  },
  {
    "path": "core/ui/src/main/kotlin/com/t8rin/imagetoolbox/core/ui/widget/value/ValueText.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.value\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun ValueText(\n    modifier: Modifier = Modifier.padding(\n        top = 8.dp,\n        end = 8.dp\n    ),\n    value: Number,\n    enabled: Boolean = true,\n    valueSuffix: String = \"\",\n    customText: String? = null,\n    onClick: (() -> Unit)?,\n    backgroundColor: Color = MaterialTheme.colorScheme.secondaryContainer.copy(\n        0.25f\n    )\n) {\n    val text by remember(customText, value, valueSuffix) {\n        derivedStateOf {\n            customText ?: \"${value.toString().trimTrailingZero()}$valueSuffix\"\n        }\n    }\n    val interactionSource = remember { MutableInteractionSource() }\n\n    val shape = shapeByInteraction(\n        shape = AutoCircleShape(),\n        pressedShape = ButtonDefaults.pressedShape,\n        interactionSource = interactionSource\n    )\n    ProvideContainerDefaults(\n        color = LocalContainerColor.current\n    ) {\n        AnimatedContent(\n            targetState = text,\n            transitionSpec = { fadeIn(tween(100)) togetherWith fadeOut(tween(100)) },\n            modifier = modifier\n                .container(\n                    shape = shape,\n                    color = backgroundColor,\n                    resultPadding = 0.dp,\n                    autoShadowElevation = if (enabled) 0.7.dp else 0.dp\n                )\n        ) {\n            AutoSizeText(\n                text = it,\n                color = LocalContentColor.current.copy(0.5f),\n                textAlign = TextAlign.Center,\n                modifier = Modifier\n                    .then(\n                        if (onClick != null) {\n                            Modifier.hapticsClickable(\n                                enabled = enabled,\n                                onClick = onClick,\n                                interactionSource = interactionSource,\n                                indication = LocalIndication.current\n                            )\n                        } else Modifier\n                    )\n                    .padding(horizontal = 16.dp, vertical = 6.dp),\n                lineHeight = 18.sp\n            )\n        }\n    }\n}"
  },
  {
    "path": "core/ui/src/market/java/com/t8rin/imagetoolbox/core/ui/utils/content_pickers/DocumentScannerImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.content_pickers\n\nimport android.app.Activity\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.ActivityResult\nimport androidx.activity.result.IntentSenderRequest\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport com.google.mlkit.vision.documentscanner.GmsDocumentScannerOptions\nimport com.google.mlkit.vision.documentscanner.GmsDocumentScanning\nimport com.google.mlkit.vision.documentscanner.GmsDocumentScanningResult\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ScanResult\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\n\nprivate class DocumentScannerImpl(\n    private val context: ComponentActivity,\n    private val scannerLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>,\n    private val onFailure: (Throwable) -> Unit\n) : DocumentScanner {\n\n    override fun scan() {\n        val options = GmsDocumentScannerOptions.Builder()\n            .setGalleryImportAllowed(true)\n            .setResultFormats(\n                GmsDocumentScannerOptions.RESULT_FORMAT_JPEG,\n                GmsDocumentScannerOptions.RESULT_FORMAT_PDF\n            )\n            .setScannerMode(GmsDocumentScannerOptions.SCANNER_MODE_FULL)\n            .build()\n\n        val scanner = GmsDocumentScanning.getClient(options)\n\n        scanner.getStartScanIntent(context)\n            .addOnSuccessListener { intentSender ->\n                scannerLauncher.launch(IntentSenderRequest.Builder(intentSender).build())\n            }\n            .addOnFailureListener(onFailure)\n    }\n\n}\n\n@Composable\ninternal fun rememberDocumentScannerImpl(\n    onSuccess: (ScanResult) -> Unit\n): DocumentScanner {\n    val context = LocalComponentActivity.current\n\n    val scannerLauncher = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.StartIntentSenderForResult()\n    ) { result ->\n        if (result.resultCode == Activity.RESULT_OK) {\n            runCatching {\n                GmsDocumentScanningResult.fromActivityResultIntent(result.data)?.apply {\n                    onSuccess(\n                        ScanResult(\n                            imageUris = pages?.let { pages ->\n                                pages.map { it.imageUri }\n                            } ?: emptyList(),\n                            pdfUri = pdf?.uri\n                        )\n                    )\n                }\n            }.onFailure(AppToastHost::showFailureToast)\n        }\n    }\n\n    return remember(context, scannerLauncher) {\n        DocumentScannerImpl(\n            context = context,\n            scannerLauncher = scannerLauncher,\n            onFailure = AppToastHost::showFailureToast\n        )\n    }\n}"
  },
  {
    "path": "core/ui/src/market/java/com/t8rin/imagetoolbox/core/ui/utils/helper/ReviewHandlerImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.utils.helper\n\nimport android.app.Activity\nimport com.google.android.play.core.review.ReviewManagerFactory\nimport com.t8rin.logger.makeLog\n\ninternal object ReviewHandlerImpl : ReviewHandler() {\n\n    override fun showReview(activity: Activity) {\n        runCatching {\n            ReviewManagerFactory.create(activity).let { reviewManager ->\n                reviewManager\n                    .requestReviewFlow()\n                    .addOnCompleteListener {\n                        if (it.isSuccessful) {\n                            reviewManager.launchReviewFlow(activity, it.result)\n                        }\n                    }\n            }\n        }.onFailure {\n            it.makeLog(\"showReview\")\n        }\n    }\n\n}"
  },
  {
    "path": "core/ui/src/market/java/com/t8rin/imagetoolbox/core/ui/widget/sheets/UpdateSheetImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.ui.widget.sheets\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileDownloadOff\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport com.google.android.play.core.appupdate.AppUpdateManagerFactory\nimport com.google.android.play.core.appupdate.AppUpdateOptions\nimport com.google.android.play.core.install.model.AppUpdateType\nimport com.google.android.play.core.install.model.UpdateAvailability\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isInstalledFromPlayStore\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\ninternal fun UpdateSheetImpl(\n    changelog: String,\n    tag: String,\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    val context = LocalComponentActivity.current\n\n    if (context.isInstalledFromPlayStore()) {\n        LaunchedEffect(visible) {\n            if (visible) {\n                runCatching {\n                    val appUpdateManager = AppUpdateManagerFactory.create(context)\n\n                    val appUpdateInfoTask = appUpdateManager.appUpdateInfo\n\n                    appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->\n                        if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE\n                            && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)\n                        ) {\n                            appUpdateManager.startUpdateFlow(\n                                appUpdateInfo,\n                                context,\n                                AppUpdateOptions.defaultOptions(AppUpdateType.IMMEDIATE)\n                            )\n                        } else {\n                            AppToastHost.showToast(\n                                icon = Icons.Rounded.FileDownloadOff,\n                                message = getString(R.string.no_updates)\n                            )\n                        }\n                    }\n                }.onFailure {\n                    AppToastHost.showToast(\n                        icon = Icons.Rounded.FileDownloadOff,\n                        message = getString(R.string.no_updates)\n                    )\n                }\n            }\n        }\n    } else {\n        DefaultUpdateSheet(\n            changelog = changelog,\n            tag = tag,\n            visible = visible,\n            onDismiss = onDismiss\n        )\n    }\n}"
  },
  {
    "path": "core/utils/.gitignore",
    "content": "/build"
  },
  {
    "path": "core/utils/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.core.utils\"\n\ndependencies {\n    implementation(projects.core.domain)\n    implementation(projects.core.resources)\n    implementation(projects.core.settings)\n    implementation(libs.logger)\n    implementation(libs.androidx.documentfile)\n    \"marketImplementation\"(libs.quickie.bundled)\n    \"fossImplementation\"(libs.quickie.foss)\n    implementation(libs.zxing.core)\n}"
  },
  {
    "path": "core/utils/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "core/utils/src/main/java/com/t8rin/imagetoolbox/core/utils/AppContext.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.utils\n\nimport android.content.Context\nimport android.content.ContextWrapper\nimport androidx.annotation.StringRes\n\nclass AppContext private constructor(\n    application: Context\n) : ContextWrapper(application) {\n\n    companion object {\n        internal var appContext: AppContext? = null\n\n        internal fun init(application: Context) {\n            appContext = AppContext(application)\n        }\n    }\n\n}\n\nfun Context.initAppContext() = AppContext.init(this)\n\nval appContext: AppContext\n    get() = checkNotNull(AppContext.appContext) {\n        \"AppContext not initialized\"\n    }\n\nfun getString(@StringRes resId: Int): String = appContext.getString(resId)\n\nfun getString(\n    @StringRes resId: Int,\n    vararg formatArgs: Any?\n): String = appContext.getString(resId, *formatArgs)"
  },
  {
    "path": "core/utils/src/main/java/com/t8rin/imagetoolbox/core/utils/QrType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.utils\n\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.model.QrType.Wifi.EncryptionType\nimport io.github.g00fy2.quickie.content.QRContent\nimport io.github.g00fy2.quickie.content.QRContent.CalendarEvent.CalendarDateTime\nimport io.github.g00fy2.quickie.content.QRContent.ContactInfo.Address.AddressType\nimport io.github.g00fy2.quickie.content.QRContent.Email.EmailType\nimport io.github.g00fy2.quickie.content.QRContent.Phone.PhoneType\nimport io.github.g00fy2.quickie.extensions.DataType\nimport java.util.Calendar\nimport java.util.Date\n\nfun QRContent.toQrType(): QrType {\n    val raw = rawValue ?: rawBytes?.toString(Charsets.UTF_8).orEmpty()\n\n    if (raw.startsWith(\"geo:\", true)) {\n        val data = raw.drop(4).split(\";\")\n        return QrType.Geo(\n            raw = raw,\n            latitude = data.getOrNull(0)?.toDoubleOrNull(),\n            longitude = data.getOrNull(1)?.toDoubleOrNull()\n        )\n    }\n\n    return when (this) {\n        is QRContent.Plain -> QrType.Plain(raw)\n\n        is QRContent.Wifi -> QrType.Wifi(\n            raw = raw,\n            ssid = ssid,\n            password = password,\n            encryptionType = EncryptionType.entries.getOrNull(encryptionType - 1)\n                ?: EncryptionType.OPEN\n        )\n\n        is QRContent.Url -> QrType.Url(\n            raw = raw,\n            title = title,\n            url = url\n        )\n\n        is QRContent.Sms -> QrType.Sms(\n            raw = raw,\n            message = message,\n            phoneNumber = phoneNumber\n        )\n\n        is QRContent.GeoPoint -> QrType.Geo(\n            raw = raw,\n            latitude = lat,\n            longitude = lng\n        )\n\n        is QRContent.Email -> QrType.Email(\n            raw = raw,\n            address = address,\n            body = body,\n            subject = subject,\n            type = type.toData()\n        )\n\n        is QRContent.Phone -> QrType.Phone(\n            raw = raw,\n            number = number,\n            type = type.toData()\n        )\n\n        is QRContent.ContactInfo -> QrType.Contact(\n            raw = raw,\n            addresses = addresses.map {\n                QrType.Contact.Address(\n                    addressLines = it.addressLines,\n                    type = it.type.toData()\n                )\n            },\n            emails = emails.map {\n                QrType.Email(\n                    raw = raw,\n                    address = it.address,\n                    body = it.body,\n                    subject = it.subject,\n                    type = it.type.toData()\n                )\n            },\n            name = QrType.Contact.PersonName(\n                first = name.first,\n                formattedName = name.formattedName,\n                last = name.last,\n                middle = name.middle,\n                prefix = name.prefix,\n                pronunciation = name.pronunciation,\n                suffix = name.suffix\n            ),\n            organization = organization,\n            phones = phones.map {\n                QrType.Phone(\n                    raw = raw,\n                    number = it.number,\n                    type = it.type.toData()\n                )\n            },\n            title = title,\n            urls = urls\n        )\n\n        is QRContent.CalendarEvent -> QrType.Calendar(\n            raw = raw,\n            description = description,\n            end = end.toDate(),\n            location = location,\n            organizer = organizer,\n            start = start.toDate(),\n            status = status,\n            summary = summary\n        )\n    }\n}\n\nprivate fun PhoneType.toData(): Int = when (this) {\n    PhoneType.WORK -> DataType.TYPE_WORK\n    PhoneType.HOME -> DataType.TYPE_HOME\n    PhoneType.FAX -> DataType.TYPE_FAX\n    PhoneType.MOBILE -> DataType.TYPE_MOBILE\n    else -> DataType.TYPE_UNKNOWN\n}\n\nprivate fun AddressType.toData(): Int = when (this) {\n    AddressType.WORK -> DataType.TYPE_WORK\n    AddressType.HOME -> DataType.TYPE_HOME\n    else -> DataType.TYPE_UNKNOWN\n}\n\nprivate fun EmailType.toData(): Int = when (this) {\n    EmailType.WORK -> DataType.TYPE_WORK\n    EmailType.HOME -> DataType.TYPE_HOME\n    else -> DataType.TYPE_UNKNOWN\n}\n\nprivate fun CalendarDateTime.toDate(): Date {\n    val cal = Calendar.getInstance().apply {\n        set(Calendar.YEAR, year)\n        set(Calendar.MONTH, month - 1)\n        set(Calendar.DAY_OF_MONTH, day)\n        set(Calendar.HOUR_OF_DAY, hours)\n        set(Calendar.MINUTE, minutes)\n        set(Calendar.SECOND, seconds)\n        set(Calendar.MILLISECOND, 0)\n    }\n    return cal.time\n}"
  },
  {
    "path": "core/utils/src/main/java/com/t8rin/imagetoolbox/core/utils/Typeface.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.utils\n\nimport android.graphics.Typeface\nimport androidx.core.content.res.ResourcesCompat\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FontType\n\nfun FontType?.toTypeface(): Typeface? = when (this) {\n    null -> null\n    is FontType.File -> Typeface.createFromFile(this.path)\n    is FontType.Resource -> ResourcesCompat.getFont(\n        appContext,\n        this.resId\n    )\n}"
  },
  {
    "path": "core/utils/src/main/java/com/t8rin/imagetoolbox/core/utils/Update.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.utils\n\nimport com.t8rin.imagetoolbox.core.domain.utils.cast\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\nimport org.w3c.dom.Element\nimport java.io.InputStream\nimport javax.xml.parsers.DocumentBuilderFactory\n\nfun isNeedUpdate(\n    updateName: String,\n    allowBetas: Boolean\n): Boolean {\n    val currentName = BuildConfig.VERSION_NAME\n    val betaList = listOf(\n        \"alpha\", \"beta\", \"rc\"\n    )\n\n    val currentVersionCodeString = currentName.toVersionCodeString(betaList)\n    val updateVersionCodeString = updateName.toVersionCodeString(betaList)\n\n    val maxLength = maxOf(currentVersionCodeString.length, updateVersionCodeString.length)\n\n    val currentVersionCode = currentVersionCodeString.padEnd(maxLength, '0').toIntOrNull() ?: -1\n    val updateVersionCode = updateVersionCodeString.padEnd(maxLength, '0').toIntOrNull() ?: -1\n\n    return if (!updateName.startsWith(currentName)) {\n        if (betaList.all { it !in updateName }) {\n            updateVersionCode > currentVersionCode\n        } else {\n            if (allowBetas || betaList.any { it in currentName }) {\n                updateVersionCode > currentVersionCode\n            } else false\n        }\n    } else false\n}\n\nfun InputStream.parseChangelog(): Changelog {\n    var tag = \"\"\n    var changelog = \"\"\n\n    val tree = DocumentBuilderFactory.newInstance()\n        .newDocumentBuilder().parse(this)\n        .getElementsByTagName(\"feed\")\n\n    repeat(tree.length) {\n        val line = tree.item(it).cast<Element>()\n            .getElementsByTagName(\"entry\").item(0)\n            .cast<Element>()\n\n        tag = line.getElementsByTagName(\"title\").item(0).textContent\n        changelog = line.getElementsByTagName(\"content\").item(0).textContent\n    }\n\n    return Changelog(\n        tag = tag,\n        changelog = changelog\n    )\n}\n\ndata class Changelog(\n    val tag: String,\n    val changelog: String\n)\n\nprivate fun String.toVersionCodeString(betaList: List<String>): String {\n    return replace(\n        regex = Regex(\"0\\\\d\"),\n        transform = {\n            it.value.replace(\"0\", \"\")\n        }\n    ).replace(\"-\", \"\")\n        .replace(\".\", \"\")\n        .replace(\"_\", \"\")\n        .let { version ->\n            if (betaList.any { it in version }) version\n            else version + \"4\"\n        }\n        .replace(\"alpha\", \"1\")\n        .replace(\"beta\", \"2\")\n        .replace(\"rc\", \"3\")\n        .replace(\"foss\", \"\")\n        .replace(\"jxl\", \"\")\n}"
  },
  {
    "path": "core/utils/src/main/java/com/t8rin/imagetoolbox/core/utils/UriUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.utils\n\nimport android.content.ContentResolver\nimport android.content.ContentUris\nimport android.content.Context\nimport android.net.Uri\nimport android.os.Build\nimport android.provider.DocumentsContract\nimport android.provider.MediaStore\nimport android.provider.OpenableColumns\nimport android.webkit.MimeTypeMap\nimport androidx.core.net.toFile\nimport androidx.core.net.toUri\nimport androidx.documentfile.provider.DocumentFile\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.SortType\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.sortedByKey\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.channelFlow\nimport kotlinx.coroutines.flow.filterIsInstance\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.map\nimport java.net.URLDecoder\nimport java.net.URLEncoder\nimport java.util.LinkedList\nimport java.util.Locale\n\nfun Uri?.uiPath(\n    default: String\n): String = this?.let { uri ->\n    if (DocumentFile.isDocumentUri(appContext, uri)) {\n        DocumentFile.fromSingleUri(appContext, uri)\n    } else {\n        DocumentFile.fromTreeUri(appContext, uri)\n    }?.uri?.path?.split(\":\")\n        ?.lastOrNull()?.let { p ->\n            val endPath = p.takeIf {\n                it.isNotEmpty()\n            }?.let { \"/$it\" } ?: \"\"\n            val startPath = if (\n                uri.toString()\n                    .split(\"%\")[0]\n                    .contains(\"primary\")\n            ) appContext.getString(R.string.device_storage)\n            else appContext.getString(R.string.external_storage)\n\n            startPath + endPath\n        }?.decodeEscaped()\n} ?: default\n\nfun Uri.lastModified(): Long? = tryExtractOriginal().run {\n    runCatching {\n        if (this.toString().startsWith(\"file:///\")) {\n            return toFile().lastModified()\n        }\n\n        with(appContext.contentResolver) {\n            val query = query(this@lastModified, null, null, null, null)\n\n            query?.use { cursor ->\n                if (cursor.moveToFirst()) {\n                    val columnNames = listOf(\n                        DocumentsContract.Document.COLUMN_LAST_MODIFIED,\n                        \"datetaken\", // When sharing an Image from Google Photos into the app.\n                    )\n\n                    val millis = columnNames.firstNotNullOfOrNull {\n                        val index = cursor.getColumnIndex(it)\n                        if (!cursor.isNull(index)) {\n                            cursor.getLong(index)\n                        } else {\n                            null\n                        }\n                    }\n\n                    return millis\n                }\n            }\n        }\n\n        return DocumentFile.fromSingleUri(appContext, this)?.lastModified()\n    }.onFailure { it.printStackTrace() }\n\n    return null\n}\n\nfun Uri.path(): String? = tryExtractOriginal().run {\n    getStringColumn(MediaStore.MediaColumns.DATA)?.takeIf {\n        \".transforms\" !in it\n    }.orEmpty().ifEmpty {\n        runCatching {\n            val path = DocumentFile.fromSingleUri(appContext, this)?.uri?.path?.split(\":\")\n                ?.lastOrNull() ?: return@run null\n\n            if (\"cloud\" in path) {\n                \"/cloud/${path.substringAfterLast('/')}\"\n            } else {\n                path\n            }\n        }.getOrNull()\n    }\n}\n\nfun Uri.dateAdded(): Long? = tryExtractOriginal().run {\n    getLongColumn(MediaStore.MediaColumns.DATE_ADDED)?.times(1000)\n}\n\nfun Uri.filename(\n    context: Context = appContext\n): String? = tryExtractOriginal().run {\n    if (this.toString().startsWith(\"file:///\")) {\n        this.toString().takeLastWhile { it != '/' }\n    } else {\n        DocumentFile.fromSingleUri(context, this)?.name\n    }?.decodeEscaped()\n}\n\nfun Uri.extension(\n    context: Context = appContext\n): String? {\n    val filename = filename(context) ?: \"\"\n    if (filename.endsWith(\".qoi\")) return \"qoi\"\n    if (filename.endsWith(\".jxl\")) return \"jxl\"\n    return if (ContentResolver.SCHEME_CONTENT == scheme) {\n        MimeTypeMap.getSingleton()\n            .getExtensionFromMimeType(\n                context.contentResolver.getType(this)\n            )\n    } else {\n        MimeTypeMap.getFileExtensionFromUrl(this.toString()).lowercase(Locale.getDefault())\n    }?.replace(\".\", \"\")\n}\n\nfun Uri.fileSize(): Long? = tryExtractOriginal().run {\n    if (this.scheme == \"content\") {\n        runCatching {\n            appContext.contentResolver\n                .query(this, null, null, null, null, null)\n                .use { cursor ->\n                    if (cursor != null && cursor.moveToFirst()) {\n                        val sizeIndex: Int = cursor.getColumnIndex(OpenableColumns.SIZE)\n                        if (!cursor.isNull(sizeIndex)) {\n                            return cursor.getLong(sizeIndex)\n                        }\n                    }\n                }\n        }\n    } else {\n        runCatching {\n            return this.toFile().length()\n        }\n    }\n    return null\n}\n\nfun Uri.tryExtractOriginal(): Uri = try {\n    if (\"com.android.externalstorage.documents\" in this.toString()) {\n        return this.makeLog(\"tryExtractOriginal\") { \"already ok - $it\" }\n    }\n\n    val mimeType = getStringColumn(MediaStore.MediaColumns.MIME_TYPE).orEmpty()\n\n    val contentUri = when {\n        \"image\" in mimeType -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI\n        \"video\" in mimeType -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI\n        \"audio\" in mimeType -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI\n        else -> return this\n    }\n\n    ContentUris.withAppendedId(\n        contentUri,\n        this.toString().decodeEscaped().substringAfterLast('/').filter { it.isDigit() }.toLong()\n    )\n} catch (e: Throwable) {\n    e.makeLog(\"tryExtractOriginal\")\n    this.makeLog(\"tryExtractOriginal\") { \"failed - $it\" }\n}\n\nsuspend fun List<Uri>.sortedByType(\n    sortType: SortType,\n): List<Uri> = coroutineScope {\n    when (sortType) {\n        SortType.DateModified -> sortedByDateModified()\n        SortType.DateModifiedReversed -> sortedByDateModified(descending = true)\n        SortType.Name -> sortedByName()\n        SortType.NameReversed -> sortedByName(descending = true)\n        SortType.Size -> sortedBySize()\n        SortType.SizeReversed -> sortedBySize(descending = true)\n        SortType.MimeType -> sortedByMimeType()\n        SortType.MimeTypeReversed -> sortedByMimeType(descending = true)\n        SortType.Extension -> sortedByExtension()\n        SortType.ExtensionReversed -> sortedByExtension(descending = true)\n        SortType.DateAdded -> sortedByDateAdded()\n        SortType.DateAddedReversed -> sortedByDateAdded(descending = true)\n    }\n}\n\nfun ImageModel.toUri(): Uri? = when (data) {\n    is Uri -> data as Uri\n    is String -> (data as String).toUri()\n    else -> null\n}\n\nfun Any.toImageModel() = ImageModel(this)\n\nfun String.toFileModel() = FileModel(this)\n\nfun String.decodeEscaped(): String = runCatching {\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n        URLDecoder.decode(URLDecoder.decode(this, Charsets.UTF_8), Charsets.UTF_8)\n    } else {\n        @Suppress(\"DEPRECATION\")\n        URLDecoder.decode(URLDecoder.decode(this))\n    }\n}.getOrDefault(this)\n\nfun String.encodeEscaped(): String {\n    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n        URLEncoder.encode(this, Charsets.UTF_8)\n    } else {\n        @Suppress(\"DEPRECATION\")\n        URLEncoder.encode(this)\n    }\n}\n\nfun Uri.isApng(): Boolean {\n    return filename().toString().endsWith(\".png\")\n        .or(appContext.contentResolver.getType(this)?.contains(\"png\") == true)\n        .or(appContext.contentResolver.getType(this)?.contains(\"apng\") == true)\n}\n\nfun Uri.isWebp(): Boolean {\n    return filename().toString().endsWith(\".webp\")\n        .or(appContext.contentResolver.getType(this)?.contains(\"webp\") == true)\n}\n\nfun Uri.isJxl(): Boolean {\n    return filename().toString().endsWith(\".jxl\")\n        .or(appContext.contentResolver.getType(this)?.contains(\"jxl\") == true)\n}\n\nfun Uri.isGif(): Boolean {\n    return filename().toString().endsWith(\".gif\")\n        .or(appContext.contentResolver.getType(this)?.contains(\"gif\") == true)\n}\n\nsuspend fun Uri.listFilesInDirectory(): List<Uri> =\n    listFilesInDirectoryAsFlowImpl().filterIsInstance<DirUri.All>().first().uris\n\nfun Uri.listFilesInDirectoryProgressive(): Flow<Uri> = listFilesInDirectoryAsFlowImpl()\n    .filterIsInstance<DirUri.Entry>()\n    .map { it.uri }\n\nfun String?.getPath(\n    context: Context = appContext\n) = this?.takeIf { it.isNotEmpty() }?.toUri().uiPath(\n    default = context.getString(R.string.default_folder)\n)\n\nprivate fun Uri.listFilesInDirectoryAsFlowImpl(): Flow<DirUri> = channelFlow {\n    val rootUri = this@listFilesInDirectoryAsFlowImpl\n\n    var childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(\n        rootUri,\n        DocumentsContract.getTreeDocumentId(rootUri)\n    )\n\n    val files: MutableList<Pair<Uri, Long>> = LinkedList()\n\n    val dirNodes: MutableList<Uri> = LinkedList()\n    dirNodes.add(childrenUri)\n    while (dirNodes.isNotEmpty()) {\n        childrenUri = dirNodes.removeAt(0)\n\n        appContext.contentResolver.query(\n            childrenUri,\n            arrayOf(\n                DocumentsContract.Document.COLUMN_DOCUMENT_ID,\n                DocumentsContract.Document.COLUMN_LAST_MODIFIED,\n                DocumentsContract.Document.COLUMN_MIME_TYPE,\n            ),\n            null,\n            null,\n            null\n        ).use {\n            while (it!!.moveToNext()) {\n                val docId = it.getString(0)\n                val lastModified = it.getLong(1)\n                val mime = it.getString(2)\n                if (isDirectory(mime)) {\n                    val newNode = DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, docId)\n                    dirNodes.add(newNode)\n                } else {\n                    val uri = DocumentsContract.buildDocumentUriUsingTree(rootUri, docId)\n\n                    channel.send(DirUri.Entry(uri))\n\n                    files.add(\n                        uri to lastModified\n                    )\n                }\n            }\n        }\n    }\n\n    files.sortedByDescending { it.second }.map { it.first }.also {\n        channel.send(DirUri.All(it))\n        channel.close()\n    }\n}.flowOn(Dispatchers.IO)\n\nprivate sealed interface DirUri {\n    data class Entry(val uri: Uri) : DirUri\n    data class All(val uris: List<Uri>) : DirUri\n}\n\nprivate fun isDirectory(mimeType: String): Boolean {\n    return DocumentsContract.Document.MIME_TYPE_DIR == mimeType\n}\n\nprivate fun List<Uri>.sortedByExtension(\n    descending: Boolean = false\n) = sortedByKey(descending) {\n    it.filename()?.substringAfterLast(\n        delimiter = '.',\n        missingDelimiterValue = \"\"\n    )?.lowercase()\n}\n\nprivate fun List<Uri>.sortedByDateModified(\n    descending: Boolean = false\n) = sortedByKey(descending) { it.lastModified() }\n\nprivate fun List<Uri>.sortedByName(\n    descending: Boolean = false\n) = sortedByKey(descending) {\n    it.filename()\n}\n\nprivate fun List<Uri>.sortedBySize(\n    descending: Boolean = false\n) = sortedByKey(descending) {\n    it.getLongColumn(OpenableColumns.SIZE)\n}\n\nprivate fun List<Uri>.sortedByMimeType(\n    descending: Boolean = false\n) = sortedByKey(descending) {\n    it.getStringColumn(\n        column = DocumentsContract.Document.COLUMN_MIME_TYPE\n    )\n}\n\nprivate fun List<Uri>.sortedByDateAdded(\n    descending: Boolean = false\n) = sortedByKey(descending) {\n    it.dateAdded()\n}\n\nprivate fun Uri.getLongColumn(column: String): Long? =\n    appContext.contentResolver.query(this, arrayOf(column), null, null, null)?.use { cursor ->\n        if (cursor.moveToFirst()) {\n            val index = cursor.getColumnIndex(column)\n            if (index != -1 && !cursor.isNull(index)) cursor.getLong(index) else null\n        } else null\n    }\n\nprivate fun Uri.getStringColumn(column: String): String? =\n    appContext.contentResolver.query(this, arrayOf(column), null, null, null)?.use { cursor ->\n        if (cursor.moveToFirst()) {\n            val index = cursor.getColumnIndex(column)\n            if (index != -1 && !cursor.isNull(index)) cursor.getString(index) else null\n        } else null\n    }\n"
  },
  {
    "path": "core/utils/src/main/java/com/t8rin/imagetoolbox/core/utils/Zip.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.core.utils\n\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipOutputStream\n\ninline fun <T> OutputStream.createZip(\n    block: (ZipOutputStream) -> T\n): T = ZipOutputStream(this).use(block)\n\nfun ZipOutputStream.putEntry(\n    name: String,\n    input: InputStream\n) {\n    putNextEntry(ZipEntry(name))\n    input.use { it.copyTo(this) }\n    closeEntry()\n}\n\nfun ZipOutputStream.putEntry(\n    name: String,\n    write: (ZipOutputStream) -> Unit\n) {\n    putNextEntry(ZipEntry(name))\n    write(this)\n    closeEntry()\n}"
  },
  {
    "path": "fastlane/metadata/android/en-US/changelogs/13.txt",
    "content": "* Update strings.xml by @Ilithy in #11\n* Redesign\n* Bug fixes\n"
  },
  {
    "path": "fastlane/metadata/android/en-US/changelogs/16.txt",
    "content": "### What's new\n* Only cropping image\n* Color picking\n* Design improved\n* Bug fixes\n"
  },
  {
    "path": "fastlane/metadata/android/en-US/full_description.txt",
    "content": "<h1>✨ Image Toolbox ✨</h1>\n\n<p>Powerful all-in-one image editor, AI toolkit and format converter for creators and power users.</p>\n\n<p><strong>Note:</strong> This is only a partial list of features. Full list is available in the <a href=\"https://github.com/T8RIN/ImageToolbox/blob/master/README.md\">README</a>.</p>\n\n<h2>Core Features</h2>\n<ul>\n<li>Batch processing</li>\n<li>310+ filters + custom filter chains (share via QR)</li>\n<li>File encryption/decryption (100+ algorithms)</li>\n<li>EXIF editing/deleting</li>\n<li>Load images from the internet</li>\n<li>Background removal (manual + AI models)</li>\n<li>Markup layers (stickers, text, shapes)</li>\n<li>Advanced drawing tools (pen, neon, highlighter, warp, pixelation, blur, spot healing)</li>\n<li>Flexible resizing (adaptive, aspect ratio, limits, multiple algorithms)</li>\n<li>Quality compression & size reduction</li>\n</ul>\n\n<h2>AI Tools</h2>\n<ul>\n<li>81 ready AI models</li>\n<li>Upscale, denoise, colorize, enhance</li>\n</ul>\n\n<h2>OCR (Text from Images)</h2>\n<ul>\n<li>120+ languages</li>\n<li>Fast / Standard / Best modes</li>\n<li>Batch extraction</li>\n<li>Write results to files or EXIF</li>\n</ul>\n\n<h2>Conversion & Media</h2>\n<ul>\n<li>HEIF, HEIC, AVIF, WEBP, JPEG, PNG, JXL, TIFF, QOI, ICO</li>\n</ul>\n\n<h2>PDF & Documents</h2>\n<ul>\n<li>PDF → Images</li>\n<li>Images → PDF</li>\n<li>Document scanning</li>\n</ul>\n\n<h2>Image Tools</h2>\n<ul>\n<li>Stitching, stacking, splitting</li>\n<li>Batch cutting</li>\n<li>Raster → SVG tracing</li>\n<li>Collages (2–10 images, 180+ layouts)</li>\n<li>Watermarking (text, image, timestamp, steganography)</li>\n</ul>\n\n<h2>Barcodes</h2>\n<ul>\n<li>Create & scan 13 formats (QR, Aztec, Data Matrix, EAN, Code 128, PDF417, UPC)</li>\n<li>Share as images</li>\n</ul>"
  },
  {
    "path": "fastlane/metadata/android/en-US/short_description.txt",
    "content": "Edit, create & convert images with powerful AI — your all-in-one studio"
  },
  {
    "path": "fastlane/metadata/android/ru/full_description.txt",
    "content": "Набор инструментов для работы с изображениями ✨\n\n<b>Возможности:</b>\n\n<ul>\n<li>Пакетная обработка</li>\n<li>Применение цепочек фильтров (более 45 различных фильтров)</li>\n<li>AES-256 GCM No Padding шифрование файлов</li>\n<li>Редактирование/удаление метаданных EXIF</li>\n<li>Загрузка изображений из Интернета</li>\n<li>Удаление фона</li>\n  <ul>\n  <li>Путем рисования</li>\n  <li>Автоматически</li>\n  </ul>\n<li>Рисование на изображении/фоне</li>\n  <ul>\n  <li>Ручка</li>\n  <li>Неон</li>\n  <li>Хайлайтер</li>\n  </ul>\n<li>Изменение размера изображения</li>\n  <ul>\n  <li>Изменение ширины</li>\n  <li>Изменение высоты</li>\n  <li>Адаптивное изменение размера</li>\n  <li>Изменить размер с сохранением соотношения сторон</li>\n  <li>Изменить размер в заданных пределах</li>\n  </ul>\n<li>Уменьшить изображение</li>\n  <ul>\n  <li>Сжатие по качеству</li>\n  <li>Сжатие по преднастройке</li>\n  <li>Уменьшение размера на заданный вес (в килобайтах)</li>\n  </ul>\n<li>Обрезка</li>\n  <ul>\n  <li>Обычная обрезка</li>\n  <li>Обрезка по соотношению сторон</li>\n  <li>Обрезка с помощью маски формы</li>\n    <ul>\n    <li>Закругленные углы</li>\n    <li>Срезанные углы</li>\n    <li>Овал</li>\n    <li>Прямоугольник</li>\n    <li>Восьмиугольник</li>\n    <li>Закругленный пятиугольник</li>\n    <li>Клевер</li>\n    <li>Звезда Давида</li>\n    <li>Логотип Kotlin</li>\n    <li>Сердце</li>\n    <li>Звезда</li>\n    <li>Маска изображения</li>\n    </ul>\n  </ul>\n<li>Преобразование формата</li>\n  <ul>\n  <li>HEIF</li>\n  <li>HEIC</li>\n  <li>AVIF</li>\n  <li>WEBP</li>\n  <li>JPEG</li>\n  <li>JPG</li>\n  <li>PNG</li>\n  <li>SVG, GIF в WEBP, PNG, JPEG, JPG, HEIF, HEIC, AVIF</li>\n  <li>Стикеры для Telegram в формате PNG</li>\n  </ul>\n<li>Цветовые утилиты</li>\n  <ul>\n  <li>Создание палитры</li>\n  <li>Выбор цвета из изображения</li>\n  </ul>\n<li>Дополнительные возможности</li>\n  <ul>\n  <li>Вращение</li>\n  <li>Переворачивание</li>\n  <li>Сравнение изображений</li>\n  <li>Предварительный просмотр SVG, GIF и в почти всех типов изображений</li>\n  <li>Сохранение в любую папку</li>\n  </ul>\n</ul>  "
  },
  {
    "path": "fastlane/metadata/android/ru/short_description.txt",
    "content": "Фильтр, Растягивание, Сравнение, Обрезание - делайте с изображениями что угодно"
  },
  {
    "path": "feature/ai-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/ai-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.ai_tools\"\n\ndependencies {\n    implementation(projects.lib.neuralTools)\n}"
  },
  {
    "path": "feature/ai-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/data/AiProcessor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UNCHECKED_CAST\")\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.data\n\nimport ai.onnxruntime.OnnxJavaType\nimport ai.onnxruntime.OnnxTensor\nimport ai.onnxruntime.OrtEnvironment\nimport ai.onnxruntime.OrtSession\nimport ai.onnxruntime.TensorInfo\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.BitmapFactory\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.saving.track\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.feature.ai_tools.data.model.ChunkInfo\nimport com.t8rin.imagetoolbox.feature.ai_tools.data.model.ModelInfo\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.AiProgressListener\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralParams\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.lang.Float.floatToIntBits\nimport java.lang.Float.intBitsToFloat\nimport java.nio.ByteBuffer\nimport java.nio.ByteOrder\nimport java.nio.FloatBuffer\nimport javax.inject.Inject\nimport kotlin.math.ceil\n\ninternal class AiProcessor @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val service: KeepAliveService,\n    dispatchersHolder: DispatchersHolder,\n    resourceManager: ResourceManager\n) : DispatchersHolder by dispatchersHolder, ResourceManager by resourceManager {\n\n    private val chunksDir: File\n        get() = File(context.cacheDir, \"processing_chunks\").apply(File::mkdirs)\n\n    suspend fun processImage(\n        session: OrtSession,\n        inputBitmap: Bitmap,\n        model: NeuralModel,\n        params: NeuralParams,\n        listener: AiProgressListener\n    ): Bitmap? = withContext(defaultDispatcher) {\n        service.track(\n            onCancel = {\n                \"Cancelled\".makeLog(\"AiProcessor\")\n                clearChunks()\n            },\n            onFailure = { e ->\n                listener.onError(\n                    e.localizedMessage ?: e.message ?: getString(R.string.something_went_wrong)\n                )\n            },\n            action = {\n                processBitmapImpl(\n                    session = session,\n                    inputBitmap = inputBitmap,\n                    listener = object : AiProgressListener {\n                        override fun onError(error: String) {\n                            listener.onError(error)\n                            stop()\n                        }\n\n                        override fun onProgress(currentChunkIndex: Int, totalChunks: Int) {\n                            listener.onProgress(\n                                currentChunkIndex = currentChunkIndex,\n                                totalChunks = totalChunks\n                            )\n\n                            if (totalChunks > 0) {\n                                updateProgress(\n                                    done = currentChunkIndex,\n                                    total = totalChunks\n                                )\n                            }\n                        }\n                    },\n                    info = ModelInfo(\n                        strength = params.strength,\n                        session = session,\n                        chunkSize = params.chunkSize,\n                        overlap = params.overlap,\n                        model = model,\n                        disableChunking = !params.enableChunking\n                    )\n                )\n            }\n        )\n    }\n\n    private suspend fun processBitmapImpl(\n        session: OrtSession,\n        inputBitmap: Bitmap,\n        listener: AiProgressListener,\n        info: ModelInfo,\n    ): Bitmap = withContext(defaultDispatcher) {\n        val width = inputBitmap.getWidth()\n        val height = inputBitmap.getHeight()\n\n        val processingConfig = Bitmap.Config.ARGB_8888\n        // Use the smaller of chunkSize or model's fixed dimensions\n        val effectiveMaxChunkSize = if (info.isNonChunkable) {\n            Int.MAX_VALUE\n        } else {\n            if (info.expectedWidth != null && info.expectedHeight != null) {\n                minOf(info.chunkSize, info.expectedWidth, info.expectedHeight)\n            } else {\n                info.chunkSize\n            }\n        }\n\n        if (width > effectiveMaxChunkSize || height > effectiveMaxChunkSize) {\n            processTiled(\n                session = session,\n                inputBitmap = inputBitmap,\n                listener = listener,\n                info = info,\n                config = processingConfig,\n                maxChunkSize = effectiveMaxChunkSize\n            )\n        } else {\n            processChunk(\n                session = session,\n                chunk = inputBitmap.copy(processingConfig, true),\n                config = processingConfig,\n                info = info\n            )\n        }\n    }\n\n    private suspend fun processTiled(\n        session: OrtSession,\n        inputBitmap: Bitmap,\n        listener: AiProgressListener,\n        info: ModelInfo,\n        config: Bitmap.Config,\n        maxChunkSize: Int\n    ): Bitmap = withContext(defaultDispatcher) {\n        ensureActive()\n        val width = inputBitmap.width\n        val height = inputBitmap.height\n        val overlap = info.overlap\n        val stride = maxChunkSize - overlap\n        val cols =\n            if (width <= maxChunkSize) 1 else ceil((width - overlap).toFloat() / stride).toInt()\n        val rows =\n            if (height <= maxChunkSize) 1 else ceil((height - overlap).toFloat() / stride).toInt()\n        \"Processing tiled: image=${width}x${height}, chunkSize=$maxChunkSize, stride=$stride, grid=${cols}x${rows}, overlap=$overlap\".makeLog(\n            \"AiProcessor\"\n        )\n        val totalChunks = cols * rows\n\n        val chunkInfoList = mutableListOf<ChunkInfo>()\n\n        \"Phase 1: Extracting $totalChunks chunks to disk\".makeLog(\"AiProcessor\")\n        var chunkIndex = 0\n        for (row in 0 until rows) {\n            for (col in 0 until cols) {\n                ensureActive()\n                val chunkX = col * stride\n                val chunkY = row * stride\n                val chunkW = minOf(chunkX + maxChunkSize, width) - chunkX\n                val chunkH = minOf(chunkY + maxChunkSize, height) - chunkY\n                if (chunkW <= 0 || chunkH <= 0) continue\n                val chunk = Bitmap.createBitmap(inputBitmap, chunkX, chunkY, chunkW, chunkH)\n                val converted = if (chunk.config != config) {\n                    val temp = chunk.copy(config, true)\n                    chunk.recycle()\n                    temp\n                } else {\n                    chunk\n                }\n\n                ensureActive()\n\n                val inputChunkFile = File(chunksDir, \"chunk_${chunkIndex}.png\")\n                val processedChunkFile = File(chunksDir, \"chunk_${chunkIndex}_processed.png\")\n                withContext(Dispatchers.IO) {\n                    FileOutputStream(inputChunkFile).use {\n                        converted.compress(Bitmap.CompressFormat.PNG, 100, it)\n                    }\n                }\n                converted.recycle()\n                chunkInfoList.add(\n                    ChunkInfo(\n                        index = chunkIndex,\n                        inputFile = inputChunkFile,\n                        processedFile = processedChunkFile,\n                        x = chunkX,\n                        y = chunkY,\n                        width = chunkW,\n                        height = chunkH,\n                        col = col,\n                        row = row\n                    )\n                )\n                chunkIndex++\n            }\n        }\n        \"Saved ${chunkInfoList.size} chunks to ${chunksDir.absolutePath}\".makeLog(\"AiProcessor\")\n        \"Phase 2: Processing $totalChunks chunks\".makeLog(\"AiProcessor\")\n        if (totalChunks > 1) {\n            listener.onProgress(0, totalChunks)\n        }\n        for (chunkInfo in chunkInfoList) {\n            ensureActive()\n\n            val loadedChunk = BitmapFactory.decodeFile(chunkInfo.inputFile.absolutePath)\n\n            val processed = processChunk(\n                session = session,\n                chunk = loadedChunk,\n                config = config,\n                info = info\n            )\n\n            loadedChunk.recycle()\n            withContext(ioDispatcher) {\n                FileOutputStream(chunkInfo.processedFile).use {\n                    processed.compress(Bitmap.CompressFormat.PNG, 100, it)\n                }\n                chunkInfo.inputFile.delete()\n            }\n\n            ensureActive()\n\n            processed.recycle()\n\n            if (totalChunks > 1) {\n                val nextChunkIndex = chunkInfo.index + 1\n                listener.onProgress(nextChunkIndex, totalChunks)\n            }\n        }\n\n        val resultWidth = width * info.scaleFactor\n        val resultHeight = height * info.scaleFactor\n        val result = createBitmap(resultWidth, resultHeight, config)\n        for (chunkInfo in chunkInfoList) {\n            ensureActive()\n            val loadedProcessed = withContext(ioDispatcher) {\n                BitmapFactory.decodeFile(chunkInfo.processedFile.absolutePath)\n            } ?: throw Exception(\"Failed to load processed chunk ${chunkInfo.index}\")\n\n            mergeChunkWithBlending(\n                result = result,\n                processedChunk = loadedProcessed,\n                chunkInfo = chunkInfo,\n                overlap = overlap,\n                scaleFactor = info.scaleFactor\n            )\n            loadedProcessed.recycle()\n        }\n        clearChunks()\n\n        result\n    }\n\n    private suspend fun processChunk(\n        session: OrtSession,\n        chunk: Bitmap,\n        config: Bitmap.Config,\n        info: ModelInfo\n    ): Bitmap = withContext(defaultDispatcher) {\n        ensureActive()\n\n        val originalW = chunk.width\n        val originalH = chunk.height\n        var w: Int\n        var h: Int\n        val minModelSize = info.minSpatialSize\n\n        if (info.isScuNetColor || minModelSize > 256) {\n            w = if (info.expectedWidth != null && info.expectedWidth > 0) {\n                info.expectedWidth\n            } else {\n                val padFactor = 8\n                val paddedW = ((originalW + padFactor - 1) / padFactor) * padFactor\n                maxOf(paddedW, minModelSize)\n            }\n            h = if (info.expectedHeight != null && info.expectedHeight > 0) {\n                info.expectedHeight\n            } else {\n                val padFactor = 8\n                val paddedH = ((originalH + padFactor - 1) / padFactor) * padFactor\n                maxOf(paddedH, minModelSize)\n            }\n        } else {\n            w = if (info.expectedWidth != null && info.expectedWidth > 0) {\n                info.expectedWidth\n            } else {\n                val padFactor = 8\n                ((originalW + padFactor - 1) / padFactor) * padFactor\n            }\n            h = if (info.expectedHeight != null && info.expectedHeight > 0) {\n                info.expectedHeight\n            } else {\n                val padFactor = 8\n                ((originalH + padFactor - 1) / padFactor) * padFactor\n            }\n        }\n\n        val needsPadding = w != originalW || h != originalH\n        val paddedChunk = if (needsPadding) {\n            \"Padding chunk from ${originalW}x${originalH} to ${w}x${h}\".makeLog(\"AiProcessor\")\n            val padded = createBitmap(w, h, config)\n            val canvas = Canvas(padded)\n            canvas.drawBitmap(chunk, 0f, 0f, null)\n            if (w > originalW) {\n                val rightStrip = Bitmap.createBitmap(chunk, originalW - 1, 0, 1, originalH)\n                for (x in originalW until w) {\n                    ensureActive()\n                    canvas.drawBitmap(rightStrip, x.toFloat(), 0f, null)\n                }\n                rightStrip.recycle()\n            }\n            if (h > originalH) {\n                val bottomStrip = Bitmap.createBitmap(padded, 0, originalH - 1, w, 1)\n                for (y in originalH until h) {\n                    ensureActive()\n                    canvas.drawBitmap(bottomStrip, 0f, y.toFloat(), null)\n                }\n                bottomStrip.recycle()\n            }\n            padded\n        } else {\n            chunk\n        }\n        val hasAlpha = chunk.hasAlpha()\n        val inputChannels = info.inputChannels\n        val outputChannels = info.outputChannels\n        val pixels = IntArray(w * h)\n        paddedChunk.getPixels(pixels, 0, w, 0, 0, w, h)\n        val inputArray = FloatArray(inputChannels * w * h)\n        val alphaChannel = if (hasAlpha) FloatArray(w * h) else null\n        for (i in 0 until w * h) {\n            ensureActive()\n\n            val color = pixels[i]\n            if (inputChannels == 1) {\n                val gray = (Color.red(color) + Color.green(color) + Color.blue(color)) / 3\n                inputArray[i] = gray / 255f\n            } else {\n                inputArray[i] = Color.red(color) / 255f\n                inputArray[w * h + i] = Color.green(color) / 255f\n                inputArray[2 * w * h + i] = Color.blue(color) / 255f\n            }\n            if (hasAlpha) {\n                alphaChannel!![i] = Color.alpha(color) / 255f\n            }\n        }\n        val env = OrtEnvironment.getEnvironment()\n        val inputShape = longArrayOf(1, inputChannels.toLong(), h.toLong(), w.toLong())\n        val inputs = mutableMapOf<String, OnnxTensor>()\n        val inputTensor = if (info.isFp16) {\n            val fp16Array = ShortArray(inputArray.size) { i -> floatToFloat16(inputArray[i]) }\n            val byteBuffer =\n                ByteBuffer.allocateDirect(fp16Array.size * 2).order(ByteOrder.nativeOrder())\n            val shortBuffer = byteBuffer.asShortBuffer()\n            shortBuffer.put(fp16Array)\n            byteBuffer.rewind()\n            OnnxTensor.createTensor(env, byteBuffer, inputShape, OnnxJavaType.FLOAT16)\n        } else {\n            OnnxTensor.createTensor(env, FloatBuffer.wrap(inputArray), inputShape)\n        }\n        inputs[info.inputName] = inputTensor\n        for ((key, nodeInfo) in info.inputInfoMap) {\n            ensureActive()\n            if (key == info.inputName) continue\n            val tensorInfo = nodeInfo.info as? TensorInfo ?: continue\n            if (tensorInfo.type == OnnxJavaType.FLOAT || tensorInfo.type == OnnxJavaType.FLOAT16) {\n                val shape = tensorInfo.shape.clone()\n                for (i in shape.indices) {\n                    ensureActive()\n                    if (shape[i] == -1L) shape[i] = 1L\n                }\n                if (shape.size == 2 && shape[0] == 1L && shape[1] == 1L) {\n                    ensureActive()\n                    val strengthTensor = if (tensorInfo.type == OnnxJavaType.FLOAT16) {\n                        val strengthFp16 = floatToFloat16(info.strength / 100f)\n                        val byteBuffer = ByteBuffer.allocateDirect(2).order(ByteOrder.nativeOrder())\n                        byteBuffer.asShortBuffer().put(strengthFp16)\n                        byteBuffer.rewind()\n                        OnnxTensor.createTensor(env, byteBuffer, shape, OnnxJavaType.FLOAT16)\n                    } else {\n                        OnnxTensor.createTensor(\n                            env,\n                            FloatBuffer.wrap(floatArrayOf(info.strength / 100f)),\n                            shape\n                        )\n                    }\n                    inputs[key] = strengthTensor\n                }\n            }\n        }\n\n        try {\n            ensureActive()\n            session.run(inputs).use { sessionResult ->\n                val outputH = h * info.scaleFactor\n                val outputW = w * info.scaleFactor\n                val (outputArray, actualOutputChannels) = extractOutputArray(\n                    outputValue = sessionResult[0].value,\n                    channels = outputChannels,\n                    h = outputH,\n                    w = outputW\n                )\n                val fullResultBitmap =\n                    createBitmap(width = outputW, height = outputH, config = config)\n                val outPixels = IntArray(outputW * outputH)\n\n                for (i in 0 until outputW * outputH) {\n                    ensureActive()\n                    val alpha = if (hasAlpha) {\n                        val srcY = ((i / outputW) / info.scaleFactor).coerceIn(0, h - 1)\n                        val srcX = ((i % outputW) / info.scaleFactor).coerceIn(0, w - 1)\n                        val srcIdx = srcY * w + srcX\n                        clamp255(alphaChannel!![srcIdx] * 255f)\n                    } else {\n                        255\n                    }\n\n                    if (actualOutputChannels == 1) {\n                        val gray = clamp255(outputArray[i] * 255f)\n                        outPixels[i] = Color.argb(alpha, gray, gray, gray)\n                    } else {\n                        val r = clamp255(outputArray[i] * 255f)\n                        val g = clamp255(outputArray[outputW * outputH + i] * 255f)\n                        val b = clamp255(outputArray[2 * outputW * outputH + i] * 255f)\n                        outPixels[i] = Color.argb(alpha, r, g, b)\n                    }\n                }\n                fullResultBitmap.setPixels(outPixels, 0, outputW, 0, 0, outputW, outputH)\n                if (needsPadding) {\n                    val croppedW = originalW * info.scaleFactor\n                    val croppedH = originalH * info.scaleFactor\n                    val cropped = Bitmap.createBitmap(fullResultBitmap, 0, 0, croppedW, croppedH)\n                    fullResultBitmap.recycle()\n                    cropped\n                } else {\n                    fullResultBitmap\n                }\n            }\n        } finally {\n            inputs.values.forEach { it.close() }\n            if (needsPadding) {\n                paddedChunk.recycle()\n            }\n        }\n    }\n\n    private suspend fun mergeChunkWithBlending(\n        result: Bitmap,\n        processedChunk: Bitmap,\n        chunkInfo: ChunkInfo,\n        overlap: Int,\n        scaleFactor: Int\n    ) = withContext(defaultDispatcher) {\n        val width = processedChunk.width\n        val height = processedChunk.height\n        val x = chunkInfo.x * scaleFactor\n        val y = chunkInfo.y * scaleFactor\n        val scaledOverlap = overlap * scaleFactor\n        val needsLeftBlend = chunkInfo.col > 0\n        val needsTopBlend = chunkInfo.row > 0\n        if (!needsLeftBlend && !needsTopBlend) {\n            val canvas = Canvas(result)\n            canvas.drawBitmap(processedChunk, x.toFloat(), y.toFloat(), null)\n            return@withContext\n        }\n        val existingPixels = IntArray(width * height)\n        try {\n            result.getPixels(existingPixels, 0, width, x, y, width, height)\n        } catch (_: Throwable) {\n            val canvas = Canvas(result)\n            canvas.drawBitmap(processedChunk, x.toFloat(), y.toFloat(), null)\n            return@withContext\n        }\n        val newPixels = IntArray(width * height)\n        processedChunk.getPixels(newPixels, 0, width, 0, 0, width, height)\n        for (localY in 0 until height) {\n            for (localX in 0 until width) {\n                ensureActive()\n                val inLeftOverlap = needsLeftBlend && localX < scaledOverlap\n                val inTopOverlap = needsTopBlend && localY < scaledOverlap\n                if (!inLeftOverlap && !inTopOverlap) continue\n                val idx = localY * width + localX\n                var blendFactor = 1.0f\n                if (inLeftOverlap) {\n                    val t =\n                        (localX.toFloat() / (scaledOverlap - 1).coerceAtLeast(1)).coerceIn(0f, 1f)\n                    blendFactor = minOf(blendFactor, t * t * (3f - 2f * t))\n                }\n                if (inTopOverlap) {\n                    val t =\n                        (localY.toFloat() / (scaledOverlap - 1).coerceAtLeast(1)).coerceIn(0f, 1f)\n                    blendFactor = minOf(blendFactor, t * t * (3f - 2f * t))\n                }\n                val existingColor = existingPixels[idx]\n                val newColor = newPixels[idx]\n                val r =\n                    ((1 - blendFactor) * Color.red(existingColor) + blendFactor * Color.red(newColor)).toInt()\n                val g = ((1 - blendFactor) * Color.green(existingColor) + blendFactor * Color.green(\n                    newColor\n                )).toInt()\n                val b = ((1 - blendFactor) * Color.blue(existingColor) + blendFactor * Color.blue(\n                    newColor\n                )).toInt()\n                val a = ((1 - blendFactor) * Color.alpha(existingColor) + blendFactor * Color.alpha(\n                    newColor\n                )).toInt()\n                newPixels[idx] = Color.argb(a, r, g, b)\n            }\n        }\n        result.setPixels(newPixels, 0, width, x, y, width, height)\n    }\n\n    private suspend fun extractOutputArray(\n        outputValue: Any,\n        channels: Int,\n        h: Int,\n        w: Int\n    ): Pair<FloatArray, Int> = withContext(defaultDispatcher) {\n        ensureActive()\n        \"Output type received: ${outputValue.javaClass.name}\".makeLog(\"AiProcessor\")\n\n        when (outputValue) {\n            is FloatArray -> {\n                \"Output is FloatArray (FP32 or auto-converted from FP16)\".makeLog(\"AiProcessor\")\n                outputValue to channels\n            }\n\n            is ShortArray -> {\n                \"Output is ShortArray (FP16) - converting to Float32\".makeLog(\"AiProcessor\")\n                FloatArray(outputValue.size) { i -> float16ToFloat(outputValue[i]) } to channels\n            }\n\n            is Array<*> -> {\n                try {\n                    val arr = outputValue as Array<Array<Array<FloatArray>>>\n                    \"Output is multi-dimensional FloatArray\".makeLog(\"AiProcessor\")\n                    val actualBatches = arr.size\n                    val actualChannels = arr[0].size\n                    val actualHeight = arr[0][0].size\n                    val actualWidth = arr[0][0][0].size\n\n                    val channelsToProcess = maxOf(channels, actualChannels)\n                    \"Actual tensor shape: [$actualBatches, $actualChannels, $actualHeight, $actualWidth]\".makeLog(\n                        \"AiProcessor\"\n                    )\n                    \"Requested extraction shape: [$channelsToProcess, $h, $w]\".makeLog(\"AiProcessor\")\n\n                    val out = FloatArray(channelsToProcess * h * w)\n                    for (ch in 0 until channelsToProcess) {\n                        for (y in 0 until h) {\n                            for (x in 0 until w) {\n                                ensureActive()\n                                out[ch * h * w + y * w + x] = arr[0][ch][y][x]\n                            }\n                        }\n                    }\n                    out to channelsToProcess\n                } catch (e: Throwable) {\n                    try {\n                        val arr = outputValue as Array<Array<Array<ShortArray>>>\n                        \"Output is multi-dimensional ShortArray (FP16)\".makeLog(\"AiProcessor\")\n                        val actualBatches = arr.size\n                        val actualChannels = arr[0].size\n                        val actualHeight = arr[0][0].size\n                        val actualWidth = arr[0][0][0].size\n\n                        val channelsToProcess = maxOf(channels, actualChannels)\n                        \"Actual tensor shape: [$actualBatches, $actualChannels, $actualHeight, $actualWidth]\".makeLog(\n                            \"AiProcessor\"\n                        )\n                        \"Requested extraction shape: [$channelsToProcess, $h, $w]\".makeLog(\"AiProcessor\")\n\n                        val out = FloatArray(channelsToProcess * h * w)\n                        for (ch in 0 until channelsToProcess) {\n                            for (y in 0 until h) {\n                                for (x in 0 until w) {\n                                    ensureActive()\n                                    out[ch * h * w + y * w + x] = float16ToFloat(arr[0][ch][y][x])\n                                }\n                            }\n                        }\n                        out to channelsToProcess\n                    } catch (e2: Throwable) {\n                        throw RuntimeException(\"Failed to extract output array: ${e.message}, ${e2.message}\")\n                    }\n                }\n            }\n\n            else -> throw RuntimeException(\"Unexpected ONNX output type: ${outputValue.javaClass}\")\n        }\n    }\n\n    private fun clamp255(v: Float): Int = v.toInt().coerceIn(0, 255)\n\n    private fun floatToFloat16(value: Float): Short {\n        val bits = floatToIntBits(value)\n        val sign = (bits ushr 16) and 0x8000\n        val exponent = ((bits ushr 23) and 0xFF) - 127 + 15\n        var mantissa = bits and 0x7FFFFF\n\n        if (exponent <= 0) {\n            if (exponent < -10) {\n                return sign.toShort()\n            }\n            mantissa = mantissa or 0x800000\n            mantissa = mantissa shr (1 - exponent)\n            return (sign or (mantissa shr 13)).toShort()\n        } else if (exponent >= 0x1F) {\n            return (sign or 0x7C00).toShort()\n        }\n\n        return (sign or (exponent shl 10) or (mantissa shr 13)).toShort()\n    }\n\n    private fun float16ToFloat(fp16: Short): Float {\n        val bits = fp16.toInt() and 0xFFFF\n        val sign = (bits and 0x8000) shl 16\n        val exponent = (bits and 0x7C00) ushr 10\n        val mantissa = bits and 0x3FF\n        if (exponent == 0) {\n            if (mantissa == 0) {\n                return intBitsToFloat(sign)\n            }\n            var e = -14\n            var m = mantissa\n            while ((m and 0x400) == 0) {\n                m = m shl 1\n                e--\n            }\n            m = m and 0x3FF\n            return intBitsToFloat(sign or ((e + 127) shl 23) or (m shl 13))\n        } else if (exponent == 0x1F) {\n            return intBitsToFloat(sign or 0x7F800000 or (mantissa shl 13))\n        }\n\n        return intBitsToFloat(sign or ((exponent - 15 + 127) shl 23) or (mantissa shl 13))\n    }\n\n    private fun clearChunks() = chunksDir.deleteRecursively()\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/data/AndroidAiToolsRepository.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.data\n\nimport ai.onnxruntime.OrtEnvironment\nimport ai.onnxruntime.OrtException\nimport ai.onnxruntime.OrtSession\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.core.net.toUri\nimport androidx.datastore.core.DataStore\nimport androidx.datastore.preferences.core.Preferences\nimport androidx.datastore.preferences.core.edit\nimport androidx.datastore.preferences.core.stringPreferencesKey\nimport com.t8rin.imagetoolbox.core.data.image.utils.healAlpha\nimport com.t8rin.imagetoolbox.core.data.saving.io.FileReadable\nimport com.t8rin.imagetoolbox.core.data.saving.io.FileWriteable\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriReadable\nimport com.t8rin.imagetoolbox.core.data.utils.computeFromReadable\nimport com.t8rin.imagetoolbox.core.data.utils.observeHasChanges\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadManager\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.track\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.AiProgressListener\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.AiToolsRepository\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralConstants\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralParams\nimport com.t8rin.logger.makeLog\nimport com.t8rin.neural_tools.bgremover.BgRemover\nimport com.t8rin.neural_tools.bgremover.GenericBackgroundRemover\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.MutableSharedFlow\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.channelFlow\nimport kotlinx.coroutines.flow.collect\nimport kotlinx.coroutines.flow.combine\nimport kotlinx.coroutines.flow.debounce\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.merge\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.flow.update\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport javax.inject.Inject\n\ninternal class AndroidAiToolsRepository @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val dataStore: DataStore<Preferences>,\n    private val appScope: AppScope,\n    private val processor: AiProcessor,\n    private val keepAliveService: KeepAliveService,\n    dispatchersHolder: DispatchersHolder,\n    resourceManager: ResourceManager,\n    private val downloadManager: DownloadManager,\n    private val fileController: FileController\n) : AiToolsRepository<Bitmap>,\n    DispatchersHolder by dispatchersHolder,\n    ResourceManager by resourceManager {\n\n    init {\n        appScope.launch { extractU2NetP() }\n    }\n\n    private var isProcessingImage = false\n\n    private val modelsDir: File\n        get() = File(\n            context.filesDir,\n            NeuralConstants.DIR\n        ).apply(File::mkdirs)\n\n    private val updateFlow: MutableSharedFlow<Unit> = MutableSharedFlow()\n\n    override val occupiedStorageSize: MutableStateFlow<Long> = MutableStateFlow(0)\n\n    override val downloadedModels: StateFlow<List<NeuralModel>> =\n        merge(\n            modelsDir.observeHasChanges().debounce(100),\n            updateFlow\n        ).map {\n            fetchDownloadedModels { files ->\n                occupiedStorageSize.update { files.sumOf { it.length() } }\n            }.sortedWith(\n                compareBy(\n                    { NeuralModel.entries.indexOfFirst { e -> e.name == it.name } },\n                    { it.title },\n                )\n            )\n        }.stateIn(\n            scope = appScope,\n            started = SharingStarted.Eagerly,\n            initialValue = emptyList()\n        )\n\n    override val selectedModel: StateFlow<NeuralModel?> = combine(\n        downloadedModels,\n        dataStore.data\n    ) { downloaded, data ->\n        downloaded.find { it.name == data[SELECTED_MODEL] }\n    }.stateIn(\n        scope = appScope,\n        started = SharingStarted.Eagerly,\n        initialValue = null\n    )\n\n    private var session: OrtSession? = null\n\n    override fun downloadModel(\n        model: NeuralModel\n    ): Flow<DownloadProgress> = channelFlow {\n        ensureActive()\n\n        if (model.name.contains(\"u2netp\")) {\n            extractU2NetP()\n            selectModelForced(model)\n            close()\n        } else {\n            downloadManager.download(\n                url = model.downloadLink,\n                onStart = {\n                    trySend(\n                        DownloadProgress(\n                            currentPercent = 0f,\n                            currentTotalSize = model.downloadSize\n                        )\n                    )\n                },\n                onProgress = ::trySend,\n                destinationPath = model.file.absolutePath,\n                onFinish = {\n                    if (it == null) selectModelForced(model)\n                    close(it)\n                }\n            )\n        }\n    }.flowOn(ioDispatcher)\n\n    private suspend fun CoroutineScope.selectModelForced(model: NeuralModel) {\n        updateFlow.emit(Unit)\n\n        ensureActive()\n\n        selectModel(\n            model = model,\n            forced = true\n        )\n        model.asBgRemover()?.checkModel()\n    }\n\n    override suspend fun importModel(\n        uri: String\n    ): SaveResult = withContext(ioDispatcher) {\n        val modelToImport = UriReadable(\n            uri = uri.toUri(),\n            context = context\n        )\n        val modelChecksum = HashingType.SHA_256.computeFromReadable(modelToImport)\n\n        val possibleModel = NeuralModel.entries.find {\n            it.checksum == modelChecksum\n        }\n\n        val modelName = possibleModel?.name\n            ?: uri.toUri().filename().orEmpty().ifEmpty {\n                \"imported_model_($modelChecksum).onnx\"\n            }\n\n        val alreadyDownloaded = downloadedModels.value.find {\n            it.checksum == modelChecksum\n        }\n\n        if (alreadyDownloaded != null) {\n            selectModelForced(alreadyDownloaded)\n            return@withContext SaveResult.Skipped\n        }\n\n        fileController.transferBytes(\n            fromUri = uri,\n            to = FileWriteable(\n                File(\n                    modelsDir,\n                    modelName\n                ).apply(File::createNewFile)\n            )\n        ).also {\n            selectModelForced(\n                NeuralModel.Imported(\n                    name = modelName,\n                    checksum = modelChecksum\n                )\n            )\n        }\n    }\n\n    override suspend fun processImage(\n        image: Bitmap,\n        listener: AiProgressListener,\n        params: NeuralParams\n    ): Bitmap? = withContext(defaultDispatcher) {\n        \"start processing\".makeLog()\n\n        val model = selectedModel.value\n\n        when {\n            model == null -> return@withContext listener.failedSession()\n\n            model.type == NeuralModel.Type.REMOVE_BG -> {\n                processImage {\n                    withClosedSession(listener) {\n                        model.asBgRemover()?.removeBackground(image = image)!!.healAlpha(image)\n                    }\n                }\n            }\n\n            else -> {\n                processImage {\n                    val ortSession = session.makeLog(\"Held session\")\n                        ?: createSession(selectedModel.value).makeLog(\"New session\")\n                        ?: return@withContext null.also {\n                            listener.onError(getString(R.string.failed_to_open_session))\n                        }\n\n                    processor.processImage(\n                        session = ortSession,\n                        inputBitmap = image,\n                        params = params,\n                        listener = listener,\n                        model = selectedModel.value!!\n                    )\n                }\n            }\n        }\n    }\n\n    private suspend fun withClosedSession(\n        listener: AiProgressListener,\n        function: suspend () -> Bitmap?\n    ): Bitmap? {\n        closeSession()\n\n        return keepAliveService.track(\n            onFailure = {\n                listener.onError(it.message ?: it::class.simpleName.orEmpty())\n            },\n            action = {\n                function()\n            }\n        )\n    }\n\n    private fun <T> AiProgressListener.failedSession(): T? = null.also {\n        onError(getString(R.string.failed_to_open_session))\n    }\n\n    override suspend fun deleteModel(model: NeuralModel) = withContext(ioDispatcher) {\n        model.file.delete()\n        if (selectedModel.value?.name == model.name) selectModel(null)\n        updateFlow.emit(Unit)\n    }\n\n    override fun cleanup() {\n        BgRemover.closeAll()\n        closeSession()\n        System.gc()\n    }\n\n    override suspend fun selectModel(\n        model: NeuralModel?,\n        forced: Boolean\n    ): Boolean = withContext(ioDispatcher) {\n        if (isProcessingImage) return@withContext false\n        if (!forced && model != null && downloadedModels.value.none { it.name == model.name }) return@withContext false\n        if (model != null && model.name == selectedModel.value?.name) return@withContext false\n\n        dataStore.edit {\n            it[SELECTED_MODEL] = model?.name.orEmpty()\n        }\n\n        cleanup()\n\n        return@withContext true\n    }\n\n    private fun createSession(model: NeuralModel?): OrtSession? {\n        return runCatching {\n            val modelName = model?.name.orEmpty()\n            val options = OrtSession.SessionOptions().apply {\n                val processors = Runtime.getRuntime().availableProcessors()\n                try {\n                    setIntraOpNumThreads(if (processors <= 2) 1 else (processors * 3) / 4)\n                } catch (e: OrtException) {\n                    \"Error setting IntraOpNumThreads: ${e.message}\".makeLog(\"ModelManager\")\n                }\n                try {\n                    setInterOpNumThreads(4)\n                } catch (e: OrtException) {\n                    \"Error setting InterOpNumThreads: ${e.message}\".makeLog(\"ModelManager\")\n                }\n                try {\n                    when {\n                        modelName.endsWith(\".ort\") -> { // prevent double optimizations (.ort models are already optimized)\n                            setOptimizationLevel(\n                                OrtSession.SessionOptions.OptLevel.NO_OPT\n                            )\n                        }\n\n                        modelName.startsWith(\"fbcnn_\") -> setOptimizationLevel(\n                            OrtSession.SessionOptions.OptLevel.EXTENDED_OPT\n                        )\n\n                        modelName.startsWith(\"scunet_\") -> setOptimizationLevel(\n                            OrtSession.SessionOptions.OptLevel.NO_OPT\n                        )\n                    }\n                } catch (e: OrtException) {\n                    \"Error setting OptimizationLevel: ${e.message}\".makeLog(\"ModelManager\")\n                }\n            }\n\n            OrtEnvironment.getEnvironment()\n                .createSession((model ?: return null).file.absolutePath, options)\n                .also { session = it }\n        }.onFailure { e ->\n            e.makeLog(\"createSession\")\n            model?.let {\n                appScope.launch { deleteModel(it) }\n            }\n        }.getOrNull()\n    }\n\n    private fun closeSession() {\n        session?.close()\n        session = null\n    }\n\n    private suspend fun fetchDownloadedModels(\n        onGetFiles: (List<File>) -> Unit\n    ) = withContext(ioDispatcher) {\n        modelsDir.listFiles().orEmpty().toList().filter {\n            !it.name.orEmpty().endsWith(\".tmp\") && !it.name.isNullOrEmpty() && it.length() > 0\n        }.also(onGetFiles).mapNotNull {\n            val name = it.name\n\n            if (name.isNullOrEmpty() || it.length() <= 0) return@mapNotNull null\n\n            NeuralModel.find(name) ?: NeuralModel.Imported(\n                name = name,\n                checksum = HashingType.SHA_256.computeFromReadable(FileReadable(it))\n            )\n        }\n    }\n\n    private val NeuralModel.file: File get() = File(modelsDir, name)\n\n    private fun NeuralModel.asBgRemover(): GenericBackgroundRemover? {\n        return BgRemover.getRemover(\n            when {\n                name.startsWith(\"u2netp\") -> BgRemover.Type.U2NetP\n                name.startsWith(\"u2net\") -> BgRemover.Type.U2Net\n                name.startsWith(\"inspyrenet\") -> BgRemover.Type.InSPyReNet\n                name.startsWith(\"RMBG_1.4\") -> BgRemover.Type.RMBG1_4\n                name.startsWith(\"birefnet_swin_tiny\") -> BgRemover.Type.BiRefNetTiny\n                name.startsWith(\"isnet\") -> BgRemover.Type.ISNet\n                else -> return null\n            }\n        )\n    }\n\n    private suspend fun extractU2NetP() {\n        //Extraction from assets\n        BgRemover.downloadModel(BgRemover.Type.U2NetP).collect()\n    }\n\n    private inline fun <T> processImage(action: () -> T): T = try {\n        isProcessingImage = true\n        action()\n    } finally {\n        isProcessingImage = false\n    }\n\n}\n\nprivate val SELECTED_MODEL = stringPreferencesKey(\"SELECTED_MODEL\")"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/data/model/ChunkInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.data.model\n\nimport java.io.File\n\ninternal data class ChunkInfo(\n    val index: Int,\n    val inputFile: File,\n    val processedFile: File,\n    val x: Int,\n    val y: Int,\n    val width: Int,\n    val height: Int,\n    val col: Int,\n    val row: Int\n)"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/data/model/ModelInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.data.model\n\nimport ai.onnxruntime.NodeInfo\nimport ai.onnxruntime.OnnxJavaType\nimport ai.onnxruntime.OrtSession\nimport ai.onnxruntime.TensorInfo\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport com.t8rin.logger.makeLog\nimport kotlin.math.abs\n\ninternal class ModelInfo(\n    val strength: Float,\n    val overlap: Int,\n    chunkSize: Int,\n    disableChunking: Boolean,\n    session: OrtSession,\n    model: NeuralModel\n) {\n    val inputName: String\n    val inputInfoMap: Map<String, NodeInfo> = session.inputInfo\n    val inputChannels: Int\n    val outputChannels: Int\n    val isFp16: Boolean\n    val expectedWidth: Int?\n    val expectedHeight: Int?\n    val isScuNet = model.name.startsWith(\"scunet_\")\n    val isScuNetColor = model.name.startsWith(\"scunet_color\")\n    val isNonChunkable = model.isNonChunkable || disableChunking\n    val chunkSize = if (isScuNet) {\n        minOf(chunkSize, 256)\n    } else {\n        chunkSize\n    }\n    val minSpatialSize = getMinSpatialSize(model.name)\n\n    val scaleFactor: Int = scaleMap.entries.find {\n        model.name.contains(it.key)\n    }?.value ?: 1\n\n    init {\n        \"Initialized with chunkSize: $chunkSize, overlap: $overlap\"\n            .makeLog(\"ModelInfo\")\n        var foundInputName: String? = null\n        var foundInputChannels = 3\n        var foundOutputChannels = 3\n        var foundIsFp16 = false\n        var foundExpectedWidth: Int? = null\n        var foundExpectedHeight: Int? = null\n\n        for ((key, nodeInfo) in inputInfoMap) {\n            val tensorInfo = nodeInfo.info as? TensorInfo ?: continue\n            val shape = tensorInfo.shape\n            if ((tensorInfo.type == OnnxJavaType.FLOAT || tensorInfo.type == OnnxJavaType.FLOAT16) && shape.size == 4) {\n                foundInputName = key\n                foundInputChannels = if (shape[1] == 1L) 1 else 3\n                foundIsFp16 = (tensorInfo.type == OnnxJavaType.FLOAT16)\n                if (shape[2] > 0) foundExpectedHeight = shape[2].toInt()\n                if (shape[3] > 0) foundExpectedWidth = shape[3].toInt()\n                break\n            }\n        }\n\n        val outputInfoMap = session.outputInfo\n        for ((_, nodeInfo) in outputInfoMap) {\n            val tensorInfo = nodeInfo.info as? TensorInfo ?: continue\n            val shape = tensorInfo.shape\n            if ((tensorInfo.type == OnnxJavaType.FLOAT || tensorInfo.type == OnnxJavaType.FLOAT16) && shape.size == 4) {\n                foundOutputChannels = if (isScuNet) {\n                    if (shape[1] == 1L) 1 else 3\n                } else {\n                    if (abs(shape[1]) == 1L) 1 else 3\n                }\n                break\n            }\n        }\n        inputName = foundInputName ?: throw RuntimeException(\"Could not find valid input tensor\")\n        inputChannels = foundInputChannels\n        outputChannels = foundOutputChannels\n        isFp16 = foundIsFp16\n        expectedWidth = foundExpectedWidth\n        expectedHeight = foundExpectedHeight\n\n        \"Model input type: ${if (isFp16) \"FP16\" else \"FP32\"}, input channels: $inputChannels, output channels: $outputChannels, expected dimensions: ${expectedWidth ?: \"dynamic\"}x${expectedHeight ?: \"dynamic\"}, scaleFactor: $scaleFactor\"\n            .makeLog(\"ModelInfo\")\n    }\n}\n\nprivate val scaleMap = buildMap {\n    repeat(16) {\n        val scale = it + 1\n\n        put(\"x$scale\", scale)\n        put(\"${scale}x\", scale)\n    }\n}\n\nprivate val minSpatial = mapOf(\n    \"nafnet\" to 512\n)\n\nprivate fun getMinSpatialSize(modelName: String?): Int {\n    val normalized = modelName?.lowercase() ?: return 256\n    for ((pattern, size) in minSpatial) {\n        if (normalized.contains(pattern)) {\n            return size\n        }\n    }\n    return 256\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/di/AiToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.ai_tools.data.AndroidAiToolsRepository\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.AiToolsRepository\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface AiToolsModule {\n\n    @Binds\n    @Singleton\n    fun repository(impl: AndroidAiToolsRepository): AiToolsRepository<Bitmap>\n\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/domain/AiProgressListener.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.domain\n\ninterface AiProgressListener {\n    fun onError(error: String)\n    fun onProgress(currentChunkIndex: Int, totalChunks: Int)\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/domain/AiToolsRepository.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralParams\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.StateFlow\n\ninterface AiToolsRepository<Image> {\n    val occupiedStorageSize: StateFlow<Long>\n\n    val downloadedModels: StateFlow<List<NeuralModel>>\n\n    val selectedModel: StateFlow<NeuralModel?>\n\n    suspend fun selectModel(\n        model: NeuralModel?,\n        forced: Boolean = false\n    ): Boolean\n\n    fun downloadModel(\n        model: NeuralModel\n    ): Flow<DownloadProgress>\n\n    suspend fun importModel(\n        uri: String\n    ): SaveResult\n\n    suspend fun processImage(\n        image: Image,\n        listener: AiProgressListener,\n        params: NeuralParams\n    ): Image?\n\n    suspend fun deleteModel(model: NeuralModel)\n\n    fun cleanup()\n\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/domain/model/NeuralConstants.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.domain.model\n\ninternal object NeuralConstants {\n    const val DIR = \"ai_models\"\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/domain/model/NeuralModel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.HF_BASE_URL\nimport com.t8rin.imagetoolbox.core.resources.R\n\ndata class NeuralModel(\n    val downloadLink: String,\n    val name: String = downloadLink.substringAfterLast(\"/\"),\n    val title: String,\n    val description: Int?,\n    val type: Type?,\n    val speed: Speed?,\n    val downloadSize: Long,\n    val checksum: String\n) {\n    val supportsStrength = name.contains(\"fbcnn_\", true)\n    val isImported = downloadLink == \"imported\"\n    val isNonChunkable = name.contains(\"ddcolor\") || type == Type.REMOVE_BG\n\n    val pointerLink: String = downloadLink.replace(\"/resolve/\", \"/blob/\")\n\n    enum class Type {\n        UPSCALE, REMOVE_BG, COLORIZE, DE_JPEG, DENOISE, ARTIFACTS, ENHANCE, ANIME, SCANS\n    }\n\n    sealed interface Speed {\n        val speedValue: Float\n\n        fun clone(value: Float): Speed = when (this) {\n            is Fast -> copy(speedValue = value)\n            is Normal -> copy(speedValue = value)\n            is Slow -> copy(speedValue = value)\n            is VeryFast -> copy(speedValue = value)\n            is VerySlow -> copy(speedValue = value)\n        }\n\n        data class VeryFast(override val speedValue: Float) : Speed\n        data class Fast(override val speedValue: Float) : Speed\n        data class Normal(override val speedValue: Float) : Speed\n        data class Slow(override val speedValue: Float) : Speed\n        data class VerySlow(override val speedValue: Float) : Speed\n\n        companion object {\n            val entries by lazy {\n                listOf(\n                    VeryFast(0f),\n                    Fast(0f),\n                    Normal(0f),\n                    Slow(0f),\n                    VerySlow(0f)\n                )\n            }\n        }\n    }\n\n    companion object {\n        val entries: List<NeuralModel> by lazy {\n            listOf(\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/fbcnn/fbcnn_color_fp16.onnx\"),\n                    title = \"FBCNN Color\",\n                    description = R.string.model_fbcnn_color_fp16,\n                    type = Type.DE_JPEG,\n                    downloadSize = 143910675,\n                    speed = Speed.Fast(2.003f),\n                    checksum = \"1a678ff4f721b557fd8a7e560b99cb94ba92f201545c7181c703e7808b93e922\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/fbcnn/fbcnn_grey_fp16.onnx\"),\n                    title = \"FBCNN Grayscale\",\n                    description = R.string.model_fbcnn_gray_fp16,\n                    type = Type.DE_JPEG,\n                    downloadSize = 143903294,\n                    speed = Speed.VeryFast(1.992f),\n                    checksum = \"e220b9637a9f2c34a36c98b275b2c9d2b9c2c029e365be82111072376afbec54\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/fbcnn/fbcnn_gray_double_fp16.onnx\"),\n                    title = \"FBCNN Grayscale Strong\",\n                    description = R.string.model_fbcnn_gray_double_fp16,\n                    type = Type.DE_JPEG,\n                    downloadSize = 143903294,\n                    speed = Speed.VeryFast(1.934f),\n                    checksum = \"17feadd8970772f5ff85596cb9fb152ae3c2b82bca4deb52a7c8b3ecb2f7ac14\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_color-GAN.onnx\"),\n                    title = \"SCUNet Color GAN\",\n                    description = R.string.model_scunet_color_gan_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 91264256,\n                    speed = Speed.Fast(2.715f),\n                    checksum = \"79ae6073c91c2d25d1f199137a67c8d0f0807df27219cdd7d890f3cc6d5b43e7\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_color-PSNR.onnx\"),\n                    title = \"SCUNet Color PSNR\",\n                    description = R.string.model_scunet_color_psnr_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 91264256,\n                    speed = Speed.Fast(2.633f),\n                    checksum = \"b0f8c12f1575bb49e39a85924152f1c6d4b527a4aae0432c9e5c7397123465e3\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_gray_15_fp16.onnx\"),\n                    title = \"SCUNet Grayscale 15\",\n                    description = R.string.model_scunet_gray_15_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 37741895,\n                    speed = Speed.Fast(3.048f),\n                    checksum = \"8e8740cea4306c9a61215194f315e5c0dc9e06c726a9ddea77d978d804da7663\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_gray_25_fp16.onnx\"),\n                    title = \"SCUNet Grayscale 25\",\n                    description = R.string.model_scunet_gray_25_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 37741895,\n                    speed = Speed.Fast(3.033f),\n                    checksum = \"dec631fbdca7705bbff1fc779cf85a657dcb67f55359c368464dd6e734e1f2b7\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_gray_50_fp16.onnx\"),\n                    title = \"SCUNet Grayscale 50\",\n                    description = R.string.model_scunet_gray_50_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 37741895,\n                    speed = Speed.Fast(3.058f),\n                    checksum = \"48b7d07229a03d98b892d2b33aa4c572ea955301772e7fcb5fd10723552a1874\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_color_15_fp16.onnx\"),\n                    title = \"SCUNet Color 15\",\n                    description = R.string.model_scunet_color_15_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 42555584,\n                    speed = Speed.Fast(7.095f),\n                    checksum = \"25a3a07de278867df9d29e9d08fe555523bb0f9f78f8956c4af943a4eeb8c934\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_color_25_fp16.onnx\"),\n                    title = \"SCUNet Color 25\",\n                    description = R.string.model_scunet_color_25_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 42555584,\n                    speed = Speed.Fast(6.994f),\n                    checksum = \"34d25ec2187d24f9f25b9dc9d918e94e87217c129471adda8c9fdf2e5a1cb62a\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/scunet/scunet_color_50_fp16.onnx\"),\n                    title = \"SCUNet Color 50\",\n                    description = R.string.model_scunet_color_50_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 42555584,\n                    speed = Speed.Normal(7.229f),\n                    checksum = \"1c6bdc6d9e0c1dea314cf22d41c261d4c744bf0ae1ae6c59b9505c4b4d50febb\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/nanomodels/1x-AnimeUndeint-Compact-fp16.onnx\"),\n                    title = \"Anime Undeint\",\n                    description = R.string.model_anime_undeint,\n                    type = Type.ANIME,\n                    downloadSize = 2391605,\n                    speed = Speed.VeryFast(0.497f),\n                    checksum = \"e2927fe5c09ad61975bfa52f7a879e3cf044a190d5b25f147a363540cd00ccd3\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/nanomodels/1x-BroadcastToStudio_Compact-fp16.onnx\"),\n                    title = \"Broadcast To Studio\",\n                    description = R.string.model_broadcast,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 1200682,\n                    speed = Speed.VeryFast(0.625f),\n                    checksum = \"52836c782140058bcc695e90102c3ef54961ebab2c12e66298eaba25d42570bc\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/nanomodels/1x-RGB-max-Denoise-fp16.onnx\"),\n                    title = \"RGB Max Denoise\",\n                    description = R.string.model_rgb_max_denoise_fp16,\n                    type = Type.DENOISE,\n                    downloadSize = 310212,\n                    speed = Speed.VeryFast(0.172f),\n                    checksum = \"1bb02e6444f306fd8ad17758ed474f6e21b909cceda1cba9606b6e923f65a102\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/nanomodels/1x-WB-Denoise-fp16.onnx\"),\n                    title = \"WB Denoise\",\n                    description = R.string.model_wb_denoise,\n                    type = Type.DENOISE,\n                    downloadSize = 310212,\n                    speed = Speed.VeryFast(0.177f),\n                    checksum = \"50978ca2777b5720d1d57c8f284d5274c96746c8721c3c2fdccb1dfcea823af1\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/nanomodels/1x-span-anime-pretrain-fp16.onnx\"),\n                    title = \"SPAN Anime Pretrain\",\n                    description = R.string.model_span_anime_pretrain,\n                    type = Type.ANIME,\n                    downloadSize = 825768,\n                    speed = Speed.VeryFast(0.399f),\n                    checksum = \"1311da8ad10af1d763b6b22797150429b377f36dda1fb26af5e3ec9bcc2701d2\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/nanomodels/1xBook-Compact-fp16.onnx\"),\n                    title = \"Book Scan\",\n                    description = R.string.model_book_scan,\n                    type = Type.SCANS,\n                    downloadSize = 1200682,\n                    speed = Speed.VeryFast(0.452f),\n                    checksum = \"7305ec3a592c5209fc2887d1f12d9b79163fca37020a719f55c83344effdb3c0\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/nanomodels/1xOverExposureCorrection_compact-fp16.onnx\"),\n                    title = \"Overexposure Correction\",\n                    description = R.string.model_overexposure,\n                    type = Type.ENHANCE,\n                    downloadSize = 2391605,\n                    speed = Speed.VeryFast(0.492f),\n                    checksum = \"8fef8e73062d2eff56aacea17caa1162b094a8c8a8010f51084c7e2cf9403ded\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-Anti-Aliasing-fp16.onnx\"),\n                    title = \"Anti-Aliasing\",\n                    description = R.string.model_antialias,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33456842,\n                    speed = Speed.Slow(14.806f),\n                    checksum = \"acd4f12a59ec606772df496f422e27099d629316671b41793b7362e6e13fe8dd\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_ColorizerV2_22000G-fp16.onnx\"),\n                    title = \"Colorizer\",\n                    description = R.string.model_colorizer,\n                    type = Type.COLORIZE,\n                    downloadSize = 33456842,\n                    speed = Speed.Slow(15.125f),\n                    checksum = \"c42520288f29a61d85107439ffea4a755129cb2f3eddfabb396598dc5d867f40\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_DeSharpen-fp16.onnx\"),\n                    title = \"DeSharpen\",\n                    description = R.string.model_desharpen,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.VerySlow(15.593f),\n                    checksum = \"3c08f894e9b05bba52f3b10cf1fb712a2370a5f352b88c3cdb246a3c295c6531\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_DeEdge-fp16.onnx\"),\n                    title = \"DeEdge\",\n                    description = R.string.model_deedge,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(14.099f),\n                    checksum = \"ead4873ec5f6870343e7dbe121f3054335941b12cf6fa4d0b54010c2cc3c0675\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_GainresV4-fp16.onnx\"),\n                    title = \"GainRes\",\n                    description = R.string.model_gainres,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(14.415f),\n                    checksum = \"a23d8157c6f809492ebbdd42632b865ce3e6c360221e7195aecc519ce610f3ac\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-DeBink-v4.onnx\"),\n                    title = \"DeBink v4\",\n                    description = R.string.model_debink_v4,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(12.947f),\n                    checksum = \"be52e251dff5a0c4504c559bb84d1b611c2e809edc99f1c261db646cd89a12fb\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-DeBink-v5.onnx\"),\n                    title = \"DeBink v5\",\n                    description = R.string.model_debink_v5,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(13.597f),\n                    checksum = \"f545222af1655b96f5b2aa3d46c40d8f256937cd2cbc2f77a6f89f29abf01e46\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-DeBink-v6.onnx\"),\n                    title = \"DeBink v6\",\n                    description = R.string.model_debink_v6,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(13.789f),\n                    checksum = \"e1c216804795a061218aa29617db52b91fb741c92bb00691da7caf9a64ef4f18\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-KDM003-scans-fp16.onnx\"),\n                    title = \"KDM003 Scans\",\n                    description = R.string.model_kdm003_scans,\n                    type = Type.SCANS,\n                    downloadSize = 33456842,\n                    speed = Speed.Slow(14.948f),\n                    checksum = \"85c740d5bdf8aa714b5b53eea1aa67c4c9e5483652702a31779a10f7a2ec9e45\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-NMKD-Jaywreck3-Lite-fp16.onnx\"),\n                    title = \"NMKD Jaywreck3 Lite\",\n                    description = R.string.model_nmkd_jaywreck3_lite,\n                    type = Type.ENHANCE,\n                    downloadSize = 10114140,\n                    speed = Speed.Fast(4.896f),\n                    checksum = \"4f72d8532e0632e87bcb0d03ff611bdac348e615873bb7c990c6291b0f08a495\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-SpongeColor-Lite-fp16.onnx\"),\n                    title = \"SpongeColor Lite\",\n                    description = R.string.model_spongecolor_lite,\n                    type = Type.COLORIZE,\n                    downloadSize = 10112988,\n                    speed = Speed.Fast(4.731f),\n                    checksum = \"c0b9df99d0cb0857eb96e0f8fb718c9010c2eeab9c30c17b0deacee79e2d2851\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-cinepak-fp16.onnx\"),\n                    title = \"Cinepak\",\n                    description = R.string.model_cinepak,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33456842,\n                    speed = Speed.VerySlow(15.515f),\n                    checksum = \"55cd3df1d3700dd31f09309beedce65f4d178d4b6e7777ecce05818bb60a2c67\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_BCGone-DetailedV2_40-60_115000_G-fp16.onnx\"),\n                    title = \"BCGone Detailed V2\",\n                    description = R.string.model_bcgone_detailed_v2,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(14.694f),\n                    checksum = \"a5237ef67f250871626020af3fc817bb6647888886cfc5b82a8e49718e52d3f4\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_BCGone_Smooth_110000_G-fp16.onnx\"),\n                    title = \"BCGone Smooth\",\n                    description = R.string.model_bcgone_smooth,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.VerySlow(15.44f),\n                    checksum = \"597ac90e1cc3105631b3a06c354cf055f1bccdfc440e4fdfe069918d228c3cdf\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_Bandage-Smooth-fp16.onnx\"),\n                    title = \"Bandage Smooth\",\n                    description = R.string.model_bandage_smooth,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33456842,\n                    speed = Speed.Slow(15.176f),\n                    checksum = \"40f98955aba23e2360b7f9f2e800e896be0d6a8071a3ff0a4bbb6cf24cd8656d\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_Bendel_Halftone-fp32.onnx\"),\n                    title = \"Bendel Halftone\",\n                    description = R.string.model_bendel_halftone,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 8660947,\n                    speed = Speed.Fast(4.019f),\n                    checksum = \"6982ab0c770ac4c210dd6df435c96aca609dfbec8745d8ff6c57db6bae88eead\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_DitherDeleterV3-Smooth-fp16.onnx\"),\n                    title = \"Dither Deleter V3 Smooth\",\n                    description = R.string.model_dither_deleter_v3_smooth,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.VerySlow(15.618f),\n                    checksum = \"55b0189c77caa8aa848d8b4c1dbf737a265d2a22f3ad0ea3805d9d6fc0881b3b\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_JPEGDestroyerV2_96000G-fp16.onnx\"),\n                    title = \"JPEG Destroyer V2\",\n                    description = R.string.model_jpeg_destroyer_v2,\n                    type = Type.DE_JPEG,\n                    downloadSize = 33456842,\n                    speed = Speed.Slow(14.9f),\n                    checksum = \"96734e021e1b616ab3e74376244895bbeed118e454e051a548f5b98a113305c9\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_NMKD-h264Texturize-fp16.onnx\"),\n                    title = \"NMKD H264 Texturize\",\n                    description = R.string.model_nmkd_h264_texturize,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33456842,\n                    speed = Speed.Slow(14.886f),\n                    checksum = \"4291323f8f4eee0623d9c01416cb8f918b61285b6e4f4112f0dfc341c0f39397\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/VHS-Sharpen-1x_46000_G-fp16.onnx\"),\n                    title = \"VHS Sharpen\",\n                    description = R.string.model_vhs_sharpen,\n                    type = Type.ENHANCE,\n                    downloadSize = 33456842,\n                    speed = Speed.Slow(15.192f),\n                    checksum = \"6d69cc4fb4fdcc34dd779a95032ddf5f32e99d5399c9dffcd557c0c3859ab866\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_artifacts_dithering_alsa-fp16.onnx\"),\n                    title = \"Artifacts Dithering ALSA\",\n                    description = R.string.model_artifacts_dithering_alsa,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33421271,\n                    speed = Speed.VerySlow(15.392f),\n                    checksum = \"668bf366457c774e10cb46a756bf9744165c53671180969d4bab47ce935cd520\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_NMKD-BrightenRedux_200k-fp16.onnx\"),\n                    title = \"NMKD Brighten Redux\",\n                    description = R.string.model_nmkd_brighten_redux,\n                    type = Type.ENHANCE,\n                    downloadSize = 33421271,\n                    speed = Speed.Slow(14.863f),\n                    checksum = \"93f50904fa78948da69ff541b42fd9ce3e0fa096d87ca22f1f2f0ebb929f1c76\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_nmkdbrighten_10000_G-fp16.onnx\"),\n                    title = \"NMKD Brighten\",\n                    description = R.string.model_nmkd_brighten,\n                    type = Type.ENHANCE,\n                    downloadSize = 33421271,\n                    speed = Speed.Slow(14.803f),\n                    checksum = \"e1c354370c04bc0433bdb54fc81898c1ade0c2db02cc02878a58aac6195c7f52\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_NMKDDetoon_97500_G-fp16.onnx\"),\n                    title = \"NMKD Detoon\",\n                    description = R.string.model_nmkd_detoon,\n                    type = Type.ENHANCE,\n                    downloadSize = 33421271,\n                    speed = Speed.Slow(14.817f),\n                    checksum = \"b75acf61a6067777dc591cb31c77a79fb73db3b72468796d69ceec73e58ac32d\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_NoiseToner-Poisson-Detailed_108000_G-fp16.onnx\"),\n                    title = \"Noise Toner Poisson Detailed\",\n                    description = R.string.model_noise_toner_poisson_detailed,\n                    type = Type.DENOISE,\n                    downloadSize = 33421271,\n                    speed = Speed.Normal(14.463f),\n                    checksum = \"ed6bb382f71385032df8fcf16ea0a1d0469de801338ed32abcc5a01557944460\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_NoiseToner-Poisson-Soft_101000_G-fp16.onnx\"),\n                    title = \"Noise Toner Poisson Soft\",\n                    description = R.string.model_noise_toner_poisson_soft,\n                    type = Type.DENOISE,\n                    downloadSize = 33421271,\n                    speed = Speed.Normal(14.606f),\n                    checksum = \"e4d18cc399e4fbf2b5239b00b640c8ff0e80811bf88ded7f151eec6760eb0471\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_NoiseToner-Uniform-Detailed_100000_G-fp16.onnx\"),\n                    title = \"Noise Toner Uniform Detailed\",\n                    description = R.string.model_noise_toner_uniform_detailed,\n                    type = Type.DENOISE,\n                    downloadSize = 33421271,\n                    speed = Speed.Normal(14.802f),\n                    checksum = \"e5602a5e1aabb8ec6ee98969d834224ac1b4b366f89a4ec26b3fae93077a4dbf\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_NoiseToner-Uniform-Soft_100000_G-fp16.onnx\"),\n                    title = \"Noise Toner Uniform Soft\",\n                    description = R.string.model_noise_toner_uniform_soft,\n                    type = Type.DENOISE,\n                    downloadSize = 33421271,\n                    speed = Speed.Slow(15.001f),\n                    checksum = \"54622791711ab457565fa0a750f668f209171a0194d0f94c206243d9a649f797\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_Repainter_20000_G-fp16.onnx\"),\n                    title = \"Repainter\",\n                    description = R.string.model_repainter,\n                    type = Type.ENHANCE,\n                    downloadSize = 33421271,\n                    speed = Speed.Normal(14.775f),\n                    checksum = \"202fdce20d84ab0da25ea0d348d2f2c29546a28509e778ef8d699fb82fcf873d\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-Debandurh-FS-Ultra-lite-fp16.onnx\"),\n                    title = \"Debandurh FS Ultra Lite\",\n                    description = R.string.model_debandurh_fs_ultra_lite,\n                    type = Type.ENHANCE,\n                    downloadSize = 1371141,\n                    speed = Speed.VeryFast(0.741f),\n                    checksum = \"6aef5e015176c48984db80e95c31539d0d1e2c1fef9bac04b335253ce372b8a9\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_JPEG_00-20.ort\"),\n                    title = \"JPEG 0-20\",\n                    description = R.string.model_jpeg_0_20,\n                    type = Type.DE_JPEG,\n                    downloadSize = 35277480,\n                    speed = Speed.VerySlow(15.994f),\n                    checksum = \"9230d501dc34fd6ef3c6dcc7640df95c20627482ff93cb236a93060bd0c9826b\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_JPEG_20-40.ort\"),\n                    title = \"JPEG 20-40\",\n                    description = R.string.model_jpeg_20_40,\n                    type = Type.DE_JPEG,\n                    downloadSize = 35277488,\n                    speed = Speed.VerySlow(15.754f),\n                    checksum = \"bbdbd9cdb86d56a5a88b0ccf8ad833d6a1ebfc4202cc25c6d139bb09a6a2535d\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_JPEG_40-60.ort\"),\n                    title = \"JPEG 40-60\",\n                    description = R.string.model_jpeg_40_60,\n                    type = Type.DE_JPEG,\n                    downloadSize = 35277480,\n                    speed = Speed.VerySlow(15.959f),\n                    checksum = \"dc248a7166cbcdcf8577d6cbd80a6d8aab3a3a7c9e2ebda29341353b4050664b\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_JPEG_60-80.ort\"),\n                    title = \"JPEG 60-80\",\n                    description = R.string.model_jpeg_60_80,\n                    type = Type.DE_JPEG,\n                    downloadSize = 35277488,\n                    speed = Speed.Normal(14.307f),\n                    checksum = \"21ece5396cf88f39f35a264000baf2ff2ec084ca7fd41b125759d845b1bfb9c3\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_JPEG_80-100.ort\"),\n                    title = \"JPEG 80-100\",\n                    description = R.string.model_jpeg_80_100,\n                    type = Type.DE_JPEG,\n                    downloadSize = 35277488,\n                    speed = Speed.Slow(15.018f),\n                    checksum = \"1041060d1d151150e14e8d51c65cd5f6608606bb4bf7ac6b5271ae074e5c3913\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_DeBLR.ort\"),\n                    title = \"DeBLR\",\n                    description = R.string.model_deblr,\n                    type = Type.ENHANCE,\n                    downloadSize = 35277480,\n                    speed = Speed.VerySlow(16.079f),\n                    checksum = \"261eb9690bc284d8cee5d81dd6156d92f9c3338c582019387a3852257c8a7b3a\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_artifacts_jpg_00_20_alsa-fp16.ort\"),\n                    title = \"JPEG Artifacts 0-20\",\n                    description = R.string.model_artifacts_jpg_0_20,\n                    type = Type.DE_JPEG,\n                    downloadSize = 34729312,\n                    speed = Speed.Slow(15.041f),\n                    checksum = \"8a416ffa7f1d78de7b3a8d211a123964b277fcb7c253f78b8e79970c7ed114bb\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_artifacts_jpg_20_40_alsa-fp16.ort\"),\n                    title = \"JPEG Artifacts 20-40\",\n                    description = R.string.model_artifacts_jpg_20_40,\n                    type = Type.DE_JPEG,\n                    downloadSize = 34729312,\n                    speed = Speed.Normal(14.733f),\n                    checksum = \"2abe485266cd1895e17b4166c5609f30a1d4d7283b9d8b2503c94f008a39244f\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_artifacts_jpg_40_60_alsa-fp16.ort\"),\n                    title = \"JPEG Artifacts 40-60\",\n                    description = R.string.model_artifacts_jpg_40_60,\n                    type = Type.DE_JPEG,\n                    downloadSize = 34729312,\n                    speed = Speed.Slow(14.973f),\n                    checksum = \"bd0116861368b83a459af687308a8acd7dc4c89aa8ba5c3dab76adb67ef9002f\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_artifacts_jpg_60_80_alsa-fp16.ort\"),\n                    title = \"JPEG Artifacts 60-80\",\n                    description = R.string.model_artifacts_jpg_60_80,\n                    type = Type.DE_JPEG,\n                    downloadSize = 34729312,\n                    speed = Speed.Normal(14.572f),\n                    checksum = \"5282f04a4520bcff4882836d134e99dbfc207f7fcaf4bf9166a99d623f579f4e\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_artifacts_jpg_80_100_alsa-fp16.ort\"),\n                    title = \"JPEG Artifacts 80-100\",\n                    description = R.string.model_artifacts_jpg_80_100,\n                    type = Type.DE_JPEG,\n                    downloadSize = 34729312,\n                    speed = Speed.VerySlow(15.404f),\n                    checksum = \"8d11451909d9318f54e1b292c0bf901856633bce835ee838bbcf4bfaf5cd174a\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_ReDetail_v2_126000_G-fp16.ort\"),\n                    title = \"ReDetail v2\",\n                    description = R.string.model_redetail_v2,\n                    type = Type.ENHANCE,\n                    downloadSize = 34724216,\n                    speed = Speed.Slow(15.265f),\n                    checksum = \"4a1790847f8e3b51ace425875abe928215d32e00d0b80af0ce90dd3481d6f272\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x-ITF-SkinDiffDetail-Lite-v1.ort\"),\n                    title = \"ITF Skin DiffDetail Lite\",\n                    description = R.string.model_itf_skin_diffdetail_lite,\n                    type = Type.ENHANCE,\n                    downloadSize = 11070576,\n                    speed = Speed.Fast(5.138f),\n                    checksum = \"813351fcee2447ff9037c86bf2807baee7a32be1db20352646c5a3eda8ced7b8\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_SBDV-DeJPEG-Lite_130000_G.ort\"),\n                    title = \"SBDV DeJPEG\",\n                    description = R.string.model_sbdv_dejpeg,\n                    type = Type.DE_JPEG,\n                    downloadSize = 11070576,\n                    speed = Speed.Fast(5.158f),\n                    checksum = \"3039271c69e3f5b3ca9af3673bea98749dffa9331930f88d057047b57d6001dc\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_ISO_denoise_v1.ort\"),\n                    title = \"ISO Denoise v1\",\n                    description = R.string.model_iso_denoise_v1,\n                    type = Type.DENOISE,\n                    downloadSize = 35277480,\n                    speed = Speed.VerySlow(15.463f),\n                    checksum = \"a16b9253a10a7e95aa10e451b2ad21b3d60124c1316ddaca746071f5843b312b\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/1x_DeJumbo.ort\"),\n                    title = \"DeJumbo\",\n                    description = R.string.model_dejumbo,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 35277488,\n                    speed = Speed.VerySlow(15.717f),\n                    checksum = \"17202a453ad7f7c89c6969d2dd0cd844b01f6685584876e54092e59f589ad180\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/other-models/ddcolor_paper_tiny.ort\"),\n                    title = \"DDColor Tiny\",\n                    description = R.string.model_ddcolor_tiny,\n                    type = Type.COLORIZE,\n                    downloadSize = 220853232,\n                    speed = Speed.VeryFast(0.159f),\n                    checksum = \"8186a8c21a5075c0c37860d7313043b6edb8a672067f73f3d8f5d362509f1bd3\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/RealESRGAN-x4v3.ort\"),\n                    title = \"RealESRGAN x4v3\",\n                    description = R.string.model_realesrgan_x4v3,\n                    type = Type.UPSCALE,\n                    downloadSize = 2621440,\n                    speed = Speed.VeryFast(1.215f),\n                    checksum = \"8dbd9c316f436c6e1d35a11ed29dbea0ce8f5b5b3ef082c9358ec93603a0398b\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/RealESRGAN_x2plus.ort\"),\n                    title = \"RealESRGAN x2 Plus\",\n                    description = R.string.model_realesrgan_x2plus,\n                    type = Type.UPSCALE,\n                    downloadSize = 35456784,\n                    speed = Speed.Fast(4.437f),\n                    checksum = \"cd6986ac4bd2d10d460c281dcd4f1df638fddb241f4810b53cb0eb98cfb420cd\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/RealESRGAN_x4plus.ort\"),\n                    title = \"RealESRGAN x4 Plus\",\n                    description = R.string.model_realesrgan_x4plus,\n                    type = Type.UPSCALE,\n                    downloadSize = 35437480,\n                    speed = Speed.VerySlow(18.018f),\n                    checksum = \"110818e1a29309d1da6087e8bbe201f50e43ea7679483ebca1df95ab333d2a66\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/RealESRGAN_x4plus_anime_6B.ort\"),\n                    title = \"RealESRGAN x4 Plus Anime 6B\",\n                    description = R.string.model_realesrgan_x4plus_anime,\n                    type = Type.UPSCALE,\n                    downloadSize = 9488256,\n                    speed = Speed.Fast(5.793f),\n                    checksum = \"e73004a743169923b28434b1487ed2f8c329fa99c057ffa15018502612b8bd36\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/RealESRNet_x4plus.ort\"),\n                    title = \"RealESRNet x4 Plus\",\n                    description = R.string.model_realesrnet_x4plus,\n                    type = Type.UPSCALE,\n                    downloadSize = 35437480,\n                    speed = Speed.VerySlow(17.11f),\n                    checksum = \"ed82b5cd61a6281db0eafa722c92803cecbf9eda8c88194c058e93e21407d38f\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/RealESRGAN_x4plus_anime_4B32F.ort\"),\n                    title = \"RealESRGAN x4 Plus Anime 4B\",\n                    description = R.string.model_realesrgan_x4plus_anime_4b32f,\n                    type = Type.UPSCALE,\n                    downloadSize = 5241720,\n                    speed = Speed.VeryFast(1.534f),\n                    checksum = \"ca05a00f6cb42fb1fdf03e3b132ae792a83d748fc8df0c0fa62f67e798385fd7\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/x4-UltraSharpV2_fp32_op17.ort\"),\n                    title = \"UltraSharp x4 V2\",\n                    description = R.string.model_ultrasharp_v2_x4,\n                    type = Type.UPSCALE,\n                    downloadSize = 80518784,\n                    speed = Speed.VerySlow(36.695f),\n                    checksum = \"6bbf8c91bced8c7c6fdacf841f34713b66b223fe5ccd5f579af04e077fa68302\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/enhance/upscale/x4-UltraSharpV2_Lite_fp16_op17.ort\"),\n                    title = \"UltraSharp x4 V2 Lite\",\n                    description = R.string.model_ultrasharp_v2_lite_x4,\n                    type = Type.UPSCALE,\n                    downloadSize = 16055408,\n                    speed = Speed.Normal(7.718f),\n                    checksum = \"f65092e0ee88c41bdbb1eb633aa4014479599228c150f796e85d429aea4d43a0\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/bgremove/RMBG_1.4.ort\"),\n                    title = \"RMBG 1.4\",\n                    description = R.string.model_rmbg_1_4,\n                    type = Type.REMOVE_BG,\n                    downloadSize = 88704616,\n                    speed = Speed.Normal(0.603f),\n                    checksum = \"ecefc6e25e88a403762e74e2d112cd8f9dea4f4628c73f3da914ef169c91d86f\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/bgremove/inspyrenet.onnx\"),\n                    title = \"InSPyReNet\",\n                    description = R.string.model_inspyrenet,\n                    type = Type.REMOVE_BG,\n                    downloadSize = 395316574,\n                    speed = Speed.Slow(3.029f),\n                    checksum = \"c108dd92b3ddfe3a2d9e9ac2b74730cc5acbb2ddc7ea863330c43f56ae832aa3\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/bgremove/u2net.onnx\"),\n                    title = \"U2Net\",\n                    description = R.string.model_u2net,\n                    type = Type.REMOVE_BG,\n                    downloadSize = 175997641,\n                    speed = Speed.Fast(0.19f),\n                    checksum = \"8d10d2f3bb75ae3b6d527c77944fc5e7dcd94b29809d47a739a7a728a912b491\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"onnx/bgremove/u2netp.onnx\"),\n                    title = \"U2NetP\",\n                    description = R.string.model_u2netp,\n                    type = Type.REMOVE_BG,\n                    downloadSize = 4574861,\n                    speed = Speed.VeryFast(0.074f),\n                    checksum = \"309c8469258dda742793dce0ebea8e6dd393174f89934733ecc8b14c76f4ddd8\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"ddcolor_modelscope.onnx\"),\n                    title = \"DDColor\",\n                    description = R.string.model_ddcolor,\n                    type = Type.COLORIZE,\n                    downloadSize = 911801965,\n                    speed = Speed.VeryFast(0.362f),\n                    checksum = \"cda896f3e61c0e489f2e11a657c6dfb711d0958364286335e3cd48fadbd621be\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"ddcolor_artistic.onnx\"),\n                    title = \"DDColor Artistic\",\n                    description = R.string.model_ddcolor_artistic,\n                    type = Type.COLORIZE,\n                    downloadSize = 911801965,\n                    speed = Speed.VeryFast(0.334f),\n                    checksum = \"e7f6d8e48d609be3f2615b70637fbc7019cbad545038279a7ba26f229503d61c\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"birefnet_swin_tiny.ort\"),\n                    title = \"BiRefNet\",\n                    description = R.string.model_birefnet,\n                    type = Type.REMOVE_BG,\n                    downloadSize = 247356800,\n                    speed = Speed.VerySlow(4.117f),\n                    checksum = \"46512ae91e17171c09476e3154fa2f2f8b0a557b3c8e9c91c10d11f35bc3f70c\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"isnet-general-use.onnx\"),\n                    title = \"ISNet\",\n                    description = R.string.model_isnet,\n                    type = Type.REMOVE_BG,\n                    downloadSize = 178647984,\n                    speed = Speed.Normal(0.573f),\n                    checksum = \"4fcc3f7f7af1d16565dd7ec767e6e2500565ed6ba76c5c30b9934116ca32153e\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/1x-Fatality-DeBlur.onnx\"),\n                    title = \"Fatality DeBlur\",\n                    description = R.string.model_fatality_deblur,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(11.609f),\n                    checksum = \"ea7b0d0d873151265ed096a55f9911240a7ef0b66db419c6f6912f2cf0c94888\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/1x-UnResize-V3.onnx\"),\n                    title = \"UnResize V3\",\n                    description = R.string.model_unresize_v3,\n                    type = Type.ARTIFACTS,\n                    downloadSize = 33456842,\n                    speed = Speed.Normal(12.356f),\n                    checksum = \"f4d67d604a8cc3fb184a662f3e2fe427a80cef444e87870be8b8eedfda774fd2\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/2xLiveActionV1_SPAN_490000.onnx\"),\n                    title = \"LiveAction V1 SPAN x2\",\n                    description = R.string.model_liveaction_v1_span,\n                    type = Type.UPSCALE,\n                    downloadSize = 1654748,\n                    speed = Speed.VeryFast(0.311f),\n                    checksum = \"bfa72f3c6347076aed140d0836cee30c27ea434c047beeaf9466469483836ecc\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/2xVHS2HD-RealPLKSR.onnx\"),\n                    title = \"VHS to HD x2\",\n                    description = R.string.model_vhs2hd_realplksr,\n                    type = Type.UPSCALE,\n                    downloadSize = 29718646,\n                    speed = Speed.Fast(5.591f),\n                    checksum = \"441c8c8acedee4cf79c5629779e7720aef25952cfc68ca137034d835bbfa66f4\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/2x_Text2HD_v.1-RealPLKSR.onnx\"),\n                    title = \"Text2HD x2\",\n                    description = R.string.model_text2hd_v1,\n                    type = Type.UPSCALE,\n                    downloadSize = 29718646,\n                    speed = Speed.Fast(5.550f),\n                    checksum = \"0c3ef0e30de53ff0156da5fb4593dd4cbc89eee4707ca8e84d640302e4b9c3df\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/4x-FrankendataPretrainer_SRFormer400K.onnx\"),\n                    title = \"SRFormer x4\",\n                    description = R.string.model_frankendata_pretrainer,\n                    type = Type.UPSCALE,\n                    downloadSize = 120837871,\n                    speed = Speed.Slow(15.130f),\n                    checksum = \"6f505d321e07dadaa3f2f2cb91e4cb37cc47ba630a601fa4207abae6f8877bbc\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/4xRealWebPhoto_v2_rgt_s.onnx\"),\n                    title = \"RealWebPhoto v2 RGT-S x4\",\n                    description = R.string.model_realwebphoto_v2,\n                    type = Type.UPSCALE,\n                    downloadSize = 48824340,\n                    speed = Speed.VerySlow(39.655f),\n                    checksum = \"1c014ca191c9e3c41c47e26a6fe859a6847dd00d9d49073386e7104ac438450e\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/4xRealWebPhoto_v4_dat2.onnx\"),\n                    title = \"RealWebPhoto v4 DAT2 x4\",\n                    description = R.string.model_realwebphoto_v4,\n                    type = Type.UPSCALE,\n                    downloadSize = 48760847,\n                    speed = Speed.VerySlow(25.959f),\n                    checksum = \"a9a3a9099e0108b793556ed9cf2123a61a727bbc611dd8d93475f7144596589e\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/DAT_2_x2.onnx\"),\n                    title = \"DAT2 x2\",\n                    description = R.string.model_dat_2x,\n                    type = Type.UPSCALE,\n                    downloadSize = 49503576,\n                    speed = Speed.VerySlow(25.567f),\n                    checksum = \"fee6f4901207b1b5f68900ebbc7e0a2dbcb881b8ddfac97219f118af2cc53066\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/DAT_2_x3.onnx\"),\n                    title = \"DAT2 x3\",\n                    description = R.string.model_dat_3x,\n                    type = Type.UPSCALE,\n                    downloadSize = 50242136,\n                    speed = Speed.VerySlow(25.736f),\n                    checksum = \"59aeb6835c29f57dc9cab3b1367ec670eddc5b51d5a8177f3f921ad7ffb63ad9\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/DAT_2_x4.onnx\"),\n                    title = \"DAT2 x4\",\n                    description = R.string.model_dat_4x,\n                    type = Type.UPSCALE,\n                    downloadSize = 50094919,\n                    speed = Speed.VerySlow(26.169f),\n                    checksum = \"e6354e8fdd1b31b6e1114300843bf7bc31f91e4294fbb8e41282fc43f0a46cbc\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"deblurring_nafnet_2025may.onnx\"),\n                    title = \"NAFNET deblurring\",\n                    description = R.string.model_nafnet_deblurring,\n                    type = Type.DENOISE,\n                    downloadSize = 91736251,\n                    speed = Speed.VeryFast(1.371f),\n                    checksum = \"07263f416febecce10193dd648e950b22e397cf521eedab1a114ef77b2bc9587\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/swin2SR-x4-bsrgan-psnr.onnx\"),\n                    title = \"Swin2SR BSRGAN PSNR x4\",\n                    description = R.string.model_swin2sr_x4_bsrgan_psnr,\n                    type = Type.UPSCALE,\n                    downloadSize = 53827735,\n                    speed = Speed.Normal(14.478f),\n                    checksum = \"987d88b356554161cbb8f67b7a8f4162cad6dc147839c344e3d5142140f25d6f\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/BSRGAN_SwinIR-M_x4_GAN.onnx\"),\n                    title = \"SwinIR-M BSRGAN GAN x4\",\n                    description = R.string.model_bsrgan_swinir_m_x4_gan,\n                    type = Type.UPSCALE,\n                    downloadSize = 61316800,\n                    speed = Speed.Normal(13.116f),\n                    checksum = \"50a7b6fcaad6c4f342c5e1d059916a3e5d48e89d1d311270a476a7ce6a2ea09f\"\n                ),\n                NeuralModel(\n                    downloadLink = res(\"upscalers/RealESR-AnimeVideo-x4v3.onnx\"),\n                    title = \"RealESR AnimeVideo x4v3\",\n                    description = R.string.model_realesr_animevideo_v3x4,\n                    type = Type.UPSCALE,\n                    downloadSize = 2495473,\n                    speed = Speed.VeryFast(0.437f),\n                    checksum = \"3d2dc0af5e2cdf3a31655c4c673df9ad74f14775d74237bd0dc68fc885bd6841\"\n                ),\n            ).sortedBy { it.type?.ordinal }\n        }\n\n        fun find(name: String?): NeuralModel? = entries.find { model ->\n            model.name.equals(name, true)\n        }\n\n        fun Imported(\n            name: String,\n            checksum: String\n        ): NeuralModel = NeuralModel(\n            downloadLink = \"imported\",\n            name = name,\n            title = name.replace(\"_\", \" \").replace(\"-\", \" \").substringBefore('.'),\n            description = null,\n            type = null,\n            speed = null,\n            downloadSize = 0,\n            checksum = checksum\n        )\n\n        private fun res(path: String): String = HF_BASE_URL.replace(\"*\", path)\n    }\n\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/domain/model/NeuralParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.domain.model\n\ndata class NeuralParams(\n    val strength: Float,\n    val chunkSize: Int,\n    val overlap: Int,\n    val enableChunking: Boolean\n) {\n    companion object {\n        val Default by lazy {\n            NeuralParams(\n                strength = 65f,\n                chunkSize = 512,\n                overlap = 16,\n                enableChunking = true\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/AiToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.lifecycle.compose.collectAsStateWithLifecycle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.image.urisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.components.AiToolsControls\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.components.NeuralSaveProgressDialog\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic.AiToolsComponent\n\n@Composable\nfun AiToolsContent(\n    component: AiToolsComponent\n) {\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.updateUris(\n            uris = uris\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val addImagesImagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.addUris(\n            uris = uris\n        )\n    }\n\n    val selectedModel by component.selectedModel.collectAsStateWithLifecycle()\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                modifier = Modifier.marquee()\n            ) {\n                Text(\n                    text = stringResource(R.string.ai_tools)\n                )\n                EnhancedBadge(\n                    content = {\n                        Text(\n                            text = NeuralModel.entries.size.toString()\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.tertiary,\n                    contentColor = MaterialTheme.colorScheme.onTertiary,\n                    modifier = Modifier\n                        .padding(horizontal = 2.dp)\n                        .padding(bottom = 12.dp)\n                        .scaleOnTap {\n                            AppToastHost.showConfetti()\n                        }\n                )\n            }\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                onShare = component::shareBitmaps,\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        showImagePreviewAsStickyHeader = false,\n        imagePreview = {\n            UrisPreview(\n                modifier = Modifier.urisPreview(),\n                uris = component.uris.orEmpty(),\n                isPortrait = true,\n                onRemoveUri = component::removeUri,\n                onAddUris = addImagesImagePicker::pickImage,\n                onNavigate = component.onNavigate\n            )\n        },\n        controls = {\n            AiToolsControls(\n                component = component\n            )\n        },\n        noDataControls = {\n            ImageNotPickedWidget(onPickImage = pickImage)\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                isPrimaryButtonVisible = selectedModel != null,\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.uris.isNullOrEmpty()) {\n                TopAppBarEmoji()\n            }\n        },\n        canShowScreenData = !component.uris.isNullOrEmpty()\n    )\n\n    NeuralSaveProgressDialog(\n        component = component\n    )\n\n    LoadingDialog(\n        visible = component.isImageLoading,\n        canCancel = false\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/AiToolsControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.WarningAmber\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.lifecycle.compose.collectAsStateWithLifecycle\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Cube\nimport com.t8rin.imagetoolbox.core.resources.icons.Exercise\nimport com.t8rin.imagetoolbox.core.resources.icons.Stacks\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.derivative.OnlyAllowedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic.AiToolsComponent\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun AiToolsControls(component: AiToolsComponent) {\n    val selectedModel by component.selectedModel.collectAsStateWithLifecycle()\n    val downloadedModels by component.downloadedModels.collectAsStateWithLifecycle()\n    val notDownloadedModels by component.notDownloadedModels.collectAsStateWithLifecycle()\n    val occupiedStorageSize by component.occupiedStorageSize.collectAsStateWithLifecycle()\n    val isModelChunkable = selectedModel?.isNonChunkable != true\n    val isChunkable = isModelChunkable && component.params.enableChunking\n\n    NeuralModelSelector(\n        value = selectedModel,\n        onSelectModel = component::selectModel,\n        onDownloadModel = component::downloadModel,\n        onDeleteModel = component::deleteModel,\n        onImportModel = component::importModel,\n        downloadedModels = downloadedModels,\n        notDownloadedModels = notDownloadedModels,\n        downloadProgresses = component.downloadProgresses,\n        occupiedStorageSize = occupiedStorageSize,\n        onCancelDownload = component::cancelDownload\n    )\n\n    AnimatedVisibility(\n        visible = isChunkable,\n        modifier = Modifier.fillMaxSize()\n    ) {\n        Column {\n            AnimatedVisibility(\n                visible = selectedModel?.supportsStrength == true,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                EnhancedSliderItem(\n                    value = component.params.strength,\n                    internalStateTransformation = { it.roundToInt() },\n                    steps = 100,\n                    valueRange = 0f..100f,\n                    onValueChange = {\n                        component.updateParams { copy(strength = it) }\n                    },\n                    title = stringResource(R.string.strength),\n                    icon = Icons.Outlined.Exercise,\n                    modifier = Modifier.padding(top = 8.dp),\n                    shape = ShapeDefaults.large,\n                )\n            }\n\n            Spacer(Modifier.height(8.dp))\n\n            val chunkPowers = remember {\n                generateSequence(128) { it * 2 }.takeWhile { it <= 2048 }.toList()\n            }\n            val overlapPowers = remember {\n                generateSequence(16) { it * 2 }.takeWhile { it <= 128 }.toList()\n            }\n\n            OnlyAllowedSliderItem(\n                label = stringResource(id = R.string.chunk_size),\n                icon = Icons.Outlined.Cube,\n                value = component.params.chunkSize,\n                allowed = chunkPowers,\n                onValueChange = { component.updateParams { copy(chunkSize = it) } }\n            )\n            AnimatedVisibility(\n                visible = component.params.chunkSize >= 2048,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                Box(\n                    contentAlignment = Alignment.Center\n                ) {\n                    InfoContainer(\n                        text = stringResource(R.string.large_chunk_warning),\n                        containerColor = MaterialTheme.colorScheme.errorContainer.copy(0.4f),\n                        contentColor = MaterialTheme.colorScheme.onErrorContainer.copy(0.7f),\n                        icon = Icons.Rounded.WarningAmber,\n                        modifier = Modifier.padding(top = 8.dp)\n                    )\n                }\n            }\n            Spacer(Modifier.height(8.dp))\n            OnlyAllowedSliderItem(\n                label = stringResource(R.string.overlap_size),\n                icon = Icons.Outlined.Stacks,\n                value = component.params.overlap,\n                allowed = overlapPowers,\n                maxAllowed = component.params.chunkSize,\n                onValueChange = { component.updateParams { copy(overlap = it) } }\n            )\n        }\n    }\n\n    Spacer(Modifier.height(8.dp))\n\n    InfoContainer(\n        text = if (isChunkable) {\n            stringResource(R.string.note_chunk_info, component.params.chunkSize)\n        } else if (!isModelChunkable) {\n            stringResource(R.string.current_model_not_chunkable)\n        } else {\n            stringResource(R.string.chunking_disabled)\n        },\n        containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(0.4f),\n        contentColor = MaterialTheme.colorScheme.onSecondaryContainer.copy(0.8f)\n    )\n\n    Spacer(Modifier.height(8.dp))\n\n    ImageFormatSelector(\n        value = component.imageFormat,\n        entries = if (selectedModel?.type != NeuralModel.Type.REMOVE_BG) {\n            ImageFormatGroup.entries\n        } else {\n            ImageFormatGroup.alphaContainedEntries\n        },\n        onValueChange = component::setImageFormat,\n        onAutoClick = { component.setImageFormat(null) }\n    )\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/DeleteModelDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\n\n@Composable\ninternal fun DeleteModelDialog(\n    model: NeuralModel?,\n    onDismiss: () -> Unit,\n    onDeleteModel: (NeuralModel) -> Unit\n) {\n    EnhancedAlertDialog(\n        visible = model != null,\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.Delete,\n                contentDescription = null\n            )\n        },\n        title = { Text(stringResource(id = R.string.delete)) },\n        text = {\n            Text(\n                stringResource(\n                    id = R.string.delete_model_sub,\n                    model?.title ?: \"\",\n                )\n            )\n        },\n        onDismissRequest = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    model?.let(onDeleteModel)\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(R.string.confirm))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.cancel))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/FilteredModels.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getStringLocalized\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport java.util.Locale\n\n@Composable\ninternal fun filteredModels(\n    downloadedModels: List<NeuralModel>,\n    notDownloadedModels: List<NeuralModel>,\n    typeFilters: List<NeuralModel.Type>,\n    speedFilters: List<NeuralModel.Speed>,\n    keywordFilter: String,\n): State<Pair<List<NeuralModel>, List<NeuralModel>>> = remember(\n    downloadedModels,\n    notDownloadedModels,\n    typeFilters,\n    speedFilters,\n    keywordFilter\n) {\n    derivedStateOf {\n        downloadedModels.filter(\n            typeFilters = typeFilters,\n            speedFilters = speedFilters,\n            keywordFilter = keywordFilter.trim()\n        ) to notDownloadedModels.filter(\n            typeFilters = typeFilters,\n            speedFilters = speedFilters,\n            keywordFilter = keywordFilter.trim()\n        )\n    }\n}\n\nprivate fun List<NeuralModel>.filter(\n    typeFilters: List<NeuralModel.Type>,\n    speedFilters: List<NeuralModel.Speed>,\n    keywordFilter: String\n): List<NeuralModel> {\n    return if (typeFilters.isEmpty() && speedFilters.isEmpty() && keywordFilter.isBlank()) this\n    else filter { model ->\n        val hasType =\n            typeFilters.isEmpty() || model.type == null || model.type in typeFilters\n        val hasSpeed =\n            speedFilters.isEmpty() || model.speed == null || speedFilters.any {\n                it::class.isInstance(model.speed)\n            }\n        val hasKeyword =\n            keywordFilter.isBlank()\n                    || model.name.contains(keywordFilter, true)\n                    || model.title.contains(keywordFilter, true)\n                    || (model.description?.let {\n                appContext.getString(model.description)\n                    .contains(keywordFilter, true)\n                        || appContext.getStringLocalized(model.description, Locale.ENGLISH)\n                    .contains(keywordFilter, true)\n            } == true)\n\n        hasType && hasSpeed && hasKeyword\n    }\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/NeuralModelFilterSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Cancel\nimport androidx.compose.material.icons.outlined.FilterAlt\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggleByClass\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\n\n@Composable\ninternal fun NeuralModelFilterSheet(\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    typeFilters: List<NeuralModel.Type>,\n    speedFilters: List<NeuralModel.Speed>,\n    keywordFilter: String,\n    onTypeFiltersChange: (List<NeuralModel.Type>) -> Unit,\n    onSpeedFiltersChange: (List<NeuralModel.Speed>) -> Unit,\n    onKeywordFilterChange: (String) -> Unit\n) {\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { onDismiss(false) }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.filter),\n                icon = Icons.Outlined.FilterAlt\n            )\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(16.dp)\n                .clearFocusOnTap(),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Column(\n                modifier = Modifier\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp,\n                        color = EnhancedBottomSheetDefaults.contentContainerColor\n                    ),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                TitleItem(\n                    text = stringResource(R.string.type),\n                    modifier = Modifier\n                        .padding(\n                            start = 4.dp,\n                            top = 4.dp,\n                            end = 4.dp\n                        )\n                )\n                Spacer(Modifier.height(8.dp))\n                FlowRow(\n                    horizontalArrangement = Arrangement.spacedBy(\n                        space = 4.dp,\n                        alignment = Alignment.CenterHorizontally\n                    ),\n                    verticalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    NeuralModel.Type.entries.forEach { type ->\n                        NeuralModelTypeBadge(\n                            type = type,\n                            isInverted = type in typeFilters,\n                            onClick = {\n                                onTypeFiltersChange(typeFilters.toggle(type))\n                            },\n                            height = 36.dp,\n                            endPadding = 12.dp,\n                            startPadding = 6.dp,\n                            style = MaterialTheme.typography.labelMedium\n                        )\n                    }\n                }\n            }\n            Spacer(Modifier.height(8.dp))\n            Column(\n                modifier = Modifier\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp,\n                        color = EnhancedBottomSheetDefaults.contentContainerColor\n                    ),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                TitleItem(\n                    text = stringResource(R.string.speed),\n                    modifier = Modifier\n                        .padding(\n                            start = 4.dp,\n                            top = 4.dp,\n                            end = 4.dp\n                        )\n                )\n                Spacer(Modifier.height(8.dp))\n                FlowRow(\n                    horizontalArrangement = Arrangement.spacedBy(\n                        space = 4.dp,\n                        alignment = Alignment.CenterHorizontally\n                    ),\n                    verticalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    NeuralModel.Speed.entries.forEach { speed ->\n                        NeuralModelSpeedBadge(\n                            speed = speed,\n                            isInverted = speedFilters.any { it::class.isInstance(speed) },\n                            onClick = {\n                                onSpeedFiltersChange(speedFilters.toggleByClass(speed))\n                            },\n                            height = 36.dp,\n                            endPadding = 12.dp,\n                            startPadding = 6.dp,\n                            style = MaterialTheme.typography.labelMedium,\n                            showTitle = true\n                        )\n                    }\n                }\n            }\n            Spacer(Modifier.height(8.dp))\n            RoundedTextField(\n                value = keywordFilter,\n                onValueChange = onKeywordFilterChange,\n                label = stringResource(R.string.keyword),\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp,\n                        color = EnhancedBottomSheetDefaults.contentContainerColor\n                    ),\n                singleLine = false,\n                endIcon = {\n                    AnimatedVisibility(keywordFilter.isNotBlank()) {\n                        EnhancedIconButton(\n                            onClick = { onKeywordFilterChange(\"\") },\n                            modifier = Modifier.padding(end = 4.dp)\n                        ) {\n                            Icon(\n                                imageVector = Icons.Outlined.Cancel,\n                                contentDescription = stringResource(R.string.cancel)\n                            )\n                        }\n                    }\n                },\n                maxLines = 4\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/NeuralModelSelectionSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FilterAlt\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Neurology\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\n\n@Composable\ninternal fun NeuralModelSelectionSheet(\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    selectedModel: NeuralModel?,\n    onSelectModel: (NeuralModel) -> Unit,\n    onDownloadModel: (NeuralModel) -> Unit,\n    onDeleteModel: (NeuralModel) -> Unit,\n    downloadedModels: List<NeuralModel>,\n    notDownloadedModels: List<NeuralModel>,\n    onImportModel: (Uri) -> Unit,\n    downloadProgresses: Map<String, DownloadProgress>,\n    occupiedStorageSize: Long,\n    onCancelDownload: (NeuralModel) -> Unit\n) {\n    var typeFilters by rememberSaveable(stateSaver = TypeFiltersSaver) {\n        mutableStateOf(emptyList())\n    }\n\n    var speedFilters by rememberSaveable(stateSaver = SpeedFiltersSaver) {\n        mutableStateOf(emptyList())\n    }\n\n    var keywordFilter by rememberSaveable {\n        mutableStateOf(\"\")\n    }\n\n    var showFilterSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = onDismiss,\n        confirmButton = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                EnhancedIconButton(\n                    onClick = {\n                        showFilterSheet = true\n                    },\n                    containerColor = MaterialTheme.colorScheme.tertiaryContainer\n                ) {\n                    Box {\n                        Icon(\n                            imageVector = Icons.Rounded.FilterAlt,\n                            contentDescription = \"more\"\n                        )\n\n                        BoxAnimatedVisibility(\n                            visible = typeFilters.isNotEmpty() || speedFilters.isNotEmpty() || keywordFilter.isNotBlank(),\n                            modifier = Modifier\n                                .size(6.dp)\n                                .align(Alignment.TopEnd)\n                        ) {\n                            EnhancedBadge()\n                        }\n                    }\n                }\n\n                NeuralModelFilterSheet(\n                    visible = showFilterSheet,\n                    onDismiss = { showFilterSheet = it },\n                    typeFilters = typeFilters,\n                    speedFilters = speedFilters,\n                    keywordFilter = keywordFilter,\n                    onTypeFiltersChange = { typeFilters = it },\n                    onSpeedFiltersChange = { speedFilters = it },\n                    onKeywordFilterChange = { keywordFilter = it }\n                )\n\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    onClick = { onDismiss(false) }\n                ) {\n                    Text(stringResource(R.string.close))\n                }\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.models),\n                icon = Icons.Outlined.Neurology\n            )\n        },\n        sheetContent = {\n            val (filteredDownloadedModels, filteredNotDownloadedModels) = filteredModels(\n                downloadedModels = downloadedModels,\n                notDownloadedModels = notDownloadedModels,\n                typeFilters = typeFilters,\n                speedFilters = speedFilters,\n                keywordFilter = keywordFilter\n            ).value\n\n            NeuralModelsColumn(\n                selectedModel = selectedModel,\n                downloadedModels = filteredDownloadedModels,\n                notDownloadedModels = filteredNotDownloadedModels,\n                onSelectModel = onSelectModel,\n                onDownloadModel = onDownloadModel,\n                onDeleteModel = onDeleteModel,\n                onImportModel = onImportModel,\n                downloadProgresses = downloadProgresses,\n                occupiedStorageSize = occupiedStorageSize,\n                onCancelDownload = onCancelDownload\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/NeuralModelSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Neurology\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\n\n@Composable\ninternal fun NeuralModelSelector(\n    value: NeuralModel?,\n    onSelectModel: (NeuralModel) -> Unit,\n    onDownloadModel: (NeuralModel) -> Unit,\n    onDeleteModel: (NeuralModel) -> Unit,\n    downloadedModels: List<NeuralModel>,\n    notDownloadedModels: List<NeuralModel>,\n    onImportModel: (Uri) -> Unit,\n    downloadProgresses: Map<String, DownloadProgress>,\n    occupiedStorageSize: Long,\n    onCancelDownload: (NeuralModel) -> Unit\n) {\n    var showSelectionSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItem(\n        modifier = Modifier.fillMaxWidth(),\n        title = stringResource(id = R.string.active_model),\n        subtitle = value?.title ?: stringResource(R.string.select_one_to_start),\n        onClick = { showSelectionSheet = true },\n        containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n        shape = ShapeDefaults.extraLarge,\n        startIcon = Icons.Outlined.Neurology,\n        endIcon = Icons.Rounded.MiniEdit,\n        placeBottomContentInside = true,\n        bottomContent = value?.type?.let { type ->\n            {\n                FlowRow(\n                    modifier = Modifier.padding(top = 8.dp),\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                ) {\n                    NeuralModelTypeBadge(\n                        type = type,\n                        isInverted = null\n                    )\n\n                    value.speed?.let { speed ->\n                        NeuralModelSpeedBadge(\n                            speed = speed,\n                            isInverted = null\n                        )\n                    }\n\n                    NeuralModelSizeBadge(\n                        model = value,\n                        isInverted = false\n                    )\n                }\n            }\n        }\n    )\n\n    NeuralModelSelectionSheet(\n        visible = showSelectionSheet,\n        onDismiss = { showSelectionSheet = it },\n        selectedModel = value,\n        onSelectModel = onSelectModel,\n        onDownloadModel = onDownloadModel,\n        onDeleteModel = onDeleteModel,\n        downloadedModels = downloadedModels,\n        notDownloadedModels = notDownloadedModels,\n        onImportModel = onImportModel,\n        downloadProgresses = downloadProgresses,\n        occupiedStorageSize = occupiedStorageSize,\n        onCancelDownload = onCancelDownload\n    )\n}\n\n@Preview\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(\n    isDarkTheme = false,\n    keyColor = Color.Green\n) {\n    NeuralModelSelector(\n        value = NeuralModel.entries.first(),\n        onSelectModel = {},\n        onDownloadModel = {},\n        onDeleteModel = {},\n        downloadedModels = emptyList(),\n        notDownloadedModels = emptyList(),\n        onImportModel = { _ -> },\n        downloadProgresses = emptyMap(),\n        occupiedStorageSize = 0,\n        onCancelDownload = {}\n    )\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/NeuralModelTypeResources.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.DirectionsWalk\nimport androidx.compose.material.icons.automirrored.rounded.InsertDriveFile\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material.icons.rounded.Bolt\nimport androidx.compose.material.icons.rounded.Cloud\nimport androidx.compose.material.icons.rounded.HighQuality\nimport androidx.compose.material.icons.rounded.Scanner\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.humanFileSize\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.Eraser\nimport com.t8rin.imagetoolbox.core.resources.icons.Eyedropper\nimport com.t8rin.imagetoolbox.core.resources.icons.Jpg\nimport com.t8rin.imagetoolbox.core.resources.icons.Manga\nimport com.t8rin.imagetoolbox.core.resources.icons.NoiseAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.Rabbit\nimport com.t8rin.imagetoolbox.core.resources.icons.Snail\nimport com.t8rin.imagetoolbox.core.resources.icons.Tortoise\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralConstants\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport java.io.File\nimport kotlin.random.Random\n\nfun NeuralModel.Type.title(): Int = when (this) {\n    NeuralModel.Type.DE_JPEG -> R.string.type_dejpeg\n    NeuralModel.Type.DENOISE -> R.string.type_denoise\n    NeuralModel.Type.COLORIZE -> R.string.type_colorize\n    NeuralModel.Type.ARTIFACTS -> R.string.type_artifacts\n    NeuralModel.Type.ENHANCE -> R.string.type_enhance\n    NeuralModel.Type.ANIME -> R.string.type_anime\n    NeuralModel.Type.SCANS -> R.string.type_scans\n    NeuralModel.Type.UPSCALE -> R.string.type_upscale\n    NeuralModel.Type.REMOVE_BG -> R.string.type_removebg\n}\n\nfun NeuralModel.Type.icon(): ImageVector = when (this) {\n    NeuralModel.Type.DE_JPEG -> Icons.Outlined.Jpg\n    NeuralModel.Type.DENOISE -> Icons.Outlined.NoiseAlt\n    NeuralModel.Type.COLORIZE -> Icons.Outlined.Eyedropper\n    NeuralModel.Type.ARTIFACTS -> Icons.Rounded.BrokenImageAlt\n    NeuralModel.Type.ENHANCE -> Icons.Rounded.AutoFixHigh\n    NeuralModel.Type.ANIME -> Icons.Rounded.Manga\n    NeuralModel.Type.SCANS -> Icons.Rounded.Scanner\n    NeuralModel.Type.UPSCALE -> Icons.Rounded.HighQuality\n    NeuralModel.Type.REMOVE_BG -> Icons.Rounded.Eraser\n}\n\nfun NeuralModel.Speed.icon(): ImageVector = when (this) {\n    is NeuralModel.Speed.VeryFast -> Icons.Rounded.Bolt\n    is NeuralModel.Speed.Fast -> Icons.Rounded.Rabbit\n    is NeuralModel.Speed.Normal -> Icons.AutoMirrored.Rounded.DirectionsWalk\n    is NeuralModel.Speed.Slow -> Icons.Rounded.Tortoise\n    is NeuralModel.Speed.VerySlow -> Icons.Rounded.Snail\n}\n\nfun NeuralModel.Speed.title(): Int = when (this) {\n    is NeuralModel.Speed.VeryFast -> R.string.very_fast\n    is NeuralModel.Speed.Fast -> R.string.fast\n    is NeuralModel.Speed.Normal -> R.string.normal\n    is NeuralModel.Speed.Slow -> R.string.slow\n    is NeuralModel.Speed.VerySlow -> R.string.very_slow\n}\n\n@Composable\nfun NeuralModelTypeBadge(\n    type: NeuralModel.Type,\n    isInverted: Boolean?,\n    modifier: Modifier = Modifier,\n    height: Dp = 22.dp,\n    endPadding: Dp = 6.dp,\n    startPadding: Dp = 2.dp,\n    onClick: (() -> Unit)? = null,\n    style: TextStyle = MaterialTheme.typography.labelSmall\n) {\n    val interactionSource = remember {\n        MutableInteractionSource()\n    }\n\n    Row(\n        modifier = modifier\n            .height(height)\n            .container(\n                color = takeColorFromScheme {\n                    when (isInverted) {\n                        true -> tertiary.blend(\n                            color = secondary,\n                            fraction = 0.3f\n                        )\n\n                        false -> tertiaryContainer.blend(\n                            color = secondaryContainer,\n                            fraction = 0.3f\n                        )\n\n                        null -> surfaceVariant.blend(\n                            color = secondaryContainer,\n                            fraction = 0.3f\n                        )\n                    }\n                },\n                shape = shapeByInteraction(\n                    shape = ShapeDefaults.circle,\n                    pressedShape = ShapeDefaults.pressed,\n                    interactionSource = interactionSource\n                ),\n                resultPadding = 0.dp\n            )\n            .then(\n                if (onClick != null) {\n                    Modifier.hapticsClickable(\n                        indication = LocalIndication.current,\n                        onClick = onClick,\n                        interactionSource = interactionSource\n                    )\n                } else {\n                    Modifier\n                }\n            )\n            .padding(start = startPadding, end = endPadding),\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.spacedBy(2.dp)\n    ) {\n        val contentColor = takeColorFromScheme {\n            when (isInverted) {\n                true -> onTertiary.blend(\n                    color = onSecondary,\n                    fraction = 0.65f\n                )\n\n                false -> onTertiaryContainer.blend(\n                    color = onSecondaryContainer,\n                    fraction = 0.65f\n                )\n\n                null -> onSurfaceVariant.blend(\n                    color = onSecondaryContainer,\n                    fraction = 0.65f\n                )\n            }\n        }\n\n        Box(\n            modifier = Modifier.size((height - 2.dp).coerceAtMost(24.dp)),\n            contentAlignment = Alignment.Center\n        ) {\n            Icon(\n                imageVector = type.icon(),\n                contentDescription = null,\n                tint = contentColor,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(2.dp)\n            )\n        }\n        Text(\n            text = stringResource(type.title()),\n            color = contentColor,\n            style = style\n        )\n    }\n}\n\n@Composable\nfun NeuralModelSpeedBadge(\n    speed: NeuralModel.Speed,\n    isInverted: Boolean?,\n    modifier: Modifier = Modifier,\n    height: Dp = 22.dp,\n    endPadding: Dp = 6.dp,\n    startPadding: Dp = 2.dp,\n    onClick: (() -> Unit)? = null,\n    showTitle: Boolean = false,\n    style: TextStyle = MaterialTheme.typography.labelSmall\n) {\n    val hasValue = showTitle || speed.speedValue > 0f\n\n    val interactionSource = remember {\n        MutableInteractionSource()\n    }\n\n    Row(\n        modifier = modifier\n            .then(\n                if (hasValue) {\n                    Modifier.height(height)\n                } else {\n                    Modifier.size(height)\n                }\n            )\n            .container(\n                color = takeColorFromScheme {\n                    when (isInverted) {\n                        true -> primary\n                        false -> primaryContainer\n                        null -> surfaceVariant.blend(\n                            color = primaryContainer,\n                            fraction = 0.2f\n                        )\n                    }\n                },\n                shape = shapeByInteraction(\n                    shape = ShapeDefaults.circle,\n                    pressedShape = ShapeDefaults.pressed,\n                    interactionSource = interactionSource\n                ),\n                resultPadding = 0.dp\n            )\n            .then(\n                if (onClick != null) {\n                    Modifier.hapticsClickable(\n                        indication = LocalIndication.current,\n                        onClick = onClick,\n                        interactionSource = interactionSource\n                    )\n                } else {\n                    Modifier\n                }\n            )\n            .then(\n                if (hasValue) {\n                    Modifier.padding(start = startPadding, end = endPadding)\n                } else Modifier\n            ),\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.spacedBy(2.dp, Alignment.CenterHorizontally)\n    ) {\n        val contentColor = takeColorFromScheme {\n            when (isInverted) {\n                true -> onPrimary\n                false -> onPrimaryContainer\n                null -> onSurfaceVariant.blend(\n                    color = onPrimaryContainer,\n                    fraction = 0.3f\n                )\n            }\n        }\n        Box(\n            modifier = Modifier.size((height - 2.dp).coerceAtMost(24.dp)),\n            contentAlignment = Alignment.Center\n        ) {\n            Icon(\n                imageVector = speed.icon(),\n                contentDescription = null,\n                tint = contentColor,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(2.dp)\n            )\n        }\n        if (hasValue) {\n            val speedValue by remember(speed.speedValue) {\n                derivedStateOf {\n                    speed.speedValue.roundTo(\n                        when {\n                            speed.speedValue > 10f -> 1\n                            speed.speedValue > 5f -> 2\n                            else -> 3\n                        }\n                    ).toString().trimTrailingZero()\n                }\n            }\n\n            Text(\n                text = if (showTitle) {\n                    stringResource(speed.title())\n                } else {\n                    speedValue\n                },\n                color = contentColor,\n                style = style\n            )\n        }\n    }\n}\n\n@Composable\nfun NeuralModelSizeBadge(\n    model: NeuralModel,\n    isInverted: Boolean,\n    modifier: Modifier = Modifier\n) {\n    Row(\n        modifier = modifier\n            .height(22.dp)\n            .container(\n                color = takeColorFromScheme {\n                    if (isInverted) surface\n                    else surfaceVariant\n                },\n                shape = ShapeDefaults.circle,\n                resultPadding = 0.dp\n            )\n            .padding(start = 4.dp, end = 6.dp),\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.spacedBy(2.dp)\n    ) {\n        val contentColor = takeColorFromScheme {\n            if (isInverted) onSurface\n            else onSurfaceVariant\n        }\n\n        val modelFile by remember(model.name) {\n            derivedStateOf {\n                File(File(appContext.filesDir, NeuralConstants.DIR), model.name)\n            }\n        }\n        val size by remember(model.downloadSize, modelFile) {\n            derivedStateOf {\n                modelFile.length().takeIf { it > 0 }?.let(::humanFileSize)\n                    ?: humanFileSize(model.downloadSize)\n            }\n        }\n\n        Box(\n            modifier = Modifier.size(20.dp),\n            contentAlignment = Alignment.Center\n        ) {\n            Icon(\n                imageVector = if (modelFile.exists()) {\n                    Icons.AutoMirrored.Rounded.InsertDriveFile\n                } else {\n                    Icons.Rounded.Cloud\n                },\n                contentDescription = null,\n                tint = contentColor,\n                modifier = Modifier.size(16.dp)\n            )\n        }\n        Text(\n            text = size,\n            color = contentColor,\n            style = MaterialTheme.typography.labelSmall\n        )\n    }\n}\n\n@Preview\n@Composable\nprivate fun PreviewSpeed() = ImageToolboxThemeForPreview(\n    isDarkTheme = true,\n    keyColor = Color.Green\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        modifier = Modifier\n            .background(MaterialTheme.colorScheme.surface)\n            .padding(8.dp)\n    ) {\n        NeuralModel.Speed.entries.forEach {\n            NeuralModelSpeedBadge(\n                speed = it.clone(12.21f),\n                isInverted = Random.nextBoolean(),\n                height = 36.dp,\n                endPadding = 12.dp,\n                startPadding = 6.dp,\n                style = MaterialTheme.typography.labelMedium\n            )\n        }\n    }\n}\n\n@Preview\n@Composable\nprivate fun PreviewType() = ImageToolboxThemeForPreview(\n    isDarkTheme = true,\n    keyColor = Color.Green\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        modifier = Modifier\n            .background(MaterialTheme.colorScheme.surface)\n            .padding(8.dp)\n    ) {\n        NeuralModel.Type.entries.forEach {\n            NeuralModelTypeBadge(\n                type = it,\n                isInverted = Random.nextBoolean(),\n                height = 36.dp,\n                endPadding = 12.dp,\n                startPadding = 6.dp,\n                style = MaterialTheme.typography.labelMedium\n            )\n        }\n    }\n}\n\n@Preview\n@Composable\nprivate fun PreviewMixed() = ImageToolboxThemeForPreview(\n    isDarkTheme = true,\n    keyColor = Color.Green\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        modifier = Modifier\n            .background(MaterialTheme.colorScheme.surfaceContainer)\n            .padding(8.dp)\n    ) {\n        NeuralModel.Type.entries.forEach {\n            Row(\n                horizontalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                val inv = Random.nextBoolean()\n                NeuralModelTypeBadge(it, inv)\n\n                NeuralModelSpeedBadge(\n                    speed = (NeuralModel.Speed.entries.getOrNull(it.ordinal)\n                        ?: NeuralModel.Speed.entries.random())\n                        .clone(Random.nextFloat() * 20), inv\n                )\n\n                NeuralModelSizeBadge(\n                    model = NeuralModel.entries.first(),\n                    isInverted = inv\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/NeuralModelsColumn.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.InsertDriveFile\nimport androidx.compose.material.icons.outlined.Link\nimport androidx.compose.material.icons.rounded.Download\nimport androidx.compose.material.icons.rounded.DownloadDone\nimport androidx.compose.material.icons.rounded.DownloadForOffline\nimport androidx.compose.material.icons.rounded.ModelTraining\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.FileImport\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCancellableCircularProgressIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealDirection\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealValue\nimport com.t8rin.imagetoolbox.core.ui.widget.other.SwipeToReveal\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberRevealState\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.OneTimeEffect\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun NeuralModelsColumn(\n    selectedModel: NeuralModel?,\n    downloadedModels: List<NeuralModel>,\n    notDownloadedModels: List<NeuralModel>,\n    onSelectModel: (NeuralModel) -> Unit,\n    onDownloadModel: (NeuralModel) -> Unit,\n    onDeleteModel: (NeuralModel) -> Unit,\n    onImportModel: (Uri) -> Unit,\n    downloadProgresses: Map<String, DownloadProgress>,\n    occupiedStorageSize: Long,\n    onCancelDownload: (NeuralModel) -> Unit\n) {\n    val scope = rememberCoroutineScope()\n\n    val listState = rememberLazyListState()\n\n    val filePicker = rememberFilePicker { uri: Uri ->\n        val name = uri.filename().orEmpty()\n        if (name.endsWith(\".onnx\") || name.endsWith(\".ort\")) {\n            onImportModel(uri)\n        } else {\n            AppToastHost.showFailureToast(R.string.only_onnx_models)\n        }\n    }\n\n    val (importedModels, downloadedModels) = remember(downloadedModels) {\n        derivedStateOf {\n            downloadedModels.partition { it.isImported }\n        }\n    }.value\n\n    val scrollToSelected = suspend {\n        downloadedModels.indexOf(selectedModel).takeIf {\n            it != -1\n        }.let {\n            listState.animateScrollToItem(it ?: 0)\n        }\n    }\n\n    var isSelectRequested by remember {\n        mutableStateOf(false)\n    }\n\n    OneTimeEffect {\n        scrollToSelected()\n    }\n\n    LaunchedEffect(downloadedModels) {\n        delay(250)\n        scrollToSelected()\n    }\n\n    LaunchedEffect(selectedModel?.name) {\n        delay(250)\n        if (isSelectRequested) {\n            isSelectRequested = false\n            return@LaunchedEffect\n        }\n        scrollToSelected()\n    }\n\n    var deleteDialogData by remember {\n        mutableStateOf<NeuralModel?>(null)\n    }\n\n    DeleteModelDialog(\n        model = deleteDialogData,\n        onDismiss = { deleteDialogData = null },\n        onDeleteModel = onDeleteModel\n    )\n\n    LazyColumn(\n        state = listState,\n        contentPadding = PaddingValues(16.dp),\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        item {\n            PreferenceItem(\n                title = stringResource(R.string.import_model),\n                subtitle = stringResource(R.string.import_model_sub),\n                onClick = filePicker::pickFile,\n                startIcon = Icons.Rounded.ModelTraining,\n                containerColor = EnhancedBottomSheetDefaults.contentContainerColor,\n                shape = ShapeDefaults.default,\n                modifier = Modifier.fillMaxWidth(),\n                endIcon = Icons.Rounded.FileImport\n            )\n        }\n        if (importedModels.isNotEmpty()) {\n            item {\n                TitleItem(\n                    icon = Icons.AutoMirrored.Rounded.InsertDriveFile,\n                    text = stringResource(id = R.string.imported_models)\n                )\n            }\n        }\n        itemsIndexed(\n            items = importedModels,\n            key = { _, m -> m.name }\n        ) { index, model ->\n            val selected = selectedModel?.name == model.name\n            val state = rememberRevealState()\n            val interactionSource = remember {\n                MutableInteractionSource()\n            }\n            val isDragged by interactionSource.collectIsDraggedAsState()\n            val shape = ShapeDefaults.byIndex(\n                index = index,\n                size = importedModels.size,\n                forceDefault = isDragged\n            )\n            SwipeToReveal(\n                state = state,\n                modifier = Modifier.animateItem(),\n                revealedContentEnd = {\n                    Box(\n                        Modifier\n                            .fillMaxSize()\n                            .container(\n                                color = MaterialTheme.colorScheme.errorContainer,\n                                shape = shape,\n                                autoShadowElevation = 0.dp,\n                                resultPadding = 0.dp\n                            )\n                            .hapticsClickable {\n                                scope.launch {\n                                    state.animateTo(RevealValue.Default)\n                                }\n                                deleteDialogData = model\n                            }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Delete,\n                            contentDescription = stringResource(R.string.delete),\n                            modifier = Modifier\n                                .padding(16.dp)\n                                .padding(end = 8.dp)\n                                .align(Alignment.CenterEnd),\n                            tint = MaterialTheme.colorScheme.onErrorContainer\n                        )\n                    }\n                },\n                directions = setOf(RevealDirection.EndToStart),\n                swipeableContent = {\n                    PreferenceItemOverload(\n                        shape = shape,\n                        containerColor = animateColorAsState(\n                            if (selected) {\n                                MaterialTheme\n                                    .colorScheme\n                                    .mixedContainer\n                                    .copy(0.8f)\n                            } else EnhancedBottomSheetDefaults.contentContainerColor\n                        ).value,\n                        onLongClick = {\n                            scope.launch {\n                                state.animateTo(RevealValue.FullyRevealedStart)\n                            }\n                        },\n                        onClick = {\n                            isSelectRequested = true\n                            onSelectModel(model)\n                        },\n                        title = model.title,\n                        subtitle = model.description?.let { stringResource(it) },\n                        modifier = Modifier.fillMaxWidth(),\n                        endIcon = {\n                            Icon(\n                                imageVector = if (selected) {\n                                    Icons.Rounded.RadioButtonChecked\n                                } else {\n                                    Icons.Rounded.RadioButtonUnchecked\n                                },\n                                contentDescription = null\n                            )\n                        },\n                        placeBottomContentInside = true,\n                        bottomContent = {\n                            NeuralModelSizeBadge(\n                                model = model,\n                                isInverted = selected,\n                                modifier = Modifier.padding(top = 8.dp)\n                            )\n                        }\n                    )\n                },\n                interactionSource = interactionSource\n            )\n        }\n        if (downloadedModels.isNotEmpty()) {\n            item {\n                TitleItem(\n                    icon = Icons.Rounded.DownloadDone,\n                    text = stringResource(id = R.string.downloaded_models),\n                    endContent = {\n                        EnhancedBadge(\n                            containerColor = MaterialTheme.colorScheme.tertiary\n                        ) {\n                            Text(\n                                rememberHumanFileSize(\n                                    byteCount = occupiedStorageSize\n                                )\n                            )\n                        }\n                    }\n                )\n            }\n        }\n        itemsIndexed(\n            items = downloadedModels,\n            key = { _, m -> m.name }\n        ) { index, model ->\n            val selected = selectedModel?.name == model.name\n            val state = rememberRevealState()\n            val interactionSource = remember {\n                MutableInteractionSource()\n            }\n            val isDragged by interactionSource.collectIsDraggedAsState()\n            val shape = ShapeDefaults.byIndex(\n                index = index,\n                size = downloadedModels.size,\n                forceDefault = isDragged\n            )\n            SwipeToReveal(\n                state = state,\n                modifier = Modifier.animateItem(),\n                revealedContentEnd = {\n                    Box(\n                        Modifier\n                            .fillMaxSize()\n                            .container(\n                                color = MaterialTheme.colorScheme.errorContainer,\n                                shape = shape,\n                                autoShadowElevation = 0.dp,\n                                resultPadding = 0.dp\n                            )\n                            .hapticsClickable {\n                                scope.launch {\n                                    state.animateTo(RevealValue.Default)\n                                }\n                                deleteDialogData = model\n                            }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Delete,\n                            contentDescription = stringResource(R.string.delete),\n                            modifier = Modifier\n                                .padding(16.dp)\n                                .padding(end = 8.dp)\n                                .align(Alignment.CenterEnd),\n                            tint = MaterialTheme.colorScheme.onErrorContainer\n                        )\n                    }\n                },\n                revealedContentStart = {\n                    val uriHandler = LocalUriHandler.current\n                    Box(\n                        Modifier\n                            .fillMaxSize()\n                            .container(\n                                color = MaterialTheme.colorScheme.tertiaryContainer.copy(\n                                    0.5f\n                                ),\n                                shape = shape,\n                                autoShadowElevation = 0.dp,\n                                resultPadding = 0.dp\n                            )\n                            .hapticsClickable {\n                                scope.launch {\n                                    state.animateTo(RevealValue.Default)\n                                }\n                                uriHandler.openUri(model.pointerLink)\n                            }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Link,\n                            contentDescription = \"link\",\n                            modifier = Modifier\n                                .padding(16.dp)\n                                .padding(start = 8.dp)\n                                .align(Alignment.CenterStart),\n                            tint = MaterialTheme.colorScheme.onTertiaryContainer\n                        )\n                    }\n                },\n                directions = setOf(\n                    RevealDirection.StartToEnd,\n                    RevealDirection.EndToStart\n                ),\n                swipeableContent = {\n                    PreferenceItemOverload(\n                        shape = shape,\n                        containerColor = animateColorAsState(\n                            if (selected) {\n                                MaterialTheme\n                                    .colorScheme\n                                    .mixedContainer\n                                    .copy(0.8f)\n                            } else EnhancedBottomSheetDefaults.contentContainerColor\n                        ).value,\n                        onLongClick = {\n                            scope.launch {\n                                state.animateTo(RevealValue.FullyRevealedStart)\n                            }\n                        },\n                        onClick = {\n                            isSelectRequested = true\n                            onSelectModel(model)\n                        },\n                        title = model.title,\n                        subtitle = model.description?.let { stringResource(it) },\n                        modifier = Modifier.fillMaxWidth(),\n                        placeBottomContentInside = true,\n                        endIcon = {\n                            Icon(\n                                imageVector = if (selected) {\n                                    Icons.Rounded.RadioButtonChecked\n                                } else {\n                                    Icons.Rounded.RadioButtonUnchecked\n                                },\n                                contentDescription = null\n                            )\n                        },\n                        bottomContent = model.type?.let { type ->\n                            {\n                                FlowRow(\n                                    modifier = Modifier.padding(top = 8.dp),\n                                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                                ) {\n                                    NeuralModelTypeBadge(\n                                        type = type,\n                                        isInverted = selected\n                                    )\n\n                                    model.speed?.let { speed ->\n                                        NeuralModelSpeedBadge(\n                                            speed = speed,\n                                            isInverted = selected\n                                        )\n                                    }\n\n                                    NeuralModelSizeBadge(\n                                        model = model,\n                                        isInverted = selected\n                                    )\n                                }\n                            }\n                        }\n                    )\n                },\n                interactionSource = interactionSource\n            )\n        }\n        if (notDownloadedModels.isNotEmpty()) {\n            item {\n                TitleItem(\n                    icon = Icons.Rounded.Download,\n                    text = stringResource(id = R.string.available_models)\n                )\n            }\n        }\n        itemsIndexed(\n            items = notDownloadedModels,\n            key = { _, m -> m.name + \"not\" }\n        ) { index, model ->\n            val state = rememberRevealState()\n            val interactionSource = remember {\n                MutableInteractionSource()\n            }\n            val isDragged by interactionSource.collectIsDraggedAsState()\n            val shape = ShapeDefaults.byIndex(\n                index = index,\n                size = notDownloadedModels.size,\n                forceDefault = isDragged\n            )\n            SwipeToReveal(\n                state = state,\n                modifier = Modifier.animateItem(),\n                revealedContentStart = {\n                    val uriHandler = LocalUriHandler.current\n                    Box(\n                        Modifier\n                            .fillMaxSize()\n                            .container(\n                                color = MaterialTheme.colorScheme.tertiaryContainer.copy(\n                                    0.5f\n                                ),\n                                shape = shape,\n                                autoShadowElevation = 0.dp,\n                                resultPadding = 0.dp\n                            )\n                            .hapticsClickable {\n                                scope.launch {\n                                    state.animateTo(RevealValue.Default)\n                                }\n                                uriHandler.openUri(model.pointerLink)\n                            }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Link,\n                            contentDescription = \"link\",\n                            modifier = Modifier\n                                .padding(16.dp)\n                                .padding(start = 8.dp)\n                                .align(Alignment.CenterStart),\n                            tint = MaterialTheme.colorScheme.onTertiaryContainer\n                        )\n                    }\n                },\n                directions = setOf(RevealDirection.StartToEnd),\n                swipeableContent = {\n                    PreferenceItemOverload(\n                        shape = shape,\n                        title = model.title,\n                        subtitle = model.description?.let { stringResource(it) },\n                        onClick = {\n                            onDownloadModel(model)\n                        },\n                        onLongClick = {\n                            scope.launch {\n                                state.animateTo(RevealValue.FullyRevealedEnd)\n                            }\n                        },\n                        containerColor = EnhancedBottomSheetDefaults.contentContainerColor,\n                        modifier = Modifier\n                            .animateItem()\n                            .fillMaxWidth(),\n                        endIcon = {\n                            AnimatedContent(\n                                targetState = downloadProgresses[model.name],\n                                contentKey = { key -> key?.currentTotalSize?.let { it > 0 } }\n                            ) { progress ->\n                                if (progress != null) {\n                                    Row(\n                                        modifier = Modifier.container(\n                                            shape = ShapeDefaults.circle,\n                                            color = MaterialTheme.colorScheme.surface,\n                                            resultPadding = 8.dp\n                                        ),\n                                        verticalAlignment = Alignment.CenterVertically\n                                    ) {\n                                        Text(\n                                            text = if (progress.currentTotalSize > 0) {\n                                                rememberHumanFileSize(progress.currentTotalSize)\n                                            } else {\n                                                stringResource(R.string.preparing)\n                                            },\n                                            style = MaterialTheme.typography.bodySmall\n                                        )\n                                        Spacer(Modifier.width(8.dp))\n                                        EnhancedCancellableCircularProgressIndicator(\n                                            progress = { progress.currentPercent },\n                                            modifier = Modifier.size(24.dp),\n                                            trackColor = MaterialTheme.colorScheme.primary.copy(0.2f),\n                                            strokeWidth = 3.dp,\n                                            onCancel = { onCancelDownload(model) }\n                                        )\n                                    }\n                                } else {\n                                    Icon(\n                                        imageVector = Icons.Rounded.DownloadForOffline,\n                                        contentDescription = null\n                                    )\n                                }\n                            }\n                        },\n                        placeBottomContentInside = true,\n                        bottomContent = model.type?.let { type ->\n                            {\n                                FlowRow(\n                                    modifier = Modifier.padding(top = 8.dp),\n                                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                                ) {\n                                    NeuralModelTypeBadge(\n                                        type = type,\n                                        isInverted = false\n                                    )\n\n                                    model.speed?.let { speed ->\n                                        NeuralModelSpeedBadge(\n                                            speed = speed,\n                                            isInverted = false\n                                        )\n                                    }\n\n                                    AnimatedVisibility(\n                                        visible = downloadProgresses[model.name] == null\n                                    ) {\n                                        NeuralModelSizeBadge(\n                                            model = model,\n                                            isInverted = false\n                                        )\n                                    }\n                                }\n                            }\n                        }\n                    )\n                },\n                interactionSource = interactionSource\n            )\n        }\n\n        if (downloadedModels.isEmpty() && notDownloadedModels.isEmpty()) {\n            item {\n                Column(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(\n                            top = 8.dp\n                        )\n                        .container(\n                            shape = ShapeDefaults.large,\n                            resultPadding = 0.dp,\n                            color = EnhancedBottomSheetDefaults.contentContainerColor\n                        )\n                        .height(256.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    Text(\n                        text = stringResource(R.string.nothing_found_by_search),\n                        fontSize = 18.sp,\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier.padding(\n                            start = 24.dp,\n                            end = 24.dp,\n                            top = 24.dp,\n                            bottom = 8.dp\n                        )\n                    )\n                    Icon(\n                        imageVector = Icons.Rounded.SearchOff,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .weight(2f)\n                            .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                            .fillMaxSize()\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/NeuralSaveProgress.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\ndata class NeuralSaveProgress(\n    val doneImages: Int,\n    val totalImages: Int,\n    val doneChunks: Int,\n    val totalChunks: Int\n) {\n    val chunkProgress = if (totalChunks > 0) {\n        doneChunks / totalChunks.toFloat()\n    } else {\n        0f\n    }\n\n    val totalProgress = if (totalImages > 0) {\n        (doneImages.toFloat() + chunkProgress) / totalImages.toFloat()\n    } else {\n        0f\n    }\n\n    val isZero = doneImages == 0 && (totalImages < 2) && doneChunks == 0 && totalChunks == 0\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/NeuralSaveProgressDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic.AiToolsComponent\n\n@Composable\ninternal fun NeuralSaveProgressDialog(\n    component: AiToolsComponent\n) {\n    component.saveProgress?.let { saveProgress ->\n        LoadingDialog(\n            visible = true,\n            onCancelLoading = component::cancelSaving,\n            progress = { saveProgress.totalProgress },\n            switchToIndicator = saveProgress.isZero,\n            loaderSize = 72.dp,\n            isLayoutSwappable = false,\n            additionalContent = {\n                Column(\n                    verticalArrangement = Arrangement.Center,\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    AutoSizeText(\n                        text = if (saveProgress.totalImages > 1) {\n                            \"${saveProgress.doneImages} / ${saveProgress.totalImages}\"\n                        } else {\n                            \"${saveProgress.doneChunks} / ${saveProgress.totalChunks}\"\n                        },\n                        maxLines = 1,\n                        fontWeight = FontWeight.Medium,\n                        modifier = Modifier.width(it * 0.7f),\n                        textAlign = TextAlign.Center\n                    )\n                    if (saveProgress.totalImages > 1 && saveProgress.totalChunks > 0) {\n                        AutoSizeText(\n                            text = \"${saveProgress.doneChunks} / ${saveProgress.totalChunks}\",\n                            maxLines = 1,\n                            style = LocalTextStyle.current.copy(\n                                fontSize = 12.sp,\n                                lineHeight = 12.sp\n                            ),\n                            color = LocalContentColor.current.copy(0.5f),\n                            fontWeight = FontWeight.Normal,\n                            modifier = Modifier.width(it * 0.45f),\n                            textAlign = TextAlign.Center\n                        )\n                    }\n                }\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/components/Savers.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.components\n\nimport androidx.compose.runtime.saveable.listSaver\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\n\ninternal val SpeedFiltersSaver = listSaver(\n    save = { state ->\n        state.map { speed ->\n            NeuralModel.Speed.entries.indexOfFirst { it::class.isInstance(speed) }\n        }\n    },\n    restore = { list ->\n        list.map { NeuralModel.Speed.entries[it] }\n    }\n)\n\ninternal val TypeFiltersSaver = listSaver(\n    save = { state -> state.map { it.name } },\n    restore = { list ->\n        list.map { NeuralModel.Type.valueOf(it) }\n    }\n)"
  },
  {
    "path": "feature/ai-tools/src/main/java/com/t8rin/imagetoolbox/feature/ai_tools/presentation/screenLogic/AiToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CheckCircle\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateMapOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshots.SnapshotStateMap\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.utils.state.updateNotNull\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.AiProgressListener\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.AiToolsRepository\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel\nimport com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralParams\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.components.NeuralSaveProgress\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.catch\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.onCompletion\nimport kotlinx.coroutines.flow.stateIn\n\nclass AiToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val aiToolsRepository: AiToolsRepository<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::updateUris)\n        }\n    }\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _saveProgress: MutableState<NeuralSaveProgress?> = mutableStateOf(null)\n    val saveProgress by _saveProgress\n\n    private var savingJob: Job? by smartJob {\n        _saveProgress.update { null }\n    }\n\n    private var downloadJobs: MutableMap<String, Job> = mutableMapOf()\n\n    val occupiedStorageSize: StateFlow<Long> = aiToolsRepository.occupiedStorageSize\n\n    val downloadedModels: StateFlow<List<NeuralModel>> = aiToolsRepository.downloadedModels\n\n    val notDownloadedModels: StateFlow<List<NeuralModel>> = downloadedModels.map {\n        NeuralModel.entries - it.toSet()\n    }.stateIn(\n        scope = componentScope,\n        started = SharingStarted.Eagerly,\n        initialValue = NeuralModel.entries\n    )\n\n    val selectedModel: StateFlow<NeuralModel?> = aiToolsRepository.selectedModel\n\n    private val _downloadProgresses: SnapshotStateMap<String, DownloadProgress> =\n        mutableStateMapOf()\n    val downloadProgresses: Map<String, DownloadProgress> = _downloadProgresses\n\n    private val _params = fileController.savable(\n        scope = componentScope,\n        initial = NeuralParams.Default\n    )\n    val params by _params\n\n    private val _imageFormat: MutableState<ImageFormat?> = mutableStateOf(null)\n    val imageFormat by _imageFormat\n\n    private val aiProgressListener = object : AiProgressListener {\n        override fun onError(error: String) {\n            AppToastHost.showFailureToast(error)\n        }\n\n        override fun onProgress(\n            currentChunkIndex: Int,\n            totalChunks: Int\n        ) {\n            _saveProgress.updateNotNull {\n                it.copy(\n                    doneChunks = currentChunkIndex,\n                    totalChunks = totalChunks\n                )\n            }\n        }\n    }\n\n    fun selectModel(model: NeuralModel) {\n        componentScope.launch {\n            aiToolsRepository.selectModel(model)\n            registerChanges()\n        }\n    }\n\n    fun downloadModel(model: NeuralModel) {\n        if (downloadJobs.contains(model.name)) return\n\n        downloadJobs[model.name] = componentScope.launch {\n            aiToolsRepository\n                .downloadModel(model)\n                .onCompletion {\n                    _downloadProgresses.remove(model.name)\n                    downloadJobs.remove(model.name)\n                }\n                .catch {\n                    _downloadProgresses.remove(model.name)\n                    downloadJobs.remove(model.name)\n                }\n                .collect { progress ->\n                    _downloadProgresses[model.name] = progress\n                }\n        }\n    }\n\n    fun cancelDownload(model: NeuralModel) {\n        downloadJobs.remove(model.name)?.cancel()\n    }\n\n    fun importModel(uri: Uri) {\n        componentScope.launch {\n            _isImageLoading.update { true }\n\n            when (val result = aiToolsRepository.importModel(uri.toString())) {\n                SaveResult.Skipped -> {\n                    AppToastHost.showToast(\n                        message = getString(R.string.model_already_downloaded),\n                        icon = Icons.Outlined.Info\n                    )\n                }\n\n                is SaveResult.Success -> {\n                    AppToastHost.showToast(\n                        message = getString(R.string.model_successfully_imported),\n                        icon = Icons.Outlined.CheckCircle\n                    )\n                }\n\n                else -> parseFileSaveResult(result)\n            }\n\n            _isImageLoading.update { false }\n        }\n    }\n\n    fun deleteModel(model: NeuralModel) {\n        componentScope.launch {\n            aiToolsRepository.deleteModel(model)\n        }\n    }\n\n    fun updateParams(\n        action: NeuralParams.() -> NeuralParams\n    ) {\n        _params.update { action(it) }\n        registerChanges()\n    }\n\n    fun updateUris(uris: List<Uri>?) {\n        _uris.value = null\n        _uris.value = uris\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            if (selectedModel.value?.type == NeuralModel.Type.REMOVE_BG && imageFormat == null) {\n                setImageFormat(ImageFormat.Png.Lossless)\n            }\n            delay(400)\n            _saveProgress.update {\n                NeuralSaveProgress(\n                    doneImages = 0,\n                    totalImages = uris.orEmpty().size,\n                    doneChunks = 0,\n                    totalChunks = 0\n                )\n            }\n\n            val results = mutableListOf<SaveResult>()\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    val (image, imageInfo) = imageGetter.getImage(uri.toString())\n                        ?: return@runSuspendCatching null\n\n                    aiToolsRepository.processImage(\n                        image = image,\n                        listener = aiProgressListener,\n                        params = params\n                    )?.let {\n                        it to imageInfo.copy(\n                            width = it.width,\n                            height = it.height,\n                            originalUri = uri.toString(),\n                            imageFormat = imageFormat ?: imageInfo.imageFormat\n                        )\n                    }\n                }.onFailure {\n                    results.add(\n                        SaveResult.Error.Exception(it)\n                    )\n                }.getOrNull()?.let { (image, imageInfo) ->\n                    results.add(\n                        fileController.save(\n                            ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                originalUri = uri.toString(),\n                                sequenceNumber = _saveProgress.value?.doneImages?.plus(1),\n                                data = imageCompressor.compressAndTransform(\n                                    image = image,\n                                    imageInfo = imageInfo\n                                )\n                            ),\n                            keepOriginalMetadata = false,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    )\n                }\n\n                _saveProgress.updateNotNull {\n                    it.copy(\n                        doneImages = it.doneImages + 1\n                    )\n                }\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _saveProgress.update { null }\n\n            aiToolsRepository.cleanup()\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _saveProgress.update { null }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            if (selectedModel.value?.type == NeuralModel.Type.REMOVE_BG && imageFormat == null) {\n                setImageFormat(ImageFormat.Png.Lossless)\n            }\n            delay(400)\n            _saveProgress.update {\n                NeuralSaveProgress(\n                    doneImages = 0,\n                    totalImages = uris.orEmpty().size,\n                    doneChunks = 0,\n                    totalChunks = 0\n                )\n            }\n            val list = mutableListOf<Uri>()\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    val (image, imageInfo) = imageGetter.getImage(uri.toString())\n                        ?: return@runSuspendCatching null\n\n                    aiToolsRepository.processImage(\n                        image = image,\n                        listener = aiProgressListener,\n                        params = params\n                    )?.let {\n                        it to imageInfo.copy(\n                            width = it.width,\n                            height = it.height,\n                            originalUri = uri.toString(),\n                            imageFormat = imageFormat ?: imageInfo.imageFormat\n                        )\n                    }\n                }.getOrNull()?.let { (image, imageInfo) ->\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = imageInfo\n                    )?.let { uri ->\n                        list.add(uri.toUri())\n                    }\n                }\n\n                _saveProgress.updateNotNull {\n                    it.copy(\n                        doneImages = it.doneImages + 1\n                    )\n                }\n            }\n            onComplete(list)\n            _saveProgress.update { null }\n\n            aiToolsRepository.cleanup()\n        }\n    }\n\n    fun shareBitmaps() {\n        cacheImages { uris ->\n            componentScope.launch {\n                shareProvider.shareUris(uris.map { it.toString() })\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun removeUri(uri: Uri) {\n        _uris.update { it.orEmpty() - uri }\n    }\n\n    fun addUris(uris: List<Uri>) {\n        _uris.update { it.orEmpty() + uris }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat?) {\n        _imageFormat.update { imageFormat }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): AiToolsComponent\n    }\n\n\n}"
  },
  {
    "path": "feature/apng-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/apng-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.apng_tools\"\n\ndependencies {\n    implementation(libs.toolbox.apng)\n    implementation(libs.jxl.coder)\n}"
  },
  {
    "path": "feature/apng-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/apng-tools/src/main/java/com/t8rin/imagetoolbox/feature/apng_tools/data/AndroidApngConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.apng_tools.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.net.toUri\nimport com.awxkee.jxlcoder.JxlCoder\nimport com.awxkee.jxlcoder.JxlDecodingSpeed\nimport com.awxkee.jxlcoder.JxlEffort\nimport com.t8rin.imagetoolbox.core.data.utils.outputStream\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.feature.apng_tools.domain.ApngConverter\nimport com.t8rin.imagetoolbox.feature.apng_tools.domain.ApngParams\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.cancel\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.channelFlow\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.withContext\nimport oupson.apng.decoder.ApngDecoder\nimport oupson.apng.encoder.ApngEncoder\nimport javax.inject.Inject\n\n\ninternal class AndroidApngConverter @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    @ApplicationContext private val context: Context,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, ApngConverter {\n\n    override fun extractFramesFromApng(\n        apngUri: String,\n        imageFormat: ImageFormat,\n        quality: Quality\n    ): Flow<String> = channelFlow {\n        ApngDecoder(\n            context = context,\n            uri = apngUri.toUri()\n        ).decodeAsync(defaultDispatcher) { frame ->\n            if (!currentCoroutineContext().isActive) {\n                currentCoroutineContext().cancel(null)\n                return@decodeAsync\n            }\n            shareProvider.cacheImage(\n                image = frame,\n                imageInfo = ImageInfo(\n                    width = frame.width,\n                    height = frame.height,\n                    imageFormat = imageFormat,\n                    quality = quality\n                )\n            )?.let { send(it) }\n        }\n    }\n\n    override suspend fun createApngFromImageUris(\n        imageUris: List<String>,\n        params: ApngParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): String? = withContext(defaultDispatcher) {\n        val size = params.size ?: imageGetter.getImage(data = imageUris[0])!!.run {\n            IntegerSize(width, height)\n        }\n\n        if (size.width <= 0 || size.height <= 0) {\n            onFailure(IllegalArgumentException(\"Width and height must be > 0\"))\n            return@withContext null\n        }\n\n        shareProvider.cacheData(\n            writeData = { writeable ->\n                val encoder = ApngEncoder(\n                    outputStream = writeable.outputStream(),\n                    width = size.width,\n                    height = size.height,\n                    numberOfFrames = imageUris.size\n                ).apply {\n                    setOptimiseApng(false)\n                    setRepetitionCount(params.repeatCount)\n                    setCompressionLevel(params.quality.qualityValue)\n                }\n                imageUris.forEach { uri ->\n                    imageGetter.getImage(\n                        data = uri,\n                        size = size\n                    )?.let {\n                        encoder.writeFrame(\n                            btm = imageScaler.scaleImage(\n                                image = imageScaler.scaleImage(\n                                    image = it,\n                                    width = size.width,\n                                    height = size.height,\n                                    resizeType = ResizeType.Flexible\n                                ),\n                                width = size.width,\n                                height = size.height,\n                                resizeType = ResizeType.CenterCrop(\n                                    canvasColor = Color.Transparent.toArgb()\n                                )\n                            ),\n                            delay = params.delay.toFloat()\n                        )\n                    }\n                    onProgress()\n                }\n                encoder.writeEnd()\n            },\n            filename = \"temp_apng.png\"\n        )\n    }\n\n    override suspend fun convertApngToJxl(\n        apngUris: List<String>,\n        quality: Quality.Jxl,\n        onProgress: suspend (String, ByteArray) -> Unit\n    ) = withContext(defaultDispatcher) {\n        apngUris.forEach { uri ->\n            uri.bytes?.let { apngData ->\n                runSuspendCatching {\n                    JxlCoder.Convenience.apng2JXL(\n                        apngData = apngData,\n                        quality = quality.qualityValue,\n                        effort = JxlEffort.entries.first { it.ordinal == quality.effort },\n                        decodingSpeed = JxlDecodingSpeed.entries.first { it.ordinal == quality.speed }\n                    ).let {\n                        onProgress(uri, it)\n                    }\n                }\n            }\n        }\n    }\n\n    private val String.bytes: ByteArray?\n        get() = context\n            .contentResolver\n            .openInputStream(toUri())?.use {\n                it.readBytes()\n            }\n\n}"
  },
  {
    "path": "feature/apng-tools/src/main/java/com/t8rin/imagetoolbox/feature/apng_tools/di/ApngToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.apng_tools.di\n\nimport com.t8rin.imagetoolbox.feature.apng_tools.data.AndroidApngConverter\nimport com.t8rin.imagetoolbox.feature.apng_tools.domain.ApngConverter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ApngToolsModule {\n\n    @Binds\n    @Singleton\n    fun provideConverter(\n        converter: AndroidApngConverter\n    ): ApngConverter\n\n}"
  },
  {
    "path": "feature/apng-tools/src/main/java/com/t8rin/imagetoolbox/feature/apng_tools/domain/ApngConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.apng_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport kotlinx.coroutines.flow.Flow\n\ninterface ApngConverter {\n\n    fun extractFramesFromApng(\n        apngUri: String,\n        imageFormat: ImageFormat,\n        quality: Quality\n    ): Flow<String>\n\n    suspend fun createApngFromImageUris(\n        imageUris: List<String>,\n        params: ApngParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): String?\n\n    suspend fun convertApngToJxl(\n        apngUris: List<String>,\n        quality: Quality.Jxl,\n        onProgress: suspend (String, ByteArray) -> Unit\n    )\n\n}"
  },
  {
    "path": "feature/apng-tools/src/main/java/com/t8rin/imagetoolbox/feature/apng_tools/domain/ApngParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.apng_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ndata class ApngParams(\n    val size: IntegerSize?,\n    val repeatCount: Int,\n    val delay: Int,\n    val quality: Quality\n) {\n    companion object {\n        val Default by lazy {\n            ApngParams(\n                size = null,\n                repeatCount = 1,\n                delay = 1000,\n                quality = Quality.Base(5)\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/apng-tools/src/main/java/com/t8rin/imagetoolbox/feature/apng_tools/presentation/ApngToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.apng_tools.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Gif\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Apng\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageReorderCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagesPreviewWithSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.image.urisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.core.utils.isApng\nimport com.t8rin.imagetoolbox.feature.apng_tools.presentation.components.ApngParamsSelector\nimport com.t8rin.imagetoolbox.feature.apng_tools.presentation.screenLogic.ApngToolsComponent\n\n@Composable\nfun ApngToolsContent(\n    component: ApngToolsComponent\n) {\n    val imagePicker = rememberImagePicker(onSuccess = component::setImageUris)\n\n    val pickSingleApngLauncher = rememberFilePicker(\n        mimeType = MimeType.Png,\n        onSuccess = { uri: Uri ->\n            if (uri.isApng()) {\n                component.setApngUri(uri)\n            } else {\n                AppToastHost.showToast(\n                    message = getString(R.string.select_apng_image_to_start),\n                    icon = Icons.Rounded.Apng\n                )\n            }\n        }\n    )\n\n    val pickMultipleApngLauncher = rememberFilePicker(\n        mimeType = MimeType.Png,\n        onSuccess = { list: List<Uri> ->\n            list.filter {\n                it.isApng()\n            }.let { uris ->\n                if (uris.isEmpty()) {\n                    AppToastHost.showToast(\n                        message = getString(R.string.select_apng_image_to_start),\n                        icon = Icons.Rounded.Apng\n                    )\n                } else {\n                    component.setType(\n                        Screen.ApngTools.Type.ApngToJxl(uris)\n                    )\n                }\n            }\n        }\n    )\n\n    val addApngLauncher = rememberFilePicker(\n        mimeType = MimeType.Png,\n        onSuccess = { list: List<Uri> ->\n            list.filter {\n                it.isApng()\n            }.let { uris ->\n                if (uris.isEmpty()) {\n                    AppToastHost.showToast(\n                        message = getString(R.string.select_gif_image_to_start),\n                        icon = Icons.Filled.Gif\n                    )\n                } else {\n                    component.setType(\n                        Screen.ApngTools.Type.ApngToJxl(\n                            (component.type as? Screen.ApngTools.Type.ApngToJxl)?.apngUris?.plus(\n                                uris\n                            )?.distinct()\n                        )\n                    )\n                }\n            }\n        }\n    )\n\n    val saveApngLauncher = rememberFileCreator(\n        mimeType = MimeType.Apng,\n        onSuccess = component::saveApngTo\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = when (val type = component.type) {\n                    null -> stringResource(R.string.apng_tools)\n                    else -> stringResource(type.title)\n                },\n                input = component.type,\n                isLoading = component.isLoading,\n                size = null\n            )\n        },\n        onGoBack = onBack,\n        topAppBarPersistentActions = {\n            if (component.type == null) TopAppBarEmoji()\n            val pagesSize by remember(component.imageFrames, component.convertedImageUris) {\n                derivedStateOf {\n                    component.imageFrames.getFramePositions(component.convertedImageUris.size).size\n                }\n            }\n            val isApngToImage = component.type is Screen.ApngTools.Type.ApngToImage\n            AnimatedVisibility(\n                visible = isApngToImage && pagesSize != component.convertedImageUris.size,\n                enter = fadeIn() + scaleIn() + expandHorizontally(),\n                exit = fadeOut() + scaleOut() + shrinkHorizontally()\n            ) {\n                EnhancedIconButton(\n                    onClick = component::selectAllConvertedImages\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.SelectAll,\n                        contentDescription = \"Select All\"\n                    )\n                }\n            }\n            AnimatedVisibility(\n                modifier = Modifier\n                    .padding(8.dp)\n                    .container(\n                        shape = ShapeDefaults.circle,\n                        color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                        resultPadding = 0.dp\n                    ),\n                visible = isApngToImage && pagesSize != 0\n            ) {\n                Row(\n                    modifier = Modifier.padding(start = 12.dp),\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.Center\n                ) {\n                    pagesSize.takeIf { it != 0 }?.let {\n                        Spacer(Modifier.width(8.dp))\n                        Text(\n                            text = it.toString(),\n                            fontSize = 20.sp,\n                            fontWeight = FontWeight.Medium\n                        )\n                    }\n                    EnhancedIconButton(\n                        onClick = component::clearConvertedImagesSelection\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Close,\n                            contentDescription = stringResource(R.string.close)\n                        )\n                    }\n                }\n            }\n        },\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = !component.isLoading && component.type != null,\n                onShare = component::performSharing,\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        imagePreview = {\n            AnimatedContent(\n                targetState = component.isLoading to component.type\n            ) { (loading, type) ->\n                Box(\n                    contentAlignment = Alignment.Center,\n                    modifier = if (loading) {\n                        Modifier.padding(32.dp)\n                    } else Modifier\n                ) {\n                    if (loading || type == null) {\n                        EnhancedLoadingIndicator()\n                    } else {\n                        when (type) {\n                            is Screen.ApngTools.Type.ApngToImage -> {\n                                ImagesPreviewWithSelection(\n                                    imageUris = component.convertedImageUris,\n                                    imageFrames = component.imageFrames,\n                                    onFrameSelectionChange = component::updateApngFrames,\n                                    isPortrait = isPortrait,\n                                    isLoadingImages = component.isLoadingApngImages\n                                )\n                            }\n\n                            is Screen.ApngTools.Type.ApngToJxl -> {\n                                UrisPreview(\n                                    modifier = Modifier.urisPreview(),\n                                    uris = type.apngUris ?: emptyList(),\n                                    isPortrait = true,\n                                    onRemoveUri = {\n                                        component.setType(\n                                            Screen.ApngTools.Type.ApngToJxl(type.apngUris?.minus(it))\n                                        )\n                                    },\n                                    onAddUris = addApngLauncher::pickFile\n                                )\n                            }\n\n                            is Screen.ApngTools.Type.ImageToApng -> Unit\n                        }\n                    }\n                }\n            }\n        },\n        placeImagePreview = component.type !is Screen.ApngTools.Type.ImageToApng,\n        showImagePreviewAsStickyHeader = false,\n        autoClearFocus = false,\n        controls = {\n            when (val type = component.type) {\n                is Screen.ApngTools.Type.ApngToImage -> {\n                    Spacer(modifier = Modifier.height(16.dp))\n                    ImageFormatSelector(\n                        value = component.imageFormat,\n                        quality = if (component.type is Screen.ApngTools.Type.ApngToJxl) {\n                            component.jxlQuality\n                        } else {\n                            component.params.quality\n                        },\n                        onValueChange = component::setImageFormat,\n                        entries = ImageFormatGroup.alphaContainedEntries\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    QualitySelector(\n                        imageFormat = component.imageFormat,\n                        quality = component.params.quality,\n                        onQualityChange = component::setQuality\n                    )\n                    Spacer(modifier = Modifier.height(16.dp))\n                }\n\n                is Screen.ApngTools.Type.ImageToApng -> {\n                    val addImagesToPdfPicker =\n                        rememberImagePicker(onSuccess = component::addImageToUris)\n\n                    Spacer(modifier = Modifier.height(16.dp))\n                    ImageReorderCarousel(\n                        images = type.imageUris,\n                        onReorder = component::reorderImageUris,\n                        onNeedToAddImage = addImagesToPdfPicker::pickImage,\n                        onNeedToRemoveImageAt = component::removeImageAt,\n                        onNavigate = component.onNavigate\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    ApngParamsSelector(\n                        value = component.params,\n                        onValueChange = component::updateParams\n                    )\n                    Spacer(modifier = Modifier.height(16.dp))\n                }\n\n                is Screen.ApngTools.Type.ApngToJxl -> {\n                    QualitySelector(\n                        imageFormat = ImageFormat.Jxl.Lossy,\n                        quality = component.jxlQuality,\n                        onQualityChange = component::setJxlQuality\n                    )\n                }\n\n                null -> Unit\n            }\n        },\n        contentPadding = animateDpAsState(\n            if (component.type == null) 12.dp\n            else 20.dp\n        ).value,\n        buttons = { actions ->\n            val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n                component.saveBitmaps(\n                    oneTimeSaveLocationUri = it,\n                    onApngSaveResult = saveApngLauncher::make\n                )\n            }\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.type == null,\n                onSecondaryButtonClick = {\n                    when (component.type) {\n                        is Screen.ApngTools.Type.ApngToImage -> pickSingleApngLauncher.pickFile()\n                        is Screen.ApngTools.Type.ApngToJxl -> pickMultipleApngLauncher.pickFile()\n                        else -> imagePicker.pickImage()\n                    }\n                },\n                isPrimaryButtonVisible = component.canSave,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    if (component.type is Screen.ApngTools.Type.ImageToApng) {\n                        saveBitmaps(null)\n                    } else showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                showNullDataButtonAsContainer = true,\n                onSecondaryButtonLongClick = if (component.type is Screen.ApngTools.Type.ImageToApng || component.type == null) {\n                    {\n                        showOneTimeImagePickingDialog = true\n                    }\n                } else null\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        insetsForNoData = WindowInsets(0),\n        noDataControls = {\n            val types = remember {\n                Screen.ApngTools.Type.entries\n            }\n            val preference1 = @Composable {\n                PreferenceItem(\n                    title = stringResource(types[0].title),\n                    subtitle = stringResource(types[0].subtitle),\n                    startIcon = types[0].icon,\n                    modifier = Modifier.fillMaxWidth(),\n                    onClick = imagePicker::pickImage\n                )\n            }\n            val preference2 = @Composable {\n                PreferenceItem(\n                    title = stringResource(types[1].title),\n                    subtitle = stringResource(types[1].subtitle),\n                    startIcon = types[1].icon,\n                    modifier = Modifier.fillMaxWidth(),\n                    onClick = pickSingleApngLauncher::pickFile\n                )\n            }\n            val preference3 = @Composable {\n                PreferenceItem(\n                    title = stringResource(types[2].title),\n                    subtitle = stringResource(types[2].subtitle),\n                    startIcon = types[2].icon,\n                    modifier = Modifier.fillMaxWidth(),\n                    onClick = pickMultipleApngLauncher::pickFile\n                )\n            }\n\n            if (isPortrait) {\n                Column {\n                    preference1()\n                    Spacer(modifier = Modifier.height(8.dp))\n                    preference2()\n                    Spacer(modifier = Modifier.height(8.dp))\n                    preference3()\n                }\n            } else {\n                val direction = LocalLayoutDirection.current\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Row(\n                        modifier = Modifier.padding(\n                            WindowInsets.displayCutout.asPaddingValues().let {\n                                PaddingValues(\n                                    start = it.calculateStartPadding(direction),\n                                    end = it.calculateEndPadding(direction)\n                                )\n                            }\n                        )\n                    ) {\n                        preference1.withModifier(modifier = Modifier.weight(1f))\n                        Spacer(modifier = Modifier.width(8.dp))\n                        preference2.withModifier(modifier = Modifier.weight(1f))\n                    }\n                    Spacer(modifier = Modifier.height(8.dp))\n                    preference3.withModifier(modifier = Modifier.fillMaxWidth(0.5f))\n                }\n            }\n        },\n        canShowScreenData = component.type != null\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component::clearAll,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/apng-tools/src/main/java/com/t8rin/imagetoolbox/feature/apng_tools/presentation/components/ApngParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.apng_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectLarge\nimport androidx.compose.material.icons.outlined.RepeatOne\nimport androidx.compose.material.icons.outlined.Timelapse\nimport androidx.compose.material.icons.rounded.Stream\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.apng_tools.domain.ApngParams\nimport kotlin.math.roundToInt\n\n@Composable\nfun ApngParamsSelector(\n    value: ApngParams,\n    onValueChange: (ApngParams) -> Unit\n) {\n    Column {\n        val size = value.size ?: IntegerSize.Undefined\n        AnimatedVisibility(size.isDefined()) {\n            ResizeImageField(\n                imageInfo = ImageInfo(size.width, size.height),\n                originalSize = null,\n                onWidthChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(width = it)\n                        )\n                    )\n                },\n                onHeightChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(height = it)\n                        )\n                    )\n                }\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.use_size_of_first_frame),\n            subtitle = stringResource(id = R.string.use_size_of_first_frame_sub),\n            checked = value.size == null,\n            onClick = {\n                onValueChange(\n                    value.copy(size = if (it) null else IntegerSize(1000, 1000))\n                )\n            },\n            startIcon = Icons.Outlined.PhotoSizeSelectLarge,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.quality.qualityValue,\n            title = stringResource(R.string.effort),\n            icon = Icons.Rounded.Stream,\n            valueRange = 0f..9f,\n            steps = 9,\n            internalStateTransformation = {\n                it.toInt().coerceIn(0..9).toFloat()\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        quality = Quality.Base(it.toInt())\n                    )\n                )\n            }\n        ) {\n            Text(\n                text = stringResource(\n                    R.string.effort_sub,\n                    0, 9\n                ),\n                fontSize = 12.sp,\n                textAlign = TextAlign.Center,\n                lineHeight = 12.sp,\n                color = LocalContentColor.current.copy(0.5f),\n                modifier = Modifier\n                    .padding(4.dp)\n                    .container(ShapeDefaults.large)\n                    .padding(4.dp)\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.repeatCount,\n            icon = Icons.Outlined.RepeatOne,\n            title = stringResource(id = R.string.repeat_count),\n            valueRange = 1f..10f,\n            steps = 9,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        repeatCount = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.delay,\n            icon = Icons.Outlined.Timelapse,\n            title = stringResource(id = R.string.frame_delay),\n            valueRange = 1f..4000f,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        delay = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n    }\n}"
  },
  {
    "path": "feature/apng-tools/src/main/java/com/t8rin/imagetoolbox/feature/apng_tools/presentation/screenLogic/ApngToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.feature.apng_tools.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FileSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.apng_tools.domain.ApngConverter\nimport com.t8rin.imagetoolbox.feature.apng_tools.domain.ApngParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.onCompletion\n\nclass ApngToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted initialType: Screen.ApngTools.Type?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val filenameCreator: FilenameCreator,\n    private val apngConverter: ApngConverter,\n    private val shareProvider: ShareProvider,\n    defaultDispatchersHolder: DispatchersHolder\n) : BaseComponent(defaultDispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialType?.let(::setType)\n        }\n    }\n\n    private val _type: MutableState<Screen.ApngTools.Type?> = mutableStateOf(null)\n    val type by _type\n\n    private val _isLoading: MutableState<Boolean> = mutableStateOf(false)\n    val isLoading by _isLoading\n\n    private val _isLoadingApngImages: MutableState<Boolean> = mutableStateOf(false)\n    val isLoadingApngImages by _isLoadingApngImages\n\n    private val _params: MutableState<ApngParams> = mutableStateOf(ApngParams.Default)\n    val params by _params\n\n    private val _convertedImageUris: MutableState<List<String>> = mutableStateOf(emptyList())\n    val convertedImageUris by _convertedImageUris\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Png.Lossless)\n    val imageFormat by _imageFormat\n\n    private val _imageFrames: MutableState<ImageFrames> = mutableStateOf(ImageFrames.All)\n    val imageFrames by _imageFrames\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _jxlQuality: MutableState<Quality.Jxl> = mutableStateOf(Quality.Jxl())\n    val jxlQuality by _jxlQuality\n\n    private var _outputApngUri: String? = null\n\n    fun setType(type: Screen.ApngTools.Type) {\n        when (type) {\n            is Screen.ApngTools.Type.ApngToImage -> {\n                type.apngUri?.let { setApngUri(it) } ?: _type.update { null }\n            }\n\n            is Screen.ApngTools.Type.ImageToApng -> {\n                _type.update { type }\n            }\n\n            is Screen.ApngTools.Type.ApngToJxl -> {\n                _type.update { type }\n            }\n        }\n    }\n\n    fun setImageUris(uris: List<Uri>) {\n        clearAll()\n        _type.update {\n            Screen.ApngTools.Type.ImageToApng(uris)\n        }\n    }\n\n    private var collectionJob: Job? by smartJob {\n        _isLoading.update { false }\n    }\n\n    fun setApngUri(uri: Uri) {\n        clearAll()\n        _type.update {\n            Screen.ApngTools.Type.ApngToImage(uri)\n        }\n        updateApngFrames(ImageFrames.All)\n        collectionJob = componentScope.launch {\n            _isLoading.update { true }\n            _isLoadingApngImages.update { true }\n            apngConverter.extractFramesFromApng(\n                apngUri = uri.toString(),\n                imageFormat = imageFormat,\n                quality = params.quality\n            ).onCompletion {\n                _isLoading.update { false }\n                _isLoadingApngImages.update { false }\n            }.collect { nextUri ->\n                if (isLoading) {\n                    _isLoading.update { false }\n                }\n                _convertedImageUris.update { it + nextUri }\n            }\n        }\n    }\n\n    fun clearAll() {\n        collectionJob = null\n        _type.update { null }\n        _convertedImageUris.update { emptyList() }\n        _outputApngUri = null\n        savingJob = null\n        updateParams(ApngParams.Default)\n        registerChangesCleared()\n    }\n\n    fun updateApngFrames(imageFrames: ImageFrames) {\n        _imageFrames.update { imageFrames }\n        registerChanges()\n    }\n\n    fun clearConvertedImagesSelection() = updateApngFrames(ImageFrames.ManualSelection(emptyList()))\n\n    fun selectAllConvertedImages() = updateApngFrames(ImageFrames.All)\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveApngTo(uri: Uri) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _outputApngUri?.let { apngUri ->\n                fileController.transferBytes(\n                    fromUri = apngUri,\n                    toUri = uri.toString(),\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n            _isSaving.value = false\n            _outputApngUri = null\n        }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?,\n        onApngSaveResult: (String) -> Unit\n    ) {\n        _isSaving.value = false\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.ApngTools.Type.ApngToImage -> {\n                    val results = mutableListOf<SaveResult>()\n                    type.apngUri?.toString()?.also { apngUri ->\n                        _left.value = 0\n                        apngConverter.extractFramesFromApng(\n                            apngUri = apngUri,\n                            imageFormat = imageFormat,\n                            quality = params.quality\n                        ).onCompletion {\n                            parseSaveResults(results.onSuccess(::registerSave))\n                        }.collect { uri ->\n                            imageGetter.getImage(\n                                data = uri,\n                                originalSize = true\n                            )?.let { localBitmap ->\n                                if ((done + 1) in imageFrames.getFramePositions(convertedImageUris.size + 10)) {\n                                    val imageInfo = ImageInfo(\n                                        imageFormat = imageFormat,\n                                        width = localBitmap.width,\n                                        height = localBitmap.height\n                                    )\n\n                                    results.add(\n                                        fileController.save(\n                                            saveTarget = ImageSaveTarget(\n                                                imageInfo = imageInfo,\n                                                originalUri = uri,\n                                                sequenceNumber = _done.value + 1,\n                                                data = imageCompressor.compressAndTransform(\n                                                    image = localBitmap,\n                                                    imageInfo = ImageInfo(\n                                                        imageFormat = imageFormat,\n                                                        quality = params.quality,\n                                                        width = localBitmap.width,\n                                                        height = localBitmap.height\n                                                    )\n                                                )\n                                            ),\n                                            keepOriginalMetadata = false,\n                                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                                        )\n                                    )\n                                }\n                            } ?: results.add(\n                                SaveResult.Error.Exception(Throwable())\n                            )\n                            _done.value++\n                        }\n                    }\n                }\n\n                is Screen.ApngTools.Type.ImageToApng -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    _outputApngUri = type.imageUris?.map { it.toString() }?.let { list ->\n                        apngConverter.createApngFromImageUris(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                            },\n                            onFailure = {\n                                parseSaveResults(listOf(SaveResult.Error.Exception(it)))\n                            }\n                        )?.also {\n                            onApngSaveResult(\"APNG_${timestamp()}.png\")\n                            registerSave()\n                        }\n                    }\n                }\n\n                is Screen.ApngTools.Type.ApngToJxl -> {\n                    val results = mutableListOf<SaveResult>()\n                    val apngUris = type.apngUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = apngUris.size\n                    apngConverter.convertApngToJxl(\n                        apngUris = apngUris,\n                        quality = jxlQuality\n                    ) { uri, jxlBytes ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = JxlSaveTarget(uri, jxlBytes),\n                                keepOriginalMetadata = true,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                        _done.update { it + 1 }\n                    }\n\n                    parseSaveResults(results.onSuccess(::registerSave))\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    private fun JxlSaveTarget(\n        uri: String,\n        jxlBytes: ByteArray\n    ): SaveTarget = FileSaveTarget(\n        originalUri = uri,\n        filename = jxlFilename(uri),\n        data = jxlBytes,\n        imageFormat = ImageFormat.Jxl.Lossless\n    )\n\n    private fun jxlFilename(\n        uri: String\n    ): String = filenameCreator.constructImageFilename(\n        ImageSaveTarget(\n            imageInfo = ImageInfo(\n                imageFormat = ImageFormat.Jxl.Lossless,\n                originalUri = uri\n            ),\n            originalUri = uri,\n            sequenceNumber = done + 1,\n            metadata = null,\n            data = ByteArray(0)\n        ),\n        forceNotAddSizeInFilename = true\n    )\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun reorderImageUris(uris: List<Uri>?) {\n        if (type is Screen.ApngTools.Type.ImageToApng) {\n            _type.update {\n                Screen.ApngTools.Type.ImageToApng(uris)\n            }\n        }\n        registerChanges()\n    }\n\n    fun addImageToUris(uris: List<Uri>) {\n        val type = _type.value\n        if (type is Screen.ApngTools.Type.ImageToApng) {\n            _type.update {\n                val newUris = type.imageUris?.plus(uris)?.toSet()?.toList()\n\n                Screen.ApngTools.Type.ImageToApng(newUris)\n            }\n        }\n        registerChanges()\n    }\n\n    fun removeImageAt(index: Int) {\n        val type = _type.value\n        if (type is Screen.ApngTools.Type.ImageToApng) {\n            _type.update {\n                val newUris = type.imageUris?.toMutableList()?.apply {\n                    removeAt(index)\n                }\n\n                Screen.ApngTools.Type.ImageToApng(newUris)\n            }\n        }\n        registerChanges()\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        registerChanges()\n    }\n\n    fun setQuality(quality: Quality) {\n        updateParams(params.copy(quality = quality))\n    }\n\n    fun updateParams(params: ApngParams) {\n        _params.update { params }\n        registerChanges()\n    }\n\n    fun performSharing() {\n        cacheImages { uris ->\n            componentScope.launch {\n                shareProvider.shareUris(uris.map { it.toString() })\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun setJxlQuality(quality: Quality) {\n        _jxlQuality.update {\n            (quality as? Quality.Jxl) ?: Quality.Jxl()\n        }\n        registerChanges()\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.ApngTools.Type.ApngToImage -> {\n                    _left.value = -1\n                    val positions =\n                        imageFrames.getFramePositions(convertedImageUris.size).map { it - 1 }\n                    val uris = convertedImageUris.filterIndexed { index, _ ->\n                        index in positions\n                    }\n                    onComplete(uris.map { it.toUri() })\n                }\n\n                is Screen.ApngTools.Type.ImageToApng -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    type.imageUris?.map { it.toString() }?.let { list ->\n                        apngConverter.createApngFromImageUris(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            },\n                            onFailure = {}\n                        )?.also { uri ->\n                            onComplete(listOf(uri.toUri()))\n                        }\n                    }\n                }\n\n                is Screen.ApngTools.Type.ApngToJxl -> {\n                    val results = mutableListOf<String?>()\n                    val apngUris = type.apngUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = apngUris.size\n                    apngConverter.convertApngToJxl(\n                        apngUris = apngUris,\n                        quality = jxlQuality\n                    ) { uri, jxlBytes ->\n                        results.add(\n                            shareProvider.cacheByteArray(\n                                byteArray = jxlBytes,\n                                filename = jxlFilename(uri)\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    onComplete(results.mapNotNull { it?.toUri() })\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    val canSave: Boolean\n        get() = (imageFrames == ImageFrames.All)\n            .or(type is Screen.ApngTools.Type.ImageToApng)\n            .or((imageFrames as? ImageFrames.ManualSelection)?.framePositions?.isNotEmpty() == true)\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialType: Screen.ApngTools.Type?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ApngToolsComponent\n    }\n}"
  },
  {
    "path": "feature/ascii-art/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/ascii-art/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.ascii_art\"\n\ndependencies {\n    implementation(projects.feature.filters)\n    implementation(projects.lib.ascii)\n}"
  },
  {
    "path": "feature/ascii-art/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/ascii-art/src/main/java/com/t8rin/imagetoolbox/feature/ascii_art/data/AndroidAsciiConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ascii_art.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.ascii.ASCIIConverter\nimport com.t8rin.ascii.Gradient\nimport com.t8rin.ascii.toMapper\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.feature.ascii_art.domain.AsciiConverter\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidAsciiConverter @Inject constructor(\n    dispatchersHolder: DispatchersHolder\n) : AsciiConverter<Bitmap>, DispatchersHolder by dispatchersHolder {\n\n    override suspend fun imageToAscii(\n        image: Bitmap,\n        fontSize: Float,\n        gradient: String\n    ): String = withContext(defaultDispatcher) {\n        ASCIIConverter(\n            fontSize = fontSize,\n            mapper = Gradient(gradient).toMapper()\n        ).convertToAscii(image)\n    }\n\n}"
  },
  {
    "path": "feature/ascii-art/src/main/java/com/t8rin/imagetoolbox/feature/ascii_art/di/AsciiArtModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ascii_art.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.ascii_art.data.AndroidAsciiConverter\nimport com.t8rin.imagetoolbox.feature.ascii_art.domain.AsciiConverter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface AsciiArtModule {\n\n    @Binds\n    @Singleton\n    fun converter(impl: AndroidAsciiConverter): AsciiConverter<Bitmap>\n\n}"
  },
  {
    "path": "feature/ascii-art/src/main/java/com/t8rin/imagetoolbox/feature/ascii_art/domain/AsciiConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ascii_art.domain\n\ninterface AsciiConverter<Image> {\n\n    suspend fun imageToAscii(\n        image: Image,\n        fontSize: Float,\n        gradient: String\n    ): String\n\n}"
  },
  {
    "path": "feature/ascii-art/src/main/java/com/t8rin/imagetoolbox/feature/ascii_art/presentation/AsciiArtContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ascii_art.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.shareText\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.ascii_art.presentation.components.AsciiArtControls\nimport com.t8rin.imagetoolbox.feature.ascii_art.presentation.screenLogic.AsciiArtComponent\n\n@Composable\nfun AsciiArtContent(\n    component: AsciiArtComponent\n) {\n    AutoContentBasedColors(component.uri)\n\n    val imagePicker = rememberImagePicker(onSuccess = component::setUri)\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    val transformations by remember(\n        component.uri,\n        component.gradient,\n        component.fontSize,\n        component.isInvertImage\n    ) {\n        derivedStateOf {\n            component.getAsciiTransformations()\n        }\n    }\n\n    ZoomModalSheet(\n        data = component.uri,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        },\n        transformations = transformations\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.ascii_art),\n                input = component.uri.takeIf { it != Uri.EMPTY },\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = component.onGoBack,\n        topAppBarPersistentActions = {\n            if (component.uri == Uri.EMPTY) {\n                TopAppBarEmoji()\n            }\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.uri != Uri.EMPTY\n            )\n        },\n        actions = {\n            ShareButton(\n                enabled = component.uri != Uri.EMPTY,\n                onShare = {\n                    component.convertToAsciiString {\n                        appContext.shareText(it)\n                    }\n                },\n            )\n        },\n        imagePreview = {\n            Box(\n                contentAlignment = Alignment.Center\n            ) {\n                var aspectRatio by remember {\n                    mutableFloatStateOf(1f)\n                }\n\n                Picture(\n                    model = component.uri,\n                    modifier = Modifier\n                        .container(MaterialTheme.shapes.medium)\n                        .aspectRatio(aspectRatio),\n                    onSuccess = {\n                        aspectRatio = it.result.image.toBitmap().safeAspectRatio\n                    },\n                    isLoadingFromDifferentPlace = component.isImageLoading,\n                    shape = MaterialTheme.shapes.medium,\n                    contentScale = ContentScale.FillBounds,\n                    transformations = transformations\n                )\n                if (component.isImageLoading) EnhancedLoadingIndicator()\n            }\n        },\n        controls = {\n            AsciiArtControls(component)\n        },\n        buttons = {\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uri == Uri.EMPTY,\n                onSecondaryButtonClick = pickImage,\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                primaryButtonIcon = Icons.Rounded.ContentCopy,\n                onPrimaryButtonClick = {\n                    component.convertToAsciiString(Clipboard::copy)\n                },\n                actions = {\n                    if (isPortrait) it()\n                }\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        canShowScreenData = component.uri != Uri.EMPTY,\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/ascii-art/src/main/java/com/t8rin/imagetoolbox/feature/ascii_art/presentation/components/AsciiArtControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ascii_art.presentation.components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Build\nimport androidx.compose.material.icons.rounded.InvertColors\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.filterItem.AsciiParamsSelector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.ascii_art.presentation.screenLogic.AsciiArtComponent\n\n@Composable\ninternal fun AsciiArtControls(\n    component: AsciiArtComponent\n) {\n    Column(\n        modifier = Modifier\n            .container(\n                shape = ShapeDefaults.large,\n                resultPadding = 0.dp\n            )\n    ) {\n        TitleItem(\n            text = stringResource(R.string.params),\n            icon = Icons.Rounded.Build,\n        )\n        Box(\n            modifier = Modifier\n                .padding(\n                    horizontal = 12.dp\n                )\n        ) {\n            AsciiParamsSelector(\n                value = component.asciiParams,\n                onValueChange = { params ->\n                    component.setGradient(params.gradient)\n                    component.setFontSize(params.fontSize)\n                },\n                itemShapes = {\n                    ShapeDefaults.byIndex(\n                        index = it,\n                        size = 3\n                    )\n                }\n            )\n        }\n        Spacer(Modifier.height(4.dp))\n        PreferenceRowSwitch(\n            title = stringResource(R.string.invert_colors),\n            subtitle = stringResource(R.string.invert_colors_ascii_sub),\n            startIcon = Icons.Rounded.InvertColors,\n            checked = component.isInvertImage,\n            onClick = {\n                component.toggleIsInvertImage()\n            },\n            shape = ShapeDefaults.bottom,\n            containerColor = MaterialTheme.colorScheme.surface,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 12.dp)\n        )\n        Spacer(Modifier.height(12.dp))\n    }\n}"
  },
  {
    "path": "feature/ascii-art/src/main/java/com/t8rin/imagetoolbox/feature/ascii_art/presentation/screenLogic/AsciiArtComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.ascii_art.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport coil3.transform.Transformation\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.AsciiParams\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiAsciiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiNegativeFilter\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.asFontType\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toCoil\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.ascii_art.domain.AsciiConverter\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\n\nclass AsciiArtComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val asciiConverter: AsciiConverter<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _uri: MutableState<Uri> = mutableStateOf(Uri.EMPTY)\n    val uri: Uri by _uri\n\n    private val _asciiParams: MutableState<AsciiParams> =\n        mutableStateOf(AsciiParams.Default.copy(isGrayscale = true))\n    val asciiParams: AsciiParams by _asciiParams\n\n    val gradient: String get() = asciiParams.gradient\n    val fontSize: Float get() = asciiParams.fontSize\n\n    private val _isInvertImage: MutableState<Boolean> = mutableStateOf(false)\n    val isInvertImage: Boolean by _isInvertImage\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n\n        settingsProvider.settingsState.onEach { settings ->\n            _asciiParams.update { it.copy(font = settings.font.asFontType()) }\n        }.launchIn(componentScope)\n    }\n\n    fun setUri(uri: Uri) {\n        _uri.update { uri }\n    }\n\n    fun convertToAsciiString(\n        onSuccess: (String) -> Unit\n    ) {\n        debouncedImageCalculation {\n            imageGetter.getImage(uri)?.let { image ->\n                onSuccess(\n                    asciiConverter.imageToAscii(\n                        image = image,\n                        fontSize = fontSize,\n                        gradient = gradient\n                    )\n                )\n            }\n        }\n    }\n\n    fun setGradient(gradient: String) {\n        _asciiParams.update {\n            it.copy(gradient = gradient)\n        }\n    }\n\n    fun setFontSize(fontSize: Float) {\n        _asciiParams.update {\n            it.copy(fontSize = fontSize)\n        }\n    }\n\n    fun toggleIsInvertImage() {\n        _isInvertImage.update { !it }\n    }\n\n    fun getAsciiTransformations(): List<Transformation> = buildList {\n        if (isInvertImage) add(UiNegativeFilter())\n        add(UiAsciiFilter(asciiParams))\n    }.map {\n        filterProvider.filterToTransformation(it).toCoil()\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n        ): AsciiArtComponent\n    }\n}"
  },
  {
    "path": "feature/audio-cover-extractor/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/audio-cover-extractor/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.audio_cover_extractor\""
  },
  {
    "path": "feature/audio-cover-extractor/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/audio-cover-extractor/src/main/java/com/t8rin/imagetoolbox/feature/audio_cover_extractor/data/AndroidAudioCoverRetriever.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.audio_cover_extractor.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.media.MediaMetadataRetriever\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.AudioCoverRetriever\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.model.AudioCoverResult\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidAudioCoverRetriever @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val shareProvider: ShareProvider,\n    private val imageGetter: ImageGetter<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n    resourceManager: ResourceManager\n) : AudioCoverRetriever,\n    DispatchersHolder by dispatchersHolder,\n    ResourceManager by resourceManager {\n\n    override suspend fun loadCover(\n        audioUri: String\n    ): AudioCoverResult = withContext(defaultDispatcher) {\n        val pictureData = runCatching {\n            MediaMetadataRetriever().run {\n                setDataSource(\n                    context,\n                    audioUri.toUri()\n                )\n\n                embeddedPicture ?: frameAtTime\n            }\n        }.onFailure {\n            return@withContext AudioCoverResult.Failure(it.message.orEmpty())\n        }.getOrNull()\n\n        ensureActive()\n\n        val coverUri = pictureData?.let {\n            imageGetter.getImage(\n                data = pictureData,\n                originalSize = true\n            )?.let { bitmap ->\n                val originalName = audioUri.toUri().filename(context)?.substringBeforeLast('.')\n                    ?: \"AUDIO_${System.currentTimeMillis()}\"\n\n                shareProvider.cacheData(\n                    writeData = {\n                        it.writeBytes(\n                            imageCompressor.compress(\n                                image = bitmap,\n                                imageFormat = ImageFormat.Png.Lossless,\n                                quality = Quality.Base()\n                            )\n                        )\n                    },\n                    filename = \"$originalName.png\"\n                )\n            }\n        }\n\n        if (coverUri.isNullOrEmpty()) {\n            AudioCoverResult.Failure(getString(R.string.no_image))\n        } else {\n            AudioCoverResult.Success(coverUri)\n        }\n    }\n\n    override suspend fun loadCover(\n        audioData: ByteArray\n    ): AudioCoverResult {\n        val audioUri = shareProvider.cacheData(\n            writeData = {\n                it.writeBytes(audioData)\n            },\n            filename = \"Audio_data_${System.currentTimeMillis()}.mp3\"\n        ) ?: return AudioCoverResult.Failure((getString(R.string.filename_is_not_set)))\n\n        return loadCover(\n            audioUri = audioUri\n        )\n    }\n\n\n}"
  },
  {
    "path": "feature/audio-cover-extractor/src/main/java/com/t8rin/imagetoolbox/feature/audio_cover_extractor/di/AudioCoverExtractorModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.audio_cover_extractor.di\n\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.data.AndroidAudioCoverRetriever\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.AudioCoverRetriever\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface AudioCoverExtractorModule {\n\n    @Binds\n    @Singleton\n    fun extractor(\n        impl: AndroidAudioCoverRetriever\n    ): AudioCoverRetriever\n\n}"
  },
  {
    "path": "feature/audio-cover-extractor/src/main/java/com/t8rin/imagetoolbox/feature/audio_cover_extractor/domain/AudioCoverRetriever.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain\n\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.model.AudioCoverResult\n\ninterface AudioCoverRetriever {\n\n    suspend fun loadCover(\n        audioUri: String\n    ): AudioCoverResult\n\n    suspend fun loadCover(\n        audioData: ByteArray\n    ): AudioCoverResult\n\n}"
  },
  {
    "path": "feature/audio-cover-extractor/src/main/java/com/t8rin/imagetoolbox/feature/audio_cover_extractor/domain/model/AudioCoverResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.model\n\nsealed interface AudioCoverResult {\n    data class Success(val coverUri: String) : AudioCoverResult\n    data class Failure(val message: String) : AudioCoverResult\n}"
  },
  {
    "path": "feature/audio-cover-extractor/src/main/java/com/t8rin/imagetoolbox/feature/audio_cover_extractor/ui/AudioCoverExtractorContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Album\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MusicAdd\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCircularProgressIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.FileNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.image.urisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.screenLogic.AudioCoverExtractorComponent\nimport kotlinx.coroutines.delay\n\n@Composable\nfun AudioCoverExtractorContent(\n    component: AudioCoverExtractorComponent\n) {\n    LaunchedEffect(component.initialUris, component.covers) {\n        delay(500)\n        if (component.initialUris != null && component.covers.isEmpty()) {\n            AppToastHost.showFailureToast(R.string.no_covers_found)\n        }\n    }\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val audioPicker = rememberFilePicker(\n        mimeType = MimeType.Audio,\n        onSuccess = component::updateCovers\n    )\n\n    AutoFilePicker(\n        onAutoPick = audioPicker::pickFile,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    val addAudioPicker = rememberFilePicker(\n        mimeType = MimeType.Audio,\n        onSuccess = component::addCovers\n    )\n\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val covers = component.covers\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            Text(\n                text = stringResource(R.string.audio_cover_extractor),\n                modifier = Modifier.marquee()\n            )\n        },\n        topAppBarPersistentActions = {\n            if (isPortrait) {\n                TopAppBarEmoji()\n            }\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n\n            ShareButton(\n                onShare = {\n                    component.performSharing(\n                        onComplete = AppToastHost::showConfetti\n                    )\n                },\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                },\n                enabled = !component.isSaving && covers.isNotEmpty()\n            )\n\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        imagePreview = {\n            val uris by remember(covers) {\n                derivedStateOf {\n                    covers.map { it.imageCoverUri ?: it.audioUri } + Uri.EMPTY\n                }\n            }\n\n            UrisPreview(\n                modifier = Modifier.urisPreview(),\n                uris = uris,\n                isPortrait = true,\n                onRemoveUri = component::removeCover,\n                onAddUris = addAudioPicker::pickFile,\n                errorContent = { index, width ->\n                    Box(\n                        modifier = Modifier\n                            .background(MaterialTheme.colorScheme.scrim.copy(0.5f))\n                            .fillMaxSize(),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        val cover = covers[index]\n\n                        val size = (width + 16.dp) / 3f\n\n                        Icon(\n                            imageVector = Icons.Rounded.Album,\n                            contentDescription = null,\n                            modifier = Modifier\n                                .size(size)\n                                .padding(8.dp),\n                            tint = MaterialTheme.colorScheme.onSurfaceVariant\n                        )\n                        AnimatedVisibility(\n                            visible = cover.isLoading,\n                            enter = fadeIn(),\n                            exit = fadeOut()\n                        ) {\n                            EnhancedCircularProgressIndicator(\n                                modifier = Modifier.size(size)\n                            )\n                        }\n                    }\n                },\n                showScrimForNonSuccess = false,\n                showTransparencyChecker = false,\n                filenameSource = { index ->\n                    covers[index].audioUri\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        showImagePreviewAsStickyHeader = false,\n        noDataControls = {\n            FileNotPickedWidget(\n                onPickFile = audioPicker::pickFile,\n                text = stringResource(R.string.pick_audio_to_start)\n            )\n        },\n        controls = {\n            ImageFormatSelector(\n                value = component.imageFormat,\n                quality = component.quality,\n                onValueChange = component::setImageFormat\n            )\n            if (component.imageFormat.canChangeCompressionValue) {\n                Spacer(Modifier.height(8.dp))\n            }\n            QualitySelector(\n                imageFormat = component.imageFormat,\n                quality = component.quality,\n                onQualityChange = component::setQuality\n            )\n        },\n        buttons = {\n            val save: (oneTimeSaveLocationUri: String?) -> Unit = { uri ->\n                component.save(\n                    oneTimeSaveLocationUri = uri\n                )\n            }\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n\n            val canSave by remember(covers) {\n                derivedStateOf {\n                    covers.none { cover -> cover.isLoading }\n                }\n            }\n\n            BottomButtonsBlock(\n                isNoData = covers.isEmpty(),\n                isPrimaryButtonEnabled = canSave,\n                onSecondaryButtonClick = audioPicker::pickFile,\n                isPrimaryButtonVisible = covers.isNotEmpty(),\n                secondaryButtonIcon = Icons.Rounded.MusicAdd,\n                secondaryButtonText = stringResource(R.string.pick_audio),\n                onPrimaryButtonClick = {\n                    save(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                },\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = save\n            )\n        },\n        canShowScreenData = covers.isNotEmpty()\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/audio-cover-extractor/src/main/java/com/t8rin/imagetoolbox/feature/audio_cover_extractor/ui/components/AudioWithCover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.components\n\nimport android.net.Uri\n\ndata class AudioWithCover(\n    val audioUri: Uri,\n    val imageCoverUri: Uri?,\n    val isLoading: Boolean\n)"
  },
  {
    "path": "feature/audio-cover-extractor/src/main/java/com/t8rin/imagetoolbox/feature/audio_cover_extractor/ui/screenLogic/AudioCoverExtractorComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.AudioCoverRetriever\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.model.AudioCoverResult\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.components.AudioWithCover\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\n\nclass AudioCoverExtractorComponent @AssistedInject constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val audioCoverRetriever: AudioCoverRetriever,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::updateCovers)\n        }\n    }\n\n    private val _covers: MutableState<List<AudioWithCover>> = mutableStateOf(emptyList())\n    val covers by _covers\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Png.Lossless)\n    val imageFormat by _imageFormat\n\n    private val _quality: MutableState<Quality> = mutableStateOf(Quality.Base())\n    val quality by _quality\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    private val mutex = Mutex()\n\n    private fun Bitmap.imageInfo() = ImageInfo(\n        width = width,\n        height = height,\n        quality = quality,\n        imageFormat = imageFormat\n    )\n\n    fun updateCovers(uris: List<Uri>) {\n        componentScope.launch {\n            val audioUris = uris.distinct()\n\n            mutex.withLock {\n                _covers.value = audioUris.map {\n                    AudioWithCover(\n                        audioUri = it,\n                        imageCoverUri = null,\n                        isLoading = true\n                    )\n                }\n            }\n\n            audioUris.forEach { audioUri ->\n                launch {\n                    val result = audioCoverRetriever.loadCover(audioUri.toString())\n\n                    val success = result as? AudioCoverResult.Success\n\n                    ensureActive()\n\n                    val newCover = AudioWithCover(\n                        audioUri = audioUri,\n                        imageCoverUri = success?.coverUri?.toUri(),\n                        isLoading = false\n                    )\n\n                    mutex.withLock {\n                        _covers.update { covers ->\n                            covers.toMutableList().apply {\n                                val index =\n                                    indexOfFirst { it.audioUri == audioUri }.takeIf { it >= 0 }\n                                        ?: return@update covers + newCover\n\n                                set(index, newCover)\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    fun addCovers(uris: List<Uri>) {\n        componentScope.launch {\n            val audioUris = uris.distinct()\n\n            mutex.withLock {\n                _covers.update { covers ->\n                    val newList = covers + audioUris.map {\n                        AudioWithCover(\n                            audioUri = it,\n                            imageCoverUri = null,\n                            isLoading = true\n                        )\n                    }\n\n                    newList.distinctBy { it.audioUri }\n                }\n            }\n\n            covers.filter { it.imageCoverUri == null }.forEach { (audioUri) ->\n                launch {\n                    val result = audioCoverRetriever.loadCover(audioUri.toString())\n\n                    val success = result as? AudioCoverResult.Success\n\n                    ensureActive()\n\n                    val newCover = AudioWithCover(\n                        audioUri = audioUri,\n                        imageCoverUri = success?.coverUri?.toUri(),\n                        isLoading = false\n                    )\n\n                    mutex.withLock {\n                        _covers.update { covers ->\n                            covers.toMutableList().apply {\n                                val index =\n                                    indexOfFirst { it.audioUri == audioUri }.takeIf { it >= 0 }\n                                        ?: return@update covers + newCover\n\n                                set(index, newCover)\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    fun performSharing(onComplete: () -> Unit) {\n        cacheImages { uris ->\n            componentScope.launch {\n                shareProvider.shareUris(uris.map { it.toString() })\n                onComplete()\n            }\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n\n            val targetUris = covers.mapNotNull { it.imageCoverUri?.toString() }\n\n            _done.update { 0 }\n            _left.update { targetUris.size }\n\n            val list = targetUris.mapNotNull { uri ->\n                imageGetter.getImage(data = uri)?.let { image ->\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = image.imageInfo()\n                    )?.toUri()\n                }.also {\n                    _done.value += 1\n                    updateProgress(\n                        done = done,\n                        total = left\n                    )\n                }\n            }\n\n            _isSaving.update { false }\n\n            onComplete(list)\n        }\n    }\n\n    fun removeCover(coverUri: Uri) {\n        _covers.update { list ->\n            list.filter {\n                it.imageCoverUri != coverUri && it.audioUri != coverUri\n            }\n        }\n    }\n\n    fun save(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            val results = mutableListOf<SaveResult>()\n            val coverUris = covers.mapNotNull { it.imageCoverUri?.toString() }\n            _done.value = 0\n            _left.value = coverUris.size\n\n            coverUris.forEach { coverUri ->\n                runSuspendCatching {\n                    imageGetter.getImage(data = coverUri)\n                }.getOrNull()?.let { bitmap ->\n                    results.add(\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = bitmap.imageInfo(),\n                                metadata = null,\n                                originalUri = coverUri,\n                                sequenceNumber = _done.value + 1,\n                                data = imageCompressor.compressAndTransform(\n                                    image = bitmap,\n                                    imageInfo = bitmap.imageInfo()\n                                )\n                            ),\n                            keepOriginalMetadata = false,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    )\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun setQuality(quality: Quality) {\n        _quality.update { quality }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n    }\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): AudioCoverExtractorComponent\n    }\n}"
  },
  {
    "path": "feature/base64-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/base64-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.base64_tools\""
  },
  {
    "path": "feature/base64-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/base64-tools/src/main/java/com/t8rin/imagetoolbox/feature/base64_tools/data/AndroidBase64Converter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.base64_tools.data\n\nimport android.graphics.Bitmap\nimport android.util.Base64\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.feature.base64_tools.domain.Base64Converter\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidBase64Converter @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val shareProvider: ShareProvider,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : Base64Converter, DispatchersHolder by dispatchersHolder {\n\n    override suspend fun decode(\n        base64: String\n    ): String? = withContext(ioDispatcher) {\n        val decoded = runCatching {\n            Base64.decode(base64, Base64.DEFAULT or Base64.NO_WRAP)\n        }.getOrNull() ?: return@withContext null\n\n        imageGetter.getImage(decoded)?.let { bitmap ->\n            shareProvider.cacheData(\n                writeData = {\n                    it.writeBytes(\n                        imageCompressor.compress(\n                            image = bitmap,\n                            imageFormat = ImageFormat.Png.Lossless,\n                            quality = Quality.Base()\n                        )\n                    )\n                },\n                filename = \"Base64_decoded_${System.currentTimeMillis()}.png\"\n            )\n        }\n    }\n\n    override suspend fun encode(\n        uri: String\n    ): String = withContext(ioDispatcher) {\n        Base64.encodeToString(fileController.readBytes(uri), Base64.DEFAULT or Base64.NO_WRAP)\n    }\n\n}"
  },
  {
    "path": "feature/base64-tools/src/main/java/com/t8rin/imagetoolbox/feature/base64_tools/di/Base64ToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.base64_tools.di\n\nimport com.t8rin.imagetoolbox.feature.base64_tools.data.AndroidBase64Converter\nimport com.t8rin.imagetoolbox.feature.base64_tools.domain.Base64Converter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface Base64ToolsModule {\n\n    @Binds\n    @Singleton\n    fun provideConverter(\n        impl: AndroidBase64Converter\n    ): Base64Converter\n\n}"
  },
  {
    "path": "feature/base64-tools/src/main/java/com/t8rin/imagetoolbox/feature/base64_tools/domain/Base64Converter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.base64_tools.domain\n\ninterface Base64Converter {\n\n    /**\n     * @param base64 - string to decode to uri\n     * @return uri\n     **/\n    suspend fun decode(base64: String): String?\n\n    /**\n     * @param uri - uri to decode\n     * @return base64\n     **/\n    suspend fun encode(uri: String): String\n\n}"
  },
  {
    "path": "feature/base64-tools/src/main/java/com/t8rin/imagetoolbox/feature/base64_tools/presentation/Base64ToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.base64_tools.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.takeUnless\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.base64_tools.presentation.components.Base64ToolsTiles\nimport com.t8rin.imagetoolbox.feature.base64_tools.presentation.screenLogic.Base64ToolsComponent\n\n@Composable\nfun Base64ToolsContent(\n    component: Base64ToolsComponent\n) {\n    AutoContentBasedColors(component.uri)\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val imagePicker = rememberImagePicker(onSuccess = component::setUri)\n    val pickImage = imagePicker::pickImage\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.base_64_tools),\n                input = component.uri,\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = component.onGoBack,\n        topAppBarPersistentActions = {\n            if (component.uri == null) {\n                TopAppBarEmoji()\n            }\n            var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.uri != null\n            )\n            ZoomModalSheet(\n                data = component.base64String,\n                visible = showZoomSheet,\n                onDismiss = {\n                    showZoomSheet = false\n                }\n            )\n        },\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.uri != null,\n                onShare = component::shareBitmap,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheCurrentImage { uri ->\n                        editSheetData = listOf(uri)\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = { editSheetData = emptyList() },\n                onNavigate = component.onNavigate\n            )\n        },\n        imagePreview = {\n            AnimatedContent(component.base64String.isEmpty()) { isEmpty ->\n                if (isEmpty) {\n                    ImageNotPickedWidget(\n                        onPickImage = pickImage,\n                        modifier = Modifier.padding(20.dp),\n                        text = stringResource(R.string.pick_image_or_base64),\n                        containerColor = MaterialTheme\n                            .colorScheme\n                            .surfaceContainerLowest\n                            .takeUnless(isPortrait)\n                    )\n                } else {\n                    Box(\n                        modifier = Modifier\n                            .container()\n                            .padding(4.dp)\n                            .animateContentSizeNoClip(\n                                alignment = Alignment.Center\n                            ),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        var aspectRatio by remember {\n                            mutableFloatStateOf(1f)\n                        }\n                        Picture(\n                            model = component.base64String,\n                            contentScale = ContentScale.FillBounds,\n                            modifier = Modifier.aspectRatio(aspectRatio),\n                            onSuccess = {\n                                aspectRatio = it.result.image.toBitmap().safeAspectRatio\n                            },\n                            error = {\n                                Icon(\n                                    imageVector = Icons.Rounded.BrokenImageAlt,\n                                    contentDescription = null,\n                                    modifier = Modifier.background(MaterialTheme.colorScheme.surface)\n                                )\n                            },\n                            shape = MaterialTheme.shapes.medium,\n                            isLoadingFromDifferentPlace = component.isImageLoading\n                        )\n                    }\n                }\n            }\n        },\n        showImagePreviewAsStickyHeader = component.base64String.isNotEmpty(),\n        controls = {\n            if (isPortrait) Spacer(Modifier.height(8.dp))\n            Base64ToolsTiles(component)\n            Spacer(Modifier.height(8.dp))\n            if (component.uri != null) {\n                if (component.imageFormat.canChangeCompressionValue) {\n                    Spacer(Modifier.height(8.dp))\n                }\n                QualitySelector(\n                    imageFormat = component.imageFormat,\n                    quality = component.quality,\n                    onQualityChange = component::setQuality\n                )\n                Spacer(Modifier.height(8.dp))\n                ImageFormatSelector(\n                    value = component.imageFormat,\n                    quality = component.quality,\n                    onValueChange = component::setImageFormat\n                )\n            } else {\n                InfoContainer(\n                    modifier = Modifier.padding(8.dp),\n                    text = stringResource(R.string.base_64_tips),\n                )\n            }\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.base64String.isEmpty() && isPortrait,\n                isPrimaryButtonVisible = isPortrait || component.base64String.isNotEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        canShowScreenData = true\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/base64-tools/src/main/java/com/t8rin/imagetoolbox/feature/base64_tools/presentation/components/Base64ToolsTiles.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.base64_tools.presentation.components\n\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FileOpen\nimport androidx.compose.material.icons.outlined.Save\nimport androidx.compose.material.icons.outlined.Share\nimport androidx.compose.material.icons.rounded.ContentPaste\nimport androidx.compose.material.icons.rounded.CopyAll\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.PlainTooltip\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TooltipAnchorPosition\nimport androidx.compose.material3.TooltipBox\nimport androidx.compose.material3.TooltipDefaults\nimport androidx.compose.material3.rememberTooltipState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.buildAnnotatedString\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.utils.isBase64\nimport com.t8rin.imagetoolbox.core.domain.utils.trimToBase64\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Base64\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.base64_tools.presentation.screenLogic.Base64ToolsComponent\n\n@Composable\ninternal fun Base64ToolsTiles(component: Base64ToolsComponent) {\n    val pasteTile: @Composable RowScope.(shape: Shape) -> Unit = { shape ->\n        Tile(\n            onClick = {\n                Clipboard.getText { raw ->\n                    val text = raw.trimToBase64()\n\n                    if (text.isBase64()) {\n                        component.setBase64(text)\n                    } else {\n                        AppToastHost.showToast(\n                            message = getString(R.string.not_a_valid_base_64),\n                            icon = Icons.Rounded.Base64\n                        )\n                    }\n                }\n            },\n            shape = shape,\n            icon = Icons.Rounded.ContentPaste,\n            textRes = R.string.paste_base_64,\n            isButton = component.uri != null\n        )\n    }\n\n    val importTile: @Composable RowScope.(shape: Shape) -> Unit = { shape ->\n        val pickLauncher = rememberLauncherForActivityResult(\n            ActivityResultContracts.OpenDocument()\n        ) { uri ->\n            uri?.let {\n                component.setBase64FromUri(\n                    uri = uri,\n                    onFailure = {\n                        AppToastHost.showToast(\n                            message = getString(R.string.not_a_valid_base_64),\n                            icon = Icons.Rounded.Base64\n                        )\n                    }\n                )\n            }\n        }\n\n        Tile(\n            onClick = {\n                pickLauncher.launch(arrayOf(\"text/plain\"))\n            },\n            shape = shape,\n            icon = Icons.Outlined.FileOpen,\n            textRes = R.string.import_base_64,\n            isButton = component.uri != null\n        )\n    }\n\n    AnimatedContent(component.uri == null) { isNoUri ->\n        if (isNoUri) {\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .height(IntrinsicSize.Max),\n                horizontalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                pasteTile(ShapeDefaults.start)\n                importTile(ShapeDefaults.end)\n            }\n        } else {\n            Column(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                modifier = Modifier\n                    .container(\n                        shape = ShapeDefaults.extremeLarge,\n                        resultPadding = 0.dp\n                    )\n                    .padding(\n                        horizontal = 12.dp\n                    )\n                    .padding(\n                        top = 4.dp,\n                        bottom = 8.dp\n                    )\n            ) {\n                Text(\n                    text = stringResource(R.string.base_64_actions),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium,\n                    modifier = Modifier.padding(8.dp)\n                )\n                Row(\n                    horizontalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    pasteTile(ShapeDefaults.circle)\n                    importTile(ShapeDefaults.circle)\n\n                    Tile(\n                        onClick = {\n                            val text = buildAnnotatedString {\n                                append(component.base64String)\n                            }\n                            if (component.base64String.isBase64()) {\n                                Clipboard.copy(text)\n                            } else {\n                                AppToastHost.showToast(\n                                    message = getString(R.string.copy_not_a_valid_base_64),\n                                    icon = Icons.Rounded.Base64\n                                )\n                            }\n                        },\n                        icon = Icons.Rounded.CopyAll,\n                        textRes = R.string.copy_base_64\n                    )\n\n                    Tile(\n                        onClick = component::shareText,\n                        icon = Icons.Outlined.Share,\n                        textRes = R.string.share_base_64\n                    )\n\n                    val saveLauncher = rememberFileCreator(\n                        mimeType = MimeType.Txt,\n                        onSuccess = component::saveContentToTxt\n                    )\n\n                    Tile(\n                        onClick = {\n                            saveLauncher.make(component.generateTextFilename())\n                        },\n                        icon = Icons.Outlined.Save,\n                        textRes = R.string.save_base_64\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun RowScope.Tile(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.circle,\n    icon: ImageVector,\n    textRes: Int,\n    isButton: Boolean = true\n) {\n    if (isButton) {\n        val tooltipState = rememberTooltipState()\n        Box(\n            modifier = Modifier.weight(1f)\n        ) {\n            TooltipBox(\n                positionProvider = TooltipDefaults.rememberTooltipPositionProvider(\n                    TooltipAnchorPosition.Above\n                ),\n                tooltip = {\n                    PlainTooltip {\n                        Text(stringResource(id = textRes))\n                    }\n                },\n                state = tooltipState\n            ) {\n                EnhancedIconButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(0.5f),\n                    contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                    onClick = onClick,\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    Icon(\n                        imageVector = icon,\n                        contentDescription = null\n                    )\n                }\n            }\n        }\n    } else {\n        PreferenceRow(\n            title = stringResource(id = textRes),\n            onClick = onClick,\n            shape = shape,\n            titleFontStyle = PreferenceItemDefaults.TitleFontStyleCenteredSmall.copy(\n                fontSize = 13.sp\n            ),\n            startIcon = icon,\n            drawStartIconContainer = false,\n            modifier = Modifier\n                .weight(1f)\n                .fillMaxHeight(),\n            color = MaterialTheme.colorScheme.secondaryContainer.copy(0.5f),\n            contentColor = MaterialTheme.colorScheme.onSecondaryContainer\n        )\n    }\n}"
  },
  {
    "path": "feature/base64-tools/src/main/java/com/t8rin/imagetoolbox/feature/base64_tools/presentation/screenLogic/Base64ToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.base64_tools.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.isBase64\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.domain.utils.trimToBase64\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.base64_tools.domain.Base64Converter\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass Base64ToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    private val converter: Base64Converter,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _imageFormat = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    private val _quality = mutableStateOf<Quality>(Quality.Base())\n    val quality by _quality\n\n    private val _uri = mutableStateOf<Uri?>(null)\n    val uri by _uri\n\n    private val _base64String = mutableStateOf(\"\")\n    val base64String by _base64String\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    fun setUri(uri: Uri) {\n        _uri.value = uri\n\n        updateBase64()\n    }\n\n    private fun updateBase64() {\n        debouncedImageCalculation {\n            uri?.let { imageGetter.getImage(it) }?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        width = image.width,\n                        height = image.height,\n                        imageFormat = imageFormat,\n                        quality = quality,\n                        originalUri = uri.toString()\n                    )\n                )?.let {\n                    _base64String.value = converter.encode(it)\n                }\n            }\n        }\n    }\n\n    fun setBase64(base64: String) {\n        _base64String.value = base64\n        debouncedImageCalculation {\n            _uri.value = converter.decode(base64)?.toUri()\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        updateBase64()\n    }\n\n    fun setQuality(quality: Quality) {\n        _quality.update { quality }\n        updateBase64()\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n    fun shareBitmap() {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            uri?.let { imageGetter.getImage(it) }?.let { image ->\n                shareProvider.shareImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        width = image.width,\n                        height = image.height,\n                        imageFormat = imageFormat,\n                        quality = quality,\n                        originalUri = uri.toString()\n                    ),\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            uri?.let { imageGetter.getImage(it) }?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        width = image.width,\n                        height = image.height,\n                        imageFormat = imageFormat,\n                        quality = quality,\n                        originalUri = uri.toString()\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.update { false }\n    }\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            uri?.let { imageGetter.getImage(it) }?.let { image ->\n                val imageInfo = ImageInfo(\n                    width = image.width,\n                    height = image.height,\n                    imageFormat = imageFormat,\n                    quality = quality,\n                    originalUri = uri.toString()\n                )\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = imageInfo,\n                            metadata = null,\n                            originalUri = uri.toString(),\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = image,\n                                imageInfo = imageInfo.copy(\n                                    originalUri = uri.toString()\n                                )\n                            )\n                        ),\n                        keepOriginalMetadata = true,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun saveContentToTxt(uri: Uri) {\n        base64String.takeIf { it.isNotEmpty() }?.let { data ->\n            componentScope.launch {\n                fileController.writeBytes(\n                    uri = uri.toString(),\n                    block = {\n                        it.writeBytes(data.encodeToByteArray())\n                    }\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n        }\n    }\n\n    fun generateTextFilename(): String = \"Base64_${timestamp()}.txt\"\n\n    fun shareText() {\n        base64String.takeIf { it.isNotEmpty() }?.let { data ->\n            componentScope.launch {\n                shareProvider.shareData(\n                    writeData = {\n                        it.writeBytes(data.encodeToByteArray())\n                    },\n                    filename = generateTextFilename()\n                )\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun setBase64FromUri(\n        uri: Uri,\n        onFailure: () -> Unit\n    ) {\n        componentScope.launch {\n            val text = fileController.readBytes(uri.toString()).decodeToString().trimToBase64()\n            if (text.isBase64()) {\n                setBase64(text)\n            } else {\n                onFailure()\n            }\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): Base64ToolsComponent\n    }\n\n}"
  },
  {
    "path": "feature/checksum-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/checksum-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.checksum_tools\""
  },
  {
    "path": "feature/checksum-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/data/AndroidChecksumManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.data\n\nimport android.content.Context\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.saving.io.StringReadable\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriReadable\nimport com.t8rin.imagetoolbox.core.data.utils.computeFromReadable\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Readable\nimport com.t8rin.imagetoolbox.feature.checksum_tools.domain.ChecksumManager\nimport com.t8rin.imagetoolbox.feature.checksum_tools.domain.ChecksumSource\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidChecksumManager @Inject constructor(\n    @ApplicationContext private val context: Context,\n    dispatchersHolder: DispatchersHolder\n) : ChecksumManager, DispatchersHolder by dispatchersHolder {\n\n    override suspend fun calculateChecksum(\n        type: HashingType,\n        source: ChecksumSource\n    ): String = withContext(defaultDispatcher) {\n        runCatching {\n            type.computeFromReadable(source.toReadable())\n        }.getOrDefault(\"\")\n    }\n\n    override suspend fun compareChecksum(\n        checksum: String,\n        type: HashingType,\n        source: ChecksumSource\n    ): Boolean = coroutineScope {\n        calculateChecksum(type, source) == checksum\n    }\n\n    private fun ChecksumSource.toReadable(): Readable = when (this) {\n        is ChecksumSource.Text -> StringReadable(data)\n        is ChecksumSource.Uri -> UriReadable(data.toUri(), context)\n    }\n\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/di/ChecksumToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.di\n\nimport com.t8rin.imagetoolbox.feature.checksum_tools.data.AndroidChecksumManager\nimport com.t8rin.imagetoolbox.feature.checksum_tools.domain.ChecksumManager\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ChecksumToolsModule {\n\n    @Binds\n    @Singleton\n    fun checksumManager(\n        impl: AndroidChecksumManager\n    ): ChecksumManager\n\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/domain/ChecksumManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\n\ninterface ChecksumManager {\n\n    suspend fun calculateChecksum(\n        type: HashingType,\n        source: ChecksumSource\n    ): String\n\n    suspend fun compareChecksum(\n        checksum: String,\n        type: HashingType,\n        source: ChecksumSource\n    ): Boolean\n\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/domain/ChecksumSource.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.domain\n\nsealed class ChecksumSource(\n    val data: String\n) {\n\n    class Uri(\n        data: String\n    ) : ChecksumSource(data)\n\n    class Text(\n        data: String\n    ) : ChecksumSource(data)\n\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/ChecksumToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Tag\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumPage\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumToolsTabs\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages.CalculateFromTextPage\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages.CalculateFromUriPage\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages.CompareWithUriPage\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages.CompareWithUrisPage\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent\n\n@Composable\nfun ChecksumToolsContent(\n    component: ChecksumToolsComponent\n) {\n    val pagerState = rememberPagerState { ChecksumPage.ENTRIES_COUNT }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        onGoBack = component.onGoBack,\n        title = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                modifier = Modifier.marquee()\n            ) {\n                Text(\n                    text = stringResource(R.string.checksum_tools)\n                )\n                EnhancedBadge(\n                    content = {\n                        Text(\n                            text = HashingType.entries.size.toString()\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.tertiary,\n                    contentColor = MaterialTheme.colorScheme.onTertiary,\n                    modifier = Modifier\n                        .padding(horizontal = 2.dp)\n                        .padding(bottom = 12.dp)\n                        .scaleOnTap {\n                            AppToastHost.showConfetti()\n                        }\n                )\n            }\n        },\n        actions = {},\n        topAppBarPersistentActions = {\n            TopAppBarEmoji()\n        },\n        imagePreview = {},\n        placeImagePreview = false,\n        addHorizontalCutoutPaddingIfNoPreview = false,\n        showImagePreviewAsStickyHeader = false,\n        canShowScreenData = true,\n        underTopAppBarContent = {\n            ChecksumToolsTabs(pagerState)\n        },\n        contentPadding = 0.dp,\n        controls = {\n            val insets = WindowInsets.navigationBars.union(\n                WindowInsets.displayCutout\n            ).only(\n                WindowInsetsSides.Horizontal\n            ).asPaddingValues()\n\n            DataSelector(\n                modifier = Modifier\n                    .padding(top = 20.dp)\n                    .padding(horizontal = 20.dp)\n                    .padding(insets),\n                value = component.hashingType,\n                containerColor = Color.Unspecified,\n                selectedItemColor = MaterialTheme.colorScheme.secondary,\n                onValueChange = component::updateChecksumType,\n                entries = HashingType.entries,\n                title = stringResource(R.string.algorithms),\n                titleIcon = Icons.Rounded.Tag,\n                itemContentText = {\n                    it.name\n                }\n            )\n            val direction = LocalLayoutDirection.current\n            HorizontalPager(\n                state = pagerState,\n                beyondViewportPageCount = 3,\n                contentPadding = insets,\n                pageSpacing = remember(insets, direction) {\n                    20.dp + insets.calculateStartPadding(direction) + insets.calculateEndPadding(\n                        direction\n                    )\n                },\n                verticalAlignment = Alignment.Top\n            ) { pageIndex ->\n                Column(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(20.dp),\n                    verticalArrangement = Arrangement.spacedBy(8.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    when (pageIndex) {\n                        ChecksumPage.CalculateFromUri.INDEX -> {\n                            CalculateFromUriPage(\n                                component = component\n                            )\n                        }\n\n                        ChecksumPage.CalculateFromText.INDEX -> {\n                            CalculateFromTextPage(\n                                component = component\n                            )\n                        }\n\n                        ChecksumPage.CompareWithUri.INDEX -> {\n                            CompareWithUriPage(\n                                component = component\n                            )\n                        }\n\n                        ChecksumPage.CompareWithUris.INDEX -> {\n                            CompareWithUrisPage(\n                                component = component\n                            )\n                        }\n                    }\n                }\n            }\n        },\n        buttons = {}\n    )\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/ChecksumEnterField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Cancel\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\n\n@Composable\ninternal fun ChecksumEnterField(\n    value: String,\n    onValueChange: (String) -> Unit,\n    label: String = stringResource(R.string.checksum_to_compare)\n) {\n    RoundedTextField(\n        modifier = Modifier\n            .container(\n                shape = MaterialTheme.shapes.large,\n                resultPadding = 8.dp\n            ),\n        keyboardOptions = KeyboardOptions(\n            keyboardType = KeyboardType.Text\n        ),\n        onValueChange = onValueChange,\n        endIcon = {\n            AnimatedVisibility(value.isNotBlank()) {\n                EnhancedIconButton(\n                    onClick = {\n                        onValueChange(\"\")\n                    },\n                    modifier = Modifier.padding(end = 4.dp)\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Cancel,\n                        contentDescription = stringResource(R.string.cancel)\n                    )\n                }\n            }\n        },\n        singleLine = false,\n        value = value,\n        label = label\n    )\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/ChecksumPage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components\n\nimport android.net.Uri\n\nsealed interface ChecksumPage {\n\n    data class CalculateFromUri(\n        val uri: Uri?,\n        val checksum: String\n    ) : ChecksumPage {\n        companion object {\n            const val INDEX = 0\n            val Empty: CalculateFromUri by lazy {\n                CalculateFromUri(\n                    uri = null,\n                    checksum = \"\"\n                )\n            }\n        }\n    }\n\n    data class CalculateFromText(\n        val text: String,\n        val checksum: String\n    ) : ChecksumPage {\n        companion object {\n            const val INDEX = 1\n            val Empty: CalculateFromText by lazy {\n                CalculateFromText(\n                    text = \"\",\n                    checksum = \"\"\n                )\n            }\n        }\n    }\n\n    data class CompareWithUri(\n        val uri: Uri?,\n        val checksum: String,\n        val targetChecksum: String,\n        val isCorrect: Boolean\n    ) : ChecksumPage {\n        companion object {\n            const val INDEX = 2\n            val Empty: CompareWithUri by lazy {\n                CompareWithUri(\n                    uri = null,\n                    checksum = \"\",\n                    targetChecksum = \"\",\n                    isCorrect = false\n                )\n            }\n        }\n    }\n\n    data class CompareWithUris(\n        val uris: List<UriWithHash>,\n        val targetChecksum: String\n    ) : ChecksumPage {\n        companion object {\n            const val INDEX = 3\n            val Empty: CompareWithUris by lazy {\n                CompareWithUris(\n                    uris = emptyList(),\n                    targetChecksum = \"\"\n                )\n            }\n        }\n    }\n\n    companion object {\n        const val ENTRIES_COUNT: Int = 4\n    }\n\n}\n\ndata class UriWithHash(\n    val uri: Uri,\n    val checksum: String\n)"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/ChecksumPreviewField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ContentCopy\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextFieldColors\n\n@Composable\ninternal fun ChecksumPreviewField(\n    value: String,\n    onCopyText: (String) -> Unit,\n    label: String = stringResource(R.string.source_checksum)\n) {\n    RoundedTextField(\n        modifier = Modifier\n            .container(\n                shape = MaterialTheme.shapes.large,\n                resultPadding = 8.dp,\n                color = MaterialTheme.colorScheme.tertiaryContainer.copy(\n                    0.2f\n                )\n            ),\n        keyboardOptions = KeyboardOptions(\n            keyboardType = KeyboardType.Text\n        ),\n        onValueChange = {},\n        singleLine = false,\n        readOnly = true,\n        value = value,\n        endIcon = {\n            AnimatedVisibility(value.isNotBlank()) {\n                EnhancedIconButton(\n                    onClick = {\n                        onCopyText(value)\n                    },\n                    modifier = Modifier.padding(end = 4.dp)\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.ContentCopy,\n                        contentDescription = stringResource(\n                            R.string.copy\n                        )\n                    )\n                }\n            }\n        },\n        colors = RoundedTextFieldColors(\n            isError = false,\n            containerColor = MaterialTheme.colorScheme.tertiaryContainer.copy(0.3f),\n            focusedIndicatorColor = MaterialTheme.colorScheme.tertiary,\n            unfocusedIndicatorColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(\n                0.5f\n            )\n        ),\n        label = label\n    )\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/ChecksumResultCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CheckCircle\nimport androidx.compose.material.icons.outlined.WarningAmber\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.tooling.preview.Preview\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.Green\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.Red\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContentColor\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\ninternal fun ChecksumResultCard(\n    isCorrect: Boolean\n) {\n    val containerColor = animateColorAsState(\n        when {\n            isCorrect -> Green\n            else -> Red\n        }\n    ).value.blend(\n        color = Color.Black,\n        fraction = 0.25f\n    )\n\n    val contentColor = containerColor.inverse(\n        fraction = { 1f },\n        darkMode = true\n    )\n\n    CompositionLocalProvider(\n        LocalIconShapeContentColor provides contentColor,\n        LocalIconShapeContainerColor provides containerColor.blend(\n            color = Color.Black,\n            fraction = 0.15f\n        )\n    ) {\n        PreferenceItem(\n            title = if (isCorrect) {\n                stringResource(R.string.match)\n            } else {\n                stringResource(R.string.difference)\n            },\n            subtitle = if (isCorrect) {\n                stringResource(R.string.match_sub)\n            } else {\n                stringResource(R.string.difference_sub)\n            },\n            startIcon = if (isCorrect) {\n                Icons.Outlined.CheckCircle\n            } else {\n                Icons.Outlined.WarningAmber\n            },\n            contentColor = contentColor,\n            containerColor = containerColor,\n            overrideIconShapeContentColor = true,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = null\n        )\n    }\n}\n\n@Composable\n@Preview\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    CompositionLocalProvider(\n        LocalSettingsState provides LocalSettingsState.current.copy(\n            drawContainerShadows = false\n        )\n    ) {\n        ChecksumResultCard(false)\n    }\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/ChecksumToolsTabs.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.statusBars\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.pager.PagerState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Calculate\nimport androidx.compose.material.icons.rounded.TextFields\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.PrimaryScrollableTabRow\nimport androidx.compose.material3.PrimaryTabRow\nimport androidx.compose.material3.Tab\nimport androidx.compose.material3.TabIndicatorScope\nimport androidx.compose.material3.TabRowDefaults\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.CompareArrows\nimport com.t8rin.imagetoolbox.core.resources.icons.FolderMatch\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun ChecksumToolsTabs(\n    pagerState: PagerState\n) {\n    val scope = rememberCoroutineScope()\n\n    val haptics = LocalHapticFeedback.current\n    val topAppBarColor = MaterialTheme.colorScheme.surfaceContainer\n    Row(\n        modifier = Modifier\n            .fillMaxWidth()\n            .drawHorizontalStroke()\n            .background(topAppBarColor)\n            .drawWithContent {\n                drawContent()\n                drawRect(\n                    color = topAppBarColor,\n                    size = size.copy(height = 6.dp.toPx()),\n                    topLeft = Offset(\n                        x = 0f,\n                        y = -4.dp.toPx()\n                    )\n                )\n            },\n        horizontalArrangement = Arrangement.Center\n    ) {\n        val modifier = Modifier.windowInsetsPadding(\n            WindowInsets.statusBars.union(\n                WindowInsets.displayCutout\n            ).only(\n                WindowInsetsSides.Horizontal\n            )\n        )\n\n        val indicator: @Composable TabIndicatorScope.() -> Unit = {\n            TabRowDefaults.PrimaryIndicator(\n                modifier = Modifier.tabIndicatorOffset(\n                    selectedTabIndex = pagerState.currentPage,\n                    matchContentSize = true\n                ),\n                width = Dp.Unspecified,\n                height = 4.dp,\n                shape = AutoCornersShape(\n                    topStart = 100f,\n                    topEnd = 100f\n                )\n            )\n        }\n\n        val tabs: @Composable () -> Unit = {\n            repeat(pagerState.pageCount) { index ->\n                val selected = pagerState.currentPage == index\n                val color by animateColorAsState(\n                    if (selected) {\n                        MaterialTheme.colorScheme.primary\n                    } else MaterialTheme.colorScheme.onSurface\n                )\n                val (icon, textRes) = when (index) {\n                    0 -> Icons.Rounded.Calculate to R.string.calculate\n                    1 -> Icons.Rounded.TextFields to R.string.text_hash\n                    2 -> Icons.Rounded.CompareArrows to R.string.compare\n                    3 -> Icons.Rounded.FolderMatch to R.string.batch_compare\n                    else -> throw IllegalArgumentException(\"Not presented index $index of ChecksumPage\")\n                }\n\n                val interactionSource = remember { MutableInteractionSource() }\n                val shape = shapeByInteraction(\n                    shape = AutoCornersShape(42.dp),\n                    pressedShape = ShapeDefaults.default,\n                    interactionSource = interactionSource\n                )\n\n                Tab(\n                    unselectedContentColor = MaterialTheme.colorScheme.onSurface,\n                    interactionSource = interactionSource,\n                    modifier = Modifier\n                        .padding(vertical = 8.dp)\n                        .clip(shape),\n                    selected = selected,\n                    onClick = {\n                        haptics.longPress()\n                        scope.launch {\n                            pagerState.animateScrollToPage(index)\n                        }\n                    },\n                    icon = {\n                        Icon(\n                            imageVector = icon,\n                            contentDescription = null,\n                            tint = color\n                        )\n                    },\n                    text = {\n                        Text(\n                            text = stringResource(textRes),\n                            color = color\n                        )\n                    }\n                )\n            }\n        }\n\n        var disableScroll by remember { mutableStateOf(false) }\n\n        if (disableScroll) {\n            PrimaryTabRow(\n                modifier = modifier.padding(horizontal = 8.dp),\n                divider = {},\n                containerColor = Color.Transparent,\n                selectedTabIndex = pagerState.currentPage,\n                indicator = indicator,\n                tabs = tabs\n            )\n        } else {\n            val screenWidth = LocalScreenSize.current.widthPx\n            PrimaryScrollableTabRow(\n                modifier = modifier.layout { measurable, constraints ->\n                    val placeable = measurable.measure(constraints)\n                    if (!disableScroll) {\n                        disableScroll = screenWidth > placeable.measuredWidth\n                    }\n                    layout(placeable.measuredWidth, placeable.measuredHeight) {\n                        placeable.placeWithLayer(x = 0, y = 0)\n                    }\n                },\n                edgePadding = 8.dp,\n                divider = {},\n                containerColor = Color.Transparent,\n                selectedTabIndex = pagerState.currentPage,\n                indicator = indicator,\n                tabs = tabs\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/UriWithHashItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FilePresent\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\n\n@Composable\ninternal fun UriWithHashItem(\n    uriWithHash: UriWithHash,\n    onCopyText: (String) -> Unit\n) {\n    val (uri, checksum) = uriWithHash\n\n    val filename = rememberFilename(uri) ?: stringResource(R.string.filename)\n\n    val fileSize = rememberHumanFileSize(uri)\n\n    Column(\n        modifier = Modifier.fillMaxWidth(),\n        verticalArrangement = Arrangement.spacedBy(8.dp),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        PreferenceItemOverload(\n            title = filename,\n            subtitle = fileSize,\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.FilePresent,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .size(48.dp)\n                        .clip(CloverShape)\n                        .background(\n                            MaterialTheme.colorScheme.secondaryContainer.copy(\n                                0.5f\n                            )\n                        )\n                        .padding(8.dp)\n                )\n            },\n            modifier = Modifier.fillMaxWidth(),\n            drawStartIconContainer = false\n        )\n\n        ChecksumPreviewField(\n            value = checksum,\n            onCopyText = onCopyText\n        )\n    }\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/pages/CalculateFromTextPage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumEnterField\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumPreviewField\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent\n\n@Composable\ninternal fun ColumnScope.CalculateFromTextPage(\n    component: ChecksumToolsComponent\n) {\n    val page = component.calculateFromTextPage\n\n    var text by remember {\n        mutableStateOf(page.text)\n    }\n\n    ChecksumEnterField(\n        value = text,\n        onValueChange = {\n            text = it\n            component.setText(it)\n        },\n        label = stringResource(R.string.text)\n    )\n\n    ChecksumPreviewField(\n        value = page.checksum,\n        onCopyText = Clipboard::copy,\n        label = stringResource(R.string.checksum)\n    )\n\n    AnimatedVisibility(page.checksum.isEmpty()) {\n        InfoContainer(\n            text = stringResource(R.string.enter_text_to_checksum),\n            modifier = Modifier.padding(8.dp),\n        )\n    }\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/pages/CalculateFromUriPage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FileSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumPreviewField\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent\n\n@Composable\ninternal fun ColumnScope.CalculateFromUriPage(\n    component: ChecksumToolsComponent\n) {\n    val page = component.calculateFromUriPage\n\n    FileSelector(\n        value = page.uri?.toString(),\n        onValueChange = component::setUri,\n        subtitle = null\n    )\n    AnimatedContent(page.checksum) { checksum ->\n        if (checksum.isNotEmpty()) {\n            ChecksumPreviewField(\n                value = checksum,\n                onCopyText = Clipboard::copy,\n                label = stringResource(R.string.checksum)\n            )\n        } else {\n            InfoContainer(\n                text = stringResource(R.string.pick_file_to_checksum),\n                modifier = Modifier.padding(8.dp),\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/pages/CompareWithUriPage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FileSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumEnterField\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumPreviewField\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumResultCard\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent\n\n@Composable\ninternal fun ColumnScope.CompareWithUriPage(\n    component: ChecksumToolsComponent,\n) {\n    val page = component.compareWithUriPage\n\n    FileSelector(\n        value = page.uri?.toString(),\n        onValueChange = component::setDataForComparison,\n        subtitle = null\n    )\n    AnimatedContent(page.checksum) { checksum ->\n        if (checksum.isNotEmpty()) {\n            ChecksumPreviewField(\n                value = checksum,\n                onCopyText = Clipboard::copy\n            )\n        } else {\n            InfoContainer(\n                text = stringResource(R.string.pick_file_to_checksum),\n                modifier = Modifier.padding(8.dp),\n            )\n        }\n    }\n\n    ChecksumEnterField(\n        value = page.targetChecksum,\n        onValueChange = {\n            component.setDataForComparison(\n                targetChecksum = it\n            )\n        }\n    )\n\n    AnimatedVisibility(\n        page.targetChecksum.isNotEmpty() && !page.uri?.toString()\n            .isNullOrEmpty()\n    ) {\n        ChecksumResultCard(page.isCorrect)\n    }\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/components/pages/CompareWithUrisPage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.pages\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FileCopy\nimport androidx.compose.material.icons.outlined.FolderOpen\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.FileType\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFolderPicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PagerScrollPanel\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.negativePadding\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumEnterField\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumResultCard\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.UriWithHashItem\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent\n\n@Composable\ninternal fun ColumnScope.CompareWithUrisPage(\n    component: ChecksumToolsComponent\n) {\n    var previousFolder by rememberSaveable {\n        mutableStateOf<Uri?>(null)\n    }\n\n    val isFilesLoading = component.filesLoadingProgress >= 0\n\n    val openDirectoryLauncher = rememberFolderPicker(\n        onSuccess = { uri ->\n            previousFolder = uri\n            component.setDataForBatchComparisonFromTree(uri)\n        }\n    )\n\n    val filePicker = rememberFilePicker(\n        type = FileType.Multiple,\n        onSuccess = component::setDataForBatchComparison\n    )\n\n    val page = component.compareWithUrisPage\n\n    Row(\n        horizontalArrangement = Arrangement.spacedBy(4.dp),\n        verticalAlignment = Alignment.CenterVertically,\n        modifier = Modifier.height(IntrinsicSize.Max)\n    ) {\n        PreferenceRow(\n            title = stringResource(R.string.pick_files),\n            onClick = filePicker::pickFile,\n            shape = ShapeDefaults.start,\n            titleFontStyle = PreferenceItemDefaults.TitleFontStyleCenteredSmall,\n            startIcon = Icons.Outlined.FileCopy,\n            drawStartIconContainer = false,\n            modifier = Modifier\n                .weight(1f)\n                .fillMaxHeight(),\n            color = MaterialTheme.colorScheme.secondaryContainer.copy(0.5f),\n            contentColor = MaterialTheme.colorScheme.onSecondaryContainer\n        )\n        PreferenceRow(\n            title = stringResource(R.string.pick_directory),\n            onClick = {\n                openDirectoryLauncher.pickFolder(previousFolder)\n            },\n            shape = ShapeDefaults.end,\n            titleFontStyle = PreferenceItemDefaults.TitleFontStyleCenteredSmall,\n            startIcon = Icons.Outlined.FolderOpen,\n            drawStartIconContainer = false,\n            modifier = Modifier\n                .weight(1f)\n                .fillMaxHeight(),\n            color = MaterialTheme.colorScheme.secondaryContainer.copy(0.5f),\n            contentColor = MaterialTheme.colorScheme.onSecondaryContainer\n        )\n    }\n\n    val nestedPagerState = rememberPagerState { page.uris.size }\n\n    AnimatedContent(\n        targetState = page.uris.isNotEmpty() to isFilesLoading,\n        modifier = Modifier.padding(vertical = 4.dp)\n    ) { (isNotEmpty, isLoading) ->\n        if (isLoading) {\n            Box(\n                modifier = Modifier.fillMaxWidth(),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedLoadingIndicator(\n                    progress = component.filesLoadingProgress\n                )\n            }\n        } else if (isNotEmpty) {\n            HorizontalPager(\n                state = nestedPagerState,\n                pageSpacing = 16.dp,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .negativePadding(horizontal = 20.dp)\n                    .fadingEdges(nestedPagerState),\n                contentPadding = PaddingValues(horizontal = 20.dp),\n                beyondViewportPageCount = 10\n            ) { nestedPage ->\n                UriWithHashItem(\n                    uriWithHash = page.uris[nestedPage],\n                    onCopyText = Clipboard::copy\n                )\n            }\n        } else {\n            InfoContainer(\n                text = stringResource(R.string.pick_files_to_checksum),\n                modifier = Modifier.padding(8.dp),\n            )\n        }\n    }\n\n    AnimatedVisibility(page.uris.isNotEmpty()) {\n        Column(\n            verticalArrangement = Arrangement.spacedBy(8.dp),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            if (page.uris.size > 1) {\n                PagerScrollPanel(nestedPagerState)\n            }\n\n            ChecksumEnterField(\n                value = page.targetChecksum,\n                onValueChange = {\n                    component.setDataForBatchComparison(\n                        targetChecksum = it\n                    )\n                }\n            )\n        }\n    }\n\n    AnimatedVisibility(page.targetChecksum.isNotEmpty() && page.uris.isNotEmpty()) {\n        val isCorrect =\n            page.targetChecksum == page.uris[nestedPagerState.currentPage].checksum\n\n        ChecksumResultCard(isCorrect)\n    }\n}"
  },
  {
    "path": "feature/checksum-tools/src/main/java/com/t8rin/imagetoolbox/feature/checksum_tools/presentation/screenLogic/ChecksumToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.checksum_tools.domain.ChecksumManager\nimport com.t8rin.imagetoolbox.feature.checksum_tools.domain.ChecksumSource\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.ChecksumPage\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.components.UriWithHash\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\n\nclass ChecksumToolsComponent @AssistedInject constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    private val checksumManager: ChecksumManager,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _hashingType = fileController.savable(\n        scope = componentScope,\n        initial = HashingType.entries.first()\n    )\n    val hashingType: HashingType by _hashingType\n\n    private val _calculateFromUriPage: MutableState<ChecksumPage.CalculateFromUri> =\n        mutableStateOf(ChecksumPage.CalculateFromUri.Empty)\n    val calculateFromUriPage: ChecksumPage.CalculateFromUri by _calculateFromUriPage\n\n    private val _calculateFromTextPage: MutableState<ChecksumPage.CalculateFromText> =\n        mutableStateOf(ChecksumPage.CalculateFromText.Empty)\n    val calculateFromTextPage: ChecksumPage.CalculateFromText by _calculateFromTextPage\n\n    private val _compareWithUriPage: MutableState<ChecksumPage.CompareWithUri> =\n        mutableStateOf(ChecksumPage.CompareWithUri.Empty)\n    val compareWithUriPage: ChecksumPage.CompareWithUri by _compareWithUriPage\n\n    private val _compareWithUrisPage: MutableState<ChecksumPage.CompareWithUris> =\n        mutableStateOf(ChecksumPage.CompareWithUris.Empty)\n    val compareWithUrisPage: ChecksumPage.CompareWithUris by _compareWithUrisPage\n\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    fun setUri(uri: Uri) {\n        _calculateFromUriPage.update {\n            it.copy(\n                uri = uri\n            )\n        }\n\n        componentScope.launch {\n            _calculateFromUriPage.update {\n                it.copy(\n                    uri = uri,\n                    checksum = checksumManager.calculateChecksum(\n                        type = hashingType,\n                        source = ChecksumSource.Uri(uri.toString())\n                    )\n                )\n            }\n        }\n    }\n\n    fun setText(text: String) {\n        _calculateFromTextPage.update {\n            it.copy(\n                text = text\n            )\n        }\n\n        componentScope.launch {\n            _calculateFromTextPage.update {\n                it.copy(\n                    text = text,\n                    checksum = if (text.isNotEmpty()) {\n                        checksumManager.calculateChecksum(\n                            type = hashingType,\n                            source = ChecksumSource.Text(text)\n                        )\n                    } else \"\"\n                )\n            }\n        }\n    }\n\n    fun setDataForComparison(\n        uri: Uri? = compareWithUriPage.uri,\n        targetChecksum: String = compareWithUriPage.targetChecksum\n    ) {\n        _compareWithUriPage.update {\n            it.copy(\n                uri = uri,\n                targetChecksum = targetChecksum\n            )\n        }\n\n        componentScope.launch {\n            _compareWithUriPage.update {\n                it.copy(\n                    uri = uri,\n                    targetChecksum = targetChecksum,\n                    checksum = checksumManager.calculateChecksum(\n                        type = hashingType,\n                        source = ChecksumSource.Uri(uri.toString())\n                    ),\n                    isCorrect = checksumManager.compareChecksum(\n                        checksum = targetChecksum,\n                        type = hashingType,\n                        source = ChecksumSource.Uri(uri.toString())\n                    )\n                )\n            }\n        }\n    }\n\n    fun updateChecksumType(type: HashingType) {\n        _hashingType.update { type }\n        calculateFromUriPage.uri?.let(::setUri)\n        calculateFromTextPage.text.let(::setText)\n        compareWithUriPage.uri?.let(::setDataForComparison)\n        setDataForBatchComparison(forceReload = true)\n    }\n\n    private var treeJob: Job? by smartJob {\n        _filesLoadingProgress.update { -1f }\n    }\n\n    fun setDataForBatchComparison(\n        uris: List<Uri> = compareWithUrisPage.uris.map { it.uri },\n        targetChecksum: String = compareWithUrisPage.targetChecksum,\n        forceReload: Boolean = false\n    ) {\n        _compareWithUrisPage.update {\n            it.copy(\n                targetChecksum = targetChecksum\n            )\n        }\n\n        val targetUris = compareWithUrisPage.uris.map { it.uri }\n\n        if (targetUris != uris || forceReload) {\n            treeJob = componentScope.launch {\n                delay(500)\n                _filesLoadingProgress.update { 0f }\n\n                var done = 0\n\n                val urisWithHash = uris.map { uri ->\n                    val checksum = checksumManager.calculateChecksum(\n                        type = hashingType,\n                        source = ChecksumSource.Uri(uri.toString())\n                    )\n\n                    _filesLoadingProgress.update {\n                        ((done++) / uris.size.toFloat()).takeIf { it.isFinite() } ?: 0f\n                    }\n\n                    UriWithHash(\n                        uri = uri,\n                        checksum = checksum\n                    )\n                }\n\n                _compareWithUrisPage.update {\n                    it.copy(\n                        uris = urisWithHash,\n                        targetChecksum = targetChecksum\n                    )\n                }\n                _filesLoadingProgress.update { -1f }\n            }\n        }\n    }\n\n    private val _filesLoadingProgress = mutableFloatStateOf(-1f)\n    val filesLoadingProgress by _filesLoadingProgress\n\n    fun setDataForBatchComparisonFromTree(uri: Uri) {\n        treeJob = componentScope.launch {\n            delay(500)\n            _filesLoadingProgress.update { 0f }\n            fileController.listFilesInDirectory(uri.toString())\n                .map { it.toUri() }\n                .let(::setDataForBatchComparison)\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n        ): ChecksumToolsComponent\n    }\n\n}"
  },
  {
    "path": "feature/cipher/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/cipher/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.cipher\""
  },
  {
    "path": "feature/cipher/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/data/AndroidCryptographyManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"PrivatePropertyName\", \"SpellCheckingInspection\")\n\npackage com.t8rin.imagetoolbox.feature.cipher.data\n\nimport com.t8rin.imagetoolbox.core.data.saving.io.StringReadable\nimport com.t8rin.imagetoolbox.core.data.utils.computeBytesFromReadable\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.CipherType\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.feature.cipher.domain.CryptographyManager\nimport com.t8rin.imagetoolbox.feature.cipher.domain.WrongKeyException\nimport kotlinx.coroutines.withContext\nimport java.security.Key\nimport java.security.SecureRandom\nimport javax.crypto.Cipher\nimport javax.crypto.SecretKeyFactory\nimport javax.crypto.spec.IvParameterSpec\nimport javax.crypto.spec.PBEKeySpec\nimport javax.crypto.spec.PBEParameterSpec\nimport javax.crypto.spec.SecretKeySpec\nimport javax.inject.Inject\n\ninternal class AndroidCryptographyManager @Inject constructor(\n    private val dispatchersHolder: DispatchersHolder\n) : CryptographyManager, DispatchersHolder by dispatchersHolder {\n\n    private val CHARS = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"\n\n    private fun createKey(\n        password: String,\n        type: CipherType\n    ): Key = if (\"PBE\" in type.name) {\n        SecretKeyFactory\n            .getInstance(type.cipher)\n            .generateSecret(\n                PBEKeySpec(password.toCharArray())\n            )\n    } else {\n        hashingType(type.name)\n            .computeBytesFromReadable(StringReadable(password))\n            .let { key ->\n                SecretKeySpec(key, type.cipher)\n            }\n    }\n\n    override fun generateRandomString(length: Int): String {\n        val sr = SecureRandom()\n        return buildString {\n            repeat(length) {\n                append(CHARS[sr.nextInt(CHARS.length)])\n            }\n        }\n    }\n\n    override suspend fun decrypt(\n        data: ByteArray,\n        key: String,\n        type: CipherType\n    ): ByteArray = withContext(defaultDispatcher) {\n        val cipher = type.toCipher(\n            keySpec = createKey(\n                password = key,\n                type = type\n            ),\n            isEncrypt = false\n        )\n\n        cipher.doOrThrow(data)\n    }\n\n    override suspend fun encrypt(\n        data: ByteArray,\n        key: String,\n        type: CipherType\n    ): ByteArray = withContext(defaultDispatcher) {\n        val cipher = type.toCipher(\n            keySpec = createKey(\n                password = key,\n                type = type\n            ),\n            isEncrypt = true\n        )\n\n        cipher.doOrThrow(data)\n    }\n\n    private fun Cipher.init(\n        keySpec: Key,\n        isEncrypt: Boolean,\n        type: CipherType\n    ) {\n        val mode = if (isEncrypt) Cipher.ENCRYPT_MODE else Cipher.DECRYPT_MODE\n        try {\n            val encodedKey = keySpec.encoded\n            when {\n                \"PBE\" in type.name -> {\n                    init(\n                        mode,\n                        keySpec,\n                        PBEParameterSpec(encodedKey, encodedKey.size)\n                    )\n                }\n\n                else -> {\n                    init(\n                        mode,\n                        keySpec,\n                        IvParameterSpec(encodedKey, 0, blockSize)\n                    )\n                }\n            }\n        } catch (_: Throwable) {\n            runCatching {\n                init(\n                    mode,\n                    keySpec,\n                    generateIV(ivSize(type.name))\n                )\n            }.getOrElse {\n                init(\n                    mode,\n                    keySpec\n                )\n            }\n        }\n    }\n\n    private fun CipherType.toCipher(\n        keySpec: Key,\n        isEncrypt: Boolean\n    ): Cipher = Cipher.getInstance(cipher).apply {\n        init(\n            keySpec = keySpec,\n            isEncrypt = isEncrypt,\n            type = this@toCipher\n        )\n    }\n\n    private fun Cipher.doOrThrow(data: ByteArray): ByteArray {\n        return try {\n            doFinal(data)\n        } catch (e: Throwable) {\n            throw if (e.message?.contains(\"mac\") == true && e.message?.contains(\"failed\") == true) {\n                WrongKeyException()\n            } else e\n        }\n    }\n\n    private fun generateIV(size: Int): IvParameterSpec {\n        val iv = ByteArray(size)\n        SecureRandom().nextBytes(iv)\n        return IvParameterSpec(iv)\n    }\n\n    private fun ivSize(name: String): Int = when {\n        name == \"AESRFC5649WRAP\"\n                || name == \"AESWRAPPAD\"\n                || name == \"AES_128/KWP/NoPadding\"\n                || name == \"AES_192/KWP/NoPadding\"\n                || name == \"AES_256/KWP/NoPadding\"\n                || name == \"ARIAWRAPPAD\" -> 4\n\n        name == \"AESWRAP\"\n                || name == \"AES_128/KW/NoPadding\"\n                || name == \"AES_192/KW/NoPadding\"\n                || name == \"CAMELLIAWRAP\"\n                || name == \"AES_256/KW/NoPadding\"\n                || name == \"ARIAWRAP\"\n                || name == \"CHACHA\"\n                || \"CBC\" in name && name != \"SEED/CBC\"\n                || name == \"DESEDEWRAP\"\n                || name == \"GRAINV1\"\n                || name == \"SALSA20\"\n                || name.contains(\"wrap\", true) -> 8\n\n        name == \"AES/ECB/PKCS7PADDING\"\n                || name == \"AES/GCM-SIV/NOPADDING\"\n                || name == \"AES128/CCM\"\n                || name == \"AES192/CCM\"\n                || name == \"AES256/CCM\"\n                || \"CCM\" in name\n                || \"CHACHA\" in name\n                || name == \"AES_256/GCM-SIV/NOPADDING\"\n                || name == \"AES_256/GCM/NOPADDING\"\n                || name == \"GRAIN128\"\n                || name == \"AES_128/CBC/NOPADDING\"\n                || name == \"AES_128/CBC/PKCS5PADDING\"\n                || name == \"AES_128/GCM/NOPADDING\" -> 12\n\n        name == \"XSALSA20\" -> 24\n        name == \"ZUC-256\" -> 25\n\n        \"DSTU7624\" in name && \"512\" in name -> 64\n\n        else -> 16\n    }\n\n    private val MD5List = listOf(\n        \"SEED\",\n        \"NOEKEON\",\n        \"HC128\",\n        \"AES_128/CBC/NOPADDING\",\n        \"AES_128/CBC/PKCS5PADDING\",\n        \"AES_128/GCM/NOPADDING\",\n        \"DESEDE\",\n        \"GRAIN128\",\n        \"SM4\",\n        \"TEA\",\n        \"ZUC-128\",\n        \"AES_128/ECB/NOPADDING\",\n        \"AES_128/ECB/PKCS5PADDING\",\n        \"AES_128/GCM/NOPADDING\"\n    )\n\n    private fun hashingType(name: String): HashingType = when {\n        MD5List.any { name.contains(it, true) } -> HashingType.MD5\n\n        else -> HashingType.SHA_256\n    }\n}"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/data/AndroidRandomStringGenerator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.data\n\nimport com.t8rin.imagetoolbox.core.domain.saving.RandomStringGenerator\nimport com.t8rin.imagetoolbox.feature.cipher.domain.CryptographyManager\nimport javax.inject.Inject\n\ninternal class AndroidRandomStringGenerator @Inject constructor(\n    private val cryptographyManager: CryptographyManager\n) : RandomStringGenerator {\n\n    override fun generate(length: Int): String = cryptographyManager.generateRandomString(length)\n\n}"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/di/CipherModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.di\n\nimport com.t8rin.imagetoolbox.core.domain.saving.RandomStringGenerator\nimport com.t8rin.imagetoolbox.feature.cipher.data.AndroidCryptographyManager\nimport com.t8rin.imagetoolbox.feature.cipher.data.AndroidRandomStringGenerator\nimport com.t8rin.imagetoolbox.feature.cipher.domain.CryptographyManager\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface CipherModule {\n\n    @Singleton\n    @Binds\n    fun cryptographyManager(\n        impl: AndroidCryptographyManager\n    ): CryptographyManager\n\n    @Singleton\n    @Binds\n    fun provideRandomStringGenerator(\n        impl: AndroidRandomStringGenerator\n    ): RandomStringGenerator\n\n}"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/domain/CryptographyManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.CipherType\n\ninterface CryptographyManager {\n\n    fun generateRandomString(\n        length: Int\n    ): String\n\n    suspend fun decrypt(\n        data: ByteArray,\n        key: String,\n        type: CipherType\n    ): ByteArray\n\n    suspend fun encrypt(\n        data: ByteArray,\n        key: String,\n        type: CipherType\n    ): ByteArray\n\n}"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/domain/WrongKeyException.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.domain\n\ninternal class WrongKeyException : Throwable()"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/presentation/CipherContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.presentation\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileOpen\nimport androidx.compose.material.icons.rounded.Lock\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.CipherType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.KeyVertical\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.FileNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.cipher.domain.WrongKeyException\nimport com.t8rin.imagetoolbox.feature.cipher.presentation.components.CipherControls\nimport com.t8rin.imagetoolbox.feature.cipher.presentation.components.CipherTipSheet\nimport com.t8rin.imagetoolbox.feature.cipher.presentation.screenLogic.CipherComponent\n\n\n@Composable\nfun CipherContent(\n    component: CipherComponent\n) {\n    val showTip = component.showTip\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val canGoBack = component.canGoBack\n    val key = component.key\n\n    val onBack = {\n        if (!canGoBack) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val filePicker = rememberFilePicker(onSuccess = component::setUri)\n\n    AutoFilePicker(\n        onAutoPick = filePicker::pickFile,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    AdaptiveLayoutScreen(\n        title = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                modifier = Modifier.marquee()\n            ) {\n                AnimatedContent(\n                    targetState = component.uri to component.isEncrypt,\n                    transitionSpec = { fadeIn() togetherWith fadeOut() }\n                ) { (uri, isEncrypt) ->\n                    Text(\n                        if (uri == null) {\n                            stringResource(R.string.cipher)\n                        } else {\n                            listOf(\n                                stringResource(R.string.encryption),\n                                stringResource(R.string.decryption)\n                            )[if (isEncrypt) 0 else 1]\n                        },\n                        textAlign = TextAlign.Center\n                    )\n                }\n                EnhancedBadge(\n                    content = {\n                        Text(\n                            text = CipherType.entries.size.toString()\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.tertiary,\n                    contentColor = MaterialTheme.colorScheme.onTertiary,\n                    modifier = Modifier\n                        .padding(horizontal = 2.dp)\n                        .padding(bottom = 12.dp)\n                        .scaleOnTap {\n                            AppToastHost.showConfetti()\n                        }\n                )\n            }\n        },\n        onGoBack = onBack,\n        shouldDisableBackHandler = canGoBack,\n        topAppBarPersistentActions = {\n            TopAppBarEmoji()\n        },\n        actions = {},\n        buttons = {\n            BottomButtonsBlock(\n                isNoData = component.uri == null,\n                onSecondaryButtonClick = filePicker::pickFile,\n                secondaryButtonIcon = Icons.Rounded.FileOpen,\n                secondaryButtonText = stringResource(R.string.pick_file),\n                onPrimaryButtonClick = {\n                    component.startCryptography {\n                        if (it is WrongKeyException) {\n                            AppToastHost.showFailureToast(R.string.invalid_password_or_not_encrypted)\n                        } else if (it != null) {\n                            AppToastHost.showFailureToast(\n                                throwable = it\n                            )\n                        }\n                    }\n                },\n                primaryButtonIcon = if (component.isEncrypt) {\n                    Icons.Rounded.Lock\n                } else {\n                    Icons.Rounded.KeyVertical\n                },\n                primaryButtonText = if (isPortrait) {\n                    if (component.isEncrypt) {\n                        stringResource(R.string.encrypt)\n                    } else {\n                        stringResource(R.string.decrypt)\n                    }\n                } else \"\",\n                isPrimaryButtonEnabled = key.isNotEmpty(),\n                actions = {}\n            )\n        },\n        canShowScreenData = component.uri != null,\n        noDataControls = {\n            FileNotPickedWidget(onPickFile = filePicker::pickFile)\n        },\n        controls = {\n            CipherControls(component)\n        },\n        imagePreview = {},\n        showImagePreviewAsStickyHeader = false,\n        placeImagePreview = false,\n        showActionsInTopAppBar = false,\n        addHorizontalCutoutPaddingIfNoPreview = false,\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    CipherTipSheet(\n        visible = showTip,\n        onDismiss = component::hideTip\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        onCancelLoading = component::cancelSaving\n    )\n\n}"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/presentation/components/CipherControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.HelpOutline\nimport androidx.compose.material.icons.automirrored.rounded.InsertDriveFile\nimport androidx.compose.material.icons.outlined.Cancel\nimport androidx.compose.material.icons.rounded.CheckCircle\nimport androidx.compose.material.icons.rounded.FileDownload\nimport androidx.compose.material.icons.rounded.Key\nimport androidx.compose.material.icons.rounded.Share\nimport androidx.compose.material.icons.rounded.Shuffle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.model.CipherType\nimport com.t8rin.imagetoolbox.core.domain.utils.toInt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.Green\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.cipher.presentation.screenLogic.CipherComponent\nimport kotlin.random.Random\n\n@Composable\ninternal fun CipherControls(component: CipherComponent) {\n    val settingsState = LocalSettingsState.current\n    val isPortrait by isPortraitOrientationAsState()\n\n    val saveLauncher = rememberFileCreator(\n        onSuccess = component::saveCryptographyTo\n    )\n\n    val filename = component.uri?.let {\n        rememberFilename(it)\n    }\n\n    Column(horizontalAlignment = Alignment.CenterHorizontally) {\n        if (isPortrait) Spacer(Modifier.height(20.dp))\n        Row(\n            modifier = Modifier\n                .container(ShapeDefaults.circle)\n                .padding(horizontal = 8.dp, vertical = 4.dp),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            val items = listOf(\n                stringResource(R.string.encryption),\n                stringResource(R.string.decryption)\n            )\n            EnhancedButtonGroup(\n                enabled = true,\n                itemCount = items.size,\n                selectedIndex = (!component.isEncrypt).toInt(),\n                onIndexChange = {\n                    component.setIsEncrypt(it == 0)\n                },\n                itemContent = {\n                    Text(\n                        text = items[it],\n                        fontSize = 12.sp\n                    )\n                },\n                isScrollable = false,\n                modifier = Modifier.weight(1f)\n            )\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = component::showTip\n            ) {\n                Icon(\n                    imageVector = Icons.AutoMirrored.Rounded.HelpOutline,\n                    contentDescription = \"Info\"\n                )\n            }\n        }\n        Spacer(Modifier.height(16.dp))\n        PreferenceItem(\n            modifier = Modifier,\n            title = filename ?: stringResource(R.string.something_went_wrong),\n            onClick = null,\n            titleFontStyle = LocalTextStyle.current.copy(\n                lineHeight = 16.sp,\n                fontSize = 15.sp\n            ),\n            subtitle = component.uri?.let {\n                stringResource(\n                    id = R.string.size,\n                    rememberHumanFileSize(it)\n                )\n            },\n            startIcon = Icons.AutoMirrored.Rounded.InsertDriveFile\n        )\n        Spacer(Modifier.height(16.dp))\n        RoundedTextField(\n            modifier = Modifier\n                .container(\n                    shape = MaterialTheme.shapes.large,\n                    resultPadding = 8.dp\n                ),\n            value = component.key,\n            startIcon = {\n                EnhancedIconButton(\n                    onClick = {\n                        component.updateKey(component.generateRandomPassword())\n                    },\n                    modifier = Modifier.padding(start = 4.dp)\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.Shuffle,\n                        contentDescription = stringResource(R.string.shuffle),\n                        tint = MaterialTheme.colorScheme.onSecondaryContainer\n                    )\n                }\n            },\n            endIcon = {\n                EnhancedIconButton(\n                    onClick = { component.updateKey(\"\") },\n                    modifier = Modifier.padding(end = 4.dp)\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Cancel,\n                        contentDescription = stringResource(R.string.cancel),\n                        tint = MaterialTheme.colorScheme.onSecondaryContainer\n                    )\n                }\n            },\n            keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),\n            singleLine = false,\n            onValueChange = component::updateKey,\n            label = {\n                Text(stringResource(R.string.key))\n            }\n        )\n        AnimatedVisibility(visible = component.byteArray != null) {\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(top = 24.dp)\n                    .container(\n                        shape = MaterialTheme.shapes.extraLarge,\n                        color = MaterialTheme\n                            .colorScheme\n                            .surfaceContainerHighest,\n                        resultPadding = 0.dp\n                    )\n                    .padding(16.dp)\n            ) {\n                Row(verticalAlignment = Alignment.CenterVertically) {\n                    Icon(\n                        imageVector = Icons.Rounded.CheckCircle,\n                        contentDescription = null,\n                        tint = Green,\n                        modifier = Modifier\n                            .size(36.dp)\n                            .background(\n                                color = MaterialTheme.colorScheme.surface,\n                                shape = ShapeDefaults.circle\n                            )\n                            .border(\n                                width = settingsState.borderWidth,\n                                color = MaterialTheme.colorScheme.outlineVariant(),\n                                shape = ShapeDefaults.circle\n                            )\n                            .padding(4.dp)\n                    )\n                    Spacer(modifier = Modifier.width(16.dp))\n                    Text(\n                        stringResource(R.string.file_proceed),\n                        fontSize = 17.sp,\n                        fontWeight = FontWeight.Medium\n                    )\n                }\n                Text(\n                    text = stringResource(R.string.store_file_desc),\n                    fontSize = 13.sp,\n                    color = LocalContentColor.current.copy(alpha = 0.7f),\n                    lineHeight = 14.sp,\n                    modifier = Modifier.padding(vertical = 16.dp)\n                )\n                var name by rememberSaveable(component.byteArray, filename) {\n                    mutableStateOf(\n                        if (component.isEncrypt) {\n                            \"enc-\"\n                        } else {\n                            \"dec-\"\n                        } + (filename ?: Random.nextInt())\n                    )\n                }\n                RoundedTextField(\n                    modifier = Modifier\n                        .padding(top = 8.dp)\n                        .container(\n                            shape = MaterialTheme.shapes.large,\n                            resultPadding = 8.dp\n                        ),\n                    value = name,\n                    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),\n                    singleLine = false,\n                    onValueChange = { name = it },\n                    label = {\n                        Text(stringResource(R.string.filename))\n                    }\n                )\n\n                Row(\n                    modifier = Modifier\n                        .padding(top = 24.dp)\n                        .fillMaxWidth()\n                ) {\n                    EnhancedButton(\n                        onClick = {\n                            saveLauncher.make(name)\n                        },\n                        modifier = Modifier\n                            .padding(end = 8.dp)\n                            .fillMaxWidth(0.5f)\n                            .height(50.dp),\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer\n                    ) {\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically,\n                            horizontalArrangement = Arrangement.Center\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.FileDownload,\n                                contentDescription = null\n                            )\n                            Spacer(modifier = Modifier.width(8.dp))\n                            AutoSizeText(\n                                text = stringResource(id = R.string.save),\n                                maxLines = 1\n                            )\n                        }\n                    }\n                    EnhancedButton(\n                        onClick = {\n                            component.byteArray?.let {\n                                component.shareFile(\n                                    it = it,\n                                    filename = name\n                                )\n                            }\n                        },\n                        modifier = Modifier\n                            .padding(start = 8.dp)\n                            .fillMaxWidth()\n                            .height(50.dp),\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer\n                    ) {\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically,\n                            horizontalArrangement = Arrangement.Center\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Share,\n                                contentDescription = stringResource(\n                                    R.string.share\n                                )\n                            )\n                            Spacer(modifier = Modifier.width(8.dp))\n                            AutoSizeText(\n                                text = stringResource(id = R.string.share),\n                                maxLines = 1\n                            )\n                        }\n                    }\n                }\n            }\n        }\n        Spacer(Modifier.height(24.dp))\n        DataSelector(\n            modifier = Modifier,\n            value = component.cipherType,\n            containerColor = Color.Unspecified,\n            spanCount = 5,\n            selectedItemColor = MaterialTheme.colorScheme.secondary,\n            onValueChange = component::updateCipherType,\n            entries = CipherType.entries,\n            title = stringResource(R.string.algorithms),\n            titleIcon = Icons.Rounded.Key,\n            itemContentText = {\n                it.name\n            },\n            initialExpanded = true\n        )\n    }\n}"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/presentation/components/CipherTipSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.InsertDriveFile\nimport androidx.compose.material.icons.rounded.Functions\nimport androidx.compose.material.icons.rounded.Security\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Interface\nimport com.t8rin.imagetoolbox.core.resources.icons.Puzzle\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun CipherTipSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Box {\n                Column(\n                    modifier = Modifier\n                        .enhancedVerticalScroll(rememberScrollState())\n                        .padding(12.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    Column(\n                        modifier = Modifier\n                            .container(\n                                shape = ShapeDefaults.top\n                            )\n                            .fillMaxWidth()\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.features),\n                            icon = Icons.Rounded.Functions\n                        )\n                        Text(\n                            text = stringResource(R.string.features_sub),\n                            modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                    Column(\n                        modifier = Modifier\n                            .container(\n                                shape = ShapeDefaults.center\n                            )\n                            .fillMaxWidth()\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.implementation),\n                            icon = Icons.Filled.Interface\n                        )\n                        Text(\n                            text = stringResource(id = R.string.implementation_sub),\n                            modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                    Column(\n                        modifier = Modifier\n                            .container(\n                                shape = ShapeDefaults.center\n                            )\n                            .fillMaxWidth()\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.file_size),\n                            icon = Icons.AutoMirrored.Outlined.InsertDriveFile\n                        )\n                        Text(\n                            text = stringResource(id = R.string.file_size_sub),\n                            modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                    Column(\n                        modifier = Modifier\n                            .container(\n                                shape = ShapeDefaults.bottom\n                            )\n                            .fillMaxWidth()\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.compatibility),\n                            icon = Icons.Outlined.Puzzle\n                        )\n                        Text(\n                            text = stringResource(id = R.string.compatibility_sub),\n                            modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                }\n            }\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.cipher),\n                icon = Icons.Rounded.Security\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/cipher/src/main/java/com/t8rin/imagetoolbox/feature/cipher/presentation/screenLogic/CipherComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.cipher.presentation.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.model.CipherType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.cipher.domain.CryptographyManager\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass CipherComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    private val cryptographyManager: CryptographyManager,\n    private val shareProvider: ShareProvider,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _cipherType = fileController.savable(\n        scope = componentScope,\n        initial = CipherType.entries.first()\n    )\n    val cipherType: CipherType by _cipherType\n\n    private val _showTip: MutableState<Boolean> = mutableStateOf(false)\n    val showTip by _showTip\n\n    private val _key: MutableState<String> = mutableStateOf(\"\")\n    val key by _key\n\n    val canGoBack: Boolean\n        get() = uri == null || (key.isEmpty() && byteArray == null)\n\n    fun showTip() = _showTip.update { true }\n    fun hideTip() = _showTip.update { false }\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    fun updateKey(newKey: String) {\n        _key.update { newKey }\n        resetCalculatedData()\n    }\n\n\n    private val _uri = mutableStateOf<Uri?>(null)\n    val uri by _uri\n\n    private val _isEncrypt = mutableStateOf(true)\n    val isEncrypt by _isEncrypt\n\n    private val _byteArray = mutableStateOf<ByteArray?>(null)\n    val byteArray by _byteArray\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    fun setUri(newUri: Uri) {\n        _uri.value = newUri\n        resetCalculatedData()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun startCryptography(\n        onComplete: (Throwable?) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val uri = uri\n\n            if (uri == null) {\n                onComplete(null)\n                return@trackProgress\n            }\n            runSuspendCatching {\n                _byteArray.update {\n                    fileController.readBytes(uri.toString()).let { file ->\n                        if (isEncrypt) {\n                            cryptographyManager.encrypt(\n                                data = file,\n                                key = key,\n                                type = cipherType\n                            )\n                        } else {\n                            cryptographyManager.decrypt(\n                                data = file,\n                                key = key,\n                                type = cipherType\n                            )\n                        }\n                    }\n                }\n            }.exceptionOrNull().let(onComplete)\n            _isSaving.value = false\n        }\n    }\n\n    fun updateCipherType(type: CipherType) {\n        _cipherType.update { type }\n        resetCalculatedData()\n    }\n\n    fun setIsEncrypt(isEncrypt: Boolean) {\n        _isEncrypt.value = isEncrypt\n        resetCalculatedData()\n    }\n\n    fun resetCalculatedData() {\n        _byteArray.value = null\n    }\n\n    fun saveCryptographyTo(uri: Uri) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            byteArray?.let { byteArray ->\n                fileController.writeBytes(\n                    uri = uri.toString(),\n                    block = { it.writeBytes(byteArray) }\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun generateRandomPassword(): String = cryptographyManager.generateRandomString(18)\n\n    fun shareFile(\n        it: ByteArray,\n        filename: String,\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            shareProvider.shareByteArray(\n                byteArray = it,\n                filename = filename,\n                onComplete = {\n                    _isSaving.value = false\n                    AppToastHost.showConfetti()\n                }\n            )\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n        ): CipherComponent\n    }\n}"
  },
  {
    "path": "feature/collage-maker/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/collage-maker/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.collage_maker\"\n\ndependencies {\n    implementation(projects.lib.collages)\n}"
  },
  {
    "path": "feature/collage-maker/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/collage-maker/src/main/java/com/t8rin/imagetoolbox/collage_maker/presentation/CollageMakerContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.collage_maker.presentation\n\nimport android.content.pm.ActivityInfo\nimport android.graphics.drawable.Drawable\nimport android.graphics.drawable.GradientDrawable\nimport android.graphics.drawable.LayerDrawable\nimport android.net.Uri\nimport androidx.appcompat.content.res.AppCompatResources\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.AutoAwesomeMosaic\nimport androidx.compose.material.icons.outlined.PinEnd\nimport androidx.compose.material.icons.outlined.SwipeVertical\nimport androidx.compose.material.icons.rounded.Add\nimport androidx.compose.material.icons.rounded.FormatLineSpacing\nimport androidx.compose.material.icons.rounded.PhotoSizeSelectSmall\nimport androidx.compose.material.icons.rounded.RoundedCorner\nimport androidx.compose.material.icons.rounded.SwapHoriz\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.graphics.drawable.DrawableCompat\nimport com.t8rin.collages.Collage\nimport com.t8rin.collages.CollageTypeSelection\nimport com.t8rin.collages.public.CollageConstants\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.collage_maker.presentation.screenLogic.CollageMakerComponent\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BackgroundColor\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveBottomScaffoldLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AspectRatioSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.other.LockScreenOrientation\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n@Composable\nfun CollageMakerContent(\n    component: CollageMakerComponent\n) {\n    LockScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)\n\n    var isLoading by rememberSaveable { mutableStateOf(true) }\n\n    LaunchedEffect(component.initialUris) {\n        component.initialUris?.takeIf { it.isNotEmpty() }?.let {\n            if (it.size in 1..CollageConstants.MAX_IMAGE_COUNT) {\n                component.updateUris(it)\n            } else {\n                AppToastHost.showToast(\n                    message = getString(\n                        R.string.pick_up_to_n_collage_images,\n                        CollageConstants.MAX_IMAGE_COUNT,\n                    ),\n                    icon = Icons.Outlined.AutoAwesomeMosaic\n                )\n            }\n        }\n    }\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        if (uris.size in 1..CollageConstants.MAX_IMAGE_COUNT) {\n            isLoading = true\n            component.updateUris(uris)\n        } else {\n            AppToastHost.showToast(\n                message = if (uris.size > CollageConstants.MAX_IMAGE_COUNT) {\n                    getString(\n                        R.string.pick_up_to_n_collage_images,\n                        CollageConstants.MAX_IMAGE_COUNT,\n                    )\n                } else {\n                    getString(R.string.pick_at_least_two_images)\n                },\n                icon = Icons.Outlined.AutoAwesomeMosaic\n            )\n        }\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    var resettingTrigger by rememberSaveable {\n        mutableIntStateOf(0)\n    }\n\n    val settings = LocalSettingsState.current\n\n    LaunchedEffect(\n        settings.isNightMode,\n        settings.appColorTuple,\n        settings.isDynamicColors\n    ) {\n        delay(500)\n        resettingTrigger++\n    }\n\n    val scope = rememberCoroutineScope()\n\n    AdaptiveBottomScaffoldLayoutScreen(\n        title = {\n            AnimatedContent(\n                targetState = component.uris.isNullOrEmpty()\n            ) { noData ->\n                if (noData) {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        modifier = Modifier.marquee()\n                    ) {\n                        Text(\n                            text = stringResource(R.string.collage_maker)\n                        )\n                        EnhancedBadge(\n                            content = {\n                                Text(\n                                    text = CollageConstants.layoutCount.toString()\n                                )\n                            },\n                            containerColor = MaterialTheme.colorScheme.tertiary,\n                            contentColor = MaterialTheme.colorScheme.onTertiary,\n                            modifier = Modifier\n                                .padding(horizontal = 2.dp)\n                                .padding(bottom = 12.dp)\n                                .scaleOnTap {\n                                    AppToastHost.showConfetti()\n                                }\n                        )\n                    }\n                } else {\n                    TopAppBarTitle(\n                        title = stringResource(R.string.collage_maker),\n                        input = component.uris,\n                        isLoading = component.isImageLoading,\n                        size = null\n                    )\n                }\n            }\n        },\n        onGoBack = onBack,\n        shouldDisableBackHandler = !component.haveChanges,\n        actions = { scaffoldState ->\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            EnhancedIconButton(\n                onClick = {\n                    scope.launch {\n                        if (scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {\n                            scaffoldState.bottomSheetState.partialExpand()\n                        } else {\n                            scaffoldState.bottomSheetState.expand()\n                        }\n                    }\n                },\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Tune,\n                    contentDescription = stringResource(R.string.properties)\n                )\n            }\n            ShareButton(\n                onShare = component::performSharing,\n                onCopy = {\n                    component.cacheImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheImage {\n                        editSheetData = listOf(it)\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.uris.isNullOrEmpty()) {\n                TopAppBarEmoji()\n            } else {\n                var showResetDialog by rememberSaveable {\n                    mutableStateOf(false)\n                }\n                EnhancedIconButton(\n                    onClick = { showResetDialog = true }\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.ImageReset,\n                        contentDescription = stringResource(R.string.reset_image)\n                    )\n                }\n                ResetDialog(\n                    visible = showResetDialog,\n                    onDismiss = { showResetDialog = false },\n                    onReset = {\n                        resettingTrigger++\n                    }\n                )\n            }\n        },\n        mainContent = {\n            LaunchedEffect(component.uris) {\n                if (!component.uris.isNullOrEmpty()) {\n                    delay(200)\n                    isLoading = false\n                }\n            }\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(20.dp)\n            ) {\n                var bottomPadding by remember {\n                    mutableStateOf(0.dp)\n                }\n                var infoHeight by remember {\n                    mutableStateOf(0.dp)\n                }\n                var tapIndex by remember { mutableIntStateOf(-1) }\n                var showItemMenu by remember { mutableStateOf(false) }\n\n                val singlePicker = rememberImagePicker { uri: Uri ->\n                    component.replaceImageAt(\n                        index = tapIndex,\n                        uri = uri\n                    )\n                }\n\n                val addPicker = rememberImagePicker { uri: Uri ->\n                    component.addImage(uri)\n                }\n\n                Box(\n                    modifier = Modifier\n                        .align(Alignment.Center)\n                        .padding(\n                            bottom = bottomPadding\n                        )\n                ) {\n                    AnimatedContent(\n                        targetState = resettingTrigger,\n                        transitionSpec = { fadeIn() togetherWith fadeOut() }\n                    ) { trigger ->\n                        key(trigger) {\n                            Box(\n                                modifier = Modifier\n                                    .zoomable(rememberZoomState())\n                                    .container(\n                                        shape = ShapeDefaults.extraSmall,\n                                        resultPadding = 0.dp\n                                    )\n                                    .shimmer(visible = isLoading),\n                                contentAlignment = Alignment.Center\n                            ) {\n                                Collage(\n                                    modifier = Modifier\n                                        .padding(4.dp)\n                                        .clip(ShapeDefaults.extraSmall)\n                                        .transparencyChecker(),\n                                    images = component.uris ?: emptyList(),\n                                    collageType = component.collageType,\n                                    collageCreationTrigger = component.collageCreationTrigger,\n                                    onCollageCreated = {\n                                        component.updateCollageBitmap(it)\n                                        isLoading = false\n                                    },\n                                    backgroundColor = component.backgroundColor,\n                                    spacing = component.params.spacing,\n                                    cornerRadius = component.params.cornerRadius,\n                                    aspectRatio = component.aspectRatio.value,\n                                    outputScaleRatio = component.params.outputScaleRatio,\n                                    disableRotation = component.params.disableRotation,\n                                    enableSnapToBorders = component.params.enableSnapToBorders,\n                                    onImageTap = { index ->\n                                        if (index >= 0) {\n                                            tapIndex = index\n                                            showItemMenu = true\n                                        } else {\n                                            showItemMenu = false\n                                        }\n                                    },\n                                    handleDrawable = rememberHandleDrawable()\n                                )\n                            }\n                        }\n                    }\n                }\n                val density = LocalDensity.current\n                InfoContainer(\n                    modifier = Modifier\n                        .align(Alignment.BottomCenter)\n                        .onSizeChanged {\n                            val height = with(density) { it.height.toDp() }\n                            infoHeight = height\n                            bottomPadding = height + 20.dp\n                        },\n                    containerColor = MaterialTheme.colorScheme.surfaceContainerLow,\n                    text = stringResource(R.string.collages_info)\n                )\n                AnimatedVisibility(\n                    visible = showItemMenu,\n                    modifier = Modifier\n                        .align(Alignment.BottomCenter)\n                        .padding(bottom = infoHeight + 12.dp),\n                    enter = fadeIn(),\n                    exit = fadeOut()\n                ) {\n                    Row(\n                        modifier = Modifier\n                            .container(\n                                color = MaterialTheme.colorScheme.surfaceContainerHigh,\n                                shape = ShapeDefaults.large,\n                                resultPadding = 0.dp\n                            ),\n                        horizontalArrangement = Arrangement.spacedBy(2.dp)\n                    ) {\n                        EnhancedIconButton(\n                            onClick = {\n                                showItemMenu = false\n                                singlePicker.pickImage()\n                            },\n                            enabled = tapIndex >= 0\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.SwapHoriz,\n                                contentDescription = \"Swap\"\n                            )\n                        }\n                        EnhancedIconButton(\n                            onClick = {\n                                showItemMenu = false\n                                addPicker.pickImage()\n                            }\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Add,\n                                contentDescription = \"Add\"\n                            )\n                        }\n                        EnhancedIconButton(\n                            onClick = {\n                                showItemMenu = false\n                                component.removeImageAt(tapIndex)\n                            },\n                            enabled = tapIndex >= 0\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Delete,\n                                contentDescription = \"Delete\"\n                            )\n                        }\n                    }\n                }\n            }\n        },\n        controls = {\n            Column(\n                modifier = Modifier.padding(16.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp)\n            ) {\n                val canChangeCollage = (component.uris?.size ?: 0) > 1\n\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    modifier = Modifier\n                        .then(\n                            if (canChangeCollage) {\n                                Modifier.container(\n                                    resultPadding = 0.dp,\n                                    shape = ShapeDefaults.extraLarge\n                                )\n                            } else Modifier\n                        )\n                ) {\n                    if (canChangeCollage) {\n                        Text(\n                            fontWeight = FontWeight.Medium,\n                            text = stringResource(R.string.collage_type),\n                            modifier = Modifier.padding(top = 16.dp),\n                            fontSize = 18.sp\n                        )\n                    }\n                    val state = rememberLazyListState()\n                    CollageTypeSelection(\n                        state = state,\n                        imagesCount = component.uris?.size ?: 0,\n                        value = component.collageType,\n                        onValueChange = component::setCollageType,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .height(100.dp)\n                            .fadingEdges(state),\n                        contentPadding = PaddingValues(16.dp),\n                        shape = ShapeDefaults.small,\n                        itemModifierFactory = { isSelected ->\n                            Modifier\n                                .container(\n                                    resultPadding = 0.dp,\n                                    color = animateColorAsState(\n                                        targetValue = if (isSelected) {\n                                            MaterialTheme.colorScheme.secondaryContainer\n                                        } else MaterialTheme.colorScheme.surfaceContainerLowest,\n                                    ).value,\n                                    shape = ShapeDefaults.small\n                                )\n                                .padding(8.dp)\n                                .clip(ShapeDefaults.extremeSmall)\n                        }\n                    )\n                }\n                ColorRowSelector(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.extraLarge\n                        ),\n                    icon = Icons.Outlined.BackgroundColor,\n                    value = component.backgroundColor,\n                    onValueChange = component::setBackgroundColor\n                )\n                AspectRatioSelector(\n                    selectedAspectRatio = component.aspectRatio,\n                    onAspectRatioChange = { aspect, _ ->\n                        component.setAspectRatio(aspect)\n                    },\n                    unselectedCardColor = MaterialTheme.colorScheme.surfaceContainerLowest,\n                    aspectRatios = remember {\n                        DomainAspectRatio.defaultList - setOf(\n                            DomainAspectRatio.Free,\n                            DomainAspectRatio.Original\n                        )\n                    }\n                )\n                EnhancedSliderItem(\n                    modifier = Modifier.fillMaxWidth(),\n                    value = component.params.spacing,\n                    title = stringResource(R.string.spacing),\n                    valueRange = 0f..50f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = component::setSpacing,\n                    sliderModifier = Modifier\n                        .padding(\n                            top = 14.dp,\n                            start = 12.dp,\n                            end = 12.dp,\n                            bottom = 10.dp\n                        ),\n                    icon = Icons.Rounded.FormatLineSpacing,\n                    shape = ShapeDefaults.extraLarge\n                )\n                EnhancedSliderItem(\n                    modifier = Modifier.fillMaxWidth(),\n                    value = component.params.cornerRadius,\n                    title = stringResource(R.string.corners),\n                    valueRange = 0f..50f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = component::setCornerRadius,\n                    sliderModifier = Modifier\n                        .padding(\n                            top = 14.dp,\n                            start = 12.dp,\n                            end = 12.dp,\n                            bottom = 10.dp\n                        ),\n                    icon = Icons.Rounded.RoundedCorner,\n                    shape = ShapeDefaults.extraLarge\n                )\n                EnhancedSliderItem(\n                    modifier = Modifier.fillMaxWidth(),\n                    value = component.params.outputScaleRatio,\n                    title = stringResource(R.string.output_image_scale),\n                    valueRange = 0.5f..4f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = component::setOutputScaleRatio,\n                    sliderModifier = Modifier\n                        .padding(\n                            top = 14.dp,\n                            start = 12.dp,\n                            end = 12.dp,\n                            bottom = 10.dp\n                        ),\n                    icon = Icons.Rounded.PhotoSizeSelectSmall,\n                    shape = ShapeDefaults.extraLarge\n                )\n                PreferenceRowSwitch(\n                    title = stringResource(id = R.string.disable_rotation),\n                    subtitle = stringResource(id = R.string.disable_rotation_sub),\n                    checked = component.params.disableRotation,\n                    startIcon = Icons.Outlined.SwipeVertical,\n                    onClick = component::setDisableRotation\n                )\n                PreferenceRowSwitch(\n                    title = stringResource(id = R.string.enable_snapping_to_borders),\n                    subtitle = stringResource(id = R.string.enable_snapping_to_borders_sub),\n                    checked = component.params.enableSnapToBorders,\n                    startIcon = Icons.Outlined.PinEnd,\n                    onClick = component::setEnableSnapToBorders\n                )\n                QualitySelector(\n                    imageFormat = component.imageFormat,\n                    quality = component.quality,\n                    onQualityChange = component::setQuality\n                )\n                ImageFormatSelector(\n                    modifier = Modifier.navigationBarsPadding(),\n                    value = component.imageFormat,\n                    quality = component.quality,\n                    onValueChange = component::setImageFormat,\n                    entries = if (component.backgroundColor.alpha != 1f) {\n                        ImageFormatGroup.alphaContainedEntries\n                    } else ImageFormatGroup.entries,\n                    forceEnabled = true\n                )\n            }\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        },\n        canShowScreenData = !component.uris.isNullOrEmpty()\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving || component.isImageLoading,\n        onCancelLoading = component::cancelSaving\n    )\n}\n\n@Composable\nprivate fun rememberHandleDrawable(): Drawable {\n    val context = LocalContext.current\n    val width = with(LocalDensity.current) { 42.dp.roundToPx() }\n    val height = width / 2\n    val backgroundColor = MaterialTheme.colorScheme.tertiary\n    val iconColor = MaterialTheme.colorScheme.onTertiary\n\n    return remember(width, backgroundColor, iconColor, context) {\n        val container = GradientDrawable().apply {\n            shape = GradientDrawable.RECTANGLE\n            setColor(Color.Transparent.toArgb())\n            setSize(width, width)\n        }\n\n        val box = GradientDrawable().apply {\n            mutate()\n            shape = GradientDrawable.RECTANGLE\n            cornerRadius = height / 2f\n            setColor(backgroundColor.toArgb())\n            setSize(width, height)\n        }\n        val icon = AppCompatResources\n            .getDrawable(context, R.drawable.outline_drag_handle_24)!!\n            .mutate()\n\n        DrawableCompat.setTint(icon, iconColor.toArgb())\n\n        LayerDrawable(arrayOf(container, box, icon)).apply {\n            val insetH = 0\n            val insetV = (width - height) / 2\n            val inset = (width * 0.2f).toInt()\n\n            setLayerInset(0, 0, 0, 0, 0)\n            setLayerInset(1, insetH, insetV, insetH, insetV)\n            setLayerInset(2, inset, inset, inset, inset)\n            setBounds(0, 0, width, height)\n        }\n    }\n}"
  },
  {
    "path": "feature/collage-maker/src/main/java/com/t8rin/imagetoolbox/collage_maker/presentation/components/CollageParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.collage_maker.presentation.components\n\ndata class CollageParams(\n    val spacing: Float = 10f,\n    val cornerRadius: Float = 0f,\n    val outputScaleRatio: Float = 2f,\n    val disableRotation: Boolean = true,\n    val enableSnapToBorders: Boolean = true\n)"
  },
  {
    "path": "feature/collage-maker/src/main/java/com/t8rin/imagetoolbox/collage_maker/presentation/screenLogic/CollageMakerComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.collage_maker.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.collages.CollageType\nimport com.t8rin.collages.public.CollageConstants\nimport com.t8rin.imagetoolbox.collage_maker.presentation.components.CollageParams\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass CollageMakerComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val settingsManager: SettingsManager,\n    dispatchersHolder: DispatchersHolder,\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::updateUris)\n\n            _imageFormat.value =\n                settingsManager.settingsState.value.defaultImageFormat ?: imageFormat\n        }\n    }\n\n    private val _aspectRatio: MutableState<DomainAspectRatio> =\n        mutableStateOf(DomainAspectRatio.Numeric(1f, 1f))\n    val aspectRatio by _aspectRatio\n\n    private val _backgroundColor = mutableStateOf(Color.White)\n    val backgroundColor: Color by _backgroundColor\n\n    private val _collageCreationTrigger = mutableStateOf(false)\n    val collageCreationTrigger by _collageCreationTrigger\n\n    private val _collageType: MutableState<CollageType> = mutableStateOf(CollageType.Empty)\n    val collageType by _collageType\n\n    private val _collageBitmap = mutableStateOf<Bitmap?>(null)\n    private val collageBitmap by _collageBitmap\n\n    private val _params = fileController.savable(\n        scope = componentScope,\n        initial = CollageParams()\n    )\n    val params by _params\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Png.Lossless)\n    val imageFormat: ImageFormat by _imageFormat\n\n    private val _quality: MutableState<Quality> = mutableStateOf(Quality.Base())\n    val quality: Quality by _quality\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private var requestedOperation: () -> Unit = {}\n\n    fun setCollageType(collageType: CollageType) {\n        _collageType.update { collageType }\n        registerChanges()\n    }\n\n    fun updateCollageBitmap(bitmap: Bitmap) {\n        _collageCreationTrigger.update { false }\n        _collageBitmap.update { bitmap }\n        requestedOperation()\n    }\n\n    fun updateUris(uris: List<Uri>?) {\n        componentScope.launch {\n            _isImageLoading.update { true }\n            _uris.update { uris }\n            _isImageLoading.update { false }\n        }\n    }\n\n    fun replaceImageAt(index: Int, uri: Uri) {\n        _uris.update { current ->\n            val list = current?.toMutableList() ?: return@update current\n            if (index in list.indices) {\n                list[index] = uri\n                list\n            } else current\n        }\n        registerChanges()\n    }\n\n    fun addImage(uri: Uri) {\n        _uris.update { current ->\n            val list = current ?: emptyList()\n            if (list.size >= CollageConstants.MAX_IMAGE_COUNT) list else list + uri\n        }\n        registerChanges()\n    }\n\n    fun removeImageAt(index: Int) {\n        _uris.update { current ->\n            val list = current?.toMutableList() ?: return@update current\n            if (index in list.indices) {\n                list.removeAt(index)\n                list\n            } else current\n        }\n        registerChanges()\n    }\n\n    fun setQuality(quality: Quality) {\n        _quality.update { quality }\n        registerChanges()\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        registerChanges()\n    }\n\n    fun setOutputScaleRatio(ratio: Float) {\n        _params.update { it.copy(outputScaleRatio = ratio) }\n        registerChanges()\n    }\n\n    fun setDisableRotation(value: Boolean) {\n        _params.update { it.copy(disableRotation = value) }\n        registerChanges()\n    }\n\n    fun setEnableSnapToBorders(value: Boolean) {\n        _params.update { it.copy(enableSnapToBorders = value) }\n        registerChanges()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        _isSaving.update { true }\n        _collageCreationTrigger.update { true }\n        requestedOperation = {\n            savingJob = trackProgress {\n                collageBitmap?.let { image ->\n                    _isSaving.update { true }\n                    val imageInfo = ImageInfo(\n                        width = image.width,\n                        height = image.height,\n                        quality = quality,\n                        imageFormat = imageFormat\n                    )\n                    val result = fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = imageInfo,\n                            originalUri = \"\",\n                            sequenceNumber = null,\n                            data = imageCompressor.compress(\n                                image = image,\n                                imageFormat = imageFormat,\n                                quality = quality\n                            )\n                        ),\n                        keepOriginalMetadata = false,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    )\n\n                    parseSaveResult(result.onSuccess(::registerSave))\n                    _isSaving.update { false }\n                }\n            }\n        }\n    }\n\n    fun performSharing() {\n        _isSaving.update { true }\n        _collageCreationTrigger.update { true }\n        requestedOperation = {\n            collageBitmap?.let { image ->\n                savingJob = trackProgress {\n                    _isSaving.update { true }\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = ImageInfo(\n                            width = image.width,\n                            height = image.height,\n                            quality = quality,\n                            imageFormat = imageFormat\n                        )\n                    )?.let { uri ->\n                        shareProvider.shareUri(\n                            uri = uri,\n                            onComplete = AppToastHost::showConfetti\n                        )\n                    }\n                    _isSaving.update { false }\n                }\n            }\n        }\n    }\n\n    fun cacheImage(\n        onComplete: (Uri) -> Unit,\n    ) {\n        _isSaving.update { true }\n        _collageCreationTrigger.update { true }\n        requestedOperation = {\n            collageBitmap?.let { image ->\n                savingJob = trackProgress {\n                    _isSaving.update { true }\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = ImageInfo(\n                            width = image.width,\n                            height = image.height,\n                            quality = quality,\n                            imageFormat = imageFormat\n                        )\n                    )?.let { uri ->\n                        onComplete(uri.toUri())\n                    }\n                    _isSaving.update { false }\n                }\n            }\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.update { false }\n    }\n\n    fun setBackgroundColor(color: Color) {\n        _backgroundColor.update { color }\n        registerChanges()\n    }\n\n    fun setSpacing(value: Float) {\n        _params.update { it.copy(spacing = value) }\n        registerChanges()\n    }\n\n    fun setCornerRadius(value: Float) {\n        _params.update { it.copy(cornerRadius = value) }\n        registerChanges()\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n    fun setAspectRatio(aspect: DomainAspectRatio) {\n        _aspectRatio.update { aspect }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): CollageMakerComponent\n    }\n\n}"
  },
  {
    "path": "feature/color-library/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/color-library/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.color_library\""
  },
  {
    "path": "feature/color-library/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/color-library/src/main/java/com/t8rin/imagetoolbox/color_library/presentation/ColorLibraryContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_library.presentation\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.plus\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Search\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.colors.util.ColorUtil\nimport com.t8rin.imagetoolbox.color_library.presentation.screenLogic.ColorLibraryComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ColorWithNameItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.isKeyboardVisibleAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\nfun ColorLibraryContent(\n    component: ColorLibraryComponent\n) {\n    val isKeyboardVisible by isKeyboardVisibleAsState()\n    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n    val colors = component.colors\n    val searchKeyword = component.searchKeyword\n    val favoriteColors = component.favoriteColors\n    val settingsState = LocalSettingsState.current\n\n    val copyColor: (Color) -> Unit = { color ->\n        Clipboard.copy(\n            text = if (color.alpha == 1f) {\n                ColorUtil.colorToHex(color)\n            } else {\n                ColorUtil.colorToHexAlpha(color)\n            }.uppercase(),\n            message = R.string.color_copied\n        )\n    }\n\n    val focus = LocalFocusManager.current\n    var isSearching by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    Scaffold(\n        modifier = Modifier\n            .clearFocusOnTap()\n            .nestedScroll(scrollBehavior.nestedScrollConnection),\n        topBar = {\n            EnhancedTopAppBar(\n                type = EnhancedTopAppBarType.Large,\n                scrollBehavior = scrollBehavior,\n                title = {\n                    Text(\n                        text = stringResource(R.string.color_library),\n                        modifier = Modifier.marquee()\n                    )\n                },\n                navigationIcon = {\n                    EnhancedIconButton(\n                        onClick = component.onGoBack\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                            contentDescription = stringResource(R.string.exit)\n                        )\n                    }\n                },\n                actions = {\n                    TopAppBarEmoji()\n                }\n            )\n        },\n        bottomBar = {\n            val insets = WindowInsets.navigationBars.union(\n                WindowInsets.displayCutout.only(\n                    WindowInsetsSides.Horizontal\n                )\n            )\n\n            AnimatedContent(\n                targetState = isSearching,\n                modifier = Modifier.fillMaxWidth()\n            ) { isSearch ->\n                if (isSearch) {\n                    Box(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .drawHorizontalStroke(true)\n                            .background(\n                                MaterialTheme.colorScheme.surfaceContainer\n                            )\n                            .pointerInput(Unit) { detectTapGestures { } }\n                            .windowInsetsPadding(insets)\n                            .padding(16.dp)\n                    ) {\n                        ProvideTextStyle(value = MaterialTheme.typography.bodyLarge) {\n                            RoundedTextField(\n                                maxLines = 1,\n                                hint = {\n                                    Text(stringResource(id = R.string.search_here))\n                                },\n                                keyboardOptions = KeyboardOptions.Default.copy(\n                                    imeAction = ImeAction.Search,\n                                    autoCorrectEnabled = null\n                                ),\n                                value = searchKeyword,\n                                onValueChange = component::updateSearch,\n                                endIcon = {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            if (searchKeyword.isNotBlank()) {\n                                                component.clearSearch()\n                                            } else {\n                                                isSearching = false\n                                                focus.clearFocus()\n                                            }\n                                        },\n                                        modifier = Modifier.padding(end = 4.dp)\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.Close,\n                                            contentDescription = stringResource(R.string.close),\n                                            tint = MaterialTheme.colorScheme.onSurface.copy(\n                                                if (it) 1f else 0.5f\n                                            )\n                                        )\n                                    }\n                                },\n                                shape = ShapeDefaults.circle\n                            )\n                        }\n                    }\n                } else {\n                    Box(\n                        modifier = Modifier\n                            .windowInsetsPadding(insets)\n                            .padding(16.dp)\n                            .fillMaxWidth()\n                    ) {\n                        EnhancedFloatingActionButton(\n                            onClick = { isSearching = true },\n                            modifier = Modifier.align(\n                                settingsState.fabAlignment.takeIf { it != Alignment.BottomCenter }\n                                    ?: Alignment.BottomEnd\n                            )\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Search,\n                                contentDescription = null\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    ) { contentPadding ->\n        AnimatedContent(\n            targetState = colors.isNotEmpty(),\n            modifier = Modifier.fillMaxSize()\n        ) { isNotEmpty ->\n            if (isNotEmpty) {\n                val reverseLayout = searchKeyword.isNotEmpty() && isKeyboardVisible\n\n                LazyVerticalGrid(\n                    contentPadding = contentPadding + PaddingValues(12.dp),\n                    verticalArrangement = Arrangement.spacedBy(\n                        space = 4.dp,\n                        alignment = if (reverseLayout) {\n                            Alignment.Bottom\n                        } else {\n                            Alignment.Top\n                        }\n                    ),\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    flingBehavior = enhancedFlingBehavior(),\n                    columns = GridCells.Adaptive(180.dp),\n                    modifier = Modifier.fillMaxSize()\n                ) {\n                    items(\n                        items = colors,\n                        key = { it.toString() }\n                    ) { colorWithName ->\n                        ColorWithNameItem(\n                            isFavorite = colorWithName.name in favoriteColors,\n                            color = colorWithName.color,\n                            name = colorWithName.name,\n                            onToggleFavorite = { component.toggleFavoriteColor(colorWithName) },\n                            onCopy = { copyColor(colorWithName.color) },\n                            modifier = Modifier.animateItem()\n                        )\n                    }\n                }\n            } else if (isSearching) {\n                Column(\n                    modifier = Modifier\n                        .padding(contentPadding)\n                        .fillMaxSize(),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    Spacer(Modifier.weight(1f))\n                    Text(\n                        text = stringResource(R.string.nothing_found_by_search),\n                        fontSize = 18.sp,\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier.padding(\n                            start = 24.dp,\n                            end = 24.dp,\n                            top = 8.dp,\n                            bottom = 8.dp\n                        )\n                    )\n                    Icon(\n                        imageVector = Icons.Rounded.SearchOff,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .weight(2f)\n                            .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                            .fillMaxSize()\n                    )\n                    Spacer(Modifier.weight(1f))\n                }\n            } else {\n                Box(\n                    modifier = Modifier\n                        .padding(contentPadding)\n                        .fillMaxSize(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    EnhancedLoadingIndicator()\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/color-library/src/main/java/com/t8rin/imagetoolbox/color_library/presentation/components/FavoriteColors.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_library.presentation.components\n\ndata class FavoriteColors(\n    val colors: Set<String> = emptySet()\n)"
  },
  {
    "path": "feature/color-library/src/main/java/com/t8rin/imagetoolbox/color_library/presentation/screenLogic/ColorLibraryComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_library.presentation.screenLogic\n\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshotFlow\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.colors.parser.ColorNameParser\nimport com.t8rin.colors.parser.ColorWithName\nimport com.t8rin.imagetoolbox.color_library.presentation.components.FavoriteColors\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.collectLatest\n\nclass ColorLibraryComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private var baseColors: List<ColorWithName> = emptyList()\n\n    private val _colors: MutableState<List<ColorWithName>> = mutableStateOf(emptyList())\n    val colors by _colors\n\n    private val _searchKeyword: MutableState<String> = mutableStateOf(\"\")\n    val searchKeyword by _searchKeyword\n\n    private val _favoriteColors = fileController.savable(\n        scope = componentScope,\n        initial = FavoriteColors(),\n    )\n    val favoriteColors get() = _favoriteColors.get().colors\n\n    init {\n        componentScope.launch {\n            setColors(ColorNameParser.colorNames.values.sortedBy { it.name }.toList())\n\n            snapshotFlow { favoriteColors }\n                .collectLatest { favorite ->\n                    setColors(\n                        baseColors.sortedBy { it.name !in favorite }\n                    )\n                    if (searchKeyword.isNotBlank()) {\n                        updateSearch()\n                    }\n                }\n        }\n    }\n\n    private fun setColors(newColors: List<ColorWithName>) {\n        baseColors = newColors\n        _colors.value = newColors\n    }\n\n    fun updateSearch(keyword: String) {\n        _searchKeyword.value = keyword\n\n        if (keyword.isBlank()) {\n            updateSearch()\n            return\n        }\n\n        debouncedImageCalculation(\n            delay = 350,\n            action = { updateSearch() }\n        )\n    }\n\n    private fun updateSearch() {\n        if (searchKeyword.isBlank()) {\n            _colors.value = baseColors\n        } else {\n            _colors.value = baseColors.filter {\n                it.name.contains(\n                    other = searchKeyword,\n                    ignoreCase = true\n                ) || searchKeyword.contains(\n                    other = it.name,\n                    ignoreCase = true\n                ) || it.color.toHex().contains(\n                    other = searchKeyword,\n                    ignoreCase = true\n                )\n            }\n        }\n    }\n\n    fun clearSearch() {\n        updateSearch(\"\")\n    }\n\n    fun toggleFavoriteColor(color: ColorWithName) {\n        _favoriteColors.update { it.copy(colors = it.colors.toggle(color.name)) }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n        ): ColorLibraryComponent\n    }\n\n}"
  },
  {
    "path": "feature/color-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/color-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.color_tools\""
  },
  {
    "path": "feature/color-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest />"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/ColorToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PushPin\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material.icons.rounded.PushPin\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.gigamole.composefadingedges.FadingEdgesGravity\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.color_tools.presentation.components.ColorHarmonies\nimport com.t8rin.imagetoolbox.color_tools.presentation.components.ColorHistogram\nimport com.t8rin.imagetoolbox.color_tools.presentation.components.ColorInfo\nimport com.t8rin.imagetoolbox.color_tools.presentation.components.ColorMixing\nimport com.t8rin.imagetoolbox.color_tools.presentation.components.ColorShading\nimport com.t8rin.imagetoolbox.color_tools.presentation.screenLogic.ColorToolsComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.negativePadding\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\nfun ColorToolsContent(\n    component: ColorToolsComponent\n) {\n    val themeState = LocalDynamicThemeState.current\n    val settingsState = LocalSettingsState.current\n    val allowChangeColor = settingsState.allowChangeColorByImage\n\n    val appColorTuple = rememberAppColorTuple()\n\n    val selectedColor = component.selectedColor.takeOrElse { appColorTuple.primary }\n\n    LaunchedEffect(selectedColor) {\n        if (allowChangeColor) {\n            themeState.updateColor(selectedColor)\n        }\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val isPinned = component.isPinned\n\n    val colorSelector = @Composable {\n        ColorRowSelector(\n            value = selectedColor,\n            onValueChange = component::updateSelectedColor,\n            modifier = Modifier\n                .fillMaxWidth()\n                .container(\n                    color = if (isPinned && !isPortrait) {\n                        MaterialTheme.colorScheme.surface\n                    } else {\n                        Color.Unspecified\n                    },\n                    shape = ShapeDefaults.large\n                ),\n            icon = Icons.Rounded.Palette,\n            title = stringResource(R.string.selected_color),\n            topEndIcon = {\n                EnhancedIconButton(\n                    onClick = {\n                        component.updateIsPinned(!isPinned)\n                    }\n                ) {\n                    Icon(\n                        imageVector = if (isPinned) Icons.Rounded.PushPin else Icons.Outlined.PushPin,\n                        contentDescription = null\n                    )\n                }\n            }\n        )\n    }\n\n    key(isPinned) {\n        AdaptiveLayoutScreen(\n            title = {\n                Text(\n                    text = stringResource(R.string.color_tools),\n                    modifier = Modifier.marquee()\n                )\n            },\n            shouldDisableBackHandler = true,\n            onGoBack = component.onGoBack,\n            actions = {},\n            topAppBarPersistentActions = {\n                TopAppBarEmoji()\n            },\n            imagePreview = {\n                Column(\n                    modifier = if (isPortrait) {\n                        Modifier\n                            .negativePadding(horizontal = 20.dp)\n                            .fadingEdges(\n                                scrollableState = null,\n                                isVertical = true,\n                                length = 16.dp,\n                                gravity = FadingEdgesGravity.End\n                            )\n                            .background(MaterialTheme.colorScheme.surface)\n                            .padding(20.dp)\n                    } else {\n                        Modifier\n                    }\n                ) {\n                    colorSelector()\n                }\n            },\n            useRegularStickyHeader = true,\n            controls = { listState ->\n                LaunchedEffect(isPinned) {\n                    if (isPinned) {\n                        listState.scrollToItem(0)\n                    }\n                }\n\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(8.dp)\n                ) {\n                    if (!isPinned) {\n                        if (isPortrait) {\n                            Spacer(modifier = Modifier.height(12.dp))\n                        }\n                        colorSelector()\n                        Spacer(modifier = Modifier.fillMaxWidth())\n                    }\n                    ColorInfo(\n                        selectedColor = selectedColor,\n                        onColorChange = component::updateSelectedColor\n                    )\n                    ColorMixing(\n                        selectedColor = selectedColor,\n                        appColorTuple = appColorTuple\n                    )\n                    ColorHarmonies(\n                        selectedColor = selectedColor\n                    )\n                    ColorShading(\n                        selectedColor = selectedColor\n                    )\n                    ColorHistogram()\n                }\n            },\n            buttons = {},\n            placeImagePreview = isPinned,\n            canShowScreenData = true\n        )\n    }\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorHarmonies.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BarChart\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ColorWithNameItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun ColorHarmonies(\n    selectedColor: Color,\n) {\n    var selectedHarmony by rememberSaveable {\n        mutableStateOf(HarmonyType.COMPLEMENTARY)\n    }\n    val harmonies by remember(selectedColor, selectedHarmony) {\n        derivedStateOf {\n            selectedColor.applyHarmony(selectedHarmony)\n        }\n    }\n\n    ExpandableItem(\n        visibleContent = {\n            TitleItem(\n                text = stringResource(R.string.color_harmonies),\n                icon = Icons.Rounded.BarChart,\n                modifier = Modifier.padding(12.dp)\n            )\n        },\n        expandableContent = {\n            Column(\n                modifier = Modifier.padding(\n                    start = 16.dp,\n                    end = 16.dp,\n                    bottom = 8.dp\n                ),\n            ) {\n                Row(\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    HarmonyType.entries.forEach {\n                        EnhancedChip(\n                            selected = it == selectedHarmony,\n                            onClick = { selectedHarmony = it },\n                            selectedColor = MaterialTheme.colorScheme.secondaryContainer,\n                            modifier = Modifier.weight(1f)\n                        ) {\n                            Icon(\n                                imageVector = it.icon(),\n                                contentDescription = null\n                            )\n                        }\n                    }\n                }\n                Spacer(Modifier.height(8.dp))\n                AnimatedContent(\n                    targetState = selectedHarmony,\n                    transitionSpec = {\n                        fadeIn() togetherWith fadeOut()\n                    }\n                ) {\n                    Text(it.title())\n                }\n                Spacer(Modifier.height(8.dp))\n                AnimatedContent(\n                    targetState = harmonies,\n                    modifier = Modifier.fillMaxWidth(),\n                    transitionSpec = {\n                        fadeIn() togetherWith fadeOut()\n                    }\n                ) { harmonies ->\n                    Row(\n                        horizontalArrangement = Arrangement.spacedBy(4.dp)\n                    ) {\n                        harmonies.forEachIndexed { index, color ->\n                            val shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = harmonies.size,\n                                vertical = false\n                            )\n                            ColorWithNameItem(\n                                color = color,\n                                containerShape = shape,\n                                onCopy = {\n                                    Clipboard.copy(\n                                        text = getFormattedColor(color),\n                                        message = R.string.color_copied\n                                    )\n                                },\n                                modifier = Modifier\n                                    .heightIn(min = 120.dp)\n                                    .weight(1f)\n                            )\n                        }\n                    }\n                }\n            }\n        },\n        shape = ShapeDefaults.extraLarge,\n        initialState = false\n    )\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorHarmoniesUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Analogous\nimport com.t8rin.imagetoolbox.core.resources.icons.AnalogousComplementary\nimport com.t8rin.imagetoolbox.core.resources.icons.Complementary\nimport com.t8rin.imagetoolbox.core.resources.icons.SplitComplementary\nimport com.t8rin.imagetoolbox.core.resources.icons.SquareHarmony\nimport com.t8rin.imagetoolbox.core.resources.icons.Tetradic\nimport com.t8rin.imagetoolbox.core.resources.icons.Triadic\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport android.graphics.Color as AndroidColor\n\nfun Color.applyHarmony(\n    type: HarmonyType\n): List<Color> {\n    val (h, s, v) = toHSV()\n    return when (type) {\n        HarmonyType.COMPLEMENTARY -> listOf(\n            hsvToColor(h, s, v),\n            hsvToColor((h + 180) % 360, s, v)\n        )\n\n        HarmonyType.ANALOGOUS -> listOf(\n            hsvToColor(h, s, v),\n            hsvToColor((h + 30) % 360, s, v),\n            hsvToColor((h - 30 + 360) % 360, s, v)\n        )\n\n        HarmonyType.ANALOGOUS_COMPLEMENTARY -> listOf(\n            hsvToColor(h, s, v),\n            hsvToColor((h + 30) % 360, s, v),\n            hsvToColor((h - 30 + 360) % 360, s, v),\n            hsvToColor((h + 180) % 360, s, v)\n        )\n\n        HarmonyType.TRIADIC -> listOf(\n            hsvToColor(h, s, v),\n            hsvToColor((h + 120) % 360, s, v),\n            hsvToColor((h - 120 + 360) % 360, s, v)\n        )\n\n        HarmonyType.SPLIT_COMPLEMENTARY -> listOf(\n            hsvToColor(h, s, v),\n            hsvToColor((h + 150) % 360, s, v),\n            hsvToColor((h - 150 + 360) % 360, s, v)\n        )\n\n        HarmonyType.TETRADIC -> listOf(\n            hsvToColor(h, s, v),\n            hsvToColor((h + 30) % 360, s, v),\n            hsvToColor((h + 180) % 360, s, v),\n            hsvToColor((h + 210) % 360, s, v)\n        )\n\n        HarmonyType.SQUARE -> listOf(\n            hsvToColor(h, s, v),\n            hsvToColor((h + 90) % 360, s, v),\n            hsvToColor((h + 180) % 360, s, v),\n            hsvToColor((h + 270) % 360, s, v)\n        )\n    }.map { it.copy(alpha) }\n}\n\nenum class HarmonyType {\n    COMPLEMENTARY,\n    ANALOGOUS,\n    ANALOGOUS_COMPLEMENTARY,\n    TRIADIC,\n    SPLIT_COMPLEMENTARY,\n    TETRADIC,\n    SQUARE\n}\n\n@Composable\nfun HarmonyType.title(): String = when (this) {\n    HarmonyType.COMPLEMENTARY -> stringResource(R.string.harmony_complementary)\n    HarmonyType.ANALOGOUS -> stringResource(R.string.harmony_analogous)\n    HarmonyType.TRIADIC -> stringResource(R.string.harmony_triadic)\n    HarmonyType.SPLIT_COMPLEMENTARY -> stringResource(R.string.harmony_split_complementary)\n    HarmonyType.TETRADIC -> stringResource(R.string.harmony_tetradic)\n    HarmonyType.SQUARE -> stringResource(R.string.harmony_square)\n    HarmonyType.ANALOGOUS_COMPLEMENTARY -> stringResource(R.string.harmony_analogous_complementary)\n}\n\nfun HarmonyType.icon(): ImageVector = when (this) {\n    HarmonyType.COMPLEMENTARY -> Icons.Filled.Complementary\n    HarmonyType.ANALOGOUS -> Icons.Filled.Analogous\n    HarmonyType.ANALOGOUS_COMPLEMENTARY -> Icons.Filled.AnalogousComplementary\n    HarmonyType.TRIADIC -> Icons.Filled.Triadic\n    HarmonyType.SPLIT_COMPLEMENTARY -> Icons.Filled.SplitComplementary\n    HarmonyType.TETRADIC -> Icons.Filled.Tetradic\n    HarmonyType.SQUARE -> Icons.Filled.SquareHarmony\n}\n\nfun Color.toHSV(): FloatArray {\n    val hsv = FloatArray(3)\n    AndroidColor.colorToHSV(toArgb(), hsv)\n    return hsv\n}\n\nfun hsvToColor(\n    h: Float,\n    s: Float,\n    v: Float\n): Color {\n    return AndroidColor.HSVToColor(floatArrayOf(h, s, v)).toColor()\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorHistogram.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.histogram.HistogramType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AreaChart\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.image.HistogramChart\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun ColorHistogram() {\n    var imageUri by rememberSaveable {\n        mutableStateOf<Uri?>(null)\n    }\n\n    ExpandableItem(\n        visibleContent = {\n            TitleItem(\n                text = stringResource(R.string.histogram),\n                icon = Icons.Rounded.AreaChart,\n                modifier = Modifier.padding(12.dp)\n            )\n        },\n        expandableContent = {\n            Column(\n                modifier = Modifier.padding(\n                    start = 16.dp,\n                    end = 16.dp,\n                    bottom = 8.dp\n                )\n            ) {\n                ImageSelector(\n                    value = imageUri,\n                    onValueChange = {\n                        imageUri = it\n                    },\n                    subtitle = stringResource(R.string.image_for_histogram),\n                    shape = ShapeDefaults.default,\n                    color = MaterialTheme.colorScheme.surface\n                )\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(8.dp)\n                ) {\n                    HistogramChart(\n                        model = imageUri,\n                        modifier = Modifier\n                            .padding(top = 16.dp)\n                            .fillMaxWidth()\n                            .height(250.dp)\n                            .background(\n                                color = MaterialTheme.colorScheme.background,\n                                shape = ShapeDefaults.extraSmall\n                            ),\n                        initialType = HistogramType.RGB,\n                        onSwapType = null,\n                        linesThickness = 1.dp,\n                        bordersShape = ShapeDefaults.pressed\n                    )\n                    HistogramChart(\n                        model = imageUri,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .height(250.dp)\n                            .background(\n                                color = MaterialTheme.colorScheme.background,\n                                shape = ShapeDefaults.extraSmall\n                            ),\n                        initialType = HistogramType.Brightness,\n                        onSwapType = null,\n                        linesThickness = 1.dp,\n                        bordersShape = ShapeDefaults.pressed\n                    )\n                    HistogramChart(\n                        model = imageUri,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .height(250.dp)\n                            .background(\n                                color = MaterialTheme.colorScheme.background,\n                                shape = ShapeDefaults.extraSmall\n                            ),\n                        initialType = HistogramType.Camera,\n                        onSwapType = null,\n                        linesThickness = 1.dp,\n                        bordersShape = ShapeDefaults.pressed\n                    )\n                }\n            }\n        },\n        shape = ShapeDefaults.extraLarge,\n        initialState = false\n    )\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Info\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ColorWithNameItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun ColorInfo(\n    selectedColor: Color,\n    onColorChange: (Color) -> Unit,\n) {\n    val scope = rememberCoroutineScope()\n\n    ExpandableItem(\n        visibleContent = {\n            TitleItem(\n                text = stringResource(R.string.color_info),\n                icon = Icons.Rounded.Info,\n                modifier = Modifier.padding(12.dp)\n            )\n        },\n        expandableContent = {\n            Column(\n                modifier = Modifier.padding(\n                    start = 16.dp,\n                    end = 16.dp,\n                    bottom = 8.dp\n                ),\n            ) {\n                ColorWithNameItem(\n                    color = selectedColor,\n                    onCopy = {\n                        Clipboard.copy(\n                            text = getFormattedColor(selectedColor),\n                            message = R.string.color_copied\n                        )\n                    }\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n                var wasNull by rememberSaveable {\n                    mutableStateOf(false)\n                }\n                var resetJob by remember {\n                    mutableStateOf<Job?>(null)\n                }\n                ColorInfoDisplay(\n                    value = selectedColor,\n                    onValueChange = {\n                        wasNull = it == null\n\n                        onColorChange(it ?: selectedColor)\n                    },\n                    onCopy = {\n                        Clipboard.copy(\n                            text = it,\n                            message = R.string.color_copied\n                        )\n                    },\n                    onLoseFocus = {\n                        resetJob?.cancel()\n                        resetJob = scope.launch {\n                            delay(100)\n                            if (wasNull) {\n                                selectedColor.let {\n                                    onColorChange(Color.White)\n                                    delay(100)\n                                    onColorChange(it)\n                                }\n                            }\n                        }\n                    }\n                )\n            }\n        },\n        shape = ShapeDefaults.extraLarge,\n        initialState = true\n    )\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorInfoDisplay.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.focus.onFocusChanged\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.unit.dp\nimport androidx.core.graphics.ColorUtils\nimport com.t8rin.colors.parser.ColorNameParser\nimport com.t8rin.colors.util.ColorUtil\nimport com.t8rin.colors.util.HexUtil\nimport com.t8rin.colors.util.HexVisualTransformation\nimport com.t8rin.colors.util.hexRegexSingleChar\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport kotlinx.coroutines.delay\nimport kotlin.math.roundToInt\nimport android.graphics.Color as AndroidColor\n\n@Composable\nfun ColorInfoDisplay(\n    value: Color,\n    onValueChange: (Color?) -> Unit,\n    onCopy: (String) -> Unit,\n    onLoseFocus: () -> Unit\n) {\n    var hexColor by remember(value) { mutableStateOf(value.toHex()) }\n    var rgb by remember(value) { mutableStateOf(value.toRGB()) }\n    var hsv by remember(value) { mutableStateOf(value.toHSVString()) }\n    var hsl by remember(value) { mutableStateOf(value.toHSL()) }\n    var cmyk by remember(value) { mutableStateOf(value.toCMYK()) }\n\n    Column(\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        Row(\n            horizontalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            ColorEditableField(\n                label = \"HEX\",\n                value = hexColor.removePrefix(\"#\"),\n                onCopy = onCopy,\n                visualTransformation = HexVisualTransformation(false),\n                onValueChange = { newHex ->\n                    val newHex = newHex.replace(\"#\", \"\")\n\n                    if (newHex.length <= 8) {\n                        var validHex = true\n\n                        for (index in newHex.indices) {\n                            validHex =\n                                hexRegexSingleChar.matches(newHex[index].toString())\n                            if (!validHex) break\n                        }\n\n                        if (validHex) {\n                            hexColor = \"#${newHex.uppercase()}\"\n                            val color = newHex.toColor()\n                            onValueChange(color)\n                        }\n                    }\n                },\n                modifier = Modifier.weight(1f),\n                onLoseFocus = onLoseFocus\n            )\n            ColorEditableField(\n                label = \"RGB\",\n                value = rgb,\n                onValueChange = { newRgb ->\n                    rgb = newRgb\n                    val color = rgbToColor(newRgb)\n                    onValueChange(color)\n                },\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f),\n                onLoseFocus = onLoseFocus\n            )\n        }\n\n        Row(\n            horizontalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            ColorEditableField(\n                label = \"HSV\",\n                value = hsv,\n                onValueChange = { newHsv ->\n                    hsv = newHsv\n                    val color = hsvToColor(newHsv)\n                    onValueChange(color)\n                },\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f),\n                onLoseFocus = onLoseFocus\n            )\n            ColorEditableField(\n                label = \"HSL\",\n                value = hsl,\n                onValueChange = { newHsl ->\n                    hsl = newHsl\n                    val color = hslToColor(newHsl)\n                    onValueChange(color)\n                },\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f),\n                onLoseFocus = onLoseFocus\n            )\n        }\n\n        ColorEditableField(\n            label = \"CMYK\",\n            value = cmyk,\n            onValueChange = { newCmyk ->\n                cmyk = newCmyk\n                val color = cmykToColor(newCmyk)\n                onValueChange(color)\n            },\n            onCopy = onCopy,\n            modifier = Modifier.fillMaxWidth(),\n            onLoseFocus = onLoseFocus\n        )\n\n        var name by remember {\n            mutableStateOf(ColorNameParser.parseColorName(color = value))\n        }\n\n        var isFocused by remember { mutableStateOf(false) }\n\n        LaunchedEffect(value, isFocused) {\n            if (!isFocused) {\n                delay(200)\n                name = ColorNameParser.parseColorName(value)\n            }\n        }\n\n        ColorEditableField(\n            label = stringResource(R.string.name),\n            value = name,\n            onValueChange = { newName ->\n                name = newName\n                onValueChange(\n                    ColorNameParser.parseColorFromNameSingle(newName)\n                )\n            },\n            onCopy = onCopy,\n            modifier = Modifier\n                .fillMaxWidth()\n                .onFocusChanged { focusState ->\n                    isFocused = focusState.isFocused\n                },\n            onLoseFocus = onLoseFocus\n        )\n    }\n}\n\ninternal fun getFormattedColor(color: Color): String {\n    return if (color.alpha == 1f) {\n        ColorUtil.colorToHex(color)\n    } else {\n        ColorUtil.colorToHexAlpha(color)\n    }.uppercase()\n}\n\n@Composable\nprivate fun ColorEditableField(\n    label: String,\n    value: String,\n    onLoseFocus: () -> Unit,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    onValueChange: (String) -> Unit,\n    onCopy: (String) -> Unit,\n    modifier: Modifier\n) {\n    RoundedTextField(\n        modifier = modifier,\n        value = value,\n        visualTransformation = visualTransformation,\n        onValueChange = onValueChange,\n        onLoseFocusTransformation = {\n            onLoseFocus()\n            this\n        },\n        label = {\n            Text(label)\n        },\n        singleLine = true,\n        endIcon = {\n            EnhancedIconButton(\n                onClick = { onCopy(value) },\n                forceMinimumInteractiveComponentSize = false,\n                modifier = Modifier.size(36.dp)\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.ContentCopy,\n                    contentDescription = null\n                )\n            }\n        }\n    )\n}\n\nfun Color.toHex(): String {\n    val red = (red * 255).roundToInt()\n    val green = (green * 255).roundToInt()\n    val blue = (blue * 255).roundToInt()\n    return String.format(\"#%02X%02X%02X\", red, green, blue)\n}\n\nfun String.toColor(): Color? {\n    return runCatching {\n        HexUtil.hexToColor(this)\n    }.getOrNull()\n}\n\nfun Color.toRGB(): String {\n    val r = (red * 255).roundToInt()\n    val g = (green * 255).roundToInt()\n    val b = (blue * 255).roundToInt()\n    return \"$r, $g, $b\"\n}\n\nfun rgbToColor(rgb: String): Color? = runCatching {\n    val (r, g, b) = rgb.split(\",\").map { it.trim().toInt() }\n    Color(r / 255f, g / 255f, b / 255f)\n}.getOrNull()\n\nfun Color.toHSVString(): String {\n    val hsv = FloatArray(3)\n    AndroidColor.colorToHSV(this.toArgb(), hsv)\n    return \"${hsv[0].roundToInt()}, ${(hsv[1] * 100).roundToInt()}, ${(hsv[2] * 100).roundToInt()}\"\n}\n\nfun hsvToColor(hsv: String): Color? = runCatching {\n    val (h, s, v) = hsv.split(\",\")\n        .map { it.trim().toInt() }\n    val colorInt = AndroidColor.HSVToColor(floatArrayOf(h.toFloat(), s / 100f, v / 100f))\n    Color(colorInt)\n}.getOrNull()\n\nfun Color.toHSL(): String {\n    val hsl = FloatArray(3)\n    ColorUtils.colorToHSL(this.toArgb(), hsl)\n    return \"${hsl[0].roundToInt()}, ${(hsl[1] * 100).roundToInt()}, ${(hsl[2] * 100).roundToInt()}\"\n}\n\nfun hslToColor(hsl: String): Color? = runCatching {\n    val (h, s, l) = hsl.split(\",\")\n        .map { it.trim().toInt() }\n    val colorInt = ColorUtils.HSLToColor(floatArrayOf(h.toFloat(), s / 100f, l / 100f))\n    Color(colorInt)\n}.getOrNull()\n\nfun Color.toCMYK(): String {\n    val k = (1 - maxOf(red, green, blue))\n    val c = ((1 - red - k) / (1 - k)).takeIf { it.isFinite() } ?: 0f\n    val m = ((1 - green - k) / (1 - k)).takeIf { it.isFinite() } ?: 0f\n    val y = ((1 - blue - k) / (1 - k)).takeIf { it.isFinite() } ?: 0f\n    return \"${(c * 100).roundToInt()}, ${(m * 100).roundToInt()}, ${(y * 100).roundToInt()}, ${(k * 100).roundToInt()}\"\n}\n\nfun cmykToColor(cmyk: String): Color? = runCatching {\n    val (c, m, y, k) = cmyk.split(\",\").map { it.trim().toInt() / 100f }\n    val r = 255 * (1 - c) * (1 - k)\n    val g = 255 * (1 - m) * (1 - k)\n    val b = 255 * (1 - y) * (1 - k)\n    Color(r / 255f, g / 255f, b / 255f)\n}.getOrNull()"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorMixing.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Blender\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ColorWithNameItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun ColorMixing(\n    selectedColor: Color,\n    appColorTuple: ColorTuple,\n) {\n    var mixingVariation by rememberSaveable {\n        mutableIntStateOf(3)\n    }\n    var colorToMix by rememberSaveable(\n        stateSaver = ColorSaver\n    ) {\n        mutableStateOf(appColorTuple.tertiary ?: Color.Yellow)\n    }\n    val mixedColors by remember(selectedColor, mixingVariation, colorToMix) {\n        derivedStateOf {\n            selectedColor.mixWith(\n                color = colorToMix,\n                variations = mixingVariation,\n                maxPercent = 1f\n            )\n        }\n    }\n\n    ExpandableItem(\n        visibleContent = {\n            TitleItem(\n                text = stringResource(R.string.color_mixing),\n                icon = Icons.Rounded.Blender,\n                modifier = Modifier.padding(12.dp)\n            )\n        },\n        expandableContent = {\n            Column(\n                modifier = Modifier.padding(\n                    start = 16.dp,\n                    end = 16.dp,\n                    bottom = 8.dp\n                ),\n            ) {\n                ColorRowSelector(\n                    value = colorToMix,\n                    onValueChange = { colorToMix = it },\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            color = MaterialTheme.colorScheme.surface,\n                            shape = ShapeDefaults.top\n                        ),\n                    title = stringResource(R.string.color_to_mix)\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                EnhancedSliderItem(\n                    value = mixingVariation,\n                    title = stringResource(R.string.variation),\n                    valueRange = 2f..20f,\n                    onValueChange = { mixingVariation = it.roundToInt() },\n                    internalStateTransformation = { it.roundToInt() },\n                    shape = ShapeDefaults.bottom,\n                    behaveAsContainer = true,\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    steps = 17\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n                Column(\n                    modifier = Modifier.fillMaxWidth(),\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    mixedColors.forEachIndexed { index, color ->\n                        ColorWithNameItem(\n                            color = color,\n                            containerShape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = mixedColors.size\n                            ),\n                            onCopy = {\n                                Clipboard.copy(\n                                    text = getFormattedColor(color),\n                                    message = R.string.color_copied\n                                )\n                            }\n                        )\n                    }\n                }\n            }\n        },\n        shape = ShapeDefaults.extraLarge,\n        initialState = false\n    )\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorMixingUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\n\nfun Color.mixWith(\n    color: Color,\n    variations: Int,\n    maxPercent: Float = 1f\n): List<Color> = List(variations) {\n    val percent = it / ((variations + (1f - maxPercent) * 10) - 1)\n    this.blend(color, percent)\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/components/ColorShading.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Swatch\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ColorWithNameItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun ColorShading(\n    selectedColor: Color\n) {\n    var shadingVariation by rememberSaveable {\n        mutableIntStateOf(5)\n    }\n    val shades by remember(selectedColor, shadingVariation) {\n        derivedStateOf {\n            selectedColor.mixWith(\n                color = Color.Black,\n                variations = shadingVariation,\n                maxPercent = 0.9f\n            )\n        }\n    }\n    val tones by remember(selectedColor, shadingVariation) {\n        derivedStateOf {\n            selectedColor.mixWith(\n                color = Color(0xff8e918f),\n                variations = shadingVariation,\n                maxPercent = 0.9f\n            )\n        }\n    }\n    val tints by remember(selectedColor, shadingVariation) {\n        derivedStateOf {\n            selectedColor.mixWith(\n                color = Color.White,\n                variations = shadingVariation,\n                maxPercent = 0.8f\n            )\n        }\n    }\n\n    ExpandableItem(\n        visibleContent = {\n            TitleItem(\n                text = stringResource(R.string.color_shading),\n                icon = Icons.Rounded.Swatch,\n                modifier = Modifier.padding(12.dp)\n            )\n        },\n        expandableContent = {\n            Column(\n                modifier = Modifier.padding(\n                    start = 16.dp,\n                    end = 16.dp,\n                    bottom = 8.dp\n                ),\n            ) {\n                EnhancedSliderItem(\n                    value = shadingVariation,\n                    title = stringResource(R.string.variation),\n                    valueRange = 2f..20f,\n                    onValueChange = { shadingVariation = it.roundToInt() },\n                    internalStateTransformation = { it.roundToInt() },\n                    behaveAsContainer = true,\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    steps = 17\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n                Row(\n                    horizontalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    listOf(\n                        tints to R.string.tints,\n                        tones to R.string.tones,\n                        shades to R.string.shades\n                    ).forEach { (data, title) ->\n                        Column(\n                            modifier = Modifier.weight(1f),\n                            verticalArrangement = Arrangement.spacedBy(4.dp),\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            Text(text = stringResource(title))\n                            data.forEachIndexed { index, color ->\n                                ColorWithNameItem(\n                                    color = color,\n                                    containerShape = ShapeDefaults.byIndex(\n                                        index = index,\n                                        size = data.size\n                                    ),\n                                    onCopy = {\n                                        Clipboard.copy(\n                                            text = getFormattedColor(color),\n                                            message = R.string.color_copied\n                                        )\n                                    },\n                                    modifier = Modifier.heightIn(min = 100.dp)\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        shape = ShapeDefaults.extraLarge,\n        initialState = false\n    )\n}"
  },
  {
    "path": "feature/color-tools/src/main/java/com/t8rin/imagetoolbox/color_tools/presentation/screenLogic/ColorToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.color_tools.presentation.screenLogic\n\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass ColorToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _selectedColor: MutableState<Color> = mutableStateOf(Color.Unspecified)\n    val selectedColor: Color by _selectedColor\n\n    private val _isPinned = fileController.savable(\n        delay = 750,\n        scope = componentScope,\n        initial = false,\n        key = \"ColorToolsComponent\"\n    )\n    val isPinned: Boolean by _isPinned\n\n    fun updateIsPinned(isPinned: Boolean) {\n        _isPinned.update { isPinned }\n    }\n\n    fun updateSelectedColor(newColor: Color) {\n        _selectedColor.update { newColor }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n        ): ColorToolsComponent\n    }\n\n}"
  },
  {
    "path": "feature/compare/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/compare/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.compare\"\n\ndependencies {\n    implementation(projects.lib.opencvTools)\n}"
  },
  {
    "path": "feature/compare/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/CompareContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.dynamic.theme.extractPrimaryColor\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareScreenContent\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareScreenTopAppBar\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareShareSheet\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareType\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.model.ifNotEmpty\nimport com.t8rin.imagetoolbox.feature.compare.presentation.screenLogic.CompareComponent\nimport kotlinx.coroutines.delay\n\n\n@Composable\nfun CompareContent(\n    component: CompareComponent\n) {\n    val settingsState = LocalSettingsState.current\n\n    val themeState = LocalDynamicThemeState.current\n    val allowChangeColor = settingsState.allowChangeColorByImage\n\n    LaunchedEffect(component.bitmapData) {\n        component.bitmapData?.ifNotEmpty { before, after ->\n            if (allowChangeColor) {\n                delay(100L) //delay to perform screen rotation\n                themeState.updateColor(\n                    after.image.extractPrimaryColor()\n                        .blend(before.image.extractPrimaryColor(), 0.5f)\n                )\n            }\n        }\n    }\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        if (uris.size != 2) {\n            AppToastHost.showFailureToast(R.string.pick_two_images)\n        } else {\n            component.updateUris(\n                uris = uris[0] to uris[1],\n                onFailure = {\n                    AppToastHost.showFailureToast(R.string.something_went_wrong)\n                }\n            )\n        }\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialComparableUris != null\n    )\n\n    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showShareSheet by rememberSaveable { mutableStateOf(false) }\n    var isLabelsEnabled by rememberSaveable {\n        mutableStateOf(true)\n    }\n\n    Box {\n        Scaffold(\n            modifier = Modifier\n                .fillMaxSize()\n                .nestedScroll(scrollBehavior.nestedScrollConnection),\n            topBar = {\n                CompareScreenTopAppBar(\n                    imageNotPicked = component.bitmapData == null,\n                    scrollBehavior = scrollBehavior,\n                    onNavigationIconClick = component.onGoBack,\n                    onShareButtonClick = {\n                        showShareSheet = true\n                    },\n                    onSwapImagesClick = component::swap,\n                    onRotateImagesClick = component::rotate,\n                    isShareButtonVisible = component.compareType == CompareType.Slide\n                            || component.compareType == CompareType.PixelByPixel,\n                    isImagesRotated = component.rotation == 90f,\n                    titleWhenBitmapsPicked = stringResource(component.compareType.title),\n                    isLabelsEnabled = isLabelsEnabled,\n                    onToggleLabelsEnabled = { isLabelsEnabled = it },\n                    isLabelsButtonVisible = component.compareType != CompareType.PixelByPixel\n                )\n            },\n            contentWindowInsets = WindowInsets()\n        ) { contentPadding ->\n            CompareScreenContent(\n                bitmapData = component.bitmapData,\n                compareType = component.compareType,\n                onCompareTypeSelected = component::setCompareType,\n                isPortrait = isPortrait,\n                compareProgress = component.compareProgress,\n                onCompareProgressChange = component::setCompareProgress,\n                imagePicker = imagePicker,\n                isLabelsEnabled = isLabelsEnabled,\n                pixelByPixelCompareState = component.pixelByPixelCompareState,\n                onPixelByPixelCompareStateChange = component::updatePixelByPixelCompareState,\n                createPixelByPixelTransformation = component::createPixelByPixelTransformation,\n                contentPadding = contentPadding\n            )\n        }\n\n        if (component.bitmapData == null) {\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            EnhancedFloatingActionButton(\n                onClick = pickImage,\n                onLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                modifier = Modifier\n                    .navigationBarsPadding()\n                    .padding(16.dp)\n                    .align(settingsState.fabAlignment),\n                content = {\n                    Spacer(Modifier.width(16.dp))\n                    Icon(\n                        imageVector = Icons.Rounded.AddPhotoAlt,\n                        contentDescription = stringResource(R.string.pick_image_alt)\n                    )\n                    Spacer(Modifier.width(16.dp))\n                    Text(stringResource(R.string.pick_image_alt))\n                    Spacer(Modifier.width(16.dp))\n                }\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        }\n    }\n\n    val previewBitmap by remember(component.bitmapData) {\n        derivedStateOf {\n            component.getImagePreview()\n        }\n    }\n    val transformations = remember(\n        component.bitmapData,\n        component.compareProgress,\n        component.pixelByPixelCompareState,\n        component.compareType,\n        showShareSheet\n    ) {\n        if (component.compareType == CompareType.PixelByPixel && showShareSheet) {\n            listOf(component.createPixelByPixelTransformation())\n        } else emptyList()\n    }\n    CompareShareSheet(\n        visible = showShareSheet,\n        onVisibleChange = {\n            showShareSheet = it\n        },\n        onSaveBitmap = { imageFormat, oneTimeSaveLocationUri ->\n            component.saveBitmap(\n                imageFormat = imageFormat,\n                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n            )\n            showShareSheet = false\n        },\n        onShare = { imageFormat ->\n            component.shareBitmap(\n                imageFormat = imageFormat\n            )\n            showShareSheet = false\n        },\n        onCopy = component::cacheCurrentImage,\n        previewData = previewBitmap,\n        transformations = transformations\n    )\n\n    LoadingDialog(\n        visible = component.isImageLoading,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareLabel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\n\n@Composable\ninternal fun BoxScope.CompareLabel(\n    uri: Uri?,\n    alignment: Alignment,\n    enabled: Boolean,\n    shape: Shape,\n    modifier: Modifier = Modifier\n) {\n    AnimatedVisibility(\n        visible = enabled && uri != null,\n        modifier = modifier.align(alignment)\n    ) {\n        Text(\n            text = uri?.let { rememberFilename(it) }\n                ?: stringResource(R.string.filename),\n            modifier = Modifier\n                .background(\n                    color = MaterialTheme.colorScheme.scrim.copy(0.4f),\n                    shape = shape\n                )\n                .padding(horizontal = 8.dp, vertical = 2.dp),\n            color = Color.White,\n            fontSize = 13.sp\n        )\n    }\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareScreenContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Highlight\nimport androidx.compose.material.icons.rounded.Pix\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.BottomAppBar\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.VerticalDivider\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.TransformOrigin\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.dp\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.model.CompareData\nimport net.engawapg.lib.zoomable.ZoomableDefaults.defaultZoomOnDoubleTap\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n@Composable\ninternal fun CompareScreenContent(\n    bitmapData: CompareData?,\n    compareType: CompareType,\n    onCompareTypeSelected: (CompareType) -> Unit,\n    isPortrait: Boolean,\n    compareProgress: Float,\n    onCompareProgressChange: (Float) -> Unit,\n    pixelByPixelCompareState: PixelByPixelCompareState,\n    onPixelByPixelCompareStateChange: (PixelByPixelCompareState) -> Unit,\n    imagePicker: ImagePicker,\n    isLabelsEnabled: Boolean,\n    createPixelByPixelTransformation: () -> Transformation,\n    contentPadding: PaddingValues\n) {\n    AnimatedContent(\n        targetState = bitmapData == null,\n        modifier = Modifier\n            .fillMaxSize()\n            .padding(contentPadding)\n    ) { noData ->\n        bitmapData.takeIf { !noData }?.let { bitmapPair ->\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n\n            val zoomEnabled = compareType != CompareType.SideBySide\n            val zoomState = rememberZoomState(30f, key = compareType)\n            val zoomModifier = Modifier\n                .clipToBounds()\n                .zoomable(\n                    zoomState = zoomState,\n                    onDoubleTap = {\n                        if (zoomEnabled) {\n                            zoomState.defaultZoomOnDoubleTap(it)\n                        }\n                    },\n                    enableOneFingerZoom = zoomEnabled,\n                    zoomEnabled = zoomEnabled\n                )\n\n            val tuneButton: @Composable BoxScope.() -> Unit = {\n                BoxAnimatedVisibility(\n                    visible = compareType == CompareType.PixelByPixel,\n                    modifier = Modifier.align(Alignment.BottomEnd)\n                ) {\n                    var openTuneMenu by rememberSaveable {\n                        mutableStateOf(false)\n                    }\n                    EnhancedIconButton(\n                        onClick = {\n                            openTuneMenu = true\n                        },\n                        contentColor = MaterialTheme.colorScheme.onPrimary,\n                        containerColor = MaterialTheme.colorScheme.primary.copy(0.85f),\n                        modifier = Modifier.padding(8.dp)\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Tune,\n                            contentDescription = null\n                        )\n                    }\n\n                    EnhancedModalBottomSheet(\n                        visible = openTuneMenu,\n                        onDismiss = { openTuneMenu = it },\n                        title = {\n                            TitleItem(\n                                icon = Icons.Rounded.Tune,\n                                text = stringResource(compareType.title)\n                            )\n                        },\n                        confirmButton = {\n                            EnhancedButton(\n                                onClick = { openTuneMenu = false }\n                            ) {\n                                Text(stringResource(R.string.close))\n                            }\n                        }\n                    ) {\n                        Column(\n                            modifier = Modifier\n                                .enhancedVerticalScroll(rememberScrollState())\n                                .padding(8.dp)\n                        ) {\n                            ColorRowSelector(\n                                value = pixelByPixelCompareState.highlightColor,\n                                onValueChange = {\n                                    onPixelByPixelCompareStateChange(\n                                        pixelByPixelCompareState.copy(\n                                            highlightColor = it\n                                        )\n                                    )\n                                },\n                                allowAlpha = false,\n                                modifier = Modifier.container(\n                                    shape = ShapeDefaults.top\n                                ),\n                                title = stringResource(R.string.highlight_color),\n                                icon = Icons.Rounded.Highlight\n                            )\n                            Spacer(Modifier.height(4.dp))\n                            DataSelector(\n                                value = pixelByPixelCompareState.comparisonType,\n                                onValueChange = {\n                                    onPixelByPixelCompareStateChange(\n                                        pixelByPixelCompareState.copy(\n                                            comparisonType = it\n                                        )\n                                    )\n                                },\n                                entries = ComparisonType.entries,\n                                title = stringResource(R.string.pixel_comparison_type),\n                                titleIcon = Icons.Rounded.Pix,\n                                spanCount = 1,\n                                shape = ShapeDefaults.bottom,\n                                itemContentText = {\n                                    it.name\n                                },\n                                containerColor = Color.Unspecified\n                            )\n                        }\n                    }\n                }\n            }\n\n            if (isPortrait) {\n                Column {\n                    Box(\n                        modifier = Modifier\n                            .weight(1f)\n                            .fillMaxWidth(),\n                        contentAlignment = Alignment.Center,\n                    ) {\n                        Box(\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .then(zoomModifier),\n                            contentAlignment = Alignment.Center,\n                        ) {\n                            CompareScreenContentImpl(\n                                compareType = compareType,\n                                bitmapPair = bitmapPair,\n                                compareProgress = compareProgress,\n                                onCompareProgressChange = onCompareProgressChange,\n                                isPortrait = true,\n                                isLabelsEnabled = isLabelsEnabled,\n                                pixelByPixelCompareState = pixelByPixelCompareState,\n                                createPixelByPixelTransformation = createPixelByPixelTransformation\n                            )\n                        }\n\n                        tuneButton()\n                    }\n                    val showButtonsAtTheTop by remember(compareType) {\n                        derivedStateOf {\n                            compareType != CompareType.Tap && compareType != CompareType.SideBySide\n                        }\n                    }\n                    AnimatedVisibility(\n                        visible = showButtonsAtTheTop\n                    ) {\n                        Row(\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .drawHorizontalStroke(\n                                    top = true\n                                )\n                                .container(\n                                    color = MaterialTheme.colorScheme.surfaceContainer,\n                                    shape = RectangleShape,\n                                    borderColor = Color.Transparent\n                                )\n                                .padding(top = 4.dp),\n                            horizontalArrangement = Arrangement.Center,\n                            verticalAlignment = Alignment.CenterVertically\n                        ) {\n                            CompareSelectionButtons(\n                                value = compareType,\n                                onValueChange = onCompareTypeSelected,\n                                isPortrait = true\n                            )\n                        }\n                    }\n                    BottomAppBar(\n                        modifier = Modifier\n                            .drawHorizontalStroke(\n                                top = true,\n                                enabled = !showButtonsAtTheTop\n                            ),\n                        floatingActionButton = {\n                            EnhancedFloatingActionButton(\n                                onClick = imagePicker::pickImage,\n                                onLongClick = {\n                                    showOneTimeImagePickingDialog = true\n                                },\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.AddPhotoAlt,\n                                    contentDescription = stringResource(R.string.pick_image_alt)\n                                )\n                            }\n                        },\n                        actions = {\n                            AnimatedContent(\n                                targetState = !showButtonsAtTheTop\n                            ) { showButtons ->\n                                if (showButtons) {\n                                    Row(\n                                        modifier = Modifier\n                                            .padding(horizontal = 16.dp),\n                                        verticalAlignment = Alignment.CenterVertically\n                                    ) {\n                                        CompareSelectionButtons(\n                                            value = compareType,\n                                            onValueChange = onCompareTypeSelected,\n                                            isPortrait = true\n                                        )\n                                    }\n                                } else {\n                                    EnhancedSlider(\n                                        modifier = Modifier\n                                            .padding(horizontal = 16.dp)\n                                            .weight(100f, true)\n                                            .offset(y = (-2).dp),\n                                        value = compareProgress,\n                                        onValueChange = onCompareProgressChange,\n                                        valueRange = 0f..100f\n                                    )\n                                }\n                            }\n                        }\n                    )\n                }\n            } else {\n                Row {\n                    val direction = LocalLayoutDirection.current\n                    Box(\n                        modifier = Modifier.weight(0.8f),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        Box(\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .then(zoomModifier)\n                                .padding(\n                                    start = WindowInsets\n                                        .displayCutout\n                                        .asPaddingValues()\n                                        .calculateStartPadding(direction)\n                                ),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            CompareScreenContentImpl(\n                                compareType = compareType,\n                                bitmapPair = bitmapPair,\n                                compareProgress = compareProgress,\n                                onCompareProgressChange = onCompareProgressChange,\n                                isPortrait = false,\n                                isLabelsEnabled = isLabelsEnabled,\n                                pixelByPixelCompareState = pixelByPixelCompareState,\n                                createPixelByPixelTransformation = createPixelByPixelTransformation\n                            )\n                        }\n\n                        tuneButton()\n                    }\n                    val showButtonsAtTheStart by remember(compareType) {\n                        derivedStateOf {\n                            compareType != CompareType.Tap && compareType != CompareType.SideBySide\n                        }\n                    }\n                    AnimatedVisibility(\n                        visible = showButtonsAtTheStart\n                    ) {\n                        Row {\n                            LocalSettingsState.current.borderWidth.takeIf {\n                                it > 0.dp\n                            }?.let {\n                                VerticalDivider(thickness = it)\n                            }\n\n                            Column(\n                                modifier = Modifier\n                                    .fillMaxHeight()\n                                    .container(\n                                        shape = RectangleShape,\n                                        borderColor = Color.Transparent\n                                    )\n                                    .padding(start = 4.dp),\n                                verticalArrangement = Arrangement.Center,\n                                horizontalAlignment = Alignment.CenterHorizontally\n                            ) {\n                                CompareSelectionButtons(\n                                    value = compareType,\n                                    onValueChange = onCompareTypeSelected,\n                                    isPortrait = false,\n                                    modifier = Modifier.padding(start = 8.dp)\n                                )\n                            }\n                        }\n                    }\n                    Column(\n                        Modifier\n                            .container(\n                                shape = RectangleShape,\n                                borderColor = if (showButtonsAtTheStart) Color.Transparent\n                                else null\n                            )\n                            .padding(horizontal = 20.dp)\n                            .fillMaxHeight()\n                            .navigationBarsPadding()\n                            .padding(\n                                end = WindowInsets.displayCutout\n                                    .asPaddingValues()\n                                    .calculateEndPadding(direction)\n                            ),\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        AnimatedContent(\n                            targetState = !showButtonsAtTheStart\n                        ) { showButtons ->\n                            if (showButtons) {\n                                Column(\n                                    horizontalAlignment = Alignment.CenterHorizontally\n                                ) {\n                                    CompareSelectionButtons(\n                                        value = compareType,\n                                        onValueChange = onCompareTypeSelected,\n                                        isPortrait = false,\n                                        modifier = Modifier.padding(16.dp)\n                                    )\n                                }\n                            } else {\n                                val modifier = Modifier\n                                    .padding(16.dp)\n                                    .graphicsLayer {\n                                        rotationZ = 270f\n                                        transformOrigin = TransformOrigin(0f, 0f)\n                                    }\n                                    .layout { measurable, constraints ->\n                                        val placeable = measurable.measure(\n                                            Constraints(\n                                                minWidth = constraints.minHeight,\n                                                maxWidth = constraints.maxHeight,\n                                                minHeight = constraints.minWidth,\n                                                maxHeight = constraints.maxHeight,\n                                            )\n                                        )\n                                        layout(placeable.height, placeable.width) {\n                                            placeable.place(-placeable.width, 0)\n                                        }\n                                    }\n                                    .width(LocalScreenSize.current.height / 2f)\n\n                                EnhancedSlider(\n                                    modifier = modifier,\n                                    value = compareProgress,\n                                    onValueChange = onCompareProgressChange,\n                                    valueRange = 0f..100f\n                                )\n                            }\n                        }\n\n                        EnhancedFloatingActionButton(\n                            onClick = imagePicker::pickImage,\n                            onLongClick = {\n                                showOneTimeImagePickingDialog = true\n                            },\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.AddPhotoAlt,\n                                contentDescription = stringResource(R.string.pick_image_alt)\n                            )\n                        }\n                    }\n                }\n            }\n\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        } ?: Column(\n            modifier = Modifier\n                .fillMaxWidth()\n                .enhancedVerticalScroll(rememberScrollState()),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            ImageNotPickedWidget(\n                onPickImage = imagePicker::pickImage,\n                modifier = Modifier\n                    .padding(bottom = 88.dp, top = 20.dp, start = 20.dp, end = 20.dp)\n                    .navigationBarsPadding(),\n                text = stringResource(R.string.pick_two_images)\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareScreenContentImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.VerticalDivider\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.CornerSides\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.only\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter.BeforeAfterLayout\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.model.CompareData\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.model.ifNotEmpty\nimport kotlinx.coroutines.delay\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n@Composable\ninternal fun CompareScreenContentImpl(\n    compareType: CompareType,\n    bitmapPair: CompareData,\n    pixelByPixelCompareState: PixelByPixelCompareState,\n    compareProgress: Float,\n    onCompareProgressChange: (Float) -> Unit,\n    isPortrait: Boolean,\n    isLabelsEnabled: Boolean,\n    createPixelByPixelTransformation: () -> Transformation\n) {\n    val modifier = Modifier\n        .padding(16.dp)\n        .container(ShapeDefaults.default)\n        .padding(4.dp)\n        .clip(ShapeDefaults.small)\n        .transparencyChecker()\n\n    AnimatedContent(targetState = compareType) { type ->\n        when (type) {\n            CompareType.Slide -> {\n                AnimatedContent(targetState = bitmapPair) { data ->\n                    data.ifNotEmpty { beforeData, afterData ->\n                        val before = remember(data) { beforeData.image.asImageBitmap() }\n                        val after = remember(data) { afterData.image.asImageBitmap() }\n\n                        BeforeAfterLayout(\n                            modifier = modifier,\n                            progress = animateFloatAsState(targetValue = compareProgress).value,\n                            onProgressChange = onCompareProgressChange,\n                            beforeContent = {\n                                Picture(\n                                    model = before,\n                                    modifier = Modifier.aspectRatio(before.safeAspectRatio)\n                                )\n                            },\n                            afterContent = {\n                                Picture(\n                                    model = after,\n                                    modifier = Modifier.aspectRatio(after.safeAspectRatio)\n                                )\n                            },\n                            beforeLabel = {\n                                Box(\n                                    modifier = Modifier.matchParentSize()\n                                ) {\n                                    CompareLabel(\n                                        uri = beforeData.uri,\n                                        alignment = Alignment.TopStart,\n                                        enabled = isLabelsEnabled,\n                                        shape = ShapeDefaults.default.only(\n                                            CornerSides.BottomEnd\n                                        )\n                                    )\n                                }\n                            },\n                            afterLabel = {\n                                Box(\n                                    modifier = Modifier.matchParentSize()\n                                ) {\n                                    CompareLabel(\n                                        uri = afterData.uri,\n                                        alignment = Alignment.BottomEnd,\n                                        enabled = isLabelsEnabled,\n                                        shape = ShapeDefaults.default.only(\n                                            CornerSides.TopStart\n                                        )\n                                    )\n                                }\n                            }\n                        )\n                    }\n                }\n            }\n\n            CompareType.SideBySide -> {\n                val first = bitmapPair.first?.image\n                val second = bitmapPair.second?.image\n\n                val zoomState = rememberZoomState(30f)\n                val zoomModifier = Modifier\n                    .clipToBounds()\n                    .zoomable(\n                        zoomState = zoomState\n                    )\n\n\n                Box(modifier) {\n                    if (isPortrait) {\n                        Column(\n                            modifier = Modifier.fillMaxSize(),\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            if (first != null) {\n                                Picture(\n                                    model = first,\n                                    contentDescription = null,\n                                    modifier = Modifier\n                                        .fillMaxWidth()\n                                        .weight(1f)\n                                        .then(zoomModifier)\n                                )\n                                HorizontalDivider()\n                            }\n                            if (second != null) {\n                                Picture(\n                                    model = second,\n                                    contentDescription = null,\n                                    modifier = Modifier\n                                        .fillMaxWidth()\n                                        .weight(1f)\n                                        .then(zoomModifier)\n                                )\n                            }\n                        }\n                        CompareLabel(\n                            uri = bitmapPair.first?.uri,\n                            alignment = Alignment.TopStart,\n                            enabled = isLabelsEnabled,\n                            shape = ShapeDefaults.default.only(\n                                CornerSides.BottomEnd\n                            )\n                        )\n                        CompareLabel(\n                            uri = bitmapPair.second?.uri,\n                            alignment = Alignment.BottomStart,\n                            enabled = isLabelsEnabled,\n                            shape = ShapeDefaults.default.only(\n                                CornerSides.TopEnd\n                            )\n                        )\n                    } else {\n                        Row(\n                            modifier = Modifier.fillMaxSize(),\n                            verticalAlignment = Alignment.CenterVertically\n                        ) {\n                            if (first != null) {\n                                Picture(\n                                    model = first,\n                                    contentDescription = null,\n                                    modifier = Modifier\n                                        .fillMaxHeight()\n                                        .weight(1f)\n                                        .then(zoomModifier)\n                                )\n                                VerticalDivider()\n                            }\n                            if (second != null) {\n                                Picture(\n                                    model = second,\n                                    contentDescription = null,\n                                    modifier = Modifier\n                                        .fillMaxHeight()\n                                        .weight(1f)\n                                        .then(zoomModifier)\n                                )\n                            }\n                        }\n                        CompareLabel(\n                            uri = bitmapPair.first?.uri,\n                            alignment = Alignment.TopStart,\n                            enabled = isLabelsEnabled,\n                            shape = ShapeDefaults.default.only(\n                                CornerSides.BottomEnd\n                            )\n                        )\n                        CompareLabel(\n                            uri = bitmapPair.second?.uri,\n                            alignment = Alignment.TopEnd,\n                            enabled = isLabelsEnabled,\n                            shape = ShapeDefaults.default.only(\n                                CornerSides.BottomStart\n                            )\n                        )\n                    }\n                }\n            }\n\n            CompareType.Tap -> {\n                var showSecondImage by rememberSaveable {\n                    mutableStateOf(false)\n                }\n                Box(\n                    modifier = modifier.tappable {\n                        showSecondImage = !showSecondImage\n                    }\n                ) {\n                    val first = bitmapPair.first?.image\n                    val second = bitmapPair.second?.image\n                    if (!showSecondImage && first != null) {\n                        Picture(\n                            model = first,\n                            contentDescription = null,\n                            contentScale = ContentScale.Inside\n                        )\n                    }\n                    if (showSecondImage && second != null) {\n                        Picture(\n                            model = second,\n                            contentDescription = null,\n                            contentScale = ContentScale.Inside\n                        )\n                    }\n                    Box(\n                        modifier = Modifier.matchParentSize()\n                    ) {\n                        CompareLabel(\n                            uri = if (showSecondImage) bitmapPair.second?.uri\n                            else bitmapPair.first?.uri,\n                            alignment = if (showSecondImage) Alignment.BottomEnd\n                            else Alignment.TopStart,\n                            enabled = isLabelsEnabled,\n                            shape = if (showSecondImage) {\n                                ShapeDefaults.default.only(\n                                    CornerSides.TopStart\n                                )\n                            } else {\n                                ShapeDefaults.default.only(\n                                    CornerSides.BottomEnd\n                                )\n                            }\n                        )\n                    }\n                }\n            }\n\n            CompareType.Transparency -> {\n                Box(\n                    modifier = modifier\n                ) {\n                    val first = bitmapPair.first?.image\n                    val second = bitmapPair.second?.image\n                    if (first != null) {\n                        Picture(\n                            model = first,\n                            contentDescription = null,\n                            contentScale = ContentScale.Inside\n                        )\n                    }\n                    if (second != null) {\n                        Picture(\n                            model = second,\n                            contentDescription = null,\n                            contentScale = ContentScale.Inside,\n                            modifier = Modifier.alpha(compareProgress / 100f)\n                        )\n                    }\n                    Box(\n                        modifier = Modifier.matchParentSize()\n                    ) {\n                        CompareLabel(\n                            uri = bitmapPair.first?.uri,\n                            alignment = Alignment.TopStart,\n                            enabled = isLabelsEnabled,\n                            shape = ShapeDefaults.default.only(\n                                CornerSides.BottomEnd\n                            )\n                        )\n                    }\n                    Box(\n                        modifier = Modifier.matchParentSize()\n                    ) {\n                        CompareLabel(\n                            uri = bitmapPair.second?.uri,\n                            modifier = Modifier.alpha(compareProgress / 100f),\n                            alignment = Alignment.BottomEnd,\n                            enabled = isLabelsEnabled,\n                            shape = ShapeDefaults.default.only(\n                                CornerSides.TopStart\n                            )\n                        )\n                    }\n                }\n            }\n\n            CompareType.PixelByPixel -> {\n                var isLoading by remember {\n                    mutableStateOf(false)\n                }\n\n                val first = bitmapPair.first?.image\n                val second = bitmapPair.second?.image\n\n                Box(\n                    modifier = Modifier.fillMaxSize(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Box(\n                        modifier = modifier\n                    ) {\n                        if (first != null) {\n                            var transformations: List<Transformation> by remember {\n                                mutableStateOf(emptyList())\n                            }\n\n                            LaunchedEffect(\n                                first,\n                                second,\n                                compareProgress,\n                                pixelByPixelCompareState\n                            ) {\n                                delay(300)\n                                transformations = listOf(\n                                    createPixelByPixelTransformation()\n                                )\n                            }\n\n                            Picture(\n                                model = first,\n                                transformations = transformations,\n                                onSuccess = {\n                                    isLoading = false\n                                },\n                                onLoading = {\n                                    isLoading = true\n                                },\n                                contentDescription = null,\n                                contentScale = ContentScale.Inside\n                            )\n                        }\n                    }\n\n                    AnimatedVisibility(\n                        visible = isLoading && first != null,\n                        enter = fadeIn(),\n                        exit = fadeOut()\n                    ) {\n                        Box(\n                            modifier = Modifier.fillMaxSize(),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            EnhancedLoadingIndicator()\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareScreenTopAppBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.automirrored.rounded.Label\nimport androidx.compose.material.icons.automirrored.rounded.RotateLeft\nimport androidx.compose.material.icons.automirrored.rounded.RotateRight\nimport androidx.compose.material.icons.rounded.SwapHoriz\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\nfun CompareScreenTopAppBar(\n    imageNotPicked: Boolean,\n    scrollBehavior: TopAppBarScrollBehavior,\n    onNavigationIconClick: () -> Unit,\n    onShareButtonClick: () -> Unit,\n    onSwapImagesClick: () -> Unit,\n    onRotateImagesClick: () -> Unit,\n    isShareButtonVisible: Boolean,\n    isImagesRotated: Boolean,\n    titleWhenBitmapsPicked: String,\n    onToggleLabelsEnabled: (Boolean) -> Unit,\n    isLabelsEnabled: Boolean,\n    isLabelsButtonVisible: Boolean\n) {\n    if (imageNotPicked) {\n        EnhancedTopAppBar(\n            type = EnhancedTopAppBarType.Large,\n            scrollBehavior = scrollBehavior,\n            navigationIcon = {\n                EnhancedIconButton(\n                    onClick = onNavigationIconClick\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                        contentDescription = stringResource(R.string.exit)\n                    )\n                }\n            },\n            title = {\n                Text(\n                    text = stringResource(R.string.compare),\n                    modifier = Modifier.marquee()\n                )\n            },\n            actions = {\n                TopAppBarEmoji()\n            }\n        )\n    } else {\n        EnhancedTopAppBar(\n            navigationIcon = {\n                EnhancedIconButton(\n                    onClick = onNavigationIconClick\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                        contentDescription = stringResource(R.string.exit)\n                    )\n                }\n            },\n            actions = {\n                AnimatedVisibility(visible = isShareButtonVisible) {\n                    ShareButton(onShare = onShareButtonClick)\n                }\n                EnhancedIconButton(\n                    onClick = onSwapImagesClick\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.SwapHoriz,\n                        contentDescription = \"Swap\"\n                    )\n                }\n                EnhancedIconButton(\n                    onClick = onRotateImagesClick\n                ) {\n                    AnimatedContent(isImagesRotated) { rotated ->\n                        Icon(\n                            imageVector = if (rotated) Icons.AutoMirrored.Rounded.RotateLeft\n                            else Icons.AutoMirrored.Rounded.RotateRight,\n                            contentDescription = \"Rotate\"\n                        )\n                    }\n                }\n                AnimatedVisibility(visible = isLabelsButtonVisible) {\n                    EnhancedIconButton(\n                        onClick = {\n                            onToggleLabelsEnabled(!isLabelsEnabled)\n                        },\n                        containerColor = animateColorAsState(\n                            if (isLabelsEnabled) MaterialTheme.colorScheme.secondary\n                            else Color.Transparent\n                        ).value\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.Label,\n                            contentDescription = \"Label\"\n                        )\n                    }\n                }\n            },\n            title = {\n                AnimatedContent(\n                    targetState = titleWhenBitmapsPicked,\n                    modifier = Modifier.marquee()\n                ) { text ->\n                    Text(text)\n                }\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareSelectionButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedHorizontalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\n\n@Composable\nfun CompareSelectionButtons(\n    value: CompareType,\n    onValueChange: (CompareType) -> Unit,\n    isPortrait: Boolean,\n    modifier: Modifier = Modifier\n) {\n    val buttonsContent = @Composable {\n        CompareType.entries.forEach { compareType ->\n            val selected by remember(compareType, value) {\n                derivedStateOf {\n                    compareType == value\n                }\n            }\n            val containerColor by animateColorAsState(\n                if (selected) MaterialTheme.colorScheme.secondaryContainer\n                else Color.Transparent\n            )\n            EnhancedIconButton(\n                containerColor = containerColor,\n                onClick = { onValueChange(compareType) }\n            ) {\n                Icon(\n                    imageVector = compareType.icon,\n                    contentDescription = stringResource(compareType.title)\n                )\n            }\n        }\n    }\n    val scrollState = rememberScrollState()\n    val internalModifier = modifier\n        .container(\n            color = MaterialTheme.colorScheme.surfaceContainerLowest,\n            shape = ShapeDefaults.circle,\n            resultPadding = 0.dp\n        )\n        .fadingEdges(\n            scrollableState = scrollState,\n            isVertical = !isPortrait\n        )\n        .then(\n            if (isPortrait) Modifier.enhancedHorizontalScroll(scrollState)\n            else Modifier.enhancedVerticalScroll(scrollState)\n        )\n\n    if (isPortrait) {\n        Row(\n            modifier = internalModifier\n        ) {\n            buttonsContent()\n        }\n    } else {\n        Column(\n            modifier = internalModifier\n        ) {\n            buttonsContent()\n        }\n    }\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareShareSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material.icons.rounded.IosShare\nimport androidx.compose.material.icons.rounded.Save\nimport androidx.compose.material.icons.rounded.Share\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults.bottom\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults.center\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults.top\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n\n@Composable\ninternal fun CompareShareSheet(\n    visible: Boolean,\n    onVisibleChange: (Boolean) -> Unit,\n    onSaveBitmap: (ImageFormat, String?) -> Unit,\n    onShare: (ImageFormat) -> Unit,\n    onCopy: (ImageFormat) -> Unit,\n    previewData: Any?,\n    transformations: List<Transformation>\n) {\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            var imageFormat by remember { mutableStateOf<ImageFormat>(ImageFormat.Png.Lossless) }\n            Box {\n                Column(\n                    modifier = Modifier.enhancedVerticalScroll(rememberScrollState()),\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Box(\n                        Modifier\n                            .padding(\n                                bottom = 8.dp,\n                                start = 4.dp,\n                                end = 4.dp,\n                                top = 16.dp\n                            )\n                            .height(100.dp)\n                            .width(120.dp)\n                            .container(\n                                shape = MaterialTheme.shapes.extraLarge,\n                                resultPadding = 0.dp\n                            )\n                    ) {\n                        Picture(\n                            model = previewData,\n                            transformations = transformations,\n                            shape = RectangleShape,\n                            modifier = Modifier.fillMaxSize()\n                        )\n                    }\n                    Spacer(Modifier.height(16.dp))\n                    ImageFormatSelector(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(horizontal = 16.dp),\n                        value = imageFormat,\n                        forceEnabled = true,\n                        onValueChange = { imageFormat = it }\n                    )\n                    Spacer(Modifier.height(8.dp))\n                    var showFolderSelectionDialog by rememberSaveable(visible) {\n                        mutableStateOf(false)\n                    }\n                    PreferenceItem(\n                        title = stringResource(id = R.string.save),\n                        onClick = {\n                            onSaveBitmap(imageFormat, null)\n                        },\n                        onLongClick = {\n                            showFolderSelectionDialog = true\n                        },\n                        shape = top,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(horizontal = 16.dp),\n                        containerColor = MaterialTheme.colorScheme.primaryContainer,\n                        endIcon = Icons.Rounded.Save\n                    )\n                    OneTimeSaveLocationSelectionDialog(\n                        visible = showFolderSelectionDialog,\n                        onDismiss = { showFolderSelectionDialog = false },\n                        onSaveRequest = {\n                            onSaveBitmap(imageFormat, it)\n                        },\n                        formatForFilenameSelection = imageFormat\n                    )\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        title = stringResource(id = R.string.copy),\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(horizontal = 16.dp),\n                        shape = center,\n                        onClick = {\n                            onCopy(imageFormat)\n                        },\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        endIcon = Icons.Rounded.ContentCopy\n                    )\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        title = stringResource(id = R.string.share),\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(horizontal = 16.dp),\n                        shape = bottom,\n                        onClick = {\n                            onShare(imageFormat)\n                        },\n                        containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                        endIcon = Icons.Rounded.Share\n                    )\n                    Spacer(Modifier.height(16.dp))\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    onVisibleChange(false)\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.share),\n                icon = Icons.Rounded.IosShare\n            )\n        },\n        onDismiss = onVisibleChange,\n        visible = visible\n    )\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Compare\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter.BeforeAfterLayout\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n@Composable\nfun CompareSheet(\n    data: Pair<Bitmap?, Bitmap?>?,\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    var progress by rememberSaveable(visible) { mutableFloatStateOf(50f) }\n\n    if (data != null) {\n        EnhancedModalBottomSheet(\n            sheetContent = {\n                Column(\n                    modifier = Modifier.navigationBarsPadding()\n                ) {\n                    Box(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .weight(1f)\n                            .padding(horizontal = 16.dp)\n                            .container(\n                                shape = ShapeDefaults.extraSmall,\n                                color = MaterialTheme.colorScheme\n                                    .outlineVariant()\n                                    .copy(alpha = 0.1f),\n                                resultPadding = 0.dp\n                            )\n                            .transparencyChecker()\n                            .clipToBounds()\n                            .zoomable(rememberZoomState(maxScale = 15f)),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        data.let { (b, a) ->\n                            val before = remember(data) { b?.asImageBitmap() }\n                            val after = remember(data) { a?.asImageBitmap() }\n                            if (before != null && after != null) {\n                                BeforeAfterLayout(\n                                    modifier = Modifier.clip(ShapeDefaults.extraSmall),\n                                    progress = animateFloatAsState(targetValue = progress).value,\n                                    onProgressChange = {\n                                        progress = it\n                                    },\n                                    beforeContent = {\n                                        Picture(\n                                            model = before,\n                                            modifier = Modifier.aspectRatio(before.safeAspectRatio)\n                                        )\n                                    },\n                                    afterContent = {\n                                        Picture(\n                                            model = after,\n                                            modifier = Modifier.aspectRatio(after.safeAspectRatio)\n                                        )\n                                    },\n                                    beforeLabel = { },\n                                    afterLabel = { }\n                                )\n                            }\n                        }\n                    }\n                    Row(\n                        modifier = Modifier.padding(8.dp),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        TitleItem(\n                            text = stringResource(R.string.compare),\n                            icon = Icons.Outlined.Compare\n                        )\n                        Spacer(Modifier.weight(1f))\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            onClick = onDismiss,\n                            modifier = Modifier.padding(horizontal = 12.dp)\n                        ) {\n                            AutoSizeText(stringResource(R.string.close))\n                        }\n                    }\n                }\n            },\n            visible = visible,\n            onDismiss = {\n                if (!it) onDismiss()\n            },\n            dragHandle = {\n                EnhancedModalSheetDragHandle(\n                    color = Color.Transparent,\n                    drawStroke = false,\n                    heightWhenDisabled = 20.dp\n                )\n            }\n        )\n    }\n}\n\n@Composable\nfun CompareSheet(\n    beforeContent: @Composable () -> Unit,\n    afterContent: @Composable () -> Unit,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    shape: Shape = ShapeDefaults.extraSmall\n) {\n    var progress by rememberSaveable(visible) { mutableFloatStateOf(50f) }\n\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Column(\n                modifier = Modifier.navigationBarsPadding()\n            ) {\n                Box(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .weight(1f)\n                        .padding(horizontal = 16.dp)\n                        .container(\n                            shape = ShapeDefaults.extraSmall,\n                            color = MaterialTheme.colorScheme\n                                .outlineVariant()\n                                .copy(alpha = 0.1f),\n                            resultPadding = 0.dp\n                        )\n                        .transparencyChecker()\n                        .clipToBounds()\n                        .zoomable(rememberZoomState(maxScale = 15f)),\n                    contentAlignment = Alignment.Center\n                ) {\n                    BeforeAfterLayout(\n                        modifier = Modifier.clip(shape),\n                        progress = animateFloatAsState(targetValue = progress).value,\n                        onProgressChange = {\n                            progress = it\n                        },\n                        beforeContent = beforeContent,\n                        afterContent = afterContent,\n                        beforeLabel = { },\n                        afterLabel = { }\n                    )\n                }\n                Row(\n                    modifier = Modifier.padding(8.dp),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    TitleItem(\n                        text = stringResource(R.string.compare),\n                        icon = Icons.Outlined.Compare\n                    )\n                    Spacer(Modifier.weight(1f))\n                    EnhancedButton(\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        onClick = onDismiss,\n                        modifier = Modifier.padding(horizontal = 12.dp)\n                    ) {\n                        AutoSizeText(stringResource(R.string.close))\n                    }\n                }\n            }\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        dragHandle = {\n            EnhancedModalSheetDragHandle(\n                color = Color.Transparent,\n                drawStroke = false,\n                heightWhenDisabled = 20.dp\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/CompareType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport androidx.annotation.StringRes\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.TouchApp\nimport androidx.compose.material.icons.rounded.ZoomIn\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Compare\nimport com.t8rin.imagetoolbox.core.resources.icons.Cube\nimport com.t8rin.imagetoolbox.core.resources.icons.Transparency\n\nsealed class CompareType(\n    val icon: ImageVector,\n    @StringRes val title: Int\n) {\n    data object Slide : CompareType(\n        icon = Icons.Outlined.Compare,\n        title = R.string.slide\n    )\n\n    data object SideBySide : CompareType(\n        icon = Icons.Rounded.ZoomIn,\n        title = R.string.side_by_side\n    )\n\n    data object Tap : CompareType(\n        icon = Icons.Rounded.TouchApp,\n        title = R.string.toggle_tap\n    )\n\n    data object Transparency : CompareType(\n        icon = Icons.Filled.Transparency,\n        title = R.string.transparency\n    )\n\n    data object PixelByPixel : CompareType(\n        icon = Icons.Outlined.Cube,\n        title = R.string.pixel_by_pixel\n    )\n\n    companion object {\n        val entries by lazy {\n            listOf(Slide, SideBySide, Tap, Transparency, PixelByPixel)\n        }\n    }\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/PixelByPixelCompareState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components\n\nimport androidx.compose.ui.graphics.Color\n\ndata class PixelByPixelCompareState(\n    val highlightColor: Color,\n    val comparisonType: ComparisonType\n) {\n    companion object {\n        val Default by lazy {\n            PixelByPixelCompareState(\n                highlightColor = Color.Red,\n                comparisonType = ComparisonType.AE\n            )\n        }\n    }\n}\n\nenum class ComparisonType {\n    SSIM, AE, MAE, NCC, PSNR, RMSE\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/BeforeAfterLayout.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.unit.DpSize\n\n/**\n * A composable that lays out and draws a given [beforeContent] and [afterContent]\n * based on [contentOrder]. This overload uses [DefaultOverlay] to draw vertical slider and thumb.\n *\n * @param enableProgressWithTouch flag to enable drag and change progress with touch\n * @param contentOrder order of composables to be drawn\n * @param overlayStyle styling values for [DefaultOverlay] to set divier color, thumb shape, size,\n * elevation and other properties\n * @param beforeContent content to be drawn as before Composable\n * @param afterContent content to be drawn as after Composable\n * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default\n * @param afterLabel label for [afterContent]. It's [AfterLabel] by default\n *\n */\n@Composable\ninternal fun BeforeAfterLayout(\n    modifier: Modifier = Modifier,\n    enableProgressWithTouch: Boolean = true,\n    contentOrder: ContentOrder = ContentOrder.BeforeAfter,\n    overlayStyle: OverlayStyle = OverlayStyle(),\n    beforeContent: @Composable () -> Unit,\n    afterContent: @Composable () -> Unit,\n    beforeLabel: @Composable BoxScope.() -> Unit = { BeforeLabel(contentOrder = contentOrder) },\n    afterLabel: @Composable BoxScope.() -> Unit = { AfterLabel(contentOrder = contentOrder) },\n) {\n    var progress by remember { mutableFloatStateOf(50f) }\n\n    Layout(\n        modifier = modifier,\n        beforeContent = beforeContent,\n        afterContent = afterContent,\n        beforeLabel = beforeLabel,\n        afterLabel = afterLabel,\n        progress = progress,\n        onProgressChange = {\n            progress = it\n        },\n        contentOrder = contentOrder,\n        enableProgressWithTouch = enableProgressWithTouch,\n        overlay = { dpSize: DpSize, offset: Offset ->\n            DefaultOverlay(\n                width = dpSize.width,\n                height = dpSize.height,\n                position = offset,\n                overlayStyle = overlayStyle\n            )\n        }\n    )\n}\n\n/**\n * A composable that lays out and draws a given [beforeContent] and [afterContent]\n * based on [contentOrder]. This overload uses [DefaultOverlay] to draw vertical slider and thumb\n * and has [progress] and [onProgressChange] which makes it eligible to animate by changing\n * [progress] value.\n *\n * @param enableProgressWithTouch flag to enable drag and change progress with touch\n * @param contentOrder order of composables to be drawn\n * @param progress current position or progress of before/after\n * @param onProgressChange current position or progress of before/after\n * @param overlayStyle styling values for [DefaultOverlay] to set divier color, thumb shape, size,\n * elevation and other properties\n * @param beforeContent content to be drawn as before Composable\n * @param afterContent content to be drawn as after Composable\n * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default\n * @param afterLabel label for [afterContent]. It's [AfterLabel] by default\n */\n@Composable\ninternal fun BeforeAfterLayout(\n    modifier: Modifier = Modifier,\n    enableProgressWithTouch: Boolean = true,\n    contentOrder: ContentOrder = ContentOrder.BeforeAfter,\n    @FloatRange(from = 0.0, to = 100.0) progress: Float = 50f,\n    onProgressChange: ((Float) -> Unit)? = null,\n    overlayStyle: OverlayStyle = OverlayStyle(),\n    beforeContent: @Composable () -> Unit,\n    afterContent: @Composable () -> Unit,\n    beforeLabel: @Composable BoxScope.() -> Unit = { BeforeLabel(contentOrder = contentOrder) },\n    afterLabel: @Composable BoxScope.() -> Unit = { AfterLabel(contentOrder = contentOrder) },\n) {\n\n    Layout(\n        modifier = modifier,\n        beforeContent = beforeContent,\n        afterContent = afterContent,\n        beforeLabel = beforeLabel,\n        afterLabel = afterLabel,\n        progress = progress,\n        onProgressChange = onProgressChange,\n        contentOrder = contentOrder,\n        enableProgressWithTouch = enableProgressWithTouch,\n        overlay = { dpSize: DpSize, offset: Offset ->\n            DefaultOverlay(\n                width = dpSize.width,\n                height = dpSize.height,\n                position = offset,\n                overlayStyle = overlayStyle\n            )\n        }\n    )\n}\n\n/**\n * A composable that lays out and draws a given [beforeContent] and [afterContent]\n * based on [contentOrder].\n *\n * @param enableProgressWithTouch flag to enable drag and change progress with touch\n * @param contentOrder order of composables to be drawn\n\n * It's between [0f-100f] to set thumb's vertical position in layout\n * @param beforeContent content to be drawn as before Composable\n * @param afterContent content to be drawn as after Composable\n * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default\n * @param afterLabel label for [afterContent]. It's [AfterLabel] by default\n * @param overlay Composable for drawing overlay over this Composable. It returns dimensions\n * of ancestor and touch position\n */\n@Composable\ninternal fun BeforeAfterLayout(\n    modifier: Modifier = Modifier,\n    enableProgressWithTouch: Boolean = true,\n    contentOrder: ContentOrder = ContentOrder.BeforeAfter,\n    beforeContent: @Composable () -> Unit,\n    afterContent: @Composable () -> Unit,\n    beforeLabel: @Composable BoxScope.() -> Unit = { BeforeLabel(contentOrder = contentOrder) },\n    afterLabel: @Composable BoxScope.() -> Unit = { AfterLabel(contentOrder = contentOrder) },\n    overlay: @Composable ((DpSize, Offset) -> Unit)?\n) {\n    var progress by remember { mutableFloatStateOf(50f) }\n\n    Layout(\n        modifier = modifier,\n        beforeContent = beforeContent,\n        afterContent = afterContent,\n        beforeLabel = beforeLabel,\n        afterLabel = afterLabel,\n        progress = progress,\n        onProgressChange = {\n            progress = it\n        },\n        contentOrder = contentOrder,\n        enableProgressWithTouch = enableProgressWithTouch,\n        overlay = overlay\n    )\n}\n\n/**\n * A composable that lays out and draws a given [beforeContent] and [afterContent]\n * based on [contentOrder].\n *\n * @param enableProgressWithTouch flag to enable drag and change progress with touch\n * @param contentOrder order of composables to be drawn\n * @param progress current position or progress of before/after\n * @param onProgressChange current position or progress of before/after\n * It's between [0f-100f] to set thumb's vertical position in layout\n * @param beforeContent content to be drawn as before Composable\n * @param afterContent content to be drawn as after Composable\n * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default\n * @param afterLabel label for [afterContent]. It's [AfterLabel] by default\n * @param overlay Composable for drawing overlay over this Composable. It returns dimensions\n * of ancestor and touch position\n */\n@Composable\ninternal fun BeforeAfterLayout(\n    modifier: Modifier = Modifier,\n    @FloatRange(from = 0.0, to = 100.0) progress: Float = 50f,\n    onProgressChange: ((Float) -> Unit)? = null,\n    enableProgressWithTouch: Boolean = true,\n    contentOrder: ContentOrder = ContentOrder.BeforeAfter,\n    beforeContent: @Composable () -> Unit,\n    afterContent: @Composable () -> Unit,\n    beforeLabel: @Composable (BoxScope.() -> Unit)? = { BeforeLabel(contentOrder = contentOrder) },\n    afterLabel: @Composable (BoxScope.() -> Unit)? = { AfterLabel(contentOrder = contentOrder) },\n    overlay: @Composable ((DpSize, Offset) -> Unit)?\n) {\n\n    Layout(\n        modifier = modifier,\n        beforeContent = beforeContent,\n        afterContent = afterContent,\n        beforeLabel = beforeLabel,\n        afterLabel = afterLabel,\n        progress = progress,\n        onProgressChange = onProgressChange,\n        contentOrder = contentOrder,\n        enableProgressWithTouch = enableProgressWithTouch,\n        overlay = overlay\n    )\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/BeforeAfterLayoutImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.GenericShape\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport com.t8rin.gesture.detectMotionEvents\n\n\n@Composable\ninternal fun Layout(\n    modifier: Modifier = Modifier,\n    @FloatRange(from = 0.0, to = 100.0) progress: Float = 50f,\n    onProgressChange: ((Float) -> Unit)? = null,\n    enableProgressWithTouch: Boolean = true,\n    contentOrder: ContentOrder = ContentOrder.BeforeAfter,\n    beforeContent: @Composable () -> Unit,\n    afterContent: @Composable () -> Unit,\n    beforeLabel: @Composable (BoxScope.() -> Unit)?,\n    afterLabel: @Composable (BoxScope.() -> Unit)?,\n    overlay: @Composable ((DpSize, Offset) -> Unit)?\n) {\n    DimensionSubcomposeLayout(\n        modifier = modifier,\n        placeMainContent = false,\n        mainContent = {\n            beforeContent()\n        },\n        dependentContent = { contentSize: Size ->\n\n            val boxWidth = contentSize.width\n            val boxHeight = contentSize.height\n\n            val boxWidthInDp: Dp\n            val boxHeightInDp: Dp\n\n            with(LocalDensity.current) {\n                boxWidthInDp = boxWidth.toDp()\n                boxHeightInDp = boxHeight.toDp()\n            }\n\n            // Sales and interpolates from offset from dragging to user value in valueRange\n            fun scaleToUserValue(offset: Float) =\n                scale(0f, boxWidth, offset, 0f, 100f)\n\n            // Scales user value using valueRange to position on x axis on screen\n            fun scaleToOffset(userValue: Float) =\n                scale(0f, 100f, userValue, 0f, boxWidth)\n\n            var rawOffset by remember {\n                mutableStateOf(\n                    Offset(\n                        x = scaleToOffset(progress),\n                        y = boxHeight / 2f,\n                    )\n                )\n            }\n\n            rawOffset = rawOffset.copy(x = scaleToOffset(progress))\n\n            var isHandleTouched by remember { mutableStateOf(false) }\n\n            val touchModifier = Modifier.pointerInput(Unit) {\n                detectMotionEvents(\n                    onDown = {\n                        val position = it.position\n                        val xPos = position.x\n\n                        isHandleTouched =\n                            ((rawOffset.x - xPos) * (rawOffset.x - xPos) < 5000)\n                    },\n                    onMove = {\n                        if (isHandleTouched) {\n                            rawOffset = it.position\n                            onProgressChange?.invoke(\n                                scaleToUserValue(rawOffset.x)\n                            )\n                            it.consume()\n                        }\n                    },\n                    onUp = {\n                        isHandleTouched = false\n                    }\n                )\n            }\n\n            val handlePosition = rawOffset.x\n\n            val shapeBefore by remember(handlePosition) {\n                mutableStateOf(\n                    GenericShape { size: Size, _: LayoutDirection ->\n                        moveTo(0f, 0f)\n                        lineTo(handlePosition, 0f)\n                        lineTo(handlePosition, size.height)\n                        lineTo(0f, size.height)\n                        close()\n                    }\n                )\n            }\n\n            val shapeAfter by remember(handlePosition) {\n                mutableStateOf(\n                    GenericShape { size: Size, _: LayoutDirection ->\n                        moveTo(handlePosition, 0f)\n                        lineTo(size.width, 0f)\n                        lineTo(size.width, size.height)\n                        lineTo(handlePosition, size.height)\n                        close()\n                    }\n                )\n            }\n\n            val parentModifier = Modifier\n                .size(boxWidthInDp, boxHeightInDp)\n                .clipToBounds()\n                .then(if (enableProgressWithTouch) touchModifier else Modifier)\n\n\n            val beforeModifier = Modifier\n                .fillMaxSize()\n                .graphicsLayer {\n                    this.clip = true\n                    this.shape = shapeBefore\n                }\n\n\n            val afterModifier = Modifier\n                .fillMaxSize()\n                .graphicsLayer {\n                    this.clip = true\n                    this.shape = shapeAfter\n                }\n\n            LayoutImpl(\n                modifier = parentModifier,\n                beforeModifier = beforeModifier,\n                afterModifier = afterModifier,\n                graphicsModifier = Modifier,\n                beforeContent = beforeContent,\n                afterContent = afterContent,\n                beforeLabel = beforeLabel,\n                afterLabel = afterLabel,\n                overlay = overlay,\n                contentOrder = contentOrder,\n                boxWidthInDp = boxWidthInDp,\n                boxHeightInDp = boxHeightInDp,\n                rawOffset = rawOffset\n            )\n        }\n    )\n}\n\n@Composable\nprivate fun LayoutImpl(\n    modifier: Modifier,\n    beforeModifier: Modifier,\n    afterModifier: Modifier,\n    graphicsModifier: Modifier,\n    beforeContent: @Composable () -> Unit,\n    afterContent: @Composable () -> Unit,\n    beforeLabel: @Composable (BoxScope.() -> Unit)? = null,\n    afterLabel: @Composable (BoxScope.() -> Unit)? = null,\n    overlay: @Composable ((DpSize, Offset) -> Unit)? = null,\n    contentOrder: ContentOrder,\n    boxWidthInDp: Dp,\n    boxHeightInDp: Dp,\n    rawOffset: Offset,\n) {\n    Box(modifier = modifier) {\n\n        // BEFORE\n        val before = @Composable {\n            Box(if (contentOrder == ContentOrder.BeforeAfter) beforeModifier else afterModifier) {\n                Box(\n                    modifier = Modifier.then(graphicsModifier)\n                ) {\n                    beforeContent()\n                }\n                beforeLabel?.invoke(this)\n            }\n        }\n\n        // AFTER\n        val after = @Composable {\n            Box(if (contentOrder == ContentOrder.BeforeAfter) afterModifier else beforeModifier) {\n                Box(\n                    modifier = Modifier.then(graphicsModifier)\n                ) {\n                    afterContent()\n                }\n                afterLabel?.invoke(this)\n            }\n        }\n\n        if (contentOrder == ContentOrder.BeforeAfter) {\n            before()\n            after()\n        } else {\n            after()\n            before()\n        }\n    }\n\n    overlay?.invoke(\n        DpSize(boxWidthInDp, boxHeightInDp), rawOffset\n    )\n}\n"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/ContentOrder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\n/**\n * Enum class to determine in which order before and after content should be drawn\n */\ninternal enum class ContentOrder {\n    BeforeAfter, AfterBefore\n}\n"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/DefaultOverlay.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.DragHandle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.draw.shadow\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\n\n/**\n * Default overlay for and [BeforeAfterLayout] that draws line and\n * thumb with properties provided.\n *\n * @param width of the or [BeforeAfterLayout]. You should get width from\n * scope of these Composables and pass to calculate bounds correctly\n * @param height of the or [BeforeAfterLayout]. You should get height from\n * scope of these Composables and pass to calculate bounds correctly\n * @param position current position or progress of before/after\n */\n@Composable\ninternal fun DefaultOverlay(\n    width: Dp,\n    height: Dp,\n    position: Offset,\n    overlayStyle: OverlayStyle\n) {\n    CompositionLocalProvider(\n        LocalLayoutDirection provides LayoutDirection.Ltr\n    ) {\n        val verticalThumbMove = overlayStyle.verticalThumbMove\n        val dividerWidth = overlayStyle.dividerWidth\n\n        val dividerColor =\n            overlayStyle.dividerColor.takeOrElse { MaterialTheme.colorScheme.primary }\n        val secondDividerColor =\n            overlayStyle.secondDividerColor.takeOrElse { MaterialTheme.colorScheme.primaryContainer }\n        val thumbBackgroundColor =\n            overlayStyle.thumbBackgroundColor.takeOrElse { MaterialTheme.colorScheme.primary }\n        val thumbTintColor =\n            overlayStyle.thumbTintColor.takeOrElse { MaterialTheme.colorScheme.primaryContainer }\n\n        val thumbShape = overlayStyle.thumbShape\n        val thumbElevation = overlayStyle.thumbElevation\n        val thumbResource = overlayStyle.thumbResource\n        val thumbHeight = overlayStyle.thumbHeight\n        val thumbWidth = overlayStyle.thumbWidth\n        val thumbPositionPercent = overlayStyle.thumbPositionPercent\n\n\n        var thumbPosX = position.x\n        var thumbPosY = position.y\n\n        val linePosition: Float\n\n        val density = LocalDensity.current\n\n        with(density) {\n            val thumbRadius = (maxOf(thumbHeight, thumbWidth) / 2).toPx()\n            val imageWidthInPx = width.toPx()\n            val imageHeightInPx = height.toPx()\n\n            val horizontalOffset = imageWidthInPx / 2\n            val verticalOffset = imageHeightInPx / 2\n\n            linePosition = thumbPosX.coerceIn(0f, imageWidthInPx)\n            thumbPosX = linePosition - horizontalOffset\n\n            thumbPosY = if (verticalThumbMove) {\n                (thumbPosY - verticalOffset)\n                    .coerceIn(\n                        -verticalOffset + thumbRadius,\n                        verticalOffset - thumbRadius\n                    )\n            } else {\n                ((imageHeightInPx * thumbPositionPercent / 100f - thumbRadius) - verticalOffset)\n            }\n        }\n\n        Box(\n            modifier = Modifier.size(width, height),\n            contentAlignment = Alignment.Center\n        ) {\n            Canvas(modifier = Modifier.fillMaxSize()) {\n\n                drawLine(\n                    color = dividerColor,\n                    strokeWidth = dividerWidth.toPx(),\n                    start = Offset(linePosition, 0f),\n                    end = Offset(linePosition, size.height)\n                )\n\n                drawLine(\n                    color = secondDividerColor,\n                    strokeWidth = dividerWidth.toPx(),\n                    start = Offset(linePosition, 0f),\n                    end = Offset(linePosition, size.height),\n                    pathEffect = PathEffect.dashPathEffect(\n                        intervals = floatArrayOf(\n                            overlayStyle.dash.toPx(),\n                            overlayStyle.gap.toPx()\n                        )\n                    )\n                )\n\n            }\n\n            Icon(\n                imageVector = thumbResource,\n                contentDescription = \"compare thumb\",\n                tint = thumbTintColor,\n                modifier = Modifier\n                    .offset {\n                        IntOffset(thumbPosX.toInt(), thumbPosY.toInt())\n                    }\n                    .shadow(thumbElevation, thumbShape)\n                    .background(thumbBackgroundColor)\n                    .size(\n                        width = thumbWidth,\n                        height = thumbHeight,\n                    )\n                    .rotate(overlayStyle.iconRotation)\n                    .scale(overlayStyle.iconScale)\n            )\n        }\n    }\n}\n\n/**\n * Values for styling [DefaultOverlay]\n *  @param verticalThumbMove when true thumb can move vertically based on user touch\n * @param dividerColor color if divider line\n * @param dividerWidth width if divider line\n * @param thumbBackgroundColor background color of thumb [Icon]\n * @param thumbTintColor tint color of thumb [Icon]\n * @param thumbShape shape of thumb [Icon]\n * @param thumbElevation elevation of thumb [Icon]\n * @param thumbResource drawable resource that should be used with thumb\n * thumbSize size of the thumb in dp\n * @param thumbPositionPercent vertical position of thumb if [verticalThumbMove] is false\n * It's between [0f-100f] to set thumb's vertical position in layout\n */\n@Immutable\ninternal class OverlayStyle(\n    val dividerColor: Color = Color.Unspecified,\n    val secondDividerColor: Color = Color.Unspecified,\n    val dash: Dp = 24.dp,\n    val gap: Dp = 24.dp,\n    val dividerWidth: Dp = 2.dp,\n    val verticalThumbMove: Boolean = true,\n    val thumbBackgroundColor: Color = Color.Unspecified,\n    val thumbTintColor: Color = Color.Unspecified,\n    val thumbShape: Shape = CircleShape,\n    val thumbElevation: Dp = 2.dp,\n    val thumbResource: ImageVector = Icons.Rounded.DragHandle,\n    val iconRotation: Float = 90f,\n    val iconScale: Float = 1.2f,\n    val thumbHeight: Dp = 36.dp,\n    val thumbWidth: Dp = 18.dp,\n    val thumbPositionPercent: Float = 85f,\n)\n"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/DimensionSubcomposeLayout.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.SubcomposeLayout\nimport androidx.compose.ui.layout.SubcomposeMeasureScope\nimport androidx.compose.ui.unit.Constraints\n\n/**\n * SubcomposeLayout that [SubcomposeMeasureScope.subcompose]s [mainContent]\n * and gets total size of [mainContent] and passes this size to [dependentContent].\n * This layout passes exact size of content unlike\n * BoxWithConstraints which returns [Constraints] that doesn't match Composable dimensions under\n * some circumstances\n *\n * @param placeMainContent when set to true places main content. Set this flag to false\n * when dimensions of content is required for inside [mainContent]. Just measure it then pass\n * its dimensions to any child composable\n *\n * @param mainContent Composable is used for calculating size and pass it\n * to Composables that depend on it\n *\n * @param dependentContent Composable requires dimensions of [mainContent] to set its size.\n * One example for this is overlay over Composable that should match [mainContent] size.\n *\n */\n@Composable\ninternal fun DimensionSubcomposeLayout(\n    modifier: Modifier = Modifier,\n    placeMainContent: Boolean = true,\n    mainContent: @Composable () -> Unit,\n    dependentContent: @Composable (Size) -> Unit\n) {\n    SubcomposeLayout(\n        modifier = modifier\n    ) { constraints: Constraints ->\n\n        // Subcompose(compose only a section) main content and get Placeable\n        val mainPlaceables: List<Placeable> = subcompose(SlotsEnum.Main, mainContent)\n            .map {\n                it.measure(constraints)\n            }\n\n        // Get max width and height of main component\n        var maxWidth = 0\n        var maxHeight = 0\n\n        mainPlaceables.forEach { placeable: Placeable ->\n            maxWidth += placeable.width\n            maxHeight = placeable.height\n        }\n\n        val dependentPlaceables: List<Placeable> = subcompose(SlotsEnum.Dependent) {\n            dependentContent(Size(maxWidth.toFloat(), maxHeight.toFloat()))\n        }\n            .map { measurable: Measurable ->\n                measurable.measure(constraints)\n            }\n\n\n        layout(maxWidth, maxHeight) {\n\n            if (placeMainContent) {\n                mainPlaceables.forEach { placeable: Placeable ->\n                    placeable.placeRelative(0, 0)\n                }\n            }\n\n            dependentPlaceables.forEach { placeable: Placeable ->\n                placeable.placeRelative(0, 0)\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/DimensionUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\n/**\n * [Linear Interpolation](https://en.wikipedia.org/wiki/Linear_interpolation) function that moves\n * amount from it's current position to start and amount\n * @param start of interval\n * @param end of interval\n * @param amount e closed unit interval [0, 1]\n */\ninternal fun lerp(start: Float, end: Float, amount: Float): Float {\n    return (1 - amount) * start + amount * end\n}\n\n/**\n * Scale x1 from start1..end1 range to start2..end2 range\n\n */\ninternal fun scale(start1: Float, end1: Float, pos: Float, start2: Float, end2: Float) =\n    lerp(start2, end2, calculateFraction(start1, end1, pos))\n\n/**\n * Scale x.start, x.endInclusive from a1..b1 range to a2..b2 range\n */\ninternal fun scale(\n    start1: Float,\n    end1: Float,\n    range: ClosedFloatingPointRange<Float>,\n    start2: Float,\n    end2: Float\n) =\n    scale(start1, end1, range.start, start2, end2)..scale(\n        start1,\n        end1,\n        range.endInclusive,\n        start2,\n        end2\n    )\n\n\n/**\n * Calculate fraction for value between a range [end] and [start] coerced into 0f-1f range\n */\nfun calculateFraction(start: Float, end: Float, pos: Float) =\n    (if (end - start == 0f) 0f else (pos - start) / (end - start)).coerceIn(0f, 1f)\n"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/Label.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.TextUnit\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\n\n/**\n * Black transparent label to display before or after text\n */\n@Composable\ninternal fun Label(\n    modifier: Modifier = Modifier,\n    textColor: Color = Color.White,\n    fontWeight: FontWeight = FontWeight.Bold,\n    fontSize: TextUnit = 14.sp,\n    text: String\n) {\n    Text(\n        text = text,\n        color = textColor,\n        fontSize = fontSize,\n        fontWeight = fontWeight,\n        modifier = modifier\n\n    )\n}\n\ninternal val labelModifier =\n    Modifier\n        .background(Color.Black.copy(alpha = .5f), RoundedCornerShape(50))\n        .padding(horizontal = 12.dp, vertical = 8.dp)\n\n@Composable\ninternal fun BoxScope.BeforeLabel(\n    text: String = \"Before\",\n    textColor: Color = Color.White,\n    fontWeight: FontWeight = FontWeight.Bold,\n    fontSize: TextUnit = 14.sp,\n    contentOrder: ContentOrder = ContentOrder.BeforeAfter\n) {\n    Label(\n        text = text,\n        textColor = textColor,\n        fontWeight = fontWeight,\n        fontSize = fontSize,\n        modifier = Modifier\n            .padding(8.dp)\n            .align(\n                if (contentOrder == ContentOrder.BeforeAfter)\n                    Alignment.TopStart else Alignment.TopEnd\n            )\n            .then(labelModifier)\n    )\n}\n\n@Composable\ninternal fun BoxScope.AfterLabel(\n    text: String = \"After\",\n    textColor: Color = Color.White,\n    fontWeight: FontWeight = FontWeight.Bold,\n    fontSize: TextUnit = 14.sp,\n    contentOrder: ContentOrder = ContentOrder.BeforeAfter\n) {\n    Label(\n        text = text,\n        textColor = textColor,\n        fontWeight = fontWeight,\n        fontSize = fontSize,\n\n        modifier = Modifier\n            .padding(8.dp)\n            .align(\n                if (contentOrder == ContentOrder.BeforeAfter)\n                    Alignment.TopEnd else Alignment.TopStart\n            )\n            .then(labelModifier)\n    )\n}\n"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/beforeafter/SlotsEnum.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.beforeafter\n\n/**\n * Enum class for SubcomposeLayouts with main and dependent Composables\n */\ninternal enum class SlotsEnum { Main, Dependent }\n"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/components/model/CompareData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.components.model\n\nimport android.graphics.Bitmap\nimport android.net.Uri\n\ndata class CompareEntry(\n    val uri: Uri,\n    val image: Bitmap\n)\n\ndata class CompareData(\n    val first: CompareEntry?,\n    val second: CompareEntry?\n) {\n    fun swap() = CompareData(\n        first = second,\n        second = first\n    )\n}\n\ninline fun <R> CompareData.ifNotEmpty(\n    action: (CompareEntry, CompareEntry) -> R\n): R? = run {\n    if (first != null && second != null) action(first, second)\n    else null\n}"
  },
  {
    "path": "feature/compare/src/main/java/com/t8rin/imagetoolbox/feature/compare/presentation/screenLogic/CompareComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.compare.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.net.toUri\nimport coil3.transform.Transformation\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.asDomain\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.transformation.GenericTransformation\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.createScaledBitmap\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toCoil\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareType\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.PixelByPixelCompareState\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.model.CompareData\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.model.CompareEntry\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.model.ifNotEmpty\nimport com.t8rin.opencv_tools.image_comparison.ImageDiffTool\nimport com.t8rin.opencv_tools.image_comparison.model.ComparisonType\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.coroutineScope\nimport kotlin.math.roundToInt\n\nclass CompareComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialComparableUris: Pair<Uri, Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialComparableUris?.let {\n                updateUris(\n                    uris = it,\n                    onFailure = {},\n                )\n            }\n        }\n    }\n\n    private val _compareProgress: MutableState<Float> = mutableFloatStateOf(50f)\n    val compareProgress by _compareProgress\n\n    fun setCompareProgress(progress: Float) {\n        _compareProgress.update { progress }\n    }\n\n    private val _bitmapData: MutableState<CompareData?> = mutableStateOf(null)\n    val bitmapData by _bitmapData\n\n    private val _rotation: MutableState<Float> = mutableFloatStateOf(0f)\n    val rotation by _rotation\n\n    private val _compareType: MutableState<CompareType> = mutableStateOf(CompareType.Slide)\n    val compareType by _compareType\n\n    private val _pixelByPixelCompareState: MutableState<PixelByPixelCompareState> = mutableStateOf(\n        PixelByPixelCompareState.Default\n    )\n    val pixelByPixelCompareState: PixelByPixelCompareState by _pixelByPixelCompareState\n\n    fun updatePixelByPixelCompareState(state: PixelByPixelCompareState) {\n        _pixelByPixelCompareState.update { state }\n    }\n\n    fun rotate() {\n        val old = _rotation.value\n        _rotation.value = _rotation.value.let {\n            if (it == 90f) 0f\n            else 90f\n        }\n        componentScope.launch {\n            bitmapData?.ifNotEmpty { first, second ->\n                _isImageLoading.value = true\n                _bitmapData.value = with(imageTransformer) {\n                    CompareData(\n                        first = first.copy(\n                            image = rotate(\n                                image = rotate(\n                                    image = first.image,\n                                    degrees = 180f - old\n                                ),\n                                degrees = rotation\n                            )\n                        ),\n                        second = second.copy(\n                            image = rotate(\n                                image = rotate(\n                                    image = second.image,\n                                    degrees = 180f - old\n                                ),\n                                degrees = rotation\n                            )\n                        )\n                    )\n                }\n                _isImageLoading.value = false\n            }\n        }\n    }\n\n    fun swap() {\n        componentScope.launch {\n            _isImageLoading.value = true\n            _bitmapData.value = bitmapData?.swap()\n            _isImageLoading.value = false\n        }\n    }\n\n    fun updateUris(\n        uris: Pair<Uri, Uri>,\n        onFailure: () -> Unit,\n    ) {\n        componentScope.launch {\n            val data = getBitmapByUri(uris.first) to getBitmapByUri(uris.second)\n            if (data.first == null || data.second == null) onFailure()\n            else {\n                _bitmapData.value = CompareData(\n                    first = CompareEntry(\n                        uri = uris.first,\n                        image = data.first!!\n                    ),\n                    second = CompareEntry(\n                        uri = uris.second,\n                        image = data.second!!\n                    )\n                )\n                setCompareProgress(\n                    if (compareType == CompareType.PixelByPixel) 4f\n                    else 50f\n                )\n            }\n        }\n    }\n\n    private suspend fun getBitmapByUri(\n        uri: Uri\n    ): Bitmap? = imageGetter.getImage(\n        data = uri.toString(),\n        size = 4000\n    )\n\n    private var savingJob: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    fun shareBitmap(\n        imageFormat: ImageFormat\n    ) {\n        savingJob = trackProgress {\n            _isImageLoading.value = true\n            getResultImage()?.let {\n                shareProvider.shareImage(\n                    image = it,\n                    imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = it.width,\n                        height = it.height\n                    ),\n                    onComplete = AppToastHost::showConfetti\n                )\n            } ?: AppToastHost.showConfetti()\n            _isImageLoading.value = false\n        }\n    }\n\n    fun saveBitmap(\n        imageFormat: ImageFormat,\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isImageLoading.value = true\n            getResultImage()?.let { localBitmap ->\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = ImageInfo(\n                                imageFormat = imageFormat,\n                                width = localBitmap.width,\n                                height = localBitmap.height\n                            ),\n                            originalUri = \"\",\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = localBitmap,\n                                imageInfo = ImageInfo(\n                                    imageFormat = imageFormat,\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                )\n                            )\n                        ),\n                        keepOriginalMetadata = false,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    )\n                )\n                _isImageLoading.value = false\n            }\n        }\n    }\n\n    private fun Bitmap.overlay(\n        overlay: Bitmap,\n        percent: Float\n    ): Bitmap = overlay.copy(overlay.safeConfig, true)\n        .apply { setHasAlpha(true) }\n        .applyCanvas {\n            runCatching {\n                val image = createScaledBitmap(\n                    width = width,\n                    height = height\n                )\n\n                drawBitmap(\n                    Bitmap.createBitmap(\n                        image, 0, 0,\n                        (image.width * percent / 100).roundToInt(),\n                        image.height\n                    )\n                )\n            }\n        }\n\n    private fun getOverlappedImage(): Bitmap? {\n        return bitmapData?.ifNotEmpty { before, after ->\n            before.image.overlay(\n                overlay = after.image,\n                percent = compareProgress\n            )\n        }\n    }\n\n    private suspend fun getResultImage(): Bitmap? = coroutineScope {\n        when (compareType) {\n            CompareType.PixelByPixel -> imageTransformer.transform(\n                image = bitmapData?.first?.image ?: return@coroutineScope null,\n                transformations = listOf(createPixelByPixelTransformation().asDomain())\n            )\n\n            CompareType.Slide -> getOverlappedImage()\n            else -> null\n        }\n    }\n\n    fun getImagePreview(): Bitmap? = when (compareType) {\n        CompareType.PixelByPixel -> bitmapData?.first?.image\n        CompareType.Slide -> getOverlappedImage()\n        else -> null\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isImageLoading.value = false\n    }\n\n    fun setCompareType(value: CompareType) {\n        _compareType.update { value }\n        if (value == CompareType.PixelByPixel) {\n            setCompareProgress(4f)\n        }\n    }\n\n    fun cacheCurrentImage(\n        imageFormat: ImageFormat,\n    ) {\n        savingJob = trackProgress {\n            _isImageLoading.value = true\n            getResultImage()?.let {\n                shareProvider.cacheImage(\n                    image = it,\n                    imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = it.width,\n                        height = it.height\n                    )\n                )\n            }?.let { uri ->\n                Clipboard.copy(uri.toUri())\n            }\n            _isImageLoading.value = false\n        }\n    }\n\n    fun createPixelByPixelTransformation(): Transformation =\n        GenericTransformation<Bitmap> { first ->\n            ImageDiffTool.highlightDifferences(\n                input = first,\n                other = bitmapData?.second?.image\n                    ?: return@GenericTransformation first,\n                comparisonType = ComparisonType.valueOf(pixelByPixelCompareState.comparisonType.name),\n                highlightColor = pixelByPixelCompareState.highlightColor.toArgb(),\n                threshold = compareProgress\n            )\n        }.toCoil()\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialComparableUris: Pair<Uri, Uri>?,\n            onGoBack: () -> Unit,\n        ): CompareComponent\n    }\n\n}"
  },
  {
    "path": "feature/crop/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/crop/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.crop\"\n\ndependencies {\n    implementation(projects.lib.opencvTools)\n}"
  },
  {
    "path": "feature/crop/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/CropContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation\n\n\nimport android.net.Uri\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.cropper.model.OutlineType\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.CropSmall\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveBottomScaffoldLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.MagnifierEnabledSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AspectRatioSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CoercePointsToImageBoundsToggle\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CropMaskSelection\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CropRotationSelector\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CropType\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.Cropper\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.FreeCornersCropToggle\nimport com.t8rin.imagetoolbox.feature.crop.presentation.screenLogic.CropComponent\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun CropContent(\n    component: CropComponent\n) {\n    val scope = rememberCoroutineScope()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.bitmap != null) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    AutoContentBasedColors(component.bitmap)\n\n    var coercePointsToImageArea by rememberSaveable {\n        mutableStateOf(true)\n    }\n\n    val rotationState = rememberSaveable {\n        mutableFloatStateOf(0f)\n    }\n\n    val imagePicker = rememberImagePicker { uri: Uri ->\n        rotationState.floatValue = 0f\n        component.setUri(uri)\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showResetDialog by rememberSaveable { mutableStateOf(false) }\n\n    var crop by remember { mutableStateOf(false) }\n\n    val actions = @Composable {\n        var editSheetData by remember {\n            mutableStateOf(listOf<Uri>())\n        }\n        ShareButton(\n            enabled = component.bitmap != null,\n            onShare = component::shareBitmap,\n            onEdit = {\n                component.cacheCurrentImage { uri ->\n                    editSheetData = listOf(uri)\n                }\n            },\n            onCopy = {\n                component.cacheCurrentImage(Clipboard::copy)\n            }\n        )\n        ProcessImagesPreferenceSheet(\n            uris = editSheetData,\n            visible = editSheetData.isNotEmpty(),\n            onDismiss = {\n                editSheetData = emptyList()\n            },\n            onNavigate = component.onNavigate\n        )\n    }\n\n    AdaptiveBottomScaffoldLayoutScreen(\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.crop),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = null,\n                originalSize = null\n            )\n        },\n        onGoBack = onBack,\n        shouldDisableBackHandler = component.bitmap == null,\n        actions = {\n            actions()\n        },\n        topAppBarPersistentActions = { scaffoldState ->\n            if (component.bitmap == null) TopAppBarEmoji()\n            else {\n                if (isPortrait) {\n                    EnhancedIconButton(\n                        onClick = {\n                            scope.launch {\n                                if (scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {\n                                    scaffoldState.bottomSheetState.partialExpand()\n                                } else {\n                                    scaffoldState.bottomSheetState.expand()\n                                }\n                            }\n                        },\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Tune,\n                            contentDescription = stringResource(R.string.properties)\n                        )\n                    }\n                }\n                EnhancedIconButton(\n                    onClick = { showResetDialog = true },\n                    enabled = component.bitmap != null && component.isBitmapChanged\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.ImageReset,\n                        contentDescription = stringResource(R.string.reset_image)\n                    )\n                }\n\n                if (!isPortrait) actions()\n            }\n        },\n        mainContent = {\n            component.bitmap?.let { bitmap ->\n                Cropper(\n                    bitmap = bitmap,\n                    crop = crop,\n                    onImageCropStarted = component::imageCropStarted,\n                    onImageCropFinished = {\n                        component.imageCropFinished()\n                        if (it != null) {\n                            component.updateBitmap(it)\n                        }\n                        crop = false\n                    },\n                    rotationState = rotationState,\n                    cropProperties = component.cropProperties,\n                    cropType = component.cropType,\n                    addVerticalInsets = !isPortrait,\n                    coercePointsToImageArea = coercePointsToImageArea\n                )\n            }\n        },\n        controls = {\n            Column(\n                modifier = Modifier.padding(16.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp)\n            ) {\n                FreeCornersCropToggle(\n                    modifier = Modifier.fillMaxWidth(),\n                    value = component.cropType == CropType.FreeCorners,\n                    onClick = component::toggleFreeCornersCrop\n                )\n                BoxAnimatedVisibility(\n                    visible = component.cropType == CropType.Default,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    CropRotationSelector(\n                        value = rotationState.floatValue,\n                        onValueChange = { rotationState.floatValue = it }\n                    )\n                }\n                BoxAnimatedVisibility(\n                    visible = component.cropType == CropType.FreeCorners,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    Column {\n                        CoercePointsToImageBoundsToggle(\n                            value = coercePointsToImageArea,\n                            onValueChange = { coercePointsToImageArea = it },\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                        Spacer(Modifier.height(8.dp))\n                        MagnifierEnabledSelector(\n                            modifier = Modifier.fillMaxWidth(),\n                            shape = ShapeDefaults.extraLarge,\n                        )\n                    }\n                }\n                BoxAnimatedVisibility(\n                    visible = component.cropType != CropType.FreeCorners,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    Column {\n                        AspectRatioSelector(\n                            modifier = Modifier.fillMaxWidth(),\n                            selectedAspectRatio = component.selectedAspectRatio,\n                            onAspectRatioChange = component::setCropAspectRatio\n                        )\n                        Spacer(modifier = Modifier.height(8.dp))\n                        CropMaskSelection(\n                            onCropMaskChange = component::setCropMask,\n                            selectedItem = component.cropProperties.cropOutlineProperty,\n                            loadImage = {\n                                component.loadImage(it)?.asImageBitmap()\n                            }\n                        )\n                    }\n                }\n                ImageFormatSelector(\n                    modifier = Modifier.navigationBarsPadding(),\n                    entries = if (component.cropProperties.cropOutlineProperty.outlineType == OutlineType.Rect) {\n                        ImageFormatGroup.entries\n                    } else ImageFormatGroup.alphaContainedEntries,\n                    value = component.imageFormat,\n                    onValueChange = {\n                        component.setImageFormat(it)\n                    }\n                )\n            }\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var job by remember { mutableStateOf<Job?>(null) }\n            BottomButtonsBlock(\n                isNoData = component.bitmap == null,\n                onSecondaryButtonClick = {\n                    if (component.bitmap == null) {\n                        pickImage()\n                    } else {\n                        job?.cancel()\n                        job = scope.launch {\n                            delay(500)\n                            crop = true\n                        }\n                    }\n                },\n                onSecondaryButtonLongClick = if (component.bitmap == null) {\n                    { showOneTimeImagePickingDialog = true }\n                } else null,\n                secondaryButtonIcon = if (component.bitmap == null) Icons.Rounded.AddPhotoAlt else Icons.Rounded.CropSmall,\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                isPrimaryButtonVisible = component.isBitmapChanged,\n                middleFab = {\n                    EnhancedFloatingActionButton(\n                        onClick = pickImage,\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.AddPhotoAlt,\n                            contentDescription = stringResource(R.string.add_image)\n                        )\n                    }\n                },\n                showMiddleFabInRow = component.bitmap != null,\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        noDataControls = {\n            ImageNotPickedWidget(onPickImage = pickImage)\n        },\n        canShowScreenData = component.bitmap != null,\n        showActionsInTopAppBar = false\n    )\n\n    ResetDialog(\n        visible = showResetDialog,\n        onDismiss = { showResetDialog = false },\n        onReset = component::resetBitmap\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving || component.isImageLoading,\n        onCancelLoading = component::cancelSaving,\n        canCancel = component.isSaving\n    )\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/components/CoercePointsToImageBoundsToggle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Rectangle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun CoercePointsToImageBoundsToggle(\n    value: Boolean,\n    onValueChange: (Boolean) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    PreferenceRowSwitch(\n        checked = value,\n        onClick = onValueChange,\n        title = stringResource(R.string.coerce_points_to_image_bounds),\n        subtitle = stringResource(R.string.coerce_points_to_image_bounds_sub),\n        startIcon = Icons.Outlined.Rectangle,\n        modifier = modifier,\n        shape = ShapeDefaults.extraLarge\n    )\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/components/CropMaskSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.cropper.model.CornerRadiusProperties\nimport com.t8rin.cropper.model.CutCornerCropShape\nimport com.t8rin.cropper.model.ImageMaskOutline\nimport com.t8rin.cropper.model.OutlineType\nimport com.t8rin.cropper.model.RoundedCornerCropShape\nimport com.t8rin.cropper.settings.CropOutlineProperty\nimport com.t8rin.cropper.widget.CropFrameDisplayCard\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport kotlinx.coroutines.launch\nimport kotlin.math.roundToInt\n\n@Composable\nfun CropMaskSelection(\n    modifier: Modifier = Modifier,\n    selectedItem: CropOutlineProperty,\n    loadImage: suspend (Uri) -> ImageBitmap?,\n    onCropMaskChange: (CropOutlineProperty) -> Unit,\n    color: Color = Color.Unspecified,\n    shape: Shape = ShapeDefaults.extraLarge\n) {\n    var cornerRadius by rememberSaveable { mutableIntStateOf(20) }\n\n    val outlineProperties = DefaultOutlineProperties\n\n    val scope = rememberCoroutineScope()\n\n    val maskLauncher = rememberImagePicker { uri: Uri ->\n        scope.launch {\n            loadImage(uri)?.let {\n                onCropMaskChange(\n                    outlineProperties.last().run {\n                        copy(\n                            cropOutline = (cropOutline as ImageMaskOutline).copy(image = it)\n                        )\n                    }\n                )\n            }\n        }\n    }\n\n\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally,\n        modifier = modifier.container(\n            color = color,\n            shape = shape\n        )\n    ) {\n        Text(\n            text = stringResource(id = R.string.crop_mask),\n            modifier = Modifier\n                .padding(start = 8.dp, end = 8.dp, top = 16.dp),\n            fontWeight = FontWeight.Medium\n        )\n        val listState = rememberLazyListState()\n        LazyRow(\n            horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally),\n            contentPadding = PaddingValues(\n                start = 16.dp,\n                top = 4.dp,\n                bottom = 4.dp,\n                end = 16.dp + WindowInsets\n                    .navigationBars\n                    .asPaddingValues()\n                    .calculateEndPadding(LocalLayoutDirection.current)\n            ),\n            state = listState,\n            verticalAlignment = Alignment.CenterVertically,\n            modifier = Modifier.fadingEdges(listState),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            itemsIndexed(\n                items = outlineProperties,\n                key = { _, o -> o.cropOutline.id }\n            ) { _, item ->\n                val selected = selectedItem.cropOutline.id == item.cropOutline.id\n                CropFrameDisplayCard(\n                    modifier = Modifier\n                        .padding(vertical = 8.dp)\n                        .height(100.dp)\n                        .container(\n                            resultPadding = 0.dp,\n                            color = animateColorAsState(\n                                targetValue = if (selected) {\n                                    MaterialTheme.colorScheme.primaryContainer\n                                } else MaterialTheme.colorScheme.surfaceContainerLowest,\n                            ).value,\n                            borderColor = if (selected) MaterialTheme.colorScheme.onPrimaryContainer.copy(\n                                0.7f\n                            )\n                            else MaterialTheme.colorScheme.outlineVariant()\n                        )\n                        .hapticsClickable {\n                            if (item.cropOutline is ImageMaskOutline) {\n                                maskLauncher.pickImage()\n                            } else {\n                                onCropMaskChange(item)\n                            }\n                            cornerRadius = 20\n                        }\n                        .padding(16.dp),\n                    editable = false,\n                    scale = 1f,\n                    outlineColor = MaterialTheme.colorScheme.secondary,\n                    title = \"\",\n                    cropOutline = item.cropOutline\n                )\n            }\n        }\n\n        EnhancedSliderItem(\n            visible = selectedItem.cropOutline.id == 1 || selectedItem.cropOutline.id == 2,\n            modifier = Modifier\n                .padding(start = 16.dp, end = 16.dp, bottom = 16.dp),\n            shape = ShapeDefaults.default,\n            value = cornerRadius,\n            title = stringResource(R.string.radius),\n            icon = null,\n            internalStateTransformation = {\n                it.roundToInt()\n            },\n            containerColor = MaterialTheme.colorScheme.surface,\n            onValueChange = {\n                cornerRadius = it.roundToInt()\n                if (selectedItem.cropOutline is CutCornerCropShape) {\n                    onCropMaskChange(\n                        selectedItem.copy(\n                            cropOutline = CutCornerCropShape(\n                                id = selectedItem.cropOutline.id,\n                                title = selectedItem.cropOutline.title,\n                                cornerRadius = CornerRadiusProperties(\n                                    topStartPercent = cornerRadius,\n                                    topEndPercent = cornerRadius,\n                                    bottomStartPercent = cornerRadius,\n                                    bottomEndPercent = cornerRadius\n                                )\n                            )\n                        )\n                    )\n                } else if (selectedItem.cropOutline is RoundedCornerCropShape) {\n                    onCropMaskChange(\n                        selectedItem.copy(\n                            cropOutline = RoundedCornerCropShape(\n                                id = selectedItem.cropOutline.id,\n                                title = selectedItem.cropOutline.title,\n                                cornerRadius = CornerRadiusProperties(\n                                    topStartPercent = cornerRadius,\n                                    topEndPercent = cornerRadius,\n                                    bottomStartPercent = cornerRadius,\n                                    bottomEndPercent = cornerRadius\n                                )\n                            )\n                        )\n                    )\n                }\n            },\n            valueRange = 0f..50f,\n            steps = 50\n        )\n        AnimatedVisibility(\n            selectedItem.cropOutline.title == OutlineType.ImageMask.name\n        ) {\n            Column(\n                modifier = Modifier\n                    .padding(start = 16.dp, end = 16.dp, bottom = 16.dp)\n                    .container(shape = ShapeDefaults.extraLarge)\n                    .padding(8.dp),\n                verticalArrangement = Arrangement.Center,\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                Text(\n                    text = stringResource(id = R.string.image_crop_mask_sub),\n                    textAlign = TextAlign.Center,\n                    color = LocalContentColor.current.copy(0.5f),\n                    fontSize = 14.sp,\n                    lineHeight = 16.sp\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/components/CropRotationSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ScreenRotationAlt\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\n\n@Composable\nfun CropRotationSelector(\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    EnhancedSliderItem(\n        value = value,\n        title = stringResource(R.string.rotation),\n        modifier = modifier,\n        icon = Icons.Rounded.ScreenRotationAlt,\n        valueRange = -45f..45f,\n        internalStateTransformation = { it.roundTo(1) },\n        onValueChange = onValueChange\n    )\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/components/CropType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.components\n\nenum class CropType {\n    Default, NoRotation, FreeCorners\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/components/Cropper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.components\n\nimport android.graphics.Bitmap\nimport android.graphics.BitmapFactory\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.systemBars\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableFloatState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toFile\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.cropper.ImageCropper\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.settings.CropDefaults\nimport com.t8rin.cropper.settings.CropProperties\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.opencv_tools.free_corners_crop.compose.FreeCornersCropper\nimport com.yalantis.ucrop.compose.UCropper\nimport kotlinx.coroutines.launch\nimport kotlin.math.roundToInt\n\n@Composable\nfun Cropper(\n    modifier: Modifier = Modifier,\n    bitmap: Bitmap,\n    crop: Boolean,\n    onImageCropStarted: () -> Unit,\n    onImageCropFinished: (Bitmap?) -> Unit,\n    cropType: CropType,\n    coercePointsToImageArea: Boolean,\n    rotationState: MutableFloatState,\n    cropProperties: CropProperties,\n    addVerticalInsets: Boolean\n) {\n    LaunchedEffect(crop) {\n        if (crop) onImageCropStarted()\n    }\n    AnimatedContent(\n        targetState = cropType,\n        transitionSpec = { fadeIn() togetherWith fadeOut() }\n    ) { type ->\n        when (type) {\n            CropType.Default -> {\n                val scope = rememberCoroutineScope()\n                UCropper(\n                    imageModel = bitmap,\n                    aspectRatio = if (cropProperties.aspectRatio != AspectRatio.Original) {\n                        cropProperties.aspectRatio.value\n                    } else null,\n                    modifier = Modifier.transparencyChecker(),\n                    containerModifier = Modifier.fillMaxSize(),\n                    hapticsStrength = LocalSettingsState.current.hapticsStrength,\n                    croppingTrigger = crop,\n                    onCropped = {\n                        scope.launch {\n                            BitmapFactory.decodeFile(it.toFile().absolutePath)\n                                .apply(onImageCropFinished)\n                        }\n                    },\n                    isOverlayDraggable = true,\n                    rotationAngleState = rotationState,\n                    onLoadingStateChange = {\n                        if (it) onImageCropStarted()\n                        else onImageCropFinished(null)\n                    },\n                    contentPadding = WindowInsets.systemBars.union(WindowInsets.displayCutout).let {\n                        if (addVerticalInsets) it.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom)\n                        else it.only(WindowInsetsSides.Horizontal)\n                    }.asPaddingValues()\n                )\n            }\n\n            CropType.NoRotation -> {\n                AnimatedContent(\n                    targetState = (cropProperties.aspectRatio != AspectRatio.Original) to bitmap,\n                    transitionSpec = { fadeIn() togetherWith fadeOut() },\n                    modifier = modifier.fillMaxSize(),\n                ) { (fixedAspectRatio, bitmap) ->\n                    Box {\n                        var zoomLevel by remember {\n                            mutableFloatStateOf(1f)\n                        }\n                        val bmp = remember(bitmap) { bitmap.asImageBitmap() }\n                        val minDimension = remember(cropProperties.handleSize) {\n                            val size = (cropProperties.handleSize * 3).roundToInt()\n\n                            IntSize(size, size)\n                        }\n                        ImageCropper(\n                            backgroundModifier = Modifier.transparencyChecker(),\n                            imageBitmap = bmp,\n                            contentDescription = null,\n                            cropProperties = cropProperties.copy(\n                                fixedAspectRatio = fixedAspectRatio,\n                                minDimension = minDimension\n                            ),\n                            onCropStart = onImageCropStarted,\n                            crop = crop,\n                            cropStyle = CropDefaults.style(\n                                overlayColor = MaterialTheme.colorScheme.surfaceVariant\n                            ),\n                            onZoomChange = { newZoom ->\n                                zoomLevel = newZoom\n                            },\n                            onCropSuccess = { image ->\n                                onImageCropFinished(image.asAndroidBitmap())\n                            }\n                        )\n                        BoxAnimatedVisibility(\n                            visible = zoomLevel > 1f,\n                            modifier = Modifier\n                                .padding(16.dp)\n                                .align(Alignment.TopStart),\n                            enter = scaleIn() + fadeIn(),\n                            exit = scaleOut() + fadeOut()\n                        ) {\n                            Text(\n                                text = stringResource(R.string.zoom) + \" ${zoomLevel.roundToTwoDigits()}x\",\n                                modifier = Modifier\n                                    .background(\n                                        color = MaterialTheme.colorScheme.scrim.copy(0.4f),\n                                        shape = ShapeDefaults.circle\n                                    )\n                                    .padding(horizontal = 8.dp, vertical = 4.dp),\n                                color = Color.White\n                            )\n                        }\n                    }\n                }\n            }\n\n            CropType.FreeCorners -> {\n                val settingsState = LocalSettingsState.current\n\n                FreeCornersCropper(\n                    bitmap = bitmap,\n                    croppingTrigger = crop,\n                    onCropped = {\n                        onImageCropFinished(it)\n                    },\n                    coercePointsToImageArea = coercePointsToImageArea,\n                    modifier = Modifier.transparencyChecker(),\n                    contentPadding = WindowInsets.systemBars.union(WindowInsets.displayCutout)\n                        .let {\n                            if (addVerticalInsets) it.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom)\n                            else it.only(WindowInsetsSides.Horizontal)\n                        }\n                        .union(\n                            WindowInsets(\n                                left = 16.dp,\n                                top = 16.dp,\n                                right = 16.dp,\n                                bottom = 16.dp\n                            )\n                        )\n                        .asPaddingValues(),\n                    showMagnifier = settingsState.magnifierEnabled\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/components/DefaultOutlineProperties.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.components\n\nimport androidx.compose.material3.MaterialShapes\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Shape\nimport com.t8rin.cropper.model.CornerRadiusProperties\nimport com.t8rin.cropper.model.CropShape\nimport com.t8rin.cropper.model.CustomPathOutline\nimport com.t8rin.cropper.model.CutCornerCropShape\nimport com.t8rin.cropper.model.ImageMaskOutline\nimport com.t8rin.cropper.model.OutlineType\nimport com.t8rin.cropper.model.RectCropShape\nimport com.t8rin.cropper.model.RoundedCornerCropShape\nimport com.t8rin.cropper.settings.CropOutlineProperty\nimport com.t8rin.cropper.settings.Paths\nimport com.t8rin.imagetoolbox.core.resources.shapes.ArrowShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.BookmarkShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.BurgerShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.DropletShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.EggShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ExplosionShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.KotlinShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.MapShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.OctagonShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.OvalShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.PentagonShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.PillShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ShieldShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.ShurikenShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SmallMaterialStarShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.SquircleShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.utils.toShape\n\nval DefaultOutlineProperties = listOf(\n    CropOutlineProperty(\n        outlineType = OutlineType.Rect,\n        cropOutline = RectCropShape(\n            id = 0,\n            title = OutlineType.Rect.name\n        )\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.RoundedRect,\n        cropOutline = RoundedCornerCropShape(\n            id = 1,\n            title = OutlineType.RoundedRect.name,\n            cornerRadius = CornerRadiusProperties()\n        )\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.CutCorner,\n        cropOutline = CutCornerCropShape(\n            id = 2,\n            title = OutlineType.CutCorner.name,\n            cornerRadius = CornerRadiusProperties()\n        )\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = OvalShape\n            override val id: Int = 3\n            override val title: String = \"Oval\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = SquircleShape\n            override val id: Int = 4\n            override val title: String = \"Squircle\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = OctagonShape\n            override val id: Int = 5\n            override val title: String = \"Octagon\"\n        },\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = PentagonShape\n            override val id: Int = 6\n            override val title: String = \"Pentagon\"\n        }\n    ),\n    CropOutlineProperty(\n        OutlineType.Custom,\n        object : CropShape {\n            override val shape: Shape = CloverShape\n            override val id: Int = 7\n            override val title: String = \"Clover\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = PillShape\n            override val id: Int = 8\n            override val title: String = \"Pill\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = BookmarkShape\n            override val id: Int = 9\n            override val title: String = \"Bookmark\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = BurgerShape\n            override val id: Int = 10\n            override val title: String = \"Burger\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = ShurikenShape\n            override val id: Int = 11\n            override val title: String = \"Shuriken\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = ExplosionShape\n            override val id: Int = 12\n            override val title: String = \"Explosion\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = MapShape\n            override val id: Int = 13\n            override val title: String = \"Map\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = MaterialStarShape\n            override val id: Int = 14\n            override val title: String = \"MaterialStar\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = SmallMaterialStarShape\n            override val id: Int = 15\n            override val title: String = \"SmallMaterialStar\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = ShieldShape\n            override val id: Int = 16\n            override val title: String = \"Shield\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = EggShape\n            override val id: Int = 17\n            override val title: String = \"Egg\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = DropletShape\n            override val id: Int = 18\n            override val title: String = \"Droplet\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = ArrowShape\n            override val id: Int = 19\n            override val title: String = \"Arrow\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = object : CropShape {\n            override val shape: Shape = KotlinShape\n            override val id: Int = 20\n            override val title: String = \"Kotlin\"\n        }\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = CustomPathOutline(\n            id = 21,\n            title = \"Heart\",\n            path = Paths.Favorite\n        )\n    ),\n    CropOutlineProperty(\n        outlineType = OutlineType.Custom,\n        cropOutline = CustomPathOutline(\n            id = 22,\n            title = \"Star\",\n            path = Paths.Star\n        )\n    ),\n).toMutableList().apply {\n    val shapes = listOf(\n        MaterialShapes.Slanted,\n        MaterialShapes.Arch,\n        MaterialShapes.Fan,\n        MaterialShapes.Arrow,\n        MaterialShapes.SemiCircle,\n        MaterialShapes.Oval,\n        MaterialShapes.Triangle,\n        MaterialShapes.Diamond,\n        MaterialShapes.ClamShell,\n        MaterialShapes.Gem,\n        MaterialShapes.Sunny,\n        MaterialShapes.VerySunny,\n        MaterialShapes.Cookie4Sided,\n        MaterialShapes.Cookie6Sided,\n        MaterialShapes.Cookie9Sided,\n        MaterialShapes.Cookie12Sided,\n        MaterialShapes.Ghostish,\n        MaterialShapes.Clover4Leaf,\n        MaterialShapes.Clover8Leaf,\n        MaterialShapes.Burst,\n        MaterialShapes.SoftBurst,\n        MaterialShapes.Boom,\n        MaterialShapes.SoftBoom,\n        MaterialShapes.Flower,\n        MaterialShapes.Puffy,\n        MaterialShapes.PuffyDiamond,\n        MaterialShapes.PixelCircle,\n        MaterialShapes.PixelTriangle,\n        MaterialShapes.Bun,\n        MaterialShapes.Heart\n    ).mapIndexed { index, polygon ->\n        CropOutlineProperty(\n            outlineType = OutlineType.Custom,\n            cropOutline = object : CropShape {\n                override val shape: Shape = polygon.toShape()\n                override val id: Int = index + 500\n                override val title: String = (index + 500).toString()\n            }\n        )\n    }\n    addAll(shapes)\n    add(\n        CropOutlineProperty(\n            outlineType = OutlineType.ImageMask,\n            cropOutline = ImageMaskOutline(\n                id = 23,\n                title = OutlineType.ImageMask.name,\n                image = ImageBitmap(\n                    width = 1,\n                    height = 1\n                )\n            )\n        )\n    )\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/components/FreeCornersCropToggle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Perspective\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun FreeCornersCropToggle(\n    value: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier\n) {\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = ShapeDefaults.extraLarge,\n        startIcon = Icons.Outlined.Perspective,\n        title = stringResource(R.string.free_corners),\n        subtitle = stringResource(R.string.free_corners_sub),\n        checked = value,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/crop/src/main/java/com/t8rin/imagetoolbox/feature/crop/presentation/screenLogic/CropComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.crop.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.model.OutlineType\nimport com.t8rin.cropper.model.RectCropShape\nimport com.t8rin.cropper.settings.CropDefaults\nimport com.t8rin.cropper.settings.CropOutlineProperty\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CropType\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass CropComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    private val _selectedAspectRatio: MutableState<DomainAspectRatio> =\n        mutableStateOf(DomainAspectRatio.Free)\n    val selectedAspectRatio by _selectedAspectRatio\n\n    private val defaultOutline = CropOutlineProperty(\n        OutlineType.Rect,\n        RectCropShape(\n            id = 0,\n            title = OutlineType.Rect.name\n        )\n    )\n\n    private val _cropProperties = mutableStateOf(\n        CropDefaults.properties(\n            cropOutlineProperty = defaultOutline,\n            fling = true\n        )\n    )\n    val cropProperties by _cropProperties\n\n    private val _cropType: MutableState<CropType> = mutableStateOf(CropType.Default)\n    val cropType: CropType by _cropType\n\n    private val _uri = mutableStateOf(Uri.EMPTY)\n\n    private var internalBitmap = mutableStateOf<Bitmap?>(null)\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    val isBitmapChanged get() = internalBitmap.value != _bitmap.value\n\n    private val _imageFormat = mutableStateOf<ImageFormat>(ImageFormat.Png.Lossless)\n    val imageFormat by _imageFormat\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    fun updateBitmap(\n        bitmap: Bitmap?,\n        newBitmap: Boolean = false\n    ) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            val bmp = imageScaler.scaleUntilCanShow(bitmap)\n            if (newBitmap) {\n                internalBitmap.value = bmp\n            }\n            _bitmap.value = bmp\n            _isImageLoading.value = false\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.value = imageFormat\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            bitmap?.let { localBitmap ->\n                val byteArray = imageCompressor.compressAndTransform(\n                    image = localBitmap,\n                    imageInfo = ImageInfo(\n                        originalUri = _uri.value.toString(),\n                        imageFormat = imageFormat,\n                        width = localBitmap.width,\n                        height = localBitmap.height\n                    )\n                )\n\n                val decoded = imageGetter.getImage(data = byteArray)\n\n                _bitmap.value = decoded\n\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = ImageInfo(\n                                originalUri = _uri.value.toString(),\n                                imageFormat = imageFormat,\n                                width = localBitmap.width,\n                                height = localBitmap.height\n                            ),\n                            originalUri = _uri.value.toString(),\n                            sequenceNumber = null,\n                            data = byteArray\n                        ),\n                        keepOriginalMetadata = false,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    )\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun setCropAspectRatio(\n        domainAspectRatio: DomainAspectRatio,\n        aspectRatio: AspectRatio\n    ) {\n        _cropProperties.update { properties ->\n            properties.copy(\n                aspectRatio = aspectRatio.takeIf {\n                    domainAspectRatio != DomainAspectRatio.Original\n                } ?: _bitmap.value?.let {\n                    AspectRatio(it.safeAspectRatio)\n                } ?: aspectRatio,\n                fixedAspectRatio = domainAspectRatio != DomainAspectRatio.Free\n            )\n        }\n        _selectedAspectRatio.update { domainAspectRatio }\n    }\n\n    fun setCropMask(cropOutlineProperty: CropOutlineProperty) {\n        _cropProperties.update { it.copy(cropOutlineProperty = cropOutlineProperty) }\n\n        if (cropOutlineProperty.cropOutline.id == 0) {\n            _cropType.update { CropType.Default }\n        } else {\n            _cropType.update { CropType.NoRotation }\n        }\n    }\n\n    fun toggleFreeCornersCrop() {\n        _cropType.update {\n            if (it != CropType.FreeCorners) {\n                CropType.FreeCorners\n            } else if (cropProperties.cropOutlineProperty.cropOutline.id != defaultOutline.cropOutline.id) {\n                CropType.NoRotation\n            } else {\n                CropType.Default\n            }\n        }\n    }\n\n    fun resetBitmap() {\n        _bitmap.value = internalBitmap.value\n    }\n\n    fun imageCropStarted() {\n        _isImageLoading.value = true\n    }\n\n    fun imageCropFinished() {\n        _isImageLoading.value = false\n    }\n\n    fun setUri(\n        uri: Uri\n    ) {\n        _uri.value = uri\n        imageGetter.getImageAsync(\n            uri = uri.toString(),\n            originalSize = true,\n            onGetImage = {\n                updateBitmap(it.image, true)\n                setImageFormat(it.imageInfo.imageFormat)\n            },\n            onFailure = AppToastHost::showFailureToast\n        )\n    }\n\n    fun shareBitmap() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            bitmap?.let { localBitmap ->\n                shareProvider.shareImage(\n                    imageInfo = ImageInfo(\n                        originalUri = _uri.value.toString(),\n                        imageFormat = imageFormat,\n                        width = localBitmap.width,\n                        height = localBitmap.height\n                    ),\n                    image = localBitmap,\n                    onComplete = {\n                        _isSaving.value = false\n                        AppToastHost.showConfetti()\n                    }\n                )\n            }\n        }\n    }\n\n    suspend fun loadImage(uri: Uri): Bitmap? = imageGetter.getImage(data = uri)\n\n    fun cancelSaving() {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = null\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            bitmap?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        originalUri = _uri.value.toString(),\n                        imageFormat = imageFormat,\n                        width = image.width,\n                        height = image.height\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): CropComponent\n    }\n}\n"
  },
  {
    "path": "feature/crop/src/main/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <dimen name=\"ucrop_default_crop_rect_min_size\" tools:override=\"true\">50dp</dimen>\n</resources>"
  },
  {
    "path": "feature/delete-exif/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/delete-exif/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.delete_exif\""
  },
  {
    "path": "feature/delete-exif/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/delete-exif/src/main/java/com/t8rin/imagetoolbox/feature/delete_exif/presentation/DeleteExifContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.delete_exif.presentation\n\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.localizedName\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.AddExifSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.delete_exif.presentation.screenLogic.DeleteExifComponent\n\n@Composable\nfun DeleteExifContent(\n    component: DeleteExifComponent\n) {\n    AutoContentBasedColors(component.bitmap)\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.updateUris(\n            uris = uris\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    var showExifSelection by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.delete_exif),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = rememberFileSize(component.selectedUri)\n            )\n        },\n        onGoBack = {\n            if (component.uris?.isNotEmpty() == true) showExitDialog = true\n            else component.onGoBack()\n        },\n        actions = {\n            if (component.previewBitmap != null) {\n                var editSheetData by remember {\n                    mutableStateOf(listOf<Uri>())\n                }\n                ShareButton(\n                    onShare = component::shareBitmaps,\n                    onCopy = {\n                        component.cacheCurrentImage(Clipboard::copy)\n                    },\n                    onEdit = {\n                        component.cacheImages {\n                            editSheetData = it\n                        }\n                    }\n                )\n                ProcessImagesPreferenceSheet(\n                    uris = editSheetData,\n                    visible = editSheetData.isNotEmpty(),\n                    onDismiss = {\n                        editSheetData = emptyList()\n                    },\n                    onNavigate = component.onNavigate\n                )\n            }\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.bitmap != null,\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.bitmap == null) {\n                TopAppBarEmoji()\n            }\n        },\n        imagePreview = {\n            ImageContainer(\n                modifier = Modifier\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                imageInside = isPortrait,\n                showOriginal = false,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.bitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = true\n            )\n        },\n        controls = {\n            val selectedTags = component.selectedTags\n            val subtitle by remember(selectedTags) {\n                derivedStateOf {\n                    if (selectedTags.isEmpty()) getString(R.string.all)\n                    else selectedTags.joinToString(\", \") {\n                        it.localizedName(appContext)\n                    }\n                }\n            }\n            ImageCounter(\n                imageCount = component.uris?.size?.takeIf { it > 1 },\n                onRepick = {\n                    showPickImageFromUrisSheet = true\n                }\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            PreferenceItem(\n                onClick = {\n                    showExifSelection = true\n                },\n                modifier = Modifier.fillMaxWidth(),\n                title = stringResource(R.string.tags_to_remove),\n                subtitle = subtitle,\n                shape = ShapeDefaults.extraLarge,\n                startIcon = Icons.Rounded.Exif,\n                endIcon = Icons.Rounded.MiniEdit\n            )\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        noDataControls = {\n            ImageNotPickedWidget(onPickImage = pickImage)\n        },\n        canShowScreenData = !component.uris.isNullOrEmpty()\n    )\n\n    AddExifSheet(\n        visible = showExifSelection,\n        onDismiss = { showExifSelection = it },\n        selectedTags = component.selectedTags,\n        onTagSelected = component::addTag,\n        isTagsRemovable = true\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris?.size ?: 1,\n        onCancelLoading = component::cancelSaving\n    )\n\n    PickImageFromUrisSheet(\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = component::updateSelectedUri,\n        onUriRemoved = { uri ->\n            component.updateUrisSilently(removedUri = uri)\n        },\n        columns = if (isPortrait) 2 else 4,\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/delete-exif/src/main/java/com/t8rin/imagetoolbox/feature/delete_exif/presentation/screenLogic/DeleteExifComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.delete_exif.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.clearAttributes\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\n\nclass DeleteExifComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val shareProvider: ShareProvider,\n    private val filenameCreator: FilenameCreator,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::updateUris)\n        }\n    }\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _selectedUri: MutableState<Uri?> = mutableStateOf(null)\n    val selectedUri by _selectedUri\n\n    private val _selectedTags: MutableState<List<MetadataTag>> = mutableStateOf(emptyList())\n    val selectedTags by _selectedTags\n\n    fun updateUris(\n        uris: List<Uri>?\n    ) {\n        _uris.value = null\n        _uris.value = uris\n        uris?.firstOrNull()?.let(::updateSelectedUri)\n    }\n\n    fun updateUrisSilently(removedUri: Uri) {\n        componentScope.launch {\n            _uris.value = uris\n            if (_selectedUri.value == removedUri) {\n                val index = uris?.indexOf(removedUri) ?: -1\n                if (index == 0) {\n                    uris?.getOrNull(1)?.let {\n                        _selectedUri.value = it\n                        _bitmap.value =\n                            imageGetter.getImage(it.toString(), originalSize = false)?.image\n                    }\n                } else {\n                    uris?.getOrNull(index - 1)?.let {\n                        _selectedUri.value = it\n                        _bitmap.value =\n                            imageGetter.getImage(it.toString(), originalSize = false)?.image\n                    }\n                }\n            }\n            val u = _uris.value?.toMutableList()?.apply {\n                remove(removedUri)\n            }\n            _uris.value = u\n        }\n    }\n\n    private fun updateBitmap(bitmap: Bitmap?) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            _bitmap.value = bitmap\n            _previewBitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n            delay(500)\n            _isImageLoading.value = false\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    imageGetter.getImage(uri.toString())\n                }.getOrNull()?.let {\n                    val metadata = if (selectedTags.isNotEmpty()) {\n                        it.metadata?.clearAttributes(selectedTags)\n                    } else null\n\n                    results.add(\n                        fileController.save(\n                            ImageSaveTarget(\n                                imageInfo = it.imageInfo,\n                                originalUri = uri.toString(),\n                                sequenceNumber = _done.value,\n                                metadata = metadata,\n                                data = ByteArray(0),\n                                readFromUriInsteadOfData = true\n                            ),\n                            keepOriginalMetadata = false,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    )\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun updateSelectedUri(\n        uri: Uri\n    ) = componentScope.launch {\n        _isImageLoading.value = true\n        _selectedUri.value = uri\n        imageGetter.getImageAsync(\n            uri = uri.toString(),\n            originalSize = false,\n            onGetImage = {\n                updateBitmap(it.image)\n            },\n            onFailure = {\n                _isImageLoading.value = false\n                AppToastHost.showFailureToast(it)\n            }\n        )\n    }\n\n    fun shareBitmaps() {\n        _isSaving.update { true }\n        cacheImages { uris ->\n            savingJob = trackProgress {\n                shareProvider.shareUris(uris.map(Uri::toString))\n                AppToastHost.showConfetti()\n                _isSaving.update { false }\n            }\n        }\n    }\n\n    fun cancelSaving() {\n        _isSaving.update { false }\n        savingJob?.cancel()\n        savingJob = null\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        cacheImages(\n            uris = listOfNotNull(selectedUri),\n            onComplete = {\n                if (it.isNotEmpty()) onComplete(it.first())\n            }\n        )\n    }\n\n    fun addTag(tag: MetadataTag) {\n        if (tag in selectedTags) {\n            _selectedTags.update { it - tag }\n        } else {\n            _selectedTags.update { it + tag }\n        }\n    }\n\n    fun cacheImages(\n        uris: List<Uri>? = this.uris,\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            val list = mutableListOf<Uri>()\n            uris?.forEach { uri ->\n                imageGetter.getImage(\n                    uri.toString()\n                )?.let {\n                    val metadata = if (selectedTags.isNotEmpty()) {\n                        it.metadata?.clearAttributes(selectedTags)\n                    } else null\n\n                    shareProvider.cacheData(\n                        writeData = { w ->\n                            w.writeBytes(\n                                fileController.readBytes(uri.toString())\n                            )\n                        },\n                        filename = filenameCreator.constructImageFilename(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = it.imageInfo.copy(originalUri = uri.toString()),\n                                originalUri = uri.toString(),\n                                sequenceNumber = done,\n                                metadata = metadata,\n                                data = ByteArray(0)\n                            )\n                        )\n                    )?.let { uri ->\n                        fileController.writeMetadata(\n                            imageUri = uri,\n                            metadata = metadata\n                        )\n                        list.add(uri.toUri())\n                    }\n                }\n                _done.value++\n                updateProgress(\n                    done = done,\n                    total = uris.size\n                )\n            }\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): DeleteExifComponent\n    }\n}"
  },
  {
    "path": "feature/document-scanner/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/document-scanner/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.document_scanner\"\n\ndependencies {\n    implementation(projects.feature.pdfTools)\n}"
  },
  {
    "path": "feature/document-scanner/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/document-scanner/src/main/java/com/t8rin/imagetoolbox/feature/document_scanner/presentation/DocumentScannerContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.document_scanner.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Share\nimport androidx.compose.material.icons.rounded.DocumentScanner\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.Pdf\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberDocumentScanner\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.FileNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagePager\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.document_scanner.presentation.screenLogic.DocumentScannerComponent\n\n\n@Composable\nfun DocumentScannerContent(\n    component: DocumentScannerComponent\n) {\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val savePdfLauncher = rememberFileCreator(\n        mimeType = MimeType.Pdf,\n        onSuccess = component::savePdfTo\n    )\n\n    val documentScanner = rememberDocumentScanner {\n        component.parseScanResult(it)\n    }\n\n    val additionalDocumentScanner = rememberDocumentScanner {\n        component.addScanResult(it)\n    }\n\n    AutoFilePicker(\n        onAutoPick = documentScanner::scan,\n        isPickedAlready = false\n    )\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            Text(\n                text = stringResource(R.string.document_scanner),\n                modifier = Modifier.marquee()\n            )\n        },\n        topAppBarPersistentActions = {\n            TopAppBarEmoji()\n        },\n        onGoBack = onBack,\n        actions = {},\n        imagePreview = {},\n        showImagePreviewAsStickyHeader = false,\n        placeImagePreview = false,\n        addHorizontalCutoutPaddingIfNoPreview = false,\n        noDataControls = {\n            FileNotPickedWidget(\n                onPickFile = documentScanner::scan,\n                text = stringResource(R.string.click_to_start_scanning)\n            )\n        },\n        controls = {\n            var selectedUriForPreview by remember {\n                mutableStateOf<Uri?>(null)\n            }\n            ImagePager(\n                visible = selectedUriForPreview != null,\n                selectedUri = selectedUriForPreview,\n                uris = component.uris,\n                onNavigate = {\n                    selectedUriForPreview = null\n                    component.onNavigate(it)\n                },\n                onUriSelected = { selectedUriForPreview = it },\n                onShare = component::shareUri,\n                onDismiss = { selectedUriForPreview = null }\n            )\n            Spacer(modifier = Modifier.height(24.dp))\n            UrisPreview(\n                uris = component.uris,\n                isPortrait = isPortrait,\n                onRemoveUri = component::removeImageUri,\n                onAddUris = additionalDocumentScanner::scan,\n                addUrisContent = { width ->\n                    Icon(\n                        imageVector = Icons.Rounded.AddPhotoAlt,\n                        contentDescription = stringResource(R.string.add),\n                        modifier = Modifier.size(width / 3f)\n                    )\n                },\n                onClickUri = { uri ->\n                    selectedUriForPreview = uri\n                }\n            )\n            Spacer(modifier = Modifier.height(12.dp))\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .container(\n                        resultPadding = 0.dp,\n                        shape = ShapeDefaults.large,\n                        color = MaterialTheme.colorScheme.surfaceContainerLow\n                    )\n                    .padding(8.dp),\n            ) {\n                EnhancedButton(\n                    onClick = component::sharePdf,\n                    containerColor = MaterialTheme.colorScheme.secondary,\n                    contentPadding = PaddingValues(\n                        top = 8.dp,\n                        bottom = 8.dp,\n                        start = 12.dp,\n                        end = 20.dp\n                    ),\n                    shape = ShapeDefaults.top,\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Share,\n                        contentDescription = stringResource(R.string.share_as_pdf)\n                    )\n                    Spacer(Modifier.width(8.dp))\n                    AutoSizeText(\n                        text = stringResource(id = R.string.share_as_pdf),\n                        maxLines = 2\n                    )\n                }\n                Spacer(Modifier.height(4.dp))\n                EnhancedButton(\n                    onClick = {\n                        savePdfLauncher.make(component.generatePdfFilename())\n                    },\n                    contentPadding = PaddingValues(\n                        top = 8.dp,\n                        bottom = 8.dp,\n                        start = 16.dp,\n                        end = 20.dp\n                    ),\n                    shape = ShapeDefaults.bottom,\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Pdf,\n                        contentDescription = stringResource(R.string.save_as_pdf)\n                    )\n                    Spacer(Modifier.width(8.dp))\n                    AutoSizeText(\n                        text = stringResource(id = R.string.save_as_pdf),\n                        maxLines = 2\n                    )\n                }\n            }\n            Spacer(modifier = Modifier.height(24.dp))\n            InfoContainer(\n                modifier = Modifier.padding(8.dp),\n                text = stringResource(R.string.options_below_is_for_images)\n            )\n            if (component.imageFormat.canChangeCompressionValue) {\n                Spacer(Modifier.height(8.dp))\n            }\n            QualitySelector(\n                imageFormat = component.imageFormat,\n                quality = component.quality,\n                onQualityChange = component::setQuality\n            )\n            Spacer(Modifier.height(8.dp))\n            ImageFormatSelector(\n                value = component.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = component.quality,\n            )\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isEmpty(),\n                onSecondaryButtonClick = documentScanner::scan,\n                secondaryButtonIcon = Icons.Rounded.DocumentScanner,\n                secondaryButtonText = stringResource(R.string.start_scanning),\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    ShareButton(\n                        enabled = component.uris.isNotEmpty(),\n                        onShare = component::shareBitmaps\n                    )\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n        },\n        canShowScreenData = component.uris.isNotEmpty()\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n}"
  },
  {
    "path": "feature/document-scanner/src/main/java/com/t8rin/imagetoolbox/feature/document_scanner/presentation/screenLogic/DocumentScannerComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.document_scanner.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ScanResult\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.coroutineScope\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCreationParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlin.random.Random\n\nclass DocumentScannerComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val pdfManager: PdfManager,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _uris = mutableStateOf<List<Uri>>(emptyList())\n    val uris by _uris\n\n    private val _imageFormat = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    private val _quality = mutableStateOf<Quality>(Quality.Base())\n    val quality by _quality\n\n    private val _pdfUris = mutableStateOf<List<Uri>>(emptyList())\n\n    private suspend fun getPdfUri(): Uri? =\n        if (_pdfUris.value.size > 1 || _pdfUris.value.isEmpty()) {\n            createPdfUri()\n        } else _pdfUris.value.firstOrNull()\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    fun parseScanResult(scanResult: ScanResult) {\n        if (scanResult.imageUris.isNotEmpty()) {\n            _uris.update { scanResult.imageUris }\n        }\n        if (scanResult.pdfUri != null) {\n            _pdfUris.update { listOfNotNull(scanResult.pdfUri) }\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            uris.forEach { uri ->\n                runSuspendCatching {\n                    imageGetter.getImage(uri.toString())?.image\n                }.getOrNull()?.let { bitmap ->\n                    val imageInfo = ImageInfo(\n                        width = bitmap.width,\n                        height = bitmap.height,\n                        imageFormat = imageFormat,\n                        quality = quality,\n                        originalUri = uri.toString()\n                    )\n                    results.add(\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                metadata = null,\n                                originalUri = uri.toString(),\n                                sequenceNumber = _done.value + 1,\n                                data = imageCompressor.compressAndTransform(\n                                    image = bitmap,\n                                    imageInfo = imageInfo\n                                )\n                            ),\n                            keepOriginalMetadata = true,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    )\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun savePdfTo(\n        uri: Uri\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getPdfUri()?.let { pdfUri ->\n                fileController.transferBytes(\n                    fromUri = pdfUri.toString(),\n                    toUri = uri.toString(),\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n                _isSaving.value = false\n            }\n        }\n    }\n\n    private suspend fun createPdfUri(): Uri? {\n        _done.update { 0 }\n        _left.update { 0 }\n        return runSuspendCatching {\n            pdfManager.createPdf(\n                imageUris = uris.map { it.toString() },\n                params = PdfCreationParams()\n            )\n        }.getOrNull()?.toUri()\n    }\n\n    fun generatePdfFilename(): String {\n        val timeStamp = \"${timestamp()}_${Random(Random.nextInt()).hashCode().toString().take(4)}\"\n        return \"PDF_$timeStamp.pdf\"\n    }\n\n    fun sharePdf() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getPdfUri()?.let { pdfUri ->\n                _done.update { 0 }\n                _left.update { 0 }\n\n                runSuspendCatching {\n                    shareProvider.shareUri(\n                        uri = pdfUri.toString(),\n                        onComplete = AppToastHost::showConfetti\n                    )\n                }.onFailure {\n                    val bytes = fileController.readBytes(pdfUri.toString())\n                    shareProvider.shareByteArray(\n                        byteArray = bytes,\n                        filename = generatePdfFilename(),\n                        onComplete = AppToastHost::showConfetti\n                    )\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun removeImageUri(uri: Uri) {\n        _uris.update { it - uri }\n        _pdfUris.update { emptyList() }\n    }\n\n    fun addScanResult(scanResult: ScanResult) {\n        _uris.update { (it + scanResult.imageUris).distinct() }\n        _pdfUris.update { (it + scanResult.pdfUri).distinct().filterNotNull() }\n    }\n\n    fun shareBitmaps() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            shareProvider.shareImages(\n                uris = uris.map { it.toString() },\n                imageLoader = { uri ->\n                    imageGetter.getImage(uri)?.image?.let { bmp ->\n                        bmp to ImageInfo(\n                            width = bmp.width,\n                            height = bmp.height,\n                            imageFormat = imageFormat,\n                            quality = quality,\n                            originalUri = uri\n                        )\n                    }\n                },\n                onProgressChange = {\n                    if (it == -1) {\n                        AppToastHost.showConfetti()\n                        _isSaving.value = false\n                        _done.value = 0\n                    } else {\n                        _done.value = it\n                    }\n                    updateProgress(\n                        done = done,\n                        total = left\n                    )\n                }\n            )\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n    }\n\n    fun setQuality(quality: Quality) {\n        _quality.update { quality }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n    fun shareUri(uri: Uri) {\n        coroutineScope.launch {\n            shareProvider.shareUri(\n                uri = uri.toString(),\n                onComplete = {}\n            )\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): DocumentScannerComponent\n    }\n\n}"
  },
  {
    "path": "feature/draw/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/draw/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.draw\"\n\ndependencies {\n    implementation(libs.trickle)\n\n    implementation(projects.core.filters)\n    implementation(projects.feature.pickColor)\n}"
  },
  {
    "path": "feature/draw/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/data/AndroidImageDrawApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.BlurMaskFilter\nimport android.graphics.Matrix\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.ImageShader\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.PaintingStyle\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.StampedPathEffectStyle\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.addOutline\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.drawable.toBitmap\nimport androidx.core.graphics.drawable.toDrawable\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.density\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.data.utils.toSoftware\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.max\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.createFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.SpotHealMode\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.utils.toImageModel\nimport com.t8rin.imagetoolbox.core.utils.toTypeface\nimport com.t8rin.imagetoolbox.feature.draw.data.utils.drawRepeatedBitmapOnPath\nimport com.t8rin.imagetoolbox.feature.draw.data.utils.drawRepeatedTextOnPath\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawBehavior\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.ImageDrawApplier\nimport com.t8rin.imagetoolbox.feature.draw.domain.PathPaint\nimport com.t8rin.trickle.WarpBrush\nimport com.t8rin.trickle.WarpEngine\nimport com.t8rin.trickle.WarpMode\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport javax.inject.Inject\nimport kotlin.math.roundToInt\nimport android.graphics.Paint as AndroidPaint\nimport android.graphics.Path as NativePath\n\ninternal class AndroidImageDrawApplier @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n) : ImageDrawApplier<Bitmap, Path, Color> {\n\n    override suspend fun applyDrawToImage(\n        drawBehavior: DrawBehavior,\n        pathPaints: List<PathPaint<Path, Color>>,\n        imageUri: String\n    ): Bitmap? {\n        val image: Bitmap? = when (drawBehavior) {\n            is DrawBehavior.Image -> {\n                imageGetter.getImage(data = imageUri)\n            }\n\n            is DrawBehavior.Background -> {\n                drawBehavior.color.toDrawable().toBitmap(\n                    width = drawBehavior.width,\n                    height = drawBehavior.height\n                )\n            }\n\n            else -> null\n        }\n\n        val drawImage = image?.let {\n            createBitmap(it.width, it.height, it.safeConfig).apply { setHasAlpha(true) }\n        }\n\n        drawImage?.let { bitmap ->\n            bitmap.applyCanvas {\n                val canvasSize = IntegerSize(width, height)\n\n                (drawBehavior as? DrawBehavior.Background)?.apply { drawColor(color) }\n\n                pathPaints.forEach { (nonScaledPath, nonScaledStroke, radius, drawColor, isErasing, drawMode, size, drawPathMode, drawLineStyle) ->\n                    val stroke = drawPathMode.convertStrokeWidth(\n                        strokeWidth = nonScaledStroke,\n                        canvasSize = canvasSize\n                    )\n                    val path = nonScaledPath.scaleToFitCanvas(\n                        currentSize = canvasSize,\n                        oldSize = size\n                    )\n                    val isSharpEdge = drawPathMode.isSharpEdge\n                    val isFilled = drawPathMode.isFilled\n\n                    if (drawMode is DrawMode.PathEffect && !isErasing) {\n                        val paint = Paint().apply {\n                            if (isFilled) {\n                                style = PaintingStyle.Fill\n                            } else {\n                                style = PaintingStyle.Stroke\n                                this.strokeWidth = stroke\n                                if (isSharpEdge) {\n                                    strokeCap = StrokeCap.Square\n                                } else {\n                                    strokeCap = StrokeCap.Round\n                                    strokeJoin = StrokeJoin.Round\n                                }\n                            }\n\n                            color = Color.Transparent\n                            blendMode = BlendMode.Clear\n                        }\n\n                        val shaderSource = imageTransformer.transform(\n                            image = image.overlay(bitmap),\n                            transformations = transformationsForMode(\n                                canvasSize = canvasSize,\n                                drawMode = drawMode\n                            )\n                        )?.asImageBitmap()?.clipBitmap(\n                            path = path,\n                            paint = paint\n                        )\n                        if (shaderSource != null) {\n                            drawBitmap(shaderSource.asAndroidBitmap())\n                        }\n                    } else if (drawMode is DrawMode.SpotHeal && !isErasing) {\n                        val paint = Paint().apply {\n                            if (isFilled) {\n                                style = PaintingStyle.Fill\n                            } else {\n                                style = PaintingStyle.Stroke\n                                this.strokeWidth = stroke\n                                if (isSharpEdge) {\n                                    strokeCap = StrokeCap.Square\n                                } else {\n                                    strokeCap = StrokeCap.Round\n                                    strokeJoin = StrokeJoin.Round\n                                }\n                            }\n\n                            color = Color.White\n                        }\n\n                        val filter = filterProvider.filterToTransformation(\n                            createFilter<Pair<ImageModel, SpotHealMode>, Filter.SpotHeal>(\n                                Pair(\n                                    createBitmap(\n                                        canvasSize.width,\n                                        canvasSize.height\n                                    ).applyCanvas {\n                                        drawColor(Color.Black.toArgb())\n                                        drawPath(\n                                            path.asAndroidPath(),\n                                            paint.nativePaint\n                                        )\n                                    }.toImageModel(),\n                                    drawMode.mode\n                                )\n                            )\n                        )\n\n                        imageTransformer.transform(\n                            image = image.overlay(bitmap),\n                            transformations = listOf(filter)\n                        )?.let {\n                            drawBitmap(\n                                it.asImageBitmap().clipBitmap(\n                                    path = path,\n                                    paint = paint.apply {\n                                        blendMode = BlendMode.Clear\n                                    }\n                                ).asAndroidBitmap()\n                            )\n                        }\n                    } else if (drawMode is DrawMode.Warp && !isErasing) {\n                        val engine = WarpEngine(image.overlay(bitmap))\n\n                        try {\n                            drawMode.strokes.forEach { warpStroke ->\n                                val warp = warpStroke.scaleToFitCanvas(\n                                    currentSize = canvasSize,\n                                    oldSize = size\n                                )\n                                engine.applyStroke(\n                                    fromX = warp.fromX,\n                                    fromY = warp.fromY,\n                                    toX = warp.toX,\n                                    toY = warp.toY,\n                                    brush = WarpBrush(\n                                        radius = stroke,\n                                        strength = drawMode.strength,\n                                        hardness = drawMode.hardness\n                                    ),\n                                    mode = WarpMode.valueOf(drawMode.warpMode.name)\n                                )\n                            }\n\n                            drawBitmap(engine.render())\n                        } finally {\n                            engine.release()\n                        }\n                    } else {\n                        val paint = Paint().apply {\n                            if (isErasing) {\n                                blendMode = BlendMode.Clear\n                                style = PaintingStyle.Stroke\n                                this.strokeWidth = stroke\n                                strokeCap = StrokeCap.Round\n                                strokeJoin = StrokeJoin.Round\n                            } else {\n                                if (drawMode !is DrawMode.Text) {\n                                    pathEffect = drawLineStyle.asPathEffect(\n                                        canvasSize = canvasSize,\n                                        strokeWidth = stroke\n                                    )\n                                    if (isFilled) {\n                                        style = PaintingStyle.Fill\n                                    } else {\n                                        style = PaintingStyle.Stroke\n                                        strokeWidth = stroke\n                                        if (drawMode is DrawMode.Highlighter || isSharpEdge) {\n                                            strokeCap = StrokeCap.Square\n                                        } else {\n                                            strokeCap = StrokeCap.Round\n                                            strokeJoin = StrokeJoin.Round\n                                        }\n                                    }\n                                }\n                            }\n                            color = drawColor\n                            alpha = drawColor.alpha\n                        }.nativePaint.apply {\n                            if (drawMode is DrawMode.Neon && !isErasing) {\n                                this.color = Color.White.toArgb()\n                                setShadowLayer(\n                                    radius.toPx(canvasSize),\n                                    0f,\n                                    0f,\n                                    drawColor\n                                        .copy(alpha = .8f)\n                                        .toArgb()\n                                )\n                            } else if (radius.value > 0f) {\n                                maskFilter =\n                                    BlurMaskFilter(\n                                        radius.toPx(canvasSize),\n                                        BlurMaskFilter.Blur.NORMAL\n                                    )\n                            }\n                            if (drawMode is DrawMode.Text && !isErasing) {\n                                isAntiAlias = true\n                                textSize = stroke\n                                typeface = drawMode.font.toTypeface()\n                            }\n                        }\n                        val androidPath = path.asAndroidPath()\n                        if (drawMode is DrawMode.Text && !isErasing) {\n                            if (drawMode.isRepeated) {\n                                drawRepeatedTextOnPath(\n                                    text = drawMode.text,\n                                    path = androidPath,\n                                    paint = paint,\n                                    interval = drawMode.repeatingInterval.toPx(canvasSize)\n                                )\n                            } else {\n                                drawTextOnPath(drawMode.text, androidPath, 0f, 0f, paint)\n                            }\n                        } else if (drawMode is DrawMode.Image && !isErasing) {\n                            imageGetter.getImage(\n                                data = drawMode.imageData,\n                                size = stroke.roundToInt()\n                            )?.let {\n                                drawRepeatedBitmapOnPath(\n                                    bitmap = it,\n                                    path = androidPath,\n                                    paint = paint,\n                                    interval = drawMode.repeatingInterval.toPx(canvasSize)\n                                )\n                            }\n                        } else if (drawPathMode is DrawPathMode.Outlined) {\n                            drawPathMode.fillColor?.let { fillColor ->\n                                val filledPaint = AndroidPaint().apply {\n                                    set(paint)\n                                    style = AndroidPaint.Style.FILL\n                                    color = fillColor.colorInt\n                                    if (Color(fillColor.colorInt).alpha == 1f) {\n                                        alpha =\n                                            (drawColor.alpha * 255).roundToInt().coerceIn(0, 255)\n                                    }\n                                    pathEffect = null\n                                }\n\n                                drawPath(androidPath, filledPaint)\n                            }\n                            drawPath(androidPath, paint)\n                        } else {\n                            drawPath(androidPath, paint)\n                        }\n                    }\n                }\n            }\n        }\n        return drawImage?.let { image.overlay(it) }\n    }\n\n    override suspend fun applyEraseToImage(\n        pathPaints: List<PathPaint<Path, Color>>,\n        imageUri: String\n    ): Bitmap? = applyEraseToImage(\n        pathPaints = pathPaints,\n        image = imageGetter.getImage(data = imageUri),\n        shaderSourceUri = imageUri\n    )\n\n    override suspend fun applyEraseToImage(\n        pathPaints: List<PathPaint<Path, Color>>,\n        image: Bitmap?,\n        shaderSourceUri: String\n    ): Bitmap? = image?.let { it.copy(it.safeConfig, true) }?.let { bitmap ->\n        bitmap.applyCanvas {\n            val canvasSize = IntegerSize(width, height)\n\n            drawBitmap(bitmap)\n\n            val recoveryShader = imageGetter.getImage(\n                data = shaderSourceUri\n            )?.asImageBitmap()?.let { bmp -> ImageShader(bmp) }\n\n            pathPaints.forEach { (nonScaledPath, stroke, radius, _, isRecoveryOn, _, size, mode) ->\n                val path = nonScaledPath.scaleToFitCanvas(\n                    currentSize = canvasSize,\n                    oldSize = size\n                )\n\n                drawPath(\n                    path.asAndroidPath(),\n                    Paint().apply {\n                        if (mode.isFilled) {\n                            style = PaintingStyle.Fill\n                        } else {\n                            style = PaintingStyle.Stroke\n                            this.strokeWidth = mode.convertStrokeWidth(\n                                strokeWidth = stroke,\n                                canvasSize = canvasSize\n                            )\n                            if (mode.isSharpEdge) {\n                                strokeCap = StrokeCap.Square\n                            } else {\n                                strokeCap = StrokeCap.Round\n                                strokeJoin = StrokeJoin.Round\n                            }\n                        }\n                        if (isRecoveryOn) {\n                            shader = recoveryShader\n                        } else {\n                            blendMode = BlendMode.Clear\n                        }\n                    }.nativePaint.apply {\n                        if (radius.value > 0f) {\n                            maskFilter =\n                                BlurMaskFilter(\n                                    radius.toPx(canvasSize),\n                                    BlurMaskFilter.Blur.NORMAL\n                                )\n                        }\n                    }\n                )\n            }\n\n        }\n    }\n\n    private fun transformationsForMode(\n        canvasSize: IntegerSize,\n        drawMode: DrawMode\n    ): List<Transformation<Bitmap>> = when (drawMode) {\n        is DrawMode.PathEffect.PrivacyBlur -> {\n            listOf(\n                createFilter<Float, Filter.NativeStackBlur>(\n                    drawMode.blurRadius.toFloat() / 1000 * max(canvasSize)\n                )\n            )\n        }\n\n        is DrawMode.PathEffect.Pixelation -> {\n            listOf(\n                createFilter<Float, Filter.NativeStackBlur>(\n                    20.toFloat() / 1000 * max(canvasSize)\n                ),\n                createFilter<Float, Filter.Pixelation>(\n                    drawMode.pixelSize / 1000 * max(canvasSize)\n                )\n            )\n        }\n\n        is DrawMode.PathEffect.Custom -> drawMode.filter?.let {\n            listOf(it)\n        } ?: emptyList()\n\n        else -> emptyList()\n    }.map {\n        filterProvider.filterToTransformation(it)\n    }\n\n    private fun DrawLineStyle.asPathEffect(\n        canvasSize: IntegerSize,\n        strokeWidth: Float\n    ): PathEffect? = when (this) {\n        is DrawLineStyle.Dashed -> {\n            PathEffect.dashPathEffect(\n                intervals = floatArrayOf(\n                    size.toPx(canvasSize),\n                    gap.toPx(canvasSize) + strokeWidth\n                ),\n                phase = 0f\n            )\n        }\n\n        DrawLineStyle.DotDashed -> {\n            val dashOnInterval1 = strokeWidth * 4\n            val dashOffInterval1 = strokeWidth * 2\n            val dashOnInterval2 = strokeWidth / 4\n            val dashOffInterval2 = strokeWidth * 2\n\n            PathEffect.dashPathEffect(\n                intervals = floatArrayOf(\n                    dashOnInterval1,\n                    dashOffInterval1,\n                    dashOnInterval2,\n                    dashOffInterval2\n                ),\n                phase = 0f\n            )\n        }\n\n        is DrawLineStyle.Stamped<*> -> {\n            fun Shape.toPath(): Path = Path().apply {\n                addOutline(\n                    createOutline(\n                        size = Size(strokeWidth, strokeWidth),\n                        layoutDirection = LayoutDirection.Ltr,\n                        density = context.density\n                    )\n                )\n            }\n\n            val path: Path? = when (shape) {\n                is Shape -> shape.toPath()\n                is NativePath -> shape.asComposePath()\n                is Path -> shape\n                null -> MaterialStarShape.toPath()\n                else -> null\n            }\n\n            path?.let {\n                PathEffect.stampedPathEffect(\n                    shape = it,\n                    advance = spacing.toPx(canvasSize) + strokeWidth,\n                    phase = 0f,\n                    style = StampedPathEffectStyle.Morph\n                )\n            }\n        }\n\n        is DrawLineStyle.ZigZag -> {\n            val zigZagPath = Path().apply {\n                val zigZagLineWidth = strokeWidth / heightRatio\n                val shapeVerticalOffset = (strokeWidth / 2) / 2\n                val shapeHorizontalOffset = (strokeWidth / 2) / 2\n                moveTo(0f, 0f)\n                lineTo(strokeWidth / 2, strokeWidth / 2)\n                lineTo(strokeWidth, 0f)\n                lineTo(strokeWidth, 0f + zigZagLineWidth)\n                lineTo(strokeWidth / 2, strokeWidth / 2 + zigZagLineWidth)\n                lineTo(0f, 0f + zigZagLineWidth)\n                translate(Offset(-shapeHorizontalOffset, -shapeVerticalOffset))\n            }\n            PathEffect.stampedPathEffect(\n                shape = zigZagPath,\n                advance = strokeWidth,\n                phase = 0f,\n                style = StampedPathEffectStyle.Morph\n            )\n        }\n\n        DrawLineStyle.None -> null\n    }\n\n    private fun ImageBitmap.clipBitmap(\n        path: Path,\n        paint: Paint,\n    ): ImageBitmap {\n        val newPath = NativePath(path.asAndroidPath())\n\n        return asAndroidBitmap().copy(Bitmap.Config.ARGB_8888, true).applyCanvas {\n            drawPath(\n                newPath.apply {\n                    fillType = NativePath.FillType.INVERSE_WINDING\n                },\n                paint.nativePaint\n            )\n        }.asImageBitmap()\n    }\n\n    private fun Bitmap.overlay(overlay: Bitmap): Bitmap {\n        val image = this\n\n        return createBitmap(\n            width = image.width,\n            height = image.height,\n            config = safeConfig.toSoftware()\n        ).applyCanvas {\n            drawBitmap(image)\n            drawBitmap(overlay.toSoftware())\n        }\n    }\n\n    private fun Path.scaleToFitCanvas(\n        currentSize: IntegerSize,\n        oldSize: IntegerSize,\n        onGetScale: (Float, Float) -> Unit = { _, _ -> }\n    ): Path {\n        val sx = currentSize.width.toFloat() / oldSize.width\n        val sy = currentSize.height.toFloat() / oldSize.height\n        onGetScale(sx, sy)\n        return NativePath(this.asAndroidPath()).apply {\n            transform(\n                Matrix().apply {\n                    setScale(sx, sy)\n                }\n            )\n        }.asComposePath()\n    }\n\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/data/utils/DrawRepeatedPath.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.data.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Matrix\nimport android.graphics.Paint\nimport android.graphics.Path\nimport android.graphics.PathMeasure\nimport androidx.core.graphics.withSave\nimport kotlin.math.atan2\n\nfun Canvas.drawRepeatedTextOnPath(\n    text: String,\n    path: Path,\n    paint: Paint,\n    interval: Float = 0f\n) {\n    val pathMeasure = PathMeasure(path, false)\n    val pathLength = pathMeasure.length\n\n    val textWidth = paint.measureText(text)\n\n    val fullRepeats = (pathLength / (textWidth + interval)).toInt()\n\n    val remainingLength = pathLength - fullRepeats * (textWidth + interval)\n\n    var distance = 0f\n\n    repeat(fullRepeats) {\n        drawTextOnPath(text, path, distance, 0f, paint)\n        distance += (textWidth + interval)\n    }\n\n    if (remainingLength > 0f) {\n        val ratio = (textWidth + interval - (remainingLength)) / (textWidth + interval)\n        val endOffset = (text.length - (text.length * ratio).toInt()).coerceAtLeast(0)\n        drawTextOnPath(text.substring(0, endOffset), path, distance, 0f, paint)\n    }\n}\n\n\nfun Canvas.drawRepeatedBitmapOnPath(\n    bitmap: Bitmap,\n    path: Path,\n    paint: Paint,\n    interval: Float = 0f\n) {\n    val pathMeasure = PathMeasure(path, false)\n    val pathLength = pathMeasure.length\n\n    val bitmapWidth = bitmap.width.toFloat()\n    val bitmapHeight = bitmap.height.toFloat()\n\n    var distance = 0f\n    val matrix = Matrix()\n\n    while (distance < pathLength) {\n        val pos = FloatArray(2)\n        val tan = FloatArray(2)\n        pathMeasure.getPosTan(distance, pos, tan)\n\n        val degree = Math.toDegrees(atan2(tan[1].toDouble(), tan[0].toDouble())).toFloat()\n\n        withSave {\n            translate(pos[0], pos[1])\n            rotate(degree)\n\n            matrix.reset()\n            matrix.postTranslate(-bitmapWidth / 2, -bitmapHeight / 2)\n            matrix.postRotate(degree)\n            matrix.postTranslate(bitmapWidth / 2, bitmapHeight / 2)\n            drawBitmap(bitmap, matrix, paint)\n        }\n\n        if (interval < 0 && distance + bitmapWidth < 0) break\n        else {\n            distance += (bitmapWidth + interval)\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/di/DrawModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.di\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport com.t8rin.imagetoolbox.feature.draw.data.AndroidImageDrawApplier\nimport com.t8rin.imagetoolbox.feature.draw.domain.ImageDrawApplier\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface DrawModule {\n\n    @Singleton\n    @Binds\n    fun provideImageDrawApplier(\n        applier: AndroidImageDrawApplier\n    ): ImageDrawApplier<Bitmap, Path, Color>\n\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/DrawBehavior.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\nsealed class DrawBehavior(\n    open val orientation: Int\n) {\n    data object None : DrawBehavior(2)\n\n    data class Image(\n        override val orientation: Int\n    ) : DrawBehavior(orientation = orientation)\n\n    data class Background(\n        override val orientation: Int,\n        val width: Int,\n        val height: Int,\n        val color: Int\n    ) : DrawBehavior(orientation = orientation)\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/DrawLineStyle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.pt\n\n// Works only for Basic draw modes (excludes DrawMode.PathEffect, DrawMode.SpotHeal, DrawMode.Text, DrawMode.Image)\nsealed class DrawLineStyle(\n    val ordinal: Int\n) {\n    data object None : DrawLineStyle(0)\n\n    data class Dashed(\n        val size: Pt = 10.pt,\n        val gap: Pt = 20.pt\n    ) : DrawLineStyle(1)\n\n    data class ZigZag(\n        val heightRatio: Float = 4f\n    ) : DrawLineStyle(2)\n\n    data class Stamped<Shape>(\n        val shape: Shape? = null,\n        val spacing: Pt = 20.pt\n    ) : DrawLineStyle(3)\n\n    data object DotDashed : DrawLineStyle(4)\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                None,\n                Dashed(),\n                DotDashed,\n                ZigZag(),\n                Stamped<Any>(),\n            )\n        }\n\n        fun fromOrdinal(\n            ordinal: Int\n        ): DrawLineStyle = entries.find {\n            it.ordinal == ordinal\n        } ?: None\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/DrawMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.SpotHealMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FontType\n\nsealed class DrawMode(open val ordinal: Int) {\n    data object Neon : DrawMode(2)\n    data object Highlighter : DrawMode(3)\n    data object Pen : DrawMode(0)\n\n    sealed class PathEffect(override val ordinal: Int) : DrawMode(ordinal) {\n        data class PrivacyBlur(\n            val blurRadius: Int = 20\n        ) : PathEffect(1)\n\n        data class Pixelation(\n            val pixelSize: Float = 35f\n        ) : PathEffect(4)\n\n        data class Custom(\n            val filter: Filter<*>? = null\n        ) : PathEffect(5)\n    }\n\n    data class Text(\n        val text: String = \"Text\",\n        val font: FontType? = null,\n        val isRepeated: Boolean = false,\n        val repeatingInterval: Pt = Pt.Zero\n    ) : DrawMode(6)\n\n    data class Image(\n        val imageData: Any = \"file:///android_asset/svg/emotions/aasparkles.svg\",\n        val repeatingInterval: Pt = Pt.Zero\n    ) : DrawMode(7)\n\n    data class SpotHeal(\n        val mode: SpotHealMode = SpotHealMode.OpenCV\n    ) : DrawMode(8)\n\n    data class Warp(\n        val warpMode: WarpMode = WarpMode.MOVE,\n        val strength: Float = 0.25f,\n        val hardness: Float = 0.5f,\n        val strokes: List<WarpStroke> = emptyList(),\n        val previewClearToken: Long = 0L\n    ) : DrawMode(9)\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                Pen,\n                PathEffect.PrivacyBlur(),\n                SpotHeal(),\n                Warp(),\n                Neon,\n                Highlighter,\n                Text(),\n                Image(),\n                PathEffect.Pixelation(),\n                PathEffect.Custom()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/DrawOnBackgroundParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\ndata class DrawOnBackgroundParams(\n    val width: Int,\n    val height: Int,\n    val color: Int?,\n) {\n    companion object {\n        val Default by lazy {\n            DrawOnBackgroundParams(\n                width = -1,\n                height = -1,\n                color = null\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/DrawPathMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.FloodFill\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.Lasso\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.OutlinedOval\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.OutlinedRect\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.Oval\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.Polygon\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.Rect\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.Spray\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.Star\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode.Triangle\n\nsealed class DrawPathMode(\n    val ordinal: Int\n) {\n    sealed class Outlined(ordinal: Int) : DrawPathMode(ordinal) {\n        abstract val fillColor: ColorModel?\n    }\n\n    data object Free : DrawPathMode(0)\n    data object Line : DrawPathMode(1)\n\n    data class PointingArrow(\n        val sizeScale: Float = 3f,\n        val angle: Float = 150f\n    ) : DrawPathMode(2)\n\n    data class DoublePointingArrow(\n        val sizeScale: Float = 3f,\n        val angle: Float = 150f\n    ) : DrawPathMode(3)\n\n    data class LinePointingArrow(\n        val sizeScale: Float = 3f,\n        val angle: Float = 150f\n    ) : DrawPathMode(4)\n\n    data class DoubleLinePointingArrow(\n        val sizeScale: Float = 3f,\n        val angle: Float = 150f\n    ) : DrawPathMode(5)\n\n    data object Lasso : DrawPathMode(6)\n\n    data class OutlinedRect(\n        val rotationDegrees: Int = 0,\n        val cornerRadius: Float = 0f,\n        override val fillColor: ColorModel? = null\n    ) : Outlined(7)\n\n    data class OutlinedOval(\n        override val fillColor: ColorModel? = null\n    ) : Outlined(8)\n\n    data class Rect(\n        val rotationDegrees: Int = 0,\n        val cornerRadius: Float = 0f\n    ) : DrawPathMode(9)\n\n    data object Oval : DrawPathMode(10)\n    data object Triangle : DrawPathMode(11)\n    data class OutlinedTriangle(\n        override val fillColor: ColorModel? = null\n    ) : Outlined(12)\n\n    data class Polygon(\n        val vertices: Int = 5,\n        val rotationDegrees: Int = 0,\n        val isRegular: Boolean = false\n    ) : DrawPathMode(13)\n\n    data class OutlinedPolygon(\n        val vertices: Int = 5,\n        val rotationDegrees: Int = 0,\n        val isRegular: Boolean = false,\n        override val fillColor: ColorModel? = null\n    ) : Outlined(14)\n\n    data class Star(\n        val vertices: Int = 5,\n        val rotationDegrees: Int = 0,\n        val innerRadiusRatio: Float = 0.5f,\n        val isRegular: Boolean = false\n    ) : DrawPathMode(15)\n\n    data class OutlinedStar(\n        val vertices: Int = 5,\n        val rotationDegrees: Int = 0,\n        val innerRadiusRatio: Float = 0.5f,\n        val isRegular: Boolean = false,\n        override val fillColor: ColorModel? = null\n    ) : Outlined(16)\n\n    data class FloodFill(\n        val tolerance: Float = 0.25f\n    ) : DrawPathMode(17) {\n        companion object {\n            val StrokeSize = 2f.pt\n        }\n    }\n\n    data class Spray(\n        val density: Int = 50,\n        val pixelSize: Float = 1f,\n        val isSquareShaped: Boolean = false\n    ) : DrawPathMode(18)\n\n    val canChangeStrokeWidth: Boolean\n        get() = this !is FloodFill && (!isFilled || this is Spray)\n\n    val isFilled: Boolean\n        get() = filled.any { this::class.isInstance(it) }\n\n    val outlinedFillColor: ColorModel?\n        get() = this.safeCast<Outlined>()?.fillColor\n\n    val isSharpEdge: Boolean\n        get() = sharp.any { this::class.isInstance(it) }\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                Free,\n                FloodFill(),\n                Spray(),\n                Line,\n                PointingArrow(),\n                DoublePointingArrow(),\n                LinePointingArrow(),\n                DoubleLinePointingArrow(),\n                Lasso,\n                OutlinedRect(),\n                OutlinedOval(),\n                OutlinedTriangle(),\n                OutlinedPolygon(),\n                OutlinedStar(),\n                Rect(),\n                Oval,\n                Triangle,\n                Polygon(),\n                Star()\n            )\n        }\n\n        val outlinedEntries by lazy {\n            listOf(\n                OutlinedRect(),\n                OutlinedOval(),\n                OutlinedTriangle(),\n                OutlinedPolygon(),\n                OutlinedStar()\n            )\n        }\n\n        fun fromOrdinal(\n            ordinal: Int\n        ): DrawPathMode = entries.find {\n            it.ordinal == ordinal\n        } ?: Free\n    }\n\n    fun convertStrokeWidth(\n        strokeWidth: Pt,\n        canvasSize: IntegerSize\n    ): Float = when (this) {\n        is FloodFill -> FloodFill.StrokeSize.toPx(canvasSize)\n        else -> strokeWidth.toPx(canvasSize)\n    }\n}\n\nprivate val filled = listOf(\n    Lasso,\n    Rect(),\n    Oval,\n    Triangle,\n    Polygon(),\n    Star(),\n    Spray()\n)\n\nprivate val sharp = listOf(\n    OutlinedRect(),\n    OutlinedOval(),\n    Rect(),\n    Oval,\n    Lasso,\n    FloodFill(),\n    Spray()\n)"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/ImageDrawApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\ninterface ImageDrawApplier<Image, Path, Color> {\n\n    suspend fun applyDrawToImage(\n        drawBehavior: DrawBehavior,\n        pathPaints: List<PathPaint<Path, Color>>,\n        imageUri: String\n    ): Image?\n\n    suspend fun applyEraseToImage(\n        pathPaints: List<PathPaint<Path, Color>>,\n        imageUri: String\n    ): Image?\n\n    suspend fun applyEraseToImage(\n        pathPaints: List<PathPaint<Path, Color>>,\n        image: Image?,\n        shaderSourceUri: String\n    ): Image?\n\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/PathPaint.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\n\ninterface PathPaint<Path, Color> {\n    operator fun component1() = path\n    operator fun component2() = strokeWidth\n    operator fun component3() = brushSoftness\n    operator fun component4() = drawColor\n    operator fun component5() = isErasing\n    operator fun component6() = drawMode\n    operator fun component7() = canvasSize\n    operator fun component8() = drawPathMode\n    operator fun component9() = drawLineStyle\n\n\n    val path: Path\n    val strokeWidth: Pt\n    val brushSoftness: Pt\n    val drawColor: Color\n    val isErasing: Boolean\n    val drawMode: DrawMode\n    val canvasSize: IntegerSize\n    val drawPathMode: DrawPathMode\n    val drawLineStyle: DrawLineStyle\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/domain/Warp.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\nenum class WarpMode {\n    MOVE,\n    GROW,\n    SHRINK,\n    SWIRL_CW,\n    SWIRL_CCW,\n    MIXING\n}\n\ndata class WarpStroke(\n    val fromX: Float,\n    val fromY: Float,\n    val toX: Float,\n    val toY: Float\n) {\n    fun scaleToFitCanvas(\n        currentSize: IntegerSize,\n        oldSize: IntegerSize\n    ): WarpStroke {\n        val sx = currentSize.width.toFloat() / oldSize.width\n        val sy = currentSize.height.toFloat() / oldSize.height\n        return copy(\n            fromX = fromX * sx,\n            fromY = fromY * sy,\n            toX = toX * sx,\n            toY = toY * sy\n        )\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/DrawContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation\n\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.core.domain.model.coerceIn\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveBottomScaffoldLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.other.DrawLockScreenOrientation\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.PtSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawBehavior\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BitmapDrawer\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.controls.DrawContentControls\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.controls.DrawContentNoDataControls\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.controls.DrawContentSecondaryControls\nimport com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent\nimport kotlinx.coroutines.launch\n\n@Composable\nfun DrawContent(\n    component: DrawComponent,\n) {\n    val settingsState = LocalSettingsState.current\n    val themeState = LocalDynamicThemeState.current\n\n    val appColorTuple = rememberAppColorTuple()\n\n    val scope = rememberCoroutineScope()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        when (component.drawBehavior) {\n            !is DrawBehavior.None if component.haveChanges -> showExitDialog = true\n\n            !is DrawBehavior.None -> {\n                component.resetDrawBehavior()\n                themeState.updateColorTuple(appColorTuple)\n            }\n\n            else -> component.onGoBack()\n        }\n    }\n\n    AutoContentBasedColors(component.bitmap)\n\n    val imagePicker = rememberImagePicker { uri: Uri ->\n        component.setUri(uri)\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val screenSize = LocalScreenSize.current\n    val isPortrait by isPortraitOrientationAsState()\n\n    var panEnabled by rememberSaveable(component.drawBehavior) { mutableStateOf(false) }\n\n    var strokeWidth by rememberSaveable(\n        component.drawBehavior,\n        stateSaver = PtSaver\n    ) { mutableStateOf(settingsState.defaultDrawLineWidth.pt) }\n\n    var drawColor by rememberSaveable(\n        component.drawBehavior,\n        stateSaver = ColorSaver\n    ) { mutableStateOf(settingsState.defaultDrawColor) }\n\n    var isEraserOn by rememberSaveable(component.drawBehavior) { mutableStateOf(false) }\n\n    val drawMode = component.drawMode\n\n    var alpha by rememberSaveable(component.drawBehavior, drawMode) {\n        mutableFloatStateOf(if (drawMode is DrawMode.Highlighter) 0.4f else 1f)\n    }\n\n    var brushSoftness by rememberSaveable(component.drawBehavior, drawMode, stateSaver = PtSaver) {\n        mutableStateOf(if (drawMode is DrawMode.Neon) 35.pt else 0.pt)\n    }\n\n    val drawPathMode = component.drawPathMode\n\n    val drawLineStyle = component.drawLineStyle\n\n    LaunchedEffect(drawMode, strokeWidth) {\n        strokeWidth = if (drawMode is DrawMode.Image) {\n            strokeWidth.coerceIn(10.pt, 120.pt)\n        } else {\n            strokeWidth.coerceIn(1.pt, 100.pt)\n        }\n    }\n\n    val secondaryControls = @Composable {\n        DrawContentSecondaryControls(\n            component = component,\n            panEnabled = panEnabled,\n            onTogglePanEnabled = { panEnabled = !panEnabled },\n            isEraserOn = isEraserOn,\n            onToggleIsEraserOn = { isEraserOn = !isEraserOn }\n        )\n    }\n\n    val bitmap = component.bitmap ?: (component.drawBehavior as? DrawBehavior.Background)?.run {\n        remember { ImageBitmap(width, height).asAndroidBitmap() }\n    } ?: remember {\n        ImageBitmap(\n            screenSize.widthPx,\n            screenSize.heightPx\n        ).asAndroidBitmap()\n    }\n\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    AdaptiveBottomScaffoldLayoutScreen(\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.draw),\n                input = component.drawBehavior.takeIf { it !is DrawBehavior.None },\n                isLoading = component.isImageLoading,\n                size = null,\n                originalSize = null\n            )\n        },\n        onGoBack = onBack,\n        shouldDisableBackHandler = component.drawBehavior is DrawBehavior.None,\n        actions = {\n            secondaryControls()\n        },\n        topAppBarPersistentActions = { scaffoldState ->\n            if (component.drawBehavior == DrawBehavior.None) TopAppBarEmoji()\n            else {\n                if (isPortrait) {\n                    EnhancedIconButton(\n                        onClick = {\n                            scope.launch {\n                                if (scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {\n                                    scaffoldState.bottomSheetState.partialExpand()\n                                } else {\n                                    scaffoldState.bottomSheetState.expand()\n                                }\n                            }\n                        },\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Tune,\n                            contentDescription = stringResource(R.string.properties)\n                        )\n                    }\n                }\n                var editSheetData by remember {\n                    mutableStateOf(listOf<Uri>())\n                }\n                ShareButton(\n                    enabled = component.drawBehavior !is DrawBehavior.None,\n                    onShare = component::shareBitmap,\n                    onCopy = {\n                        component.cacheCurrentImage(Clipboard::copy)\n                    },\n                    onEdit = {\n                        component.cacheCurrentImage { uri ->\n                            editSheetData = listOf(uri)\n                        }\n                    }\n                )\n                ProcessImagesPreferenceSheet(\n                    uris = editSheetData,\n                    visible = editSheetData.isNotEmpty(),\n                    onDismiss = {\n                        editSheetData = emptyList()\n                    },\n                    onNavigate = component.onNavigate\n                )\n                EnhancedIconButton(\n                    onClick = component::clearDrawing,\n                    enabled = component.drawBehavior !is DrawBehavior.None && component.havePaths\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Delete,\n                        contentDescription = stringResource(R.string.delete)\n                    )\n                }\n            }\n        },\n        mainContent = {\n            AnimatedContent(\n                targetState = remember(bitmap) {\n                    derivedStateOf {\n                        bitmap.copy(Bitmap.Config.ARGB_8888, true).asImageBitmap()\n                    }\n                }.value,\n                transitionSpec = { fadeIn() togetherWith fadeOut() }\n            ) { imageBitmap ->\n                val direction = LocalLayoutDirection.current\n                val aspectRatio = imageBitmap.width / imageBitmap.height.toFloat()\n                BitmapDrawer(\n                    imageBitmap = imageBitmap,\n                    paths = component.paths,\n                    strokeWidth = strokeWidth,\n                    brushSoftness = brushSoftness,\n                    drawColor = drawColor.copy(alpha),\n                    onAddPath = component::addPath,\n                    isEraserOn = isEraserOn,\n                    drawMode = drawMode,\n                    modifier = Modifier\n                        .padding(\n                            start = WindowInsets\n                                .displayCutout\n                                .asPaddingValues()\n                                .calculateStartPadding(direction)\n                        )\n                        .padding(16.dp)\n                        .aspectRatio(aspectRatio, isPortrait)\n                        .fillMaxSize(),\n                    panEnabled = panEnabled,\n                    onRequestFiltering = component::filter,\n                    drawPathMode = drawPathMode,\n                    backgroundColor = component.backgroundColor,\n                    drawLineStyle = drawLineStyle,\n                    helperGridParams = component.helperGridParams\n                )\n            }\n        },\n        controls = {\n            DrawContentControls(\n                component = component,\n                secondaryControls = secondaryControls,\n                drawColor = drawColor,\n                onDrawColorChange = { drawColor = it },\n                strokeWidth = strokeWidth,\n                onStrokeWidthChange = { strokeWidth = it },\n                brushSoftness = brushSoftness,\n                onBrushSoftnessChange = { brushSoftness = it },\n                alpha = alpha,\n                onAlphaChange = { alpha = it }\n            )\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.drawBehavior is DrawBehavior.None,\n                onSecondaryButtonClick = pickImage,\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                isSecondaryButtonVisible = component.drawBehavior !is DrawBehavior.Background,\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                isPrimaryButtonVisible = component.drawBehavior !is DrawBehavior.None,\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                },\n                showNullDataButtonAsContainer = true\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        enableNoDataScroll = false,\n        noDataControls = {\n            DrawContentNoDataControls(\n                component = component,\n                onPickImage = pickImage\n            )\n        },\n        canShowScreenData = component.drawBehavior !is DrawBehavior.None,\n        showActionsInTopAppBar = false,\n        mainContentWeight = 0.65f\n    )\n\n    LoadingDialog(\n        visible = component.isSaving || component.isImageLoading,\n        onCancelLoading = component::cancelSaving,\n        canCancel = component.isSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = {\n            if (component.drawBehavior !is DrawBehavior.None) {\n                component.resetDrawBehavior()\n                themeState.updateColorTuple(appColorTuple)\n            } else component.onGoBack()\n        },\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    DrawLockScreenOrientation()\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/BitmapDrawer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport android.annotation.SuppressLint\nimport android.graphics.Bitmap\nimport android.graphics.PorterDuff\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableLongStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.isSpecified\nimport androidx.compose.ui.geometry.isUnspecified\nimport androidx.compose.ui.geometry.takeOrElse\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathMeasure\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.createScaledBitmap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.WarpStroke\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.BitmapDrawerPreview\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.DrawPathEffectPreview\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.MotionEvent\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.copy\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.drawRepeatedImageOnPath\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.drawRepeatedTextOnPath\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.floodFill\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.handle\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.overlay\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.pointerDrawObserver\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.rememberPaint\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.rememberPathHelper\nimport com.t8rin.trickle.WarpBrush\nimport com.t8rin.trickle.WarpEngine\nimport com.t8rin.trickle.WarpMode\nimport kotlinx.coroutines.flow.filterNotNull\nimport kotlinx.coroutines.launch\nimport net.engawapg.lib.zoomable.ZoomState\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport kotlin.math.roundToInt\nimport android.graphics.Canvas as AndroidCanvas\nimport android.graphics.Paint as AndroidPaint\n\n\n@SuppressLint(\"CoroutineCreationDuringComposition\")\n@Composable\nfun BitmapDrawer(\n    imageBitmap: ImageBitmap,\n    onRequestFiltering: suspend (Bitmap, List<Filter<*>>) -> Bitmap?,\n    paths: List<UiPathPaint>,\n    brushSoftness: Pt,\n    zoomState: ZoomState = rememberZoomState(maxScale = 30f),\n    onAddPath: (UiPathPaint) -> Unit,\n    strokeWidth: Pt,\n    isEraserOn: Boolean,\n    drawMode: DrawMode,\n    modifier: Modifier,\n    drawPathMode: DrawPathMode = DrawPathMode.Free,\n    onDrawStart: (() -> Unit)? = null,\n    onDraw: ((Bitmap) -> Unit)? = null,\n    onDrawFinish: (() -> Unit)? = null,\n    backgroundColor: Color,\n    panEnabled: Boolean,\n    drawColor: Color,\n    drawLineStyle: DrawLineStyle = DrawLineStyle.None,\n    helperGridParams: HelperGridParams = remember { HelperGridParams() },\n) {\n    val scope = rememberCoroutineScope()\n\n    val settingsState = LocalSettingsState.current\n    val magnifierEnabled by remember(zoomState.scale, settingsState.magnifierEnabled) {\n        derivedStateOf {\n            zoomState.scale <= 3f && !panEnabled && settingsState.magnifierEnabled\n        }\n    }\n    val globalTouchPointersCount = remember { mutableIntStateOf(0) }\n\n    var currentDrawPosition by remember { mutableStateOf(Offset.Unspecified) }\n\n    Box(\n        modifier = Modifier.pointerDrawObserver(\n            magnifierEnabled = magnifierEnabled,\n            currentDrawPosition = currentDrawPosition,\n            zoomState = zoomState,\n            globalTouchPointersCount = globalTouchPointersCount,\n            panEnabled = panEnabled\n        ),\n        contentAlignment = Alignment.Center\n    ) {\n        BoxWithConstraints(modifier) {\n            val motionEvent = remember { mutableStateOf(MotionEvent.Idle) }\n            var previousDrawPosition by remember { mutableStateOf(Offset.Unspecified) }\n            var drawDownPosition by remember { mutableStateOf(Offset.Unspecified) }\n\n            val imageWidth = constraints.maxWidth\n            val imageHeight = constraints.maxHeight\n\n            val drawImageBitmap by remember(imageWidth, imageHeight, backgroundColor) {\n                derivedStateOf {\n                    imageBitmap.asAndroidBitmap().createScaledBitmap(\n                        width = imageWidth,\n                        height = imageHeight\n                    ).apply {\n                        val canvas = AndroidCanvas(this)\n                        val paint = android.graphics.Paint().apply {\n                            color = backgroundColor.toArgb()\n                        }\n                        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)\n                    }.asImageBitmap()\n                }\n            }\n\n            val drawBitmap: ImageBitmap by remember(imageWidth, imageHeight) {\n                derivedStateOf {\n                    createBitmap(imageWidth, imageHeight).asImageBitmap()\n                }\n            }\n\n            var invalidations by remember {\n                mutableIntStateOf(0)\n            }\n\n            val drawPathBitmap: ImageBitmap by remember(imageWidth, imageHeight, invalidations) {\n                derivedStateOf {\n                    createBitmap(imageWidth, imageHeight).asImageBitmap()\n                }\n            }\n\n            LaunchedEffect(\n                paths,\n                drawMode,\n                backgroundColor,\n                drawPathMode,\n                imageWidth,\n                imageHeight\n            ) {\n                invalidations++\n            }\n\n            val outputImage by remember(invalidations) {\n                derivedStateOf {\n                    drawImageBitmap.overlay(drawBitmap)\n                }\n            }\n\n            val canvas: Canvas by remember(drawBitmap, imageHeight, imageWidth) {\n                derivedStateOf {\n                    Canvas(drawBitmap)\n                }\n            }\n\n            val drawPathCanvas: Canvas by remember(drawPathBitmap, imageWidth, imageHeight) {\n                derivedStateOf {\n                    Canvas(drawPathBitmap)\n                }\n            }\n\n            val canvasSize by remember(canvas.nativeCanvas) {\n                derivedStateOf {\n                    IntegerSize(\n                        width = canvas.nativeCanvas.width,\n                        height = canvas.nativeCanvas.height\n                    )\n                }\n            }\n\n            val drawPaint by rememberPaint(\n                strokeWidth = strokeWidth,\n                isEraserOn = isEraserOn,\n                drawColor = drawColor,\n                brushSoftness = brushSoftness,\n                drawMode = drawMode,\n                canvasSize = canvasSize,\n                drawPathMode = drawPathMode,\n                drawLineStyle = drawLineStyle\n            )\n\n            var drawPath by remember(\n                drawMode,\n                strokeWidth,\n                isEraserOn,\n                drawColor,\n                brushSoftness,\n                drawPathMode\n            ) { mutableStateOf(Path()) }\n\n            var pathWithoutTransformations by remember(\n                drawMode,\n                strokeWidth,\n                isEraserOn,\n                drawColor,\n                brushSoftness,\n                drawPathMode\n            ) { mutableStateOf(Path()) }\n\n            var warpRuntimeStrokes by remember(drawMode) {\n                mutableStateOf(emptyList<WarpStroke>())\n            }\n            var warpClearTrigger by remember {\n                mutableIntStateOf(0)\n            }\n            var warpPreviewToken by remember {\n                mutableLongStateOf(0L)\n            }\n            var pendingWarpCommitToken by remember {\n                mutableLongStateOf(-1L)\n            }\n            var previousPathsCount by remember {\n                mutableIntStateOf(paths.size)\n            }\n\n            LaunchedEffect(paths.size) {\n                if (paths.isEmpty() || paths.size < previousPathsCount) {\n                    warpClearTrigger++\n                    pendingWarpCommitToken = -1L\n                }\n                previousPathsCount = paths.size\n            }\n\n            LaunchedEffect(drawMode, isEraserOn) {\n                if (drawMode !is DrawMode.Warp || isEraserOn) {\n                    pendingWarpCommitToken = -1L\n                }\n            }\n\n            val isWarpInputLocked by remember(drawMode, isEraserOn, pendingWarpCommitToken) {\n                derivedStateOf {\n                    drawMode is DrawMode.Warp && !isEraserOn && pendingWarpCommitToken >= 0L\n                }\n            }\n\n            with(canvas) {\n                with(nativeCanvas) {\n                    drawColor(Color.Transparent.toArgb(), PorterDuff.Mode.CLEAR)\n                    drawColor(backgroundColor.toArgb())\n\n                    paths.forEach { uiPathPaint ->\n                        UiPathPaintCanvasAction(\n                            uiPathPaint = uiPathPaint,\n                            invalidations = invalidations,\n                            onInvalidate = { invalidations++ },\n                            pathsCount = paths.size,\n                            backgroundColor = backgroundColor,\n                            drawImageBitmap = drawImageBitmap,\n                            drawBitmap = drawBitmap,\n                            onClearDrawPath = {\n                                drawPath = Path()\n                                warpClearTrigger++\n                                warpRuntimeStrokes = emptyList()\n                            },\n                            onClearWarpDrawPath = { token ->\n                                if (token == pendingWarpCommitToken) {\n                                    drawPath = Path()\n                                    warpClearTrigger++\n                                    warpRuntimeStrokes = emptyList()\n                                    pendingWarpCommitToken = -1L\n                                }\n                            },\n                            onRequestFiltering = onRequestFiltering,\n                            canvasSize = canvasSize\n                        )\n                    }\n\n                    if ((drawMode !is DrawMode.PathEffect && drawMode !is DrawMode.Warp) || isEraserOn) {\n                        val androidPath by remember(drawPath) {\n                            derivedStateOf {\n                                drawPath.asAndroidPath()\n                            }\n                        }\n                        if (drawMode is DrawMode.Text && !isEraserOn) {\n                            if (drawMode.isRepeated) {\n                                drawRepeatedTextOnPath(\n                                    text = drawMode.text,\n                                    path = androidPath,\n                                    paint = drawPaint,\n                                    interval = drawMode.repeatingInterval.toPx(canvasSize)\n                                )\n                            } else {\n                                drawTextOnPath(drawMode.text, androidPath, 0f, 0f, drawPaint)\n                            }\n                        } else if (drawMode is DrawMode.Image && !isEraserOn) {\n                            drawRepeatedImageOnPath(\n                                drawMode = drawMode,\n                                strokeWidth = strokeWidth,\n                                canvasSize = canvasSize,\n                                path = androidPath,\n                                paint = drawPaint,\n                                invalidations = invalidations\n                            )\n                        } else if (drawMode is DrawMode.SpotHeal && !isEraserOn) {\n                            with(drawPathCanvas.nativeCanvas) {\n                                drawColor(Color.Transparent.toArgb(), PorterDuff.Mode.CLEAR)\n                                drawPath(\n                                    androidPath,\n                                    drawPaint.apply { color = Color.Red.copy(0.5f).toArgb() }\n                                )\n                            }\n                        } else if (drawPathMode is DrawPathMode.Outlined) {\n                            drawPathMode.fillColor?.let { fillColor ->\n                                val filledPaint = remember(fillColor, drawPaint) {\n                                    AndroidPaint().apply {\n                                        set(drawPaint)\n                                        style = AndroidPaint.Style.FILL\n                                        color = fillColor.colorInt\n                                        if (Color(fillColor.colorInt).alpha == 1f) {\n                                            alpha =\n                                                (drawColor.alpha * 255).roundToInt()\n                                                    .coerceIn(0, 255)\n                                        }\n                                        pathEffect = null\n                                    }\n                                }\n\n                                drawPath(androidPath, filledPaint)\n                            }\n                            drawPath(androidPath, drawPaint)\n                        } else {\n                            drawPath(androidPath, drawPaint)\n                        }\n                    }\n                }\n\n                val drawHelper by rememberPathHelper(\n                    drawDownPosition = drawDownPosition,\n                    currentDrawPosition = currentDrawPosition,\n                    onPathChange = { drawPath = it },\n                    strokeWidth = strokeWidth,\n                    canvasSize = canvasSize,\n                    drawPathMode = drawPathMode,\n                    isEraserOn = isEraserOn,\n                    drawMode = drawMode\n                )\n\n                motionEvent.value.handle(\n                    onDown = {\n                        if (drawMode is DrawMode.Warp && !isEraserOn) {\n                            warpPreviewToken++\n                            warpRuntimeStrokes = emptyList()\n                            drawPath = Path()\n                            pathWithoutTransformations = Path()\n                        } else {\n                            warpClearTrigger++\n                            warpRuntimeStrokes = emptyList()\n                        }\n\n                        if (currentDrawPosition.isSpecified) {\n                            onDrawStart?.invoke()\n                            drawPath.moveTo(currentDrawPosition.x, currentDrawPosition.y)\n                            previousDrawPosition = currentDrawPosition\n                            pathWithoutTransformations = drawPath.copy()\n                        } else {\n                            drawPath = Path()\n                            pathWithoutTransformations = Path()\n                        }\n\n                        motionEvent.value = MotionEvent.Idle\n                    },\n                    onMove = {\n                        if (drawMode is DrawMode.Warp && !isEraserOn) {\n                            if (\n                                previousDrawPosition.isSpecified &&\n                                currentDrawPosition.isSpecified\n                            ) {\n                                warpRuntimeStrokes += WarpStroke(\n                                    fromX = previousDrawPosition.x,\n                                    fromY = previousDrawPosition.y,\n                                    toX = currentDrawPosition.x,\n                                    toY = currentDrawPosition.y\n                                )\n                            }\n                        }\n\n                        drawHelper.drawPath(\n                            currentDrawPath = drawPath,\n                            onDrawFreeArrow = {\n                                if (previousDrawPosition.isUnspecified && currentDrawPosition.isSpecified) {\n                                    drawPath = Path().apply {\n                                        moveTo(\n                                            currentDrawPosition.x,\n                                            currentDrawPosition.y\n                                        )\n                                    }\n                                    pathWithoutTransformations = drawPath.copy()\n                                    previousDrawPosition = currentDrawPosition\n                                }\n                                if (previousDrawPosition.isSpecified && currentDrawPosition.isSpecified) {\n                                    drawPath = pathWithoutTransformations\n                                    drawPath.quadraticTo(\n                                        previousDrawPosition.x,\n                                        previousDrawPosition.y,\n                                        (previousDrawPosition.x + currentDrawPosition.x) / 2,\n                                        (previousDrawPosition.y + currentDrawPosition.y) / 2\n                                    )\n                                    previousDrawPosition = currentDrawPosition\n\n                                    pathWithoutTransformations = drawPath.copy()\n\n                                    drawArrowsIfNeeded(drawPath)\n                                }\n                            },\n                            onBaseDraw = {\n                                if (previousDrawPosition.isUnspecified && currentDrawPosition.isSpecified) {\n                                    drawPath.moveTo(currentDrawPosition.x, currentDrawPosition.y)\n                                    previousDrawPosition = currentDrawPosition\n                                }\n\n                                if (currentDrawPosition.isSpecified && previousDrawPosition.isSpecified) {\n                                    drawPath.quadraticTo(\n                                        previousDrawPosition.x,\n                                        previousDrawPosition.y,\n                                        (previousDrawPosition.x + currentDrawPosition.x) / 2,\n                                        (previousDrawPosition.y + currentDrawPosition.y) / 2\n                                    )\n                                }\n                                previousDrawPosition = currentDrawPosition\n                            },\n                        )\n\n                        motionEvent.value = MotionEvent.Idle\n                    },\n                    onUp = {\n                        if (currentDrawPosition.isSpecified && drawDownPosition.isSpecified) {\n                            if (drawMode is DrawMode.Warp && warpRuntimeStrokes.isNotEmpty() && !isEraserOn) {\n                                PathMeasure().apply {\n                                    setPath(drawPath, false)\n                                }.let {\n                                    it.getPosition(it.length)\n                                }.takeOrElse { currentDrawPosition }.let { lastPoint ->\n                                    warpRuntimeStrokes += WarpStroke(\n                                        fromX = lastPoint.x,\n                                        fromY = lastPoint.y,\n                                        toX = currentDrawPosition.x,\n                                        toY = currentDrawPosition.y\n                                    )\n                                }\n\n                                onAddPath(\n                                    UiPathPaint(\n                                        path = drawPath,\n                                        strokeWidth = strokeWidth,\n                                        brushSoftness = 0.pt,\n                                        drawColor = Color.Transparent,\n                                        isErasing = false,\n                                        drawMode = drawMode.copy(\n                                            strokes = warpRuntimeStrokes.toList(),\n                                            previewClearToken = warpPreviewToken\n                                        ),\n                                        canvasSize = canvasSize,\n                                        drawPathMode = DrawPathMode.Free,\n                                        drawLineStyle = DrawLineStyle.None\n                                    )\n                                )\n                                pendingWarpCommitToken = warpPreviewToken\n                            } else {\n                                drawHelper.drawPath(\n                                    currentDrawPath = null,\n                                    onDrawFreeArrow = {\n                                        drawPath = pathWithoutTransformations\n                                        PathMeasure().apply {\n                                            setPath(drawPath, false)\n                                        }.let {\n                                            it.getPosition(it.length)\n                                        }.let { lastPoint ->\n                                            if (!lastPoint.isSpecified) {\n                                                drawPath.moveTo(\n                                                    currentDrawPosition.x,\n                                                    currentDrawPosition.y\n                                                )\n                                            }\n                                            drawPath.lineTo(\n                                                currentDrawPosition.x,\n                                                currentDrawPosition.y\n                                            )\n                                        }\n\n                                        drawArrowsIfNeeded(drawPath)\n                                    },\n                                    onBaseDraw = {\n                                        PathMeasure().apply {\n                                            setPath(drawPath, false)\n                                        }.let {\n                                            it.getPosition(it.length)\n                                        }.takeOrElse { currentDrawPosition }.let { lastPoint ->\n                                            drawPath.moveTo(lastPoint.x, lastPoint.y)\n                                            drawPath.lineTo(\n                                                currentDrawPosition.x,\n                                                currentDrawPosition.y\n                                            )\n                                        }\n                                    },\n                                    onFloodFill = { tolerance ->\n                                        outputImage\n                                            .floodFill(\n                                                offset = currentDrawPosition,\n                                                tolerance = tolerance\n                                            )\n                                            ?.let { drawPath = it }\n                                    }\n                                )\n\n                                onAddPath(\n                                    UiPathPaint(\n                                        path = drawPath,\n                                        strokeWidth = strokeWidth,\n                                        brushSoftness = brushSoftness,\n                                        drawColor = drawColor,\n                                        isErasing = isEraserOn,\n                                        drawMode = drawMode,\n                                        canvasSize = canvasSize,\n                                        drawPathMode = drawPathMode,\n                                        drawLineStyle = drawLineStyle\n                                    )\n                                )\n                            }\n                        }\n\n                        currentDrawPosition = Offset.Unspecified\n                        previousDrawPosition = Offset.Unspecified\n                        motionEvent.value = MotionEvent.Idle\n\n                        scope.launch {\n                            if ((drawMode is DrawMode.PathEffect || drawMode is DrawMode.SpotHeal || drawMode is DrawMode.Warp) && !isEraserOn) Unit\n                            else drawPath = Path()\n\n                            pathWithoutTransformations = Path()\n                        }\n                        onDrawFinish?.invoke()\n                    }\n                )\n            }\n\n            if (drawMode is DrawMode.PathEffect && !isEraserOn) {\n                DrawPathEffectPreview(\n                    drawPathCanvas = drawPathCanvas,\n                    drawMode = drawMode,\n                    canvasSize = canvasSize,\n                    imageWidth = imageWidth,\n                    imageHeight = imageHeight,\n                    outputImage = outputImage,\n                    onRequestFiltering = onRequestFiltering,\n                    paths = paths,\n                    drawPath = drawPath,\n                    backgroundColor = backgroundColor,\n                    strokeWidth = strokeWidth,\n                    drawPathMode = drawPathMode\n                )\n            }\n\n            var warpEngine by remember {\n                mutableStateOf(\n                    WarpEngine(\n                        src = outputImage.asAndroidBitmap()\n                    )\n                )\n            }\n\n            LaunchedEffect(warpClearTrigger, drawMode) {\n                warpEngine.release()\n                warpEngine = WarpEngine(\n                    src = outputImage.asAndroidBitmap()\n                )\n            }\n\n            LaunchedEffect(warpEngine) {\n                snapshotFlow { warpRuntimeStrokes.lastOrNull() }\n                    .filterNotNull()\n                    .collect {\n                        if (drawMode is DrawMode.Warp) {\n                            warpEngine.applyStroke(\n                                fromX = it.fromX,\n                                fromY = it.fromY,\n                                toX = it.toX,\n                                toY = it.toY,\n                                brush = WarpBrush(\n                                    radius = strokeWidth.toPx(canvasSize),\n                                    strength = drawMode.strength,\n                                    hardness = drawMode.hardness\n                                ),\n                                mode = WarpMode.valueOf(drawMode.warpMode.name)\n                            )\n                            invalidations++\n                        }\n                    }\n            }\n\n            val warpedImage by remember(invalidations, warpEngine) {\n                derivedStateOf {\n                    if (warpRuntimeStrokes.isNotEmpty()) {\n                        warpEngine.render().asImageBitmap().also {\n                            it.prepareToDraw()\n                        }\n                    } else {\n                        outputImage.overlay(drawPathBitmap)\n                    }\n                }\n            }\n\n            val previewBitmap by remember(invalidations) {\n                derivedStateOf {\n                    if (drawMode is DrawMode.Warp) {\n                        warpedImage\n                    } else {\n                        outputImage.overlay(drawPathBitmap)\n                    }\n                }\n            }\n\n            onDraw?.let {\n                LaunchedEffect(invalidations) {\n                    onDraw(previewBitmap.asAndroidBitmap())\n                }\n            }\n\n            BitmapDrawerPreview(\n                preview = previewBitmap,\n                globalTouchPointersCount = globalTouchPointersCount,\n                onReceiveMotionEvent = { motionEvent.value = it },\n                onInvalidate = { invalidations++ },\n                onUpdateCurrentDrawPosition = { currentDrawPosition = it },\n                onUpdateDrawDownPosition = { drawDownPosition = it },\n                drawEnabled = !panEnabled && !isWarpInputLocked,\n                helperGridParams = helperGridParams\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/BrushSoftnessSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Dots\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun BrushSoftnessSelector(\n    modifier: Modifier,\n    value: Float,\n    color: Color = Color.Unspecified,\n    onValueChange: (Float) -> Unit\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        title = stringResource(R.string.brush_softness),\n        valueRange = 0f..100f,\n        onValueChange = {\n            onValueChange(it.roundToTwoDigits())\n        },\n        valueSuffix = \" Pt\",\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        icon = Icons.Rounded.Dots,\n        shape = ShapeDefaults.extraLarge,\n        containerColor = color\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/DrawColorSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrushColor\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun DrawColorSelector(\n    modifier: Modifier = Modifier\n        .padding(start = 16.dp, end = 16.dp, bottom = 16.dp),\n    value: Color,\n    onValueChange: (Color) -> Unit,\n    color: Color = Color.Unspecified,\n    titleText: String = stringResource(R.string.paint_color),\n    defaultColors: List<Color> = ColorSelectionRowDefaults.colorList,\n) {\n    ColorRowSelector(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier\n            .container(\n                shape = ShapeDefaults.extraLarge,\n                color = color\n            ),\n        title = titleText,\n        allowAlpha = false,\n        icon = Icons.Outlined.BrushColor,\n        defaultColors = defaultColors\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/DrawLineStyleSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyHorizontalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BoldLine\nimport com.t8rin.imagetoolbox.core.resources.icons.DashedLine\nimport com.t8rin.imagetoolbox.core.resources.icons.DotDashedLine\nimport com.t8rin.imagetoolbox.core.resources.icons.StampedLine\nimport com.t8rin.imagetoolbox.core.resources.icons.ZigzagLine\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.IconShape\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\n\n@Composable\nfun DrawLineStyleSelector(\n    modifier: Modifier,\n    value: DrawLineStyle,\n    onValueChange: (DrawLineStyle) -> Unit,\n    values: List<DrawLineStyle> = DrawLineStyle.entries\n) {\n    var isSheetVisible by rememberSaveable { mutableStateOf(false) }\n\n    LaunchedEffect(values, value) {\n        if (values.filterIsInstance(value::class.java).isEmpty() && values.isNotEmpty()) {\n            onValueChange(values.first())\n        }\n    }\n\n    Column(\n        modifier = modifier\n            .container(ShapeDefaults.extraLarge),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        EnhancedButtonGroup(\n            enabled = true,\n            itemCount = values.size,\n            title = {\n                Text(\n                    text = stringResource(R.string.line_style),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n                Spacer(modifier = Modifier.width(8.dp))\n                SupportingButton(\n                    onClick = {\n                        isSheetVisible = true\n                    }\n                )\n            },\n            selectedIndex = values.indexOfFirst {\n                value::class.isInstance(it)\n            },\n            itemContent = {\n                Icon(\n                    imageVector = values[it].getIcon(),\n                    contentDescription = null\n                )\n            },\n            onIndexChange = {\n                onValueChange(values[it])\n            },\n            activeButtonColor = MaterialTheme.colorScheme.secondaryContainer\n        )\n        var lineStyle by remember {\n            mutableStateOf<DrawLineStyle?>(value)\n        }\n\n        AnimatedVisibility(\n            visible = value is DrawLineStyle.Dashed,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            SideEffect {\n                if (value is DrawLineStyle.Dashed) {\n                    lineStyle = value\n                }\n            }\n            DisposableEffect(Unit) {\n                onDispose { lineStyle = null }\n            }\n            val style = lineStyle as? DrawLineStyle.Dashed ?: return@AnimatedVisibility\n\n            Column {\n                EnhancedSliderItem(\n                    value = style.size.value,\n                    title = stringResource(R.string.dash_size),\n                    valueRange = 0f..100f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        onValueChange(\n                            style.copy(\n                                size = it.pt\n                            )\n                        )\n                    },\n                    valueSuffix = \" Pt\",\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp),\n                    shape = ShapeDefaults.top\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                EnhancedSliderItem(\n                    value = style.gap.value,\n                    title = stringResource(R.string.gap_size),\n                    valueRange = 0f..100f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        onValueChange(\n                            style.copy(\n                                gap = it.pt\n                            )\n                        )\n                    },\n                    valueSuffix = \" Pt\",\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp),\n                    shape = ShapeDefaults.bottom\n                )\n                Spacer(modifier = Modifier.height(8.dp))\n            }\n        }\n\n        AnimatedVisibility(\n            visible = value is DrawLineStyle.ZigZag,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            SideEffect {\n                if (value is DrawLineStyle.ZigZag) {\n                    lineStyle = value\n                }\n            }\n            DisposableEffect(Unit) {\n                onDispose { lineStyle = null }\n            }\n            val style = lineStyle as? DrawLineStyle.ZigZag ?: return@AnimatedVisibility\n\n            Column {\n                var ratio by remember {\n                    mutableFloatStateOf(style.heightRatio)\n                }\n                EnhancedSliderItem(\n                    value = ratio,\n                    title = stringResource(R.string.zigzag_ratio),\n                    valueRange = 0.5f..20f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        ratio = it\n                        onValueChange(\n                            style.copy(\n                                heightRatio = 20.5f - it\n                            )\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp),\n                    shape = ShapeDefaults.default\n                )\n                Spacer(modifier = Modifier.height(8.dp))\n            }\n        }\n\n        AnimatedVisibility(\n            visible = value is DrawLineStyle.Stamped<*>,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            SideEffect {\n                if (value is DrawLineStyle.Stamped<*>) {\n                    lineStyle = value\n                }\n            }\n            DisposableEffect(Unit) {\n                onDispose { lineStyle = null }\n            }\n            val style = lineStyle as? DrawLineStyle.Stamped<*> ?: return@AnimatedVisibility\n\n            val shape = if (style.shape is Shape) style.shape\n            else MaterialStarShape\n\n            Column {\n                val shapes = IconShape.entriesNoRandom\n\n                Column(\n                    modifier = Modifier\n                        .padding(horizontal = 8.dp)\n                        .container(\n                            shape = ShapeDefaults.top,\n                            color = MaterialTheme.colorScheme.surface,\n                            resultPadding = 0.dp\n                        )\n                ) {\n                    val state = rememberLazyGridState()\n                    LazyHorizontalGrid(\n                        state = state,\n                        rows = GridCells.Adaptive(48.dp),\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .height(240.dp)\n                            .fadingEdges(\n                                scrollableState = state,\n                                spanCount = 4,\n                                length = 32.dp\n                            ),\n                        verticalArrangement = Arrangement.spacedBy(\n                            space = 6.dp,\n                            alignment = Alignment.CenterVertically\n                        ),\n                        horizontalArrangement = Arrangement.spacedBy(\n                            space = 6.dp,\n                            alignment = Alignment.CenterHorizontally\n                        ),\n                        contentPadding = PaddingValues(8.dp),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        items(shapes) { iconShape ->\n                            val selected by remember(iconShape, shape) {\n                                derivedStateOf {\n                                    iconShape.shape == shape\n                                }\n                            }\n                            val color by animateColorAsState(\n                                if (selected) MaterialTheme.colorScheme.primaryContainer\n                                else Color.Unspecified\n                            )\n                            val borderColor by animateColorAsState(\n                                if (selected) {\n                                    MaterialTheme.colorScheme.onPrimaryContainer.copy(0.7f)\n                                } else MaterialTheme.colorScheme.onSecondaryContainer.copy(\n                                    alpha = 0.1f\n                                )\n                            )\n                            Box(\n                                modifier = Modifier\n                                    .aspectRatio(1f)\n                                    .container(\n                                        color = color,\n                                        shape = CloverShape,\n                                        borderColor = borderColor,\n                                        resultPadding = 0.dp\n                                    )\n                                    .hapticsClickable {\n                                        onValueChange(\n                                            DrawLineStyle.Stamped(\n                                                shape = iconShape.shape,\n                                                spacing = style.spacing\n                                            )\n                                        )\n                                    },\n                                contentAlignment = Alignment.Center\n                            ) {\n                                Box(\n                                    modifier = Modifier\n                                        .size(30.dp)\n                                        .container(\n                                            borderWidth = 2.dp,\n                                            borderColor = MaterialTheme.colorScheme.onSurfaceVariant,\n                                            color = Color.Transparent,\n                                            shape = iconShape.shape\n                                        )\n                                )\n                            }\n                        }\n                    }\n                }\n                Spacer(modifier = Modifier.height(4.dp))\n                EnhancedSliderItem(\n                    value = style.spacing.value,\n                    title = stringResource(R.string.spacing),\n                    valueRange = 0f..100f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        onValueChange(\n                            style.copy(\n                                spacing = it.pt\n                            )\n                        )\n                    },\n                    valueSuffix = \" Pt\",\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp),\n                    shape = ShapeDefaults.bottom\n                )\n                Spacer(modifier = Modifier.height(8.dp))\n            }\n        }\n    }\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Column(\n                modifier = Modifier\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(8.dp),\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                values.forEachIndexed { index, item ->\n                    Column(\n                        Modifier\n                            .fillMaxWidth()\n                            .container(\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = values.size\n                                ),\n                                resultPadding = 0.dp\n                            )\n                    ) {\n                        TitleItem(\n                            text = stringResource(item.getTitle()),\n                            icon = item.getIcon()\n                        )\n                        Text(\n                            text = stringResource(item.getSubtitle()),\n                            modifier = Modifier.padding(\n                                start = 16.dp,\n                                end = 16.dp,\n                                bottom = 16.dp\n                            ),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                }\n            }\n        },\n        visible = isSheetVisible,\n        onDismiss = {\n            isSheetVisible = it\n        },\n        title = {\n            TitleItem(text = stringResource(R.string.draw_mode))\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { isSheetVisible = false }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}\n\nprivate fun DrawLineStyle.getSubtitle(): Int = when (this) {\n    is DrawLineStyle.Dashed -> R.string.dashed_sub\n    DrawLineStyle.DotDashed -> R.string.dot_dashed_sub\n    DrawLineStyle.None -> R.string.defaultt_sub\n    is DrawLineStyle.Stamped<*> -> R.string.stamped_sub\n    is DrawLineStyle.ZigZag -> R.string.zigzag_sub\n}\n\nprivate fun DrawLineStyle.getTitle(): Int = when (this) {\n    is DrawLineStyle.Dashed -> R.string.dashed\n    DrawLineStyle.DotDashed -> R.string.dot_dashed\n    DrawLineStyle.None -> R.string.defaultt\n    is DrawLineStyle.Stamped<*> -> R.string.stamped\n    is DrawLineStyle.ZigZag -> R.string.zigzag\n}\n\nprivate fun DrawLineStyle.getIcon(): ImageVector = when (this) {\n    is DrawLineStyle.Dashed -> Icons.Rounded.DashedLine\n    DrawLineStyle.DotDashed -> Icons.Rounded.DotDashedLine\n    DrawLineStyle.None -> Icons.Rounded.BoldLine\n    is DrawLineStyle.Stamped<*> -> Icons.Rounded.StampedLine\n    is DrawLineStyle.ZigZag -> Icons.Rounded.ZigzagLine\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/DrawModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.AutoFixHigh\nimport androidx.compose.material.icons.outlined.Healing\nimport androidx.compose.material.icons.outlined.Image\nimport androidx.compose.material.icons.rounded.BlurCircular\nimport androidx.compose.material.icons.rounded.TextFormat\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Cube\nimport com.t8rin.imagetoolbox.core.resources.icons.Highlighter\nimport com.t8rin.imagetoolbox.core.resources.icons.MeshGradient\nimport com.t8rin.imagetoolbox.core.resources.icons.NeonBrush\nimport com.t8rin.imagetoolbox.core.resources.icons.Pen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.CustomPathEffectParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.ImageParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.PixelationParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.PrivacyBlurParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.SpotHealParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.TextParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.WarpParamsSelector\n\n@Composable\nfun DrawModeSelector(\n    addFiltersSheetComponent: AddFiltersSheetComponent,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent,\n    modifier: Modifier,\n    value: DrawMode,\n    strokeWidth: Pt,\n    onValueChange: (DrawMode) -> Unit,\n    values: List<DrawMode> = DrawMode.entries\n) {\n    var isSheetVisible by rememberSaveable { mutableStateOf(false) }\n\n    LaunchedEffect(values, value) {\n        if (values.find { it::class.isInstance(value) } == null) {\n            values.firstOrNull()?.let { onValueChange(it) }\n        }\n    }\n\n    Column(\n        modifier = modifier\n            .container(ShapeDefaults.extraLarge),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        EnhancedButtonGroup(\n            enabled = true,\n            itemCount = values.size,\n            title = {\n                Text(\n                    text = stringResource(R.string.draw_mode),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n                Spacer(modifier = Modifier.width(8.dp))\n                SupportingButton(\n                    onClick = {\n                        isSheetVisible = true\n                    }\n                )\n            },\n            selectedIndex = values.indexOfFirst {\n                value::class.isInstance(it)\n            },\n            itemContent = {\n                Icon(\n                    imageVector = values[it].getIcon(),\n                    contentDescription = null\n                )\n            },\n            onIndexChange = {\n                onValueChange(values[it])\n            }\n        )\n\n        WarpParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        SpotHealParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        PrivacyBlurParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        PixelationParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        TextParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        ImageParamsSelector(\n            value = value,\n            onValueChange = onValueChange,\n            strokeWidth = strokeWidth\n        )\n\n        CustomPathEffectParamsSelector(\n            value = value,\n            onValueChange = onValueChange,\n            addFiltersSheetComponent = addFiltersSheetComponent,\n            filterTemplateCreationSheetComponent = filterTemplateCreationSheetComponent\n        )\n    }\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Column(\n                modifier = Modifier\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(8.dp),\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                values.forEachIndexed { index, item ->\n                    Column(\n                        Modifier\n                            .fillMaxWidth()\n                            .container(\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = values.size\n                                ),\n                                resultPadding = 0.dp\n                            )\n                    ) {\n                        TitleItem(\n                            text = stringResource(item.getTitle()),\n                            icon = item.getIcon()\n                        )\n                        Text(\n                            text = stringResource(item.getSubtitle()),\n                            modifier = Modifier.padding(\n                                start = 16.dp,\n                                end = 16.dp,\n                                bottom = 16.dp\n                            ),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                }\n            }\n        },\n        visible = isSheetVisible,\n        onDismiss = {\n            isSheetVisible = it\n        },\n        title = {\n            TitleItem(text = stringResource(R.string.draw_mode))\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { isSheetVisible = false }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}\n\nprivate fun DrawMode.getSubtitle(): Int = when (this) {\n    is DrawMode.Highlighter -> R.string.highlighter_sub\n    is DrawMode.Neon -> R.string.neon_sub\n    is DrawMode.Pen -> R.string.pen_sub\n    is DrawMode.PathEffect.PrivacyBlur -> R.string.privacy_blur_sub\n    is DrawMode.PathEffect.Pixelation -> R.string.pixelation_sub\n    is DrawMode.Text -> R.string.draw_text_sub\n    is DrawMode.Image -> R.string.draw_mode_image_sub\n    is DrawMode.PathEffect.Custom -> R.string.draw_filter_sub\n    is DrawMode.SpotHeal -> R.string.spot_heal_sub\n    is DrawMode.Warp -> R.string.warp_sub\n}\n\nprivate fun DrawMode.getTitle(): Int = when (this) {\n    is DrawMode.Highlighter -> R.string.highlighter\n    is DrawMode.Neon -> R.string.neon\n    is DrawMode.Pen -> R.string.pen\n    is DrawMode.PathEffect.PrivacyBlur -> R.string.privacy_blur\n    is DrawMode.PathEffect.Pixelation -> R.string.pixelation\n    is DrawMode.Text -> R.string.text\n    is DrawMode.Image -> R.string.image\n    is DrawMode.PathEffect.Custom -> R.string.filter\n    is DrawMode.SpotHeal -> R.string.spot_heal\n    is DrawMode.Warp -> R.string.warp\n}\n\nprivate fun DrawMode.getIcon(): ImageVector = when (this) {\n    is DrawMode.Highlighter -> Icons.Outlined.Highlighter\n    is DrawMode.Neon -> Icons.Outlined.NeonBrush\n    is DrawMode.Pen -> Icons.Outlined.Pen\n    is DrawMode.PathEffect.PrivacyBlur -> Icons.Rounded.BlurCircular\n    is DrawMode.PathEffect.Pixelation -> Icons.Outlined.Cube\n    is DrawMode.Text -> Icons.Rounded.TextFormat\n    is DrawMode.Image -> Icons.Outlined.Image\n    is DrawMode.PathEffect.Custom -> Icons.Outlined.AutoFixHigh\n    is DrawMode.SpotHeal -> Icons.Outlined.Healing\n    is DrawMode.Warp -> Icons.Outlined.MeshGradient\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/DrawPathModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.ArrowParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.DrawPathModeInfoSheet\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.FloodFillParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.OvalParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.PolygonParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.RectParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.SprayParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.StarParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.element.TriangleParamsSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.getIcon\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.saveState\n\n@Composable\nfun DrawPathModeSelector(\n    modifier: Modifier,\n    values: List<DrawPathMode> = DrawPathMode.entries,\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit,\n    drawMode: DrawMode,\n    containerColor: Color = Color.Unspecified\n) {\n    var isSheetVisible by rememberSaveable { mutableStateOf(false) }\n\n    LaunchedEffect(value, values) {\n        if (values.find { it::class.isInstance(value) } == null) {\n            values.firstOrNull()?.let { onValueChange(it) }\n        }\n    }\n\n    Column(\n        modifier = modifier\n            .container(\n                shape = ShapeDefaults.extraLarge,\n                color = containerColor\n            ),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        EnhancedButtonGroup(\n            enabled = true,\n            itemCount = values.size,\n            title = {\n                Text(\n                    text = stringResource(R.string.draw_path_mode),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n                Spacer(modifier = Modifier.width(8.dp))\n                SupportingButton(\n                    onClick = {\n                        isSheetVisible = true\n                    }\n                )\n            },\n            selectedIndex = remember(values, value) {\n                derivedStateOf {\n                    values.indexOfFirst {\n                        value::class.isInstance(it)\n                    }\n                }\n            }.value,\n            activeButtonColor = MaterialTheme.colorScheme.surfaceContainerHighest,\n            itemContent = {\n                Icon(\n                    imageVector = values[it].getIcon(),\n                    contentDescription = null\n                )\n            },\n            onIndexChange = {\n                onValueChange(values[it].saveState(value))\n            }\n        )\n\n        val canChangeFillColor =\n            value is DrawPathMode.Outlined && (drawMode is DrawMode.Pen || drawMode is DrawMode.Highlighter || drawMode is DrawMode.Neon)\n\n        PolygonParamsSelector(\n            value = value,\n            onValueChange = onValueChange,\n            canChangeFillColor = canChangeFillColor\n        )\n\n        StarParamsSelector(\n            value = value,\n            onValueChange = onValueChange,\n            canChangeFillColor = canChangeFillColor\n        )\n\n        RectParamsSelector(\n            value = value,\n            onValueChange = onValueChange,\n            canChangeFillColor = canChangeFillColor\n        )\n\n        OvalParamsSelector(\n            value = value,\n            onValueChange = onValueChange,\n            canChangeFillColor = canChangeFillColor\n        )\n\n        TriangleParamsSelector(\n            value = value,\n            onValueChange = onValueChange,\n            canChangeFillColor = canChangeFillColor\n        )\n\n        ArrowParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        FloodFillParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        SprayParamsSelector(\n            value = value,\n            onValueChange = onValueChange\n        )\n    }\n\n    DrawPathModeInfoSheet(\n        visible = isSheetVisible,\n        onDismiss = { isSheetVisible = false },\n        values = values\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/LineWidthSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.LineWeight\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun LineWidthSelector(\n    modifier: Modifier,\n    value: Float,\n    title: String = stringResource(R.string.line_width),\n    valueRange: ClosedFloatingPointRange<Float> = 1f..100f,\n    color: Color = Color.Unspecified,\n    onValueChange: (Float) -> Unit\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        containerColor = color,\n        icon = Icons.Rounded.LineWeight,\n        title = title,\n        valueSuffix = \" Pt\",\n        sliderModifier = Modifier\n            .padding(top = 14.dp, start = 12.dp, end = 12.dp, bottom = 10.dp),\n        valueRange = valueRange,\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        onValueChange = {\n            onValueChange(it.roundToTwoDigits())\n        },\n        shape = ShapeDefaults.extraLarge\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/OpenColorPickerCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Eyedropper\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun OpenColorPickerCard(\n    onOpen: () -> Unit,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 16.dp)\n) {\n    Row(\n        modifier = modifier\n            .container(\n                resultPadding = 0.dp,\n                color = MaterialTheme.colorScheme.mixedContainer.copy(0.7f),\n                shape = ShapeDefaults.extraLarge\n            )\n            .hapticsClickable(onClick = onOpen)\n            .padding(16.dp),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Text(\n            text = stringResource(id = R.string.pipette),\n            modifier = Modifier.weight(1f),\n            color = MaterialTheme.colorScheme.onMixedContainer\n        )\n        Icon(\n            imageVector = Icons.Outlined.Eyedropper,\n            contentDescription = stringResource(R.string.pipette),\n            tint = MaterialTheme.colorScheme.onMixedContainer\n        )\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/PixelSizeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Cube\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun PixelSizeSelector(\n    modifier: Modifier,\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    color: Color = Color.Unspecified\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        title = stringResource(R.string.pixel_size),\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        icon = Icons.Outlined.Cube,\n        valueRange = 10f..75f,\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        onValueChange = {\n            onValueChange(it.roundToTwoDigits())\n        },\n        shape = ShapeDefaults.default,\n        containerColor = color\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/UiPathPaint.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.PathPaint\n\ndata class UiPathPaint(\n    override val path: Path,\n    override val strokeWidth: Pt,\n    override val brushSoftness: Pt,\n    override val drawColor: Color = Color.Transparent,\n    override val isErasing: Boolean,\n    override val drawMode: DrawMode = DrawMode.Pen,\n    override val canvasSize: IntegerSize,\n    override val drawPathMode: DrawPathMode = DrawPathMode.Free,\n    override val drawLineStyle: DrawLineStyle = DrawLineStyle.None\n) : PathPaint<Path, Color>\n\n\nfun PathPaint<Path, Color>.toUiPathPaint() = UiPathPaint(\n    path = path,\n    strokeWidth = strokeWidth,\n    brushSoftness = brushSoftness,\n    drawColor = drawColor,\n    isErasing = isErasing,\n    drawMode = drawMode,\n    canvasSize = canvasSize,\n    drawPathMode = drawPathMode,\n    drawLineStyle = drawLineStyle\n)"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/UiPathPaintCanvasAction.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components\n\nimport android.annotation.SuppressLint\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.PaintingStyle\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePaint\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.createFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.SpotHealMode\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.scaleToFitCanvas\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.utils.toImageModel\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.clipBitmap\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.drawRepeatedImageOnPath\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.drawRepeatedTextOnPath\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.overlay\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.pathEffectPaint\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.rememberPaint\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.transformationsForMode\nimport com.t8rin.trickle.WarpBrush\nimport com.t8rin.trickle.WarpEngine\nimport com.t8rin.trickle.WarpMode\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport kotlin.math.roundToInt\nimport android.graphics.Paint as AndroidPaint\n\n@SuppressLint(\"ComposableNaming\")\n@Composable\ninternal fun Canvas.UiPathPaintCanvasAction(\n    uiPathPaint: UiPathPaint,\n    invalidations: Int,\n    onInvalidate: () -> Unit,\n    canvasSize: IntegerSize,\n    pathsCount: Int,\n    backgroundColor: Color,\n    drawImageBitmap: ImageBitmap,\n    drawBitmap: ImageBitmap,\n    onClearDrawPath: () -> Unit,\n    onClearWarpDrawPath: (Long) -> Unit,\n    onRequestFiltering: suspend (Bitmap, List<Filter<*>>) -> Bitmap?,\n) = with(nativeCanvas) {\n    val (nonScaledPath, strokeWidth, brushSoftness, drawColor, isEraserOn, drawMode, size, drawPathMode, drawLineStyle) = uiPathPaint\n\n    val path by remember(nonScaledPath, canvasSize, size) {\n        derivedStateOf {\n            nonScaledPath.scaleToFitCanvas(\n                currentSize = canvasSize,\n                oldSize = size\n            ).asAndroidPath()\n        }\n    }\n\n    if (drawMode is DrawMode.PathEffect && !isEraserOn) {\n        var shaderSource by remember(backgroundColor) {\n            mutableStateOf<ImageBitmap?>(null)\n        }\n        LaunchedEffect(shaderSource, invalidations) {\n            withContext(Dispatchers.Default) {\n                if (shaderSource == null || invalidations <= pathsCount) {\n                    shaderSource = onRequestFiltering(\n                        drawImageBitmap.overlay(drawBitmap)\n                            .asAndroidBitmap(),\n                        transformationsForMode(\n                            drawMode = drawMode,\n                            canvasSize = canvasSize\n                        )\n                    )?.asImageBitmap()?.clipBitmap(\n                        path = path.asComposePath(),\n                        paint = pathEffectPaint(\n                            strokeWidth = strokeWidth,\n                            drawPathMode = drawPathMode,\n                            canvasSize = canvasSize\n                        ).asComposePaint()\n                    )?.also {\n                        it.prepareToDraw()\n                        onInvalidate()\n                    }\n                }\n            }\n        }\n        if (shaderSource != null) {\n            LaunchedEffect(shaderSource) {\n                onClearDrawPath()\n            }\n            val imagePaint = remember { Paint() }\n            drawImage(\n                image = shaderSource!!,\n                topLeftOffset = Offset.Zero,\n                paint = imagePaint\n            )\n        }\n    } else if (drawMode is DrawMode.SpotHeal && !isEraserOn) {\n        val paint = remember(uiPathPaint, canvasSize) {\n            val isSharpEdge = drawPathMode.isSharpEdge\n            val isFilled = drawPathMode.isFilled\n            val stroke = strokeWidth.toPx(canvasSize)\n\n            Paint().apply {\n                if (isFilled) {\n                    style = PaintingStyle.Fill\n                } else {\n                    style = PaintingStyle.Stroke\n                    this.strokeWidth = stroke\n                    if (isSharpEdge) {\n                        strokeCap = StrokeCap.Square\n                    } else {\n                        strokeCap = StrokeCap.Round\n                        strokeJoin = StrokeJoin.Round\n                    }\n                }\n\n                color = Color.White\n            }\n        }\n\n        var isLoading by remember {\n            mutableStateOf(false)\n        }\n\n        var progress by remember {\n            mutableFloatStateOf(0f)\n        }\n\n        var shaderSource by remember(backgroundColor) {\n            mutableStateOf<ImageBitmap?>(null)\n        }\n        LaunchedEffect(shaderSource, invalidations) {\n            withContext(Dispatchers.Default) {\n                if (shaderSource == null || invalidations <= pathsCount) {\n                    isLoading = true\n                    val job = launch {\n                        while (progress < 0.5f && isActive && isLoading) {\n                            progress += 0.01f\n                            delay(100)\n                        }\n                        while (progress < 0.75f && isActive && isLoading) {\n                            progress += 0.0025f\n                            delay(100)\n                        }\n                        while (progress < 1f && isActive && isLoading) {\n                            progress += 0.0025f\n                            delay(500)\n                        }\n                    }\n\n                    shaderSource = withContext(Dispatchers.IO) {\n                        onRequestFiltering(\n                            drawImageBitmap.overlay(drawBitmap).asAndroidBitmap(),\n                            listOf(\n                                createFilter<Pair<ImageModel, SpotHealMode>, Filter.SpotHeal>(\n                                    Pair(\n                                        createBitmap(\n                                            width = canvasSize.width,\n                                            height = canvasSize.height\n                                        ).applyCanvas {\n                                            drawColor(Color.Black.toArgb())\n                                            drawPath(\n                                                path,\n                                                paint.nativePaint\n                                            )\n                                        }.toImageModel(),\n                                        drawMode.mode\n                                    )\n                                )\n                            )\n                        )?.asImageBitmap()?.clipBitmap(\n                            path = path.asComposePath(),\n                            paint = paint.apply {\n                                blendMode = BlendMode.Clear\n                            }\n                        )?.also {\n                            it.prepareToDraw()\n                            onInvalidate()\n                        }\n                    }\n                    isLoading = false\n                    job.cancel()\n                    progress = 0f\n                }\n            }\n        }\n        if (shaderSource != null) {\n            LaunchedEffect(shaderSource) {\n                onClearDrawPath()\n                onInvalidate()\n            }\n            val imagePaint = remember { Paint() }\n            drawImage(\n                image = shaderSource!!,\n                topLeftOffset = Offset.Zero,\n                paint = imagePaint\n            )\n        }\n\n        LoadingDialog(\n            visible = isLoading,\n            canCancel = false,\n            progress = { progress },\n            loaderSize = 72.dp,\n            additionalContent = {\n                AutoSizeText(\n                    text = \"${(progress * 100).roundToInt()}%\",\n                    maxLines = 1,\n                    fontWeight = FontWeight.Medium,\n                    modifier = Modifier.width(it * 0.8f),\n                    textAlign = TextAlign.Center\n                )\n            }\n        )\n    } else if (drawMode is DrawMode.Warp && !isEraserOn) {\n        var warpedBitmap by remember(uiPathPaint, canvasSize) {\n            mutableStateOf<ImageBitmap?>(null)\n        }\n\n        LaunchedEffect(warpedBitmap, invalidations) {\n            if (warpedBitmap == null || invalidations <= pathsCount) {\n                val source = drawImageBitmap\n                    .overlay(drawBitmap)\n                    .asAndroidBitmap()\n\n                withContext(Dispatchers.Default) {\n                    val engine = WarpEngine(source)\n\n                    try {\n                        drawMode.strokes.forEach { warp ->\n                            val stroke = warp.scaleToFitCanvas(\n                                currentSize = canvasSize,\n                                oldSize = size\n                            )\n                            engine.applyStroke(\n                                fromX = stroke.fromX,\n                                fromY = stroke.fromY,\n                                toX = stroke.toX,\n                                toY = stroke.toY,\n                                brush = WarpBrush(\n                                    radius = strokeWidth.toPx(canvasSize),\n                                    strength = drawMode.strength,\n                                    hardness = drawMode.hardness\n                                ),\n                                mode = WarpMode.valueOf(drawMode.warpMode.name)\n                            )\n                        }\n\n                        warpedBitmap = engine\n                            .render()\n                            .asImageBitmap().also {\n                                it.prepareToDraw()\n                                onInvalidate()\n                            }\n                    } finally {\n                        engine.release()\n                    }\n                }\n            }\n        }\n\n        warpedBitmap?.let {\n            LaunchedEffect(warpedBitmap) {\n                onClearWarpDrawPath(drawMode.previewClearToken)\n            }\n            val imagePaint = remember { Paint() }\n            drawImage(\n                image = warpedBitmap!!,\n                topLeftOffset = Offset.Zero,\n                paint = imagePaint\n            )\n        }\n    } else {\n        val pathPaint by rememberPaint(\n            strokeWidth = strokeWidth,\n            isEraserOn = isEraserOn,\n            drawColor = drawColor,\n            brushSoftness = brushSoftness,\n            drawMode = drawMode,\n            canvasSize = canvasSize,\n            drawPathMode = drawPathMode,\n            drawLineStyle = drawLineStyle\n        )\n        if (drawMode is DrawMode.Text && !isEraserOn) {\n            if (drawMode.isRepeated) {\n                drawRepeatedTextOnPath(\n                    text = drawMode.text,\n                    path = path,\n                    paint = pathPaint,\n                    interval = drawMode.repeatingInterval.toPx(canvasSize)\n                )\n            } else {\n                drawTextOnPath(drawMode.text, path, 0f, 0f, pathPaint)\n            }\n        } else if (drawMode is DrawMode.Image && !isEraserOn) {\n            drawRepeatedImageOnPath(\n                drawMode = drawMode,\n                strokeWidth = strokeWidth,\n                canvasSize = canvasSize,\n                path = path,\n                paint = pathPaint,\n                invalidations = invalidations\n            )\n        } else if (drawPathMode is DrawPathMode.Outlined) {\n            drawPathMode.fillColor?.let { fillColor ->\n                val filledPaint = remember(fillColor, pathPaint) {\n                    AndroidPaint().apply {\n                        set(pathPaint)\n                        style = AndroidPaint.Style.FILL\n                        color = fillColor.colorInt\n                        if (Color(fillColor.colorInt).alpha == 1f) {\n                            alpha =\n                                (drawColor.alpha * 255).roundToInt().coerceIn(0, 255)\n                        }\n                        pathEffect = null\n                    }\n                }\n\n                drawPath(path, filledPaint)\n            }\n            drawPath(path, pathPaint)\n        } else {\n            drawPath(path, pathPaint)\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/controls/DrawContentControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.controls\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BackgroundColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.HelperGridParamsSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.MagnifierEnabledSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawBehavior\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BrushSoftnessSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawColorSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawLineStyleSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawModeSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawPathModeSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.LineWidthSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.OpenColorPickerCard\nimport com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageSheet\n\n@Composable\ninternal fun DrawContentControls(\n    component: DrawComponent,\n    secondaryControls: @Composable () -> Unit,\n    drawColor: Color,\n    onDrawColorChange: (Color) -> Unit,\n    strokeWidth: Pt,\n    onStrokeWidthChange: (Pt) -> Unit,\n    brushSoftness: Pt,\n    onBrushSoftnessChange: (Pt) -> Unit,\n    alpha: Float,\n    onAlphaChange: (Float) -> Unit\n) {\n    var showPickColorSheet by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val drawMode = component.drawMode\n    val drawPathMode = component.drawPathMode\n    val drawLineStyle = component.drawLineStyle\n\n    Column(\n        modifier = Modifier.padding(16.dp),\n        verticalArrangement = Arrangement.spacedBy(8.dp),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        if (!isPortrait) {\n            Row(\n                modifier = Modifier\n                    .padding(vertical = 8.dp)\n                    .container(shape = ShapeDefaults.circle)\n            ) {\n                secondaryControls()\n            }\n        }\n        AnimatedVisibility(\n            visible = drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            OpenColorPickerCard(\n                modifier = Modifier.fillMaxWidth(),\n                onOpen = {\n                    component.openColorPicker()\n                    showPickColorSheet = true\n                }\n            )\n        }\n        AnimatedVisibility(\n            visible = drawMode !is DrawMode.PathEffect && drawMode !is DrawMode.Image && drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            DrawColorSelector(\n                modifier = Modifier.fillMaxWidth(),\n                value = drawColor,\n                onValueChange = onDrawColorChange\n            )\n        }\n        AnimatedVisibility(\n            visible = drawPathMode.canChangeStrokeWidth,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            LineWidthSelector(\n                modifier = Modifier.fillMaxWidth(),\n                title = if (drawMode is DrawMode.Text) {\n                    stringResource(R.string.font_size)\n                } else stringResource(R.string.line_width),\n                valueRange = if (drawMode is DrawMode.Image) {\n                    10f..120f\n                } else 1f..100f,\n                value = strokeWidth.value,\n                onValueChange = { onStrokeWidthChange(it.pt) }\n            )\n        }\n        AnimatedVisibility(\n            visible = drawMode !is DrawMode.Highlighter && drawMode !is DrawMode.PathEffect && drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            BrushSoftnessSelector(\n                modifier = Modifier.fillMaxWidth(),\n                value = brushSoftness.value,\n                onValueChange = { onBrushSoftnessChange(it.pt) }\n            )\n        }\n        if (component.drawBehavior is DrawBehavior.Background) {\n            ColorRowSelector(\n                value = component.backgroundColor,\n                onValueChange = component::updateBackgroundColor,\n                icon = Icons.Outlined.BackgroundColor,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .container(\n                        shape = ShapeDefaults.extraLarge\n                    )\n            )\n        }\n        AnimatedVisibility(\n            visible = drawMode !is DrawMode.Neon && drawMode !is DrawMode.PathEffect && drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            AlphaSelector(\n                value = alpha,\n                onValueChange = onAlphaChange,\n                modifier = Modifier.fillMaxWidth()\n            )\n        }\n        DrawModeSelector(\n            modifier = Modifier.fillMaxWidth(),\n            value = drawMode,\n            strokeWidth = strokeWidth,\n            onValueChange = component::updateDrawMode,\n            values = remember(drawLineStyle) {\n                derivedStateOf {\n                    if (drawLineStyle == DrawLineStyle.None) {\n                        DrawMode.entries\n                    } else {\n                        listOf(\n                            DrawMode.Pen,\n                            DrawMode.Highlighter,\n                            DrawMode.Neon\n                        )\n                    }\n                }\n            }.value,\n            addFiltersSheetComponent = component.addFiltersSheetComponent,\n            filterTemplateCreationSheetComponent = component.filterTemplateCreationSheetComponent\n        )\n        AnimatedVisibility(\n            visible = drawMode !is DrawMode.Warp,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            DrawPathModeSelector(\n                modifier = Modifier.fillMaxWidth(),\n                value = drawPathMode,\n                onValueChange = component::updateDrawPathMode,\n                values = remember(drawMode, drawLineStyle) {\n                    derivedStateOf {\n                        if (drawMode !is DrawMode.Text && drawMode !is DrawMode.Image) {\n                            when (drawLineStyle) {\n                                DrawLineStyle.None -> DrawPathMode.entries\n\n                                !is DrawLineStyle.Stamped<*> -> listOf(\n                                    DrawPathMode.Free,\n                                    DrawPathMode.Line,\n                                    DrawPathMode.LinePointingArrow(),\n                                    DrawPathMode.PointingArrow(),\n                                    DrawPathMode.DoublePointingArrow(),\n                                    DrawPathMode.DoubleLinePointingArrow(),\n                                ) + DrawPathMode.outlinedEntries\n\n                                else -> listOf(\n                                    DrawPathMode.Free,\n                                    DrawPathMode.Line\n                                ) + DrawPathMode.outlinedEntries\n                            }\n                        } else {\n                            listOf(\n                                DrawPathMode.Free,\n                                DrawPathMode.Line\n                            ) + DrawPathMode.outlinedEntries\n                        }\n                    }\n                }.value,\n                drawMode = drawMode\n            )\n        }\n        AnimatedVisibility(\n            visible = drawMode !is DrawMode.Warp,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            DrawLineStyleSelector(\n                modifier = Modifier.fillMaxWidth(),\n                value = drawLineStyle,\n                onValueChange = component::updateDrawLineStyle\n            )\n        }\n        HelperGridParamsSelector(\n            value = component.helperGridParams,\n            onValueChange = component::updateHelperGridParams,\n            modifier = Modifier.fillMaxWidth()\n        )\n        MagnifierEnabledSelector(\n            modifier = Modifier.fillMaxWidth(),\n            shape = ShapeDefaults.extraLarge,\n        )\n        SaveExifWidget(\n            modifier = Modifier.fillMaxWidth(),\n            checked = component.saveExif,\n            imageFormat = component.imageFormat,\n            onCheckedChange = component::setSaveExif\n        )\n        ImageFormatSelector(\n            modifier = Modifier.navigationBarsPadding(),\n            forceEnabled = component.drawBehavior is DrawBehavior.Background,\n            value = component.imageFormat,\n            onValueChange = component::setImageFormat\n        )\n    }\n\n    var colorPickerColor by rememberSaveable(stateSaver = ColorSaver) { mutableStateOf(Color.Black) }\n    PickColorFromImageSheet(\n        visible = showPickColorSheet,\n        onDismiss = {\n            showPickColorSheet = false\n        },\n        bitmap = component.colorPickerBitmap,\n        onColorChange = { colorPickerColor = it },\n        color = colorPickerColor\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/controls/DrawContentNoDataControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.controls\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BackgroundColor\nimport com.t8rin.imagetoolbox.core.resources.icons.ImagesMode\nimport com.t8rin.imagetoolbox.core.resources.icons.ImagesearchRoller\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.restrict\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent\n\n@Composable\ninternal fun DrawContentNoDataControls(\n    component: DrawComponent,\n    onPickImage: () -> Unit\n) {\n    var showBackgroundDrawingSetup by rememberSaveable { mutableStateOf(false) }\n\n    val cutout = WindowInsets.displayCutout.asPaddingValues()\n    LazyVerticalStaggeredGrid(\n        modifier = Modifier.fillMaxHeight(),\n        columns = StaggeredGridCells.Adaptive(300.dp),\n        horizontalArrangement = Arrangement.spacedBy(\n            space = 12.dp,\n            alignment = Alignment.CenterHorizontally\n        ),\n        verticalItemSpacing = 12.dp,\n        contentPadding = PaddingValues(\n            bottom = 12.dp + WindowInsets\n                .navigationBars\n                .asPaddingValues()\n                .calculateBottomPadding(),\n            top = 12.dp,\n            end = 12.dp + cutout.calculateEndPadding(\n                LocalLayoutDirection.current\n            ),\n            start = 12.dp + cutout.calculateStartPadding(\n                LocalLayoutDirection.current\n            )\n        ),\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        item {\n            PreferenceItem(\n                onClick = onPickImage,\n                startIcon = Icons.Outlined.ImagesMode,\n                title = stringResource(R.string.draw_on_image),\n                subtitle = stringResource(R.string.draw_on_image_sub),\n                modifier = Modifier.fillMaxWidth()\n            )\n        }\n        item {\n            PreferenceItem(\n                onClick = { showBackgroundDrawingSetup = true },\n                startIcon = Icons.Outlined.ImagesearchRoller,\n                title = stringResource(R.string.draw_on_background),\n                subtitle = stringResource(R.string.draw_on_background_sub),\n                modifier = Modifier.fillMaxWidth()\n            )\n        }\n    }\n\n    val drawOnBackgroundParams = component.drawOnBackgroundParams\n    val screenSize = LocalScreenSize.current\n    val screenWidth = screenSize.widthPx\n    val screenHeight = screenSize.heightPx\n\n    var width by remember(\n        showBackgroundDrawingSetup,\n        screenWidth,\n        drawOnBackgroundParams\n    ) {\n        mutableIntStateOf(drawOnBackgroundParams.width.takeIf { it > -1 } ?: screenWidth)\n    }\n    var height by remember(\n        showBackgroundDrawingSetup,\n        screenHeight,\n        drawOnBackgroundParams\n    ) {\n        mutableIntStateOf(drawOnBackgroundParams.height.takeIf { it > -1 } ?: screenHeight)\n    }\n    var sheetBackgroundColor by rememberSaveable(\n        showBackgroundDrawingSetup,\n        drawOnBackgroundParams,\n        stateSaver = ColorSaver\n    ) {\n        mutableStateOf(drawOnBackgroundParams.color?.toColor() ?: Color.White)\n    }\n    EnhancedModalBottomSheet(\n        title = {\n            TitleItem(\n                text = stringResource(R.string.draw),\n                icon = Icons.Rounded.ImagesearchRoller\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    showBackgroundDrawingSetup = false\n                    component.startDrawOnBackground(\n                        reqWidth = width,\n                        reqHeight = height,\n                        color = sheetBackgroundColor\n                    )\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.ok))\n            }\n        },\n        sheetContent = {\n            Box {\n                Column(Modifier.enhancedVerticalScroll(rememberScrollState())) {\n                    Row(\n                        Modifier\n                            .padding(16.dp)\n                            .container(shape = ShapeDefaults.extraLarge)\n                    ) {\n                        RoundedTextField(\n                            value = width.takeIf { it != 0 }?.toString() ?: \"\",\n                            onValueChange = {\n                                width = it.restrict(8192).toIntOrNull() ?: 0\n                            },\n                            shape = ShapeDefaults.smallStart,\n                            keyboardOptions = KeyboardOptions(\n                                keyboardType = KeyboardType.Number\n                            ),\n                            label = {\n                                Text(stringResource(R.string.width, \" \"))\n                            },\n                            modifier = Modifier\n                                .weight(1f)\n                                .padding(\n                                    start = 8.dp,\n                                    top = 8.dp,\n                                    bottom = 8.dp,\n                                    end = 2.dp\n                                )\n                        )\n                        RoundedTextField(\n                            value = height.takeIf { it != 0 }?.toString() ?: \"\",\n                            onValueChange = {\n                                height = it.restrict(8192).toIntOrNull() ?: 0\n                            },\n                            keyboardOptions = KeyboardOptions(\n                                keyboardType = KeyboardType.Number\n                            ),\n                            shape = ShapeDefaults.smallEnd,\n                            label = {\n                                Text(stringResource(R.string.height, \" \"))\n                            },\n                            modifier = Modifier\n                                .weight(1f)\n                                .padding(\n                                    start = 2.dp,\n                                    top = 8.dp,\n                                    bottom = 8.dp,\n                                    end = 8.dp\n                                ),\n                        )\n                    }\n                    ColorRowSelector(\n                        value = sheetBackgroundColor,\n                        onValueChange = { sheetBackgroundColor = it },\n                        icon = Icons.Outlined.BackgroundColor,\n                        modifier = Modifier\n                            .padding(\n                                start = 16.dp,\n                                end = 16.dp,\n                                bottom = 16.dp\n                            )\n                            .container(ShapeDefaults.extraLarge)\n                    )\n                }\n            }\n        },\n        visible = showBackgroundDrawingSetup,\n        onDismiss = {\n            showBackgroundDrawingSetup = it\n        }\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/controls/DrawContentSecondaryControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.controls\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.Redo\nimport androidx.compose.material.icons.automirrored.rounded.Undo\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.EraseModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent\n\n@Composable\ninternal fun DrawContentSecondaryControls(\n    component: DrawComponent,\n    panEnabled: Boolean,\n    onTogglePanEnabled: () -> Unit,\n    isEraserOn: Boolean,\n    onToggleIsEraserOn: () -> Unit\n) {\n    PanModeButton(\n        selected = panEnabled,\n        onClick = onTogglePanEnabled\n    )\n    EnhancedIconButton(\n        onClick = component::undo,\n        enabled = component.lastPaths.isNotEmpty() || component.paths.isNotEmpty()\n    ) {\n        Icon(\n            imageVector = Icons.AutoMirrored.Rounded.Undo,\n            contentDescription = \"Undo\"\n        )\n    }\n    EnhancedIconButton(\n        onClick = component::redo,\n        enabled = component.undonePaths.isNotEmpty()\n    ) {\n        Icon(\n            imageVector = Icons.AutoMirrored.Rounded.Redo,\n            contentDescription = \"Redo\"\n        )\n    }\n    EraseModeButton(\n        selected = isEraserOn,\n        enabled = !panEnabled,\n        onClick = onToggleIsEraserOn\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/ArrowParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.angle\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isArrow\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.sizeScale\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateArrow\n\n@Composable\ninternal fun ArrowParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value.isArrow(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            EnhancedSliderItem(\n                value = value.sizeScale(),\n                title = stringResource(R.string.head_length_scale),\n                valueRange = 0.5f..8f,\n                internalStateTransformation = {\n                    it.roundTo(1)\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateArrow(sizeScale = it)\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.top\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = value.angle() - 90f,\n                title = stringResource(R.string.angle),\n                valueRange = 0f..90f,\n                internalStateTransformation = {\n                    it.roundTo(1)\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateArrow(angle = it + 90f)\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.bottom\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/CustomPathEffectParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AutoFixNormal\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.AddFilterButton\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\n\n@Composable\ninternal fun CustomPathEffectParamsSelector(\n    value: DrawMode,\n    onValueChange: (DrawMode) -> Unit,\n    addFiltersSheetComponent: AddFiltersSheetComponent,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent\n) {\n    AnimatedVisibility(\n        visible = value is DrawMode.PathEffect.Custom,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        val filter by remember(value) {\n            derivedStateOf {\n                (value as? DrawMode.PathEffect.Custom)?.filter?.toUiFilter()\n            }\n        }\n        var showFilterSelection by rememberSaveable {\n            mutableStateOf(false)\n        }\n        AnimatedContent(\n            targetState = filter,\n            contentKey = { it != null }\n        ) { filter ->\n            Column(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                modifier = Modifier.padding(horizontal = 8.dp)\n            ) {\n                if (filter != null) {\n                    FilterItem(\n                        filter = filter,\n                        showDragHandle = false,\n                        onRemove = {\n                            onValueChange(\n                                DrawMode.PathEffect.Custom()\n                            )\n                        },\n                        onFilterChange = { value ->\n                            onValueChange(\n                                DrawMode.PathEffect.Custom(filter.copy(value))\n                            )\n                        },\n                        backgroundColor = MaterialTheme.colorScheme.surface,\n                        shape = ShapeDefaults.default,\n                        canHide = false,\n                        onCreateTemplate = null\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    EnhancedButton(\n                        containerColor = MaterialTheme.colorScheme.mixedContainer,\n                        onClick = {\n                            showFilterSelection = true\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.AutoFixNormal,\n                            contentDescription = stringResource(R.string.replace_filter)\n                        )\n                        Spacer(Modifier.width(8.dp))\n                        Text(stringResource(id = R.string.replace_filter))\n                    }\n                    Spacer(modifier = Modifier.height(8.dp))\n                } else {\n                    InfoContainer(\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerLow,\n                        text = stringResource(R.string.pick_filter_info)\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    AddFilterButton(\n                        onClick = {\n                            showFilterSelection = true\n                        }\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                }\n            }\n            AddFiltersSheet(\n                component = addFiltersSheetComponent,\n                filterTemplateCreationSheetComponent = filterTemplateCreationSheetComponent,\n                visible = showFilterSelection,\n                onVisibleChange = {\n                    showFilterSelection = it\n                },\n                canAddTemplates = false,\n                previewBitmap = null,\n                onFilterPicked = {\n                    onValueChange(\n                        DrawMode.PathEffect.Custom(it.newInstance())\n                    )\n                },\n                onFilterPickedWithParams = {\n                    onValueChange(\n                        DrawMode.PathEffect.Custom(it)\n                    )\n                }\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/DrawPathModeInfoSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.getIcon\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.getSubtitle\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.getTitle\n\n@Composable\ninternal fun DrawPathModeInfoSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    values: List<DrawPathMode>\n) {\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Column(\n                modifier = Modifier\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(8.dp),\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                values.forEachIndexed { index, item ->\n                    Column(\n                        Modifier\n                            .fillMaxWidth()\n                            .container(\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = values.size\n                                ),\n                                resultPadding = 0.dp\n                            )\n                    ) {\n                        TitleItem(text = stringResource(item.getTitle()), icon = item.getIcon())\n                        Text(\n                            text = stringResource(item.getSubtitle()),\n                            modifier = Modifier.padding(\n                                start = 16.dp,\n                                end = 16.dp,\n                                bottom = 16.dp\n                            ),\n                            fontSize = 14.sp,\n                            lineHeight = 18.sp\n                        )\n                    }\n                }\n            }\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(text = stringResource(R.string.draw_path_mode))\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/FloodFillParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isFloodFill\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.tolerance\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateFloodFill\n\n\n@Composable\ninternal fun FloodFillParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value.isFloodFill(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            EnhancedSliderItem(\n                value = value.tolerance(),\n                title = stringResource(R.string.tolerance),\n                valueRange = 0f..1f,\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateFloodFill(tolerance = it.roundToTwoDigits())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.default\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/ImageParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.coerceIn\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\n\n@Composable\ninternal fun ImageParamsSelector(\n    value: DrawMode,\n    onValueChange: (DrawMode) -> Unit,\n    strokeWidth: Pt\n) {\n    AnimatedVisibility(\n        visible = value is DrawMode.Image,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            ImageSelector(\n                modifier = Modifier\n                    .padding(horizontal = 8.dp),\n                value = (value as? DrawMode.Image)?.imageData ?: \"\",\n                onValueChange = {\n                    onValueChange(\n                        (value as? DrawMode.Image)?.copy(\n                            imageData = it\n                        ) ?: value\n                    )\n                },\n                subtitle = stringResource(id = R.string.draw_image_sub),\n                shape = ShapeDefaults.top,\n                color = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            val dashMinimum = -((strokeWidth.value * 0.9f) / 2).toInt().toFloat()\n            LaunchedEffect(dashMinimum, value) {\n                if (value is DrawMode.Image && value.repeatingInterval < dashMinimum.pt) {\n                    onValueChange(\n                        value.copy(\n                            repeatingInterval = value.repeatingInterval.coerceIn(\n                                dashMinimum.pt,\n                                100.pt\n                            )\n                        )\n                    )\n                }\n            }\n            EnhancedSliderItem(\n                value = (value as? DrawMode.Image)?.repeatingInterval?.value ?: 0f,\n                title = stringResource(R.string.dash_size),\n                valueRange = dashMinimum..100f,\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        (value as? DrawMode.Image)?.copy(\n                            repeatingInterval = it.pt.coerceIn(dashMinimum.pt, 100.pt)\n                        ) ?: value\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                valueSuffix = \" Pt\",\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.bottom\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/OutlinedFillColorSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FormatColorFill\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun OutlinedFillColorSelector(\n    value: Color?,\n    onValueChange: (Color?) -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = ShapeDefaults.default,\n    containerColor: Color = Color.Unspecified\n) {\n    ColorRowSelector(\n        value = value,\n        onValueChange = onValueChange,\n        onNullClick = { onValueChange(null) },\n        title = stringResource(R.string.fill_color),\n        icon = Icons.Outlined.FormatColorFill,\n        allowAlpha = true,\n        modifier = modifier\n            .fillMaxWidth()\n            .container(\n                color = containerColor,\n                shape = shape\n            )\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/OvalParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateOutlined\n\n@Composable\ninternal fun OvalParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit,\n    canChangeFillColor: Boolean\n) {\n    AnimatedVisibility(\n        visible = value is DrawPathMode.OutlinedOval && canChangeFillColor,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            OutlinedFillColorSelector(\n                value = value.outlinedFillColor?.toColor(),\n                onValueChange = {\n                    onValueChange(value.updateOutlined(it))\n                },\n                shape = ShapeDefaults.default,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                containerColor = MaterialTheme.colorScheme.surface,\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}\n"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/PixelationParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.PixelSizeSelector\n\n@Composable\ninternal fun PixelationParamsSelector(\n    value: DrawMode,\n    onValueChange: (DrawMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value is DrawMode.PathEffect.Pixelation,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        PixelSizeSelector(\n            modifier = Modifier.padding(8.dp),\n            value = (value as? DrawMode.PathEffect.Pixelation)?.pixelSize ?: 0f,\n            onValueChange = {\n                onValueChange(DrawMode.PathEffect.Pixelation(it))\n            },\n            color = MaterialTheme.colorScheme.surface\n        )\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/PolygonParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SquareFoot\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isPolygon\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isRegular\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.rotationDegrees\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateOutlined\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updatePolygon\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.vertices\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun PolygonParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit,\n    canChangeFillColor: Boolean\n) {\n    AnimatedVisibility(\n        visible = value.isPolygon(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            AnimatedVisibility(\n                visible = canChangeFillColor,\n                enter = fadeIn() + expandVertically(),\n                exit = fadeOut() + shrinkVertically()\n            ) {\n                OutlinedFillColorSelector(\n                    value = value.outlinedFillColor?.toColor(),\n                    onValueChange = {\n                        onValueChange(value.updateOutlined(it))\n                    },\n                    shape = ShapeDefaults.top,\n                    modifier = Modifier\n                        .padding(bottom = 4.dp)\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp),\n                    containerColor = MaterialTheme.colorScheme.surface,\n                )\n            }\n            EnhancedSliderItem(\n                value = value.vertices(),\n                title = stringResource(R.string.vertices),\n                valueRange = 3f..24f,\n                steps = 20,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updatePolygon(vertices = it.toInt())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = if (canChangeFillColor) ShapeDefaults.center else ShapeDefaults.top\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = value.rotationDegrees(),\n                title = stringResource(R.string.angle),\n                valueRange = 0f..360f,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updatePolygon(rotationDegrees = it.toInt())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.center\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            PreferenceRowSwitch(\n                title = stringResource(R.string.draw_regular_polygon),\n                subtitle = stringResource(R.string.draw_regular_polygon_sub),\n                checked = value.isRegular(),\n                onClick = {\n                    onValueChange(\n                        value.updatePolygon(isRegular = it)\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                shape = ShapeDefaults.bottom,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                startIcon = Icons.Rounded.SquareFoot,\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/PrivacyBlurParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group.components.BlurRadiusSelector\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\n\n@Composable\ninternal fun PrivacyBlurParamsSelector(\n    value: DrawMode,\n    onValueChange: (DrawMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value is DrawMode.PathEffect.PrivacyBlur,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        BlurRadiusSelector(\n            modifier = Modifier.padding(8.dp),\n            value = (value as? DrawMode.PathEffect.PrivacyBlur)?.blurRadius ?: 0,\n            valueRange = 5f..50f,\n            onValueChange = {\n                onValueChange(DrawMode.PathEffect.PrivacyBlur(it))\n            },\n            color = MaterialTheme.colorScheme.surface\n        )\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/RectParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.cornerRadius\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isRect\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.rotationDegrees\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateOutlined\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateRect\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun RectParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit,\n    canChangeFillColor: Boolean\n) {\n    AnimatedVisibility(\n        visible = value.isRect(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            AnimatedVisibility(\n                visible = canChangeFillColor,\n                enter = fadeIn() + expandVertically(),\n                exit = fadeOut() + shrinkVertically()\n            ) {\n                OutlinedFillColorSelector(\n                    value = value.outlinedFillColor?.toColor(),\n                    onValueChange = {\n                        onValueChange(value.updateOutlined(it))\n                    },\n                    shape = ShapeDefaults.top,\n                    modifier = Modifier\n                        .padding(bottom = 4.dp)\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp),\n                    containerColor = MaterialTheme.colorScheme.surface,\n                )\n            }\n            EnhancedSliderItem(\n                value = value.rotationDegrees(),\n                title = stringResource(R.string.angle),\n                valueRange = 0f..360f,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateRect(rotationDegrees = it.toInt())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = if (canChangeFillColor) ShapeDefaults.center else ShapeDefaults.top\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = value.cornerRadius(),\n                title = stringResource(R.string.radius),\n                valueRange = 0f..0.5f,\n                internalStateTransformation = { it.roundToTwoDigits() },\n                onValueChange = {\n                    onValueChange(\n                        value.updateRect(cornerRadius = it.roundToTwoDigits())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.bottom\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/SpotHealParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.retain.retain\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.saving.track\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.throttleLatest\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.SpotHealMode\nimport com.t8rin.imagetoolbox.core.filters.presentation.utils.LamaLoader\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalKeepAliveService\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCancellableCircularProgressIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.catch\nimport kotlinx.coroutines.flow.onCompletion\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.flow.onStart\nimport kotlinx.coroutines.launch\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun SpotHealParamsSelector(\n    value: DrawMode,\n    onValueChange: (DrawMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value is DrawMode.SpotHeal,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        val keepAliveService = LocalKeepAliveService.current\n        val settingsState = LocalSettingsState.current\n        val scope = retain { CoroutineScope(Dispatchers.IO) }\n        val simpleSettingsInteractor = LocalSimpleSettingsInteractor.current\n        var downloadJob by retain {\n            mutableStateOf<Job?>(null)\n        }\n        var downloadProgress by remember(LamaLoader.isDownloaded) {\n            mutableStateOf<DownloadProgress?>(null)\n        }\n        var useLama by remember(settingsState.spotHealMode) {\n            mutableStateOf(settingsState.spotHealMode == 1)\n        }\n        LaunchedEffect(LamaLoader.isDownloaded) {\n            if (!LamaLoader.isDownloaded) {\n                useLama = false\n                simpleSettingsInteractor.setSpotHealMode(0)\n            }\n        }\n\n        LaunchedEffect(useLama) {\n            onValueChange(\n                DrawMode.SpotHeal(\n                    if (useLama) SpotHealMode.LaMa else SpotHealMode.OpenCV\n                )\n            )\n        }\n\n        PreferenceRowSwitch(\n            title = stringResource(R.string.generative_inpaint),\n            subtitle = stringResource(\n                if (LamaLoader.isDownloaded) R.string.generative_inpaint_ready_sub\n                else R.string.generative_inpaint_sub\n            ),\n            checked = useLama,\n            onClick = { new ->\n                if (downloadJob == null) {\n                    useLama = new\n\n                    scope.launch { simpleSettingsInteractor.setSpotHealMode(if (useLama) 1 else 0) }\n\n                    if (useLama && !LamaLoader.isDownloaded) {\n                        downloadJob?.cancel()\n                        downloadJob = scope.launch {\n                            keepAliveService.track(\n                                initial = {\n                                    updateOrStart(\n                                        title = getString(R.string.downloading)\n                                    )\n                                }\n                            ) {\n                                LamaLoader.download()\n                                    .onStart {\n                                        downloadProgress = DownloadProgress(\n                                            currentPercent = 0f,\n                                            currentTotalSize = 0\n                                        )\n                                    }\n                                    .onCompletion {\n                                        downloadProgress = null\n                                        downloadJob = null\n                                    }\n                                    .catch {\n                                        simpleSettingsInteractor.setSpotHealMode(0)\n                                        AppToastHost.showFailureToast(it)\n                                        useLama = false\n                                        downloadProgress = null\n                                        downloadJob = null\n                                    }\n                                    .onEach {\n                                        downloadProgress = it\n                                    }\n                                    .throttleLatest(50)\n                                    .collect {\n                                        updateProgress(\n                                            title = getString(R.string.downloading),\n                                            done = (it.currentPercent * 100).roundToInt(),\n                                            total = 100\n                                        )\n                                    }\n                            }\n                        }\n                    }\n                }\n            },\n            contentInsteadOfSwitch = downloadProgress?.let { progress ->\n                {\n                    EnhancedCancellableCircularProgressIndicator(\n                        progress = { progress.currentPercent },\n                        modifier = Modifier.size(24.dp),\n                        trackColor = MaterialTheme.colorScheme.primary.copy(0.2f),\n                        strokeWidth = 3.dp,\n                        onCancel = {\n                            downloadJob?.cancel()\n                            downloadProgress = null\n                            downloadJob = null\n                            useLama = false\n                            scope.launch {\n                                simpleSettingsInteractor.setSpotHealMode(0)\n                            }\n                        }\n                    )\n                }\n            },\n            containerColor = MaterialTheme.colorScheme.surface,\n            shape = ShapeDefaults.default,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(8.dp),\n            resultModifier = Modifier.padding(16.dp),\n            applyHorizontalPadding = false\n        )\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/SprayParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CropSquare\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.density\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isSpray\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isSquareShaped\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.pixelSize\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateSpray\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun SprayParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value.isSpray(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            EnhancedSliderItem(\n                value = value.density(),\n                title = stringResource(R.string.density),\n                valueRange = 1f..500f,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateSpray(density = it.roundToInt())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.top\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = value.pixelSize(),\n                title = stringResource(R.string.pixel_size),\n                valueRange = 0.5f..20f,\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateSpray(pixelSize = it.roundToTwoDigits())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.center\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            PreferenceRowSwitch(\n                title = stringResource(R.string.square_particles),\n                subtitle = stringResource(R.string.square_particles_sub),\n                checked = value.isSquareShaped(),\n                onClick = {\n                    onValueChange(\n                        value.updateSpray(isSquareShaped = it)\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                shape = ShapeDefaults.bottom,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                resultModifier = Modifier.padding(16.dp),\n                startIcon = Icons.Rounded.CropSquare\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/StarParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SquareFoot\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.innerRadiusRatio\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isRegular\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.isStar\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.rotationDegrees\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateOutlined\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateStar\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.vertices\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun StarParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit,\n    canChangeFillColor: Boolean\n) {\n    AnimatedVisibility(\n        visible = value.isStar(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            AnimatedVisibility(\n                visible = canChangeFillColor,\n                enter = fadeIn() + expandVertically(),\n                exit = fadeOut() + shrinkVertically()\n            ) {\n                OutlinedFillColorSelector(\n                    value = value.outlinedFillColor?.toColor(),\n                    onValueChange = {\n                        onValueChange(value.updateOutlined(it))\n                    },\n                    shape = ShapeDefaults.top,\n                    modifier = Modifier\n                        .padding(bottom = 4.dp)\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp),\n                    containerColor = MaterialTheme.colorScheme.surface,\n                )\n            }\n            EnhancedSliderItem(\n                value = value.vertices(),\n                title = stringResource(R.string.vertices),\n                valueRange = 3f..24f,\n                steps = 20,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateStar(vertices = it.toInt())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = if (canChangeFillColor) ShapeDefaults.center else ShapeDefaults.top\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = value.rotationDegrees(),\n                title = stringResource(R.string.angle),\n                valueRange = 0f..360f,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateStar(rotationDegrees = it.toInt())\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.center\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = value.innerRadiusRatio(),\n                title = stringResource(R.string.inner_radius_ratio),\n                valueRange = 0f..1f,\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.updateStar(innerRadiusRatio = it)\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.center\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            PreferenceRowSwitch(\n                title = stringResource(R.string.draw_regular_star),\n                subtitle = stringResource(R.string.draw_regular_star_sub),\n                checked = value.isRegular(),\n                onClick = {\n                    onValueChange(\n                        value.updateStar(isRegular = it)\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                shape = ShapeDefaults.bottom,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                startIcon = Icons.Rounded.SquareFoot,\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/TextParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiFont\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FontSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\n\n@Composable\ninternal fun TextParamsSelector(\n    value: DrawMode,\n    onValueChange: (DrawMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value is DrawMode.Text,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            RoundedTextField(\n                modifier = Modifier\n                    .padding(horizontal = 8.dp)\n                    .container(\n                        shape = ShapeDefaults.top,\n                        color = MaterialTheme.colorScheme.surface,\n                        resultPadding = 8.dp\n                    ),\n                value = (value as? DrawMode.Text)?.text ?: \"\",\n                singleLine = false,\n                onValueChange = {\n                    onValueChange(\n                        (value as? DrawMode.Text)?.copy(\n                            text = it\n                        ) ?: value\n                    )\n                },\n                label = {\n                    Text(stringResource(R.string.text))\n                }\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            FontSelector(\n                value = (value as? DrawMode.Text)?.font.toUiFont(),\n                onValueChange = {\n                    onValueChange(\n                        (value as? DrawMode.Text)?.copy(\n                            font = it.type\n                        ) ?: value\n                    )\n                },\n                modifier = Modifier\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.center\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            val isDashSizeControlVisible = (value as? DrawMode.Text)?.isRepeated == true\n            PreferenceRowSwitch(\n                title = stringResource(R.string.repeat_text),\n                subtitle = stringResource(R.string.repeat_text_sub),\n                checked = (value as? DrawMode.Text)?.isRepeated == true,\n                onClick = {\n                    onValueChange(\n                        (value as? DrawMode.Text)?.copy(\n                            isRepeated = it\n                        ) ?: value\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                shape = animateShape(\n                    if (isDashSizeControlVisible) ShapeDefaults.center\n                    else ShapeDefaults.bottom\n                ),\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                resultModifier = Modifier.padding(16.dp),\n                applyHorizontalPadding = false\n            )\n            Spacer(\n                modifier = Modifier.height(\n                    if (isDashSizeControlVisible) 4.dp else 8.dp\n                )\n            )\n            AnimatedVisibility(\n                visible = isDashSizeControlVisible,\n                enter = fadeIn() + expandVertically(),\n                exit = fadeOut() + shrinkVertically()\n            ) {\n                EnhancedSliderItem(\n                    value = (value as? DrawMode.Text)?.repeatingInterval?.value ?: 0f,\n                    title = stringResource(R.string.dash_size),\n                    valueRange = 0f..100f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        onValueChange(\n                            (value as? DrawMode.Text)?.copy(\n                                repeatingInterval = it.pt\n                            ) ?: value\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    valueSuffix = \" Pt\",\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 8.dp)\n                        .padding(bottom = 8.dp),\n                    shape = ShapeDefaults.bottom\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/TriangleParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.updateOutlined\n\n@Composable\ninternal fun TriangleParamsSelector(\n    value: DrawPathMode,\n    onValueChange: (DrawPathMode) -> Unit,\n    canChangeFillColor: Boolean\n) {\n    AnimatedVisibility(\n        visible = value is DrawPathMode.OutlinedTriangle && canChangeFillColor,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            OutlinedFillColorSelector(\n                value = value.outlinedFillColor?.toColor(),\n                onValueChange = {\n                    onValueChange(value.updateOutlined(it))\n                },\n                shape = ShapeDefaults.default,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                containerColor = MaterialTheme.colorScheme.surface,\n            )\n            Spacer(Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/element/WarpParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.element\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.WarpMode\n\n@Composable\ninternal fun WarpParamsSelector(\n    value: DrawMode,\n    onValueChange: (DrawMode) -> Unit\n) {\n    AnimatedVisibility(\n        visible = value is DrawMode.Warp,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            EnhancedSliderItem(\n                value = value.safeCast<DrawMode.Warp>()?.strength ?: 0f,\n                title = stringResource(R.string.strength),\n                valueRange = 0f..1f,\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.safeCast<DrawMode.Warp>()?.copy(\n                            strength = it.roundToTwoDigits()\n                        ) ?: value\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.top\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = value.safeCast<DrawMode.Warp>()?.hardness ?: 0f,\n                title = stringResource(R.string.hardness),\n                valueRange = 0f..1f,\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        value.safeCast<DrawMode.Warp>()?.copy(\n                            hardness = it.roundToTwoDigits()\n                        ) ?: value\n                    )\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp),\n                shape = ShapeDefaults.center\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedButtonGroup(\n                enabled = true,\n                modifier = Modifier\n                    .padding(horizontal = 8.dp)\n                    .container(\n                        shape = ShapeDefaults.bottom,\n                        color = MaterialTheme.colorScheme.surface\n                    ),\n                itemCount = WarpMode.entries.size,\n                title = {\n                    Text(\n                        text = stringResource(R.string.warp_mode),\n                        textAlign = TextAlign.Center,\n                        fontWeight = FontWeight.Medium,\n                        modifier = Modifier.padding(top = 4.dp)\n                    )\n                },\n                selectedIndex = WarpMode.entries.indexOfFirst {\n                    value.safeCast<DrawMode.Warp>()?.warpMode == it\n                },\n                itemContent = {\n                    Text(\n                        text = stringResource(WarpMode.entries[it].title())\n                    )\n                },\n                onIndexChange = {\n                    onValueChange(\n                        value.safeCast<DrawMode.Warp>()?.copy(\n                            warpMode = WarpMode.entries[it]\n                        ) ?: value\n                    )\n                },\n                inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}\n\nprivate fun WarpMode.title(): Int = when (this) {\n    WarpMode.MOVE -> R.string.warp_mode_move\n    WarpMode.GROW -> R.string.warp_mode_grow\n    WarpMode.SHRINK -> R.string.warp_mode_shrink\n    WarpMode.SWIRL_CW -> R.string.warp_mode_swirl_cw\n    WarpMode.SWIRL_CCW -> R.string.warp_mode_swirl_ccw\n    WarpMode.MIXING -> R.string.mix\n}\n\n@Composable\n@Preview\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    Surface(\n        color = MaterialTheme.colorScheme.surfaceContainer\n    ) {\n        WarpParamsSelector(\n            value = DrawMode.Warp(),\n            onValueChange = {}\n        )\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/BitmapDrawerPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.MutableIntState\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHelperGrid\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\nfun BoxScope.BitmapDrawerPreview(\n    preview: ImageBitmap,\n    globalTouchPointersCount: MutableIntState,\n    onReceiveMotionEvent: (MotionEvent) -> Unit,\n    onInvalidate: () -> Unit,\n    onUpdateCurrentDrawPosition: (Offset) -> Unit,\n    onUpdateDrawDownPosition: (Offset) -> Unit,\n    drawEnabled: Boolean,\n    helperGridParams: HelperGridParams,\n    beforeHelperGridModifier: Modifier = Modifier,\n) {\n    Picture(\n        model = preview,\n        modifier = Modifier\n            .matchParentSize()\n            .pointerDrawHandler(\n                globalTouchPointersCount = globalTouchPointersCount,\n                onReceiveMotionEvent = onReceiveMotionEvent,\n                onInvalidate = onInvalidate,\n                onUpdateCurrentDrawPosition = onUpdateCurrentDrawPosition,\n                onUpdateDrawDownPosition = onUpdateDrawDownPosition,\n                enabled = drawEnabled\n            )\n            .clip(ShapeDefaults.extremeSmall)\n            .transparencyChecker()\n            .then(beforeHelperGridModifier)\n            .drawHelperGrid(helperGridParams)\n            .border(\n                width = 1.dp,\n                color = MaterialTheme.colorScheme.outlineVariant(),\n                shape = ShapeDefaults.extremeSmall\n            ),\n        contentDescription = null,\n        contentScale = ContentScale.FillBounds\n    )\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/DrawPathEffectPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.PorterDuff\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.createScaledBitmap\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport android.graphics.Path as NativePath\n\n@Composable\ninternal fun DrawPathEffectPreview(\n    drawPathCanvas: Canvas,\n    drawMode: DrawMode.PathEffect,\n    canvasSize: IntegerSize,\n    imageWidth: Int,\n    imageHeight: Int,\n    outputImage: ImageBitmap,\n    onRequestFiltering: suspend (Bitmap, List<Filter<*>>) -> Bitmap?,\n    paths: List<UiPathPaint>,\n    drawPath: Path,\n    backgroundColor: Color,\n    strokeWidth: Pt,\n    drawPathMode: DrawPathMode\n) {\n    var shaderBitmap by remember {\n        mutableStateOf<ImageBitmap?>(null)\n    }\n\n    LaunchedEffect(outputImage, paths, backgroundColor, drawMode) {\n        shaderBitmap = onRequestFiltering(\n            outputImage.asAndroidBitmap(),\n            transformationsForMode(\n                drawMode = drawMode,\n                canvasSize = canvasSize\n            )\n        )?.createScaledBitmap(\n            width = imageWidth,\n            height = imageHeight\n        )?.asImageBitmap()\n    }\n\n    shaderBitmap?.let {\n        with(drawPathCanvas) {\n            with(nativeCanvas) {\n                drawColor(Color.Transparent.toArgb(), PorterDuff.Mode.CLEAR)\n\n                val paint by rememberPathEffectPaint(\n                    strokeWidth = strokeWidth,\n                    drawPathMode = drawPathMode,\n                    canvasSize = canvasSize\n                )\n                val newPath = drawPath.copyAsAndroidPath().apply {\n                    fillType = NativePath.FillType.INVERSE_WINDING\n                }\n                val imagePaint = remember { Paint() }\n\n                drawImage(\n                    image = it,\n                    topLeftOffset = Offset.Zero,\n                    paint = imagePaint\n                )\n                drawPath(newPath, paint)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/DrawPathModeUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CheckBoxOutlineBlank\nimport androidx.compose.material.icons.rounded.Circle\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material.icons.rounded.Star\nimport androidx.compose.material.icons.rounded.StarOutline\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toColor\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FloodFill\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeDoubleArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeDraw\nimport com.t8rin.imagetoolbox.core.resources.icons.Lasso\nimport com.t8rin.imagetoolbox.core.resources.icons.Line\nimport com.t8rin.imagetoolbox.core.resources.icons.LineArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.LineDoubleArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.Polygon\nimport com.t8rin.imagetoolbox.core.resources.icons.Spray\nimport com.t8rin.imagetoolbox.core.resources.icons.Square\nimport com.t8rin.imagetoolbox.core.resources.icons.Triangle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\n\ninternal fun DrawPathMode.saveState(\n    value: DrawPathMode\n): DrawPathMode = when (value) {\n    is DrawPathMode.Rect if this is DrawPathMode.OutlinedRect -> {\n        copy(\n            rotationDegrees = value.rotationDegrees,\n            cornerRadius = value.cornerRadius\n        )\n    }\n\n    is DrawPathMode.OutlinedRect if this is DrawPathMode.Rect -> {\n        copy(\n            rotationDegrees = value.rotationDegrees,\n            cornerRadius = value.cornerRadius\n        )\n    }\n\n    is DrawPathMode.Polygon if this is DrawPathMode.OutlinedPolygon -> {\n        copy(\n            vertices = value.vertices,\n            rotationDegrees = value.rotationDegrees,\n            isRegular = value.isRegular\n        )\n    }\n\n    is DrawPathMode.OutlinedPolygon if this is DrawPathMode.Polygon -> {\n        copy(\n            vertices = value.vertices,\n            rotationDegrees = value.rotationDegrees,\n            isRegular = value.isRegular\n        )\n    }\n\n    is DrawPathMode.Star if this is DrawPathMode.OutlinedStar -> {\n        copy(\n            vertices = value.vertices,\n            innerRadiusRatio = innerRadiusRatio,\n            rotationDegrees = value.rotationDegrees,\n            isRegular = value.isRegular\n        )\n    }\n\n    is DrawPathMode.OutlinedStar if this is DrawPathMode.Star -> {\n        copy(\n            vertices = value.vertices,\n            innerRadiusRatio = innerRadiusRatio,\n            rotationDegrees = value.rotationDegrees,\n            isRegular = value.isRegular\n        )\n    }\n\n    is DrawPathMode.PointingArrow if this is DrawPathMode.LinePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.LinePointingArrow if this is DrawPathMode.PointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.PointingArrow if this is DrawPathMode.DoublePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.DoublePointingArrow if this is DrawPathMode.PointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.PointingArrow if this is DrawPathMode.DoubleLinePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.DoubleLinePointingArrow if this is DrawPathMode.PointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.LinePointingArrow if this is DrawPathMode.DoublePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.DoublePointingArrow if this is DrawPathMode.LinePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.LinePointingArrow if this is DrawPathMode.DoubleLinePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.DoubleLinePointingArrow if this is DrawPathMode.LinePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.DoublePointingArrow if this is DrawPathMode.DoubleLinePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.DoubleLinePointingArrow if this is DrawPathMode.DoublePointingArrow -> {\n        copy(\n            sizeScale = value.sizeScale,\n            angle = value.angle\n        )\n    }\n\n    is DrawPathMode.FloodFill if this is DrawPathMode.FloodFill -> {\n        copy(\n            tolerance = value.tolerance\n        )\n    }\n\n    is DrawPathMode.Spray if this is DrawPathMode.Spray -> {\n        copy(\n            density = value.density,\n            pixelSize = value.pixelSize,\n            isSquareShaped = value.isSquareShaped\n        )\n    }\n\n    else -> this\n}.run {\n    if (value is DrawPathMode.Outlined && this is DrawPathMode.Outlined) {\n        updateOutlined(\n            fillColor = value.fillColor?.toColor()\n        )\n    } else this\n}\n\ninternal fun DrawPathMode.density(): Int = when (this) {\n    is DrawPathMode.Spray -> density\n    else -> 0\n}\n\ninternal fun DrawPathMode.pixelSize(): Float = when (this) {\n    is DrawPathMode.Spray -> pixelSize\n    else -> 0f\n}\n\ninternal fun DrawPathMode.isSquareShaped(): Boolean = when (this) {\n    is DrawPathMode.Spray -> isSquareShaped\n    else -> false\n}\n\ninternal fun DrawPathMode.tolerance(): Float = when (this) {\n    is DrawPathMode.FloodFill -> tolerance\n    else -> 0f\n}\n\ninternal fun DrawPathMode.sizeScale(): Float = when (this) {\n    is DrawPathMode.PointingArrow -> sizeScale\n    is DrawPathMode.LinePointingArrow -> sizeScale\n    is DrawPathMode.DoublePointingArrow -> sizeScale\n    is DrawPathMode.DoubleLinePointingArrow -> sizeScale\n    else -> 1f\n}\n\ninternal fun DrawPathMode.angle(): Float = when (this) {\n    is DrawPathMode.PointingArrow -> angle\n    is DrawPathMode.LinePointingArrow -> angle\n    is DrawPathMode.DoublePointingArrow -> angle\n    is DrawPathMode.DoubleLinePointingArrow -> angle\n    else -> 0f\n}\n\ninternal fun DrawPathMode.vertices(): Int = when (this) {\n    is DrawPathMode.Polygon -> vertices\n    is DrawPathMode.OutlinedPolygon -> vertices\n    is DrawPathMode.Star -> vertices\n    is DrawPathMode.OutlinedStar -> vertices\n    else -> 0\n}\n\ninternal fun DrawPathMode.rotationDegrees(): Int = when (this) {\n    is DrawPathMode.Polygon -> rotationDegrees\n    is DrawPathMode.OutlinedPolygon -> rotationDegrees\n    is DrawPathMode.Star -> rotationDegrees\n    is DrawPathMode.OutlinedStar -> rotationDegrees\n    is DrawPathMode.Rect -> rotationDegrees\n    is DrawPathMode.OutlinedRect -> rotationDegrees\n    else -> 0\n}\n\ninternal fun DrawPathMode.cornerRadius(): Float = when (this) {\n    is DrawPathMode.Rect -> cornerRadius\n    is DrawPathMode.OutlinedRect -> cornerRadius\n    else -> 0f\n}\n\ninternal fun DrawPathMode.isRegular(): Boolean = when (this) {\n    is DrawPathMode.Polygon -> isRegular\n    is DrawPathMode.OutlinedPolygon -> isRegular\n    is DrawPathMode.Star -> isRegular\n    is DrawPathMode.OutlinedStar -> isRegular\n    else -> false\n}\n\ninternal fun DrawPathMode.innerRadiusRatio(): Float = when (this) {\n    is DrawPathMode.Star -> innerRadiusRatio\n    is DrawPathMode.OutlinedStar -> innerRadiusRatio\n    else -> 0.5f\n}\n\ninternal fun DrawPathMode.updateOutlined(\n    fillColor: Color?\n) = when (this) {\n    is DrawPathMode.Outlined -> {\n        when (this) {\n            is DrawPathMode.OutlinedOval -> copy(\n                fillColor = fillColor?.toModel()\n            )\n\n            is DrawPathMode.OutlinedPolygon -> copy(\n                fillColor = fillColor?.toModel()\n            )\n\n            is DrawPathMode.OutlinedRect -> copy(\n                fillColor = fillColor?.toModel()\n            )\n\n            is DrawPathMode.OutlinedStar -> copy(\n                fillColor = fillColor?.toModel()\n            )\n\n            is DrawPathMode.OutlinedTriangle -> copy(\n                fillColor = fillColor?.toModel()\n            )\n        }\n    }\n\n    else -> this\n}\n\ninternal fun DrawPathMode.updatePolygon(\n    vertices: Int? = null,\n    rotationDegrees: Int? = null,\n    isRegular: Boolean? = null\n) = when (this) {\n    is DrawPathMode.Polygon -> {\n        copy(\n            vertices = vertices ?: this.vertices,\n            rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n            isRegular = isRegular ?: this.isRegular\n        )\n    }\n\n    is DrawPathMode.OutlinedPolygon -> {\n        copy(\n            vertices = vertices ?: this.vertices,\n            rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n            isRegular = isRegular ?: this.isRegular\n        )\n    }\n\n    else -> this\n}\n\ninternal fun DrawPathMode.updateStar(\n    vertices: Int? = null,\n    innerRadiusRatio: Float? = null,\n    rotationDegrees: Int? = null,\n    isRegular: Boolean? = null\n) = when (this) {\n    is DrawPathMode.Star -> {\n        copy(\n            vertices = vertices ?: this.vertices,\n            innerRadiusRatio = innerRadiusRatio ?: this.innerRadiusRatio,\n            rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n            isRegular = isRegular ?: this.isRegular\n        )\n    }\n\n    is DrawPathMode.OutlinedStar -> {\n        copy(\n            vertices = vertices ?: this.vertices,\n            innerRadiusRatio = innerRadiusRatio ?: this.innerRadiusRatio,\n            rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n            isRegular = isRegular ?: this.isRegular\n        )\n    }\n\n    else -> this\n}\n\ninternal fun DrawPathMode.updateRect(\n    rotationDegrees: Int? = null,\n    cornerRadius: Float? = null\n) = when (this) {\n    is DrawPathMode.Rect -> {\n        copy(\n            rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n            cornerRadius = cornerRadius ?: this.cornerRadius\n        )\n    }\n\n    is DrawPathMode.OutlinedRect -> {\n        copy(\n            rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n            cornerRadius = cornerRadius ?: this.cornerRadius\n        )\n    }\n\n    else -> this\n}\n\ninternal fun DrawPathMode.updateArrow(\n    sizeScale: Float? = null,\n    angle: Float? = null\n) = when (this) {\n    is DrawPathMode.PointingArrow -> {\n        copy(\n            sizeScale = sizeScale ?: this.sizeScale,\n            angle = angle ?: this.angle\n        )\n    }\n\n    is DrawPathMode.LinePointingArrow -> {\n        copy(\n            sizeScale = sizeScale ?: this.sizeScale,\n            angle = angle ?: this.angle\n        )\n    }\n\n    is DrawPathMode.DoublePointingArrow -> {\n        copy(\n            sizeScale = sizeScale ?: this.sizeScale,\n            angle = angle ?: this.angle\n        )\n    }\n\n    is DrawPathMode.DoubleLinePointingArrow -> {\n        copy(\n            sizeScale = sizeScale ?: this.sizeScale,\n            angle = angle ?: this.angle\n        )\n    }\n\n    else -> this\n}\n\ninternal fun DrawPathMode.updateFloodFill(\n    tolerance: Float? = null,\n) = when (this) {\n    is DrawPathMode.FloodFill -> {\n        copy(\n            tolerance = tolerance ?: this.tolerance\n        )\n    }\n\n    else -> this\n}\n\ninternal fun DrawPathMode.updateSpray(\n    density: Int? = null,\n    pixelSize: Float? = null,\n    isSquareShaped: Boolean? = null,\n) = when (this) {\n    is DrawPathMode.Spray -> {\n        copy(\n            density = density ?: this.density,\n            pixelSize = pixelSize ?: this.pixelSize,\n            isSquareShaped = isSquareShaped ?: this.isSquareShaped\n        )\n    }\n\n    else -> this\n}\n\ninternal fun DrawPathMode.isArrow(): Boolean =\n    this is DrawPathMode.PointingArrow || this is DrawPathMode.LinePointingArrow\n            || this is DrawPathMode.DoublePointingArrow || this is DrawPathMode.DoubleLinePointingArrow\n\ninternal fun DrawPathMode.isRect(): Boolean =\n    this is DrawPathMode.Rect || this is DrawPathMode.OutlinedRect\n\ninternal fun DrawPathMode.isPolygon(): Boolean =\n    this is DrawPathMode.Polygon || this is DrawPathMode.OutlinedPolygon\n\ninternal fun DrawPathMode.isStar(): Boolean =\n    this is DrawPathMode.Star || this is DrawPathMode.OutlinedStar\n\ninternal fun DrawPathMode.isFloodFill(): Boolean =\n    this is DrawPathMode.FloodFill\n\ninternal fun DrawPathMode.isSpray(): Boolean =\n    this is DrawPathMode.Spray\n\ninternal fun DrawPathMode.getSubtitle(): Int = when (this) {\n    is DrawPathMode.DoubleLinePointingArrow -> R.string.double_line_arrow_sub\n    is DrawPathMode.DoublePointingArrow -> R.string.double_arrow_sub\n    DrawPathMode.Free -> R.string.free_drawing_sub\n    DrawPathMode.Line -> R.string.line_sub\n    is DrawPathMode.LinePointingArrow -> R.string.line_arrow_sub\n    is DrawPathMode.PointingArrow -> R.string.arrow_sub\n    is DrawPathMode.OutlinedOval -> R.string.outlined_oval_sub\n    is DrawPathMode.OutlinedRect -> R.string.outlined_rect_sub\n    DrawPathMode.Oval -> R.string.oval_sub\n    is DrawPathMode.Rect -> R.string.rect_sub\n    DrawPathMode.Lasso -> R.string.lasso_sub\n    is DrawPathMode.OutlinedTriangle -> R.string.outlined_triangle_sub\n    DrawPathMode.Triangle -> R.string.triangle_sub\n    is DrawPathMode.Polygon -> R.string.polygon_sub\n    is DrawPathMode.OutlinedPolygon -> R.string.outlined_polygon_sub\n    is DrawPathMode.OutlinedStar -> R.string.outlined_star_sub\n    is DrawPathMode.Star -> R.string.star_sub\n    is DrawPathMode.FloodFill -> R.string.flood_fill_sub\n    is DrawPathMode.Spray -> R.string.spray_sub\n}\n\ninternal fun DrawPathMode.getTitle(): Int = when (this) {\n    is DrawPathMode.DoubleLinePointingArrow -> R.string.double_line_arrow\n    is DrawPathMode.DoublePointingArrow -> R.string.double_arrow\n    DrawPathMode.Free -> R.string.free_drawing\n    DrawPathMode.Line -> R.string.line\n    is DrawPathMode.LinePointingArrow -> R.string.line_arrow\n    is DrawPathMode.PointingArrow -> R.string.arrow\n    is DrawPathMode.OutlinedOval -> R.string.outlined_oval\n    is DrawPathMode.OutlinedRect -> R.string.outlined_rect\n    DrawPathMode.Oval -> R.string.oval\n    is DrawPathMode.Rect -> R.string.rect\n    DrawPathMode.Lasso -> R.string.lasso\n    is DrawPathMode.OutlinedTriangle -> R.string.outlined_triangle\n    DrawPathMode.Triangle -> R.string.triangle\n    is DrawPathMode.Polygon -> R.string.polygon\n    is DrawPathMode.OutlinedPolygon -> R.string.outlined_polygon\n    is DrawPathMode.OutlinedStar -> R.string.outlined_star\n    is DrawPathMode.Star -> R.string.star\n    is DrawPathMode.FloodFill -> R.string.flood_fill\n    is DrawPathMode.Spray -> R.string.spray\n}\n\ninternal fun DrawPathMode.getIcon(): ImageVector = when (this) {\n    is DrawPathMode.DoubleLinePointingArrow -> Icons.Rounded.LineDoubleArrow\n    is DrawPathMode.DoublePointingArrow -> Icons.Rounded.FreeDoubleArrow\n    DrawPathMode.Free -> Icons.Rounded.FreeDraw\n    DrawPathMode.Line -> Icons.Rounded.Line\n    is DrawPathMode.LinePointingArrow -> Icons.Rounded.LineArrow\n    is DrawPathMode.PointingArrow -> Icons.Rounded.FreeArrow\n    is DrawPathMode.OutlinedOval -> Icons.Rounded.RadioButtonUnchecked\n    is DrawPathMode.OutlinedRect -> Icons.Rounded.CheckBoxOutlineBlank\n    DrawPathMode.Oval -> Icons.Rounded.Circle\n    is DrawPathMode.Rect -> Icons.Rounded.Square\n    DrawPathMode.Lasso -> Icons.Rounded.Lasso\n    DrawPathMode.Triangle -> Icons.Rounded.Triangle\n    is DrawPathMode.OutlinedTriangle -> Icons.Outlined.Triangle\n    is DrawPathMode.Polygon -> Icons.Rounded.Polygon\n    is DrawPathMode.OutlinedPolygon -> Icons.Outlined.Polygon\n    is DrawPathMode.OutlinedStar -> Icons.Rounded.StarOutline\n    is DrawPathMode.Star -> Icons.Rounded.Star\n    is DrawPathMode.FloodFill -> Icons.Rounded.FloodFill\n    is DrawPathMode.Spray -> Icons.Outlined.Spray\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/DrawRepeatedPath.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Matrix\nimport android.graphics.Paint\nimport android.graphics.Path\nimport android.graphics.PathMeasure\nimport androidx.core.graphics.withSave\nimport kotlin.math.atan2\n\nfun Canvas.drawRepeatedTextOnPath(\n    text: String,\n    path: Path,\n    paint: Paint,\n    interval: Float = 0f\n) {\n    val pathMeasure = PathMeasure(path, false)\n    val pathLength = pathMeasure.length\n\n    val textWidth = paint.measureText(text)\n\n    val fullRepeats = (pathLength / (textWidth + interval)).toInt()\n\n    val remainingLength = pathLength - fullRepeats * (textWidth + interval)\n\n    var distance = 0f\n\n    repeat(fullRepeats) {\n        drawTextOnPath(text, path, distance, 0f, paint)\n        distance += (textWidth + interval)\n    }\n\n    if (remainingLength > 0f) {\n        val ratio = (textWidth + interval - (remainingLength)) / (textWidth + interval)\n        val endOffset = (text.length - (text.length * ratio).toInt()).coerceAtLeast(0)\n        drawTextOnPath(text.substring(0, endOffset), path, distance, 0f, paint)\n    }\n}\n\nfun Canvas.drawRepeatedBitmapOnPath(\n    bitmap: Bitmap,\n    path: Path,\n    paint: Paint,\n    interval: Float = 0f\n) {\n    val pathMeasure = PathMeasure(path, false)\n    val pathLength = pathMeasure.length\n\n    val bitmapWidth = bitmap.width.toFloat()\n    val bitmapHeight = bitmap.height.toFloat()\n\n    var distance = 0f\n    val matrix = Matrix()\n\n    while (distance < pathLength) {\n        val pos = FloatArray(2)\n        val tan = FloatArray(2)\n        pathMeasure.getPosTan(distance, pos, tan)\n\n        val degree = Math.toDegrees(atan2(tan[1].toDouble(), tan[0].toDouble())).toFloat()\n\n        withSave {\n            translate(pos[0], pos[1])\n            rotate(degree)\n\n            matrix.reset()\n            matrix.postTranslate(-bitmapWidth / 2, -bitmapHeight / 2)\n            matrix.postRotate(degree)\n            matrix.postTranslate(bitmapWidth / 2, bitmapHeight / 2)\n            drawBitmap(bitmap, matrix, paint)\n        }\n\n        if (interval < 0 && distance + bitmapWidth < 0) break\n        else {\n            distance += (bitmapWidth + interval)\n        }\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/DrawUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.BlurMaskFilter\nimport android.graphics.Canvas\nimport android.graphics.Matrix\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.PaintingStyle\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.StampedPathEffectStyle\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.addOutline\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.max\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiNativeStackBlurFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiPixelationFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.density\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.Line\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.toTypeface\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport kotlin.math.roundToInt\nimport kotlin.math.sqrt\nimport android.graphics.Canvas as NativeCanvas\nimport android.graphics.Paint as NativePaint\nimport android.graphics.Path as NativePath\n\n/**\n *  Needed to trigger recomposition\n **/\nfun ImageBitmap.copy(): ImageBitmap = asAndroidBitmap().asImageBitmap()\n\ninternal fun Path.copy(): Path = copyAsAndroidPath().asComposePath()\n\ninternal fun Path.copyAsAndroidPath(): NativePath = NativePath(this.asAndroidPath())\n\ninternal fun NativePath.mirror(\n    x: Float,\n    y: Float,\n    x1: Float,\n    y1: Float\n): NativePath {\n    val dx = x1 - x\n    val dy = y1 - y\n    val lengthSq = dx * dx + dy * dy\n\n    val matrix = Matrix().apply {\n        setValues(\n            floatArrayOf(\n                (dx * dx - dy * dy) / lengthSq,\n                (2 * dx * dy) / lengthSq,\n                (2 * x * dy * dy - 2 * y * dx * dy) / lengthSq,\n                (2 * dx * dy) / lengthSq,\n                (dy * dy - dx * dx) / lengthSq,\n                (2 * y * dx * dx - 2 * x * dx * dy) / lengthSq,\n                0f,\n                0f,\n                1f\n            )\n        )\n    }\n\n    val mirroredPath = NativePath()\n    this.transform(matrix, mirroredPath)\n    return mirroredPath\n}\n\n@Suppress(\"unused\")\ninternal fun Path.mirrorIfNeeded(\n    canvasSize: IntegerSize,\n    mirroringLines: List<Line>\n): Path = asAndroidPath().mirrorIfNeeded(\n    canvasSize = canvasSize,\n    mirroringLines = mirroringLines\n).asComposePath()\n\ninternal fun NativePath.mirrorIfNeeded(\n    canvasSize: IntegerSize,\n    mirroringLines: List<Line>\n): NativePath = if (mirroringLines.isNotEmpty()) {\n    NativePath(this).apply {\n        mirroringLines.forEach { mirroringLine ->\n            addPath(\n                mirror(\n                    x = mirroringLine.startX * canvasSize.width,\n                    y = mirroringLine.startY * canvasSize.height,\n                    x1 = mirroringLine.endX * canvasSize.width,\n                    y1 = mirroringLine.endY * canvasSize.height\n                )\n            )\n        }\n    }\n} else {\n    this\n}\n\n@Suppress(\"unused\")\ninternal fun Path.mirror(\n    x: Float,\n    y: Float,\n    x1: Float,\n    y1: Float\n): Path = asAndroidPath().mirror(\n    x = x,\n    y = y,\n    x1 = x1,\n    y1 = y1\n).asComposePath()\n\n@Suppress(\"unused\")\nfun Canvas.drawInfiniteLine(\n    line: Line,\n    paint: NativePaint = NativePaint().apply {\n        color = Color.Red.toArgb()\n        style = NativePaint.Style.STROKE\n        strokeWidth = 5f\n    }\n) {\n    val width = width.toFloat()\n    val height = height.toFloat()\n\n    val startX = line.startX * width\n    val startY = line.startY * height\n    val endX = line.endX * width\n    val endY = line.endY * height\n\n    val dx = endX - startX\n    val dy = endY - startY\n\n    if (dx == 0f) {\n        drawLine(startX, 0f, startX, height, paint)\n        return\n    }\n\n    if (dy == 0f) {\n        drawLine(0f, startY, width, startY, paint)\n        return\n    }\n\n    val directionX = dx / sqrt(dx * dx + dy * dy)\n    val directionY = dy / sqrt(dx * dx + dy * dy)\n\n    val scale = maxOf(width, height) * 2\n    val extendedStartX = startX - directionX * scale\n    val extendedStartY = startY - directionY * scale\n    val extendedEndX = endX + directionX * scale\n    val extendedEndY = endY + directionY * scale\n\n    drawLine(extendedStartX, extendedStartY, extendedEndX, extendedEndY, paint)\n}\n\ninternal fun ImageBitmap.clipBitmap(\n    path: Path,\n    paint: Paint,\n): ImageBitmap = asAndroidBitmap()\n    .let { it.copy(it.safeConfig, true) }\n    .applyCanvas {\n        drawPath(\n            NativePath(path.asAndroidPath()).apply {\n                fillType = NativePath.FillType.INVERSE_WINDING\n            },\n            paint.nativePaint\n        )\n    }.asImageBitmap()\n\ninternal fun ImageBitmap.overlay(overlay: ImageBitmap): ImageBitmap {\n    val image = this.asAndroidBitmap()\n    return createBitmap(\n        width = image.width,\n        height = image.height,\n        config = image.safeConfig\n    ).applyCanvas {\n        drawBitmap(image)\n        drawBitmap(overlay.asAndroidBitmap())\n    }.asImageBitmap()\n}\n\n@Composable\ninternal fun rememberPaint(\n    strokeWidth: Pt,\n    isEraserOn: Boolean,\n    drawColor: Color,\n    brushSoftness: Pt,\n    drawMode: DrawMode,\n    canvasSize: IntegerSize,\n    drawPathMode: DrawPathMode,\n    drawLineStyle: DrawLineStyle\n): State<NativePaint> {\n    val context = LocalContext.current\n\n    return remember(\n        strokeWidth,\n        isEraserOn,\n        drawColor,\n        brushSoftness,\n        drawMode,\n        canvasSize,\n        drawPathMode,\n        context,\n        drawLineStyle\n    ) {\n        derivedStateOf {\n            val isSharpEdge = drawPathMode.isSharpEdge\n            val isFilled = drawPathMode.isFilled\n\n            Paint().apply {\n                if (drawMode !is DrawMode.Text && drawMode !is DrawMode.Image) {\n                    pathEffect = drawLineStyle.asPathEffect(\n                        canvasSize = canvasSize,\n                        strokeWidth = strokeWidth.toPx(canvasSize),\n                        context = context\n                    )\n                }\n                blendMode = if (!isEraserOn) blendMode else BlendMode.Clear\n                if (isEraserOn) {\n                    style = PaintingStyle.Stroke\n                    this.strokeWidth = strokeWidth.toPx(canvasSize)\n                    strokeCap = StrokeCap.Round\n                    strokeJoin = StrokeJoin.Round\n                } else {\n                    if (drawMode !is DrawMode.Text) {\n                        if (isFilled) {\n                            style = PaintingStyle.Fill\n                        } else {\n                            style = PaintingStyle.Stroke\n                            this.strokeWidth = drawPathMode.convertStrokeWidth(\n                                strokeWidth = strokeWidth,\n                                canvasSize = canvasSize\n                            )\n                            if (drawMode is DrawMode.Highlighter || isSharpEdge) {\n                                strokeCap = StrokeCap.Square\n                            } else {\n                                strokeCap = StrokeCap.Round\n                                strokeJoin = StrokeJoin.Round\n                            }\n                        }\n                    }\n                }\n                color = if (drawMode is DrawMode.PathEffect) {\n                    Color.Transparent\n                } else drawColor\n                alpha = drawColor.alpha\n            }.nativePaint.apply {\n                if (drawMode is DrawMode.Neon && !isEraserOn) {\n                    this.color = Color.White.toArgb()\n                    setShadowLayer(\n                        brushSoftness.toPx(canvasSize),\n                        0f,\n                        0f,\n                        drawColor\n                            .copy(alpha = .8f)\n                            .toArgb()\n                    )\n                } else if (brushSoftness.value > 0f) {\n                    maskFilter = BlurMaskFilter(\n                        brushSoftness.toPx(canvasSize),\n                        BlurMaskFilter.Blur.NORMAL\n                    )\n                }\n                if (drawMode is DrawMode.Text && !isEraserOn) {\n                    isAntiAlias = true\n                    textSize = strokeWidth.toPx(canvasSize)\n                    typeface = drawMode.font.toTypeface()\n                }\n            }\n        }\n    }\n}\n\nfun pathEffectPaint(\n    strokeWidth: Pt,\n    drawPathMode: DrawPathMode,\n    canvasSize: IntegerSize,\n): NativePaint {\n    val isSharpEdge = drawPathMode.isSharpEdge\n    val isFilled = drawPathMode.isFilled\n\n    return Paint().apply {\n        if (isFilled) {\n            style = PaintingStyle.Fill\n        } else {\n            style = PaintingStyle.Stroke\n            this.strokeWidth = strokeWidth.toPx(canvasSize)\n            if (isSharpEdge) {\n                strokeCap = StrokeCap.Square\n            } else {\n                strokeCap = StrokeCap.Round\n                strokeJoin = StrokeJoin.Round\n            }\n        }\n\n        color = Color.Transparent\n        blendMode = BlendMode.Clear\n    }.nativePaint\n}\n\n@Composable\nfun rememberPathEffectPaint(\n    strokeWidth: Pt,\n    drawPathMode: DrawPathMode,\n    canvasSize: IntegerSize,\n): State<NativePaint> = remember(\n    strokeWidth,\n    drawPathMode,\n    canvasSize\n) {\n    derivedStateOf {\n        pathEffectPaint(\n            strokeWidth = strokeWidth,\n            drawPathMode = drawPathMode,\n            canvasSize = canvasSize\n        )\n    }\n}\n\ninternal fun DrawLineStyle.asPathEffect(\n    canvasSize: IntegerSize,\n    strokeWidth: Float,\n    context: Context\n): PathEffect? = when (this) {\n    is DrawLineStyle.Dashed -> {\n        PathEffect.dashPathEffect(\n            intervals = floatArrayOf(\n                size.toPx(canvasSize),\n                gap.toPx(canvasSize) + strokeWidth\n            ),\n            phase = 0f\n        )\n    }\n\n    DrawLineStyle.DotDashed -> {\n        val dashOnInterval1 = strokeWidth * 4\n        val dashOffInterval1 = strokeWidth * 2\n        val dashOnInterval2 = strokeWidth / 4\n        val dashOffInterval2 = strokeWidth * 2\n\n        PathEffect.dashPathEffect(\n            intervals = floatArrayOf(\n                dashOnInterval1,\n                dashOffInterval1,\n                dashOnInterval2,\n                dashOffInterval2\n            ),\n            phase = 0f\n        )\n    }\n\n    is DrawLineStyle.Stamped<*> -> {\n        fun Shape.toPath(): Path = Path().apply {\n            addOutline(\n                createOutline(\n                    size = Size(strokeWidth, strokeWidth),\n                    layoutDirection = LayoutDirection.Ltr,\n                    density = context.density\n                )\n            )\n        }\n\n        val path: Path? = when (shape) {\n            is Shape -> shape.toPath()\n            is NativePath -> shape.asComposePath()\n            is Path -> shape\n            null -> MaterialStarShape.toPath()\n            else -> null\n        }\n\n        path?.let {\n            PathEffect.stampedPathEffect(\n                shape = it,\n                advance = spacing.toPx(canvasSize) + strokeWidth,\n                phase = 0f,\n                style = StampedPathEffectStyle.Morph\n            )\n        }\n    }\n\n    is DrawLineStyle.ZigZag -> {\n        val zigZagPath = Path().apply {\n            val zigZagLineWidth = strokeWidth / heightRatio\n            val shapeVerticalOffset = (strokeWidth / 2) / 2\n            val shapeHorizontalOffset = (strokeWidth / 2) / 2\n            moveTo(0f, 0f)\n            lineTo(strokeWidth / 2, strokeWidth / 2)\n            lineTo(strokeWidth, 0f)\n            lineTo(strokeWidth, 0f + zigZagLineWidth)\n            lineTo(strokeWidth / 2, strokeWidth / 2 + zigZagLineWidth)\n            lineTo(0f, 0f + zigZagLineWidth)\n            translate(Offset(-shapeHorizontalOffset, -shapeVerticalOffset))\n        }\n\n        PathEffect.stampedPathEffect(\n            shape = zigZagPath,\n            advance = strokeWidth,\n            phase = 0f,\n            style = StampedPathEffectStyle.Morph\n        )\n    }\n\n    DrawLineStyle.None -> null\n}\n\n@SuppressLint(\"ComposableNaming\")\n@Composable\ninternal fun NativeCanvas.drawRepeatedImageOnPath(\n    drawMode: DrawMode.Image,\n    strokeWidth: Pt,\n    canvasSize: IntegerSize,\n    path: NativePath,\n    paint: NativePaint,\n    invalidations: Int\n) {\n    var pathImage by remember(strokeWidth, canvasSize, drawMode.imageData) {\n        mutableStateOf<Bitmap?>(null)\n    }\n    LaunchedEffect(pathImage, drawMode.imageData, strokeWidth, canvasSize, invalidations) {\n        if (pathImage == null) {\n            pathImage = appContext.imageLoader.execute(\n                ImageRequest.Builder(appContext)\n                    .data(drawMode.imageData)\n                    .size(strokeWidth.toPx(canvasSize).roundToInt())\n                    .build()\n            ).image?.toBitmap()\n        }\n    }\n    pathImage?.let { bitmap ->\n        drawRepeatedBitmapOnPath(\n            bitmap = bitmap,\n            path = path,\n            paint = paint,\n            interval = drawMode.repeatingInterval.toPx(canvasSize)\n        )\n    }\n}\n\ninternal fun transformationsForMode(\n    drawMode: DrawMode,\n    canvasSize: IntegerSize\n): List<Filter<*>> = when (drawMode) {\n    is DrawMode.PathEffect.PrivacyBlur -> {\n        listOf(\n            UiNativeStackBlurFilter(\n                value = drawMode.blurRadius.toFloat() / 1000 * max(canvasSize)\n            )\n        )\n    }\n\n    is DrawMode.PathEffect.Pixelation -> {\n        listOf(\n            UiNativeStackBlurFilter(\n                value = 20f / 1000 * max(canvasSize)\n            ),\n            UiPixelationFilter(\n                value = drawMode.pixelSize / 1000 * max(canvasSize)\n            )\n        )\n    }\n\n    is DrawMode.PathEffect.Custom -> {\n        drawMode.filter?.let {\n            listOf(it.toUiFilter())\n        } ?: emptyList()\n    }\n\n    else -> emptyList()\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/FloodFill.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.Color\nimport android.graphics.Path\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asComposePath\nimport com.t8rin.logger.makeLog\nimport java.util.LinkedList\nimport java.util.Queue\nimport kotlin.math.roundToInt\nimport androidx.compose.ui.graphics.Path as ComposePath\n\ninternal class FloodFill(image: Bitmap) {\n    private val path = Path()\n\n    private val width: Int = image.width\n    private val height: Int = image.height\n    private val pixels: IntArray = IntArray(width * height)\n\n    private lateinit var pixelsChecked: BooleanArray\n    private lateinit var ranges: Queue<FloodFillRange>\n\n    private var tolerance = 0\n\n    private var startColorRed = 0\n    private var startColorGreen = 0\n    private var startColorBlue = 0\n    private var startColorAlpha = 0\n\n    init {\n        image.getPixels(pixels, 0, width, 0, 0, width, height)\n    }\n\n    private fun prepare() {\n        // Called before starting flood-fill\n        pixelsChecked = BooleanArray(pixels.size)\n        ranges = LinkedList()\n    }\n\n    //  Fills the specified point on the bitmap with the currently selected fill color.\n    //  int x, int y: The starting coordinates for the fill\n    fun performFloodFill(\n        x: Int,\n        y: Int,\n        tolerance: Float\n    ): Path? {\n        if (x >= width || y >= height || x < 0 || y < 0) return null\n\n        path.rewind()\n        this.tolerance = (tolerance * 255).roundToInt().coerceIn(0, 255)\n        // Setup\n        prepare()\n\n        // Get starting color.\n        val startPixel = pixels.getOrNull(width * y + x) ?: return null\n        startColorRed = Color.red(startPixel)\n        startColorGreen = Color.green(startPixel)\n        startColorBlue = Color.blue(startPixel)\n        startColorAlpha = Color.alpha(startPixel)\n\n        // Do first call to flood-fill.\n        linearFill(x, y)\n\n        // Call flood-fill routine while flood-fill ranges still exist on the queue\n        var range: FloodFillRange\n        while (ranges.isNotEmpty()) {\n            // Get Next Range Off the Queue\n            range = ranges.remove()\n\n            // Check Above and Below Each Pixel in the flood-fill Range\n            var downPxIdx = width * (range.Y + 1) + range.startX\n            var upPxIdx = width * (range.Y - 1) + range.startX\n            val upY = range.Y - 1 // so we can pass the y coordinate by ref\n            val downY = range.Y + 1\n            for (i in range.startX..range.endX) {\n                // Start Fill Upwards\n                // if we're not above the top of the bitmap and the pixel above this one is within the color tolerance\n                if (range.Y > 0 && !pixelsChecked[upPxIdx] && isPixelColorWithinTolerance(upPxIdx)) {\n                    linearFill(i, upY)\n                }\n\n                // Start Fill Downwards\n                // if we're not below the bottom of the bitmap and the pixel below this one is within the color tolerance\n                if (\n                    range.Y < height - 1 && !pixelsChecked[downPxIdx]\n                    && isPixelColorWithinTolerance(downPxIdx)\n                ) {\n                    linearFill(i, downY)\n                }\n                downPxIdx++\n                upPxIdx++\n            }\n        }\n\n        return path\n    }\n\n    //  Finds the furthermost left and right boundaries of the fill area\n    //  on a given y coordinate, starting from a given x coordinate, filling as it goes.\n    //  Adds the resulting horizontal range to the queue of flood-fill ranges,\n    //  to be processed in the main loop.\n    //\n    //  int x, int y: The starting coordinates\n    private fun linearFill(x: Int, y: Int) {\n        // Find Left Edge of Color Area\n        var lFillLoc = x // the location to check/fill on the left\n        var pxIdx = width * y + x\n        path.moveTo(x.toFloat(), y.toFloat())\n        while (true) {\n            pixelsChecked[pxIdx] = true\n            lFillLoc--\n            pxIdx--\n            // exit loop if we're at edge of bitmap or color area\n            if (lFillLoc < 0 || pixelsChecked[pxIdx] || !isPixelColorWithinTolerance(pxIdx)) {\n                break\n            }\n        }\n        vectorFill(pxIdx + 1)\n        lFillLoc++\n\n        // Find Right Edge of Color Area\n        var rFillLoc = x // the location to check/fill on the left\n        pxIdx = width * y + x\n        while (true) {\n            pixelsChecked[pxIdx] = true\n            rFillLoc++\n            pxIdx++\n            if (rFillLoc >= width || pixelsChecked[pxIdx] || !isPixelColorWithinTolerance(pxIdx)) {\n                break\n            }\n        }\n        vectorFill(pxIdx - 1)\n        rFillLoc--\n\n        // add range to queue\n        val r = FloodFillRange(lFillLoc, rFillLoc, y)\n        ranges.offer(r)\n    }\n\n    // vector fill pixels with color\n    private fun vectorFill(pxIndex: Int) {\n        val x = (pxIndex % width).toFloat()\n        val y = (pxIndex - x) / width\n        path.lineTo(x, y)\n    }\n\n    // Sees if a pixel is within the color tolerance range.\n    private fun isPixelColorWithinTolerance(px: Int): Boolean {\n        val alpha = pixels[px] ushr 24 and 0xff\n        val red = pixels[px] ushr 16 and 0xff\n        val green = pixels[px] ushr 8 and 0xff\n        val blue = pixels[px] and 0xff\n\n        return alpha >= startColorAlpha - tolerance && alpha <= startColorAlpha + tolerance &&\n                red >= startColorRed - tolerance && red <= startColorRed + tolerance &&\n                green >= startColorGreen - tolerance && green <= startColorGreen + tolerance &&\n                blue >= startColorBlue - tolerance && blue <= startColorBlue + tolerance\n    }\n\n    //  Represents a linear range to be filled and branched from.\n    private data class FloodFillRange(\n        val startX: Int,\n        val endX: Int,\n        val Y: Int\n    )\n}\n\nfun ImageBitmap.floodFill(\n    offset: Offset,\n    tolerance: Float\n): ComposePath? = runCatching {\n    FloodFill(\n        asAndroidBitmap().copy(Bitmap.Config.ARGB_8888, false)\n    ).performFloodFill(\n        x = offset.x.roundToInt().coerceIn(0, width - 1),\n        y = offset.y.roundToInt().coerceIn(0, height - 1),\n        tolerance = tolerance\n    )?.asComposePath()\n}.onFailure { it.makeLog(\"floodFill\") }.getOrNull()"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/MotionEvent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nenum class MotionEvent {\n    Idle,\n    Down,\n    Move,\n    Up;\n}\n\ninline fun MotionEvent.handle(\n    onDown: () -> Unit,\n    onMove: () -> Unit,\n    onUp: () -> Unit\n) {\n    when (this) {\n        MotionEvent.Down -> onDown()\n        MotionEvent.Move -> onMove()\n        MotionEvent.Up -> onUp()\n        else -> Unit\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/PathHelper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport android.graphics.Matrix\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.RoundRect\nimport androidx.compose.ui.geometry.isSpecified\nimport androidx.compose.ui.geometry.takeOrElse\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathMeasure\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rotate\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport kotlin.math.abs\nimport kotlin.math.cos\nimport kotlin.math.max\nimport kotlin.math.min\nimport kotlin.math.sin\nimport kotlin.math.sqrt\nimport kotlin.random.Random\n\ndata class PathHelper(\n    val drawDownPosition: Offset,\n    val currentDrawPosition: Offset,\n    val onPathChange: (Path) -> Unit,\n    val strokeWidth: Pt,\n    val canvasSize: IntegerSize,\n    val drawPathMode: DrawPathMode,\n    val isEraserOn: Boolean,\n    val drawMode: DrawMode\n) {\n    private val strokeWidthSized = strokeWidth.toPx(canvasSize)\n\n    private val drawArrowsScope by lazy {\n        object : DrawArrowsScope {\n            override fun drawArrowsIfNeeded(\n                drawPath: Path,\n            ) {\n                fun drawStartEndArrows(\n                    sizeScale: Float = 3f,\n                    angle: Float = 150f\n                ) {\n                    drawEndArrow(\n                        drawPath = drawPath,\n                        arrowSize = sizeScale,\n                        arrowAngle = angle.toDouble()\n                    )\n\n                    drawStartArrow(\n                        drawPath = drawPath,\n                        arrowSize = sizeScale,\n                        arrowAngle = angle.toDouble()\n                    )\n                }\n\n\n                when (drawPathMode) {\n                    is DrawPathMode.DoublePointingArrow -> {\n                        drawStartEndArrows(\n                            sizeScale = drawPathMode.sizeScale,\n                            angle = drawPathMode.angle\n                        )\n                    }\n\n                    is DrawPathMode.DoubleLinePointingArrow -> {\n                        drawStartEndArrows(\n                            sizeScale = drawPathMode.sizeScale,\n                            angle = drawPathMode.angle\n                        )\n                    }\n\n                    is DrawPathMode.PointingArrow -> {\n                        drawEndArrow(\n                            drawPath = drawPath,\n                            arrowSize = drawPathMode.sizeScale,\n                            arrowAngle = drawPathMode.angle.toDouble()\n                        )\n                    }\n\n                    is DrawPathMode.LinePointingArrow -> {\n                        drawEndArrow(\n                            drawPath = drawPath,\n                            arrowSize = drawPathMode.sizeScale,\n                            arrowAngle = drawPathMode.angle.toDouble()\n                        )\n                    }\n\n                    else -> Unit\n                }\n            }\n\n            private fun drawEndArrow(\n                drawPath: Path,\n                arrowSize: Float = 3f,\n                arrowAngle: Double = 150.0\n            ) {\n                val (preLastPoint, lastPoint) = PathMeasure().apply {\n                    setPath(drawPath, false)\n                }.let {\n                    Pair(\n                        it.getPosition(it.length - strokeWidthSized * arrowSize)\n                            .takeOrElse { Offset.Zero },\n                        it.getPosition(it.length).takeOrElse { Offset.Zero }\n                    )\n                }\n\n                val arrowVector = lastPoint - preLastPoint\n\n                fun drawArrow() {\n                    val (rx1, ry1) = arrowVector.rotate(arrowAngle)\n                    val (rx2, ry2) = arrowVector.rotate(360 - arrowAngle)\n\n                    drawPath.apply {\n                        relativeLineTo(rx1, ry1)\n                        moveTo(lastPoint.x, lastPoint.y)\n                        relativeLineTo(rx2, ry2)\n                    }\n                }\n\n                if (abs(arrowVector.x) < arrowSize * strokeWidthSized &&\n                    abs(arrowVector.y) < arrowSize * strokeWidthSized &&\n                    preLastPoint != Offset.Zero\n                ) {\n                    drawArrow()\n                }\n            }\n\n            private fun drawStartArrow(\n                drawPath: Path,\n                arrowSize: Float = 3f,\n                arrowAngle: Double = 150.0\n            ) {\n                val (firstPoint, secondPoint) = PathMeasure().apply {\n                    setPath(drawPath, false)\n                }.let {\n                    Pair(\n                        it.getPosition(0f).takeOrElse { Offset.Zero },\n                        it.getPosition(strokeWidthSized * arrowSize)\n                            .takeOrElse { Offset.Zero }\n                    )\n                }\n\n                val arrowVector = firstPoint - secondPoint\n\n                fun drawArrow() {\n                    val (rx1, ry1) = arrowVector.rotate(arrowAngle)\n                    val (rx2, ry2) = arrowVector.rotate(360 - arrowAngle)\n\n                    drawPath.apply {\n                        moveTo(firstPoint.x, firstPoint.y)\n                        relativeLineTo(rx1, ry1)\n                        moveTo(firstPoint.x, firstPoint.y)\n                        relativeLineTo(rx2, ry2)\n                    }\n                }\n\n                if (abs(arrowVector.x) < arrowSize * strokeWidthSized &&\n                    abs(arrowVector.y) < arrowSize * strokeWidthSized &&\n                    secondPoint != Offset.Zero\n                ) {\n                    drawArrow()\n                }\n            }\n        }\n    }\n\n    fun drawPolygon(\n        vertices: Int,\n        rotationDegrees: Int,\n        isRegular: Boolean,\n    ) {\n        if (drawDownPosition.isSpecified && currentDrawPosition.isSpecified) {\n            val top = max(drawDownPosition.y, currentDrawPosition.y)\n            val left = min(drawDownPosition.x, currentDrawPosition.x)\n            val bottom = min(drawDownPosition.y, currentDrawPosition.y)\n            val right = max(drawDownPosition.x, currentDrawPosition.x)\n\n            val width = right - left\n            val height = bottom - top\n            val centerX = (left + right) / 2f\n            val centerY = (top + bottom) / 2f\n            val radius = min(width, height) / 2f\n\n            val newPath = Path().apply {\n                if (isRegular) {\n                    val angleStep = 360f / vertices\n                    val startAngle = rotationDegrees - 270.0\n                    moveTo(\n                        centerX + radius * cos(Math.toRadians(startAngle)).toFloat(),\n                        centerY + radius * sin(Math.toRadians(startAngle)).toFloat()\n                    )\n                    for (i in 1 until vertices) {\n                        val angle = startAngle + i * angleStep\n                        lineTo(\n                            centerX + radius * cos(Math.toRadians(angle)).toFloat(),\n                            centerY + radius * sin(Math.toRadians(angle)).toFloat()\n                        )\n                    }\n                } else {\n                    for (i in 0 until vertices) {\n                        val angle = i * (360f / vertices) + rotationDegrees - 270.0\n                        val x =\n                            centerX + width / 2f * cos(Math.toRadians(angle)).toFloat()\n                        val y =\n                            centerY + height / 2f * sin(Math.toRadians(angle)).toFloat()\n                        if (i == 0) {\n                            moveTo(x, y)\n                        } else {\n                            lineTo(x, y)\n                        }\n                    }\n                }\n                close()\n            }\n            onPathChange(newPath)\n        }\n    }\n\n    fun drawStar(\n        vertices: Int,\n        innerRadiusRatio: Float,\n        rotationDegrees: Int,\n        isRegular: Boolean,\n    ) {\n        if (drawDownPosition.isSpecified && currentDrawPosition.isSpecified) {\n            val top = max(drawDownPosition.y, currentDrawPosition.y)\n            val left = min(drawDownPosition.x, currentDrawPosition.x)\n            val bottom = min(drawDownPosition.y, currentDrawPosition.y)\n            val right = max(drawDownPosition.x, currentDrawPosition.x)\n\n            val centerX = (left + right) / 2f\n            val centerY = (top + bottom) / 2f\n            val width = right - left\n            val height = bottom - top\n\n            val newPath = Path().apply {\n                if (isRegular) {\n                    val outerRadius = min(width, height) / 2f\n                    val innerRadius = outerRadius * innerRadiusRatio\n\n                    val angleStep = 360f / (2 * vertices)\n                    val startAngle = rotationDegrees - 270.0\n\n                    for (i in 0 until (2 * vertices)) {\n                        val radius = if (i % 2 == 0) outerRadius else innerRadius\n                        val angle = startAngle + i * angleStep\n                        val x = centerX + radius * cos(Math.toRadians(angle)).toFloat()\n                        val y = centerY + radius * sin(Math.toRadians(angle)).toFloat()\n                        if (i == 0) {\n                            moveTo(x, y)\n                        } else {\n                            lineTo(x, y)\n                        }\n                    }\n                } else {\n                    for (i in 0 until (2 * vertices)) {\n                        val angle = i * (360f / (2 * vertices)) + rotationDegrees - 270.0\n                        val radiusX =\n                            (if (i % 2 == 0) width else width * innerRadiusRatio) / 2f\n                        val radiusY =\n                            (if (i % 2 == 0) height else height * innerRadiusRatio) / 2f\n\n                        val x = centerX + radiusX * cos(Math.toRadians(angle)).toFloat()\n                        val y = centerY + radiusY * sin(Math.toRadians(angle)).toFloat()\n                        if (i == 0) {\n                            moveTo(x, y)\n                        } else {\n                            lineTo(x, y)\n                        }\n                    }\n                }\n                close()\n            }\n\n            onPathChange(newPath)\n        }\n    }\n\n    fun drawTriangle() {\n        if (drawDownPosition.isSpecified && currentDrawPosition.isSpecified) {\n            val newPath = Path().apply {\n                moveTo(drawDownPosition.x, drawDownPosition.y)\n\n                lineTo(currentDrawPosition.x, drawDownPosition.y)\n                lineTo(\n                    (drawDownPosition.x + currentDrawPosition.x) / 2,\n                    currentDrawPosition.y\n                )\n                lineTo(drawDownPosition.x, drawDownPosition.y)\n                close()\n            }\n            onPathChange(newPath)\n        }\n    }\n\n    fun drawRect(\n        rotationDegrees: Int,\n        cornerRadius: Float\n    ) {\n        if (!drawDownPosition.isSpecified || !currentDrawPosition.isSpecified) return\n\n        val left = min(drawDownPosition.x, currentDrawPosition.x)\n        val right = max(drawDownPosition.x, currentDrawPosition.x)\n        val top = min(drawDownPosition.y, currentDrawPosition.y)\n        val bottom = max(drawDownPosition.y, currentDrawPosition.y)\n\n        val width = right - left\n        val height = bottom - top\n        if (width <= 0f || height <= 0f) return\n\n        val radius = min(width, height) * cornerRadius.coerceIn(0f, 0.5f)\n        val centerX = (left + right) / 2f\n        val centerY = (top + bottom) / 2f\n\n        val path = Path().apply {\n            addRoundRect(\n                RoundRect(\n                    rect = Rect(left, top, right, bottom),\n                    radius, radius\n                )\n            )\n        }\n\n        val matrix = Matrix().apply {\n            setRotate(rotationDegrees.toFloat(), centerX, centerY)\n        }\n\n\n        onPathChange(\n            path.asAndroidPath().apply { transform(matrix) }.asComposePath()\n        )\n    }\n\n    fun drawOval() {\n        if (drawDownPosition.isSpecified && currentDrawPosition.isSpecified) {\n            val newPath = Path().apply {\n                addOval(\n                    Rect(\n                        top = max(\n                            drawDownPosition.y,\n                            currentDrawPosition.y\n                        ),\n                        left = min(\n                            drawDownPosition.x,\n                            currentDrawPosition.x\n                        ),\n                        bottom = min(\n                            drawDownPosition.y,\n                            currentDrawPosition.y\n                        ),\n                        right = max(\n                            drawDownPosition.x,\n                            currentDrawPosition.x\n                        ),\n                    )\n                )\n            }\n            onPathChange(newPath)\n        }\n    }\n\n    fun drawLine() {\n        if (drawDownPosition.isSpecified && currentDrawPosition.isSpecified) {\n            val newPath = Path().apply {\n                moveTo(drawDownPosition.x, drawDownPosition.y)\n                lineTo(currentDrawPosition.x, currentDrawPosition.y)\n            }\n            drawArrowsScope.drawArrowsIfNeeded(newPath)\n\n            onPathChange(newPath)\n        }\n    }\n\n    fun drawPath(\n        currentDrawPath: Path? = null,\n        onDrawFreeArrow: DrawArrowsScope.() -> Unit = {},\n        onBaseDraw: () -> Unit = {},\n        onFloodFill: (tolerance: Float) -> Unit = {}\n    ) {\n        if (!isEraserOn && drawMode !is DrawMode.Warp) {\n            when (drawPathMode) {\n                is DrawPathMode.PointingArrow,\n                is DrawPathMode.DoublePointingArrow -> onDrawFreeArrow(drawArrowsScope)\n\n                is DrawPathMode.DoubleLinePointingArrow,\n                DrawPathMode.Line,\n                is DrawPathMode.LinePointingArrow -> drawLine()\n\n                is DrawPathMode.Rect -> drawRect(\n                    rotationDegrees = drawPathMode.rotationDegrees,\n                    cornerRadius = drawPathMode.cornerRadius\n                )\n\n                is DrawPathMode.OutlinedRect -> drawRect(\n                    rotationDegrees = drawPathMode.rotationDegrees,\n                    cornerRadius = drawPathMode.cornerRadius\n                )\n\n                is DrawPathMode.Triangle,\n                is DrawPathMode.OutlinedTriangle -> drawTriangle()\n\n                is DrawPathMode.Polygon -> {\n                    drawPolygon(\n                        vertices = drawPathMode.vertices,\n                        rotationDegrees = drawPathMode.rotationDegrees,\n                        isRegular = drawPathMode.isRegular\n                    )\n                }\n\n                is DrawPathMode.OutlinedPolygon -> {\n                    drawPolygon(\n                        vertices = drawPathMode.vertices,\n                        rotationDegrees = drawPathMode.rotationDegrees,\n                        isRegular = drawPathMode.isRegular\n                    )\n                }\n\n                is DrawPathMode.Star -> {\n                    drawStar(\n                        vertices = drawPathMode.vertices,\n                        innerRadiusRatio = drawPathMode.innerRadiusRatio,\n                        rotationDegrees = drawPathMode.rotationDegrees,\n                        isRegular = drawPathMode.isRegular\n                    )\n                }\n\n                is DrawPathMode.OutlinedStar -> {\n                    drawStar(\n                        vertices = drawPathMode.vertices,\n                        innerRadiusRatio = drawPathMode.innerRadiusRatio,\n                        rotationDegrees = drawPathMode.rotationDegrees,\n                        isRegular = drawPathMode.isRegular\n                    )\n                }\n\n                is DrawPathMode.Oval,\n                is DrawPathMode.OutlinedOval -> drawOval()\n\n                is DrawPathMode.Free,\n                is DrawPathMode.Lasso -> onBaseDraw()\n\n                is DrawPathMode.FloodFill -> onFloodFill(drawPathMode.tolerance)\n\n                is DrawPathMode.Spray -> {\n                    currentDrawPath?.let {\n                        val path = currentDrawPath.copy().apply {\n                            repeat(drawPathMode.density) {\n                                val angle = Random.nextFloat() * PI_2\n                                val radius = sqrt(Random.nextFloat()) * strokeWidthSized\n                                val x = currentDrawPosition.x + radius * cos(angle)\n                                val y = currentDrawPosition.y + radius * sin(angle)\n\n                                val rect = Rect(\n                                    left = x,\n                                    top = y,\n                                    right = x + drawPathMode.pixelSize,\n                                    bottom = y + drawPathMode.pixelSize\n                                )\n\n                                if (drawPathMode.isSquareShaped) addRect(rect) else addOval(rect)\n                            }\n                        }\n\n                        onPathChange(path)\n                    }\n                }\n            }\n        } else onBaseDraw()\n    }\n}\n\nprivate const val PI_2 = (Math.PI * 2).toFloat()\n\ninterface DrawArrowsScope {\n    fun drawArrowsIfNeeded(\n        drawPath: Path,\n    )\n}\n\n@Composable\nfun rememberPathHelper(\n    drawDownPosition: Offset,\n    currentDrawPosition: Offset,\n    onPathChange: (Path) -> Unit,\n    strokeWidth: Pt,\n    canvasSize: IntegerSize,\n    drawPathMode: DrawPathMode,\n    isEraserOn: Boolean,\n    drawMode: DrawMode\n): State<PathHelper> = remember(\n    drawDownPosition,\n    currentDrawPosition,\n    onPathChange,\n    strokeWidth,\n    canvasSize,\n    drawPathMode,\n    isEraserOn,\n    drawMode\n) {\n    derivedStateOf {\n        PathHelper(\n            drawDownPosition = drawDownPosition,\n            currentDrawPosition = currentDrawPosition,\n            onPathChange = onPathChange,\n            strokeWidth = strokeWidth,\n            canvasSize = canvasSize,\n            drawPathMode = drawPathMode,\n            isEraserOn = isEraserOn,\n            drawMode = drawMode\n        )\n    }\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/components/utils/PointerDraw.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.components.utils\n\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.magnifier\nimport androidx.compose.runtime.MutableIntState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.isSpecified\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.gesture.pointerMotionEvents\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.observePointersCountWithOffset\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.smartDelayAfterDownInMillis\nimport net.engawapg.lib.zoomable.ZoomState\nimport net.engawapg.lib.zoomable.ZoomableDefaults.defaultZoomOnDoubleTap\nimport net.engawapg.lib.zoomable.zoomable\n\nfun Modifier.pointerDrawObserver(\n    magnifierEnabled: Boolean,\n    currentDrawPosition: Offset,\n    zoomState: ZoomState,\n    globalTouchPointersCount: MutableIntState,\n    panEnabled: Boolean\n) = this.composed {\n    var globalTouchPosition by remember { mutableStateOf(Offset.Unspecified) }\n\n    Modifier\n        .fillMaxSize()\n        .observePointersCountWithOffset { size, offset ->\n            globalTouchPointersCount.intValue = size\n            globalTouchPosition = offset\n        }\n        .then(\n            if (magnifierEnabled) {\n                Modifier.magnifier(\n                    sourceCenter = {\n                        if (currentDrawPosition.isSpecified) {\n                            globalTouchPosition\n                        } else Offset.Unspecified\n                    },\n                    magnifierCenter = {\n                        globalTouchPosition - Offset(0f, 100.dp.toPx())\n                    },\n                    size = DpSize(height = 100.dp, width = 100.dp),\n                    cornerRadius = 50.dp,\n                    elevation = 2.dp\n                )\n            } else Modifier\n        )\n        .clipToBounds()\n        .zoomable(\n            zoomState = zoomState,\n            zoomEnabled = (globalTouchPointersCount.intValue >= 2 || panEnabled),\n            enableOneFingerZoom = panEnabled,\n            onDoubleTap = { pos ->\n                if (panEnabled) zoomState.defaultZoomOnDoubleTap(pos)\n            }\n        )\n}\n\nfun Modifier.pointerDrawHandler(\n    globalTouchPointersCount: MutableIntState,\n    onReceiveMotionEvent: (MotionEvent) -> Unit,\n    onInvalidate: () -> Unit,\n    onUpdateCurrentDrawPosition: (Offset) -> Unit,\n    onUpdateDrawDownPosition: (Offset) -> Unit,\n    enabled: Boolean\n) = if (enabled) {\n    this.composed {\n        var drawStartedWithOnePointer by remember {\n            mutableStateOf(false)\n        }\n\n        Modifier.pointerMotionEvents(\n            onDown = { pointerInputChange ->\n                drawStartedWithOnePointer = globalTouchPointersCount.intValue <= 1\n\n                if (drawStartedWithOnePointer) {\n                    onReceiveMotionEvent(MotionEvent.Down)\n                    onUpdateCurrentDrawPosition(pointerInputChange.position)\n                    onUpdateDrawDownPosition(pointerInputChange.position)\n                    pointerInputChange.consume()\n                    onInvalidate()\n                }\n            },\n            onMove = { pointerInputChange ->\n                if (drawStartedWithOnePointer) {\n                    onReceiveMotionEvent(MotionEvent.Move)\n                    onUpdateCurrentDrawPosition(pointerInputChange.position)\n                    pointerInputChange.consume()\n                    onInvalidate()\n                }\n            },\n            onUp = { pointerInputChange ->\n                if (drawStartedWithOnePointer) {\n                    onReceiveMotionEvent(MotionEvent.Up)\n                    pointerInputChange.consume()\n                    onInvalidate()\n                }\n                drawStartedWithOnePointer = false\n            },\n            delayAfterDownInMillis = smartDelayAfterDownInMillis(globalTouchPointersCount.intValue)\n        )\n    }\n} else {\n    this\n}"
  },
  {
    "path": "feature/draw/src/main/java/com/t8rin/imagetoolbox/feature/draw/presentation/screenLogic/DrawComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic\n\nimport android.content.pm.ActivityInfo\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.childContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawBehavior\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawOnBackgroundParams\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.ImageDrawApplier\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.withContext\n\nclass DrawComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageDrawApplier: ImageDrawApplier<Bitmap, Path, Color>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    private val settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder,\n    addFiltersSheetComponentFactory: AddFiltersSheetComponent.Factory,\n    filterTemplateCreationSheetComponentFactory: FilterTemplateCreationSheetComponent.Factory\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    val addFiltersSheetComponent: AddFiltersSheetComponent = addFiltersSheetComponentFactory(\n        componentContext = componentContext.childContext(\n            key = \"addFilters\"\n        )\n    )\n\n    val filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent =\n        filterTemplateCreationSheetComponentFactory(\n            componentContext = componentContext.childContext(\n                key = \"filterTemplateCreationSheetComponentDraw\"\n            )\n        )\n\n    private val _drawOnBackgroundParams = fileController.savable(\n        scope = componentScope,\n        initial = DrawOnBackgroundParams.Default\n    )\n    val drawOnBackgroundParams: DrawOnBackgroundParams by _drawOnBackgroundParams\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _backgroundColor: MutableState<Color> = mutableStateOf(Color.Transparent)\n    val backgroundColor by _backgroundColor\n\n    private val _colorPickerBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val colorPickerBitmap by _colorPickerBitmap\n\n    private val _drawBehavior: MutableState<DrawBehavior> = mutableStateOf(DrawBehavior.None)\n    val drawBehavior: DrawBehavior by _drawBehavior\n\n    private val _drawMode: MutableState<DrawMode> = mutableStateOf(DrawMode.Pen)\n    val drawMode: DrawMode by _drawMode\n\n    private val _drawPathMode: MutableState<DrawPathMode> = mutableStateOf(DrawPathMode.Free)\n    val drawPathMode: DrawPathMode by _drawPathMode\n\n    private val _drawLineStyle: MutableState<DrawLineStyle> = mutableStateOf(DrawLineStyle.None)\n    val drawLineStyle: DrawLineStyle by _drawLineStyle\n\n    private val _uri = mutableStateOf(Uri.EMPTY)\n    val uri: Uri by _uri\n\n    private val _paths = mutableStateOf(listOf<UiPathPaint>())\n    val paths: List<UiPathPaint> by _paths\n\n    private val _lastPaths = mutableStateOf(listOf<UiPathPaint>())\n    val lastPaths: List<UiPathPaint> by _lastPaths\n\n    private val _undonePaths = mutableStateOf(listOf<UiPathPaint>())\n    val undonePaths: List<UiPathPaint> by _undonePaths\n\n    val havePaths: Boolean\n        get() = paths.isNotEmpty() || lastPaths.isNotEmpty() || undonePaths.isNotEmpty()\n\n    private val _imageFormat = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _saveExif: MutableState<Boolean> = mutableStateOf(false)\n    val saveExif: Boolean by _saveExif\n\n    private val _helperGridParams = fileController.savable(\n        scope = componentScope,\n        initial = HelperGridParams()\n    )\n    val helperGridParams: HelperGridParams by _helperGridParams\n\n    init {\n        componentScope.launch {\n            val settingsState = settingsProvider.getSettingsState()\n            _drawPathMode.update { DrawPathMode.fromOrdinal(settingsState.defaultDrawPathMode) }\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getDrawingBitmap()?.let { localBitmap ->\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = ImageInfo(\n                                originalUri = _uri.value.toString(),\n                                imageFormat = imageFormat,\n                                width = localBitmap.width,\n                                height = localBitmap.height\n                            ),\n                            originalUri = _uri.value.toString(),\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = localBitmap,\n                                imageInfo = ImageInfo(\n                                    originalUri = _uri.value.toString(),\n                                    imageFormat = imageFormat,\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                )\n                            )\n                        ),\n                        keepOriginalMetadata = _saveExif.value,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    private suspend fun calculateScreenOrientationBasedOnUri(uri: Uri): Int {\n        val bmp = imageGetter.getImage(uri = uri.toString(), originalSize = false)?.image\n        val imageRatio = (bmp?.width ?: 0) / (bmp?.height?.toFloat() ?: 1f)\n        return if (imageRatio <= 1.05f) {\n            ActivityInfo.SCREEN_ORIENTATION_PORTRAIT\n        } else {\n            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.value = imageFormat\n        registerChanges()\n    }\n\n    fun setSaveExif(bool: Boolean) {\n        _saveExif.value = bool\n        registerChanges()\n    }\n\n    private fun updateBitmap(bitmap: Bitmap?) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            _bitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n            _isImageLoading.value = false\n        }\n    }\n\n    fun setUri(\n        uri: Uri\n    ) {\n        componentScope.launch {\n            _paths.value = listOf()\n            _lastPaths.value = listOf()\n            _undonePaths.value = listOf()\n            _isImageLoading.value = true\n\n            _uri.value = uri\n            if (drawBehavior !is DrawBehavior.Image) {\n                _drawBehavior.update {\n                    DrawBehavior.Image(calculateScreenOrientationBasedOnUri(uri))\n                }\n            }\n            imageGetter.getImageData(\n                uri = uri.toString(),\n                size = 2500,\n                onFailure = AppToastHost::showFailureToast\n            )?.let { data ->\n                updateBitmap(data.image)\n                _imageFormat.update { data.imageInfo.imageFormat }\n            }\n        }\n    }\n\n    private suspend fun getDrawingBitmap(): Bitmap? = withContext(defaultDispatcher) {\n        imageDrawApplier.applyDrawToImage(\n            drawBehavior = drawBehavior.let {\n                if (it is DrawBehavior.Background) it.copy(color = backgroundColor.toArgb())\n                else it\n            },\n            pathPaints = paths,\n            imageUri = _uri.value.toString()\n        )\n    }\n\n    fun openColorPicker() {\n        componentScope.launch {\n            _colorPickerBitmap.value = getDrawingBitmap()\n        }\n    }\n\n    fun resetDrawBehavior() {\n        _paths.value = listOf()\n        _lastPaths.value = listOf()\n        _undonePaths.value = listOf()\n        _bitmap.value = null\n        _drawBehavior.update {\n            DrawBehavior.None\n        }\n        _drawPathMode.update { DrawPathMode.Free }\n        _uri.value = Uri.EMPTY\n        _backgroundColor.value = Color.Transparent\n        registerChangesCleared()\n    }\n\n    fun startDrawOnBackground(\n        reqWidth: Int,\n        reqHeight: Int,\n        color: Color,\n    ) {\n        val width = reqWidth.takeIf { it > 0 } ?: 1\n        val height = reqHeight.takeIf { it > 0 } ?: 1\n        val imageRatio = width / height.toFloat()\n        _drawBehavior.update {\n            DrawBehavior.Background(\n                orientation = if (imageRatio <= 1f) {\n                    ActivityInfo.SCREEN_ORIENTATION_PORTRAIT\n                } else {\n                    ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE\n                },\n                width = width,\n                height = height,\n                color = color.toArgb()\n            )\n        }\n        _backgroundColor.value = color\n\n        componentScope.launch {\n            val newValue = DrawOnBackgroundParams(\n                width = width,\n                height = height,\n                color = color.toArgb()\n            )\n\n            _drawOnBackgroundParams.update { newValue }\n        }\n    }\n\n    fun shareBitmap() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getDrawingBitmap()?.let {\n                shareProvider.shareImage(\n                    image = it,\n                    imageInfo = ImageInfo(\n                        originalUri = _uri.value.toString(),\n                        imageFormat = imageFormat,\n                        width = it.width,\n                        height = it.height\n                    ),\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun updateBackgroundColor(color: Color) {\n        _backgroundColor.value = color\n        registerChanges()\n    }\n\n    fun clearDrawing() {\n        if (paths.isNotEmpty()) {\n            _lastPaths.value = paths\n            _paths.value = listOf()\n            _undonePaths.value = listOf()\n            registerChanges()\n        }\n    }\n\n    fun undo() {\n        if (paths.isEmpty() && lastPaths.isNotEmpty()) {\n            _paths.value = lastPaths\n            _lastPaths.value = listOf()\n            return\n        }\n        if (paths.isEmpty()) return\n\n        val lastPath = paths.last()\n\n        _paths.update { it - lastPath }\n        _undonePaths.update { it + lastPath }\n        registerChanges()\n    }\n\n    fun redo() {\n        if (undonePaths.isEmpty()) return\n\n        val lastPath = undonePaths.last()\n        _paths.update { it + lastPath }\n        _undonePaths.update { it - lastPath }\n        registerChanges()\n    }\n\n    fun addPath(pathPaint: UiPathPaint) {\n        _paths.update { it + pathPaint }\n        _undonePaths.value = listOf()\n        registerChanges()\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    suspend fun filter(\n        bitmap: Bitmap,\n        filters: List<Filter<*>>,\n    ): Bitmap? = imageTransformer.transform(\n        image = bitmap,\n        transformations = filters.map { filterProvider.filterToTransformation(it) }\n    )\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getDrawingBitmap()?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        originalUri = _uri.value.toString(),\n                        imageFormat = imageFormat,\n                        width = image.width,\n                        height = image.height\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun updateDrawMode(drawMode: DrawMode) {\n        _drawMode.update { drawMode }\n\n        if (drawMode is DrawMode.Warp) {\n            _drawPathMode.update { DrawPathMode.Free }\n            _drawLineStyle.update { DrawLineStyle.None }\n        }\n    }\n\n    fun updateDrawPathMode(drawPathMode: DrawPathMode) {\n        _drawPathMode.update { drawPathMode }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n    fun updateDrawLineStyle(style: DrawLineStyle) {\n        _drawLineStyle.update { style }\n    }\n\n    fun updateHelperGridParams(params: HelperGridParams) {\n        _helperGridParams.update { params }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): DrawComponent\n    }\n}\n"
  },
  {
    "path": "feature/easter-egg/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/easter-egg/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.compose)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.easter_egg\""
  },
  {
    "path": "feature/easter-egg/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/easter-egg/src/main/java/com/t8rin/imagetoolbox/feature/easter_egg/presentation/EasterEggContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"KotlinConstantConditions\", \"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.feature.easter_egg.presentation\n\nimport androidx.compose.animation.core.RepeatMode\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.infiniteRepeatable\nimport androidx.compose.animation.core.rememberInfiniteTransition\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.coerceAtMost\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.min\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.emoji.Emoji\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppVersion\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.EmojiItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.easter_egg.presentation.screenLogic.EasterEggComponent\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.isActive\nimport kotlin.math.roundToInt\nimport kotlin.random.Random\n\n@Composable\nfun EasterEggContent(\n    component: EasterEggComponent\n) {\n    val themeState = LocalDynamicThemeState.current\n    val allEmojis = Emoji.allIcons()\n    val emojiData = remember {\n        mutableStateListOf<String>().apply {\n            addAll(\n                List(11) {\n                    allEmojis.random().toString()\n                }\n            )\n        }\n    }\n    val counter: MutableState<Int> = remember {\n        mutableIntStateOf(0)\n    }\n\n    LaunchedEffect(Unit) {\n        while (isActive) {\n            delay(700)\n            if (counter.value > 10) counter.value = 0\n            emojiData[counter.value] = allEmojis.random().toString()\n            emojiData[10 - counter.value] = allEmojis.random().toString()\n            counter.value++\n        }\n    }\n\n    val painter = painterResource(R.drawable.ic_launcher_foreground)\n\n    Scaffold(\n        modifier = Modifier\n            .fillMaxSize()\n            .background(MaterialTheme.colorScheme.surface),\n        topBar = {\n            EnhancedTopAppBar(\n                title = {\n                    Row(modifier = Modifier.marquee()) {\n                        emojiData.forEach { emoji ->\n                            EmojiItem(\n                                emoji = emoji,\n                                fontScale = 1f\n                            )\n                        }\n                    }\n                },\n                navigationIcon = {\n                    EnhancedIconButton(\n                        onClick = component.onGoBack\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                            contentDescription = stringResource(R.string.exit)\n                        )\n                    }\n                },\n                type = EnhancedTopAppBarType.Center\n            )\n        },\n        contentWindowInsets = WindowInsets()\n    ) { contentPadding ->\n        BoxWithConstraints(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(contentPadding)\n        ) {\n            val density = LocalDensity.current\n            val width = constraints.maxWidth\n            val height = constraints.maxHeight\n            val ballSize = remember(maxWidth, maxHeight) {\n                (min(maxWidth, maxHeight) * 0.3f).coerceAtMost(180.dp)\n            }\n            val ballSizePx = remember(density, ballSize) {\n                with(density) { ballSize.toPx().roundToInt() }\n            }\n            var speed by remember { mutableFloatStateOf(0.2f) }\n\n            var x by remember { mutableFloatStateOf((width - ballSizePx) * 1f) }\n            var y by remember { mutableFloatStateOf((height - ballSizePx) * 1f) }\n\n            val animatedX = animateFloatAsState(x)\n            val animatedY = animateFloatAsState(y)\n\n            var xSpeed by rememberSaveable { mutableFloatStateOf(10f) }\n            var ySpeed by rememberSaveable { mutableFloatStateOf(10f) }\n            val rotation = rememberInfiniteTransition().animateFloat(\n                initialValue = 0f,\n                targetValue = 360f,\n                animationSpec = infiniteRepeatable(\n                    animation = tween(2500),\n                    repeatMode = RepeatMode.Reverse\n                )\n            )\n\n            var bounces by remember {\n                mutableIntStateOf(0)\n            }\n\n            LaunchedEffect(bounces) {\n                if (bounces % 10 == 0) {\n                    themeState.updateColorTuple(ColorTuple(Color(Random.nextInt())))\n                }\n            }\n\n            LaunchedEffect(speed) {\n                while (isActive) {\n                    x += xSpeed * speed\n                    y += ySpeed * speed\n\n                    val rightBounce = x > width - ballSizePx\n                    val leftBounce = x < 0\n                    val bottomBounce = y > height - ballSizePx\n                    val topBounce = y < 0\n\n                    if (rightBounce || leftBounce) {\n                        xSpeed = -xSpeed\n                        bounces++\n                    }\n\n                    if (topBounce || bottomBounce) {\n                        ySpeed = -ySpeed\n                        bounces++\n                    }\n\n                    delay(10)\n                }\n            }\n\n            val icons = remember {\n                Screen.entries.mapNotNull { it.icon }.shuffled()\n            }\n            val tint = MaterialTheme.colorScheme.secondary.copy(0.8f)\n            val minIconSize = remember(density) {\n                with(density) { 22.dp.roundToPx() }\n            }\n\n\n            Column(\n                modifier = Modifier.fillMaxSize()\n            ) {\n                repeat(height / minIconSize) {\n                    Row(\n                        modifier = Modifier.weight(1f)\n                    ) {\n                        repeat(width / minIconSize) {\n                            val icon = remember(it) { icons.random() }\n                            Icon(\n                                imageVector = icon,\n                                contentDescription = null,\n                                modifier = Modifier\n                                    .weight(1f)\n                                    .aspectRatio(1f)\n                                    .padding(1.dp),\n                                tint = tint\n                            )\n                        }\n                    }\n                }\n            }\n\n            Box(\n                modifier = Modifier\n                    .graphicsLayer {\n                        translationX = animatedX.value\n                        translationY = animatedY.value\n                        rotationZ = rotation.value\n                    },\n                contentAlignment = Alignment.Center\n            ) {\n                rememberCoroutineScope()\n                Column(\n                    modifier = Modifier\n                        .container(\n                            shape = MaterialStarShape,\n                            color = MaterialTheme.colorScheme.tertiaryContainer\n                        )\n                        .hapticsClickable {\n                            speed = if (speed == 0.2f) {\n                                Random.nextFloat()\n                            } else 0.2f\n                            AppToastHost.showConfetti()\n                        }\n                        .size(ballSize)\n                        .graphicsLayer {\n                            rotationZ = -rotation.value\n                        },\n                    verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically),\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Icon(\n                        painter = painter,\n                        contentDescription = stringResource(R.string.version),\n                        tint = MaterialTheme.colorScheme.onTertiaryContainer,\n                        modifier = Modifier\n                            .size(ballSize * 0.6f)\n                            .weight(1f, false)\n                    )\n                    Column(\n                        modifier = Modifier.offset(\n                            y = -ballSize * 0.15f\n                        ),\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        Text(\n                            text = stringResource(R.string.version),\n                            style = LocalTextStyle.current.copy(\n                                lineHeight = 18.sp,\n                                color = MaterialTheme.colorScheme.onTertiaryContainer.copy(0.9f)\n                            ),\n                            maxLines = 1\n                        )\n                        AutoSizeText(\n                            text = \"$AppVersion\\n(${BuildConfig.VERSION_CODE})\",\n                            style = LocalTextStyle.current.copy(\n                                fontSize = 12.sp,\n                                fontWeight = FontWeight.Normal,\n                                lineHeight = 14.sp,\n                                textAlign = TextAlign.Center,\n                                color = MaterialTheme.colorScheme.onTertiaryContainer.copy(0.5f)\n                            ),\n                            maxLines = 2\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/easter-egg/src/main/java/com/t8rin/imagetoolbox/feature/easter_egg/presentation/screenLogic/EasterEggComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.easter_egg.presentation.screenLogic\n\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass EasterEggComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n        ): EasterEggComponent\n    }\n\n}"
  },
  {
    "path": "feature/edit-exif/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/edit-exif/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.edit_exif\""
  },
  {
    "path": "feature/edit-exif/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/edit-exif/src/main/java/com/t8rin/imagetoolbox/feature/edit_exif/presentation/EditExifContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.edit_exif.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exif\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.FormatExifWarning\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.EditExifSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.edit_exif.presentation.screenLogic.EditExifComponent\n\n@Composable\nfun EditExifContent(\n    component: EditExifComponent,\n) {\n    AutoContentBasedColors(component.uri)\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val imagePicker = rememberImagePicker(onSuccess = component::setUri)\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    ZoomModalSheet(\n        data = component.uri,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    var showEditExifDialog by rememberSaveable { mutableStateOf(false) }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.edit_exif_screen),\n                input = component.uri.takeIf { it != Uri.EMPTY },\n                isLoading = component.isImageLoading,\n                size = rememberFileSize(component.uri)\n            )\n        },\n        onGoBack = onBack,\n        topAppBarPersistentActions = {\n            if (component.uri == Uri.EMPTY) {\n                TopAppBarEmoji()\n            }\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.uri != Uri.EMPTY\n            )\n        },\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.uri != Uri.EMPTY,\n                onShare = component::shareBitmap,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheCurrentImage { uri ->\n                        editSheetData = listOf(uri)\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = { editSheetData = emptyList() },\n                onNavigate = component.onNavigate\n            )\n        },\n        imagePreview = {\n            Box(\n                contentAlignment = Alignment.Center\n            ) {\n                var aspectRatio by remember {\n                    mutableFloatStateOf(1f)\n                }\n                Picture(\n                    model = component.uri,\n                    modifier = Modifier\n                        .container(MaterialTheme.shapes.medium)\n                        .aspectRatio(aspectRatio),\n                    onSuccess = {\n                        aspectRatio = it.result.image.toBitmap().safeAspectRatio\n                    },\n                    isLoadingFromDifferentPlace = component.isImageLoading,\n                    shape = MaterialTheme.shapes.medium,\n                    contentScale = ContentScale.FillBounds\n                )\n                if (component.isImageLoading) EnhancedLoadingIndicator()\n            }\n        },\n        controls = {\n            PreferenceItem(\n                onClick = {\n                    showEditExifDialog = true\n                },\n                modifier = Modifier.fillMaxWidth(),\n                title = stringResource(R.string.edit_exif),\n                subtitle = stringResource(R.string.edit_exif_tag),\n                shape = ShapeDefaults.extraLarge,\n                enabled = component.imageFormat.canWriteExif,\n                onDisabledClick = {\n                    AppToastHost.showToast(\n                        getString(\n                            R.string.image_exif_warning,\n                            component.imageFormat.title\n                        )\n                    )\n                },\n                startIcon = Icons.Rounded.Exif,\n                endIcon = Icons.Rounded.MiniEdit\n            )\n            Spacer(Modifier.height(8.dp))\n            FormatExifWarning(component.imageFormat)\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uri == Uri.EMPTY,\n                onSecondaryButtonClick = pickImage,\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        canShowScreenData = component.uri != Uri.EMPTY,\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        }\n    )\n\n    EditExifSheet(\n        visible = showEditExifDialog,\n        onDismiss = {\n            showEditExifDialog = false\n        },\n        exif = component.exif,\n        onClearExif = component::clearExif,\n        onUpdateTag = component::updateExifByTag,\n        onRemoveTag = component::removeExifTag\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/edit-exif/src/main/java/com/t8rin/imagetoolbox/feature/edit_exif/presentation/screenLogic/EditExifComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.edit_exif.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.clearAllAttributes\nimport com.t8rin.imagetoolbox.core.domain.image.clearAttribute\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\n\nclass EditExifComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ShareProvider,\n    private val filenameCreator: FilenameCreator,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    private val _exif: MutableState<Metadata?> = mutableStateOf(null)\n    val exif by _exif\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    private val _uri: MutableState<Uri> = mutableStateOf(Uri.EMPTY)\n    val uri: Uri by _uri\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            runSuspendCatching {\n                imageGetter.getImage(uri.toString())\n            }.getOrNull()?.let {\n                val result = fileController.save(\n                    ImageSaveTarget(\n                        imageInfo = it.imageInfo,\n                        originalUri = uri.toString(),\n                        sequenceNumber = null,\n                        metadata = exif,\n                        data = ByteArray(0),\n                        readFromUriInsteadOfData = true\n                    ),\n                    keepOriginalMetadata = false,\n                    oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                )\n\n                parseSaveResult(result.onSuccess(::registerSave))\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun setUri(uri: Uri) {\n        _uri.update { uri }\n        componentScope.launch {\n            imageGetter.getImage(uri.toString())?.let {\n                _exif.value = it.metadata\n                _imageFormat.value = it.imageInfo.imageFormat\n            }\n        }\n    }\n\n    fun shareBitmap() {\n        cacheCurrentImage {\n            componentScope.launch {\n                shareProvider.shareUris(listOf(it.toString()))\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            imageGetter.getImage(\n                uri.toString()\n            )?.let {\n                shareProvider.cacheData(\n                    writeData = { w ->\n                        w.writeBytes(\n                            fileController.readBytes(uri.toString())\n                        )\n                    },\n                    filename = filenameCreator.constructImageFilename(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = it.imageInfo.copy(originalUri = uri.toString()),\n                            originalUri = uri.toString(),\n                            metadata = exif,\n                            sequenceNumber = null,\n                            data = ByteArray(0)\n                        )\n                    )\n                )?.let { uri ->\n                    fileController.writeMetadata(\n                        imageUri = uri,\n                        metadata = exif\n                    )\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun clearExif() {\n        updateExif(_exif.value?.clearAllAttributes())\n    }\n\n    private fun updateExif(metadata: Metadata?) {\n        _exif.update { metadata }\n        registerChanges()\n    }\n\n    fun removeExifTag(tag: MetadataTag) {\n        updateExif(_exif.value?.clearAttribute(tag))\n    }\n\n    fun updateExifByTag(\n        tag: MetadataTag,\n        value: String,\n    ) {\n        updateExif(_exif.value?.setAttribute(tag, value))\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.update { false }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): EditExifComponent\n    }\n}\n"
  },
  {
    "path": "feature/erase-background/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/erase-background/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.erase_background\"\n\ndependencies {\n    \"marketImplementation\"(libs.mlkit.subject.segmentation)\n    \"marketImplementation\"(libs.mlkit.segmentation.selfie)\n\n    implementation(projects.lib.neuralTools)\n    implementation(libs.trickle)\n    \n    implementation(projects.feature.draw)\n}"
  },
  {
    "path": "feature/erase-background/src/foss/java/com/t8rin/imagetoolbox/feature/erase_background/data/backend/MlKitBackgroundRemoverBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.data.backend\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemoverBackend\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\n\ninternal object MlKitBackgroundRemoverBackend :\n    AutoBackgroundRemoverBackend<Bitmap> by GenericBackgroundRemoverBackend(modelType = BgModelType.U2NetP)"
  },
  {
    "path": "feature/erase-background/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/data/AndroidAutoBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.data\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.data.image.utils.healAlpha\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemover\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemoverBackendFactory\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\nimport com.t8rin.logger.makeLog\nimport com.t8rin.neural_tools.bgremover.BgRemover\nimport com.t8rin.trickle.TrickleUtils\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\ninternal class AndroidAutoBackgroundRemover @Inject constructor(\n    private val backendFactory: AutoBackgroundRemoverBackendFactory<Bitmap>,\n    private val appScope: AppScope\n) : AutoBackgroundRemover<Bitmap> {\n\n    override suspend fun trimEmptyParts(\n        image: Bitmap,\n        emptyColor: Int?\n    ): Bitmap = coroutineScope {\n        val transparent = emptyColor ?: Color.Transparent.toArgb()\n\n        runCatching {\n            TrickleUtils.trimEmptyParts(\n                bitmap = image,\n                transparent = transparent\n            )\n        }.onFailure {\n            \"trimEmptyParts\".makeLog(\"Failed to crop image ${it.message}\")\n        }.getOrNull() ?: image\n    }\n\n    override fun removeBackgroundFromImage(\n        image: Bitmap,\n        modelType: BgModelType,\n        onSuccess: (Bitmap) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        appScope.launch {\n            backendFactory.create(modelType)\n                .performBackgroundRemove(image)\n                .map { it.healAlpha(image) }\n                .onSuccess(onSuccess)\n                .onFailure {\n                    onFailure(it.makeLog())\n                }\n        }\n    }\n\n    override fun cleanup() = BgRemover.closeAll()\n\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/data/AndroidAutoBackgroundRemoverBackendFactory.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.erase_background.data.backend.GenericBackgroundRemoverBackend\nimport com.t8rin.imagetoolbox.feature.erase_background.data.backend.MlKitBackgroundRemoverBackend\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemoverBackend\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemoverBackendFactory\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\nimport javax.inject.Inject\n\ninternal class AndroidAutoBackgroundRemoverBackendFactory @Inject constructor() :\n    AutoBackgroundRemoverBackendFactory<Bitmap> {\n\n    override fun create(\n        modelType: BgModelType\n    ): AutoBackgroundRemoverBackend<Bitmap> = when (modelType) {\n        BgModelType.MlKit -> MlKitBackgroundRemoverBackend\n        else -> GenericBackgroundRemoverBackend(modelType)\n    }\n\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/data/backend/GenericBackgroundRemoverBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.data.backend\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemoverBackend\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\nimport com.t8rin.neural_tools.bgremover.BgRemover\n\ninternal class GenericBackgroundRemoverBackend(\n    private val modelType: BgModelType\n) : AutoBackgroundRemoverBackend<Bitmap> {\n\n    override suspend fun performBackgroundRemove(\n        image: Bitmap\n    ): Result<Bitmap> = runCatching {\n        BgRemover.removeBackground(\n            image = image,\n            type = when (modelType) {\n                BgModelType.MlKit,\n                BgModelType.U2NetP -> BgRemover.Type.U2NetP\n\n                BgModelType.U2Net -> BgRemover.Type.U2Net\n                BgModelType.RMBG -> BgRemover.Type.RMBG1_4\n                BgModelType.InSPyReNet -> BgRemover.Type.InSPyReNet\n                BgModelType.BiRefNetTiny -> BgRemover.Type.BiRefNetTiny\n                BgModelType.ISNet -> BgRemover.Type.ISNet\n            }\n        )!!\n    }\n\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/di/EraseBackgroundModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.erase_background.data.AndroidAutoBackgroundRemover\nimport com.t8rin.imagetoolbox.feature.erase_background.data.AndroidAutoBackgroundRemoverBackendFactory\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemover\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemoverBackendFactory\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface EraseBackgroundModule {\n\n    @Binds\n    @Singleton\n    fun provideBackgroundRemover(\n        remover: AndroidAutoBackgroundRemover\n    ): AutoBackgroundRemover<Bitmap>\n\n    @Binds\n    @Singleton\n    fun provideBackendFactory(\n        backend: AndroidAutoBackgroundRemoverBackendFactory\n    ): AutoBackgroundRemoverBackendFactory<Bitmap>\n\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/domain/AutoBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.domain\n\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\n\ninterface AutoBackgroundRemover<I> {\n\n    fun removeBackgroundFromImage(\n        image: I,\n        modelType: BgModelType,\n        onSuccess: (I) -> Unit,\n        onFailure: (Throwable) -> Unit\n    )\n\n    suspend fun trimEmptyParts(\n        image: I,\n        emptyColor: Int? = null\n    ): I\n\n    fun cleanup()\n\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/domain/AutoBackgroundRemoverBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.domain\n\ninternal interface AutoBackgroundRemoverBackend<I> {\n\n    suspend fun performBackgroundRemove(image: I): Result<I>\n\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/domain/AutoBackgroundRemoverBackendFactory.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.domain\n\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\n\ninternal interface AutoBackgroundRemoverBackendFactory<I> {\n    fun create(modelType: BgModelType): AutoBackgroundRemoverBackend<I>\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/domain/model/BgModelType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.utils.Flavor\n\nenum class BgModelType(\n    val title: String\n) {\n    MlKit(\"MlKit\"),\n    U2NetP(\"U2NetP\"),\n    U2Net(\"U2Net\"),\n    RMBG(\"RMBG\"),\n    InSPyReNet(\"InSPyReNet\"),\n    BiRefNetTiny(\"BiRefNet\"),\n    ISNet(\"ISNet\");\n\n    companion object {\n        val Default = if (Flavor.isFoss()) U2NetP else MlKit\n    }\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/presentation/EraseBackgroundContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.presentation\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.Redo\nimport androidx.compose.material.icons.automirrored.rounded.Undo\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveBottomScaffoldLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.HelperGridParamsSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.MagnifierEnabledSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.other.DrawLockScreenOrientation\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.PtSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BrushSoftnessSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawPathModeSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.LineWidthSelector\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.AutoEraseBackgroundCard\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.BitmapEraser\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.OriginalImagePreviewAlphaSelector\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.RecoverModeButton\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.RecoverModeCard\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.TrimImageToggle\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.screenLogic.EraseBackgroundComponent\nimport kotlinx.coroutines.launch\n\n@Composable\nfun EraseBackgroundContent(\n    component: EraseBackgroundComponent,\n) {\n    val settingsState = LocalSettingsState.current\n\n    val scope = rememberCoroutineScope()\n\n    AutoContentBasedColors(component.bitmap)\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n\n    val imagePicker = rememberImagePicker { uri: Uri ->\n        component.setUri(uri)\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var strokeWidth by rememberSaveable(stateSaver = PtSaver) {\n        mutableStateOf(\n            settingsState.defaultDrawLineWidth.pt\n        )\n    }\n    var brushSoftness by rememberSaveable(stateSaver = PtSaver) {\n        mutableStateOf(\n            0.pt\n        )\n    }\n\n    val drawPathMode = component.drawPathMode\n\n    var originalImagePreviewAlpha by rememberSaveable {\n        mutableFloatStateOf(0.2f)\n    }\n\n    val screenSize = LocalScreenSize.current\n    val isPortrait by isPortraitOrientationAsState()\n\n    var panEnabled by rememberSaveable { mutableStateOf(false) }\n\n    val secondaryControls = @Composable {\n        PanModeButton(\n            selected = panEnabled,\n            onClick = {\n                panEnabled = !panEnabled\n            }\n        )\n        EnhancedIconButton(\n            containerColor = Color.Transparent,\n            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                luminance = 0.1f\n            ),\n            onClick = { component.undo() },\n            enabled = component.lastPaths.isNotEmpty() || component.paths.isNotEmpty()\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.Undo,\n                contentDescription = \"Undo\"\n            )\n        }\n        EnhancedIconButton(\n            containerColor = Color.Transparent,\n            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                luminance = 0.1f\n            ),\n            onClick = { component.redo() },\n            enabled = component.undonePaths.isNotEmpty()\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.Redo,\n                contentDescription = \"Redo\"\n            )\n        }\n    }\n\n    AdaptiveBottomScaffoldLayoutScreen(\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.background_remover),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = null,\n                originalSize = null\n            )\n        },\n        onGoBack = onBack,\n        shouldDisableBackHandler = !component.haveChanges,\n        actions = {\n            secondaryControls()\n            RecoverModeButton(\n                selected = component.isRecoveryOn,\n                enabled = !panEnabled,\n                onClick = component::toggleEraser\n            )\n        },\n        topAppBarPersistentActions = { scaffoldState ->\n            if (component.bitmap == null) TopAppBarEmoji()\n            else {\n                if (isPortrait) {\n                    EnhancedIconButton(\n                        onClick = {\n                            scope.launch {\n                                if (scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {\n                                    scaffoldState.bottomSheetState.partialExpand()\n                                } else {\n                                    scaffoldState.bottomSheetState.expand()\n                                }\n                            }\n                        },\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Tune,\n                            contentDescription = stringResource(R.string.properties)\n                        )\n                    }\n                }\n                var editSheetData by remember {\n                    mutableStateOf(listOf<Uri>())\n                }\n                ShareButton(\n                    enabled = component.bitmap != null,\n                    onShare = component::shareBitmap,\n                    onCopy = {\n                        component.cacheCurrentImage(Clipboard::copy)\n                    },\n                    onEdit = {\n                        component.cacheCurrentImage { uri ->\n                            editSheetData = listOf(uri)\n                        }\n                    }\n                )\n                ProcessImagesPreferenceSheet(\n                    uris = editSheetData,\n                    visible = editSheetData.isNotEmpty(),\n                    onDismiss = {\n                        editSheetData = emptyList()\n                    },\n                    onNavigate = component.onNavigate\n                )\n                EnhancedIconButton(\n                    onClick = { component.clearDrawing() },\n                    enabled = component.paths.isNotEmpty()\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Delete,\n                        contentDescription = stringResource(R.string.delete)\n                    )\n                }\n            }\n        },\n        mainContent = {\n            AnimatedContent(\n                targetState = remember(component.bitmap) {\n                    derivedStateOf {\n                        component.bitmap?.copy(\n                            Bitmap.Config.ARGB_8888,\n                            true\n                        )?.asImageBitmap() ?: ImageBitmap(\n                            screenSize.widthPx,\n                            screenSize.heightPx\n                        )\n                    }\n                }.value,\n                transitionSpec = { fadeIn() togetherWith fadeOut() }\n            ) { imageBitmap ->\n                val direction = LocalLayoutDirection.current\n                val aspectRatio = imageBitmap.width / imageBitmap.height.toFloat()\n                BitmapEraser(\n                    imageBitmapForShader = component.internalBitmap?.asImageBitmap(),\n                    imageBitmap = imageBitmap,\n                    paths = component.paths,\n                    strokeWidth = strokeWidth,\n                    brushSoftness = brushSoftness,\n                    onAddPath = component::addPath,\n                    isRecoveryOn = component.isRecoveryOn,\n                    modifier = Modifier\n                        .padding(\n                            start = WindowInsets\n                                .displayCutout\n                                .asPaddingValues()\n                                .calculateStartPadding(direction)\n                        )\n                        .padding(16.dp)\n                        .aspectRatio(\n                            ratio = aspectRatio,\n                            matchHeightConstraintsFirst = isPortrait\n                        )\n                        .fillMaxSize(),\n                    panEnabled = panEnabled,\n                    originalImagePreviewAlpha = originalImagePreviewAlpha,\n                    drawPathMode = drawPathMode,\n                    helperGridParams = component.helperGridParams\n                )\n            }\n        },\n        controls = { scaffoldState ->\n            Column(\n                modifier = Modifier.padding(16.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                if (!isPortrait) {\n                    Row(\n                        modifier = Modifier\n                            .padding(vertical = 8.dp)\n                            .container(shape = ShapeDefaults.circle)\n                    ) {\n                        secondaryControls()\n                    }\n                }\n                RecoverModeCard(\n                    modifier = Modifier.fillMaxWidth(),\n                    selected = component.isRecoveryOn,\n                    enabled = !panEnabled,\n                    onClick = component::toggleEraser\n                )\n                AutoEraseBackgroundCard(\n                    modifier = Modifier.fillMaxWidth(),\n                    onClick = { modelType ->\n                        scope.launch {\n                            scaffoldState.bottomSheetState.partialExpand()\n                            component.autoEraseBackground(\n                                modelType = modelType\n                            )\n                        }\n                    },\n                    onReset = component::resetImage\n                )\n                OriginalImagePreviewAlphaSelector(\n                    value = originalImagePreviewAlpha,\n                    onValueChange = {\n                        originalImagePreviewAlpha = it\n                    },\n                    modifier = Modifier.fillMaxWidth()\n                )\n                DrawPathModeSelector(\n                    modifier = Modifier.fillMaxWidth(),\n                    value = drawPathMode,\n                    onValueChange = component::updateDrawPathMode,\n                    values = remember {\n                        listOf(\n                            DrawPathMode.Free,\n                            DrawPathMode.FloodFill(),\n                            DrawPathMode.Spray(),\n                            DrawPathMode.Line,\n                            DrawPathMode.Lasso,\n                            DrawPathMode.Rect(),\n                            DrawPathMode.Oval\n                        )\n                    },\n                    drawMode = DrawMode.Pen\n                )\n                BoxAnimatedVisibility(drawPathMode.canChangeStrokeWidth) {\n                    LineWidthSelector(\n                        modifier = Modifier.fillMaxWidth(),\n                        value = strokeWidth.value,\n                        onValueChange = { strokeWidth = it.pt }\n                    )\n                }\n                BrushSoftnessSelector(\n                    modifier = Modifier.fillMaxWidth(),\n                    value = brushSoftness.value,\n                    onValueChange = { brushSoftness = it.pt }\n                )\n                TrimImageToggle(\n                    checked = component.trimImage,\n                    onCheckedChange = { component.setTrimImage(it) },\n                    modifier = Modifier.fillMaxWidth()\n                )\n                HelperGridParamsSelector(\n                    value = component.helperGridParams,\n                    onValueChange = component::updateHelperGridParams,\n                    modifier = Modifier.fillMaxWidth()\n                )\n                MagnifierEnabledSelector(\n                    modifier = Modifier.fillMaxWidth(),\n                    shape = ShapeDefaults.extraLarge,\n                )\n                SaveExifWidget(\n                    imageFormat = component.imageFormat,\n                    checked = component.saveExif,\n                    onCheckedChange = component::setSaveExif,\n                    modifier = Modifier.fillMaxWidth()\n                )\n                ImageFormatSelector(\n                    modifier = Modifier.navigationBarsPadding(),\n                    entries = ImageFormatGroup.alphaContainedEntries,\n                    value = component.imageFormat,\n                    onValueChange = component::setImageFormat\n                )\n            }\n        },\n        buttons = {\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.bitmap == null,\n                onSecondaryButtonClick = pickImage,\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        noDataControls = {\n            ImageNotPickedWidget(\n                onPickImage = pickImage\n            )\n        },\n        canShowScreenData = component.bitmap != null,\n        showActionsInTopAppBar = false,\n        mainContentWeight = 0.65f\n    )\n\n    LoadingDialog(\n        visible = component.isSaving || component.isImageLoading || component.isErasingBG,\n        onCancelLoading = component::cancelSaving,\n        canCancel = component.isSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    DrawLockScreenOrientation()\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/presentation/components/AutoEraseBackgroundCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"KotlinConstantConditions\")\n\npackage com.t8rin.imagetoolbox.feature.erase_background.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material.icons.rounded.DownloadForOffline\nimport androidx.compose.material.icons.rounded.SettingsBackupRestore\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateMapOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.retain.retain\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.lifecycle.compose.collectAsStateWithLifecycle\nimport com.t8rin.imagetoolbox.core.domain.saving.track\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.Flavor\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.throttleLatest\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalKeepAliveService\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCancellableCircularProgressIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\nimport com.t8rin.neural_tools.DownloadProgress\nimport com.t8rin.neural_tools.bgremover.BgRemover\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.catch\nimport kotlinx.coroutines.flow.onCompletion\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.flow.onStart\nimport kotlinx.coroutines.launch\nimport kotlin.math.roundToInt\n\n@Composable\nfun AutoEraseBackgroundCard(\n    modifier: Modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp),\n    onClick: (BgModelType) -> Unit,\n    onReset: () -> Unit\n) {\n    var selectedModel by rememberSaveable {\n        mutableStateOf(flavoredEntries.first())\n    }\n\n    val downloadedModelsRaw by BgRemover.downloadedModels.collectAsStateWithLifecycle()\n    val downloadedModels by remember(downloadedModelsRaw) {\n        derivedStateOf {\n            downloadedModelsRaw.mapNotNull { it.toDomain() }\n        }\n    }\n\n    val downloadProgresses = remember(downloadedModels) {\n        mutableStateMapOf<BgModelType, DownloadProgress>()\n    }\n\n    LaunchedEffect(Unit) {\n        flavoredEntries.forEach {\n            BgRemover.getRemover(it.toLib()).checkModel()\n            delay(100)\n        }\n    }\n\n    LaunchedEffect(downloadedModels) {\n        if (!downloadedModels.contains(selectedModel)) {\n            selectedModel = BgModelType.Default\n        }\n    }\n\n    val scope = retain { CoroutineScope(Dispatchers.IO) }\n    var downloadJob by retain {\n        mutableStateOf<Job?>(null)\n    }\n\n    val keepAliveService = LocalKeepAliveService.current\n\n    Column(\n        Modifier\n            .then(modifier)\n            .container(\n                resultPadding = 8.dp,\n                shape = ShapeDefaults.extraLarge\n            )\n    ) {\n        if (flavoredEntries.size > 1) {\n            EnhancedButtonGroup(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .height(IntrinsicSize.Min),\n                entries = flavoredEntries,\n                value = selectedModel,\n                title = null,\n                onValueChange = { type ->\n                    if (downloadJob == null) {\n                        if (selectedModel != type) {\n                            BgRemover.getRemover(selectedModel.toLib()).close()\n                        }\n\n                        selectedModel = type\n\n                        if (type in downloadedModels) return@EnhancedButtonGroup\n\n                        downloadJob?.cancel()\n                        downloadJob = scope.launch {\n                            keepAliveService.track(\n                                initial = {\n                                    updateOrStart(\n                                        title = getString(R.string.downloading)\n                                    )\n                                }\n                            ) {\n                                BgRemover.downloadModel(type.toLib())\n                                    .onStart {\n                                        downloadProgresses[type] = DownloadProgress(\n                                            currentPercent = 0f,\n                                            currentTotalSize = 0\n                                        )\n                                    }\n                                    .onCompletion {\n                                        downloadProgresses.remove(type)\n                                        downloadJob = null\n                                        delay(100)\n                                        BgRemover.getRemover(type.toLib()).checkModel()\n                                    }\n                                    .catch {\n                                        selectedModel = BgModelType.Default\n                                        downloadProgresses.remove(type)\n                                        downloadJob = null\n                                    }\n                                    .onEach {\n                                        downloadProgresses[type] = it\n                                    }\n                                    .throttleLatest(50)\n                                    .collect {\n                                        updateProgress(\n                                            title = getString(R.string.downloading),\n                                            done = (it.currentPercent * 100).roundToInt(),\n                                            total = 100\n                                        )\n                                    }\n                            }\n                        }\n                    }\n                },\n                itemContent = { type ->\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        modifier = Modifier.fillMaxHeight()\n                    ) {\n                        Text(\n                            text = type.title\n                        )\n\n                        if (type != BgModelType.MlKit) {\n                            AnimatedVisibility(type !in downloadedModels) {\n                                downloadProgresses[type]?.let { progress ->\n                                    EnhancedCancellableCircularProgressIndicator(\n                                        progress = { progress.currentPercent },\n                                        modifier = Modifier\n                                            .padding(start = 8.dp)\n                                            .size(24.dp),\n                                        trackColor = MaterialTheme.colorScheme.primary.copy(0.2f),\n                                        strokeWidth = 3.dp,\n                                        onCancel = {\n                                            downloadJob?.cancel()\n                                            selectedModel = BgModelType.Default\n                                            downloadProgresses.remove(type)\n                                            downloadJob = null\n                                        }\n                                    )\n                                } ?: Icon(\n                                    imageVector = Icons.Rounded.DownloadForOffline,\n                                    contentDescription = null,\n                                    modifier = Modifier.padding(start = 8.dp)\n                                )\n                            }\n                        }\n                    }\n                },\n                isScrollable = true,\n                contentPadding = PaddingValues(0.dp),\n                activeButtonColor = MaterialTheme.colorScheme.secondaryContainer\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n        Row(\n            modifier = Modifier\n                .container(\n                    resultPadding = 0.dp,\n                    color = MaterialTheme.colorScheme.mixedContainer.copy(0.7f)\n                )\n                .hapticsClickable(\n                    onClick = { onClick(selectedModel) }\n                )\n                .padding(16.dp),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Text(\n                stringResource(id = R.string.auto_erase_background),\n                modifier = Modifier.weight(1f),\n                color = MaterialTheme.colorScheme.onMixedContainer\n            )\n            Icon(\n                imageVector = Icons.Rounded.AutoFixHigh,\n                contentDescription = stringResource(R.string.auto_erase_background),\n                tint = MaterialTheme.colorScheme.onMixedContainer\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedButton(\n            containerColor = MaterialTheme.colorScheme.errorContainer.copy(0.2f),\n            contentColor = MaterialTheme.colorScheme.onErrorContainer,\n            onClick = onReset,\n            modifier = Modifier.fillMaxWidth(),\n            shape = ShapeDefaults.default,\n            isShadowClip = true\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.SettingsBackupRestore,\n                contentDescription = null\n            )\n            Spacer(Modifier.width(8.dp))\n            Text(stringResource(id = R.string.restore_image))\n        }\n    }\n}\n\nprivate val flavoredEntries: List<BgModelType> = BgModelType.entries.let {\n    if (Flavor.isFoss()) it.toggle(BgModelType.MlKit)\n    else it\n}\n\nprivate fun BgModelType.toLib(): BgRemover.Type = when (this) {\n    BgModelType.MlKit,\n    BgModelType.U2NetP -> BgRemover.Type.U2NetP\n\n    BgModelType.U2Net -> BgRemover.Type.U2Net\n    BgModelType.RMBG -> BgRemover.Type.RMBG1_4\n    BgModelType.InSPyReNet -> BgRemover.Type.InSPyReNet\n    BgModelType.BiRefNetTiny -> BgRemover.Type.BiRefNetTiny\n    BgModelType.ISNet -> BgRemover.Type.ISNet\n}\n\nprivate fun BgRemover.Type.toDomain(): BgModelType? = when (this) {\n    BgRemover.Type.U2NetP -> BgModelType.U2NetP\n    BgRemover.Type.U2Net -> BgModelType.U2Net\n    BgRemover.Type.RMBG1_4 -> BgModelType.RMBG\n    BgRemover.Type.InSPyReNet -> BgModelType.InSPyReNet\n    BgRemover.Type.BiRefNetTiny -> BgModelType.BiRefNetTiny\n    BgRemover.Type.BiRefNet -> null\n    BgRemover.Type.ISNet -> BgModelType.ISNet\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/presentation/components/BitmapEraser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.feature.erase_background.presentation.components\n\nimport android.annotation.SuppressLint\nimport android.graphics.Bitmap\nimport android.graphics.BlurMaskFilter\nimport android.graphics.PorterDuff\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.isSpecified\nimport androidx.compose.ui.geometry.isUnspecified\nimport androidx.compose.ui.geometry.takeOrElse\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.ImageShader\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.PaintingStyle\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathMeasure\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.unit.IntSize\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.createScaledBitmap\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.scaleToFitCanvas\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.BitmapDrawerPreview\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.MotionEvent\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.copy\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.floodFill\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.handle\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.pointerDrawObserver\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.utils.rememberPathHelper\nimport kotlinx.coroutines.launch\nimport net.engawapg.lib.zoomable.rememberZoomState\n\n@SuppressLint(\"CoroutineCreationDuringComposition\")\n@Composable\nfun BitmapEraser(\n    imageBitmap: ImageBitmap,\n    imageBitmapForShader: ImageBitmap?,\n    paths: List<UiPathPaint>,\n    brushSoftness: Pt,\n    originalImagePreviewAlpha: Float,\n    onAddPath: (UiPathPaint) -> Unit,\n    drawPathMode: DrawPathMode = DrawPathMode.Lasso,\n    strokeWidth: Pt,\n    isRecoveryOn: Boolean = false,\n    modifier: Modifier,\n    onErased: (Bitmap) -> Unit = {},\n    panEnabled: Boolean,\n    helperGridParams: HelperGridParams = remember { HelperGridParams() },\n) {\n    val zoomState = rememberZoomState(maxScale = 30f)\n    val scope = rememberCoroutineScope()\n\n    val settingsState = LocalSettingsState.current\n    val magnifierEnabled by remember(zoomState.scale, settingsState.magnifierEnabled) {\n        derivedStateOf {\n            zoomState.scale <= 3f && !panEnabled && settingsState.magnifierEnabled\n        }\n    }\n    val globalTouchPointersCount = remember { mutableIntStateOf(0) }\n\n    var currentDrawPosition by remember { mutableStateOf(Offset.Unspecified) }\n\n    Box(\n        modifier = Modifier.pointerDrawObserver(\n            magnifierEnabled = magnifierEnabled,\n            currentDrawPosition = currentDrawPosition,\n            zoomState = zoomState,\n            globalTouchPointersCount = globalTouchPointersCount,\n            panEnabled = panEnabled\n        ),\n        contentAlignment = Alignment.Center\n    ) {\n        BoxWithConstraints(modifier) {\n            var invalidations by remember {\n                mutableIntStateOf(0)\n            }\n\n            LaunchedEffect(paths, constraints) {\n                invalidations++\n            }\n\n            val motionEvent = remember { mutableStateOf(MotionEvent.Idle) }\n            var previousDrawPosition by remember { mutableStateOf(Offset.Unspecified) }\n            var drawDownPosition by remember { mutableStateOf(Offset.Unspecified) }\n\n            val imageWidth = constraints.maxWidth\n            val imageHeight = constraints.maxHeight\n\n            val drawImageBitmap by remember(imageWidth, imageHeight) {\n                derivedStateOf {\n                    imageBitmap\n                        .asAndroidBitmap()\n                        .createScaledBitmap(\n                            width = imageWidth,\n                            height = imageHeight\n                        )\n                        .asImageBitmap()\n                }\n            }\n\n            val shaderBitmap by remember(imageBitmapForShader, imageWidth, imageHeight) {\n                derivedStateOf {\n                    imageBitmapForShader\n                        ?.asAndroidBitmap()\n                        ?.createScaledBitmap(\n                            imageWidth,\n                            imageHeight\n                        )\n                        ?.asImageBitmap()\n                }\n            }\n\n            val erasedBitmap: ImageBitmap by remember(imageWidth, imageHeight) {\n                derivedStateOf {\n                    createBitmap(imageWidth, imageHeight).asImageBitmap()\n                }\n            }\n\n            val outputImage by remember(invalidations) {\n                derivedStateOf {\n                    erasedBitmap.copy()\n                }\n            }\n\n            LaunchedEffect(invalidations) {\n                onErased(outputImage.asAndroidBitmap())\n            }\n\n            val canvas: Canvas by remember(imageHeight, imageWidth, erasedBitmap) {\n                derivedStateOf {\n                    Canvas(erasedBitmap)\n                }\n            }\n\n            val canvasSize by remember(canvas.nativeCanvas) {\n                derivedStateOf {\n                    IntegerSize(canvas.nativeCanvas.width, canvas.nativeCanvas.height)\n                }\n            }\n\n            val drawPaint by remember(\n                drawPathMode,\n                strokeWidth,\n                isRecoveryOn,\n                brushSoftness,\n                canvasSize\n            ) {\n                derivedStateOf {\n                    Paint().apply {\n                        style = if (drawPathMode.isFilled) {\n                            PaintingStyle.Fill\n                        } else PaintingStyle.Stroke\n\n                        blendMode = if (isRecoveryOn) blendMode else BlendMode.Clear\n                        shader = if (isRecoveryOn) shaderBitmap?.let { ImageShader(it) } else shader\n                        this.strokeWidth = drawPathMode.convertStrokeWidth(\n                            strokeWidth = strokeWidth,\n                            canvasSize = canvasSize\n                        )\n                        if (drawPathMode.isSharpEdge) {\n                            strokeCap = StrokeCap.Square\n                        } else {\n                            strokeCap = StrokeCap.Round\n                            strokeJoin = StrokeJoin.Round\n                        }\n                        isAntiAlias = true\n                    }.nativePaint.apply {\n                        if (brushSoftness.value > 0f) maskFilter =\n                            BlurMaskFilter(\n                                brushSoftness.toPx(canvasSize),\n                                BlurMaskFilter.Blur.NORMAL\n                            )\n                    }\n                }\n            }\n\n            var drawPath by remember(\n                strokeWidth,\n                brushSoftness\n            ) { mutableStateOf(Path()) }\n\n            with(canvas) {\n                with(nativeCanvas) {\n                    drawColor(Color.Transparent.toArgb(), PorterDuff.Mode.CLEAR)\n\n                    val imagePaint = remember { Paint() }\n                    drawImageRect(\n                        image = drawImageBitmap,\n                        dstSize = IntSize(canvasSize.width, canvasSize.height),\n                        paint = imagePaint\n                    )\n\n                    paths.forEach { (nonScaledPath, stroke, radius, _, isRecoveryOn, _, size, drawPathMode) ->\n                        val path by remember(nonScaledPath, size, canvasSize) {\n                            derivedStateOf {\n                                nonScaledPath.scaleToFitCanvas(\n                                    currentSize = canvasSize,\n                                    oldSize = size\n                                ).asAndroidPath()\n                            }\n                        }\n                        val paint by remember(\n                            drawPathMode,\n                            isRecoveryOn,\n                            shaderBitmap,\n                            stroke,\n                            canvasSize,\n                            radius\n                        ) {\n                            derivedStateOf {\n                                Paint().apply {\n                                    style = if (drawPathMode.isFilled) {\n                                        PaintingStyle.Fill\n                                    } else PaintingStyle.Stroke\n                                    blendMode = if (isRecoveryOn) blendMode else BlendMode.Clear\n\n                                    if (isRecoveryOn) shader = shaderBitmap?.let { ImageShader(it) }\n                                    this.strokeWidth = drawPathMode.convertStrokeWidth(\n                                        strokeWidth = stroke,\n                                        canvasSize = canvasSize\n                                    )\n                                    if (drawPathMode.isSharpEdge) {\n                                        strokeCap = StrokeCap.Square\n                                    } else {\n                                        strokeCap = StrokeCap.Round\n                                        strokeJoin = StrokeJoin.Round\n                                    }\n                                    isAntiAlias = true\n                                }.nativePaint.apply {\n                                    if (radius.value > 0f) {\n                                        maskFilter = BlurMaskFilter(\n                                            radius.toPx(canvasSize),\n                                            BlurMaskFilter.Blur.NORMAL\n                                        )\n                                    }\n                                }\n                            }\n                        }\n                        drawPath(path, paint)\n                    }\n                    drawPath(\n                        drawPath.asAndroidPath(),\n                        drawPaint\n                    )\n                }\n\n                val drawHelper by rememberPathHelper(\n                    drawDownPosition = drawDownPosition,\n                    currentDrawPosition = currentDrawPosition,\n                    onPathChange = { drawPath = it },\n                    strokeWidth = strokeWidth,\n                    canvasSize = canvasSize,\n                    drawPathMode = drawPathMode,\n                    isEraserOn = false,\n                    drawMode = DrawMode.Pen\n                )\n\n                motionEvent.value.handle(\n                    onDown = {\n                        if (currentDrawPosition.isSpecified) {\n                            drawPath.moveTo(currentDrawPosition.x, currentDrawPosition.y)\n                            previousDrawPosition = currentDrawPosition\n                        } else {\n                            drawPath = Path()\n                        }\n                        motionEvent.value = MotionEvent.Idle\n                    },\n                    onMove = {\n                        drawHelper.drawPath(\n                            onBaseDraw = {\n                                if (previousDrawPosition.isUnspecified && currentDrawPosition.isSpecified) {\n                                    drawPath.moveTo(currentDrawPosition.x, currentDrawPosition.y)\n                                    previousDrawPosition = currentDrawPosition\n                                }\n\n                                if (currentDrawPosition.isSpecified && previousDrawPosition.isSpecified) {\n                                    drawPath.quadraticTo(\n                                        previousDrawPosition.x,\n                                        previousDrawPosition.y,\n                                        (previousDrawPosition.x + currentDrawPosition.x) / 2,\n                                        (previousDrawPosition.y + currentDrawPosition.y) / 2\n                                    )\n                                }\n                                previousDrawPosition = currentDrawPosition\n                            },\n                            currentDrawPath = drawPath\n                        )\n\n                        motionEvent.value = MotionEvent.Idle\n                    },\n                    onUp = {\n                        drawHelper.drawPath(\n                            onBaseDraw = {\n                                PathMeasure().apply {\n                                    setPath(drawPath, false)\n                                }.let {\n                                    it.getPosition(it.length)\n                                }.takeOrElse { currentDrawPosition }.let { lastPoint ->\n                                    drawPath.moveTo(lastPoint.x, lastPoint.y)\n                                    drawPath.lineTo(\n                                        currentDrawPosition.x,\n                                        currentDrawPosition.y\n                                    )\n                                }\n                            },\n                            onFloodFill = { tolerance ->\n                                erasedBitmap.floodFill(\n                                    offset = currentDrawPosition,\n                                    tolerance = tolerance\n                                )?.let { drawPath = it }\n                            },\n                            currentDrawPath = null\n                        )\n\n                        onAddPath(\n                            UiPathPaint(\n                                path = drawPath,\n                                strokeWidth = strokeWidth,\n                                brushSoftness = brushSoftness,\n                                isErasing = isRecoveryOn,\n                                canvasSize = canvasSize,\n                                drawPathMode = drawPathMode\n                            )\n                        )\n\n                        currentDrawPosition = Offset.Unspecified\n                        previousDrawPosition = Offset.Unspecified\n                        motionEvent.value = MotionEvent.Idle\n\n                        scope.launch {\n                            drawPath = Path()\n                        }\n                    }\n                )\n            }\n\n            BitmapDrawerPreview(\n                preview = outputImage,\n                globalTouchPointersCount = globalTouchPointersCount,\n                onReceiveMotionEvent = { motionEvent.value = it },\n                onInvalidate = { invalidations++ },\n                onUpdateCurrentDrawPosition = { currentDrawPosition = it },\n                onUpdateDrawDownPosition = { drawDownPosition = it },\n                drawEnabled = !panEnabled,\n                helperGridParams = helperGridParams,\n                beforeHelperGridModifier = Modifier.drawBehind {\n                    if (originalImagePreviewAlpha != 0f) {\n                        drawContext.canvas.apply {\n                            drawImageRect(\n                                image = imageBitmapForShader ?: drawImageBitmap,\n                                dstSize = IntSize(canvasSize.width, canvasSize.height),\n                                paint = Paint().apply {\n                                    alpha = originalImagePreviewAlpha\n                                }\n                            )\n                        }\n                    }\n                }\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/presentation/components/OriginalImagePreviewAlphaSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ImageSearch\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\n\n@Composable\nfun OriginalImagePreviewAlphaSelector(\n    value: Float,\n    onValueChange: (Float) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    AlphaSelector(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier,\n        title = stringResource(id = R.string.original_image_preview_alpha),\n        icon = Icons.Rounded.ImageSearch\n    )\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/presentation/components/RecoverModeCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Healing\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun RecoverModeCard(\n    modifier: Modifier = Modifier\n        .padding(start = 16.dp, end = 16.dp, top = 8.dp),\n    selected: Boolean,\n    enabled: Boolean,\n    onClick: () -> Unit,\n) {\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = ShapeDefaults.extraLarge,\n        enabled = enabled,\n        title = stringResource(R.string.restore_background),\n        subtitle = stringResource(R.string.restore_background_sub),\n        startIcon = Icons.Rounded.Healing,\n        checked = selected,\n        onClick = {\n            onClick()\n        }\n    )\n}\n\n@Composable\nfun RecoverModeButton(\n    selected: Boolean,\n    enabled: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n) {\n    EnhancedIconButton(\n        modifier = modifier,\n        enabled = enabled,\n        containerColor = animateColorAsState(\n            if (selected) MaterialTheme.colorScheme.mixedContainer\n            else Color.Transparent\n        ).value,\n        contentColor = animateColorAsState(\n            if (selected) MaterialTheme.colorScheme.onMixedContainer\n            else MaterialTheme.colorScheme.onSurface\n        ).value,\n        borderColor = MaterialTheme.colorScheme.outlineVariant(\n            luminance = 0.1f\n        ),\n        onClick = onClick\n    ) {\n        Icon(\n            imageVector = Icons.Rounded.Healing,\n            contentDescription = \"Brush\"\n        )\n    }\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/presentation/components/TrimImageToggle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ScissorsSmall\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n\n@Composable\nfun TrimImageToggle(\n    checked: Boolean,\n    onCheckedChange: (Boolean) -> Unit,\n    modifier: Modifier = Modifier,\n    color: Color = Color.Unspecified\n) {\n    PreferenceRowSwitch(\n        modifier = modifier,\n        title = stringResource(R.string.trim_image),\n        subtitle = stringResource(R.string.trim_image_sub),\n        checked = checked,\n        containerColor = color,\n        shape = ShapeDefaults.extraLarge,\n        onClick = onCheckedChange,\n        startIcon = Icons.Outlined.ScissorsSmall\n    )\n}"
  },
  {
    "path": "feature/erase-background/src/main/java/com/t8rin/imagetoolbox/feature/erase_background/presentation/screenLogic/EraseBackgroundComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.essenty.lifecycle.doOnDestroy\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.ImageDrawApplier\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemover\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.model.BgModelType\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass EraseBackgroundComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val fileController: FileController,\n    private val imageDrawApplier: ImageDrawApplier<Bitmap, Path, Color>,\n    private val autoBackgroundRemover: AutoBackgroundRemover<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n\n        doOnDestroy {\n            autoBackgroundRemover.cleanup()\n        }\n    }\n\n    private val _internalBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val internalBitmap: Bitmap? by _internalBitmap\n\n    private val _isRecoveryOn: MutableState<Boolean> = mutableStateOf(false)\n    val isRecoveryOn: Boolean by _isRecoveryOn\n\n    private val _saveExif: MutableState<Boolean> = mutableStateOf(false)\n    val saveExif: Boolean by _saveExif\n\n    private val _trimImage: MutableState<Boolean> = mutableStateOf(true)\n    val trimImage: Boolean by _trimImage\n\n    private val _paths = mutableStateOf(listOf<UiPathPaint>())\n    val paths: List<UiPathPaint> by _paths\n\n    private val _lastPaths = mutableStateOf(listOf<UiPathPaint>())\n    val lastPaths: List<UiPathPaint> by _lastPaths\n\n    private val _undonePaths = mutableStateOf(listOf<UiPathPaint>())\n    val undonePaths: List<UiPathPaint> by _undonePaths\n\n    private val _drawPathMode: MutableState<DrawPathMode> = mutableStateOf(DrawPathMode.Free)\n    val drawPathMode: DrawPathMode by _drawPathMode\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _isErasingBG: MutableState<Boolean> = mutableStateOf(false)\n    val isErasingBG: Boolean by _isErasingBG\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Default)\n    val imageFormat: ImageFormat by _imageFormat\n\n    private val _uri: MutableState<Uri> = mutableStateOf(Uri.EMPTY)\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _helperGridParams = fileController.savable(\n        scope = componentScope,\n        initial = HelperGridParams()\n    )\n    val helperGridParams: HelperGridParams by _helperGridParams\n\n    private fun updateBitmap(bitmap: Bitmap?) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            _bitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n            _internalBitmap.value = _bitmap.value\n            _isImageLoading.value = false\n        }\n    }\n\n    fun setUri(\n        uri: Uri\n    ) {\n        _uri.value = uri\n        autoEraseCount = 0\n        _isImageLoading.value = true\n        componentScope.launch {\n            _paths.value = listOf()\n            _lastPaths.value = listOf()\n            _undonePaths.value = listOf()\n\n            imageGetter.getImageAsync(\n                uri = uri.toString(),\n                originalSize = true,\n                onGetImage = { data ->\n                    updateBitmap(data.image)\n                    _imageFormat.update {\n                        data.imageInfo.imageFormat\n                    }\n                },\n                onFailure = AppToastHost::showFailureToast\n            )\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.value = imageFormat\n        registerChanges()\n    }\n\n    private var savingJob: Job? = null\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getErasedBitmap(true)?.let { localBitmap ->\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = ImageInfo(\n                                originalUri = _uri.value.toString(),\n                                imageFormat = imageFormat,\n                                width = localBitmap.width,\n                                height = localBitmap.height\n                            ),\n                            originalUri = _uri.value.toString(),\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = localBitmap,\n                                imageInfo = ImageInfo(\n                                    originalUri = _uri.value.toString(),\n                                    imageFormat = imageFormat,\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                )\n                            )\n                        ),\n                        keepOriginalMetadata = _saveExif.value,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    private suspend fun getErasedBitmap(canTrim: Boolean): Bitmap? {\n        return if (autoEraseCount == 0) {\n            imageDrawApplier.applyEraseToImage(\n                pathPaints = _paths.value,\n                imageUri = _uri.value.toString()\n            )\n        } else {\n            imageDrawApplier.applyEraseToImage(\n                pathPaints = _paths.value,\n                image = _bitmap.value,\n                shaderSourceUri = _uri.value.toString()\n            )\n        }?.let {\n            if (trimImage && canTrim) autoBackgroundRemover.trimEmptyParts(it)\n            else it\n        }\n    }\n\n    fun shareBitmap() {\n        componentScope.launch {\n            getErasedBitmap(true)?.let {\n                _isSaving.value = true\n                shareProvider.shareImage(\n                    imageInfo = ImageInfo(\n                        originalUri = _uri.value.toString(),\n                        imageFormat = imageFormat,\n                        width = it.width,\n                        height = it.height\n                    ),\n                    image = it,\n                    onComplete = AppToastHost::showConfetti\n                )\n            } ?: AppToastHost.showConfetti()\n            _isSaving.value = false\n        }.also {\n            _isSaving.value = false\n            savingJob?.cancel()\n            savingJob = it\n        }\n    }\n\n    fun undo() {\n        if (paths.isEmpty() && lastPaths.isNotEmpty()) {\n            _paths.value = lastPaths\n            _lastPaths.value = listOf()\n            return\n        }\n        if (paths.isEmpty()) return\n\n        val lastPath = paths.last()\n\n        _paths.update { it - lastPath }\n        _undonePaths.update { it + lastPath }\n        registerChanges()\n    }\n\n    fun redo() {\n        if (undonePaths.isEmpty()) return\n\n        val lastPath = undonePaths.last()\n        _paths.update { it + lastPath }\n        _undonePaths.update { it - lastPath }\n        registerChanges()\n    }\n\n    fun addPath(pathPaint: UiPathPaint) {\n        _paths.update { it + pathPaint }\n        _undonePaths.value = listOf()\n        registerChanges()\n    }\n\n    fun clearDrawing() {\n        if (paths.isNotEmpty()) {\n            _lastPaths.value = paths\n            _paths.value = listOf()\n            _undonePaths.value = listOf()\n            registerChanges()\n        }\n    }\n\n    fun setSaveExif(bool: Boolean) {\n        _saveExif.value = bool\n        registerChanges()\n    }\n\n    fun setTrimImage(boolean: Boolean) {\n        _trimImage.value = boolean\n        registerChanges()\n    }\n\n    private var autoEraseCount: Int = 0\n\n    fun autoEraseBackground(\n        modelType: BgModelType,\n    ) {\n        componentScope.launch {\n            getErasedBitmap(false)?.let { image ->\n                _isErasingBG.value = true\n                autoBackgroundRemover.removeBackgroundFromImage(\n                    image = image,\n                    modelType = modelType,\n                    onSuccess = {\n                        _bitmap.value = it\n                        _paths.value = listOf()\n                        _lastPaths.value = listOf()\n                        _undonePaths.value = listOf()\n                        _isErasingBG.value = false\n                        AppToastHost.showConfetti()\n                        autoEraseCount++\n                        registerChanges()\n                    },\n                    onFailure = {\n                        _isErasingBG.value = false\n                        AppToastHost.showFailureToast(it)\n                    }\n                )\n            }\n        }\n    }\n\n    fun resetImage() {\n        componentScope.launch {\n            autoEraseCount = 0\n            _bitmap.value = _internalBitmap.value\n            _paths.value = listOf()\n            _lastPaths.value = listOf()\n        }\n    }\n\n    fun toggleEraser() {\n        _isRecoveryOn.update { !it }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getErasedBitmap(true)?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        originalUri = _uri.value.toString(),\n                        imageFormat = imageFormat,\n                        width = image.width,\n                        height = image.height\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun updateDrawPathMode(drawPathMode: DrawPathMode) {\n        _drawPathMode.update { drawPathMode }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n    fun updateHelperGridParams(params: HelperGridParams) {\n        _helperGridParams.update { params }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): EraseBackgroundComponent\n    }\n\n}"
  },
  {
    "path": "feature/erase-background/src/market/java/com/t8rin/imagetoolbox/feature/erase_background/data/backend/MlKitBackgroundRemoverBackend.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.erase_background.data.backend\n\nimport android.annotation.SuppressLint\nimport android.graphics.Bitmap\nimport android.os.Build\nimport androidx.annotation.RequiresApi\nimport androidx.core.graphics.set\nimport com.google.mlkit.vision.common.InputImage\nimport com.google.mlkit.vision.segmentation.Segmentation\nimport com.google.mlkit.vision.segmentation.Segmenter\nimport com.google.mlkit.vision.segmentation.selfie.SelfieSegmenterOptions\nimport com.google.mlkit.vision.segmentation.subject.SubjectSegmentation\nimport com.google.mlkit.vision.segmentation.subject.SubjectSegmenter\nimport com.google.mlkit.vision.segmentation.subject.SubjectSegmenterOptions\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemoverBackend\nimport kotlinx.coroutines.suspendCancellableCoroutine\nimport java.nio.ByteBuffer\nimport kotlin.coroutines.resume\n\ninternal object MlKitBackgroundRemoverBackend : AutoBackgroundRemoverBackend<Bitmap> {\n\n    override suspend fun performBackgroundRemove(\n        image: Bitmap\n    ): Result<Bitmap> = suspendCancellableCoroutine { continuation ->\n        runCatching {\n            autoRemove(\n                image = image,\n                onFinish = { continuation.resume(it) }\n            )\n        }.onFailure {\n            continuation.resume(Result.failure(it))\n        }\n    }\n\n    @SuppressLint(\"NewApi\")\n    private fun autoRemove(\n        type: ApiType = ApiType.Best,\n        image: Bitmap,\n        onFinish: (Result<Bitmap>) -> Unit\n    ) {\n        val old = {\n            MlKitBackgroundRemover.removeBackground(\n                bitmap = image,\n                onFinish = onFinish\n            )\n        }\n        val new = {\n            MlKitSubjectBackgroundRemover.removeBackground(\n                bitmap = image,\n                onFinish = {\n                    if (it.isFailure) old() else onFinish(it)\n                }\n            )\n        }\n\n        when (type) {\n            ApiType.Old -> old()\n            ApiType.New -> new()\n        }\n    }\n\n    private enum class ApiType {\n        Old, New;\n\n        companion object Companion {\n            val Best: ApiType get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) New else Old\n        }\n    }\n\n}\n\nprivate object MlKitBackgroundRemover {\n\n    private var segment: Segmenter? = null\n    private var buffer = ByteBuffer.allocate(0)\n    private var width = 0\n    private var height = 0\n\n\n    init {\n        runCatching {\n            val segmentOptions = SelfieSegmenterOptions.Builder()\n                .setDetectorMode(SelfieSegmenterOptions.SINGLE_IMAGE_MODE)\n                .build()\n            segment = Segmentation.getClient(segmentOptions)\n        }\n    }\n\n\n    /**\n     * Process the image to get buffer and image height and width\n     * @param bitmap Bitmap which you want to remove background.\n     * @param onFinish listener for success and failure callback.\n     **/\n    fun removeBackground(\n        bitmap: Bitmap,\n        onFinish: (Result<Bitmap>) -> Unit\n    ) {\n        //Generate a copy of bitmap just in case the if the bitmap is immutable.\n        val copyBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true)\n        val input = InputImage.fromBitmap(copyBitmap, 0)\n        val segmenter = segment ?: return onFinish(Result.failure(NoClassDefFoundError()))\n\n        segmenter.process(input)\n            .addOnSuccessListener { segmentationMask ->\n                buffer = segmentationMask.buffer\n                width = segmentationMask.width\n                height = segmentationMask.height\n\n                val resultBitmap = removeBackgroundFromImage(copyBitmap)\n                onFinish(Result.success(resultBitmap))\n            }\n            .addOnFailureListener { e ->\n                onFinish(Result.failure(e))\n            }\n    }\n\n\n    /**\n     * Change the background pixels color to transparent.\n     * */\n    private fun removeBackgroundFromImage(\n        image: Bitmap\n    ): Bitmap {\n        image.setHasAlpha(true)\n        for (y in 0 until height) {\n            for (x in 0 until width) {\n                val bgConfidence = ((1.0 - buffer.float) * 255).toInt()\n                if (bgConfidence >= 100) {\n                    image[x, y] = 0\n                }\n            }\n        }\n        buffer.rewind()\n\n        return image\n    }\n\n}\n\n@RequiresApi(api = Build.VERSION_CODES.N)\nprivate object MlKitSubjectBackgroundRemover {\n\n    private var segment: SubjectSegmenter? = null\n\n    init {\n        runCatching {\n            val segmentOptions = SubjectSegmenterOptions.Builder()\n                .enableForegroundBitmap()\n                .build()\n            segment = SubjectSegmentation.getClient(segmentOptions)\n        }\n    }\n\n\n    /**\n     * Process the image to get buffer and image height and width\n     * @param bitmap Bitmap which you want to remove background.\n     * @param onFinish listener for success and failure callback.\n     **/\n    @RequiresApi(api = Build.VERSION_CODES.N)\n    fun removeBackground(\n        bitmap: Bitmap,\n        onFinish: (Result<Bitmap>) -> Unit\n    ) {\n        //Generate a copy of bitmap just in case the if the bitmap is immutable.\n        val copyBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true)\n        val input = InputImage.fromBitmap(copyBitmap, 0)\n        val segmenter = segment ?: return onFinish(Result.failure(NoClassDefFoundError()))\n\n        segmenter.process(input)\n            .addOnSuccessListener {\n                onFinish(Result.success(it?.foregroundBitmap ?: bitmap))\n            }\n            .addOnFailureListener { e ->\n                onFinish(Result.failure(e))\n            }\n    }\n\n}"
  },
  {
    "path": "feature/filters/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/filters/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.filters\"\n\ndependencies {\n    api(projects.core.filters)\n    ksp(projects.core.ksp)\n    implementation(projects.core.ksp)\n    implementation(projects.feature.draw)\n    implementation(projects.feature.pickColor)\n    implementation(projects.feature.compare)\n    implementation(libs.kotlin.reflect)\n    implementation(libs.aire)\n    implementation(libs.trickle)\n    implementation(libs.toolbox.gpuimage)\n    implementation(projects.lib.opencvTools)\n    implementation(projects.lib.neuralTools)\n    implementation(projects.lib.curves)\n    implementation(libs.toolbox.jhlabs)\n    implementation(projects.lib.ascii)\n}"
  },
  {
    "path": "feature/filters/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/AndroidFilterMaskApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data\n\nimport android.graphics.Bitmap\nimport android.graphics.BlurMaskFilter\nimport android.graphics.Matrix\nimport android.graphics.PorterDuff\nimport android.graphics.PorterDuffXfermode\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.PaintingStyle\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.data.utils.toSoftware\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.feature.draw.domain.PathPaint\nimport com.t8rin.imagetoolbox.feature.filters.domain.FilterMask\nimport com.t8rin.imagetoolbox.feature.filters.domain.FilterMaskApplier\nimport javax.inject.Inject\nimport android.graphics.Paint as NativePaint\n\ninternal class AndroidFilterMaskApplier @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n) : FilterMaskApplier<Bitmap, Path, Color> {\n\n    override suspend fun filterByMask(\n        filterMask: FilterMask<Path, Color>,\n        imageUri: String,\n    ): Bitmap? = imageGetter.getImage(uri = imageUri)?.let {\n        filterByMask(filterMask = filterMask, image = it.image)\n    }\n\n    override suspend fun filterByMask(\n        filterMask: FilterMask<Path, Color>,\n        image: Bitmap,\n    ): Bitmap? {\n        if (filterMask.filters.isEmpty()) return image\n\n        val filteredBitmap = imageTransformer.transform(\n            image = image,\n            transformations = filterMask.filters.map {\n                filterProvider.filterToTransformation(it)\n            }\n        )?.clipBitmap(\n            pathPaints = filterMask.maskPaints,\n            inverse = filterMask.isInverseFillType\n        )\n        return filteredBitmap?.let {\n            image.let { bitmap ->\n                if (filterMask.filters.any { it is Filter.RemoveColor }) {\n                    bitmap.clipBitmap(\n                        pathPaints = filterMask.maskPaints,\n                        inverse = !filterMask.isInverseFillType\n                    )\n                } else bitmap\n            }.overlay(filteredBitmap)\n        }\n    }\n\n    private fun Bitmap.clipBitmap(\n        pathPaints: List<PathPaint<Path, Color>>,\n        inverse: Boolean,\n    ): Bitmap = createBitmap(\n        width = this.width,\n        height = this.height,\n        config = this.safeConfig\n    ).apply { setHasAlpha(true) }.applyCanvas {\n        val canvasSize = IntegerSize(width, height)\n\n        pathPaints.forEach { pathPaint ->\n            val path = pathPaint.path.scaleToFitCanvas(\n                currentSize = canvasSize,\n                oldSize = pathPaint.canvasSize\n            )\n            val drawPathMode = pathPaint.drawPathMode\n            val isSharpEdge = drawPathMode.isSharpEdge\n            val isFilled = drawPathMode.isFilled\n\n            drawPath(\n                path,\n                Paint().apply {\n                    if (pathPaint.isErasing) {\n                        style = PaintingStyle.Stroke\n                        this.strokeWidth = pathPaint.strokeWidth.toPx(canvasSize)\n                        strokeCap = StrokeCap.Round\n                        strokeJoin = StrokeJoin.Round\n                    } else {\n                        if (isFilled) {\n                            style = PaintingStyle.Fill\n                        } else {\n                            style = PaintingStyle.Stroke\n                            if (isSharpEdge) {\n                                strokeCap = StrokeCap.Square\n                            } else {\n                                strokeCap = StrokeCap.Round\n                                strokeJoin = StrokeJoin.Round\n                            }\n                            this.strokeWidth = pathPaint.strokeWidth.toPx(canvasSize)\n                        }\n                    }\n                    color = pathPaint.drawColor\n                    if (pathPaint.isErasing) {\n                        blendMode = BlendMode.Clear\n                    }\n                }.nativePaint.apply {\n                    if (pathPaint.brushSoftness.value > 0f) {\n                        maskFilter = BlurMaskFilter(\n                            pathPaint.brushSoftness.toPx(canvasSize),\n                            BlurMaskFilter.Blur.NORMAL\n                        )\n                    }\n                }\n            )\n        }\n        drawBitmap(\n            this@clipBitmap,\n            0f,\n            0f,\n            NativePaint()\n                .apply {\n                    xfermode = if (!inverse) {\n                        PorterDuffXfermode(PorterDuff.Mode.SRC_IN)\n                    } else {\n                        PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)\n                    }\n                }\n        )\n    }\n\n    private fun Bitmap.overlay(overlay: Bitmap): Bitmap {\n        val image = this\n\n        return createBitmap(\n            width = image.width,\n            height = image.height,\n            config = image.safeConfig.toSoftware()\n        ).applyCanvas {\n            drawBitmap(image)\n            drawBitmap(overlay.toSoftware())\n        }\n    }\n\n    private fun Path.scaleToFitCanvas(\n        currentSize: IntegerSize,\n        oldSize: IntegerSize,\n        onGetScale: (Float, Float) -> Unit = { _, _ -> },\n    ): android.graphics.Path {\n        val sx = currentSize.width.toFloat() / oldSize.width\n        val sy = currentSize.height.toFloat() / oldSize.height\n        onGetScale(sx, sy)\n        return android.graphics.Path(this.asAndroidPath()).apply {\n            transform(\n                Matrix().apply {\n                    setScale(sx, sy)\n                }\n            )\n        }\n    }\n\n    override suspend fun filterByMasks(\n        filterMasks: List<FilterMask<Path, Color>>,\n        imageUri: String,\n    ): Bitmap? = imageGetter.getImage(uri = imageUri)?.let {\n        filterByMasks(filterMasks, it.image)\n    }\n\n    override suspend fun filterByMasks(\n        filterMasks: List<FilterMask<Path, Color>>,\n        image: Bitmap,\n    ): Bitmap? = filterMasks.fold<FilterMask<Path, Color>, Bitmap?>(\n        initial = image,\n        operation = { bmp, mask ->\n            bmp?.let {\n                filterByMask(\n                    filterMask = mask, image = bmp\n                )\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/AndroidFilterParamsInteractor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UNCHECKED_CAST\")\n\npackage com.t8rin.imagetoolbox.feature.filters.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.core.net.toUri\nimport androidx.datastore.core.DataStore\nimport androidx.datastore.preferences.core.Preferences\nimport androidx.datastore.preferences.core.booleanPreferencesKey\nimport androidx.datastore.preferences.core.edit\nimport androidx.datastore.preferences.core.stringPreferencesKey\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterParamsInteractor\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.toImageModel\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.serialization.PACKAGE_ALIAS\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.serialization.toDatastoreString\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.serialization.toFiltersList\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.serialization.toTemplateFiltersList\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.flow.map\nimport java.io.File\nimport javax.inject.Inject\n\ninternal class AndroidFilterParamsInteractor @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val dataStore: DataStore<Preferences>,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>\n) : FilterParamsInteractor {\n\n    override fun getFavoriteFilters(): Flow<List<Filter<*>>> = dataStore.data.map { prefs ->\n        prefs[FAVORITE_FILTERS]?.toFiltersList(false, context) ?: emptyList()\n    }\n\n    override suspend fun toggleFavorite(filter: Filter<*>) {\n        val currentFilters = getFavoriteFilters().first()\n        if (currentFilters.filterIsInstance(filter::class.java).isEmpty()) {\n            dataStore.edit { prefs ->\n                prefs[FAVORITE_FILTERS] =\n                    (listOf(filter) + currentFilters).toDatastoreString(context = context)\n            }\n        } else {\n            dataStore.edit { prefs ->\n                prefs[FAVORITE_FILTERS] = currentFilters\n                    .filter {\n                        !it::class.java.isInstance(filter)\n                    }\n                    .toDatastoreString(context = context)\n            }\n        }\n    }\n\n    override fun getTemplateFilters(): Flow<List<TemplateFilter>> =\n        dataStore.data.map { prefs ->\n            prefs[TEMPLATE_FILTERS]?.takeIf { it.isNotEmpty() }?.toTemplateFiltersList(context)\n                ?: emptyList()\n        }\n\n    override suspend fun addTemplateFilterFromString(\n        string: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit,\n    ) {\n        runSuspendCatching {\n            if (isValidTemplateFilter(string)) {\n                runSuspendCatching {\n                    string.removePrefix(LINK_HEADER).toTemplateFiltersList(context).firstOrNull()\n                }.getOrNull()?.let {\n                    addTemplateFilter(it)\n                    onSuccess(it.name, it.filters.size)\n                } ?: onFailure()\n            } else onFailure()\n        }.onFailure { onFailure() }\n    }\n\n    override fun isValidTemplateFilter(\n        string: String,\n    ): Boolean =\n        (context.applicationInfo.packageName in string || PACKAGE_ALIAS in string) && \"Filter\" in string && LINK_HEADER in string\n\n    override suspend fun reorderFavoriteFilters(newOrder: List<Filter<*>>) {\n        dataStore.edit { prefs ->\n            prefs[FAVORITE_FILTERS] = newOrder.toDatastoreString(context = context)\n        }\n    }\n\n    override fun getFilterPreviewModel(): Flow<ImageModel> = dataStore.data.map { prefs ->\n        prefs[PREVIEW_MODEL]?.let {\n            when (it) {\n                \"0\" -> R.drawable.filter_preview_source\n                \"1\" -> R.drawable.filter_preview_source_3\n                else -> it\n            }.toImageModel()\n        } ?: R.drawable.filter_preview_source.toImageModel()\n    }\n\n    override suspend fun setFilterPreviewModel(uri: String) {\n        if (uri.any { !it.isDigit() }) {\n            imageGetter.getImage(\n                data = uri,\n                size = 300\n            )?.let { image ->\n                fileController.writeBytes(\n                    File(context.filesDir, \"filterPreview.png\").apply {\n                        createNewFile()\n                    }.toUri().toString()\n                ) { writeable ->\n                    writeable.writeBytes(\n                        imageCompressor.compress(\n                            image = image,\n                            imageFormat = ImageFormat.Png.Lossless,\n                            quality = Quality.Base(100)\n                        )\n                    )\n                }\n            }\n        }\n        dataStore.edit {\n            it[PREVIEW_MODEL] = uri\n        }\n    }\n\n    override suspend fun addTemplateFilterFromUri(\n        uri: String,\n        onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,\n        onFailure: suspend () -> Unit,\n    ) {\n        addTemplateFilterFromString(\n            string = fileController.readBytes(uri).decodeToString(),\n            onSuccess = onSuccess,\n            onFailure = onFailure\n        )\n    }\n\n    override suspend fun removeTemplateFilter(templateFilter: TemplateFilter) {\n        val currentFilters = getTemplateFilters().first()\n        dataStore.edit { prefs ->\n            prefs[TEMPLATE_FILTERS] = currentFilters.filter {\n                convertTemplateFilterToString(it) != convertTemplateFilterToString(templateFilter)\n            }.toDatastoreString(context)\n        }\n    }\n\n    override suspend fun convertTemplateFilterToString(\n        templateFilter: TemplateFilter,\n    ): String = \"$LINK_HEADER${listOf(templateFilter).toDatastoreString(context)}\"\n\n    override suspend fun addTemplateFilter(templateFilter: TemplateFilter) {\n        val currentFilters = getTemplateFilters().first()\n        dataStore.edit { prefs ->\n            prefs[TEMPLATE_FILTERS] = currentFilters.let { filters ->\n                val index = filters.indexOfFirst {\n                    convertTemplateFilterToString(it) == convertTemplateFilterToString(\n                        templateFilter\n                    )\n                }\n                if (index != -1) filters else filters + templateFilter\n            }.toDatastoreString(context)\n        }\n    }\n\n    override fun getCanSetDynamicFilterPreview(): Flow<Boolean> =\n        dataStore.data.map { it[CAN_SET_DYNAMIC_FILTER_PREVIEW] == true }\n\n    override suspend fun setCanSetDynamicFilterPreview(value: Boolean) {\n        dataStore.edit { prefs ->\n            prefs[CAN_SET_DYNAMIC_FILTER_PREVIEW] = value\n        }\n    }\n}\n\nprivate const val LINK_HEADER: String = \"https://github.com/T8RIN/ImageToolbox?\"\n\nprivate val FAVORITE_FILTERS = stringPreferencesKey(\"FAVORITE_FILTERS\")\nprivate val TEMPLATE_FILTERS = stringPreferencesKey(\"TEMPLATE_FILTERS\")\nprivate val PREVIEW_MODEL = stringPreferencesKey(\"PREVIEW_MODEL\")\nprivate val CAN_SET_DYNAMIC_FILTER_PREVIEW = booleanPreferencesKey(\"CAN_SET_DYNAMIC_FILTER_PREVIEW\")"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/AndroidFilterProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ifVisible\nimport com.t8rin.imagetoolbox.core.domain.transformation.EmptyTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.generated.mapFilter\nimport javax.inject.Inject\n\ninternal class AndroidFilterProvider @Inject constructor() : FilterProvider<Bitmap> {\n\n    override fun filterToTransformation(\n        filter: Filter<*>,\n    ): Transformation<Bitmap> = filter.ifVisible(::mapFilter) ?: EmptyTransformation()\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AcesFilmicToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class AcesFilmicToneMappingFilter(\n    override val value: Float = 1f,\n) : Transformation<Bitmap>, Filter.AcesFilmicToneMapping {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.acesFilmicToneMapping(\n        bitmap = input,\n        exposure = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AcesHillToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class AcesHillToneMappingFilter(\n    override val value: Float = 1f,\n) : Transformation<Bitmap>, Filter.AcesHillToneMapping {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.acesHillToneMapping(\n        bitmap = input,\n        exposure = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AchromatomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class AchromatomalyFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Achromatomaly {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.ACHROMATOMALY).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AchromatopsiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class AchromatopsiaFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Achromatopsia {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.ACHROMATOPSIA).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AldridgeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class AldridgeFilter(\n    override val value: Pair<Float, Float> = 1f to 0.025f\n) : Transformation<Bitmap>, Filter.Aldridge {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.aldridge(\n        bitmap = input,\n        exposure = value.first,\n        cutoff = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AmatorkaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class AmatorkaFilter(\n    override val value: Float = 1f,\n) : ChainTransformation<Bitmap>, Filter.Amatorka {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_amatorka))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AnaglyphFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.glitch.GlitchTool\n\n@FilterInject\ninternal class AnaglyphFilter(\n    override val value: Float = 20f\n) : Transformation<Bitmap>, Filter.Anaglyph {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = GlitchTool.anaglyph(input, value.toInt())\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AnisotropicDiffusionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class AnisotropicDiffusionFilter(\n    override val value: Triple<Float, Float, Float> = Triple(20f, 0.6f, 0.5f)\n) : Transformation<Bitmap>, Filter.AnisotropicDiffusion {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.anisotropicDiffusion(\n        bitmap = input,\n        numOfSteps = value.first.roundToInt(),\n        conduction = value.second,\n        diffusion = value.third\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ArcFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.jhlabs.ArcFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ArcParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\nimport kotlin.math.max\n\n@FilterInject\ninternal class ArcFilter(\n    override val value: ArcParams = ArcParams.Default\n) : JhFilterTransformation(), Filter.Arc {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = ArcFilter()\n\n    override fun createFilter(image: Bitmap): JhFilter = ArcFilter().apply {\n        radius = value.radius * (max(image.width, image.height) / 2f)\n        height = value.height * (max(image.width, image.height) / 2f)\n        angle = Math.toRadians(value.angle.toDouble()).toFloat()\n        spreadAngle = Math.toRadians(value.spreadAngle.toDouble()).toFloat()\n        centreX = value.centreX\n        centreY = value.centreY\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AsciiFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport android.graphics.Typeface\nimport com.t8rin.ascii.ASCIIConverter\nimport com.t8rin.ascii.Gradient\nimport com.t8rin.ascii.toMapper\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.AsciiParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.utils.toTypeface\n\n@FilterInject\ninternal class AsciiFilter(\n    override val value: AsciiParams = AsciiParams.Default\n) : Transformation<Bitmap>, Filter.Ascii {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ASCIIConverter(\n        fontSize = value.fontSize,\n        mapper = Gradient(value.gradient).toMapper()\n    ).convertToAsciiBitmap(\n        bitmap = input,\n        typeface = value.font.toTypeface() ?: Typeface.DEFAULT,\n        backgroundColor = value.backgroundColor.colorInt,\n        isGrayscale = value.isGrayscale\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AtkinsonDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class AtkinsonDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.AtkinsonDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Atkinson,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AutoCropFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.autocrop.AutoCropper\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class AutoCropFilter(\n    override val value: Float = 5f\n) : Transformation<Bitmap>, Filter.AutoCrop {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = AutoCropper.crop(\n        bitmap = input,\n        sensitivity = value.roundToInt()\n    ) ?: input\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AutoPerspectiveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.auto_straight.AutoStraighten\nimport com.t8rin.opencv_tools.auto_straight.model.StraightenMode\n\n@FilterInject\ninternal class AutoPerspectiveFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.AutoPerspective {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = AutoStraighten.process(\n        input = input,\n        mode = StraightenMode.Perspective\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AutoRemoveRedEyesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.red_eye.RedEyeRemover\n\n@FilterInject\ninternal class AutoRemoveRedEyesFilter(\n    override val value: Float = 150f,\n) : Transformation<Bitmap>, Filter.AutoRemoveRedEyes {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = RedEyeRemover.removeRedEyes(\n        bitmap = input,\n        minEyeSize = 35.0,\n        redThreshold = value.toDouble()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AutumnTonesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class AutumnTonesFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.AutumnTones {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.AUTUMN_TONES).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/AverageDistanceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.forensics.ImageForensics\n\n@FilterInject\ninternal class AverageDistanceFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.AverageDistance {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ImageForensics.averageDistance(\n        input = input\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BayerEightDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class BayerEightDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.BayerEightDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.BayerEight,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BayerFourDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class BayerFourDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.BayerFourDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.BayerFour,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BayerThreeDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class BayerThreeDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.BayerThreeDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.BayerThree,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BayerTwoDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class BayerTwoDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.BayerTwoDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.BayerTwo,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BilaterialBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BilaterialBlurParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\n\n@FilterInject\ninternal class BilaterialBlurFilter(\n    override val value: BilaterialBlurParams = BilaterialBlurParams.Default\n) : Transformation<Bitmap>, Filter.BilaterialBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.bilateralBlur(\n        bitmap = input,\n        spatialSigma = value.spatialSigma,\n        rangeSigma = value.rangeSigma,\n        edgeMode = value.edgeMode.toEdgeMode(),\n        borderScalar = Scalar.ZEROS,\n        kernelSize = 2 * value.radius + 1\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BlackAndWhiteFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageLuminanceFilter\n\n@FilterInject\ninternal class BlackAndWhiteFilter(\n    override val value: Unit = Unit,\n) : GPUFilterTransformation(), Filter.BlackAndWhite {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageLuminanceFilter()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BlackHatFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphKernels\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\n\n@FilterInject\ninternal class BlackHatFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : Transformation<Bitmap>, Filter.BlackHat {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = if (value.second) {\n            MorphKernels.circle(value.first.toInt())\n        } else {\n            MorphKernels.box(value.first.toInt())\n        },\n        morphOp = MorphOp.BLACKHAT,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.toInt(),\n        kernelWidth = value.first.toInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BleachBypassFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class BleachBypassFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.BleachBypass {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_bleach_bypass))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BlockGlitchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class BlockGlitchFilter(\n    override val value: Pair<Float, Float> = 0.02f to 0.5f,\n) : Transformation<Bitmap>, Filter.BlockGlitch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.blockGlitch(\n        src = input,\n        blockSizeFraction = value.first,\n        strength = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BloomFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BloomParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class BloomFilter(\n    override val value: BloomParams = BloomParams.Default\n) : Transformation<Bitmap>, Filter.Bloom {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.bloom(\n        src = input,\n        threshold = value.threshold,\n        intensity = value.intensity,\n        radius = value.radius,\n        softKnee = value.softKnee,\n        exposure = value.exposure,\n        gamma = value.gamma\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BokehFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class BokehFilter(\n    override val value: Pair<Float, Float> = 6f to 6f\n) : Transformation<Bitmap>, Filter.Bokeh {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = Aire.getBokehKernel(\n            kernelSize = value.first.roundToInt(),\n            sides = value.second.roundToInt()\n        ),\n        morphOp = MorphOp.DILATE,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.roundToInt(),\n        kernelWidth = value.first.roundToInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BorderFrameFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class BorderFrameFilter(\n    override val value: Triple<Float, Float, ColorModel> = Triple(20f, 40f, Color.White.toModel())\n) : Transformation<Bitmap>, Filter.BorderFrame {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap {\n        val horizontal = value.first.roundToInt()\n        val vertical = value.second.roundToInt()\n\n        return createBitmap(\n            width = input.width + horizontal * 2,\n            height = input.height + vertical * 2\n        ).applyCanvas {\n            drawColor(value.third.colorInt)\n\n            drawBitmap(\n                bitmap = input,\n                position = Position.Center\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class BoxBlurFilter(\n    override val value: Float = 10f,\n) : Transformation<Bitmap>, Filter.BoxBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.boxBlur(\n        bitmap = input,\n        kernelSize = 2 * value.toInt() + 1\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BrightnessFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class BrightnessFilter(\n    override val value: Float = 0.5f,\n) : Transformation<Bitmap>, Filter.Brightness {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.brightness(\n        bitmap = input,\n        bias = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BrowniFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class BrowniFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Browni {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.BROWNI).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BulgeDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport android.graphics.PointF\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageBulgeDistortionFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class BulgeDistortionFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.5f,\n) : GPUFilterTransformation(), Filter.BulgeDistortion {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageBulgeDistortionFilter(\n        /* radius = */ value.first,\n        /* scale = */value.second,\n        /* center = */PointF(0.5f, 0.5f)\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/BurkesDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class BurkesDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.BurkesDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Burkes,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CGAColorSpaceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageCGAColorspaceFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class CGAColorSpaceFilter(\n    override val value: Unit = Unit,\n) : GPUFilterTransformation(), Filter.CGAColorSpace {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageCGAColorspaceFilter()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CandlelightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class CandlelightFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.Candlelight {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_candlelight))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CannyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.image_processing.ImageProcessing\n\n@FilterInject\ninternal class CannyFilter(\n    override val value: Pair<Float, Float> = 100f to 200f\n) : Transformation<Bitmap>, Filter.Canny {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ImageProcessing.canny(\n        bitmap = input,\n        thresholdOne = value.first,\n        thresholdTwo = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CaramelDarknessFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class CaramelDarknessFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.CaramelDarkness {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.CARAMEL_DARKNESS).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CelluloidFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class CelluloidFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.Celluloid {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_celluloid))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ChannelMixFilter.kt",
    "content": "package com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.ChannelMixFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ChannelMixParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class ChannelMixFilter(\n    override val value: ChannelMixParams = ChannelMixParams.Default\n) : JhFilterTransformation(), Filter.ChannelMix {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = ChannelMixFilter().apply {\n        blueGreen = value.blueGreen\n        redBlue = value.redBlue\n        greenRed = value.greenRed\n        intoR = value.intoR\n        intoG = value.intoG\n        intoB = value.intoB\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CircleBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ConvolveKernels\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.convolution.convolve2D\n\n@FilterInject\ninternal class CircleBlurFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.CircleBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.convolve2D(\n        input = input,\n        kernelProducer = ConvolveKernels::circle,\n        size = value.roundTo(NEAREST_ODD_ROUNDING).toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CirclePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class CirclePixelationFilter(\n    override val value: Float = 24f,\n) : Transformation<Bitmap>, Filter.CirclePixelation {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { circle(value) }\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class ClaheFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.5f, 8f, 8f)\n) : Transformation<Bitmap>, Filter.Clahe {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.clahe(\n        bitmap = input,\n        threshold = value.first,\n        gridSizeHorizontal = value.second.roundToInt(),\n        gridSizeVertical = value.third.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheHSLFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ClaheHSLFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : Transformation<Bitmap>, Filter.ClaheHSL {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.claheHSL(\n        bitmap = input,\n        threshold = value.threshold,\n        gridSizeHorizontal = value.gridSizeHorizontal,\n        gridSizeVertical = value.gridSizeVertical,\n        binsCount = value.binsCount\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheHSVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ClaheHSVFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : Transformation<Bitmap>, Filter.ClaheHSV {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.claheHSV(\n        bitmap = input,\n        threshold = value.threshold,\n        gridSizeHorizontal = value.gridSizeHorizontal,\n        gridSizeVertical = value.gridSizeVertical,\n        binsCount = value.binsCount\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheJzazbzFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ClaheJzazbzFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : Transformation<Bitmap>, Filter.ClaheJzazbz {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.claheJzazbz(\n        bitmap = input,\n        threshold = value.threshold,\n        gridSizeHorizontal = value.gridSizeHorizontal,\n        gridSizeVertical = value.gridSizeVertical,\n        binsCount = value.binsCount\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheLABFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ClaheLABFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : Transformation<Bitmap>, Filter.ClaheLAB {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.claheLAB(\n        bitmap = input,\n        threshold = value.threshold,\n        gridSizeHorizontal = value.gridSizeHorizontal,\n        gridSizeVertical = value.gridSizeVertical,\n        binsCount = value.binsCount\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheLUVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ClaheLUVFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : Transformation<Bitmap>, Filter.ClaheLUV {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.claheLUV(\n        bitmap = input,\n        threshold = value.threshold,\n        gridSizeHorizontal = value.gridSizeHorizontal,\n        gridSizeVertical = value.gridSizeVertical,\n        binsCount = value.binsCount\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheOklabFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ClaheOklabFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : Transformation<Bitmap>, Filter.ClaheOklab {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.claheOklab(\n        bitmap = input,\n        threshold = value.threshold,\n        gridSizeHorizontal = value.gridSizeHorizontal,\n        gridSizeVertical = value.gridSizeVertical,\n        binsCount = value.binsCount\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClaheOklchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ClaheOklchFilter(\n    override val value: ClaheParams = ClaheParams.Default\n) : Transformation<Bitmap>, Filter.ClaheOklch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.claheOklch(\n        bitmap = input,\n        threshold = value.threshold,\n        gridSizeHorizontal = value.gridSizeHorizontal,\n        gridSizeVertical = value.gridSizeVertical,\n        binsCount = value.binsCount\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ClosingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphKernels\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\n\n@FilterInject\ninternal class ClosingFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : Transformation<Bitmap>, Filter.Closing {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = if (value.second) {\n            MorphKernels.circle(value.first.toInt())\n        } else {\n            MorphKernels.box(value.first.toInt())\n        },\n        morphOp = MorphOp.CLOSING,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.toInt(),\n        kernelWidth = value.first.toInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/Clustered2x2DitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class Clustered2x2DitheringFilter(\n    override val value: Boolean = false,\n) : Transformation<Bitmap>, Filter.Clustered2x2Dithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Clustered2x2,\n        isGrayScale = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/Clustered4x4DitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class Clustered4x4DitheringFilter(\n    override val value: Boolean = false,\n) : Transformation<Bitmap>, Filter.Clustered4x4Dithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Clustered4x4,\n        isGrayScale = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/Clustered8x8DitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class Clustered8x8DitheringFilter(\n    override val value: Boolean = false,\n) : Transformation<Bitmap>, Filter.Clustered8x8Dithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Clustered8x8,\n        isGrayScale = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CodaChromeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class CodaChromeFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.CodaChrome {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.CODA_CHROME).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CoffeeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class CoffeeFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.Coffee {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_coffee))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorAnomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ColorAnomalyFilter(\n    override val value: Float = 0.56f\n) : Transformation<Bitmap>, Filter.ColorAnomaly {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = AldridgeFilter(0.5f to value).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorBalanceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageColorBalanceFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class ColorBalanceFilter(\n    override val value: FloatArray = floatArrayOf(\n        0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f\n    ),\n) : GPUFilterTransformation(), Filter.ColorBalance {\n\n    override val cacheKey: String\n        get() = value.contentHashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageColorBalanceFilter().apply {\n        setHighlights(value.take(3).toFloatArray())\n        setMidtones(floatArrayOf(value[3], value[4], value[6]))\n        setShowdows(value.takeLast(3).toFloatArray())\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorExplosionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ColorExplosionFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.ColorExplosion {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.COLOR_EXPLOSION).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorHalftoneFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.ColorHalftoneFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class ColorHalftoneFilter(\n    override val value: Quad<Float, Float, Float, Float> = Quad(\n        first = 2f,\n        second = 108f,\n        third = 162f,\n        fourth = 90f\n    )\n) : JhFilterTransformation(), Filter.ColorHalftone {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = ColorHalftoneFilter().apply {\n        setdotRadius(value.first)\n        cyanScreenAngle = Math.toRadians(value.second.toDouble()).toFloat()\n        magentaScreenAngle = Math.toRadians(value.third.toDouble()).toFloat()\n        yellowScreenAngle = Math.toRadians(value.fourth.toDouble()).toFloat()\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorMapFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.ColorMapType\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.ColorMapTransformation\n\n@FilterInject\ninternal class AutumnFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.AUTUMN), Filter.Autumn\n\n@FilterInject\ninternal class BoneFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.BONE), Filter.Bone\n\n@FilterInject\ninternal class JetFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.JET), Filter.Jet\n\n@FilterInject\ninternal class WinterFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.WINTER), Filter.Winter\n\n@FilterInject\ninternal class RainbowFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.RAINBOW), Filter.Rainbow\n\n@FilterInject\ninternal class OceanFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.OCEAN), Filter.Ocean\n\n@FilterInject\ninternal class SummerFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.SUMMER), Filter.Summer\n\n@FilterInject\ninternal class SpringFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.SPRING), Filter.Spring\n\n@FilterInject\ninternal class CoolVariantFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.COOL), Filter.CoolVariant\n\n@FilterInject\ninternal class HsvFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.HSV), Filter.Hsv\n\n@FilterInject\ninternal class PinkFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.PINK), Filter.Pink\n\n@FilterInject\ninternal class HotFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.HOT), Filter.Hot\n\n@FilterInject\ninternal class ParulaFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.PARULA), Filter.Parula\n\n@FilterInject\ninternal class MagmaFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.MAGMA), Filter.Magma\n\n@FilterInject\ninternal class InfernoFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.INFERNO), Filter.Inferno\n\n@FilterInject\ninternal class PlasmaFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.PLASMA), Filter.Plasma\n\n@FilterInject\ninternal class ViridisFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.VIRIDIS), Filter.Viridis\n\n@FilterInject\ninternal class CividisFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.CIVIDIS), Filter.Cividis\n\n@FilterInject\ninternal class TwilightFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.TWILIGHT), Filter.Twilight\n\n@FilterInject\ninternal class TwilightShiftedFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.TWILIGHT_SHIFTED), Filter.TwilightShifted\n\n@FilterInject\ninternal class TurboFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.TURBO), Filter.Turbo\n\n@FilterInject\ninternal class DeepGreenFilter(\n    override val value: Unit = Unit\n) : ColorMapTransformation(ColorMapType.DEEPGREEN), Filter.DeepGreen"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorMatrix3x3Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ColorMatrix3x3Filter(\n    override val value: FloatArray = floatArrayOf(\n        1.0f, 0.0f, 0.0f,\n        0.0f, 1.0f, 0.0f,\n        0.0f, 0.0f, 1.0f,\n    ),\n) : Transformation<Bitmap>, Filter.ColorMatrix3x3 {\n\n    override val cacheKey: String\n        get() = value.contentHashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.colorMatrix(\n        bitmap = input,\n        colorMatrix = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorMatrix4x4Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageColorMatrixFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class ColorMatrix4x4Filter(\n    override val value: FloatArray = floatArrayOf(\n        1.0f, 0.0f, 0.0f, 0.0f,\n        0.0f, 1.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 1.0f, 0.0f,\n        0.0f, 0.0f, 0.0f, 1.0f\n    ),\n) : GPUFilterTransformation(), Filter.ColorMatrix4x4 {\n\n    override val cacheKey: String\n        get() = value.contentHashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageColorMatrixFilter(1f, value)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorOverlayFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterValueWrapper\nimport com.t8rin.imagetoolbox.core.filters.domain.model.wrap\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class ColorOverlayFilter(\n    override val value: FilterValueWrapper<ColorModel> = Color.Yellow.copy(0.3f).toModel().wrap(),\n) : Transformation<Bitmap>, Filter.ColorOverlay {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.drawColorAbove(\n        input = input,\n        color = value.wrapped.colorInt\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorPosterFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\nimport com.t8rin.trickle.TrickleUtils\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class ColorPosterFilter(\n    override val value: Pair<Float, ColorModel> = 0.5f to Color(0xFF4DFFE4).toModel()\n) : Transformation<Bitmap>, Filter.ColorPoster {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.colorPosterize(\n        input = input,\n        colors = TrickleUtils.generateShades(\n            color = value.second.colorInt,\n            shadeStep = (50 * value.first).coerceAtLeast(1f).roundToInt()\n        ).toIntArray()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ColorfulSwirlFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ColorfulSwirlFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.ColorfulSwirl {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.COLORFUL_SWIRL).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ContourFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.jhlabs.ContourFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class ContourFilter(\n    override val value: Quad<Float, Float, Float, ColorModel> = Quad(\n        first = 5f,\n        second = 1f,\n        third = 0f,\n        fourth = Color(0xff000000).toModel()\n    )\n) : JhFilterTransformation(), Filter.Contour {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = ContourFilter().apply {\n        levels = value.first\n        scale = value.second\n        offset = value.third\n        contourColor = value.fourth.colorInt\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ContrastFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ContrastFilter(\n    override val value: Float = 2f,\n) : Transformation<Bitmap>, Filter.Contrast {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.contrast(\n        bitmap = input,\n        gain = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ConvexFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ConvexFilter(\n    override val value: Float = 3f,\n) : Transformation<Bitmap>, Filter.Convex {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.convex(\n        bitmap = input,\n        strength = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/Convolution3x3Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.convolution.convolve2D\n\n@FilterInject\ninternal class Convolution3x3Filter(\n    override val value: FloatArray = floatArrayOf(\n        0.0f, 0.0f, 0.0f,\n        0.0f, 1.0f, 0.0f,\n        0.0f, 0.0f, 0.0f\n    ),\n) : Transformation<Bitmap>, Filter.Convolution3x3 {\n\n    override val cacheKey: String\n        get() = value.contentHashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.convolve2D(\n        input = input,\n        kernelProducer = { value },\n        size = 3\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CoolFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class CoolFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Cool {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.COOL).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CopyMoveDetectionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.forensics.ImageForensics\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class CopyMoveDetectionFilter(\n    override val value: Pair<Float, Float> = 4f to 1f\n) : Transformation<Bitmap>, Filter.CopyMoveDetection {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ImageForensics.detectCopyMove(\n        input = input,\n        retain = value.first.roundToInt(),\n        qCoefficent = value.second.toDouble()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CropOrPerspectiveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.CropOrPerspectiveParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.auto_straight.AutoStraighten\nimport com.t8rin.opencv_tools.auto_straight.model.Corners\nimport com.t8rin.opencv_tools.auto_straight.model.PointD\nimport com.t8rin.opencv_tools.auto_straight.model.StraightenMode\n\n@FilterInject\ninternal class CropOrPerspectiveFilter(\n    override val value: CropOrPerspectiveParams = CropOrPerspectiveParams.Default\n) : Transformation<Bitmap>, Filter.CropOrPerspective {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = AutoStraighten.process(\n        input = input,\n        mode = StraightenMode.Manual(\n            corners = Corners(\n                topLeft = PointD(\n                    x = value.topLeft.first.toDouble(),\n                    y = value.topLeft.second.toDouble()\n                ),\n                topRight = PointD(\n                    x = value.topRight.first.toDouble(),\n                    y = value.topRight.second.toDouble()\n                ),\n                bottomLeft = PointD(\n                    x = value.bottomLeft.first.toDouble(),\n                    y = value.bottomLeft.second.toDouble()\n                ),\n                bottomRight = PointD(\n                    x = value.bottomRight.first.toDouble(),\n                    y = value.bottomRight.second.toDouble()\n                ),\n                isAbsolute = value.isAbsolute\n            )\n        )\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CropToContentFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class CropToContentFilter(\n    override val value: Pair<Float, ColorModel> = 0f to Color.Black.toModel()\n) : Transformation<Bitmap>, Filter.CropToContent {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.cropToContent(\n        input = input,\n        colorToIgnore = value.second.colorInt,\n        tolerance = value.first\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CrossBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ConvolveKernels\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.convolution.convolve2D\n\n@FilterInject\ninternal class CrossBlurFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.CrossBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.convolve2D(\n        input = input,\n        kernelProducer = ConvolveKernels::cross,\n        size = value.roundTo(NEAREST_ODD_ROUNDING).toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CrossPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class CrossPixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.CrossPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { cross(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CrosshatchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageCrosshatchFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class CrosshatchFilter(\n    override val value: Pair<Float, Float> = 0.01f to 0.003f,\n) : GPUFilterTransformation(), Filter.Crosshatch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter =\n        GPUImageCrosshatchFilter(value.first, value.second)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CrtCurvatureFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class CrtCurvatureFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.25f, 0.65f, 0.015f),\n) : Transformation<Bitmap>, Filter.CrtCurvature {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.crtCurvature(\n        src = input,\n        curvature = value.first,\n        vignette = value.second,\n        chroma = value.third\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CrystallizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class CrystallizeFilter(\n    override val value: Pair<Float, ColorModel> = 1f to Color.Transparent.toModel()\n) : Transformation<Bitmap>, Filter.Crystallize {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.crystallize(\n        bitmap = input,\n        numClusters = (input.width * input.height * 0.01f * value.first).toInt(),\n        strokeColor = value.second.colorInt\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CubeLutFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.trickle.Trickle\nimport com.t8rin.trickle.TrickleUtils\n\n@FilterInject\ninternal class CubeLutFilter(\n    override val value: Pair<Float, FileModel> = 1f to FileModel(\"\"),\n) : Transformation<Bitmap>, Filter.CubeLut {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap {\n        if (value.second.uri.isEmpty()) return input\n\n        val lutPath = TrickleUtils.getAbsolutePath(\n            uri = value.second.uri.toUri(),\n            context = appContext\n        )\n\n        return Trickle.applyCubeLut(\n            input = input,\n            cubeLutPath = lutPath,\n            intensity = value.first\n        )\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/CyberpunkFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class CyberpunkFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Cyberpunk {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.CYBERPUNK).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DeepPurpleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class DeepPurpleFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.DeepPurple {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.DEEP_PURPLE).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DehazeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class DehazeFilter(\n    override val value: Pair<Float, Float> = 17f to 0.45f\n) : Transformation<Bitmap>, Filter.Dehaze {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.dehaze(\n        bitmap = input,\n        radius = value.first.roundToInt(),\n        omega = value.second,\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DeskewFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.auto_straight.AutoStraighten\nimport com.t8rin.opencv_tools.auto_straight.model.StraightenMode\n\n@FilterInject\ninternal class DeskewFilter(\n    override val value: Pair<Float, Boolean> = 15f to true\n) : Transformation<Bitmap>, Filter.Deskew {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = AutoStraighten.process(\n        input = input,\n        mode = StraightenMode.Deskew(\n            maxSkew = value.first.toInt(),\n            allowCrop = value.second\n        )\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DespeckleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.DespeckleFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class DespeckleFilter(\n    override val value: Unit = Unit,\n) : JhFilterTransformation(), Filter.Despeckle {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = DespeckleFilter()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DeutaromalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class DeutaromalyFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Deutaromaly {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.DEUTAROMALY).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DeutaronotopiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class DeutaronotopiaFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Deutaronotopia {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.DEUTARONOPIA).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DiamondPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class DiamondPixelationFilter(\n    override val value: Float = 24f,\n) : Transformation<Bitmap>, Filter.DiamondPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { diamond(value) }\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DiffuseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.DiffuseFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class DiffuseFilter(\n    override val value: Float = 4f\n) : JhFilterTransformation(), Filter.Diffuse {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = DiffuseFilter().apply {\n        scale = value\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DigitalCodeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class DigitalCodeFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.DigitalCode {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.DIGITAL_CODE).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DilationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphKernels\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\n\n@FilterInject\ninternal class DilationFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : Transformation<Bitmap>, Filter.Dilation {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = if (value.second) {\n            MorphKernels.circle(value.first.toInt())\n        } else {\n            MorphKernels.box(value.first.toInt())\n        },\n        morphOp = MorphOp.DILATE,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.toInt(),\n        kernelWidth = value.first.toInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DoGFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.DoGFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class DoGFilter(\n    override val value: Pair<Float, Float> = 1f to 2f\n) : JhFilterTransformation(), Filter.DoG {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = DoGFilter().apply {\n        radius1 = value.first\n        radius2 = value.second\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DragoFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class DragoFilter(\n    override val value: Pair<Float, Float> = 1f to 250f\n) : Transformation<Bitmap>, Filter.Drago {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.drago(\n        bitmap = input,\n        exposure = value.first,\n        sdrWhitePoint = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/DropBluesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class DropBluesFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.DropBlues {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_drop_blues))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EdgyAmberFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class EdgyAmberFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.EdgyAmber {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_edgy_amber))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ElectricGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ElectricGradientFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.ElectricGradient {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.ELECTRIC_GRADIENT).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EmbossFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class EmbossFilter(\n    override val value: Float = 1f,\n) : Transformation<Bitmap>, Filter.Emboss {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.emboss(\n        bitmap = input,\n        intensity = value\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EnhancedCirclePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class EnhancedCirclePixelationFilter(\n    override val value: Float = 32f,\n) : Transformation<Bitmap>, Filter.EnhancedCirclePixelation {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { enhancedCircle(value) }\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EnhancedDiamondPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class EnhancedDiamondPixelationFilter(\n    override val value: Float = 48f,\n) : Transformation<Bitmap>, Filter.EnhancedDiamondPixelation {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { enhancedDiamond(value) }\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EnhancedGlitchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.GlitchParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class EnhancedGlitchFilter(\n    override val value: GlitchParams = GlitchParams()\n) : Transformation<Bitmap>, Filter.EnhancedGlitch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.glitch(\n        bitmap = input,\n        channelsShiftX = value.channelsShiftX,\n        channelsShiftY = value.corruptionShiftY,\n        corruptionSize = value.corruptionSize,\n        corruptionCount = value.corruptionCount,\n        corruptionShiftX = value.channelsShiftX,\n        corruptionShiftY = value.corruptionShiftY\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EnhancedOilFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class EnhancedOilFilter(\n    override val value: Float = 10f\n) : Transformation<Bitmap>, Filter.EnhancedOil {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.oil(\n        input = input,\n        oilRange = value.toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EnhancedPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class EnhancedPixelationFilter(\n    override val value: Float = 48f,\n) : Transformation<Bitmap>, Filter.EnhancedPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { enhancedSquare(value) }\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EnhancedZoomBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.EnhancedZoomBlurParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class EnhancedZoomBlurFilter(\n    override val value: EnhancedZoomBlurParams = EnhancedZoomBlurParams.Default,\n) : Transformation<Bitmap>, Filter.EnhancedZoomBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.zoomBlur(\n        bitmap = input,\n        kernelSize = value.radius * 2 + 1,\n        sigma = value.sigma,\n        centerX = value.centerX,\n        centerY = value.centerY,\n        strength = value.strength,\n        angle = value.angle * Math.PI.toFloat() / 180f\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.EqualizeFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class EqualizeFilter(\n    override val value: Unit = Unit\n) : JhFilterTransformation(), Filter.Equalize {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = EqualizeFilter()\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramAdaptiveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class EqualizeHistogramAdaptiveFilter(\n    override val value: Pair<Float, Float> = 3f to 3f\n) : Transformation<Bitmap>, Filter.EqualizeHistogramAdaptive {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHistAdaptive(\n        bitmap = input,\n        gridSizeHorizontal = value.first.roundToInt(),\n        gridSizeVertical = value.second.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramAdaptiveHSLFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class EqualizeHistogramAdaptiveHSLFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : Transformation<Bitmap>, Filter.EqualizeHistogramAdaptiveHSL {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHistAdaptiveHSL(\n        bitmap = input,\n        gridSizeHorizontal = value.first.roundToInt(),\n        gridSizeVertical = value.second.roundToInt(),\n        binsCount = value.third.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramAdaptiveHSVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class EqualizeHistogramAdaptiveHSVFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : Transformation<Bitmap>, Filter.EqualizeHistogramAdaptiveHSV {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHistAdaptiveHSV(\n        bitmap = input,\n        gridSizeHorizontal = value.first.roundToInt(),\n        gridSizeVertical = value.second.roundToInt(),\n        binsCount = value.third.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramAdaptiveLABFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class EqualizeHistogramAdaptiveLABFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : Transformation<Bitmap>, Filter.EqualizeHistogramAdaptiveLAB {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHistAdaptiveLAB(\n        bitmap = input,\n        gridSizeHorizontal = value.first.roundToInt(),\n        gridSizeVertical = value.second.roundToInt(),\n        binsCount = value.third.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramAdaptiveLUVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class EqualizeHistogramAdaptiveLUVFilter(\n    override val value: Triple<Float, Float, Float> = Triple(3f, 3f, 128f)\n) : Transformation<Bitmap>, Filter.EqualizeHistogramAdaptiveLUV {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHistAdaptiveLUV(\n        bitmap = input,\n        gridSizeHorizontal = value.first.roundToInt(),\n        gridSizeVertical = value.second.roundToInt(),\n        binsCount = value.third.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class EqualizeHistogramFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.EqualizeHistogram {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHist(\n        bitmap = input\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramHSVFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class EqualizeHistogramHSVFilter(\n    override val value: Float = 128f\n) : Transformation<Bitmap>, Filter.EqualizeHistogramHSV {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHistHSV(\n        bitmap = input,\n        binsCount = value.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/EqualizeHistogramPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class EqualizeHistogramPixelationFilter(\n    override val value: Pair<Float, Float> = 50f to 50f\n) : Transformation<Bitmap>, Filter.EqualizeHistogramPixelation {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.equalizeHistSquares(\n        bitmap = input,\n        gridSizeHorizontal = value.first.roundToInt(),\n        gridSizeVertical = value.second.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ErodeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphKernels\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\n\n@FilterInject\ninternal class ErodeFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : Transformation<Bitmap>, Filter.Erode {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = if (value.second) {\n            MorphKernels.circle(value.first.toInt())\n        } else {\n            MorphKernels.box(value.first.toInt())\n        },\n        morphOp = MorphOp.ERODE,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.toInt(),\n        kernelWidth = value.first.toInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ErrorLevelAnalysisFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.forensics.ImageForensics\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class ErrorLevelAnalysisFilter(\n    override val value: Float = 90f\n) : Transformation<Bitmap>, Filter.ErrorLevelAnalysis {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ImageForensics.errorLevelAnalysis(\n        input = input,\n        quality = value.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ExposureFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageExposureFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class ExposureFilter(\n    override val value: Float = 1f,\n) : GPUFilterTransformation(), Filter.Exposure {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageExposureFilter(value)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FallColorsFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class FallColorsFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.FallColors {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_fall_colors))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FalseColorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.blue\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.green\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.red\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFalseColorFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class FalseColorFilter(\n    override val value: Pair<ColorModel, ColorModel> = Color.Yellow.toModel() to Color.Magenta.toModel(),\n) : GPUFilterTransformation(), Filter.FalseColor {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageFalseColorFilter(\n        value.first.red,\n        value.first.green,\n        value.first.blue,\n        value.second.red,\n        value.second.green,\n        value.second.blue\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FalseFloydSteinbergDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class FalseFloydSteinbergDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.FalseFloydSteinbergDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.FalseFloydSteinberg,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FantasyLandscapeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class FantasyLandscapeFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.FantasyLandscape {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.FANTASY_LANDSCAPE).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FastBilaterialBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class FastBilaterialBlurFilter(\n    override val value: Triple<Float, Float, Float> = Triple(11f, 10f, 3f),\n) : Transformation<Bitmap>, Filter.FastBilaterialBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.fastBilateralBlur(\n        bitmap = input,\n        spatialSigma = value.second,\n        rangeSigma = value.third,\n        kernelSize = value.first.roundTo(NEAREST_ODD_ROUNDING).toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FastBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class FastBlurFilter(\n    override val value: Pair<Float, Float> = 0.5f to 5f,\n) : Transformation<Bitmap>, Filter.FastBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.fastBlur(\n        bitmap = input,\n        scale = value.first,\n        radius = value.second.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FastGaussianBlur2DFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class FastGaussianBlur2DFilter(\n    override val value: Pair<Float, BlurEdgeMode> = 10f to BlurEdgeMode.Reflect101\n) : Transformation<Bitmap>, Filter.FastGaussianBlur2D {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.fastGaussian2Degree(\n        bitmap = input,\n        verticalRadius = value.first.roundToInt(),\n        horizontalRadius = value.first.roundToInt(),\n        edgeMode = value.second.toEdgeMode()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FastGaussianBlur3DFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class FastGaussianBlur3DFilter(\n    override val value: Pair<Float, BlurEdgeMode> = 10f to BlurEdgeMode.Reflect101\n) : Transformation<Bitmap>, Filter.FastGaussianBlur3D {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.fastGaussian3Degree(\n        bitmap = input,\n        verticalRadius = value.first.roundToInt(),\n        horizontalRadius = value.first.roundToInt(),\n        edgeMode = value.second.toEdgeMode()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FastGaussianBlur4DFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class FastGaussianBlur4DFilter(\n    override val value: Float = 10f\n) : Transformation<Bitmap>, Filter.FastGaussianBlur4D {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.fastGaussian4Degree(\n        bitmap = input,\n        radius = value.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FilmStock50Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class FilmStock50Filter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.FilmStock50 {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_filmstock_50))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FloydSteinbergDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class FloydSteinbergDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.FloydSteinbergDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.FloydSteinberg,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FoggyNightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class FoggyNightFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.FoggyNight {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_foggy_night))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FractalGlassFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class FractalGlassFilter(\n    override val value: Pair<Float, Float> = 0.02f to 0.02f\n) : Transformation<Bitmap>, Filter.FractalGlass {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.fractalGlass(\n        bitmap = input,\n        glassSize = value.first,\n        amplitude = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/FuturisticGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class FuturisticGradientFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.FuturisticGradient {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.FUTURISTIC_GRADIENT).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GammaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class GammaFilter(\n    override val value: Float = 1.5f,\n) : Transformation<Bitmap>, Filter.Gamma {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.gamma(\n        bitmap = input,\n        gamma = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GaussianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.GaussianPreciseLevel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\n\n@FilterInject\ninternal class GaussianBlurFilter(\n    override val value: Triple<Float, Float, BlurEdgeMode> = Triple(\n        25f,\n        10f,\n        BlurEdgeMode.Reflect101\n    ),\n) : Transformation<Bitmap>, Filter.GaussianBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.gaussianBlur(\n        bitmap = input,\n        verticalKernelSize = 2 * value.first.toInt() + 1,\n        horizontalKernelSize = 2 * value.first.toInt() + 1,\n        verticalSigma = value.second,\n        horizontalSigma = value.second,\n        edgeMode = value.third.toEdgeMode(),\n        gaussianPreciseLevel = GaussianPreciseLevel.INTEGRAL\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GaussianBoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class GaussianBoxBlurFilter(\n    override val value: Float = 10f\n) : Transformation<Bitmap>, Filter.GaussianBoxBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.gaussianBoxBlur(\n        bitmap = input,\n        sigma = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GlassSphereRefractionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport android.graphics.PointF\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageGlassSphereFilter\n\n@FilterInject\ninternal class GlassSphereRefractionFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.71f,\n) : GPUFilterTransformation(), Filter.GlassSphereRefraction {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageGlassSphereFilter(\n        PointF(0.5f, 0.5f),\n        value.first, value.second\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GlitchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.glitch.GlitchTool\n\n@FilterInject\ninternal class GlitchFilter(\n    override val value: Triple<Float, Float, Float> = Triple(20f, 15f, 9f),\n) : Transformation<Bitmap>, Filter.Glitch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = GlitchTool.jpegGlitch(\n        input = input,\n        amount = value.first.toInt(),\n        seed = value.second.toInt(),\n        iterations = value.third.toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GlitchVariantFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class GlitchVariantFilter(\n    override val value: Triple<Float, Float, Float> = Triple(30f, 0.25f, 0.3f),\n) : Transformation<Bitmap>, Filter.GlitchVariant {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.glitchVariant(\n        src = input,\n        iterations = value.first.roundToInt(),\n        maxOffsetFraction = value.second,\n        channelShiftFraction = value.third\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GlowFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.GlowFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class GlowFilter(\n    override val value: Float = 0.5f\n) : JhFilterTransformation(), Filter.Glow {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = GlowFilter().apply {\n        amount = value\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GoldenForestFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class GoldenForestFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.GoldenForest {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_golden_forest))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GoldenHourFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class GoldenHourFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.GoldenHour {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.GOLDEN_HOUR).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GothamFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class GothamFilter(\n    override val value: Unit = Unit,\n) : Transformation<Bitmap>, Filter.Gotham {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Trickle.gotham(input)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GrainFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class GrainFilter(\n    override val value: Float = 0.75f\n) : Transformation<Bitmap>, Filter.Grain {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.grain(\n        bitmap = input,\n        intensity = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GrayscaleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class GrayscaleFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.299f, 0.587f, 0.114f)\n) : Transformation<Bitmap>, Filter.Grayscale {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.grayscale(\n        bitmap = input,\n        rPrimary = value.first,\n        gPrimary = value.second,\n        bPrimary = value.third\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GreenSunFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class GreenSunFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.GreenSun {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.GREEN_SUN).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/GreenishFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class GreenishFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.Greenish {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_greenish))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HDRFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class HDRFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.HDR {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.hdr(input)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HableFilmicToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class HableFilmicToneMappingFilter(\n    override val value: Float = 1f,\n) : Transformation<Bitmap>, Filter.HableFilmicToneMapping {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.hableFilmicToneMapping(\n        bitmap = input,\n        exposure = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HalftoneFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageHalftoneFilter\n\n@FilterInject\ninternal class HalftoneFilter(\n    override val value: Float = 0.005f,\n) : GPUFilterTransformation(), Filter.Halftone {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageHalftoneFilter(value)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HazeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageHazeFilter\n\n@FilterInject\ninternal class HazeFilter(\n    override val value: Pair<Float, Float> = 0.2f to 0f,\n) : GPUFilterTransformation(), Filter.Haze {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageHazeFilter(value.first, value.second)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HejlBurgessToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class HejlBurgessToneMappingFilter(\n    override val value: Float = 1f,\n) : Transformation<Bitmap>, Filter.HejlBurgessToneMapping {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.hejlBurgessToneMapping(\n        bitmap = input,\n        exposure = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HighlightsAndShadowsFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.gpu.GPUImageHighlightShadowWideRangeFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class HighlightsAndShadowsFilter(\n    override val value: Float = 0.25f,\n) : GPUFilterTransformation(), Filter.HighlightsAndShadows {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageHighlightShadowWideRangeFilter(value, 1f)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HorizontalWindStaggerFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toAbgr\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\n\n@FilterInject\ninternal class HorizontalWindStaggerFilter(\n    override val value: Triple<Float, Int, ColorModel> = Triple(\n        first = 0.2f,\n        second = 90,\n        third = Color.Transparent.toModel()\n    )\n) : Transformation<Bitmap>, Filter.HorizontalWindStagger {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.horizontalWindStagger(\n        bitmap = input,\n        windStrength = value.first,\n        streamsCount = value.second,\n        clearColor = value.third.colorInt.toColor().toAbgr()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HotSummerFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class HotSummerFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.HotSummer {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.HOT_SUMMER).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/HueFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageHueFilter\n\n@FilterInject\ninternal class HueFilter(\n    override val value: Float = 90f,\n) : GPUFilterTransformation(), Filter.Hue {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageHueFilter(value)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/JarvisJudiceNinkeDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class JarvisJudiceNinkeDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.JarvisJudiceNinkeDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.JarvisJudiceNinke,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/KaleidoscopeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.JhFilter\nimport com.jhlabs.KaleidoscopeFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.KaleidoscopeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class KaleidoscopeFilter(\n    override val value: KaleidoscopeParams = KaleidoscopeParams.Default\n) : JhFilterTransformation(), Filter.Kaleidoscope {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = KaleidoscopeFilter().apply {\n        angle = value.angle\n        angle2 = value.angle2\n        centreX = value.centreX\n        centreY = value.centreY\n        sides = value.sides\n        radius = value.radius\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/KodakFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class KodakFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.Kodak {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_kodak))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/KuwaharaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageKuwaharaFilter\n\n@FilterInject\ninternal class KuwaharaFilter(\n    override val value: Float = 9f,\n) : GPUFilterTransformation(), Filter.Kuwahara {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageKuwaharaFilter(value.toInt())\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LUT512x512Filter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.scale\nimport com.t8rin.imagetoolbox.core.data.utils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.image.loadBitmap\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class LUT512x512Filter(\n    override val value: Pair<Float, ImageModel> = 1f to ImageModel(R.drawable.lookup),\n) : Transformation<Bitmap>, Filter.LUT512x512 {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap {\n        val lutBitmap = value.second.data.loadBitmap(512)?.takeIf {\n            it.safeAspectRatio == 1f\n        } ?: return input\n\n        return Trickle.applyLut(\n            input = input,\n            lutBitmap = lutBitmap.scale(\n                width = 512,\n                height = 512\n            ),\n            intensity = value.first\n        )\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LaplacianFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageLaplacianFilter\n\n@FilterInject\ninternal class LaplacianFilter(\n    override val value: Unit = Unit,\n) : GPUFilterTransformation(), Filter.Laplacian {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageLaplacianFilter()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LaplacianSimpleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class LaplacianSimpleFilter(\n    override val value: Unit = Unit,\n) : Transformation<Bitmap>, Filter.LaplacianSimple {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.laplacian(\n        bitmap = input,\n        edgeMode = EdgeMode.REFLECT_101,\n        scalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LavenderDreamFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class LavenderDreamFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.LavenderDream {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.LAVENDER_DREAM).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LeftToRightDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class LeftToRightDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.LeftToRightDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.LeftToRight,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LemonadeLightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class LemonadeLightFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.LemonadeLight {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.LEMONADE_LIGHT).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LensCorrectionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.model.FileModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.lens_correction.LensCorrection\nimport com.t8rin.opencv_tools.lens_correction.model.SAMPLE_LENS_PROFILE\n\n@FilterInject\ninternal class LensCorrectionFilter(\n    override val value: Pair<Float, FileModel> = 1f to FileModel(\"\"),\n) : Transformation<Bitmap>, Filter.LensCorrection {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = value.second.uri.let { uri ->\n        if (uri.isEmpty()) {\n            LensCorrection.undistort(\n                bitmap = input,\n                lensDataJson = LensCorrection.SAMPLE_LENS_PROFILE,\n                intensity = value.first.toDouble()\n            )\n        } else {\n            LensCorrection.undistort(\n                bitmap = input,\n                lensDataUri = uri.toUri(),\n                intensity = value.first.toDouble()\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearBoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toFunc\n\n@FilterInject\ninternal class LinearBoxBlurFilter(\n    override val value: Pair<Int, TransferFunc> = 10 to TransferFunc.SRGB\n) : Transformation<Bitmap>, Filter.LinearBoxBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.linearBoxBlur(\n        bitmap = input,\n        kernelSize = 2 * value.first + 1,\n        transferFunction = value.second.toFunc()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearFastGaussianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toFunc\n\n@FilterInject\ninternal class LinearFastGaussianBlurFilter(\n    override val value: Triple<Int, TransferFunc, BlurEdgeMode> = Triple(\n        first = 10,\n        second = TransferFunc.SRGB,\n        third = BlurEdgeMode.Reflect101\n    )\n) : Transformation<Bitmap>, Filter.LinearFastGaussianBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.linearFastGaussian(\n        bitmap = input,\n        verticalRadius = value.first,\n        horizontalRadius = value.first,\n        transferFunction = value.second.toFunc(),\n        edgeMode = value.third.toEdgeMode()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearFastGaussianBlurNextFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toFunc\n\n@FilterInject\ninternal class LinearFastGaussianBlurNextFilter(\n    override val value: Triple<Int, TransferFunc, BlurEdgeMode> = Triple(\n        first = 10,\n        second = TransferFunc.SRGB,\n        third = BlurEdgeMode.Reflect101\n    )\n) : Transformation<Bitmap>, Filter.LinearFastGaussianBlurNext {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.linearFastGaussianNext(\n        bitmap = input,\n        verticalRadius = value.first,\n        horizontalRadius = value.first,\n        transferFunction = value.second.toFunc(),\n        edgeMode = value.third.toEdgeMode()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearGaussianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearGaussianParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toFunc\n\n@FilterInject\ninternal class LinearGaussianBlurFilter(\n    override val value: LinearGaussianParams = LinearGaussianParams.Default\n) : Transformation<Bitmap>, Filter.LinearGaussianBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.linearGaussianBlur(\n        bitmap = input,\n        verticalKernelSize = value.kernelSize.toFloat().roundTo(NEAREST_ODD_ROUNDING).toInt(),\n        horizontalKernelSize = value.kernelSize.toFloat().roundTo(NEAREST_ODD_ROUNDING).toInt(),\n        verticalSigma = value.sigma,\n        horizontalSigma = value.sigma,\n        edgeMode = value.edgeMode.toEdgeMode(),\n        transferFunction = value.transferFunction.toFunc()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearGaussianBoxBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toFunc\n\n@FilterInject\ninternal class LinearGaussianBoxBlurFilter(\n    override val value: Pair<Float, TransferFunc> = 10f to TransferFunc.SRGB\n) : Transformation<Bitmap>, Filter.LinearGaussianBoxBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.linearGaussianBoxBlur(\n        bitmap = input,\n        sigma = value.first,\n        transferFunction = value.second.toFunc()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearStackBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toFunc\n\n@FilterInject\ninternal class LinearStackBlurFilter(\n    override val value: Pair<Int, TransferFunc> = 10 to TransferFunc.SRGB\n) : Transformation<Bitmap>, Filter.LinearStackBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.linearStackBlur(\n        bitmap = input,\n        verticalRadius = value.first,\n        horizontalRadius = value.first,\n        transferFunction = value.second.toFunc()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearTentBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toFunc\n\n@FilterInject\ninternal class LinearTentBlurFilter(\n    override val value: Pair<Float, TransferFunc> = 11f to TransferFunc.SRGB,\n) : Transformation<Bitmap>, Filter.LinearTentBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.linearTentBlur(\n        bitmap = input,\n        sigma = value.first.roundTo(NEAREST_ODD_ROUNDING),\n        transferFunction = value.second.toFunc()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LinearTiltShiftFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearTiltShiftParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class LinearTiltShiftFilter(\n    override val value: LinearTiltShiftParams = LinearTiltShiftParams.Default\n) : Transformation<Bitmap>, Filter.LinearTiltShift {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.horizontalTiltShift(\n        bitmap = input,\n        radius = value.blurRadius.roundToInt(),\n        sigma = value.sigma,\n        anchorX = value.anchorX,\n        anchorY = value.anchorY,\n        tiltRadius = value.holeRadius,\n        angle = value.angle * Math.PI.toFloat() / 180f\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LogarithmicToneMappingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class LogarithmicToneMappingFilter(\n    override val value: Float = 1f,\n) : Transformation<Bitmap>, Filter.LogarithmicToneMapping {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.logarithmicToneMapping(\n        bitmap = input,\n        exposure = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LookupFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageLookupFilter\n\n@FilterInject\ninternal class LookupFilter(\n    override val value: Float = -1f,\n) : GPUFilterTransformation(), Filter.Lookup {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageLookupFilter(value)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LowPolyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class LowPolyFilter(\n    override val value: Pair<Float, Boolean> = 2000f to true\n) : Transformation<Bitmap>, Filter.LowPoly {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.lowPoly(\n        input = input,\n        alphaOrPointCount = value.first.roundToInt().toFloat(),\n        fill = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/LuminanceGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.forensics.ImageForensics\n\n@FilterInject\ninternal class LuminanceGradientFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.LuminanceGradient {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ImageForensics.luminanceGradient(\n        input = input\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MarbleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class MarbleFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.02f, 1f, 1f)\n) : Transformation<Bitmap>, Filter.Marble {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.marble(\n        bitmap = input,\n        intensity = value.first,\n        turbulence = value.second,\n        amplitude = value.third\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MedianBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class MedianBlurFilter(\n    override val value: Float = 10f\n) : Transformation<Bitmap>, Filter.MedianBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode()\n            .toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.medianBlur(\n        bitmap = input,\n        kernelSize = 2 * value.roundToInt() + 1\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MicroMacroPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class MicroMacroPixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.MicroMacroPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { microMacro(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MirrorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.mirror\n\n@FilterInject\ninternal class MirrorFilter(\n    override val value: Pair<Float, MirrorSide> = 0.5f to MirrorSide.LeftToRight,\n) : Transformation<Bitmap>, Filter.Mirror {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = input.mirror(\n        value = value.first,\n        side = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MissEtikateFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class MissEtikateFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.MissEtikate {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_miss_etikate))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MobiusFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class MobiusFilter(\n    override val value: Triple<Float, Float, Float> = Triple(1f, 0.9f, 1f)\n) : Transformation<Bitmap>, Filter.Mobius {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.mobius(\n        bitmap = input,\n        exposure = value.first,\n        transition = value.second,\n        peak = value.third\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MoireFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.moire.Moire\n\n@FilterInject\ninternal class MoireFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Moire {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Moire.remove(input)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MonochromeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.blue\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.green\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.red\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class MonochromeFilter(\n    override val value: Pair<Float, ColorModel> = 1f to Color(\n        red = 0.6f,\n        green = 0.45f,\n        blue = 0.3f,\n        alpha = 1.0f\n    ).toModel(),\n) : Transformation<Bitmap>, Filter.Monochrome {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.monochrome(\n        bitmap = input,\n        color = floatArrayOf(\n            value.second.red,\n            value.second.green,\n            value.second.blue,\n            value.first\n        ),\n        exposure = 1f\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MorphologicalGradientFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphKernels\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\n\n@FilterInject\ninternal class MorphologicalGradientFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : Transformation<Bitmap>, Filter.MorphologicalGradient {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = if (value.second) {\n            MorphKernels.circle(value.first.toInt())\n        } else {\n            MorphKernels.box(value.first.toInt())\n        },\n        morphOp = MorphOp.GRADIENT,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.toInt(),\n        kernelWidth = value.first.toInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/MotionBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toEdgeMode\n\n@FilterInject\ninternal class MotionBlurFilter(\n    override val value: Triple<Int, Float, BlurEdgeMode> = Triple(25, 45f, BlurEdgeMode.Reflect101),\n) : Transformation<Bitmap>, Filter.MotionBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.motionBlur(\n        bitmap = input,\n        kernelSize = value.first.toFloat().roundTo(NEAREST_ODD_ROUNDING).toInt(),\n        angle = value.second,\n        borderMode = value.third.toEdgeMode(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NativeStackBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class NativeStackBlurFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.NativeStackBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.stackBlur(\n        bitmap = input,\n        verticalRadius = value.toInt(),\n        horizontalRadius = value.toInt()\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NegativeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageColorInvertFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class NegativeFilter(\n    override val value: Unit = Unit,\n) : GPUFilterTransformation(), Filter.Negative {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageColorInvertFilter()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NeonFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.wrap\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class NeonFilter(\n    override val value: Triple<Float, Float, ColorModel> = Triple(\n        first = 1f,\n        second = 0.26f,\n        third = Color.Magenta.toModel()\n    )\n) : ChainTransformation<Bitmap>, Filter.Neon {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        SharpenFilter(value.second),\n        SobelEdgeDetectionFilter(value.first),\n        RGBFilter(value.third.wrap())\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NightMagicFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class NightMagicFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.NightMagic {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.NIGHT_MAGIC).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NightVisionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class NightVisionFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.NightVision {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.NIGHT_VISION).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NoiseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class NoiseFilter(\n    override val value: Float = 128f\n) : Transformation<Bitmap>, Filter.Noise {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.noise(\n        input = input,\n        threshold = value.toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NonMaximumSuppressionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageNonMaximumSuppressionFilter\n\n@FilterInject\ninternal class NonMaximumSuppressionFilter(\n    override val value: Unit = Unit,\n) : GPUFilterTransformation(), Filter.NonMaximumSuppression {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageNonMaximumSuppressionFilter()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/NucleusPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class NucleusPixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.NucleusPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { nucleus(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/OffsetFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.jhlabs.JhFilter\nimport com.jhlabs.OffsetFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class OffsetFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.25f\n) : JhFilterTransformation(), Filter.Offset {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = OffsetFilter()\n\n    override fun createFilter(image: Bitmap): JhFilter = OffsetFilter().apply {\n        xOffset = (value.first * image.width).roundToInt()\n        yOffset = (value.second * image.height).roundToInt()\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/OilFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class OilFilter(\n    override val value: Pair<Float, Float> = 4f to 1f\n) : Transformation<Bitmap>, Filter.Oil {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.oil(\n        bitmap = input,\n        radius = value.first.roundToInt(),\n        levels = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/OldTvFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class OldTvFilter(\n    override val value: Unit\n) : ChainTransformation<Bitmap>, Filter.OldTv {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        GrainFilter(0.36f),\n        HazeFilter(0f to 0.3f),\n        MonochromeFilter(1f to Color(0xFF1C3A00).toModel())\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/OpacityFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageOpacityFilter\n\n@FilterInject\ninternal class OpacityFilter(\n    override val value: Float = 0.5f,\n) : GPUFilterTransformation(), Filter.Opacity {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageOpacityFilter(value)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/OpeningFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphKernels\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\n\n@FilterInject\ninternal class OpeningFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : Transformation<Bitmap>, Filter.Opening {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = if (value.second) {\n            MorphKernels.circle(value.first.toInt())\n        } else {\n            MorphKernels.box(value.first.toInt())\n        },\n        morphOp = MorphOp.OPENING,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.toInt(),\n        kernelWidth = value.first.toInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/OrangeHazeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class OrangeHazeFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.OrangeHaze {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.ORANGE_HAZE).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/OrbitalPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class OrbitalPixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.OrbitalPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { orbital(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PaletteTransferFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.image.loadBitmap\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class PaletteTransferFilter(\n    override val value: Pair<Float, ImageModel> = 1f to ImageModel(R.drawable.filter_preview_source_2),\n) : Transformation<Bitmap>, Filter.PaletteTransfer {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap {\n        val reference = value.second.data.loadBitmap(1000) ?: return input\n\n        return Trickle.transferPalette(\n            source = reference,\n            target = input,\n            intensity = value.first\n        )\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PaletteTransferVariantFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PaletteTransferSpace\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.image.loadBitmap\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toSpace\n\n@FilterInject\ninternal class PaletteTransferVariantFilter(\n    override val value: Triple<Float, PaletteTransferSpace, ImageModel> = Triple(\n        first = 1f,\n        second = PaletteTransferSpace.OKLAB,\n        third = ImageModel(R.drawable.filter_preview_source_2)\n    )\n) : Transformation<Bitmap>, Filter.PaletteTransferVariant {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap {\n        val reference = value.third.data.loadBitmap(1000) ?: return input\n\n        return Aire.copyPalette(\n            source = reference,\n            destination = input,\n            colorSpace = value.second.toSpace(),\n            intensity = value.first\n        )\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PastelFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class PastelFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Pastel {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.PASTEL).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PerlinDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class PerlinDistortionFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.02f, 1f, 1f)\n) : Transformation<Bitmap>, Filter.PerlinDistortion {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.perlinDistortion(\n        bitmap = input,\n        intensity = value.first,\n        turbulence = value.second,\n        amplitude = value.third\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PinchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.jhlabs.JhFilter\nimport com.jhlabs.PinchFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.PinchParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\nimport kotlin.math.max\n\n@FilterInject\ninternal class PinchFilter(\n    override val value: PinchParams = PinchParams.Default\n) : JhFilterTransformation(), Filter.Pinch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = PinchFilter()\n\n    override fun createFilter(image: Bitmap): JhFilter = PinchFilter().apply {\n        angle = Math.toRadians(value.angle.toDouble()).toFloat()\n        centreX = value.centreX\n        centreY = value.centreY\n        radius = value.radius * (max(image.width, image.height) / 2f)\n        amount = value.amount\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PinkDreamFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class PinkDreamFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.PinkDream {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.PINK_DREAM).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PixelMeltFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class PixelMeltFilter(\n    override val value: Pair<Float, Float> = 20f to 0.5f,\n) : Transformation<Bitmap>, Filter.PixelMelt {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.pixelMelt(\n        src = input,\n        maxDrop = value.first.roundToInt(),\n        strength = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class PixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.Pixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { square(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PointillizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.JhFilter\nimport com.jhlabs.PointillizeFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class PointillizeFilter(\n    override val value: VoronoiCrystallizeParams = VoronoiCrystallizeParams.Companion.Default\n) : JhFilterTransformation(), Filter.Pointillize {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = PointillizeFilter().apply {\n        edgeThickness = value.borderThickness\n        edgeColor = value.color.colorInt\n        scale = value.scale\n        randomness = value.randomness\n        gridType = value.shape\n        turbulence = value.turbulence\n        angle = Math.toRadians(value.angle.toDouble()).toFloat()\n        stretch = value.stretch\n        amount = value.amount\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PoissonBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class PoissonBlurFilter(\n    override val value: Float = 10f,\n) : Transformation<Bitmap>, Filter.PoissonBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.poissonBlur(\n        bitmap = input,\n        kernelSize = 2 * value.toInt() + 1\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PolarCoordinatesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.JhFilter\nimport com.jhlabs.PolarFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PolarCoordinatesType\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class PolarCoordinatesFilter(\n    override val value: PolarCoordinatesType = PolarCoordinatesType.RECT_TO_POLAR\n) : JhFilterTransformation(), Filter.PolarCoordinates {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = PolarFilter(value.ordinal)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PolaroidFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class PolaroidFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Polaroid {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.POLAROID).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PolkaDotFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class PolkaDotFilter(\n    override val value: Triple<Int, Int, ColorModel> = Triple(\n        first = 10,\n        second = 8,\n        third = Color.Black.toModel()\n    )\n) : Transformation<Bitmap>, Filter.PolkaDot {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = if (value.third.colorInt == Color.Transparent.toArgb()) {\n        Trickle.polkaDot(\n            input = input,\n            dotRadius = value.first,\n            spacing = value.second\n        )\n    } else {\n        Trickle.drawColorBehind(\n            input = Trickle.polkaDot(\n                input = input,\n                dotRadius = value.first,\n                spacing = value.second\n            ),\n            color = value.third.colorInt\n        )\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PopArtFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.toMode\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class PopArtFilter(\n    override val value: Triple<Float, ColorModel, PopArtBlendingMode> = Triple(\n        first = 1f,\n        second = Color.Red.toModel(),\n        third = PopArtBlendingMode.MULTIPLY\n    )\n) : Transformation<Bitmap>, Filter.PopArt {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.popArt(\n        input = input,\n        color = value.second.colorInt,\n        strength = value.first,\n        blendMode = value.third.toMode()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PosterizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImagePosterizeFilter\n\n@FilterInject\ninternal class PosterizeFilter(\n    override val value: Float = 5f,\n) : GPUFilterTransformation(), Filter.Posterize {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImagePosterizeFilter(value.toInt())\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ProtanopiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ProtanopiaFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Protanopia {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.PROTANOPIA).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ProtonomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ProtonomalyFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Protonomaly {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.PROTANOMALY).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PulseGridPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class PulseGridPixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.PulseGridPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { pulseGrid(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/PurpleMistFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class PurpleMistFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.PurpleMist {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.PURPLE_MIST).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/QuantizierFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.AireColorMapper\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class QuantizierFilter(\n    override val value: Float = 256f\n) : Transformation<Bitmap>, Filter.Quantizier {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.palette(\n        bitmap = input,\n        maxColors = value.toInt(),\n        colorMapper = AireColorMapper.COVER_TREE\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RGBFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.blue\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.green\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.red\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterValueWrapper\nimport com.t8rin.imagetoolbox.core.filters.domain.model.wrap\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageRGBFilter\n\n@FilterInject\ninternal class RGBFilter(\n    override val value: FilterValueWrapper<ColorModel> = Color.Green.toModel().wrap(),\n) : GPUFilterTransformation(), Filter.RGB {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageRGBFilter(\n        value.wrapped.red, value.wrapped.green, value.wrapped.blue\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RadialTiltShiftFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RadialTiltShiftParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class RadialTiltShiftFilter(\n    override val value: RadialTiltShiftParams = RadialTiltShiftParams.Default\n) : Transformation<Bitmap>, Filter.RadialTiltShift {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.tiltShift(\n        bitmap = input,\n        radius = value.blurRadius.roundToInt(),\n        sigma = value.sigma,\n        anchorX = value.anchorX,\n        anchorY = value.anchorY,\n        tiltRadius = value.holeRadius\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RadialWeavePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class RadialWeavePixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.RadialWeavePixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { radialWeave(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RainbowWorldFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class RainbowWorldFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.RainbowWorld {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.RAINBOW_WORLD).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RandomDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class RandomDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.RandomDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Random,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RedSwirlFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class RedSwirlFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.RedSwirl {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.RED_SWIRL).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ReduceNoiseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.JhFilter\nimport com.jhlabs.ReduceNoiseFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class ReduceNoiseFilter(\n    override val value: Unit = Unit\n) : JhFilterTransformation(), Filter.ReduceNoise {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = ReduceNoiseFilter()\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RemoveColorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class RemoveColorFilter(\n    override val value: Pair<Float, ColorModel> = 0f to Color(0xFF000000).toModel(),\n) : Transformation<Bitmap>, Filter.RemoveColor {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ReplaceColorFilter(\n        value = Triple(\n            first = value.first,\n            second = value.second,\n            third = Color.Transparent.toModel()\n        )\n    ).transform(input, size)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ReplaceColorFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class ReplaceColorFilter(\n    override val value: Triple<Float, ColorModel, ColorModel> = Triple(\n        first = 0f,\n        second = Color(red = 0.0f, green = 0.0f, blue = 0.0f, alpha = 1.0f).toModel(),\n        third = Color(red = 1.0f, green = 1.0f, blue = 1.0f, alpha = 1.0f).toModel()\n    ),\n) : Transformation<Bitmap>, Filter.ReplaceColor {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.replaceColor(\n        input = input,\n        sourceColor = value.second.colorInt,\n        targetColor = value.third.colorInt,\n        tolerance = value.first\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RetroYellowFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class RetroYellowFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.RetroYellow {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_retro_yellow))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RingBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ConvolveKernels\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.convolution.convolve2D\n\n@FilterInject\ninternal class RingBlurFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.RingBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.convolve2D(\n        input = input,\n        kernelProducer = ConvolveKernels::ring,\n        size = value.roundTo(NEAREST_ODD_ROUNDING).toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/RubberStampFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.jhlabs.JhFilter\nimport com.jhlabs.StampFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RubberStampParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\nimport kotlin.math.max\n\n@FilterInject\ninternal class RubberStampFilter(\n    override val value: RubberStampParams = RubberStampParams.Default\n) : JhFilterTransformation(), Filter.RubberStamp {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = StampFilter()\n\n    override fun createFilter(image: Bitmap): JhFilter = StampFilter().apply {\n        threshold = value.threshold\n        softness = value.softness\n        radius = value.radius * (max(image.width, image.height) / 64f)\n        white = value.firstColor.colorInt\n        black = value.secondColor.colorInt\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SandPaintingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class SandPaintingFilter(\n    override val value: Triple<Int, Int, ColorModel> = Triple(5000, 50, Color.Black.toModel())\n) : Transformation<Bitmap>, Filter.SandPainting {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.drawColorBehind(\n        input = Trickle.sandPainting(\n            input = input,\n            alphaOrPointCount = value.first.toFloat(),\n            threshold = value.second\n        ),\n        color = value.third.colorInt\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SaturationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SaturationFilter(\n    override val value: Pair<Float, Boolean> = 2f to true,\n) : Transformation<Bitmap>, Filter.Saturation {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.saturation(\n        bitmap = input,\n        saturation = value.first,\n        tonemap = value.second\n    )\n\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SeamCarvingFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.opencv_tools.seam_carving.SeamCarver\n\n@FilterInject\ninternal class SeamCarvingFilter(\n    override val value: IntegerSize = IntegerSize.Zero\n) : Transformation<Bitmap>, Filter.SeamCarving {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = if (value.isZero()) {\n        input\n    } else {\n        SeamCarver.carve(\n            bitmap = input,\n            desiredWidth = value.width,\n            desiredHeight = value.height\n        )\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SepiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SepiaFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Sepia {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.SEPIA).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SharpenFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageSharpenFilter\n\n@FilterInject\ninternal class SharpenFilter(\n    override val value: Float = 1f,\n) : GPUFilterTransformation(), Filter.Sharpen {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageSharpenFilter(value)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ShuffleBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class ShuffleBlurFilter(\n    override val value: Pair<Float, Float> = 35f to 1f\n) : Transformation<Bitmap>, Filter.ShuffleBlur {\n\n    private val radiusMapping = listOf(0f, RAD_1) + List(200) {\n        RAD_2 + STEP * it\n    }\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.shuffleBlur(\n        input = input,\n        threshold = value.second,\n        strength = radiusMapping.getOrNull(value.first.roundToInt()) ?: 0f\n    )\n\n    private companion object {\n        private const val RAD_1 = 0.001f\n        private const val RAD_2 = 0.005f\n        private const val STEP = 0.005f\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SideFadeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.applyCanvas\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.data.getPaint\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SideFadeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class SideFadeFilter(\n    override val value: SideFadeParams = SideFadeParams.Relative(FadeSide.Start, 0.5f),\n) : Transformation<Bitmap>, Filter.SideFade {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap {\n        val bitmap = input.copy(input.safeConfig, true).apply { setHasAlpha(true) }\n        val fadeSize: Int = when (value) {\n            is SideFadeParams.Absolute -> value.size\n            is SideFadeParams.Relative -> {\n                when (value.side) {\n                    FadeSide.Start, FadeSide.End -> {\n                        bitmap.width * value.scale\n                    }\n\n                    FadeSide.Bottom, FadeSide.Top -> {\n                        bitmap.height * value.scale\n                    }\n                }.roundToInt()\n            }\n        }\n        val strength = when (value) {\n            is SideFadeParams.Absolute -> value.strength\n            is SideFadeParams.Relative -> 1f\n        }\n\n        return bitmap.applyCanvas {\n            drawPaint(\n                value.side.getPaint(\n                    bmp = input,\n                    length = fadeSize,\n                    strength = strength\n                )\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SierraDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class SierraDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.SierraDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Sierra,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SierraLiteDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class SierraLiteDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.SierraLiteDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.SierraLite,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SimpleOldTvFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class SimpleOldTvFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.SimpleOldTv {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.tv(input)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SimpleSketchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class SimpleSketchFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.SimpleSketch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.sketch(input)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SimpleSolarizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.JhFilter\nimport com.jhlabs.SolarizeFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class SimpleSolarizeFilter(\n    override val value: Unit = Unit\n) : JhFilterTransformation(), Filter.SimpleSolarize {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = SolarizeFilter()\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SimpleThresholdDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class SimpleThresholdDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.SimpleThresholdDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.SimpleThreshold,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SimpleWeavePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class SimpleWeavePixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.SimpleWeavePixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { simpleWeave(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SketchFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SketchFilter(\n    override val value: Float = 5f,\n) : Transformation<Bitmap>, Filter.Sketch {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.removeShadows(\n        bitmap = input,\n        kernelSize = value.toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SmearFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.JhFilter\nimport com.jhlabs.SmearFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SmearParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class SmearFilter(\n    override val value: SmearParams = SmearParams.Default\n) : JhFilterTransformation(), Filter.Smear {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = SmearFilter().apply {\n        angle = Math.toRadians(value.angle.toDouble()).toFloat()\n        density = value.density\n        mix = value.mix\n        distance = value.distance\n        shape = value.shape\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SmoothToonFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageSmoothToonFilter\n\n@FilterInject\ninternal class SmoothToonFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.5f, 0.2f, 10f),\n) : GPUFilterTransformation(), Filter.SmoothToon {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageSmoothToonFilter().apply {\n        setBlurSize(value.first)\n        setThreshold(value.second)\n        setQuantizationLevels(value.third)\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SobelEdgeDetectionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageSobelEdgeDetectionFilter\n\n@FilterInject\ninternal class SobelEdgeDetectionFilter(\n    override val value: Float = 1f,\n) : GPUFilterTransformation(), Filter.SobelEdgeDetection {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageSobelEdgeDetectionFilter().apply {\n        setLineSize(value)\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SobelSimpleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SobelSimpleFilter(\n    override val value: Unit = Unit,\n) : Transformation<Bitmap>, Filter.SobelSimple {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.sobel(\n        bitmap = input,\n        edgeMode = EdgeMode.REFLECT_101,\n        scalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SoftEleganceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class SoftEleganceFilter(\n    override val value: Float = 1f,\n) : ChainTransformation<Bitmap>, Filter.SoftElegance {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_soft_elegance_1))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SoftEleganceVariantFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.transformation.ChainTransformation\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.core.resources.R\n\n@FilterInject\ninternal class SoftEleganceVariantFilter(\n    override val value: Float = 1f\n) : ChainTransformation<Bitmap>, Filter.SoftEleganceVariant {\n\n    override fun getTransformations(): List<Transformation<Bitmap>> = listOf(\n        LUT512x512Filter(value to ImageModel(R.drawable.lookup_soft_elegance_2))\n    )\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SoftSpringLightFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SoftSpringLightFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.SoftSpringLight {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.SOFT_SPRING_LIGHT).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SolarizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageSolarizeFilter\n\n@FilterInject\ninternal class SolarizeFilter(\n    override val value: Float = 0.5f,\n) : GPUFilterTransformation(), Filter.Solarize {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageSolarizeFilter(value)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SpacePortalFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SpacePortalFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.SpacePortal {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.SPACE_PORTAL).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SparkleFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.jhlabs.JhFilter\nimport com.jhlabs.SparkleFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SparkleParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\nimport kotlin.math.max\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class SparkleFilter(\n    override val value: SparkleParams = SparkleParams.Default\n) : JhFilterTransformation(), Filter.Sparkle {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = SparkleFilter(1, 1)\n\n    override fun createFilter(image: Bitmap): JhFilter =\n        SparkleFilter(\n            (value.centreX * image.width).roundToInt(),\n            (value.centreY * image.height).roundToInt()\n        ).apply {\n            amount = value.amount\n            rays = value.rays\n            radius = (value.radius * (max(image.width, image.height) / 2f)).roundToInt()\n            randomness = value.randomness\n            color = value.color.colorInt\n        }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SpectralFireFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SpectralFireFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.SpectralFire {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.SPECTRAL_FIRE).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SphereLensDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.jhlabs.JhFilter\nimport com.jhlabs.SphereLensDistortionFilter\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\nimport kotlin.math.max\n\n@FilterInject\ninternal class SphereLensDistortionFilter(\n    override val value: Quad<Float, Float, Float, Float> = 1.5f to 0.5f qto (0.5f to 0.5f)\n) : JhFilterTransformation(), Filter.SphereLensDistortion {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = SphereLensDistortionFilter()\n\n    override fun createFilter(image: Bitmap): JhFilter = SphereLensDistortionFilter().apply {\n        refractionIndex = value.first\n        radius = value.second * (max(image.width, image.height) / 2f)\n        centreX = value.third\n        centreY = value.fourth\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SphereRefractionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.PointF\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageSphereRefractionFilter\n\n@FilterInject\ninternal class SphereRefractionFilter(\n    override val value: Pair<Float, Float> = 0.25f to 0.71f,\n) : GPUFilterTransformation(), Filter.SphereRefraction {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageSphereRefractionFilter(\n        PointF(0.5f, 0.5f),\n        value.first, value.second\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SpotHealFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.SpotHealMode\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.image.loadBitmap\nimport com.t8rin.neural_tools.inpaint.LaMaProcessor\nimport com.t8rin.opencv_tools.spot_heal.SpotHealer\nimport com.t8rin.opencv_tools.spot_heal.model.HealType\n\n@FilterInject\ninternal class SpotHealFilter(\n    override val value: Pair<ImageModel, SpotHealMode>,\n) : Transformation<Bitmap>, Filter.SpotHeal {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap {\n        val mask = value.first.data.loadBitmap() ?: return input\n\n        return when (value.second) {\n            SpotHealMode.OpenCV -> openCV(\n                input = input,\n                mask = mask\n            )\n\n            SpotHealMode.LaMa -> lama(\n                input = input,\n                mask = mask\n            )\n        }\n    }\n\n    private fun openCV(\n        input: Bitmap,\n        mask: Bitmap\n    ) = SpotHealer.heal(\n        image = input,\n        mask = mask,\n        radius = 3f,\n        type = HealType.TELEA\n    )\n\n    private fun lama(\n        input: Bitmap,\n        mask: Bitmap\n    ) = LaMaProcessor.inpaint(\n        image = input,\n        mask = mask\n    ) ?: openCV(\n        input = input,\n        mask = mask\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/StackBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\nimport kotlin.math.roundToInt\n\n@FilterInject\ninternal class StackBlurFilter(\n    override val value: Pair<Float, Float> = 0.5f to 10f,\n) : Transformation<Bitmap>, Filter.StackBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.stackBlur(\n        bitmap = input,\n        scale = value.first,\n        radius = value.second.roundToInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/StaggeredPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class StaggeredPixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.StaggeredPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { staggered(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/StarBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ConvolveKernels\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.convolution.convolve2D\n\n@FilterInject\ninternal class StarBlurFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.StarBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.convolve2D(\n        input = input,\n        kernelProducer = ConvolveKernels::star,\n        size = value.roundTo(NEAREST_ODD_ROUNDING).toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/StrokePixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class StrokePixelationFilter(\n    override val value: Pair<Float, ColorModel> = 20f to Color.Black.toModel(),\n) : Transformation<Bitmap>, Filter.StrokePixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { stroke(value.first) }\n    ).let {\n        Trickle.drawColorBehind(\n            input = it,\n            color = value.second.colorInt\n        )\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/StuckiDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class StuckiDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.StuckiDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Stucki,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SunriseFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class SunriseFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Sunrise {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.SUNRISE).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/SwirlDistortionFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.PointF\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageSwirlFilter\n\n@FilterInject\ninternal class SwirlDistortionFilter(\n    override val value: Quad<Float, Float, Float, Float> = 0.5f to 1f qto (0.5f to 0.5f)\n) : GPUFilterTransformation(), Filter.SwirlDistortion {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter =\n        GPUImageSwirlFilter(value.first, value.second, PointF(value.third, value.fourth))\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/TentBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.NEAREST_ODD_ROUNDING\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class TentBlurFilter(\n    override val value: Float = 15f,\n) : Transformation<Bitmap>, Filter.TentBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize,\n    ): Bitmap = Aire.tentBlur(\n        bitmap = input,\n        sigma = value.roundTo(NEAREST_ODD_ROUNDING)\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ThresholdFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class ThresholdFilter(\n    override val value: Float = 128f\n) : Transformation<Bitmap>, Filter.Threshold {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.threshold(\n        bitmap = input,\n        level = value.toInt()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ToneCurvesFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.curves.GPUImageToneCurveFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ToneCurvesParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\n@FilterInject\ninternal class ToneCurvesFilter(\n    override val value: ToneCurvesParams = ToneCurvesParams.Default,\n) : GPUFilterTransformation(), Filter.ToneCurves {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageToneCurveFilter(value.controlPoints)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ToonFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageToonFilter\n\n@FilterInject\ninternal class ToonFilter(\n    override val value: Pair<Float, Float> = 0.2f to 10f,\n) : GPUFilterTransformation(), Filter.Toon {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter =\n        GPUImageToonFilter(value.first, value.second)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/TopHatFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.MorphKernels\nimport com.awxkee.aire.MorphOp\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.TrickleUtils.checkHasAlpha\n\n@FilterInject\ninternal class TopHatFilter(\n    override val value: Pair<Float, Boolean> = 25f to true\n) : Transformation<Bitmap>, Filter.TopHat {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.morphology(\n        bitmap = input,\n        kernel = if (value.second) {\n            MorphKernels.circle(value.first.toInt())\n        } else {\n            MorphKernels.box(value.first.toInt())\n        },\n        morphOp = MorphOp.TOPHAT,\n        morphOpMode = if (input.checkHasAlpha()) MorphOpMode.RGBA\n        else MorphOpMode.RGB,\n        borderMode = EdgeMode.REFLECT_101,\n        kernelHeight = value.first.toInt(),\n        kernelWidth = value.first.toInt(),\n        borderScalar = Scalar.ZEROS\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/TriToneFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class TriToneFilter(\n    override val value: Triple<ColorModel, ColorModel, ColorModel> = Triple(\n        first = Color(0xFFFF003B).toModel(),\n        second = Color(0xFF831111).toModel(),\n        third = Color(0xFFFF0099).toModel()\n    )\n) : Transformation<Bitmap>, Filter.TriTone {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.tritone(\n        input = input,\n        shadowsColor = value.first.colorInt,\n        middleColor = value.second.colorInt,\n        highlightsColor = value.third.colorInt\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/TritanopiaFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class TritanopiaFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Tritanopia {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.TRITANOPIA).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/TritonomalyFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class TritonomalyFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Tritonomaly {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.Assistance.TRITONOMALY).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/TwirlFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.jhlabs.JhFilter\nimport com.jhlabs.TwirlFilter\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\nimport kotlin.math.max\n\n@FilterInject\ninternal class TwirlFilter(\n    override val value: Quad<Float, Float, Float, Float> = 45f to 0.5f qto (0.5f to 0.5f)\n) : JhFilterTransformation(), Filter.Twirl {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = TwirlFilter()\n\n    override fun createFilter(image: Bitmap): JhFilter = TwirlFilter().apply {\n        angle = Math.toRadians(value.first.toDouble()).toFloat()\n        centreX = value.second\n        centreY = value.third\n        radius = value.fourth * (max(image.width, image.height) / 2f)\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/TwoRowSierraDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class TwoRowSierraDitheringFilter(\n    override val value: Pair<Float, Boolean> = 200f to false,\n) : Transformation<Bitmap>, Filter.TwoRowSierraDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.TwoRowSierra,\n        threshold = value.first.toInt(),\n        isGrayScale = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/UchimuraFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class UchimuraFilter(\n    override val value: Float = 1f\n) : Transformation<Bitmap>, Filter.Uchimura {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.uchimura(\n        bitmap = input,\n        exposure = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/UnsharpFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class UnsharpFilter(\n    override val value: Float = 0.5f,\n) : Transformation<Bitmap>, Filter.Unsharp {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.unsharp(\n        bitmap = input,\n        intensity = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/VHSFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class VHSFilter(\n    override val value: Pair<Float, Float> = 2f to 3f,\n) : Transformation<Bitmap>, Filter.VHS {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.vhsGlitch(\n        src = input,\n        time = value.first,\n        strength = value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/VibranceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class VibranceFilter(\n    override val value: Float = 3f,\n) : Transformation<Bitmap>, Filter.Vibrance {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.vibrance(\n        bitmap = input,\n        vibrance = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/VignetteFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.PointF\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.blue\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.green\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.red\nimport com.t8rin.imagetoolbox.core.data.image.utils.ColorUtils.toModel\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageVignetteFilter\n\n@FilterInject\ninternal class VignetteFilter(\n    override val value: Triple<Float, Float, ColorModel> = Triple(\n        first = 0.3f,\n        second = 0.75f,\n        third = Color.Black.toModel()\n    )\n) : GPUFilterTransformation(), Filter.Vignette {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageVignetteFilter(\n        PointF(0.5f, 0.5f),\n        floatArrayOf(value.third.red, value.third.green, value.third.blue),\n        value.first,\n        value.second\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/VintageFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class VintageFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Vintage {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.VINTAGE).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/VoronoiCrystallizeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.CrystallizeFilter\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class VoronoiCrystallizeFilter(\n    override val value: VoronoiCrystallizeParams = VoronoiCrystallizeParams.Default\n) : JhFilterTransformation(), Filter.VoronoiCrystallize {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = CrystallizeFilter().apply {\n        edgeThickness = value.borderThickness\n        edgeColor = value.color.colorInt\n        scale = value.scale\n        randomness = value.randomness\n        gridType = value.shape\n        turbulence = value.turbulence\n        angle = Math.toRadians(value.angle.toDouble()).toFloat()\n        stretch = value.stretch\n        amount = value.amount\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/VortexPixelationFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.PixelationTool\n\n@FilterInject\ninternal class VortexPixelationFilter(\n    override val value: Float = 25f,\n) : Transformation<Bitmap>, Filter.VortexPixelation {\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = PixelationTool.pixelate(\n        input = input,\n        layers = { vortex(value) }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/WarmFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.ColorMatrices\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\n\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class WarmFilter(\n    override val value: Unit = Unit\n) : Transformation<Bitmap>, Filter.Warm {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMatrix3x3Filter(ColorMatrices.WARM).transform(input, size)\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/WaterEffectFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.WaterParams\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\n\n@FilterInject\ninternal class WaterEffectFilter(\n    override val value: WaterParams = WaterParams()\n) : Transformation<Bitmap>, Filter.WaterEffect {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Aire.waterEffect(\n        bitmap = input,\n        fractionSize = 0.2f * value.fractionSize,\n        frequencyX = value.frequencyX,\n        frequencyY = value.frequencyY,\n        amplitudeX = value.amplitudeX,\n        amplitudeY = value.amplitudeY\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/WeakPixelFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageWeakPixelInclusionFilter\n\n@FilterInject\ninternal class WeakPixelFilter(\n    override val value: Unit = Unit,\n) : GPUFilterTransformation(), Filter.WeakPixel {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter = GPUImageWeakPixelInclusionFilter()\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/WeaveFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.jhlabs.JhFilter\nimport com.jhlabs.WeaveFilter\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.qto\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.JhFilterTransformation\n\n@FilterInject\ninternal class WeaveFilter(\n    override val value: Quad<Float, Float, Float, Float> = 16f to 16f qto (6f to 6f)\n) : JhFilterTransformation(), Filter.Weave {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): JhFilter = WeaveFilter().apply {\n        xWidth = value.first\n        yWidth = value.second\n        xGap = value.third\n        yGap = value.fourth\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/WhiteBalanceFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageWhiteBalanceFilter\n\n@FilterInject\ninternal class WhiteBalanceFilter(\n    override val value: Pair<Float, Float> = 7000.0f to 100f,\n) : GPUFilterTransformation(), Filter.WhiteBalance {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override fun createFilter(): GPUImageFilter =\n        GPUImageWhiteBalanceFilter(value.first, value.second)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/YililomaDitheringFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.trickle.DitheringType\nimport com.t8rin.trickle.Trickle\n\n@FilterInject\ninternal class YililomaDitheringFilter(\n    override val value: Boolean = false,\n) : Transformation<Bitmap>, Filter.YililomaDithering {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = Trickle.dithering(\n        input = input,\n        type = DitheringType.Yililoma,\n        isGrayScale = value\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/model/ZoomBlurFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.model\n\n\nimport android.graphics.PointF\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.ksp.annotations.FilterInject\nimport com.t8rin.imagetoolbox.feature.filters.data.transformation.GPUFilterTransformation\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageZoomBlurFilter\n\n@FilterInject\ninternal class ZoomBlurFilter(\n    override val value: Triple<Float, Float, Float> = Triple(0.5f, 0.5f, 5f),\n) : GPUFilterTransformation(), Filter.ZoomBlur {\n\n    override val cacheKey: String\n        get() = value.hashCode().toString()\n\n\n    override fun createFilter(): GPUImageFilter =\n        GPUImageZoomBlurFilter(PointF(value.first, value.second), value.third)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/transformation/ColorMapTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.transformation\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.ColorMapType\nimport com.t8rin.opencv_tools.color_map.ColorMap\nimport com.t8rin.opencv_tools.color_map.model.ColorMapType as NativeColorMapType\n\ninternal abstract class ColorMapTransformation(\n    val type: ColorMapType\n) : Transformation<Bitmap> {\n\n    override val cacheKey: String\n        get() = type.hashCode().toString()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = ColorMap.apply(\n        bitmap = input,\n        map = NativeColorMapType.valueOf(type.name)\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/transformation/GPUFilterTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.transformation\n\nimport android.graphics.Bitmap\nimport coil3.size.Size\nimport com.t8rin.imagetoolbox.core.data.utils.asCoil\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.flexible\nimport jp.co.cyberagent.android.gpuimage.GPUImage\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\nimport coil3.transform.Transformation as CoilTransformation\n\ninternal abstract class GPUFilterTransformation : CoilTransformation(), Transformation<Bitmap> {\n\n    /**\n     * Create the [GPUImageFilter] to apply to this [Transformation]\n     */\n    abstract fun createFilter(): GPUImageFilter\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: Size\n    ): Bitmap = GPUImage(appContext).apply {\n        setImage(input.flexible(size))\n        setFilter(createFilter())\n    }.bitmapWithFilterApplied\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = transform(input, size.asCoil())\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/transformation/JhFilterTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.transformation\n\nimport android.graphics.Bitmap\nimport coil3.size.Size\nimport com.jhlabs.JhFilter\nimport com.t8rin.imagetoolbox.core.data.utils.asCoil\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.flexible\nimport coil3.transform.Transformation as CoilTransformation\n\ninternal abstract class JhFilterTransformation : CoilTransformation(), Transformation<Bitmap> {\n\n    abstract fun createFilter(): JhFilter\n\n    open fun createFilter(image: Bitmap): JhFilter = createFilter()\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: Size\n    ): Bitmap = input.flexible(size).let {\n        createFilter(it).filter(it)\n    }\n\n    override suspend fun transform(\n        input: Bitmap,\n        size: IntegerSize\n    ): Bitmap = transform(input, size.asCoil())\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/EnumMappings.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils\n\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.PaletteTransferColorspace\nimport com.awxkee.aire.TransferFunction\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PaletteTransferSpace\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.trickle.PopArtBlendMode\n\nfun BlurEdgeMode.toEdgeMode(): EdgeMode = when (this) {\n    BlurEdgeMode.Clamp -> EdgeMode.CLAMP\n    BlurEdgeMode.Reflect101 -> EdgeMode.REFLECT_101\n    BlurEdgeMode.Wrap -> EdgeMode.WRAP\n    BlurEdgeMode.Reflect -> EdgeMode.REFLECT\n}\n\nfun TransferFunc.toFunc(): TransferFunction = when (this) {\n    TransferFunc.SRGB -> TransferFunction.SRGB\n    TransferFunc.REC709 -> TransferFunction.REC709\n    TransferFunc.GAMMA2P2 -> TransferFunction.GAMMA2P2\n    TransferFunc.GAMMA2P8 -> TransferFunction.GAMMA2P8\n}\n\nfun PaletteTransferSpace.toSpace(): PaletteTransferColorspace = when (this) {\n    PaletteTransferSpace.LALPHABETA -> PaletteTransferColorspace.LALPHABETA\n    PaletteTransferSpace.LAB -> PaletteTransferColorspace.LAB\n    PaletteTransferSpace.OKLAB -> PaletteTransferColorspace.OKLAB\n    PaletteTransferSpace.LUV -> PaletteTransferColorspace.LUV\n}\n\nfun PopArtBlendingMode.toMode(): PopArtBlendMode = when (this) {\n    PopArtBlendingMode.MULTIPLY -> PopArtBlendMode.MULTIPLY\n    PopArtBlendingMode.COLOR_BURN -> PopArtBlendMode.COLOR_BURN\n    PopArtBlendingMode.SOFT_LIGHT -> PopArtBlendMode.SOFT_LIGHT\n    PopArtBlendingMode.HSL_COLOR -> PopArtBlendMode.HSL_COLOR\n    PopArtBlendingMode.HSL_HUE -> PopArtBlendMode.HSL_HUE\n    PopArtBlendingMode.DIFFERENCE -> PopArtBlendMode.DIFFERENCE\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/TransformationUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.Matrix\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.scale\nimport coil3.size.Size\nimport coil3.size.pxOrElse\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.aspectRatio\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport java.lang.Integer.max\n\ninternal fun Bitmap.flexible(size: Size): Bitmap = flexibleResize(\n    image = this,\n    max = max(\n        size.height.pxOrElse { height },\n        size.width.pxOrElse { width }\n    )\n)\n\ninternal fun Bitmap.mirror(\n    value: Float = 0.5f,\n    side: MirrorSide = MirrorSide.LeftToRight\n): Bitmap {\n    val input = this\n    if (value <= 0f || value >= 1f) return input\n\n    val width = input.width\n    val height = input.height\n\n    return when (side) {\n        MirrorSide.LeftToRight, MirrorSide.RightToLeft -> {\n            val centerX = (width * value).toInt().coerceIn(1, width - 1)\n            val leftWidth = centerX\n            val rightWidth = width - centerX\n            val halfWidth = minOf(leftWidth, rightWidth)\n            val outputWidth = halfWidth * 2\n\n            createBitmap(\n                width = outputWidth,\n                height = height,\n                config = input.safeConfig\n            ).applyCanvas {\n                if (side == MirrorSide.LeftToRight) {\n                    val leftPart =\n                        Bitmap.createBitmap(input, centerX - halfWidth, 0, halfWidth, height)\n                    val flipped =\n                        Bitmap.createBitmap(leftPart, 0, 0, halfWidth, height, Matrix().apply {\n                            preScale(-1f, 1f)\n                        }, true)\n                    drawBitmap(leftPart)\n                    drawBitmap(flipped, halfWidth.toFloat(), 0f)\n                } else {\n                    val rightPart = Bitmap.createBitmap(input, centerX, 0, halfWidth, height)\n                    val flipped =\n                        Bitmap.createBitmap(rightPart, 0, 0, halfWidth, height, Matrix().apply {\n                            preScale(-1f, 1f)\n                        }, true)\n                    drawBitmap(flipped)\n                    drawBitmap(rightPart, halfWidth.toFloat(), 0f)\n                }\n            }\n        }\n\n        MirrorSide.TopToBottom, MirrorSide.BottomToTop -> {\n            val centerY = (height * value).toInt().coerceIn(1, height - 1)\n            val topHeight = centerY\n            val bottomHeight = height - centerY\n            val halfHeight = minOf(topHeight, bottomHeight)\n            val outputHeight = halfHeight * 2\n\n            createBitmap(\n                width = width,\n                height = outputHeight,\n                config = input.safeConfig\n            ).applyCanvas {\n                if (side == MirrorSide.TopToBottom) {\n                    val topPart =\n                        Bitmap.createBitmap(input, 0, centerY - halfHeight, width, halfHeight)\n                    val flipped =\n                        Bitmap.createBitmap(topPart, 0, 0, width, halfHeight, Matrix().apply {\n                            preScale(1f, -1f)\n                        }, true)\n                    drawBitmap(topPart)\n                    drawBitmap(flipped, 0f, halfHeight.toFloat())\n                } else {\n                    val bottomPart = Bitmap.createBitmap(input, 0, centerY, width, halfHeight)\n                    val flipped =\n                        Bitmap.createBitmap(bottomPart, 0, 0, width, halfHeight, Matrix().apply {\n                            preScale(1f, -1f)\n                        }, true)\n                    drawBitmap(flipped)\n                    drawBitmap(bottomPart, 0f, halfHeight.toFloat())\n                }\n            }\n        }\n    }\n}\n\nprivate fun flexibleResize(\n    image: Bitmap,\n    max: Int\n): Bitmap {\n    return runCatching {\n        if (image.height >= image.width) {\n            val aspectRatio = image.aspectRatio\n            val targetWidth = (max * aspectRatio).toInt()\n            image.scale(targetWidth, max)\n        } else {\n            val aspectRatio = 1f / image.aspectRatio\n            val targetHeight = (max * aspectRatio).toInt()\n            image.scale(max, targetHeight)\n        }\n    }.getOrNull() ?: image\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/convolution/AireConvolution.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnusedReceiverParameter\")\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.convolution\n\nimport android.graphics.Bitmap\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.EdgeMode\nimport com.awxkee.aire.KernelShape\nimport com.awxkee.aire.MorphOpMode\nimport com.awxkee.aire.Scalar\n\ninternal inline fun Aire.convolve2D(\n    input: Bitmap,\n    kernelProducer: (Int) -> FloatArray,\n    size: Int\n): Bitmap = Aire.convolve2D(\n    bitmap = input,\n    kernel = kernelProducer(size),\n    kernelShape = KernelShape(size, size),\n    edgeMode = EdgeMode.REFLECT_101,\n    scalar = Scalar.ZEROS,\n    mode = MorphOpMode.RGBA\n)"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/glitch/GlitchTool.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.glitch\n\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.glitch.tools.Anaglyph\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.glitch.tools.JpegGlitch\n\ninternal object GlitchTool : Anaglyph, JpegGlitch"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/glitch/tools/Anaglyph.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.glitch.tools\n\nimport android.graphics.Bitmap\nimport android.graphics.BitmapShader\nimport android.graphics.ColorMatrix\nimport android.graphics.ColorMatrixColorFilter\nimport android.graphics.Matrix\nimport android.graphics.Paint\nimport android.graphics.PorterDuff\nimport android.graphics.PorterDuffXfermode\nimport android.graphics.Shader\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport kotlinx.coroutines.coroutineScope\n\ninternal interface Anaglyph {\n    suspend fun anaglyph(\n        image: Bitmap,\n        percentage: Int\n    ): Bitmap = coroutineScope {\n        val anaglyphPaint = Paint()\n        val anaglyphShader = BitmapShader(image, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)\n\n        anaglyphPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.ADD)\n        anaglyphPaint.shader = anaglyphShader\n\n        val w = image.width\n        val h = image.height\n\n        val transX = (percentage)\n        val transY = 0\n\n        val colorMatrix = ColorMatrix()\n\n        createBitmap(\n            width = w,\n            height = h\n        ).applyCanvas {\n            drawColor(0, PorterDuff.Mode.CLEAR)\n\n            //left\n            val matrix = Matrix()\n            matrix.setTranslate((-transX).toFloat(), (transY).toFloat())\n            anaglyphShader.setLocalMatrix(matrix)\n            colorMatrix.set(leftArray)\n            anaglyphPaint.colorFilter = ColorMatrixColorFilter(colorMatrix)\n            drawRect(0.0f, 0.0f, w.toFloat(), h.toFloat(), anaglyphPaint)\n\n            //right\n            val matrix2 = Matrix()\n            matrix2.setTranslate((transX).toFloat(), transY.toFloat())\n            anaglyphShader.setLocalMatrix(matrix2)\n            colorMatrix.set(rightArray)\n            anaglyphPaint.colorFilter = ColorMatrixColorFilter(colorMatrix)\n            drawRect(0.0f, 0.0f, w.toFloat(), h.toFloat(), anaglyphPaint)\n\n\n            drawBitmap(image, 0f, 0f, anaglyphPaint)\n        }\n    }\n\n    companion object {\n        private val leftArray = floatArrayOf(\n            1.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            1.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            1.0f\n        )\n        private val rightArray = floatArrayOf(\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            1.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            1.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            1.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            0.0f,\n            1.0f\n        )\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/glitch/tools/JpegGlitch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.glitch.tools\n\nimport android.graphics.Bitmap\nimport android.graphics.BitmapFactory\nimport kotlinx.coroutines.coroutineScope\nimport java.io.ByteArrayOutputStream\nimport kotlin.math.floor\n\ninternal interface JpegGlitch {\n    suspend fun jpegGlitch(\n        input: Bitmap,\n        amount: Int = 20,\n        seed: Int = 15,\n        iterations: Int = 9\n    ): Bitmap = coroutineScope {\n        val imageByteArray = ByteArrayOutputStream().use {\n            input.compress(Bitmap.CompressFormat.JPEG, 100, it)\n            it.toByteArray()\n        }\n        val jpgHeaderLength = getJpegHeaderSize(imageByteArray)\n        repeat(\n            times = iterations\n        ) {\n            glitchJpegBytes(\n                pos = it,\n                imageByteArray = imageByteArray,\n                jpgHeaderLength = jpgHeaderLength,\n                amount = amount,\n                seed = seed,\n                iterations = iterations\n            )\n        }\n        BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.size)\n    }\n\n    companion object {\n        private fun glitchJpegBytes(\n            pos: Int,\n            imageByteArray: ByteArray,\n            jpgHeaderLength: Int,\n            amount: Int = 20,\n            seed: Int = 15,\n            iterations: Int = 9\n        ) {\n            val maxIndex = imageByteArray.size - jpgHeaderLength - 4f\n            val pxMin = maxIndex / iterations * pos\n            val pxMax = maxIndex / iterations * (pos + 1)\n            val delta = pxMax - pxMin\n            var pxIndex = pxMin + delta * seed / 100f\n            if (pxIndex > maxIndex) {\n                pxIndex = maxIndex\n            }\n            val index = floor((jpgHeaderLength + pxIndex).toDouble()).toInt()\n            imageByteArray[index] = floor((amount / 100f * 256f).toDouble()).toInt().toByte()\n        }\n\n        private fun getJpegHeaderSize(imageByteArray: ByteArray): Int {\n            var result = 417\n            var i = 0\n            val len = imageByteArray.size\n            while (i < len) {\n                if (imageByteArray[i].toInt() == 255 && imageByteArray[i + 1].toInt() == 218) {\n                    result = i + 2\n                    break\n                }\n                i++\n            }\n            return result\n        }\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/gpu/GPUImageHighlightShadowWideRangeFilter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.gpu\n\nimport android.opengl.GLES20\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter\n\ninternal class GPUImageHighlightShadowWideRangeFilter @JvmOverloads constructor(\n    private var shadows: Float = 1.0f,\n    private var highlights: Float = 1.0f\n) :\n    GPUImageFilter(NO_FILTER_VERTEX_SHADER, HIGHLIGHT_SHADOW_FRAGMENT_SHADER) {\n    private var shadowsLocation = 0\n    private var highlightsLocation = 0\n\n    override fun onInit() {\n        super.onInit()\n        highlightsLocation = GLES20.glGetUniformLocation(program, \"highlights\")\n        shadowsLocation = GLES20.glGetUniformLocation(program, \"shadows\")\n    }\n\n    override fun onInitialized() {\n        super.onInitialized()\n        setHighlights(highlights)\n        setShadows(shadows)\n    }\n\n    fun setHighlights(highlights: Float) {\n        this.highlights = highlights\n        setFloat(highlightsLocation, this.highlights)\n    }\n\n    fun setShadows(shadows: Float) {\n        this.shadows = shadows\n        setFloat(shadowsLocation, this.shadows)\n    }\n\n    companion object {\n        const val HIGHLIGHT_SHADOW_FRAGMENT_SHADER: String = \"\" +\n                \" uniform sampler2D inputImageTexture;\\n\" +\n                \" varying highp vec2 textureCoordinate;\\n\" +\n                \" \\n\" +\n                \" uniform lowp float shadows;\\n\" +\n                \" uniform lowp float highlights;\\n\" +\n                \" \\n\" +\n                \" const mediump vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3);\\n\" +\n                \" \\n\" +\n                \" void main()\\n\" +\n                \" {\\n\" +\n                \"   lowp vec4 source = texture2D(inputImageTexture, textureCoordinate);\\n\" +\n                \"   mediump float luminance = dot(source.rgb, luminanceWeighting);\\n\" +\n                \" \\n\" +\n                \"   mediump float shadow = clamp((pow(luminance, 1.0/shadows) + (-0.76)*pow(luminance, 2.0/shadows)) - luminance, 0.0, 1.0);\\n\" +\n                \"   mediump float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0);\\n\" +\n                \"   lowp vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0));\\n\" +\n                \" \\n\" +\n                \"   mediump float contrastedLuminance = ((luminance - 0.5) * 1.5) + 0.5;\\n\" +\n                \"   mediump float whiteInterp = contrastedLuminance*contrastedLuminance*contrastedLuminance;\\n\" +\n                \"   mediump float whiteTarget = clamp(highlights, 1.0, 2.0) - 1.0;\\n\" +\n                \"   result = mix(result, vec3(1.0), whiteInterp*whiteTarget);\\n\" +\n                \" \\n\" +\n                \"   mediump float invContrastedLuminance = 1.0 - contrastedLuminance;\\n\" +\n                \"   mediump float blackInterp = invContrastedLuminance*invContrastedLuminance*invContrastedLuminance;\\n\" +\n                \"   mediump float blackTarget = 1.0 - clamp(shadows, 0.0, 1.0);\\n\" +\n                \"   result = mix(result, vec3(0.0), blackInterp*blackTarget);\\n\" +\n                \" \\n\" +\n                \"   gl_FragColor = vec4(result, source.a);\\n\" +\n                \" }\"\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/image/ImageLoader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.image\n\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\ninternal suspend fun Any.loadBitmap(size: Int? = null) = appContext.imageLoader.execute(\n    ImageRequest.Builder(appContext)\n        .data(this)\n        .apply {\n            if (size != null) size(size)\n        }\n        .build()\n).image?.toBitmap()"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/pixelation/PixelationTool.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"MemberVisibilityCanBePrivate\")\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation\n\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.graphics.Paint\nimport android.graphics.Rect\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.get\nimport androidx.core.graphics.withClip\nimport androidx.core.graphics.withSave\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.tool.PixelationCommands\nimport com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.tool.PixelationLayer\nimport kotlin.math.sqrt\n\ninternal object PixelationTool {\n\n    fun pixelate(\n        input: Bitmap,\n        inBounds: Rect? = null,\n        outBounds: Rect? = null,\n        layers: PixelationCommands.() -> Array<PixelationLayer>,\n    ): Bitmap = pixelate(\n        input = input,\n        inBounds = inBounds,\n        outBounds = outBounds,\n        layers = layers(PixelationCommands)\n    )\n\n    fun pixelate(\n        input: Bitmap,\n        inBounds: Rect? = null,\n        outBounds: Rect? = null,\n        vararg layers: PixelationLayer,\n    ): Bitmap {\n        val bounds = outBounds ?: Rect(0, 0, input.width, input.height)\n\n        return createBitmap(\n            width = bounds.width(),\n            height = bounds.height()\n        ).applyCanvas {\n            render(\n                input = input,\n                inBounds = inBounds,\n                outBounds = bounds,\n                layers = layers\n            )\n        }\n    }\n\n    private fun Canvas.render(\n        input: Bitmap,\n        inBounds: Rect?,\n        outBounds: Rect,\n        vararg layers: PixelationLayer,\n    ) {\n        val inWidth = inBounds?.width() ?: input.width\n        val inHeight = inBounds?.height() ?: input.height\n        val inX = inBounds?.left ?: 0\n        val inY = inBounds?.top ?: 0\n        val scaleX = outBounds.width().toFloat() / inWidth\n        val scaleY = outBounds.height().toFloat() / inHeight\n        withClip(outBounds) {\n            translate(\n                outBounds.left.toFloat(),\n                outBounds.top.toFloat()\n            )\n            scale(scaleX, scaleY)\n            for (layer in layers) {\n                // option defaults\n                val size: Float = layer.size ?: layer.resolution\n                val cols = (inWidth / layer.resolution + 1).toInt()\n                val rows = (inHeight / layer.resolution + 1).toInt()\n                val halfSize = size / 2f\n                val diamondSize = size / SQRT2\n                val halfDiamondSize = diamondSize / 2f\n                for (row in 0..rows) {\n                    val y: Float = (row - 0.5f) * layer.resolution + layer.offsetY\n                    // normalize y so shapes around edges get color\n                    val pixelY = inY + y.coerceAtMost((inHeight - 1).toFloat()).coerceAtLeast(0f)\n                    for (col in 0..cols) {\n                        val x: Float = (col - 0.5f) * layer.resolution + layer.offsetX\n                        // normalize y so shapes around edges get color\n                        val pixelX = inX + x.coerceAtMost((inWidth - 1).toFloat()).coerceAtLeast(0f)\n                        paint.color = getPixelColor(input, pixelX.toInt(), pixelY.toInt(), layer)\n                        when (layer.shape) {\n                            PixelationLayer.Shape.Circle -> drawCircle(x, y, halfSize, paint)\n                            PixelationLayer.Shape.Diamond -> {\n                                withSave {\n                                    translate(x, y)\n                                    rotate(45f)\n                                    drawRect(\n                                        -halfDiamondSize,\n                                        -halfDiamondSize,\n                                        halfDiamondSize,\n                                        halfDiamondSize,\n                                        paint\n                                    )\n                                }\n                            }\n\n                            PixelationLayer.Shape.Square -> drawRect(\n                                x - halfSize,\n                                y - halfSize,\n                                x + halfSize,\n                                y + halfSize,\n                                paint\n                            )\n                        }\n                    } // col\n                } // row\n            }\n        }\n    }\n\n    /**\n     * Returns the color of the cluster. If options.enableDominantColor is true, return the\n     * dominant color around the provided point. Return the color of the point itself otherwise.\n     * The dominant color algorithm is based on simple counting search, so use with caution.\n     *\n     * @param pixels the bitmap\n     * @param pixelX the x coordinate of the reference point\n     * @param pixelY the y coordinate of the reference point\n     * @param opts additional options\n     * @return the color of the cluster\n     */\n    private fun getPixelColor(\n        pixels: Bitmap,\n        pixelX: Int,\n        pixelY: Int,\n        opts: PixelationLayer\n    ): Int {\n        var pixel = pixels[pixelX, pixelY]\n        if (opts.enableDominantColor) {\n            val colorCounter: MutableMap<Int, Int> = HashMap(100)\n            for (x in 0.coerceAtLeast((pixelX - opts.resolution).toInt()) until pixels.width.coerceAtMost(\n                (pixelX + opts.resolution).toInt()\n            )) {\n                for (y in 0.coerceAtLeast((pixelY - opts.resolution).toInt()) until pixels.height.coerceAtMost(\n                    (pixelY + opts.resolution).toInt()\n                )) {\n                    val currentRGB = pixels[x, y]\n                    val count =\n                        if (colorCounter.containsKey(currentRGB)) colorCounter[currentRGB]!! else 0\n                    colorCounter[currentRGB] = count + 1\n                }\n            }\n            var max: Int? = null\n            var dominantRGB: Int? = null\n            for ((key, value) in colorCounter) {\n                if (max == null || value > max) {\n                    max = value\n                    dominantRGB = key\n                }\n            }\n            pixel = dominantRGB!!\n        }\n        val red = Color.red(pixel)\n        val green = Color.green(pixel)\n        val blue = Color.blue(pixel)\n        val alpha = (opts.alpha * Color.alpha(pixel)).toInt()\n        return Color.argb(alpha, red, green, blue)\n    }\n\n    private val SQRT2 = sqrt(2.0).toFloat()\n\n    private val paint =\n        Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG)\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/pixelation/tool/PixelationCommands.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *  \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.tool\n\ninternal object PixelationCommands {\n\n    fun enhancedDiamond(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value)\n            .setOffset(value / 4)\n            .setAlpha(0.5f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value)\n            .setOffset(value)\n            .setAlpha(0.5f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value / 3)\n            .setSize(value / 6)\n            .setOffset(value / 12)\n            .build()\n    )\n\n    fun circle(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 3f)\n            .setOffset(value / 2)\n            .build()\n    )\n\n    fun diamond(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value)\n            .setSize(value + 1)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value)\n            .setOffset(value / 2)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .setAlpha(0.6f)\n            .build()\n    )\n\n    fun enhancedCircle(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setOffset(value / 2)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 1.2f)\n            .setOffset(value / 2.5f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 1.8f)\n            .setOffset(value / 3)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 2.7f)\n            .setOffset(value / 4)\n            .build()\n    )\n\n    fun enhancedSquare(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value / 4)\n            .setSize(value / 6)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value / 4)\n            .setSize(value / 6)\n            .setOffset(value / 8)\n            .build()\n    )\n\n    fun square(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value - 4f)\n            .setSize(value)\n            .build()\n    )\n\n    fun stroke(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 5)\n            .setOffset(value / 4)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 4)\n            .setOffset(value / 2)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 3)\n            .setOffset(value / 1.3f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value / 4)\n            .setOffset(0f)\n            .build()\n    )\n\n    fun simpleWeave(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .setSize(value / 2)\n            .setOffset(value / 2)\n            .setAlpha(0.5f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value)\n            .setSize(value / 3)\n            .setOffset(value / 4)\n            .setAlpha(0.4f)\n            .build()\n    )\n\n    fun staggered(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .setOffset(value / 2)\n            .setSize(value * 0.85f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value * 2)\n            .setAlpha(0.35f)\n            .build()\n    )\n\n    fun cross(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value)\n            .setSize(value * 0.7f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value / 2)\n            .setSize(value / 3)\n            .setAlpha(0.45f)\n            .build()\n    )\n\n    fun microMacro(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value * 2)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value / 2)\n            .setSize(value / 3)\n            .build()\n    )\n\n    fun orbital(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value * 0.9f)\n            .setOffset(value / 3)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value * 0.6f)\n            .setOffset(value / 1.5f)\n            .build()\n    )\n\n    fun vortex(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value * 0.85f)\n            .setOffset(value / 3)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value * 1.4f)\n            .setSize(value * 0.6f)\n            .setOffset(value / 1.1f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value / 2)\n            .setSize(value / 3)\n            .build()\n    )\n\n    fun pulseGrid(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value * 1.5f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value * 0.7f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value / 1.8f)\n            .setSize(value / 2.8f)\n            .setOffset(value / 2)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value / 2.5f)\n            .setAlpha(0.35f)\n            .build()\n    )\n\n    fun nucleus(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value * 0.6f)\n            .setOffset(value / 2)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value / 2)\n            .setSize(value / 3)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value * 2)\n            .setAlpha(0.25f)\n            .build()\n    )\n\n    fun radialWeave(value: Float): Array<PixelationLayer> = arrayOf(\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value * 0.9f)\n            .setOffset(value / 3)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value)\n            .setSize(value * 0.6f)\n            .setOffset(value / 1.5f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Circle)\n            .setResolution(value / 2)\n            .setSize(value / 3)\n            .setOffset(value / 4)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Diamond)\n            .setResolution(value / 3)\n            .setSize(value / 5)\n            .setOffset(value / 6)\n            .setAlpha(0.35f)\n            .build(),\n        PixelationLayer.Builder(PixelationLayer.Shape.Square)\n            .setResolution(value / 4)\n            .setAlpha(0.25f)\n            .build()\n    )\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/pixelation/tool/PixelationLayer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.pixelation.tool\n\n\n@ConsistentCopyVisibility\ninternal data class PixelationLayer private constructor(\n    val shape: Shape,\n    val enableDominantColor: Boolean = false,\n    val resolution: Float = 16f,\n    val size: Float? = null,\n    val alpha: Float = 1f,\n    val offsetX: Float = 0f,\n    val offsetY: Float = 0f\n) {\n    class Builder(shape: Shape) {\n        private var layer: PixelationLayer = PixelationLayer(shape)\n\n        private inline fun mutate(\n            action: PixelationLayer.() -> PixelationLayer\n        ): Builder = apply { layer = layer.action() }\n\n        fun setResolution(resolution: Float): Builder = mutate {\n            copy(resolution = resolution)\n        }\n\n        fun setSize(size: Float): Builder = mutate {\n            copy(\n                size = size\n            )\n        }\n\n        fun setOffset(size: Float): Builder = mutate {\n            copy(\n                offsetX = size,\n                offsetY = size\n            )\n        }\n\n        fun setAlpha(alpha: Float): Builder = mutate {\n            copy(\n                alpha = alpha\n            )\n        }\n\n        fun setEnableDominantColors(enable: Boolean): Builder = mutate {\n            copy(\n                enableDominantColor = enable\n            )\n        }\n\n        fun build(): PixelationLayer = layer\n    }\n\n    enum class Shape {\n        Circle,\n        Diamond,\n        Square\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/serialization/FilterSerializationUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.serialization\n\nimport android.content.Context\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport kotlin.reflect.full.primaryConstructor\n\ninternal fun List<Filter<*>>.toDatastoreString(\n    includeValue: Boolean = false,\n    context: Context\n): String = joinToString(separator = FILTERS_SEPARATOR) { filter ->\n    filter::class.qualifiedName!!.replace(\n        context.applicationInfo.packageName,\n        PACKAGE_ALIAS\n    ) + if (includeValue) {\n        VALUE_SEPARATOR + filter.value.toPair()\n            ?.let { it.first + VALUE_SEPARATOR + it.second }\n    } else \"\"\n}.trim()\n\n\n@Suppress(\"UNCHECKED_CAST\")\ninternal fun String.toFiltersList(\n    includeValue: Boolean,\n    context: Context\n): List<Filter<*>> = split(FILTERS_SEPARATOR).mapNotNull { line ->\n    if (line.trim().isEmpty()) return@mapNotNull null\n\n    val (name, value) = if (includeValue) {\n        runCatching {\n            val splitData = line.split(VALUE_SEPARATOR)\n            val className = splitData[1]\n            val valueString = splitData[2]\n\n            splitData[0].trim() to (className to valueString).fromPair()\n        }.getOrElse { line.trim() to Unit }\n    } else line.trim() to Unit\n    runCatching {\n        val filterClass = Class.forName(\n            name.replace(\n                PACKAGE_ALIAS,\n                context.applicationInfo.packageName\n            )\n        ) as Class<Filter<*>>\n        filterClass.kotlin.primaryConstructor?.run {\n            try {\n                if (includeValue && value != null) {\n                    callBy(mapOf(parameters[0] to value))\n                } else callBy(emptyMap())\n            } catch (_: Throwable) {\n                callBy(emptyMap())\n            }\n        }\n    }.getOrNull()\n}\n\ninternal fun String.toTemplateFiltersList(context: Context): List<TemplateFilter> =\n    split(TEMPLATES_SEPARATOR).map {\n        val splitData = it.split(TEMPLATE_CONTENT_SEPARATOR)\n        val name = splitData[0]\n        val filters = splitData[1].toFiltersList(true, context)\n\n        TemplateFilter(\n            name = name,\n            filters = filters\n        )\n    }\n\ninternal fun List<TemplateFilter>.toDatastoreString(context: Context): String =\n    joinToString(separator = TEMPLATES_SEPARATOR) {\n        it.name + TEMPLATE_CONTENT_SEPARATOR + it.filters.toDatastoreString(true, context)\n    }\n\nprivate const val FILTERS_SEPARATOR = \",\"\nprivate const val TEMPLATES_SEPARATOR = \"\\\\\"\nprivate const val TEMPLATE_CONTENT_SEPARATOR = \"+\"\nprivate const val VALUE_SEPARATOR = \":\"\n\ninternal const val PACKAGE_ALIAS = \"^^\""
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/data/utils/serialization/Mappings.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.data.utils.serialization\n\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.toColorModel\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.component6\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.component7\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.component8\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.component9\nimport com.t8rin.imagetoolbox.core.domain.utils.Quad\nimport com.t8rin.imagetoolbox.core.domain.utils.simpleName\nimport com.t8rin.imagetoolbox.core.filters.domain.model.FilterValueWrapper\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.BlurEdgeMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.MirrorSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PolarCoordinatesType\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.PopArtBlendingMode\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.TransferFunc\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ArcParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.AsciiParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BilaterialBlurParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.BloomParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ChannelMixParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ClaheParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.CropOrPerspectiveParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.EnhancedZoomBlurParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.GlitchParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.KaleidoscopeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearGaussianParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.LinearTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.PinchParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RadialTiltShiftParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.RubberStampParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SideFadeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SmearParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SparkleParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.ToneCurvesParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.VoronoiCrystallizeParams\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.WaterParams\nimport com.t8rin.imagetoolbox.core.settings.domain.model.DomainFontFamily\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.asDomain\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.asFontType\nimport kotlin.io.encoding.Base64\n\ninternal fun Any.toPair(): Pair<String, String>? {\n    return when (this) {\n        is Int -> Int::class.simpleName() to toString()\n        is Float -> Float::class.simpleName() to toString()\n        is Unit -> Unit::class.simpleName() to \"Unit\"\n        is PolarCoordinatesType -> PolarCoordinatesType::class.simpleName() to name\n        is FloatArray -> FloatArray::class.simpleName() to joinToString(separator = PROPERTIES_SEPARATOR) { it.toString() }\n        is FilterValueWrapper<*> -> {\n            when (wrapped) {\n                is ColorModel -> \"${FilterValueWrapper::class.simpleName()}{${ColorModel::class.simpleName}}\" to (wrapped as ColorModel).colorInt\n                    .toString()\n\n                else -> null\n            }\n        }\n\n        is Pair<*, *> -> {\n            val firstPart = first!!.toPart()\n            val secondPart = second!!.toPart()\n            \"${Pair::class.simpleName}{${first!!::class.simpleName}$PROPERTIES_SEPARATOR${second!!::class.simpleName}}\" to listOf(\n                firstPart,\n                secondPart\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is Triple<*, *, *> -> {\n            val firstPart = first!!.toPart()\n            val secondPart = second!!.toPart()\n            val thirdPart = third!!.toPart()\n\n            \"${Triple::class.simpleName}{${first!!::class.simpleName}$PROPERTIES_SEPARATOR${second!!::class.simpleName}$PROPERTIES_SEPARATOR${third!!::class.simpleName}}\" to listOf(\n                firstPart,\n                secondPart,\n                thirdPart\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is Quad<*, *, *, *> -> {\n            val firstPart = first!!.toPart()\n            val secondPart = second!!.toPart()\n            val thirdPart = third!!.toPart()\n            val fourthPart = fourth!!.toPart()\n\n            \"${Quad::class.simpleName}{${first!!::class.simpleName}$PROPERTIES_SEPARATOR${second!!::class.simpleName}$PROPERTIES_SEPARATOR${third!!::class.simpleName}$PROPERTIES_SEPARATOR${fourth!!::class.simpleName}}\" to listOf(\n                firstPart,\n                secondPart,\n                thirdPart,\n                fourthPart\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is GlitchParams -> {\n            GlitchParams::class.simpleName() to listOf(\n                channelsShiftX,\n                channelsShiftY,\n                corruptionSize,\n                corruptionCount,\n                corruptionShiftX,\n                corruptionShiftY\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is LinearTiltShiftParams -> {\n            LinearTiltShiftParams::class.simpleName() to listOf(\n                blurRadius,\n                sigma,\n                anchorX,\n                anchorY,\n                holeRadius,\n                angle\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is RadialTiltShiftParams -> {\n            RadialTiltShiftParams::class.simpleName() to listOf(\n                blurRadius,\n                sigma,\n                anchorX,\n                anchorY,\n                holeRadius\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is EnhancedZoomBlurParams -> {\n            EnhancedZoomBlurParams::class.simpleName() to listOf(\n                radius,\n                sigma,\n                centerX,\n                centerY,\n                strength,\n                angle\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is SideFadeParams.Relative -> {\n            SideFadeParams::class.simpleName() to listOf(\n                side.name, scale\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is WaterParams -> {\n            WaterParams::class.simpleName() to listOf(\n                fractionSize,\n                frequencyX,\n                frequencyY,\n                amplitudeX,\n                amplitudeY\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is ClaheParams -> {\n            ClaheParams::class.simpleName() to listOf(\n                threshold,\n                gridSizeHorizontal,\n                gridSizeVertical,\n                binsCount\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is LinearGaussianParams -> {\n            LinearGaussianParams::class.simpleName() to listOf(\n                kernelSize,\n                sigma,\n                edgeMode.name,\n                transferFunction.name\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is ToneCurvesParams -> {\n            ToneCurvesParams::class.simpleName() to controlPoints.joinToString(PROPERTIES_SEPARATOR) {\n                it.joinToString(ADDITIONAL_PROPERTIES_SEPARATOR)\n            }\n        }\n\n        is BilaterialBlurParams -> {\n            BilaterialBlurParams::class.simpleName() to listOf(\n                radius,\n                spatialSigma,\n                rangeSigma,\n                edgeMode.name\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is KaleidoscopeParams -> {\n            KaleidoscopeParams::class.simpleName() to listOf(\n                angle,\n                angle2,\n                centreX,\n                centreY,\n                sides,\n                radius\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is ChannelMixParams -> {\n            ChannelMixParams::class.simpleName() to listOf(\n                blueGreen,\n                redBlue,\n                greenRed,\n                intoR,\n                intoG,\n                intoB\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is VoronoiCrystallizeParams -> {\n            VoronoiCrystallizeParams::class.simpleName!! to listOf(\n                borderThickness,\n                scale,\n                randomness,\n                shape,\n                turbulence,\n                angle,\n                stretch,\n                amount,\n                color.colorInt\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is PinchParams -> {\n            PinchParams::class.simpleName!! to listOf(\n                angle,\n                centreX,\n                centreY,\n                radius,\n                amount\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is RubberStampParams -> {\n            RubberStampParams::class.simpleName!! to listOf(\n                threshold,\n                softness,\n                radius,\n                firstColor.colorInt,\n                secondColor.colorInt,\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is SmearParams -> {\n            SmearParams::class.simpleName!! to listOf(\n                angle,\n                density,\n                mix,\n                distance,\n                shape,\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is ArcParams -> {\n            ArcParams::class.simpleName!! to listOf(\n                radius,\n                height,\n                angle,\n                spreadAngle,\n                centreX,\n                centreY\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is SparkleParams -> {\n            SparkleParams::class.simpleName!! to listOf(\n                amount,\n                rays,\n                radius,\n                randomness,\n                centreX,\n                centreY,\n                color.colorInt\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is AsciiParams -> {\n            val font = font?.asDomain()?.takeIf { it !is DomainFontFamily.Custom }\n                ?: DomainFontFamily.System\n\n            AsciiParams::class.simpleName!! to listOf(\n                Base64.encode(gradient.toByteArray(Charsets.UTF_8)),\n                fontSize,\n                backgroundColor.colorInt,\n                isGrayscale,\n                font.asString()\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is BloomParams -> {\n            BloomParams::class.simpleName!! to listOf(\n                threshold,\n                intensity,\n                radius,\n                softKnee,\n                exposure,\n                gamma\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is CropOrPerspectiveParams -> {\n            CropOrPerspectiveParams::class.simpleName!! to listOf(\n                topLeft.join(),\n                topRight.join(),\n                bottomLeft.join(),\n                bottomRight.join(),\n                isAbsolute\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        is IntegerSize -> {\n            IntegerSize::class.simpleName!! to listOf(\n                width,\n                height\n            ).joinToString(PROPERTIES_SEPARATOR)\n        }\n\n        else -> null\n    }\n}\n\ninternal fun Pair<String, String>.fromPair(): Any? {\n    val name = first.trim()\n    val value = second.trim()\n\n    return when {\n        name == Int::class.simpleName -> value.toInt()\n        name == Float::class.simpleName -> value.toFloat()\n        name == Boolean::class.simpleName -> value.toBoolean()\n        name == Unit::class.simpleName -> Unit\n        name == PolarCoordinatesType::class.simpleName -> PolarCoordinatesType.valueOf(value)\n        name == FloatArray::class.simpleName -> value.split(PROPERTIES_SEPARATOR)\n            .map { it.toFloat() }\n            .toFloatArray()\n\n        \"${FilterValueWrapper::class.simpleName}{\" in name -> {\n            when (name.getTypeFromBraces()) {\n                ColorModel::class.simpleName -> FilterValueWrapper(ColorModel(value.toInt()))\n                else -> null\n            }\n        }\n\n        \"${Pair::class.simpleName}{\" in name -> {\n            val (firstType, secondType) = name.getTypeFromBraces().split(PROPERTIES_SEPARATOR)\n            val (firstPart, secondPart) = value.split(PROPERTIES_SEPARATOR)\n            firstPart.fromPart(firstType) to secondPart.fromPart(secondType)\n        }\n\n        \"${Triple::class.simpleName}{\" in name -> {\n            val (firstType, secondType, thirdType) = name.getTypeFromBraces()\n                .split(PROPERTIES_SEPARATOR)\n            val (firstPart, secondPart, thirdPart) = value.split(PROPERTIES_SEPARATOR)\n            Triple(\n                firstPart.fromPart(firstType),\n                secondPart.fromPart(secondType),\n                thirdPart.fromPart(thirdType)\n            )\n        }\n\n        \"${Quad::class.simpleName}{\" in name -> {\n            val (firstType, secondType, thirdType, fourthType) = name.getTypeFromBraces()\n                .split(PROPERTIES_SEPARATOR)\n            val (firstPart, secondPart, thirdPart, fourthPart) = value.split(PROPERTIES_SEPARATOR)\n            Quad(\n                firstPart.fromPart(firstType),\n                secondPart.fromPart(secondType),\n                thirdPart.fromPart(thirdType),\n                fourthPart.fromPart(fourthType)\n            )\n        }\n\n        name == GlitchParams::class.simpleName -> {\n            val (\n                channelsShiftX,\n                channelsShiftY,\n                corruptionSize,\n                corruptionCount,\n                corruptionShiftX,\n                corruptionShiftY,\n            ) = value.split(PROPERTIES_SEPARATOR)\n            GlitchParams(\n                channelsShiftX = channelsShiftX.toFloat(),\n                channelsShiftY = channelsShiftY.toFloat(),\n                corruptionSize = corruptionSize.toFloat(),\n                corruptionCount = corruptionCount.toInt(),\n                corruptionShiftX = corruptionShiftX.toFloat(),\n                corruptionShiftY = corruptionShiftY.toFloat()\n            )\n        }\n\n        name == LinearTiltShiftParams::class.simpleName -> {\n            val (blurRadius, sigma, anchorX, anchorY, holeRadius, angle) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            LinearTiltShiftParams(\n                blurRadius = blurRadius.toFloat(),\n                sigma = sigma.toFloat(),\n                anchorX = anchorX.toFloat(),\n                anchorY = anchorY.toFloat(),\n                holeRadius = holeRadius.toFloat(),\n                angle = angle.toFloat()\n            )\n        }\n\n        name == RadialTiltShiftParams::class.simpleName -> {\n            val (blurRadius, sigma, anchorX, anchorY, holeRadius) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            RadialTiltShiftParams(\n                blurRadius = blurRadius.toFloat(),\n                sigma = sigma.toFloat(),\n                anchorX = anchorX.toFloat(),\n                anchorY = anchorY.toFloat(),\n                holeRadius = holeRadius.toFloat()\n            )\n        }\n\n        name == EnhancedZoomBlurParams::class.simpleName -> {\n            val (radius, sigma, centerX, centerY, strength, angle) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            EnhancedZoomBlurParams(\n                radius = radius.toInt(),\n                sigma = sigma.toFloat(),\n                centerX = centerX.toFloat(),\n                centerY = centerY.toFloat(),\n                strength = strength.toFloat(),\n                angle = angle.toFloat()\n            )\n        }\n\n        name == SideFadeParams::class.simpleName -> {\n            val (sideName, scale) = value.split(PROPERTIES_SEPARATOR)\n            SideFadeParams.Relative(\n                side = FadeSide.valueOf(sideName),\n                scale = scale.toFloat()\n            )\n        }\n\n        name == WaterParams::class.simpleName -> {\n            val (fractionSize, frequencyX, frequencyY, amplitudeX, amplitudeY) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            WaterParams(\n                fractionSize = fractionSize.toFloat(),\n                frequencyX = frequencyX.toFloat(),\n                frequencyY = frequencyY.toFloat(),\n                amplitudeX = amplitudeX.toFloat(),\n                amplitudeY = amplitudeY.toFloat()\n            )\n        }\n\n        name == ClaheParams::class.simpleName -> {\n            val (threshold, gridSizeHorizontal, gridSizeVertical, binsCount) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            ClaheParams(\n                threshold = threshold.toFloat(),\n                gridSizeHorizontal = gridSizeHorizontal.toInt(),\n                gridSizeVertical = gridSizeVertical.toInt(),\n                binsCount = binsCount.toInt()\n            )\n        }\n\n        name == LinearGaussianParams::class.simpleName -> {\n            val (kernelSize, sigma, edgeModeName, transferFunctionName) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            LinearGaussianParams(\n                kernelSize = kernelSize.toInt(),\n                sigma = sigma.toFloat(),\n                edgeMode = BlurEdgeMode.valueOf(edgeModeName),\n                transferFunction = TransferFunc.valueOf(transferFunctionName)\n            )\n        }\n\n        name == ToneCurvesParams::class.simpleName -> {\n            val controlPoints = value.split(PROPERTIES_SEPARATOR).map { valueString ->\n                valueString.split(ADDITIONAL_PROPERTIES_SEPARATOR).map {\n                    it.toFloatOrNull() ?: 0f\n                }\n            }\n\n            ToneCurvesParams(\n                controlPoints = controlPoints\n            )\n        }\n\n        name == BilaterialBlurParams::class.simpleName -> {\n            val (radius, spatialSigma, rangeSigma, edgeMode) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            BilaterialBlurParams(\n                radius = radius.toInt(),\n                spatialSigma = spatialSigma.toFloat(),\n                rangeSigma = rangeSigma.toFloat(),\n                edgeMode = BlurEdgeMode.valueOf(edgeMode)\n            )\n        }\n\n        name == KaleidoscopeParams::class.simpleName -> {\n            val (angle, angle2, centreX, centreY, sides, radius) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n            KaleidoscopeParams(\n                angle = angle.toFloat(),\n                angle2 = angle2.toFloat(),\n                centreX = centreX.toFloat(),\n                centreY = centreY.toFloat(),\n                sides = sides.toInt(),\n                radius = radius.toFloat()\n            )\n        }\n\n        name == ChannelMixParams::class.simpleName -> {\n            val (blueGreen, redBlue, greenRed, intoR, intoG, intoB) = value.split(\n                PROPERTIES_SEPARATOR\n            ).map { it.toInt() }\n\n            ChannelMixParams(\n                blueGreen = blueGreen,\n                redBlue = redBlue,\n                greenRed = greenRed,\n                intoR = intoR,\n                intoG = intoG,\n                intoB = intoB\n            )\n        }\n\n        name == VoronoiCrystallizeParams::class.simpleName -> {\n            val (borderThickness, scale, randomness, shape, turbulence, angle, stretch, amount, color) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n\n            VoronoiCrystallizeParams(\n                borderThickness = borderThickness.toFloat(),\n                scale = scale.toFloat(),\n                randomness = randomness.toFloat(),\n                shape = shape.toInt(),\n                turbulence = turbulence.toFloat(),\n                angle = angle.toFloat(),\n                stretch = stretch.toFloat(),\n                amount = amount.toFloat(),\n                color = color.toInt().toColorModel()\n            )\n        }\n\n        name == PinchParams::class.simpleName -> {\n            val (angle, centreX, centreY, radius, amount) = value.split(\n                PROPERTIES_SEPARATOR\n            ).map { it.toFloat() }\n\n            PinchParams(\n                angle = angle,\n                centreX = centreX,\n                centreY = centreY,\n                radius = radius,\n                amount = amount\n            )\n        }\n\n        name == RubberStampParams::class.simpleName -> {\n            val (threshold, softness, radius, firstColor, secondColor) = value.split(\n                PROPERTIES_SEPARATOR\n            ).map { it.toFloat() }\n\n            RubberStampParams(\n                threshold = threshold,\n                softness = softness,\n                radius = radius,\n                firstColor = firstColor.toInt().toColorModel(),\n                secondColor = secondColor.toInt().toColorModel()\n            )\n        }\n\n        name == SmearParams::class.simpleName -> {\n            val (angle, density, mix, distance, shape) = value.split(\n                PROPERTIES_SEPARATOR\n            ).map { it.toFloat() }\n\n            SmearParams(\n                angle = angle,\n                density = density,\n                mix = mix,\n                distance = distance.toInt(),\n                shape = shape.toInt()\n            )\n        }\n\n        name == ArcParams::class.simpleName -> {\n            val (radius, height, angle, spreadAngle, centreX, centreY) = value.split(\n                PROPERTIES_SEPARATOR\n            ).map { it.toFloat() }\n\n            ArcParams(\n                radius = radius,\n                height = height,\n                angle = angle,\n                spreadAngle = spreadAngle,\n                centreX = centreX,\n                centreY = centreY\n            )\n        }\n\n        name == SparkleParams::class.simpleName -> {\n            val (amount, rays, radius, randomness, centreX, centreY, color) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n\n            SparkleParams(\n                amount = amount.toInt(),\n                rays = rays.toInt(),\n                radius = radius.toFloat(),\n                randomness = randomness.toInt(),\n                centreX = centreX.toFloat(),\n                centreY = centreY.toFloat(),\n                color = color.toInt().toColorModel()\n            )\n        }\n\n        name == AsciiParams::class.simpleName -> {\n            val (gradient, fontSize, backgroundColor, isGrayscale, font) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n\n            AsciiParams(\n                gradient = Base64.decode(gradient).toString(Charsets.UTF_8),\n                fontSize = fontSize.toFloat(),\n                backgroundColor = backgroundColor.toInt().toColorModel(),\n                isGrayscale = isGrayscale.toBoolean(),\n                font = DomainFontFamily.fromString(font).asFontType()\n            )\n        }\n\n        name == BloomParams::class.simpleName -> {\n            val (threshold, intensity, radius, softKnee, exposure, gamma) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n\n            BloomParams(\n                threshold = threshold.toFloat(),\n                intensity = intensity.toFloat(),\n                radius = radius.toInt(),\n                softKnee = softKnee.toFloat(),\n                exposure = exposure.toFloat(),\n                gamma = gamma.toFloat()\n            )\n        }\n\n        name == CropOrPerspectiveParams::class.simpleName -> {\n            val (topLeft, topRight, bottomLeft, bottomRight, isAbsolute) = value.split(\n                PROPERTIES_SEPARATOR\n            )\n\n            CropOrPerspectiveParams(\n                topLeft = topLeft.toFloatPair(),\n                topRight = topRight.toFloatPair(),\n                bottomLeft = bottomLeft.toFloatPair(),\n                bottomRight = bottomRight.toFloatPair(),\n                isAbsolute = isAbsolute.toBoolean()\n            )\n        }\n\n        name == IntegerSize::class.simpleName -> {\n            val (width, height) = value.split(PROPERTIES_SEPARATOR)\n\n            IntegerSize(\n                width = width.toInt(),\n                height = height.toInt()\n            )\n        }\n\n        else -> null\n    }\n}\n\ninternal fun String.getTypeFromBraces(): String = removeSuffix(\"}\").split(\"{\")[1]\n\ninternal fun Any.toPart(): String {\n    return when (this) {\n        is Int -> toString()\n        is Float -> toString()\n        is ColorModel -> colorInt.toString()\n        is Boolean -> toString()\n        is BlurEdgeMode -> name\n        is TransferFunc -> name\n        is FadeSide -> name\n        is PopArtBlendingMode -> name\n        is MirrorSide -> name\n        is PolarCoordinatesType -> name\n        else -> \"\"\n    }\n}\n\ninternal fun String.fromPart(type: String): Any {\n    return when (type) {\n        Int::class.simpleName() -> toInt()\n        Float::class.simpleName() -> toFloat()\n        ColorModel::class.simpleName() -> ColorModel(toInt())\n        Boolean::class.simpleName() -> toBoolean()\n        BlurEdgeMode::class.simpleName() -> BlurEdgeMode.valueOf(this)\n        TransferFunc::class.simpleName() -> TransferFunc.valueOf(this)\n        FadeSide::class.simpleName() -> FadeSide.valueOf(this)\n        PopArtBlendingMode::class.simpleName() -> PopArtBlendingMode.valueOf(this)\n        MirrorSide::class.simpleName() -> MirrorSide.valueOf(this)\n        PolarCoordinatesType::class.simpleName() -> PolarCoordinatesType.valueOf(this)\n        else -> \"\"\n    }\n}\n\nprivate fun Pair<*, *>.join() = \"$first$ADDITIONAL_PROPERTIES_SEPARATOR$second\"\nprivate fun String.toFloatPair() =\n    split(ADDITIONAL_PROPERTIES_SEPARATOR).let { it[0].toFloat() to it[1].toFloat() }\n\nprivate const val PROPERTIES_SEPARATOR = \"$\"\nprivate const val ADDITIONAL_PROPERTIES_SEPARATOR = \"*\""
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/di/FilterModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.di\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterParamsInteractor\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.feature.filters.data.AndroidFilterMaskApplier\nimport com.t8rin.imagetoolbox.feature.filters.data.AndroidFilterParamsInteractor\nimport com.t8rin.imagetoolbox.feature.filters.data.AndroidFilterProvider\nimport com.t8rin.imagetoolbox.feature.filters.domain.FilterMaskApplier\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface FilterModule {\n\n    @Singleton\n    @Binds\n    fun filterProvider(\n        provider: AndroidFilterProvider\n    ): FilterProvider<Bitmap>\n\n    @Singleton\n    @Binds\n    fun filterMaskApplier(\n        applier: AndroidFilterMaskApplier\n    ): FilterMaskApplier<Bitmap, Path, Color>\n\n    @Singleton\n    @Binds\n    fun favoriteFiltersInteractor(\n        interactor: AndroidFilterParamsInteractor\n    ): FilterParamsInteractor\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/domain/FilterMask.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.domain\n\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.feature.draw.domain.PathPaint\n\ninterface FilterMask<Path, Color> {\n    val maskPaints: List<PathPaint<Path, Color>>\n    val filters: List<Filter<*>>\n    val isInverseFillType: Boolean\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/domain/FilterMaskApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.domain\n\ninterface FilterMaskApplier<Image, Path, Color> {\n\n    suspend fun filterByMask(\n        filterMask: FilterMask<Path, Color>,\n        imageUri: String\n    ): Image?\n\n    suspend fun filterByMask(\n        filterMask: FilterMask<Path, Color>,\n        image: Image\n    ): Image?\n\n    suspend fun filterByMasks(\n        filterMasks: List<FilterMask<Path, Color>>,\n        imageUri: String\n    ): Image?\n\n    suspend fun filterByMasks(\n        filterMasks: List<FilterMask<Path, Color>>,\n        image: Image\n    ): Image?\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/FiltersContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvideFilterPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.CompareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShowOriginalButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareSheet\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.FiltersContentActionButtons\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.FiltersContentControls\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.FiltersContentNoData\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.FiltersContentSheets\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.FiltersContentTopAppBarActions\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\n\n@Composable\nfun FiltersContent(\n    component: FiltersComponent\n) {\n    AutoContentBasedColors(component.previewBitmap)\n\n    val imagePicker = rememberImagePicker(onSuccess = component::setBasicFilter)\n\n    val pickSingleImagePicker = rememberImagePicker(onSuccess = component::setMaskFilter)\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else if (component.filterType != null) {\n            component.clearType()\n        } else component.onGoBack()\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showOriginal by remember { mutableStateOf(false) }\n\n    val actions: @Composable RowScope.() -> Unit = {\n        Spacer(modifier = Modifier.width(8.dp))\n        if (component.bitmap != null) {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.canSave,\n                onShare = component::performSharing,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n            ShowOriginalButton(\n                canShow = component.canShow(),\n                onStateChange = {\n                    showOriginal = it\n                }\n            )\n        }\n        var showCompareSheet by rememberSaveable { mutableStateOf(false) }\n        CompareButton(\n            onClick = { showCompareSheet = true },\n            visible = component.previewBitmap != null\n        )\n        CompareSheet(\n            data = component.bitmap to component.previewBitmap,\n            visible = showCompareSheet,\n            onDismiss = {\n                showCompareSheet = false\n            }\n        )\n\n        if (component.bitmap != null && (component.basicFilterState.filters.size >= 2 || component.maskingFilterState.masks.size >= 2)) {\n            EnhancedIconButton(\n                onClick = component::showReorderSheet\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Tune,\n                    contentDescription = stringResource(R.string.properties)\n                )\n            }\n        }\n    }\n\n    var tempSelectionUris by rememberSaveable {\n        mutableStateOf<List<Uri>?>(\n            null\n        )\n    }\n\n    LaunchedEffect(component.isSelectionFilterPickerVisible) {\n        if (!component.isSelectionFilterPickerVisible) tempSelectionUris = null\n    }\n\n    val selectionFilterPicker = rememberImagePicker { uris: List<Uri> ->\n        tempSelectionUris = uris\n        if (uris.size > 1) {\n            component.setBasicFilter(tempSelectionUris)\n        } else {\n            component.showSelectionFilterPicker()\n        }\n    }\n\n    AutoFilePicker(\n        onAutoPick = selectionFilterPicker::pickImage,\n        isPickedAlready = component.initialType != null\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !(component.haveChanges || component.filterType != null),\n        onGoBack = onBack,\n        title = {\n            AnimatedContent(\n                targetState = component.filterType?.let {\n                    stringResource(it.title)\n                }\n            ) { title ->\n                if (title == null) {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        modifier = Modifier.marquee()\n                    ) {\n                        Text(\n                            text = stringResource(R.string.filter)\n                        )\n                        EnhancedBadge(\n                            content = {\n                                Text(\n                                    text = UiFilter.count.toString()\n                                )\n                            },\n                            containerColor = MaterialTheme.colorScheme.tertiary,\n                            contentColor = MaterialTheme.colorScheme.onTertiary,\n                            modifier = Modifier\n                                .padding(horizontal = 2.dp)\n                                .padding(bottom = 12.dp)\n                                .scaleOnTap {\n                                    AppToastHost.showConfetti()\n                                }\n                        )\n                    }\n                } else {\n                    TopAppBarTitle(\n                        title = title,\n                        input = component.bitmap,\n                        isLoading = component.isImageLoading,\n                        size = component.imageInfo.sizeInBytes.toLong()\n                    )\n                }\n            }\n        },\n        topAppBarPersistentActions = {\n            FiltersContentTopAppBarActions(\n                component = component,\n                actions = actions\n            )\n        },\n        actions = actions,\n        showActionsInTopAppBar = false,\n        canShowScreenData = component.filterType != null,\n        imagePreview = {\n            ImageContainer(\n                modifier = Modifier\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                imageInside = isPortrait,\n                showOriginal = showOriginal,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.bitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = true,\n                animatePreviewChange = false\n            )\n        },\n        forceImagePreviewToMax = showOriginal,\n        controls = {\n            FiltersContentControls(component)\n        },\n        buttons = { bottomActions ->\n            FiltersContentActionButtons(\n                component = component,\n                actions = bottomActions,\n                imagePicker = imagePicker,\n                pickSingleImagePicker = pickSingleImagePicker,\n                selectionFilterPicker = selectionFilterPicker\n            )\n        },\n        insetsForNoData = WindowInsets(0),\n        noDataControls = {\n            FiltersContentNoData(\n                component = component,\n                imagePicker = imagePicker,\n                pickSingleImagePicker = pickSingleImagePicker,\n                tempSelectionUris = tempSelectionUris\n            )\n        },\n        contentPadding = animateDpAsState(\n            if (component.filterType == null) 12.dp\n            else 20.dp\n        ).value,\n    )\n\n    ProvideFilterPreview(component.previewBitmap)\n\n    FiltersContentSheets(component)\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = {\n            if (component.filterType != null) {\n                component.clearType()\n            } else {\n                component.onGoBack()\n            }\n        },\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/BasicFilterPreference.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun BasicFilterPreference(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    color: Color = Color.Unspecified\n) {\n    PreferenceItem(\n        onClick = onClick,\n        startIcon = Icons.Rounded.AutoFixHigh,\n        title = stringResource(R.string.filter),\n        subtitle = stringResource(R.string.filter_sub),\n        containerColor = color,\n        modifier = modifier\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/BasicFilterState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport android.net.Uri\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\n\ndata class BasicFilterState(\n    val uris: List<Uri>? = null,\n    val filters: List<UiFilter<*>> = emptyList(),\n    val selectedUri: Uri? = null\n)"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/FiltersContentActionButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material.icons.rounded.Texture\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\n\n@Composable\ninternal fun FiltersContentActionButtons(\n    component: FiltersComponent,\n    actions: @Composable RowScope.() -> Unit,\n    imagePicker: ImagePicker,\n    pickSingleImagePicker: ImagePicker,\n    selectionFilterPicker: ImagePicker,\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    val filterType = component.filterType\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        when (filterType) {\n            is Screen.Filter.Type.Basic -> {\n                component.saveBitmaps(\n                    oneTimeSaveLocationUri = it\n                )\n            }\n\n            is Screen.Filter.Type.Masking -> {\n                component.saveMaskedBitmap(\n                    oneTimeSaveLocationUri = it\n                )\n            }\n\n            else -> Unit\n        }\n    }\n    var showFolderSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    BottomButtonsBlock(\n        isNoData = component.basicFilterState.uris.isNullOrEmpty() && component.maskingFilterState.uri == null,\n        onSecondaryButtonClick = {\n            when (filterType) {\n                is Screen.Filter.Type.Basic -> imagePicker.pickImage()\n                is Screen.Filter.Type.Masking -> pickSingleImagePicker.pickImage()\n                null -> selectionFilterPicker.pickImage()\n            }\n        },\n        onPrimaryButtonClick = {\n            saveBitmaps(null)\n        },\n        onPrimaryButtonLongClick = {\n            showFolderSelectionDialog = true\n        },\n        isPrimaryButtonVisible = component.canSave,\n        middleFab = {\n            EnhancedFloatingActionButton(\n                onClick = component::showAddFiltersSheet,\n                containerColor = MaterialTheme.colorScheme.mixedContainer\n            ) {\n                when (filterType) {\n                    is Screen.Filter.Type.Basic -> {\n                        Icon(\n                            imageVector = Icons.Rounded.AutoFixHigh,\n                            contentDescription = null\n                        )\n                    }\n\n                    is Screen.Filter.Type.Masking -> {\n                        Icon(\n                            imageVector = Icons.Rounded.Texture,\n                            contentDescription = null\n                        )\n                    }\n\n                    null -> Unit\n                }\n            }\n\n        },\n        actions = {\n            if (isPortrait) actions()\n        },\n        onSecondaryButtonLongClick = {\n            showOneTimeImagePickingDialog = true\n        },\n        showNullDataButtonAsContainer = true\n    )\n    OneTimeSaveLocationSelectionDialog(\n        visible = showFolderSelectionDialog,\n        onDismiss = { showFolderSelectionDialog = false },\n        onSaveRequest = saveBitmaps,\n        formatForFilenameSelection = component.getFormatForFilenameSelection()\n    )\n    OneTimeImagePickingDialog(\n        onDismiss = { showOneTimeImagePickingDialog = false },\n        picker = if (filterType !is Screen.Filter.Type.Masking) {\n            Picker.Multiple\n        } else {\n            Picker.Single\n        },\n        imagePicker = selectionFilterPicker,\n        visible = showOneTimeImagePickingDialog\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/FiltersContentControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Texture\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.AddFilterButton\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheet\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.HistogramChart\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\n\n@Composable\ninternal fun FiltersContentControls(\n    component: FiltersComponent\n) {\n    val filterType = component.filterType\n\n    var showTemplateCreationSheet by rememberSaveable(filterType) {\n        mutableStateOf(false)\n    }\n\n    val histogramItem = @Composable {\n        PreferenceItemOverload(\n            title = stringResource(R.string.histogram),\n            subtitle = stringResource(R.string.histogram_sub),\n            endIcon = {\n                AnimatedContent(component.previewBitmap != null) {\n                    if (it) {\n                        HistogramChart(\n                            model = component.previewBitmap,\n                            modifier = Modifier\n                                .width(100.dp)\n                                .height(65.dp)\n                                .background(MaterialTheme.colorScheme.background)\n                        )\n                    } else {\n                        Box(modifier = Modifier.size(56.dp)) {\n                            EnhancedLoadingIndicator()\n                        }\n                    }\n                }\n            },\n            shape = ShapeDefaults.extraLarge,\n            modifier = Modifier.fillMaxWidth()\n        )\n        Spacer(Modifier.size(8.dp))\n    }\n\n    when (filterType) {\n        is Screen.Filter.Type.Basic -> {\n            val filterList = component.basicFilterState.filters\n            if (component.bitmap != null) {\n                ImageCounter(\n                    imageCount = component.basicFilterState.uris?.size?.takeIf { it > 1 },\n                    onRepick = component::showPickImageFromUrisSheet\n                )\n                if (filterList.isNotEmpty()) histogramItem()\n                AnimatedContent(\n                    targetState = filterList.isNotEmpty(),\n                    transitionSpec = {\n                        fadeIn() + expandVertically() togetherWith fadeOut() + shrinkVertically()\n                    }\n                ) { notEmpty ->\n                    if (notEmpty) {\n                        Column(Modifier.container(MaterialTheme.shapes.extraLarge)) {\n                            TitleItem(text = stringResource(R.string.filters))\n                            Column(\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                verticalArrangement = Arrangement.spacedBy(\n                                    8.dp\n                                ),\n                                modifier = Modifier.padding(8.dp)\n                            ) {\n                                filterList.forEachIndexed { index, filter ->\n                                    FilterItem(\n                                        backgroundColor = MaterialTheme.colorScheme.surface,\n                                        filter = filter,\n                                        onFilterChange = { newValue ->\n                                            component.updateFilter(\n                                                value = newValue,\n                                                index = index\n                                            )\n                                        },\n                                        onLongPress = component::showReorderSheet,\n                                        showDragHandle = false,\n                                        onRemove = {\n                                            component.removeFilterAtIndex(index)\n                                        },\n                                        onCreateTemplate = {\n                                            showTemplateCreationSheet = true\n                                            component.filterTemplateCreationSheetComponent.setInitialTemplateFilter(\n                                                TemplateFilter(\n                                                    name = getString(filter.title),\n                                                    filters = listOf(filter)\n                                                )\n                                            )\n                                        }\n                                    )\n                                }\n                                AddFilterButton(\n                                    modifier = Modifier.padding(horizontal = 16.dp),\n                                    onClick = component::showAddFiltersSheet,\n                                    onCreateTemplate = {\n                                        showTemplateCreationSheet = true\n                                        component.filterTemplateCreationSheetComponent.setInitialTemplateFilter(\n                                            TemplateFilter(\n                                                name = getString(\n                                                    filterList.firstOrNull()?.title\n                                                        ?: R.string.template_filter\n                                                ),\n                                                filters = filterList\n                                            )\n                                        )\n                                    }\n                                )\n                            }\n                        }\n                    } else {\n                        AddFilterButton(\n                            onClick = component::showAddFiltersSheet,\n                            modifier = Modifier.padding(\n                                horizontal = 16.dp\n                            )\n                        )\n                    }\n                }\n                Spacer(Modifier.size(8.dp))\n                if (filterList.isEmpty()) histogramItem()\n                SaveExifWidget(\n                    imageFormat = component.imageInfo.imageFormat,\n                    checked = component.keepExif,\n                    onCheckedChange = component::setKeepExif\n                )\n                if (component.imageInfo.imageFormat.canChangeCompressionValue) Spacer(\n                    Modifier.size(8.dp)\n                )\n                QualitySelector(\n                    imageFormat = component.imageInfo.imageFormat,\n                    quality = component.imageInfo.quality,\n                    onQualityChange = component::setQuality\n                )\n                Spacer(Modifier.size(8.dp))\n                ImageFormatSelector(\n                    value = component.imageInfo.imageFormat,\n                    onValueChange = component::setImageFormat,\n                    quality = component.imageInfo.quality,\n                )\n            }\n            Spacer(Modifier.height(8.dp))\n        }\n\n        is Screen.Filter.Type.Masking -> {\n            val maskList = component.maskingFilterState.masks\n            if (component.bitmap != null) {\n                if (maskList.isNotEmpty()) histogramItem()\n                AnimatedContent(\n                    targetState = maskList.isNotEmpty(),\n                    transitionSpec = {\n                        fadeIn() + expandVertically() togetherWith fadeOut() + shrinkVertically()\n                    }\n                ) { notEmpty ->\n                    if (notEmpty) {\n                        Column(Modifier.container(MaterialTheme.shapes.extraLarge)) {\n                            TitleItem(text = stringResource(R.string.masks))\n                            Column(\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                verticalArrangement = Arrangement.spacedBy(\n                                    4.dp\n                                ),\n                                modifier = Modifier.padding(8.dp)\n                            ) {\n                                maskList.forEachIndexed { index, mask ->\n                                    MaskItem(\n                                        backgroundColor = MaterialTheme.colorScheme.surface,\n                                        imageUri = component.maskingFilterState.uri,\n                                        previousMasks = maskList.take(index),\n                                        mask = mask,\n                                        titleText = stringResource(\n                                            R.string.mask_indexed,\n                                            index + 1\n                                        ),\n                                        onMaskChange = { filterMask ->\n                                            component.updateMask(\n                                                value = filterMask,\n                                                index = index\n                                            )\n                                        },\n                                        onLongPress = component::showReorderSheet,\n                                        showDragHandle = false,\n                                        onRemove = {\n                                            component.removeMaskAtIndex(index)\n                                        },\n                                        addMaskSheetComponent = component.addMaskSheetComponent,\n                                        onCreateTemplate = {\n                                            showTemplateCreationSheet = true\n                                            component.filterTemplateCreationSheetComponent.setInitialTemplateFilter(\n                                                TemplateFilter(\n                                                    name = getString(\n                                                        mask.filters.firstOrNull()\n                                                            ?.toUiFilter()?.title\n                                                            ?: R.string.template_filter\n                                                    ),\n                                                    filters = mask.filters\n                                                )\n                                            )\n                                        }\n                                    )\n                                }\n                                EnhancedButton(\n                                    containerColor = MaterialTheme.colorScheme.mixedContainer,\n                                    onClick = component::showAddFiltersSheet,\n                                    modifier = Modifier.padding(\n                                        start = 16.dp,\n                                        end = 16.dp,\n                                        top = 4.dp\n                                    )\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Texture,\n                                        contentDescription = stringResource(R.string.add_mask)\n                                    )\n                                    Spacer(Modifier.width(8.dp))\n                                    Text(stringResource(id = R.string.add_mask))\n                                }\n                            }\n                        }\n                    } else {\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.mixedContainer,\n                            onClick = component::showAddFiltersSheet,\n                            modifier = Modifier.padding(\n                                horizontal = 16.dp\n                            )\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Texture,\n                                contentDescription = stringResource(R.string.add_mask)\n                            )\n                            Spacer(Modifier.width(8.dp))\n                            Text(stringResource(id = R.string.add_mask))\n                        }\n                    }\n                }\n                Spacer(Modifier.size(8.dp))\n                if (maskList.isEmpty()) histogramItem()\n                SaveExifWidget(\n                    imageFormat = component.imageInfo.imageFormat,\n                    checked = component.keepExif,\n                    onCheckedChange = component::setKeepExif\n                )\n                if (component.imageInfo.imageFormat.canChangeCompressionValue) Spacer(\n                    Modifier.size(8.dp)\n                )\n                QualitySelector(\n                    imageFormat = component.imageInfo.imageFormat,\n                    quality = component.imageInfo.quality,\n                    onQualityChange = component::setQuality\n                )\n                Spacer(Modifier.size(8.dp))\n                ImageFormatSelector(\n                    value = component.imageInfo.imageFormat,\n                    onValueChange = component::setImageFormat,\n                    quality = component.imageInfo.quality\n                )\n            }\n            Spacer(Modifier.height(8.dp))\n        }\n\n        else -> Unit\n    }\n\n    FilterTemplateCreationSheet(\n        component = component.filterTemplateCreationSheetComponent,\n        visible = showTemplateCreationSheet,\n        onDismiss = { showTemplateCreationSheet = false }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/FiltersContentNoData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileOpen\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\n\n@Composable\ninternal fun FiltersContentNoData(\n    component: FiltersComponent,\n    imagePicker: ImagePicker,\n    pickSingleImagePicker: ImagePicker,\n    tempSelectionUris: List<Uri>?\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    val preference1 = @Composable {\n        BasicFilterPreference(\n            onClick = imagePicker::pickImage,\n            modifier = Modifier.fillMaxWidth()\n        )\n    }\n    val preference2 = @Composable {\n        MaskFilterPreference(\n            onClick = pickSingleImagePicker::pickImage,\n            modifier = Modifier.fillMaxWidth()\n        )\n    }\n    if (isPortrait) {\n        Column {\n            preference1()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference2()\n        }\n    } else {\n        val direction = LocalLayoutDirection.current\n        Row(\n            modifier = Modifier.padding(\n                WindowInsets.displayCutout.asPaddingValues()\n                    .let {\n                        PaddingValues(\n                            start = it.calculateStartPadding(direction),\n                            end = it.calculateEndPadding(direction)\n                        )\n                    }\n            )\n        ) {\n            preference1.withModifier(modifier = Modifier.weight(1f))\n            Spacer(modifier = Modifier.width(8.dp))\n            preference2.withModifier(modifier = Modifier.weight(1f))\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        visible = component.isSelectionFilterPickerVisible,\n        onDismiss = {\n            if (!it) component.hideSelectionFilterPicker()\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = component::hideSelectionFilterPicker,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(id = R.string.close))\n            }\n        },\n        sheetContent = {\n            SideEffect {\n                if (tempSelectionUris == null) {\n                    component.hideSelectionFilterPicker()\n                }\n            }\n\n            LazyVerticalStaggeredGrid(\n                columns = StaggeredGridCells.Adaptive(250.dp),\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = 12.dp,\n                    alignment = Alignment.CenterHorizontally\n                ),\n                verticalItemSpacing = 12.dp,\n                contentPadding = PaddingValues(12.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                item {\n                    BasicFilterPreference(\n                        onClick = {\n                            component.setBasicFilter(tempSelectionUris)\n                            component.hideSelectionFilterPicker()\n                        },\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                }\n                item {\n                    MaskFilterPreference(\n                        onClick = {\n                            component.setMaskFilter(tempSelectionUris?.firstOrNull())\n                            component.hideSelectionFilterPicker()\n                        },\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                }\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.pick_file),\n                icon = Icons.Rounded.FileOpen\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/FiltersContentSheets.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterReorderSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheet\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet.AddEditMaskSheet\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\n\n@Composable\ninternal fun FiltersContentSheets(\n    component: FiltersComponent\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    if (component.filterType is Screen.Filter.Type.Basic) {\n        val transformations by remember(component.basicFilterState, component.imageInfo) {\n            derivedStateOf(component::getFiltersTransformation)\n        }\n\n        PickImageFromUrisSheet(\n            transformations = transformations,\n            visible = component.isPickImageFromUrisSheetVisible,\n            onDismiss = component::hidePickImageFromUrisSheet,\n            uris = component.basicFilterState.uris,\n            selectedUri = component.basicFilterState.selectedUri,\n            onUriPicked = component::updateSelectedUri,\n            onUriRemoved = component::updateUrisSilently,\n            columns = if (isPortrait) 2 else 4,\n        )\n\n        AddFiltersSheet(\n            visible = component.isAddFiltersSheetVisible,\n            onDismiss = component::hideAddFiltersSheet,\n            previewBitmap = component.previewBitmap,\n            onFilterPicked = component::addFilterNewInstance,\n            onFilterPickedWithParams = component::addFilter,\n            component = component.addFiltersSheetComponent,\n            filterTemplateCreationSheetComponent = component.filterTemplateCreationSheetComponent\n        )\n\n        FilterReorderSheet(\n            filterList = component.basicFilterState.filters,\n            visible = component.isReorderSheetVisible,\n            onDismiss = component::hideReorderSheet,\n            onReorder = component::updateFiltersOrder\n        )\n    } else if (component.filterType is Screen.Filter.Type.Masking) {\n        AddEditMaskSheet(\n            visible = component.isAddFiltersSheetVisible,\n            targetBitmapUri = component.maskingFilterState.uri,\n            onMaskPicked = component::addMask,\n            onDismiss = component::hideAddFiltersSheet,\n            masks = component.maskingFilterState.masks,\n            component = component.addMaskSheetComponent\n        )\n\n        MaskReorderSheet(\n            maskList = component.maskingFilterState.masks,\n            visible = component.isReorderSheetVisible,\n            onDismiss = component::hideReorderSheet,\n            onReorder = component::updateMasksOrder\n        )\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/FiltersContentTopAppBarActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material.icons.rounded.Texture\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Eyedropper\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageSheet\n\n@Composable\ninternal fun RowScope.FiltersContentTopAppBarActions(\n    component: FiltersComponent,\n    actions: @Composable RowScope.() -> Unit\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    if (component.previewBitmap != null) {\n        var showColorPicker by rememberSaveable { mutableStateOf(false) }\n        var tempColor by rememberSaveable(\n            showColorPicker,\n            stateSaver = ColorSaver\n        ) { mutableStateOf(Color.Black) }\n\n        EnhancedIconButton(\n            onClick = {\n                showColorPicker = true\n            },\n            enabled = component.previewBitmap != null\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.Eyedropper,\n                contentDescription = stringResource(R.string.pipette)\n            )\n        }\n        PickColorFromImageSheet(\n            visible = showColorPicker,\n            onDismiss = {\n                showColorPicker = false\n            },\n            bitmap = component.previewBitmap,\n            onColorChange = { tempColor = it },\n            color = tempColor\n        )\n\n        var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n        ZoomButton(\n            onClick = { showZoomSheet = true },\n            visible = component.bitmap != null,\n        )\n        ZoomModalSheet(\n            data = component.previewBitmap,\n            visible = showZoomSheet,\n            onDismiss = {\n                showZoomSheet = false\n            }\n        )\n    }\n    if (component.bitmap == null) {\n        TopAppBarEmoji()\n    } else {\n        if (isPortrait) {\n            when (component.filterType) {\n                is Screen.Filter.Type.Basic -> {\n                    EnhancedIconButton(\n                        containerColor = MaterialTheme.colorScheme.mixedContainer,\n                        onClick = component::showAddFiltersSheet\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.AutoFixHigh,\n                            contentDescription = stringResource(R.string.add_filter)\n                        )\n                    }\n                }\n\n                is Screen.Filter.Type.Masking -> {\n                    EnhancedIconButton(\n                        containerColor = MaterialTheme.colorScheme.mixedContainer,\n                        onClick = component::showAddFiltersSheet\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Texture,\n                            contentDescription = stringResource(R.string.add_mask)\n                        )\n                    }\n                }\n\n                null -> Unit\n            }\n        } else {\n            actions()\n        }\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/MaskFilterPreference.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Texture\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun MaskFilterPreference(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    color: Color = Color.Unspecified\n) {\n    PreferenceItem(\n        onClick = onClick,\n        startIcon = Icons.Rounded.Texture,\n        title = stringResource(R.string.mask_filter),\n        subtitle = stringResource(R.string.mask_filter_sub),\n        containerColor = color,\n        modifier = modifier\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/MaskItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.DragHandle\nimport androidx.compose.material.icons.rounded.RemoveCircleOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.AddFilterButton\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheet\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.EditAlt\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet.AddEditMaskSheet\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet.AddMaskSheetComponent\n\n@Composable\nfun MaskItem(\n    addMaskSheetComponent: AddMaskSheetComponent?,\n    mask: UiFilterMask,\n    modifier: Modifier = Modifier,\n    titleText: String,\n    onMaskChange: (UiFilterMask) -> Unit,\n    previewOnly: Boolean = false,\n    backgroundColor: Color = Color.Unspecified,\n    showDragHandle: Boolean,\n    onLongPress: (() -> Unit)? = null,\n    onCreateTemplate: (() -> Unit)?,\n    onRemove: () -> Unit,\n    imageUri: Uri? = null,\n    previousMasks: List<UiFilterMask> = emptyList(),\n    shape: Shape = MaterialTheme.shapes.extraLarge\n) {\n    var showMaskRemoveDialog by rememberSaveable { mutableStateOf(false) }\n    var showAddFilterSheet by rememberSaveable { mutableStateOf(false) }\n    var showEditMaskSheet by rememberSaveable { mutableStateOf(false) }\n    val settingsState = LocalSettingsState.current\n    Box {\n        Row(\n            modifier = modifier\n                .container(\n                    color = backgroundColor,\n                    shape = shape\n                )\n                .animateContentSizeNoClip()\n                .then(\n                    onLongPress?.let {\n                        Modifier.pointerInput(Unit) {\n                            detectTapGestures(\n                                onLongPress = { it() }\n                            )\n                        }\n                    } ?: Modifier\n                ),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            if (showDragHandle) {\n                Spacer(Modifier.width(8.dp))\n                Icon(\n                    imageVector = Icons.Rounded.DragHandle,\n                    contentDescription = stringResource(R.string.drag_handle_width)\n                )\n                Spacer(Modifier.width(8.dp))\n                Box(\n                    Modifier\n                        .height(32.dp)\n                        .width(settingsState.borderWidth.coerceAtLeast(0.25.dp))\n                        .background(MaterialTheme.colorScheme.outlineVariant())\n                        .padding(start = 20.dp)\n                )\n            }\n            Column(\n                Modifier\n                    .weight(1f)\n                    .alpha(if (previewOnly) 0.5f else 1f)\n            ) {\n                Row(verticalAlignment = Alignment.CenterVertically) {\n                    Row(\n                        modifier = Modifier.weight(1f),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        PathPaintPreview(\n                            modifier = Modifier\n                                .padding(start = 12.dp)\n                                .sizeIn(maxHeight = 30.dp, maxWidth = 30.dp),\n                            pathPaints = mask.maskPaints\n                        )\n                        Text(\n                            text = titleText,\n                            fontWeight = FontWeight.SemiBold,\n                            modifier = Modifier\n                                .padding(\n                                    end = 8.dp,\n                                    start = 16.dp\n                                )\n                        )\n                        Spacer(Modifier.weight(1f))\n                        EnhancedIconButton(\n                            onClick = { showMaskRemoveDialog = true }\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.RemoveCircleOutline,\n                                contentDescription = stringResource(R.string.remove)\n                            )\n                        }\n                        EnhancedIconButton(\n                            onClick = { showEditMaskSheet = true }\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.EditAlt,\n                                contentDescription = stringResource(R.string.edit)\n                            )\n                        }\n                    }\n                    EnhancedAlertDialog(\n                        visible = showMaskRemoveDialog,\n                        onDismissRequest = { showMaskRemoveDialog = false },\n                        confirmButton = {\n                            EnhancedButton(\n                                onClick = { showMaskRemoveDialog = false }\n                            ) {\n                                Text(stringResource(R.string.cancel))\n                            }\n                        },\n                        dismissButton = {\n                            EnhancedButton(\n                                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                                onClick = {\n                                    showMaskRemoveDialog = false\n                                    onRemove()\n                                }\n                            ) {\n                                Text(stringResource(R.string.delete))\n                            }\n                        },\n                        title = {\n                            Text(stringResource(R.string.delete_mask))\n                        },\n                        icon = {\n                            Icon(\n                                imageVector = Icons.Outlined.Delete,\n                                contentDescription = stringResource(R.string.delete)\n                            )\n                        },\n                        text = {\n                            Column(\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                verticalArrangement = Arrangement.Center\n                            ) {\n                                PathPaintPreview(\n                                    pathPaints = mask.maskPaints,\n                                    modifier = Modifier.sizeIn(\n                                        maxHeight = 80.dp,\n                                        maxWidth = 80.dp\n                                    )\n                                )\n                                Spacer(modifier = Modifier.height(8.dp))\n                                Text(stringResource(R.string.delete_mask_warn))\n                            }\n                        }\n                    )\n                }\n\n                AnimatedVisibility(mask.filters.isNotEmpty()) {\n                    ExpandableItem(\n                        modifier = Modifier.padding(8.dp),\n                        visibleContent = {\n                            TitleItem(text = stringResource(id = R.string.filters) + \" (${mask.filters.size})\")\n                        },\n                        expandableContent = {\n                            Column(\n                                verticalArrangement = Arrangement.spacedBy(8.dp),\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                modifier = Modifier.padding(horizontal = 8.dp)\n                            ) {\n                                mask.filters.forEachIndexed { index, filter ->\n                                    val uiFilter by remember(filter) {\n                                        derivedStateOf {\n                                            filter.toUiFilter()\n                                        }\n                                    }\n                                    FilterItem(\n                                        backgroundColor = MaterialTheme.colorScheme.surface,\n                                        filter = uiFilter,\n                                        showDragHandle = false,\n                                        onRemove = {\n                                            onMaskChange(\n                                                mask.copy(filters = mask.filters - filter)\n                                            )\n                                        },\n                                        onFilterChange = { value ->\n                                            onMaskChange(\n                                                mask.copy(\n                                                    filters = mask.filters.toMutableList()\n                                                        .apply {\n                                                            this[index] = uiFilter.copy(value)\n                                                        }\n                                                )\n                                            )\n                                        },\n                                        onCreateTemplate = onCreateTemplate\n                                    )\n                                }\n                                AddFilterButton(\n                                    containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,\n                                    onClick = {\n                                        showAddFilterSheet = true\n                                    }\n                                )\n                            }\n                        }\n                    )\n                }\n            }\n        }\n        if (previewOnly) {\n            Surface(\n                color = Color.Transparent,\n                modifier = modifier.matchParentSize()\n            ) {}\n        }\n    }\n\n    addMaskSheetComponent?.let {\n        AddFiltersSheet(\n            visible = showAddFilterSheet,\n            onVisibleChange = { showAddFilterSheet = it },\n            previewBitmap = null,\n            onFilterPicked = { filter ->\n                onMaskChange(\n                    mask.copy(\n                        filters = mask.filters + filter.newInstance()\n                    )\n                )\n            },\n            onFilterPickedWithParams = { filter ->\n                onMaskChange(\n                    mask.copy(\n                        filters = mask.filters + filter\n                    )\n                )\n            },\n            component = addMaskSheetComponent.addFiltersSheetComponent,\n            filterTemplateCreationSheetComponent = addMaskSheetComponent.filterTemplateCreationSheetComponent\n        )\n\n        AddEditMaskSheet(\n            mask = mask,\n            visible = showEditMaskSheet,\n            targetBitmapUri = imageUri,\n            masks = previousMasks,\n            onDismiss = {\n                showEditMaskSheet = false\n            },\n            onMaskPicked = onMaskChange,\n            component = addMaskSheetComponent\n        )\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/MaskReorderSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Reorder\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\n\n@Composable\nfun MaskReorderSheet(\n    maskList: List<UiFilterMask>,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onReorder: (List<UiFilterMask>) -> Unit\n) {\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            if (maskList.size < 2) onDismiss()\n\n            Box {\n                val data = remember { mutableStateOf(maskList) }\n                val listState = rememberLazyListState()\n                val haptics = LocalHapticFeedback.current\n                val state = rememberReorderableLazyListState(\n                    lazyListState = listState,\n                    onMove = { from, to ->\n                        haptics.press()\n                        data.value = data.value.toMutableList().apply {\n                            add(to.index, removeAt(from.index))\n                        }\n                    }\n                )\n                LazyColumn(\n                    state = listState,\n                    contentPadding = PaddingValues(16.dp),\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    itemsIndexed(\n                        items = data.value,\n                        key = { _, it -> it.hashCode() }\n                    ) { index, mask ->\n                        ReorderableItem(\n                            state = state,\n                            key = mask.hashCode()\n                        ) { isDragging ->\n                            MaskItem(\n                                mask = mask,\n                                modifier = Modifier\n                                    .fillMaxWidth()\n                                    .longPressDraggableHandle(\n                                        onDragStarted = {\n                                            haptics.longPress()\n                                        },\n                                        onDragStopped = {\n                                            onReorder(data.value)\n                                        }\n                                    )\n                                    .scale(\n                                        animateFloatAsState(\n                                            if (isDragging) 1.05f\n                                            else 1f\n                                        ).value\n                                    ),\n                                onMaskChange = {},\n                                previewOnly = true,\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = data.value.size\n                                ),\n                                titleText = stringResource(R.string.mask_indexed, index + 1),\n                                showDragHandle = maskList.size >= 2,\n                                onRemove = {},\n                                addMaskSheetComponent = null,\n                                onCreateTemplate = null\n                            )\n                        }\n                    }\n                }\n            }\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.reorder),\n                icon = Icons.Rounded.Reorder\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/MaskingFilterState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport android.net.Uri\n\ndata class MaskingFilterState(\n    val uri: Uri? = null,\n    val masks: List<UiFilterMask> = emptyList()\n)"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/PathPaintPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport android.graphics.BlurMaskFilter\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.PaintingStyle\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.drawscope.drawIntoCanvas\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.drawText\nimport androidx.compose.ui.text.rememberTextMeasurer\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.scaleToFitCanvas\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.feature.draw.domain.PathPaint\n\n@Composable\nfun PathPaintPreview(\n    modifier: Modifier = Modifier,\n    pathPaints: List<PathPaint<Path, Color>>\n) {\n    val visuals = Modifier\n        .border(\n            width = 1.dp,\n            color = MaterialTheme.colorScheme.outlineVariant(),\n            shape = ShapeDefaults.extraSmall\n        )\n        .clip(ShapeDefaults.extraSmall)\n        .transparencyChecker(\n            checkerHeight = 2.dp,\n            checkerWidth = 2.dp\n        )\n    val first = pathPaints.firstOrNull()\n    if (first != null) {\n        Box(\n            modifier = modifier\n                .aspectRatio(first.canvasSize.aspectRatio)\n                .then(visuals)\n                .alpha(0.99f)\n                .drawBehind {\n                    val currentSize = IntegerSize(\n                        size.width.toInt(),\n                        size.height.toInt()\n                    )\n                    drawIntoCanvas { composeCanvas ->\n                        val canvas = composeCanvas.nativeCanvas\n                        pathPaints.forEach { pathPaint ->\n                            val stroke = pathPaint\n                                .strokeWidth\n                                .toPx(currentSize)\n\n                            val drawPathMode = pathPaint.drawPathMode\n\n                            val isSharpEdge = drawPathMode.isSharpEdge\n                            val isFilled = drawPathMode.isFilled\n\n                            canvas.drawPath(\n                                pathPaint.path\n                                    .scaleToFitCanvas(\n                                        currentSize = currentSize,\n                                        oldSize = pathPaint.canvasSize\n                                    )\n                                    .asAndroidPath(),\n                                Paint()\n                                    .apply {\n                                        if (pathPaint.isErasing) {\n                                            blendMode = BlendMode.Clear\n                                            style = PaintingStyle.Stroke\n                                            strokeWidth = stroke\n                                            strokeCap = StrokeCap.Round\n                                            strokeJoin = StrokeJoin.Round\n                                        } else {\n                                            color = pathPaint.drawColor\n                                            if (isFilled) {\n                                                style = PaintingStyle.Fill\n                                            } else {\n                                                style = PaintingStyle.Stroke\n                                                strokeWidth = stroke\n                                                if (isSharpEdge) {\n                                                    style = PaintingStyle.Stroke\n                                                } else {\n                                                    strokeCap = StrokeCap.Round\n                                                    strokeJoin = StrokeJoin.Round\n                                                }\n                                            }\n                                        }\n                                    }\n                                    .nativePaint\n                                    .apply {\n                                        if (pathPaint.brushSoftness.value > 0f) {\n                                            maskFilter = BlurMaskFilter(\n                                                pathPaint.brushSoftness.toPx(currentSize),\n                                                BlurMaskFilter.Blur.NORMAL\n                                            )\n                                        }\n                                    }\n                            )\n                        }\n                    }\n                }\n        )\n    } else {\n        val color = MaterialTheme.colorScheme.onSecondaryContainer.copy(0.6f)\n        val textMeasurer = rememberTextMeasurer()\n        Box(\n            modifier = modifier\n                .aspectRatio(1f)\n                .then(visuals)\n                .drawBehind {\n                    drawText(\n                        textMeasurer = textMeasurer,\n                        text = \"N\",\n                        topLeft = Offset(\n                            size.width / 2,\n                            size.height / 2\n                        ),\n                        style = TextStyle(color = color)\n                    )\n                }\n        )\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/UiFilterMask.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.feature.draw.domain.PathPaint\nimport com.t8rin.imagetoolbox.feature.filters.domain.FilterMask\n\ndata class UiFilterMask(\n    override val filters: List<Filter<*>>,\n    override val maskPaints: List<PathPaint<Path, Color>>,\n    override val isInverseFillType: Boolean\n) : FilterMask<Path, Color>"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/addEditMaskSheet/AddEditMaskSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet\n\nimport android.net.Uri\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.Texture\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageHeaderState\nimport com.t8rin.imagetoolbox.core.ui.widget.image.imageStickyHeader\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.PtSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.rememberAvailableHeight\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.UiFilterMask\n\n@Composable\nfun AddEditMaskSheet(\n    component: AddMaskSheetComponent,\n    mask: UiFilterMask? = null,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    targetBitmapUri: Uri? = null,\n    masks: List<UiFilterMask> = emptyList(),\n    onMaskPicked: (UiFilterMask) -> Unit,\n) {\n    var invalidations by remember {\n        mutableIntStateOf(0)\n    }\n    LaunchedEffect(mask, masks, targetBitmapUri, invalidations) {\n        component.setMask(\n            mask = mask,\n            bitmapUri = targetBitmapUri,\n            masks = masks\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showExitDialog by remember { mutableStateOf(false) }\n\n    val settingsState = LocalSettingsState.current\n    var isEraserOn by rememberSaveable { mutableStateOf(false) }\n    var strokeWidth by rememberSaveable(stateSaver = PtSaver) { mutableStateOf(settingsState.defaultDrawLineWidth.pt) }\n    var brushSoftness by rememberSaveable(stateSaver = PtSaver) { mutableStateOf(20.pt) }\n    var panEnabled by rememberSaveable { mutableStateOf(false) }\n\n    val canSave = component.paths.isNotEmpty() && component.filterList.isNotEmpty()\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (component.paths.isEmpty() && component.filterList.isEmpty()) onDismiss()\n            else showExitDialog = true\n        },\n        cancelable = false,\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.add_mask),\n                icon = Icons.Rounded.Texture\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                enabled = canSave,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    onMaskPicked(component.getUiMask())\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(id = R.string.save))\n            }\n        },\n        dragHandle = {\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .drawHorizontalStroke(autoElevation = 3.dp)\n                    .zIndex(Float.MAX_VALUE)\n                    .background(EnhancedBottomSheetDefaults.barContainerColor)\n                    .padding(8.dp)\n            ) {\n                EnhancedIconButton(\n                    onClick = {\n                        if (component.paths.isEmpty() && component.filterList.isEmpty()) onDismiss()\n                        else showExitDialog = true\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                        contentDescription = stringResource(R.string.exit)\n                    )\n                }\n            }\n        },\n        enableBackHandler = component.paths.isEmpty() && component.filterList.isEmpty()\n    ) {\n        component.AttachLifecycle()\n\n        LaunchedEffect(Unit) {\n            invalidations++\n        }\n        var imageState by remember { mutableStateOf(ImageHeaderState(2)) }\n\n        if (visible) {\n            BackHandler(\n                enabled = !(component.paths.isEmpty() && component.filterList.isEmpty())\n            ) {\n                showExitDialog = true\n            }\n        }\n        val drawPreview: @Composable () -> Unit = {\n            AddMaskSheetBitmapPreview(\n                component = component,\n                imageState = imageState,\n                strokeWidth = strokeWidth,\n                brushSoftness = brushSoftness,\n                isEraserOn = isEraserOn,\n                panEnabled = panEnabled\n            )\n        }\n        Row {\n            val backgroundColor = MaterialTheme.colorScheme.surfaceContainerLow\n            if (!isPortrait) {\n                Box(modifier = Modifier.weight(1.3f)) {\n                    drawPreview()\n                }\n            }\n            val internalHeight = rememberAvailableHeight(imageState = imageState)\n            LazyColumn(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                modifier = Modifier.weight(1f),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                imageStickyHeader(\n                    visible = isPortrait,\n                    internalHeight = internalHeight,\n                    imageState = imageState,\n                    onStateChange = {\n                        imageState = it\n                    },\n                    isControlsVisibleIndefinitely = true,\n                    padding = 0.dp,\n                    backgroundColor = backgroundColor,\n                    imageBlock = drawPreview\n                )\n                item {\n                    AddEditMaskSheetControls(\n                        component = component,\n                        imageState = imageState,\n                        strokeWidth = strokeWidth,\n                        onStrokeWidthChange = { strokeWidth = it },\n                        brushSoftness = brushSoftness,\n                        onBrushSoftnessChange = { brushSoftness = it },\n                        panEnabled = panEnabled,\n                        onTogglePanEnabled = { panEnabled = !panEnabled },\n                        isEraserOn = isEraserOn,\n                        onToggleIsEraserOn = { isEraserOn = !isEraserOn }\n                    )\n                }\n            }\n        }\n    }\n\n    ExitWithoutSavingDialog(\n        onExit = onDismiss,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog,\n        placeAboveAll = true\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/addEditMaskSheet/AddEditMaskSheetControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.Redo\nimport androidx.compose.material.icons.automirrored.rounded.Undo\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.AddFilterButton\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterReorderSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheet\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Preview\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.EraseModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.HistogramChart\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageHeaderState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BrushSoftnessSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawColorSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawPathModeSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.LineWidthSelector\n\n\n@Composable\ninternal fun AddEditMaskSheetControls(\n    component: AddMaskSheetComponent,\n    imageState: ImageHeaderState,\n    strokeWidth: Pt,\n    onStrokeWidthChange: (Pt) -> Unit,\n    brushSoftness: Pt,\n    onBrushSoftnessChange: (Pt) -> Unit,\n    panEnabled: Boolean,\n    onTogglePanEnabled: () -> Unit,\n    isEraserOn: Boolean,\n    onToggleIsEraserOn: () -> Unit\n) {\n    var showAddFilterSheet by rememberSaveable { mutableStateOf(false) }\n\n    var showReorderSheet by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n    val canSave = component.paths.isNotEmpty() && component.filterList.isNotEmpty()\n\n    Row(\n        Modifier\n            .then(\n                if (imageState.isBlocked && isPortrait) {\n                    Modifier.padding(\n                        start = 16.dp,\n                        end = 16.dp,\n                        bottom = 16.dp\n                    )\n                } else Modifier.padding(16.dp)\n            )\n            .container(shape = ShapeDefaults.circle)\n    ) {\n        PanModeButton(\n            selected = panEnabled,\n            onClick = onTogglePanEnabled\n        )\n        Spacer(Modifier.width(4.dp))\n        EnhancedIconButton(\n            containerColor = Color.Transparent,\n            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                luminance = 0.1f\n            ),\n            onClick = component::undo,\n            enabled = (component.lastPaths.isNotEmpty() || component.paths.isNotEmpty())\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.Undo,\n                contentDescription = \"Undo\"\n            )\n        }\n        EnhancedIconButton(\n            containerColor = Color.Transparent,\n            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                luminance = 0.1f\n            ),\n            onClick = component::redo,\n            enabled = component.undonePaths.isNotEmpty()\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.Redo,\n                contentDescription = \"Redo\"\n            )\n        }\n        EraseModeButton(\n            selected = isEraserOn,\n            enabled = !panEnabled,\n            onClick = onToggleIsEraserOn\n        )\n    }\n\n    AnimatedVisibility(visible = canSave) {\n        Column {\n            BoxAnimatedVisibility(component.maskPreviewModeEnabled) {\n                PreferenceItemOverload(\n                    title = stringResource(R.string.histogram),\n                    subtitle = stringResource(R.string.histogram_sub),\n                    endIcon = {\n                        AnimatedContent(component.previewBitmap != null) {\n                            if (it) {\n                                HistogramChart(\n                                    model = component.previewBitmap,\n                                    modifier = Modifier\n                                        .width(100.dp)\n                                        .height(65.dp)\n                                        .background(MaterialTheme.colorScheme.background)\n                                )\n                            } else {\n                                Box(modifier = Modifier.size(56.dp)) {\n                                    EnhancedLoadingIndicator()\n                                }\n                            }\n                        }\n                    },\n                    shape = ShapeDefaults.extraLarge,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 16.dp)\n                        .padding(bottom = 8.dp)\n                )\n            }\n            PreferenceRowSwitch(\n                title = stringResource(id = R.string.mask_preview),\n                subtitle = stringResource(id = R.string.mask_preview_sub),\n                containerColor = animateColorAsState(\n                    if (component.maskPreviewModeEnabled) MaterialTheme.colorScheme.onPrimary\n                    else Color.Unspecified,\n                ).value,\n                modifier = Modifier.padding(horizontal = 16.dp),\n                shape = ShapeDefaults.extraLarge,\n                contentColor = animateColorAsState(\n                    if (component.maskPreviewModeEnabled) MaterialTheme.colorScheme.primary\n                    else MaterialTheme.colorScheme.onSurface\n                ).value,\n                onClick = component::togglePreviewMode,\n                checked = component.maskPreviewModeEnabled,\n                startIcon = Icons.Outlined.Preview\n            )\n        }\n    }\n\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        DrawColorSelector(\n            color = Color.Unspecified,\n            titleText = stringResource(id = R.string.mask_color),\n            defaultColors = remember {\n                listOf(\n                    Color.Red,\n                    Color.Green,\n                    Color.Blue,\n                    Color.Yellow,\n                    Color.Cyan,\n                    Color.Magenta\n                )\n            },\n            value = component.maskColor,\n            onValueChange = component::updateMaskColor,\n            modifier = Modifier.padding(\n                start = 16.dp,\n                end = 16.dp,\n                top = 8.dp\n            )\n        )\n        DrawPathModeSelector(\n            modifier = Modifier.padding(\n                start = 16.dp,\n                end = 16.dp,\n                top = 8.dp\n            ),\n            values = remember {\n                listOf(\n                    DrawPathMode.Free,\n                    DrawPathMode.FloodFill(),\n                    DrawPathMode.Spray(),\n                    DrawPathMode.Lasso,\n                    DrawPathMode.Rect(),\n                    DrawPathMode.Oval,\n                    DrawPathMode.Triangle,\n                    DrawPathMode.Polygon(),\n                    DrawPathMode.Star()\n                )\n            },\n            value = component.drawPathMode,\n            onValueChange = component::setDrawPathMode,\n            drawMode = DrawMode.Pen\n        )\n        LineWidthSelector(\n            modifier = Modifier.padding(\n                start = 16.dp,\n                end = 16.dp,\n                top = 8.dp\n            ),\n            color = Color.Unspecified,\n            value = strokeWidth.value,\n            onValueChange = { onStrokeWidthChange(it.pt) }\n        )\n        BrushSoftnessSelector(\n            modifier = Modifier\n                .padding(top = 8.dp, end = 16.dp, start = 16.dp),\n            color = Color.Unspecified,\n            value = brushSoftness.value,\n            onValueChange = { onBrushSoftnessChange(it.pt) }\n        )\n    }\n\n    PreferenceRowSwitch(\n        title = stringResource(id = R.string.inverse_fill_type),\n        subtitle = stringResource(id = R.string.inverse_fill_type_sub),\n        checked = component.isInverseFillType,\n        modifier = Modifier.padding(\n            start = 16.dp,\n            end = 16.dp,\n            top = 8.dp\n        ),\n        containerColor = Color.Unspecified,\n        resultModifier = Modifier.padding(16.dp),\n        applyHorizontalPadding = false,\n        shape = ShapeDefaults.extraLarge,\n        onClick = {\n            component.toggleIsInverseFillType()\n        }\n    )\n    AnimatedContent(\n        targetState = component.filterList.isNotEmpty(),\n        transitionSpec = {\n            fadeIn() + expandVertically() togetherWith fadeOut() + shrinkVertically()\n        }\n    ) { notEmpty ->\n        if (notEmpty) {\n            var showTemplateCreationSheet by rememberSaveable {\n                mutableStateOf(false)\n            }\n\n            Column(\n                modifier = Modifier\n                    .padding(horizontal = 16.dp, vertical = 8.dp)\n                    .container(MaterialTheme.shapes.extraLarge)\n            ) {\n                TitleItem(text = stringResource(R.string.filters))\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.spacedBy(8.dp),\n                    modifier = Modifier.padding(8.dp)\n                ) {\n                    component.filterList.forEachIndexed { index, filter ->\n                        FilterItem(\n                            backgroundColor = MaterialTheme.colorScheme.surface,\n                            filter = filter,\n                            onFilterChange = { value ->\n                                component.updateFilter(\n                                    value = value,\n                                    index = index\n                                )\n                            },\n                            onLongPress = {\n                                showReorderSheet = true\n                            },\n                            showDragHandle = false,\n                            onRemove = {\n                                component.removeFilterAtIndex(index)\n                            },\n                            onCreateTemplate = {\n                                showTemplateCreationSheet = true\n                                component.filterTemplateCreationSheetComponent.setInitialTemplateFilter(\n                                    TemplateFilter(\n                                        name = getString(filter.title),\n                                        filters = listOf(filter)\n                                    )\n                                )\n                            }\n                        )\n                    }\n                    AddFilterButton(\n                        modifier = Modifier.padding(horizontal = 16.dp),\n                        onClick = {\n                            showAddFilterSheet = true\n                        },\n                        onCreateTemplate = {\n                            showTemplateCreationSheet = true\n                            component.filterTemplateCreationSheetComponent.setInitialTemplateFilter(\n                                TemplateFilter(\n                                    name = getString(\n                                        component.filterList.firstOrNull()?.title\n                                            ?: R.string.template_filter\n                                    ),\n                                    filters = component.filterList\n                                )\n                            )\n                        }\n                    )\n                }\n            }\n\n            FilterTemplateCreationSheet(\n                component = component.filterTemplateCreationSheetComponent,\n                visible = showTemplateCreationSheet,\n                onDismiss = { showTemplateCreationSheet = false }\n            )\n        } else {\n            AddFilterButton(\n                onClick = {\n                    showAddFilterSheet = true\n                },\n                modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)\n            )\n        }\n    }\n\n    AddFiltersSheet(\n        visible = showAddFilterSheet,\n        onVisibleChange = { showAddFilterSheet = it },\n        previewBitmap = component.previewBitmap,\n        onFilterPicked = { component.addFilter(it.newInstance()) },\n        onFilterPickedWithParams = { component.addFilter(it) },\n        component = component.addFiltersSheetComponent,\n        filterTemplateCreationSheetComponent = component.filterTemplateCreationSheetComponent\n    )\n    FilterReorderSheet(\n        filterList = component.filterList,\n        visible = showReorderSheet,\n        onDismiss = {\n            showReorderSheet = false\n        },\n        onReorder = component::updateFiltersOrder\n    )\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/addEditMaskSheet/AddMaskSheetBitmapPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.Pt\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageHeaderState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.CornerSides\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.only\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BitmapDrawer\nimport net.engawapg.lib.zoomable.rememberZoomState\n\n@Composable\ninternal fun AddMaskSheetBitmapPreview(\n    component: AddMaskSheetComponent,\n    imageState: ImageHeaderState,\n    strokeWidth: Pt,\n    brushSoftness: Pt,\n    isEraserOn: Boolean,\n    panEnabled: Boolean\n) {\n    val zoomState = rememberZoomState(maxScale = 30f, key = imageState)\n    val isPortrait by isPortraitOrientationAsState()\n\n    AnimatedContent(\n        targetState = Triple(\n            first = remember(component.previewBitmap) {\n                derivedStateOf {\n                    component.previewBitmap?.asImageBitmap()\n                }\n            }.value,\n            second = component.maskPreviewModeEnabled,\n            third = component.isImageLoading\n        ),\n        transitionSpec = { fadeIn() togetherWith fadeOut() },\n        modifier = Modifier\n            .fillMaxSize()\n            .clip(\n                if (isPortrait) {\n                    ShapeDefaults.extraLarge.only(\n                        CornerSides.Bottom\n                    )\n                } else RectangleShape\n            )\n            .background(\n                color = MaterialTheme.colorScheme\n                    .surfaceContainer\n                    .copy(0.8f)\n            )\n    ) { (imageBitmap, preview, loading) ->\n        if (loading || imageBitmap == null) {\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(16.dp),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedLoadingIndicator()\n            }\n        } else {\n            val aspectRatio = imageBitmap.width / imageBitmap.height.toFloat()\n            var drawing by remember { mutableStateOf(false) }\n            BitmapDrawer(\n                zoomState = zoomState,\n                imageBitmap = imageBitmap,\n                paths = if (!preview || drawing || component.isImageLoading) component.paths else emptyList(),\n                strokeWidth = strokeWidth,\n                brushSoftness = brushSoftness,\n                drawColor = component.maskColor,\n                onAddPath = component::addPath,\n                isEraserOn = isEraserOn,\n                drawMode = DrawMode.Pen,\n                modifier = Modifier\n                    .padding(16.dp)\n                    .aspectRatio(aspectRatio, isPortrait)\n                    .fillMaxSize(),\n                panEnabled = panEnabled,\n                onDrawStart = {\n                    drawing = true\n                },\n                onDrawFinish = {\n                    drawing = false\n                },\n                onRequestFiltering = component::filter,\n                drawPathMode = component.drawPathMode,\n                backgroundColor = Color.Transparent\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/components/addEditMaskSheet/AddMaskSheetComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.childContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.toUiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.toUiPathPaint\nimport com.t8rin.imagetoolbox.feature.filters.domain.FilterMaskApplier\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.UiFilterMask\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass AddMaskSheetComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val filterMaskApplier: FilterMaskApplier<Bitmap, Path, Color>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n    addFiltersSheetComponentFactory: AddFiltersSheetComponent.Factory,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent.Factory\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    val addFiltersSheetComponent: AddFiltersSheetComponent = addFiltersSheetComponentFactory(\n        componentContext = componentContext.childContext(\n            key = \"addFiltersMask\"\n        )\n    )\n\n    val filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent =\n        filterTemplateCreationSheetComponent(\n            componentContext = componentContext.childContext(\n                key = \"filterTemplateCreationSheetComponentMask\"\n            )\n        )\n\n    private val _maskColor = mutableStateOf(Color.Red)\n    val maskColor by _maskColor\n\n    private val _paths: MutableState<List<UiPathPaint>> = mutableStateOf(emptyList())\n    val paths by _paths\n\n    private val _lastPaths = mutableStateOf(listOf<UiPathPaint>())\n    val lastPaths: List<UiPathPaint> by _lastPaths\n\n    private val _undonePaths = mutableStateOf(listOf<UiPathPaint>())\n    val undonePaths: List<UiPathPaint> by _undonePaths\n\n    private val _filterList: MutableState<List<UiFilter<*>>> = mutableStateOf(emptyList())\n    val filterList by _filterList\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap by _previewBitmap\n\n    private val _maskPreviewModeEnabled: MutableState<Boolean> = mutableStateOf(false)\n    val maskPreviewModeEnabled by _maskPreviewModeEnabled\n\n    private val _isInverseFillType: MutableState<Boolean> = mutableStateOf(false)\n    val isInverseFillType by _isInverseFillType\n\n    private val _drawPathMode: MutableState<DrawPathMode> = mutableStateOf(DrawPathMode.Line)\n    val drawPathMode by _drawPathMode\n\n    private var bitmapUri: Uri? = null\n\n    private var initialMasks: List<UiFilterMask> = emptyList()\n\n    private var initialMask: UiFilterMask? = null\n\n    private fun updatePreview() {\n        debouncedImageCalculation {\n            if (filterList.isEmpty() || paths.isEmpty()) {\n                _maskPreviewModeEnabled.update { false }\n            }\n            if (maskPreviewModeEnabled) {\n                imageGetter.getImage(\n                    data = bitmapUri.toString(),\n                    originalSize = false\n                )?.let { bmp ->\n                    _previewBitmap.value = filterMaskApplier.filterByMasks(\n                        filterMasks = initialMasks.takeWhile {\n                            it != initialMask\n                        }.let {\n                            it + getUiMask()\n                        },\n                        image = bmp\n                    )?.let {\n                        imagePreviewCreator.createPreview(\n                            image = it,\n                            imageInfo = ImageInfo(\n                                width = it.width,\n                                height = it.height,\n                                imageFormat = ImageFormat.Png.Lossless\n                            ),\n                            onGetByteCount = {}\n                        )\n                    }\n                }\n            } else {\n                _previewBitmap.value = imageGetter.getImage(\n                    data = bitmapUri.toString(),\n                    originalSize = false\n                )?.let { bmp ->\n                    filterMaskApplier.filterByMasks(\n                        filterMasks = initialMasks.takeWhile { it != initialMask },\n                        image = bmp\n                    )\n                }\n            }\n        }\n    }\n\n    fun togglePreviewMode(value: Boolean) {\n        _maskPreviewModeEnabled.update { value }\n        updatePreview()\n    }\n\n    fun removeFilterAtIndex(index: Int) {\n        _filterList.update {\n            it.toMutableList().apply {\n                removeAt(index)\n            }\n        }\n        updatePreview()\n    }\n\n    fun <T : Any> updateFilter(\n        value: T,\n        index: Int\n    ) {\n        val list = _filterList.value.toMutableList()\n        runCatching {\n            list[index] = list[index].copy(value)\n            _filterList.update { list }\n        }.exceptionOrNull()?.let { throwable ->\n            AppToastHost.showFailureToast(throwable)\n            list[index] = list[index].newInstance()\n            _filterList.update { list }\n        }\n        updatePreview()\n    }\n\n    fun updateFiltersOrder(uiFilters: List<UiFilter<*>>) {\n        _filterList.update { uiFilters }\n    }\n\n    fun addFilter(filter: UiFilter<*>) {\n        _filterList.update {\n            it + filter\n        }\n        updatePreview()\n    }\n\n    fun getUiMask(): UiFilterMask = UiFilterMask(\n        filters = filterList,\n        maskPaints = paths,\n        isInverseFillType = isInverseFillType\n    )\n\n    fun addPath(pathPaint: UiPathPaint) {\n        _paths.update { it + pathPaint }\n        _undonePaths.value = listOf()\n        if (maskPreviewModeEnabled) updatePreview()\n    }\n\n    fun undo() {\n        if (paths.isEmpty() && lastPaths.isNotEmpty()) {\n            _paths.value = lastPaths\n            _lastPaths.value = listOf()\n            if (maskPreviewModeEnabled) updatePreview()\n            return\n        }\n        if (paths.isEmpty()) return\n\n        val lastPath = paths.last()\n\n        _paths.update { it - lastPath }\n        _undonePaths.update { it + lastPath }\n        if (maskPreviewModeEnabled || paths.isEmpty()) updatePreview()\n    }\n\n    fun redo() {\n        if (undonePaths.isEmpty()) return\n\n        val lastPath = undonePaths.last()\n        _paths.update { it + lastPath }\n        _undonePaths.update { it - lastPath }\n        if (maskPreviewModeEnabled) updatePreview()\n    }\n\n    fun updateMaskColor(color: Color) {\n        _maskColor.update { color }\n        _paths.update { paintList ->\n            paintList.map {\n                it.copy(drawColor = color)\n            }\n        }\n    }\n\n    fun setMask(\n        mask: UiFilterMask?,\n        bitmapUri: Uri?,\n        masks: List<UiFilterMask>,\n    ) {\n        mask?.let {\n            _paths.update { mask.maskPaints.map { it.toUiPathPaint() } }\n            _filterList.update { mask.filters.map { it.toUiFilter() } }\n            _maskColor.update { initial ->\n                val color = mask.maskPaints.map { it.drawColor }.toSet().firstOrNull()\n                color ?: initial\n            }\n            _isInverseFillType.update { mask.isInverseFillType }\n        }\n        this.initialMask = mask\n        this.bitmapUri = bitmapUri\n        this.initialMasks = masks\n        updatePreview()\n    }\n\n    fun toggleIsInverseFillType() {\n        _isInverseFillType.update { !it }\n        updatePreview()\n    }\n\n    suspend fun filter(\n        bitmap: Bitmap,\n        filters: List<Filter<*>>,\n        size: IntegerSize? = null,\n    ): Bitmap? = size?.let { intSize ->\n        imageTransformer.transform(\n            image = bitmap,\n            transformations = filters.map { filterProvider.filterToTransformation(it) },\n            size = intSize\n        )\n    } ?: imageTransformer.transform(\n        image = bitmap,\n        transformations = filters.map { filterProvider.filterToTransformation(it) }\n    )\n\n    fun setDrawPathMode(mode: DrawPathMode) {\n        _drawPathMode.update { mode }\n    }\n\n    override fun resetState() {\n        _maskColor.update { Color.Red }\n        _paths.update { emptyList() }\n        _undonePaths.update { emptyList() }\n        _lastPaths.update { emptyList() }\n        _filterList.update { emptyList() }\n        cancelImageLoading()\n        _previewBitmap.update { null }\n        filterTemplateCreationSheetComponent.resetState()\n        addFiltersSheetComponent.resetState()\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext\n        ): AddMaskSheetComponent\n    }\n\n}"
  },
  {
    "path": "feature/filters/src/main/java/com/t8rin/imagetoolbox/feature/filters/presentation/screenLogic/FiltersComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.core.net.toUri\nimport coil3.transform.Transformation\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.childContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.ui.transformation.ImageInfoTransformation\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.filters.domain.FilterMaskApplier\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.BasicFilterState\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.MaskingFilterState\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.UiFilterMask\nimport com.t8rin.imagetoolbox.feature.filters.presentation.components.addEditMaskSheet.AddMaskSheetComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\n\nclass FiltersComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialType: Screen.Filter.Type?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val filterMaskApplier: FilterMaskApplier<Bitmap, Path, Color>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    private val imageInfoTransformationFactory: ImageInfoTransformation.Factory,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n    addFiltersSheetComponentFactory: AddFiltersSheetComponent.Factory,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent.Factory,\n    addMaskSheetComponentFactory: AddMaskSheetComponent.Factory,\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialType?.let(::setType)\n        }\n    }\n\n    val addFiltersSheetComponent: AddFiltersSheetComponent = addFiltersSheetComponentFactory(\n        componentContext = componentContext.childContext(\n            key = \"addFiltersFilters\"\n        )\n    )\n\n    val filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent =\n        filterTemplateCreationSheetComponent(\n            componentContext = componentContext.childContext(\n                key = \"filterTemplateCreationSheetComponentFilters\"\n            )\n        )\n\n    val addMaskSheetComponent: AddMaskSheetComponent = addMaskSheetComponentFactory(\n        componentContext = componentContext.childContext(\n            key = \"addMaskSheetComponentFactoryFilters\"\n        )\n    )\n\n    fun getFiltersTransformation(): List<Transformation> = listOf(\n        imageInfoTransformationFactory(\n            imageInfo = imageInfo,\n            transformations = basicFilterState.filters.map(\n                filterProvider::filterToTransformation\n            )\n        )\n    )\n\n    private val _isPickImageFromUrisSheetVisible = mutableStateOf(false)\n    val isPickImageFromUrisSheetVisible by _isPickImageFromUrisSheetVisible\n\n    fun showPickImageFromUrisSheet() {\n        _isPickImageFromUrisSheetVisible.update { true }\n    }\n\n    fun hidePickImageFromUrisSheet() {\n        _isPickImageFromUrisSheetVisible.update { false }\n    }\n\n    private val _isAddFiltersSheetVisible = mutableStateOf(false)\n    val isAddFiltersSheetVisible by _isAddFiltersSheetVisible\n\n    fun showAddFiltersSheet() {\n        _isAddFiltersSheetVisible.update { true }\n    }\n\n    fun hideAddFiltersSheet() {\n        _isAddFiltersSheetVisible.update { false }\n    }\n\n    private val _isReorderSheetVisible = mutableStateOf(false)\n    val isReorderSheetVisible by _isReorderSheetVisible\n\n    fun showReorderSheet() {\n        _isReorderSheetVisible.update { true }\n    }\n\n    fun hideReorderSheet() {\n        _isReorderSheetVisible.update { false }\n    }\n\n    private val _isSelectionFilterPickerVisible = mutableStateOf(false)\n    val isSelectionFilterPickerVisible by _isSelectionFilterPickerVisible\n\n    fun showSelectionFilterPicker() {\n        _isSelectionFilterPickerVisible.update { true }\n    }\n\n    fun hideSelectionFilterPicker() {\n        _isSelectionFilterPickerVisible.update { false }\n    }\n\n    private val _canSave = mutableStateOf(false)\n    val canSave by _canSave\n\n    private val _basicFilterState: MutableState<BasicFilterState> =\n        mutableStateOf(BasicFilterState())\n    val basicFilterState by _basicFilterState\n\n    private val _maskingFilterState: MutableState<MaskingFilterState> =\n        mutableStateOf(MaskingFilterState())\n    val maskingFilterState by _maskingFilterState\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _keepExif = mutableStateOf(false)\n    val keepExif by _keepExif\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(1)\n    val left by _left\n\n    private val _imageInfo = mutableStateOf(ImageInfo())\n    val imageInfo by _imageInfo\n\n    private val _filterType: MutableState<Screen.Filter.Type?> = mutableStateOf(null)\n    val filterType: Screen.Filter.Type? by _filterType\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageInfo.value = _imageInfo.value.copy(imageFormat = imageFormat)\n        updatePreview()\n        registerChanges()\n    }\n\n    fun setBasicFilter(uris: List<Uri>?) {\n        _filterType.update {\n            it as? Screen.Filter.Type.Basic ?: Screen.Filter.Type.Basic(uris)\n        }\n        _basicFilterState.update {\n            it.copy(\n                uris = uris,\n                selectedUri = uris?.firstOrNull()?.also(::updateSelectedUri)\n            )\n        }\n    }\n\n    fun updateUrisSilently(removedUri: Uri) {\n        componentScope.launch {\n            val state = _basicFilterState.value\n            if (state.selectedUri == removedUri) {\n                val index = state.uris?.indexOf(removedUri) ?: -1\n                if (index == 0) {\n                    state.uris?.getOrNull(1)?.let {\n                        _basicFilterState.update { f ->\n                            f.copy(selectedUri = it)\n                        }\n                        updateSelectedUri(it)\n                    }\n                } else {\n                    state.uris?.getOrNull(index - 1)?.let {\n                        _basicFilterState.update { f ->\n                            f.copy(selectedUri = it)\n                        }\n                        updateSelectedUri(it)\n                    }\n                }\n            }\n            _basicFilterState.update {\n                it.copy(\n                    uris = it.uris?.toMutableList()?.apply {\n                        remove(removedUri)\n                    }\n                )\n            }\n        }\n    }\n\n    fun setKeepExif(boolean: Boolean) {\n        _keepExif.value = boolean\n        registerChanges()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            _left.value = _basicFilterState.value.uris?.size ?: 1\n            _basicFilterState.value.uris?.forEach { uri ->\n                runSuspendCatching {\n                    imageGetter.getImageWithTransformations(\n                        uri = uri.toString(),\n                        transformations = _basicFilterState.value.filters.map {\n                            filterProvider.filterToTransformation(it)\n                        }\n                    )?.image\n                }.getOrNull()?.let { bitmap ->\n                    val localBitmap = bitmap\n\n                    results.add(\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                originalUri = uri.toString(),\n                                sequenceNumber = _done.value + 1,\n                                data = imageCompressor.compressAndTransform(\n                                    image = localBitmap,\n                                    imageInfo = imageInfo.copy(\n                                        width = localBitmap.width,\n                                        height = localBitmap.height\n                                    )\n                                )\n                            ),\n                            keepOriginalMetadata = keepExif,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    )\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun updateSelectedUri(\n        uri: Uri,\n        onFailure: (Throwable) -> Unit = {}\n    ) {\n        runCatching {\n            componentScope.launch {\n                _isImageLoading.update { true }\n                val req = imageGetter.getImage(uri = uri.toString())\n                val tempBitmap = req?.image\n                val size = tempBitmap?.let { it.width to it.height }\n                _bitmap.update {\n                    imageScaler.scaleUntilCanShow(tempBitmap)\n                }\n                _imageInfo.update {\n                    it.copy(\n                        width = size?.first ?: 0,\n                        height = size?.second ?: 0,\n                        imageFormat = req?.imageInfo?.imageFormat ?: ImageFormat.Default\n                    )\n                }\n                updatePreview()\n                _basicFilterState.update {\n                    it.copy(selectedUri = uri)\n                }\n                _isImageLoading.update { false }\n            }\n        }.onFailure(onFailure)\n    }\n\n    private fun updateCanSave() {\n        _canSave.value =\n            _bitmap.value != null && ((_filterType.value is Screen.Filter.Type.Basic && _basicFilterState.value.filters.isNotEmpty()) || (_filterType.value is Screen.Filter.Type.Masking && _maskingFilterState.value.masks.isNotEmpty()))\n        registerChanges()\n    }\n\n    private var filterJob: Job? by smartJob()\n\n    fun <T : Any> updateFilter(\n        value: T,\n        index: Int\n    ) {\n        val list = _basicFilterState.value.filters.toMutableList()\n        runCatching {\n            list[index] = list[index].copy(value)\n            _basicFilterState.update {\n                it.copy(filters = list)\n            }\n        }.onFailure { throwable ->\n            AppToastHost.showFailureToast(throwable)\n            list[index] = list[index].newInstance()\n            _basicFilterState.update {\n                it.copy(filters = list)\n            }\n        }\n        updateCanSave()\n        updatePreview()\n    }\n\n    fun updateFiltersOrder(value: List<UiFilter<*>>) {\n        _basicFilterState.update {\n            it.copy(filters = value)\n        }\n        filterJob = null\n        updateCanSave()\n        updatePreview()\n    }\n\n    fun addFilterNewInstance(filter: UiFilter<*>) {\n        addFilter(filter.newInstance())\n    }\n\n    fun addFilter(filter: UiFilter<*>) {\n        _basicFilterState.update {\n            it.copy(filters = it.filters + filter)\n        }\n        updateCanSave()\n        filterJob = null\n        updatePreview()\n    }\n\n    fun removeFilterAtIndex(index: Int) {\n        _basicFilterState.update {\n            it.copy(\n                filters = it.filters.toMutableList().apply {\n                    removeAt(index)\n                }\n            )\n        }\n        updateCanSave()\n        filterJob = null\n        updatePreview()\n    }\n\n    fun canShow(): Boolean = bitmap?.let { imagePreviewCreator.canShow(it) } == true\n\n    fun performSharing() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            when (filterType) {\n                is Screen.Filter.Type.Basic -> {\n                    _left.value = _basicFilterState.value.uris?.size ?: 1\n                    shareProvider.shareImages(\n                        uris = _basicFilterState.value.uris?.map { it.toString() } ?: emptyList(),\n                        imageLoader = { uri ->\n                            imageGetter.getImageWithTransformations(\n                                uri = uri,\n                                transformations = _basicFilterState.value.filters.map {\n                                    filterProvider.filterToTransformation(it)\n                                }\n                            )?.let {\n                                it.image to it.imageInfo\n                            }\n                        },\n                        onProgressChange = {\n                            if (it == -1) {\n                                AppToastHost.showConfetti()\n                                _isSaving.value = false\n                                _done.value = 0\n                            } else {\n                                _done.value = it\n                            }\n\n                            updateProgress(\n                                done = done,\n                                total = left\n                            )\n                        }\n                    )\n                }\n\n                is Screen.Filter.Type.Masking -> {\n                    _left.value = maskingFilterState.masks.size\n                    maskingFilterState.uri?.toString()?.let {\n                        imageGetter.getImage(uri = it)\n                    }?.let {\n                        maskingFilterState.masks.fold<UiFilterMask, Bitmap?>(\n                            initial = it.image,\n                            operation = { bmp, mask ->\n                                bmp?.let {\n                                    filterMaskApplier.filterByMask(\n                                        filterMask = mask, image = bmp\n                                    )\n                                }?.also {\n                                    _done.value++\n                                    updateProgress(\n                                        done = done,\n                                        total = left\n                                    )\n                                }\n                            }\n                        )?.let { bitmap ->\n                            shareProvider.shareImage(\n                                image = bitmap,\n                                imageInfo = imageInfo.copy(\n                                    width = bitmap.width,\n                                    height = bitmap.height\n                                ),\n                                onComplete = {\n                                    _isSaving.value = false\n                                    AppToastHost.showConfetti()\n                                }\n                            )\n                        }\n                    }\n                }\n\n                null -> Unit\n            }\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        _imageInfo.update(onValueChanged = ::updatePreview) {\n            it.copy(quality = quality)\n        }\n    }\n\n    private fun updatePreview() {\n        _bitmap.value?.let { bitmap ->\n            filterJob = componentScope.launch {\n                delay(200L)\n                _isImageLoading.value = true\n                when (filterType) {\n                    is Screen.Filter.Type.Basic -> {\n                        _previewBitmap.value = imagePreviewCreator.createPreview(\n                            image = bitmap,\n                            imageInfo = imageInfo,\n                            transformations = _basicFilterState.value.filters.map {\n                                filterProvider.filterToTransformation(it)\n                            },\n                            onGetByteCount = { size ->\n                                _imageInfo.update { it.copy(sizeInBytes = size) }\n                            }\n                        )\n                    }\n\n                    is Screen.Filter.Type.Masking -> {\n                        _previewBitmap.value = filterMaskApplier.filterByMasks(\n                            filterMasks = _maskingFilterState.value.masks,\n                            image = bitmap\n                        )?.let { bmp ->\n                            imagePreviewCreator.createPreview(\n                                image = bmp,\n                                imageInfo = imageInfo,\n                                onGetByteCount = { size ->\n                                    _imageInfo.update { it.copy(sizeInBytes = size) }\n                                }\n                            )\n                        }\n                    }\n\n                    null -> Unit\n                }\n                _isImageLoading.value = false\n            }\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun setType(type: Screen.Filter.Type) {\n        when (type) {\n            is Screen.Filter.Type.Basic -> setBasicFilter(type.uris)\n            is Screen.Filter.Type.Masking -> setMaskFilter(type.uri)\n        }\n    }\n\n    fun setMaskFilter(uri: Uri?) {\n        _filterType.update {\n            it as? Screen.Filter.Type.Masking ?: Screen.Filter.Type.Masking(uri)\n        }\n        uri?.let { updateSelectedUri(it) }\n        _maskingFilterState.value = MaskingFilterState(uri)\n        updatePreview()\n        updateCanSave()\n    }\n\n    fun clearType() {\n        _filterType.update { null }\n        _basicFilterState.update { BasicFilterState() }\n        _maskingFilterState.update { MaskingFilterState() }\n        _bitmap.value = null\n        _previewBitmap.value = null\n        _imageInfo.update { ImageInfo() }\n        updateCanSave()\n        registerChangesCleared()\n    }\n\n    fun saveMaskedBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            _left.value = maskingFilterState.masks.size\n            maskingFilterState.uri?.toString()?.let {\n                imageGetter.getImage(uri = it)\n            }?.let {\n                maskingFilterState.masks.fold<UiFilterMask, Bitmap?>(\n                    initial = it.image,\n                    operation = { bmp, mask ->\n                        bmp?.let {\n                            filterMaskApplier.filterByMask(\n                                filterMask = mask, image = bmp\n                            )\n                        }?.also {\n                            _done.value++\n                            updateProgress(\n                                done = done,\n                                total = left\n                            )\n                        }\n                    }\n                )?.let { localBitmap ->\n                    parseSaveResult(\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = imageInfo.copy(\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                ),\n                                originalUri = maskingFilterState.uri.toString(),\n                                sequenceNumber = null,\n                                data = imageCompressor.compressAndTransform(\n                                    image = localBitmap,\n                                    imageInfo = imageInfo.copy(\n                                        width = localBitmap.width,\n                                        height = localBitmap.height\n                                    )\n                                )\n                            ),\n                            keepOriginalMetadata = keepExif,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        ).onSuccess(::registerSave)\n                    )\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun updateMasksOrder(uiFilterMasks: List<UiFilterMask>) {\n        _maskingFilterState.update {\n            it.copy(masks = uiFilterMasks)\n        }\n        updatePreview()\n        updateCanSave()\n    }\n\n    fun updateMask(\n        value: UiFilterMask,\n        index: Int\n    ) {\n        runCatching {\n            _maskingFilterState.update {\n                it.copy(\n                    masks = it.masks.toMutableList().apply {\n                        this[index] = value\n                    }\n                )\n            }\n            updatePreview()\n            updateCanSave()\n        }.onFailure(AppToastHost::showFailureToast)\n    }\n\n    fun removeMaskAtIndex(index: Int) {\n        _maskingFilterState.update {\n            it.copy(\n                masks = it.masks.toMutableList().apply {\n                    removeAt(index)\n                }\n            )\n        }\n        updatePreview()\n        updateCanSave()\n    }\n\n    fun addMask(value: UiFilterMask) {\n        _maskingFilterState.update {\n            it.copy(\n                masks = it.masks + value\n            )\n        }\n        updatePreview()\n        updateCanSave()\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            when (filterType) {\n                is Screen.Filter.Type.Basic -> {\n                    imageGetter.getImageWithTransformations(\n                        uri = _basicFilterState.value.selectedUri.toString(),\n                        transformations = _basicFilterState.value.filters.map {\n                            filterProvider.filterToTransformation(it)\n                        }\n                    )?.let { (image, imageInfo) ->\n                        shareProvider.cacheImage(\n                            image = image,\n                            imageInfo = imageInfo\n                        )?.let {\n                            onComplete(it.toUri())\n                        }\n                    }\n                }\n\n                is Screen.Filter.Type.Masking -> {\n                    _left.value = maskingFilterState.masks.size\n                    maskingFilterState.uri?.toString()?.let {\n                        imageGetter.getImage(uri = it)\n                    }?.let { imageData ->\n                        maskingFilterState.masks.fold<UiFilterMask, Bitmap?>(\n                            initial = imageData.image,\n                            operation = { bmp, mask ->\n                                bmp?.let {\n                                    filterMaskApplier.filterByMask(\n                                        filterMask = mask,\n                                        image = bmp\n                                    )\n                                }?.also {\n                                    _done.value++\n                                    updateProgress(\n                                        done = done,\n                                        total = left\n                                    )\n                                }\n                            }\n                        )?.let { bitmap ->\n                            shareProvider.cacheImage(\n                                image = bitmap,\n                                imageInfo = imageInfo.copy(\n                                    width = bitmap.width,\n                                    height = bitmap.height\n                                )\n                            )?.let {\n                                onComplete(it.toUri())\n                            }\n                        }\n                    }\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val list = mutableListOf<Uri>()\n            when (filterType) {\n                is Screen.Filter.Type.Basic -> {\n                    _done.value = 0\n                    _left.value = basicFilterState.uris?.size ?: 0\n                    basicFilterState.uris?.forEach { uri ->\n                        imageGetter.getImageWithTransformations(\n                            uri = uri.toString(),\n                            transformations = _basicFilterState.value.filters.map {\n                                filterProvider.filterToTransformation(it)\n                            }\n                        )?.let { (image, imageInfo) ->\n                            shareProvider.cacheImage(\n                                image = image,\n                                imageInfo = imageInfo\n                            )?.let {\n                                list.add(it.toUri())\n                            }\n                        }\n                        _done.value++\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n                }\n\n                is Screen.Filter.Type.Masking -> {\n                    _done.value = 0\n                    _left.value = maskingFilterState.masks.size\n                    maskingFilterState.uri?.toString()?.let {\n                        imageGetter.getImage(uri = it)\n                    }?.let { imageData ->\n                        maskingFilterState.masks.fold<UiFilterMask, Bitmap?>(\n                            initial = imageData.image,\n                            operation = { bmp, mask ->\n                                bmp?.let {\n                                    filterMaskApplier.filterByMask(\n                                        filterMask = mask,\n                                        image = bmp\n                                    )\n                                }?.also {\n                                    _done.value++\n                                    updateProgress(\n                                        done = done,\n                                        total = left\n                                    )\n                                }\n                            }\n                        )?.let { bitmap ->\n                            shareProvider.cacheImage(\n                                image = bitmap,\n                                imageInfo = imageInfo.copy(\n                                    width = bitmap.width,\n                                    height = bitmap.height\n                                )\n                            )?.let {\n                                list.add(it.toUri())\n                            }\n                        }\n                    }\n                }\n\n                null -> Unit\n            }\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        basicFilterState.uris\n            ?.indexOf(basicFilterState.selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                basicFilterState.uris?.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        basicFilterState.uris\n            ?.indexOf(basicFilterState.selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                basicFilterState.uris?.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? = when {\n        basicFilterState.uris?.size == 1 -> imageInfo.imageFormat\n        maskingFilterState.uri != null -> imageInfo.imageFormat\n        else -> null\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialType: Screen.Filter.Type?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): FiltersComponent\n    }\n\n}"
  },
  {
    "path": "feature/format-conversion/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/format-conversion/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.format_conversion\"\n\ndependencies {\n    implementation(projects.feature.compare)\n}"
  },
  {
    "path": "feature/format-conversion/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/format-conversion/src/main/java/com/t8rin/imagetoolbox/feature/format_conversion/presentation/FormatConversionContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.format_conversion.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.CompareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.core.utils.fileSize\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareSheet\nimport com.t8rin.imagetoolbox.feature.format_conversion.presentation.screenLogic.FormatConversionComponent\n\n@Composable\nfun FormatConversionContent(\n    component: FormatConversionComponent\n) {\n    AutoContentBasedColors(component.bitmap)\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setUris(\n            uris = uris\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    var showCompareSheet by rememberSaveable { mutableStateOf(false) }\n\n    CompareSheet(\n        data = component.bitmap to component.previewBitmap,\n        visible = showCompareSheet,\n        onDismiss = {\n            showCompareSheet = false\n        }\n    )\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.format_conversion),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = component.imageInfo.sizeInBytes.toLong(),\n                originalSize = component.selectedUri?.fileSize()\n            )\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.bitmap != null,\n                onShare = component::shareBitmaps,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        imagePreview = {\n            ImageContainer(\n                modifier = Modifier\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                imageInside = isPortrait,\n                showOriginal = false,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.bitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = component.shouldShowPreview\n            )\n        },\n        controls = {\n            val imageInfo = component.imageInfo\n            ImageCounter(\n                imageCount = component.uris?.size?.takeIf { it > 1 },\n                onRepick = {\n                    showPickImageFromUrisSheet = true\n                }\n            )\n            Spacer(Modifier.size(8.dp))\n            AnimatedVisibility(\n                visible = component.uris?.size != 1,\n                enter = fadeIn() + expandVertically(),\n                exit = fadeOut() + shrinkVertically()\n            ) {\n                Column {\n                    SaveExifWidget(\n                        imageFormat = component.imageInfo.imageFormat,\n                        checked = component.keepExif,\n                        onCheckedChange = component::setKeepExif\n                    )\n                    Spacer(Modifier.size(8.dp))\n                }\n            }\n            Spacer(Modifier.height(8.dp))\n            ImageFormatSelector(\n                value = imageInfo.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = imageInfo.quality\n            )\n            if (imageInfo.imageFormat.canChangeCompressionValue) {\n                Spacer(Modifier.height(8.dp))\n            }\n            QualitySelector(\n                imageFormat = imageInfo.imageFormat,\n                quality = imageInfo.quality,\n                onQualityChange = component::setQuality\n            )\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.bitmap == null) TopAppBarEmoji()\n            CompareButton(\n                onClick = { showCompareSheet = true },\n                visible = component.previewBitmap != null\n                        && component.bitmap != null\n                        && component.shouldShowPreview\n            )\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.previewBitmap != null && component.shouldShowPreview\n            )\n        },\n        canShowScreenData = component.bitmap != null,\n        forceImagePreviewToMax = false,\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        }\n    )\n\n    val transformations by remember(component.imageInfo) {\n        derivedStateOf(component::getConversionTransformation)\n    }\n\n    PickImageFromUrisSheet(\n        transformations = transformations,\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = component::updateSelectedUri,\n        onUriRemoved = component::updateUrisSilently,\n        columns = if (isPortrait) 2 else 4,\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris?.size ?: 1,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/format-conversion/src/main/java/com/t8rin/imagetoolbox/feature/format_conversion/presentation/screenLogic/FormatConversionComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.format_conversion.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageData\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.transformation.ImageInfoTransformation\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass FormatConversionComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageInfoTransformationFactory: ImageInfoTransformation.Factory,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n        }\n    }\n\n    private val _originalSize: MutableState<IntegerSize?> = mutableStateOf(null)\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _keepExif = mutableStateOf(false)\n    val keepExif by _keepExif\n\n    private val _imageInfo: MutableState<ImageInfo> = mutableStateOf(ImageInfo())\n    val imageInfo: ImageInfo by _imageInfo\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _shouldShowPreview: MutableState<Boolean> = mutableStateOf(true)\n    val shouldShowPreview by _shouldShowPreview\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _selectedUri: MutableState<Uri?> = mutableStateOf(null)\n    val selectedUri by _selectedUri\n\n    private var job: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    fun setUris(\n        uris: List<Uri>?\n    ) {\n        _uris.value = null\n        _uris.value = uris\n        _selectedUri.value = uris?.firstOrNull()\n        uris?.firstOrNull()?.let { uri ->\n            _imageInfo.update {\n                it.copy(originalUri = uri.toString())\n            }\n            imageGetter.getImageAsync(\n                uri = uri.toString(),\n                originalSize = false,\n                onGetImage = ::setImageData,\n                onFailure = AppToastHost::showFailureToast\n            )\n        }\n    }\n\n    fun updateUrisSilently(\n        removedUri: Uri\n    ) {\n        componentScope.launch {\n            _uris.value = uris\n            if (_selectedUri.value == removedUri) {\n                val index = uris?.indexOf(removedUri) ?: -1\n                if (index == 0) {\n                    uris?.getOrNull(1)?.let {\n                        updateSelectedUri(it)\n                    }\n                } else {\n                    uris?.getOrNull(index - 1)?.let {\n                        updateSelectedUri(it)\n                    }\n                }\n            }\n            val u = _uris.value?.toMutableList()?.apply {\n                remove(removedUri)\n            }\n            _uris.value = u\n\n            registerChanges()\n        }\n    }\n\n    private suspend fun checkBitmapAndUpdate() {\n        _bitmap.value?.let { bmp ->\n            val preview = updatePreview(bmp)\n            _previewBitmap.value = null\n            _shouldShowPreview.value = imagePreviewCreator.canShow(preview)\n            if (shouldShowPreview) _previewBitmap.value = preview\n        }\n    }\n\n    private suspend fun updatePreview(\n        bitmap: Bitmap\n    ): Bitmap? = imagePreviewCreator.createPreview(\n        image = bitmap,\n        imageInfo = imageInfo,\n        onGetByteCount = { size ->\n            _imageInfo.update { it.copy(sizeInBytes = size) }\n        }\n    )\n\n    private fun resetValues() {\n        _imageInfo.value = ImageInfo(\n            width = _originalSize.value?.width ?: 0,\n            height = _originalSize.value?.height ?: 0,\n            imageFormat = imageInfo.imageFormat,\n            originalUri = selectedUri?.toString()\n        )\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n    }\n\n    private fun setImageData(imageData: ImageData<Bitmap>) {\n        job = componentScope.launch {\n            _isImageLoading.update { true }\n            val bitmap = imageData.image\n            val size = bitmap.width to bitmap.height\n            _originalSize.update {\n                size.run { IntegerSize(width = first, height = second) }\n            }\n            _bitmap.update {\n                imageScaler.scaleUntilCanShow(bitmap)\n            }\n            resetValues()\n            _imageInfo.update {\n                imageData.imageInfo.copy(\n                    width = size.first,\n                    height = size.second\n                )\n            }\n            checkBitmapAndUpdate()\n            _isImageLoading.update { false }\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        if (_imageInfo.value.quality != quality) {\n            _imageInfo.value = _imageInfo.value.copy(quality = quality)\n            debouncedImageCalculation {\n                checkBitmapAndUpdate()\n            }\n            registerChanges()\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        if (_imageInfo.value.imageFormat != imageFormat) {\n            _imageInfo.value = _imageInfo.value.copy(imageFormat = imageFormat)\n            debouncedImageCalculation {\n                checkBitmapAndUpdate()\n            }\n            registerChanges()\n        }\n    }\n\n    fun setKeepExif(boolean: Boolean) {\n        _keepExif.value = boolean\n        registerChanges()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    imageGetter.getImage(uri.toString())?.image\n                }.getOrNull()?.let { bitmap ->\n                    imageInfo.copy(\n                        originalUri = uri.toString()\n                    ).let {\n                        imageTransformer.applyPresetBy(\n                            image = bitmap,\n                            preset = Preset.Original,\n                            currentInfo = it\n                        )\n                    }.let { imageInfo ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = ImageSaveTarget(\n                                    imageInfo = imageInfo,\n                                    metadata = null,\n                                    originalUri = uri.toString(),\n                                    sequenceNumber = _done.value + 1,\n                                    data = imageCompressor.compressAndTransform(\n                                        image = bitmap,\n                                        imageInfo = imageInfo\n                                    ),\n                                    canSkipIfLarger = true\n                                ),\n                                keepOriginalMetadata = keepExif,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                    }\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun updateSelectedUri(\n        uri: Uri\n    ) {\n        _selectedUri.value = uri\n        componentScope.launch {\n            runSuspendCatching {\n                _isImageLoading.update { true }\n                val bitmap = imageGetter.getImage(\n                    uri = uri.toString(),\n                    originalSize = true\n                )?.image\n                val size = bitmap?.let { it.width to it.height }\n                _originalSize.value = size?.run { IntegerSize(width = first, height = second) }\n                _bitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n                _imageInfo.value = _imageInfo.value.copy(\n                    width = size?.first ?: 0,\n                    height = size?.second ?: 0,\n                    originalUri = uri.toString()\n                )\n                _imageInfo.value = imageTransformer.applyPresetBy(\n                    image = _bitmap.value,\n                    preset = Preset.Original,\n                    currentInfo = _imageInfo.value\n                )\n                checkBitmapAndUpdate()\n                _isImageLoading.update { false }\n            }.onFailure {\n                _isImageLoading.update { false }\n                AppToastHost.showFailureToast(it)\n            }\n        }\n    }\n\n    fun shareBitmaps() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            shareProvider.shareImages(\n                uris = uris?.map { it.toString() } ?: emptyList(),\n                imageLoader = { uri ->\n                    imageGetter.getImage(uri)?.image?.let { bmp ->\n                        bmp to imageInfo.copy(\n                            originalUri = uri\n                        ).let {\n                            imageTransformer.applyPresetBy(\n                                image = bitmap,\n                                preset = Preset.Original,\n                                currentInfo = it\n                            )\n                        }\n                    }\n                },\n                onProgressChange = {\n                    if (it == -1) {\n                        AppToastHost.showConfetti()\n                        _isSaving.value = false\n                        _done.value = 0\n                    } else {\n                        _done.value = it\n                    }\n                    updateProgress(\n                        done = done,\n                        total = uris.orEmpty().size\n                    )\n                }\n            )\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            imageGetter.getImage(selectedUri.toString())?.image?.let { bmp ->\n                bmp to imageInfo.copy(\n                    originalUri = selectedUri.toString()\n                ).let {\n                    imageTransformer.applyPresetBy(\n                        image = bitmap,\n                        preset = Preset.Original,\n                        currentInfo = it\n                    )\n                }\n            }?.let { (image, imageInfo) ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo.copy(originalUri = selectedUri.toString())\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            val list = mutableListOf<Uri>()\n            uris?.forEach {\n                imageGetter.getImage(it.toString())?.image?.let { bmp ->\n                    bmp to imageInfo.copy(\n                        originalUri = it.toString()\n                    ).let { info ->\n                        imageTransformer.applyPresetBy(\n                            image = bitmap,\n                            preset = Preset.Original,\n                            currentInfo = info\n                        )\n                    }\n                }?.let { (image, imageInfo) ->\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = imageInfo.copy(originalUri = it.toString())\n                    )?.let { uri ->\n                        list.add(uri.toUri())\n                    }\n                }\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? =\n        if (uris?.size == 1) imageInfo.imageFormat\n        else null\n\n    fun getConversionTransformation() = listOf(\n        imageInfoTransformationFactory(\n            imageInfo = imageInfo,\n            preset = Preset.Original\n        )\n    )\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): FormatConversionComponent\n    }\n}"
  },
  {
    "path": "feature/gif-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/gif-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.gif_tools\"\n\ndependencies {\n    implementation(libs.toolbox.awebp)\n    implementation(libs.toolbox.gifConverter)\n    implementation(libs.jxl.coder)\n}"
  },
  {
    "path": "feature/gif-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/data/AndroidGifConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.PorterDuff\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.net.toUri\nimport com.awxkee.jxlcoder.JxlCoder\nimport com.awxkee.jxlcoder.JxlDecodingSpeed\nimport com.awxkee.jxlcoder.JxlEffort\nimport com.t8rin.awebp.encoder.AnimatedWebpEncoder\nimport com.t8rin.gif_converter.GifDecoder\nimport com.t8rin.gif_converter.GifEncoder\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.data.utils.toSoftware\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.feature.gif_tools.domain.GifConverter\nimport com.t8rin.imagetoolbox.feature.gif_tools.domain.GifParams\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.cancel\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.flow.mapNotNull\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.withContext\nimport java.io.ByteArrayOutputStream\nimport java.io.InputStream\nimport javax.inject.Inject\n\n\ninternal class AndroidGifConverter @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageShareProvider: ImageShareProvider<Bitmap>,\n    @ApplicationContext private val context: Context,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, GifConverter {\n\n    override fun extractFramesFromGif(\n        gifUri: String,\n        imageFormat: ImageFormat,\n        imageFrames: ImageFrames,\n        quality: Quality,\n        onGetFramesCount: (frames: Int) -> Unit\n    ): Flow<String> = extractFramesFromGif(\n        gifUri = gifUri,\n        imageFrames = imageFrames,\n        onGetFramesCount = onGetFramesCount\n    ).mapNotNull { (frame) ->\n        imageShareProvider.cacheImage(\n            image = frame,\n            imageInfo = ImageInfo(\n                width = frame.width,\n                height = frame.height,\n                imageFormat = imageFormat,\n                quality = quality\n            )\n        )\n    }\n\n    override suspend fun createGifFromImageUris(\n        imageUris: List<String>,\n        params: GifParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): ByteArray? = withContext(defaultDispatcher) {\n        val out = ByteArrayOutputStream()\n        val encoder = GifEncoder().apply {\n            params.size?.let { size ->\n                if (size.width <= 0 || size.height <= 0) {\n                    onFailure(IllegalArgumentException(\"Width and height must be > 0\"))\n                    return@withContext null\n                }\n\n                setSize(\n                    size.width,\n                    size.height\n                )\n            }\n            setRepeat(params.repeatCount)\n            setQuality(\n                (100 - ((params.quality.qualityValue - 1) * (100 / 19f))).toInt()\n            )\n            setFrameRate(params.fps.toFloat())\n            setDispose(\n                if (params.dontStack) 2 else 0\n            )\n            setTransparent(Color.Transparent.toArgb())\n            start(out)\n        }\n        imageUris.forEachIndexed { index, uri ->\n            imageGetter.getImage(\n                data = uri,\n                size = params.size\n            )?.apply { setHasAlpha(true) }?.let { frame ->\n                encoder.addFrame(frame)\n                if (params.crossfadeCount > 1) {\n                    val list = mutableSetOf(0, 255)\n                    for (a in 0..255 step (255 / params.crossfadeCount)) {\n                        list.add(a)\n                    }\n                    val alphas = list.sortedDescending()\n\n\n                    imageGetter.getImage(\n                        data = imageUris.getOrNull(index + 1) ?: Unit,\n                        size = params.size\n                    )?.let { next ->\n                        alphas.forEach { alpha ->\n                            encoder.addFrame(\n                                next.overlay(\n                                    frame.copy(frame.safeConfig, true).applyCanvas {\n                                        drawColor(\n                                            Color.Black.copy(alpha / 255f).toArgb(),\n                                            PorterDuff.Mode.DST_IN\n                                        )\n                                    }\n                                )\n                            )\n                        }\n                    }\n                }\n            }\n            onProgress()\n        }\n        encoder.finish()\n\n        out.toByteArray()\n    }\n\n    private fun Bitmap.overlay(overlay: Bitmap): Bitmap {\n        return createBitmap(width, height, safeConfig.toSoftware()).applyCanvas {\n            drawBitmap(this@overlay)\n            drawBitmap(overlay.toSoftware())\n        }\n    }\n\n    override suspend fun convertGifToJxl(\n        gifUris: List<String>,\n        quality: Quality.Jxl,\n        onProgress: suspend (String, ByteArray) -> Unit\n    ) = withContext(defaultDispatcher) {\n        gifUris.forEach { uri ->\n            uri.bytes?.let { gifData ->\n                runSuspendCatching {\n                    JxlCoder.Convenience.gif2JXL(\n                        gifData = gifData,\n                        quality = quality.qualityValue.coerceIn(0, 99),\n                        effort = JxlEffort.entries.first { it.ordinal == quality.effort },\n                        decodingSpeed = JxlDecodingSpeed.entries.first { it.ordinal == quality.speed }\n                    ).let {\n                        onProgress(uri, it)\n                    }\n                }\n            }\n        }\n    }\n\n    override suspend fun convertGifToWebp(\n        gifUris: List<String>,\n        quality: Quality.Base,\n        onProgress: suspend (String, ByteArray) -> Unit\n    ) = withContext(defaultDispatcher) {\n        gifUris.forEach { uri ->\n            runSuspendCatching {\n                val encoder = AnimatedWebpEncoder(\n                    quality = quality.qualityValue,\n                    loopCount = 1,\n                    backgroundColor = Color.Transparent.toArgb()\n                )\n\n                extractFramesFromGif(\n                    gifUri = uri,\n                    imageFrames = ImageFrames.All,\n                    onGetFramesCount = {}\n                ).collect { (frame, duration) ->\n                    encoder.addFrame(\n                        bitmap = frame.copy(frame.safeConfig, false),\n                        duration = duration\n                    )\n                }\n\n                onProgress(uri, encoder.encode())\n            }\n        }\n    }\n\n    private fun extractFramesFromGif(\n        gifUri: String,\n        imageFrames: ImageFrames,\n        onGetFramesCount: (frames: Int) -> Unit\n    ): Flow<Pair<Bitmap, Int>> = flow {\n        val bytes = gifUri.bytes\n        val decoder = GifDecoder().apply {\n            read(bytes)\n        }\n        onGetFramesCount(decoder.frameCount)\n        val indexes = imageFrames\n            .getFramePositions(decoder.frameCount)\n            .map { it - 1 }\n        repeat(decoder.frameCount) { pos ->\n            if (!currentCoroutineContext().isActive) {\n                currentCoroutineContext().cancel(null)\n                return@repeat\n            }\n            decoder.advance()\n            decoder.nextFrame?.let { frame ->\n                frame to decoder.nextDelay\n            }?.takeIf {\n                pos in indexes\n            }?.let { emit(it) }\n        }\n    }\n\n    private val String.inputStream: InputStream?\n        get() = context\n            .contentResolver\n            .openInputStream(toUri())\n\n    private val String.bytes: ByteArray?\n        get() = inputStream?.use {\n            it.readBytes()\n        }\n\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/di/GifToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.di\n\nimport com.t8rin.imagetoolbox.feature.gif_tools.data.AndroidGifConverter\nimport com.t8rin.imagetoolbox.feature.gif_tools.domain.GifConverter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface GifToolsModule {\n\n    @Binds\n    @Singleton\n    fun provideConverter(\n        converter: AndroidGifConverter\n    ): GifConverter\n\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/domain/GifConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport kotlinx.coroutines.flow.Flow\n\ninterface GifConverter {\n\n    fun extractFramesFromGif(\n        gifUri: String,\n        imageFormat: ImageFormat,\n        imageFrames: ImageFrames,\n        quality: Quality,\n        onGetFramesCount: (frames: Int) -> Unit = {}\n    ): Flow<String>\n\n    suspend fun createGifFromImageUris(\n        imageUris: List<String>,\n        params: GifParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): ByteArray?\n\n    suspend fun convertGifToJxl(\n        gifUris: List<String>,\n        quality: Quality.Jxl,\n        onProgress: suspend (String, ByteArray) -> Unit\n    )\n\n    suspend fun convertGifToWebp(\n        gifUris: List<String>,\n        quality: Quality.Base,\n        onProgress: suspend (String, ByteArray) -> Unit\n    )\n\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/domain/GifParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ndata class GifParams(\n    val size: IntegerSize?,\n    val repeatCount: Int,\n    val fps: Int,\n    val quality: Quality,\n    val dontStack: Boolean,\n    val crossfadeCount: Int\n) {\n    companion object {\n        val Default by lazy {\n            GifParams(\n                size = null,\n                repeatCount = 0,\n                fps = 12,\n                quality = Quality.Base(50),\n                dontStack = false,\n                crossfadeCount = 0\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/presentation/GifToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Gif\nimport androidx.compose.material.icons.rounded.Gif\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.core.utils.isGif\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.components.GifToolsControls\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.components.GifToolsImagePreview\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.components.GifToolsNoDataControls\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.components.GifToolsTopAppBarActions\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent\n\n@Composable\nfun GifToolsContent(\n    component: GifToolsComponent\n) {\n    val imagePicker = rememberImagePicker(onSuccess = component::setImageUris)\n\n    val pickSingleGifLauncher = rememberFilePicker(\n        mimeType = MimeType.Gif,\n        onSuccess = { uri: Uri ->\n            if (uri.isGif()) {\n                component.setGifUri(uri)\n            } else {\n                AppToastHost.showToast(\n                    message = getString(R.string.select_gif_image_to_start),\n                    icon = Icons.Rounded.Gif\n                )\n            }\n        }\n    )\n\n    val pickMultipleGifToJxlLauncher = rememberFilePicker(\n        mimeType = MimeType.Gif,\n        onSuccess = { list: List<Uri> ->\n            list.filter {\n                it.isGif()\n            }.let { uris ->\n                if (uris.isEmpty()) {\n                    AppToastHost.showToast(\n                        message = getString(R.string.select_gif_image_to_start),\n                        icon = Icons.Filled.Gif\n                    )\n                } else {\n                    component.setType(\n                        Screen.GifTools.Type.GifToJxl(uris)\n                    )\n                }\n            }\n        }\n    )\n\n    val pickMultipleGifToWebpLauncher = rememberFilePicker(\n        mimeType = MimeType.Gif,\n        onSuccess = { list: List<Uri> ->\n            list.filter {\n                it.isGif()\n            }.let { uris ->\n                if (uris.isEmpty()) {\n                    AppToastHost.showToast(\n                        message = getString(R.string.select_gif_image_to_start),\n                        icon = Icons.Filled.Gif\n                    )\n                } else {\n                    component.setType(\n                        Screen.GifTools.Type.GifToWebp(uris)\n                    )\n                }\n            }\n        }\n    )\n\n    val addGifsToJxlLauncher = rememberFilePicker(\n        mimeType = MimeType.Gif,\n        onSuccess = { list: List<Uri> ->\n            list.filter {\n                it.isGif()\n            }.let { uris ->\n                if (uris.isEmpty()) {\n                    AppToastHost.showToast(\n                        message = getString(R.string.select_gif_image_to_start),\n                        icon = Icons.Filled.Gif\n                    )\n                } else {\n                    component.setType(\n                        Screen.GifTools.Type.GifToJxl(\n                            (component.type as? Screen.GifTools.Type.GifToJxl)?.gifUris?.plus(uris)\n                                ?.distinct()\n                        )\n                    )\n                }\n            }\n        }\n    )\n\n    val addGifsToWebpLauncher = rememberFilePicker(\n        mimeType = MimeType.Gif,\n        onSuccess = { list: List<Uri> ->\n            list.filter {\n                it.isGif()\n            }.let { uris ->\n                if (uris.isEmpty()) {\n                    AppToastHost.showToast(\n                        message = getString(R.string.select_gif_image_to_start),\n                        icon = Icons.Filled.Gif\n                    )\n                } else {\n                    component.setType(\n                        Screen.GifTools.Type.GifToWebp(\n                            (component.type as? Screen.GifTools.Type.GifToWebp)?.gifUris?.plus(uris)\n                                ?.distinct()\n                        )\n                    )\n                }\n            }\n        }\n    )\n\n    val saveGifLauncher = rememberFileCreator(\n        mimeType = MimeType.Gif,\n        onSuccess = component::saveGifTo\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = when (val type = component.type) {\n                    null -> stringResource(R.string.gif_tools)\n                    else -> stringResource(type.title)\n                },\n                input = component.type,\n                isLoading = component.isLoading,\n                size = null\n            )\n        },\n        onGoBack = onBack,\n        topAppBarPersistentActions = {\n            GifToolsTopAppBarActions(component)\n        },\n        actions = {\n            ShareButton(\n                enabled = !component.isLoading && component.type != null,\n                onShare = component::performSharing\n            )\n        },\n        imagePreview = {\n            GifToolsImagePreview(\n                component = component,\n                onAddGifsToJxl = addGifsToJxlLauncher::pickFile,\n                onAddGifsToWebp = addGifsToWebpLauncher::pickFile\n            )\n        },\n        placeImagePreview = component.type !is Screen.GifTools.Type.ImageToGif,\n        showImagePreviewAsStickyHeader = false,\n        autoClearFocus = false,\n        controls = {\n            GifToolsControls(component)\n        },\n        contentPadding = animateDpAsState(\n            if (component.type == null) 12.dp\n            else 20.dp\n        ).value,\n        buttons = { actions ->\n            val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n                component.saveBitmaps(\n                    oneTimeSaveLocationUri = it,\n                    onGifSaveResult = saveGifLauncher::make\n                )\n            }\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n\n            BottomButtonsBlock(\n                isNoData = component.type == null,\n                onSecondaryButtonClick = {\n                    when (component.type) {\n                        is Screen.GifTools.Type.GifToImage -> pickSingleGifLauncher.pickFile()\n                        is Screen.GifTools.Type.GifToJxl -> pickMultipleGifToJxlLauncher.pickFile()\n                        is Screen.GifTools.Type.GifToWebp -> pickMultipleGifToWebpLauncher.pickFile()\n                        else -> imagePicker.pickImage()\n                    }\n                },\n                isPrimaryButtonVisible = component.canSave,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    if (component.type is Screen.GifTools.Type.ImageToGif) {\n                        saveBitmaps(null)\n                    } else showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                showNullDataButtonAsContainer = true,\n                onSecondaryButtonLongClick = if (component.type is Screen.GifTools.Type.ImageToGif || component.type == null) {\n                    {\n                        showOneTimeImagePickingDialog = true\n                    }\n                } else null\n            )\n\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        insetsForNoData = WindowInsets(0),\n        noDataControls = {\n            GifToolsNoDataControls(\n                onClickType = { type ->\n                    when (type) {\n                        is Screen.GifTools.Type.GifToImage -> pickSingleGifLauncher.pickFile()\n                        is Screen.GifTools.Type.GifToJxl -> pickMultipleGifToJxlLauncher.pickFile()\n                        is Screen.GifTools.Type.GifToWebp -> pickMultipleGifToWebpLauncher.pickFile()\n                        is Screen.GifTools.Type.ImageToGif -> imagePicker.pickImage()\n                    }\n                }\n            )\n        },\n        canShowScreenData = component.type != null\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component::resetState,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}\n\nprivate val GifToolsComponent.canSave: Boolean\n    get() = (gifFrames == ImageFrames.All)\n        .or(type is Screen.GifTools.Type.ImageToGif)\n        .or((gifFrames as? ImageFrames.ManualSelection)?.framePositions?.isNotEmpty() == true)"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/presentation/components/GifParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FilterFrames\nimport androidx.compose.material.icons.outlined.Opacity\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectLarge\nimport androidx.compose.material.icons.outlined.RepeatOne\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Counter\nimport com.t8rin.imagetoolbox.core.resources.icons.Stacks\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.gif_tools.domain.GifParams\nimport kotlinx.collections.immutable.persistentMapOf\nimport kotlin.math.roundToInt\n\n@Composable\nfun GifParamsSelector(\n    value: GifParams,\n    onValueChange: (GifParams) -> Unit\n) {\n    Column {\n        val size = value.size ?: IntegerSize.Undefined\n        AnimatedVisibility(size.isDefined()) {\n            ResizeImageField(\n                imageInfo = ImageInfo(size.width, size.height),\n                originalSize = null,\n                onWidthChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(width = it)\n                        )\n                    )\n                },\n                onHeightChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(height = it)\n                        )\n                    )\n                }\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.use_size_of_first_frame),\n            subtitle = stringResource(id = R.string.use_size_of_first_frame_sub),\n            checked = value.size == null,\n            onClick = {\n                onValueChange(\n                    value.copy(size = if (it) null else IntegerSize(1000, 1000))\n                )\n            },\n            startIcon = Icons.Outlined.PhotoSizeSelectLarge,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.dont_stack_frames),\n            subtitle = stringResource(id = R.string.dont_stack_frames_sub),\n            checked = value.dontStack,\n            onClick = {\n                onValueChange(\n                    value.copy(dontStack = it)\n                )\n            },\n            startIcon = Icons.Outlined.Stacks,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        QualitySelector(\n            imageFormat = ImageFormat.Jpeg,\n            quality = value.quality,\n            onQualityChange = {\n                onValueChange(\n                    value.copy(\n                        quality = it\n                    )\n                )\n            }\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.repeatCount,\n            icon = Icons.Outlined.RepeatOne,\n            title = stringResource(id = R.string.repeat_count),\n            valueRange = 0f..10f,\n            steps = 10,\n            valuesPreviewMapping = remember {\n                persistentMapOf(\n                    0f to \"∞\"\n                )\n            },\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        repeatCount = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.fps,\n            icon = Icons.Outlined.FilterFrames,\n            title = stringResource(id = R.string.fps),\n            valueRange = 1f..120f,\n            steps = 119,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        fps = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.crossfade),\n            subtitle = stringResource(id = R.string.crossfade_sub),\n            checked = value.crossfadeCount > 1,\n            onClick = {\n                onValueChange(\n                    value.copy(\n                        crossfadeCount = if (it) 2 else 0\n                    )\n                )\n            },\n            startIcon = Icons.Outlined.Opacity,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n        AnimatedVisibility(value.crossfadeCount > 1) {\n            EnhancedSliderItem(\n                value = value.crossfadeCount,\n                icon = Icons.Outlined.Counter,\n                title = stringResource(id = R.string.crossfade_count),\n                valueRange = 2f..20f,\n                steps = 18,\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = {\n                    onValueChange(\n                        value.copy(\n                            crossfadeCount = it.roundToInt()\n                        )\n                    )\n                },\n                shape = ShapeDefaults.extraLarge,\n                modifier = Modifier.padding(top = 8.dp)\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/presentation/components/GifToolsControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageReorderCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent\n\n@Composable\ninternal fun GifToolsControls(component: GifToolsComponent) {\n    when (val type = component.type) {\n        is Screen.GifTools.Type.GifToImage -> {\n            Spacer(modifier = Modifier.height(16.dp))\n            ImageFormatSelector(\n                value = component.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = component.params.quality\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            QualitySelector(\n                imageFormat = component.imageFormat,\n                quality = component.params.quality,\n                onQualityChange = component::setQuality\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n        }\n\n        is Screen.GifTools.Type.ImageToGif -> {\n            val addImagesToGifPicker =\n                rememberImagePicker(onSuccess = component::addImageToUris)\n            Spacer(modifier = Modifier.height(16.dp))\n            ImageReorderCarousel(\n                images = type.imageUris,\n                onReorder = component::reorderImageUris,\n                onNeedToAddImage = addImagesToGifPicker::pickImage,\n                onNeedToRemoveImageAt = component::removeImageAt,\n                onNavigate = component.onNavigate\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            GifParamsSelector(\n                value = component.params,\n                onValueChange = component::updateParams\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n        }\n\n        is Screen.GifTools.Type.GifToJxl -> {\n            QualitySelector(\n                imageFormat = ImageFormat.Jxl.Lossy,\n                quality = component.jxlQuality,\n                onQualityChange = component::setJxlQuality\n            )\n        }\n\n        is Screen.GifTools.Type.GifToWebp -> {\n            QualitySelector(\n                imageFormat = ImageFormat.Jpg,\n                quality = component.webpQuality,\n                onQualityChange = component::setWebpQuality\n            )\n        }\n\n        null -> Unit\n    }\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/presentation/components/GifToolsImagePreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagesPreviewWithSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.image.urisPreview\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent\n\n@Composable\ninternal fun GifToolsImagePreview(\n    component: GifToolsComponent,\n    onAddGifsToJxl: () -> Unit,\n    onAddGifsToWebp: () -> Unit,\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    AnimatedContent(\n        targetState = component.isLoading to component.type\n    ) { (loading, type) ->\n        Box(\n            contentAlignment = Alignment.Center,\n            modifier = if (loading) {\n                Modifier.padding(32.dp)\n            } else Modifier\n        ) {\n            if (loading || type == null) {\n                EnhancedLoadingIndicator()\n            } else {\n                when (type) {\n                    is Screen.GifTools.Type.GifToImage -> {\n                        ImagesPreviewWithSelection(\n                            imageUris = component.convertedImageUris,\n                            imageFrames = component.gifFrames,\n                            onFrameSelectionChange = component::updateGifFrames,\n                            isPortrait = isPortrait,\n                            isLoadingImages = component.isLoadingGifImages\n                        )\n                    }\n\n                    is Screen.GifTools.Type.GifToJxl -> {\n                        UrisPreview(\n                            modifier = Modifier.urisPreview(),\n                            uris = type.gifUris ?: emptyList(),\n                            isPortrait = true,\n                            onRemoveUri = {\n                                component.setType(\n                                    Screen.GifTools.Type.GifToJxl(type.gifUris?.minus(it))\n                                )\n                            },\n                            onAddUris = onAddGifsToJxl\n                        )\n                    }\n\n                    is Screen.GifTools.Type.GifToWebp -> {\n                        UrisPreview(\n                            modifier = Modifier.urisPreview(),\n                            uris = type.gifUris ?: emptyList(),\n                            isPortrait = true,\n                            onRemoveUri = {\n                                component.setType(\n                                    Screen.GifTools.Type.GifToWebp(type.gifUris?.minus(it))\n                                )\n                            },\n                            onAddUris = onAddGifsToWebp\n                        )\n                    }\n\n                    is Screen.GifTools.Type.ImageToGif -> Unit\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/presentation/components/GifToolsNoDataControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\ninternal fun GifToolsNoDataControls(\n    onClickType: (Screen.GifTools.Type) -> Unit\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    val types = remember {\n        Screen.GifTools.Type.entries\n    }\n    val preference1 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[0].title),\n            subtitle = stringResource(types[0].subtitle),\n            startIcon = types[0].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onClickType(types[0])\n            }\n        )\n    }\n    val preference2 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[1].title),\n            subtitle = stringResource(types[1].subtitle),\n            startIcon = types[1].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onClickType(types[1])\n            }\n        )\n    }\n    val preference3 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[2].title),\n            subtitle = stringResource(types[2].subtitle),\n            startIcon = types[2].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onClickType(types[2])\n            }\n        )\n    }\n    val preference4 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[3].title),\n            subtitle = stringResource(types[3].subtitle),\n            startIcon = types[3].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onClickType(types[3])\n            }\n        )\n    }\n    if (isPortrait) {\n        Column {\n            preference1()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference2()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference3()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference4()\n        }\n    } else {\n        val direction = LocalLayoutDirection.current\n        val cutout = WindowInsets.displayCutout.asPaddingValues().let {\n            PaddingValues(\n                start = it.calculateStartPadding(direction),\n                end = it.calculateEndPadding(direction)\n            )\n        }\n\n        Column {\n            Row(\n                modifier = Modifier.padding(cutout)\n            ) {\n                preference1.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference2.withModifier(modifier = Modifier.weight(1f))\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            Row(\n                modifier = Modifier.padding(cutout)\n            ) {\n                preference3.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference4.withModifier(modifier = Modifier.weight(1f))\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/presentation/components/GifToolsTopAppBarActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent\n\n@Composable\ninternal fun RowScope.GifToolsTopAppBarActions(component: GifToolsComponent) {\n    if (component.type == null) TopAppBarEmoji()\n    val pagesSize by remember(component.gifFrames, component.convertedImageUris) {\n        derivedStateOf {\n            component.gifFrames.getFramePositions(component.convertedImageUris.size).size\n        }\n    }\n    val isGifToImage = component.type is Screen.GifTools.Type.GifToImage\n    AnimatedVisibility(\n        visible = isGifToImage && pagesSize != component.convertedImageUris.size,\n        enter = fadeIn() + scaleIn() + expandHorizontally(),\n        exit = fadeOut() + scaleOut() + shrinkHorizontally()\n    ) {\n        EnhancedIconButton(\n            onClick = component::selectAllConvertedImages\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.SelectAll,\n                contentDescription = \"Select All\"\n            )\n        }\n    }\n    AnimatedVisibility(\n        modifier = Modifier\n            .padding(8.dp)\n            .container(\n                shape = ShapeDefaults.circle,\n                color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                resultPadding = 0.dp\n            ),\n        visible = isGifToImage && pagesSize != 0\n    ) {\n        Row(\n            modifier = Modifier.padding(start = 12.dp),\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.Center\n        ) {\n            pagesSize.takeIf { it != 0 }?.let {\n                Spacer(Modifier.width(8.dp))\n                Text(\n                    text = it.toString(),\n                    fontSize = 20.sp,\n                    fontWeight = FontWeight.Medium\n                )\n            }\n            EnhancedIconButton(\n                onClick = component::clearConvertedImagesSelection\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Close,\n                    contentDescription = stringResource(R.string.close)\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/gif-tools/src/main/java/com/t8rin/imagetoolbox/feature/gif_tools/presentation/screenLogic/GifToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FileSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.gif_tools.domain.GifConverter\nimport com.t8rin.imagetoolbox.feature.gif_tools.domain.GifParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.onCompletion\n\nclass GifToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialType: Screen.GifTools.Type?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val filenameCreator: FilenameCreator,\n    private val gifConverter: GifConverter,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialType?.let(::setType)\n        }\n    }\n\n    private val _type: MutableState<Screen.GifTools.Type?> = mutableStateOf(null)\n    val type by _type\n\n    private val _isLoading: MutableState<Boolean> = mutableStateOf(false)\n    val isLoading by _isLoading\n\n    private val _isLoadingGifImages: MutableState<Boolean> = mutableStateOf(false)\n    val isLoadingGifImages by _isLoadingGifImages\n\n    private val _params: MutableState<GifParams> = mutableStateOf(GifParams.Default)\n    val params by _params\n\n    private val _convertedImageUris: MutableState<List<String>> = mutableStateOf(emptyList())\n    val convertedImageUris by _convertedImageUris\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    private val _imageFrames: MutableState<ImageFrames> = mutableStateOf(ImageFrames.All)\n    val gifFrames by _imageFrames\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _jxlQuality: MutableState<Quality.Jxl> = mutableStateOf(Quality.Jxl())\n    val jxlQuality by _jxlQuality\n\n    private val _webpQuality: MutableState<Quality.Base> = mutableStateOf(Quality.Base())\n    val webpQuality by _webpQuality\n\n    private var gifData: ByteArray? = null\n\n    fun setType(type: Screen.GifTools.Type) {\n        when (type) {\n            is Screen.GifTools.Type.GifToImage -> {\n                type.gifUri?.let { setGifUri(it) } ?: _type.update { null }\n            }\n\n            is Screen.GifTools.Type.ImageToGif -> {\n                _type.update { type }\n            }\n\n            is Screen.GifTools.Type.GifToJxl -> {\n                _type.update { type }\n            }\n\n            is Screen.GifTools.Type.GifToWebp -> {\n                _type.update { type }\n            }\n        }\n    }\n\n    fun setImageUris(uris: List<Uri>) {\n        resetState()\n        _type.update {\n            Screen.GifTools.Type.ImageToGif(uris)\n        }\n    }\n\n    private var collectionJob: Job? by smartJob {\n        _isLoading.update { false }\n    }\n\n    fun setGifUri(uri: Uri) {\n        resetState()\n        _type.update {\n            Screen.GifTools.Type.GifToImage(uri)\n        }\n        updateGifFrames(ImageFrames.All)\n\n        collectionJob = componentScope.launch {\n            _isLoading.update { true }\n            _isLoadingGifImages.update { true }\n            gifConverter.extractFramesFromGif(\n                gifUri = uri.toString(),\n                imageFormat = imageFormat,\n                imageFrames = ImageFrames.All,\n                quality = params.quality\n            ).onCompletion {\n                _isLoading.update { false }\n                _isLoadingGifImages.update { false }\n            }.collect { nextUri ->\n                if (isLoading) {\n                    _isLoading.update { false }\n                }\n                _convertedImageUris.update { it + nextUri }\n            }\n        }\n    }\n\n    override fun resetState() {\n        collectionJob?.cancel()\n        collectionJob = null\n        _type.update { null }\n        _convertedImageUris.update { emptyList() }\n        gifData = null\n        savingJob?.cancel()\n        savingJob = null\n        updateParams(GifParams.Default)\n        registerChangesCleared()\n    }\n\n    fun updateGifFrames(imageFrames: ImageFrames) {\n        _imageFrames.update { imageFrames }\n        registerChanges()\n    }\n\n    fun clearConvertedImagesSelection() = updateGifFrames(ImageFrames.ManualSelection(emptyList()))\n\n    fun selectAllConvertedImages() = updateGifFrames(ImageFrames.All)\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveGifTo(uri: Uri) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            gifData?.let { byteArray ->\n                fileController.writeBytes(\n                    uri = uri.toString(),\n                    block = { it.writeBytes(byteArray) }\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n            _isSaving.value = false\n            gifData = null\n        }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?,\n        onGifSaveResult: (filename: String) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.GifTools.Type.GifToImage -> {\n                    val results = mutableListOf<SaveResult>()\n                    type.gifUri?.toString()?.also { gifUri ->\n                        gifConverter.extractFramesFromGif(\n                            gifUri = gifUri,\n                            imageFormat = imageFormat,\n                            imageFrames = gifFrames,\n                            quality = params.quality,\n                            onGetFramesCount = {\n                                if (it == 0) {\n                                    _isSaving.value = false\n                                    savingJob?.cancel()\n                                    parseSaveResults(\n                                        listOf(SaveResult.Error.MissingPermissions)\n                                    )\n                                }\n                                _left.value = gifFrames.getFramePositions(it).size\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            }\n                        ).onCompletion {\n                            parseSaveResults(results.onSuccess(::registerSave))\n                        }.collect { uri ->\n                            imageGetter.getImage(\n                                data = uri,\n                                originalSize = true\n                            )?.let { localBitmap ->\n                                val imageInfo = ImageInfo(\n                                    imageFormat = imageFormat,\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                )\n                                results.add(\n                                    fileController.save(\n                                        saveTarget = ImageSaveTarget(\n                                            imageInfo = imageInfo,\n                                            originalUri = uri,\n                                            sequenceNumber = _done.value + 1,\n                                            data = imageCompressor.compressAndTransform(\n                                                image = localBitmap,\n                                                imageInfo = ImageInfo(\n                                                    imageFormat = imageFormat,\n                                                    quality = params.quality,\n                                                    width = localBitmap.width,\n                                                    height = localBitmap.height\n                                                )\n                                            )\n                                        ),\n                                        keepOriginalMetadata = false,\n                                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                                    )\n                                )\n                            } ?: results.add(\n                                SaveResult.Error.Exception(Throwable())\n                            )\n                            _done.value++\n                            updateProgress(\n                                done = done,\n                                total = left\n                            )\n                        }\n                    }\n                }\n\n                is Screen.GifTools.Type.ImageToGif -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    gifData = type.imageUris?.map { it.toString() }?.let { list ->\n                        gifConverter.createGifFromImageUris(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            },\n                            onFailure = {\n                                parseSaveResults(listOf(SaveResult.Error.Exception(it)))\n                            }\n                        )?.also {\n                            onGifSaveResult(\"GIF_${timestamp()}.gif\")\n                        }\n                    }\n                }\n\n                is Screen.GifTools.Type.GifToJxl -> {\n                    val results = mutableListOf<SaveResult>()\n                    val gifUris = type.gifUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = gifUris.size\n                    gifConverter.convertGifToJxl(\n                        gifUris = gifUris,\n                        quality = jxlQuality\n                    ) { uri, jxlBytes ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = JxlSaveTarget(uri, jxlBytes),\n                                keepOriginalMetadata = true,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    parseSaveResults(results.onSuccess(::registerSave))\n                }\n\n                is Screen.GifTools.Type.GifToWebp -> {\n                    val results = mutableListOf<SaveResult>()\n                    val gifUris = type.gifUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = gifUris.size\n                    gifConverter.convertGifToWebp(\n                        gifUris = gifUris,\n                        quality = webpQuality\n                    ) { uri, webpBytes ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = WebpSaveTarget(uri, webpBytes),\n                                keepOriginalMetadata = true,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    parseSaveResults(results.onSuccess(::registerSave))\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    private fun JxlSaveTarget(\n        uri: String,\n        jxlBytes: ByteArray\n    ): SaveTarget = FileSaveTarget(\n        originalUri = uri,\n        filename = jxlFilename(uri),\n        data = jxlBytes,\n        imageFormat = ImageFormat.Jxl.Lossless\n    )\n\n    private fun WebpSaveTarget(\n        uri: String,\n        webpBytes: ByteArray\n    ): SaveTarget = FileSaveTarget(\n        originalUri = uri,\n        filename = webpFilename(uri),\n        data = webpBytes,\n        imageFormat = ImageFormat.Webp.Lossless\n    )\n\n    private fun webpFilename(\n        uri: String\n    ): String = filenameCreator.constructImageFilename(\n        ImageSaveTarget(\n            imageInfo = ImageInfo(\n                imageFormat = ImageFormat.Webp.Lossless,\n                originalUri = uri\n            ),\n            originalUri = uri,\n            sequenceNumber = done + 1,\n            metadata = null,\n            data = ByteArray(0)\n        ),\n        forceNotAddSizeInFilename = true\n    )\n\n    private fun jxlFilename(\n        uri: String\n    ): String = filenameCreator.constructImageFilename(\n        ImageSaveTarget(\n            imageInfo = ImageInfo(\n                imageFormat = ImageFormat.Jxl.Lossless,\n                originalUri = uri\n            ),\n            originalUri = uri,\n            sequenceNumber = done + 1,\n            metadata = null,\n            data = ByteArray(0)\n        ),\n        forceNotAddSizeInFilename = true\n    )\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun reorderImageUris(uris: List<Uri>?) {\n        if (type is Screen.GifTools.Type.ImageToGif) {\n            _type.update {\n                Screen.GifTools.Type.ImageToGif(uris)\n            }\n            registerChanges()\n        }\n    }\n\n    fun addImageToUris(uris: List<Uri>) {\n        val type = _type.value\n        if (type is Screen.GifTools.Type.ImageToGif) {\n            _type.update {\n                val newUris = type.imageUris?.plus(uris)?.toSet()?.toList()\n\n                Screen.GifTools.Type.ImageToGif(newUris)\n            }\n            registerChanges()\n        }\n    }\n\n    fun removeImageAt(index: Int) {\n        val type = _type.value\n        if (type is Screen.GifTools.Type.ImageToGif) {\n            _type.update {\n                val newUris = type.imageUris?.toMutableList()?.apply {\n                    removeAt(index)\n                }\n\n                Screen.GifTools.Type.ImageToGif(newUris)\n            }\n            registerChanges()\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        registerChanges()\n    }\n\n    fun setQuality(quality: Quality) {\n        updateParams(params.copy(quality = quality))\n    }\n\n    fun updateParams(params: GifParams) {\n        _params.update { params }\n        registerChanges()\n    }\n\n    fun performSharing() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.GifTools.Type.GifToImage -> {\n                    _left.value = -1\n                    val positions =\n                        gifFrames.getFramePositions(convertedImageUris.size).map { it - 1 }\n                    val uris = convertedImageUris.filterIndexed { index, _ ->\n                        index in positions\n                    }\n                    shareProvider.shareUris(uris)\n                    AppToastHost.showConfetti()\n                }\n\n                is Screen.GifTools.Type.ImageToGif -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    type.imageUris?.map { it.toString() }?.let { list ->\n                        gifConverter.createGifFromImageUris(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            },\n                            onFailure = { }\n                        )?.also { byteArray ->\n                            shareProvider.shareByteArray(\n                                byteArray = byteArray,\n                                filename = \"GIF_${timestamp()}.gif\",\n                                onComplete = AppToastHost::showConfetti\n                            )\n                        }\n                    }\n                }\n\n                is Screen.GifTools.Type.GifToJxl -> {\n                    val results = mutableListOf<String?>()\n                    val gifUris = type.gifUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = gifUris.size\n                    gifConverter.convertGifToJxl(\n                        gifUris = gifUris,\n                        quality = jxlQuality\n                    ) { uri, jxlBytes ->\n                        results.add(\n                            shareProvider.cacheByteArray(\n                                byteArray = jxlBytes,\n                                filename = jxlFilename(uri)\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    shareProvider.shareUris(results.filterNotNull())\n                }\n\n                is Screen.GifTools.Type.GifToWebp -> {\n                    val results = mutableListOf<String?>()\n                    val gifUris = type.gifUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = gifUris.size\n                    gifConverter.convertGifToWebp(\n                        gifUris = gifUris,\n                        quality = webpQuality\n                    ) { uri, webpBytes ->\n                        results.add(\n                            shareProvider.cacheByteArray(\n                                byteArray = webpBytes,\n                                filename = webpFilename(uri)\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    shareProvider.shareUris(results.filterNotNull())\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun setJxlQuality(quality: Quality) {\n        _jxlQuality.update {\n            (quality as? Quality.Jxl) ?: Quality.Jxl()\n        }\n        registerChanges()\n    }\n\n    fun setWebpQuality(quality: Quality) {\n        _webpQuality.update {\n            (quality as? Quality.Base) ?: Quality.Base()\n        }\n        registerChanges()\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialType: Screen.GifTools.Type?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): GifToolsComponent\n    }\n\n}"
  },
  {
    "path": "feature/gradient-maker/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/gradient-maker/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.gradient_maker\"\n\ndependencies {\n    implementation(projects.feature.compare)\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/data/AndroidGradientMaker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.data\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathMeasure\nimport androidx.compose.ui.graphics.ShaderBrush\nimport androidx.compose.ui.graphics.TileMode\nimport androidx.compose.ui.graphics.VertexMode\nimport androidx.compose.ui.graphics.Vertices\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.drawscope.CanvasDrawScope\nimport androidx.compose.ui.graphics.drawscope.scale\nimport androidx.compose.ui.graphics.lerp\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientMaker\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientState\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.MeshGradientState\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidGradientMaker @Inject constructor(\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder,\n    GradientMaker<Bitmap, ShaderBrush, Size, Color, TileMode, Offset> {\n\n    override suspend fun createGradient(\n        integerSize: IntegerSize,\n        gradientState: GradientState<ShaderBrush, Size, Color, TileMode, Offset>\n    ): Bitmap? = createGradient(\n        src = integerSize.toSize().run {\n            createBitmap(\n                width = width.toInt(),\n                height = height.toInt()\n            )\n        },\n        gradientState = gradientState,\n        gradientAlpha = 1f\n    )\n\n    override suspend fun createGradient(\n        src: Bitmap,\n        gradientState: GradientState<ShaderBrush, Size, Color, TileMode, Offset>,\n        gradientAlpha: Float\n    ): Bitmap? = withContext(defaultDispatcher) {\n        val size = IntegerSize(\n            src.width,\n            src.height\n        ).toSize()\n        gradientState.getBrush(size)?.let { brush ->\n            src.copy(src.safeConfig, true).apply {\n                setHasAlpha(true)\n\n                Canvas(asImageBitmap()).apply {\n                    drawImage(asImageBitmap(), Offset.Zero, Paint())\n                    drawRect(\n                        paint = Paint().apply {\n                            shader = brush.createShader(size)\n                            alpha = gradientAlpha\n                        },\n                        rect = Rect(offset = Offset.Zero, size = size)\n                    )\n                }\n            }\n        }\n    }\n\n    override suspend fun createMeshGradient(\n        integerSize: IntegerSize,\n        gradientState: MeshGradientState<Color, Offset>\n    ): Bitmap? = createMeshGradient(\n        src = integerSize.toSize().run {\n            createBitmap(\n                width = width.toInt(),\n                height = height.toInt()\n            )\n        },\n        gradientState = gradientState,\n        gradientAlpha = 1f\n    )\n\n    override suspend fun createMeshGradient(\n        src: Bitmap,\n        gradientState: MeshGradientState<Color, Offset>,\n        gradientAlpha: Float\n    ): Bitmap? = withContext(defaultDispatcher) {\n        src.copy(src.safeConfig, true).apply {\n            setHasAlpha(true)\n\n            val paint = Paint().apply {\n                alpha = gradientAlpha\n            }\n\n            Canvas(asImageBitmap()).apply {\n                drawImage(asImageBitmap(), Offset.Zero, Paint())\n                drawMeshGradient(\n                    pointData = PointData(\n                        points = gradientState.points,\n                        stepsX = gradientState.resolutionX,\n                        stepsY = gradientState.resolutionY\n                    ),\n                    size = Size(width.toFloat(), height.toFloat()),\n                    paint = paint\n                )\n            }\n        }\n    }\n\n    private fun IntegerSize.toSize(): Size = Size(\n        width.coerceAtLeast(1).toFloat(),\n        height.coerceAtLeast(1).toFloat(),\n    )\n\n\n    private fun Canvas.drawMeshGradient(\n        pointData: PointData,\n        indicesModifier: (List<Int>) -> List<Int> = { it },\n        size: Size,\n        paint: Paint\n    ) {\n        CanvasDrawScope().apply {\n            drawContext.canvas = this@drawMeshGradient\n            drawContext.size = size\n\n            with(drawContext.canvas) {\n                scale(\n                    scaleX = size.width,\n                    scaleY = size.height,\n                    pivot = Offset.Zero\n                ) {\n                    drawVertices(\n                        vertices = Vertices(\n                            vertexMode = VertexMode.Triangles,\n                            positions = pointData.offsets,\n                            textureCoordinates = pointData.offsets,\n                            colors = pointData.colors,\n                            indices = indicesModifier(pointData.indices)\n                        ),\n                        blendMode = BlendMode.Dst,\n                        paint = paint,\n                    )\n                }\n            }\n        }\n    }\n\n}\n\ninternal class PointData(\n    private val points: List<List<Pair<Offset, Color>>>,\n    private val stepsX: Int,\n    private val stepsY: Int\n) {\n    val offsets: MutableList<Offset>\n    val colors: MutableList<Color>\n    val indices: List<Int>\n    private val xLength: Int = (points[0].size * stepsX) - (stepsX - 1)\n    private val yLength: Int = (points.size * stepsY) - (stepsY - 1)\n    private val measure = PathMeasure()\n\n    private val indicesBlocks: List<IndicesBlock>\n\n    init {\n        offsets = buildList {\n            repeat((xLength - 0) * (yLength - 0)) {\n                add(Offset(0f, 0f))\n            }\n        }.toMutableList()\n\n        colors = buildList {\n            repeat((xLength - 0) * (yLength - 0)) {\n                add(Color.Transparent)\n            }\n        }.toMutableList()\n\n        indicesBlocks =\n            buildList {\n                for (y in 0..yLength - 2) {\n                    for (x in 0..xLength - 2) {\n\n                        val a = (y * xLength) + x\n                        val b = a + 1\n                        val c = ((y + 1) * xLength) + x\n                        val d = c + 1\n\n                        add(\n                            IndicesBlock(\n                                indices = buildList {\n                                    add(a)\n                                    add(c)\n                                    add(d)\n\n                                    add(a)\n                                    add(b)\n                                    add(d)\n                                },\n                                x = x, y = y\n                            )\n                        )\n\n                    }\n                }\n            }\n\n        indices = indicesBlocks.flatMap { it.indices }\n        generateInterpolatedOffsets()\n    }\n\n    private fun generateInterpolatedOffsets() {\n        for (y in 0..points.lastIndex) {\n            for (x in 0..points[y].lastIndex) {\n                this[x * stepsX, y * stepsY] = points[y][x].first\n                this[x * stepsX, y * stepsY] = points[y][x].second\n\n                if (x != points[y].lastIndex) {\n                    val path = cubicPathX(\n                        point1 = points[y][x].first,\n                        point2 = points[y][x + 1].first,\n                        when (x) {\n                            0 -> 0\n                            points[y].lastIndex - 1 -> 2\n                            else -> 1\n                        }\n                    )\n                    measure.setPath(path, false)\n\n                    for (i in 1..<stepsX) {\n                        measure.getPosition(i / stepsX.toFloat() * measure.length).let {\n                            this[(x * stepsX) + i, (y * stepsY)] = Offset(it.x, it.y)\n                            this[(x * stepsX) + i, (y * stepsY)] =\n                                lerp(\n                                    points[y][x].second,\n                                    points[y][x + 1].second,\n                                    i / stepsX.toFloat(),\n                                )\n                        }\n                    }\n                }\n            }\n        }\n\n        for (y in 0..<points.lastIndex) {\n            for (x in 0..<this.xLength) {\n                val path = cubicPathY(\n                    point1 = this[x, y * stepsY].let { Offset(it.x, it.y) },\n                    point2 = this[x, (y + 1) * stepsY].let { Offset(it.x, it.y) },\n                    when (y) {\n                        0 -> 0\n                        points[y].lastIndex - 1 -> 2\n                        else -> 1\n                    }\n                )\n                measure.setPath(path, false)\n                for (i in (1..<stepsY)) {\n                    val point3 = measure.getPosition(i / stepsY.toFloat() * measure.length).let {\n                        Offset(it.x, it.y)\n                    }\n\n                    this[x, ((y * stepsY) + i)] = point3\n\n                    this[x, ((y * stepsY) + i)] = lerp(\n                        this.getColor(x, y * stepsY),\n                        this.getColor(x, (y + 1) * stepsY),\n                        i / stepsY.toFloat(),\n                    )\n\n                }\n            }\n        }\n    }\n\n    data class IndicesBlock(\n        val indices: List<Int>,\n        val x: Int,\n        val y: Int\n    )\n\n    operator fun get(\n        x: Int,\n        y: Int\n    ): Offset {\n        val index = (y * xLength) + x\n        return offsets[index]\n    }\n\n    private fun getColor(\n        x: Int,\n        y: Int\n    ): Color {\n        val index = (y * xLength) + x\n        return colors[index]\n    }\n\n    private operator fun set(\n        x: Int,\n        y: Int,\n        offset: Offset\n    ) {\n        val index = (y * xLength) + x\n        offsets[index] = Offset(offset.x, offset.y)\n    }\n\n    private operator fun set(\n        x: Int,\n        y: Int,\n        color: Color\n    ) {\n        val index = (y * xLength) + x\n        colors[index] = color\n    }\n}\n\nprivate fun cubicPathX(\n    point1: Offset,\n    point2: Offset,\n    position: Int\n): Path {\n    val path = Path().apply {\n        moveTo(point1.x, point1.y)\n        val delta = (point2.x - point1.x) * .5f\n        when (position) {\n            0 -> cubicTo(\n                point1.x, point1.y,\n                point2.x - delta, point2.y,\n                point2.x, point2.y\n            )\n\n            2 -> cubicTo(\n                point1.x + delta, point1.y,\n                point2.x, point2.y,\n                point2.x, point2.y\n            )\n\n            else -> cubicTo(\n                point1.x + delta, point1.y,\n                point2.x - delta, point2.y,\n                point2.x, point2.y\n            )\n        }\n\n        lineTo(point2.x, point2.y)\n    }\n    return path\n}\n\nprivate fun cubicPathY(\n    point1: Offset,\n    point2: Offset,\n    position: Int\n): Path {\n    val path = Path().apply {\n        moveTo(point1.x, point1.y)\n        val delta = (point2.y - point1.y) * .5f\n        when (position) {\n            0 -> cubicTo(\n                point1.x, point1.y,\n                point2.x, point2.y - delta,\n                point2.x, point2.y\n            )\n\n            2 -> cubicTo(\n                point1.x, point1.y + delta,\n                point2.x, point2.y,\n                point2.x, point2.y\n            )\n\n            else -> cubicTo(\n                point1.x, point1.y + delta,\n                point2.x, point2.y - delta,\n                point2.x, point2.y\n            )\n        }\n\n        lineTo(point2.x, point2.y)\n    }\n    return path\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/di/GradientMakerModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.di\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ShaderBrush\nimport androidx.compose.ui.graphics.TileMode\nimport com.t8rin.imagetoolbox.feature.gradient_maker.data.AndroidGradientMaker\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientMaker\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface GradientMakerModule {\n\n    @Singleton\n    @Binds\n    fun provideGradientMaker(\n        maker: AndroidGradientMaker\n    ): GradientMaker<Bitmap, ShaderBrush, Size, Color, TileMode, Offset>\n\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/domain/GradientMaker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ninterface GradientMaker<Image, Brush, Size, Color, TileMode, Offset> {\n\n    suspend fun createGradient(\n        integerSize: IntegerSize,\n        gradientState: GradientState<Brush, Size, Color, TileMode, Offset>\n    ): Image?\n\n    suspend fun createGradient(\n        src: Image,\n        gradientState: GradientState<Brush, Size, Color, TileMode, Offset>,\n        gradientAlpha: Float\n    ): Image?\n\n    suspend fun createMeshGradient(\n        integerSize: IntegerSize,\n        gradientState: MeshGradientState<Color, Offset>,\n    ): Image?\n\n    suspend fun createMeshGradient(\n        src: Image,\n        gradientState: MeshGradientState<Color, Offset>,\n        gradientAlpha: Float\n    ): Image?\n\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/domain/GradientState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.domain\n\ninterface GradientState<Brush, Size, Color, TileMode, Offset> {\n    var size: Size\n\n    val brush: Brush?\n        get() = getBrush(size)\n\n    fun getBrush(size: Size): Brush?\n\n    var gradientType: GradientType\n\n    val colorStops: List<Pair<Float, Color>>\n\n    var tileMode: TileMode\n\n    var linearGradientAngle: Float\n\n    var centerFriction: Offset\n\n    var radiusFriction: Float\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/domain/GradientType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.domain\n\nenum class GradientType {\n    Linear, Radial, Sweep\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/domain/MeshGradientState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.domain\n\ninterface MeshGradientState<Color, Offset> {\n    val points: List<List<Pair<Offset, Color>>>\n    var resolutionX: Int\n    var resolutionY: Int\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/GradientMakerContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShowOriginalButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.GradientMakerAppColorSchemeHandler\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.GradientMakerBottomButtons\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.GradientMakerCompareButton\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.GradientMakerControls\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.GradientMakerImagePreview\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.GradientMakerNoDataControls\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.GradientMakerType\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\n\n@Composable\nfun GradientMakerContent(\n    component: GradientMakerComponent\n) {\n    val screenType = component.screenType\n\n    GradientMakerAppColorSchemeHandler(component)\n\n    LaunchedEffect(screenType) {\n        if (screenType == null) {\n            component.resetState()\n        }\n    }\n    val goBack = {\n        if (screenType != null) {\n            component.resetState()\n        } else {\n            component.onGoBack()\n        }\n    }\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setUris(uris)\n        component.updateGradientAlpha(0.5f)\n    }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = screenType == null,\n        canShowScreenData = screenType != null,\n        title = {\n            TopAppBarTitle(\n                title = when (screenType) {\n                    null, GradientMakerType.Default -> stringResource(R.string.gradient_maker)\n                    GradientMakerType.Overlay -> stringResource(R.string.gradient_maker_type_image)\n                    GradientMakerType.Mesh -> stringResource(R.string.mesh_gradients)\n                    GradientMakerType.MeshOverlay -> stringResource(R.string.gradient_maker_type_image_mesh)\n                },\n                input = Unit,\n                isLoading = false,\n                size = null\n            )\n        },\n        onGoBack = {\n            if (component.haveChanges) showExitDialog = true\n            else goBack()\n        },\n        actions = {\n            if (component.uris.isNotEmpty()) {\n                ShowOriginalButton(\n                    onStateChange = component::setShowOriginal\n                )\n            }\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.brush != null,\n                onShare = component::shareBitmaps,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        topAppBarPersistentActions = {\n            if (screenType == null) {\n                TopAppBarEmoji()\n            }\n\n            GradientMakerCompareButton(component)\n        },\n        imagePreview = {\n            GradientMakerImagePreview(component)\n        },\n        controls = {\n            GradientMakerControls(component)\n        },\n        insetsForNoData = WindowInsets(0),\n        noDataControls = {\n            GradientMakerNoDataControls(component)\n        },\n        buttons = { actions ->\n            GradientMakerBottomButtons(\n                component = component,\n                actions = actions,\n                imagePicker = imagePicker\n            )\n        },\n        forceImagePreviewToMax = component.showOriginal,\n        contentPadding = animateDpAsState(\n            if (screenType == null) 12.dp\n            else 20.dp\n        ).value\n    )\n\n    LoadingDialog(\n        visible = component.isSaving || component.isImageLoading,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving,\n        canCancel = component.isSaving,\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = goBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/ColorStopSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorInfo\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealDirection\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealValue\nimport com.t8rin.imagetoolbox.core.ui.widget.other.SwipeToReveal\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberRevealState\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueText\nimport kotlinx.coroutines.launch\nimport kotlin.math.roundToInt\n\n@Composable\nfun ColorStopSelection(\n    colorStops: List<Pair<Float, Color>>,\n    onRemoveClick: (Int) -> Unit,\n    onValueChange: (Int, Pair<Float, Color>) -> Unit,\n    onAddColorStop: (Pair<Float, Color>) -> Unit\n) {\n    var showColorPicker by rememberSaveable { mutableStateOf(false) }\n\n    ExpandableItem(\n        initialState = true,\n        modifier = Modifier.padding(1.dp),\n        shape = ShapeDefaults.extraLarge,\n        color = MaterialTheme.colorScheme.surfaceContainer,\n        visibleContent = {\n            TitleItem(text = stringResource(R.string.color_stops))\n        },\n        expandableContent = {\n            Column(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                modifier = Modifier.padding(8.dp)\n            ) {\n                colorStops.forEachIndexed { index, (value, color) ->\n                    ColorStopSelectionItem(\n                        value = value,\n                        color = color,\n                        onRemoveClick = {\n                            onRemoveClick(index)\n                        },\n                        onValueChange = {\n                            onValueChange(index, it)\n                        },\n                        canDelete = colorStops.size > 2\n                    )\n                }\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.mixedContainer,\n                    onClick = {\n                        showColorPicker = true\n                    },\n                    modifier = Modifier.padding(\n                        horizontal = 16.dp\n                    )\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.Palette,\n                        contentDescription = null\n                    )\n                    Spacer(Modifier.width(8.dp))\n                    Text(stringResource(id = R.string.add_color))\n                }\n            }\n        }\n    )\n\n    var color by rememberSaveable(stateSaver = ColorSaver) {\n        mutableStateOf(Color.Red)\n    }\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Box {\n                Column(\n                    Modifier\n                        .enhancedVerticalScroll(rememberScrollState())\n                        .padding(start = 36.dp, top = 36.dp, end = 36.dp, bottom = 24.dp)\n                ) {\n                    ColorSelection(\n                        value = color,\n                        onValueChange = { color = it },\n                        withAlpha = true\n                    )\n                }\n            }\n        },\n        visible = showColorPicker,\n        onDismiss = {\n            showColorPicker = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.color),\n                icon = Icons.Rounded.Palette\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    onAddColorStop(1f to color)\n                    showColorPicker = false\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.ok))\n            }\n        }\n    )\n}\n\n@Composable\nprivate fun ColorStopSelectionItem(\n    value: Float,\n    color: Color,\n    onRemoveClick: () -> Unit,\n    onValueChange: (Pair<Float, Color>) -> Unit,\n    canDelete: Boolean\n) {\n    var showColorPicker by rememberSaveable { mutableStateOf(false) }\n\n    val scope = rememberCoroutineScope()\n    val state = rememberRevealState()\n    SwipeToReveal(\n        state = state,\n        enableSwipe = canDelete,\n        revealedContentEnd = {\n            Box(\n                Modifier\n                    .fillMaxSize()\n                    .container(\n                        color = MaterialTheme.colorScheme.errorContainer,\n                        shape = MaterialTheme.shapes.large,\n                        autoShadowElevation = 0.dp,\n                        resultPadding = 0.dp\n                    )\n                    .hapticsClickable {\n                        scope.launch {\n                            state.animateTo(RevealValue.Default)\n                        }\n                        onRemoveClick()\n                    }\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.Delete,\n                    contentDescription = stringResource(R.string.delete),\n                    modifier = Modifier\n                        .padding(16.dp)\n                        .padding(end = 8.dp)\n                        .align(Alignment.CenterEnd),\n                    tint = MaterialTheme.colorScheme.onErrorContainer\n                )\n            }\n        },\n        directions = setOf(RevealDirection.EndToStart),\n        swipeableContent = {\n            Column(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp\n                    )\n                    .then(\n                        if (canDelete) {\n                            Modifier.pointerInput(Unit) {\n                                detectTapGestures(\n                                    onPress = {\n                                        val time = System.currentTimeMillis()\n                                        awaitRelease()\n                                        if (System.currentTimeMillis() - time >= 200) {\n                                            scope.launch {\n                                                state.animateTo(RevealValue.FullyRevealedStart)\n                                            }\n                                        }\n                                    }\n                                )\n                            }\n                        } else Modifier\n                    )\n            ) {\n                ColorInfo(\n                    color = color,\n                    onColorChange = {\n                        onValueChange(value to it)\n                    },\n                    supportButtonIcon = Icons.Rounded.MiniEdit,\n                    onSupportButtonClick = {\n                        showColorPicker = true\n                    }\n                )\n                Spacer(modifier = Modifier.height(8.dp))\n                Row(\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    EnhancedSlider(\n                        value = value,\n                        onValueChange = { onValueChange(it to color) },\n                        valueRange = 0f..1f,\n                        modifier = Modifier.weight(1f)\n                    )\n                    var showValueDialog by rememberSaveable {\n                        mutableStateOf(false)\n                    }\n                    ValueText(\n                        modifier = Modifier,\n                        value = (value * 100).toInt(),\n                        onClick = {\n                            showValueDialog = true\n                        }\n                    )\n                    ValueDialog(\n                        roundTo = 0,\n                        valueRange = 0f..100f,\n                        valueState = (value * 100).toInt().toString(),\n                        expanded = showValueDialog,\n                        onDismiss = {\n                            showValueDialog = false\n                        },\n                        onValueUpdate = {\n                            onValueChange(it.roundToInt() / 100f to color)\n                            showValueDialog = false\n                        }\n                    )\n                }\n            }\n        }\n    )\n\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Box {\n                Column(\n                    Modifier\n                        .enhancedVerticalScroll(rememberScrollState())\n                        .padding(start = 36.dp, top = 36.dp, end = 36.dp, bottom = 24.dp)\n                ) {\n                    ColorSelection(\n                        value = color,\n                        onValueChange = {\n                            onValueChange(value to it)\n                        },\n                        withAlpha = true\n                    )\n                }\n            }\n        },\n        visible = showColorPicker,\n        onDismiss = {\n            showColorPicker = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.color),\n                icon = Icons.Rounded.Palette\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    showColorPicker = false\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientMakerAppColorSchemeHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\n\n@Composable\ninternal fun GradientMakerAppColorSchemeHandler(component: GradientMakerComponent) {\n    AutoContentBasedColors(\n        model = Triple(component.brush, component.meshPoints, component.selectedUri),\n        selector = { (_, uri) ->\n            component.createGradientBitmap(\n                data = uri,\n                integerSize = IntegerSize(1000, 1000)\n            )\n        },\n        allowChangeColor = component.screenType != null\n    )\n\n    val colorScheme = MaterialTheme.colorScheme\n    LaunchedEffect(component.colorStops) {\n        if (component.colorStops.isEmpty()) {\n            colorScheme.apply {\n                component.addColorStop(\n                    pair = 0f to primary.blend(primaryContainer, 0.5f),\n                    isInitial = true\n                )\n                component.addColorStop(\n                    pair = 0.5f to secondary.blend(secondaryContainer, 0.5f),\n                    isInitial = true\n                )\n                component.addColorStop(\n                    pair = 1f to tertiary.blend(tertiaryContainer, 0.5f),\n                    isInitial = true\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientMakerBottomButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.canPickImage\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\n\n@Composable\ninternal fun GradientMakerBottomButtons(\n    component: GradientMakerComponent,\n    actions: @Composable RowScope.() -> Unit,\n    imagePicker: ImagePicker\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        if (component.brush != null) {\n            component.saveBitmaps(\n                oneTimeSaveLocationUri = it\n            )\n        }\n    }\n    var showFolderSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    BottomButtonsBlock(\n        isNoData = component.screenType == null,\n        onSecondaryButtonClick = imagePicker::pickImage,\n        isSecondaryButtonVisible = component.screenType.canPickImage(),\n        isPrimaryButtonVisible = component.brush != null,\n        showNullDataButtonAsContainer = true,\n        onPrimaryButtonClick = {\n            saveBitmap(null)\n        },\n        onPrimaryButtonLongClick = {\n            showFolderSelectionDialog = true\n        },\n        actions = {\n            if (isPortrait) actions()\n        },\n        onSecondaryButtonLongClick = {\n            showOneTimeImagePickingDialog = true\n        }\n    )\n    OneTimeSaveLocationSelectionDialog(\n        visible = showFolderSelectionDialog,\n        onDismiss = { showFolderSelectionDialog = false },\n        onSaveRequest = saveBitmap,\n        formatForFilenameSelection = component.getFormatForFilenameSelection()\n    )\n    OneTimeImagePickingDialog(\n        onDismiss = { showOneTimeImagePickingDialog = false },\n        picker = Picker.Multiple,\n        imagePicker = imagePicker,\n        visible = showOneTimeImagePickingDialog\n    )\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientMakerCompareButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.CompareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareSheet\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.canPickImage\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.isMesh\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\n\n@Composable\ninternal fun GradientMakerCompareButton(component: GradientMakerComponent) {\n    var showCompareSheet by rememberSaveable { mutableStateOf(false) }\n\n    val screenType = component.screenType\n\n    CompareButton(\n        onClick = { showCompareSheet = true },\n        visible = component.brush != null && screenType.canPickImage() && component.selectedUri != Uri.EMPTY\n    )\n\n    CompareSheet(\n        beforeContent = {\n            Picture(\n                model = component.selectedUri,\n                modifier = Modifier.aspectRatio(\n                    component.imageAspectRatio\n                )\n            )\n        },\n        afterContent = {\n            if (screenType.isMesh()) {\n                MeshGradientPreview(\n                    meshGradientState = component.meshGradientState,\n                    gradientAlpha = component.gradientAlpha,\n                    allowPickingImage = screenType.canPickImage(),\n                    gradientSize = component.gradientSize,\n                    selectedUri = component.selectedUri,\n                    imageAspectRatio = component.imageAspectRatio\n                )\n            } else {\n                val gradientState = rememberGradientState()\n                LaunchedEffect(component.brush) {\n                    gradientState.gradientType = component.gradientType\n                    gradientState.linearGradientAngle = component.angle\n                    gradientState.centerFriction = component.centerFriction\n                    gradientState.radiusFriction = component.radiusFriction\n                    gradientState.colorStops.apply {\n                        clear()\n                        addAll(component.colorStops)\n                    }\n                    gradientState.tileMode = component.tileMode\n                }\n                GradientPreview(\n                    brush = gradientState.brush,\n                    gradientAlpha = component.gradientAlpha,\n                    allowPickingImage = screenType.canPickImage(),\n                    gradientSize = component.gradientSize,\n                    onSizeChanged = {\n                        gradientState.size = it\n                    },\n                    selectedUri = component.selectedUri,\n                    imageAspectRatio = component.imageAspectRatio\n                )\n            }\n        },\n        visible = showCompareSheet,\n        onDismiss = {\n            showCompareSheet = false\n        }\n    )\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientMakerControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Build\nimport androidx.compose.material.icons.rounded.DensitySmall\nimport androidx.compose.material.icons.rounded.GridOn\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.lerp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.canPickImage\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.isMesh\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun GradientMakerControls(component: GradientMakerComponent) {\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n\n    val screenType = component.screenType\n\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        ImageCounter(\n            imageCount = component.uris.size.takeIf { it > 1 },\n            onRepick = {\n                showPickImageFromUrisSheet = true\n            }\n        )\n\n        AnimatedContent(\n            screenType != null && !screenType.canPickImage()\n        ) { canChangeSize ->\n            if (canChangeSize) {\n                GradientSizeSelector(\n                    value = component.gradientSize,\n                    onWidthChange = component::updateWidth,\n                    onHeightChange = component::updateHeight\n                )\n            } else {\n                AlphaSelector(\n                    value = component.gradientAlpha,\n                    onValueChange = component::updateGradientAlpha,\n                    modifier = Modifier\n                )\n            }\n        }\n        Spacer(Modifier.height(8.dp))\n\n        if (screenType.isMesh()) {\n            Column(\n                modifier = Modifier.container(\n                    resultPadding = 0.dp\n                )\n            ) {\n                Spacer(Modifier.height(16.dp))\n                TitleItem(\n                    text = stringResource(R.string.points_customization),\n                    icon = Icons.Rounded.Build,\n                    modifier = Modifier.padding(\n                        horizontal = 16.dp\n                    )\n                )\n                MeshGradientEditor(\n                    state = component.meshGradientState,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .aspectRatio(1f)\n                        .padding(16.dp)\n                )\n            }\n            Spacer(Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = component.meshGradientState.gridSize,\n                title = stringResource(R.string.grid_size),\n                icon = Icons.Rounded.GridOn,\n                valueRange = 2f..6f,\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = { value ->\n                    if (value.roundToInt() != component.meshGradientState.gridSize) {\n                        val size = value.roundToInt()\n                        component.setResolution(lerp(1f, 16f, 2f / size))\n                        component.meshGradientState.points.apply {\n                            clear()\n                            addAll(generateMesh(size))\n                        }\n                    }\n                }\n            )\n            Spacer(Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = component.meshResolutionX,\n                title = stringResource(R.string.resolution),\n                icon = Icons.Rounded.DensitySmall,\n                valueRange = 1f..64f,\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = component::setResolution\n            )\n        } else {\n            GradientTypeSelector(\n                value = component.gradientType,\n                onValueChange = component::setGradientType\n            ) {\n                GradientPropertiesSelector(\n                    gradientType = component.gradientType,\n                    linearAngle = component.angle,\n                    onLinearAngleChange = component::updateLinearAngle,\n                    centerFriction = component.centerFriction,\n                    radiusFriction = component.radiusFriction,\n                    onRadialDimensionsChange = component::setRadialProperties\n                )\n            }\n            Spacer(Modifier.height(8.dp))\n            ColorStopSelection(\n                colorStops = component.colorStops,\n                onRemoveClick = component::removeColorStop,\n                onValueChange = component::updateColorStop,\n                onAddColorStop = component::addColorStop\n            )\n            Spacer(Modifier.height(8.dp))\n            TileModeSelector(\n                value = component.tileMode,\n                onValueChange = component::setTileMode\n            )\n        }\n        if (screenType.canPickImage()) {\n            Spacer(Modifier.height(8.dp))\n            SaveExifWidget(\n                checked = component.keepExif,\n                imageFormat = component.imageFormat,\n                onCheckedChange = component::toggleKeepExif\n            )\n        }\n        Spacer(Modifier.height(8.dp))\n        ImageFormatSelector(\n            value = component.imageFormat,\n            forceEnabled = screenType != null && !screenType.canPickImage(),\n            onValueChange = component::setImageFormat\n        )\n    }\n\n    val transformations by remember(\n        component.brush,\n        screenType.isMesh(),\n        component.meshPoints,\n        component.meshResolutionX,\n        component.meshResolutionY,\n        component.gradientAlpha\n    ) {\n        derivedStateOf {\n            listOf(\n                component.getGradientTransformation()\n            )\n        }\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    PickImageFromUrisSheet(\n        transformations = transformations,\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = component::updateSelectedUri,\n        onUriRemoved = component::updateUrisSilently,\n        columns = if (isPortrait) 2 else 4,\n    )\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientMakerImagePreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.canPickImage\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.isMesh\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\n\n@Composable\ninternal fun GradientMakerImagePreview(component: GradientMakerComponent) {\n    val screenType = component.screenType\n\n    Box(\n        modifier = Modifier\n            .detectSwipes(\n                onSwipeRight = component::selectLeftUri,\n                onSwipeLeft = component::selectRightUri\n            )\n            .container()\n            .padding(4.dp),\n        contentAlignment = Alignment.Center\n    ) {\n        if (screenType.isMesh()) {\n            MeshGradientPreview(\n                meshGradientState = component.meshGradientState,\n                gradientAlpha = if (component.showOriginal) 0f else component.gradientAlpha,\n                allowPickingImage = screenType.canPickImage(),\n                gradientSize = component.gradientSize,\n                selectedUri = component.selectedUri,\n                imageAspectRatio = component.imageAspectRatio\n            )\n        } else {\n            GradientPreview(\n                brush = component.brush,\n                gradientAlpha = if (component.showOriginal) 0f else component.gradientAlpha,\n                allowPickingImage = screenType.canPickImage(),\n                gradientSize = component.gradientSize,\n                onSizeChanged = component::setPreviewSize,\n                selectedUri = component.selectedUri,\n                imageAspectRatio = component.imageAspectRatio\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientMakerNoDataControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageOverlay\nimport com.t8rin.imagetoolbox.core.resources.icons.ImagesMode\nimport com.t8rin.imagetoolbox.core.resources.icons.MeshDownload\nimport com.t8rin.imagetoolbox.core.resources.icons.MeshGradient\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.GradientMakerType\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\n\n@Composable\ninternal fun GradientMakerNoDataControls(\n    component: GradientMakerComponent\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    var requestedType by rememberSaveable(component.screenType) {\n        mutableStateOf<GradientMakerType?>(null)\n    }\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setScreenType(requestedType)\n        component.setUris(uris)\n        component.updateGradientAlpha(0.5f)\n    }\n\n    val preference1 = @Composable {\n        val screen = remember {\n            Screen.GradientMaker()\n        }\n        PreferenceItem(\n            title = stringResource(screen.title),\n            subtitle = stringResource(screen.subtitle),\n            startIcon = screen.icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                component.setScreenType(GradientMakerType.Default)\n            }\n        )\n    }\n    val preference2 = @Composable {\n        PreferenceItem(\n            title = stringResource(R.string.gradient_maker_type_image),\n            subtitle = stringResource(R.string.gradient_maker_type_image_sub),\n            startIcon = Icons.Outlined.ImagesMode,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                requestedType = GradientMakerType.Overlay\n                imagePicker.pickImage()\n            }\n        )\n    }\n    val preference3 = @Composable {\n        PreferenceItem(\n            title = stringResource(R.string.mesh_gradients),\n            subtitle = stringResource(R.string.mesh_gradients_sub),\n            startIcon = Icons.Outlined.MeshGradient,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                component.setScreenType(GradientMakerType.Mesh)\n            }\n        )\n    }\n    val preference4 = @Composable {\n        PreferenceItem(\n            title = stringResource(R.string.gradient_maker_type_image_mesh),\n            subtitle = stringResource(R.string.gradient_maker_type_image_mesh_sub),\n            startIcon = Icons.Outlined.ImageOverlay,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                requestedType = GradientMakerType.MeshOverlay\n                imagePicker.pickImage()\n            }\n        )\n    }\n    val preference5 = @Composable {\n        PreferenceItem(\n            title = stringResource(R.string.collection_mesh_gradients),\n            subtitle = stringResource(R.string.collection_mesh_gradients_sub),\n            startIcon = Icons.Outlined.MeshDownload,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                component.onNavigate(Screen.MeshGradients)\n            }\n        )\n    }\n    if (isPortrait) {\n        Column {\n            preference1()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference2()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference3()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference4()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference5()\n        }\n    } else {\n        Column(\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Row(\n                modifier = Modifier.windowInsetsPadding(\n                    WindowInsets.displayCutout.only(WindowInsetsSides.Horizontal)\n                )\n            ) {\n                preference1.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference2.withModifier(modifier = Modifier.weight(1f))\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            Row(\n                modifier = Modifier.windowInsetsPadding(\n                    WindowInsets.displayCutout.only(WindowInsetsSides.Horizontal)\n                )\n            ) {\n                preference3.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference4.withModifier(modifier = Modifier.weight(1f))\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            preference5.withModifier(modifier = Modifier.fillMaxWidth(0.5f))\n        }\n    }\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.ShaderBrush\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.layout.onGloballyPositioned\nimport androidx.compose.ui.zIndex\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\ninternal fun GradientPreview(\n    brush: ShaderBrush?,\n    gradientAlpha: Float,\n    allowPickingImage: Boolean?,\n    gradientSize: IntegerSize,\n    onSizeChanged: (Size) -> Unit,\n    imageAspectRatio: Float,\n    selectedUri: Uri\n) {\n    val alpha by animateFloatAsState(\n        if (brush == null) 1f\n        else gradientAlpha\n    )\n    val solidBrush = SolidColor(MaterialTheme.colorScheme.surfaceContainer)\n    AnimatedContent(\n        targetState = if (allowPickingImage == true) {\n            imageAspectRatio\n        } else {\n            gradientSize\n                .aspectRatio\n                .roundToTwoDigits()\n                .coerceIn(0.01f..100f)\n        }\n    ) { aspectRatio ->\n        Box {\n            Box(\n                modifier = Modifier\n                    .aspectRatio(aspectRatio)\n                    .clip(MaterialTheme.shapes.medium)\n                    .then(\n                        if (allowPickingImage != true) {\n                            Modifier.transparencyChecker()\n                        } else Modifier\n                    )\n                    .drawBehind {\n                        drawRect(\n                            brush = brush ?: solidBrush,\n                            alpha = alpha\n                        )\n                    }\n                    .onGloballyPositioned {\n                        onSizeChanged(\n                            Size(\n                                it.size.width.toFloat(),\n                                it.size.height.toFloat()\n                            )\n                        )\n                    }\n                    .zIndex(2f),\n                contentAlignment = Alignment.Center\n            ) {\n                Spacer(\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .shimmer(visible = brush == null)\n                )\n            }\n            if (allowPickingImage == true) {\n                Picture(\n                    model = selectedUri,\n                    modifier = Modifier.matchParentSize(),\n                    shape = MaterialTheme.shapes.medium\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientPropertiesSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientType\nimport kotlin.math.roundToInt\n\n@Composable\nfun GradientPropertiesSelector(\n    gradientType: GradientType,\n    linearAngle: Float,\n    centerFriction: Offset,\n    radiusFriction: Float,\n    onLinearAngleChange: (Float) -> Unit,\n    onRadialDimensionsChange: (Offset, Float) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    AnimatedContent(\n        targetState = gradientType,\n        modifier = modifier\n    ) { type ->\n        when (type) {\n            GradientType.Linear -> {\n                EnhancedSliderItem(\n                    behaveAsContainer = false,\n                    value = linearAngle,\n                    title = stringResource(id = R.string.angle),\n                    valueRange = 0f..360f,\n                    internalStateTransformation = { it.roundToInt() },\n                    onValueChange = {\n                        onLinearAngleChange(it.roundToInt().toFloat())\n                    }\n                )\n            }\n\n            GradientType.Radial,\n            GradientType.Sweep -> {\n                var centerX by remember { mutableFloatStateOf(centerFriction.x) }\n                var centerY by remember { mutableFloatStateOf(centerFriction.y) }\n                var radius by remember { mutableFloatStateOf(radiusFriction) }\n\n                onRadialDimensionsChange(Offset(centerX, centerY), radius)\n\n                Column {\n                    EnhancedSliderItem(\n                        value = centerX,\n                        title = stringResource(id = R.string.center_x),\n                        internalStateTransformation = {\n                            it.roundToTwoDigits()\n                        },\n                        onValueChange = {\n                            centerX = it\n                        },\n                        valueRange = 0f..1f,\n                        behaveAsContainer = false\n                    )\n                    EnhancedSliderItem(\n                        value = centerY,\n                        title = stringResource(id = R.string.center_y),\n                        internalStateTransformation = {\n                            it.roundToTwoDigits()\n                        },\n                        onValueChange = {\n                            centerY = it\n                        },\n                        valueRange = 0f..1f,\n                        behaveAsContainer = false\n                    )\n                    AnimatedVisibility(\n                        visible = type != GradientType.Sweep\n                    ) {\n                        EnhancedSliderItem(\n                            value = radius,\n                            title = stringResource(id = R.string.radius),\n                            internalStateTransformation = {\n                                it.roundToTwoDigits()\n                            },\n                            onValueChange = {\n                                radius = it\n                            },\n                            valueRange = 0f..1f,\n                            behaveAsContainer = false\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientSizeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.restrict\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextFieldColors\n\n@Composable\nfun GradientSizeSelector(\n    value: IntegerSize,\n    onWidthChange: (Int) -> Unit,\n    onHeightChange: (Int) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Row(\n        modifier = modifier.container(\n            shape = ShapeDefaults.extraLarge\n        )\n    ) {\n        val (width, height) = value\n        RoundedTextField(\n            value = width.takeIf { it != 0 }?.toString() ?: \"\",\n            onValueChange = {\n                onWidthChange(it.restrict(8192).toIntOrNull() ?: 0)\n            },\n            shape = ShapeDefaults.smallStart,\n            keyboardOptions = KeyboardOptions(\n                keyboardType = KeyboardType.Number\n            ),\n            label = {\n                Text(stringResource(R.string.width, \" \"))\n            },\n            modifier = Modifier\n                .weight(1f)\n                .padding(\n                    start = 8.dp,\n                    top = 8.dp,\n                    bottom = 8.dp,\n                    end = 2.dp\n                ),\n            colors = RoundedTextFieldColors(\n                isError = false,\n                containerColor = MaterialTheme.colorScheme.surfaceContainer\n            )\n        )\n        RoundedTextField(\n            value = height.takeIf { it != 0 }?.toString() ?: \"\",\n            onValueChange = {\n                onHeightChange(it.restrict(8192).toIntOrNull() ?: 0)\n            },\n            keyboardOptions = KeyboardOptions(\n                keyboardType = KeyboardType.Number\n            ),\n            shape = ShapeDefaults.smallEnd,\n            label = {\n                Text(stringResource(R.string.height, \" \"))\n            },\n            modifier = Modifier\n                .weight(1f)\n                .padding(\n                    start = 2.dp,\n                    top = 8.dp,\n                    bottom = 8.dp,\n                    end = 8.dp\n                ),\n            colors = RoundedTextFieldColors(\n                isError = false,\n                containerColor = MaterialTheme.colorScheme.surfaceContainer\n            )\n        )\n    }\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/GradientTypeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Tune\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientType\n\n@Composable\nfun GradientTypeSelector(\n    value: GradientType,\n    onValueChange: (GradientType) -> Unit,\n    modifier: Modifier = Modifier,\n    propertiesContent: @Composable () -> Unit\n) {\n    Column(\n        modifier = modifier\n            .container(\n                shape = ShapeDefaults.extraLarge\n            )\n            .animateContentSizeNoClip(),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        EnhancedButtonGroup(\n            modifier = Modifier.padding(8.dp),\n            enabled = true,\n            items = GradientType.entries.map { it.translatedName },\n            selectedIndex = GradientType.entries.indexOf(value),\n            title = stringResource(id = R.string.gradient_type),\n            onIndexChange = {\n                onValueChange(GradientType.entries[it])\n            }\n        )\n        ExpandableItem(\n            visibleContent = {\n                TitleItem(\n                    text = stringResource(id = R.string.properties),\n                    icon = Icons.Outlined.Tune\n                )\n            },\n            expandableContent = {\n                Column(\n                    modifier = Modifier.padding(horizontal = 8.dp)\n                ) {\n                    propertiesContent()\n                }\n            },\n            modifier = Modifier.padding(end = 8.dp, start = 8.dp, bottom = 8.dp),\n            color = MaterialTheme.colorScheme.surface\n        )\n    }\n}\n\nprivate val GradientType.translatedName: String\n    @Composable\n    get() = when (this) {\n        GradientType.Linear -> stringResource(id = R.string.gradient_type_linear)\n        GradientType.Radial -> stringResource(id = R.string.gradient_type_radial)\n        GradientType.Sweep -> stringResource(id = R.string.gradient_type_sweep)\n    }\n"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/MeshGradientEditor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.gestures.detectDragGestures\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.SaverScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.asComposePaint\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.graphics.nativePaint\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.graphics.vector.rememberVectorPainter\nimport androidx.compose.ui.input.pointer.pointerInput\nimport com.t8rin.imagetoolbox.core.resources.icons.EditAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.inverseByLuma\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorPickerSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.meshGradient\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.OffsetSaver\nimport kotlin.math.pow\nimport kotlin.math.sqrt\n\n@Composable\ninternal fun MeshGradientEditor(\n    state: UiMeshGradientState,\n    modifier: Modifier = Modifier\n) {\n    val selectedPoint = rememberSaveable(\n        stateSaver = PairOffsetColorSaver\n    ) { mutableStateOf(null) }\n\n    val dragOffset = rememberSaveable(\n        stateSaver = OffsetSaver\n    ) { mutableStateOf(null) }\n\n    val showColorPicker = rememberSaveable { mutableStateOf(false) }\n    val isDragging = rememberSaveable { mutableStateOf(false) }\n\n    Box(\n        modifier = modifier\n            .clip(ShapeDefaults.extraSmall)\n            .transparencyChecker()\n            .meshGradient(\n                points = state.points,\n                resolutionX = state.resolutionX,\n                resolutionY = state.resolutionY\n            )\n            .tappable { tapOffset ->\n                val tappedPoint = state.points.flatten()\n                    .firstOrNull { (offset, _) ->\n                        Offset(offset.x * size.width, offset.y * size.height).getDistance(\n                            tapOffset\n                        ) < 60f\n                    }\n\n                showColorPicker.value = tappedPoint == selectedPoint.value\n\n                selectedPoint.value = tappedPoint\n                if (tappedPoint == null) dragOffset.value = null\n            }\n    ) {\n        val painter = rememberVectorPainter(Icons.Rounded.EditAlt)\n\n        Canvas(\n            modifier = Modifier\n                .fillMaxSize()\n                .then(\n                    if (selectedPoint.value != null) {\n                        Modifier.pointerInput(Unit) {\n                            detectDragGestures(\n                                onDragStart = { startOffset ->\n                                    val tappedPoint = state.points.flatten()\n                                        .firstOrNull { (offset, _) ->\n                                            Offset(\n                                                offset.x * size.width,\n                                                offset.y * size.height\n                                            ).getDistance(startOffset) < 60f\n                                        }\n\n                                    if (tappedPoint != null) {\n                                        selectedPoint.value = tappedPoint\n                                        dragOffset.value = tappedPoint.first\n                                        isDragging.value = true\n                                        showColorPicker.value = false\n                                    }\n                                },\n                                onDrag = { _, dragAmount ->\n                                    selectedPoint.value?.let { (oldOffset, color) ->\n                                        val newOffset = Offset(\n                                            ((oldOffset.x * size.width + dragAmount.x) / size.width).coerceIn(\n                                                0f,\n                                                1f\n                                            ),\n                                            ((oldOffset.y * size.height + dragAmount.y) / size.height).coerceIn(\n                                                0f,\n                                                1f\n                                            )\n                                        )\n                                        state.updatePointPosition(oldOffset, newOffset)\n                                        selectedPoint.value = newOffset to color\n                                    }\n                                },\n                                onDragEnd = {\n                                    isDragging.value = false\n                                }\n                            )\n                        }\n                    } else Modifier\n                )\n        ) {\n            state.points.flatten().forEach { (offset, color) ->\n                val scaledOffset = Offset(offset.x * size.width, offset.y * size.height)\n                val isSelected = selectedPoint.value?.first == offset\n                val inverseColor = color.inverseByLuma()\n                drawContext.canvas.apply {\n                    drawCircle(\n                        radius = if (isSelected) 32f else 27f,\n                        center = scaledOffset,\n                        paint = Paint().nativePaint.apply {\n                            setShadowLayer(\n                                if (isSelected) 36f else 31f,\n                                0f,\n                                0f,\n                                Color.Black.copy(alpha = if (isSelected) .8f else .4f)\n                                    .toArgb()\n                            )\n                        }.asComposePaint()\n                    )\n                }\n                if (isSelected) {\n                    drawCircle(\n                        color = inverseColor,\n                        radius = 40f,\n                        center = scaledOffset\n                    )\n                }\n                drawCircle(\n                    color = color,\n                    radius = if (isSelected) 35f else 30f,\n                    center = scaledOffset\n                )\n                if (isSelected) {\n                    translate(\n                        scaledOffset.x - 25f,\n                        scaledOffset.y - 25f\n                    ) {\n                        with(painter) {\n                            draw(\n                                size = Size(width = 50f, height = 50f),\n                                colorFilter = ColorFilter.tint(inverseColor)\n                            )\n                        }\n                    }\n                }\n            }\n        }\n\n        ColorPickerSheet(\n            visible = showColorPicker.value,\n            onDismiss = { showColorPicker.value = false },\n            color = selectedPoint.value?.second,\n            onColorSelected = { newColor ->\n                selectedPoint.value?.let { (offset) ->\n                    state.updatePointColor(offset, newColor)\n                }\n            },\n            allowAlpha = true\n        )\n    }\n}\n\nprivate fun UiMeshGradientState.updatePointPosition(\n    oldOffset: Offset,\n    newOffset: Offset\n) {\n    var found = false\n    points.replaceAll { row ->\n        row.map {\n            if (it.first == oldOffset && !found) {\n                found = true\n\n                newOffset to it.second\n            } else {\n                it\n            }\n        }\n    }\n}\n\nprivate fun UiMeshGradientState.updatePointColor(\n    offset: Offset,\n    newColor: Color\n) {\n    var found = false\n\n    points.replaceAll { row ->\n        row.map {\n            if (it.first == offset && !found) {\n                found = true\n\n                it.first to newColor\n            } else {\n                it\n            }\n        }\n    }\n}\n\nprivate fun Offset.getDistance(other: Offset): Float {\n    return sqrt((x - other.x).pow(2) + (y - other.y).pow(2))\n}\n\nprivate val PairOffsetColorSaver: Saver<Pair<Offset, Color>?, List<Float>> =\n    object : Saver<Pair<Offset, Color>?, List<Float>> {\n        override fun restore(value: List<Float>): Pair<Offset, Color>? {\n            return if (value.size == 5) {\n                val offset = Offset(value[0], value[1])\n                val color = Color(value[2], value[3], value[4])\n                offset to color\n            } else {\n                null\n            }\n        }\n\n        override fun SaverScope.save(value: Pair<Offset, Color>?): List<Float> {\n            return if (value == null) emptyList()\n            else listOf(\n                value.first.x, value.first.y,\n                value.second.red, value.second.green, value.second.blue\n            )\n        }\n    }"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/MeshGradientPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.zIndex\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.meshGradient\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\ninternal fun MeshGradientPreview(\n    meshGradientState: UiMeshGradientState,\n    gradientAlpha: Float,\n    allowPickingImage: Boolean?,\n    gradientSize: IntegerSize,\n    imageAspectRatio: Float,\n    selectedUri: Uri\n) {\n    val alpha by animateFloatAsState(gradientAlpha)\n    AnimatedContent(\n        targetState = if (allowPickingImage == true) {\n            imageAspectRatio\n        } else {\n            gradientSize\n                .aspectRatio\n                .roundToTwoDigits()\n                .coerceIn(0.01f..100f)\n        }\n    ) { aspectRatio ->\n        Box {\n            Spacer(\n                modifier = Modifier\n                    .aspectRatio(aspectRatio)\n                    .clip(MaterialTheme.shapes.medium)\n                    .then(\n                        if (allowPickingImage != true) {\n                            Modifier.transparencyChecker()\n                        } else Modifier\n                    )\n                    .meshGradient(\n                        points = meshGradientState.points,\n                        resolutionX = meshGradientState.resolutionX,\n                        resolutionY = meshGradientState.resolutionY,\n                        alpha = alpha\n                    )\n                    .zIndex(2f)\n            )\n            if (allowPickingImage == true) {\n                Picture(\n                    model = selectedUri,\n                    modifier = Modifier.matchParentSize(),\n                    shape = MaterialTheme.shapes.medium,\n                    size = 1500\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/TileModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.TileMode\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun TileModeSelector(\n    value: TileMode,\n    onValueChange: (TileMode) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    val entries = remember {\n        listOf(\n            TileMode.Clamp,\n            TileMode.Repeated,\n            TileMode.Mirror,\n            TileMode.Decal\n        )\n    }\n    Box(\n        modifier = modifier\n            .container(\n                shape = ShapeDefaults.extraLarge\n            )\n            .animateContentSizeNoClip(),\n        contentAlignment = Alignment.Center\n    ) {\n        EnhancedButtonGroup(\n            modifier = Modifier.padding(8.dp),\n            enabled = true,\n            items = entries.map { it.translatedName },\n            selectedIndex = entries.indexOf(value),\n            title = stringResource(id = R.string.tile_mode),\n            onIndexChange = {\n                onValueChange(entries[it])\n            }\n        )\n    }\n}\n\nprivate val TileMode.translatedName: String\n    @Composable\n    get() = when (this) {\n        TileMode.Repeated -> stringResource(id = R.string.tile_mode_repeated)\n        TileMode.Mirror -> stringResource(id = R.string.tile_mode_mirror)\n        TileMode.Decal -> stringResource(id = R.string.tile_mode_decal)\n        else -> stringResource(id = R.string.tile_mode_clamp)\n    }"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/UiGradientState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.geometry.center\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ShaderBrush\nimport androidx.compose.ui.graphics.TileMode\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.DpSize\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientState\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientType\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.MeshGradientState\nimport kotlin.math.PI\nimport kotlin.math.cos\nimport kotlin.math.min\nimport kotlin.math.pow\nimport kotlin.math.sin\nimport kotlin.math.sqrt\nimport kotlin.random.Random\n\n@Composable\nfun rememberGradientState(\n    size: DpSize = DpSize.Zero\n): UiGradientState {\n\n    val density = LocalDensity.current\n\n    return remember {\n        val sizePx = if (size == DpSize.Zero) {\n            Size.Zero\n        } else {\n            with(density) {\n                Size(\n                    size.width.toPx(),\n                    size.height.toPx()\n                )\n            }\n        }\n        UiGradientState(sizePx)\n    }\n}\n\nclass UiGradientState(\n    size: Size = Size.Zero\n) : GradientState<ShaderBrush, Size, Color, TileMode, Offset> {\n\n    override var size by mutableStateOf(size)\n\n    override val brush: ShaderBrush?\n        get() = getBrush(size)\n\n    override fun getBrush(size: Size): ShaderBrush? {\n        if (colorStops.isEmpty()) return null\n\n        val colorStops = colorStops.sortedBy { it.first }.let { pairs ->\n            if (gradientType != GradientType.Sweep) {\n                pairs.distinctBy { it.first }\n            } else pairs\n        }.let {\n            if (it.size == 1) {\n                listOf(it.first(), it.first())\n            } else it\n        }.toTypedArray()\n\n        val brush = runCatching {\n            when (gradientType) {\n                GradientType.Linear -> {\n                    val angleRad = linearGradientAngle / 180f * PI\n                    val x = cos(angleRad).toFloat()\n                    val y = sin(angleRad).toFloat()\n\n                    val radius = sqrt(size.width.pow(2) + size.height.pow(2)) / 2f\n                    val offset = size.center + Offset(x * radius, y * radius)\n\n                    val exactOffset = Offset(\n                        x = min(offset.x.coerceAtLeast(0f), size.width),\n                        y = size.height - min(offset.y.coerceAtLeast(0f), size.height)\n                    )\n                    Brush.linearGradient(\n                        colorStops = colorStops,\n                        start = Offset(size.width, size.height) - exactOffset,\n                        end = exactOffset,\n                        tileMode = tileMode\n                    )\n                }\n\n                GradientType.Radial -> Brush.radialGradient(\n                    colorStops = colorStops,\n                    center = Offset(\n                        x = size.width * centerFriction.x,\n                        y = size.height * centerFriction.y\n                    ),\n                    radius = ((size.width.coerceAtLeast(size.height)) / 2 * radiusFriction)\n                        .coerceAtLeast(0.01f),\n                    tileMode = tileMode\n                )\n\n                GradientType.Sweep -> Brush.sweepGradient(\n                    colorStops = colorStops,\n                    center = Offset(\n                        x = size.width * centerFriction.x,\n                        y = size.height * centerFriction.y\n                    )\n                )\n            } as ShaderBrush\n        }.getOrNull()\n\n        return brush\n    }\n\n    override var gradientType: GradientType by mutableStateOf(GradientType.Linear)\n\n    override val colorStops = mutableStateListOf<Pair<Float, Color>>()\n\n    override var tileMode by mutableStateOf(TileMode.Clamp)\n\n    override var linearGradientAngle by mutableFloatStateOf(0f)\n\n    override var centerFriction by mutableStateOf(Offset(.5f, .5f))\n    override var radiusFriction by mutableFloatStateOf(.5f)\n}\n\nclass UiMeshGradientState : MeshGradientState<Color, Offset> {\n\n    override val points = mutableStateListOf<List<Pair<Offset, Color>>>().apply {\n        addAll(generateMesh(2))\n    }\n\n    val gridSize: Int\n        get() = points.firstOrNull()?.size ?: 0\n\n    override var resolutionX: Int by mutableIntStateOf(16)\n\n    override var resolutionY: Int by mutableIntStateOf(16)\n\n}\n\nfun generateMesh(size: Int): List<List<Pair<Offset, Color>>> {\n    return List(size) { y ->\n        List(size) { x ->\n            Offset(x / (size - 1f), y / (size - 1f)) to Color.random()\n        }\n    }\n}\n\nprivate fun Color.Companion.random(): Color = Color(Random.nextInt()).copy(1f)"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/components/model/GradientMakerType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model\n\nenum class GradientMakerType {\n    Default,\n    Overlay,\n    Mesh,\n    MeshOverlay\n}\n\nfun GradientMakerType?.isMesh() =\n    this == GradientMakerType.Mesh || this == GradientMakerType.MeshOverlay\n\nfun GradientMakerType?.canPickImage() =\n    this == GradientMakerType.Overlay || this == GradientMakerType.MeshOverlay"
  },
  {
    "path": "feature/gradient-maker/src/main/java/com/t8rin/imagetoolbox/feature/gradient_maker/presentation/screenLogic/GradientMakerComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ShaderBrush\nimport androidx.compose.ui.graphics.TileMode\nimport androidx.core.net.toUri\nimport coil3.transform.Transformation\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.data.utils.toCoil\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.transformation.GenericTransformation\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientMaker\nimport com.t8rin.imagetoolbox.feature.gradient_maker.domain.GradientType\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.UiGradientState\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.UiMeshGradientState\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.GradientMakerType\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.components.model.isMesh\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlin.math.roundToInt\n\nclass GradientMakerComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val gradientMaker: GradientMaker<Bitmap, ShaderBrush, Size, Color, TileMode, Offset>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n            resetState()\n        }\n    }\n\n    private val _screenType: MutableState<GradientMakerType?> = mutableStateOf(null)\n    val screenType by _screenType\n\n    private val _showOriginal: MutableState<Boolean> = mutableStateOf(false)\n    val showOriginal by _showOriginal\n\n    private var _gradientState = UiGradientState()\n    private val gradientState: UiGradientState get() = _gradientState\n\n    private var _meshGradientState = UiMeshGradientState()\n    val meshGradientState: UiMeshGradientState get() = _meshGradientState\n\n    val meshResolutionX: Int get() = meshGradientState.resolutionX\n    val meshResolutionY: Int get() = meshGradientState.resolutionY\n    val meshPoints: List<List<Pair<Offset, Color>>> get() = meshGradientState.points\n\n    val brush: ShaderBrush? get() = gradientState.brush\n    val gradientType: GradientType get() = gradientState.gradientType\n    val colorStops: List<Pair<Float, Color>> get() = gradientState.colorStops\n    val tileMode: TileMode get() = gradientState.tileMode\n    val angle: Float get() = gradientState.linearGradientAngle\n    val centerFriction: Offset get() = gradientState.centerFriction\n    val radiusFriction: Float get() = gradientState.radiusFriction\n\n    private var _gradientAlpha: MutableState<Float> = mutableFloatStateOf(1f)\n    val gradientAlpha by _gradientAlpha\n\n    private val _keepExif = mutableStateOf(false)\n    val keepExif by _keepExif\n\n    private val _selectedUri = mutableStateOf(Uri.EMPTY)\n    val selectedUri: Uri by _selectedUri\n\n    private val _uris = mutableStateOf(emptyList<Uri>())\n    val uris by _uris\n\n    private val _imageAspectRatio: MutableState<Float> = mutableFloatStateOf(1f)\n    val imageAspectRatio by _imageAspectRatio\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _imageFormat = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    private val _gradientSize: MutableState<IntegerSize> = mutableStateOf(IntegerSize(1000, 1000))\n    val gradientSize by _gradientSize\n\n    suspend fun createGradientBitmap(\n        data: Any,\n        integerSize: IntegerSize = gradientSize,\n        useBitmapOriginalSizeIfAvailable: Boolean = false\n    ): Bitmap? {\n        return if (selectedUri == Uri.EMPTY) {\n            if (screenType.isMesh()) {\n                gradientMaker.createMeshGradient(\n                    integerSize = integerSize,\n                    gradientState = meshGradientState\n                )\n            } else {\n                gradientMaker.createGradient(\n                    integerSize = integerSize,\n                    gradientState = gradientState\n                )\n            }\n        } else {\n            imageGetter.getImage(\n                data = data,\n                originalSize = useBitmapOriginalSizeIfAvailable\n            )?.let {\n                if (screenType.isMesh()) {\n                    gradientMaker.createMeshGradient(\n                        src = it,\n                        gradientState = meshGradientState,\n                        gradientAlpha = gradientAlpha\n                    )\n                } else {\n                    gradientMaker.createGradient(\n                        src = it,\n                        gradientState = gradientState,\n                        gradientAlpha = gradientAlpha\n                    )\n                }\n            }\n        }\n    }\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _left.value = -1\n            _isSaving.value = true\n            if (uris.isEmpty()) {\n                createGradientBitmap(\n                    data = Unit,\n                    useBitmapOriginalSizeIfAvailable = true\n                )?.let { localBitmap ->\n                    val imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = localBitmap.width,\n                        height = localBitmap.height\n                    )\n                    parseSaveResult(\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                originalUri = \"Gradient\",\n                                sequenceNumber = null,\n                                data = imageCompressor.compressAndTransform(\n                                    image = localBitmap,\n                                    imageInfo = imageInfo\n                                )\n                            ),\n                            keepOriginalMetadata = false,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        ).onSuccess(::registerSave)\n                    )\n                }\n            } else {\n                val results = mutableListOf<SaveResult>()\n                _done.value = 0\n                _left.value = uris.size\n                uris.forEach { uri ->\n                    createGradientBitmap(\n                        data = uri,\n                        useBitmapOriginalSizeIfAvailable = true\n                    )?.let { localBitmap ->\n                        val imageInfo = ImageInfo(\n                            imageFormat = imageFormat,\n                            width = localBitmap.width,\n                            height = localBitmap.height,\n                            originalUri = uri.toString()\n                        )\n                        results.add(\n                            fileController.save(\n                                saveTarget = ImageSaveTarget(\n                                    imageInfo = imageInfo,\n                                    originalUri = uri.toString(),\n                                    sequenceNumber = _done.value + 1,\n                                    data = imageCompressor.compressAndTransform(\n                                        image = localBitmap,\n                                        imageInfo = imageInfo\n                                    )\n                                ),\n                                keepOriginalMetadata = keepExif,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                    } ?: results.add(\n                        SaveResult.Error.Exception(Throwable())\n                    )\n\n                    _done.value += 1\n                    updateProgress(\n                        done = done,\n                        total = left\n                    )\n                }\n                parseSaveResults(results.onSuccess(::registerSave))\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun shareBitmaps() {\n        savingJob = trackProgress {\n            _left.value = -1\n            _isSaving.value = true\n            if (uris.isEmpty()) {\n                createGradientBitmap(\n                    data = Unit,\n                    useBitmapOriginalSizeIfAvailable = true\n                )?.let {\n                    shareProvider.shareImage(\n                        image = it,\n                        imageInfo = ImageInfo(\n                            imageFormat = imageFormat,\n                            width = it.width,\n                            height = it.height\n                        ),\n                        onComplete = AppToastHost::showConfetti\n                    )\n                }\n            } else {\n                _done.value = 0\n                _left.value = uris.size\n                shareProvider.shareImages(\n                    uris.map { it.toString() },\n                    imageLoader = { uri ->\n                        createGradientBitmap(\n                            data = uri,\n                            useBitmapOriginalSizeIfAvailable = true\n                        )?.let {\n                            it to ImageInfo(\n                                width = it.width,\n                                height = it.height,\n                                imageFormat = imageFormat\n                            )\n                        }\n                    },\n                    onProgressChange = {\n                        if (it == -1) {\n                            AppToastHost.showConfetti()\n                            _isSaving.value = false\n                            _done.value = 0\n                        } else {\n                            _done.value = it\n                        }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n                )\n            }\n            _isSaving.value = false\n            _left.value = -1\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob = null\n        _isSaving.value = false\n        _left.value = -1\n    }\n\n    fun updateHeight(value: Int) {\n        _gradientSize.update {\n            it.copy(height = value)\n        }\n        registerChanges()\n    }\n\n    fun updateWidth(value: Int) {\n        _gradientSize.update {\n            it.copy(width = value)\n        }\n        registerChanges()\n    }\n\n    fun setGradientType(gradientType: GradientType) {\n        gradientState.gradientType = gradientType\n        registerChanges()\n    }\n\n    fun setPreviewSize(size: Size) {\n        gradientState.size = size\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        registerChanges()\n    }\n\n    fun updateLinearAngle(angle: Float) {\n        gradientState.linearGradientAngle = angle\n        registerChanges()\n    }\n\n    fun setRadialProperties(\n        center: Offset,\n        radius: Float\n    ) {\n        gradientState.centerFriction = center\n        gradientState.radiusFriction = radius\n        registerChanges()\n    }\n\n    fun setTileMode(tileMode: TileMode) {\n        gradientState.tileMode = tileMode\n        registerChanges()\n    }\n\n    fun setResolution(resolution: Float) {\n        meshGradientState.resolutionX = resolution.roundToInt()\n        meshGradientState.resolutionY = resolution.roundToInt()\n        registerChanges()\n    }\n\n    fun setScreenType(\n        type: GradientMakerType?\n    ) {\n        _screenType.update { type }\n    }\n\n    fun addColorStop(\n        pair: Pair<Float, Color>,\n        isInitial: Boolean = false\n    ) {\n        gradientState.colorStops.add(pair)\n        if (!isInitial) {\n            registerChanges()\n        }\n    }\n\n    fun updateColorStop(\n        index: Int,\n        pair: Pair<Float, Color>\n    ) {\n        gradientState.colorStops[index] = pair.copy()\n        registerChanges()\n    }\n\n    fun removeColorStop(index: Int) {\n        if (gradientState.colorStops.size > 2) {\n            gradientState.colorStops.removeAt(index)\n            registerChanges()\n        }\n    }\n\n    fun updateSelectedUri(uri: Uri) {\n        componentScope.launch {\n            _selectedUri.value = uri\n            _isImageLoading.value = true\n            imageGetter.getImageAsync(\n                uri = uri.toString(),\n                originalSize = false,\n                onGetImage = { imageData ->\n                    _imageAspectRatio.update {\n                        imageData.image.safeAspectRatio\n                    }\n                    _isImageLoading.value = false\n                    setImageFormat(imageData.imageInfo.imageFormat)\n                },\n                onFailure = {\n                    _isImageLoading.value = false\n                }\n            )\n        }\n    }\n\n    fun updateGradientAlpha(value: Float) {\n        _gradientAlpha.update { value }\n        registerChanges()\n    }\n\n    override fun resetState() {\n        _selectedUri.update { Uri.EMPTY }\n        _uris.update { emptyList() }\n        _gradientAlpha.update { 1f }\n        _gradientState = UiGradientState()\n        _meshGradientState = UiMeshGradientState()\n        setScreenType(null)\n        registerChangesCleared()\n    }\n\n    fun updateUrisSilently(\n        removedUri: Uri\n    ) = componentScope.launch {\n        if (selectedUri == removedUri) {\n            val index = uris.indexOf(removedUri)\n            if (index == 0) {\n                uris.getOrNull(1)?.let(::updateSelectedUri)\n            } else {\n                uris.getOrNull(index - 1)?.let(::updateSelectedUri)\n            }\n        }\n        _uris.update {\n            it.toMutableList().apply {\n                remove(removedUri)\n            }\n        }\n    }\n\n    fun setUris(uris: List<Uri>) {\n        _uris.update { uris }\n        uris.firstOrNull()?.let(::updateSelectedUri)\n    }\n\n    fun getGradientTransformation(): Transformation =\n        GenericTransformation<Bitmap>(\n            Triple(brush, meshPoints, screenType.isMesh())\n        ) { input ->\n            createGradientBitmap(\n                data = input,\n                useBitmapOriginalSizeIfAvailable = false\n            ) ?: input\n        }.toCoil()\n\n    fun toggleKeepExif(value: Boolean) {\n        _keepExif.update { value }\n        registerChanges()\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            createGradientBitmap(\n                data = selectedUri,\n                useBitmapOriginalSizeIfAvailable = true\n            )?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = image.width,\n                        height = image.height\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            val list = mutableListOf<Uri>()\n\n            _left.value = -1\n            _isSaving.value = true\n\n            if (uris.isEmpty()) {\n                createGradientBitmap(\n                    data = Unit,\n                    useBitmapOriginalSizeIfAvailable = true\n                )?.let { localBitmap ->\n                    val imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = localBitmap.width,\n                        height = localBitmap.height\n                    )\n                    shareProvider.cacheImage(\n                        image = localBitmap,\n                        imageInfo = imageInfo\n                    )?.toUri()?.let(list::add)\n                }\n            } else {\n                _done.value = 0\n                _left.value = uris.size\n                uris.forEach { uri ->\n                    createGradientBitmap(\n                        data = uri,\n                        useBitmapOriginalSizeIfAvailable = true\n                    )?.let { localBitmap ->\n                        val imageInfo = ImageInfo(\n                            imageFormat = imageFormat,\n                            width = localBitmap.width,\n                            height = localBitmap.height,\n                            originalUri = uri.toString()\n                        )\n\n                        shareProvider.cacheImage(\n                            image = localBitmap,\n                            imageInfo = imageInfo\n                        )?.toUri()?.let(list::add)\n                    }\n\n                    _done.value += 1\n                    updateProgress(\n                        done = done,\n                        total = left\n                    )\n                }\n            }\n            _isSaving.value = false\n\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            .indexOf(selectedUri)\n            .takeIf { it >= 0 }\n            ?.let {\n                uris.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            .indexOf(selectedUri)\n            .takeIf { it >= 0 }\n            ?.let {\n                uris.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? = if (uris.size < 2) imageFormat\n    else null\n\n    fun setShowOriginal(value: Boolean) {\n        _showOriginal.update { value }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): GradientMakerComponent\n    }\n}"
  },
  {
    "path": "feature/image-cutting/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/image-cutting/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.image_cutting\"\n\ndependencies {\n    implementation(projects.feature.compare)\n}"
  },
  {
    "path": "feature/image-cutting/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/data/AndroidImageCutter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.data\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.image_cutting.domain.CutParams\nimport com.t8rin.imagetoolbox.image_cutting.domain.ImageCutter\nimport com.t8rin.imagetoolbox.image_cutting.domain.PivotPair\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.math.roundToInt\n\ninternal class AndroidImageCutter @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : ImageCutter<Bitmap>, DispatchersHolder by dispatchersHolder {\n\n    override suspend fun cutAndMerge(\n        imageUri: String,\n        params: CutParams\n    ): Bitmap? {\n        return cutAndMerge(\n            image = imageGetter.getImage(\n                data = imageUri,\n                originalSize = true\n            ) ?: return null,\n            params = params\n        )\n    }\n\n    override suspend fun cutAndMerge(\n        image: Bitmap,\n        params: CutParams\n    ): Bitmap = withContext(defaultDispatcher) {\n        runSuspendCatching {\n            val (verticalStart, verticalEnd) = params.vertical.toCutBounds(image.width)\n            val (horizontalStart, horizontalEnd) = params.horizontal.toCutBounds(image.height)\n\n            image.cutAndMerge(\n                verticalStart = verticalStart,\n                verticalEnd = verticalEnd,\n                horizontalStart = horizontalStart,\n                horizontalEnd = horizontalEnd,\n                inverseVertical = params.inverseVertical,\n                inverseHorizontal = params.inverseHorizontal\n            )\n        }.getOrNull() ?: image\n    }\n\n    private fun PivotPair?.toCutBounds(\n        size: Int\n    ): Pair<Int?, Int?> {\n        val bounds = this\n            ?.takeIf { it != PivotPair(0f, 1f) }\n            ?.let {\n                (it.startRtlAdjusted * size).roundToInt() to\n                        (it.endRtlAdjusted * size).roundToInt()\n            }\n            ?: return null to null\n\n        val (start, end) = bounds\n\n        return if (start in 0..size && end in 0..size && start < end) {\n            start to end\n        } else {\n            null to null\n        }\n    }\n\n    private suspend fun Bitmap.cutAndMerge(\n        verticalStart: Int? = null,\n        verticalEnd: Int? = null,\n        horizontalStart: Int? = null,\n        horizontalEnd: Int? = null,\n        inverseVertical: Boolean = false,\n        inverseHorizontal: Boolean = false\n    ): Bitmap = coroutineScope {\n        if (inverseVertical && inverseHorizontal) {\n            Bitmap.createBitmap(\n                this@cutAndMerge,\n                verticalStart ?: 0,\n                horizontalStart ?: 0,\n                (verticalEnd ?: width) - (verticalStart ?: 0),\n                (horizontalEnd ?: height) - (horizontalStart ?: 0)\n            )\n        } else {\n            cutVertically(\n                start = verticalStart,\n                end = verticalEnd,\n                inverse = inverseVertical\n            ).cutHorizontally(\n                start = horizontalStart,\n                end = horizontalEnd,\n                inverse = inverseHorizontal\n            )\n        }\n    }\n\n    private suspend fun Bitmap.cutHorizontally(\n        start: Int?,\n        end: Int?,\n        inverse: Boolean\n    ): Bitmap = coroutineScope {\n        val source = this@cutHorizontally\n\n        if (inverse) {\n            if (start != null && end != null) {\n                return@coroutineScope Bitmap.createBitmap(\n                    source,\n                    0,\n                    start,\n                    source.width,\n                    end - start\n                )\n            } else if (start == null && end != null) {\n                return@coroutineScope Bitmap.createBitmap(\n                    source,\n                    0,\n                    0,\n                    source.width,\n                    end\n                )\n            } else if (start != null) {\n                return@coroutineScope Bitmap.createBitmap(\n                    source,\n                    0,\n                    start,\n                    source.width,\n                    source.height - start\n                )\n            }\n        }\n\n\n        val parts = mutableListOf<Bitmap>()\n        if (start != null || end != null) {\n            if (start != null && start > 0) {\n                parts.add(\n                    Bitmap.createBitmap(\n                        source,\n                        0,\n                        0,\n                        source.width,\n                        start\n                    )\n                )\n            }\n            if (end != null && end < source.height) {\n                parts.add(\n                    Bitmap.createBitmap(\n                        source,\n                        0,\n                        end,\n                        source.width,\n                        source.height - end\n                    )\n                )\n            }\n        } else {\n            parts.add(source.copy(source.safeConfig, true))\n        }\n\n        val mergedWidth = parts.maxOf { it.width }\n        val mergedHeight = parts.sumOf { it.height }\n\n        createBitmap(mergedWidth, mergedHeight, source.safeConfig)\n            .applyCanvas {\n                var offsetY = 0f\n                for (part in parts) {\n                    drawBitmap(part, 0f, offsetY)\n                    offsetY += part.height\n                    part.recycle()\n                }\n            }\n    }\n\n    private suspend fun Bitmap.cutVertically(\n        start: Int?,\n        end: Int?,\n        inverse: Boolean\n    ): Bitmap = coroutineScope {\n        val source = this@cutVertically\n\n        if (inverse) {\n            if (start != null && end != null) {\n                return@coroutineScope Bitmap.createBitmap(\n                    source,\n                    start,\n                    0,\n                    end - start,\n                    source.height\n                )\n            } else if (start == null && end != null) {\n                return@coroutineScope Bitmap.createBitmap(\n                    source,\n                    0,\n                    0,\n                    end,\n                    source.height\n                )\n            } else if (start != null) {\n                return@coroutineScope Bitmap.createBitmap(\n                    source,\n                    start,\n                    0,\n                    source.width - start,\n                    source.height\n                )\n            }\n        }\n\n        val parts = mutableListOf<Bitmap>()\n        if (start != null || end != null) {\n            if (start != null && start > 0) {\n                parts.add(\n                    Bitmap.createBitmap(\n                        source,\n                        0,\n                        0,\n                        start,\n                        source.height\n                    )\n                )\n            }\n            if (end != null && end < source.width) {\n                parts.add(\n                    Bitmap.createBitmap(\n                        source,\n                        end,\n                        0,\n                        source.width - end,\n                        source.height\n                    )\n                )\n            }\n        } else {\n            parts.add(source.copy(source.safeConfig, true))\n        }\n\n        val mergedWidth = parts.sumOf { it.width }\n        val mergedHeight = parts.maxOf { it.height }\n\n        createBitmap(mergedWidth, mergedHeight, source.safeConfig)\n            .applyCanvas {\n                var offsetX = 0f\n                for (part in parts) {\n                    drawBitmap(part, offsetX, 0f)\n                    offsetX += part.width\n                    part.recycle()\n                }\n            }\n    }\n\n}\n"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/di/ImageCutterModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.image_cutting.data.AndroidImageCutter\nimport com.t8rin.imagetoolbox.image_cutting.domain.ImageCutter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ImageCutterModule {\n\n    @Binds\n    @Singleton\n    fun cutter(\n        impl: AndroidImageCutter\n    ): ImageCutter<Bitmap>\n\n}"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/domain/CutParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.domain\n\ndata class CutParams(\n    val vertical: PivotPair?,\n    val horizontal: PivotPair?,\n    val inverseVertical: Boolean,\n    val inverseHorizontal: Boolean\n) {\n    companion object {\n        val Default by lazy {\n            CutParams(\n                vertical = null,\n                horizontal = null,\n                inverseVertical = false,\n                inverseHorizontal = false\n            )\n        }\n    }\n}\n\nclass PivotPair(\n    val start: Float,\n    val end: Float,\n    val isRtl: Boolean = false\n) {\n    val startRtlAdjusted = if (isRtl) 1f - end else start\n    val endRtlAdjusted = if (isRtl) 1f - start else end\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as PivotPair\n\n        if (start != other.start) return false\n        if (end != other.end) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = start.hashCode()\n        result = 31 * result + end.hashCode()\n        return result\n    }\n}"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/domain/ImageCutter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.domain\n\ninterface ImageCutter<Image> {\n\n    suspend fun cutAndMerge(\n        imageUri: String,\n        params: CutParams\n    ): Image?\n\n    suspend fun cutAndMerge(\n        image: Image,\n        params: CutParams\n    ): Image?\n\n}"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/presentation/ImageCutterContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.CompareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareSheet\nimport com.t8rin.imagetoolbox.image_cutting.presentation.components.CutParamsSelector\nimport com.t8rin.imagetoolbox.image_cutting.presentation.components.CutPreview\nimport com.t8rin.imagetoolbox.image_cutting.presentation.components.rememberCutTransformations\nimport com.t8rin.imagetoolbox.image_cutting.presentation.screenLogic.ImageCutterComponent\n\n@Composable\nfun ImageCutterContent(\n    component: ImageCutterComponent\n) {\n    val imagePicker = rememberImagePicker(onSuccess = component::updateUris)\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.image_cutting),\n                input = component.uris,\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.uris != null,\n                onShare = component::shareBitmaps,\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                },\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        imagePreview = {\n            Box(\n                modifier = Modifier\n                    .container()\n                    .padding(4.dp)\n                    .animateContentSizeNoClip(\n                        alignment = Alignment.Center\n                    )\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                CutPreview(\n                    uri = component.selectedUri,\n                    params = component.params,\n                    isLoadingFromDifferentPlace = component.isImageLoading\n                )\n            }\n        },\n        controls = {\n            ImageCounter(\n                imageCount = component.uris?.size?.takeIf { it > 1 },\n                onRepick = {\n                    showPickImageFromUrisSheet = true\n                }\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            val params = component.params\n            CutParamsSelector(\n                value = params,\n                onValueChange = component::updateParams\n            )\n            Spacer(Modifier.height(8.dp))\n            ImageFormatSelector(\n                value = component.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = component.quality,\n            )\n            if (component.imageFormat.canChangeCompressionValue) {\n                Spacer(Modifier.height(8.dp))\n            }\n            QualitySelector(\n                imageFormat = component.imageFormat,\n                quality = component.quality,\n                onQualityChange = component::setQuality\n            )\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.uris.isNullOrEmpty()) {\n                TopAppBarEmoji()\n            }\n\n            var showZoomSheet by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showCompareSheet by rememberSaveable {\n                mutableStateOf(false)\n            }\n            CompareButton(\n                visible = !component.uris.isNullOrEmpty(),\n                onClick = { showCompareSheet = true }\n            )\n            ZoomButton(\n                visible = !component.uris.isNullOrEmpty(),\n                onClick = { showZoomSheet = true }\n            )\n\n            CompareSheet(\n                beforeContent = {\n                    var aspectRatio by remember {\n                        mutableFloatStateOf(1f)\n                    }\n                    Picture(\n                        model = component.selectedUri,\n                        modifier = Modifier.aspectRatio(aspectRatio),\n                        onSuccess = {\n                            aspectRatio = it.result.image.toBitmap().safeAspectRatio\n                        }\n                    )\n                },\n                afterContent = {\n                    var aspectRatio by remember {\n                        mutableFloatStateOf(1f)\n                    }\n                    Picture(\n                        model = component.selectedUri,\n                        transformations = component.rememberCutTransformations(component.selectedUri),\n                        modifier = Modifier.aspectRatio(aspectRatio),\n                        onSuccess = {\n                            aspectRatio = it.result.image.toBitmap().safeAspectRatio\n                        }\n                    )\n                },\n                visible = showCompareSheet,\n                onDismiss = {\n                    showCompareSheet = false\n                }\n            )\n\n            ZoomModalSheet(\n                data = component.selectedUri,\n                transformations = component.rememberCutTransformations(component.selectedUri),\n                visible = showZoomSheet,\n                onDismiss = { showZoomSheet = false }\n            )\n        },\n        canShowScreenData = !component.uris.isNullOrEmpty(),\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        }\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    PickImageFromUrisSheet(\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        transformations = component.rememberCutTransformations(component.uris),\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = { uri ->\n            component.updateSelectedUri(uri)\n        },\n        onUriRemoved = { uri ->\n            component.updateUrisSilently(removedUri = uri)\n        },\n        columns = if (isPortrait) 2 else 4,\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris?.size ?: -1,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/presentation/components/CutParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BorderHorizontal\nimport androidx.compose.material.icons.rounded.BorderVertical\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectInverse\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedRangeSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.image_cutting.domain.CutParams\nimport com.t8rin.imagetoolbox.image_cutting.domain.PivotPair\n\n@Composable\ninternal fun CutParamsSelector(\n    value: CutParams,\n    onValueChange: (CutParams) -> Unit\n) {\n    val params by rememberUpdatedState(value)\n    val layoutDirection = LocalLayoutDirection.current\n\n    Column {\n        EnhancedRangeSliderItem(\n            value = params.vertical?.let { it.start..it.end } ?: 0f..1f,\n            valueRange = 0f..1f,\n            icon = Icons.Rounded.BorderVertical,\n            title = stringResource(R.string.vertical_pivot_line),\n            internalStateTransformation = {\n                it.start.roundTo(3)..it.endInclusive.roundTo(3)\n            },\n            onValueChange = {\n                onValueChange(\n                    params.copy(\n                        vertical = PivotPair(\n                            start = it.start,\n                            end = it.endInclusive,\n                            isRtl = layoutDirection == LayoutDirection.Rtl\n                        )\n                    )\n                )\n            },\n            additionalContent = {\n                PreferenceRowSwitch(\n                    title = stringResource(R.string.inverse_selection),\n                    subtitle = stringResource(R.string.inverse_vertical_selection_sub),\n                    startIcon = Icons.Rounded.SelectInverse,\n                    checked = params.inverseVertical,\n                    onClick = {\n                        onValueChange(\n                            params.copy(\n                                inverseVertical = it\n                            )\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    shape = ShapeDefaults.small,\n                    modifier = Modifier.padding(\n                        start = 4.dp,\n                        end = 4.dp,\n                        bottom = 4.dp\n                    )\n                )\n            }\n        )\n        Spacer(Modifier.height(8.dp))\n        EnhancedRangeSliderItem(\n            value = params.horizontal?.let { it.start..it.end } ?: 0f..1f,\n            valueRange = 0f..1f,\n            icon = Icons.Rounded.BorderHorizontal,\n            title = stringResource(R.string.horizontal_pivot_line),\n            internalStateTransformation = {\n                it.start.roundTo(3)..it.endInclusive.roundTo(3)\n            },\n            onValueChange = {\n                onValueChange(\n                    params.copy(\n                        horizontal = PivotPair(\n                            start = it.start,\n                            end = it.endInclusive,\n                            isRtl = layoutDirection == LayoutDirection.Rtl\n                        )\n                    )\n                )\n            },\n            additionalContent = {\n                PreferenceRowSwitch(\n                    title = stringResource(R.string.inverse_selection),\n                    subtitle = stringResource(R.string.inverse_horizontal_selection_sub),\n                    startIcon = Icons.Rounded.SelectInverse,\n                    checked = params.inverseHorizontal,\n                    onClick = {\n                        onValueChange(\n                            params.copy(\n                                inverseHorizontal = it\n                            )\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.surface,\n                    shape = ShapeDefaults.small,\n                    modifier = Modifier.padding(\n                        start = 4.dp,\n                        end = 4.dp,\n                        bottom = 4.dp\n                    )\n                )\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/presentation/components/CutPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.CompositingStrategy\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.Black\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberAnimatedBorderPhase\nimport com.t8rin.imagetoolbox.image_cutting.domain.CutParams\nimport com.t8rin.imagetoolbox.image_cutting.domain.PivotPair\nimport kotlin.math.abs\nimport kotlin.math.hypot\n\n@Composable\ninternal fun CutPreview(\n    uri: Uri?,\n    params: CutParams,\n    modifier: Modifier = Modifier,\n    isLoadingFromDifferentPlace: Boolean = false\n) {\n    var aspectRatio by rememberSaveable(uri) {\n        mutableFloatStateOf(1f)\n    }\n\n    Box(\n        modifier = modifier\n            .aspectRatio(aspectRatio)\n            .clip(MaterialTheme.shapes.medium)\n    ) {\n        Picture(\n            model = uri,\n            size = 1500,\n            contentScale = ContentScale.FillBounds,\n            modifier = Modifier.fillMaxSize(),\n            onSuccess = {\n                aspectRatio = it.result.image.toBitmap().safeAspectRatio\n            },\n            shape = RectangleShape,\n            isLoadingFromDifferentPlace = isLoadingFromDifferentPlace\n        )\n\n        CutFrameBorder(\n            modifier = Modifier.fillMaxSize(),\n            params = params\n        )\n    }\n}\n\n@Composable\nprivate fun CutFrameBorder(\n    modifier: Modifier = Modifier,\n    params: CutParams\n) {\n    val keptRects = remember(params) {\n        params.toPreviewRects()\n    } ?: return\n    val meaningfulEdgeGroups = remember(keptRects) {\n        keptRects.map(Rect::toMeaningfulEdges).filter(List<PreviewEdge>::isNotEmpty)\n    }\n\n    val isNightMode = LocalSettingsState.current.isNightMode\n    val colorScheme = MaterialTheme.colorScheme\n    val overlayColor = Black.copy(alpha = if (isNightMode) 0.5f else 0.3f)\n    val animatedBorderPhase = rememberAnimatedBorderPhase()\n\n    Canvas(\n        modifier = modifier.graphicsLayer {\n            compositingStrategy = CompositingStrategy.Offscreen\n        }\n    ) {\n        val strokeWidth = 1.5.dp.toPx()\n\n        drawRect(\n            color = overlayColor,\n            size = size\n        )\n\n        keptRects.forEach { rect ->\n            val topLeft = Offset(\n                x = rect.left * size.width,\n                y = rect.top * size.height\n            )\n            val rectSize = Size(\n                width = rect.width * size.width,\n                height = rect.height * size.height\n            )\n\n            drawRect(\n                color = Color.Transparent,\n                blendMode = BlendMode.Clear,\n                topLeft = topLeft,\n                size = rectSize\n            )\n        }\n\n        meaningfulEdgeGroups.forEach { edges ->\n            var accumulatedLength = 0f\n\n            edges.forEach { edge ->\n                val start = Offset(\n                    x = edge.start.x * size.width,\n                    y = edge.start.y * size.height\n                )\n                val end = Offset(\n                    x = edge.end.x * size.width,\n                    y = edge.end.y * size.height\n                )\n                val lineLength = hypot(end.x - start.x, end.y - start.y)\n\n                drawLine(\n                    color = colorScheme.primary,\n                    start = start,\n                    end = end,\n                    strokeWidth = strokeWidth\n                )\n\n                drawLine(\n                    color = colorScheme.primaryContainer,\n                    start = start,\n                    end = end,\n                    strokeWidth = strokeWidth,\n                    pathEffect = PathEffect.dashPathEffect(\n                        intervals = DashIntervals,\n                        phase = animatedBorderPhase - accumulatedLength\n                    )\n                )\n\n                accumulatedLength += lineLength\n            }\n        }\n    }\n}\n\nprivate fun CutParams.toPreviewRects(): List<Rect>? {\n    val vertical = vertical.toPreviewRangeOrNull()\n    val horizontal = horizontal.toPreviewRangeOrNull()\n\n    if (vertical == null && horizontal == null) return null\n\n    val xSegments = vertical.toPreviewSegments(inverse = inverseVertical)\n    val ySegments = horizontal.toPreviewSegments(inverse = inverseHorizontal)\n\n    return buildList {\n        xSegments.forEach { xRange ->\n            ySegments.forEach { yRange ->\n                Rect(\n                    left = xRange.start,\n                    top = yRange.start,\n                    right = xRange.endInclusive,\n                    bottom = yRange.endInclusive\n                ).takeIf {\n                    it.width > 0f && it.height > 0f\n                }?.let(::add)\n            }\n        }\n    }\n}\n\nprivate fun PivotPair?.toPreviewRangeOrNull(): ClosedFloatingPointRange<Float>? {\n    return this\n        ?.takeIf { it != PivotPair(0f, 1f) }\n        ?.let {\n            it.startRtlAdjusted.coerceIn(0f, 1f)..it.endRtlAdjusted.coerceIn(0f, 1f)\n        }\n}\n\nprivate fun ClosedFloatingPointRange<Float>?.toPreviewSegments(\n    inverse: Boolean\n): List<ClosedFloatingPointRange<Float>> {\n    return when {\n        this == null -> listOf(0f..1f)\n        inverse -> listOf(this)\n        else -> buildList {\n            if (start > 0f) add(0f..start)\n            if (endInclusive < 1f) add(endInclusive..1f)\n        }\n    }\n}\n\nprivate data class PreviewEdge(\n    val start: Offset,\n    val end: Offset\n)\n\nprivate val DashIntervals = floatArrayOf(20f, 20f)\n\nprivate fun Rect.toMeaningfulEdges(): List<PreviewEdge> {\n    return buildList {\n        if (!top.isCloseTo(0f)) {\n            add(\n                PreviewEdge(\n                    start = Offset(left, top),\n                    end = Offset(right, top)\n                )\n            )\n        }\n        if (!right.isCloseTo(1f)) {\n            add(\n                PreviewEdge(\n                    start = Offset(right, top),\n                    end = Offset(right, bottom)\n                )\n            )\n        }\n        if (!bottom.isCloseTo(1f)) {\n            add(\n                PreviewEdge(\n                    start = Offset(right, bottom),\n                    end = Offset(left, bottom)\n                )\n            )\n        }\n        if (!left.isCloseTo(0f)) {\n            add(\n                PreviewEdge(\n                    start = Offset(left, bottom),\n                    end = Offset(left, top)\n                )\n            )\n        }\n    }\n}\n\nprivate fun Float.isCloseTo(\n    other: Float,\n    epsilon: Float = 0.001f\n): Boolean = abs(this - other) <= epsilon\n\n@EnPreview\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    CutPreview(\n        uri = \"111\".toUri(),\n        params = CutParams(\n            vertical = PivotPair(start = 0.2f, end = 0.8f),\n            horizontal = PivotPair(start = 0.3f, end = 0.65f),\n            inverseVertical = false,\n            inverseHorizontal = true\n        )\n    )\n}\n"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/presentation/components/Utils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.presentation.components\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport coil3.transform.Transformation\nimport com.t8rin.imagetoolbox.image_cutting.presentation.screenLogic.ImageCutterComponent\n\n@Composable\ninternal fun ImageCutterComponent.rememberCutTransformations(\n    key: Any?\n): List<Transformation> {\n    return remember(\n        params,\n        imageFormat,\n        quality,\n        key\n    ) {\n        derivedStateOf {\n            getCutTransformation()\n        }\n    }.value\n}"
  },
  {
    "path": "feature/image-cutting/src/main/java/com/t8rin/imagetoolbox/image_cutting/presentation/screenLogic/ImageCutterComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_cutting.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport coil3.transform.Transformation\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.data.utils.toCoil\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.transformation.GenericTransformation\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.image_cutting.domain.CutParams\nimport com.t8rin.imagetoolbox.image_cutting.domain.ImageCutter\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass ImageCutterComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageCutter: ImageCutter<Bitmap>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::updateUris)\n        }\n    }\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _selectedUri: MutableState<Uri?> = mutableStateOf(null)\n    val selectedUri by _selectedUri\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Default)\n    val imageFormat: ImageFormat by _imageFormat\n\n    private val _quality: MutableState<Quality> = mutableStateOf(Quality.Base(100))\n    val quality: Quality by _quality\n\n    private val _params: MutableState<CutParams> = mutableStateOf(CutParams.Default)\n    val params by _params\n\n    fun updateParams(cutParams: CutParams) {\n        _params.update { cutParams }\n        registerChanges()\n    }\n\n    fun updateUris(uris: List<Uri>?) {\n        _uris.value = null\n        _uris.value = uris\n        _selectedUri.value = uris?.firstOrNull()\n    }\n\n    fun updateUrisSilently(removedUri: Uri) {\n        componentScope.launch {\n            _uris.value = uris\n            if (_selectedUri.value == removedUri) {\n                val index = uris?.indexOf(removedUri) ?: -1\n                if (index == 0) {\n                    uris?.getOrNull(1)?.let {\n                        updateSelectedUri(it)\n                    }\n                } else {\n                    uris?.getOrNull(index - 1)?.let {\n                        updateSelectedUri(it)\n                    }\n                }\n            }\n            val u = _uris.value?.toMutableList()?.apply {\n                remove(removedUri)\n            }\n            _uris.value = u\n\n            registerChanges()\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        if (_quality.value != quality) {\n            _quality.value = quality\n            registerChanges()\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        if (_imageFormat.value != imageFormat) {\n            _imageFormat.value = imageFormat\n            registerChanges()\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    imageCutter.cutAndMerge(\n                        imageUri = uri.toString(),\n                        params = params\n                    )\n                }.getOrNull()?.let { bitmap ->\n                    ImageInfo(\n                        width = bitmap.width,\n                        height = bitmap.height,\n                        originalUri = uri.toString(),\n                        quality = quality,\n                        imageFormat = imageFormat\n                    ).let { imageInfo ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = ImageSaveTarget(\n                                    imageInfo = imageInfo,\n                                    metadata = null,\n                                    originalUri = uri.toString(),\n                                    sequenceNumber = _done.value + 1,\n                                    data = imageCompressor.compress(\n                                        image = bitmap,\n                                        imageFormat = imageFormat,\n                                        quality = quality\n                                    )\n                                ),\n                                keepOriginalMetadata = false,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                    }\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun updateSelectedUri(uri: Uri) {\n        _selectedUri.value = uri\n    }\n\n    fun shareBitmaps() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            shareProvider.shareImages(\n                uris = uris?.map { it.toString() } ?: emptyList(),\n                imageLoader = { uri ->\n                    imageGetter.getImage(uri)?.image?.let { bmp ->\n                        bmp to ImageInfo(\n                            width = bmp.width,\n                            height = bmp.height,\n                            originalUri = uri,\n                            quality = quality,\n                            imageFormat = imageFormat\n                        )\n                    }\n                },\n                onProgressChange = {\n                    if (it == -1) {\n                        AppToastHost.showConfetti()\n                        _isSaving.value = false\n                        _done.value = 0\n                    } else {\n                        _done.value = it\n                    }\n                    updateProgress(\n                        done = done,\n                        total = uris.orEmpty().size\n                    )\n                }\n            )\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            imageCutter.cutAndMerge(\n                imageUri = selectedUri.toString(),\n                params = params\n            )?.let { bmp ->\n                bmp to ImageInfo(\n                    width = bmp.width,\n                    height = bmp.height,\n                    originalUri = selectedUri.toString(),\n                    quality = quality,\n                    imageFormat = imageFormat\n                )\n            }?.let { (image, imageInfo) ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo.copy(originalUri = selectedUri.toString())\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            val list = mutableListOf<Uri>()\n            uris?.forEach { uri ->\n                imageCutter.cutAndMerge(\n                    imageUri = uri.toString(),\n                    params = params\n                )?.let { bmp ->\n                    bmp to ImageInfo(\n                        width = bmp.width,\n                        height = bmp.height,\n                        originalUri = uri.toString(),\n                        quality = quality,\n                        imageFormat = imageFormat\n                    )\n                }?.let { (image, imageInfo) ->\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = imageInfo.copy(originalUri = uri.toString())\n                    )?.let { uri ->\n                        list.add(uri.toUri())\n                    }\n                }\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? =\n        if (uris?.size == 1) imageFormat\n        else null\n\n    fun getCutTransformation(): List<Transformation> = listOf(\n        GenericTransformation { image: Bitmap ->\n            val bitmap = imageCutter.cutAndMerge(\n                image = image,\n                params = params\n            ) ?: image\n\n            imagePreviewCreator.createPreview(\n                image = bitmap,\n                imageInfo = ImageInfo(\n                    width = bitmap.width,\n                    height = bitmap.height,\n                    quality = quality,\n                    imageFormat = imageFormat\n                ),\n                transformations = emptyList(),\n                onGetByteCount = {}\n            ) ?: image\n        }.toCoil()\n    )\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ImageCutterComponent\n    }\n}"
  },
  {
    "path": "feature/image-preview/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/image-preview/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.image_preview\""
  },
  {
    "path": "feature/image-preview/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/image-preview/src/main/java/com/t8rin/imagetoolbox/feature/image_preview/presentation/ImagePreviewContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_preview.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.Crossfade\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.outlined.ImageSearch\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Share\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.FolderOpened\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFolderPicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SortButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitBackHandler\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButtonType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagePreviewGrid\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.core.utils.sortedByType\nimport com.t8rin.imagetoolbox.feature.image_preview.presentation.screenLogic.ImagePreviewComponent\n\n@Composable\nfun ImagePreviewContent(\n    component: ImagePreviewComponent\n) {\n    var showExitDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    val onBack = {\n        if (component.uris.isNullOrEmpty()) component.onGoBack()\n        else showExitDialog = true\n    }\n\n    val initialShowImagePreviewDialog = !component.initialUris.isNullOrEmpty()\n\n    val settingsState = LocalSettingsState.current\n\n    val imagePicker = rememberImagePicker(onSuccess = component::updateUris)\n\n    val isLoadingImages = component.isImageLoading\n\n    var previousFolder by rememberSaveable {\n        mutableStateOf<Uri?>(null)\n    }\n    val openDirectoryLauncher = rememberFolderPicker(\n        onSuccess = { uri ->\n            previousFolder = uri\n            component.updateUrisFromTree(uri)\n        }\n    )\n\n    val pickImage = imagePicker::pickImage\n\n    val selectedUris by remember(component.uris, component.imageFrames) {\n        derivedStateOf {\n            component.getSelectedUris() ?: emptyList()\n        }\n    }\n    var wantToEdit by rememberSaveable(selectedUris.isNotEmpty()) {\n        mutableStateOf(false)\n    }\n\n    var gridInvalidations by remember {\n        mutableIntStateOf(0)\n    }\n\n    Surface(\n        color = MaterialTheme.colorScheme.background\n    ) {\n        val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) {\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n\n            Scaffold(\n                modifier = Modifier.fillMaxSize(),\n                topBar = {\n                    EnhancedTopAppBar(\n                        type = EnhancedTopAppBarType.Large,\n                        scrollBehavior = scrollBehavior,\n                        title = {\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically,\n                                modifier = Modifier.marquee()\n                            ) {\n                                Text(\n                                    text = stringResource(R.string.image_preview)\n                                )\n                                AnimatedVisibility(!component.uris.isNullOrEmpty()) {\n                                    EnhancedBadge(\n                                        content = {\n                                            val prefix = if (isLoadingImages) \"~\" else \"\"\n                                            Text(\n                                                text = \"$prefix${component.uris.orEmpty().size}\"\n                                            )\n                                        },\n                                        containerColor = MaterialTheme.colorScheme.tertiary,\n                                        contentColor = MaterialTheme.colorScheme.onTertiary,\n                                        modifier = Modifier\n                                            .padding(horizontal = 2.dp)\n                                            .padding(bottom = 12.dp)\n                                            .scaleOnTap {\n                                                AppToastHost.showConfetti()\n                                            }\n                                    )\n                                }\n                            }\n                        },\n                        navigationIcon = {\n                            EnhancedIconButton(\n                                onClick = component.onGoBack\n                            ) {\n                                Icon(\n                                    imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                    contentDescription = stringResource(R.string.exit)\n                                )\n                            }\n                        },\n                        actions = {\n                            val isCanClear = selectedUris.isNotEmpty()\n                            val isCanSelectAll =\n                                component.uris?.size != selectedUris.size && component.uris != null\n\n                            AnimatedContent(\n                                targetState = (!isCanSelectAll && !isCanClear) to selectedUris.isEmpty(),\n                                modifier = Modifier.size(40.dp)\n                            ) { (notSelection, haveUris) ->\n                                if (notSelection && haveUris) {\n                                    TopAppBarEmoji()\n                                } else if (haveUris) {\n                                    SortButton(\n                                        modifier = Modifier.size(40.dp),\n                                        iconSize = 24.dp,\n                                        containerColor = Color.Transparent,\n                                        contentColor = MaterialTheme.colorScheme.onSurface,\n                                        onSortTypeSelected = { sortType ->\n                                            component.asyncUpdateUris(\n                                                onFinish = { gridInvalidations++ },\n                                                action = {\n                                                    it.orEmpty().sortedByType(\n                                                        sortType = sortType\n                                                    )\n                                                }\n                                            )\n                                        }\n                                    )\n                                }\n                            }\n\n                            AnimatedVisibility(\n                                visible = isCanSelectAll && isCanClear,\n                                enter = fadeIn() + scaleIn() + expandHorizontally(),\n                                exit = fadeOut() + scaleOut() + shrinkHorizontally()\n                            ) {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        component.updateImageFrames(ImageFrames.All)\n                                    }\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Outlined.SelectAll,\n                                        contentDescription = \"Select All\"\n                                    )\n                                }\n                            }\n\n                            AnimatedVisibility(\n                                modifier = Modifier\n                                    .padding(8.dp)\n                                    .container(\n                                        shape = ShapeDefaults.circle,\n                                        color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                                        resultPadding = 0.dp\n                                    ),\n                                visible = isCanClear\n                            ) {\n                                Row(\n                                    modifier = Modifier.padding(start = 12.dp),\n                                    verticalAlignment = Alignment.CenterVertically,\n                                    horizontalArrangement = Arrangement.Center\n                                ) {\n                                    Spacer(Modifier.width(8.dp))\n                                    Text(\n                                        text = selectedUris.size.toString(),\n                                        fontSize = 20.sp,\n                                        fontWeight = FontWeight.Medium\n                                    )\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            component.updateImageFrames(\n                                                ImageFrames.ManualSelection(emptyList())\n                                            )\n                                        }\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.Close,\n                                            contentDescription = stringResource(R.string.close)\n                                        )\n                                    }\n                                }\n                            }\n                        }\n                    )\n                },\n                contentWindowInsets = WindowInsets()\n            ) { contentPadding ->\n                AnimatedContent(\n                    targetState = !component.uris.isNullOrEmpty() || isLoadingImages,\n                    transitionSpec = {\n                        fadeIn() togetherWith fadeOut()\n                    },\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .padding(contentPadding)\n                ) { canShowGrid ->\n                    if (canShowGrid) {\n                        Crossfade(gridInvalidations) { key ->\n                            key(key) {\n                                ImagePreviewGrid(\n                                    data = component.uris,\n                                    onAddImages = component::updateUris,\n                                    onShareImage = {\n                                        component.shareImages(\n                                            uriList = listOf(element = it)\n                                        )\n                                    },\n                                    onRemove = component::removeUri,\n                                    initialShowImagePreviewDialog = initialShowImagePreviewDialog,\n                                    onNavigate = component.onNavigate,\n                                    imageFrames = component.imageFrames,\n                                    onFrameSelectionChange = component::updateImageFrames\n                                )\n                            }\n                        }\n                    } else {\n                        Column(\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .enhancedVerticalScroll(rememberScrollState()),\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            ImageNotPickedWidget(\n                                onPickImage = pickImage,\n                                modifier = Modifier.padding(\n                                    PaddingValues(\n                                        bottom = 88.dp + WindowInsets\n                                            .navigationBars\n                                            .asPaddingValues()\n                                            .calculateBottomPadding(),\n                                        top = 12.dp,\n                                        end = 12.dp,\n                                        start = 12.dp\n                                    )\n                                )\n                            )\n                        }\n                    }\n                }\n            }\n\n            Row(\n                modifier = Modifier\n                    .navigationBarsPadding()\n                    .padding(16.dp)\n                    .align(settingsState.fabAlignment)\n            ) {\n                AnimatedContent(targetState = selectedUris.isNotEmpty()) { isFramesSelected ->\n                    if (isFramesSelected) {\n                        EnhancedFloatingActionButton(\n                            onClick = {\n                                wantToEdit = true\n                            },\n                            content = {\n                                Spacer(Modifier.width(16.dp))\n                                Icon(\n                                    imageVector = Icons.Outlined.ImageEdit,\n                                    contentDescription = stringResource(R.string.edit)\n                                )\n                                Spacer(Modifier.width(16.dp))\n                                Text(stringResource(R.string.edit))\n                                Spacer(Modifier.width(16.dp))\n                            }\n                        )\n                    } else {\n                        EnhancedFloatingActionButton(\n                            onClick = pickImage,\n                            onLongClick = {\n                                showOneTimeImagePickingDialog = true\n                            },\n                            content = {\n                                Spacer(Modifier.width(16.dp))\n                                Icon(\n                                    imageVector = Icons.Rounded.AddPhotoAlt,\n                                    contentDescription = stringResource(R.string.pick_image_alt)\n                                )\n                                Spacer(Modifier.width(16.dp))\n                                Text(stringResource(R.string.pick_image_alt))\n                                Spacer(Modifier.width(16.dp))\n                            }\n                        )\n                    }\n                }\n                Spacer(modifier = Modifier.width(8.dp))\n                AnimatedContent(targetState = selectedUris.isNotEmpty()) { isFramesSelected ->\n                    if (isFramesSelected) {\n                        EnhancedFloatingActionButton(\n                            onClick = {\n                                component.shareImages(\n                                    uriList = null\n                                )\n                            },\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            type = EnhancedFloatingActionButtonType.SecondaryHorizontal,\n                            content = {\n                                Icon(\n                                    imageVector = Icons.Rounded.Share,\n                                    contentDescription = stringResource(R.string.share)\n                                )\n                            }\n                        )\n                    } else {\n                        EnhancedFloatingActionButton(\n                            onClick = {\n                                openDirectoryLauncher.pickFolder(previousFolder)\n                            },\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            type = EnhancedFloatingActionButtonType.SecondaryHorizontal,\n                            content = {\n                                Icon(\n                                    imageVector = Icons.Rounded.FolderOpened,\n                                    contentDescription = stringResource(R.string.folder)\n                                )\n                            }\n                        )\n                    }\n                }\n            }\n\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n\n            ProcessImagesPreferenceSheet(\n                uris = selectedUris,\n                visible = wantToEdit,\n                onDismiss = {\n                    wantToEdit = false\n                },\n                onNavigate = component.onNavigate\n            )\n\n            ExitBackHandler(\n                enabled = !component.uris.isNullOrEmpty(),\n                onBack = onBack\n            )\n        }\n    }\n\n    LoadingDialog(\n        visible = isLoadingImages,\n        onCancelLoading = component::cancelImageLoading,\n        isForSaving = false\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog,\n        title = stringResource(id = R.string.image_preview),\n        text = stringResource(id = R.string.preview_closing),\n        icon = Icons.Outlined.ImageSearch\n    )\n}"
  },
  {
    "path": "feature/image-preview/src/main/java/com/t8rin/imagetoolbox/feature/image_preview/presentation/screenLogic/ImagePreviewComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_preview.presentation.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshots.SnapshotStateList\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.mapNotNull\nimport kotlinx.coroutines.withContext\n\nclass ImagePreviewComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val shareProvider: ShareProvider,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::updateUris)\n        }\n    }\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _imageFrames: MutableState<ImageFrames> = mutableStateOf(\n        ImageFrames.ManualSelection(\n            emptyList()\n        )\n    )\n    val imageFrames by _imageFrames\n\n    fun updateUris(uris: List<Uri>?) {\n        _uris.value = null\n        _uris.value = uris\n    }\n\n    fun shareImages(\n        uriList: List<Uri>?\n    ) = componentScope.launch {\n        uris?.let {\n            shareProvider.shareUris(\n                if (uriList.isNullOrEmpty()) {\n                    getSelectedUris()!!\n                } else {\n                    uriList\n                }.map { it.toString() }\n            )\n            AppToastHost.showConfetti()\n        }\n    }\n\n    fun getSelectedUris(): List<Uri>? {\n        val targetUris = uris ?: return null\n\n        val positions = imageFrames.getFramePositions(targetUris.size)\n\n        return targetUris.mapIndexedNotNull { index, uri ->\n            if (index + 1 in positions) uri\n            else null\n        }\n    }\n\n    fun removeUri(\n        uri: Uri\n    ) = _uris.update { it?.minus(uri) }\n\n    fun updateImageFrames(imageFrames: ImageFrames) {\n        _imageFrames.update { imageFrames }\n    }\n\n    fun updateUrisFromTree(uri: Uri) {\n        asyncUpdateUris { _ ->\n            withContext(ioDispatcher) {\n                val buffer = SnapshotStateList<Uri>()\n                _uris.update { buffer }\n\n                buildList {\n                    fileController.listFilesInDirectoryAsFlow(uri.toString())\n                        .mapNotNull { uri ->\n                            if (EXCLUDED.any { uri.endsWith(\".$it\", true) }) return@mapNotNull null\n\n                            uri.toUri().also {\n                                val mime = appContext.contentResolver.getType(it).orEmpty()\n\n                                if (\"audio\" in mime || \"video\" in mime) return@mapNotNull null\n                            }\n                        }\n                        .collect { uri ->\n                            add(uri)\n                            buffer.add(uri)\n                        }\n                }\n            }\n        }\n    }\n\n    fun asyncUpdateUris(\n        onFinish: suspend () -> Unit = {},\n        action: suspend (List<Uri>?) -> List<Uri>\n    ) {\n        debouncedImageCalculation(delay = 100, onFinish = onFinish) {\n            _uris.value = action(_uris.value)\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ImagePreviewComponent\n    }\n\n}\n\nprivate val EXCLUDED = listOf(\n    \"xml\",\n    \"mov\",\n    \"zip\",\n    \"apk\",\n    \"mp4\",\n    \"mp3\",\n    \"pdf\",\n    \"ldb\",\n    \"ttf\",\n    \"gz\",\n    \"rar\"\n)"
  },
  {
    "path": "feature/image-splitting/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/image-splitting/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.image_splitting\""
  },
  {
    "path": "feature/image-splitting/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/image-splitting/src/main/java/com/t8rin/imagetoolbox/image_splitting/data/AndroidImageSplitter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_splitting.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.image_splitting.domain.ImageSplitter\nimport com.t8rin.imagetoolbox.image_splitting.domain.SplitParams\nimport kotlinx.coroutines.Deferred\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidImageSplitter @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : ImageSplitter, DispatchersHolder by dispatchersHolder {\n\n    override suspend fun split(\n        imageUri: String,\n        params: SplitParams\n    ): List<String> = withContext(defaultDispatcher) {\n        if (params.columnsCount <= 1 && params.rowsCount <= 1) {\n            return@withContext listOf(imageUri)\n        }\n\n        val image = imageGetter.getImage(\n            data = imageUri,\n            originalSize = true\n        ) ?: return@withContext emptyList()\n\n        if (params.rowsCount <= 1) {\n            splitForColumns(\n                image = image,\n                count = params.columnsCount,\n                imageFormat = params.imageFormat,\n                quality = params.quality,\n                columnPercentages = params.columnPercentages,\n            )\n        } else if (params.columnsCount <= 1) {\n            splitForRows(\n                image = image,\n                count = params.rowsCount,\n                imageFormat = params.imageFormat,\n                quality = params.quality,\n                rowPercentages = params.rowPercentages\n            )\n        } else {\n            splitBoth(\n                image = image,\n                rowsCount = params.rowsCount,\n                columnsCount = params.columnsCount,\n                imageFormat = params.imageFormat,\n                quality = params.quality,\n                rowPercentages = params.rowPercentages,\n                columnPercentages = params.columnPercentages\n            )\n        }\n    }\n\n    private suspend fun splitBoth(\n        image: Bitmap,\n        rowsCount: Int,\n        columnsCount: Int,\n        imageFormat: ImageFormat,\n        quality: Quality,\n        rowPercentages: List<Float> = emptyList(),\n        columnPercentages: List<Float> = emptyList()\n    ): List<String> = withContext(defaultDispatcher) {\n        val rowHeights = calculatePartSizes(image.height, rowPercentages, rowsCount)\n        val uris = mutableListOf<Deferred<List<String>>>()\n\n        var currentY = 0\n        for (row in 0 until rowsCount) {\n            val height = rowHeights[row]\n            val rowBitmap = Bitmap.createBitmap(image, 0, currentY, image.width, height)\n\n            val rowUris = async {\n                splitForColumns(\n                    image = rowBitmap,\n                    count = columnsCount,\n                    imageFormat = imageFormat,\n                    quality = quality,\n                    columnPercentages = columnPercentages\n                )\n            }\n            uris.add(rowUris)\n            currentY += height\n        }\n\n        uris.flatMap { it.await() }\n    }\n\n    private suspend fun splitForRows(\n        image: Bitmap,\n        count: Int,\n        imageFormat: ImageFormat,\n        quality: Quality,\n        rowPercentages: List<Float> = emptyList()\n    ): List<String> = withContext(defaultDispatcher) {\n        val rowHeights = calculatePartSizes(image.height, rowPercentages, count)\n        val uris = mutableListOf<String?>()\n\n        var currentY = 0\n        for (i in 0 until count) {\n            val height = rowHeights[i]\n            val cell = Bitmap.createBitmap(image, 0, currentY, image.width, height)\n\n            uris.add(\n                shareProvider.cacheImage(\n                    image = cell,\n                    imageInfo = ImageInfo(\n                        height = cell.height,\n                        width = cell.width,\n                        imageFormat = imageFormat,\n                        quality = quality.coerceIn(imageFormat)\n                    )\n                )\n            )\n            currentY += height\n        }\n\n        uris.filterNotNull()\n    }\n\n    private suspend fun splitForColumns(\n        image: Bitmap,\n        count: Int,\n        imageFormat: ImageFormat,\n        quality: Quality,\n        columnPercentages: List<Float> = emptyList()\n    ): List<String> = withContext(defaultDispatcher) {\n        val columnWidths = calculatePartSizes(image.width, columnPercentages, count)\n        val uris = mutableListOf<String?>()\n\n        var currentX = 0\n        for (i in 0 until count) {\n            val width = columnWidths[i]\n            val cell = Bitmap.createBitmap(image, currentX, 0, width, image.height)\n\n            uris.add(\n                shareProvider.cacheImage(\n                    image = cell,\n                    imageInfo = ImageInfo(\n                        height = cell.height,\n                        width = cell.width,\n                        imageFormat = imageFormat,\n                        quality = quality.coerceIn(imageFormat)\n                    )\n                )\n            )\n            currentX += width\n        }\n        uris.filterNotNull()\n    }\n\n    private fun calculatePartSizes(\n        totalSize: Int,\n        percentages: List<Float>,\n        count: Int\n    ): List<Int> {\n        if (percentages.isEmpty()) {\n            val partSize = totalSize / count\n            return List(count) { index ->\n                if (index == count - 1) {\n                    totalSize - (partSize * (count - 1))\n                } else {\n                    partSize\n                }\n            }\n        }\n\n        val normalizedPercentages = if (percentages.size < count) {\n            val remainingPercentage = 1f - percentages.sum()\n            val remainingParts = count - percentages.size\n            val equalPercentage = remainingPercentage / remainingParts\n            percentages + List(remainingParts) { equalPercentage }\n        } else if (percentages.size > count) {\n            percentages.take(count)\n        } else {\n            percentages\n        }\n\n        val totalPercentage = normalizedPercentages.sum()\n        val normalized = normalizedPercentages.map { it / totalPercentage }\n\n        return normalized.map { percentage ->\n            (totalSize * percentage).toInt()\n        }.let { sizes ->\n            val calculatedTotal = sizes.sum()\n            if (calculatedTotal != totalSize) {\n                sizes.dropLast(1) + (totalSize - sizes.dropLast(1).sum())\n            } else {\n                sizes\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "feature/image-splitting/src/main/java/com/t8rin/imagetoolbox/image_splitting/di/ImageSplitterModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_splitting.di\n\nimport com.t8rin.imagetoolbox.image_splitting.data.AndroidImageSplitter\nimport com.t8rin.imagetoolbox.image_splitting.domain.ImageSplitter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ImageSplitterModule {\n\n    @Binds\n    @Singleton\n    fun splitter(\n        impl: AndroidImageSplitter\n    ): ImageSplitter\n\n}"
  },
  {
    "path": "feature/image-splitting/src/main/java/com/t8rin/imagetoolbox/image_splitting/domain/ImageSplitter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_splitting.domain\n\ninterface ImageSplitter {\n\n    suspend fun split(\n        imageUri: String,\n        params: SplitParams\n    ): List<String>\n\n}"
  },
  {
    "path": "feature/image-splitting/src/main/java/com/t8rin/imagetoolbox/image_splitting/domain/SplitParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_splitting.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ndata class SplitParams(\n    val rowsCount: Int,\n    val columnsCount: Int,\n    val rowPercentages: List<Float>,\n    val columnPercentages: List<Float>,\n    val imageFormat: ImageFormat,\n    val quality: Quality,\n) {\n    fun withAspectRatio(\n        targetAspectRatio: Float,\n        maxRows: Int = rowsCount,\n        maxColumns: Int = columnsCount\n    ): SplitParams {\n        require(targetAspectRatio > 0f) { \"aspectRatio must be > 0\" }\n\n        var bestRows = 1\n        var bestCols = 1\n\n        for (rows in 1..maxRows) {\n            val tileHeight = 1f / rows\n            val tileWidth = tileHeight * targetAspectRatio\n            val cols = (1f / tileWidth).toInt()\n            if (cols in 1..maxColumns) {\n                bestRows = rows\n                bestCols = cols\n            }\n        }\n\n        val rowsCount = bestRows\n        val columnsCount = bestCols\n\n        val rowPercentages = List(rowsCount) { 1f / rowsCount }.let { rows ->\n            rows.dropLast(1) + (1f - rows.dropLast(1).sum())\n        }\n\n        val columnPercentages = List(columnsCount) { 1f / columnsCount }.let { cols ->\n            cols.dropLast(1) + (1f - cols.dropLast(1).sum())\n        }\n\n\n        return this.copy(\n            rowsCount = rowsCount,\n            columnsCount = columnsCount,\n            rowPercentages = rowPercentages,\n            columnPercentages = columnPercentages\n        )\n    }\n\n    companion object {\n        val Default by lazy {\n            SplitParams(\n                rowsCount = 2,\n                columnsCount = 2,\n                rowPercentages = emptyList(),\n                columnPercentages = emptyList(),\n                imageFormat = ImageFormat.Default,\n                quality = Quality.Base()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/image-splitting/src/main/java/com/t8rin/imagetoolbox/image_splitting/presentation/ImageSplitterContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_splitting.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.image_splitting.presentation.components.SplitParamsSelector\nimport com.t8rin.imagetoolbox.image_splitting.presentation.screenLogic.ImageSplitterComponent\n\n@Composable\nfun ImageSplitterContent(\n    component: ImageSplitterComponent\n) {\n    val imagePicker = rememberImagePicker(onSuccess = component::updateUri)\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    @Composable\n    fun ImagePreview(showUrisPreview: Boolean) {\n        if (showUrisPreview) {\n            var aspectRatio by remember {\n                mutableFloatStateOf(2f / 1f)\n            }\n            Picture(\n                model = component.uri,\n                contentDescription = null,\n                modifier = Modifier\n                    .padding(top = if (isPortrait) 20.dp else 0.dp)\n                    .heightIn(max = 200.dp)\n                    .aspectRatio(aspectRatio)\n                    .container()\n                    .padding(4.dp)\n                    .clip(MaterialTheme.shapes.medium),\n                onSuccess = {\n                    aspectRatio = it.result.image.toBitmap().safeAspectRatio\n                }\n            )\n        } else {\n            UrisPreview(\n                uris = component.uris.ifEmpty {\n                    listOf(Uri.EMPTY, Uri.EMPTY)\n                },\n                modifier = Modifier\n                    .animateContentSizeNoClip()\n                    .padding(2.dp),\n                isPortrait = true,\n                onRemoveUri = null,\n                onAddUris = null,\n                isAddUrisVisible = component.isImageLoading,\n                addUrisContent = { width ->\n                    Box(\n                        modifier = Modifier.fillMaxSize(),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        EnhancedLoadingIndicator(modifier = Modifier.size(width / 2))\n                    }\n                },\n                onNavigate = component.onNavigate\n            )\n        }\n    }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.image_splitting),\n                input = component.uri,\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.uri != null,\n                onShare = component::shareBitmaps,\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        showImagePreviewAsStickyHeader = false,\n        imagePreview = {\n            ImagePreview(isPortrait)\n        },\n        controls = {\n            Spacer(Modifier.height(8.dp))\n            ImagePreview(!isPortrait)\n            Spacer(Modifier.height(8.dp))\n            val params = component.params\n            SplitParamsSelector(\n                value = params,\n                onValueChange = component::updateParams\n            )\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.uri == null) TopAppBarEmoji()\n        },\n        canShowScreenData = component.uri != null,\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        }\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris.size,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/image-splitting/src/main/java/com/t8rin/imagetoolbox/image_splitting/presentation/components/SplitParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_splitting.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CheckCircle\nimport androidx.compose.material.icons.rounded.Percent\nimport androidx.compose.material.icons.rounded.TableRows\nimport androidx.compose.material.icons.rounded.ViewColumn\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.image_splitting.domain.SplitParams\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun SplitParamsSelector(\n    value: SplitParams,\n    onValueChange: (SplitParams) -> Unit\n) {\n    var recomputeTrigger by remember {\n        mutableIntStateOf(0)\n    }\n    var rowsCount by remember(recomputeTrigger) {\n        mutableIntStateOf(value.rowsCount)\n    }\n    var columnsCount by remember(recomputeTrigger) {\n        mutableIntStateOf(value.columnsCount)\n    }\n\n    Column(\n        modifier = Modifier.container(\n            shape = ShapeDefaults.top\n        )\n    ) {\n        Row(\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            TitleItem(\n                text = stringResource(R.string.compute_percents),\n                icon = Icons.Rounded.Percent,\n                modifier = Modifier.padding(\n                    start = 12.dp,\n                    top = 8.dp,\n                    bottom = 4.dp,\n                    end = 12.dp\n                )\n            )\n        }\n\n        var aspectRatio by rememberSaveable {\n            mutableStateOf(\"\")\n        }\n        val focus = LocalFocusManager.current\n\n        val computed by remember(aspectRatio) {\n            derivedStateOf {\n                aspectRatio\n                    .replace(',', '.')\n                    .filter { it.isDigit() || it == '.' }\n                    .takeIf { it.isNotEmpty() }\n                    ?.toFloatOrNull() ?: 0f\n            }\n        }\n        val scope = rememberCoroutineScope()\n\n        RoundedTextField(\n            value = aspectRatio,\n            onValueChange = { text ->\n                aspectRatio = text\n            },\n            hint = {\n                Text(1f.toString())\n            },\n            label = {\n                Text(stringResource(R.string.aspect_ratio))\n            },\n            endIcon = {\n                AnimatedVisibility(\n                    visible = computed > 0f,\n                    enter = scaleIn() + fadeIn(),\n                    exit = scaleOut() + fadeOut()\n                ) {\n                    EnhancedIconButton(\n                        onClick = {\n                            onValueChange(\n                                value.withAspectRatio(computed)\n                            )\n                            aspectRatio = \"\"\n                            scope.launch {\n                                delay(200)\n                                recomputeTrigger++\n                                focus.clearFocus()\n                            }\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.CheckCircle,\n                            contentDescription = null\n                        )\n                    }\n                }\n            },\n            modifier = Modifier.padding(12.dp)\n        )\n    }\n    Spacer(Modifier.height(4.dp))\n    EnhancedSliderItem(\n        value = rowsCount,\n        title = stringResource(R.string.rows_count),\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        icon = Icons.Rounded.TableRows,\n        valueRange = 1f..20f,\n        steps = 18,\n        internalStateTransformation = {\n            it.roundToInt()\n        },\n        onValueChangeFinished = {\n            onValueChange(\n                value.copy(rowsCount = it.roundToInt())\n            )\n            rowsCount = it.roundToInt()\n        },\n        onValueChange = {},\n        shape = ShapeDefaults.center,\n        additionalContent = if (rowsCount > 1) {\n            {\n                PercentagesField(\n                    totalSize = rowsCount,\n                    percentageValues = value.rowPercentages,\n                    onValueChange = {\n                        onValueChange(\n                            value.copy(\n                                rowPercentages = it\n                            )\n                        )\n                    }\n                )\n            }\n        } else null\n    )\n    Spacer(Modifier.height(4.dp))\n    EnhancedSliderItem(\n        value = columnsCount,\n        title = stringResource(R.string.columns_count),\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        steps = 18,\n        icon = Icons.Rounded.ViewColumn,\n        valueRange = 1f..20f,\n        internalStateTransformation = {\n            it.roundToInt()\n        },\n        onValueChangeFinished = {\n            onValueChange(\n                value.copy(columnsCount = it.roundToInt())\n            )\n            columnsCount = it.roundToInt()\n        },\n        onValueChange = {},\n        shape = ShapeDefaults.bottom,\n        additionalContent = if (columnsCount > 1) {\n            {\n                PercentagesField(\n                    totalSize = columnsCount,\n                    percentageValues = value.columnPercentages,\n                    onValueChange = {\n                        onValueChange(\n                            value.copy(\n                                columnPercentages = it\n                            )\n                        )\n                    }\n                )\n            }\n        } else null\n    )\n    if (value.imageFormat.canChangeCompressionValue) {\n        Spacer(Modifier.height(8.dp))\n    }\n    QualitySelector(\n        imageFormat = value.imageFormat,\n        quality = value.quality,\n        onQualityChange = {\n            onValueChange(\n                value.copy(quality = it)\n            )\n        }\n    )\n    Spacer(Modifier.height(8.dp))\n    ImageFormatSelector(\n        value = value.imageFormat,\n        onValueChange = {\n            onValueChange(\n                value.copy(imageFormat = it)\n            )\n        },\n        quality = value.quality,\n    )\n}\n\n@Composable\nprivate fun PercentagesField(\n    totalSize: Int,\n    percentageValues: List<Float>,\n    onValueChange: (List<Float>) -> Unit\n) {\n    val default by remember(totalSize) {\n        derivedStateOf {\n            List(totalSize) { 1f / totalSize }.joinToString(\"/\") {\n                it.roundToTwoDigits().toString()\n            }\n        }\n    }\n    var percentages by remember {\n        mutableStateOf(\n            percentageValues.joinToString(\"/\") {\n                it.roundToTwoDigits().toString()\n            }\n        )\n    }\n\n    LaunchedEffect(percentageValues, totalSize) {\n        if (percentageValues.size > totalSize) {\n            percentages = percentageValues.take(totalSize).joinToString(\"/\") {\n                it.roundToTwoDigits().toString()\n            }\n        }\n    }\n\n    LaunchedEffect(percentages) {\n        onValueChange(\n            percentages.split(\"/\").mapNotNull { it.toFloatOrNull() }\n        )\n    }\n\n    Row(\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        TitleItem(\n            text = stringResource(R.string.part_percents),\n            icon = Icons.Rounded.Percent,\n            modifier = Modifier.padding(\n                start = 12.dp,\n                top = 8.dp,\n                bottom = 4.dp,\n                end = 12.dp\n            )\n        )\n    }\n\n    RoundedTextField(\n        value = percentages,\n        onValueChange = {\n            percentages = it\n        },\n        hint = {\n            Text(text = default)\n        },\n        modifier = Modifier.padding(12.dp)\n    )\n}"
  },
  {
    "path": "feature/image-splitting/src/main/java/com/t8rin/imagetoolbox/image_splitting/presentation/screenLogic/ImageSplitterComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.image_splitting.presentation.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.image_splitting.domain.ImageSplitter\nimport com.t8rin.imagetoolbox.image_splitting.domain.SplitParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass ImageSplitterComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageSplitter: ImageSplitter,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::updateUri)\n        }\n    }\n\n    private val _uri = mutableStateOf<Uri?>(null)\n    val uri by _uri\n\n    private val _uris = mutableStateOf<List<Uri>>(emptyList())\n    val uris by _uris\n\n    private val _params: MutableState<SplitParams> = mutableStateOf(SplitParams.Default)\n    val params: SplitParams by _params\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n\n    private fun updateUris() {\n        if (uri == null) return\n\n        debouncedImageCalculation {\n            _uris.update {\n                imageSplitter.split(\n                    imageUri = uri!!.toString(),\n                    params = params\n                ).map { it.toUri() }\n            }\n        }\n    }\n\n    fun updateUri(uri: Uri?) {\n        _uri.value = null\n        _uri.value = uri\n        updateUris()\n    }\n\n    fun updateParams(params: SplitParams) {\n        if (params != this.params) {\n            _params.update { params }\n            registerChanges()\n            updateUris()\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            uris.forEach { uri ->\n                results.add(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = ImageInfo(\n                                imageFormat = params.imageFormat,\n                                quality = params.quality,\n                                originalUri = uri.toString()\n                            ),\n                            metadata = null,\n                            originalUri = uri.toString(),\n                            sequenceNumber = _done.value + 1,\n                            data = fileController.readBytes(uri.toString())\n                        ),\n                        keepOriginalMetadata = false,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    )\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.size\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n\n    fun shareBitmaps() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            shareProvider.shareUris(\n                uris = uris.map { it.toString() }\n            )\n            AppToastHost.showConfetti()\n            _isSaving.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            onComplete(uris)\n            _isSaving.value = false\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ImageSplitterComponent\n    }\n\n}"
  },
  {
    "path": "feature/image-stacking/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/image-stacking/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.image_stacking\""
  },
  {
    "path": "feature/image-stacking/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/data/AndroidImageStacker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.data\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.toPaint\nimport com.t8rin.imagetoolbox.core.data.utils.getSuitableConfig\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeAnchor\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.ImageStacker\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.StackImage\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.StackingParams\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidImageStacker @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, ImageStacker<Bitmap> {\n\n    override suspend fun stackImages(\n        stackImages: List<StackImage>,\n        stackingParams: StackingParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: (Int) -> Unit\n    ): Bitmap? = withContext(defaultDispatcher) {\n        val resultSize = stackingParams.size\n            ?: imageGetter.getImage(\n                data = stackImages.firstOrNull()?.uri ?: \"\",\n                originalSize = true\n            )?.let {\n                IntegerSize(it.width, it.height)\n            } ?: IntegerSize(0, 0)\n\n        if (resultSize.width <= 0 || resultSize.height <= 0) {\n            onFailure(IllegalArgumentException(\"Width and height must be > 0\"))\n            return@withContext null\n        }\n\n        createBitmap(\n            width = resultSize.width,\n            height = resultSize.height,\n            config = getSuitableConfig()\n        ).applyCanvas {\n            stackImages.forEachIndexed { index, stackImage ->\n                val bitmap = imageGetter.getImage(\n                    data = stackImage.uri\n                )?.let { bitmap ->\n                    bitmap.setHasAlpha(true)\n\n                    val resizeType = when (stackImage.scale) {\n                        StackImage.Scale.None -> null\n                        StackImage.Scale.Fill -> ResizeType.Explicit\n                        StackImage.Scale.Fit -> ResizeType.Flexible(ResizeAnchor.Min)\n                        StackImage.Scale.FitWidth -> ResizeType.Flexible(ResizeAnchor.Width)\n                        StackImage.Scale.FitHeight -> ResizeType.Flexible(ResizeAnchor.Height)\n                        StackImage.Scale.Crop -> ResizeType.CenterCrop(0x00000000)\n                    }\n\n                    resizeType?.let {\n                        imageScaler.scaleImage(\n                            image = bitmap,\n                            width = resultSize.width,\n                            height = resultSize.height,\n                            resizeType = resizeType\n                        )\n                    } ?: bitmap\n                }\n\n                bitmap?.let {\n                    drawBitmap(\n                        bitmap = it,\n                        position = stackImage.position,\n                        paint = stackImage.blendingMode.toPaint().apply {\n                            alpha = (stackImage.alpha * 255).toInt()\n                        }\n                    )\n                }\n\n                onProgress(index + 1)\n            }\n        }\n    }\n\n    override suspend fun stackImagesPreview(\n        stackImages: List<StackImage>,\n        stackingParams: StackingParams,\n        imageFormat: ImageFormat,\n        quality: Quality,\n        onGetByteCount: (Int) -> Unit\n    ): Bitmap? = withContext(defaultDispatcher) {\n        stackImages(\n            stackImages = stackImages,\n            stackingParams = stackingParams,\n            onProgress = {},\n            onFailure = {}\n        )?.let { image ->\n            val imageSize = IntegerSize(\n                width = image.width,\n                height = image.height\n            )\n            return@let imagePreviewCreator.createPreview(\n                image = image,\n                imageInfo = ImageInfo(\n                    width = imageSize.width,\n                    height = imageSize.height,\n                    imageFormat = imageFormat,\n                    quality = quality\n                ),\n                transformations = emptyList(),\n                onGetByteCount = onGetByteCount\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/di/ImageStackingModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.image_stacking.data.AndroidImageStacker\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.ImageStacker\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ImageStackingModule {\n\n    @Binds\n    @Singleton\n    fun provideImageStacker(stackerImpl: AndroidImageStacker): ImageStacker<Bitmap>\n\n}"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/domain/ImageStacker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\n\ninterface ImageStacker<I> {\n\n    suspend fun stackImages(\n        stackImages: List<StackImage>,\n        stackingParams: StackingParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: (Int) -> Unit\n    ): I?\n\n    suspend fun stackImagesPreview(\n        stackImages: List<StackImage>,\n        stackingParams: StackingParams,\n        imageFormat: ImageFormat,\n        quality: Quality,\n        onGetByteCount: (Int) -> Unit\n    ): I?\n\n}"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/domain/StackImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.model.Position\n\ndata class StackImage(\n    val uri: String,\n    val alpha: Float,\n    val blendingMode: BlendingMode,\n    val position: Position,\n    val scale: Scale\n) {\n    enum class Scale {\n        None, Fill, Fit, FitWidth, FitHeight, Crop\n    }\n}\n\nfun String.toStackImage() = StackImage(\n    uri = this,\n    alpha = 1f,\n    blendingMode = BlendingMode.SrcOver,\n    position = Position.TopLeft,\n    scale = StackImage.Scale.Fit\n)"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/domain/StackingParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ndata class StackingParams(\n    val size: IntegerSize?\n) {\n\n    companion object {\n        val Default by lazy {\n            StackingParams(size = null)\n        }\n    }\n\n}"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/presentation/ImageStackingContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AddCircleOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageReorderCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.StackImage\nimport com.t8rin.imagetoolbox.feature.image_stacking.presentation.components.StackImageItem\nimport com.t8rin.imagetoolbox.feature.image_stacking.presentation.components.StackingParamsSelector\nimport com.t8rin.imagetoolbox.feature.image_stacking.presentation.screenLogic.ImageStackingComponent\n\n@Composable\nfun ImageStackingContent(\n    component: ImageStackingComponent\n) {\n    AutoContentBasedColors(component.previewBitmap)\n\n    val imagePicker = rememberImagePicker(onSuccess = component::updateUris)\n\n    val addImagesImagePicker = rememberImagePicker(onSuccess = component::addUrisToEnd)\n\n    val addImages = addImagesImagePicker::pickImage\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.image_stacking),\n                input = component.stackImages,\n                isLoading = component.isImageLoading,\n                size = component.imageByteSize?.toLong(),\n                updateOnSizeChange = false\n            )\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.previewBitmap != null,\n                onShare = component::shareBitmap,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheCurrentImage {\n                        editSheetData = listOf(it)\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.previewBitmap != null,\n            )\n        },\n        imagePreview = {\n            ImageContainer(\n                imageInside = isPortrait,\n                showOriginal = false,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = null,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = true\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.stackImages.isEmpty()) {\n                TopAppBarEmoji()\n            }\n        },\n        controls = {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                ImageReorderCarousel(\n                    images = remember(component.stackImages) {\n                        derivedStateOf {\n                            component.stackImages.map { it.uri.toUri() }\n                        }\n                    }.value,\n                    onReorder = component::reorderUris,\n                    onNeedToAddImage = addImages,\n                    onNeedToRemoveImageAt = component::removeImageAt,\n                    onNavigate = component.onNavigate\n                )\n                StackingParamsSelector(\n                    value = component.stackingParams,\n                    onValueChange = component::updateParams\n                )\n                Column(Modifier.container(MaterialTheme.shapes.extraLarge)) {\n                    TitleItem(\n                        text = stringResource(\n                            R.string.images,\n                            component.stackImages.size\n                        )\n                    )\n                    Column(\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.spacedBy(4.dp),\n                        modifier = Modifier.padding(8.dp)\n                    ) {\n                        component.stackImages.forEachIndexed { index, stackImage ->\n                            StackImageItem(\n                                backgroundColor = MaterialTheme.colorScheme.surface,\n                                stackImage = stackImage,\n                                index = index,\n                                onStackImageChange = { image: StackImage ->\n                                    component.updateStackImage(\n                                        value = image,\n                                        index = index\n                                    )\n                                },\n                                isRemoveVisible = component.stackImages.size > 2,\n                                onRemove = {\n                                    component.removeImageAt(index)\n                                },\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = component.stackImages.size\n                                )\n                            )\n                        }\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.mixedContainer,\n                            onClick = addImages,\n                            modifier = Modifier\n                                .padding(top = 4.dp)\n                                .padding(\n                                    horizontal = 16.dp\n                                )\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.AddCircleOutline,\n                                contentDescription = stringResource(R.string.add_image)\n                            )\n                            Spacer(Modifier.width(8.dp))\n                            Text(stringResource(id = R.string.add_image))\n                        }\n                    }\n                }\n                QualitySelector(\n                    imageFormat = component.imageInfo.imageFormat,\n                    quality = component.imageInfo.quality,\n                    onQualityChange = component::setQuality\n                )\n                ImageFormatSelector(\n                    value = component.imageInfo.imageFormat,\n                    onValueChange = component::setImageFormat,\n                    quality = component.imageInfo.quality,\n                )\n            }\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.stackImages.isEmpty(),\n                isPrimaryButtonVisible = component.stackImages.isNotEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        },\n        canShowScreenData = component.stackImages.isNotEmpty()\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.stackImages.size,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/presentation/components/StackImageItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectLarge\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material.icons.rounded.RemoveCircleOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.BlendingModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PositionSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.StackImage\n\n@Composable\nfun StackImageItem(\n    stackImage: StackImage,\n    index: Int,\n    onRemove: () -> Unit,\n    modifier: Modifier = Modifier,\n    onStackImageChange: (StackImage) -> Unit,\n    isRemoveVisible: Boolean,\n    backgroundColor: Color = Color.Unspecified,\n    shape: Shape = MaterialTheme.shapes.extraLarge\n) {\n    var isControlsExpanded by rememberSaveable {\n        mutableStateOf(true)\n    }\n\n    Row(\n        modifier = modifier\n            .container(color = backgroundColor, shape = shape)\n            .animateContentSizeNoClip(),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Column(\n            modifier = Modifier.weight(1f)\n        ) {\n            Row(verticalAlignment = Alignment.CenterVertically) {\n                if (!isRemoveVisible) {\n                    EnhancedIconButton(\n                        onClick = onRemove\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.RemoveCircleOutline,\n                            contentDescription = stringResource(R.string.remove)\n                        )\n                    }\n                }\n                Row(\n                    modifier = Modifier\n                        .weight(1f)\n                        .padding(\n                            top = 8.dp,\n                            end = 8.dp,\n                            start = 16.dp,\n                            bottom = 8.dp\n                        ),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Box(\n                        contentAlignment = Alignment.Center,\n                        modifier = Modifier.clip(MaterialTheme.shapes.small)\n                    ) {\n                        Picture(\n                            model = stackImage.uri,\n                            shape = RectangleShape,\n                            modifier = Modifier\n                                .height(56.dp)\n                                .width(112.dp)\n                        )\n                        Box(\n                            Modifier\n                                .matchParentSize()\n                                .background(\n                                    color = MaterialTheme.colorScheme.surfaceContainer.copy(\n                                        alpha = 0.3f\n                                    )\n                                ),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            Text(\n                                text = \"${index + 1}\",\n                                color = MaterialTheme.colorScheme.onSurface,\n                                fontSize = 20.sp,\n                                fontWeight = FontWeight.Bold\n                            )\n                        }\n                    }\n\n                }\n                EnhancedIconButton(\n                    onClick = {\n                        isControlsExpanded = !isControlsExpanded\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.KeyboardArrowDown,\n                        contentDescription = \"Expand\",\n                        modifier = Modifier.rotate(\n                            animateFloatAsState(\n                                if (isControlsExpanded) 180f\n                                else 0f\n                            ).value\n                        )\n                    )\n                }\n            }\n            AnimatedVisibility(\n                visible = isControlsExpanded\n            ) {\n                Column(\n                    modifier = Modifier.padding(8.dp)\n                ) {\n                    AlphaSelector(\n                        value = stackImage.alpha,\n                        onValueChange = {\n                            onStackImageChange(\n                                stackImage.copy(alpha = it)\n                            )\n                        },\n                        modifier = Modifier.fillMaxWidth(),\n                        shape = ShapeDefaults.top\n                    )\n                    Spacer(modifier = Modifier.height(4.dp))\n                    BlendingModeSelector(\n                        value = stackImage.blendingMode,\n                        onValueChange = {\n                            onStackImageChange(\n                                stackImage.copy(blendingMode = it)\n                            )\n                        },\n                        color = Color.Unspecified,\n                        shape = ShapeDefaults.center\n                    )\n                    Spacer(modifier = Modifier.height(4.dp))\n                    PositionSelector(\n                        value = stackImage.position,\n                        onValueChange = {\n                            onStackImageChange(\n                                stackImage.copy(position = it)\n                            )\n                        },\n                        color = Color.Unspecified,\n                        shape = ShapeDefaults.center\n                    )\n                    Spacer(modifier = Modifier.height(4.dp))\n                    DataSelector(\n                        value = stackImage.scale,\n                        onValueChange = {\n                            onStackImageChange(\n                                stackImage.copy(scale = it)\n                            )\n                        },\n                        entries = StackImage.Scale.entries,\n                        spanCount = 1,\n                        title = stringResource(R.string.scale),\n                        titleIcon = Icons.Outlined.PhotoSizeSelectLarge,\n                        itemContentText = {\n                            it.title()\n                        },\n                        containerColor = Color.Unspecified,\n                        shape = ShapeDefaults.bottom\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun StackImage.Scale.title(): String = when (this) {\n    StackImage.Scale.None -> stringResource(R.string.none)\n    StackImage.Scale.Fill -> stringResource(R.string.fill)\n    StackImage.Scale.Fit -> stringResource(R.string.fit)\n    StackImage.Scale.FitWidth -> stringResource(R.string.fit_width)\n    StackImage.Scale.FitHeight -> stringResource(R.string.fit_height)\n    StackImage.Scale.Crop -> stringResource(R.string.crop)\n}"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/presentation/components/StackingParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectLarge\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.StackingParams\n\n@Composable\ninternal fun StackingParamsSelector(\n    value: StackingParams,\n    onValueChange: (StackingParams) -> Unit,\n) {\n    Column {\n        val size = value.size ?: IntegerSize.Undefined\n        AnimatedVisibility(size.isDefined()) {\n            ResizeImageField(\n                imageInfo = ImageInfo(size.width, size.height),\n                originalSize = null,\n                onWidthChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(width = it)\n                        )\n                    )\n                },\n                onHeightChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(height = it)\n                        )\n                    )\n                }\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.use_size_of_first_frame),\n            subtitle = stringResource(id = R.string.use_size_of_first_frame_sub),\n            checked = value.size == null,\n            onClick = {\n                onValueChange(\n                    value.copy(size = if (it) null else IntegerSize(1000, 1000))\n                )\n            },\n            startIcon = Icons.Outlined.PhotoSizeSelectLarge,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n    }\n}"
  },
  {
    "path": "feature/image-stacking/src/main/java/com/t8rin/imagetoolbox/feature/image_stacking/presentation/screenLogic/ImageStackingComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stacking.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.ImageStacker\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.StackImage\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.StackingParams\nimport com.t8rin.imagetoolbox.feature.image_stacking.domain.toStackImage\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\n\nclass ImageStackingComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageStacker: ImageStacker<Bitmap>,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::updateUris)\n        }\n    }\n\n    private val _stackImages: MutableState<List<StackImage>> = mutableStateOf(emptyList())\n    val stackImages by _stackImages\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    fun updateUris(uris: List<Uri>) {\n        _stackImages.value = uris.map { it.toString().toStackImage() }\n        if (uris.isNotEmpty()) {\n            calculatePreview()\n        }\n    }\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _stackingParams: MutableState<StackingParams> =\n        mutableStateOf(StackingParams.Default)\n    val stackingParams by _stackingParams\n\n    private val _imageInfo = mutableStateOf(ImageInfo(imageFormat = ImageFormat.Png.Lossless))\n    val imageInfo by _imageInfo\n\n    private val _imageByteSize: MutableState<Int?> = mutableStateOf(null)\n    val imageByteSize by _imageByteSize\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageInfo.value = _imageInfo.value.copy(imageFormat = imageFormat)\n        calculatePreview()\n    }\n\n    private var calculationPreviewJob: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    private fun calculatePreview() {\n        calculationPreviewJob = componentScope.launch {\n            delay(300L)\n            _isImageLoading.value = true\n            stackImages.takeIf { it.isNotEmpty() }?.let {\n                registerChanges()\n                imageStacker.stackImagesPreview(\n                    stackImages = stackImages,\n                    stackingParams = stackingParams,\n                    imageFormat = imageInfo.imageFormat,\n                    quality = imageInfo.quality,\n                    onGetByteCount = {\n                        _imageByteSize.update { it }\n                    }\n                ).let { image ->\n                    _previewBitmap.value = image\n                }\n            }\n            _isImageLoading.value = false\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            imageStacker.stackImages(\n                stackImages = stackImages,\n                stackingParams = stackingParams,\n                onFailure = {\n                    parseSaveResult(SaveResult.Error.Exception(it))\n                },\n                onProgress = {\n                    _done.value = it\n                    updateProgress(\n                        done = done,\n                        total = stackImages.size\n                    )\n                }\n            )?.let { image ->\n                val imageInfo = ImageInfo(\n                    height = image.height,\n                    width = image.width,\n                    quality = imageInfo.quality,\n                    imageFormat = imageInfo.imageFormat\n                )\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = imageInfo,\n                            metadata = null,\n                            originalUri = \"Stacked\",\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = image,\n                                imageInfo = imageInfo\n                            )\n                        ),\n                        keepOriginalMetadata = true,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun shareBitmap() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            imageStacker.stackImages(\n                stackImages = stackImages,\n                stackingParams = stackingParams,\n                onProgress = {\n                    _done.value = it\n                    updateProgress(\n                        done = done,\n                        total = stackImages.size\n                    )\n                },\n                onFailure = AppToastHost::showFailureToast\n            )?.let { image ->\n                val imageInfo = ImageInfo(\n                    height = image.height,\n                    width = image.width,\n                    quality = imageInfo.quality,\n                    imageFormat = imageInfo.imageFormat\n                )\n                shareProvider.shareImage(\n                    image = image,\n                    imageInfo = imageInfo,\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        _imageInfo.value = _imageInfo.value.copy(quality = quality)\n        calculatePreview()\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun addUrisToEnd(uris: List<Uri>) {\n        _stackImages.update { list ->\n            list + uris.map { it.toString().toStackImage() }.filter { it !in list }\n        }\n        calculatePreview()\n    }\n\n    fun removeImageAt(index: Int) {\n        _stackImages.update { list ->\n            list.toMutableList().apply {\n                removeAt(index)\n            }.takeIf { it.size >= 2 }.also {\n                if (it == null) _previewBitmap.value = null\n            } ?: emptyList()\n        }\n        calculatePreview()\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            imageStacker.stackImages(\n                stackImages = stackImages,\n                stackingParams = stackingParams,\n                onProgress = {\n                    _done.value = it\n                    updateProgress(\n                        done = done,\n                        total = stackImages.size\n                    )\n                },\n                onFailure = {}\n            )?.let { image ->\n                val imageInfo = ImageInfo(\n                    height = image.height,\n                    width = image.width,\n                    quality = imageInfo.quality,\n                    imageFormat = imageInfo.imageFormat\n                )\n\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun updateParams(\n        newParams: StackingParams\n    ) {\n        _stackingParams.update { newParams }\n        calculatePreview()\n    }\n\n    fun updateStackImage(\n        value: StackImage,\n        index: Int\n    ) {\n        val list = stackImages.toMutableList()\n        runCatching {\n            list[index] = value\n            _stackImages.update { list }\n        }.onFailure(AppToastHost::showFailureToast)\n\n        calculatePreview()\n    }\n\n    fun reorderUris(uris: List<Uri>) {\n        if (stackImages.map { it.uri } != uris) {\n            _stackImages.update { stack ->\n                val stackOrder = uris.map { it.toString() }\n                val data = stack.associateBy { it.uri }\n                val leftStack = stack.filter { it.uri !in stackOrder }\n                (leftStack + stackOrder.mapNotNull { data[it] }).distinct()\n            }\n            calculatePreview()\n        }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageInfo.imageFormat\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ImageStackingComponent\n    }\n\n}"
  },
  {
    "path": "feature/image-stitch/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/image-stitch/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.image_stitch\"\n\ndependencies {\n    implementation(projects.core.filters)\n    implementation(projects.lib.opencvTools)\n    implementation(libs.trickle)\n}"
  },
  {
    "path": "feature/image-stitch/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/data/AndroidImageCombiner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.data\n\nimport android.graphics.Bitmap\nimport android.graphics.Paint\nimport android.graphics.PorterDuff\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.toPaint\nimport com.t8rin.imagetoolbox.core.data.utils.aspectRatio\nimport com.t8rin.imagetoolbox.core.data.utils.getSuitableConfig\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageWithSize\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.withSize\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.createFilter\nimport com.t8rin.imagetoolbox.core.filters.domain.model.enums.FadeSide\nimport com.t8rin.imagetoolbox.core.filters.domain.model.params.SideFadeParams\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.CombiningParams\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.ImageCombiner\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchAlignment\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchFadeSide\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchMode\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.math.absoluteValue\nimport kotlin.math.max\nimport kotlin.math.roundToInt\nimport kotlin.math.roundToLong\n\ninternal class AndroidImageCombiner @Inject constructor(\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val cvStitchHelper: CvStitchHelper,\n    settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, ImageCombiner<Bitmap> {\n\n    private val _settingsState = settingsProvider.settingsState\n    private val settingsState get() = _settingsState.value\n\n    override suspend fun combineImages(\n        imageUris: List<String>,\n        combiningParams: CombiningParams,\n        onProgress: (Int) -> Unit\n    ): Pair<Bitmap, ImageInfo> = withContext(defaultDispatcher) {\n        if (combiningParams.stitchMode is StitchMode.Auto) {\n            return@withContext cvStitchHelper.cvCombine(\n                imageUris = imageUris,\n                combiningParams = combiningParams\n            )\n        }\n\n        suspend fun getImageData(\n            imagesUris: List<String>,\n            isHorizontal: Boolean\n        ): Pair<Bitmap, ImageInfo> {\n            val (size, images) = calculateCombinedImageDimensionsAndBitmaps(\n                imageUris = imagesUris,\n                isHorizontal = isHorizontal,\n                scaleSmallImagesToLarge = combiningParams.scaleSmallImagesToLarge,\n                imageSpacing = combiningParams.spacing,\n                imageScale = combiningParams.outputScale\n            )\n\n            val bitmaps = images.map { image ->\n                if (\n                    combiningParams.scaleSmallImagesToLarge && image.shouldUpscale(\n                        isHorizontal = isHorizontal,\n                        size = size\n                    )\n                ) {\n                    image.upscale(isHorizontal, size)\n                } else image\n            }\n\n            val bitmap = createBitmap(\n                width = size.width,\n                height = size.height,\n                config = getSuitableConfig()\n            ).applyCanvas {\n                drawColor(Color.Transparent.toArgb(), PorterDuff.Mode.CLEAR)\n                drawColor(combiningParams.backgroundColor)\n\n                var pos = 0\n\n                val fullSpace = combiningParams.spacing.absoluteValue\n                val halfSpace = fullSpace / 2\n                val strength = combiningParams.fadeStrength\n\n                for (i in imagesUris.indices) {\n                    var bmp = bitmaps[i]\n\n                    combiningParams.spacing.takeIf { it < 0 && combiningParams.fadingEdgesMode != StitchFadeSide.None }\n                        ?.let {\n                            val filters = when (combiningParams.fadingEdgesMode) {\n                                StitchFadeSide.Start -> {\n                                    when (i) {\n                                        0 -> emptyList()\n                                        else -> listOf(\n                                            createFilter<SideFadeParams, Filter.SideFade>(\n                                                SideFadeParams.Absolute(\n                                                    side = if (isHorizontal) FadeSide.Start else FadeSide.Top,\n                                                    size = fullSpace,\n                                                    strength = strength\n                                                )\n                                            )\n                                        )\n                                    }\n                                }\n\n                                StitchFadeSide.End -> {\n                                    when (i) {\n                                        imagesUris.lastIndex -> emptyList()\n                                        else -> listOf(\n                                            createFilter<SideFadeParams, Filter.SideFade>(\n                                                SideFadeParams.Absolute(\n                                                    side = if (isHorizontal) FadeSide.End else FadeSide.Bottom,\n                                                    size = fullSpace,\n                                                    strength = strength\n                                                )\n                                            )\n                                        )\n                                    }\n                                }\n\n                                StitchFadeSide.Both -> {\n                                    when (i) {\n                                        0 -> listOf(\n                                            createFilter<SideFadeParams, Filter.SideFade>(\n                                                SideFadeParams.Absolute(\n                                                    side = if (isHorizontal) FadeSide.End else FadeSide.Bottom,\n                                                    size = halfSpace,\n                                                    strength = strength\n                                                )\n                                            )\n                                        )\n\n                                        imagesUris.lastIndex -> listOf(\n                                            createFilter<SideFadeParams, Filter.SideFade>(\n                                                SideFadeParams.Absolute(\n                                                    side = if (isHorizontal) FadeSide.Start else FadeSide.Top,\n                                                    size = halfSpace,\n                                                    strength = strength\n                                                )\n                                            )\n                                        )\n\n                                        else -> listOf(\n                                            createFilter<SideFadeParams, Filter.SideFade>(\n                                                SideFadeParams.Absolute(\n                                                    side = if (isHorizontal) FadeSide.Start else FadeSide.Top,\n                                                    size = halfSpace,\n                                                    strength = strength\n                                                )\n                                            ),\n                                            createFilter<SideFadeParams, Filter.SideFade>(\n                                                SideFadeParams.Absolute(\n                                                    side = if (isHorizontal) FadeSide.End else FadeSide.Bottom,\n                                                    size = halfSpace,\n                                                    strength = strength\n                                                )\n                                            )\n                                        )\n                                    }\n                                }\n\n                                else -> emptyList()\n                            }\n\n                            imageTransformer.transform(\n                                image = bmp,\n                                transformations = filters.map(filterProvider::filterToTransformation)\n                            )?.let { bmp = it }\n                        }\n\n                    if (isHorizontal) {\n                        drawBitmap(\n                            bitmap = bmp,\n                            left = pos.toFloat(),\n                            top = when (combiningParams.alignment) {\n                                StitchAlignment.Start -> 0f\n                                StitchAlignment.Center -> (height - bmp.height) / 2f\n                                StitchAlignment.End -> (height - bmp.height).toFloat()\n                            },\n                            paint = if (pos > 0) combiningParams.blendingMode.toPaint() else Paint()\n                        )\n                    } else {\n                        drawBitmap(\n                            bitmap = bmp,\n                            left = when (combiningParams.alignment) {\n                                StitchAlignment.Start -> 0f\n                                StitchAlignment.Center -> (width - bmp.width) / 2f\n                                StitchAlignment.End -> (width - bmp.width).toFloat()\n                            },\n                            top = pos.toFloat(),\n                            paint = if (pos > 0) combiningParams.blendingMode.toPaint() else Paint()\n                        )\n                    }\n                    pos += if (isHorizontal) {\n                        (bmp.width + combiningParams.spacing).coerceAtLeast(1)\n                    } else (bmp.height + combiningParams.spacing).coerceAtLeast(1)\n\n                    onProgress(i + 1)\n                }\n            }\n\n            return bitmap.createScaledBitmap(\n                width = size.width,\n                height = size.height\n            ) to ImageInfo(\n                width = size.width,\n                height = size.height,\n                imageFormat = ImageFormat.Png.Lossless\n            )\n        }\n\n        if (combiningParams.stitchMode.gridCellsCount().let { !(it == 0 || it > imageUris.size) }) {\n            combineImages(\n                imageUris = distributeImages(\n                    images = imageUris,\n                    cellCount = combiningParams.stitchMode.gridCellsCount()\n                ).mapNotNull { images ->\n                    val data = getImageData(\n                        imagesUris = images,\n                        isHorizontal = combiningParams.stitchMode.isHorizontal()\n                    )\n                    shareProvider.cacheImage(\n                        image = data.first,\n                        imageInfo = data.second\n                    )\n                },\n                combiningParams = combiningParams.copy(\n                    stitchMode = when (combiningParams.stitchMode) {\n                        is StitchMode.Grid.Horizontal -> StitchMode.Vertical\n                        else -> StitchMode.Horizontal\n                    }\n                ),\n                onProgress = onProgress\n            )\n        } else {\n            getImageData(\n                imagesUris = imageUris,\n                isHorizontal = combiningParams.stitchMode.isHorizontal()\n            )\n        }\n    }\n\n    override suspend fun calculateCombinedImageDimensions(\n        imageUris: List<String>,\n        combiningParams: CombiningParams\n    ): IntegerSize {\n        return if (combiningParams.stitchMode.gridCellsCount()\n                .let { it == 0 || it > imageUris.size }\n        ) {\n            calculateCombinedImageDimensionsAndBitmaps(\n                imageUris = imageUris,\n                isHorizontal = combiningParams.stitchMode.isHorizontal(),\n                scaleSmallImagesToLarge = combiningParams.scaleSmallImagesToLarge,\n                imageSpacing = combiningParams.spacing,\n                imageScale = combiningParams.outputScale\n            ).first\n        } else {\n            val isHorizontalGrid = combiningParams.stitchMode.isHorizontal()\n            var size = IntegerSize(0, 0)\n            distributeImages(\n                images = imageUris,\n                cellCount = combiningParams.stitchMode.gridCellsCount()\n            ).forEach { images ->\n                calculateCombinedImageDimensionsAndBitmaps(\n                    imageUris = images,\n                    isHorizontal = !isHorizontalGrid,\n                    scaleSmallImagesToLarge = combiningParams.scaleSmallImagesToLarge,\n                    imageSpacing = combiningParams.spacing,\n                    imageScale = combiningParams.outputScale\n                ).first.let { newSize ->\n                    size = if (isHorizontalGrid) {\n                        size.copy(\n                            height = size.height + newSize.height,\n                            width = max(newSize.width, size.width)\n                        )\n                    } else {\n                        size.copy(\n                            height = max(newSize.height, size.height),\n                            width = size.width + newSize.width,\n                        )\n                    }\n                }\n            }\n            IntegerSize(\n                width = size.width.coerceAtLeast(1),\n                height = size.height.coerceAtLeast(1)\n            )\n        }\n    }\n\n    private suspend fun calculateCombinedImageDimensionsAndBitmaps(\n        imageUris: List<String>,\n        isHorizontal: Boolean,\n        scaleSmallImagesToLarge: Boolean,\n        imageSpacing: Int,\n        imageScale: Float\n    ): Pair<IntegerSize, List<Bitmap>> = withContext(defaultDispatcher) {\n        var w = 0\n        var h = 0\n        var maxHeight = 0\n        var maxWidth = 0\n        val drawables = imageUris.mapNotNull { uri ->\n            imageGetter.getImage(\n                data = uri,\n                originalSize = true\n            )?.let {\n                it.createScaledBitmap(\n                    width = (it.width * imageScale).roundToInt(),\n                    height = (it.height * imageScale).roundToInt()\n                )\n            }?.apply {\n                maxWidth = max(maxWidth, width)\n                maxHeight = max(maxHeight, height)\n            }\n        }\n\n        drawables.forEachIndexed { index, image ->\n            val width = image.width\n            val height = image.height\n\n            val spacing = if (index != drawables.lastIndex) imageSpacing else 0\n\n            if (scaleSmallImagesToLarge && image.shouldUpscale(\n                    isHorizontal = isHorizontal,\n                    size = IntegerSize(maxWidth, maxHeight)\n                )\n            ) {\n                val targetHeight: Int\n                val targetWidth: Int\n\n                if (isHorizontal) {\n                    targetHeight = maxHeight\n                    targetWidth = (targetHeight * image.aspectRatio).toInt()\n                } else {\n                    targetWidth = maxWidth\n                    targetHeight = (targetWidth / image.aspectRatio).toInt()\n                }\n                if (isHorizontal) {\n                    w += (targetWidth + spacing).coerceAtLeast(1)\n                } else {\n                    h += (targetHeight + spacing).coerceAtLeast(1)\n                }\n            } else {\n                if (isHorizontal) {\n                    w += (width + spacing).coerceAtLeast(1)\n                } else {\n                    h += (height + spacing).coerceAtLeast(1)\n                }\n            }\n        }\n\n        if (isHorizontal) {\n            h = maxHeight\n        } else {\n            w = maxWidth\n        }\n\n        IntegerSize(\n            width = w.coerceAtLeast(1),\n            height = h.coerceAtLeast(1)\n        ) to drawables\n    }\n\n    private fun distributeImages(\n        images: List<String>,\n        cellCount: Int\n    ): List<List<String>> {\n        val imageCount = images.size\n        val imagesPerRow = imageCount / cellCount\n        val remainingImages = imageCount % cellCount\n\n        val result = MutableList(cellCount) { imagesPerRow }\n\n        for (i in 0 until remainingImages) {\n            result[i] += 1\n        }\n\n        var offset = 0\n        return result.map { count ->\n            images.subList(\n                fromIndex = offset,\n                toIndex = offset + count\n            ).also {\n                offset += count\n            }\n        }\n    }\n\n    override suspend fun createCombinedImagesPreview(\n        imageUris: List<String>,\n        combiningParams: CombiningParams,\n        imageFormat: ImageFormat,\n        quality: Quality,\n        onGetByteCount: (Long) -> Unit\n    ): ImageWithSize<Bitmap?> = withContext(defaultDispatcher) {\n        val imageSize = calculateCombinedImageDimensions(\n            imageUris = imageUris,\n            combiningParams = combiningParams\n        ).let {\n            it.copy(\n                width = (it.width / combiningParams.outputScale).roundToInt(),\n                height = (it.height / combiningParams.outputScale).roundToInt()\n            )\n        }\n\n        if (!settingsState.generatePreviews) return@withContext null withSize imageSize\n\n        val scale = 0.2f\n\n        combineImages(\n            imageUris = imageUris,\n            combiningParams = combiningParams.copy(\n                outputScale = scale\n            ),\n            onProgress = {}\n        ).let { (image, imageInfo) ->\n            return@let imagePreviewCreator.createPreview(\n                image = image,\n                imageInfo = imageInfo.copy(\n                    imageFormat = imageFormat,\n                    quality = quality\n                ),\n                transformations = emptyList(),\n                onGetByteCount = {\n                    val original = it / (scale * scale)\n                    onGetByteCount(original.roundToLong())\n                }\n            ) withSize imageSize\n        }\n    }\n\n    private fun Bitmap.shouldUpscale(\n        isHorizontal: Boolean,\n        size: IntegerSize\n    ): Boolean {\n        return if (isHorizontal) this.height != size.height\n        else this.width != size.width\n    }\n\n    private suspend fun Bitmap.upscale(\n        isHorizontal: Boolean,\n        size: IntegerSize\n    ): Bitmap {\n        return if (isHorizontal) {\n            createScaledBitmap(\n                width = (size.height * aspectRatio).toInt(),\n                height = size.height\n            )\n        } else {\n            createScaledBitmap(\n                width = size.width,\n                height = (size.width / aspectRatio).toInt()\n            )\n        }\n    }\n\n    private suspend fun Bitmap.createScaledBitmap(\n        width: Int,\n        height: Int\n    ): Bitmap = imageScaler.scaleImage(\n        image = this,\n        width = width,\n        height = height\n    )\n\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/data/CvStitchHelper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.data\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.CombiningParams\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchMode\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport com.t8rin.trickle.Trickle\nimport org.opencv.calib3d.Calib3d\nimport org.opencv.core.Core\nimport org.opencv.core.CvType\nimport org.opencv.core.Mat\nimport org.opencv.core.MatOfDMatch\nimport org.opencv.core.MatOfKeyPoint\nimport org.opencv.core.MatOfPoint2f\nimport org.opencv.core.Point\nimport org.opencv.core.Rect\nimport org.opencv.core.Scalar\nimport org.opencv.core.Size\nimport org.opencv.core.times\nimport org.opencv.features2d.FlannBasedMatcher\nimport org.opencv.features2d.SIFT\nimport org.opencv.imgproc.Imgproc\nimport javax.inject.Inject\nimport kotlin.math.max\nimport kotlin.math.roundToInt\n\ninternal class CvStitchHelper @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>\n) : OpenCV() {\n\n    private val kernel = Mat(3, 3, CvType.CV_8SC1).apply {\n        put(0, 0, 1.0, 1.0, 1.0)\n        put(1, 0, 1.0, -8.0, 1.0)\n        put(2, 0, 1.0, 1.0, 1.0)\n    }\n\n    fun stitchBitmaps(\n        mat0: Mat,\n        mat1: Mat,\n        homo: Boolean = true,\n        diff: Boolean = true\n    ): Mat? {\n        return if (homo) {\n            stitchHomography(mat0, mat1, diff)\n        } else {\n            stitchPhaseCorrelate(mat0, mat1, diff)\n        }\n    }\n\n    private fun stitchHomography(mat0: Mat, mat1: Mat, diff: Boolean): Mat? {\n        val mat0Proc = if (diff) {\n            val tmp = Mat()\n            Imgproc.filter2D(mat0, tmp, CvType.CV_8U, kernel)\n            tmp\n        } else mat0\n        val mat1Proc = if (diff) {\n            val tmp = Mat()\n            Imgproc.filter2D(mat1, tmp, CvType.CV_8U, kernel)\n            tmp\n        } else mat1\n\n        val sift = SIFT.create()\n        val kp0 = MatOfKeyPoint()\n        val kp1 = MatOfKeyPoint()\n        val desc0 = Mat()\n        val desc1 = Mat()\n        sift.detectAndCompute(mat0Proc, Mat(), kp0, desc0)\n        sift.detectAndCompute(mat1Proc, Mat(), kp1, desc1)\n        if (kp0.empty() || kp1.empty()) return null\n\n        val matcher = FlannBasedMatcher.create()\n        val knnMatches = mutableListOf<MatOfDMatch>()\n        matcher.knnMatch(desc0, desc1, knnMatches, 2)\n\n        val queryPoints = mutableListOf<Point>()\n        val trainPoints = mutableListOf<Point>()\n        val kp0a = kp0.toArray()\n        val kp1a = kp1.toArray()\n        for (m in knnMatches) {\n            val matches = m.toArray()\n            if (matches.size < 2) continue\n            if (matches[0].distance > 0.7 * matches[1].distance) continue\n            queryPoints.add(kp0a[matches[0].queryIdx].pt)\n            trainPoints.add(kp1a[matches[0].trainIdx].pt)\n        }\n        if (queryPoints.size < 10) return null\n\n        val homoMat = Calib3d.findHomography(\n            MatOfPoint2f(*trainPoints.toTypedArray()),\n            MatOfPoint2f(*queryPoints.toTypedArray()),\n            Calib3d.RANSAC\n        )\n\n        val corners = arrayOf(\n            Point(0.0, 0.0),\n            Point(mat1.cols().toDouble(), 0.0),\n            Point(mat1.cols().toDouble(), mat1.rows().toDouble()),\n            Point(0.0, mat1.rows().toDouble())\n        )\n        val transformedCorners = MatOfPoint2f(*corners).let { src ->\n            val dst = MatOfPoint2f()\n            Core.perspectiveTransform(src, dst, homoMat)\n            dst.toArray()\n        }\n\n        val allX = transformedCorners.map { it.x } + listOf(0.0, mat0.cols().toDouble())\n        val allY = transformedCorners.map { it.y } + listOf(0.0, mat0.rows().toDouble())\n        val minX = allX.minOrNull() ?: 0.0\n        val minY = allY.minOrNull() ?: 0.0\n        val maxX = allX.maxOrNull() ?: mat0.cols().toDouble()\n        val maxY = allY.maxOrNull() ?: mat0.rows().toDouble()\n        val width = (maxX - minX).toInt()\n        val height = (maxY - minY).toInt()\n\n        val offset = Mat.eye(3, 3, CvType.CV_64F)\n        offset.put(0, 2, -minX)\n        offset.put(1, 2, -minY)\n        val adjustedHomo = offset * homoMat\n\n        val canvas = Mat(Size(width.toDouble(), height.toDouble()), mat0.type())\n        Imgproc.warpPerspective(mat1, canvas, adjustedHomo, canvas.size())\n        val roi0 = Rect((-minX).toInt(), (-minY).toInt(), mat0.cols(), mat0.rows())\n        mat0.copyTo(canvas.submat(roi0))\n        return canvas\n    }\n\n    private fun stitchPhaseCorrelate(mat0: Mat, mat1: Mat, diff: Boolean): Mat? {\n        if (mat0.size() != mat1.size()) {\n            val targetSize = Size(\n                minOf(mat0.cols(), mat1.cols()).toDouble(),\n                minOf(mat0.rows(), mat1.rows()).toDouble()\n            )\n            val resized0 = Mat()\n            val resized1 = Mat()\n            Imgproc.resize(mat0, resized0, targetSize)\n            Imgproc.resize(mat1, resized1, targetSize)\n            return stitchPhaseCorrelate(resized0, resized1, diff)\n        }\n\n        val mat0Gray = Mat()\n        val mat1Gray = Mat()\n        if (diff) {\n            val grad0 = Mat()\n            val grad1 = Mat()\n            Imgproc.filter2D(mat0, grad0, CvType.CV_8U, kernel)\n            Imgproc.filter2D(mat1, grad1, CvType.CV_8U, kernel)\n            val diffMat = Mat()\n            Core.absdiff(grad0, grad1, diffMat)\n            Core.bitwise_and(grad0, diffMat, grad0)\n            Core.bitwise_and(grad1, diffMat, grad1)\n            Imgproc.cvtColor(grad0, mat0Gray, Imgproc.COLOR_RGBA2GRAY)\n            Imgproc.cvtColor(grad1, mat1Gray, Imgproc.COLOR_RGBA2GRAY)\n        } else {\n            Imgproc.cvtColor(mat0, mat0Gray, Imgproc.COLOR_RGBA2GRAY)\n            Imgproc.cvtColor(mat1, mat1Gray, Imgproc.COLOR_RGBA2GRAY)\n        }\n\n        val matchResult = Mat()\n        Imgproc.matchTemplate(mat0Gray, mat1Gray, matchResult, Imgproc.TM_CCORR_NORMED)\n        val mmr = Core.minMaxLoc(matchResult)\n        val dx = mmr.maxLoc.x.toInt()\n        val dy = mmr.maxLoc.y.toInt()\n\n        val width = max(mat0.cols(), mat1.cols() + dx)\n        val height = max(mat0.rows(), mat1.rows() + dy)\n        val canvas = Mat(Size(width.toDouble(), height.toDouble()), mat0.type())\n        canvas.setTo(Scalar.all(0.0))\n        mat0.copyTo(canvas.submat(Rect(0, 0, mat0.cols(), mat0.rows())))\n        mat1.copyTo(canvas.submat(Rect(dx, dy, mat1.cols(), mat1.rows())))\n        return canvas\n    }\n\n    suspend fun cvCombine(\n        imageUris: List<String>,\n        combiningParams: CombiningParams,\n    ): Pair<Bitmap, ImageInfo> {\n        val result = cvStitch(\n            uris = imageUris,\n            imageScale = combiningParams.outputScale,\n            stitchMode = combiningParams.stitchMode as StitchMode.Auto\n        ) ?: imageUris.first().toBitmap(\n            imageScale = combiningParams.outputScale,\n            stitchMode = combiningParams.stitchMode\n        ) ?: createBitmap(1, 1)\n\n        return Trickle.drawColorBehind(\n            input = result,\n            color = combiningParams.backgroundColor\n        ) to ImageInfo(\n            width = result.width,\n            height = result.height,\n            imageFormat = ImageFormat.Png.Lossless\n        )\n    }\n\n    private suspend fun cvStitch(\n        uris: List<String>,\n        imageScale: Float,\n        stitchMode: StitchMode.Auto\n    ): Bitmap? {\n        if (uris.size < 2) return null\n\n        var current = uris.first().toBitmap(\n            imageScale = imageScale,\n            stitchMode = stitchMode\n        )?.toMat() ?: return null\n\n        for (i in 1 until uris.size) {\n            val next = uris[i].toBitmap(\n                imageScale = imageScale,\n                stitchMode = stitchMode\n            )?.toMat() ?: continue\n\n            val stitched = stitchBitmaps(\n                mat0 = current,\n                mat1 = next\n            )\n            current.release()\n            next.release()\n\n            stitched ?: return null\n            current = stitched\n        }\n\n        return current.toBitmap().also { current.release() }\n    }\n\n    private suspend fun String.toBitmap(\n        imageScale: Float,\n        stitchMode: StitchMode.Auto\n    ): Bitmap? = imageGetter.getImage(\n        data = this,\n        originalSize = true\n    )?.let {\n        val scaled = it.createScaledBitmap(\n            width = (it.width * imageScale).roundToInt(),\n            height = (it.height * imageScale).roundToInt()\n        )\n        val newWidth = scaled.width - stitchMode.startDrop - stitchMode.endDrop\n        val newHeight = scaled.height - stitchMode.topDrop - stitchMode.bottomDrop\n\n        if (newWidth < 1 || newHeight < 1) {\n            scaled\n        } else {\n            Bitmap.createBitmap(\n                scaled,\n                stitchMode.startDrop,\n                stitchMode.topDrop,\n                newWidth.coerceAtLeast(1),\n                newHeight.coerceAtLeast(1)\n            )\n        }\n    }\n\n    private suspend fun Bitmap.createScaledBitmap(\n        width: Int,\n        height: Int\n    ): Bitmap = imageScaler.scaleImage(\n        image = this,\n        width = width,\n        height = height\n    )\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/di/ImageStitchModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.image_stitch.data.AndroidImageCombiner\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.ImageCombiner\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ImageStitchModule {\n\n    @Singleton\n    @Binds\n    fun provideImageCombiner(\n        combiner: AndroidImageCombiner\n    ): ImageCombiner<Bitmap>\n\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/domain/CombiningParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\n\ndata class CombiningParams(\n    val stitchMode: StitchMode = StitchMode.Horizontal,\n    val spacing: Int = 0,\n    val scaleSmallImagesToLarge: Boolean = false,\n    val backgroundColor: Int = 0x00000000,\n    val fadingEdgesMode: StitchFadeSide = StitchFadeSide.Start,\n    val alignment: StitchAlignment = StitchAlignment.Start,\n    val outputScale: Float = 0.5f,\n    val blendingMode: BlendingMode = BlendingMode.SrcOver,\n    val fadeStrength: Float = 1f\n)"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/domain/ImageCombiner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageWithSize\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ninterface ImageCombiner<I> {\n\n    suspend fun combineImages(\n        imageUris: List<String>,\n        combiningParams: CombiningParams,\n        onProgress: (Int) -> Unit\n    ): Pair<I, ImageInfo>\n\n    suspend fun calculateCombinedImageDimensions(\n        imageUris: List<String>,\n        combiningParams: CombiningParams\n    ): IntegerSize\n\n    suspend fun createCombinedImagesPreview(\n        imageUris: List<String>,\n        combiningParams: CombiningParams,\n        imageFormat: ImageFormat,\n        quality: Quality,\n        onGetByteCount: (Long) -> Unit\n    ): ImageWithSize<I?>\n\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/domain/SavableCombiningParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.entries\n\ndata class SavableCombiningParams(\n    val stitchMode: String,\n    val spacing: Int,\n    val scaleSmallImagesToLarge: Boolean,\n    val backgroundColor: Int,\n    val fadingEdgesMode: StitchFadeSide,\n    val alignment: StitchAlignment,\n    val outputScale: Float,\n    val blendingMode: Int,\n    val fadeStrength: Float\n)\n\nfun CombiningParams.toSavable() = SavableCombiningParams(\n    stitchMode = \"${stitchMode.ordinal}_${stitchMode.gridCellsCount()}_${\n        stitchMode.drops().joinToString(separator = \"_\")\n    }\",\n    spacing = spacing,\n    scaleSmallImagesToLarge = scaleSmallImagesToLarge,\n    backgroundColor = backgroundColor,\n    fadingEdgesMode = fadingEdgesMode,\n    alignment = alignment,\n    outputScale = outputScale,\n    blendingMode = blendingMode.value,\n    fadeStrength = fadeStrength\n)\n\nfun SavableCombiningParams.toParams() = CombiningParams(\n    stitchMode = stitchMode.split(\"_\").let {\n        if (it.size < 2) StitchMode.Horizontal\n        else {\n            val mode = StitchMode.fromOrdinal(it.getOrNull(0)?.toIntOrNull() ?: 0)\n            val cells = it.getOrNull(1)?.toIntOrNull() ?: 0\n\n            when (mode) {\n                is StitchMode.Grid.Horizontal -> mode.copy(rows = cells)\n                is StitchMode.Grid.Vertical -> mode.copy(columns = cells)\n                is StitchMode.Auto -> StitchMode.Auto(it.drop(2).map { s -> s.toIntOrNull() ?: 0 })\n\n                else -> mode\n            }\n        }\n    },\n    spacing = spacing,\n    scaleSmallImagesToLarge = scaleSmallImagesToLarge,\n    backgroundColor = backgroundColor,\n    fadingEdgesMode = fadingEdgesMode,\n    alignment = alignment,\n    outputScale = outputScale,\n    blendingMode = BlendingMode.entries.find { it.value == blendingMode } ?: BlendingMode.SrcOver,\n    fadeStrength = fadeStrength\n)"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/domain/StitchAlignment.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.domain\n\nenum class StitchAlignment {\n    Start,\n    Center,\n    End\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/domain/StitchFadeSide.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.domain\n\nenum class StitchFadeSide {\n    None,\n    Start,\n    End,\n    Both\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/domain/StitchMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.domain\n\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\n\nsealed class StitchMode(val ordinal: Int) {\n    fun drops(): List<Int> = safeCast<Auto>()?.drops ?: emptyList()\n\n    data class Auto(\n        val topDrop: Int = 0,\n        val bottomDrop: Int = 0,\n        val startDrop: Int = 0,\n        val endDrop: Int = 0\n    ) : StitchMode(-1) {\n        val drops = listOf(topDrop, bottomDrop, startDrop, endDrop)\n\n        constructor(drops: List<Int>) : this(\n            topDrop = drops.getOrNull(0) ?: 0,\n            bottomDrop = drops.getOrNull(1) ?: 0,\n            startDrop = drops.getOrNull(2) ?: 0,\n            endDrop = drops.getOrNull(3) ?: 0\n        )\n    }\n\n    data object Horizontal : StitchMode(0)\n\n    data object Vertical : StitchMode(1)\n\n    sealed class Grid(ordinal: Int) : StitchMode(ordinal) {\n        data class Horizontal(val rows: Int = 2) : Grid(2)\n        data class Vertical(val columns: Int = 2) : Grid(3)\n    }\n\n    fun gridCellsCount(): Int {\n        return when (this) {\n            is Grid.Horizontal -> this.rows\n            is Grid.Vertical -> this.columns\n            else -> 0\n        }\n    }\n\n    fun isHorizontal(): Boolean = this is Horizontal || this is Grid.Horizontal\n\n    companion object {\n        fun fromOrdinal(ordinal: Int) = when (ordinal) {\n            -1 -> Auto()\n            0 -> Horizontal\n            1 -> Vertical\n            2 -> Grid.Horizontal()\n            3 -> Grid.Vertical()\n            else -> Horizontal\n        }\n\n        val entries by lazy {\n            listOf(\n                Horizontal,\n                Vertical,\n                Grid.Horizontal(),\n                Grid.Vertical(),\n                Auto()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/ImageStitchingContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageReorderCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ScaleSmallImagesToLargeToggle\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.BlendingModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchFadeSide\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchMode\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.components.FadeStrengthSelector\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.components.ImageFadingEdgesSelector\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.components.ImageScaleSelector\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.components.SpacingSelector\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.components.StitchAlignmentSelector\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.components.StitchModeSelector\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.screenLogic.ImageStitchingComponent\nimport kotlin.math.pow\nimport kotlin.math.roundToLong\n\n@Composable\nfun ImageStitchingContent(\n    component: ImageStitchingComponent\n) {\n    AutoContentBasedColors(component.previewBitmap)\n\n    val imagePicker = rememberImagePicker(onSuccess = component::updateUris)\n\n    val addImagesImagePicker = rememberImagePicker(onSuccess = component::addUrisToEnd)\n\n    val addImages = addImagesImagePicker::pickImage\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.image_stitching),\n                input = component.uris,\n                isLoading = component.isImageLoading,\n                size = component\n                    .imageByteSize?.times(component.combiningParams.outputScale.pow(2))\n                    ?.roundToLong(),\n                updateOnSizeChange = false\n            )\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.previewBitmap != null,\n                onShare = component::shareBitmap,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheCurrentImage {\n                        editSheetData = listOf(it)\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.previewBitmap != null,\n            )\n        },\n        imagePreview = {\n            ImageContainer(\n                imageInside = isPortrait,\n                showOriginal = false,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = null,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = true\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.uris.isNullOrEmpty()) {\n                TopAppBarEmoji()\n            }\n        },\n        controls = {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                ImageReorderCarousel(\n                    images = component.uris,\n                    onReorder = component::updateUris,\n                    onNeedToAddImage = addImages,\n                    onNeedToRemoveImageAt = component::removeImageAt,\n                    onNavigate = component.onNavigate\n                )\n                ImageScaleSelector(\n                    modifier = Modifier.padding(top = 8.dp),\n                    value = component.combiningParams.outputScale,\n                    onValueChange = component::updateImageScale,\n                    approximateImageSize = component.imageSize\n                )\n                StitchModeSelector(\n                    value = component.combiningParams.stitchMode,\n                    onValueChange = component::setStitchMode\n                )\n                AnimatedVisibility(\n                    visible = component.combiningParams.stitchMode !is StitchMode.Auto,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    SpacingSelector(\n                        value = component.combiningParams.spacing,\n                        onValueChange = component::updateImageSpacing\n                    )\n                }\n                AnimatedVisibility(\n                    visible = component.combiningParams.spacing < 0 && component.combiningParams.stitchMode !is StitchMode.Auto,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    ImageFadingEdgesSelector(\n                        value = component.combiningParams.fadingEdgesMode,\n                        onValueChange = component::setFadingEdgesMode\n                    )\n                }\n                AnimatedVisibility(\n                    visible = component.combiningParams.spacing < 0 && component.combiningParams.fadingEdgesMode != StitchFadeSide.None && component.combiningParams.stitchMode !is StitchMode.Auto,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    FadeStrengthSelector(\n                        value = component.combiningParams.fadeStrength,\n                        onValueChange = component::setFadeStrength\n                    )\n                }\n                AnimatedVisibility(\n                    visible = component.combiningParams.stitchMode !is StitchMode.Auto,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    ScaleSmallImagesToLargeToggle(\n                        checked = component.combiningParams.scaleSmallImagesToLarge,\n                        onCheckedChange = component::toggleScaleSmallImagesToLarge\n                    )\n                }\n                AnimatedVisibility(\n                    visible = component.combiningParams.spacing < 0 && component.combiningParams.stitchMode !is StitchMode.Auto,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    BlendingModeSelector(\n                        value = component.combiningParams.blendingMode,\n                        onValueChange = component::setBlendingMode,\n                        color = Color.Unspecified\n                    )\n                }\n                AnimatedVisibility(\n                    visible = !component.combiningParams.scaleSmallImagesToLarge && component.combiningParams.stitchMode !is StitchMode.Auto,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    StitchAlignmentSelector(\n                        value = component.combiningParams.alignment,\n                        onValueChange = component::setStitchAlignment\n                    )\n                }\n                ColorRowSelector(\n                    value = Color(component.combiningParams.backgroundColor),\n                    onValueChange = {\n                        component.updateBackgroundSelector(it.toArgb())\n                    },\n                    modifier = Modifier.container(\n                        shape = ShapeDefaults.extraLarge\n                    )\n                )\n                QualitySelector(\n                    imageFormat = component.imageInfo.imageFormat,\n                    quality = component.imageInfo.quality,\n                    onQualityChange = component::setQuality\n                )\n                ImageFormatSelector(\n                    value = component.imageInfo.imageFormat,\n                    onValueChange = component::setImageFormat,\n                    quality = component.imageInfo.quality,\n                )\n            }\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                isPrimaryButtonVisible = component.previewBitmap != null,\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        },\n        canShowScreenData = !component.uris.isNullOrEmpty()\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris?.size ?: 1,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/components/FadeStrengthSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exercise\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun FadeStrengthSelector(\n    modifier: Modifier = Modifier,\n    value: Float,\n    onValueChange: (Float) -> Unit\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        title = stringResource(R.string.fade_strength),\n        valueRange = 0f..1f,\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        onValueChange = {\n            onValueChange(it.roundToTwoDigits())\n        },\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        icon = Icons.Outlined.Exercise,\n        shape = ShapeDefaults.extraLarge\n    )\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/components/ImageFadingEdgesSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation.components\n\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchFadeSide\n\n@Composable\nfun ImageFadingEdgesSelector(\n    modifier: Modifier = Modifier,\n    value: StitchFadeSide,\n    onValueChange: (StitchFadeSide) -> Unit\n) {\n    EnhancedButtonGroup(\n        modifier = modifier\n            .container(shape = ShapeDefaults.extraLarge),\n        title = stringResource(id = R.string.fading_edges),\n        entries = StitchFadeSide.entries,\n        value = value,\n        onValueChange = onValueChange,\n        itemContent = {\n            Text(it.title())\n        }\n    )\n}\n\n@Composable\nprivate fun StitchFadeSide.title() = when (this) {\n    StitchFadeSide.None -> stringResource(R.string.disabled)\n    StitchFadeSide.Start -> stringResource(R.string.start)\n    StitchFadeSide.End -> stringResource(R.string.end)\n    StitchFadeSide.Both -> stringResource(R.string.both)\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/components/ImageScaleSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.PhotoSizeSelectSmall\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.OOMWarning\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun ImageScaleSelector(\n    modifier: Modifier,\n    value: Float,\n    approximateImageSize: IntegerSize,\n    onValueChange: (Float) -> Unit\n) {\n    val scaledSize by remember(approximateImageSize, value) {\n        derivedStateOf {\n            val s = approximateImageSize * value\n            if (s.isZero()) null\n            else s\n        }\n    }\n    val showWarning by remember(scaledSize) {\n        derivedStateOf {\n            scaledSize!!.width * scaledSize!!.height * 4L >= 7_000 * 7_000 * 3L\n        }\n    }\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value.roundToTwoDigits(),\n        title = stringResource(R.string.output_image_scale),\n        valueRange = 0.1f..1f,\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        onValueChange = {\n            onValueChange(it.roundToTwoDigits())\n        },\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        icon = Icons.Rounded.PhotoSizeSelectSmall,\n        shape = ShapeDefaults.extraLarge\n    ) {\n        AnimatedContent(\n            targetState = scaledSize != null,\n            transitionSpec = { fadeIn() togetherWith fadeOut() }\n        ) { notNull ->\n            if (notNull) {\n                Column {\n                    Row(\n                        modifier = Modifier\n                            .padding(4.dp)\n                            .container(\n                                shape = ShapeDefaults.large,\n                                color = MaterialTheme.colorScheme.surface\n                            )\n                            .padding(4.dp)\n                    ) {\n                        Column(\n                            modifier = Modifier\n                                .weight(1f)\n                                .container(\n                                    autoShadowElevation = 0.2.dp,\n                                    color = MaterialTheme.colorScheme.surfaceContainerLow\n                                )\n                                .padding(4.dp),\n                            verticalArrangement = Arrangement.Center,\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            Text(stringResource(R.string.width, \"\"))\n                            Spacer(Modifier.height(8.dp))\n                            Text(\n                                text = scaledSize!!.width.toString(),\n                                fontSize = 16.sp,\n                                textAlign = TextAlign.Center,\n                                color = LocalContentColor.current.copy(0.5f),\n                            )\n                        }\n                        Spacer(Modifier.width(8.dp))\n                        Column(\n                            modifier = Modifier\n                                .weight(1f)\n                                .container(\n                                    autoShadowElevation = 0.2.dp,\n                                    color = MaterialTheme.colorScheme.surfaceContainerLow\n                                )\n                                .padding(4.dp),\n                            verticalArrangement = Arrangement.Center,\n                            horizontalAlignment = Alignment.CenterHorizontally\n                        ) {\n                            Text(stringResource(R.string.height, \"\"))\n                            Spacer(Modifier.height(8.dp))\n                            Text(\n                                text = scaledSize!!.height.toString(),\n                                fontSize = 16.sp,\n                                textAlign = TextAlign.Center,\n                                color = LocalContentColor.current.copy(0.5f),\n                            )\n                        }\n                    }\n                    OOMWarning(\n                        visible = showWarning,\n                        modifier = Modifier.padding(4.dp)\n                    )\n                }\n            } else {\n                Text(\n                    text = stringResource(R.string.loading),\n                    modifier = Modifier\n                        .padding(4.dp)\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.large,\n                            color = MaterialTheme.colorScheme.surface\n                        )\n                        .padding(6.dp),\n                    color = LocalContentColor.current.copy(0.5f),\n                    textAlign = TextAlign.Center\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/components/SpacingSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FormatLineSpacing\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlin.math.roundToInt\n\n@Composable\nfun SpacingSelector(\n    modifier: Modifier = Modifier,\n    value: Int,\n    onValueChange: (Int) -> Unit\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        title = stringResource(R.string.spacing),\n        valueRange = -512f..256f,\n        internalStateTransformation = {\n            it.roundToInt()\n        },\n        onValueChange = {\n            onValueChange(it.roundToInt())\n        },\n        sliderModifier = Modifier\n            .padding(\n                top = 14.dp,\n                start = 12.dp,\n                end = 12.dp,\n                bottom = 10.dp\n            ),\n        icon = Icons.Rounded.FormatLineSpacing,\n        shape = ShapeDefaults.extraLarge\n    )\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/components/StitchAlignmentSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.state.derivedValueOf\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchAlignment\n\n\n@Composable\nfun StitchAlignmentSelector(\n    modifier: Modifier = Modifier,\n    value: StitchAlignment,\n    onValueChange: (StitchAlignment) -> Unit\n) {\n    Column(\n        modifier = modifier\n            .container(shape = ShapeDefaults.extraLarge)\n    ) {\n        EnhancedButtonGroup(\n            modifier = Modifier.padding(start = 3.dp, end = 2.dp),\n            enabled = true,\n            title = {\n                Column {\n                    Spacer(modifier = Modifier.height(8.dp))\n                    Text(stringResource(id = R.string.alignment))\n                    Spacer(modifier = Modifier.height(8.dp))\n                }\n            },\n            itemCount = StitchAlignment.entries.size,\n            selectedIndex = derivedValueOf(value) {\n                StitchAlignment.entries.indexOfFirst { it == value }\n            },\n            onIndexChange = {\n                onValueChange(StitchAlignment.entries[it])\n            },\n            itemContent = {\n                val text = when (StitchAlignment.entries[it]) {\n                    StitchAlignment.Start -> R.string.start\n                    StitchAlignment.Center -> R.string.center\n                    StitchAlignment.End -> R.string.end\n                }\n                Text(stringResource(text))\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/components/StitchModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BorderBottom\nimport androidx.compose.material.icons.rounded.BorderLeft\nimport androidx.compose.material.icons.rounded.BorderRight\nimport androidx.compose.material.icons.rounded.BorderTop\nimport androidx.compose.material.icons.rounded.TableRows\nimport androidx.compose.material.icons.rounded.ViewColumn\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchMode\nimport kotlin.math.roundToInt\n\n@Composable\nfun StitchModeSelector(\n    modifier: Modifier = Modifier,\n    value: StitchMode,\n    onValueChange: (StitchMode) -> Unit\n) {\n    Column(\n        modifier = modifier\n            .container(shape = ShapeDefaults.extraLarge)\n    ) {\n        EnhancedButtonGroup(\n            modifier = Modifier.padding(start = 3.dp, end = 2.dp),\n            title = stringResource(id = R.string.stitch_mode),\n            entries = StitchMode.entries,\n            value = value,\n            onValueChange = onValueChange,\n            itemContent = {\n                Text(it.title())\n            },\n            useClassFinding = true\n        )\n        AnimatedVisibility(\n            visible = value is StitchMode.Grid.Horizontal,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            EnhancedSliderItem(\n                modifier = Modifier.padding(8.dp),\n                value = value.gridCellsCount(),\n                title = stringResource(R.string.rows_count),\n                sliderModifier = Modifier\n                    .padding(\n                        top = 14.dp,\n                        start = 12.dp,\n                        end = 12.dp,\n                        bottom = 10.dp\n                    ),\n                icon = Icons.Rounded.TableRows,\n                valueRange = 2f..6f,\n                steps = 3,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChangeFinished = {\n                    onValueChange(\n                        StitchMode.Grid.Horizontal(it.roundToInt())\n                    )\n                },\n                onValueChange = {},\n                shape = ShapeDefaults.default,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        }\n        AnimatedVisibility(\n            visible = value is StitchMode.Grid.Vertical,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            EnhancedSliderItem(\n                modifier = Modifier.padding(8.dp),\n                value = value.gridCellsCount(),\n                title = stringResource(R.string.columns_count),\n                sliderModifier = Modifier\n                    .padding(\n                        top = 14.dp,\n                        start = 12.dp,\n                        end = 12.dp,\n                        bottom = 10.dp\n                    ),\n                icon = Icons.Rounded.ViewColumn,\n                valueRange = 2f..6f,\n                steps = 3,\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChangeFinished = {\n                    onValueChange(\n                        StitchMode.Grid.Vertical(it.roundToInt())\n                    )\n                },\n                onValueChange = {},\n                shape = ShapeDefaults.default,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        }\n        AnimatedVisibility(\n            visible = value is StitchMode.Auto,\n            enter = fadeIn() + expandVertically(),\n            exit = fadeOut() + shrinkVertically()\n        ) {\n            Column {\n                Spacer(Modifier.height(8.dp))\n                EnhancedSliderItem(\n                    modifier = Modifier.padding(horizontal = 8.dp),\n                    value = value.safeCast<StitchMode.Auto>()?.topDrop ?: 0,\n                    title = stringResource(R.string.top_drop),\n                    sliderModifier = Modifier\n                        .padding(\n                            top = 14.dp,\n                            start = 12.dp,\n                            end = 12.dp,\n                            bottom = 10.dp\n                        ),\n                    icon = Icons.Rounded.BorderTop,\n                    valueRange = 0f..512f,\n                    internalStateTransformation = {\n                        it.roundToInt()\n                    },\n                    onValueChangeFinished = {\n                        onValueChange(\n                            value.safeCast<StitchMode.Auto>()?.copy(\n                                topDrop = it.roundToInt()\n                            ) ?: value\n                        )\n                    },\n                    onValueChange = {},\n                    shape = ShapeDefaults.top,\n                    containerColor = MaterialTheme.colorScheme.surface\n                )\n                Spacer(Modifier.height(4.dp))\n                EnhancedSliderItem(\n                    modifier = Modifier.padding(horizontal = 8.dp),\n                    value = value.safeCast<StitchMode.Auto>()?.bottomDrop ?: 0,\n                    title = stringResource(R.string.bottom_drop),\n                    sliderModifier = Modifier\n                        .padding(\n                            top = 14.dp,\n                            start = 12.dp,\n                            end = 12.dp,\n                            bottom = 10.dp\n                        ),\n                    icon = Icons.Rounded.BorderBottom,\n                    valueRange = 0f..512f,\n                    internalStateTransformation = {\n                        it.roundToInt()\n                    },\n                    onValueChangeFinished = {\n                        onValueChange(\n                            value.safeCast<StitchMode.Auto>()?.copy(\n                                bottomDrop = it.roundToInt()\n                            ) ?: value\n                        )\n                    },\n                    onValueChange = {},\n                    shape = ShapeDefaults.center,\n                    containerColor = MaterialTheme.colorScheme.surface\n                )\n                Spacer(Modifier.height(4.dp))\n                EnhancedSliderItem(\n                    modifier = Modifier.padding(horizontal = 8.dp),\n                    value = value.safeCast<StitchMode.Auto>()?.startDrop ?: 0,\n                    title = stringResource(R.string.start_drop),\n                    sliderModifier = Modifier\n                        .padding(\n                            top = 14.dp,\n                            start = 12.dp,\n                            end = 12.dp,\n                            bottom = 10.dp\n                        ),\n                    icon = Icons.Rounded.BorderLeft,\n                    valueRange = 0f..512f,\n                    internalStateTransformation = {\n                        it.roundToInt()\n                    },\n                    onValueChangeFinished = {\n                        onValueChange(\n                            value.safeCast<StitchMode.Auto>()?.copy(\n                                startDrop = it.roundToInt()\n                            ) ?: value\n                        )\n                    },\n                    onValueChange = {},\n                    shape = ShapeDefaults.center,\n                    containerColor = MaterialTheme.colorScheme.surface\n                )\n                Spacer(Modifier.height(4.dp))\n                EnhancedSliderItem(\n                    modifier = Modifier.padding(horizontal = 8.dp),\n                    value = value.safeCast<StitchMode.Auto>()?.endDrop ?: 0,\n                    title = stringResource(R.string.end_drop),\n                    sliderModifier = Modifier\n                        .padding(\n                            top = 14.dp,\n                            start = 12.dp,\n                            end = 12.dp,\n                            bottom = 10.dp\n                        ),\n                    icon = Icons.Rounded.BorderRight,\n                    valueRange = 0f..512f,\n                    internalStateTransformation = {\n                        it.roundToInt()\n                    },\n                    onValueChangeFinished = {\n                        onValueChange(\n                            value.safeCast<StitchMode.Auto>()?.copy(\n                                endDrop = it.roundToInt()\n                            ) ?: value\n                        )\n                    },\n                    onValueChange = {},\n                    shape = ShapeDefaults.bottom,\n                    containerColor = MaterialTheme.colorScheme.surface\n                )\n                Spacer(Modifier.height(8.dp))\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun StitchMode.title(): String = when (this) {\n    is StitchMode.Auto -> stringResource(R.string.auto)\n    is StitchMode.Grid.Horizontal -> stringResource(R.string.horizontal_grid)\n    is StitchMode.Grid.Vertical -> stringResource(R.string.vertical_grid)\n    StitchMode.Horizontal -> stringResource(R.string.horizontal)\n    StitchMode.Vertical -> stringResource(R.string.vertical)\n}"
  },
  {
    "path": "feature/image-stitch/src/main/java/com/t8rin/imagetoolbox/feature/image_stitch/presentation/screenLogic/ImageStitchingComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.image_stitch.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.CombiningParams\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.ImageCombiner\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchAlignment\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchFadeSide\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.StitchMode\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.toParams\nimport com.t8rin.imagetoolbox.feature.image_stitch.domain.toSavable\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\n\nclass ImageStitchingComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageCombiner: ImageCombiner<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _imageSize: MutableState<IntegerSize> = mutableStateOf(IntegerSize(0, 0))\n    val imageSize by _imageSize\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _imageInfo = mutableStateOf(ImageInfo(imageFormat = ImageFormat.Png.Lossless))\n    val imageInfo by _imageInfo\n\n    private val _combiningParams = fileController.savable(\n        scope = componentScope,\n        initial = CombiningParams().toSavable()\n    )\n    val combiningParams: CombiningParams get() = _combiningParams.get().toParams()\n\n    private val _imageByteSize: MutableState<Long?> = mutableStateOf(null)\n    val imageByteSize by _imageByteSize\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    init {\n        debounce {\n            initialUris?.let(::updateUris)\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageInfo.update { it.copy(imageFormat = imageFormat) }\n        calculatePreview(true)\n    }\n\n    fun updateUris(uris: List<Uri>?) {\n        if (uris != _uris.value) {\n            _uris.value = uris\n            calculatePreview(true)\n        }\n    }\n\n    private var calculationPreviewJob: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    private var previousParams: CombiningParams? = null\n\n    private fun calculatePreview(force: Boolean = false) {\n        if (previousParams == combiningParams && !force) return\n\n        calculationPreviewJob = componentScope.launch {\n            delay(300L)\n            _isImageLoading.value = true\n            uris?.let { uris ->\n                registerChanges()\n                imageCombiner.createCombinedImagesPreview(\n                    imageUris = uris.map { it.toString() },\n                    combiningParams = combiningParams,\n                    imageFormat = imageInfo.imageFormat,\n                    quality = imageInfo.quality,\n                    onGetByteCount = {\n                        _imageByteSize.value = it\n                    }\n                ).let { (image, size) ->\n                    _previewBitmap.value = image\n                    _imageSize.value = size\n                    previousParams = combiningParams\n                }\n            }\n            _isImageLoading.value = false\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            imageCombiner.combineImages(\n                imageUris = uris?.map { it.toString() } ?: emptyList(),\n                combiningParams = combiningParams,\n                onProgress = {\n                    _done.value = it\n                    updateProgress(\n                        done = done,\n                        total = uris.orEmpty().size\n                    )\n                }\n            ).let { (image, info) ->\n                val imageInfo = info.copy(\n                    quality = imageInfo.quality,\n                    imageFormat = imageInfo.imageFormat\n                )\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = imageInfo,\n                            metadata = null,\n                            originalUri = \"Combined\",\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = image,\n                                imageInfo = imageInfo\n                            )\n                        ),\n                        keepOriginalMetadata = true,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun shareBitmap() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            imageCombiner.combineImages(\n                imageUris = uris?.map { it.toString() } ?: emptyList(),\n                combiningParams = combiningParams,\n                onProgress = {\n                    _done.value = it\n                    updateProgress(\n                        done = done,\n                        total = uris.orEmpty().size\n                    )\n                }\n            ).let {\n                it.copy(\n                    second = it.second.copy(\n                        quality = imageInfo.quality,\n                        imageFormat = imageInfo.imageFormat\n                    )\n                )\n            }.let { (image, imageInfo) ->\n                shareProvider.shareImage(\n                    image = image,\n                    imageInfo = imageInfo,\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        _imageInfo.update { it.copy(quality = quality) }\n        calculatePreview(true)\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun updateImageScale(newScale: Float) {\n        _combiningParams.update { it.copy(outputScale = newScale) }\n        registerChanges()\n    }\n\n    fun setStitchMode(value: StitchMode) {\n        updateCombiningParams(\n            combiningParams.copy(\n                stitchMode = value,\n                scaleSmallImagesToLarge = false\n            )\n        )\n        calculatePreview()\n    }\n\n    fun setFadingEdgesMode(mode: StitchFadeSide) {\n        updateCombiningParams(\n            combiningParams.copy(fadingEdgesMode = mode)\n        )\n        calculatePreview()\n    }\n\n    fun setFadeStrength(value: Float) {\n        updateCombiningParams(combiningParams.copy(fadeStrength = value))\n        calculatePreview()\n    }\n\n    fun updateImageSpacing(spacing: Int) {\n        updateCombiningParams(\n            combiningParams.copy(spacing = spacing)\n        )\n        calculatePreview()\n    }\n\n    fun toggleScaleSmallImagesToLarge(checked: Boolean) {\n        updateCombiningParams(\n            combiningParams.copy(scaleSmallImagesToLarge = checked)\n        )\n        calculatePreview()\n    }\n\n    fun updateBackgroundSelector(color: Int) {\n        updateCombiningParams(\n            combiningParams.copy(backgroundColor = color)\n        )\n        calculatePreview()\n    }\n\n    fun addUrisToEnd(uris: List<Uri>) {\n        _uris.update { list ->\n            list?.plus(\n                uris.filter { it !in list }\n            )\n        }\n        calculatePreview(true)\n    }\n\n    fun removeImageAt(index: Int) {\n        _uris.update { list ->\n            list?.toMutableList()?.apply {\n                removeAt(index)\n            }?.takeIf { it.size >= 2 }.also {\n                if (it == null) _previewBitmap.value = null\n            }\n        }\n        calculatePreview(true)\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            imageCombiner.combineImages(\n                imageUris = uris?.map { it.toString() } ?: emptyList(),\n                combiningParams = combiningParams,\n                onProgress = {\n                    _done.value = it\n                    updateProgress(\n                        done = done,\n                        total = uris.orEmpty().size\n                    )\n                }\n            ).let {\n                it.copy(\n                    second = it.second.copy(\n                        quality = imageInfo.quality,\n                        imageFormat = imageInfo.imageFormat\n                    )\n                )\n            }.let { (image, imageInfo) ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun setStitchAlignment(stitchAlignment: StitchAlignment) {\n        updateCombiningParams(combiningParams.copy(alignment = stitchAlignment))\n        calculatePreview()\n    }\n\n    fun setBlendingMode(blendingMode: BlendingMode) {\n        updateCombiningParams(combiningParams.copy(blendingMode = blendingMode))\n        calculatePreview()\n    }\n\n    private fun updateCombiningParams(params: CombiningParams) {\n        _combiningParams.update { params.toSavable() }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageInfo.imageFormat\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ImageStitchingComponent\n    }\n\n}"
  },
  {
    "path": "feature/jxl-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/jxl-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.jxl_tools\"\n\ndependencies {\n    implementation(libs.jxl.coder)\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/data/AndroidJxlConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.net.toUri\nimport com.awxkee.jxlcoder.JxlAnimatedEncoder\nimport com.awxkee.jxlcoder.JxlAnimatedImage\nimport com.awxkee.jxlcoder.JxlChannelsConfiguration\nimport com.awxkee.jxlcoder.JxlCoder\nimport com.awxkee.jxlcoder.JxlCompressionOption\nimport com.awxkee.jxlcoder.JxlDecodingSpeed\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.feature.jxl_tools.domain.AnimatedJxlParams\nimport com.t8rin.imagetoolbox.feature.jxl_tools.domain.JxlConverter\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.cancel\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.catch\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\n\ninternal class AndroidJxlConverter @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageShareProvider: ImageShareProvider<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, JxlConverter {\n\n    override suspend fun jpegToJxl(\n        jpegUris: List<String>,\n        onFailure: (Throwable) -> Unit,\n        onProgress: suspend (String, ByteArray) -> Unit\n    ) = withContext(defaultDispatcher) {\n        jpegUris.forEach { uri ->\n            runSuspendCatching {\n                uri.jxl?.let { onProgress(uri, it) }\n            }.onFailure(onFailure)\n        }\n    }\n\n    override suspend fun jxlToJpeg(\n        jxlUris: List<String>,\n        onFailure: (Throwable) -> Unit,\n        onProgress: suspend (String, ByteArray) -> Unit\n    ) = withContext(defaultDispatcher) {\n        jxlUris.forEach { uri ->\n            runSuspendCatching {\n                uri.jpeg?.let { onProgress(uri, it) }\n            }.onFailure(onFailure)\n        }\n    }\n\n    override suspend fun createJxlAnimation(\n        imageUris: List<String>,\n        params: AnimatedJxlParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): ByteArray? = withContext(defaultDispatcher) {\n        val jxlQuality = params.quality as? Quality.Jxl\n\n        if (jxlQuality == null) {\n            onFailure(IllegalArgumentException(\"Quality Must be Jxl\"))\n            return@withContext null\n        }\n\n        runSuspendCatching {\n            val size = params.size ?: imageGetter.getImage(data = imageUris[0])!!.run {\n                IntegerSize(width, height)\n            }\n            if (size.width <= 0 || size.height <= 0) {\n                onFailure(IllegalArgumentException(\"Width and height must be > 0\"))\n                return@withContext null\n            }\n\n            val (quality, compressionOption) = if (params.isLossy) {\n                params.quality.qualityValue to JxlCompressionOption.LOSSY\n            } else 100 to JxlCompressionOption.LOSSLESS\n\n            val encoder = JxlAnimatedEncoder(\n                width = size.width,\n                height = size.height,\n                numLoops = params.repeatCount,\n                channelsConfiguration = when (params.quality.channels) {\n                    Quality.Channels.RGBA -> JxlChannelsConfiguration.RGBA\n                    Quality.Channels.RGB -> JxlChannelsConfiguration.RGB\n                    Quality.Channels.Monochrome -> JxlChannelsConfiguration.MONOCHROME\n                },\n                compressionOption = compressionOption,\n                effort = params.quality.effort.coerceAtLeast(1),\n                quality = quality,\n                decodingSpeed = JxlDecodingSpeed.entries.first { it.ordinal == params.quality.speed }\n            )\n            imageUris.forEach { uri ->\n                imageGetter.getImage(\n                    data = uri,\n                    size = params.size\n                )?.let {\n                    encoder.addFrame(\n                        bitmap = imageScaler.scaleImage(\n                            image = imageScaler.scaleImage(\n                                image = it,\n                                width = size.width,\n                                height = size.height,\n                                resizeType = ResizeType.Flexible\n                            ),\n                            width = size.width,\n                            height = size.height,\n                            resizeType = ResizeType.CenterCrop(\n                                canvasColor = Color.Transparent.toArgb()\n                            )\n                        ).apply {\n                            setHasAlpha(true)\n                        },\n                        duration = params.delay\n                    )\n                }\n                onProgress()\n            }\n            encoder.encode()\n        }.onFailure {\n            onFailure(it)\n            return@withContext null\n        }.getOrNull()\n    }\n\n    override fun extractFramesFromJxl(\n        jxlUri: String,\n        imageFormat: ImageFormat,\n        imageFrames: ImageFrames,\n        quality: Quality,\n        onFailure: (Throwable) -> Unit,\n        onGetFramesCount: (frames: Int) -> Unit\n    ): Flow<String> = flow {\n        val bytes = jxlUri.bytes ?: return@flow\n\n        val decoder = JxlAnimatedImage(bytes)\n\n        onGetFramesCount(decoder.numberOfFrames)\n        val indexes = imageFrames\n            .getFramePositions(decoder.numberOfFrames)\n            .map { it - 1 }\n        repeat(decoder.numberOfFrames) { pos ->\n            if (!currentCoroutineContext().isActive) {\n                currentCoroutineContext().cancel(null)\n                return@repeat\n            }\n            decoder.getFrame(pos).let { frame ->\n                imageShareProvider.cacheImage(\n                    image = frame,\n                    imageInfo = ImageInfo(\n                        width = frame.width,\n                        height = frame.height,\n                        imageFormat = imageFormat,\n                        quality = quality\n                    )\n                )\n            }?.takeIf {\n                pos in indexes\n            }?.let { emit(it) }\n        }\n    }.catch {\n        onFailure(it)\n    }\n\n    private val String.jxl: ByteArray?\n        get() = bytes?.let { JxlCoder.Convenience.construct(it) }\n\n    private val String.jpeg: ByteArray?\n        get() = bytes?.let { JxlCoder.Convenience.reconstructJPEG(it) }\n\n    private val String.bytes: ByteArray?\n        get() = context\n            .contentResolver\n            .openInputStream(toUri())?.use {\n                it.readBytes()\n            }\n\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/di/JxlToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.di\n\nimport com.t8rin.imagetoolbox.feature.jxl_tools.data.AndroidJxlConverter\nimport com.t8rin.imagetoolbox.feature.jxl_tools.domain.JxlConverter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface JxlToolsModule {\n\n    @Binds\n    @Singleton\n    fun provideTranscoder(\n        converter: AndroidJxlConverter\n    ): JxlConverter\n\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/domain/AnimatedJxlParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\n\ndata class AnimatedJxlParams(\n    val size: IntegerSize?,\n    val repeatCount: Int,\n    val delay: Int,\n    val quality: Quality,\n    val isLossy: Boolean\n) {\n    companion object {\n        val Default by lazy {\n            AnimatedJxlParams(\n                size = null,\n                repeatCount = 1,\n                delay = 1000,\n                quality = Quality.Jxl(),\n                isLossy = true\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/domain/JxlConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport kotlinx.coroutines.flow.Flow\n\ninterface JxlConverter {\n\n    suspend fun jpegToJxl(\n        jpegUris: List<String>,\n        onFailure: (Throwable) -> Unit,\n        onProgress: suspend (originalUri: String, data: ByteArray) -> Unit\n    )\n\n    suspend fun jxlToJpeg(\n        jxlUris: List<String>,\n        onFailure: (Throwable) -> Unit,\n        onProgress: suspend (originalUri: String, data: ByteArray) -> Unit\n    )\n\n    suspend fun createJxlAnimation(\n        imageUris: List<String>,\n        params: AnimatedJxlParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): ByteArray?\n\n    fun extractFramesFromJxl(\n        jxlUri: String,\n        imageFormat: ImageFormat,\n        imageFrames: ImageFrames,\n        quality: Quality,\n        onFailure: (Throwable) -> Unit,\n        onGetFramesCount: (frames: Int) -> Unit = {}\n    ): Flow<String>\n\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/JxlToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Jxl\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.core.utils.isJxl\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components.JxlToolsBitmapPreview\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components.JxlToolsButtons\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components.JxlToolsControls\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components.JxlToolsNoDataControls\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components.JxlToolsTopAppBarActions\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent\n\n@Composable\nfun JxlToolsContent(\n    component: JxlToolsComponent\n) {\n    val pickJpegsLauncher = rememberFilePicker(\n        mimeType = MimeType.JpgAll,\n        onSuccess = { list: List<Uri> ->\n            list.let { uris ->\n                component.setType(\n                    type = Screen.JxlTools.Type.JpegToJxl(uris)\n                )\n            }\n        }\n    )\n\n    val pickJxlsLauncher = rememberFilePicker { list: List<Uri> ->\n        list.filter {\n            it.isJxl()\n        }.let { uris ->\n            if (uris.isEmpty()) {\n                AppToastHost.showToast(\n                    message = getString(R.string.select_jxl_image_to_start),\n                    icon = Icons.Filled.Jxl\n                )\n            } else {\n                component.setType(\n                    type = Screen.JxlTools.Type.JxlToJpeg(uris)\n                )\n            }\n        }\n    }\n\n    val pickSingleJxlLauncher = rememberFilePicker { uri: Uri ->\n        if (uri.isJxl()) {\n            component.setType(\n                type = Screen.JxlTools.Type.JxlToImage(uri)\n            )\n        } else {\n            AppToastHost.showToast(\n                message = getString(R.string.select_jxl_image_to_start),\n                icon = Icons.Filled.Jxl\n            )\n        }\n    }\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setType(\n            type = Screen.JxlTools.Type.ImageToJxl(uris)\n        )\n    }\n\n    val addImagesImagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setType(\n            type = Screen.JxlTools.Type.ImageToJxl(\n                (component.type as? Screen.JxlTools.Type.ImageToJxl)?.imageUris?.plus(uris)\n                    ?.distinct()\n            )\n        )\n    }\n\n    val addJpegsLauncher = rememberFilePicker(\n        mimeType = MimeType.JpgAll,\n        onSuccess = { list: List<Uri> ->\n            component.setType(\n                type = (component.type as? Screen.JxlTools.Type.JpegToJxl)?.let {\n                    it.copy(jpegImageUris = it.jpegImageUris?.plus(list)?.distinct())\n                }\n            )\n        }\n    )\n\n    val addJxlsLauncher = rememberFilePicker { list: List<Uri> ->\n        list.filter {\n            it.isJxl()\n        }.let { uris ->\n            if (uris.isEmpty()) {\n                AppToastHost.showToast(\n                    message = getString(R.string.select_jxl_image_to_start),\n                    icon = Icons.Filled.Jxl\n                )\n            } else {\n                component.setType(\n                    type = (component.type as? Screen.JxlTools.Type.JxlToJpeg)?.let {\n                        it.copy(jxlImageUris = it.jxlImageUris?.plus(uris)?.distinct())\n                    }\n                )\n            }\n        }\n    }\n\n    fun pickImage(type: Screen.JxlTools.Type? = null) {\n        when (type ?: component.type) {\n            is Screen.JxlTools.Type.ImageToJxl -> imagePicker.pickImage()\n            is Screen.JxlTools.Type.JpegToJxl -> pickJpegsLauncher.pickFile()\n            is Screen.JxlTools.Type.JxlToImage -> pickSingleJxlLauncher.pickFile()\n            else -> pickJxlsLauncher.pickFile()\n        }\n    }\n\n    val addImages: () -> Unit = {\n        when (component.type) {\n            is Screen.JxlTools.Type.ImageToJxl -> addImagesImagePicker.pickImage()\n            is Screen.JxlTools.Type.JpegToJxl -> addJpegsLauncher.pickFile()\n            else -> addJxlsLauncher.pickFile()\n        }\n    }\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = when (val type = component.type) {\n                    null -> stringResource(R.string.jxl_tools)\n                    else -> stringResource(type.title)\n                },\n                input = component.type,\n                isLoading = component.isLoading,\n                size = null\n            )\n        },\n        onGoBack = onBack,\n        topAppBarPersistentActions = {\n            JxlToolsTopAppBarActions(component = component)\n        },\n        actions = {\n            if (component.type is Screen.JxlTools.Type.JxlToImage) {\n                ShareButton(\n                    enabled = !component.isLoading && component.type != null,\n                    onShare = component::performSharing\n                )\n            }\n        },\n        imagePreview = {\n            JxlToolsBitmapPreview(\n                component = component,\n                onAddImages = addImages\n            )\n        },\n        placeImagePreview = component.type is Screen.JxlTools.Type.JxlToImage\n                || component.type is Screen.JxlTools.Type.ImageToJxl,\n        showImagePreviewAsStickyHeader = false,\n        autoClearFocus = false,\n        controls = {\n            JxlToolsControls(\n                component = component,\n                onAddImages = addImages\n            )\n        },\n        contentPadding = animateDpAsState(\n            if (component.type == null) 12.dp\n            else 20.dp\n        ).value,\n        buttons = { actions ->\n            JxlToolsButtons(\n                component = component,\n                actions = actions,\n                onPickImage = ::pickImage,\n                imagePicker = imagePicker\n            )\n        },\n        insetsForNoData = WindowInsets(0),\n        noDataControls = {\n            JxlToolsNoDataControls(::pickImage)\n        },\n        canShowScreenData = component.type != null\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component::clearAll,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/components/AnimatedJxlParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.EnergySavingsLeaf\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectLarge\nimport androidx.compose.material.icons.outlined.RepeatOne\nimport androidx.compose.material.icons.outlined.Timelapse\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.jxl_tools.domain.AnimatedJxlParams\nimport kotlin.math.roundToInt\n\n@Composable\nfun AnimatedJxlParamsSelector(\n    value: AnimatedJxlParams,\n    onValueChange: (AnimatedJxlParams) -> Unit\n) {\n    Column {\n        val size = value.size ?: IntegerSize.Undefined\n        AnimatedVisibility(size.isDefined()) {\n            ResizeImageField(\n                imageInfo = ImageInfo(size.width, size.height),\n                originalSize = null,\n                onWidthChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(width = it)\n                        )\n                    )\n                },\n                onHeightChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(height = it)\n                        )\n                    )\n                }\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.use_size_of_first_frame),\n            subtitle = stringResource(id = R.string.use_size_of_first_frame_sub),\n            checked = value.size == null,\n            onClick = {\n                onValueChange(\n                    value.copy(size = if (it) null else IntegerSize(1000, 1000))\n                )\n            },\n            startIcon = Icons.Outlined.PhotoSizeSelectLarge,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.lossy_compression),\n            subtitle = stringResource(id = R.string.lossy_compression_sub),\n            checked = value.isLossy,\n            onClick = {\n                onValueChange(\n                    value.copy(\n                        isLossy = it\n                    )\n                )\n            },\n            startIcon = Icons.Outlined.EnergySavingsLeaf,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        QualitySelector(\n            imageFormat = if (value.isLossy) {\n                ImageFormat.Jxl.Lossy\n            } else ImageFormat.Jxl.Lossless,\n            quality = value.quality,\n            onQualityChange = {\n                onValueChange(\n                    value.copy(\n                        quality = it\n                    )\n                )\n            }\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.repeatCount,\n            icon = Icons.Outlined.RepeatOne,\n            title = stringResource(id = R.string.repeat_count),\n            valueRange = 1f..10f,\n            steps = 9,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        repeatCount = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.delay,\n            icon = Icons.Outlined.Timelapse,\n            title = stringResource(id = R.string.frame_delay),\n            valueRange = 1f..4000f,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        delay = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n    }\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/components/JxlToolsBitmapPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageReorderCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagesPreviewWithSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent\n\n@Composable\ninternal fun JxlToolsBitmapPreview(\n    component: JxlToolsComponent,\n    onAddImages: () -> Unit\n) {\n    val uris = when (val type = component.type) {\n        is Screen.JxlTools.Type.JpegToJxl -> type.jpegImageUris\n        is Screen.JxlTools.Type.JxlToJpeg -> type.jxlImageUris\n        is Screen.JxlTools.Type.ImageToJxl -> type.imageUris\n        is Screen.JxlTools.Type.JxlToImage -> listOfNotNull(type.jxlUri)\n        null -> null\n    } ?: emptyList()\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    AnimatedContent(\n        targetState = component.isLoading to component.type\n    ) { (loading, type) ->\n        Box(\n            contentAlignment = Alignment.Center,\n            modifier = if (loading) {\n                Modifier.padding(32.dp)\n            } else Modifier\n        ) {\n            if (loading || type == null) {\n                EnhancedLoadingIndicator()\n            } else {\n                when (type) {\n                    is Screen.JxlTools.Type.JxlToImage -> {\n                        ImagesPreviewWithSelection(\n                            imageUris = component.convertedImageUris,\n                            imageFrames = component.imageFrames,\n                            onFrameSelectionChange = component::updateJxlFrames,\n                            isPortrait = isPortrait,\n                            isLoadingImages = component.isLoadingJxlImages\n                        )\n                    }\n\n                    is Screen.JxlTools.Type.ImageToJxl -> {\n                        ImageReorderCarousel(\n                            images = uris,\n                            modifier = Modifier\n                                .padding(top = if (isPortrait) 24.dp else 0.dp)\n                                .container(\n                                    shape = ShapeDefaults.extraLarge,\n                                    color = if (isPortrait) {\n                                        Color.Unspecified\n                                    } else MaterialTheme.colorScheme.surface\n                                ),\n                            onReorder = {\n                                component.setType(\n                                    Screen.JxlTools.Type.ImageToJxl(it)\n                                )\n                            },\n                            onNeedToAddImage = onAddImages,\n                            onNeedToRemoveImageAt = {\n                                component.setType(\n                                    Screen.JxlTools.Type.ImageToJxl(\n                                        (component.type as Screen.JxlTools.Type.ImageToJxl)\n                                            .imageUris?.toMutableList()\n                                            ?.apply {\n                                                removeAt(it)\n                                            }\n                                    )\n                                )\n                            },\n                            onNavigate = component.onNavigate\n                        )\n                        Spacer(modifier = Modifier.height(12.dp))\n                    }\n\n                    else -> Unit\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/components/JxlToolsButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components\n\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent\n\n@Composable\ninternal fun JxlToolsButtons(\n    component: JxlToolsComponent,\n    actions: @Composable RowScope.() -> Unit,\n    onPickImage: () -> Unit,\n    imagePicker: ImagePicker\n) {\n    val uris = when (val type = component.type) {\n        is Screen.JxlTools.Type.JpegToJxl -> type.jpegImageUris\n        is Screen.JxlTools.Type.JxlToJpeg -> type.jxlImageUris\n        is Screen.JxlTools.Type.ImageToJxl -> type.imageUris\n        is Screen.JxlTools.Type.JxlToImage -> listOfNotNull(type.jxlUri)\n        null -> null\n    } ?: emptyList()\n\n    val save: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.save(\n            oneTimeSaveLocationUri = it\n        )\n    }\n    var showFolderSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    BottomButtonsBlock(\n        isNoData = component.type == null,\n        onSecondaryButtonClick = onPickImage,\n        isPrimaryButtonVisible = component.canSave,\n        onPrimaryButtonClick = {\n            save(null)\n        },\n        onPrimaryButtonLongClick = {\n            showFolderSelectionDialog = true\n        },\n        actions = {\n            if (component.type is Screen.JxlTools.Type.JxlToImage) {\n                actions()\n            } else {\n                EnhancedChip(\n                    selected = true,\n                    onClick = null,\n                    selectedColor = MaterialTheme.colorScheme.secondaryContainer,\n                    modifier = Modifier.padding(8.dp)\n                ) {\n                    Text(uris.size.toString())\n                }\n            }\n        },\n        showNullDataButtonAsContainer = true,\n        onSecondaryButtonLongClick = if (component.type is Screen.JxlTools.Type.ImageToJxl || component.type == null) {\n            {\n                showOneTimeImagePickingDialog = true\n            }\n        } else null\n    )\n    OneTimeSaveLocationSelectionDialog(\n        visible = showFolderSelectionDialog,\n        onDismiss = { showFolderSelectionDialog = false },\n        onSaveRequest = save\n    )\n    OneTimeImagePickingDialog(\n        onDismiss = { showOneTimeImagePickingDialog = false },\n        picker = Picker.Multiple,\n        imagePicker = imagePicker,\n        visible = showOneTimeImagePickingDialog\n    )\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/components/JxlToolsControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent\n\n@Composable\ninternal fun JxlToolsControls(\n    component: JxlToolsComponent,\n    onAddImages: () -> Unit\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    when (component.type) {\n        is Screen.JxlTools.Type.JxlToImage -> {\n            Spacer(modifier = Modifier.height(16.dp))\n            ImageFormatSelector(\n                value = component.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = component.params.quality,\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            QualitySelector(\n                imageFormat = component.imageFormat,\n                quality = component.params.quality,\n                onQualityChange = {\n                    component.updateParams(\n                        component.params.copy(\n                            quality = it\n                        )\n                    )\n                }\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n        }\n\n        is Screen.JxlTools.Type.JpegToJxl,\n        is Screen.JxlTools.Type.JxlToJpeg -> {\n            val uris = when (val type = component.type) {\n                is Screen.JxlTools.Type.JpegToJxl -> type.jpegImageUris\n                is Screen.JxlTools.Type.JxlToJpeg -> type.jxlImageUris\n                is Screen.JxlTools.Type.ImageToJxl -> type.imageUris\n                is Screen.JxlTools.Type.JxlToImage -> listOfNotNull(type.jxlUri)\n                null -> null\n            } ?: emptyList()\n\n            UrisPreview(\n                modifier = Modifier\n                    .padding(\n                        vertical = if (isPortrait) 24.dp else 8.dp\n                    ),\n                uris = uris,\n                isPortrait = true,\n                onRemoveUri = component::removeUri,\n                onAddUris = onAddImages\n            )\n        }\n\n        is Screen.JxlTools.Type.ImageToJxl -> {\n            AnimatedJxlParamsSelector(\n                value = component.params,\n                onValueChange = component::updateParams\n            )\n        }\n\n        else -> Unit\n    }\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/components/JxlToolsNoDataControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n\n@Composable\ninternal fun JxlToolsNoDataControls(\n    onPickImage: (Screen.JxlTools.Type) -> Unit\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    val types = remember {\n        Screen.JxlTools.Type.entries\n    }\n    val preference1 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[0].title),\n            subtitle = stringResource(types[0].subtitle),\n            startIcon = types[0].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onPickImage(types[0])\n            }\n        )\n    }\n    val preference2 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[1].title),\n            subtitle = stringResource(types[1].subtitle),\n            startIcon = types[1].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onPickImage(types[1])\n            }\n        )\n    }\n    val preference3 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[2].title),\n            subtitle = stringResource(types[2].subtitle),\n            startIcon = types[2].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onPickImage(types[2])\n            }\n        )\n    }\n    val preference4 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[3].title),\n            subtitle = stringResource(types[3].subtitle),\n            startIcon = types[3].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                onPickImage(types[3])\n            }\n        )\n    }\n    if (isPortrait) {\n        Column {\n            preference1()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference2()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference3()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference4()\n        }\n    } else {\n        val direction = LocalLayoutDirection.current\n        val cutout = WindowInsets.displayCutout.asPaddingValues().let {\n            PaddingValues(\n                start = it.calculateStartPadding(direction),\n                end = it.calculateEndPadding(direction)\n            )\n        }\n\n        Column {\n            Row(\n                modifier = Modifier.padding(cutout)\n            ) {\n                preference1.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference2.withModifier(modifier = Modifier.weight(1f))\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            Row(\n                modifier = Modifier.padding(cutout)\n            ) {\n                preference3.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference4.withModifier(modifier = Modifier.weight(1f))\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/components/JxlToolsTopAppBarActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent\n\n@Composable\ninternal fun RowScope.JxlToolsTopAppBarActions(\n    component: JxlToolsComponent\n) {\n    val isJxlToImage = component.type is Screen.JxlTools.Type.JxlToImage\n    if (component.type == null) TopAppBarEmoji()\n    else if (!isJxlToImage) {\n        ShareButton(\n            enabled = !component.isLoading && component.type != null,\n            onShare = component::performSharing\n        )\n    }\n    val pagesSize by remember(component.imageFrames, component.convertedImageUris) {\n        derivedStateOf {\n            component.imageFrames.getFramePositions(component.convertedImageUris.size).size\n        }\n    }\n    AnimatedVisibility(\n        visible = isJxlToImage && pagesSize != component.convertedImageUris.size,\n        enter = fadeIn() + scaleIn() + expandHorizontally(),\n        exit = fadeOut() + scaleOut() + shrinkHorizontally()\n    ) {\n        EnhancedIconButton(\n            onClick = component::selectAllConvertedImages\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.SelectAll,\n                contentDescription = \"Select All\"\n            )\n        }\n    }\n    AnimatedVisibility(\n        modifier = Modifier\n            .padding(8.dp)\n            .container(\n                shape = ShapeDefaults.circle,\n                color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                resultPadding = 0.dp\n            ),\n        visible = isJxlToImage && pagesSize != 0\n    ) {\n        Row(\n            modifier = Modifier.padding(start = 12.dp),\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.Center\n        ) {\n            pagesSize.takeIf { it != 0 }?.let {\n                Spacer(Modifier.width(8.dp))\n                Text(\n                    text = it.toString(),\n                    fontSize = 20.sp,\n                    fontWeight = FontWeight.Medium\n                )\n            }\n            EnhancedIconButton(\n                onClick = component::clearConvertedImagesSelection\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Close,\n                    contentDescription = stringResource(R.string.close)\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/jxl-tools/src/main/java/com/t8rin/imagetoolbox/feature/jxl_tools/presentation/screenLogic/JxlToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FileSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.jxl_tools.domain.AnimatedJxlParams\nimport com.t8rin.imagetoolbox.feature.jxl_tools.domain.JxlConverter\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.onCompletion\n\nclass JxlToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialType: Screen.JxlTools.Type?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val jxlConverter: JxlConverter,\n    private val fileController: FileController,\n    private val filenameCreator: FilenameCreator,\n    private val shareProvider: ShareProvider,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialType?.let(::setType)\n        }\n    }\n\n    private val _type: MutableState<Screen.JxlTools.Type?> = mutableStateOf(null)\n    val type by _type\n\n    private val _isLoading: MutableState<Boolean> = mutableStateOf(false)\n    val isLoading by _isLoading\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Png.Lossless)\n    val imageFormat by _imageFormat\n\n    private val _imageFrames: MutableState<ImageFrames> = mutableStateOf(ImageFrames.All)\n    val imageFrames by _imageFrames\n\n    private val _isLoadingJxlImages: MutableState<Boolean> = mutableStateOf(false)\n    val isLoadingJxlImages by _isLoadingJxlImages\n\n    private val _params: MutableState<AnimatedJxlParams> = mutableStateOf(AnimatedJxlParams.Default)\n    val params by _params\n\n    private val _convertedImageUris: MutableState<List<String>> = mutableStateOf(emptyList())\n    val convertedImageUris by _convertedImageUris\n\n    fun setType(\n        type: Screen.JxlTools.Type?\n    ) {\n        when (type) {\n            is Screen.JxlTools.Type.JpegToJxl -> {\n                if (!type.jpegImageUris.isNullOrEmpty()) _type.update { type }\n                else _type.update { null }\n            }\n\n            is Screen.JxlTools.Type.JxlToJpeg -> {\n                if (!type.jxlImageUris.isNullOrEmpty()) _type.update { type }\n                else _type.update { null }\n            }\n\n            is Screen.JxlTools.Type.JxlToImage -> {\n                type.jxlUri?.let(::setJxlUri) ?: _type.update { null }\n            }\n\n            else -> _type.update { type }\n        }\n        registerChanges()\n        if (_type.value == null) {\n            clearAll()\n        } else if (!_type.value!!::class.isInstance(type)) {\n            clearAll()\n        }\n    }\n\n    private var collectionJob: Job? by smartJob {\n        _isLoading.update { false }\n    }\n\n    private fun setJxlUri(uri: Uri) {\n        clearAll()\n        _type.update {\n            Screen.JxlTools.Type.JxlToImage(uri)\n        }\n        updateJxlFrames(ImageFrames.All)\n        collectionJob = componentScope.launch {\n            _isLoading.update { true }\n            _isLoadingJxlImages.update { true }\n            jxlConverter.extractFramesFromJxl(\n                jxlUri = uri.toString(),\n                imageFormat = imageFormat,\n                quality = params.quality,\n                imageFrames = imageFrames,\n                onFailure = AppToastHost::showFailureToast\n            ).onCompletion {\n                _isLoading.update { false }\n                _isLoadingJxlImages.update { false }\n            }.collect { nextUri ->\n                if (isLoading) {\n                    _isLoading.update { false }\n                }\n                _convertedImageUris.update { it + nextUri }\n            }\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun save(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.JxlTools.Type.JpegToJxl -> {\n                    val results = mutableListOf<SaveResult>()\n                    val jpegUris = type.jpegImageUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = jpegUris.size\n                    jxlConverter.jpegToJxl(\n                        jpegUris = jpegUris,\n                        onFailure = {\n                            results.add(SaveResult.Error.Exception(it))\n                        }\n                    ) { uri, jxlBytes ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = JxlSaveTarget(uri, jxlBytes),\n                                keepOriginalMetadata = false,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    parseSaveResults(results.onSuccess(::registerSave))\n                }\n\n                is Screen.JxlTools.Type.JxlToJpeg -> {\n                    val results = mutableListOf<SaveResult>()\n                    val jxlUris = type.jxlImageUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = jxlUris.size\n                    jxlConverter.jxlToJpeg(\n                        jxlUris = jxlUris,\n                        onFailure = {\n                            results.add(SaveResult.Error.Exception(it))\n                        }\n                    ) { uri, jpegBytes ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = JpegSaveTarget(uri, jpegBytes),\n                                keepOriginalMetadata = false,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    parseSaveResults(results.onSuccess(::registerSave))\n                }\n\n                is Screen.JxlTools.Type.JxlToImage -> {\n                    val results = mutableListOf<SaveResult>()\n                    type.jxlUri?.toString()?.also { jxlUri ->\n                        _left.value = 0\n                        jxlConverter.extractFramesFromJxl(\n                            jxlUri = jxlUri,\n                            imageFormat = imageFormat,\n                            quality = params.quality,\n                            imageFrames = imageFrames,\n                            onFailure = {\n                                results.add(SaveResult.Error.Exception(it))\n                            },\n                            onGetFramesCount = {\n                                if (it == 0) {\n                                    _isSaving.value = false\n                                    savingJob?.cancel()\n                                    parseSaveResults(\n                                        listOf(SaveResult.Error.MissingPermissions)\n                                    )\n                                }\n                                _left.value = imageFrames.getFramePositions(it).size\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            }\n                        ).onCompletion {\n                            parseSaveResults(results.onSuccess(::registerSave))\n                        }.collect { uri ->\n                            imageGetter.getImage(\n                                data = uri,\n                                originalSize = true\n                            )?.let { localBitmap ->\n                                val imageInfo = ImageInfo(\n                                    imageFormat = imageFormat,\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                )\n\n                                results.add(\n                                    fileController.save(\n                                        saveTarget = ImageSaveTarget(\n                                            imageInfo = imageInfo,\n                                            originalUri = uri,\n                                            sequenceNumber = _done.value + 1,\n                                            data = imageCompressor.compressAndTransform(\n                                                image = localBitmap,\n                                                imageInfo = ImageInfo(\n                                                    imageFormat = imageFormat,\n                                                    quality = params.quality,\n                                                    width = localBitmap.width,\n                                                    height = localBitmap.height\n                                                )\n                                            )\n                                        ),\n                                        keepOriginalMetadata = false,\n                                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                                    )\n                                )\n                            } ?: results.add(\n                                SaveResult.Error.Exception(Throwable())\n                            )\n                            _done.value++\n                            updateProgress(\n                                done = done,\n                                total = left\n                            )\n                        }\n                    }\n                }\n\n                is Screen.JxlTools.Type.ImageToJxl -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    type.imageUris?.map { it.toString() }?.let { list ->\n                        jxlConverter.createJxlAnimation(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            },\n                            onFailure = {\n                                parseSaveResults(\n                                    listOf(\n                                        SaveResult.Error.Exception(it)\n                                    )\n                                )\n                            },\n                        )?.also { jxlBytes ->\n                            val result = fileController.save(\n                                saveTarget = JxlSaveTarget(\"\", jxlBytes),\n                                keepOriginalMetadata = false,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            ).onSuccess(::registerSave)\n                            parseSaveResults(listOf(result))\n                        }\n                    }\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    private fun JpegSaveTarget(\n        uri: String,\n        jpegBytes: ByteArray\n    ): SaveTarget = FileSaveTarget(\n        originalUri = uri,\n        filename = filename(\n            uri = uri,\n            format = ImageFormat.Jpg\n        ),\n        data = jpegBytes,\n        imageFormat = ImageFormat.Jpg\n    )\n\n    private fun JxlSaveTarget(\n        uri: String,\n        jxlBytes: ByteArray\n    ): SaveTarget = FileSaveTarget(\n        originalUri = uri,\n        filename = filename(\n            uri = uri,\n            format = ImageFormat.Jxl.Lossless\n        ),\n        data = jxlBytes,\n        imageFormat = ImageFormat.Jxl.Lossless\n    )\n\n    private fun filename(\n        uri: String,\n        format: ImageFormat\n    ): String = filenameCreator.constructImageFilename(\n        ImageSaveTarget(\n            imageInfo = ImageInfo(\n                imageFormat = format,\n                originalUri = uri\n            ),\n            originalUri = uri,\n            sequenceNumber = done + 1,\n            metadata = null,\n            data = ByteArray(0)\n        ),\n        forceNotAddSizeInFilename = true\n    )\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun performSharing() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.JxlTools.Type.JpegToJxl -> {\n                    val results = mutableListOf<String?>()\n                    val jpegUris = type.jpegImageUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = jpegUris.size\n                    jxlConverter.jpegToJxl(\n                        jpegUris = jpegUris,\n                        onFailure = AppToastHost::showFailureToast\n                    ) { uri, jxlBytes ->\n                        results.add(\n                            shareProvider.cacheByteArray(\n                                byteArray = jxlBytes,\n                                filename = filename(uri, ImageFormat.Jxl.Lossless)\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    shareProvider.shareUris(results.filterNotNull())\n                    AppToastHost.showConfetti()\n                }\n\n                is Screen.JxlTools.Type.JxlToJpeg -> {\n                    val results = mutableListOf<String?>()\n                    val jxlUris = type.jxlImageUris?.map {\n                        it.toString()\n                    } ?: emptyList()\n\n                    _left.value = jxlUris.size\n                    jxlConverter.jxlToJpeg(\n                        jxlUris = jxlUris,\n                        onFailure = AppToastHost::showFailureToast\n                    ) { uri, jpegBytes ->\n                        results.add(\n                            shareProvider.cacheByteArray(\n                                byteArray = jpegBytes,\n                                filename = filename(uri, ImageFormat.Jpg)\n                            )\n                        )\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n\n                    shareProvider.shareUris(results.filterNotNull())\n                    AppToastHost.showConfetti()\n                }\n\n                is Screen.JxlTools.Type.JxlToImage -> {\n                    _left.value = -1\n                    val positions =\n                        imageFrames.getFramePositions(convertedImageUris.size).map { it - 1 }\n                    val uris = convertedImageUris.filterIndexed { index, _ ->\n                        index in positions\n                    }\n                    shareProvider.shareUris(uris)\n                    AppToastHost.showConfetti()\n                }\n\n                is Screen.JxlTools.Type.ImageToJxl -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    type.imageUris?.map { it.toString() }?.let { list ->\n                        jxlConverter.createJxlAnimation(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            },\n                            onFailure = {\n                                _isSaving.value = false\n                                savingJob?.cancel()\n                                AppToastHost.showFailureToast(it)\n                            }\n                        )?.also { byteArray ->\n                            shareProvider.shareByteArray(\n                                byteArray = byteArray,\n                                filename = \"JXL_${timestamp()}.jxl\",\n                                onComplete = AppToastHost::showConfetti\n                            )\n                        }\n                    }\n                }\n\n                null -> Unit\n            }\n\n            _isSaving.value = false\n        }\n    }\n\n    fun clearAll() {\n        collectionJob?.cancel()\n        collectionJob = null\n        _type.update { null }\n        _convertedImageUris.update { emptyList() }\n        savingJob?.cancel()\n        savingJob = null\n        updateParams(AnimatedJxlParams.Default)\n        registerChangesCleared()\n    }\n\n    fun removeUri(uri: Uri) {\n        setType(\n            when (val type = _type.value) {\n                is Screen.JxlTools.Type.JpegToJxl -> type.copy(\n                    jpegImageUris = type.jpegImageUris?.minus(uri)\n                )\n\n                is Screen.JxlTools.Type.JxlToJpeg -> type.copy(\n                    jxlImageUris = type.jxlImageUris?.minus(uri)\n                )\n\n                is Screen.JxlTools.Type.ImageToJxl -> type.copy(\n                    imageUris = type.imageUris?.minus(uri)\n                )\n\n                is Screen.JxlTools.Type.JxlToImage -> type\n                null -> null\n            }\n        )\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        registerChanges()\n    }\n\n    fun updateJxlFrames(imageFrames: ImageFrames) {\n        _imageFrames.update { imageFrames }\n        registerChanges()\n    }\n\n    fun updateParams(params: AnimatedJxlParams) {\n        _params.update { params }\n        registerChanges()\n    }\n\n    fun clearConvertedImagesSelection() = updateJxlFrames(ImageFrames.ManualSelection(emptyList()))\n\n    fun selectAllConvertedImages() = updateJxlFrames(ImageFrames.All)\n\n    val canSave: Boolean\n        get() = (imageFrames == ImageFrames.All)\n            .or(type !is Screen.JxlTools.Type.JxlToImage)\n            .or((imageFrames as? ImageFrames.ManualSelection)?.framePositions?.isNotEmpty() == true)\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialType: Screen.JxlTools.Type?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): JxlToolsComponent\n    }\n\n}"
  },
  {
    "path": "feature/libraries-info/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/libraries-info/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.libraries_info\"\n\ndependencies {\n    implementation(libs.aboutlibraries.m3)\n}"
  },
  {
    "path": "feature/libraries-info/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/libraries-info/src/main/java/com/t8rin/imagetoolbox/feature/libraries_info/presentation/LibrariesInfoContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.libraries_info.presentation\n\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.plus\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.mikepenz.aboutlibraries.Libs\nimport com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults\nimport com.mikepenz.aboutlibraries.ui.compose.m3.chipColors\nimport com.mikepenz.aboutlibraries.ui.compose.m3.libraryColors\nimport com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent\nimport com.mikepenz.aboutlibraries.util.withContext\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.libraries_info.presentation.components.LibrariesContainer\nimport com.t8rin.imagetoolbox.feature.libraries_info.presentation.components.link\nimport com.t8rin.imagetoolbox.feature.libraries_info.presentation.screenLogic.LibrariesInfoComponent\nimport kotlinx.collections.immutable.toPersistentList\n\n\n@Composable\nfun LibrariesInfoContent(\n    component: LibrariesInfoComponent\n) {\n    val context = LocalContext.current\n\n    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n    Scaffold(\n        modifier = Modifier\n            .fillMaxSize()\n            .nestedScroll(scrollBehavior.nestedScrollConnection),\n        topBar = {\n            EnhancedTopAppBar(\n                title = {\n                    Text(\n                        text = stringResource(id = R.string.open_source_licenses),\n                        modifier = Modifier.marquee()\n                    )\n                },\n                navigationIcon = {\n                    EnhancedIconButton(\n                        onClick = component.onGoBack\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                            contentDescription = null\n                        )\n                    }\n                },\n                actions = {\n                    TopAppBarEmoji()\n                },\n                type = EnhancedTopAppBarType.Large,\n                scrollBehavior = scrollBehavior\n            )\n        }\n    ) { contentPadding ->\n        val linkHandler = LocalUriHandler.current\n\n        val libraries = remember(context) {\n            Libs.Builder()\n                .withContext(context)\n                .build().let { libs ->\n                    libs.copy(\n                        libraries = libs.libraries.distinctBy {\n                            it.name\n                        }.filter { it.licenses.isNotEmpty() }.sortedWith(\n                            compareBy(\n                                { !it.name.contains(\"T8RIN\", true) },\n                                { it.name }\n                            ),\n                        ).toPersistentList()\n                    )\n                }\n        }\n\n        LibrariesContainer(\n            libraries = libraries,\n            modifier = Modifier.fillMaxSize(),\n            contentPadding = contentPadding + PaddingValues(12.dp),\n            dimensions = LibraryDefaults.libraryDimensions(\n                itemSpacing = 4.dp\n            ),\n            colors = LibraryDefaults.libraryColors(\n                versionChipColors = LibraryDefaults.chipColors(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(0.5f),\n                    contentColor = MaterialTheme.colorScheme.onSecondaryContainer\n                )\n            ),\n            onLibraryClick = { library ->\n                val license = library.licenses.firstOrNull()\n                val url = library.link()\n\n                if (!license?.htmlReadyLicenseContent.isNullOrBlank()) {\n                    component.selectLibrary(library)\n                } else if (!url.isNullOrBlank()) {\n                    linkHandler.openUri(url)\n                }\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/libraries-info/src/main/java/com/t8rin/imagetoolbox/feature/libraries_info/presentation/components/LibrariesContainer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.libraries_info.presentation.components\n\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ExperimentalLayoutApi\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.FlowRowScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.LazyItemScope\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.Typography\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.pointer.PointerIcon\nimport androidx.compose.ui.input.pointer.pointerHoverIcon\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.mikepenz.aboutlibraries.Libs\nimport com.mikepenz.aboutlibraries.entity.Funding\nimport com.mikepenz.aboutlibraries.entity.Library\nimport com.mikepenz.aboutlibraries.entity.License\nimport com.mikepenz.aboutlibraries.ui.compose.LibraryColors\nimport com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults\nimport com.mikepenz.aboutlibraries.ui.compose.LibraryDimensions\nimport com.mikepenz.aboutlibraries.ui.compose.LibraryPadding\nimport com.mikepenz.aboutlibraries.ui.compose.LibraryShapes\nimport com.mikepenz.aboutlibraries.ui.compose.LibraryTextStyles\nimport com.mikepenz.aboutlibraries.ui.compose.m3.component.LibraryChip\nimport com.mikepenz.aboutlibraries.ui.compose.m3.libraryColors\nimport com.mikepenz.aboutlibraries.ui.compose.util.author\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.collections.immutable.persistentListOf\nimport kotlinx.collections.immutable.toPersistentList\n\n\n@Composable\ninternal fun LibrariesContainer(\n    libraries: Libs?,\n    modifier: Modifier = Modifier,\n    libraryModifier: Modifier = Modifier,\n    lazyListState: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    showAuthor: Boolean = true,\n    showDescription: Boolean = true,\n    showVersion: Boolean = true,\n    showLicenseBadges: Boolean = true,\n    showFundingBadges: Boolean = true,\n    typography: Typography = MaterialTheme.typography,\n    colors: LibraryColors = LibraryDefaults.libraryColors(),\n    padding: LibraryPadding = LibraryDefaults.libraryPadding(),\n    dimensions: LibraryDimensions = LibraryDefaults.libraryDimensions(),\n    textStyles: LibraryTextStyles = LibraryDefaults.libraryTextStyles(),\n    shapes: LibraryShapes = LibraryDefaults.libraryShapes(),\n    onLibraryClick: ((Library) -> Unit)? = null,\n    onFundingClick: ((Funding) -> Unit)? = null,\n    name: @Composable BoxScope.(name: String) -> Unit = {\n        DefaultLibraryName(\n            it,\n            textStyles,\n            colors,\n            typography\n        )\n    },\n    version: (@Composable BoxScope.(version: String) -> Unit)? = { version ->\n        if (showVersion) DefaultLibraryVersion(\n            version,\n            textStyles,\n            colors,\n            typography,\n            padding,\n            dimensions,\n            shapes\n        )\n    },\n    author: (@Composable BoxScope.(authors: String) -> Unit)? = { author ->\n        if (showAuthor && author.isNotBlank()) DefaultLibraryAuthor(\n            author,\n            textStyles,\n            colors,\n            typography\n        )\n    },\n    description: (@Composable BoxScope.(description: String) -> Unit)? = { description ->\n        if (showDescription) DefaultLibraryDescription(description, textStyles, colors, typography)\n    },\n    license: (@Composable FlowRowScope.(license: License) -> Unit)? = { license ->\n        if (showLicenseBadges) DefaultLibraryLicense(\n            license,\n            textStyles,\n            colors,\n            padding,\n            dimensions,\n            shapes\n        )\n    },\n    funding: (@Composable FlowRowScope.(funding: Funding) -> Unit)? = { funding ->\n        if (showFundingBadges) DefaultLibraryFunding(\n            funding,\n            textStyles,\n            colors,\n            padding,\n            dimensions,\n            shapes,\n            onFundingClick\n        )\n    },\n    actions: (@Composable FlowRowScope.(library: Library) -> Unit)? = null,\n    header: (LazyListScope.() -> Unit)? = null,\n    divider: (@Composable LazyItemScope.() -> Unit)? = null,\n    footer: (LazyListScope.() -> Unit)? = null,\n) {\n    val libs = remember(libraries) {\n        libraries?.libraries?.toPersistentList() ?: persistentListOf()\n    }\n\n    LibrariesScaffold(\n        libraries = libs,\n        modifier = modifier,\n        libraryModifier = libraryModifier.background(colors.libraryBackgroundColor),\n        lazyListState = lazyListState,\n        contentPadding = contentPadding,\n        padding = padding,\n        dimensions = dimensions,\n        name = name,\n        version = version,\n        author = author,\n        description = description,\n        license = license,\n        funding = funding,\n        actions = actions,\n        header = header,\n        divider = divider,\n        footer = footer,\n        onLibraryClick = { library ->\n            if (onLibraryClick != null) {\n                onLibraryClick(library)\n                true\n            } else {\n                false\n            }\n        },\n    )\n}\n\nprivate val DefaultLibraryName: @Composable BoxScope.(name: String, textStyles: LibraryTextStyles, colors: LibraryColors, typography: Typography) -> Unit =\n    { libraryName, textStyles, colors, typography ->\n        Text(\n            text = libraryName,\n            style = textStyles.nameTextStyle ?: typography.titleLarge,\n            color = colors.libraryContentColor,\n            maxLines = textStyles.nameMaxLines,\n            overflow = textStyles.nameOverflow,\n        )\n    }\n\nprivate val DefaultLibraryVersion: @Composable BoxScope.(version: String, textStyles: LibraryTextStyles, colors: LibraryColors, typography: Typography, padding: LibraryPadding, dimensions: LibraryDimensions, shapes: LibraryShapes) -> Unit =\n    { version, textStyles, colors, typography, padding, dimensions, shapes ->\n        LibraryChip(\n            modifier = Modifier.padding(padding.versionPadding.containerPadding),\n            minHeight = dimensions.chipMinHeight,\n            containerColor = colors.versionChipColors.containerColor,\n            contentColor = colors.versionChipColors.contentColor,\n            shape = shapes.chipShape,\n        ) {\n            Text(\n                modifier = Modifier.padding(padding.versionPadding.contentPadding),\n                text = version,\n                style = textStyles.versionTextStyle ?: typography.bodyMedium,\n                maxLines = textStyles.versionMaxLines,\n                textAlign = TextAlign.Center,\n                overflow = textStyles.defaultOverflow,\n            )\n        }\n    }\n\nprivate val DefaultLibraryAuthor: @Composable BoxScope.(author: String, textStyles: LibraryTextStyles, colors: LibraryColors, typography: Typography) -> Unit =\n    { author, textStyles, colors, typography ->\n        Text(\n            text = author,\n            style = textStyles.authorTextStyle ?: typography.bodyMedium,\n            color = colors.libraryContentColor,\n            maxLines = textStyles.authorMaxLines,\n            overflow = textStyles.defaultOverflow,\n            textAlign = TextAlign.End,\n            modifier = Modifier\n                .fillMaxWidth()\n                .marquee()\n        )\n    }\n\nprivate val DefaultLibraryDescription: @Composable BoxScope.(description: String, textStyles: LibraryTextStyles, colors: LibraryColors, typography: Typography) -> Unit =\n    { description, textStyles, colors, typography ->\n        Text(\n            text = description,\n            style = textStyles.descriptionTextStyle ?: typography.bodySmall,\n            color = colors.libraryContentColor,\n            maxLines = textStyles.descriptionMaxLines,\n            overflow = textStyles.defaultOverflow,\n        )\n    }\n\nprivate val DefaultLibraryLicense: @Composable FlowRowScope.(license: License, textStyles: LibraryTextStyles, colors: LibraryColors, padding: LibraryPadding, dimensions: LibraryDimensions, shapes: LibraryShapes) -> Unit =\n    { license, textStyles, colors, padding, dimensions, shapes ->\n        LibraryChip(\n            modifier = Modifier.padding(padding.licensePadding.containerPadding),\n            minHeight = dimensions.chipMinHeight,\n            containerColor = colors.licenseChipColors.containerColor,\n            contentColor = colors.licenseChipColors.contentColor,\n            shape = shapes.chipShape,\n        ) {\n            Text(\n                modifier = Modifier.padding(padding.licensePadding.contentPadding),\n                maxLines = 1,\n                text = license.name,\n                style = textStyles.licensesTextStyle ?: LocalTextStyle.current,\n                textAlign = TextAlign.Center,\n                overflow = textStyles.defaultOverflow,\n            )\n        }\n    }\n\nprivate val DefaultLibraryFunding: @Composable FlowRowScope.(funding: Funding, textStyles: LibraryTextStyles, colors: LibraryColors, padding: LibraryPadding, dimensions: LibraryDimensions, shapes: LibraryShapes, onFundingClick: ((Funding) -> Unit)?) -> Unit =\n    { funding, textStyles, colors, padding, dimensions, shapes, onFundingClick ->\n        val uriHandler = LocalUriHandler.current\n        LibraryChip(\n            modifier = Modifier\n                .padding(padding.fundingPadding.containerPadding)\n                .pointerHoverIcon(PointerIcon.Hand),\n            onClick = {\n                if (onFundingClick != null) {\n                    onFundingClick(funding)\n                } else {\n                    try {\n                        uriHandler.openUri(funding.url)\n                    } catch (t: Throwable) {\n                        println(\"Failed to open funding url: ${funding.url} // ${t.message}\")\n                    }\n                }\n            },\n            minHeight = dimensions.chipMinHeight,\n            containerColor = colors.fundingChipColors.containerColor,\n            contentColor = colors.fundingChipColors.contentColor,\n            shape = shapes.chipShape,\n        ) {\n            Text(\n                modifier = Modifier.padding(padding.fundingPadding.contentPadding),\n                maxLines = 1,\n                text = funding.platform,\n                style = textStyles.fundingTextStyle ?: LocalTextStyle.current,\n                textAlign = TextAlign.Center,\n                overflow = textStyles.defaultOverflow,\n            )\n        }\n    }\n\n@Composable\nprivate fun LibrariesScaffold(\n    libraries: ImmutableList<Library>,\n    modifier: Modifier = Modifier,\n    libraryModifier: Modifier = Modifier,\n    lazyListState: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    padding: LibraryPadding = LibraryDefaults.libraryPadding(),\n    dimensions: LibraryDimensions = LibraryDefaults.libraryDimensions(),\n    name: @Composable BoxScope.(name: String) -> Unit = {},\n    version: (@Composable BoxScope.(version: String) -> Unit)? = null,\n    author: (@Composable BoxScope.(authors: String) -> Unit)? = null,\n    description: (@Composable BoxScope.(description: String) -> Unit)? = null,\n    license: (@Composable FlowRowScope.(license: License) -> Unit)? = null,\n    funding: (@Composable FlowRowScope.(funding: Funding) -> Unit)? = null,\n    actions: (@Composable FlowRowScope.(library: Library) -> Unit)? = null,\n    header: (LazyListScope.() -> Unit)? = null,\n    divider: (@Composable LazyItemScope.() -> Unit)? = null,\n    footer: (LazyListScope.() -> Unit)? = null,\n    onLibraryClick: ((Library) -> Boolean)? = { false },\n) {\n    val uriHandler = LocalUriHandler.current\n    LazyColumn(\n        modifier = modifier,\n        verticalArrangement = Arrangement.spacedBy(dimensions.itemSpacing),\n        state = lazyListState,\n        contentPadding = contentPadding,\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        header?.invoke(this)\n        itemsIndexed(libraries) { index, library ->\n            val interactionSource = remember { MutableInteractionSource() }\n            LibraryScaffoldLayout(\n                modifier = libraryModifier\n                    .container(\n                        shape = shapeByInteraction(\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = libraries.size,\n                            ),\n                            pressedShape = ShapeDefaults.pressed,\n                            interactionSource = interactionSource\n                        ),\n                        resultPadding = 0.dp\n                    )\n                    .hapticsClickable(\n                        indication = LocalIndication.current,\n                        interactionSource = interactionSource\n                    ) {\n                        val license = library.licenses.firstOrNull()\n                        val handled = onLibraryClick?.invoke(library) ?: false\n\n                        if (!handled && !license?.url.isNullOrBlank()) {\n                            license.url?.also {\n                                try {\n                                    uriHandler.openUri(it)\n                                } catch (t: Throwable) {\n                                    println(\"Failed to open url: $it // ${t.message}\")\n                                }\n                            }\n                        }\n                    },\n                libraryPadding = padding,\n                name = { name(library.name) },\n                version = {\n                    val artifactVersion = library.artifactVersion\n                    if (version != null && artifactVersion != null) {\n                        version(artifactVersion)\n                    }\n                },\n                author = {\n                    val authors = library.author\n                    if (author != null && authors.isNotBlank()) {\n                        author(authors)\n                    }\n                },\n                description = {\n                    val desc = library.description\n                    if (description != null && !desc.isNullOrBlank()) {\n                        description(desc)\n                    }\n                },\n                licenses = {\n                    if (license != null && library.licenses.isNotEmpty()) {\n                        library.licenses.forEach {\n                            license(it)\n                        }\n                    }\n                },\n                actions = {\n                    if (funding != null && library.funding.isNotEmpty()) {\n                        library.funding.forEach {\n                            funding(it)\n                        }\n                    }\n                    if (actions != null) {\n                        actions(library)\n                    }\n                }\n            )\n\n            if (divider != null && index < libraries.lastIndex) {\n                divider.invoke(this)\n            }\n        }\n        footer?.invoke(this)\n    }\n}\n\n@OptIn(ExperimentalLayoutApi::class)\n@Composable\nprivate fun LibraryScaffoldLayout(\n    name: @Composable BoxScope.() -> Unit,\n    version: @Composable BoxScope.() -> Unit,\n    author: @Composable BoxScope.() -> Unit,\n    description: @Composable BoxScope.() -> Unit,\n    licenses: @Composable FlowRowScope.() -> Unit,\n    actions: @Composable FlowRowScope.() -> Unit,\n    modifier: Modifier = Modifier,\n    libraryPadding: LibraryPadding = LibraryDefaults.libraryPadding(),\n) {\n    Column(\n        modifier = modifier.padding(libraryPadding.contentPadding)\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Box(\n                modifier = Modifier\n                    .padding(libraryPadding.namePadding)\n                    .weight(1f),\n                content = name\n            )\n            Box(content = version)\n        }\n        Spacer(Modifier.height(4.dp))\n        Box(content = description)\n        Spacer(Modifier.height(4.dp))\n        Row(\n            verticalAlignment = Alignment.Bottom\n        ) {\n            FlowRow(\n                modifier = Modifier\n                    .weight(1f)\n                    .padding(end = 8.dp)\n            ) {\n                licenses()\n                actions()\n            }\n\n            Box(\n                modifier = Modifier.weight(1.2f),\n                content = author\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/libraries-info/src/main/java/com/t8rin/imagetoolbox/feature/libraries_info/presentation/components/LibraryLink.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.libraries_info.presentation.components\n\nimport com.mikepenz.aboutlibraries.entity.Library\n\nfun Library.link(): String? =\n    (scm?.url ?: website ?: licenses.firstOrNull()?.url)?.replace(\"git://\", \"\")"
  },
  {
    "path": "feature/libraries-info/src/main/java/com/t8rin/imagetoolbox/feature/libraries_info/presentation/screenLogic/LibrariesInfoComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.libraries_info.presentation.screenLogic\n\nimport com.arkivanov.decompose.ComponentContext\nimport com.mikepenz.aboutlibraries.entity.Library\nimport com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.feature.libraries_info.presentation.components.link\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass LibrariesInfoComponent @AssistedInject constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted private val onNavigate: (Screen) -> Unit,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    fun selectLibrary(library: Library) {\n        onNavigate(\n            Screen.LibraryDetails(\n                name = library.name,\n                htmlDescription = library.licenses.joinToString(\"\\n\\n\") {\n                    it.htmlReadyLicenseContent\n                        .orEmpty()\n                        .trimIndent()\n                },\n                link = library.link()\n            )\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit\n        ): LibrariesInfoComponent\n    }\n\n}"
  },
  {
    "path": "feature/library-details/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/library-details/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.library_details\""
  },
  {
    "path": "feature/library-details/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/library-details/src/main/java/com/t8rin/imagetoolbox/library_details/presentation/LibraryDetailsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.library_details.presentation\n\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.selection.SelectionContainer\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.automirrored.rounded.OpenInNew\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.HtmlText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.library_details.presentation.screenLogic.LibraryDetailsComponent\n\n@Composable\nfun LibraryDetailsContent(\n    component: LibraryDetailsComponent\n) {\n    val childScrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n    val linkHandler = LocalUriHandler.current\n\n    Scaffold(\n        modifier = Modifier\n            .fillMaxSize()\n            .nestedScroll(childScrollBehavior.nestedScrollConnection),\n        topBar = {\n            EnhancedTopAppBar(\n                title = {\n                    Text(\n                        text = component.libraryName,\n                        modifier = Modifier.marquee()\n                    )\n                },\n                navigationIcon = {\n                    EnhancedIconButton(\n                        onClick = component.onGoBack\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                            contentDescription = null\n                        )\n                    }\n                },\n                actions = {\n                    if (component.libraryLink.isNullOrBlank()) {\n                        TopAppBarEmoji()\n                    } else {\n                        EnhancedIconButton(\n                            onClick = { linkHandler.openUri(component.libraryLink) }\n                        ) {\n                            Icon(\n                                imageVector = Icons.AutoMirrored.Rounded.OpenInNew,\n                                contentDescription = component.libraryLink\n                            )\n                        }\n                    }\n                },\n                type = EnhancedTopAppBarType.Large,\n                scrollBehavior = childScrollBehavior\n            )\n        }\n    ) { contentPadding ->\n        SelectionContainer {\n            HtmlText(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(contentPadding)\n                    .padding(12.dp)\n                    .container(\n                        resultPadding = 12.dp\n                    ),\n                html = component.libraryDescription\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/library-details/src/main/java/com/t8rin/imagetoolbox/library_details/presentation/screenLogic/LibraryDetailsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.library_details.presentation.screenLogic\n\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass LibraryDetailsComponent @AssistedInject constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted(\"libraryName\") val libraryName: String,\n    @Assisted(\"libraryDescription\") val libraryDescription: String,\n    @Assisted(\"libraryLink\") val libraryLink: String?,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            @Assisted componentContext: ComponentContext,\n            @Assisted onGoBack: () -> Unit,\n            @Assisted(\"libraryName\") libraryName: String,\n            @Assisted(\"libraryDescription\") libraryDescription: String,\n            @Assisted(\"libraryLink\") libraryLink: String?,\n        ): LibraryDetailsComponent\n    }\n\n}"
  },
  {
    "path": "feature/limits-resize/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/limits-resize/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.limits_resize\""
  },
  {
    "path": "feature/limits-resize/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/data/AndroidLimitsImageScaler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.utils.aspectRatio\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.feature.limits_resize.domain.LimitsImageScaler\nimport com.t8rin.imagetoolbox.feature.limits_resize.domain.LimitsResizeType\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidLimitsImageScaler @Inject constructor(\n    private val imageScaler: ImageScaler<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder,\n    LimitsImageScaler<Bitmap>,\n    ImageScaler<Bitmap> by imageScaler {\n\n    override suspend fun scaleImage(\n        image: Bitmap,\n        width: Int,\n        height: Int,\n        resizeType: LimitsResizeType,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap? = withContext(defaultDispatcher) {\n        val widthInternal = width.takeIf { it > 0 } ?: Int.MAX_VALUE\n        val heightInternal = height.takeIf { it > 0 } ?: Int.MAX_VALUE\n\n        resizeType.resizeWithLimits(\n            image = image,\n            width = widthInternal,\n            height = heightInternal,\n            imageScaleMode = imageScaleMode\n        )\n    }\n\n    private suspend fun LimitsResizeType.resizeWithLimits(\n        image: Bitmap,\n        width: Int,\n        height: Int,\n        imageScaleMode: ImageScaleMode\n    ): Bitmap? {\n        val limitWidth: Int\n        val limitHeight: Int\n\n        if (autoRotateLimitBox && image.aspectRatio < 1f) {\n            limitWidth = height\n            limitHeight = width\n        } else {\n            limitWidth = width\n            limitHeight = height\n        }\n\n        val limitAspectRatio = limitWidth / limitHeight.toFloat()\n\n        if (image.height > limitHeight || image.width > limitWidth) {\n            return when {\n                image.aspectRatio > limitAspectRatio -> {\n                    scaleImage(\n                        image = image,\n                        width = limitWidth,\n                        height = (limitWidth / image.aspectRatio).toInt(),\n                        imageScaleMode = imageScaleMode\n                    )\n                }\n\n                image.aspectRatio < limitAspectRatio -> {\n                    scaleImage(\n                        image = image,\n                        width = (limitHeight * image.aspectRatio).toInt(),\n                        height = limitHeight,\n                        imageScaleMode = imageScaleMode\n                    )\n                }\n\n                else -> {\n                    scaleImage(\n                        image = image,\n                        width = limitWidth,\n                        height = limitHeight,\n                        imageScaleMode = imageScaleMode\n                    )\n                }\n            }\n        } else {\n            return when (this) {\n                is LimitsResizeType.Recode -> image\n\n                is LimitsResizeType.Zoom -> {\n                    when {\n                        limitHeight == Int.MAX_VALUE -> {\n                            val newHeight = (limitWidth / image.aspectRatio).toInt()\n                            scaleImage(\n                                image = image,\n                                width = limitWidth,\n                                height = newHeight,\n                                imageScaleMode = imageScaleMode\n                            )\n                        }\n\n                        limitWidth == Int.MAX_VALUE -> {\n                            val newWidth = (limitHeight * image.aspectRatio).toInt()\n                            scaleImage(\n                                image = image,\n                                width = newWidth,\n                                height = limitHeight,\n                                imageScaleMode = imageScaleMode\n                            )\n                        }\n\n                        else -> {\n                            val widthRatio = limitWidth.toDouble() / image.width\n                            val heightRatio = limitHeight.toDouble() / image.height\n                            val ratio = minOf(widthRatio, heightRatio)\n\n                            val newWidth = (image.width * ratio).toInt()\n                            val newHeight = (image.height * ratio).toInt()\n\n                            scaleImage(\n                                image = image,\n                                width = newWidth,\n                                height = newHeight,\n                                imageScaleMode = imageScaleMode\n                            )\n                        }\n                    }\n                }\n\n                is LimitsResizeType.Skip -> null\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/di/LimitsResizeModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.limits_resize.data.AndroidLimitsImageScaler\nimport com.t8rin.imagetoolbox.feature.limits_resize.domain.LimitsImageScaler\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface LimitsResizeModule {\n\n    @Binds\n    @Singleton\n    fun provideScaler(\n        scaler: AndroidLimitsImageScaler\n    ): LimitsImageScaler<Bitmap>\n\n}"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/domain/LimitsImageScaler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\n\ninterface LimitsImageScaler<I> : ImageScaler<I> {\n\n    suspend fun scaleImage(\n        image: I,\n        width: Int,\n        height: Int,\n        resizeType: LimitsResizeType,\n        imageScaleMode: ImageScaleMode\n    ): I?\n\n}"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/domain/LimitsResizeType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.domain\n\n\nsealed class LimitsResizeType(\n    val autoRotateLimitBox: Boolean\n) {\n\n    fun copy(autoRotateLimitBox: Boolean) = when (this) {\n        is Recode -> Recode(autoRotateLimitBox)\n        is Skip -> Skip(autoRotateLimitBox)\n        is Zoom -> Zoom(autoRotateLimitBox)\n    }\n\n    class Skip(\n        autoRotateLimitBox: Boolean = false\n    ) : LimitsResizeType(autoRotateLimitBox)\n\n    class Recode(\n        autoRotateLimitBox: Boolean = false\n    ) : LimitsResizeType(autoRotateLimitBox)\n\n    class Zoom(\n        autoRotateLimitBox: Boolean = false\n    ) : LimitsResizeType(autoRotateLimitBox)\n}"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/presentation/LimitsResizeContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ScaleModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.limits_resize.presentation.components.AutoRotateLimitBoxToggle\nimport com.t8rin.imagetoolbox.feature.limits_resize.presentation.components.LimitsResizeSelector\nimport com.t8rin.imagetoolbox.feature.limits_resize.presentation.screenLogic.LimitsResizeComponent\n\n@Composable\nfun LimitsResizeContent(\n    component: LimitsResizeComponent\n) {\n    AutoContentBasedColors(component.bitmap)\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setUris(uris)\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.limits_resize),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = rememberFileSize(component.selectedUri)\n            )\n        },\n        onGoBack = onBack,\n        actions = {\n            if (component.previewBitmap != null) {\n                var editSheetData by remember {\n                    mutableStateOf(listOf<Uri>())\n                }\n                ShareButton(\n                    enabled = component.canSave,\n                    onShare = component::shareBitmaps,\n                    onCopy = {\n                        component.cacheCurrentImage(Clipboard::copy)\n                    },\n                    onEdit = {\n                        component.cacheImages {\n                            editSheetData = it\n                        }\n                    }\n                )\n                ProcessImagesPreferenceSheet(\n                    uris = editSheetData,\n                    visible = editSheetData.isNotEmpty(),\n                    onDismiss = {\n                        editSheetData = emptyList()\n                    },\n                    onNavigate = component.onNavigate\n                )\n            }\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.bitmap != null,\n            )\n        },\n        imagePreview = {\n            ImageContainer(\n                modifier = Modifier\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                imageInside = isPortrait,\n                showOriginal = false,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.bitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = true\n            )\n        },\n        controls = {\n            ImageCounter(\n                imageCount = component.uris?.size?.takeIf { it > 1 },\n                onRepick = {\n                    showPickImageFromUrisSheet = true\n                }\n            )\n            ResizeImageField(\n                imageInfo = component.imageInfo,\n                originalSize = component.originalSize,\n                onWidthChange = component::updateWidth,\n                onHeightChange = component::updateHeight\n            )\n            Spacer(Modifier.size(8.dp))\n            SaveExifWidget(\n                imageFormat = component.imageInfo.imageFormat,\n                checked = component.keepExif,\n                onCheckedChange = component::setKeepExif\n            )\n            if (component.imageInfo.imageFormat.canChangeCompressionValue) Spacer(\n                Modifier.size(8.dp)\n            )\n            QualitySelector(\n                imageFormat = component.imageInfo.imageFormat,\n                quality = component.imageInfo.quality,\n                onQualityChange = component::setQuality\n            )\n            Spacer(Modifier.size(8.dp))\n            ImageFormatSelector(\n                value = component.imageInfo.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = component.imageInfo.quality\n            )\n            Spacer(Modifier.size(8.dp))\n            AutoRotateLimitBoxToggle(\n                value = component.resizeType.autoRotateLimitBox,\n                onClick = component::toggleAutoRotateLimitBox\n            )\n            Spacer(Modifier.size(8.dp))\n            LimitsResizeSelector(\n                enabled = component.bitmap != null,\n                value = component.resizeType,\n                onValueChange = component::setResizeType\n            )\n            Spacer(Modifier.height(8.dp))\n            ScaleModeSelector(\n                value = component.imageInfo.imageScaleMode,\n                onValueChange = component::setImageScaleMode\n            )\n        },\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                isPrimaryButtonVisible = component.canSave,\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.bitmap == null) {\n                TopAppBarEmoji()\n            }\n        },\n        canShowScreenData = component.bitmap != null\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris?.size ?: 1,\n        onCancelLoading = component::cancelSaving\n    )\n\n    PickImageFromUrisSheet(\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = component::updateSelectedUri,\n        onUriRemoved = component::updateUrisSilently,\n        columns = if (isPortrait) 2 else 4,\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/presentation/components/AutoRotateLimitBoxToggle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.MotionPhotosAuto\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AutoRotateLimitBoxToggle(\n    value: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n) {\n    PreferenceRowSwitch(\n        modifier = modifier,\n        title = stringResource(R.string.auto_rotate_limits),\n        subtitle = stringResource(R.string.auto_rotate_limits_sub),\n        checked = value,\n        shape = ShapeDefaults.extraLarge,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Rounded.MotionPhotosAuto\n    )\n}"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/presentation/components/LimitResizeGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.limits_resize.domain.LimitsResizeType\n\n@Composable\nfun LimitsResizeSelector(\n    enabled: Boolean,\n    value: LimitsResizeType,\n    onValueChange: (LimitsResizeType) -> Unit\n) {\n    EnhancedButtonGroup(\n        modifier = Modifier\n            .container(shape = ShapeDefaults.extraLarge)\n            .padding(start = 3.dp, end = 2.dp),\n        enabled = enabled,\n        title = {\n            Spacer(modifier = Modifier.height(8.dp))\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                Text(\n                    text = stringResource(R.string.fallback_option),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n        },\n        items = listOf(\n            stringResource(R.string.skip),\n            stringResource(R.string.recode),\n            stringResource(R.string.zoom)\n        ),\n        selectedIndex = when (value) {\n            is LimitsResizeType.Skip -> 0\n            is LimitsResizeType.Recode -> 1\n            is LimitsResizeType.Zoom -> 2\n        },\n        onIndexChange = {\n            onValueChange(\n                when (it) {\n                    0 -> LimitsResizeType.Skip(value.autoRotateLimitBox)\n                    1 -> LimitsResizeType.Recode(value.autoRotateLimitBox)\n                    else -> LimitsResizeType.Zoom(value.autoRotateLimitBox)\n                }\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/limits-resize/src/main/java/com/t8rin/imagetoolbox/feature/limits_resize/presentation/screenLogic/LimitsResizeComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.limits_resize.presentation.screenLogic\n\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.limits_resize.domain.LimitsImageScaler\nimport com.t8rin.imagetoolbox.feature.limits_resize.domain.LimitsResizeType\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass LimitsResizeComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: LimitsImageScaler<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n        }\n    }\n\n    private val _originalSize: MutableState<IntegerSize?> = mutableStateOf(null)\n    val originalSize by _originalSize\n\n    private val _canSave: MutableState<Boolean> = mutableStateOf(false)\n    val canSave by _canSave\n\n    private val _uris: MutableState<List<Uri>?> = mutableStateOf(null)\n    val uris by _uris\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _keepExif: MutableState<Boolean> = mutableStateOf(false)\n    val keepExif by _keepExif\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _selectedUri: MutableState<Uri?> = mutableStateOf(null)\n    val selectedUri by _selectedUri\n\n    private val _imageInfo: MutableState<ImageInfo> = mutableStateOf(ImageInfo())\n    val imageInfo by _imageInfo\n\n    private val _resizeType: MutableState<LimitsResizeType> =\n        mutableStateOf(LimitsResizeType.Recode())\n    val resizeType by _resizeType\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageInfo.value = _imageInfo.value.copy(imageFormat = imageFormat)\n    }\n\n    fun setUris(\n        uris: List<Uri>?\n    ) {\n        _uris.value = null\n        _uris.value = uris\n        _selectedUri.value = uris?.firstOrNull()\n        if (uris != null) {\n            componentScope.launch {\n                imageGetter.getImageAsync(\n                    uri = uris[0].toString(),\n                    originalSize = true,\n                    onGetImage = {\n                        updateBitmap(it.image)\n                        setImageFormat(it.imageInfo.imageFormat)\n                    },\n                    onFailure = AppToastHost::showFailureToast\n                )\n            }\n        }\n    }\n\n    fun updateUrisSilently(removedUri: Uri) {\n        componentScope.launch {\n            _uris.value = uris\n            if (_selectedUri.value == removedUri) {\n                val index = uris?.indexOf(removedUri) ?: -1\n                if (index == 0) {\n                    uris?.getOrNull(1)?.let {\n                        _selectedUri.value = it\n                        _bitmap.value = imageGetter.getImage(it.toString())?.image\n                    }\n                } else {\n                    uris?.getOrNull(index - 1)?.let {\n                        _selectedUri.value = it\n                        _bitmap.value = imageGetter.getImage(it.toString())?.image\n                    }\n                }\n            }\n            val u = _uris.value?.toMutableList()?.apply {\n                remove(removedUri)\n            }\n            _uris.value = u\n        }\n    }\n\n    private fun updateBitmap(\n        bitmap: Bitmap?,\n        preview: Bitmap? = null\n    ) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            val size = bitmap?.let { it.width to it.height }\n            _originalSize.value = size?.run { IntegerSize(width = first, height = second) }\n            _bitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n            _previewBitmap.value = preview ?: _bitmap.value\n            _isImageLoading.value = false\n        }\n    }\n\n    fun setKeepExif(boolean: Boolean) {\n        _keepExif.value = boolean\n        registerChanges()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    imageGetter.getImage(uri.toString())?.image\n                }.getOrNull()?.let { bitmap ->\n                    imageScaler.scaleImage(\n                        image = bitmap,\n                        width = imageInfo.width,\n                        height = imageInfo.height,\n                        resizeType = resizeType,\n                        imageScaleMode = imageInfo.imageScaleMode\n                    )\n                }?.let { localBitmap ->\n                    results.add(\n                        fileController.save(\n                            ImageSaveTarget(\n                                imageInfo = imageInfo.copy(\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                ),\n                                originalUri = uri.toString(),\n                                sequenceNumber = _done.value + 1,\n                                data = imageCompressor.compressAndTransform(\n                                    image = localBitmap,\n                                    imageInfo = imageInfo.copy(\n                                        width = localBitmap.width,\n                                        height = localBitmap.height\n                                    )\n                                )\n                            ),\n                            keepOriginalMetadata = keepExif,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    )\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun updateSelectedUri(\n        uri: Uri\n    ) {\n        runCatching {\n            componentScope.launch {\n                _isImageLoading.value = true\n                updateBitmap(imageGetter.getImage(uri.toString())?.image)\n                _selectedUri.value = uri\n                _isImageLoading.value = false\n            }\n        }.onFailure(AppToastHost::showFailureToast)\n    }\n\n\n    private fun updateCanSave() {\n        _canSave.update {\n            _bitmap.value != null && (_imageInfo.value.height != 0 || _imageInfo.value.width != 0)\n        }\n\n        registerChanges()\n    }\n\n    fun updateWidth(i: Int) {\n        _imageInfo.value = _imageInfo.value.copy(width = i)\n        updateCanSave()\n    }\n\n    fun updateHeight(i: Int) {\n        _imageInfo.value = _imageInfo.value.copy(height = i)\n        updateCanSave()\n    }\n\n    fun shareBitmaps() {\n        _isSaving.value = false\n        savingJob = trackProgress {\n            _isSaving.value = true\n            shareProvider.shareImages(\n                uris = uris?.map { it.toString() } ?: emptyList(),\n                imageLoader = { uri ->\n                    imageGetter.getImage(uri)?.image?.let { bitmap: Bitmap ->\n                        imageScaler.scaleImage(\n                            image = bitmap,\n                            width = imageInfo.width,\n                            height = imageInfo.height,\n                            resizeType = resizeType,\n                            imageScaleMode = imageInfo.imageScaleMode\n                        )\n                    }?.let {\n                        it to imageInfo.copy(\n                            width = it.width,\n                            height = it.height\n                        )\n                    }\n                },\n                onProgressChange = {\n                    if (it == -1) {\n                        AppToastHost.showConfetti()\n                        _done.value = 0\n                        _isSaving.value = false\n                    } else {\n                        _done.value = it\n                    }\n                    updateProgress(\n                        done = done,\n                        total = uris.orEmpty().size\n                    )\n                }\n            )\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        _imageInfo.value = _imageInfo.value.copy(quality = quality)\n        registerChanges()\n    }\n\n    fun setResizeType(resizeType: LimitsResizeType) {\n        _resizeType.value = resizeType\n        registerChanges()\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun toggleAutoRotateLimitBox() {\n        _resizeType.update { it.copy(!it.autoRotateLimitBox) }\n        registerChanges()\n    }\n\n    fun setImageScaleMode(imageScaleMode: ImageScaleMode) {\n        _imageInfo.update {\n            it.copy(\n                imageScaleMode = imageScaleMode\n            )\n        }\n        registerChanges()\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            imageGetter.getImage(\n                uri = selectedUri.toString()\n            )?.image?.let { bitmap ->\n                imageScaler.scaleImage(\n                    image = bitmap,\n                    width = imageInfo.width,\n                    height = imageInfo.height,\n                    resizeType = resizeType,\n                    imageScaleMode = imageInfo.imageScaleMode\n                )\n            }?.let {\n                it to imageInfo.copy(\n                    width = it.width,\n                    height = it.height\n                )\n            }?.let { (image, imageInfo) ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo.copy(originalUri = selectedUri.toString())\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            val list = mutableListOf<Uri>()\n            uris?.forEach { uri ->\n                imageGetter.getImage(\n                    uri = uri.toString()\n                )?.image?.let { bitmap ->\n                    imageScaler.scaleImage(\n                        image = bitmap,\n                        width = imageInfo.width,\n                        height = imageInfo.height,\n                        resizeType = resizeType,\n                        imageScaleMode = imageInfo.imageScaleMode\n                    )\n                }?.let {\n                    it to imageInfo.copy(\n                        width = it.width,\n                        height = it.height\n                    )\n                }?.let { (image, imageInfo) ->\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = imageInfo.copy(originalUri = uri.toString())\n                    )?.let { uri ->\n                        list.add(uri.toUri())\n                    }\n                }\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? =\n        if (uris?.size == 1) imageInfo.imageFormat\n        else null\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): LimitsResizeComponent\n    }\n}"
  },
  {
    "path": "feature/load-net-image/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/load-net-image/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.load_net_image\"\n\ndependencies {\n    implementation(libs.jsoup)\n}"
  },
  {
    "path": "feature/load-net-image/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/data/AndroidHtmlImageParser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.USER_AGENT\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.feature.load_net_image.domain.HtmlImageParser\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport org.jsoup.Jsoup\nimport java.net.UnknownHostException\nimport javax.inject.Inject\n\ninternal class AndroidHtmlImageParser @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : HtmlImageParser, DispatchersHolder by dispatchersHolder {\n\n    override suspend fun parseImagesSrc(\n        url: String,\n        onFailure: (message: String) -> Unit\n    ): List<String> = withContext(defaultDispatcher) {\n        val trimmedUrl = url.trim()\n        val realUrl = if (trimmedUrl.isMalformed()) {\n            \"https://$trimmedUrl\"\n        } else trimmedUrl\n\n        val baseImage = loadImage(realUrl)\n\n        val parsedImages = if (realUrl.isNotEmpty()) {\n            runSuspendCatching {\n                val parsed = Jsoup\n                    .connect(realUrl)\n                    .userAgent(USER_AGENT)\n                    .execute()\n                    .parse()\n\n                val list = parsed.getElementsByTag(\"img\")\n                    .mapNotNull { element ->\n                        element.absUrl(\"src\").takeIf { it.isNotEmpty() }?.substringBefore(\"?\")\n                    }\n\n                val content = parsed.getElementsByTag(\"meta\")\n                    .mapNotNull { element ->\n                        when (element.attr(\"property\")) {\n                            \"og:image\" -> element.attr(\"content\")\n                            else -> null\n                        }\n                    }\n\n                val favIcon = loadImage(\n                    parsed.head()\n                        .select(\"link[href~=.*\\\\.ico]\")\n                        .firstOrNull()\n                        ?.attr(\"href\") ?: \"\"\n                ).ifEmpty {\n                    loadImage(realUrl.removeSuffix(\"/\") + \"/favicon.ico\")\n                }\n\n                content + list + favIcon\n            }.onFailure {\n                if (it is UnknownHostException) onFailure(context.getString(R.string.unknown_host))\n            }.getOrNull() ?: emptyList()\n        } else {\n            emptyList()\n        }\n\n        baseImage + parsedImages\n    }\n\n    private suspend fun loadImage(\n        url: String\n    ): List<String> = imageGetter.getImage(data = url)?.let {\n        shareProvider.cacheImage(\n            image = it,\n            imageInfo = ImageInfo(\n                width = it.width,\n                height = it.height,\n                imageFormat = ImageFormat.Png.Lossless\n            )\n        )\n    }.let(::listOfNotNull)\n\n    private fun String.isMalformed(): Boolean = !(startsWith(\"https://\") || startsWith(\"http://\"))\n\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/di/LoadNetImageModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.di\n\nimport com.t8rin.imagetoolbox.feature.load_net_image.data.AndroidHtmlImageParser\nimport com.t8rin.imagetoolbox.feature.load_net_image.domain.HtmlImageParser\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface LoadNetImageModule {\n\n    @Binds\n    @Singleton\n    fun parser(\n        impl: AndroidHtmlImageParser\n    ): HtmlImageParser\n\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/domain/HtmlImageParser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.domain\n\ninterface HtmlImageParser {\n\n    suspend fun parseImagesSrc(\n        url: String,\n        onFailure: (message: String) -> Unit\n    ): List<String>\n\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/LoadNetImageContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.takeUnless\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.components.LoadNetImageActionButtons\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.components.LoadNetImageAdaptiveActions\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.components.LoadNetImageTopAppBarActions\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.components.LoadNetImageUrlTextField\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.components.ParsedImagePreview\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.components.ParsedImagesSelection\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\n\n@Composable\nfun LoadNetImageContent(\n    component: LoadNetImageComponent\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    AutoContentBasedColors(component.bitmap)\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.load_image_from_net),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = component.onGoBack,\n        actions = {\n            LoadNetImageAdaptiveActions(component)\n        },\n        topAppBarPersistentActions = {\n            LoadNetImageTopAppBarActions(component)\n        },\n        imagePreview = {\n            AnimatedContent(component.targetUrl.isEmpty()) { isEmpty ->\n                if (isEmpty) {\n                    ImageNotPickedWidget(\n                        onPickImage = {\n                            Clipboard.getText(component::updateTargetUrl)\n                        },\n                        modifier = Modifier.padding(20.dp),\n                        text = stringResource(R.string.type_image_link),\n                        containerColor = MaterialTheme\n                            .colorScheme\n                            .surfaceContainerLowest\n                            .takeUnless(isPortrait)\n                    )\n                } else {\n                    ParsedImagePreview(component)\n                }\n            }\n        },\n        controls = {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(8.dp)\n            ) {\n                LoadNetImageUrlTextField(component)\n                ParsedImagesSelection(component)\n            }\n        },\n        buttons = { actions ->\n            LoadNetImageActionButtons(\n                component = component,\n                actions = actions\n            )\n        },\n        showImagePreviewAsStickyHeader = component.targetUrl.isNotEmpty(),\n        canShowScreenData = true\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/components/LoadNetImageActionButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ContentPaste\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageEdit\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\n\n@Composable\ninternal fun LoadNetImageActionButtons(\n    component: LoadNetImageComponent,\n    actions: @Composable RowScope.() -> Unit\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var showFolderSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var editSheetData by remember {\n        mutableStateOf(listOf<Uri>())\n    }\n    val noData = component.parsedImages.isEmpty()\n    BottomButtonsBlock(\n        isNoData = noData,\n        isPrimaryButtonVisible = !noData,\n        isSecondaryButtonVisible = !noData,\n        secondaryButtonIcon = if (noData) Icons.Rounded.ContentPaste else Icons.Outlined.ImageEdit,\n        secondaryButtonText = if (noData) stringResource(R.string.paste_link) else stringResource(R.string.edit),\n        showNullDataButtonAsContainer = true,\n        isScreenHaveNoDataContent = true,\n        onSecondaryButtonClick = {\n            if (noData) {\n                Clipboard.getText(component::updateTargetUrl)\n            } else {\n                component.cacheImages {\n                    editSheetData = it\n                }\n            }\n        },\n        onPrimaryButtonClick = {\n            saveBitmap(null)\n        },\n        onPrimaryButtonLongClick = {\n            showFolderSelectionDialog = true\n        },\n        actions = {\n            if (isPortrait) actions()\n        }\n    )\n    OneTimeSaveLocationSelectionDialog(\n        visible = showFolderSelectionDialog,\n        onDismiss = { showFolderSelectionDialog = false },\n        onSaveRequest = saveBitmap,\n        formatForFilenameSelection = component.getFormatForFilenameSelection()\n    )\n\n    ProcessImagesPreferenceSheet(\n        uris = editSheetData,\n        visible = editSheetData.isNotEmpty(),\n        onDismiss = {\n            editSheetData = emptyList()\n        },\n        onNavigate = component.onNavigate\n    )\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/components/LoadNetImageAdaptiveActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\n\n@Composable\ninternal fun RowScope.LoadNetImageAdaptiveActions(\n    component: LoadNetImageComponent\n) {\n    AnimatedVisibility(component.parsedImages.isNotEmpty()) {\n        ShareButton(\n            onShare = component::performSharing,\n            onCopy = {\n                component.cacheCurrentImage(Clipboard::copy)\n            }\n        )\n    }\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n    ZoomButton(\n        onClick = { showZoomSheet = true },\n        visible = component.bitmap != null,\n    )\n    ZoomModalSheet(\n        data = component.bitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/components/LoadNetImageTopAppBarActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\n\n@Composable\ninternal fun RowScope.LoadNetImageTopAppBarActions(\n    component: LoadNetImageComponent\n) {\n    if (component.bitmap == null) {\n        TopAppBarEmoji()\n    } else {\n        AnimatedVisibility(component.parsedImages.size > 1) {\n            Row(\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                val pagesSize by remember(component.imageFrames, component.parsedImages) {\n                    derivedStateOf {\n                        component.imageFrames.getFramePositions(component.parsedImages.size).size\n                    }\n                }\n                AnimatedVisibility(\n                    visible = pagesSize != component.parsedImages.size,\n                    enter = fadeIn() + scaleIn() + expandHorizontally(),\n                    exit = fadeOut() + scaleOut() + shrinkHorizontally()\n                ) {\n                    EnhancedIconButton(\n                        onClick = component::selectAllImages\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.SelectAll,\n                            contentDescription = \"Select All\"\n                        )\n                    }\n                }\n                AnimatedVisibility(\n                    modifier = Modifier\n                        .padding(8.dp)\n                        .container(\n                            shape = ShapeDefaults.circle,\n                            color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                            resultPadding = 0.dp\n                        ),\n                    visible = pagesSize != 0\n                ) {\n                    Row(\n                        modifier = Modifier.padding(start = 12.dp),\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.Center\n                    ) {\n                        pagesSize.takeIf { it != 0 }?.let {\n                            Spacer(Modifier.width(8.dp))\n                            Text(\n                                text = it.toString(),\n                                fontSize = 20.sp,\n                                fontWeight = FontWeight.Medium\n                            )\n                        }\n                        EnhancedIconButton(\n                            onClick = component::clearImagesSelection\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Close,\n                                contentDescription = stringResource(R.string.close)\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/components/LoadNetImageUrlTextField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Cancel\nimport androidx.compose.material.icons.rounded.WifiTetheringError\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\n\n@Composable\ninternal fun LoadNetImageUrlTextField(\n    component: LoadNetImageComponent\n) {\n    RoundedTextField(\n        modifier = Modifier\n            .container(\n                shape = MaterialTheme.shapes.large,\n                resultPadding = 8.dp\n            ),\n        value = component.targetUrl,\n        onValueChange = {\n            component.updateTargetUrl(\n                newUrl = it,\n                onFailure = {\n                    AppToastHost.showToast(\n                        message = it,\n                        icon = Icons.Rounded.WifiTetheringError\n                    )\n                }\n            )\n        },\n        singleLine = false,\n        label = {\n            Text(stringResource(id = R.string.image_link))\n        },\n        endIcon = {\n            AnimatedVisibility(component.targetUrl.isNotBlank()) {\n                EnhancedIconButton(\n                    onClick = {\n                        component.updateTargetUrl(\"\")\n                    },\n                    modifier = Modifier.padding(end = 4.dp)\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Cancel,\n                        contentDescription = stringResource(R.string.cancel)\n                    )\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/components/ParsedImagePreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation.components\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.data.utils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\n\n@Composable\ninternal fun ParsedImagePreview(\n    component: LoadNetImageComponent\n) {\n    Picture(\n        allowHardware = false,\n        model = component.targetUrl,\n        modifier = Modifier\n            .container(\n                resultPadding = 8.dp\n            )\n            .then(\n                if (component.bitmap == null) {\n                    Modifier\n                        .fillMaxWidth()\n                        .height(140.dp)\n                } else {\n                    Modifier.aspectRatio(component.bitmap?.safeAspectRatio ?: 2f)\n                }\n            ),\n        isLoadingFromDifferentPlace = component.isImageLoading,\n        contentScale = ContentScale.FillBounds,\n        shape = MaterialTheme.shapes.small,\n        error = {\n            if (component.bitmap != null) {\n                Picture(\n                    modifier = Modifier.fillMaxSize(),\n                    model = component.bitmap,\n                    contentDescription = contentDescription,\n                    contentScale = ContentScale.FillBounds\n                )\n            } else {\n                Column(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .background(MaterialTheme.colorScheme.surfaceContainer),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.BrokenImageAlt,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .padding(vertical = 8.dp, horizontal = 16.dp)\n                            .size(64.dp)\n                    )\n                    Text(stringResource(id = R.string.no_image))\n                    Spacer(Modifier.height(8.dp))\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/components/ParsedImagesSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagesPreviewWithSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.negativePadding\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\n\n@Composable\ninternal fun ParsedImagesSelection(\n    component: LoadNetImageComponent\n) {\n    AnimatedVisibility(component.parsedImages.size > 1) {\n        ImagesPreviewWithSelection(\n            imageUris = component.parsedImages,\n            imageFrames = component.imageFrames,\n            onFrameSelectionChange = component::updateImageFrames,\n            isPortrait = true,\n            isLoadingImages = component.isImageLoading,\n            contentScale = ContentScale.Fit,\n            contentPadding = PaddingValues(20.dp),\n            modifier = Modifier\n                .fillMaxWidth()\n                .height(\n                    (130.dp * component.parsedImages.size).coerceAtMost(420.dp)\n                )\n                .negativePadding(horizontal = 20.dp),\n            showExtension = false\n        )\n    }\n}"
  },
  {
    "path": "feature/load-net-image/src/main/java/com/t8rin/imagetoolbox/feature/load_net_image/presentation/screenLogic/LoadNetImageComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic\n\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.load_net_image.domain.HtmlImageParser\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass LoadNetImageComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted initialUrl: String,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val htmlImageParser: HtmlImageParser,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            updateTargetUrl(initialUrl)\n        }\n    }\n\n    private val _targetUrl: MutableState<String> = mutableStateOf(\"\")\n    val targetUrl: String by _targetUrl\n\n    private val _bitmap = mutableStateOf<Bitmap?>(null)\n    val bitmap by _bitmap\n\n    private val _parsedImages: MutableState<List<String>> = mutableStateOf(emptyList())\n    val parsedImages: List<String> by _parsedImages\n\n    private val _imageFrames: MutableState<ImageFrames> = mutableStateOf(ImageFrames.All)\n    val imageFrames by _imageFrames\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    fun updateTargetUrl(\n        newUrl: String,\n        onFailure: (String) -> Unit = {}\n    ) {\n        _targetUrl.update(\n            onValueChanged = {\n                debouncedImageCalculation {\n                    val newImages = htmlImageParser.parseImagesSrc(\n                        url = newUrl,\n                        onFailure = onFailure\n                    )\n\n                    newImages.firstOrNull().let { src ->\n                        _bitmap.update { src?.let { imageGetter.getImage(data = src) } }\n                    }\n                    _parsedImages.update { newImages }\n                }\n            },\n            transform = { newUrl }\n        )\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n\n            val results = mutableListOf<SaveResult>()\n            val positions = imageFrames.getFramePositions(parsedImages.size)\n\n            _done.value = 0\n            _left.value = positions.size\n\n            parsedImages.forEachIndexed { index, url ->\n                if ((index + 1) in positions) {\n                    imageGetter.getImage(data = url)?.let { bitmap ->\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = ImageInfo(\n                                    width = bitmap.width,\n                                    height = bitmap.height,\n                                    imageFormat = ImageFormat.Png.Lossless\n                                ),\n                                originalUri = \"_\",\n                                sequenceNumber = null,\n                                data = imageCompressor.compress(\n                                    image = bitmap,\n                                    imageFormat = ImageFormat.Png.Lossless,\n                                    quality = Quality.Base(100)\n                                )\n                            ),\n                            keepOriginalMetadata = false,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    }?.let(results::add) ?: results.add(\n                        SaveResult.Error.Exception(Throwable())\n                    )\n                    _done.value++\n                }\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.update { false }\n        }\n    }\n\n    fun performSharing() {\n        cacheImages { uris ->\n            componentScope.launch {\n                shareProvider.shareUris(uris.map { it.toString() })\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n\n            val positions =\n                imageFrames.getFramePositions(parsedImages.size).map { it - 1 }\n\n            _done.value = 0\n            _left.value = positions.size\n\n            val uris = parsedImages.filterIndexed { index, _ ->\n                index in positions\n            }\n            onComplete(\n                uris.mapNotNull {\n                    val image = imageGetter.getImage(data = it) ?: return@mapNotNull null\n\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = ImageInfo(\n                            width = image.width,\n                            height = image.height,\n                            imageFormat = ImageFormat.Png.Lossless\n                        )\n                    )?.toUri()\n                }\n            )\n            _isSaving.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        _done.value = 0\n        _left.value = 1\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            imageFrames.getFramePositions(parsedImages.size).firstOrNull()?.let {\n                imageGetter.getImage(data = parsedImages[it - 1])\n            }?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        width = image.width,\n                        height = image.height,\n                        imageFormat = ImageFormat.Png.Lossless\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = ImageFormat.Png.Lossless\n\n    fun updateImageFrames(imageFrames: ImageFrames) {\n        _imageFrames.update { imageFrames }\n        registerChanges()\n    }\n\n    fun clearImagesSelection() = updateImageFrames(ImageFrames.ManualSelection(emptyList()))\n\n    fun selectAllImages() = updateImageFrames(ImageFrames.All)\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUrl: String,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): LoadNetImageComponent\n    }\n}"
  },
  {
    "path": "feature/main/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/main/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.main\"\n\ndependencies {\n    implementation(projects.feature.settings)\n}"
  },
  {
    "path": "feature/main/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/MainContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.automirrored.rounded.MenuOpen\nimport androidx.compose.material.icons.rounded.FileDownloadOff\nimport androidx.compose.material3.DrawerDefaults\nimport androidx.compose.material3.DrawerValue\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ModalNavigationDrawer\nimport androidx.compose.material3.rememberDrawerState\nimport androidx.compose.material3.windowsizeclass.WindowWidthSizeClass\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.movableContentOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.vector.rememberVectorPainter\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.arkivanov.decompose.extensions.compose.subscribeAsState\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalWindowSizeClass\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.main.presentation.components.MainContentImpl\nimport com.t8rin.imagetoolbox.feature.main.presentation.components.MainDrawerContent\nimport com.t8rin.imagetoolbox.feature.main.presentation.screenLogic.MainComponent\nimport com.t8rin.imagetoolbox.feature.settings.presentation.SettingsContent\nimport com.t8rin.snowfall.snowfall\nimport com.t8rin.snowfall.types.FlakeType\nimport kotlinx.coroutines.delay\n\n@Composable\nfun MainContent(\n    component: MainComponent\n) {\n    val isUpdateAvailable by component.isUpdateAvailable.subscribeAsState()\n\n    val settingsState = LocalSettingsState.current\n    val isGrid = LocalWindowSizeClass.current.widthSizeClass != WindowWidthSizeClass.Compact\n\n    val sideSheetState = rememberDrawerState(initialValue = DrawerValue.Closed)\n    val isSheetSlideable = (isGrid && !settingsState.showSettingsInLandscape) || !isGrid\n    val layoutDirection = LocalLayoutDirection.current\n\n    var sheetExpanded by rememberSaveable { mutableStateOf(false) }\n\n    val drawerContent = remember(isSheetSlideable) {\n        movableContentOf {\n            MainDrawerContent(\n                sideSheetState = sideSheetState,\n                isSheetSlideable = isSheetSlideable,\n                sheetExpanded = sheetExpanded,\n                layoutDirection = layoutDirection,\n                settingsBlockContent = {\n                    SettingsContent(\n                        component = component.settingsComponent,\n                        appBarNavigationIcon = { showSettingsSearch, onCloseSearch ->\n                            AnimatedContent(\n                                targetState = !isSheetSlideable to showSettingsSearch,\n                                transitionSpec = { fadeIn() + scaleIn() togetherWith fadeOut() + scaleOut() }\n                            ) { (expanded, searching) ->\n                                if (searching) {\n                                    EnhancedIconButton(onClick = onCloseSearch) {\n                                        Icon(\n                                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                            contentDescription = stringResource(R.string.exit)\n                                        )\n                                    }\n                                } else if (expanded) {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            sheetExpanded = !sheetExpanded\n                                        }\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.AutoMirrored.Rounded.MenuOpen,\n                                            contentDescription = \"Expand\",\n                                            modifier = Modifier.rotate(\n                                                animateFloatAsState(if (!sheetExpanded) 0f else 180f).value\n                                            )\n                                        )\n                                    }\n                                }\n                            }\n                        }\n                    )\n                }\n            )\n        }\n    }\n\n    var showFeaturesFall by rememberSaveable { mutableStateOf(false) }\n\n    val content = remember {\n        movableContentOf {\n            MainContentImpl(\n                layoutDirection = layoutDirection,\n                isSheetSlideable = isSheetSlideable,\n                sideSheetState = sideSheetState,\n                sheetExpanded = sheetExpanded,\n                isGrid = isGrid,\n                onShowFeaturesFall = {\n                    showFeaturesFall = true\n                },\n                onGetClipList = component::parseClipList,\n                onTryGetUpdate = {\n                    component.tryGetUpdate(\n                        isNewRequest = true,\n                        onNoUpdates = {\n                            AppToastHost.showToast(\n                                icon = Icons.Rounded.FileDownloadOff,\n                                message = getString(R.string.no_updates)\n                            )\n                        }\n                    )\n                },\n                isUpdateAvailable = isUpdateAvailable,\n                onNavigate = component.onNavigate,\n                onToggleFavorite = component::toggleFavoriteScreen\n            )\n        }\n    }\n\n    Box(\n        modifier = Modifier\n            .fillMaxSize()\n            .clipToBounds()\n    ) {\n        if (settingsState.useFullscreenSettings) {\n            content()\n        } else {\n            if (isSheetSlideable) {\n                LocalLayoutDirection.ProvidesValue(\n                    if (layoutDirection == LayoutDirection.Ltr) LayoutDirection.Rtl\n                    else LayoutDirection.Ltr\n                ) {\n                    ModalNavigationDrawer(\n                        drawerState = sideSheetState,\n                        drawerContent = drawerContent,\n                        content = content\n                    )\n                }\n            } else {\n                Row {\n                    content.withModifier(\n                        modifier = Modifier.weight(1f)\n                    )\n                    if (settingsState.borderWidth > 0.dp) {\n                        Spacer(\n                            modifier = Modifier\n                                .fillMaxHeight()\n                                .width(settingsState.borderWidth)\n                                .background(\n                                    MaterialTheme.colorScheme.outlineVariant(\n                                        0.3f,\n                                        DrawerDefaults.standardContainerColor\n                                    )\n                                )\n                        )\n                    }\n                    drawerContent.withModifier(\n                        modifier = Modifier.container(\n                            shape = RectangleShape,\n                            borderColor = MaterialTheme.colorScheme.outlineVariant(\n                                0.3f,\n                                DrawerDefaults.standardContainerColor\n                            ),\n                            autoShadowElevation = 2.dp,\n                            resultPadding = 0.dp\n                        )\n                    )\n                }\n            }\n        }\n\n        AnimatedVisibility(\n            visible = showFeaturesFall,\n            modifier = Modifier\n                .fillMaxSize(),\n            enter = fadeIn(tween(1000)) + slideInVertically(tween(1000)) { -it / 4 },\n            exit = fadeOut(tween(1000)) + slideOutVertically(tween(1000)) { it / 4 }\n        ) {\n            val snowFallList = Screen.entries.mapNotNull { screen ->\n                screen.icon?.let { rememberVectorPainter(image = it) }\n            }\n            val color = MaterialTheme.colorScheme.onSecondaryContainer.copy(0.5f)\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .snowfall(\n                        type = FlakeType.Custom(snowFallList),\n                        color = color\n                    )\n            )\n            LaunchedEffect(showFeaturesFall) {\n                if (showFeaturesFall) {\n                    delay(5000)\n                    showFeaturesFall = false\n                }\n            }\n            DisposableEffect(Unit) {\n                onDispose { showFeaturesFall = false }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/FilteredScreenListFor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getStringLocalized\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport java.util.Locale\n\n@Composable\ninternal fun filteredScreenListFor(\n    screenSearchKeyword: String,\n    selectedNavigationItem: Int,\n    showScreenSearch: Boolean\n): State<List<Screen>> {\n    val settingsState = LocalSettingsState.current\n    val canSearchScreens = settingsState.screensSearchEnabled\n\n    val screenList by remember(settingsState.screenList) {\n        derivedStateOf {\n            settingsState.screenList.mapNotNull {\n                Screen.entries.find { s -> s.id == it }\n            }.takeIf { it.isNotEmpty() } ?: Screen.entries\n        }\n    }\n\n    return remember(\n        settingsState.groupOptionsByTypes,\n        settingsState.favoriteScreenList,\n        screenSearchKeyword,\n        screenList,\n        selectedNavigationItem,\n        showScreenSearch\n    ) {\n        derivedStateOf {\n            when {\n                settingsState.groupOptionsByTypes && (screenSearchKeyword.isEmpty() && !showScreenSearch) -> {\n                    Screen.typedEntries[selectedNavigationItem].entries\n                }\n\n                !settingsState.groupOptionsByTypes && (screenSearchKeyword.isEmpty() && !showScreenSearch) -> {\n                    if (selectedNavigationItem == 0) {\n                        screenList.filter {\n                            it.id in settingsState.favoriteScreenList\n                        }\n                    } else screenList\n                }\n\n                else -> screenList\n            }.let { screens ->\n                if (screenSearchKeyword.isNotEmpty() && canSearchScreens) {\n                    screens.filter {\n                        val string =\n                            appContext.getString(it.title) + \" \" + appContext.getString(it.subtitle)\n                        val stringEn = appContext.getStringLocalized(it.title, Locale.ENGLISH)\n                            .plus(\" \")\n                            .plus(appContext.getStringLocalized(it.subtitle, Locale.ENGLISH))\n                        stringEn.contains(other = screenSearchKeyword, ignoreCase = true).or(\n                            string.contains(other = screenSearchKeyword, ignoreCase = true)\n                        )\n                    }\n                } else screens\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/LauncherScreenSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BookmarkBorder\nimport androidx.compose.material3.BadgedBox\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.RichTooltip\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TooltipAnchorPosition\nimport androidx.compose.material3.TooltipBox\nimport androidx.compose.material3.TooltipDefaults\nimport androidx.compose.material3.rememberTooltipState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.icons.BookmarkRemove\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.IconShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\n\n@Composable\ninternal fun LauncherScreenSelector(\n    screenList: List<Screen>,\n    onNavigateToScreenWithPopUpTo: (Screen) -> Unit,\n    contentPadding: PaddingValues,\n    onToggleFavorite: (Screen) -> Unit,\n) {\n    val settingsState = LocalSettingsState.current\n\n    LazyVerticalGrid(\n        columns = GridCells.Adaptive(80.dp),\n        contentPadding = contentPadding,\n        verticalArrangement = Arrangement.spacedBy(16.dp),\n        horizontalArrangement = Arrangement.spacedBy(16.dp),\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        items(screenList) { screen ->\n            val containerColor by animateColorAsState(\n                if (settingsState.isNightMode) {\n                    MaterialTheme.colorScheme.secondaryContainer.blend(\n                        color = Color.Black,\n                        fraction = 0.3f\n                    )\n                } else {\n                    MaterialTheme.colorScheme.primaryContainer\n                }\n            )\n\n            Column(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                modifier = Modifier.animateItem()\n            ) {\n                TooltipBox(\n                    positionProvider = TooltipDefaults.rememberTooltipPositionProvider(\n                        TooltipAnchorPosition.Below\n                    ),\n                    tooltip = {\n                        RichTooltip(\n                            title = {\n                                Text(\n                                    text = stringResource(screen.title),\n                                    textAlign = TextAlign.Start\n                                )\n                            },\n                            text = {\n                                Text(\n                                    text = stringResource(screen.subtitle),\n                                    textAlign = TextAlign.Start\n                                )\n                            },\n                            colors = TooltipDefaults.richTooltipColors(\n                                containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                contentColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(\n                                    0.5f\n                                ),\n                                titleContentColor = MaterialTheme.colorScheme.onTertiaryContainer\n                            ),\n                        )\n                    },\n                    state = rememberTooltipState()\n                ) {\n                    BadgedBox(\n                        badge = {\n                            BoxAnimatedVisibility(\n                                visible = !settingsState.groupOptionsByTypes,\n                                modifier = Modifier\n                                    .size(34.dp)\n                                    .offset(x = (-8).dp, y = 8.dp),\n                            ) {\n                                val interactionSource = remember { MutableInteractionSource() }\n                                val shape = shapeByInteraction(\n                                    shape = AutoCircleShape(),\n                                    pressedShape = ShapeDefaults.smallMini,\n                                    interactionSource = interactionSource\n                                )\n                                EnhancedIconButton(\n                                    onClick = {\n                                        onToggleFavorite(screen)\n                                    },\n                                    modifier = Modifier\n                                        .fillMaxSize()\n                                        .background(\n                                            shape = shape,\n                                            color = MaterialTheme.colorScheme.surface\n                                        )\n                                        .padding(2.dp)\n                                        .padding(bottom = 0.5.dp),\n                                    containerColor = containerColor.copy(0.5f),\n                                    contentColor = LocalContentColor.current,\n                                    interactionSource = interactionSource\n                                ) {\n                                    val inFavorite by remember(\n                                        settingsState.favoriteScreenList,\n                                        screen\n                                    ) {\n                                        derivedStateOf {\n                                            settingsState.favoriteScreenList.find { it == screen.id } != null\n                                        }\n                                    }\n                                    AnimatedContent(\n                                        targetState = inFavorite,\n                                        transitionSpec = {\n                                            (fadeIn() + scaleIn(initialScale = 0.85f))\n                                                .togetherWith(\n                                                    fadeOut() + scaleOut(\n                                                        targetScale = 0.85f\n                                                    )\n                                                )\n                                        },\n                                        modifier = Modifier.fillMaxSize(0.6f)\n                                    ) { isInFavorite ->\n                                        val icon by remember(isInFavorite) {\n                                            derivedStateOf {\n                                                if (isInFavorite) Icons.Rounded.BookmarkRemove\n                                                else Icons.Rounded.BookmarkBorder\n                                            }\n                                        }\n                                        Icon(\n                                            imageVector = icon,\n                                            contentDescription = null\n                                        )\n                                    }\n                                }\n                            }\n                        }\n                    ) {\n                        val iconShape by remember(settingsState.iconShape) {\n                            derivedStateOf {\n                                settingsState.iconShape?.takeOrElseFrom(IconShape.entries)\n                            }\n                        }\n                        Box(\n                            modifier = Modifier\n                                .size(64.dp)\n                                .container(\n                                    resultPadding = 0.dp,\n                                    color = containerColor,\n                                    borderColor = MaterialTheme.colorScheme.outlineVariant(),\n                                    shape = iconShape?.shape ?: ShapeDefaults.circle\n                                )\n                                .hapticsClickable {\n                                    onNavigateToScreenWithPopUpTo(screen)\n                                }\n                                .padding(iconShape?.padding ?: 0.dp),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            AnimatedContent(\n                                targetState = screen.icon!!,\n                                modifier = Modifier.fillMaxSize(0.6f),\n                                transitionSpec = {\n                                    (slideInVertically() + fadeIn() + scaleIn())\n                                        .togetherWith(slideOutVertically { it / 2 } + fadeOut() + scaleOut())\n                                        .using(SizeTransform(false))\n                                }\n                            ) { icon ->\n                                Icon(\n                                    imageVector = icon,\n                                    contentDescription = null,\n                                    tint = animateColorAsState(\n                                        if (settingsState.isNightMode) {\n                                            MaterialTheme.colorScheme.primary\n                                        } else {\n                                            MaterialTheme.colorScheme.primary.blend(Color.Black)\n                                        }\n                                    ).value,\n                                    modifier = Modifier.fillMaxSize()\n                                )\n                            }\n                        }\n                    }\n                }\n                Spacer(Modifier.height(8.dp))\n                AnimatedContent(\n                    targetState = screen.title,\n                    transitionSpec = { fadeIn() togetherWith fadeOut() },\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    Text(\n                        text = stringResource(it),\n                        fontSize = 12.sp,\n                        lineHeight = 12.sp,\n                        maxLines = 1,\n                        overflow = TextOverflow.Ellipsis,\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(horizontal = 8.dp)\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/MainContentImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.DrawerState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.LayoutDirection\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberCurrentLifecycleEvent\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.realisticSnowfall\nimport kotlinx.coroutines.delay\nimport java.time.LocalDate\n\n@Composable\ninternal fun MainContentImpl(\n    layoutDirection: LayoutDirection,\n    isSheetSlideable: Boolean,\n    sideSheetState: DrawerState,\n    sheetExpanded: Boolean,\n    isGrid: Boolean,\n    onGetClipList: (List<Uri>) -> Unit,\n    onNavigate: (Screen) -> Unit,\n    onToggleFavorite: (Screen) -> Unit,\n    onShowFeaturesFall: () -> Unit,\n    onTryGetUpdate: () -> Unit,\n    isUpdateAvailable: Boolean\n) {\n    val settingsState = LocalSettingsState.current\n\n    var selectedNavigationItem by rememberSaveable { mutableIntStateOf(0) }\n    val canSearchScreens = settingsState.screensSearchEnabled\n    var showScreenSearch by rememberSaveable(canSearchScreens) { mutableStateOf(false) }\n    var screenSearchKeyword by rememberSaveable(canSearchScreens) { mutableStateOf(\"\") }\n    val currentScreenList by filteredScreenListFor(\n        screenSearchKeyword = screenSearchKeyword,\n        selectedNavigationItem = selectedNavigationItem,\n        showScreenSearch = showScreenSearch\n    )\n\n    LocalLayoutDirection.ProvidesValue(layoutDirection) {\n        val snowfallMode = settingsState.snowfallMode\n\n        val event = rememberCurrentLifecycleEvent()\n\n        val showSnowfall by remember(snowfallMode, event) {\n            derivedStateOf {\n                when (snowfallMode) {\n                    SnowfallMode.Auto -> {\n                        LocalDate.now().run {\n                            (monthValue == 12 && dayOfMonth >= 22) || (monthValue == 1 && dayOfMonth <= 11)\n                        }\n                    }\n\n                    SnowfallMode.Enabled -> true\n                    SnowfallMode.Disabled -> false\n                }\n            }\n        }\n\n        val scrollBehavior = if (showSnowfall) {\n            TopAppBarDefaults.pinnedScrollBehavior()\n        } else {\n            TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n        }\n\n        val topBar: @Composable () -> Unit = {\n            MainTopAppBar(\n                scrollBehavior = scrollBehavior,\n                onShowFeaturesFall = onShowFeaturesFall,\n                sideSheetState = sideSheetState,\n                isSheetSlideable = isSheetSlideable,\n                onNavigate = onNavigate,\n                type = if (showSnowfall) {\n                    EnhancedTopAppBarType.Medium\n                } else {\n                    EnhancedTopAppBarType.Large\n                },\n                modifier = Modifier.realisticSnowfall(\n                    enabled = showSnowfall\n                )\n            )\n        }\n\n        Scaffold(\n            modifier = Modifier\n                .fillMaxSize()\n                .nestedScroll(scrollBehavior.nestedScrollConnection),\n            topBar = {\n                val colorScheme = MaterialTheme.colorScheme\n\n                var key by remember {\n                    mutableStateOf(colorScheme.primary)\n                }\n\n                LaunchedEffect(colorScheme) {\n                    delay(200)\n                    key = colorScheme.primary\n                }\n\n                if (showSnowfall) {\n                    key(key) {\n                        topBar()\n                    }\n                } else {\n                    topBar()\n                }\n            },\n            bottomBar = {\n                AnimatedVisibility(\n                    visible = !isGrid || sheetExpanded || (showScreenSearch && canSearchScreens),\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    AnimatedContent(\n                        targetState = settingsState.groupOptionsByTypes to (showScreenSearch && canSearchScreens),\n                        transitionSpec = { fadeIn() togetherWith fadeOut() }\n                    ) { (groupOptionsByTypes, searching) ->\n                        if (groupOptionsByTypes && !searching) {\n                            MainNavigationBar(\n                                selectedIndex = selectedNavigationItem,\n                                onValueChange = { selectedNavigationItem = it }\n                            )\n                        } else if (!searching) {\n                            MainNavigationBarForFavorites(\n                                selectedIndex = selectedNavigationItem,\n                                onValueChange = { selectedNavigationItem = it }\n                            )\n                        } else {\n                            SearchableBottomBar(\n                                searching = true,\n                                updateAvailable = isUpdateAvailable,\n                                onTryGetUpdate = onTryGetUpdate,\n                                screenSearchKeyword = screenSearchKeyword,\n                                onUpdateSearch = {\n                                    screenSearchKeyword = it\n                                },\n                                onCloseSearch = {\n                                    showScreenSearch = false\n                                }\n                            )\n                        }\n                    }\n                }\n            },\n            contentWindowInsets = WindowInsets()\n        ) { contentPadding ->\n            Row(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(contentPadding)\n            ) {\n                val showNavRail =\n                    isGrid && screenSearchKeyword.isEmpty() && !sheetExpanded\n\n                AnimatedVisibility(\n                    visible = showNavRail,\n                    enter = fadeIn() + expandHorizontally(),\n                    exit = fadeOut() + shrinkHorizontally()\n                ) {\n                    if (settingsState.groupOptionsByTypes) {\n                        MainNavigationRail(\n                            selectedIndex = selectedNavigationItem,\n                            onValueChange = {\n                                selectedNavigationItem = it\n                            }\n                        )\n                    } else {\n                        MainNavigationRailForFavorites(\n                            selectedIndex = selectedNavigationItem,\n                            onValueChange = {\n                                selectedNavigationItem = it\n                            }\n                        )\n                    }\n                }\n\n                ScreenPreferenceSelection(\n                    currentScreenList = currentScreenList,\n                    showScreenSearch = showScreenSearch,\n                    screenSearchKeyword = screenSearchKeyword,\n                    isGrid = isGrid,\n                    isSheetSlideable = isSheetSlideable,\n                    showNavRail = showNavRail,\n                    onChangeShowScreenSearch = {\n                        showScreenSearch = it\n                    },\n                    onGetClipList = onGetClipList,\n                    onNavigateToScreenWithPopUpTo = onNavigate,\n                    onNavigationBarItemChange = { selectedNavigationItem = it },\n                    onToggleFavorite = onToggleFavorite\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/MainDrawerContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.DrawerDefaults\nimport androidx.compose.material3.DrawerState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ModalDrawerSheet\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.movableContentOf\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.GraphicsLayerScope\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.TransformOrigin\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.coerceAtLeast\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.min\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.CornerSides\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.autoElevatedBorder\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.only\nimport kotlinx.coroutines.delay\n\n@Composable\ninternal fun MainDrawerContent(\n    sideSheetState: DrawerState,\n    isSheetSlideable: Boolean,\n    sheetExpanded: Boolean,\n    layoutDirection: LayoutDirection,\n    settingsBlockContent: @Composable () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val settingsBlock = remember {\n        movableContentOf {\n            settingsBlockContent()\n        }\n    }\n\n    val screenSize = LocalScreenSize.current\n    val widthState by remember(sheetExpanded, screenSize) {\n        derivedStateOf {\n            if (isSheetSlideable) {\n                min(\n                    screenSize.width * 0.85f,\n                    DrawerDefaults.MaximumDrawerWidth\n                )\n            } else {\n                if (sheetExpanded) screenSize.width * 0.55f\n                else min(\n                    screenSize.width * 0.4f,\n                    DrawerDefaults.MaximumDrawerWidth\n                )\n            }.coerceAtLeast(1.dp)\n        }\n    }\n\n    var predictiveBackProgress by remember {\n        mutableFloatStateOf(0f)\n    }\n    val animatedPredictiveBackProgress by animateFloatAsState(predictiveBackProgress)\n\n    val clean = {\n        predictiveBackProgress = 0f\n    }\n    val shape = if (isSheetSlideable) {\n        ShapeDefaults.extraLarge.only(\n            CornerSides.End\n        )\n    } else RectangleShape\n\n    LaunchedEffect(sideSheetState.isOpen, isSheetSlideable) {\n        if (!sideSheetState.isOpen || isSheetSlideable) {\n            delay(300L)\n            clean()\n        }\n    }\n\n    PredictiveBackObserver(\n        onProgress = {\n            predictiveBackProgress = it / 6f\n        },\n        onClean = { isCompleted ->\n            if (isCompleted) {\n                sideSheetState.close()\n            }\n            clean()\n        },\n        enabled = (sideSheetState.isOpen || sideSheetState.isAnimationRunning) && isSheetSlideable\n    )\n\n    val autoElevation by animateDpAsState(\n        if (settingsState.drawContainerShadows) 16.dp\n        else 0.dp\n    )\n    ModalDrawerSheet(\n        modifier = Modifier\n            .width(animateDpAsState(targetValue = widthState).value)\n            .then(\n                if (isSheetSlideable) {\n                    Modifier\n                        .graphicsLayer {\n                            val sheetOffset = 0f\n                            val sheetHeight = size.height\n                            if (!sheetOffset.isNaN() && !sheetHeight.isNaN() && sheetHeight != 0f) {\n                                val progress = animatedPredictiveBackProgress\n                                scaleX = calculatePredictiveBackScaleX(progress)\n                                scaleY = calculatePredictiveBackScaleY(progress)\n                                transformOrigin =\n                                    TransformOrigin((sheetOffset + sheetHeight) / sheetHeight, 0.5f)\n                            }\n                        }\n                        .offset(-((settingsState.borderWidth + 1.dp)))\n                        .autoElevatedBorder(\n                            shape = shape,\n                            autoElevation = autoElevation\n                        )\n                        .autoElevatedBorder(\n                            height = 0.dp,\n                            shape = shape,\n                            autoElevation = autoElevation\n                        )\n                        .clip(shape)\n                } else Modifier\n            ),\n        drawerContainerColor = MaterialTheme.colorScheme.surfaceContainerLowest,\n        drawerShape = shape,\n        windowInsets = WindowInsets(0)\n    ) {\n        LocalLayoutDirection.ProvidesValue(layoutDirection) {\n            settingsBlock()\n        }\n    }\n}\n\nfun GraphicsLayerScope.calculatePredictiveBackScaleX(progress: Float): Float {\n    val width = size.width\n    return if (width.isNaN() || width == 0f) {\n        1f\n    } else {\n        (1f - progress).coerceAtLeast(0.85f)\n    }\n}\n\nfun GraphicsLayerScope.calculatePredictiveBackScaleY(progress: Float): Float {\n    val height = size.height\n    return if (height.isNaN() || height == 0f) {\n        1f\n    } else {\n        (1f - progress).coerceAtLeast(0.85f)\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/MainNavigationBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.NavigationBar\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedNavigationBarItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\ninternal fun MainNavigationBar(\n    selectedIndex: Int,\n    onValueChange: (Int) -> Unit\n) {\n    NavigationBar(\n        modifier = Modifier.drawHorizontalStroke(top = true)\n    ) {\n        Screen.typedEntries.forEachIndexed { index, group ->\n            val selected = index == selectedIndex\n            val haptics = LocalHapticFeedback.current\n            EnhancedNavigationBarItem(\n                modifier = Modifier.weight(1f),\n                selected = selected,\n                onClick = {\n                    onValueChange(index)\n                    haptics.longPress()\n                },\n                icon = {\n                    AnimatedContent(\n                        targetState = selected,\n                        transitionSpec = {\n                            fadeIn() togetherWith fadeOut()\n                        }\n                    ) { selected ->\n                        Icon(\n                            imageVector = group.icon(selected),\n                            contentDescription = stringResource(group.title)\n                        )\n                    }\n                },\n                label = {\n                    Text(\n                        text = stringResource(group.title),\n                        modifier = Modifier.marquee()\n                    )\n                }\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/MainNavigationBarForFavorites.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Bookmark\nimport androidx.compose.material.icons.rounded.BookmarkBorder\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.NavigationBar\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ServiceToolbox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedNavigationBarItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\ninternal fun MainNavigationBarForFavorites(\n    selectedIndex: Int,\n    onValueChange: (Int) -> Unit\n) {\n    NavigationBar(\n        modifier = Modifier.drawHorizontalStroke(top = true)\n    ) {\n        val haptics = LocalHapticFeedback.current\n\n        EnhancedNavigationBarItem(\n            modifier = Modifier.weight(1f),\n            selected = selectedIndex == 0,\n            onClick = {\n                onValueChange(0)\n                haptics.longPress()\n            },\n            icon = {\n                AnimatedContent(\n                    targetState = selectedIndex == 0,\n                    transitionSpec = {\n                        fadeIn() togetherWith fadeOut()\n                    }\n                ) { selected ->\n                    Icon(\n                        imageVector = if (selected) Icons.Rounded.Bookmark else Icons.Rounded.BookmarkBorder,\n                        contentDescription = null\n                    )\n                }\n            },\n            label = {\n                Text(\n                    text = stringResource(R.string.favorite),\n                    modifier = Modifier.marquee()\n                )\n            }\n        )\n\n        EnhancedNavigationBarItem(\n            modifier = Modifier.weight(1f),\n            selected = selectedIndex == 1,\n            onClick = {\n                onValueChange(1)\n                haptics.longPress()\n            },\n            icon = {\n                AnimatedContent(\n                    targetState = selectedIndex == 1,\n                    transitionSpec = {\n                        fadeIn() togetherWith fadeOut()\n                    }\n                ) { selected ->\n                    Icon(\n                        imageVector = if (selected) Icons.Rounded.ServiceToolbox else Icons.Outlined.ServiceToolbox,\n                        contentDescription = null\n                    )\n                }\n            },\n            label = {\n                Text(\n                    text = stringResource(R.string.tools),\n                    modifier = Modifier.marquee()\n                )\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/MainNavigationRail.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.statusBars\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.DrawerDefaults\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedNavigationRailItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun MainNavigationRail(\n    selectedIndex: Int,\n    onValueChange: (Int) -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n\n    Row {\n        Box(\n            modifier = Modifier\n                .fillMaxHeight()\n                .widthIn(min = 80.dp)\n                .container(\n                    shape = RectangleShape,\n                    autoShadowElevation = 10.dp,\n                    resultPadding = 0.dp\n                )\n        ) {\n            Column(\n                modifier = Modifier\n                    .fillMaxHeight()\n                    .padding(horizontal = 8.dp)\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .navigationBarsPadding()\n                    .padding(\n                        start = WindowInsets\n                            .statusBars\n                            .asPaddingValues()\n                            .calculateStartPadding(LocalLayoutDirection.current)\n                    )\n                    .padding(\n                        start = WindowInsets\n                            .displayCutout\n                            .asPaddingValues()\n                            .calculateStartPadding(LocalLayoutDirection.current)\n                    ),\n                verticalArrangement = Arrangement.spacedBy(\n                    4.dp,\n                    Alignment.CenterVertically\n                ),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                Spacer(Modifier.height(8.dp))\n                Screen.typedEntries.forEachIndexed { index, group ->\n                    val selected = index == selectedIndex\n                    val haptics = LocalHapticFeedback.current\n                    EnhancedNavigationRailItem(\n                        modifier = Modifier.width(100.dp),\n                        selected = selected,\n                        onClick = {\n                            onValueChange(index)\n                            haptics.longPress()\n                        },\n                        icon = {\n                            AnimatedContent(\n                                targetState = selected,\n                                transitionSpec = {\n                                    fadeIn() togetherWith fadeOut()\n                                }\n                            ) { selected ->\n                                Icon(\n                                    imageVector = group.icon(selected),\n                                    contentDescription = stringResource(group.title)\n                                )\n                            }\n                        },\n                        label = {\n                            Text(stringResource(group.title))\n                        }\n                    )\n                }\n                Spacer(Modifier.height(8.dp))\n            }\n        }\n        Spacer(\n            Modifier\n                .fillMaxHeight()\n                .width(settingsState.borderWidth)\n                .background(\n                    MaterialTheme.colorScheme.outlineVariant(\n                        0.3f,\n                        DrawerDefaults.standardContainerColor\n                    )\n                )\n        )\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/MainNavigationRailForFavorites.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.statusBars\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Bookmark\nimport androidx.compose.material.icons.rounded.BookmarkBorder\nimport androidx.compose.material3.DrawerDefaults\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.NavigationRailItem\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ServiceToolbox\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\ninternal fun MainNavigationRailForFavorites(\n    selectedIndex: Int,\n    onValueChange: (Int) -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n\n    Row {\n        Box(\n            modifier = Modifier\n                .fillMaxHeight()\n                .widthIn(min = 80.dp)\n                .container(\n                    shape = RectangleShape,\n                    autoShadowElevation = 10.dp,\n                    resultPadding = 0.dp\n                )\n        ) {\n            Column(\n                modifier = Modifier\n                    .fillMaxHeight()\n                    .padding(horizontal = 8.dp)\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .navigationBarsPadding()\n                    .padding(\n                        start = WindowInsets\n                            .statusBars\n                            .asPaddingValues()\n                            .calculateStartPadding(LocalLayoutDirection.current)\n                    )\n                    .padding(\n                        start = WindowInsets\n                            .displayCutout\n                            .asPaddingValues()\n                            .calculateStartPadding(LocalLayoutDirection.current)\n                    ),\n                verticalArrangement = Arrangement.spacedBy(\n                    4.dp,\n                    Alignment.CenterVertically\n                ),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                Spacer(Modifier.height(8.dp))\n                val haptics = LocalHapticFeedback.current\n                NavigationRailItem(\n                    modifier = Modifier\n                        .height(height = 56.dp)\n                        .width(100.dp),\n                    selected = selectedIndex == 0,\n                    onClick = {\n                        onValueChange(0)\n                        haptics.longPress()\n                    },\n                    icon = {\n                        AnimatedContent(\n                            targetState = selectedIndex == 0,\n                            transitionSpec = {\n                                fadeIn() togetherWith fadeOut()\n                            }\n                        ) { selected ->\n                            Icon(\n                                imageVector = if (selected) Icons.Rounded.Bookmark else Icons.Rounded.BookmarkBorder,\n                                contentDescription = null\n                            )\n                        }\n                    },\n                    label = {\n                        Text(\n                            text = stringResource(R.string.favorite),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n\n                NavigationRailItem(\n                    modifier = Modifier\n                        .height(height = 56.dp)\n                        .width(100.dp),\n                    selected = selectedIndex == 1,\n                    onClick = {\n                        onValueChange(1)\n                        haptics.longPress()\n                    },\n                    icon = {\n                        AnimatedContent(\n                            targetState = selectedIndex == 1,\n                            transitionSpec = {\n                                fadeIn() togetherWith fadeOut()\n                            }\n                        ) { selected ->\n                            Icon(\n                                imageVector = if (selected) Icons.Rounded.ServiceToolbox else Icons.Outlined.ServiceToolbox,\n                                contentDescription = null\n                            )\n                        }\n                    },\n                    label = {\n                        Text(\n                            text = stringResource(R.string.tools),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n                Spacer(Modifier.height(8.dp))\n            }\n        }\n        Box(\n            Modifier\n                .fillMaxHeight()\n                .width(settingsState.borderWidth)\n                .background(\n                    MaterialTheme.colorScheme.outlineVariant(\n                        0.3f,\n                        DrawerDefaults.standardContainerColor\n                    )\n                )\n        )\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/MainTopAppBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"KotlinConstantConditions\")\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.PushPin\nimport androidx.compose.material.icons.rounded.Settings\nimport androidx.compose.material.icons.twotone.BugReport\nimport androidx.compose.material3.DrawerState\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileArrowUpRight\nimport com.t8rin.imagetoolbox.core.resources.icons.PhotoPrints\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.isFirstLaunch\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppVersionPreReleaseFlavored\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.canPinShortcuts\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.createScreenShortcut\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.pulsate\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.rotateAnimation\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport kotlinx.coroutines.launch\nimport kotlin.time.ExperimentalTime\n\n@OptIn(ExperimentalTime::class)\n@Composable\ninternal fun MainTopAppBar(\n    scrollBehavior: TopAppBarScrollBehavior,\n    onShowFeaturesFall: () -> Unit,\n    onNavigate: (Screen) -> Unit,\n    sideSheetState: DrawerState,\n    isSheetSlideable: Boolean,\n    type: EnhancedTopAppBarType = EnhancedTopAppBarType.Large,\n    modifier: Modifier = Modifier\n) {\n    EnhancedTopAppBar(\n        type = type,\n        title = {\n            MainTitle(onShowSnowfall = onShowFeaturesFall)\n        },\n        actions = {\n            PinShortcutButton()\n\n            EmbeddedPickerButton(\n                onNavigate = onNavigate\n            )\n\n            SettingsButton(\n                onNavigate = onNavigate,\n                sideSheetState = sideSheetState,\n                isSheetSlideable = isSheetSlideable\n            )\n        },\n        scrollBehavior = scrollBehavior,\n        modifier = modifier\n    )\n}\n\n@Composable\nprivate fun PinShortcutButton() {\n    val context = LocalContext.current\n\n    if (context.canPinShortcuts()) {\n        val settingsState = LocalSettingsState.current\n\n        val scope = rememberCoroutineScope()\n\n        var showShortcutAddingSheet by rememberSaveable {\n            mutableStateOf(false)\n        }\n        EnhancedIconButton(\n            onClick = {\n                showShortcutAddingSheet = true\n            },\n            forceMinimumInteractiveComponentSize = false\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.MobileArrowUpRight,\n                contentDescription = null\n            )\n        }\n        EnhancedModalBottomSheet(\n            visible = showShortcutAddingSheet,\n            onDismiss = { showShortcutAddingSheet = it },\n            confirmButton = {\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.primaryContainer,\n                    onClick = {\n                        showShortcutAddingSheet = false\n                    }\n                ) {\n                    Text(stringResource(R.string.close))\n                }\n            },\n            title = {\n                TitleItem(\n                    text = stringResource(R.string.create_shortcut),\n                    icon = Icons.Rounded.MobileArrowUpRight,\n                )\n            }\n        ) {\n            val screenList by remember(settingsState.screenList) {\n                derivedStateOf {\n                    settingsState.screenList.mapNotNull {\n                        Screen.entries.find { s -> s.id == it }\n                    }.distinctBy { it.id }.ifEmpty { Screen.entries }\n                }\n            }\n\n            var showShortcutPreviewDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var selectedScreenId by rememberSaveable {\n                mutableIntStateOf(-1)\n            }\n            val colorScheme = MaterialTheme.colorScheme\n            var shortcutColor by rememberSaveable(\n                selectedScreenId,\n                stateSaver = ColorSaver\n            ) {\n                mutableStateOf(colorScheme.primaryContainer)\n            }\n            val selectedScreen by remember(screenList, selectedScreenId) {\n                derivedStateOf {\n                    screenList.find { it.id == selectedScreenId }\n                }\n            }\n\n            EnhancedAlertDialog(\n                visible = showShortcutPreviewDialog,\n                onDismissRequest = { showShortcutPreviewDialog = false },\n                confirmButton = {\n                    EnhancedButton(\n                        onClick = {\n                            selectedScreen?.let { screen ->\n                                scope.launch {\n                                    context.createScreenShortcut(\n                                        screen = screen,\n                                        tint = shortcutColor,\n                                        onFailure = AppToastHost::showFailureToast\n                                    )\n                                }\n                            }\n                        }\n                    ) {\n                        Text(stringResource(R.string.add))\n                    }\n                },\n                dismissButton = {\n                    EnhancedButton(\n                        onClick = {\n                            showShortcutPreviewDialog = false\n                        },\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer\n                    ) {\n                        Text(stringResource(R.string.close))\n                    }\n                },\n                icon = {\n                    Icon(\n                        imageVector = Icons.Rounded.MobileArrowUpRight,\n                        contentDescription = null\n                    )\n                },\n                title = {\n                    Text(\n                        text = stringResource(R.string.create_shortcut)\n                    )\n                },\n                text = {\n                    val state = rememberScrollState()\n                    Column(\n                        verticalArrangement = Arrangement.Center,\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        modifier = Modifier\n                            .fadingEdges(\n                                scrollableState = state,\n                                isVertical = true\n                            )\n                            .enhancedVerticalScroll(state)\n                    ) {\n                        Box(\n                            modifier = Modifier\n                                .background(Color.White, ShapeDefaults.circle)\n                                .padding(8.dp)\n                        ) {\n                            Icon(\n                                imageVector = selectedScreen?.icon\n                                    ?: Icons.Rounded.MobileArrowUpRight,\n                                contentDescription = null,\n                                tint = shortcutColor,\n                                modifier = Modifier.size(36.dp)\n                            )\n                        }\n                        Spacer(Modifier.height(16.dp))\n                        ColorSelection(\n                            value = shortcutColor,\n                            onValueChange = { shortcutColor = it }\n                        )\n                    }\n                }\n            )\n\n            LazyVerticalStaggeredGrid(\n                columns = StaggeredGridCells.Adaptive(250.dp),\n                contentPadding = PaddingValues(16.dp),\n                verticalItemSpacing = 8.dp,\n                horizontalArrangement = Arrangement.spacedBy(8.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                item(\n                    span = StaggeredGridItemSpan.FullLine\n                ) {\n                    PreferenceItem(\n                        title = stringResource(R.string.create_shortcut_title),\n                        subtitle = stringResource(R.string.create_shortcut_subtitle),\n                        startIcon = Icons.Rounded.PushPin,\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        modifier = Modifier.padding(bottom = 8.dp),\n                        shape = ShapeDefaults.extremeLarge\n                    )\n                }\n\n                items(\n                    items = screenList,\n                    key = { it.id }\n                ) { screen ->\n                    PreferenceItem(\n                        onClick = {\n                            showShortcutPreviewDialog = true\n                            selectedScreenId = screen.id\n                        },\n                        startIcon = screen.icon,\n                        title = stringResource(screen.title),\n                        subtitle = stringResource(screen.subtitle),\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun EmbeddedPickerButton(\n    onNavigate: (Screen) -> Unit\n) {\n    var editSheetData by remember {\n        mutableStateOf(listOf<Uri>())\n    }\n\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        editSheetData = uris\n    }\n\n    EnhancedIconButton(\n        onClick = imagePicker::pickImage,\n        onLongClick = { showOneTimeImagePickingDialog = true },\n        forceMinimumInteractiveComponentSize = false\n    ) {\n        Icon(\n            imageVector = Icons.Outlined.PhotoPrints,\n            contentDescription = \"Embedded Picker Button\"\n        )\n    }\n\n    OneTimeImagePickingDialog(\n        onDismiss = { showOneTimeImagePickingDialog = false },\n        picker = Picker.Multiple,\n        imagePicker = imagePicker,\n        visible = showOneTimeImagePickingDialog\n    )\n\n    ProcessImagesPreferenceSheet(\n        uris = editSheetData,\n        visible = editSheetData.isNotEmpty(),\n        onDismiss = {\n            editSheetData = emptyList()\n        },\n        onNavigate = onNavigate\n    )\n}\n\n@Composable\nprivate fun SettingsButton(\n    onNavigate: (Screen) -> Unit,\n    sideSheetState: DrawerState,\n    isSheetSlideable: Boolean\n) {\n    val scope = rememberCoroutineScope()\n    val settingsState = LocalSettingsState.current\n\n    if (isSheetSlideable || settingsState.useFullscreenSettings) {\n        EnhancedIconButton(\n            onClick = {\n                if (settingsState.useFullscreenSettings) {\n                    onNavigate(Screen.Settings())\n                } else {\n                    scope.launch {\n                        sideSheetState.open()\n                    }\n                }\n            },\n            modifier = Modifier\n                .pulsate(\n                    range = 0.95f..1.2f,\n                    enabled = settingsState.isFirstLaunch()\n                )\n                .rotateAnimation(enabled = settingsState.isFirstLaunch())\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.Settings,\n                contentDescription = stringResource(R.string.settings)\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun MainTitle(\n    onShowSnowfall: () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n\n    LocalLayoutDirection.ProvidesValue(LayoutDirection.Ltr) {\n        val badgeText = remember {\n            \"${Screen.FEATURES_COUNT} $AppVersionPreReleaseFlavored\".trim()\n        }\n\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            modifier = Modifier.marquee()\n        ) {\n            AnimatedContent(settingsState.mainScreenTitle) { title ->\n                Text(title)\n            }\n            if (BuildConfig.DEBUG) {\n                Icon(\n                    imageVector = Icons.TwoTone.BugReport,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .offset(x = 2.dp)\n                        .size(\n                            with(LocalDensity.current) {\n                                LocalTextStyle.current.fontSize.toDp() * 1.05f\n                            }\n                        )\n                )\n            }\n\n            EnhancedBadge(\n                content = {\n                    Text(badgeText)\n                },\n                containerColor = MaterialTheme.colorScheme.tertiary,\n                contentColor = MaterialTheme.colorScheme.onTertiary,\n                modifier = Modifier\n                    .padding(horizontal = 2.dp)\n                    .padding(bottom = 12.dp)\n                    .scaleOnTap {\n                        onShowSnowfall()\n                    }\n            )\n            Spacer(Modifier.width(12.dp))\n            TopAppBarEmoji()\n        }\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/ScreenPreferenceSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport android.content.ClipboardManager\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ContentPasteOff\nimport androidx.compose.material.icons.rounded.BookmarkBorder\nimport androidx.compose.material.icons.rounded.ContentPaste\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material3.BadgedBox\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.content.getSystemService\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BookmarkOff\nimport com.t8rin.imagetoolbox.core.resources.icons.BookmarkRemove\nimport com.t8rin.imagetoolbox.core.resources.icons.LayersSearchOutline\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.clipList\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberClipboardData\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButtonType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\ninternal fun RowScope.ScreenPreferenceSelection(\n    currentScreenList: List<Screen>,\n    showScreenSearch: Boolean,\n    screenSearchKeyword: String,\n    isGrid: Boolean,\n    isSheetSlideable: Boolean,\n    onGetClipList: (List<Uri>) -> Unit,\n    onNavigationBarItemChange: (Int) -> Unit,\n    onNavigateToScreenWithPopUpTo: (Screen) -> Unit,\n    onChangeShowScreenSearch: (Boolean) -> Unit,\n    onToggleFavorite: (Screen) -> Unit,\n    showNavRail: Boolean,\n) {\n    val settingsState = LocalSettingsState.current\n    val cutout = WindowInsets.displayCutout.asPaddingValues()\n    val canSearchScreens = settingsState.screensSearchEnabled\n    val isSearching =\n        showScreenSearch && screenSearchKeyword.isNotEmpty() && canSearchScreens\n    val isScreenSelectionLauncherMode = settingsState.isScreenSelectionLauncherMode\n\n    AnimatedContent(\n        modifier = Modifier\n            .weight(1f)\n            .widthIn(min = 1.dp),\n        targetState = remember(currentScreenList, isSearching, settingsState.favoriteScreenList) {\n            Triple(\n                currentScreenList.isNotEmpty(),\n                isSearching,\n                settingsState.favoriteScreenList.isEmpty()\n            )\n        },\n        transitionSpec = {\n            fadeIn() togetherWith fadeOut()\n        }\n    ) { (hasScreens, isSearching, noFavorites) ->\n        if (hasScreens) {\n            Box(\n                modifier = Modifier.fillMaxSize()\n            ) {\n                val clipboardData by rememberClipboardData()\n                val allowAutoPaste = settingsState.allowAutoClipboardPaste\n                val showClipButton =\n                    (clipboardData.isNotEmpty() && allowAutoPaste) || !allowAutoPaste\n                val showSearchButton = !showScreenSearch && canSearchScreens\n\n                val layoutDirection = LocalLayoutDirection.current\n                val navBarsPadding = WindowInsets\n                    .navigationBars\n                    .asPaddingValues()\n                    .calculateBottomPadding()\n\n                val contentPadding by remember(\n                    isGrid, navBarsPadding,\n                    showClipButton, showSearchButton,\n                    isSheetSlideable, layoutDirection,\n                    cutout, showNavRail, isScreenSelectionLauncherMode\n                ) {\n                    derivedStateOf {\n                        val vertical = if (isScreenSelectionLauncherMode) 12.dp else 0.dp\n                        val firstBottomPart = if (isGrid) {\n                            navBarsPadding\n                        } else {\n                            0.dp\n                        }\n\n                        val secondBottomPart = if (showClipButton && showSearchButton) {\n                            76.dp + 48.dp\n                        } else if (showClipButton || showSearchButton) {\n                            76.dp\n                        } else {\n                            0.dp\n                        }\n\n                        PaddingValues(\n                            bottom = 12.dp + firstBottomPart + secondBottomPart + vertical,\n                            top = 12.dp + vertical,\n                            end = 12.dp + if (isSheetSlideable) {\n                                cutout.calculateEndPadding(layoutDirection)\n                            } else 0.dp,\n                            start = 12.dp + if (!showNavRail) {\n                                cutout.calculateStartPadding(layoutDirection)\n                            } else 0.dp\n                        )\n                    }\n                }\n\n                AnimatedContent(\n                    targetState = isScreenSelectionLauncherMode,\n                    modifier = Modifier.fillMaxSize()\n                ) { isLauncherMode ->\n                    if (isLauncherMode) {\n                        LauncherScreenSelector(\n                            screenList = currentScreenList,\n                            onNavigateToScreenWithPopUpTo = onNavigateToScreenWithPopUpTo,\n                            contentPadding = contentPadding,\n                            onToggleFavorite = onToggleFavorite\n                        )\n                    } else {\n                        LazyVerticalStaggeredGrid(\n                            reverseLayout = showScreenSearch && screenSearchKeyword.isNotEmpty() && canSearchScreens,\n                            modifier = Modifier.fillMaxSize(),\n                            columns = StaggeredGridCells.Adaptive(220.dp),\n                            verticalItemSpacing = 12.dp,\n                            horizontalArrangement = Arrangement.spacedBy(\n                                space = 12.dp,\n                                alignment = Alignment.CenterHorizontally\n                            ),\n                            contentPadding = contentPadding,\n                            flingBehavior = enhancedFlingBehavior(),\n                            content = {\n                                items(currentScreenList) { screen ->\n                                    PreferenceItemOverload(\n                                        onClick = {\n                                            onNavigateToScreenWithPopUpTo(screen)\n                                        },\n                                        containerColor = MaterialTheme.colorScheme.surfaceContainerLow,\n                                        modifier = Modifier\n                                            .widthIn(min = 1.dp)\n                                            .fillMaxWidth()\n                                            .animateItem(),\n                                        shape = ShapeDefaults.default,\n                                        title = stringResource(screen.title),\n                                        subtitle = stringResource(screen.subtitle),\n                                        badge = {\n                                            AnimatedVisibility(\n                                                visible = screen.isBetaFeature,\n                                                modifier = Modifier\n                                                    .align(Alignment.CenterVertically)\n                                                    .padding(\n                                                        start = 4.dp,\n                                                        bottom = 2.dp,\n                                                        top = 2.dp\n                                                    ),\n                                                enter = fadeIn(),\n                                                exit = fadeOut()\n                                            ) {\n                                                EnhancedBadge(\n                                                    content = {\n                                                        Text(stringResource(R.string.beta))\n                                                    },\n                                                    containerColor = MaterialTheme.colorScheme.secondary,\n                                                    contentColor = MaterialTheme.colorScheme.onSecondary\n                                                )\n                                            }\n                                        },\n                                        endIcon = {\n                                            Row(\n                                                verticalAlignment = Alignment.CenterVertically,\n                                                horizontalArrangement = Arrangement.spacedBy(4.dp)\n                                            ) {\n                                                if (!settingsState.groupOptionsByTypes) {\n                                                    EnhancedIconButton(\n                                                        onClick = {\n                                                            onToggleFavorite(screen)\n                                                        },\n                                                        modifier = Modifier.offset(8.dp)\n                                                    ) {\n                                                        val inFavorite by remember(\n                                                            settingsState.favoriteScreenList,\n                                                            screen\n                                                        ) {\n                                                            derivedStateOf {\n                                                                settingsState.favoriteScreenList.find { it == screen.id } != null\n                                                            }\n                                                        }\n                                                        AnimatedContent(\n                                                            targetState = inFavorite,\n                                                            transitionSpec = {\n                                                                (fadeIn() + scaleIn(initialScale = 0.85f))\n                                                                    .togetherWith(\n                                                                        fadeOut() + scaleOut(\n                                                                            targetScale = 0.85f\n                                                                        )\n                                                                    )\n                                                            }\n                                                        ) { isInFavorite ->\n                                                            val icon by remember(isInFavorite) {\n                                                                derivedStateOf {\n                                                                    if (isInFavorite) Icons.Rounded.BookmarkRemove\n                                                                    else Icons.Rounded.BookmarkBorder\n                                                                }\n                                                            }\n                                                            Icon(\n                                                                imageVector = icon,\n                                                                contentDescription = null\n                                                            )\n                                                        }\n                                                    }\n                                                }\n                                            }\n                                        },\n                                        startIcon = {\n                                            AnimatedContent(\n                                                targetState = screen.icon,\n                                                transitionSpec = {\n                                                    (slideInVertically() + fadeIn() + scaleIn())\n                                                        .togetherWith(slideOutVertically { it / 2 } + fadeOut() + scaleOut())\n                                                        .using(SizeTransform(false))\n                                                }\n                                            ) { icon ->\n                                                icon?.let {\n                                                    Icon(\n                                                        imageVector = icon,\n                                                        contentDescription = null\n                                                    )\n                                                }\n                                            }\n                                        }\n                                    )\n                                }\n                            }\n                        )\n                    }\n                }\n\n                val context = LocalContext.current\n                val clipboardManager = remember(context) {\n                    context.getSystemService<ClipboardManager>()\n                }\n                BoxAnimatedVisibility(\n                    visible = showClipButton,\n                    modifier = Modifier\n                        .align(Alignment.BottomEnd)\n                        .padding(16.dp)\n                        .then(\n                            if (showNavRail) {\n                                Modifier.navigationBarsPadding()\n                            } else Modifier\n                        ),\n                    enter = fadeIn() + scaleIn(),\n                    exit = fadeOut() + scaleOut()\n                ) {\n                    BadgedBox(\n                        badge = {\n                            if (clipboardData.isNotEmpty()) {\n                                EnhancedBadge(\n                                    containerColor = MaterialTheme.colorScheme.primary\n                                ) {\n                                    Text(clipboardData.size.toString())\n                                }\n                            }\n                        }\n                    ) {\n                        EnhancedFloatingActionButton(\n                            onClick = {\n                                if (!allowAutoPaste) {\n                                    val list = clipboardManager.clipList()\n                                    if (list.isEmpty()) {\n                                        AppToastHost.showToast(\n                                            message = getString(R.string.clipboard_paste_invalid_empty),\n                                            icon = Icons.Outlined.ContentPasteOff\n                                        )\n                                    } else onGetClipList(list)\n                                } else onGetClipList(clipboardData)\n                            },\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.ContentPaste,\n                                contentDescription = stringResource(R.string.copy)\n                            )\n                        }\n                    }\n                }\n                BoxAnimatedVisibility(\n                    visible = showSearchButton,\n                    enter = fadeIn() + scaleIn(),\n                    exit = fadeOut() + scaleOut(),\n                    modifier = Modifier\n                        .align(Alignment.BottomEnd)\n                        .then(\n                            if (showClipButton) {\n                                Modifier.padding(start = 16.dp, end = 16.dp, bottom = 4.dp)\n                            } else Modifier.padding(16.dp)\n                        )\n                        .then(\n                            if (showNavRail) {\n                                Modifier.navigationBarsPadding()\n                            } else Modifier\n                        )\n                        .then(\n                            if (showClipButton) {\n                                Modifier.padding(bottom = 76.dp)\n                            } else Modifier\n                        )\n                ) {\n                    EnhancedFloatingActionButton(\n                        containerColor = if (showClipButton) {\n                            MaterialTheme.colorScheme.secondaryContainer\n                        } else MaterialTheme.colorScheme.tertiaryContainer,\n                        type = if (showClipButton) {\n                            EnhancedFloatingActionButtonType.Small\n                        } else EnhancedFloatingActionButtonType.Primary,\n                        onClick = { onChangeShowScreenSearch(canSearchScreens) }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.LayersSearchOutline,\n                            contentDescription = stringResource(R.string.search_here)\n                        )\n                    }\n                }\n            }\n        } else {\n            if (!isSearching && noFavorites) {\n                Column(\n                    modifier = Modifier.fillMaxSize(),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    Spacer(Modifier.weight(1f))\n                    Text(\n                        text = stringResource(R.string.no_favorite_options_selected),\n                        fontSize = 18.sp,\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier.padding(\n                            start = 24.dp,\n                            end = 24.dp,\n                            top = 8.dp,\n                            bottom = 8.dp\n                        )\n                    )\n                    Icon(\n                        imageVector = Icons.Outlined.BookmarkOff,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .weight(2f)\n                            .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                            .fillMaxSize()\n                    )\n                    Spacer(Modifier.height(16.dp))\n                    EnhancedButton(\n                        onClick = {\n                            onNavigationBarItemChange(1)\n                        }\n                    ) {\n                        Text(stringResource(R.string.add_favorites))\n                    }\n                    Spacer(Modifier.weight(1f))\n                }\n            } else {\n                Column(\n                    modifier = Modifier.fillMaxSize(),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    Spacer(Modifier.weight(1f))\n                    Text(\n                        text = stringResource(R.string.nothing_found_by_search),\n                        fontSize = 18.sp,\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier.padding(\n                            start = 24.dp,\n                            end = 24.dp,\n                            top = 8.dp,\n                            bottom = 8.dp\n                        )\n                    )\n                    Icon(\n                        imageVector = Icons.Rounded.SearchOff,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .weight(2f)\n                            .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                            .fillMaxSize()\n                    )\n                    Spacer(Modifier.weight(1f))\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/components/SearchableBottomBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.components\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.BottomAppBar\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.focus.FocusRequester\nimport androidx.compose.ui.focus.focusRequester\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.APP_GITHUB_LINK\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Github\nimport com.t8rin.imagetoolbox.core.resources.icons.GooglePlay\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppVersion\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isInstalledFromPlayStore\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.asUnsafe\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.pulsate\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport kotlinx.coroutines.delay\n\n@Composable\ninternal fun SearchableBottomBar(\n    searching: Boolean,\n    updateAvailable: Boolean,\n    onTryGetUpdate: () -> Unit,\n    screenSearchKeyword: String,\n    onUpdateSearch: (String) -> Unit,\n    onCloseSearch: () -> Unit\n) {\n    BottomAppBar(\n        modifier = Modifier.drawHorizontalStroke(top = true),\n        actions = {\n            if (!searching) {\n                EnhancedButton(\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                    contentColor = MaterialTheme.colorScheme.onSecondaryContainer.copy(\n                        alpha = 0.5f\n                    ),\n                    borderColor = MaterialTheme.colorScheme.outlineVariant(\n                        onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                    ),\n                    modifier = Modifier\n                        .padding(horizontal = 16.dp)\n                        .pulsate(enabled = updateAvailable),\n                    onClick = onTryGetUpdate\n                ) {\n                    Text(\n                        stringResource(R.string.version) + \" $AppVersion (${BuildConfig.VERSION_CODE})\"\n                    )\n                }\n            } else {\n                val focus = remember {\n                    FocusRequester()\n                }\n                LaunchedEffect(Unit) {\n                    delay(100)\n                    focus.requestFocus()\n                }\n                BackHandler {\n                    onUpdateSearch(\"\")\n                    onCloseSearch()\n                }\n                ProvideTextStyle(value = MaterialTheme.typography.bodyLarge) {\n                    RoundedTextField(\n                        maxLines = 1,\n                        hint = { Text(stringResource(id = R.string.search_here)) },\n                        modifier = Modifier\n                            .focusRequester(focus)\n                            .padding(start = 6.dp)\n                            .offset(2.dp, (-2).dp),\n                        keyboardOptions = KeyboardOptions.Default.copy(\n                            imeAction = ImeAction.Search,\n                            autoCorrectEnabled = null\n                        ),\n                        value = screenSearchKeyword,\n                        onValueChange = {\n                            onUpdateSearch(it)\n                        },\n                        startIcon = {\n                            EnhancedIconButton(\n                                onClick = {\n                                    onUpdateSearch(\"\")\n                                    onCloseSearch()\n                                },\n                                modifier = Modifier.padding(start = 4.dp)\n                            ) {\n                                Icon(\n                                    imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                    contentDescription = stringResource(R.string.exit),\n                                    tint = MaterialTheme.colorScheme.onSurface\n                                )\n                            }\n                        },\n                        endIcon = {\n                            AnimatedVisibility(\n                                visible = screenSearchKeyword.isNotEmpty(),\n                                enter = fadeIn() + scaleIn(),\n                                exit = fadeOut() + scaleOut()\n                            ) {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        onUpdateSearch(\"\")\n                                    },\n                                    modifier = Modifier.padding(end = 4.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Close,\n                                        contentDescription = stringResource(R.string.close),\n                                        tint = MaterialTheme.colorScheme.onSurface\n                                    )\n                                }\n                            }\n                        },\n                        shape = ShapeDefaults.circle\n                    )\n                }\n            }\n        },\n        floatingActionButton = {\n            val context = LocalContext.current\n            val linkHandler = LocalUriHandler.current.asUnsafe()\n            if (!searching) {\n                EnhancedFloatingActionButton(\n                    onClick = {\n                        if (context.isInstalledFromPlayStore()) {\n                            runCatching {\n                                linkHandler.openUri(\"market://details?id=${context.packageName}\")\n                            }.onFailure {\n                                linkHandler.openUri(\"https://play.google.com/store/apps/details?id=${context.packageName}\")\n                            }\n                        } else {\n                            linkHandler.openUri(APP_GITHUB_LINK)\n                        }\n                    },\n                    modifier = Modifier.requiredSize(size = 56.dp),\n                    content = {\n                        if (context.isInstalledFromPlayStore()) {\n                            Icon(\n                                imageVector = Icons.Rounded.GooglePlay,\n                                contentDescription = \"Google Play\",\n                                modifier = Modifier.offset(1.5.dp)\n                            )\n                        } else {\n                            Icon(\n                                imageVector = Icons.Rounded.Github,\n                                contentDescription = stringResource(R.string.github)\n                            )\n                        }\n                    }\n                )\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/main/src/main/java/com/t8rin/imagetoolbox/feature/main/presentation/screenLogic/MainComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.main.presentation.screenLogic\n\nimport android.net.Uri\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.childContext\nimport com.arkivanov.decompose.value.Value\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass MainComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted private val onTryGetUpdate: (Boolean, () -> Unit) -> Unit,\n    @Assisted private val onGetClipList: (List<Uri>) -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    @Assisted val isUpdateAvailable: Value<Boolean>,\n    dispatchersHolder: DispatchersHolder,\n    private val settingsManager: SettingsManager,\n    settingsComponentFactory: SettingsComponent.Factory\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    val settingsComponent = settingsComponentFactory(\n        componentContext = childContext(\"mainSettings\"),\n        onTryGetUpdate = onTryGetUpdate,\n        onNavigate = onNavigate,\n        isUpdateAvailable = isUpdateAvailable,\n        onGoBack = null,\n        initialSearchQuery = \"\"\n    )\n\n    fun tryGetUpdate(\n        isNewRequest: Boolean = false,\n        onNoUpdates: () -> Unit = {}\n    ) = onTryGetUpdate(isNewRequest, onNoUpdates)\n\n    fun toggleFavoriteScreen(screen: Screen) {\n        componentScope.launch {\n            settingsManager.toggleFavoriteScreen(screen.id)\n        }\n    }\n\n    fun parseClipList(\n        list: List<Uri>\n    ) = onGetClipList(list)\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onTryGetUpdate: (Boolean, () -> Unit) -> Unit,\n            onGetClipList: (List<Uri>) -> Unit,\n            onNavigate: (Screen) -> Unit,\n            isUpdateAvailable: Value<Boolean>,\n        ): MainComponent\n    }\n\n}"
  },
  {
    "path": "feature/markup-layers/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/markup-layers/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.markup_layers\"\n"
  },
  {
    "path": "feature/markup-layers/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/AndroidMarkupLayersApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.utils.outputStream\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.json.JsonParser\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.createZip\nimport com.t8rin.imagetoolbox.core.utils.putEntry\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.AssetRegistry\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.MarkupMapper\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.MarkupProjectFile\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.MarkupProjectJsonEntry\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.ProjectArchive\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.ProjectFileLoadResult\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.LayersRenderer\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayersApplier\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProject\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProjectResult\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.util.UUID\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipException\nimport java.util.zip.ZipInputStream\nimport javax.inject.Inject\n\ninternal class AndroidMarkupLayersApplier @Inject constructor(\n    @ApplicationContext private val context: Context,\n    dispatchersHolder: DispatchersHolder,\n    private val mapper: MarkupMapper,\n    private val renderer: LayersRenderer,\n    private val jsonParser: JsonParser,\n) : MarkupLayersApplier<Bitmap>, DispatchersHolder by dispatchersHolder {\n\n    private val projectCacheRoot by lazy {\n        File(context.filesDir, \"markup-projects\").apply(File::mkdirs)\n    }\n\n    override suspend fun applyToImage(\n        image: Bitmap,\n        layers: List<MarkupLayer>\n    ): Bitmap = withContext(defaultDispatcher) {\n        renderer.render(\n            backgroundImage = image,\n            layers = layers\n        )\n    }\n\n    override suspend fun saveProject(\n        destination: Writeable,\n        project: MarkupProject\n    ) = withContext(ioDispatcher) {\n        writeProjectArchive(\n            destination = destination,\n            archive = project.toArchive() ?: return@withContext\n        )\n    }\n\n    override suspend fun openProject(uri: String): MarkupProjectResult = withContext(ioDispatcher) {\n        clearProjectCache()\n        try {\n            val extractionDir =\n                File(projectCacheRoot, UUID.randomUUID().toString()).apply(File::mkdirs)\n\n            val loadResult = loadProjectFile(\n                uri = uri,\n                extractionDir = extractionDir\n            )\n\n            when (loadResult) {\n                is ProjectFileLoadResult.Error -> loadResult.error\n                is ProjectFileLoadResult.Success -> mapper.map(\n                    project = loadResult.projectFile,\n                    extractionDir = extractionDir\n                )\n            }\n        } catch (t: Throwable) {\n            clearProjectCache()\n            if (t is ZipException) {\n                invalidArchiveError()\n            } else {\n                MarkupProjectResult.Error.Exception(\n                    throwable = t,\n                    message = t.localizedMessage\n                        ?: context.getString(R.string.something_went_wrong)\n                )\n            }\n        }\n    }\n\n    override fun clearProjectCache() {\n        projectCacheRoot.listFiles().orEmpty().forEach(File::deleteRecursively)\n    }\n\n    private fun MarkupProject.toArchive(): ProjectArchive? {\n        val assetRegistry = AssetRegistry()\n        val projectJson = jsonParser.toJson(\n            obj = mapper.map(\n                project = this,\n                registry = assetRegistry\n            ),\n            type = MarkupProjectFile::class.java\n        ) ?: return null\n\n        return ProjectArchive(\n            projectJson = projectJson,\n            assets = assetRegistry.entries()\n        )\n    }\n\n    private fun loadProjectFile(\n        uri: String,\n        extractionDir: File\n    ): ProjectFileLoadResult {\n        val projectJson = extractProjectArchive(\n            uri = uri,\n            extractionDir = extractionDir\n        ) ?: return ProjectFileLoadResult.Error(invalidArchiveError())\n\n        if (projectJson.isBlank()) {\n            return ProjectFileLoadResult.Error(\n                MarkupProjectResult.Error.MissingProjectFile(\n                    message = context.getString(R.string.markup_project_missing_data)\n                )\n            )\n        }\n\n        val projectFile = jsonParser.fromJson<MarkupProjectFile>(\n            json = projectJson,\n            type = MarkupProjectFile::class.java\n        ) ?: return ProjectFileLoadResult.Error(\n            MarkupProjectResult.Error.InvalidProjectFile(\n                message = context.getString(R.string.markup_project_corrupted)\n            )\n        )\n\n        return ProjectFileLoadResult.Success(projectFile)\n    }\n\n    private fun invalidArchiveError(): MarkupProjectResult.Error.InvalidArchive {\n        return MarkupProjectResult.Error.InvalidArchive(\n            message = context.getString(R.string.markup_project_open_failed)\n        )\n    }\n\n    private fun writeProjectArchive(\n        destination: Writeable,\n        archive: ProjectArchive\n    ) {\n        destination.outputStream().createZip { zip ->\n            zip.putEntry(MarkupProjectJsonEntry) {\n                it.write(archive.projectJson.toByteArray())\n            }\n            archive.assets.forEach { asset ->\n                zip.putEntry(asset.entryName) { entry ->\n                    openSourceStream(asset.source)?.use { input ->\n                        input.copyTo(entry)\n                    }\n                }\n            }\n        }\n    }\n\n    private fun extractProjectArchive(\n        uri: String,\n        extractionDir: File\n    ): String? {\n        val extractionDirPath = extractionDir.canonicalPath + File.separator\n\n        return context.contentResolver.openInputStream(uri.toUri())?.use { inputStream ->\n            ZipInputStream(inputStream).use { zipIn ->\n                var projectJson: String? = null\n                var entry: ZipEntry?\n                while (zipIn.nextEntry.also { entry = it } != null) {\n                    entry?.let { zipEntry ->\n                        if (!zipEntry.isDirectory && zipEntry.name == MarkupProjectJsonEntry) {\n                            projectJson = zipIn.readBytes().decodeToString()\n                            zipIn.closeEntry()\n                            return@let\n                        }\n\n                        val output = File(extractionDir, zipEntry.name).canonicalFile\n                        if (!output.path.startsWith(extractionDirPath)) {\n                            throw ZipException(\"Invalid zip entry path: ${zipEntry.name}\")\n                        }\n\n                        if (zipEntry.isDirectory) {\n                            output.mkdirs()\n                        } else {\n                            output.parentFile?.mkdirs()\n                            FileOutputStream(output).use { fos ->\n                                zipIn.copyTo(fos)\n                            }\n                        }\n                        zipIn.closeEntry()\n                    }\n                }\n                projectJson\n            }\n        }\n    }\n\n    private fun openSourceStream(source: String) = when {\n        source.startsWith(\"content://\") || source.startsWith(\"file://\") -> {\n            context.contentResolver.openInputStream(source.toUri())\n        }\n\n        else -> File(source).takeIf(File::exists)?.inputStream()\n            ?: context.contentResolver.openInputStream(source.toUri())\n    }\n\n}"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/project/AssetRegistry.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.project\n\nimport androidx.core.net.toUri\nimport java.io.File\n\ninternal class AssetRegistry {\n    private val entryBySource = linkedMapOf<String, AssetSource>()\n\n    fun register(\n        source: String,\n        proposedEntryName: String\n    ): String {\n        val key = sourceKey(source)\n        return entryBySource[key]?.entryName ?: proposedEntryName.also {\n            entryBySource[key] = AssetSource(\n                entryName = proposedEntryName,\n                source = source\n            )\n        }\n    }\n\n    private fun sourceKey(\n        source: String\n    ): String = when {\n        source.startsWith(\"android.resource://\") -> source\n        source.startsWith(\"content://\") -> source\n        source.startsWith(\"file://\") -> {\n            source.toUri().path\n                ?.let(::File)\n                ?.canonicalPath\n                ?.let { \"file:$it\" }\n                ?: source\n        }\n\n        else -> runCatching { File(source).canonicalPath }\n            .getOrNull()\n            ?.let { \"path:$it\" }\n            ?: source\n    }\n\n    fun entries(): List<AssetSource> = entryBySource.values.toList()\n}\n\ninternal data class AssetSource(\n    val entryName: String,\n    val source: String\n)\n\ninternal data class ProjectArchive(\n    val projectJson: String,\n    val assets: List<AssetSource>\n)"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/project/Mapping.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.project\n\nimport android.net.Uri\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Outline\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.DomainFontFamily\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FontType\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.asFontType\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.asUi\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.entries\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.extension\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.DropShadow\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerPosition\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProject\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProjectHistorySnapshot\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProjectResult\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ProjectBackground\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.TextGeometricTransform\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.arrowAngle\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.arrowSizeScale\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.cornerRadius\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.innerRadiusRatio\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.isRegular\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.layerCornerRadiusPercent\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ordinal\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.outlinedFillColorInt\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.resolveMarkupLayerShapeMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.rotationDegrees\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updateArrow\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updatePolygon\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updateRect\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updateStar\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.vertices\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.withOutlinedFillColor\nimport com.t8rin.logger.makeLog\nimport java.io.File\nimport javax.inject.Inject\n\ninternal class MarkupMapper @Inject constructor(\n    private val settingsManager: SettingsManager\n) {\n\n    fun map(project: MarkupProject, registry: AssetRegistry) = project.toSnapshot(registry)\n\n    suspend fun map(\n        project: MarkupProjectFile,\n        extractionDir: File\n    ) = project.toDomain(extractionDir)\n\n    private fun MarkupProject.toSnapshot(\n        assetRegistry: AssetRegistry\n    ): MarkupProjectFile = MarkupProjectFile(\n        version = MarkupProjectVersion,\n        background = background.toSnapshot(assetRegistry),\n        layers = layers.toSnapshotList(assetRegistry, prefix = \"layer\"),\n        lastLayers = lastLayers.toSnapshotList(assetRegistry, prefix = \"last\"),\n        undoneLayers = undoneLayers.toSnapshotList(assetRegistry, prefix = \"undone\"),\n        history = history.toEditorSnapshots(assetRegistry, prefix = \"history\"),\n        redoHistory = redoHistory.toEditorSnapshots(assetRegistry, prefix = \"redo\")\n    )\n\n    private suspend fun MarkupProjectFile.toDomain(\n        extractionDir: File\n    ): MarkupProjectResult {\n        if (version != MarkupProjectVersion) {\n            return MarkupProjectResult.Error.UnsupportedVersion(\n                version = version,\n                message = getString(R.string.unsupported_markup_project_version, version)\n            )\n        }\n\n        return MarkupProjectResult.Success(\n            project = MarkupProject(\n                background = background.toDomain(extractionDir),\n                layers = layers.toDomainLayers(extractionDir),\n                lastLayers = lastLayers.toDomainLayers(extractionDir),\n                undoneLayers = undoneLayers.toDomainLayers(extractionDir),\n                history = history.toDomainSnapshots(extractionDir),\n                redoHistory = redoHistory.toDomainSnapshots(extractionDir)\n            )\n        )\n    }\n\n    private fun List<MarkupProjectHistorySnapshot>.toEditorSnapshots(\n        assetRegistry: AssetRegistry,\n        prefix: String\n    ): List<EditorSnapshot> = mapIndexed { index, snapshot ->\n        snapshot.toSnapshot(\n            assetRegistry = assetRegistry,\n            prefix = \"$prefix-$index\"\n        )\n    }\n\n    private fun MarkupProjectHistorySnapshot.toSnapshot(\n        assetRegistry: AssetRegistry,\n        prefix: String\n    ): EditorSnapshot = EditorSnapshot(\n        background = background.toSnapshot(assetRegistry),\n        layers = layers.toSnapshotList(\n            assetRegistry = assetRegistry,\n            prefix = prefix\n        )\n    )\n\n    private fun List<MarkupLayer>.toSnapshotList(\n        assetRegistry: AssetRegistry,\n        prefix: String\n    ): List<LayerSnapshot> = mapIndexed { index, layer ->\n        layer.toSnapshot(\n            index = index,\n            assetRegistry = assetRegistry,\n            prefix = prefix\n        )\n    }\n\n    private fun ProjectBackground.toSnapshot(\n        assetRegistry: AssetRegistry\n    ): BackgroundSnapshot = when (this) {\n        is ProjectBackground.Color -> BackgroundSnapshot(\n            type = BackgroundType.Color,\n            width = width,\n            height = height,\n            color = color\n        )\n\n        is ProjectBackground.Image -> {\n            val source = uri\n            val entryName = assetRegistry.register(\n                source = source,\n                proposedEntryName = assetEntryName(\n                    prefix = \"background\",\n                    extension = sourceExtension(source)\n                )\n            )\n            BackgroundSnapshot(\n                type = BackgroundType.Image,\n                assetPath = entryName\n            )\n        }\n\n        ProjectBackground.None -> BackgroundSnapshot(type = BackgroundType.None)\n    }\n\n    private fun MarkupLayer.toSnapshot(\n        index: Int,\n        assetRegistry: AssetRegistry,\n        prefix: String\n    ): LayerSnapshot {\n        val layerType = type\n        return LayerSnapshot(\n            type = layerType.toSnapshotType(),\n            position = position.toSnapshot(),\n            contentWidth = contentSize.width,\n            contentHeight = contentSize.height,\n            visibleLineCount = visibleLineCount,\n            cornerRadiusPercent = layerType.layerCornerRadiusPercent(cornerRadiusPercent),\n            isLocked = isLocked,\n            blendingMode = blendingMode.value,\n            text = (layerType as? LayerType.Text)?.toSnapshot(\n                assetRegistry = assetRegistry,\n                fontPrefix = \"$prefix-$index-font\"\n            ),\n            picture = layerType.toPictureSnapshot(\n                assetRegistry = assetRegistry,\n                prefix = \"$prefix-$index\"\n            ),\n            shape = (layerType as? LayerType.Shape)?.toSnapshot(),\n            groupedLayers = groupedLayers.toSnapshotList(\n                assetRegistry = assetRegistry,\n                prefix = \"$prefix-$index-group\"\n            )\n        )\n    }\n\n    private fun LayerPosition.toSnapshot(): PositionSnapshot = PositionSnapshot(\n        scale = scale,\n        rotation = rotation,\n        isFlippedHorizontally = isFlippedHorizontally,\n        isFlippedVertically = isFlippedVertically,\n        offsetX = offsetX,\n        offsetY = offsetY,\n        alpha = alpha,\n        canvasWidth = currentCanvasSize.width,\n        canvasHeight = currentCanvasSize.height,\n        coerceToBounds = coerceToBounds,\n        isVisible = isVisible\n    )\n\n    private fun LayerType.toSnapshotType(): LayerSnapshotType = when (this) {\n        is LayerType.Text -> LayerSnapshotType.Text\n        is LayerType.Picture.Image -> LayerSnapshotType.Image\n        is LayerType.Picture.Sticker -> LayerSnapshotType.Sticker\n        is LayerType.Shape -> LayerSnapshotType.Shape\n    }\n\n    private fun LayerType.Text.toSnapshot(\n        assetRegistry: AssetRegistry,\n        fontPrefix: String\n    ): TextSnapshot = TextSnapshot(\n        color = color,\n        size = size,\n        font = font?.toSnapshot(\n            assetRegistry = assetRegistry,\n            prefix = fontPrefix\n        ),\n        backgroundColor = backgroundColor,\n        text = text,\n        decorations = decorations.map(Enum<*>::name),\n        outline = outline?.toSnapshot(),\n        alignment = alignment.name,\n        geometricTransform = geometricTransform?.toSnapshot(),\n        shadow = shadow?.toSnapshot()\n    )\n\n    private fun LayerType.toPictureSnapshot(\n        assetRegistry: AssetRegistry,\n        prefix: String\n    ): PictureSnapshot? = when (this) {\n        is LayerType.Picture.Image -> {\n            val source = imageData.toPersistableSource()\n            val entryName = assetRegistry.register(\n                source = source,\n                proposedEntryName = assetEntryName(\n                    prefix = prefix,\n                    extension = sourceExtension(source)\n                )\n            )\n            PictureSnapshot(\n                assetPath = entryName,\n                shadow = shadow?.toSnapshot()\n            )\n        }\n\n        is LayerType.Picture.Sticker -> PictureSnapshot(\n            value = imageData.toString(),\n            shadow = shadow?.toSnapshot()\n        )\n\n        is LayerType.Text,\n        is LayerType.Shape -> null\n    }\n\n    private fun LayerType.Shape.toSnapshot(): ShapeSnapshot = ShapeSnapshot(\n        modeName = shapeMode.kind.name,\n        modeOrdinal = shapeMode.ordinal,\n        color = color,\n        strokeWidth = strokeWidth,\n        widthRatio = widthRatio,\n        heightRatio = heightRatio,\n        fillColor = shapeMode.outlinedFillColorInt(),\n        rotationDegrees = shapeMode.rotationDegrees(),\n        cornerRadius = shapeMode.cornerRadius(),\n        vertices = shapeMode.vertices(),\n        isRegular = shapeMode.isRegular(),\n        innerRadiusRatio = shapeMode.innerRadiusRatio(),\n        sizeScale = shapeMode.arrowSizeScale(),\n        angle = shapeMode.arrowAngle(),\n        shadow = shadow?.toSnapshot()\n    )\n\n    private fun Outline.toSnapshot(): OutlineSnapshot = OutlineSnapshot(\n        color = color,\n        width = width\n    )\n\n    private fun TextGeometricTransform.toSnapshot(): TextGeometricTransformSnapshot =\n        TextGeometricTransformSnapshot(\n            scaleX = scaleX,\n            skewX = skewX\n        )\n\n    private fun DropShadow.toSnapshot(): DropShadowSnapshot = DropShadowSnapshot(\n        color = color,\n        offsetX = offsetX,\n        offsetY = offsetY,\n        blurRadius = blurRadius\n    )\n\n    private suspend fun List<LayerSnapshot>.toDomainLayers(\n        extractionDir: File\n    ): List<MarkupLayer> = map { it.toDomain(extractionDir) }\n\n    private suspend fun List<EditorSnapshot>.toDomainSnapshots(\n        extractionDir: File\n    ): List<MarkupProjectHistorySnapshot> = map { snapshot ->\n        MarkupProjectHistorySnapshot(\n            background = snapshot.background.toDomain(extractionDir),\n            layers = snapshot.layers.toDomainLayers(extractionDir)\n        )\n    }\n\n    private fun BackgroundSnapshot.toDomain(\n        extractionDir: File\n    ): ProjectBackground = when (type) {\n        BackgroundType.Image -> ProjectBackground.Image(\n            uri = File(extractionDir, assetPath.orEmpty()).toUri().toString()\n        )\n\n        BackgroundType.Color -> ProjectBackground.Color(\n            width = width ?: 1,\n            height = height ?: 1,\n            color = color ?: 0\n        )\n\n        BackgroundType.None -> ProjectBackground.None\n    }\n\n    private suspend fun LayerSnapshot.toDomain(\n        extractionDir: File\n    ): MarkupLayer {\n        val layerType = toDomainType(extractionDir)\n        return MarkupLayer(\n            type = layerType,\n            position = position.toDomain(),\n            contentSize = IntegerSize(\n                width = (contentWidth ?: 0).coerceAtLeast(0),\n                height = (contentHeight ?: 0).coerceAtLeast(0)\n            ),\n            visibleLineCount = visibleLineCount,\n            cornerRadiusPercent = layerType.layerCornerRadiusPercent(cornerRadiusPercent),\n            isLocked = isLocked,\n            blendingMode = BlendingMode.entries.find { it.value == blendingMode }\n                ?: BlendingMode.SrcOver,\n            groupedLayers = groupedLayers.toDomainLayers(extractionDir)\n        )\n    }\n\n    private suspend fun LayerSnapshot.toDomainType(\n        extractionDir: File\n    ): LayerType = when (type) {\n        LayerSnapshotType.Text -> {\n            val value = text ?: error(\"Missing text layer data\")\n            value.toDomain(extractionDir)\n        }\n\n        LayerSnapshotType.Image -> LayerType.Picture.Image(\n            imageData = File(extractionDir, picture?.assetPath.orEmpty()).toUri().toString(),\n            shadow = picture?.shadow?.toDomain()\n        )\n\n        LayerSnapshotType.Sticker -> LayerType.Picture.Sticker(\n            imageData = picture?.value.orEmpty(),\n            shadow = picture?.shadow?.toDomain()\n        )\n\n        LayerSnapshotType.Shape -> {\n            val value = shape ?: error(\"Missing shape layer data\")\n            value.toDomain()\n        }\n    }\n\n    private suspend fun TextSnapshot.toDomain(\n        extractionDir: File\n    ): LayerType.Text = LayerType.Text(\n        color = color,\n        size = size,\n        font = font?.toDomain(extractionDir),\n        backgroundColor = backgroundColor,\n        text = text,\n        decorations = decorations.toDomainDecorations(),\n        outline = outline?.toDomain(),\n        alignment = alignment.toDomainAlignment(),\n        geometricTransform = geometricTransform?.toDomain(),\n        shadow = shadow?.toDomain()\n    )\n\n    private fun ShapeSnapshot.toDomain(): LayerType.Shape {\n        val baseMode = resolveMarkupLayerShapeMode(\n            modeName = modeName,\n            modeOrdinal = modeOrdinal\n        )\n\n        val shapeMode = baseMode\n            .updateArrow(\n                sizeScale = sizeScale,\n                angle = angle\n            )\n            .updateRect(\n                rotationDegrees = rotationDegrees,\n                cornerRadius = cornerRadius\n            )\n            .updatePolygon(\n                vertices = vertices,\n                rotationDegrees = rotationDegrees,\n                isRegular = isRegular\n            )\n            .updateStar(\n                vertices = vertices,\n                innerRadiusRatio = innerRadiusRatio,\n                rotationDegrees = rotationDegrees,\n                isRegular = isRegular\n            )\n            .withOutlinedFillColor(fillColor)\n\n        return LayerType.Shape(\n            shapeMode = shapeMode,\n            color = color,\n            strokeWidth = strokeWidth,\n            widthRatio = widthRatio,\n            heightRatio = heightRatio,\n            shadow = shadow?.toDomain()\n        )\n    }\n\n    private fun List<String>.toDomainDecorations(): List<LayerType.Text.Decoration> {\n        return mapNotNull { value ->\n            runCatching {\n                LayerType.Text.Decoration.valueOf(value)\n            }.onFailure(Throwable::makeLog).getOrNull()\n        }\n    }\n\n    private fun String.toDomainAlignment(): LayerType.Text.Alignment {\n        return runCatching {\n            LayerType.Text.Alignment.valueOf(this)\n        }.getOrDefault(LayerType.Text.Alignment.Start)\n    }\n\n    private fun PositionSnapshot.toDomain(): LayerPosition = LayerPosition(\n        scale = scale,\n        rotation = rotation,\n        isFlippedHorizontally = isFlippedHorizontally,\n        isFlippedVertically = isFlippedVertically,\n        offsetX = offsetX,\n        offsetY = offsetY,\n        alpha = alpha,\n        currentCanvasSize = IntegerSize(\n            width = canvasWidth,\n            height = canvasHeight\n        ),\n        coerceToBounds = coerceToBounds,\n        isVisible = isVisible\n    )\n\n    private fun OutlineSnapshot.toDomain(): Outline = Outline(\n        color = color,\n        width = width\n    )\n\n    private fun TextGeometricTransformSnapshot.toDomain(): TextGeometricTransform =\n        TextGeometricTransform(\n            scaleX = scaleX,\n            skewX = skewX\n        )\n\n    private fun DropShadowSnapshot.toDomain(): DropShadow = DropShadow(\n        color = color,\n        offsetX = offsetX,\n        offsetY = offsetY,\n        blurRadius = blurRadius\n    )\n\n    private fun FontType.toSnapshot(\n        assetRegistry: AssetRegistry,\n        prefix: String\n    ): FontSnapshot =\n        when (this) {\n            is FontType.File -> {\n                val source = path\n                val fileName = File(path).name.takeIf(String::isNotBlank)\n                    ?: \"$prefix.ttf\"\n                val entryName = assetRegistry.register(\n                    source = source,\n                    proposedEntryName = \"assets/fonts/$prefix/$fileName\"\n                )\n                FontSnapshot(\n                    type = FontSnapshotType.File,\n                    path = path,\n                    assetPath = entryName,\n                    filename = fileName\n                )\n            }\n\n            is FontType.Resource -> {\n                val source = \"android.resource://${appContext.packageName}/$resId\"\n                val entryName = assetRegistry.register(\n                    source = source,\n                    proposedEntryName = \"assets/fonts/$prefix/resource-$resId.font\"\n                )\n                FontSnapshot(\n                    type = FontSnapshotType.Resource,\n                    resourceId = resId,\n                    resourceName = runCatching {\n                        appContext.resources.getResourceEntryName(resId)\n                    }.getOrNull(),\n                    familyKey = asUi()\n                        .takeIf { (it.type as? FontType.Resource)?.resId == resId }\n                        ?.asDomain()\n                        ?.asString(),\n                    assetPath = entryName,\n                    filename = \"resource-$resId.font\"\n                )\n            }\n        }\n\n    private suspend fun FontSnapshot.toDomain(\n        extractionDir: File\n    ): FontType? =\n        when (type) {\n            FontSnapshotType.File -> path\n                ?.takeIf { File(it).exists() }\n                ?.let { FontType.File(it) }\n                ?: restoreFontFromAsset(extractionDir)\n\n            FontSnapshotType.Resource -> familyKey\n                ?.let { DomainFontFamily.fromString(familyKey)?.asFontType() }\n                ?: resourceName\n                    ?.let(::resolveResourceByKnownFonts)\n                    ?.let { FontType.Resource(it) }\n                ?: resourceId\n                    ?.takeIf(::isValidFontResource)\n                    ?.let { FontType.Resource(it) }\n                ?: restoreFontFromAsset(extractionDir)\n        }\n\n    private fun Any.toPersistableSource(): String = when (this) {\n        is Uri -> toString()\n        is File -> toUri().toString()\n        else -> toString()\n    }\n\n    private fun assetEntryName(\n        prefix: String,\n        extension: String\n    ): String = \"assets/$prefix.$extension\"\n\n    private fun sourceExtension(\n        source: String\n    ): String = source.toUri().extension()\n        ?.takeIf(String::isNotBlank)\n        ?: source.substringAfterLast('.', \"\")\n            .takeIf(String::isNotBlank)\n        ?: \"png\"\n\n    private suspend fun FontSnapshot.restoreFontFromAsset(\n        extractionDir: File\n    ): FontType.File? {\n        val fontAsset = assetPath\n            ?.let { File(extractionDir, it) }\n            ?.takeIf(File::exists)\n            ?: return null\n\n        val preferredFilename = filename\n            ?.let { File(it).name }\n            ?.takeIf(String::isNotBlank)\n\n        val existingFont = settingsManager.settingsState.value.customFonts\n            .firstOrNull { custom ->\n                val file = File(custom.filePath)\n                file.exists() && preferredFilename != null && file.name.equals(\n                    preferredFilename,\n                    ignoreCase = true\n                )\n            }\n            ?.filePath\n            ?.let(FontType::File)\n\n        if (existingFont != null) return existingFont\n\n        return settingsManager.importCustomFont(fontAsset.toUri().toString())\n            ?.let { imported ->\n                FontType.File(imported.filePath)\n            } ?: FontType.File(fontAsset.absolutePath)\n    }\n\n    private fun resolveResourceByKnownFonts(\n        resourceName: String\n    ): Int? = UiFontFamily.defaultEntries\n        .mapNotNull { (it.type as? FontType.Resource)?.resId }\n        .firstOrNull { resId ->\n            runCatching {\n                appContext.resources.getResourceEntryName(resId) == resourceName\n            }.getOrDefault(false)\n        }\n\n    private fun isValidFontResource(\n        resourceId: Int\n    ): Boolean = runCatching {\n        appContext.resources.getResourceTypeName(resourceId) == \"font\"\n    }.getOrDefault(false)\n\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/project/MarkupProjectConstants.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.project\n\nconst val MarkupProjectExtension = \"itp\"\nconst val MarkupProjectJsonEntry = \"project.json\"\nconst val MarkupProjectVersion = 1"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/project/MarkupProjectExtensions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.project\n\nimport android.net.Uri\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.filename\n\nfun Uri.isMarkupProject(): Boolean {\n    val name = filename(appContext).orEmpty()\n    val uri = toString()\n\n    return name.isMarkupProjectFilename() || uri.isMarkupProjectFilename()\n}\n\nprivate fun String.isMarkupProjectFilename(): Boolean {\n    val value = lowercase()\n    return value.endsWith(\".$MarkupProjectExtension\") ||\n            value.endsWith(\".$MarkupProjectExtension.zip\")\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/project/MarkupProjectFile.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.project\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\n\ndata class MarkupProjectFile(\n    val version: Int = MarkupProjectVersion,\n    val background: BackgroundSnapshot,\n    val layers: List<LayerSnapshot>,\n    val lastLayers: List<LayerSnapshot>,\n    val undoneLayers: List<LayerSnapshot>,\n    val history: List<EditorSnapshot> = emptyList(),\n    val redoHistory: List<EditorSnapshot> = emptyList(),\n)\n\ndata class EditorSnapshot(\n    val background: BackgroundSnapshot,\n    val layers: List<LayerSnapshot>,\n)\n\ndata class BackgroundSnapshot(\n    val type: BackgroundType,\n    val assetPath: String? = null,\n    val width: Int? = null,\n    val height: Int? = null,\n    val color: Int? = null,\n)\n\ndata class LayerSnapshot(\n    val type: LayerSnapshotType,\n    val position: PositionSnapshot,\n    val contentWidth: Int? = null,\n    val contentHeight: Int? = null,\n    val visibleLineCount: Int? = null,\n    val cornerRadiusPercent: Int = 0,\n    val isLocked: Boolean = false,\n    val blendingMode: Int = BlendingMode.SrcOver.value,\n    val text: TextSnapshot? = null,\n    val picture: PictureSnapshot? = null,\n    val shape: ShapeSnapshot? = null,\n    val groupedLayers: List<LayerSnapshot> = emptyList(),\n)\n\ndata class PositionSnapshot(\n    val scale: Float,\n    val rotation: Float,\n    val isFlippedHorizontally: Boolean = false,\n    val isFlippedVertically: Boolean = false,\n    val offsetX: Float,\n    val offsetY: Float,\n    val alpha: Float,\n    val canvasWidth: Int,\n    val canvasHeight: Int,\n    val coerceToBounds: Boolean,\n    val isVisible: Boolean,\n)\n\ndata class TextSnapshot(\n    val color: Int,\n    val size: Float,\n    val font: FontSnapshot?,\n    val backgroundColor: Int,\n    val text: String,\n    val decorations: List<String>,\n    val outline: OutlineSnapshot?,\n    val alignment: String,\n    val geometricTransform: TextGeometricTransformSnapshot? = null,\n    val shadow: DropShadowSnapshot? = null,\n)\n\ndata class PictureSnapshot(\n    val assetPath: String? = null,\n    val value: String? = null,\n    val shadow: DropShadowSnapshot? = null,\n)\n\ndata class ShapeSnapshot(\n    val modeName: String? = null,\n    val modeOrdinal: Int = 0,\n    val color: Int,\n    val strokeWidth: Float,\n    val widthRatio: Float,\n    val heightRatio: Float,\n    val fillColor: Int? = null,\n    val rotationDegrees: Int? = null,\n    val cornerRadius: Float? = null,\n    val vertices: Int? = null,\n    val isRegular: Boolean? = null,\n    val innerRadiusRatio: Float? = null,\n    val sizeScale: Float? = null,\n    val angle: Float? = null,\n    val shadow: DropShadowSnapshot? = null,\n)\n\ndata class FontSnapshot(\n    val type: FontSnapshotType,\n    val resourceId: Int? = null,\n    val path: String? = null,\n    val resourceName: String? = null,\n    val familyKey: String? = null,\n    val assetPath: String? = null,\n    val filename: String? = null,\n)\n\ndata class OutlineSnapshot(\n    val color: Int,\n    val width: Float,\n)\n\ndata class TextGeometricTransformSnapshot(\n    val scaleX: Float = 1f,\n    val skewX: Float = 0f,\n)\n\ndata class DropShadowSnapshot(\n    val color: Int,\n    val offsetX: Float = 0f,\n    val offsetY: Float = 0f,\n    val blurRadius: Float = 0f,\n)\n\nenum class BackgroundType {\n    None, Image, Color\n}\n\nenum class LayerSnapshotType {\n    Text, Image, Sticker, Shape\n}\n\nenum class FontSnapshotType {\n    File, Resource\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/project/ProjectFileLoadResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.project\n\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProjectResult\n\ninternal sealed interface ProjectFileLoadResult {\n    data class Success(\n        val projectFile: MarkupProjectFile\n    ) : ProjectFileLoadResult\n\n    data class Error(\n        val error: MarkupProjectResult.Error\n    ) : ProjectFileLoadResult\n}"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/utils/LayersRenderer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.utils\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Paint\nimport android.graphics.Path\nimport android.graphics.RectF\nimport android.text.Layout\nimport android.text.StaticLayout\nimport android.text.TextPaint\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.withSave\nimport coil3.ImageLoader\nimport coil3.request.ImageRequest\nimport coil3.request.allowHardware\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.static\nimport com.t8rin.imagetoolbox.core.data.image.utils.toPaint\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayer\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.math.absoluteValue\nimport kotlin.math.ceil\nimport kotlin.math.min\nimport kotlin.math.roundToInt\n\ninternal class LayersRenderer @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageLoader: ImageLoader,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder {\n\n    suspend fun render(\n        backgroundImage: Bitmap,\n        layers: List<MarkupLayer>\n    ): Bitmap = withContext(defaultDispatcher) {\n        val resultBitmap = backgroundImage.copy(Bitmap.Config.ARGB_8888, true)\n\n        val visibleLayers = layers.filter { it.position.isVisible }\n        if (visibleLayers.isEmpty()) return@withContext resultBitmap\n\n        val targetWidth = resultBitmap.width.toFloat()\n        val targetHeight = resultBitmap.height.toFloat()\n        val authorSize = visibleLayers\n            .asSequence()\n            .map { it.position.currentCanvasSize }\n            .firstOrNull { it.width > 0 && it.height > 0 }\n\n        val authorWidth = (authorSize?.width ?: resultBitmap.width).toFloat().coerceAtLeast(1f)\n        val authorHeight = (authorSize?.height ?: resultBitmap.height).toFloat().coerceAtLeast(1f)\n        val ratio = min(targetWidth / authorWidth, targetHeight / authorHeight)\n        val canvasOffsetX = (targetWidth - authorWidth * ratio) / 2f\n        val canvasOffsetY = (targetHeight - authorHeight * ratio) / 2f\n        val textFullSize = min(authorWidth, authorHeight).roundToInt().coerceAtLeast(1)\n        val shapeContentInsetPx = context.resources.displayMetrics.density * 4f\n\n        val pictureCache = mutableMapOf<Any, Bitmap?>()\n        val textCache = mutableMapOf<TextLayerCacheKey, TextLayerRenderData>()\n        val shapeCache = mutableMapOf<ShapeLayerCacheKey, ShapeLayerCacheValue>()\n\n        resultBitmap.applyCanvas {\n            withSave {\n                translate(canvasOffsetX, canvasOffsetY)\n                scale(ratio, ratio)\n\n                layers.forEach { layer ->\n                    if (!layer.position.isVisible) return@forEach\n\n                    val centerX = authorWidth / 2f + layer.position.offsetX\n                    val centerY = authorHeight / 2f + layer.position.offsetY\n\n                    when (val type = layer.type) {\n                        is LayerType.Picture -> {\n                            val contentBitmap = pictureCache.getOrPut(type.imageData) {\n                                loadPictureBitmap(\n                                    imageData = type.imageData\n                                )\n                            } ?: return@forEach\n\n                            val pictureData = resolvePictureRenderData(\n                                bitmap = contentBitmap,\n                                shadow = type.shadow,\n                                contentSize = layer.contentSize,\n                                maxWidth = authorWidth / 2f,\n                                maxHeight = authorHeight / 2f\n                            ) ?: return@forEach\n                            val shadowRenderData = buildPictureShadowRenderData(\n                                sourceBitmap = contentBitmap,\n                                shadow = type.shadow,\n                                targetWidth = pictureData.contentWidth,\n                                targetHeight = pictureData.contentHeight,\n                                cornerRadiusPercent = layer.cornerRadiusPercent,\n                                rasterScale = resolveShadowRasterScale(\n                                    layerScale = layer.position.scale\n                                )\n                            )\n\n                            drawPictureLayer(\n                                bitmap = contentBitmap,\n                                data = pictureData,\n                                shadowRenderData = shadowRenderData,\n                                centerX = centerX,\n                                centerY = centerY,\n                                rotation = layer.position.rotation,\n                                scale = layer.position.scale,\n                                isFlippedHorizontally = layer.position.isFlippedHorizontally,\n                                isFlippedVertically = layer.position.isFlippedVertically,\n                                cornerRadiusPercent = layer.cornerRadiusPercent,\n                                blendingMode = layer.blendingMode,\n                                alpha = (layer.position.alpha * 255).roundToInt().coerceIn(0, 255)\n                            )\n                        }\n\n                        is LayerType.Text -> {\n                            val shadowRasterScale = resolveShadowRasterScale(\n                                layerScale = layer.position.scale\n                            )\n                            val textData = textCache.getOrPut(\n                                TextLayerCacheKey(\n                                    type = type,\n                                    textFullSize = textFullSize,\n                                    contentSize = layer.contentSize,\n                                    maxLines = layer.visibleLineCount,\n                                    shadowRasterScaleKey = (shadowRasterScale * 100f).roundToInt()\n                                )\n                            ) {\n                                buildTextLayerRenderData(\n                                    type = type,\n                                    textFullSize = textFullSize,\n                                    contentSize = layer.contentSize,\n                                    fallbackMaxTextBoxWidth = authorWidth,\n                                    maxLines = layer.visibleLineCount,\n                                    shadowRasterScale = shadowRasterScale\n                                )\n                            }\n                            drawTextLayer(\n                                data = textData,\n                                centerX = centerX,\n                                centerY = centerY,\n                                rotation = layer.position.rotation,\n                                scale = layer.position.scale,\n                                isFlippedHorizontally = layer.position.isFlippedHorizontally,\n                                isFlippedVertically = layer.position.isFlippedVertically,\n                                cornerRadiusPercent = layer.cornerRadiusPercent,\n                                blendingMode = layer.blendingMode,\n                                alpha = (layer.position.alpha * 255).roundToInt().coerceIn(0, 255)\n                            )\n                        }\n\n                        is LayerType.Shape -> {\n                            val shadowRasterScale = resolveShadowRasterScale(\n                                layerScale = layer.position.scale\n                            )\n                            val shapeValue = shapeCache.getOrPut(\n                                ShapeLayerCacheKey(\n                                    type = type,\n                                    referenceSize = textFullSize,\n                                    contentSize = layer.contentSize,\n                                    shadowRasterScaleKey = (shadowRasterScale * 100f).roundToInt(),\n                                    contentInsetKey = shapeContentInsetPx.roundToInt()\n                                )\n                            ) {\n                                val data = resolveShapeLayerRenderData(\n                                    type = type,\n                                    referenceSize = textFullSize.toFloat(),\n                                    contentSize = layer.contentSize,\n                                    maxWidth = authorWidth / 2f,\n                                    maxHeight = authorHeight / 2f,\n                                    contentInsetPx = shapeContentInsetPx\n                                )\n                                ShapeLayerCacheValue(\n                                    data = data,\n                                    shadowRenderData = buildShapeShadowRenderData(\n                                        type = type,\n                                        data = data,\n                                        rasterScale = shadowRasterScale\n                                    )\n                                )\n                            }\n                            drawShapeLayerItem(\n                                type = type,\n                                data = shapeValue.data,\n                                shadowRenderData = shapeValue.shadowRenderData,\n                                centerX = centerX,\n                                centerY = centerY,\n                                rotation = layer.position.rotation,\n                                scale = layer.position.scale,\n                                isFlippedHorizontally = layer.position.isFlippedHorizontally,\n                                isFlippedVertically = layer.position.isFlippedVertically,\n                                blendingMode = layer.blendingMode,\n                                alpha = (layer.position.alpha * 255).roundToInt().coerceIn(0, 255)\n                            )\n                        }\n                    }\n                }\n            }\n        }\n\n        resultBitmap\n    }\n\n    private suspend fun loadPictureBitmap(\n        imageData: Any\n    ): Bitmap? = imageLoader.execute(\n            ImageRequest.Builder(appContext)\n                .data(imageData)\n                .static()\n                .allowHardware(false)\n                .size(1600)\n                .build()\n    ).image?.toBitmap()\n\n    private fun resolvePictureRenderData(\n        bitmap: Bitmap,\n        shadow: com.t8rin.imagetoolbox.feature.markup_layers.domain.DropShadow?,\n        contentSize: IntegerSize,\n        maxWidth: Float,\n        maxHeight: Float\n    ): PictureLayerRenderData? {\n        val shadowPadding = calculateShadowPadding(shadow)\n        val horizontalShadowPadding = shadowPadding.leftPx + shadowPadding.rightPx\n        val verticalShadowPadding = shadowPadding.topPx + shadowPadding.bottomPx\n\n        contentSize.takeIf { it.width > 0 && it.height > 0 }?.let {\n            val width = it.width.toFloat().coerceAtLeast(horizontalShadowPadding + 1f)\n            val height = it.height.toFloat().coerceAtLeast(verticalShadowPadding + 1f)\n            return PictureLayerRenderData(\n                width = width,\n                height = height,\n                contentLeft = shadowPadding.leftPx,\n                contentTop = shadowPadding.topPx,\n                contentWidth = (width - horizontalShadowPadding).coerceAtLeast(1f),\n                contentHeight = (height - verticalShadowPadding).coerceAtLeast(1f)\n            )\n        }\n\n        val width = bitmap.width.takeIf { it > 0 } ?: return null\n        val height = bitmap.height.takeIf { it > 0 } ?: return null\n        val availableContentWidth = (maxWidth - horizontalShadowPadding).coerceAtLeast(1f)\n        val availableContentHeight = (maxHeight - verticalShadowPadding).coerceAtLeast(1f)\n        val fitScale = min(\n            1f,\n            min(availableContentWidth / width, availableContentHeight / height)\n        )\n        val contentWidth = (width * fitScale).roundToInt().coerceAtLeast(1).toFloat()\n        val contentHeight = (height * fitScale).roundToInt().coerceAtLeast(1).toFloat()\n\n        return PictureLayerRenderData(\n            width = contentWidth + horizontalShadowPadding,\n            height = contentHeight + verticalShadowPadding,\n            contentLeft = shadowPadding.leftPx,\n            contentTop = shadowPadding.topPx,\n            contentWidth = contentWidth,\n            contentHeight = contentHeight\n        )\n    }\n\n    private fun buildTextLayerRenderData(\n        type: LayerType.Text,\n        textFullSize: Int,\n        contentSize: IntegerSize,\n        fallbackMaxTextBoxWidth: Float,\n        maxLines: Int?,\n        shadowRasterScale: Float\n    ): TextLayerRenderData {\n        val textMetrics = context.calculateTextLayerMetrics(\n            type = type,\n            textFullSize = textFullSize\n        )\n        val outlineWidth = type.outline?.width ?: 0f\n        val layoutText = type.text.ifEmpty { \" \" }\n        val resolvedContentSize = contentSize.takeIf { it.width > 0 && it.height > 0 }\n        val availableLayoutWidth = (\n                (resolvedContentSize?.width?.toFloat() ?: fallbackMaxTextBoxWidth) -\n                        textMetrics.padding.leftPx -\n                        textMetrics.padding.rightPx -\n                        outlineWidth * 2f\n                ).roundToInt().coerceAtLeast(1)\n\n        val fillPaint = TextPaint(Paint.ANTI_ALIAS_FLAG or Paint.SUBPIXEL_TEXT_FLAG).apply {\n            color = type.color\n            textSize = textMetrics.fontSizePx\n            hinting = Paint.HINTING_ON\n            isLinearText = true\n            isUnderlineText = type.decorations.any { it == LayerType.Text.Decoration.Underline }\n            isStrikeThruText = type.decorations.any { it == LayerType.Text.Decoration.LineThrough }\n            typeface = textMetrics.typeface\n            textScaleX = type.geometricTransform?.scaleX?.coerceAtLeast(0.01f) ?: 1f\n            textSkewX = type.geometricTransform?.skewX ?: 0f\n        }\n\n        val desiredLayoutWidth = maxLineWidth(\n            text = layoutText,\n            paint = fillPaint\n        ).coerceAtLeast(1)\n        val layoutWidth = resolvedContentSize?.let { availableLayoutWidth }\n            ?: min(desiredLayoutWidth, availableLayoutWidth)\n        val alignment = when (type.alignment) {\n            LayerType.Text.Alignment.Start -> Layout.Alignment.ALIGN_NORMAL\n            LayerType.Text.Alignment.Center -> Layout.Alignment.ALIGN_CENTER\n            LayerType.Text.Alignment.End -> Layout.Alignment.ALIGN_OPPOSITE\n        }\n\n        val fillLayout = createTextStaticLayout(\n            text = layoutText,\n            paint = fillPaint,\n            width = layoutWidth,\n            alignment = alignment,\n            lineHeightPx = textMetrics.lineHeightPx,\n            maxLines = maxLines\n        )\n        val shadowRenderData = buildTextShadowRenderData(\n            type = type,\n            textMetrics = textMetrics,\n            layoutWidth = layoutWidth,\n            maxLines = maxLines,\n            rasterScale = shadowRasterScale\n        )\n\n        val bitmapWidth = resolvedContentSize?.width?.coerceAtLeast(1) ?: ceil(\n            layoutWidth +\n                    textMetrics.padding.leftPx +\n                    textMetrics.padding.rightPx +\n                    outlineWidth * 2f\n        ).toInt().coerceAtLeast(1)\n        val bitmapHeight = resolvedContentSize?.height?.coerceAtLeast(1) ?: ceil(\n            fillLayout.height +\n                    textMetrics.padding.topPx +\n                    textMetrics.padding.bottomPx +\n                    outlineWidth * 2f\n        ).toInt().coerceAtLeast(1)\n\n        val outlineLayout = type.outline?.takeIf { it.width > 0f }?.let { outline ->\n            val outlinePaint = TextPaint(fillPaint).apply {\n                color = outline.color\n                style = Paint.Style.STROKE\n                strokeWidth = outline.width\n                strokeJoin = Paint.Join.ROUND\n                strokeCap = Paint.Cap.ROUND\n                clearShadowLayer()\n            }\n            createTextStaticLayout(\n                text = layoutText,\n                paint = outlinePaint,\n                width = layoutWidth,\n                alignment = alignment,\n                lineHeightPx = textMetrics.lineHeightPx,\n                maxLines = maxLines\n            )\n        }\n\n        return TextLayerRenderData(\n            width = bitmapWidth.toFloat(),\n            height = bitmapHeight.toFloat(),\n            backgroundPaint = type.backgroundColor.takeIf { it != 0 }?.let { backgroundColor ->\n                Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                    color = backgroundColor\n                }\n            },\n            textLeft = outlineWidth + textMetrics.padding.leftPx,\n            textTop = outlineWidth + textMetrics.padding.topPx,\n            shadowRenderData = shadowRenderData,\n            outlineLayout = outlineLayout,\n            fillLayout = fillLayout\n        )\n    }\n\n    private fun Canvas.drawTextLayer(\n        data: TextLayerRenderData,\n        centerX: Float,\n        centerY: Float,\n        rotation: Float,\n        scale: Float,\n        isFlippedHorizontally: Boolean,\n        isFlippedVertically: Boolean,\n        cornerRadiusPercent: Int,\n        blendingMode: BlendingMode,\n        alpha: Int\n    ) {\n        withSave {\n            translate(centerX, centerY)\n            rotate(rotation)\n            scale(\n                scale * if (isFlippedHorizontally) -1f else 1f,\n                scale * if (isFlippedVertically) -1f else 1f\n            )\n            val destination = RectF(\n                -data.width / 2f,\n                -data.height / 2f,\n                data.width / 2f,\n                data.height / 2f\n            )\n            clipToRoundedBounds(\n                bounds = destination,\n                cornerRadiusPx = cornerRadiusPx(\n                    cornerRadiusPercent = cornerRadiusPercent,\n                    width = data.width,\n                    height = data.height\n                )\n            )\n\n            if (blendingMode == BlendingMode.SrcOver && alpha >= 255) {\n                drawTextLayerContent(\n                    data = data,\n                    bounds = destination\n                )\n            } else {\n                drawBitmap(\n                    renderTextLayerBitmap(\n                        data = data,\n                        cornerRadiusPercent = cornerRadiusPercent\n                    ),\n                    null,\n                    destination,\n                    blendingMode.toPaint().apply {\n                        this.alpha = alpha\n                        isFilterBitmap = true\n                    }\n                )\n            }\n        }\n    }\n\n    private fun Canvas.drawTextLayerContent(\n        data: TextLayerRenderData,\n        bounds: RectF\n    ) {\n        withSave {\n            translate(bounds.left, bounds.top)\n\n            data.backgroundPaint?.let {\n                drawRect(\n                    0f,\n                    0f,\n                    data.width,\n                    data.height,\n                    it\n                )\n            }\n\n            data.shadowRenderData?.let { shadow ->\n                withSave {\n                    val rasterScale = shadow.rasterScale.coerceAtLeast(1f)\n                    scale(1f / rasterScale, 1f / rasterScale)\n                    drawBitmap(\n                        shadow.bitmap,\n                        data.textLeft * rasterScale + shadow.left,\n                        data.textTop * rasterScale + shadow.top,\n                        Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                            isFilterBitmap = true\n                        }\n                    )\n                }\n            }\n\n            withSave {\n                translate(data.textLeft, data.textTop)\n                data.outlineLayout?.draw(this@drawTextLayerContent)\n                data.fillLayout.draw(this@drawTextLayerContent)\n            }\n        }\n    }\n\n    private fun Canvas.drawPictureLayer(\n        bitmap: Bitmap,\n        data: PictureLayerRenderData,\n        shadowRenderData: PictureShadowRenderData?,\n        centerX: Float,\n        centerY: Float,\n        rotation: Float,\n        scale: Float,\n        isFlippedHorizontally: Boolean,\n        isFlippedVertically: Boolean,\n        cornerRadiusPercent: Int,\n        blendingMode: BlendingMode,\n        alpha: Int\n    ) {\n        withSave {\n            translate(centerX, centerY)\n            rotate(rotation)\n            scale(\n                scale * if (isFlippedHorizontally) -1f else 1f,\n                scale * if (isFlippedVertically) -1f else 1f\n            )\n\n            val destination = RectF(\n                -data.width / 2f,\n                -data.height / 2f,\n                data.width / 2f,\n                data.height / 2f\n            )\n\n            if (blendingMode == BlendingMode.SrcOver && alpha >= 255) {\n                drawPictureLayerContent(\n                    bitmap = bitmap,\n                    data = data,\n                    bounds = destination,\n                    shadowRenderData = shadowRenderData,\n                    cornerRadiusPercent = cornerRadiusPercent\n                )\n            } else {\n                drawBitmap(\n                    renderPictureLayerBitmap(\n                        bitmap = bitmap,\n                        data = data,\n                        shadowRenderData = shadowRenderData,\n                        cornerRadiusPercent = cornerRadiusPercent\n                    ),\n                    null,\n                    destination,\n                    blendingMode.toPaint().apply {\n                        this.alpha = alpha\n                        isFilterBitmap = true\n                    }\n                )\n            }\n        }\n    }\n\n    private fun Canvas.drawPictureLayerContent(\n        bitmap: Bitmap,\n        data: PictureLayerRenderData,\n        bounds: RectF,\n        shadowRenderData: PictureShadowRenderData?,\n        cornerRadiusPercent: Int\n    ) {\n        withSave {\n            translate(bounds.left, bounds.top)\n\n            shadowRenderData?.let { shadow ->\n                withSave {\n                    val rasterScale = shadow.rasterScale.coerceAtLeast(1f)\n                    scale(1f / rasterScale, 1f / rasterScale)\n                    drawBitmap(\n                        shadow.bitmap,\n                        data.contentLeft * rasterScale + shadow.left,\n                        data.contentTop * rasterScale + shadow.top,\n                        Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                            isFilterBitmap = true\n                        }\n                    )\n                }\n            }\n\n            val imageBounds = RectF(\n                data.contentLeft,\n                data.contentTop,\n                data.contentLeft + data.contentWidth,\n                data.contentTop + data.contentHeight\n            )\n            withSave {\n                clipToRoundedBounds(\n                    bounds = imageBounds,\n                    cornerRadiusPx = cornerRadiusPx(\n                        cornerRadiusPercent = cornerRadiusPercent,\n                        width = imageBounds.width(),\n                        height = imageBounds.height()\n                    )\n                )\n                drawBitmap(\n                    bitmap,\n                    null,\n                    imageBounds,\n                    Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                        isFilterBitmap = true\n                    }\n                )\n            }\n        }\n    }\n\n    private fun Canvas.drawShapeLayerItem(\n        type: LayerType.Shape,\n        data: ShapeLayerRenderData,\n        shadowRenderData: PictureShadowRenderData?,\n        centerX: Float,\n        centerY: Float,\n        rotation: Float,\n        scale: Float,\n        isFlippedHorizontally: Boolean,\n        isFlippedVertically: Boolean,\n        blendingMode: BlendingMode,\n        alpha: Int\n    ) {\n        withSave {\n            translate(centerX, centerY)\n            rotate(rotation)\n            scale(\n                scale * if (isFlippedHorizontally) -1f else 1f,\n                scale * if (isFlippedVertically) -1f else 1f\n            )\n\n            val destination = RectF(\n                -data.width / 2f,\n                -data.height / 2f,\n                data.width / 2f,\n                data.height / 2f\n            )\n\n            if (blendingMode == BlendingMode.SrcOver && alpha >= 255) {\n                drawShapeLayerContent(\n                    type = type,\n                    data = data,\n                    bounds = destination,\n                    shadowRenderData = shadowRenderData\n                )\n            } else {\n                drawBitmap(\n                    renderShapeLayerBitmap(\n                        type = type,\n                        data = data,\n                        shadowRenderData = shadowRenderData\n                    ),\n                    null,\n                    destination,\n                    blendingMode.toPaint().apply {\n                        this.alpha = alpha\n                        isFilterBitmap = true\n                    }\n                )\n            }\n        }\n    }\n\n    private fun Canvas.drawShapeLayerContent(\n        type: LayerType.Shape,\n        data: ShapeLayerRenderData,\n        bounds: RectF,\n        shadowRenderData: PictureShadowRenderData?\n    ) {\n        withSave {\n            translate(bounds.left, bounds.top)\n\n            shadowRenderData?.let { shadow ->\n                withSave {\n                    val rasterScale = shadow.rasterScale.coerceAtLeast(1f)\n                    scale(1f / rasterScale, 1f / rasterScale)\n                    drawBitmap(\n                        shadow.bitmap,\n                        data.contentLeft * rasterScale + shadow.left,\n                        data.contentTop * rasterScale + shadow.top,\n                        Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                            isFilterBitmap = true\n                        }\n                    )\n                }\n            }\n\n            withSave {\n                translate(data.contentLeft, data.contentTop)\n                drawShapeLayer(\n                    type = type,\n                    data = data.copy(\n                        width = data.contentWidth,\n                        height = data.contentHeight,\n                        contentLeft = 0f,\n                        contentTop = 0f\n                    )\n                )\n            }\n        }\n    }\n\n    private fun renderTextLayerBitmap(\n        data: TextLayerRenderData,\n        cornerRadiusPercent: Int\n    ): Bitmap = createLayerBitmap(\n        width = data.width,\n        height = data.height\n    ) { canvas ->\n        val bounds = RectF(\n            0f,\n            0f,\n            data.width,\n            data.height\n        )\n        canvas.withSave {\n            clipToRoundedBounds(\n                bounds = bounds,\n                cornerRadiusPx = cornerRadiusPx(\n                    cornerRadiusPercent = cornerRadiusPercent,\n                    width = data.width,\n                    height = data.height\n                )\n            )\n            drawTextLayerContent(\n                data = data,\n                bounds = bounds\n            )\n        }\n    }\n\n    private fun renderPictureLayerBitmap(\n        bitmap: Bitmap,\n        data: PictureLayerRenderData,\n        shadowRenderData: PictureShadowRenderData?,\n        cornerRadiusPercent: Int\n    ): Bitmap = createLayerBitmap(\n        width = data.width,\n        height = data.height\n    ) { canvas ->\n        canvas.drawPictureLayerContent(\n            bitmap = bitmap,\n            data = data,\n            bounds = RectF(\n                0f,\n                0f,\n                data.width,\n                data.height\n            ),\n            shadowRenderData = shadowRenderData,\n            cornerRadiusPercent = cornerRadiusPercent\n        )\n    }\n\n    private fun renderShapeLayerBitmap(\n        type: LayerType.Shape,\n        data: ShapeLayerRenderData,\n        shadowRenderData: PictureShadowRenderData?\n    ): Bitmap = createLayerBitmap(\n        width = data.width,\n        height = data.height\n    ) { canvas ->\n        canvas.drawShapeLayerContent(\n            type = type,\n            data = data,\n            bounds = RectF(\n                0f,\n                0f,\n                data.width,\n                data.height\n            ),\n            shadowRenderData = shadowRenderData\n        )\n    }\n\n    private inline fun createLayerBitmap(\n        width: Float,\n        height: Float,\n        draw: (Canvas) -> Unit\n    ): Bitmap = createBitmap(\n        ceil(width.toDouble()).toInt().coerceAtLeast(1),\n        ceil(height.toDouble()).toInt().coerceAtLeast(1)\n    ).apply {\n        draw(Canvas(this))\n    }\n\n    private fun resolveShadowRasterScale(\n        layerScale: Float\n    ): Float = layerScale\n        .absoluteValue\n        .coerceAtLeast(1f)\n        .coerceAtMost(MAX_SHADOW_RASTER_SCALE)\n\n    private companion object {\n        const val MAX_SHADOW_RASTER_SCALE = 4f\n    }\n\n    private fun maxLineWidth(\n        text: String,\n        paint: TextPaint\n    ): Int = text\n        .split('\\n')\n        .maxOfOrNull { line ->\n            ceil(Layout.getDesiredWidth(line.ifEmpty { \" \" }, paint).toDouble()).toInt()\n        }\n        ?.coerceAtLeast(1)\n        ?: 1\n\n    private fun cornerRadiusPx(\n        cornerRadiusPercent: Int,\n        width: Float,\n        height: Float\n    ): Float {\n        val normalizedPercent = cornerRadiusPercent.coerceIn(0, 50)\n        if (normalizedPercent == 0) return 0f\n\n        return min(width, height) * (normalizedPercent / 100f)\n    }\n\n    private fun Canvas.clipToRoundedBounds(\n        bounds: RectF,\n        cornerRadiusPx: Float\n    ) {\n        if (cornerRadiusPx <= 0f) return\n\n        clipPath(\n            Path().apply {\n                addRoundRect(\n                    bounds,\n                    cornerRadiusPx,\n                    cornerRadiusPx,\n                    Path.Direction.CW\n                )\n            }\n        )\n    }\n}\n\nprivate data class TextLayerRenderData(\n    val width: Float,\n    val height: Float,\n    val backgroundPaint: Paint?,\n    val textLeft: Float,\n    val textTop: Float,\n    val shadowRenderData: TextShadowRenderData?,\n    val outlineLayout: StaticLayout?,\n    val fillLayout: StaticLayout\n)\n\nprivate data class TextLayerCacheKey(\n    val type: LayerType.Text,\n    val textFullSize: Int,\n    val contentSize: IntegerSize,\n    val maxLines: Int?,\n    val shadowRasterScaleKey: Int\n)\n\nprivate data class PictureLayerRenderData(\n    val width: Float,\n    val height: Float,\n    val contentLeft: Float,\n    val contentTop: Float,\n    val contentWidth: Float,\n    val contentHeight: Float\n)\n\nprivate data class ShapeLayerCacheKey(\n    val type: LayerType.Shape,\n    val referenceSize: Int,\n    val contentSize: IntegerSize,\n    val shadowRasterScaleKey: Int,\n    val contentInsetKey: Int\n)\n\nprivate data class ShapeLayerCacheValue(\n    val data: ShapeLayerRenderData,\n    val shadowRenderData: PictureShadowRenderData?\n)\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/utils/PictureLayerShadowRenderer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.BlurMaskFilter\nimport android.graphics.Paint\nimport android.graphics.Path\nimport android.graphics.PorterDuff\nimport android.graphics.RectF\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.withSave\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.DropShadow\nimport kotlin.math.min\nimport kotlin.math.roundToInt\n\ninternal data class PictureShadowRenderData(\n    val bitmap: Bitmap,\n    val left: Float,\n    val top: Float,\n    val rasterScale: Float\n)\n\ninternal fun buildPictureShadowRenderData(\n    sourceBitmap: Bitmap,\n    shadow: DropShadow?,\n    targetWidth: Float,\n    targetHeight: Float,\n    cornerRadiusPercent: Int = 0,\n    rasterScale: Float = 1f\n): PictureShadowRenderData? {\n    shadow ?: return null\n\n    val safeRasterScale = rasterScale.coerceAtLeast(1f)\n    val safeTargetWidth = (targetWidth\n        .coerceAtLeast(1f)\n            * safeRasterScale)\n        .roundToInt()\n        .coerceAtLeast(1)\n    val safeTargetHeight = (targetHeight\n        .coerceAtLeast(1f)\n            * safeRasterScale)\n        .roundToInt()\n        .coerceAtLeast(1)\n    val targetRect = RectF(0f, 0f, safeTargetWidth.toFloat(), safeTargetHeight.toFloat())\n    val cornerRadiusPx = calculatePictureCornerRadiusPx(\n        cornerRadiusPercent = cornerRadiusPercent,\n        width = targetRect.width(),\n        height = targetRect.height()\n    )\n\n    val contentBitmap = createBitmap(\n        width = safeTargetWidth,\n        height = safeTargetHeight\n    ).applyCanvas {\n        withSave {\n            if (cornerRadiusPx > 0f) {\n                clipPath(\n                    Path().apply {\n                        addRoundRect(\n                            targetRect,\n                            cornerRadiusPx,\n                            cornerRadiusPx,\n                            Path.Direction.CW\n                        )\n                    }\n                )\n            }\n            drawBitmap(\n                sourceBitmap,\n                null,\n                targetRect,\n                Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                    isFilterBitmap = true\n                }\n            )\n        }\n    }\n\n    val blurRadius = shadow.blurRadius.coerceAtLeast(0f) * safeRasterScale\n    val offset = IntArray(2)\n    val alphaBitmap = contentBitmap.extractAlpha(\n        Paint(Paint.ANTI_ALIAS_FLAG).apply {\n            if (blurRadius > 0f) {\n                maskFilter = BlurMaskFilter(\n                    blurRadius,\n                    BlurMaskFilter.Blur.NORMAL\n                )\n            }\n        },\n        offset\n    )\n    val tintedBitmap = createBitmap(\n        width = alphaBitmap.width.coerceAtLeast(1),\n        height = alphaBitmap.height.coerceAtLeast(1)\n    ).applyCanvas {\n        drawBitmap(\n            alphaBitmap,\n            0f,\n            0f,\n            Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                isFilterBitmap = true\n            }\n        )\n        drawColor(shadow.color, PorterDuff.Mode.SRC_IN)\n    }\n\n    contentBitmap.recycle()\n    alphaBitmap.recycle()\n\n    return PictureShadowRenderData(\n        bitmap = tintedBitmap,\n        left = offset[0].toFloat() + shadow.offsetX * safeRasterScale,\n        top = offset[1].toFloat() + shadow.offsetY * safeRasterScale,\n        rasterScale = safeRasterScale\n    )\n}\n\nprivate fun calculatePictureCornerRadiusPx(\n    cornerRadiusPercent: Int,\n    width: Float,\n    height: Float\n): Float {\n    val normalizedPercent = cornerRadiusPercent.coerceIn(0, 50)\n    if (normalizedPercent == 0) return 0f\n\n    return min(width, height) * (normalizedPercent / 100f)\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/utils/ShapeLayerRenderer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Matrix\nimport android.graphics.Paint\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.RoundRect\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asComposePath\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Fill\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ShapeMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.arrowAngle\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.arrowSizeScale\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.cornerRadius\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.innerRadiusRatio\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.isFilledShapeMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.isOutlinedShapeMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.isRegular\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.outlinedFillColorInt\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.rotationDegrees\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.usesStrokeWidth\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.vertices\nimport kotlin.math.abs\nimport kotlin.math.cos\nimport kotlin.math.max\nimport kotlin.math.min\nimport kotlin.math.roundToInt\nimport kotlin.math.sin\n\ninternal data class ShapeLayerRenderData(\n    val width: Float,\n    val height: Float,\n    val contentLeft: Float,\n    val contentTop: Float,\n    val contentWidth: Float,\n    val contentHeight: Float,\n    val shapeWidth: Float,\n    val shapeHeight: Float,\n    val shapeTranslateX: Float,\n    val shapeTranslateY: Float\n)\n\ninternal fun resolveShapeLayerRenderData(\n    type: LayerType.Shape,\n    referenceSize: Float,\n    contentSize: IntegerSize = IntegerSize.Zero,\n    maxWidth: Float = Float.POSITIVE_INFINITY,\n    maxHeight: Float = Float.POSITIVE_INFINITY,\n    contentInsetPx: Float = 0f\n): ShapeLayerRenderData {\n    val shadowPadding = calculateShadowPadding(type.shadow)\n    val horizontalShadowPadding = shadowPadding.leftPx + shadowPadding.rightPx\n    val verticalShadowPadding = shadowPadding.topPx + shadowPadding.bottomPx\n    val desiredShapeWidth = (referenceSize * type.widthRatio).coerceAtLeast(1f)\n    val desiredShapeHeight = (referenceSize * type.heightRatio).coerceAtLeast(1f)\n    val constrainedSize = contentSize.takeIf { it.width > 0 && it.height > 0 }\n    val availableContentWidth = constrainedSize?.width?.toFloat()?.let {\n        (it - horizontalShadowPadding).coerceAtLeast(1f)\n    } ?: maxWidth\n        .takeIf(Float::isFinite)\n        ?.let { (it - horizontalShadowPadding).coerceAtLeast(1f) }\n    ?: Float.POSITIVE_INFINITY\n    val availableContentHeight = constrainedSize?.height?.toFloat()?.let {\n        (it - verticalShadowPadding).coerceAtLeast(1f)\n    } ?: maxHeight\n        .takeIf(Float::isFinite)\n        ?.let { (it - verticalShadowPadding).coerceAtLeast(1f) }\n    ?: Float.POSITIVE_INFINITY\n    val desiredPlacement = resolveShapePlacement(\n        type = type,\n        shapeWidth = desiredShapeWidth,\n        shapeHeight = desiredShapeHeight,\n        contentInsetPx = contentInsetPx\n    )\n    val fitScale = min(\n        1f,\n        min(\n            availableContentWidth / desiredPlacement.contentWidth,\n            availableContentHeight / desiredPlacement.contentHeight\n        )\n    ).coerceAtLeast(0.01f)\n    val shapeWidth = desiredShapeWidth * fitScale\n    val shapeHeight = desiredShapeHeight * fitScale\n    val placement = if (fitScale == 1f) desiredPlacement else resolveShapePlacement(\n        type = type,\n        shapeWidth = shapeWidth,\n        shapeHeight = shapeHeight,\n        contentInsetPx = contentInsetPx\n    )\n    val resolvedContentWidth = constrainedSize?.let {\n        (it.width.toFloat() - horizontalShadowPadding).coerceAtLeast(1f)\n    } ?: placement.contentWidth\n    val resolvedContentHeight = constrainedSize?.let {\n        (it.height.toFloat() - verticalShadowPadding).coerceAtLeast(1f)\n    } ?: placement.contentHeight\n    val extraContentLeft = ((resolvedContentWidth - placement.contentWidth) / 2f).coerceAtLeast(0f)\n    val extraContentTop = ((resolvedContentHeight - placement.contentHeight) / 2f).coerceAtLeast(0f)\n    val totalWidth = constrainedSize?.width?.toFloat()?.coerceAtLeast(horizontalShadowPadding + 1f)\n        ?: (placement.contentWidth + horizontalShadowPadding)\n    val totalHeight = constrainedSize?.height?.toFloat()?.coerceAtLeast(verticalShadowPadding + 1f)\n        ?: (placement.contentHeight + verticalShadowPadding)\n\n    return ShapeLayerRenderData(\n        width = totalWidth,\n        height = totalHeight,\n        contentLeft = shadowPadding.leftPx,\n        contentTop = shadowPadding.topPx,\n        contentWidth = resolvedContentWidth,\n        contentHeight = resolvedContentHeight,\n        shapeWidth = shapeWidth,\n        shapeHeight = shapeHeight,\n        shapeTranslateX = placement.shapeTranslateX + extraContentLeft,\n        shapeTranslateY = placement.shapeTranslateY + extraContentTop\n    )\n}\n\ninternal fun buildShapeShadowRenderData(\n    type: LayerType.Shape,\n    data: ShapeLayerRenderData,\n    rasterScale: Float = 1f\n): PictureShadowRenderData? {\n    if (type.shadow == null) return null\n\n    val scaledData = data.scaleContent(rasterScale)\n    val scaledWidth = scaledData.contentWidth.roundToInt().coerceAtLeast(1)\n    val scaledHeight = scaledData.contentHeight.roundToInt().coerceAtLeast(1)\n    val bitmap = renderShapeBitmap(\n        type = type.copy(strokeWidth = type.strokeWidth * rasterScale),\n        data = scaledData,\n        width = scaledWidth,\n        height = scaledHeight\n    )\n\n    return buildPictureShadowRenderData(\n        sourceBitmap = bitmap,\n        shadow = type.shadow,\n        targetWidth = data.contentWidth,\n        targetHeight = data.contentHeight,\n        cornerRadiusPercent = 0,\n        rasterScale = rasterScale\n    )\n}\n\ninternal fun DrawScope.drawShapeLayer(\n    type: LayerType.Shape,\n    data: ShapeLayerRenderData\n) {\n    val path = buildPlacedShapePath(\n        type = type,\n        data = data\n    )\n\n    if (type.shapeMode.isFilledShapeMode()) {\n        drawPath(\n            path = path,\n            color = type.color.toColor(),\n            style = Fill\n        )\n        return\n    }\n\n    if (type.shapeMode.isOutlinedShapeMode()) {\n        type.shapeMode.outlinedFillColorInt()?.let {\n            drawPath(\n                path = path,\n                color = Color(it),\n                style = Fill\n            )\n        }\n    }\n\n    drawPath(\n        path = path,\n        color = type.color.toColor(),\n        style = Stroke(\n            width = type.strokeWidth.coerceAtLeast(1f),\n            cap = StrokeCap.Round,\n            join = StrokeJoin.Round\n        )\n    )\n}\n\ninternal fun Canvas.drawShapeLayer(\n    type: LayerType.Shape,\n    data: ShapeLayerRenderData\n) {\n    val path = buildPlacedShapePath(\n        type = type,\n        data = data\n    ).asAndroidPath()\n\n    if (type.shapeMode.isFilledShapeMode()) {\n        drawPath(\n            path,\n            Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                color = type.color\n                style = Paint.Style.FILL\n            }\n        )\n        return\n    }\n\n    if (type.shapeMode.isOutlinedShapeMode()) {\n        type.shapeMode.outlinedFillColorInt()?.let {\n            drawPath(\n                path,\n                Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                    color = it\n                    style = Paint.Style.FILL\n                }\n            )\n        }\n    }\n\n    drawPath(\n        path,\n        Paint(Paint.ANTI_ALIAS_FLAG).apply {\n            color = type.color\n            style = Paint.Style.STROKE\n            strokeWidth = type.strokeWidth.coerceAtLeast(1f)\n            strokeJoin = Paint.Join.ROUND\n            strokeCap = Paint.Cap.ROUND\n        }\n    )\n}\n\nprivate fun renderShapeBitmap(\n    type: LayerType.Shape,\n    data: ShapeLayerRenderData,\n    width: Int,\n    height: Int\n): Bitmap = createBitmap(\n    width = width.coerceAtLeast(1),\n    height = height.coerceAtLeast(1)\n).apply {\n    Canvas(this).drawShapeLayer(\n        type = type,\n        data = data\n    )\n}\n\nprivate data class ShapePlacement(\n    val contentWidth: Float,\n    val contentHeight: Float,\n    val shapeTranslateX: Float,\n    val shapeTranslateY: Float\n)\n\nprivate fun resolveShapePlacement(\n    type: LayerType.Shape,\n    shapeWidth: Float,\n    shapeHeight: Float,\n    contentInsetPx: Float\n): ShapePlacement {\n    val path = buildShapePath(\n        type = type,\n        width = shapeWidth,\n        height = shapeHeight\n    )\n    val bounds = path.getBounds()\n    val drawPadding = if (type.shapeMode.usesStrokeWidth()) {\n        type.strokeWidth.coerceAtLeast(1f) / 2f + 1f\n    } else {\n        1f\n    }\n    val visibleLeft = bounds.left - drawPadding\n    val visibleTop = bounds.top - drawPadding\n    val visibleRight = bounds.right + drawPadding\n    val visibleBottom = bounds.bottom + drawPadding\n\n    return ShapePlacement(\n        contentWidth = (visibleRight - visibleLeft + contentInsetPx * 2f).coerceAtLeast(1f),\n        contentHeight = (visibleBottom - visibleTop + contentInsetPx * 2f).coerceAtLeast(1f),\n        shapeTranslateX = -visibleLeft + contentInsetPx,\n        shapeTranslateY = -visibleTop + contentInsetPx\n    )\n}\n\nprivate fun buildPlacedShapePath(\n    type: LayerType.Shape,\n    data: ShapeLayerRenderData\n): Path {\n    val path = buildShapePath(\n        type = type,\n        width = data.shapeWidth,\n        height = data.shapeHeight\n    )\n    if (data.shapeTranslateX == 0f && data.shapeTranslateY == 0f) return path\n\n    val matrix = Matrix().apply {\n        setTranslate(data.shapeTranslateX, data.shapeTranslateY)\n    }\n    return path.asAndroidPath().apply { transform(matrix) }.asComposePath()\n}\n\nprivate fun buildShapePath(\n    type: LayerType.Shape,\n    width: Float,\n    height: Float\n): Path {\n    val strokeInset = if (type.shapeMode.usesStrokeWidth()) {\n        type.strokeWidth / 2f + 1f\n    } else {\n        1f\n    }\n    val left = strokeInset.coerceAtMost(width / 2f)\n    val top = strokeInset.coerceAtMost(height / 2f)\n    val right = max(left + 1f, width - strokeInset)\n    val bottom = max(top + 1f, height - strokeInset)\n\n    return when (val mode = type.shapeMode) {\n        is ShapeMode.Rect,\n        is ShapeMode.OutlinedRect -> {\n            buildRotatedRoundRectPath(\n                left = left,\n                top = top,\n                right = right,\n                bottom = bottom,\n                rotationDegrees = mode.rotationDegrees(),\n                cornerRadius = mode.cornerRadius()\n            )\n        }\n\n        ShapeMode.Oval,\n        is ShapeMode.OutlinedOval -> Path().apply {\n            addOval(Rect(left, top, right, bottom))\n        }\n\n        ShapeMode.Triangle,\n        is ShapeMode.OutlinedTriangle -> Path().apply {\n            moveTo((left + right) / 2f, top)\n            lineTo(right, bottom)\n            lineTo(left, bottom)\n            close()\n        }\n\n        is ShapeMode.Polygon,\n        is ShapeMode.OutlinedPolygon -> {\n            buildPolygonPath(\n                left = left,\n                top = top,\n                right = right,\n                bottom = bottom,\n                vertices = mode.vertices(),\n                rotationDegrees = mode.rotationDegrees(),\n                isRegular = mode.isRegular()\n            )\n        }\n\n        is ShapeMode.Star,\n        is ShapeMode.OutlinedStar -> {\n            buildStarPath(\n                left = left,\n                top = top,\n                right = right,\n                bottom = bottom,\n                vertices = mode.vertices(),\n                rotationDegrees = mode.rotationDegrees(),\n                innerRadiusRatio = mode.innerRadiusRatio(),\n                isRegular = mode.isRegular()\n            )\n        }\n\n        is ShapeMode.Arrow -> {\n            buildFilledArrowPath(\n                left = left,\n                top = top,\n                right = right,\n                bottom = bottom,\n                doubleHeaded = false,\n                sizeScale = mode.arrowSizeScale(),\n                angle = mode.arrowAngle()\n            )\n        }\n\n        is ShapeMode.DoubleArrow -> {\n            buildFilledArrowPath(\n                left = left,\n                top = top,\n                right = right,\n                bottom = bottom,\n                doubleHeaded = true,\n                sizeScale = mode.arrowSizeScale(),\n                angle = mode.arrowAngle()\n            )\n        }\n\n        ShapeMode.Line,\n        is ShapeMode.LineArrow,\n        is ShapeMode.DoubleLineArrow -> {\n            buildLineArrowPath(\n                left = left,\n                top = top,\n                right = right,\n                bottom = bottom,\n                drawStartArrow = mode is ShapeMode.DoubleLineArrow,\n                drawEndArrow = mode is ShapeMode.LineArrow || mode is ShapeMode.DoubleLineArrow,\n                sizeScale = mode.arrowSizeScale(),\n                angle = mode.arrowAngle()\n            )\n        }\n    }\n}\n\nprivate fun buildRotatedRoundRectPath(\n    left: Float,\n    top: Float,\n    right: Float,\n    bottom: Float,\n    rotationDegrees: Int,\n    cornerRadius: Float\n): Path {\n    val width = right - left\n    val height = bottom - top\n    val radius = min(width, height) * cornerRadius.coerceIn(0f, 0.5f)\n\n    val path = Path().apply {\n        addRoundRect(\n            RoundRect(\n                rect = Rect(left, top, right, bottom),\n                radiusX = radius,\n                radiusY = radius\n            )\n        )\n    }\n    if (rotationDegrees == 0) return path\n\n    val matrix = Matrix().apply {\n        setRotate(\n            rotationDegrees.toFloat(),\n            (left + right) / 2f,\n            (top + bottom) / 2f\n        )\n    }\n    return path.asAndroidPath().apply { transform(matrix) }.asComposePath()\n}\n\nprivate fun buildPolygonPath(\n    left: Float,\n    top: Float,\n    right: Float,\n    bottom: Float,\n    vertices: Int,\n    rotationDegrees: Int,\n    isRegular: Boolean\n): Path {\n    val centerX = (left + right) / 2f\n    val centerY = (top + bottom) / 2f\n    val width = right - left\n    val height = bottom - top\n    val safeVertices = vertices.coerceAtLeast(3)\n\n    return Path().apply {\n        if (isRegular) {\n            val radius = min(width, height) / 2f\n            val step = 360f / safeVertices\n            val startAngle = rotationDegrees - 90f\n\n            repeat(safeVertices) { index ->\n                val angle = Math.toRadians((startAngle + index * step).toDouble())\n                val x = centerX + radius * cos(angle).toFloat()\n                val y = centerY + radius * sin(angle).toFloat()\n                if (index == 0) moveTo(x, y) else lineTo(x, y)\n            }\n        } else {\n            repeat(safeVertices) { index ->\n                val angle = Math.toRadians(\n                    (rotationDegrees - 90f + index * (360f / safeVertices)).toDouble()\n                )\n                val x = centerX + width / 2f * cos(angle).toFloat()\n                val y = centerY + height / 2f * sin(angle).toFloat()\n                if (index == 0) moveTo(x, y) else lineTo(x, y)\n            }\n        }\n        close()\n    }\n}\n\nprivate fun buildStarPath(\n    left: Float,\n    top: Float,\n    right: Float,\n    bottom: Float,\n    vertices: Int,\n    rotationDegrees: Int,\n    innerRadiusRatio: Float,\n    isRegular: Boolean\n): Path {\n    val safeVertices = vertices.coerceAtLeast(3)\n    val centerX = (left + right) / 2f\n    val centerY = (top + bottom) / 2f\n    val width = right - left\n    val height = bottom - top\n    val safeInnerRadiusRatio = innerRadiusRatio.coerceIn(0f, 1f)\n\n    return Path().apply {\n        if (isRegular) {\n            val outerRadius = min(width, height) / 2f\n            val innerRadius = outerRadius * safeInnerRadiusRatio\n            val step = 360f / (safeVertices * 2)\n            val startAngle = rotationDegrees - 90f\n\n            repeat(safeVertices * 2) { index ->\n                val radius = if (index % 2 == 0) outerRadius else innerRadius\n                val angle = Math.toRadians((startAngle + index * step).toDouble())\n                val x = centerX + radius * cos(angle).toFloat()\n                val y = centerY + radius * sin(angle).toFloat()\n                if (index == 0) moveTo(x, y) else lineTo(x, y)\n            }\n        } else {\n            val step = 360f / (safeVertices * 2)\n            val startAngle = rotationDegrees - 90f\n\n            repeat(safeVertices * 2) { index ->\n                val radiusX = if (index % 2 == 0) width / 2f else width / 2f * safeInnerRadiusRatio\n                val radiusY =\n                    if (index % 2 == 0) height / 2f else height / 2f * safeInnerRadiusRatio\n                val angle = Math.toRadians((startAngle + index * step).toDouble())\n                val x = centerX + radiusX * cos(angle).toFloat()\n                val y = centerY + radiusY * sin(angle).toFloat()\n                if (index == 0) moveTo(x, y) else lineTo(x, y)\n            }\n        }\n        close()\n    }\n}\n\nprivate fun buildLineArrowPath(\n    left: Float,\n    top: Float,\n    right: Float,\n    bottom: Float,\n    drawStartArrow: Boolean,\n    drawEndArrow: Boolean,\n    sizeScale: Float,\n    angle: Float\n): Path {\n    val centerY = (top + bottom) / 2f\n    val length = right - left\n    val headLength = min(\n        length / if (drawStartArrow && drawEndArrow) 3f else 2f,\n        max(bottom - top, 1f) * sizeScale.coerceAtLeast(0.5f)\n    ).coerceAtLeast(1f)\n\n    return Path().apply {\n        moveTo(left, centerY)\n        lineTo(right, centerY)\n\n        if (drawEndArrow) {\n            addArrowHead(\n                tip = Offset(right, centerY),\n                directionAngleDegrees = 0f,\n                headLength = headLength,\n                angle = angle\n            )\n        }\n        if (drawStartArrow) {\n            addArrowHead(\n                tip = Offset(left, centerY),\n                directionAngleDegrees = 180f,\n                headLength = headLength,\n                angle = angle\n            )\n        }\n    }\n}\n\nprivate fun Path.addArrowHead(\n    tip: Offset,\n    directionAngleDegrees: Float,\n    headLength: Float,\n    angle: Float\n) {\n    val first = directionAngleDegrees + angle\n    val second = directionAngleDegrees - angle\n\n    moveTo(tip.x, tip.y)\n    lineTo(\n        tip.x + cos(Math.toRadians(first.toDouble())).toFloat() * headLength,\n        tip.y + sin(Math.toRadians(first.toDouble())).toFloat() * headLength\n    )\n    moveTo(tip.x, tip.y)\n    lineTo(\n        tip.x + cos(Math.toRadians(second.toDouble())).toFloat() * headLength,\n        tip.y + sin(Math.toRadians(second.toDouble())).toFloat() * headLength\n    )\n}\n\nprivate fun buildFilledArrowPath(\n    left: Float,\n    top: Float,\n    right: Float,\n    bottom: Float,\n    doubleHeaded: Boolean,\n    sizeScale: Float,\n    angle: Float\n): Path {\n    val width = right - left\n    val height = bottom - top\n    val centerY = (top + bottom) / 2f\n    val angleRadians = Math.toRadians(angle.coerceIn(100f, 175f).toDouble())\n    val normalizedScale = (sizeScale.coerceIn(0.5f, 8f) - 0.5f) / 7.5f\n    val desiredHeadLength = width * (0.22f + normalizedScale * 0.28f)\n    val headBackOffset = abs(cos(angleRadians)).toFloat() * desiredHeadLength\n    val tipHalfHeight = min(height / 2f, abs(sin(angleRadians)).toFloat() * desiredHeadLength)\n    val shaftHalfHeight = min(height * 0.24f, tipHalfHeight * 0.55f).coerceAtLeast(height * 0.12f)\n\n    return Path().apply {\n        if (doubleHeaded) {\n            val safeHeadOffset = min(headBackOffset, width / 2.5f)\n            val leftBackX = left + safeHeadOffset\n            val rightBackX = right - safeHeadOffset\n\n            moveTo(left, centerY)\n            lineTo(leftBackX, centerY - tipHalfHeight)\n            lineTo(leftBackX, centerY - shaftHalfHeight)\n            lineTo(rightBackX, centerY - shaftHalfHeight)\n            lineTo(rightBackX, centerY - tipHalfHeight)\n            lineTo(right, centerY)\n            lineTo(rightBackX, centerY + tipHalfHeight)\n            lineTo(rightBackX, centerY + shaftHalfHeight)\n            lineTo(leftBackX, centerY + shaftHalfHeight)\n            lineTo(leftBackX, centerY + tipHalfHeight)\n        } else {\n            val safeHeadOffset = min(headBackOffset, width * 0.6f)\n            val backX = right - safeHeadOffset\n\n            moveTo(left, centerY - shaftHalfHeight)\n            lineTo(backX, centerY - shaftHalfHeight)\n            lineTo(backX, centerY - tipHalfHeight)\n            lineTo(right, centerY)\n            lineTo(backX, centerY + tipHalfHeight)\n            lineTo(backX, centerY + shaftHalfHeight)\n            lineTo(left, centerY + shaftHalfHeight)\n        }\n        close()\n    }\n}\n\nprivate fun ShapeLayerRenderData.scaleContent(\n    scale: Float\n): ShapeLayerRenderData = copy(\n    width = width * scale,\n    height = height * scale,\n    contentLeft = contentLeft * scale,\n    contentTop = contentTop * scale,\n    contentWidth = contentWidth * scale,\n    contentHeight = contentHeight * scale,\n    shapeWidth = shapeWidth * scale,\n    shapeHeight = shapeHeight * scale,\n    shapeTranslateX = shapeTranslateX * scale,\n    shapeTranslateY = shapeTranslateY * scale\n)\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/utils/TextLayerMetrics.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.utils\n\nimport android.content.Context\nimport android.graphics.Paint\nimport android.graphics.Typeface\nimport android.text.TextPaint\nimport android.util.TypedValue\nimport com.t8rin.imagetoolbox.core.utils.toTypeface\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.DropShadow\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport kotlin.math.abs\nimport kotlin.math.ceil\n\ninternal data class TextLayerPadding(\n    val leftPx: Float,\n    val topPx: Float,\n    val rightPx: Float,\n    val bottomPx: Float\n) {\n    companion object {\n        val Zero = TextLayerPadding(\n            leftPx = 0f,\n            topPx = 0f,\n            rightPx = 0f,\n            bottomPx = 0f\n        )\n    }\n}\n\ninternal data class TextLayerMetrics(\n    val fontSizePx: Float,\n    val lineHeightPx: Float,\n    val padding: TextLayerPadding,\n    val typeface: Typeface\n)\n\ninternal fun Context.calculateTextLayerMetrics(\n    type: LayerType.Text,\n    textFullSize: Int\n): TextLayerMetrics {\n    val displayMetrics = resources.displayMetrics\n    val baseTextSize = textFullSize.coerceAtLeast(1) * type.size\n    val fontSizePx = TypedValue.applyDimension(\n        TypedValue.COMPLEX_UNIT_SP,\n        baseTextSize / 12.5f,\n        displayMetrics\n    ).coerceAtLeast(1f)\n    val typeface = createTextLayerTypeface(type)\n    val lineHeightPx = TextPaint(Paint.ANTI_ALIAS_FLAG or Paint.SUBPIXEL_TEXT_FLAG).apply {\n        textSize = fontSizePx\n        hinting = Paint.HINTING_ON\n        isLinearText = true\n        isUnderlineText = type.decorations.any { it == LayerType.Text.Decoration.Underline }\n        isStrikeThruText = type.decorations.any { it == LayerType.Text.Decoration.LineThrough }\n        this.typeface = typeface\n    }.fontMetrics.run {\n        ceil((descent - ascent + leading.coerceAtLeast(0f)).toDouble())\n            .toFloat()\n            .coerceAtLeast(fontSizePx)\n    }\n    val baseHorizontalPaddingPx = baseTextSize / 10f\n    val baseVerticalPaddingPx = baseTextSize / 12f\n    val shadowPadding = calculateShadowPadding(type.shadow)\n    val geometricTransformPaddingPx = lineHeightPx * abs(type.geometricTransform?.skewX ?: 0f)\n\n    return TextLayerMetrics(\n        fontSizePx = fontSizePx,\n        lineHeightPx = lineHeightPx,\n        padding = TextLayerPadding(\n            leftPx = baseHorizontalPaddingPx + geometricTransformPaddingPx + shadowPadding.leftPx,\n            topPx = baseVerticalPaddingPx + shadowPadding.topPx,\n            rightPx = baseHorizontalPaddingPx + geometricTransformPaddingPx + shadowPadding.rightPx,\n            bottomPx = baseVerticalPaddingPx + shadowPadding.bottomPx\n        ),\n        typeface = typeface\n    )\n}\n\ninternal fun createTextLayerTypeface(type: LayerType.Text): Typeface {\n    val isBold = type.decorations.any { it == LayerType.Text.Decoration.Bold }\n    val isItalic = type.decorations.any { it == LayerType.Text.Decoration.Italic }\n    val style = when {\n        isBold && isItalic -> Typeface.BOLD_ITALIC\n        isBold -> Typeface.BOLD\n        isItalic -> Typeface.ITALIC\n        else -> Typeface.NORMAL\n    }\n\n    return Typeface.create(type.font.toTypeface() ?: Typeface.DEFAULT, style)\n}\n\ninternal fun calculateShadowPadding(\n    shadow: DropShadow?\n): TextLayerPadding {\n    shadow ?: return TextLayerPadding.Zero\n    val blurRadius = shadow.blurRadius.coerceAtLeast(0f)\n\n    return TextLayerPadding(\n        leftPx = (blurRadius - shadow.offsetX).coerceAtLeast(0f),\n        topPx = (blurRadius - shadow.offsetY).coerceAtLeast(0f),\n        rightPx = (blurRadius + shadow.offsetX).coerceAtLeast(0f),\n        bottomPx = (blurRadius + shadow.offsetY).coerceAtLeast(0f)\n    )\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/data/utils/TextLayerShadowRenderer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.data.utils\n\nimport android.graphics.Bitmap\nimport android.graphics.BlurMaskFilter\nimport android.graphics.Paint\nimport android.graphics.PorterDuff\nimport android.text.Layout\nimport android.text.StaticLayout\nimport android.text.TextPaint\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.withSave\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport kotlin.math.ceil\nimport kotlin.math.roundToInt\n\ninternal data class TextShadowRenderData(\n    val bitmap: Bitmap,\n    val left: Float,\n    val top: Float,\n    val rasterScale: Float\n)\n\ninternal fun buildTextShadowRenderData(\n    type: LayerType.Text,\n    textMetrics: TextLayerMetrics,\n    layoutWidth: Int,\n    maxLines: Int?,\n    rasterScale: Float = 1f\n): TextShadowRenderData? {\n    val shadow = type.shadow ?: return null\n    val safeRasterScale = rasterScale.coerceAtLeast(1f)\n    val safeLayoutWidth = (layoutWidth.coerceAtLeast(1) * safeRasterScale)\n        .roundToInt()\n        .coerceAtLeast(1)\n    val text = type.text.ifEmpty { \" \" }\n    val alignment = when (type.alignment) {\n        LayerType.Text.Alignment.Start -> Layout.Alignment.ALIGN_NORMAL\n        LayerType.Text.Alignment.Center -> Layout.Alignment.ALIGN_CENTER\n        LayerType.Text.Alignment.End -> Layout.Alignment.ALIGN_OPPOSITE\n    }\n    val paint = TextPaint(Paint.ANTI_ALIAS_FLAG or Paint.SUBPIXEL_TEXT_FLAG).apply {\n        color = android.graphics.Color.BLACK\n        textSize = textMetrics.fontSizePx * safeRasterScale\n        hinting = Paint.HINTING_ON\n        isLinearText = true\n        isUnderlineText = type.decorations.any { it == LayerType.Text.Decoration.Underline }\n        isStrikeThruText = type.decorations.any { it == LayerType.Text.Decoration.LineThrough }\n        typeface = textMetrics.typeface\n        textScaleX = type.geometricTransform?.scaleX?.coerceAtLeast(0.01f) ?: 1f\n        textSkewX = type.geometricTransform?.skewX ?: 0f\n    }\n    val layout = createTextStaticLayout(\n        text = text,\n        paint = paint,\n        width = safeLayoutWidth,\n        alignment = alignment,\n        lineHeightPx = textMetrics.lineHeightPx * safeRasterScale,\n        maxLines = maxLines\n    )\n    val sourcePadding = shadowSourcePadding(\n        textMetrics = textMetrics,\n        rasterScale = safeRasterScale\n    )\n    val sourceBitmap = createBitmap(\n        width = ceil(layout.width + sourcePadding.leftPx + sourcePadding.rightPx)\n            .toInt()\n            .coerceAtLeast(1),\n        height = ceil(layout.height + sourcePadding.topPx + sourcePadding.bottomPx)\n            .toInt()\n            .coerceAtLeast(1)\n    ).applyCanvas {\n        withSave {\n            translate(sourcePadding.leftPx, sourcePadding.topPx)\n            layout.draw(this)\n        }\n    }\n\n    val blurRadius = shadow.blurRadius.coerceAtLeast(0f) * safeRasterScale\n    val offset = IntArray(2)\n    val alphaBitmap = sourceBitmap.extractAlpha(\n        Paint(Paint.ANTI_ALIAS_FLAG).apply {\n            if (blurRadius > 0f) {\n                maskFilter = BlurMaskFilter(\n                    blurRadius,\n                    BlurMaskFilter.Blur.NORMAL\n                )\n            }\n        },\n        offset\n    )\n\n    val tintedBitmap = createBitmap(\n        width = alphaBitmap.width.coerceAtLeast(1),\n        height = alphaBitmap.height.coerceAtLeast(1)\n    ).applyCanvas {\n        drawBitmap(\n            alphaBitmap,\n            0f,\n            0f,\n            Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                isFilterBitmap = true\n            }\n        )\n        drawColor(shadow.color, PorterDuff.Mode.SRC_IN)\n    }\n\n    sourceBitmap.recycle()\n    alphaBitmap.recycle()\n\n    return TextShadowRenderData(\n        bitmap = tintedBitmap,\n        left = offset[0].toFloat() - sourcePadding.leftPx + shadow.offsetX * safeRasterScale,\n        top = offset[1].toFloat() - sourcePadding.topPx + shadow.offsetY * safeRasterScale,\n        rasterScale = safeRasterScale\n    )\n}\n\nprivate fun shadowSourcePadding(\n    textMetrics: TextLayerMetrics,\n    rasterScale: Float\n): TextLayerPadding = TextLayerPadding(\n    leftPx = ceil(textMetrics.padding.leftPx * rasterScale),\n    topPx = ceil(textMetrics.padding.topPx * rasterScale),\n    rightPx = ceil(textMetrics.padding.rightPx * rasterScale),\n    bottomPx = ceil(textMetrics.padding.bottomPx * rasterScale)\n)\n\ninternal fun createTextStaticLayout(\n    text: String,\n    paint: TextPaint,\n    width: Int,\n    alignment: Layout.Alignment,\n    lineHeightPx: Float,\n    maxLines: Int?\n): StaticLayout {\n    val boundedText = maxLines\n        ?.takeIf { it > 0 }\n        ?.let { linesLimit ->\n            val fullLayout = StaticLayout.Builder\n                .obtain(text, 0, text.length, paint, width)\n                .setAlignment(alignment)\n                .setIncludePad(false)\n                .build()\n\n            if (fullLayout.lineCount <= linesLimit) {\n                text\n            } else {\n                text.substring(0, fullLayout.getLineEnd(linesLimit - 1))\n            }\n        }\n        ?: text\n\n    val naturalLineHeightPx = ceil(\n        (paint.fontMetrics.descent - paint.fontMetrics.ascent).toDouble()\n    ).toFloat()\n    return StaticLayout.Builder\n        .obtain(boundedText, 0, boundedText.length, paint, width)\n        .setAlignment(alignment)\n        .setIncludePad(false)\n        .setLineSpacing((lineHeightPx - naturalLineHeightPx).coerceAtLeast(0f), 1f)\n        .build()\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/di/MarkupLayersModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.AndroidMarkupLayersApplier\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayersApplier\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface MarkupLayersModule {\n\n    @Binds\n    @Singleton\n    fun applier(\n        impl: AndroidMarkupLayersApplier\n    ): MarkupLayersApplier<Bitmap>\n\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/domain/MarkupLayer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Outline\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FontType\n\ndata class MarkupLayer(\n    val type: LayerType,\n    val position: LayerPosition,\n    val contentSize: IntegerSize = IntegerSize.Zero,\n    val visibleLineCount: Int? = null,\n    val cornerRadiusPercent: Int = 0,\n    val isLocked: Boolean = false,\n    val blendingMode: BlendingMode = BlendingMode.SrcOver,\n    val groupedLayers: List<MarkupLayer> = emptyList()\n)\n\ndata class LayerPosition(\n    val scale: Float = 1f,\n    val rotation: Float = 0f,\n    val isFlippedHorizontally: Boolean = false,\n    val isFlippedVertically: Boolean = false,\n    val offsetX: Float = 0f,\n    val offsetY: Float = 0f,\n    val alpha: Float = 1f,\n    val currentCanvasSize: IntegerSize,\n    val coerceToBounds: Boolean,\n    val isVisible: Boolean\n)\n\ntypealias DomainTextDecoration = LayerType.Text.Decoration\n\ndata class TextGeometricTransform(\n    val scaleX: Float = 1f,\n    val skewX: Float = 0f\n)\n\ndata class DropShadow(\n    val color: Int = 0xFF000000.toInt(),\n    val offsetX: Float = 0f,\n    val offsetY: Float = 6f,\n    val blurRadius: Float = 12f\n) {\n    companion object {\n        val Default = DropShadow()\n\n        val BlurRadiusRange: ClosedFloatingPointRange<Float>\n            get() = 0f..100f\n\n        val OffsetXRange: ClosedFloatingPointRange<Float>\n            get() = -64f..64f\n\n        val OffsetYRange: ClosedFloatingPointRange<Float>\n            get() = -64f..64f\n    }\n}\n\nsealed interface LayerType {\n    data class Text(\n        val color: Int,\n        val size: Float,\n        val font: FontType?,\n        val backgroundColor: Int,\n        val text: String,\n        val decorations: List<Decoration>,\n        val outline: Outline?,\n        val alignment: Alignment,\n        val geometricTransform: TextGeometricTransform? = null,\n        val shadow: DropShadow? = null\n    ) : LayerType {\n\n        enum class Decoration {\n            Bold, Italic, Underline, LineThrough\n        }\n\n        enum class Alignment {\n            Start, Center, End\n        }\n\n        companion object {\n            val Default by lazy {\n                Text(\n                    color = -16777216,\n                    size = 0.5f,\n                    font = null,\n                    backgroundColor = 0,\n                    text = \"Text\",\n                    decorations = listOf(),\n                    outline = null,\n                    alignment = Alignment.Start,\n                    geometricTransform = null,\n                    shadow = null\n                )\n            }\n        }\n    }\n\n    sealed class Picture(\n        open val imageData: Any,\n        open val shadow: DropShadow? = null\n    ) : LayerType {\n        data class Image(\n            override val imageData: Any,\n            override val shadow: DropShadow? = null\n        ) : Picture(\n            imageData = imageData,\n            shadow = shadow\n        )\n\n        data class Sticker(\n            override val imageData: Any,\n            override val shadow: DropShadow? = null\n        ) : Picture(\n            imageData = imageData,\n            shadow = shadow\n        )\n    }\n\n    data class Shape(\n        val shapeMode: ShapeMode,\n        val color: Int,\n        val strokeWidth: Float = 16f,\n        val widthRatio: Float = 0.35f,\n        val heightRatio: Float = 0.35f,\n        val shadow: DropShadow? = null\n    ) : LayerType {\n\n        companion object {\n            val Default by lazy {\n                Shape(\n                    shapeMode = ShapeMode.Star(),\n                    color = -16777216,\n                    strokeWidth = 16f,\n                    widthRatio = 0.35f,\n                    heightRatio = 0.35f,\n                    shadow = null\n                )\n            }\n        }\n    }\n}\n\ninternal fun LayerType.layerCornerRadiusPercent(value: Int): Int = when (this) {\n    is LayerType.Shape -> 0\n    else -> value.coerceIn(0, 50)\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/domain/MarkupLayersApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.domain\n\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\n\ninterface MarkupLayersApplier<I> {\n\n    suspend fun applyToImage(\n        image: I,\n        layers: List<MarkupLayer>\n    ): I\n\n    suspend fun saveProject(\n        destination: Writeable,\n        project: MarkupProject\n    )\n\n    suspend fun openProject(\n        uri: String\n    ): MarkupProjectResult\n\n    fun clearProjectCache()\n\n}"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/domain/MarkupProject.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.domain\n\ndata class MarkupProject(\n    val background: ProjectBackground,\n    val layers: List<MarkupLayer>,\n    val lastLayers: List<MarkupLayer>,\n    val undoneLayers: List<MarkupLayer>,\n    val history: List<MarkupProjectHistorySnapshot> = emptyList(),\n    val redoHistory: List<MarkupProjectHistorySnapshot> = emptyList(),\n)\n\ndata class MarkupProjectHistorySnapshot(\n    val background: ProjectBackground,\n    val layers: List<MarkupLayer>,\n)\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/domain/MarkupProjectResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.domain\n\nsealed interface MarkupProjectResult {\n\n    data class Success(\n        val project: MarkupProject\n    ) : MarkupProjectResult\n\n    sealed class Error(\n        open val message: String\n    ) : MarkupProjectResult {\n        data class InvalidArchive(\n            override val message: String\n        ) : Error(message)\n\n        data class MissingProjectFile(\n            override val message: String\n        ) : Error(message)\n\n        data class InvalidProjectFile(\n            override val message: String\n        ) : Error(message)\n\n        data class UnsupportedVersion(\n            val version: Int,\n            override val message: String\n        ) : Error(message)\n\n        data class Exception(\n            val throwable: Throwable,\n            override val message: String\n        ) : Error(message)\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/domain/ProjectBackground.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.domain\n\nsealed class ProjectBackground {\n    data object None : ProjectBackground()\n\n    data class Image(\n        val uri: String\n    ) : ProjectBackground()\n\n    data class Color(\n        val width: Int,\n        val height: Int,\n        val color: Int\n    ) : ProjectBackground()\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/domain/ShapeLayerModeExt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.domain\n\nsealed interface ShapeMode {\n    val kind: Kind\n\n    enum class Kind {\n        Line,\n        Arrow,\n        DoubleArrow,\n        LineArrow,\n        DoubleLineArrow,\n        Rect,\n        OutlinedRect,\n        Oval,\n        OutlinedOval,\n        Triangle,\n        OutlinedTriangle,\n        Polygon,\n        OutlinedPolygon,\n        Star,\n        OutlinedStar\n    }\n\n    object Line : ShapeMode {\n        override val kind: Kind = Kind.Line\n    }\n\n    data class Arrow(\n        val sizeScale: Float = DEFAULT_ARROW_SIZE_SCALE,\n        val angle: Float = DEFAULT_ARROW_ANGLE\n    ) : ShapeMode {\n        override val kind: Kind = Kind.Arrow\n    }\n\n    data class DoubleArrow(\n        val sizeScale: Float = DEFAULT_ARROW_SIZE_SCALE,\n        val angle: Float = DEFAULT_ARROW_ANGLE\n    ) : ShapeMode {\n        override val kind: Kind = Kind.DoubleArrow\n    }\n\n    data class LineArrow(\n        val sizeScale: Float = DEFAULT_ARROW_SIZE_SCALE,\n        val angle: Float = DEFAULT_ARROW_ANGLE\n    ) : ShapeMode {\n        override val kind: Kind = Kind.LineArrow\n    }\n\n    data class DoubleLineArrow(\n        val sizeScale: Float = DEFAULT_ARROW_SIZE_SCALE,\n        val angle: Float = DEFAULT_ARROW_ANGLE\n    ) : ShapeMode {\n        override val kind: Kind = Kind.DoubleLineArrow\n    }\n\n    data class Rect(\n        val rotationDegrees: Int = 0,\n        val cornerRadius: Float = DEFAULT_RECT_CORNER_RADIUS\n    ) : ShapeMode {\n        override val kind: Kind = Kind.Rect\n    }\n\n    data class OutlinedRect(\n        val rotationDegrees: Int = 0,\n        val cornerRadius: Float = DEFAULT_RECT_CORNER_RADIUS,\n        val fillColor: Int? = null\n    ) : ShapeMode {\n        override val kind: Kind = Kind.OutlinedRect\n    }\n\n    object Oval : ShapeMode {\n        override val kind: Kind = Kind.Oval\n    }\n\n    data class OutlinedOval(\n        val fillColor: Int? = null\n    ) : ShapeMode {\n        override val kind: Kind = Kind.OutlinedOval\n    }\n\n    object Triangle : ShapeMode {\n        override val kind: Kind = Kind.Triangle\n    }\n\n    data class OutlinedTriangle(\n        val fillColor: Int? = null\n    ) : ShapeMode {\n        override val kind: Kind = Kind.OutlinedTriangle\n    }\n\n    data class Polygon(\n        val vertices: Int = DEFAULT_VERTICES,\n        val rotationDegrees: Int = 0,\n        val isRegular: Boolean = false\n    ) : ShapeMode {\n        override val kind: Kind = Kind.Polygon\n    }\n\n    data class OutlinedPolygon(\n        val vertices: Int = DEFAULT_VERTICES,\n        val rotationDegrees: Int = 0,\n        val isRegular: Boolean = false,\n        val fillColor: Int? = null\n    ) : ShapeMode {\n        override val kind: Kind = Kind.OutlinedPolygon\n    }\n\n    data class Star(\n        val vertices: Int = DEFAULT_VERTICES,\n        val rotationDegrees: Int = 0,\n        val innerRadiusRatio: Float = DEFAULT_INNER_RADIUS_RATIO,\n        val isRegular: Boolean = false\n    ) : ShapeMode {\n        override val kind: Kind = Kind.Star\n    }\n\n    data class OutlinedStar(\n        val vertices: Int = DEFAULT_VERTICES,\n        val rotationDegrees: Int = 0,\n        val innerRadiusRatio: Float = DEFAULT_INNER_RADIUS_RATIO,\n        val isRegular: Boolean = false,\n        val fillColor: Int? = null\n    ) : ShapeMode {\n        override val kind: Kind = Kind.OutlinedStar\n    }\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                Line,\n                Arrow(),\n                DoubleArrow(),\n                LineArrow(),\n                DoubleLineArrow(),\n                Rect(),\n                OutlinedRect(),\n                Oval,\n                OutlinedOval(),\n                Triangle,\n                OutlinedTriangle(),\n                Polygon(),\n                OutlinedPolygon(),\n                Star(),\n                OutlinedStar()\n            )\n        }\n    }\n}\n\nprivate data class ShapeSizePreset(\n    val widthRatio: Float,\n    val heightRatio: Float\n)\n\nprivate enum class ShapeGeometryFamily {\n    Line,\n    FilledArrow,\n    RectLike,\n    Triangle,\n    Polygon,\n    Star\n}\n\ninternal val ShapeMode.ordinal: Int\n    get() = ShapeMode.entries.indexOfFirst { it.kind == kind }\n        .takeIf { it >= 0 }\n        ?: 0\n\ninternal fun ShapeMode.Kind.defaultMode(): ShapeMode = when (this) {\n    ShapeMode.Kind.Line -> ShapeMode.Line\n    ShapeMode.Kind.Arrow -> ShapeMode.Arrow()\n    ShapeMode.Kind.DoubleArrow -> ShapeMode.DoubleArrow()\n    ShapeMode.Kind.LineArrow -> ShapeMode.LineArrow()\n    ShapeMode.Kind.DoubleLineArrow -> ShapeMode.DoubleLineArrow()\n    ShapeMode.Kind.Rect -> ShapeMode.Rect()\n    ShapeMode.Kind.OutlinedRect -> ShapeMode.OutlinedRect()\n    ShapeMode.Kind.Oval -> ShapeMode.Oval\n    ShapeMode.Kind.OutlinedOval -> ShapeMode.OutlinedOval()\n    ShapeMode.Kind.Triangle -> ShapeMode.Triangle\n    ShapeMode.Kind.OutlinedTriangle -> ShapeMode.OutlinedTriangle()\n    ShapeMode.Kind.Polygon -> ShapeMode.Polygon()\n    ShapeMode.Kind.OutlinedPolygon -> ShapeMode.OutlinedPolygon()\n    ShapeMode.Kind.Star -> ShapeMode.Star()\n    ShapeMode.Kind.OutlinedStar -> ShapeMode.OutlinedStar()\n}\n\ninternal fun resolveMarkupLayerShapeMode(\n    modeName: String?,\n    modeOrdinal: Int?\n): ShapeMode {\n    val modeByName = modeName\n        ?.let { raw -> ShapeMode.Kind.entries.firstOrNull { it.name == raw } }\n        ?.defaultMode()\n\n    return modeByName\n        ?: modeOrdinal?.let(ShapeMode.entries::getOrNull)\n        ?: ShapeMode.Kind.OutlinedRect.defaultMode()\n}\n\ninternal fun ShapeMode.isOutlinedShapeMode(): Boolean = when (this) {\n    is ShapeMode.OutlinedRect,\n    is ShapeMode.OutlinedOval,\n    is ShapeMode.OutlinedTriangle,\n    is ShapeMode.OutlinedPolygon,\n    is ShapeMode.OutlinedStar -> true\n\n    else -> false\n}\n\ninternal fun ShapeMode.isFilledShapeMode(): Boolean = when (this) {\n    is ShapeMode.Rect,\n    ShapeMode.Oval,\n    ShapeMode.Triangle,\n    is ShapeMode.Polygon,\n    is ShapeMode.Star,\n    is ShapeMode.Arrow,\n    is ShapeMode.DoubleArrow -> true\n\n    else -> false\n}\n\ninternal fun ShapeMode.usesStrokeWidth(): Boolean = when (this) {\n    ShapeMode.Line,\n    is ShapeMode.LineArrow,\n    is ShapeMode.DoubleLineArrow,\n    is ShapeMode.OutlinedRect,\n    is ShapeMode.OutlinedOval,\n    is ShapeMode.OutlinedTriangle,\n    is ShapeMode.OutlinedPolygon,\n    is ShapeMode.OutlinedStar -> true\n\n    else -> false\n}\n\ninternal fun ShapeMode.outlinedFillColorInt(): Int? = when (this) {\n    is ShapeMode.OutlinedRect -> fillColor\n    is ShapeMode.OutlinedOval -> fillColor\n    is ShapeMode.OutlinedTriangle -> fillColor\n    is ShapeMode.OutlinedPolygon -> fillColor\n    is ShapeMode.OutlinedStar -> fillColor\n    else -> null\n}\n\ninternal fun ShapeMode.withOutlinedFillColor(color: Int?): ShapeMode = when (this) {\n    is ShapeMode.OutlinedRect -> copy(fillColor = color)\n    is ShapeMode.OutlinedOval -> copy(fillColor = color)\n    is ShapeMode.OutlinedTriangle -> copy(fillColor = color)\n    is ShapeMode.OutlinedPolygon -> copy(fillColor = color)\n    is ShapeMode.OutlinedStar -> copy(fillColor = color)\n    else -> this\n}\n\ninternal fun ShapeMode.arrowSizeScale(): Float = when (this) {\n    is ShapeMode.Arrow -> sizeScale\n    is ShapeMode.DoubleArrow -> sizeScale\n    is ShapeMode.LineArrow -> sizeScale\n    is ShapeMode.DoubleLineArrow -> sizeScale\n    else -> DEFAULT_ARROW_SIZE_SCALE\n}\n\ninternal fun ShapeMode.arrowAngle(): Float = when (this) {\n    is ShapeMode.Arrow -> angle\n    is ShapeMode.DoubleArrow -> angle\n    is ShapeMode.LineArrow -> angle\n    is ShapeMode.DoubleLineArrow -> angle\n    else -> DEFAULT_ARROW_ANGLE\n}\n\ninternal fun ShapeMode.vertices(): Int = when (this) {\n    is ShapeMode.Polygon -> vertices\n    is ShapeMode.OutlinedPolygon -> vertices\n    is ShapeMode.Star -> vertices\n    is ShapeMode.OutlinedStar -> vertices\n    else -> DEFAULT_VERTICES\n}\n\ninternal fun ShapeMode.rotationDegrees(): Int = when (this) {\n    is ShapeMode.Rect -> rotationDegrees\n    is ShapeMode.OutlinedRect -> rotationDegrees\n    is ShapeMode.Polygon -> rotationDegrees\n    is ShapeMode.OutlinedPolygon -> rotationDegrees\n    is ShapeMode.Star -> rotationDegrees\n    is ShapeMode.OutlinedStar -> rotationDegrees\n    else -> 0\n}\n\ninternal fun ShapeMode.cornerRadius(): Float = when (this) {\n    is ShapeMode.Rect -> cornerRadius\n    is ShapeMode.OutlinedRect -> cornerRadius\n    else -> DEFAULT_RECT_CORNER_RADIUS\n}\n\ninternal fun ShapeMode.isRegular(): Boolean = when (this) {\n    is ShapeMode.Polygon -> isRegular\n    is ShapeMode.OutlinedPolygon -> isRegular\n    is ShapeMode.Star -> isRegular\n    is ShapeMode.OutlinedStar -> isRegular\n    else -> false\n}\n\ninternal fun ShapeMode.innerRadiusRatio(): Float = when (this) {\n    is ShapeMode.Star -> innerRadiusRatio\n    is ShapeMode.OutlinedStar -> innerRadiusRatio\n    else -> DEFAULT_INNER_RADIUS_RATIO\n}\n\ninternal fun ShapeMode.updateArrow(\n    sizeScale: Float? = null,\n    angle: Float? = null\n): ShapeMode = when (this) {\n    is ShapeMode.Arrow -> copy(\n        sizeScale = sizeScale ?: this.sizeScale,\n        angle = angle ?: this.angle\n    )\n\n    is ShapeMode.DoubleArrow -> copy(\n        sizeScale = sizeScale ?: this.sizeScale,\n        angle = angle ?: this.angle\n    )\n\n    is ShapeMode.LineArrow -> copy(\n        sizeScale = sizeScale ?: this.sizeScale,\n        angle = angle ?: this.angle\n    )\n\n    is ShapeMode.DoubleLineArrow -> copy(\n        sizeScale = sizeScale ?: this.sizeScale,\n        angle = angle ?: this.angle\n    )\n\n    else -> this\n}\n\ninternal fun ShapeMode.updateRect(\n    rotationDegrees: Int? = null,\n    cornerRadius: Float? = null\n): ShapeMode = when (this) {\n    is ShapeMode.Rect -> copy(\n        rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n        cornerRadius = cornerRadius ?: this.cornerRadius\n    )\n\n    is ShapeMode.OutlinedRect -> copy(\n        rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n        cornerRadius = cornerRadius ?: this.cornerRadius\n    )\n\n    else -> this\n}\n\ninternal fun ShapeMode.updatePolygon(\n    vertices: Int? = null,\n    rotationDegrees: Int? = null,\n    isRegular: Boolean? = null\n): ShapeMode = when (this) {\n    is ShapeMode.Polygon -> copy(\n        vertices = vertices ?: this.vertices,\n        rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n        isRegular = isRegular ?: this.isRegular\n    )\n\n    is ShapeMode.OutlinedPolygon -> copy(\n        vertices = vertices ?: this.vertices,\n        rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n        isRegular = isRegular ?: this.isRegular\n    )\n\n    else -> this\n}\n\ninternal fun ShapeMode.updateStar(\n    vertices: Int? = null,\n    innerRadiusRatio: Float? = null,\n    rotationDegrees: Int? = null,\n    isRegular: Boolean? = null\n): ShapeMode = when (this) {\n    is ShapeMode.Star -> copy(\n        vertices = vertices ?: this.vertices,\n        innerRadiusRatio = innerRadiusRatio ?: this.innerRadiusRatio,\n        rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n        isRegular = isRegular ?: this.isRegular\n    )\n\n    is ShapeMode.OutlinedStar -> copy(\n        vertices = vertices ?: this.vertices,\n        innerRadiusRatio = innerRadiusRatio ?: this.innerRadiusRatio,\n        rotationDegrees = rotationDegrees ?: this.rotationDegrees,\n        isRegular = isRegular ?: this.isRegular\n    )\n\n    else -> this\n}\n\ninternal fun ShapeMode.withSavedStateFrom(previous: ShapeMode): ShapeMode {\n    val previousArrow = previous.takeIf {\n        it is ShapeMode.Arrow ||\n                it is ShapeMode.DoubleArrow ||\n                it is ShapeMode.LineArrow ||\n                it is ShapeMode.DoubleLineArrow\n    }\n    if (previousArrow != null) {\n        val current = updateArrow(\n            sizeScale = previousArrow.arrowSizeScale(),\n            angle = previousArrow.arrowAngle()\n        )\n        if (current !== this) return current\n    }\n\n    return when (previous) {\n        is ShapeMode.Rect,\n        is ShapeMode.OutlinedRect -> updateRect(\n            rotationDegrees = previous.rotationDegrees(),\n            cornerRadius = previous.cornerRadius()\n        )\n\n        is ShapeMode.Polygon,\n        is ShapeMode.OutlinedPolygon -> updatePolygon(\n            vertices = previous.vertices(),\n            rotationDegrees = previous.rotationDegrees(),\n            isRegular = previous.isRegular()\n        )\n\n        is ShapeMode.Star,\n        is ShapeMode.OutlinedStar -> updateStar(\n            vertices = previous.vertices(),\n            innerRadiusRatio = previous.innerRadiusRatio(),\n            rotationDegrees = previous.rotationDegrees(),\n            isRegular = previous.isRegular()\n        )\n\n        else -> this\n    }\n}\n\ninternal fun LayerType.Shape.withPreferredGeometryFor(\n    newMode: ShapeMode\n): LayerType.Shape {\n    val previousKind = shapeMode.kind\n    val updatedType = copy(shapeMode = newMode)\n    if (previousKind.geometryFamily() == newMode.kind.geometryFamily()) {\n        return updatedType\n    }\n\n    val preset = newMode.kind.preferredSizePreset()\n    return updatedType.copy(\n        widthRatio = preset.widthRatio,\n        heightRatio = preset.heightRatio\n    )\n}\n\ninternal fun LayerType.Shape.withPreferredInitialGeometryFor(\n    mode: ShapeMode\n): LayerType.Shape {\n    val preset = mode.kind.preferredSizePreset()\n    return copy(\n        shapeMode = mode,\n        widthRatio = preset.widthRatio,\n        heightRatio = preset.heightRatio\n    )\n}\n\nprivate fun ShapeMode.Kind.geometryFamily(): ShapeGeometryFamily = when (this) {\n    ShapeMode.Kind.Line,\n    ShapeMode.Kind.LineArrow,\n    ShapeMode.Kind.DoubleLineArrow -> ShapeGeometryFamily.Line\n\n    ShapeMode.Kind.Arrow,\n    ShapeMode.Kind.DoubleArrow -> ShapeGeometryFamily.FilledArrow\n\n    ShapeMode.Kind.Rect,\n    ShapeMode.Kind.OutlinedRect,\n    ShapeMode.Kind.Oval,\n    ShapeMode.Kind.OutlinedOval -> ShapeGeometryFamily.RectLike\n\n    ShapeMode.Kind.Triangle,\n    ShapeMode.Kind.OutlinedTriangle -> ShapeGeometryFamily.Triangle\n\n    ShapeMode.Kind.Polygon,\n    ShapeMode.Kind.OutlinedPolygon -> ShapeGeometryFamily.Polygon\n\n    ShapeMode.Kind.Star,\n    ShapeMode.Kind.OutlinedStar -> ShapeGeometryFamily.Star\n}\n\nprivate fun ShapeMode.Kind.preferredSizePreset(): ShapeSizePreset = when (this) {\n    ShapeMode.Kind.Line,\n    ShapeMode.Kind.LineArrow,\n    ShapeMode.Kind.DoubleLineArrow -> ShapeSizePreset(\n        widthRatio = 0.5f,\n        heightRatio = 0.1f\n    )\n\n    ShapeMode.Kind.Arrow,\n    ShapeMode.Kind.DoubleArrow -> ShapeSizePreset(\n        widthRatio = 0.5f,\n        heightRatio = 0.2f\n    )\n\n    ShapeMode.Kind.Rect,\n    ShapeMode.Kind.OutlinedRect,\n    ShapeMode.Kind.Oval,\n    ShapeMode.Kind.OutlinedOval -> ShapeSizePreset(\n        widthRatio = 0.42f,\n        heightRatio = 0.42f\n    )\n\n    ShapeMode.Kind.Triangle,\n    ShapeMode.Kind.OutlinedTriangle -> ShapeSizePreset(\n        widthRatio = 0.36f,\n        heightRatio = 0.32f\n    )\n\n    ShapeMode.Kind.Polygon,\n    ShapeMode.Kind.OutlinedPolygon -> ShapeSizePreset(\n        widthRatio = 0.36f,\n        heightRatio = 0.36f\n    )\n\n    ShapeMode.Kind.Star,\n    ShapeMode.Kind.OutlinedStar -> ShapeSizePreset(\n        widthRatio = 0.38f,\n        heightRatio = 0.38f\n    )\n}\n\nprivate const val DEFAULT_ARROW_SIZE_SCALE = 3f\nprivate const val DEFAULT_ARROW_ANGLE = 150f\nprivate const val DEFAULT_VERTICES = 5\nprivate const val DEFAULT_INNER_RADIUS_RATIO = 0.5f\nprivate const val DEFAULT_RECT_CORNER_RADIUS = 0f\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/MarkupLayersContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.withFrameNanos\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.CompositingStrategy\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastAny\nimport androidx.compose.ui.zIndex\nimport androidx.core.graphics.applyCanvas\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Archive\nimport com.t8rin.imagetoolbox.core.resources.icons.BackgroundColor\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveBottomScaffoldLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.Layer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.MarkupLayersActions\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.MarkupLayersNoDataControls\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.MarkupLayersSideMenu\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.MarkupLayersTopAppBarActions\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.MarkupLayersUndoRedo\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.activeLayerGestures\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.BackgroundBehavior\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n@Composable\nfun MarkupLayersContent(\n    component: MarkupLayersComponent\n) {\n    AutoContentBasedColors(component.bitmap)\n\n    val themeState = LocalDynamicThemeState.current\n\n    val appColorTuple = rememberAppColorTuple()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        when (component.backgroundBehavior) {\n            !is BackgroundBehavior.None if component.haveChanges -> showExitDialog = true\n\n            !is BackgroundBehavior.None -> {\n                component.resetState()\n                themeState.updateColorTuple(appColorTuple)\n            }\n\n            else -> component.onGoBack()\n        }\n    }\n\n    AutoContentBasedColors(component.bitmap)\n\n    val imagePicker = rememberImagePicker { uri: Uri ->\n        component.setUri(\n            uri = uri\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n    val projectOpener = rememberFilePicker(\n        mimeType = MimeType.MarkupProjectList,\n        onSuccess = component::setUri\n    )\n    val activeLayer by remember(component) {\n        derivedStateOf {\n            component.layers.firstOrNull { it.state.isActive }\n        }\n    }\n    val projectSaver = rememberFileCreator(\n        mimeType = MimeType.MarkupProject,\n        onSuccess = component::saveProject\n    )\n\n    val screenSize = LocalScreenSize.current\n    val isPortrait by isPortraitOrientationAsState()\n\n    val bitmap =\n        component.bitmap ?: (component.backgroundBehavior as? BackgroundBehavior.Color)?.run {\n            remember(width, height, color) {\n                ImageBitmap(width, height).asAndroidBitmap()\n                    .applyCanvas { drawColor(color) }\n            }\n        } ?: remember {\n            ImageBitmap(\n                screenSize.widthPx,\n                screenSize.heightPx\n            ).asAndroidBitmap()\n        }\n\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var showLayersSelection by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    var isContextOptionsVisible by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var shouldOpenContextOptions by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    val closeLayersSelection = {\n        showLayersSelection = false\n        isContextOptionsVisible = false\n        shouldOpenContextOptions = false\n        component.cancelGroupingSelection()\n    }\n    val toggleLayersSelection = {\n        if (showLayersSelection) {\n            closeLayersSelection()\n        } else {\n            showLayersSelection = true\n        }\n    }\n    val requestContextOptions = { waitForActiveLayer: Boolean ->\n        showLayersSelection = true\n        if (waitForActiveLayer || activeLayer != null) {\n            shouldOpenContextOptions = true\n        }\n    }\n\n    LaunchedEffect(showLayersSelection, activeLayer, shouldOpenContextOptions) {\n        if (showLayersSelection && shouldOpenContextOptions && activeLayer != null) {\n            withFrameNanos { }\n            isContextOptionsVisible = true\n            shouldOpenContextOptions = false\n        }\n    }\n\n    AdaptiveBottomScaffoldLayoutScreen(\n        autoClearFocus = false,\n        modifier = Modifier\n            .clearFocusOnTap()\n            .tappable {\n                component.deactivateAllLayers()\n            },\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.markup_layers),\n                input = component.backgroundBehavior.takeIf { it !is BackgroundBehavior.None },\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = onBack,\n        shouldDisableBackHandler = component.backgroundBehavior is BackgroundBehavior.None,\n        actions = {\n            MarkupLayersActions(\n                component = component,\n                showLayersSelection = showLayersSelection,\n                onToggleLayersSection = toggleLayersSelection,\n                onToggleLayersSectionQuick = {\n                    requestContextOptions(false)\n                }\n            )\n        },\n        topAppBarPersistentActions = { scaffoldState ->\n            MarkupLayersTopAppBarActions(\n                component = component,\n                scaffoldState = scaffoldState\n            )\n        },\n        mainContent = {\n            val imageBitmap by remember(bitmap) {\n                derivedStateOf {\n                    bitmap.copy(Bitmap.Config.ARGB_8888, true).asImageBitmap()\n                }\n            }\n            val direction = LocalLayoutDirection.current\n            val aspectRatio = imageBitmap.width / imageBitmap.height.toFloat()\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .clipToBounds()\n                    .zoomable(\n                        zoomState = rememberZoomState(maxScale = 10f),\n                        zoomEnabled = !component.layers.fastAny { it.state.isActive }\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                Box {\n                    Box(\n                        modifier = Modifier\n                            .padding(\n                                start = WindowInsets\n                                    .displayCutout\n                                    .asPaddingValues()\n                                    .calculateStartPadding(direction)\n                            )\n                            .padding(16.dp)\n                            .aspectRatio(aspectRatio, isPortrait)\n                            .fillMaxSize()\n                            .clip(ShapeDefaults.extremeSmall)\n                            .border(\n                                width = 1.dp,\n                                color = MaterialTheme.colorScheme.outlineVariant(),\n                                shape = ShapeDefaults.extremeSmall\n                            )\n                            .background(MaterialTheme.colorScheme.surfaceContainerLow),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        Box(\n                            modifier = Modifier\n                                .zIndex(-1f)\n                                .matchParentSize()\n                                .clipToBounds()\n                                .transparencyChecker()\n                        )\n                        BoxWithConstraints(\n                            modifier = Modifier\n                                .matchParentSize()\n                                .activeLayerGestures(\n                                    component = component,\n                                    activeLayer = activeLayer\n                                )\n                                .graphicsLayer {\n                                    compositingStrategy = CompositingStrategy.Offscreen\n                                },\n                            contentAlignment = Alignment.Center\n                        ) {\n                            Picture(\n                                model = imageBitmap,\n                                contentDescription = null,\n                                contentScale = ContentScale.FillBounds,\n                                modifier = Modifier\n                                    .matchParentSize()\n                                    .clipToBounds(),\n                                showTransparencyChecker = false\n                            )\n\n                            component.layers.forEachIndexed { index, layer ->\n                                Layer(\n                                    component = component,\n                                    layer = layer,\n                                    onActivate = {\n                                        component.activateLayer(layer)\n                                    },\n                                    onUpdateLayer = { updatedLayer, commitToHistory ->\n                                        component.updateLayerAt(\n                                            index = index,\n                                            layer = updatedLayer,\n                                            commitToHistory = commitToHistory\n                                        )\n                                    },\n                                    onShowContextOptions = {\n                                        requestContextOptions(true)\n                                    }\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        controls = {\n            Column(\n                modifier = Modifier.padding(16.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                if (!isPortrait) {\n                    MarkupLayersUndoRedo(\n                        component = component,\n                        color = Color.Unspecified,\n                        removePadding = false\n                    )\n                    Spacer(Modifier.height(4.dp))\n                }\n                val behavior = component.backgroundBehavior\n                if (behavior is BackgroundBehavior.Color) {\n                    ColorRowSelector(\n                        value = behavior.color.toColor(),\n                        onValueChange = component::updateBackgroundColor,\n                        icon = Icons.Outlined.BackgroundColor,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .container(\n                                shape = ShapeDefaults.extraLarge\n                            )\n                    )\n                }\n                SaveExifWidget(\n                    modifier = Modifier.fillMaxWidth(),\n                    checked = component.saveExif,\n                    imageFormat = component.imageFormat,\n                    onCheckedChange = component::setSaveExif\n                )\n                PreferenceItem(\n                    onClick = {\n                        projectSaver.make(component.createProjectFilename())\n                    },\n                    startIcon = Icons.Outlined.Archive,\n                    title = stringResource(R.string.save_markup_project),\n                    subtitle = stringResource(R.string.save_markup_project_sub),\n                    modifier = Modifier.fillMaxWidth(),\n                    shape = ShapeDefaults.large,\n                )\n                ImageFormatSelector(\n                    modifier = Modifier.navigationBarsPadding(),\n                    forceEnabled = component.backgroundBehavior is BackgroundBehavior.Color,\n                    value = component.imageFormat,\n                    onValueChange = component::setImageFormat\n                )\n            }\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.backgroundBehavior is BackgroundBehavior.None,\n                onSecondaryButtonClick = pickImage,\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                isSecondaryButtonVisible = component.backgroundBehavior !is BackgroundBehavior.Color,\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                isPrimaryButtonVisible = component.backgroundBehavior !is BackgroundBehavior.None,\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                },\n                showNullDataButtonAsContainer = true\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        enableNoDataScroll = false,\n        noDataControls = {\n            MarkupLayersNoDataControls(\n                component = component,\n                onPickImage = pickImage,\n                onOpenProject = projectOpener::pickFile\n            )\n        },\n        canShowScreenData = component.backgroundBehavior !is BackgroundBehavior.None,\n        mainContentWeight = 0.65f\n    )\n\n    MarkupLayersSideMenu(\n        component = component,\n        visible = showLayersSelection,\n        onDismiss = closeLayersSelection,\n        isContextOptionsVisible = isContextOptionsVisible,\n        onContextOptionsVisibleChange = { isContextOptionsVisible = it }\n    )\n\n    LoadingDialog(\n        visible = component.isSaving || component.isImageLoading,\n        onCancelLoading = component::cancelSaving,\n        canCancel = component.isSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = {\n            if (component.backgroundBehavior !is BackgroundBehavior.None) {\n                component.resetState()\n                themeState.updateColorTuple(appColorTuple)\n            } else component.onGoBack()\n        },\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/ActiveLayerGestureModifier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.gestures.calculateCentroidSize\nimport androidx.compose.foundation.gestures.calculatePan\nimport androidx.compose.foundation.gestures.calculateRotation\nimport androidx.compose.foundation.gestures.calculateZoom\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.input.pointer.positionChange\nimport androidx.compose.ui.input.pointer.positionChanged\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.applyGroupGlobalChanges\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.uiCornerRadiusPercent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\nimport kotlin.math.PI\nimport kotlin.math.abs\n\ninternal fun Modifier.activeLayerGestures(\n    component: MarkupLayersComponent,\n    activeLayer: UiMarkupLayer?\n): Modifier = pointerInput(activeLayer) {\n    activeLayer ?: return@pointerInput\n\n    awaitEachGesture {\n        activeLayer.state\n        var totalZoom = 1f\n        var totalRotation = 0f\n        var totalPan = Offset.Zero\n        var pastTouchSlop = false\n        val touchSlop = viewConfiguration.touchSlop\n\n        var down = awaitFirstDown(\n            pass = PointerEventPass.Initial,\n            requireUnconsumed = false\n        )\n        var activePointerId = down.id\n\n        do {\n            val event = awaitPointerEvent(pass = PointerEventPass.Initial)\n            val pressedChanges = event.changes.filter(PointerInputChange::pressed)\n            if (pressedChanges.isEmpty()) break\n\n            val activePointer = pressedChanges.firstOrNull { it.id == activePointerId }\n                ?: pressedChanges.first().also {\n                    activePointerId = it.id\n                }\n\n            val isMultiTouch = pressedChanges.size > 1\n            val panChange = if (isMultiTouch) {\n                event.calculatePan()\n            } else {\n                activePointer.positionChange()\n            }\n            val zoomChange = if (isMultiTouch) event.calculateZoom() else 1f\n            val rotationChange = if (isMultiTouch) event.calculateRotation() else 0f\n\n            if (!pastTouchSlop) {\n                totalPan += panChange\n                totalZoom *= zoomChange\n                totalRotation += rotationChange\n\n                val centroidSize = if (isMultiTouch) {\n                    event.calculateCentroidSize(useCurrent = false)\n                } else {\n                    0f\n                }\n                val zoomMotion = abs(1 - totalZoom) * centroidSize\n                val rotationMotion = abs(totalRotation * PI.toFloat() * centroidSize / 180f)\n                val panMotion = totalPan.getDistance()\n\n                if (zoomMotion > touchSlop ||\n                    rotationMotion > touchSlop ||\n                    panMotion > touchSlop\n                ) {\n                    component.beginHistoryTransaction()\n                    pastTouchSlop = true\n                }\n            }\n\n            if (pastTouchSlop) {\n                component.updateLayerState(\n                    layer = activeLayer,\n                    commitToHistory = false\n                ) {\n                    if (activeLayer.isGroup) {\n                        activeLayer.applyGroupGlobalChanges(\n                            zoomChange = zoomChange,\n                            offsetChange = panChange,\n                            rotationChange = rotationChange\n                        )\n                    } else {\n                        val contentSize = contentSize\n                        if (contentSize.width > 0 && contentSize.height > 0) {\n                            val canvasWidth = canvasSize.width.takeIf { it > 0 } ?: size.width\n                            val canvasHeight = canvasSize.height.takeIf { it > 0 } ?: size.height\n\n                            applyGlobalChanges(\n                                parentMaxWidth = canvasWidth,\n                                parentMaxHeight = canvasHeight,\n                                contentSize = contentSize,\n                                cornerRadiusPercent = activeLayer.uiCornerRadiusPercent(),\n                                zoomChange = zoomChange,\n                                offsetChange = panChange,\n                                rotationChange = rotationChange\n                            )\n                        }\n                    }\n                }\n\n                event.changes.forEach { change ->\n                    if (change.positionChanged()) {\n                        change.consume()\n                    }\n                }\n            }\n\n            down = activePointer\n            activePointerId = down.id\n        } while (true)\n\n        if (pastTouchSlop) {\n            component.commitHistoryTransaction()\n        }\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/AddShapeLayerDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.StarSticky\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ShapeMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.defaultMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.icon\n\n@Composable\ninternal fun AddShapeLayerDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onShapePicked: (ShapeMode) -> Unit\n) {\n    var selectedKindName by rememberSaveable(visible) {\n        mutableStateOf<String?>(null)\n    }\n\n    val selectedKind = selectedKindName?.let { raw ->\n        ShapeMode.Kind.entries.firstOrNull { it.name == raw }\n    }\n\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.StarSticky,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(stringResource(R.string.shape))\n        },\n        text = {\n            val state = rememberScrollState()\n\n            FlowRow(\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = 8.dp,\n                    alignment = Alignment.CenterHorizontally\n                ),\n                verticalArrangement = Arrangement.spacedBy(\n                    space = 8.dp,\n                    alignment = Alignment.CenterVertically\n                ),\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .verticalScroll(\n                        state = state,\n                        flingBehavior = enhancedFlingBehavior()\n                    )\n                    .fadingEdges(\n                        scrollableState = state,\n                        isVertical = true\n                    )\n            ) {\n                ShapeMode.Kind.entries.forEach { kind ->\n                    EnhancedChip(\n                        selected = selectedKind == kind,\n                        onClick = {\n                            selectedKindName = kind.name\n                        },\n                        selectedColor = MaterialTheme.colorScheme.tertiaryContainer,\n                        unselectedColor = MaterialTheme.colorScheme.surface,\n                        contentPadding = PaddingValues(\n                            horizontal = 12.dp,\n                            vertical = 8.dp\n                        ),\n                        label = {\n                            Icon(\n                                imageVector = kind.icon,\n                                contentDescription = null\n                            )\n                        }\n                    )\n                }\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                enabled = selectedKind != null,\n                onClick = {\n                    selectedKind?.let {\n                        onShapePicked(it.defaultMode())\n                    }\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(R.string.add))\n            }\n        }\n    )\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/AddTextLayerDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.TextSticky\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\n\n@Composable\ninternal fun AddTextLayerDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onAddLayer: (UiMarkupLayer) -> Unit\n) {\n    var dialogText by rememberSaveable(visible) {\n        mutableStateOf(\"\")\n    }\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.TextSticky,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(stringResource(R.string.text))\n        },\n        text = {\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                OutlinedTextField(\n                    shape = ShapeDefaults.default,\n                    value = dialogText,\n                    textStyle = MaterialTheme.typography.titleMedium.copy(\n                        textAlign = TextAlign.Center\n                    ),\n                    onValueChange = {\n                        dialogText = it\n                    }\n                )\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss,\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                enabled = dialogText.isNotEmpty(),\n                onClick = {\n                    onAddLayer(\n                        UiMarkupLayer(\n                            type = LayerType.Text.Default.copy(\n                                text = dialogText\n                            )\n                        )\n                    )\n                    onDismiss()\n                },\n            ) {\n                Text(stringResource(R.string.add))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/ClickableTile.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.gestures.waitForUpOrCancellation\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.PlainTooltip\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TooltipAnchorPosition\nimport androidx.compose.material3.TooltipBox\nimport androidx.compose.material3.TooltipDefaults\nimport androidx.compose.material3.rememberTooltipState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun ClickableTile(\n    onClick: () -> Unit,\n    icon: ImageVector,\n    text: String?,\n    enabled: Boolean = true,\n    containerColor: Color = MaterialTheme.colorScheme.surfaceContainerLow,\n    onHoldStep: (() -> Unit)? = null,\n    modifier: Modifier = Modifier\n) {\n    if (text != null) {\n        val tooltipState = rememberTooltipState()\n        TooltipBox(\n            positionProvider = TooltipDefaults.rememberTooltipPositionProvider(\n                TooltipAnchorPosition.Above\n            ),\n            tooltip = {\n                PlainTooltip {\n                    Text(text)\n                }\n            },\n            state = tooltipState\n        ) {\n            ClickableTile(\n                containerColor = containerColor,\n                onClick = onClick,\n                enabled = enabled,\n                onHoldStep = onHoldStep,\n                modifier = modifier\n            ) {\n                Icon(\n                    imageVector = icon,\n                    contentDescription = null\n                )\n            }\n        }\n    } else {\n        ClickableTile(\n            containerColor = containerColor,\n            onClick = onClick,\n            enabled = enabled,\n            onHoldStep = onHoldStep,\n            modifier = modifier\n        ) {\n            Icon(\n                imageVector = icon,\n                contentDescription = null\n            )\n        }\n    }\n}\n\n\n@Composable\ninternal fun ClickableTile(\n    onClick: () -> Unit,\n    enabled: Boolean = true,\n    containerColor: Color = MaterialTheme.colorScheme.surfaceContainerLow,\n    onHoldStep: (() -> Unit)? = null,\n    modifier: Modifier = Modifier,\n    content: @Composable ColumnScope.() -> Unit\n) {\n    val haptics = LocalHapticFeedback.current\n\n    val interactionModifier = if (!enabled) {\n        Modifier\n    } else if (onHoldStep != null) {\n        Modifier.pointerInput(onClick, onHoldStep) {\n            awaitEachGesture {\n                val down = awaitFirstDown(requireUnconsumed = false)\n                down.consume()\n\n                haptics.longPress()\n                onClick()\n\n                var repeatDelayMs = 140L\n                val minRepeatDelayMs = 45L\n\n                var up = withTimeoutOrNull(240L) {\n                    waitForUpOrCancellation()\n                }\n                if (up != null) {\n                    up.consume()\n                    return@awaitEachGesture\n                }\n\n                val holdStartNanos = System.nanoTime()\n                var stepsAccumulator = 0f\n                while (up == null) {\n                    val holdDurationMs = ((System.nanoTime() - holdStartNanos) / 1_000_000L)\n\n                    // Smoothly ramps average speed from 1 to 10 steps per tick.\n                    val progress = (holdDurationMs / 3000f).coerceIn(0f, 1f)\n                    val smoothStepsPerTick = 1f + 9f * progress\n                    stepsAccumulator += smoothStepsPerTick\n\n                    val stepsPerTick = stepsAccumulator.toInt().coerceIn(1, 20).also {\n                        stepsAccumulator -= it\n                    }\n                    repeat(stepsPerTick) {\n                        onHoldStep()\n                    }\n\n                    repeatDelayMs = (repeatDelayMs * 0.94f).toLong()\n                        .coerceAtLeast(minRepeatDelayMs)\n                    up = withTimeoutOrNull(repeatDelayMs) {\n                        waitForUpOrCancellation()\n                    }\n                }\n                up.consume()\n            }\n        }\n    } else {\n        Modifier.hapticsClickable(onClick = onClick)\n    }\n\n    Column(\n        modifier = Modifier\n            .then(\n                if (modifier == Modifier) {\n                    Modifier.size(\n                        width = 100.dp,\n                        height = 72.dp\n                    )\n                } else {\n                    modifier\n                }\n            )\n            .container(\n                shape = ShapeDefaults.extraSmall,\n                color = containerColor,\n                resultPadding = 0.dp\n            )\n            .alpha(if (enabled) 1f else 0.5f)\n            .then(interactionModifier)\n            .padding(6.dp),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally,\n        content = content\n    )\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/DropShadowSection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Shadow\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.DropShadow\n\n@Composable\ninternal fun DropShadowSection(\n    shadow: DropShadow?,\n    onShadowChange: (DropShadow?) -> Unit,\n    onShadowChangeContinuously: (DropShadow) -> Unit,\n    onContinuousEditFinished: () -> Unit,\n    shape: androidx.compose.ui.graphics.Shape = ShapeDefaults.large\n) {\n    var haveShadow by rememberSaveable(shadow != null) {\n        mutableStateOf(shadow != null)\n    }\n\n    LaunchedEffect(haveShadow, shadow) {\n        val desiredShadow = if (haveShadow) {\n            shadow ?: DropShadow.Default\n        } else null\n\n        if (shadow != desiredShadow) {\n            onShadowChange(desiredShadow)\n        }\n    }\n\n    PreferenceRowSwitch(\n        title = stringResource(R.string.add_shadow),\n        subtitle = stringResource(R.string.add_shadow_sub),\n        shape = shape,\n        containerColor = MaterialTheme.colorScheme.surface,\n        startIcon = Icons.Outlined.Shadow,\n        checked = haveShadow,\n        onClick = { haveShadow = it },\n        additionalContent = {\n            AnimatedVisibility(\n                visible = shadow != null,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                val resolvedShadow = shadow ?: DropShadow.Default\n\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    modifier = Modifier.padding(top = 16.dp)\n                ) {\n                    ColorRowSelector(\n                        value = resolvedShadow.color.toColor(),\n                        onValueChange = {\n                            onShadowChange(\n                                resolvedShadow.copy(\n                                    color = it.toArgb()\n                                )\n                            )\n                        },\n                        title = stringResource(R.string.shadow_color),\n                        modifier = Modifier.container(\n                            shape = ShapeDefaults.top,\n                            color = MaterialTheme.colorScheme.surfaceContainerLow\n                        )\n                    )\n                    EnhancedSliderItem(\n                        value = resolvedShadow.blurRadius,\n                        title = stringResource(R.string.blur_radius),\n                        internalStateTransformation = { it.roundToTwoDigits() },\n                        onValueChange = {\n                            onShadowChangeContinuously(\n                                resolvedShadow.copy(\n                                    blurRadius = it\n                                )\n                            )\n                        },\n                        onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                        valueRange = DropShadow.BlurRadiusRange,\n                        shape = ShapeDefaults.center,\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerLow\n                    )\n                    EnhancedSliderItem(\n                        value = resolvedShadow.offsetX,\n                        title = stringResource(R.string.offset_x),\n                        internalStateTransformation = { it.roundToTwoDigits() },\n                        onValueChange = {\n                            onShadowChangeContinuously(\n                                resolvedShadow.copy(\n                                    offsetX = it\n                                )\n                            )\n                        },\n                        onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                        valueRange = DropShadow.OffsetXRange,\n                        shape = ShapeDefaults.center,\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerLow\n                    )\n                    EnhancedSliderItem(\n                        value = resolvedShadow.offsetY,\n                        title = stringResource(R.string.offset_y),\n                        internalStateTransformation = { it.roundToTwoDigits() },\n                        onValueChange = {\n                            onShadowChangeContinuously(\n                                resolvedShadow.copy(\n                                    offsetY = it\n                                )\n                            )\n                        },\n                        onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                        valueRange = DropShadow.OffsetYRange,\n                        shape = ShapeDefaults.bottom,\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerLow\n                    )\n                }\n            }\n        }\n    )\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/EditBox.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.animateIntAsState\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.BoxWithConstraintsScope\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawWithCache\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.toRect\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.asComposePaint\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.imagetoolbox.core.data.image.utils.toPaint\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.other.AnimatedBorder\nimport kotlinx.coroutines.launch\n\n@Composable\nfun BoxWithConstraintsScope.EditBox(\n    state: EditBoxState,\n    onTap: () -> Unit,\n    modifier: Modifier = Modifier,\n    onLongTap: (() -> Unit)? = null,\n    cornerRadiusPercent: Int = 0,\n    blendingMode: BlendingMode = BlendingMode.SrcOver,\n    isInteractive: Boolean = true,\n    showSelectionBackground: Boolean = true,\n    content: @Composable BoxScope.() -> Unit\n) {\n    val parentSize by remember(constraints) {\n        derivedStateOf {\n            IntegerSize(\n                constraints.maxWidth,\n                constraints.maxHeight\n            )\n        }\n    }\n    EditBox(\n        modifier = modifier,\n        onTap = onTap,\n        onLongTap = onLongTap,\n        state = state,\n        parentSize = parentSize,\n        cornerRadiusPercent = cornerRadiusPercent,\n        blendingMode = blendingMode,\n        isInteractive = isInteractive,\n        showSelectionBackground = showSelectionBackground,\n        content = content\n    )\n}\n\n@Composable\nfun EditBox(\n    state: EditBoxState,\n    onTap: () -> Unit,\n    parentSize: IntegerSize,\n    modifier: Modifier = Modifier,\n    onLongTap: (() -> Unit)? = null,\n    cornerRadiusPercent: Int = 0,\n    blendingMode: BlendingMode = BlendingMode.SrcOver,\n    isInteractive: Boolean = true,\n    showSelectionBackground: Boolean = true,\n    content: @Composable BoxScope.() -> Unit\n) {\n    if (!state.isVisible) return\n\n    var contentSize by remember {\n        mutableStateOf(IntSize.Zero)\n    }\n\n    val parentMaxWidth = parentSize.width\n    val parentMaxHeight = parentSize.height\n\n    SideEffect {\n        state.canvasSize = parentSize\n    }\n\n    var needRecalculations by rememberSaveable(state.coerceToBounds, contentSize) {\n        mutableStateOf(state.coerceToBounds && contentSize != IntSize.Zero)\n    }\n\n    LaunchedEffect(needRecalculations) {\n        if (needRecalculations) {\n            state.applyChanges(\n                parentMaxWidth = parentMaxWidth,\n                parentMaxHeight = parentMaxHeight,\n                contentSize = contentSize,\n                cornerRadiusPercent = cornerRadiusPercent,\n                zoomChange = 1f,\n                offsetChange = Offset.Zero,\n                rotationChange = 0f\n            )\n            needRecalculations = false\n        }\n    }\n\n    val tapScale = remember { Animatable(1f) }\n    val scope = rememberCoroutineScope()\n    val haptics = LocalHapticFeedback.current\n    val animateTap = {\n        haptics.longPress()\n        scope.launch {\n            tapScale.animateTo(0.98f)\n            tapScale.animateTo(1.02f)\n            tapScale.animateTo(1f)\n        }\n    }\n\n    val borderAlpha by animateFloatAsState(if (state.isActive) 1f else 0f)\n    val shape = AutoCornersShape(\n        animateIntAsState(cornerRadiusPercent).value\n    )\n    val selectionBackgroundColor = MaterialTheme.colorScheme.primary.copy(\n        alpha = 0.2f * borderAlpha\n    )\n    val interactionModifier = if (isInteractive) {\n        Modifier.pointerInput(onTap, animateTap) {\n            detectTapGestures(\n                onLongPress = onLongTap?.let {\n                    {\n                        it()\n                        animateTap()\n                    }\n                }\n            ) {\n                onTap()\n                if (state.isActive) animateTap()\n            }\n        }\n    } else {\n        Modifier\n    }\n\n    Box(\n        modifier = modifier\n            .onSizeChanged {\n                contentSize = it\n                state.contentSize = it\n            }\n            .graphicsLayer(\n                scaleX = state.scale * if (state.isFlippedHorizontally) -1f else 1f,\n                scaleY = state.scale * if (state.isFlippedVertically) -1f else 1f,\n                rotationZ = state.rotation,\n                translationX = state.offset.x,\n                translationY = state.offset.y\n            )\n            .scale(tapScale.value)\n            .clip(shape)\n            .drawWithCache {\n                onDrawWithContent {\n                    if (showSelectionBackground && state.isActive && blendingMode == BlendingMode.SrcOver) {\n                        drawRect(selectionBackgroundColor)\n                    }\n                    drawContent()\n                }\n            }\n            .then(interactionModifier),\n        contentAlignment = Alignment.Center\n    ) {\n        Box(\n            Modifier\n                .layerBlendingMode(\n                    mode = blendingMode,\n                    alpha = state.alpha\n                )\n        ) {\n            content()\n        }\n        AnimatedBorder(\n            modifier = Modifier.matchParentSize(),\n            alpha = borderAlpha,\n            scale = state.scale,\n            shape = shape\n        )\n        if (state.isActive) {\n            Surface(\n                color = Color.Transparent,\n                modifier = Modifier.matchParentSize()\n            ) { }\n        }\n    }\n}\n\nprivate fun Modifier.layerBlendingMode(\n    mode: BlendingMode,\n    alpha: Float\n): Modifier {\n    val coercedAlpha = alpha.coerceIn(0f, 1f)\n\n    if (mode == BlendingMode.SrcOver) {\n        return if (coercedAlpha >= 0.999f) this else graphicsLayer {\n            this.alpha = coercedAlpha\n        }\n    }\n\n    return drawWithCache {\n        val paint = mode.toPaint().asComposePaint().apply {\n            this.alpha = coercedAlpha\n        }\n        onDrawWithContent {\n            drawContext.canvas.saveLayer(size.toRect(), paint)\n            drawContent()\n            drawContext.canvas.restore()\n        }\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/EditBoxState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.util.fastCoerceIn\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport kotlin.math.abs\nimport kotlin.math.absoluteValue\nimport kotlin.math.cos\nimport kotlin.math.max\nimport kotlin.math.min\nimport kotlin.math.sin\n\nclass EditBoxState(\n    scale: Float = 1f,\n    rotation: Float = 0f,\n    isFlippedHorizontally: Boolean = false,\n    isFlippedVertically: Boolean = false,\n    offset: Offset = Offset.Zero,\n    alpha: Float = 1f,\n    isActive: Boolean = false,\n    canvasSize: IntegerSize = IntegerSize.Zero,\n    contentSize: IntSize = IntSize.Zero,\n    isVisible: Boolean = true,\n    coerceToBounds: Boolean = true,\n    isInEditMode: Boolean = false,\n) {\n    fun copy(\n        scale: Float = this.scale,\n        rotation: Float = this.rotation,\n        isFlippedHorizontally: Boolean = this.isFlippedHorizontally,\n        isFlippedVertically: Boolean = this.isFlippedVertically,\n        offset: Offset = this.offset,\n        alpha: Float = this.alpha,\n        isActive: Boolean = this.isActive,\n        canvasSize: IntegerSize = this.canvasSize,\n        contentSize: IntSize = this.contentSize,\n        isVisible: Boolean = this.isVisible,\n        coerceToBounds: Boolean = this.coerceToBounds,\n        isInEditMode: Boolean = this.isInEditMode,\n    ): EditBoxState = EditBoxState(\n        scale = scale,\n        rotation = rotation,\n        isFlippedHorizontally = isFlippedHorizontally,\n        isFlippedVertically = isFlippedVertically,\n        offset = offset,\n        alpha = alpha,\n        isActive = isActive,\n        canvasSize = canvasSize,\n        contentSize = contentSize,\n        isVisible = isVisible,\n        coerceToBounds = coerceToBounds,\n        isInEditMode = isInEditMode\n    )\n\n    var isActive by mutableStateOf(isActive)\n        internal set\n\n    var isInEditMode by mutableStateOf(isInEditMode)\n        internal set\n\n    private val _isVisible = mutableStateOf(isVisible)\n\n    var isVisible: Boolean\n        get() = _isVisible.value\n        internal set(value) {\n            if (!value) {\n                isActive = false\n            }\n            _isVisible.value = value\n        }\n\n    fun activate() {\n        isActive = true\n    }\n\n    fun deactivate() {\n        isActive = false\n    }\n\n    internal fun applyChanges(\n        parentMaxWidth: Int,\n        parentMaxHeight: Int,\n        contentSize: IntSize,\n        cornerRadiusPercent: Int,\n        zoomChange: Float,\n        offsetChange: Offset,\n        rotationChange: Float\n    ) {\n        applyChangeSet(\n            parentMaxWidth = parentMaxWidth,\n            parentMaxHeight = parentMaxHeight,\n            contentSize = contentSize,\n            cornerRadiusPercent = cornerRadiusPercent,\n            zoomChange = zoomChange,\n            offsetChange = (offsetChange * scale).rotateBy(rotation),\n            rotationChange = rotationChange\n        )\n    }\n\n    internal fun applyGlobalChanges(\n        parentMaxWidth: Int,\n        parentMaxHeight: Int,\n        contentSize: IntSize,\n        cornerRadiusPercent: Int,\n        zoomChange: Float,\n        offsetChange: Offset,\n        rotationChange: Float\n    ) {\n        applyChangeSet(\n            parentMaxWidth = parentMaxWidth,\n            parentMaxHeight = parentMaxHeight,\n            contentSize = contentSize,\n            cornerRadiusPercent = cornerRadiusPercent,\n            zoomChange = zoomChange,\n            offsetChange = offsetChange,\n            rotationChange = rotationChange\n        )\n    }\n\n    private fun applyChangeSet(\n        parentMaxWidth: Int,\n        parentMaxHeight: Int,\n        contentSize: IntSize,\n        cornerRadiusPercent: Int,\n        zoomChange: Float,\n        offsetChange: Offset,\n        rotationChange: Float\n    ) {\n        rotation += rotationChange\n        val currentScale = scale\n        scale = coerceInteractiveScale(\n            currentScale = currentScale,\n            targetScale = currentScale * zoomChange,\n            minimumValue = SCALE_RANGE.start,\n            maximumValue = SCALE_RANGE.endInclusive\n        )\n\n        val halfExtents = contentSize.rotatedHalfExtents(\n            degrees = rotation,\n            cornerRadiusPercent = cornerRadiusPercent\n        )\n        val halfParentWidth = parentMaxWidth / 2f\n        val halfParentHeight = parentMaxHeight / 2f\n        val maxX = (halfParentWidth - halfExtents.x * scale).absoluteValue\n        val maxY = (halfParentHeight - halfExtents.y * scale).absoluteValue\n\n        offset = Offset(\n            x = (offset.x + offsetChange.x).coerceIn(-maxX, maxX, coerceToBounds),\n            y = (offset.y + offsetChange.y).coerceIn(-maxY, maxY, coerceToBounds),\n        )\n    }\n\n    private fun Float.coerceIn(\n        minimumValue: Float,\n        maximumValue: Float,\n        enable: Boolean\n    ) = if (enable) coerceIn(minimumValue, maximumValue) else this\n\n    var scale by mutableFloatStateOf(scale)\n        internal set\n\n    var rotation by mutableFloatStateOf(rotation)\n        internal set\n\n    var isFlippedHorizontally by mutableStateOf(isFlippedHorizontally)\n        internal set\n\n    var isFlippedVertically by mutableStateOf(isFlippedVertically)\n        internal set\n\n    var offset by mutableStateOf(offset)\n        internal set\n\n    var alpha by mutableFloatStateOf(alpha)\n        internal set\n\n    var coerceToBounds by mutableStateOf(coerceToBounds)\n        internal set\n\n    var contentSize by mutableStateOf(contentSize)\n        internal set\n\n    private val _canvasSize = mutableStateOf(IntegerSize.Zero)\n\n    init {\n        adjustByCanvasSize(canvasSize)\n    }\n\n    var canvasSize: IntegerSize\n        get() = _canvasSize.value\n        set(value) {\n            adjustByCanvasSize(value)\n        }\n\n    internal fun syncCanvasSize(\n        value: IntegerSize,\n        forceScaleAdjustment: Boolean = false\n    ) {\n        adjustByCanvasSize(\n            value = value,\n            forceScaleAdjustment = forceScaleAdjustment\n        )\n    }\n\n    private fun adjustByCanvasSize(\n        value: IntegerSize,\n        forceScaleAdjustment: Boolean = false\n    ) {\n        val previousCanvasSize = _canvasSize.value\n        if (previousCanvasSize == value) {\n            _canvasSize.value = value\n            return\n        }\n        if (previousCanvasSize != IntegerSize.Zero) {\n            val sx = value.width.toFloat() / previousCanvasSize.width\n            val sy = value.height.toFloat() / previousCanvasSize.height\n\n            offset = Offset(\n                x = offset.x * sx,\n                y = offset.y * sy\n            )\n\n            // Layers whose measured content did not depend on the canvas bounds\n            // need an explicit scale adjustment to preserve their visual size\n            // relative to the preview after canvas resize. Layers already capped\n            // by `sizeIn(max = canvas / 2)` will remeasure on their own.\n            if (\n                contentSize.isSpecified() && (\n                        forceScaleAdjustment || !contentSize.isBoundedByCanvas(previousCanvasSize)\n                        )\n            ) {\n                val scaledValue = scale * min(sx, sy)\n                scale = if (forceScaleAdjustment) {\n                    scaledValue.coerceAtMost(SCALE_RANGE.endInclusive)\n                } else {\n                    scaledValue.fastCoerceIn(\n                        minimumValue = SCALE_RANGE.start,\n                        maximumValue = SCALE_RANGE.endInclusive\n                    )\n                }\n            }\n        }\n        _canvasSize.value = value\n    }\n\n    internal fun normalizedPosition(\n        cornerRadiusPercent: Int\n    ): Offset? {\n        val contentSize = contentSize\n        val canvasWidth = canvasSize.width.takeIf { it > 0 } ?: return null\n        val canvasHeight = canvasSize.height.takeIf { it > 0 } ?: return null\n\n        if (contentSize.width <= 0 || contentSize.height <= 0) return null\n\n        val halfExtents = contentSize.rotatedHalfExtents(\n            degrees = rotation,\n            cornerRadiusPercent = cornerRadiusPercent\n        )\n\n        val halfWidth = halfExtents.x * scale\n        val halfHeight = halfExtents.y * scale\n        val layerWidth = halfWidth * 2f\n        val layerHeight = halfHeight * 2f\n        val left = canvasWidth / 2f + offset.x - halfWidth\n        val top = canvasHeight / 2f + offset.y - halfHeight\n\n        return Offset(\n            x = left.normalizeEdgeAware(\n                axisSize = canvasWidth.toFloat(),\n                layerSize = layerWidth\n            ),\n            y = top.normalizeEdgeAware(\n                axisSize = canvasHeight.toFloat(),\n                layerSize = layerHeight\n            )\n        )\n    }\n\n    internal fun setNormalizedPosition(\n        x: Float? = null,\n        y: Float? = null,\n        cornerRadiusPercent: Int\n    ) {\n        if (x == null && y == null) return\n\n        val contentSize = contentSize\n        val canvasWidth = canvasSize.width.takeIf { it > 0 } ?: return\n        val canvasHeight = canvasSize.height.takeIf { it > 0 } ?: return\n\n        if (contentSize.width <= 0 || contentSize.height <= 0) return\n\n        val halfExtents = contentSize.rotatedHalfExtents(\n            degrees = rotation,\n            cornerRadiusPercent = cornerRadiusPercent\n        )\n\n        val halfWidth = halfExtents.x * scale\n        val halfHeight = halfExtents.y * scale\n        val layerWidth = halfWidth * 2f\n        val layerHeight = halfHeight * 2f\n        val currentLeft = canvasWidth / 2f + offset.x - halfWidth\n        val currentTop = canvasHeight / 2f + offset.y - halfHeight\n\n        val targetLeft = x?.denormalizeEdgeAware(\n            axisSize = canvasWidth.toFloat(),\n            layerSize = layerWidth\n        ) ?: currentLeft\n        val targetTop = y?.denormalizeEdgeAware(\n            axisSize = canvasHeight.toFloat(),\n            layerSize = layerHeight\n        ) ?: currentTop\n        val targetOffset = Offset(\n            x = targetLeft - canvasWidth / 2f + halfWidth,\n            y = targetTop - canvasHeight / 2f + halfHeight\n        )\n\n        applyGlobalChanges(\n            parentMaxWidth = canvasWidth,\n            parentMaxHeight = canvasHeight,\n            contentSize = contentSize,\n            cornerRadiusPercent = cornerRadiusPercent,\n            zoomChange = 1f,\n            offsetChange = Offset(\n                x = targetOffset.x - offset.x,\n                y = targetOffset.y - offset.y\n            ),\n            rotationChange = 0f\n        )\n    }\n\n    internal fun setScalePrecisely(\n        targetScale: Float,\n        cornerRadiusPercent: Int\n    ) {\n        val contentSize = contentSize\n        val scale = coerceInteractiveScale(\n            currentScale = this.scale,\n            targetScale = targetScale,\n            minimumValue = SCALE_RANGE.start,\n            maximumValue = SCALE_RANGE.endInclusive\n        )\n\n        if (contentSize.width <= 0 || contentSize.height <= 0) {\n            this.scale = scale\n            return\n        }\n\n        val canvasWidth = canvasSize.width.takeIf { it > 0 } ?: contentSize.width\n        val canvasHeight = canvasSize.height.takeIf { it > 0 } ?: contentSize.height\n\n        applyGlobalChanges(\n            parentMaxWidth = canvasWidth,\n            parentMaxHeight = canvasHeight,\n            contentSize = contentSize,\n            cornerRadiusPercent = cornerRadiusPercent,\n            zoomChange = scale / this.scale.coerceAtLeast(0.0001f),\n            offsetChange = Offset.Zero,\n            rotationChange = 0f\n        )\n    }\n}\n\nprivate fun Float.normalizeEdgeAware(\n    axisSize: Float,\n    layerSize: Float\n): Float {\n    val safeAxisSize = axisSize.coerceAtLeast(1f)\n    val safeLayerSize = layerSize.coerceAtLeast(1f)\n    val maxInsideStart = safeAxisSize - safeLayerSize\n\n    return when {\n        maxInsideStart > 0f -> when {\n            this < 0f -> this / safeLayerSize\n            this + safeLayerSize > safeAxisSize -> 1f + (this - maxInsideStart) / safeLayerSize\n            else -> this / maxInsideStart\n        }\n\n        maxInsideStart == 0f -> when {\n            this < 0f -> this / safeLayerSize\n            this > 0f -> 1f + this / safeLayerSize\n            else -> 0f\n        }\n\n        else -> when {\n            this > 0f -> -this / safeLayerSize\n            this < maxInsideStart -> 1f + (maxInsideStart - this) / safeLayerSize\n            else -> this / maxInsideStart\n        }\n    }\n}\n\nprivate fun Float.denormalizeEdgeAware(\n    axisSize: Float,\n    layerSize: Float\n): Float {\n    val safeAxisSize = axisSize.coerceAtLeast(1f)\n    val safeLayerSize = layerSize.coerceAtLeast(1f)\n    val maxInsideStart = safeAxisSize - safeLayerSize\n\n    return when {\n        maxInsideStart > 0f -> when {\n            this < 0f -> this * safeLayerSize\n            this > 1f -> maxInsideStart + (this - 1f) * safeLayerSize\n            else -> this * maxInsideStart\n        }\n\n        maxInsideStart == 0f -> when {\n            this < 0f -> this * safeLayerSize\n            this > 1f -> (this - 1f) * safeLayerSize\n            else -> 0f\n        }\n\n        else -> when {\n            this < 0f -> -this * safeLayerSize\n            this > 1f -> maxInsideStart - (this - 1f) * safeLayerSize\n            else -> this * maxInsideStart\n        }\n    }\n}\n\nprivate fun IntSize.rotatedHalfExtents(\n    degrees: Float,\n    cornerRadiusPercent: Int\n): Offset {\n    val halfWidth = width / 2f\n    val halfHeight = height / 2f\n\n    val cornerRadiusPx = (\n            min(width, height) *\n                    (cornerRadiusPercent.coerceIn(0, 50) / 100f)\n            ).coerceIn(0f, min(halfWidth, halfHeight))\n\n    // Rounded rectangle can be represented as an inner rectangle expanded by a circle.\n    // This gives accurate support extents for collision checks in any rotation.\n    val innerHalfWidth = max(0f, halfWidth - cornerRadiusPx)\n    val innerHalfHeight = max(0f, halfHeight - cornerRadiusPx)\n\n    val radians = Math.toRadians(degrees.toDouble())\n    val cos = abs(cos(radians)).toFloat()\n    val sin = abs(sin(radians)).toFloat()\n\n    return Offset(\n        x = innerHalfWidth * cos + innerHalfHeight * sin + cornerRadiusPx,\n        y = innerHalfWidth * sin + innerHalfHeight * cos + cornerRadiusPx\n    )\n}\n\nprivate fun IntSize.isSpecified(): Boolean = width > 0 && height > 0\n\nprivate fun IntSize.isBoundedByCanvas(\n    canvasSize: IntegerSize,\n    tolerancePx: Int = 1\n): Boolean {\n    val maxWidth = canvasSize.width / 2\n    val maxHeight = canvasSize.height / 2\n\n    return width >= maxWidth - tolerancePx || height >= maxHeight - tolerancePx\n}\n\nprivate fun Offset.rotateBy(\n    angle: Float\n): Offset {\n    val angleInRadians = ROTATION_CONST * angle\n    val newX = x * cos(angleInRadians) - y * sin(angleInRadians)\n    val newY = x * sin(angleInRadians) + y * cos(angleInRadians)\n    return Offset(newX, newY)\n}\n\nprivate fun coerceInteractiveScale(\n    currentScale: Float,\n    targetScale: Float,\n    minimumValue: Float,\n    maximumValue: Float\n): Float {\n    val safeTargetScale = targetScale.coerceAtLeast(MIN_SCALE_EPSILON)\n\n    return when {\n        safeTargetScale >= minimumValue -> safeTargetScale.coerceAtMost(maximumValue)\n        currentScale < minimumValue -> safeTargetScale.coerceAtMost(maximumValue)\n        else -> minimumValue\n    }\n}\n\nprivate const val ROTATION_CONST = (Math.PI / 180f).toFloat()\nprivate const val MIN_SCALE_EPSILON = 0.0001f\nprivate val SCALE_RANGE = 0.1f..10f\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/EditLayerSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.FormatAlignLeft\nimport androidx.compose.material.icons.automirrored.rounded.FormatAlignRight\nimport androidx.compose.material.icons.outlined.BorderColor\nimport androidx.compose.material.icons.outlined.BorderStyle\nimport androidx.compose.material.icons.outlined.Percent\nimport androidx.compose.material.icons.outlined.Rectangle\nimport androidx.compose.material.icons.rounded.FormatAlignCenter\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.Outline\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.emoji.Emoji\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.BackgroundColor\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEditLarge\nimport com.t8rin.imagetoolbox.core.resources.icons.SkewMore\nimport com.t8rin.imagetoolbox.core.resources.icons.StackSticky\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiFont\nimport com.t8rin.imagetoolbox.core.ui.theme.inverseByLuma\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.BlendingModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FontSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.EmojiSelectionSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextFieldColors\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.DomainTextDecoration\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType.Text.Alignment\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.TextGeometricTransform\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.icon\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.titleRes\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.withCoerceToBoundsRecursively\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun EditLayerSheet(\n    component: MarkupLayersComponent,\n    visible: Boolean,\n    onDismiss: (Boolean) -> Unit,\n    onUpdateLayer: (UiMarkupLayer, Boolean) -> Unit,\n    layer: UiMarkupLayer\n) {\n    val updateLayerWithHistory: (UiMarkupLayer) -> Unit = {\n        onUpdateLayer(it, true)\n    }\n    val updateLayerContinuously: (UiMarkupLayer) -> Unit = {\n        component.beginHistoryTransaction()\n        onUpdateLayer(it, false)\n    }\n    val finishContinuousEdit = component::commitHistoryTransaction\n\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = onDismiss,\n        title = {\n            if (layer.isGroup) {\n                TitleItem(\n                    icon = Icons.Outlined.StackSticky,\n                    text = stringResource(R.string.edit_layer)\n                )\n            } else when (val type = layer.type) {\n                is LayerType.Picture -> {\n                    TitleItem(\n                        icon = Icons.Rounded.MiniEditLarge,\n                        text = stringResource(R.string.edit_layer)\n                    )\n                }\n\n                is LayerType.Text -> {\n                    Row {\n                        DomainTextDecoration.entries.forEach { decoration ->\n                            EnhancedIconButton(\n                                onClick = {\n                                    updateLayerWithHistory(\n                                        layer.copy(\n                                            type = type.copy(\n                                                decorations = type.decorations.toggle(decoration)\n                                            )\n                                        )\n                                    )\n                                },\n                                containerColor = takeColorFromScheme {\n                                    if (decoration in type.decorations) secondaryContainer else surface\n                                },\n                                contentColor = takeColorFromScheme {\n                                    if (decoration in type.decorations) onSecondaryContainer else onSurface\n                                }\n                            ) {\n                                Icon(\n                                    imageVector = decoration.icon,\n                                    contentDescription = null\n                                )\n                            }\n                        }\n                    }\n                }\n\n                is LayerType.Shape -> {\n                    TitleItem(\n                        icon = type.shapeMode.kind.icon,\n                        text = stringResource(type.shapeMode.kind.titleRes)\n                    )\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    onDismiss(false)\n                }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(16.dp)\n        ) {\n            if (!layer.isGroup) {\n                when (val type = layer.type) {\n                    is LayerType.Text -> {\n                        RoundedTextField(\n                            value = type.text,\n                            onValueChange = {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            text = it\n                                        )\n                                    )\n                                )\n                            },\n                            hint = stringResource(R.string.text),\n                            colors = RoundedTextFieldColors(\n                                isError = false,\n                                containerColor = SafeLocalContainerColor\n                            ),\n                            modifier = Modifier.container(\n                                shape = ShapeDefaults.top,\n                                color = MaterialTheme.colorScheme.surface,\n                                resultPadding = 8.dp\n                            ),\n                            keyboardOptions = KeyboardOptions(),\n                            singleLine = false\n                        )\n                        Spacer(Modifier.height(4.dp))\n                        EnhancedButtonGroup(\n                            modifier = Modifier\n                                .container(\n                                    shape = ShapeDefaults.bottom,\n                                    color = MaterialTheme.colorScheme.surface\n                                ),\n                            title = stringResource(id = R.string.alignment),\n                            entries = Alignment.entries,\n                            value = type.alignment,\n                            onValueChange = {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(alignment = it)\n                                    )\n                                )\n                            },\n                            itemContent = {\n                                Icon(\n                                    imageVector = when (it) {\n                                        Alignment.Start -> Icons.AutoMirrored.Rounded.FormatAlignLeft\n                                        Alignment.Center -> Icons.Rounded.FormatAlignCenter\n                                        Alignment.End -> Icons.AutoMirrored.Rounded.FormatAlignRight\n                                    },\n                                    contentDescription = null\n                                )\n                            },\n                            activeButtonColor = MaterialTheme.colorScheme.secondaryContainer,\n                            inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                            isScrollable = false\n                        )\n                        Spacer(Modifier.height(8.dp))\n                        FontSelector(\n                            value = type.font.toUiFont(),\n                            onValueChange = {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            font = it.type\n                                        )\n                                    )\n                                )\n                            },\n                            shape = ShapeDefaults.top,\n                            containerColor = MaterialTheme.colorScheme.surface\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        EnhancedSliderItem(\n                            value = type.size,\n                            title = stringResource(R.string.font_scale),\n                            internalStateTransformation = {\n                                it.roundToTwoDigits()\n                            },\n                            onValueChange = {\n                                updateLayerContinuously(\n                                    layer.copy(\n                                        type = type.copy(size = it)\n                                    )\n                                )\n                            },\n                            onValueChangeFinished = { _ -> finishContinuousEdit() },\n                            valueRange = 0.01f..1f,\n                            shape = ShapeDefaults.center,\n                            containerColor = MaterialTheme.colorScheme.surface\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        ColorRowSelector(\n                            value = type.backgroundColor.toColor(),\n                            onValueChange = {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            backgroundColor = it.toArgb()\n                                        )\n                                    )\n                                )\n                            },\n                            title = stringResource(R.string.background_color),\n                            icon = Icons.Outlined.BackgroundColor,\n                            modifier = Modifier.container(\n                                shape = ShapeDefaults.center,\n                                color = MaterialTheme.colorScheme.surface\n                            )\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        ColorRowSelector(\n                            value = type.color.toColor(),\n                            onValueChange = {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            color = it.toArgb()\n                                        )\n                                    )\n                                )\n                            },\n                            title = stringResource(R.string.text_color),\n                            modifier = Modifier.container(\n                                shape = ShapeDefaults.center,\n                                color = MaterialTheme.colorScheme.surface\n                            )\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        var haveTextGeometry by remember {\n                            mutableStateOf(type.geometricTransform != null)\n                        }\n                        LaunchedEffect(haveTextGeometry, type.geometricTransform) {\n                            val desiredGeometricTransform = if (haveTextGeometry) {\n                                type.geometricTransform ?: TextGeometricTransform()\n                            } else null\n\n                            if (type.geometricTransform != desiredGeometricTransform) {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            geometricTransform = desiredGeometricTransform\n                                        )\n                                    )\n                                )\n                            }\n                        }\n\n                        PreferenceRowSwitch(\n                            title = stringResource(R.string.text_geometry),\n                            subtitle = stringResource(R.string.text_geometry_sub),\n                            shape = ShapeDefaults.center,\n                            containerColor = MaterialTheme.colorScheme.surface,\n                            startIcon = Icons.Outlined.SkewMore,\n                            checked = haveTextGeometry,\n                            onClick = {\n                                haveTextGeometry = it\n                            },\n                            additionalContent = {\n                                AnimatedVisibility(\n                                    visible = type.geometricTransform != null,\n                                    modifier = Modifier.fillMaxWidth()\n                                ) {\n                                    Column(\n                                        verticalArrangement = Arrangement.spacedBy(4.dp),\n                                        modifier = Modifier.padding(top = 16.dp)\n                                    ) {\n                                        EnhancedSliderItem(\n                                            value = type.geometricTransform?.scaleX ?: 1f,\n                                            title = stringResource(R.string.scale_x),\n                                            internalStateTransformation = {\n                                                it.roundToTwoDigits()\n                                            },\n                                            onValueChange = {\n                                                updateLayerContinuously(\n                                                    layer.copy(\n                                                        type = type.copy(\n                                                            geometricTransform = type.geometricTransform?.copy(\n                                                                scaleX = it\n                                                            )\n                                                        )\n                                                    )\n                                                )\n                                            },\n                                            onValueChangeFinished = { _ -> finishContinuousEdit() },\n                                            valueRange = 0.25f..3f,\n                                            shape = ShapeDefaults.top,\n                                            containerColor = MaterialTheme.colorScheme.surfaceContainerLow\n                                        )\n                                        EnhancedSliderItem(\n                                            value = type.geometricTransform?.skewX ?: 0f,\n                                            title = stringResource(R.string.skew_x),\n                                            internalStateTransformation = {\n                                                it.roundToTwoDigits()\n                                            },\n                                            onValueChange = {\n                                                updateLayerContinuously(\n                                                    layer.copy(\n                                                        type = type.copy(\n                                                            geometricTransform = type.geometricTransform?.copy(\n                                                                skewX = it\n                                                            )\n                                                        )\n                                                    )\n                                                )\n                                            },\n                                            onValueChangeFinished = { _ -> finishContinuousEdit() },\n                                            valueRange = -1.5f..1.5f,\n                                            shape = ShapeDefaults.bottom,\n                                            containerColor = MaterialTheme.colorScheme.surfaceContainerLow\n                                        )\n                                    }\n                                }\n                            }\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        DropShadowSection(\n                            shadow = type.shadow,\n                            onShadowChange = { shadow ->\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            shadow = shadow\n                                        )\n                                    )\n                                )\n                            },\n                            onShadowChangeContinuously = { shadow ->\n                                updateLayerContinuously(\n                                    layer.copy(\n                                        type = type.copy(\n                                            shadow = shadow\n                                        )\n                                    )\n                                )\n                            },\n                            onContinuousEditFinished = finishContinuousEdit,\n                            shape = ShapeDefaults.center\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        var haveOutline by remember {\n                            mutableStateOf(type.outline != null)\n                        }\n                        LaunchedEffect(haveOutline, type.outline, type.color) {\n                            val desiredOutline = if (haveOutline) {\n                                type.outline ?: Outline(\n                                    color = type.color.toColor()\n                                        .inverseByLuma()\n                                        .toArgb(),\n                                    width = 4f\n                                )\n                            } else null\n\n                            if (type.outline != desiredOutline) {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            outline = desiredOutline\n                                        )\n                                    )\n                                )\n                            }\n                        }\n\n                        PreferenceRowSwitch(\n                            title = stringResource(R.string.add_outline),\n                            subtitle = stringResource(R.string.add_outline_sub),\n                            shape = ShapeDefaults.bottom,\n                            containerColor = MaterialTheme.colorScheme.surface,\n                            startIcon = Icons.Outlined.BorderStyle,\n                            checked = haveOutline,\n                            onClick = {\n                                haveOutline = it\n                            },\n                            additionalContent = {\n                                AnimatedVisibility(\n                                    visible = type.outline != null,\n                                    modifier = Modifier.fillMaxWidth()\n                                ) {\n                                    Column(\n                                        verticalArrangement = Arrangement.spacedBy(4.dp),\n                                        modifier = Modifier.padding(top = 16.dp)\n                                    ) {\n                                        ColorRowSelector(\n                                            value = type.outline?.color?.toColor()\n                                                ?: Color.Transparent,\n                                            onValueChange = {\n                                                updateLayerWithHistory(\n                                                    layer.copy(\n                                                        type = type.copy(\n                                                            outline = type.outline?.copy(\n                                                                color = it.toArgb()\n                                                            )\n                                                        )\n                                                    )\n                                                )\n                                            },\n                                            title = stringResource(R.string.outline_color),\n                                            modifier = Modifier.container(\n                                                shape = ShapeDefaults.top,\n                                                color = MaterialTheme.colorScheme.surfaceContainerLow\n                                            ),\n                                            icon = Icons.Outlined.BorderColor\n                                        )\n                                        EnhancedSliderItem(\n                                            value = type.outline?.width ?: 0.2f,\n                                            title = stringResource(R.string.outline_size),\n                                            internalStateTransformation = {\n                                                it.roundToTwoDigits()\n                                            },\n                                            onValueChange = {\n                                                updateLayerContinuously(\n                                                    layer.copy(\n                                                        type = type.copy(\n                                                            outline = type.outline?.copy(\n                                                                width = it\n                                                            )\n                                                        )\n                                                    )\n                                                )\n                                            },\n                                            onValueChangeFinished = { _ -> finishContinuousEdit() },\n                                            valueRange = 0.01f..10f,\n                                            shape = ShapeDefaults.bottom,\n                                            containerColor = MaterialTheme.colorScheme.surfaceContainerLow\n                                        )\n                                    }\n                                }\n                            }\n                        )\n                    }\n\n                    is LayerType.Shape -> {\n                        ShapeLayerParamsSelector(\n                            layer = layer,\n                            type = type,\n                            onUpdateLayer = updateLayerWithHistory,\n                            onUpdateLayerContinuously = updateLayerContinuously,\n                            onContinuousEditFinished = finishContinuousEdit\n                        )\n                    }\n\n                    is LayerType.Picture.Image -> {\n                        ImageSelector(\n                            value = type.imageData,\n                            onValueChange = {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            imageData = it\n                                        )\n                                    )\n                                )\n                            },\n                            subtitle = null,\n                            color = MaterialTheme.colorScheme.surface\n                        )\n                        Spacer(modifier = Modifier.height(4.dp))\n                        DropShadowSection(\n                            shadow = type.shadow,\n                            onShadowChange = { shadow ->\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            shadow = shadow\n                                        )\n                                    )\n                                )\n                            },\n                            onShadowChangeContinuously = { shadow ->\n                                updateLayerContinuously(\n                                    layer.copy(\n                                        type = type.copy(\n                                            shadow = shadow\n                                        )\n                                    )\n                                )\n                            },\n                            onContinuousEditFinished = finishContinuousEdit\n                        )\n                    }\n\n                    is LayerType.Picture.Sticker -> {\n                        var showEmojiPicker by rememberSaveable {\n                            mutableStateOf(false)\n                        }\n\n                        PreferenceItemOverload(\n                            title = stringResource(R.string.change_sticker),\n                            subtitle = null,\n                            onClick = {\n                                showEmojiPicker = true\n                            },\n                            startIcon = {\n                                Picture(\n                                    model = type.imageData,\n                                    contentPadding = PaddingValues(8.dp),\n                                    shape = MaterialStarShape,\n                                    modifier = Modifier.size(48.dp),\n                                    error = {\n                                        Icon(\n                                            imageVector = Icons.Outlined.AddPhotoAlt,\n                                            contentDescription = null,\n                                            modifier = Modifier\n                                                .fillMaxSize()\n                                                .clip(MaterialStarShape)\n                                                .background(\n                                                    color = MaterialTheme.colorScheme.secondaryContainer.copy(\n                                                        0.5f\n                                                    )\n                                                )\n                                                .padding(8.dp)\n                                        )\n                                    }\n                                )\n                            },\n                            endIcon = {\n                                Icon(\n                                    imageVector = Icons.Rounded.MiniEdit,\n                                    contentDescription = stringResource(R.string.edit)\n                                )\n                            },\n                            modifier = Modifier.fillMaxWidth(),\n                            shape = ShapeDefaults.large,\n                            containerColor = MaterialTheme.colorScheme.surface,\n                            drawStartIconContainer = false\n                        )\n\n                        Spacer(modifier = Modifier.height(4.dp))\n                        DropShadowSection(\n                            shadow = type.shadow,\n                            onShadowChange = { shadow ->\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            shadow = shadow\n                                        )\n                                    )\n                                )\n                            },\n                            onShadowChangeContinuously = { shadow ->\n                                updateLayerContinuously(\n                                    layer.copy(\n                                        type = type.copy(\n                                            shadow = shadow\n                                        )\n                                    )\n                                )\n                            },\n                            onContinuousEditFinished = finishContinuousEdit\n                        )\n\n                        val allEmojis = Emoji.allIcons()\n\n                        EmojiSelectionSheet(\n                            selectedEmojiIndex = null,\n                            allEmojis = allEmojis,\n                            onEmojiPicked = {\n                                updateLayerWithHistory(\n                                    layer.copy(\n                                        type = type.copy(\n                                            imageData = allEmojis[it]\n                                        )\n                                    )\n                                )\n                                showEmojiPicker = false\n                            },\n                            visible = showEmojiPicker,\n                            onDismiss = {\n                                showEmojiPicker = false\n                            }\n                        )\n                    }\n                }\n                Spacer(modifier = Modifier.height(8.dp))\n            }\n            PreferenceRowSwitch(\n                title = stringResource(R.string.coerce_points_to_image_bounds),\n                subtitle = stringResource(R.string.coerce_points_to_image_bounds_sub),\n                startIcon = Icons.Outlined.Rectangle,\n                checked = layer.state.coerceToBounds,\n                onClick = {\n                    updateLayerWithHistory(\n                        layer.withCoerceToBoundsRecursively(it)\n                    )\n                },\n                shape = if (layer.isGroup) ShapeDefaults.large else ShapeDefaults.top,\n                modifier = Modifier.fillMaxWidth(),\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            if (!layer.isGroup) {\n                Spacer(modifier = Modifier.height(4.dp))\n                AlphaSelector(\n                    value = layer.state.alpha,\n                    onValueChange = {\n                        component.beginHistoryTransaction()\n                        component.updateLayerState(\n                            layer = layer,\n                            commitToHistory = false\n                        ) {\n                            alpha = it\n                        }\n                    },\n                    onValueChangeFinished = { _ ->\n                        finishContinuousEdit()\n                    },\n                    modifier = Modifier.fillMaxWidth(),\n                    title = stringResource(R.string.layer_alpha),\n                    color = MaterialTheme.colorScheme.surface,\n                    shape = ShapeDefaults.center\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                BlendingModeSelector(\n                    value = layer.blendingMode,\n                    onValueChange = {\n                        updateLayerWithHistory(\n                            layer.copy(blendingMode = it)\n                        )\n                    },\n                    modifier = Modifier.fillMaxWidth(),\n                    color = MaterialTheme.colorScheme.surface,\n                    shape = if (layer.type is LayerType.Shape) {\n                        ShapeDefaults.bottom\n                    } else {\n                        ShapeDefaults.center\n                    }\n                )\n                if (layer.type !is LayerType.Shape) {\n                    Spacer(modifier = Modifier.height(4.dp))\n                    EnhancedSliderItem(\n                        value = layer.cornerRadiusPercent,\n                        title = stringResource(R.string.corners_size),\n                        icon = Icons.Outlined.Percent,\n                        internalStateTransformation = {\n                            it.roundToInt()\n                        },\n                        onValueChange = {\n                            updateLayerContinuously(\n                                layer.copy(\n                                    cornerRadiusPercent = it.roundToInt().coerceIn(0, 50)\n                                )\n                            )\n                        },\n                        onValueChangeFinished = { _ -> finishContinuousEdit() },\n                        valueRange = 0f..50f,\n                        steps = 49,\n                        shape = ShapeDefaults.bottom,\n                        containerColor = MaterialTheme.colorScheme.surface\n                    )\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/Layer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraintsScope\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.canvasLeafLayers\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.groupContentSize\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.renderCopy\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.uiCornerRadiusPercent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\n\n@Composable\ninternal fun BoxWithConstraintsScope.Layer(\n    component: MarkupLayersComponent?,\n    layer: UiMarkupLayer,\n    onActivate: (() -> Unit)?,\n    onShowContextOptions: (() -> Unit)?,\n    onUpdateLayer: ((UiMarkupLayer, Boolean) -> Unit)?,\n    referenceSizeOverride: Int? = null\n) {\n    val canEditLayer = onUpdateLayer != null && component != null\n\n    if (layer.isGroup) {\n        GroupLayer(\n            component = component,\n            layer = layer,\n            onActivate = onActivate,\n            onShowContextOptions = onShowContextOptions,\n            onUpdateLayer = onUpdateLayer,\n            canEditLayer = canEditLayer\n        )\n        return\n    }\n\n    val type = layer.type\n    val cornerRadiusPercent = layer.uiCornerRadiusPercent()\n    val isInteractive = !layer.isLocked && onActivate != null\n\n    EditBox(\n        state = layer.state,\n        cornerRadiusPercent = cornerRadiusPercent,\n        blendingMode = layer.blendingMode,\n        isInteractive = isInteractive,\n        onTap = {\n            if (layer.state.isActive && canEditLayer) {\n                layer.state.isInEditMode = true\n            } else {\n                onActivate?.invoke()\n            }\n        },\n        onLongTap = {\n            if (!layer.state.isActive) {\n                onActivate?.invoke()\n            }\n            onShowContextOptions?.invoke()\n        },\n        content = {\n            val measuredContentSize = layer.state.contentSize\n            val density = LocalDensity.current\n            val contentModifier = when {\n                measuredContentSize.width > 0 &&\n                        measuredContentSize.height > 0 &&\n                        (layer.isGroup || onUpdateLayer == null) -> Modifier.requiredSize(\n                    width = with(density) { measuredContentSize.width.toDp() },\n                    height = with(density) { measuredContentSize.height.toDp() }\n                )\n\n                layer.isGroup || type is LayerType.Text -> Modifier.sizeIn(\n                    maxWidth = this@Layer.maxWidth,\n                    maxHeight = this@Layer.maxHeight\n                )\n\n                else -> {\n                    Modifier.sizeIn(\n                        maxWidth = this@Layer.maxWidth / 2,\n                        maxHeight = this@Layer.maxHeight / 2\n                    )\n                }\n            }\n\n            LayerContent(\n                modifier = contentModifier,\n                type = type,\n                groupedLayers = layer.groupedLayers,\n                textFullSize = referenceSizeOverride\n                    ?: this@Layer.constraints.run { minOf(maxWidth, maxHeight) },\n                cornerRadiusPercent = cornerRadiusPercent,\n                onTextLayout = if (layer.type is LayerType.Text && onUpdateLayer != null) {\n                    { result ->\n                        val visibleLineCount = if (result.didOverflowHeight) {\n                            (0 until result.lineCount).count { lineIndex ->\n                                result.getLineBottom(lineIndex) <= result.size.height\n                            }\n                        } else {\n                            result.lineCount\n                        }\n\n                        if (visibleLineCount > 0 && layer.visibleLineCount != visibleLineCount) {\n                            onUpdateLayer(\n                                layer.copy(visibleLineCount = visibleLineCount),\n                                false\n                            )\n                        }\n                    }\n                } else null\n            )\n        }\n    )\n\n    if (canEditLayer) {\n        EditLayerSheet(\n            component = component,\n            visible = layer.state.isInEditMode && !layer.isLocked,\n            onDismiss = { layer.state.isInEditMode = it },\n            onUpdateLayer = onUpdateLayer,\n            layer = layer\n        )\n    }\n}\n\n@Composable\nprivate fun BoxWithConstraintsScope.GroupLayer(\n    component: MarkupLayersComponent?,\n    layer: UiMarkupLayer,\n    onActivate: (() -> Unit)?,\n    onShowContextOptions: (() -> Unit)?,\n    onUpdateLayer: ((UiMarkupLayer, Boolean) -> Unit)?,\n    canEditLayer: Boolean\n) {\n    val density = LocalDensity.current\n    val parentCanvasSize = IntegerSize(\n        width = constraints.maxWidth,\n        height = constraints.maxHeight\n    )\n    val activateGroup = if (!layer.isLocked && onActivate != null) {\n        {\n            if (layer.state.isActive && canEditLayer) {\n                layer.state.isInEditMode = true\n            } else {\n                onActivate()\n            }\n        }\n    } else null\n\n    val leafLayers = layer.canvasLeafLayers(canvasSize = parentCanvasSize)\n\n    leafLayers.forEach { child ->\n        val renderedChild = child.renderCopy().let { renderCopy ->\n            if (layer.state.isActive) {\n                renderCopy.copy(\n                    state = renderCopy.state.copy(\n                        isActive = true\n                    )\n                )\n            } else renderCopy\n        }\n        Layer(\n            component = null,\n            layer = renderedChild,\n            onActivate = null,\n            onShowContextOptions = null,\n            onUpdateLayer = null\n        )\n    }\n\n    if (!layer.isLocked && (activateGroup != null || onShowContextOptions != null)) {\n        leafLayers.forEach { child ->\n            val hitContentSize = child.state.contentSize\n                .takeIf(IntSize::isSpecified)\n                ?: IntSize(1, 1)\n\n            EditBox(\n                state = child.state.copy(\n                    isActive = false,\n                    isInEditMode = false\n                ),\n                cornerRadiusPercent = child.uiCornerRadiusPercent(),\n                isInteractive = true,\n                showSelectionBackground = false,\n                onTap = {\n                    activateGroup?.invoke()\n                },\n                onLongTap = {\n                    if (!layer.state.isActive) {\n                        activateGroup?.invoke()\n                    }\n                    onShowContextOptions?.invoke()\n                }\n            ) {\n                Box(\n                    modifier = Modifier.requiredSize(\n                        width = with(density) { hitContentSize.width.toDp() },\n                        height = with(density) { hitContentSize.height.toDp() }\n                    )\n                )\n            }\n        }\n    }\n\n    val measuredContentSize = layer.groupContentSize()\n        ?.takeIf { it.isSpecified() }\n        ?: layer.state.contentSize.takeIf { it.isSpecified() }\n        ?: IntSize(1, 1)\n\n    SideEffect {\n        layer.state.syncCanvasSize(\n            value = parentCanvasSize,\n            forceScaleAdjustment = true\n        )\n        if (layer.state.contentSize != measuredContentSize) {\n            layer.state.contentSize = measuredContentSize\n        }\n    }\n\n    if (canEditLayer && component != null && onUpdateLayer != null) {\n        EditLayerSheet(\n            component = component,\n            visible = layer.state.isInEditMode && !layer.isLocked,\n            onDismiss = { layer.state.isInEditMode = it },\n            onUpdateLayer = onUpdateLayer,\n            layer = layer\n        )\n    }\n}\n\nprivate fun IntSize.isSpecified(): Boolean = width > 0 && height > 0\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/LayerContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawWithCache\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.font.FontStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.text.style.TextDecoration\nimport androidx.compose.ui.unit.dp\nimport androidx.core.graphics.withSave\nimport coil3.request.ImageRequest\nimport coil3.request.allowHardware\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.static\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiFont\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.text.OutlineParams\nimport com.t8rin.imagetoolbox.core.ui.widget.text.OutlinedText\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.buildPictureShadowRenderData\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.buildShapeShadowRenderData\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.buildTextShadowRenderData\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.calculateShadowPadding\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.calculateTextLayerMetrics\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.drawShapeLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.utils.resolveShapeLayerRenderData\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.DomainTextDecoration\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.renderCopy\nimport kotlin.math.roundToInt\nimport androidx.compose.ui.text.style.TextGeometricTransform as ComposeTextGeometricTransform\n\n@Composable\ninternal fun LayerContent(\n    modifier: Modifier = Modifier,\n    type: LayerType,\n    groupedLayers: List<UiMarkupLayer> = emptyList(),\n    textFullSize: Int,\n    maxLines: Int = Int.MAX_VALUE,\n    cornerRadiusPercent: Int = 0,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null\n) {\n    if (groupedLayers.isNotEmpty()) {\n        GroupLayerContent(\n            modifier = modifier,\n            groupedLayers = groupedLayers,\n            referenceSize = textFullSize\n        )\n    } else {\n        when (type) {\n            is LayerType.Picture -> PictureLayerContent(\n                modifier = modifier,\n                type = type,\n                cornerRadiusPercent = cornerRadiusPercent\n            )\n\n            is LayerType.Text -> TextLayerContent(\n                modifier = modifier,\n                type = type,\n                textFullSize = textFullSize,\n                maxLines = maxLines,\n                onTextLayout = onTextLayout\n            )\n\n            is LayerType.Shape -> ShapeLayerContent(\n                modifier = modifier,\n                type = type,\n                textFullSize = textFullSize\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun GroupLayerContent(\n    modifier: Modifier,\n    groupedLayers: List<UiMarkupLayer>,\n    referenceSize: Int\n) {\n    val renderLayers = remember(groupedLayers) {\n        groupedLayers.map(UiMarkupLayer::renderCopy)\n    }\n\n    BoxWithConstraints(\n        modifier = modifier,\n        contentAlignment = Alignment.Center\n    ) {\n        renderLayers.forEach { layer ->\n            Layer(\n                component = null,\n                layer = layer,\n                onActivate = null,\n                onShowContextOptions = null,\n                onUpdateLayer = null,\n                referenceSizeOverride = referenceSize\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun ShapeLayerContent(\n    modifier: Modifier,\n    type: LayerType.Shape,\n    textFullSize: Int\n) {\n    val density = LocalDensity.current\n    val shapeContentInsetPx = with(density) { 4.dp.toPx() }\n    BoxWithConstraints(\n        modifier = modifier,\n        contentAlignment = Alignment.Center\n    ) {\n        val renderData = remember(\n            type,\n            textFullSize,\n            constraints.maxWidth,\n            constraints.maxHeight,\n            shapeContentInsetPx\n        ) {\n            resolveShapeLayerRenderData(\n                type = type,\n                referenceSize = textFullSize.toFloat(),\n                maxWidth = constraints.maxWidth.toFloat(),\n                maxHeight = constraints.maxHeight.toFloat(),\n                contentInsetPx = shapeContentInsetPx\n            )\n        }\n\n        Box(\n            modifier = Modifier\n                .requiredSize(\n                    width = with(density) { renderData.width.toDp() },\n                    height = with(density) { renderData.height.toDp() }\n                )\n                .drawWithCache {\n                    val shadow = buildShapeShadowRenderData(\n                        type = type,\n                        data = renderData\n                    )\n\n                    onDrawWithContent {\n                        shadow?.let { shadowData ->\n                            drawContext.canvas.nativeCanvas.drawBitmap(\n                                shadowData.bitmap,\n                                renderData.contentLeft + shadowData.left,\n                                renderData.contentTop + shadowData.top,\n                                null\n                            )\n                        }\n                        drawContent()\n                    }\n                },\n            contentAlignment = Alignment.Center\n        ) {\n            Canvas(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(\n                        start = with(density) { renderData.contentLeft.toDp() },\n                        top = with(density) { renderData.contentTop.toDp() },\n                        end = with(density) { (renderData.width - renderData.contentLeft - renderData.contentWidth).toDp() },\n                        bottom = with(density) { (renderData.height - renderData.contentTop - renderData.contentHeight).toDp() }\n                    )\n            ) {\n                drawShapeLayer(\n                    type = type,\n                    data = renderData\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun PictureLayerContent(\n    modifier: Modifier,\n    type: LayerType.Picture,\n    cornerRadiusPercent: Int\n) {\n    val density = LocalDensity.current\n    var previewBitmap by remember(type.imageData) {\n        mutableStateOf<Bitmap?>(null)\n    }\n    val shadowPadding = remember(type.shadow) {\n        calculateShadowPadding(type.shadow)\n    }\n\n    Box(\n        modifier = modifier\n            .drawWithCache {\n                val contentWidth = (\n                        size.width -\n                                shadowPadding.leftPx -\n                                shadowPadding.rightPx\n                        )\n                    .coerceAtLeast(1f)\n                val contentHeight = (\n                        size.height -\n                                shadowPadding.topPx -\n                                shadowPadding.bottomPx\n                        )\n                    .coerceAtLeast(1f)\n                val shadow = previewBitmap?.let { bitmap ->\n                    buildPictureShadowRenderData(\n                        sourceBitmap = bitmap,\n                        shadow = type.shadow,\n                        targetWidth = contentWidth,\n                        targetHeight = contentHeight,\n                        cornerRadiusPercent = cornerRadiusPercent\n                    )\n                }\n\n                onDrawWithContent {\n                    shadow?.let { shadowData ->\n                        drawContext.canvas.nativeCanvas.drawBitmap(\n                            shadowData.bitmap,\n                            shadowPadding.leftPx + shadowData.left,\n                            shadowPadding.topPx + shadowData.top,\n                            null\n                        )\n                    }\n                    drawContent()\n                }\n            },\n        contentAlignment = Alignment.Center\n    ) {\n        Picture(\n            model = remember(type.imageData) {\n                ImageRequest.Builder(appContext)\n                    .data(type.imageData)\n                    .static()\n                    .allowHardware(false)\n                    .size(1600)\n                    .build()\n            },\n            contentScale = ContentScale.Fit,\n            modifier = Modifier\n                .padding(\n                    start = with(density) { shadowPadding.leftPx.toDp() },\n                    top = with(density) { shadowPadding.topPx.toDp() },\n                    end = with(density) { shadowPadding.rightPx.toDp() },\n                    bottom = with(density) { shadowPadding.bottomPx.toDp() }\n                )\n                .clip(AutoCornersShape(cornerRadiusPercent)),\n            showTransparencyChecker = false,\n            allowHardware = false,\n            onSuccess = {\n                previewBitmap = it.result.image.toBitmap()\n            },\n            onError = {\n                previewBitmap = null\n            }\n        )\n    }\n}\n\n@Composable\nprivate fun TextLayerContent(\n    modifier: Modifier,\n    type: LayerType.Text,\n    textFullSize: Int,\n    maxLines: Int = Int.MAX_VALUE,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null\n) {\n    val context = LocalContext.current\n    val density = LocalDensity.current\n    val style = LocalTextStyle.current\n    val fontFamily = type.font.toUiFont().fontFamily\n    val textMetrics = remember(type, textFullSize, density) {\n        context.calculateTextLayerMetrics(\n            type = type,\n            textFullSize = textFullSize\n        )\n    }\n    val mergedStyle = remember(\n        style,\n        type,\n        fontFamily,\n        textMetrics,\n        density\n    ) {\n        style.copy(\n            color = type.color.toColor(),\n            fontSize = with(density) { textMetrics.fontSizePx.toSp() },\n            lineHeight = with(density) { textMetrics.lineHeightPx.toSp() },\n            fontFamily = fontFamily,\n            textDecoration = TextDecoration.combine(\n                type.decorations.mapNotNull {\n                    when (it) {\n                        DomainTextDecoration.LineThrough -> TextDecoration.LineThrough\n                        DomainTextDecoration.Underline -> TextDecoration.Underline\n                        else -> null\n                    }\n                }\n            ),\n            fontWeight = if (type.decorations.any { it == DomainTextDecoration.Bold }) {\n                FontWeight.Bold\n            } else {\n                style.fontWeight\n            },\n            fontStyle = if (type.decorations.any { it == DomainTextDecoration.Italic }) {\n                FontStyle.Italic\n            } else {\n                FontStyle.Normal\n            },\n            textGeometricTransform = type.geometricTransform?.let {\n                ComposeTextGeometricTransform(\n                    scaleX = it.scaleX,\n                    skewX = it.skewX\n                )\n            },\n            textAlign = when (type.alignment) {\n                LayerType.Text.Alignment.Start -> TextAlign.Start\n                LayerType.Text.Alignment.Center -> TextAlign.Center\n                LayerType.Text.Alignment.End -> TextAlign.End\n            }\n        )\n    }\n    val outlineParams = remember(type) {\n        type.outline?.let {\n            OutlineParams(\n                color = Color(it.color),\n                stroke = Stroke(\n                    width = it.width,\n                    cap = StrokeCap.Round,\n                    join = StrokeJoin.Round\n                )\n            )\n        }\n    }\n\n    Box(\n        modifier = modifier,\n        contentAlignment = Alignment.Center\n    ) {\n        OutlinedText(\n            text = type.text,\n            style = mergedStyle,\n            outlineParams = outlineParams,\n            maxLines = maxLines,\n            onTextLayout = onTextLayout,\n            modifier = Modifier\n                .drawWithCache {\n                    val textLeft = textMetrics.padding.leftPx\n                    val textTop = textMetrics.padding.topPx\n                    val layoutWidth =\n                        (size.width - textMetrics.padding.leftPx - textMetrics.padding.rightPx)\n                            .roundToInt()\n                            .coerceAtLeast(1)\n                    val shadow = buildTextShadowRenderData(\n                        type = type,\n                        textMetrics = textMetrics,\n                        layoutWidth = layoutWidth,\n                        maxLines = maxLines.takeIf { it != Int.MAX_VALUE }\n                    )\n\n                    onDrawWithContent {\n                        drawRect(type.backgroundColor.toColor())\n                        shadow?.let { shadowData ->\n                            drawContext.canvas.nativeCanvas.apply {\n                                withSave {\n                                    scale(\n                                        1f / shadowData.rasterScale,\n                                        1f / shadowData.rasterScale\n                                    )\n                                    drawBitmap(\n                                        bitmap = shadowData.bitmap,\n                                        top = textTop * shadowData.rasterScale + shadowData.top,\n                                        left = textLeft * shadowData.rasterScale + shadowData.left\n                                    )\n                                }\n                            }\n                        }\n                        drawContent()\n                    }\n                }\n                .padding(\n                    start = with(density) { textMetrics.padding.leftPx.toDp() },\n                    top = with(density) { textMetrics.padding.topPx.toDp() },\n                    end = with(density) { textMetrics.padding.rightPx.toDp() },\n                    bottom = with(density) { textMetrics.padding.bottomPx.toDp() }\n                )\n        )\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/MarkupLayersActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.Redo\nimport androidx.compose.material.icons.automirrored.rounded.Undo\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.emoji.Emoji\nimport com.t8rin.imagetoolbox.core.resources.icons.AddSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.EmojiSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.Layers\nimport com.t8rin.imagetoolbox.core.resources.icons.StarSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.TextSticky\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedHorizontalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.EmojiSelectionSheet\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.withPreferredInitialGeometryFor\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\n\n@Composable\ninternal fun MarkupLayersActions(\n    component: MarkupLayersComponent,\n    showLayersSelection: Boolean,\n    onToggleLayersSection: () -> Unit,\n    onToggleLayersSectionQuick: () -> Unit\n) {\n    val layerImagePicker = rememberImagePicker { uri: Uri ->\n        component.addLayer(\n            UiMarkupLayer(\n                type = LayerType.Picture.Image(uri)\n            )\n        )\n    }\n    var showTextEnteringDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var showEmojiPicker by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var showShapePicker by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    val state = rememberScrollState()\n    Row(\n        modifier = Modifier\n            .fadingEdges(state)\n            .enhancedHorizontalScroll(state)\n            .padding(bottom = 2.dp),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        EnhancedIconButton(\n            containerColor = takeColorFromScheme {\n                if (showLayersSelection) tertiary\n                else Color.Transparent\n            },\n            onLongClick = onToggleLayersSectionQuick,\n            onClick = onToggleLayersSection,\n            enabled = component.layers.isNotEmpty()\n        ) {\n            Icon(\n                imageVector = Icons.Rounded.Layers,\n                contentDescription = null\n            )\n        }\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            modifier = Modifier.container(\n                shape = ShapeDefaults.circle,\n                color = takeColorFromScheme {\n                    if (component.isOptionsExpanded) surface else Color.Transparent\n                },\n                composeColorOnTopOfBackground = false,\n                clip = false,\n                resultPadding = 0.dp\n            )\n        ) {\n            EnhancedIconButton(\n                onClick = component::toggleExpandOptions,\n                containerColor = takeColorFromScheme {\n                    if (component.isOptionsExpanded) secondaryContainer else Color.Transparent\n                },\n                contentColor = takeColorFromScheme {\n                    if (component.isOptionsExpanded) onSecondaryContainer else LocalContentColor.current\n                }\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.AddSticky,\n                    contentDescription = null\n                )\n            }\n\n            AnimatedVisibility(\n                visible = component.isOptionsExpanded,\n                enter = fadeIn() + expandHorizontally(),\n                exit = fadeOut() + shrinkHorizontally()\n            ) {\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    modifier = Modifier.padding(end = 4.dp)\n                ) {\n                    EnhancedIconButton(\n                        onClick = {\n                            showTextEnteringDialog = true\n                        },\n                        forceMinimumInteractiveComponentSize = false\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.TextSticky,\n                            contentDescription = null\n                        )\n                    }\n                    EnhancedIconButton(\n                        onClick = layerImagePicker::pickImage,\n                        forceMinimumInteractiveComponentSize = false\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.ImageSticky,\n                            contentDescription = null\n                        )\n                    }\n                    EnhancedIconButton(\n                        onClick = {\n                            showEmojiPicker = true\n                        },\n                        forceMinimumInteractiveComponentSize = false\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.EmojiSticky,\n                            contentDescription = null\n                        )\n                    }\n                    EnhancedIconButton(\n                        onClick = {\n                            showShapePicker = true\n                        },\n                        forceMinimumInteractiveComponentSize = false\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.StarSticky,\n                            contentDescription = null\n                        )\n                    }\n                }\n            }\n        }\n\n        val isPortrait by isPortraitOrientationAsState()\n        if (isPortrait) {\n            Spacer(Modifier.width(8.dp))\n            MarkupLayersUndoRedo(\n                component = component,\n                color = MaterialTheme.colorScheme.surface,\n                removePadding = true\n            )\n            Spacer(Modifier.width(8.dp))\n        }\n    }\n\n    val allEmojis = Emoji.allIcons()\n\n    EmojiSelectionSheet(\n        selectedEmojiIndex = null,\n        allEmojis = allEmojis,\n        onEmojiPicked = {\n            component.addLayer(\n                UiMarkupLayer(\n                    type = LayerType.Picture.Sticker(allEmojis[it])\n                )\n            )\n            showEmojiPicker = false\n        },\n        visible = showEmojiPicker,\n        onDismiss = {\n            showEmojiPicker = false\n        },\n        icon = Icons.Outlined.EmojiSticky\n    )\n\n    AddShapeLayerDialog(\n        visible = showShapePicker,\n        onDismiss = {\n            showShapePicker = false\n        },\n        onShapePicked = { mode ->\n            component.addLayer(\n                UiMarkupLayer(\n                    type = LayerType.Shape.Default.withPreferredInitialGeometryFor(mode)\n                )\n            )\n            showShapePicker = false\n        }\n    )\n\n    AddTextLayerDialog(\n        visible = showTextEnteringDialog,\n        onDismiss = { showTextEnteringDialog = false },\n        onAddLayer = component::addLayer\n    )\n}\n\n@Composable\ninternal fun MarkupLayersUndoRedo(\n    component: MarkupLayersComponent,\n    color: Color,\n    removePadding: Boolean\n) {\n    Row(\n        modifier = Modifier.container(\n            shape = ShapeDefaults.circle,\n            color = color,\n            resultPadding = if (removePadding) 0.dp else 4.dp\n        )\n    ) {\n        EnhancedIconButton(\n            onClick = component::undo,\n            enabled = component.canUndo\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.Undo,\n                contentDescription = \"Undo\"\n            )\n        }\n        EnhancedIconButton(\n            onClick = component::redo,\n            enabled = component.canRedo\n        ) {\n            Icon(\n                imageVector = Icons.AutoMirrored.Rounded.Redo,\n                contentDescription = \"Redo\"\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/MarkupLayersContextActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnusedReceiverParameter\")\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowLeft\nimport androidx.compose.material.icons.automirrored.rounded.ArrowRight\nimport androidx.compose.material.icons.outlined.FitScreen\nimport androidx.compose.material.icons.rounded.ArrowDropDown\nimport androidx.compose.material.icons.rounded.ArrowDropUp\nimport androidx.compose.material.icons.rounded.CenterFocusStrong\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material.icons.rounded.Lock\nimport androidx.compose.material.icons.rounded.LockOpen\nimport androidx.compose.material.icons.rounded.ScreenRotationAlt\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.Deselect\nimport com.t8rin.imagetoolbox.core.resources.icons.Flip\nimport com.t8rin.imagetoolbox.core.resources.icons.FlipVertical\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.SupportingButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedDropdownMenu\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.value.ValueText\n\n@Composable\ninternal fun BoxScope.MarkupLayersContextActions(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onCopyLayer: () -> Unit,\n    onToggleEditMode: () -> Unit,\n    onRemoveLayer: () -> Unit,\n    onActivateLayer: () -> Unit,\n    isLayerLocked: Boolean,\n    onToggleLayerLock: () -> Unit,\n    isGroupingSelectionMode: Boolean,\n    groupingSelectionCount: Int,\n    onFlipLayerHorizontally: () -> Unit,\n    onFlipLayerVertically: () -> Unit,\n    onMoveLayerBy: (Float, Float) -> Unit,\n    onResetLayerPosition: () -> Unit,\n    onNormalizedPositionXChange: (Float) -> Unit,\n    onNormalizedPositionYChange: (Float) -> Unit,\n    normalizedPositionX: Float?,\n    normalizedPositionY: Float?,\n    scale: Float?,\n    onScaleChange: (Float) -> Unit,\n    onScaleChangeFinished: () -> Unit,\n    rotationDegrees: Float?,\n    onRotationDegreesChange: (Float) -> Unit,\n    onRotationDegreesChangeFinished: () -> Unit\n) {\n    var expandedAdjustableAction by rememberSaveable {\n        mutableStateOf(AdjustableActionType.None)\n    }\n    var valueDialogType by rememberSaveable {\n        mutableStateOf(ValueDialogType.None)\n    }\n    val transformActionsEnabled = !isLayerLocked && !isGroupingSelectionMode\n\n    EnhancedDropdownMenu(\n        expanded = visible,\n        onDismissRequest = {\n            if (expandedAdjustableAction != AdjustableActionType.None) {\n                expandedAdjustableAction = AdjustableActionType.None\n            } else {\n                onDismiss()\n            }\n        },\n        containerColor = MaterialTheme.colorScheme.surface\n    ) {\n        Column(\n            modifier = Modifier.padding(horizontal = 8.dp),\n            verticalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            Row(\n                horizontalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                ClickableTile(\n                    onClick = {\n                        onToggleEditMode()\n                        onDismiss()\n                    },\n                    enabled = transformActionsEnabled,\n                    icon = Icons.Rounded.MiniEdit,\n                    text = stringResource(R.string.edit),\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n                ClickableTile(\n                    onClick = onCopyLayer,\n                    enabled = !isGroupingSelectionMode,\n                    icon = Icons.Rounded.ContentCopy,\n                    text = stringResource(R.string.copy),\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n                ClickableTile(\n                    onClick = onRemoveLayer,\n                    enabled = !isGroupingSelectionMode,\n                    icon = Icons.Rounded.Delete,\n                    text = stringResource(R.string.delete),\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n            }\n            Row(\n                horizontalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                ClickableTile(\n                    onClick = onActivateLayer,\n                    enabled = !isGroupingSelectionMode || groupingSelectionCount > 0,\n                    icon = Icons.Outlined.Deselect,\n                    text = stringResource(R.string.clear_selection),\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n                ClickableTile(\n                    onClick = onFlipLayerHorizontally,\n                    enabled = transformActionsEnabled,\n                    icon = Icons.Outlined.Flip,\n                    text = stringResource(R.string.horizontal_flip),\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n                ClickableTile(\n                    onClick = onFlipLayerVertically,\n                    enabled = transformActionsEnabled,\n                    icon = Icons.Outlined.FlipVertical,\n                    text = stringResource(R.string.vertical_flip),\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n            }\n            val activeActionContainerColor = takeColorFromScheme {\n                surfaceContainerLow.blend(\n                    color = tertiaryContainer,\n                    fraction = 0.7f\n                )\n            }\n            Row(\n                horizontalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                ClickableTile(\n                    onClick = {\n                        onToggleLayerLock()\n                        onDismiss()\n                    },\n                    enabled = !isGroupingSelectionMode,\n                    icon = if (isLayerLocked) Icons.Rounded.LockOpen else Icons.Rounded.Lock,\n                    text = stringResource(\n                        if (isLayerLocked) R.string.unlock else R.string.lock\n                    ),\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n                ClickableTile(\n                    onClick = {\n                        if (transformActionsEnabled) {\n                            expandedAdjustableAction =\n                                expandedAdjustableAction.toggle(AdjustableActionType.Rotation)\n                        }\n                    },\n                    enabled = transformActionsEnabled,\n                    icon = Icons.Rounded.ScreenRotationAlt,\n                    text = stringResource(R.string.rotation),\n                    containerColor = if (expandedAdjustableAction == AdjustableActionType.Rotation) {\n                        activeActionContainerColor\n                    } else {\n                        MaterialTheme.colorScheme.surfaceContainerLow\n                    },\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n                ClickableTile(\n                    onClick = {\n                        if (transformActionsEnabled) {\n                            expandedAdjustableAction =\n                                expandedAdjustableAction.toggle(AdjustableActionType.Scale)\n                        }\n                    },\n                    enabled = transformActionsEnabled,\n                    icon = Icons.Outlined.FitScreen,\n                    text = stringResource(R.string.scale),\n                    containerColor = if (expandedAdjustableAction == AdjustableActionType.Scale) {\n                        activeActionContainerColor\n                    } else {\n                        MaterialTheme.colorScheme.surfaceContainerLow\n                    },\n                    modifier = Modifier.size(\n                        width = 66.dp,\n                        height = 50.dp\n                    )\n                )\n            }\n            AnimatedContent(\n                targetState = expandedAdjustableAction,\n                modifier = Modifier.fillMaxWidth()\n            ) { action ->\n                when (action) {\n                    AdjustableActionType.Rotation -> AdjustableActionCard(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .heightIn(min = 50.dp),\n                        title = stringResource(R.string.rotation),\n                        value = rotationDegrees ?: 0f,\n                        valueRange = 0f..360f,\n                        enabled = transformActionsEnabled,\n                        sliderEnabled = rotationDegrees != null,\n                        onValueClick = {\n                            expandedAdjustableAction = AdjustableActionType.None\n                            onDismiss()\n                            valueDialogType = ValueDialogType.Rotation\n                        },\n                        onValueChange = onRotationDegreesChange,\n                        onValueChangeFinished = onRotationDegreesChangeFinished\n                    )\n\n                    AdjustableActionType.Scale -> AdjustableActionCard(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .heightIn(min = 50.dp),\n                        title = stringResource(R.string.scale),\n                        value = scale ?: 1f,\n                        valueRange = 0.1f..10f,\n                        enabled = transformActionsEnabled,\n                        sliderEnabled = scale != null,\n                        onValueClick = {\n                            expandedAdjustableAction = AdjustableActionType.None\n                            onDismiss()\n                            valueDialogType = ValueDialogType.Scale\n                        },\n                        onValueChange = onScaleChange,\n                        onValueChangeFinished = onScaleChangeFinished\n                    )\n\n                    AdjustableActionType.None -> Unit\n                }\n            }\n\n            CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {\n                Row(\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .height(100.dp)\n                ) {\n                    val buttonContainerColor = takeColorFromScheme {\n                        surfaceContainerLow.blend(\n                            color = primaryContainer,\n                            fraction = 0.2f\n                        )\n                    }\n\n                    ClickableTile(\n                        onClick = { onMoveLayerBy(-1f, 0f) },\n                        onHoldStep = { onMoveLayerBy(-1f, 0f) },\n                        enabled = transformActionsEnabled,\n                        icon = Icons.AutoMirrored.Rounded.ArrowLeft,\n                        text = null,\n                        containerColor = buttonContainerColor,\n                        modifier = Modifier\n                            .width(66.dp)\n                            .fillMaxHeight()\n                    )\n                    Column(\n                        verticalArrangement = Arrangement.spacedBy(4.dp),\n                        modifier = Modifier\n                            .width(66.dp)\n                            .fillMaxHeight()\n                    ) {\n                        ClickableTile(\n                            onClick = { onMoveLayerBy(0f, -1f) },\n                            onHoldStep = { onMoveLayerBy(0f, -1f) },\n                            enabled = transformActionsEnabled,\n                            icon = Icons.Rounded.ArrowDropUp,\n                            text = null,\n                            modifier = Modifier\n                                .weight(1f)\n                                .fillMaxWidth(),\n                            containerColor = buttonContainerColor\n                        )\n                        ClickableTile(\n                            onClick = { onMoveLayerBy(0f, 1f) },\n                            onHoldStep = { onMoveLayerBy(0f, 1f) },\n                            enabled = transformActionsEnabled,\n                            icon = Icons.Rounded.ArrowDropDown,\n                            text = null,\n                            modifier = Modifier\n                                .weight(1f)\n                                .fillMaxWidth(),\n                            containerColor = buttonContainerColor\n                        )\n                    }\n                    ClickableTile(\n                        onClick = { onMoveLayerBy(1f, 0f) },\n                        onHoldStep = { onMoveLayerBy(1f, 0f) },\n                        enabled = transformActionsEnabled,\n                        icon = Icons.AutoMirrored.Rounded.ArrowRight,\n                        text = null,\n                        containerColor = buttonContainerColor,\n                        modifier = Modifier\n                            .width(66.dp)\n                            .fillMaxHeight()\n                    )\n                }\n            }\n            if (normalizedPositionX != null && normalizedPositionY != null) {\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    modifier = Modifier.container(\n                        shape = ShapeDefaults.extraSmall,\n                        color = takeColorFromScheme {\n                            surfaceContainerLow.blend(tertiaryContainer, 0.3f)\n                        },\n                        resultPadding = 0.dp\n                    )\n                ) {\n                    Row(\n                        horizontalArrangement = Arrangement.spacedBy(4.dp),\n                        modifier = Modifier.weight(1f)\n                    ) {\n                        val x = normalizedPositionX.roundTo(3)\n                        val y = normalizedPositionY.roundTo(3)\n\n                        AutoSizeText(\n                            text = \"X: $x\",\n                            style = MaterialTheme.typography.labelSmall.copy(\n                                fontSize = 12.sp\n                            ),\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier\n                                .then(\n                                    if (transformActionsEnabled) {\n                                        Modifier.hapticsClickable {\n                                            onDismiss()\n                                            valueDialogType = ValueDialogType.PositionX\n                                        }\n                                    } else Modifier\n                                )\n                                .alpha(if (transformActionsEnabled) 1f else 0.5f)\n                                .padding(\n                                    start = 8.dp,\n                                    top = 8.dp,\n                                    bottom = 8.dp,\n                                    end = 4.dp\n                                )\n                        )\n                        AutoSizeText(\n                            text = \"Y: $y\",\n                            style = MaterialTheme.typography.labelSmall.copy(\n                                fontSize = 12.sp\n                            ),\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier\n                                .then(\n                                    if (transformActionsEnabled) {\n                                        Modifier.hapticsClickable {\n                                            onDismiss()\n                                            valueDialogType = ValueDialogType.PositionY\n                                        }\n                                    } else Modifier\n                                )\n                                .alpha(if (transformActionsEnabled) 1f else 0.5f)\n                                .padding(\n                                    start = 4.dp,\n                                    top = 8.dp,\n                                    bottom = 8.dp,\n                                    end = 8.dp\n                                )\n                        )\n                    }\n                    SupportingButton(\n                        icon = Icons.Rounded.CenterFocusStrong,\n                        onClick = {\n                            if (transformActionsEnabled) {\n                                onResetLayerPosition()\n                            }\n                        },\n                        containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                        contentColor = MaterialTheme.colorScheme.onTertiaryContainer,\n                        shape = ShapeDefaults.extremeSmall,\n                        modifier = Modifier\n                            .padding(4.dp)\n                            .alpha(if (transformActionsEnabled) 1f else 0.5f)\n                    )\n                }\n            }\n        }\n    }\n\n    val activeValueDialogType = valueDialogType\n\n    ValueDialog(\n        roundTo = when (activeValueDialogType) {\n            ValueDialogType.Rotation -> null\n            ValueDialogType.Scale -> 3\n            ValueDialogType.PositionX,\n            ValueDialogType.PositionY -> 3\n            ValueDialogType.None -> null\n        },\n        valueRange = when (activeValueDialogType) {\n            ValueDialogType.Rotation -> 0f..360f\n            ValueDialogType.Scale -> 0.1f..10f\n            ValueDialogType.PositionX,\n            ValueDialogType.PositionY -> -2f..2f\n\n            ValueDialogType.None -> 0f..1f\n        },\n        valueState = when (activeValueDialogType) {\n            ValueDialogType.Rotation -> (rotationDegrees ?: 0f).toString()\n            ValueDialogType.Scale -> (scale ?: 1f).toString()\n            ValueDialogType.PositionX -> (normalizedPositionX?.roundTo(3) ?: 0f).toString()\n            ValueDialogType.PositionY -> (normalizedPositionY?.roundTo(3) ?: 0f).toString()\n            ValueDialogType.None -> \"0\"\n        },\n        expanded = activeValueDialogType != ValueDialogType.None,\n        onDismiss = { valueDialogType = ValueDialogType.None },\n        onValueUpdate = {\n            when (activeValueDialogType) {\n                ValueDialogType.Rotation -> {\n                    onRotationDegreesChange(it)\n                    onRotationDegreesChangeFinished()\n                }\n\n                ValueDialogType.Scale -> {\n                    onScaleChange(it)\n                    onScaleChangeFinished()\n                }\n\n                ValueDialogType.PositionX -> {\n                    onNormalizedPositionXChange(it)\n                }\n\n                ValueDialogType.PositionY -> {\n                    onNormalizedPositionYChange(it)\n                }\n\n                ValueDialogType.None -> Unit\n            }\n        }\n    )\n}\n\n@Composable\nprivate fun AdjustableActionCard(\n    title: String,\n    value: Float,\n    valueRange: ClosedFloatingPointRange<Float>,\n    enabled: Boolean,\n    sliderEnabled: Boolean,\n    onValueClick: () -> Unit,\n    onValueChange: (Float) -> Unit,\n    onValueChangeFinished: () -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Column(\n        modifier = modifier\n            .container(\n                shape = ShapeDefaults.extraSmall,\n                color = MaterialTheme.colorScheme.surfaceContainerLow,\n                resultPadding = 0.dp\n            )\n            .alpha(if (enabled) 1f else 0.5f)\n            .padding(6.dp),\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        Row(\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 8.dp),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Text(\n                text = title,\n                style = MaterialTheme.typography.labelLarge,\n                modifier = Modifier.weight(1f)\n            )\n            ValueText(\n                value = value,\n                onClick = if (enabled) {\n                    onValueClick\n                } else null,\n                modifier = Modifier\n            )\n        }\n        EnhancedSlider(\n            value = value,\n            enabled = enabled && sliderEnabled,\n            onValueChange = onValueChange,\n            onValueChangeFinished = onValueChangeFinished,\n            valueRange = valueRange,\n            drawContainer = false,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 8.dp)\n        )\n    }\n}\n\nprivate enum class AdjustableActionType {\n    None, Rotation, Scale\n}\n\nprivate fun AdjustableActionType.toggle(target: AdjustableActionType): AdjustableActionType {\n    return if (this == target) AdjustableActionType.None else target\n}\n\nprivate enum class ValueDialogType {\n    None, Rotation, Scale, PositionX, PositionY\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/MarkupLayersNoDataControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BackgroundColor\nimport com.t8rin.imagetoolbox.core.resources.icons.ImagesMode\nimport com.t8rin.imagetoolbox.core.resources.icons.ImagesearchRoller\nimport com.t8rin.imagetoolbox.core.resources.icons.Stacks\nimport com.t8rin.imagetoolbox.core.resources.icons.Unarchive\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.restrict\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\n\n@Composable\ninternal fun MarkupLayersNoDataControls(\n    component: MarkupLayersComponent,\n    onPickImage: () -> Unit,\n    onOpenProject: () -> Unit\n) {\n    var showBackgroundDrawingSetup by rememberSaveable { mutableStateOf(false) }\n\n    val cutout = WindowInsets.displayCutout.asPaddingValues()\n    LazyVerticalStaggeredGrid(\n        modifier = Modifier.fillMaxHeight(),\n        columns = StaggeredGridCells.Adaptive(300.dp),\n        horizontalArrangement = Arrangement.spacedBy(\n            space = 12.dp,\n            alignment = Alignment.CenterHorizontally\n        ),\n        verticalItemSpacing = 12.dp,\n        contentPadding = PaddingValues(\n            bottom = 12.dp + WindowInsets\n                .navigationBars\n                .asPaddingValues()\n                .calculateBottomPadding(),\n            top = 12.dp,\n            end = 12.dp + cutout.calculateEndPadding(\n                LocalLayoutDirection.current\n            ),\n            start = 12.dp + cutout.calculateStartPadding(\n                LocalLayoutDirection.current\n            )\n        ),\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        item {\n            PreferenceItem(\n                onClick = onPickImage,\n                startIcon = Icons.Outlined.ImagesMode,\n                title = stringResource(R.string.layers_on_image),\n                subtitle = stringResource(R.string.layers_on_image_sub),\n                modifier = Modifier.fillMaxWidth()\n            )\n        }\n        item {\n            PreferenceItem(\n                onClick = { showBackgroundDrawingSetup = true },\n                startIcon = Icons.Outlined.ImagesearchRoller,\n                title = stringResource(R.string.layers_on_background),\n                subtitle = stringResource(R.string.layers_on_background_sub),\n                modifier = Modifier.fillMaxWidth()\n            )\n        }\n        item {\n            PreferenceItem(\n                onClick = onOpenProject,\n                startIcon = Icons.Outlined.Unarchive,\n                title = stringResource(R.string.open_markup_project),\n                subtitle = stringResource(R.string.open_markup_project_sub),\n                modifier = Modifier.fillMaxWidth()\n            )\n        }\n    }\n\n    val screenSize = LocalScreenSize.current\n    val screenWidth = screenSize.widthPx\n    val screenHeight = screenSize.heightPx\n\n    var width by remember(\n        showBackgroundDrawingSetup,\n        screenWidth\n    ) {\n        mutableIntStateOf(screenWidth)\n    }\n    var height by remember(\n        showBackgroundDrawingSetup,\n        screenHeight\n    ) {\n        mutableIntStateOf(screenHeight)\n    }\n    var sheetBackgroundColor by rememberSaveable(\n        showBackgroundDrawingSetup,\n        stateSaver = ColorSaver\n    ) {\n        mutableStateOf(Color.White)\n    }\n    EnhancedModalBottomSheet(\n        title = {\n            TitleItem(\n                text = stringResource(R.string.markup_layers),\n                icon = Icons.Rounded.Stacks\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    showBackgroundDrawingSetup = false\n                    component.startDrawOnBackground(\n                        reqWidth = width,\n                        reqHeight = height,\n                        color = sheetBackgroundColor\n                    )\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.ok))\n            }\n        },\n        sheetContent = {\n            Column(Modifier.enhancedVerticalScroll(rememberScrollState())) {\n                Row(\n                    Modifier\n                        .padding(16.dp)\n                        .container(shape = ShapeDefaults.extraLarge)\n                ) {\n                    RoundedTextField(\n                        value = width.takeIf { it != 0 }?.toString() ?: \"\",\n                        onValueChange = {\n                            width = it.restrict(8192).toIntOrNull() ?: 0\n                        },\n                        shape = ShapeDefaults.smallStart,\n                        keyboardOptions = KeyboardOptions(\n                            keyboardType = KeyboardType.Number\n                        ),\n                        label = {\n                            Text(stringResource(R.string.width, \" \"))\n                        },\n                        modifier = Modifier\n                            .weight(1f)\n                            .padding(\n                                start = 8.dp,\n                                top = 8.dp,\n                                bottom = 8.dp,\n                                end = 2.dp\n                            )\n                    )\n                    RoundedTextField(\n                        value = height.takeIf { it != 0 }?.toString() ?: \"\",\n                        onValueChange = {\n                            height = it.restrict(8192).toIntOrNull() ?: 0\n                        },\n                        keyboardOptions = KeyboardOptions(\n                            keyboardType = KeyboardType.Number\n                        ),\n                        shape = ShapeDefaults.smallEnd,\n                        label = {\n                            Text(stringResource(R.string.height, \" \"))\n                        },\n                        modifier = Modifier\n                            .weight(1f)\n                            .padding(\n                                start = 2.dp,\n                                top = 8.dp,\n                                bottom = 8.dp,\n                                end = 8.dp\n                            ),\n                    )\n                }\n                ColorRowSelector(\n                    value = sheetBackgroundColor,\n                    onValueChange = { sheetBackgroundColor = it },\n                    icon = Icons.Outlined.BackgroundColor,\n                    modifier = Modifier\n                        .padding(\n                            start = 16.dp,\n                            end = 16.dp,\n                            bottom = 16.dp\n                        )\n                        .container(ShapeDefaults.extraLarge)\n                )\n            }\n        },\n        visible = showBackgroundDrawingSetup,\n        onDismiss = {\n            showBackgroundDrawingSetup = it\n        }\n    )\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/MarkupLayersSideMenu.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.systemBars\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Build\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.StackSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.StackStickyOff\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSlider\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.uiCornerRadiusPercent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\nimport com.t8rin.modalsheet.FullscreenPopup\n\n@Composable\ninternal fun MarkupLayersSideMenu(\n    component: MarkupLayersComponent,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    isContextOptionsVisible: Boolean,\n    onContextOptionsVisibleChange: (Boolean) -> Unit\n) {\n    val layers = component.layers\n\n    FullscreenPopup {\n        BoxWithConstraints(\n            modifier = Modifier.fillMaxSize(),\n            contentAlignment = Alignment.CenterEnd\n        ) {\n            if (visible) {\n                BackHandler(onBack = onDismiss)\n                Box(\n                    Modifier\n                        .fillMaxSize()\n                        .tappable { onDismiss() }\n                )\n            }\n\n            val maxHeightFull = this.maxHeight\n            AnimatedVisibility(\n                visible = visible,\n                enter = fadeIn() + expandHorizontally(),\n                exit = fadeOut() + shrinkHorizontally()\n            ) {\n                Surface(\n                    color = Color.Transparent\n                ) {\n                    Column(\n                        modifier = Modifier\n                            .padding(8.dp)\n                            .padding(\n                                WindowInsets.systemBars\n                                    .union(WindowInsets.displayCutout)\n                                    .asPaddingValues()\n                            )\n                            .height(\n                                minOf(maxHeightFull, 480.dp)\n                            )\n                            .width(168.dp)\n                            .container(\n                                color = MaterialTheme.colorScheme.surfaceContainer.copy(0.9f),\n                                composeColorOnTopOfBackground = false,\n                                resultPadding = 0.dp\n                            ),\n                        horizontalAlignment = Alignment.CenterHorizontally\n                    ) {\n                        val activeLayer by remember(layers) {\n                            derivedStateOf {\n                                layers.find { it.state.isActive }\n                            }\n                        }\n                        val normalizedPosition by remember(activeLayer) {\n                            derivedStateOf {\n                                activeLayer?.let { layer ->\n                                    layer.state.normalizedPosition(\n                                        cornerRadiusPercent = layer.uiCornerRadiusPercent()\n                                    )\n                                }\n                            }\n                        }\n                        val scale by remember(activeLayer) {\n                            derivedStateOf {\n                                activeLayer?.state?.scale?.roundTo(3)\n                            }\n                        }\n                        val normalizedRotationDegrees by remember(activeLayer) {\n                            derivedStateOf {\n                                activeLayer?.state?.rotation\n                                    ?.normalizeForUi()\n                                    ?.roundTo(1)\n                            }\n                        }\n                        Scaffold(\n                            topBar = {\n                                Column(\n                                    modifier = Modifier.container(\n                                        shape = RectangleShape,\n                                        color = MaterialTheme.colorScheme.surfaceContainerHigh\n                                    )\n                                ) {\n                                    Row(\n                                        verticalAlignment = Alignment.CenterVertically,\n                                        horizontalArrangement = Arrangement.Center\n                                    ) {\n                                        EnhancedIconButton(\n                                            onClick = {\n                                                activeLayer?.let(component::removeLayer)\n                                            },\n                                            enabled = activeLayer != null && !component.isGroupingSelectionMode\n                                        ) {\n                                            Icon(\n                                                imageVector = Icons.Rounded.Delete,\n                                                contentDescription = null\n                                            )\n                                        }\n                                        Spacer(Modifier.weight(1f))\n\n                                        AnimatedContent(\n                                            targetState = (component.groupingSelectionCount >= 2) to (activeLayer?.isGroup == true && !component.isGroupingSelectionMode)\n                                        ) { (canGroupLayers, canUngroupLayer) ->\n                                            if (canGroupLayers) {\n                                                EnhancedIconButton(\n                                                    onClick = component::groupSelectedLayers\n                                                ) {\n                                                    Icon(\n                                                        imageVector = Icons.Outlined.StackSticky,\n                                                        contentDescription = null\n                                                    )\n                                                }\n                                            } else if (canUngroupLayer) {\n                                                EnhancedIconButton(\n                                                    onClick = {\n                                                        activeLayer?.let(component::ungroupLayer)\n                                                    }\n                                                ) {\n                                                    Icon(\n                                                        imageVector = Icons.Outlined.StackStickyOff,\n                                                        contentDescription = null\n                                                    )\n                                                }\n                                            } else {\n                                                Spacer(Modifier.height(48.dp))\n                                            }\n                                        }\n                                        Box {\n                                            EnhancedIconButton(\n                                                onClick = {\n                                                    onContextOptionsVisibleChange(true)\n                                                },\n                                                enabled = activeLayer != null || component.isGroupingSelectionMode\n                                            ) {\n                                                Icon(\n                                                    imageVector = Icons.Rounded.Build,\n                                                    contentDescription = null\n                                                )\n                                            }\n                                            MarkupLayersContextActions(\n                                                visible = isContextOptionsVisible && (activeLayer != null || component.isGroupingSelectionMode),\n                                                onDismiss = { onContextOptionsVisibleChange(false) },\n                                                onCopyLayer = {\n                                                    activeLayer?.let(component::copyLayer)\n                                                },\n                                                onToggleEditMode = {\n                                                    activeLayer\n                                                        ?.takeIf { !it.isLocked }\n                                                        ?.state\n                                                        ?.isInEditMode = true\n                                                },\n                                                onRemoveLayer = {\n                                                    activeLayer?.let(component::removeLayer)\n                                                },\n                                                onActivateLayer = {\n                                                    component.clearSelections()\n                                                },\n                                                isLayerLocked = activeLayer?.isLocked == true,\n                                                onToggleLayerLock = {\n                                                    activeLayer?.let(component::toggleLayerLock)\n                                                },\n                                                isGroupingSelectionMode = component.isGroupingSelectionMode,\n                                                groupingSelectionCount = component.groupingSelectionCount,\n                                                onFlipLayerHorizontally = {\n                                                    activeLayer?.let { layer ->\n                                                        component.updateLayerState(layer) {\n                                                            isFlippedHorizontally =\n                                                                !isFlippedHorizontally\n                                                        }\n                                                    }\n                                                },\n                                                onFlipLayerVertically = {\n                                                    activeLayer?.let { layer ->\n                                                        component.updateLayerState(layer) {\n                                                            isFlippedVertically =\n                                                                !isFlippedVertically\n                                                        }\n                                                    }\n                                                },\n                                                onMoveLayerBy = { dx, dy ->\n                                                    activeLayer?.let { layer ->\n                                                        component.moveLayerBy(\n                                                            layer = layer,\n                                                            offsetChange = Offset(dx, dy)\n                                                        )\n                                                    }\n                                                },\n                                                onResetLayerPosition = {\n                                                    activeLayer?.let(component::resetLayerPosition)\n                                                },\n                                                onNormalizedPositionXChange = { x ->\n                                                    activeLayer?.let { layer ->\n                                                        component.setLayerNormalizedPosition(\n                                                            layer = layer,\n                                                            x = x\n                                                        )\n                                                    }\n                                                },\n                                                onNormalizedPositionYChange = { y ->\n                                                    activeLayer?.let { layer ->\n                                                        component.setLayerNormalizedPosition(\n                                                            layer = layer,\n                                                            y = y\n                                                        )\n                                                    }\n                                                },\n                                                normalizedPositionX = normalizedPosition?.x,\n                                                normalizedPositionY = normalizedPosition?.y,\n                                                scale = scale,\n                                                onScaleChange = {\n                                                    component.beginHistoryTransaction()\n                                                    activeLayer?.let { layer ->\n                                                        component.setLayerScale(\n                                                            layer = layer,\n                                                            scale = it,\n                                                            commitToHistory = false\n                                                        )\n                                                    }\n                                                },\n                                                onScaleChangeFinished = {\n                                                    component.commitHistoryTransaction()\n                                                },\n                                                rotationDegrees = normalizedRotationDegrees,\n                                                onRotationDegreesChange = {\n                                                    component.beginHistoryTransaction()\n                                                    activeLayer?.let { layer ->\n                                                        component.updateLayerState(\n                                                            layer = layer,\n                                                            commitToHistory = false\n                                                        ) {\n                                                            rotation = it.roundTo(1)\n                                                        }\n                                                    }\n                                                },\n                                                onRotationDegreesChangeFinished = {\n                                                    component.commitHistoryTransaction()\n                                                }\n                                            )\n                                        }\n                                    }\n                                    EnhancedSlider(\n                                        value = activeLayer?.state?.alpha ?: 1f,\n                                        enabled = activeLayer != null &&\n                                                activeLayer?.isLocked != true &&\n                                                !component.isGroupingSelectionMode,\n                                        onValueChange = {\n                                            component.beginHistoryTransaction()\n                                            activeLayer?.let { layer ->\n                                                component.updateLayerState(\n                                                    layer = layer,\n                                                    commitToHistory = false\n                                                ) {\n                                                    alpha = it\n                                                }\n                                            }\n                                        },\n                                        onValueChangeFinished = component::commitHistoryTransaction,\n                                        valueRange = 0f..1f,\n                                        drawContainer = false,\n                                        modifier = Modifier.padding(horizontal = 8.dp)\n                                    )\n                                }\n                            },\n                            contentWindowInsets = WindowInsets(0)\n                        ) { contentPadding ->\n                            MarkupLayersSideMenuColumn(\n                                modifier = Modifier.fillMaxSize(),\n                                contentPadding = contentPadding,\n                                layers = layers,\n                                onReorderLayers = component::reorderLayers,\n                                onActivateLayer = component::activateLayer,\n                                isGroupingSelectionMode = component.isGroupingSelectionMode,\n                                groupingSelectionIds = component.groupingSelectionIds,\n                                onStartGroupingSelection = component::startGroupingSelection,\n                                onToggleGroupingSelection = component::toggleGroupingSelection,\n                                onToggleLayerVisibility = { layer ->\n                                    component.updateLayerState(\n                                        layer = layer,\n                                        allowLocked = true\n                                    ) {\n                                        isVisible = !isVisible\n                                    }\n                                },\n                                onUnlockLayer = component::toggleLayerLock\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nprivate fun Float.normalizeForUi(): Float {\n    val normalized = this % 360f\n\n    return when {\n        normalized < 0f -> normalized + 360f\n        normalized == 0f && this > 0f -> 360f\n        else -> normalized\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/MarkupLayersSideMenuColumn.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.plus\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.DragHandle\nimport androidx.compose.material.icons.rounded.Lock\nimport androidx.compose.material.icons.rounded.Visibility\nimport androidx.compose.material.icons.rounded.VisibilityOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.CompositingStrategy\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.icons.EmojiSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.StackSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.StarSticky\nimport com.t8rin.imagetoolbox.core.resources.icons.TextSticky\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.AnimatedBorder\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.toPreviewGroupData\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.uiCornerRadiusPercent\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\nimport kotlin.math.abs\nimport kotlin.math.cos\nimport kotlin.math.min\nimport kotlin.math.sin\n\n@Composable\ninternal fun MarkupLayersSideMenuColumn(\n    modifier: Modifier,\n    contentPadding: PaddingValues,\n    layers: List<UiMarkupLayer>,\n    onReorderLayers: (List<UiMarkupLayer>) -> Unit,\n    onActivateLayer: (UiMarkupLayer) -> Unit,\n    isGroupingSelectionMode: Boolean,\n    groupingSelectionIds: Set<Long>,\n    onStartGroupingSelection: (UiMarkupLayer) -> Unit,\n    onToggleGroupingSelection: (UiMarkupLayer) -> Unit,\n    onToggleLayerVisibility: (UiMarkupLayer) -> Unit,\n    onUnlockLayer: (UiMarkupLayer) -> Unit\n) {\n    val haptics = LocalHapticFeedback.current\n    val lazyListState = rememberLazyListState()\n    val reorderableLazyListState = rememberReorderableLazyListState(\n        lazyListState = lazyListState\n    ) { from, to ->\n        if (isGroupingSelectionMode) return@rememberReorderableLazyListState\n        haptics.press()\n        val data = layers.toMutableList().apply {\n            add(to.index, removeAt(from.index))\n        }\n        onReorderLayers(data)\n    }\n    LaunchedEffect(Unit) {\n        val index = layers.indexOfFirst { it.state.isActive }\n            .takeIf { it >= 0 } ?: return@LaunchedEffect\n\n        lazyListState.scrollToItem(index)\n    }\n    LazyColumn(\n        state = lazyListState,\n        modifier = modifier,\n        contentPadding = contentPadding + PaddingValues(\n            top = 12.dp,\n            bottom = 12.dp,\n            start = 8.dp,\n            end = 4.dp\n        ),\n        verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.Bottom),\n        reverseLayout = true,\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        items(\n            items = layers,\n            key = { it.id }\n        ) { layer ->\n            ReorderableItem(\n                state = reorderableLazyListState,\n                key = layer.id\n            ) {\n                val type = layer.type\n                val state = layer.state\n                val isSelectedForGrouping = layer.id in groupingSelectionIds\n                val density = LocalDensity.current\n                val previewData by remember(layer) {\n                    derivedStateOf {\n                        layer.takeIf(UiMarkupLayer::isGroup)?.toPreviewGroupData()\n                    }\n                }\n                val previewContentSize = remember(state.contentSize, previewData) {\n                    previewData?.contentSize ?: state.contentSize.takeIf(IntSize::isSpecified)\n                }\n                val previewTextFullSize by remember(state.canvasSize) {\n                    derivedStateOf {\n                        min(state.canvasSize.width, state.canvasSize.height)\n                            .coerceAtLeast(1)\n                    }\n                }\n                val previewReferenceSize = remember(previewData, previewTextFullSize) {\n                    previewData?.referenceSize ?: previewTextFullSize\n                }\n\n                val boxSize = 92.dp\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.SpaceBetween\n                ) {\n                    Icon(\n                        imageVector = if (layer.state.isVisible) {\n                            Icons.Rounded.Visibility\n                        } else {\n                            Icons.Rounded.VisibilityOff\n                        },\n                        contentDescription = null,\n                        modifier = Modifier\n                            .hapticsClickable(\n                                indication = null,\n                                interactionSource = null\n                            ) {\n                                onToggleLayerVisibility(layer)\n                            }\n                    )\n                    Spacer(Modifier.width(8.dp))\n                    Box(\n                        modifier = Modifier\n                            .size(boxSize)\n                            .clip(ShapeDefaults.extraSmall)\n                            .transparencyChecker()\n                            .hapticsCombinedClickable(\n                                onLongClick = {\n                                    onStartGroupingSelection(layer)\n                                }\n                            ) {\n                                if (isGroupingSelectionMode) {\n                                    onToggleGroupingSelection(layer)\n                                } else if (!layer.isLocked) {\n                                    onActivateLayer(layer)\n                                }\n                            }\n                    ) {\n                        val borderAlpha by animateFloatAsState(\n                            if (state.isActive || isSelectedForGrouping) 1f else 0f\n                        )\n\n                        BoxWithConstraints(\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .background(\n                                    MaterialTheme.colorScheme.primary.copy(\n                                        0.16f * borderAlpha\n                                    )\n                                )\n                                .padding(6.dp),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            val scope = this\n                            val previewContainerSize = remember(scope.constraints) {\n                                IntSize(\n                                    width = scope.constraints.maxWidth,\n                                    height = scope.constraints.maxHeight\n                                )\n                            }\n                            val previewFitScale by remember(\n                                previewContentSize,\n                                previewContainerSize,\n                                state.rotation\n                            ) {\n                                derivedStateOf {\n                                    previewContentSize?.let { contentSize ->\n                                        calculatePreviewFitScale(\n                                            contentSize = contentSize,\n                                            containerSize = previewContainerSize,\n                                            rotation = if (layer.isGroup) 0f else state.rotation\n                                        )\n                                    } ?: 1f\n                                }\n                            }\n                            val previewModifier = remember(\n                                previewContentSize,\n                                density,\n                                scope.maxWidth,\n                                scope.maxHeight\n                            ) {\n                                previewContentSize?.let { contentSize ->\n                                    Modifier.requiredSize(\n                                        width = with(density) { contentSize.width.toDp() },\n                                        height = with(density) { contentSize.height.toDp() }\n                                    )\n                                } ?: Modifier.sizeIn(\n                                    maxWidth = scope.maxWidth,\n                                    maxHeight = scope.maxHeight\n                                )\n                            }\n\n                            Box(\n                                modifier = Modifier\n                                    .fillMaxSize(0.96f)\n                                    .graphicsLayer {\n                                        scaleX = if (layer.isGroup) {\n                                            previewFitScale\n                                        } else {\n                                            previewFitScale *\n                                                    if (state.isFlippedHorizontally) -1f else 1f\n                                        }\n                                        scaleY = if (layer.isGroup) {\n                                            previewFitScale\n                                        } else {\n                                            previewFitScale *\n                                                    if (state.isFlippedVertically) -1f else 1f\n                                        }\n                                        rotationZ = if (layer.isGroup) 0f else state.rotation\n                                        alpha = if (layer.isGroup) 1f else state.alpha\n                                        compositingStrategy =\n                                            if ((if (layer.isGroup) 1f else state.alpha) >= 1f) {\n                                                CompositingStrategy.Auto\n                                            } else {\n                                                CompositingStrategy.ModulateAlpha\n                                            }\n                                    }\n                                    .padding(4.dp),\n                                contentAlignment = Alignment.Center\n                            ) {\n                                LayerContent(\n                                    modifier = previewModifier,\n                                    type = type,\n                                    groupedLayers = previewData?.layers ?: layer.groupedLayers,\n                                    textFullSize = previewReferenceSize,\n                                    maxLines = layer.visibleLineCount ?: Int.MAX_VALUE,\n                                    cornerRadiusPercent = layer.uiCornerRadiusPercent()\n                                )\n                            }\n                        }\n\n                        AnimatedBorder(\n                            modifier = Modifier.matchParentSize(),\n                            alpha = borderAlpha,\n                            scale = 1f,\n                            shape = ShapeDefaults.extraSmall\n                        )\n                        Box(\n                            modifier = Modifier\n                                .align(Alignment.TopStart)\n                                .padding(3.dp)\n                                .clip(ShapeDefaults.extraSmall)\n                                .background(MaterialTheme.colorScheme.primaryContainer.copy(0.8f))\n                                .padding(2.dp)\n                        ) {\n                            Icon(\n                                imageVector = if (layer.isGroup) {\n                                    Icons.Outlined.StackSticky\n                                } else {\n                                    when (layer.type) {\n                                        is LayerType.Picture.Image -> Icons.Outlined.ImageSticky\n                                        is LayerType.Picture.Sticker -> Icons.Outlined.EmojiSticky\n                                        is LayerType.Text -> Icons.Outlined.TextSticky\n                                        is LayerType.Shape -> Icons.Outlined.StarSticky\n                                    }\n                                },\n                                contentDescription = null,\n                                tint = MaterialTheme.colorScheme.onPrimaryContainer,\n                                modifier = Modifier.size(13.dp)\n                            )\n                        }\n\n                        if (layer.isLocked) {\n                            Box(\n                                modifier = Modifier\n                                    .align(Alignment.TopEnd)\n                                    .padding(6.dp)\n                                    .clip(ShapeDefaults.extraSmall)\n                                    .background(MaterialTheme.colorScheme.surfaceContainerHigh)\n                                    .hapticsClickable {\n                                        onUnlockLayer(layer)\n                                    }\n                                    .padding(4.dp)\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Lock,\n                                    contentDescription = null,\n                                    modifier = Modifier.size(16.dp)\n                                )\n                            }\n                        }\n                    }\n                    Spacer(Modifier.width(8.dp))\n                    Icon(\n                        imageVector = Icons.Rounded.DragHandle,\n                        contentDescription = null,\n                        modifier = if (isGroupingSelectionMode) {\n                            Modifier.graphicsLayer {\n                                alpha = 0.35f\n                            }\n                        } else {\n                            Modifier.longPressDraggableHandle(\n                                onDragStarted = {\n                                    haptics.longPress()\n                                }\n                            )\n                        }\n                    )\n                }\n            }\n        }\n    }\n}\n\nprivate fun calculatePreviewFitScale(\n    contentSize: IntSize,\n    containerSize: IntSize,\n    rotation: Float\n): Float {\n    if (!contentSize.isSpecified() || !containerSize.isSpecified()) return 1f\n\n    val radians = Math.toRadians(rotation.toDouble())\n    val cos = abs(cos(radians)).toFloat()\n    val sin = abs(sin(radians)).toFloat()\n    val rotatedWidth = contentSize.width * cos + contentSize.height * sin\n    val rotatedHeight = contentSize.width * sin + contentSize.height * cos\n\n    return min(\n        containerSize.width / rotatedWidth.coerceAtLeast(1f),\n        containerSize.height / rotatedHeight.coerceAtLeast(1f)\n    ).coerceIn(0f, 1f)\n}\n\nprivate fun IntSize.isSpecified(): Boolean = width > 0 && height > 0\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/MarkupLayersTopAppBarActions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.BottomSheetScaffoldState\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.BackgroundBehavior\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun MarkupLayersTopAppBarActions(\n    component: MarkupLayersComponent,\n    scaffoldState: BottomSheetScaffoldState\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    val scope = rememberCoroutineScope()\n\n    if (component.backgroundBehavior == BackgroundBehavior.None) TopAppBarEmoji()\n    else {\n        if (isPortrait) {\n            EnhancedIconButton(\n                onClick = {\n                    scope.launch {\n                        if (scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {\n                            scaffoldState.bottomSheetState.partialExpand()\n                        } else {\n                            scaffoldState.bottomSheetState.expand()\n                        }\n                    }\n                },\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Tune,\n                    contentDescription = stringResource(R.string.properties)\n                )\n            }\n        }\n\n        EnhancedIconButton(\n            onClick = component::clearLayers,\n            enabled = component.layers.isNotEmpty()\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.Delete,\n                contentDescription = stringResource(R.string.clear)\n            )\n        }\n\n        var editSheetData by remember {\n            mutableStateOf(listOf<Uri>())\n        }\n        ShareButton(\n            enabled = component.backgroundBehavior !is BackgroundBehavior.None,\n            onShare = component::shareBitmap,\n            onCopy = {\n                component.cacheCurrentImage(Clipboard::copy)\n            },\n            onEdit = {\n                component.cacheCurrentImage { uri ->\n                    editSheetData = listOf(uri)\n                }\n            }\n        )\n        ProcessImagesPreferenceSheet(\n            uris = editSheetData,\n            visible = editSheetData.isNotEmpty(),\n            onDismiss = {\n                editSheetData = emptyList()\n            },\n            onNavigate = component.onNavigate\n        )\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/ShapeLayerParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FormatColorFill\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SquareFoot\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ShapeMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.arrowAngle\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.arrowSizeScale\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.cornerRadius\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.innerRadiusRatio\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.isOutlinedShapeMode\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.isRegular\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ordinal\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.outlinedFillColorInt\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.rotationDegrees\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updateArrow\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updatePolygon\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updateRect\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.updateStar\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.usesStrokeWidth\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.vertices\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.withOutlinedFillColor\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.withPreferredGeometryFor\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.withSavedStateFrom\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.icon\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun ShapeLayerParamsSelector(\n    layer: UiMarkupLayer,\n    type: LayerType.Shape,\n    onUpdateLayer: (UiMarkupLayer) -> Unit,\n    onUpdateLayerContinuously: (UiMarkupLayer) -> Unit,\n    onContinuousEditFinished: () -> Unit\n) {\n    Column(\n        modifier = Modifier.container(\n            shape = ShapeDefaults.large,\n            color = MaterialTheme.colorScheme.surface,\n        )\n    ) {\n        EnhancedButtonGroup(\n            enabled = true,\n            itemCount = ShapeMode.entries.size,\n            title = {\n                Text(\n                    text = stringResource(R.string.shape),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n            },\n            selectedIndex = type.shapeMode.ordinal,\n            activeButtonColor = MaterialTheme.colorScheme.surfaceContainerHighest,\n            inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n            itemContent = {\n                Icon(\n                    imageVector = ShapeMode.entries[it].kind.icon,\n                    contentDescription = null\n                )\n            },\n            onIndexChange = {\n                val mode = ShapeMode.entries[it]\n                    .withSavedStateFrom(type.shapeMode)\n                    .let { candidate ->\n                        if (candidate.isOutlinedShapeMode() && candidate.outlinedFillColorInt() == null) {\n                            candidate.withOutlinedFillColor(\n                                color = type.shapeMode.outlinedFillColorInt()\n                            )\n                        } else {\n                            candidate\n                        }\n                    }\n\n                onUpdateLayer(\n                    layer.copy(\n                        cornerRadiusPercent = 0,\n                        type = type.withPreferredGeometryFor(mode)\n                    )\n                )\n            }\n        )\n    }\n\n    Spacer(modifier = Modifier.height(8.dp))\n    ShapeAppearanceSection(\n        layer = layer,\n        type = type,\n        onUpdateLayer = onUpdateLayer,\n        onUpdateLayerContinuously = onUpdateLayerContinuously,\n        onContinuousEditFinished = onContinuousEditFinished\n    )\n\n    Spacer(modifier = Modifier.height(8.dp))\n    ShapeSizeSection(\n        layer = layer,\n        type = type,\n        onUpdateLayerContinuously = onUpdateLayerContinuously,\n        onContinuousEditFinished = onContinuousEditFinished\n    )\n\n    AnimatedContent(\n        targetState = type,\n        contentKey = { it.shapeMode.kind },\n        modifier = Modifier.fillMaxWidth()\n    ) { animatedType ->\n        Column {\n            ShapeSpecificControls(\n                layer = layer,\n                type = animatedType,\n                onUpdateLayer = onUpdateLayer,\n                onUpdateLayerContinuously = onUpdateLayerContinuously,\n                onContinuousEditFinished = onContinuousEditFinished\n            )\n        }\n    }\n\n    Spacer(modifier = Modifier.height(4.dp))\n    DropShadowSection(\n        shadow = type.shadow,\n        onShadowChange = { shadow ->\n            onUpdateLayer(\n                layer.copy(\n                    type = type.copy(\n                        shadow = shadow\n                    )\n                )\n            )\n        },\n        onShadowChangeContinuously = { shadow ->\n            onUpdateLayerContinuously(\n                layer.copy(\n                    type = type.copy(\n                        shadow = shadow\n                    )\n                )\n            )\n        },\n        onContinuousEditFinished = onContinuousEditFinished\n    )\n}\n\n@Composable\nprivate fun ShapeAppearanceSection(\n    layer: UiMarkupLayer,\n    type: LayerType.Shape,\n    onUpdateLayer: (UiMarkupLayer) -> Unit,\n    onUpdateLayerContinuously: (UiMarkupLayer) -> Unit,\n    onContinuousEditFinished: () -> Unit\n) {\n    val mode = type.shapeMode\n    val showFillColor = mode.isOutlinedShapeMode()\n    val showStrokeWidth = mode.usesStrokeWidth()\n    val singleItemShape = ShapeDefaults.large\n\n    ColorRowSelector(\n        value = type.color.toColor(),\n        onValueChange = {\n            onUpdateLayer(\n                layer.copy(\n                    type = type.copy(color = it.toArgb())\n                )\n            )\n        },\n        title = stringResource(R.string.color),\n        modifier = Modifier.container(\n            shape = when {\n                showFillColor || showStrokeWidth -> ShapeDefaults.top\n                else -> singleItemShape\n            },\n            color = MaterialTheme.colorScheme.surface\n        )\n    )\n\n    AnimatedVisibility(\n        visible = showFillColor,\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        Column {\n            Spacer(modifier = Modifier.height(4.dp))\n            ColorRowSelector(\n                value = mode.outlinedFillColorInt()?.toColor(),\n                onValueChange = {\n                    onUpdateLayer(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.withOutlinedFillColor(it.toArgb())\n                            )\n                        )\n                    )\n                },\n                onNullClick = {\n                    onUpdateLayer(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.withOutlinedFillColor(null)\n                            )\n                        )\n                    )\n                },\n                title = stringResource(R.string.fill_color),\n                icon = Icons.Outlined.FormatColorFill,\n                allowAlpha = true,\n                modifier = Modifier.container(\n                    shape = if (showStrokeWidth) ShapeDefaults.center else ShapeDefaults.bottom,\n                    color = MaterialTheme.colorScheme.surface\n                )\n            )\n        }\n    }\n\n    AnimatedVisibility(\n        visible = showStrokeWidth,\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        Column {\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = type.strokeWidth,\n                title = stringResource(R.string.line_width),\n                internalStateTransformation = { it.roundToTwoDigits() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(strokeWidth = it)\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 1f..64f,\n                shape = if (showFillColor) ShapeDefaults.bottom else ShapeDefaults.bottom,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun ShapeSizeSection(\n    layer: UiMarkupLayer,\n    type: LayerType.Shape,\n    onUpdateLayerContinuously: (UiMarkupLayer) -> Unit,\n    onContinuousEditFinished: () -> Unit\n) {\n    EnhancedSliderItem(\n        value = type.widthRatio,\n        title = stringResource(R.string.width, \"\").trim(),\n        internalStateTransformation = { it.roundToTwoDigits() },\n        onValueChange = {\n            onUpdateLayerContinuously(\n                layer.copy(\n                    type = type.copy(widthRatio = it.roundToTwoDigits())\n                )\n            )\n        },\n        onValueChangeFinished = { _ -> onContinuousEditFinished() },\n        valueRange = 0.05f..0.5f,\n        shape = ShapeDefaults.top,\n        containerColor = MaterialTheme.colorScheme.surface\n    )\n    Spacer(modifier = Modifier.height(4.dp))\n    EnhancedSliderItem(\n        value = type.heightRatio,\n        title = stringResource(R.string.height, \"\").trim(),\n        internalStateTransformation = { it.roundToTwoDigits() },\n        onValueChange = {\n            onUpdateLayerContinuously(\n                layer.copy(\n                    type = type.copy(heightRatio = it.roundToTwoDigits())\n                )\n            )\n        },\n        onValueChangeFinished = { _ -> onContinuousEditFinished() },\n        valueRange = 0.05f..0.5f,\n        shape = ShapeDefaults.bottom,\n        containerColor = MaterialTheme.colorScheme.surface\n    )\n}\n\n@Composable\nprivate fun ShapeSpecificControls(\n    layer: UiMarkupLayer,\n    type: LayerType.Shape,\n    onUpdateLayer: (UiMarkupLayer) -> Unit,\n    onUpdateLayerContinuously: (UiMarkupLayer) -> Unit,\n    onContinuousEditFinished: () -> Unit\n) {\n    when (val mode = type.shapeMode) {\n        is ShapeMode.Arrow,\n        is ShapeMode.DoubleArrow,\n        is ShapeMode.LineArrow,\n        is ShapeMode.DoubleLineArrow -> {\n            Spacer(modifier = Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = mode.arrowSizeScale(),\n                title = stringResource(R.string.head_length_scale),\n                internalStateTransformation = { it.roundToTwoDigits() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateArrow(sizeScale = it)\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 0.5f..8f,\n                shape = ShapeDefaults.top,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = (mode.arrowAngle() - 90f).coerceAtLeast(0f),\n                title = stringResource(R.string.angle),\n                internalStateTransformation = { it.roundToTwoDigits() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateArrow(angle = it + 90f)\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 0f..90f,\n                shape = ShapeDefaults.bottom,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        }\n\n        is ShapeMode.Rect,\n        is ShapeMode.OutlinedRect -> {\n            Spacer(modifier = Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = mode.rotationDegrees().toFloat(),\n                title = stringResource(R.string.angle),\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateRect(rotationDegrees = it.roundToInt())\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 0f..360f,\n                shape = ShapeDefaults.top,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = mode.cornerRadius(),\n                title = stringResource(R.string.radius),\n                internalStateTransformation = { it.roundToTwoDigits() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateRect(cornerRadius = it.roundToTwoDigits())\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 0f..0.5f,\n                shape = ShapeDefaults.bottom,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        }\n\n        is ShapeMode.Polygon,\n        is ShapeMode.OutlinedPolygon -> {\n            Spacer(modifier = Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = mode.vertices().toFloat(),\n                title = stringResource(R.string.vertices),\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updatePolygon(vertices = it.roundToInt())\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 3f..24f,\n                steps = 20,\n                shape = ShapeDefaults.top,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = mode.rotationDegrees().toFloat(),\n                title = stringResource(R.string.angle),\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updatePolygon(rotationDegrees = it.roundToInt())\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 0f..360f,\n                shape = ShapeDefaults.center,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            PreferenceRowSwitch(\n                title = stringResource(R.string.draw_regular_polygon),\n                subtitle = stringResource(R.string.draw_regular_polygon_sub),\n                checked = mode.isRegular(),\n                onClick = {\n                    onUpdateLayer(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updatePolygon(isRegular = it)\n                            )\n                        )\n                    )\n                },\n                shape = ShapeDefaults.bottom,\n                modifier = Modifier.fillMaxWidth(),\n                startIcon = Icons.Rounded.SquareFoot,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        }\n\n        is ShapeMode.Star,\n        is ShapeMode.OutlinedStar -> {\n            Spacer(modifier = Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = mode.vertices().toFloat(),\n                title = stringResource(R.string.vertices),\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateStar(vertices = it.roundToInt())\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 3f..24f,\n                steps = 20,\n                shape = ShapeDefaults.top,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = mode.rotationDegrees().toFloat(),\n                title = stringResource(R.string.angle),\n                internalStateTransformation = { it.roundToInt() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateStar(rotationDegrees = it.roundToInt())\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 0f..360f,\n                shape = ShapeDefaults.center,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = mode.innerRadiusRatio(),\n                title = stringResource(R.string.inner_radius_ratio),\n                internalStateTransformation = { it.roundToTwoDigits() },\n                onValueChange = {\n                    onUpdateLayerContinuously(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateStar(innerRadiusRatio = it.roundToTwoDigits())\n                            )\n                        )\n                    )\n                },\n                onValueChangeFinished = { _ -> onContinuousEditFinished() },\n                valueRange = 0f..1f,\n                shape = ShapeDefaults.center,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            PreferenceRowSwitch(\n                title = stringResource(R.string.draw_regular_star),\n                subtitle = stringResource(R.string.draw_regular_star_sub),\n                checked = mode.isRegular(),\n                onClick = {\n                    onUpdateLayer(\n                        layer.copy(\n                            type = type.copy(\n                                shapeMode = mode.updateStar(isRegular = it)\n                            )\n                        )\n                    )\n                },\n                shape = ShapeDefaults.bottom,\n                modifier = Modifier.fillMaxWidth(),\n                startIcon = Icons.Rounded.SquareFoot,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        }\n\n        else -> Unit\n    }\n}\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/model/BackgroundBehavior.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model\n\nsealed class BackgroundBehavior {\n    data object None : BackgroundBehavior()\n\n    data object Image : BackgroundBehavior()\n\n    data class Color(\n        val width: Int,\n        val height: Int,\n        val color: Int\n    ) : BackgroundBehavior()\n}"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/model/ShapeLayerModeUiExt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CheckBoxOutlineBlank\nimport androidx.compose.material.icons.rounded.Circle\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material.icons.rounded.Star\nimport androidx.compose.material.icons.rounded.StarOutline\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeDoubleArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.Line\nimport com.t8rin.imagetoolbox.core.resources.icons.LineArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.LineDoubleArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.Polygon\nimport com.t8rin.imagetoolbox.core.resources.icons.Square\nimport com.t8rin.imagetoolbox.core.resources.icons.Triangle\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ShapeMode\n\ninternal val ShapeMode.Kind.titleRes: Int\n    get() = when (this) {\n        ShapeMode.Kind.Line -> R.string.line\n        ShapeMode.Kind.Arrow -> R.string.arrow\n        ShapeMode.Kind.DoubleArrow -> R.string.double_arrow\n        ShapeMode.Kind.LineArrow -> R.string.line_arrow\n        ShapeMode.Kind.DoubleLineArrow -> R.string.double_line_arrow\n        ShapeMode.Kind.Rect -> R.string.rect\n        ShapeMode.Kind.OutlinedRect -> R.string.outlined_rect\n        ShapeMode.Kind.Oval -> R.string.oval\n        ShapeMode.Kind.OutlinedOval -> R.string.outlined_oval\n        ShapeMode.Kind.Triangle -> R.string.triangle\n        ShapeMode.Kind.OutlinedTriangle -> R.string.outlined_triangle\n        ShapeMode.Kind.Polygon -> R.string.polygon\n        ShapeMode.Kind.OutlinedPolygon -> R.string.outlined_polygon\n        ShapeMode.Kind.Star -> R.string.star\n        ShapeMode.Kind.OutlinedStar -> R.string.outlined_star\n    }\n\ninternal val ShapeMode.Kind.icon: ImageVector\n    get() = when (this) {\n        ShapeMode.Kind.Line -> Icons.Rounded.Line\n        ShapeMode.Kind.Arrow -> Icons.Rounded.FreeArrow\n        ShapeMode.Kind.DoubleArrow -> Icons.Rounded.FreeDoubleArrow\n        ShapeMode.Kind.LineArrow -> Icons.Rounded.LineArrow\n        ShapeMode.Kind.DoubleLineArrow -> Icons.Rounded.LineDoubleArrow\n        ShapeMode.Kind.Rect -> Icons.Rounded.Square\n        ShapeMode.Kind.OutlinedRect -> Icons.Rounded.CheckBoxOutlineBlank\n        ShapeMode.Kind.Oval -> Icons.Rounded.Circle\n        ShapeMode.Kind.OutlinedOval -> Icons.Rounded.RadioButtonUnchecked\n        ShapeMode.Kind.Triangle -> Icons.Rounded.Triangle\n        ShapeMode.Kind.OutlinedTriangle -> Icons.Outlined.Triangle\n        ShapeMode.Kind.Polygon -> Icons.Rounded.Polygon\n        ShapeMode.Kind.OutlinedPolygon -> Icons.Outlined.Polygon\n        ShapeMode.Kind.Star -> Icons.Rounded.Star\n        ShapeMode.Kind.OutlinedStar -> Icons.Rounded.StarOutline\n    }\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/model/UiMarkupLayer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FormatBold\nimport androidx.compose.material.icons.rounded.FormatItalic\nimport androidx.compose.material.icons.rounded.FormatStrikethrough\nimport androidx.compose.material.icons.rounded.FormatUnderlined\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.DomainTextDecoration\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerPosition\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.layerCornerRadiusPercent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.EditBoxState\nimport java.util.concurrent.atomic.AtomicLong\n\ndata class UiMarkupLayer(\n    val id: Long = nextUiLayerId(),\n    val type: LayerType,\n    val visibleLineCount: Int? = null,\n    val cornerRadiusPercent: Int = 0,\n    val blendingMode: BlendingMode = BlendingMode.SrcOver,\n    val isLocked: Boolean = false,\n    val groupedLayers: List<UiMarkupLayer> = emptyList(),\n    val state: EditBoxState = EditBoxState(isActive = true)\n) {\n    val isGroup: Boolean\n        get() = groupedLayers.isNotEmpty()\n\n    fun copy(\n        isActive: Boolean = state.isActive,\n        coerceToBounds: Boolean = state.coerceToBounds\n    ) = UiMarkupLayer(\n        id = id,\n        type = type,\n        visibleLineCount = visibleLineCount,\n        cornerRadiusPercent = cornerRadiusPercent,\n        blendingMode = blendingMode,\n        isLocked = isLocked,\n        groupedLayers = groupedLayers,\n        state = state.copy(\n            isActive = isActive,\n            coerceToBounds = coerceToBounds\n        )\n    )\n}\n\nfun UiMarkupLayer.asDomain(): MarkupLayer = MarkupLayer(\n    type = if (isGroup) defaultGroupPlaceholderType() else type,\n    position = LayerPosition(\n        scale = state.scale,\n        rotation = state.rotation,\n        isFlippedHorizontally = state.isFlippedHorizontally,\n        isFlippedVertically = state.isFlippedVertically,\n        offsetX = state.offset.x,\n        offsetY = state.offset.y,\n        alpha = state.alpha,\n        currentCanvasSize = state.canvasSize,\n        coerceToBounds = state.coerceToBounds,\n        isVisible = state.isVisible\n    ),\n    contentSize = state.contentSize.toIntegerSize(),\n    visibleLineCount = visibleLineCount,\n    cornerRadiusPercent = type.layerCornerRadiusPercent(cornerRadiusPercent),\n    isLocked = isLocked,\n    blendingMode = blendingMode,\n    groupedLayers = groupedLayers.map(UiMarkupLayer::asDomain)\n)\n\nfun MarkupLayer.asUi(): UiMarkupLayer = UiMarkupLayer(\n    type = type,\n    visibleLineCount = visibleLineCount,\n    cornerRadiusPercent = type.layerCornerRadiusPercent(cornerRadiusPercent),\n    blendingMode = blendingMode,\n    isLocked = isLocked,\n    groupedLayers = groupedLayers.map(MarkupLayer::asUi),\n    state = EditBoxState(\n        scale = position.scale,\n        rotation = position.rotation,\n        isFlippedHorizontally = position.isFlippedHorizontally,\n        isFlippedVertically = position.isFlippedVertically,\n        offset = Offset(\n            x = position.offsetX,\n            y = position.offsetY\n        ),\n        alpha = position.alpha,\n        isActive = false,\n        canvasSize = position.currentCanvasSize,\n        contentSize = contentSize.toIntSize(),\n        isVisible = position.isVisible,\n        coerceToBounds = position.coerceToBounds\n    )\n)\n\nprivate fun IntSize.toIntegerSize(): IntegerSize = IntegerSize(\n    width = width.coerceAtLeast(0),\n    height = height.coerceAtLeast(0)\n)\n\nprivate fun IntegerSize.toIntSize(): IntSize = IntSize(\n    width = width.coerceAtLeast(0),\n    height = height.coerceAtLeast(0)\n)\n\ninternal fun defaultGroupPlaceholderType(): LayerType = LayerType.Shape.Default.copy(\n    color = 0,\n    shadow = null\n)\n\ninternal fun noteUiLayerId(id: Long) {\n    uiLayerIdCounter.updateAndGet { current ->\n        maxOf(current, id + 1)\n    }\n}\n\nprivate fun nextUiLayerId(): Long = uiLayerIdCounter.getAndIncrement()\n\nprivate val uiLayerIdCounter = AtomicLong(1L)\n\nval DomainTextDecoration.icon: ImageVector\n    get() = when (this) {\n        LayerType.Text.Decoration.Bold -> Icons.Rounded.FormatBold\n        LayerType.Text.Decoration.Italic -> Icons.Rounded.FormatItalic\n        LayerType.Text.Decoration.Underline -> Icons.Rounded.FormatUnderlined\n        LayerType.Text.Decoration.LineThrough -> Icons.Rounded.FormatStrikethrough\n    }\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/components/model/UiMarkupLayerGrouping.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model\n\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerPosition\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.layerCornerRadiusPercent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.EditBoxState\nimport kotlin.math.PI\nimport kotlin.math.abs\nimport kotlin.math.ceil\nimport kotlin.math.cos\nimport kotlin.math.roundToInt\nimport kotlin.math.sin\nimport kotlin.math.sqrt\n\ninternal fun UiMarkupLayer.uiCornerRadiusPercent(): Int = if (isGroup) {\n    0\n} else {\n    type.layerCornerRadiusPercent(cornerRadiusPercent)\n}\n\ninternal fun UiMarkupLayer.deepDuplicate(): UiMarkupLayer = UiMarkupLayer(\n    type = type,\n    visibleLineCount = visibleLineCount,\n    cornerRadiusPercent = cornerRadiusPercent,\n    blendingMode = blendingMode,\n    isLocked = isLocked,\n    groupedLayers = groupedLayers.map(UiMarkupLayer::deepDuplicate),\n    state = state.copy(\n        isActive = false,\n        isInEditMode = false\n    )\n)\n\ninternal fun UiMarkupLayer.renderCopy(): UiMarkupLayer = UiMarkupLayer(\n    id = id,\n    type = type,\n    visibleLineCount = visibleLineCount,\n    cornerRadiusPercent = cornerRadiusPercent,\n    blendingMode = blendingMode,\n    isLocked = false,\n    groupedLayers = groupedLayers.map(UiMarkupLayer::renderCopy),\n    state = state.copy(\n        isActive = false,\n        isInEditMode = false\n    )\n)\n\ninternal fun UiMarkupLayer.groupChildAt(\n    center: Offset\n): UiMarkupLayer = copy(\n    state = state.copy(\n        offset = state.offset - center,\n        isActive = false,\n        isInEditMode = false\n    )\n)\n\ninternal fun UiMarkupLayer.effectiveCoerceToBounds(): Boolean = state.coerceToBounds &&\n        groupedLayers.all(UiMarkupLayer::effectiveCoerceToBounds)\n\ninternal fun UiMarkupLayer.withCoerceToBoundsRecursively(\n    value: Boolean\n): UiMarkupLayer = copy(\n    groupedLayers = groupedLayers.map { child ->\n        child.withCoerceToBoundsRecursively(value)\n    },\n    state = state.copy(\n        coerceToBounds = value\n    )\n)\n\ninternal data class GroupPreviewData(\n    val layers: List<UiMarkupLayer>,\n    val contentSize: IntSize,\n    val referenceSize: Int\n)\n\ninternal fun UiMarkupLayer.groupContentSize(): IntSize? = localLeafLayers()\n    .combinedBounds()\n    ?.toIntSize()\n\ninternal fun UiMarkupLayer.canvasLeafLayers(\n    canvasSize: IntegerSize = state.canvasSize,\n    coerceScale: Boolean = false\n): List<UiMarkupLayer> {\n    val rootState = state.adjustedToCanvasSize(\n        canvasSize = canvasSize,\n        forceScaleAdjustment = true\n    ).let { state ->\n        if (coerceScale) {\n            state.copy(\n                scale = 1f\n            )\n        } else {\n            state\n        }\n    }\n\n    return groupedLayers.flatMap { child ->\n        child.flattenLeafLayers(\n            parentTransform = rootState.toLayerTransform(),\n            inheritedAlpha = rootState.alpha,\n            inheritedVisible = rootState.isVisible,\n            rootCanvasSize = rootState.canvasSize\n        )\n    }\n}\n\ninternal fun UiMarkupLayer.coerceGroupToBounds() {\n    if (!isGroup || !state.coerceToBounds) return\n\n    val canvasSize = state.canvasSize.takeIf { it.width > 0 && it.height > 0 } ?: return\n    val bounds = canvasLeafLayers(canvasSize = canvasSize).combinedBounds() ?: return\n    val constrainedOffset = state.offset + bounds.offsetCorrection(canvasSize)\n\n    if (constrainedOffset != state.offset) {\n        state.offset = constrainedOffset\n    }\n}\n\ninternal fun UiMarkupLayer.applyGroupGlobalChanges(\n    zoomChange: Float = 1f,\n    offsetChange: Offset = Offset.Zero,\n    rotationChange: Float = 0f\n) {\n    if (!isGroup) return\n\n    val currentScale = state.scale\n    val targetScale = coerceGroupInteractiveScale(\n        currentScale = currentScale,\n        targetScale = currentScale * zoomChange\n    )\n    val proposedState = state.copy(\n        scale = targetScale,\n        rotation = state.rotation + rotationChange,\n        offset = state.offset + offsetChange\n    )\n\n    val targetOffset = if (proposedState.coerceToBounds) {\n        proposedState.withOffsetCorrection(\n            layer = this,\n            canvasSize = proposedState.canvasSize\n        )\n    } else {\n        proposedState.offset\n    }\n\n    state.scale = targetScale\n    state.rotation = proposedState.rotation\n    state.offset = targetOffset\n}\n\ninternal fun UiMarkupLayer.setGroupScalePrecisely(\n    targetScale: Float\n) {\n    val resolvedScale = coerceGroupInteractiveScale(\n        currentScale = state.scale,\n        targetScale = targetScale\n    )\n    val currentScale = state.scale.coerceAtLeast(MIN_GROUP_SCALE_EPSILON)\n    applyGroupGlobalChanges(\n        zoomChange = resolvedScale / currentScale\n    )\n}\n\nprivate fun EditBoxState.withOffsetCorrection(\n    layer: UiMarkupLayer,\n    canvasSize: IntegerSize\n): Offset {\n    if (canvasSize.width <= 0 || canvasSize.height <= 0) return offset\n\n    val bounds = layer.copy(state = this)\n        .canvasLeafLayers(canvasSize = canvasSize)\n        .combinedBounds() ?: return offset\n\n    return offset + bounds.offsetCorrection(canvasSize)\n}\n\nprivate fun LayerBounds.offsetCorrection(\n    canvasSize: IntegerSize\n): Offset {\n    val halfCanvasWidth = canvasSize.width / 2f\n    val halfCanvasHeight = canvasSize.height / 2f\n    val dx = axisCoerceDelta(\n        minEdge = -halfCanvasWidth,\n        maxEdge = halfCanvasWidth,\n        start = left,\n        end = right\n    )\n    val dy = axisCoerceDelta(\n        minEdge = -halfCanvasHeight,\n        maxEdge = halfCanvasHeight,\n        start = top,\n        end = bottom\n    )\n\n    return Offset(dx, dy)\n}\n\ninternal fun UiMarkupLayer.flattenToDomain(): List<MarkupLayer> = flattenToDomain(\n    parentTransform = null,\n    inheritedAlpha = 1f,\n    inheritedVisible = true,\n    rootCanvasSize = state.canvasSize\n)\n\ninternal fun UiMarkupLayer.toPreviewGroupData(): GroupPreviewData {\n    val previewLayers = previewLeafLayers()\n    val bounds = previewLayers.combinedBounds() ?: LayerBounds(-0.5f, -0.5f, 0.5f, 0.5f)\n    val previewSize = bounds.toIntSize()\n    val previewCanvasSize = previewSize.toIntegerSize()\n    val centeredLayers = previewLayers.map { layer ->\n        layer.renderCopy().copy(\n            state = layer.state.copy(\n                offset = layer.state.offset - bounds.center,\n                canvasSize = previewCanvasSize,\n                isActive = false,\n                isInEditMode = false\n            )\n        )\n    }\n\n    return GroupPreviewData(\n        layers = centeredLayers,\n        contentSize = previewSize,\n        referenceSize = minOf(state.canvasSize.width, state.canvasSize.height).coerceAtLeast(1)\n    )\n}\n\ninternal fun UiMarkupLayer.composeToParentSpace(\n    parent: UiMarkupLayer\n): UiMarkupLayer {\n    val rootCanvasSize = parent.state.canvasSize\n    val detachedLayer = detachedSubtree()\n    val composedTransform = parent.state.toLayerTransform().compose(\n        detachedLayer.state.toLayerTransform()\n    )\n    val decomposition = composedTransform.matrix.decompose()\n\n    return detachedLayer.copy(\n        state = detachedLayer.state.copy(\n            scale = decomposition.scale,\n            rotation = decomposition.rotation,\n            isFlippedHorizontally = decomposition.isFlippedHorizontally,\n            isFlippedVertically = decomposition.isFlippedVertically,\n            offset = composedTransform.offset,\n            alpha = (parent.state.alpha * detachedLayer.state.alpha).coerceIn(0f, 1f),\n            isActive = false,\n            canvasSize = rootCanvasSize,\n            isVisible = parent.state.isVisible && detachedLayer.state.isVisible,\n            coerceToBounds = detachedLayer.state.coerceToBounds,\n            isInEditMode = false\n        )\n    )\n}\n\ninternal fun UiMarkupLayer.visualBounds(): LayerBounds {\n    val size = state.contentSize.takeIf(IntSize::isSpecified) ?: IntSize(1, 1)\n    val halfExtents = size.rotatedHalfExtents(\n        degrees = state.rotation,\n        cornerRadiusPercent = uiCornerRadiusPercent()\n    )\n    val scaledHalfWidth = halfExtents.x * state.scale\n    val scaledHalfHeight = halfExtents.y * state.scale\n\n    return LayerBounds(\n        left = state.offset.x - scaledHalfWidth,\n        top = state.offset.y - scaledHalfHeight,\n        right = state.offset.x + scaledHalfWidth,\n        bottom = state.offset.y + scaledHalfHeight\n    )\n}\n\ninternal data class UiMarkupLayerSnapshot(\n    val id: Long,\n    val type: com.t8rin.imagetoolbox.feature.markup_layers.domain.LayerType,\n    val visibleLineCount: Int?,\n    val cornerRadiusPercent: Int,\n    val blendingMode: com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode,\n    val isLocked: Boolean,\n    val groupedLayers: List<UiMarkupLayerSnapshot>,\n    val state: EditBoxStateSnapshot\n)\n\ninternal data class EditBoxStateSnapshot(\n    val scale: Float,\n    val rotation: Float,\n    val isFlippedHorizontally: Boolean,\n    val isFlippedVertically: Boolean,\n    val offsetX: Float,\n    val offsetY: Float,\n    val alpha: Float,\n    val isActive: Boolean,\n    val canvasWidth: Int,\n    val canvasHeight: Int,\n    val contentWidth: Int,\n    val contentHeight: Int,\n    val isVisible: Boolean,\n    val coerceToBounds: Boolean,\n    val isInEditMode: Boolean\n)\n\ninternal fun UiMarkupLayer.toSnapshot(): UiMarkupLayerSnapshot = UiMarkupLayerSnapshot(\n    id = id,\n    type = type,\n    visibleLineCount = visibleLineCount,\n    cornerRadiusPercent = cornerRadiusPercent,\n    blendingMode = blendingMode,\n    isLocked = isLocked,\n    groupedLayers = groupedLayers.map(UiMarkupLayer::toSnapshot),\n    state = state.toSnapshot()\n)\n\ninternal fun UiMarkupLayerSnapshot.toUi(): UiMarkupLayer {\n    noteUiLayerId(id)\n    return UiMarkupLayer(\n        id = id,\n        type = type,\n        visibleLineCount = visibleLineCount,\n        cornerRadiusPercent = cornerRadiusPercent,\n        blendingMode = blendingMode,\n        isLocked = isLocked,\n        groupedLayers = groupedLayers.map(UiMarkupLayerSnapshot::toUi),\n        state = state.toUi()\n    )\n}\n\nprivate fun EditBoxState.toSnapshot(): EditBoxStateSnapshot = EditBoxStateSnapshot(\n    scale = scale,\n    rotation = rotation,\n    isFlippedHorizontally = isFlippedHorizontally,\n    isFlippedVertically = isFlippedVertically,\n    offsetX = offset.x,\n    offsetY = offset.y,\n    alpha = alpha,\n    isActive = isActive,\n    canvasWidth = canvasSize.width,\n    canvasHeight = canvasSize.height,\n    contentWidth = contentSize.width,\n    contentHeight = contentSize.height,\n    isVisible = isVisible,\n    coerceToBounds = coerceToBounds,\n    isInEditMode = isInEditMode\n)\n\nprivate fun EditBoxStateSnapshot.toUi(): EditBoxState = EditBoxState(\n    scale = scale,\n    rotation = rotation,\n    isFlippedHorizontally = isFlippedHorizontally,\n    isFlippedVertically = isFlippedVertically,\n    offset = Offset(offsetX, offsetY),\n    alpha = alpha,\n    isActive = isActive,\n    canvasSize = IntegerSize(canvasWidth, canvasHeight),\n    contentSize = IntSize(contentWidth, contentHeight),\n    isVisible = isVisible,\n    coerceToBounds = coerceToBounds,\n    isInEditMode = isInEditMode\n)\n\nprivate fun UiMarkupLayer.flattenToDomain(\n    parentTransform: LayerTransform?,\n    inheritedAlpha: Float,\n    inheritedVisible: Boolean,\n    rootCanvasSize: IntegerSize\n): List<MarkupLayer> {\n    val currentTransform =\n        parentTransform?.compose(state.toLayerTransform()) ?: state.toLayerTransform()\n    val combinedAlpha = (inheritedAlpha * state.alpha).coerceIn(0f, 1f)\n    val combinedVisible = inheritedVisible && state.isVisible\n\n    if (isGroup) {\n        return groupedLayers.flatMap { child ->\n            child.flattenToDomain(\n                parentTransform = currentTransform,\n                inheritedAlpha = combinedAlpha,\n                inheritedVisible = combinedVisible,\n                rootCanvasSize = rootCanvasSize\n            )\n        }\n    }\n\n    val decomposition = currentTransform.matrix.decompose()\n\n    return listOf(\n        MarkupLayer(\n            type = type,\n            position = LayerPosition(\n                scale = decomposition.scale,\n                rotation = decomposition.rotation,\n                isFlippedHorizontally = decomposition.isFlippedHorizontally,\n                isFlippedVertically = decomposition.isFlippedVertically,\n                offsetX = currentTransform.offset.x,\n                offsetY = currentTransform.offset.y,\n                alpha = combinedAlpha,\n                currentCanvasSize = rootCanvasSize,\n                coerceToBounds = state.coerceToBounds,\n                isVisible = combinedVisible\n            ),\n            contentSize = state.contentSize.toIntegerSize(),\n            visibleLineCount = visibleLineCount,\n            cornerRadiusPercent = type.layerCornerRadiusPercent(cornerRadiusPercent),\n            isLocked = isLocked,\n            blendingMode = blendingMode\n        )\n    )\n}\n\nprivate data class LayerTransform(\n    val matrix: TransformMatrix,\n    val offset: Offset\n) {\n    fun compose(\n        child: LayerTransform\n    ): LayerTransform = LayerTransform(\n        matrix = matrix * child.matrix,\n        offset = offset + matrix.transform(child.offset)\n    )\n}\n\nprivate data class TransformMatrix(\n    val m00: Float,\n    val m01: Float,\n    val m10: Float,\n    val m11: Float\n) {\n    operator fun times(\n        other: TransformMatrix\n    ): TransformMatrix = TransformMatrix(\n        m00 = m00 * other.m00 + m01 * other.m10,\n        m01 = m00 * other.m01 + m01 * other.m11,\n        m10 = m10 * other.m00 + m11 * other.m10,\n        m11 = m10 * other.m01 + m11 * other.m11\n    )\n\n    fun transform(\n        offset: Offset\n    ): Offset = Offset(\n        x = m00 * offset.x + m01 * offset.y,\n        y = m10 * offset.x + m11 * offset.y\n    )\n\n    fun decompose(): DecomposedTransform {\n        val scale = sqrt(m00 * m00 + m10 * m10).coerceAtLeast(0.0001f)\n        val determinant = m00 * m11 - m01 * m10\n\n        return if (determinant < 0f) {\n            DecomposedTransform(\n                scale = scale,\n                rotation = radiansToDegrees(\n                    kotlin.math.atan2(-m10, -m00)\n                ),\n                isFlippedHorizontally = true,\n                isFlippedVertically = false\n            )\n        } else {\n            DecomposedTransform(\n                scale = scale,\n                rotation = radiansToDegrees(\n                    kotlin.math.atan2(m10, m00)\n                ),\n                isFlippedHorizontally = false,\n                isFlippedVertically = false\n            )\n        }\n    }\n}\n\nprivate data class DecomposedTransform(\n    val scale: Float,\n    val rotation: Float,\n    val isFlippedHorizontally: Boolean,\n    val isFlippedVertically: Boolean\n)\n\ninternal data class LayerBounds(\n    val left: Float,\n    val top: Float,\n    val right: Float,\n    val bottom: Float\n) {\n    val center: Offset\n        get() = Offset(\n            x = (left + right) / 2f,\n            y = (top + bottom) / 2f\n        )\n\n    fun plus(\n        other: LayerBounds\n    ): LayerBounds = LayerBounds(\n        left = minOf(left, other.left),\n        top = minOf(top, other.top),\n        right = maxOf(right, other.right),\n        bottom = maxOf(bottom, other.bottom)\n    )\n\n    fun toIntSize(): IntSize = IntSize(\n        width = ceil(right - left).roundToInt().coerceAtLeast(1),\n        height = ceil(bottom - top).roundToInt().coerceAtLeast(1)\n    )\n\n    fun contains(point: Offset): Boolean = point.x in left..right && point.y in top..bottom\n\n    fun axisCoerceDelta(\n        minEdge: Float,\n        maxEdge: Float,\n        start: Float,\n        end: Float\n    ): Float {\n        val size = end - start\n        val availableSize = maxEdge - minEdge\n\n        return if (size <= availableSize) {\n            when {\n                start < minEdge -> minEdge - start\n                end > maxEdge -> maxEdge - end\n                else -> 0f\n            }\n        } else {\n            when {\n                start > minEdge -> minEdge - start\n                end < maxEdge -> maxEdge - end\n                else -> 0f\n            }\n        }\n    }\n}\n\ninternal fun List<UiMarkupLayer>.combinedBounds(): LayerBounds? = map(UiMarkupLayer::visualBounds)\n    .reduceOrNull(LayerBounds::plus)\n\nprivate fun UiMarkupLayer.previewLeafLayers(): List<UiMarkupLayer> = canvasLeafLayers(\n    coerceScale = true\n)\n\nprivate fun UiMarkupLayer.detachedSubtree(): UiMarkupLayer = copy(\n    groupedLayers = groupedLayers.map(UiMarkupLayer::detachedSubtree),\n    state = state.copy(\n        isActive = false,\n        isInEditMode = false\n    )\n)\n\nprivate fun UiMarkupLayer.localLeafLayers(): List<UiMarkupLayer> = groupedLayers.flatMap { child ->\n    child.flattenLeafLayers()\n}\n\nprivate fun EditBoxState.adjustedToCanvasSize(\n    canvasSize: IntegerSize,\n    forceScaleAdjustment: Boolean = false\n): EditBoxState = copy().also {\n    it.syncCanvasSize(\n        value = canvasSize,\n        forceScaleAdjustment = forceScaleAdjustment\n    )\n}\n\nprivate fun UiMarkupLayer.flattenLeafLayers(\n    parentTransform: LayerTransform? = null,\n    inheritedAlpha: Float = 1f,\n    inheritedVisible: Boolean = true,\n    rootCanvasSize: IntegerSize = state.canvasSize,\n    includeScale: Boolean = true\n): List<UiMarkupLayer> {\n    val currentTransform =\n        parentTransform?.compose(state.toLayerTransform(includeScale = includeScale))\n            ?: state.toLayerTransform(includeScale = includeScale)\n    val combinedAlpha = (inheritedAlpha * state.alpha).coerceIn(0f, 1f)\n    val combinedVisible = inheritedVisible && state.isVisible\n\n    if (isGroup) {\n        return groupedLayers.flatMap { child ->\n            child.flattenLeafLayers(\n                parentTransform = currentTransform,\n                inheritedAlpha = combinedAlpha,\n                inheritedVisible = combinedVisible,\n                rootCanvasSize = rootCanvasSize,\n                includeScale = includeScale\n            )\n        }\n    }\n\n    val decomposition = currentTransform.matrix.decompose()\n\n    return listOf(\n        copy(\n            groupedLayers = emptyList(),\n            state = state.copy(\n                scale = decomposition.scale,\n                rotation = decomposition.rotation,\n                isFlippedHorizontally = decomposition.isFlippedHorizontally,\n                isFlippedVertically = decomposition.isFlippedVertically,\n                offset = currentTransform.offset,\n                alpha = combinedAlpha,\n                canvasSize = rootCanvasSize,\n                isVisible = combinedVisible,\n                isActive = false,\n                isInEditMode = false\n            )\n        )\n    )\n}\n\nprivate fun EditBoxState.toLayerTransform(\n    includeScale: Boolean = true\n): LayerTransform {\n    val angle = rotation * DEGREES_TO_RADIANS\n    val cos = cos(angle)\n    val sin = sin(angle)\n    val appliedScale = if (includeScale) scale else 1f\n    val scaleX = appliedScale * if (isFlippedHorizontally) -1f else 1f\n    val scaleY = appliedScale * if (isFlippedVertically) -1f else 1f\n\n    return LayerTransform(\n        matrix = TransformMatrix(\n            m00 = cos * scaleX,\n            m01 = -sin * scaleY,\n            m10 = sin * scaleX,\n            m11 = cos * scaleY\n        ),\n        offset = offset\n    )\n}\n\nprivate fun IntSize.toIntegerSize(): IntegerSize = IntegerSize(\n    width = width.coerceAtLeast(0),\n    height = height.coerceAtLeast(0)\n)\n\nprivate fun IntSize.rotatedHalfExtents(\n    degrees: Float,\n    cornerRadiusPercent: Int\n): Offset {\n    val halfWidth = width / 2f\n    val halfHeight = height / 2f\n    val cornerRadiusPx = (\n            minOf(width, height) * (cornerRadiusPercent.coerceIn(0, 50) / 100f)\n            ).coerceIn(0f, minOf(halfWidth, halfHeight))\n    val innerHalfWidth = (halfWidth - cornerRadiusPx).coerceAtLeast(0f)\n    val innerHalfHeight = (halfHeight - cornerRadiusPx).coerceAtLeast(0f)\n\n    val radians = degrees * DEGREES_TO_RADIANS\n    val absCos = abs(cos(radians))\n    val absSin = abs(sin(radians))\n\n    return Offset(\n        x = innerHalfWidth * absCos + innerHalfHeight * absSin + cornerRadiusPx,\n        y = innerHalfWidth * absSin + innerHalfHeight * absCos + cornerRadiusPx\n    )\n}\n\nprivate fun IntSize.isSpecified(): Boolean = width > 0 && height > 0\n\nprivate fun radiansToDegrees(\n    radians: Float\n): Float = radians * 180f / PI.toFloat()\n\nprivate fun coerceGroupInteractiveScale(\n    currentScale: Float,\n    targetScale: Float\n): Float {\n    val minimumValue = GROUP_SCALE_RANGE.start\n    val maximumValue = GROUP_SCALE_RANGE.endInclusive\n    val safeTargetScale = targetScale.coerceAtLeast(MIN_GROUP_SCALE_EPSILON)\n\n    return when {\n        safeTargetScale >= minimumValue -> safeTargetScale.coerceAtMost(maximumValue)\n        currentScale < minimumValue -> safeTargetScale.coerceAtMost(maximumValue)\n        else -> minimumValue\n    }\n}\n\nprivate const val DEGREES_TO_RADIANS = (PI / 180f).toFloat()\nprivate const val MIN_GROUP_SCALE_EPSILON = 0.0001f\nprivate val GROUP_SCALE_RANGE = 0.1f..10f\n"
  },
  {
    "path": "feature/markup-layers/src/main/java/com/t8rin/imagetoolbox/feature/markup_layers/presentation/screenLogic/MarkupLayersComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.drawable.toBitmap\nimport androidx.core.graphics.drawable.toDrawable\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.MarkupProjectExtension\nimport com.t8rin.imagetoolbox.feature.markup_layers.data.project.isMarkupProject\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupLayersApplier\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProject\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProjectHistorySnapshot\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.MarkupProjectResult\nimport com.t8rin.imagetoolbox.feature.markup_layers.domain.ProjectBackground\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.EditBoxState\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.BackgroundBehavior\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayer\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.UiMarkupLayerSnapshot\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.applyGroupGlobalChanges\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.asDomain\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.asUi\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.coerceGroupToBounds\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.combinedBounds\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.composeToParentSpace\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.deepDuplicate\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.defaultGroupPlaceholderType\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.effectiveCoerceToBounds\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.flattenToDomain\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.groupChildAt\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.setGroupScalePrecisely\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.toSnapshot\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.toUi\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.uiCornerRadiusPercent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.components.model.withCoerceToBoundsRecursively\nimport com.t8rin.logger.makeLog\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.withContext\n\n\nclass MarkupLayersComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    dispatchersHolder: DispatchersHolder,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val markupLayersApplier: MarkupLayersApplier<Bitmap>,\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    private val _isOptionsExpanded = fileController.savable(\n        scope = componentScope,\n        initial = false\n    )\n    val isOptionsExpanded: Boolean get() = _isOptionsExpanded.get()\n\n    private val _backgroundBehavior: MutableState<BackgroundBehavior> =\n        mutableStateOf(BackgroundBehavior.None)\n    val backgroundBehavior: BackgroundBehavior by _backgroundBehavior\n\n    private val _layers: MutableState<List<UiMarkupLayer>> = mutableStateOf(emptyList())\n    val layers: List<UiMarkupLayer> by _layers\n\n    private val _groupingSelectionIds: MutableState<Set<Long>> = mutableStateOf(emptySet())\n    val groupingSelectionIds: Set<Long> by _groupingSelectionIds\n    val isGroupingSelectionMode: Boolean get() = groupingSelectionIds.isNotEmpty()\n    val groupingSelectionCount: Int get() = groupingSelectionIds.size\n\n    private val _history: MutableState<List<HistorySnapshot>> = mutableStateOf(\n        listOf(HistorySnapshot())\n    )\n    private val history: List<HistorySnapshot> by _history\n\n    private val _redoHistory: MutableState<List<HistorySnapshot>> = mutableStateOf(emptyList())\n    private val redoHistory: List<HistorySnapshot> by _redoHistory\n\n    private var pendingHistorySnapshot: HistorySnapshot? = null\n\n    val canUndo: Boolean get() = history.size > 1\n    val canRedo: Boolean get() = redoHistory.isNotEmpty()\n\n    fun toggleExpandOptions() {\n        _isOptionsExpanded.update { !it }\n    }\n\n    fun undo() {\n        finalizePendingHistoryTransaction()\n        if (!canUndo) return\n\n        val current = history.last()\n        val previous = history[history.lastIndex - 1]\n\n        _history.value = history.dropLast(1)\n        _redoHistory.update { (it + current).takeLast(MAX_HISTORY_SIZE) }\n        applyHistorySnapshot(previous)\n        registerChanges()\n    }\n\n    fun redo() {\n        finalizePendingHistoryTransaction()\n        if (!canRedo) return\n\n        val snapshot = redoHistory.last()\n\n        _redoHistory.value = redoHistory.dropLast(1)\n        _history.update { (it + snapshot).takeLast(MAX_HISTORY_SIZE) }\n        applyHistorySnapshot(snapshot)\n        registerChanges()\n    }\n\n    fun clearLayers() {\n        if (layers.isEmpty()) return\n\n        cancelGroupingSelection()\n        runEditorChange {\n            _layers.value = emptyList()\n        }\n    }\n\n    fun addLayer(layer: UiMarkupLayer) {\n        cancelGroupingSelection()\n        deactivateAllLayers()\n        runEditorChange {\n            _layers.update { it + layer }\n        }\n    }\n\n    fun deactivateAllLayers() {\n        _layers.value.forEach { it.state.deactivate() }\n    }\n\n    fun activateLayer(layer: UiMarkupLayer) {\n        if (layer.isLocked) return\n        deactivateAllLayers()\n        layer.state.activate()\n    }\n\n    fun copyLayer(layer: UiMarkupLayer) {\n        cancelGroupingSelection()\n        runEditorChange {\n            val copied = layer.deepDuplicate()\n            _layers.update {\n                it.toMutableList().apply {\n                    add(indexOf(layer), copied)\n                }\n            }\n            activateLayer(copied)\n        }\n    }\n\n    fun updateLayerAt(\n        index: Int,\n        layer: UiMarkupLayer,\n        commitToHistory: Boolean = true\n    ) {\n        val currentLayer = layers.getOrNull(index) ?: return\n        if (currentLayer == layer) return\n        val metadataOnlyUpdate = currentLayer.copy(\n            visibleLineCount = layer.visibleLineCount\n        ) == layer\n        if (currentLayer.isLocked && !metadataOnlyUpdate) return\n\n        val replaceLayer: () -> Unit = {\n            _layers.update {\n                it.toMutableList().apply {\n                    set(index, layer)\n                }\n            }\n        }\n\n        val shouldTrackHistory = commitToHistory && !metadataOnlyUpdate\n\n        if (shouldTrackHistory) {\n            runEditorChange(replaceLayer)\n        } else {\n            replaceLayer()\n        }\n    }\n\n    fun updateLayerState(\n        layer: UiMarkupLayer,\n        commitToHistory: Boolean = true,\n        allowLocked: Boolean = false,\n        block: EditBoxState.() -> Unit\n    ) {\n        if (layer.isLocked && !allowLocked) return\n\n        if (commitToHistory) {\n            runEditorChange {\n                layer.state.block()\n                layer.coerceGroupToBounds()\n            }\n        } else {\n            layer.state.block()\n            layer.coerceGroupToBounds()\n        }\n    }\n\n    fun toggleLayerLock(layer: UiMarkupLayer) {\n        cancelGroupingSelection()\n        runEditorChange {\n            val copied = layer.copy(\n                isLocked = !layer.isLocked,\n                state = layer.state.copy(\n                    isActive = false,\n                    isInEditMode = false\n                )\n            )\n\n            _layers.update {\n                it.toMutableList().apply {\n                    set(\n                        index = indexOf(layer),\n                        element = copied\n                    )\n                }\n            }\n        }\n    }\n\n    fun removeLayer(layer: UiMarkupLayer) {\n        cancelGroupingSelection()\n        runEditorChange {\n            _layers.update { it - layer }\n        }\n    }\n\n    fun reorderLayers(layers: List<UiMarkupLayer>) {\n        runEditorChange {\n            _layers.update { layers }\n        }\n    }\n\n    fun beginHistoryTransaction() {\n        if (pendingHistorySnapshot == null) {\n            pendingHistorySnapshot = currentHistorySnapshot()\n        }\n    }\n\n    fun commitHistoryTransaction() {\n        pendingHistorySnapshot?.let(::commitHistoryFrom)\n    }\n\n    fun moveLayerBy(\n        layer: UiMarkupLayer,\n        offsetChange: Offset,\n        commitToHistory: Boolean = true\n    ) {\n        updateLayerState(\n            layer = layer,\n            commitToHistory = commitToHistory\n        ) {\n            if (layer.isGroup) {\n                layer.applyGroupGlobalChanges(\n                    offsetChange = offsetChange\n                )\n            } else {\n                moveBy(\n                    offsetChange = offsetChange,\n                    cornerRadiusPercent = layer.uiCornerRadiusPercent()\n                )\n            }\n        }\n    }\n\n    fun setLayerScale(\n        layer: UiMarkupLayer,\n        scale: Float,\n        commitToHistory: Boolean = true\n    ) {\n        updateLayerState(\n            layer = layer,\n            commitToHistory = commitToHistory\n        ) {\n            if (layer.isGroup) {\n                layer.setGroupScalePrecisely(scale)\n            } else {\n                setScalePrecisely(\n                    targetScale = scale,\n                    cornerRadiusPercent = layer.uiCornerRadiusPercent()\n                )\n            }\n        }\n    }\n\n    fun resetLayerPosition(layer: UiMarkupLayer) {\n        updateLayerState(layer = layer) {\n            resetPosition()\n        }\n    }\n\n    fun setLayerNormalizedPosition(\n        layer: UiMarkupLayer,\n        x: Float? = null,\n        y: Float? = null,\n        commitToHistory: Boolean = true\n    ) {\n        updateLayerState(\n            layer = layer,\n            commitToHistory = commitToHistory\n        ) {\n            setNormalizedPosition(\n                x = x,\n                y = y,\n                cornerRadiusPercent = layer.uiCornerRadiusPercent()\n            )\n        }\n    }\n\n    fun toggleGroupingSelection(layer: UiMarkupLayer) {\n        if (layer.isLocked) return\n        if (layers.none { it.id == layer.id }) return\n\n        deactivateAllLayers()\n        _groupingSelectionIds.update { ids ->\n            if (layer.id in ids) ids - layer.id else ids + layer.id\n        }\n    }\n\n    fun startGroupingSelection(layer: UiMarkupLayer) {\n        if (layer.isLocked) return\n        if (layers.none { it.id == layer.id }) return\n\n        val activeLayerId = layers.firstOrNull { it.state.isActive && !it.isLocked }?.id\n\n        deactivateAllLayers()\n        _groupingSelectionIds.update { ids ->\n            val seededIds = ids.ifEmpty {\n                buildSet {\n                    activeLayerId?.let(::add)\n                    add(layer.id)\n                }\n            }\n\n            when {\n                seededIds.isEmpty() -> setOf(layer.id)\n                ids.isEmpty() -> seededIds\n                layer.id in seededIds -> seededIds - layer.id\n                else -> seededIds + layer.id\n            }\n        }\n    }\n\n    fun cancelGroupingSelection() {\n        _groupingSelectionIds.value = emptySet()\n    }\n\n    fun clearSelections() {\n        cancelGroupingSelection()\n        deactivateAllLayers()\n    }\n\n    fun groupSelectedLayers() {\n        val selectedEntries = layers.withIndex()\n            .filter { it.value.id in groupingSelectionIds }\n        if (selectedEntries.size < 2) return\n\n        val selectedLayers = selectedEntries.map { it.value }\n        val bounds = selectedLayers.combinedBounds() ?: return\n        val center = bounds.center\n        val canvasSize = selectedLayers.firstNotNullOfOrNull { layer ->\n            layer.state.canvasSize.takeIf { it.width > 0 && it.height > 0 }\n        } ?: return\n        val groupCoerceToBounds = selectedLayers.all(UiMarkupLayer::effectiveCoerceToBounds)\n\n        val groupedLayer = UiMarkupLayer(\n            type = defaultGroupPlaceholderType(),\n            groupedLayers = selectedLayers.map { layer ->\n                layer.groupChildAt(center)\n            },\n            state = EditBoxState(\n                isActive = true,\n                canvasSize = canvasSize,\n                contentSize = bounds.toIntSize(),\n                offset = center,\n                coerceToBounds = groupCoerceToBounds\n            )\n        ).withCoerceToBoundsRecursively(groupCoerceToBounds)\n\n        runEditorChange {\n            val selectedIds = selectedEntries.map { it.value.id }.toSet()\n            val firstSelectedIndex = selectedEntries.minOf { it.index }\n\n            _layers.update { current ->\n                buildList {\n                    current.forEachIndexed { index, currentLayer ->\n                        if (index == firstSelectedIndex) add(groupedLayer)\n                        if (currentLayer.id !in selectedIds) add(currentLayer)\n                    }\n                }\n            }\n        }\n        cancelGroupingSelection()\n    }\n\n    fun ungroupLayer(layer: UiMarkupLayer) {\n        if (!layer.isGroup) return\n\n        cancelGroupingSelection()\n        runEditorChange {\n            val restoredLayers = layer.groupedLayers.map { child ->\n                child.composeToParentSpace(layer)\n            }\n\n            _layers.update { current ->\n                current.toMutableList().apply {\n                    val index = indexOf(layer)\n                    if (index >= 0) {\n                        removeAt(index)\n                        addAll(index, restoredLayers)\n                    }\n                }\n            }\n\n            restoredLayers.firstOrNull()?.let(::activateLayer)\n        }\n    }\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _uri = mutableStateOf(Uri.EMPTY)\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Png.Lossless)\n    val imageFormat by _imageFormat\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _saveExif: MutableState<Boolean> = mutableStateOf(false)\n    val saveExif: Boolean by _saveExif\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            renderLayers()?.let { localBitmap ->\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = ImageInfo(\n                                imageFormat = imageFormat,\n                                width = localBitmap.width,\n                                height = localBitmap.height\n                            ),\n                            originalUri = _uri.value.toString(),\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = localBitmap,\n                                imageInfo = ImageInfo(\n                                    imageFormat = imageFormat,\n                                    width = localBitmap.width,\n                                    height = localBitmap.height\n                                )\n                            )\n                        ),\n                        keepOriginalMetadata = _saveExif.value,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.value = imageFormat\n        registerChanges()\n    }\n\n    fun setSaveExif(bool: Boolean) {\n        _saveExif.value = bool\n        registerChanges()\n    }\n\n    private fun updateBitmap(bitmap: Bitmap?) {\n        componentScope.launch {\n            updateBitmapSync(bitmap)\n        }\n    }\n\n    private suspend fun updateBitmapSync(bitmap: Bitmap?) {\n        _isImageLoading.value = true\n        _bitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n        _isImageLoading.value = false\n    }\n\n    fun setUri(uri: Uri) {\n        if (uri.isMarkupProject()) {\n            loadProject(uri)\n        } else {\n            setImageUri(uri)\n        }\n    }\n\n    fun saveProject(uri: Uri) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            finalizePendingHistoryTransaction()\n\n            fileController.writeBytes(uri.toString()) { output ->\n                markupLayersApplier.saveProject(\n                    destination = output,\n                    project = createProject()\n                )\n            }.onSuccess {\n                registerSave()\n                AppToastHost.showConfetti()\n            }.let(::parseSaveResult)\n\n            _isSaving.value = false\n        }\n    }\n\n    fun createProjectFilename(): String {\n        val baseName = when (backgroundBehavior) {\n            is BackgroundBehavior.Image -> {\n                _uri.value.filename()?.substringBeforeLast('.')?.takeIf(String::isNotBlank)\n            }\n\n            is BackgroundBehavior.Color -> \"Markup\"\n            BackgroundBehavior.None -> null\n        } ?: \"Markup\"\n\n        return \"${baseName}_${timestamp()}.$MarkupProjectExtension\"\n    }\n\n    private fun setImageUri(uri: Uri) {\n        componentScope.launch {\n            cancelGroupingSelection()\n            _layers.update { emptyList() }\n            _isImageLoading.value = true\n\n            _uri.value = uri\n            imageGetter.getImageAsync(\n                uri = uri.toString(),\n                originalSize = false,\n                onGetImage = { data ->\n                    _backgroundBehavior.update { BackgroundBehavior.Image }\n                    updateBitmap(data.image)\n                    _imageFormat.update { data.imageInfo.imageFormat }\n                    resetHistory()\n                    registerChangesCleared()\n                },\n                onFailure = {\n                    _isImageLoading.value = false\n\n                    if (bitmap == null) resetState()\n\n                    AppToastHost.showFailureToast(it)\n                }\n            )\n        }\n    }\n\n    private fun loadProject(uri: Uri) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            when (val result = markupLayersApplier.openProject(uri.toString())) {\n                is MarkupProjectResult.Success -> {\n                    applyProject(\n                        project = result.project\n                    )\n                    registerChangesCleared()\n                }\n\n                is MarkupProjectResult.Error -> {\n                    AppToastHost.showFailureToast(result.message)\n                }\n            }\n            _isImageLoading.value = false\n        }\n    }\n\n    private suspend fun renderLayers(): Bitmap? = withContext(defaultDispatcher) {\n        deactivateAllLayers()\n\n        runCatching {\n            markupLayersApplier.applyToImage(\n                image = imageGetter.getImage(data = _uri.value)\n                    ?: (backgroundBehavior as? BackgroundBehavior.Color)?.run {\n                        color.toDrawable().toBitmap(width, height)\n                    } ?: run {\n                        val w =\n                            layers.firstOrNull()?.state?.canvasSize?.width?.takeIf { it > 0 } ?: 1\n                        val h =\n                            layers.firstOrNull()?.state?.canvasSize?.height?.takeIf { it > 0 } ?: 1\n                        ImageBitmap(w, h).asAndroidBitmap()\n                    },\n                layers = flattenLayers(layers)\n            )\n        }.onFailure {\n            it.makeLog()\n        }.getOrNull()\n    }\n\n    override fun resetState() {\n        markupLayersApplier.clearProjectCache()\n        _bitmap.value = null\n        _backgroundBehavior.update {\n            BackgroundBehavior.None\n        }\n        _uri.value = Uri.EMPTY\n        _layers.update { emptyList() }\n        cancelGroupingSelection()\n        resetHistory()\n        registerChangesCleared()\n    }\n\n    fun startDrawOnBackground(\n        reqWidth: Int,\n        reqHeight: Int,\n        color: Color,\n    ) {\n        val width = reqWidth.takeIf { it > 0 } ?: 1\n        val height = reqHeight.takeIf { it > 0 } ?: 1\n        width / height.toFloat()\n        _backgroundBehavior.update {\n            BackgroundBehavior.Color(\n                width = width,\n                height = height,\n                color = color.toArgb()\n            )\n        }\n        _uri.value = Uri.EMPTY\n        _layers.value = emptyList()\n        cancelGroupingSelection()\n        updateBitmap(null)\n        resetHistory()\n        registerChangesCleared()\n    }\n\n    fun shareBitmap() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            renderLayers()?.let {\n                shareProvider.shareImage(\n                    image = it,\n                    imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = it.width,\n                        height = it.height\n                    ),\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            renderLayers()?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = image.width,\n                        height = image.height\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n    fun updateBackgroundColor(color: Color) {\n        runEditorChange {\n            _backgroundBehavior.update {\n                if (it is BackgroundBehavior.Color) {\n                    it.copy(color = color.toArgb())\n                } else it\n            }\n        }\n    }\n\n    private fun createProject(): MarkupProject = MarkupProject(\n        background = when (val behavior = backgroundBehavior) {\n            is BackgroundBehavior.Color -> ProjectBackground.Color(\n                width = behavior.width,\n                height = behavior.height,\n                color = behavior.color\n            )\n\n            is BackgroundBehavior.Image -> ProjectBackground.Image(\n                uri = _uri.value.toString()\n            )\n\n            BackgroundBehavior.None -> ProjectBackground.None\n        },\n        layers = layers.toProjectLayers(),\n        lastLayers = history.dropLast(1).lastOrNull()?.projectLayers() ?: emptyList(),\n        undoneLayers = redoHistory.lastOrNull()?.projectLayers() ?: emptyList(),\n        history = history.map { it.toProjectHistorySnapshot() },\n        redoHistory = redoHistory.map { it.toProjectHistorySnapshot() }\n    )\n\n    private suspend fun applyProject(\n        project: MarkupProject\n    ) {\n        cancelGroupingSelection()\n        _layers.value = emptyList()\n\n        when (val background = project.background) {\n            is ProjectBackground.Image -> {\n                _uri.value = background.uri.toUri()\n                _backgroundBehavior.value = BackgroundBehavior.Image\n                updateBitmapSync(\n                    bitmap = imageGetter.getImage(\n                        data = background.uri,\n                        originalSize = false\n                    )\n                )\n            }\n\n            is ProjectBackground.Color -> {\n                _uri.value = Uri.EMPTY\n                _backgroundBehavior.value = BackgroundBehavior.Color(\n                    width = background.width,\n                    height = background.height,\n                    color = background.color\n                )\n                updateBitmapSync(null)\n            }\n\n            ProjectBackground.None -> {\n                _uri.value = Uri.EMPTY\n                _backgroundBehavior.value = BackgroundBehavior.None\n                updateBitmapSync(null)\n            }\n        }\n\n        _layers.value = project.layers.map { it.asUi() }\n        if (project.history.isNotEmpty() || project.redoHistory.isNotEmpty()) {\n            restoreHistory(\n                historySnapshots = project.history.map { it.toInternalHistorySnapshot() },\n                redoSnapshots = project.redoHistory.map { it.toInternalHistorySnapshot() }\n            )\n        } else {\n            restoreHistory(\n                previousLayers = project.lastLayers,\n                redoneLayers = project.undoneLayers\n            )\n        }\n    }\n\n    private fun runEditorChange(\n        block: () -> Unit\n    ) {\n        val beforeSnapshot = pendingHistorySnapshot ?: currentHistorySnapshot()\n        pendingHistorySnapshot = null\n        block()\n        normalizeGroupingSelection()\n        commitHistoryFrom(beforeSnapshot)\n    }\n\n    private fun currentHistorySnapshot(): HistorySnapshot = HistorySnapshot(\n        backgroundBehavior = backgroundBehavior,\n        layers = layers.map(UiMarkupLayer::toSnapshot)\n    )\n\n    private fun commitHistoryFrom(beforeSnapshot: HistorySnapshot) {\n        pendingHistorySnapshot = null\n\n        val afterSnapshot = currentHistorySnapshot()\n        if (afterSnapshot == beforeSnapshot) return\n\n        _history.update { states ->\n            val normalizedStates = when {\n                states.isEmpty() -> listOf(beforeSnapshot)\n                states.last() == beforeSnapshot -> states\n                else -> (states + beforeSnapshot).takeLast(MAX_HISTORY_SIZE)\n            }\n\n            (normalizedStates + afterSnapshot).takeLast(MAX_HISTORY_SIZE)\n        }\n        _redoHistory.value = emptyList()\n        registerChanges()\n    }\n\n    private fun finalizePendingHistoryTransaction() {\n        pendingHistorySnapshot?.let(::commitHistoryFrom)\n    }\n\n    private fun resetHistory() {\n        restoreHistory()\n    }\n\n    private fun restoreHistory(\n        previousLayers: List<MarkupLayer> = emptyList(),\n        redoneLayers: List<MarkupLayer> = emptyList(),\n        historySnapshots: List<HistorySnapshot> = emptyList(),\n        redoSnapshots: List<HistorySnapshot> = emptyList()\n    ) {\n        pendingHistorySnapshot = null\n\n        val currentSnapshot = currentHistorySnapshot()\n        if (historySnapshots.isNotEmpty() || redoSnapshots.isNotEmpty()) {\n            val restoredHistory = historySnapshots\n                .ifEmpty { listOf(currentSnapshot) }\n                .let { snapshots ->\n                    if (snapshots.lastOrNull() == currentSnapshot) {\n                        snapshots\n                    } else {\n                        (snapshots + currentSnapshot).takeLast(MAX_HISTORY_SIZE)\n                    }\n                }\n            _history.value = restoredHistory.takeLast(MAX_HISTORY_SIZE)\n            _redoHistory.value = redoSnapshots.takeLast(MAX_HISTORY_SIZE)\n            return\n        }\n\n        val previousSnapshot = HistorySnapshot(\n            backgroundBehavior = currentSnapshot.backgroundBehavior,\n            layers = previousLayers.map { it.asUi().toSnapshot() }\n        ).takeIf { it != currentSnapshot }\n        val redoneSnapshot = HistorySnapshot(\n            backgroundBehavior = currentSnapshot.backgroundBehavior,\n            layers = redoneLayers.map { it.asUi().toSnapshot() }\n        ).takeIf { it != currentSnapshot }\n\n        _history.value = listOfNotNull(previousSnapshot, currentSnapshot)\n        _redoHistory.value = listOfNotNull(redoneSnapshot)\n    }\n\n    private fun applyHistorySnapshot(snapshot: HistorySnapshot) {\n        _backgroundBehavior.value = snapshot.backgroundBehavior\n        _layers.value = snapshot.layers.map(UiMarkupLayerSnapshot::toUi)\n        cancelGroupingSelection()\n    }\n\n    private data class HistorySnapshot(\n        val backgroundBehavior: BackgroundBehavior = BackgroundBehavior.None,\n        val layers: List<UiMarkupLayerSnapshot> = emptyList()\n    )\n\n    private fun HistorySnapshot.toProjectHistorySnapshot(): MarkupProjectHistorySnapshot =\n        MarkupProjectHistorySnapshot(\n            background = backgroundBehavior.toProjectBackground(),\n            layers = projectLayers()\n        )\n\n    private fun MarkupProjectHistorySnapshot.toInternalHistorySnapshot(): HistorySnapshot =\n        HistorySnapshot(\n            backgroundBehavior = background.toBackgroundBehavior(),\n            layers = layers.map { it.asUi().toSnapshot() }\n        )\n\n    private fun HistorySnapshot.projectLayers(): List<MarkupLayer> = layers.map(\n        UiMarkupLayerSnapshot::toUi\n    ).toProjectLayers()\n\n    private fun BackgroundBehavior.toProjectBackground(): ProjectBackground = when (this) {\n        is BackgroundBehavior.Color -> ProjectBackground.Color(\n            width = width,\n            height = height,\n            color = color\n        )\n\n        BackgroundBehavior.Image -> ProjectBackground.Image(\n            uri = _uri.value.toString()\n        )\n\n        BackgroundBehavior.None -> ProjectBackground.None\n    }\n\n    private fun ProjectBackground.toBackgroundBehavior(): BackgroundBehavior = when (this) {\n        is ProjectBackground.Color -> BackgroundBehavior.Color(\n            width = width,\n            height = height,\n            color = color\n        )\n\n        is ProjectBackground.Image -> BackgroundBehavior.Image\n        ProjectBackground.None -> BackgroundBehavior.None\n    }\n\n    private fun flattenLayers(\n        layers: List<UiMarkupLayer>\n    ): List<MarkupLayer> = layers.flatMap(UiMarkupLayer::flattenToDomain)\n\n    private fun List<UiMarkupLayer>.toProjectLayers(): List<MarkupLayer> = map(\n        UiMarkupLayer::asDomain\n    )\n\n    private fun normalizeGroupingSelection() {\n        if (groupingSelectionIds.isEmpty()) return\n\n        val validIds = layers.mapTo(mutableSetOf()) { it.id }\n        _groupingSelectionIds.update { ids ->\n            ids.filterTo(mutableSetOf()) { it in validIds }\n        }\n    }\n\n    private companion object {\n        const val MAX_HISTORY_SIZE = 50\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): MarkupLayersComponent\n    }\n\n}\n\nprivate fun EditBoxState.moveBy(\n    offsetChange: Offset,\n    cornerRadiusPercent: Int\n) {\n    val contentSize = contentSize\n    if (contentSize.width <= 0 || contentSize.height <= 0) {\n        offset += offsetChange\n        return\n    }\n\n    val canvasWidth = canvasSize.width.takeIf { it > 0 } ?: contentSize.width\n    val canvasHeight = canvasSize.height.takeIf { it > 0 } ?: contentSize.height\n\n    applyGlobalChanges(\n        parentMaxWidth = canvasWidth,\n        parentMaxHeight = canvasHeight,\n        contentSize = contentSize,\n        cornerRadiusPercent = cornerRadiusPercent,\n        zoomChange = 1f,\n        offsetChange = offsetChange,\n        rotationChange = 0f\n    )\n}\n\nprivate fun EditBoxState.resetPosition() {\n    offset = Offset.Zero\n}\n"
  },
  {
    "path": "feature/media-picker/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/media-picker/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.media_picker\"\n\ndependencies {\n    implementation(projects.core.crash)\n}\n"
  },
  {
    "path": "feature/media-picker/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application>\n        <activity\n            android:name=\".presentation.MediaPickerActivity\"\n            android:enabled=\"@bool/at_least_26\"\n            android:exported=\"true\"\n            android:launchMode=\"singleTask\"\n            android:windowSoftInputMode=\"adjustResize\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.PICK\" />\n                <action android:name=\"android.intent.action.GET_CONTENT\" />\n\n                <data android:mimeType=\"image/*\" />\n                <data android:mimeType=\"vnd.android.cursor.dir/image\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.OPENABLE\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/data/AndroidMediaRetriever.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.data\n\nimport android.content.ContentResolver\nimport android.content.Context\nimport android.os.Bundle\nimport android.provider.MediaStore\nimport androidx.annotation.RequiresApi\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.Query\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.contentFlowObserver\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.getAlbums\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.getMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.getSupportedFileSequence\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.MediaRetriever\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Album\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.MediaOrder\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.OrderType\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.conflate\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.map\nimport javax.inject.Inject\n\n@RequiresApi(26)\ninternal class AndroidMediaRetriever @Inject constructor(\n    @ApplicationContext private val context: Context,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, MediaRetriever {\n\n    override fun getAlbumsWithType(\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Album>>> = context.retrieveAlbums {\n        val query = Query.AlbumQuery().copy(\n            bundle = Bundle().apply {\n                val mimeType = when (allowedMedia) {\n                    is AllowedMedia.Photos -> \"image%\"\n                    AllowedMedia.Videos -> \"video%\"\n                    AllowedMedia.Both -> \"%/%\"\n                }\n                putString(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION,\n                    MediaStore.MediaColumns.MIME_TYPE + \" like ?\"\n                )\n                putStringArray(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,\n                    arrayOf(mimeType)\n                )\n            }\n        )\n        val fileQuery = Query.AlbumQuery().copy(\n            bundle = Bundle().apply {\n                val extensions = getSupportedFileSequence(allowedMedia).toList()\n                putString(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION,\n                    extensions.asSequence().map { MediaStore.MediaColumns.DATA + \" LIKE ?\" }\n                        .joinToString(\" OR \")\n                )\n                putStringArray(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,\n                    extensions.toTypedArray()\n                )\n            }\n        )\n        it.getAlbums(\n            query = query,\n            fileQuery = fileQuery,\n            mediaOrder = MediaOrder.Date(OrderType.Descending)\n        )\n    }\n\n    override fun mediaFlowWithType(\n        albumId: Long,\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Media>>> = if (albumId != -1L) {\n        getMediaByAlbumIdWithType(albumId, allowedMedia)\n    } else {\n        getMediaByType(allowedMedia)\n    }.flowOn(defaultDispatcher).conflate()\n\n    override fun getMediaByAlbumIdWithType(\n        albumId: Long,\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Media>>> = context.retrieveMedia {\n        val query = Query.MediaQuery().copy(\n            bundle = Bundle().apply {\n                val mimeType = when (allowedMedia) {\n                    is AllowedMedia.Photos -> \"image%\"\n                    AllowedMedia.Videos -> \"video%\"\n                    AllowedMedia.Both -> \"%/%\"\n                }\n                putString(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION,\n                    MediaStore.MediaColumns.BUCKET_ID + \"= ? and (\" + MediaStore.MediaColumns.MIME_TYPE + \" like ? OR ${MediaStore.MediaColumns.DATA} LIKE ? OR ${MediaStore.MediaColumns.DATA} LIKE ?)\"\n                )\n                putStringArray(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,\n                    arrayOf(albumId.toString(), mimeType, \"%.jxl\", \"%.qoi\")\n                )\n            }\n        )\n        val fileQuery = Query.MediaQuery().copy(\n            bundle = Bundle().apply {\n                val extensions = getSupportedFileSequence(allowedMedia).toList()\n\n                putString(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION,\n                    MediaStore.MediaColumns.BUCKET_ID + \"= ? and (\"\n                            + extensions.asSequence()\n                        .map { MediaStore.MediaColumns.DATA + \" LIKE ?\" }\n                        .joinToString(\" OR \")\n                            + \")\"\n                )\n                putStringArray(\n                    ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,\n                    arrayOf(albumId.toString(), *extensions.toTypedArray())\n                )\n            }\n        )\n        /** return@retrieveMedia */\n        it.getMedia(\n            mediaQuery = query,\n            fileQuery = fileQuery\n        )\n    }\n\n    override fun getMediaByType(\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Media>>> = context.retrieveMedia {\n        val query = when (allowedMedia) {\n            is AllowedMedia.Photos -> Query.PhotoQuery()\n            AllowedMedia.Videos -> Query.VideoQuery()\n            AllowedMedia.Both -> Query.MediaQuery()\n        }\n        val fileQuery = Query.FileQuery(getSupportedFileSequence(allowedMedia).toList())\n        it.getMedia(\n            mediaQuery = query,\n            fileQuery = fileQuery\n        )\n    }\n\n    private val uris = arrayOf(\n        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,\n        MediaStore.Video.Media.EXTERNAL_CONTENT_URI,\n        MediaStore.Files.getContentUri(\"external\")\n    )\n\n    private fun Context.retrieveMedia(\n        dataBody: suspend (ContentResolver) -> List<Media>\n    ) = contentFlowObserver(\n        uris = uris,\n        coroutineContext = ioDispatcher\n    ).map {\n        runSuspendCatching {\n            dataBody.invoke(contentResolver)\n        }\n    }.conflate()\n\n    private fun Context.retrieveAlbums(\n        dataBody: suspend (ContentResolver) -> List<Album>\n    ) = contentFlowObserver(\n        uris = uris,\n        coroutineContext = ioDispatcher\n    ).map {\n        runSuspendCatching {\n            dataBody.invoke(contentResolver)\n        }\n    }.conflate()\n\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/data/utils/DateExt.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.data.utils\n\nimport android.text.format.DateFormat\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.DEFAULT_DATE_FORMAT\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.EXTENDED_DATE_FORMAT\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.WEEKLY_DATE_FORMAT\nimport java.text.ParseException\nimport java.text.SimpleDateFormat\nimport java.util.Calendar\nimport java.util.Locale\nimport java.util.concurrent.TimeUnit\n\ndata class DateExt(\n    val month: String,\n    val day: Int,\n    val year: Int\n)\n\nfun Long.getDateExt(): DateExt {\n    val mediaDate = Calendar.getInstance(Locale.US)\n    mediaDate.timeInMillis = this * 1000L\n    return DateExt(\n        month = mediaDate.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.US)!!,\n        day = mediaDate.get(Calendar.DAY_OF_MONTH),\n        year = mediaDate.get(Calendar.YEAR)\n    )\n}\n\nfun Long.getDate(\n    format: CharSequence = DEFAULT_DATE_FORMAT,\n): String {\n    val mediaDate = Calendar.getInstance(Locale.US)\n    mediaDate.timeInMillis = this * 1000L\n    return DateFormat.format(format, mediaDate).toString()\n}\n\nfun Long.getDate(\n    format: CharSequence = DEFAULT_DATE_FORMAT,\n    weeklyFormat: CharSequence = WEEKLY_DATE_FORMAT,\n    extendedFormat: CharSequence = EXTENDED_DATE_FORMAT,\n    stringToday: String,\n    stringYesterday: String\n): String {\n    val currentDate = Calendar.getInstance(Locale.US)\n    currentDate.timeInMillis = System.currentTimeMillis()\n    val mediaDate = Calendar.getInstance(Locale.US)\n    mediaDate.timeInMillis = this * 1000L\n    val different: Long = System.currentTimeMillis() - mediaDate.timeInMillis\n    val secondsInMilli: Long = 1000\n    val minutesInMilli = secondsInMilli * 60\n    val hoursInMilli = minutesInMilli * 60\n    val daysInMilli = hoursInMilli * 24\n\n    val daysDifference = different / daysInMilli\n\n    return when (daysDifference.toInt()) {\n        0 -> {\n            if (currentDate.get(Calendar.DATE) != mediaDate.get(Calendar.DATE)) {\n                stringYesterday\n            } else {\n                stringToday\n            }\n        }\n\n        1 -> {\n            stringYesterday\n        }\n\n        else -> {\n            if (daysDifference.toInt() in 2..5) {\n                DateFormat.format(weeklyFormat, mediaDate).toString()\n            } else {\n                if (currentDate.get(Calendar.YEAR) > mediaDate.get(Calendar.YEAR)) {\n                    DateFormat.format(extendedFormat, mediaDate).toString()\n                } else DateFormat.format(format, mediaDate).toString()\n            }\n        }\n    }\n}\n\nfun Long.getMonth(): String {\n    val currentDate =\n        Calendar.getInstance(Locale.US).apply { timeInMillis = System.currentTimeMillis() }\n    val mediaDate = Calendar.getInstance(Locale.US).apply { timeInMillis = this@getMonth * 1000L }\n    val month = mediaDate.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.US)!!\n    val year = mediaDate.get(Calendar.YEAR)\n    return if (currentDate.get(Calendar.YEAR) != mediaDate.get(Calendar.YEAR))\n        \"$month $year\"\n    else month\n}\n\nfun getMonth(date: String): String {\n    return try {\n        val dateFormatExtended =\n            SimpleDateFormat(EXTENDED_DATE_FORMAT, Locale.US).parse(date)\n        val cal = Calendar.getInstance(Locale.US).apply { timeInMillis = dateFormatExtended!!.time }\n        val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.US)!!\n        val year = cal.get(Calendar.YEAR)\n        \"$month $year\"\n    } catch (e: ParseException) {\n        try {\n            val dateFormat = SimpleDateFormat(DEFAULT_DATE_FORMAT, Locale.US).parse(date)\n            val cal = Calendar.getInstance(Locale.US).apply { timeInMillis = dateFormat!!.time }\n            cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.US)!!\n        } catch (e: ParseException) {\n            \"\"\n        }\n    }\n}\n\nfun getDateHeader(\n    startDate: DateExt,\n    endDate: DateExt\n): String {\n    return if (startDate.year == endDate.year) {\n        if (startDate.month == endDate.month) {\n            if (startDate.day == endDate.day) {\n                \"${startDate.month} ${startDate.day}, ${startDate.year}\"\n            } else \"${startDate.month} ${startDate.day} - ${endDate.day}, ${startDate.year}\"\n        } else\n            \"${startDate.month} ${startDate.day} - ${endDate.month} ${endDate.day}, ${startDate.year}\"\n    } else {\n        \"${startDate.month} ${startDate.day}, ${startDate.year} - ${endDate.month} ${endDate.day}, ${endDate.year}\"\n    }\n}\n\nfun Long.formatMinSec(): String {\n    return if (this == 0L) {\n        \"00:00\"\n    } else {\n        String.format(\n            locale = Locale.getDefault(),\n            format = \"%02d:%02d\",\n            TimeUnit.MILLISECONDS.toMinutes(this),\n            TimeUnit.MILLISECONDS.toSeconds(this) -\n                    TimeUnit.MINUTES.toSeconds(\n                        TimeUnit.MILLISECONDS.toMinutes(this)\n                    )\n        )\n    }\n}\n\nfun String?.formatMinSec(): String {\n    return when (val value = this?.toLong()) {\n        null -> \"\"\n        else -> value.formatMinSec()\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/data/utils/MediaObserver.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.data.utils\n\nimport android.content.ContentResolver\nimport android.content.ContentUris\nimport android.content.Context\nimport android.database.ContentObserver\nimport android.database.Cursor\nimport android.database.MergeCursor\nimport android.net.Uri\nimport android.os.Build\nimport android.provider.MediaStore\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.FULL_DATE_FORMAT\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.MediaOrder\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.OrderType\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.channels.awaitClose\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.callbackFlow\nimport kotlinx.coroutines.flow.conflate\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.launch\nimport kotlin.coroutines.CoroutineContext\nimport kotlin.io.path.Path\nimport kotlin.io.path.extension\n\nprivate var observerJob: Job? = null\n\n/**\n * Register an observer class that gets callbacks when data identified by a given content URI\n * changes.\n */\nfun Context.contentFlowObserver(\n    uris: Array<Uri>,\n    coroutineContext: CoroutineContext\n) = callbackFlow {\n    val observer = object : ContentObserver(null) {\n        override fun onChange(selfChange: Boolean) {\n            observerJob?.cancel()\n            observerJob = launch(coroutineContext) {\n                send(false)\n            }\n        }\n    }\n    for (uri in uris) {\n        contentResolver.registerContentObserver(uri, true, observer)\n    }\n    // trigger first.\n    observerJob = launch(coroutineContext) {\n        send(true)\n    }\n    awaitClose {\n        contentResolver.unregisterContentObserver(observer)\n    }\n}.conflate().onEach { if (!it) delay(1000) }\n\nsuspend fun ContentResolver.getMedia(\n    mediaQuery: Query = Query.MediaQuery(),\n    fileQuery: Query = Query.MediaQuery(),\n    mediaOrder: MediaOrder = MediaOrder.Date(OrderType.Descending)\n): List<Media> {\n    return coroutineScope {\n        val media = mutableListOf<Media>()\n        query(mediaQuery, fileQuery).use { cursor ->\n            while (cursor.moveToNext()) {\n                try {\n                    media.add(cursor.getMediaFromCursor())\n                } catch (e: Throwable) {\n                    e.printStackTrace()\n                }\n            }\n        }\n\n        mediaOrder.sortMedia(media)\n    }\n}\n\n\nfun Cursor.getMediaFromCursor(): Media {\n    val id: Long =\n        getLong(getColumnIndexOrThrow(MediaStore.MediaColumns._ID))\n    val path: String =\n        getString(getColumnIndexOrThrow(MediaStore.MediaColumns.DATA))\n    val relativePath: String =\n        getString(\n            getColumnIndexOrThrow(\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                    MediaStore.MediaColumns.RELATIVE_PATH\n                } else MediaStore.MediaColumns.DATA\n            )\n        )\n    val title: String =\n        getString(getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME))\n    val albumID: Long =\n        getLong(getColumnIndexOrThrow(MediaStore.MediaColumns.BUCKET_ID))\n    val albumLabel: String = try {\n        getString(\n            getColumnIndexOrThrow(\n                MediaStore.MediaColumns.BUCKET_DISPLAY_NAME\n            )\n        )\n    } catch (_: Throwable) {\n        Build.MODEL\n    }\n    val takenTimestamp: Long? = try {\n        getLong(getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_TAKEN))\n    } catch (_: Throwable) {\n        null\n    }\n    val modifiedTimestamp: Long =\n        getLong(getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED))\n    val duration: String? = try {\n        getString(getColumnIndexOrThrow(MediaStore.MediaColumns.DURATION))\n    } catch (_: Throwable) {\n        null\n    }\n\n    val expiryTimestamp: Long? = try {\n        getLong(getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_EXPIRES))\n    } catch (_: Throwable) {\n        null\n    }\n\n    val (mimeType, contentUri) = SUPPORTED_FILES[Path(path).extension]?.let { (mimeType, _) ->\n        Pair(mimeType, MediaStore.Files.getContentUri(\"external\"))\n    } ?: run {\n        val mimeType: String =\n            getString(getColumnIndexOrThrow(MediaStore.MediaColumns.MIME_TYPE))\n\n        val contentUri = if (mimeType.contains(\"image\"))\n            MediaStore.Images.Media.EXTERNAL_CONTENT_URI\n        else\n            MediaStore.Video.Media.EXTERNAL_CONTENT_URI\n\n        Pair(mimeType, contentUri)\n    }\n\n    val uri = ContentUris.withAppendedId(contentUri, id)\n    val formattedDate = modifiedTimestamp.getDate(FULL_DATE_FORMAT)\n\n    return Media(\n        id = id,\n        label = title,\n        uri = uri.toString(),\n        path = path,\n        relativePath = relativePath,\n        albumID = albumID,\n        albumLabel = albumLabel,\n        timestamp = modifiedTimestamp,\n        takenTimestamp = takenTimestamp,\n        expiryTimestamp = expiryTimestamp,\n        fullDate = formattedDate,\n        duration = duration,\n        mimeType = mimeType,\n    )\n}\n\nsuspend fun ContentResolver.query(\n    mediaQuery: Query,\n    fileQuery: Query\n): Cursor = coroutineScope {\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n        MergeCursor(\n            arrayOf(\n                query(\n                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,\n                    mediaQuery.projection,\n                    mediaQuery.bundle,\n                    null\n                ),\n                query(\n                    MediaStore.Files.getContentUri(\"external\"),\n                    fileQuery.projection,\n                    fileQuery.bundle,\n                    null\n                ),\n                query(\n                    MediaStore.Video.Media.EXTERNAL_CONTENT_URI,\n                    mediaQuery.projection,\n                    mediaQuery.bundle,\n                    null\n                )\n            )\n        )\n    } else {\n        MergeCursor(\n            arrayOf(\n                query(\n                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,\n                    mediaQuery.projection,\n                    null,\n                    null,\n                    null\n                ),\n                query(\n                    MediaStore.Files.getContentUri(\"external\"),\n                    fileQuery.projection,\n                    null,\n                    null,\n                    null\n                ),\n                query(\n                    MediaStore.Video.Media.EXTERNAL_CONTENT_URI,\n                    mediaQuery.projection,\n                    null,\n                    null,\n                    null\n                )\n            )\n        )\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/data/utils/MediaQuery.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.data.utils\n\nimport android.content.ContentResolver\nimport android.content.ContentUris\nimport android.os.Build\nimport android.os.Bundle\nimport android.provider.MediaStore\nimport androidx.annotation.RequiresApi\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Album\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.MediaOrder\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.OrderType\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.coroutineScope\n\n@RequiresApi(26)\nsealed class Query(\n    var projection: Array<String>,\n    var bundle: Bundle? = null\n) {\n    class MediaQuery : Query(\n        projection = listOfNotNull(\n            MediaStore.MediaColumns._ID,\n            MediaStore.MediaColumns.DATA,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.RELATIVE_PATH\n            } else MediaStore.MediaColumns.DATA,\n            MediaStore.MediaColumns.DISPLAY_NAME,\n            MediaStore.MediaColumns.BUCKET_ID,\n            MediaStore.MediaColumns.DATE_MODIFIED,\n            MediaStore.MediaColumns.DATE_TAKEN,\n            MediaStore.MediaColumns.BUCKET_DISPLAY_NAME,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.DURATION\n            } else null,\n            MediaStore.MediaColumns.MIME_TYPE\n        ).toTypedArray(),\n    )\n\n    class PhotoQuery : Query(\n        projection = listOfNotNull(\n            MediaStore.MediaColumns._ID,\n            MediaStore.MediaColumns.DATA,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.RELATIVE_PATH\n            } else MediaStore.MediaColumns.DATA,\n            MediaStore.MediaColumns.DISPLAY_NAME,\n            MediaStore.MediaColumns.BUCKET_ID,\n            MediaStore.MediaColumns.DATE_MODIFIED,\n            MediaStore.MediaColumns.DATE_TAKEN,\n            MediaStore.MediaColumns.BUCKET_DISPLAY_NAME,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.DURATION\n            } else null,\n            MediaStore.MediaColumns.MIME_TYPE\n        ).toTypedArray(),\n        bundle = defaultBundle.apply {\n            putString(\n                ContentResolver.QUERY_ARG_SQL_SELECTION,\n                MediaStore.MediaColumns.MIME_TYPE + \" like ?\"\n            )\n            putStringArray(\n                ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,\n                arrayOf(\"image%\")\n            )\n        }\n    )\n\n    class VideoQuery : Query(\n        projection = listOfNotNull(\n            MediaStore.MediaColumns._ID,\n            MediaStore.MediaColumns.DATA,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.RELATIVE_PATH\n            } else MediaStore.MediaColumns.DATA,\n            MediaStore.MediaColumns.DISPLAY_NAME,\n            MediaStore.MediaColumns.BUCKET_ID,\n            MediaStore.MediaColumns.DATE_MODIFIED,\n            MediaStore.MediaColumns.BUCKET_DISPLAY_NAME,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.DURATION\n            } else null,\n            MediaStore.MediaColumns.MIME_TYPE,\n            MediaStore.MediaColumns.ORIENTATION\n        ).toTypedArray(),\n        bundle = defaultBundle.apply {\n            putString(\n                ContentResolver.QUERY_ARG_SQL_SELECTION,\n                MediaStore.MediaColumns.MIME_TYPE + \" LIKE ?\"\n            )\n            putStringArray(\n                ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,\n                arrayOf(\"video%\")\n            )\n        }\n    )\n\n    class AlbumQuery : Query(\n        projection = arrayOf(\n            MediaStore.MediaColumns.BUCKET_ID,\n            MediaStore.MediaColumns.BUCKET_DISPLAY_NAME,\n            MediaStore.MediaColumns.DISPLAY_NAME,\n            MediaStore.MediaColumns.DATA,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.RELATIVE_PATH\n            } else MediaStore.MediaColumns.DATA,\n            MediaStore.MediaColumns._ID,\n            MediaStore.MediaColumns.MIME_TYPE,\n            MediaStore.MediaColumns.DATE_MODIFIED,\n            MediaStore.MediaColumns.DATE_TAKEN\n        )\n    )\n\n    class FileQuery(fileExtensions: List<String>) : Query(\n        projection = listOfNotNull(\n            MediaStore.MediaColumns._ID,\n            MediaStore.MediaColumns.DATA,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.RELATIVE_PATH\n            } else MediaStore.MediaColumns.DATA,\n            MediaStore.MediaColumns.DISPLAY_NAME,\n            MediaStore.MediaColumns.BUCKET_ID,\n            MediaStore.MediaColumns.DATE_MODIFIED,\n            MediaStore.MediaColumns.DATE_TAKEN,\n            MediaStore.MediaColumns.BUCKET_DISPLAY_NAME,\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                MediaStore.MediaColumns.DURATION\n            } else null,\n            MediaStore.MediaColumns.MIME_TYPE\n        ).toTypedArray(),\n        bundle = defaultBundle.deepCopy().apply {\n            putString(\n                ContentResolver.QUERY_ARG_SQL_SELECTION,\n                fileExtensions.indices.asSequence().map { \"${MediaStore.MediaColumns.DATA} like ?\" }\n                    .joinToString(\" OR \")\n            )\n            putStringArray(\n                ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,\n                fileExtensions.toTypedArray()\n            )\n        }\n    )\n\n    fun copy(\n        projection: Array<String> = this.projection,\n        bundle: Bundle? = this.bundle,\n    ): Query {\n        this.projection = projection\n        this.bundle = bundle\n        return this\n    }\n\n    companion object {\n        val defaultBundle = Bundle().apply {\n            putStringArray(\n                ContentResolver.QUERY_ARG_SORT_COLUMNS,\n                arrayOf(MediaStore.MediaColumns.DATE_MODIFIED)\n            )\n            putInt(\n                ContentResolver.QUERY_ARG_SQL_SORT_ORDER,\n                ContentResolver.QUERY_SORT_DIRECTION_DESCENDING\n            )\n        }\n    }\n\n}\n\n@RequiresApi(26)\nprivate fun Query.copyAsAlbum(): Query {\n    val bundle = this.bundle ?: Bundle()\n\n    return this.copy(\n        bundle = bundle.apply {\n            putInt(\n                ContentResolver.QUERY_ARG_SORT_DIRECTION,\n                ContentResolver.QUERY_SORT_DIRECTION_DESCENDING\n            )\n            putStringArray(\n                ContentResolver.QUERY_ARG_SORT_COLUMNS,\n                arrayOf(MediaStore.MediaColumns.DATE_MODIFIED)\n            )\n        }\n    )\n}\n\n@RequiresApi(26)\nsuspend fun ContentResolver.getAlbums(\n    query: Query = Query.AlbumQuery(),\n    fileQuery: Query = Query.AlbumQuery(),\n    mediaOrder: MediaOrder = MediaOrder.Date(OrderType.Descending)\n): List<Album> = coroutineScope {\n    val timeStart = System.currentTimeMillis()\n    val albums = mutableListOf<Album>()\n    val albumQuery = query.copyAsAlbum()\n    val albumFileQuery = fileQuery.copyAsAlbum()\n\n    query(\n        mediaQuery = albumQuery,\n        fileQuery = albumFileQuery\n    ).use {\n        with(it) {\n            while (moveToNext()) {\n                runCatching {\n                    val albumId =\n                        getLong(getColumnIndexOrThrow(MediaStore.MediaColumns.BUCKET_ID))\n                    val id = getLong(getColumnIndexOrThrow(MediaStore.MediaColumns._ID))\n                    val label: String? = try {\n                        getString(\n                            getColumnIndexOrThrow(\n                                MediaStore.MediaColumns.BUCKET_DISPLAY_NAME\n                            )\n                        )\n                    } catch (_: Throwable) {\n                        Build.MODEL\n                    }\n                    val thumbnailPath =\n                        getString(getColumnIndexOrThrow(MediaStore.MediaColumns.DATA))\n                    val thumbnailRelativePath =\n                        getString(\n                            getColumnIndexOrThrow(\n                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                                    MediaStore.MediaColumns.RELATIVE_PATH\n                                } else MediaStore.MediaColumns.DATA\n                            )\n                        )\n                    val thumbnailDate =\n                        getLong(getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED))\n                    val mimeType =\n                        getString(getColumnIndexOrThrow(MediaStore.MediaColumns.MIME_TYPE))\n                    val contentUri = if (mimeType.contains(\"image\"))\n                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI\n                    else\n                        MediaStore.Video.Media.EXTERNAL_CONTENT_URI\n                    val album = Album(\n                        id = albumId,\n                        label = label ?: Build.MODEL,\n                        uri = ContentUris.withAppendedId(contentUri, id).toString(),\n                        pathToThumbnail = thumbnailPath,\n                        relativePath = thumbnailRelativePath,\n                        timestamp = thumbnailDate,\n                        count = 1\n                    )\n                    val currentAlbum = albums.find { a -> a.id == albumId }\n                    if (currentAlbum == null)\n                        albums.add(album)\n                    else {\n                        val i = albums.indexOf(currentAlbum)\n                        albums[i] = albums[i].let { a -> a.copy(count = a.count + 1) }\n                        if (albums[i].timestamp <= thumbnailDate) {\n                            albums[i] = album.copy(count = albums[i].count)\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    mediaOrder.sortAlbums(albums).also {\n        \"Album parsing took: ${System.currentTimeMillis() - timeStart}ms\".makeLog()\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/data/utils/SupportedFiles.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.data.utils\n\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\n\nenum class FileType {\n    Photo,\n    Video\n}\n\nval SUPPORTED_FILES = mapOf(\n    \"jxl\" to Pair(\"image/jxl\", FileType.Photo),\n    \"qoi\" to Pair(\"image/qoi\", FileType.Photo)\n)\n\nfun getSupportedFileSequence(allowedMedia: AllowedMedia) = when (allowedMedia) {\n    AllowedMedia.Both -> SUPPORTED_FILES.asSequence()\n    is AllowedMedia.Photos -> SUPPORTED_FILES.asSequence()\n        .filter { (_, p) -> p.second == FileType.Photo }\n\n    AllowedMedia.Videos -> SUPPORTED_FILES.asSequence()\n        .filter { (_, p) -> p.second == FileType.Video }\n}.map { (ext, _) -> \"%.$ext\" }"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/di/MediaPickerModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.di\n\nimport com.t8rin.imagetoolbox.feature.media_picker.data.AndroidMediaRetriever\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.MediaRetriever\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface MediaPickerModule {\n\n    @Binds\n    @Singleton\n    fun mediaRetriever(\n        impl: AndroidMediaRetriever\n    ): MediaRetriever\n\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/MediaRetriever.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.domain\n\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Album\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\nimport kotlinx.coroutines.flow.Flow\n\ninterface MediaRetriever {\n\n    fun getAlbumsWithType(\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Album>>>\n\n    fun mediaFlowWithType(\n        albumId: Long,\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Media>>>\n\n    fun getMediaByAlbumIdWithType(\n        albumId: Long,\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Media>>>\n\n    fun getMediaByType(\n        allowedMedia: AllowedMedia\n    ): Flow<Result<List<Media>>>\n\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/model/Album.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\npackage com.t8rin.imagetoolbox.feature.media_picker.domain.model\n\ndata class Album(\n    val id: Long = 0,\n    val label: String,\n    val uri: String,\n    val pathToThumbnail: String,\n    val relativePath: String,\n    val timestamp: Long,\n    val count: Long = 0,\n    val selected: Boolean = false,\n    val isPinned: Boolean = false,\n) {\n\n    val volume: String =\n        pathToThumbnail.substringBeforeLast(\"/\").removeSuffix(relativePath.removeSuffix(\"/\"))\n\n    val isOnSdcard: Boolean =\n        volume.lowercase().matches(\".*[0-9a-f]{4}-[0-9a-f]{4}\".toRegex())\n\n    companion object {\n\n        val NewAlbum = Album(\n            id = -200,\n            label = \"New Album\",\n            uri = \"\",\n            pathToThumbnail = \"\",\n            relativePath = \"\",\n            timestamp = 0,\n            count = 0,\n        )\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/model/AllowedMedia.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.domain.model\n\nsealed class AllowedMedia {\n    data class Photos(val ext: String?) : AllowedMedia()\n    data object Videos : AllowedMedia()\n    data object Both : AllowedMedia()\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/model/Media.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.imagetoolbox.feature.media_picker.domain.model\n\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.utils.humanFileSize\nimport com.t8rin.imagetoolbox.core.utils.fileSize\n\n\ndata class Media(\n    val id: Long = 0,\n    val label: String,\n    val uri: String,\n    val path: String,\n    val relativePath: String,\n    val albumID: Long,\n    val albumLabel: String,\n    val timestamp: Long,\n    val expiryTimestamp: Long? = null,\n    val takenTimestamp: Long? = null,\n    val fullDate: String,\n    val mimeType: String,\n    val duration: String? = null,\n) {\n    val fileSize: Long by lazy { uri.toUri().fileSize() ?: 0 }\n\n    val humanFileSize: String by lazy { humanFileSize(fileSize) }\n\n    val isVideo: Boolean = mimeType.startsWith(\"video/\") && duration != null\n\n    val isImage: Boolean = mimeType.startsWith(\"image/\")\n\n    /**\n     * Used to determine if the Media object is not accessible\n     * via MediaStore.\n     * This happens when the user tries to open media from an app\n     * using external sources (in our case, Gallery Media Viewer), but\n     * the specific media is only available internally in that app\n     * (Android/data(OR media)/com.package.name/)\n     *\n     * If it's readUriOnly then we know that we should expect a barebone\n     * Media object with limited functionality (no favorites, trash, timestamp etc)\n     */\n    val readUriOnly: Boolean = albumID == -99L && albumLabel == \"\"\n\n    /**\n     * Determine if the current media is a raw format\n     *\n     * Checks if [mimeType] starts with \"image/x-\" or \"image/vnd.\"\n     *\n     * Most used formats:\n     * - ARW: image/x-sony-arw\n     * - CR2: image/x-canon-cr2\n     * - CRW: image/x-canon-crw\n     * - DCR: image/x-kodak-dcr\n     * - DNG: image/x-adobe-dng\n     * - ERF: image/x-epson-erf\n     * - K25: image/x-kodak-k25\n     * - KDC: image/x-kodak-kdc\n     * - MRW: image/x-minolta-mrw\n     * - NEF: image/x-nikon-nef\n     * - ORF: image/x-olympus-orf\n     * - PEF: image/x-pentax-pef\n     * - RAF: image/x-fuji-raf\n     * - RAW: image/x-panasonic-raw\n     * - SR2: image/x-sony-sr2\n     * - SRF: image/x-sony-srf\n     * - X3F: image/x-sigma-x3f\n     *\n     * Other proprietary image types in the standard:\n     * image/vnd.manufacturer.filename_extension for instance for NEF by Nikon and .mrv for Minolta:\n     * - NEF: image/vnd.nikon.nef\n     * - Minolta: image/vnd.minolta.mrw\n     */\n    val isRaw: Boolean =\n        mimeType.isNotBlank() && (mimeType.startsWith(\"image/x-\") || mimeType.startsWith(\"image/vnd.\"))\n\n    val fileExtension: String = label.substringAfterLast(\".\").removePrefix(\".\")\n\n    val volume: String = path.substringBeforeLast(\"/\").removeSuffix(relativePath.removeSuffix(\"/\"))\n}\n\nconst val WEEKLY_DATE_FORMAT = \"EEEE\"\nconst val DEFAULT_DATE_FORMAT = \"EEE, MMMM d\"\nconst val EXTENDED_DATE_FORMAT = \"EEE, MMM d, yyyy\"\nconst val FULL_DATE_FORMAT = \"EEEE, MMMM d, yyyy, hh:mm a\"\nconst val HEADER_DATE_FORMAT = \"MMMM d, yyyy\\n\" + \"h:mm a\"\nconst val EXIF_DATE_FORMAT = \"MMMM d, yyyy • h:mm a\""
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/model/MediaItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\npackage com.t8rin.imagetoolbox.feature.media_picker.domain.model\n\nsealed class MediaItem {\n\n    abstract val key: String\n\n    data class Header(\n        override val key: String,\n        val text: String,\n        val data: List<Media>\n    ) : MediaItem()\n\n    data class MediaViewItem(\n        override val key: String,\n        val media: Media\n    ) : MediaItem()\n\n}\n\nval Any.isHeaderKey: Boolean\n    get() = this is String && this.startsWith(\"header_\")\n\nval Any.isBigHeaderKey: Boolean\n    get() = this is String && this.startsWith(\"header_big_\")\n\nval Any.isIgnoredKey: Boolean\n    get() = this is String && this == \"aboveGrid\""
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/model/MediaOrder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.domain.model\n\nimport kotlinx.coroutines.coroutineScope\n\nsealed class MediaOrder(private val orderType: OrderType) {\n    class Label(orderType: OrderType) : MediaOrder(orderType)\n    class Date(orderType: OrderType) : MediaOrder(orderType)\n    class Expiry(orderType: OrderType = OrderType.Descending) : MediaOrder(orderType)\n\n    fun copy(orderType: OrderType): MediaOrder {\n        return when (this) {\n            is Date -> Date(orderType)\n            is Label -> Label(orderType)\n            is Expiry -> Expiry(orderType)\n        }\n    }\n\n    suspend fun sortMedia(media: List<Media>): List<Media> = coroutineScope {\n        when (orderType) {\n            OrderType.Ascending -> {\n                when (this@MediaOrder) {\n                    is Date -> media.sortedBy { it.timestamp }\n                    is Label -> media.sortedBy { it.label.lowercase() }\n                    is Expiry -> media.sortedBy { it.expiryTimestamp ?: it.timestamp }\n                }\n            }\n\n            OrderType.Descending -> {\n                when (this@MediaOrder) {\n                    is Date -> media.sortedByDescending { it.timestamp }\n                    is Label -> media.sortedByDescending { it.label.lowercase() }\n                    is Expiry -> media.sortedByDescending { it.expiryTimestamp ?: it.timestamp }\n                }\n            }\n        }\n    }\n\n    fun sortAlbums(albums: List<Album>): List<Album> {\n        return when (orderType) {\n            OrderType.Ascending -> {\n                when (this) {\n                    is Date -> albums.sortedBy { it.timestamp }\n                    is Label -> albums.sortedBy { it.label.lowercase() }\n                    else -> albums\n                }\n            }\n\n            OrderType.Descending -> {\n                when (this) {\n                    is Date -> albums.sortedByDescending { it.timestamp }\n                    is Label -> albums.sortedByDescending { it.label.lowercase() }\n                    else -> albums\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/model/MediaState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.domain.model\n\ndata class MediaState(\n    val media: List<Media> = emptyList(),\n    val mappedMedia: List<MediaItem> = emptyList(),\n    val dateHeader: String = \"\",\n    val error: String = \"\",\n    val isLoading: Boolean = true\n)\n\ndata class AlbumState(\n    val albums: List<Album> = emptyList(),\n    val error: String = \"\"\n)"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/domain/model/OrderType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.domain.model\n\nsealed class OrderType {\n    data object Ascending : OrderType()\n    data object Descending : OrderType()\n}\n"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/MediaPickerActivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation\n\nimport androidx.compose.runtime.Composable\nimport com.arkivanov.decompose.retainedComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.ComposeActivity\nimport com.t8rin.imagetoolbox.feature.media_picker.presentation.components.MediaPickerRootContent\nimport com.t8rin.imagetoolbox.feature.media_picker.presentation.screenLogic.MediaPickerComponent\nimport dagger.hilt.android.AndroidEntryPoint\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nclass MediaPickerActivity : ComposeActivity() {\n\n    @Inject\n    lateinit var componentFactory: MediaPickerComponent.Factory\n\n    private val component: MediaPickerComponent by lazy {\n        retainedComponent(factory = componentFactory::invoke)\n    }\n\n    @Composable\n    override fun Content() = MediaPickerRootContent(component)\n\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/ManageExternalStorageWarning.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.WarningAmber\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun ManageExternalStorageWarning(\n    onRequestManagePermission: () -> Unit\n) {\n    Row(\n        modifier = Modifier\n            .container(\n                color = MaterialTheme.colorScheme.errorContainer,\n                resultPadding = 0.dp,\n                shape = RectangleShape\n            )\n            .padding(\n                start = 16.dp,\n                end = 16.dp,\n                top = 16.dp,\n                bottom = 16.dp\n            ),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Column(modifier = Modifier.weight(1f)) {\n            Row(\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.WarningAmber,\n                    contentDescription = null,\n                    tint = MaterialTheme.colorScheme.error\n                )\n                Spacer(modifier = Modifier.width(8.dp))\n                Text(\n                    text = stringResource(R.string.manage_storage_extra_types),\n                    color = MaterialTheme.colorScheme.error,\n                    style = MaterialTheme.typography.bodyLarge,\n                    lineHeight = 18.sp,\n                    modifier = Modifier.weight(1f, false)\n                )\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            Text(\n                text = stringResource(R.string.manage_storage_extra_types_sub),\n                color = MaterialTheme.colorScheme.onBackground,\n                style = MaterialTheme.typography.bodyMedium,\n                lineHeight = 16.sp,\n                textAlign = TextAlign.Start\n            )\n        }\n        Spacer(modifier = Modifier.width(8.dp))\n        EnhancedButton(\n            containerColor = MaterialTheme.colorScheme.error,\n            contentColor = MaterialTheme.colorScheme.onError,\n            onClick = onRequestManagePermission\n        ) {\n            Text(text = stringResource(R.string.request))\n        }\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaExtensionHeader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.advancedShadow\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\n\n@Composable\nfun MediaExtensionHeader(\n    modifier: Modifier = Modifier,\n    media: Media\n) {\n    Row(\n        modifier = modifier\n            .padding(8.dp)\n            .padding(vertical = 2.dp)\n            .advancedShadow(\n                cornersRadius = 4.dp,\n                shadowBlurRadius = 6.dp,\n                alpha = 0.4f\n            )\n            .padding(horizontal = 2.dp),\n        horizontalArrangement = Arrangement.End,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Text(\n            modifier = Modifier,\n            text = media.fileExtension.uppercase(),\n            style = MaterialTheme.typography.labelMedium,\n            color = White\n        )\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.animation.animateColor\nimport androidx.compose.animation.core.animateDp\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.updateTransition\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.CheckCircle\nimport androidx.compose.material.icons.filled.Error\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.TransformOrigin\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport coil3.request.ImageRequest\nimport coil3.request.allowHardware\nimport coil3.size.Precision\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.MediaCheckBox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\n\n@Composable\nfun MediaImage(\n    modifier: Modifier = Modifier,\n    media: Media,\n    isInSelection: Boolean = true,\n    isSelected: Boolean,\n    selectionIndex: Int,\n    canClick: Boolean,\n    onItemClick: (Media) -> Unit,\n    onItemLongClick: (Media) -> Unit,\n) {\n    val transition = updateTransition(isSelected)\n\n    val selectedSize = transition.animateDp {\n        if (it) 12.dp else 0.dp\n    }\n    val scale = transition.animateFloat {\n        if (it) 0.5f else 1f\n    }\n    var isImageError by remember {\n        mutableStateOf(false)\n    }\n    val strokeColor = takeColorFromScheme {\n        if (isSelected) {\n            if (isImageError) errorContainer\n            else primaryContainer\n        } else Color.Transparent\n    }\n\n    Box(\n        modifier = modifier\n            .clip(ShapeDefaults.extraSmall)\n            .background(MaterialTheme.colorScheme.surfaceContainer)\n            .then(\n                if (canClick) {\n                    Modifier.hapticsCombinedClickable(\n                        onClick = {\n                            onItemClick(media)\n                        },\n                        onLongClick = {\n                            onItemLongClick(media)\n                        },\n                    )\n                } else Modifier\n            )\n            .aspectRatio(1f)\n    ) {\n        val shape = animateShape(\n            if (isSelected) {\n                AutoCornersShape(16.dp)\n            } else {\n                AutoCornersShape(4.dp)\n            }\n        )\n\n        Box(\n            modifier = Modifier\n                .align(Alignment.Center)\n                .aspectRatio(1f)\n                .padding(selectedSize.value)\n                .clip(shape)\n                .border(\n                    width = if (isSelected) 2.dp else 0.dp,\n                    shape = shape,\n                    color = strokeColor\n                )\n                .background(\n                    color = MaterialTheme.colorScheme.surfaceContainerHigh,\n                    shape = shape\n                )\n        ) {\n            Picture(\n                modifier = Modifier.fillMaxSize(),\n                model = remember(media.uri) {\n                    ImageRequest.Builder(appContext)\n                        .data(media.uri)\n                        .size(384)\n                        .precision(Precision.INEXACT)\n                        .memoryCacheKey(media.uri)\n                        .diskCacheKey(media.uri)\n                        .allowHardware(true)\n                        .build()\n                },\n                contentDescription = media.label,\n                contentScale = ContentScale.Crop,\n                onSuccess = {\n                    isImageError = false\n                },\n                onError = {\n                    isImageError = true\n                },\n                error = {\n                    Box(\n                        contentAlignment = Alignment.Center,\n                        modifier = Modifier.background(\n                            takeColorFromScheme { isNightMode ->\n                                errorContainer.copy(\n                                    if (isNightMode) 0.25f\n                                    else 1f\n                                ).compositeOver(surface)\n                            }\n                        )\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.BrokenImageAlt,\n                            contentDescription = null,\n                            modifier = Modifier.fillMaxSize(0.5f),\n                            tint = MaterialTheme.colorScheme.onErrorContainer.copy(0.8f)\n                        )\n                    }\n                },\n                filterQuality = FilterQuality.High\n            )\n        }\n\n        Box(\n            modifier = Modifier.align(Alignment.TopEnd)\n        ) {\n            if (media.duration != null) {\n                MediaVideoDurationHeader(\n                    modifier = Modifier\n                        .padding(selectedSize.value / 2)\n                        .graphicsLayer {\n                            scaleX = scale.value\n                            scaleY = scale.value\n                        },\n                    media = media,\n                )\n            } else {\n                MediaExtensionHeader(\n                    modifier = Modifier\n                        .padding(selectedSize.value / 2)\n                        .graphicsLayer {\n                            scaleX = scale.value\n                            scaleY = scale.value\n                        },\n                    media = media\n                )\n            }\n        }\n\n        if (media.fileSize > 0) {\n            MediaSizeFooter(\n                modifier = Modifier\n                    .align(Alignment.BottomStart)\n                    .padding(selectedSize.value / 2)\n                    .graphicsLayer {\n                        scaleX = scale.value\n                        scaleY = scale.value\n                        transformOrigin = TransformOrigin(0.3f, 0.5f)\n                    },\n                media = media,\n            )\n        }\n\n        if (isInSelection) {\n            Box(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(4.dp)\n            ) {\n                MediaCheckBox(\n                    isChecked = isSelected,\n                    uncheckedColor = White.copy(0.8f),\n                    checkedColor = if (isImageError) {\n                        MaterialTheme.colorScheme.error\n                    } else MaterialTheme.colorScheme.primary,\n                    checkedIcon = if (isImageError) {\n                        Icons.Filled.Error\n                    } else Icons.Filled.CheckCircle,\n                    selectionIndex = selectionIndex,\n                    modifier = Modifier\n                        .clip(ShapeDefaults.circle)\n                        .background(\n                            transition.animateColor {\n                                if (it) MaterialTheme.colorScheme.surfaceContainer\n                                else Color.Transparent\n                            }.value\n                        )\n                )\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaImagePager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.AnchoredDraggableDefaults\nimport androidx.compose.foundation.gestures.AnchoredDraggableState\nimport androidx.compose.foundation.gestures.DraggableAnchors\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.anchoredDraggable\nimport androidx.compose.foundation.gestures.snapTo\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.displayCutoutPadding\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.systemBars\nimport androidx.compose.foundation.layout.systemBarsPadding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.filled.CheckCircle\nimport androidx.compose.material.icons.filled.Error\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshots.SnapshotStateList\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.onPrimaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.theme.primaryContainerFixed\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.MediaCheckBox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.image.HistogramChart\nimport com.t8rin.imagetoolbox.core.ui.widget.image.MetadataPreviewButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.toShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withLayoutCorners\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\nimport com.t8rin.modalsheet.FullscreenPopup\nimport kotlinx.coroutines.delay\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.toggleScale\nimport net.engawapg.lib.zoomable.zoomable\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun MediaImagePager(\n    imagePreviewUri: String?,\n    onDismiss: () -> Unit,\n    media: List<Media>,\n    selectedMedia: SnapshotStateList<Media>,\n    onMediaClick: (Media) -> Unit\n) {\n    val visible = imagePreviewUri != null\n\n    FullscreenPopup {\n        var predictiveBackProgress by remember {\n            mutableFloatStateOf(0f)\n        }\n        val animatedPredictiveBackProgress by animateFloatAsState(predictiveBackProgress)\n        val scale = (1f - animatedPredictiveBackProgress).coerceAtLeast(0.75f)\n\n        LaunchedEffect(predictiveBackProgress, visible) {\n            if (!visible && predictiveBackProgress != 0f) {\n                delay(600)\n                predictiveBackProgress = 0f\n            }\n        }\n\n        AnimatedVisibility(\n            visible = visible,\n            modifier = Modifier.fillMaxSize(),\n            enter = fadeIn(tween(500)),\n            exit = fadeOut(tween(500))\n        ) {\n            val density = LocalDensity.current\n            val screenHeight =\n                LocalScreenSize.current.height + WindowInsets.systemBars.asPaddingValues()\n                    .let { it.calculateTopPadding() + it.calculateBottomPadding() }\n            val anchors = with(density) {\n                DraggableAnchors {\n                    true at 0f\n                    false at -screenHeight.toPx()\n                }\n            }\n\n            val draggableState = remember(anchors) {\n                AnchoredDraggableState(\n                    initialValue = true,\n                    anchors = anchors\n                )\n            }\n\n            LaunchedEffect(draggableState.settledValue) {\n                if (!draggableState.settledValue) {\n                    onDismiss()\n                    delay(600)\n                    draggableState.snapTo(true)\n                }\n            }\n\n            val initialPage by remember(imagePreviewUri, media) {\n                derivedStateOf {\n                    imagePreviewUri?.let {\n                        media.indexOfFirst { it.uri == imagePreviewUri }\n                    }?.takeIf { it >= 0 } ?: 0\n                }\n            }\n            val pagerState = rememberPagerState(\n                initialPage = initialPage,\n                pageCount = {\n                    media.size\n                }\n            )\n            val progress by remember(draggableState) {\n                derivedStateOf {\n                    draggableState.progress(\n                        from = false,\n                        to = true\n                    )\n                }\n            }\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .withLayoutCorners { corners ->\n                        graphicsLayer {\n                            scaleX = scale\n                            scaleY = scale\n                            shape = corners.toShape(animatedPredictiveBackProgress)\n                            clip = true\n                        }\n                    }\n                    .background(\n                        MaterialTheme.colorScheme.scrim.copy(alpha = 0.6f * progress)\n                    )\n            ) {\n                val currentMedia = media.getOrNull(pagerState.currentPage)\n                val imageErrorPages = remember {\n                    mutableStateListOf<Int>()\n                }\n                var hideControls by remember(animatedPredictiveBackProgress) {\n                    mutableStateOf(false)\n                }\n                HorizontalPager(\n                    state = pagerState,\n                    modifier = Modifier.fillMaxSize(),\n                    beyondViewportPageCount = 5,\n                    pageSpacing = if (pagerState.pageCount > 1) 16.dp\n                    else 0.dp\n                ) { page ->\n                    Box(\n                        modifier = Modifier.fillMaxSize()\n                    ) {\n                        val zoomState = rememberZoomState(20f)\n                        Picture(\n                            showTransparencyChecker = false,\n                            model = media.getOrNull(page)?.uri,\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .clipToBounds()\n                                .systemBarsPadding()\n                                .displayCutoutPadding()\n                                .offset {\n                                    IntOffset(\n                                        x = 0,\n                                        y = -draggableState\n                                            .requireOffset()\n                                            .roundToInt(),\n                                    )\n                                }\n                                .anchoredDraggable(\n                                    state = draggableState,\n                                    enabled = zoomState.scale < 1.01f && !pagerState.isScrollInProgress,\n                                    orientation = Orientation.Vertical,\n                                    reverseDirection = true,\n                                    flingBehavior = AnchoredDraggableDefaults.flingBehavior(\n                                        animationSpec = tween(500),\n                                        state = draggableState\n                                    )\n                                )\n                                .zoomable(\n                                    zoomEnabled = !imageErrorPages.contains(page),\n                                    zoomState = zoomState,\n                                    onTap = {\n                                        hideControls = !hideControls\n                                    },\n                                    onDoubleTap = {\n                                        zoomState.toggleScale(\n                                            targetScale = 5f,\n                                            position = it\n                                        )\n                                    }\n                                ),\n                            enableUltraHDRSupport = true,\n                            contentScale = ContentScale.Fit,\n                            shape = RectangleShape,\n                            onSuccess = {\n                                imageErrorPages.remove(page)\n                            },\n                            onError = {\n                                imageErrorPages.add(page)\n                            },\n                            error = {\n                                Box(\n                                    contentAlignment = Alignment.Center,\n                                    modifier = Modifier.background(\n                                        takeColorFromScheme { isNightMode ->\n                                            errorContainer.copy(\n                                                if (isNightMode) 0.25f\n                                                else 1f\n                                            ).compositeOver(surface)\n                                        }\n                                    )\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.BrokenImageAlt,\n                                        contentDescription = null,\n                                        modifier = Modifier.fillMaxSize(0.5f),\n                                        tint = MaterialTheme.colorScheme.onErrorContainer.copy(0.8f)\n                                    )\n                                }\n                            }\n                        )\n                    }\n                }\n                val showTopBar by remember(hideControls, draggableState) {\n                    derivedStateOf {\n                        draggableState.offset == 0f && !hideControls\n                    }\n                }\n                val showBottomHist = pagerState.currentPage !in imageErrorPages\n                val showBottomBar by remember(draggableState, showBottomHist, hideControls) {\n                    derivedStateOf {\n                        draggableState.offset == 0f && showBottomHist && !hideControls\n                    }\n                }\n\n                AnimatedVisibility(\n                    visible = showTopBar,\n                    modifier = Modifier.fillMaxWidth(),\n                    enter = fadeIn() + slideInVertically(),\n                    exit = fadeOut() + slideOutVertically()\n                ) {\n                    EnhancedTopAppBar(\n                        colors = EnhancedTopAppBarDefaults.colors(\n                            containerColor = MaterialTheme.colorScheme.scrim.copy(alpha = 0.5f)\n                        ),\n                        type = EnhancedTopAppBarType.Center,\n                        drawHorizontalStroke = false,\n                        title = {\n                            media.size.takeIf { it > 1 }?.let {\n                                Text(\n                                    text = \"${pagerState.currentPage + 1}/$it\",\n                                    modifier = Modifier\n                                        .padding(vertical = 4.dp, horizontal = 12.dp),\n                                    color = White\n                                )\n                            }\n                        },\n                        actions = {\n                            val isImageError = imageErrorPages.contains(pagerState.currentPage)\n                            AnimatedVisibility(\n                                visible = media.isNotEmpty(),\n                                enter = fadeIn() + scaleIn(),\n                                exit = fadeOut() + scaleOut()\n                            ) {\n                                val isChecked = selectedMedia.contains(currentMedia)\n                                MediaCheckBox(\n                                    isChecked = isChecked,\n                                    onCheck = {\n                                        currentMedia?.let(onMediaClick)\n                                    },\n                                    uncheckedColor = White,\n                                    checkedColor = if (isImageError) {\n                                        MaterialTheme.colorScheme.error\n                                    } else MaterialTheme.colorScheme.primary,\n                                    checkedIcon = if (isImageError) {\n                                        Icons.Filled.Error\n                                    } else Icons.Filled.CheckCircle,\n                                    addContainer = isChecked\n                                )\n                            }\n                        },\n                        navigationIcon = {\n                            AnimatedVisibility(media.isNotEmpty()) {\n                                EnhancedIconButton(\n                                    onClick = onDismiss\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit),\n                                        tint = White\n                                    )\n                                }\n                            }\n                        },\n                    )\n                }\n\n                AnimatedVisibility(\n                    visible = showBottomBar,\n                    modifier = Modifier.align(Alignment.BottomEnd),\n                    enter = fadeIn() + slideInVertically { it / 2 },\n                    exit = fadeOut() + slideOutVertically { it / 2 }\n                ) {\n                    Row(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .background(MaterialTheme.colorScheme.scrim.copy(0.5f))\n                            .navigationBarsPadding()\n                            .padding(\n                                WindowInsets.displayCutout\n                                    .only(\n                                        WindowInsetsSides.Horizontal\n                                    )\n                                    .asPaddingValues()\n                            )\n                            .padding(16.dp),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        Row(\n                            modifier = Modifier.weight(1f),\n                            verticalAlignment = Alignment.CenterVertically\n                        ) {\n                            currentMedia?.label?.let {\n                                Text(\n                                    text = it,\n                                    modifier = Modifier\n                                        .animateContentSizeNoClip()\n                                        .weight(1f, false),\n                                    color = White,\n                                    style = MaterialTheme.typography.labelLarge,\n                                    fontSize = 13.sp\n                                )\n                            }\n                            currentMedia?.humanFileSize\n                                ?.takeIf { currentMedia.fileSize > 0 }\n                                ?.let { size ->\n                                    Spacer(Modifier.width(8.dp))\n                                    Text(\n                                        text = size,\n                                        modifier = Modifier\n                                            .animateContentSizeNoClip()\n                                            .background(\n                                                color = MaterialTheme.colorScheme.primaryContainerFixed,\n                                                shape = ShapeDefaults.circle\n                                            )\n                                            .padding(horizontal = 8.dp, vertical = 4.dp),\n                                        color = MaterialTheme.colorScheme.onPrimaryContainerFixed,\n                                        style = MaterialTheme.typography.labelMedium\n                                    )\n                                }\n                            MetadataPreviewButton(\n                                uri = currentMedia?.uri?.toUri(),\n                                dateModified = { currentMedia?.timestamp?.times(1000) },\n                                path = { currentMedia?.path },\n                                name = { currentMedia?.label },\n                                fileSize = { currentMedia?.humanFileSize }\n                            )\n                        }\n                        Spacer(Modifier.width(16.dp))\n                        HistogramChart(\n                            model = currentMedia?.uri ?: Uri.EMPTY,\n                            modifier = Modifier\n                                .height(50.dp)\n                                .width(90.dp),\n                            bordersColor = Color.White\n                        )\n                    }\n                }\n            }\n\n            PredictiveBackObserver(\n                onProgress = {\n                    predictiveBackProgress = it / 6f\n                },\n                onClean = { isCompleted ->\n                    if (isCompleted) {\n                        onDismiss()\n                        delay(400)\n                    }\n                    predictiveBackProgress = 0f\n                },\n                enabled = visible\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaPickerGrid.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.GridItemSpan\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.itemsIndexed\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshots.SnapshotStateList\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.dragHandler\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.MediaItem\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.MediaState\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.isHeaderKey\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun MediaPickerGrid(\n    state: MediaState,\n    isSelectionOfAll: Boolean,\n    selectedMedia: SnapshotStateList<Media>,\n    allowMultiple: Boolean,\n    isButtonVisible: Boolean,\n    onRequestManagePermission: () -> Unit,\n    isManagePermissionAllowed: Boolean\n) {\n    val scope = rememberCoroutineScope()\n    val stringToday = stringResource(id = R.string.header_today)\n    val stringYesterday = stringResource(id = R.string.header_yesterday)\n    val gridState = rememberLazyGridState()\n    val isCheckVisible = rememberSaveable { mutableStateOf(allowMultiple) }\n    val hapticFeedback = LocalHapticFeedback.current\n\n    LaunchedEffect(state.media) {\n        gridState.scrollToItem(0)\n    }\n\n    var imagePreviewUri by rememberSaveable {\n        mutableStateOf<String?>(null)\n    }\n\n    val onMediaClick: (Media) -> Unit = {\n        if (allowMultiple) {\n            if (selectedMedia.contains(it)) selectedMedia.remove(it)\n            else selectedMedia.add(it)\n        } else {\n            if (selectedMedia.contains(it)) selectedMedia.remove(it)\n            else {\n                if (selectedMedia.isNotEmpty()) selectedMedia[0] = it\n                else selectedMedia.add(it)\n            }\n        }\n    }\n\n    val layoutDirection = LocalLayoutDirection.current\n    val privateSelection = remember {\n        mutableStateOf(emptySet<Int>())\n    }\n\n    LaunchedEffect(state.mappedMedia, isSelectionOfAll, selectedMedia.size) {\n        if (isSelectionOfAll) {\n            privateSelection.value = state.mappedMedia.mapIndexedNotNull { index, item ->\n                if (item is MediaItem.MediaViewItem && item.media in selectedMedia) {\n                    index\n                } else null\n            }.toSet()\n        }\n    }\n\n    LaunchedEffect(selectedMedia.size) {\n        if (selectedMedia.isEmpty() && isSelectionOfAll) {\n            privateSelection.value = emptySet()\n        }\n    }\n\n    val cutout = WindowInsets.displayCutout.asPaddingValues()\n    val navBar = WindowInsets.navigationBars.asPaddingValues()\n\n    LazyVerticalGrid(\n        state = gridState,\n        modifier = Modifier\n            .fillMaxSize()\n            .background(MaterialTheme.colorScheme.surface)\n            .padding(\n                start = cutout.calculateStartPadding(layoutDirection),\n                end = cutout.calculateEndPadding(layoutDirection)\n            )\n            .dragHandler(\n                enabled = isSelectionOfAll && allowMultiple,\n                key = state.mappedMedia,\n                lazyGridState = gridState,\n                isVertical = true,\n                selectedItems = privateSelection,\n                onSelectionChange = { indices ->\n                    val order: MutableList<Any> = indices.toMutableList()\n                    state.mappedMedia.forEachIndexed { index, mediaItem ->\n                        if (index in indices && mediaItem is MediaItem.MediaViewItem) {\n                            order.indexOf(index).takeIf { it >= 0 }?.let {\n                                order[it] = mediaItem.media\n                            }\n                        }\n                    }\n                    selectedMedia.clear()\n                    selectedMedia.addAll(order.mapNotNull(Any::safeCast))\n                },\n                onLongTap = {\n                    if (selectedMedia.isEmpty()) {\n                        imagePreviewUri =\n                            (state.mappedMedia[it + 1] as? MediaItem.MediaViewItem)?.media?.uri\n                    }\n                },\n                shouldHandleLongTap = selectedMedia.isNotEmpty()\n            ),\n        columns = GridCells.Adaptive(100.dp),\n        horizontalArrangement = Arrangement.spacedBy(1.dp),\n        verticalArrangement = Arrangement.spacedBy(1.dp),\n        contentPadding = remember(\n            navBar,\n            layoutDirection,\n            isButtonVisible,\n            selectedMedia.isNotEmpty()\n        ) {\n            PaddingValues(\n                bottom = navBar.calculateBottomPadding().plus(\n                    if (isButtonVisible) 80.dp\n                    else 0.dp\n                ).plus(\n                    if (selectedMedia.isNotEmpty()) 52.dp\n                    else 0.dp\n                )\n            )\n        },\n        flingBehavior = enhancedFlingBehavior(FlingType.IOS_STYLE)\n    ) {\n        if (!isManagePermissionAllowed) {\n            item(\n                span = {\n                    GridItemSpan(maxLineSpan)\n                }\n            ) {\n                ManageExternalStorageWarning(onRequestManagePermission)\n            }\n        }\n        itemsIndexed(\n            items = state.mappedMedia,\n            key = { index, item ->\n                \"${item.key}-$index\"\n            },\n            contentType = { _, item -> item.key.startsWith(\"media_\") },\n            span = { _, item ->\n                GridItemSpan(if (item.key.isHeaderKey) maxLineSpan else 1)\n            }\n        ) { _, item ->\n            when (item) {\n                is MediaItem.Header -> {\n                    val isChecked = rememberSaveable { mutableStateOf(false) }\n                    if (allowMultiple) {\n                        LaunchedEffect(selectedMedia.size) {\n                            // Partial check of media items should not check the header\n                            isChecked.value = selectedMedia.containsAll(item.data)\n                        }\n                    }\n                    MediaStickyHeader(\n                        date = remember(item.text) {\n                            item.text\n                                .replace(\"Today\", stringToday)\n                                .replace(\"Yesterday\", stringYesterday)\n                        },\n                        isCheckVisible = isCheckVisible,\n                        isChecked = isChecked.value,\n                        onChecked = {\n                            if (allowMultiple) {\n                                hapticFeedback.longPress()\n                                scope.launch {\n                                    isChecked.value = !isChecked.value\n                                    if (isChecked.value) {\n                                        val toAdd = item.data.toMutableList().apply {\n                                            // Avoid media from being added twice to selection\n                                            removeIf { selectedMedia.contains(it) }\n                                        }\n                                        selectedMedia.addAll(toAdd)\n                                    } else selectedMedia.removeAll(item.data)\n                                }\n                            }\n                        }\n                    )\n                }\n\n                is MediaItem.MediaViewItem -> {\n                    val selectionIndex = selectedMedia.indexOf(item.media)\n\n                    MediaImage(\n                        media = item.media,\n                        canClick = !isSelectionOfAll || !allowMultiple,\n                        onItemClick = {\n                            hapticFeedback.longPress()\n                            onMediaClick(it)\n                        },\n                        onItemLongClick = {\n                            imagePreviewUri = it.uri\n                        },\n                        selectionIndex = if (selectedMedia.size > 1) selectionIndex else -1,\n                        isSelected = selectionIndex >= 0\n                    )\n                }\n            }\n        }\n    }\n\n    MediaImagePager(\n        imagePreviewUri = imagePreviewUri,\n        onDismiss = { imagePreviewUri = null },\n        media = state.media,\n        selectedMedia = selectedMedia,\n        onMediaClick = onMediaClick\n    )\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaPickerGridWithOverlays.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport android.net.Uri\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.imePadding\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.safeDrawingPadding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.TaskAlt\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Search\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material.icons.twotone.ImageNotSupported\nimport androidx.compose.material3.BadgedBox\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.semantics.contentDescription\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButtonType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.presentation.screenLogic.MediaPickerComponent\n\n@Composable\ninternal fun MediaPickerGridWithOverlays(\n    component: MediaPickerComponent,\n    isSearching: Boolean,\n    allowedMedia: AllowedMedia,\n    allowMultiple: Boolean,\n    onRequestManagePermission: () -> Unit,\n    isManagePermissionAllowed: Boolean,\n    selectedAlbumIndex: Long,\n    onSearchingChange: (Boolean) -> Unit,\n    onPicked: (List<Uri>) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    val albumsState by component.albumsState.collectAsState()\n    val mediaState by component.mediaState.collectAsState()\n    val selectedMedia = component.selectedMedia\n\n    var searchKeyword by rememberSaveable(isSearching) {\n        mutableStateOf(\"\")\n    }\n\n    val filterMedia = {\n        component.filterMedia(\n            searchKeyword = searchKeyword.trim(),\n            isForceReset = !isSearching || searchKeyword.trim()\n                .isBlank() || mediaState.media.isEmpty()\n        )\n    }\n\n    val filteredMediaState by component.filteredMediaState.collectAsState()\n\n    Box(\n        modifier = modifier.fillMaxSize()\n    ) {\n        Box(\n            modifier = Modifier.fillMaxSize()\n        ) {\n            val isButtonVisible =\n                (!allowMultiple || selectedMedia.isNotEmpty()) && !isSearching\n            MediaPickerGrid(\n                state = filteredMediaState,\n                isSelectionOfAll = selectedAlbumIndex == -1L,\n                selectedMedia = selectedMedia,\n                allowMultiple = allowMultiple,\n                isButtonVisible = isButtonVisible,\n                isManagePermissionAllowed = isManagePermissionAllowed,\n                onRequestManagePermission = onRequestManagePermission\n            )\n            BoxAnimatedVisibility(\n                modifier = Modifier\n                    .align(Alignment.BottomEnd)\n                    .padding(16.dp)\n                    .safeDrawingPadding(),\n                visible = isButtonVisible,\n                enter = slideInVertically { it * 2 },\n                exit = slideOutVertically { it * 2 }\n            ) {\n                val enabled = selectedMedia.isNotEmpty()\n                val containerColor by animateColorAsState(\n                    targetValue = if (enabled) {\n                        MaterialTheme.colorScheme.primaryContainer\n                    } else MaterialTheme.colorScheme.surfaceVariant\n                )\n                val contentColor by animateColorAsState(\n                    targetValue = if (enabled) {\n                        MaterialTheme.colorScheme.onPrimaryContainer\n                    } else MaterialTheme.colorScheme.onSurfaceVariant\n                )\n                Column(\n                    horizontalAlignment = Alignment.End\n                ) {\n                    AnimatedVisibility(visible = selectedMedia.isNotEmpty()) {\n                        EnhancedFloatingActionButton(\n                            type = EnhancedFloatingActionButtonType.Small,\n                            onClick = selectedMedia::clear,\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                            content = {\n                                Icon(\n                                    imageVector = Icons.Rounded.Close,\n                                    contentDescription = stringResource(R.string.close)\n                                )\n                            },\n                            modifier = Modifier.padding(bottom = 8.dp)\n                        )\n                    }\n                    BadgedBox(\n                        badge = {\n                            if (selectedMedia.isNotEmpty() && allowMultiple) {\n                                EnhancedBadge(\n                                    containerColor = MaterialTheme.colorScheme.primary\n                                ) {\n                                    Text(selectedMedia.size.toString())\n                                }\n                            }\n                        }\n                    ) {\n                        EnhancedFloatingActionButton(\n                            content = {\n                                Row(\n                                    verticalAlignment = Alignment.CenterVertically,\n                                    modifier = Modifier.padding(horizontal = 16.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Outlined.TaskAlt,\n                                        contentDescription = null\n                                    )\n                                    Spacer(modifier = Modifier.width(8.dp))\n                                    Text(stringResource(R.string.pick))\n                                }\n                            },\n                            containerColor = containerColor,\n                            contentColor = contentColor,\n                            onClick = {\n                                if (enabled) {\n                                    onPicked(selectedMedia.map { it.uri.toUri() })\n                                }\n                            },\n                            modifier = Modifier\n                                .semantics {\n                                    contentDescription = \"Add media\"\n                                }\n                        )\n                    }\n                }\n                BackHandler(selectedMedia.isNotEmpty()) {\n                    selectedMedia.clear()\n                }\n            }\n        }\n\n        val isHaveNoData = mediaState.media.isEmpty() && !mediaState.isLoading\n        val showLoading = (mediaState.isLoading || filteredMediaState.isLoading) && !isHaveNoData\n\n        val backgroundColor by animateColorAsState(\n            MaterialTheme.colorScheme.scrim.copy(\n                if (showLoading && filteredMediaState.media.isNotEmpty()) 0.5f else 0f\n            )\n        )\n        BoxAnimatedVisibility(\n            visible = showLoading,\n            modifier = Modifier\n                .fillMaxSize()\n                .imePadding()\n                .background(backgroundColor),\n            enter = scaleIn() + fadeIn(),\n            exit = scaleOut() + fadeOut()\n        ) {\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .windowInsetsPadding(\n                        WindowInsets.displayCutout\n                            .union(WindowInsets.navigationBars)\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedLoadingIndicator()\n            }\n        }\n\n        BoxAnimatedVisibility(\n            visible = filteredMediaState.media.isEmpty() && !filteredMediaState.isLoading && isSearching,\n            enter = scaleIn() + fadeIn(),\n            exit = scaleOut() + fadeOut(),\n            modifier = Modifier\n                .fillMaxSize()\n                .imePadding()\n        ) {\n            Column(\n                modifier = Modifier.fillMaxSize(),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                Spacer(Modifier.weight(1f))\n                Text(\n                    text = stringResource(R.string.nothing_found_by_search),\n                    fontSize = 18.sp,\n                    textAlign = TextAlign.Center,\n                    modifier = Modifier.padding(\n                        start = 24.dp,\n                        end = 24.dp,\n                        top = 8.dp,\n                        bottom = 8.dp\n                    )\n                )\n                Icon(\n                    imageVector = Icons.Rounded.SearchOff,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .weight(2f)\n                        .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                        .fillMaxSize()\n                )\n                Spacer(Modifier.weight(1f))\n            }\n        }\n\n        BoxAnimatedVisibility(\n            visible = isHaveNoData,\n            enter = scaleIn() + fadeIn(),\n            exit = scaleOut() + fadeOut(),\n            modifier = Modifier\n                .fillMaxSize()\n                .imePadding()\n        ) {\n            val errorMessage = albumsState.error + \"\\n\" + mediaState.error\n            Column(\n                modifier = Modifier.fillMaxSize(),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                Spacer(Modifier.weight(1f))\n                Icon(\n                    imageVector = Icons.TwoTone.ImageNotSupported,\n                    contentDescription = null,\n                    modifier = Modifier.size(108.dp)\n                )\n                Spacer(modifier = Modifier.height(8.dp))\n                Text(\n                    text = errorMessage.trim().ifEmpty {\n                        stringResource(id = R.string.no_data)\n                    },\n                    fontWeight = FontWeight.SemiBold,\n                    fontSize = 16.sp\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n                Spacer(modifier = Modifier.height(16.dp))\n                EnhancedButton(\n                    onClick = {\n                        component.init(allowedMedia)\n                    }\n                ) {\n                    Text(stringResource(id = R.string.try_again))\n                }\n                Spacer(Modifier.weight(1f))\n            }\n        }\n\n        BoxAnimatedVisibility(\n            visible = !mediaState.isLoading && !isHaveNoData,\n            modifier = Modifier.fillMaxSize(),\n            enter = fadeIn(),\n            exit = fadeOut()\n        ) {\n            AnimatedContent(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(16.dp)\n                    .safeDrawingPadding(),\n                targetState = isSearching,\n                transitionSpec = {\n                    fadeIn() togetherWith fadeOut()\n                }\n            ) { searchMode ->\n                Box(\n                    modifier = Modifier.fillMaxSize(),\n                    contentAlignment = Alignment.BottomStart\n                ) {\n                    if (searchMode) {\n                        RoundedTextField(\n                            maxLines = 1,\n                            hint = { Text(stringResource(id = R.string.search_here)) },\n                            keyboardOptions = KeyboardOptions.Default.copy(\n                                imeAction = ImeAction.Search,\n                                autoCorrectEnabled = null\n                            ),\n                            value = searchKeyword,\n                            onValueChange = {\n                                searchKeyword = it\n                                filterMedia()\n                            },\n                            startIcon = {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        searchKeyword = \"\"\n                                        onSearchingChange(false)\n                                        filterMedia()\n                                    },\n                                    modifier = Modifier.padding(start = 4.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Close,\n                                        contentDescription = stringResource(R.string.exit),\n                                        tint = MaterialTheme.colorScheme.onSurface\n                                    )\n                                }\n                            },\n                            endIcon = {\n                                BoxAnimatedVisibility(\n                                    visible = searchKeyword.isNotEmpty(),\n                                    enter = fadeIn() + scaleIn(),\n                                    exit = fadeOut() + scaleOut()\n                                ) {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            searchKeyword = \"\"\n                                            filterMedia()\n                                        },\n                                        modifier = Modifier.padding(end = 4.dp)\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Outlined.Delete,\n                                            contentDescription = stringResource(R.string.close),\n                                            tint = MaterialTheme.colorScheme.onSurface\n                                        )\n                                    }\n                                }\n                            },\n                            shape = ShapeDefaults.circle\n                        )\n                    } else {\n                        EnhancedIconButton(\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                            contentColor = MaterialTheme.colorScheme.onTertiaryContainer,\n                            modifier = Modifier\n                                .padding(bottom = 6.dp)\n                                .size(44.dp),\n                            onClick = {\n                                onSearchingChange(true)\n                                filterMedia()\n                            },\n                            shape = MaterialStarShape,\n                            pressedShape = MaterialStarShape\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Search,\n                                contentDescription = null\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaPickerHavePermissions.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport android.net.Uri\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableLongStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.coerceAtLeast\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Album\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.presentation.screenLogic.MediaPickerComponent\n\n@Composable\ninternal fun MediaPickerHavePermissions(\n    component: MediaPickerComponent,\n    allowedMedia: AllowedMedia,\n    allowMultiple: Boolean,\n    onRequestManagePermission: () -> Unit,\n    isManagePermissionAllowed: Boolean,\n    onPicked: (List<Uri>) -> Unit\n) {\n    var selectedAlbumIndex by rememberSaveable { mutableLongStateOf(-1) }\n\n    val albumsState by component.albumsState.collectAsState()\n    var isSearching by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    BackHandler(selectedAlbumIndex != -1L) {\n        selectedAlbumIndex = -1L\n        component.getAlbum(selectedAlbumIndex)\n    }\n\n    BackHandler(isSearching) {\n        isSearching = false\n    }\n\n    Scaffold(\n        topBar = {\n            AnimatedVisibility(\n                modifier = Modifier.fillMaxWidth(),\n                visible = albumsState.albums.size > 1\n            ) {\n                val layoutDirection = LocalLayoutDirection.current\n                var showAlbumThumbnail by rememberSaveable {\n                    mutableStateOf(false)\n                }\n                val listState = rememberLazyListState()\n                Row(\n                    modifier = Modifier\n                        .drawHorizontalStroke()\n                        .background(MaterialTheme.colorScheme.surfaceContainer)\n                ) {\n                    LazyRow(\n                        modifier = Modifier\n                            .weight(1f)\n                            .fadingEdges(listState)\n                            .padding(vertical = 8.dp),\n                        horizontalArrangement = Arrangement.spacedBy(\n                            space = 8.dp\n                        ),\n                        contentPadding = PaddingValues(\n                            start = WindowInsets.displayCutout\n                                .asPaddingValues()\n                                .calculateStartPadding(layoutDirection) + 8.dp,\n                            end = WindowInsets.displayCutout\n                                .asPaddingValues()\n                                .calculateEndPadding(layoutDirection) + 8.dp\n                        ),\n                        state = listState,\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        items(\n                            items = albumsState.albums,\n                            key = Album::toString\n                        ) { album ->\n                            val selected = selectedAlbumIndex == album.id\n                            val isImageVisible = showAlbumThumbnail && album.uri.isNotEmpty()\n                            EnhancedChip(\n                                selected = selected,\n                                selectedColor = MaterialTheme.colorScheme.secondaryContainer,\n                                unselectedColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                                unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant,\n                                onClick = {\n                                    selectedAlbumIndex = album.id\n                                    component.getAlbum(selectedAlbumIndex)\n                                },\n                                contentPadding = PaddingValues(\n                                    horizontal = animateDpAsState(\n                                        if (isImageVisible) 8.dp\n                                        else 12.dp\n                                    ).value,\n                                    vertical = animateDpAsState(\n                                        if (isImageVisible) 8.dp\n                                        else 0.dp\n                                    ).value\n                                ),\n                                label = {\n                                    val title =\n                                        if (album.id == -1L) stringResource(R.string.all) else album.label\n                                    Column(\n                                        modifier = Modifier\n                                            .animateContentSizeNoClip(\n                                                alignment = Alignment.Center\n                                            )\n                                            .then(\n                                                if (showAlbumThumbnail && album.uri.isEmpty()) {\n                                                    Modifier.height(140.dp)\n                                                } else Modifier\n                                            ),\n                                        verticalArrangement = Arrangement.Center,\n                                        horizontalAlignment = Alignment.CenterHorizontally\n                                    ) {\n                                        var width by remember {\n                                            mutableStateOf(1.dp)\n                                        }\n                                        val density = LocalDensity.current\n                                        Text(\n                                            text = title,\n                                            modifier = Modifier.onSizeChanged {\n                                                width = with(density) {\n                                                    it.width.toDp().coerceAtLeast(100.dp)\n                                                }\n                                            }\n                                        )\n                                        BoxAnimatedVisibility(\n                                            visible = isImageVisible,\n                                            enter = fadeIn() + expandVertically(),\n                                            exit = fadeOut() + shrinkVertically()\n                                        ) {\n                                            Box {\n                                                BoxAnimatedVisibility(\n                                                    visible = width > 1.dp,\n                                                    enter = fadeIn() + scaleIn(),\n                                                    exit = fadeOut() + scaleOut()\n                                                ) {\n                                                    Picture(\n                                                        model = album.uri,\n                                                        modifier = Modifier\n                                                            .padding(top = 8.dp)\n                                                            .height(100.dp)\n                                                            .width(width),\n                                                        shape = ShapeDefaults.small\n                                                    )\n                                                }\n                                                Box(\n                                                    modifier = Modifier\n                                                        .padding(top = 8.dp)\n                                                        .height(100.dp)\n                                                        .width(width)\n                                                        .clip(ShapeDefaults.small)\n                                                        .background(\n                                                            MaterialTheme\n                                                                .colorScheme\n                                                                .surfaceContainer\n                                                                .copy(0.6f)\n                                                        ),\n                                                    contentAlignment = Alignment.Center\n                                                ) {\n                                                    AutoSizeText(\n                                                        text = album.count.toString(),\n                                                        style = MaterialTheme.typography.headlineLarge.copy(\n                                                            fontSize = 20.sp,\n                                                            color = MaterialTheme.colorScheme.onSurface,\n                                                            fontWeight = FontWeight.Bold\n                                                        )\n                                                    )\n                                                }\n                                            }\n                                        }\n                                    }\n                                },\n                                defaultMinSize = 32.dp,\n                                shape = ShapeDefaults.default\n                            )\n                        }\n                    }\n                    EnhancedIconButton(\n                        onClick = { showAlbumThumbnail = !showAlbumThumbnail }\n                    ) {\n                        val rotation by animateFloatAsState(if (showAlbumThumbnail) 180f else 0f)\n                        Icon(\n                            imageVector = Icons.Rounded.KeyboardArrowDown,\n                            contentDescription = \"Expand\",\n                            modifier = Modifier.rotate(rotation)\n                        )\n                    }\n                }\n            }\n        },\n        contentWindowInsets = WindowInsets()\n    ) { contentPadding ->\n        MediaPickerGridWithOverlays(\n            component = component,\n            isSearching = isSearching,\n            allowedMedia = allowedMedia,\n            allowMultiple = allowMultiple,\n            onRequestManagePermission = onRequestManagePermission,\n            isManagePermissionAllowed = isManagePermissionAllowed,\n            selectedAlbumIndex = selectedAlbumIndex,\n            onSearchingChange = { isSearching = it },\n            onPicked = onPicked,\n            modifier = Modifier.padding(contentPadding)\n        )\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaPickerRootContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport android.content.Intent\nimport androidx.compose.runtime.Composable\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ImageToolboxCompositionLocals\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.presentation.screenLogic.MediaPickerComponent\n\n@Composable\ninternal fun MediaPickerRootContent(component: MediaPickerComponent) {\n    val context = LocalComponentActivity.current\n\n    ImageToolboxCompositionLocals(\n        settingsState = component.settingsState.toUiState()\n    ) {\n        MediaPickerRootContentEmbeddable(\n            component = component,\n            allowedMedia = context.intent.type.allowedMedia,\n            allowMultiple = context.intent.allowMultiple,\n            onPicked = context::sendMediaAsResult,\n            onBack = context::finish\n        )\n\n        ObserveColorSchemeExtra()\n    }\n}\n\nprivate val Intent.allowMultiple get() = getBooleanExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)\nprivate val String?.pickImage: Boolean get() = this?.startsWith(\"image\") == true\nprivate val String?.pickVideo: Boolean get() = this?.startsWith(\"video\") == true\nprivate val String?.allowedMedia: AllowedMedia\n    get() = if (pickImage) AllowedMedia.Photos(this?.takeLastWhile { it != '/' })\n    else if (pickVideo) AllowedMedia.Videos\n    else AllowedMedia.Both"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaPickerRootContentEmbeddable.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport android.Manifest\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Environment\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.app.ActivityCompat\nimport com.t8rin.imagetoolbox.core.domain.utils.tryAll\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.appSettingsIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isInstalledFromPlayStore\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.manageAllFilesIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.manageAppAllFilesIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.requestPermissions\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionStatus\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.checkPermissions\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberCurrentLifecycleEvent\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.presentation.screenLogic.MediaPickerComponent\n\n@Composable\nfun MediaPickerRootContentEmbeddable(\n    component: MediaPickerComponent,\n    onPicked: (List<Uri>) -> Unit,\n    modifier: Modifier = Modifier,\n    allowedMedia: AllowedMedia = AllowedMedia.Photos(null),\n    allowMultiple: Boolean = true,\n    onBack: (() -> Unit)? = null\n) {\n    val context = LocalComponentActivity.current\n\n    var isPermissionAllowed by remember {\n        mutableStateOf(true)\n    }\n    var isManagePermissionAllowed by remember {\n        mutableStateOf(true)\n    }\n    var invalidator by remember {\n        mutableIntStateOf(0)\n    }\n\n    val launcher = rememberLauncherForActivityResult(\n        ActivityResultContracts.StartActivityForResult()\n    ) {\n        invalidator++\n    }\n\n    val requestManagePermission = {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {\n            tryAll(\n                { launcher.launch(context.manageAppAllFilesIntent()) },\n                { launcher.launch(manageAllFilesIntent()) },\n                { launcher.launch(context.appSettingsIntent()) }\n            )\n        }\n    }\n\n    val lifecycleEvent = rememberCurrentLifecycleEvent()\n    LaunchedEffect(lifecycleEvent, invalidator) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n            val permission = Manifest.permission.READ_MEDIA_IMAGES\n            isManagePermissionAllowed =\n                Environment.isExternalStorageManager() || context.isInstalledFromPlayStore()\n            when (context.checkPermissions(listOf(permission)).finalStatus) {\n                PermissionStatus.ALLOWED -> {\n                    isPermissionAllowed = true\n                    component.init(allowedMedia)\n                }\n\n                PermissionStatus.NOT_GIVEN -> {\n                    ActivityCompat.requestPermissions(\n                        context,\n                        arrayOf(permission),\n                        0\n                    )\n                }\n\n                PermissionStatus.DENIED_PERMANENTLY -> Unit\n            }\n        }\n    }\n\n    val content: @Composable (PaddingValues) -> Unit = {\n        AnimatedContent(\n            targetState = isPermissionAllowed,\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(top = it.calculateTopPadding())\n        ) { havePermissions ->\n            if (havePermissions) {\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(8.dp)\n                ) {\n                    MediaPickerHavePermissions(\n                        allowedMedia = allowedMedia,\n                        allowMultiple = allowMultiple,\n                        component = component,\n                        isManagePermissionAllowed = isManagePermissionAllowed,\n                        onRequestManagePermission = requestManagePermission,\n                        onPicked = onPicked\n                    )\n                    LaunchedEffect(Unit) {\n                        component.init(allowedMedia = allowedMedia)\n                    }\n                }\n            } else {\n                Column(\n                    modifier = Modifier.fillMaxSize(),\n                    verticalArrangement = Arrangement.Center,\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.BrokenImageAlt,\n                        contentDescription = null,\n                        modifier = Modifier.size(108.dp)\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    Text(\n                        text = stringResource(id = R.string.no_permissions),\n                        fontWeight = FontWeight.SemiBold,\n                        fontSize = 16.sp,\n                        textAlign = TextAlign.Center,\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(16.dp)\n                    )\n                    Spacer(modifier = Modifier.height(16.dp))\n                    EnhancedButton(\n                        onClick = {\n                            val permission =\n                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n                                    Manifest.permission.READ_MEDIA_IMAGES\n                                } else {\n                                    Manifest.permission.READ_EXTERNAL_STORAGE\n                                }\n                            context.requestPermissions(listOf(permission))\n                        }\n                    ) {\n                        Text(stringResource(id = R.string.request))\n                    }\n                }\n            }\n        }\n    }\n\n    Box(modifier = modifier) {\n        if (onBack == null) {\n            content(PaddingValues())\n        } else {\n            Scaffold(\n                topBar = {\n                    EnhancedTopAppBar(\n                        title = {\n                            Text(\n                                text = if (allowMultiple) {\n                                    stringResource(R.string.pick_multiple_media)\n                                } else {\n                                    stringResource(R.string.pick_single_media)\n                                },\n                                modifier = Modifier.marquee()\n                            )\n                        },\n                        navigationIcon = {\n                            EnhancedIconButton(\n                                onClick = onBack,\n                                containerColor = Color.Transparent\n                            ) {\n                                Icon(\n                                    imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                    contentDescription = stringResource(R.string.close)\n                                )\n                            }\n                        },\n                        actions = {\n                            TopAppBarEmoji()\n                        },\n                        drawHorizontalStroke = component.albumsState.collectAsState().value.albums.size <= 1\n                    )\n                },\n                content = content\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaSizeFooter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.advancedShadow\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\n\n@Composable\nfun MediaSizeFooter(\n    modifier: Modifier = Modifier,\n    media: Media\n) {\n    Row(\n        modifier = modifier\n            .padding(8.dp)\n            .padding(vertical = 2.dp)\n            .advancedShadow(\n                cornersRadius = 4.dp,\n                shadowBlurRadius = 6.dp,\n                alpha = 0.4f\n            )\n            .padding(horizontal = 2.dp),\n        horizontalArrangement = Arrangement.End,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Text(\n            modifier = Modifier,\n            text = media.humanFileSize,\n            style = MaterialTheme.typography.labelMedium,\n            color = White\n        )\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaStickyHeader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.MediaCheckBox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\n\n@Composable\nfun MediaStickyHeader(\n    modifier: Modifier = Modifier,\n    date: String,\n    isCheckVisible: MutableState<Boolean>,\n    isChecked: Boolean,\n    onChecked: (() -> Unit)? = null\n) {\n    Row(\n        modifier = modifier\n            .padding(\n                horizontal = 16.dp,\n                vertical = 24.dp\n            )\n            .fillMaxWidth(),\n        horizontalArrangement = Arrangement.SpaceBetween,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Text(\n            text = date,\n            style = MaterialTheme.typography.titleMedium,\n            color = MaterialTheme.colorScheme.onSurface,\n            modifier = Modifier.hapticsCombinedClickable(\n                interactionSource = remember { MutableInteractionSource() },\n                indication = null,\n                onLongClick = onChecked,\n                onClick = {\n                    if (isCheckVisible.value) onChecked?.invoke()\n                }\n            )\n        )\n        if (onChecked != null) {\n            AnimatedVisibility(\n                visible = isCheckVisible.value,\n                enter = enterAnimation,\n                exit = exitAnimation\n            ) {\n                MediaCheckBox(\n                    isChecked = isChecked,\n                    onCheck = onChecked,\n                    modifier = Modifier.size(20.dp)\n                )\n            }\n        }\n    }\n}\n\nprivate val enterAnimation = fadeIn(tween(150))\nprivate val exitAnimation = fadeOut(tween(150))"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/MediaVideoDurationHeader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.PlayCircle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.advancedShadow\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.formatMinSec\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\n\n@Composable\nfun MediaVideoDurationHeader(\n    modifier: Modifier = Modifier,\n    media: Media\n) {\n    Row(\n        modifier = modifier\n            .padding(all = 8.dp)\n            .advancedShadow(\n                cornersRadius = 8.dp,\n                shadowBlurRadius = 6.dp,\n                alpha = 0.3f\n            ),\n        horizontalArrangement = Arrangement.End,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Text(\n            modifier = Modifier,\n            text = media.duration.formatMinSec(),\n            style = MaterialTheme.typography.labelSmall,\n            color = White\n        )\n        Spacer(modifier = Modifier.size(2.dp))\n        Icon(\n            modifier = Modifier\n                .size(16.dp)\n                .advancedShadow(\n                    cornersRadius = 2.dp,\n                    shadowBlurRadius = 6.dp,\n                    alpha = 0.1f,\n                    offsetY = (-2).dp\n                ),\n            imageVector = Icons.Rounded.PlayCircle,\n            tint = White,\n            contentDescription = \"Video\"\n        )\n    }\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/ObserveColorSchemeExtra.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ColorSchemeName\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun ObserveColorSchemeExtra() {\n    val context = LocalComponentActivity.current\n    val dynamicTheme = LocalDynamicThemeState.current\n\n    val scope = rememberCoroutineScope()\n    SideEffect {\n        context.intent.getIntExtra(ColorSchemeName, Color.Transparent.toArgb()).takeIf {\n            it != Color.Transparent.toArgb()\n        }?.let {\n            scope.launch {\n                while (dynamicTheme.colorTuple.value.primary != Color(it)) {\n                    dynamicTheme.updateColorTuple(ColorTuple(Color(it)))\n                    delay(500L)\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/components/SendMediaAsResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.components\n\nimport android.content.Intent\nimport android.net.Uri\nimport androidx.activity.ComponentActivity\nimport androidx.appcompat.app.AppCompatActivity.RESULT_OK\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toClipData\n\ninternal fun ComponentActivity.sendMediaAsResult(selectedMedia: List<Uri>) {\n    val newIntent = Intent(\n        if (selectedMedia.size == 1) Intent.ACTION_SEND\n        else Intent.ACTION_SEND_MULTIPLE\n    ).apply {\n        if (selectedMedia.size == 1) {\n            data = selectedMedia.first()\n            clipData = selectedMedia.toClipData()\n            putExtra(\n                Intent.EXTRA_STREAM,\n                selectedMedia.first()\n            )\n        } else {\n            clipData = selectedMedia.toClipData()\n            putParcelableArrayListExtra(\n                Intent.EXTRA_STREAM,\n                ArrayList(selectedMedia)\n            )\n        }\n        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)\n    }\n    setResult(RESULT_OK, newIntent)\n\n    finish()\n}"
  },
  {
    "path": "feature/media-picker/src/main/java/com/t8rin/imagetoolbox/feature/media_picker/presentation/screenLogic/MediaPickerComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\npackage com.t8rin.imagetoolbox.feature.media_picker.presentation.screenLogic\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.DateExt\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.getDate\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.getDateExt\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.getDateHeader\nimport com.t8rin.imagetoolbox.feature.media_picker.data.utils.getMonth\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.MediaRetriever\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Album\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AlbumState\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.AllowedMedia\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.Media\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.MediaItem\nimport com.t8rin.imagetoolbox.feature.media_picker.domain.model.MediaState\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.runBlocking\nimport kotlinx.coroutines.withContext\n\nclass MediaPickerComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    private val settingsManager: SettingsManager,\n    private val mediaRetriever: MediaRetriever,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _settingsState = mutableStateOf(SettingsState.Default)\n    val settingsState: SettingsState by _settingsState\n\n    val selectedMedia = mutableStateListOf<Media>()\n\n    private val _mediaState = MutableStateFlow(MediaState())\n    val mediaState = _mediaState.asStateFlow()\n\n    private val _filteredMediaState = MutableStateFlow(MediaState())\n    val filteredMediaState = _filteredMediaState.asStateFlow()\n\n    private val _albumsState = MutableStateFlow(AlbumState())\n    val albumsState = _albumsState.asStateFlow()\n\n    fun init(allowedMedia: AllowedMedia) {\n        this.allowedMedia = allowedMedia\n        getMedia(selectedAlbumId, allowedMedia)\n        getAlbums(allowedMedia)\n    }\n\n    fun getAlbum(albumId: Long) {\n        this.selectedAlbumId = albumId\n        getMedia(albumId, allowedMedia)\n        getAlbums(allowedMedia)\n    }\n\n    private var allowedMedia: AllowedMedia = AllowedMedia.Photos(null)\n\n    private var selectedAlbumId: Long = -1L\n\n    private val emptyAlbum = Album(\n        id = -1,\n        label = \"All\",\n        uri = \"\",\n        pathToThumbnail = \"\",\n        timestamp = 0,\n        relativePath = \"\"\n    )\n\n    private var albumJob: Job? by smartJob()\n\n    private fun getAlbums(allowedMedia: AllowedMedia) {\n        albumJob = componentScope.launch {\n            mediaRetriever.getAlbumsWithType(allowedMedia)\n                .flowOn(defaultDispatcher)\n                .collectLatest { result ->\n                    val data = result.getOrNull() ?: emptyList()\n                    val error = if (result.isFailure) result.exceptionOrNull()?.message\n                        ?: \"An error occurred\" else \"\"\n                    if (data.isEmpty()) {\n                        return@collectLatest _albumsState.emit(\n                            AlbumState(\n                                albums = listOf(emptyAlbum),\n                                error = error\n                            )\n                        )\n                    }\n                    val albums = mutableListOf<Album>().apply {\n                        add(emptyAlbum)\n                        addAll(data)\n                    }\n                    _albumsState.emit(AlbumState(albums = albums, error = error))\n                }\n        }\n    }\n\n    private var mediaGettingJob: Job? by smartJob()\n\n    private fun getMedia(\n        albumId: Long,\n        allowedMedia: AllowedMedia\n    ) {\n        mediaGettingJob = componentScope.launch {\n            _mediaState.emit(mediaState.value.copy(isLoading = true))\n            mediaRetriever.mediaFlowWithType(albumId, allowedMedia)\n                .flowOn(defaultDispatcher)\n                .collectLatest { result ->\n                    val data =\n                        if (allowedMedia is AllowedMedia.Photos && allowedMedia.ext != null && allowedMedia.ext != \"*\") {\n                            result.getOrNull()?.filter { it.uri.endsWith(allowedMedia.ext) }\n                        } else {\n                            result.getOrNull()\n                        }?.distinctBy { it.id } ?: emptyList()\n\n                    val error = if (result.isFailure) result.exceptionOrNull()?.message\n                        ?: \"An error occurred\" else \"\"\n                    if (data.isEmpty()) {\n                        return@collectLatest _mediaState.emit(MediaState(isLoading = false))\n                    }\n                    _mediaState.collectMedia(data, error, albumId)\n                    _filteredMediaState.emit(mediaState.value)\n                }\n        }\n    }\n\n    private suspend fun MutableStateFlow<MediaState>.collectMedia(\n        data: List<Media>,\n        error: String,\n        albumId: Long,\n        groupByMonth: Boolean = false\n    ) {\n        val mappedData = mutableListOf<MediaItem>()\n        val monthHeaderList: MutableSet<String> = mutableSetOf()\n        withContext(defaultDispatcher) {\n            val groupedData = data.groupBy {\n                if (groupByMonth) {\n                    it.timestamp.getMonth()\n                } else {\n                    it.timestamp.getDate(\n                        stringToday = \"Today\",\n                        stringYesterday = \"Yesterday\"\n                    )\n                }\n            }\n            groupedData.forEach { (date, data) ->\n                val dateHeader = MediaItem.Header(\"header_$date\", date, data)\n                val groupedMedia = data.map {\n                    MediaItem.MediaViewItem(\"media_${it.id}_${it.label}\", it)\n                }\n                if (groupByMonth) {\n                    mappedData.add(dateHeader)\n                    mappedData.addAll(groupedMedia)\n                } else {\n                    val month = getMonth(date)\n                    if (month.isNotEmpty() && !monthHeaderList.contains(month)) {\n                        monthHeaderList.add(month)\n                    }\n                    mappedData.add(dateHeader)\n                    mappedData.addAll(groupedMedia)\n                }\n            }\n        }\n        withContext(uiDispatcher) {\n            tryEmit(\n                MediaState(\n                    isLoading = false,\n                    error = error,\n                    media = data,\n                    mappedMedia = mappedData,\n                    dateHeader = data.dateHeader(albumId)\n                )\n            )\n        }\n    }\n\n    private fun List<Media>.dateHeader(albumId: Long): String =\n        if (albumId != -1L && isNotEmpty()) {\n            val startDate: DateExt = last().timestamp.getDateExt()\n            val endDate: DateExt = first().timestamp.getDateExt()\n            getDateHeader(startDate, endDate)\n        } else \"\"\n\n    private var mediaFilterJob: Job? by smartJob()\n\n    fun filterMedia(\n        searchKeyword: String,\n        isForceReset: Boolean\n    ) {\n        mediaFilterJob = componentScope.launch {\n            if (isForceReset) {\n                _filteredMediaState.emit(mediaState.value)\n            } else {\n                _filteredMediaState.emit(mediaState.value.copy(isLoading = true))\n                _filteredMediaState.collectMedia(\n                    data = mediaState.value.media.filter {\n                        if (searchKeyword.startsWith(\"*\")) {\n                            it.label.endsWith(\n                                suffix = searchKeyword.drop(1),\n                                ignoreCase = true\n                            )\n                        } else if (searchKeyword.endsWith(\"*\")) {\n                            it.label.startsWith(\n                                prefix = searchKeyword.dropLast(1),\n                                ignoreCase = true\n                            )\n                        } else {\n                            it.label.contains(\n                                other = searchKeyword,\n                                ignoreCase = true\n                            )\n                        }\n                    }.distinctBy { it.id },\n                    error = mediaState.value.error,\n                    albumId = selectedAlbumId\n                )\n            }\n        }\n    }\n\n    init {\n        runBlocking {\n            _settingsState.value = settingsManager.getSettingsState()\n        }\n        settingsManager.settingsState.onEach {\n            _settingsState.value = it\n        }.launchIn(componentScope)\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext\n        ): MediaPickerComponent\n    }\n\n}"
  },
  {
    "path": "feature/mesh-gradients/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/mesh-gradients/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.mesh_gradients\""
  },
  {
    "path": "feature/mesh-gradients/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/mesh-gradients/src/main/java/com/t8rin/imagetoolbox/feature/mesh_gradients/presentation/MeshGradientsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.mesh_gradients.presentation\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagePreviewGrid\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.screenLogic.MeshGradientsComponent\n\n@Composable\nfun MeshGradientsContent(\n    component: MeshGradientsComponent\n) {\n    val childScrollBehavior =\n        TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n    Scaffold(\n        modifier = Modifier\n            .fillMaxSize()\n            .nestedScroll(childScrollBehavior.nestedScrollConnection),\n        topBar = {\n            EnhancedTopAppBar(\n                title = {\n                    Text(\n                        text = stringResource(R.string.collection_mesh_gradients),\n                        modifier = Modifier.marquee()\n                    )\n                },\n                navigationIcon = {\n                    EnhancedIconButton(\n                        onClick = component.onGoBack\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                            contentDescription = null\n                        )\n                    }\n                },\n                actions = {\n                    TopAppBarEmoji()\n                },\n                type = EnhancedTopAppBarType.Large,\n                scrollBehavior = childScrollBehavior\n            )\n        }\n    ) { contentPadding ->\n        AnimatedContent(\n            modifier = Modifier.fillMaxSize(),\n            targetState = component.meshGradientUris\n        ) { uris ->\n            if (uris.isNotEmpty()) {\n                ImagePreviewGrid(\n                    data = uris,\n                    onAddImages = null,\n                    onShareImage = {\n                        component.shareImages(\n                            uriList = listOf(element = it),\n                        )\n                    },\n                    onRemove = null,\n                    onNavigate = component.onNavigate,\n                    imageFrames = null,\n                    onFrameSelectionChange = {},\n                    contentPadding = PaddingValues(12.dp),\n                    isSelectable = false,\n                    modifier = Modifier.padding(contentPadding)\n                )\n            } else {\n                val meshGradientDownloadProgress =\n                    component.meshGradientDownloadProgress\n                Box(\n                    modifier = Modifier.fillMaxSize(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    val currentPercent =\n                        meshGradientDownloadProgress?.currentPercent ?: 0f\n\n                    if (currentPercent > 0f) {\n                        EnhancedLoadingIndicator(\n                            progress = currentPercent,\n                            loaderSize = 72.dp\n                        ) {\n                            Column(\n                                verticalArrangement = Arrangement.Center,\n                                horizontalAlignment = Alignment.CenterHorizontally,\n                                modifier = Modifier\n                                    .fillMaxSize()\n                                    .padding(8.dp)\n                            ) {\n                                Text(\n                                    text = rememberHumanFileSize(\n                                        meshGradientDownloadProgress?.currentTotalSize ?: 0\n                                    ),\n                                    maxLines = 1,\n                                    textAlign = TextAlign.Center,\n                                    fontSize = 10.sp,\n                                    lineHeight = 10.sp\n                                )\n                            }\n                        }\n                    } else {\n                        EnhancedLoadingIndicator()\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/mesh-gradients/src/main/java/com/t8rin/imagetoolbox/feature/mesh_gradients/presentation/screenLogic/MeshGradientsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResources\nimport com.t8rin.imagetoolbox.core.domain.remote.RemoteResourcesStore\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.delay\n\nclass MeshGradientsComponent @AssistedInject constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n    remoteResourcesStore: RemoteResourcesStore\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _meshGradientUris = mutableStateOf(emptyList<Uri>())\n    val meshGradientUris by _meshGradientUris\n\n    private val _meshGradientDownloadProgress: MutableState<DownloadProgress?> =\n        mutableStateOf(null)\n    val meshGradientDownloadProgress by _meshGradientDownloadProgress\n\n    init {\n        componentScope.launch {\n            delay(200)\n            val resources = remoteResourcesStore\n                .getResources(\n                    name = RemoteResources.MESH_GRADIENTS,\n                    forceUpdate = true,\n                    onDownloadRequest = {\n                        launch {\n                            remoteResourcesStore.downloadResources(\n                                name = RemoteResources.MESH_GRADIENTS,\n                                onProgress = { _meshGradientDownloadProgress.value = it },\n                                onFailure = {},\n                                downloadOnlyNewData = true\n                            )\n                        }\n                        null\n                    }\n                )\n\n            _meshGradientUris.value = resources?.list?.map { it.uri.toUri() } ?: emptyList()\n        }\n    }\n\n    fun shareImages(\n        uriList: List<Uri>\n    ) = componentScope.launch {\n        shareProvider.shareImages(\n            uris = uriList.map { it.toString() },\n            imageLoader = {\n                imageGetter.getImage(it)?.run { image to imageInfo }\n            },\n            onProgressChange = {}\n        )\n        AppToastHost.showConfetti()\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit\n        ): MeshGradientsComponent\n    }\n\n}"
  },
  {
    "path": "feature/noise-generation/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/noise-generation/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.noise_generation\"\n\ndependencies {\n    implementation(libs.toolbox.fastNoise)\n}"
  },
  {
    "path": "feature/noise-generation/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest />"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/data/AndroidNoiseGenerator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.fast_noise.FastNoise\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.noise_generation.domain.NoiseGenerator\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.NoiseParams\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidNoiseGenerator @Inject constructor(\n    dispatchersHolder: DispatchersHolder\n) : NoiseGenerator<Bitmap>, DispatchersHolder by dispatchersHolder {\n\n    override suspend fun generateNoise(\n        width: Int,\n        height: Int,\n        noiseParams: NoiseParams,\n        onFailure: (Throwable) -> Unit\n    ): Bitmap? = withContext(defaultDispatcher) {\n        runCatching {\n            with(noiseParams) {\n                FastNoise.generateNoiseImage(\n                    width = width,\n                    height = height,\n                    seed = seed,\n                    frequency = frequency,\n                    noiseType = noiseType.ordinal,\n                    rotationType3D = rotationType3D.ordinal,\n                    fractalType = fractalType.ordinal,\n                    fractalOctaves = fractalOctaves,\n                    fractalLacunarity = fractalLacunarity,\n                    fractalGain = fractalGain,\n                    fractalWeightedStrength = fractalWeightedStrength,\n                    fractalPingPongStrength = fractalPingPongStrength,\n                    cellularDistanceFunction = cellularDistanceFunction.ordinal,\n                    cellularReturnType = cellularReturnType.ordinal,\n                    cellularJitter = cellularJitter,\n                    domainWarpType = domainWarpType.ordinal,\n                    domainWarpAmp = domainWarpAmp,\n                )\n            }\n        }.onFailure(onFailure).getOrNull()\n    }\n\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/di/NoiseGenerationModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.noise_generation.data.AndroidNoiseGenerator\nimport com.t8rin.imagetoolbox.noise_generation.domain.NoiseGenerator\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface NoiseGenerationModule {\n\n    @Binds\n    fun provideGenerator(\n        impl: AndroidNoiseGenerator\n    ): NoiseGenerator<Bitmap>\n\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/NoiseGenerator.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain\n\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.NoiseParams\n\ninterface NoiseGenerator<Image> {\n\n    suspend fun generateNoise(\n        width: Int,\n        height: Int,\n        noiseParams: NoiseParams,\n        onFailure: (Throwable) -> Unit = {}\n    ): Image?\n\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/model/CellularDistanceFunction.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain.model\n\nenum class CellularDistanceFunction {\n    Euclidean,\n    EuclideanSq,\n    Manhattan,\n    Hybrid\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/model/CellularReturnType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain.model\n\nenum class CellularReturnType {\n    CellValue,\n    Distance,\n    Distance2,\n    Distance2Add,\n    Distance2Sub,\n    Distance2Mul,\n    Distance2Div\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/model/DomainWarpType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain.model\n\nenum class DomainWarpType {\n    OpenSimplex2,\n    OpenSimplex2Reduced,\n    BasicGrid\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/model/FractalType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain.model\n\nenum class FractalType {\n    None,\n    FBm,\n    Ridged,\n    PingPong,\n    DomainWarpProgressive,\n    DomainWarpIndependent\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/model/NoiseParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain.model\n\ndata class NoiseParams(\n    val seed: Int,\n    val frequency: Float,\n    val noiseType: NoiseType,\n    val rotationType3D: RotationType3D,\n    val fractalType: FractalType,\n    val fractalOctaves: Int,\n    val fractalLacunarity: Float,\n    val fractalGain: Float,\n    val fractalWeightedStrength: Float,\n    val fractalPingPongStrength: Float,\n    val cellularDistanceFunction: CellularDistanceFunction,\n    val cellularReturnType: CellularReturnType,\n    val cellularJitter: Float,\n    val domainWarpType: DomainWarpType,\n    val domainWarpAmp: Float\n) {\n    companion object {\n        val Default by lazy {\n            NoiseParams(\n                seed = 1337,\n                frequency = 0.01f,\n                noiseType = NoiseType.OpenSimplex2,\n                rotationType3D = RotationType3D.None,\n                fractalType = FractalType.None,\n                fractalOctaves = 3,\n                fractalLacunarity = 2f,\n                fractalGain = 0.5f,\n                fractalWeightedStrength = 0f,\n                fractalPingPongStrength = 2f,\n                cellularDistanceFunction = CellularDistanceFunction.EuclideanSq,\n                cellularReturnType = CellularReturnType.Distance,\n                cellularJitter = 1f,\n                domainWarpType = DomainWarpType.OpenSimplex2,\n                domainWarpAmp = 1f\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/model/NoiseType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain.model\n\nenum class NoiseType {\n    OpenSimplex2,\n    OpenSimplex2S,\n    Cellular,\n    Perlin,\n    ValueCubic,\n    Value\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/domain/model/RotationType3D.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.domain.model\n\nenum class RotationType3D {\n    None,\n    ImproveXYPlanes,\n    ImproveXZPlanes\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/presentation/NoiseGenerationContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.animate\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.state.derivedValueOf\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.noise_generation.presentation.components.NoiseParamsSelection\nimport com.t8rin.imagetoolbox.noise_generation.presentation.screenLogic.NoiseGenerationComponent\n\n@Composable\nfun NoiseGenerationContent(\n    component: NoiseGenerationComponent\n) {\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveNoise(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val shareButton: @Composable () -> Unit = {\n        var editSheetData by remember {\n            mutableStateOf(listOf<Uri>())\n        }\n        ShareButton(\n            onShare = component::shareNoise,\n            onCopy = {\n                component.cacheCurrentNoise(Clipboard::copy)\n            },\n            onEdit = {\n                component.cacheCurrentNoise {\n                    editSheetData = listOf(it)\n                }\n            }\n        )\n        ProcessImagesPreferenceSheet(\n            uris = editSheetData,\n            visible = editSheetData.isNotEmpty(),\n            onDismiss = {\n                editSheetData = emptyList()\n            },\n            onNavigate = component.onNavigate\n        )\n    }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        title = {\n            Text(\n                text = stringResource(R.string.noise_generation),\n                textAlign = TextAlign.Center,\n                modifier = Modifier.marquee()\n            )\n        },\n        onGoBack = component.onGoBack,\n        actions = {},\n        topAppBarPersistentActions = {\n            TopAppBarEmoji()\n        },\n        imagePreview = {\n            Box(\n                contentAlignment = Alignment.Center\n            ) {\n                Picture(\n                    model = component.previewBitmap,\n                    modifier = Modifier\n                        .container(MaterialTheme.shapes.medium)\n                        .aspectRatio(component.noiseSize.safeAspectRatio.animate()),\n                    shape = MaterialTheme.shapes.medium,\n                    contentScale = ContentScale.FillBounds\n                )\n                if (component.isImageLoading) EnhancedLoadingIndicator()\n            }\n        },\n        controls = {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(8.dp)\n            ) {\n                ResizeImageField(\n                    imageInfo = derivedValueOf(component.noiseSize) {\n                        ImageInfo(component.noiseSize.width, component.noiseSize.height)\n                    },\n                    originalSize = null,\n                    onWidthChange = component::setNoiseWidth,\n                    onHeightChange = component::setNoiseHeight\n                )\n                NoiseParamsSelection(\n                    value = component.noiseParams,\n                    onValueChange = component::updateParams\n                )\n                Spacer(Modifier.height(4.dp))\n                ImageFormatSelector(\n                    value = component.imageFormat,\n                    onValueChange = component::setImageFormat,\n                    forceEnabled = true,\n                    quality = component.quality,\n                )\n                QualitySelector(\n                    quality = component.quality,\n                    imageFormat = component.imageFormat,\n                    onQualityChange = component::setQuality\n                )\n            }\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = false,\n                isSecondaryButtonVisible = false,\n                onSecondaryButtonClick = {},\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    shareButton()\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n        },\n        canShowScreenData = true\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        onCancelLoading = component::cancelSaving\n    )\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/presentation/components/NoiseParamsSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.RampLeft\nimport androidx.compose.material.icons.outlined.SettingsEthernet\nimport androidx.compose.material.icons.outlined.Waves\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.CellularDistanceFunction\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.CellularReturnType\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.DomainWarpType\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.FractalType\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.NoiseParams\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.NoiseType\nimport kotlin.math.roundToInt\n\n@Composable\nfun NoiseParamsSelection(\n    value: NoiseParams,\n    onValueChange: (NoiseParams) -> Unit\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        EnhancedSliderItem(\n            value = value.seed,\n            icon = Icons.Outlined.SettingsEthernet,\n            title = stringResource(R.string.seed),\n            valueRange = -10000f..10000f,\n            internalStateTransformation = {\n                it.roundToInt()\n            },\n            onValueChange = {\n                onValueChange(value.copy(seed = it.toInt()))\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        EnhancedSliderItem(\n            value = value.frequency,\n            icon = Icons.Outlined.Waves,\n            title = stringResource(R.string.frequency),\n            valueRange = -0.5f..0.5f,\n            internalStateTransformation = {\n                it.roundTo(3)\n            },\n            onValueChange = {\n                onValueChange(value.copy(frequency = it))\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        DataSelector(\n            value = value.noiseType,\n            onValueChange = {\n                onValueChange(value.copy(noiseType = it))\n            },\n            entries = NoiseType.entries,\n            title = stringResource(R.string.noise_type),\n            titleIcon = null,\n            itemContentText = {\n                it.name\n            },\n            spanCount = 2,\n            containerColor = Color.Unspecified\n        )\n        DataSelector(\n            value = value.fractalType,\n            onValueChange = {\n                onValueChange(value.copy(fractalType = it))\n            },\n            entries = FractalType.entries,\n            title = stringResource(R.string.fractal_type),\n            titleIcon = null,\n            itemContentText = {\n                it.name\n            },\n            spanCount = 2,\n            containerColor = Color.Unspecified\n        )\n        AnimatedVisibility(value.fractalType != FractalType.None) {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(8.dp)\n            ) {\n                EnhancedSliderItem(\n                    value = value.fractalOctaves,\n                    title = stringResource(R.string.octaves),\n                    valueRange = 1f..5f,\n                    steps = 3,\n                    internalStateTransformation = {\n                        it.roundToInt()\n                    },\n                    onValueChange = {\n                        onValueChange(value.copy(fractalOctaves = it.toInt()))\n                    },\n                    shape = ShapeDefaults.extraLarge\n                )\n                EnhancedSliderItem(\n                    value = value.fractalLacunarity,\n                    title = stringResource(R.string.lacunarity),\n                    valueRange = -50f..50f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        onValueChange(value.copy(fractalLacunarity = it))\n                    },\n                    shape = ShapeDefaults.extraLarge\n                )\n                EnhancedSliderItem(\n                    value = value.fractalGain,\n                    title = stringResource(R.string.gain),\n                    valueRange = -10f..10f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        onValueChange(value.copy(fractalGain = it))\n                    },\n                    shape = ShapeDefaults.extraLarge\n                )\n                EnhancedSliderItem(\n                    value = value.fractalWeightedStrength,\n                    title = stringResource(R.string.weighted_strength),\n                    valueRange = -3f..3f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        onValueChange(value.copy(fractalWeightedStrength = it))\n                    },\n                    shape = ShapeDefaults.extraLarge\n                )\n                AnimatedVisibility(value.fractalType == FractalType.PingPong) {\n                    EnhancedSliderItem(\n                        value = value.fractalPingPongStrength,\n                        title = stringResource(R.string.ping_pong_strength),\n                        valueRange = 0f..20f,\n                        internalStateTransformation = {\n                            it.roundToTwoDigits()\n                        },\n                        onValueChange = {\n                            onValueChange(value.copy(fractalPingPongStrength = it))\n                        },\n                        shape = ShapeDefaults.extraLarge\n                    )\n                }\n                AnimatedVisibility(value.noiseType == NoiseType.Cellular) {\n                    Column {\n                        DataSelector(\n                            value = value.cellularDistanceFunction,\n                            onValueChange = {\n                                onValueChange(value.copy(cellularDistanceFunction = it))\n                            },\n                            entries = CellularDistanceFunction.entries,\n                            title = stringResource(R.string.distance_function),\n                            titleIcon = null,\n                            itemContentText = {\n                                it.name\n                            },\n                            spanCount = 2,\n                            containerColor = Color.Unspecified\n                        )\n                        Spacer(Modifier.height(8.dp))\n                        DataSelector(\n                            value = value.cellularReturnType,\n                            onValueChange = {\n                                onValueChange(value.copy(cellularReturnType = it))\n                            },\n                            entries = CellularReturnType.entries,\n                            title = stringResource(R.string.return_type),\n                            titleIcon = null,\n                            itemContentText = {\n                                it.name\n                            },\n                            spanCount = 2,\n                            containerColor = Color.Unspecified\n                        )\n                        Spacer(Modifier.height(8.dp))\n                        EnhancedSliderItem(\n                            value = value.cellularJitter,\n                            title = stringResource(R.string.jitter),\n                            valueRange = -10f..10f,\n                            internalStateTransformation = {\n                                it.roundToTwoDigits()\n                            },\n                            onValueChange = {\n                                onValueChange(value.copy(cellularJitter = it))\n                            },\n                            shape = ShapeDefaults.extraLarge\n                        )\n                    }\n                }\n            }\n        }\n        DataSelector(\n            value = value.domainWarpType,\n            onValueChange = {\n                onValueChange(value.copy(domainWarpType = it))\n            },\n            entries = DomainWarpType.entries,\n            title = stringResource(R.string.domain_warp),\n            titleIcon = null,\n            itemContentText = {\n                it.name\n            },\n            spanCount = 2,\n            containerColor = Color.Unspecified\n        )\n        EnhancedSliderItem(\n            value = value.domainWarpAmp,\n            icon = Icons.Outlined.RampLeft,\n            title = stringResource(R.string.amplitude),\n            valueRange = -2000f..2000f,\n            internalStateTransformation = {\n                it.roundToTwoDigits()\n            },\n            onValueChange = {\n                onValueChange(value.copy(domainWarpAmp = it))\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n    }\n}"
  },
  {
    "path": "feature/noise-generation/src/main/java/com/t8rin/imagetoolbox/noise_generation/presentation/screenLogic/NoiseGenerationComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.noise_generation.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.noise_generation.domain.NoiseGenerator\nimport com.t8rin.imagetoolbox.noise_generation.domain.model.NoiseParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass NoiseGenerationComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    dispatchersHolder: DispatchersHolder,\n    private val noiseGenerator: NoiseGenerator<Bitmap>,\n    private val fileController: FileController,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        updatePreview()\n    }\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _noiseParams: MutableState<NoiseParams> = mutableStateOf(NoiseParams.Default)\n    val noiseParams: NoiseParams by _noiseParams\n\n    private val _noiseSize: MutableState<IntegerSize> = mutableStateOf(IntegerSize(1000, 1000))\n    val noiseSize: IntegerSize by _noiseSize\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Default)\n    val imageFormat: ImageFormat by _imageFormat\n\n    private val _quality: MutableState<Quality> = mutableStateOf(Quality.Base(100))\n    val quality: Quality by _quality\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveNoise(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            noiseGenerator.generateNoise(\n                width = noiseSize.width,\n                height = noiseSize.height,\n                noiseParams = noiseParams,\n                onFailure = {\n                    parseSaveResult(SaveResult.Error.Exception(it))\n                }\n            )?.let { bitmap ->\n                val imageInfo = ImageInfo(\n                    width = bitmap.width,\n                    height = bitmap.height,\n                    quality = quality,\n                    imageFormat = imageFormat\n                )\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = imageInfo,\n                            metadata = null,\n                            originalUri = \"\",\n                            sequenceNumber = null,\n                            data = imageCompressor.compress(\n                                image = bitmap,\n                                imageFormat = imageFormat,\n                                quality = quality\n                            )\n                        ),\n                        keepOriginalMetadata = true,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun cacheCurrentNoise(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            noiseGenerator.generateNoise(\n                width = noiseSize.width,\n                height = noiseSize.height,\n                noiseParams = noiseParams\n            )?.let { image ->\n                val imageInfo = ImageInfo(\n                    width = image.width,\n                    height = image.height,\n                    quality = quality,\n                    imageFormat = imageFormat\n                )\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun shareNoise() {\n        cacheCurrentNoise { uri ->\n            componentScope.launch {\n                shareProvider.shareUri(\n                    uri = uri.toString(),\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.update { false }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n    }\n\n    fun setQuality(quality: Quality) {\n        _quality.update { quality }\n    }\n\n    fun updateParams(params: NoiseParams) {\n        _noiseParams.update(\n            onValueChanged = ::updatePreview,\n            transform = { params }\n        )\n    }\n\n    fun setNoiseWidth(width: Int) {\n        _noiseSize.update(\n            onValueChanged = ::updatePreview,\n            transform = { it.copy(width = width.coerceAtMost(8192)) }\n        )\n    }\n\n    fun setNoiseHeight(height: Int) {\n        _noiseSize.update(\n            onValueChanged = ::updatePreview,\n            transform = { it.copy(height = height.coerceAtMost(8192)) }\n        )\n    }\n\n    private fun updatePreview() {\n        componentScope.launch {\n            _isImageLoading.update { true }\n            _previewBitmap.update { null }\n            debouncedImageCalculation {\n                noiseGenerator.generateNoise(\n                    width = noiseSize.width,\n                    height = noiseSize.height,\n                    noiseParams = noiseParams\n                )?.let {\n                    imageScaler.scaleImage(\n                        image = it,\n                        width = 512,\n                        height = 512,\n                        resizeType = ResizeType.Flexible\n                    )\n                }.also { bitmap ->\n                    _previewBitmap.update { bitmap }\n                    _isImageLoading.update { false }\n                }\n            }\n        }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): NoiseGenerationComponent\n    }\n\n}"
  },
  {
    "path": "feature/palette-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/palette-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.palette_tools\"\n\ndependencies {\n    implementation(projects.feature.pickColor)\n    implementation(projects.lib.palette)\n}"
  },
  {
    "path": "feature/palette-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/PaletteToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileOpen\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.pluralStringResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.icons.ContractEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Eyedropper\nimport com.t8rin.imagetoolbox.core.resources.icons.PaletteBox\nimport com.t8rin.imagetoolbox.core.resources.icons.PaletteSwatch\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.SimplePicture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.PaletteToolsScreenControls\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.PaletteType\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.screenLogic.PaletteToolsComponent\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageSheet\n\n@Composable\nfun PaletteToolsContent(\n    component: PaletteToolsComponent\n) {\n    val paletteType = component.paletteType\n\n    var showPreferencePicker by rememberSaveable(component.initialUri) {\n        mutableStateOf(component.initialUri != null && paletteType == PaletteType.Default || paletteType == PaletteType.MaterialYou)\n    }\n\n    var showExitDialog by remember {\n        mutableStateOf(false)\n    }\n\n    AutoContentBasedColors(\n        model = component.bitmap,\n        allowChangeColor = paletteType == PaletteType.Default\n    )\n\n    val imagePicker = rememberImagePicker { uri: Uri ->\n        showPreferencePicker = true\n        component.setUri(uri)\n    }\n\n    AutoFilePicker(\n        onAutoPick = imagePicker::pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val paletteImageLauncher = rememberImagePicker { uri: Uri ->\n        component.setPaletteType(PaletteType.Default)\n        component.setUri(uri)\n    }\n\n    val materialYouImageLauncher = rememberImagePicker { uri: Uri ->\n        component.setPaletteType(PaletteType.MaterialYou)\n        component.setUri(uri)\n    }\n\n    val paletteFormatPicker = rememberFilePicker { uri: Uri ->\n        component.setPaletteType(PaletteType.Edit)\n        component.setUri(uri)\n    }\n\n    val pickImage = when (paletteType) {\n        PaletteType.MaterialYou -> materialYouImageLauncher::pickImage\n        PaletteType.Default -> paletteImageLauncher::pickImage\n        PaletteType.Edit -> paletteFormatPicker::pickFile\n        null -> imagePicker::pickImage\n    }\n\n    val paletteSaver = rememberFileCreator(onSuccess = component::savePaletteTo)\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    ZoomModalSheet(\n        data = component.bitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    var showColorPickerSheet by rememberSaveable { mutableStateOf(false) }\n\n    val preferences: @Composable () -> Unit = {\n        val preference1 = @Composable {\n            PreferenceItem(\n                title = stringResource(R.string.generate_palette),\n                subtitle = stringResource(R.string.palette_sub),\n                startIcon = Icons.Outlined.PaletteSwatch,\n                modifier = Modifier.fillMaxWidth(),\n                onClick = {\n                    if (component.bitmap == null) {\n                        paletteImageLauncher.pickImage()\n                    } else {\n                        component.setPaletteType(PaletteType.Default)\n                    }\n                    showPreferencePicker = false\n                }\n            )\n        }\n        val preference2 = @Composable {\n            PreferenceItem(\n                title = stringResource(R.string.material_you),\n                subtitle = stringResource(R.string.material_you_sub),\n                startIcon = Icons.Outlined.PaletteBox,\n                modifier = Modifier.fillMaxWidth(),\n                onClick = {\n                    if (component.bitmap == null) {\n                        materialYouImageLauncher.pickImage()\n                    } else {\n                        component.setPaletteType(PaletteType.MaterialYou)\n                    }\n                    showPreferencePicker = false\n                }\n            )\n        }\n        val preference3 = @Composable {\n            PreferenceItem(\n                title = stringResource(R.string.edit_palette),\n                subtitle = stringResource(R.string.edit_palette_sub),\n                startIcon = Icons.Outlined.ContractEdit,\n                modifier = Modifier.fillMaxWidth(),\n                onClick = {\n                    component.setPaletteType(PaletteType.Edit)\n                    showPreferencePicker = false\n                }\n            )\n        }\n        if (isPortrait) {\n            Column {\n                preference1()\n                Spacer(modifier = Modifier.height(8.dp))\n                preference2()\n                Spacer(modifier = Modifier.height(8.dp))\n                preference3()\n            }\n        } else {\n            Column(\n                Modifier.windowInsetsPadding(WindowInsets.displayCutout.only(WindowInsetsSides.End))\n            ) {\n                Row {\n                    preference1.withModifier(modifier = Modifier.weight(1f))\n                    Spacer(modifier = Modifier.width(8.dp))\n                    preference2.withModifier(modifier = Modifier.weight(1f))\n                }\n                Spacer(modifier = Modifier.height(8.dp))\n                Row {\n                    preference3.withModifier(modifier = Modifier.weight(1f))\n                    Spacer(modifier = Modifier.width(8.dp))\n                    Spacer(Modifier.weight(1f))\n                }\n            }\n        }\n    }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = paletteType == null,\n        title = {\n            TopAppBarTitle(\n                title = when (paletteType) {\n                    PaletteType.MaterialYou -> stringResource(R.string.material_you)\n\n                    PaletteType.Default -> stringResource(R.string.generate_palette)\n\n                    PaletteType.Edit -> {\n                        val base = stringResource(R.string.edit_palette)\n                        val end = component.palette.colors.size.takeIf { it > 0 }?.let {\n                            \": \" + pluralStringResource(R.plurals.color_count, it, it)\n                        }.orEmpty()\n\n                        base + end\n                    }\n\n                    null -> stringResource(R.string.palette_tools)\n                },\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = {\n            when (paletteType) {\n                PaletteType.Edit if component.palette.isNotEmpty() -> showExitDialog = true\n                null -> component.onGoBack()\n                else -> component.setUri(null)\n            }\n        },\n        actions = {\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.bitmap != null,\n            )\n            if (component.bitmap != null) {\n                EnhancedIconButton(\n                    onClick = {\n                        showColorPickerSheet = true\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Eyedropper,\n                        contentDescription = stringResource(R.string.pipette)\n                    )\n                }\n            }\n            if (paletteType == PaletteType.Edit && component.palette.isNotEmpty()) {\n                ShareButton(\n                    onShare = component::sharePalette\n                )\n            }\n        },\n        topAppBarPersistentActions = {\n            if (component.bitmap == null) {\n                TopAppBarEmoji()\n            }\n        },\n        imagePreview = {\n            SimplePicture(bitmap = component.bitmap)\n        },\n        showImagePreviewAsStickyHeader = paletteType == PaletteType.Default,\n        placeImagePreview = paletteType == PaletteType.Default,\n        controls = {\n            PaletteToolsScreenControls(\n                component = component\n            )\n        },\n        buttons = { actions ->\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n\n            BottomButtonsBlock(\n                isNoData = if (paletteType == PaletteType.Edit) {\n                    isPortrait\n                } else {\n                    paletteType == null || component.bitmap == null\n                },\n                onSecondaryButtonClick = pickImage,\n                isPrimaryButtonVisible = paletteType == PaletteType.Edit && component.palette.isNotEmpty(),\n                secondaryButtonIcon = if (paletteType == PaletteType.Edit) Icons.Rounded.FileOpen else Icons.Rounded.AddPhotoAlt,\n                secondaryButtonText = stringResource(\n                    if (paletteType == PaletteType.Edit) R.string.pick_file else R.string.pick_image_alt\n                ),\n                onPrimaryButtonClick = {\n                    paletteSaver.make(component.createPaletteFilename())\n                },\n                showNullDataButtonAsContainer = true,\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }.takeIf { paletteType != PaletteType.Edit }\n            )\n\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        contentPadding = animateDpAsState(\n            if (paletteType == null) 12.dp\n            else 20.dp\n        ).value,\n        insetsForNoData = WindowInsets(0),\n        noDataControls = { preferences() },\n        canShowScreenData = paletteType != null && (paletteType == PaletteType.Edit || component.bitmap != null)\n    )\n\n    var colorPickerValue by rememberSaveable(stateSaver = ColorSaver) {\n        mutableStateOf(Color.Black)\n    }\n    PickColorFromImageSheet(\n        visible = showColorPickerSheet,\n        onDismiss = {\n            showColorPickerSheet = false\n        },\n        bitmap = component.bitmap,\n        onColorChange = {\n            colorPickerValue = it\n        },\n        color = colorPickerValue\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showPreferencePicker,\n        onDismiss = {\n            showPreferencePicker = it\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showPreferencePicker = false\n                }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.palette),\n                icon = Icons.Rounded.Palette\n            )\n        }\n    ) {\n        Column(\n            modifier = Modifier.padding(12.dp)\n        ) {\n            preferences()\n        }\n    }\n\n    ExitWithoutSavingDialog(\n        onExit = {\n            if (paletteType != null) {\n                component.setUri(null)\n            } else {\n                component.onGoBack()\n            }\n        },\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isImageLoading || component.isSaving,\n        canCancel = false\n    )\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/DefaultPaletteControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.rememberImageColorPaletteState\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FileExport\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.NamedColor\n\n\n@Composable\ninternal fun DefaultPaletteControls(\n    bitmap: Bitmap,\n    onOpenExport: (List<NamedColor>) -> Unit\n) {\n    var count by rememberSaveable { mutableIntStateOf(32) }\n\n    val state = rememberImageColorPaletteState(\n        imageBitmap = bitmap.asImageBitmap(),\n        maximumColorCount = count\n    )\n\n    PaletteColorsCountSelector(\n        value = count,\n        onValueChange = { count = it }\n    )\n    Spacer(modifier = Modifier.height(16.dp))\n\n    PreferenceItem(\n        title = stringResource(R.string.export),\n        subtitle = stringResource(R.string.export_palette_sub),\n        onClick = {\n            onOpenExport(\n                state.paletteData.map {\n                    NamedColor(\n                        color = it.colorData.color,\n                        name = it.colorData.name\n                    )\n                }\n            )\n        },\n        endIcon = Icons.Outlined.FileExport,\n        shape = ShapeDefaults.top,\n        modifier = Modifier.fillMaxWidth(),\n        containerColor = MaterialTheme.colorScheme.mixedContainer.copy(0.5f),\n        contentColor = MaterialTheme.colorScheme.onMixedContainer\n    )\n    Spacer(modifier = Modifier.height(4.dp))\n    ImageColorPalette(\n        paletteDataList = state.paletteData,\n        modifier = Modifier\n            .fillMaxSize()\n            .container(ShapeDefaults.bottom)\n            .padding(4.dp),\n        onColorClick = {\n            Clipboard.copy(\n                text = it.color.toHex(),\n                message = R.string.color_copied\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/EditPaletteControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.InsertDriveFile\nimport androidx.compose.material.icons.outlined.AddCircleOutline\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.replaceAt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.Swatch\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorPickerSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.NamedColor\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.NamedPalette\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.PaletteFormatHelper\nimport com.t8rin.palette.PaletteFormat\n\n\n@Composable\ninternal fun EditPaletteControls(\n    paletteFormat: PaletteFormat?,\n    onPaletteFormatChange: (PaletteFormat) -> Unit,\n    palette: NamedPalette,\n    onPaletteChange: (NamedPalette) -> Unit\n) {\n    Spacer(modifier = Modifier.height(16.dp))\n\n    val entries = PaletteFormatHelper.entries\n    val format = paletteFormat ?: entries.first()\n\n    AnimatedContent(\n        targetState = format,\n        contentKey = { it.withPaletteName },\n        modifier = Modifier.fillMaxWidth()\n    ) { formatAnimated ->\n        RoundedTextField(\n            value = palette.name,\n            onValueChange = {\n                onPaletteChange(\n                    palette.copy(\n                        name = it\n                    )\n                )\n            },\n            enabled = formatAnimated.withPaletteName,\n            modifier = Modifier\n                .container(\n                    shape = ShapeDefaults.top,\n                    resultPadding = 8.dp\n                ),\n            isError = !formatAnimated.withPaletteName,\n            supportingText = if (!formatAnimated.withPaletteName) {\n                {\n                    Text(\n                        stringResource(\n                            R.string.palette_name_not_supported,\n                            formatAnimated.name.uppercase().replace(\"_\", \" \")\n                        )\n                    )\n                }\n            } else null,\n            label = { Text(stringResource(R.string.palette_name)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Rounded.Swatch,\n                    contentDescription = null\n                )\n            }\n        )\n    }\n    Spacer(modifier = Modifier.height(4.dp))\n    DataSelector(\n        shape = ShapeDefaults.bottom,\n        value = format,\n        onValueChange = onPaletteFormatChange,\n        entries = entries,\n        title = stringResource(R.string.palette_format),\n        titleIcon = Icons.AutoMirrored.Rounded.InsertDriveFile,\n        itemContentText = {\n            it.name.uppercase().replace(\"_\", \" \")\n        },\n        badgeContent = {\n            Text(entries.size.toString())\n        }\n    )\n    Spacer(modifier = Modifier.height(12.dp))\n    Column(\n        modifier = Modifier.container(resultPadding = 8.dp),\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        (palette.colors + null).forEachIndexed { index, data ->\n            var showColorPicker by remember {\n                mutableStateOf(false)\n            }\n\n            ColorPickerSheet(\n                visible = showColorPicker,\n                onDismiss = { showColorPicker = false },\n                color = data?.color,\n                onColorSelected = {\n                    onPaletteChange(\n                        palette.copy(\n                            colors = if (data == null) {\n                                palette.colors + NamedColor(\n                                    color = it,\n                                    name = \"\"\n                                )\n                            } else {\n                                palette.colors.replaceAt(index) { item ->\n                                    item.copy(\n                                        color = it.copy(1f)\n                                    )\n                                }\n                            }\n                        )\n                    )\n                },\n                allowAlpha = false\n            )\n\n            if (data == null) {\n                PreferenceItem(\n                    onClick = { showColorPicker = true },\n                    title = stringResource(R.string.add_color),\n                    subtitle = stringResource(R.string.add_color_palette_sub),\n                    startIcon = Icons.Rounded.Palette,\n                    endIcon = Icons.Outlined.AddCircleOutline,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(top = 4.dp),\n                    shape = ShapeDefaults.default,\n                    containerColor = MaterialTheme.colorScheme.surface\n                )\n            } else {\n                val baseShape = ShapeDefaults.byIndex(\n                    index = index,\n                    size = palette.colors.size\n                )\n                val interactionSource = remember { MutableInteractionSource() }\n                val shape = shapeByInteraction(\n                    shape = baseShape,\n                    pressedShape = ShapeDefaults.pressed,\n                    interactionSource = interactionSource\n                )\n\n                Row(\n                    modifier = Modifier\n                        .container(\n                            shape = shape,\n                            color = MaterialTheme.colorScheme.surface,\n                            resultPadding = 0.dp\n                        )\n                        .fillMaxWidth()\n                        .padding(8.dp),\n                    horizontalArrangement = Arrangement.spacedBy(8.dp)\n                ) {\n                    val colorInteractionSource =\n                        remember { MutableInteractionSource() }\n\n                    Row(\n                        modifier = Modifier\n                            .container(\n                                shape = ShapeDefaults.circle,\n                                color = data.color.inverse(\n                                    fraction = { 0.8f },\n                                    darkMode = data.color.luminance() < 0.3f\n                                )\n                            )\n                            .hapticsClickable(\n                                interactionSource = colorInteractionSource,\n                                indication = LocalIndication.current\n                            ) {\n                                showColorPicker = true\n                            },\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        Box(\n                            modifier = Modifier\n                                .size(32.dp)\n                                .container(\n                                    shape = ShapeDefaults.circle,\n                                    color = data.color\n                                )\n                        )\n\n                        Box(\n                            contentAlignment = Alignment.Center,\n                            modifier = Modifier.padding(\n                                horizontal = 8.dp\n                            )\n                        ) {\n                            Text(\n                                text = \"#FFFFFF\",\n                                fontSize = 15.sp,\n                                modifier = Modifier.alpha(0f)\n                            )\n\n                            Text(\n                                text = remember(data.color) {\n                                    data.color.toHex().uppercase()\n                                },\n                                color = data.color,\n                                fontSize = 15.sp\n                            )\n                        }\n                    }\n\n                    PaletteColorNameField(\n                        value = data.name,\n                        onValueChange = {\n                            onPaletteChange(\n                                palette.copy(\n                                    colors = palette.colors.replaceAt(index) { item ->\n                                        item.copy(\n                                            name = it\n                                        )\n                                    }\n                                )\n                            )\n                        },\n                        modifier = Modifier\n                            .weight(1f)\n                            .heightIn(min = 40.dp)\n                    )\n\n                    EnhancedIconButton(\n                        onClick = {\n                            onPaletteChange(\n                                palette.copy(\n                                    colors = palette.colors - data\n                                )\n                            )\n                        },\n                        modifier = Modifier.size(28.dp, 40.dp),\n                        forceMinimumInteractiveComponentSize = false,\n                        contentColor = MaterialTheme.colorScheme.onErrorContainer,\n                        containerColor = MaterialTheme.colorScheme.errorContainer.copy(0.5f)\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Delete,\n                            contentDescription = null,\n                            modifier = Modifier.size(20.dp)\n                        )\n                    }\n                }\n            }\n        }\n    }\n    Spacer(modifier = Modifier.height(16.dp))\n}\n"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/ImageColorPalette.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.colors.PaletteData\nimport com.t8rin.colors.model.ColorData\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.PaletteSwatch\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.SourceNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\n\n@Composable\ninternal fun ImageColorPalette(\n    modifier: Modifier,\n    paletteDataList: List<PaletteData>,\n    onColorClick: (ColorData) -> Unit,\n) {\n    AnimatedContent(\n        targetState = paletteDataList.isEmpty(),\n        modifier = modifier.fillMaxSize(),\n        contentAlignment = Alignment.Center\n    ) { isEmpty ->\n        if (isEmpty) {\n            SourceNotPickedWidget(\n                onClick = null,\n                text = stringResource(R.string.no_palette),\n                icon = Icons.Rounded.PaletteSwatch,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n        } else {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                paletteDataList.forEachIndexed { index, paletteData: PaletteData ->\n                    val colorData = paletteData.colorData\n                    val baseShape = ShapeDefaults.byIndex(\n                        index = index,\n                        size = paletteDataList.size\n                    )\n                    val interactionSource = remember { MutableInteractionSource() }\n                    val shape = shapeByInteraction(\n                        shape = baseShape,\n                        pressedShape = ShapeDefaults.pressed,\n                        interactionSource = interactionSource\n                    )\n\n                    Row(\n                        modifier = Modifier\n                            .container(\n                                shape = shape,\n                                color = MaterialTheme.colorScheme.surface,\n                                resultPadding = 0.dp\n                            )\n                            .fillMaxWidth()\n                            .hapticsClickable(\n                                indication = LocalIndication.current,\n                                interactionSource = interactionSource\n                            ) {\n                                onColorClick(colorData)\n                            }\n                            .padding(top = 8.dp, bottom = 8.dp, start = 8.dp, end = 16.dp),\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        Box(\n                            modifier = Modifier\n                                .size(38.dp)\n                                .container(\n                                    shape = ShapeDefaults.circle,\n                                    color = colorData.color\n                                )\n                        )\n\n                        Spacer(modifier = Modifier.width(12.dp))\n\n                        Text(\n                            text = colorData.name,\n                            fontSize = 17.sp,\n                            fontWeight = FontWeight.Bold,\n                            modifier = Modifier.weight(1f)\n                        )\n\n                        Spacer(modifier = Modifier.width(12.dp))\n                        Text(\n                            text = colorData.hexText.uppercase(),\n                            fontSize = 16.sp\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/MaterialYouPalette.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.dynamic.theme.getColorScheme\nimport com.t8rin.dynamic.theme.rememberColorScheme\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Cube\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport kotlinx.coroutines.delay\n\n@Composable\ninternal fun MaterialYouPalette(\n    keyColor: Color,\n    paletteStyle: PaletteStyle,\n    isDarkTheme: Boolean,\n    isInvertColors: Boolean,\n    contrastLevel: Float\n) {\n    val colorScheme = rememberColorScheme(\n        isDarkTheme = isDarkTheme,\n        amoledMode = false,\n        colorTuple = ColorTuple(keyColor),\n        style = paletteStyle,\n        contrastLevel = contrastLevel.toDouble(),\n        dynamicColor = false,\n        isInvertColors = isInvertColors\n    )\n    val context = LocalContext.current\n\n    val themeState = LocalDynamicThemeState.current\n    LaunchedEffect(colorScheme.primary) {\n        delay(200L)\n        themeState.updateColorTuple(\n            ColorTuple(\n                primary = colorScheme.primary,\n                secondary = colorScheme.secondary,\n                tertiary = colorScheme.tertiary,\n                surface = colorScheme.surface\n            )\n        )\n    }\n\n    MaterialYouPaletteGroup(\n        colorScheme = colorScheme,\n        onCopy = { color ->\n            Clipboard.copy(\n                text = color.toHex(),\n                message = R.string.color_copied\n            )\n        }\n    )\n\n    Spacer(modifier = Modifier.height(16.dp))\n\n    EnhancedButton(\n        onClick = {\n            val light = context.getColorScheme(\n                isDarkTheme = false,\n                amoledMode = false,\n                colorTuple = ColorTuple(keyColor),\n                style = paletteStyle,\n                contrastLevel = contrastLevel.toDouble(),\n                dynamicColor = false,\n                isInvertColors = isInvertColors\n            ).asCodeString(false)\n\n            val dark = context.getColorScheme(\n                isDarkTheme = true,\n                amoledMode = false,\n                colorTuple = ColorTuple(keyColor),\n                style = paletteStyle,\n                contrastLevel = contrastLevel.toDouble(),\n                dynamicColor = false,\n                isInvertColors = isInvertColors\n            ).asCodeString(true)\n\n            Clipboard.copy(light + \"\\n\\n\" + dark)\n        },\n        containerColor = MaterialTheme.colorScheme.tertiary\n    ) {\n        Icon(\n            imageVector = Icons.Outlined.Cube,\n            contentDescription = null\n        )\n        Spacer(modifier = Modifier.width(8.dp))\n        Text(stringResource(R.string.copy_as_compose_code))\n    }\n\n}\n\nprivate fun ColorScheme.asCodeString(\n    isDarkTheme: Boolean\n): String = \"\"\"\nval ${isDarkTheme.schemeName} = ColorScheme(\n    background = ${background.colorCode},\n    error = ${error.colorCode},\n    errorContainer = ${errorContainer.colorCode},\n    inverseOnSurface = ${inverseOnSurface.colorCode},\n    inversePrimary = ${inversePrimary.colorCode},\n    inverseSurface = ${inverseSurface.colorCode},\n    onBackground = ${onBackground.colorCode},\n    onError = ${onError.colorCode},\n    onErrorContainer = ${onErrorContainer.colorCode},\n    onPrimary = ${onPrimary.colorCode},\n    onPrimaryContainer = ${onPrimaryContainer.colorCode},\n    onSecondary = ${onSecondary.colorCode},\n    onSecondaryContainer = ${onSecondaryContainer.colorCode},\n    onSurface = ${onSurface.colorCode},\n    onSurfaceVariant = ${onSurfaceVariant.colorCode},\n    onTertiary = ${onTertiary.colorCode},\n    onTertiaryContainer = ${onTertiaryContainer.colorCode},\n    outline = ${outline.colorCode},\n    outlineVariant = ${outlineVariant.colorCode},\n    primary = ${primary.colorCode},\n    primaryContainer = ${primaryContainer.colorCode},\n    scrim = ${scrim.colorCode},\n    secondary = ${secondary.colorCode},\n    secondaryContainer = ${secondaryContainer.colorCode},\n    surface = ${surface.colorCode},\n    surfaceTint = ${surfaceTint.colorCode},\n    surfaceVariant = ${surfaceVariant.colorCode},\n    tertiary = ${tertiary.colorCode},\n    tertiaryContainer = ${tertiaryContainer.colorCode},\n    surfaceBright = ${surfaceBright.colorCode},\n    surfaceDim = ${surfaceDim.colorCode},\n    surfaceContainer = ${surfaceContainer.colorCode},\n    surfaceContainerHigh = ${surfaceContainerHigh.colorCode},\n    surfaceContainerHighest = ${surfaceContainerHighest.colorCode},\n    surfaceContainerLow = ${surfaceContainerLow.colorCode},\n    surfaceContainerLowest = ${surfaceContainerLowest.colorCode},\n)\n\"\"\".trim()\n\nprivate val Boolean.schemeName: String\n    get() = \"${if (this) \"dark\" else \"light\"}ColorScheme\"\n\nprivate val Color.colorCode\n    get() = \"Color(0xff${this.toHex().drop(1).lowercase()})\""
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/MaterialYouPaletteControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Contrast\nimport androidx.compose.material.icons.rounded.DarkMode\nimport androidx.compose.material.icons.rounded.InvertColors\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.dynamic.theme.extractPrimaryColor\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Swatch\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorInfo\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.palette_selection.getTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun MaterialYouPaletteControls(bitmap: Bitmap) {\n    val context = LocalContext.current\n    val settingsState = LocalSettingsState.current\n\n    var showColorPicker by rememberSaveable { mutableStateOf(false) }\n\n    var paletteStyle by rememberSaveable {\n        mutableStateOf(PaletteStyle.TonalSpot)\n    }\n    var isDarkTheme by rememberSaveable {\n        mutableStateOf(settingsState.isNightMode)\n    }\n    var invertColors by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var contrast by rememberSaveable {\n        mutableFloatStateOf(0f)\n    }\n    var keyColor by rememberSaveable(bitmap, stateSaver = ColorSaver) {\n        mutableStateOf(bitmap.extractPrimaryColor())\n    }\n    Spacer(modifier = Modifier.height(16.dp))\n    Row(\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        ColorInfo(\n            color = keyColor,\n            onColorChange = { keyColor = it },\n            supportButtonIcon = Icons.Rounded.MiniEdit,\n            onSupportButtonClick = {\n                showColorPicker = true\n            },\n            modifier = Modifier.weight(1f)\n        )\n        Spacer(modifier = Modifier.width(16.dp))\n        Picture(\n            model = bitmap,\n            shape = RectangleShape,\n            modifier = Modifier\n                .size(56.dp)\n                .container(\n                    shape = ShapeDefaults.mini,\n                    resultPadding = 0.dp\n                )\n        )\n    }\n    Spacer(modifier = Modifier.height(16.dp))\n    MaterialYouPalette(\n        keyColor = keyColor,\n        paletteStyle = paletteStyle,\n        isDarkTheme = isDarkTheme,\n        isInvertColors = invertColors,\n        contrastLevel = contrast\n    )\n    Spacer(modifier = Modifier.height(16.dp))\n    PreferenceRowSwitch(\n        title = stringResource(R.string.dark_colors),\n        subtitle = stringResource(R.string.dark_colors_sub),\n        checked = isDarkTheme,\n        startIcon = Icons.Rounded.DarkMode,\n        onClick = {\n            isDarkTheme = it\n        },\n        containerColor = Color.Unspecified,\n        shape = ShapeDefaults.top\n    )\n    Spacer(modifier = Modifier.height(4.dp))\n    PreferenceRowSwitch(\n        title = stringResource(R.string.invert_colors),\n        subtitle = stringResource(R.string.invert_colors_sub),\n        checked = invertColors,\n        startIcon = Icons.Rounded.InvertColors,\n        onClick = {\n            invertColors = it\n        },\n        containerColor = Color.Unspecified,\n        shape = ShapeDefaults.center\n    )\n    Spacer(modifier = Modifier.height(4.dp))\n    EnhancedSliderItem(\n        containerColor = Color.Unspecified,\n        value = contrast.roundToTwoDigits(),\n        icon = Icons.Rounded.Contrast,\n        title = stringResource(id = R.string.contrast),\n        valueRange = -1f..1f,\n        shape = ShapeDefaults.center,\n        onValueChange = { },\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        steps = 198,\n        onValueChangeFinished = {\n            contrast = it\n        }\n    )\n    Spacer(modifier = Modifier.height(4.dp))\n    Column(\n        modifier = Modifier.container(\n            shape = ShapeDefaults.bottom\n        )\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            IconShapeContainer(\n                modifier = Modifier.padding(top = 16.dp, start = 16.dp)\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Swatch,\n                    contentDescription = null\n                )\n            }\n            Text(\n                fontWeight = FontWeight.Medium,\n                text = stringResource(R.string.palette_style),\n                modifier = Modifier.padding(top = 16.dp, start = 16.dp)\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n\n        val listState = rememberLazyListState()\n        LazyRow(\n            state = listState,\n            modifier = Modifier\n                .fillMaxWidth()\n                .fadingEdges(listState),\n            horizontalArrangement = Arrangement.spacedBy(4.dp),\n            verticalAlignment = Alignment.CenterVertically,\n            contentPadding = PaddingValues(8.dp),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            items(PaletteStyle.entries) {\n                EnhancedChip(\n                    selected = it == paletteStyle,\n                    onClick = { paletteStyle = it },\n                    selectedColor = MaterialTheme.colorScheme.secondary,\n                    contentPadding = PaddingValues(\n                        horizontal = 12.dp,\n                        vertical = 8.dp\n                    )\n                ) {\n                    Text(it.getTitle(context))\n                }\n            }\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Box {\n                Column(\n                    Modifier\n                        .enhancedVerticalScroll(rememberScrollState())\n                        .padding(\n                            start = 36.dp,\n                            top = 36.dp,\n                            end = 36.dp,\n                            bottom = 24.dp\n                        )\n                ) {\n                    ColorSelection(\n                        value = keyColor,\n                        onValueChange = { keyColor = it }\n                    )\n                }\n            }\n        },\n        visible = showColorPicker,\n        onDismiss = {\n            showColorPicker = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.color),\n                icon = Icons.Rounded.Palette\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    showColorPicker = false\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/MaterialYouPaletteGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun MaterialYouPaletteGroup(\n    colorScheme: ColorScheme,\n    onCopy: (Color) -> Unit\n) {\n    Column(\n        modifier = Modifier.clip(MaterialTheme.shapes.large),\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.primary,\n                colorScheme = colorScheme,\n                name = \"Primary\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onPrimary,\n                colorScheme = colorScheme,\n                name = \"On Primary\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.primaryContainer,\n                colorScheme = colorScheme,\n                name = \"Primary Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onPrimaryContainer,\n                colorScheme = colorScheme,\n                name = \"On Primary Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.secondary,\n                colorScheme = colorScheme,\n                name = \"Secondary\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onSecondary,\n                colorScheme = colorScheme,\n                name = \"On Secondary\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.secondaryContainer,\n                colorScheme = colorScheme,\n                name = \"Secondary Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onSecondaryContainer,\n                colorScheme = colorScheme,\n                name = \"On Secondary Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.tertiary,\n                colorScheme = colorScheme,\n                name = \"Tertiary\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onTertiary,\n                colorScheme = colorScheme,\n                name = \"On Tertiary\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.tertiaryContainer,\n                colorScheme = colorScheme,\n                name = \"Tertiary Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onTertiaryContainer,\n                colorScheme = colorScheme,\n                name = \"On Tertiary Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.error,\n                colorScheme = colorScheme,\n                name = \"Error\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onError,\n                colorScheme = colorScheme,\n                name = \"On Error\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.errorContainer,\n                colorScheme = colorScheme,\n                name = \"Error Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onErrorContainer,\n                colorScheme = colorScheme,\n                name = \"On Error Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.inversePrimary,\n                colorScheme = colorScheme,\n                name = \"Inverse Primary\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceTint,\n                colorScheme = colorScheme,\n                name = \"Surface Tint\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceDim,\n                colorScheme = colorScheme,\n                name = \"Surface Dim\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceBright,\n                colorScheme = colorScheme,\n                name = \"Surface Bright\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceVariant,\n                colorScheme = colorScheme,\n                name = \"Surface Variant\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.onSurfaceVariant,\n                colorScheme = colorScheme,\n                name = \"On Surface Variant\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.inverseSurface,\n                colorScheme = colorScheme,\n                name = \"Inverse Surface\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.inverseOnSurface,\n                colorScheme = colorScheme,\n                name = \"Inverse On Surface\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.onSurface,\n                colorScheme = colorScheme,\n                name = \"On Surface\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surface,\n                colorScheme = colorScheme,\n                name = \"Surface\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceContainerLowest,\n                colorScheme = colorScheme,\n                name = \"Surface Lowest\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceContainerLow,\n                colorScheme = colorScheme,\n                name = \"Surface Low\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceContainer,\n                colorScheme = colorScheme,\n                name = \"Surface Container\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceContainerHigh,\n                colorScheme = colorScheme,\n                name = \"Surface High\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.surfaceContainerHighest,\n                colorScheme = colorScheme,\n                name = \"Surface Highest\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Row(\n            modifier = Modifier.height(IntrinsicSize.Max)\n        ) {\n            MaterialYouPaletteItem(\n                color = colorScheme.outline,\n                colorScheme = colorScheme,\n                name = \"Outline\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n            MaterialYouPaletteItem(\n                color = colorScheme.outlineVariant,\n                colorScheme = colorScheme,\n                name = \"Outline Variant\",\n                onCopy = onCopy,\n                modifier = Modifier.weight(1f)\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/MaterialYouPaletteItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.selection.SelectionContainer\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun MaterialYouPaletteItem(\n    color: Color,\n    colorScheme: ColorScheme,\n    name: String,\n    onCopy: (Color) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    val containerColor by animateColorAsState(color)\n    val contentColor = colorScheme.contentColorFor(containerColor)\n\n    LocalContentColor.ProvidesValue(contentColor) {\n        Column(\n            modifier = modifier\n                .container(\n                    shape = RectangleShape,\n                    color = containerColor,\n                    resultPadding = 0.dp\n                )\n                .hapticsClickable {\n                    onCopy(containerColor)\n                }\n                .padding(12.dp)\n        ) {\n            AutoSizeText(\n                text = name,\n                maxLines = if (name.length < 11) 1\n                else 2,\n                style = LocalTextStyle.current.copy(\n                    lineHeight = 16.sp\n                )\n            )\n            Spacer(modifier = Modifier.weight(1f))\n            Spacer(modifier = Modifier.height(6.dp))\n            SelectionContainer {\n                AutoSizeText(\n                    text = containerColor.toHex(),\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .offset(y = 2.dp),\n                    style = LocalTextStyle.current.copy(\n                        textAlign = TextAlign.End,\n                        fontSize = 12.sp,\n                        color = LocalContentColor.current.copy(0.5f)\n                    )\n                )\n            }\n        }\n    }\n\n}\n\n@Stable\nprivate fun ColorScheme.contentColorFor(\n    color: Color\n): Color = when (color) {\n    primary -> onPrimary\n    secondary -> onSecondary\n    tertiary -> onTertiary\n    background -> onBackground\n    error -> onError\n    primaryContainer -> onPrimaryContainer\n    secondaryContainer -> onSecondaryContainer\n    tertiaryContainer -> onTertiaryContainer\n    errorContainer -> onErrorContainer\n    inverseSurface -> inverseOnSurface\n    surface -> onSurface\n    inversePrimary -> primary\n    surfaceVariant -> onSurfaceVariant\n    surfaceBright -> onSurface\n    surfaceContainer -> onSurface\n    surfaceContainerHigh -> onSurface\n    surfaceContainerHighest -> onSurface\n    surfaceContainerLow -> onSurface\n    surfaceContainerLowest -> onSurface\n    onPrimary -> primary\n    onSecondary -> secondary\n    onTertiary -> tertiary\n    onBackground -> background\n    onError -> error\n    onPrimaryContainer -> primaryContainer\n    onSecondaryContainer -> secondaryContainer\n    onTertiaryContainer -> tertiaryContainer\n    onErrorContainer -> errorContainer\n    inverseOnSurface -> inverseSurface\n    onSurface -> surface\n    outline -> surfaceContainerLow\n    outlineVariant -> onSurfaceVariant\n    onSurfaceVariant -> surfaceVariant\n    else -> Color.Unspecified\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/PaletteColorNameField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.BasicTextField\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TextFieldColors\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.focus.onFocusChanged\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextFieldColors\n\n\n@Composable\ninternal fun PaletteColorNameField(\n    value: String,\n    onValueChange: (String) -> Unit,\n    shape: Shape = ShapeDefaults.large,\n    colors: TextFieldColors = RoundedTextFieldColors(\n        isError = false,\n        unfocusedIndicatorColor = MaterialTheme.colorScheme.surfaceVariant.inverse({ 0.2f })\n            .copy(0.5f)\n    ),\n    modifier: Modifier = Modifier\n) {\n    var isFocused by remember {\n        mutableStateOf(false)\n    }\n    BasicTextField(\n        value = value,\n        onValueChange = onValueChange,\n        textStyle = LocalTextStyle.current.copy(\n            fontSize = 17.sp,\n            fontWeight = FontWeight.Bold,\n            color = colors.textColor(\n                enabled = true,\n                isError = false,\n                focused = true\n            )\n        ),\n        modifier = modifier\n            .background(\n                color = colors.containerColor(\n                    enabled = true,\n                    isError = false,\n                    focused = isFocused\n                ),\n                shape = shape\n            )\n            .border(\n                width = animateDpAsState(\n                    if (isFocused) 2.dp else 1.dp\n                ).value,\n                color = if (isFocused) {\n                    colors.focusedIndicatorColor\n                } else {\n                    colors.unfocusedIndicatorColor\n                },\n                shape = shape\n            )\n            .onFocusChanged { isFocused = it.isFocused },\n        maxLines = 3,\n        cursorBrush = SolidColor(colors.focusedIndicatorColor)\n    ) { inner ->\n        Box(\n            modifier = Modifier.padding(\n                horizontal = 16.dp,\n                vertical = 8.dp\n            )\n        ) {\n            inner()\n            if (value.isEmpty()) {\n                Text(\n                    text = stringResource(id = R.string.color_name),\n                    color = MaterialTheme.colorScheme.outline\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/PaletteColorsCountSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlin.math.roundToInt\n\n@Composable\nfun PaletteColorsCountSelector(\n    modifier: Modifier = Modifier,\n    value: Int,\n    onValueChange: (Int) -> Unit\n) {\n    EnhancedSliderItem(\n        modifier = modifier,\n        value = value,\n        icon = Icons.Rounded.Palette,\n        title = stringResource(R.string.max_colors_count),\n        onValueChange = {},\n        internalStateTransformation = {\n            it.roundToInt()\n        },\n        onValueChangeFinished = {\n            onValueChange(it.roundToInt())\n        },\n        valueRange = 1f..128f,\n        steps = 127,\n        shape = ShapeDefaults.extraLarge\n    )\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/PaletteToolsScreenControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.NamedPalette\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.screenLogic.PaletteToolsComponent\n\n@Composable\ninternal fun PaletteToolsScreenControls(\n    component: PaletteToolsComponent\n) {\n    val paletteType = component.paletteType ?: return\n\n    val bitmap = component.bitmap\n\n    AnimatedContent(\n        targetState = paletteType\n    ) { type ->\n        Column(\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            when (type) {\n                PaletteType.Default -> {\n                    DefaultPaletteControls(\n                        bitmap = bitmap ?: return@AnimatedContent,\n                        onOpenExport = { colors ->\n                            component.setPaletteType(PaletteType.Edit)\n                            component.updatePalette(\n                                NamedPalette(\n                                    name = \"\",\n                                    colors = colors\n                                )\n                            )\n                        }\n                    )\n                }\n\n                PaletteType.MaterialYou -> {\n                    MaterialYouPaletteControls(\n                        bitmap = bitmap ?: return@AnimatedContent\n                    )\n                }\n\n                PaletteType.Edit -> {\n                    EditPaletteControls(\n                        paletteFormat = component.paletteFormat,\n                        onPaletteFormatChange = component::updatePaletteFormat,\n                        palette = component.palette,\n                        onPaletteChange = component::updatePalette\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/PaletteType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components\n\nenum class PaletteType {\n    Default,\n    MaterialYou,\n    Edit\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/model/NamedColor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model\n\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteColor\n\ndata class NamedColor(\n    val color: Color,\n    val name: String\n)\n\ndata class NamedColorGroup(\n    val name: String,\n    val colors: List<NamedColor>\n)\n\ndata class NamedPalette(\n    val name: String = \"\",\n    val colors: List<NamedColor> = emptyList(),\n    val groups: List<NamedColorGroup> = emptyList()\n) {\n    fun isNotEmpty() = name.isNotBlank() || colors.isNotEmpty() || groups.isNotEmpty()\n}\n\nfun NamedPalette.toPalette(): Palette {\n    return Palette(\n        name = name,\n        colors = colors.map {\n            PaletteColor(\n                color = it.color,\n                name = it.name\n            )\n        },\n        groups = groups.map { group ->\n            ColorGroup(\n                name = group.name,\n                colors = group.colors.map {\n                    PaletteColor(\n                        color = it.color,\n                        name = it.name\n                    )\n                }\n            )\n        }.distinct(),\n    )\n}\n\nfun Palette.toNamed(): NamedPalette? {\n    if (name.isEmpty() && colors.isEmpty() && groups.isEmpty()) return null\n\n    return NamedPalette(\n        name = name,\n        colors = colors.map { it.toNamed() }.filter { it.color.alpha > 0f }.distinct(),\n        groups = groups.map { group ->\n            NamedColorGroup(\n                name = group.name,\n                colors = group.colors.map { it.toNamed() }.filter { it.color.alpha > 0f }\n            )\n        }.distinct()\n    )\n}\n\nfun PaletteColor.toNamed(): NamedColor = NamedColor(\n    color = toComposeColor(),\n    name = name\n)"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/components/model/PaletteFormatHelper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model\n\nimport com.t8rin.palette.PaletteFormat\n\nobject PaletteFormatHelper {\n    val entries: List<PaletteFormat> =\n        PaletteFormat.entries.toSet().minus(\n            setOf(\n                PaletteFormat.CSV,\n                PaletteFormat.HEX_RGBA\n            )\n        ).plus(\n            setOf(\n                PaletteFormat.HEX_RGBA,\n                PaletteFormat.CSV\n            )\n        ).toList()\n\n    fun entriesFor(filename: String): Set<PaletteFormat> = buildSet {\n        PaletteFormat.fromFilename(filename)?.let {\n            add(it)\n            addAll(entries - it)\n        } ?: addAll(entries)\n    }\n}"
  },
  {
    "path": "feature/palette-tools/src/main/java/com/t8rin/imagetoolbox/feature/palette_tools/presentation/screenLogic/PaletteToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.palette_tools.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.PaletteType\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.NamedPalette\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.PaletteFormatHelper\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.toNamed\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.toPalette\nimport com.t8rin.palette.PaletteFormat\nimport com.t8rin.palette.decode\nimport com.t8rin.palette.encode\nimport com.t8rin.palette.getCoder\nimport com.t8rin.palette.use\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.withContext\n\nclass PaletteToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    private val _paletteType: MutableState<PaletteType?> = mutableStateOf(null)\n    val paletteType by _paletteType\n\n    private val _paletteFormat: MutableState<PaletteFormat?> = mutableStateOf(null)\n    val paletteFormat by _paletteFormat\n\n    private val _palette: MutableState<NamedPalette> = mutableStateOf(NamedPalette())\n    val palette by _palette\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _uri = mutableStateOf<Uri?>(null)\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private var savingJob by smartJob()\n\n    fun setUri(uri: Uri?) {\n        _uri.value = uri\n        if (uri == null) {\n            _paletteType.update { null }\n            _paletteFormat.update { null }\n            _palette.update { NamedPalette() }\n            _bitmap.value = null\n            return\n        }\n\n        componentScope.launch {\n            _isImageLoading.value = true\n\n            _bitmap.value = imageScaler.scaleUntilCanShow(\n                imageGetter.getImage(\n                    data = uri.toString(),\n                    originalSize = false\n                )\n            )\n\n            if (bitmap == null || paletteType == PaletteType.Edit) {\n                _bitmap.update { null }\n                withContext(defaultDispatcher) {\n                    val data = fileController.readBytes(uri.toString())\n                    val entries =\n                        PaletteFormatHelper.entriesFor(uri.filename() ?: uri.toString())\n\n                    for (format in entries) {\n                        format.getCoder().use { decode(data) }.onSuccess { palette ->\n                            palette.toNamed()?.let { named ->\n                                _palette.update { named }\n                                updatePaletteFormat(format)\n                                break\n                            }\n                        }\n                    }\n                }\n            }\n\n            _isImageLoading.value = false\n        }\n    }\n\n    fun savePaletteTo(uri: Uri) {\n        val format = paletteFormat ?: PaletteFormatHelper.entries.first()\n\n        savingJob = trackProgress {\n            _isSaving.value = true\n            fileController.writeBytes(\n                uri = uri.toString(),\n                block = {\n                    it.writeBytes(\n                        format.getCoder().encode(palette.toPalette())\n                    )\n                }\n            ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            _isSaving.value = false\n        }\n    }\n\n    fun sharePalette() {\n        val format = paletteFormat ?: PaletteFormatHelper.entries.first()\n\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val data = withContext(defaultDispatcher) {\n                format.getCoder().use {\n                    encode(palette.toPalette())\n                }.getOrNull()\n            }\n\n            if (data == null) {\n                _isSaving.update { false }\n                return@trackProgress\n            }\n\n            shareProvider.shareByteArray(\n                byteArray = data,\n                filename = createPaletteFilename(),\n                onComplete = {\n                    _isSaving.value = false\n                    AppToastHost.showConfetti()\n                }\n            )\n        }\n    }\n\n    fun updatePalette(palette: NamedPalette) {\n        _palette.update { palette }\n    }\n\n    fun updatePaletteFormat(format: PaletteFormat) {\n        _paletteFormat.update { format }\n    }\n\n    fun setPaletteType(type: PaletteType) {\n        _paletteType.update { type }\n        if (type != PaletteType.Edit) {\n            _palette.update { NamedPalette() }\n            _paletteFormat.update { null }\n        }\n    }\n\n    fun createPaletteFilename(): String {\n        val name = palette.name.ifBlank { \"Palette_Export\" }\n        val format = paletteFormat ?: PaletteFormatHelper.entries.first()\n        val extension = format.fileExtension.maxBy { it.length }\n\n        return \"${name}_${timestamp()}.$extension\"\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n        ): PaletteToolsComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/pdf-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.pdf_tools\"\n\ndependencies {\n    implementation(libs.androidx.pdfviewer.fragment)\n    implementation(libs.androidx.fragment.compose)\n    implementation(libs.trickle)\n    implementation(libs.aire)\n    implementation(libs.pdfbox)\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/data/AndroidPdfHelper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.core.net.toFile\nimport androidx.core.net.toUri\nimport androidx.core.text.HtmlCompat\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ResizeFunction\nimport com.awxkee.aire.ScaleColorSpace\nimport com.t8rin.imagetoolbox.core.data.utils.aspectRatio\nimport com.t8rin.imagetoolbox.core.data.utils.observeHasChanges\nimport com.t8rin.imagetoolbox.core.domain.PDF\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.HocrData\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.HocrPageBox\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.HocrWord\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.PdfRenderer\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.asXObject\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.createPage\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.createPdf\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.pageIndices\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.safeOpenPdf\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.save\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.setMetadata\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfHelper\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PageSize\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCheckResult\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCreationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfMetadata\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PrintPdfParams\nimport com.t8rin.logger.makeLog\nimport com.tom_roush.pdfbox.pdmodel.PDDocument\nimport com.tom_roush.pdfbox.pdmodel.PDPage\nimport com.tom_roush.pdfbox.pdmodel.PDPageContentStream\nimport com.tom_roush.pdfbox.pdmodel.common.PDRectangle\nimport com.tom_roush.pdfbox.pdmodel.encryption.InvalidPasswordException\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.flow.MutableSharedFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.debounce\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.merge\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport javax.inject.Inject\nimport kotlin.math.max\nimport kotlin.math.roundToInt\nimport kotlin.random.Random\n\ninternal class AndroidPdfHelper @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val appScope: AppScope,\n    private val shareProvider: ShareProvider,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : PdfHelper, DispatchersHolder by dispatchersHolder {\n\n    companion object {\n        private const val SIGNATURES_LIMIT = 20\n\n        val HOCR_PAGE_REGEX = Regex(\n            pattern = \"<(?:div|span)[^>]*class=[\\\"'][^\\\"']*ocr_page[^\\\"']*[\\\"'][^>]*title=[\\\"'][^\\\"']*bbox\\\\s+(\\\\d+)\\\\s+(\\\\d+)\\\\s+(\\\\d+)\\\\s+(\\\\d+)[^\\\"']*[\\\"'][^>]*>\",\n            options = setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)\n        )\n        val HOCR_WORD_REGEX = Regex(\n            pattern = \"<span[^>]*class=[\\\"'][^\\\"']*ocrx_word[^\\\"']*[\\\"'][^>]*title=[\\\"'][^\\\"']*bbox\\\\s+(\\\\d+)\\\\s+(\\\\d+)\\\\s+(\\\\d+)\\\\s+(\\\\d+)[^\\\"']*[\\\"'][^>]*>(.*?)</span>\",\n            options = setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)\n        )\n        val HOCR_TAG_REGEX = Regex(\"<[^>]+>\")\n        val PDF_CONTROL_REGEX = Regex(\"[\\\\p{Cntrl}&&[^\\\\n\\\\r\\\\t]]\")\n    }\n\n    private val pagesCache = hashMapOf<String, List<IntegerSize>>()\n\n    private val signaturesDir: File get() = File(context.filesDir, \"signatures\").apply(File::mkdirs)\n\n    private val updateFlow: MutableSharedFlow<Unit> = MutableSharedFlow()\n\n    private var _masterPassword: String? = null\n    val masterPassword: String? get() = _masterPassword\n\n    override val savedSignatures: StateFlow<List<String>> =\n        merge(\n            updateFlow,\n            signaturesDir.observeHasChanges().debounce(100)\n        ).map {\n            signaturesDir\n                .listFiles()\n                .orEmpty()\n                .sortedByDescending { it.lastModified() }\n                .map { it.toUri().toString() }\n        }.stateIn(\n            scope = appScope,\n            started = SharingStarted.Eagerly,\n            initialValue = emptyList()\n        )\n\n    override suspend fun saveSignature(signature: Any): Boolean {\n        return runSuspendCatching {\n            val currentSignatures = savedSignatures.value\n\n            if (currentSignatures.size + 1 > SIGNATURES_LIMIT) {\n                currentSignatures.last().toUri().toFile().delete()\n            }\n\n            File(signaturesDir, \"signature_${System.currentTimeMillis()}.png\")\n                .outputStream()\n                .use { out ->\n                    imageGetter.getImage(signature)?.compress(\n                        Bitmap.CompressFormat.PNG,\n                        100,\n                        out\n                    )\n                }\n            updateFlow.emit(Unit)\n        }.onFailure {\n            it.makeLog(\"saveSignature\")\n        }.isSuccess\n    }\n\n    override fun setMasterPassword(password: String?) {\n        _masterPassword = password\n    }\n\n    override fun createTempName(key: String, uri: String?): String = tempName(\n        key = key,\n        uri = uri\n    ).removePrefix(PDF)\n\n    override fun clearPdfCache(uri: String?) {\n        appScope.launch {\n            runCatching {\n                if (uri.isNullOrBlank()) {\n                    File(context.cacheDir, \"pdf\").deleteRecursively()\n                } else {\n                    context.contentResolver.delete(uri.toUri(), null, null)\n                }\n            }.onFailure {\n                \"failed to delete $uri\".makeLog(\"delete\")\n            }\n        }\n    }\n\n    override suspend fun checkPdf(uri: String): PdfCheckResult = withContext(defaultDispatcher) {\n        try {\n            usePdf(uri) { document ->\n                if (masterPassword.isNullOrBlank()) {\n                    PdfCheckResult.Open\n                } else {\n                    PdfCheckResult.Protected.Unlocked(\n                        document.save(\n                            filename = uri.toUri().filename()?.let { \"$PDF$it\" } ?: tempName(\n                                key = \"unlocked\",\n                                uri = uri\n                            )\n                        )\n                    )\n                }\n            }\n        } catch (_: InvalidPasswordException) {\n            PdfCheckResult.Protected.NeedsPassword\n        } catch (t: Throwable) {\n            ensureActive()\n            PdfCheckResult.Failure(t)\n        }.makeLog(\"checkPdf\")\n    }\n\n    override suspend fun getPdfPages(\n        uri: String\n    ): List<Int> = withContext(decodingDispatcher) {\n        try {\n            usePdf(\n                uri = uri,\n                password = masterPassword,\n                action = PDDocument::pageIndices\n            )\n        } catch (_: Throwable) {\n            emptyList()\n        }\n    }\n\n    override suspend fun getPdfPageSizes(\n        uri: String\n    ): List<IntegerSize> = withContext(decodingDispatcher) {\n        pagesCache[uri]?.takeIf { it.isNotEmpty() }?.let { return@withContext it }\n\n        try {\n            PdfRenderer(\n                uri = uri,\n                password = masterPassword\n            )?.use { renderer ->\n                List(renderer.pageCount) {\n                    renderer.openPage(it).run {\n                        IntegerSize(width, height)\n                    }\n                }\n            }.orEmpty()\n        } catch (_: Throwable) {\n            emptyList()\n        }.also { pagesCache[uri] = it }\n    }\n\n    internal fun tempName(\n        key: String,\n        uri: String? = null\n    ): String {\n        val keyFixed = if (key.isBlank()) \"_\" else \"_${key}_\"\n\n        return PDF + (uri?.toUri()?.filename()?.substringBeforeLast('.')?.let {\n            \"${it}${keyFixed.removeSuffix(\"_\")}.pdf\"\n        } ?: \"PDF$keyFixed${timestamp()}_${\n            Random(Random.nextInt()).hashCode().toString().take(4)\n        }.pdf\")\n    }\n\n    internal inline fun <T> usePdf(\n        uri: String,\n        password: String? = masterPassword,\n        action: (PDDocument) -> T\n    ): T = openPdf(\n        uri = uri,\n        password = password\n    ).use(action)\n\n    internal fun openPdf(\n        uri: String,\n        password: String? = masterPassword\n    ): PDDocument = safeOpenPdf(\n        uri = uri,\n        password = password\n    )\n\n    internal inline fun <T> useRenderer(\n        uri: String,\n        password: String? = masterPassword,\n        action: (PdfRenderer) -> T\n    ) = PdfRenderer(\n        uri = uri,\n        password = password,\n        onFailure = { throw it }\n    )?.use(action)\n\n    internal suspend fun PDDocument.save(\n        filename: String,\n        password: String? = null,\n        metadata: PdfMetadata? = PdfMetadata.Empty\n    ): String {\n        if (metadata != PdfMetadata.Empty) {\n            setMetadata(metadata)\n        }\n\n        return shareProvider.cacheDataOrThrow(\n            filename = filename,\n            writeData = {\n                save(\n                    writeable = it,\n                    password = password\n                )\n            }\n        )\n    }\n\n    internal fun PrintPdfParams.calculatePageSize(\n        firstPageOnSheet: PDPage\n    ) = pageSizeFinal\n        ?: copy(\n            pageSize = firstPageOnSheet.cropBox.run {\n                PageSize(\n                    width = width.roundToInt(),\n                    height = height.roundToInt(),\n                    name = \"Auto\"\n                )\n            }\n        ).pageSizeFinal\n\n    internal fun parseHocrData(hocr: String): HocrData {\n        val pageBox = HOCR_PAGE_REGEX.find(hocr)?.let { match ->\n            val left = match.groupValues.getOrNull(1)?.toFloatOrNull() ?: return@let null\n            val top = match.groupValues.getOrNull(2)?.toFloatOrNull() ?: return@let null\n            val right = match.groupValues.getOrNull(3)?.toFloatOrNull() ?: return@let null\n            val bottom = match.groupValues.getOrNull(4)?.toFloatOrNull() ?: return@let null\n            HocrPageBox(\n                width = (right - left).coerceAtLeast(1f),\n                height = (bottom - top).coerceAtLeast(1f)\n            )\n        }\n\n        val words = HOCR_WORD_REGEX\n            .findAll(hocr)\n            .mapNotNull { match ->\n                val left = match.groupValues.getOrNull(1)?.toFloatOrNull() ?: return@mapNotNull null\n                val top = match.groupValues.getOrNull(2)?.toFloatOrNull() ?: return@mapNotNull null\n                val right =\n                    match.groupValues.getOrNull(3)?.toFloatOrNull() ?: return@mapNotNull null\n                val bottom =\n                    match.groupValues.getOrNull(4)?.toFloatOrNull() ?: return@mapNotNull null\n                val rawText = match.groupValues.getOrNull(5).orEmpty()\n                val text = HtmlCompat\n                    .fromHtml(rawText.replace(HOCR_TAG_REGEX, \"\"), HtmlCompat.FROM_HTML_MODE_LEGACY)\n                    .toString()\n                    .trim()\n                    .takeIf { it.isNotBlank() }\n                    ?: return@mapNotNull null\n\n                HocrWord(\n                    left = left,\n                    top = top,\n                    right = right,\n                    bottom = bottom,\n                    text = text\n                )\n            }\n            .toList()\n\n        return HocrData(\n            pageBox = pageBox,\n            words = words\n        )\n    }\n\n    internal fun String.cleanPdfText(): String = replace(PDF_CONTROL_REGEX, \"\").take(2000)\n\n    internal suspend fun prepareImagesForPdf(\n        imageUris: List<String>,\n        params: PdfCreationParams\n    ): List<Bitmap> {\n        val scale = params.preset.value / 100f\n        return imageUris.mapNotNull { uri ->\n            imageGetter.getImage(data = uri)?.let {\n                imageScaler.scaleImage(\n                    image = it,\n                    width = (it.width * scale).roundToInt(),\n                    height = (it.height * scale).roundToInt(),\n                    resizeType = ResizeType.Flexible\n                )\n            }\n        }\n    }\n\n    internal suspend fun createPdfFromPreparedImages(\n        images: List<Bitmap>,\n        quality: Float,\n        scaleSmallImagesToLarge: Boolean,\n        addTextLayer: (PDPageContentStream.(pageIndex: Int, pageWidth: Float, pageHeight: Float, document: PDDocument) -> Unit)?\n    ): String {\n        if (images.isEmpty()) error(\"No PDF created\")\n\n        return createPdf { newDoc ->\n            var h = 0\n            var maxWidth = 0\n\n            images.forEach {\n                maxWidth = max(maxWidth, it.width)\n            }\n\n            for (image in images) {\n                h += if (scaleSmallImagesToLarge && image.width != maxWidth) {\n                    (maxWidth / image.aspectRatio).toInt().coerceAtLeast(1)\n                } else {\n                    image.height.coerceAtLeast(1)\n                }\n            }\n\n            val size = IntegerSize(maxWidth, h)\n\n            images.forEachIndexed { index, image ->\n                val bitmap = if (scaleSmallImagesToLarge && image.width != size.width) {\n                    Aire.scale(\n                        bitmap = image,\n                        dstWidth = size.width,\n                        dstHeight = (size.width / image.aspectRatio).toInt(),\n                        scaleMode = ResizeFunction.Bicubic,\n                        colorSpace = ScaleColorSpace.SRGB\n                    )\n                } else image\n\n                val pageHeight = bitmap.height.toFloat()\n                val pageWidth = bitmap.width.toFloat()\n                newDoc.createPage(\n                    PDPage(\n                        PDRectangle(\n                            pageWidth,\n                            pageHeight\n                        )\n                    )\n                ) {\n                    drawImage(\n                        bitmap.asXObject(newDoc, quality),\n                        0f,\n                        0f,\n                        pageWidth,\n                        pageHeight\n                    )\n                    addTextLayer?.invoke(this, index, pageWidth, pageHeight, newDoc)\n                }\n            }\n\n            shareProvider.cacheData(\n                writeData = newDoc::save,\n                filename = createTempName(key = \"\")\n            ) ?: error(\"No PDF created\")\n        }\n    }\n\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/data/AndroidPdfManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.net.toUri\nimport com.awxkee.aire.Aire\nimport com.t8rin.imagetoolbox.core.data.saving.io.ByteArrayReadable\nimport com.t8rin.imagetoolbox.core.data.saving.io.StreamWriteable\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriReadable\nimport com.t8rin.imagetoolbox.core.data.saving.io.shielded\nimport com.t8rin.imagetoolbox.core.data.utils.computeFromReadable\nimport com.t8rin.imagetoolbox.core.data.utils.outputStream\nimport com.t8rin.imagetoolbox.core.domain.PDF\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.createZip\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.core.utils.putEntry\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.HocrWord\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.PdfRenderer\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.asXObject\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.createPage\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.createPdf\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.crop\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.defaultFont\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.getAllImages\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.getPageSafe\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.metadata\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.orAll\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.pageIndices\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.save\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.setAlpha\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.setColor\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.transformImages\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.writePage\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfHelper\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.ExtractPagesAction\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfAnnotationType\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCreationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCropParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfExtractPagesParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfMetadata\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfPageNumbersParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfRemoveAnnotationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfSignatureParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfWatermarkParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PrintPdfParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.SearchablePdfPage\nimport com.t8rin.logger.makeLog\nimport com.t8rin.trickle.Trickle\nimport com.tom_roush.pdfbox.io.MemoryUsageSetting\nimport com.tom_roush.pdfbox.multipdf.PDFMergerUtility\nimport com.tom_roush.pdfbox.pdmodel.PDDocument\nimport com.tom_roush.pdfbox.pdmodel.PDPage\nimport com.tom_roush.pdfbox.pdmodel.common.PDRectangle\nimport com.tom_roush.pdfbox.pdmodel.encryption.InvalidPasswordException\nimport com.tom_roush.pdfbox.pdmodel.graphics.state.RenderingMode\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationFileAttachment\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationLine\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationPopup\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationRubberStamp\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationText\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationUnknown\nimport com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget\nimport com.tom_roush.pdfbox.text.PDFTextStripper\nimport com.tom_roush.pdfbox.util.Matrix\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.channelFlow\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.withContext\nimport java.io.ByteArrayOutputStream\nimport javax.inject.Inject\n\ninternal class AndroidPdfManager @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val helper: AndroidPdfHelper,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, PdfManager, PdfHelper by helper {\n\n    override fun extractPages(\n        uri: String,\n        params: PdfExtractPagesParams\n    ): Flow<ExtractPagesAction> = channelFlow {\n        val scale = params.preset.value / 100f\n        val dpi = 72f * scale\n\n        catchPdf {\n            useRenderer(uri) { renderer ->\n                params.pages.orAll(renderer.pDocument).also {\n                    send(ExtractPagesAction.PagesCount(it.size))\n                }.forEach { pageIndex ->\n                    send(\n                        ExtractPagesAction.Progress(\n                            index = pageIndex,\n                            image = renderer.safeRenderDpi(\n                                pageIndex = pageIndex,\n                                dpi = dpi\n                            ).whiteBg()\n                        )\n                    )\n                }\n            }\n        }\n        close()\n    }.flowOn(defaultDispatcher)\n\n    override suspend fun createPdf(\n        imageUris: List<String>,\n        params: PdfCreationParams\n    ): String = catchPdf {\n        createPdfFromPreparedImages(\n            images = prepareImagesForPdf(\n                imageUris = imageUris,\n                params = params\n            ),\n            quality = params.quality / 100f,\n            scaleSmallImagesToLarge = params.scaleSmallImagesToLarge,\n            addTextLayer = null\n        )\n    }\n\n    override suspend fun createSearchablePdf(\n        pages: List<SearchablePdfPage>,\n        params: PdfCreationParams\n    ): String = catchPdf {\n        createPdfFromPreparedImages(\n            images = prepareImagesForPdf(\n                imageUris = pages.map(SearchablePdfPage::imageUri),\n                params = params\n            ),\n            quality = params.quality / 100f,\n            scaleSmallImagesToLarge = params.scaleSmallImagesToLarge,\n            addTextLayer = { pageIndex, pageWidth, pageHeight, document ->\n                val page = pages.getOrNull(pageIndex) ?: return@createPdfFromPreparedImages\n                val hocrData = page.hocr.let(::parseHocrData)\n                val sourcePageWidth = hocrData.pageBox?.width?.takeIf { it > 0f } ?: pageWidth\n                val sourcePageHeight = hocrData.pageBox?.height?.takeIf { it > 0f } ?: pageHeight\n                val scaleX = (pageWidth / sourcePageWidth).coerceAtLeast(0.0001f)\n                val scaleY = (pageHeight / sourcePageHeight).coerceAtLeast(0.0001f)\n\n                val words = hocrData.words\n                    .ifEmpty {\n                        page.text\n                            .lineSequence()\n                            .map(String::trim)\n                            .filter(String::isNotBlank)\n                            .take(300)\n                            .mapIndexed { index, line ->\n                                HocrWord(\n                                    left = 8f,\n                                    top = (index * 14f),\n                                    right = 8f + 1000f,\n                                    bottom = (index * 14f) + 12f,\n                                    text = line\n                                )\n                            }\n                            .toList()\n                    }\n\n                words.forEach { word ->\n                    val text = word.text.cleanPdfText()\n                    if (text.isBlank()) return@forEach\n\n                    val left = word.left * scaleX\n                    val right = word.right * scaleX\n                    val top = word.top * scaleY\n                    val bottom = word.bottom * scaleY\n\n                    val boxHeight = (bottom - top).coerceAtLeast(1f)\n                    val targetWidth = (right - left).coerceAtLeast(1f)\n                    val x = left.coerceIn(0f, pageWidth - 1f)\n\n                    val glyphWidthEm = (document.defaultFont.getStringWidth(text) / 1000f)\n                        .coerceAtLeast(0.001f)\n\n                    val fontByHeight = (boxHeight * 0.84f).coerceAtLeast(1f)\n                    val fontByWidth = (targetWidth / glyphWidthEm).coerceAtLeast(1f)\n                    val fontSize = (fontByHeight * 0.72f + fontByWidth * 0.28f)\n                        .coerceIn(1f, pageHeight.coerceAtLeast(1f))\n\n                    val sourceWidth = (glyphWidthEm * fontSize).coerceAtLeast(0.1f)\n                    val horizontalScale = (targetWidth / sourceWidth * 100f).coerceIn(80f, 125f)\n\n                    val y = (pageHeight - bottom +\n                            ((boxHeight - fontSize).coerceAtLeast(0f) * 0.5f) +\n                            (fontSize * 0.10f)\n                            ).coerceIn(0f, pageHeight - 1f)\n\n                    beginText()\n                    setRenderingMode(RenderingMode.NEITHER)\n                    setFont(document.defaultFont, fontSize)\n                    setHorizontalScaling(horizontalScale)\n                    newLineAtOffset(x, y)\n                    showText(text)\n                    endText()\n                }\n            }\n        )\n    }\n\n    override suspend fun mergePdfs(uris: List<String>): String = catchPdf {\n        PDFMergerUtility().run {\n            uris.forEach { uri ->\n                addSource(UriReadable(uri.toUri(), context).stream)\n            }\n            shareProvider.cacheDataOrThrow(filename = tempName(\"merged\")) { output ->\n                destinationStream = output.outputStream()\n                mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly())\n            }\n        }\n    }\n\n    override suspend fun splitPdf(\n        uri: String,\n        pages: List<Int>?\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            createPdf { newDoc ->\n                pages.orAll(document).forEach { index ->\n                    newDoc.addPage(document.getPageSafe(index))\n                }\n\n                newDoc.save(\n                    filename = tempName(\n                        key = \"split\",\n                        uri = uri\n                    )\n                )\n            }\n        }\n    }\n\n    override suspend fun removePdfPages(\n        uri: String,\n        pages: List<Int>\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            createPdf { newDoc ->\n                document.pageIndices.forEach { index ->\n                    if (index !in pages) newDoc.addPage(document.getPage(index))\n                }\n\n                if (newDoc.numberOfPages <= 0) {\n                    error(getString(R.string.cant_remove_all))\n                }\n\n                newDoc.save(\n                    filename = tempName(\n                        key = \"removed\",\n                        uri = uri\n                    )\n                )\n            }\n        }\n    }\n\n    override suspend fun rotatePdf(\n        uri: String,\n        rotations: List<Int>\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            document.pages.forEachIndexed { idx, page ->\n                val angle = rotations.getOrNull(idx) ?: 0\n                page.rotation = (page.rotation + angle) % 360\n            }\n\n            document.save(\n                filename = tempName(\n                    key = \"rotated\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun rearrangePdf(\n        uri: String,\n        newOrder: List<Int>\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            createPdf { newDoc ->\n                newOrder.forEach { pageIndex ->\n                    newDoc.addPage(document.getPageSafe(pageIndex))\n                }\n\n                newDoc.save(\n                    filename = tempName(\n                        key = \"rearranged\",\n                        uri = uri\n                    )\n                )\n            }\n        }\n    }\n\n    override suspend fun addPageNumbers(\n        uri: String,\n        params: PdfPageNumbersParams\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            val font = document.defaultFont\n            val totalPages = document.numberOfPages\n            val label = params.labelFormat\n                .replace(\"{total}\", totalPages.toString())\n\n            document.pages.forEachIndexed { idx, page ->\n                val text = label.replace(\"{n}\", (idx + 1).toString())\n\n                val cropBox = page.cropBox\n                val pageWidth = cropBox.width\n                val pageHeight = cropBox.height\n                val originX = cropBox.lowerLeftX\n                val originY = cropBox.lowerLeftY\n\n                val textWidth = font.getStringWidth(text) / 1000f * 12f\n\n                val baseX = when (params.position) {\n                    Position.TopLeft,\n                    Position.CenterLeft,\n                    Position.BottomLeft -> 10f\n\n                    Position.TopCenter,\n                    Position.Center,\n                    Position.BottomCenter -> pageWidth / 2f\n\n                    Position.TopRight,\n                    Position.CenterRight,\n                    Position.BottomRight -> pageWidth - 10f\n                }\n\n                val baseY = when (params.position) {\n                    Position.TopLeft,\n                    Position.TopCenter,\n                    Position.TopRight -> pageHeight - 20f\n\n                    Position.CenterLeft,\n                    Position.Center,\n                    Position.CenterRight -> pageHeight / 2f\n\n                    Position.BottomLeft,\n                    Position.BottomCenter,\n                    Position.BottomRight -> 20f\n                }\n\n                val adjustedX = when (params.position) {\n                    Position.TopCenter,\n                    Position.Center,\n                    Position.BottomCenter -> baseX - textWidth / 2f\n\n                    Position.TopRight,\n                    Position.CenterRight,\n                    Position.BottomRight -> baseX - textWidth\n\n                    else -> baseX\n                }\n\n                val adjustedY = when (params.position) {\n                    Position.CenterLeft,\n                    Position.Center,\n                    Position.CenterRight -> baseY - 6f\n\n                    else -> baseY\n                }\n\n                val adjustedXWithOrigin = adjustedX + originX\n                val adjustedYWithOrigin = adjustedY + originY\n\n                document.writePage(page) {\n                    beginText()\n                    setFont(font, 12f)\n                    setColor(params.color)\n                    newLineAtOffset(adjustedXWithOrigin, adjustedYWithOrigin)\n                    showText(text)\n                    endText()\n                }\n            }\n\n            document.save(\n                filename = tempName(\n                    key = \"numbered\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun addWatermark(\n        uri: String,\n        params: PdfWatermarkParams\n    ): String = catchPdf {\n        val color = Color(params.color)\n\n        usePdf(uri) { document ->\n            val font = document.defaultFont\n\n            params.pages.orAll(document).forEach { pageIndex ->\n                val page = document.getPageSafe(pageIndex)\n\n                val textWidth =\n                    font.getStringWidth(params.text) / 1000f * params.fontSize\n\n                val radians = Math.toRadians(-params.rotation.toDouble())\n                val cropBox = page.cropBox\n\n                val originX = cropBox.lowerLeftX\n                val originY = cropBox.lowerLeftY\n\n                val centerX = originX + cropBox.width / 2f\n                val centerY = originY + cropBox.height / 2f\n\n                val matrix = Matrix.getRotateInstance(\n                    radians,\n                    centerX,\n                    centerY\n                )\n\n                document.writePage(page) {\n                    beginText()\n                    setFont(font, params.fontSize)\n                    setColor(color.copy(params.opacity))\n                    setTextMatrix(matrix)\n                    newLineAtOffset(-textWidth / 2f, 0f)\n                    showText(params.text)\n                    endText()\n                }\n            }\n\n            document.save(\n                filename = tempName(\n                    key = \"watermarked\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun addSignature(\n        uri: String,\n        params: PdfSignatureParams\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            val signatureImage = imageGetter.getImage(data = params.signatureImage)!!.asXObject(\n                document = document,\n                quality = 1f\n            )\n\n            val imageAspect = signatureImage.width.toFloat() / signatureImage.height.toFloat()\n\n            params.pages.orAll(document).forEach { pageIndex ->\n                val page = document.getPageSafe(pageIndex)\n\n                val crop = page.cropBox\n\n                val pageWidth = crop.width\n                val pageHeight = crop.height\n                val originX = crop.lowerLeftX\n                val originY = crop.lowerLeftY\n\n                val targetWidth = pageWidth * params.size\n                val targetHeight = targetWidth / imageAspect\n\n                val centerX = pageWidth * params.x\n                val centerY = pageHeight * (1f - params.y)\n\n                var x = centerX - targetWidth / 2f\n                var y = centerY - targetHeight / 2f\n\n                x = x.coerceIn(0f, pageWidth - targetWidth)\n                y = y.coerceIn(0f, pageHeight - targetHeight)\n\n                x += originX\n                y += originY\n\n                document.writePage(page) {\n                    setAlpha(params.opacity)\n                    saveGraphicsState()\n                    transform(\n                        Matrix(\n                            targetWidth,\n                            0f,\n                            0f,\n                            -targetHeight,\n                            x,\n                            y + targetHeight\n                        )\n                    )\n                    drawImage(signatureImage, 0f, 0f, 1f, 1f)\n                    restoreGraphicsState()\n                }\n            }\n\n            document.save(\n                filename = tempName(\n                    key = \"signed\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun protectPdf(\n        uri: String,\n        password: String\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            document.save(\n                filename = tempName(\n                    key = \"protected\",\n                    uri = uri\n                ),\n                password = password\n            )\n        }\n    }\n\n    override suspend fun unlockPdf(\n        uri: String,\n        password: String\n    ): String = catchPdf {\n        usePdf(\n            uri = uri,\n            password = password,\n            action = { document ->\n                document.save(\n                    filename = tempName(\n                        key = \"unlocked\",\n                        uri = uri\n                    )\n                )\n            }\n        )\n    }\n\n    override suspend fun extractPagesFromPdf(uri: String): List<String> = catchPdf {\n        useRenderer(uri) { renderer ->\n            renderer.pageIndices.mapNotNull { pageIndex ->\n                val bitmap = renderer.safeRenderDpi(\n                    pageIndex = pageIndex,\n                    dpi = 72f\n                ).whiteBg()\n\n                shareProvider.cacheImage(\n                    image = bitmap,\n                    imageInfo = ImageInfo(\n                        width = bitmap.width,\n                        height = bitmap.height,\n                        imageFormat = ImageFormat.Png.Lossless\n                    )\n                )\n            }\n        } ?: emptyList()\n    }\n\n    override suspend fun compressPdf(\n        uri: String,\n        quality: Float\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            document.transformImages(\n                quality = quality,\n                transform = { it }\n            )\n            document.save(\n                filename = tempName(\n                    key = \"compressed\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun convertToGrayscale(uri: String): String = catchPdf {\n        usePdf(uri) { document ->\n            document.transformImages(\n                quality = 0.8f,\n                transform = {\n                    Aire.saturation(\n                        bitmap = it,\n                        saturation = 0f,\n                        tonemap = false\n                    )\n                }\n            )\n            document.save(\n                filename = tempName(\n                    key = \"grayscale\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun repairPdf(uri: String): String = catchPdf {\n        usePdf(uri) { document ->\n            document.save(\n                filename = tempName(\n                    key = \"repaired\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun changePdfMetadata(\n        uri: String,\n        metadata: PdfMetadata?\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            document.save(\n                metadata = metadata,\n                filename = tempName(\n                    key = \"metadata\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun getPdfMetadata(uri: String): PdfMetadata = catchPdf {\n        usePdf(\n            uri = uri,\n            action = PDDocument::metadata\n        )\n    }\n\n    override suspend fun stripText(uri: String): List<String> = catchPdf {\n        usePdf(uri) { document ->\n            PDFTextStripper().run {\n                document.pageIndices.map { pageIndex ->\n                    startPage = pageIndex + 1\n                    endPage = pageIndex + 1\n                    getText(document).trim()\n                }\n            }\n        }\n    }\n\n    override suspend fun cropPdf(\n        uri: String,\n        params: PdfCropParams\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            params.pages.orAll(document).forEach { pageIndex ->\n                document.getPageSafe(pageIndex).let { page ->\n                    page.cropBox = page.cropBox.crop(\n                        rotation = page.rotation,\n                        rect = params.rect\n                    )\n                }\n            }\n\n            document.save(\n                filename = tempName(\n                    key = \"cropped\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    override suspend fun flattenPdf(\n        uri: String,\n        quality: Float\n    ): String = catchPdf {\n        val dpi = 72f + (228f * quality)\n\n        usePdf(uri) { document ->\n            val renderer = PdfRenderer(document)\n\n            createPdf { newDoc ->\n                document.pages.forEachIndexed { index, page ->\n                    val cropBox = page.cropBox\n\n                    val pdImage = renderer\n                        .safeRenderDpi(index, dpi)\n                        .whiteBg()\n                        .asXObject(newDoc, quality)\n\n                    newDoc.createPage(PDPage(cropBox)) {\n                        drawImage(\n                            pdImage,\n                            0f,\n                            0f,\n                            cropBox.width,\n                            cropBox.height\n                        )\n                    }\n                }\n\n                newDoc.save(\n                    filename = createTempName(\n                        key = \"flattened\",\n                        uri = uri\n                    )\n                )\n            }\n        }\n    }\n\n    override suspend fun detectPdfAutoRotations(\n        uri: String\n    ): List<Int> = catchPdf {\n        usePdf(uri) { document ->\n            val rotations = document.pages.map { page ->\n                ((page.rotation % 360) + 360) % 360\n            }\n\n            val majority = rotations\n                .groupingBy { it }\n                .eachCount()\n                .maxByOrNull { it.value }\n                ?.key ?: 0\n\n            rotations.map { rotation ->\n                ((majority - rotation) + 360) % 360\n            }\n        }\n    }\n\n    override suspend fun extractImagesFromPdf(\n        uri: String\n    ): String? = catchPdf {\n        var hasImages = false\n\n        val prefix = uri.toUri().filename()?.substringBeforeLast('.') ?: timestamp()\n        val filename = \"$PDF${prefix}_extracted.zip\"\n\n        val zipPath = usePdf(uri) { document ->\n            shareProvider.cacheDataOrThrow(\n                filename = filename\n            ) { output ->\n                val seen = mutableSetOf<Any>()\n                var index = 0\n\n                output.outputStream().createZip { zip ->\n                    for (xObject in document.getAllImages()) {\n                        if (!seen.add(xObject.cosObject)) continue\n\n                        val suffix = xObject.suffix?.lowercase() ?: \"png\"\n                        val stream = if (suffix == \"jpg\" || suffix == \"jp2\" || suffix == \"tiff\") {\n                            xObject.stream.createInputStream()\n                        } else {\n                            val data = ByteArrayOutputStream().apply {\n                                use {\n                                    xObject.image.compress(\n                                        Bitmap.CompressFormat.PNG,\n                                        100,\n                                        it\n                                    )\n                                }\n                            }.toByteArray()\n\n                            if (!seen.add(HashingType.MD5.computeFromReadable(ByteArrayReadable(data)))) continue\n\n                            data.inputStream()\n                        }\n\n                        zip.putEntry(\n                            name = \"extracted_${index++}.$suffix\",\n                            input = stream\n                        )\n                        hasImages = true\n                    }\n                }\n            }\n        }\n\n        if (!hasImages) {\n            clearPdfCache(zipPath)\n            null\n        } else {\n            zipPath\n        }\n    }\n\n    override suspend fun convertToZip(\n        uri: String,\n        interval: Int\n    ): String = catchPdf {\n        val prefix = uri.toUri().filename()?.substringBeforeLast('.') ?: timestamp()\n        val filename = \"$PDF${prefix}.zip\"\n\n        usePdf(uri) { document ->\n            shareProvider.cacheDataOrThrow(\n                filename = filename\n            ) { output ->\n                var index = 0\n\n                output.outputStream().createZip { zip ->\n                    document.pageIndices\n                        .chunked(interval.coerceAtLeast(1))\n                        .forEach { pages ->\n                            createPdf { newDoc ->\n                                pages.forEach { pageIndex ->\n                                    newDoc.addPage(document.getPageSafe(pageIndex))\n                                }\n\n                                zip.putEntry(\n                                    name = \"${prefix}_${index++}.pdf\",\n                                    write = {\n                                        newDoc.save(StreamWriteable(it).shielded())\n                                    }\n                                )\n                            }\n                        }\n                }\n            }\n        }\n    }\n\n    override suspend fun printPdf(\n        uri: String,\n        params: PrintPdfParams\n    ): String = catchPdf {\n        val dpi = 72f + (228f * params.quality)\n\n        usePdf(uri) { document ->\n            val renderer = PdfRenderer(document)\n\n            createPdf { newDoc ->\n                val pagesPerSheet = params.pagesPerSheet.coerceIn(PrintPdfParams.pageRange)\n\n                val gridSize = params.gridSize\n\n                val totalPages = document.numberOfPages\n                val sheetsNeeded = (totalPages + pagesPerSheet - 1) / pagesPerSheet\n\n                for (sheetIndex in 0 until sheetsNeeded) {\n                    val startPageIndex = sheetIndex * pagesPerSheet\n                    val firstPageOnSheet = document.getPage(startPageIndex)\n\n                    val cropBox = params.calculatePageSize(firstPageOnSheet)?.let { size ->\n                        PDRectangle(size.width.toFloat(), size.height.toFloat())\n                    } ?: firstPageOnSheet.cropBox\n\n                    newDoc.createPage(PDPage(cropBox)) {\n                        val pageWidth = cropBox.width\n                        val pageHeight = cropBox.height\n\n                        val rows = gridSize.first\n                        val cols = gridSize.second\n\n                        val cellWidth = pageWidth / cols\n                        val cellHeight = pageHeight / rows\n\n                        val margin = if (params.marginPercent > 0) {\n                            (minOf(\n                                pageWidth,\n                                pageHeight\n                            ) * params.marginPercent / 100f).coerceAtLeast(0f)\n                        } else 0f\n\n                        val availableContentWidth = if (margin > 0) {\n                            (pageWidth - (cols + 1) * margin) / cols\n                        } else cellWidth\n\n                        val availableContentHeight = if (margin > 0) {\n                            (pageHeight - (rows + 1) * margin) / rows\n                        } else cellHeight\n\n                        for (i in 0 until pagesPerSheet) {\n                            val pageIndex = startPageIndex + i\n                            if (pageIndex >= totalPages) break\n\n                            val sourcePage = document.getPage(pageIndex)\n                            val sourceWidth = sourcePage.cropBox.width\n                            val sourceHeight = sourcePage.cropBox.height\n\n                            val scale = minOf(\n                                availableContentWidth / sourceWidth,\n                                availableContentHeight / sourceHeight\n                            ).coerceAtMost(1f)\n\n                            val scaledWidth = sourceWidth * scale\n                            val scaledHeight = sourceHeight * scale\n\n                            val col = i % cols\n                            val row = i / cols\n\n                            val cellLeft = col * cellWidth\n                            val cellBottom = pageHeight - (row + 1) * cellHeight\n\n                            val x: Float\n                            val y: Float\n\n                            if (margin > 0) {\n                                val contentLeft = cellLeft + margin\n                                val contentBottom = cellBottom + margin\n                                val contentCenterX = contentLeft + availableContentWidth / 2\n                                val contentCenterY = contentBottom + availableContentHeight / 2\n                                x = contentCenterX - scaledWidth / 2\n                                y = contentCenterY - scaledHeight / 2\n                            } else {\n                                x = cellLeft + (cellWidth - scaledWidth) / 2\n                                y = cellBottom + (cellHeight - scaledHeight) / 2\n                            }\n\n                            val pdImage = Trickle\n                                .drawColorBehind(\n                                    input = renderer.safeRenderDpi(pageIndex, dpi),\n                                    color = Color.White.toArgb()\n                                )\n                                .asXObject(\n                                    document = newDoc,\n                                    quality = params.quality\n                                )\n\n                            drawImage(pdImage, x, y, scaledWidth, scaledHeight)\n                        }\n                    }\n                }\n\n                newDoc.save(\n                    filename = createTempName(\n                        key = \"printed\",\n                        uri = uri\n                    )\n                )\n            }\n        }\n    }\n\n    override suspend fun removeAnnotations(\n        uri: String,\n        params: PdfRemoveAnnotationParams\n    ): String = catchPdf {\n        usePdf(uri) { document ->\n            val removeAll = params.types == PdfAnnotationType.setEntries\n\n            params.pages.orAll(document).forEach { pageIndex ->\n                val page = document.getPageSafe(pageIndex)\n\n                if (removeAll) {\n                    page.annotations = emptyList()\n                } else {\n                    page.annotations = page.annotations.filterNot { annotation ->\n                        params.types.any { type ->\n                            when (type) {\n                                PdfAnnotationType.Link -> annotation is PDAnnotationLink\n                                PdfAnnotationType.FileAttachment -> annotation is PDAnnotationFileAttachment\n                                PdfAnnotationType.Line -> annotation is PDAnnotationLine\n                                PdfAnnotationType.Popup -> annotation is PDAnnotationPopup\n                                PdfAnnotationType.Stamp -> annotation is PDAnnotationRubberStamp\n                                PdfAnnotationType.SquareCircle -> annotation is PDAnnotationSquareCircle\n                                PdfAnnotationType.Text -> annotation is PDAnnotationText\n                                PdfAnnotationType.TextMarkup -> annotation is PDAnnotationTextMarkup\n                                PdfAnnotationType.Widget -> annotation is PDAnnotationWidget\n                                PdfAnnotationType.Markup -> annotation is PDAnnotationMarkup\n                                PdfAnnotationType.Unknown -> annotation is PDAnnotationUnknown\n                            }\n                        }\n                    }\n                }\n            }\n\n            document.save(\n                filename = tempName(\n                    key = \"annotations_removed\",\n                    uri = uri\n                )\n            )\n        }\n    }\n\n    private suspend inline fun <T> catchPdf(\n        crossinline action: suspend AndroidPdfHelper.() -> T\n    ): T = withContext(defaultDispatcher) {\n        try {\n            helper.action()\n        } catch (k: InvalidPasswordException) {\n            throw SecurityException(k.message)\n        } catch (e: Throwable) {\n            e.makeLog(\"catchPdf\")\n            throw e\n        }\n    }\n\n    private fun Bitmap.whiteBg(): Bitmap = Trickle.drawColorBehind(\n        input = this,\n        color = Color.White.toArgb()\n    )\n\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/data/utils/Hocr.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.data.utils\n\ninternal data class HocrWord(\n    val left: Float,\n    val top: Float,\n    val right: Float,\n    val bottom: Float,\n    val text: String\n)\n\ninternal data class HocrPageBox(\n    val width: Float,\n    val height: Float\n)\n\ninternal data class HocrData(\n    val pageBox: HocrPageBox?,\n    val words: List<HocrWord>\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/data/utils/PdfContentStreamEditor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.data.utils\n\nimport android.graphics.Path\nimport android.graphics.PointF\nimport com.tom_roush.pdfbox.contentstream.PDFGraphicsStreamEngine\nimport com.tom_roush.pdfbox.contentstream.operator.Operator\nimport com.tom_roush.pdfbox.cos.COSBase\nimport com.tom_roush.pdfbox.cos.COSName\nimport com.tom_roush.pdfbox.pdfwriter.ContentStreamWriter\nimport com.tom_roush.pdfbox.pdmodel.PDDocument\nimport com.tom_roush.pdfbox.pdmodel.PDPage\nimport com.tom_roush.pdfbox.pdmodel.common.PDStream\nimport com.tom_roush.pdfbox.pdmodel.font.PDFont\nimport com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject\nimport com.tom_roush.pdfbox.pdmodel.graphics.image.PDImage\nimport com.tom_roush.pdfbox.util.Matrix\nimport com.tom_roush.pdfbox.util.Vector\nimport java.io.IOException\nimport java.io.OutputStream\n\n\ninternal open class PdfContentStreamEditor(val document: PDDocument, page: PDPage?) :\n    PDFGraphicsStreamEngine(page) {\n    /**\n     * \n     * \n     * This method retrieves the next operation before its registered\n     * listener is called. The default does nothing.\n     * \n     * \n     * \n     * Override this method to retrieve state information from before the\n     * operation execution.\n     * \n     */\n    protected fun nextOperation(operator: Operator?, operands: List<COSBase>) {\n    }\n\n    /**\n     * \n     * \n     * This method writes content stream operations to the target canvas. The default\n     * implementation writes them as they come, so it essentially generates identical\n     * copies of the original instructions [.processOperator]\n     * forwards to it.\n     * \n     * \n     * \n     * Override this method to achieve some fancy editing effect.\n     * \n     */\n    @Throws(IOException::class)\n    protected open fun write(\n        contentStreamWriter: ContentStreamWriter,\n        operator: Operator,\n        operands: List<COSBase>\n    ) {\n        contentStreamWriter.writeTokens(operands)\n        contentStreamWriter.writeToken(operator)\n    }\n\n    // stub implementation of PDFGraphicsStreamEngine abstract methods\n\n    override fun appendRectangle(\n        p0: PointF?,\n        p1: PointF?,\n        p2: PointF?,\n        p3: PointF?\n    ) {\n    }\n\n    @Throws(IOException::class)\n    override fun drawImage(pdImage: PDImage?) {\n    }\n\n    override fun clip(windingRule: Path.FillType?) {\n    }\n\n    @Throws(IOException::class)\n    override fun moveTo(x: Float, y: Float) {\n    }\n\n    @Throws(IOException::class)\n    override fun lineTo(x: Float, y: Float) {\n    }\n\n    @Throws(IOException::class)\n    override fun curveTo(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float) {\n    }\n\n    @Throws(IOException::class)\n    override fun getCurrentPoint(): PointF? {\n        return PointF()\n    }\n\n    @Throws(IOException::class)\n    override fun closePath() {\n    }\n\n    @Throws(IOException::class)\n    override fun endPath() {\n    }\n\n    @Throws(IOException::class)\n    override fun strokePath() {\n    }\n\n    override fun fillPath(windingRule: Path.FillType?) {\n\n    }\n\n    override fun fillAndStrokePath(windingRule: Path.FillType?) {\n\n    }\n\n    @Throws(IOException::class)\n    override fun shadingFill(shadingName: COSName?) {\n    }\n\n    // Actual editing methods\n    @Throws(IOException::class)\n    override fun processPage(page: PDPage) {\n        val stream = PDStream(document)\n        replacement = ContentStreamWriter(\n            stream.createOutputStream(COSName.FLATE_DECODE).also { replacementStream = it })\n        super.processPage(page)\n        replacementStream!!.close()\n        page.setContents(stream)\n        replacement = null\n        replacementStream = null\n    }\n\n    @Throws(IOException::class)\n    fun processFormXObject(formXObject: PDFormXObject, page: PDPage?) {\n        val stream = PDStream(document)\n        replacement = ContentStreamWriter(\n            stream.createOutputStream(COSName.FLATE_DECODE).also { replacementStream = it })\n        super.processChildStream(formXObject, page)\n        replacementStream!!.close()\n        try {\n            formXObject.cosObject.createOutputStream().use { outputStream ->\n                stream.createInputStream().copyTo(outputStream)\n            }\n        } finally {\n            replacement = null\n            replacementStream = null\n        }\n    }\n\n    // PDFStreamEngine overrides to allow editing\n    @Throws(IOException::class)\n    override fun showForm(form: PDFormXObject?) {\n        // DON'T descend into XObjects\n        // super.showForm(form);\n    }\n\n    @Throws(IOException::class)\n    protected override fun processOperator(operator: Operator, operands: List<COSBase>) {\n        if (inOperator) {\n            super.processOperator(operator, operands)\n        } else {\n            inOperator = true\n            nextOperation(operator, operands)\n            super.processOperator(operator, operands)\n            write(replacement!!, operator, operands)\n            inOperator = false\n        }\n    }\n\n    var replacementStream: OutputStream? = null\n    var replacement: ContentStreamWriter? = null\n    var inOperator: Boolean = false\n}\n\ninternal fun PDDocument.removeText(linesToRemove: Set<String>) {\n    for (page in pages) {\n        val editor = object : PdfContentStreamEditor(this, page) {\n            val recentChars = StringBuilder()\n            val TEXT_SHOWING_OPERATORS = listOf(\"Tj\", \"'\", \"\\\"\", \"TJ\")\n\n            @Suppress(\"DEPRECATION\")\n            @Deprecated(\"Deprecated in Java\")\n            override fun showGlyph(\n                textRenderingMatrix: Matrix,\n                font: PDFont,\n                code: Int,\n                unicode: String,\n                displacement: Vector\n            ) {\n                recentChars.append(unicode)\n                super.showGlyph(textRenderingMatrix, font, code, unicode, displacement)\n            }\n\n            override fun write(\n                contentStreamWriter: ContentStreamWriter,\n                operator: Operator,\n                operands: List<COSBase>\n            ) {\n                val recentText = recentChars.toString()\n                recentChars.setLength(0)\n                if (TEXT_SHOWING_OPERATORS.contains(operator.name) &&\n                    linesToRemove.any { recentText.contains(it, ignoreCase = true) }\n                ) {\n                    return\n                }\n                super.write(contentStreamWriter, operator, operands)\n            }\n        }\n        editor.processPage(page)\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/data/utils/PdfRenderer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.data.utils\n\nimport android.graphics.Bitmap\nimport android.os.Build\nimport android.os.ext.SdkExtensions\nimport androidx.annotation.ChecksSdkIntAtLeast\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.logger.makeLog\nimport com.tom_roush.pdfbox.pdmodel.PDDocument\nimport com.tom_roush.pdfbox.pdmodel.encryption.InvalidPasswordException\nimport com.tom_roush.pdfbox.rendering.PDFRenderer\nimport java.lang.AutoCloseable\nimport kotlin.math.roundToInt\n\nclass PdfRenderer(\n    val pDocument: PDDocument\n) : PDFRenderer(pDocument), AutoCloseable {\n    val pageCount: Int get() = pDocument.numberOfPages\n    val pageIndices: List<Int> get() = pDocument.pageIndices\n\n    fun openPage(index: Int): Page = pDocument.getPage(index).let { page ->\n        page.cropBox.run {\n            Page(\n                width = width.roundToInt(),\n                height = height.roundToInt()\n            )\n        }\n    }\n\n    fun safeRenderDpi(\n        pageIndex: Int,\n        dpi: Float\n    ): Bitmap = try {\n        System.gc()\n        if (openPage(pageIndex).run { width * height * 4 <= 4096 * 4096 * 4 }) {\n            renderImageWithDPI(pageIndex, dpi)\n        } else {\n            renderImage(pageIndex)\n        }\n    } catch (t1: Throwable) {\n        t1.makeLog(\"safeRenderDpi\")\n        System.gc()\n        try {\n            renderImage(pageIndex)\n        } catch (t2: Throwable) {\n            t2.makeLog(\"safeRenderDpi\")\n            System.gc()\n            renderImage(pageIndex, 0.5f)\n        }\n    } finally {\n        System.gc()\n    }\n\n    override fun close() = pDocument.close()\n\n    class Page(\n        val width: Int,\n        val height: Int\n    ) {\n        val size = IntegerSize(width, height)\n    }\n}\n\nfun PdfRenderer(\n    uri: String,\n    password: String? = null,\n    onFailure: (Throwable) -> Unit = {},\n    onPasswordRequest: (() -> Unit)? = null\n): PdfRenderer? = runCatching {\n    safeOpenPdf(\n        uri = uri,\n        password = password\n    ).let(::PdfRenderer)\n}.onFailure { throwable ->\n    when (throwable) {\n        is InvalidPasswordException -> onPasswordRequest?.invoke() ?: onFailure(throwable)\n        else -> onFailure(throwable)\n    }\n}.getOrNull()\n\n\n@ChecksSdkIntAtLeast(api = 13, extension = Build.VERSION_CODES.S)\nfun canUseNewPdf(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM\n        || Build.VERSION.SDK_INT >= Build.VERSION_CODES.R\n        && SdkExtensions.getExtensionVersion(Build.VERSION_CODES.S) >= 13"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/data/utils/PdfUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.data.utils\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriReadable\nimport com.t8rin.imagetoolbox.core.data.utils.outputStream\nimport com.t8rin.imagetoolbox.core.domain.model.RectModel\nimport com.t8rin.imagetoolbox.core.domain.saving.io.Writeable\nimport com.t8rin.imagetoolbox.core.domain.utils.applyUse\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfMetadata\nimport com.t8rin.logger.makeLog\nimport com.tom_roush.harmony.awt.AWTColor\nimport com.tom_roush.pdfbox.io.MemoryUsageSetting\nimport com.tom_roush.pdfbox.pdmodel.PDDocument\nimport com.tom_roush.pdfbox.pdmodel.PDDocumentInformation\nimport com.tom_roush.pdfbox.pdmodel.PDPage\nimport com.tom_roush.pdfbox.pdmodel.PDPageContentStream\nimport com.tom_roush.pdfbox.pdmodel.PDResources\nimport com.tom_roush.pdfbox.pdmodel.common.PDRectangle\nimport com.tom_roush.pdfbox.pdmodel.encryption.AccessPermission\nimport com.tom_roush.pdfbox.pdmodel.encryption.InvalidPasswordException\nimport com.tom_roush.pdfbox.pdmodel.encryption.StandardProtectionPolicy\nimport com.tom_roush.pdfbox.pdmodel.font.PDType0Font\nimport com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject\nimport com.tom_roush.pdfbox.pdmodel.graphics.image.JPEGFactory\nimport com.tom_roush.pdfbox.pdmodel.graphics.image.LosslessFactory\nimport com.tom_roush.pdfbox.pdmodel.graphics.image.PDImageXObject\nimport com.tom_roush.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState\nimport java.util.Calendar\nimport kotlin.math.roundToInt\n\ninternal fun PDDocument.save(\n    writeable: Writeable,\n    password: String? = null\n) {\n    if (password.isNullOrBlank()) {\n        isAllSecurityToBeRemoved = true\n    } else {\n        protect(\n            StandardProtectionPolicy(password, password, AccessPermission()).apply {\n                encryptionKeyLength = 128\n            }\n        )\n    }\n    save(writeable.outputStream())\n}\n\ninternal var PDDocument.metadata: PdfMetadata\n    get() = documentInformation.run {\n        PdfMetadata(\n            title = title,\n            author = author,\n            subject = subject,\n            keywords = keywords,\n            creator = creator,\n            producer = producer\n        )\n    }\n    set(value) {\n        documentInformation.apply {\n            title = value.title ?: title\n            author = value.author ?: author\n            subject = value.subject ?: subject\n            keywords = value.keywords ?: keywords\n            creator = value.creator ?: creator\n            producer = value.producer ?: producer\n        }\n    }\n\n@JvmName(\"setMetadataNullable\")\ninternal fun PDDocument.setMetadata(value: PdfMetadata?) {\n    if (value == null) {\n        documentInformation = PDDocumentInformation().apply {\n            creationDate = Calendar.getInstance()\n            modificationDate = Calendar.getInstance()\n        }\n    } else {\n        metadata = value\n    }\n}\n\ninternal val PDDocument.defaultFont\n    get() = PDType0Font.load(\n        this, appContext.resources.openRawResource(R.raw.roboto_bold)\n    )\n\ninternal fun PDDocument.getPageSafe(index: Int): PDPage = getPage(\n    index.coerceIn(\n        minimumValue = 0,\n        maximumValue = numberOfPages - 1\n    )\n)\n\ninternal val PDDocument.pageIndices: List<Int> get() = List(numberOfPages) { it }\n\ninternal fun PDPageContentStream.setAlpha(alpha: Float) {\n    val gs = PDExtendedGraphicsState().apply {\n        nonStrokingAlphaConstant = alpha\n    }\n\n    setGraphicsStateParameters(gs)\n}\n\ninternal fun PDPageContentStream.setColor(color: Color) {\n    if (color.alpha < 1f) {\n        setAlpha(color.alpha)\n    }\n    setNonStrokingColor(\n        AWTColor(\n            (color.red * 255).roundToInt(),\n            (color.green * 255).roundToInt(),\n            (color.blue * 255).roundToInt(),\n            (color.alpha * 255).roundToInt()\n        )\n    )\n}\n\ninternal fun PDPageContentStream.setColor(color: Int) = setColor(Color(color))\n\ninternal fun <T> PDDocument.createPage(\n    page: PDPage,\n    graphics: PDPageContentStream.() -> T\n) {\n    addPage(page)\n    writePage(\n        page = page,\n        overwrite = true,\n        graphics = graphics\n    )\n}\n\ninternal fun <T> PDDocument.writePage(\n    page: PDPage,\n    overwrite: Boolean = false,\n    graphics: PDPageContentStream.() -> T\n) = if (overwrite) {\n    PDPageContentStream(this, page)\n} else {\n    PDPageContentStream(\n        this,\n        page,\n        PDPageContentStream.AppendMode.APPEND,\n        true\n    )\n}.applyUse(graphics)\n\ninternal fun safeOpenPdf(\n    uri: String,\n    password: String?\n): PDDocument {\n    val stream = UriReadable(uri.toUri(), appContext).stream\n\n    return try {\n        PDDocument.load(\n            stream,\n            password.orEmpty()\n        )\n    } catch (t: Throwable) {\n        if (t is InvalidPasswordException) throw t\n\n        \"failed to open pdf from $uri - trying again\".makeLog(\"openPdf\")\n\n        PDDocument.load(\n            stream,\n            password.orEmpty(),\n            MemoryUsageSetting.setupTempFileOnly()\n        )\n    }\n}\n\ninternal fun Bitmap.asXObject(\n    document: PDDocument,\n    quality: Float\n): PDImageXObject = if (quality >= 1f) {\n    LosslessFactory.createFromImage(document, this)\n} else {\n    JPEGFactory.createFromImage(document, this, quality.coerceAtLeast(0f))\n}\n\ninternal fun PDDocument.getAllImages(): List<PDImageXObject> =\n    pages.flatMap { it.getResources().getImages() }\n\ninternal inline fun <T> createPdf(action: (PDDocument) -> T) = PDDocument().use(action)\n\ninternal fun List<Int>?.orAll(document: PDDocument) = orEmpty().ifEmpty { document.pageIndices }\n\ninternal inline fun PDDocument.transformImages(\n    quality: Float,\n    transform: (Bitmap) -> Bitmap\n) {\n    pages.forEach { page ->\n        page.resources.apply {\n            for (name in xObjectNames) {\n                val image = getXObject(name)\n                    .safeCast<PDImageXObject>()\n                    ?.image\n                    ?.let(transform)\n                    ?.asXObject(\n                        document = this@transformImages,\n                        quality = quality\n                    ) ?: continue\n\n                put(name, image)\n            }\n        }\n    }\n}\n\ninternal fun PDRectangle.crop(\n    rotation: Int,\n    rect: RectModel\n): PDRectangle {\n    val width = width\n    val height = height\n    val originX = lowerLeftX\n    val originY = lowerLeftY\n\n    return when (rotation) {\n        90 -> PDRectangle(\n            originX + rect.top * width,\n            originY + rect.left * height,\n            (rect.bottom - rect.top) * width,\n            (rect.right - rect.left) * height\n        )\n\n        180 -> PDRectangle(\n            originX + (1f - rect.right) * width,\n            originY + rect.top * height,\n            (rect.right - rect.left) * width,\n            (rect.bottom - rect.top) * height\n        )\n\n        270 -> PDRectangle(\n            originX + (1f - rect.bottom) * width,\n            originY + (1f - rect.right) * height,\n            (rect.bottom - rect.top) * width,\n            (rect.right - rect.left) * height\n        )\n\n        else -> PDRectangle(\n            originX + rect.left * width,\n            originY + (1f - rect.bottom) * height,\n            (rect.right - rect.left) * width,\n            (rect.bottom - rect.top) * height\n        )\n    }\n}\n\nprivate fun PDResources.getImages(): List<PDImageXObject> {\n    val images: MutableList<PDImageXObject> = mutableListOf()\n\n    for (xObjectName in xObjectNames) {\n        val xObject = getXObject(xObjectName)\n\n        if (xObject is PDFormXObject) {\n            images.addAll(xObject.getResources().getImages())\n        } else if (xObject is PDImageXObject) {\n            images.add(xObject)\n        }\n    }\n\n    return images\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/di/PdfToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.di\n\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.AndroidPdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface PdfToolsModule {\n\n    @Singleton\n    @Binds\n    fun providePdfManager(\n        manager: AndroidPdfManager\n    ): PdfManager\n\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/PdfHelper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCheckResult\nimport kotlinx.coroutines.flow.StateFlow\n\ninterface PdfHelper {\n\n    val savedSignatures: StateFlow<List<String>>\n\n    suspend fun saveSignature(signature: Any): Boolean\n\n    fun setMasterPassword(\n        password: String?\n    )\n\n    fun createTempName(\n        key: String,\n        uri: String? = null\n    ): String\n\n    fun clearPdfCache(uri: String?)\n\n    suspend fun checkPdf(\n        uri: String\n    ): PdfCheckResult\n\n    suspend fun getPdfPages(\n        uri: String\n    ): List<Int>\n\n    suspend fun getPdfPageSizes(\n        uri: String\n    ): List<IntegerSize>\n\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/PdfManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain\n\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.ExtractPagesAction\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCreationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCropParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfExtractPagesParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfMetadata\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfPageNumbersParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfRemoveAnnotationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfSignatureParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfWatermarkParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PrintPdfParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.SearchablePdfPage\nimport kotlinx.coroutines.flow.Flow\n\ninterface PdfManager : PdfHelper {\n\n    fun extractPages(\n        uri: String,\n        params: PdfExtractPagesParams\n    ): Flow<ExtractPagesAction>\n\n    suspend fun createPdf(\n        imageUris: List<String>,\n        params: PdfCreationParams\n    ): String\n\n    suspend fun createSearchablePdf(\n        pages: List<SearchablePdfPage>,\n        params: PdfCreationParams = PdfCreationParams(quality = 100)\n    ): String\n\n    suspend fun mergePdfs(\n        uris: List<String>\n    ): String\n\n    suspend fun splitPdf(\n        uri: String,\n        pages: List<Int>?\n    ): String\n\n    suspend fun removePdfPages(\n        uri: String,\n        pages: List<Int>\n    ): String\n\n    suspend fun rotatePdf(\n        uri: String,\n        rotations: List<Int>\n    ): String\n\n    suspend fun rearrangePdf(\n        uri: String,\n        newOrder: List<Int>\n    ): String\n\n    suspend fun addPageNumbers(\n        uri: String,\n        params: PdfPageNumbersParams\n    ): String\n\n    suspend fun addWatermark(\n        uri: String,\n        params: PdfWatermarkParams\n    ): String\n\n    suspend fun addSignature(\n        uri: String,\n        params: PdfSignatureParams\n    ): String\n\n    suspend fun protectPdf(\n        uri: String,\n        password: String\n    ): String\n\n    suspend fun unlockPdf(\n        uri: String,\n        password: String\n    ): String\n\n    suspend fun extractPagesFromPdf(\n        uri: String\n    ): List<String>\n\n    suspend fun compressPdf(\n        uri: String,\n        quality: Float\n    ): String\n\n    suspend fun convertToGrayscale(\n        uri: String\n    ): String\n\n    suspend fun repairPdf(\n        uri: String\n    ): String\n\n    suspend fun changePdfMetadata(\n        uri: String,\n        metadata: PdfMetadata?\n    ): String\n\n    suspend fun getPdfMetadata(\n        uri: String\n    ): PdfMetadata\n\n    suspend fun stripText(\n        uri: String\n    ): List<String>\n\n    suspend fun cropPdf(\n        uri: String,\n        params: PdfCropParams\n    ): String\n\n    suspend fun flattenPdf(\n        uri: String,\n        quality: Float\n    ): String\n\n    suspend fun detectPdfAutoRotations(\n        uri: String\n    ): List<Int>\n\n    suspend fun extractImagesFromPdf(\n        uri: String\n    ): String?\n\n    suspend fun convertToZip(\n        uri: String,\n        interval: Int\n    ): String\n\n    suspend fun printPdf(\n        uri: String,\n        params: PrintPdfParams\n    ): String\n\n    suspend fun removeAnnotations(\n        uri: String,\n        params: PdfRemoveAnnotationParams\n    ): String\n\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/ExtractPagesAction.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nsealed interface ExtractPagesAction {\n    data class PagesCount(val count: Int) : ExtractPagesAction\n    data class Progress(val index: Int, val image: Any) : ExtractPagesAction\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PageOrientation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nenum class PageOrientation {\n    ORIGINAL, VERTICAL, HORIZONTAL\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PageSize.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\ndata class PageSize(\n    val width: Int,\n    val height: Int,\n    val name: String?\n) {\n    companion object {\n        val Auto by lazy {\n            PageSize(\n                width = -100,\n                height = -100,\n                name = null\n            )\n        }\n\n        val entries: List<PageSize> by lazy {\n            listOf(\n                // ISO A Series\n                PageSize(2384, 3370, \"A0\"),\n                PageSize(1684, 2384, \"A1\"),\n                PageSize(1191, 1684, \"A2\"),\n                PageSize(842, 1191, \"A3\"),\n                PageSize(595, 842, \"A4\"),\n                PageSize(420, 595, \"A5\"),\n                PageSize(297, 420, \"A6\"),\n                PageSize(210, 297, \"A7\"),\n                PageSize(148, 210, \"A8\"),\n                PageSize(105, 148, \"A9\"),\n                PageSize(74, 105, \"A10\"),\n\n                // ISO B Series\n                PageSize(2835, 4008, \"B0\"),\n                PageSize(2004, 2835, \"B1\"),\n                PageSize(1417, 2004, \"B2\"),\n                PageSize(1001, 1417, \"B3\"),\n                PageSize(709, 1001, \"B4\"),\n                PageSize(499, 709, \"B5\"),\n                PageSize(354, 499, \"B6\"),\n                PageSize(249, 354, \"B7\"),\n                PageSize(176, 249, \"B8\"),\n                PageSize(125, 176, \"B9\"),\n                PageSize(88, 125, \"B10\"),\n\n                // ISO C Series (envelopes)\n                PageSize(2599, 3677, \"C0\"),\n                PageSize(1837, 2599, \"C1\"),\n                PageSize(1298, 1837, \"C2\"),\n                PageSize(918, 1298, \"C3\"),\n                PageSize(649, 918, \"C4\"),\n                PageSize(459, 649, \"C5\"),\n                PageSize(323, 459, \"C6\"),\n                PageSize(230, 323, \"C7\"),\n                PageSize(162, 230, \"C8\"),\n                PageSize(113, 162, \"C9\"),\n                PageSize(79, 113, \"C10\"),\n\n                // US/ANSI Series\n                PageSize(612, 792, \"Letter\"),           // 8.5 x 11 in\n                PageSize(612, 1008, \"Legal\"),            // 8.5 x 14 in\n                PageSize(792, 1224, \"Tabloid\"),          // 11 x 17 in\n                PageSize(612, 936, \"Statement\"),          // 5.5 x 8.5 in\n                PageSize(396, 612, \"Executive\"),          // 7.25 x 10.5 in\n\n                // ANSI Series\n                PageSize(612, 792, \"ANSI A\"),             // Letter\n                PageSize(792, 1224, \"ANSI B\"),            // Tabloid/Ledger\n                PageSize(1224, 1584, \"ANSI C\"),\n                PageSize(1584, 2448, \"ANSI D\"),\n                PageSize(2448, 3168, \"ANSI E\"),\n\n                // Architectural Series\n                PageSize(432, 576, \"Arch A\"),             // 9 x 12 in\n                PageSize(576, 864, \"Arch B\"),             // 12 x 18 in\n                PageSize(864, 1152, \"Arch C\"),            // 18 x 24 in\n                PageSize(1152, 1728, \"Arch D\"),           // 24 x 36 in\n                PageSize(1728, 2304, \"Arch E\"),           // 36 x 48 in\n                PageSize(2304, 3240, \"Arch E1\"),          // 30 x 42 in\n\n                // Other Common Sizes\n                PageSize(280, 416, \"Business Card\"),      // 2.91 x 4.33 in (ISO)\n                PageSize(255, 408, \"Business Card US\"),   // 2 x 3.5 in\n                PageSize(499, 709, \"A5+\"),\n                PageSize(595, 984, \"A4+\"),\n                PageSize(842, 1338, \"A3+\"),\n\n                // Photo Sizes\n                PageSize(300, 450, \"Photo 4x6\"),           // 4 x 6 in\n                PageSize(450, 600, \"Photo 5x7\"),           // 5 x 7 in\n                PageSize(600, 720, \"Photo 6x8\"),           // 6 x 8 in\n                PageSize(720, 960, \"Photo 8x10\"),          // 8 x 10 in\n                PageSize(900, 1200, \"Photo 10x12\"),        // 10 x 12 in\n                PageSize(1200, 1800, \"Photo 12x18\"),       // 12 x 18 in\n\n                // Other International\n                PageSize(700, 1000, \"F4\"),                 // 8.27 x 13 in\n                PageSize(827, 1169, \"Quarto\"),             // 8.46 x 10.83 in\n                PageSize(649, 918, \"C5 Envelope\"),\n                PageSize(461, 648, \"DL Envelope\"),         // 110 x 220 mm\n                PageSize(413, 610, \"Japanese Postcard\"),   // 100 x 148 mm\n                PageSize(630, 882, \"ISO B6\"),\n\n                // Square formats\n                PageSize(420, 420, \"Square 15cm\"),         // 15 x 15 cm\n                PageSize(595, 595, \"Square 21cm\"),         // 21 x 21 cm\n                PageSize(842, 842, \"Square 30cm\"),         // 30 x 30 cm\n\n                // Digital formats\n                PageSize(768, 1024, \"iPad\"),\n                PageSize(600, 800, \"E-reader\"),\n                PageSize(1080, 1920, \"HD Video\"),\n\n                // Posters\n                PageSize(1191, 1684, \"A2 Poster\"),\n                PageSize(842, 1191, \"A3 Poster\"),\n                PageSize(1684, 2384, \"A1 Poster\"),\n                PageSize(1224, 1584, \"ANSI C Poster\"),\n                PageSize(1584, 2448, \"ANSI D Poster\"),\n\n                // Index cards\n                PageSize(300, 500, \"Index Card 3x5\"),      // 3 x 5 in\n                PageSize(400, 600, \"Index Card 4x6\"),      // 4 x 6 in\n                PageSize(500, 800, \"Index Card 5x8\")       // 5 x 8 in\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfAnnotationType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nenum class PdfAnnotationType {\n    Link,\n    FileAttachment,\n    Line,\n    Popup,\n    Stamp,\n    SquareCircle,\n    Text,\n    TextMarkup,\n    Widget,\n    Markup,\n    Unknown;\n\n    companion object {\n        val setEntries by lazy {\n            entries.toSet()\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfCheckResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nsealed interface PdfCheckResult {\n    data class Failure(val throwable: Throwable) : PdfCheckResult\n\n    data object Open : PdfCheckResult\n\n    sealed interface Protected : PdfCheckResult {\n        data object NeedsPassword : Protected\n        data class Unlocked(val decryptedUri: String) : Protected\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfCreationParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\n\ndata class PdfCreationParams(\n    val scaleSmallImagesToLarge: Boolean = false,\n    val preset: Preset.Percentage = Preset.Original,\n    val quality: Int = 85\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfCropParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.RectModel\n\ndata class PdfCropParams(\n    val pages: List<Int>? = null,\n    val rect: RectModel = RectModel(\n        left = 0.1f,\n        right = 0.9f,\n        top = 0.1f,\n        bottom = 0.9f\n    )\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfExtractPagesParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\n\ndata class PdfExtractPagesParams(\n    val pages: List<Int>? = null,\n    val preset: Preset.Percentage = Preset.Original\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfMetadata.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\ndata class PdfMetadata(\n    val title: String? = null,\n    val author: String? = null,\n    val subject: String? = null,\n    val keywords: String? = null,\n    val creator: String? = null,\n    val producer: String? = null\n) {\n    companion object {\n        val Empty = PdfMetadata()\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfPageNumbersParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.Position\n\ndata class PdfPageNumbersParams(\n    val labelFormat: String = \"Page {n} of {total}\",\n    val position: Position = Position.BottomCenter,\n    val color: Int = -7829368\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfRemoveAnnotationParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\ndata class PdfRemoveAnnotationParams(\n    val pages: List<Int>? = null,\n    val types: Set<PdfAnnotationType> = setOf(PdfAnnotationType.Link)\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfSignatureParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\ndata class PdfSignatureParams(\n    val x: Float = 0.1f,\n    val y: Float = 0.1f,\n    val size: Float = 0.25f,\n    val pages: List<Int> = emptyList(),\n    val opacity: Float = 0.3f,\n    val signatureImage: Any = \"file:///android_asset/svg/emotions/aasparkles.svg\"\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PdfWatermarkParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\ndata class PdfWatermarkParams(\n    val color: Int = 0x000000,\n    val fontSize: Float = 50f,\n    val rotation: Float = 315f,\n    val opacity: Float = 0.3f,\n    val pages: List<Int> = emptyList(),\n    val text: String = \"Watermark\",\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/PrintPdfParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\ndata class PrintPdfParams(\n    val orientation: PageOrientation = PageOrientation.ORIGINAL,\n    val pageSize: PageSize = PageSize.Auto,\n    val pagesPerSheet: Int = 1,\n    val marginPercent: Float = 0f,\n    val quality: Float = 0.85f,\n) {\n    val pageSizeFinal = if (pageSize == PageSize.Auto) {\n        null\n    } else {\n        when (orientation) {\n            PageOrientation.ORIGINAL -> null\n            PageOrientation.VERTICAL -> pageSize\n            PageOrientation.HORIZONTAL -> pageSize.run { copy(width = height, height = width) }\n        }\n    }\n\n    val gridSize = pagesMapping.getOrDefault(pagesPerSheet, 1 to 1).let {\n        when (orientation) {\n            PageOrientation.ORIGINAL,\n            PageOrientation.VERTICAL -> it\n\n            PageOrientation.HORIZONTAL -> it.second to it.first\n        }\n    }\n\n    companion object {\n        val pagesMapping by lazy {\n            mapOf(\n                1 to (1 to 1),\n                2 to (2 to 1),\n                4 to (2 to 2),\n                6 to (3 to 2),\n                8 to (4 to 2),\n                9 to (3 to 3),\n                12 to (4 to 3),\n                16 to (4 to 4)\n            )\n        }\n\n        val pageRange by lazy {\n            pagesMapping.keys.sorted().run { first()..last() }\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/domain/model/SearchablePdfPage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.domain.model\n\ndata class SearchablePdfPage(\n    val imageUri: String,\n    val text: String,\n    val hocr: String\n)"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/common/BasePdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.essenty.lifecycle.doOnDestroy\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCheckResult\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.Job\n\nabstract class BasePdfToolComponent(\n    val onGoBack: () -> Unit,\n    val onNavigate: (Screen) -> Unit,\n    dispatchersHolder: DispatchersHolder,\n    componentContext: ComponentContext,\n    private val pdfManager: PdfManager,\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    protected val _showPasswordRequestDialog: MutableState<Boolean> = mutableStateOf(false)\n    val showPasswordRequestDialog by _showPasswordRequestDialog\n\n    protected var isRtl = false\n\n    open val extraDataType: ExtraDataType? = ExtraDataType.Pdf\n    open val mimeType: MimeType.Single = MimeType.Pdf\n\n    init {\n        doOnDestroy {\n            pdfManager.setMasterPassword(null)\n        }\n    }\n\n    protected var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    open fun setPassword(password: String) {\n        _showPasswordRequestDialog.update { false }\n        pdfManager.setMasterPassword(password)\n    }\n\n    fun hidePasswordRequestDialog() {\n        _showPasswordRequestDialog.update { false }\n    }\n\n    fun updateIsRtl(isRtl: Boolean) {\n        this.isRtl = isRtl\n    }\n\n    fun checkPdf(\n        uri: Uri?,\n        onDecrypted: (Uri) -> Unit,\n        onSuccess: (Uri) -> Unit = {}\n    ) {\n        if (uri == null) return\n\n        componentScope.launch {\n            when (val result = pdfManager.checkPdf(uri.toString())) {\n                is PdfCheckResult.Open -> onSuccess(uri)\n\n                is PdfCheckResult.Protected.NeedsPassword -> _showPasswordRequestDialog.update { true }\n\n                is PdfCheckResult.Protected.Unlocked -> {\n                    pdfManager.setMasterPassword(null)\n                    onDecrypted(result.decryptedUri.toUri())\n                    onSuccess(result.decryptedUri.toUri())\n                }\n\n                is PdfCheckResult.Failure -> result.throwable.makeLog(\"checkPdf\")\n            }\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    open fun createTargetFilename(): String = getKey().let {\n        pdfManager.createTempName(\n            key = it?.first.orEmpty(),\n            uri = it?.second?.toString()\n        )\n    }\n\n    protected open fun getKey(): Pair<String, Uri?>? = null\n\n    abstract fun saveTo(uri: Uri)\n\n    abstract fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    )\n\n    abstract fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    )\n\n    protected fun doSaving(\n        action: suspend KeepAliveService.() -> SaveResult\n    ) {\n        savingJob = trackProgress {\n            runSuspendCatching {\n                _isSaving.value = true\n                parseFileSaveResult(action())\n            }.onFailure {\n                if (it is SecurityException) {\n                    _showPasswordRequestDialog.update { true }\n                } else {\n                    parseFileSaveResult(SaveResult.Error.Exception(it))\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    protected fun <T> doSharing(\n        action: suspend KeepAliveService.() -> T,\n        onSuccess: (T) -> Unit = {},\n        onFailure: (Throwable) -> Unit\n    ) {\n        savingJob = trackProgress {\n            runSuspendCatching {\n                _isSaving.value = true\n                onSuccess(action())\n            }.onFailure {\n                if (it is SecurityException) {\n                    _showPasswordRequestDialog.update { true }\n                } else {\n                    onFailure(it)\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/common/BasePdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileOpen\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Pdf\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ResultLauncher\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitBackHandler\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.PasswordRequestDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.FileNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\n\n@Composable\ninternal fun BasePdfToolContent(\n    component: BasePdfToolComponent,\n    contentPicker: ResultLauncher,\n    isPickedAlready: Boolean,\n    canShowScreenData: Boolean,\n    title: String,\n    actions: @Composable RowScope.() -> Unit = {},\n    topAppBarPersistentActions: @Composable RowScope.() -> Unit = {},\n    imagePreview: @Composable () -> Unit = {},\n    placeImagePreview: Boolean = false,\n    showImagePreviewAsStickyHeader: Boolean = false,\n    controls: (@Composable ColumnScope.(LazyListState) -> Unit)?,\n    canSave: Boolean = true,\n    canShare: Boolean = canSave,\n    onFilledPassword: () -> Unit = {},\n    forceImagePreviewToMax: Boolean = false,\n    placeControlsSeparately: Boolean = false,\n    addHorizontalCutoutPaddingIfNoPreview: Boolean = placeImagePreview && showImagePreviewAsStickyHeader,\n    secondaryButtonIcon: ImageVector = Icons.Rounded.FileOpen,\n    secondaryButtonText: String = stringResource(R.string.pick_file),\n    noDataText: String = stringResource(R.string.pick_file_to_start),\n    onPrimaryButtonClick: (() -> Unit)? = null,\n    onPrimaryButtonLongClick: (() -> Unit)? = null,\n    drawBottomShadow: Boolean = true,\n    shareDialogTitle: String = \"PDF\",\n    shareDialogIcon: ImageVector = Icons.Outlined.Pdf\n) {\n    val saveLauncher = rememberFileCreator(\n        mimeType = component.mimeType,\n        onSuccess = component::saveTo\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    AutoFilePicker(\n        onAutoPick = contentPicker::launch,\n        isPickedAlready = isPickedAlready\n    )\n\n    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n\n    LaunchedEffect(component) {\n        snapshotFlow { isRtl }\n            .collect { component.updateIsRtl(it) }\n    }\n\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        placeImagePreview = placeImagePreview,\n        addHorizontalCutoutPaddingIfNoPreview = addHorizontalCutoutPaddingIfNoPreview,\n        showImagePreviewAsStickyHeader = showImagePreviewAsStickyHeader,\n        title = {\n            TopAppBarTitle(\n                title = title,\n                input = null,\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        forceImagePreviewToMax = forceImagePreviewToMax,\n        placeControlsSeparately = placeControlsSeparately,\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n\n            ShareButton(\n                enabled = canShare,\n                onShare = {\n                    component.performSharing(\n                        onSuccess = AppToastHost::showConfetti,\n                        onFailure = AppToastHost::showFailureToast\n                    )\n                },\n                onEdit = {\n                    component.prepareForSharing(\n                        onSuccess = {\n                            editSheetData = it\n                        },\n                        onFailure = AppToastHost::showFailureToast\n                    )\n                },\n                dialogTitle = shareDialogTitle,\n                dialogIcon = shareDialogIcon\n            )\n\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                extraDataType = component.extraDataType,\n                onNavigate = component.onNavigate\n            )\n\n            actions()\n        },\n        topAppBarPersistentActions = {\n            if (!canShowScreenData) {\n                TopAppBarEmoji()\n            } else {\n                topAppBarPersistentActions()\n            }\n        },\n        imagePreview = imagePreview,\n        controls = controls?.let {\n            {\n                Column(\n                    modifier = if (!placeImagePreview && !isPortrait) {\n                        Modifier.windowInsetsPadding(\n                            WindowInsets.displayCutout.only(WindowInsetsSides.Start)\n                        )\n                    } else {\n                        Modifier\n                    },\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    controls(this, it)\n                }\n            }\n        },\n        buttons = { actions ->\n            BottomButtonsBlock(\n                isNoData = !canShowScreenData,\n                isPrimaryButtonVisible = canSave,\n                secondaryButtonIcon = secondaryButtonIcon,\n                secondaryButtonText = secondaryButtonText,\n                onSecondaryButtonClick = contentPicker::launch,\n                onPrimaryButtonClick = onPrimaryButtonClick ?: {\n                    saveLauncher.make(component.createTargetFilename())\n                },\n                onPrimaryButtonLongClick = onPrimaryButtonLongClick,\n                actions = {\n                    if (isPortrait) actions()\n                },\n                enableHorizontalStroke = drawBottomShadow\n            )\n        },\n        noDataControls = {\n            FileNotPickedWidget(\n                text = noDataText,\n                onPickFile = contentPicker::launch\n            )\n        },\n        portraitTopPadding = 20.dp,\n        canShowScreenData = canShowScreenData\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitBackHandler(\n        enabled = component.haveChanges,\n        onBack = onBack\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    PasswordRequestDialog(\n        isVisible = component.showPasswordRequestDialog,\n        onDismiss = {\n            component.hidePasswordRequestDialog()\n            component.onGoBack()\n        },\n        onFillPassword = {\n            component.setPassword(it)\n            onFilledPassword()\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/common/PageSwitcher.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.VisibilityOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\n\n@Composable\ninternal fun PageSwitcher(\n    pageCount: Int,\n    activePages: List<Int>? = null,\n    modifier: Modifier = Modifier,\n    content: @Composable (page: Int) -> Unit\n) {\n    var page by rememberSaveable {\n        mutableIntStateOf(0)\n    }\n    val indices = remember(pageCount) {\n        List(pageCount) { it }\n    }\n\n    Column(\n        modifier = modifier\n            .detectSwipes(\n                key = indices,\n                onSwipeLeft = {\n                    page = indices.rightFrom(page)\n                },\n                onSwipeRight = {\n                    page = indices.leftFrom(page)\n                }\n            ),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        val targetPage = if (indices.isEmpty()) 0 else indices[page]\n\n        Box(modifier = Modifier.weight(1f, false)) {\n            content(targetPage)\n        }\n\n        if (pageCount > 1) {\n            val isActive = activePages == null || targetPage in activePages\n\n            Spacer(Modifier.height(6.dp))\n            Row(\n                horizontalArrangement = Arrangement.Center,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                EnhancedBadge(\n                    contentColor = takeColorFromScheme {\n                        if (isActive) {\n                            onSecondary\n                        } else {\n                            outline\n                        }\n                    },\n                    containerColor = takeColorFromScheme {\n                        if (isActive) {\n                            secondary\n                        } else {\n                            outlineVariant\n                        }\n                    }\n                ) {\n                    Text(\"${targetPage + 1} / $pageCount\")\n                }\n\n                AnimatedVisibility(\n                    visible = !isActive\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.VisibilityOff,\n                        contentDescription = null,\n                        tint = MaterialTheme.colorScheme.outline,\n                        modifier = Modifier\n                            .padding(start = 4.dp)\n                            .size(16.dp)\n                            .background(\n                                color = MaterialTheme.colorScheme.outlineVariant,\n                                shape = CircleShape\n                            )\n                            .padding(2.dp)\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/common/PdfPreviewItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberHumanFileSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\n\n@Composable\ninternal fun PdfPreviewItem(\n    uri: Uri,\n    onRemove: () -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Row(\n        verticalAlignment = Alignment.CenterVertically,\n        modifier = modifier\n            .fillMaxWidth()\n            .container(\n                resultPadding = 8.dp\n            )\n    ) {\n        Picture(\n            model = uri,\n            modifier = Modifier\n                .height(80.dp)\n                .defaultMinSize(minWidth = 60.dp)\n                .widthIn(max = 120.dp)\n                .container(\n                    shape = ShapeDefaults.small,\n                    color = Color.Transparent,\n                    resultPadding = 0.dp\n                ),\n            shape = RectangleShape,\n            contentScale = ContentScale.Fit\n        )\n        Spacer(Modifier.width(16.dp))\n        Column(\n            modifier = Modifier.weight(1f)\n        ) {\n            Text(\n                text = rememberFilename(uri) ?: uri.toString(),\n                style = PreferenceItemDefaults.TitleFontStyle\n            )\n            Spacer(Modifier.height(4.dp))\n            val size = rememberHumanFileSize(uri)\n            val pages by rememberPdfPages(uri)\n\n            Text(\n                text = \"$size • $pages ${stringResource(R.string.pages_short)}\",\n                fontSize = 12.sp,\n                textAlign = TextAlign.Start,\n                fontWeight = FontWeight.Normal,\n                lineHeight = 14.sp,\n                color = LocalContentColor.current.copy(alpha = 0.5f)\n            )\n        }\n        Spacer(Modifier.width(16.dp))\n        EnhancedIconButton(\n            onClick = onRemove,\n            containerColor = MaterialTheme.colorScheme.errorContainer.copy(\n                0.4f\n            ),\n            contentColor = MaterialTheme.colorScheme.onErrorContainer,\n            modifier = Modifier.padding(top = 4.dp)\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.Delete,\n                contentDescription = null\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/compress/CompressPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.screenLogic.CompressPdfToolComponent\nimport kotlin.math.roundToInt\n\n@Composable\nfun CompressPdfToolContent(\n    component: CompressPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.compress_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            QualitySelector(\n                imageFormat = ImageFormat.Jpg,\n                quality = Quality.Base((component.quality * 100).roundToInt()),\n                onQualityChange = {\n                    component.updateQuality(it.qualityValue / 100f)\n                },\n                autoCoerce = false\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/compress/screenLogic/CompressPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass CompressPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _quality: MutableState<Float> = mutableFloatStateOf(0.8f)\n    val quality by _quality\n\n    override fun getKey(): Pair<String, Uri?> = \"compressed\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateQuality(quality: Float) {\n        registerChanges()\n        _quality.update { quality }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.compressPdf(\n                uri = _uri.value.toString(),\n                quality = quality\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.compressPdf(\n                            uri = _uri.value.toString(),\n                            quality = quality\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): CompressPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/crop/CropPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.BorderHorizontal\nimport androidx.compose.material.icons.rounded.BorderVertical\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.utils.roundTo\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.page.PageSelectionItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedRangeSliderItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.components.CropPreview\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.screenLogic.CropPdfToolComponent\n\n@Composable\nfun CropPdfToolContent(\n    component: CropPdfToolComponent\n) {\n    val pageCount by rememberPdfPages(component.uri)\n    val params = component.params\n\n    LaunchedEffect(pageCount, params.pages) {\n        if (params.pages == null && pageCount > 0) {\n            component.updateParams(\n                params.copy(\n                    pages = List(pageCount) { it }\n                )\n            )\n        }\n    }\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canSave = !params.rect.isEmpty,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.crop_pdf),\n        imagePreview = {\n            CropPreview(\n                uri = component.uri,\n                params = params,\n                pageCount = pageCount\n            )\n        },\n        placeImagePreview = true,\n        showImagePreviewAsStickyHeader = true,\n        controls = {\n            PageSelectionItem(\n                value = params.pages,\n                onValueChange = {\n                    component.updateParams(params.copy(pages = it))\n                },\n                pageCount = pageCount\n            )\n\n            Spacer(Modifier.height(16.dp))\n\n            EnhancedRangeSliderItem(\n                value = params.rect.let { it.left..it.right },\n                valueRange = 0f..1f,\n                icon = Icons.Rounded.BorderVertical,\n                title = stringResource(R.string.vertical_pivot_line),\n                internalStateTransformation = {\n                    it.start.roundTo(3)..it.endInclusive.roundTo(3)\n                },\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            rect = params.rect.copy(\n                                left = it.start,\n                                right = it.endInclusive\n                            )\n                        )\n                    )\n                }\n            )\n            Spacer(Modifier.height(8.dp))\n            EnhancedRangeSliderItem(\n                value = params.rect.let { it.top..it.bottom },\n                valueRange = 0f..1f,\n                icon = Icons.Rounded.BorderHorizontal,\n                title = stringResource(R.string.horizontal_pivot_line),\n                internalStateTransformation = {\n                    it.start.roundTo(3)..it.endInclusive.roundTo(3)\n                },\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            rect = params.rect.copy(\n                                top = it.start,\n                                bottom = it.endInclusive\n                            )\n                        )\n                    )\n                }\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/crop/components/CropPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.CompositingStrategy\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.domain.model.RectModel\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.Black\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberAnimatedBorder\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCropParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PageSwitcher\n\n@Composable\ninternal fun CropPreview(\n    uri: Uri?,\n    params: PdfCropParams,\n    pageCount: Int\n) {\n    PageSwitcher(\n        activePages = params.pages,\n        pageCount = pageCount\n    ) { page ->\n        Box(\n            modifier = Modifier\n                .container()\n                .padding(4.dp)\n                .animateContentSizeNoClip(\n                    alignment = Alignment.Center\n                ),\n            contentAlignment = Alignment.Center\n        ) {\n            var aspectRatio by rememberSaveable {\n                mutableFloatStateOf(1f)\n            }\n\n            Box(\n                modifier = Modifier\n                    .aspectRatio(aspectRatio)\n                    .clip(MaterialTheme.shapes.small)\n            ) {\n                Picture(\n                    model = remember(uri, page) {\n                        PdfImageRequest(\n                            data = uri,\n                            pdfPage = page\n                        )\n                    },\n                    contentScale = ContentScale.FillBounds,\n                    modifier = Modifier.matchParentSize(),\n                    onSuccess = {\n                        aspectRatio = it.result.image.safeAspectRatio\n                    },\n                    shape = RectangleShape\n                )\n\n                if (params.pages == null || page in params.pages) {\n                    CropFrameBorder(\n                        modifier = Modifier.matchParentSize(),\n                        cropRect = remember(params.rect) {\n                            Rect(\n                                left = params.rect.left,\n                                top = params.rect.top,\n                                right = params.rect.right,\n                                bottom = params.rect.bottom\n                            )\n                        }\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun CropFrameBorder(\n    modifier: Modifier = Modifier,\n    cropRect: Rect\n) {\n    val isNightMode = LocalSettingsState.current.isNightMode\n    val black = Black\n    val colorScheme = MaterialTheme.colorScheme\n    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n\n    val cropRect = remember(cropRect, isRtl) {\n        if (isRtl) {\n            cropRect.copy(\n                left = 1f - cropRect.left,\n                right = 1f - cropRect.right\n            )\n        } else {\n            cropRect\n        }\n    }\n\n    val pathEffect = rememberAnimatedBorder()\n\n    Canvas(\n        modifier = modifier.graphicsLayer {\n            compositingStrategy = CompositingStrategy.Offscreen\n        }\n    ) {\n        val canvasWidth = size.width\n        val canvasHeight = size.height\n\n        drawRect(\n            color = black.copy(alpha = if (isNightMode) 0.5f else 0.3f),\n            size = size\n        )\n\n        val topLeft = Offset(\n            x = cropRect.left * canvasWidth,\n            y = cropRect.top * canvasHeight\n        )\n        val size = Size(\n            width = (cropRect.right - cropRect.left) * canvasWidth,\n            height = (cropRect.bottom - cropRect.top) * canvasHeight\n        )\n\n        drawRect(\n            color = Color.Transparent,\n            blendMode = BlendMode.Clear,\n            topLeft = topLeft,\n            size = size\n        )\n\n        drawRect(\n            color = colorScheme.primary,\n            style = Stroke(\n                width = 1.5.dp.toPx()\n            ),\n            topLeft = topLeft,\n            size = size\n        )\n\n        drawRect(\n            color = colorScheme.primaryContainer,\n            style = Stroke(\n                width = 1.5.dp.toPx(),\n                pathEffect = pathEffect\n            ),\n            topLeft = topLeft,\n            size = size\n        )\n    }\n}\n\n@EnPreview\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    LocalLayoutDirection.ProvidesValue(LayoutDirection.Ltr) {\n        CropPreview(\n            uri = \"111\".toUri(),\n            pageCount = 100,\n            params = PdfCropParams(\n                rect = RectModel(\n                    left = 0.4f,\n                    top = 0.4f,\n                    right = 0.9f,\n                    bottom = 0.9f\n                ),\n                pages = null\n            ),\n        )\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/crop/screenLogic/CropPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCropParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.distinctUntilChanged\n\nclass CropPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _params: MutableState<PdfCropParams> = mutableStateOf(PdfCropParams())\n    val params by _params\n\n    override fun getKey(): Pair<String, Uri?> = \"cropped\" to uri\n\n    init {\n        componentScope.launch {\n            snapshotFlow { uri }\n                .distinctUntilChanged()\n                .collect {\n                    _params.update { it.copy(pages = null) }\n                }\n        }\n    }\n\n    private val adjustedParams: PdfCropParams\n        get() = params.copy(\n            rect = if (isRtl) {\n                params.rect.copy(\n                    left = 1f - params.rect.left,\n                    right = 1f - params.rect.right\n                )\n            } else {\n                params.rect\n            }\n        )\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateParams(params: PdfCropParams) {\n        _params.update { params }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.cropPdf(\n                uri = _uri.value.toString(),\n                params = adjustedParams\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.cropPdf(\n                            uri = _uri.value.toString(),\n                            params = adjustedParams\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): CropPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/extract_images/ExtractImagesPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.screenLogic.ExtractImagesPdfToolComponent\n\n@Composable\nfun ExtractImagesPdfToolContent(\n    component: ExtractImagesPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.extract_images),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            InfoContainer(\n                text = stringResource(R.string.extract_images_info)\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/extract_images/screenLogic/ExtractImagesPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass ExtractImagesPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val fileController: FileController,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    override val extraDataType: ExtraDataType = ExtraDataType.File\n    override val mimeType: MimeType.Single = MimeType.Zip\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    override fun createTargetFilename(): String =\n        \"${uri?.filename()?.substringBeforeLast('.') ?: timestamp()}_extracted.zip\"\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.extractImagesFromPdf(\n                uri = _uri.value.toString()\n            )\n                ?: return@doSaving SaveResult.Error.Exception(Throwable(getString(R.string.pdf_no_embedded)))\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                val processed = pdfManager.extractImagesFromPdf(\n                    uri = _uri.value.toString()\n                ) ?: return@doSharing onFailure(Throwable(getString(R.string.pdf_no_embedded)))\n\n                onSuccess(\n                    listOf(\n                        processed.toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ExtractImagesPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/extract_pages/ExtractPagesPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Image\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.page.PageSelectionItem\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PresetSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagesPreviewWithSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.screenLogic.ExtractPagesPdfToolComponent\n\n@Composable\nfun ExtractPagesPdfToolContent(\n    component: ExtractPagesPdfToolComponent\n) {\n    val pagesCount by rememberPdfPages(component.uri)\n    val params = component.params\n    val selectedPagesSize = params.pages?.size ?: 0\n    val isPortrait by isPortraitOrientationAsState()\n\n    var trigger by remember {\n        mutableIntStateOf(0)\n    }\n\n    val savePdfToImages: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.save(\n            oneTimeSaveLocationUri = it\n        )\n    }\n    var showFolderSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.pdf_to_images),\n        topAppBarPersistentActions = {\n            AnimatedVisibility(\n                visible = selectedPagesSize != pagesCount,\n                enter = fadeIn() + scaleIn() + expandHorizontally(),\n                exit = fadeOut() + scaleOut() + shrinkHorizontally()\n            ) {\n                EnhancedIconButton(\n                    onClick = {\n                        component.updatePages(\n                            List(pagesCount) { it }\n                        )\n                        trigger++\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.SelectAll,\n                        contentDescription = \"Select All\"\n                    )\n                }\n            }\n            AnimatedVisibility(\n                modifier = Modifier\n                    .padding(8.dp)\n                    .container(\n                        shape = ShapeDefaults.circle,\n                        color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                        resultPadding = 0.dp\n                    ),\n                visible = selectedPagesSize != 0\n            ) {\n                Row(\n                    modifier = Modifier.padding(start = 12.dp),\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.Center\n                ) {\n                    selectedPagesSize.takeIf { it != 0 }?.let {\n                        Spacer(Modifier.width(8.dp))\n                        Text(\n                            text = selectedPagesSize.toString(),\n                            fontSize = 20.sp,\n                            fontWeight = FontWeight.Medium\n                        )\n                    }\n                    EnhancedIconButton(\n                        onClick = {\n                            component.updatePages(emptyList())\n                            trigger++\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Close,\n                            contentDescription = stringResource(R.string.close)\n                        )\n                    }\n                }\n            }\n        },\n        canSave = !params.pages.isNullOrEmpty(),\n        imagePreview = {\n            key(trigger, pagesCount, component.uri) {\n                ImagesPreviewWithSelection(\n                    imageUris = remember(pagesCount, component.uri) {\n                        List(pagesCount) {\n                            PdfImageRequest(\n                                data = component.uri,\n                                pdfPage = it\n                            )\n                        }\n                    },\n                    imageFrames = remember(params.pages) {\n                        ImageFrames.ManualSelection(\n                            params.pages.orEmpty().map { it + 1 }\n                        )\n                    },\n                    onFrameSelectionChange = { frames ->\n                        component.updatePages(\n                            frames.getFramePositions(pagesCount).map { it - 1 }\n                        )\n                    },\n                    isPortrait = isPortrait,\n                    isLoadingImages = false\n                )\n            }\n        },\n        placeImagePreview = true,\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            PageSelectionItem(\n                value = params.pages,\n                onValueChange = {\n                    component.updatePages(it)\n                    trigger++\n                },\n                pageCount = pagesCount\n            )\n\n            Spacer(Modifier.height(8.dp))\n            PresetSelector(\n                value = params.preset,\n                includeTelegramOption = false,\n                onValueChange = {\n                    if (it is Preset.Percentage) {\n                        component.selectPreset(it)\n                    }\n                }\n            )\n            if (component.imageInfo.imageFormat.canChangeCompressionValue) {\n                Spacer(Modifier.height(8.dp))\n            }\n            QualitySelector(\n                imageFormat = component.imageInfo.imageFormat,\n                quality = component.imageInfo.quality,\n                onQualityChange = component::setQuality\n            )\n            Spacer(Modifier.height(8.dp))\n            ImageFormatSelector(\n                value = component.imageInfo.imageFormat,\n                onValueChange = component::updateImageFormat,\n                quality = component.imageInfo.quality,\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        },\n        onPrimaryButtonClick = { savePdfToImages(null) },\n        onPrimaryButtonLongClick = { showFolderSelectionDialog = true },\n        shareDialogTitle = stringResource(R.string.image),\n        shareDialogIcon = Icons.Outlined.Image\n    )\n\n    OneTimeSaveLocationSelectionDialog(\n        visible = showFolderSelectionDialog,\n        onDismiss = { showFolderSelectionDialog = false },\n        onSaveRequest = savePdfToImages\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/extract_pages/screenLogic/ExtractPagesPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.ExtractPagesAction\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfExtractPagesParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.catch\nimport kotlinx.coroutines.flow.distinctUntilChanged\nimport kotlinx.coroutines.flow.onCompletion\n\nclass ExtractPagesPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    override val extraDataType: ExtraDataType? = null\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _params: MutableState<PdfExtractPagesParams> =\n        mutableStateOf(PdfExtractPagesParams())\n    val params by _params\n\n    private val _imageInfo = mutableStateOf(ImageInfo())\n    val imageInfo by _imageInfo\n\n    init {\n        componentScope.launch {\n            snapshotFlow { uri }\n                .distinctUntilChanged()\n                .collect {\n                    _params.update { it.copy(pages = null) }\n                }\n        }\n    }\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updatePages(pages: List<Int>) {\n        registerChanges()\n        _params.update {\n            it.copy(\n                pages = pages\n            )\n        }\n    }\n\n    fun selectPreset(preset: Preset.Percentage) {\n        preset.value()?.takeIf { it <= 100f }?.let { quality ->\n            _imageInfo.update {\n                it.copy(\n                    quality = when (val q = it.quality) {\n                        is Quality.Base -> q.copy(qualityValue = quality)\n                        is Quality.Jxl -> q.copy(qualityValue = quality)\n                        else -> q\n                    }\n                )\n            }\n        }\n        _params.update {\n            it.copy(\n                preset = preset\n            )\n        }\n        registerChanges()\n    }\n\n    fun updateImageFormat(imageFormat: ImageFormat) {\n        _imageInfo.update {\n            it.copy(imageFormat = imageFormat)\n        }\n        registerChanges()\n    }\n\n    fun setQuality(quality: Quality) {\n        _imageInfo.update {\n            it.copy(quality = quality)\n        }\n        registerChanges()\n    }\n\n    fun save(\n        oneTimeSaveLocationUri: String?\n    ) {\n        doSharing(\n            action = {\n                extractPages(\n                    onPage = { bitmap, imageInfo ->\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                metadata = null,\n                                originalUri = uri?.toString().orEmpty(),\n                                sequenceNumber = null,\n                                data = imageCompressor.compressAndTransform(\n                                    image = bitmap,\n                                    imageInfo = imageInfo\n                                )\n                            ),\n                            keepOriginalMetadata = false,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    },\n                    onSuccess = {\n                        parseSaveResults(it.onSuccess(::registerSave))\n                    },\n                    onFailure = {\n                        parseSaveResults(listOf(SaveResult.Error.Exception(it)))\n                    }\n                )\n            },\n            onFailure = {\n                parseSaveResults(listOf(SaveResult.Error.Exception(it)))\n            }\n        )\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) = Unit\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                extractPages(\n                    onPage = { bitmap, imageInfo ->\n                        shareProvider.cacheImage(\n                            imageInfo = imageInfo,\n                            image = bitmap\n                        )?.toUri()\n                    },\n                    onSuccess = onSuccess,\n                    onFailure = onFailure\n                )\n            },\n            onFailure = onFailure\n        )\n    }\n\n    private suspend fun <T : Any> KeepAliveService.extractPages(\n        onPage: suspend (Bitmap, ImageInfo) -> T?,\n        onSuccess: suspend (List<T>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        var done = 0\n        var left = 1\n\n        val results = mutableListOf<T>()\n\n        pdfManager.extractPages(\n            uri = uri.toString(),\n            params = params\n        ).onCompletion {\n            onSuccess(results)\n            registerSave()\n        }.catch {\n            onFailure(it)\n        }.collect { action ->\n            when (action) {\n                is ExtractPagesAction.PagesCount -> left = action.count\n\n                is ExtractPagesAction.Progress -> {\n                    val bitmap = imageGetter.getImage(action.image) ?: return@collect\n                    val imageInfo = imageTransformer.applyPresetBy(\n                        image = bitmap,\n                        preset = params.preset,\n                        currentInfo = imageInfo\n                    ).copy(\n                        originalUri = uri?.toString()\n                    )\n\n                    onPage(bitmap, imageInfo)?.let(results::add)\n\n                    done += 1\n                    updateProgress(\n                        done = done,\n                        total = left\n                    )\n                }\n            }\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ExtractPagesPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/flatten/FlattenPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.screenLogic.FlattenPdfToolComponent\nimport kotlin.math.roundToInt\n\n@Composable\nfun FlattenPdfToolContent(\n    component: FlattenPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.flatten_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            QualitySelector(\n                imageFormat = ImageFormat.Jpg,\n                quality = Quality.Base((component.quality * 100).roundToInt()),\n                onQualityChange = {\n                    component.updateQuality(it.qualityValue / 100f)\n                },\n                autoCoerce = false\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/flatten/screenLogic/FlattenPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass FlattenPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _quality: MutableState<Float> = mutableFloatStateOf(0.85f)\n    val quality by _quality\n\n    override fun getKey(): Pair<String, Uri?> = \"flattened\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateQuality(quality: Float) {\n        registerChanges()\n        _quality.update { quality }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.flattenPdf(\n                uri = _uri.value.toString(),\n                quality = quality\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.flattenPdf(\n                            uri = _uri.value.toString(),\n                            quality = quality\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): FlattenPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/grayscale/GrayscalePdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.screenLogic.GrayscalePdfToolComponent\n\n@Composable\nfun GrayscalePdfToolContent(\n    component: GrayscalePdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.grayscale),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            InfoContainer(\n                text = stringResource(R.string.grayscale_info)\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/grayscale/screenLogic/GrayscalePdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass GrayscalePdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    override fun getKey(): Pair<String, Uri?> = \"grayscale\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.convertToGrayscale(\n                uri = _uri.value.toString()\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.convertToGrayscale(\n                            uri = _uri.value.toString()\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): GrayscalePdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/images_to_pdf/ImagesToPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageReorderCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ScaleSmallImagesToLargeToggle\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PresetSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.screenLogic.ImagesToPdfToolComponent\n\n@Composable\nfun ImagesToPdfToolContent(\n    component: ImagesToPdfToolComponent\n) {\n    val addImagesToPdfPicker = rememberImagePicker(onSuccess = component::addUris)\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberImagePicker(\n            onSuccess = component::setUris\n        ),\n        secondaryButtonIcon = Icons.Rounded.AddPhotoAlt,\n        secondaryButtonText = stringResource(R.string.pick_image_alt),\n        noDataText = stringResource(R.string.pick_image),\n        isPickedAlready = component.initialUris != null,\n        canShowScreenData = !component.uris.isNullOrEmpty(),\n        title = stringResource(R.string.images_to_pdf),\n        controls = {\n            ImageReorderCarousel(\n                images = component.uris,\n                onReorder = component::setUris,\n                onNeedToAddImage = addImagesToPdfPicker::pickImage,\n                onNeedToRemoveImageAt = component::removeAt,\n                onNavigate = component.onNavigate\n            )\n            Spacer(Modifier.height(16.dp))\n            PresetSelector(\n                value = component.presetSelected,\n                includeTelegramOption = false,\n                onValueChange = {\n                    if (it is Preset.Percentage) {\n                        component.selectPreset(it)\n                    }\n                }\n            )\n            Spacer(Modifier.height(8.dp))\n            QualitySelector(\n                imageFormat = ImageFormat.Jpg,\n                quality = Quality.Base(component.quality),\n                onQualityChange = {\n                    component.setQuality(it.qualityValue)\n                },\n                autoCoerce = false\n            )\n            Spacer(Modifier.height(8.dp))\n            ScaleSmallImagesToLargeToggle(\n                checked = component.scaleSmallImagesToLarge,\n                onCheckedChange = {\n                    component.toggleScaleSmallImagesToLarge()\n                }\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/images_to_pdf/screenLogic/ImagesToPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfCreationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass ImagesToPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUris != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uris: MutableState<List<Uri>?> = mutableStateOf(initialUris)\n    val uris by _uris\n\n    private val _presetSelected: MutableState<Preset.Percentage> =\n        mutableStateOf(Preset.Percentage(100))\n    val presetSelected by _presetSelected\n\n    private val _quality: MutableState<Int> = mutableIntStateOf(85)\n    val quality by _quality\n\n    private val _scaleSmallImagesToLarge: MutableState<Boolean> = mutableStateOf(false)\n    val scaleSmallImagesToLarge by _scaleSmallImagesToLarge\n\n    private val pdfCreationParams: PdfCreationParams\n        get() = PdfCreationParams(\n            scaleSmallImagesToLarge = _scaleSmallImagesToLarge.value,\n            preset = _presetSelected.value,\n            quality = _quality.value\n        )\n\n    fun setUris(uris: List<Uri>?) {\n        if (uris == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uris.update { uris }\n    }\n\n    fun addUris(uris: List<Uri>) {\n        setUris(this.uris.orEmpty().plus(uris).distinct())\n    }\n\n    fun removeAt(index: Int) {\n        runCatching {\n            _uris.update {\n                it?.toMutableList()?.apply { removeAt(index) }\n            }\n            registerChanges()\n        }\n    }\n\n    fun toggleScaleSmallImagesToLarge() {\n        _scaleSmallImagesToLarge.update { !it }\n        registerChanges()\n    }\n\n    fun setQuality(quality: Int) {\n        _quality.update { quality }\n        registerChanges()\n    }\n\n    fun selectPreset(preset: Preset.Percentage) {\n        _presetSelected.update { preset }\n        registerChanges()\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.createPdf(\n                imageUris = uris?.map { it.toString() } ?: emptyList(),\n                params = pdfCreationParams\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.createPdf(\n                            imageUris = uris?.map { it.toString() } ?: emptyList(),\n                            params = pdfCreationParams\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUris: List<Uri>?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ImagesToPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/merge/MergePdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.FileReorderVerticalList\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.screenLogic.MergePdfToolComponent\n\n@Composable\nfun MergePdfToolContent(\n    component: MergePdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUris\n        ),\n        isPickedAlready = !component.initialUris.isNullOrEmpty(),\n        canShowScreenData = component.uris.isNotEmpty(),\n        title = stringResource(R.string.merge_pdf),\n        controls = {\n            val addFilesPicker = rememberFilePicker(\n                mimeType = MimeType.Pdf,\n                onSuccess = component::addUris\n            )\n\n            FileReorderVerticalList(\n                files = component.uris,\n                onReorder = component::setUris,\n                onNeedToAddFile = addFilesPicker::pickFile,\n                onNeedToRemoveFileAt = component::removeAt\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/merge/screenLogic/MergePdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass MergePdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(!initialUris.isNullOrEmpty())\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uris: MutableState<List<Uri>> = mutableStateOf(initialUris.orEmpty())\n    val uris by _uris\n\n    fun setUris(uris: List<Uri>) {\n        registerChanges()\n        _uris.update { uris }\n    }\n\n    fun addUris(uris: List<Uri>) {\n        _uris.update { (it + uris).distinct() }\n    }\n\n    fun removeAt(index: Int) {\n        _uris.update { it.toMutableList().apply { removeAt(index) } }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.mergePdfs(uris.map(Uri::toString))\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(listOf(pdfManager.mergePdfs(uris.map(Uri::toString)).toUri()))\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUris: List<Uri>?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): MergePdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/metadata/MetadataPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.components.MetadataEditor\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.screenLogic.MetadataPdfToolComponent\n\n@Composable\nfun MetadataPdfToolContent(\n    component: MetadataPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.metadata),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            MetadataEditor(\n                value = component.metadata,\n                onValueChange = component::updateMetadata,\n                deepClean = component.deepClean,\n                onReset = component::resetMetadata,\n                onUpdateDeepClean = component::updateDeepClean\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/metadata/components/MetadataEditor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Cancel\nimport androidx.compose.material.icons.rounded.Restore\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Mop\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfMetadata\n\n@Composable\ninternal fun MetadataEditor(\n    value: PdfMetadata,\n    onValueChange: (PdfMetadata) -> Unit,\n    onReset: () -> Unit,\n    deepClean: Boolean,\n    onUpdateDeepClean: (Boolean) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Column(\n        modifier = modifier.container(\n            shape = ShapeDefaults.extraLarge,\n            clip = false\n        ),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.SpaceBetween,\n            modifier = Modifier\n                .padding(\n                    top = 16.dp,\n                    bottom = 8.dp,\n                    start = 16.dp,\n                    end = 8.dp\n                )\n        ) {\n            Text(\n                fontWeight = FontWeight.Medium,\n                text = stringResource(R.string.tags),\n                modifier = Modifier.weight(1f),\n                fontSize = 18.sp,\n            )\n            Spacer(Modifier.width(16.dp))\n\n            EnhancedButton(\n                onClick = onReset,\n                containerColor = MaterialTheme.colorScheme.surface,\n                contentColor = MaterialTheme.colorScheme.onSurface,\n                contentPadding = PaddingValues(\n                    start = 8.dp,\n                    end = 12.dp\n                ),\n                modifier = Modifier\n                    .padding(start = 8.dp, end = 8.dp)\n                    .height(30.dp),\n            ) {\n                Row {\n                    Icon(\n                        imageVector = Icons.Rounded.Restore,\n                        contentDescription = \"Restore\",\n                        modifier = Modifier.size(20.dp)\n                    )\n                    Spacer(Modifier.width(4.dp))\n                    Text(\n                        stringResource(R.string.reset)\n                    )\n                }\n            }\n\n        }\n        PreferenceRowSwitch(\n            title = stringResource(R.string.privacy_deep_clean),\n            subtitle = stringResource(R.string.privacy_deep_clean_sub),\n            checked = deepClean,\n            onClick = onUpdateDeepClean,\n            startIcon = Icons.Rounded.Mop,\n            shape = ShapeDefaults.default,\n            containerColor = MaterialTheme.colorScheme.surface,\n            modifier = Modifier.padding(8.dp)\n        )\n\n        val previewValue = value.takeIf { !deepClean }\n\n        Box {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(4.dp),\n                modifier = Modifier\n                    .padding(8.dp)\n                    .alpha(\n                        animateFloatAsState(\n                            if (deepClean) 0.5f else 1f\n                        ).value\n                    )\n            ) {\n                MetadataField(\n                    shape = ShapeDefaults.top,\n                    value = previewValue?.title.orEmpty(),\n                    onValueChange = {\n                        onValueChange(value.copy(title = it))\n                    },\n                    label = stringResource(R.string.title)\n                )\n                MetadataField(\n                    shape = ShapeDefaults.center,\n                    value = previewValue?.author.orEmpty(),\n                    onValueChange = {\n                        onValueChange(value.copy(author = it))\n                    },\n                    label = stringResource(R.string.author)\n                )\n                MetadataField(\n                    shape = ShapeDefaults.center,\n                    value = previewValue?.subject.orEmpty(),\n                    onValueChange = {\n                        onValueChange(value.copy(subject = it))\n                    },\n                    label = stringResource(R.string.subject)\n                )\n                MetadataField(\n                    shape = ShapeDefaults.center,\n                    value = previewValue?.keywords.orEmpty(),\n                    onValueChange = {\n                        onValueChange(value.copy(keywords = it))\n                    },\n                    label = stringResource(R.string.keywords)\n                )\n                MetadataField(\n                    shape = ShapeDefaults.center,\n                    value = previewValue?.creator.orEmpty(),\n                    onValueChange = {\n                        onValueChange(value.copy(creator = it))\n                    },\n                    label = stringResource(R.string.creator)\n                )\n                MetadataField(\n                    shape = ShapeDefaults.bottom,\n                    value = previewValue?.producer.orEmpty(),\n                    onValueChange = {\n                        onValueChange(value.copy(producer = it))\n                    },\n                    label = stringResource(R.string.producer)\n                )\n            }\n\n            if (deepClean) {\n                Surface(\n                    modifier = Modifier.matchParentSize(),\n                    color = Color.Transparent\n                ) { }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun MetadataField(\n    shape: Shape,\n    value: String,\n    onValueChange: (String) -> Unit,\n    label: String\n) {\n    RoundedTextField(\n        modifier = Modifier\n            .container(\n                shape = shape,\n                color = MaterialTheme.colorScheme.surface,\n                resultPadding = 8.dp\n            ),\n        value = value,\n        endIcon = {\n            if (value.isNotEmpty()) {\n                EnhancedIconButton(\n                    onClick = { onValueChange(\"\") },\n                    modifier = Modifier.padding(end = 4.dp)\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Cancel,\n                        contentDescription = stringResource(R.string.cancel),\n                        tint = MaterialTheme.colorScheme.onSecondaryContainer\n                    )\n                }\n            }\n        },\n        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),\n        singleLine = false,\n        onValueChange = onValueChange,\n        label = {\n            Text(label)\n        }\n    )\n}\n\n@Composable\n@EnPreview\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    MetadataEditor(\n        value = PdfMetadata(),\n        onValueChange = {},\n        onReset = {},\n        deepClean = false,\n        onUpdateDeepClean = {},\n        modifier = Modifier.padding(16.dp)\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/metadata/screenLogic/MetadataPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfMetadata\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass MetadataPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _metadata: MutableState<PdfMetadata> = mutableStateOf(PdfMetadata())\n    val metadata by _metadata\n\n    private val _deepClean: MutableState<Boolean> = mutableStateOf(false)\n    val deepClean by _deepClean\n\n    override fun getKey(): Pair<String, Uri?> = \"metadata\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it },\n            onSuccess = { newUri ->\n                doSharing(\n                    action = {\n                        pdfManager.getPdfMetadata(newUri.toString())\n                    },\n                    onSuccess = { metadata ->\n                        _metadata.update { metadata }\n                    },\n                    onFailure = {\n                        _metadata.update { PdfMetadata() }\n                    }\n                )\n                _deepClean.update { false }\n            }\n        )\n    }\n\n    fun updateMetadata(metadata: PdfMetadata) {\n        registerChanges()\n        _metadata.update { metadata }\n    }\n\n    fun updateDeepClean(value: Boolean) {\n        registerChanges()\n        _deepClean.update { value }\n    }\n\n    fun resetMetadata() {\n        setUri(uri)\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.changePdfMetadata(\n                uri = _uri.value.toString(),\n                metadata = metadata.takeIf { !deepClean }?.copy(\n                    producer = metadata.producer.orEmpty().ifEmpty { \"ImageToolbox\" }\n                )\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.changePdfMetadata(\n                            uri = _uri.value.toString(),\n                            metadata = metadata.takeIf { !deepClean }?.copy(\n                                producer = metadata.producer.orEmpty().ifEmpty { \"ImageToolbox\" }\n                            )\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): MetadataPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/ocr/OCRPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FilePresent\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.screenLogic.OCRPdfToolComponent\n\n@Composable\nfun OCRPdfToolContent(\n    component: OCRPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.pdf_to_text),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            PreferenceItem(\n                title = stringResource(R.string.deep_ocr),\n                subtitle = stringResource(R.string.deep_ocr_sub),\n                startIcon = Icons.Outlined.FilePresent,\n                modifier = Modifier.fillMaxWidth(),\n                onClick = component::navigateToOcr\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/ocr/screenLogic/OCRPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass OCRPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val fileController: FileController,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    override val extraDataType: ExtraDataType = ExtraDataType.File\n    override val mimeType: MimeType.Single = MimeType.Txt\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    override fun createTargetFilename(): String =\n        \"${uri?.filename()?.substringBeforeLast('.') ?: timestamp()}_extracted.txt\"\n\n    fun navigateToOcr() {\n        doSharing(\n            action = {\n                pdfManager.extractPagesFromPdf(uri.toString())\n            },\n            onSuccess = { uris ->\n                onNavigate(\n                    Screen.RecognizeText(Screen.RecognizeText.Type.WriteToFile(uris.map { it.toUri() }))\n                )\n            },\n            onFailure = {\n                AppToastHost.showFailureToast(it)\n                _uri.value = null\n                registerChangesCleared()\n            }\n        )\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = stripText()\n\n            fileController.writeBytes(\n                uri = uri.toString(),\n                block = {\n                    it.writeBytes(processed)\n                }\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                val processed = stripText()\n\n                shareProvider.cacheData(\n                    filename = createTargetFilename(),\n                    writeData = {\n                        it.writeBytes(processed)\n                    }\n                )?.toUri()?.let {\n                    onSuccess(listOf(it))\n                    registerSave()\n                }\n            },\n            onFailure = onFailure\n        )\n    }\n\n    private suspend fun stripText(): ByteArray = pdfManager.stripText(\n        uri = _uri.value.toString()\n    ).mapIndexed { index, text ->\n        \"--- ${getString(R.string.page)} ${index + 1} ---\\n$text\\n\\n\"\n    }.joinToString(\"\").encodeToByteArray()\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): OCRPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/page_numbers/PageNumbersPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PositionSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.components.PageNumbersPreview\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.screenLogic.PageNumbersPdfToolComponent\n\n@Composable\nfun PageNumbersPdfToolContent(\n    component: PageNumbersPdfToolComponent\n) {\n    val pageCount by rememberPdfPages(component.uri)\n    val params = component.params\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.page_numbers),\n        actions = {},\n        imagePreview = {\n            PageNumbersPreview(\n                uri = component.uri,\n                params = params,\n                pageCount = pageCount\n            )\n        },\n        placeImagePreview = true,\n        showImagePreviewAsStickyHeader = true,\n        controls = {\n            RoundedTextField(\n                modifier = Modifier\n                    .padding(top = 8.dp)\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp\n                    ),\n                value = params.labelFormat,\n                keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),\n                singleLine = false,\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            labelFormat = it\n                        )\n                    )\n                },\n                label = {\n                    Text(stringResource(R.string.label_format))\n                }\n            )\n            Spacer(Modifier.height(8.dp))\n            PositionSelector(\n                value = params.position,\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            position = it\n                        )\n                    )\n                },\n                color = Color.Unspecified\n            )\n            Spacer(Modifier.height(8.dp))\n            ColorRowSelector(\n                value = Color(params.color),\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            color = it.toArgb()\n                        )\n                    )\n                },\n                title = stringResource(R.string.text_color),\n                modifier = Modifier.container(\n                    shape = ShapeDefaults.large\n                )\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/page_numbers/components/PageNumbersPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfPageNumbersParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PageSwitcher\n\n@Composable\ninternal fun PageNumbersPreview(\n    uri: Uri?,\n    params: PdfPageNumbersParams,\n    pageCount: Int\n) {\n    PageSwitcher(\n        activePages = null,\n        pageCount = pageCount\n    ) { page ->\n        Box(\n            modifier = Modifier\n                .container()\n                .padding(4.dp)\n                .animateContentSizeNoClip(\n                    alignment = Alignment.Center\n                ),\n            contentAlignment = Alignment.Center\n        ) {\n            var aspectRatio by rememberSaveable {\n                mutableFloatStateOf(1f)\n            }\n\n            val previewText = params.labelFormat\n                .replace(\"{n}\", (page + 1).toString())\n                .replace(\"{total}\", pageCount.toString())\n\n            val previewAlignment = when (params.position) {\n                Position.TopLeft -> Alignment.TopStart\n                Position.TopCenter -> Alignment.TopCenter\n                Position.TopRight -> Alignment.TopEnd\n                Position.CenterLeft -> Alignment.CenterStart\n                Position.Center -> Alignment.Center\n                Position.CenterRight -> Alignment.CenterEnd\n                Position.BottomLeft -> Alignment.BottomStart\n                Position.BottomCenter -> Alignment.BottomCenter\n                Position.BottomRight -> Alignment.BottomEnd\n            }\n\n            Box(\n                modifier = Modifier.aspectRatio(aspectRatio)\n            ) {\n                Picture(\n                    model = remember(uri, page) {\n                        PdfImageRequest(\n                            data = uri,\n                            pdfPage = page\n                        )\n                    },\n                    contentScale = ContentScale.FillBounds,\n                    modifier = Modifier.matchParentSize(),\n                    onSuccess = {\n                        aspectRatio = it.result.image.safeAspectRatio\n                    },\n                    shape = MaterialTheme.shapes.medium\n                )\n\n                BoxWithConstraints(\n                    modifier = Modifier.matchParentSize()\n                ) {\n                    AutoSizeText(\n                        key = { maxWidth },\n                        text = previewText,\n                        modifier = Modifier\n                            .align(previewAlignment)\n                            .padding(8.dp),\n                        style = MaterialTheme.typography.labelSmall,\n                        lineHeight = 11.sp,\n                        color = Color(params.color)\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/page_numbers/screenLogic/PageNumbersPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfPageNumbersParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass PageNumbersPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _params: MutableState<PdfPageNumbersParams> = mutableStateOf(PdfPageNumbersParams())\n    val params by _params\n\n    override fun getKey(): Pair<String, Uri?> = \"numbered\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateParams(params: PdfPageNumbersParams) {\n        registerChanges()\n        _params.update { params }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.addPageNumbers(\n                uri = _uri.value.toString(),\n                params = params\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.addPageNumbers(\n                            uri = _uri.value.toString(),\n                            params = params\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): PageNumbersPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/preview/PreviewPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview\n\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Search\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.rememberFilename\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.canUseNewPdf\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.screenLogic.PreviewPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.components.PdfViewer\n\n@Composable\nfun PreviewPdfToolContent(\n    component: PreviewPdfToolComponent\n) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    var isSearching by remember(component.uri) {\n        mutableStateOf(false)\n    }\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = component.uri?.let {\n            rememberFilename(it)\n        }.orEmpty().ifEmpty { stringResource(R.string.preview_pdf) },\n        actions = {},\n        forceImagePreviewToMax = component.uri != null,\n        placeControlsSeparately = true,\n        canShare = true,\n        canSave = false,\n        topAppBarPersistentActions = {\n            if (component.uri != null && canUseNewPdf()) {\n                EnhancedIconButton(\n                    onClick = {\n                        isSearching = !isSearching\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Search,\n                        contentDescription = stringResource(R.string.search_here)\n                    )\n                }\n            }\n        },\n        drawBottomShadow = !isSearching,\n        controls = {\n            if (rememberPdfPages(component.uri).value > 0) {\n                PdfViewer(\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .padding(bottom = if (isPortrait) 104.dp else 0.dp),\n                    uri = component.uri,\n                    contentPadding = PaddingValues(),\n                    isSearching = isSearching\n                )\n            }\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/preview/screenLogic/PreviewPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass PreviewPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    fun setUri(uri: Uri?) {\n        registerChangesCleared()\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) = Unit\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                shareProvider.cacheData(\n                    writeData = { writeable ->\n                        fileController.transferBytes(\n                            fromUri = _uri.value.toString(),\n                            to = writeable\n                        )\n                    },\n                    filename = _uri.value?.filename() ?: createTargetFilename()\n                )?.let {\n                    onSuccess(listOf(it.toUri()))\n                    registerSave()\n                }\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): PreviewPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/print/PrintPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Receipt\nimport androidx.compose.material.icons.outlined.ViewWeek\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.derivative.OnlyAllowedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PageOrientation\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PageSize\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PrintPdfParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.screenLogic.PrintPdfToolComponent\nimport kotlin.math.roundToInt\n\n@Composable\nfun PrintPdfToolContent(\n    component: PrintPdfToolComponent\n) {\n    val params = component.params\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.print_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n            QualitySelector(\n                imageFormat = ImageFormat.Jpg,\n                quality = Quality.Base((params.quality * 100).roundToInt()),\n                onQualityChange = {\n                    component.updateParams(\n                        params.copy(quality = it.qualityValue / 100f)\n                    )\n                },\n                autoCoerce = false\n            )\n            Spacer(Modifier.height(8.dp))\n            OnlyAllowedSliderItem(\n                label = stringResource(id = R.string.pages_per_sheet),\n                icon = Icons.Outlined.ViewWeek,\n                value = component.params.pagesPerSheet,\n                allowed = PrintPdfParams.pagesMapping.keys,\n                onValueChange = { component.updateParams(params.copy(pagesPerSheet = it)) },\n                valueSuffix = \"\"\n            )\n            Spacer(Modifier.height(8.dp))\n            DataSelector(\n                value = component.params.pageSize,\n                onValueChange = { component.updateParams(params.copy(pageSize = it)) },\n                entries = remember {\n                    listOf(PageSize.Auto) + PageSize.entries\n                },\n                spanCount = 3,\n                initialExpanded = true,\n                title = stringResource(R.string.page_size),\n                titleIcon = Icons.Outlined.Receipt,\n                itemContentText = { value ->\n                    value.name.orEmpty().ifBlank {\n                        stringResource(R.string.auto)\n                    }\n                },\n                shape = ShapeDefaults.large\n            )\n            Spacer(Modifier.height(8.dp))\n            EnhancedButtonGroup(\n                modifier = Modifier\n                    .container(ShapeDefaults.large),\n                title = stringResource(id = R.string.orientation),\n                entries = PageOrientation.entries,\n                value = component.params.orientation,\n                onValueChange = { component.updateParams(params.copy(orientation = it)) },\n                itemContent = { value ->\n                    Text(\n                        stringResource(\n                            when (value) {\n                                PageOrientation.ORIGINAL -> R.string.original\n                                PageOrientation.VERTICAL -> R.string.vertical\n                                PageOrientation.HORIZONTAL -> R.string.horizontal\n                            }\n                        )\n                    )\n                }\n            )\n            Spacer(Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = params.marginPercent,\n                title = stringResource(id = R.string.margin),\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    component.updateParams(params.copy(marginPercent = it))\n                },\n                valueRange = 0f..50f,\n                shape = ShapeDefaults.large,\n                valueSuffix = \"%\"\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/print/screenLogic/PrintPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PrintPdfParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass PrintPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _params: MutableState<PrintPdfParams> =\n        mutableStateOf(PrintPdfParams())\n    val params by _params\n\n    override fun getKey(): Pair<String, Uri?> = \"printed\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateParams(params: PrintPdfParams) {\n        registerChanges()\n        _params.update { params }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.printPdf(\n                uri = _uri.value.toString(),\n                params = params\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.printPdf(\n                            uri = _uri.value.toString(),\n                            params = params\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): PrintPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/protect/ProtectPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Cancel\nimport androidx.compose.material.icons.rounded.Shuffle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.screenLogic.ProtectPdfToolComponent\n\n@Composable\nfun ProtectPdfToolContent(\n    component: ProtectPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.protect_pdf),\n        canSave = component.password.isNotEmpty(),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            RoundedTextField(\n                modifier = Modifier\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp\n                    ),\n                value = component.password,\n                startIcon = {\n                    EnhancedIconButton(\n                        onClick = {\n                            component.updatePassword(component.generateRandomPassword())\n                        },\n                        modifier = Modifier.padding(start = 4.dp)\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Shuffle,\n                            contentDescription = stringResource(R.string.shuffle),\n                            tint = MaterialTheme.colorScheme.onSecondaryContainer\n                        )\n                    }\n                },\n                endIcon = {\n                    EnhancedIconButton(\n                        onClick = { component.updatePassword(\"\") },\n                        modifier = Modifier.padding(end = 4.dp)\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Cancel,\n                            contentDescription = stringResource(R.string.cancel),\n                            tint = MaterialTheme.colorScheme.onSecondaryContainer\n                        )\n                    }\n                },\n                keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),\n                singleLine = false,\n                onValueChange = component::updatePassword,\n                label = {\n                    Text(stringResource(R.string.password))\n                }\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/protect/screenLogic/ProtectPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.RandomStringGenerator\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass ProtectPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    private val randomStringGenerator: RandomStringGenerator,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _password: MutableState<String> = mutableStateOf(\"\")\n    val password by _password\n\n    override fun getKey(): Pair<String, Uri?> = \"protected\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updatePassword(password: String) {\n        registerChanges()\n        _password.update { password }\n    }\n\n    fun generateRandomPassword(): String = randomStringGenerator.generate(18)\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.protectPdf(\n                uri = _uri.value.toString(),\n                password = password\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.protectPdf(\n                            uri = _uri.value.toString(),\n                            password = password\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ProtectPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/rearrange/RearrangePdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.components.PageData\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.components.PdfPagesRearrangeGrid\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.screenLogic.RearrangePdfToolComponent\n\n@Composable\nfun RearrangePdfToolContent(\n    component: RearrangePdfToolComponent\n) {\n    val pagesCount by rememberPdfPages(component.uri)\n\n    LaunchedEffect(pagesCount, component.pages) {\n        if (pagesCount > 0 && (component.pages.isEmpty() || component.pages.size != pagesCount)) {\n            component.updatePages(\n                List(pagesCount) {\n                    PageData(\n                        index = it,\n                        request = PdfImageRequest(\n                            data = component.uri,\n                            pdfPage = it\n                        )\n                    )\n                }\n            )\n        }\n    }\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.rearrange_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n            PdfPagesRearrangeGrid(\n                pages = component.pages,\n                onReorder = component::updatePages\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/rearrange/components/PdfPagesRearrangeGrid.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Restore\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport coil3.request.ImageRequest\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyGridState\n\n@Composable\ninternal fun PdfPagesRearrangeGrid(\n    pages: List<PageData>?,\n    modifier: Modifier = Modifier\n        .container(\n            shape = ShapeDefaults.extraLarge,\n            clip = false\n        ),\n    onReorder: (List<PageData>) -> Unit,\n    title: String = stringResource(R.string.hold_drag_drop),\n    coerceHeight: Boolean = true\n) {\n    val data = remember(pages) { mutableStateOf(pages ?: emptyList()) }\n\n    val haptics = LocalHapticFeedback.current\n    val listState = rememberLazyGridState()\n\n    val state = rememberReorderableLazyGridState(\n        lazyGridState = listState,\n        onMove = { from, to ->\n            haptics.press()\n            data.value = data.value.toMutableList().apply {\n                add(to.index, removeAt(from.index))\n            }\n        }\n    )\n\n    Column(\n        modifier = modifier\n            .then(\n                if (coerceHeight) {\n                    Modifier\n                        .heightIn(\n                            max = LocalWindowInfo.current.containerDpSize.height * 0.7f\n                        )\n                } else {\n                    Modifier\n                }\n            ),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.SpaceBetween,\n            modifier = Modifier\n                .padding(\n                    top = 16.dp,\n                    bottom = 8.dp,\n                    start = 16.dp,\n                    end = 8.dp\n                )\n        ) {\n            Text(\n                fontWeight = FontWeight.Medium,\n                text = title,\n                modifier = Modifier.weight(1f),\n                fontSize = 18.sp,\n            )\n            Spacer(Modifier.width(16.dp))\n\n            EnhancedButton(\n                onClick = {\n                    onReorder(data.value.sortedBy { it.index })\n                },\n                containerColor = MaterialTheme.colorScheme.surface,\n                contentColor = MaterialTheme.colorScheme.onSurface,\n                contentPadding = PaddingValues(\n                    start = 8.dp,\n                    end = 12.dp\n                ),\n                modifier = Modifier\n                    .padding(start = 8.dp, end = 8.dp)\n                    .height(30.dp),\n            ) {\n                Row {\n                    Icon(\n                        imageVector = Icons.Rounded.Restore,\n                        contentDescription = \"Restore\",\n                        modifier = Modifier.size(20.dp)\n                    )\n                    Spacer(Modifier.width(4.dp))\n                    Text(\n                        stringResource(R.string.reset)\n                    )\n                }\n            }\n\n        }\n        Box(\n            modifier = Modifier.weight(1f, false)\n        ) {\n            LazyVerticalGrid(\n                state = listState,\n                modifier = Modifier\n                    .fadingEdges(\n                        scrollableState = listState,\n                        isVertical = true\n                    )\n                    .animateContentSizeNoClip(),\n                contentPadding = PaddingValues(12.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalArrangement = Arrangement.spacedBy(8.dp),\n                flingBehavior = enhancedFlingBehavior(),\n                columns = GridCells.Adaptive(minSize = 150.dp)\n            ) {\n                items(\n                    items = data.value,\n                    key = { uri -> uri.toString() + uri.hashCode() }\n                ) { uri ->\n                    ReorderableItem(\n                        state = state,\n                        key = uri.toString() + uri.hashCode(),\n                    ) { isDragging ->\n                        val alpha by animateFloatAsState(if (isDragging) 0.3f else 0.6f)\n                        Box(\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .aspectRatio(1f)\n                                .container(\n                                    color = MaterialTheme.colorScheme.surface,\n                                    resultPadding = 8.dp\n                                )\n                                .container(\n                                    shape = ShapeDefaults.small,\n                                    color = Color.Transparent,\n                                    resultPadding = 0.dp\n                                )\n                                .longPressDraggableHandle(\n                                    onDragStarted = {\n                                        haptics.longPress()\n                                    },\n                                    onDragStopped = {\n                                        onReorder(data.value)\n                                    }\n                                )\n                        ) {\n                            Picture(\n                                model = uri.request,\n                                modifier = Modifier.fillMaxSize(),\n                                shape = RectangleShape,\n                                contentScale = ContentScale.Inside\n                            )\n                            Box(\n                                modifier = Modifier\n                                    .matchParentSize()\n                                    .background(\n                                        MaterialTheme.colorScheme.surfaceContainer.copy(alpha)\n                                    ),\n                                contentAlignment = Alignment.Center\n                            ) {\n                                Text(\n                                    text = \"${uri.index + 1}\",\n                                    color = MaterialTheme.colorScheme.onSurface,\n                                    fontSize = 20.sp,\n                                    fontWeight = FontWeight.Bold\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\ninternal data class PageData(\n    val index: Int,\n    val request: ImageRequest\n)\n\n@Composable\n@EnPreview\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    var files by remember {\n        mutableStateOf(\n            List(15) {\n                PageData(\n                    index = it,\n                    request = ImageRequest.Builder(appContext).data(\"file:///uri_$it.pdf\".toUri())\n                        .build()\n                )\n            }\n        )\n    }\n\n    LazyColumn {\n        item {\n            PdfPagesRearrangeGrid(\n                pages = files,\n                onReorder = {\n                    files = it\n                }\n            )\n        }\n\n        items(30) {\n            Text(\"TEST $it\")\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/rearrange/screenLogic/RearrangePdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.components.PageData\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass RearrangePdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _pages: MutableState<List<PageData>> = mutableStateOf(emptyList())\n    internal val pages by _pages\n\n    override fun getKey(): Pair<String, Uri?> = \"rearranged\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    internal fun updatePages(pages: List<PageData>) {\n        registerChanges()\n        _pages.update { pages }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.rearrangePdf(\n                uri = _uri.value.toString(),\n                newOrder = pages.map { it.index }\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.rearrangePdf(\n                            uri = _uri.value.toString(),\n                            newOrder = pages.map { it.index }\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): RearrangePdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/remove_annotations/RemoveAnnotationsPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.page.PageSelectionItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.components.PdfAnnotationTypeSelector\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.components.RemoveAnnotationsPreview\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.screenLogic.RemoveAnnotationsPdfToolComponent\n\n@Composable\nfun RemoveAnnotationsPdfToolContent(\n    component: RemoveAnnotationsPdfToolComponent\n) {\n    val pageCount by rememberPdfPages(component.uri)\n    val params = component.params\n\n    LaunchedEffect(pageCount, params.pages) {\n        if (params.pages == null && pageCount > 0) {\n            component.updateParams(\n                params.copy(\n                    pages = List(pageCount) { it }\n                )\n            )\n        }\n    }\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canSave = params.types.isNotEmpty(),\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.remove_annotations),\n        imagePreview = {\n            RemoveAnnotationsPreview(\n                uri = component.uri,\n                params = params,\n                pageCount = pageCount\n            )\n        },\n        placeImagePreview = true,\n        showImagePreviewAsStickyHeader = true,\n        controls = {\n            PageSelectionItem(\n                value = params.pages,\n                onValueChange = {\n                    component.updateParams(params.copy(pages = it))\n                },\n                pageCount = pageCount\n            )\n\n            Spacer(Modifier.height(16.dp))\n\n            PdfAnnotationTypeSelector(\n                values = params.types,\n                onValueChange = { newTypes ->\n                    component.updateParams(\n                        params.copy(\n                            types = newTypes\n                        )\n                    )\n                }\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/remove_annotations/components/PdfAnnotationTypeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfAnnotationType\n\n@Composable\ninternal fun PdfAnnotationTypeSelector(\n    values: Set<PdfAnnotationType>,\n    onValueChange: (Set<PdfAnnotationType>) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Column(\n        modifier = modifier\n            .fillMaxWidth()\n            .container(\n                shape = ShapeDefaults.extraLarge\n            ),\n        horizontalAlignment = Alignment.CenterHorizontally,\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        Spacer(Modifier.height(4.dp))\n\n        Text(\n            text = stringResource(R.string.annotations),\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(bottom = 4.dp),\n            textAlign = TextAlign.Center,\n            fontWeight = FontWeight.Medium\n        )\n\n        FlowRow(\n            verticalArrangement = Arrangement.spacedBy(\n                space = 8.dp,\n                alignment = Alignment.CenterVertically\n            ),\n            horizontalArrangement = Arrangement.spacedBy(\n                space = 8.dp,\n                alignment = Alignment.CenterHorizontally\n            ),\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 8.dp)\n                .container(\n                    shape = ShapeDefaults.default,\n                    color = MaterialTheme.colorScheme.surface\n                )\n                .padding(horizontal = 8.dp, vertical = 12.dp)\n        ) {\n            PdfAnnotationType.entries.forEach { type ->\n                val selected = type in values\n\n                EnhancedChip(\n                    selected = selected,\n                    onClick = {\n                        onValueChange(values.toggle(type))\n                    },\n                    selectedColor = MaterialTheme.colorScheme.primary,\n                    contentPadding = PaddingValues(\n                        horizontal = 12.dp,\n                        vertical = 8.dp\n                    ),\n                    modifier = Modifier.height(36.dp)\n                ) {\n                    Text(stringResource(type.title()))\n                }\n            }\n        }\n\n        Spacer(Modifier.height(4.dp))\n    }\n}\n\nprivate fun PdfAnnotationType.title(): Int = when (this) {\n    PdfAnnotationType.Link -> R.string.annotation_link\n    PdfAnnotationType.FileAttachment -> R.string.annotation_file_attachment\n    PdfAnnotationType.Line -> R.string.annotation_line\n    PdfAnnotationType.Popup -> R.string.annotation_popup\n    PdfAnnotationType.Stamp -> R.string.annotation_stamp\n    PdfAnnotationType.SquareCircle -> R.string.annotation_shapes\n    PdfAnnotationType.Text -> R.string.annotation_text\n    PdfAnnotationType.TextMarkup -> R.string.annotation_text_markup\n    PdfAnnotationType.Widget -> R.string.annotation_widget\n    PdfAnnotationType.Markup -> R.string.annotation_markup\n    PdfAnnotationType.Unknown -> R.string.annotation_unknown\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/remove_annotations/components/RemoveAnnotationsPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfRemoveAnnotationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PageSwitcher\n\n@Composable\ninternal fun RemoveAnnotationsPreview(\n    uri: Uri?,\n    params: PdfRemoveAnnotationParams,\n    pageCount: Int\n) {\n    PageSwitcher(\n        activePages = params.pages,\n        pageCount = pageCount\n    ) { page ->\n        Box(\n            modifier = Modifier\n                .container()\n                .padding(4.dp)\n                .animateContentSizeNoClip(\n                    alignment = Alignment.Center\n                ),\n            contentAlignment = Alignment.Center\n        ) {\n            var aspectRatio by rememberSaveable {\n                mutableFloatStateOf(1f)\n            }\n\n            Box(\n                modifier = Modifier\n                    .aspectRatio(aspectRatio)\n                    .clip(MaterialTheme.shapes.small)\n            ) {\n                Picture(\n                    model = remember(uri, page) {\n                        PdfImageRequest(\n                            data = uri,\n                            pdfPage = page\n                        )\n                    },\n                    contentScale = ContentScale.FillBounds,\n                    modifier = Modifier.matchParentSize(),\n                    onSuccess = {\n                        aspectRatio = it.result.image.safeAspectRatio\n                    },\n                    shape = RectangleShape\n                )\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/remove_annotations/screenLogic/RemoveAnnotationsPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfRemoveAnnotationParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.distinctUntilChanged\n\nclass RemoveAnnotationsPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _params: MutableState<PdfRemoveAnnotationParams> =\n        mutableStateOf(PdfRemoveAnnotationParams())\n    val params by _params\n\n    override fun getKey(): Pair<String, Uri?> = \"annotations_removed\" to uri\n\n    init {\n        componentScope.launch {\n            snapshotFlow { uri }\n                .distinctUntilChanged()\n                .collect {\n                    _params.update { it.copy(pages = null) }\n                }\n        }\n    }\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateParams(params: PdfRemoveAnnotationParams) {\n        _params.update { params }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.removeAnnotations(\n                uri = _uri.value.toString(),\n                params = params\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.removeAnnotations(\n                            uri = _uri.value.toString(),\n                            params = params\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): RemoveAnnotationsPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/remove_pages/RemovePagesPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.components.PdfPagesRemoveGrid\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.screenLogic.RemovePagesPdfToolComponent\n\n@Composable\nfun RemovePagesPdfToolContent(\n    component: RemovePagesPdfToolComponent\n) {\n    val pagesCount by rememberPdfPages(component.uri)\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.remove_pages_pdf),\n        canSave = component.pagesToDelete.size < pagesCount,\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n            PdfPagesRemoveGrid(\n                pages = remember(pagesCount, component.uri) {\n                    List(pagesCount) {\n                        PdfImageRequest(\n                            data = component.uri,\n                            pdfPage = it\n                        )\n                    }\n                },\n                pagesToDelete = component.pagesToDelete,\n                onClearAll = {\n                    component.updatePages(emptyList())\n                },\n                onClickPage = {\n                    component.updatePages(\n                        component.pagesToDelete.toggle(it)\n                    )\n                },\n                onUpdatePages = component::updatePages,\n                pagesCount = pagesCount\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/remove_pages/components/PdfPagesRemoveGrid.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.components\n\nimport androidx.compose.animation.animateColor\nimport androidx.compose.animation.core.animateDp\nimport androidx.compose.animation.core.updateTransition\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.itemsIndexed\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.CheckCircle\nimport androidx.compose.material.icons.rounded.Pages\nimport androidx.compose.material.icons.rounded.Restore\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.MediaCheckBox\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.page.PageInputDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\ninternal fun PdfPagesRemoveGrid(\n    pages: List<Any>,\n    modifier: Modifier = Modifier\n        .container(\n            shape = ShapeDefaults.extraLarge,\n            clip = false\n        ),\n    onUpdatePages: (List<Int>) -> Unit,\n    onClearAll: () -> Unit,\n    pagesToDelete: List<Int>,\n    onClickPage: (Int) -> Unit,\n    title: String = stringResource(R.string.pages_selection),\n    coerceHeight: Boolean = true,\n    pagesCount: Int\n) {\n    var showPageSelector by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    Column(\n        modifier = modifier\n            .then(\n                if (coerceHeight) {\n                    Modifier\n                        .heightIn(\n                            max = LocalWindowInfo.current.containerDpSize.height * 0.7f\n                        )\n                } else {\n                    Modifier\n                }\n            ),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.SpaceBetween,\n            modifier = Modifier\n                .padding(\n                    top = 16.dp,\n                    bottom = 8.dp,\n                    start = 16.dp,\n                    end = 8.dp\n                )\n        ) {\n            Text(\n                fontWeight = FontWeight.Medium,\n                text = title,\n                modifier = Modifier.weight(1f),\n                fontSize = 18.sp,\n            )\n            Spacer(Modifier.width(16.dp))\n\n            EnhancedButton(\n                onClick = {\n                    showPageSelector = true\n                },\n                containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                contentColor = MaterialTheme.colorScheme.onSurfaceVariant,\n                contentPadding = PaddingValues(\n                    start = 8.dp,\n                    end = 10.dp\n                ),\n                modifier = Modifier\n                    .padding(start = 8.dp)\n                    .height(30.dp),\n            ) {\n                Row(\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.Pages,\n                        contentDescription = \"manually\",\n                        modifier = Modifier.size(20.dp)\n                    )\n                    Spacer(Modifier.width(4.dp))\n                    Text(\n                        stringResource(R.string.manually)\n                    )\n                }\n            }\n            EnhancedButton(\n                onClick = onClearAll,\n                containerColor = MaterialTheme.colorScheme.surface,\n                contentColor = MaterialTheme.colorScheme.onSurface,\n                contentPadding = PaddingValues(\n                    start = 8.dp,\n                    end = 12.dp\n                ),\n                modifier = Modifier\n                    .padding(start = 8.dp, end = 8.dp)\n                    .height(30.dp),\n            ) {\n                Row {\n                    Icon(\n                        imageVector = Icons.Rounded.Restore,\n                        contentDescription = \"Restore\",\n                        modifier = Modifier.size(20.dp)\n                    )\n                    Spacer(Modifier.width(4.dp))\n                    Text(\n                        stringResource(R.string.reset)\n                    )\n                }\n            }\n\n        }\n        Box(\n            modifier = Modifier.weight(1f, false)\n        ) {\n            val listState = rememberLazyGridState()\n            LazyVerticalGrid(\n                state = listState,\n                modifier = Modifier\n                    .fadingEdges(\n                        scrollableState = listState,\n                        isVertical = true\n                    )\n                    .animateContentSizeNoClip(),\n                contentPadding = PaddingValues(12.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalArrangement = Arrangement.spacedBy(8.dp),\n                flingBehavior = enhancedFlingBehavior(),\n                columns = GridCells.Adaptive(minSize = 150.dp)\n            ) {\n                itemsIndexed(\n                    items = pages,\n                    key = { _, uri -> uri.toString() + uri.hashCode() }\n                ) { index, uri ->\n                    Box(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .aspectRatio(1f)\n                            .container(\n                                color = MaterialTheme.colorScheme.errorContainer,\n                                resultPadding = 0.dp\n                            )\n                    ) {\n                        val transition = updateTransition(index in pagesToDelete)\n\n                        Box(\n                            modifier = Modifier\n                                .padding(\n                                    transition.animateDp {\n                                        if (it) 12.dp else 0.dp\n                                    }.value\n                                )\n                                .container(\n                                    color = MaterialTheme.colorScheme.surface,\n                                    shape = AutoCornersShape(\n                                        transition.animateDp {\n                                            if (it) 8.dp else 16.dp\n                                        }.value\n                                    ),\n                                    resultPadding = 8.dp\n                                )\n                                .container(\n                                    shape = AutoCornersShape(\n                                        transition.animateDp {\n                                            if (it) 4.dp else 12.dp\n                                        }.value\n                                    ),\n                                    color = Color.Transparent,\n                                    resultPadding = 0.dp\n                                )\n                                .hapticsClickable {\n                                    onClickPage(index)\n                                }\n                        ) {\n                            Picture(\n                                model = uri,\n                                modifier = Modifier\n                                    .fillMaxSize()\n                                    .transparencyChecker(),\n                                showTransparencyChecker = false,\n                                shape = RectangleShape,\n                                contentScale = ContentScale.Inside\n                            )\n                            Box(\n                                modifier = Modifier\n                                    .matchParentSize()\n                                    .background(\n                                        MaterialTheme.colorScheme.surfaceContainer.copy(0.6f)\n                                    ),\n                                contentAlignment = Alignment.Center\n                            ) {\n                                Text(\n                                    text = \"${index + 1}\",\n                                    color = MaterialTheme.colorScheme.onSurface,\n                                    fontSize = 20.sp,\n                                    fontWeight = FontWeight.Bold\n                                )\n                            }\n                        }\n                        Box(\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .padding(\n                                    transition.animateDp {\n                                        if (it) 6.dp else 12.dp\n                                    }.value\n                                )\n                        ) {\n                            MediaCheckBox(\n                                isChecked = transition.targetState,\n                                uncheckedColor = White.copy(0.8f),\n                                checkedColor = MaterialTheme.colorScheme.error,\n                                checkedIcon = Icons.Filled.CheckCircle,\n                                modifier = Modifier\n                                    .clip(ShapeDefaults.circle)\n                                    .background(\n                                        transition.animateColor {\n                                            if (it) MaterialTheme.colorScheme.errorContainer else Color.Transparent\n                                        }.value\n                                    )\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    PageInputDialog(\n        visible = showPageSelector,\n        onDismiss = { showPageSelector = false },\n        value = pagesToDelete,\n        onValueChange = onUpdatePages,\n        pagesCount = pagesCount\n    )\n}\n\n@Composable\n@EnPreview\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    var files by remember {\n        mutableStateOf(\n            List(15) {\n                \"file:///uri_$it.pdf\".toUri()\n            }\n        )\n    }\n\n    var rotations by remember(files) {\n        mutableStateOf(\n            emptyList<Int>()\n        )\n    }\n    LazyColumn {\n        item {\n            PdfPagesRemoveGrid(\n                pages = files,\n                pagesToDelete = rotations,\n                onClearAll = {\n                    rotations = emptyList()\n                },\n                onClickPage = {\n                    rotations = rotations.toggle(it)\n                },\n                onUpdatePages = {\n                    rotations = it\n                },\n                pagesCount = 100\n            )\n        }\n\n        items(30) {\n            Text(\"TEST $it\")\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/remove_pages/screenLogic/RemovePagesPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass RemovePagesPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _pagesToDelete: MutableState<List<Int>> = mutableStateOf(emptyList())\n    val pagesToDelete by _pagesToDelete\n\n    override fun getKey(): Pair<String, Uri?> = \"removed\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updatePages(pages: List<Int>) {\n        registerChanges()\n        _pagesToDelete.update { pages }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.removePdfPages(\n                uri = _uri.value.toString(),\n                pages = pagesToDelete\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.removePdfPages(\n                            uri = _uri.value.toString(),\n                            pages = pagesToDelete\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): RemovePagesPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/repair/RepairPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.screenLogic.RepairPdfToolComponent\n\n@Composable\nfun RepairPdfToolContent(\n    component: RepairPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.repair_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            InfoContainer(\n                text = stringResource(R.string.repair_info)\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/repair/screenLogic/RepairPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass RepairPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    override fun getKey(): Pair<String, Uri?> = \"repaired\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.repairPdf(\n                uri = _uri.value.toString()\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.repairPdf(\n                            uri = _uri.value.toString()\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): RepairPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/root/RootPdfToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.plus\nimport androidx.compose.foundation.layout.systemBars\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileOpen\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.screenLogic.RootPdfToolsComponent\n\n@Composable\nfun RootPdfToolsContent(\n    component: RootPdfToolsComponent\n) {\n    var tempSelectionUri by rememberSaveable { mutableStateOf<Uri?>(null) }\n    var showSelectionPdfPicker by rememberSaveable { mutableStateOf(false) }\n\n    LaunchedEffect(showSelectionPdfPicker) {\n        if (!showSelectionPdfPicker) tempSelectionUri = null\n    }\n    val selectionPdfPicker = rememberFilePicker(\n        mimeType = MimeType.Pdf,\n        onSuccess = { uri: Uri ->\n            tempSelectionUri = uri\n            showSelectionPdfPicker = true\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        title = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                modifier = Modifier.marquee()\n            ) {\n                Text(\n                    text = stringResource(R.string.pdf_tools),\n                    textAlign = TextAlign.Center\n                )\n                EnhancedBadge(\n                    content = {\n                        Text(\n                            text = Screen.PdfTools.options.size.toString()\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.tertiary,\n                    contentColor = MaterialTheme.colorScheme.onTertiary,\n                    modifier = Modifier\n                        .padding(horizontal = 2.dp)\n                        .padding(bottom = 12.dp)\n                        .scaleOnTap {\n                            AppToastHost.showConfetti()\n                        }\n                )\n            }\n        },\n        topAppBarPersistentActions = {\n            TopAppBarEmoji()\n        },\n        onGoBack = component.onGoBack,\n        shouldDisableBackHandler = true,\n        buttons = {},\n        controls = {\n            Scaffold(\n                bottomBar = {\n                    BottomButtonsBlock(\n                        isNoData = true,\n                        showNullDataButtonAsContainer = true,\n                        isPrimaryButtonVisible = false,\n                        onSecondaryButtonClick = selectionPdfPicker::pickFile,\n                        onPrimaryButtonClick = { },\n                        actions = { },\n                        secondaryButtonIcon = Icons.Rounded.FileOpen,\n                        secondaryButtonText = stringResource(R.string.pick_file)\n                    )\n                },\n                contentWindowInsets = WindowInsets.systemBars\n                    .union(WindowInsets.displayCutout)\n                    .only(WindowInsetsSides.Start)\n            ) { contentPadding ->\n                LazyVerticalStaggeredGrid(\n                    modifier = Modifier.fillMaxHeight(),\n                    columns = StaggeredGridCells.Adaptive(300.dp),\n                    horizontalArrangement = Arrangement.spacedBy(\n                        space = 12.dp,\n                        alignment = Alignment.CenterHorizontally\n                    ),\n                    verticalItemSpacing = 12.dp,\n                    contentPadding = contentPadding + PaddingValues(16.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    items(Screen.PdfTools.options) { screen ->\n                        PreferenceItem(\n                            title = stringResource(screen.title),\n                            subtitle = stringResource(screen.subtitle),\n                            startIcon = screen.icon,\n                            modifier = Modifier.fillMaxWidth(),\n                            onClick = { component.onNavigate(screen) }\n                        )\n                    }\n                }\n            }\n        },\n        imagePreview = {},\n        placeImagePreview = false,\n        showImagePreviewAsStickyHeader = false,\n        placeControlsSeparately = true,\n        canShowScreenData = true,\n        noDataControls = {},\n        actions = {}\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showSelectionPdfPicker,\n        onDismiss = {\n            showSelectionPdfPicker = it\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showSelectionPdfPicker = false\n                },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(id = R.string.close))\n            }\n        },\n        sheetContent = {\n            if (tempSelectionUri == null) showSelectionPdfPicker = false\n\n            LazyVerticalStaggeredGrid(\n                columns = StaggeredGridCells.Adaptive(250.dp),\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = 12.dp,\n                    alignment = Alignment.CenterHorizontally\n                ),\n                verticalItemSpacing = 12.dp,\n                contentPadding = PaddingValues(12.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                items(Screen.PdfTools.options) { screen ->\n                    PreferenceItem(\n                        title = stringResource(screen.title),\n                        subtitle = stringResource(screen.subtitle),\n                        startIcon = screen.icon,\n                        modifier = Modifier.fillMaxWidth(),\n                        onClick = {\n                            showSelectionPdfPicker = false\n                            component.navigate(\n                                screen = screen,\n                                tempSelectionUri = tempSelectionUri\n                            )\n                        }\n                    )\n                }\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.pick_file),\n                icon = Icons.Rounded.FileOpen\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/root/components/PdfViewer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.components\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.canUseNewPdf\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.components.viewer.LegacyPdfViewer\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.components.viewer.ModernPdfViewer\n\n@Composable\nfun PdfViewer(\n    uri: Uri?,\n    modifier: Modifier,\n    spacing: Dp = 8.dp,\n    contentPadding: PaddingValues = PaddingValues(start = 20.dp, end = 20.dp),\n    isSearching: Boolean = false\n) {\n    AnimatedContent(\n        targetState = uri\n    ) { uri ->\n        if (uri != null) {\n            if (canUseNewPdf()) {\n                ModernPdfViewer(\n                    uri = uri,\n                    isSearching = isSearching,\n                    modifier = modifier\n                )\n            } else {\n                LegacyPdfViewer(\n                    uri = uri,\n                    spacing = spacing,\n                    contentPadding = contentPadding,\n                    modifier = modifier\n                )\n            }\n        } else {\n            Box(\n                modifier = modifier\n                    .fillMaxSize()\n                    .animateContentSizeNoClip(),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedLoadingIndicator()\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/root/components/viewer/LegacyPdfViewer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.components.viewer\n\nimport android.net.Uri\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.produceState\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport coil3.Image\nimport coil3.asImage\nimport coil3.imageLoader\nimport coil3.memory.MemoryCache\nimport coil3.request.ImageRequest\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.flexibleResize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.pdf_tools.data.utils.PdfRenderer\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport my.nanihadesuka.compose.LazyColumnScrollbar\nimport my.nanihadesuka.compose.ScrollbarSelectionMode\nimport my.nanihadesuka.compose.ScrollbarSettings\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\nimport kotlin.math.sqrt\n\n@Composable\ninternal fun LegacyPdfViewer(\n    uri: Uri,\n    spacing: Dp = 8.dp,\n    contentPadding: PaddingValues = PaddingValues(start = 20.dp, end = 20.dp),\n    modifier: Modifier = Modifier\n) {\n    val showError: (Throwable) -> Unit = {\n        it.makeLog(\"PdfViewer\")\n        AppToastHost.showFailureToast(it)\n    }\n\n    val listState = rememberLazyListState()\n    BoxWithConstraints(modifier = modifier.animateContentSizeNoClip()) {\n        val density = LocalDensity.current\n        val width = with(density) { this@BoxWithConstraints.maxWidth.toPx() }.toInt()\n        val height = (width * sqrt(2f)).toInt()\n\n        val rendererScope = rememberCoroutineScope()\n        val mutex = remember { Mutex() }\n        val pagesSize = remember { mutableStateListOf<IntegerSize>() }\n        val renderer by produceState<PdfRenderer?>(null, uri) {\n            rendererScope.launch(Dispatchers.IO) {\n                runCatching {\n                    mutex.withLock {\n                        pagesSize.clear()\n                        val renderer = PdfRenderer(\n                            uri = uri.toString(),\n                            onFailure = showError\n                        )?.also {\n                            repeat(it.pageCount) { index ->\n                                it.openPage(index).let { page ->\n                                    val size = IntegerSize(\n                                        width = page.width,\n                                        height = page.height\n                                    ).flexibleResize(width, height)\n\n                                    pagesSize.add(size)\n                                }\n                            }\n                        }\n                        value = renderer\n                    }\n                }.onFailure(showError)\n            }\n            awaitDispose {\n                val currentRenderer = value\n                rendererScope.launch(Dispatchers.IO) {\n                    mutex.withLock {\n                        currentRenderer?.close()\n                    }\n                }\n            }\n        }\n        val pageCount by remember(renderer) {\n            derivedStateOf {\n                renderer?.pageCount ?: 0\n            }\n        }\n\n        LazyColumnScrollbar(\n            state = listState,\n            settings = ScrollbarSettings(\n                thumbUnselectedColor = MaterialTheme.colorScheme.primary,\n                thumbSelectedColor = MaterialTheme.colorScheme.primary,\n                scrollbarPadding = 0.dp,\n                thumbThickness = 10.dp,\n                selectionMode = ScrollbarSelectionMode.Full,\n                thumbShape = AutoCornersShape(\n                    topStartPercent = 100,\n                    bottomStartPercent = 100\n                ),\n                hideDelayMillis = 1500\n            ),\n            indicatorContent = { index, _ ->\n                val text by remember(index, pageCount, listState) {\n                    derivedStateOf {\n                        val first =\n                            listState.layoutInfo.visibleItemsInfo.firstOrNull()\n                        val last =\n                            listState.layoutInfo.visibleItemsInfo.lastOrNull()\n                        first?.takeIf {\n                            it.index == 0\n                        }?.let { 1 } ?: ((last?.index ?: index) + 1)\n                    }\n                }\n                Text(\n                    text = \"$text / $pageCount\",\n                    modifier = Modifier\n                        .padding(6.dp)\n                        .container(\n                            shape = ShapeDefaults.circle,\n                            color = MaterialTheme.colorScheme.secondaryContainer\n                        )\n                        .padding(\n                            start = 6.dp,\n                            end = 6.dp,\n                            top = 2.dp,\n                            bottom = 2.dp\n                        ),\n                    color = MaterialTheme.colorScheme.onSecondaryContainer\n                )\n            }\n        ) {\n            LazyColumn(\n                state = listState,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .background(MaterialTheme.colorScheme.surfaceContainerLow)\n                    .clipToBounds()\n                    .zoomable(\n                        rememberZoomState(10f)\n                    ),\n                contentPadding = contentPadding,\n                horizontalAlignment = Alignment.CenterHorizontally,\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                items(\n                    count = pageCount,\n                    key = { index -> \"$uri-$index\" }\n                ) { index ->\n                    if (index == 0) {\n                        Spacer(Modifier.height(16.dp))\n                    } else Spacer(Modifier.height(spacing))\n\n                    val cacheKey =\n                        MemoryCache.Key(\"$uri-${pagesSize[index]}-$index\")\n\n                    PdfPage(\n                        contentScale = ContentScale.Fit,\n                        renderWidth = pagesSize[index].width,\n                        renderHeight = pagesSize[index].height,\n                        index = index,\n                        mutex = mutex,\n                        renderer = renderer,\n                        cacheKey = cacheKey\n                    )\n                    if (index == pageCount - 1) {\n                        Spacer(Modifier.height(16.dp))\n                    }\n                }\n            }\n        }\n\n        if (pageCount == 0) {\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedLoadingIndicator()\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun PdfPage(\n    contentScale: ContentScale = ContentScale.Crop,\n    modifier: Modifier = Modifier,\n    index: Int,\n    renderWidth: Int,\n    renderHeight: Int,\n    zoom: Float = 1f,\n    mutex: Mutex,\n    renderer: PdfRenderer?,\n    cacheKey: MemoryCache.Key,\n) {\n    val imageLoadingScope = rememberCoroutineScope()\n\n    val cacheValue: Image? = appContext.imageLoader.memoryCache?.get(cacheKey)?.image\n\n    var bitmap: Image? by remember { mutableStateOf(cacheValue) }\n    if (bitmap == null) {\n        DisposableEffect(cacheKey, index) {\n            val job = imageLoadingScope.launch(Dispatchers.IO) {\n                mutex.withLock {\n                    if (!coroutineContext.isActive) return@launch\n                    try {\n                        renderer?.let {\n                            it.openPage(index).let { page ->\n                                val originalWidth = page.width\n                                val originalHeight = page.height\n\n                                val targetSize = IntegerSize(\n                                    width = originalWidth,\n                                    height = originalHeight\n                                ).flexibleResize(\n                                    w = renderWidth,\n                                    h = renderHeight\n                                )\n\n                                val scaleX = targetSize.width / originalWidth.toFloat()\n                                val scaleY = targetSize.height / originalHeight.toFloat()\n                                val scale = minOf(scaleX, scaleY) * 1.2f\n\n                                bitmap = renderer.renderImage(\n                                    index,\n                                    scale.coerceAtMost(3f).makeLog(\"PdfDecoder, scale\")\n                                ).asImage()\n                            }\n                        }\n                    } catch (_: Throwable) {\n                        //Just catch and return in case the renderer is being closed\n                        return@launch\n                    }\n                }\n            }\n            onDispose {\n                job.cancel()\n            }\n        }\n    }\n\n    val request = remember(renderWidth, renderHeight, bitmap) {\n        ImageRequest.Builder(appContext)\n            .size(renderWidth, renderHeight)\n            .memoryCacheKey(cacheKey)\n            .data(bitmap?.toBitmap())\n            .build()\n    }\n\n    val bgColor = MaterialTheme.colorScheme.secondaryContainer\n\n    val density = LocalDensity.current\n    Box(\n        modifier\n            .clip(ShapeDefaults.extraSmall)\n            .background(bgColor)\n    ) {\n        Picture(\n            modifier = Modifier\n                .then(\n                    if (contentScale == ContentScale.Crop) Modifier.matchParentSize()\n                    else Modifier\n                )\n                .width(with(density) { renderWidth.toDp() * zoom })\n                .aspectRatio(renderWidth / renderHeight.toFloat())\n                .background(Color.White),\n            shape = RectangleShape,\n            contentScale = contentScale,\n            showTransparencyChecker = false,\n            model = request\n        )\n    }\n\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/root/components/viewer/ModernPdfViewer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.components.viewer\n\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport androidx.annotation.RequiresExtension\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.fragment.compose.AndroidFragment\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\n\n@RequiresExtension(extension = Build.VERSION_CODES.S, version = 13)\n@Composable\ninternal fun ModernPdfViewer(\n    uri: Uri,\n    isSearching: Boolean,\n    modifier: Modifier = Modifier\n) {\n    var fragmentReference by remember {\n        mutableStateOf<ModernPdfViewerDelegate?>(null)\n    }\n    val loadingState = fragmentReference?.loadingState?.collectAsState()?.value\n    val colorScheme = MaterialTheme.colorScheme\n\n    LaunchedEffect(colorScheme, fragmentReference) {\n        fragmentReference?.setScheme(colorScheme)\n    }\n\n    LaunchedEffect(fragmentReference, isSearching) {\n        fragmentReference?.isTextSearchActive = isSearching\n    }\n\n    AndroidFragment<ModernPdfViewerDelegate>(\n        arguments = Bundle().apply {\n            putParcelable(\"documentUri\", uri)\n        },\n        modifier = modifier\n            .fillMaxSize()\n            .background(MaterialTheme.colorScheme.surface),\n        onUpdate = {\n            fragmentReference = it\n        }\n    )\n\n    if (loadingState == true) {\n        Box(\n            modifier = modifier\n                .fillMaxSize()\n                .animateContentSizeNoClip(),\n            contentAlignment = Alignment.Center\n        ) {\n            EnhancedLoadingIndicator()\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/root/components/viewer/ModernPdfViewerDelegate.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.components.viewer\n\nimport android.annotation.SuppressLint\nimport android.content.res.ColorStateList\nimport android.graphics.Canvas\nimport android.graphics.ColorFilter\nimport android.graphics.Paint\nimport android.graphics.Path\nimport android.graphics.PixelFormat\nimport android.graphics.drawable.Drawable\nimport android.graphics.drawable.GradientDrawable\nimport android.os.Build\nimport android.text.TextPaint\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.annotation.RequiresExtension\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.content.ContextCompat\nimport androidx.core.graphics.withScale\nimport androidx.core.graphics.withTranslation\nimport androidx.core.view.updateLayoutParams\nimport androidx.core.widget.ImageViewCompat\nimport androidx.pdf.ExperimentalPdfApi\nimport androidx.pdf.PdfDocument\nimport androidx.pdf.R\nimport androidx.pdf.view.PdfView\nimport androidx.pdf.view.ToolBoxView\nimport androidx.pdf.viewer.fragment.PdfViewerFragment\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\nimport com.t8rin.logger.makeLog\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.launch\nimport kotlin.math.min\n\n@OptIn(ExperimentalPdfApi::class)\n@SuppressLint(\"RestrictedApi\", \"VisibleForTests\", \"PrivateResource\")\n@RequiresExtension(extension = Build.VERSION_CODES.S, version = 13)\ninternal class ModernPdfViewerDelegate : PdfViewerFragment() {\n    private val _loadingState = MutableStateFlow<Boolean?>(true)\n    val loadingState: StateFlow<Boolean?> = _loadingState\n\n    override fun onLoadDocumentSuccess(document: PdfDocument) {\n        super.onLoadDocumentSuccess(document)\n        _loadingState.value = false\n    }\n\n    override fun onPdfViewCreated(pdfView: PdfView) {\n        super.onPdfViewCreated(pdfView)\n        pdfContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {\n            leftMargin = 0\n            rightMargin = 0\n        }\n    }\n\n    override fun onLoadDocumentError(error: Throwable) {\n        super.onLoadDocumentError(error)\n        _loadingState.value = null\n    }\n\n    fun setScheme(colorScheme: ColorScheme) {\n        toolboxView.getEditFab()?.let { fab ->\n            fab.backgroundTintList = ColorStateList.valueOf(colorScheme.tertiaryContainer.toArgb())\n            fab.imageTintList = ColorStateList.valueOf(colorScheme.onTertiaryContainer.toArgb())\n            fab.invalidate()\n        }\n\n        pdfSearchView.apply {\n            background = GradientDrawable().apply {\n                shape = GradientDrawable.RECTANGLE\n                cornerRadii = floatArrayOf(\n                    36f.dp, 36f.dp,\n                    36f.dp, 36f.dp,\n                    0f, 0f,\n                    0f, 0f\n                )\n                setColor(colorScheme.surfaceContainer.toArgb())\n            }\n        }\n\n        pdfSearchView.findViewById<View>(R.id.searchViewContainer).apply {\n            background = GradientDrawable().apply {\n                shape = GradientDrawable.RECTANGLE\n                cornerRadius = 28f.dp\n                setColor(colorScheme.surfaceBright.toArgb())\n            }\n            invalidate()\n        }\n\n        pdfSearchView.searchQueryBox.apply {\n            setTextColor(colorScheme.onSurface.toArgb())\n            setHintTextColor(colorScheme.onSurfaceVariant.toArgb())\n            highlightColor = colorScheme.primary.copy(alpha = 0.3f).toArgb()\n            invalidate()\n        }\n\n        pdfSearchView.matchStatusTextView.apply {\n            setTextColor(\n                colorScheme.onSurfaceVariant.toArgb()\n            )\n            invalidate()\n        }\n\n        val iconTint = ColorStateList.valueOf(\n            colorScheme.onSurfaceVariant.toArgb()\n        )\n        val buttonBgTint = ColorStateList.valueOf(\n            Color.Transparent.toArgb()\n        )\n\n        listOf(\n            pdfSearchView.findPrevButton,\n            pdfSearchView.findNextButton,\n            pdfSearchView.closeButton\n        ).forEach { button ->\n            ImageViewCompat.setImageTintList(button, iconTint)\n            button.backgroundTintList = buttonBgTint\n            button.invalidate()\n        }\n\n        pdfSearchView.invalidate()\n\n        pdfView.fastScrollVerticalThumbDrawable = createFastScrollDrawable(\n            backgroundColor = colorScheme.surfaceContainerHigh.toArgb(),\n            indicatorColor = colorScheme.onSurfaceVariant.toArgb()\n        )\n\n        ContextCompat.getDrawable(requireContext(), R.drawable.page_indicator_background)\n            ?.mutate()?.let { pageIndicatorDrawable ->\n                pageIndicatorDrawable.setTint(colorScheme.surfaceContainerHigh.toArgb())\n                pdfView.fastScrollPageIndicatorBackgroundDrawable = pageIndicatorDrawable\n            }\n\n        CoroutineScope(Dispatchers.Main.immediate).launch {\n            repeat(20) { i ->\n                pdfView.fastScroller?.fastScrollDrawer?.let {\n                    try {\n                        it.javaClass.getDeclaredField(\"textPaint\").apply {\n                            isAccessible = true\n                            set(\n                                it,\n                                TextPaint(get(it) as TextPaint).apply {\n                                    color = colorScheme.onSurface.toArgb()\n                                }\n                            )\n                        }\n                    } catch (t: Throwable) {\n                        if (i == 0) t.makeLog(\"textPaint\")\n                    }\n                }\n                pdfView.fastScrollVisibility = PdfView.FastScrollVisibility.ALWAYS_SHOW\n\n                pdfView.invalidate()\n                delay(100)\n            }\n        }\n    }\n\n    private fun createFastScrollDrawable(\n        backgroundColor: Int,\n        indicatorColor: Int\n    ): Drawable {\n        val density = requireContext().resources.displayMetrics.density\n        val widthDp = 36f\n        val heightDp = 48f\n\n        return object : Drawable() {\n            private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                color = backgroundColor\n                style = Paint.Style.FILL\n            }\n\n            private val indicatorPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {\n                color = indicatorColor\n                style = Paint.Style.FILL\n            }\n\n            private val indicatorPath = Path().apply {\n                moveTo(480f, 880f)\n                lineTo(240f, 640f)\n                lineTo(297f, 583f)\n                lineTo(480f, 766f)\n                lineTo(663f, 583f)\n                lineTo(720f, 640f)\n                lineTo(480f, 880f)\n                close()\n\n                moveTo(298f, 376f)\n                lineTo(240f, 320f)\n                lineTo(480f, 80f)\n                lineTo(720f, 320f)\n                lineTo(662f, 376f)\n                lineTo(480f, 194f)\n                lineTo(298f, 376f)\n                close()\n            }\n\n            override fun draw(canvas: Canvas) {\n                val sizePx = 24 * density\n                val offsetX = 8 * density\n                val left = bounds.left + offsetX\n                val top = bounds.top + (bounds.height() - sizePx) / 2\n                val scale = sizePx / 960f\n\n                canvas.withTranslation(left, top) {\n                    canvas.withTranslation(-12f, -sizePx / 2) {\n                        val cx = bounds.width() / 2f\n                        val cy = bounds.height() / 2f\n                        val radius = min(bounds.width(), bounds.height()) / 2f\n                        canvas.drawCircle(cx, cy, radius + 16, bgPaint)\n                    }\n\n                    canvas.withScale(scale, scale) {\n                        drawPath(indicatorPath, indicatorPaint)\n                    }\n                }\n            }\n\n            override fun setAlpha(alpha: Int) {\n                bgPaint.alpha = alpha\n                indicatorPaint.alpha = alpha\n                invalidateSelf()\n            }\n\n            override fun getAlpha(): Int = bgPaint.alpha\n\n            override fun setColorFilter(colorFilter: ColorFilter?) {\n                bgPaint.colorFilter = colorFilter\n                indicatorPaint.colorFilter = colorFilter\n                invalidateSelf()\n            }\n\n            @Deprecated(\"Deprecated in Java\")\n            override fun getOpacity(): Int = PixelFormat.TRANSLUCENT\n\n            override fun getIntrinsicWidth(): Int = (widthDp * density).toInt()\n            override fun getIntrinsicHeight(): Int = (heightDp * density).toInt()\n        }\n    }\n\n    private fun ToolBoxView.getEditFab(): FloatingActionButton? {\n        return try {\n            val field = ToolBoxView::class.java.getDeclaredField(\"editButton\")\n            field.isAccessible = true\n            field.get(this) as? FloatingActionButton\n        } catch (t: Throwable) {\n            t.makeLog(\"getEditFab\")\n            null\n        }\n    }\n\n    private val Float.dp: Float\n        get() = this * requireContext().resources.displayMetrics.density\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/root/screenLogic/RootPdfToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.screenLogic\n\nimport android.net.Uri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass RootPdfToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    fun navigate(screen: Screen, tempSelectionUri: Uri?) {\n        onNavigate(\n            when (screen) {\n                is Screen.PdfTools.ExtractPages -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Merge -> screen.copy(uris = tempSelectionUri?.let(::listOf))\n                is Screen.PdfTools.RemovePages -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Split -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Rotate -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Rearrange -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Crop -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.PageNumbers -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Watermark -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Signature -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Compress -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.RemoveAnnotations -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Flatten -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Print -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Grayscale -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Repair -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Protect -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Unlock -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Metadata -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.ExtractImages -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.OCR -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.ZipConvert -> screen.copy(uri = tempSelectionUri)\n                is Screen.PdfTools.Preview -> screen.copy(uri = tempSelectionUri)\n                else -> screen\n            }\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit\n        ): RootPdfToolsComponent\n    }\n\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/rotate/RotatePdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.components.PdfPagesRotationGrid\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.screenLogic.RotatePdfToolComponent\n\n@Composable\nfun RotatePdfToolContent(\n    component: RotatePdfToolComponent\n) {\n    val pagesCount by rememberPdfPages(component.uri)\n\n    LaunchedEffect(pagesCount, component.rotations) {\n        if (pagesCount > 0 && (component.rotations.isEmpty() || component.rotations.size != pagesCount)) {\n            component.updateRotations(List(pagesCount) { 0 })\n        }\n    }\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.rotate_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n            PdfPagesRotationGrid(\n                pages = remember(pagesCount, component.uri) {\n                    List(pagesCount) {\n                        PdfImageRequest(\n                            data = component.uri,\n                            pdfPage = it\n                        )\n                    }\n                },\n                rotations = component.rotations,\n                onRotateAll = {\n                    component.updateRotations(\n                        component.rotations.map { (it + 90) % 360 }\n                    )\n                },\n                onClearAll = {\n                    component.updateRotations(List(pagesCount) { 0 })\n                },\n                onAutoClick = component::autoRotate,\n                onRotateAt = {\n                    component.updateRotations(\n                        component.rotations.mapIndexed { index, rotation ->\n                            if (index == it) (rotation + 90) % 360\n                            else rotation\n                        }\n                    )\n                }\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/rotate/components/PdfPagesRotationGrid.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.itemsIndexed\nimport androidx.compose.foundation.lazy.grid.rememberLazyGridState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.RotateRight\nimport androidx.compose.material.icons.rounded.AutoMode\nimport androidx.compose.material.icons.rounded.Restore\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.lessSpringySpec\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\ninternal fun PdfPagesRotationGrid(\n    pages: List<Any>,\n    modifier: Modifier = Modifier\n        .container(\n            shape = ShapeDefaults.extraLarge,\n            clip = false\n        ),\n    onAutoClick: () -> Unit,\n    onRotateAll: () -> Unit,\n    onClearAll: () -> Unit,\n    rotations: List<Int>,\n    onRotateAt: (Int) -> Unit,\n    title: String = stringResource(R.string.pages),\n    coerceHeight: Boolean = true\n) {\n    Column(\n        modifier = modifier\n            .then(\n                if (coerceHeight) {\n                    Modifier\n                        .heightIn(\n                            max = LocalWindowInfo.current.containerDpSize.height * 0.7f\n                        )\n                } else {\n                    Modifier\n                }\n            ),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.SpaceBetween,\n            modifier = Modifier\n                .padding(\n                    top = 16.dp,\n                    bottom = 8.dp,\n                    start = 16.dp,\n                    end = 8.dp\n                )\n        ) {\n            Text(\n                fontWeight = FontWeight.Medium,\n                text = title,\n                modifier = Modifier.weight(1f),\n                fontSize = 18.sp,\n            )\n            Spacer(Modifier.width(16.dp))\n\n            EnhancedButton(\n                onClick = onAutoClick,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                contentPadding = PaddingValues(\n                    start = 8.dp,\n                    end = 12.dp\n                ),\n                modifier = Modifier\n                    .padding(start = 8.dp)\n                    .height(30.dp),\n            ) {\n                Row(\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.AutoMode,\n                        contentDescription = \"auto\",\n                        modifier = Modifier.size(18.dp)\n                    )\n                    Spacer(Modifier.width(4.dp))\n                    Text(\n                        stringResource(R.string.auto)\n                    )\n                }\n            }\n\n            EnhancedButton(\n                onClick = onRotateAll,\n                containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n                contentColor = MaterialTheme.colorScheme.onSurfaceVariant,\n                contentPadding = PaddingValues(\n                    start = 8.dp,\n                    end = 12.dp\n                ),\n                modifier = Modifier\n                    .padding(start = 8.dp)\n                    .height(30.dp),\n            ) {\n                Row(\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.RotateRight,\n                        contentDescription = \"Rotate 90\",\n                        modifier = Modifier.size(20.dp)\n                    )\n                    Spacer(Modifier.width(4.dp))\n                    Text(\n                        stringResource(R.string.all)\n                    )\n                }\n            }\n\n            EnhancedButton(\n                onClick = onClearAll,\n                containerColor = MaterialTheme.colorScheme.surface,\n                contentColor = MaterialTheme.colorScheme.onSurface,\n                contentPadding = PaddingValues(\n                    start = 8.dp,\n                    end = 12.dp\n                ),\n                modifier = Modifier\n                    .padding(start = 8.dp, end = 8.dp)\n                    .height(30.dp),\n            ) {\n                Row {\n                    Icon(\n                        imageVector = Icons.Rounded.Restore,\n                        contentDescription = \"Restore\",\n                        modifier = Modifier.size(20.dp)\n                    )\n                    Spacer(Modifier.width(4.dp))\n                    Text(\n                        stringResource(R.string.reset)\n                    )\n                }\n            }\n\n        }\n        Box(\n            modifier = Modifier.weight(1f, false)\n        ) {\n            val listState = rememberLazyGridState()\n            LazyVerticalGrid(\n                state = listState,\n                modifier = Modifier\n                    .fadingEdges(\n                        scrollableState = listState,\n                        isVertical = true\n                    )\n                    .animateContentSizeNoClip(),\n                contentPadding = PaddingValues(12.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalArrangement = Arrangement.spacedBy(8.dp),\n                flingBehavior = enhancedFlingBehavior(),\n                columns = GridCells.Adaptive(minSize = 150.dp)\n            ) {\n                itemsIndexed(\n                    items = pages,\n                    key = { _, uri -> uri.toString() + uri.hashCode() }\n                ) { index, uri ->\n                    Box(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .aspectRatio(1f)\n                            .container(\n                                color = MaterialTheme.colorScheme.surface,\n                                resultPadding = 8.dp\n                            )\n                            .container(\n                                shape = ShapeDefaults.small,\n                                color = Color.Transparent,\n                                resultPadding = 0.dp\n                            )\n                            .hapticsClickable {\n                                onRotateAt(index)\n                            }\n                    ) {\n                        Picture(\n                            model = uri,\n                            modifier = Modifier\n                                .fillMaxSize()\n                                .transparencyChecker()\n                                .rotate(\n                                    animateFloatAsState(\n                                        targetValue = rotations.getOrNull(index)?.toFloat() ?: 0f,\n                                        animationSpec = lessSpringySpec()\n                                    ).value\n                                ),\n                            showTransparencyChecker = false,\n                            shape = RectangleShape,\n                            contentScale = ContentScale.Inside\n                        )\n                        Box(\n                            modifier = Modifier\n                                .matchParentSize()\n                                .background(\n                                    MaterialTheme.colorScheme.surfaceContainer.copy(0.6f)\n                                ),\n                            contentAlignment = Alignment.Center\n                        ) {\n                            Text(\n                                text = \"${index + 1}\",\n                                color = MaterialTheme.colorScheme.onSurface,\n                                fontSize = 20.sp,\n                                fontWeight = FontWeight.Bold\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\n@EnPreview\nprivate fun Preview() = ImageToolboxThemeForPreview(true) {\n    var files by remember {\n        mutableStateOf(\n            List(15) {\n                \"file:///uri_$it.pdf\".toUri()\n            }\n        )\n    }\n\n    var rotations by remember(files) {\n        mutableStateOf(\n            List(files.size) { 0 }\n        )\n    }\n    LazyColumn {\n        item {\n            PdfPagesRotationGrid(\n                pages = files,\n                rotations = rotations,\n                onRotateAll = {\n                    rotations = rotations.map { (it + 90) % 360 }\n                },\n                onClearAll = {\n                    rotations = rotations.map { 0 }\n                },\n                onRotateAt = {\n                    rotations = rotations.toMutableList().apply {\n                        this[it] = (this[it] + 90) % 360\n                    }\n                },\n                onAutoClick = {}\n            )\n        }\n\n        items(30) {\n            Text(\"TEST $it\")\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/rotate/screenLogic/RotatePdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass RotatePdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _rotations: MutableState<List<Int>> = mutableStateOf(emptyList())\n    val rotations by _rotations\n\n    override fun getKey(): Pair<String, Uri?> = \"rotated\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateRotations(rotations: List<Int>) {\n        registerChanges()\n        _rotations.update { rotations }\n    }\n\n    fun autoRotate() {\n        doSharing(\n            action = {\n                updateRotations(\n                    pdfManager.detectPdfAutoRotations(\n                        uri?.toString() ?: return@doSharing\n                    )\n                )\n            },\n            onFailure = {}\n        )\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.rotatePdf(\n                uri = _uri.value.toString(),\n                rotations = rotations\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.rotatePdf(\n                            uri = _uri.value.toString(),\n                            rotations = rotations\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): RotatePdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/signature/SignaturePdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.lifecycle.compose.collectAsStateWithLifecycle\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.page.PageSelectionItem\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.components.SignaturePreview\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.components.SignatureSelector\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.screenLogic.SignaturePdfToolComponent\n\n@Composable\nfun SignaturePdfToolContent(\n    component: SignaturePdfToolComponent\n) {\n    val params = component.params\n\n    val pagesCount by rememberPdfPages(component.uri)\n\n    LaunchedEffect(pagesCount, params.pages) {\n        if (pagesCount > 0 && params.pages.isEmpty()) {\n            component.updateParams(\n                params.copy(\n                    pages = List(pagesCount) { it }\n                )\n            )\n        }\n    }\n\n    val savedSignatures by component.savedSignatures.collectAsStateWithLifecycle()\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.signature),\n        actions = {},\n        imagePreview = {\n            SignaturePreview(\n                uri = component.uri,\n                params = component.params,\n                pageCount = pagesCount\n            )\n        },\n        placeImagePreview = true,\n        showImagePreviewAsStickyHeader = true,\n        controls = {\n            ImageSelector(\n                value = params.signatureImage,\n                onValueChange = component::updateSignature,\n                subtitle = stringResource(R.string.will_be_for_signature)\n            )\n            Spacer(Modifier.height(16.dp))\n            PageSelectionItem(\n                value = params.pages,\n                onValueChange = {\n                    component.updateParams(params.copy(pages = it))\n                },\n                pageCount = pagesCount\n            )\n            Spacer(Modifier.height(8.dp))\n            SignatureSelector(\n                savedSignatures = savedSignatures,\n                onSelect = {\n                    component.updateParams(params.copy(opacity = 1f))\n                    component.updateSignature(it)\n                },\n                onAdd = {\n                    component.updateSignature(\n                        data = it,\n                        save = true\n                    )\n                }\n            )\n            Spacer(Modifier.height(8.dp))\n            AlphaSelector(\n                value = params.opacity,\n                onValueChange = {\n                    component.updateParams(params.copy(opacity = it))\n                },\n                modifier = Modifier.fillMaxWidth(),\n                shape = ShapeDefaults.large\n            )\n            Spacer(Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = params.x,\n                title = stringResource(id = R.string.offset_x),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    component.updateParams(params.copy(x = it))\n                },\n                valueRange = 0f..1f,\n                shape = ShapeDefaults.large\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = params.y,\n                title = stringResource(id = R.string.offset_y),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    component.updateParams(params.copy(y = it))\n                },\n                valueRange = 0f..1f,\n                shape = ShapeDefaults.large\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = params.size,\n                title = stringResource(R.string.just_size),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    component.updateParams(params.copy(size = it))\n                },\n                valueRange = 0.01f..1f,\n                shape = ShapeDefaults.large\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/signature/components/SignatureDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.LineWeight\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.retain.retain\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.PaintingStyle\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrushColor\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.Signature\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreviewLandscape\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.scaleToFitCanvas\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.PtSaver\nimport kotlin.math.abs\n\n@Composable\nfun SignatureDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onDone: (bitmap: Bitmap) -> Unit\n) {\n    val path = retain(visible) { Path() }\n\n    var redraw by remember { mutableIntStateOf(0) }\n\n    var lastPoint by remember { mutableStateOf<Offset?>(null) }\n    var lastMid by remember { mutableStateOf<Offset?>(null) }\n\n    val borderColor = MaterialTheme.colorScheme.outlineVariant()\n\n    var canvasSize by remember {\n        mutableStateOf(IntegerSize.Zero)\n    }\n    var strokeWidth by rememberSaveable(stateSaver = PtSaver) {\n        mutableStateOf(15.pt)\n    }\n\n    var drawColor by rememberSaveable(stateSaver = ColorSaver) {\n        mutableStateOf(Color.Black)\n    }\n\n    var showTuneDialog by remember {\n        mutableStateOf(false)\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n    val screenHeight = LocalWindowInfo.current.containerDpSize.height\n    val showIconAndTitle = isPortrait || screenHeight > 500.dp\n\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        icon = if (showIconAndTitle) {\n            {\n                Icon(\n                    imageVector = Icons.Outlined.Signature,\n                    contentDescription = null\n                )\n            }\n        } else null,\n        title = if (showIconAndTitle) {\n            {\n                Text(stringResource(R.string.draw_signature))\n            }\n        } else null,\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    val size = IntegerSize(1024, 1024)\n\n                    val bitmap = ImageBitmap(size.width, size.height)\n\n                    val canvas = Canvas(bitmap)\n\n                    canvas.drawPath(\n                        path = path.scaleToFitCanvas(\n                            oldSize = canvasSize,\n                            currentSize = size\n                        ),\n                        paint = Paint().apply {\n                            color = drawColor\n                            this.strokeWidth = strokeWidth.toPx(size)\n                            style = PaintingStyle.Stroke\n                            isAntiAlias = true\n                            strokeCap = StrokeCap.Round\n                            strokeJoin = StrokeJoin.Round\n                        }\n                    )\n\n                    onDone(bitmap.asAndroidBitmap())\n\n                    path.reset()\n                    redraw++\n\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(R.string.confirm))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        text = {\n            BoxWithConstraints(\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                val min = minOf(maxWidth, maxHeight)\n                val shape = ShapeDefaults.mini\n\n                Box(\n                    modifier = Modifier\n                        .size(min)\n                        .align(Alignment.Center)\n                ) {\n                    Canvas(\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .onSizeChanged {\n                                canvasSize = IntegerSize(it.width, it.height)\n                            }\n                            .border(\n                                width = 1.dp,\n                                color = borderColor,\n                                shape = shape\n                            )\n                            .clip(shape)\n                            .transparencyChecker()\n                            .background(Color.White.copy(0.6f))\n                            .pointerInput(Unit) {\n                                awaitEachGesture {\n                                    val down = awaitFirstDown()\n\n                                    path.moveTo(down.position.x, down.position.y)\n\n                                    lastPoint = down.position\n                                    lastMid = down.position\n\n                                    redraw++\n\n                                    while (true) {\n                                        val event = awaitPointerEvent()\n                                        val change = event.changes.first()\n\n                                        if (!change.pressed) break\n                                        val point = change.position\n                                        val prev = lastPoint ?: point\n\n                                        if (\n                                            abs(point.x - prev.x) < 1f &&\n                                            abs(point.y - prev.y) < 1f\n                                        ) continue\n\n                                        val mid = Offset(\n                                            (prev.x + point.x) / 2f,\n                                            (prev.y + point.y) / 2f\n                                        )\n                                        val lastMidPoint = lastMid ?: prev\n                                        path.cubicTo(\n                                            lastMidPoint.x,\n                                            lastMidPoint.y,\n                                            prev.x,\n                                            prev.y,\n                                            mid.x,\n                                            mid.y\n                                        )\n                                        lastPoint = point\n                                        lastMid = mid\n                                        redraw++\n\n                                        change.consume()\n                                    }\n                                }\n                            }\n                    ) {\n                        redraw\n                        drawPath(\n                            path = path,\n                            color = drawColor,\n                            style = Stroke(\n                                width = strokeWidth.toPx(canvasSize),\n                                cap = StrokeCap.Round,\n                                join = StrokeJoin.Round\n                            )\n                        )\n                    }\n\n                    EnhancedIconButton(\n                        modifier = Modifier\n                            .align(Alignment.BottomStart)\n                            .offset(\n                                x = (-2).dp,\n                                y = 2.dp\n                            ),\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerHigh.copy(0.8f),\n                        enableAutoShadowAndBorder = false,\n                        onClick = {\n                            showTuneDialog = true\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Tune,\n                            contentDescription = null\n                        )\n                    }\n\n                    EnhancedIconButton(\n                        modifier = Modifier\n                            .align(Alignment.BottomEnd)\n                            .offset(\n                                x = 2.dp,\n                                y = 2.dp\n                            ),\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerHigh.copy(0.8f),\n                        enableAutoShadowAndBorder = false,\n                        onClick = {\n                            path.reset()\n                            lastPoint = null\n                            lastMid = null\n                            redraw++\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Delete,\n                            contentDescription = null\n                        )\n                    }\n                }\n            }\n        },\n        modifier = if (canvasSize != IntegerSize.Zero) {\n            Modifier.width(\n                with(LocalDensity.current) { canvasSize.width.toDp() + 48.dp }.coerceAtLeast(300.dp)\n            )\n        } else Modifier\n    )\n\n    EnhancedAlertDialog(\n        visible = showTuneDialog,\n        onDismissRequest = { showTuneDialog = false },\n        icon = {\n            Icon(Icons.Rounded.Tune, null)\n        },\n        title = {\n            Text(stringResource(R.string.pen_params))\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showTuneDialog = false\n                },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        text = {\n            Column {\n                ColorRowSelector(\n                    value = drawColor,\n                    onValueChange = { drawColor = it },\n                    modifier = Modifier\n                        .container(\n                            shape = ShapeDefaults.top\n                        ),\n                    title = stringResource(R.string.paint_color),\n                    allowAlpha = false,\n                    icon = Icons.Outlined.BrushColor\n                )\n                Spacer(Modifier.height(4.dp))\n                EnhancedSliderItem(\n                    modifier = Modifier.fillMaxWidth(),\n                    value = strokeWidth.value,\n                    icon = Icons.Rounded.LineWeight,\n                    title = stringResource(R.string.line_width),\n                    valueSuffix = \" Pt\",\n                    sliderModifier = Modifier\n                        .padding(top = 14.dp, start = 12.dp, end = 12.dp, bottom = 10.dp),\n                    valueRange = 1f..50f,\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    onValueChange = {\n                        strokeWidth = it.roundToTwoDigits().pt\n                    },\n                    shape = ShapeDefaults.bottom\n                )\n            }\n        }\n    )\n}\n\n@EnPreview\n@EnPreviewLandscape\n@Composable\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    Surface {\n        Spacer(Modifier.fillMaxSize())\n        var image by remember {\n            mutableStateOf<Bitmap?>(null)\n        }\n        var visible by remember {\n            mutableStateOf(true)\n        }\n        if (visible) {\n            SignatureDialog(\n                visible = true,\n                onDismiss = { visible = false },\n                onDone = { bmp -> image = bmp }\n            )\n        }\n\n        image?.let {\n            Image(it.asImageBitmap(), null, modifier = Modifier.background(Color.White))\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/signature/components/SignaturePreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.dp\nimport coil3.compose.AsyncImage\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toDp\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toPx\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfSignatureParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PageSwitcher\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun SignaturePreview(\n    uri: Uri?,\n    params: PdfSignatureParams,\n    pageCount: Int\n) {\n    PageSwitcher(\n        activePages = params.pages,\n        pageCount = pageCount\n    ) { page ->\n        Box(\n            modifier = Modifier\n                .container()\n                .padding(4.dp)\n                .animateContentSizeNoClip(alignment = Alignment.Center),\n            contentAlignment = Alignment.Center\n        ) {\n            var aspectRatio by rememberSaveable {\n                mutableFloatStateOf(1f)\n            }\n\n            Box(\n                modifier = Modifier.aspectRatio(aspectRatio)\n            ) {\n                Picture(\n                    model = remember(uri, page) {\n                        PdfImageRequest(\n                            data = uri,\n                            pdfPage = page\n                        )\n                    },\n                    contentScale = ContentScale.FillBounds,\n                    modifier = Modifier.matchParentSize(),\n                    onSuccess = {\n                        aspectRatio = it.result.image.safeAspectRatio\n                    },\n                    shape = MaterialTheme.shapes.medium\n                )\n\n                if (page in params.pages) {\n                    BoxWithConstraints(\n                        modifier = Modifier.matchParentSize()\n                    ) {\n                        var imageAspect by remember {\n                            mutableFloatStateOf(1f)\n                        }\n\n                        val boxWidthPx = maxWidth.toPx()\n                        val boxHeightPx = maxHeight.toPx()\n\n                        val targetWidthPx = boxWidthPx * params.size\n                        val targetHeightPx = targetWidthPx / imageAspect\n\n                        val centerXPx = boxWidthPx * params.x\n                        val centerYPx = boxHeightPx * params.y\n\n                        var offsetXPx = centerXPx - targetWidthPx / 2f\n                        var offsetYPx = centerYPx - targetHeightPx / 2f\n\n                        offsetXPx = offsetXPx.coerceIn(0f, boxWidthPx - targetWidthPx)\n                        offsetYPx = offsetYPx.coerceIn(0f, boxHeightPx - targetHeightPx)\n\n                        AsyncImage(\n                            model = params.signatureImage,\n                            contentDescription = null,\n                            modifier = Modifier\n                                .offset {\n                                    IntOffset(\n                                        x = offsetXPx.roundToInt(),\n                                        y = (boxHeightPx - offsetYPx - targetHeightPx).roundToInt()\n                                    )\n                                }\n                                .width(targetWidthPx.toDp())\n                                .aspectRatio(imageAspect)\n                                .graphicsLayer {\n                                    alpha = params.opacity\n                                },\n                            contentScale = ContentScale.Fit,\n                            onSuccess = {\n                                imageAspect = it.result.image.safeAspectRatio\n                            }\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/signature/components/SignatureSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.components\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AddCircleOutline\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Signature\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.EnPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun SignatureSelector(\n    savedSignatures: List<String>,\n    onAdd: (Any) -> Unit,\n    onSelect: (Any) -> Unit\n) {\n    var isDrawingVisible by remember {\n        mutableStateOf(false)\n    }\n\n    PreferenceItem(\n        shape = ShapeDefaults.large,\n        onClick = { isDrawingVisible = true },\n        title = stringResource(R.string.draw_signature),\n        subtitle = stringResource(R.string.draw_signature_sub),\n        startIcon = Icons.Outlined.Signature,\n        endIcon = Icons.Rounded.AddCircleOutline,\n        modifier = Modifier.fillMaxWidth(),\n        bottomContent = if (savedSignatures.isNotEmpty()) {\n            {\n                val shape = ShapeDefaults.mini\n                LazyRow(\n                    contentPadding = PaddingValues(\n                        start = 16.dp,\n                        end = 16.dp,\n                        bottom = 16.dp\n                    ),\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    items(savedSignatures) { signature ->\n                        Picture(\n                            model = signature,\n                            modifier = Modifier\n                                .size(40.dp)\n                                .border(\n                                    width = 1.dp,\n                                    color = MaterialTheme.colorScheme.outlineVariant(),\n                                    shape = shape\n                                )\n                                .clip(shape)\n                                .transparencyChecker(\n                                    checkerWidth = 6.dp,\n                                    checkerHeight = 6.dp\n                                )\n                                .background(Color.White.copy(0.4f))\n                                .hapticsClickable {\n                                    onSelect(signature)\n                                },\n                            showTransparencyChecker = false,\n                            shape = RectangleShape\n                        )\n                    }\n                }\n            }\n        } else null\n    )\n\n    SignatureDialog(\n        visible = isDrawingVisible,\n        onDismiss = { isDrawingVisible = false },\n        onDone = onAdd\n    )\n}\n\n@Composable\n@EnPreview\nprivate fun Preview() = ImageToolboxThemeForPreview(false) {\n    SignatureSelector(\n        savedSignatures = List(10) { \"qwqw\" },\n        onSelect = {},\n        onAdd = {}\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/signature/screenLogic/SignaturePdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfSignatureParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.distinctUntilChanged\n\nclass SignaturePdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _params: MutableState<PdfSignatureParams> =\n        mutableStateOf(PdfSignatureParams())\n    val params by _params\n\n    val savedSignatures = pdfManager.savedSignatures\n\n    override fun getKey(): Pair<String, Uri?> = \"signed\" to uri\n\n    init {\n        componentScope.launch {\n            snapshotFlow { uri }\n                .distinctUntilChanged()\n                .collect {\n                    _params.update { it.copy(pages = emptyList()) }\n                }\n        }\n    }\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateParams(params: PdfSignatureParams) {\n        registerChanges()\n        _params.update { params }\n    }\n\n    fun updateSignature(\n        data: Any,\n        save: Boolean = false\n    ) {\n        registerChanges()\n        _params.update {\n            it.copy(\n                signatureImage = data\n            )\n        }\n        if (save) {\n            updateParams(params.copy(opacity = 1f))\n            componentScope.launch {\n                pdfManager.saveSignature(data)\n            }\n        }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.addSignature(\n                uri = _uri.value.toString(),\n                params = params\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.addSignature(\n                            uri = _uri.value.toString(),\n                            params = params\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): SignaturePdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/split/SplitPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.page.PageSelectionItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagesPreviewWithSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.screenLogic.SplitPdfToolComponent\n\n@Composable\nfun SplitPdfToolContent(\n    component: SplitPdfToolComponent\n) {\n    val pagesCount by rememberPdfPages(component.uri)\n    val selectedPagesSize = component.pages?.size ?: 0\n    val isPortrait by isPortraitOrientationAsState()\n\n    var trigger by remember {\n        mutableIntStateOf(0)\n    }\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.split_pdf),\n        topAppBarPersistentActions = {\n            AnimatedVisibility(\n                visible = selectedPagesSize != pagesCount,\n                enter = fadeIn() + scaleIn() + expandHorizontally(),\n                exit = fadeOut() + scaleOut() + shrinkHorizontally()\n            ) {\n                EnhancedIconButton(\n                    onClick = {\n                        component.updatePages(\n                            List(pagesCount) { it }\n                        )\n                        trigger++\n                    }\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.SelectAll,\n                        contentDescription = \"Select All\"\n                    )\n                }\n            }\n            AnimatedVisibility(\n                modifier = Modifier\n                    .padding(8.dp)\n                    .container(\n                        shape = ShapeDefaults.circle,\n                        color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                        resultPadding = 0.dp\n                    ),\n                visible = selectedPagesSize != 0\n            ) {\n                Row(\n                    modifier = Modifier.padding(start = 12.dp),\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.Center\n                ) {\n                    selectedPagesSize.takeIf { it != 0 }?.let {\n                        Spacer(Modifier.width(8.dp))\n                        Text(\n                            text = selectedPagesSize.toString(),\n                            fontSize = 20.sp,\n                            fontWeight = FontWeight.Medium\n                        )\n                    }\n                    EnhancedIconButton(\n                        onClick = {\n                            component.updatePages(emptyList())\n                            trigger++\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Close,\n                            contentDescription = stringResource(R.string.close)\n                        )\n                    }\n                }\n            }\n        },\n        canSave = !component.pages.isNullOrEmpty(),\n        actions = {},\n        imagePreview = {\n            key(trigger, pagesCount, component.uri) {\n                ImagesPreviewWithSelection(\n                    imageUris = remember(pagesCount, component.uri) {\n                        List(pagesCount) {\n                            PdfImageRequest(\n                                data = component.uri,\n                                pdfPage = it\n                            )\n                        }\n                    },\n                    imageFrames = remember(component.pages) {\n                        ImageFrames.ManualSelection(\n                            component.pages.orEmpty().map { it + 1 }\n                        )\n                    },\n                    onFrameSelectionChange = { frames ->\n                        component.updatePages(\n                            frames.getFramePositions(pagesCount).map { it - 1 }\n                        )\n                    },\n                    isPortrait = isPortrait,\n                    isLoadingImages = false\n                )\n            }\n        },\n        placeImagePreview = true,\n        showImagePreviewAsStickyHeader = false,\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            PageSelectionItem(\n                value = component.pages,\n                onValueChange = {\n                    component.updatePages(it)\n                    trigger++\n                },\n                pageCount = pagesCount\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/split/screenLogic/SplitPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.distinctUntilChanged\n\nclass SplitPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _pages: MutableState<List<Int>?> = mutableStateOf(null)\n    val pages by _pages\n\n    init {\n        componentScope.launch {\n            snapshotFlow { uri }\n                .distinctUntilChanged()\n                .collect {\n                    _pages.update { null }\n                }\n        }\n    }\n\n    override fun getKey(): Pair<String, Uri?> = \"split\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updatePages(pages: List<Int>) {\n        registerChanges()\n        _pages.update { pages }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.splitPdf(\n                uri = _uri.value.toString(),\n                pages = pages\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.splitPdf(\n                            uri = _uri.value.toString(),\n                            pages = pages\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): SplitPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/unlock/UnlockPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.CheckCircle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.Green\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContentColor\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.screenLogic.UnlockPdfToolComponent\n\n@Composable\nfun UnlockPdfToolContent(\n    component: UnlockPdfToolComponent\n) {\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.unlock_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            AnimatedVisibility(\n                visible = rememberPdfPages(component.uri).value != 0,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                val containerColor = Green.blend(\n                    color = Color.Black,\n                    fraction = 0.4f\n                )\n\n                val contentColor = containerColor.inverse(\n                    fraction = { 1f },\n                    darkMode = true\n                )\n\n                CompositionLocalProvider(\n                    LocalIconShapeContentColor provides contentColor,\n                    LocalIconShapeContainerColor provides containerColor.blend(\n                        color = Color.Black,\n                        fraction = 0.15f\n                    )\n                ) {\n                    PreferenceItem(\n                        title = stringResource(R.string.success),\n                        subtitle = stringResource(R.string.pdf_unlocked),\n                        startIcon = Icons.Outlined.CheckCircle,\n                        contentColor = contentColor,\n                        containerColor = containerColor,\n                        overrideIconShapeContentColor = true,\n                        modifier = Modifier.fillMaxWidth(),\n                        onClick = null\n                    )\n                }\n            }\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/unlock/screenLogic/UnlockPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass UnlockPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _password: MutableState<String> = mutableStateOf(\"\")\n    val password by _password\n\n    override fun getKey(): Pair<String, Uri?> = \"unlocked\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    override fun setPassword(password: String) {\n        _password.update { password }\n        _showPasswordRequestDialog.update { false }\n        pdfManager.setMasterPassword(password)\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.unlockPdf(\n                uri = _uri.value.toString(),\n                password = password\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.unlockPdf(\n                            uri = _uri.value.toString(),\n                            password = password\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): UnlockPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/watermark/WatermarkPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.TextRotationAngleup\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.page.PageSelectionItem\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.components.WatermarkPreview\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.screenLogic.WatermarkPdfToolComponent\nimport kotlin.math.roundToInt\n\n@Composable\nfun WatermarkPdfToolContent(\n    component: WatermarkPdfToolComponent\n) {\n    val params = component.params\n\n    val pagesCount by rememberPdfPages(component.uri)\n\n    LaunchedEffect(pagesCount, params.pages) {\n        if (pagesCount > 0 && params.pages.isEmpty()) {\n            component.updateParams(\n                params.copy(\n                    pages = List(pagesCount) { it }\n                )\n            )\n        }\n    }\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.watermarking),\n        actions = {},\n        imagePreview = {\n            WatermarkPreview(\n                uri = component.uri,\n                params = params,\n                pageCount = pagesCount\n            )\n        },\n        placeImagePreview = true,\n        showImagePreviewAsStickyHeader = true,\n        controls = {\n            RoundedTextField(\n                modifier = Modifier\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp\n                    ),\n                value = params.text,\n                keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),\n                singleLine = false,\n                onValueChange = {\n                    component.updateParams(params.copy(text = it))\n                },\n                label = {\n                    Text(stringResource(R.string.text))\n                }\n            )\n            Spacer(Modifier.height(16.dp))\n            PageSelectionItem(\n                value = params.pages,\n                onValueChange = {\n                    component.updateParams(params.copy(pages = it))\n                },\n                pageCount = pagesCount\n            )\n            Spacer(Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = params.rotation,\n                icon = Icons.Outlined.TextRotationAngleup,\n                title = stringResource(id = R.string.angle),\n                valueRange = 0f..360f,\n                internalStateTransformation = Float::roundToInt,\n                onValueChange = {\n                    component.updateParams(params.copy(rotation = it))\n                },\n                shape = ShapeDefaults.large\n            )\n            Spacer(Modifier.height(8.dp))\n            AlphaSelector(\n                value = params.opacity,\n                onValueChange = {\n                    component.updateParams(params.copy(opacity = it))\n                },\n                modifier = Modifier.fillMaxWidth(),\n                shape = ShapeDefaults.large\n            )\n            Spacer(Modifier.height(8.dp))\n            EnhancedSliderItem(\n                value = params.fontSize,\n                title = stringResource(R.string.watermark_size),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    component.updateParams(params.copy(fontSize = it))\n                },\n                valueRange = 5f..100f,\n                shape = ShapeDefaults.large\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            ColorRowSelector(\n                value = params.color.toColor(),\n                onValueChange = {\n                    component.updateParams(params.copy(color = it.toArgb()))\n                },\n                title = stringResource(R.string.text_color),\n                modifier = Modifier.container(\n                    shape = ShapeDefaults.large\n                ),\n                allowAlpha = false\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/watermark/components/WatermarkPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.data.coil.PdfImageRequest\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfWatermarkParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PageSwitcher\n\n@Composable\ninternal fun WatermarkPreview(\n    uri: Uri?,\n    params: PdfWatermarkParams,\n    pageCount: Int\n) {\n    PageSwitcher(\n        activePages = params.pages,\n        pageCount = pageCount\n    ) { page ->\n        Box(\n            modifier = Modifier\n                .container()\n                .padding(4.dp)\n                .animateContentSizeNoClip(\n                    alignment = Alignment.Center\n                ),\n            contentAlignment = Alignment.Center\n        ) {\n            var aspectRatio by rememberSaveable {\n                mutableFloatStateOf(1f)\n            }\n\n            Box(\n                modifier = Modifier.aspectRatio(aspectRatio)\n            ) {\n                Picture(\n                    model = remember(uri, page) {\n                        PdfImageRequest(\n                            data = uri,\n                            pdfPage = page\n                        )\n                    },\n                    contentScale = ContentScale.FillBounds,\n                    modifier = Modifier.matchParentSize(),\n                    onSuccess = {\n                        aspectRatio = it.result.image.safeAspectRatio\n                    },\n                    shape = MaterialTheme.shapes.medium\n                )\n\n                if (page in params.pages) {\n                    BoxWithConstraints(\n                        modifier = Modifier.matchParentSize()\n                    ) {\n                        val scaledFontSize = remember(\n                            params.fontSize,\n                            maxWidth\n                        ) {\n                            val scaleFactor = maxWidth.value / 300f\n                            (params.fontSize * scaleFactor).sp\n                        }\n\n                        AutoSizeText(\n                            key = { maxWidth },\n                            text = params.text,\n                            modifier = Modifier\n                                .align(Alignment.Center)\n                                .graphicsLayer {\n                                    rotationZ = params.rotation\n                                    alpha = params.opacity\n                                },\n                            color = Color(params.color),\n                            style = MaterialTheme.typography.bodyMedium.copy(\n                                fontSize = scaledFontSize\n                            )\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/watermark/screenLogic/WatermarkPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.PdfWatermarkParams\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.flow.distinctUntilChanged\n\nclass WatermarkPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _params: MutableState<PdfWatermarkParams> =\n        mutableStateOf(PdfWatermarkParams(color = Color.Gray.toArgb()))\n    val params by _params\n\n    init {\n        componentScope.launch {\n            snapshotFlow { uri }\n                .distinctUntilChanged()\n                .collect {\n                    _params.update { it.copy(pages = emptyList()) }\n                }\n        }\n    }\n\n    override fun getKey(): Pair<String, Uri?> = \"watermarked\" to uri\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateParams(params: PdfWatermarkParams) {\n        registerChanges()\n        _params.update { params }\n    }\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.addWatermark(\n                uri = _uri.value.toString(),\n                params = params\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.addWatermark(\n                            uri = _uri.value.toString(),\n                            params = params\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): WatermarkPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/zip_convert/ZipConvertPdfToolContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastCoerceAtLeast\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.rememberPdfPages\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.PdfPreviewItem\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.screenLogic.ZipConvertPdfToolComponent\nimport kotlin.math.roundToInt\n\n@Composable\nfun ZipConvertPdfToolContent(\n    component: ZipConvertPdfToolComponent\n) {\n    val pagesCount by rememberPdfPages(component.uri)\n\n    BasePdfToolContent(\n        component = component,\n        contentPicker = rememberFilePicker(\n            mimeType = MimeType.Pdf,\n            onSuccess = component::setUri\n        ),\n        isPickedAlready = component.initialUri != null,\n        canShowScreenData = component.uri != null,\n        title = stringResource(R.string.zip_pdf),\n        controls = {\n            component.uri?.let {\n                PdfPreviewItem(\n                    uri = it,\n                    onRemove = {\n                        component.setUri(null)\n                    }\n                )\n                Spacer(Modifier.height(16.dp))\n            }\n\n            EnhancedSliderItem(\n                value = component.interval,\n                title = stringResource(R.string.interval),\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                onValueChange = {\n                    component.updateInterval(it.roundToInt())\n                },\n                valueRange = 1f..pagesCount.fastCoerceAtLeast(1).toFloat(),\n                shape = ShapeDefaults.large\n            )\n        },\n        onFilledPassword = {\n            component.setUri(component.uri)\n        }\n    )\n}\n"
  },
  {
    "path": "feature/pdf-tools/src/main/java/com/t8rin/imagetoolbox/feature/pdf_tools/presentation/zip_convert/screenLogic/ZipConvertPdfToolComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.common.BasePdfToolComponent\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass ZipConvertPdfToolComponent @AssistedInject internal constructor(\n    @Assisted val initialUri: Uri?,\n    @Assisted componentContext: ComponentContext,\n    @Assisted onGoBack: () -> Unit,\n    @Assisted onNavigate: (Screen) -> Unit,\n    private val pdfManager: PdfManager,\n    private val fileController: FileController,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : BasePdfToolComponent(\n    onGoBack = onGoBack,\n    onNavigate = onNavigate,\n    dispatchersHolder = dispatchersHolder,\n    componentContext = componentContext,\n    pdfManager = pdfManager\n) {\n    override val _haveChanges: MutableState<Boolean> = mutableStateOf(initialUri != null)\n    override val haveChanges: Boolean by _haveChanges\n\n    override val extraDataType: ExtraDataType = ExtraDataType.File\n    override val mimeType: MimeType.Single = MimeType.Zip\n\n    private val _uri: MutableState<Uri?> = mutableStateOf(initialUri)\n    val uri by _uri\n\n    private val _interval: MutableState<Int> = mutableIntStateOf(1)\n    val interval by _interval\n\n    fun setUri(uri: Uri?) {\n        if (uri == null) {\n            registerChangesCleared()\n        } else {\n            registerChanges()\n        }\n        _uri.update { uri }\n        checkPdf(\n            uri = uri,\n            onDecrypted = { _uri.value = it }\n        )\n    }\n\n    fun updateInterval(interval: Int) {\n        registerChanges()\n        _interval.update { interval }\n    }\n\n    override fun createTargetFilename(): String =\n        \"${uri?.filename()?.substringBeforeLast('.') ?: timestamp()}.zip\"\n\n    override fun saveTo(\n        uri: Uri\n    ) {\n        doSaving {\n            val processed = pdfManager.convertToZip(\n                uri = _uri.value.toString(),\n                interval = interval\n            )\n\n            fileController.transferBytes(\n                fromUri = processed,\n                toUri = uri.toString()\n            ).onSuccess(::registerSave)\n        }\n    }\n\n    override fun performSharing(\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        prepareForSharing(\n            onSuccess = {\n                shareProvider.shareUris(it.map(Uri::toString))\n                registerSave()\n                onSuccess()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    override fun prepareForSharing(\n        onSuccess: suspend (List<Uri>) -> Unit,\n        onFailure: (Throwable) -> Unit\n    ) {\n        doSharing(\n            action = {\n                onSuccess(\n                    listOf(\n                        pdfManager.convertToZip(\n                            uri = _uri.value.toString(),\n                            interval = interval\n                        ).toUri()\n                    )\n                )\n                registerSave()\n            },\n            onFailure = onFailure\n        )\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            initialUri: Uri?,\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ZipConvertPdfToolComponent\n    }\n}"
  },
  {
    "path": "feature/pick-color/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/pick-color/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.pick_color\""
  },
  {
    "path": "feature/pick-color/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/pick-color/src/main/java/com/t8rin/imagetoolbox/feature/pick_color/presentation/PickColorFromImageContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pick_color.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.statusBarsPadding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ZoomIn\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageBottomAppBar\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageContentImpl\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageTopAppBar\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.screenLogic.PickColorFromImageComponent\nimport kotlinx.coroutines.launch\n\n@Composable\nfun PickColorFromImageContent(\n    component: PickColorFromImageComponent\n) {\n    val settingsState = LocalSettingsState.current\n\n    val scope = rememberCoroutineScope()\n\n    var panEnabled by rememberSaveable { mutableStateOf(false) }\n\n    AutoContentBasedColors(component.bitmap)\n    AutoContentBasedColors(component.color)\n\n    val imagePicker = rememberImagePicker { uri: Uri ->\n        component.setUri(\n            uri = uri\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val switch = @Composable {\n        PanModeButton(\n            selected = panEnabled,\n            onClick = { panEnabled = !panEnabled }\n        )\n    }\n\n    val magnifierButton = @Composable {\n        val settingsInteractor = LocalSimpleSettingsInteractor.current\n        EnhancedIconButton(\n            containerColor = takeColorFromScheme {\n                if (settingsState.magnifierEnabled) {\n                    secondary\n                } else surfaceContainer\n            },\n            contentColor = takeColorFromScheme {\n                if (settingsState.magnifierEnabled) {\n                    onSecondary\n                } else onSurface\n            },\n            enableAutoShadowAndBorder = false,\n            onClick = {\n                scope.launch {\n                    settingsInteractor.toggleMagnifierEnabled()\n                }\n            },\n            modifier = Modifier.statusBarsPadding()\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.ZoomIn,\n                contentDescription = stringResource(R.string.magnifier)\n            )\n        }\n    }\n\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    Box {\n        Scaffold(\n            modifier = Modifier\n                .fillMaxSize()\n                .nestedScroll(scrollBehavior.nestedScrollConnection),\n            topBar = {\n                PickColorFromImageTopAppBar(\n                    bitmap = component.bitmap,\n                    scrollBehavior = scrollBehavior,\n                    onGoBack = component.onGoBack,\n                    isPortrait = isPortrait,\n                    magnifierButton = magnifierButton,\n                    color = component.color\n                )\n            },\n            bottomBar = {\n                PickColorFromImageBottomAppBar(\n                    bitmap = component.bitmap,\n                    isPortrait = isPortrait,\n                    switch = switch,\n                    color = component.color,\n                    onPickImage = pickImage,\n                    onOneTimePickImage = { showOneTimeImagePickingDialog = true },\n                )\n            },\n            contentWindowInsets = WindowInsets()\n        ) { contentPadding ->\n            PickColorFromImageContentImpl(\n                bitmap = component.bitmap,\n                isPortrait = isPortrait,\n                panEnabled = panEnabled,\n                onColorChange = component::updateColor,\n                onPickImage = pickImage,\n                onOneTimePickImage = { showOneTimeImagePickingDialog = true },\n                magnifierButton = magnifierButton,\n                switch = switch,\n                color = component.color,\n                contentPadding = contentPadding\n            )\n        }\n\n        if (component.bitmap == null) {\n            EnhancedFloatingActionButton(\n                onClick = pickImage,\n                onLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                modifier = Modifier\n                    .navigationBarsPadding()\n                    .padding(16.dp)\n                    .align(settingsState.fabAlignment)\n            ) {\n                Spacer(Modifier.width(16.dp))\n                Icon(\n                    imageVector = Icons.Rounded.AddPhotoAlt,\n                    contentDescription = stringResource(R.string.pick_image_alt)\n                )\n                Spacer(Modifier.width(16.dp))\n                Text(stringResource(R.string.pick_image_alt))\n                Spacer(Modifier.width(16.dp))\n            }\n        }\n    }\n\n    OneTimeImagePickingDialog(\n        onDismiss = { showOneTimeImagePickingDialog = false },\n        picker = Picker.Single,\n        imagePicker = imagePicker,\n        visible = showOneTimeImagePickingDialog\n    )\n\n    LoadingDialog(\n        visible = component.isImageLoading,\n        canCancel = false\n    )\n}"
  },
  {
    "path": "feature/pick-color/src/main/java/com/t8rin/imagetoolbox/feature/pick_color/presentation/components/PickColorFromImageBottomAppBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pick_color.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.BottomAppBar\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.parser.ColorNameParser\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\n\n@Composable\ninternal fun PickColorFromImageBottomAppBar(\n    bitmap: Bitmap?,\n    isPortrait: Boolean,\n    switch: @Composable () -> Unit,\n    onOneTimePickImage: () -> Unit,\n    onPickImage: () -> Unit,\n    color: Color,\n) {\n    AnimatedVisibility(\n        visible = bitmap != null && isPortrait,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        val text by remember(color) {\n            derivedStateOf {\n                ColorNameParser.parseColorName(color)\n            }\n        }\n\n        BottomAppBar(\n            modifier = Modifier\n                .drawHorizontalStroke(true),\n            actions = {\n                switch()\n                Spacer(Modifier.width(16.dp))\n                Text(\n                    modifier = Modifier\n                        .weight(1f)\n                        .padding(2.dp),\n                    text = text,\n                    textAlign = TextAlign.Center\n                )\n            },\n            floatingActionButton = {\n                EnhancedFloatingActionButton(\n                    onClick = onPickImage,\n                    onLongClick = onOneTimePickImage\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.AddPhotoAlt,\n                        contentDescription = stringResource(R.string.pick_image_alt)\n                    )\n                }\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/pick-color/src/main/java/com/t8rin/imagetoolbox/feature/pick_color/presentation/components/PickColorFromImageContentImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pick_color.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.ImageColorDetector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\ninternal fun PickColorFromImageContentImpl(\n    bitmap: Bitmap?,\n    isPortrait: Boolean,\n    panEnabled: Boolean,\n    onColorChange: (Color) -> Unit,\n    onPickImage: () -> Unit,\n    magnifierButton: @Composable () -> Unit,\n    switch: @Composable () -> Unit,\n    onOneTimePickImage: () -> Unit,\n    color: Color,\n    contentPadding: PaddingValues\n) {\n    val settingsState = LocalSettingsState.current\n\n    Box(\n        modifier = Modifier\n            .fillMaxSize()\n            .padding(contentPadding)\n    ) {\n        bitmap?.let {\n            if (isPortrait) {\n                AnimatedContent(\n                    targetState = it\n                ) { bitmap ->\n                    ImageColorDetector(\n                        panEnabled = panEnabled,\n                        imageBitmap = bitmap.asImageBitmap(),\n                        color = color,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .padding(16.dp)\n                            .windowInsetsPadding(\n                                WindowInsets.navigationBars\n                                    .only(WindowInsetsSides.Bottom)\n                                    .union(WindowInsets.displayCutout)\n                            )\n                            .container(resultPadding = 8.dp)\n                            .clip(\n                                ShapeDefaults.small\n                            )\n                            .transparencyChecker(),\n                        isMagnifierEnabled = settingsState.magnifierEnabled,\n                        onColorChange = onColorChange\n                    )\n                }\n            } else {\n                Row {\n                    Box(\n                        modifier = Modifier.weight(0.8f)\n                    ) {\n                        Box(Modifier.align(Alignment.Center)) {\n                            AnimatedContent(\n                                targetState = it\n                            ) { bitmap ->\n                                val direction = LocalLayoutDirection.current\n                                ImageColorDetector(\n                                    panEnabled = panEnabled,\n                                    imageBitmap = bitmap.asImageBitmap(),\n                                    color = color,\n                                    modifier = Modifier\n                                        .fillMaxSize()\n                                        .padding(20.dp)\n                                        .windowInsetsPadding(\n                                            WindowInsets.navigationBars\n                                                .only(WindowInsetsSides.Bottom)\n                                                .union(WindowInsets.displayCutout)\n                                        )\n                                        .padding(\n                                            start = WindowInsets\n                                                .displayCutout\n                                                .asPaddingValues()\n                                                .calculateStartPadding(direction)\n                                        )\n                                        .container(resultPadding = 8.dp)\n                                        .clip(ShapeDefaults.small)\n                                        .transparencyChecker(),\n                                    isMagnifierEnabled = settingsState.magnifierEnabled,\n                                    onColorChange = onColorChange\n                                )\n                            }\n                        }\n                    }\n                    val direction = LocalLayoutDirection.current\n                    Column(\n                        modifier = Modifier\n                            .container(\n                                shape = RectangleShape,\n                                resultPadding = 0.dp\n                            )\n                            .fillMaxHeight()\n                            .padding(horizontal = 20.dp)\n                            .padding(\n                                end = WindowInsets.displayCutout\n                                    .asPaddingValues()\n                                    .calculateEndPadding(direction)\n                            )\n                            .navigationBarsPadding(),\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        magnifierButton()\n                        Spacer(modifier = Modifier.height(8.dp))\n                        switch()\n                        Spacer(modifier = Modifier.height(8.dp))\n                        EnhancedFloatingActionButton(\n                            onClick = onPickImage,\n                            onLongClick = onOneTimePickImage\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.AddPhotoAlt,\n                                contentDescription = stringResource(R.string.pick_image_alt)\n                            )\n                        }\n                    }\n                }\n            }\n        } ?: Column(\n            modifier = Modifier\n                .fillMaxWidth()\n                .enhancedVerticalScroll(rememberScrollState()),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            ImageNotPickedWidget(\n                onPickImage = onPickImage,\n                modifier = Modifier\n                    .padding(bottom = 88.dp, top = 20.dp, start = 20.dp, end = 20.dp)\n                    .navigationBarsPadding()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/pick-color/src/main/java/com/t8rin/imagetoolbox/feature/pick_color/presentation/components/PickColorFromImageSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pick_color.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.ImageColorDetector\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shimmer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\n\n@Composable\nfun PickColorFromImageSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    bitmap: Bitmap?,\n    onColorChange: (Color) -> Unit,\n    color: Color\n) {\n    val settingsState = LocalSettingsState.current\n    var panEnabled by rememberSaveable { mutableStateOf(false) }\n\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Column(\n                modifier = Modifier.navigationBarsPadding()\n            ) {\n                remember(bitmap) { bitmap?.asImageBitmap() }?.let {\n                    ImageColorDetector(\n                        panEnabled = panEnabled,\n                        color = color,\n                        imageBitmap = it,\n                        onColorChange = onColorChange,\n                        isMagnifierEnabled = settingsState.magnifierEnabled,\n                        boxModifier = Modifier\n                            .weight(1f)\n                            .fillMaxWidth()\n                            .padding(horizontal = 16.dp)\n                            .container(\n                                shape = ShapeDefaults.extraSmall,\n                                color = MaterialTheme.colorScheme\n                                    .outlineVariant()\n                                    .copy(alpha = 0.1f),\n                                resultPadding = 0.dp\n                            )\n                            .transparencyChecker()\n                    )\n                } ?: Box(\n                    modifier = Modifier\n                        .weight(1f)\n                        .fillMaxWidth()\n                        .padding(horizontal = 16.dp)\n                        .container(\n                            shape = ShapeDefaults.extraSmall,\n                            color = MaterialTheme.colorScheme\n                                .outlineVariant()\n                                .copy(alpha = 0.1f),\n                            resultPadding = 0.dp\n                        )\n                        .shimmer(true)\n                )\n\n                Row(\n                    modifier = Modifier.padding(16.dp),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically,\n                            modifier = Modifier\n                                .padding(end = 16.dp)\n                                .container(\n                                    color = MaterialTheme.colorScheme.surfaceContainerHighest\n                                )\n                                .padding(4.dp)\n                        ) {\n                            Box(\n                                modifier = Modifier\n                                    .padding(end = 16.dp)\n                                    .background(\n                                        color = animateColorAsState(color).value,\n                                        shape = ShapeDefaults.small\n                                    )\n                                    .size(40.dp)\n                                    .border(\n                                        width = settingsState.borderWidth,\n                                        color = MaterialTheme.colorScheme.outlineVariant(\n                                            onTopOf = animateColorAsState(color).value\n                                        ),\n                                        shape = ShapeDefaults.small\n                                    )\n                                    .clip(ShapeDefaults.small)\n                                    .hapticsClickable {\n                                        Clipboard.copy(\n                                            text = color.toHex(),\n                                            message = R.string.color_copied\n                                        )\n                                    },\n                                contentAlignment = Alignment.Center\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.ContentCopy,\n                                    contentDescription = stringResource(R.string.copy),\n                                    tint = animateColorAsState(\n                                        color.inverse(\n                                            fraction = { cond ->\n                                                if (cond) 0.8f\n                                                else 0.5f\n                                            },\n                                            darkMode = color.luminance() < 0.3f\n                                        )\n                                    ).value,\n                                    modifier = Modifier.size(20.dp)\n                                )\n                            }\n\n                            Text(\n                                modifier = Modifier\n                                    .clip(ShapeDefaults.mini)\n                                    .hapticsClickable {\n                                        Clipboard.copy(\n                                            text = color.toHex(),\n                                            message = R.string.color_copied\n                                        )\n                                    }\n                                    .background(MaterialTheme.colorScheme.secondaryContainer)\n                                    .border(\n                                        width = settingsState.borderWidth,\n                                        color = MaterialTheme.colorScheme.outlineVariant(\n                                            onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                                        ),\n                                        shape = ShapeDefaults.mini\n                                    )\n                                    .padding(horizontal = 8.dp),\n                                text = color.toHex(),\n                                style = LocalTextStyle.current.copy(\n                                    fontWeight = FontWeight.Bold,\n                                    color = MaterialTheme.colorScheme.onSecondaryContainer\n                                )\n                            )\n                        }\n                    }\n                    Spacer(Modifier.weight(1f))\n                    PanModeButton(\n                        selected = panEnabled,\n                        onClick = { panEnabled = !panEnabled }\n                    )\n                }\n            }\n        },\n        dragHandle = {\n            EnhancedModalSheetDragHandle(\n                color = Color.Transparent,\n                drawStroke = false,\n                heightWhenDisabled = 20.dp\n            )\n        },\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        }\n    )\n}"
  },
  {
    "path": "feature/pick-color/src/main/java/com/t8rin/imagetoolbox/feature/pick_color/presentation/components/PickColorFromImageTopAppBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pick_color.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.statusBarsPadding\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.parser.ColorNameParser\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toHex\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\ninternal fun PickColorFromImageTopAppBar(\n    bitmap: Bitmap?,\n    scrollBehavior: TopAppBarScrollBehavior,\n    onGoBack: () -> Unit,\n    isPortrait: Boolean,\n    magnifierButton: @Composable () -> Unit,\n    color: Color,\n) {\n    val settingsState = LocalSettingsState.current\n\n    AnimatedContent(\n        modifier = Modifier.drawHorizontalStroke(),\n        targetState = bitmap == null,\n        transitionSpec = { fadeIn() togetherWith fadeOut() }\n    ) { noBmp ->\n        if (noBmp) {\n            EnhancedTopAppBar(\n                type = EnhancedTopAppBarType.Large,\n                scrollBehavior = scrollBehavior,\n                drawHorizontalStroke = false,\n                navigationIcon = {\n                    EnhancedIconButton(\n                        onClick = onGoBack\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                            contentDescription = stringResource(R.string.exit)\n                        )\n                    }\n                },\n                title = {\n                    Text(\n                        text = stringResource(R.string.pick_color),\n                        modifier = Modifier.marquee()\n                    )\n                },\n                actions = {\n                    if (bitmap == null) {\n                        TopAppBarEmoji()\n                    }\n                }\n            )\n        } else {\n            Surface(\n                color = MaterialTheme.colorScheme.surfaceContainer,\n                modifier = Modifier.animateContentSizeNoClip(),\n            ) {\n                Column {\n                    Column(\n                        modifier = Modifier.windowInsetsPadding(\n                            WindowInsets.navigationBars\n                                .only(WindowInsetsSides.End)\n                                .union(WindowInsets.displayCutout)\n                        )\n                    ) {\n                        Spacer(modifier = Modifier.height(8.dp))\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically\n                        ) {\n                            Row {\n                                EnhancedIconButton(\n                                    onClick = onGoBack,\n                                    modifier = Modifier.statusBarsPadding()\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit)\n                                    )\n                                }\n                                if (isPortrait) {\n                                    Spacer(modifier = Modifier.weight(1f))\n                                    magnifierButton()\n                                    Spacer(modifier = Modifier.width(4.dp))\n                                }\n                            }\n                            if (!isPortrait) {\n                                ProvideTextStyle(\n                                    value = LocalTextStyle.current.merge(\n                                        MaterialTheme.typography.headlineSmall\n                                    )\n                                ) {\n                                    Row(\n                                        verticalAlignment = Alignment.CenterVertically,\n                                        modifier = Modifier\n                                            .padding(\n                                                start = 16.dp,\n                                                end = 16.dp\n                                            )\n                                            .statusBarsPadding()\n                                    ) {\n                                        Text(stringResource(R.string.color))\n\n                                        Text(\n                                            modifier = Modifier\n                                                .padding(horizontal = 8.dp)\n                                                .clip(ShapeDefaults.mini)\n                                                .hapticsClickable {\n                                                    Clipboard.copy(\n                                                        text = color.toHex(),\n                                                        message = R.string.color_copied\n                                                    )\n                                                }\n                                                .background(MaterialTheme.colorScheme.secondaryContainer)\n                                                .border(\n                                                    width = settingsState.borderWidth,\n                                                    color = MaterialTheme.colorScheme.outlineVariant(\n                                                        onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                                                    ),\n                                                    shape = ShapeDefaults.mini\n                                                )\n                                                .padding(horizontal = 6.dp),\n                                            text = color.toHex(),\n                                            style = LocalTextStyle.current.copy(\n                                                fontWeight = FontWeight.Bold,\n                                                color = MaterialTheme.colorScheme.onSecondaryContainer\n                                            )\n                                        )\n\n                                        Text(\n                                            modifier = Modifier\n                                                .weight(1f)\n                                                .padding(2.dp),\n                                            text = remember(color) {\n                                                derivedStateOf {\n                                                    ColorNameParser.parseColorName(color)\n                                                }\n                                            }.value\n                                        )\n\n                                        Box(\n                                            Modifier\n                                                .padding(\n                                                    vertical = 4.dp,\n                                                    horizontal = 16.dp\n                                                )\n                                                .background(\n                                                    color = animateColorAsState(color).value,\n                                                    shape = ShapeDefaults.small\n                                                )\n                                                .height(40.dp)\n                                                .width(72.dp)\n                                                .border(\n                                                    width = settingsState.borderWidth,\n                                                    color = MaterialTheme.colorScheme.outlineVariant(\n                                                        onTopOf = animateColorAsState(color).value\n                                                    ),\n                                                    shape = ShapeDefaults.small\n                                                )\n                                                .clip(ShapeDefaults.small)\n                                                .hapticsClickable {\n                                                    Clipboard.copy(\n                                                        text = color.toHex(),\n                                                        message = R.string.color_copied\n                                                    )\n                                                }\n                                        )\n                                    }\n                                }\n                            }\n                            Spacer(\n                                Modifier\n                                    .weight(1f)\n                                    .padding(start = 8.dp)\n                            )\n                        }\n                        if (isPortrait) {\n                            Spacer(modifier = Modifier.height(8.dp))\n                            ProvideTextStyle(\n                                value = LocalTextStyle.current.merge(\n                                    MaterialTheme.typography.headlineSmall\n                                )\n                            ) {\n                                Row(\n                                    verticalAlignment = Alignment.CenterVertically,\n                                    modifier = Modifier\n                                        .padding(start = 16.dp, end = 16.dp, bottom = 16.dp)\n                                ) {\n                                    Text(stringResource(R.string.color))\n\n                                    Text(\n                                        modifier = Modifier\n                                            .padding(horizontal = 8.dp)\n                                            .clip(ShapeDefaults.mini)\n                                            .hapticsClickable {\n                                                Clipboard.copy(\n                                                    text = color.toHex(),\n                                                    message = R.string.color_copied\n                                                )\n                                            }\n                                            .background(MaterialTheme.colorScheme.secondaryContainer)\n                                            .border(\n                                                width = settingsState.borderWidth,\n                                                color = MaterialTheme.colorScheme.outlineVariant(\n                                                    onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                                                ),\n                                                shape = ShapeDefaults.mini\n                                            )\n                                            .padding(horizontal = 6.dp),\n                                        text = color.toHex(),\n                                        style = LocalTextStyle.current.copy(\n                                            fontWeight = FontWeight.Bold,\n                                            color = MaterialTheme.colorScheme.onSecondaryContainer\n                                        )\n                                    )\n\n                                    Spacer(\n                                        modifier = Modifier\n                                            .weight(1f)\n                                            .padding(2.dp)\n                                    )\n\n                                    Box(\n                                        Modifier\n                                            .padding(vertical = 4.dp)\n                                            .background(\n                                                color = animateColorAsState(color).value,\n                                                shape = ShapeDefaults.small\n                                            )\n                                            .height(40.dp)\n                                            .width(72.dp)\n                                            .border(\n                                                width = settingsState.borderWidth,\n                                                color = MaterialTheme.colorScheme.outlineVariant(\n                                                    onTopOf = animateColorAsState(color).value\n                                                ),\n                                                shape = ShapeDefaults.small\n                                            )\n                                            .clip(ShapeDefaults.small)\n                                            .hapticsClickable {\n                                                Clipboard.copy(\n                                                    text = color.toHex(),\n                                                    message = R.string.color_copied\n                                                )\n                                            }\n                                    )\n                                }\n                            }\n                        } else {\n                            Spacer(modifier = Modifier.height(8.dp))\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/pick-color/src/main/java/com/t8rin/imagetoolbox/feature/pick_color/presentation/screenLogic/PickColorFromImageComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.pick_color.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\n\nclass PickColorFromImageComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    private val imageGetter: ImageGetter<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n    }\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _color: MutableState<Color> = mutableStateOf(Color.Unspecified)\n    val color: Color by _color\n\n    private val _uri = mutableStateOf<Uri?>(null)\n\n    fun setUri(\n        uri: Uri\n    ) {\n        _uri.value = uri\n        componentScope.launch {\n            runSuspendCatching {\n                _bitmap.value = imageGetter.getImage(\n                    data = uri,\n                    size = 4000\n                )\n            }.onFailure(AppToastHost::showFailureToast)\n        }\n    }\n\n    fun updateColor(color: Color) {\n        _color.value = color\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n        ): PickColorFromImageComponent\n    }\n}"
  },
  {
    "path": "feature/quick-tiles/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/quick-tiles/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.quick_tiles\"\n\ndependencies {\n    implementation(projects.feature.eraseBackground)\n}"
  },
  {
    "path": "feature/quick-tiles/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <application tools:targetApi=\"tiramisu\">\n        <service\n            android:name=\".tiles.ColorPickerTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/outline_colorize_24\"\n            android:label=\"@string/pick_color\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.ImageToolboxTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/ic_launcher_monochrome_24\"\n            android:label=\"@string/app_name\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.EditScreenshotTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/app_registration_24px\"\n            android:label=\"@string/edit_screenshot\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.TakeScreenshotTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/mobile_screenshot\"\n            android:label=\"@string/screenshot\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.QrTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/rounded_qr_code_scanner_24\"\n            android:label=\"@string/qr_code\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.DocumentScannerTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/rounded_document_scanner_24\"\n            android:label=\"@string/document_scanner\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.TextRecognitionTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/image_to_text_outlined\"\n            android:label=\"@string/recognize_text\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.ResizeAndConvertTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/multiple_image_edit\"\n            android:label=\"@string/resize_and_convert\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <service\n            android:name=\".tiles.GeneratePaletteTile\"\n            android:exported=\"true\"\n            android:icon=\"@drawable/palette_swatch_outlined\"\n            android:label=\"@string/generate_palette\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\"\n            android:process=\":remote\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <activity\n            android:name=\".screenshot.ScreenshotLauncher\"\n            android:theme=\"@style/TransparentActivity\" />\n\n        <service\n            android:name=\".screenshot.ScreenshotService\"\n            android:foregroundServiceType=\"mediaProjection\"\n            android:process=\":remote\" />\n    </application>\n</manifest>"
  },
  {
    "path": "feature/quick-tiles/src/main/java/com/t8rin/imagetoolbox/feature/quick_tiles/screenshot/Contants.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.quick_tiles.screenshot\n\ninternal const val SCREENSHOT_ACTION = \"shot\"\ninternal const val DATA_EXTRA = \"data\"\ninternal const val RESULT_CODE_EXTRA = \"resultCode\""
  },
  {
    "path": "feature/quick-tiles/src/main/java/com/t8rin/imagetoolbox/feature/quick_tiles/screenshot/ScreenshotLauncher.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.quick_tiles.screenshot\n\nimport android.media.projection.MediaProjectionManager\nimport android.os.Build\nimport android.os.Bundle\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.annotation.RequiresApi\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.content.getSystemService\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.buildIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getScreenExtra\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.postToast\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.putScreenExtra\n\nclass ScreenshotLauncher : AppCompatActivity() {\n\n    @RequiresApi(Build.VERSION_CODES.N)\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        val projectionManager = getSystemService<MediaProjectionManager>()\n        val captureIntent = projectionManager?.createScreenCaptureIntent()\n\n        if (captureIntent == null) {\n            onFailure(NullPointerException(\"No projection manager\"))\n        }\n\n        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->\n            runCatching {\n                val resultCode = result.resultCode\n                val data = result.data\n                if (resultCode == RESULT_OK) {\n                    val serviceIntent = buildIntent(ScreenshotService::class.java) {\n                        putExtra(DATA_EXTRA, data)\n                        putExtra(RESULT_CODE_EXTRA, resultCode)\n                        action = intent.action\n                        putScreenExtra(intent.getScreenExtra())\n                    }\n\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n                        startForegroundService(serviceIntent)\n                    } else {\n                        startService(serviceIntent)\n                    }\n                    finish()\n                } else throw SecurityException()\n            }.onFailure(::onFailure)\n        }.launch(captureIntent!!)\n    }\n\n    private fun onFailure(throwable: Throwable) {\n        postToast(\n            textRes = R.string.smth_went_wrong,\n            isLong = true,\n            throwable.localizedMessage ?: \"\"\n        )\n        finish()\n    }\n\n}"
  },
  {
    "path": "feature/quick-tiles/src/main/java/com/t8rin/imagetoolbox/feature/quick_tiles/screenshot/ScreenshotMaker.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.quick_tiles.screenshot\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.PixelFormat\nimport android.graphics.Point\nimport android.graphics.Rect\nimport android.hardware.display.DisplayManager\nimport android.hardware.display.VirtualDisplay\nimport android.media.ImageReader\nimport android.media.ImageReader.OnImageAvailableListener\nimport android.media.projection.MediaProjection\nimport android.os.Build\nimport android.view.WindowManager\nimport androidx.core.content.getSystemService\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.mainLooperDelayedAction\nimport com.t8rin.logger.makeLog\n\n\nclass ScreenshotMaker(\n    private val mediaProjection: MediaProjection,\n    private val context: Context,\n    private val onSuccess: (Bitmap) -> Unit\n) : OnImageAvailableListener {\n\n    private var virtualDisplay: VirtualDisplay? = null\n\n    private var imageReader: ImageReader? = null\n\n    @Suppress(\"DEPRECATION\")\n    private val screenSize: IntegerSize = run {\n        val wm = context.getSystemService<WindowManager>()\n            ?: return@run context.resources.displayMetrics.run {\n                IntegerSize(\n                    width = widthPixels, height = heightPixels\n                )\n            }\n\n        val bounds = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {\n            wm.currentWindowMetrics.bounds\n        } else {\n            val display = wm.defaultDisplay\n            val size = Point()\n            display.getRealSize(size)\n            Rect(0, 0, size.x, size.y)\n        }\n\n        IntegerSize(bounds.width(), bounds.height())\n    }.also {\n        it.makeLog(\"Acquired screen size for screenshot\")\n    }\n\n    fun takeScreenshot(delay: Long) {\n        mainLooperDelayedAction(delay) {\n            imageReader = ImageReader.newInstance(\n                screenSize.width,\n                screenSize.height,\n                PixelFormat.RGBA_8888,\n                1\n            )\n            runCatching {\n                virtualDisplay = mediaProjection.createVirtualDisplay(\n                    \"screenshot\",\n                    screenSize.width,\n                    screenSize.height,\n                    context.resources.displayMetrics.densityDpi,\n                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,\n                    imageReader?.surface,\n                    null,\n                    null\n                )\n                imageReader?.setOnImageAvailableListener(this@ScreenshotMaker, null)\n            }\n        }\n    }\n\n    override fun onImageAvailable(reader: ImageReader) {\n        val image = reader.acquireLatestImage() ?: return takeScreenshot(300)\n        val planes = image.planes\n        val buffer = planes[0].buffer.rewind()\n        val pixelStride = planes[0].pixelStride\n        val rowStride = planes[0].rowStride\n        val rowPadding = rowStride - pixelStride * screenSize.width\n\n        val bitmap = createBitmap(\n            width = screenSize.width + rowPadding / pixelStride,\n            height = screenSize.height\n        )\n\n        bitmap.copyPixelsFromBuffer(buffer)\n\n        finish()\n\n        image.close()\n\n        onSuccess(bitmap)\n    }\n\n    private fun finish() {\n        virtualDisplay?.release()\n        mediaProjection.stop()\n        imageReader = null\n    }\n\n}"
  },
  {
    "path": "feature/quick-tiles/src/main/java/com/t8rin/imagetoolbox/feature/quick_tiles/screenshot/ScreenshotService.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.quick_tiles.screenshot\n\nimport android.app.Activity.RESULT_CANCELED\nimport android.app.Notification\nimport android.app.NotificationChannel\nimport android.app.NotificationManager\nimport android.app.Service\nimport android.content.ClipData\nimport android.content.ClipboardManager\nimport android.content.Intent\nimport android.content.pm.ServiceInfo\nimport android.graphics.Bitmap\nimport android.media.projection.MediaProjection\nimport android.media.projection.MediaProjectionManager\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Handler\nimport android.os.IBinder\nimport android.os.Looper\nimport androidx.annotation.RequiresApi\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.content.getSystemService\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.safeConfig\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FileSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getScreenExtra\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.postToast\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.putScreenExtra\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.IntentUtils.parcelable\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemover\nimport dagger.hilt.android.AndroidEntryPoint\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.channels.Channel\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.debounce\nimport kotlinx.coroutines.flow.receiveAsFlow\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\nimport kotlin.time.Duration.Companion.milliseconds\nimport kotlin.time.Duration.Companion.seconds\n\n@RequiresApi(Build.VERSION_CODES.N)\n@AndroidEntryPoint\nclass ScreenshotService : Service() {\n\n    @Inject\n    lateinit var fileController: FileController\n\n    @Inject\n    lateinit var shareProvider: ImageShareProvider<Bitmap>\n\n    @Inject\n    lateinit var imageCompressor: ImageCompressor<Bitmap>\n\n    @Inject\n    lateinit var autoBackgroundRemover: AutoBackgroundRemover<Bitmap>\n\n    @Inject\n    lateinit var dispatchersHolder: DispatchersHolder\n\n    private val coroutineScope by lazy {\n        CoroutineScope(dispatchersHolder.defaultDispatcher)\n    }\n\n    private val clipboardManager get() = getSystemService<ClipboardManager>()\n    private val mediaProjectionManager get() = getSystemService<MediaProjectionManager>()\n\n    private val screenshotChannel = Channel<Screenshot>(Channel.BUFFERED)\n    private var screenshotJob by smartJob()\n\n    private var timeoutJob by smartJob()\n\n    override fun onStartCommand(\n        intent: Intent?,\n        flags: Int,\n        startId: Int\n    ): Int = runCatching {\n        startListening()\n\n        val resultCode = intent?.getIntExtra(RESULT_CODE_EXTRA, RESULT_CANCELED) ?: RESULT_CANCELED\n\n        val data = intent?.parcelable<Intent>(DATA_EXTRA)\n        val channelId = 1\n\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            getSystemService<NotificationManager>()\n                ?.createNotificationChannel(\n                    NotificationChannel(\n                        channelId.toString(),\n                        \"screenshot\",\n                        NotificationManager.IMPORTANCE_MIN\n                    )\n                )\n\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                startForeground(\n                    channelId,\n                    Notification.Builder(applicationContext, channelId.toString())\n                        .setSmallIcon(R.drawable.ic_launcher_foreground)\n                        .setContentTitle(getString(R.string.processing_screenshot))\n                        .build(),\n                    ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION\n                )\n            } else {\n                startForeground(\n                    channelId,\n                    Notification.Builder(applicationContext, channelId.toString())\n                        .setSmallIcon(R.drawable.ic_launcher_foreground)\n                        .setContentTitle(getString(R.string.processing_screenshot))\n                        .build()\n                )\n            }\n        }\n        val callback = object : MediaProjection.Callback() {}\n\n        mediaProjectionManager?.getMediaProjection(resultCode, data!!)?.apply {\n            registerCallback(\n                callback,\n                Handler(Looper.getMainLooper())\n            )\n            val screenshotMaker = buildScreenshotMaker(\n                mediaProjection = this,\n                intent = intent\n            )\n\n            screenshotMaker.takeScreenshot(1000)\n        }\n\n        START_REDELIVER_INTENT\n    }.getOrNull() ?: START_REDELIVER_INTENT\n\n    override fun onDestroy() {\n        screenshotJob?.cancel()\n        timeoutJob?.cancel()\n        super.onDestroy()\n    }\n\n    override fun onBind(intent: Intent): IBinder? = null\n\n    private fun startListening() {\n        screenshotJob = coroutineScope.launch {\n            screenshotChannel\n                .receiveAsFlow()\n                .debounce(500.milliseconds)\n                .collectLatest { (intent, output) ->\n                    val bitmap = autoBackgroundRemover.trimEmptyParts(output)\n\n                    val resultBitmap = createBitmap(\n                        width = bitmap.width,\n                        height = bitmap.height,\n                        config = bitmap.safeConfig\n                    ).applyCanvas {\n                        drawColor(Color.Black.toArgb())\n                        drawBitmap(bitmap)\n                    }\n\n                    val uri: Uri? = shareProvider.cacheImage(\n                        image = resultBitmap,\n                        imageInfo = ImageInfo(\n                            width = resultBitmap.width,\n                            height = resultBitmap.height,\n                            imageFormat = ImageFormat.Png.Lossless\n                        )\n                    )?.toUri()\n\n                    if (intent?.action != SCREENSHOT_ACTION) {\n                        startActivity(\n                            Intent(Intent.ACTION_SEND).apply {\n                                setPackage(applicationContext.packageName)\n                                type = \"image/png\"\n                                putScreenExtra(intent.getScreenExtra())\n                                putExtra(Intent.EXTRA_STREAM, uri)\n                                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                            }\n                        )\n                    } else {\n                        fileController.save(\n                            saveTarget = FileSaveTarget(\n                                filename = \"screenshot-${timestamp()}.png\",\n                                originalUri = \"screenshot\",\n                                imageFormat = ImageFormat.Png.Lossless,\n                                data = imageCompressor.compress(\n                                    image = resultBitmap,\n                                    imageFormat = ImageFormat.Png.Lossless,\n                                    quality = Quality.Base()\n                                )\n                            ),\n                            keepOriginalMetadata = true\n                        )\n\n                        uri?.let { uri ->\n                            clipboardManager?.setPrimaryClip(\n                                ClipData.newUri(\n                                    contentResolver,\n                                    \"IMAGE\",\n                                    uri\n                                )\n                            )\n                        }\n                        postToast(\n                            textRes = R.string.saved_to_without_filename,\n                            fileController.defaultSavingPath\n                        )\n                    }\n\n                    stopForeground(STOP_FOREGROUND_REMOVE)\n                    stopSelf()\n                }\n        }\n\n        timeoutJob = coroutineScope.launch {\n            delay(5.seconds)\n            if (screenshotChannel.isEmpty) {\n                postToast(\n                    textRes = R.string.screenshot_not_captured_try_again,\n                    isLong = true\n                )\n                stopForeground(STOP_FOREGROUND_REMOVE)\n                stopSelf()\n            }\n        }\n    }\n\n    private fun buildScreenshotMaker(\n        mediaProjection: MediaProjection,\n        intent: Intent?\n    ) = ScreenshotMaker(\n        mediaProjection = mediaProjection,\n        context = this,\n        onSuccess = {\n            screenshotChannel.trySend(\n                Screenshot(\n                    intent = intent,\n                    output = it\n                )\n            )\n        }\n    )\n\n    private data class Screenshot(\n        val intent: Intent?,\n        val output: Bitmap\n    )\n\n}"
  },
  {
    "path": "feature/quick-tiles/src/main/java/com/t8rin/imagetoolbox/feature/quick_tiles/tiles/QuickTile.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.quick_tiles.tiles\n\nimport android.annotation.SuppressLint\nimport android.app.PendingIntent\nimport android.service.quicksettings.TileService\nimport androidx.core.service.quicksettings.PendingIntentActivityWrapper\nimport androidx.core.service.quicksettings.TileServiceCompat\n\n@SuppressLint(\"NewApi\")\nsealed class QuickTile(\n    private val tileAction: TileAction\n) : TileService() {\n\n    override fun onClick() {\n        super.onClick()\n        runCatching {\n            TileServiceCompat.startActivityAndCollapse(\n                this,\n                PendingIntentActivityWrapper(\n                    applicationContext,\n                    0,\n                    tileAction.toIntent(this),\n                    PendingIntent.FLAG_UPDATE_CURRENT,\n                    false\n                )\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "feature/quick-tiles/src/main/java/com/t8rin/imagetoolbox/feature/quick_tiles/tiles/TileAction.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.quick_tiles.tiles\n\nimport android.content.Context\nimport android.content.Intent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppActivityClass\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.SHORTCUT_OPEN_ACTION\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.buildIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.putScreenExtra\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.feature.quick_tiles.screenshot.SCREENSHOT_ACTION\nimport com.t8rin.imagetoolbox.feature.quick_tiles.screenshot.ScreenshotLauncher\n\ninternal sealed class TileAction(val clazz: Class<*>) {\n    data class ScreenshotAndOpenScreen(val screen: Screen?) : TileAction(ScreenshotClass)\n    data class OpenScreen(val screen: Screen?) : TileAction(AppActivityClass)\n    data object Screenshot : TileAction(ScreenshotClass)\n    data object OpenApp : TileAction(AppActivityClass)\n\n    fun toIntent(context: Context): Intent = context.buildIntent(clazz) {\n        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK\n\n        when (this@TileAction) {\n            OpenApp -> setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)\n\n            Screenshot -> action = SCREENSHOT_ACTION\n\n            is ScreenshotAndOpenScreen -> {\n                action = SHORTCUT_OPEN_ACTION\n                putScreenExtra(screen)\n            }\n\n            is OpenScreen -> {\n                action = SHORTCUT_OPEN_ACTION\n                putScreenExtra(screen)\n            }\n        }\n    }\n\n    companion object {\n        private val ScreenshotClass = ScreenshotLauncher::class.java\n    }\n}"
  },
  {
    "path": "feature/quick-tiles/src/main/java/com/t8rin/imagetoolbox/feature/quick_tiles/tiles/Tiles.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.quick_tiles.tiles\n\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.feature.quick_tiles.tiles.TileAction.OpenApp\nimport com.t8rin.imagetoolbox.feature.quick_tiles.tiles.TileAction.OpenScreen\nimport com.t8rin.imagetoolbox.feature.quick_tiles.tiles.TileAction.Screenshot\nimport com.t8rin.imagetoolbox.feature.quick_tiles.tiles.TileAction.ScreenshotAndOpenScreen\n\nclass ImageToolboxTile : QuickTile(\n    tileAction = OpenApp\n)\n\nclass TakeScreenshotTile : QuickTile(\n    tileAction = Screenshot\n)\n\nclass EditScreenshotTile : QuickTile(\n    tileAction = ScreenshotAndOpenScreen(null)\n)\n\nclass GeneratePaletteTile : QuickTile(\n    tileAction = ScreenshotAndOpenScreen(Screen.PaletteTools())\n)\n\nclass ColorPickerTile : QuickTile(\n    tileAction = ScreenshotAndOpenScreen(Screen.PickColorFromImage())\n)\n\nclass QrTile : QuickTile(\n    tileAction = OpenScreen(Screen.ScanQrCode())\n)\n\nclass DocumentScannerTile : QuickTile(\n    tileAction = OpenScreen(Screen.DocumentScanner)\n)\n\nclass TextRecognitionTile : QuickTile(\n    tileAction = OpenScreen(Screen.RecognizeText())\n)\n\nclass ResizeAndConvertTile : QuickTile(\n    tileAction = OpenScreen(Screen.ResizeAndConvert())\n)"
  },
  {
    "path": "feature/recognize-text/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/recognize-text/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.recognize.text\"\n\ndependencies {\n    implementation(projects.core.filters)\n    implementation(projects.feature.pdfTools)\n    implementation(projects.feature.singleEdit)\n    implementation(libs.tesseract)\n}"
  },
  {
    "path": "feature/recognize-text/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest></manifest>"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/data/AndroidImageTextReader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.core.net.toUri\nimport com.googlecode.tesseract.android.TessBaseAPI\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadManager\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.createZip\nimport com.t8rin.imagetoolbox.core.utils.putEntry\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.DownloadData\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.ImageTextReader\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OcrEngineMode\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionData\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.SegmentationMode\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessParams\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TextRecognitionResult\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.flow.channelFlow\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.io.ByteArrayOutputStream\nimport java.io.File\nimport java.io.FileInputStream\nimport java.io.FileOutputStream\nimport java.util.Locale\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipInputStream\nimport javax.inject.Inject\n\ninternal class AndroidImageTextReader @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    @ApplicationContext private val context: Context,\n    private val shareProvider: ShareProvider,\n    private val downloadManager: DownloadManager,\n    resourceManager: ResourceManager,\n    dispatchersHolder: DispatchersHolder,\n    appScope: AppScope,\n) : ImageTextReader,\n    DispatchersHolder by dispatchersHolder,\n    ResourceManager by resourceManager {\n\n    init {\n        appScope.launch {\n            RecognitionType.entries.forEach {\n                File(getPathFromMode(it), \"tessdata\").mkdirs()\n            }\n        }\n    }\n\n    override suspend fun getTextFromImage(\n        type: RecognitionType,\n        languageCode: String,\n        segmentationMode: SegmentationMode,\n        ocrEngineMode: OcrEngineMode,\n        parameters: TessParams,\n        model: Any?,\n        onProgress: (Int) -> Unit\n    ): TextRecognitionResult = withContext(defaultDispatcher) {\n        val empty = TextRecognitionResult.Success(RecognitionData.Empty)\n\n        if (model == null) return@withContext empty\n\n        val image = model as? Bitmap ?: (imageGetter.getImage(model) ?: return@withContext empty)\n\n        val needToDownload = getNeedToDownloadLanguages(type, languageCode)\n\n        if (needToDownload.isNotEmpty()) {\n            return@withContext TextRecognitionResult.NoData(needToDownload)\n        }\n\n        return@withContext runCatching {\n            val api = TessBaseAPI {\n                if (isActive) onProgress(it.percent)\n                else return@TessBaseAPI\n            }.apply {\n                val success = init(\n                    getPathFromMode(type),\n                    languageCode,\n                    ocrEngineMode.ordinal\n                )\n                if (!success) {\n                    return@withContext TextRecognitionResult.NoData(\n                        getNeedToDownloadLanguages(\n                            type = type,\n                            languageCode = languageCode\n                        )\n                    ).also {\n                        it.data.forEach { data ->\n                            getModelFile(\n                                type = type,\n                                languageCode = data.languageCode\n                            ).delete()\n                        }\n                    }\n                }\n                pageSegMode = segmentationMode.ordinal\n\n                parameters.tessParamList.forEach { param ->\n                    setVariable(param.key, param.stringValue)\n                }\n                runCatching {\n                    parameters.tessCustomParams.trim().removePrefix(\"--\").split(\"--\").forEach { s ->\n                        val (key, value) = s.trim().split(\" \").filter { it.isNotEmpty() }\n                        setVariable(key, value)\n                    }\n                }\n\n                setImage(image.copy(Bitmap.Config.ARGB_8888, false))\n            }\n\n            val hocr = api.getHOCRText(0)\n\n            val text = api.utF8Text\n\n            val accuracy = api.meanConfidence()\n\n            TextRecognitionResult.Success(\n                RecognitionData(\n                    text = text,\n                    accuracy = if (text.isEmpty()) 0 else accuracy,\n                    hocr = hocr\n                )\n            )\n        }.let {\n            if (it.isSuccess) {\n                it.getOrNull()!!\n            } else {\n                languageCode.split(\"+\").forEach { code ->\n                    getModelFile(\n                        type = type,\n                        languageCode = code\n                    ).delete()\n                }\n\n                TextRecognitionResult.Error(it.exceptionOrNull()!!)\n            }\n        }\n    }\n\n    private fun getNeedToDownloadLanguages(\n        type: RecognitionType,\n        languageCode: String\n    ): List<DownloadData> {\n        val needToDownload = mutableListOf<DownloadData>()\n        languageCode.split(\"+\").filter { it.isNotBlank() }.forEach { code ->\n            if (!isLanguageDataExists(type, code)) {\n                needToDownload.add(\n                    DownloadData(\n                        type = type,\n                        languageCode = code,\n                        name = getDisplayName(code, false),\n                        localizedName = getDisplayName(code, true)\n                    )\n                )\n            }\n        }\n        return needToDownload\n    }\n\n    override fun isLanguageDataExists(\n        type: RecognitionType,\n        languageCode: String\n    ): Boolean = getModelFile(\n        type = type,\n        languageCode = languageCode\n    ).exists()\n\n    override suspend fun getLanguages(\n        type: RecognitionType\n    ): List<OCRLanguage> = withContext(ioDispatcher) {\n        val codes = context.resources.getStringArray(R.array.key_ocr_engine_language_value)\n\n        return@withContext codes.mapNotNull { code ->\n            val name = getDisplayName(code, false)\n            val localizedName = getDisplayName(code, true)\n            if (name.isBlank() || localizedName.isBlank()) return@mapNotNull null\n\n            OCRLanguage(\n                name = name,\n                code = code,\n                downloaded = RecognitionType.entries.filter {\n                    isLanguageDataExists(\n                        type = it,\n                        languageCode = code\n                    )\n                },\n                localizedName = localizedName\n            )\n        }.toList()\n    }\n\n    override fun getLanguageForCode(\n        code: String\n    ): OCRLanguage = OCRLanguage(\n        name = getDisplayName(code, false),\n        code = code,\n        downloaded = RecognitionType.entries.filter {\n            isLanguageDataExists(it, code)\n        },\n        localizedName = getDisplayName(code, true)\n    )\n\n    override suspend fun deleteLanguage(\n        language: OCRLanguage,\n        types: List<RecognitionType>\n    ) = withContext(ioDispatcher) {\n        types.forEach { type ->\n            getModelFile(\n                type = type,\n                languageCode = language.code\n            ).delete()\n        }\n    }\n\n    override suspend fun downloadTrainingData(\n        type: RecognitionType,\n        languageCode: String,\n        onProgress: (DownloadProgress) -> Unit\n    ) {\n        val needToDownloadLanguages = getNeedToDownloadLanguages(type, languageCode)\n\n        if (needToDownloadLanguages.isNotEmpty()) {\n            downloadTrainingDataImpl(\n                type = type,\n                needToDownloadLanguages = needToDownloadLanguages,\n                onProgress = onProgress\n            )\n        }\n    }\n\n    private suspend fun downloadTrainingDataImpl(\n        type: RecognitionType,\n        needToDownloadLanguages: List<DownloadData>,\n        onProgress: (DownloadProgress) -> Unit\n    ) = needToDownloadLanguages.map {\n        downloadTrainingDataForCode(\n            type = type,\n            lang = it.languageCode,\n            onProgress = onProgress\n        )\n    }\n\n    private suspend fun downloadTrainingDataForCode(\n        type: RecognitionType,\n        lang: String,\n        onProgress: (DownloadProgress) -> Unit\n    ) {\n        channelFlow {\n            downloadManager.download(\n                url = when (type) {\n                    RecognitionType.Best -> TessConstants.TESSERACT_DATA_DOWNLOAD_URL_BEST\n                    RecognitionType.Standard -> TessConstants.TESSERACT_DATA_DOWNLOAD_URL_STANDARD\n                    RecognitionType.Fast -> TessConstants.TESSERACT_DATA_DOWNLOAD_URL_FAST\n                }.format(lang),\n                destinationPath = getModelFile(\n                    type = type,\n                    languageCode = lang\n                ).absolutePath,\n                onProgress = ::trySend,\n                onFinish = { close() }\n            )\n        }.collect { progress ->\n            onProgress(progress)\n        }\n    }\n\n    private fun getPathFromMode(\n        type: RecognitionType\n    ): String = File(\n        File(context.filesDir, \"tesseract\").apply(File::mkdirs),\n        type.displayName\n    ).absolutePath\n\n    private fun getModelFile(\n        type: RecognitionType,\n        languageCode: String\n    ) = File(\n        \"${getPathFromMode(type)}/tessdata\",\n        TessConstants.LANGUAGE_CODE.format(languageCode)\n    )\n\n    private fun getDisplayName(\n        lang: String?,\n        useDefaultLocale: Boolean\n    ): String {\n        if (lang.isNullOrEmpty()) {\n            return \"\"\n        }\n\n        val locale = Locale.forLanguageTag(\n            if (lang.contains(\"chi_sim\")) \"zh-CN\"\n            else if (lang.contains(\"chi_tra\")) \"zh-TW\"\n            else lang\n        )\n        return locale.getDisplayName(\n            if (useDefaultLocale) Locale.getDefault()\n            else locale\n        ).replaceFirstChar { it.uppercase(locale) }\n    }\n\n    override suspend fun exportLanguagesToZip(): String? = withContext(ioDispatcher) {\n        val zipBytes = ByteArrayOutputStream().apply {\n            createZip { zip ->\n                RecognitionType.entries.forEach { type ->\n                    File(getPathFromMode(type), \"tessdata\").listFiles()?.forEach { file ->\n                        zip.putEntry(\n                            name = \"${type.displayName}/tessdata/${file.name}\",\n                            input = FileInputStream(file)\n                        )\n                    }\n                }\n            }\n        }.toByteArray()\n\n        shareProvider.cacheByteArray(\n            byteArray = zipBytes,\n            filename = \"exported_languages.zip\"\n        )\n    }\n\n    override suspend fun importLanguagesFromUri(\n        zipUri: String\n    ): Result<Any> = withContext(ioDispatcher) {\n        val zipInput = context.contentResolver.openInputStream(\n            zipUri.toUri()\n        ) ?: return@withContext Result.failure(NullPointerException())\n\n        runCatching {\n            zipInput.use { inputStream ->\n                ZipInputStream(inputStream).use { zipIn ->\n                    var entry: ZipEntry?\n                    while (zipIn.nextEntry.also { entry = it } != null) {\n                        entry?.let { zipEntry ->\n                            val outFile = File(\n                                File(context.filesDir, \"tesseract\").apply(File::mkdirs),\n                                zipEntry.name\n                            )\n                            outFile.parentFile?.mkdirs()\n                            FileOutputStream(outFile).use { fos ->\n                                zipIn.copyTo(fos)\n                            }\n                            zipIn.closeEntry()\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/di/RecognizeTextModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.di\n\nimport com.t8rin.imagetoolbox.feature.recognize.text.data.AndroidImageTextReader\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.ImageTextReader\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface RecognizeTextModule {\n\n    @Singleton\n    @Binds\n    fun provideImageTextReader(\n        reader: AndroidImageTextReader\n    ): ImageTextReader\n\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/DownloadData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\ndata class DownloadData(\n    val type: RecognitionType,\n    val languageCode: String,\n    val name: String,\n    val localizedName: String\n)\n"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/ImageTextReader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\n\ninterface ImageTextReader {\n\n    suspend fun getTextFromImage(\n        type: RecognitionType,\n        languageCode: String,\n        segmentationMode: SegmentationMode,\n        ocrEngineMode: OcrEngineMode,\n        parameters: TessParams,\n        model: Any?,\n        onProgress: (Int) -> Unit\n    ): TextRecognitionResult\n\n    suspend fun downloadTrainingData(\n        type: RecognitionType,\n        languageCode: String,\n        onProgress: (DownloadProgress) -> Unit\n    )\n\n    fun isLanguageDataExists(\n        type: RecognitionType,\n        languageCode: String\n    ): Boolean\n\n    suspend fun getLanguages(\n        type: RecognitionType\n    ): List<OCRLanguage>\n\n    fun getLanguageForCode(\n        code: String\n    ): OCRLanguage\n\n    suspend fun deleteLanguage(\n        language: OCRLanguage,\n        types: List<RecognitionType>\n    )\n\n    suspend fun exportLanguagesToZip(): String?\n\n    suspend fun importLanguagesFromUri(\n        zipUri: String\n    ): Result<Any>\n\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/OCRLanguage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\ndata class OCRLanguage(\n    val name: String,\n    val localizedName: String,\n    val code: String,\n    val downloaded: List<RecognitionType>\n) {\n    companion object {\n        val Default by lazy {\n            OCRLanguage(\n                name = \"English\",\n                localizedName = \"English\",\n                code = \"eng\",\n                downloaded = emptyList()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/OcrEngineMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\nenum class OcrEngineMode {\n    TESSERACT_ONLY, LSTM_ONLY, TESSERACT_LSTM_COMBINED, DEFAULT\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/RecognitionData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\ndata class RecognitionData(\n    val text: String,\n    val accuracy: Int,\n    val hocr: String\n) {\n    companion object {\n        val Empty = RecognitionData(\n            text = \"\",\n            accuracy = 0,\n            hocr = \"\"\n        )\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/RecognitionType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\nenum class RecognitionType(val displayName: String) {\n    Fast(\"fast\"),\n    Standard(\"standard\"),\n    Best(\"best\")\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/SegmentationMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\nenum class SegmentationMode {\n    PSM_OSD_ONLY, PSM_AUTO_OSD, PSM_AUTO_ONLY, PSM_AUTO, PSM_SINGLE_COLUMN, PSM_SINGLE_BLOCK_VERT_TEXT,\n    PSM_SINGLE_BLOCK, PSM_SINGLE_LINE, PSM_SINGLE_WORD, PSM_CIRCLE_WORD, PSM_SINGLE_CHAR, PSM_SPARSE_TEXT,\n    PSM_SPARSE_TEXT_OSD, PSM_RAW_LINE\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/TessConstants.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\n\ninternal object TessConstants {\n\n    const val LANGUAGE_CODE = \"%s.traineddata\"\n\n    const val TESSERACT_DATA_DOWNLOAD_URL_BEST =\n        \"https://github.com/tesseract-ocr/tessdata_best/raw/refs/heads/main/%s.traineddata\"\n    const val TESSERACT_DATA_DOWNLOAD_URL_STANDARD =\n        \"https://github.com/tesseract-ocr/tessdata/raw/refs/heads/main/%s.traineddata\"\n    const val TESSERACT_DATA_DOWNLOAD_URL_FAST =\n        \"https://github.com/tesseract-ocr/tessdata_fast/raw/refs/heads/main/%s.traineddata\"\n\n    const val KEY_PRESERVE_INTERWORD_SPACES = \"preserve_interword_spaces\"\n    const val KEY_CHOP_ENABLE = \"chop_enable\"\n    const val KEY_USE_NEW_STATE_COST = \"use_new_state_cost\"\n    const val KEY_SEGMENT_SEGCOST_RATING = \"segment_segcost_rating\"\n    const val KEY_ENABLE_NEW_SEGSEARCH = \"enable_new_segsearch\"\n    const val KEY_LANGUAGE_MODEL_NGRAM_ON = \"language_model_ngram_on\"\n    const val KEY_TEXTORD_FORCE_MAKE_PROP_WORDS = \"textord_force_make_prop_words\"\n    const val KEY_EDGES_MAX_CHILDREN_PER_OUTLINE = \"edges_max_children_per_outline\"\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/TessParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_CHOP_ENABLE\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_EDGES_MAX_CHILDREN_PER_OUTLINE\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_ENABLE_NEW_SEGSEARCH\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_LANGUAGE_MODEL_NGRAM_ON\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_PRESERVE_INTERWORD_SPACES\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_SEGMENT_SEGCOST_RATING\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_TEXTORD_FORCE_MAKE_PROP_WORDS\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessConstants.KEY_USE_NEW_STATE_COST\nimport kotlinx.collections.immutable.toImmutableList\n\nclass TessParam(\n    val key: String,\n    val value: Any\n) {\n    val stringValue: String\n        get() = when (value) {\n            is Boolean -> if (value) \"1\" else \"0\"\n            else -> value.toString()\n        }\n\n    fun copy(value: Any) = TessParam(\n        key = key,\n        value = value\n    )\n\n    override fun equals(other: Any?): Boolean {\n        if (other !is TessParam) return false\n        if (this.key != other.key) return false\n\n        return this.value == other.value\n    }\n\n    override fun hashCode(): Int {\n        var result = key.hashCode()\n        result = 31 * result + value.hashCode()\n        return result\n    }\n\n    operator fun component1(): String = key\n    operator fun component2(): Any = value\n}\n\nclass TessParams private constructor(\n    val tessParamList: List<TessParam>,\n    val tessCustomParams: String = \"\"\n) {\n    fun update(\n        key: String,\n        transform: (Any) -> Any\n    ): TessParams = TessParams(\n        tessParamList = tessParamList.toMutableList().apply {\n            val index = indexOfFirst { it.key == key }.takeIf {\n                it >= 0\n            } ?: return this@TessParams\n\n            this[index] = this[index].let {\n                it.copy(value = transform(it.value))\n            }\n        }.toImmutableList(),\n        tessCustomParams = tessCustomParams\n    )\n\n    fun update(\n        newCustomParams: String\n    ): TessParams = TessParams(\n        tessParamList = tessParamList,\n        tessCustomParams = newCustomParams\n    )\n\n    companion object {\n        val Default by lazy {\n            TessParams(\n                tessParamList = listOf(\n                    KEY_PRESERVE_INTERWORD_SPACES.disabled(),\n                    KEY_CHOP_ENABLE.enabled(),\n                    KEY_USE_NEW_STATE_COST.disabled(),\n                    KEY_SEGMENT_SEGCOST_RATING.disabled(),\n                    KEY_ENABLE_NEW_SEGSEARCH.disabled(),\n                    KEY_LANGUAGE_MODEL_NGRAM_ON.disabled(),\n                    KEY_TEXTORD_FORCE_MAKE_PROP_WORDS.disabled(),\n                    KEY_EDGES_MAX_CHILDREN_PER_OUTLINE.int(40)\n                )\n            )\n        }\n\n        private fun String.enabled() = TessParam(\n            key = this,\n            value = true\n        )\n\n        private fun String.disabled() = TessParam(\n            key = this,\n            value = false\n        )\n\n        private fun String.int(value: Int) = TessParam(\n            key = this,\n            value = value\n        )\n\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/domain/TextRecognitionResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.domain\n\n\nsealed interface TextRecognitionResult {\n\n    data class Error(val throwable: Throwable) : TextRecognitionResult\n\n    data class Success(val data: RecognitionData) : TextRecognitionResult\n\n    data class NoData(val data: List<DownloadData>) : TextRecognitionResult\n\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/RecognizeTextContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Save\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.image.urisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.components.RecognizeTextButtons\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.components.RecognizeTextControls\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.components.RecognizeTextDownloadDataDialog\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.components.RecognizeTextNoDataControls\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.components.CropEditOption\n\n\n@Composable\nfun RecognizeTextContent(\n    component: RecognizeTextComponent\n) {\n    val type = component.type\n    val isExtraction = type is Screen.RecognizeText.Type.Extraction\n\n    val isHaveText = component.editedText.orEmpty().isNotEmpty()\n\n    AutoContentBasedColors(\n        model = (type as? Screen.RecognizeText.Type.Extraction)?.uri\n    )\n\n    LaunchedEffect(component.previewBitmap, component.filtersAdded) {\n        if (component.previewBitmap != null) component.startRecognition()\n    }\n\n    val multipleImagePicker = rememberImagePicker { uris: List<Uri> ->\n        when {\n            isExtraction || (uris.size == 1) -> {\n                component.updateType(\n                    type = Screen.RecognizeText.Type.Extraction(uris.firstOrNull())\n                )\n            }\n\n            type is Screen.RecognizeText.Type.WriteToFile -> {\n                component.updateType(\n                    type = Screen.RecognizeText.Type.WriteToFile(uris)\n                )\n            }\n\n            type is Screen.RecognizeText.Type.WriteToMetadata -> {\n                component.updateType(\n                    type = Screen.RecognizeText.Type.WriteToMetadata(uris)\n                )\n            }\n\n            type is Screen.RecognizeText.Type.WriteToSearchablePdf -> {\n                component.updateType(\n                    type = Screen.RecognizeText.Type.WriteToSearchablePdf(uris)\n                )\n            }\n\n            type == null -> {\n                component.showSelectionTypeSheet(uris)\n            }\n        }\n    }\n\n    val addImagesImagePicker = rememberImagePicker { uris: List<Uri> ->\n        when (type) {\n            is Screen.RecognizeText.Type.WriteToFile -> {\n                component.updateType(\n                    type = Screen.RecognizeText.Type.WriteToFile(\n                        type.uris?.plus(uris)?.distinct()\n                    )\n                )\n            }\n\n            is Screen.RecognizeText.Type.WriteToMetadata -> {\n                component.updateType(\n                    type = Screen.RecognizeText.Type.WriteToMetadata(\n                        type.uris?.plus(uris)?.distinct()\n                    )\n                )\n            }\n\n            is Screen.RecognizeText.Type.WriteToSearchablePdf -> {\n                component.updateType(\n                    type = Screen.RecognizeText.Type.WriteToSearchablePdf(\n                        type.uris?.plus(uris)?.distinct()\n                    )\n                )\n            }\n\n            else -> Unit\n        }\n    }\n\n    AutoFilePicker(\n        onAutoPick = multipleImagePicker::pickImage,\n        isPickedAlready = component.initialType != null\n    )\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val saveLauncher = rememberFileCreator(\n        mimeType = MimeType.Txt,\n        onSuccess = component::saveContentToTxt\n    )\n\n    var showCropper by rememberSaveable { mutableStateOf(false) }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        title = {\n            AnimatedContent(\n                targetState = component.recognitionData to type\n            ) { (data, type) ->\n                TopAppBarTitle(\n                    title = if (data == null) {\n                        when (type) {\n                            null -> stringResource(R.string.recognize_text)\n                            else -> stringResource(type.title)\n                        }\n                    } else {\n                        stringResource(\n                            R.string.accuracy,\n                            data.accuracy\n                        )\n                    },\n                    input = type,\n                    isLoading = component.isTextLoading,\n                    size = null\n                )\n            }\n        },\n        onGoBack = component.onGoBack,\n        topAppBarPersistentActions = {\n            if (type == null) TopAppBarEmoji()\n\n            if (type is Screen.RecognizeText.Type.Extraction) {\n                var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n                ZoomButton(\n                    onClick = { showZoomSheet = true },\n                    visible = true\n                )\n                ZoomModalSheet(\n                    data = type.uri,\n                    visible = showZoomSheet,\n                    onDismiss = {\n                        showZoomSheet = false\n                    },\n                    transformations = component.getTransformations()\n                )\n            }\n        },\n        actions = {\n            ShareButton(\n                onShare = {\n                    if (isExtraction) {\n                        component.shareEditedText()\n                    } else {\n                        component.shareData()\n                    }\n                },\n                enabled = isHaveText || !isExtraction\n            )\n            if (isExtraction) {\n                EnhancedIconButton(\n                    onClick = {\n                        saveLauncher.make(component.generateTextFilename())\n                    },\n                    enabled = !component.text.isNullOrEmpty()\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Save,\n                        contentDescription = null\n                    )\n                }\n            }\n        },\n        imagePreview = {\n            if (isExtraction) {\n                Box(\n                    modifier = Modifier\n                        .container()\n                        .padding(4.dp)\n                        .animateContentSizeNoClip(\n                            alignment = Alignment.Center\n                        ),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Picture(\n                        model = component.previewBitmap,\n                        contentScale = ContentScale.FillBounds,\n                        modifier = Modifier.aspectRatio(\n                            component.previewBitmap?.safeAspectRatio ?: 1f\n                        ),\n                        transformations = component.getTransformations(),\n                        shape = MaterialTheme.shapes.medium,\n                        isLoadingFromDifferentPlace = component.isImageLoading\n                    )\n                }\n            } else {\n                UrisPreview(\n                    modifier = Modifier.urisPreview(),\n                    uris = component.uris,\n                    isPortrait = true,\n                    onRemoveUri = component::removeUri,\n                    onAddUris = addImagesImagePicker::pickImage\n                )\n            }\n        },\n        showImagePreviewAsStickyHeader = isExtraction,\n        controls = {\n            RecognizeTextControls(\n                component = component,\n                onShowCropper = { showCropper = true }\n            )\n        },\n        buttons = { actions ->\n            RecognizeTextButtons(\n                component = component,\n                multipleImagePicker = multipleImagePicker,\n                actions = actions\n            )\n        },\n        noDataControls = {\n            RecognizeTextNoDataControls(component)\n        },\n        insetsForNoData = WindowInsets(0),\n        contentPadding = animateDpAsState(\n            if (component.type == null) 12.dp\n            else 20.dp\n        ).value,\n        canShowScreenData = type != null\n    )\n\n    RecognizeTextDownloadDataDialog(component)\n\n    LoadingDialog(\n        visible = component.isExporting || component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving,\n        canCancel = component.isSaving\n    )\n\n    CropEditOption(\n        visible = showCropper,\n        onDismiss = { showCropper = false },\n        useScaffold = isPortrait,\n        bitmap = component.previewBitmap,\n        onGetBitmap = component::updateBitmap,\n        cropProperties = component.cropProperties,\n        setCropAspectRatio = component::setCropAspectRatio,\n        setCropMask = component::setCropMask,\n        selectedAspectRatio = component.selectedAspectRatio,\n        loadImage = component::loadImage\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/DeleteLanguageDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\n\n@Composable\ninternal fun DeleteLanguageDialog(\n    languageToDelete: OCRLanguage?,\n    onDismiss: () -> Unit,\n    onDeleteLanguage: (OCRLanguage, List<RecognitionType>) -> Unit,\n    currentRecognitionType: RecognitionType\n) {\n    EnhancedAlertDialog(\n        visible = languageToDelete != null,\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.Delete,\n                contentDescription = null\n            )\n        },\n        title = { Text(stringResource(id = R.string.delete)) },\n        text = {\n            Text(\n                stringResource(\n                    id = R.string.delete_language_sub,\n                    languageToDelete?.name ?: \"\",\n                    currentRecognitionType.displayName\n                )\n            )\n        },\n        onDismissRequest = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.error,\n                onClick = {\n                    languageToDelete?.let {\n                        onDeleteLanguage(it, listOf(currentRecognitionType))\n                    }\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(R.string.current))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.errorContainer,\n                onClick = {\n                    languageToDelete?.let {\n                        onDeleteLanguage(it, RecognitionType.entries)\n                    }\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(R.string.all))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/DownloadLanguageDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Download\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isNetworkAvailable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.BasicEnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun DownloadLanguageDialog(\n    downloadDialogData: List<UiDownloadData>,\n    onDownloadRequest: (List<UiDownloadData>) -> Unit,\n    downloadProgress: Float,\n    dataRemaining: String,\n    onNoConnection: () -> Unit,\n    onDismiss: () -> Unit\n) {\n    val context = LocalContext.current\n    var downloadStarted by rememberSaveable(downloadDialogData) {\n        mutableStateOf(false)\n    }\n\n    EnhancedAlertDialog(\n        visible = !downloadStarted,\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.Download,\n                contentDescription = null\n            )\n        },\n        title = { Text(stringResource(id = R.string.no_data)) },\n        text = {\n            Text(\n                stringResource(\n                    id = R.string.download_description,\n                    downloadDialogData.firstOrNull()?.type?.displayName ?: \"\",\n                    downloadDialogData.joinToString(separator = \", \") { it.localizedName }\n                )\n            )\n        },\n        onDismissRequest = {},\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    if (context.isNetworkAvailable()) {\n                        downloadDialogData.let { downloadData ->\n                            onDownloadRequest(downloadData)\n                            downloadStarted = true\n                        }\n                    } else onNoConnection()\n                }\n            ) {\n                Text(stringResource(R.string.download))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    )\n\n    BasicEnhancedAlertDialog(\n        onDismissRequest = {},\n        visible = downloadStarted,\n        modifier = Modifier.fillMaxSize()\n    ) {\n        EnhancedLoadingIndicator(\n            progress = downloadProgress,\n            loaderSize = 64.dp\n        ) {\n            AutoSizeText(\n                text = dataRemaining,\n                maxLines = 1,\n                fontWeight = FontWeight.Medium,\n                modifier = Modifier.width(it * 0.8f),\n                textAlign = TextAlign.Center,\n                style = LocalTextStyle.current.copy(\n                    fontSize = 12.sp,\n                    lineHeight = 12.sp\n                )\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/DownloadedLanguageItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyItemScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Cancel\nimport androidx.compose.material.icons.rounded.CheckCircle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalMinimumInteractiveComponentSize\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.Green\nimport com.t8rin.imagetoolbox.core.ui.theme.Red\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCheckbox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsCombinedClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealDirection\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealValue\nimport com.t8rin.imagetoolbox.core.ui.widget.other.SwipeToReveal\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberRevealState\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun LazyItemScope.DownloadedLanguageItem(\n    index: Int,\n    value: List<OCRLanguage>,\n    lang: OCRLanguage,\n    downloadedLanguages: List<OCRLanguage>,\n    onWantDelete: (OCRLanguage) -> Unit,\n    onValueChange: (Boolean, OCRLanguage) -> Unit,\n    onValueChangeForced: (List<OCRLanguage>, RecognitionType) -> Unit,\n    currentRecognitionType: RecognitionType\n) {\n    val settingsState = LocalSettingsState.current\n    val selected by remember(value, lang) {\n        derivedStateOf {\n            lang in value\n        }\n    }\n    val scope = rememberCoroutineScope()\n    val state = rememberRevealState()\n    val interactionSource = remember {\n        MutableInteractionSource()\n    }\n    val isDragged by interactionSource.collectIsDraggedAsState()\n    val shape = ShapeDefaults.byIndex(\n        index = index,\n        size = downloadedLanguages.size,\n        forceDefault = isDragged\n    )\n    SwipeToReveal(\n        state = state,\n        modifier = Modifier.animateItem(),\n        revealedContentEnd = {\n            Box(\n                Modifier\n                    .fillMaxSize()\n                    .container(\n                        color = MaterialTheme.colorScheme.errorContainer,\n                        shape = shape,\n                        autoShadowElevation = 0.dp,\n                        resultPadding = 0.dp\n                    )\n                    .hapticsClickable {\n                        scope.launch {\n                            state.animateTo(RevealValue.Default)\n                        }\n                        onWantDelete(lang)\n                    }\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.Delete,\n                    contentDescription = stringResource(R.string.delete),\n                    modifier = Modifier\n                        .padding(16.dp)\n                        .padding(end = 8.dp)\n                        .align(Alignment.CenterEnd),\n                    tint = MaterialTheme.colorScheme.onErrorContainer\n                )\n            }\n        },\n        directions = setOf(RevealDirection.EndToStart),\n        swipeableContent = {\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .container(\n                        shape = shape,\n                        color = animateColorAsState(\n                            if (selected) {\n                                MaterialTheme\n                                    .colorScheme\n                                    .mixedContainer\n                                    .copy(0.8f)\n                            } else EnhancedBottomSheetDefaults.contentContainerColor\n                        ).value,\n                        resultPadding = 0.dp\n                    )\n                    .hapticsCombinedClickable(\n                        onLongClick = {\n                            scope.launch {\n                                state.animateTo(RevealValue.FullyRevealedStart)\n                            }\n                        },\n                        onClick = {\n                            onValueChange(selected, lang)\n                        }\n                    )\n                    .padding(16.dp),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                AnimatedVisibility(visible = value.size > 1) {\n                    LocalMinimumInteractiveComponentSize.ProvidesValue(\n                        Dp.Unspecified\n                    ) {\n                        EnhancedCheckbox(\n                            checked = selected,\n                            onCheckedChange = {\n                                onValueChange(selected, lang)\n                            },\n                            modifier = Modifier.padding(end = 8.dp)\n                        )\n                    }\n                }\n                Column {\n                    Text(\n                        text = lang.name,\n                        style = LocalTextStyle.current.copy(\n                            fontSize = 16.sp,\n                            fontWeight = FontWeight.Medium,\n                            lineHeight = 18.sp\n                        )\n                    )\n                    if (lang.name != lang.localizedName) {\n                        Spacer(modifier = Modifier.height(2.dp))\n                        Text(\n                            text = lang.localizedName,\n                            fontSize = 12.sp,\n                            fontWeight = FontWeight.Normal,\n                            lineHeight = 14.sp,\n                            color = LocalContentColor.current.copy(alpha = 0.5f)\n                        )\n                    }\n                }\n                Spacer(modifier = Modifier.weight(1f))\n                Row(\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    modifier = Modifier.container()\n                ) {\n                    RecognitionType.entries.forEach { type ->\n                        Column(\n                            horizontalAlignment = Alignment.CenterHorizontally,\n                            verticalArrangement = Arrangement.Center,\n                            modifier = Modifier\n                                .clip(ShapeDefaults.circle)\n                                .hapticsClickable {\n                                    onValueChangeForced(value, type)\n                                }\n                        ) {\n                            val notDownloaded by remember(\n                                type,\n                                lang.downloaded\n                            ) {\n                                derivedStateOf {\n                                    type !in lang.downloaded\n                                }\n                            }\n                            val displayName by remember(type) {\n                                derivedStateOf {\n                                    type.displayName.first().uppercase()\n                                }\n                            }\n                            val green = Green\n                            val red = Red\n                            val color by remember(\n                                currentRecognitionType,\n                                red,\n                                green,\n                                lang.downloaded\n                            ) {\n                                derivedStateOf {\n                                    when (type) {\n                                        currentRecognitionType -> if (type in lang.downloaded) {\n                                            green\n                                        } else red\n\n                                        !in lang.downloaded -> red.copy(\n                                            0.3f\n                                        )\n\n                                        else -> green.copy(0.3f)\n                                    }\n                                }\n                            }\n                            Text(\n                                text = displayName,\n                                fontSize = 12.sp\n                            )\n                            Spacer(modifier = Modifier.height(4.dp))\n                            Icon(\n                                imageVector = if (notDownloaded) {\n                                    Icons.Rounded.Cancel\n                                } else Icons.Rounded.CheckCircle,\n                                contentDescription = null,\n                                tint = animateColorAsState(color).value,\n                                modifier = Modifier\n                                    .size(28.dp)\n                                    .border(\n                                        width = settingsState.borderWidth,\n                                        color = MaterialTheme.colorScheme.outlineVariant(),\n                                        shape = ShapeDefaults.circle\n                                    )\n                            )\n                        }\n                    }\n                }\n            }\n        },\n        interactionSource = interactionSource\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/FillableButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCircleShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun FillableButton(\n    modifier: Modifier,\n    onClick: () -> Unit,\n    content: @Composable RowScope.() -> Unit\n) {\n    Row(\n        modifier = modifier\n            .container(\n                color = MaterialTheme.colorScheme.secondaryContainer.copy(0.5f),\n                shape = AutoCircleShape(),\n                resultPadding = 0.dp\n            )\n            .hapticsClickable(onClick = onClick)\n            .padding(ButtonDefaults.ContentPadding),\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.Center\n    ) {\n        CompositionLocalProvider(\n            LocalContentColor provides MaterialTheme.colorScheme.onSecondaryContainer\n        ) {\n            content()\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/FilterSelectionBar.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.then\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\n\n@Composable\nfun FilterSelectionBar(\n    addedFilters: List<Filter<*>>,\n    onContrastClick: () -> Unit,\n    onThresholdClick: () -> Unit,\n    onSharpnessClick: () -> Unit,\n    modifier: Modifier = Modifier\n) {\n    val selectedIndices = remember(addedFilters) {\n        derivedStateOf {\n            setOfNotNull(\n                addedFilters.filterIsInstance<Filter.Contrast>().isNotEmpty().then(0),\n                addedFilters.filterIsInstance<Filter.Sharpen>().isNotEmpty().then(1),\n                addedFilters.filterIsInstance<Filter.Threshold>().isNotEmpty().then(2),\n            )\n        }\n    }.value\n\n    EnhancedButtonGroup(\n        itemCount = 3,\n        modifier = modifier.container(\n            ShapeDefaults.extraLarge\n        ),\n        activeButtonColor = MaterialTheme.colorScheme.secondaryContainer,\n        selectedIndices = selectedIndices,\n        onIndexChange = {\n            when (it) {\n                0 -> onContrastClick()\n                1 -> onSharpnessClick()\n                2 -> onThresholdClick()\n            }\n        },\n        title = {\n            Text(\n                text = stringResource(id = R.string.transformations),\n                textAlign = TextAlign.Center,\n                fontWeight = FontWeight.Medium,\n                modifier = Modifier.padding(vertical = 8.dp)\n            )\n        },\n        itemContent = {\n            val text = when (it) {\n                0 -> stringResource(id = R.string.contrast)\n                1 -> stringResource(id = R.string.sharpen)\n                else -> stringResource(id = R.string.threshold)\n            }\n\n            AutoSizeText(\n                text = text,\n                maxLines = 1\n            )\n        },\n        isScrollable = false\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/ModelTypeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.Segment\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.SegmentationMode\n\n@Composable\nfun ModelTypeSelector(\n    value: SegmentationMode,\n    onValueChange: (SegmentationMode) -> Unit\n) {\n    var showSelectionSheet by remember {\n        mutableStateOf(false)\n    }\n    PreferenceItem(\n        modifier = Modifier.fillMaxWidth(),\n        title = stringResource(id = R.string.segmentation_mode),\n        subtitle = stringResource(id = value.title),\n        onClick = {\n            showSelectionSheet = true\n        },\n        shape = ShapeDefaults.extraLarge,\n        startIcon = Icons.AutoMirrored.Outlined.Segment,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showSelectionSheet,\n        onDismiss = {\n            showSelectionSheet = it\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    showSelectionSheet = false\n                }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.segmentation_mode),\n                icon = Icons.AutoMirrored.Outlined.Segment\n            )\n        }\n    ) {\n        LazyColumn(\n            contentPadding = PaddingValues(16.dp),\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            itemsIndexed(\n                items = SegmentationMode.entries,\n                key = { _, e -> e.name }\n            ) { index, mode ->\n                PreferenceItem(\n                    modifier = Modifier.fillMaxWidth(),\n                    title = stringResource(id = mode.title),\n                    onClick = {\n                        onValueChange(mode)\n                    },\n                    containerColor = animateColorAsState(\n                        if (value == mode) MaterialTheme.colorScheme.secondaryContainer\n                        else MaterialTheme.colorScheme.surfaceContainer\n                    ).value,\n                    shape = ShapeDefaults.byIndex(\n                        index = index,\n                        size = SegmentationMode.entries.size\n                    )\n                )\n            }\n        }\n    }\n}\n\nprivate inline val SegmentationMode.title: Int\n    get() = when (this) {\n        SegmentationMode.PSM_OSD_ONLY -> R.string.segmentation_mode_osd_only\n        SegmentationMode.PSM_AUTO_OSD -> R.string.segmentation_mode_auto_osd\n        SegmentationMode.PSM_AUTO_ONLY -> R.string.segmentation_mode_auto_only\n        SegmentationMode.PSM_AUTO -> R.string.segmentation_mode_auto\n        SegmentationMode.PSM_SINGLE_COLUMN -> R.string.segmentation_mode_single_column\n        SegmentationMode.PSM_SINGLE_BLOCK_VERT_TEXT -> R.string.segmentation_mode_single_block_vert_text\n        SegmentationMode.PSM_SINGLE_BLOCK -> R.string.segmentation_mode_single_block\n        SegmentationMode.PSM_SINGLE_LINE -> R.string.segmentation_mode_single_line\n        SegmentationMode.PSM_SINGLE_WORD -> R.string.segmentation_mode_single_word\n        SegmentationMode.PSM_CIRCLE_WORD -> R.string.segmentation_mode_circle_word\n        SegmentationMode.PSM_SINGLE_CHAR -> R.string.segmentation_mode_single_char\n        SegmentationMode.PSM_SPARSE_TEXT -> R.string.segmentation_mode_sparse_text\n        SegmentationMode.PSM_SPARSE_TEXT_OSD -> R.string.segmentation_mode_sparse_text_osd\n        SegmentationMode.PSM_RAW_LINE -> R.string.segmentation_mode_raw_line\n    }\n"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/OCRLanguageColumnForSearch.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\n\n@Composable\ninternal fun OCRLanguageColumnForSearch(\n    languagesForSearch: List<OCRLanguage>,\n    value: List<OCRLanguage>,\n    currentRecognitionType: RecognitionType,\n    onValueChange: (List<OCRLanguage>, RecognitionType) -> Unit,\n    allowMultipleLanguagesSelection: Boolean\n) {\n    fun onValueChangeImpl(\n        selected: Boolean,\n        type: RecognitionType,\n        lang: OCRLanguage\n    ) {\n        if (allowMultipleLanguagesSelection) {\n            if (selected) {\n                onValueChange(\n                    (value - lang).distinct(),\n                    type\n                )\n            } else onValueChange(\n                (value + lang).distinct(),\n                type\n            )\n        } else onValueChange(listOf(lang), type)\n    }\n\n    LazyColumn(\n        contentPadding = PaddingValues(16.dp),\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        itemsIndexed(\n            items = languagesForSearch,\n            key = { _, l -> l.code }\n        ) { index, lang ->\n            val selected by remember(value, lang) {\n                derivedStateOf {\n                    lang in value\n                }\n            }\n            PreferenceItem(\n                title = lang.name,\n                subtitle = lang.localizedName.takeIf { it != lang.name },\n                onClick = {\n                    onValueChangeImpl(\n                        selected = selected,\n                        type = currentRecognitionType,\n                        lang = lang\n                    )\n                },\n                containerColor = animateColorAsState(\n                    if (selected) {\n                        MaterialTheme.colorScheme.surfaceColorAtElevation(\n                            20.dp\n                        )\n                    } else EnhancedBottomSheetDefaults.contentContainerColor\n                ).value,\n                shape = ShapeDefaults.byIndex(\n                    index = index,\n                    size = languagesForSearch.size\n                ),\n                modifier = Modifier\n                    .animateItem()\n                    .fillMaxWidth()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/OCRLanguagesColumn.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.UploadFile\nimport androidx.compose.material.icons.rounded.Download\nimport androidx.compose.material.icons.rounded.DownloadDone\nimport androidx.compose.material.icons.rounded.MultipleStop\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.DownloadFile\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.negativePadding\nimport com.t8rin.imagetoolbox.core.ui.widget.other.GradientEdge\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\n\n@Composable\ninternal fun OCRLanguagesColumn(\n    listState: LazyListState,\n    allowMultipleLanguagesSelection: Boolean,\n    value: List<OCRLanguage>,\n    currentRecognitionType: RecognitionType,\n    onValueChange: (List<OCRLanguage>, RecognitionType) -> Unit,\n    onImportLanguages: () -> Unit,\n    onExportLanguages: () -> Unit,\n    downloadedLanguages: List<OCRLanguage>,\n    notDownloadedLanguages: List<OCRLanguage>,\n    onDeleteLanguage: (OCRLanguage, List<RecognitionType>) -> Unit,\n    onToggleAllowMultipleLanguagesSelection: () -> Unit\n) {\n    fun onValueChangeImpl(\n        selected: Boolean,\n        type: RecognitionType,\n        lang: OCRLanguage\n    ) {\n        if (allowMultipleLanguagesSelection) {\n            if (selected) {\n                onValueChange(\n                    (value - lang).distinct(),\n                    type\n                )\n            } else onValueChange(\n                (value + lang).distinct(),\n                type\n            )\n        } else onValueChange(listOf(lang), type)\n    }\n\n    var deleteDialogData by remember {\n        mutableStateOf<OCRLanguage?>(null)\n    }\n\n    DeleteLanguageDialog(\n        languageToDelete = deleteDialogData,\n        onDismiss = { deleteDialogData = null },\n        onDeleteLanguage = onDeleteLanguage,\n        currentRecognitionType = currentRecognitionType\n    )\n\n    LazyColumn(\n        state = listState,\n        contentPadding = PaddingValues(\n            start = 16.dp,\n            bottom = 16.dp,\n            end = 16.dp\n        ),\n        verticalArrangement = Arrangement.spacedBy(4.dp),\n        flingBehavior = enhancedFlingBehavior()\n    ) {\n        stickyHeader {\n            Column(\n                modifier = Modifier\n                    .negativePadding(horizontal = 16.dp)\n                    .background(EnhancedBottomSheetDefaults.containerColor)\n                    .padding(horizontal = 16.dp)\n            ) {\n                Spacer(modifier = Modifier.height(20.dp))\n                PreferenceRowSwitch(\n                    title = stringResource(R.string.allow_multiple_languages),\n                    containerColor = animateColorAsState(\n                        if (allowMultipleLanguagesSelection) MaterialTheme.colorScheme.primaryContainer\n                        else MaterialTheme.colorScheme.surfaceContainer\n                    ).value,\n                    modifier = Modifier.fillMaxWidth(),\n                    shape = ShapeDefaults.extremeLarge,\n                    checked = allowMultipleLanguagesSelection,\n                    startIcon = Icons.Rounded.MultipleStop,\n                    onClick = {\n                        if (!it) {\n                            onValueChange(\n                                value.take(1),\n                                currentRecognitionType\n                            )\n                        }\n                        onToggleAllowMultipleLanguagesSelection()\n                    }\n                )\n                Spacer(modifier = Modifier.height(8.dp))\n            }\n            GradientEdge(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .height(16.dp),\n                startColor = EnhancedBottomSheetDefaults.containerColor,\n                endColor = Color.Transparent\n            )\n        }\n        item {\n            Column(\n                modifier = Modifier\n                    .container(\n                        shape = ShapeDefaults.large,\n                        color = EnhancedBottomSheetDefaults.contentContainerColor,\n                        resultPadding = 0.dp\n                    )\n                    .padding(8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.Center\n            ) {\n                Spacer(modifier = Modifier.height(8.dp))\n                Text(\n                    text = stringResource(R.string.backup_ocr_models),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n                Row(\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    FillableButton(\n                        onClick = onImportLanguages,\n                        modifier = Modifier.weight(1f)\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.DownloadFile,\n                            contentDescription = null\n                        )\n                        Spacer(modifier = Modifier.width(8.dp))\n                        Text(text = stringResource(R.string.import_word))\n                    }\n                    Spacer(modifier = Modifier.width(4.dp))\n                    FillableButton(\n                        onClick = onExportLanguages,\n                        modifier = Modifier.weight(1f)\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.UploadFile,\n                            contentDescription = null\n                        )\n                        Spacer(modifier = Modifier.width(8.dp))\n                        Text(text = stringResource(R.string.export))\n                    }\n                }\n            }\n        }\n        if (downloadedLanguages.isNotEmpty()) {\n            item {\n                TitleItem(\n                    icon = Icons.Rounded.DownloadDone,\n                    text = stringResource(id = R.string.downloaded_languages)\n                )\n            }\n        }\n        itemsIndexed(\n            items = downloadedLanguages,\n            key = { _, l -> l.code }\n        ) { index, lang ->\n            DownloadedLanguageItem(\n                index = index,\n                value = value,\n                lang = lang,\n                downloadedLanguages = downloadedLanguages,\n                onWantDelete = { deleteDialogData = it },\n                onValueChange = { selected, language ->\n                    onValueChangeImpl(\n                        selected = selected,\n                        type = currentRecognitionType,\n                        lang = language\n                    )\n                },\n                onValueChangeForced = onValueChange,\n                currentRecognitionType = currentRecognitionType\n            )\n        }\n        if (notDownloadedLanguages.isNotEmpty()) {\n            item {\n                TitleItem(\n                    icon = Icons.Rounded.Download,\n                    text = stringResource(id = R.string.available_languages)\n                )\n            }\n        }\n        itemsIndexed(\n            items = notDownloadedLanguages,\n            key = { _, l -> l.code }\n        ) { index, lang ->\n            val selected by remember(value, lang) {\n                derivedStateOf {\n                    lang in value\n                }\n            }\n            PreferenceItem(\n                title = lang.name,\n                subtitle = lang.localizedName.takeIf { it != lang.name },\n                onClick = {\n                    onValueChangeImpl(\n                        selected = selected,\n                        type = currentRecognitionType,\n                        lang = lang\n                    )\n                },\n                containerColor = animateColorAsState(\n                    if (selected) {\n                        MaterialTheme.colorScheme.surfaceColorAtElevation(20.dp)\n                    } else EnhancedBottomSheetDefaults.contentContainerColor\n                ).value,\n                shape = ShapeDefaults.byIndex(\n                    index = index,\n                    size = notDownloadedLanguages.size\n                ),\n                modifier = Modifier\n                    .animateItem()\n                    .fillMaxWidth()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/OCRTextPreviewItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.text.BasicTextField\nimport androidx.compose.foundation.text.selection.SelectionContainer\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.KeyboardArrowDown\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun OCRTextPreviewItem(\n    text: String?,\n    onTextEdit: (String) -> Unit,\n    isLoading: Boolean,\n    loadingProgress: Int,\n    accuracy: Int\n) {\n    var expanded by rememberSaveable {\n        mutableStateOf(true)\n    }\n\n    AnimatedContent(targetState = isLoading) { loading ->\n        Box(\n            modifier = Modifier\n                .fillMaxWidth()\n                .container(shape = ShapeDefaults.extraLarge)\n                .padding(8.dp),\n            contentAlignment = Alignment.Center\n        ) {\n            if (loading) {\n                Box(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .border(\n                            width = 2.dp,\n                            color = MaterialTheme.colorScheme.outline,\n                            shape = ShapeDefaults.small\n                        ),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Box(\n                        modifier = Modifier\n                            .padding(24.dp)\n                            .size(72.dp)\n                    ) {\n                        EnhancedLoadingIndicator(\n                            progress = loadingProgress / 100f,\n                            loaderSize = 36.dp\n                        )\n                    }\n                }\n            } else {\n                Column(\n                    Modifier\n                        .fillMaxWidth()\n                        .border(\n                            width = 2.dp,\n                            color = MaterialTheme.colorScheme.outline,\n                            shape = ShapeDefaults.small\n                        )\n                        .padding(16.dp)\n                        .animateContentSizeNoClip()\n                ) {\n                    Row(\n                        verticalAlignment = Alignment.Top\n                    ) {\n                        Text(\n                            text = stringResource(R.string.accuracy, accuracy),\n                            style = MaterialTheme.typography.bodyMedium,\n                            textAlign = TextAlign.Start,\n                            color = MaterialTheme.colorScheme.outline,\n                            modifier = Modifier.weight(1f)\n                        )\n                        if ((text?.length ?: 0) >= 100) {\n                            val rotation by animateFloatAsState(\n                                if (expanded) 180f\n                                else 0f\n                            )\n                            EnhancedIconButton(\n                                forceMinimumInteractiveComponentSize = false,\n                                containerColor = Color.Transparent,\n                                onClick = { expanded = !expanded },\n                                modifier = Modifier.size(24.dp)\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.KeyboardArrowDown,\n                                    contentDescription = \"Expand\",\n                                    modifier = Modifier.rotate(rotation)\n                                )\n                            }\n                        }\n                    }\n                    AnimatedContent(\n                        targetState = expanded,\n                        transitionSpec = {\n                            fadeIn(tween(200)) togetherWith fadeOut(tween(200))\n                        }\n                    ) { showFull ->\n                        SelectionContainer {\n                            if (showFull) {\n                                BasicTextField(\n                                    value = text\n                                        ?: stringResource(R.string.picture_has_no_text),\n                                    onValueChange = onTextEdit,\n                                    enabled = text != null,\n                                    textStyle = LocalTextStyle.current.copy(\n                                        color = LocalContentColor.current\n                                    ),\n                                    cursorBrush = SolidColor(MaterialTheme.colorScheme.primary)\n                                )\n                            } else {\n                                Text(\n                                    text = text ?: stringResource(R.string.picture_has_no_text),\n                                    maxLines = if (text == null) Int.MAX_VALUE else 3,\n                                    overflow = TextOverflow.Ellipsis,\n                                    style = LocalTextStyle.current\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/OcrEngineModeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Engineering\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OcrEngineMode\n\n@Composable\nfun OcrEngineModeSelector(\n    value: OcrEngineMode,\n    onValueChange: (OcrEngineMode) -> Unit\n) {\n    var showSelectionSheet by remember {\n        mutableStateOf(false)\n    }\n    PreferenceItem(\n        modifier = Modifier.fillMaxWidth(),\n        title = stringResource(id = R.string.engine_mode),\n        subtitle = stringResource(id = value.title),\n        onClick = {\n            showSelectionSheet = true\n        },\n        shape = ShapeDefaults.extraLarge,\n        startIcon = Icons.Outlined.Engineering,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showSelectionSheet,\n        onDismiss = {\n            showSelectionSheet = it\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    showSelectionSheet = false\n                }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.engine_mode),\n                icon = Icons.Outlined.Engineering\n            )\n        }\n    ) {\n        LazyColumn(\n            contentPadding = PaddingValues(16.dp),\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            itemsIndexed(OcrEngineMode.entries) { index, mode ->\n                PreferenceItem(\n                    modifier = Modifier.fillMaxWidth(),\n                    title = stringResource(id = mode.title),\n                    onClick = {\n                        onValueChange(mode)\n                    },\n                    containerColor = animateColorAsState(\n                        if (value == mode) MaterialTheme.colorScheme.secondaryContainer\n                        else MaterialTheme.colorScheme.surfaceContainer\n                    ).value,\n                    shape = ShapeDefaults.byIndex(\n                        index = index,\n                        size = OcrEngineMode.entries.size\n                    )\n                )\n            }\n        }\n    }\n}\n\nprivate inline val OcrEngineMode.title: Int\n    get() = when (this) {\n        OcrEngineMode.TESSERACT_ONLY -> R.string.legacy\n        OcrEngineMode.LSTM_ONLY -> R.string.lstm_network\n        OcrEngineMode.TESSERACT_LSTM_COMBINED -> R.string.legacy_and_lstm\n        OcrEngineMode.DEFAULT -> R.string.defaultt\n    }\n"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/RecognitionTypeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\n\n@Composable\nfun RecognitionTypeSelector(\n    value: RecognitionType,\n    onValueChange: (RecognitionType) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Box(\n        modifier = modifier\n            .container(shape = ShapeDefaults.extraLarge)\n            .animateContentSizeNoClip(),\n        contentAlignment = Alignment.Center\n    ) {\n        EnhancedButtonGroup(\n            modifier = Modifier.padding(8.dp),\n            enabled = true,\n            items = RecognitionType.entries.map { it.translatedName },\n            selectedIndex = RecognitionType.entries.indexOf(value),\n            title = stringResource(id = R.string.recognition_type),\n            onIndexChange = {\n                onValueChange(RecognitionType.entries[it])\n            }\n        )\n    }\n}\n\nprivate val RecognitionType.translatedName: String\n    @Composable\n    get() = when (this) {\n        RecognitionType.Best -> stringResource(id = R.string.best)\n        RecognitionType.Fast -> stringResource(id = R.string.fast)\n        RecognitionType.Standard -> stringResource(id = R.string.standard)\n    }"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/RecognizeLanguageSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.outlined.Language\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Search\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\n\n@Composable\nfun RecognizeLanguageSelector(\n    currentRecognitionType: RecognitionType,\n    value: List<OCRLanguage>,\n    availableLanguages: List<OCRLanguage>,\n    onValueChange: (List<OCRLanguage>, RecognitionType) -> Unit,\n    onDeleteLanguage: (OCRLanguage, List<RecognitionType>) -> Unit,\n    onImportLanguages: () -> Unit,\n    onExportLanguages: () -> Unit\n) {\n    var showDetailedLanguageSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItem(\n        modifier = Modifier.fillMaxWidth(),\n        title = stringResource(id = R.string.language),\n        subtitle = value.joinToString(separator = \", \") { it.localizedName },\n        onClick = {\n            showDetailedLanguageSheet = true\n        },\n        containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,\n        shape = ShapeDefaults.extraLarge,\n        startIcon = Icons.Outlined.Language,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    var isSearching by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var searchKeyword by rememberSaveable {\n        mutableStateOf(\"\")\n    }\n\n    var allowMultipleLanguagesSelection by rememberSaveable {\n        mutableStateOf(value.isNotEmpty())\n    }\n\n    EnhancedModalBottomSheet(\n        visible = showDetailedLanguageSheet,\n        onDismiss = {\n            showDetailedLanguageSheet = it\n        },\n        enableBottomContentWeight = false,\n        confirmButton = {},\n        title = {\n            AnimatedContent(\n                targetState = isSearching\n            ) { searching ->\n                if (searching) {\n                    BackHandler {\n                        searchKeyword = \"\"\n                        isSearching = false\n                    }\n                    ProvideTextStyle(value = MaterialTheme.typography.bodyLarge) {\n                        RoundedTextField(\n                            maxLines = 1,\n                            hint = { Text(stringResource(id = R.string.search_here)) },\n                            keyboardOptions = KeyboardOptions.Default.copy(\n                                imeAction = ImeAction.Search,\n                                autoCorrectEnabled = null\n                            ),\n                            value = searchKeyword,\n                            onValueChange = {\n                                searchKeyword = it\n                            },\n                            startIcon = {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        searchKeyword = \"\"\n                                        isSearching = false\n                                    },\n                                    modifier = Modifier.padding(start = 4.dp)\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                        contentDescription = stringResource(R.string.exit),\n                                        tint = MaterialTheme.colorScheme.onSurface\n                                    )\n                                }\n                            },\n                            endIcon = {\n                                AnimatedVisibility(\n                                    visible = searchKeyword.isNotEmpty(),\n                                    enter = fadeIn() + scaleIn(),\n                                    exit = fadeOut() + scaleOut()\n                                ) {\n                                    EnhancedIconButton(\n                                        onClick = {\n                                            searchKeyword = \"\"\n                                        },\n                                        modifier = Modifier.padding(end = 4.dp)\n                                    ) {\n                                        Icon(\n                                            imageVector = Icons.Rounded.Close,\n                                            contentDescription = stringResource(R.string.close),\n                                            tint = MaterialTheme.colorScheme.onSurface\n                                        )\n                                    }\n                                }\n                            },\n                            shape = ShapeDefaults.circle\n                        )\n                    }\n                } else {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically\n                    ) {\n                        TitleItem(\n                            text = stringResource(id = R.string.language),\n                            icon = Icons.Outlined.Language\n                        )\n                        Spacer(modifier = Modifier.weight(1f))\n                        EnhancedIconButton(\n                            onClick = { isSearching = true },\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Search,\n                                contentDescription = stringResource(R.string.search_here)\n                            )\n                        }\n                        EnhancedButton(\n                            containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                            onClick = {\n                                showDetailedLanguageSheet = false\n                            }\n                        ) {\n                            Text(stringResource(R.string.close))\n                        }\n                    }\n                }\n            }\n        },\n        sheetContent = {\n            RecognizeLanguageSelectorSheetContent(\n                value = value,\n                currentRecognitionType = currentRecognitionType,\n                onValueChange = onValueChange,\n                onImportLanguages = onImportLanguages,\n                onExportLanguages = onExportLanguages,\n                isSearching = isSearching,\n                searchKeyword = searchKeyword,\n                availableLanguages = availableLanguages,\n                onDeleteLanguage = onDeleteLanguage,\n                allowMultipleLanguagesSelection = allowMultipleLanguagesSelection,\n                onToggleAllowMultipleLanguagesSelection = {\n                    allowMultipleLanguagesSelection = !allowMultipleLanguagesSelection\n                }\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/RecognizeLanguageSelectorSheetContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\nimport kotlinx.coroutines.delay\n\n@Composable\ninternal fun RecognizeLanguageSelectorSheetContent(\n    value: List<OCRLanguage>,\n    currentRecognitionType: RecognitionType,\n    onValueChange: (List<OCRLanguage>, RecognitionType) -> Unit,\n    onImportLanguages: () -> Unit,\n    onExportLanguages: () -> Unit,\n    isSearching: Boolean,\n    searchKeyword: String,\n    availableLanguages: List<OCRLanguage>,\n    onDeleteLanguage: (OCRLanguage, List<RecognitionType>) -> Unit,\n    allowMultipleLanguagesSelection: Boolean,\n    onToggleAllowMultipleLanguagesSelection: () -> Unit\n) {\n    val downloadedLanguages by remember(availableLanguages) {\n        derivedStateOf {\n            availableLanguages.filter {\n                it.downloaded.isNotEmpty()\n            }.sortedByDescending {\n                it.downloaded.size\n            }\n        }\n    }\n    val notDownloadedLanguages by remember(availableLanguages, value) {\n        derivedStateOf {\n            availableLanguages.filter {\n                it.downloaded.isEmpty()\n            }.sortedByDescending {\n                it in value\n            }\n        }\n    }\n\n    var languagesForSearch by remember {\n        mutableStateOf(\n            downloadedLanguages + notDownloadedLanguages\n        )\n    }\n\n    LaunchedEffect(searchKeyword) {\n        delay(400L) // Debounce calculations\n        if (searchKeyword.isEmpty()) {\n            languagesForSearch = downloadedLanguages + notDownloadedLanguages\n            return@LaunchedEffect\n        }\n\n        languagesForSearch = (downloadedLanguages + notDownloadedLanguages).filter {\n            it.name.contains(\n                other = searchKeyword,\n                ignoreCase = true\n            ).or(\n                it.localizedName.contains(\n                    other = searchKeyword,\n                    ignoreCase = true\n                )\n            )\n        }.sortedBy { it.name }\n    }\n\n    AnimatedContent(targetState = value.isEmpty()) { loading ->\n        if (loading) {\n            Box(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(16.dp),\n                contentAlignment = Alignment.Center\n            ) {\n                EnhancedLoadingIndicator()\n            }\n        } else {\n            val listState = rememberLazyListState()\n            LaunchedEffect(downloadedLanguages) {\n                downloadedLanguages.indexOf(value.firstOrNull()).takeIf {\n                    it != -1\n                }.let {\n                    listState.scrollToItem(it ?: 0)\n                }\n            }\n\n            AnimatedContent(\n                targetState = isSearching to languagesForSearch.isNotEmpty()\n            ) { (searching, haveData) ->\n                if (searching) {\n                    if (haveData) {\n                        OCRLanguageColumnForSearch(\n                            languagesForSearch = languagesForSearch,\n                            value = value,\n                            currentRecognitionType = currentRecognitionType,\n                            onValueChange = onValueChange,\n                            allowMultipleLanguagesSelection = allowMultipleLanguagesSelection\n                        )\n                    } else {\n                        Column(\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .fillMaxHeight(0.5f),\n                            horizontalAlignment = Alignment.CenterHorizontally,\n                            verticalArrangement = Arrangement.Center\n                        ) {\n                            Spacer(Modifier.weight(1f))\n                            Text(\n                                text = stringResource(R.string.nothing_found_by_search),\n                                fontSize = 18.sp,\n                                textAlign = TextAlign.Center,\n                                modifier = Modifier.padding(\n                                    start = 24.dp,\n                                    end = 24.dp,\n                                    top = 8.dp,\n                                    bottom = 8.dp\n                                )\n                            )\n                            Icon(\n                                imageVector = Icons.Rounded.SearchOff,\n                                contentDescription = null,\n                                modifier = Modifier\n                                    .weight(2f)\n                                    .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                                    .fillMaxSize()\n                            )\n                            Spacer(Modifier.weight(1f))\n                        }\n                    }\n                } else {\n                    OCRLanguagesColumn(\n                        listState = listState,\n                        allowMultipleLanguagesSelection = allowMultipleLanguagesSelection,\n                        value = value,\n                        currentRecognitionType = currentRecognitionType,\n                        onValueChange = onValueChange,\n                        onImportLanguages = onImportLanguages,\n                        onExportLanguages = onExportLanguages,\n                        downloadedLanguages = downloadedLanguages,\n                        notDownloadedLanguages = notDownloadedLanguages,\n                        onDeleteLanguage = onDeleteLanguage,\n                        onToggleAllowMultipleLanguagesSelection = onToggleAllowMultipleLanguagesSelection\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/RecognizeTextButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CopyAll\nimport androidx.compose.material.icons.rounded.Save\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent\n\n@Composable\ninternal fun RecognizeTextButtons(\n    component: RecognizeTextComponent,\n    multipleImagePicker: ImagePicker,\n    actions: @Composable RowScope.() -> Unit\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    val type = component.type\n    val isExtraction = type is Screen.RecognizeText.Type.Extraction\n\n    val isHaveText = component.editedText.orEmpty().isNotEmpty()\n\n    val copyText: () -> Unit = {\n        component.editedText?.let(Clipboard::copy)\n    }\n\n    var showOneTimeImagePickingDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var showFolderSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    val saveSearchablePdfLauncher = rememberFileCreator(\n        mimeType = MimeType.Pdf,\n        onSuccess = component::saveSearchablePdfTo\n    )\n    val save: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.save(\n            oneTimeSaveLocationUri = it\n        )\n    }\n    BottomButtonsBlock(\n        isNoData = type == null,\n        onSecondaryButtonClick = multipleImagePicker::pickImage,\n        onSecondaryButtonLongClick = {\n            showOneTimeImagePickingDialog = true\n        },\n        onPrimaryButtonClick = {\n            if (isExtraction) {\n                copyText()\n            } else if (type is Screen.RecognizeText.Type.WriteToSearchablePdf) {\n                saveSearchablePdfLauncher.make(component.generateSearchablePdfFilename())\n            } else {\n                save(null)\n            }\n        },\n        onPrimaryButtonLongClick = {\n            if (isExtraction) {\n                copyText()\n            } else {\n                showFolderSelectionDialog = true\n            }\n        },\n        primaryButtonIcon = if (isExtraction) {\n            Icons.Rounded.CopyAll\n        } else {\n            Icons.Rounded.Save\n        },\n        isPrimaryButtonVisible = if (isExtraction) isHaveText else type != null,\n        actions = {\n            if (isPortrait) actions()\n        },\n        showNullDataButtonAsContainer = true\n    )\n    OneTimeSaveLocationSelectionDialog(\n        visible = showFolderSelectionDialog,\n        onDismiss = { showFolderSelectionDialog = false },\n        onSaveRequest = save\n    )\n    OneTimeImagePickingDialog(\n        onDismiss = { showOneTimeImagePickingDialog = false },\n        picker = Picker.Multiple,\n        imagePicker = multipleImagePicker,\n        visible = showOneTimeImagePickingDialog\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/RecognizeTextControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CameraAlt\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.CropSmall\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ImagePickerMode\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.localImagePickerMode\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageTransformBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.other.LinkPreviewList\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent\n\n@Composable\ninternal fun RecognizeTextControls(\n    component: RecognizeTextComponent,\n    onShowCropper: () -> Unit\n) {\n    val type = component.type\n    val isExtraction = type is Screen.RecognizeText.Type.Extraction\n    val imagePickerMode = localImagePickerMode(Picker.Single)\n\n    val editedText = component.editedText\n\n    val captureImageLauncher = rememberImagePicker(ImagePickerMode.CameraCapture) { list ->\n        component.updateType(\n            type = Screen.RecognizeText.Type.Extraction(list.firstOrNull())\n        )\n    }\n\n    val captureImage = captureImageLauncher::pickImage\n\n    val exportLanguagesPicker = rememberFileCreator(\n        mimeType = MimeType.Zip,\n        onSuccess = component::exportLanguagesTo\n    )\n\n    val importLanguagesPicker = rememberFilePicker(\n        mimeType = MimeType.Zip,\n        onSuccess = { uri: Uri ->\n            component.importLanguagesFrom(\n                uri = uri,\n                onFailure = AppToastHost::showFailureToast\n            )\n        }\n    )\n\n    val onExportLanguages: () -> Unit = {\n        exportLanguagesPicker.make(component.generateExportFilename())\n    }\n\n    val onImportLanguages: () -> Unit = importLanguagesPicker::pickFile\n\n    if (isExtraction) {\n        ImageTransformBar(\n            onRotateLeft = component::rotateBitmapLeft,\n            onFlip = component::flipImage,\n            onRotateRight = component::rotateBitmapRight\n        ) {\n            if (imagePickerMode != ImagePickerMode.CameraCapture) {\n                EnhancedIconButton(\n                    containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                    contentColor = MaterialTheme.colorScheme.onTertiaryContainer,\n                    onClick = captureImage\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.CameraAlt,\n                        contentDescription = stringResource(R.string.camera)\n                    )\n                }\n                Spacer(Modifier.weight(1f))\n            }\n            EnhancedIconButton(\n                containerColor = MaterialTheme.colorScheme.mixedContainer,\n                contentColor = MaterialTheme.colorScheme.onMixedContainer,\n                onClick = onShowCropper\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.CropSmall,\n                    contentDescription = stringResource(R.string.crop)\n                )\n            }\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n    }\n    FilterSelectionBar(\n        addedFilters = component.filtersAdded,\n        onContrastClick = component::toggleContrastFilter,\n        onThresholdClick = component::toggleThresholdFilter,\n        onSharpnessClick = component::toggleSharpnessFilter\n    )\n    Spacer(modifier = Modifier.height(16.dp))\n    RecognizeLanguageSelector(\n        currentRecognitionType = component.recognitionType,\n        value = component.selectedLanguages,\n        availableLanguages = component.languages,\n        onValueChange = { codeList, recognitionType ->\n            component.onLanguagesSelected(codeList)\n            component.setRecognitionType(recognitionType)\n            component.startRecognition()\n        },\n        onDeleteLanguage = { language, types ->\n            component.deleteLanguage(\n                language = language,\n                types = types\n            )\n        },\n        onImportLanguages = onImportLanguages,\n        onExportLanguages = onExportLanguages\n    )\n    if (isExtraction) {\n        LinkPreviewList(\n            text = editedText ?: \"\",\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(top = 8.dp)\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        OCRTextPreviewItem(\n            text = editedText,\n            onTextEdit = { newText ->\n                if (editedText != null) {\n                    component.updateEditedText(newText)\n                }\n            },\n            isLoading = component.isTextLoading,\n            loadingProgress = component.textLoadingProgress,\n            accuracy = component.recognitionData?.accuracy ?: 0\n        )\n    }\n    Spacer(modifier = Modifier.height(8.dp))\n    RecognitionTypeSelector(\n        value = component.recognitionType,\n        onValueChange = component::setRecognitionType\n    )\n    Spacer(modifier = Modifier.height(8.dp))\n    ModelTypeSelector(\n        value = component.segmentationMode,\n        onValueChange = component::setSegmentationMode\n    )\n    Spacer(modifier = Modifier.height(8.dp))\n    OcrEngineModeSelector(\n        value = component.ocrEngineMode,\n        onValueChange = component::setOcrEngineMode\n    )\n    Spacer(modifier = Modifier.height(8.dp))\n    TessParamsSelector(\n        value = component.params,\n        onValueChange = component::updateParams,\n        modifier = Modifier.fillMaxWidth()\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/RecognizeTextDownloadDataDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.SignalCellularConnectedNoInternet0Bar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport com.t8rin.imagetoolbox.core.domain.utils.humanFileSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent\n\n@Composable\ninternal fun RecognizeTextDownloadDataDialog(component: RecognizeTextComponent) {\n    val downloadDialogData = component.downloadDialogData\n\n    if (downloadDialogData.isNotEmpty()) {\n        var progress by rememberSaveable(downloadDialogData) {\n            mutableFloatStateOf(0f)\n        }\n        var dataRemaining by rememberSaveable(downloadDialogData) {\n            mutableStateOf(\"\")\n        }\n        DownloadLanguageDialog(\n            downloadDialogData = downloadDialogData,\n            onDownloadRequest = { downloadData ->\n                component.downloadTrainData(\n                    type = downloadData.firstOrNull()?.type\n                        ?: RecognitionType.Standard,\n                    languageCode = downloadDialogData.joinToString(separator = \"+\") { it.languageCode },\n                    onProgress = { (p, size) ->\n                        dataRemaining = humanFileSize(size)\n                        progress = p\n                    },\n                    onComplete = {\n                        component.clearDownloadDialogData()\n                        AppToastHost.showConfetti()\n                        component.startRecognition()\n                    }\n                )\n            },\n            downloadProgress = progress,\n            dataRemaining = dataRemaining,\n            onNoConnection = {\n                component.clearDownloadDialogData()\n                AppToastHost.showToast(\n                    message = getString(R.string.no_connection),\n                    icon = Icons.Outlined.SignalCellularConnectedNoInternet0Bar,\n                    duration = ToastDuration.Long\n                )\n            },\n            onDismiss = component::clearDownloadDialogData\n        )\n    }\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/RecognizeTextNoDataControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileOpen\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.localImagePickerMode\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent\n\n@Composable\ninternal fun RecognizeTextNoDataControls(component: RecognizeTextComponent) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    val imagePickerMode = localImagePickerMode(Picker.Single)\n\n    val imagePicker = rememberImagePicker(imagePickerMode) { list ->\n        component.updateType(\n            type = Screen.RecognizeText.Type.Extraction(list.firstOrNull())\n        )\n    }\n\n    val writeToFilePicker = rememberImagePicker { uris: List<Uri> ->\n        component.updateType(\n            type = Screen.RecognizeText.Type.WriteToFile(uris)\n        )\n    }\n\n    val writeToMetadataPicker = rememberImagePicker { uris: List<Uri> ->\n        component.updateType(\n            type = Screen.RecognizeText.Type.WriteToMetadata(uris)\n        )\n    }\n\n    val writeToSearchablePdfPicker = rememberImagePicker { uris: List<Uri> ->\n        component.updateType(\n            type = Screen.RecognizeText.Type.WriteToSearchablePdf(uris)\n        )\n    }\n\n    val types = remember {\n        Screen.RecognizeText.Type.entries\n    }\n    val preference1 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[0].title),\n            subtitle = stringResource(types[0].subtitle),\n            startIcon = types[0].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = imagePicker::pickImage\n        )\n    }\n    val preference2 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[1].title),\n            subtitle = stringResource(types[1].subtitle),\n            startIcon = types[1].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                if (component.selectionSheetData.isNotEmpty()) {\n                    component.updateType(\n                        type = Screen.RecognizeText.Type.WriteToFile(component.selectionSheetData)\n                    )\n                    component.hideSelectionTypeSheet()\n                } else {\n                    writeToFilePicker.pickImage()\n                }\n            }\n        )\n    }\n    val preference3 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[2].title),\n            subtitle = stringResource(types[2].subtitle),\n            startIcon = types[2].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                if (component.selectionSheetData.isNotEmpty()) {\n                    component.updateType(\n                        type = Screen.RecognizeText.Type.WriteToMetadata(component.selectionSheetData)\n                    )\n                    component.hideSelectionTypeSheet()\n                } else {\n                    writeToMetadataPicker.pickImage()\n                }\n            }\n        )\n    }\n    val preference4 = @Composable {\n        PreferenceItem(\n            title = stringResource(types[3].title),\n            subtitle = stringResource(types[3].subtitle),\n            startIcon = types[3].icon,\n            modifier = Modifier.fillMaxWidth(),\n            onClick = {\n                if (component.selectionSheetData.isNotEmpty()) {\n                    component.updateType(\n                        type = Screen.RecognizeText.Type.WriteToSearchablePdf(component.selectionSheetData)\n                    )\n                    component.hideSelectionTypeSheet()\n                } else {\n                    writeToSearchablePdfPicker.pickImage()\n                }\n            }\n        )\n    }\n\n    if (isPortrait) {\n        Column {\n            preference1()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference2()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference3()\n            Spacer(modifier = Modifier.height(8.dp))\n            preference4()\n        }\n    } else {\n        Column(\n            horizontalAlignment = Alignment.CenterHorizontally,\n            modifier = Modifier.padding(\n                WindowInsets.displayCutout.only(WindowInsetsSides.Horizontal)\n                    .asPaddingValues()\n            )\n        ) {\n            Row {\n                preference1.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference2.withModifier(modifier = Modifier.weight(1f))\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            Row {\n                preference3.withModifier(modifier = Modifier.weight(1f))\n                Spacer(modifier = Modifier.width(8.dp))\n                preference4.withModifier(modifier = Modifier.weight(1f))\n            }\n        }\n    }\n\n    EnhancedModalBottomSheet(\n        visible = component.selectionSheetData.isNotEmpty(),\n        onDismiss = {\n            if (!it) component.hideSelectionTypeSheet()\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = component::hideSelectionTypeSheet,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(id = R.string.close))\n            }\n        },\n        sheetContent = {\n            LazyVerticalStaggeredGrid(\n                columns = StaggeredGridCells.Adaptive(250.dp),\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = 12.dp,\n                    alignment = Alignment.CenterHorizontally\n                ),\n                verticalItemSpacing = 12.dp,\n                contentPadding = PaddingValues(12.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                item {\n                    preference2()\n                }\n                item {\n                    preference3()\n                }\n                item {\n                    preference4()\n                }\n            }\n        },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.pick_file),\n                icon = Icons.Rounded.FileOpen\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/TessParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Tune\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessParams\nimport kotlin.math.roundToInt\n\n@Composable\nfun TessParamsSelector(\n    value: TessParams,\n    onValueChange: (TessParams) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    ExpandableItem(\n        modifier = modifier,\n        visibleContent = {\n            TitleItem(\n                text = stringResource(R.string.tesseract_options),\n                subtitle = stringResource(R.string.tesseract_options_sub),\n                icon = Icons.Outlined.Tune,\n                iconEndPadding = 16.dp,\n                modifier = Modifier.padding(8.dp)\n            )\n        },\n        expandableContent = {\n            val params by rememberUpdatedState(value)\n\n            Column(\n                verticalArrangement = Arrangement.spacedBy(4.dp),\n                modifier = Modifier.padding(horizontal = 8.dp)\n            ) {\n                val size = params.tessParamList.size\n\n                params.tessParamList.forEachIndexed { index, (key, paramValue) ->\n                    if (paramValue is Int) {\n                        EnhancedSliderItem(\n                            value = paramValue,\n                            onValueChange = { newValue ->\n                                onValueChange(\n                                    params.update(key) {\n                                        newValue.roundToInt()\n                                    }\n                                )\n                            },\n                            title = key,\n                            valueRange = 0f..100f,\n                            steps = 98,\n                            internalStateTransformation = {\n                                it.roundToInt()\n                            },\n                            shape = ShapeDefaults.byIndex(index, size),\n                            containerColor = MaterialTheme.colorScheme.surface\n                        )\n                    } else if (paramValue is Boolean) {\n                        PreferenceRowSwitch(\n                            title = key,\n                            checked = paramValue,\n                            onClick = { checked ->\n                                onValueChange(\n                                    params.update(key) { checked }\n                                )\n                            },\n                            shape = ShapeDefaults.byIndex(index, size),\n                            modifier = Modifier.fillMaxWidth(),\n                            applyHorizontalPadding = false,\n                            containerColor = MaterialTheme.colorScheme.surface\n                        )\n                    }\n                }\n\n                var tempTessParams by rememberSaveable(params.tessCustomParams) {\n                    mutableStateOf(params.tessCustomParams)\n                }\n                Column(\n                    modifier = Modifier\n                        .container(\n                            shape = ShapeDefaults.default,\n                            color = MaterialTheme.colorScheme.surface\n                        )\n                        .padding(8.dp)\n                ) {\n                    RoundedTextField(\n                        modifier = Modifier.fillMaxWidth(),\n                        value = tempTessParams,\n                        singleLine = false,\n                        onValueChange = {\n                            tempTessParams = it\n                        },\n                        label = {\n                            Text(stringResource(R.string.custom_options))\n                        },\n                        onLoseFocusTransformation = {\n                            tempTessParams.trim().also {\n                                onValueChange(\n                                    params.update(newCustomParams = it)\n                                )\n                                tempTessParams = it\n                            }\n                        },\n                        endIcon = {\n                            AnimatedVisibility(tempTessParams.isNotEmpty()) {\n                                EnhancedIconButton(\n                                    onClick = {\n                                        onValueChange(\n                                            params.update(newCustomParams = tempTessParams)\n                                        )\n                                    }\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Done,\n                                        contentDescription = \"Done\"\n                                    )\n                                }\n                            }\n                        },\n                        shape = ShapeDefaults.small\n                    )\n                    Spacer(Modifier.height(8.dp))\n                    InfoContainer(\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerLow,\n                        text = stringResource(R.string.custom_params_info)\n                    )\n                }\n            }\n        },\n        shape = ShapeDefaults.extraLarge\n    )\n}"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/components/UiDownloadData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.components\n\nimport android.os.Parcelable\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.DownloadData\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\nimport kotlinx.parcelize.Parcelize\n\n@Parcelize\ndata class UiDownloadData(\n    val type: RecognitionType,\n    val languageCode: String,\n    val name: String,\n    val localizedName: String\n) : Parcelable\n\nfun DownloadData.toUi() = UiDownloadData(type, languageCode, name, localizedName)"
  },
  {
    "path": "feature/recognize-text/src/main/java/com/t8rin/imagetoolbox/feature/recognize/text/presentation/screenLogic/RecognizeTextComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Language\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.model.OutlineType\nimport com.t8rin.cropper.model.RectCropShape\nimport com.t8rin.cropper.settings.CropDefaults\nimport com.t8rin.cropper.settings.CropOutlineProperty\nimport com.t8rin.imagetoolbox.core.data.utils.asDomain\nimport com.t8rin.imagetoolbox.core.data.utils.toCoil\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.remote.DownloadProgress\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FileSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiContrastFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiSharpenFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiThresholdFilter\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.PdfManager\nimport com.t8rin.imagetoolbox.feature.pdf_tools.domain.model.SearchablePdfPage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.DownloadData\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.ImageTextReader\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OCRLanguage\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.OcrEngineMode\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionData\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.RecognitionType\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.SegmentationMode\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TessParams\nimport com.t8rin.imagetoolbox.feature.recognize.text.domain.TextRecognitionResult\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.components.UiDownloadData\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.components.toUi\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport coil3.transform.Transformation as CoilTransformation\n\nclass RecognizeTextComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialType: Screen.RecognizeText.Type?,\n    @Assisted onGoBack: () -> Unit,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageTextReader: ImageTextReader,\n    private val settingsManager: SettingsManager,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val shareProvider: ShareProvider,\n    private val fileController: FileController,\n    private val pdfManager: PdfManager,\n    private val filenameCreator: FilenameCreator,\n    resourceManager: ResourceManager,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext), ResourceManager by resourceManager {\n\n    init {\n        debounce {\n            initialType?.let(::updateType)\n        }\n    }\n\n    private val _segmentationMode: MutableState<SegmentationMode> =\n        mutableStateOf(SegmentationMode.PSM_AUTO_OSD)\n    val segmentationMode by _segmentationMode\n\n    private val _ocrEngineMode: MutableState<OcrEngineMode> = mutableStateOf(OcrEngineMode.DEFAULT)\n    val ocrEngineMode by _ocrEngineMode\n\n    private val _params: MutableState<TessParams> = mutableStateOf(TessParams.Default)\n    val params by _params\n\n    private val _selectedLanguages = mutableStateOf(listOf(OCRLanguage.Default))\n    val selectedLanguages by _selectedLanguages\n\n    private var isRecognitionTypeSet = false\n    private val _recognitionType = mutableStateOf(RecognitionType.Standard)\n    val recognitionType by _recognitionType\n\n    private val _type = mutableStateOf<Screen.RecognizeText.Type?>(null)\n    val type by _type\n\n    val uris: List<Uri>\n        get() = when (val target = type) {\n            is Screen.RecognizeText.Type.WriteToFile -> target.uris ?: emptyList()\n            is Screen.RecognizeText.Type.WriteToMetadata -> target.uris ?: emptyList()\n            is Screen.RecognizeText.Type.WriteToSearchablePdf -> target.uris ?: emptyList()\n            else -> emptyList()\n        }\n\n    val onGoBack: () -> Unit = {\n        if (type == null) onGoBack()\n        else {\n            _recognitionData.update { null }\n            _type.update { null }\n        }\n    }\n\n    private val _recognitionData = mutableStateOf<RecognitionData?>(null)\n    val recognitionData by _recognitionData\n\n    val text: String? get() = recognitionData?.text?.takeIf { it.isNotEmpty() }\n\n    private val _editedText = mutableStateOf(text)\n    val editedText by _editedText\n\n    private val _textLoadingProgress: MutableState<Int> = mutableIntStateOf(-1)\n    val textLoadingProgress by _textLoadingProgress\n\n    private val _languages: MutableState<List<OCRLanguage>> = mutableStateOf(emptyList())\n    val languages by _languages\n\n    private val contrastFilterInstance = UiContrastFilter()\n\n    private val sharpenFilterInstance = UiSharpenFilter()\n\n    private val thresholdFilterInstance = UiThresholdFilter()\n\n    private val filtersOrder = listOf(\n        contrastFilterInstance,\n        sharpenFilterInstance,\n        thresholdFilterInstance\n    )\n\n    private val _filtersAdded: MutableState<List<Filter<*>>> = mutableStateOf(emptyList())\n    val filtersAdded by _filtersAdded\n\n    private val internalBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _rotation: MutableState<Float> = mutableFloatStateOf(0f)\n\n    private val _isFlipped: MutableState<Boolean> = mutableStateOf(false)\n\n    private val _selectedAspectRatio: MutableState<DomainAspectRatio> =\n        mutableStateOf(DomainAspectRatio.Free)\n    val selectedAspectRatio by _selectedAspectRatio\n\n    private val _cropProperties = mutableStateOf(\n        CropDefaults.properties(\n            cropOutlineProperty = CropOutlineProperty(\n                OutlineType.Rect,\n                RectCropShape(\n                    id = 0,\n                    title = OutlineType.Rect.name\n                )\n            ),\n            fling = true\n        )\n    )\n    val cropProperties by _cropProperties\n\n    private val _isExporting: MutableState<Boolean> = mutableStateOf(false)\n    val isExporting by _isExporting\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private var languagesJob: Job? by smartJob {\n        _isExporting.update { false }\n    }\n\n    val isTextLoading: Boolean\n        get() = textLoadingProgress in 0..100\n\n    private var loadingJob: Job? by smartJob()\n\n    private val _selectionSheetData = mutableStateOf(emptyList<Uri>())\n    val selectionSheetData by _selectionSheetData\n\n    private val _downloadDialogData = mutableStateOf<List<UiDownloadData>>(emptyList())\n    val downloadDialogData by _downloadDialogData\n\n    fun clearDownloadDialogData() {\n        _downloadDialogData.update { emptyList() }\n    }\n\n    fun showSelectionTypeSheet(uris: List<Uri>) {\n        _selectionSheetData.update { uris }\n    }\n\n    fun hideSelectionTypeSheet() {\n        _selectionSheetData.update { emptyList() }\n    }\n\n    private fun loadLanguages(\n        onComplete: suspend () -> Unit = {}\n    ) {\n        loadingJob = componentScope.launch {\n            delay(200L)\n            if (!isRecognitionTypeSet) {\n                _recognitionType.update {\n                    RecognitionType.entries[settingsManager.getSettingsState().initialOcrMode]\n                }\n                isRecognitionTypeSet = true\n            }\n            val data = imageTextReader.getLanguages(recognitionType)\n            _selectedLanguages.update { ocrLanguages ->\n                ocrLanguages.toMutableList().also { oldList ->\n                    data.forEach { ocrLanguage ->\n                        ocrLanguages.indexOfFirst {\n                            it.code == ocrLanguage.code\n                        }.takeIf { it != -1 }?.let { index ->\n                            oldList[index] = ocrLanguage\n                        }\n                    }\n                }.ifEmpty {\n                    listOf(OCRLanguage.Default)\n                }\n            }\n            _languages.update { data }\n            onComplete()\n        }\n    }\n\n    init {\n        loadLanguages()\n        componentScope.launch {\n            val languageCodes = settingsManager\n                .getSettingsState()\n                .initialOcrCodes\n                .filter { it.isNotBlank() }\n                .map(imageTextReader::getLanguageForCode)\n            _selectedLanguages.update {\n                languageCodes.ifEmpty { listOf(OCRLanguage.Default) }\n            }\n        }\n    }\n\n    fun getTransformations(): List<CoilTransformation> = filtersOrder.filter {\n        it in filtersAdded\n    }.map {\n        filterProvider.filterToTransformation(it).toCoil()\n    }\n\n    fun updateType(\n        type: Screen.RecognizeText.Type?\n    ) {\n        type?.let {\n            componentScope.launch {\n                _isImageLoading.value = true\n                _type.update { type }\n                if (type is Screen.RecognizeText.Type.Extraction) {\n                    imageGetter.getImage(\n                        data = type.uri ?: \"\",\n                        originalSize = false\n                    )?.let {\n                        updateBitmap(\n                            bitmap = it,\n                            onComplete = ::startRecognition\n                        )\n                    }\n                }\n                _isImageLoading.value = false\n            }\n        }\n    }\n\n    fun save(\n        oneTimeSaveLocationUri: String?\n    ) {\n        recognitionJob = componentScope.launch {\n            delay(400)\n            _isSaving.update { true }\n            when (type) {\n                is Screen.RecognizeText.Type.WriteToFile -> {\n                    val txtString = StringBuilder()\n\n                    _left.update { uris.size }\n\n                    uris.forEach { uri ->\n                        uri.readText().appendToStringBuilder(\n                            builder = txtString,\n                            uri = uri,\n                            onRequestDownload = { data ->\n                                _downloadDialogData.update { data.map(DownloadData::toUi) }\n                                return@launch\n                            }\n                        )\n                        _done.update { it + 1 }\n                    }\n\n                    parseSaveResults(\n                        listOf(\n                            fileController.save(\n                                saveTarget = TxtSaveTarget(\n                                    txtBytes = txtString.toString().toByteArray()\n                                ),\n                                keepOriginalMetadata = true,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            ).onSuccess(::registerSave)\n                        )\n                    )\n                }\n\n                is Screen.RecognizeText.Type.WriteToMetadata -> {\n                    val results = mutableListOf<SaveResult>()\n\n                    _left.update { uris.size }\n\n                    uris.forEach { uri ->\n                        runSuspendCatching {\n                            imageGetter.getImage(uri.toString())\n                        }.getOrNull()?.let { data ->\n                            val txtString = when (val result = data.image.readText()) {\n                                is TextRecognitionResult.Error -> {\n                                    result.throwable.message ?: \"\"\n                                }\n\n                                is TextRecognitionResult.NoData -> {\n                                    _downloadDialogData.update { result.data.map(DownloadData::toUi) }\n                                    return@launch\n                                }\n\n                                is TextRecognitionResult.Success -> {\n                                    result.data.text.ifEmpty { getString(R.string.picture_has_no_text) }\n                                }\n                            }\n\n                            results.add(\n                                fileController.save(\n                                    ImageSaveTarget(\n                                        imageInfo = data.imageInfo,\n                                        originalUri = uri.toString(),\n                                        sequenceNumber = null,\n                                        metadata = data.metadata?.apply {\n                                            setAttribute(\n                                                MetadataTag.UserComment,\n                                                txtString.takeIf { it.isNotEmpty() }\n                                            )\n                                        },\n                                        data = ByteArray(0),\n                                        readFromUriInsteadOfData = true\n                                    ),\n                                    keepOriginalMetadata = false,\n                                    oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                                )\n                            )\n                            _done.update { it + 1 }\n                        }\n                    }\n\n                    parseSaveResults(results.onSuccess(::registerSave))\n                }\n\n                else -> return@launch\n            }\n        }.apply {\n            invokeOnCompletion {\n                _isSaving.update { false }\n            }\n        }\n    }\n\n    private fun TxtSaveTarget(\n        txtBytes: ByteArray\n    ): SaveTarget = FileSaveTarget(\n        originalUri = \"\",\n        filename = filenameCreator.constructImageFilename(\n            ImageSaveTarget(\n                imageInfo = ImageInfo(),\n                originalUri = \"\",\n                sequenceNumber = null,\n                metadata = null,\n                data = ByteArray(0),\n                extension = \"txt\"\n            ),\n            oneTimePrefix = \"OCR_images(${uris.size})\",\n            forceNotAddSizeInFilename = true\n        ),\n        data = txtBytes,\n        mimeType = MimeType.Txt,\n        extension = \"txt\"\n    )\n\n    fun removeUri(uri: Uri) {\n        when (type) {\n            is Screen.RecognizeText.Type.WriteToFile -> {\n                updateType(\n                    type = Screen.RecognizeText.Type.WriteToFile(uris - uri)\n                )\n            }\n\n            is Screen.RecognizeText.Type.WriteToMetadata -> {\n                updateType(\n                    type = Screen.RecognizeText.Type.WriteToMetadata(uris - uri),\n                )\n            }\n\n            is Screen.RecognizeText.Type.WriteToSearchablePdf -> {\n                updateType(\n                    type = Screen.RecognizeText.Type.WriteToSearchablePdf(uris - uri),\n                )\n            }\n\n            else -> Unit\n        }\n    }\n\n    fun updateBitmap(\n        bitmap: Bitmap,\n        onComplete: () -> Unit = {}\n    ) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            _previewBitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n            internalBitmap.update { previewBitmap }\n            _isImageLoading.value = false\n            onComplete()\n        }\n    }\n\n    private var recognitionJob: Job? by smartJob {\n        _textLoadingProgress.update { -1 }\n        _isSaving.update { false }\n    }\n\n    fun startRecognition() {\n        recognitionJob = componentScope.launch {\n            val type = _type.value\n            if (type !is Screen.RecognizeText.Type.Extraction) return@launch\n            delay(400L)\n            _textLoadingProgress.update { 0 }\n            (previewBitmap ?: type.uri)?.readText()?.also { result ->\n                when (result) {\n                    is TextRecognitionResult.Error -> {\n                        AppToastHost.showFailureToast(result.throwable)\n                    }\n\n                    is TextRecognitionResult.NoData -> {\n                        _downloadDialogData.update { result.data.map(DownloadData::toUi) }\n                    }\n\n                    is TextRecognitionResult.Success -> {\n                        _recognitionData.update { result.data }\n                        _editedText.update { text }\n                    }\n                }\n            }\n            _textLoadingProgress.update { -1 }\n        }\n    }\n\n    fun setRecognitionType(recognitionType: RecognitionType) {\n        _recognitionType.update { recognitionType }\n        componentScope.launch {\n            settingsManager.setInitialOcrMode(recognitionType.ordinal)\n        }\n        loadLanguages()\n        startRecognition()\n    }\n\n    private val downloadMutex = Mutex()\n    fun downloadTrainData(\n        type: RecognitionType,\n        languageCode: String,\n        onProgress: (DownloadProgress) -> Unit,\n        onComplete: () -> Unit\n    ) {\n        componentScope.launch {\n            downloadMutex.withLock {\n                imageTextReader.downloadTrainingData(\n                    type = type,\n                    languageCode = languageCode,\n                    onProgress = onProgress\n                )\n                loadLanguages {\n                    settingsManager.setInitialOCRLanguageCodes(\n                        selectedLanguages.filter {\n                            it.downloaded.isNotEmpty()\n                        }.map { it.code }.ifEmpty {\n                            listOf(OCRLanguage.Default.code)\n                        }\n                    )\n                }\n                onComplete()\n            }\n        }\n    }\n\n    fun onLanguagesSelected(ocrLanguages: List<OCRLanguage>) {\n        componentScope.launch {\n            settingsManager.setInitialOCRLanguageCodes(\n                ocrLanguages.filter {\n                    it.downloaded.isNotEmpty() && it.code.isNotBlank()\n                }.map { it.code }.ifEmpty {\n                    listOf(OCRLanguage.Default.code)\n                }\n            )\n        }\n        _selectedLanguages.update {\n            ocrLanguages.ifEmpty {\n                listOf(OCRLanguage.Default)\n            }\n        }\n        _recognitionData.update { null }\n        _editedText.update { null }\n        recognitionJob?.cancel()\n        _textLoadingProgress.update { -1 }\n    }\n\n    fun setSegmentationMode(segmentationMode: SegmentationMode) {\n        _segmentationMode.update { segmentationMode }\n        startRecognition()\n    }\n\n    fun deleteLanguage(\n        language: OCRLanguage,\n        types: List<RecognitionType>\n    ) {\n        componentScope.launch {\n            imageTextReader.deleteLanguage(language, types)\n            onLanguagesSelected(selectedLanguages - language)\n            val availableTypes = language.downloaded - types.toSet()\n            availableTypes.firstOrNull()?.let(::setRecognitionType) ?: loadLanguages()\n            startRecognition()\n        }\n    }\n\n    fun rotateBitmapLeft() {\n        _rotation.update { it - 90f }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n    }\n\n    fun rotateBitmapRight() {\n        _rotation.update { it + 90f }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n    }\n\n    fun flipImage() {\n        _isFlipped.update { !it }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n    }\n\n    private suspend fun checkBitmapAndUpdate() {\n        _previewBitmap.value = internalBitmap.value?.let {\n            imageTransformer.flip(\n                image = imageTransformer.rotate(\n                    image = it,\n                    degrees = _rotation.value\n                ),\n                isFlipped = _isFlipped.value\n            )\n        }\n    }\n\n    fun setCropAspectRatio(\n        domainAspectRatio: DomainAspectRatio,\n        aspectRatio: AspectRatio\n    ) {\n        _cropProperties.update { properties ->\n            properties.copy(\n                aspectRatio = aspectRatio.takeIf {\n                    domainAspectRatio != DomainAspectRatio.Original\n                } ?: _previewBitmap.value?.let {\n                    AspectRatio(it.safeAspectRatio)\n                } ?: aspectRatio,\n                fixedAspectRatio = domainAspectRatio != DomainAspectRatio.Free\n            )\n        }\n        _selectedAspectRatio.update { domainAspectRatio }\n    }\n\n    fun setCropMask(cropOutlineProperty: CropOutlineProperty) {\n        _cropProperties.update { it.copy(cropOutlineProperty = cropOutlineProperty) }\n    }\n\n    suspend fun loadImage(uri: Uri): Bitmap? = imageGetter.getImage(data = uri)\n\n    fun toggleContrastFilter() {\n        _filtersAdded.update {\n            it.toggle(contrastFilterInstance)\n        }\n    }\n\n    fun toggleThresholdFilter() {\n        _filtersAdded.update {\n            it.toggle(thresholdFilterInstance)\n        }\n    }\n\n    fun toggleSharpnessFilter() {\n        _filtersAdded.update {\n            it.toggle(sharpenFilterInstance)\n        }\n    }\n\n    fun setOcrEngineMode(mode: OcrEngineMode) {\n        _ocrEngineMode.update { mode }\n        startRecognition()\n    }\n\n    fun shareEditedText() {\n        editedText?.let {\n            shareProvider.shareText(\n                value = it,\n                onComplete = AppToastHost::showConfetti\n            )\n        }\n    }\n\n    fun updateEditedText(text: String) {\n        _editedText.update { text }\n    }\n\n    fun shareData() {\n        recognitionJob = componentScope.launch {\n            delay(400)\n            _isSaving.update { true }\n            when (type) {\n                is Screen.RecognizeText.Type.WriteToFile -> {\n                    val txtString = StringBuilder()\n\n                    _left.update { uris.size }\n\n                    uris.forEach { uri ->\n                        uri.readText().also { result ->\n                            result.appendToStringBuilder(\n                                builder = txtString,\n                                uri = uri,\n                                onRequestDownload = { data ->\n                                    _downloadDialogData.update { data.map(DownloadData::toUi) }\n                                    return@launch\n                                }\n                            )\n                            _done.update { it + 1 }\n                        }\n                    }\n\n                    val saveTarget = TxtSaveTarget(\n                        txtBytes = txtString.toString().toByteArray()\n                    )\n\n                    shareProvider.shareByteArray(\n                        byteArray = saveTarget.data,\n                        filename = saveTarget.filename ?: \"\",\n                        onComplete = AppToastHost::showConfetti\n                    )\n                }\n\n                is Screen.RecognizeText.Type.WriteToMetadata -> {\n                    val cachedUris = mutableListOf<String>()\n\n                    _left.update { uris.size }\n\n                    uris.forEach { uri ->\n                        runSuspendCatching {\n                            imageGetter.getImage(uri.toString())\n                        }.getOrNull()?.let { data ->\n                            data.image.readText().also { result ->\n                                val txtString = when (result) {\n                                    is TextRecognitionResult.Error -> {\n                                        result.throwable.message ?: \"\"\n                                    }\n\n                                    is TextRecognitionResult.NoData -> {\n                                        _downloadDialogData.update { result.data.map(DownloadData::toUi) }\n                                        return@launch\n                                    }\n\n                                    is TextRecognitionResult.Success -> {\n                                        result.data.text.ifEmpty { getString(R.string.picture_has_no_text) }\n                                    }\n                                }\n\n                                val exif = data.metadata?.apply {\n                                    setAttribute(\n                                        MetadataTag.UserComment,\n                                        txtString.takeIf { it.isNotEmpty() }\n                                    )\n                                }\n\n                                shareProvider.cacheData(\n                                    writeData = { w ->\n                                        w.writeBytes(\n                                            fileController.readBytes(uri.toString())\n                                        )\n                                    },\n                                    filename = filenameCreator.constructImageFilename(\n                                        saveTarget = ImageSaveTarget(\n                                            imageInfo = data.imageInfo.copy(originalUri = uri.toString()),\n                                            originalUri = uri.toString(),\n                                            metadata = exif,\n                                            sequenceNumber = null,\n                                            data = ByteArray(0)\n                                        )\n                                    )\n                                )?.let { uri ->\n                                    fileController.writeMetadata(\n                                        imageUri = uri,\n                                        metadata = exif\n                                    )\n\n                                    cachedUris.add(uri)\n                                }\n\n                                _done.update { it + 1 }\n                            }\n                        }\n                    }\n\n                    shareProvider.shareUris(cachedUris)\n                }\n\n                is Screen.RecognizeText.Type.WriteToSearchablePdf -> {\n                    val pdfUri = createSearchablePdfUri(\n                        onRequestDownload = { data ->\n                            _downloadDialogData.update { data.map(DownloadData::toUi) }\n                        }\n                    ) ?: return@launch\n\n                    shareProvider.shareUri(\n                        uri = pdfUri,\n                        type = MimeType.Pdf,\n                        onComplete = AppToastHost::showConfetti\n                    )\n                }\n\n                else -> return@launch\n            }\n        }.apply {\n            invokeOnCompletion {\n                _isSaving.update { false }\n            }\n        }\n    }\n\n    private inline fun TextRecognitionResult.appendToStringBuilder(\n        builder: StringBuilder,\n        uri: Uri,\n        onRequestDownload: (List<DownloadData>) -> Unit\n    ) {\n        when (this) {\n            is TextRecognitionResult.Error -> {\n                builder.apply {\n                    append(\"${done + 1} - \")\n                    append(\"[${filenameCreator.getFilename(uri.toString())}]\")\n                    append(\"\\n\\n\")\n                    append(throwable.message)\n                    append(\"\\n\\n\")\n                }\n            }\n\n            is TextRecognitionResult.NoData -> onRequestDownload(data)\n\n            is TextRecognitionResult.Success -> {\n                builder.apply {\n                    append(\"${done + 1} - \")\n                    append(\"[${filenameCreator.getFilename(uri.toString())}]\")\n                    append(\" \")\n                    append(getString(R.string.accuracy, data.accuracy))\n                    append(\"\\n\\n\")\n                    append(data.text.ifEmpty { getString(R.string.picture_has_no_text) })\n                    append(\"\\n\\n\")\n                }\n            }\n        }\n    }\n\n    fun exportLanguagesTo(uri: Uri) {\n        languagesJob = componentScope.launch {\n            _isExporting.value = true\n            imageTextReader.exportLanguagesToZip()?.let { zipUri ->\n                fileController.writeBytes(\n                    uri = uri.toString(),\n                    block = { it.writeBytes(fileController.readBytes(zipUri)) }\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n            _isExporting.value = false\n        }\n    }\n\n    fun generateExportFilename(): String = \"image_toolbox_ocr_languages_${timestamp()}.zip\"\n\n    fun generateTextFilename(): String = \"OCR_${timestamp()}.txt\"\n\n    fun generateSearchablePdfFilename(): String = \"OCR_searchable_${timestamp()}.pdf\"\n\n    fun importLanguagesFrom(\n        uri: Uri,\n        onFailure: (Throwable) -> Unit\n    ) {\n        languagesJob = componentScope.launch {\n            _isExporting.value = true\n            imageTextReader.importLanguagesFromUri(uri.toString())\n                .onSuccess {\n                    loadLanguages {\n                        AppToastHost.showConfetti()\n                        AppToastHost.showToast(\n                            message = getString(R.string.languages_imported),\n                            icon = Icons.Outlined.Language\n                        )\n                        startRecognition()\n                    }\n                }\n                .onFailure(onFailure)\n            _isExporting.value = false\n        }\n    }\n\n    fun saveContentToTxt(uri: Uri) {\n        recognitionData?.text?.takeIf { it.isNotEmpty() }?.let { data ->\n            componentScope.launch {\n                fileController.writeBytes(\n                    uri = uri.toString(),\n                    block = {\n                        it.writeBytes(data.encodeToByteArray())\n                    }\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n        }\n    }\n\n    fun saveSearchablePdfTo(uri: Uri) {\n        recognitionJob = componentScope.launch {\n            _isSaving.update { true }\n            val pdfUri = createSearchablePdfUri(\n                onRequestDownload = { data ->\n                    _downloadDialogData.update { data.map(DownloadData::toUi) }\n                }\n            ) ?: return@launch\n            fileController.transferBytes(\n                fromUri = pdfUri,\n                toUri = uri.toString()\n            ).also(::parseFileSaveResult).onSuccess(::registerSave)\n        }.apply {\n            invokeOnCompletion {\n                _isSaving.update { false }\n            }\n        }\n    }\n\n    fun updateParams(newParams: TessParams) {\n        _params.update { newParams }\n        startRecognition()\n    }\n\n    fun cancelSaving() {\n        recognitionJob?.cancel()\n        recognitionJob = null\n        _isSaving.update { false }\n    }\n\n    private suspend fun createSearchablePdfUri(\n        onRequestDownload: (List<DownloadData>) -> Unit\n    ): String? {\n        val pages = mutableListOf<SearchablePdfPage>()\n        _left.update { uris.size }\n        _done.update { 0 }\n\n        uris.forEachIndexed { index, uri ->\n            val data = when (val result = uri.readText()) {\n                is TextRecognitionResult.Error -> return null\n\n                is TextRecognitionResult.NoData -> {\n                    onRequestDownload(result.data)\n                    return null\n                }\n\n                is TextRecognitionResult.Success -> result.data\n            }\n            pages.add(\n                SearchablePdfPage(\n                    imageUri = uri.toString(),\n                    text = data.text,\n                    hocr = data.hocr\n                )\n            )\n            _done.update { index + 1 }\n        }\n\n        return pdfManager.createSearchablePdf(\n            pages = pages\n        )\n    }\n\n    private suspend fun Any.readText(): TextRecognitionResult {\n        return imageTextReader.getTextFromImage(\n            type = recognitionType,\n            languageCode = selectedLanguages.joinToString(\"+\") { it.code },\n            segmentationMode = segmentationMode,\n            model = imageGetter.getImage(this)?.let { bitmap ->\n                imageTransformer.transform(\n                    transformations = getTransformations().map(CoilTransformation::asDomain),\n                    image = bitmap\n                )\n            },\n            parameters = params,\n            ocrEngineMode = ocrEngineMode,\n            onProgress = { progress ->\n                _textLoadingProgress.update { progress }\n            }\n        ).also {\n            _textLoadingProgress.update { -1 }\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialType: Screen.RecognizeText.Type?,\n            onGoBack: () -> Unit,\n        ): RecognizeTextComponent\n    }\n\n}"
  },
  {
    "path": "feature/resize-convert/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/resize-convert/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.resize_convert\"\n\ndependencies {\n    implementation(projects.feature.compare)\n}"
  },
  {
    "path": "feature/resize-convert/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/resize-convert/src/main/java/com/t8rin/imagetoolbox/feature/resize_convert/presentation/ResizeAndConvertContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.resize_convert.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.History\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.CompareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShowOriginalButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageTransformBar\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group.ResizeTypeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PresetSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ScaleModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.EditExifSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.core.utils.fileSize\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareSheet\nimport com.t8rin.imagetoolbox.feature.resize_convert.presentation.screenLogic.ResizeAndConvertComponent\n\n@Composable\nfun ResizeAndConvertContent(\n    component: ResizeAndConvertComponent\n) {\n    AutoContentBasedColors(component.bitmap)\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setUris(\n            uris = uris\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var showResetDialog by rememberSaveable { mutableStateOf(false) }\n    var showOriginal by rememberSaveable { mutableStateOf(false) }\n\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n\n    var showEditExifDialog by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n    var showCompareSheet by rememberSaveable { mutableStateOf(false) }\n\n    CompareSheet(\n        data = component.bitmap to component.previewBitmap,\n        visible = showCompareSheet,\n        onDismiss = {\n            showCompareSheet = false\n        }\n    )\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.resize_and_convert),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = component.imageInfo.sizeInBytes.toLong(),\n                originalSize = component.selectedUri?.fileSize()\n            )\n        },\n        onGoBack = onBack,\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.bitmap != null,\n                onShare = component::performSharing,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n\n            EnhancedIconButton(\n                enabled = component.bitmap != null,\n                onClick = { showResetDialog = true }\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.ImageReset,\n                    contentDescription = stringResource(R.string.reset_image)\n                )\n            }\n            if (component.bitmap != null) {\n                ShowOriginalButton(\n                    canShow = component.canShow(),\n                    onStateChange = {\n                        showOriginal = it\n                    }\n                )\n            } else {\n                EnhancedIconButton(\n                    enabled = false,\n                    onClick = {}\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.History,\n                        contentDescription = stringResource(R.string.original)\n                    )\n                }\n            }\n        },\n        imagePreview = {\n            ImageContainer(\n                modifier = Modifier\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                imageInside = isPortrait,\n                showOriginal = showOriginal,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.bitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = component.shouldShowPreview\n            )\n        },\n        controls = {\n            val imageInfo = component.imageInfo\n            ImageCounter(\n                imageCount = component.uris?.size?.takeIf { it > 1 },\n                onRepick = {\n                    showPickImageFromUrisSheet = true\n                }\n            )\n            AnimatedContent(\n                targetState = component.uris?.size == 1\n            ) { oneUri ->\n                val preset = component.presetSelected\n                if (oneUri) {\n                    ImageTransformBar(\n                        onEditExif = { showEditExifDialog = true },\n                        onRotateLeft = component::rotateLeft,\n                        onFlip = component::flip,\n                        imageFormat = component.imageInfo.imageFormat,\n                        onRotateRight = component::rotateRight,\n                        canRotate = !(preset is Preset.AspectRatio && preset.ratio != 1f)\n                    )\n                } else {\n                    LaunchedEffect(Unit) {\n                        showEditExifDialog = false\n                        component.updateExif(null)\n                    }\n                    ImageTransformBar(\n                        onRotateLeft = component::rotateLeft,\n                        onFlip = component::flip,\n                        onRotateRight = component::rotateRight,\n                        canRotate = !(preset is Preset.AspectRatio && preset.ratio != 1f)\n                    )\n                }\n            }\n            Spacer(Modifier.size(8.dp))\n            PresetSelector(\n                value = component.presetSelected,\n                includeTelegramOption = true,\n                includeAspectRatioOption = true,\n                onValueChange = component::updatePreset\n            )\n            Spacer(Modifier.size(8.dp))\n            AnimatedVisibility(\n                visible = component.uris?.size != 1,\n                enter = fadeIn() + expandVertically(),\n                exit = fadeOut() + shrinkVertically()\n            ) {\n                Column {\n                    SaveExifWidget(\n                        imageFormat = component.imageInfo.imageFormat,\n                        checked = component.keepExif,\n                        onCheckedChange = component::setKeepExif\n                    )\n                    Spacer(Modifier.size(8.dp))\n                }\n            }\n            ResizeImageField(\n                imageInfo = imageInfo,\n                originalSize = component.originalSize,\n                onHeightChange = component::updateHeight,\n                onWidthChange = component::updateWidth,\n                showWarning = component.showWarning\n            )\n            if (imageInfo.imageFormat.canChangeCompressionValue) {\n                Spacer(Modifier.height(8.dp))\n            }\n            QualitySelector(\n                imageFormat = imageInfo.imageFormat,\n                quality = imageInfo.quality,\n                onQualityChange = component::setQuality\n            )\n            Spacer(Modifier.height(8.dp))\n            ImageFormatSelector(\n                value = imageInfo.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = imageInfo.quality,\n            )\n            Spacer(Modifier.height(8.dp))\n            ResizeTypeSelector(\n                enabled = component.bitmap != null,\n                value = imageInfo.resizeType,\n                onValueChange = component::setResizeType\n            )\n            Spacer(Modifier.height(8.dp))\n            ScaleModeSelector(\n                value = imageInfo.imageScaleMode,\n                onValueChange = component::setImageScaleMode\n            )\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        topAppBarPersistentActions = {\n            if (component.bitmap == null) TopAppBarEmoji()\n            CompareButton(\n                onClick = { showCompareSheet = true },\n                visible = component.previewBitmap != null\n                        && component.bitmap != null\n                        && component.shouldShowPreview\n            )\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.previewBitmap != null && component.shouldShowPreview\n            )\n        },\n        canShowScreenData = component.bitmap != null,\n        forceImagePreviewToMax = showOriginal,\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        }\n    )\n\n    ResetDialog(\n        visible = showResetDialog,\n        onDismiss = { showResetDialog = false },\n        onReset = component::resetValues\n    )\n\n    val transformations by remember(component.imageInfo, component.presetSelected) {\n        derivedStateOf(component::getTransformations)\n    }\n\n    PickImageFromUrisSheet(\n        transformations = transformations,\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = component::updateSelectedUri,\n        onUriRemoved = component::updateUrisSilently,\n        columns = if (isPortrait) 2 else 4,\n    )\n\n    EditExifSheet(\n        visible = showEditExifDialog,\n        onDismiss = {\n            showEditExifDialog = false\n        },\n        exif = component.exif,\n        onClearExif = component::clearExif,\n        onUpdateTag = component::updateExifByTag,\n        onRemoveTag = component::removeExifTag\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris?.size ?: 1,\n        onCancelLoading = component::cancelSaving\n    )\n\n}"
  },
  {
    "path": "feature/resize-convert/src/main/java/com/t8rin/imagetoolbox/feature/resize_convert/presentation/screenLogic/ResizeAndConvertComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.resize_convert.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.clearAllAttributes\nimport com.t8rin.imagetoolbox.core.domain.image.clearAttribute\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageData\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.core.ui.transformation.ImageInfoTransformation\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.withContext\n\nclass ResizeAndConvertComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageInfoTransformationFactory: ImageInfoTransformation.Factory,\n    settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n        }\n    }\n\n    private val _originalSize: MutableState<IntegerSize?> = mutableStateOf(null)\n    val originalSize by _originalSize\n\n    private val _exif: MutableState<Metadata?> = mutableStateOf(null)\n    val exif by _exif\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _keepExif = mutableStateOf(false)\n    val keepExif by _keepExif\n\n    private val _imageInfo: MutableState<ImageInfo> = mutableStateOf(ImageInfo())\n    val imageInfo: ImageInfo by _imageInfo\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _shouldShowPreview: MutableState<Boolean> = mutableStateOf(true)\n    val shouldShowPreview by _shouldShowPreview\n\n    private val _showWarning: MutableState<Boolean> = mutableStateOf(false)\n    val showWarning: Boolean by _showWarning\n\n    private val _presetSelected: MutableState<Preset> = mutableStateOf(Preset.None)\n    val presetSelected by _presetSelected\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _selectedUri: MutableState<Uri?> = mutableStateOf(null)\n    val selectedUri by _selectedUri\n\n    init {\n        componentScope.launch {\n            val settingsState = settingsProvider.getSettingsState()\n            _imageInfo.update {\n                it.copy(resizeType = settingsState.defaultResizeType)\n            }\n        }\n    }\n\n    private var job: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    fun setUris(\n        uris: List<Uri>?\n    ) {\n        _uris.update { null }\n        _uris.update { uris }\n        _selectedUri.update { uris?.firstOrNull() }\n        _presetSelected.update { Preset.None }\n        uris?.firstOrNull()?.let { uri ->\n            componentScope.launch {\n                _imageInfo.update {\n                    it.copy(originalUri = uri.toString())\n                }\n                imageGetter.getImageAsync(\n                    uri = uri.toString(),\n                    originalSize = true,\n                    onGetImage = ::setImageData,\n                    onFailure = AppToastHost::showFailureToast\n                )\n            }\n        }\n    }\n\n    fun updateUrisSilently(removedUri: Uri) {\n        componentScope.launch {\n            _uris.update { uris }\n            if (_selectedUri.value == removedUri) {\n                val index = uris?.indexOf(removedUri) ?: -1\n                if (index == 0) {\n                    uris?.getOrNull(1)?.let {\n                        updateSelectedUri(it)\n                    }\n                } else {\n                    uris?.getOrNull(index - 1)?.let {\n                        updateSelectedUri(it)\n                    }\n                }\n            }\n            _uris.update {\n                it?.toMutableList()?.apply {\n                    remove(removedUri)\n                }\n            }\n        }\n    }\n\n    private suspend fun checkBitmapAndUpdate(\n        resetPreset: Boolean = false\n    ) {\n        if (resetPreset) {\n            _presetSelected.update { Preset.None }\n        }\n        _bitmap.value?.let { bmp ->\n            val preview = updatePreview(bmp)\n            _previewBitmap.update { null }\n            _shouldShowPreview.update { imagePreviewCreator.canShow(preview) }\n            if (shouldShowPreview) _previewBitmap.update { preview }\n        }\n    }\n\n    private suspend fun updatePreview(\n        bitmap: Bitmap\n    ): Bitmap? = withContext(defaultDispatcher) {\n        return@withContext imageInfo.run {\n            _showWarning.update { width * height * 4L >= 10_000 * 10_000 * 3L }\n            imagePreviewCreator.createPreview(\n                image = bitmap,\n                imageInfo = this,\n                onGetByteCount = { sizeInBytes ->\n                    _imageInfo.update { it.copy(sizeInBytes = sizeInBytes) }\n                }\n            )\n        }\n    }\n\n    private fun setBitmapInfo(newInfo: ImageInfo) {\n        if (_imageInfo.value != newInfo) {\n            _imageInfo.update { newInfo }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate()\n            }\n            registerChanges()\n        }\n    }\n\n    fun resetValues(\n        saveFormat: Boolean = false,\n        resetPreset: Boolean = true\n    ) {\n        _imageInfo.update {\n            ImageInfo(\n                width = _originalSize.value?.width ?: 0,\n                height = _originalSize.value?.height ?: 0,\n                imageFormat = if (saveFormat) {\n                    imageInfo.imageFormat\n                } else ImageFormat.Default,\n                originalUri = selectedUri?.toString()\n            )\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate(\n                resetPreset = resetPreset\n            )\n        }\n    }\n\n    private fun setImageData(imageData: ImageData<Bitmap>) {\n        job = componentScope.launch {\n            _isImageLoading.update { true }\n            _exif.update { imageData.metadata }\n            val bitmap = imageData.image\n            val size = bitmap.width to bitmap.height\n            _originalSize.update { size.run { IntegerSize(width = first, height = second) } }\n            _bitmap.update { imageScaler.scaleUntilCanShow(bitmap) }\n            resetValues(true)\n            _imageInfo.update {\n                imageData.imageInfo.copy(\n                    width = size.first,\n                    height = size.second\n                )\n            }\n            checkBitmapAndUpdate(\n                resetPreset = _presetSelected.value == Preset.Telegram && imageData.imageInfo.imageFormat != ImageFormat.Png.Lossless\n            )\n            _isImageLoading.update { false }\n        }\n    }\n\n    fun rotateLeft() {\n        _imageInfo.update {\n            it.copy(\n                rotationDegrees = it.rotationDegrees - 90f,\n                height = it.width,\n                width = it.height\n            )\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    fun rotateRight() {\n        _imageInfo.update {\n            it.copy(\n                rotationDegrees = it.rotationDegrees + 90f,\n                height = it.width,\n                width = it.height\n            )\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    fun flip() {\n        _imageInfo.update {\n            it.copy(isFlipped = !it.isFlipped)\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    fun updateWidth(width: Int) {\n        if (imageInfo.width != width) {\n            _imageInfo.update {\n                it.copy(width = width)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(true)\n            }\n            registerChanges()\n        }\n    }\n\n    fun updateHeight(height: Int) {\n        if (imageInfo.height != height) {\n            _imageInfo.update {\n                it.copy(height = height)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(true)\n            }\n            registerChanges()\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        if (imageInfo.quality != quality) {\n            _imageInfo.update {\n                it.copy(quality = quality)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate()\n            }\n            registerChanges()\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        if (imageInfo.imageFormat != imageFormat) {\n            _imageInfo.update {\n                it.copy(imageFormat = imageFormat)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(\n                    resetPreset = _presetSelected.value == Preset.Telegram && imageFormat != ImageFormat.Png.Lossless\n                )\n            }\n            registerChanges()\n        }\n    }\n\n    fun setResizeType(type: ResizeType) {\n        if (imageInfo.resizeType != type) {\n            _imageInfo.update {\n                it.copy(\n                    resizeType = type.withOriginalSizeIfCrop(originalSize)\n                )\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate()\n            }\n            registerChanges()\n        }\n    }\n\n    fun setKeepExif(boolean: Boolean) {\n        _keepExif.update { boolean }\n        registerChanges()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            val results = mutableListOf<SaveResult>()\n            _done.update { 0 }\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    imageGetter.getImage(uri.toString())?.image\n                }.getOrNull()?.let { bitmap ->\n                    imageInfo.copy(\n                        originalUri = uri.toString()\n                    ).let {\n                        imageTransformer.applyPresetBy(\n                            image = bitmap,\n                            preset = presetSelected,\n                            currentInfo = it\n                        )\n                    }.let { imageInfo ->\n                        results.add(\n                            fileController.save(\n                                saveTarget = ImageSaveTarget(\n                                    imageInfo = imageInfo,\n                                    metadata = if (uris!!.size == 1) exif else null,\n                                    originalUri = uri.toString(),\n                                    sequenceNumber = done + 1,\n                                    data = imageCompressor.compressAndTransform(\n                                        image = bitmap,\n                                        imageInfo = imageInfo\n                                    ),\n                                    presetInfo = presetSelected,\n                                    canSkipIfLarger = true\n                                ),\n                                keepOriginalMetadata = if (uris!!.size == 1) true else keepExif,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                    }\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.update { false }\n        }\n    }\n\n    fun updateSelectedUri(uri: Uri) {\n        runCatching {\n            _selectedUri.update { uri }\n            componentScope.launch {\n                _isImageLoading.update { true }\n                val bitmap = imageGetter.getImage(\n                    uri = uri.toString(),\n                    originalSize = true\n                )?.image\n                val size = bitmap?.let { it.width to it.height }\n                _originalSize.update {\n                    size?.run {\n                        IntegerSize(\n                            width = first,\n                            height = second\n                        )\n                    }\n                }\n                _bitmap.update { imageScaler.scaleUntilCanShow(bitmap) }\n                _imageInfo.update {\n                    it.copy(\n                        width = size?.first ?: 0,\n                        height = size?.second ?: 0,\n                        originalUri = uri.toString()\n                    )\n                }\n                _imageInfo.update {\n                    imageTransformer.applyPresetBy(\n                        image = _bitmap.value,\n                        preset = presetSelected,\n                        currentInfo = it\n                    )\n                }\n                checkBitmapAndUpdate()\n                _isImageLoading.update { false }\n            }\n        }.onFailure(AppToastHost::showFailureToast)\n    }\n\n    fun updatePreset(preset: Preset) {\n        componentScope.launch {\n            if (preset is Preset.AspectRatio && preset.ratio != 1f) {\n                _imageInfo.update { it.copy(rotationDegrees = 0f) }\n            }\n            setBitmapInfo(\n                imageTransformer.applyPresetBy(\n                    image = bitmap,\n                    preset = preset,\n                    currentInfo = imageInfo.copy(\n                        originalUri = selectedUri?.toString()\n                    )\n                )\n            )\n            _presetSelected.update { preset }\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun performSharing() {\n        cacheImages { uris ->\n            componentScope.launch {\n                shareProvider.shareUris(uris.map { it.toString() })\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun canShow(): Boolean = bitmap?.let { imagePreviewCreator.canShow(it) } == true\n\n    fun clearExif() {\n        updateExif(_exif.value?.clearAllAttributes())\n    }\n\n    fun updateExif(metadata: Metadata?) {\n        _exif.update { metadata }\n        registerChanges()\n    }\n\n    fun removeExifTag(tag: MetadataTag) {\n        updateExif(_exif.value?.clearAttribute(tag))\n    }\n\n    fun updateExifByTag(\n        tag: MetadataTag,\n        value: String\n    ) {\n        updateExif(_exif.value?.setAttribute(tag, value))\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.update { false }\n    }\n\n    fun setImageScaleMode(imageScaleMode: ImageScaleMode) {\n        _imageInfo.update {\n            it.copy(\n                imageScaleMode = imageScaleMode\n            )\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            imageGetter.getImage(selectedUri.toString())?.image?.let { bmp ->\n                bmp to imageInfo.copy(\n                    originalUri = selectedUri.toString()\n                ).let {\n                    imageTransformer.applyPresetBy(\n                        image = bitmap,\n                        preset = presetSelected,\n                        currentInfo = it\n                    )\n                }\n            }?.let { (image, imageInfo) ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo.copy(originalUri = selectedUri.toString())\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            _done.update { 0 }\n            val list = mutableListOf<Uri>()\n            uris?.forEach { uri ->\n                imageGetter.getImage(uri.toString())?.image?.let { bmp ->\n                    bmp to imageInfo.copy(\n                        originalUri = uri.toString()\n                    ).let {\n                        imageTransformer.applyPresetBy(\n                            image = bitmap,\n                            preset = presetSelected,\n                            currentInfo = it\n                        )\n                    }\n                }?.let { (image, imageInfo) ->\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = imageInfo.copy(originalUri = uri.toString())\n                    )?.let { uri ->\n                        list.add(uri.toUri())\n                    }\n                }\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            onComplete(list)\n            _isSaving.update { false }\n        }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? =\n        if (uris?.size == 1) imageInfo.imageFormat\n        else null\n\n    fun getTransformations() = listOf(\n        imageInfoTransformationFactory(\n            imageInfo = imageInfo,\n            preset = presetSelected\n        )\n    )\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): ResizeAndConvertComponent\n    }\n}"
  },
  {
    "path": "feature/root/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/root/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.root\"\n\ndependencies {\n    implementation(projects.feature.main)\n    implementation(projects.feature.loadNetImage)\n    implementation(projects.feature.crop)\n    implementation(projects.feature.limitsResize)\n    implementation(projects.feature.cipher)\n    implementation(projects.feature.imagePreview)\n    implementation(projects.feature.weightResize)\n    implementation(projects.feature.compare)\n    implementation(projects.feature.deleteExif)\n    implementation(projects.feature.paletteTools)\n    implementation(projects.feature.resizeConvert)\n    implementation(projects.feature.pdfTools)\n    implementation(projects.feature.singleEdit)\n    implementation(projects.feature.eraseBackground)\n    implementation(projects.feature.draw)\n    implementation(projects.feature.filters)\n    implementation(projects.feature.imageStitch)\n    implementation(projects.feature.pickColor)\n    implementation(projects.feature.recognizeText)\n    implementation(projects.feature.gradientMaker)\n    implementation(projects.feature.watermarking)\n    implementation(projects.feature.gifTools)\n    implementation(projects.feature.apngTools)\n    implementation(projects.feature.zip)\n    implementation(projects.feature.jxlTools)\n    implementation(projects.feature.settings)\n    implementation(projects.feature.easterEgg)\n    implementation(projects.feature.svgMaker)\n    implementation(projects.feature.formatConversion)\n    implementation(projects.feature.documentScanner)\n    implementation(projects.feature.scanQrCode)\n    implementation(projects.feature.imageStacking)\n    implementation(projects.feature.imageSplitting)\n    implementation(projects.feature.colorTools)\n    implementation(projects.feature.webpTools)\n    implementation(projects.feature.noiseGeneration)\n    implementation(projects.feature.collageMaker)\n    implementation(projects.feature.librariesInfo)\n    implementation(projects.feature.markupLayers)\n    implementation(projects.feature.base64Tools)\n    implementation(projects.feature.checksumTools)\n    implementation(projects.feature.meshGradients)\n    implementation(projects.feature.editExif)\n    implementation(projects.feature.imageCutting)\n    implementation(projects.feature.audioCoverExtractor)\n    implementation(projects.feature.libraryDetails)\n    implementation(projects.feature.wallpapersExport)\n    implementation(projects.feature.asciiArt)\n    implementation(projects.feature.aiTools)\n    implementation(projects.feature.colorLibrary)\n}"
  },
  {
    "path": "feature/root/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/RootContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport com.arkivanov.decompose.extensions.compose.subscribeAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ImageToolboxCompositionLocals\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.RootDialogs\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.ScreenSelector\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.utils.uiSettingsState\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\n\n@Composable\nfun RootContent(\n    component: RootComponent\n) {\n    val stack by component.childStack.subscribeAsState()\n\n    ImageToolboxCompositionLocals(\n        settingsState = component.uiSettingsState(),\n        filterPreviewModel = component.filterPreviewModel,\n        canSetDynamicFilterPreview = component.canSetDynamicFilterPreview,\n        currentScreen = stack.items.lastOrNull()?.configuration\n    ) {\n        ScreenSelector(component)\n\n        RootDialogs(component)\n    }\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/RootDialogs.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components\n\nimport androidx.compose.runtime.Composable\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalEditPresetsController\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ReviewHandler\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.UpdateSheet\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.AppExitDialog\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.EditPresetsSheet\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.FirstLaunchSetupDialog\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.GithubReviewDialog\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.PermissionDialog\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.TelegramGroupDialog\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.utils.HandleLookForUpdates\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.utils.SuccessRestoreBackupToastHandler\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.additional.DonateDialog\n\n@Composable\ninternal fun RootDialogs(component: RootComponent) {\n    val editPresetsController = LocalEditPresetsController.current\n\n    AppExitDialog(component)\n\n    EditPresetsSheet(\n        visible = editPresetsController.isVisible,\n        onDismiss = editPresetsController::close,\n        onUpdatePresets = component::setPresets\n    )\n\n    ProcessImagesPreferenceSheet(\n        uris = component.uris ?: emptyList(),\n        extraDataType = component.extraDataType,\n        visible = component.showSelectDialog,\n        onDismiss = component::hideSelectDialog,\n        onNavigate = { screen ->\n            component.navigateTo(screen)\n            Clipboard.clear()\n        }\n    )\n\n    UpdateSheet(\n        tag = component.tag,\n        changelog = component.changelog,\n        visible = component.showUpdateDialog,\n        onDismiss = component::cancelledUpdate\n    )\n\n    FirstLaunchSetupDialog(\n        toggleShowUpdateDialog = component::toggleShowUpdateDialog,\n        toggleAllowBetas = component::toggleAllowBetas,\n        adjustPerformance = component::adjustPerformance\n    )\n\n    DonateDialog(\n        onRegisterDonateDialogOpen = component::registerDonateDialogOpen,\n        onNotShowDonateDialogAgain = component::notShowDonateDialogAgain\n    )\n\n    PermissionDialog()\n\n    GithubReviewDialog(\n        visible = component.showGithubReviewDialog,\n        onDismiss = component::hideReviewDialog,\n        onNotShowAgain = ReviewHandler.current::notShowReviewAgain,\n        isNotShowAgainButtonVisible = ReviewHandler.current.showNotShowAgainButton\n    )\n\n    TelegramGroupDialog(\n        visible = component.showTelegramGroupDialog,\n        onDismiss = component::hideTelegramGroupDialog,\n        onRedirected = component::registerTelegramGroupOpen\n    )\n\n    SuccessRestoreBackupToastHandler(component)\n\n    HandleLookForUpdates(component)\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/ScreenSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components\n\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport com.arkivanov.decompose.extensions.compose.stack.Children\nimport com.arkivanov.decompose.extensions.compose.subscribeAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.toolboxPredictiveBackAnimation\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalCurrentScreen\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.utils.ResetThemeOnGoBack\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.utils.ScreenBasedMaxBrightnessEnforcement\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\n\n@Composable\ninternal fun ScreenSelector(\n    component: RootComponent\n) {\n    ResetThemeOnGoBack(component)\n\n    val childStack by component.childStack.subscribeAsState()\n    val currentScreen = LocalCurrentScreen.current\n\n    SettingsBackdropWrapper(\n        currentScreen = currentScreen,\n        concealBackdropFlow = component.concealBackdropFlow,\n        settingsComponent = component.settingsComponent,\n        children = {\n            Children(\n                stack = childStack,\n                modifier = Modifier.fillMaxSize(),\n                animation = remember(component) {\n                    toolboxPredictiveBackAnimation(\n                        backHandler = component.backHandler,\n                        onBack = component::navigateBack\n                    )\n                },\n                content = { child ->\n                    child.instance.Content()\n                }\n            )\n        }\n    )\n\n    ScreenBasedMaxBrightnessEnforcement(currentScreen)\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/SettingsBackdropWrapper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.material.BackdropScaffold\nimport androidx.compose.material.BackdropValue\nimport androidx.compose.material.Surface\nimport androidx.compose.material.rememberBackdropScaffoldState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.gesture.detectPointerTransformGestures\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.FancyTransitionEasing\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle\nimport com.t8rin.imagetoolbox.feature.settings.presentation.SettingsContent\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.debounce\n\n@Composable\ninternal fun SettingsBackdropWrapper(\n    currentScreen: Screen?,\n    concealBackdropFlow: Flow<Boolean>,\n    settingsComponent: SettingsComponent,\n    children: @Composable () -> Unit\n) {\n    val scaffoldState = rememberBackdropScaffoldState(\n        initialValue = BackdropValue.Concealed,\n        animationSpec = tween(\n            durationMillis = 400,\n            easing = FancyTransitionEasing\n        )\n    )\n    val canExpandSettings = ((currentScreen?.id ?: -1) >= 0)\n        .and(settingsComponent.settingsState.fastSettingsSide != FastSettingsSide.None)\n\n    var predictiveBackProgress by remember {\n        mutableFloatStateOf(0f)\n    }\n    val animatedPredictiveBackProgress by animateFloatAsState(predictiveBackProgress)\n\n    val clean = {\n        predictiveBackProgress = 0f\n    }\n\n    LaunchedEffect(canExpandSettings) {\n        if (!canExpandSettings) {\n            clean()\n            scaffoldState.conceal()\n        }\n    }\n\n    LaunchedEffect(concealBackdropFlow) {\n        concealBackdropFlow\n            .debounce(200)\n            .collectLatest {\n                if (it) {\n                    clean()\n                    scaffoldState.conceal()\n                }\n            }\n    }\n\n    val isTargetRevealed = scaffoldState.targetValue == BackdropValue.Revealed\n\n    BackdropScaffold(\n        scaffoldState = scaffoldState,\n        appBar = {},\n        frontLayerContent = {\n            val alpha by animateFloatAsState(\n                if (isTargetRevealed) 1f else 0f\n            )\n            val color = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha / 2f)\n            var isWantOpenSettings by remember {\n                mutableStateOf(false)\n            }\n\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .drawWithContent {\n                        drawContent()\n                        drawRect(color)\n                    }\n            ) {\n                Box(\n                    modifier = Modifier.pointerInput(isWantOpenSettings) {\n                        detectPointerTransformGestures(\n                            consume = false,\n                            onGestureEnd = {},\n                            onGestureStart = {\n                                isWantOpenSettings = false\n                            },\n                            onGesture = { _, _, _, _, _, _ -> }\n                        )\n                    },\n                    content = {\n                        children()\n\n                        if (isTargetRevealed || scaffoldState.isRevealed) {\n                            Surface(\n                                modifier = Modifier.fillMaxSize(),\n                                color = Color.Transparent\n                            ) {}\n                        }\n                    }\n                )\n\n                SettingsOpenButton(\n                    isWantOpenSettings = isWantOpenSettings,\n                    onStateChange = { isWantOpenSettings = it },\n                    scaffoldState = scaffoldState,\n                    canExpandSettings = canExpandSettings\n                )\n\n                val progress = scaffoldState.progress(\n                    from = BackdropValue.Revealed,\n                    to = BackdropValue.Concealed\n                ) * 20f\n\n                EnhancedModalSheetDragHandle(\n                    color = Color.Transparent,\n                    drawStroke = false,\n                    bendAngle = (-15f * (1f - progress)).coerceAtMost(0f),\n                    modifier = Modifier.alpha(alpha)\n                )\n            }\n        },\n        backLayerContent = {\n            if (canExpandSettings && (scaffoldState.isRevealed || isTargetRevealed)) {\n                PredictiveBackObserver(\n                    onProgress = {\n                        predictiveBackProgress = it * 1.3f\n                    },\n                    onClean = { isCompleted ->\n                        if (isCompleted) scaffoldState.conceal()\n                        clean()\n                    },\n                    enabled = isTargetRevealed\n                )\n                Box(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .height(LocalScreenSize.current.height)\n                        .alpha(1f - animatedPredictiveBackProgress)\n                ) {\n                    SettingsContent(\n                        component = settingsComponent\n                    )\n                }\n            }\n        },\n        peekHeight = 0.dp,\n        headerHeight = 48.dp + WindowInsets.navigationBars.asPaddingValues()\n            .calculateBottomPadding(),\n        persistentAppBar = false,\n        frontLayerElevation = 0.dp,\n        backLayerBackgroundColor = MaterialTheme.colorScheme.surface,\n        frontLayerBackgroundColor = MaterialTheme.colorScheme.surface,\n        frontLayerScrimColor = Color.Transparent,\n        frontLayerShape = RectangleShape,\n        gesturesEnabled = scaffoldState.isRevealed\n    )\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/SettingsOpenButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.VisibilityThreshold\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.safeDrawing\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.BackdropScaffoldState\nimport androidx.compose.material.Icon\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Settings\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.springySpec\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberRipple\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun BoxScope.SettingsOpenButton(\n    isWantOpenSettings: Boolean,\n    onStateChange: (Boolean) -> Unit,\n    scaffoldState: BackdropScaffoldState,\n    canExpandSettings: Boolean\n) {\n    val scope = rememberCoroutineScope()\n    val fastSettingsSide = LocalSettingsState.current.fastSettingsSide\n    val alignment = if (fastSettingsSide == FastSettingsSide.CenterStart) {\n        Alignment.CenterStart\n    } else {\n        Alignment.CenterEnd\n    }\n\n    val direction = LocalLayoutDirection.current\n    val paddingValues = WindowInsets.safeDrawing.asPaddingValues()\n    val (startPadding, endPadding) = remember(paddingValues, direction) {\n        derivedStateOf {\n            paddingValues.calculateStartPadding(direction) to paddingValues.calculateEndPadding(\n                direction\n            )\n        }\n    }.value\n\n    val expandedPart = if (isWantOpenSettings) 12.dp else 42.dp\n    val cornerRadius = expandedPart.coerceAtLeast(4.dp)\n\n    val shape = animateShape(\n        targetValue = key(cornerRadius) {\n            if (fastSettingsSide == FastSettingsSide.CenterStart) {\n                if (startPadding == 0.dp) {\n                    AutoCornersShape(\n                        topEnd = cornerRadius,\n                        bottomEnd = cornerRadius\n                    )\n                } else {\n                    AutoCornersShape(cornerRadius)\n                }\n            } else {\n                if (endPadding == 0.dp) {\n                    AutoCornersShape(\n                        topStart = cornerRadius,\n                        bottomStart = cornerRadius\n                    )\n                } else {\n                    AutoCornersShape(cornerRadius)\n                }\n            }\n        },\n        animationSpec = spring(\n            dampingRatio = 0.5f,\n            stiffness = Spring.StiffnessLow\n        )\n    )\n\n    val height by animateDpAsState(\n        targetValue = if (isWantOpenSettings) 64.dp else 104.dp\n    )\n    val width by animateDpAsState(\n        targetValue = if (isWantOpenSettings) 48.dp else 24.dp,\n        animationSpec = springySpec()\n    )\n    val xOffset by animateDpAsState(\n        targetValue = if (!canExpandSettings) {\n            if (fastSettingsSide == FastSettingsSide.CenterStart) {\n                -width\n            } else {\n                width\n            }\n        } else {\n            0.dp\n        },\n        animationSpec = spring(\n            visibilityThreshold = Dp.VisibilityThreshold,\n            dampingRatio = Spring.DampingRatioMediumBouncy,\n            stiffness = Spring.StiffnessLow\n        )\n    )\n    val alpha by animateFloatAsState(\n        targetValue = if (canExpandSettings) 1f else 0f,\n        animationSpec = tween(650)\n    )\n    val interactionSource = remember { MutableInteractionSource() }\n\n    Surface(\n        color = Color.Transparent,\n        modifier = Modifier\n            .align(alignment)\n            .padding(\n                start = startPadding,\n                end = endPadding\n            )\n            .size(\n                height = height,\n                width = width\n            )\n            .hapticsClickable(\n                enabled = canExpandSettings,\n                indication = null,\n                interactionSource = interactionSource\n            ) {\n                if (isWantOpenSettings) {\n                    scope.launch {\n                        scaffoldState.reveal()\n                        onStateChange(false)\n                    }\n                } else {\n                    onStateChange(true)\n                }\n            }\n            .alpha(alpha)\n            .offset {\n                IntOffset(\n                    x = xOffset.roundToPx(),\n                    y = 0\n                )\n            }\n    ) {\n        Box {\n            val width by animateDpAsState(\n                targetValue = if (isWantOpenSettings) 48.dp else 4.dp,\n                animationSpec = spring(\n                    dampingRatio = 0.35f,\n                    stiffness = Spring.StiffnessLow\n                )\n            )\n\n            val containerColor = takeColorFromScheme {\n                tertiary.blend(primary, 0.65f)\n            }\n\n            val contentColor = takeColorFromScheme {\n                onTertiary.blend(onPrimary, 0.8f)\n            }\n\n            Box(\n                modifier = Modifier\n                    .align(alignment)\n                    .width(width)\n                    .height(64.dp)\n                    .container(\n                        shape = shape,\n                        resultPadding = 0.dp,\n                        color = containerColor\n                    )\n                    .indication(\n                        interactionSource = interactionSource,\n                        indication = rememberRipple(contentColor = contentColor)\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                AnimatedVisibility(\n                    visible = isWantOpenSettings,\n                    enter = fadeIn() + scaleIn(\n                        animationSpec = spring(\n                            dampingRatio = 0.35f,\n                            stiffness = Spring.StiffnessLow\n                        )\n                    ),\n                    exit = fadeOut() + scaleOut()\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.Settings,\n                        contentDescription = null,\n                        tint = contentColor\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/dialogs/AppExitDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs\n\nimport android.os.Build\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.DoorBack\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalCurrentScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\n\n\n@Composable\ninternal fun AppExitDialog(component: RootComponent) {\n    val currentScreen = LocalCurrentScreen.current\n\n    if (currentScreen is Screen.Main) {\n        val context = LocalComponentActivity.current\n\n        var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n        val tiramisu = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU\n        BackHandler(enabled = !tiramisu) {\n            if (component.shouldShowDialog) showExitDialog = true\n            else context.finishAffinity()\n        }\n\n        AppExitDialogImpl(\n            onDismiss = { showExitDialog = false },\n            visible = showExitDialog && !tiramisu\n        )\n    }\n}\n\n@Composable\nprivate fun AppExitDialogImpl(\n    onDismiss: () -> Unit,\n    visible: Boolean\n) {\n    val activity = LocalComponentActivity.current\n\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = activity::finishAffinity\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        confirmButton = {\n            EnhancedButton(onClick = onDismiss) {\n                Text(stringResource(R.string.stay))\n            }\n        },\n        title = { Text(stringResource(R.string.app_closing)) },\n        text = {\n            Text(\n                stringResource(R.string.app_closing_sub),\n                textAlign = TextAlign.Center\n            )\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Outlined.DoorBack,\n                contentDescription = null\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/dialogs/EditPresetsSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectSmall\nimport androidx.compose.material.icons.rounded.AddCircle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.core.text.isDigitsOnly\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.LabelPercent\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun EditPresetsSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onUpdatePresets: (List<Int>) -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.presets),\n                icon = Icons.Rounded.LabelPercent\n            )\n        },\n        sheetContent = {\n            val data = settingsState.presets\n            Box {\n                AnimatedContent(\n                    targetState = data,\n                    transitionSpec = { fadeIn() togetherWith fadeOut() },\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .enhancedVerticalScroll(rememberScrollState())\n                ) { list ->\n                    var expanded by remember { mutableStateOf(false) }\n\n                    FlowRow(\n                        modifier = Modifier\n                            .align(Alignment.Center)\n                            .fillMaxWidth()\n                            .padding(16.dp),\n                        horizontalArrangement = Arrangement.spacedBy(\n                            8.dp,\n                            Alignment.CenterHorizontally\n                        ),\n                        verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically)\n                    ) {\n                        list.forEach {\n                            EnhancedChip(\n                                onClick = {\n                                    onUpdatePresets(list - it)\n                                },\n                                selected = false,\n                                selectedColor = MaterialTheme.colorScheme.primary,\n                                shape = MaterialTheme.shapes.medium\n                            ) {\n                                AutoSizeText(it.toString())\n                            }\n                        }\n                        EnhancedChip(\n                            onClick = {\n                                expanded = true\n                            },\n                            selected = false,\n                            selectedColor = MaterialTheme.colorScheme.primary,\n                            shape = MaterialTheme.shapes.medium,\n                            label = {\n                                Icon(\n                                    imageVector = Icons.Rounded.AddCircle,\n                                    contentDescription = stringResource(R.string.add)\n                                )\n                            }\n                        )\n                    }\n\n                    var value by remember(expanded) { mutableStateOf(\"\") }\n                    EnhancedAlertDialog(\n                        visible = expanded,\n                        onDismissRequest = { expanded = false },\n                        icon = {\n                            Icon(\n                                imageVector = Icons.Outlined.PhotoSizeSelectSmall,\n                                contentDescription = null\n                            )\n                        },\n                        title = {\n                            Text(stringResource(R.string.presets))\n                        },\n                        text = {\n                            OutlinedTextField(\n                                modifier = Modifier.fillMaxWidth(),\n                                shape = ShapeDefaults.default,\n                                value = value,\n                                textStyle = MaterialTheme.typography.titleMedium.copy(\n                                    textAlign = TextAlign.Center\n                                ),\n                                maxLines = 1,\n                                keyboardOptions = KeyboardOptions(\n                                    keyboardType = KeyboardType.Number\n                                ),\n                                onValueChange = {\n                                    if (it.isDigitsOnly()) {\n                                        value = it.toIntOrNull()?.coerceAtMost(500)?.toString()\n                                            ?: \"\"\n                                    }\n                                },\n                                placeholder = {\n                                    Text(\n                                        modifier = Modifier.fillMaxWidth(),\n                                        text = stringResource(R.string.enter_percent),\n                                        style = MaterialTheme.typography.titleMedium.copy(\n                                            textAlign = TextAlign.Center\n                                        ),\n                                        color = LocalContentColor.current.copy(0.5f)\n                                    )\n                                }\n                            )\n                        },\n                        confirmButton = {\n                            EnhancedButton(\n                                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                                onClick = {\n                                    onUpdatePresets(\n                                        list + (value.toIntOrNull() ?: 0)\n                                    )\n                                    expanded = false\n                                },\n                                enabled = value.isNotEmpty()\n                            ) {\n                                Text(stringResource(R.string.add))\n                            }\n                        }\n                    )\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = onDismiss,\n                borderColor = MaterialTheme.colorScheme.outlineVariant(),\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/dialogs/FirstLaunchSetupDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.NewReleases\nimport androidx.compose.material.icons.rounded.SystemSecurityUpdate\nimport androidx.compose.material.icons.rounded.Webhook\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.PerformanceClass\nimport com.t8rin.imagetoolbox.core.domain.utils.Flavor\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Beta\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.isFirstLaunch\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isInstalledFromPlayStore\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.performanceClass\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.OneTimeEffect\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\ninternal fun FirstLaunchSetupDialog(\n    toggleAllowBetas: () -> Unit,\n    toggleShowUpdateDialog: () -> Unit,\n    adjustPerformance: (PerformanceClass) -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    var updateOnFirstOpen by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    OneTimeEffect {\n        updateOnFirstOpen = settingsState.isFirstLaunch(false)\n\n        if (updateOnFirstOpen) {\n            adjustPerformance(appContext.performanceClass)\n        }\n    }\n\n    EnhancedAlertDialog(\n        visible = updateOnFirstOpen,\n        onDismissRequest = {},\n        icon = {\n            Icon(\n                imageVector = Icons.Rounded.SystemSecurityUpdate,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(stringResource(R.string.updates))\n        },\n        text = {\n            val state = rememberScrollState()\n            ProvideTextStyle(value = LocalTextStyle.current.copy(textAlign = TextAlign.Left)) {\n                Column(\n                    modifier = Modifier\n                        .fadingEdges(\n                            isVertical = true,\n                            scrollableState = state,\n                            scrollFactor = 1.1f\n                        )\n                        .enhancedVerticalScroll(state)\n                        .padding(2.dp)\n                ) {\n                    if (Flavor.isFoss()) {\n                        PreferenceItem(\n                            title = stringResource(id = R.string.attention),\n                            subtitle = stringResource(R.string.foss_update_checker_warning),\n                            startIcon = Icons.Rounded.Webhook,\n                            shape = ShapeDefaults.default,\n                            modifier = Modifier.padding(bottom = 8.dp),\n                            containerColor = MaterialTheme.colorScheme.surfaceContainerHighest\n                        )\n                    }\n                    PreferenceRowSwitch(\n                        shape = if (!appContext.isInstalledFromPlayStore()) {\n                            ShapeDefaults.top\n                        } else ShapeDefaults.default,\n                        modifier = Modifier,\n                        title = stringResource(R.string.check_updates),\n                        subtitle = stringResource(R.string.check_updates_sub),\n                        checked = settingsState.showUpdateDialogOnStartup,\n                        onClick = {\n                            toggleShowUpdateDialog()\n                        },\n                        startIcon = Icons.Rounded.NewReleases\n                    )\n                    if (!appContext.isInstalledFromPlayStore()) {\n                        Spacer(Modifier.height(4.dp))\n                        PreferenceRowSwitch(\n                            modifier = Modifier,\n                            shape = ShapeDefaults.bottom,\n                            title = stringResource(R.string.allow_betas),\n                            subtitle = stringResource(R.string.allow_betas_sub),\n                            checked = settingsState.allowBetas,\n                            onClick = {\n                                toggleAllowBetas()\n                            },\n                            startIcon = Icons.Rounded.Beta\n                        )\n                    }\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = { updateOnFirstOpen = false }\n            ) {\n                Text(stringResource(id = R.string.ok))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/dialogs/GithubReviewDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.StarRate\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.domain.APP_GITHUB_LINK\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\n\n@Composable\ninternal fun GithubReviewDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    isNotShowAgainButtonVisible: Boolean,\n    onNotShowAgain: () -> Unit\n) {\n    val linkHandler = LocalUriHandler.current\n    EnhancedAlertDialog(\n        visible = visible,\n        onDismissRequest = onDismiss,\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    linkHandler.openUri(APP_GITHUB_LINK)\n                }\n            ) {\n                Text(text = stringResource(id = R.string.rate))\n            }\n        },\n        dismissButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    if (isNotShowAgainButtonVisible) onNotShowAgain()\n\n                    onDismiss()\n                }\n            ) {\n                Text(stringResource(id = R.string.close))\n            }\n        },\n        title = {\n            Text(stringResource(R.string.rate_app))\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Rounded.StarRate,\n                contentDescription = null\n            )\n        },\n        text = {\n            Text(stringResource(R.string.rate_app_sub))\n        }\n    )\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/dialogs/PermissionDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs\n\nimport android.Manifest\nimport android.os.Build\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Storage\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport androidx.core.app.ActivityCompat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.needToShowStoragePermissionRequest\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.requestStoragePermission\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.hasPermissionAllowed\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberCurrentLifecycleEvent\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport kotlinx.coroutines.delay\n\n@Composable\ninternal fun PermissionDialog() {\n    val context = LocalComponentActivity.current\n    val settingsState = LocalSettingsState.current\n\n    var showDialog by remember { mutableStateOf(false) }\n\n    val currentLifecycleEvent = rememberCurrentLifecycleEvent()\n    LaunchedEffect(\n        showDialog,\n        context,\n        settingsState,\n        currentLifecycleEvent\n    ) {\n        showDialog = context.needToShowStoragePermissionRequest() == true\n        while (showDialog) {\n            showDialog = context.needToShowStoragePermissionRequest() == true\n            delay(100)\n        }\n    }\n\n    var requestedOnce by rememberSaveable {\n        mutableStateOf(false)\n    }\n    LaunchedEffect(Unit) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !requestedOnce) {\n            val notAllowed = listOf(\n                Manifest.permission.ACCESS_MEDIA_LOCATION,\n                Manifest.permission.POST_NOTIFICATIONS\n            ).filter { !context.hasPermissionAllowed(it) }\n\n            if (notAllowed.isNotEmpty()) {\n                ActivityCompat.requestPermissions(\n                    context,\n                    buildList {\n                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n                            add(Manifest.permission.READ_MEDIA_IMAGES)\n                        }\n                        addAll(notAllowed)\n                    }.toTypedArray(),\n                    0\n                )\n            }\n            requestedOnce = true\n        }\n    }\n\n    EnhancedAlertDialog(\n        visible = showDialog,\n        onDismissRequest = { },\n        icon = {\n            Icon(\n                imageVector = Icons.Rounded.Storage,\n                contentDescription = null\n            )\n        },\n        title = { Text(stringResource(R.string.permission)) },\n        text = {\n            Text(stringResource(R.string.permission_sub))\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    context.requestStoragePermission()\n                }\n            ) {\n                Text(stringResource(id = R.string.grant))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/dialogs/TelegramGroupDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Cancel\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.domain.TELEGRAM_CHANNEL_LINK\nimport com.t8rin.imagetoolbox.core.domain.TELEGRAM_GROUP_LINK\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Telegram\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\n\n@Composable\nfun TelegramGroupDialog(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onRedirected: () -> Unit\n) {\n    val linkHandler = LocalUriHandler.current\n    EnhancedAlertDialog(\n        visible = visible,\n        icon = {\n            Icon(\n                imageVector = Icons.Rounded.Telegram,\n                contentDescription = \"Telegram\"\n            )\n        },\n        title = {\n            Text(stringResource(R.string.image_toolbox_in_telegram))\n        },\n        text = {\n            Text(stringResource(R.string.image_toolbox_in_telegram_sub))\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    onRedirected()\n                    linkHandler.openUri(TELEGRAM_GROUP_LINK)\n                }\n            ) {\n                Text(stringResource(R.string.group))\n            }\n        },\n        dismissButton = {\n            EnhancedIconButton(\n                onClick = {\n                    onRedirected()\n                },\n                containerColor = MaterialTheme.colorScheme.errorContainer,\n                contentColor = MaterialTheme.colorScheme.onErrorContainer\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.Cancel,\n                    contentDescription = null\n                )\n            }\n            EnhancedButton(\n                onClick = {\n                    onRedirected()\n                    linkHandler.openUri(TELEGRAM_CHANNEL_LINK)\n                },\n                containerColor = MaterialTheme.colorScheme.tertiaryContainer\n            ) {\n                Text(stringResource(R.string.ci_channel))\n            }\n        },\n        onDismissRequest = onDismiss\n    )\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/navigation/ChildProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.navigation\n\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.collage_maker.presentation.screenLogic.CollageMakerComponent\nimport com.t8rin.imagetoolbox.color_library.presentation.screenLogic.ColorLibraryComponent\nimport com.t8rin.imagetoolbox.color_tools.presentation.screenLogic.ColorToolsComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic.AiToolsComponent\nimport com.t8rin.imagetoolbox.feature.apng_tools.presentation.screenLogic.ApngToolsComponent\nimport com.t8rin.imagetoolbox.feature.ascii_art.presentation.screenLogic.AsciiArtComponent\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.screenLogic.AudioCoverExtractorComponent\nimport com.t8rin.imagetoolbox.feature.base64_tools.presentation.screenLogic.Base64ToolsComponent\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent\nimport com.t8rin.imagetoolbox.feature.cipher.presentation.screenLogic.CipherComponent\nimport com.t8rin.imagetoolbox.feature.compare.presentation.screenLogic.CompareComponent\nimport com.t8rin.imagetoolbox.feature.crop.presentation.screenLogic.CropComponent\nimport com.t8rin.imagetoolbox.feature.delete_exif.presentation.screenLogic.DeleteExifComponent\nimport com.t8rin.imagetoolbox.feature.document_scanner.presentation.screenLogic.DocumentScannerComponent\nimport com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent\nimport com.t8rin.imagetoolbox.feature.easter_egg.presentation.screenLogic.EasterEggComponent\nimport com.t8rin.imagetoolbox.feature.edit_exif.presentation.screenLogic.EditExifComponent\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.screenLogic.EraseBackgroundComponent\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\nimport com.t8rin.imagetoolbox.feature.format_conversion.presentation.screenLogic.FormatConversionComponent\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\nimport com.t8rin.imagetoolbox.feature.image_preview.presentation.screenLogic.ImagePreviewComponent\nimport com.t8rin.imagetoolbox.feature.image_stacking.presentation.screenLogic.ImageStackingComponent\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.screenLogic.ImageStitchingComponent\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent\nimport com.t8rin.imagetoolbox.feature.libraries_info.presentation.screenLogic.LibrariesInfoComponent\nimport com.t8rin.imagetoolbox.feature.limits_resize.presentation.screenLogic.LimitsResizeComponent\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\nimport com.t8rin.imagetoolbox.feature.main.presentation.screenLogic.MainComponent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\nimport com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.screenLogic.MeshGradientsComponent\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.screenLogic.PaletteToolsComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.screenLogic.CompressPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.screenLogic.CropPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.screenLogic.ExtractImagesPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.screenLogic.ExtractPagesPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.screenLogic.FlattenPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.screenLogic.GrayscalePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.screenLogic.ImagesToPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.screenLogic.MergePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.screenLogic.MetadataPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.screenLogic.OCRPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.screenLogic.PageNumbersPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.screenLogic.PreviewPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.screenLogic.PrintPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.screenLogic.ProtectPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.screenLogic.RearrangePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.screenLogic.RemoveAnnotationsPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.screenLogic.RemovePagesPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.screenLogic.RepairPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.screenLogic.RootPdfToolsComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.screenLogic.RotatePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.screenLogic.SignaturePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.screenLogic.SplitPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.screenLogic.UnlockPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.screenLogic.WatermarkPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.screenLogic.ZipConvertPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.screenLogic.PickColorFromImageComponent\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent\nimport com.t8rin.imagetoolbox.feature.resize_convert.presentation.screenLogic.ResizeAndConvertComponent\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.AiTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ApngTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.AsciiArt\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.AudioCoverExtractor\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Base64Tools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ChecksumTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Cipher\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.CollageMaker\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ColorLibrary\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ColorTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Compare\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.CompressPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Crop\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.CropPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.DeleteExif\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.DocumentScanner\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Draw\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.EasterEgg\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.EditExif\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.EraseBackground\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ExtractImagesPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ExtractPagesPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Filter\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.FlattenPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.FormatConversion\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.GifTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.GradientMaker\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.GrayscalePdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageCutter\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImagePreview\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageSplitting\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageStacking\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageStitching\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImagesToPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.JxlTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LibrariesInfo\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LibraryDetails\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LimitResize\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LoadNetImage\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Main\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MarkupLayers\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MergePdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MeshGradients\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MetadataPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.NoiseGeneration\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.OCRPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PageNumbersPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PaletteTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PickColorFromImage\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PreviewPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PrintPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ProtectPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RearrangePdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RecognizeText\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RemoveAnnotationsPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RemovePagesPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RepairPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ResizeAndConvert\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RootPdfTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RotatePdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ScanQrCode\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Settings\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SignaturePdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SingleEdit\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SplitPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SvgMaker\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.UnlockPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WallpapersExport\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WatermarkPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Watermarking\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WebpTools\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WeightResize\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Zip\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ZipConvertPdfTool\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.screenLogic.ScanQrCodeComponent\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.screenLogic.SingleEditComponent\nimport com.t8rin.imagetoolbox.feature.svg_maker.presentation.screenLogic.SvgMakerComponent\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.screenLogic.WatermarkingComponent\nimport com.t8rin.imagetoolbox.feature.webp_tools.presentation.screenLogic.WebpToolsComponent\nimport com.t8rin.imagetoolbox.feature.weight_resize.presentation.screenLogic.WeightResizeComponent\nimport com.t8rin.imagetoolbox.feature.zip.presentation.screenLogic.ZipComponent\nimport com.t8rin.imagetoolbox.image_cutting.presentation.screenLogic.ImageCutterComponent\nimport com.t8rin.imagetoolbox.image_splitting.presentation.screenLogic.ImageSplitterComponent\nimport com.t8rin.imagetoolbox.library_details.presentation.screenLogic.LibraryDetailsComponent\nimport com.t8rin.imagetoolbox.noise_generation.presentation.screenLogic.NoiseGenerationComponent\nimport javax.inject.Inject\n\ninternal class ChildProvider @Inject constructor(\n    private val apngToolsComponentFactory: ApngToolsComponent.Factory,\n    private val cipherComponentFactory: CipherComponent.Factory,\n    private val collageMakerComponentFactory: CollageMakerComponent.Factory,\n    private val compareComponentFactory: CompareComponent.Factory,\n    private val cropComponentFactory: CropComponent.Factory,\n    private val deleteExifComponentFactory: DeleteExifComponent.Factory,\n    private val documentScannerComponentFactory: DocumentScannerComponent.Factory,\n    private val drawComponentFactory: DrawComponent.Factory,\n    private val eraseBackgroundComponentFactory: EraseBackgroundComponent.Factory,\n    private val filtersComponentFactory: FiltersComponent.Factory,\n    private val formatConversionComponentFactory: FormatConversionComponent.Factory,\n    private val paletteToolsComponentFactory: PaletteToolsComponent.Factory,\n    private val gifToolsComponentFactory: GifToolsComponent.Factory,\n    private val gradientMakerComponentFactory: GradientMakerComponent.Factory,\n    private val imagePreviewComponentFactory: ImagePreviewComponent.Factory,\n    private val imageSplittingComponentFactory: ImageSplitterComponent.Factory,\n    private val imageStackingComponentFactory: ImageStackingComponent.Factory,\n    private val imageStitchingComponentFactory: ImageStitchingComponent.Factory,\n    private val jxlToolsComponentFactory: JxlToolsComponent.Factory,\n    private val limitResizeComponentFactory: LimitsResizeComponent.Factory,\n    private val loadNetImageComponentFactory: LoadNetImageComponent.Factory,\n    private val noiseGenerationComponentFactory: NoiseGenerationComponent.Factory,\n    private val rootPdfToolsComponentFactory: RootPdfToolsComponent.Factory,\n    private val pickColorFromImageComponentFactory: PickColorFromImageComponent.Factory,\n    private val recognizeTextComponentFactory: RecognizeTextComponent.Factory,\n    private val resizeAndConvertComponentFactory: ResizeAndConvertComponent.Factory,\n    private val scanQrCodeComponentFactory: ScanQrCodeComponent.Factory,\n    private val settingsComponentFactory: SettingsComponent.Factory,\n    private val singleEditComponentFactory: SingleEditComponent.Factory,\n    private val svgMakerComponentFactory: SvgMakerComponent.Factory,\n    private val watermarkingComponentFactory: WatermarkingComponent.Factory,\n    private val webpToolsComponentFactory: WebpToolsComponent.Factory,\n    private val weightResizeComponentFactory: WeightResizeComponent.Factory,\n    private val zipComponentFactory: ZipComponent.Factory,\n    private val easterEggComponentFactory: EasterEggComponent.Factory,\n    private val colorToolsComponentFactory: ColorToolsComponent.Factory,\n    private val librariesInfoComponentFactory: LibrariesInfoComponent.Factory,\n    private val mainComponentFactory: MainComponent.Factory,\n    private val markupLayersComponentFactory: MarkupLayersComponent.Factory,\n    private val base64ToolsComponentFactory: Base64ToolsComponent.Factory,\n    private val checksumToolsComponentFactory: ChecksumToolsComponent.Factory,\n    private val meshGradientsComponentFactory: MeshGradientsComponent.Factory,\n    private val editExifComponentFactory: EditExifComponent.Factory,\n    private val imageCutterComponentFactory: ImageCutterComponent.Factory,\n    private val audioCoverExtractorComponentFactory: AudioCoverExtractorComponent.Factory,\n    private val libraryDetailsComponentFactory: LibraryDetailsComponent.Factory,\n    private val wallpapersExportComponentFactory: WallpapersExportComponent.Factory,\n    private val asciiArtComponentFactory: AsciiArtComponent.Factory,\n    private val aiToolsComponentFactory: AiToolsComponent.Factory,\n    private val colorLibraryComponentFactory: ColorLibraryComponent.Factory,\n    private val mergePdfToolComponentFactory: MergePdfToolComponent.Factory,\n    private val splitPdfToolComponentFactory: SplitPdfToolComponent.Factory,\n    private val rotatePdfToolComponentFactory: RotatePdfToolComponent.Factory,\n    private val rearrangePdfToolComponentFactory: RearrangePdfToolComponent.Factory,\n    private val pageNumbersPdfToolComponentFactory: PageNumbersPdfToolComponent.Factory,\n    private val ocrPdfToolComponentFactory: OCRPdfToolComponent.Factory,\n    private val watermarkPdfToolComponentFactory: WatermarkPdfToolComponent.Factory,\n    private val signaturePdfToolComponentFactory: SignaturePdfToolComponent.Factory,\n    private val protectPdfToolComponentFactory: ProtectPdfToolComponent.Factory,\n    private val unlockPdfToolComponentFactory: UnlockPdfToolComponent.Factory,\n    private val compressPdfToolComponentFactory: CompressPdfToolComponent.Factory,\n    private val grayscalePdfToolComponentFactory: GrayscalePdfToolComponent.Factory,\n    private val repairPdfToolComponentFactory: RepairPdfToolComponent.Factory,\n    private val metadataPdfToolComponentFactory: MetadataPdfToolComponent.Factory,\n    private val removePagesPdfToolComponentFactory: RemovePagesPdfToolComponent.Factory,\n    private val cropPdfToolComponentFactory: CropPdfToolComponent.Factory,\n    private val flattenPdfToolComponentFactory: FlattenPdfToolComponent.Factory,\n    private val extractImagesPdfToolComponentFactory: ExtractImagesPdfToolComponent.Factory,\n    private val zipConvertPdfToolComponentFactory: ZipConvertPdfToolComponent.Factory,\n    private val printPdfToolComponentFactory: PrintPdfToolComponent.Factory,\n    private val previewPdfToolComponentFactory: PreviewPdfToolComponent.Factory,\n    private val imagesToPdfToolComponentFactory: ImagesToPdfToolComponent.Factory,\n    private val extractPagesPdfToolComponentFactory: ExtractPagesPdfToolComponent.Factory,\n    private val removeAnnotationsPdfToolComponentFactory: RemoveAnnotationsPdfToolComponent.Factory,\n) {\n    fun RootComponent.createChild(\n        config: Screen,\n        componentContext: ComponentContext\n    ): NavigationChild = when (config) {\n        Screen.ColorTools -> ColorTools(\n            colorToolsComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        Screen.EasterEgg -> EasterEgg(\n            easterEggComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        Screen.Main -> Main(\n            mainComponentFactory(\n                componentContext = componentContext,\n                onTryGetUpdate = ::tryGetUpdate,\n                onGetClipList = ::updateUris,\n                onNavigate = ::navigateToNew,\n                isUpdateAvailable = isUpdateAvailable\n            )\n        )\n\n        is Screen.ApngTools -> ApngTools(\n            apngToolsComponentFactory(\n                componentContext = componentContext,\n                initialType = config.type,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.Cipher -> Cipher(\n            cipherComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.CollageMaker -> CollageMaker(\n            collageMakerComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.Compare -> Compare(\n            compareComponentFactory(\n                componentContext = componentContext,\n                initialComparableUris = config.uris\n                    ?.takeIf { it.size == 2 }\n                    ?.let { it[0] to it[1] },\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.Crop -> Crop(\n            cropComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.DeleteExif -> DeleteExif(\n            deleteExifComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        Screen.DocumentScanner -> DocumentScanner(\n            documentScannerComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.Draw -> Draw(\n            drawComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.EraseBackground -> EraseBackground(\n            eraseBackgroundComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.Filter -> Filter(\n            filtersComponentFactory(\n                componentContext = componentContext,\n                initialType = config.type,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.FormatConversion -> FormatConversion(\n            formatConversionComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.PaletteTools -> PaletteTools(\n            paletteToolsComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.GifTools -> GifTools(\n            gifToolsComponentFactory(\n                componentContext = componentContext,\n                initialType = config.type,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.GradientMaker -> GradientMaker(\n            gradientMakerComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ImagePreview -> ImagePreview(\n            imagePreviewComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ImageSplitting -> ImageSplitting(\n            imageSplittingComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uri,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ImageStacking -> ImageStacking(\n            imageStackingComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ImageStitching -> ImageStitching(\n            imageStitchingComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.JxlTools -> JxlTools(\n            jxlToolsComponentFactory(\n                componentContext = componentContext,\n                initialType = config.type,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.LimitResize -> LimitResize(\n            limitResizeComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.LoadNetImage -> LoadNetImage(\n            loadNetImageComponentFactory(\n                componentContext = componentContext,\n                initialUrl = config.url,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n\n        Screen.NoiseGeneration -> NoiseGeneration(\n            noiseGenerationComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo,\n            )\n        )\n\n        is Screen.PdfTools -> RootPdfTools(\n            rootPdfToolsComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.PickColorFromImage -> PickColorFromImage(\n            pickColorFromImageComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.RecognizeText -> RecognizeText(\n            recognizeTextComponentFactory(\n                componentContext = componentContext,\n                initialType = config.type,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.ResizeAndConvert -> ResizeAndConvert(\n            resizeAndConvertComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ScanQrCode -> ScanQrCode(\n            scanQrCodeComponentFactory(\n                componentContext = componentContext,\n                initialQrCodeContent = config.qrCodeContent,\n                uriToAnalyze = config.uriToAnalyze,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.Settings -> Settings(\n            settingsComponentFactory(\n                componentContext = componentContext,\n                onTryGetUpdate = ::tryGetUpdate,\n                onNavigate = ::navigateToNew,\n                isUpdateAvailable = isUpdateAvailable,\n                onGoBack = ::navigateBack,\n                initialSearchQuery = config.searchQuery\n            )\n        )\n\n        is Screen.SingleEdit -> SingleEdit(\n            singleEditComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onNavigate = ::navigateTo,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.SvgMaker -> SvgMaker(\n            svgMakerComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.Watermarking -> Watermarking(\n            watermarkingComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.WebpTools -> WebpTools(\n            webpToolsComponentFactory(\n                componentContext = componentContext,\n                initialType = config.type,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.WeightResize -> WeightResize(\n            weightResizeComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.Zip -> Zip(\n            zipComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        Screen.LibrariesInfo -> LibrariesInfo(\n            librariesInfoComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.MarkupLayers -> MarkupLayers(\n            markupLayersComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.Base64Tools -> Base64Tools(\n            base64ToolsComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ChecksumTools -> ChecksumTools(\n            checksumToolsComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.MeshGradients -> MeshGradients(\n            meshGradientsComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.EditExif -> EditExif(\n            editExifComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ImageCutter -> ImageCutter(\n            imageCutterComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.AudioCoverExtractor -> AudioCoverExtractor(\n            audioCoverExtractorComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.LibraryDetails -> LibraryDetails(\n            libraryDetailsComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                libraryName = config.name,\n                libraryDescription = config.htmlDescription,\n                libraryLink = config.link\n            )\n        )\n\n        is Screen.WallpapersExport -> WallpapersExport(\n            wallpapersExportComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.AsciiArt -> AsciiArt(\n            asciiArtComponentFactory(\n                componentContext = componentContext,\n                initialUri = config.uri,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.AiTools -> AiTools(\n            aiToolsComponentFactory(\n                componentContext = componentContext,\n                initialUris = config.uris,\n                onGoBack = ::navigateBack,\n                onNavigate = ::navigateTo\n            )\n        )\n\n        is Screen.ColorLibrary -> ColorLibrary(\n            colorLibraryComponentFactory(\n                componentContext = componentContext,\n                onGoBack = ::navigateBack\n            )\n        )\n\n        is Screen.PdfTools.Merge -> MergePdfTool(\n            mergePdfToolComponentFactory(\n                initialUris = config.uris,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Split -> SplitPdfTool(\n            splitPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Rotate -> RotatePdfTool(\n            rotatePdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Rearrange -> RearrangePdfTool(\n            rearrangePdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.PageNumbers -> PageNumbersPdfTool(\n            pageNumbersPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.OCR -> OCRPdfTool(\n            ocrPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Watermark -> WatermarkPdfTool(\n            watermarkPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Signature -> SignaturePdfTool(\n            signaturePdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Protect -> ProtectPdfTool(\n            protectPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Unlock -> UnlockPdfTool(\n            unlockPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Compress -> CompressPdfTool(\n            compressPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Grayscale -> GrayscalePdfTool(\n            grayscalePdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Repair -> RepairPdfTool(\n            repairPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Metadata -> MetadataPdfTool(\n            metadataPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.RemovePages -> RemovePagesPdfTool(\n            removePagesPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Crop -> CropPdfTool(\n            cropPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Flatten -> FlattenPdfTool(\n            flattenPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.ExtractImages -> ExtractImagesPdfTool(\n            extractImagesPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.ZipConvert -> ZipConvertPdfTool(\n            zipConvertPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Print -> PrintPdfTool(\n            printPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.Preview -> PreviewPdfTool(\n            previewPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.ImagesToPdf -> ImagesToPdfTool(\n            imagesToPdfToolComponentFactory(\n                initialUris = config.uris,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.ExtractPages -> ExtractPagesPdfTool(\n            extractPagesPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n        is Screen.PdfTools.RemoveAnnotations -> RemoveAnnotationsPdfTool(\n            removeAnnotationsPdfToolComponentFactory(\n                initialUri = config.uri,\n                componentContext = componentContext,\n                onGoBack = ::navigateBack,\n                onNavigate = ::replaceTo\n            )\n        )\n\n    }\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/navigation/NavigationChild.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.navigation\n\nimport androidx.compose.runtime.Composable\nimport com.t8rin.imagetoolbox.collage_maker.presentation.CollageMakerContent\nimport com.t8rin.imagetoolbox.collage_maker.presentation.screenLogic.CollageMakerComponent\nimport com.t8rin.imagetoolbox.color_library.presentation.ColorLibraryContent\nimport com.t8rin.imagetoolbox.color_library.presentation.screenLogic.ColorLibraryComponent\nimport com.t8rin.imagetoolbox.color_tools.presentation.ColorToolsContent\nimport com.t8rin.imagetoolbox.color_tools.presentation.screenLogic.ColorToolsComponent\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.AiToolsContent\nimport com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic.AiToolsComponent\nimport com.t8rin.imagetoolbox.feature.apng_tools.presentation.ApngToolsContent\nimport com.t8rin.imagetoolbox.feature.apng_tools.presentation.screenLogic.ApngToolsComponent\nimport com.t8rin.imagetoolbox.feature.ascii_art.presentation.AsciiArtContent\nimport com.t8rin.imagetoolbox.feature.ascii_art.presentation.screenLogic.AsciiArtComponent\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.AudioCoverExtractorContent\nimport com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.screenLogic.AudioCoverExtractorComponent\nimport com.t8rin.imagetoolbox.feature.base64_tools.presentation.Base64ToolsContent\nimport com.t8rin.imagetoolbox.feature.base64_tools.presentation.screenLogic.Base64ToolsComponent\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.ChecksumToolsContent\nimport com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent\nimport com.t8rin.imagetoolbox.feature.cipher.presentation.CipherContent\nimport com.t8rin.imagetoolbox.feature.cipher.presentation.screenLogic.CipherComponent\nimport com.t8rin.imagetoolbox.feature.compare.presentation.CompareContent\nimport com.t8rin.imagetoolbox.feature.compare.presentation.screenLogic.CompareComponent\nimport com.t8rin.imagetoolbox.feature.crop.presentation.CropContent\nimport com.t8rin.imagetoolbox.feature.crop.presentation.screenLogic.CropComponent\nimport com.t8rin.imagetoolbox.feature.delete_exif.presentation.DeleteExifContent\nimport com.t8rin.imagetoolbox.feature.delete_exif.presentation.screenLogic.DeleteExifComponent\nimport com.t8rin.imagetoolbox.feature.document_scanner.presentation.DocumentScannerContent\nimport com.t8rin.imagetoolbox.feature.document_scanner.presentation.screenLogic.DocumentScannerComponent\nimport com.t8rin.imagetoolbox.feature.draw.presentation.DrawContent\nimport com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent\nimport com.t8rin.imagetoolbox.feature.easter_egg.presentation.EasterEggContent\nimport com.t8rin.imagetoolbox.feature.easter_egg.presentation.screenLogic.EasterEggComponent\nimport com.t8rin.imagetoolbox.feature.edit_exif.presentation.EditExifContent\nimport com.t8rin.imagetoolbox.feature.edit_exif.presentation.screenLogic.EditExifComponent\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.EraseBackgroundContent\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.screenLogic.EraseBackgroundComponent\nimport com.t8rin.imagetoolbox.feature.filters.presentation.FiltersContent\nimport com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent\nimport com.t8rin.imagetoolbox.feature.format_conversion.presentation.FormatConversionContent\nimport com.t8rin.imagetoolbox.feature.format_conversion.presentation.screenLogic.FormatConversionComponent\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.GifToolsContent\nimport com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.GradientMakerContent\nimport com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent\nimport com.t8rin.imagetoolbox.feature.image_preview.presentation.ImagePreviewContent\nimport com.t8rin.imagetoolbox.feature.image_preview.presentation.screenLogic.ImagePreviewComponent\nimport com.t8rin.imagetoolbox.feature.image_stacking.presentation.ImageStackingContent\nimport com.t8rin.imagetoolbox.feature.image_stacking.presentation.screenLogic.ImageStackingComponent\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.ImageStitchingContent\nimport com.t8rin.imagetoolbox.feature.image_stitch.presentation.screenLogic.ImageStitchingComponent\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.JxlToolsContent\nimport com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent\nimport com.t8rin.imagetoolbox.feature.libraries_info.presentation.LibrariesInfoContent\nimport com.t8rin.imagetoolbox.feature.libraries_info.presentation.screenLogic.LibrariesInfoComponent\nimport com.t8rin.imagetoolbox.feature.limits_resize.presentation.LimitsResizeContent\nimport com.t8rin.imagetoolbox.feature.limits_resize.presentation.screenLogic.LimitsResizeComponent\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.LoadNetImageContent\nimport com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent\nimport com.t8rin.imagetoolbox.feature.main.presentation.MainContent\nimport com.t8rin.imagetoolbox.feature.main.presentation.screenLogic.MainComponent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.MarkupLayersContent\nimport com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent\nimport com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.MeshGradientsContent\nimport com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.screenLogic.MeshGradientsComponent\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.PaletteToolsContent\nimport com.t8rin.imagetoolbox.feature.palette_tools.presentation.screenLogic.PaletteToolsComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.CompressPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.screenLogic.CompressPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.CropPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.screenLogic.CropPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.ExtractImagesPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.screenLogic.ExtractImagesPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.ExtractPagesPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.screenLogic.ExtractPagesPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.FlattenPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.screenLogic.FlattenPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.GrayscalePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.screenLogic.GrayscalePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.ImagesToPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.screenLogic.ImagesToPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.MergePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.screenLogic.MergePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.MetadataPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.screenLogic.MetadataPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.OCRPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.screenLogic.OCRPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.PageNumbersPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.screenLogic.PageNumbersPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.PreviewPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.screenLogic.PreviewPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.PrintPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.screenLogic.PrintPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.ProtectPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.screenLogic.ProtectPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.RearrangePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.screenLogic.RearrangePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.RemoveAnnotationsPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.screenLogic.RemoveAnnotationsPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.RemovePagesPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.screenLogic.RemovePagesPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.RepairPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.screenLogic.RepairPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.RootPdfToolsContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.screenLogic.RootPdfToolsComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.RotatePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.screenLogic.RotatePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.SignaturePdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.screenLogic.SignaturePdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.SplitPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.screenLogic.SplitPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.UnlockPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.screenLogic.UnlockPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.WatermarkPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.screenLogic.WatermarkPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.ZipConvertPdfToolContent\nimport com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.screenLogic.ZipConvertPdfToolComponent\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.PickColorFromImageContent\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.screenLogic.PickColorFromImageComponent\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.RecognizeTextContent\nimport com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent\nimport com.t8rin.imagetoolbox.feature.resize_convert.presentation.ResizeAndConvertContent\nimport com.t8rin.imagetoolbox.feature.resize_convert.presentation.screenLogic.ResizeAndConvertComponent\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.ScanQrCodeContent\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.screenLogic.ScanQrCodeComponent\nimport com.t8rin.imagetoolbox.feature.settings.presentation.SettingsContent\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.SingleEditContent\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.screenLogic.SingleEditComponent\nimport com.t8rin.imagetoolbox.feature.svg_maker.presentation.SvgMakerContent\nimport com.t8rin.imagetoolbox.feature.svg_maker.presentation.screenLogic.SvgMakerComponent\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.WallpapersExportContent\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.WatermarkingContent\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.screenLogic.WatermarkingComponent\nimport com.t8rin.imagetoolbox.feature.webp_tools.presentation.WebpToolsContent\nimport com.t8rin.imagetoolbox.feature.webp_tools.presentation.screenLogic.WebpToolsComponent\nimport com.t8rin.imagetoolbox.feature.weight_resize.presentation.WeightResizeContent\nimport com.t8rin.imagetoolbox.feature.weight_resize.presentation.screenLogic.WeightResizeComponent\nimport com.t8rin.imagetoolbox.feature.zip.presentation.ZipContent\nimport com.t8rin.imagetoolbox.feature.zip.presentation.screenLogic.ZipComponent\nimport com.t8rin.imagetoolbox.image_cutting.presentation.ImageCutterContent\nimport com.t8rin.imagetoolbox.image_cutting.presentation.screenLogic.ImageCutterComponent\nimport com.t8rin.imagetoolbox.image_splitting.presentation.ImageSplitterContent\nimport com.t8rin.imagetoolbox.image_splitting.presentation.screenLogic.ImageSplitterComponent\nimport com.t8rin.imagetoolbox.library_details.presentation.LibraryDetailsContent\nimport com.t8rin.imagetoolbox.library_details.presentation.screenLogic.LibraryDetailsComponent\nimport com.t8rin.imagetoolbox.noise_generation.presentation.NoiseGenerationContent\nimport com.t8rin.imagetoolbox.noise_generation.presentation.screenLogic.NoiseGenerationComponent\n\n\ninternal sealed interface NavigationChild {\n\n    @Composable\n    fun Content()\n\n\n    class ApngTools(private val component: ApngToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ApngToolsContent(component)\n    }\n\n    class Cipher(private val component: CipherComponent) : NavigationChild {\n        @Composable\n        override fun Content() = CipherContent(component)\n    }\n\n    class CollageMaker(private val component: CollageMakerComponent) : NavigationChild {\n        @Composable\n        override fun Content() = CollageMakerContent(component)\n    }\n\n    class ColorTools(private val component: ColorToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ColorToolsContent(component)\n    }\n\n    class Compare(private val component: CompareComponent) : NavigationChild {\n        @Composable\n        override fun Content() = CompareContent(component)\n    }\n\n    class Crop(private val component: CropComponent) : NavigationChild {\n        @Composable\n        override fun Content() = CropContent(component)\n    }\n\n    class DeleteExif(private val component: DeleteExifComponent) : NavigationChild {\n        @Composable\n        override fun Content() = DeleteExifContent(component)\n    }\n\n    class DocumentScanner(private val component: DocumentScannerComponent) : NavigationChild {\n        @Composable\n        override fun Content() = DocumentScannerContent(component)\n    }\n\n    class Draw(private val component: DrawComponent) : NavigationChild {\n        @Composable\n        override fun Content() = DrawContent(component)\n    }\n\n    class EasterEgg(private val component: EasterEggComponent) : NavigationChild {\n        @Composable\n        override fun Content() = EasterEggContent(component)\n    }\n\n    class EraseBackground(private val component: EraseBackgroundComponent) : NavigationChild {\n        @Composable\n        override fun Content() = EraseBackgroundContent(component)\n    }\n\n    class Filter(private val component: FiltersComponent) : NavigationChild {\n        @Composable\n        override fun Content() = FiltersContent(component)\n    }\n\n    class FormatConversion(private val component: FormatConversionComponent) : NavigationChild {\n        @Composable\n        override fun Content() = FormatConversionContent(component)\n    }\n\n    class PaletteTools(private val component: PaletteToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = PaletteToolsContent(component)\n    }\n\n    class GifTools(private val component: GifToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = GifToolsContent(component)\n    }\n\n    class GradientMaker(private val component: GradientMakerComponent) : NavigationChild {\n        @Composable\n        override fun Content() = GradientMakerContent(component)\n    }\n\n    class ImagePreview(private val component: ImagePreviewComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ImagePreviewContent(component)\n    }\n\n    class ImageSplitting(private val component: ImageSplitterComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ImageSplitterContent(component)\n    }\n\n    class ImageStacking(private val component: ImageStackingComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ImageStackingContent(component)\n    }\n\n    class ImageStitching(private val component: ImageStitchingComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ImageStitchingContent(component)\n    }\n\n    class JxlTools(private val component: JxlToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = JxlToolsContent(component)\n    }\n\n    class LimitResize(private val component: LimitsResizeComponent) : NavigationChild {\n        @Composable\n        override fun Content() = LimitsResizeContent(component)\n    }\n\n    class LoadNetImage(private val component: LoadNetImageComponent) : NavigationChild {\n        @Composable\n        override fun Content() = LoadNetImageContent(component)\n    }\n\n    class Main(private val component: MainComponent) : NavigationChild {\n        @Composable\n        override fun Content() = MainContent(component)\n    }\n\n    class NoiseGeneration(private val component: NoiseGenerationComponent) : NavigationChild {\n        @Composable\n        override fun Content() = NoiseGenerationContent(component)\n    }\n\n    class RootPdfTools(private val component: RootPdfToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = RootPdfToolsContent(component)\n    }\n\n    class PickColorFromImage(private val component: PickColorFromImageComponent) : NavigationChild {\n        @Composable\n        override fun Content() = PickColorFromImageContent(component)\n    }\n\n    class RecognizeText(private val component: RecognizeTextComponent) : NavigationChild {\n        @Composable\n        override fun Content() = RecognizeTextContent(component)\n    }\n\n    class ResizeAndConvert(private val component: ResizeAndConvertComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ResizeAndConvertContent(component)\n    }\n\n    class ScanQrCode(private val component: ScanQrCodeComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ScanQrCodeContent(component)\n    }\n\n    class Settings(private val component: SettingsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = SettingsContent(component)\n    }\n\n    class SingleEdit(private val component: SingleEditComponent) : NavigationChild {\n        @Composable\n        override fun Content() = SingleEditContent(component)\n    }\n\n    class SvgMaker(private val component: SvgMakerComponent) : NavigationChild {\n        @Composable\n        override fun Content() = SvgMakerContent(component)\n    }\n\n    class Watermarking(private val component: WatermarkingComponent) : NavigationChild {\n        @Composable\n        override fun Content() = WatermarkingContent(component)\n    }\n\n    class WebpTools(private val component: WebpToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = WebpToolsContent(component)\n    }\n\n    class WeightResize(private val component: WeightResizeComponent) : NavigationChild {\n        @Composable\n        override fun Content() = WeightResizeContent(component)\n    }\n\n    class Zip(private val component: ZipComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ZipContent(component)\n    }\n\n    class LibrariesInfo(private val component: LibrariesInfoComponent) : NavigationChild {\n        @Composable\n        override fun Content() = LibrariesInfoContent(component)\n    }\n\n    class MarkupLayers(private val component: MarkupLayersComponent) : NavigationChild {\n        @Composable\n        override fun Content() = MarkupLayersContent(component)\n    }\n\n    class Base64Tools(private val component: Base64ToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = Base64ToolsContent(component)\n    }\n\n    class ChecksumTools(private val component: ChecksumToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ChecksumToolsContent(component)\n    }\n\n    class MeshGradients(private val component: MeshGradientsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = MeshGradientsContent(component)\n    }\n\n    class EditExif(private val component: EditExifComponent) : NavigationChild {\n        @Composable\n        override fun Content() = EditExifContent(component)\n    }\n\n    class ImageCutter(private val component: ImageCutterComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ImageCutterContent(component)\n    }\n\n    class AudioCoverExtractor(\n        private val component: AudioCoverExtractorComponent\n    ) : NavigationChild {\n        @Composable\n        override fun Content() = AudioCoverExtractorContent(component)\n    }\n\n    class LibraryDetails(private val component: LibraryDetailsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = LibraryDetailsContent(component)\n    }\n\n    class WallpapersExport(private val component: WallpapersExportComponent) : NavigationChild {\n        @Composable\n        override fun Content() = WallpapersExportContent(component)\n    }\n\n    class AsciiArt(private val component: AsciiArtComponent) : NavigationChild {\n        @Composable\n        override fun Content() = AsciiArtContent(component)\n    }\n\n    class AiTools(private val component: AiToolsComponent) : NavigationChild {\n        @Composable\n        override fun Content() = AiToolsContent(component)\n    }\n\n    class ColorLibrary(private val component: ColorLibraryComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ColorLibraryContent(component)\n    }\n\n    class MergePdfTool(private val component: MergePdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = MergePdfToolContent(component)\n    }\n\n    class SplitPdfTool(private val component: SplitPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = SplitPdfToolContent(component)\n    }\n\n    class RotatePdfTool(private val component: RotatePdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = RotatePdfToolContent(component)\n    }\n\n    class RearrangePdfTool(private val component: RearrangePdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = RearrangePdfToolContent(component)\n    }\n\n    class PageNumbersPdfTool(private val component: PageNumbersPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = PageNumbersPdfToolContent(component)\n    }\n\n    class OCRPdfTool(private val component: OCRPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = OCRPdfToolContent(component)\n    }\n\n    class WatermarkPdfTool(private val component: WatermarkPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = WatermarkPdfToolContent(component)\n    }\n\n    class SignaturePdfTool(private val component: SignaturePdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = SignaturePdfToolContent(component)\n    }\n\n    class ProtectPdfTool(private val component: ProtectPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ProtectPdfToolContent(component)\n    }\n\n    class UnlockPdfTool(private val component: UnlockPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = UnlockPdfToolContent(component)\n    }\n\n    class CompressPdfTool(private val component: CompressPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = CompressPdfToolContent(component)\n    }\n\n    class GrayscalePdfTool(private val component: GrayscalePdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = GrayscalePdfToolContent(component)\n    }\n\n    class RepairPdfTool(private val component: RepairPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = RepairPdfToolContent(component)\n    }\n\n    class MetadataPdfTool(private val component: MetadataPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = MetadataPdfToolContent(component)\n    }\n\n    class RemovePagesPdfTool(private val component: RemovePagesPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = RemovePagesPdfToolContent(component)\n    }\n\n    class CropPdfTool(private val component: CropPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = CropPdfToolContent(component)\n    }\n\n    class FlattenPdfTool(private val component: FlattenPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = FlattenPdfToolContent(component)\n    }\n\n    class ExtractImagesPdfTool(private val component: ExtractImagesPdfToolComponent) :\n        NavigationChild {\n        @Composable\n        override fun Content() = ExtractImagesPdfToolContent(component)\n    }\n\n    class ZipConvertPdfTool(private val component: ZipConvertPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ZipConvertPdfToolContent(component)\n    }\n\n    class PrintPdfTool(private val component: PrintPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = PrintPdfToolContent(component)\n    }\n\n    class PreviewPdfTool(private val component: PreviewPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = PreviewPdfToolContent(component)\n    }\n\n    class ImagesToPdfTool(private val component: ImagesToPdfToolComponent) : NavigationChild {\n        @Composable\n        override fun Content() = ImagesToPdfToolContent(component)\n    }\n\n    class ExtractPagesPdfTool(private val component: ExtractPagesPdfToolComponent) :\n        NavigationChild {\n        @Composable\n        override fun Content() = ExtractPagesPdfToolContent(component)\n    }\n\n    class RemoveAnnotationsPdfTool(private val component: RemoveAnnotationsPdfToolComponent) :\n        NavigationChild {\n        @Composable\n        override fun Content() = RemoveAnnotationsPdfToolContent(component)\n    }\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/utils/BackEventObserver.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.utils\n\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\n\nfun interface BackEventObserver {\n    fun onBack(closedScreen: Screen?)\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/utils/ResetThemeOnGoBack.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.utils\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport com.t8rin.dynamic.theme.LocalDynamicThemeState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\n\n@Composable\ninternal fun ResetThemeOnGoBack(\n    component: RootComponent\n) {\n    val appColorTuple = rememberAppColorTuple()\n    val themeState = LocalDynamicThemeState.current\n\n    DisposableEffect(component, themeState, appColorTuple) {\n        val observer = BackEventObserver {\n            themeState.updateColorTuple(appColorTuple)\n        }\n\n        component.addBackEventsObserver(observer)\n\n        onDispose {\n            component.removeBackEventsObserver(observer)\n        }\n    }\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/utils/ScreenBasedMaxBrightnessEnforcement.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.utils\n\nimport android.view.WindowManager\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.ui.util.fastAny\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\n\n@Composable\ninternal fun ScreenBasedMaxBrightnessEnforcement(\n    currentScreen: Screen?\n) {\n    val context = LocalComponentActivity.current\n\n    val listToForceBrightness = LocalSettingsState.current.screenListWithMaxBrightnessEnforcement\n\n    DisposableEffect(currentScreen) {\n        if (listToForceBrightness.fastAny { it == currentScreen?.id }) {\n            context.window.apply {\n                attributes.apply {\n                    screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL\n                }\n                addFlags(WindowManager.LayoutParams.SCREEN_BRIGHTNESS_CHANGED)\n            }\n        }\n        onDispose {\n            context.window.apply {\n                attributes.apply {\n                    screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE\n                }\n                addFlags(WindowManager.LayoutParams.SCREEN_BRIGHTNESS_CHANGED)\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/utils/SettingsUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.utils\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport com.arkivanov.decompose.extensions.compose.subscribeAsState\nimport com.arkivanov.decompose.router.stack.ChildStack\nimport com.arkivanov.decompose.value.Value\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\nimport kotlinx.coroutines.delay\n\n@Composable\ninternal fun RootComponent.uiSettingsState(): UiSettingsState = settingsState.toUiState(\n    randomEmojiKey = childStack.randomEmojiKey()\n)\n\n@Composable\ninternal fun HandleLookForUpdates(component: RootComponent) {\n    if (component.settingsState.shouldTryGetUpdate) {\n        LaunchedEffect(Unit) {\n            delay(500)\n            component.tryGetUpdate()\n        }\n    }\n}\n\n\nprivate val SettingsState.shouldTryGetUpdate: Boolean\n    get() = appOpenCount >= 2 && showUpdateDialogOnStartup\n\n@Composable\nprivate fun Value<ChildStack<Screen, *>>.randomEmojiKey(): Any {\n    val randomEmojiKey = remember {\n        mutableIntStateOf(0)\n    }\n\n    val currentDestination = subscribeAsState().value.items\n    LaunchedEffect(currentDestination) {\n        delay(200L) // Delay for transition\n        randomEmojiKey.intValue++\n    }\n\n    return randomEmojiKey.intValue\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/components/utils/SuccessRestoreBackupToastHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.components.utils\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Save\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun SuccessRestoreBackupToastHandler(component: RootComponent) {\n    val context = LocalComponentActivity.current\n    LaunchedEffect(component) {\n        component.backupRestoredEvents.collectLatest { restored ->\n            if (restored) {\n                launch {\n                    AppToastHost.showConfetti()\n                    //Wait for confetti to appear, then trigger font scale adjustment\n                    delay(300L)\n                    context.recreate()\n                }\n                AppToastHost.showToast(\n                    message = context.getString(R.string.settings_restored),\n                    icon = Icons.Rounded.Save\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/root/src/main/java/com/t8rin/imagetoolbox/feature/root/presentation/screenLogic/RootComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.root.presentation.screenLogic\n\nimport android.content.Intent\nimport android.net.Uri\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ErrorOutline\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.childContext\nimport com.arkivanov.decompose.router.stack.ChildStack\nimport com.arkivanov.decompose.router.stack.StackNavigation\nimport com.arkivanov.decompose.router.stack.childStack\nimport com.arkivanov.decompose.router.stack.items\nimport com.arkivanov.decompose.router.stack.navigate\nimport com.arkivanov.decompose.router.stack.pop\nimport com.arkivanov.decompose.router.stack.pushNew\nimport com.arkivanov.decompose.value.MutableValue\nimport com.arkivanov.decompose.value.Value\nimport com.t8rin.imagetoolbox.core.domain.APP_CHANGELOG\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.model.ExtraDataType\nimport com.t8rin.imagetoolbox.core.domain.model.ImageModel\nimport com.t8rin.imagetoolbox.core.domain.model.PerformanceClass\nimport com.t8rin.imagetoolbox.core.domain.remote.AnalyticsManager\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterParamsInteractor\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.handleDeeplinks\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration\nimport com.t8rin.imagetoolbox.core.utils.isNeedUpdate\nimport com.t8rin.imagetoolbox.core.utils.parseChangelog\nimport com.t8rin.imagetoolbox.core.utils.toImageModel\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.ChildProvider\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild\nimport com.t8rin.imagetoolbox.feature.root.presentation.components.utils.BackEventObserver\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\nimport com.t8rin.logger.makeLog\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport io.ktor.client.HttpClient\nimport io.ktor.client.request.get\nimport io.ktor.client.statement.bodyAsChannel\nimport io.ktor.utils.io.jvm.javaio.toInputStream\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.channels.Channel\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.flow.receiveAsFlow\nimport kotlinx.coroutines.runBlocking\nimport kotlinx.coroutines.withContext\n\nclass RootComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    private val settingsManager: SettingsManager,\n    private val childProvider: ChildProvider,\n    private val analyticsManager: AnalyticsManager,\n    private val client: HttpClient,\n    filterParamsInteractor: FilterParamsInteractor,\n    fileController: FileController,\n    dispatchersHolder: DispatchersHolder,\n    settingsComponentFactory: SettingsComponent.Factory,\n    resourceManager: ResourceManager,\n) : BaseComponent(dispatchersHolder, componentContext), ResourceManager by resourceManager {\n\n    private var updatesJob: Job? by smartJob()\n\n    private val _backupRestoredEvents: Channel<Boolean> = Channel(Channel.BUFFERED)\n    val backupRestoredEvents: Flow<Boolean> = _backupRestoredEvents.receiveAsFlow()\n\n    private val _isUpdateAvailable: MutableValue<Boolean> = MutableValue(false)\n    val isUpdateAvailable: Value<Boolean> = _isUpdateAvailable\n\n    private val _concealBackdropChannel: Channel<Boolean> = Channel(Channel.BUFFERED)\n    val concealBackdropFlow: Flow<Boolean> = _concealBackdropChannel.receiveAsFlow()\n\n    val settingsComponent = settingsComponentFactory(\n        componentContext = childContext(\"rootSettings\"),\n        onTryGetUpdate = ::tryGetUpdate,\n        onNavigate = ::navigateTo,\n        isUpdateAvailable = isUpdateAvailable,\n        onGoBack = {\n            _concealBackdropChannel.trySend(true)\n        },\n        initialSearchQuery = \"\"\n    )\n\n    private val _settingsState = mutableStateOf(SettingsState.Default)\n    val settingsState: SettingsState by _settingsState\n\n    private val navController = StackNavigation<Screen>()\n\n    internal val childStack: Value<ChildStack<Screen, NavigationChild>> by lazy {\n        childStack(\n            source = navController,\n            initialConfiguration = Screen.Main,\n            serializer = Screen.serializer(),\n            handleBackButton = true,\n            childFactory = { screen, context ->\n                with(childProvider) {\n                    createChild(\n                        config = screen,\n                        componentContext = context\n                    )\n                }\n            }\n        )\n    }\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _extraDataType = mutableStateOf<ExtraDataType?>(null)\n    val extraDataType: ExtraDataType? by _extraDataType\n\n    private val _showSelectDialog = mutableStateOf(false)\n    val showSelectDialog by _showSelectDialog\n\n    private val _showUpdateDialog = mutableStateOf(false)\n    val showUpdateDialog by _showUpdateDialog\n\n    private val _isUpdateCancelled = mutableStateOf(false)\n\n    private val _shouldShowExitDialog = mutableStateOf(true)\n    val shouldShowDialog by _shouldShowExitDialog\n\n    private val _showGithubReviewDialog = mutableStateOf(false)\n    val showGithubReviewDialog by _showGithubReviewDialog\n\n    private val _showTelegramGroupDialog = mutableStateOf(false)\n    val showTelegramGroupDialog by _showTelegramGroupDialog\n\n    private val _tag = mutableStateOf(\"\")\n    val tag by _tag\n\n    private val _changelog = mutableStateOf(\"\")\n    val changelog by _changelog\n\n    private val _filterPreviewModel: MutableState<ImageModel> =\n        mutableStateOf(R.drawable.filter_preview_source.toImageModel())\n    val filterPreviewModel by _filterPreviewModel\n\n    private val _canSetDynamicFilterPreview: MutableState<Boolean> =\n        mutableStateOf(false)\n    val canSetDynamicFilterPreview by _canSetDynamicFilterPreview\n\n    init {\n        runBlocking {\n            _settingsState.value = settingsManager.getSettingsState()\n\n            if (settingsState.clearCacheOnLaunch && fileController.getCacheSize() > 20 * 1024 * 1024) {\n                fileController.clearCache()\n            }\n        }\n        settingsManager\n            .settingsState\n            .onEach { state ->\n                _showTelegramGroupDialog.update {\n                    state.appOpenCount % 6 == 0 && state.appOpenCount != 0 && !state.isTelegramGroupOpened\n                }\n                _settingsState.value = state\n            }\n            .launchIn(componentScope)\n\n        if (settingsState.screenList.size != Screen.entries.size) {\n            componentScope.launch {\n                val currentList = settingsState.screenList\n                val neededList = Screen.entries.filter { it.id !in currentList }.map { it.id }\n                settingsManager.setScreenOrder(\n                    (currentList + neededList).joinToString(\"/\")\n                )\n            }\n        }\n\n        filterParamsInteractor\n            .getFilterPreviewModel().onEach { data ->\n                _filterPreviewModel.update { data }\n            }.launchIn(componentScope)\n\n        filterParamsInteractor\n            .getCanSetDynamicFilterPreview().onEach { value ->\n                _canSetDynamicFilterPreview.update { value }\n            }.launchIn(componentScope)\n    }\n\n    fun toggleShowUpdateDialog() {\n        componentScope.launch {\n            settingsManager.toggleShowUpdateDialogOnStartup()\n        }\n    }\n\n    fun setPresets(newPresets: List<Int>) {\n        componentScope.launch {\n            settingsManager.setPresets(newPresets)\n        }\n    }\n\n    fun cancelledUpdate(showAgain: Boolean = false) {\n        if (!showAgain) _isUpdateCancelled.value = true\n        _showUpdateDialog.value = false\n    }\n\n    fun tryGetUpdate(\n        isNewRequest: Boolean = false,\n        onNoUpdates: () -> Unit = {}\n    ) {\n        if (settingsState.appOpenCount < 2 && !isNewRequest) return\n        val isInstalledFromMarket = settingsManager.isInstalledFromPlayStore()\n\n        val showDialog = settingsState.showUpdateDialogOnStartup\n        if (isInstalledFromMarket) {\n            if (showDialog) {\n                _showUpdateDialog.value = isNewRequest\n            }\n        } else {\n            if (!_isUpdateCancelled.value || isNewRequest) {\n                updatesJob = componentScope.launch {\n                    checkForUpdates(\n                        showDialog = showDialog,\n                        onNoUpdates = onNoUpdates\n                    )\n                }\n            }\n        }\n    }\n\n    private suspend fun checkForUpdates(\n        showDialog: Boolean,\n        onNoUpdates: () -> Unit\n    ) = withContext(defaultDispatcher) {\n        \"start updates check\".makeLog(\"checkForUpdates\")\n        runCatching {\n            val (tag, changelog) = client\n                .get(APP_CHANGELOG).bodyAsChannel().toInputStream()\n                .use { it.parseChangelog() }\n\n            _tag.update { tag }\n            _changelog.update { changelog }\n\n            val isNeedUpdate = isNeedUpdate(\n                updateName = tag,\n                allowBetas = settingsState.allowBetas\n            ).makeLog(\"checkForUpdates\") { \"isNeedUpdate = $it\" }\n\n            if (isNeedUpdate) {\n                _isUpdateAvailable.value = true\n                _showUpdateDialog.value = showDialog\n            } else {\n                onNoUpdates()\n            }\n        }.onFailure {\n            it.makeLog(\"checkForUpdates\")\n            onNoUpdates()\n        }\n    }\n\n    fun hideSelectDialog() {\n        _showSelectDialog.value = false\n        _uris.update { null }\n    }\n\n    fun updateUris(uris: List<Uri>) {\n        _uris.value = uris\n\n        if (uris.isNotEmpty() || extraDataType != null) {\n            _showSelectDialog.value = true\n        }\n    }\n\n    fun updateExtraDataType(type: ExtraDataType?) {\n        type.makeLog(\"updateExtraDataType\")\n\n        if (type is ExtraDataType.Backup) {\n            componentScope.launch {\n                settingsManager.restoreFromBackupFile(\n                    backupFileUri = type.uri.trim(),\n                    onSuccess = {\n                        _backupRestoredEvents.trySend(true)\n                    },\n                    onFailure = { throwable ->\n                        AppToastHost.showToast(\n                            message = getString(\n                                R.string.smth_went_wrong,\n                                throwable.localizedMessage ?: \"\"\n                            ),\n                            icon = Icons.Rounded.ErrorOutline,\n                            duration = ToastDuration.Long\n                        )\n                        _backupRestoredEvents.trySend(false)\n                    }\n                )\n            }\n            return\n        }\n\n        _extraDataType.update { null }\n        _extraDataType.update { type }\n    }\n\n    fun cancelShowingExitDialog() {\n        _shouldShowExitDialog.update { false }\n    }\n\n    fun toggleAllowBetas() {\n        componentScope.launch {\n            settingsManager.toggleAllowBetas()\n        }\n    }\n\n    fun onWantGithubReview() {\n        _showGithubReviewDialog.update { true }\n    }\n\n    fun hideReviewDialog() {\n        _showGithubReviewDialog.update { false }\n    }\n\n    fun hideTelegramGroupDialog() {\n        _showTelegramGroupDialog.update { false }\n    }\n\n    fun adjustPerformance(performanceClass: PerformanceClass) {\n        componentScope.launch {\n            settingsManager.adjustPerformance(performanceClass)\n        }\n    }\n\n    fun registerDonateDialogOpen() {\n        componentScope.launch {\n            settingsManager.registerDonateDialogOpen()\n        }\n    }\n\n    fun notShowDonateDialogAgain() {\n        componentScope.launch {\n            settingsManager.setNotShowDonateDialogAgain()\n        }\n    }\n\n    fun registerTelegramGroupOpen() {\n        componentScope.launch {\n            settingsManager.registerTelegramGroupOpen()\n        }\n    }\n\n    fun navigateTo(screen: Screen) {\n        componentScope.launch {\n            delay(100)\n            screen.simpleName.makeLog(\"Navigator\").also(analyticsManager::registerScreenOpen)\n            navController.pushNew(screen)\n            hideSelectDialog()\n        }\n    }\n\n    fun replaceTo(screen: Screen) {\n        componentScope.launch {\n            delay(100)\n            screen.simpleName.makeLog(\"Navigator\").also(analyticsManager::registerScreenOpen)\n            navController.navigate(\n                transformer = { stack ->\n                    stack.dropLastWhile { it !is Screen.PdfTools } + screen\n                }\n            )   \n            hideSelectDialog()\n        }\n    }\n\n    fun navigateToNew(screen: Screen) {\n        if (childStack.items.lastOrNull()?.configuration != Screen.Main) {\n            navigateBack()\n        }\n        screen.simpleName.makeLog(\"Navigator\").also(analyticsManager::registerScreenOpen)\n        navController.pushNew(screen)\n    }\n\n    private val backEventsObservers: MutableList<BackEventObserver> = mutableListOf()\n\n    fun navigateBack() {\n        val closedScreen = childStack.items.lastOrNull()?.configuration\n        backEventsObservers.forEach { observer ->\n            observer.onBack(closedScreen)\n        }\n        hideSelectDialog()\n        \"Pop ${closedScreen?.simpleName}\".makeLog(\"Navigator\")\n        navController.pop()\n    }\n\n    fun addBackEventsObserver(\n        observer: BackEventObserver\n    ) {\n        backEventsObservers.add(observer)\n    }\n\n    fun removeBackEventsObserver(\n        observer: BackEventObserver\n    ) {\n        backEventsObservers.remove(observer)\n    }\n\n    fun handleDeeplinks(intent: Intent?) {\n        intent.handleDeeplinks(\n            onStart = ::hideSelectDialog,\n            onHasExtraDataType = ::updateExtraDataType,\n            onColdStart = ::cancelShowingExitDialog,\n            onGetUris = ::updateUris,\n            onNavigate = ::navigateTo,\n            isHasUris = !uris.isNullOrEmpty(),\n            onWantGithubReview = ::onWantGithubReview,\n            isOpenEditInsteadOfPreview = settingsState.openEditInsteadOfPreview\n        )\n    }\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext\n        ): RootComponent\n    }\n\n}"
  },
  {
    "path": "feature/scan-qr-code/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/scan-qr-code/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.scan_qr_code\"\n\ndependencies {\n    implementation(projects.core.filters)\n    \"marketImplementation\"(libs.quickie.bundled)\n    \"fossImplementation\"(libs.quickie.foss)\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/data/AndroidImageBarcodeReader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.data.utils.toSoftware\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.utils.toQrType\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.domain.ImageBarcodeReader\nimport io.github.g00fy2.quickie.extensions.readQrCode\nimport kotlinx.coroutines.suspendCancellableCoroutine\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.coroutines.resume\n\ninternal class AndroidImageBarcodeReader @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    resourceManager: ResourceManager,\n    dispatchersHolder: DispatchersHolder\n) : ImageBarcodeReader, DispatchersHolder by dispatchersHolder, ResourceManager by resourceManager {\n\n    override suspend fun readBarcode(\n        image: Any\n    ): Result<QrType> = withContext(defaultDispatcher) {\n        val bitmap = image as? Bitmap\n            ?: imageGetter.getImage(\n                data = image,\n                originalSize = false\n            )\n\n        if (bitmap == null) {\n            return@withContext Result.failure(NullPointerException(getString(R.string.something_went_wrong)))\n        }\n\n        suspendCancellableCoroutine { continuation ->\n            bitmap.toSoftware().readQrCode(\n                barcodeFormats = IntArray(0),\n                onSuccess = {\n                    continuation.resume(Result.success(it.toQrType()))\n                },\n                onFailure = {\n                    continuation.resume(Result.failure(it))\n                }\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/di/ScanQrCodeModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.di\n\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.data.AndroidImageBarcodeReader\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.domain.ImageBarcodeReader\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ScanQrCodeModule {\n\n    @Binds\n    @Singleton\n    fun reader(\n        impl: AndroidImageBarcodeReader\n    ): ImageBarcodeReader\n\n\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/domain/ImageBarcodeReader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.domain\n\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\n\ninterface ImageBarcodeReader {\n\n    suspend fun readBarcode(\n        image: Any\n    ): Result<QrType>\n\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/ScanQrCodeContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation\n\nimport android.annotation.SuppressLint\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.AutoFixHigh\nimport androidx.compose.material.icons.rounded.ImageSearch\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BarcodeScanner\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.rememberCaptureController\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberBarcodeScanner\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BarcodeType\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.other.renderAsQr\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.QrCodePreview\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.ScanQrCodeControls\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.screenLogic.ScanQrCodeComponent\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@SuppressLint(\"StringFormatInvalid\")\n@Composable\nfun ScanQrCodeContent(\n    component: ScanQrCodeComponent\n) {\n    val params = component.params\n\n    val scanner = rememberBarcodeScanner {\n        component.updateParams(\n            params = params.copy(\n                content = it\n            )\n        )\n    }\n\n    val isNotScannable = params.content.raw.isNotEmpty() && component.mayBeNotScannable\n    val isSaveEnabled = params.content.raw.isNotEmpty() && component.isSaveEnabled\n\n    val analyzerImagePicker = rememberImagePicker { uri: Uri ->\n        component.readBarcodeFromImage(\n            image = uri,\n            onFailure = {\n                AppToastHost.showFailureToast(\n                    Throwable(getString(R.string.no_barcode_found), it)\n                )\n            }\n        )\n    }\n\n    val captureController = rememberCaptureController()\n\n    LaunchedEffect(params) {\n        if (params.content.raw.isEmpty()) return@LaunchedEffect\n        delay(500)\n        component.syncReadBarcodeFromImage(\n            image = params.qrParams.renderAsQr(\n                content = params.content.raw,\n                type = params.type\n            )\n        )\n    }\n\n    LaunchedEffect(params.content) {\n        component.processFilterTemplateFromQrContent(\n            onSuccess = { filterName, filtersCount ->\n                AppToastHost.showToast(\n                    message = getString(\n                        R.string.added_filter_template,\n                        filterName,\n                        filtersCount\n                    ),\n                    icon = Icons.Outlined.AutoFixHigh\n                )\n            }\n        )\n    }\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?, bitmap: Bitmap) -> Unit =\n        { oneTimeSaveLocationUri, bitmap ->\n            component.saveBitmap(\n                bitmap = bitmap,\n                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n            )\n        }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    val scope = rememberCoroutineScope()\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        title = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                modifier = Modifier.marquee()\n            ) {\n                Text(\n                    text = stringResource(R.string.qr_code)\n                )\n                EnhancedBadge(\n                    content = {\n                        Text(\n                            text = BarcodeType.entries.size.toString()\n                        )\n                    },\n                    containerColor = MaterialTheme.colorScheme.tertiary,\n                    contentColor = MaterialTheme.colorScheme.onTertiary,\n                    modifier = Modifier\n                        .padding(horizontal = 2.dp)\n                        .padding(bottom = 12.dp)\n                        .scaleOnTap {\n                            AppToastHost.showConfetti()\n                        }\n                )\n            }\n        },\n        onGoBack = component.onGoBack,\n        actions = {\n            ShareButton(\n                enabled = params.content.raw.isNotEmpty(),\n                onShare = {\n                    scope.launch {\n                        component.shareImage(\n                            bitmap = captureController.bitmap()\n                        )\n                    }\n                },\n                onCopy = {\n                    scope.launch {\n                        component.cacheImage(\n                            bitmap = captureController.bitmap(),\n                            onComplete = Clipboard::copy\n                        )\n                    }\n                }\n            )\n        },\n        topAppBarPersistentActions = {\n            TopAppBarEmoji()\n        },\n        showImagePreviewAsStickyHeader = false,\n        imagePreview = {\n            if (!isPortrait) {\n                QrCodePreview(\n                    captureController = captureController,\n                    isLandscape = true,\n                    params = params,\n                    onStartScan = scanner::scan\n                )\n            }\n        },\n        controls = {\n            if (isPortrait) {\n                Spacer(modifier = Modifier.height(20.dp))\n                QrCodePreview(\n                    captureController = captureController,\n                    isLandscape = false,\n                    params = params,\n                    onStartScan = scanner::scan\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n            }\n            ScanQrCodeControls(\n                component = component\n            )\n        },\n        buttons = { actions ->\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = params.content.raw.isEmpty() && isPortrait,\n                secondaryButtonIcon = Icons.Outlined.BarcodeScanner,\n                secondaryButtonText = stringResource(R.string.start_scanning),\n                onSecondaryButtonClick = scanner::scan,\n                isPrimaryButtonEnabled = isSaveEnabled,\n                onPrimaryButtonClick = {\n                    scope.launch {\n                        saveBitmap(null, captureController.bitmap())\n                    }\n                },\n                primaryButtonContainerColor = takeColorFromScheme {\n                    if (isNotScannable) error\n                    else primaryContainer\n                },\n                primaryButtonContentColor = takeColorFromScheme {\n                    if (isNotScannable) onError\n                    else onPrimaryContainer\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                isPrimaryButtonVisible = isPortrait || params.content.raw.isNotEmpty(),\n                actions = {\n                    if (isPortrait) actions()\n                },\n                showMiddleFabInRow = true,\n                middleFab = {\n                    EnhancedFloatingActionButton(\n                        onClick = analyzerImagePicker::pickImage,\n                        onLongClick = {\n                            showOneTimeImagePickingDialog = true\n                        },\n                        containerColor = takeColorFromScheme {\n                            if (params.content.raw.isEmpty()) tertiaryContainer\n                            else secondaryContainer\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.ImageSearch,\n                            contentDescription = null\n                        )\n                    }\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = {\n                    scope.launch {\n                        saveBitmap(it, captureController.bitmap())\n                    }\n                },\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = analyzerImagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        canShowScreenData = true\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        onCancelLoading = component::cancelSaving\n    )\n\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrCodePreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"COMPOSE_APPLIER_CALL_MISMATCH\")\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateIntAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.min\nimport coil3.request.ImageRequest\nimport coil3.size.Precision\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.theme.ProvideTypography\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.theme.takeIf\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.CaptureController\nimport com.t8rin.imagetoolbox.core.ui.utils.capturable.capturable\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.rememberPrevious\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCode\nimport com.t8rin.imagetoolbox.core.utils.appContext\n\n@Composable\ninternal fun QrCodePreview(\n    captureController: CaptureController,\n    isLandscape: Boolean,\n    params: QrPreviewParams,\n    onStartScan: () -> Unit\n) {\n    Box(\n        modifier = Modifier.fillMaxWidth(),\n        contentAlignment = Alignment.Center\n    ) {\n        Column(Modifier.capturable(captureController)) {\n            if (params.imageUri != null) {\n                Spacer(modifier = Modifier.height(32.dp))\n            }\n            BoxWithConstraints(\n                modifier = Modifier\n                    .then(\n                        if ((params.imageUri != null || params.description.isNotEmpty()) && params.content.raw.isNotEmpty()) {\n                            Modifier\n                                .background(\n                                    color = takeColorFromScheme {\n                                        if (isLandscape) {\n                                            surfaceContainerLowest\n                                        } else surfaceContainerLow\n                                    },\n                                    shape = ShapeDefaults.default\n                                )\n                                .padding(16.dp)\n                        } else Modifier\n                    )\n            ) {\n                val targetSize = min(min(this.maxWidth, this.maxHeight), 400.dp)\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    val previous = rememberPrevious(params)\n\n                    AnimatedContent(\n                        targetState = params.content.raw.isEmpty(),\n                        modifier = Modifier\n                            .padding(\n                                top = if (params.imageUri != null) 36.dp else 0.dp,\n                                bottom = if (params.description.isNotEmpty()) 16.dp else 0.dp\n                            )\n                            .then(\n                                if (isLandscape) {\n                                    Modifier\n                                        .weight(1f, false)\n                                        .aspectRatio(1f)\n                                } else Modifier\n                            )\n                    ) { isEmpty ->\n                        if (isEmpty) {\n                            ImageNotPickedWidget(\n                                onPickImage = onStartScan,\n                                text = stringResource(R.string.generated_barcode_will_be_here),\n                                containerColor = MaterialTheme\n                                    .colorScheme\n                                    .surfaceContainerLowest\n                                    .takeIf(isLandscape)\n                            )\n                        } else {\n                            QrCode(\n                                content = params.content.raw,\n                                modifier = Modifier.width(targetSize),\n                                heightRatio = params.heightRatio,\n                                type = params.type,\n                                qrParams = params.qrParams,\n                                cornerRadius = animateIntAsState(params.cornersSize).value.dp,\n                                onSuccess = AppToastHost::dismissToasts,\n                                onFailure = {\n                                    AppToastHost.dismissToasts()\n                                    if (previous != params) AppToastHost.showFailureToast(it)\n                                }\n                            )\n                        }\n                    }\n\n                    BoxAnimatedVisibility(visible = params.description.isNotEmpty() && params.content.raw.isNotEmpty()) {\n                        ProvideTypography(params.descriptionFont) {\n                            Text(\n                                text = params.description,\n                                style = MaterialTheme.typography.headlineSmall,\n                                textAlign = TextAlign.Center,\n                                modifier = Modifier.width(targetSize)\n                            )\n                        }\n                    }\n                }\n\n                if (params.imageUri != null && params.content.raw.isNotEmpty()) {\n                    Picture(\n                        modifier = Modifier\n                            .align(Alignment.TopCenter)\n                            .offset(y = (-48).dp)\n                            .size(64.dp),\n                        model = remember(params.imageUri) {\n                            ImageRequest.Builder(appContext)\n                                .data(params.imageUri)\n                                .size(1000, 1000)\n                                .precision(Precision.INEXACT)\n                                .build()\n                        },\n                        contentScale = ContentScale.Crop,\n                        filterQuality = FilterQuality.High,\n                        contentDescription = null,\n                        shape = MaterialTheme.shapes.medium\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport android.content.Intent\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.StickyNote2\nimport androidx.compose.material.icons.automirrored.rounded.ShortText\nimport androidx.compose.material.icons.outlined.Badge\nimport androidx.compose.material.icons.outlined.Business\nimport androidx.compose.material.icons.outlined.Description\nimport androidx.compose.material.icons.outlined.Event\nimport androidx.compose.material.icons.outlined.Flag\nimport androidx.compose.material.icons.outlined.Home\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.outlined.Link\nimport androidx.compose.material.icons.outlined.Person\nimport androidx.compose.material.icons.outlined.Phone\nimport androidx.compose.material.icons.outlined.Place\nimport androidx.compose.material.icons.outlined.RecordVoiceOver\nimport androidx.compose.material.icons.outlined.Start\nimport androidx.compose.material.icons.outlined.Topic\nimport androidx.compose.material.icons.rounded.AlternateEmail\nimport androidx.compose.material.icons.rounded.Numbers\nimport androidx.compose.material.icons.rounded.Password\nimport androidx.compose.material.icons.rounded.Public\nimport androidx.compose.material.icons.rounded.Security\nimport androidx.compose.material.icons.rounded.TextFields\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.model.QrType.Wifi.EncryptionType\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Latitude\nimport com.t8rin.imagetoolbox.core.resources.icons.Longitude\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport java.text.DateFormat\n\ninternal data class InfoEntry(\n    val icon: ImageVector,\n    val text: String,\n    val canCopy: Boolean,\n)\n\ninternal data class QrInfo(\n    val title: String,\n    val icon: ImageVector,\n    val intent: Intent?,\n    val data: List<InfoEntry>,\n) {\n    companion object\n}\n\n@Composable\ninternal fun rememberQrInfo(qrType: QrType.Complex): QrInfo {\n    return when (qrType) {\n        is QrType.Wifi -> wifiQrInfo(qrType)\n        is QrType.Email -> emailQrInfo(qrType)\n        is QrType.Geo -> geoQrInfo(qrType)\n        is QrType.Phone -> phoneQrInfo(qrType)\n        is QrType.Sms -> smsQrInfo(qrType)\n        is QrType.Contact -> contactQrInfo(qrType)\n        is QrType.Calendar -> calendarQrInfo(qrType)\n    }\n}\n\n@Composable\nprivate fun calendarQrInfo(\n    qrType: QrType.Calendar\n): QrInfo = qrInfoBuilder(qrType) {\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Event,\n            text = qrType.summary.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.summary.isNotBlank()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Description,\n            text = qrType.description.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.description.isNotBlank()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Place,\n            text = qrType.location.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.location.isNotBlank()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Person,\n            text = qrType.organizer.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.organizer.isNotBlank()\n        )\n    )\n    val start = runCatching {\n        qrType.start?.let {\n            DateFormat.getDateTimeInstance().format(it)\n        }?.removeSuffix(\":00\")\n    }.getOrNull().orEmpty()\n\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Start,\n            text = start.ifBlank { getString(R.string.not_specified) },\n            canCopy = start.isNotBlank()\n        )\n    )\n\n    val end = runCatching {\n        qrType.end?.let {\n            DateFormat.getDateTimeInstance().format(it)\n        }?.removeSuffix(\":00\")\n    }.getOrNull().orEmpty()\n\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Flag,\n            text = end.ifBlank { getString(R.string.not_specified) },\n            canCopy = end.isNotBlank()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Info,\n            text = qrType.status.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.status.isNotBlank()\n        )\n    )\n}\n\n@Composable\nprivate fun contactQrInfo(\n    qrType: QrType.Contact\n): QrInfo = qrInfoBuilder(qrType) {\n    val formattedName = qrType.name.formattedName.replace(\"\\\\\", \"\")\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Person,\n            text = formattedName.ifBlank { getString(R.string.not_specified) },\n            canCopy = formattedName.isNotBlank()\n        )\n    )\n    if (qrType.name.pronunciation.isNotBlank()) {\n        entry(\n            InfoEntry(\n                icon = Icons.Outlined.RecordVoiceOver,\n                text = qrType.name.pronunciation,\n                canCopy = true\n            )\n        )\n    }\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Business,\n            text = qrType.organization.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.organization.isNotBlank()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Badge,\n            text = qrType.title.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.title.isNotBlank()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Phone,\n            text = qrType.phones.joinToString(\"\\n\") { it.number }\n                .ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.phones.isNotEmpty()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Rounded.AlternateEmail,\n            text = qrType.emails.joinToString(\"\\n\") { it.address }\n                .ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.emails.isNotEmpty()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Link,\n            text = qrType.urls.joinToString(\"\\n\")\n                .ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.urls.isNotEmpty()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Home,\n            text = qrType.addresses.joinToString(\"\\n\") { it.addressLines.joinToString(\" \") }\n                .ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.addresses.isNotEmpty()\n        )\n    )\n}\n\n@Composable\nprivate fun smsQrInfo(\n    qrType: QrType.Sms\n): QrInfo = qrInfoBuilder(qrType) {\n    entry(\n        InfoEntry(\n            icon = Icons.AutoMirrored.Outlined.StickyNote2,\n            text = qrType.message.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.message.isNotBlank()\n        )\n    )\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Phone,\n            text = qrType.phoneNumber.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.phoneNumber.isNotBlank()\n        )\n    )\n}\n\n@Composable\nprivate fun phoneQrInfo(\n    qrType: QrType.Phone\n): QrInfo = qrInfoBuilder(qrType) {\n    entry(\n        InfoEntry(\n            icon = Icons.Rounded.Numbers,\n            text = qrType.number.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.number.isNotBlank()\n        )\n    )\n}\n\n@Composable\nprivate fun geoQrInfo(\n    qrType: QrType.Geo\n): QrInfo = qrInfoBuilder(qrType) {\n    val latitude = qrType.latitude?.toString()?.trimTrailingZero().orEmpty()\n    val longitude = qrType.longitude?.toString()?.trimTrailingZero().orEmpty()\n\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Latitude,\n            text = latitude.ifBlank { getString(R.string.not_specified) },\n            canCopy = latitude.isNotBlank()\n        )\n    )\n\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Longitude,\n            text = longitude.ifBlank { getString(R.string.not_specified) },\n            canCopy = longitude.isNotBlank()\n        )\n    )\n}\n\n@Composable\nprivate fun emailQrInfo(\n    qrType: QrType.Email\n): QrInfo = qrInfoBuilder(qrType) {\n    entry(\n        InfoEntry(\n            icon = Icons.Rounded.AlternateEmail,\n            text = qrType.address.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.address.isNotBlank()\n        )\n    )\n\n    entry(\n        InfoEntry(\n            icon = Icons.Outlined.Topic,\n            text = qrType.subject.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.subject.isNotBlank()\n        )\n    )\n\n    entry(\n        InfoEntry(\n            icon = Icons.AutoMirrored.Rounded.ShortText,\n            text = qrType.body.ifBlank { getString(R.string.not_specified) },\n            canCopy = qrType.body.isNotBlank()\n        )\n    )\n}\n\n@Composable\nprivate fun wifiQrInfo(\n    qrType: QrType.Wifi\n): QrInfo = qrInfoBuilder(qrType) {\n    val ssid = InfoEntry(\n        icon = Icons.Rounded.TextFields,\n        text = qrType.ssid.ifBlank { getString(R.string.not_specified) },\n        canCopy = qrType.ssid.isNotBlank()\n    )\n    when (qrType.encryptionType) {\n        EncryptionType.OPEN -> {\n            entry(\n                InfoEntry(\n                    icon = Icons.Rounded.Public,\n                    text = getString(R.string.open_network),\n                    canCopy = false\n                )\n            )\n            entry(ssid)\n        }\n\n        else -> {\n            entry(\n                InfoEntry(\n                    icon = Icons.Rounded.Security,\n                    text = qrType.encryptionType.toString(),\n                    canCopy = false\n                )\n            )\n            entry(ssid)\n            entry(\n                InfoEntry(\n                    icon = Icons.Rounded.Password,\n                    text = qrType.password.ifBlank { getString(R.string.not_specified) },\n                    canCopy = qrType.password.isNotBlank()\n                )\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrInfoBuilder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport android.content.Intent\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.utils.getString\n\ninternal interface QrInfoBuilderScope {\n    fun title(title: String): QrInfoBuilderScope\n    fun icon(icon: ImageVector): QrInfoBuilderScope\n    fun intent(intent: Intent?): QrInfoBuilderScope\n    fun entry(infoEntry: InfoEntry): QrInfoBuilderScope\n\n    fun build(): QrInfo\n}\n\ninternal operator fun QrInfo.Companion.invoke(\n    builder: QrInfoBuilderScope.() -> Unit\n): QrInfo = QrInfoBuilderScopeImpl().apply(builder).build()\n\n@Composable\ninternal fun qrInfoBuilder(\n    qrType: QrType,\n    builder: QrInfoBuilderScope.() -> Unit\n): QrInfo = remember(qrType) {\n    derivedStateOf {\n        QrInfo {\n            title(getString(qrType.name))\n            icon(qrType.icon)\n\n            if (qrType is QrType.Complex) intent(qrType.toIntent())\n\n            builder()\n        }\n    }\n}.value\n\nprivate class QrInfoBuilderScopeImpl : QrInfoBuilderScope {\n    private var title: String? = null\n    private var icon: ImageVector? = null\n    private var intent: Intent? = null\n    private var data: List<InfoEntry> = emptyList()\n\n    override fun title(title: String) = apply {\n        this.title = title\n    }\n\n    override fun icon(icon: ImageVector) = apply {\n        this.icon = icon\n    }\n\n    override fun intent(intent: Intent?) = apply {\n        this.intent = intent\n    }\n\n    override fun entry(infoEntry: InfoEntry) = apply {\n        data += infoEntry\n    }\n\n    override fun build(): QrInfo = QrInfo(\n        title = requireNotNull(title),\n        icon = requireNotNull(icon),\n        intent = intent,\n        data = data\n    )\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CutCornerShape\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Code\nimport androidx.compose.material.icons.outlined.DarkMode\nimport androidx.compose.material.icons.outlined.LightMode\nimport androidx.compose.material.icons.outlined.Padding\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectLarge\nimport androidx.compose.material.icons.outlined.RoundedCorner\nimport androidx.compose.material.icons.rounded.Circle\nimport androidx.compose.material.icons.rounded.RoundedCorner\nimport androidx.compose.material.icons.rounded.Shuffle\nimport androidx.compose.material.icons.rounded.TableRows\nimport androidx.compose.material.icons.rounded.ViewColumn\nimport androidx.compose.material.icons.sharp.Square\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.rotate\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.TopLeft\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams.BallShape\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams.ErrorCorrectionLevel\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams.FrameShape\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams.FrameShape.Corners.CornerSide\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams.MaskPattern\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams.PixelShape\nimport com.t8rin.imagetoolbox.core.ui.widget.other.defaultQrColors\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun QrParamsSelector(\n    isQrType: Boolean,\n    value: QrCodeParams,\n    onValueChange: (QrCodeParams) -> Unit\n) {\n    Column(\n        modifier = Modifier\n            .container(\n                shape = ShapeDefaults.large,\n                resultPadding = 12.dp\n            ),\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        TitleItem(\n            text = stringResource(R.string.code_customization),\n            icon = Icons.Outlined.Code,\n            modifier = Modifier.padding(bottom = 8.dp)\n        )\n        Column(\n            verticalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            val (bg, fg) = defaultQrColors()\n\n            ColorRowSelector(\n                value = value.foregroundColor ?: fg,\n                onValueChange = {\n                    onValueChange(\n                        value.copy(\n                            foregroundColor = it\n                        )\n                    )\n                },\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .container(\n                        color = MaterialTheme.colorScheme.surface,\n                        shape = ShapeDefaults.top\n                    ),\n                title = stringResource(R.string.dark_color),\n                icon = Icons.Outlined.DarkMode\n            )\n            ColorRowSelector(\n                value = value.backgroundColor ?: bg,\n                onValueChange = {\n                    onValueChange(\n                        value.copy(\n                            backgroundColor = it\n                        )\n                    )\n                },\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .container(\n                        color = MaterialTheme.colorScheme.surface,\n                        shape = ShapeDefaults.bottom\n                    ),\n                title = stringResource(R.string.light_color),\n                icon = Icons.Outlined.LightMode\n            )\n        }\n        AnimatedVisibility(\n            visible = isQrType,\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            Column(\n                modifier = Modifier.fillMaxWidth(),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    val logoParamsSize = 4\n                    Row(\n                        modifier = Modifier.height(intrinsicSize = IntrinsicSize.Max)\n                    ) {\n                        ImageSelector(\n                            value = value.logo,\n                            title = stringResource(R.string.logo),\n                            subtitle = stringResource(R.string.qr_logo_image),\n                            onValueChange = {\n                                onValueChange(\n                                    value.copy(\n                                        logo = it\n                                    )\n                                )\n                            },\n                            modifier = Modifier\n                                .fillMaxHeight()\n                                .weight(1f),\n                            shape = if (value.logo == null) {\n                                ShapeDefaults.default\n                            } else {\n                                ShapeDefaults.topStart\n                            },\n                            color = MaterialTheme.colorScheme.surface\n                        )\n\n                        BoxAnimatedVisibility(visible = value.logo != null) {\n                            val interactionSource = remember { MutableInteractionSource() }\n\n                            Box(\n                                modifier = Modifier\n                                    .fillMaxHeight()\n                                    .padding(start = 4.dp)\n                                    .container(\n                                        color = MaterialTheme.colorScheme.errorContainer,\n                                        resultPadding = 0.dp,\n                                        shape = shapeByInteraction(\n                                            shape = ShapeDefaults.topEnd,\n                                            pressedShape = ShapeDefaults.pressed,\n                                            interactionSource = interactionSource\n                                        )\n                                    )\n                                    .hapticsClickable(\n                                        interactionSource = interactionSource,\n                                        indication = LocalIndication.current\n                                    ) {\n                                        onValueChange(\n                                            value.copy(\n                                                logo = null\n                                            )\n                                        )\n                                    }\n                                    .padding(horizontal = 8.dp),\n                                contentAlignment = Alignment.Center\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Outlined.Delete,\n                                    contentDescription = null,\n                                    tint = MaterialTheme.colorScheme.onErrorContainer\n                                )\n                            }\n                        }\n                    }\n                    BoxAnimatedVisibility(\n                        visible = value.logo != null,\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        Column(\n                            verticalArrangement = Arrangement.spacedBy(4.dp)\n                        ) {\n                            var logoPadding by remember {\n                                mutableFloatStateOf(value.logoPadding)\n                            }\n                            EnhancedSliderItem(\n                                value = logoPadding,\n                                title = stringResource(R.string.logo_padding),\n                                valueRange = 0f..1f,\n                                internalStateTransformation = { it.roundToTwoDigits() },\n                                onValueChange = {\n                                    logoPadding = it.roundToTwoDigits()\n\n                                    onValueChange(\n                                        value.copy(\n                                            logoPadding = logoPadding\n                                        )\n                                    )\n                                },\n                                containerColor = MaterialTheme.colorScheme.surface,\n                                icon = Icons.Outlined.Padding,\n                                shape = ShapeDefaults.byIndex(\n                                    index = 1,\n                                    size = logoParamsSize\n                                )\n                            )\n                            var logoSize by remember {\n                                mutableFloatStateOf(value.logoSize)\n                            }\n                            EnhancedSliderItem(\n                                value = logoSize,\n                                title = stringResource(R.string.logo_size),\n                                valueRange = 0f..1f,\n                                internalStateTransformation = { it.roundToTwoDigits() },\n                                onValueChange = {\n                                    logoSize = it.roundToTwoDigits()\n                                    onValueChange(\n                                        value.copy(\n                                            logoSize = logoSize\n                                        )\n                                    )\n                                },\n                                icon = Icons.Outlined.PhotoSizeSelectLarge,\n                                containerColor = MaterialTheme.colorScheme.surface,\n                                shape = ShapeDefaults.byIndex(\n                                    index = 2,\n                                    size = logoParamsSize\n                                )\n                            )\n                            var logoCorners by remember {\n                                mutableFloatStateOf(value.logoCorners)\n                            }\n                            EnhancedSliderItem(\n                                value = logoCorners,\n                                title = stringResource(R.string.logo_corners),\n                                valueRange = 0f..1f,\n                                internalStateTransformation = { it.roundToTwoDigits() },\n                                onValueChange = {\n                                    logoCorners = it.roundToTwoDigits()\n                                    onValueChange(\n                                        value.copy(\n                                            logoCorners = logoCorners\n                                        )\n                                    )\n                                },\n                                icon = Icons.Outlined.RoundedCorner,\n                                containerColor = MaterialTheme.colorScheme.surface,\n                                shape = ShapeDefaults.byIndex(\n                                    index = 3,\n                                    size = logoParamsSize\n                                )\n                            )\n                        }\n                    }\n                }\n                EnhancedButtonGroup(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.default,\n                            color = MaterialTheme.colorScheme.surface\n                        ),\n                    entries = PixelShape.entries,\n                    value = value.pixelShape,\n                    itemContent = { it.Content() },\n                    onValueChange = {\n                        onValueChange(\n                            value.copy(\n                                pixelShape = it\n                            )\n                        )\n                    },\n                    title = stringResource(R.string.pixel_shape),\n                    inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n                    activeButtonColor = MaterialTheme.colorScheme.primary\n                )\n                val frameShape = value.frameShape\n\n                val frameShapes by remember(frameShape) {\n                    derivedStateOf {\n                        FrameShape.entries.map {\n                            if (it is FrameShape.Corners && frameShape is FrameShape.Corners) {\n                                it.copy(\n                                    sides = frameShape.sides\n                                )\n                            } else it\n                        }\n                    }\n                }\n                EnhancedButtonGroup(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.default,\n                            color = MaterialTheme.colorScheme.surface\n                        ),\n                    entries = frameShapes,\n                    value = value.frameShape,\n                    itemContent = { it.Content() },\n                    onValueChange = {\n                        onValueChange(\n                            value.copy(\n                                frameShape = if (it is FrameShape.Corners && it.percent <= 0f) {\n                                    it.copy(sides = CornerSide.entries)\n                                } else it\n                            )\n                        )\n                    },\n                    title = stringResource(R.string.frame_shape),\n                    inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n                    activeButtonColor = MaterialTheme.colorScheme.primary\n                )\n\n                AnimatedVisibility(\n                    visible = frameShape is FrameShape.Corners && frameShape.percent > 0f,\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    val shape = frameShape.safeCast<FrameShape.Corners>()\n\n                    EnhancedButtonGroup(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .container(\n                                shape = ShapeDefaults.default,\n                                color = MaterialTheme.colorScheme.surface\n                            ),\n                        entries = CornerSide.entries,\n                        values = shape?.sides ?: emptyList(),\n                        itemContent = { it.Content() },\n                        onValueChange = {\n                            shape?.apply {\n                                val newCorners = shape.sides.toggle(it)\n\n                                if (newCorners.isNotEmpty()) {\n                                    onValueChange(\n                                        value.copy(\n                                            frameShape = shape.copy(\n                                                sides = newCorners\n                                            )\n                                        )\n                                    )\n                                }\n                            }\n                        },\n                        title = stringResource(R.string.corners),\n                        inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n                        activeButtonColor = MaterialTheme.colorScheme.tertiaryContainer\n                    )\n                }\n                EnhancedButtonGroup(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.default,\n                            color = MaterialTheme.colorScheme.surface\n                        ),\n                    entries = BallShape.entries,\n                    value = value.ballShape,\n                    itemContent = { it.Content() },\n                    onValueChange = {\n                        onValueChange(\n                            value.copy(\n                                ballShape = it\n                            )\n                        )\n                    },\n                    title = stringResource(R.string.ball_shape),\n                    inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n                    activeButtonColor = MaterialTheme.colorScheme.primary\n                )\n                EnhancedButtonGroup(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.default,\n                            color = MaterialTheme.colorScheme.surface\n                        ),\n                    entries = ErrorCorrectionLevel.entries,\n                    value = value.errorCorrectionLevel,\n                    itemContent = {\n                        Text(\n                            text = when (it) {\n                                ErrorCorrectionLevel.Auto -> stringResource(R.string.auto)\n                                else -> it.name\n                            }\n                        )\n                    },\n                    onValueChange = {\n                        onValueChange(\n                            value.copy(\n                                errorCorrectionLevel = it\n                            )\n                        )\n                    },\n                    title = stringResource(R.string.error_correction_level),\n                    inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n                    activeButtonColor = MaterialTheme.colorScheme.secondaryContainer\n                )\n                EnhancedButtonGroup(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = ShapeDefaults.default,\n                            color = MaterialTheme.colorScheme.surface\n                        ),\n                    entries = MaskPattern.entries,\n                    value = value.maskPattern,\n                    itemContent = {\n                        Text(\n                            text = when (it) {\n                                MaskPattern.Auto -> stringResource(R.string.auto)\n                                else -> it.name.removePrefix(\"P_\")\n                            }\n                        )\n                    },\n                    onValueChange = {\n                        onValueChange(\n                            value.copy(\n                                maskPattern = it\n                            )\n                        )\n                    },\n                    title = stringResource(R.string.mask_pattern),\n                    inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n                    activeButtonColor = MaterialTheme.colorScheme.secondaryContainer\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun CornerSide.Content() {\n    Icon(\n        imageVector = Icons.Outlined.TopLeft,\n        contentDescription = null,\n        modifier = Modifier\n            .size(24.dp)\n            .rotate(90f * ordinal)\n    )\n}\n\n@Composable\nprivate fun PixelShape.Content() {\n    when (this) {\n        is PixelShape.Predefined -> {\n            Icon(\n                imageVector = when (this) {\n                    PixelShape.Square -> Icons.Sharp.Square\n                    PixelShape.RoundSquare -> Icons.Rounded.RoundedCorner\n                    PixelShape.Circle -> Icons.Rounded.Circle\n                    PixelShape.Vertical -> Icons.Rounded.ViewColumn\n                    PixelShape.Horizontal -> Icons.Rounded.TableRows\n                },\n                contentDescription = null,\n                modifier = Modifier.size(24.dp)\n            )\n        }\n\n        is PixelShape.Random -> {\n            Icon(\n                imageVector = Icons.Rounded.Shuffle,\n                contentDescription = null,\n                modifier = Modifier.size(24.dp)\n            )\n        }\n\n        is PixelShape.Shaped -> {\n            Spacer(\n                modifier = Modifier\n                    .size(20.dp)\n                    .background(\n                        color = LocalContentColor.current,\n                        shape = shape,\n                    )\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun FrameShape.Content() {\n    when (this) {\n        is FrameShape.Corners -> {\n            val percent = (percent * 100).roundToInt()\n            Spacer(\n                modifier = Modifier\n                    .size(20.dp)\n                    .border(\n                        width = 2.dp,\n                        color = LocalContentColor.current,\n                        shape = if (isCut) {\n                            CutCornerShape(\n                                topStartPercent = if (topLeft) percent else 0,\n                                topEndPercent = if (topRight) percent else 0,\n                                bottomStartPercent = if (bottomLeft) percent else 0,\n                                bottomEndPercent = if (bottomRight) percent else 0\n                            )\n                        } else {\n                            RoundedCornerShape(\n                                topStartPercent = if (topLeft) percent else 0,\n                                topEndPercent = if (topRight) percent else 0,\n                                bottomStartPercent = if (bottomLeft) percent else 0,\n                                bottomEndPercent = if (bottomRight) percent else 0\n                            )\n                        }\n                    )\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun BallShape.Content() {\n    when (this) {\n        is BallShape.Predefined -> {\n            Icon(\n                imageVector = when (this) {\n                    BallShape.Square -> Icons.Sharp.Square\n                    BallShape.Circle -> Icons.Rounded.Circle\n                },\n                contentDescription = null,\n                modifier = Modifier.size(24.dp)\n            )\n        }\n\n        is BallShape.Shaped -> {\n            Spacer(\n                modifier = Modifier\n                    .size(20.dp)\n                    .background(\n                        color = LocalContentColor.current,\n                        shape = shape,\n                    )\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrPreviewParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport android.net.Uri\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BarcodeType\nimport com.t8rin.imagetoolbox.core.ui.widget.other.QrCodeParams\n\ndata class QrPreviewParams(\n    val imageUri: Uri?,\n    val description: String,\n    val content: QrType,\n    val cornersSize: Int,\n    val descriptionFont: UiFontFamily,\n    val heightRatio: Float,\n    val type: BarcodeType,\n    val qrParams: QrCodeParams,\n) {\n    companion object {\n        val Default by lazy {\n            QrPreviewParams(\n                imageUri = null,\n                description = \"\",\n                content = QrType.Empty,\n                cornersSize = 4,\n                descriptionFont = UiFontFamily.System,\n                heightRatio = 2f,\n                type = BarcodeType.QR_CODE,\n                qrParams = QrCodeParams()\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrTypeEditSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.QrCode\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.retain.retain\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor.QrEditField\n\n@Composable\ninternal fun QrTypeEditSheet(\n    qrType: QrType.Complex?,\n    onSave: (QrType.Complex) -> Unit,\n    onDismiss: () -> Unit,\n    visible: Boolean\n) {\n    var edited by retain(visible, qrType) {\n        mutableStateOf(qrType ?: QrType.Wifi())\n    }\n\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = { onDismiss() },\n        title = {\n            TitleItem(\n                text = stringResource(\n                    if (qrType == null) R.string.create_barcode\n                    else R.string.edit_barcode\n                ),\n                icon = Icons.Rounded.QrCode\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    onSave(edited.updateRaw())\n                    onDismiss()\n                },\n                containerColor = MaterialTheme.colorScheme.primary,\n                enabled = !edited.isEmpty()\n            ) {\n                Text(stringResource(R.string.save))\n            }\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(16.dp)\n                .clearFocusOnTap(),\n            verticalArrangement = Arrangement.spacedBy(8.dp),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            DataSelector(\n                value = edited,\n                onValueChange = {\n                    edited = if (qrType != null && it::class.isInstance(qrType)) qrType else it\n                },\n                itemEqualityDelegate = { t, o -> t::class.isInstance(o) },\n                entries = QrType.complexEntries,\n                title = null,\n                titleIcon = null,\n                itemContentText = { stringResource(it.name) },\n                itemContentIcon = { item, _ -> item.icon },\n                canExpand = false\n            )\n            QrEditField(\n                value = edited,\n                onValueChange = { edited = it },\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(top = 4.dp)\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrTypeInfoItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport androidx.activity.compose.LocalActivity\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.OpenInNew\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun QrTypeInfoItem(\n    qrType: QrType,\n    modifier: Modifier = Modifier\n) {\n    AnimatedContent(\n        targetState = qrType,\n        transitionSpec = {\n            if (initialState::class.isInstance(targetState)) {\n                fadeIn(tween(150)) togetherWith fadeOut(tween(150))\n            } else if (targetState !is QrType.Complex) {\n                slideInVertically { it } + fadeIn() togetherWith slideOutVertically { -it } + fadeOut()\n            } else {\n                slideInVertically { -it } + fadeIn() togetherWith slideOutVertically { it } + fadeOut()\n            }\n        },\n        modifier = Modifier.fillMaxWidth()\n    ) { type ->\n        when (type) {\n            is QrType.Complex -> {\n                QrInfoItem(\n                    qrInfo = rememberQrInfo(type),\n                    modifier = modifier\n                )\n            }\n\n            else -> Spacer(Modifier.fillMaxWidth())\n        }\n    }\n}\n\n@Composable\nprivate fun QrInfoItem(\n    qrInfo: QrInfo,\n    modifier: Modifier,\n) {\n    if (qrInfo.data.isEmpty()) return\n\n    val activity = LocalActivity.current\n\n    Column(\n        modifier = Modifier\n            .then(modifier)\n            .container(\n                shape = ShapeDefaults.large,\n                resultPadding = 0.dp\n            )\n            .padding(8.dp)\n    ) {\n        TitleItem(\n            text = qrInfo.title,\n            icon = qrInfo.icon,\n            modifier = Modifier.padding(8.dp),\n            endContent = {\n                qrInfo.intent?.let {\n                    EnhancedIconButton(\n                        modifier = Modifier.size(32.dp),\n                        onClick = {\n                            runCatching {\n                                activity?.startActivity(qrInfo.intent)\n                            }.onFailure(AppToastHost::showFailureToast)\n                        }\n                    ) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Rounded.OpenInNew,\n                            contentDescription = \"open\",\n                            modifier = Modifier.size(20.dp)\n                        )\n                    }\n                }\n            }\n        )\n        Spacer(modifier = Modifier.padding(4.dp))\n        Column(\n            verticalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            qrInfo.data.forEachIndexed { index, (icon, text, canCopy) ->\n                val interactionSource = remember(index) { MutableInteractionSource() }\n\n                val shape = shapeByInteraction(\n                    shape = ShapeDefaults.byIndex(\n                        index = index,\n                        size = qrInfo.data.size\n                    ),\n                    pressedShape = ShapeDefaults.pressed,\n                    interactionSource = interactionSource\n                )\n\n                Row(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .container(\n                            shape = shape,\n                            color = MaterialTheme.colorScheme.surface,\n                            resultPadding = 0.dp\n                        )\n                        .hapticsClickable(\n                            enabled = canCopy,\n                            onClick = { Clipboard.copy(text) },\n                            interactionSource = interactionSource,\n                            indication = LocalIndication.current\n                        )\n                        .padding(\n                            vertical = 10.dp,\n                            horizontal = 12.dp\n                        ),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Icon(\n                        imageVector = icon,\n                        contentDescription = null,\n                        tint = MaterialTheme.colorScheme.onSurface\n                    )\n                    Spacer(Modifier.width(8.dp))\n                    Text(\n                        text = text,\n                        color = MaterialTheme.colorScheme.onSurface,\n                        modifier = Modifier.weight(1f)\n                    )\n                    if (canCopy) {\n                        Spacer(Modifier.width(16.dp))\n                        Icon(\n                            imageVector = Icons.Rounded.ContentCopy,\n                            contentDescription = null,\n                            tint = MaterialTheme.colorScheme.onSurface.copy(0.5f),\n                            modifier = Modifier.size(18.dp)\n                        )\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/QrTypeUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport android.content.ContentValues\nimport android.content.Intent\nimport android.provider.CalendarContract\nimport android.provider.ContactsContract\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CalendarMonth\nimport androidx.compose.material.icons.rounded.Contacts\nimport androidx.compose.material.icons.rounded.Email\nimport androidx.compose.material.icons.rounded.Link\nimport androidx.compose.material.icons.rounded.LocationOn\nimport androidx.compose.material.icons.rounded.Phone\nimport androidx.compose.material.icons.rounded.Sms\nimport androidx.compose.material.icons.rounded.TextFields\nimport androidx.compose.material.icons.rounded.Wifi\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.model.copy\nimport com.t8rin.imagetoolbox.core.domain.model.ifNotEmpty\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Contact\nimport ezvcard.Ezvcard\nimport ezvcard.VCard\nimport ezvcard.parameter.EmailType\nimport ezvcard.parameter.TelephoneType\nimport ezvcard.property.FormattedName\nimport ezvcard.property.Organization\nimport ezvcard.property.RawProperty\nimport ezvcard.property.StructuredName\nimport ezvcard.property.Telephone\nimport ezvcard.property.Title\nimport io.github.g00fy2.quickie.extensions.DataType\nimport java.text.SimpleDateFormat\nimport java.util.Date\nimport java.util.Locale\nimport java.util.TimeZone\n\ninternal val QrType.name: Int\n    get() = when (this) {\n        is QrType.Calendar -> R.string.qr_type_calendar_event\n        is QrType.Contact -> R.string.qr_type_contact_info\n        is QrType.Email -> R.string.qr_type_email\n        is QrType.Geo -> R.string.qr_type_geo_point\n        is QrType.Phone -> R.string.qr_type_phone\n        is QrType.Plain -> R.string.qr_type_plain\n        is QrType.Sms -> R.string.qr_type_sms\n        is QrType.Url -> R.string.qr_type_url\n        is QrType.Wifi -> R.string.qr_type_wifi\n    }\n\ninternal val QrType.icon: ImageVector\n    get() = when (this) {\n        is QrType.Calendar -> Icons.Rounded.CalendarMonth\n        is QrType.Contact -> Icons.Rounded.Contacts\n        is QrType.Email -> Icons.Rounded.Email\n        is QrType.Geo -> Icons.Rounded.LocationOn\n        is QrType.Phone -> Icons.Rounded.Phone\n        is QrType.Sms -> Icons.Rounded.Sms\n        is QrType.Wifi -> Icons.Rounded.Wifi\n        is QrType.Plain -> Icons.Rounded.TextFields\n        is QrType.Url -> Icons.Rounded.Link\n    }\n\ninternal fun QrType.toIntent(): Intent? = ifNotEmpty {\n    when (this) {\n        is QrType.Plain -> Intent(Intent.ACTION_SEND).setType(\"text/plain\")\n            .putExtra(Intent.EXTRA_TEXT, raw)\n\n        is QrType.Url -> Intent(Intent.ACTION_VIEW, url.toUri())\n\n        is QrType.Email -> Intent(Intent.ACTION_SENDTO, raw.toUri())\n        is QrType.Phone -> Intent(Intent.ACTION_DIAL, raw.toUri())\n        is QrType.Sms -> {\n            val cleanNumber = phoneNumber.removePrefix(\"smsto:\").removePrefix(\"sms:\")\n\n            return Intent(Intent.ACTION_SENDTO, \"smsto:$cleanNumber\".toUri()).apply {\n                if (message.isNotBlank()) {\n                    putExtra(\"sms_body\", message)\n                }\n            }\n        }\n\n        is QrType.Geo -> Intent(Intent.ACTION_VIEW, raw.toUri())\n\n        is QrType.Wifi -> null\n\n        is QrType.Contact -> {\n            Intent(Intent.ACTION_INSERT).apply {\n                type = ContactsContract.Contacts.CONTENT_TYPE\n                if (organization.isNotBlank()) {\n                    putExtra(ContactsContract.Intents.Insert.COMPANY, organization)\n                }\n                if (title.isNotBlank()) {\n                    putExtra(ContactsContract.Intents.Insert.JOB_TITLE, title)\n                }\n                if (name.pronunciation.isNotBlank()) {\n                    putExtra(ContactsContract.Intents.Insert.PHONETIC_NAME, name.pronunciation)\n                }\n\n                val data = arrayListOf<ContentValues>()\n\n                val nameCv = ContentValues().apply {\n                    put(\n                        ContactsContract.Data.MIMETYPE,\n                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE\n                    )\n                    if (name.first.isNotBlank())\n                        put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name.first)\n                    if (name.middle.isNotBlank())\n                        put(\n                            ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,\n                            name.middle\n                        )\n                    if (name.last.isNotBlank())\n                        put(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, name.last)\n                    if (name.prefix.isNotBlank())\n                        put(ContactsContract.CommonDataKinds.StructuredName.PREFIX, name.prefix)\n                    if (name.suffix.isNotBlank())\n                        put(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, name.suffix)\n                    if (name.formattedName.isNotBlank())\n                        put(\n                            ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,\n                            name.formattedName\n                        )\n                }\n                data.add(nameCv)\n\n                phones.forEach { phone ->\n                    val cv = ContentValues()\n                    cv.put(\n                        ContactsContract.Data.MIMETYPE,\n                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE\n                    )\n                    cv.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone.number)\n                    cv.put(\n                        ContactsContract.CommonDataKinds.Phone.TYPE,\n                        when (phone.type) {\n                            DataType.TYPE_HOME -> ContactsContract.CommonDataKinds.Phone.TYPE_HOME\n                            DataType.TYPE_WORK -> ContactsContract.CommonDataKinds.Phone.TYPE_WORK\n                            DataType.TYPE_FAX -> ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK\n                            DataType.TYPE_MOBILE -> ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE\n                            else -> ContactsContract.CommonDataKinds.Phone.TYPE_OTHER\n                        }\n                    )\n                    data.add(cv)\n                }\n\n                emails.forEach { email ->\n                    val cv = ContentValues()\n                    cv.put(\n                        ContactsContract.Data.MIMETYPE,\n                        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE\n                    )\n                    cv.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email.address)\n                    cv.put(\n                        ContactsContract.CommonDataKinds.Email.TYPE,\n                        when (email.type) {\n                            DataType.TYPE_HOME -> ContactsContract.CommonDataKinds.Email.TYPE_HOME\n                            DataType.TYPE_WORK -> ContactsContract.CommonDataKinds.Email.TYPE_WORK\n                            else -> ContactsContract.CommonDataKinds.Email.TYPE_OTHER\n                        }\n                    )\n                    data.add(cv)\n                }\n\n                addresses.forEach { addr ->\n                    val cv = ContentValues().apply {\n                        put(\n                            ContactsContract.Data.MIMETYPE,\n                            ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE\n                        )\n                        put(\n                            ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS,\n                            addr.addressLines.joinToString(\" \")\n                        )\n                        put(\n                            ContactsContract.CommonDataKinds.StructuredPostal.TYPE,\n                            when (addr.type) {\n                                DataType.TYPE_HOME -> ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME\n                                DataType.TYPE_WORK -> ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK\n                                else -> ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER\n                            }\n                        )\n                    }\n                    data.add(cv)\n                }\n\n                urls.forEach { url ->\n                    val cv = ContentValues().apply {\n                        put(\n                            ContactsContract.Data.MIMETYPE,\n                            ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE\n                        )\n                        put(ContactsContract.CommonDataKinds.Website.URL, url)\n                        put(\n                            ContactsContract.CommonDataKinds.Website.TYPE,\n                            ContactsContract.CommonDataKinds.Website.TYPE_OTHER\n                        )\n                    }\n                    data.add(cv)\n                }\n\n                putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, data)\n            }\n        }\n\n        is QrType.Calendar -> {\n            Intent(Intent.ACTION_INSERT).apply {\n                data = CalendarContract.Events.CONTENT_URI\n                putExtra(CalendarContract.Events.TITLE, summary)\n                putExtra(CalendarContract.Events.DESCRIPTION, description)\n                putExtra(CalendarContract.Events.EVENT_LOCATION, location)\n                putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, start?.time)\n                putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end?.time)\n            }\n        }\n    }?.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n}\n\ninternal fun QrType.Complex.createRaw(): String = runCatching {\n    when (this) {\n        is QrType.Wifi -> buildString {\n            append(\"WIFI:\")\n            append(\"S:\").append(ssid).append(\";\")\n            if (encryptionType != QrType.Wifi.EncryptionType.OPEN) {\n                append(\"T:\").append(encryptionType.name).append(\";\")\n                append(\"P:\").append(password).append(\";\")\n            }\n            append(\";\")\n        }\n\n        is QrType.Sms -> buildString {\n            append(\"SMSTO:\").append(phoneNumber).append(\":\").append(message)\n        }\n\n        is QrType.Geo -> buildString {\n            if (latitude != null && longitude != null) {\n                append(\"geo:\").append(latitude).append(\",\").append(longitude)\n            }\n        }\n\n        is QrType.Email -> buildString {\n            append(\"MATMSG:TO:\").append(address).append(\";\")\n            append(\"SUB:\").append(subject).append(\";\")\n            append(\"BODY:\").append(body).append(\";;\")\n        }\n\n        is QrType.Phone -> \"tel:$number\"\n\n        is QrType.Contact -> {\n            val vcard = VCard()\n\n            val structuredName = StructuredName().apply {\n                given = name.first\n                family = name.last\n                additionalNames.add(name.middle)\n                prefixes.add(name.prefix)\n                suffixes.add(name.suffix)\n            }\n\n            if (name.pronunciation.isNotBlank()) {\n                vcard.addProperty(RawProperty(\"X-PHONETIC-FIRST-NAME\", name.pronunciation))\n                vcard.addProperty(RawProperty(\"X-PHONETIC-LAST-NAME\", name.pronunciation))\n                vcard.addProperty(RawProperty(\"X-PHONETIC-MIDDLE-NAME\", name.pronunciation))\n            }\n\n            vcard.formattedName = FormattedName(name.formattedName)\n            vcard.structuredName = structuredName\n\n            vcard.organization = Organization().apply { values.add(organization) }\n            vcard.titles.add(Title(title))\n\n            phones.forEach {\n                vcard.telephoneNumbers.add(\n                    Telephone(it.number).apply {\n                        types.add(mapPhoneType(it.type))\n                    }\n                )\n            }\n\n            emails.forEach {\n                vcard.emails.add(\n                    ezvcard.property.Email(it.address).apply {\n                        types.add(mapEmailType(it.type))\n                    }\n                )\n            }\n\n            addresses.forEach {\n                vcard.addresses.add(\n                    ezvcard.property.Address().apply {\n                        streetAddress = it.addressLines.joinToString(\", \")\n                        types.add(mapAddressType(it.type))\n                    }\n                )\n            }\n\n            urls.forEach {\n                vcard.urls.add(ezvcard.property.Url(it))\n            }\n\n            Ezvcard.write(vcard).go()\n        }\n\n        is QrType.Calendar -> buildString {\n            val dateFormat = SimpleDateFormat(\"yyyyMMdd'T'HHmmss'Z'\", Locale.US).apply {\n                timeZone = TimeZone.getTimeZone(\"UTC\")\n            }\n\n            append(\"BEGIN:VEVENT\\n\")\n            if (summary.isNotBlank()) append(\"SUMMARY:\").append(summary).append(\"\\n\")\n            if (description.isNotBlank()) append(\"DESCRIPTION:\").append(description)\n                .append(\"\\n\")\n            if (location.isNotBlank()) append(\"LOCATION:\").append(location).append(\"\\n\")\n            if (organizer.isNotBlank()) append(\"ORGANIZER:\").append(organizer).append(\"\\n\")\n            if (status.isNotBlank()) append(\"STATUS:\").append(status).append(\"\\n\")\n\n            append(\"DTSTART:\").append(dateFormat.format(start ?: Date())).append(\"\\n\")\n            append(\"DTEND:\").append(dateFormat.format(end ?: Date())).append(\"\\n\")\n            append(\"END:VEVENT\")\n        }\n    }\n}.getOrDefault(raw)\n\ninternal fun QrType.Complex.updateRaw(): QrType.Complex = copy(createRaw().trim())\n\ninternal fun QrType.Contact.updateFormattedName(): QrType.Contact {\n    val formatted = buildString {\n        if (name.prefix.isNotBlank()) append(name.prefix.trim()).append(' ')\n        if (name.first.isNotBlank()) append(name.first.trim()).append(' ')\n        if (name.middle.isNotBlank()) append(name.middle.trim()).append(' ')\n        if (name.last.isNotBlank()) append(name.last.trim()).append(' ')\n        if (name.suffix.isNotBlank()) append(\", ${name.suffix.trim()}\")\n    }.trim()\n\n    return copy(\n        name = name.copy(\n            formattedName = formatted\n        )\n    )\n}\n\ninternal fun Contact.toQrType(raw: String = \"\"): QrType.Contact {\n    return QrType.Contact(\n        raw = raw,\n        addresses = addresses.map {\n            QrType.Contact.Address(\n                addressLines = it.addressLines,\n                type = it.type\n            )\n        },\n        emails = emails.map {\n            QrType.Email(\n                raw = \"\",\n                address = it.address,\n                body = it.body,\n                subject = it.subject,\n                type = it.type\n            )\n        },\n        name = QrType.Contact.PersonName(\n            first = name.first,\n            formattedName = name.formattedName,\n            last = name.last,\n            middle = name.middle,\n            prefix = name.prefix,\n            pronunciation = name.pronunciation,\n            suffix = name.suffix\n        ),\n        organization = organization,\n        phones = phones.map {\n            QrType.Phone(\n                raw = \"\",\n                number = it.number,\n                type = it.type\n            )\n        },\n        title = title,\n        urls = urls\n    )\n}\n\nprivate fun mapPhoneType(type: Int): TelephoneType = when (type) {\n    DataType.TYPE_WORK -> TelephoneType.WORK\n    DataType.TYPE_HOME -> TelephoneType.HOME\n    DataType.TYPE_FAX -> TelephoneType.FAX\n    DataType.TYPE_MOBILE -> TelephoneType.CELL\n    else -> TelephoneType.VOICE\n}\n\nprivate fun mapEmailType(type: Int): EmailType = when (type) {\n    DataType.TYPE_WORK -> EmailType.WORK\n    DataType.TYPE_HOME -> EmailType.HOME\n    else -> EmailType.INTERNET\n}\n\nprivate fun mapAddressType(type: Int): ezvcard.parameter.AddressType = when (type) {\n    DataType.TYPE_WORK -> ezvcard.parameter.AddressType.WORK\n    DataType.TYPE_HOME -> ezvcard.parameter.AddressType.HOME\n    else -> ezvcard.parameter.AddressType.HOME\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/ScanQrCodeControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.RoundedCorner\nimport androidx.compose.material.icons.rounded.QrCode2\nimport androidx.compose.material.icons.rounded.WarningAmber\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.model.copy\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FontSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.shapeByInteraction\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BarcodeType\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.other.LinkPreviewList\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.screenLogic.ScanQrCodeComponent\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun ScanQrCodeControls(component: ScanQrCodeComponent) {\n    val params by rememberUpdatedState(component.params)\n\n    LinkPreviewList(\n        text = params.content.raw,\n        externalLinks = remember(params.content) {\n            (params.content as? QrType.Url)?.let { listOf(it.url) }\n        },\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(bottom = 8.dp)\n    )\n    QrTypeInfoItem(\n        qrType = params.content,\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(bottom = 8.dp)\n    )\n\n    val noContent = params.content.raw.isEmpty()\n\n    val isNotScannable = !noContent && component.mayBeNotScannable\n\n    AnimatedVisibility(\n        visible = isNotScannable,\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        InfoContainer(\n            text = stringResource(R.string.code_may_be_not_scannable),\n            modifier = Modifier.padding(8.dp),\n            containerColor = MaterialTheme.colorScheme.errorContainer.copy(0.4f),\n            contentColor = MaterialTheme.colorScheme.onErrorContainer.copy(0.7f),\n            icon = Icons.Rounded.WarningAmber\n        )\n    }\n\n    Column(\n        modifier = Modifier\n            .container(\n                shape = MaterialTheme.shapes.large,\n                resultPadding = 0.dp\n            )\n    ) {\n        RoundedTextField(\n            modifier = Modifier\n                .padding(\n                    top = 8.dp,\n                    start = 8.dp,\n                    end = 8.dp,\n                    bottom = if (noContent) 4.dp else 6.dp\n                ),\n            shape = animateShape(\n                if (noContent) ShapeDefaults.smallTop else ShapeDefaults.small\n            ),\n            value = params.content.raw,\n            onValueChange = {\n                component.updateParams(\n                    params.copy(\n                        content = params.content.copy(it)\n                    )\n                )\n            },\n            maxSymbols = 2500,\n            singleLine = false,\n            supportingText = if (!noContent) {\n                {\n                    AnimatedContent(\n                        targetState = params.content,\n                        contentKey = { it::class.simpleName },\n                        transitionSpec = { fadeIn() togetherWith fadeOut() }\n                    ) { content ->\n                        Text(\n                            text = stringResource(content.name),\n                            color = MaterialTheme.colorScheme.onMixedContainer,\n                            modifier = Modifier\n                                .background(\n                                    color = MaterialTheme.colorScheme.mixedContainer,\n                                    shape = ShapeDefaults.small\n                                )\n                                .padding(horizontal = 5.dp, vertical = 1.dp)\n                        )\n                    }\n                }\n            } else null,\n            label = {\n                Text(stringResource(id = R.string.code_content))\n            },\n            keyboardOptions = KeyboardOptions()\n        )\n\n        var showEditField by rememberSaveable {\n            mutableStateOf(false)\n        }\n\n        EnhancedButton(\n            onClick = { showEditField = true },\n            shape = if (noContent) ShapeDefaults.smallBottom else ShapeDefaults.small,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(\n                    start = 8.dp,\n                    end = 8.dp,\n                    bottom = 8.dp\n                ),\n            containerColor = MaterialTheme.colorScheme.surfaceContainerHighest\n        ) {\n            Row(\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.MiniEdit,\n                    contentDescription = null\n                )\n                Spacer(Modifier.width(4.dp))\n                Text(\n                    text = stringResource(\n                        if (params.content is QrType.Complex) R.string.edit_barcode else R.string.create_barcode\n                    )\n                )\n            }\n        }\n\n        QrTypeEditSheet(\n            qrType = params.content.safeCast(),\n            onSave = { component.updateParams(params.copy(content = it)) },\n            onDismiss = { showEditField = false },\n            visible = showEditField\n        )\n    }\n    Spacer(modifier = Modifier.height(8.dp))\n    InfoContainer(\n        text = stringResource(R.string.scan_qr_code_to_replace_content),\n        modifier = Modifier.padding(8.dp)\n    )\n    Spacer(modifier = Modifier.height(8.dp))\n\n    AnimatedVisibility(visible = params.content.raw.isNotEmpty()) {\n        Column {\n            DataSelector(\n                value = params.type,\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            type = it\n                        )\n                    )\n                },\n                spanCount = 2,\n                entries = BarcodeType.entries,\n                title = stringResource(R.string.barcode_type),\n                titleIcon = Icons.Rounded.QrCode2,\n                itemContentText = {\n                    remember {\n                        it.name.replace(\"_\", \" \")\n                    }\n                }\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            BoxAnimatedVisibility(\n                visible = !params.type.isSquare || params.type == BarcodeType.DATA_MATRIX,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                EnhancedSliderItem(\n                    value = params.heightRatio,\n                    title = stringResource(R.string.height_ratio),\n                    valueRange = 1f..4f,\n                    onValueChange = {},\n                    onValueChangeFinished = {\n                        component.updateParams(\n                            params.copy(\n                                heightRatio = it\n                            )\n                        )\n                    },\n                    internalStateTransformation = {\n                        it.roundToTwoDigits()\n                    },\n                    modifier = Modifier.padding(bottom = 8.dp)\n                )\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            QrParamsSelector(\n                isQrType = params.type == BarcodeType.QR_CODE,\n                value = params.qrParams,\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            qrParams = it\n                        )\n                    )\n                }\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            Row(\n                modifier = Modifier.height(intrinsicSize = IntrinsicSize.Max)\n            ) {\n                ImageSelector(\n                    value = params.imageUri,\n                    subtitle = stringResource(id = R.string.qr_code_top_image),\n                    onValueChange = {\n                        component.updateParams(\n                            params.copy(\n                                imageUri = it\n                            )\n                        )\n                    },\n                    modifier = Modifier\n                        .fillMaxHeight()\n                        .weight(1f),\n                    shape = ShapeDefaults.extraLarge\n                )\n                BoxAnimatedVisibility(visible = params.imageUri != null) {\n                    val interactionSource = remember { MutableInteractionSource() }\n\n                    Box(\n                        modifier = Modifier\n                            .fillMaxHeight()\n                            .padding(start = 8.dp)\n                            .container(\n                                color = MaterialTheme.colorScheme.errorContainer,\n                                resultPadding = 0.dp,\n                                shape = shapeByInteraction(\n                                    shape = ShapeDefaults.default,\n                                    pressedShape = ShapeDefaults.pressed,\n                                    interactionSource = interactionSource\n                                )\n                            )\n                            .hapticsClickable(\n                                interactionSource = interactionSource,\n                                indication = LocalIndication.current\n                            ) {\n                                component.updateParams(\n                                    params.copy(\n                                        imageUri = null\n                                    )\n                                )\n                            }\n                            .padding(horizontal = 8.dp),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Delete,\n                            contentDescription = null,\n                            tint = MaterialTheme.colorScheme.onErrorContainer\n                        )\n                    }\n                }\n            }\n            Spacer(modifier = Modifier.height(8.dp))\n            RoundedTextField(\n                modifier = Modifier.container(\n                    shape = animateShape(\n                        if (params.description.isNotEmpty()) ShapeDefaults.top\n                        else ShapeDefaults.default\n                    ),\n                    resultPadding = 8.dp\n                ),\n                value = params.description,\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            description = it\n                        )\n                    )\n                },\n                singleLine = false,\n                label = {\n                    Text(stringResource(id = R.string.qr_description))\n                }\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            BoxAnimatedVisibility(\n                visible = params.description.isNotEmpty(),\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                FontSelector(\n                    value = params.descriptionFont,\n                    onValueChange = {\n                        component.updateParams(\n                            params.copy(\n                                descriptionFont = it\n                            )\n                        )\n                    },\n                    containerColor = Color.Unspecified,\n                    shape = ShapeDefaults.bottom,\n                    modifier = Modifier.padding(bottom = 8.dp)\n                )\n            }\n            EnhancedSliderItem(\n                value = params.cornersSize,\n                title = stringResource(R.string.corners),\n                valueRange = 0f..36f,\n                onValueChange = {\n                    component.updateParams(\n                        params.copy(\n                            cornersSize = it.toInt()\n                        )\n                    )\n                },\n                internalStateTransformation = {\n                    it.roundToInt()\n                },\n                icon = Icons.Outlined.RoundedCorner,\n                steps = 22\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrCalendarEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.DateRange\nimport androidx.compose.material.icons.outlined.Description\nimport androidx.compose.material.icons.outlined.Event\nimport androidx.compose.material.icons.outlined.Flag\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.outlined.Person\nimport androidx.compose.material.icons.outlined.Place\nimport androidx.compose.material.icons.outlined.Start\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.rememberDateRangePickerState\nimport androidx.compose.material3.rememberTimePickerState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.TimerEdit\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedDateRangePickerDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTimePickerDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport java.text.DateFormat\nimport java.util.Calendar\nimport java.util.Date\n\n@Composable\ninternal fun QrCalendarEditField(\n    value: QrType.Calendar,\n    onValueChange: (QrType.Calendar) -> Unit\n) {\n    var isDateDialogVisible by rememberSaveable { mutableStateOf(false) }\n    var showStartTimePicker by rememberSaveable { mutableStateOf(false) }\n    var showEndTimePicker by rememberSaveable { mutableStateOf(false) }\n\n    val startDate = remember(value.start) {\n        value.start ?: Date()\n    }\n    val endDate = remember(value.end) {\n        value.end ?: Calendar.getInstance()\n            .apply { add(Calendar.DAY_OF_YEAR, 1) }.time\n    }\n\n    val startCalendar = remember(startDate) {\n        Calendar.getInstance().apply { time = startDate }\n    }\n    val endCalendar = remember(endDate) {\n        Calendar.getInstance().apply { time = endDate }\n    }\n\n    val dateState = rememberDateRangePickerState(\n        initialSelectedStartDateMillis = startDate.time,\n        initialSelectedEndDateMillis = endDate.time\n    )\n    val startTimeState = rememberTimePickerState(\n        initialHour = startCalendar.get(Calendar.HOUR_OF_DAY),\n        initialMinute = startCalendar.get(Calendar.MINUTE)\n    )\n    val endTimeState = rememberTimePickerState(\n        initialHour = endCalendar.get(Calendar.HOUR_OF_DAY),\n        initialMinute = endCalendar.get(Calendar.MINUTE)\n    )\n\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        RoundedTextField(\n            value = value.summary,\n            onValueChange = { onValueChange(value.copy(summary = it)) },\n            label = { Text(stringResource(R.string.summary)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Event,\n                    contentDescription = null\n                )\n            }\n        )\n\n        RoundedTextField(\n            value = value.description,\n            onValueChange = { onValueChange(value.copy(description = it)) },\n            label = { Text(stringResource(R.string.description)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Description,\n                    contentDescription = null\n                )\n            },\n            singleLine = false\n        )\n\n        RoundedTextField(\n            value = value.location,\n            onValueChange = { onValueChange(value.copy(location = it)) },\n            label = { Text(stringResource(R.string.location)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Place,\n                    contentDescription = null\n                )\n            }\n        )\n\n        RoundedTextField(\n            value = value.organizer,\n            onValueChange = { onValueChange(value.copy(organizer = it)) },\n            label = { Text(stringResource(R.string.organizer)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Person,\n                    contentDescription = null\n                )\n            }\n        )\n\n        val startText = remember(startDate) {\n            runCatching {\n                DateFormat.getDateTimeInstance().format(startDate).removeSuffix(\":00\")\n            }.getOrDefault(\"\")\n        }\n\n        val endText = remember(endDate) {\n            runCatching {\n                DateFormat.getDateTimeInstance().format(endDate).removeSuffix(\":00\")\n            }.getOrDefault(\"\")\n        }\n\n        Row(\n            modifier = Modifier\n                .fillMaxWidth()\n                .height(IntrinsicSize.Max),\n            horizontalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            Column(\n                modifier = Modifier\n                    .fillMaxHeight()\n                    .weight(1f),\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                Row(\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    modifier = Modifier.weight(1f)\n                ) {\n                    RoundedTextField(\n                        modifier = Modifier.weight(1f),\n                        value = startText,\n                        onValueChange = {},\n                        readOnly = true,\n                        label = { Text(stringResource(R.string.start_date)) },\n                        startIcon = {\n                            Icon(\n                                imageVector = Icons.Outlined.Start,\n                                contentDescription = null\n                            )\n                        },\n                        shape = ShapeDefaults.smallStart\n                    )\n                    EnhancedIconButton(\n                        onClick = {\n                            showStartTimePicker = true\n                        },\n                        modifier = Modifier.fillMaxHeight(),\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        forceMinimumInteractiveComponentSize = false,\n                        shape = ShapeDefaults.smallEnd\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.TimerEdit,\n                            contentDescription = null\n                        )\n                    }\n                }\n                Row(\n                    horizontalArrangement = Arrangement.spacedBy(4.dp),\n                    modifier = Modifier.weight(1f)\n                ) {\n                    RoundedTextField(\n                        modifier = Modifier.weight(1f),\n                        value = endText,\n                        onValueChange = {},\n                        readOnly = true,\n                        label = { Text(stringResource(R.string.end_date)) },\n                        startIcon = {\n                            Icon(\n                                imageVector = Icons.Outlined.Flag,\n                                contentDescription = null\n                            )\n                        },\n                        shape = ShapeDefaults.smallStart\n                    )\n                    EnhancedIconButton(\n                        onClick = {\n                            showEndTimePicker = true\n                        },\n                        modifier = Modifier.fillMaxHeight(),\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        forceMinimumInteractiveComponentSize = false,\n                        shape = ShapeDefaults.smallEnd\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.TimerEdit,\n                            contentDescription = null\n                        )\n                    }\n                }\n            }\n            EnhancedIconButton(\n                onClick = {\n                    isDateDialogVisible = true\n                },\n                modifier = Modifier.fillMaxHeight(),\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                forceMinimumInteractiveComponentSize = false,\n                shape = ShapeDefaults.small\n            ) {\n                Icon(\n                    imageVector = Icons.Outlined.DateRange,\n                    contentDescription = null\n                )\n            }\n        }\n\n        RoundedTextField(\n            value = value.status,\n            onValueChange = { onValueChange(value.copy(status = it)) },\n            label = { Text(stringResource(R.string.status)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Info,\n                    contentDescription = null\n                )\n            }\n        )\n\n        EnhancedDateRangePickerDialog(\n            visible = isDateDialogVisible,\n            onDismissRequest = { isDateDialogVisible = false },\n            state = dateState,\n            onDatePicked = { start, end ->\n                onValueChange(\n                    value.copy(\n                        start = startCalendar.apply {\n                            time = Date(start)\n                            set(Calendar.HOUR_OF_DAY, startTimeState.hour)\n                            set(Calendar.MINUTE, startTimeState.minute)\n                        }.time,\n                        end = endCalendar.apply {\n                            time = Date(end)\n                            set(Calendar.HOUR_OF_DAY, endTimeState.hour)\n                            set(Calendar.MINUTE, endTimeState.minute)\n                        }.time\n                    )\n                )\n            }\n        )\n\n        EnhancedTimePickerDialog(\n            visible = showStartTimePicker,\n            onDismissRequest = { showStartTimePicker = false },\n            state = startTimeState,\n            onTimePicked = { hour, minute ->\n                onValueChange(\n                    value.copy(\n                        start = startCalendar.apply {\n                            set(Calendar.HOUR_OF_DAY, hour)\n                            set(Calendar.MINUTE, minute)\n                        }.time\n                    )\n                )\n            }\n        )\n\n        EnhancedTimePickerDialog(\n            visible = showEndTimePicker,\n            onDismissRequest = { showEndTimePicker = false },\n            state = endTimeState,\n            onTimePicked = { hour, minute ->\n                onValueChange(\n                    value.copy(\n                        end = endCalendar.apply {\n                            set(Calendar.HOUR_OF_DAY, hour)\n                            set(Calendar.MINUTE, minute)\n                        }.time\n                    )\n                )\n            }\n        )\n\n        LaunchedEffect(startCalendar, endCalendar) {\n            startTimeState.hour = startCalendar.get(Calendar.HOUR_OF_DAY)\n            startTimeState.minute = startCalendar.get(Calendar.MINUTE)\n\n            endTimeState.hour = endCalendar.get(Calendar.HOUR_OF_DAY)\n            endTimeState.minute = endCalendar.get(Calendar.MINUTE)\n        }\n\n        LaunchedEffect(Unit) {\n            val start = dateState.selectedStartDateMillis\n            val end = dateState.selectedEndDateMillis\n\n            if (start != null && end != null) {\n                onValueChange(\n                    value.copy(\n                        start = Date(start),\n                        end = Date(end)\n                    )\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrContactEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnusedReceiverParameter\")\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.annotation.StringRes\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Add\nimport androidx.compose.material.icons.outlined.AlternateEmail\nimport androidx.compose.material.icons.outlined.Badge\nimport androidx.compose.material.icons.outlined.Business\nimport androidx.compose.material.icons.outlined.Call\nimport androidx.compose.material.icons.outlined.Email\nimport androidx.compose.material.icons.outlined.Home\nimport androidx.compose.material.icons.outlined.Link\nimport androidx.compose.material.icons.outlined.Person\nimport androidx.compose.material.icons.outlined.Place\nimport androidx.compose.material.icons.outlined.Public\nimport androidx.compose.material.icons.outlined.RecordVoiceOver\nimport androidx.compose.material.icons.outlined.RemoveCircleOutline\nimport androidx.compose.material.icons.outlined.SupervisedUserCircle\nimport androidx.compose.material.icons.rounded.Numbers\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Prefix\nimport com.t8rin.imagetoolbox.core.resources.icons.Suffix\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ContactPickerButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.toQrType\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.updateFormattedName\n\n@Composable\ninternal fun QrContactEditField(\n    value: QrType.Contact,\n    onValueChange: (QrType.Contact) -> Unit\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        ContactPickerButton(\n            onPicked = { contact ->\n                onValueChange(contact.toQrType())\n            }\n        )\n\n        ContactInfoEnterBlock(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        PhonesEnterBlock(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        EmailsEnterBlock(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        AddressesEnterBlock(\n            value = value,\n            onValueChange = onValueChange\n        )\n\n        UrlsEnterBlock(\n            value = value,\n            onValueChange = onValueChange\n        )\n    }\n}\n\n@Composable\nprivate fun ColumnScope.ContactInfoEnterBlock(\n    value: QrType.Contact,\n    onValueChange: (QrType.Contact) -> Unit\n) {\n    TitleItem(\n        text = stringResource(R.string.contact_info),\n        icon = Icons.Outlined.Person,\n        modifier = Modifier.padding(vertical = 8.dp)\n    )\n\n    NameEditField(\n        value = value,\n        onValueChange = { onValueChange(it.updateFormattedName()) }\n    )\n\n    RoundedTextField(\n        value = value.organization,\n        onValueChange = { onValueChange(value.copy(organization = it)) },\n        label = { Text(stringResource(R.string.organization)) },\n        startIcon = { Icon(Icons.Outlined.Business, null) }\n    )\n\n    RoundedTextField(\n        value = value.title,\n        onValueChange = { onValueChange(value.copy(title = it)) },\n        label = { Text(stringResource(R.string.title)) },\n        startIcon = { Icon(Icons.Outlined.Badge, null) }\n    )\n}\n\n@Composable\nprivate fun ColumnScope.NameEditField(\n    value: QrType.Contact,\n    onValueChange: (QrType.Contact) -> Unit\n) {\n    RoundedTextField(\n        value = value.name.first,\n        onValueChange = { onValueChange(value.copy(name = value.name.copy(first = it))) },\n        label = { Text(stringResource(R.string.first_name)) },\n        startIcon = { Icon(Icons.Outlined.SupervisedUserCircle, null) }\n    )\n\n    RoundedTextField(\n        value = value.name.middle,\n        onValueChange = { onValueChange(value.copy(name = value.name.copy(middle = it))) },\n        label = { Text(stringResource(R.string.middle_name)) },\n        startIcon = { Icon(Icons.Outlined.SupervisedUserCircle, null) }\n    )\n\n    RoundedTextField(\n        value = value.name.last,\n        onValueChange = { onValueChange(value.copy(name = value.name.copy(last = it))) },\n        label = { Text(stringResource(R.string.last_name)) },\n        startIcon = { Icon(Icons.Outlined.SupervisedUserCircle, null) }\n    )\n    RoundedTextField(\n        value = value.name.prefix,\n        onValueChange = { onValueChange(value.copy(name = value.name.copy(prefix = it))) },\n        label = { Text(stringResource(R.string.prefix)) },\n        startIcon = { Icon(Icons.Filled.Prefix, null) }\n    )\n\n    RoundedTextField(\n        value = value.name.suffix,\n        onValueChange = { onValueChange(value.copy(name = value.name.copy(suffix = it))) },\n        label = { Text(stringResource(R.string.suffix)) },\n        startIcon = { Icon(Icons.Filled.Suffix, null) }\n    )\n\n\n    RoundedTextField(\n        value = value.name.pronunciation,\n        onValueChange = { onValueChange(value.copy(name = value.name.copy(pronunciation = it))) },\n        label = { Text(stringResource(R.string.pronunciation)) },\n        startIcon = { Icon(Icons.Outlined.RecordVoiceOver, null) }\n    )\n}\n\n@Composable\nprivate fun ColumnScope.UrlsEnterBlock(\n    value: QrType.Contact,\n    onValueChange: (QrType.Contact) -> Unit\n) {\n    TitleItem(\n        text = stringResource(R.string.urls),\n        icon = Icons.Outlined.Public,\n        modifier = Modifier.padding(vertical = 8.dp)\n    )\n\n    value.urls.forEachIndexed { index, url ->\n        RemovableTextField(\n            value = url,\n            onValueChange = {\n                val updated = value.urls.toMutableList()\n                updated[index] = it\n                onValueChange(value.copy(urls = updated))\n            },\n            startIcon = Icons.Outlined.Link,\n            label = \"${stringResource(R.string.website)} ${index + 1}\",\n            onRemove = {\n                val updated = value.urls.toMutableList()\n                updated.removeAt(index)\n                onValueChange(value.copy(urls = updated))\n            },\n            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri)\n        )\n    }\n\n    AddButton(\n        onClick = {\n            onValueChange(value.copy(urls = value.urls + \"\"))\n        },\n        title = R.string.add_website\n    )\n}\n\n@Composable\nprivate fun ColumnScope.AddressesEnterBlock(\n    value: QrType.Contact,\n    onValueChange: (QrType.Contact) -> Unit\n) {\n    TitleItem(\n        text = stringResource(R.string.addresses),\n        icon = Icons.Outlined.Home,\n        modifier = Modifier.padding(vertical = 8.dp)\n    )\n\n    value.addresses.forEachIndexed { index, address ->\n        RemovableTextField(\n            value = address.addressLines.joinToString(\", \"),\n            onValueChange = {\n                val updated = value.addresses.toMutableList()\n                updated[index] =\n                    address.copy(addressLines = it.split(\",\").map(String::trim))\n                onValueChange(value.copy(addresses = updated))\n            },\n            startIcon = Icons.Outlined.Place,\n            label = \"${stringResource(R.string.address)} ${index + 1}\",\n            onRemove = {\n                val updated = value.addresses.toMutableList()\n                updated.removeAt(index)\n                onValueChange(value.copy(addresses = updated))\n            },\n            keyboardOptions = KeyboardOptions()\n        )\n    }\n\n    AddButton(\n        onClick = {\n            onValueChange(\n                value.copy(\n                    addresses = value.addresses + QrType.Contact.Address()\n                )\n            )\n        },\n        title = R.string.add_address\n    )\n}\n\n@Composable\nprivate fun ColumnScope.EmailsEnterBlock(\n    value: QrType.Contact,\n    onValueChange: (QrType.Contact) -> Unit\n) {\n    TitleItem(\n        text = stringResource(R.string.emails),\n        icon = Icons.Outlined.Email,\n        modifier = Modifier.padding(vertical = 8.dp)\n    )\n\n    value.emails.forEachIndexed { index, email ->\n        RemovableTextField(\n            value = email.address,\n            onValueChange = {\n                val updated = value.emails.toMutableList()\n                updated[index] = email.copy(address = it)\n                onValueChange(value.copy(emails = updated))\n            },\n            startIcon = Icons.Outlined.AlternateEmail,\n            label = \"${stringResource(R.string.email)} ${index + 1}\",\n            onRemove = {\n                val updated = value.emails.toMutableList()\n                updated.removeAt(index)\n                onValueChange(value.copy(emails = updated))\n            },\n            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email)\n        )\n    }\n\n    AddButton(\n        onClick = {\n            onValueChange(value.copy(emails = value.emails + QrType.Email()))\n        },\n        title = R.string.add_email\n    )\n}\n\n@Composable\nprivate fun ColumnScope.PhonesEnterBlock(\n    value: QrType.Contact,\n    onValueChange: (QrType.Contact) -> Unit\n) {\n    TitleItem(\n        text = stringResource(R.string.phones),\n        icon = Icons.Outlined.Call,\n        modifier = Modifier.padding(vertical = 8.dp)\n    )\n\n    value.phones.forEachIndexed { index, phone ->\n        RemovableTextField(\n            value = phone.number,\n            onValueChange = {\n                val updated = value.phones.toMutableList()\n                updated[index] = phone.copy(number = it)\n                onValueChange(value.copy(phones = updated))\n            },\n            startIcon = Icons.Rounded.Numbers,\n            label = \"${stringResource(R.string.phone)} ${index + 1}\",\n            onRemove = {\n                val updated = value.phones.toMutableList()\n                updated.removeAt(index)\n                onValueChange(value.copy(phones = updated))\n            },\n            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone)\n        )\n    }\n\n    AddButton(\n        onClick = {\n            onValueChange(value.copy(phones = value.phones + QrType.Phone()))\n        },\n        title = R.string.add_phone\n    )\n}\n\n@Composable\nprivate fun RemovableTextField(\n    value: String,\n    onValueChange: (String) -> Unit,\n    onRemove: () -> Unit,\n    startIcon: ImageVector,\n    label: String,\n    keyboardOptions: KeyboardOptions\n) {\n    Row(\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        RoundedTextField(\n            value = value,\n            onValueChange = onValueChange,\n            label = {\n                Text(text = label)\n            },\n            startIcon = {\n                Icon(\n                    imageVector = startIcon,\n                    contentDescription = null\n                )\n            },\n            keyboardOptions = keyboardOptions,\n            modifier = Modifier.weight(1f)\n        )\n        EnhancedIconButton(\n            onClick = onRemove\n        ) {\n            Icon(\n                imageVector = Icons.Outlined.RemoveCircleOutline,\n                contentDescription = null,\n                tint = MaterialTheme.colorScheme.error\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun AddButton(\n    onClick: () -> Unit,\n    @StringRes title: Int\n) {\n    EnhancedButton(\n        onClick = onClick,\n        modifier = Modifier.fillMaxWidth(),\n        containerColor = MaterialTheme.colorScheme.secondaryContainer\n    ) {\n        Icon(Icons.Outlined.Add, null)\n        Spacer(Modifier.width(4.dp))\n        Text(stringResource(title))\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun QrEditField(\n    value: QrType.Complex,\n    onValueChange: (QrType.Complex) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    AnimatedContent(\n        targetState = value,\n        contentKey = { it::class.simpleName },\n        modifier = modifier\n            .container(\n                shape = ShapeDefaults.large,\n                resultPadding = 12.dp\n            )\n    ) { qrType ->\n        when (qrType) {\n            is QrType.Wifi -> QrWifiEditField(\n                value = qrType,\n                onValueChange = onValueChange\n            )\n\n            is QrType.Phone -> QrPhoneEditField(\n                value = qrType,\n                onValueChange = onValueChange\n            )\n\n            is QrType.Sms -> QrSmsEditField(\n                value = qrType,\n                onValueChange = onValueChange\n            )\n\n            is QrType.Email -> QrEmailEditField(\n                value = qrType,\n                onValueChange = onValueChange\n            )\n\n            is QrType.Geo -> QrGeoEditField(\n                value = qrType,\n                onValueChange = onValueChange\n            )\n\n            is QrType.Calendar -> QrCalendarEditField(\n                value = qrType,\n                onValueChange = onValueChange\n            )\n\n            is QrType.Contact -> QrContactEditField(\n                value = qrType,\n                onValueChange = onValueChange\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrEmailEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ShortText\nimport androidx.compose.material.icons.outlined.Topic\nimport androidx.compose.material.icons.rounded.AlternateEmail\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\n\n@Composable\ninternal fun QrEmailEditField(\n    value: QrType.Email,\n    onValueChange: (QrType.Email) -> Unit\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        RoundedTextField(\n            value = value.address,\n            onValueChange = { onValueChange(value.copy(address = it)) },\n            label = { Text(stringResource(R.string.address)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Rounded.AlternateEmail,\n                    contentDescription = null\n                )\n            },\n            keyboardOptions = KeyboardOptions(\n                keyboardType = KeyboardType.Email\n            )\n        )\n        RoundedTextField(\n            value = value.subject,\n            onValueChange = { onValueChange(value.copy(subject = it)) },\n            label = { Text(stringResource(R.string.subject)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Topic,\n                    contentDescription = null\n                )\n            },\n            singleLine = false\n        )\n        RoundedTextField(\n            value = value.body,\n            onValueChange = { onValueChange(value.copy(body = it)) },\n            label = { Text(stringResource(R.string.body)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.AutoMirrored.Rounded.ShortText,\n                    contentDescription = null\n                )\n            },\n            singleLine = false\n        )\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrGeoEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.utils.trimTrailingZero\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Latitude\nimport com.t8rin.imagetoolbox.core.resources.icons.Longitude\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.value.filterDecimal\n\n@Composable\ninternal fun QrGeoEditField(\n    value: QrType.Geo,\n    onValueChange: (QrType.Geo) -> Unit\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        var latitude by remember {\n            mutableStateOf(value.latitude?.toString().orEmpty().trimTrailingZero())\n        }\n        var longitude by remember {\n            mutableStateOf(value.longitude?.toString().orEmpty().trimTrailingZero())\n        }\n\n        RoundedTextField(\n            value = latitude,\n            onValueChange = {\n                latitude = it.filterDecimal()\n\n                latitude.toDoubleOrNull()?.coerceIn(LatitudeRange)?.let { new ->\n                    onValueChange(value.copy(latitude = new))\n                }\n            },\n            label = { Text(stringResource(R.string.latitude)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Latitude,\n                    contentDescription = null\n                )\n            },\n            keyboardOptions = KeyboardOptions(\n                keyboardType = KeyboardType.Decimal\n            )\n        )\n        RoundedTextField(\n            value = longitude,\n            onValueChange = {\n                longitude = it.filterDecimal()\n\n                longitude.toDoubleOrNull()?.coerceIn(LongitudeRange)?.let { new ->\n                    onValueChange(value.copy(longitude = new))\n                }\n            },\n            label = { Text(stringResource(R.string.longitude)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Outlined.Longitude,\n                    contentDescription = null\n                )\n            },\n            keyboardOptions = KeyboardOptions(\n                keyboardType = KeyboardType.Decimal\n            )\n        )\n    }\n}\n\nprivate val LatitudeRange = -90.0..90.0\nprivate val LongitudeRange = -180.0..180.0"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrPhoneEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Numbers\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ContactPickerButton\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\n\n@Composable\ninternal fun QrPhoneEditField(\n    value: QrType.Phone,\n    onValueChange: (QrType.Phone) -> Unit\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        RoundedTextField(\n            value = value.number,\n            onValueChange = { onValueChange(value.copy(number = it)) },\n            label = { Text(stringResource(R.string.phone)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Rounded.Numbers,\n                    contentDescription = null\n                )\n            },\n            keyboardOptions = KeyboardOptions(\n                keyboardType = KeyboardType.Phone\n            )\n        )\n\n        ContactPickerButton(\n            onPicked = { onValueChange(value.copy(number = it.phones.firstOrNull()?.number.orEmpty())) }\n        )\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrSmsEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.StickyNote2\nimport androidx.compose.material.icons.rounded.Numbers\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.ContactPickerButton\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\n\n@Composable\ninternal fun QrSmsEditField(\n    value: QrType.Sms,\n    onValueChange: (QrType.Sms) -> Unit\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        RoundedTextField(\n            value = value.phoneNumber,\n            onValueChange = { onValueChange(value.copy(phoneNumber = it)) },\n            label = { Text(stringResource(R.string.phone)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Rounded.Numbers,\n                    contentDescription = null\n                )\n            },\n            keyboardOptions = KeyboardOptions(\n                keyboardType = KeyboardType.Phone\n            )\n        )\n        RoundedTextField(\n            value = value.message,\n            onValueChange = { onValueChange(value.copy(message = it)) },\n            label = { Text(stringResource(R.string.message)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.AutoMirrored.Outlined.StickyNote2,\n                    contentDescription = null\n                )\n            },\n            singleLine = false\n        )\n\n        ContactPickerButton(\n            onPicked = { onValueChange(value.copy(phoneNumber = it.phones.firstOrNull()?.number.orEmpty())) }\n        )\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/components/editor/QrWifiEditField.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.editor\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CheckCircleOutline\nimport androidx.compose.material.icons.rounded.Password\nimport androidx.compose.material.icons.rounded.Security\nimport androidx.compose.material.icons.rounded.TextFields\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.model.QrType.Wifi.EncryptionType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Build\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun QrWifiEditField(\n    value: QrType.Wifi,\n    onValueChange: (QrType.Wifi) -> Unit\n) {\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        TitleItem(\n            text = stringResource(R.string.wifi_configuration),\n            icon = Icons.Outlined.Build,\n            modifier = Modifier.padding(bottom = 8.dp)\n        )\n        RoundedTextField(\n            value = value.ssid,\n            onValueChange = { onValueChange(value.copy(ssid = it)) },\n            label = { Text(stringResource(R.string.ssid)) },\n            startIcon = {\n                Icon(\n                    imageVector = Icons.Rounded.TextFields,\n                    contentDescription = null\n                )\n            },\n            singleLine = false\n        )\n        AnimatedVisibility(\n            visible = value.encryptionType != EncryptionType.OPEN,\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            RoundedTextField(\n                value = value.password,\n                onValueChange = { onValueChange(value.copy(password = it)) },\n                label = { Text(stringResource(R.string.password)) },\n                startIcon = {\n                    Icon(\n                        imageVector = Icons.Rounded.Password,\n                        contentDescription = null\n                    )\n                },\n                keyboardOptions = KeyboardOptions(\n                    keyboardType = KeyboardType.Password\n                )\n            )\n        }\n\n        DataSelector(\n            value = value.encryptionType,\n            onValueChange = { onValueChange(value.copy(encryptionType = it)) },\n            entries = EncryptionType.entries,\n            title = stringResource(R.string.security),\n            titleIcon = Icons.Rounded.Security,\n            itemContentText = { it.name },\n            itemContentIcon = { _, selected -> if (selected) Icons.Rounded.CheckCircleOutline else null },\n            spanCount = 1,\n            behaveAsContainer = false,\n            titlePadding = PaddingValues(top = 8.dp, bottom = 16.dp),\n            contentPadding = PaddingValues(),\n            canExpand = false,\n            selectedItemColor = MaterialTheme.colorScheme.secondaryContainer\n        )\n    }\n}"
  },
  {
    "path": "feature/scan-qr-code/src/main/java/com/t8rin/imagetoolbox/feature/scan_qr_code/presentation/screenLogic/ScanQrCodeComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.screenLogic\n\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.QrType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.utils.onResult\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterParamsInteractor\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiFont\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.domain.ImageBarcodeReader\nimport com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.components.QrPreviewParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\n\nclass ScanQrCodeComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted initialQrCodeContent: String?,\n    @Assisted uriToAnalyze: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    private val fileController: FileController,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val filterParamsInteractor: FilterParamsInteractor,\n    private val imageBarcodeReader: ImageBarcodeReader,\n    settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _params: MutableState<QrPreviewParams> = mutableStateOf(QrPreviewParams.Default)\n    val params by _params\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    private var settingsState: SettingsState = SettingsState.Default\n\n    private val _mayBeNotScannable = mutableStateOf(false)\n    val mayBeNotScannable by _mayBeNotScannable\n\n    private val _isSaveEnabled = mutableStateOf(false)\n    val isSaveEnabled by _isSaveEnabled\n\n    init {\n        settingsProvider.settingsState.onEach { state ->\n            settingsState = state\n            _params.update {\n                it.copy(\n                    descriptionFont = settingsState.font.toUiFont()\n                )\n            }\n        }.launchIn(componentScope)\n\n        initialQrCodeContent?.let { content ->\n            updateParams(\n                params.copy(\n                    content = QrType.Plain(content)\n                )\n            )\n        }\n\n        uriToAnalyze?.let(::readBarcodeFromImage)\n    }\n\n    fun saveBitmap(\n        bitmap: Bitmap,\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            parseSaveResult(\n                fileController.save(\n                    saveTarget = ImageSaveTarget(\n                        imageInfo = ImageInfo(\n                            width = bitmap.width,\n                            height = bitmap.height\n                        ),\n                        originalUri = \"_\",\n                        sequenceNumber = null,\n                        data = imageCompressor.compress(\n                            image = bitmap,\n                            imageFormat = ImageFormat.Png.Lossless,\n                            quality = Quality.Base(100)\n                        )\n                    ),\n                    keepOriginalMetadata = false,\n                    oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                )\n            )\n            _isSaving.update { false }\n        }\n    }\n\n    fun shareImage(\n        bitmap: Bitmap\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            bitmap.let { image ->\n                shareProvider.shareImage(\n                    imageInfo = ImageInfo(\n                        width = image.width,\n                        height = image.height,\n                        imageFormat = ImageFormat.Png.Lossless\n                    ),\n                    image = image,\n                    onComplete = {\n                        _isSaving.value = false\n                        AppToastHost.showConfetti()\n                    }\n                )\n            }\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun cacheImage(\n        bitmap: Bitmap,\n        onComplete: (Uri) -> Unit\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            bitmap.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = ImageInfo(\n                        width = image.width,\n                        height = image.height,\n                        imageFormat = ImageFormat.Png.Lossless\n                    )\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun processFilterTemplateFromQrContent(\n        onSuccess: (filterName: String, filtersCount: Int) -> Unit\n    ) {\n        componentScope.launch {\n            if (filterParamsInteractor.isValidTemplateFilter(params.content.raw)) {\n                filterParamsInteractor.addTemplateFilterFromString(\n                    string = params.content.raw,\n                    onSuccess = onSuccess,\n                    onFailure = {}\n                )\n            }\n        }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = ImageFormat.Png.Lossless\n\n    fun updateParams(params: QrPreviewParams) {\n        _params.update { params }\n    }\n\n    fun readBarcodeFromImage(\n        image: Any,\n        onFailure: (Throwable) -> Unit = {}\n    ) {\n        componentScope.launch {\n            syncReadBarcodeFromImage(image).onFailure(onFailure)\n        }\n    }\n\n    suspend fun syncReadBarcodeFromImage(\n        image: Any?\n    ): Result<QrType> {\n        _isSaveEnabled.value = image != null\n\n        if (image == null) return Result.failure(Throwable(\"Barcode not rendered\"))\n\n        return imageBarcodeReader\n            .readBarcode(image)\n            .onResult { isSuccess ->\n                _mayBeNotScannable.value = !isSuccess\n            }\n            .onSuccess {\n                updateParams(\n                    params.copy(\n                        content = it\n                    )\n                )\n            }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialQrCodeContent: String?,\n            uriToAnalyze: Uri?,\n            onGoBack: () -> Unit,\n        ): ScanQrCodeComponent\n    }\n\n}"
  },
  {
    "path": "feature/settings/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/settings/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.settings\""
  },
  {
    "path": "feature/settings/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/data/AndroidSettingsManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.data\n\nimport android.content.Context\nimport android.graphics.Typeface\nimport androidx.core.net.toFile\nimport androidx.core.net.toUri\nimport androidx.datastore.core.DataStore\nimport androidx.datastore.preferences.core.MutablePreferences\nimport androidx.datastore.preferences.core.Preferences\nimport androidx.datastore.preferences.core.edit\nimport com.t8rin.imagetoolbox.core.data.utils.isInstalledFromPlayStore\nimport com.t8rin.imagetoolbox.core.data.utils.outputStream\nimport com.t8rin.imagetoolbox.core.domain.BACKUP_FILE_EXT\nimport com.t8rin.imagetoolbox.core.domain.GLOBAL_STORAGE_NAME\nimport com.t8rin.imagetoolbox.core.domain.coroutines.AppScope\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.json.JsonParser\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.model.PerformanceClass\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ColorHarmonizer\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.DomainFontFamily\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.NightMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType\nimport com.t8rin.imagetoolbox.core.utils.createZip\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.core.utils.putEntry\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_ORIGINAL_NAME_TO_FILENAME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_PRESET_TO_FILENAME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_SCALE_MODE_TO_FILENAME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_SEQ_NUM_TO_FILENAME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_SIZE_TO_FILENAME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_TIMESTAMP_TO_FILENAME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ALLOW_ANALYTICS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ALLOW_AUTO_PASTE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ALLOW_BETAS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ALLOW_CRASHLYTICS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ALLOW_IMAGE_MONET\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ALLOW_SKIP_IF_LARGER\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.AMOLED_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.APP_COLOR_TUPLE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.APP_OPEN_COUNT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ASCII_CUSTOM_GRADIENTS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.AUTO_CACHE_CLEAR\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.BACKGROUND_COLOR_FOR_NA_FORMATS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.BORDER_WIDTH\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.CAN_ENTER_PRESETS_BY_TEXT_FIELD\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.CENTER_ALIGN_DIALOG_BUTTONS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.COLOR_BLIND_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.COLOR_TUPLES\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.CONFETTI_ENABLED\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.CONFETTI_HARMONIZATION_LEVEL\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.CONFETTI_HARMONIZER\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.CONFETTI_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.COPY_TO_CLIPBOARD_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.CUSTOM_FONTS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DEFAULT_DRAW_COLOR\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DEFAULT_DRAW_LINE_WIDTH\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DEFAULT_DRAW_PATH_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DEFAULT_IMAGE_FORMAT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DEFAULT_QUALITY\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DEFAULT_RESIZE_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DONATE_DIALOG_OPEN_COUNT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DRAG_HANDLE_WIDTH\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DRAW_APPBAR_SHADOWS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DRAW_BUTTON_SHADOWS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DRAW_CONTAINER_SHADOWS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DRAW_FAB_SHADOWS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DRAW_SLIDER_SHADOWS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DRAW_SWITCH_SHADOWS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.DYNAMIC_COLORS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.EMOJI_COUNT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ENABLE_BACKGROUND_COLOR_FOR_ALPHA_FORMATS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ENABLE_TOOL_EXIT_CONFIRMATION\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.EXIF_WIDGET_INITIAL_STATE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FAB_ALIGNMENT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FAST_SETTINGS_SIDE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FAVORITE_COLORS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FAVORITE_SCREENS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FILENAME_BEHAVIOR\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FILENAME_PATTERN\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FILENAME_PREFIX\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FILENAME_SUFFIX\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FLING_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.FONT_SCALE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.GENERATE_PREVIEWS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.GROUP_OPTIONS_BY_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.HIDDEN_FOR_SHARE_SCREENS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ICON_SHAPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.IMAGE_PICKER_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.IMAGE_SCALE_COLOR_SPACE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.IMAGE_SCALE_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.INITIAL_OCR_CODES\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.INITIAL_OCR_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.INVERT_THEME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.IS_LAUNCHER_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.IS_LINK_PREVIEW_ENABLED\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.IS_SYSTEM_BARS_VISIBLE_BY_SWIPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.IS_TELEGRAM_GROUP_OPENED\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.KEEP_DATE_TIME\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.LOCK_DRAW_ORIENTATION\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.MAGNIFIER_ENABLED\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.MAIN_SCREEN_TITLE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.NIGHT_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.ONE_TIME_SAVE_LOCATIONS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.OPEN_EDIT_INSTEAD_OF_PREVIEW\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.PRESETS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.RECENT_COLORS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SAVE_FOLDER_URI\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SCREENS_WITH_BRIGHTNESS_ENFORCEMENT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SCREEN_ORDER\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SCREEN_SEARCH_ENABLED\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SECURE_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SELECTED_EMOJI_INDEX\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SELECTED_FONT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SETTINGS_GROUP_VISIBILITY\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SHAPES_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SHOW_SETTINGS_IN_LANDSCAPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SHOW_UPDATE_DIALOG\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SKIP_IMAGE_PICKING\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SLIDER_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SNOWFALL_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SPOT_HEAL_MODE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SWITCH_TYPE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.SYSTEM_BARS_VISIBILITY\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.THEME_CONTRAST_LEVEL\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.THEME_STYLE\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.USE_COMPACT_SELECTORS_LAYOUT\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.USE_EMOJI_AS_PRIMARY_COLOR\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.USE_FORMATTED_TIMESTAMP\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.USE_FULLSCREEN_SETTINGS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.USE_RANDOM_EMOJIS\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.VIBRATION_STRENGTH\nimport com.t8rin.imagetoolbox.feature.settings.data.keys.toSettingsState\nimport com.t8rin.logger.Logger\nimport com.t8rin.logger.makeLog\nimport dagger.Lazy\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.io.ByteArrayInputStream\nimport java.io.File\nimport java.io.FileInputStream\nimport javax.inject.Inject\nimport kotlin.random.Random\n\ninternal class AndroidSettingsManager @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val dataStore: DataStore<Preferences>,\n    private val shareProvider: Lazy<ShareProvider>,\n    private val jsonParser: JsonParser,\n    dispatchersHolder: DispatchersHolder,\n    appScope: AppScope,\n) : DispatchersHolder by dispatchersHolder, SettingsManager {\n\n    init {\n        appScope.launch {\n            registerAppOpen()\n        }\n    }\n\n    private val default = SettingsState.Default\n\n    private val currentSettings: SettingsState get() = settingsState.value\n\n    override suspend fun getSettingsState(): SettingsState = rawFlow().first()\n\n    private fun rawFlow(): Flow<SettingsState> = dataStore.data.map {\n        it.toSettingsState(\n            default = default,\n            jsonParser = jsonParser\n        )\n    }\n\n    override val settingsState: StateFlow<SettingsState> = rawFlow().stateIn(\n        scope = appScope,\n        started = SharingStarted.Eagerly,\n        initialValue = default\n    )\n\n    override suspend fun toggleAddSequenceNumber() = toggle(\n        key = ADD_SEQ_NUM_TO_FILENAME,\n        defaultValue = default.addSequenceNumber\n    )\n\n    override suspend fun toggleAddOriginalFilename() = toggle(\n        key = ADD_ORIGINAL_NAME_TO_FILENAME,\n        defaultValue = default.addOriginalFilename\n    )\n\n    override suspend fun setEmojisCount(count: Int) = edit {\n        it[EMOJI_COUNT] = count\n    }\n\n    override suspend fun setImagePickerMode(mode: Int) = edit {\n        it[IMAGE_PICKER_MODE] = mode\n    }\n\n    override suspend fun toggleAddFileSize() = toggle(\n        key = ADD_SIZE_TO_FILENAME,\n        defaultValue = default.addSizeInFilename\n    )\n\n    override suspend fun setEmoji(emoji: Int) = edit {\n        it[SELECTED_EMOJI_INDEX] = emoji\n    }\n\n    override suspend fun setFilenamePrefix(name: String) = edit {\n        it[FILENAME_PREFIX] = name\n    }\n\n    override suspend fun toggleShowUpdateDialogOnStartup() = toggle(\n        key = SHOW_UPDATE_DIALOG,\n        defaultValue = default.showUpdateDialogOnStartup\n    )\n\n\n    override suspend fun setColorTuple(colorTuple: String) = edit {\n        it[APP_COLOR_TUPLE] = colorTuple\n    }\n\n    override suspend fun setPresets(newPresets: List<Int>) = edit { preferences ->\n        if (newPresets.size > 3) {\n            preferences[PRESETS] = newPresets\n                .map { it.coerceIn(10..500) }\n                .toSortedSet()\n                .toList()\n                .reversed()\n                .joinToString(\"*\")\n        }\n    }\n\n    override suspend fun toggleDynamicColors() = edit {\n        it.toggle(\n            key = DYNAMIC_COLORS,\n            defaultValue = default.isDynamicColors\n        )\n        if (it[DYNAMIC_COLORS] == true) {\n            it[ALLOW_IMAGE_MONET] = false\n        }\n    }\n\n    override suspend fun setBorderWidth(width: Float) = edit {\n        it[BORDER_WIDTH] = if (width > 0) width else -1f\n    }\n\n    override suspend fun toggleAllowImageMonet() = toggle(\n        key = ALLOW_IMAGE_MONET,\n        defaultValue = default.allowChangeColorByImage\n    )\n\n    override suspend fun toggleAmoledMode() = toggle(\n        key = AMOLED_MODE,\n        defaultValue = default.isAmoledMode\n    )\n\n    override suspend fun setNightMode(nightMode: NightMode) = edit {\n        it[NIGHT_MODE] = nightMode.ordinal\n    }\n\n    override suspend fun setSaveFolderUri(uri: String?) = edit {\n        it[SAVE_FOLDER_URI] = uri ?: \"\"\n    }\n\n    override suspend fun setColorTuples(colorTuples: String) = edit {\n        it[COLOR_TUPLES] = colorTuples\n    }\n\n    override suspend fun setAlignment(align: Int) = edit {\n        it[FAB_ALIGNMENT] = align\n    }\n\n    override suspend fun setScreenOrder(data: String) = edit {\n        it[SCREEN_ORDER] = data\n    }\n\n    override suspend fun toggleClearCacheOnLaunch() = toggle(\n        key = AUTO_CACHE_CLEAR,\n        defaultValue = default.clearCacheOnLaunch\n    )\n\n    override suspend fun toggleGroupOptionsByTypes() = toggle(\n        key = GROUP_OPTIONS_BY_TYPE,\n        defaultValue = default.groupOptionsByTypes\n    )\n\n    override suspend fun toggleRandomizeFilename() = toggleFilenameBehavior(\n        behavior = FilenameBehavior.Random()\n    )\n\n    override suspend fun createBackupFile(): ByteArray =\n        context.obtainDatastoreData(GLOBAL_STORAGE_NAME)\n\n    override suspend fun restoreFromBackupFile(\n        backupFileUri: String,\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit,\n    ) = withContext(ioDispatcher) {\n        context.restoreDatastore(\n            fileName = GLOBAL_STORAGE_NAME,\n            backupUri = backupFileUri.toUri(),\n            onFailure = onFailure,\n            onSuccess = {\n                onSuccess()\n                setSaveFolderUri(null)\n            }\n        )\n        toggleClearCacheOnLaunch()\n        toggleClearCacheOnLaunch()\n    }\n\n    override suspend fun resetSettings() = withContext(defaultDispatcher) {\n        context.resetDatastore(GLOBAL_STORAGE_NAME)\n        registerAppOpen()\n    }\n\n    override fun createBackupFilename(): String =\n        \"image_toolbox_${timestamp()}.$BACKUP_FILE_EXT\"\n\n    override suspend fun setFont(font: DomainFontFamily) = edit {\n        it[SELECTED_FONT] = font.asString()\n    }\n\n    override suspend fun setFontScale(scale: Float) = edit {\n        it[FONT_SCALE] = scale\n    }\n\n    override suspend fun toggleAllowCrashlytics() = toggle(\n        key = ALLOW_CRASHLYTICS,\n        defaultValue = default.allowCollectCrashlytics\n    )\n\n    override suspend fun toggleAllowAnalytics() = toggle(\n        key = ALLOW_ANALYTICS,\n        defaultValue = default.allowCollectAnalytics\n    )\n\n    override suspend fun toggleAllowBetas() = toggle(\n        key = ALLOW_BETAS,\n        defaultValue = default.allowBetas\n    )\n\n    override suspend fun toggleDrawContainerShadows() = toggle(\n        key = DRAW_CONTAINER_SHADOWS,\n        defaultValue = default.drawContainerShadows\n    )\n\n    override suspend fun toggleDrawButtonShadows() = toggle(\n        key = DRAW_BUTTON_SHADOWS,\n        defaultValue = default.drawButtonShadows\n    )\n\n    override suspend fun toggleDrawSliderShadows() = toggle(\n        key = DRAW_SLIDER_SHADOWS,\n        defaultValue = default.drawSliderShadows\n    )\n\n    override suspend fun toggleDrawSwitchShadows() = toggle(\n        key = DRAW_SWITCH_SHADOWS,\n        defaultValue = default.drawSwitchShadows\n    )\n\n    override suspend fun toggleDrawFabShadows() = toggle(\n        key = DRAW_FAB_SHADOWS,\n        defaultValue = default.drawFabShadows\n    )\n\n    private suspend fun registerAppOpen() = edit {\n        val v = it[APP_OPEN_COUNT] ?: default.appOpenCount\n        it[APP_OPEN_COUNT] = v + 1\n    }\n\n    override suspend fun toggleLockDrawOrientation() = toggle(\n        key = LOCK_DRAW_ORIENTATION,\n        defaultValue = default.lockDrawOrientation\n    )\n\n    override suspend fun setThemeStyle(value: Int) = edit {\n        it[THEME_STYLE] = value\n    }\n\n    override suspend fun setThemeContrast(value: Double) = edit {\n        it[THEME_CONTRAST_LEVEL] = value\n    }\n\n    override suspend fun toggleInvertColors() = toggle(\n        key = INVERT_THEME,\n        defaultValue = default.isInvertThemeColors\n    )\n\n    override suspend fun toggleScreensSearchEnabled() = toggle(\n        key = SCREEN_SEARCH_ENABLED,\n        defaultValue = default.screensSearchEnabled\n    )\n\n    override suspend fun toggleDrawAppBarShadows() = toggle(\n        key = DRAW_APPBAR_SHADOWS,\n        defaultValue = default.drawAppBarShadows\n    )\n\n    override suspend fun setCopyToClipboardMode(\n        copyToClipboardMode: CopyToClipboardMode\n    ) = edit {\n        it[COPY_TO_CLIPBOARD_MODE] = copyToClipboardMode.value\n    }\n\n    override suspend fun setVibrationStrength(strength: Int) = edit {\n        it[VIBRATION_STRENGTH] = strength\n    }\n\n    override suspend fun toggleOverwriteFiles() = toggleFilenameBehavior(\n        behavior = FilenameBehavior.Overwrite()\n    )\n\n    override suspend fun setSpotHealMode(mode: Int) = edit {\n        it[SPOT_HEAL_MODE] = mode\n    }\n\n    override suspend fun setFilenameSuffix(name: String) = edit {\n        it[FILENAME_SUFFIX] = name\n    }\n\n    override suspend fun setDefaultImageScaleMode(imageScaleMode: ImageScaleMode) = edit {\n        it[IMAGE_SCALE_MODE] = imageScaleMode.value\n        it[IMAGE_SCALE_COLOR_SPACE] = imageScaleMode.scaleColorSpace.ordinal\n    }\n\n    override suspend fun toggleMagnifierEnabled() = toggle(\n        key = MAGNIFIER_ENABLED,\n        defaultValue = default.magnifierEnabled\n    )\n\n    override suspend fun toggleExifWidgetInitialState() = toggle(\n        key = EXIF_WIDGET_INITIAL_STATE,\n        defaultValue = default.exifWidgetInitialState\n    )\n\n    override suspend fun setInitialOCRLanguageCodes(list: List<String>) = edit {\n        it[INITIAL_OCR_CODES] = list.joinToString(separator = \"+\")\n    }\n\n    override suspend fun createLogsExport(): String = withContext(ioDispatcher) {\n        \"Start Logs Export\".makeLog(\"SettingsManager\")\n\n        val logsFile = Logger.getLogsFile().toFile()\n        val settingsFile = createBackupFile()\n\n        shareProvider.get().cacheData(\n            writeData = { writeable ->\n                writeable.outputStream().createZip { zip ->\n                    zip.putEntry(\n                        name = logsFile.name,\n                        input = FileInputStream(logsFile)\n                    )\n                    zip.putEntry(\n                        name = createBackupFilename(),\n                        input = ByteArrayInputStream(settingsFile)\n                    )\n                }\n            },\n            filename = \"image_toolbox_logs_${timestamp()}.zip\"\n        ) ?: \"\"\n    }\n\n    override suspend fun toggleAddPresetInfoToFilename() = toggle(\n        key = ADD_PRESET_TO_FILENAME,\n        defaultValue = default.addPresetInfoToFilename\n    )\n\n    override suspend fun toggleAddImageScaleModeInfoToFilename() = toggle(\n        key = ADD_SCALE_MODE_TO_FILENAME,\n        defaultValue = default.addImageScaleModeInfoToFilename\n    )\n\n    override suspend fun toggleAllowSkipIfLarger() = toggle(\n        key = ALLOW_SKIP_IF_LARGER,\n        defaultValue = default.allowSkipIfLarger\n    )\n\n    override suspend fun toggleIsScreenSelectionLauncherMode() = toggle(\n        key = IS_LAUNCHER_MODE,\n        defaultValue = default.isScreenSelectionLauncherMode\n    )\n\n    override suspend fun setScreensWithBrightnessEnforcement(data: List<Int>) =\n        edit { preferences ->\n            preferences[SCREENS_WITH_BRIGHTNESS_ENFORCEMENT] =\n                data.joinToString(\"/\") { it.toString() }\n        }\n\n    override suspend fun toggleConfettiEnabled() = toggle(\n        key = CONFETTI_ENABLED,\n        defaultValue = default.isConfettiEnabled\n    )\n\n    override suspend fun toggleSecureMode() = toggle(\n        key = SECURE_MODE,\n        defaultValue = default.isSecureMode\n    )\n\n    override suspend fun toggleUseRandomEmojis() = toggle(\n        key = USE_RANDOM_EMOJIS,\n        defaultValue = default.useRandomEmojis\n    )\n\n    override suspend fun setIconShape(iconShape: Int) = edit {\n        it[ICON_SHAPE] = iconShape\n    }\n\n    override suspend fun toggleUseEmojiAsPrimaryColor() = toggle(\n        key = USE_EMOJI_AS_PRIMARY_COLOR,\n        defaultValue = default.useEmojiAsPrimaryColor\n    )\n\n    override suspend fun setDragHandleWidth(width: Int) = edit {\n        it[DRAG_HANDLE_WIDTH] = width\n    }\n\n    override suspend fun setConfettiType(type: Int) = edit {\n        it[CONFETTI_TYPE] = type\n    }\n\n    override suspend fun toggleAllowAutoClipboardPaste() = toggle(\n        key = ALLOW_AUTO_PASTE,\n        defaultValue = default.allowAutoClipboardPaste\n    )\n\n    override suspend fun setConfettiHarmonizer(colorHarmonizer: ColorHarmonizer) = edit {\n        it[CONFETTI_HARMONIZER] = colorHarmonizer.ordinal\n    }\n\n    override suspend fun setConfettiHarmonizationLevel(level: Float) = edit {\n        it[CONFETTI_HARMONIZATION_LEVEL] = level\n    }\n\n    override suspend fun toggleGeneratePreviews() = toggle(\n        key = GENERATE_PREVIEWS,\n        defaultValue = default.generatePreviews\n    )\n\n    override suspend fun toggleSkipImagePicking() = toggle(\n        key = SKIP_IMAGE_PICKING,\n        defaultValue = default.skipImagePicking\n    )\n\n    override suspend fun toggleShowSettingsInLandscape() = toggle(\n        key = SHOW_SETTINGS_IN_LANDSCAPE,\n        defaultValue = default.showSettingsInLandscape\n    )\n\n    override suspend fun toggleUseFullscreenSettings() = toggle(\n        key = USE_FULLSCREEN_SETTINGS,\n        defaultValue = default.useFullscreenSettings\n    )\n\n    override suspend fun setSwitchType(type: SwitchType) = edit {\n        it[SWITCH_TYPE] = type.ordinal\n    }\n\n    override suspend fun setDefaultDrawLineWidth(value: Float) = edit {\n        it[DEFAULT_DRAW_LINE_WIDTH] = value\n    }\n\n    override suspend fun setOneTimeSaveLocations(\n        value: List<OneTimeSaveLocation>\n    ) = edit { preferences ->\n        preferences[ONE_TIME_SAVE_LOCATIONS] = value.filter {\n            it.uri.isNotEmpty() && it.date != null\n        }.distinctBy { it.uri }.joinToString(\", \")\n    }\n\n    override suspend fun toggleRecentColor(\n        color: ColorModel,\n        forceExclude: Boolean,\n    ) = edit { preferences ->\n        val current = currentSettings.recentColors\n        val newColors = if (color in current) {\n            if (forceExclude) {\n                current - color\n            } else {\n                listOf(color) + (current - color)\n            }\n        } else {\n            listOf(color) + current\n        }\n\n        preferences[RECENT_COLORS] = newColors.take(30).map { it.colorInt.toString() }.toSet()\n    }\n\n    override suspend fun toggleFavoriteColor(\n        color: ColorModel,\n        forceExclude: Boolean\n    ) = edit { preferences ->\n        val current = currentSettings.favoriteColors\n        val newColors = if (color in current) {\n            if (forceExclude) {\n                current - color\n            } else {\n                listOf(color) + (current - color)\n            }\n        } else {\n            listOf(color) + current\n        }\n\n        preferences[FAVORITE_COLORS] = newColors.joinToString(\"/\") { it.colorInt.toString() }\n    }\n\n    override suspend fun toggleOpenEditInsteadOfPreview() = toggle(\n        key = OPEN_EDIT_INSTEAD_OF_PREVIEW,\n        defaultValue = default.openEditInsteadOfPreview\n    )\n\n    override suspend fun toggleCanEnterPresetsByTextField() = toggle(\n        key = CAN_ENTER_PRESETS_BY_TEXT_FIELD,\n        defaultValue = default.canEnterPresetsByTextField\n    )\n\n    override suspend fun adjustPerformance(performanceClass: PerformanceClass) = edit {\n        when (performanceClass) {\n            PerformanceClass.Low -> {\n                it[CONFETTI_ENABLED] = false\n                it[DRAW_BUTTON_SHADOWS] = false\n                it[DRAW_SWITCH_SHADOWS] = false\n                it[DRAW_SLIDER_SHADOWS] = false\n                it[DRAW_CONTAINER_SHADOWS] = false\n                it[DRAW_APPBAR_SHADOWS] = false\n            }\n\n            PerformanceClass.Average -> {\n                it[CONFETTI_ENABLED] = true\n                it[DRAW_BUTTON_SHADOWS] = false\n                it[DRAW_SWITCH_SHADOWS] = true\n                it[DRAW_SLIDER_SHADOWS] = false\n                it[DRAW_CONTAINER_SHADOWS] = false\n                it[DRAW_APPBAR_SHADOWS] = true\n            }\n\n            PerformanceClass.High -> {\n                it[CONFETTI_ENABLED] = true\n                it[DRAW_BUTTON_SHADOWS] = true\n                it[DRAW_SWITCH_SHADOWS] = true\n                it[DRAW_SLIDER_SHADOWS] = true\n                it[DRAW_CONTAINER_SHADOWS] = true\n                it[DRAW_APPBAR_SHADOWS] = true\n            }\n        }\n    }\n\n    override suspend fun registerDonateDialogOpen() = edit {\n        val value = it[DONATE_DIALOG_OPEN_COUNT] ?: default.donateDialogOpenCount\n\n        if (value != -1) {\n            it[DONATE_DIALOG_OPEN_COUNT] = value + 1\n        }\n    }\n\n    override suspend fun setNotShowDonateDialogAgain() = edit {\n        it[DONATE_DIALOG_OPEN_COUNT] = -1\n    }\n\n    override suspend fun setColorBlindType(value: Int?) = edit {\n        it[COLOR_BLIND_TYPE] = value ?: -1\n    }\n\n    override suspend fun toggleFavoriteScreen(screenId: Int) = edit {\n        val current = currentSettings.favoriteScreenList\n        val newScreens = if (screenId in current) {\n            current - screenId\n        } else {\n            current + screenId\n        }\n\n        it[FAVORITE_SCREENS] = newScreens.joinToString(\"/\")\n    }\n\n    override suspend fun toggleIsLinkPreviewEnabled() = toggle(\n        key = IS_LINK_PREVIEW_ENABLED,\n        defaultValue = default.isLinkPreviewEnabled\n    )\n\n    override suspend fun setDefaultDrawColor(color: ColorModel) = edit {\n        it[DEFAULT_DRAW_COLOR] = color.colorInt\n    }\n\n    override suspend fun setDefaultDrawPathMode(modeOrdinal: Int) = edit {\n        it[DEFAULT_DRAW_PATH_MODE] = modeOrdinal\n    }\n\n    override suspend fun toggleAddTimestampToFilename() = toggle(\n        key = ADD_TIMESTAMP_TO_FILENAME,\n        defaultValue = default.addTimestampToFilename\n    )\n\n    override suspend fun toggleUseFormattedFilenameTimestamp() = toggle(\n        key = USE_FORMATTED_TIMESTAMP,\n        defaultValue = default.useFormattedFilenameTimestamp\n    )\n\n    override suspend fun registerTelegramGroupOpen() = edit {\n        it[IS_TELEGRAM_GROUP_OPENED] = true\n    }\n\n    override suspend fun setDefaultResizeType(resizeType: ResizeType) = edit { preferences ->\n        preferences[DEFAULT_RESIZE_TYPE] = ResizeType.entries.indexOfFirst {\n            it::class.isInstance(resizeType)\n        }\n    }\n\n    override suspend fun setSystemBarsVisibility(\n        systemBarsVisibility: SystemBarsVisibility\n    ) = edit {\n        it[SYSTEM_BARS_VISIBILITY] = systemBarsVisibility.ordinal\n    }\n\n    override suspend fun toggleIsSystemBarsVisibleBySwipe() = toggle(\n        key = IS_SYSTEM_BARS_VISIBLE_BY_SWIPE,\n        defaultValue = default.isSystemBarsVisibleBySwipe\n    )\n\n    override suspend fun setInitialOcrMode(mode: Int) = edit {\n        it[INITIAL_OCR_MODE] = mode\n    }\n\n    override suspend fun toggleUseCompactSelectorsLayout() = toggle(\n        key = USE_COMPACT_SELECTORS_LAYOUT,\n        defaultValue = default.isCompactSelectorsLayout\n    )\n\n    override suspend fun setMainScreenTitle(title: String) = edit {\n        it[MAIN_SCREEN_TITLE] = title\n    }\n\n    override suspend fun setSliderType(type: SliderType) = edit {\n        it[SLIDER_TYPE] = type.ordinal\n    }\n\n    override suspend fun toggleIsCenterAlignDialogButtons() = toggle(\n        key = CENTER_ALIGN_DIALOG_BUTTONS,\n        defaultValue = default.isCenterAlignDialogButtons\n    )\n\n    override fun isInstalledFromPlayStore(): Boolean = context.isInstalledFromPlayStore()\n\n    override suspend fun toggleSettingsGroupVisibility(\n        key: Int,\n        value: Boolean\n    ) = edit { preferences ->\n        preferences[SETTINGS_GROUP_VISIBILITY] =\n            currentSettings.settingGroupsInitialVisibility.toMutableMap().run {\n                this[key] = value\n                map {\n                    \"${it.key}:${it.value}\"\n                }.toSet()\n            }\n    }\n\n    override suspend fun clearRecentColors() = edit {\n        it[RECENT_COLORS] = emptySet()\n    }\n\n    override suspend fun updateFavoriteColors(\n        colors: List<ColorModel>\n    ) = edit { preferences ->\n        preferences[FAVORITE_COLORS] = colors.joinToString(\"/\") { it.colorInt.toString() }\n    }\n\n    override suspend fun setBackgroundColorForNoAlphaFormats(\n        color: ColorModel\n    ) = edit {\n        it[BACKGROUND_COLOR_FOR_NA_FORMATS] = color.colorInt\n    }\n\n    override suspend fun setFastSettingsSide(side: FastSettingsSide) = edit {\n        it[FAST_SETTINGS_SIDE] = side.ordinal\n    }\n\n    override suspend fun setChecksumTypeForFilename(type: HashingType?) = toggleFilenameBehavior(\n        behavior = type?.let {\n            FilenameBehavior.Checksum(type)\n        } ?: FilenameBehavior.None()\n    )\n\n    override suspend fun setCustomFonts(fonts: List<DomainFontFamily.Custom>) = edit {\n        it[CUSTOM_FONTS] = fonts.map(DomainFontFamily::asString).toSet()\n    }\n\n    override suspend fun importCustomFont(\n        uri: String\n    ): DomainFontFamily.Custom? = withContext(ioDispatcher) {\n        val font = context.contentResolver.openInputStream(uri.toUri())?.use {\n            it.buffered().readBytes()\n        } ?: ByteArray(0)\n        val filename = uri.toUri().filename(context) ?: \"font${Random.nextInt()}.ttf\"\n\n        val directory = File(context.filesDir, \"customFonts\").apply {\n            mkdir()\n        }\n        val file = File(directory, filename).apply {\n            if (exists()) {\n                val fontToRemove = DomainFontFamily.Custom(\n                    name = nameWithoutExtension.replace(\"[:\\\\-_.,]\".toRegex(), \" \"),\n                    filePath = absolutePath\n                )\n                removeCustomFont(fontToRemove)\n            }\n            delete()\n            createNewFile()\n\n            outputStream().use {\n                writeBytes(font)\n            }\n        }\n\n        val typeface = runCatching {\n            Typeface.createFromFile(file)\n        }.getOrNull()\n\n        if (typeface == null) {\n            file.delete()\n            return@withContext null\n        }\n\n        DomainFontFamily.Custom(\n            name = file.nameWithoutExtension.replace(\"[:\\\\-_.,]\".toRegex(), \" \"),\n            filePath = file.absolutePath\n        ).also {\n            setCustomFonts(currentSettings.customFonts + it)\n        }\n    }\n\n    override suspend fun removeCustomFont(\n        font: DomainFontFamily.Custom\n    ) = withContext(ioDispatcher) {\n        File(font.filePath).delete()\n\n        setCustomFonts(currentSettings.customFonts - font)\n    }\n\n    override suspend fun createCustomFontsExport(): String? = withContext(ioDispatcher) {\n        shareProvider.get().cacheData(\n            writeData = { writeable ->\n                writeable.outputStream().createZip { zip ->\n                    File(context.filesDir, \"customFonts\").listFiles()?.forEach { file ->\n                        zip.putEntry(\n                            name = file.name,\n                            input = FileInputStream(file)\n                        )\n                    }\n                }\n            },\n            filename = \"fonts_export.zip\"\n        )\n    }\n\n    override suspend fun toggleEnableToolExitConfirmation() = toggle(\n        key = ENABLE_TOOL_EXIT_CONFIRMATION,\n        defaultValue = default.enableToolExitConfirmation\n    )\n\n    override suspend fun toggleCustomAsciiGradient(gradient: String) = edit {\n        it[ASCII_CUSTOM_GRADIENTS] = (it[ASCII_CUSTOM_GRADIENTS] ?: emptySet()).toggle(gradient)\n    }\n\n    override suspend fun setSnowfallMode(snowfallMode: SnowfallMode) = edit {\n        it[SNOWFALL_MODE] = snowfallMode.ordinal\n    }\n\n    override suspend fun setDefaultImageFormat(imageFormat: ImageFormat?) = edit {\n        if (imageFormat == null) {\n            it[DEFAULT_IMAGE_FORMAT] = \"\"\n        } else {\n            it[DEFAULT_IMAGE_FORMAT] = imageFormat.title\n        }\n    }\n\n    override suspend fun setDefaultQuality(quality: Quality) = edit {\n        jsonParser.toJson(quality, Quality::class.java)?.apply {\n            it[DEFAULT_QUALITY] = this\n        }\n    }\n\n    override suspend fun setShapesType(shapeType: ShapeType) = edit {\n        jsonParser.toJson(shapeType, ShapeType::class.java)?.apply {\n            it[SHAPES_TYPE] = this\n        }\n    }\n\n    override suspend fun setFilenamePattern(pattern: String?) = edit {\n        it[FILENAME_PATTERN] = pattern.orEmpty()\n    }\n\n    override suspend fun setFlingType(type: FlingType) = edit {\n        it[FLING_TYPE] = type.ordinal\n    }\n\n    override suspend fun setHiddenForShareScreens(data: List<Int>) = edit { preferences ->\n        preferences[HIDDEN_FOR_SHARE_SCREENS] = data.joinToString(\"/\") { it.toString() }\n    }\n\n    override suspend fun toggleKeepDateTime() = toggle(\n        key = KEEP_DATE_TIME,\n        defaultValue = default.keepDateTime\n    )\n\n    override suspend fun toggleEnableBackgroundColorForAlphaFormats() = toggle(\n        key = ENABLE_BACKGROUND_COLOR_FOR_ALPHA_FORMATS,\n        defaultValue = default.enableBackgroundColorForAlphaFormats\n    )\n\n    private suspend fun toggleFilenameBehavior(\n        behavior: FilenameBehavior\n    ) = edit {\n        val useToggle = behavior is FilenameBehavior.Checksum\n                || !currentSettings.filenameBehavior::class.isInstance(behavior)\n\n        if (useToggle) {\n            it[FILENAME_BEHAVIOR] =\n                jsonParser.toJson(behavior, FilenameBehavior::class.java).orEmpty()\n        } else {\n            it[FILENAME_BEHAVIOR] = \"\"\n        }\n    }\n\n    private fun MutablePreferences.toggle(\n        key: Preferences.Key<Boolean>,\n        defaultValue: Boolean,\n    ) {\n        val value = this[key] ?: defaultValue\n        this[key] = !value\n    }\n\n    private suspend fun toggle(\n        key: Preferences.Key<Boolean>,\n        defaultValue: Boolean,\n    ) = edit {\n        it.toggle(\n            key = key,\n            defaultValue = defaultValue\n        )\n    }\n\n    private suspend fun edit(\n        transform: suspend (MutablePreferences) -> Unit\n    ) {\n        dataStore.edit(transform)\n    }\n\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/data/ContextUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.data\n\nimport android.content.Context\nimport android.net.Uri\nimport androidx.datastore.preferences.core.PreferencesSerializer\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.resources.R\nimport kotlinx.coroutines.coroutineScope\nimport okio.buffer\nimport okio.source\nimport java.io.ByteArrayInputStream\nimport java.io.File\n\ninternal suspend fun Context.restoreDatastore(\n    fileName: String,\n    backupUri: Uri,\n    onFailure: (Throwable) -> Unit,\n    onSuccess: suspend () -> Unit\n) = coroutineScope {\n    runSuspendCatching {\n        contentResolver.openInputStream(backupUri)?.use { input ->\n            val bytes = input.readBytes()\n            restoreDatastore(\n                fileName = fileName,\n                backupData = bytes,\n                onFailure = onFailure,\n                onSuccess = onSuccess\n            )\n        }\n    }.onFailure(onFailure).onSuccess {\n        onSuccess()\n    }\n}\n\ninternal suspend fun Context.restoreDatastore(\n    fileName: String,\n    backupData: ByteArray,\n    onFailure: (Throwable) -> Unit,\n    onSuccess: suspend () -> Unit\n) = coroutineScope {\n    runSuspendCatching {\n\n        runSuspendCatching {\n            PreferencesSerializer.readFrom(ByteArrayInputStream(backupData).source().buffer())\n        }.onFailure {\n            onFailure(Throwable(getString(R.string.corrupted_file_or_not_a_backup)))\n            return@coroutineScope\n        }\n\n        File(\n            filesDir,\n            \"datastore/${fileName}.preferences_pb\"\n        ).outputStream().use {\n            ByteArrayInputStream(backupData).copyTo(it)\n        }\n    }.onFailure(onFailure).onSuccess {\n        onSuccess()\n    }\n}\n\ninternal suspend fun Context.obtainDatastoreData(\n    fileName: String\n) = coroutineScope {\n    File(filesDir, \"datastore/${fileName}.preferences_pb\").readBytes()\n}\n\ninternal suspend fun Context.resetDatastore(\n    fileName: String\n) = coroutineScope {\n    File(\n        filesDir,\n        \"datastore/${fileName}.preferences_pb\"\n    ).apply {\n        delete()\n        createNewFile()\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/data/keys/MapToSettingsState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.data.keys\n\nimport androidx.datastore.preferences.core.Preferences\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.image.model.ScaleColorSpace\nimport com.t8rin.imagetoolbox.core.domain.json.JsonParser\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ColorHarmonizer\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.DomainFontFamily\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.NightMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType\n\ninternal fun Preferences.toSettingsState(\n    default: SettingsState,\n    jsonParser: JsonParser\n): SettingsState = SettingsState(\n    nightMode = NightMode.fromOrdinal(this[NIGHT_MODE]) ?: default.nightMode,\n    isDynamicColors = this[DYNAMIC_COLORS] ?: default.isDynamicColors,\n    isAmoledMode = this[AMOLED_MODE] ?: default.isAmoledMode,\n    appColorTuple = this[APP_COLOR_TUPLE] ?: default.appColorTuple,\n    borderWidth = this[BORDER_WIDTH] ?: default.borderWidth,\n    showUpdateDialogOnStartup = this[SHOW_UPDATE_DIALOG]\n        ?: default.showUpdateDialogOnStartup,\n    selectedEmoji = this[SELECTED_EMOJI_INDEX] ?: default.selectedEmoji,\n    screenList = this[SCREEN_ORDER]?.split(\"/\")?.mapNotNull {\n        it.toIntOrNull()\n    }?.takeIf { it.isNotEmpty() } ?: default.screenList,\n    emojisCount = this[EMOJI_COUNT] ?: default.emojisCount,\n    clearCacheOnLaunch = this[AUTO_CACHE_CLEAR] ?: default.clearCacheOnLaunch,\n    groupOptionsByTypes = this[GROUP_OPTIONS_BY_TYPE] ?: default.groupOptionsByTypes,\n    addSequenceNumber = this[ADD_SEQ_NUM_TO_FILENAME] ?: default.addSequenceNumber,\n    saveFolderUri = this[SAVE_FOLDER_URI],\n    presets = Preset.createListFromInts(this[PRESETS]) ?: default.presets,\n    colorTupleList = this[COLOR_TUPLES],\n    allowChangeColorByImage = this[ALLOW_IMAGE_MONET] ?: default.allowChangeColorByImage,\n    picturePickerModeInt = this[IMAGE_PICKER_MODE] ?: default.picturePickerModeInt,\n    fabAlignment = this[FAB_ALIGNMENT] ?: default.fabAlignment,\n    filenamePrefix = this[FILENAME_PREFIX] ?: default.filenamePrefix,\n    addSizeInFilename = this[ADD_SIZE_TO_FILENAME] ?: default.addSizeInFilename,\n    addOriginalFilename = this[ADD_ORIGINAL_NAME_TO_FILENAME]\n        ?: default.addOriginalFilename,\n    font = DomainFontFamily.fromString(this[SELECTED_FONT]) ?: default.font,\n    fontScale = (this[FONT_SCALE] ?: 1f).takeIf { it > 0f },\n    allowCollectCrashlytics = this[ALLOW_CRASHLYTICS] ?: default.allowCollectCrashlytics,\n    allowCollectAnalytics = this[ALLOW_ANALYTICS] ?: default.allowCollectAnalytics,\n    allowBetas = this[ALLOW_BETAS] ?: default.allowBetas,\n    drawContainerShadows = this[DRAW_CONTAINER_SHADOWS]\n        ?: default.drawContainerShadows,\n    drawFabShadows = this[DRAW_FAB_SHADOWS]\n        ?: default.drawFabShadows,\n    drawSwitchShadows = this[DRAW_SWITCH_SHADOWS]\n        ?: default.drawSwitchShadows,\n    drawSliderShadows = this[DRAW_SLIDER_SHADOWS]\n        ?: default.drawSliderShadows,\n    drawButtonShadows = this[DRAW_BUTTON_SHADOWS]\n        ?: default.drawButtonShadows,\n    drawAppBarShadows = this[DRAW_APPBAR_SHADOWS]\n        ?: default.drawAppBarShadows,\n    appOpenCount = this[APP_OPEN_COUNT] ?: default.appOpenCount,\n    aspectRatios = default.aspectRatios,\n    lockDrawOrientation = this[LOCK_DRAW_ORIENTATION] ?: default.lockDrawOrientation,\n    themeContrastLevel = this[THEME_CONTRAST_LEVEL] ?: default.themeContrastLevel,\n    themeStyle = this[THEME_STYLE] ?: default.themeStyle,\n    isInvertThemeColors = this[INVERT_THEME] ?: default.isInvertThemeColors,\n    screensSearchEnabled = this[SCREEN_SEARCH_ENABLED] ?: default.screensSearchEnabled,\n    copyToClipboardMode = this[COPY_TO_CLIPBOARD_MODE]?.let {\n        CopyToClipboardMode.fromInt(it)\n    } ?: default.copyToClipboardMode,\n    hapticsStrength = this[VIBRATION_STRENGTH] ?: default.hapticsStrength,\n    filenameSuffix = this[FILENAME_SUFFIX] ?: default.filenameSuffix,\n    defaultImageScaleMode = this.toDefaultImageScaleMode(default),\n    magnifierEnabled = this[MAGNIFIER_ENABLED] ?: default.magnifierEnabled,\n    exifWidgetInitialState = this[EXIF_WIDGET_INITIAL_STATE]\n        ?: default.exifWidgetInitialState,\n    initialOcrCodes = this[INITIAL_OCR_CODES]?.split(\"+\") ?: default.initialOcrCodes,\n    screenListWithMaxBrightnessEnforcement = this[SCREENS_WITH_BRIGHTNESS_ENFORCEMENT]?.split(\n        \"/\"\n    )?.mapNotNull {\n        it.toIntOrNull()\n    } ?: default.screenListWithMaxBrightnessEnforcement,\n    isConfettiEnabled = this[CONFETTI_ENABLED] ?: default.isConfettiEnabled,\n    isSecureMode = this[SECURE_MODE] ?: default.isSecureMode,\n    useRandomEmojis = this[USE_RANDOM_EMOJIS] ?: default.useRandomEmojis,\n    iconShape = (this[ICON_SHAPE] ?: default.iconShape)?.takeIf { it >= 0 },\n    useEmojiAsPrimaryColor = this[USE_EMOJI_AS_PRIMARY_COLOR]\n        ?: default.useEmojiAsPrimaryColor,\n    dragHandleWidth = this[DRAG_HANDLE_WIDTH] ?: default.dragHandleWidth,\n    confettiType = this[CONFETTI_TYPE] ?: default.confettiType,\n    allowAutoClipboardPaste = this[ALLOW_AUTO_PASTE] ?: default.allowAutoClipboardPaste,\n    confettiColorHarmonizer = this[CONFETTI_HARMONIZER]?.let {\n        ColorHarmonizer.fromInt(it)\n    } ?: default.confettiColorHarmonizer,\n    confettiHarmonizationLevel = this[CONFETTI_HARMONIZATION_LEVEL]\n        ?: default.confettiHarmonizationLevel,\n    skipImagePicking = this[SKIP_IMAGE_PICKING]\n        ?: default.skipImagePicking,\n    generatePreviews = this[GENERATE_PREVIEWS]\n        ?: default.generatePreviews,\n    showSettingsInLandscape = this[SHOW_SETTINGS_IN_LANDSCAPE]\n        ?: default.showSettingsInLandscape,\n    useFullscreenSettings = this[USE_FULLSCREEN_SETTINGS]\n        ?: default.useFullscreenSettings,\n    switchType = this[SWITCH_TYPE]?.let {\n        SwitchType.fromInt(it)\n    } ?: default.switchType,\n    defaultDrawLineWidth = this[DEFAULT_DRAW_LINE_WIDTH]\n        ?: default.defaultDrawLineWidth,\n    oneTimeSaveLocations = this[ONE_TIME_SAVE_LOCATIONS]?.split(\", \")\n        ?.mapNotNull { string ->\n            OneTimeSaveLocation.fromString(string)?.takeIf {\n                it.uri.isNotEmpty() && it.date != null\n            }\n        }\n        ?.sortedWith(compareBy(OneTimeSaveLocation::count, OneTimeSaveLocation::date))\n        ?.reversed()\n        ?: default.oneTimeSaveLocations,\n    openEditInsteadOfPreview = this[OPEN_EDIT_INSTEAD_OF_PREVIEW]\n        ?: default.openEditInsteadOfPreview,\n    canEnterPresetsByTextField = this[CAN_ENTER_PRESETS_BY_TEXT_FIELD]\n        ?: default.canEnterPresetsByTextField,\n    donateDialogOpenCount = this[DONATE_DIALOG_OPEN_COUNT]\n        ?: default.donateDialogOpenCount,\n    colorBlindType = this[COLOR_BLIND_TYPE]?.let {\n        if (it < 0) null\n        else it\n    } ?: default.colorBlindType,\n    favoriteScreenList = this[FAVORITE_SCREENS]?.split(\"/\")?.mapNotNull {\n        it.toIntOrNull()\n    }?.takeIf { it.isNotEmpty() } ?: default.favoriteScreenList,\n    isLinkPreviewEnabled = this[IS_LINK_PREVIEW_ENABLED] ?: default.isLinkPreviewEnabled,\n    defaultDrawColor = this[DEFAULT_DRAW_COLOR]?.let { ColorModel(it) }\n        ?: default.defaultDrawColor,\n    defaultDrawPathMode = this[DEFAULT_DRAW_PATH_MODE] ?: default.defaultDrawPathMode,\n    addTimestampToFilename = this[ADD_TIMESTAMP_TO_FILENAME]\n        ?: default.addTimestampToFilename,\n    useFormattedFilenameTimestamp = this[USE_FORMATTED_TIMESTAMP]\n        ?: default.useFormattedFilenameTimestamp,\n    favoriteColors = this[FAVORITE_COLORS]?.split(\"/\")?.mapNotNull { color ->\n        color.toIntOrNull()?.let { ColorModel(it) }\n    } ?: default.favoriteColors,\n    defaultResizeType = this[DEFAULT_RESIZE_TYPE]?.let {\n        ResizeType.entries.getOrNull(it)\n    } ?: default.defaultResizeType,\n    systemBarsVisibility = SystemBarsVisibility.fromOrdinal(this[SYSTEM_BARS_VISIBILITY])\n        ?: default.systemBarsVisibility,\n    isSystemBarsVisibleBySwipe = this[IS_SYSTEM_BARS_VISIBLE_BY_SWIPE]\n        ?: default.isSystemBarsVisibleBySwipe,\n    isCompactSelectorsLayout = this[USE_COMPACT_SELECTORS_LAYOUT]\n        ?: default.isCompactSelectorsLayout,\n    mainScreenTitle = this[MAIN_SCREEN_TITLE] ?: default.mainScreenTitle,\n    sliderType = this[SLIDER_TYPE]?.let {\n        SliderType.fromInt(it)\n    } ?: default.sliderType,\n    isCenterAlignDialogButtons = this[CENTER_ALIGN_DIALOG_BUTTONS]\n        ?: default.isCenterAlignDialogButtons,\n    fastSettingsSide = this[FAST_SETTINGS_SIDE]?.let {\n        FastSettingsSide.fromOrdinal(it)\n    } ?: default.fastSettingsSide,\n    settingGroupsInitialVisibility = this[SETTINGS_GROUP_VISIBILITY].toSettingGroupsInitialVisibility(\n        default\n    ),\n    customFonts = this[CUSTOM_FONTS].toCustomFonts(),\n    enableToolExitConfirmation = this[ENABLE_TOOL_EXIT_CONFIRMATION]\n        ?: default.enableToolExitConfirmation,\n    recentColors = this[RECENT_COLORS]?.mapNotNull { color ->\n        color.toIntOrNull()?.let { ColorModel(it) }\n    } ?: default.recentColors,\n    backgroundForNoAlphaImageFormats = this[BACKGROUND_COLOR_FOR_NA_FORMATS]?.let { ColorModel(it) }\n        ?: default.backgroundForNoAlphaImageFormats,\n    addPresetInfoToFilename = this[ADD_PRESET_TO_FILENAME] ?: default.addPresetInfoToFilename,\n    addImageScaleModeInfoToFilename = this[ADD_SCALE_MODE_TO_FILENAME]\n        ?: default.addImageScaleModeInfoToFilename,\n    allowSkipIfLarger = this[ALLOW_SKIP_IF_LARGER]\n        ?: default.allowSkipIfLarger,\n    customAsciiGradients = this[ASCII_CUSTOM_GRADIENTS]\n        ?: default.customAsciiGradients,\n    isScreenSelectionLauncherMode = this[IS_LAUNCHER_MODE] ?: default.isScreenSelectionLauncherMode,\n    isTelegramGroupOpened = this[IS_TELEGRAM_GROUP_OPENED] ?: default.isTelegramGroupOpened,\n    initialOcrMode = this[INITIAL_OCR_MODE] ?: default.initialOcrMode,\n    spotHealMode = this[SPOT_HEAL_MODE] ?: default.spotHealMode,\n    snowfallMode = this[SNOWFALL_MODE]?.let { SnowfallMode.entries[it] } ?: default.snowfallMode,\n    defaultImageFormat = this[DEFAULT_IMAGE_FORMAT].let { title ->\n        if (title.isNullOrBlank()) {\n            null\n        } else {\n            ImageFormat.entries.find { it.title == title } ?: default.defaultImageFormat\n        }\n    },\n    defaultQuality = this[DEFAULT_QUALITY]?.let {\n        jsonParser.fromJson(\n            json = it,\n            type = Quality::class.java\n        )\n    } ?: default.defaultQuality,\n    shapesType = this[SHAPES_TYPE]?.let {\n        jsonParser.fromJson(\n            json = it,\n            type = ShapeType::class.java\n        )\n    } ?: default.shapesType,\n    filenamePattern = this[FILENAME_PATTERN]?.takeIf { it.isNotBlank() } ?: default.filenamePattern,\n    filenameBehavior = this[FILENAME_BEHAVIOR]?.let {\n        jsonParser.fromJson(\n            json = it,\n            type = FilenameBehavior::class.java\n        )\n    } ?: default.filenameBehavior,\n    flingType = this[FLING_TYPE]?.let {\n        FlingType.entries[it]\n    } ?: default.flingType,\n    hiddenForShareScreens = this[HIDDEN_FOR_SHARE_SCREENS]?.split(\n        \"/\"\n    )?.mapNotNull {\n        it.toIntOrNull()\n    } ?: default.hiddenForShareScreens,\n    keepDateTime = this[KEEP_DATE_TIME] ?: default.keepDateTime,\n    enableBackgroundColorForAlphaFormats = this[ENABLE_BACKGROUND_COLOR_FOR_ALPHA_FORMATS]\n        ?: default.enableBackgroundColorForAlphaFormats\n)\n\nprivate fun Preferences.toDefaultImageScaleMode(default: SettingsState): ImageScaleMode {\n    val scaleMode = this[IMAGE_SCALE_MODE]?.let {\n        ImageScaleMode.fromInt(it)\n    } ?: default.defaultImageScaleMode\n\n    val scaleColorSpace = this[IMAGE_SCALE_COLOR_SPACE]?.let {\n        ScaleColorSpace.fromOrdinal(it)\n    } ?: default.defaultImageScaleMode.scaleColorSpace\n\n    return scaleMode.copy(scaleColorSpace)\n}\n\nprivate fun Set<String>?.toSettingGroupsInitialVisibility(\n    default: SettingsState\n): Map<Int, Boolean> =\n    this?.associate { key ->\n        key.split(\":\").let { it[0].toInt() to it[1].toBoolean() }\n    } ?: default.settingGroupsInitialVisibility\n\nprivate fun Set<String>?.toCustomFonts(): List<DomainFontFamily.Custom> = this?.map {\n    val split = it.split(\":\")\n    DomainFontFamily.Custom(\n        name = split[0],\n        filePath = split[1]\n    )\n} ?: emptyList()"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/data/keys/SettingKeys.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.data.keys\n\nimport androidx.datastore.preferences.core.booleanPreferencesKey\nimport androidx.datastore.preferences.core.doublePreferencesKey\nimport androidx.datastore.preferences.core.floatPreferencesKey\nimport androidx.datastore.preferences.core.intPreferencesKey\nimport androidx.datastore.preferences.core.stringPreferencesKey\nimport androidx.datastore.preferences.core.stringSetPreferencesKey\n\ninternal val SAVE_FOLDER_URI = stringPreferencesKey(\"saveFolder\")\ninternal val NIGHT_MODE = intPreferencesKey(\"nightMode\")\ninternal val DYNAMIC_COLORS = booleanPreferencesKey(\"dynamicColors\")\ninternal val ALLOW_IMAGE_MONET = booleanPreferencesKey(\"imageMonet\")\ninternal val AMOLED_MODE = booleanPreferencesKey(\"amoledMode\")\ninternal val APP_COLOR_TUPLE = stringPreferencesKey(\"appColorTuple\")\ninternal val BORDER_WIDTH = floatPreferencesKey(\"borderWidth\")\ninternal val PRESETS = stringPreferencesKey(\"presets\")\ninternal val COLOR_TUPLES = stringPreferencesKey(\"color_tuples\")\ninternal val FAB_ALIGNMENT = intPreferencesKey(\"alignment\")\ninternal val SHOW_UPDATE_DIALOG = booleanPreferencesKey(\"showDialog\")\ninternal val FILENAME_PREFIX = stringPreferencesKey(\"filename\")\ninternal val SELECTED_EMOJI_INDEX = intPreferencesKey(\"emoji\")\ninternal val ADD_SIZE_TO_FILENAME = booleanPreferencesKey(\"add_size\")\ninternal val IMAGE_PICKER_MODE = intPreferencesKey(\"picker_mode\")\ninternal val SCREEN_ORDER = stringPreferencesKey(\"order\")\ninternal val EMOJI_COUNT = intPreferencesKey(\"em_count\")\ninternal val ADD_ORIGINAL_NAME_TO_FILENAME = booleanPreferencesKey(\"ADD_ORIGINAL_NAME\")\ninternal val ADD_SEQ_NUM_TO_FILENAME = booleanPreferencesKey(\"ADD_SEQ_NUM\")\ninternal val AUTO_CACHE_CLEAR = booleanPreferencesKey(\"auto_clear\")\ninternal val GROUP_OPTIONS_BY_TYPE = booleanPreferencesKey(\"group_options\")\ninternal val SELECTED_FONT = stringPreferencesKey(\"SELECTED_FONT\")\ninternal val FONT_SCALE = floatPreferencesKey(\"font_scale\")\ninternal val ALLOW_CRASHLYTICS = booleanPreferencesKey(\"allow_crashlytics\")\ninternal val ALLOW_ANALYTICS = booleanPreferencesKey(\"allow_analytics\")\ninternal val ALLOW_BETAS = booleanPreferencesKey(\"allow_betas\")\ninternal val DRAW_CONTAINER_SHADOWS = booleanPreferencesKey(\"ALLOW_SHADOWS_INSTEAD_OF_BORDERS\")\ninternal val APP_OPEN_COUNT = intPreferencesKey(\"APP_OPEN_COUNT\")\ninternal val LOCK_DRAW_ORIENTATION = booleanPreferencesKey(\"LOCK_DRAW_ORIENTATION\")\ninternal val THEME_CONTRAST_LEVEL = doublePreferencesKey(\"THEME_CONTRAST_LEVEL\")\ninternal val THEME_STYLE = intPreferencesKey(\"THEME_STYLE\")\ninternal val INVERT_THEME = booleanPreferencesKey(\"INVERT_THEME\")\ninternal val SCREEN_SEARCH_ENABLED = booleanPreferencesKey(\"SCREEN_SEARCH_ENABLED\")\ninternal val DRAW_BUTTON_SHADOWS = booleanPreferencesKey(\"DRAW_BUTTON_SHADOWS\")\ninternal val DRAW_FAB_SHADOWS = booleanPreferencesKey(\"DRAW_FAB_SHADOWS\")\ninternal val DRAW_SWITCH_SHADOWS = booleanPreferencesKey(\"DRAW_SWITCH_SHADOWS\")\ninternal val DRAW_SLIDER_SHADOWS = booleanPreferencesKey(\"DRAW_SLIDER_SHADOWS\")\ninternal val DRAW_APPBAR_SHADOWS = booleanPreferencesKey(\"DRAW_APPBAR_SHADOWS\")\ninternal val COPY_TO_CLIPBOARD_MODE = intPreferencesKey(\"COPY_TO_CLIPBOARD_MODE\")\ninternal val VIBRATION_STRENGTH = intPreferencesKey(\"VIBRATION_STRENGTH\")\ninternal val FILENAME_SUFFIX = stringPreferencesKey(\"FILENAME_SUFFIX\")\ninternal val IMAGE_SCALE_MODE = intPreferencesKey(\"IMAGE_SCALE_MODE\")\ninternal val MAGNIFIER_ENABLED = booleanPreferencesKey(\"MAGNIFIER_ENABLED\")\ninternal val EXIF_WIDGET_INITIAL_STATE = booleanPreferencesKey(\"EXIF_WIDGET_INITIAL_STATE\")\ninternal val INITIAL_OCR_CODES = stringPreferencesKey(\"INITIAL_OCR_CODES\")\ninternal val SCREENS_WITH_BRIGHTNESS_ENFORCEMENT =\n    stringPreferencesKey(\"SCREENS_WITH_BRIGHTNESS_ENFORCEMENT\")\ninternal val CONFETTI_ENABLED = booleanPreferencesKey(\"CONFETTI_ENABLED\")\ninternal val SECURE_MODE = booleanPreferencesKey(\"SECURE_MODE\")\ninternal val USE_RANDOM_EMOJIS = booleanPreferencesKey(\"USE_RANDOM_EMOJIS\")\ninternal val ICON_SHAPE = intPreferencesKey(\"ICON_SHAPE\")\ninternal val USE_EMOJI_AS_PRIMARY_COLOR = booleanPreferencesKey(\"USE_EMOJI_AS_PRIMARY_COLOR\")\ninternal val DRAG_HANDLE_WIDTH = intPreferencesKey(\"DRAG_HANDLE_WIDTH\")\ninternal val CONFETTI_TYPE = intPreferencesKey(\"CONFETTI_TYPE\")\ninternal val ALLOW_AUTO_PASTE = booleanPreferencesKey(\"ALLOW_AUTO_PASTE\")\ninternal val CONFETTI_HARMONIZER = intPreferencesKey(\"CONFETTI_HARMONIZER\")\ninternal val CONFETTI_HARMONIZATION_LEVEL = floatPreferencesKey(\"CONFETTI_HARMONIZATION_LEVEL\")\ninternal val SKIP_IMAGE_PICKING = booleanPreferencesKey(\"SKIP_IMAGE_PICKER\")\ninternal val GENERATE_PREVIEWS = booleanPreferencesKey(\"GENERATE_PREVIEWS\")\ninternal val SHOW_SETTINGS_IN_LANDSCAPE = booleanPreferencesKey(\"SHOW_SETTINGS_IN_LANDSCAPE\")\ninternal val USE_FULLSCREEN_SETTINGS = booleanPreferencesKey(\"USE_FULLSCREEN_SETTINGS\")\ninternal val SWITCH_TYPE = intPreferencesKey(\"SWITCH_TYPE\")\ninternal val DEFAULT_DRAW_LINE_WIDTH = floatPreferencesKey(\"DEFAULT_DRAW_LINE_WIDTH\")\ninternal val ONE_TIME_SAVE_LOCATIONS = stringPreferencesKey(\"ONE_TIME_SAVE_LOCATIONS\")\ninternal val OPEN_EDIT_INSTEAD_OF_PREVIEW = booleanPreferencesKey(\"OPEN_EDIT_INSTEAD_OF_PREVIEW\")\ninternal val CAN_ENTER_PRESETS_BY_TEXT_FIELD =\n    booleanPreferencesKey(\"CAN_ENTER_PRESETS_BY_TEXT_FIELD\")\ninternal val DONATE_DIALOG_OPEN_COUNT = intPreferencesKey(\"DONATE_DIALOG_OPEN_COUNT\")\ninternal val COLOR_BLIND_TYPE = intPreferencesKey(\"COLOR_BLIND_TYPE\")\ninternal val FAVORITE_SCREENS = stringPreferencesKey(\"FAVORITE_SCREENS\")\ninternal val IS_LINK_PREVIEW_ENABLED = booleanPreferencesKey(\"IS_LINK_PREVIEW_ENABLED\")\ninternal val DEFAULT_DRAW_COLOR = intPreferencesKey(\"DEFAULT_DRAW_COLOR\")\ninternal val DEFAULT_DRAW_PATH_MODE = intPreferencesKey(\"DEFAULT_DRAW_PATH_MODE\")\ninternal val ADD_TIMESTAMP_TO_FILENAME = booleanPreferencesKey(\"ADD_TIMESTAMP_TO_FILENAME\")\ninternal val USE_FORMATTED_TIMESTAMP = booleanPreferencesKey(\"USE_FORMATTED_TIMESTAMP\")\ninternal val IS_TELEGRAM_GROUP_OPENED = booleanPreferencesKey(\"IS_TELEGRAM_GROUP_OPENED\")\ninternal val DEFAULT_RESIZE_TYPE = intPreferencesKey(\"DEFAULT_RESIZE_TYPE\")\ninternal val SYSTEM_BARS_VISIBILITY = intPreferencesKey(\"SYSTEM_BARS_VISIBILITY\")\ninternal val IS_SYSTEM_BARS_VISIBLE_BY_SWIPE =\n    booleanPreferencesKey(\"IS_SYSTEM_BARS_VISIBLE_BY_SWIPE\")\ninternal val INITIAL_OCR_MODE = intPreferencesKey(\"INITIAL_OCR_MODE\")\ninternal val USE_COMPACT_SELECTORS_LAYOUT = booleanPreferencesKey(\"USE_COMPACT_SELECTORS_LAYOUT\")\ninternal val MAIN_SCREEN_TITLE = stringPreferencesKey(\"MAIN_SCREEN_TITLE\")\ninternal val SLIDER_TYPE = intPreferencesKey(\"SLIDER_TYPE\")\ninternal val CENTER_ALIGN_DIALOG_BUTTONS = booleanPreferencesKey(\"CENTER_ALIGN_DIALOG_BUTTONS\")\ninternal val FAST_SETTINGS_SIDE = intPreferencesKey(\"FAST_SETTINGS_SIDE\")\ninternal val SETTINGS_GROUP_VISIBILITY = stringSetPreferencesKey(\"SETTINGS_GROUP_VISIBILITY\")\ninternal val CUSTOM_FONTS = stringSetPreferencesKey(\"CUSTOM_FONTS\")\ninternal val ENABLE_TOOL_EXIT_CONFIRMATION = booleanPreferencesKey(\"ENABLE_TOOL_EXIT_CONFIRMATION\")\ninternal val RECENT_COLORS = stringSetPreferencesKey(\"RECENT_COLORS\")\ninternal val FAVORITE_COLORS = stringPreferencesKey(\"FAVORITE_COLORS_KEY\")\ninternal val BACKGROUND_COLOR_FOR_NA_FORMATS = intPreferencesKey(\"BACKGROUND_COLOR_FOR_NA_FORMATS\")\ninternal val IMAGE_SCALE_COLOR_SPACE = intPreferencesKey(\"IMAGE_SCALE_COLOR_SPACE\")\ninternal val ADD_PRESET_TO_FILENAME = booleanPreferencesKey(\"ADD_PRESET_TO_FILENAME\")\ninternal val ADD_SCALE_MODE_TO_FILENAME = booleanPreferencesKey(\"ADD_SCALE_MODE_TO_FILENAME\")\ninternal val ALLOW_SKIP_IF_LARGER = booleanPreferencesKey(\"ALLOW_SKIP_IF_LARGER\")\ninternal val ASCII_CUSTOM_GRADIENTS = stringSetPreferencesKey(\"ASCII_CUSTOM_GRADIENTS\")\ninternal val IS_LAUNCHER_MODE = booleanPreferencesKey(\"IS_LAUNCHER_MODE\")\ninternal val SPOT_HEAL_MODE = intPreferencesKey(\"SPOT_HEAL_MODE\")\ninternal val SNOWFALL_MODE = intPreferencesKey(\"SNOWFALL_MODE\")\ninternal val DEFAULT_QUALITY = stringPreferencesKey(\"DEFAULT_QUALITY\")\ninternal val DEFAULT_IMAGE_FORMAT = stringPreferencesKey(\"DEFAULT_IMAGE_FORMAT\")\ninternal val SHAPES_TYPE = stringPreferencesKey(\"SHAPES_TYPE_NEW\")\ninternal val FILENAME_PATTERN = stringPreferencesKey(\"FILENAME_PATTERN\")\ninternal val FILENAME_BEHAVIOR = stringPreferencesKey(\"FILENAME_BEHAVIOR\")\ninternal val FLING_TYPE = intPreferencesKey(\"FLING_TYPE\")\ninternal val HIDDEN_FOR_SHARE_SCREENS =\n    stringPreferencesKey(\"HIDDEN_FOR_SHARE_SCREENS\")\ninternal val KEEP_DATE_TIME =\n    booleanPreferencesKey(\"KEEP_DATE_TIME\")\ninternal val ENABLE_BACKGROUND_COLOR_FOR_ALPHA_FORMATS =\n    booleanPreferencesKey(\"ENABLE_BACKGROUND_COLOR_FOR_ALPHA_FORMATS\")"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/di/SettingsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.di\n\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsInteractor\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.feature.settings.data.AndroidSettingsManager\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface SettingsModule {\n\n    @Singleton\n    @Binds\n    fun provideSettingsManager(\n        repository: AndroidSettingsManager\n    ): SettingsManager\n\n    @Singleton\n    @Binds\n    fun provideSettingsProvider(\n        repository: SettingsManager\n    ): SettingsProvider\n\n    @Singleton\n    @Binds\n    fun provideSettingsInteractor(\n        repository: SettingsManager\n    ): SettingsInteractor\n\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/SettingsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"KotlinConstantConditions\")\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.foundation.lazy.staggeredgrid.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.ArrowBack\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Search\nimport androidx.compose.material.icons.rounded.SearchOff\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.arkivanov.decompose.extensions.compose.subscribeAsState\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.SettingsGroup\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.other.SearchBar\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.isKeyboardVisibleAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.SearchableSettingItem\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.SettingGroupItem\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.SettingItem\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\n\n\n@Composable\nfun SettingsContent(\n    component: SettingsComponent,\n    disableBottomInsets: Boolean = false,\n    appBarNavigationIcon: (@Composable (Boolean, () -> Unit) -> Unit)? = null\n) {\n    val isStandaloneScreen = appBarNavigationIcon == null\n\n    val isUpdateAvailable by component.isUpdateAvailable.subscribeAsState()\n\n    val settingsState = LocalSettingsState.current\n    val layoutDirection = LocalLayoutDirection.current\n    val initialSettingGroups = SettingsGroup.entries\n\n    val searchKeyword = component.searchKeyword\n    var showSearch by rememberSaveable { mutableStateOf(false) }\n\n    val settings = component.filteredSettings\n    val loading = component.isFilteringSettings\n\n    val padding = WindowInsets.navigationBars\n        .union(WindowInsets.displayCutout)\n        .let { insets ->\n            if (disableBottomInsets) {\n                insets.only(\n                    WindowInsetsSides.Horizontal + WindowInsetsSides.Top\n                )\n            } else {\n                insets\n            }\n        }\n        .asPaddingValues()\n        .run {\n            PaddingValues(\n                top = 8.dp,\n                bottom = calculateBottomPadding() + 8.dp,\n                end = calculateEndPadding(layoutDirection) + 8.dp,\n                start = if (isStandaloneScreen) calculateStartPadding(layoutDirection) + 8.dp\n                else 8.dp\n            )\n        }\n\n    val focus = LocalFocusManager.current\n    val isKeyboardVisible by isKeyboardVisibleAsState()\n\n    DisposableEffect(Unit) {\n        onDispose {\n            if (!isKeyboardVisible) {\n                focus.clearFocus()\n            }\n        }\n    }\n\n    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n    Scaffold(\n        modifier = if (isStandaloneScreen) {\n            Modifier\n                .fillMaxSize()\n                .background(MaterialTheme.colorScheme.surface)\n                .nestedScroll(\n                    scrollBehavior.nestedScrollConnection\n                )\n        } else Modifier,\n        topBar = {\n            EnhancedTopAppBar(\n                type = if (isStandaloneScreen) EnhancedTopAppBarType.Large\n                else EnhancedTopAppBarType.Normal,\n                title = {\n                    AnimatedContent(\n                        targetState = showSearch\n                    ) { searching ->\n                        if (!searching) {\n                            Row(\n                                verticalAlignment = Alignment.CenterVertically,\n                                modifier = Modifier.marquee()\n                            ) {\n                                Text(\n                                    text = stringResource(R.string.settings),\n                                    style = if (!isStandaloneScreen) {\n                                        MaterialTheme.typography.titleLarge\n                                    } else LocalTextStyle.current\n                                )\n                                if (isStandaloneScreen) {\n                                    Spacer(modifier = Modifier.width(8.dp))\n                                    TopAppBarEmoji()\n                                }\n                            }\n                        } else {\n                            BackHandler {\n                                component.updateSearchKeyword(\"\")\n                                showSearch = false\n                            }\n                            SearchBar(\n                                searchString = searchKeyword,\n                                onValueChange = component::updateSearchKeyword\n                            )\n                        }\n                    }\n                },\n                actions = {\n                    AnimatedContent(\n                        targetState = showSearch to searchKeyword.isNotEmpty(),\n                        transitionSpec = { fadeIn() + scaleIn() togetherWith fadeOut() + scaleOut() }\n                    ) { (searching, hasSearchKey) ->\n                        EnhancedIconButton(\n                            onClick = {\n                                if (!showSearch) {\n                                    showSearch = true\n                                } else {\n                                    component.updateSearchKeyword(\"\")\n                                }\n                            }\n                        ) {\n                            if (searching && hasSearchKey) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Close,\n                                    contentDescription = stringResource(R.string.close)\n                                )\n                            } else if (!searching) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Search,\n                                    contentDescription = stringResource(R.string.search_here)\n                                )\n                            }\n                        }\n                    }\n                },\n                navigationIcon = {\n                    if (appBarNavigationIcon != null) {\n                        appBarNavigationIcon(showSearch) {\n                            showSearch = false\n                            component.updateSearchKeyword(\"\")\n                        }\n                    } else if (component.onGoBack != null || showSearch) {\n                        EnhancedIconButton(\n                            onClick = {\n                                if (showSearch) {\n                                    showSearch = false\n                                    component.updateSearchKeyword(\"\")\n                                } else {\n                                    component.onGoBack?.invoke()\n                                }\n                            },\n                            containerColor = Color.Transparent\n                        ) {\n                            Icon(\n                                imageVector = Icons.AutoMirrored.Rounded.ArrowBack,\n                                contentDescription = stringResource(R.string.exit)\n                            )\n                        }\n                    }\n                },\n                windowInsets = if (isStandaloneScreen) {\n                    EnhancedTopAppBarDefaults.windowInsets\n                } else {\n                    EnhancedTopAppBarDefaults.windowInsets.only(\n                        WindowInsetsSides.End + WindowInsetsSides.Top\n                    )\n                },\n                colors = if (isStandaloneScreen) {\n                    EnhancedTopAppBarDefaults.colors()\n                } else {\n                    EnhancedTopAppBarDefaults.colors(\n                        containerColor = MaterialTheme.colorScheme.surfaceContainerHigh.blend(\n                            color = MaterialTheme.colorScheme.surfaceContainer,\n                            fraction = 0.5f\n                        )\n                    )\n                },\n                scrollBehavior = if (isStandaloneScreen) {\n                    scrollBehavior\n                } else null\n            )\n        },\n        contentWindowInsets = WindowInsets()\n    ) { contentPadding ->\n        Box(\n            modifier = Modifier.padding(contentPadding)\n        ) {\n            AnimatedContent(\n                targetState = settings,\n                modifier = Modifier\n                    .fillMaxSize()\n                    .clearFocusOnTap(),\n                transitionSpec = {\n                    fadeIn() + scaleIn(initialScale = 0.95f) togetherWith fadeOut() + scaleOut(\n                        targetScale = 0.8f\n                    )\n                }\n            ) { settingsAnimated ->\n                val oneColumn = LocalScreenSize.current.width < 600.dp\n                val spacing = if (searchKeyword.isNotEmpty()) 4.dp\n                else if (isStandaloneScreen) 8.dp\n                else 2.dp\n\n                if (settingsAnimated == null) {\n                    LazyVerticalStaggeredGrid(\n                        contentPadding = padding,\n                        columns = StaggeredGridCells.Adaptive(300.dp),\n                        verticalItemSpacing = spacing,\n                        horizontalArrangement = Arrangement.spacedBy(spacing),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        items(\n                            items = initialSettingGroups,\n                            key = { it.id }\n                        ) { group ->\n                            BoxAnimatedVisibility(\n                                visible = if (group is SettingsGroup.Shadows) {\n                                    settingsState.borderWidth <= 0.dp\n                                } else true\n                            ) {\n                                if (isStandaloneScreen) {\n                                    Column(\n                                        verticalArrangement = Arrangement.spacedBy(4.dp),\n                                        modifier = if (!oneColumn) {\n                                            Modifier.container(\n                                                shape = ShapeDefaults.large,\n                                                resultPadding = 0.dp,\n                                                color = MaterialTheme.colorScheme.surfaceContainerLowest\n                                            )\n                                        } else Modifier\n                                    ) {\n                                        TitleItem(\n                                            modifier = Modifier.padding(\n                                                start = 8.dp,\n                                                end = 8.dp,\n                                                top = 12.dp,\n                                                bottom = 12.dp\n                                            ),\n                                            icon = group.icon,\n                                            text = stringResource(group.titleId),\n                                            iconContainerColor = takeColorFromScheme {\n                                                primary.blend(tertiary, 0.5f)\n                                            },\n                                            iconContentColor = takeColorFromScheme {\n                                                onPrimary.blend(onTertiary, 0.5f)\n                                            }\n                                        )\n                                        Column(\n                                            verticalArrangement = Arrangement.spacedBy(4.dp),\n                                            modifier = Modifier.padding(bottom = 8.dp)\n                                        ) {\n                                            group.settingsList.forEach { setting ->\n                                                SettingItem(\n                                                    setting = setting,\n                                                    component = component,\n                                                    isUpdateAvailable = isUpdateAvailable,\n                                                    containerColor = MaterialTheme.colorScheme.surfaceContainerLow,\n                                                    onNavigateToEasterEgg = {\n                                                        component.onNavigate(Screen.EasterEgg)\n                                                    },\n                                                    onNavigateToSettings = {\n                                                        component.onNavigate(Screen.Settings())\n                                                    },\n                                                    onNavigateToLibrariesInfo = {\n                                                        component.onNavigate(Screen.LibrariesInfo)\n                                                    }\n                                                )\n                                            }\n                                        }\n                                    }\n                                } else {\n                                    SettingGroupItem(\n                                        groupKey = group.id,\n                                        icon = group.icon,\n                                        text = stringResource(group.titleId),\n                                        initialState = group.initialState\n                                    ) {\n                                        Column(\n                                            verticalArrangement = Arrangement.spacedBy(4.dp)\n                                        ) {\n                                            group.settingsList.forEach { setting ->\n                                                SettingItem(\n                                                    setting = setting,\n                                                    component = component,\n                                                    isUpdateAvailable = isUpdateAvailable,\n                                                    onNavigateToEasterEgg = {\n                                                        component.onNavigate(Screen.EasterEgg)\n                                                    },\n                                                    onNavigateToSettings = {\n                                                        component.onNavigate(Screen.Settings())\n                                                    },\n                                                    onNavigateToLibrariesInfo = {\n                                                        component.onNavigate(Screen.LibrariesInfo)\n                                                    }\n                                                )\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                } else if (settingsAnimated.isNotEmpty()) {\n                    LazyVerticalStaggeredGrid(\n                        contentPadding = padding,\n                        columns = StaggeredGridCells.Adaptive(300.dp),\n                        verticalItemSpacing = spacing,\n                        horizontalArrangement = Arrangement.spacedBy(spacing),\n                        flingBehavior = enhancedFlingBehavior()\n                    ) {\n                        itemsIndexed(\n                            items = settingsAnimated,\n                            key = { _, v -> v.hashCode() }\n                        ) { index, (group, setting) ->\n                            SearchableSettingItem(\n                                shape = ShapeDefaults.byIndex(\n                                    index = if (oneColumn) index else -1,\n                                    size = settingsAnimated.size\n                                ),\n                                group = group,\n                                setting = setting,\n                                component = component,\n                                isUpdateAvailable = isUpdateAvailable,\n                                onNavigateToEasterEgg = {\n                                    component.onNavigate(Screen.EasterEgg)\n                                },\n                                onNavigateToSettings = {\n                                    component.onNavigate(Screen.Settings())\n                                },\n                                onNavigateToLibrariesInfo = {\n                                    component.onNavigate(Screen.LibrariesInfo)\n                                }\n                            )\n                        }\n                    }\n                } else {\n                    Column(\n                        modifier = Modifier.fillMaxSize(),\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.Center\n                    ) {\n                        Spacer(Modifier.weight(1f))\n                        Text(\n                            text = stringResource(R.string.nothing_found_by_search),\n                            fontSize = 18.sp,\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier.padding(\n                                start = 24.dp,\n                                end = 24.dp,\n                                top = 8.dp,\n                                bottom = 8.dp\n                            )\n                        )\n                        Icon(\n                            imageVector = Icons.Rounded.SearchOff,\n                            contentDescription = null,\n                            modifier = Modifier\n                                .weight(2f)\n                                .sizeIn(maxHeight = 140.dp, maxWidth = 140.dp)\n                                .fillMaxSize()\n                        )\n                        Spacer(Modifier.weight(1f))\n                    }\n                }\n            }\n            BoxAnimatedVisibility(\n                visible = loading,\n                modifier = Modifier.fillMaxSize(),\n                enter = fadeIn(),\n                exit = fadeOut()\n            ) {\n                Box(\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .background(\n                            MaterialTheme.colorScheme.surfaceDim.copy(0.7f)\n                        ),\n                    contentAlignment = Alignment.Center\n                ) {\n                    EnhancedLoadingIndicator()\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AddFileSizeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ScaleUnbalanced\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AddFileSizeSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        startIcon = Icons.Outlined.ScaleUnbalanced,\n        onClick = {\n            onClick()\n        },\n        title = stringResource(R.string.add_file_size),\n        subtitle = stringResource(R.string.add_file_size_sub),\n        checked = settingsState.addSizeInFilename\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AddImageScaleModeToFilenameSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FitScreen\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AddImageScaleModeToFilenameSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.Companion.padding(horizontal = 8.dp),\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        title = stringResource(R.string.add_image_scale_mode_to_filename),\n        subtitle = stringResource(R.string.add_image_scale_mode_to_filename_sub),\n        checked = settingsState.addImageScaleModeInfoToFilename,\n        startIcon = Icons.Outlined.FitScreen\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AddOriginalFilenameSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Difference\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AddOriginalFilenameSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        modifier = modifier,\n        startIcon = Icons.Outlined.Difference,\n        onClick = {\n            onClick()\n        },\n        title = stringResource(R.string.add_original_filename),\n        subtitle = stringResource(R.string.add_original_filename_sub),\n        checked = settingsState.addOriginalFilename\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AddPresetToFilenameSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.LabelPercent\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AddPresetToFilenameSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.Companion.padding(horizontal = 8.dp),\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        title = stringResource(R.string.add_preset_to_filename),\n        subtitle = stringResource(R.string.add_preset_to_filename_sub),\n        checked = settingsState.addPresetInfoToFilename,\n        startIcon = Icons.Outlined.LabelPercent\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AddTimestampToFilenameSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Timer\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AddTimestampToFilenameSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        title = stringResource(R.string.add_timestamp),\n        subtitle = stringResource(R.string.add_timestamp_sub),\n        checked = settingsState.addTimestampToFilename,\n        startIcon = Icons.Outlined.Timer\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AllowAutoClipboardPasteSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ContentPasteGo\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AllowAutoClipboardPasteSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.auto_paste),\n        subtitle = stringResource(R.string.auto_paste_sub),\n        checked = settingsState.allowAutoClipboardPaste,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.ContentPasteGo\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AllowBetasSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Beta\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AllowBetasSettingItem(\n    onClick: (Boolean) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.allow_betas),\n        subtitle = stringResource(R.string.allow_betas_sub),\n        checked = settingsState.allowBetas,\n        onClick = onClick,\n        startIcon = Icons.Rounded.Beta\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AllowImageMonetSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.WaterDrop\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun AllowImageMonetSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        enabled = !settingsState.isDynamicColors,\n        onDisabledClick = {\n            AppToastHost.showToast(\n                icon = Icons.Outlined.WaterDrop,\n                message = getString(R.string.cannot_use_monet_while_dynamic_colors_applied)\n            )\n        },\n        title = stringResource(R.string.allow_image_monet),\n        subtitle = stringResource(R.string.allow_image_monet_sub),\n        checked = settingsState.allowChangeColorByImage,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.WaterDrop\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AllowSkipIfLargerSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.NextPlan\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AllowSkipIfLargerSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.Companion.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.allow_skip_if_larger),\n        subtitle = stringResource(R.string.allow_skip_if_larger_sub),\n        checked = settingsState.allowSkipIfLarger,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.NextPlan\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AmoledModeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Brightness4\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AmoledModeSettingItem(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.center\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        startIcon = Icons.Outlined.Brightness4,\n        title = stringResource(R.string.amoled_mode),\n        subtitle = stringResource(R.string.amoled_mode_sub),\n        checked = settingsState.isAmoledMode,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AnalyticsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Analytics\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AnalyticsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.analytics),\n        subtitle = stringResource(id = R.string.analytics_sub),\n        startIcon = Icons.Rounded.Analytics,\n        checked = settingsState.allowCollectAnalytics,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AppBarShadowsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.HorizontalSplit\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AppBarShadowsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        enabled = settingsState.borderWidth <= 0.dp,\n        shape = shape,\n        title = stringResource(R.string.app_bars_shadow),\n        subtitle = stringResource(R.string.app_bars_shadow_sub),\n        checked = settingsState.drawAppBarShadows,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.HorizontalSplit\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AuthorSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Forum\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.additional.AuthorLinksSheet\n\n@Composable\nfun AuthorSettingItem(\n    shape: Shape = ShapeDefaults.top\n) {\n    var showAuthorSheet by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceRow(\n        modifier = Modifier.padding(horizontal = 8.dp),\n        color = MaterialTheme.colorScheme.secondaryContainer,\n        title = stringResource(R.string.app_developer),\n        subtitle = stringResource(R.string.app_developer_nick),\n        shape = shape,\n        startIcon = Icons.Outlined.Forum,\n        endContent = {\n            Picture(\n                model = painterResource(id = R.drawable.avatar),\n                modifier = Modifier\n                    .padding(end = 8.dp)\n                    .size(64.dp)\n                    .container(\n                        shape = MaterialStarShape,\n                        resultPadding = 0.dp\n                    ),\n                contentDescription = null\n            )\n        },\n        onClick = { showAuthorSheet = true }\n    )\n    AuthorLinksSheet(\n        visible = showAuthorSheet,\n        onDismiss = { showAuthorSheet = false }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AutoCacheClearSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AutoDelete\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AutoCacheClearSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.auto_cache_clearing),\n        subtitle = stringResource(R.string.auto_cache_clearing_sub),\n        checked = settingsState.clearCacheOnLaunch,\n        startIcon = Icons.Outlined.AutoDelete,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AutoCheckUpdatesSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.NewReleases\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun AutoCheckUpdatesSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.check_updates),\n        subtitle = stringResource(R.string.check_updates_sub),\n        checked = settingsState.showUpdateDialogOnStartup,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.NewReleases\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AutoPinClipboardOnlyClipSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.SaveAs\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n\n@Composable\nfun AutoPinClipboardOnlyClipSettingItem(\n    onClick: (Boolean) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        enabled = settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled,\n        shape = shape,\n        title = stringResource(R.string.only_clip),\n        subtitle = stringResource(R.string.only_clip_sub),\n        checked = settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled.WithoutSaving,\n        onClick = onClick,\n        startIcon = Icons.Outlined.SaveAs\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/AutoPinClipboardSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PushPin\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n\n@Composable\nfun AutoPinClipboardSettingItem(\n    onClick: (Boolean) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.auto_pin),\n        subtitle = stringResource(R.string.auto_pin_sub),\n        checked = settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled,\n        onClick = onClick,\n        startIcon = Icons.Outlined.PushPin\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/BackupSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.UploadFile\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun BackupSettingItem(\n    onCreateBackupFilename: () -> String,\n    onCreateBackup: (Uri) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val backupSavingLauncher = rememberFileCreator(onSuccess = onCreateBackup)\n\n    PreferenceItem(\n        onClick = {\n            backupSavingLauncher.make(onCreateBackupFilename())\n        },\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.backup),\n        subtitle = stringResource(R.string.backup_sub),\n        startIcon = Icons.Outlined.UploadFile\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/BorderThicknessSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.BorderStyle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlinx.coroutines.delay\nimport kotlin.math.roundToInt\n\n@Composable\nfun BorderThicknessSettingItem(\n    onValueChange: (Float) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var value by remember {\n        mutableFloatStateOf(settingsState.borderWidth.value.coerceAtLeast(0f))\n    }\n    LaunchedEffect(value) {\n        delay(500)\n        onValueChange(value)\n    }\n    EnhancedSliderItem(\n        modifier = modifier,\n        shape = shape,\n        valueSuffix = \" Dp\",\n        value = value,\n        title = stringResource(R.string.border_thickness),\n        icon = Icons.Outlined.BorderStyle,\n        onValueChange = {\n            value = (it * 10).roundToInt() / 10f\n        },\n        internalStateTransformation = {\n            (it * 10).roundToInt() / 10f\n        },\n        valueRange = 0f..1.5f,\n        steps = 14\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/BrightnessEnforcementSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.BrightnessHigh\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastAny\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCheckbox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n\n@Composable\nfun BrightnessEnforcementSettingItem(\n    onValueChange: (Screen) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val settingsScreenList = settingsState.screenListWithMaxBrightnessEnforcement\n    val screenList by remember(settingsScreenList) {\n        derivedStateOf {\n            settingsScreenList.mapNotNull {\n                Screen.entries.find { s -> s.id == it }\n            }\n        }\n    }\n\n    var showPickerSheet by rememberSaveable { mutableStateOf(false) }\n\n    val context = LocalResourceManager.current\n\n    val subtitle by remember(screenList, context) {\n        derivedStateOf {\n            screenList.joinToString(separator = \", \") {\n                context.getString(it.title)\n            }.ifEmpty {\n                context.getString(R.string.disabled)\n            }\n        }\n    }\n\n    PreferenceItem(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            showPickerSheet = true\n        },\n        startIcon = Icons.Outlined.BrightnessHigh,\n        title = stringResource(R.string.brightness_enforcement),\n        subtitle = subtitle,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showPickerSheet,\n        onDismiss = {\n            showPickerSheet = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.brightness),\n                icon = Icons.Outlined.BrightnessHigh\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { showPickerSheet = false }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        sheetContent = {\n            Box {\n                LazyColumn(\n                    contentPadding = PaddingValues(8.dp),\n                    verticalArrangement = Arrangement.spacedBy(8.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    items(\n                        items = Screen.entries,\n                        key = { it.id }\n                    ) { screen ->\n                        val checked by remember(screen, screenList) {\n                            derivedStateOf {\n                                screenList.fastAny { it::class.isInstance(screen) }\n                            }\n                        }\n                        PreferenceItemOverload(\n                            modifier = Modifier.fillMaxWidth(),\n                            title = stringResource(screen.title),\n                            subtitle = stringResource(screen.subtitle),\n                            startIcon = {\n                                screen.icon?.let {\n                                    Icon(\n                                        imageVector = it,\n                                        contentDescription = null\n                                    )\n                                }\n                            },\n                            endIcon = {\n                                EnhancedCheckbox(\n                                    checked = checked,\n                                    onCheckedChange = {\n                                        onValueChange(screen)\n                                    }\n                                )\n                            },\n                            onClick = {\n                                onValueChange(screen)\n                            }\n                        )\n                    }\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ButtonShadowsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Gamepad\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ButtonShadowsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        enabled = settingsState.borderWidth <= 0.dp,\n        shape = shape,\n        title = stringResource(R.string.buttons_shadow),\n        subtitle = stringResource(R.string.buttons_shadow_sub),\n        checked = settingsState.drawButtonShadows,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.Gamepad\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/CanEnterPresetsByTextFieldSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.WrapText\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun CanEnterPresetsByTextFieldSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.allow_enter_by_text_field),\n        subtitle = stringResource(R.string.allow_enter_by_text_field_sub),\n        checked = settingsState.canEnterPresetsByTextField,\n        onClick = { onClick() },\n        startIcon = Icons.AutoMirrored.Outlined.WrapText\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/CenterAlignDialogButtonsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.PictureInPictureCenter\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun CenterAlignDialogButtonsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        title = stringResource(R.string.center_align_dialog_buttons),\n        subtitle = stringResource(R.string.center_align_dialog_buttons_sub),\n        checked = settingsState.isCenterAlignDialogButtons,\n        startIcon = Icons.Outlined.PictureInPictureCenter\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ChangeFontSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FontFamily\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.additional.PickFontFamilySheet\n\n@Composable\nfun ChangeFontSettingItem(\n    onValueChange: (UiFontFamily) -> Unit,\n    onAddFont: (Uri) -> Unit,\n    onRemoveFont: (UiFontFamily.Custom) -> Unit,\n    onExportFonts: (Uri) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .fillMaxWidth()\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var showFontSheet by rememberSaveable { mutableStateOf(false) }\n\n    val exportFontsLauncher = rememberFileCreator(\n        mimeType = MimeType.Zip,\n        onSuccess = onExportFonts\n    )\n\n    PreferenceItem(\n        shape = shape,\n        onClick = { showFontSheet = true },\n        title = stringResource(R.string.font),\n        subtitle = settingsState.font.name ?: stringResource(R.string.system),\n        startIcon = Icons.Rounded.FontFamily,\n        endIcon = Icons.Rounded.MiniEdit,\n        modifier = modifier\n    )\n    PickFontFamilySheet(\n        visible = showFontSheet,\n        onDismiss = {\n            showFontSheet = false\n        },\n        onFontSelected = onValueChange,\n        onAddFont = onAddFont,\n        onRemoveFont = onRemoveFont,\n        onExportFonts = {\n            exportFontsLauncher.make(\"FONTS_EXPORT_${timestamp()}.zip\")\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ChangeLanguageSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport android.app.LocaleManager\nimport android.content.Context\nimport android.content.Intent\nimport android.content.res.Resources\nimport android.os.Build\nimport android.os.LocaleList\nimport android.provider.Settings\nimport androidx.appcompat.app.AppCompatDelegate\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Language\nimport androidx.compose.material.icons.rounded.Language\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport androidx.core.os.LocaleListCompat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getCurrentLocaleString\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getDisplayName\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.getLanguages\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedRadioButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.logger.makeLog\nimport java.util.Locale\n\n@Composable\nfun ChangeLanguageSettingItem(\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.top\n) {\n    val context = LocalContext.current\n    var showEmbeddedLanguagePicker by rememberSaveable { mutableStateOf(false) }\n\n    Column(Modifier.animateContentSizeNoClip()) {\n        PreferenceItem(\n            shape = shape,\n            modifier = modifier.padding(bottom = 1.dp),\n            title = stringResource(R.string.language),\n            subtitle = remember {\n                context.getCurrentLocaleString()\n            },\n            startIcon = Icons.Outlined.Language,\n            endIcon = Icons.Rounded.MiniEdit,\n            onClick = {\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n                    try {\n                        context.startActivity(\n                            Intent(\n                                Settings.ACTION_APP_LOCALE_SETTINGS,\n                                \"package:${context.packageName}\".toUri()\n                            )\n                        )\n                    } catch (e: Throwable) {\n                        e.makeLog(\"LocaleSelect\")\n                        showEmbeddedLanguagePicker = true\n                    }\n                } else {\n                    showEmbeddedLanguagePicker = true\n                }\n            }\n        )\n    }\n\n    PickLanguageSheet(\n        entries = remember {\n            context.getLanguages()\n        },\n        selected = remember {\n            context.getCurrentLocaleString()\n        },\n        onSelect = { tag ->\n            context.setGlobalLocale(\n                tag.takeIf { it.isNotBlank() }?.let(Locale::forLanguageTag)\n            )\n        },\n        visible = showEmbeddedLanguagePicker,\n        onDismiss = {\n            showEmbeddedLanguagePicker = false\n        }\n    )\n}\n\n@Composable\nprivate fun PickLanguageSheet(\n    entries: Map<String, String>,\n    selected: String,\n    onSelect: (String) -> Unit,\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    EnhancedModalBottomSheet(\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.language),\n                icon = Icons.Rounded.Language\n            )\n        },\n        sheetContent = {\n            Box {\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    modifier = Modifier\n                        .enhancedVerticalScroll(rememberScrollState())\n                        .padding(12.dp)\n                ) {\n                    entries.entries.forEachIndexed { index, locale ->\n                        val isSelected =\n                            selected == locale.value || (selected.isEmpty() && index == 0)\n                        PreferenceItemOverload(\n                            modifier = Modifier.fillMaxWidth(),\n                            onClick = {\n                                onSelect(locale.key)\n                            },\n                            resultModifier = Modifier.padding(\n                                start = 16.dp,\n                                end = 8.dp,\n                                top = 8.dp,\n                                bottom = 8.dp\n                            ),\n                            containerColor = animateColorAsState(\n                                if (isSelected) MaterialTheme\n                                    .colorScheme\n                                    .secondaryContainer\n                                else EnhancedBottomSheetDefaults.contentContainerColor\n                            ).value,\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = entries.size\n                            ),\n                            endIcon = {\n                                EnhancedRadioButton(\n                                    selected = isSelected,\n                                    onClick = {\n                                        onSelect(locale.key)\n                                    }\n                                )\n                            },\n                            title = locale.value,\n                            subtitle = remember(locale) {\n                                getDisplayName(\n                                    lang = locale.key,\n                                    useDefaultLocale = true\n                                )\n                            }.takeIf { locale.value != it }\n                        )\n                    }\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        visible = visible\n    )\n}\n\n@Suppress(\"DEPRECATION\")\nprivate fun Context.setGlobalLocale(locale: Locale?) {\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n        getSystemService(LocaleManager::class.java).applicationLocales =\n            locale?.let {\n                LocaleList.forLanguageTags(locale.toLanguageTag())\n            } ?: LocaleList.getEmptyLocaleList()\n    } else {\n        val newLocale = locale ?: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n            Resources.getSystem().configuration.locales[0]\n        } else {\n            Resources.getSystem().configuration.locale\n        }\n        Locale.setDefault(newLocale)\n\n        val configuration = resources.configuration\n        configuration.setLocale(newLocale)\n\n        resources.updateConfiguration(\n            configuration,\n            resources.displayMetrics\n        )\n    }\n\n    AppCompatDelegate.setApplicationLocales(\n        locale?.let {\n            LocaleListCompat.forLanguageTags(locale.toLanguageTag())\n        } ?: LocaleListCompat.getEmptyLocaleList()\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/CheckUpdatesButtonSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SyncArrowDown\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun CheckUpdatesButtonSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    PreferenceItem(\n        title = stringResource(R.string.check_for_updates),\n        containerColor = MaterialTheme.colorScheme.mixedContainer,\n        contentColor = MaterialTheme.colorScheme.onMixedContainer,\n        modifier = modifier,\n        shape = shape,\n        startIcon = Icons.Outlined.SyncArrowDown,\n        overrideIconShapeContentColor = true,\n        onClick = onClick\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ChecksumAsFilenameSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Tag\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.utils.safeCast\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.drop\n\n@Composable\nfun ChecksumAsFilenameSettingItem(\n    onValueChange: (HashingType?) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var checkedState by remember {\n        mutableStateOf(settingsState.filenameBehavior is FilenameBehavior.Checksum)\n    }\n    LaunchedEffect(onValueChange, settingsState) {\n        snapshotFlow { checkedState }\n            .drop(1)\n            .collectLatest {\n                onValueChange(\n                    if (it) {\n                        settingsState.filenameBehavior.safeCast<FilenameBehavior.Checksum>()?.hashingType\n                            ?: HashingType.entries.first()\n                    } else {\n                        null\n                    }\n                )\n            }\n    }\n\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None || settingsState.filenameBehavior is FilenameBehavior.Checksum,\n        onClick = {\n            checkedState = it\n        },\n        title = stringResource(R.string.checksum_as_filename),\n        subtitle = stringResource(R.string.checksum_as_filename_sub),\n        checked = checkedState,\n        startIcon = Icons.Rounded.Tag,\n        additionalContent = {\n            AnimatedVisibility(\n                visible = checkedState,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                DataSelector(\n                    modifier = Modifier\n                        .padding(top = 16.dp),\n                    value = settingsState.filenameBehavior.safeCast<FilenameBehavior.Checksum>()?.hashingType\n                        ?: HashingType.entries.first(),\n                    onValueChange = onValueChange,\n                    entries = HashingType.entries,\n                    containerColor = MaterialTheme.colorScheme.surfaceContainerLowest,\n                    shape = shape,\n                    title = stringResource(R.string.algorithms),\n                    titleIcon = null,\n                    badgeContent = {\n                        Text(HashingType.entries.size.toString())\n                    },\n                    itemContentText = {\n                        it.name\n                    }\n                )\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ClearCacheSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Memory\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun ClearCacheSettingItem(\n    onClearCache: ((String) -> Unit) -> Unit,\n    value: String,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    var cache by remember(value) {\n        mutableStateOf(value)\n    }\n\n    PreferenceItem(\n        shape = shape,\n        onClick = {\n            onClearCache { cache = it }\n        },\n        modifier = modifier,\n        title = stringResource(R.string.cache_size),\n        subtitle = stringResource(R.string.found_s, cache),\n        endIcon = Icons.Outlined.Delete,\n        startIcon = Icons.Outlined.Memory\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ColorBlindSchemeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid\nimport androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells\nimport androidx.compose.foundation.lazy.staggeredgrid.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.RemoveRedEye\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material.icons.rounded.RemoveRedEye\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.ColorBlindType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun ColorBlindSchemeSettingItem(\n    onValueChange: (Int?) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier\n        .fillMaxWidth()\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var isShowSheet by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceItem(\n        shape = shape,\n        onClick = { isShowSheet = true },\n        title = stringResource(R.string.color_blind_scheme),\n        subtitle = settingsState.colorBlindType?.localizedTitle\n            ?: stringResource(R.string.disabled),\n        startIcon = Icons.Outlined.RemoveRedEye,\n        endIcon = Icons.Rounded.MiniEdit,\n        modifier = modifier\n    )\n\n    EnhancedModalBottomSheet(\n        visible = isShowSheet,\n        onDismiss = {\n            isShowSheet = false\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.color_blind_scheme),\n                icon = Icons.Rounded.RemoveRedEye\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = { isShowSheet = false }\n            ) {\n                Text(text = stringResource(R.string.close))\n            }\n        },\n    ) {\n        val entries = remember {\n            listOf(null) + ColorBlindType.entries\n        }\n        LazyVerticalStaggeredGrid(\n            columns = StaggeredGridCells.Adaptive(250.dp),\n            contentPadding = PaddingValues(16.dp),\n            verticalItemSpacing = 8.dp,\n            horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            items(entries) { type ->\n                ColorBlindTypeSelectionItem(\n                    type = type,\n                    onClick = {\n                        onValueChange(type?.ordinal)\n                    }\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun ColorBlindTypeSelectionItem(\n    type: ColorBlindType?,\n    onClick: () -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n    val selected = settingsState.colorBlindType == type\n\n    PreferenceItem(\n        onClick = onClick,\n        title = type?.localizedTitle ?: stringResource(R.string.not_use_color_blind_scheme),\n        subtitle = type?.localizedDescription\n            ?: stringResource(R.string.not_use_color_blind_scheme_sub),\n        containerColor = takeColorFromScheme {\n            if (selected) secondaryContainer\n            else SafeLocalContainerColor\n        },\n        modifier = Modifier\n            .fillMaxWidth()\n            .border(\n                width = settingsState.borderWidth,\n                color = animateColorAsState(\n                    if (selected) MaterialTheme.colorScheme\n                        .onSecondaryContainer\n                        .copy(alpha = 0.5f)\n                    else Color.Transparent\n                ).value,\n                shape = ShapeDefaults.default\n            ),\n        endIcon = if (selected) {\n            Icons.Rounded.RadioButtonChecked\n        } else Icons.Rounded.RadioButtonUnchecked\n    )\n}\n\nprivate val ColorBlindType.localizedTitle: String\n    @Composable\n    get() = stringResource(\n        when (this) {\n            ColorBlindType.Protanomaly -> R.string.protonomaly\n            ColorBlindType.Deuteranomaly -> R.string.deutaromaly\n            ColorBlindType.Tritanomaly -> R.string.tritonomaly\n            ColorBlindType.Protanopia -> R.string.protanopia\n            ColorBlindType.Deuteranopia -> R.string.deutaronotopia\n            ColorBlindType.Tritanopia -> R.string.tritanopia\n            ColorBlindType.Achromatomaly -> R.string.achromatomaly\n            ColorBlindType.Achromatopsia -> R.string.achromatopsia\n        }\n    )\n\nprivate val ColorBlindType.localizedDescription: String\n    @Composable\n    get() = stringResource(\n        when (this) {\n            ColorBlindType.Protanomaly -> R.string.protanomaly_sub\n            ColorBlindType.Deuteranomaly -> R.string.deuteranomaly_sub\n            ColorBlindType.Tritanomaly -> R.string.tritanomaly_sub\n            ColorBlindType.Protanopia -> R.string.protanopia_sub\n            ColorBlindType.Deuteranopia -> R.string.deuteranopia_sub\n            ColorBlindType.Tritanopia -> R.string.tritanopia_sub\n            ColorBlindType.Achromatomaly -> R.string.achromatomaly_sub\n            ColorBlindType.Achromatopsia -> R.string.achromatopsia_sub\n        }\n    )\n"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ColorSchemeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Palette\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.ColorTupleItem\nimport com.t8rin.dynamic.theme.PaletteStyle\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.PaletteBox\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.AvailableColorTuplesSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorTuplePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun ColorSchemeSettingItem(\n    onToggleInvertColors: () -> Unit,\n    onSetThemeStyle: (Int) -> Unit,\n    onUpdateThemeContrast: (Float) -> Unit,\n    onUpdateColorTuple: (ColorTuple) -> Unit,\n    onUpdateColorTuples: (List<ColorTuple>) -> Unit,\n    onToggleUseEmojiAsPrimaryColor: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n) {\n    val settingsState = LocalSettingsState.current\n    val enabled = !settingsState.isDynamicColors\n\n    var showPickColorSheet by rememberSaveable { mutableStateOf(false) }\n    PreferenceRow(\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        title = stringResource(R.string.color_scheme),\n        startIcon = Icons.Outlined.PaletteBox,\n        subtitle = stringResource(R.string.pick_accent_color),\n        onClick = {\n            showPickColorSheet = true\n        },\n        onDisabledClick = {\n            AppToastHost.showToast(\n                icon = Icons.Rounded.Palette,\n                message = getString(R.string.cannot_change_palette_while_dynamic_colors_applied)\n            )\n        },\n        endContent = {\n            val colorTuple by remember(\n                settingsState.themeStyle,\n                settingsState.appColorTuple\n            ) {\n                derivedStateOf {\n                    if (settingsState.themeStyle == PaletteStyle.TonalSpot) {\n                        settingsState.appColorTuple\n                    } else settingsState.appColorTuple.run {\n                        copy(secondary = primary, tertiary = primary)\n                    }\n                }\n            }\n            Box(\n                modifier = Modifier\n                    .padding(end = 8.dp)\n                    .size(72.dp)\n                    .container(\n                        shape = MaterialStarShape,\n                        color = MaterialTheme.colorScheme\n                            .surfaceVariant\n                            .copy(alpha = 0.5f),\n                        borderColor = MaterialTheme.colorScheme.outlineVariant(\n                            0.2f\n                        ),\n                        resultPadding = 5.dp\n                    )\n            ) {\n                ColorTupleItem(\n                    modifier = Modifier\n                        .clip(ShapeDefaults.circle),\n                    colorTuple = colorTuple,\n                    backgroundColor = Color.Transparent\n                ) {\n                    Box(\n                        modifier = Modifier\n                            .size(28.dp)\n                            .background(\n                                color = animateColorAsState(\n                                    settingsState.appColorTuple.primary.inverse(\n                                        fraction = {\n                                            if (it) 0.8f\n                                            else 0.5f\n                                        },\n                                        darkMode = settingsState.appColorTuple.primary.luminance() < 0.3f\n                                    )\n                                ).value,\n                                shape = ShapeDefaults.circle\n                            )\n                    )\n                    Icon(\n                        imageVector = Icons.Rounded.MiniEdit,\n                        contentDescription = stringResource(R.string.edit),\n                        tint = settingsState.appColorTuple.primary\n                    )\n                }\n            }\n        }\n    )\n    var showColorPicker by rememberSaveable { mutableStateOf(false) }\n    AvailableColorTuplesSheet(\n        visible = showPickColorSheet,\n        colorTupleList = settingsState.colorTupleList,\n        currentColorTuple = rememberAppColorTuple(),\n        onToggleInvertColors = onToggleInvertColors,\n        onThemeStyleSelected = { onSetThemeStyle(it.ordinal) },\n        onUpdateThemeContrast = onUpdateThemeContrast,\n        onOpenColorPicker = {\n            showColorPicker = true\n        },\n        colorPicker = {\n            ColorTuplePicker(\n                visible = showColorPicker,\n                colorTuple = settingsState.appColorTuple,\n                onDismiss = {\n                    showColorPicker = false\n                },\n                onColorChange = {\n                    onUpdateColorTuple(it)\n                    onUpdateColorTuples(settingsState.colorTupleList + it)\n                }\n            )\n        },\n        onUpdateColorTuples = onUpdateColorTuples,\n        onToggleUseEmojiAsPrimaryColor = onToggleUseEmojiAsPrimaryColor,\n        onDismiss = {\n            showPickColorSheet = false\n        },\n        onPickTheme = onUpdateColorTuple\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ConfettiHarmonizationColorSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ColorLens\nimport androidx.compose.material.icons.rounded.ColorLens\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ColorHarmonizer\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.RecentAndFavoriteColorsCard\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun ConfettiHarmonizationColorSettingItem(\n    onValueChange: (ColorHarmonizer) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val items = remember {\n        ColorHarmonizer.entries\n    }\n\n    val enabled = settingsState.isConfettiEnabled\n\n    val scope = rememberCoroutineScope()\n\n    var showColorPicker by remember {\n        mutableStateOf(false)\n    }\n\n    Box {\n        Column(\n            modifier = modifier\n                .container(\n                    shape = shape\n                )\n                .alpha(\n                    animateFloatAsState(\n                        if (enabled) 1f\n                        else 0.5f\n                    ).value\n                )\n        ) {\n            TitleItem(\n                modifier = Modifier.padding(\n                    top = 12.dp,\n                    end = 12.dp,\n                    bottom = 16.dp,\n                    start = 12.dp\n                ),\n                iconEndPadding = 14.dp,\n                text = stringResource(R.string.harmonization_color),\n                icon = Icons.Outlined.ColorLens\n            )\n\n            FlowRow(\n                verticalArrangement = Arrangement.spacedBy(\n                    space = 8.dp,\n                    alignment = Alignment.CenterVertically\n                ),\n                horizontalArrangement = Arrangement.spacedBy(\n                    space = 8.dp,\n                    alignment = Alignment.CenterHorizontally\n                ),\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(start = 8.dp, bottom = 8.dp, end = 8.dp)\n            ) {\n                val value = settingsState.confettiColorHarmonizer\n                items.forEach { harmonizer ->\n                    val colorScheme = MaterialTheme.colorScheme\n                    val selectedColor = when (harmonizer) {\n                        is ColorHarmonizer.Custom -> Color(value.ordinal)\n                            .blend(\n                                color = colorScheme.surface,\n                                fraction = 0.1f\n                            )\n\n                        ColorHarmonizer.Primary -> colorScheme.primary\n                        ColorHarmonizer.Secondary -> colorScheme.secondary\n                        ColorHarmonizer.Tertiary -> colorScheme.tertiary\n                    }\n                    EnhancedChip(\n                        onClick = {\n                            if (harmonizer !is ColorHarmonizer.Custom) {\n                                AppToastHost.dismissToasts()\n                                onValueChange(harmonizer)\n                                scope.launch {\n                                    delay(200L)\n                                    AppToastHost.showConfetti()\n                                }\n                            } else {\n                                showColorPicker = true\n                            }\n                        },\n                        selected = harmonizer::class.isInstance(value),\n                        label = {\n                            Text(text = harmonizer.title)\n                        },\n                        contentPadding = PaddingValues(horizontal = 16.dp, vertical = 6.dp),\n                        selectedColor = selectedColor,\n                        selectedContentColor = when (harmonizer) {\n                            is ColorHarmonizer.Custom -> selectedColor.inverse(\n                                fraction = {\n                                    if (it) 0.9f\n                                    else 0.6f\n                                },\n                                darkMode = selectedColor.luminance() < 0.3f\n                            )\n\n                            else -> contentColorFor(backgroundColor = selectedColor)\n                        },\n                        unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant\n                    )\n                }\n            }\n        }\n\n        if (!enabled) {\n            Surface(\n                color = Color.Transparent,\n                modifier = Modifier.matchParentSize()\n            ) {}\n        }\n    }\n\n    var tempColor by remember(settingsState.confettiColorHarmonizer) {\n        mutableStateOf(\n            (settingsState.confettiColorHarmonizer as? ColorHarmonizer.Custom)?.color?.toColor()\n                ?: Color.Black\n        )\n    }\n    EnhancedModalBottomSheet(\n        sheetContent = {\n            Column(\n                modifier = Modifier\n                    .enhancedVerticalScroll(rememberScrollState())\n                    .padding(24.dp)\n            ) {\n                RecentAndFavoriteColorsCard(\n                    onRecentColorClick = { tempColor = it },\n                    onFavoriteColorClick = { tempColor = it }\n                )\n\n                ColorSelection(\n                    value = tempColor,\n                    onValueChange = {\n                        tempColor = it\n                    }\n                )\n            }\n        },\n        visible = showColorPicker,\n        onDismiss = {\n            showColorPicker = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.color),\n                icon = Icons.Rounded.ColorLens\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    AppToastHost.dismissToasts()\n                    onValueChange(ColorHarmonizer.Custom(tempColor.toArgb()))\n                    scope.launch {\n                        delay(200L)\n                        AppToastHost.showConfetti()\n                    }\n                    showColorPicker = false\n                }\n            ) {\n                AutoSizeText(stringResource(R.string.ok))\n            }\n        }\n    )\n}\n\nprivate val ColorHarmonizer.title: String\n    @Composable\n    get() = when (this) {\n        is ColorHarmonizer.Custom -> stringResource(R.string.custom)\n        ColorHarmonizer.Primary -> stringResource(R.string.primary)\n        ColorHarmonizer.Secondary -> stringResource(R.string.secondary)\n        ColorHarmonizer.Tertiary -> stringResource(R.string.tertiary)\n    }"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ConfettiHarmonizationLevelSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exercise\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n\n@Composable\nfun ConfettiHarmonizationLevelSettingItem(\n    onValueChange: (Float) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var value by remember {\n        mutableFloatStateOf(settingsState.confettiHarmonizationLevel)\n    }\n\n    EnhancedSliderItem(\n        modifier = modifier,\n        shape = shape,\n        value = value,\n        title = stringResource(R.string.harmonization_level),\n        enabled = settingsState.isConfettiEnabled,\n        icon = Icons.Outlined.Exercise,\n        onValueChange = {\n            value = it.roundToTwoDigits()\n            onValueChange(value)\n        },\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        valueRange = 0f..1f\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ConfettiSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Celebration\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun ConfettiSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val scope = rememberCoroutineScope()\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.confetti),\n        subtitle = stringResource(R.string.confetti_sub),\n        checked = settingsState.isConfettiEnabled,\n        onClick = { isEnabled ->\n            onClick()\n            if (isEnabled) {\n                scope.launch {\n                    //Wait for setting to be applied\n                    delay(200L)\n                    AppToastHost.showConfetti()\n                }\n            }\n        },\n        startIcon = Icons.Outlined.Celebration\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ConfettiTypeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Emergency\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.confetti.Particles\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun ConfettiTypeSettingItem(\n    onValueChange: (Int) -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val items = remember {\n        Particles.Type.entries\n    }\n\n    val enabled = settingsState.isConfettiEnabled\n\n    Box {\n        Column(\n            modifier = modifier\n                .container(\n                    shape = shape\n                )\n                .alpha(\n                    animateFloatAsState(\n                        if (enabled) 1f\n                        else 0.5f\n                    ).value\n                )\n        ) {\n            TitleItem(\n                modifier = Modifier.padding(\n                    top = 12.dp,\n                    end = 12.dp,\n                    bottom = 16.dp,\n                    start = 12.dp\n                ),\n                iconEndPadding = 14.dp,\n                text = stringResource(R.string.confetti_type),\n                icon = Icons.Outlined.Emergency\n            )\n\n            FlowRow(\n                verticalArrangement = Arrangement.spacedBy(\n                    8.dp,\n                    Alignment.CenterVertically\n                ),\n                horizontalArrangement = Arrangement.spacedBy(\n                    8.dp,\n                    Alignment.CenterHorizontally\n                ),\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(start = 8.dp, bottom = 8.dp, end = 8.dp)\n            ) {\n                val scope = rememberCoroutineScope()\n                val value = settingsState.confettiType\n                items.forEach {\n                    EnhancedChip(\n                        onClick = {\n                            AppToastHost.dismissToasts()\n                            onValueChange(it.ordinal)\n                            scope.launch {\n                                delay(200L)\n                                AppToastHost.showConfetti()\n                            }\n                        },\n                        selected = it.ordinal == value,\n                        label = {\n                            Text(text = it.title)\n                        },\n                        contentPadding = PaddingValues(horizontal = 16.dp, vertical = 6.dp),\n                        selectedColor = MaterialTheme.colorScheme.outlineVariant(\n                            0.2f,\n                            MaterialTheme.colorScheme.tertiary\n                        ),\n                        selectedContentColor = MaterialTheme.colorScheme.onTertiary,\n                        unselectedContentColor = MaterialTheme.colorScheme.onSurface\n                    )\n                }\n            }\n        }\n\n        if (!enabled) {\n            Surface(\n                color = Color.Transparent,\n                modifier = Modifier.matchParentSize()\n            ) {}\n        }\n    }\n}\n\nprivate val Particles.Type.title: String\n    @Composable\n    get() = when (this) {\n        Particles.Type.Default -> stringResource(R.string.defaultt)\n        Particles.Type.Festive -> stringResource(R.string.festive)\n        Particles.Type.Explode -> stringResource(R.string.explode)\n        Particles.Type.Rain -> stringResource(R.string.rain)\n        Particles.Type.Side -> stringResource(R.string.side)\n        Particles.Type.Corners -> stringResource(R.string.corners)\n        Particles.Type.Toolbox -> stringResource(R.string.app_name)\n    }"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ContainerShadowsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ViewComfy\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ContainerShadowsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        enabled = settingsState.borderWidth <= 0.dp,\n        shape = shape,\n        title = stringResource(R.string.containers_shadow),\n        subtitle = stringResource(R.string.containers_shadow_sub),\n        checked = settingsState.drawContainerShadows,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.ViewComfy\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/CornersSizeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Percent\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.drop\n\n@Composable\nfun CornersSizeSettingItem(\n    onValueChange: (ShapeType) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val settingsInteractor = LocalSimpleSettingsInteractor.current\n\n    var value by remember {\n        mutableFloatStateOf(settingsState.shapesType.strength)\n    }\n\n    var isSwapped by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var trigger by remember {\n        mutableIntStateOf(0)\n    }\n\n    LaunchedEffect(settingsState.shapesType) {\n        snapshotFlow { trigger }\n            .drop(1)\n            .collectLatest {\n                if (settingsState.shapesType is ShapeType.Smooth && settingsState.drawContainerShadows && value > 1f) {\n                    settingsInteractor.setBorderWidth(0.2f)\n                    isSwapped = true\n                } else if (isSwapped && settingsState.borderWidth.value == 0.2f) {\n                    settingsInteractor.setBorderWidth(0f)\n                    isSwapped = false\n                }\n                onValueChange(settingsState.shapesType.copy(value))\n            }\n    }\n\n    EnhancedSliderItem(\n        modifier = modifier,\n        shape = shape,\n        value = value,\n        title = stringResource(R.string.corners_size),\n        icon = Icons.Outlined.Percent,\n        onValueChange = {\n            value = it.roundToTwoDigits()\n        },\n        onValueChangeFinished = {\n            trigger++\n        },\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        valueRange = 0f..2f\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/CrashlyticsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Crashlytics\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun CrashlyticsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.crashlytics),\n        subtitle = stringResource(id = R.string.crashlytics_sub),\n        startIcon = Icons.Rounded.Crashlytics,\n        checked = settingsState.allowCollectCrashlytics,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/CurrentVersionCodeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"KotlinConstantConditions\")\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Verified\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.BuildConfig\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.shapes.MaterialStarShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppVersion\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.pulsate\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\n\n@Composable\nfun CurrentVersionCodeSettingItem(\n    isUpdateAvailable: Boolean,\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRow(\n        shape = shape,\n        modifier = Modifier\n            .pulsate(\n                enabled = isUpdateAvailable,\n                range = 0.98f..1.02f\n            )\n            .then(modifier),\n        title = stringResource(R.string.version),\n        subtitle = remember {\n            \"$AppVersion (${BuildConfig.VERSION_CODE})\"\n        },\n        startIcon = Icons.Outlined.Verified,\n        endContent = {\n            Icon(\n                painter = painterResource(R.drawable.ic_launcher_foreground),\n                contentDescription = stringResource(R.string.version),\n                tint = animateColorAsState(\n                    if (settingsState.isNightMode) {\n                        MaterialTheme.colorScheme.primary\n                    } else {\n                        MaterialTheme.colorScheme.primary.blend(Color.Black)\n                    }\n                ).value,\n                modifier = Modifier\n                    .padding(horizontal = 8.dp)\n                    .size(64.dp)\n                    .container(\n                        resultPadding = 0.dp,\n                        color = animateColorAsState(\n                            if (settingsState.isNightMode) {\n                                MaterialTheme.colorScheme.secondaryContainer.blend(\n                                    color = Color.Black,\n                                    fraction = 0.3f\n                                )\n                            } else {\n                                MaterialTheme.colorScheme.primaryContainer\n                            }\n                        ).value,\n                        borderColor = MaterialTheme.colorScheme.outlineVariant(),\n                        shape = MaterialStarShape\n                    )\n                    .scale(1.25f)\n            )\n        },\n        onClick = onClick\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultColorSpaceSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ColorLens\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.ScaleColorSpace\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.DataSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.title\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun DefaultColorSpaceSettingItem(\n    onValueChange: (ImageScaleMode) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    AnimatedVisibility(\n        visible = settingsState.defaultImageScaleMode != ImageScaleMode.Base,\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        val items = remember {\n            ScaleColorSpace.entries\n        }\n        DataSelector(\n            value = settingsState.defaultImageScaleMode.scaleColorSpace,\n            onValueChange = {\n                onValueChange(\n                    settingsState.defaultImageScaleMode.copy(it)\n                )\n            },\n            initialExpanded = true,\n            spanCount = 2,\n            entries = items,\n            title = stringResource(R.string.tag_color_space),\n            titleIcon = Icons.Outlined.ColorLens,\n            itemContentText = { it.title },\n            containerColor = Color.Unspecified,\n            shape = shape,\n            modifier = modifier,\n            selectedItemColor = MaterialTheme.colorScheme.secondary\n        )\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultDrawColorSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BrushColor\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.toModel\nimport com.t8rin.imagetoolbox.core.ui.widget.color_picker.ColorSelectionRowDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\nfun DefaultDrawColorSettingItem(\n    onValueChange: (ColorModel) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp),\n) {\n    val settingsState = LocalSettingsState.current\n\n    ColorRowSelector(\n        modifier = modifier.container(shape = shape),\n        value = settingsState.defaultDrawColor,\n        onValueChange = {\n            onValueChange(it.toModel())\n        },\n        icon = Icons.Outlined.BrushColor,\n        title = stringResource(R.string.default_draw_color),\n        defaultColors = ColorSelectionRowDefaults.colorList\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultDrawLineWidthSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.LineWeight\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun DefaultDrawLineWidthSettingItem(\n    onValueChange: (Float) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    var value by remember {\n        mutableFloatStateOf(settingsState.defaultDrawLineWidth)\n    }\n\n    EnhancedSliderItem(\n        modifier = modifier,\n        shape = shape,\n        value = value,\n        title = stringResource(R.string.default_line_width),\n        icon = Icons.Rounded.LineWeight,\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        onValueChange = {\n            value = it\n            onValueChange(it)\n        },\n        valueSuffix = \" Pt\",\n        valueRange = 1f..100f\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultDrawPathModeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.TouchApp\nimport androidx.compose.material.icons.rounded.CheckBoxOutlineBlank\nimport androidx.compose.material.icons.rounded.Circle\nimport androidx.compose.material.icons.rounded.HourglassEmpty\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material.icons.rounded.Star\nimport androidx.compose.material.icons.rounded.StarOutline\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FloodFill\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeDoubleArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeDraw\nimport com.t8rin.imagetoolbox.core.resources.icons.Lasso\nimport com.t8rin.imagetoolbox.core.resources.icons.Line\nimport com.t8rin.imagetoolbox.core.resources.icons.LineArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.LineDoubleArrow\nimport com.t8rin.imagetoolbox.core.resources.icons.Polygon\nimport com.t8rin.imagetoolbox.core.resources.icons.Spray\nimport com.t8rin.imagetoolbox.core.resources.icons.Square\nimport com.t8rin.imagetoolbox.core.resources.icons.Triangle\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun DefaultDrawPathModeSettingItem(\n    onValueChange: (Int) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    Column(modifier = modifier.container(shape = shape)) {\n        TitleItem(\n            text = stringResource(R.string.default_draw_path_mode),\n            icon = Icons.Outlined.TouchApp,\n            iconEndPadding = 14.dp,\n            modifier = Modifier\n                .padding(horizontal = 12.dp)\n                .padding(top = 12.dp)\n        )\n        EnhancedButtonGroup(\n            enabled = true,\n            itemCount = ordinals.size,\n            title = {},\n            selectedIndex = ordinals.indexOf(settingsState.defaultDrawPathMode),\n            activeButtonColor = MaterialTheme.colorScheme.surfaceContainerHighest,\n            inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n            itemContent = {\n                Icon(\n                    imageVector = ordinals[it].getIcon(),\n                    contentDescription = null\n                )\n            },\n            onIndexChange = {\n                onValueChange(ordinals[it])\n            }\n        )\n    }\n}\n\nprivate val ordinals = listOf(\n    0,\n    17,\n    18,\n    1,\n    2,\n    3,\n    4,\n    5,\n    6,\n    7,\n    8,\n    9,\n    10,\n    11,\n    12,\n    13,\n    14,\n    15,\n    16\n)\n\nprivate fun Int.getIcon(): ImageVector = when (this) {\n    5 -> Icons.Rounded.LineDoubleArrow\n    3 -> Icons.Rounded.FreeDoubleArrow\n    0 -> Icons.Rounded.FreeDraw\n    1 -> Icons.Rounded.Line\n    4 -> Icons.Rounded.LineArrow\n    2 -> Icons.Rounded.FreeArrow\n    8 -> Icons.Rounded.RadioButtonUnchecked\n    7 -> Icons.Rounded.CheckBoxOutlineBlank\n    10 -> Icons.Rounded.Circle\n    9 -> Icons.Rounded.Square\n    6 -> Icons.Rounded.Lasso\n    11 -> Icons.Rounded.Triangle\n    12 -> Icons.Outlined.Triangle\n    13 -> Icons.Rounded.Polygon\n    14 -> Icons.Outlined.Polygon\n    16 -> Icons.Rounded.StarOutline\n    15 -> Icons.Rounded.Star\n    17 -> Icons.Rounded.FloodFill\n    18 -> Icons.Outlined.Spray\n    else -> Icons.Rounded.HourglassEmpty\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultImageFormatSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Png\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\n\n@Composable\nfun DefaultImageFormatSettingItem(\n    onValueChange: (ImageFormat?) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    ImageFormatSelector(\n        modifier = modifier,\n        shape = shape,\n        quality = settingsState.defaultQuality,\n        backgroundColor = Color.Unspecified,\n        value = settingsState.defaultImageFormat,\n        onValueChange = onValueChange,\n        enableItemsCardBackground = false,\n        onAutoClick = { onValueChange(null) },\n        title = {\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 12.dp)\n                    .padding(top = 4.dp),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                IconShapeContainer(\n                    content = {\n                        Icon(\n                            imageVector = Icons.Outlined.Png,\n                            contentDescription = null\n                        )\n                    }\n                )\n                Spacer(modifier = Modifier.width(8.dp))\n                Text(\n                    text = stringResource(R.string.image_format),\n                    style = PreferenceItemDefaults.TitleFontStyle,\n                    modifier = Modifier.weight(1f, false)\n                )\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultQualitySettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.resources.icons.ShineDiamond\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\n\n@Composable\nfun DefaultQualitySettingItem(\n    onValueChange: (Quality) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    var quality by remember {\n        mutableStateOf(settingsState.defaultQuality)\n    }\n\n    QualitySelector(\n        modifier = modifier,\n        shape = shape,\n        imageFormat = settingsState.defaultImageFormat ?: ImageFormat.Default,\n        quality = quality,\n        onQualityChange = {\n            quality = it\n            onValueChange(quality)\n        },\n        icon = Icons.Outlined.ShineDiamond,\n        activeButtonColor = MaterialTheme.colorScheme.surfaceContainerHighest,\n        inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultResizeTypeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.PhotoSizeSelectSmall\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.state.derivedValueOf\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun DefaultResizeTypeSettingItem(\n    onValueChange: (ResizeType) -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val value = settingsState.defaultResizeType\n    val entries = remember {\n        ResizeType.entries\n    }\n\n    Column(modifier = modifier.container(shape = shape)) {\n        TitleItem(\n            text = stringResource(R.string.resize_type),\n            icon = Icons.Outlined.PhotoSizeSelectSmall,\n            modifier = Modifier\n                .padding(horizontal = 12.dp)\n                .padding(top = 12.dp)\n        )\n        EnhancedButtonGroup(\n            enabled = true,\n            itemCount = entries.size,\n            title = {},\n            selectedIndex = derivedValueOf(value) {\n                entries.indexOfFirst { it::class.isInstance(value) }\n            },\n            activeButtonColor = MaterialTheme.colorScheme.surfaceContainerHighest,\n            inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n            itemContent = {\n                Text(stringResource(entries[it].getTitle()))\n            },\n            onIndexChange = {\n                onValueChange(entries[it])\n            }\n        )\n    }\n}\n\nprivate fun ResizeType.getTitle(): Int = when (this) {\n    is ResizeType.CenterCrop -> R.string.crop\n    is ResizeType.Explicit -> R.string.explicit\n    is ResizeType.Flexible -> R.string.flexible\n    is ResizeType.Fit -> R.string.fit\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DefaultScaleModeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FitScreen\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ScaleModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\n\n@Composable\nfun DefaultScaleModeSettingItem(\n    onValueChange: (ImageScaleMode) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    ScaleModeSelector(\n        modifier = modifier,\n        shape = shape,\n        backgroundColor = Color.Unspecified,\n        value = settingsState.defaultImageScaleMode,\n        onValueChange = onValueChange,\n        titlePadding = PaddingValues(\n            top = 12.dp,\n            start = 12.dp,\n            end = 12.dp\n        ),\n        titleArrangement = Arrangement.Start,\n        enableItemsCardBackground = false,\n        title = {\n            IconShapeContainer(\n                content = {\n                    Icon(\n                        imageVector = Icons.Outlined.FitScreen,\n                        contentDescription = null\n                    )\n                }\n            )\n            Spacer(modifier = Modifier.width(8.dp))\n            Text(\n                text = stringResource(R.string.scale_mode),\n                style = PreferenceItemDefaults.TitleFontStyle,\n                modifier = Modifier.weight(1f, false)\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DonateSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.VolunteerActivism\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.isFirstLaunch\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContentColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.pulsate\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.additional.DonateSheet\n\n@Composable\nfun DonateSettingItem(\n    shape: Shape = ShapeDefaults.bottom\n) {\n    val settingsState = LocalSettingsState.current\n    var showDonateSheet by rememberSaveable { mutableStateOf(false) }\n\n    CompositionLocalProvider(\n        LocalIconShapeContentColor provides MaterialTheme.colorScheme.onTertiaryContainer,\n        LocalIconShapeContainerColor provides MaterialTheme.colorScheme.tertiaryContainer.blend(\n            color = MaterialTheme.colorScheme.tertiary,\n            fraction = if (settingsState.isNightMode) 0.2f else 0.1f\n        )\n    ) {\n        PreferenceItem(\n            modifier = Modifier\n                .pulsate(\n                    range = 0.98f..1.02f,\n                    enabled = settingsState.isFirstLaunch()\n                )\n                .padding(horizontal = 8.dp),\n            shape = shape,\n            containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n            contentColor = MaterialTheme.colorScheme.onTertiaryContainer,\n            title = stringResource(R.string.donation),\n            subtitle = stringResource(R.string.donation_sub),\n            startIcon = Icons.Outlined.VolunteerActivism,\n            onClick = {\n                showDonateSheet = true\n            },\n            overrideIconShapeContentColor = true\n        )\n    }\n    DonateSheet(\n        visible = showDonateSheet,\n        onDismiss = { showDonateSheet = false }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DragHandleWidthSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.DragHandle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlin.math.roundToInt\n\n@Composable\nfun DragHandleWidthSettingItem(\n    onValueChange: (Int) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var value by remember {\n        mutableFloatStateOf(settingsState.dragHandleWidth.value)\n    }\n    EnhancedSliderItem(\n        modifier = modifier,\n        shape = shape,\n        valueSuffix = \" Dp\",\n        value = value,\n        title = stringResource(R.string.drag_handle_width),\n        icon = Icons.Rounded.DragHandle,\n        onValueChange = {\n            value = it.roundToInt().toFloat()\n            onValueChange(it.roundToInt())\n        },\n        internalStateTransformation = {\n            it.roundToInt()\n        },\n        valueRange = 0f..128f\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/DynamicColorsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FormatColorFill\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun DynamicColorsSettingItem(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.center\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        startIcon = Icons.Outlined.FormatColorFill,\n        title = stringResource(R.string.dynamic_colors),\n        subtitle = stringResource(R.string.dynamic_colors_sub),\n        checked = settingsState.isDynamicColors,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/EmojiSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Block\nimport androidx.compose.material.icons.rounded.Casino\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Cool\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.scaleOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.other.EmojiItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.EmojiSelectionSheet\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun EmojiSettingItem(\n    selectedEmojiIndex: Int,\n    onAddColorTupleFromEmoji: (String) -> Unit,\n    onUpdateEmoji: (Int) -> Unit,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.top\n) {\n    val settingsState = LocalSettingsState.current\n    var showSecretDescriptionDialog by rememberSaveable { mutableStateOf(\"\") }\n    var showShoeDescriptionDialog by rememberSaveable { mutableStateOf(\"\") }\n    var showEmojiDialog by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceRow(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.emoji),\n        subtitle = stringResource(R.string.emoji_sub),\n        onClick = {\n            showEmojiDialog = true\n        },\n        startIcon = Icons.Outlined.Cool,\n        enabled = !settingsState.useRandomEmojis,\n        onDisabledClick = {\n            AppToastHost.showToast(\n                message = getString(R.string.emoji_selection_error),\n                icon = Icons.Rounded.Casino\n            )\n        },\n        endContent = {\n            val emoji = LocalSettingsState.current.selectedEmoji\n            Box(\n                modifier = Modifier\n                    .padding(end = 8.dp)\n                    .size(64.dp)\n                    .container(\n                        shape = CloverShape,\n                        color = MaterialTheme.colorScheme\n                            .surfaceVariant\n                            .copy(alpha = 0.5f),\n                        borderColor = MaterialTheme.colorScheme.outlineVariant(\n                            0.2f\n                        )\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                EmojiItem(\n                    emoji = emoji?.toString(),\n                    modifier = Modifier.then(\n                        if (emoji != null) {\n                            Modifier.scaleOnTap(\n                                onRelease = { time ->\n                                    if (time > 500) {\n                                        onAddColorTupleFromEmoji(emoji.toString())\n                                        if (emoji.toString().contains(\"frog\", true)) {\n                                            showSecretDescriptionDialog = emoji.toString()\n                                        } else if (emoji.toString().contains(\"shoe\", true)) {\n                                            showShoeDescriptionDialog = emoji.toString()\n                                        }\n                                    }\n                                }\n                            )\n                        } else Modifier\n                    ),\n                    fontScale = 1f,\n                    fontSize = MaterialTheme.typography.headlineLarge.fontSize,\n                    onNoEmoji = { size ->\n                        Icon(\n                            imageVector = Icons.Rounded.Block,\n                            contentDescription = null,\n                            modifier = Modifier.size(size)\n                        )\n                    }\n                )\n            }\n        }\n    )\n    EmojiSelectionSheet(\n        selectedEmojiIndex = selectedEmojiIndex,\n        onEmojiPicked = onUpdateEmoji,\n        visible = showEmojiDialog,\n        onDismiss = {\n            showEmojiDialog = false\n        }\n    )\n\n    EnhancedAlertDialog(\n        visible = showShoeDescriptionDialog.isNotEmpty(),\n        icon = {\n            EmojiItem(\n                emoji = showShoeDescriptionDialog,\n                fontScale = 1f,\n                fontSize = MaterialTheme.typography.headlineLarge.fontSize,\n            )\n        },\n        title = {\n            Text(text = \"Shoe\")\n        },\n        text = {\n            Text(text = \"15.07.1981 - Shoe, (ShoeUnited since 1998)\")\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { showShoeDescriptionDialog = \"\" }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        onDismissRequest = {\n            showShoeDescriptionDialog = \"\"\n        }\n    )\n\n    EnhancedAlertDialog(\n        visible = showSecretDescriptionDialog.isNotEmpty(),\n        icon = {\n            EmojiItem(\n                emoji = showSecretDescriptionDialog,\n                fontScale = 1f,\n                fontSize = MaterialTheme.typography.headlineLarge.fontSize,\n            )\n        },\n        text = {\n            Text(\n                text = \"\\uD83D\\uDC49 \\uD83D\\uDC46, \\uD83D\\uDC47 \\uD83D\\uDE4B \\uD83D\\uDC70 ❗ \\uD83D\\uDC64 \\uD83D\\uDC96 \\uD83D\\uDCF6 \\uD83C\\uDF05\",\n                modifier = Modifier.fillMaxWidth()\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { showSecretDescriptionDialog = \"\" }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        },\n        onDismissRequest = {\n            showSecretDescriptionDialog = \"\"\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/EmojisCountSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.EmojiMultiple\nimport com.t8rin.imagetoolbox.core.resources.icons.Robot\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun EmojisCountSettingItem(\n    onValueChange: (Int) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    EnhancedSliderItem(\n        modifier = modifier.then(\n            if (settingsState.selectedEmoji == null) {\n                Modifier\n                    .clip(ShapeDefaults.extraSmall)\n                    .hapticsClickable {\n                        AppToastHost.showToast(\n                            message = getString(R.string.random_emojis_error),\n                            icon = Icons.Rounded.Robot\n                        )\n                    }\n            } else Modifier\n        ),\n        shape = shape,\n        value = settingsState.emojisCount.coerceAtLeast(1),\n        title = stringResource(R.string.emojis_count),\n        icon = Icons.Outlined.EmojiMultiple,\n        valueRange = 1f..5f,\n        steps = 3,\n        enabled = settingsState.selectedEmoji != null,\n        onValueChange = {},\n        internalStateTransformation = {\n            it.toInt()\n        },\n        onValueChangeFinished = {\n            onValueChange(it.toInt())\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/EnableBackgroundColorForAlphaFormatsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Transparency\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun EnableBackgroundColorForAlphaFormatsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.background_color_for_alpha_formats),\n        subtitle = stringResource(R.string.background_color_for_alpha_formats_sub),\n        checked = settingsState.enableBackgroundColorForAlphaFormats,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Filled.Transparency\n    )\n}\n"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/EnableLauncherModeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Apps\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun EnableLauncherModeSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.Companion.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.launcher_mode),\n        subtitle = stringResource(R.string.launcher_mode_sub),\n        checked = settingsState.isScreenSelectionLauncherMode,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.Apps\n    )\n}\n"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/EnableLinksPreviewSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Link\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun EnableLinksPreviewSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.links_preview),\n        subtitle = stringResource(R.string.links_preview_sub),\n        checked = settingsState.isLinkPreviewEnabled,\n        onClick = { onClick() },\n        startIcon = Icons.Outlined.Link\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/EnableToolExitConfirmationSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SaveConfirm\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun EnableToolExitConfirmationSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.tool_exit_confirmation),\n        subtitle = stringResource(R.string.tool_exit_confirmation_sub),\n        checked = settingsState.enableToolExitConfirmation,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.SaveConfirm\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ExifWidgetInitialStateSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.DataSaverOff\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ExifWidgetInitialStateSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.force_exif_widget_initial_value),\n        subtitle = stringResource(R.string.force_exif_widget_initial_value_sub),\n        checked = settingsState.exifWidgetInitialState,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.DataSaverOff\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FabAlignmentSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AlignVerticalCenter\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateContentSizeNoClip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.settings.presentation.components.additional.FabPreview\n\n@Composable\nfun FabAlignmentSettingItem(\n    onValueChange: (Float) -> Unit,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.bottom\n) {\n    val settingsState = LocalSettingsState.current\n\n    Row(\n        modifier\n            .height(IntrinsicSize.Max)\n            .container(\n                shape = shape\n            )\n            .animateContentSizeNoClip()\n            .padding(\n                start = 4.dp,\n                top = 4.dp,\n                bottom = 4.dp,\n                end = 4.dp\n            ),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        val derivedValue by remember(settingsState) {\n            derivedStateOf {\n                when (settingsState.fabAlignment) {\n                    Alignment.BottomStart -> 0\n                    Alignment.BottomCenter -> 1\n                    else -> 2\n                }\n            }\n        }\n        Column(\n            modifier = Modifier\n                .weight(1f)\n                .fillMaxHeight()\n                .padding(end = 12.dp)\n        ) {\n            TitleItem(\n                text = stringResource(R.string.fab_alignment),\n                icon = Icons.Rounded.AlignVerticalCenter,\n                modifier = Modifier.padding(\n                    start = 8.dp,\n                    top = 6.dp\n                )\n            )\n            Spacer(modifier = Modifier.weight(1f))\n            EnhancedButtonGroup(\n                modifier = Modifier.padding(horizontal = 4.dp),\n                itemCount = 3,\n                itemContent = {\n                    Text(\n                        stringResource(\n                            when (it) {\n                                0 -> R.string.start_position\n                                1 -> R.string.center_position\n                                else -> R.string.end_position\n                            }\n                        )\n                    )\n                },\n                onIndexChange = {\n                    onValueChange(it.toFloat())\n                },\n                selectedIndex = derivedValue,\n                inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer\n            )\n        }\n        FabPreview(\n            alignment = settingsState.fabAlignment,\n            modifier = Modifier\n                .width(75.dp)\n                .fillMaxHeight()\n        )\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FabShadowsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FabCorner\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun FabShadowsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        enabled = settingsState.borderWidth <= 0.dp,\n        shape = shape,\n        title = stringResource(R.string.fabs_shadow),\n        subtitle = stringResource(R.string.fabs_shadow_sub),\n        checked = settingsState.drawFabShadows,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.FabCorner\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FastSettingsSideSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SettingsTimelapse\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun FastSettingsSideSettingItem(\n    onValueChange: (FastSettingsSide) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            if (it) {\n                onValueChange(FastSettingsSide.CenterEnd)\n            } else {\n                onValueChange(FastSettingsSide.None)\n            }\n        },\n        title = stringResource(R.string.fast_settings_side),\n        subtitle = stringResource(R.string.fast_settings_side_sub),\n        checked = settingsState.fastSettingsSide != FastSettingsSide.None,\n        startIcon = Icons.Outlined.SettingsTimelapse,\n        additionalContent = {\n            AnimatedVisibility(\n                visible = settingsState.fastSettingsSide != FastSettingsSide.None,\n                enter = fadeIn() + expandVertically(),\n                exit = fadeOut() + shrinkVertically()\n            ) {\n                ProvideContainerDefaults(\n                    shape = null,\n                    color = LocalContainerColor.current\n                ) {\n                    Row(\n                        horizontalArrangement = Arrangement.spacedBy(4.dp),\n                        verticalAlignment = Alignment.CenterVertically,\n                        modifier = Modifier\n                            .padding(top = 16.dp)\n                            .height(IntrinsicSize.Max)\n                    ) {\n                        val entries = remember {\n                            listOf(FastSettingsSide.CenterStart, FastSettingsSide.CenterEnd)\n                        }\n\n                        entries.forEachIndexed { index, side ->\n                            val selected = settingsState.fastSettingsSide == side\n                            PreferenceRow(\n                                title = when (side) {\n                                    FastSettingsSide.CenterEnd -> stringResource(R.string.end)\n                                    FastSettingsSide.CenterStart -> stringResource(R.string.start)\n                                    FastSettingsSide.None -> \"\"\n                                },\n                                onClick = {\n                                    onValueChange(side)\n                                },\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = entries.size,\n                                    vertical = false\n                                ),\n                                titleFontStyle = PreferenceItemDefaults.TitleFontStyleCenteredSmall,\n                                startIcon = if (selected) {\n                                    Icons.Rounded.RadioButtonChecked\n                                } else {\n                                    Icons.Rounded.RadioButtonUnchecked\n                                },\n                                drawStartIconContainer = false,\n                                modifier = Modifier\n                                    .weight(1f)\n                                    .fillMaxHeight(),\n                                color = takeColorFromScheme {\n                                    if (selected) tertiaryContainer.copy(0.5f)\n                                    else surfaceContainer\n                                },\n                                contentColor = takeColorFromScheme {\n                                    if (selected) onTertiaryContainer.copy(0.8f)\n                                    else onSurface\n                                },\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FilenamePatternSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Description\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.JAVA_FORMAT_SPECIFICATION\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Date\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Extension\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Height\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.OriginalName\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Prefix\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.PresetInfo\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Rand\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.ScaleMode\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Sequence\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Suffix\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FilenamePattern.Companion.Width\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.ImageToolboxThemeForPreview\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBadge\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.PatternHighlightTransformation\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun FilenamePatternSettingItem(\n    onValueChange: (String) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    filenameCreator: FilenameCreator\n) {\n    val settingsState = LocalSettingsState.current\n    var showEditDialog by rememberSaveable { mutableStateOf(false) }\n\n    val exampleSaveTarget = remember {\n        val originalUri = \"file:///android_asset/svg/emotions/aasparkles.svg\"\n        ImageSaveTarget(\n            imageInfo = ImageInfo(\n                width = 123,\n                height = 456,\n                originalUri = originalUri\n            ),\n            originalUri = originalUri,\n            sequenceNumber = 1,\n            data = ByteArray(1),\n            presetInfo = Preset.Percentage(95)\n        )\n    }\n\n    var value by remember(showEditDialog, settingsState) {\n        mutableStateOf(\n            settingsState.filenamePattern?.takeIf { it.isNotBlank() }\n                ?: if (settingsState.addOriginalFilename) {\n                    FilenamePattern.ForOriginal\n                } else {\n                    FilenamePattern.Default\n                }\n        )\n    }\n\n    val exampleFilename by remember(filenameCreator, value, settingsState) {\n        derivedStateOf {\n            filenameCreator.constructImageFilename(\n                saveTarget = exampleSaveTarget,\n                oneTimePrefix = null,\n                forceNotAddSizeInFilename = false,\n                pattern = value\n            )\n        }\n    }\n\n    PreferenceItem(\n        shape = shape,\n        onClick = {\n            showEditDialog = true\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        title = stringResource(R.string.filename_format),\n        subtitle = exampleFilename,\n        endIcon = Icons.Rounded.MiniEdit,\n        startIcon = Icons.Outlined.Description,\n        modifier = modifier.fillMaxWidth()\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showEditDialog,\n        onDismiss = { showEditDialog = it },\n        title = {\n            TitleItem(\n                icon = Icons.Outlined.Description,\n                text = stringResource(R.string.filename_format)\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(\n                    alpha = if (settingsState.isNightMode) 0.5f\n                    else 1f\n                ),\n                contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                onClick = {\n                    onValueChange(value.trim())\n                    showEditDialog = false\n                },\n                borderColor = MaterialTheme.colorScheme.outlineVariant(\n                    onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                )\n            ) {\n                Text(stringResource(R.string.save))\n            }\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .fillMaxWidth()\n                .clearFocusOnTap()\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(8.dp),\n            horizontalAlignment = Alignment.CenterHorizontally,\n            verticalArrangement = Arrangement.spacedBy(\n                space = 4.dp,\n                alignment = Alignment.CenterVertically\n            ),\n        ) {\n            PreferenceItem(\n                title = stringResource(R.string.filename),\n                subtitle = exampleFilename,\n                modifier = Modifier\n            )\n\n            RoundedTextField(\n                modifier = Modifier\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp\n                    ),\n                value = value,\n                textStyle = MaterialTheme.typography.titleMedium,\n                onValueChange = {\n                    value = it\n                },\n                maxLines = Int.MAX_VALUE,\n                singleLine = false,\n                hint = { Text(stringResource(R.string.format_pattern)) },\n                label = null,\n                visualTransformation = PatternHighlightTransformation.default()\n            )\n\n            Spacer(Modifier.height(4.dp))\n\n            Column(\n                verticalArrangement = Arrangement.spacedBy(\n                    space = 4.dp,\n                    alignment = Alignment.CenterVertically\n                ),\n            ) {\n                val linkHandler = LocalUriHandler.current\n\n                FilenamePattern.entries.forEachIndexed { index, pattern ->\n                    PreferenceItemOverload(\n                        title = when (pattern) {\n                            Date -> pattern.value + \"{pattern}\"\n                            Rand -> pattern.value + \"{count}\"\n                            else -> pattern.value\n                        },\n                        subtitle = when (pattern) {\n                            Prefix -> stringResource(R.string.prefix_pattern_description)\n                            OriginalName -> stringResource(R.string.original_filename_pattern_description)\n                            Width -> stringResource(R.string.width_pattern_description)\n                            Height -> stringResource(R.string.height_pattern_description)\n                            Date -> stringResource(R.string.formatted_timestamp_pattern_description)\n                            Rand -> stringResource(R.string.random_numbers_pattern_description)\n                            Sequence -> stringResource(R.string.sequence_number_pattern_description)\n                            PresetInfo -> stringResource(R.string.preset_info_pattern_description)\n                            ScaleMode -> stringResource(R.string.scale_mode_pattern_description)\n                            Suffix -> stringResource(R.string.suffix_pattern_description)\n                            Extension -> stringResource(R.string.extension_pattern_description)\n                            else -> null\n                        },\n                        badge = if (pattern.hasUpper()) {\n                            {\n                                EnhancedBadge(\n                                    modifier = Modifier\n                                        .align(Alignment.CenterVertically)\n                                        .padding(horizontal = 4.dp, vertical = 2.dp),\n                                    content = { Text(\"A/a\") },\n                                    containerColor = MaterialTheme.colorScheme.secondary,\n                                    contentColor = MaterialTheme.colorScheme.onSecondary\n                                )\n                            }\n                        } else null,\n                        containerColor = takeColorFromScheme {\n                            if (pattern.value in value) {\n                                secondaryContainer\n                            } else {\n                                SafeLocalContainerColor\n                            }\n                        },\n                        contentColor = takeColorFromScheme {\n                            if (pattern.value in value) {\n                                onSecondaryContainer\n                            } else {\n                                onSurface\n                            }\n                        },\n                        endIcon = if (pattern == Date) {\n                            {\n                                Icon(\n                                    imageVector = Icons.Outlined.Info,\n                                    contentDescription = null\n                                )\n                            }\n                        } else null,\n                        onClick = if (pattern == Date) {\n                            {\n                                linkHandler.openUri(JAVA_FORMAT_SPECIFICATION)\n                            }\n                        } else null,\n                        shape = ShapeDefaults.byIndex(\n                            index = index,\n                            size = FilenamePattern.entries.size\n                        ),\n                        modifier = Modifier\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\n@Preview\nprivate fun Preview() = ImageToolboxThemeForPreview(\n    isDarkTheme = true\n) {\n    Surface {\n        FilenamePatternSettingItem(\n            onValueChange = {},\n            filenameCreator = object : FilenameCreator {\n                override fun constructImageFilename(\n                    saveTarget: ImageSaveTarget,\n                    oneTimePrefix: String?,\n                    forceNotAddSizeInFilename: Boolean,\n                    pattern: String?\n                ): String = \"Not yet implemented\"\n\n                override fun constructRandomFilename(\n                    extension: String,\n                    length: Int\n                ): String = \"Not yet implemented\"\n\n                override fun getFilename(uri: String): String = \"Not yet implemented\"\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FilenamePrefixSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Prefix\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun FilenamePrefixSettingItem(\n    onValueChange: (String) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var showChangeFilenameDialog by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceItem(\n        shape = shape,\n        onClick = {\n            showChangeFilenameDialog = true\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        title = stringResource(R.string.prefix),\n        subtitle = (settingsState.filenamePrefix.takeIf { it.isNotEmpty() }\n            ?: stringResource(R.string.empty)),\n        endIcon = Icons.Rounded.MiniEdit,\n        startIcon = Icons.Filled.Prefix,\n        modifier = modifier\n    )\n\n    var value by remember(showChangeFilenameDialog) {\n        mutableStateOf(\n            settingsState.filenamePrefix\n        )\n    }\n    EnhancedAlertDialog(\n        visible = showChangeFilenameDialog,\n        onDismissRequest = { showChangeFilenameDialog = false },\n        icon = {\n            Icon(\n                imageVector = Icons.Filled.Prefix,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(stringResource(R.string.prefix))\n        },\n        text = {\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                OutlinedTextField(\n                    placeholder = {\n                        Text(\n                            text = stringResource(R.string.default_prefix),\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                    },\n                    shape = ShapeDefaults.default,\n                    value = value,\n                    textStyle = MaterialTheme.typography.titleMedium.copy(\n                        textAlign = TextAlign.Center\n                    ),\n                    onValueChange = {\n                        value = it\n                    }\n                )\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(\n                    alpha = if (settingsState.isNightMode) 0.5f\n                    else 1f\n                ),\n                contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                onClick = {\n                    onValueChange(value.trim())\n                    showChangeFilenameDialog = false\n                },\n                borderColor = MaterialTheme.colorScheme.outlineVariant(\n                    onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                ),\n            ) {\n                Text(stringResource(R.string.ok))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FilenameSuffixSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Suffix\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun FilenameSuffixSettingItem(\n    onValueChange: (String) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var showChangeFilenameDialog by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceItem(\n        shape = shape,\n        onClick = {\n            showChangeFilenameDialog = true\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        title = stringResource(R.string.suffix),\n        subtitle = (settingsState.filenameSuffix.takeIf { it.isNotEmpty() }\n            ?: stringResource(R.string.empty)),\n        endIcon = Icons.Rounded.MiniEdit,\n        startIcon = Icons.Filled.Suffix,\n        modifier = modifier.fillMaxWidth()\n    )\n\n    var value by remember(showChangeFilenameDialog) {\n        mutableStateOf(\n            settingsState.filenameSuffix\n        )\n    }\n    EnhancedAlertDialog(\n        visible = showChangeFilenameDialog,\n        onDismissRequest = { showChangeFilenameDialog = false },\n        icon = {\n            Icon(\n                imageVector = Icons.Filled.Suffix,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(stringResource(R.string.suffix))\n        },\n        text = {\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                OutlinedTextField(\n                    shape = ShapeDefaults.default,\n                    value = value,\n                    textStyle = MaterialTheme.typography.titleMedium.copy(\n                        textAlign = TextAlign.Center\n                    ),\n                    onValueChange = {\n                        value = it\n                    }\n                )\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(\n                    alpha = if (settingsState.isNightMode) 0.5f\n                    else 1f\n                ),\n                contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                onClick = {\n                    onValueChange(value.trim())\n                    showChangeFilenameDialog = false\n                },\n                borderColor = MaterialTheme.colorScheme.outlineVariant(\n                    onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                ),\n            ) {\n                Text(stringResource(R.string.ok))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FlingTypeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Animation\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Animation\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun FlingTypeSettingItem(\n    onValueChange: (FlingType) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    var showSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItem(\n        modifier = modifier,\n        title = stringResource(id = R.string.fling_type),\n        startIcon = Icons.Outlined.Animation,\n        subtitle = settingsState.flingType.title,\n        onClick = {\n            showSheet = true\n        },\n        shape = shape,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showSheet,\n        onDismiss = { showSheet = it },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.fling_type),\n                icon = Icons.Rounded.Animation\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showSheet = false\n                },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    ) {\n        Column(\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(8.dp)\n        ) {\n            val entries = FlingType.entries\n\n            entries.forEachIndexed { index, type ->\n                val selected = type == settingsState.flingType\n                PreferenceItem(\n                    onClick = { onValueChange(type) },\n                    title = type.title,\n                    subtitle = type.subtitle,\n                    containerColor = takeColorFromScheme {\n                        if (selected) secondaryContainer\n                        else SafeLocalContainerColor\n                    },\n                    shape = ShapeDefaults.byIndex(index, entries.size),\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .border(\n                            width = settingsState.borderWidth,\n                            color = animateColorAsState(\n                                if (selected) MaterialTheme.colorScheme\n                                    .onSecondaryContainer\n                                    .copy(alpha = 0.5f)\n                                else Color.Transparent\n                            ).value,\n                            shape = ShapeDefaults.byIndex(index, entries.size)\n                        ),\n                    endIcon = if (selected) {\n                        Icons.Rounded.RadioButtonChecked\n                    } else Icons.Rounded.RadioButtonUnchecked\n                )\n            }\n        }\n    }\n}\n\nprivate val FlingType.title: String\n    @Composable\n    get() = when (this) {\n        FlingType.DEFAULT -> stringResource(R.string.android_native)\n        FlingType.SMOOTH -> stringResource(R.string.smooth)\n        FlingType.IOS_STYLE -> stringResource(R.string.ios_style)\n        FlingType.SMOOTH_CURVE -> stringResource(R.string.smooth_curve)\n        FlingType.QUICK_STOP -> stringResource(R.string.quick_stop)\n        FlingType.BOUNCY -> stringResource(R.string.bouncy)\n        FlingType.FLOATY -> stringResource(R.string.floaty)\n        FlingType.SNAPPY -> stringResource(R.string.snappy)\n        FlingType.ULTRA_SMOOTH -> stringResource(R.string.ultra_smooth)\n        FlingType.ADAPTIVE -> stringResource(R.string.adaptive)\n        FlingType.ACCESSIBILITY_AWARE -> stringResource(R.string.accessibility_aware)\n        FlingType.REDUCED_MOTION -> stringResource(R.string.reduced_motion)\n    }\n\nprivate val FlingType.subtitle: String\n    @Composable\n    get() = when (this) {\n        FlingType.DEFAULT -> stringResource(R.string.android_native_sub)\n        FlingType.SMOOTH -> stringResource(R.string.smooth_sub)\n        FlingType.IOS_STYLE -> stringResource(R.string.ios_style_sub)\n        FlingType.SMOOTH_CURVE -> stringResource(R.string.smooth_curve_sub)\n        FlingType.QUICK_STOP -> stringResource(R.string.quick_stop_sub)\n        FlingType.BOUNCY -> stringResource(R.string.bouncy_sub)\n        FlingType.FLOATY -> stringResource(R.string.floaty_sub)\n        FlingType.SNAPPY -> stringResource(R.string.snappy_sub)\n        FlingType.ULTRA_SMOOTH -> stringResource(R.string.ultra_smooth_sub)\n        FlingType.ADAPTIVE -> stringResource(R.string.adaptive_sub)\n        FlingType.ACCESSIBILITY_AWARE -> stringResource(R.string.accessibility_aware_sub)\n        FlingType.REDUCED_MOTION -> stringResource(R.string.reduced_motion_sub)\n    }"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FontScaleSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.TextFields\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport kotlinx.collections.immutable.persistentMapOf\n\n@Composable\nfun FontScaleSettingItem(\n    onValueChange: (Float) -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val resources = LocalResourceManager.current\n\n    var sliderValue by remember(settingsState.fontScale) {\n        mutableFloatStateOf(settingsState.fontScale ?: 0.45f)\n    }\n\n    EnhancedSliderItem(\n        modifier = modifier,\n        shape = shape,\n        value = sliderValue,\n        title = stringResource(R.string.font_scale),\n        icon = Icons.Outlined.TextFields,\n        onValueChange = {\n            sliderValue = it.roundToTwoDigits()\n        },\n        internalStateTransformation = {\n            it.roundToTwoDigits()\n        },\n        onValueChangeFinished = {\n            onValueChange(\n                if (sliderValue < 0.5f) 0f\n                else sliderValue\n            )\n        },\n        valueRange = 0.45f..1.5f,\n        steps = 20,\n        valuesPreviewMapping = remember {\n            persistentMapOf(0.45f to resources.getString(R.string.defaultt))\n        },\n        valueTextTapEnabled = false,\n        additionalContent = {\n            AnimatedVisibility(\n                visible = sliderValue > 1.2f,\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                InfoContainer(\n                    text = stringResource(R.string.using_large_fonts_warn),\n                    textAlign = TextAlign.Start,\n                    containerColor = MaterialTheme.colorScheme.errorContainer.copy(0.4f),\n                    contentColor = MaterialTheme.colorScheme.onErrorContainer.copy(0.7f),\n                    modifier = Modifier.padding(4.dp)\n                )\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/FreeSoftwarePartnerSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.PARTNER_FREE_SOFTWARE\nimport com.t8rin.imagetoolbox.core.domain.utils.Flavor\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.HandshakeAlt\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport java.util.Locale\n\n@Composable\nfun FreeSoftwarePartnerSettingItem(\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    if (Flavor.isFoss() || Locale.getDefault().language != \"ru\") return\n\n    val linkHandler = LocalUriHandler.current\n    PreferenceRow(\n        shape = shape,\n        onClick = {\n            linkHandler.openUri(PARTNER_FREE_SOFTWARE)\n        },\n        startIcon = Icons.Outlined.HandshakeAlt,\n        title = stringResource(R.string.free_software_partner),\n        subtitle = stringResource(R.string.free_software_partner_sub),\n        color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.35f)\n            .compositeOver(MaterialTheme.colorScheme.surface),\n        contentColor = MaterialTheme.colorScheme.onSecondaryContainer.copy(0.9f),\n        modifier = modifier\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/GeneratePreviewsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Preview\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun GeneratePreviewsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.generate_previews),\n        subtitle = stringResource(R.string.generate_previews_sub),\n        checked = settingsState.generatePreviews,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.Preview\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/GroupOptionsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BatchPrediction\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun GroupOptionsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        startIcon = Icons.Outlined.BatchPrediction,\n        title = stringResource(R.string.group_tools_by_type),\n        subtitle = stringResource(R.string.group_tools_by_type_sub),\n        checked = settingsState.groupOptionsByTypes,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/HelpTranslateSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Translate\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.WEBLATE_LINK\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun HelpTranslateSettingItem(\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val linkHandler = LocalUriHandler.current\n    PreferenceItem(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.help_translate),\n        subtitle = stringResource(R.string.help_translate_sub),\n        startIcon = Icons.Rounded.Translate,\n        onClick = {\n            linkHandler.openUri(WEBLATE_LINK)\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/IconShapeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FormatShapes\nimport androidx.compose.material.icons.rounded.Block\nimport androidx.compose.material.icons.rounded.Shuffle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.IconShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun IconShapeSettingItem(\n    value: Int?,\n    onValueChange: (Int) -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    var showPickerSheet by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceRow(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.icon_shape),\n        subtitle = stringResource(R.string.icon_shape_sub),\n        onClick = {\n            showPickerSheet = true\n        },\n        startIcon = Icons.Outlined.FormatShapes,\n        endContent = {\n            Box(\n                modifier = Modifier\n                    .padding(end = 8.dp)\n                    .size(64.dp)\n                    .container(\n                        shape = CloverShape,\n                        color = MaterialTheme.colorScheme\n                            .surfaceVariant\n                            .copy(alpha = 0.5f),\n                        borderColor = MaterialTheme.colorScheme.outlineVariant(\n                            0.2f\n                        )\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                IconShapePreview()\n            }\n        }\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showPickerSheet,\n        onDismiss = { showPickerSheet = false },\n        title = {\n            TitleItem(\n                icon = Icons.Outlined.FormatShapes,\n                text = stringResource(R.string.icon_shape)\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = {\n                    showPickerSheet = false\n                }\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    ) {\n        LazyVerticalGrid(\n            columns = GridCells.Adaptive(55.dp),\n            modifier = Modifier\n                .fillMaxWidth(),\n            verticalArrangement = Arrangement.spacedBy(\n                space = 6.dp,\n                alignment = Alignment.CenterVertically\n            ),\n            horizontalArrangement = Arrangement.spacedBy(\n                space = 6.dp,\n                alignment = Alignment.CenterHorizontally\n            ),\n            contentPadding = PaddingValues(16.dp),\n            flingBehavior = enhancedFlingBehavior()\n        ) {\n            itemsIndexed(IconShape.entries) { index, iconShape ->\n                val selected by remember(index, value) {\n                    derivedStateOf {\n                        index == value\n                    }\n                }\n                val color by animateColorAsState(\n                    if (selected) MaterialTheme.colorScheme.primaryContainer\n                    else SafeLocalContainerColor\n                )\n                val borderColor by animateColorAsState(\n                    if (selected) {\n                        MaterialTheme.colorScheme.onPrimaryContainer.copy(0.7f)\n                    } else MaterialTheme.colorScheme.onSecondaryContainer.copy(\n                        alpha = 0.1f\n                    )\n                )\n                Box(\n                    modifier = Modifier\n                        .aspectRatio(1f)\n                        .container(\n                            color = color,\n                            shape = CloverShape,\n                            borderColor = borderColor,\n                            resultPadding = 0.dp\n                        )\n                        .hapticsClickable {\n                            onValueChange(index)\n                        },\n                    contentAlignment = Alignment.Center\n                ) {\n                    IconShapePreview(iconShape)\n                }\n            }\n            item {\n                val selected by remember(value) {\n                    derivedStateOf {\n                        value == null\n                    }\n                }\n                val color by animateColorAsState(\n                    if (selected) MaterialTheme.colorScheme.primaryContainer\n                    else SafeLocalContainerColor\n                )\n                val borderColor by animateColorAsState(\n                    if (selected) {\n                        MaterialTheme.colorScheme.onPrimaryContainer.copy(0.7f)\n                    } else MaterialTheme.colorScheme.onSecondaryContainer.copy(\n                        alpha = 0.1f\n                    )\n                )\n                Box(\n                    modifier = Modifier\n                        .aspectRatio(1f)\n                        .container(\n                            color = color,\n                            shape = CloverShape,\n                            borderColor = borderColor,\n                            resultPadding = 0.dp\n                        )\n                        .hapticsClickable {\n                            onValueChange(-1)\n                        },\n                    contentAlignment = Alignment.Center\n                ) {\n                    IconShapePreview(iconShape = null)\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun IconShapePreview(\n    iconShape: IconShape? = LocalSettingsState.current.iconShape\n) {\n    val color = MaterialTheme.colorScheme.onSurfaceVariant\n    when (iconShape) {\n        null -> {\n            Icon(\n                imageVector = Icons.Rounded.Block,\n                contentDescription = null,\n                tint = color,\n                modifier = Modifier.size(30.dp)\n            )\n        }\n\n        IconShape.Random -> {\n            Icon(\n                imageVector = Icons.Rounded.Shuffle,\n                contentDescription = null,\n                tint = color,\n                modifier = Modifier.size(30.dp)\n            )\n        }\n\n        else -> {\n            Box(\n                modifier = Modifier\n                    .size(30.dp)\n                    .container(\n                        borderWidth = 2.dp,\n                        borderColor = color,\n                        color = Color.Transparent,\n                        shape = iconShape.shape\n                    )\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ImagePickerModeSettingItemGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.PicturePickerMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun ImagePickerModeSettingItemGroup(\n    onValueChange: (Int) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    val settingsState = LocalSettingsState.current\n    Column(\n        modifier = modifier,\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        val data = remember {\n            PicturePickerMode.entries\n        }\n\n        data.forEachIndexed { index, mode ->\n            val selected = settingsState.picturePickerMode.ordinal == mode.ordinal\n\n            val shape = ShapeDefaults.byIndex(\n                index = index,\n                size = data.size\n            )\n            PreferenceItem(\n                shape = shape,\n                onClick = { onValueChange(mode.ordinal) },\n                title = stringResource(mode.title),\n                startIcon = mode.icon,\n                subtitle = stringResource(mode.subtitle),\n                containerColor = takeColorFromScheme {\n                    if (selected) secondaryContainer.copy(0.7f)\n                    else SafeLocalContainerColor\n                },\n                contentColor = takeColorFromScheme {\n                    if (selected) onSecondaryContainer\n                    else MaterialTheme.colorScheme.onBackground\n                },\n                endIcon = if (selected) {\n                    Icons.Rounded.RadioButtonChecked\n                } else {\n                    Icons.Rounded.RadioButtonUnchecked\n                },\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp)\n                    .border(\n                        width = settingsState.borderWidth,\n                        color = animateColorAsState(\n                            if (selected) {\n                                MaterialTheme.colorScheme.onSecondaryContainer.copy(0.5f)\n                            } else Color.Transparent\n                        ).value,\n                        shape = shape\n                    )\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/IssueTrackerSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.BugReport\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.ISSUE_TRACKER\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun IssueTrackerSettingItem(\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val linkHandler = LocalUriHandler.current\n    PreferenceItem(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.issue_tracker),\n        subtitle = stringResource(R.string.issue_tracker_sub),\n        startIcon = Icons.Outlined.BugReport,\n        onClick = {\n            linkHandler.openUri(ISSUE_TRACKER)\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/KeepDateTimeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.AccessTime\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun KeepDateTimeSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.keep_date_time),\n        subtitle = stringResource(R.string.keep_date_time_sub),\n        checked = settingsState.keepDateTime,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.AccessTime\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/LockDrawOrientationSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileRotateLock\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun LockDrawOrientationSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        title = stringResource(R.string.lock_draw_orientation),\n        subtitle = stringResource(R.string.lock_draw_orientation_sub),\n        checked = settingsState.lockDrawOrientation,\n        startIcon = Icons.Outlined.MobileRotateLock\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/MagnifierSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ZoomIn\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun MagnifierSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.magnifier),\n        subtitle = stringResource(R.string.magnifier_sub),\n        checked = settingsState.magnifierEnabled,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.ZoomIn\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/MainScreenTitleSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Title\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun MainScreenTitleSettingItem(\n    onValueChange: (String) -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var showDialog by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceItem(\n        shape = shape,\n        onClick = {\n            showDialog = true\n        },\n        title = stringResource(R.string.main_screen_title),\n        subtitle = settingsState.mainScreenTitle,\n        endIcon = Icons.Rounded.MiniEdit,\n        startIcon = Icons.Rounded.Title,\n        modifier = modifier\n    )\n\n    var value by remember(showDialog) {\n        mutableStateOf(\n            settingsState.mainScreenTitle\n        )\n    }\n    EnhancedAlertDialog(\n        visible = showDialog,\n        onDismissRequest = { showDialog = false },\n        icon = {\n            Icon(\n                imageVector = Icons.Rounded.Title,\n                contentDescription = null\n            )\n        },\n        title = {\n            Text(stringResource(R.string.main_screen_title))\n        },\n        text = {\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                OutlinedTextField(\n                    placeholder = {\n                        Text(\n                            text = stringResource(R.string.app_name),\n                            textAlign = TextAlign.Center,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                    },\n                    shape = ShapeDefaults.default,\n                    value = value,\n                    textStyle = MaterialTheme.typography.titleMedium.copy(\n                        textAlign = TextAlign.Center\n                    ),\n                    onValueChange = {\n                        value = it\n                    }\n                )\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(\n                    alpha = if (settingsState.isNightMode) 0.5f\n                    else 1f\n                ),\n                contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                onClick = {\n                    onValueChange(value.trim())\n                    showDialog = false\n                },\n                borderColor = MaterialTheme.colorScheme.outlineVariant(\n                    onTopOf = MaterialTheme.colorScheme.secondaryContainer\n                ),\n            ) {\n                Text(stringResource(R.string.ok))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/NightModeSettingItemGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.DarkMode\nimport androidx.compose.material.icons.outlined.LightMode\nimport androidx.compose.material.icons.outlined.SettingsSuggest\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.NightMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun NightModeSettingItemGroup(\n    value: NightMode,\n    onValueChange: (NightMode) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Column(\n        modifier = modifier,\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        val settingsState = LocalSettingsState.current\n        listOf(\n            Triple(\n                stringResource(R.string.dark),\n                Icons.Outlined.DarkMode,\n                NightMode.Dark\n            ),\n            Triple(\n                stringResource(R.string.light),\n                Icons.Outlined.LightMode,\n                NightMode.Light\n            ),\n            Triple(\n                stringResource(R.string.system),\n                Icons.Outlined.SettingsSuggest,\n                NightMode.System\n            ),\n        ).forEachIndexed { index, (title, icon, nightMode) ->\n            val selected = nightMode == value\n            val shape = ShapeDefaults.byIndex(index, 3)\n            PreferenceItem(\n                onClick = { onValueChange(nightMode) },\n                title = title,\n                containerColor = takeColorFromScheme {\n                    if (selected) secondaryContainer.copy(0.7f)\n                    else SafeLocalContainerColor\n                },\n                shape = shape,\n                startIcon = icon,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 8.dp)\n                    .border(\n                        width = settingsState.borderWidth,\n                        color = animateColorAsState(\n                            if (selected) MaterialTheme.colorScheme\n                                .onSecondaryContainer\n                                .copy(alpha = 0.5f)\n                            else Color.Transparent\n                        ).value,\n                        shape = shape\n                    ),\n                endIcon = if (selected) {\n                    Icons.Rounded.RadioButtonChecked\n                } else Icons.Rounded.RadioButtonUnchecked\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/OneTimeSaveLocationSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.LocationSearching\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun OneTimeSaveLocationSettingItem(\n    shape: Shape = ShapeDefaults.default,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    var showDialog by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceItem(\n        shape = shape,\n        onClick = { showDialog = true },\n        title = stringResource(R.string.one_time_save_location),\n        subtitle = stringResource(R.string.one_time_save_location_sub),\n        startIcon = Icons.Rounded.LocationSearching,\n        endIcon = Icons.Rounded.MiniEdit,\n        modifier = modifier\n    )\n    OneTimeSaveLocationSelectionDialog(\n        visible = showDialog,\n        onDismiss = { showDialog = false },\n        onSaveRequest = null\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/OpenEditInsteadOfPreviewSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.EditAlt\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun OpenEditInsteadOfPreviewSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.open_edit_instead_of_preview),\n        subtitle = stringResource(R.string.open_edit_instead_of_preview_sub),\n        checked = settingsState.openEditInsteadOfPreview,\n        onClick = { onClick() },\n        startIcon = Icons.Rounded.EditAlt\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/OpenSourceLicensesSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.License\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun OpenSourceLicensesSettingItem(\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    onClick: () -> Unit\n) {\n    PreferenceItem(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.open_source_licenses),\n        subtitle = stringResource(R.string.open_source_licenses_sub),\n        startIcon = Icons.Outlined.License,\n        onClick = onClick\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/OverwriteFilesSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FileReplace\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun OverwriteFilesSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None || settingsState.filenameBehavior is FilenameBehavior.Overwrite,\n        title = stringResource(R.string.overwrite_files),\n        subtitle = stringResource(R.string.overwrite_files_sub),\n        checked = settingsState.filenameBehavior is FilenameBehavior.Overwrite,\n        startIcon = Icons.Outlined.FileReplace\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/PresetsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Numbers\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalEditPresetsController\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun PresetsSettingItem(\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val editPresetsController = LocalEditPresetsController.current\n    val settingsState = LocalSettingsState.current\n    PreferenceItem(\n        shape = shape,\n        onClick = editPresetsController::open,\n        title = stringResource(R.string.values),\n        subtitle = settingsState.presets.joinToString(\", \"),\n        startIcon = Icons.Outlined.Numbers,\n        endIcon = Icons.Rounded.MiniEdit,\n        modifier = modifier\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/RandomizeFilenameSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Symbol\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun RandomizeFilenameSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None || settingsState.filenameBehavior is FilenameBehavior.Random,\n        onClick = {\n            onClick()\n        },\n        title = stringResource(R.string.randomize_filename),\n        subtitle = stringResource(R.string.randomize_filename_sub),\n        checked = settingsState.filenameBehavior is FilenameBehavior.Random,\n        startIcon = Icons.Rounded.Symbol\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ReplaceSequenceNumberSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Numeric\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ReplaceSequenceNumberSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None,\n        title = stringResource(R.string.replace_sequence_number),\n        subtitle = stringResource(R.string.replace_sequence_number_sub),\n        checked = settingsState.addSequenceNumber,\n        startIcon = Icons.Filled.Numeric\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ResetSettingsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.RestartAlt\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContentColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun ResetSettingsSettingItem(\n    onReset: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    var showResetDialog by remember { mutableStateOf(false) }\n\n    CompositionLocalProvider(\n        LocalIconShapeContentColor provides MaterialTheme.colorScheme.onErrorContainer,\n        LocalIconShapeContainerColor provides MaterialTheme.colorScheme.errorContainer\n    ) {\n        PreferenceItem(\n            onClick = {\n                showResetDialog = true\n            },\n            shape = shape,\n            modifier = modifier,\n            containerColor = MaterialTheme.colorScheme\n                .errorContainer\n                .copy(alpha = 0.5f),\n            title = stringResource(R.string.reset),\n            subtitle = stringResource(R.string.reset_settings_sub),\n            startIcon = Icons.Rounded.RestartAlt,\n            overrideIconShapeContentColor = true\n        )\n    }\n\n    ResetDialog(\n        visible = showResetDialog,\n        onDismiss = {\n            showResetDialog = false\n        },\n        onReset = {\n            showResetDialog = false\n            onReset()\n        },\n        title = stringResource(R.string.reset),\n        text = stringResource(R.string.reset_settings_sub),\n        icon = Icons.Rounded.RestartAlt\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/RestoreSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.DownloadFile\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n@Composable\nfun RestoreSettingItem(\n    onObtainBackupFile: (uri: Uri) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val filePicker = rememberFilePicker(onSuccess = onObtainBackupFile)\n\n    PreferenceItem(\n        onClick = filePicker::pickFile,\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.restore),\n        subtitle = stringResource(R.string.restore_sub),\n        startIcon = Icons.Outlined.DownloadFile\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SavingFolderSettingItemGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FolderShared\nimport androidx.compose.material.icons.outlined.FolderSpecial\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFolderPicker\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.utils.uiPath\n\n@Composable\nfun SavingFolderSettingItemGroup(\n    modifier: Modifier = Modifier,\n    onValueChange: (Uri?) -> Unit\n) {\n    Column(modifier) {\n        val settingsState = LocalSettingsState.current\n        val currentFolderUri = settingsState.saveFolderUri\n        val launcher = rememberFolderPicker(\n            onSuccess = onValueChange\n        )\n\n        PreferenceItem(\n            shape = ShapeDefaults.top,\n            onClick = { onValueChange(null) },\n            title = stringResource(R.string.def),\n            subtitle = stringResource(R.string.default_folder),\n            containerColor = takeColorFromScheme {\n                if (currentFolderUri == null) secondaryContainer.copy(0.7f)\n                else SafeLocalContainerColor\n            },\n            startIcon = Icons.Outlined.FolderSpecial,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 8.dp)\n                .border(\n                    width = settingsState.borderWidth,\n                    color = animateColorAsState(\n                        if (currentFolderUri == null) {\n                            MaterialTheme.colorScheme.onSecondaryContainer.copy(0.5f)\n                        } else Color.Transparent\n                    ).value,\n                    shape = ShapeDefaults.top\n                )\n        )\n        Spacer(modifier = Modifier.height(4.dp))\n        PreferenceItem(\n            shape = ShapeDefaults.bottom,\n            onClick = {\n                launcher.pickFolder(currentFolderUri)\n            },\n            title = stringResource(R.string.custom),\n            subtitle = currentFolderUri.uiPath(\n                default = stringResource(R.string.unspecified)\n            ),\n            containerColor = takeColorFromScheme {\n                if (currentFolderUri != null) secondaryContainer.copy(0.7f)\n                else Color.Unspecified\n            },\n            startIcon = Icons.Outlined.FolderShared,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 8.dp)\n                .border(\n                    width = settingsState.borderWidth,\n                    color = animateColorAsState(\n                        if (currentFolderUri != null) {\n                            MaterialTheme.colorScheme.onSecondaryContainer.copy(0.5f)\n                        } else Color.Transparent\n                    ).value,\n                    shape = ShapeDefaults.bottom\n                )\n        )\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ScreenOrderSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.FormatLineSpacing\nimport androidx.compose.material.icons.rounded.DragHandle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.BatchPrediction\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Stacks\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.longPress\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.press\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport sh.calvin.reorderable.ReorderableItem\nimport sh.calvin.reorderable.rememberReorderableLazyListState\n\n@Composable\nfun ScreenOrderSettingItem(\n    onValueChange: (List<Screen>) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val screenList by remember(settingsState.screenList, settingsState.favoriteScreenList) {\n        derivedStateOf {\n            val fav = settingsState.favoriteScreenList.mapNotNull {\n                Screen.entries.find { s -> s.id == it }\n            }\n\n            val other = settingsState.screenList.mapNotNull {\n                Screen.entries.find { s -> s.id == it }\n            }.ifEmpty { Screen.entries }.filter {\n                it !in fav\n            }\n\n            fav.plus(other).distinctBy { it.id }\n        }\n    }\n    var showArrangementSheet by rememberSaveable { mutableStateOf(false) }\n\n    PreferenceItem(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            showArrangementSheet = true\n        },\n        onDisabledClick = {\n            AppToastHost.showToast(\n                icon = Icons.Outlined.BatchPrediction,\n                message = getString(R.string.cannot_change_arrangement_while_options_grouping_enabled)\n            )\n        },\n        enabled = !settingsState.groupOptionsByTypes,\n        startIcon = Icons.Outlined.FormatLineSpacing,\n        title = stringResource(R.string.order),\n        subtitle = stringResource(R.string.order_sub),\n        endIcon = Icons.Rounded.MiniEdit,\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showArrangementSheet,\n        onDismiss = {\n            showArrangementSheet = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.order),\n                icon = Icons.Rounded.Stacks\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { showArrangementSheet = false }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        sheetContent = {\n            Box {\n                val data = remember(screenList) { mutableStateOf(screenList) }\n                val listState = rememberLazyListState()\n                val haptics = LocalHapticFeedback.current\n                val state = rememberReorderableLazyListState(\n                    lazyListState = listState,\n                    onMove = { from, to ->\n                        haptics.press()\n                        data.value = data.value.toMutableList().apply {\n                            add(to.index, removeAt(from.index))\n                        }\n                    }\n                )\n                LazyColumn(\n                    state = listState,\n                    contentPadding = PaddingValues(8.dp),\n                    verticalArrangement = Arrangement.spacedBy(4.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    itemsIndexed(\n                        items = data.value,\n                        key = { _, s -> s.id }\n                    ) { index, screen ->\n                        ReorderableItem(\n                            state = state,\n                            key = screen.id\n                        ) { isDragging ->\n                            PreferenceItem(\n                                modifier = Modifier\n                                    .fillMaxWidth()\n                                    .longPressDraggableHandle(\n                                        onDragStarted = {\n                                            haptics.longPress()\n                                        },\n                                        onDragStopped = {\n                                            onValueChange(data.value)\n                                        }\n                                    )\n                                    .scale(\n                                        animateFloatAsState(\n                                            if (isDragging) 1.05f\n                                            else 1f\n                                        ).value\n                                    ),\n                                title = stringResource(screen.title),\n                                subtitle = stringResource(screen.subtitle),\n                                startIcon = screen.icon,\n                                endIcon = Icons.Rounded.DragHandle,\n                                containerColor = if (screen.id in settingsState.favoriteScreenList) {\n                                    MaterialTheme.colorScheme.secondaryContainer\n                                } else Color.Unspecified,\n                                shape = ShapeDefaults.byIndex(\n                                    index = index,\n                                    size = data.value.size\n                                )\n                            )\n                        }\n                    }\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ScreenSearchSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.LayersSearchOutline\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ScreenSearchSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        title = stringResource(R.string.search_option),\n        startIcon = Icons.Outlined.LayersSearchOutline,\n        subtitle = stringResource(R.string.search_option_sub),\n        checked = settingsState.screensSearchEnabled,\n        onClick = {\n            onClick()\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SearchableSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.IconShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.Setting\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.SettingsGroup\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.IconShapeContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\n\n@Composable\ninternal fun SearchableSettingItem(\n    modifier: Modifier = Modifier,\n    group: SettingsGroup,\n    setting: Setting,\n    shape: Shape,\n    component: SettingsComponent,\n    onNavigateToEasterEgg: () -> Unit,\n    onNavigateToSettings: () -> Unit,\n    onNavigateToLibrariesInfo: () -> Unit,\n    isUpdateAvailable: Boolean\n) {\n    Column(\n        modifier = modifier.container(\n            resultPadding = 0.dp,\n            shape = shape\n        )\n    ) {\n        val settingState = LocalSettingsState.current\n        val iconShape = remember(settingState.iconShape) {\n            derivedStateOf {\n                settingState.iconShape?.takeOrElseFrom(IconShape.entries)\n            }\n        }.value\n\n        Row(\n            modifier = Modifier.padding(8.dp),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            IconShapeContainer(\n                iconShape = iconShape?.copy(\n                    iconSize = 16.dp\n                )\n            ) {\n                Icon(\n                    imageVector = group.icon,\n                    contentDescription = null,\n                    modifier = Modifier.size(16.dp)\n                )\n            }\n            Spacer(Modifier.width(8.dp))\n            Text(\n                text = stringResource(id = group.titleId),\n                fontSize = 12.sp\n            )\n        }\n        val itemShape = when (setting) {\n            is Setting.ImagePickerMode -> null\n            is Setting.NightMode -> null\n            else -> ShapeDefaults.small\n        }\n        ProvideContainerDefaults(itemShape) {\n            SettingItem(\n                setting = setting,\n                component = component,\n                isUpdateAvailable = isUpdateAvailable,\n                onNavigateToEasterEgg = onNavigateToEasterEgg,\n                onNavigateToSettings = onNavigateToSettings,\n                onNavigateToLibrariesInfo = onNavigateToLibrariesInfo\n            )\n        }\n        Spacer(Modifier.height(8.dp))\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SecureModeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Security\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun SecureModeSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.secure_mode),\n        subtitle = stringResource(R.string.secure_mode_sub),\n        checked = settingsState.isSecureMode,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.Security\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SendLogsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileShare\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.animation.springySpec\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCircularProgressIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport kotlinx.coroutines.delay\n\n@Composable\nfun SendLogsSettingItem(\n    onClick: (onComplete: () -> Unit) -> Unit,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.center,\n    color: Color = MaterialTheme.colorScheme.mixedContainer.copy(0.9f),\n    contentColor: Color = MaterialTheme.colorScheme.onMixedContainer\n) {\n    var isLoading by rememberSaveable {\n        mutableStateOf(false)\n    }\n    val progressAnimatable = remember { Animatable(if (isLoading) 1f else 0f) }\n    val progress = progressAnimatable.value\n\n    LaunchedEffect(isLoading) {\n        delay(400)\n        if (isLoading) {\n            progressAnimatable.animateTo(\n                targetValue = 1f,\n                animationSpec = springySpec()\n            )\n        } else {\n            progressAnimatable.animateTo(\n                targetValue = 0f,\n                animationSpec = tween(200)\n            )\n        }\n    }\n\n    PreferenceItemOverload(\n        contentColor = contentColor,\n        shape = shape,\n        onClick = {\n            isLoading = true\n            onClick { isLoading = false }\n        },\n        startIcon = {\n            Icon(\n                imageVector = Icons.Outlined.MobileShare,\n                contentDescription = null\n            )\n        },\n        title = stringResource(R.string.send_logs),\n        subtitle = stringResource(R.string.send_logs_sub),\n        containerColor = color,\n        modifier = modifier,\n        endIcon = if (progress > 0f) {\n            {\n                EnhancedCircularProgressIndicator(\n                    modifier = Modifier.size(24.dp * progress),\n                    trackColor = MaterialTheme.colorScheme.primary.copy(0.2f),\n                    strokeWidth = 3.dp\n                )\n            }\n        } else null\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SettingGroupItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Settings\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSimpleSettingsInteractor\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport kotlinx.coroutines.launch\n\n@Composable\nfun SettingGroupItem(\n    groupKey: Int,\n    icon: ImageVector,\n    text: String,\n    initialState: Boolean = false,\n    modifier: Modifier = Modifier\n        .fillMaxWidth()\n        .padding(2.dp),\n    content: @Composable ColumnScope.(Boolean) -> Unit\n) {\n    val settingsState = LocalSettingsState.current\n\n    val initialState =\n        settingsState.settingGroupsInitialVisibility[groupKey] ?: initialState\n\n    val simpleSettingsInteractor = LocalSimpleSettingsInteractor.current\n    val scope = rememberCoroutineScope()\n\n    ExpandableItem(\n        modifier = modifier,\n        visibleContent = {\n            TitleItem(\n                modifier = Modifier.padding(start = 8.dp),\n                icon = icon,\n                text = text\n            )\n        },\n        color = takeColorFromScheme {\n            surfaceContainer.blend(\n                surfaceContainerLowest, 0.4f\n            )\n        },\n        onLongClick = {\n            scope.launch {\n                simpleSettingsInteractor.toggleSettingsGroupVisibility(\n                    key = groupKey,\n                    value = !initialState\n                )\n\n                AppToastHost.showToast(\n                    message = getString(\n                        if (initialState) {\n                            R.string.settings_group_visibility_hidden\n                        } else {\n                            R.string.settings_group_visibility_visible\n                        },\n                        text\n                    ),\n                    icon = Icons.Outlined.Settings\n                )\n            }\n        },\n        expandableContent = content,\n        initialState = initialState\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.activity.compose.LocalActivity\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileDownloadOff\nimport androidx.compose.material.icons.rounded.Save\nimport androidx.compose.material.icons.rounded.TextFields\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.Setting\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isInstalledFromPlayStore\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalContainerShape\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberCurrentLifecycleEvent\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun SettingItem(\n    setting: Setting,\n    component: SettingsComponent,\n    onNavigateToEasterEgg: () -> Unit,\n    onNavigateToSettings: () -> Unit,\n    onNavigateToLibrariesInfo: () -> Unit,\n    isUpdateAvailable: Boolean,\n    containerColor: Color = MaterialTheme.colorScheme.surface,\n) {\n    ProvideContainerDefaults(\n        color = containerColor,\n        shape = LocalContainerShape.current\n    ) {\n        when (setting) {\n            Setting.AddFileSize -> {\n                AddFileSizeSettingItem(onClick = component::toggleAddFileSize)\n            }\n\n            Setting.AddOriginalFilename -> {\n                AddOriginalFilenameSettingItem(onClick = component::toggleAddOriginalFilename)\n            }\n\n            Setting.AllowBetas -> {\n                if (!appContext.isInstalledFromPlayStore()) {\n                    AllowBetasSettingItem(\n                        onClick = {\n                            component.toggleAllowBetas()\n                            component.tryGetUpdate()\n                        }\n                    )\n                }\n            }\n\n            Setting.AllowImageMonet -> {\n                AllowImageMonetSettingItem(onClick = component::toggleAllowImageMonet)\n            }\n\n            Setting.AmoledMode -> {\n                AmoledModeSettingItem(onClick = component::toggleAmoledMode)\n            }\n\n            Setting.Analytics -> {\n                AnalyticsSettingItem(onClick = component::toggleAllowCollectAnalytics)\n            }\n\n            Setting.Author -> {\n                AuthorSettingItem()\n            }\n\n            Setting.AutoCacheClear -> {\n                AutoCacheClearSettingItem(onClick = component::toggleClearCacheOnLaunch)\n            }\n\n            Setting.AutoCheckUpdates -> {\n                AutoCheckUpdatesSettingItem(onClick = component::toggleShowUpdateDialog)\n            }\n\n            Setting.Backup -> {\n                BackupSettingItem(\n                    onCreateBackupFilename = component::createBackupFilename,\n                    onCreateBackup = component::createBackup\n                )\n            }\n\n            Setting.BorderThickness -> {\n                BorderThicknessSettingItem(onValueChange = component::setBorderWidth)\n            }\n\n            Setting.ChangeFont -> {\n                val context = LocalComponentActivity.current\n                ChangeFontSettingItem(\n                    onValueChange = { font ->\n                        component.setFont(font.asDomain())\n                        context.recreate()\n                    },\n                    onAddFont = {\n                        component.importCustomFont(\n                            uri = it,\n                            onSuccess = AppToastHost::showConfetti,\n                            onFailure = {\n                                AppToastHost.showToast(\n                                    message = getString(R.string.wrong_font),\n                                    icon = Icons.Rounded.TextFields\n                                )\n                            }\n                        )\n                    },\n                    onRemoveFont = component::removeCustomFont,\n                    onExportFonts = component::exportFonts\n                )\n            }\n\n            Setting.ChangeLanguage -> {\n                ChangeLanguageSettingItem()\n            }\n\n            Setting.ClearCache -> {\n                val lifecycleEvent = rememberCurrentLifecycleEvent()\n                ClearCacheSettingItem(\n                    value = remember(lifecycleEvent) {\n                        component.getReadableCacheSize()\n                    },\n                    onClearCache = component::clearCache\n                )\n            }\n\n            Setting.ColorScheme -> {\n                ColorSchemeSettingItem(\n                    onToggleInvertColors = component::toggleInvertColors,\n                    onSetThemeStyle = component::setThemeStyle,\n                    onUpdateThemeContrast = component::setThemeContrast,\n                    onUpdateColorTuple = component::setColorTuple,\n                    onUpdateColorTuples = component::setColorTuples,\n                    onToggleUseEmojiAsPrimaryColor = component::toggleUseEmojiAsPrimaryColor\n                )\n            }\n\n            Setting.Crashlytics -> {\n                CrashlyticsSettingItem(onClick = component::toggleAllowCollectCrashlytics)\n            }\n\n            Setting.CurrentVersionCode -> {\n                var clicks by rememberSaveable {\n                    mutableIntStateOf(0)\n                }\n                LaunchedEffect(clicks) {\n                    if (clicks >= 3) {\n                        onNavigateToEasterEgg()\n                        clicks = 0\n                    }\n\n                    delay(500L) //debounce\n\n                    if (clicks == 0) return@LaunchedEffect\n\n                    AppToastHost.dismissToasts()\n                    if (clicks == 1) {\n                        component.tryGetUpdate(true) {\n                            AppToastHost.showToast(\n                                icon = Icons.Rounded.FileDownloadOff,\n                                message = getString(R.string.no_updates)\n                            )\n                        }\n                    }\n                }\n\n                CurrentVersionCodeSettingItem(\n                    isUpdateAvailable = isUpdateAvailable,\n                    onClick = { clicks++ }\n                )\n            }\n\n            Setting.Donate -> {\n                DonateSettingItem()\n            }\n\n            Setting.DynamicColors -> {\n                DynamicColorsSettingItem(onClick = component::toggleDynamicColors)\n            }\n\n            Setting.Emoji -> {\n                EmojiSettingItem(\n                    onAddColorTupleFromEmoji = component::addColorTupleFromEmoji,\n                    selectedEmojiIndex = component.settingsState.selectedEmoji ?: 0,\n                    onUpdateEmoji = component::setEmoji\n                )\n            }\n\n            Setting.EmojisCount -> {\n                EmojisCountSettingItem(onValueChange = component::setEmojisCount)\n            }\n\n            Setting.FabAlignment -> {\n                FabAlignmentSettingItem(onValueChange = component::setAlignment)\n            }\n\n            Setting.FilenamePrefix -> {\n                FilenamePrefixSettingItem(onValueChange = component::setFilenamePrefix)\n            }\n\n            Setting.FilenameSuffix -> {\n                FilenameSuffixSettingItem(onValueChange = component::setFilenameSuffix)\n            }\n\n            Setting.FontScale -> {\n                val context = LocalComponentActivity.current\n                FontScaleSettingItem(\n                    onValueChange = {\n                        component.setFontScale(it)\n                        context.recreate()\n                    }\n                )\n            }\n\n            Setting.GroupOptions -> {\n                GroupOptionsSettingItem(onClick = component::toggleGroupOptionsByType)\n            }\n\n            Setting.HelpTranslate -> {\n                HelpTranslateSettingItem()\n            }\n\n            Setting.ImagePickerMode -> {\n                ImagePickerModeSettingItemGroup(onValueChange = component::setImagePickerMode)\n            }\n\n            Setting.IssueTracker -> {\n                IssueTrackerSettingItem()\n            }\n\n            Setting.LockDrawOrientation -> {\n                LockDrawOrientationSettingItem(onClick = component::toggleLockDrawOrientation)\n            }\n\n            Setting.NightMode -> {\n                NightModeSettingItemGroup(\n                    value = component.settingsState.nightMode,\n                    onValueChange = component::setNightMode\n                )\n            }\n\n            Setting.Presets -> {\n                PresetsSettingItem()\n            }\n\n            Setting.RandomizeFilename -> {\n                RandomizeFilenameSettingItem(onClick = component::toggleRandomizeFilename)\n            }\n\n            Setting.ReplaceSequenceNumber -> {\n                ReplaceSequenceNumberSettingItem(onClick = component::toggleAddSequenceNumber)\n            }\n\n            Setting.OverwriteFiles -> {\n                OverwriteFilesSettingItem(onClick = component::toggleOverwriteFiles)\n            }\n\n            Setting.Reset -> {\n                ResetSettingsSettingItem(onReset = component::resetSettings)\n            }\n\n            Setting.Restore -> {\n                val scope = rememberCoroutineScope()\n                val context = LocalActivity.current\n\n                RestoreSettingItem(\n                    onObtainBackupFile = { uri ->\n                        component.restoreBackupFrom(\n                            uri = uri,\n                            onSuccess = {\n                                scope.launch {\n                                    AppToastHost.showConfetti()\n                                    //Wait for confetti to appear, then trigger font scale adjustment\n                                    delay(300L)\n                                    context?.recreate()\n                                }\n                                AppToastHost.showToast(\n                                    message = getString(R.string.settings_restored),\n                                    icon = Icons.Rounded.Save\n                                )\n                            },\n                            onFailure = AppToastHost::showFailureToast\n                        )\n                    }\n                )\n            }\n\n            Setting.SavingFolder -> {\n                SavingFolderSettingItemGroup(onValueChange = component::setSaveFolderUri)\n            }\n\n            Setting.ScreenOrder -> {\n                ScreenOrderSettingItem(onValueChange = component::setScreenOrder)\n            }\n\n            Setting.ScreenSearch -> {\n                ScreenSearchSettingItem(onClick = component::toggleScreenSearchEnabled)\n            }\n\n            Setting.SourceCode -> {\n                SourceCodeSettingItem()\n            }\n\n            Setting.TelegramGroup -> {\n                TelegramGroupSettingItem()\n            }\n\n            Setting.TelegramChannel -> {\n                TelegramChannelSettingItem()\n            }\n\n            Setting.FreeSoftwarePartner -> {\n                FreeSoftwarePartnerSettingItem()\n            }\n\n            Setting.CheckUpdatesButton -> {\n                CheckUpdatesButtonSettingItem(\n                    onClick = {\n                        component.tryGetUpdate(true) {\n                            AppToastHost.showToast(\n                                icon = Icons.Rounded.FileDownloadOff,\n                                message = getString(R.string.no_updates)\n                            )\n                        }\n                    }\n                )\n            }\n\n            Setting.ContainerShadows -> {\n                ContainerShadowsSettingItem(onClick = component::toggleDrawContainerShadows)\n            }\n\n            Setting.ButtonShadows -> {\n                ButtonShadowsSettingItem(onClick = component::toggleDrawButtonShadows)\n            }\n\n            Setting.FABShadows -> {\n                FabShadowsSettingItem(onClick = component::toggleDrawFabShadows)\n            }\n\n            Setting.SliderShadows -> {\n                SliderShadowsSettingItem(onClick = component::toggleDrawSliderShadows)\n            }\n\n            Setting.SwitchShadows -> {\n                SwitchShadowsSettingItem(onClick = component::toggleDrawSwitchShadows)\n            }\n\n            Setting.AppBarShadows -> {\n                AppBarShadowsSettingItem(onClick = component::toggleDrawAppBarShadows)\n            }\n\n            Setting.AutoPinClipboard -> {\n                AutoPinClipboardSettingItem(onClick = component::toggleAutoPinClipboard)\n            }\n\n            Setting.AutoPinClipboardOnlyClip -> {\n                AutoPinClipboardOnlyClipSettingItem(onClick = component::toggleAutoPinClipboardOnlyClip)\n            }\n\n            Setting.VibrationStrength -> {\n                VibrationStrengthSettingItem(onValueChange = component::setVibrationStrength)\n            }\n\n            Setting.DefaultScaleMode -> {\n                DefaultScaleModeSettingItem(onValueChange = component::setDefaultImageScaleMode)\n            }\n\n            Setting.DefaultColorSpace -> {\n                DefaultColorSpaceSettingItem(onValueChange = component::setDefaultImageScaleMode)\n            }\n\n            Setting.SwitchType -> {\n                SwitchTypeSettingItem(onValueChange = component::setSwitchType)\n            }\n\n            Setting.Magnifier -> {\n                MagnifierSettingItem(onClick = component::toggleMagnifierEnabled)\n            }\n\n            Setting.ExifWidgetInitialState -> {\n                ExifWidgetInitialStateSettingItem(onClick = component::toggleExifWidgetInitialState)\n            }\n\n            Setting.BrightnessEnforcement -> {\n                BrightnessEnforcementSettingItem(onValueChange = component::setScreensWithBrightnessEnforcement)\n            }\n\n            Setting.Confetti -> {\n                ConfettiSettingItem(onClick = component::toggleConfettiEnabled)\n            }\n\n            Setting.SecureMode -> {\n                SecureModeSettingItem(onClick = component::toggleSecureMode)\n            }\n\n            Setting.UseRandomEmojis -> {\n                UseRandomEmojisSettingItem(onClick = component::toggleUseRandomEmojis)\n            }\n\n            Setting.IconShape -> {\n                IconShapeSettingItem(\n                    value = component.settingsState.iconShape,\n                    onValueChange = component::setIconShape\n                )\n            }\n\n            Setting.DragHandleWidth -> {\n                DragHandleWidthSettingItem(onValueChange = component::setDragHandleWidth)\n            }\n\n            Setting.ConfettiType -> {\n                ConfettiTypeSettingItem(onValueChange = component::setConfettiType)\n            }\n\n            Setting.AllowAutoClipboardPaste -> {\n                AllowAutoClipboardPasteSettingItem(onClick = component::toggleAllowAutoClipboardPaste)\n            }\n\n            Setting.ConfettiHarmonizer -> {\n                ConfettiHarmonizationColorSettingItem(onValueChange = component::setConfettiHarmonizer)\n            }\n\n            Setting.ConfettiHarmonizationLevel -> {\n                ConfettiHarmonizationLevelSettingItem(onValueChange = component::setConfettiHarmonizationLevel)\n            }\n\n            Setting.GeneratePreviews -> {\n                GeneratePreviewsSettingItem(onClick = component::toggleGeneratePreviews)\n            }\n\n            Setting.SkipFilePicking -> {\n                SkipImagePickingSettingItem(onClick = component::toggleSkipImagePicking)\n            }\n\n            Setting.ShowSettingsInLandscape -> {\n                ShowSettingsInLandscapeSettingItem(onClick = component::toggleShowSettingsInLandscape)\n            }\n\n            Setting.UseFullscreenSettings -> {\n                UseFullscreenSettingsSettingItem(\n                    onClick = component::toggleUseFullscreenSettings,\n                    onNavigateToSettings = onNavigateToSettings\n                )\n            }\n\n            Setting.DefaultDrawLineWidth -> {\n                DefaultDrawLineWidthSettingItem(onValueChange = component::setDefaultDrawLineWidth)\n            }\n\n            Setting.OpenEditInsteadOfPreview -> {\n                OpenEditInsteadOfPreviewSettingItem(onClick = component::toggleOpenEditInsteadOfPreview)\n            }\n\n            Setting.CanEnterPresetsByTextField -> {\n                CanEnterPresetsByTextFieldSettingItem(onClick = component::toggleCanEnterPresetsByTextField)\n            }\n\n            Setting.ColorBlindScheme -> {\n                ColorBlindSchemeSettingItem(onValueChange = component::setColorBlindScheme)\n            }\n\n            Setting.EnableLinksPreview -> {\n                EnableLinksPreviewSettingItem(onClick = component::toggleIsLinksPreviewEnabled)\n            }\n\n            Setting.DefaultDrawColor -> {\n                DefaultDrawColorSettingItem(onValueChange = component::setDefaultDrawColor)\n            }\n\n            Setting.DefaultDrawPathMode -> {\n                DefaultDrawPathModeSettingItem(onValueChange = component::setDefaultDrawPathMode)\n            }\n\n            Setting.AddTimestampToFilename -> {\n                AddTimestampToFilenameSettingItem(onClick = component::toggleAddTimestampToFilename)\n            }\n\n            Setting.UseFormattedFilenameTimestamp -> {\n                UseFormattedFilenameTimestampSettingItem(onClick = component::toggleUseFormattedFilenameTimestamp)\n            }\n\n            Setting.OneTimeSaveLocation -> {\n                OneTimeSaveLocationSettingItem()\n            }\n\n            Setting.DefaultResizeType -> {\n                DefaultResizeTypeSettingItem(onValueChange = component::setDefaultResizeType)\n            }\n\n            Setting.SystemBarsVisibility -> {\n                SystemBarsVisibilitySettingItem(onValueChange = component::setSystemBarsVisibility)\n            }\n\n            Setting.ShowSystemBarsBySwipe -> {\n                ShowSystemBarsBySwipeSettingItem(onClick = component::toggleIsSystemBarsVisibleBySwipe)\n            }\n\n            Setting.UseCompactSelectors -> {\n                UseCompactSelectorsSettingItem(onClick = component::toggleUseCompactSelectors)\n            }\n\n            Setting.MainScreenTitle -> {\n                MainScreenTitleSettingItem(onValueChange = component::setMainScreenTitle)\n            }\n\n            Setting.SliderType -> {\n                SliderTypeSettingItem(onValueChange = component::setSliderType)\n            }\n\n            Setting.CenterAlignDialogButtons -> {\n                CenterAlignDialogButtonsSettingItem(onClick = component::toggleIsCenterAlignDialogButtons)\n            }\n\n            Setting.OpenSourceLicenses -> {\n                OpenSourceLicensesSettingItem(onClick = onNavigateToLibrariesInfo)\n            }\n\n            Setting.FastSettingsSide -> {\n                FastSettingsSideSettingItem(onValueChange = component::setFastSettingsSide)\n            }\n\n            Setting.ChecksumAsFilename -> {\n                ChecksumAsFilenameSettingItem(onValueChange = component::setChecksumTypeForFilename)\n            }\n\n            Setting.EnableToolExitConfirmation -> {\n                EnableToolExitConfirmationSettingItem(onClick = component::toggleEnableToolExitConfirmation)\n            }\n\n            Setting.SendLogs -> {\n                SendLogsSettingItem(onClick = component::shareLogs)\n            }\n\n            Setting.AddPresetToFilename -> {\n                AddPresetToFilenameSettingItem(onClick = component::toggleAddPresetInfoToFilename)\n            }\n\n            Setting.AddImageScaleModeToFilename -> {\n                AddImageScaleModeToFilenameSettingItem(onClick = component::toggleAddImageScaleModeInfoToFilename)\n            }\n\n            Setting.AllowSkipIfLarger -> {\n                AllowSkipIfLargerSettingItem(onClick = component::toggleAllowSkipIfLarger)\n            }\n\n            Setting.EnableLauncherMode -> {\n                EnableLauncherModeSettingItem(onClick = component::toggleIsScreenSelectionLauncherMode)\n            }\n\n            Setting.SnowfallMode -> {\n                SnowfallModeSettingItem(onValueChange = component::setSnowfallMode)\n            }\n\n            Setting.DefaultImageFormat -> {\n                DefaultImageFormatSettingItem(onValueChange = component::setDefaultImageFormat)\n            }\n\n            Setting.DefaultQuality -> {\n                DefaultQualitySettingItem(onValueChange = component::setDefaultQuality)\n            }\n\n            Setting.ShapeType -> {\n                ShapeTypeSettingItem(onValueChange = component::setShapesType)\n            }\n\n            Setting.CornersSize -> {\n                CornersSizeSettingItem(onValueChange = component::setShapesType)\n            }\n\n            Setting.FilenamePattern -> {\n                FilenamePatternSettingItem(\n                    onValueChange = component::setFilenamePattern,\n                    filenameCreator = component\n                )\n            }\n\n            Setting.FlingType -> {\n                FlingTypeSettingItem(onValueChange = component::setFlingType)\n            }\n\n            Setting.ToolsHiddenForShare -> {\n                ToolsHiddenForShareSettingItem(onValueChange = component::setHiddenForShareScreens)\n            }\n\n            Setting.KeepDateTime -> {\n                KeepDateTimeSettingItem(onClick = component::toggleKeepDateTime)\n            }\n\n            Setting.EnableBackgroundColorForAlphaFormats -> {\n                EnableBackgroundColorForAlphaFormatsSettingItem(onClick = component::toggleEnableBackgroundColorForAlphaFormats)\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ShapeTypeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material.icons.rounded.RoundedCorner\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun ShapeTypeSettingItem(\n    onValueChange: (ShapeType) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    var showSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItem(\n        modifier = modifier,\n        title = stringResource(id = R.string.shapes_type),\n        startIcon = Icons.Rounded.RoundedCorner,\n        subtitle = stringResource(settingsState.shapesType.title()),\n        onClick = {\n            showSheet = true\n        },\n        shape = shape,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showSheet,\n        onDismiss = { showSheet = it },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.shape_type),\n                icon = Icons.Rounded.RoundedCorner\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showSheet = false\n                },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    ) {\n        Column(\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(8.dp)\n        ) {\n            val entries = ShapeType.entries\n\n            entries.forEachIndexed { index, type ->\n                val selected = type::class.isInstance(settingsState.shapesType)\n                PreferenceItemOverload(\n                    onClick = { onValueChange(type.copy(settingsState.shapesType.strength)) },\n                    title = stringResource(type.title()),\n                    subtitle = stringResource(type.subtitle()),\n                    containerColor = takeColorFromScheme {\n                        if (selected) secondaryContainer\n                        else SafeLocalContainerColor\n                    },\n                    shape = ShapeDefaults.byIndex(index, entries.size),\n                    startIcon = {\n                        Spacer(\n                            modifier = Modifier\n                                .size(24.dp)\n                                .padding(2.dp)\n                                .border(\n                                    width = 2.dp,\n                                    color = LocalContentColor.current,\n                                    shape = AutoCornersShape(\n                                        size = when (type) {\n                                            is ShapeType.Smooth -> 8.dp\n                                            is ShapeType.Squircle -> 24.dp\n                                            else -> 6.dp\n                                        },\n                                        shapesType = type\n                                    )\n                                )\n                        )\n                    },\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .border(\n                            width = settingsState.borderWidth,\n                            color = animateColorAsState(\n                                if (selected) MaterialTheme.colorScheme\n                                    .onSecondaryContainer\n                                    .copy(alpha = 0.5f)\n                                else Color.Transparent\n                            ).value,\n                            shape = ShapeDefaults.byIndex(index, entries.size)\n                        ),\n                    endIcon = {\n                        Icon(\n                            imageVector = if (selected) {\n                                Icons.Rounded.RadioButtonChecked\n                            } else Icons.Rounded.RadioButtonUnchecked,\n                            contentDescription = null\n                        )\n                    }\n                )\n            }\n        }\n    }\n}\n\nprivate fun ShapeType.title() = when (this) {\n    is ShapeType.Cut -> R.string.cut\n    is ShapeType.Rounded -> R.string.rounded\n    is ShapeType.Smooth -> R.string.smooth\n    is ShapeType.Squircle -> R.string.squircle\n}\n\nprivate fun ShapeType.subtitle() = when (this) {\n    is ShapeType.Cut -> R.string.cut_shapes_sub\n    is ShapeType.Rounded -> R.string.rounded_shapes_sub\n    is ShapeType.Smooth -> R.string.smooth_shapes_sub\n    is ShapeType.Squircle -> R.string.squircle_shapes_sub\n}\n"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ShowSettingsInLandscapeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MobileLandscape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ShowSettingsInLandscapeSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        enabled = !settingsState.useFullscreenSettings,\n        title = stringResource(R.string.show_settings_in_landscape),\n        subtitle = stringResource(R.string.show_settings_in_landscape_sub),\n        checked = settingsState.showSettingsInLandscape,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.MobileLandscape\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ShowSystemBarsBySwipeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.SwipeVertical\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun ShowSystemBarsBySwipeSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        title = stringResource(R.string.show_system_bars_by_swipe),\n        subtitle = stringResource(R.string.show_system_bars_by_swipe_sub),\n        checked = settingsState.isSystemBarsVisibleBySwipe,\n        startIcon = Icons.Outlined.SwipeVertical\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SkipImagePickingSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.SkipNext\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun SkipImagePickingSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.skip_file_picking),\n        subtitle = stringResource(R.string.skip_file_picking_sub),\n        checked = settingsState.skipImagePicking,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.SkipNext\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SliderShadowsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Slider\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun SliderShadowsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        enabled = settingsState.borderWidth <= 0.dp,\n        shape = shape,\n        title = stringResource(R.string.sliders_shadow),\n        subtitle = stringResource(R.string.sliders_shadow_sub),\n        checked = settingsState.drawSliderShadows,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Rounded.Slider\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SliderTypeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Android\nimport androidx.compose.material.icons.rounded.AutoAwesome\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.HyperOS\nimport com.t8rin.imagetoolbox.core.resources.icons.MaterialDesign\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.Slider\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun SliderTypeSettingItem(\n    onValueChange: (SliderType) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    var showSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItem(\n        modifier = modifier,\n        title = stringResource(id = R.string.slider_type),\n        startIcon = Icons.Rounded.Slider,\n        subtitle = settingsState.sliderType.title,\n        onClick = {\n            showSheet = true\n        },\n        shape = shape,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showSheet,\n        onDismiss = { showSheet = it },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.slider_type),\n                icon = Icons.Rounded.Slider\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showSheet = false\n                },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    ) {\n        Column(\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(8.dp)\n        ) {\n            val entries = remember {\n                SliderType.entries\n            }\n\n            entries.forEachIndexed { index, type ->\n                val selected = type == settingsState.sliderType\n                PreferenceItem(\n                    onClick = { onValueChange(type) },\n                    title = type.title,\n                    subtitle = type.subtitle,\n                    containerColor = takeColorFromScheme {\n                        if (selected) secondaryContainer\n                        else SafeLocalContainerColor\n                    },\n                    shape = ShapeDefaults.byIndex(index, entries.size),\n                    startIcon = type.icon,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .border(\n                            width = settingsState.borderWidth,\n                            color = animateColorAsState(\n                                if (selected) MaterialTheme.colorScheme\n                                    .onSecondaryContainer\n                                    .copy(alpha = 0.5f)\n                                else Color.Transparent\n                            ).value,\n                            shape = ShapeDefaults.byIndex(index, entries.size)\n                        ),\n                    endIcon = if (selected) {\n                        Icons.Rounded.RadioButtonChecked\n                    } else Icons.Rounded.RadioButtonUnchecked\n                )\n            }\n        }\n    }\n}\n\nprivate val SliderType.title: String\n    @Composable\n    get() = when (this) {\n        SliderType.Fancy -> stringResource(R.string.fancy)\n        SliderType.Material -> stringResource(R.string.material_2)\n        SliderType.MaterialYou -> stringResource(R.string.material_you)\n        SliderType.HyperOS -> stringResource(R.string.hyper_os)\n    }\n\nprivate val SliderType.subtitle: String\n    @Composable\n    get() = when (this) {\n        SliderType.Fancy -> stringResource(R.string.fancy_sub)\n        SliderType.Material -> stringResource(R.string.material_2_sub)\n        SliderType.MaterialYou -> stringResource(R.string.material_you_slider_sub)\n        SliderType.HyperOS -> stringResource(R.string.hyper_os_sub)\n    }\n\n\nprivate val SliderType.icon: ImageVector\n    get() = when (this) {\n        SliderType.Fancy -> Icons.Rounded.AutoAwesome\n        SliderType.Material -> Icons.Rounded.Android\n        SliderType.MaterialYou -> Icons.Outlined.MaterialDesign\n        SliderType.HyperOS -> Icons.Outlined.HyperOS\n    }"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SnowfallModeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Snowflake\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.state.derivedValueOf\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun SnowfallModeSettingItem(\n    onValueChange: (SnowfallMode) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val value = settingsState.snowfallMode\n    val entries = SnowfallMode.entries\n\n    Column(\n        modifier = modifier.container(shape = shape)\n    ) {\n        TitleItem(\n            text = stringResource(R.string.snowfall_mode),\n            icon = Icons.Outlined.Snowflake,\n            iconEndPadding = 14.dp,\n            modifier = Modifier\n                .padding(horizontal = 12.dp)\n                .padding(top = 8.dp)\n        )\n        EnhancedButtonGroup(\n            enabled = true,\n            itemCount = entries.size,\n            title = {},\n            modifier = Modifier.fillMaxWidth(),\n            isScrollable = false,\n            selectedIndex = derivedValueOf(value) {\n                entries.indexOfFirst { it::class.isInstance(value) }\n            },\n            activeButtonColor = MaterialTheme.colorScheme.surfaceContainerHighest,\n            inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainer,\n            itemContent = {\n                Text(stringResource(entries[it].getTitle()))\n            },\n            onIndexChange = {\n                onValueChange(entries[it])\n            }\n        )\n    }\n}\n\nprivate fun SnowfallMode.getTitle(): Int = when (this) {\n    SnowfallMode.Auto -> R.string.auto\n    SnowfallMode.Enabled -> R.string.enabled\n    SnowfallMode.Disabled -> R.string.disabled\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SourceCodeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.APP_GITHUB_LINK\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Github\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContentColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\n\n\n@Composable\nfun SourceCodeSettingItem(\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.bottom,\n) {\n    val linkHandler = LocalUriHandler.current\n\n    CompositionLocalProvider(\n        LocalIconShapeContentColor provides MaterialTheme.colorScheme.onTertiaryContainer,\n        LocalIconShapeContainerColor provides MaterialTheme.colorScheme.tertiaryContainer.blend(\n            color = MaterialTheme.colorScheme.tertiary,\n            fraction = 0.1f\n        )\n    ) {\n        PreferenceItem(\n            contentColor = MaterialTheme.colorScheme.onTertiaryContainer,\n            shape = shape,\n            onClick = {\n                linkHandler.openUri(APP_GITHUB_LINK)\n            },\n            startIcon = Icons.Rounded.Github,\n            title = stringResource(R.string.check_source_code),\n            subtitle = stringResource(R.string.check_source_code_sub),\n            containerColor = MaterialTheme.colorScheme.tertiaryContainer.copy(0.7f),\n            modifier = modifier,\n            overrideIconShapeContentColor = true\n        )\n    }\n}\n\n"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SwitchShadowsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ToggleOff\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun SwitchShadowsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        modifier = modifier,\n        enabled = settingsState.borderWidth <= 0.dp,\n        shape = shape,\n        title = stringResource(R.string.switches_shadow),\n        subtitle = stringResource(R.string.switches_shadow_sub),\n        checked = settingsState.drawSwitchShadows,\n        onClick = {\n            onClick()\n        },\n        startIcon = Icons.Outlined.ToggleOff\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SwitchTypeSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.ToggleOff\nimport androidx.compose.material.icons.outlined.ToggleOn\nimport androidx.compose.material.icons.rounded.Android\nimport androidx.compose.material.icons.rounded.RadioButtonChecked\nimport androidx.compose.material.icons.rounded.RadioButtonUnchecked\nimport androidx.compose.material.icons.rounded.Water\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Cube\nimport com.t8rin.imagetoolbox.core.resources.icons.HyperOS\nimport com.t8rin.imagetoolbox.core.resources.icons.IOS\nimport com.t8rin.imagetoolbox.core.resources.icons.MaterialDesign\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.SamsungLetter\nimport com.t8rin.imagetoolbox.core.resources.icons.Windows\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun SwitchTypeSettingItem(\n    onValueChange: (SwitchType) -> Unit,\n    shape: Shape = ShapeDefaults.top,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    var showSheet by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    PreferenceItem(\n        modifier = modifier,\n        title = stringResource(id = R.string.switch_type),\n        startIcon = Icons.Outlined.ToggleOn,\n        subtitle = settingsState.switchType.title,\n        onClick = {\n            showSheet = true\n        },\n        shape = shape,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showSheet,\n        onDismiss = { showSheet = it },\n        title = {\n            TitleItem(\n                text = stringResource(id = R.string.switch_type),\n                icon = Icons.Outlined.ToggleOff\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    showSheet = false\n                },\n                containerColor = MaterialTheme.colorScheme.secondaryContainer\n            ) {\n                Text(stringResource(R.string.close))\n            }\n        }\n    ) {\n        Column(\n            verticalArrangement = Arrangement.spacedBy(4.dp),\n            modifier = Modifier\n                .enhancedVerticalScroll(rememberScrollState())\n                .padding(8.dp)\n        ) {\n            val entries = remember {\n                SwitchType.entries\n            }\n\n            entries.forEachIndexed { index, type ->\n                val selected = type == settingsState.switchType\n                PreferenceItem(\n                    onClick = { onValueChange(type) },\n                    title = type.title,\n                    subtitle = type.subtitle,\n                    containerColor = takeColorFromScheme {\n                        if (selected) secondaryContainer\n                        else SafeLocalContainerColor\n                    },\n                    shape = ShapeDefaults.byIndex(index, entries.size),\n                    startIcon = type.icon,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .border(\n                            width = settingsState.borderWidth,\n                            color = animateColorAsState(\n                                if (selected) MaterialTheme.colorScheme\n                                    .onSecondaryContainer\n                                    .copy(alpha = 0.5f)\n                                else Color.Transparent\n                            ).value,\n                            shape = ShapeDefaults.byIndex(index, entries.size)\n                        ),\n                    endIcon = if (selected) {\n                        Icons.Rounded.RadioButtonChecked\n                    } else Icons.Rounded.RadioButtonUnchecked\n                )\n            }\n        }\n    }\n}\n\nprivate val SwitchType.title: String\n    @Composable\n    get() = when (this) {\n        SwitchType.MaterialYou -> stringResource(R.string.material_you)\n        SwitchType.Compose -> stringResource(R.string.compose)\n        SwitchType.Pixel -> stringResource(R.string.pixel_switch)\n        SwitchType.Fluent -> stringResource(R.string.fluent_switch)\n        SwitchType.Cupertino -> stringResource(R.string.cupertino_switch)\n        SwitchType.LiquidGlass -> stringResource(R.string.liquid_glass)\n        SwitchType.HyperOS -> stringResource(R.string.hyper_os)\n        SwitchType.OneUI -> stringResource(R.string.one_ui)\n    }\n\nprivate val SwitchType.subtitle: String\n    @Composable\n    get() = when (this) {\n        SwitchType.MaterialYou -> stringResource(R.string.material_you_switch_sub)\n        SwitchType.Compose -> stringResource(R.string.compose_switch_sub)\n        SwitchType.Pixel -> stringResource(R.string.use_pixel_switch_sub)\n        SwitchType.Fluent -> stringResource(R.string.fluent_switch_sub)\n        SwitchType.Cupertino -> stringResource(R.string.cupertino_switch_sub)\n        SwitchType.LiquidGlass -> stringResource(R.string.liquid_glass_sub)\n        SwitchType.HyperOS -> stringResource(R.string.hyper_os_sub)\n        SwitchType.OneUI -> stringResource(R.string.one_ui_sub)\n    }\n\n\nprivate val SwitchType.icon: ImageVector\n    get() = when (this) {\n        SwitchType.MaterialYou -> Icons.Outlined.MaterialDesign\n        SwitchType.Compose -> Icons.Outlined.Cube\n        SwitchType.Pixel -> Icons.Rounded.Android\n        SwitchType.Fluent -> Icons.Rounded.Windows\n        SwitchType.Cupertino -> Icons.Rounded.IOS\n        SwitchType.LiquidGlass -> Icons.Rounded.Water\n        SwitchType.HyperOS -> Icons.Outlined.HyperOS\n        SwitchType.OneUI -> Icons.Outlined.SamsungLetter\n    }"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/SystemBarsVisibilitySettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.TelevisionAmbientLight\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun SystemBarsVisibilitySettingItem(\n    onValueChange: (SystemBarsVisibility) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val items = remember {\n        SystemBarsVisibility.entries\n    }\n\n    Column(\n        modifier = modifier.container(\n            shape = shape\n        )\n    ) {\n        TitleItem(\n            modifier = Modifier.padding(\n                top = 12.dp,\n                end = 12.dp,\n                bottom = 16.dp,\n                start = 12.dp\n            ),\n            iconEndPadding = 14.dp,\n            text = stringResource(R.string.system_bars_visibility),\n            icon = Icons.Outlined.TelevisionAmbientLight\n        )\n\n        FlowRow(\n            verticalArrangement = Arrangement.spacedBy(\n                space = 8.dp,\n                alignment = Alignment.CenterVertically\n            ),\n            horizontalArrangement = Arrangement.spacedBy(\n                space = 8.dp,\n                alignment = Alignment.CenterHorizontally\n            ),\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(start = 8.dp, bottom = 8.dp, end = 8.dp)\n        ) {\n            val value = settingsState.systemBarsVisibility\n            items.forEach { item ->\n                EnhancedChip(\n                    onClick = {\n                        onValueChange(item)\n                    },\n                    selected = item::class.isInstance(value),\n                    label = {\n                        Text(text = item.title)\n                    },\n                    contentPadding = PaddingValues(horizontal = 16.dp, vertical = 6.dp),\n                    selectedColor = MaterialTheme.colorScheme.tertiary,\n                    unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant\n                )\n            }\n        }\n    }\n}\n\nprivate val SystemBarsVisibility.title: String\n    @Composable\n    get() = stringResource(\n        when (this) {\n            SystemBarsVisibility.Auto -> R.string.auto\n            SystemBarsVisibility.HideAll -> R.string.hide_all\n            SystemBarsVisibility.HideNavigationBar -> R.string.hide_nav_bar\n            SystemBarsVisibility.HideStatusBar -> R.string.hide_status_bar\n            SystemBarsVisibility.ShowAll -> R.string.show_all\n        }\n    )"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/TelegramChannelSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.RssFeed\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.TELEGRAM_CHANNEL_LINK\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\n\n@Composable\nfun TelegramChannelSettingItem(\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val linkHandler = LocalUriHandler.current\n    PreferenceRow(\n        shape = shape,\n        onClick = {\n            linkHandler.openUri(TELEGRAM_CHANNEL_LINK)\n        },\n        startIcon = Icons.Outlined.RssFeed,\n        title = stringResource(R.string.ci_channel),\n        subtitle = stringResource(R.string.ci_channel_sub),\n        color = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.7f),\n        contentColor = MaterialTheme.colorScheme.onPrimaryContainer,\n        modifier = modifier\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/TelegramGroupSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.TELEGRAM_GROUP_LINK\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Telegram\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\n\n@Composable\nfun TelegramGroupSettingItem(\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val linkHandler = LocalUriHandler.current\n    PreferenceRow(\n        shape = shape,\n        onClick = {\n            linkHandler.openUri(TELEGRAM_GROUP_LINK)\n        },\n        startIcon = Icons.Rounded.Telegram,\n        title = stringResource(R.string.tg_chat),\n        subtitle = stringResource(R.string.tg_chat_sub),\n        color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.5f),\n        contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n        modifier = modifier\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/ToolsHiddenForShareSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastAny\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.MiniEdit\nimport com.t8rin.imagetoolbox.core.resources.icons.ShareOff\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedCheckbox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\nfun ToolsHiddenForShareSettingItem(\n    onValueChange: (Screen) -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n    val settingsScreenList = settingsState.hiddenForShareScreens\n    val screenList by remember(settingsScreenList) {\n        derivedStateOf {\n            settingsScreenList.mapNotNull {\n                Screen.entries.find { s -> s.id == it }\n            }\n        }\n    }\n\n    var showPickerSheet by rememberSaveable { mutableStateOf(false) }\n\n    val context = LocalResourceManager.current\n\n    val subtitle by remember(screenList, context) {\n        derivedStateOf {\n            screenList.joinToString(separator = \", \") {\n                context.getString(it.title)\n            }.ifEmpty {\n                context.getString(R.string.disabled)\n            }\n        }\n    }\n\n    PreferenceItem(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            showPickerSheet = true\n        },\n        startIcon = Icons.Outlined.ShareOff,\n        title = stringResource(R.string.hidden_for_share),\n        subtitle = subtitle,\n        endIcon = Icons.Rounded.MiniEdit\n    )\n\n    EnhancedModalBottomSheet(\n        visible = showPickerSheet,\n        onDismiss = {\n            showPickerSheet = it\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.brightness),\n                icon = Icons.Rounded.ShareOff\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = { showPickerSheet = false }\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        sheetContent = {\n            Box {\n                LazyColumn(\n                    contentPadding = PaddingValues(8.dp),\n                    verticalArrangement = Arrangement.spacedBy(8.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    items(\n                        items = Screen.entries,\n                        key = { it.id }\n                    ) { screen ->\n                        val checked by remember(screen, screenList) {\n                            derivedStateOf {\n                                screenList.fastAny { it::class.isInstance(screen) }\n                            }\n                        }\n                        PreferenceItemOverload(\n                            modifier = Modifier.fillMaxWidth(),\n                            title = stringResource(screen.title),\n                            subtitle = stringResource(screen.subtitle),\n                            startIcon = {\n                                screen.icon?.let {\n                                    Icon(\n                                        imageVector = it,\n                                        contentDescription = null\n                                    )\n                                }\n                            },\n                            endIcon = {\n                                EnhancedCheckbox(\n                                    checked = checked,\n                                    onCheckedChange = {\n                                        onValueChange(screen)\n                                    }\n                                )\n                            },\n                            onClick = {\n                                onValueChange(screen)\n                            }\n                        )\n                    }\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/UseCompactSelectorsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FullscreenExit\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\n\n@Composable\nfun UseCompactSelectorsSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp),\n) {\n    val settingsState = LocalSettingsState.current\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        title = stringResource(R.string.compact_selectors),\n        subtitle = stringResource(R.string.compact_selectors_sub),\n        checked = settingsState.isCompactSelectorsLayout,\n        startIcon = Icons.Rounded.FullscreenExit\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/UseFormattedFilenameTimestampSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.FormatTextdirectionLToR\nimport androidx.compose.material.icons.outlined.Timer\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun UseFormattedFilenameTimestampSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        shape = shape,\n        modifier = modifier,\n        onClick = {\n            onClick()\n        },\n        enabled = settingsState.filenameBehavior is FilenameBehavior.None && settingsState.addTimestampToFilename,\n        onDisabledClick = {\n            AppToastHost.showToast(\n                message = getString(R.string.enable_timestamps_to_format_them),\n                icon = Icons.Outlined.Timer\n            )\n        },\n        title = stringResource(R.string.formatted_timestamp),\n        subtitle = stringResource(R.string.formatted_timestamp_sub),\n        checked = settingsState.useFormattedFilenameTimestamp,\n        startIcon = Icons.AutoMirrored.Outlined.FormatTextdirectionLToR\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/UseFullscreenSettingsSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Fullscreen\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun UseFullscreenSettingsSettingItem(\n    onClick: () -> Unit,\n    onNavigateToSettings: () -> Unit,\n    shape: Shape = ShapeDefaults.center,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.fullscreen_settings),\n        subtitle = stringResource(R.string.fullscreen_settings_sub),\n        checked = settingsState.useFullscreenSettings,\n        onClick = {\n            if (it) {\n                onNavigateToSettings()\n                GlobalScope.launch {\n                    delay(1000)\n                    onClick()\n                }\n            } else onClick()\n        },\n        startIcon = Icons.Outlined.Fullscreen\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/UseRandomEmojisSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Casino\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun UseRandomEmojisSettingItem(\n    onClick: () -> Unit,\n    shape: Shape = ShapeDefaults.bottom,\n    modifier: Modifier = Modifier.padding(horizontal = 8.dp)\n) {\n    val settingsState = LocalSettingsState.current\n\n    PreferenceRowSwitch(\n        modifier = modifier,\n        shape = shape,\n        title = stringResource(R.string.random_emojis),\n        subtitle = stringResource(R.string.random_emojis_sub),\n        checked = settingsState.useRandomEmojis,\n        enabled = settingsState.selectedEmoji != null,\n        onClick = {\n            onClick()\n        },\n        onDisabledClick = {\n            AppToastHost.showToast(\n                message = getString(R.string.random_emojis_error),\n                icon = Icons.Outlined.Casino\n            )\n        },\n        startIcon = Icons.Outlined.Casino\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/VibrationStrengthSettingItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Exercise\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalResourceManager\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport kotlinx.collections.immutable.persistentMapOf\nimport kotlin.math.roundToInt\n\n@Composable\nfun VibrationStrengthSettingItem(\n    onValueChange: (Int) -> Unit,\n    modifier: Modifier = Modifier\n        .padding(horizontal = 8.dp),\n    shape: Shape = ShapeDefaults.default\n) {\n    val settingsState = LocalSettingsState.current\n    val resources = LocalResourceManager.current\n\n    EnhancedSliderItem(\n        modifier = modifier,\n        shape = shape,\n        value = settingsState.hapticsStrength,\n        title = stringResource(R.string.vibration_strength),\n        icon = Icons.Outlined.Exercise,\n        onValueChange = {\n            onValueChange(it.roundToInt())\n        },\n        internalStateTransformation = {\n            it.roundToInt()\n        },\n        valueRange = 0f..2f,\n        valuesPreviewMapping = remember {\n            persistentMapOf(0f to resources.getString(R.string.disabled))\n        },\n        steps = 1,\n        valueTextTapEnabled = false\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/additional/AuthorLinksSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components.additional\n\nimport android.content.Intent\nimport androidx.activity.compose.LocalActivity\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AlternateEmail\nimport androidx.compose.material.icons.rounded.Link\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.domain.AUTHOR_GITHUB\nimport com.t8rin.imagetoolbox.core.domain.AUTHOR_TELEGRAM\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Forum\nimport com.t8rin.imagetoolbox.core.resources.icons.Github\nimport com.t8rin.imagetoolbox.core.resources.icons.Telegram\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.shareText\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContentColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults.bottom\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults.center\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults.top\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.core.utils.getString\n\n@Composable\nfun AuthorLinksSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.app_developer_nick),\n                icon = Icons.Rounded.Forum\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss,\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        sheetContent = {\n            val activity = LocalActivity.current\n            val linkHandler = LocalUriHandler.current\n            val settingsState = LocalSettingsState.current\n\n\n            Box {\n                Column(Modifier.enhancedVerticalScroll(rememberScrollState())) {\n                    Spacer(Modifier.height(16.dp))\n                    CompositionLocalProvider(\n                        LocalIconShapeContentColor provides MaterialTheme.colorScheme.onTertiaryContainer,\n                        LocalIconShapeContainerColor provides MaterialTheme.colorScheme.tertiaryContainer.blend(\n                            color = MaterialTheme.colorScheme.tertiary,\n                            fraction = if (settingsState.isNightMode) 0.2f else 0.1f\n                        )\n                    ) {\n                        PreferenceItem(\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                            onClick = {\n                                linkHandler.openUri(AUTHOR_TELEGRAM)\n                            },\n                            endIcon = Icons.Rounded.Link,\n                            shape = top,\n                            title = stringResource(R.string.telegram),\n                            startIcon = Icons.Rounded.Telegram,\n                            subtitle = stringResource(R.string.app_developer_nick),\n                            overrideIconShapeContentColor = true\n                        )\n                    }\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                        onClick = {\n                            val mail = getString(R.string.developer_email)\n\n                            runCatching {\n                                activity!!.startActivity(\n                                    Intent(Intent.ACTION_SENDTO).apply {\n                                        data = \"mailto:$mail\".toUri()\n                                    }\n                                )\n                            }.onFailure {\n                                appContext.shareText(mail)\n                            }\n                        },\n                        shape = center,\n                        endIcon = Icons.Rounded.Link,\n                        title = stringResource(R.string.email),\n                        startIcon = Icons.Rounded.AlternateEmail,\n                        subtitle = stringResource(R.string.developer_email)\n                    )\n                    Spacer(Modifier.height(4.dp))\n                    PreferenceItem(\n                        containerColor = MaterialTheme.colorScheme.primaryContainer,\n                        onClick = {\n                            linkHandler.openUri(AUTHOR_GITHUB)\n                        },\n                        endIcon = Icons.Rounded.Link,\n                        shape = bottom,\n                        title = stringResource(R.string.github),\n                        startIcon = Icons.Rounded.Github,\n                        subtitle = stringResource(R.string.app_developer_nick)\n                    )\n                    Spacer(Modifier.height(16.dp))\n                }\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/additional/DonateContainerContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components.additional\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material.icons.rounded.Link\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.BOOSTY_LINK\nimport com.t8rin.imagetoolbox.core.domain.BTC_WALLET\nimport com.t8rin.imagetoolbox.core.domain.TON_SPACE_WALLET\nimport com.t8rin.imagetoolbox.core.domain.TON_WALLET\nimport com.t8rin.imagetoolbox.core.domain.USDT_WALLET\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Bitcoin\nimport com.t8rin.imagetoolbox.core.resources.icons.Boosty\nimport com.t8rin.imagetoolbox.core.resources.icons.Ton\nimport com.t8rin.imagetoolbox.core.resources.icons.USDT\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.BitcoinColor\nimport com.t8rin.imagetoolbox.core.ui.theme.BoostyColor\nimport com.t8rin.imagetoolbox.core.ui.theme.TONColor\nimport com.t8rin.imagetoolbox.core.ui.theme.TONSpaceColor\nimport com.t8rin.imagetoolbox.core.ui.theme.USDTColor\nimport com.t8rin.imagetoolbox.core.ui.theme.blend\nimport com.t8rin.imagetoolbox.core.ui.theme.inverse\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.icon_shape.LocalIconShapeContainerColor\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\n\n@Composable\nfun DonateContainerContent(\n    modifier: Modifier = Modifier\n) {\n    Column(\n        modifier = modifier,\n        verticalArrangement = Arrangement.spacedBy(4.dp)\n    ) {\n        InfoContainer(\n            text = stringResource(R.string.donation_sub),\n            modifier = Modifier\n                .padding(\n                    start = 16.dp,\n                    top = 16.dp,\n                    end = 16.dp,\n                    bottom = 12.dp\n                ),\n            containerColor = MaterialTheme.colorScheme.surfaceVariant,\n            contentColor = MaterialTheme.colorScheme.onSurfaceVariant,\n        )\n        val options = DonationOption.entries\n\n        options.forEachIndexed { index, option ->\n            CompositionLocalProvider(\n                LocalIconShapeContainerColor provides option.containerColor().blend(\n                    color = Color.White,\n                    fraction = 0.1f\n                )\n            ) {\n                PreferenceItem(\n                    containerColor = option.containerColor(),\n                    overrideIconShapeContentColor = true,\n                    contentColor = option.contentColor(),\n                    shape = ShapeDefaults.byIndex(\n                        index = index,\n                        size = options.size\n                    ),\n                    onClick = option.onClick,\n                    endIcon = option.endIcon,\n                    startIcon = option.startIcon,\n                    title = option.title(),\n                    subtitle = option.subtitle,\n                    titleFontStyle = PreferenceItemDefaults.TitleFontStyle.copy(\n                        textAlign = TextAlign.Start\n                    )\n                )\n            }\n        }\n        Spacer(Modifier.height(12.dp))\n    }\n}\n\nprivate data class DonationOption(\n    val containerColor: @Composable () -> Color,\n    val contentColor: @Composable () -> Color,\n    val onClick: () -> Unit,\n    val endIcon: ImageVector,\n    val startIcon: ImageVector,\n    val title: @Composable () -> String,\n    val subtitle: String\n) {\n    companion object Companion {\n        val entries: List<DonationOption>\n            @Composable\n            get() {\n                val linkHandler = LocalUriHandler.current\n                val darkMode = !LocalSettingsState.current.isNightMode\n\n                return remember(linkHandler, darkMode) {\n                    listOf(\n                        DonationOption(\n                            containerColor = { BoostyColor },\n                            contentColor = {\n                                BoostyColor.inverse(\n                                    fraction = { 1f },\n                                    darkMode = true\n                                )\n                            },\n                            onClick = { linkHandler.openUri(BOOSTY_LINK) },\n                            endIcon = Icons.Rounded.Link,\n                            startIcon = Icons.Rounded.Boosty,\n                            title = { stringResource(R.string.boosty) },\n                            subtitle = BOOSTY_LINK\n                        ),\n                        DonationOption(\n                            containerColor = { BitcoinColor },\n                            contentColor = {\n                                BitcoinColor.inverse(\n                                    fraction = { 1f },\n                                    darkMode = darkMode\n                                )\n                            },\n                            onClick = {\n                                Clipboard.copy(BTC_WALLET)\n                            },\n                            endIcon = Icons.Rounded.ContentCopy,\n                            title = { stringResource(R.string.bitcoin) },\n                            startIcon = Icons.Filled.Bitcoin,\n                            subtitle = BTC_WALLET\n                        ),\n                        DonationOption(\n                            containerColor = { USDTColor },\n                            contentColor = {\n                                USDTColor.inverse(\n                                    fraction = { 1f },\n                                    darkMode = darkMode\n                                )\n                            },\n                            onClick = {\n                                Clipboard.copy(BTC_WALLET)\n                            },\n                            endIcon = Icons.Rounded.ContentCopy,\n                            title = { stringResource(R.string.usdt) },\n                            startIcon = Icons.Filled.USDT,\n                            subtitle = USDT_WALLET\n                        ),\n                        DonationOption(\n                            containerColor = { TONColor },\n                            contentColor = {\n                                TONColor.inverse(\n                                    fraction = { 1f },\n                                    darkMode = darkMode\n                                )\n                            },\n                            onClick = {\n                                Clipboard.copy(TON_WALLET)\n                            },\n                            endIcon = Icons.Rounded.ContentCopy,\n                            startIcon = Icons.Rounded.Ton,\n                            title = { stringResource(R.string.ton) },\n                            subtitle = TON_WALLET\n                        ),\n                        DonationOption(\n                            containerColor = { TONSpaceColor },\n                            contentColor = {\n                                TONSpaceColor.inverse(\n                                    fraction = { 1f },\n                                    darkMode = true\n                                )\n                            },\n                            onClick = {\n                                Clipboard.copy(TON_SPACE_WALLET)\n                            },\n                            endIcon = Icons.Rounded.ContentCopy,\n                            startIcon = Icons.Rounded.Ton,\n                            title = { stringResource(R.string.ton_space) },\n                            subtitle = TON_SPACE_WALLET\n                        )\n                    )\n                }\n            }\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/additional/DonateDialog.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components.additional\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.VolunteerActivism\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.isFirstLaunch\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport kotlinx.coroutines.delay\n\n@Composable\nfun DonateDialog(\n    onNotShowDonateDialogAgain: () -> Unit,\n    onRegisterDonateDialogOpen: () -> Unit\n) {\n    val settings = LocalSettingsState.current\n    var isClosed by rememberSaveable {\n        mutableStateOf(false)\n    }\n    val showDialog = settings.appOpenCount % 12 == 0\n            && !settings.isFirstLaunch(false) && !isClosed\n            && settings.donateDialogOpenCount != null\n\n\n    var isOpenRegistered by rememberSaveable(showDialog) {\n        mutableStateOf(false)\n    }\n    if (showDialog) {\n        LaunchedEffect(isOpenRegistered) {\n            if (!isOpenRegistered) {\n                delay(1000)\n                onRegisterDonateDialogOpen()\n                isOpenRegistered = true\n            }\n        }\n    }\n\n    val isNotShowAgainButtonVisible = (settings.donateDialogOpenCount ?: 0) > 2\n\n    EnhancedAlertDialog(\n        visible = showDialog,\n        onDismissRequest = { },\n        icon = {\n            Icon(\n                imageVector = Icons.Rounded.VolunteerActivism,\n                contentDescription = null\n            )\n        },\n        title = { Text(stringResource(R.string.donation)) },\n        text = {\n            val scrollState = rememberScrollState()\n            Column(\n                modifier = Modifier\n                    .fadingEdges(\n                        isVertical = true,\n                        scrollableState = scrollState\n                    )\n                    .enhancedVerticalScroll(scrollState)\n            ) {\n                DonateContainerContent()\n            }\n        },\n        dismissButton = {\n            if (isNotShowAgainButtonVisible) {\n                EnhancedButton(\n                    onClick = {\n                        onNotShowDonateDialogAgain()\n                        isClosed = true\n                    },\n                    containerColor = MaterialTheme.colorScheme.errorContainer\n                ) {\n                    Text(stringResource(id = R.string.dismiss_forever))\n                }\n            }\n        },\n        confirmButton = {\n            EnhancedButton(\n                onClick = {\n                    isClosed = true\n                },\n                containerColor = takeColorFromScheme {\n                    if (isNotShowAgainButtonVisible) tertiaryContainer\n                    else secondaryContainer\n                }\n            ) {\n                Text(stringResource(id = R.string.close))\n            }\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/additional/DonateSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components.additional\n\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.VolunteerActivism\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n\n@Composable\nfun DonateSheet(\n    visible: Boolean,\n    onDismiss: () -> Unit\n) {\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        title = {\n            TitleItem(\n                text = stringResource(R.string.donation),\n                icon = Icons.Rounded.VolunteerActivism\n            )\n        },\n        confirmButton = {\n            EnhancedButton(\n                containerColor = MaterialTheme.colorScheme.secondaryContainer,\n                onClick = onDismiss,\n            ) {\n                AutoSizeText(stringResource(R.string.close))\n            }\n        },\n        sheetContent = {\n            DonateContainerContent(\n                modifier = Modifier.enhancedVerticalScroll(rememberScrollState())\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/additional/FabPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components.additional\n\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.twotone.Image\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme.colorScheme\nimport androidx.compose.material3.MaterialTheme.shapes\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvidesValue\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.autoElevatedBorder\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.containerFabBorder\n\n@Composable\nfun FabPreview(\n    modifier: Modifier = Modifier,\n    alignment: Alignment,\n) {\n    val shadowEnabled = LocalSettingsState.current.drawContainerShadows\n    val elevation by animateDpAsState(if (shadowEnabled) 2.dp else 0.dp)\n    Column(\n        modifier = modifier\n            .padding(4.dp)\n            .autoElevatedBorder(\n                shape = ShapeDefaults.small,\n                autoElevation = elevation\n            )\n            .clip(ShapeDefaults.small)\n            .background(colorScheme.surfaceContainerLowest),\n        verticalArrangement = Arrangement.SpaceBetween\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(horizontal = 8.dp, vertical = 8.dp)\n                .autoElevatedBorder(shape = shapes.small, autoElevation = elevation)\n                .clip(shapes.small)\n                .background(colorScheme.surfaceContainer)\n                .fillMaxWidth(1f),\n            verticalArrangement = Arrangement.Center,\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Spacer(Modifier.height(4.dp))\n            EnhancedIconButton(\n                onClick = {},\n                modifier = Modifier\n                    .size(25.dp)\n                    .aspectRatio(1f),\n                shape = CloverShape,\n                containerColor = colorScheme.surfaceColorAtElevation(6.dp),\n                contentColor = colorScheme.onSurfaceVariant\n            ) {\n                Icon(\n                    imageVector = Icons.TwoTone.Image,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .padding(3.dp),\n                    tint = colorScheme.onSurfaceVariant\n                )\n            }\n            Text(\n                text = stringResource(R.string.pick_image),\n                modifier = Modifier.padding(4.dp),\n                fontSize = 3.sp,\n                lineHeight = 4.sp,\n                textAlign = TextAlign.Center,\n                color = colorScheme.onSurfaceVariant\n            )\n        }\n        val weight by animateFloatAsState(\n            targetValue = when (alignment) {\n                Alignment.BottomStart -> 0f\n                Alignment.BottomCenter -> 0.5f\n                else -> 1f\n            }\n        )\n\n        val settingsState = LocalSettingsState.current\n        LocalContentColor.ProvidesValue(colorScheme.onPrimaryContainer) {\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n            ) {\n                Spacer(modifier = Modifier.weight(0.01f + weight))\n                Box(\n                    modifier = Modifier\n                        .padding(8.dp)\n                        .size(22.dp)\n                        .aspectRatio(1f)\n                        .containerFabBorder(\n                            shape = ShapeDefaults.mini,\n                            autoElevation = animateDpAsState(\n                                if (settingsState.drawFabShadows) 3.dp\n                                else 0.dp\n                            ).value\n                        )\n                        .background(\n                            color = colorScheme.primaryContainer,\n                            shape = ShapeDefaults.mini,\n                        )\n                        .clip(ShapeDefaults.mini)\n                        .hapticsClickable { },\n                    contentAlignment = Alignment.Center\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.AddPhotoAlt,\n                        contentDescription = null,\n                        modifier = Modifier.size(10.dp)\n                    )\n                }\n                Spacer(modifier = Modifier.weight(1.01f - weight))\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/additional/FontItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components.additional\n\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyItemScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Delete\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.FontSelectionItem\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealDirection\nimport com.t8rin.imagetoolbox.core.ui.widget.other.RevealValue\nimport com.t8rin.imagetoolbox.core.ui.widget.other.SwipeToReveal\nimport com.t8rin.imagetoolbox.core.ui.widget.other.rememberRevealState\nimport kotlinx.coroutines.launch\n\n@Composable\ninternal fun LazyItemScope.FontItem(\n    font: UiFontFamily,\n    onFontSelected: (UiFontFamily) -> Unit,\n    onRemoveFont: (UiFontFamily.Custom) -> Unit\n) {\n    if (font is UiFontFamily.Custom) {\n        val scope = rememberCoroutineScope()\n        val state = rememberRevealState()\n        val interactionSource = remember {\n            MutableInteractionSource()\n        }\n        val isDragged by interactionSource.collectIsDraggedAsState()\n        val shape = animateShape(\n            if (isDragged) ShapeDefaults.extraSmall\n            else ShapeDefaults.default\n        )\n        SwipeToReveal(\n            state = state,\n            modifier = Modifier.animateItem(),\n            revealedContentEnd = {\n                Box(\n                    Modifier\n                        .fillMaxSize()\n                        .container(\n                            color = MaterialTheme.colorScheme.errorContainer,\n                            shape = shape,\n                            autoShadowElevation = 0.dp,\n                            resultPadding = 0.dp\n                        )\n                        .hapticsClickable {\n                            scope.launch {\n                                state.animateTo(RevealValue.Default)\n                            }\n                            onRemoveFont(font)\n                        }\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.Delete,\n                        contentDescription = stringResource(R.string.delete),\n                        modifier = Modifier\n                            .padding(16.dp)\n                            .padding(end = 8.dp)\n                            .align(Alignment.CenterEnd),\n                        tint = MaterialTheme.colorScheme.onErrorContainer\n                    )\n                }\n            },\n            directions = setOf(RevealDirection.EndToStart),\n            swipeableContent = {\n                FontSelectionItem(\n                    font = font,\n                    onClick = {\n                        onFontSelected(font)\n                    },\n                    onLongClick = {\n                        scope.launch {\n                            state.animateTo(RevealValue.FullyRevealedStart)\n                        }\n                    },\n                    modifier = Modifier.fillMaxWidth(),\n                    shape = shape\n                )\n            },\n            interactionSource = interactionSource\n        )\n    } else {\n        FontSelectionItem(\n            font = font,\n            onClick = {\n                onFontSelected(font)\n            }\n        )\n    }\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/components/additional/PickFontFamilySheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.components.additional\n\nimport android.net.Uri\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Extension\nimport androidx.compose.material.icons.rounded.FontDownload\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FileExport\nimport com.t8rin.imagetoolbox.core.resources.icons.FileImport\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.negativePadding\nimport com.t8rin.imagetoolbox.core.ui.widget.other.GradientEdge\nimport com.t8rin.imagetoolbox.core.ui.widget.other.InfoContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRow\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\n\n@Composable\ninternal fun PickFontFamilySheet(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    onFontSelected: (UiFontFamily) -> Unit,\n    onAddFont: (Uri) -> Unit,\n    onRemoveFont: (UiFontFamily.Custom) -> Unit,\n    onExportFonts: () -> Unit\n) {\n    EnhancedModalBottomSheet(\n        visible = visible,\n        onDismiss = {\n            if (!it) onDismiss()\n        },\n        sheetContent = {\n            val defaultEntries = UiFontFamily.defaultEntries\n            val customEntries = UiFontFamily.customEntries\n\n            LazyColumn(\n                contentPadding = PaddingValues(16.dp),\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                flingBehavior = enhancedFlingBehavior()\n            ) {\n                stickyHeader {\n                    Column(\n                        modifier = Modifier\n                            .negativePadding(horizontal = 16.dp)\n                            .background(EnhancedBottomSheetDefaults.containerColor)\n                            .padding(horizontal = 16.dp)\n                    ) {\n                        Spacer(modifier = Modifier.height(20.dp))\n                        Row(\n                            horizontalArrangement = Arrangement.spacedBy(4.dp),\n                            modifier = Modifier.height(IntrinsicSize.Max)\n                        ) {\n                            val pickFileLauncher = rememberFilePicker(\n                                mimeType = MimeType.Font,\n                                onSuccess = onAddFont\n                            )\n                            PreferenceRow(\n                                title = stringResource(R.string.import_font),\n                                onClick = pickFileLauncher::pickFile,\n                                shape = ShapeDefaults.start,\n                                titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered,\n                                startIcon = Icons.Rounded.FileImport,\n                                modifier = Modifier\n                                    .weight(1f)\n                                    .fillMaxHeight(),\n                                color = MaterialTheme.colorScheme.primaryContainer\n                            )\n\n                            val canExport = customEntries.isNotEmpty()\n\n                            PreferenceRow(\n                                title = stringResource(R.string.export_fonts),\n                                onClick = onExportFonts,\n                                shape = ShapeDefaults.end,\n                                enabled = canExport,\n                                startIcon = Icons.Rounded.FileExport,\n                                modifier = Modifier\n                                    .weight(1f)\n                                    .fillMaxHeight(),\n                                color = takeColorFromScheme {\n                                    if (canExport) primaryContainer\n                                    else surfaceVariant\n                                },\n                                titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered\n                            )\n                        }\n                        Spacer(modifier = Modifier.height(8.dp))\n                    }\n                    GradientEdge(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .height(16.dp),\n                        startColor = EnhancedBottomSheetDefaults.containerColor,\n                        endColor = Color.Transparent\n                    )\n                }\n\n                items(\n                    items = defaultEntries,\n                    key = { it.name ?: \"sys\" }\n                ) { font ->\n                    FontItem(\n                        font = font,\n                        onFontSelected = onFontSelected,\n                        onRemoveFont = onRemoveFont\n                    )\n                }\n                if (customEntries.isNotEmpty()) {\n                    item {\n                        InfoContainer(\n                            text = stringResource(R.string.imported_fonts),\n                            icon = Icons.Outlined.Extension,\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .padding(8.dp),\n                            contentColor = MaterialTheme.colorScheme.onTertiaryContainer.copy(alpha = 0.6f),\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer.copy(0.4f)\n                        )\n                    }\n                    items(\n                        items = customEntries,\n                        key = { it.name ?: \"sys\" }\n                    ) { font ->\n                        FontItem(\n                            font = font,\n                            onFontSelected = onFontSelected,\n                            onRemoveFont = onRemoveFont\n                        )\n                    }\n                }\n            }\n        },\n        confirmButton = {\n            Row(\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                EnhancedButton(\n                    onClick = onDismiss,\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer\n                ) {\n                    AutoSizeText(stringResource(R.string.close))\n                }\n            }\n        },\n        title = {\n            TitleItem(\n                icon = Icons.Rounded.FontDownload,\n                text = stringResource(R.string.font),\n            )\n        }\n    )\n}"
  },
  {
    "path": "feature/settings/src/main/java/com/t8rin/imagetoolbox/feature/settings/presentation/screenLogic/SettingsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.value.Value\nimport com.t8rin.dynamic.theme.ColorTuple\nimport com.t8rin.dynamic.theme.extractPrimaryColor\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.ColorModel\nimport com.t8rin.imagetoolbox.core.domain.model.HashingType\nimport com.t8rin.imagetoolbox.core.domain.model.SystemBarsVisibility\nimport com.t8rin.imagetoolbox.core.domain.resource.ResourceManager\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.humanFileSize\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsManager\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ColorHarmonizer\nimport com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.DomainFontFamily\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FlingType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.NightMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState\nimport com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SliderType\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode\nimport com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.Setting\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.SettingsGroup\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.UiFontFamily\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.collect\nimport kotlinx.coroutines.flow.onEach\nimport java.util.Locale\n\nclass SettingsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted private val onTryGetUpdate: (Boolean, () -> Unit) -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    @Assisted val isUpdateAvailable: Value<Boolean>,\n    @Assisted val onGoBack: (() -> Unit)?,\n    @Assisted initialSearchQuery: String,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val settingsManager: SettingsManager,\n    private val resourceManager: ResourceManager,\n    private val shareProvider: ShareProvider,\n    filenameCreator: FilenameCreator,\n    dispatchersHolder: DispatchersHolder,\n) : BaseComponent(dispatchersHolder, componentContext), FilenameCreator by filenameCreator {\n\n    private val _settingsState = mutableStateOf(SettingsState.Default)\n    val settingsState: SettingsState by _settingsState\n\n    private val _searchKeyword = mutableStateOf(\"\")\n    val searchKeyword by _searchKeyword\n\n    private val _filteredSettings: MutableState<List<Pair<SettingsGroup, Setting>>?> =\n        mutableStateOf(null)\n    val filteredSettings by _filteredSettings\n\n    private val _isFilteringSettings = mutableStateOf(false)\n    val isFilteringSettings by _isFilteringSettings\n\n    private var filterJob by smartJob()\n    private fun filterSettings() {\n        filterJob = componentScope.launch {\n            delay(150)\n            _isFilteringSettings.update { searchKeyword.isNotEmpty() }\n            _filteredSettings.update {\n                searchKeyword.takeIf { it.trim().isNotEmpty() }?.let {\n                    val newList = mutableListOf<Pair<Pair<SettingsGroup, Setting>, Int>>()\n                    SettingsGroup.entries.forEach { group ->\n                        group.settingsList.forEach { setting ->\n                            val keywords = mutableListOf<String>().apply {\n                                add(resourceManager.getString(group.titleId))\n                                add(resourceManager.getString(setting.title))\n                                add(\n                                    resourceManager.getStringLocalized(\n                                        group.titleId,\n                                        Locale.ENGLISH.language\n                                    )\n                                )\n                                add(\n                                    resourceManager.getStringLocalized(\n                                        setting.title,\n                                        Locale.ENGLISH.language\n                                    )\n                                )\n                                setting.subtitle?.let {\n                                    add(resourceManager.getString(it))\n                                    add(\n                                        resourceManager.getStringLocalized(\n                                            it,\n                                            Locale.ENGLISH.language\n                                        )\n                                    )\n                                }\n                            }\n\n                            val substringStart = keywords\n                                .joinToString()\n                                .indexOf(\n                                    string = searchKeyword,\n                                    ignoreCase = true\n                                ).takeIf { it != -1 }\n\n                            substringStart?.plus(searchKeyword.length)?.let { substringEnd ->\n                                newList.add(group to setting to (substringEnd - substringStart))\n                            }\n                        }\n                    }\n                    newList.sortedBy { it.second }.map { it.first }\n                }\n            }\n            _isFilteringSettings.update { false }\n        }\n    }\n\n    fun updateSearchKeyword(value: String) {\n        _searchKeyword.update { value }\n        filterSettings()\n    }\n\n    fun tryGetUpdate(\n        isNewRequest: Boolean = false,\n        onNoUpdates: () -> Unit = {}\n    ) = onTryGetUpdate(isNewRequest, onNoUpdates)\n\n    init {\n        settingsScope {\n            settingsState.onEach {\n                _settingsState.value = it\n            }.collect()\n        }\n\n        debounce {\n            updateSearchKeyword(initialSearchQuery)\n        }\n    }\n\n    fun getReadableCacheSize(): String = humanFileSize(fileController.getCacheSize())\n\n    fun clearCache(onComplete: (String) -> Unit = {}) = fileController.clearCache {\n        onComplete(getReadableCacheSize())\n    }\n\n    fun toggleAddSequenceNumber() = settingsScope { toggleAddSequenceNumber() }\n\n    fun toggleAddOriginalFilename() = settingsScope { toggleAddOriginalFilename() }\n\n    fun setEmojisCount(count: Int) = settingsScope { setEmojisCount(count) }\n\n    fun setImagePickerMode(mode: Int) = settingsScope { setImagePickerMode(mode) }\n\n    fun toggleAddFileSize() = settingsScope { toggleAddFileSize() }\n\n    fun setEmoji(emoji: Int) = settingsScope { setEmoji(emoji) }\n\n    fun setFilenamePrefix(name: String) = settingsScope { setFilenamePrefix(name) }\n\n    fun setFilenameSuffix(name: String) = settingsScope { setFilenameSuffix(name) }\n\n    fun toggleShowUpdateDialog() = settingsScope { toggleShowUpdateDialogOnStartup() }\n\n    fun setColorTuple(colorTuple: ColorTuple) = settingsScope {\n        setColorTuple(\n            colorTuple.run {\n                \"${primary.toArgb()}*${secondary?.toArgb()}*${tertiary?.toArgb()}*${surface?.toArgb()}\"\n            }\n        )\n    }\n\n    fun toggleDynamicColors() = settingsScope { toggleDynamicColors() }\n\n    fun toggleLockDrawOrientation() = settingsScope { toggleLockDrawOrientation() }\n\n    fun setBorderWidth(width: Float) = settingsScope { setBorderWidth(width) }\n\n    fun toggleAllowImageMonet() = settingsScope { toggleAllowImageMonet() }\n\n    fun toggleAmoledMode() = settingsScope { toggleAmoledMode() }\n\n    fun setNightMode(nightMode: NightMode) = settingsScope { setNightMode(nightMode) }\n\n    fun setSaveFolderUri(uri: Uri?) = settingsScope { setSaveFolderUri(uri?.toString()) }\n\n    private fun List<ColorTuple>.asString(): String = joinToString(separator = \"*\") {\n        \"${it.primary.toArgb()}/${it.secondary?.toArgb()}/${it.tertiary?.toArgb()}/${it.surface?.toArgb()}\"\n    }\n\n    fun setColorTuples(colorTuples: List<ColorTuple>) =\n        settingsScope { setColorTuples(colorTuples.asString()) }\n\n    fun setAlignment(align: Float) = settingsScope { setAlignment(align.toInt()) }\n\n    fun setScreenOrder(data: List<Screen>) =\n        settingsScope { setScreenOrder(data.joinToString(\"/\") { it.id.toString() }) }\n\n    fun toggleClearCacheOnLaunch() = settingsScope { toggleClearCacheOnLaunch() }\n\n    fun toggleGroupOptionsByType() = settingsScope { toggleGroupOptionsByTypes() }\n\n    fun toggleRandomizeFilename() = settingsScope { toggleRandomizeFilename() }\n\n    fun createBackup(\n        uri: Uri\n    ) = settingsScope {\n        fileController.writeBytes(\n            uri = uri.toString(),\n            block = { it.writeBytes(createBackupFile()) }\n        ).also(::parseFileSaveResult)\n    }\n\n    fun exportFonts(uri: Uri) = settingsScope {\n        fileController.transferBytes(\n            fromUri = createCustomFontsExport().toString(),\n            toUri = uri.toString()\n        ).also(::parseFileSaveResult)\n    }\n\n    fun restoreBackupFrom(\n        uri: Uri,\n        onSuccess: () -> Unit,\n        onFailure: (Throwable) -> Unit,\n    ) = settingsScope {\n        restoreFromBackupFile(\n            backupFileUri = uri.toString(),\n            onSuccess = onSuccess,\n            onFailure = onFailure\n        )\n    }\n\n    fun resetSettings() = settingsScope { resetSettings() }\n\n    fun createBackupFilename(): String = settingsManager.createBackupFilename()\n\n    fun setFont(font: DomainFontFamily) = settingsScope { setFont(font) }\n\n    fun setFontScale(scale: Float) = settingsScope { setFontScale(scale) }\n\n    fun toggleAllowCollectCrashlytics() = settingsScope { toggleAllowCrashlytics() }\n\n    fun toggleAllowCollectAnalytics() = settingsScope { toggleAllowAnalytics() }\n\n    fun toggleAllowBetas() = settingsScope { toggleAllowBetas() }\n\n    fun toggleDrawContainerShadows() = settingsScope { toggleDrawContainerShadows() }\n\n    fun toggleDrawSwitchShadows() = settingsScope { toggleDrawSwitchShadows() }\n\n    fun toggleDrawSliderShadows() = settingsScope { toggleDrawSliderShadows() }\n\n    fun toggleDrawButtonShadows() = settingsScope { toggleDrawButtonShadows() }\n\n    fun toggleDrawFabShadows() = settingsScope { toggleDrawFabShadows() }\n\n    fun addColorTupleFromEmoji(emoji: String) = settingsScope {\n        if (emoji.contains(\"shoe\", true)) {\n            setFont(DomainFontFamily.DejaVu)\n            val colorTuple = ColorTuple(\n                primary = Color(0xFF6D216D),\n                secondary = Color(0xFF240A95),\n                tertiary = Color(0xFFFFFFA0),\n                surface = Color(0xFF1D2D3D)\n            )\n            val colorTupleS = listOf(colorTuple).asString()\n            setColorTuple(colorTuple)\n            setColorTuples(this@SettingsComponent.settingsState.colorTupleList + \"*\" + colorTupleS)\n            setThemeContrast(0f)\n            setThemeStyle(0)\n            if (this@SettingsComponent.settingsState.useEmojiAsPrimaryColor) toggleUseEmojiAsPrimaryColor()\n            if (this@SettingsComponent.settingsState.isInvertThemeColors) toggleInvertColors()\n        } else {\n            imageGetter.getImage(data = emoji)\n                ?.extractPrimaryColor()\n                ?.let { primary ->\n                    val colorTuple = ColorTuple(primary)\n                    setColorTuple(colorTuple)\n                    settingsManager.setColorTuples(\n                        this@SettingsComponent.settingsState.colorTupleList + \"*\" + listOf(\n                            colorTuple\n                        ).asString()\n                    )\n                }\n        }\n        if (this@SettingsComponent.settingsState.isDynamicColors) toggleDynamicColors()\n    }\n\n    fun setThemeContrast(value: Float) = settingsScope { setThemeContrast(value.toDouble()) }\n\n    fun setThemeStyle(value: Int) = settingsScope { setThemeStyle(value) }\n\n    fun toggleInvertColors() = settingsScope { toggleInvertColors() }\n\n    fun toggleScreenSearchEnabled() = settingsScope { toggleScreensSearchEnabled() }\n\n    fun toggleDrawAppBarShadows() = settingsScope { toggleDrawAppBarShadows() }\n\n    private fun setCopyToClipboardMode(copyToClipboardMode: CopyToClipboardMode) =\n        settingsScope { setCopyToClipboardMode(copyToClipboardMode) }\n\n    fun toggleAutoPinClipboard(value: Boolean) {\n        val mode = if (value) {\n            CopyToClipboardMode.Enabled.WithSaving\n        } else {\n            CopyToClipboardMode.Disabled\n        }\n        setCopyToClipboardMode(mode)\n    }\n\n    fun toggleAutoPinClipboardOnlyClip(value: Boolean) {\n        val mode = if (value) {\n            CopyToClipboardMode.Enabled.WithoutSaving\n        } else {\n            CopyToClipboardMode.Enabled.WithSaving\n        }\n        setCopyToClipboardMode(mode)\n    }\n\n    fun setVibrationStrength(strength: Int) = settingsScope { setVibrationStrength(strength) }\n\n    fun toggleOverwriteFiles() = settingsScope { toggleOverwriteFiles() }\n\n    fun setDefaultImageScaleMode(imageScaleMode: ImageScaleMode) =\n        settingsScope { setDefaultImageScaleMode(imageScaleMode) }\n\n    fun setSwitchType(type: SwitchType) = settingsScope { setSwitchType(type) }\n\n    fun toggleMagnifierEnabled() = settingsScope { toggleMagnifierEnabled() }\n\n    fun toggleExifWidgetInitialState() = settingsScope { toggleExifWidgetInitialState() }\n\n    fun setScreensWithBrightnessEnforcement(screen: Screen) = settingsScope {\n        val screens =\n            this@SettingsComponent.settingsState.screenListWithMaxBrightnessEnforcement\n                .toggle(screen.id)\n\n        setScreensWithBrightnessEnforcement(screens)\n    }\n\n    fun toggleConfettiEnabled() = settingsScope { toggleConfettiEnabled() }\n\n    fun toggleSecureMode() = settingsScope { toggleSecureMode() }\n\n    fun toggleUseEmojiAsPrimaryColor() = settingsScope { toggleUseEmojiAsPrimaryColor() }\n\n    fun toggleUseRandomEmojis() = settingsScope { toggleUseRandomEmojis() }\n\n    fun setIconShape(iconShape: Int) = settingsScope { setIconShape(iconShape) }\n\n    fun setDragHandleWidth(width: Int) = settingsScope { setDragHandleWidth(width) }\n\n    fun setConfettiType(type: Int) = settingsScope { setConfettiType(type) }\n\n    fun toggleAllowAutoClipboardPaste() = settingsScope { toggleAllowAutoClipboardPaste() }\n\n    fun setConfettiHarmonizer(colorHarmonizer: ColorHarmonizer) =\n        settingsScope { setConfettiHarmonizer(colorHarmonizer) }\n\n    fun setConfettiHarmonizationLevel(level: Float) =\n        settingsScope { setConfettiHarmonizationLevel(level) }\n\n    fun toggleGeneratePreviews() = settingsScope { toggleGeneratePreviews() }\n\n    fun toggleSkipImagePicking() = settingsScope { toggleSkipImagePicking() }\n\n    fun toggleShowSettingsInLandscape() = settingsScope { toggleShowSettingsInLandscape() }\n\n    fun toggleUseFullscreenSettings() = settingsScope { toggleUseFullscreenSettings() }\n\n    fun setDefaultDrawLineWidth(value: Float) = settingsScope { setDefaultDrawLineWidth(value) }\n\n    fun toggleOpenEditInsteadOfPreview() = settingsScope { toggleOpenEditInsteadOfPreview() }\n\n    fun toggleCanEnterPresetsByTextField() = settingsScope { toggleCanEnterPresetsByTextField() }\n\n    fun setColorBlindScheme(value: Int?) = settingsScope { setColorBlindType(value) }\n\n    fun toggleIsLinksPreviewEnabled() = settingsScope { toggleIsLinkPreviewEnabled() }\n\n    fun setDefaultDrawColor(colorModel: ColorModel) =\n        settingsScope { setDefaultDrawColor(colorModel) }\n\n    fun setDefaultDrawPathMode(mode: Int) = settingsScope { setDefaultDrawPathMode(mode) }\n\n    fun toggleAddTimestampToFilename() = settingsScope { toggleAddTimestampToFilename() }\n\n    fun toggleUseFormattedFilenameTimestamp() =\n        settingsScope { toggleUseFormattedFilenameTimestamp() }\n\n    fun setDefaultResizeType(resizeType: ResizeType) =\n        settingsScope { setDefaultResizeType(resizeType) }\n\n    fun setSystemBarsVisibility(systemBarsVisibility: SystemBarsVisibility) =\n        settingsScope { setSystemBarsVisibility(systemBarsVisibility) }\n\n    fun toggleIsSystemBarsVisibleBySwipe() = settingsScope { toggleIsSystemBarsVisibleBySwipe() }\n\n    fun toggleUseCompactSelectors() = settingsScope { toggleUseCompactSelectorsLayout() }\n\n    fun setMainScreenTitle(title: String) = settingsScope { setMainScreenTitle(title) }\n\n    fun setSliderType(sliderType: SliderType) = settingsScope { setSliderType(sliderType) }\n\n    fun toggleIsCenterAlignDialogButtons() = settingsScope { toggleIsCenterAlignDialogButtons() }\n\n    fun setFastSettingsSide(side: FastSettingsSide) = settingsScope { setFastSettingsSide(side) }\n\n    fun setChecksumTypeForFilename(type: HashingType?) =\n        settingsScope { setChecksumTypeForFilename(type) }\n\n    fun importCustomFont(\n        uri: Uri,\n        onSuccess: () -> Unit,\n        onFailure: () -> Unit\n    ) = settingsScope {\n        importCustomFont(uri.toString())?.let { font ->\n            setFont(font)\n            onSuccess()\n        } ?: onFailure()\n    }\n\n    fun removeCustomFont(\n        font: UiFontFamily.Custom\n    ) = settingsScope {\n        removeCustomFont(font.asDomain() as DomainFontFamily.Custom)\n        setFont(DomainFontFamily.System)\n    }\n\n    fun toggleEnableToolExitConfirmation() = settingsScope { toggleEnableToolExitConfirmation() }\n\n    fun shareLogs(onComplete: () -> Unit) = settingsScope {\n        shareProvider.shareUri(\n            uri = settingsManager.createLogsExport(),\n            onComplete = onComplete\n        )\n    }\n\n    fun toggleAddPresetInfoToFilename() = settingsScope { toggleAddPresetInfoToFilename() }\n\n    fun toggleAddImageScaleModeInfoToFilename() =\n        settingsScope { toggleAddImageScaleModeInfoToFilename() }\n\n    fun toggleAllowSkipIfLarger() = settingsScope { toggleAllowSkipIfLarger() }\n\n    fun toggleIsScreenSelectionLauncherMode() =\n        settingsScope { toggleIsScreenSelectionLauncherMode() }\n\n    fun setSnowfallMode(snowfallMode: SnowfallMode) =\n        settingsScope { setSnowfallMode(snowfallMode) }\n\n    fun setDefaultImageFormat(imageFormat: ImageFormat?) =\n        settingsScope { setDefaultImageFormat(imageFormat) }\n\n    fun setDefaultQuality(quality: Quality) =\n        settingsScope { setDefaultQuality(quality) }\n\n    fun setShapesType(shapeType: ShapeType) = settingsScope { setShapesType(shapeType) }\n\n    fun setFilenamePattern(value: String) = settingsScope { setFilenamePattern(value) }\n\n    fun setFlingType(type: FlingType) = settingsScope { setFlingType(type) }\n\n    fun setHiddenForShareScreens(screen: Screen) = settingsScope {\n        val screens =\n            this@SettingsComponent.settingsState.hiddenForShareScreens\n                .toggle(screen.id)\n\n        setHiddenForShareScreens(screens)\n    }\n\n    fun toggleKeepDateTime() =\n        settingsScope { toggleKeepDateTime() }\n\n    fun toggleEnableBackgroundColorForAlphaFormats() =\n        settingsScope { toggleEnableBackgroundColorForAlphaFormats() }\n\n\n    private inline fun settingsScope(\n        crossinline action: suspend SettingsManager.() -> Unit\n    ) {\n        componentScope.launch {\n            settingsManager.action()\n        }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onTryGetUpdate: (Boolean, () -> Unit) -> Unit,\n            onNavigate: (Screen) -> Unit,\n            isUpdateAvailable: Value<Boolean>,\n            onGoBack: (() -> Unit)?,\n            initialSearchQuery: String\n        ): SettingsComponent\n    }\n}"
  },
  {
    "path": "feature/single-edit/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/single-edit/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.single_edit\"\n\ndependencies {\n    implementation(projects.feature.crop)\n    implementation(projects.feature.eraseBackground)\n    implementation(projects.feature.draw)\n    implementation(projects.feature.filters)\n    implementation(projects.feature.pickColor)\n    implementation(projects.feature.compare)\n    implementation(projects.lib.curves)\n}"
  },
  {
    "path": "feature/single-edit/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/SingleEditContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.History\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.CompareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShowOriginalButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageExtraTransformBar\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageTransformBar\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.resize_group.ResizeTypeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PresetSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ScaleModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.EditExifSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.core.utils.fileSize\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareSheet\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.components.CropEditOption\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.components.DrawEditOption\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.components.EraseBackgroundEditOption\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.components.FilterEditOption\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.components.ToneCurvesEditOption\nimport com.t8rin.imagetoolbox.feature.single_edit.presentation.screenLogic.SingleEditComponent\n\n@Composable\nfun SingleEditContent(\n    component: SingleEditComponent,\n) {\n    AutoContentBasedColors(component.bitmap)\n\n    var showResetDialog by rememberSaveable { mutableStateOf(false) }\n    var showOriginal by rememberSaveable { mutableStateOf(false) }\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val imageInfo = component.imageInfo\n\n    val imagePicker = rememberImagePicker(onSuccess = component::setUri)\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = component.initialUri != null\n    )\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmap(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n    var showCompareSheet by rememberSaveable { mutableStateOf(false) }\n\n    CompareSheet(\n        data = component.initialBitmap to component.previewBitmap,\n        visible = showCompareSheet,\n        onDismiss = {\n            showCompareSheet = false\n        }\n    )\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    var showCropper by rememberSaveable { mutableStateOf(false) }\n    var showFiltering by rememberSaveable { mutableStateOf(false) }\n    var showDrawing by rememberSaveable { mutableStateOf(false) }\n    var showEraseBackground by rememberSaveable { mutableStateOf(false) }\n    var showApplyCurves by rememberSaveable { mutableStateOf(false) }\n\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            val originalSize = component.uri.fileSize() ?: 0\n            val compressedSize = component.imageInfo.sizeInBytes.toLong()\n            TopAppBarTitle(\n                title = stringResource(R.string.single_edit),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = compressedSize,\n                originalSize = originalSize\n            )\n        },\n        onGoBack = onBack,\n        topAppBarPersistentActions = {\n            if (component.bitmap == null) {\n                TopAppBarEmoji()\n            }\n            CompareButton(\n                onClick = { showCompareSheet = true },\n                visible = component.previewBitmap != null\n                        && component.bitmap != null\n                        && component.shouldShowPreview\n            )\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.previewBitmap != null && component.shouldShowPreview\n            )\n        },\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.bitmap != null,\n                onShare = component::shareBitmap,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheCurrentImage { uri ->\n                        editSheetData = listOf(uri)\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = { editSheetData = emptyList() },\n                onNavigate = component.onNavigate\n            )\n\n            EnhancedIconButton(\n                enabled = component.bitmap != null,\n                onClick = { showResetDialog = true }\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.ImageReset,\n                    contentDescription = stringResource(R.string.reset_image)\n                )\n            }\n            if (component.bitmap != null) {\n                ShowOriginalButton(\n                    canShow = component.canShow(),\n                    onStateChange = {\n                        showOriginal = it\n                    }\n                )\n            } else {\n                EnhancedIconButton(\n                    enabled = false,\n                    onClick = {}\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.History,\n                        contentDescription = stringResource(R.string.original)\n                    )\n                }\n            }\n        },\n        imagePreview = {\n            ImageContainer(\n                imageInside = isPortrait,\n                showOriginal = showOriginal,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.initialBitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = component.shouldShowPreview\n            )\n        },\n        controls = {\n            var showEditExifDialog by rememberSaveable { mutableStateOf(false) }\n            val preset = component.presetSelected\n            ImageTransformBar(\n                onEditExif = { showEditExifDialog = true },\n                imageFormat = component.imageInfo.imageFormat,\n                onRotateLeft = component::rotateBitmapLeft,\n                onFlip = component::flipImage,\n                onRotateRight = component::rotateBitmapRight,\n                canRotate = !(preset is Preset.AspectRatio && preset.ratio != 1f)\n            )\n            Spacer(Modifier.size(8.dp))\n            ImageExtraTransformBar(\n                onCrop = { showCropper = true },\n                onFilter = { showFiltering = true },\n                onDraw = { showDrawing = true },\n                onEraseBackground = { showEraseBackground = true },\n                onApplyCurves = { showApplyCurves = true }\n            )\n            Spacer(Modifier.size(16.dp))\n            PresetSelector(\n                value = component.presetSelected,\n                includeTelegramOption = true,\n                includeAspectRatioOption = true,\n                onValueChange = component::setPreset\n            )\n            Spacer(Modifier.size(8.dp))\n            ResizeImageField(\n                imageInfo = imageInfo,\n                originalSize = component.originalSize,\n                onHeightChange = component::updateHeight,\n                onWidthChange = component::updateWidth,\n                showWarning = component.showWarning\n            )\n            if (imageInfo.imageFormat.canChangeCompressionValue) Spacer(\n                Modifier.height(8.dp)\n            )\n            QualitySelector(\n                imageFormat = imageInfo.imageFormat,\n                quality = imageInfo.quality,\n                onQualityChange = component::setQuality\n            )\n            Spacer(Modifier.height(8.dp))\n            ImageFormatSelector(\n                value = imageInfo.imageFormat,\n                onValueChange = component::setImageFormat,\n                quality = imageInfo.quality,\n            )\n            Spacer(Modifier.height(8.dp))\n            ResizeTypeSelector(\n                enabled = component.bitmap != null,\n                value = imageInfo.resizeType,\n                onValueChange = component::setResizeType\n            )\n            Spacer(Modifier.height(8.dp))\n            ScaleModeSelector(\n                value = imageInfo.imageScaleMode,\n                onValueChange = component::setImageScaleMode\n            )\n\n            EditExifSheet(\n                visible = showEditExifDialog,\n                onDismiss = {\n                    showEditExifDialog = false\n                },\n                exif = component.exif,\n                onClearExif = component::clearExif,\n                onUpdateTag = component::updateExifByTag,\n                onRemoveTag = component::removeExifTag\n            )\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uri == Uri.EMPTY,\n                onSecondaryButtonClick = pickImage,\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                },\n                onPrimaryButtonClick = {\n                    saveBitmap(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmap,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Single,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        canShowScreenData = component.bitmap != null,\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        },\n        forceImagePreviewToMax = showOriginal\n    )\n\n    ResetDialog(\n        visible = showResetDialog,\n        onDismiss = { showResetDialog = false },\n        onReset = {\n            component.resetValues(true)\n        }\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        onCancelLoading = component::cancelSaving\n    )\n\n    CropEditOption(\n        visible = showCropper,\n        onDismiss = { showCropper = false },\n        useScaffold = isPortrait,\n        bitmap = component.previewBitmap,\n        onGetBitmap = component::updateBitmapAfterEditing,\n        cropProperties = component.cropProperties,\n        setCropAspectRatio = component::setCropAspectRatio,\n        setCropMask = component::setCropMask,\n        selectedAspectRatio = component.selectedAspectRatio,\n        loadImage = component::loadImage\n    )\n\n    FilterEditOption(\n        visible = showFiltering,\n        onDismiss = {\n            showFiltering = false\n            component.clearFilterList()\n        },\n        useScaffold = isPortrait,\n        bitmap = component.previewBitmap,\n        onGetBitmap = {\n            component.updateBitmapAfterEditing(it, true)\n        },\n        onRequestMappingFilters = component::mapFilters,\n        filterList = component.filterList,\n        updateOrder = component::updateOrder,\n        updateFilter = component::updateFilter,\n        removeAt = component::removeFilterAtIndex,\n        addFilter = component::addFilter,\n        filterTemplateCreationSheetComponent = component.filterTemplateCreationSheetComponent,\n        addFilterSheetComponent = component.addFiltersSheetComponent\n    )\n\n    DrawEditOption(\n        addFiltersSheetComponent = component.addFiltersSheetComponent,\n        filterTemplateCreationSheetComponent = component.filterTemplateCreationSheetComponent,\n        onRequestFiltering = component::filter,\n        visible = showDrawing,\n        onDismiss = {\n            showDrawing = false\n            component.clearDrawing()\n        },\n        useScaffold = isPortrait,\n        bitmap = component.previewBitmap,\n        onGetBitmap = {\n            component.updateBitmapAfterEditing(it, true)\n            component.clearDrawing()\n        },\n        undo = component::undoDraw,\n        redo = component::redoDraw,\n        paths = component.drawPaths,\n        lastPaths = component.drawLastPaths,\n        undonePaths = component.drawUndonePaths,\n        addPath = component::addPathToDrawList,\n        drawMode = component.drawMode,\n        onUpdateDrawMode = component::updateDrawMode,\n        drawPathMode = component.drawPathMode,\n        onUpdateDrawPathMode = component::updateDrawPathMode,\n        drawLineStyle = component.drawLineStyle,\n        onUpdateDrawLineStyle = component::updateDrawLineStyle,\n        helperGridParams = component.helperGridParams,\n        onUpdateHelperGridParams = component::updateHelperGridParams\n    )\n\n    EraseBackgroundEditOption(\n        visible = showEraseBackground,\n        onDismiss = {\n            showEraseBackground = false\n            component.clearErasing()\n        },\n        useScaffold = isPortrait,\n        bitmap = component.previewBitmap,\n        onGetBitmap = { bitmap, saveSize ->\n            component.updateBitmapAfterEditing(\n                bitmap = bitmap,\n                saveOriginalSize = saveSize\n            )\n        },\n        clearErasing = component::clearErasing,\n        undo = component::undoErase,\n        redo = component::redoErase,\n        paths = component.erasePaths,\n        lastPaths = component.eraseLastPaths,\n        undonePaths = component.eraseUndonePaths,\n        addPath = component::addPathToEraseList,\n        drawPathMode = component.drawPathMode,\n        onUpdateDrawPathMode = component::updateDrawPathMode,\n        autoBackgroundRemover = component.getBackgroundRemover(),\n        helperGridParams = component.helperGridParams,\n        onUpdateHelperGridParams = component::updateHelperGridParams\n    )\n\n    ToneCurvesEditOption(\n        visible = showApplyCurves,\n        onDismiss = { showApplyCurves = false },\n        useScaffold = isPortrait,\n        bitmap = component.previewBitmap,\n        editorState = component.imageCurvesEditorState,\n        onResetState = component::resetImageCurvesEditorState,\n        onGetBitmap = {\n            component.updateBitmapAfterEditing(it, true)\n        }\n    )\n}"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/components/CropEditOption.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation.components\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.settings.CropOutlineProperty\nimport com.t8rin.cropper.settings.CropProperties\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.utils.notNullAnd\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.CropSmall\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.MagnifierEnabledSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AspectRatioSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CoercePointsToImageBoundsToggle\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CropMaskSelection\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CropRotationSelector\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.CropType\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.Cropper\nimport com.t8rin.imagetoolbox.feature.crop.presentation.components.FreeCornersCropToggle\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun CropEditOption(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    useScaffold: Boolean,\n    bitmap: Bitmap?,\n    onGetBitmap: (Bitmap) -> Unit,\n    cropProperties: CropProperties,\n    selectedAspectRatio: DomainAspectRatio,\n    setCropAspectRatio: (DomainAspectRatio, AspectRatio) -> Unit,\n    setCropMask: (CropOutlineProperty) -> Unit,\n    loadImage: suspend (Uri) -> Bitmap?\n) {\n    val rotationState = rememberSaveable {\n        mutableFloatStateOf(0f)\n    }\n    var coercePointsToImageArea by rememberSaveable {\n        mutableStateOf(true)\n    }\n    var cropType by rememberSaveable {\n        mutableStateOf(CropType.Default)\n    }\n\n    LaunchedEffect(cropProperties.cropOutlineProperty) {\n        cropType = if (cropProperties.cropOutlineProperty.cropOutline.id != 0) {\n            CropType.NoRotation\n        } else {\n            CropType.Default\n        }\n    }\n\n    val toggleFreeCornersCrop: () -> Unit = {\n        cropType = if (cropType != CropType.FreeCorners) {\n            CropType.FreeCorners\n        } else if (cropProperties.cropOutlineProperty.cropOutline.id != 0) {\n            CropType.NoRotation\n        } else {\n            CropType.Default\n        }\n    }\n\n    val scope = rememberCoroutineScope()\n    bitmap?.let {\n        var crop by remember(visible) { mutableStateOf(false) }\n        var stateBitmap by remember(bitmap, visible) { mutableStateOf(bitmap) }\n        FullscreenEditOption(\n            canGoBack = stateBitmap == bitmap,\n            visible = visible,\n            onDismiss = onDismiss,\n            useScaffold = useScaffold,\n            controls = { scaffoldState ->\n                val focus = LocalFocusManager.current\n                LaunchedEffect(scaffoldState?.bottomSheetState?.currentValue, focus) {\n                    val current = scaffoldState?.bottomSheetState?.currentValue\n                    if (current.notNullAnd { it != SheetValue.Expanded }) {\n                        focus.clearFocus()\n                    }\n                }\n\n                Spacer(modifier = Modifier.height(16.dp))\n                FreeCornersCropToggle(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 16.dp),\n                    value = cropType == CropType.FreeCorners,\n                    onClick = toggleFreeCornersCrop\n                )\n                BoxAnimatedVisibility(\n                    visible = cropType == CropType.Default,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    CropRotationSelector(\n                        value = rotationState.floatValue,\n                        onValueChange = { rotationState.floatValue = it },\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(top = 8.dp)\n                            .padding(horizontal = 16.dp),\n                    )\n                }\n                BoxAnimatedVisibility(\n                    visible = cropType == CropType.FreeCorners,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    Column(\n                        modifier = Modifier\n                            .padding(top = 8.dp)\n                            .padding(horizontal = 16.dp)\n                    ) {\n                        CoercePointsToImageBoundsToggle(\n                            value = coercePointsToImageArea,\n                            onValueChange = { coercePointsToImageArea = it },\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                        Spacer(Modifier.height(8.dp))\n                        MagnifierEnabledSelector(\n                            modifier = Modifier.fillMaxWidth(),\n                            shape = ShapeDefaults.extraLarge,\n                        )\n                    }\n                }\n                BoxAnimatedVisibility(\n                    visible = cropType != CropType.FreeCorners,\n                    enter = fadeIn() + expandVertically(),\n                    exit = fadeOut() + shrinkVertically()\n                ) {\n                    Column {\n                        Spacer(modifier = Modifier.height(8.dp))\n                        AspectRatioSelector(\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .padding(horizontal = 16.dp),\n                            selectedAspectRatio = selectedAspectRatio,\n                            onAspectRatioChange = setCropAspectRatio\n                        )\n                        Spacer(modifier = Modifier.height(8.dp))\n                        CropMaskSelection(\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .padding(horizontal = 16.dp),\n                            onCropMaskChange = setCropMask,\n                            selectedItem = cropProperties.cropOutlineProperty,\n                            loadImage = {\n                                loadImage(it)?.asImageBitmap()\n                            }\n                        )\n                    }\n                }\n                Spacer(modifier = Modifier.height(16.dp))\n            },\n            fabButtons = {\n                var job by remember { mutableStateOf<Job?>(null) }\n                EnhancedFloatingActionButton(\n                    onClick = {\n                        job?.cancel()\n                        job = scope.launch {\n                            delay(500)\n                            crop = true\n                        }\n                    },\n                    containerColor = MaterialTheme.colorScheme.primaryContainer\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.CropSmall,\n                        contentDescription = stringResource(R.string.crop)\n                    )\n                }\n            },\n            actions = {},\n            topAppBar = { closeButton ->\n                EnhancedTopAppBar(\n                    type = EnhancedTopAppBarType.Center,\n                    navigationIcon = closeButton,\n                    actions = {\n                        AnimatedVisibility(visible = stateBitmap != bitmap) {\n                            EnhancedIconButton(\n                                containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                onClick = {\n                                    onGetBitmap(stateBitmap)\n                                    onDismiss()\n                                }\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Done,\n                                    contentDescription = \"Done\"\n                                )\n                            }\n                        }\n                    },\n                    title = {\n                        Text(\n                            text = stringResource(R.string.crop),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n            }\n        ) {\n            var loading by remember { mutableStateOf(false) }\n            Box(contentAlignment = Alignment.Center) {\n                Cropper(\n                    bitmap = stateBitmap,\n                    crop = crop,\n                    onImageCropStarted = { loading = true },\n                    onImageCropFinished = {\n                        if (it != null) {\n                            stateBitmap = it\n                            scope.launch {\n                                delay(500)\n                                loading = false\n                            }\n                        } else {\n                            loading = false\n                        }\n                        crop = false\n                    },\n                    rotationState = rotationState,\n                    cropProperties = cropProperties,\n                    cropType = cropType,\n                    addVerticalInsets = !useScaffold,\n                    coercePointsToImageArea = coercePointsToImageArea\n                )\n                AnimatedVisibility(\n                    visible = loading,\n                    modifier = Modifier.fillMaxSize(),\n                    enter = fadeIn(),\n                    exit = fadeOut()\n                ) {\n                    Box(\n                        contentAlignment = Alignment.Center,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .background(MaterialTheme.colorScheme.scrim.copy(0.5f))\n                    ) {\n                        EnhancedLoadingIndicator()\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/components/DrawEditOption.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.Redo\nimport androidx.compose.material.icons.automirrored.rounded.Undo\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.platform.LocalFocusManager\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.coerceIn\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.domain.utils.notNullAnd\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.EraseModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.HelperGridParamsSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.MagnifierEnabledSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.DrawLockScreenOrientation\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.PtSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BitmapDrawer\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BrushSoftnessSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawColorSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawLineStyleSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawModeSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawPathModeSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.LineWidthSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.OpenColorPickerCard\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageSheet\n\n@Composable\nfun DrawEditOption(\n    visible: Boolean,\n    onRequestFiltering: suspend (Bitmap, List<Filter<*>>) -> Bitmap?,\n    drawMode: DrawMode,\n    onUpdateDrawMode: (DrawMode) -> Unit,\n    drawPathMode: DrawPathMode,\n    onUpdateDrawPathMode: (DrawPathMode) -> Unit,\n    drawLineStyle: DrawLineStyle,\n    onUpdateDrawLineStyle: (DrawLineStyle) -> Unit,\n    onDismiss: () -> Unit,\n    useScaffold: Boolean,\n    bitmap: Bitmap?,\n    onGetBitmap: (Bitmap) -> Unit,\n    undo: () -> Unit,\n    redo: () -> Unit,\n    paths: List<UiPathPaint>,\n    lastPaths: List<UiPathPaint>,\n    undonePaths: List<UiPathPaint>,\n    addPath: (UiPathPaint) -> Unit,\n    helperGridParams: HelperGridParams,\n    onUpdateHelperGridParams: (HelperGridParams) -> Unit,\n    addFiltersSheetComponent: AddFiltersSheetComponent,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent\n) {\n    bitmap?.let {\n        var panEnabled by rememberSaveable { mutableStateOf(false) }\n\n        val switch = @Composable {\n            PanModeButton(\n                selected = panEnabled,\n                onClick = {\n                    panEnabled = !panEnabled\n                }\n            )\n        }\n\n        var showPickColorSheet by rememberSaveable { mutableStateOf(false) }\n\n        var isEraserOn by rememberSaveable { mutableStateOf(false) }\n\n        val settingsState = LocalSettingsState.current\n        var strokeWidth by rememberSaveable(stateSaver = PtSaver) { mutableStateOf(settingsState.defaultDrawLineWidth.pt) }\n        var drawColor by rememberSaveable(stateSaver = ColorSaver) { mutableStateOf(settingsState.defaultDrawColor) }\n\n        var alpha by rememberSaveable(drawMode) {\n            mutableFloatStateOf(if (drawMode is DrawMode.Highlighter) 0.4f else 1f)\n        }\n        var brushSoftness by rememberSaveable(drawMode, stateSaver = PtSaver) {\n            mutableStateOf(if (drawMode is DrawMode.Neon) 35.pt else 0.pt)\n        }\n\n        LaunchedEffect(drawMode, strokeWidth) {\n            strokeWidth = if (drawMode is DrawMode.Image) {\n                strokeWidth.coerceIn(10.pt, 120.pt)\n            } else {\n                strokeWidth.coerceIn(1.pt, 100.pt)\n            }\n        }\n\n        val secondaryControls = @Composable {\n            Row(\n                modifier = Modifier.then(\n                    if (!useScaffold) {\n                        Modifier\n                            .padding(16.dp)\n                            .container(shape = ShapeDefaults.circle)\n                    } else Modifier\n                )\n            ) {\n                switch()\n                Spacer(Modifier.width(8.dp))\n                EnhancedIconButton(\n                    containerColor = Color.Transparent,\n                    borderColor = MaterialTheme.colorScheme.outlineVariant(\n                        luminance = 0.1f\n                    ),\n                    onClick = undo,\n                    enabled = lastPaths.isNotEmpty() || paths.isNotEmpty()\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.Undo,\n                        contentDescription = \"Undo\"\n                    )\n                }\n                EnhancedIconButton(\n                    containerColor = Color.Transparent,\n                    borderColor = MaterialTheme.colorScheme.outlineVariant(\n                        luminance = 0.1f\n                    ),\n                    onClick = redo,\n                    enabled = undonePaths.isNotEmpty()\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.Redo,\n                        contentDescription = \"Redo\"\n                    )\n                }\n                EraseModeButton(\n                    selected = isEraserOn,\n                    enabled = !panEnabled,\n                    onClick = {\n                        isEraserOn = !isEraserOn\n                    }\n                )\n            }\n        }\n\n        var stateBitmap by remember(bitmap, visible) { mutableStateOf(bitmap) }\n        FullscreenEditOption(\n            canGoBack = paths.isEmpty(),\n            visible = visible,\n            onDismiss = onDismiss,\n            useScaffold = useScaffold,\n            controls = { scaffoldState ->\n                Column(\n                    modifier = Modifier.padding(vertical = 16.dp),\n                    verticalArrangement = Arrangement.spacedBy(8.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    val focus = LocalFocusManager.current\n                    LaunchedEffect(scaffoldState?.bottomSheetState?.currentValue, focus) {\n                        val current = scaffoldState?.bottomSheetState?.currentValue\n                        if (current.notNullAnd { it != SheetValue.Expanded }) {\n                            focus.clearFocus()\n                        }\n                    }\n\n                    if (!useScaffold) secondaryControls()\n                    AnimatedVisibility(\n                        visible = drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n                        enter = fadeIn() + expandVertically(),\n                        exit = fadeOut() + shrinkVertically(),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        OpenColorPickerCard(\n                            onOpen = {\n                                showPickColorSheet = true\n                            }\n                        )\n                    }\n                    AnimatedVisibility(\n                        visible = drawMode !is DrawMode.PathEffect && drawMode !is DrawMode.Image && drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n                        enter = fadeIn() + expandVertically(),\n                        exit = fadeOut() + shrinkVertically(),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        DrawColorSelector(\n                            value = drawColor,\n                            onValueChange = { drawColor = it },\n                            modifier = Modifier.padding(horizontal = 16.dp)\n                        )\n                    }\n                    AnimatedVisibility(\n                        visible = drawPathMode.canChangeStrokeWidth,\n                        enter = fadeIn() + expandVertically(),\n                        exit = fadeOut() + shrinkVertically(),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        LineWidthSelector(\n                            modifier = Modifier.padding(horizontal = 16.dp),\n                            title = if (drawMode is DrawMode.Text) {\n                                stringResource(R.string.font_size)\n                            } else stringResource(R.string.line_width),\n                            valueRange = if (drawMode is DrawMode.Image) {\n                                10f..120f\n                            } else 1f..100f,\n                            value = strokeWidth.value,\n                            onValueChange = { strokeWidth = it.pt }\n                        )\n                    }\n                    AnimatedVisibility(\n                        visible = drawMode !is DrawMode.Highlighter && drawMode !is DrawMode.PathEffect && drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n                        enter = fadeIn() + expandVertically(),\n                        exit = fadeOut() + shrinkVertically(),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        BrushSoftnessSelector(\n                            modifier = Modifier.padding(horizontal = 16.dp),\n                            value = brushSoftness.value,\n                            onValueChange = { brushSoftness = it.pt }\n                        )\n                    }\n                    AnimatedVisibility(\n                        visible = drawMode !is DrawMode.Neon && drawMode !is DrawMode.PathEffect && drawMode !is DrawMode.SpotHeal && drawMode !is DrawMode.Warp,\n                        enter = fadeIn() + expandVertically(),\n                        exit = fadeOut() + shrinkVertically(),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        AlphaSelector(\n                            value = alpha,\n                            onValueChange = { alpha = it },\n                            modifier = Modifier.padding(horizontal = 16.dp)\n                        )\n                    }\n                    DrawModeSelector(\n                        addFiltersSheetComponent = addFiltersSheetComponent,\n                        filterTemplateCreationSheetComponent = filterTemplateCreationSheetComponent,\n                        modifier = Modifier.padding(horizontal = 16.dp),\n                        value = drawMode,\n                        strokeWidth = strokeWidth,\n                        onValueChange = {\n                            if (it is DrawMode.Warp) {\n                                onUpdateDrawPathMode(DrawPathMode.Free)\n                                onUpdateDrawLineStyle(DrawLineStyle.None)\n                            }\n                            onUpdateDrawMode(it)\n                        },\n                        values = remember(drawLineStyle) {\n                            derivedStateOf {\n                                if (drawLineStyle == DrawLineStyle.None) {\n                                    DrawMode.entries\n                                } else {\n                                    listOf(\n                                        DrawMode.Pen,\n                                        DrawMode.Highlighter,\n                                        DrawMode.Neon\n                                    )\n                                }\n                            }\n                        }.value\n                    )\n                    AnimatedVisibility(\n                        visible = drawMode !is DrawMode.Warp,\n                        enter = fadeIn() + expandVertically(),\n                        exit = fadeOut() + shrinkVertically(),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        DrawPathModeSelector(\n                            modifier = Modifier.padding(horizontal = 16.dp),\n                            value = drawPathMode,\n                            onValueChange = onUpdateDrawPathMode,\n                            values = remember(drawMode, drawLineStyle) {\n                                derivedStateOf {\n                                    if (drawMode !is DrawMode.Text && drawMode !is DrawMode.Image) {\n                                        when (drawLineStyle) {\n                                            DrawLineStyle.None -> DrawPathMode.entries\n\n                                            !is DrawLineStyle.Stamped<*> -> listOf(\n                                                DrawPathMode.Free,\n                                                DrawPathMode.Line,\n                                                DrawPathMode.LinePointingArrow(),\n                                                DrawPathMode.PointingArrow(),\n                                                DrawPathMode.DoublePointingArrow(),\n                                                DrawPathMode.DoubleLinePointingArrow(),\n                                            ) + DrawPathMode.outlinedEntries\n\n                                            else -> listOf(\n                                                DrawPathMode.Free,\n                                                DrawPathMode.Line\n                                            ) + DrawPathMode.outlinedEntries\n                                        }\n                                    } else {\n                                        listOf(\n                                            DrawPathMode.Free,\n                                            DrawPathMode.Line\n                                        ) + DrawPathMode.outlinedEntries\n                                    }\n                                }\n                            }.value,\n                            drawMode = drawMode\n                        )\n                    }\n                    AnimatedVisibility(\n                        visible = drawMode !is DrawMode.Warp,\n                        enter = fadeIn() + expandVertically(),\n                        exit = fadeOut() + shrinkVertically(),\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        DrawLineStyleSelector(\n                            modifier = Modifier.padding(horizontal = 16.dp),\n                            value = drawLineStyle,\n                            onValueChange = onUpdateDrawLineStyle\n                        )\n                    }\n                    HelperGridParamsSelector(\n                        value = helperGridParams,\n                        onValueChange = onUpdateHelperGridParams,\n                        modifier = Modifier.padding(horizontal = 16.dp)\n                    )\n                    MagnifierEnabledSelector(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(horizontal = 16.dp),\n                        shape = ShapeDefaults.extraLarge,\n                    )\n                }\n            },\n            fabButtons = null,\n            actions = {\n                if (useScaffold) {\n                    secondaryControls()\n                    Spacer(Modifier.weight(1f))\n                }\n            },\n            topAppBar = { closeButton ->\n                EnhancedTopAppBar(\n                    type = EnhancedTopAppBarType.Center,\n                    navigationIcon = closeButton,\n                    actions = {\n                        AnimatedVisibility(\n                            visible = paths.isNotEmpty(),\n                            enter = fadeIn() + scaleIn(),\n                            exit = fadeOut() + scaleOut()\n                        ) {\n                            EnhancedIconButton(\n                                containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                onClick = {\n                                    onGetBitmap(stateBitmap)\n                                    onDismiss()\n                                }\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Done,\n                                    contentDescription = \"Done\"\n                                )\n                            }\n                        }\n                    },\n                    title = {\n                        Text(\n                            text = stringResource(R.string.draw),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n            }\n        ) {\n            val direction = LocalLayoutDirection.current\n            Box(contentAlignment = Alignment.Center) {\n                remember(bitmap) {\n                    derivedStateOf {\n                        bitmap.copy(Bitmap.Config.ARGB_8888, true).asImageBitmap()\n                    }\n                }.value.let { imageBitmap ->\n                    val aspectRatio = imageBitmap.width / imageBitmap.height.toFloat()\n                    BitmapDrawer(\n                        imageBitmap = imageBitmap,\n                        paths = paths,\n                        onRequestFiltering = onRequestFiltering,\n                        strokeWidth = strokeWidth,\n                        brushSoftness = brushSoftness,\n                        drawColor = drawColor.copy(alpha),\n                        onAddPath = addPath,\n                        isEraserOn = isEraserOn,\n                        drawMode = drawMode,\n                        modifier = Modifier\n                            .padding(\n                                start = WindowInsets\n                                    .displayCutout\n                                    .asPaddingValues()\n                                    .calculateStartPadding(direction)\n                            )\n                            .padding(16.dp)\n                            .aspectRatio(aspectRatio, !useScaffold)\n                            .fillMaxSize(),\n                        panEnabled = panEnabled,\n                        onDraw = {\n                            stateBitmap = it\n                        },\n                        drawPathMode = drawPathMode,\n                        backgroundColor = Color.Transparent,\n                        drawLineStyle = drawLineStyle,\n                        helperGridParams = helperGridParams\n                    )\n                }\n            }\n        }\n        var color by rememberSaveable(stateSaver = ColorSaver) {\n            mutableStateOf(Color.Black)\n        }\n        PickColorFromImageSheet(\n            visible = showPickColorSheet,\n            onDismiss = {\n                showPickColorSheet = false\n            },\n            bitmap = stateBitmap,\n            onColorChange = { color = it },\n            color = color\n        )\n\n        if (visible) {\n            DrawLockScreenOrientation()\n        }\n    }\n}"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/components/EraseBackgroundEditOption.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.rounded.Redo\nimport androidx.compose.material.icons.automirrored.rounded.Undo\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.model.pt\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.HelperGridParamsSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.MagnifierEnabledSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.other.BoxAnimatedVisibility\nimport com.t8rin.imagetoolbox.core.ui.widget.other.DrawLockScreenOrientation\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.PtSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.BrushSoftnessSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.DrawPathModeSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.LineWidthSelector\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemover\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.AutoEraseBackgroundCard\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.BitmapEraser\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.OriginalImagePreviewAlphaSelector\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.RecoverModeButton\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.RecoverModeCard\nimport com.t8rin.imagetoolbox.feature.erase_background.presentation.components.TrimImageToggle\nimport kotlinx.coroutines.launch\n\n@Composable\nfun EraseBackgroundEditOption(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    useScaffold: Boolean,\n    bitmap: Bitmap?,\n    onGetBitmap: (Bitmap, Boolean) -> Unit,\n    clearErasing: (Boolean) -> Unit,\n    undo: () -> Unit,\n    redo: () -> Unit,\n    paths: List<UiPathPaint>,\n    lastPaths: List<UiPathPaint>,\n    undonePaths: List<UiPathPaint>,\n    drawPathMode: DrawPathMode,\n    onUpdateDrawPathMode: (DrawPathMode) -> Unit,\n    addPath: (UiPathPaint) -> Unit,\n    autoBackgroundRemover: AutoBackgroundRemover<Bitmap>,\n    helperGridParams: HelperGridParams,\n    onUpdateHelperGridParams: (HelperGridParams) -> Unit,\n) {\n    val scope = rememberCoroutineScope()\n\n    bitmap?.let {\n        var panEnabled by rememberSaveable { mutableStateOf(false) }\n\n        val switch = @Composable {\n            PanModeButton(\n                selected = panEnabled,\n                onClick = {\n                    panEnabled = !panEnabled\n                }\n            )\n        }\n\n        var isRecoveryOn by rememberSaveable { mutableStateOf(false) }\n\n        val settingsState = LocalSettingsState.current\n        var strokeWidth by rememberSaveable(stateSaver = PtSaver) { mutableStateOf(settingsState.defaultDrawLineWidth.pt) }\n        var brushSoftness by rememberSaveable(stateSaver = PtSaver) {\n            mutableStateOf(0.pt)\n        }\n\n        var originalImagePreviewAlpha by rememberSaveable {\n            mutableFloatStateOf(0.2f)\n        }\n\n        var trimImage by rememberSaveable { mutableStateOf(true) }\n\n        val secondaryControls = @Composable {\n            Row(\n                modifier = Modifier\n                    .then(\n                        if (!useScaffold) {\n                            Modifier\n                                .padding(16.dp)\n                                .container(shape = ShapeDefaults.circle)\n                        } else Modifier\n                    )\n            ) {\n                switch()\n                Spacer(Modifier.width(8.dp))\n                EnhancedIconButton(\n                    containerColor = Color.Transparent,\n                    borderColor = MaterialTheme.colorScheme.outlineVariant(\n                        luminance = 0.1f\n                    ),\n                    onClick = undo,\n                    enabled = lastPaths.isNotEmpty() || paths.isNotEmpty()\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.Undo,\n                        contentDescription = \"Undo\"\n                    )\n                }\n                EnhancedIconButton(\n                    containerColor = Color.Transparent,\n                    borderColor = MaterialTheme.colorScheme.outlineVariant(\n                        luminance = 0.1f\n                    ),\n                    onClick = redo,\n                    enabled = undonePaths.isNotEmpty()\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Rounded.Redo,\n                        contentDescription = \"Redo\"\n                    )\n                }\n                RecoverModeButton(\n                    selected = isRecoveryOn,\n                    enabled = !panEnabled,\n                    onClick = { isRecoveryOn = !isRecoveryOn }\n                )\n            }\n        }\n\n        var bitmapState by remember(bitmap, visible) { mutableStateOf(bitmap) }\n        var erasedBitmap by remember(bitmap, visible) { mutableStateOf(bitmap) }\n\n        var loading by remember { mutableStateOf(false) }\n\n        var autoErased by remember { mutableStateOf(false) }\n\n        FullscreenEditOption(\n            canGoBack = paths.isEmpty() && !autoErased,\n            visible = visible,\n            onDismiss = onDismiss,\n            useScaffold = useScaffold,\n            controls = { scaffoldState ->\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    if (!useScaffold) secondaryControls()\n                    Spacer(modifier = Modifier.height(8.dp))\n                    RecoverModeCard(\n                        selected = isRecoveryOn,\n                        enabled = !panEnabled,\n                        onClick = { isRecoveryOn = !isRecoveryOn }\n                    )\n                    AutoEraseBackgroundCard(\n                        onClick = { modelType ->\n                            scope.launch {\n                                scaffoldState?.bottomSheetState?.partialExpand()\n                            }\n                            loading = true\n                            autoBackgroundRemover.removeBackgroundFromImage(\n                                image = erasedBitmap,\n                                modelType = modelType,\n                                onSuccess = {\n                                    loading = false\n                                    bitmapState = it\n                                    clearErasing(false)\n                                    autoErased = true\n                                    AppToastHost.showConfetti()\n                                },\n                                onFailure = {\n                                    loading = false\n                                    AppToastHost.showFailureToast(it)\n                                }\n                            )\n                        },\n                        onReset = {\n                            bitmapState = bitmap\n                            autoErased = true\n                        }\n                    )\n                    OriginalImagePreviewAlphaSelector(\n                        value = originalImagePreviewAlpha,\n                        onValueChange = {\n                            originalImagePreviewAlpha = it\n                        },\n                        modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp)\n                    )\n                    DrawPathModeSelector(\n                        modifier = Modifier.padding(\n                            start = 16.dp,\n                            end = 16.dp,\n                            top = 8.dp\n                        ),\n                        value = drawPathMode,\n                        onValueChange = onUpdateDrawPathMode,\n                        values = remember {\n                            listOf(\n                                DrawPathMode.Free,\n                                DrawPathMode.FloodFill(),\n                                DrawPathMode.Spray(),\n                                DrawPathMode.Line,\n                                DrawPathMode.Lasso,\n                                DrawPathMode.Rect(),\n                                DrawPathMode.Oval\n                            )\n                        },\n                        drawMode = DrawMode.Pen\n                    )\n                    BoxAnimatedVisibility(drawPathMode.canChangeStrokeWidth) {\n                        LineWidthSelector(\n                            modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp),\n                            value = strokeWidth.value,\n                            onValueChange = { strokeWidth = it.pt }\n                        )\n                    }\n                    BrushSoftnessSelector(\n                        modifier = Modifier\n                            .padding(top = 8.dp, end = 16.dp, start = 16.dp),\n                        value = brushSoftness.value,\n                        onValueChange = { brushSoftness = it.pt }\n                    )\n                    TrimImageToggle(\n                        checked = trimImage,\n                        onCheckedChange = { trimImage = it },\n                        modifier = Modifier.padding(\n                            start = 16.dp,\n                            end = 16.dp,\n                            top = 8.dp,\n                        )\n                    )\n                    HelperGridParamsSelector(\n                        value = helperGridParams,\n                        onValueChange = onUpdateHelperGridParams,\n                        modifier = Modifier.padding(\n                            start = 16.dp,\n                            end = 16.dp,\n                            top = 8.dp,\n                        )\n                    )\n                    MagnifierEnabledSelector(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(\n                                start = 16.dp,\n                                end = 16.dp,\n                                top = 8.dp,\n                                bottom = 16.dp\n                            ),\n                        shape = ShapeDefaults.extraLarge\n                    )\n                }\n            },\n            fabButtons = null,\n            actions = {\n                if (useScaffold) {\n                    secondaryControls()\n                    Spacer(Modifier.weight(1f))\n                }\n            },\n            topAppBar = { closeButton ->\n                EnhancedTopAppBar(\n                    type = EnhancedTopAppBarType.Center,\n                    navigationIcon = closeButton,\n                    actions = {\n                        AnimatedVisibility(\n                            visible = paths.isNotEmpty() || autoErased,\n                            enter = fadeIn() + scaleIn(),\n                            exit = fadeOut() + scaleOut()\n                        ) {\n                            EnhancedIconButton(\n                                containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                onClick = {\n                                    scope.launch {\n                                        val trimmed = if (trimImage) {\n                                            autoBackgroundRemover.trimEmptyParts(\n                                                erasedBitmap\n                                            )\n                                        } else {\n                                            erasedBitmap\n                                        }\n\n                                        onGetBitmap(\n                                            trimmed,\n                                            trimmed.width == erasedBitmap.width && trimmed.height == erasedBitmap.height\n                                        )\n                                        clearErasing(false)\n                                    }\n                                    onDismiss()\n                                }\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Done,\n                                    contentDescription = \"Done\"\n                                )\n                            }\n                        }\n                    },\n                    title = {\n                        Text(\n                            text = stringResource(R.string.erase_background),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n            }\n        ) {\n            Box(contentAlignment = Alignment.Center) {\n                AnimatedContent(\n                    targetState = remember(bitmapState) {\n                        derivedStateOf {\n                            bitmapState.copy(Bitmap.Config.ARGB_8888, true).asImageBitmap()\n                        }\n                    }.value,\n                    transitionSpec = { fadeIn() togetherWith fadeOut() }\n                ) { imageBitmap ->\n                    val direction = LocalLayoutDirection.current\n                    val aspectRatio = imageBitmap.width / imageBitmap.height.toFloat()\n                    BitmapEraser(\n                        imageBitmapForShader = bitmap.asImageBitmap(),\n                        imageBitmap = imageBitmap,\n                        paths = paths,\n                        strokeWidth = strokeWidth,\n                        brushSoftness = brushSoftness,\n                        onAddPath = addPath,\n                        isRecoveryOn = isRecoveryOn,\n                        modifier = Modifier\n                            .padding(\n                                start = WindowInsets\n                                    .displayCutout\n                                    .asPaddingValues()\n                                    .calculateStartPadding(direction)\n                            )\n                            .padding(16.dp)\n                            .aspectRatio(aspectRatio, !useScaffold)\n                            .fillMaxSize(),\n                        panEnabled = panEnabled,\n                        drawPathMode = drawPathMode,\n                        originalImagePreviewAlpha = originalImagePreviewAlpha,\n                        onErased = { erasedBitmap = it },\n                        helperGridParams = helperGridParams\n                    )\n                }\n\n                AnimatedVisibility(\n                    visible = loading,\n                    modifier = Modifier.fillMaxSize(),\n                    enter = fadeIn(),\n                    exit = fadeOut()\n                ) {\n                    Box(\n                        contentAlignment = Alignment.Center,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .background(MaterialTheme.colorScheme.scrim.copy(0.5f))\n                    ) {\n                        EnhancedLoadingIndicator()\n                    }\n                }\n            }\n        }\n\n        if (visible) {\n            DrawLockScreenOrientation()\n        }\n    }\n}"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/components/FilterEditOption.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.AutoFixHigh\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.rememberBottomSheetScaffoldState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil3.toBitmap\nimport com.t8rin.imagetoolbox.core.data.utils.toCoil\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.filters.domain.model.TemplateFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterItem\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterReorderSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheet\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Eyedropper\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ProvideFilterPreview\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedFloatingActionButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.tappable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.transparencyChecker\nimport com.t8rin.imagetoolbox.core.ui.widget.saver.ColorSaver\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.OpenColorPickerCard\nimport com.t8rin.imagetoolbox.feature.pick_color.presentation.components.PickColorFromImageSheet\nimport kotlinx.coroutines.launch\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n@Composable\nfun FilterEditOption(\n    addFilterSheetComponent: AddFiltersSheetComponent,\n    filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent,\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    useScaffold: Boolean,\n    bitmap: Bitmap?,\n    onGetBitmap: (Bitmap) -> Unit,\n    onRequestMappingFilters: (List<UiFilter<*>>) -> List<Transformation<Bitmap>>,\n    filterList: List<UiFilter<*>>,\n    updateFilter: (Any, Int) -> Unit,\n    removeAt: (Int) -> Unit,\n    addFilter: (UiFilter<*>) -> Unit,\n    updateOrder: (List<UiFilter<*>>) -> Unit\n) {\n    var stateBitmap by remember(bitmap, visible) { mutableStateOf(if (!visible) null else bitmap) }\n\n    ProvideFilterPreview(stateBitmap)\n\n    bitmap?.let {\n        val scaffoldState = rememberBottomSheetScaffoldState()\n\n        var showFilterSheet by rememberSaveable { mutableStateOf(false) }\n        var showReorderSheet by rememberSaveable { mutableStateOf(false) }\n\n        var showColorPicker by rememberSaveable { mutableStateOf(false) }\n        var tempColor by rememberSaveable(\n            showColorPicker,\n            stateSaver = ColorSaver\n        ) { mutableStateOf(Color.Black) }\n\n        LaunchedEffect(visible) {\n            if (visible && filterList.isEmpty()) {\n                showFilterSheet = true\n            }\n        }\n\n        var showTemplateCreationSheet by rememberSaveable {\n            mutableStateOf(false)\n        }\n\n        FullscreenEditOption(\n            showControls = filterList.isNotEmpty(),\n            canGoBack = stateBitmap == bitmap,\n            visible = visible,\n            modifier = Modifier.heightIn(max = LocalScreenSize.current.height / 1.5f),\n            onDismiss = onDismiss,\n            useScaffold = useScaffold,\n            controls = {\n                Column(\n                    modifier = Modifier.padding(16.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    if (!useScaffold) {\n                        OpenColorPickerCard(\n                            onOpen = {\n                                showColorPicker = true\n                            },\n                            modifier = Modifier\n                                .fillMaxWidth()\n                                .padding(bottom = 16.dp)\n                        )\n                    }\n                    Column(Modifier.container(MaterialTheme.shapes.extraLarge)) {\n                        TitleItem(text = stringResource(R.string.filters))\n                        Column(\n                            horizontalAlignment = Alignment.CenterHorizontally,\n                            verticalArrangement = Arrangement.spacedBy(8.dp),\n                            modifier = Modifier.padding(8.dp)\n                        ) {\n                            filterList.forEachIndexed { index, filter ->\n                                FilterItem(\n                                    filter = filter,\n                                    onFilterChange = { filterChange ->\n                                        updateFilter(\n                                            filterChange,\n                                            index\n                                        )\n                                    },\n                                    onLongPress = {\n                                        showReorderSheet = true\n                                    },\n                                    backgroundColor = MaterialTheme.colorScheme.surface,\n                                    showDragHandle = false,\n                                    onRemove = {\n                                        removeAt(index)\n                                    },\n                                    onCreateTemplate = {\n                                        showTemplateCreationSheet = true\n                                        filterTemplateCreationSheetComponent.setInitialTemplateFilter(\n                                            TemplateFilter(\n                                                name = getString(filter.title),\n                                                filters = listOf(filter)\n                                            )\n                                        )\n                                    }\n                                )\n                            }\n                            EnhancedButton(\n                                containerColor = MaterialTheme.colorScheme.mixedContainer,\n                                onClick = { showFilterSheet = true },\n                                modifier = Modifier.padding(horizontal = 16.dp)\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.AutoFixHigh,\n                                    contentDescription = null\n                                )\n                                Spacer(Modifier.width(8.dp))\n                                Text(stringResource(R.string.add_filter))\n                            }\n                        }\n\n                        FilterTemplateCreationSheet(\n                            component = filterTemplateCreationSheetComponent,\n                            visible = showTemplateCreationSheet,\n                            onDismiss = { showTemplateCreationSheet = false }\n                        )\n                    }\n                }\n            },\n            fabButtons = {\n                EnhancedFloatingActionButton(\n                    onClick = {\n                        showFilterSheet = true\n                    },\n                    containerColor = MaterialTheme.colorScheme.primaryContainer,\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.AutoFixHigh,\n                        contentDescription = stringResource(R.string.add_filter)\n                    )\n                }\n            },\n            scaffoldState = scaffoldState,\n            actions = {\n                if (filterList.isEmpty()) {\n                    Text(\n                        text = stringResource(id = R.string.add_filter),\n                        modifier = Modifier\n                            .padding(horizontal = 16.dp)\n                            .tappable {\n                                showFilterSheet = true\n                            }\n                    )\n                } else {\n                    EnhancedIconButton(\n                        onClick = {\n                            showColorPicker = true\n                        },\n                    ) {\n                        Icon(\n                            imageVector = Icons.Outlined.Eyedropper,\n                            contentDescription = stringResource(R.string.pipette)\n                        )\n                    }\n                }\n            },\n            topAppBar = { closeButton ->\n                EnhancedTopAppBar(\n                    type = EnhancedTopAppBarType.Center,\n                    navigationIcon = closeButton,\n                    actions = {\n                        AnimatedVisibility(\n                            visible = stateBitmap != bitmap && stateBitmap != null,\n                            enter = fadeIn() + scaleIn(),\n                            exit = fadeOut() + scaleOut()\n                        ) {\n                            EnhancedIconButton(\n                                containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                                onClick = {\n                                    stateBitmap?.let(onGetBitmap)\n                                    onDismiss()\n                                }\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Rounded.Done,\n                                    contentDescription = \"Done\"\n                                )\n                            }\n                        }\n                    },\n                    title = {\n                        Text(\n                            text = stringResource(R.string.filter),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n            }\n        ) {\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                val direction = LocalLayoutDirection.current\n                Picture(\n                    model = bitmap,\n                    shape = RectangleShape,\n                    transformations = remember(filterList) {\n                        derivedStateOf {\n                            onRequestMappingFilters(filterList).map { it.toCoil() }\n                        }\n                    }.value,\n                    onSuccess = {\n                        stateBitmap = it.result.image.toBitmap()\n                    },\n                    showTransparencyChecker = false,\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .clipToBounds()\n                        .transparencyChecker()\n                        .clipToBounds()\n                        .zoomable(rememberZoomState())\n                        .padding(\n                            start = WindowInsets\n                                .displayCutout\n                                .asPaddingValues()\n                                .calculateStartPadding(direction)\n                        ),\n                    contentScale = ContentScale.Fit,\n                )\n            }\n        }\n\n        val scope = rememberCoroutineScope()\n\n        AddFiltersSheet(\n            visible = showFilterSheet,\n            onVisibleChange = { showFilterSheet = it },\n            previewBitmap = stateBitmap,\n            onFilterPicked = {\n                scope.launch {\n                    scaffoldState.bottomSheetState.expand()\n                }\n                addFilter(it.newInstance())\n            },\n            onFilterPickedWithParams = {\n                scope.launch {\n                    scaffoldState.bottomSheetState.expand()\n                }\n                addFilter(it)\n            },\n            component = addFilterSheetComponent,\n            filterTemplateCreationSheetComponent = filterTemplateCreationSheetComponent\n        )\n\n        FilterReorderSheet(\n            filterList = filterList,\n            visible = showReorderSheet,\n            onDismiss = {\n                showReorderSheet = false\n            },\n            onReorder = updateOrder\n        )\n\n        PickColorFromImageSheet(\n            visible = showColorPicker,\n            onDismiss = {\n                showColorPicker = false\n            },\n            bitmap = stateBitmap,\n            onColorChange = { tempColor = it },\n            color = tempColor\n        )\n    }\n}"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/components/FullscreenEditOption.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material.icons.rounded.Tune\nimport androidx.compose.material3.BottomAppBar\nimport androidx.compose.material3.BottomSheetScaffold\nimport androidx.compose.material3.BottomSheetScaffoldState\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.rememberBottomSheetScaffoldState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.ProvideContainerDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitBackHandler\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedBottomSheetDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.clearFocusOnTap\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.drawHorizontalStroke\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.onSwipeDown\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.toShape\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withLayoutCorners\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n@Composable\nfun FullscreenEditOption(\n    visible: Boolean,\n    canGoBack: Boolean,\n    onDismiss: () -> Unit,\n    useScaffold: Boolean,\n    modifier: Modifier = Modifier,\n    showControls: Boolean = true,\n    controls: @Composable (BottomSheetScaffoldState?) -> Unit,\n    fabButtons: (@Composable () -> Unit)?,\n    actions: @Composable RowScope.() -> Unit,\n    topAppBar: @Composable (closeButton: @Composable () -> Unit) -> Unit,\n    scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(),\n    content: @Composable () -> Unit\n) {\n    var predictiveBackProgress by remember {\n        mutableFloatStateOf(0f)\n    }\n\n    LaunchedEffect(predictiveBackProgress, visible) {\n        if (!visible && predictiveBackProgress != 0f) {\n            delay(600)\n            predictiveBackProgress = 0f\n        }\n    }\n\n    AnimatedVisibility(\n        visible = visible,\n        modifier = Modifier.fillMaxSize(),\n        enter = fadeIn(tween(600)),\n        exit = fadeOut(tween(600))\n    ) {\n        var showExitDialog by remember(visible) { mutableStateOf(false) }\n        val internalOnDismiss = {\n            if (!canGoBack) showExitDialog = true\n            else onDismiss()\n        }\n        val direction = LocalLayoutDirection.current\n\n        val animatedPredictiveBackProgress by animateFloatAsState(predictiveBackProgress)\n        val scale = (1f - animatedPredictiveBackProgress).coerceAtLeast(0.75f)\n\n\n        Box(\n            Modifier\n                .fillMaxSize()\n                .background(MaterialTheme.colorScheme.scrim.copy(0.5f * scale))\n        )\n\n        Surface(\n            modifier = Modifier\n                .fillMaxSize()\n                .withLayoutCorners { corners ->\n                    graphicsLayer {\n                        scaleX = scale\n                        scaleY = scale\n                        shape = corners.toShape(animatedPredictiveBackProgress)\n                        clip = true\n                    }\n                }\n        ) {\n            Column {\n                if (useScaffold) {\n                    val screenHeight = LocalScreenSize.current.height\n                    val sheetSwipeEnabled =\n                        scaffoldState.bottomSheetState.currentValue == SheetValue.PartiallyExpanded\n                                && !scaffoldState.bottomSheetState.isAnimationRunning\n\n                    BottomSheetScaffold(\n                        topBar = {\n                            topAppBar {\n                                EnhancedIconButton(\n                                    onClick = internalOnDismiss\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Close,\n                                        contentDescription = stringResource(R.string.close)\n                                    )\n                                }\n                            }\n                        },\n                        scaffoldState = scaffoldState,\n                        sheetPeekHeight = 80.dp + WindowInsets.navigationBars.asPaddingValues()\n                            .calculateBottomPadding(),\n                        sheetDragHandle = null,\n                        sheetShape = RectangleShape,\n                        sheetSwipeEnabled = sheetSwipeEnabled,\n                        sheetContent = {\n                            Scaffold(\n                                modifier = modifier\n                                    .heightIn(max = screenHeight * 0.7f)\n                                    .clearFocusOnTap(),\n                                topBar = {\n                                    val scope = rememberCoroutineScope()\n                                    Box(\n                                        modifier = Modifier.onSwipeDown(!sheetSwipeEnabled) {\n                                            scope.launch {\n                                                scaffoldState.bottomSheetState.partialExpand()\n                                            }\n                                        }\n                                    ) {\n                                        BottomAppBar(\n                                            modifier = Modifier.drawHorizontalStroke(true),\n                                            actions = {\n                                                actions()\n                                                if (showControls) {\n                                                    EnhancedIconButton(\n                                                        onClick = {\n                                                            scope.launch {\n                                                                if (scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {\n                                                                    scaffoldState.bottomSheetState.partialExpand()\n                                                                } else {\n                                                                    scaffoldState.bottomSheetState.expand()\n                                                                }\n                                                            }\n                                                        }\n                                                    ) {\n                                                        Icon(\n                                                            imageVector = Icons.Rounded.Tune,\n                                                            contentDescription = stringResource(R.string.properties)\n                                                        )\n                                                    }\n                                                }\n                                            },\n                                            floatingActionButton = {\n                                                Row(\n                                                    horizontalArrangement = Arrangement.spacedBy(\n                                                        8.dp,\n                                                        Alignment.CenterHorizontally\n                                                    ),\n                                                    verticalAlignment = Alignment.CenterVertically\n                                                ) {\n                                                    if (fabButtons != null) {\n                                                        fabButtons()\n                                                    }\n                                                }\n                                            }\n                                        )\n                                    }\n                                }\n                            ) { contentPadding ->\n                                if (showControls) {\n                                    Column(\n                                        modifier = Modifier\n                                            .enhancedVerticalScroll(rememberScrollState())\n                                            .padding(contentPadding),\n                                        horizontalAlignment = Alignment.CenterHorizontally\n                                    ) {\n                                        ProvideContainerDefaults(\n                                            color = EnhancedBottomSheetDefaults.contentContainerColor\n                                        ) {\n                                            controls(scaffoldState)\n                                        }\n                                    }\n                                }\n                            }\n                        },\n                        content = {\n                            Box(Modifier.padding(it)) {\n                                content()\n                            }\n                        }\n                    )\n                } else {\n                    Scaffold(\n                        topBar = {\n                            topAppBar {\n                                EnhancedIconButton(\n                                    onClick = internalOnDismiss\n                                ) {\n                                    Icon(\n                                        imageVector = Icons.Rounded.Close,\n                                        contentDescription = stringResource(R.string.close)\n                                    )\n                                }\n                            }\n                        },\n                        contentWindowInsets = WindowInsets()\n                    ) { contentPadding ->\n                        Row(\n                            verticalAlignment = Alignment.CenterVertically,\n                            modifier = Modifier.padding(contentPadding)\n                        ) {\n                            Box(\n                                Modifier\n                                    .container(\n                                        shape = RectangleShape,\n                                        resultPadding = 0.dp\n                                    )\n                                    .weight(0.8f)\n                                    .fillMaxHeight()\n                                    .clipToBounds()\n                            ) {\n                                content()\n                            }\n\n                            if (showControls) {\n                                Column(\n                                    modifier = Modifier\n                                        .weight(0.7f)\n                                        .clearFocusOnTap()\n                                        .enhancedVerticalScroll(rememberScrollState())\n                                        .then(\n                                            if (fabButtons == null) {\n                                                Modifier.padding(\n                                                    end = WindowInsets.displayCutout\n                                                        .asPaddingValues()\n                                                        .calculateEndPadding(direction)\n                                                )\n                                            } else Modifier\n                                        ),\n                                    horizontalAlignment = Alignment.CenterHorizontally\n                                ) {\n                                    ProvideContainerDefaults(\n                                        color = MaterialTheme.colorScheme.surfaceContainerLowest\n                                    ) {\n                                        controls(null)\n                                    }\n                                }\n                            }\n                            fabButtons?.let {\n                                Column(\n                                    Modifier\n                                        .container(\n                                            shape = RectangleShape,\n                                            resultPadding = 0.dp\n                                        )\n                                        .padding(horizontal = 20.dp)\n                                        .padding(\n                                            end = WindowInsets.displayCutout\n                                                .asPaddingValues()\n                                                .calculateEndPadding(direction)\n                                        )\n                                        .fillMaxHeight()\n                                        .navigationBarsPadding(),\n                                    horizontalAlignment = Alignment.CenterHorizontally,\n                                    verticalArrangement = Arrangement.spacedBy(\n                                        8.dp,\n                                        Alignment.CenterVertically\n                                    )\n                                ) {\n                                    it()\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        if (visible) {\n            if (canGoBack) {\n                PredictiveBackObserver(\n                    onProgress = {\n                        predictiveBackProgress = it / 6f\n                    },\n                    onClean = { isCompleted ->\n                        if (isCompleted) {\n                            internalOnDismiss()\n                            delay(400)\n                        }\n                        predictiveBackProgress = 0f\n                    }\n                )\n            } else {\n                ExitBackHandler(onBack = internalOnDismiss)\n            }\n\n            ExitWithoutSavingDialog(\n                onExit = onDismiss,\n                onDismiss = { showExitDialog = false },\n                visible = showExitDialog\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/components/ToneCurvesEditOption.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation.components\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.systemBars\nimport androidx.compose.foundation.layout.union\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Done\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.rememberBottomSheetScaffoldState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.curves.ImageCurvesEditor\nimport com.t8rin.curves.ImageCurvesEditorState\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShowOriginalButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBar\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedTopAppBarType\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\n\n@Composable\nfun ToneCurvesEditOption(\n    visible: Boolean,\n    onDismiss: () -> Unit,\n    useScaffold: Boolean,\n    bitmap: Bitmap?,\n    onGetBitmap: (Bitmap) -> Unit,\n    editorState: ImageCurvesEditorState,\n    onResetState: () -> Unit\n) {\n    bitmap?.let {\n        val scaffoldState = rememberBottomSheetScaffoldState()\n\n        var showOriginal by remember {\n            mutableStateOf(false)\n        }\n        var imageObtainingTrigger by remember {\n            mutableStateOf(false)\n        }\n\n        var showResetDialog by rememberSaveable { mutableStateOf(false) }\n\n        val actions = @Composable {\n            EnhancedIconButton(\n                onClick = { showResetDialog = true }\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.ImageReset,\n                    contentDescription = stringResource(R.string.reset_image)\n                )\n            }\n            ShowOriginalButton(\n                onStateChange = {\n                    showOriginal = it\n                }\n            )\n        }\n\n        var isDefault by remember(editorState) {\n            mutableStateOf(editorState.isDefault())\n        }\n\n        FullscreenEditOption(\n            showControls = false,\n            canGoBack = isDefault,\n            visible = visible,\n            modifier = Modifier.heightIn(max = LocalScreenSize.current.height / 1.5f),\n            onDismiss = {\n                onDismiss()\n                onResetState()\n            },\n            useScaffold = useScaffold,\n            controls = { },\n            fabButtons = if (useScaffold) {\n                {\n                    Box(\n                        modifier = Modifier\n                            .size(48.dp)\n                            .offset(y = 8.dp),\n                        contentAlignment = Alignment.Center\n                    ) {\n                        TopAppBarEmoji()\n                    }\n                }\n            } else {\n                {\n                    actions()\n                }\n            },\n            scaffoldState = scaffoldState,\n            actions = {\n                actions()\n            },\n            topAppBar = { closeButton ->\n                EnhancedTopAppBar(\n                    type = EnhancedTopAppBarType.Center,\n                    navigationIcon = closeButton,\n                    actions = {\n                        EnhancedIconButton(\n                            containerColor = MaterialTheme.colorScheme.tertiaryContainer,\n                            onClick = {\n                                imageObtainingTrigger = true\n                            },\n                            enabled = !showOriginal\n                        ) {\n                            Icon(\n                                imageVector = Icons.Rounded.Done,\n                                contentDescription = \"Done\"\n                            )\n                        }\n                    },\n                    title = {\n                        Text(\n                            text = stringResource(R.string.tone_curves),\n                            modifier = Modifier.marquee()\n                        )\n                    }\n                )\n            }\n        ) {\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                ImageCurvesEditor(\n                    bitmap = bitmap,\n                    state = editorState,\n                    curvesSelectionText = {\n                        Text(\n                            text = when (it) {\n                                0 -> stringResource(R.string.all)\n                                1 -> stringResource(R.string.color_red)\n                                2 -> stringResource(R.string.color_green)\n                                3 -> stringResource(R.string.color_blue)\n                                else -> \"\"\n                            },\n                            style = MaterialTheme.typography.bodySmall\n                        )\n                    },\n                    placeControlsAtTheEnd = !useScaffold,\n                    imageObtainingTrigger = imageObtainingTrigger,\n                    onImageObtained = {\n                        imageObtainingTrigger = false\n                        onGetBitmap(it)\n                        onResetState()\n                        onDismiss()\n                    },\n                    contentPadding = WindowInsets.systemBars.union(WindowInsets.displayCutout)\n                        .let {\n                            if (!useScaffold) it.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom)\n                            else it.only(WindowInsetsSides.Horizontal)\n                        }\n                        .union(\n                            WindowInsets(\n                                left = 16.dp,\n                                top = 16.dp,\n                                right = 16.dp,\n                                bottom = 16.dp\n                            )\n                        )\n                        .asPaddingValues(),\n                    containerModifier = Modifier.align(Alignment.Center),\n                    showOriginal = showOriginal,\n                    onStateChange = {\n                        isDefault = it.isDefault()\n                    }\n                )\n            }\n        }\n\n        ResetDialog(\n            visible = showResetDialog,\n            onDismiss = { showResetDialog = false },\n            title = stringResource(R.string.reset_curves),\n            text = stringResource(R.string.reset_curves_sub),\n            onReset = onResetState\n        )\n    }\n}\n"
  },
  {
    "path": "feature/single-edit/src/main/java/com/t8rin/imagetoolbox/feature/single_edit/presentation/screenLogic/SingleEditComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.single_edit.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.arkivanov.decompose.childContext\nimport com.arkivanov.essenty.lifecycle.doOnDestroy\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.model.OutlineType\nimport com.t8rin.cropper.model.RectCropShape\nimport com.t8rin.cropper.settings.CropDefaults\nimport com.t8rin.cropper.settings.CropOutlineProperty\nimport com.t8rin.curves.ImageCurvesEditorState\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImagePreviewCreator\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.Metadata\nimport com.t8rin.imagetoolbox.core.domain.image.clearAllAttributes\nimport com.t8rin.imagetoolbox.core.domain.image.clearAttribute\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageData\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.MetadataTag\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.DomainAspectRatio\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.transformation.Transformation\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.update\nimport com.t8rin.imagetoolbox.core.filters.domain.FilterProvider\nimport com.t8rin.imagetoolbox.core.filters.domain.model.Filter\nimport com.t8rin.imagetoolbox.core.filters.presentation.model.UiFilter\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.FilterTemplateCreationSheetComponent\nimport com.t8rin.imagetoolbox.core.filters.presentation.widget.addFilters.AddFiltersSheetComponent\nimport com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.safeAspectRatio\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.savable\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.HelperGridParams\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawLineStyle\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawMode\nimport com.t8rin.imagetoolbox.feature.draw.domain.DrawPathMode\nimport com.t8rin.imagetoolbox.feature.draw.presentation.components.UiPathPaint\nimport com.t8rin.imagetoolbox.feature.erase_background.domain.AutoBackgroundRemover\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.withContext\n\n\nclass SingleEditComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUri: Uri?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    private val imagePreviewCreator: ImagePreviewCreator<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val autoBackgroundRemover: AutoBackgroundRemover<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val filterProvider: FilterProvider<Bitmap>,\n    private val settingsProvider: SettingsProvider,\n    dispatchersHolder: DispatchersHolder,\n    addFiltersSheetComponentFactory: AddFiltersSheetComponent.Factory,\n    filterTemplateCreationSheetComponentFactory: FilterTemplateCreationSheetComponent.Factory,\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUri?.let(::setUri)\n        }\n\n        doOnDestroy {\n            autoBackgroundRemover.cleanup()\n        }\n    }\n\n    val addFiltersSheetComponent: AddFiltersSheetComponent = addFiltersSheetComponentFactory(\n        componentContext = componentContext.childContext(\n            key = \"addFiltersSingle\"\n        )\n    )\n\n    val filterTemplateCreationSheetComponent: FilterTemplateCreationSheetComponent =\n        filterTemplateCreationSheetComponentFactory(\n            componentContext = componentContext.childContext(\n                key = \"filterTemplateCreationSheetComponentSingle\"\n            )\n        )\n\n    private val _originalSize: MutableState<IntegerSize?> = mutableStateOf(null)\n    val originalSize by _originalSize\n\n    private val _erasePaths = mutableStateOf(listOf<UiPathPaint>())\n    val erasePaths: List<UiPathPaint> by _erasePaths\n\n    private val _eraseLastPaths = mutableStateOf(listOf<UiPathPaint>())\n    val eraseLastPaths: List<UiPathPaint> by _eraseLastPaths\n\n    private val _eraseUndonePaths = mutableStateOf(listOf<UiPathPaint>())\n    val eraseUndonePaths: List<UiPathPaint> by _eraseUndonePaths\n\n    private val _drawPaths = mutableStateOf(listOf<UiPathPaint>())\n    val drawPaths: List<UiPathPaint> by _drawPaths\n\n    private val _drawLastPaths = mutableStateOf(listOf<UiPathPaint>())\n    val drawLastPaths: List<UiPathPaint> by _drawLastPaths\n\n    private val _drawUndonePaths = mutableStateOf(listOf<UiPathPaint>())\n    val drawUndonePaths: List<UiPathPaint> by _drawUndonePaths\n\n    private val _filterList =\n        mutableStateOf(listOf<UiFilter<*>>())\n    val filterList by _filterList\n\n    private val _selectedAspectRatio: MutableState<DomainAspectRatio> =\n        mutableStateOf(DomainAspectRatio.Free)\n    val selectedAspectRatio by _selectedAspectRatio\n\n    private val _cropProperties = mutableStateOf(\n        CropDefaults.properties(\n            cropOutlineProperty = CropOutlineProperty(\n                outlineType = OutlineType.Rect,\n                cropOutline = RectCropShape(\n                    id = 0,\n                    title = OutlineType.Rect.name\n                )\n            ),\n            fling = true\n        )\n    )\n    val cropProperties by _cropProperties\n\n    private val _imageCurvesEditorState: MutableState<ImageCurvesEditorState> =\n        mutableStateOf(ImageCurvesEditorState.Default)\n    val imageCurvesEditorState: ImageCurvesEditorState by _imageCurvesEditorState\n\n    private val _exif: MutableState<Metadata?> = mutableStateOf(null)\n    val exif by _exif\n\n    private val _uri: MutableState<Uri> = mutableStateOf(Uri.EMPTY)\n    val uri: Uri by _uri\n\n    private val _internalBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val initialBitmap by _internalBitmap\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _imageInfo: MutableState<ImageInfo> = mutableStateOf(ImageInfo())\n    val imageInfo: ImageInfo by _imageInfo\n\n    private val _showWarning: MutableState<Boolean> = mutableStateOf(false)\n    val showWarning: Boolean by _showWarning\n\n    private val _shouldShowPreview: MutableState<Boolean> = mutableStateOf(true)\n    val shouldShowPreview by _shouldShowPreview\n\n    private val _presetSelected: MutableState<Preset> = mutableStateOf(Preset.None)\n    val presetSelected by _presetSelected\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private val _drawMode: MutableState<DrawMode> = mutableStateOf(DrawMode.Pen)\n    val drawMode: DrawMode by _drawMode\n\n    private val _drawPathMode: MutableState<DrawPathMode> = mutableStateOf(DrawPathMode.Free)\n    val drawPathMode: DrawPathMode by _drawPathMode\n\n    private val _drawLineStyle: MutableState<DrawLineStyle> = mutableStateOf(DrawLineStyle.None)\n    val drawLineStyle: DrawLineStyle by _drawLineStyle\n\n    private val _helperGridParams = fileController.savable(\n        scope = componentScope,\n        initial = HelperGridParams()\n    )\n    val helperGridParams: HelperGridParams by _helperGridParams\n\n    init {\n        componentScope.launch {\n            val settingsState = settingsProvider.getSettingsState()\n            _drawPathMode.update { DrawPathMode.fromOrdinal(settingsState.defaultDrawPathMode) }\n            _imageInfo.update {\n                it.copy(resizeType = settingsState.defaultResizeType)\n            }\n        }\n    }\n\n    private var job: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    private suspend fun checkBitmapAndUpdate(resetPreset: Boolean = false) {\n        if (resetPreset) {\n            _presetSelected.update { Preset.None }\n        }\n        _bitmap.value?.let { bmp ->\n            val preview = updatePreview(bmp)\n            _previewBitmap.update { null }\n            _shouldShowPreview.update { imagePreviewCreator.canShow(preview) }\n            if (shouldShowPreview) _previewBitmap.update { preview }\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmap(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            bitmap?.let { bitmap ->\n                parseSaveResult(\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = imageInfo,\n                            metadata = exif,\n                            originalUri = uri.toString(),\n                            sequenceNumber = null,\n                            data = imageCompressor.compressAndTransform(\n                                image = bitmap,\n                                imageInfo = imageInfo.copy(\n                                    originalUri = uri.toString()\n                                )\n                            ),\n                            presetInfo = presetSelected\n                        ),\n                        keepOriginalMetadata = true,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    ).onSuccess(::registerSave)\n                )\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    private suspend fun updatePreview(\n        bitmap: Bitmap,\n    ): Bitmap? = withContext(defaultDispatcher) {\n        return@withContext imageInfo.run {\n            _showWarning.update {\n                width * height * 4L >= 10_000 * 10_000 * 3L\n            }\n            imagePreviewCreator.createPreview(\n                image = bitmap,\n                imageInfo = this,\n                onGetByteCount = { sizeInBytes ->\n                    _imageInfo.update { it.copy(sizeInBytes = sizeInBytes) }\n                }\n            )\n        }\n    }\n\n    private fun setBitmapInfo(newInfo: ImageInfo) {\n        if (imageInfo != newInfo) {\n            _imageInfo.update { newInfo }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate()\n            }\n        }\n    }\n\n    fun resetValues(newBitmapComes: Boolean = false) {\n        _imageInfo.update {\n            ImageInfo(\n                width = _originalSize.value?.width ?: 0,\n                height = _originalSize.value?.height ?: 0,\n                imageFormat = it.imageFormat,\n                originalUri = uri.toString()\n            )\n        }\n        if (newBitmapComes) {\n            _bitmap.update {\n                _internalBitmap.value\n            }\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate(\n                resetPreset = true\n            )\n        }\n    }\n\n    fun updateBitmapAfterEditing(\n        bitmap: Bitmap?,\n        saveOriginalSize: Boolean = false,\n    ) {\n        componentScope.launch {\n            if (!saveOriginalSize) {\n                val size = bitmap?.let { it.width to it.height }\n                _originalSize.update {\n                    size?.run { IntegerSize(width = first, height = second) }\n                }\n            }\n            _bitmap.update {\n                imageScaler.scaleUntilCanShow(bitmap)\n            }\n            _imageInfo.update {\n                it.copy(\n                    rotationDegrees = 0f\n                )\n            }\n            if (!saveOriginalSize) {\n                _imageInfo.update {\n                    it.copy(\n                        width = bitmap?.width ?: 0,\n                        height = bitmap?.height ?: 0\n                    )\n                }\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(\n                    resetPreset = true\n                )\n            }\n            registerChanges()\n        }\n    }\n\n    fun rotateBitmapLeft() {\n        _imageInfo.update {\n            it.copy(\n                rotationDegrees = it.rotationDegrees - 90f,\n                height = it.width,\n                width = it.height\n            )\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    fun rotateBitmapRight() {\n        _imageInfo.update {\n            it.copy(\n                rotationDegrees = it.rotationDegrees + 90f,\n                height = it.width,\n                width = it.height\n            )\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    fun flipImage() {\n        _imageInfo.update {\n            it.copy(isFlipped = !it.isFlipped)\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    fun updateWidth(width: Int) {\n        if (imageInfo.width != width) {\n            _imageInfo.update {\n                it.copy(width = width)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(\n                    resetPreset = true\n                )\n            }\n            registerChanges()\n        }\n    }\n\n    fun updateHeight(height: Int) {\n        if (imageInfo.height != height) {\n            _imageInfo.update {\n                it.copy(height = height)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(\n                    resetPreset = true\n                )\n            }\n            registerChanges()\n        }\n    }\n\n    fun setQuality(quality: Quality) {\n        if (imageInfo.quality != quality) {\n            _imageInfo.update {\n                it.copy(quality = quality)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate()\n            }\n            registerChanges()\n        }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        if (imageInfo.imageFormat != imageFormat) {\n            _imageInfo.update {\n                it.copy(imageFormat = imageFormat)\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(\n                    resetPreset = _presetSelected.value == Preset.Telegram && imageFormat != ImageFormat.Png.Lossless\n                )\n            }\n            registerChanges()\n        }\n    }\n\n    fun setResizeType(type: ResizeType) {\n        if (imageInfo.resizeType != type) {\n            _imageInfo.update {\n                it.copy(\n                    resizeType = type.withOriginalSizeIfCrop(originalSize)\n                )\n            }\n            debouncedImageCalculation {\n                checkBitmapAndUpdate(\n                    resetPreset = false\n                )\n            }\n            registerChanges()\n        }\n    }\n\n    fun setUri(uri: Uri) {\n        _uri.update { uri }\n        decodeBitmapByUri(uri)\n    }\n\n    private fun decodeBitmapByUri(uri: Uri) {\n        _isImageLoading.update { true }\n        _imageInfo.update {\n            it.copy(originalUri = uri.toString())\n        }\n        imageGetter.getImageAsync(\n            uri = uri.toString(),\n            originalSize = true,\n            onGetImage = ::setImageData,\n            onFailure = {\n                _isImageLoading.update { false }\n            }\n        )\n    }\n\n    private fun setImageData(imageData: ImageData<Bitmap>) {\n        job = componentScope.launch {\n            _isImageLoading.update { true }\n            _exif.update { imageData.metadata }\n            val bitmap = imageData.image\n            val size = bitmap.width to bitmap.height\n            _originalSize.update {\n                size.run { IntegerSize(width = first, height = second) }\n            }\n            _bitmap.update {\n                _internalBitmap.update {\n                    imageScaler.scaleUntilCanShow(bitmap)\n                }\n            }\n            resetValues(true)\n            _imageInfo.update {\n                imageData.imageInfo.copy(\n                    width = size.first,\n                    height = size.second\n                )\n            }\n            checkBitmapAndUpdate(\n                resetPreset = _presetSelected.value == Preset.Telegram && imageData.imageInfo.imageFormat != ImageFormat.Png.Lossless\n            )\n            _isImageLoading.update { false }\n        }\n    }\n\n    fun shareBitmap() {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            bitmap?.let { image ->\n                shareProvider.shareImage(\n                    image = image,\n                    imageInfo = imageInfo.copy(originalUri = uri.toString()),\n                    onComplete = AppToastHost::showConfetti\n                )\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n            bitmap?.let { image ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo.copy(originalUri = uri.toString())\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.update { false }\n        }\n    }\n\n    fun canShow(): Boolean = bitmap?.let { imagePreviewCreator.canShow(it) } == true\n\n    fun setPreset(preset: Preset) {\n        componentScope.launch {\n            if (preset is Preset.AspectRatio && preset.ratio != 1f) {\n                _imageInfo.update { it.copy(rotationDegrees = 0f) }\n            }\n            setBitmapInfo(\n                imageTransformer.applyPresetBy(\n                    image = bitmap,\n                    preset = preset,\n                    currentInfo = imageInfo.copy(\n                        originalUri = uri.toString()\n                    )\n                )\n            )\n            _presetSelected.update { preset }\n            registerChanges()\n        }\n    }\n\n    fun clearExif() {\n        updateExif(_exif.value?.clearAllAttributes())\n    }\n\n    private fun updateExif(metadata: Metadata?) {\n        _exif.update { metadata }\n        registerChanges()\n    }\n\n    fun removeExifTag(tag: MetadataTag) {\n        updateExif(_exif.value?.clearAttribute(tag))\n    }\n\n    fun updateExifByTag(\n        tag: MetadataTag,\n        value: String,\n    ) {\n        updateExif(_exif.value?.setAttribute(tag, value))\n    }\n\n    fun setCropAspectRatio(\n        domainAspectRatio: DomainAspectRatio,\n        aspectRatio: AspectRatio,\n    ) {\n        _cropProperties.update { properties ->\n            properties.copy(\n                aspectRatio = aspectRatio.takeIf {\n                    domainAspectRatio != DomainAspectRatio.Original\n                } ?: _bitmap.value?.let {\n                    AspectRatio(it.safeAspectRatio)\n                } ?: aspectRatio,\n                fixedAspectRatio = domainAspectRatio != DomainAspectRatio.Free\n            )\n        }\n        _selectedAspectRatio.update { domainAspectRatio }\n    }\n\n    fun setCropMask(cropOutlineProperty: CropOutlineProperty) {\n        _cropProperties.value =\n            _cropProperties.value.copy(cropOutlineProperty = cropOutlineProperty)\n    }\n\n    suspend fun loadImage(uri: Uri): Bitmap? = imageGetter.getImage(data = uri)\n\n    fun getBackgroundRemover(): AutoBackgroundRemover<Bitmap> = autoBackgroundRemover\n\n    fun <T : Any> updateFilter(\n        value: T,\n        index: Int\n    ) {\n        val list = _filterList.value.toMutableList()\n        runCatching {\n            list[index] = list[index].copy(value)\n            _filterList.update { list }\n        }.onFailure {\n            AppToastHost.showFailureToast(it)\n            list[index] = list[index].newInstance()\n            _filterList.update { list }\n        }\n    }\n\n    fun updateOrder(value: List<UiFilter<*>>) {\n        _filterList.update { value }\n    }\n\n    fun addFilter(filter: UiFilter<*>) {\n        _filterList.update {\n            it + filter\n        }\n    }\n\n    fun removeFilterAtIndex(index: Int) {\n        _filterList.update {\n            it.toMutableList().apply {\n                removeAt(index)\n            }\n        }\n    }\n\n    fun clearFilterList() {\n        _filterList.update { listOf() }\n    }\n\n    fun clearDrawing(canUndo: Boolean = false) {\n        componentScope.launch {\n            delay(500L)\n            _drawLastPaths.update { if (canUndo) drawPaths else listOf() }\n            _drawPaths.update { listOf() }\n            _drawUndonePaths.update { listOf() }\n            _drawMode.update { DrawMode.Pen }\n            _drawPathMode.update { DrawPathMode.Free }\n        }\n    }\n\n    fun undoDraw() {\n        if (drawPaths.isEmpty() && drawLastPaths.isNotEmpty()) {\n            _drawPaths.update { drawLastPaths }\n            _drawLastPaths.update { listOf() }\n            return\n        }\n        if (drawPaths.isEmpty()) return\n\n        val lastPath = drawPaths.last()\n\n        _drawPaths.update { it - lastPath }\n        _drawUndonePaths.update { it + lastPath }\n    }\n\n    fun redoDraw() {\n        if (drawUndonePaths.isEmpty()) return\n\n        val lastPath = drawUndonePaths.last()\n        _drawPaths.update { it + lastPath }\n        _drawUndonePaths.update { it - lastPath }\n    }\n\n    fun addPathToDrawList(pathPaint: UiPathPaint) {\n        _drawPaths.update { it + pathPaint }\n        _drawUndonePaths.update { listOf() }\n    }\n\n    fun clearErasing(canUndo: Boolean = false) {\n        componentScope.launch {\n            delay(250L)\n            _eraseLastPaths.update { if (canUndo) erasePaths else listOf() }\n            _erasePaths.update { listOf() }\n            _eraseUndonePaths.update { listOf() }\n            _drawPathMode.update { DrawPathMode.Free }\n        }\n    }\n\n    fun undoErase() {\n        if (erasePaths.isEmpty() && eraseLastPaths.isNotEmpty()) {\n            _erasePaths.update { eraseLastPaths }\n            _eraseLastPaths.update { listOf() }\n            return\n        }\n        if (erasePaths.isEmpty()) return\n\n        val lastPath = erasePaths.last()\n\n        _erasePaths.update { it - lastPath }\n        _eraseUndonePaths.update { it + lastPath }\n    }\n\n    fun redoErase() {\n        if (eraseUndonePaths.isEmpty()) return\n\n        val lastPath = eraseUndonePaths.last()\n        _erasePaths.update { it + lastPath }\n        _eraseUndonePaths.update { it - lastPath }\n    }\n\n    fun addPathToEraseList(pathPaint: UiPathPaint) {\n        _erasePaths.update { it + pathPaint }\n        _eraseUndonePaths.update { listOf() }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.update { false }\n    }\n\n    fun setImageScaleMode(imageScaleMode: ImageScaleMode) {\n        _imageInfo.update {\n            it.copy(imageScaleMode = imageScaleMode)\n        }\n        debouncedImageCalculation {\n            checkBitmapAndUpdate()\n        }\n        registerChanges()\n    }\n\n    suspend fun filter(\n        bitmap: Bitmap,\n        filters: List<Filter<*>>,\n    ): Bitmap? = imageTransformer.transform(\n        image = bitmap,\n        transformations = mapFilters(filters)\n    )\n\n    fun mapFilters(\n        filters: List<Filter<*>>,\n    ): List<Transformation<Bitmap>> = filters.map { filterProvider.filterToTransformation(it) }\n\n    fun updateDrawMode(drawMode: DrawMode) {\n        _drawMode.update { drawMode }\n    }\n\n    fun updateDrawPathMode(drawPathMode: DrawPathMode) {\n        _drawPathMode.update { drawPathMode }\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageInfo.imageFormat\n\n    fun resetImageCurvesEditorState() {\n        _imageCurvesEditorState.update { ImageCurvesEditorState.Default }\n    }\n\n    fun updateDrawLineStyle(style: DrawLineStyle) {\n        _drawLineStyle.update { style }\n    }\n\n    fun updateHelperGridParams(params: HelperGridParams) {\n        _helperGridParams.update { params }\n    }\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUri: Uri?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): SingleEditComponent\n    }\n}\n"
  },
  {
    "path": "feature/svg-maker/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/svg-maker/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.svg_maker\"\n\ndependencies {\n    implementation(libs.toolbox.svg)\n}"
  },
  {
    "path": "feature/svg-maker/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/svg-maker/src/main/java/com/t8rin/imagetoolbox/feature/svg_maker/data/AndroidSvgManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.feature.svg_maker.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport com.t8rin.image.toolbox.svg.ImageTracerAndroid\nimport com.t8rin.image.toolbox.svg.ImageTracerAndroid.SvgListener\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.saving.RandomStringGenerator\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.feature.svg_maker.domain.SvgManager\nimport com.t8rin.imagetoolbox.feature.svg_maker.domain.SvgParams\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport javax.inject.Inject\n\n\ninternal class AndroidSvgManager @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val randomStringGenerator: RandomStringGenerator,\n    private val imageGetter: ImageGetter<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, SvgManager {\n\n    override suspend fun convertToSvg(\n        imageUris: List<String>,\n        params: SvgParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: suspend (originalUri: String, data: ByteArray) -> Unit\n    ) = withContext(defaultDispatcher) {\n        imageUris.forEach { uri ->\n            runSuspendCatching {\n                val folder = File(context.cacheDir, \"svg\").apply { mkdirs() }\n                val file = File(folder, \"${randomStringGenerator.generate(10)}.svg\")\n\n                withContext(ioDispatcher) {\n                    file.bufferedWriter().use { writer ->\n                        ImageTracerAndroid.imageToSVG(\n                            imageGetter.getImage(\n                                data = uri,\n                                size = if (params.isImageSampled) {\n                                    IntegerSize(1000, 1000)\n                                } else null\n                            )!!,\n                            params.toOptions(),\n                            null,\n                            SvgTracer {\n                                writer.write(it)\n                            }\n                        )\n                    }\n                }\n\n                onProgress(uri, file.readBytes())\n            }.onFailure(onFailure)\n        }\n    }\n\n    private fun SvgTracer(\n        onProgress: (String) -> Unit\n    ): SvgListener = object : SvgListener {\n        override fun onProgress(\n            part: String?\n        ): SvgListener = apply { onProgress(part ?: \"\") }\n\n        override fun onProgress(\n            part: Double\n        ): SvgListener = apply { onProgress(part.toString()) }\n    }\n\n    private fun SvgParams.toOptions(): HashMap<String, Float> = HashMap<String, Float>().apply {\n        put(\"numberofcolors\", colorsCount.toFloat())\n        put(\"colorquantcycles\", quantizationCyclesCount.toFloat())\n        put(\"colorsampling\", if (isPaletteSampled) 1f else 0f)\n        put(\"blurradius\", blurRadius.toFloat())\n        put(\"blurdelta\", blurDelta.toFloat())\n        put(\"pathomit\", pathOmit.toFloat())\n        put(\"ltres\", linesThreshold)\n        put(\"qtres\", quadraticThreshold)\n        put(\"roundcoords\", coordinatesRoundingAmount.toFloat())\n        put(\"mincolorratio\", minColorRatio)\n        put(\"scale\", svgPathsScale)\n    }\n\n}"
  },
  {
    "path": "feature/svg-maker/src/main/java/com/t8rin/imagetoolbox/feature/svg_maker/di/SvgMakerModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.svg_maker.di\n\nimport com.t8rin.imagetoolbox.feature.svg_maker.data.AndroidSvgManager\nimport com.t8rin.imagetoolbox.feature.svg_maker.domain.SvgManager\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface SvgMakerModule {\n\n    @Singleton\n    @Binds\n    fun provideSvgManager(\n        manager: AndroidSvgManager\n    ): SvgManager\n\n}"
  },
  {
    "path": "feature/svg-maker/src/main/java/com/t8rin/imagetoolbox/feature/svg_maker/domain/SvgManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.svg_maker.domain\n\ninterface SvgManager {\n\n    suspend fun convertToSvg(\n        imageUris: List<String>,\n        params: SvgParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: suspend (originalUri: String, data: ByteArray) -> Unit\n    )\n\n}"
  },
  {
    "path": "feature/svg-maker/src/main/java/com/t8rin/imagetoolbox/feature/svg_maker/domain/SvgParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.svg_maker.domain\n\ndata class SvgParams(\n    val colorsCount: Int,\n    val isPaletteSampled: Boolean,\n    val quantizationCyclesCount: Int,\n    val blurRadius: Int,\n    val blurDelta: Int,\n    val pathOmit: Int,\n    val linesThreshold: Float,\n    val quadraticThreshold: Float,\n    val minColorRatio: Float,\n    val coordinatesRoundingAmount: Int,\n    val svgPathsScale: Float, // 0.01f, 100f\n    val isImageSampled: Boolean\n) {\n    companion object {\n        val Default by lazy {\n            SvgParams(\n                colorsCount = 16,\n                isPaletteSampled = true,\n                quantizationCyclesCount = 3,\n                blurRadius = 0,\n                blurDelta = 20,\n                pathOmit = 8,\n                linesThreshold = 1f,\n                quadraticThreshold = 1f,\n                minColorRatio = 0.02f,\n                coordinatesRoundingAmount = 1,\n                svgPathsScale = 1f,\n                isImageSampled = true\n            )\n        }\n        val Detailed by lazy {\n            Default.copy(\n                pathOmit = 0,\n                linesThreshold = 0.5f,\n                quadraticThreshold = 0.5f,\n                coordinatesRoundingAmount = 3,\n                colorsCount = 64,\n                quantizationCyclesCount = 1\n            )\n        }\n        val Grayscale by lazy {\n            Default.copy(\n                isPaletteSampled = false,\n                quantizationCyclesCount = 1,\n                colorsCount = 7\n            )\n        }\n\n        val presets by lazy {\n            listOf(Default, Detailed, Grayscale)\n        }\n    }\n}"
  },
  {
    "path": "feature/svg-maker/src/main/java/com/t8rin/imagetoolbox/feature/svg_maker/presentation/SvgMakerContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.svg_maker.presentation\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.image.urisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.svg_maker.domain.SvgParams\nimport com.t8rin.imagetoolbox.feature.svg_maker.presentation.components.SvgParamsSelector\nimport com.t8rin.imagetoolbox.feature.svg_maker.presentation.screenLogic.SvgMakerComponent\n\n\n@Composable\nfun SvgMakerContent(\n    component: SvgMakerComponent\n) {\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val imagePicker = rememberImagePicker(onSuccess = component::setUris)\n\n    AutoFilePicker(\n        onAutoPick = imagePicker::pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    val addImagesImagePicker = rememberImagePicker(onSuccess = component::addUris)\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showResetDialog by rememberSaveable { mutableStateOf(false) }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            Text(\n                text = stringResource(R.string.images_to_svg),\n                modifier = Modifier.marquee()\n            )\n        },\n        topAppBarPersistentActions = {\n            if (isPortrait) {\n                TopAppBarEmoji()\n            }\n        },\n        onGoBack = onBack,\n        actions = {\n            ShareButton(\n                onShare = component::performSharing,\n                enabled = !component.isSaving && component.uris.isNotEmpty()\n            )\n            EnhancedIconButton(\n                enabled = component.params != SvgParams.Default,\n                onClick = { showResetDialog = true }\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.ImageReset,\n                    contentDescription = stringResource(R.string.reset_image)\n                )\n            }\n        },\n        imagePreview = {\n            UrisPreview(\n                modifier = Modifier.urisPreview(),\n                uris = component.uris,\n                isPortrait = true,\n                onRemoveUri = component::removeUri,\n                onAddUris = addImagesImagePicker::pickImage\n            )\n        },\n        showImagePreviewAsStickyHeader = false,\n        noDataControls = {\n            ImageNotPickedWidget(onPickImage = imagePicker::pickImage)\n        },\n        controls = {\n            SvgParamsSelector(\n                value = component.params,\n                onValueChange = component::updateParams\n            )\n        },\n        buttons = { actions ->\n            val save: (oneTimeSaveLocationUri: String?) -> Unit = {\n                component.save(\n                    oneTimeSaveLocationUri = it\n                )\n            }\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isEmpty(),\n                onSecondaryButtonClick = imagePicker::pickImage,\n                isPrimaryButtonVisible = component.uris.isNotEmpty(),\n                onPrimaryButtonClick = {\n                    save(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = save\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        canShowScreenData = component.uris.isNotEmpty()\n    )\n\n    ResetDialog(\n        visible = showResetDialog,\n        onDismiss = { showResetDialog = false },\n        title = stringResource(R.string.reset_properties),\n        text = stringResource(R.string.reset_properties_sub),\n        onReset = {\n            component.updateParams(SvgParams.Default)\n        }\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n}"
  },
  {
    "path": "feature/svg-maker/src/main/java/com/t8rin/imagetoolbox/feature/svg_maker/presentation/components/SvgParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.svg_maker.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Calculate\nimport androidx.compose.material.icons.outlined.ChangeHistory\nimport androidx.compose.material.icons.outlined.ColorLens\nimport androidx.compose.material.icons.outlined.FormatColorFill\nimport androidx.compose.material.icons.outlined.LinearScale\nimport androidx.compose.material.icons.outlined.RepeatOne\nimport androidx.compose.material.icons.outlined.Upcoming\nimport androidx.compose.material.icons.rounded.BlurCircular\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.Eyedropper\nimport com.t8rin.imagetoolbox.core.resources.icons.FreeDraw\nimport com.t8rin.imagetoolbox.core.resources.icons.Line\nimport com.t8rin.imagetoolbox.core.resources.icons.PhotoSizeSelectSmall\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedFlingBehavior\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.feature.svg_maker.domain.SvgParams\nimport kotlin.math.pow\nimport kotlin.math.roundToInt\n\n@Composable\nfun SvgParamsSelector(\n    value: SvgParams,\n    onValueChange: (SvgParams) -> Unit\n) {\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Column(\n            modifier = Modifier\n                .container(shape = ShapeDefaults.extraLarge),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Spacer(Modifier.height(8.dp))\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                Text(\n                    text = stringResource(R.string.presets),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.Medium\n                )\n            }\n            Spacer(Modifier.height(12.dp))\n\n            Box(\n                contentAlignment = Alignment.Center,\n                modifier = Modifier.padding(bottom = 8.dp)\n            ) {\n                val listState = rememberLazyListState()\n\n                LazyRow(\n                    state = listState,\n                    modifier = Modifier\n                        .fadingEdges(listState)\n                        .padding(vertical = 1.dp),\n                    horizontalArrangement = Arrangement.spacedBy(\n                        8.dp, Alignment.CenterHorizontally\n                    ),\n                    contentPadding = PaddingValues(horizontal = 8.dp),\n                    flingBehavior = enhancedFlingBehavior()\n                ) {\n                    items(SvgParams.presets) {\n                        val selected = value == it\n                        EnhancedChip(\n                            selected = selected,\n                            onClick = { onValueChange(it) },\n                            selectedColor = MaterialTheme.colorScheme.primary,\n                            shape = MaterialTheme.shapes.medium\n                        ) {\n                            AutoSizeText(it.name)\n                        }\n                    }\n                }\n            }\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.downscale_image),\n            subtitle = stringResource(id = R.string.downscale_image_sub),\n            checked = value.isImageSampled,\n            onClick = {\n                onValueChange(\n                    value.copy(isImageSampled = it)\n                )\n            },\n            startIcon = Icons.Outlined.PhotoSizeSelectSmall,\n            modifier = Modifier.fillMaxWidth(),\n            shape = ShapeDefaults.extraLarge\n        )\n        AnimatedVisibility(\n            visible = !value.isImageSampled\n        ) {\n            Box(\n                modifier = Modifier\n                    .padding(top = 8.dp)\n                    .fillMaxWidth()\n                    .container(\n                        shape = ShapeDefaults.large,\n                        borderColor = MaterialTheme.colorScheme.onErrorContainer.copy(\n                            0.4f\n                        ),\n                        color = MaterialTheme.colorScheme.errorContainer.copy(\n                            alpha = 0.7f\n                        )\n                    ),\n                contentAlignment = Alignment.Center\n            ) {\n                Text(\n                    text = stringResource(R.string.svg_warning),\n                    fontSize = 12.sp,\n                    modifier = Modifier.padding(8.dp),\n                    textAlign = TextAlign.Center,\n                    fontWeight = FontWeight.SemiBold,\n                    lineHeight = 14.sp,\n                    color = MaterialTheme.colorScheme.onErrorContainer.copy(alpha = 0.5f)\n                )\n            }\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.colorsCount,\n            title = stringResource(R.string.max_colors_count),\n            icon = Icons.Outlined.ColorLens,\n            valueRange = 2f..64f,\n            steps = 61,\n            internalStateTransformation = {\n                it.roundToInt()\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        colorsCount = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.minColorRatio,\n            title = stringResource(R.string.min_color_ratio),\n            icon = Icons.Outlined.Eyedropper,\n            valueRange = 0f..0.1f,\n            internalStateTransformation = {\n                it.roundTo(3)\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        minColorRatio = it\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.quantizationCyclesCount,\n            icon = Icons.Outlined.RepeatOne,\n            title = stringResource(id = R.string.repeat_count),\n            valueRange = 1f..10f,\n            steps = 8,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        quantizationCyclesCount = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.use_sampled_palette),\n            subtitle = stringResource(id = R.string.use_sampled_palette_sub),\n            checked = value.isPaletteSampled,\n            onClick = {\n                onValueChange(\n                    value.copy(isPaletteSampled = it)\n                )\n            },\n            startIcon = Icons.Outlined.FormatColorFill,\n            modifier = Modifier.fillMaxWidth(),\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.svgPathsScale,\n            icon = Icons.Outlined.LinearScale,\n            title = stringResource(R.string.path_scale),\n            valueRange = 0.01f..100f,\n            internalStateTransformation = {\n                it.roundToTwoDigits()\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        svgPathsScale = it\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.blurRadius,\n            title = stringResource(R.string.blur_radius),\n            icon = Icons.Rounded.BlurCircular,\n            internalStateTransformation = {\n                it.roundToInt()\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        blurRadius = it.roundToInt()\n                    )\n                )\n            },\n            containerColor = Color.Unspecified,\n            valueRange = 0f..5f,\n            steps = 4,\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.blurDelta,\n            icon = Icons.Outlined.ChangeHistory,\n            title = stringResource(id = R.string.blur_size),\n            valueRange = 0f..255f,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        blurDelta = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.pathOmit,\n            icon = Icons.Outlined.Upcoming,\n            title = stringResource(id = R.string.path_omit),\n            valueRange = 0f..64f,\n            steps = 63,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        pathOmit = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.linesThreshold,\n            icon = Icons.Rounded.Line,\n            title = stringResource(R.string.lines_threshold),\n            valueRange = 0f..10f,\n            internalStateTransformation = {\n                it.roundToTwoDigits()\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        linesThreshold = it\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.quadraticThreshold,\n            icon = Icons.Rounded.FreeDraw,\n            title = stringResource(R.string.quadratic_threshold),\n            valueRange = 0f..10f,\n            internalStateTransformation = {\n                it.roundToTwoDigits()\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        quadraticThreshold = it\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.coordinatesRoundingAmount,\n            icon = Icons.Outlined.Calculate,\n            title = stringResource(R.string.coordinates_rounding_tolerance),\n            valueRange = 0f..8f,\n            steps = 7,\n            internalStateTransformation = {\n                it.roundToInt()\n            },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        coordinatesRoundingAmount = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n    }\n}\n\nprivate fun Float.roundTo(\n    digits: Int? = 2\n) = digits?.let {\n    (this * 10f.pow(digits)).roundToInt() / (10f.pow(digits))\n} ?: this\n\nprivate val SvgParams.name: String\n    @Composable\n    get() = when (this) {\n        SvgParams.Default -> stringResource(R.string.defaultt)\n        SvgParams.Detailed -> stringResource(R.string.detailed)\n        SvgParams.Grayscale -> stringResource(R.string.gray_scale)\n        else -> \"\"\n    }"
  },
  {
    "path": "feature/svg-maker/src/main/java/com/t8rin/imagetoolbox/feature/svg_maker/presentation/screenLogic/SvgMakerComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.imagetoolbox.feature.svg_maker.presentation.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.FileSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.svg_maker.domain.SvgManager\nimport com.t8rin.imagetoolbox.feature.svg_maker.domain.SvgParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass SvgMakerComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    private val svgManager: SvgManager,\n    private val shareProvider: ShareProvider,\n    private val fileController: FileController,\n    private val filenameCreator: FilenameCreator,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n        }\n    }\n\n    private val _uris = mutableStateOf<List<Uri>>(emptyList())\n    val uris by _uris\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _params = mutableStateOf(SvgParams.Default)\n    val params by _params\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun save(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            val results = mutableListOf<SaveResult>()\n\n            _isSaving.value = true\n            _done.update { 0 }\n            _left.value = uris.size\n\n            svgManager.convertToSvg(\n                imageUris = uris.map { it.toString() },\n                params = params,\n                onFailure = {\n                    results.add(\n                        SaveResult.Error.Exception(it)\n                    )\n                }\n            ) { uri, svgBytes ->\n                results.add(\n                    fileController.save(\n                        saveTarget = SvgSaveTarget(uri, svgBytes),\n                        keepOriginalMetadata = true,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    )\n                )\n                _done.update { it + 1 }\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n\n            _isSaving.value = false\n            parseSaveResults(results.onSuccess(::registerSave))\n        }\n    }\n\n    fun performSharing() {\n        savingJob = trackProgress {\n            _done.update { 0 }\n            _left.update { uris.size }\n\n            _isSaving.value = true\n            val results = mutableListOf<String?>()\n\n            svgManager.convertToSvg(\n                imageUris = uris.map { it.toString() },\n                params = params,\n                onFailure = AppToastHost::showFailureToast\n            ) { uri, jxlBytes ->\n                results.add(\n                    shareProvider.cacheByteArray(\n                        byteArray = jxlBytes,\n                        filename = filename(uri)\n                    )\n                )\n                _done.update { it + 1 }\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n\n            shareProvider.shareUris(results.filterNotNull())\n\n            _isSaving.value = false\n            AppToastHost.showConfetti()\n        }\n    }\n\n    private fun filename(\n        uri: String\n    ): String = filenameCreator.constructImageFilename(\n        ImageSaveTarget(\n            imageInfo = ImageInfo(\n                originalUri = uri\n            ),\n            originalUri = uri,\n            sequenceNumber = done + 1,\n            metadata = null,\n            data = ByteArray(0),\n            extension = \"svg\"\n        ),\n        forceNotAddSizeInFilename = true\n    )\n\n    private fun SvgSaveTarget(\n        uri: String,\n        svgBytes: ByteArray\n    ): SaveTarget = FileSaveTarget(\n        originalUri = uri,\n        filename = filename(uri),\n        data = svgBytes,\n        mimeType = MimeType.Svg,\n        extension = \"svg\"\n    )\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun setUris(newUris: List<Uri>) {\n        _uris.update { newUris.distinct() }\n    }\n\n    fun removeUri(uri: Uri) {\n        _uris.update { it - uri }\n        registerChanges()\n    }\n\n    fun addUris(list: List<Uri>) {\n        setUris(uris + list)\n        registerChanges()\n    }\n\n    fun updateParams(newParams: SvgParams) {\n        _params.update { newParams }\n        registerChanges()\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n        ): SvgMakerComponent\n    }\n\n}"
  },
  {
    "path": "feature/wallpapers-export/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/wallpapers-export/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.wallpapers_export\""
  },
  {
    "path": "feature/wallpapers-export/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/data/AndroidWallpapersProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.data\n\nimport android.Manifest\nimport android.annotation.SuppressLint\nimport android.app.WallpaperManager\nimport android.app.WallpaperManager.FLAG_LOCK\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.BitmapFactory\nimport android.graphics.drawable.Drawable\nimport android.os.Build\nimport android.os.Environment\nimport androidx.core.graphics.drawable.toBitmap\nimport androidx.core.graphics.drawable.toDrawable\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.hasPermissionAllowed\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.WallpapersProvider\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.Permission\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.Wallpaper\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.WallpapersResult\nimport com.t8rin.logger.makeLog\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidWallpapersProvider @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : WallpapersProvider, DispatchersHolder by dispatchersHolder {\n\n    private val wallpaperManager = WallpaperManager.getInstance(context)\n\n    override suspend fun getWallpapers(): WallpapersResult = withContext(defaultDispatcher) {\n        val missingPermissions = mutableListOf<Permission>()\n\n        if (!context.hasPermissionAllowed(Manifest.permission.READ_MEDIA_IMAGES) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n            missingPermissions.add(Permission.ReadMediaImages)\n        }\n\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {\n            missingPermissions.add(Permission.ManageExternalStorage)\n        }\n\n        if (missingPermissions.isNotEmpty()) {\n            return@withContext WallpapersResult.Failed.NoPermissions(missingPermissions)\n        }\n\n        val wallpapers = loadWallpapers()\n\n        return@withContext WallpapersResult.Success(\n            wallpapers.mapIndexed { index, drawable ->\n                val imageUri = drawable?.let {\n                    shareProvider.cacheImage(\n                        image = drawable.toBitmap(),\n                        imageInfo = ImageInfo(\n                            width = drawable.intrinsicWidth,\n                            height = drawable.intrinsicHeight,\n                            imageFormat = ImageFormat.Png.Lossless\n                        )\n                    )\n                }\n\n                Wallpaper(\n                    imageUri = imageUri,\n                    nameRes = nameByIndex(index),\n                    resolution = drawable?.let {\n                        IntegerSize(\n                            width = it.intrinsicWidth,\n                            height = it.intrinsicHeight\n                        )\n                    } ?: IntegerSize.Zero\n                )\n            }\n        )\n    }\n\n    @SuppressLint(\"MissingPermission\")\n    private fun loadWallpapers(): List<Drawable?> {\n        val home = safe { wallpaperManager.drawable }\n        val builtIn = safe { wallpaperManager.getBuiltInDrawable(30000, 30000, false, 0.5f, 0.5f) }\n        val lock = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n            safe {\n                wallpaperManager.getWallpaperFile(FLAG_LOCK)?.use {\n                    BitmapFactory.decodeFileDescriptor(it.fileDescriptor)\n                        .toDrawable(context.resources)\n                }\n            } ?: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {\n                safe {\n                    wallpaperManager.getDrawable(FLAG_LOCK)\n                } ?: safe {\n                    wallpaperManager.getBuiltInDrawable(FLAG_LOCK)\n                }\n            } else {\n                safe { wallpaperManager.getBuiltInDrawable(FLAG_LOCK) }\n            }\n        } else {\n            null\n        }\n\n        return listOf(home, lock, builtIn)\n    }\n\n    private inline fun <T> safe(action: () -> T): T? = runCatching { action() }\n        .onFailure { it.makeLog(\"AndroidWallpapersProvider\") }.getOrNull()\n\n    private fun nameByIndex(index: Int): Int = when (index) {\n        0 -> R.string.home_screen\n        1 -> R.string.lock_screen\n        else -> R.string.built_in\n    }\n\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/di/WallpapersExportModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.di\n\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.data.AndroidWallpapersProvider\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.WallpapersProvider\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface WallpapersExportModule {\n\n    @Binds\n    @Singleton\n    fun provider(\n        impl: AndroidWallpapersProvider\n    ): WallpapersProvider\n\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/domain/WallpapersProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.domain\n\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.WallpapersResult\n\ninterface WallpapersProvider {\n    suspend fun getWallpapers(): WallpapersResult\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/domain/model/Permission.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model\n\nsealed interface Permission {\n    data object ManageExternalStorage : Permission\n    data object ReadMediaImages : Permission\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/domain/model/Wallpaper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model\n\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ndata class Wallpaper(\n    val imageUri: String?,\n    val nameRes: Int,\n    val resolution: IntegerSize\n)"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/domain/model/WallpapersResult.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model\n\nsealed interface WallpapersResult {\n    data object Loading : WallpapersResult\n\n    data class Success(\n        val wallpapers: List<Wallpaper>\n    ) : WallpapersResult\n\n    sealed interface Failed : WallpapersResult {\n        data class NoPermissions(val missingPermissions: List<Permission>) : Failed\n    }\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/presentation/WallpapersExportContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.presentation\n\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isInstalledFromPlayStore\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.rememberCurrentLifecycleEvent\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.other.FeatureNotAvailableContent\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.core.utils.appContext\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.WallpapersResult\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.components.WallpapersActionButtons\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.components.WallpapersControls\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.components.WallpapersPreview\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent\n\n@Composable\nfun WallpapersExportContent(\n    component: WallpapersExportComponent\n) {\n    if (appContext.isInstalledFromPlayStore()) {\n        FeatureNotAvailableContent(\n            title = {\n                Text(\n                    text = stringResource(R.string.wallpapers_export),\n                    modifier = Modifier.marquee()\n                )\n            },\n            onGoBack = component.onGoBack\n        )\n        return\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n    val lifecycleEvent = rememberCurrentLifecycleEvent()\n\n    LaunchedEffect(lifecycleEvent) {\n        component.loadWallpapers()\n    }\n\n    AutoContentBasedColors(component.wallpapers.firstOrNull()?.imageUri)\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = true,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.wallpapers_export),\n                input = component.wallpapers.takeIf { it.isNotEmpty() },\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = component.onGoBack,\n        actions = {\n            ShareButton(\n                enabled = component.selectedImages.isNotEmpty(),\n                onShare = component::performSharing,\n                onCopy = if (component.wallpapers.size == 1) {\n                    { component.cacheImages { it.firstOrNull()?.let(Clipboard::copy) } }\n                } else null\n            )\n        },\n        topAppBarPersistentActions = {\n            if (isPortrait) {\n                TopAppBarEmoji()\n            }\n        },\n        imagePreview = {\n            WallpapersPreview(component)\n        },\n        controls = {\n            WallpapersControls(component)\n        },\n        buttons = { actions ->\n            WallpapersActionButtons(\n                component = component,\n                actions = actions\n            )\n        },\n        placeImagePreview = component.wallpapersState is WallpapersResult.Success,\n        showImagePreviewAsStickyHeader = false,\n        canShowScreenData = true\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving,\n        canCancel = component.isSaving\n    )\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/presentation/components/WallpapersActionButtons.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.components\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Refresh\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageEdit\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.WallpapersResult\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent\n\n@Composable\ninternal fun WallpapersActionButtons(\n    component: WallpapersExportComponent,\n    actions: @Composable RowScope.() -> Unit\n) {\n    if (component.wallpapersState is WallpapersResult.Loading) return\n    val isPortrait by isPortraitOrientationAsState()\n\n    val saveBitmap: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var showFolderSelectionDialog by rememberSaveable {\n        mutableStateOf(false)\n    }\n    var editSheetData by remember {\n        mutableStateOf(listOf<Uri>())\n    }\n    val noData = component.wallpapers.isEmpty()\n    val canRefresh = if (noData) true else component.selectedImages.isNotEmpty()\n    BottomButtonsBlock(\n        isNoData = noData,\n        isPrimaryButtonVisible = !noData,\n        isPrimaryButtonEnabled = component.selectedImages.isNotEmpty(),\n        isSecondaryButtonVisible = canRefresh,\n        secondaryButtonIcon = if (noData) Icons.Rounded.Refresh else Icons.Outlined.ImageEdit,\n        secondaryButtonText = if (noData) stringResource(R.string.refresh) else stringResource(R.string.edit),\n        showNullDataButtonAsContainer = true,\n        isScreenHaveNoDataContent = true,\n        onSecondaryButtonClick = {\n            if (canRefresh && noData) {\n                component.loadWallpapers()\n            } else {\n                component.cacheImages {\n                    editSheetData = it\n                }\n            }\n        },\n        onPrimaryButtonClick = {\n            saveBitmap(null)\n        },\n        onPrimaryButtonLongClick = {\n            showFolderSelectionDialog = true\n        },\n        actions = {\n            if (isPortrait) actions()\n        }\n    )\n    OneTimeSaveLocationSelectionDialog(\n        visible = showFolderSelectionDialog,\n        onDismiss = { showFolderSelectionDialog = false },\n        onSaveRequest = saveBitmap,\n        formatForFilenameSelection = component.getFormatForFilenameSelection()\n    )\n\n    ProcessImagesPreferenceSheet(\n        uris = editSheetData,\n        visible = editSheetData.isNotEmpty(),\n        onDismiss = {\n            editSheetData = emptyList()\n        },\n        onNavigate = component.onNavigate\n    )\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/presentation/components/WallpapersControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.components\n\nimport android.Manifest\nimport android.os.Build\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.ArrowCircleRight\nimport androidx.compose.material.icons.rounded.ImageSearch\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.utils.tryAll\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.FolderOpened\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.appSettingsIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.manageAllFilesIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.manageAppAllFilesIntent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.requestPermissions\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity\nimport com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.Permission\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.WallpapersResult\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent\n\n@Composable\nfun WallpapersControls(component: WallpapersExportComponent) {\n    val isPortrait by isPortraitOrientationAsState()\n\n    AnimatedContent(\n        targetState = component.wallpapersState,\n        contentKey = { it::class.simpleName },\n        modifier = Modifier.fillMaxWidth()\n    ) { state ->\n        when (state) {\n            is WallpapersResult.Success -> {\n                Column {\n                    if (isPortrait) {\n                        Spacer(Modifier.height(16.dp))\n                    }\n                    QualitySelector(\n                        imageFormat = component.imageFormat,\n                        quality = component.quality,\n                        onQualityChange = component::setQuality\n                    )\n                    if (component.imageFormat.canChangeCompressionValue) {\n                        Spacer(Modifier.height(8.dp))\n                    }\n                    ImageFormatSelector(\n                        value = component.imageFormat,\n                        onValueChange = component::setImageFormat,\n                        quality = component.quality,\n                    )\n                }\n            }\n\n            is WallpapersResult.Failed.NoPermissions -> {\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(4.dp)\n                ) {\n                    if (isPortrait) {\n                        Spacer(Modifier.height(12.dp))\n                    }\n\n                    state.missingPermissions.forEachIndexed { index, permission ->\n                        PermissionItem(\n                            permission = permission,\n                            shape = ShapeDefaults.byIndex(\n                                index = index,\n                                size = state.missingPermissions.size\n                            )\n                        )\n                    }\n                }\n            }\n\n            is WallpapersResult.Loading -> {\n                val screenHeight = LocalScreenSize.current.height\n                Box(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(vertical = screenHeight * 0.3f),\n                    contentAlignment = Alignment.Center\n                ) {\n                    EnhancedLoadingIndicator()\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun PermissionItem(\n    permission: Permission,\n    shape: Shape\n) {\n    val launcher = rememberLauncherForActivityResult(\n        contract = ActivityResultContracts.StartActivityForResult(),\n        onResult = {}\n    )\n    val context = LocalComponentActivity.current\n\n    PreferenceItem(\n        title = permission.title,\n        subtitle = permission.subtitle,\n        modifier = Modifier.fillMaxWidth(),\n        onClick = {\n            when (permission) {\n                Permission.ManageExternalStorage -> {\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {\n                        tryAll(\n                            { launcher.launch(context.manageAppAllFilesIntent()) },\n                            { launcher.launch(manageAllFilesIntent()) },\n                            { launcher.launch(context.appSettingsIntent()) }\n                        )\n                    }\n                }\n\n                Permission.ReadMediaImages -> {\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n                        context.requestPermissions(listOf(Manifest.permission.READ_MEDIA_IMAGES))\n                    }\n                }\n            }\n        },\n        shape = shape,\n        containerColor = MaterialTheme.colorScheme.errorContainer,\n        endIcon = Icons.Rounded.ArrowCircleRight,\n        startIcon = permission.icon\n    )\n}\n\nprivate val Permission.icon: ImageVector\n    get() = when (this) {\n        Permission.ManageExternalStorage -> Icons.Rounded.FolderOpened\n        Permission.ReadMediaImages -> Icons.Rounded.ImageSearch\n    }\n\nprivate val Permission.subtitle: String\n    @Composable\n    get() = when (this) {\n        Permission.ManageExternalStorage -> stringResource(R.string.allow_access_to_all_files_for_wp)\n        Permission.ReadMediaImages -> stringResource(R.string.allow_read_media_images_for_wp)\n    }\n\nprivate val Permission.title: String\n    get() = when (this) {\n        Permission.ManageExternalStorage -> \"MANAGE_EXTERNAL_STORAGE\"\n        Permission.ReadMediaImages -> \"READ_MEDIA_IMAGES\"\n    }"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/presentation/components/WallpapersPreview.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.CheckCircle\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport coil3.compose.AsyncImage\nimport com.t8rin.imagetoolbox.core.resources.icons.BrokenImageAlt\nimport com.t8rin.imagetoolbox.core.ui.theme.White\nimport com.t8rin.imagetoolbox.core.ui.theme.mixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.onMixedContainer\nimport com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.MediaCheckBox\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.Wallpaper\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent\n\n@Composable\ninternal fun WallpapersPreview(component: WallpapersExportComponent) {\n    val wallpapers = component.wallpapers\n    val isPortrait by isPortraitOrientationAsState()\n\n    AnimatedVisibility(\n        visible = wallpapers.isNotEmpty(),\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        Row(\n            horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally),\n            verticalAlignment = Alignment.CenterVertically,\n            modifier = Modifier\n                .then(\n                    if (isPortrait) Modifier.padding(top = 20.dp)\n                    else Modifier\n                )\n                .fillMaxWidth()\n                .height(IntrinsicSize.Max)\n        ) {\n            wallpapers.forEachIndexed { index, wallpaper ->\n                val isSelected by remember(index, component.selectedImages) {\n                    derivedStateOf {\n                        index in component.selectedImages\n                    }\n                }\n\n                WallpaperItem(\n                    wallpaper = wallpaper,\n                    onClick = { component.toggleSelection(index) },\n                    isSelected = isSelected,\n                    shape = ShapeDefaults.byIndex(\n                        index = index,\n                        size = wallpapers.size,\n                        vertical = false\n                    )\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun RowScope.WallpaperItem(\n    wallpaper: Wallpaper,\n    onClick: () -> Unit,\n    isSelected: Boolean,\n    shape: Shape\n) {\n    Box(\n        modifier = Modifier\n            .weight(1f)\n            .container(\n                shape = shape,\n                resultPadding = 0.dp\n            )\n    ) {\n        Column(\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            if (wallpaper.imageUri.isNullOrBlank()) {\n                Box(\n                    modifier = Modifier\n                        .weight(1f)\n                        .fillMaxWidth()\n                        .background(MaterialTheme.colorScheme.errorContainer),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Icon(\n                        imageVector = Icons.Rounded.BrokenImageAlt,\n                        contentDescription = null,\n                        tint = MaterialTheme.colorScheme.onErrorContainer,\n                        modifier = Modifier\n                            .fillMaxWidth(0.5f)\n                            .padding(vertical = 16.dp)\n                    )\n                }\n            } else {\n                Box(\n                    modifier = Modifier\n                        .weight(1f)\n                        .fillMaxWidth()\n                ) {\n                    val padding by animateDpAsState(\n                        if (isSelected) 8.dp else 0.dp\n                    )\n                    val borderColor = takeColorFromScheme {\n                        if (isSelected) primary else Color.Transparent\n                    }\n                    AsyncImage(\n                        model = wallpaper.imageUri,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .fillMaxSize()\n                            .padding(padding)\n                            .border(\n                                width = 2.dp,\n                                color = borderColor,\n                                shape = ShapeDefaults.small\n                            )\n                            .clip(ShapeDefaults.small)\n                            .hapticsClickable(onClick = onClick),\n                        filterQuality = FilterQuality.None,\n                        contentScale = ContentScale.Crop\n                    )\n\n                    Box(\n                        modifier = Modifier\n                            .fillMaxWidth()\n                            .padding(4.dp)\n                    ) {\n                        MediaCheckBox(\n                            isChecked = isSelected,\n                            uncheckedColor = White.copy(0.8f),\n                            checkedColor = MaterialTheme.colorScheme.primary,\n                            checkedIcon = Icons.Filled.CheckCircle,\n                            modifier = Modifier\n                                .clip(ShapeDefaults.circle)\n                                .background(\n                                    animateColorAsState(\n                                        if (isSelected) MaterialTheme.colorScheme.surfaceContainer\n                                        else Color.Transparent\n                                    ).value\n                                )\n                        )\n                    }\n                }\n            }\n            Spacer(Modifier.height(4.dp))\n            AutoSizeText(\n                key = { wallpaper.imageUri },\n                text = stringResource(wallpaper.nameRes),\n                textAlign = TextAlign.Center,\n                color = MaterialTheme.colorScheme.onMixedContainer,\n                modifier = Modifier\n                    .padding(horizontal = 4.dp)\n                    .container(\n                        shape = ShapeDefaults.circle,\n                        color = MaterialTheme.colorScheme.mixedContainer\n                    )\n                    .padding(horizontal = 4.dp, vertical = 2.dp),\n                style = TextStyle(fontSize = 12.sp, lineHeight = 13.sp)\n            )\n            Spacer(Modifier.height(4.dp))\n            if (!wallpaper.imageUri.isNullOrBlank()) {\n                AutoSizeText(\n                    key = { wallpaper.imageUri },\n                    text = \"${wallpaper.resolution.width}x${wallpaper.resolution.height}\",\n                    textAlign = TextAlign.Center,\n                    color = MaterialTheme.colorScheme.onSecondaryContainer,\n                    modifier = Modifier\n                        .padding(horizontal = 4.dp)\n                        .container(\n                            shape = ShapeDefaults.circle,\n                            color = MaterialTheme.colorScheme.secondaryContainer\n                        )\n                        .padding(horizontal = 4.dp, vertical = 2.dp),\n                    style = TextStyle(fontSize = 11.sp, lineHeight = 12.sp)\n                )\n                Spacer(Modifier.height(4.dp))\n            }\n            Spacer(Modifier.height(4.dp))\n        }\n    }\n}"
  },
  {
    "path": "feature/wallpapers-export/src/main/java/com/t8rin/imagetoolbox/feature/wallpapers_export/presentation/screenLogic/WallpapersExportComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.toggle\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.WallpapersProvider\nimport com.t8rin.imagetoolbox.feature.wallpapers_export.domain.model.WallpapersResult\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass WallpapersExportComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val wallpapersProvider: WallpapersProvider,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    private val _imageFormat = mutableStateOf<ImageFormat>(ImageFormat.Png.Lossless)\n    val imageFormat by _imageFormat\n\n    private val _quality = mutableStateOf<Quality>(Quality.Base())\n    val quality by _quality\n\n    private val _wallpapersState: MutableState<WallpapersResult> =\n        mutableStateOf(WallpapersResult.Loading)\n    val wallpapersState: WallpapersResult by _wallpapersState\n\n    private var switchToLoading = true\n\n    val wallpapers get() = (wallpapersState as? WallpapersResult.Success)?.wallpapers.orEmpty()\n\n    private val _selectedImages: MutableState<List<Int>> = mutableStateOf(emptyList())\n    val selectedImages: List<Int> by _selectedImages\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    private var wallpapersJob: Job? by smartJob()\n\n    fun loadWallpapers() {\n        wallpapersJob = componentScope.launch {\n            if (switchToLoading) _wallpapersState.value = WallpapersResult.Loading\n\n            _wallpapersState.value = wallpapersProvider.getWallpapers().also { result ->\n                val success = result is WallpapersResult.Success\n                if (!success) {\n                    _selectedImages.update { emptyList() }\n                }\n                if (switchToLoading && success) {\n                    _selectedImages.update {\n                        result.wallpapers.mapIndexedNotNull { index, wallpaper ->\n                            index.takeIf { wallpaper.imageUri != null }\n                        }\n                    }\n                }\n                switchToLoading = !success\n            }\n        }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.update { true }\n\n            val results = mutableListOf<SaveResult>()\n            val uris = wallpapers.mapIndexedNotNull { index, wallpaper ->\n                wallpaper.imageUri?.takeIf { index in selectedImages }\n            }\n\n            _done.value = 0\n            _left.value = uris.size\n\n            uris.forEach { url ->\n                imageGetter.getImage(data = url)?.let { bitmap ->\n                    fileController.save(\n                        saveTarget = ImageSaveTarget(\n                            imageInfo = ImageInfo(\n                                width = bitmap.width,\n                                height = bitmap.height,\n                                imageFormat = imageFormat,\n                                quality = quality\n                            ),\n                            originalUri = \"_\",\n                            sequenceNumber = null,\n                            data = imageCompressor.compress(\n                                image = bitmap,\n                                imageFormat = imageFormat,\n                                quality = quality\n                            )\n                        ),\n                        keepOriginalMetadata = false,\n                        oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                    )\n                }?.let(results::add) ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n                _done.value++\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.update { false }\n        }\n    }\n\n    fun performSharing() {\n        cacheImages { uris ->\n            componentScope.launch {\n                shareProvider.shareUris(uris.map { it.toString() })\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n\n            val uris = wallpapers.mapIndexedNotNull { index, wallpaper ->\n                wallpaper.imageUri?.takeIf { index in selectedImages }\n            }\n\n            _done.value = 0\n            _left.value = uris.size\n\n            onComplete(\n                uris.mapNotNull {\n                    val image = imageGetter.getImage(data = it) ?: return@mapNotNull null\n\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = ImageInfo(\n                            width = image.width,\n                            height = image.height,\n                            imageFormat = imageFormat,\n                            quality = quality\n                        )\n                    )?.toUri().also {\n                        _done.value++\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n                }\n            )\n            _isSaving.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat = imageFormat\n\n    fun toggleSelection(position: Int) {\n        _selectedImages.update { it.toggle(position) }\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n    }\n\n    fun setQuality(quality: Quality) {\n        _quality.update { quality }\n    }\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): WallpapersExportComponent\n    }\n}"
  },
  {
    "path": "feature/watermarking/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/watermarking/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.watermarking\"\n\ndependencies {\n    implementation(projects.feature.compare)\n    implementation(libs.toolbox.androidwm)\n}"
  },
  {
    "path": "feature/watermarking/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/data/AndroidWatermarkApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnnecessaryVariable\")\n\npackage com.t8rin.imagetoolbox.feature.watermarking.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.Paint\nimport android.graphics.PorterDuffXfermode\nimport android.os.Build\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.applyCanvas\nimport coil3.transform.RoundedCornersTransformation\nimport com.t8rin.imagetoolbox.core.data.image.utils.drawBitmap\nimport com.t8rin.imagetoolbox.core.data.image.utils.toAndroidBlendMode\nimport com.t8rin.imagetoolbox.core.data.image.utils.toPorterDuffMode\nimport com.t8rin.imagetoolbox.core.data.utils.asDomain\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageTransformer\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.utils.toTypeface\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.DigitalParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.HiddenWatermark\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.TextParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkApplier\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkingType\nimport com.watermark.androidwm.WatermarkBuilder\nimport com.watermark.androidwm.WatermarkDetector\nimport com.watermark.androidwm.bean.WatermarkImage\nimport com.watermark.androidwm.bean.WatermarkText\nimport com.watermark.androidwm.listener.BuildFinishListener\nimport com.watermark.androidwm.listener.DetectFinishListener\nimport com.watermark.androidwm.task.DetectionReturnValue\nimport com.watermark.androidwm.utils.BitmapUtils\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.InternalCoroutinesApi\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.suspendCancellableCoroutine\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.coroutines.resume\nimport kotlin.math.roundToInt\n\ninternal class AndroidWatermarkApplier @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val imageTransformer: ImageTransformer<Bitmap>,\n    dispatchersHolder: DispatchersHolder,\n) : DispatchersHolder by dispatchersHolder, WatermarkApplier<Bitmap> {\n\n    override suspend fun applyWatermark(\n        image: Bitmap,\n        originalSize: Boolean,\n        params: WatermarkParams\n    ): Bitmap? = withContext(defaultDispatcher) {\n        when (val type = params.watermarkingType) {\n            is WatermarkingType.Text -> {\n                WatermarkBuilder\n                    .create(context, image, !originalSize)\n                    .loadWatermarkText(\n                        WatermarkText(type.text)\n                            .setPositionX(params.positionX.toDouble())\n                            .setPositionY(params.positionY.toDouble())\n                            .setRotation(params.rotation.toDouble())\n                            .setTextAlpha(\n                                (params.alpha * 255).roundToInt()\n                            )\n                            .setTextSize(\n                                type.params.size.toDouble()\n                            )\n                            .setBackgroundColor(type.params.backgroundColor)\n                            .setTextColor(type.params.color)\n                            .apply {\n                                type.params.font.toTypeface()?.let(::setTextTypeface)\n                            }\n                            .setTextStyle(\n                                Paint.Style.FILL\n                            )\n                    )\n                    .setTileMode(params.isRepeated)\n                    .apply {\n                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                            setBlendMode(\n                                params.overlayMode.toAndroidBlendMode()\n                            )\n                        } else {\n                            setPorterDuffMode(\n                                params.overlayMode.toPorterDuffMode()\n                            )\n                        }\n                    }\n                    .generateImage(type.digitalParams)\n            }\n\n            is WatermarkingType.Image -> {\n                imageGetter.getImage(\n                    data = type.imageData,\n                    size = IntegerSize(\n                        (image.width * type.size).toInt(),\n                        (image.height * type.size).toInt()\n                    )\n                )?.let { watermarkSource ->\n                    WatermarkBuilder\n                        .create(context, image, !originalSize)\n                        .loadWatermarkImage(\n                            WatermarkImage(watermarkSource)\n                                .setPositionX(params.positionX.toDouble())\n                                .setPositionY(params.positionY.toDouble())\n                                .setRotation(params.rotation.toDouble())\n                                .setImageAlpha(\n                                    (params.alpha * 255).roundToInt()\n                                )\n                                .setSize(type.size.toDouble())\n                        )\n                        .setTileMode(params.isRepeated)\n                        .apply {\n                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                                setBlendMode(\n                                    params.overlayMode.toAndroidBlendMode()\n                                )\n                            } else {\n                                setPorterDuffMode(\n                                    params.overlayMode.toPorterDuffMode()\n                                )\n                            }\n                        }\n                        .generateImage(type.digitalParams)\n                }\n            }\n\n            is WatermarkingType.Stamp.Text -> {\n                drawStamp(\n                    image = image,\n                    alpha = params.alpha,\n                    overlayMode = params.overlayMode,\n                    position = type.position,\n                    params = type.params,\n                    text = type.text,\n                    padding = type.padding\n                )\n            }\n\n            is WatermarkingType.Stamp.Time -> {\n                drawStamp(\n                    image = image,\n                    alpha = params.alpha,\n                    overlayMode = params.overlayMode,\n                    position = type.position,\n                    params = type.params,\n                    text = timestamp(type.format),\n                    padding = type.padding\n                )\n            }\n        }\n    }\n\n    @OptIn(InternalCoroutinesApi::class)\n    override suspend fun checkHiddenWatermark(\n        image: Bitmap\n    ): HiddenWatermark? = runSuspendCatching {\n        suspendCancellableCoroutine { continuation ->\n            WatermarkDetector\n                .create(image, true)\n                .detect(\n                    object : DetectFinishListener {\n                        override fun onSuccess(\n                            returnValue: DetectionReturnValue\n                        ) = continuation.resume(\n                            returnValue.watermarkBitmap\n                                ?.let(HiddenWatermark::Image)\n                                ?: returnValue.watermarkString?.takeIf { it.isNotEmpty() }\n                                    ?.let(HiddenWatermark::Text)\n                        )\n\n                        override fun onFailure(message: String?) = continuation.resume(null)\n                    }\n                )\n        }\n    }.getOrNull()\n\n    @OptIn(InternalCoroutinesApi::class)\n    private suspend fun WatermarkBuilder.generateImage(\n        params: DigitalParams\n    ): Bitmap? = runSuspendCatching {\n        if (params.isInvisible) {\n            suspendCancellableCoroutine { continuation ->\n                setInvisibleWMListener(\n                    params.isLSB,\n                    object : BuildFinishListener<Bitmap> {\n                        override fun onSuccess(image: Bitmap) = continuation.resume(image)\n                        override fun onFailure(reason: String) = continuation.resume(null)\n                    }\n                )\n            }\n        } else {\n            watermark?.outputImage\n        }\n    }.getOrNull()\n\n    private suspend fun drawStamp(\n        image: Bitmap,\n        alpha: Float,\n        overlayMode: BlendingMode,\n        position: Position,\n        padding: Float,\n        params: TextParams,\n        text: String,\n    ): Bitmap = coroutineScope {\n        image.copy(Bitmap.Config.ARGB_8888, true).applyCanvas {\n            val watermark = WatermarkText(text)\n                .setTextAlpha(\n                    (alpha * 255).roundToInt()\n                )\n                .setTextSize(\n                    params.size.toDouble()\n                )\n                .setBackgroundColor(params.backgroundColor)\n                .setTextColor(params.color)\n                .apply {\n                    params.font.toTypeface()?.let(::setTextTypeface)\n                }\n                .setTextStyle(\n                    Paint.Style.FILL\n                )\n\n            val verticalPadding = padding - (6f * padding / 20f)\n            val horizontalPadding = padding\n\n            val processedText = BitmapUtils.textAsBitmap(context, watermark, image)\n            val scaled = imageScaler.scaleImage(\n                image = processedText,\n                width = (processedText.width - 2 * horizontalPadding).roundToInt(),\n                height = (processedText.height - 2 * verticalPadding).roundToInt(),\n                resizeType = ResizeType.Flexible\n            )\n            val textBitmap = if (params.backgroundColor != Color.Transparent.toArgb()) {\n                imageTransformer.transform(\n                    image = scaled,\n                    transformations = listOf(\n                        RoundedCornersTransformation(12f).asDomain()\n                    )\n                ) ?: scaled\n            } else {\n                scaled\n            }\n\n            drawBitmap(\n                bitmap = textBitmap,\n                position = position,\n                paint = Paint().apply {\n                    if (Build.VERSION.SDK_INT >= 29) {\n                        blendMode = overlayMode.toAndroidBlendMode()\n                    } else {\n                        xfermode = PorterDuffXfermode(overlayMode.toPorterDuffMode())\n                    }\n                },\n                verticalPadding = verticalPadding,\n                horizontalPadding = horizontalPadding\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/di/WatermarkingModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.watermarking.data.AndroidWatermarkApplier\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkApplier\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface WatermarkingModule {\n\n    @Singleton\n    @Binds\n    fun provideWatermarkApplier(\n        applier: AndroidWatermarkApplier\n    ): WatermarkApplier<Bitmap>\n\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/domain/HiddenWatermark.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.domain\n\nsealed interface HiddenWatermark {\n    data class Image(val image: Any) : HiddenWatermark\n    data class Text(val text: String) : HiddenWatermark\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/domain/WatermarkApplier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.domain\n\ninterface WatermarkApplier<I> {\n\n    suspend fun applyWatermark(\n        image: I,\n        originalSize: Boolean,\n        params: WatermarkParams\n    ): I?\n\n    suspend fun checkHiddenWatermark(\n        image: I\n    ): HiddenWatermark?\n\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/domain/WatermarkParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.BlendingMode\nimport com.t8rin.imagetoolbox.core.domain.model.Position\nimport com.t8rin.imagetoolbox.core.settings.domain.model.FontType\n\ndata class WatermarkParams(\n    val positionX: Float,\n    val positionY: Float,\n    val rotation: Int,\n    val alpha: Float,\n    val isRepeated: Boolean,\n    val overlayMode: BlendingMode,\n    val watermarkingType: WatermarkingType\n) {\n    companion object {\n        val Default by lazy {\n            WatermarkParams(\n                positionX = 0f,\n                positionY = 0f,\n                rotation = 45,\n                alpha = 0.5f,\n                isRepeated = true,\n                overlayMode = BlendingMode.SrcOver,\n                watermarkingType = WatermarkingType.Text.Default\n            )\n        }\n    }\n}\n\nsealed interface WatermarkingType {\n    data class Text(\n        val params: TextParams,\n        val text: String,\n        val digitalParams: DigitalParams\n    ) : WatermarkingType {\n        companion object {\n            val Default by lazy {\n                Text(\n                    params = TextParams.Default,\n                    text = \"Watermark\",\n                    digitalParams = DigitalParams.Default\n                )\n            }\n        }\n    }\n\n    data class Image(\n        val imageData: Any,\n        val size: Float,\n        val digitalParams: DigitalParams\n    ) : WatermarkingType {\n        companion object {\n            val Default by lazy {\n                Image(\n                    size = 0.1f,\n                    imageData = \"file:///android_asset/svg/emotions/aasparkles.svg\",\n                    digitalParams = DigitalParams.Default\n                )\n            }\n        }\n    }\n\n    sealed interface Stamp : WatermarkingType {\n        val position: Position\n        val padding: Float\n        val params: TextParams\n\n        data class Text(\n            override val position: Position,\n            override val padding: Float,\n            override val params: TextParams,\n            val text: String,\n        ) : Stamp {\n            companion object {\n                val Default by lazy {\n                    Text(\n                        params = TextParams.Default.copy(size = 0.2f),\n                        padding = 20f,\n                        position = Position.BottomRight,\n                        text = \"Stamp\"\n                    )\n                }\n            }\n        }\n\n        data class Time(\n            override val position: Position,\n            override val padding: Float,\n            override val params: TextParams,\n            val format: String,\n        ) : Stamp {\n            companion object {\n                val Default by lazy {\n                    Time(\n                        params = TextParams.Default.copy(size = 0.2f),\n                        padding = 20f,\n                        position = Position.BottomRight,\n                        format = \"dd/MM/yyyy HH:mm\"\n                    )\n                }\n            }\n        }\n    }\n\n    companion object {\n        val entries by lazy {\n            listOf(\n                Text.Default,\n                Image.Default,\n                Stamp.Text.Default,\n                Stamp.Time.Default\n            )\n        }\n    }\n}\n\nfun WatermarkingType.Stamp.copy(\n    position: Position = this.position,\n    padding: Float = this.padding,\n    params: TextParams = this.params,\n): WatermarkingType.Stamp = when (this) {\n    is WatermarkingType.Stamp.Text -> {\n        copy(\n            position = position,\n            padding = padding,\n            params = params,\n            text = this.text\n        )\n    }\n\n    is WatermarkingType.Stamp.Time -> {\n        copy(\n            position = position,\n            padding = padding,\n            params = params,\n            format = this.format\n        )\n    }\n}\n\ndata class TextParams(\n    val color: Int,\n    val size: Float,\n    val font: FontType?,\n    val backgroundColor: Int,\n) {\n    companion object {\n        val Default by lazy {\n            TextParams(\n                color = -16777216,\n                size = 0.1f,\n                font = null,\n                backgroundColor = 0,\n            )\n        }\n    }\n}\n\ndata class DigitalParams(\n    val isInvisible: Boolean,\n    val isLSB: Boolean\n) {\n    companion object {\n        val Default by lazy {\n            DigitalParams(\n                isInvisible = false,\n                isLSB = true\n            )\n        }\n    }\n}\n\nfun WatermarkingType.isStamp() = this is WatermarkingType.Stamp\n\nfun WatermarkingType.digitalParams(): DigitalParams? = when (this) {\n    is WatermarkingType.Image -> digitalParams\n    is WatermarkingType.Text -> digitalParams\n    else -> null\n}\n\nfun WatermarkParams.copy(\n    digitalParams: DigitalParams? = this.watermarkingType.digitalParams()\n): WatermarkParams = when (watermarkingType) {\n    is WatermarkingType.Image -> copy(\n        watermarkingType = watermarkingType.copy(\n            digitalParams = digitalParams ?: watermarkingType.digitalParams\n        )\n    )\n\n    is WatermarkingType.Text -> copy(\n        watermarkingType = watermarkingType.copy(\n            digitalParams = digitalParams ?: watermarkingType.digitalParams\n        )\n    )\n\n    else -> this\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/WatermarkingContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material3.Icon\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.ImageReset\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.CompareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShowOriginalButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ResetDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.compare.presentation.components.CompareSheet\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.HiddenWatermarkInfo\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.WatermarkDataSelector\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.WatermarkParamsSelectionGroup\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.WatermarkingTypeSelector\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.screenLogic.WatermarkingComponent\n\n@Composable\nfun WatermarkingContent(\n    component: WatermarkingComponent\n) {\n    AutoContentBasedColors(\n        model = component.selectedUri\n    )\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setUris(\n            uris = uris\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n    var showOriginal by rememberSaveable { mutableStateOf(false) }\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n    var showCompareSheet by rememberSaveable { mutableStateOf(false) }\n    var showResetDialog by rememberSaveable { mutableStateOf(false) }\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.watermarking),\n                input = component.selectedUri.takeIf { it != Uri.EMPTY },\n                isLoading = component.isImageLoading,\n                size = null\n            )\n        },\n        onGoBack = {\n            if (component.haveChanges) showExitDialog = true\n            else component.onGoBack()\n        },\n        topAppBarPersistentActions = {\n            if (component.previewBitmap == null) TopAppBarEmoji()\n            CompareButton(\n                onClick = { showCompareSheet = true },\n                visible = component.previewBitmap != null && component.internalBitmap != null\n            )\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.previewBitmap != null\n            )\n        },\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = component.previewBitmap != null,\n                onShare = component::shareBitmaps,\n                onCopy = {\n                    component.cacheCurrentImage(Clipboard::copy)\n                },\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n            EnhancedIconButton(\n                enabled = component.internalBitmap != null,\n                onClick = { showResetDialog = true }\n            ) {\n                Icon(\n                    imageVector = Icons.Rounded.ImageReset,\n                    contentDescription = stringResource(R.string.reset_image)\n                )\n            }\n            if (component.internalBitmap != null) {\n                ShowOriginalButton(\n                    onStateChange = {\n                        showOriginal = it\n                    }\n                )\n            }\n        },\n        forceImagePreviewToMax = showOriginal,\n        imagePreview = {\n            ImageContainer(\n                modifier = Modifier\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                imageInside = isPortrait,\n                showOriginal = showOriginal,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.internalBitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = true\n            )\n        },\n        controls = {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                ImageCounter(\n                    imageCount = component.uris.size.takeIf { it > 1 },\n                    onRepick = {\n                        showPickImageFromUrisSheet = true\n                    }\n                )\n                HiddenWatermarkInfo(\n                    hiddenWatermark = component.currentHiddenWatermark\n                )\n                WatermarkingTypeSelector(\n                    value = component.watermarkParams,\n                    onValueChange = component::updateWatermarkParams\n                )\n                WatermarkDataSelector(\n                    value = component.watermarkParams,\n                    onValueChange = component::updateWatermarkParams\n                )\n                WatermarkParamsSelectionGroup(\n                    value = component.watermarkParams,\n                    onValueChange = component::updateWatermarkParams\n                )\n                SaveExifWidget(\n                    checked = component.keepExif,\n                    imageFormat = component.imageFormat,\n                    onCheckedChange = component::toggleKeepExif\n                )\n                QualitySelector(\n                    imageFormat = component.imageFormat,\n                    quality = component.quality,\n                    onQualityChange = component::setQuality\n                )\n                ImageFormatSelector(\n                    value = component.imageFormat,\n                    onValueChange = component::setImageFormat,\n                    quality = component.quality,\n                )\n            }\n        },\n        buttons = {\n            val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = { oneTimeSaveLocationUri ->\n                component.saveBitmaps(\n                    oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                )\n            }\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) it()\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        noDataControls = {\n            ImageNotPickedWidget(onPickImage = pickImage)\n        },\n        canShowScreenData = component.uris.isNotEmpty()\n    )\n\n    val transformations by remember(component.previewBitmap) {\n        derivedStateOf {\n            listOf(\n                component.getWatermarkTransformation()\n            )\n        }\n    }\n\n    PickImageFromUrisSheet(\n        transformations = transformations,\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = component::updateSelectedUri,\n        onUriRemoved = component::updateUrisSilently,\n        columns = if (isPortrait) 2 else 4,\n    )\n\n    ResetDialog(\n        visible = showResetDialog,\n        onDismiss = { showResetDialog = false },\n        title = stringResource(R.string.reset_properties),\n        text = stringResource(R.string.reset_properties_sub),\n        onReset = {\n            component.updateWatermarkParams(WatermarkParams.Default)\n        }\n    )\n\n    CompareSheet(\n        data = component.internalBitmap to component.previewBitmap,\n        visible = showCompareSheet,\n        onDismiss = {\n            showCompareSheet = false\n        }\n    )\n\n    ZoomModalSheet(\n        data = component.selectedUri,\n        visible = showZoomSheet,\n        transformations = transformations,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/HiddenWatermarkInfo.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.rounded.ContentCopy\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.AddPhotoAlt\nimport com.t8rin.imagetoolbox.core.resources.shapes.CloverShape\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.widget.image.Picture\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.HiddenWatermark\n\n@Composable\ninternal fun HiddenWatermarkInfo(\n    hiddenWatermark: HiddenWatermark?\n) {\n    AnimatedContent(\n        targetState = hiddenWatermark,\n        modifier = Modifier.fillMaxWidth()\n    ) { hidden ->\n        hidden?.let {\n            PreferenceItemOverload(\n                title = stringResource(\n                    when (hidden) {\n                        is HiddenWatermark.Text -> R.string.hidden_watermark_text_detected\n                        is HiddenWatermark.Image -> R.string.hidden_watermark_image_detected\n                    }\n                ),\n                subtitle = when (hidden) {\n                    is HiddenWatermark.Text -> hidden.text\n                    is HiddenWatermark.Image -> stringResource(R.string.this_image_was_hidden)\n                },\n                onClick = if (hidden is HiddenWatermark.Text) {\n                    { Clipboard.copy(hidden.text) }\n                } else null,\n                contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.35f),\n                titleFontStyle = PreferenceItemDefaults.TitleFontStyleSmall,\n                startIcon = {\n                    Icon(\n                        imageVector = Icons.Outlined.Info,\n                        contentDescription = null\n                    )\n                },\n                endIcon = {\n                    when (hidden) {\n                        is HiddenWatermark.Text -> {\n                            Icon(\n                                imageVector = Icons.Rounded.ContentCopy,\n                                contentDescription = null\n                            )\n                        }\n\n                        is HiddenWatermark.Image -> {\n                            Picture(\n                                model = hidden.image,\n                                shape = CloverShape,\n                                modifier = Modifier.size(48.dp),\n                                error = {\n                                    Icon(\n                                        imageVector = Icons.TwoTone.AddPhotoAlt,\n                                        contentDescription = null,\n                                        modifier = Modifier\n                                            .fillMaxSize()\n                                            .clip(CloverShape)\n                                            .background(\n                                                color = MaterialTheme.colorScheme.secondaryContainer\n                                                    .copy(0.5f)\n                                                    .compositeOver(MaterialTheme.colorScheme.surfaceContainer)\n                                            )\n                                            .padding(8.dp)\n                                    )\n                                }\n                            )\n                        }\n                    }\n                },\n                modifier = Modifier.fillMaxWidth(),\n                shape = ShapeDefaults.large\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/WatermarkDataSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.JAVA_FORMAT_SPECIFICATION\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkingType\n\n@Composable\nfun WatermarkDataSelector(\n    value: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    Column {\n        AnimatedContent(\n            targetState = value.watermarkingType::class.qualifiedName,\n            transitionSpec = { fadeIn() + slideInVertically() togetherWith fadeOut() + slideOutVertically() }\n        ) { qualifiedName ->\n            when (qualifiedName) {\n                WatermarkingType.Image::class.qualifiedName -> {\n                    val type = value.watermarkingType as? WatermarkingType.Image\n                        ?: return@AnimatedContent\n\n                    ImageSelector(\n                        value = type.imageData,\n                        subtitle = stringResource(id = R.string.watermarking_image_sub),\n                        onValueChange = {\n                            onValueChange(\n                                value.copy(\n                                    watermarkingType = type.copy(imageData = it)\n                                )\n                            )\n                        },\n                        modifier = modifier.fillMaxWidth()\n                    )\n                }\n\n                WatermarkingType.Text::class.qualifiedName -> {\n                    val type = value.watermarkingType as? WatermarkingType.Text\n                        ?: return@AnimatedContent\n\n                    RoundedTextField(\n                        modifier = modifier\n                            .container(\n                                shape = MaterialTheme.shapes.large,\n                                resultPadding = 8.dp\n                            ),\n                        value = type.text,\n                        singleLine = false,\n                        onValueChange = {\n                            onValueChange(\n                                value.copy(\n                                    watermarkingType = type.copy(text = it)\n                                )\n                            )\n                        },\n                        label = {\n                            Text(stringResource(R.string.text))\n                        }\n                    )\n                }\n\n                WatermarkingType.Stamp.Text::class.qualifiedName -> {\n                    val type = value.watermarkingType as? WatermarkingType.Stamp.Text\n                        ?: return@AnimatedContent\n\n                    RoundedTextField(\n                        modifier = modifier\n                            .container(\n                                shape = MaterialTheme.shapes.large,\n                                resultPadding = 8.dp\n                            ),\n                        value = type.text,\n                        singleLine = false,\n                        onValueChange = {\n                            onValueChange(\n                                value.copy(\n                                    watermarkingType = type.copy(text = it)\n                                )\n                            )\n                        },\n                        label = {\n                            Text(stringResource(R.string.text))\n                        }\n                    )\n                }\n\n                WatermarkingType.Stamp.Time::class.qualifiedName -> {\n                    val type = value.watermarkingType as? WatermarkingType.Stamp.Time\n                        ?: return@AnimatedContent\n\n                    RoundedTextField(\n                        modifier = modifier\n                            .container(\n                                shape = MaterialTheme.shapes.large,\n                                resultPadding = 8.dp\n                            ),\n                        value = type.format,\n                        singleLine = false,\n                        onValueChange = {\n                            onValueChange(\n                                value.copy(\n                                    watermarkingType = type.copy(format = it)\n                                )\n                            )\n                        },\n                        label = {\n                            Text(stringResource(R.string.format_pattern))\n                        },\n                        endIcon = {\n                            val linkHandler = LocalUriHandler.current\n                            EnhancedIconButton(\n                                onClick = {\n                                    linkHandler.openUri(JAVA_FORMAT_SPECIFICATION)\n                                }\n                            ) {\n                                Icon(\n                                    imageVector = Icons.Outlined.Info,\n                                    contentDescription = null\n                                )\n                            }\n                        }\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/WatermarkParamsSelectionGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Tune\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.other.ExpandableItem\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors.CommonParamsContent\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors.DigitalParamsContent\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors.ImageParamsContent\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors.StampParamsContent\nimport com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors.TextParamsContent\n\n@Composable\nfun WatermarkParamsSelectionGroup(\n    value: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    ExpandableItem(\n        modifier = modifier,\n        color = MaterialTheme.colorScheme.surfaceContainer,\n        visibleContent = {\n            TitleItem(\n                text = stringResource(id = R.string.properties),\n                icon = Icons.Outlined.Tune\n            )\n        },\n        expandableContent = {\n            Column(\n                modifier = Modifier.padding(horizontal = 8.dp),\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                val params by rememberUpdatedState(value)\n\n                CommonParamsContent(\n                    params = params,\n                    onValueChange = onValueChange\n                )\n\n                TextParamsContent(\n                    params = params,\n                    onValueChange = onValueChange\n                )\n\n                ImageParamsContent(\n                    params = params,\n                    onValueChange = onValueChange\n                )\n\n                DigitalParamsContent(\n                    params = params,\n                    onValueChange = onValueChange\n                )\n\n                StampParamsContent(\n                    params = params,\n                    onValueChange = onValueChange\n                )\n            }\n        },\n        shape = ShapeDefaults.extraLarge\n    )\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/WatermarkingTypeSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components\n\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButtonGroup\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkingType\n\n@Composable\nfun WatermarkingTypeSelector(\n    value: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit,\n    modifier: Modifier = Modifier\n) {\n    val selectedIndex by remember(value.watermarkingType) {\n        derivedStateOf {\n            WatermarkingType\n                .entries\n                .indexOfFirst {\n                    value.watermarkingType::class.java.isInstance(it)\n                }\n        }\n    }\n    EnhancedButtonGroup(\n        modifier = modifier\n            .container(\n                shape = ShapeDefaults.large\n            ),\n        enabled = true,\n        items = WatermarkingType.entries.map { it.translatedName },\n        selectedIndex = selectedIndex,\n        title = stringResource(id = R.string.watermark_type),\n        onIndexChange = {\n            onValueChange(value.copy(watermarkingType = WatermarkingType.entries[it]))\n        },\n        inactiveButtonColor = MaterialTheme.colorScheme.surfaceContainerHigh\n    )\n}\n\nprivate val WatermarkingType.translatedName: String\n    @Composable\n    get() = when (this) {\n        is WatermarkingType.Text -> stringResource(R.string.text)\n        is WatermarkingType.Image -> stringResource(R.string.image)\n        is WatermarkingType.Stamp.Text -> stringResource(R.string.stamp)\n        is WatermarkingType.Stamp.Time -> stringResource(R.string.timestamp)\n    }"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/selectors/CommonParamsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.TextRotationAngleup\nimport androidx.compose.material.icons.rounded.Repeat\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.AlphaSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.BlendingModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.digitalParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.isStamp\nimport kotlin.math.roundToInt\n\n@Composable\ninternal fun CommonParamsContent(\n    params: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit\n) {\n    val digitalParams = params.watermarkingType.digitalParams()\n    val isInvisible = digitalParams?.isInvisible == true\n    val isNotStampAndInvisible = !params.watermarkingType.isStamp() && !isInvisible\n\n\n    AnimatedVisibility(\n        visible = !params.isRepeated && isNotStampAndInvisible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            EnhancedSliderItem(\n                value = params.positionX,\n                title = stringResource(id = R.string.offset_x),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(params.copy(positionX = it))\n                },\n                valueRange = 0f..1f,\n                shape = ShapeDefaults.large,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = params.positionY,\n                title = stringResource(id = R.string.offset_y),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(params.copy(positionY = it))\n                },\n                valueRange = 0f..1f,\n                shape = ShapeDefaults.large,\n                containerColor = MaterialTheme.colorScheme.surface,\n                modifier = Modifier.padding(bottom = 4.dp)\n            )\n        }\n    }\n\n    AnimatedVisibility(\n        visible = isNotStampAndInvisible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        EnhancedSliderItem(\n            value = params.rotation,\n            icon = Icons.Outlined.TextRotationAngleup,\n            title = stringResource(id = R.string.angle),\n            valueRange = 0f..360f,\n            internalStateTransformation = Float::roundToInt,\n            onValueChange = {\n                onValueChange(params.copy(rotation = it.roundToInt()))\n            },\n            shape = ShapeDefaults.large,\n            containerColor = MaterialTheme.colorScheme.surface\n        )\n    }\n\n    AnimatedVisibility(\n        visible = !isInvisible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        AlphaSelector(\n            value = params.alpha,\n            onValueChange = {\n                onValueChange(params.copy(alpha = it))\n            },\n            modifier = Modifier.fillMaxWidth(),\n            shape = ShapeDefaults.large,\n            color = MaterialTheme.colorScheme.surface\n        )\n    }\n\n    AnimatedVisibility(\n        visible = isNotStampAndInvisible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            PreferenceRowSwitch(\n                title = stringResource(id = R.string.repeat_watermark),\n                subtitle = stringResource(id = R.string.repeat_watermark_sub),\n                checked = params.isRepeated,\n                startIcon = Icons.Rounded.Repeat,\n                onClick = {\n                    onValueChange(params.copy(isRepeated = it))\n                },\n                shape = ShapeDefaults.large,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(Modifier.height(4.dp))\n            BlendingModeSelector(\n                value = params.overlayMode,\n                onValueChange = {\n                    onValueChange(\n                        params.copy(overlayMode = it)\n                    )\n                }\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/selectors/DigitalParamsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.DisabledVisible\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.copy\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.digitalParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.isStamp\n\n@Composable\ninternal fun DigitalParamsContent(\n    params: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit\n) {\n    val digitalParams = params.watermarkingType.digitalParams()\n    val isInvisible = digitalParams?.isInvisible == true\n\n    AnimatedVisibility(\n        visible = !params.watermarkingType.isStamp(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        Column {\n            PreferenceRowSwitch(\n                title = stringResource(id = R.string.invisible_mode),\n                subtitle = stringResource(id = R.string.invisible_mode_sub),\n                checked = isInvisible,\n                startIcon = Icons.Rounded.DisabledVisible,\n                onClick = {\n                    onValueChange(\n                        params.copy(\n                            digitalParams = digitalParams?.copy(\n                                isInvisible = !isInvisible\n                            )\n                        )\n                    )\n                },\n                shape = ShapeDefaults.large,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n//            AnimatedVisibility(visible = isInvisible) {\n//                PreferenceRowSwitch(\n//                    title = stringResource(id = R.string.use_lsb),\n//                    subtitle = stringResource(id = R.string.use_lsb_sub),\n//                    checked = digitalParams?.isLSB ?: false,\n//                    startIcon = Icons.Rounded.GraphicEq,\n//                    onClick = {\n//                        onValueChange(\n//                            params.copy(\n//                                digitalParams = digitalParams?.copy(\n//                                    isLSB = !digitalParams.isLSB\n//                                )\n//                            )\n//                        )\n//                    },\n//                    shape = ShapeDefaults.large,\n//                    containerColor = MaterialTheme.colorScheme.surface,\n//                    modifier = Modifier.padding(top = 4.dp)\n//                )\n//            }\n        }\n    }\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/selectors/ImageParamsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkingType\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.digitalParams\n\n@Composable\ninternal fun ImageParamsContent(\n    params: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit\n) {\n    val digitalParams = params.watermarkingType.digitalParams()\n    val isInvisible = digitalParams?.isInvisible == true\n\n    AnimatedVisibility(\n        visible = params.watermarkingType is WatermarkingType.Image && !isInvisible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        val type = params.watermarkingType as? WatermarkingType.Image\n            ?: return@AnimatedVisibility\n\n        EnhancedSliderItem(\n            value = type.size,\n            title = stringResource(R.string.watermark_size),\n            internalStateTransformation = {\n                it.roundToTwoDigits()\n            },\n            onValueChange = {\n                onValueChange(\n                    params.copy(\n                        watermarkingType = type.copy(size = it)\n                    )\n                )\n            },\n            valueRange = 0.01f..1f,\n            shape = ShapeDefaults.large,\n            containerColor = MaterialTheme.colorScheme.surface\n        )\n    }\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/selectors/StampParamsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiFont\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FontSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PositionSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkingType\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.copy\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.isStamp\n\n@Composable\ninternal fun StampParamsContent(\n    params: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit\n) {\n    AnimatedVisibility(\n        visible = params.watermarkingType.isStamp(),\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        val type = params.watermarkingType as? WatermarkingType.Stamp\n            ?: return@AnimatedVisibility\n\n        Column {\n            FontSelector(\n                value = type.params.font.toUiFont(),\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(\n                                    font = it.type\n                                )\n                            )\n                        )\n                    )\n                }\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            PositionSelector(\n                value = type.position,\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                position = it\n                            )\n                        )\n                    )\n                },\n                selectedItemColor = MaterialTheme.colorScheme.primary\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = type.padding,\n                title = stringResource(R.string.padding),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                padding = it\n                            )\n                        )\n                    )\n                },\n                valueRange = 0f..50f,\n                shape = ShapeDefaults.large,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = type.params.size,\n                title = stringResource(R.string.watermark_size),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(\n                                    size = it\n                                )\n                            )\n                        )\n                    )\n                },\n                valueRange = 0.01f..1f,\n                shape = ShapeDefaults.large,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            ColorRowSelector(\n                value = type.params.color.toColor(),\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(\n                                    color = it.toArgb()\n                                )\n                            )\n                        )\n                    )\n                },\n                title = stringResource(R.string.text_color),\n                modifier = Modifier.container(\n                    shape = ShapeDefaults.large,\n                    color = MaterialTheme.colorScheme.surface\n                )\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            ColorRowSelector(\n                value = type.params.backgroundColor.toColor(),\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(\n                                    backgroundColor = it.toArgb()\n                                )\n                            )\n                        )\n                    )\n                },\n                title = stringResource(R.string.background_color),\n                modifier = Modifier.container(\n                    shape = ShapeDefaults.large,\n                    color = MaterialTheme.colorScheme.surface\n                )\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/components/selectors/TextParamsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.components.selectors\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.colors.util.roundToTwoDigits\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.model.toUiFont\nimport com.t8rin.imagetoolbox.core.ui.theme.toColor\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ColorRowSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.FontSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkingType\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.digitalParams\n\n@Composable\ninternal fun TextParamsContent(\n    params: WatermarkParams,\n    onValueChange: (WatermarkParams) -> Unit\n) {\n    val digitalParams = params.watermarkingType.digitalParams()\n    val isInvisible = digitalParams?.isInvisible == true\n\n    AnimatedVisibility(\n        visible = params.watermarkingType is WatermarkingType.Text && !isInvisible,\n        enter = fadeIn() + expandVertically(),\n        exit = fadeOut() + shrinkVertically()\n    ) {\n        val type = params.watermarkingType as? WatermarkingType.Text\n            ?: return@AnimatedVisibility\n\n        Column {\n            FontSelector(\n                value = type.params.font.toUiFont(),\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(font = it.type)\n                            )\n                        )\n                    )\n                }\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            EnhancedSliderItem(\n                value = type.params.size,\n                title = stringResource(R.string.watermark_size),\n                internalStateTransformation = {\n                    it.roundToTwoDigits()\n                },\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(size = it)\n                            )\n                        )\n                    )\n                },\n                valueRange = 0.01f..1f,\n                shape = ShapeDefaults.large,\n                containerColor = MaterialTheme.colorScheme.surface\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            ColorRowSelector(\n                value = type.params.color.toColor(),\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(color = it.toArgb())\n                            )\n                        )\n                    )\n                },\n                title = stringResource(R.string.text_color),\n                modifier = Modifier.container(\n                    shape = ShapeDefaults.large,\n                    color = MaterialTheme.colorScheme.surface\n                )\n            )\n            Spacer(modifier = Modifier.height(4.dp))\n            ColorRowSelector(\n                value = type.params.backgroundColor.toColor(),\n                onValueChange = {\n                    onValueChange(\n                        params.copy(\n                            watermarkingType = type.copy(\n                                params = type.params.copy(backgroundColor = it.toArgb())\n                            )\n                        )\n                    )\n                },\n                title = stringResource(R.string.background_color),\n                modifier = Modifier.container(\n                    shape = ShapeDefaults.large,\n                    color = MaterialTheme.colorScheme.surface\n                )\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/watermarking/src/main/java/com/t8rin/imagetoolbox/feature/watermarking/presentation/screenLogic/WatermarkingComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.watermarking.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport coil3.transform.Transformation\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.data.utils.toCoil\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.transformation.GenericTransformation\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.HiddenWatermark\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkApplier\nimport com.t8rin.imagetoolbox.feature.watermarking.domain.WatermarkParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.withContext\n\nclass WatermarkingComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    private val watermarkApplier: WatermarkApplier<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n        }\n    }\n\n    private val _internalBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val internalBitmap: Bitmap? by _internalBitmap\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _keepExif = mutableStateOf(false)\n    val keepExif by _keepExif\n\n    private val _selectedUri = mutableStateOf(Uri.EMPTY)\n    val selectedUri: Uri by _selectedUri\n\n    private val _uris = mutableStateOf<List<Uri>>(emptyList())\n    val uris by _uris\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _watermarkParams = mutableStateOf(WatermarkParams.Default)\n    val watermarkParams by _watermarkParams\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    private val _quality: MutableState<Quality> = mutableStateOf(Quality.Base())\n    val quality by _quality\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _currentHiddenWatermark: MutableState<HiddenWatermark?> = mutableStateOf(null)\n    val currentHiddenWatermark by _currentHiddenWatermark\n\n    private fun updateBitmap(\n        bitmap: Bitmap,\n        onComplete: () -> Unit = {}\n    ) {\n        componentScope.launch {\n            _currentHiddenWatermark.update {\n                watermarkApplier.checkHiddenWatermark(bitmap)\n            }\n        }\n        componentScope.launch {\n            _isImageLoading.value = true\n            _internalBitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n            checkBitmapAndUpdate()\n            _isImageLoading.value = false\n            onComplete()\n        }\n    }\n\n    private fun checkBitmapAndUpdate() {\n        debouncedImageCalculation {\n            _previewBitmap.value = _internalBitmap.value?.let {\n                getWatermarkedBitmap(it)\n            }\n        }\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _left.value = -1\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            _left.value = uris.size\n            uris.forEach { uri ->\n                getWatermarkedBitmap(\n                    data = uri.toString(),\n                    originalSize = true\n                )?.let { localBitmap ->\n                    val imageInfo = ImageInfo(\n                        imageFormat = imageFormat,\n                        width = localBitmap.width,\n                        height = localBitmap.height,\n                        quality = quality\n                    )\n\n                    results.add(\n                        fileController.save(\n                            saveTarget = ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                originalUri = uri.toString(),\n                                sequenceNumber = _done.value + 1,\n                                data = imageCompressor.compressAndTransform(\n                                    image = localBitmap,\n                                    imageInfo = imageInfo\n                                )\n                            ),\n                            keepOriginalMetadata = keepExif,\n                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                        )\n                    )\n\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    private suspend fun getWatermarkedBitmap(\n        data: Any,\n        originalSize: Boolean = false\n    ): Bitmap? = withContext(defaultDispatcher) {\n        imageGetter.getImage(data, originalSize)?.let { image ->\n            watermarkApplier.applyWatermark(\n                image = image,\n                originalSize = originalSize,\n                params = watermarkParams\n            )\n        }\n    }\n\n    fun shareBitmaps() {\n        _left.value = -1\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            _left.value = uris.size\n            shareProvider.shareImages(\n                uris.map { it.toString() },\n                imageLoader = { uri ->\n                    getWatermarkedBitmap(\n                        data = uri,\n                        originalSize = true\n                    )?.let {\n                        it to ImageInfo(\n                            width = it.width,\n                            height = it.height,\n                            imageFormat = imageFormat,\n                            quality = quality\n                        )\n                    }\n                },\n                onProgressChange = {\n                    if (it == -1) {\n                        AppToastHost.showConfetti()\n                        _isSaving.value = false\n                        _done.value = 0\n                    } else {\n                        _done.value = it\n                    }\n                    updateProgress(\n                        done = done,\n                        total = left\n                    )\n                }\n            )\n            _isSaving.value = false\n            _left.value = -1\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n        _left.value = -1\n    }\n\n    fun setQuality(quality: Quality) {\n        _quality.update { quality }\n        registerChanges()\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        registerChanges()\n    }\n\n    fun updateWatermarkParams(watermarkParams: WatermarkParams) {\n        _watermarkParams.update { watermarkParams }\n        registerChanges()\n        checkBitmapAndUpdate()\n    }\n\n    fun updateSelectedUri(\n        uri: Uri\n    ) {\n        componentScope.launch {\n            _selectedUri.value = uri\n            _isImageLoading.value = true\n            imageGetter.getImageAsync(\n                uri = uri.toString(),\n                originalSize = false,\n                onGetImage = { imageData ->\n                    updateBitmap(imageData.image)\n                    _isImageLoading.value = false\n                    setImageFormat(imageData.imageInfo.imageFormat)\n                },\n                onFailure = {\n                    _isImageLoading.value = false\n                    AppToastHost.showFailureToast(it)\n                }\n            )\n        }\n    }\n\n    fun updateUrisSilently(removedUri: Uri) {\n        componentScope.launch {\n            if (selectedUri == removedUri) {\n                val index = uris.indexOf(removedUri)\n                if (index == 0) {\n                    uris.getOrNull(1)?.let(::updateSelectedUri)\n                } else {\n                    uris.getOrNull(index - 1)?.let(::updateSelectedUri)\n                }\n            }\n            _uris.update {\n                it.toMutableList().apply {\n                    remove(removedUri)\n                }\n            }\n        }\n    }\n\n    fun setUris(\n        uris: List<Uri>,\n    ) {\n        _uris.update { uris }\n        uris.firstOrNull()?.let(::updateSelectedUri)\n    }\n\n    fun toggleKeepExif(value: Boolean) {\n        _keepExif.update { value }\n        registerChanges()\n    }\n\n    fun getWatermarkTransformation(): Transformation {\n        return GenericTransformation<Bitmap>(watermarkParams) { input, size ->\n            imageScaler.scaleImage(\n                image = getWatermarkedBitmap(input) ?: input,\n                width = size.width,\n                height = size.height,\n                resizeType = ResizeType.Flexible\n            )\n        }.toCoil()\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            getWatermarkedBitmap(\n                data = selectedUri,\n                originalSize = true\n            )?.let {\n                it to ImageInfo(\n                    width = it.width,\n                    height = it.height,\n                    imageFormat = imageFormat,\n                    quality = quality\n                )\n            }?.let { (image, imageInfo) ->\n                shareProvider.cacheImage(\n                    image = image,\n                    imageInfo = imageInfo.copy(originalUri = selectedUri.toString())\n                )?.let { uri ->\n                    onComplete(uri.toUri())\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            _left.value = uris.size\n            val list = mutableListOf<Uri>()\n            uris.forEach { uri ->\n                getWatermarkedBitmap(\n                    data = uri,\n                    originalSize = true\n                )?.let {\n                    it to ImageInfo(\n                        width = it.width,\n                        height = it.height,\n                        imageFormat = imageFormat,\n                        quality = quality\n                    )\n                }?.let { (image, imageInfo) ->\n                    shareProvider.cacheImage(\n                        image = image,\n                        imageInfo = imageInfo.copy(originalUri = uri.toString())\n                    )?.let { uri ->\n                        list.add(uri.toUri())\n                    }\n                }\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = left\n                )\n            }\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            .indexOf(selectedUri)\n            .takeIf { it >= 0 }\n            ?.let {\n                uris.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            .indexOf(selectedUri)\n            .takeIf { it >= 0 }\n            ?.let {\n                uris.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? =\n        if (uris.size == 1) imageFormat\n        else null\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): WatermarkingComponent\n    }\n}"
  },
  {
    "path": "feature/webp-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/webp-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.webp_tools\"\n\ndependencies {\n    implementation(libs.toolbox.awebp)\n}"
  },
  {
    "path": "feature/webp-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/webp-tools/src/main/java/com/t8rin/imagetoolbox/feature/webp_tools/data/AndroidWebpConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.webp_tools.data\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.net.toUri\nimport com.t8rin.awebp.decoder.AnimatedWebpDecoder\nimport com.t8rin.awebp.encoder.AnimatedWebpEncoder\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.image.model.ResizeType\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.feature.webp_tools.domain.WebpConverter\nimport com.t8rin.imagetoolbox.feature.webp_tools.domain.WebpParams\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.mapNotNull\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.io.InputStream\nimport javax.inject.Inject\n\n\ninternal class AndroidWebpConverter @Inject constructor(\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageShareProvider: ImageShareProvider<Bitmap>,\n    private val imageScaler: ImageScaler<Bitmap>,\n    @ApplicationContext private val context: Context,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, WebpConverter {\n\n    override fun extractFramesFromWebp(\n        webpUri: String,\n        imageFormat: ImageFormat,\n        quality: Quality\n    ): Flow<String> = AnimatedWebpDecoder(\n        sourceFile = webpUri.file,\n        coroutineScope = CoroutineScope(decodingDispatcher)\n    ).frames().mapNotNull { frame ->\n        imageShareProvider.cacheImage(\n            image = frame.bitmap,\n            imageInfo = ImageInfo(\n                width = frame.bitmap.width,\n                height = frame.bitmap.height,\n                imageFormat = imageFormat,\n                quality = quality\n            )\n        ).also {\n            frame.bitmap.recycle()\n        }\n    }\n\n    override suspend fun createWebpFromImageUris(\n        imageUris: List<String>,\n        params: WebpParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): ByteArray? = withContext(defaultDispatcher) {\n        val size = params.size ?: imageGetter.getImage(data = imageUris[0])!!.run {\n            IntegerSize(width, height)\n        }\n\n        if (size.width <= 0 || size.height <= 0) {\n            onFailure(IllegalArgumentException(\"Width and height must be > 0\"))\n            return@withContext null\n        }\n\n        val encoder = AnimatedWebpEncoder(\n            quality = params.quality.qualityValue,\n            loopCount = params.repeatCount,\n            backgroundColor = Color.Transparent.toArgb()\n        )\n\n        imageUris.forEach { uri ->\n            imageGetter.getImage(\n                data = uri,\n                size = size\n            )?.let {\n                encoder.addFrame(\n                    bitmap = imageScaler.scaleImage(\n                        image = imageScaler.scaleImage(\n                            image = it,\n                            width = size.width,\n                            height = size.height,\n                            resizeType = ResizeType.Flexible\n                        ),\n                        width = size.width,\n                        height = size.height,\n                        resizeType = ResizeType.CenterCrop(\n                            canvasColor = Color.Transparent.toArgb()\n                        )\n                    ),\n                    duration = params.delay\n                )\n            }\n            onProgress()\n        }\n\n        runCatching {\n            encoder.encode()\n        }.onFailure(onFailure).getOrNull()\n    }\n\n    private val String.inputStream: InputStream?\n        get() = context\n            .contentResolver\n            .openInputStream(toUri())\n\n    private val String.file: File\n        get() {\n            val gifFile = File(context.cacheDir, \"temp.webp\")\n            inputStream?.use { gifStream ->\n                gifStream.copyTo(FileOutputStream(gifFile))\n            }\n            return gifFile\n        }\n\n\n}"
  },
  {
    "path": "feature/webp-tools/src/main/java/com/t8rin/imagetoolbox/feature/webp_tools/di/WebpToolsModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.webp_tools.di\n\nimport com.t8rin.imagetoolbox.feature.webp_tools.data.AndroidWebpConverter\nimport com.t8rin.imagetoolbox.feature.webp_tools.domain.WebpConverter\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface WebpToolsModule {\n\n    @Binds\n    @Singleton\n    fun provideConverter(\n        converter: AndroidWebpConverter\n    ): WebpConverter\n\n}"
  },
  {
    "path": "feature/webp-tools/src/main/java/com/t8rin/imagetoolbox/feature/webp_tools/domain/WebpConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.webp_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport kotlinx.coroutines.flow.Flow\n\ninterface WebpConverter {\n\n    fun extractFramesFromWebp(\n        webpUri: String,\n        imageFormat: ImageFormat,\n        quality: Quality\n    ): Flow<String>\n\n    suspend fun createWebpFromImageUris(\n        imageUris: List<String>,\n        params: WebpParams,\n        onFailure: (Throwable) -> Unit,\n        onProgress: () -> Unit\n    ): ByteArray?\n\n}"
  },
  {
    "path": "feature/webp-tools/src/main/java/com/t8rin/imagetoolbox/feature/webp_tools/domain/WebpParams.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.webp_tools.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\n\ndata class WebpParams(\n    val size: IntegerSize?,\n    val repeatCount: Int,\n    val delay: Int,\n    val quality: Quality\n) {\n    companion object {\n        val Default by lazy {\n            WebpParams(\n                size = null,\n                repeatCount = 1,\n                delay = 1000,\n                quality = Quality.Base(100)\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/webp-tools/src/main/java/com/t8rin/imagetoolbox/feature/webp_tools/presentation/WebpToolsContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.webp_tools.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleIn\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.displayCutout\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.Close\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.resources.icons.SelectAll\nimport com.t8rin.imagetoolbox.core.resources.icons.Webp\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ImageReorderCarousel\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedLoadingIndicator\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImagesPreviewWithSelection\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.withModifier\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.utils.getString\nimport com.t8rin.imagetoolbox.core.utils.isWebp\nimport com.t8rin.imagetoolbox.feature.webp_tools.presentation.components.WebpParamsSelector\nimport com.t8rin.imagetoolbox.feature.webp_tools.presentation.screenLogic.WebpToolsComponent\n\n@Composable\nfun WebpToolsContent(\n    component: WebpToolsComponent\n) {\n    val imagePicker = rememberImagePicker(onSuccess = component::setImageUris)\n\n    val pickSingleWebpLauncher = rememberFilePicker(\n        mimeType = MimeType.Webp,\n        onSuccess = { uri: Uri ->\n            if (uri.isWebp()) {\n                component.setWebpUri(uri)\n            } else {\n                AppToastHost.showToast(\n                    message = getString(R.string.select_webp_image_to_start),\n                    icon = Icons.Rounded.Webp\n                )\n            }\n        }\n    )\n\n    val saveWebpLauncher = rememberFileCreator(\n        mimeType = MimeType.Webp,\n        onSuccess = component::saveWebpTo\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = when (val type = component.type) {\n                    null -> stringResource(R.string.webp_tools)\n                    else -> stringResource(type.title)\n                },\n                input = component.type,\n                isLoading = component.isLoading,\n                size = null\n            )\n        },\n        onGoBack = onBack,\n        topAppBarPersistentActions = {\n            if (component.type == null) TopAppBarEmoji()\n            val pagesSize by remember(component.imageFrames, component.convertedImageUris) {\n                derivedStateOf {\n                    component.imageFrames.getFramePositions(component.convertedImageUris.size).size\n                }\n            }\n            val isWebpToImage = component.type is Screen.WebpTools.Type.WebpToImage\n            AnimatedVisibility(\n                visible = isWebpToImage && pagesSize != component.convertedImageUris.size,\n                enter = fadeIn() + scaleIn() + expandHorizontally(),\n                exit = fadeOut() + scaleOut() + shrinkHorizontally()\n            ) {\n                EnhancedIconButton(\n                    onClick = component::selectAllConvertedImages\n                ) {\n                    Icon(\n                        imageVector = Icons.Outlined.SelectAll,\n                        contentDescription = \"Select All\"\n                    )\n                }\n            }\n            AnimatedVisibility(\n                modifier = Modifier\n                    .padding(8.dp)\n                    .container(\n                        shape = ShapeDefaults.circle,\n                        color = MaterialTheme.colorScheme.surfaceContainerHighest,\n                        resultPadding = 0.dp\n                    ),\n                visible = isWebpToImage && pagesSize != 0\n            ) {\n                Row(\n                    modifier = Modifier.padding(start = 12.dp),\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.Center\n                ) {\n                    pagesSize.takeIf { it != 0 }?.let {\n                        Spacer(Modifier.width(8.dp))\n                        Text(\n                            text = it.toString(),\n                            fontSize = 20.sp,\n                            fontWeight = FontWeight.Medium\n                        )\n                    }\n                    EnhancedIconButton(\n                        onClick = component::clearConvertedImagesSelection\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Close,\n                            contentDescription = stringResource(R.string.close)\n                        )\n                    }\n                }\n            }\n        },\n        actions = {\n            var editSheetData by remember {\n                mutableStateOf(listOf<Uri>())\n            }\n            ShareButton(\n                enabled = !component.isLoading && component.type != null,\n                onShare = component::performSharing,\n                onEdit = {\n                    component.cacheImages {\n                        editSheetData = it\n                    }\n                }\n            )\n            ProcessImagesPreferenceSheet(\n                uris = editSheetData,\n                visible = editSheetData.isNotEmpty(),\n                onDismiss = {\n                    editSheetData = emptyList()\n                },\n                onNavigate = component.onNavigate\n            )\n        },\n        imagePreview = {\n            AnimatedContent(\n                targetState = component.isLoading to component.type\n            ) { (loading, type) ->\n                Box(\n                    contentAlignment = Alignment.Center,\n                    modifier = if (loading) {\n                        Modifier.padding(32.dp)\n                    } else Modifier\n                ) {\n                    if (loading || type == null) {\n                        EnhancedLoadingIndicator()\n                    } else {\n                        when (type) {\n                            is Screen.WebpTools.Type.WebpToImage -> {\n                                ImagesPreviewWithSelection(\n                                    imageUris = component.convertedImageUris,\n                                    imageFrames = component.imageFrames,\n                                    onFrameSelectionChange = component::updateWebpFrames,\n                                    isPortrait = isPortrait,\n                                    isLoadingImages = component.isLoadingWebpImages\n                                )\n                            }\n\n                            is Screen.WebpTools.Type.ImageToWebp -> Unit\n                        }\n                    }\n                }\n            }\n        },\n        placeImagePreview = component.type !is Screen.WebpTools.Type.ImageToWebp,\n        showImagePreviewAsStickyHeader = false,\n        autoClearFocus = false,\n        controls = {\n            when (val type = component.type) {\n                is Screen.WebpTools.Type.WebpToImage -> {\n                    Spacer(modifier = Modifier.height(16.dp))\n                    ImageFormatSelector(\n                        value = component.imageFormat,\n                        onValueChange = component::setImageFormat,\n                        entries = ImageFormatGroup.alphaContainedEntries\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    QualitySelector(\n                        imageFormat = component.imageFormat,\n                        quality = component.params.quality,\n                        onQualityChange = component::setQuality\n                    )\n                    Spacer(modifier = Modifier.height(16.dp))\n                }\n\n                is Screen.WebpTools.Type.ImageToWebp -> {\n                    val addImagesToPdfPicker =\n                        rememberImagePicker(onSuccess = component::addImageToUris)\n\n                    Spacer(modifier = Modifier.height(16.dp))\n                    ImageReorderCarousel(\n                        images = type.imageUris,\n                        onReorder = component::reorderImageUris,\n                        onNeedToAddImage = addImagesToPdfPicker::pickImage,\n                        onNeedToRemoveImageAt = component::removeImageAt,\n                        onNavigate = component.onNavigate\n                    )\n                    Spacer(modifier = Modifier.height(8.dp))\n                    WebpParamsSelector(\n                        value = component.params,\n                        onValueChange = component::updateParams\n                    )\n                    Spacer(modifier = Modifier.height(16.dp))\n                }\n\n                null -> Unit\n            }\n        },\n        contentPadding = animateDpAsState(\n            if (component.type == null) 12.dp\n            else 20.dp\n        ).value,\n        buttons = { actions ->\n            val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n                component.saveBitmaps(\n                    oneTimeSaveLocationUri = it,\n                    onWebpSaveResult = saveWebpLauncher::make\n                )\n            }\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.type == null,\n                onSecondaryButtonClick = {\n                    when (component.type) {\n                        is Screen.WebpTools.Type.WebpToImage -> pickSingleWebpLauncher.pickFile()\n                        else -> imagePicker.pickImage()\n                    }\n                },\n                isPrimaryButtonVisible = component.canSave,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    if (component.type is Screen.WebpTools.Type.ImageToWebp) {\n                        saveBitmaps(null)\n                    } else showFolderSelectionDialog = true\n                },\n                actions = {\n                    if (isPortrait) actions()\n                },\n                showNullDataButtonAsContainer = true,\n                onSecondaryButtonLongClick = if (component.type is Screen.WebpTools.Type.ImageToWebp || component.type == null) {\n                    {\n                        showOneTimeImagePickingDialog = true\n                    }\n                } else null\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        insetsForNoData = WindowInsets(0),\n        noDataControls = {\n            val types = remember {\n                Screen.WebpTools.Type.entries\n            }\n            val preference1 = @Composable {\n                PreferenceItem(\n                    title = stringResource(types[0].title),\n                    subtitle = stringResource(types[0].subtitle),\n                    startIcon = types[0].icon,\n                    modifier = Modifier.fillMaxWidth(),\n                    onClick = imagePicker::pickImage\n                )\n            }\n            val preference2 = @Composable {\n                PreferenceItem(\n                    title = stringResource(types[1].title),\n                    subtitle = stringResource(types[1].subtitle),\n                    startIcon = types[1].icon,\n                    modifier = Modifier.fillMaxWidth(),\n                    onClick = pickSingleWebpLauncher::pickFile\n                )\n            }\n\n            if (isPortrait) {\n                Column {\n                    preference1()\n                    Spacer(modifier = Modifier.height(8.dp))\n                    preference2()\n                }\n            } else {\n                val direction = LocalLayoutDirection.current\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Row(\n                        modifier = Modifier.padding(\n                            WindowInsets.displayCutout.asPaddingValues().let {\n                                PaddingValues(\n                                    start = it.calculateStartPadding(direction),\n                                    end = it.calculateEndPadding(direction)\n                                )\n                            }\n                        )\n                    ) {\n                        preference1.withModifier(modifier = Modifier.weight(1f))\n                        Spacer(modifier = Modifier.width(8.dp))\n                        preference2.withModifier(modifier = Modifier.weight(1f))\n                    }\n                }\n            }\n        },\n        canShowScreenData = component.type != null\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component::clearAll,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/webp-tools/src/main/java/com/t8rin/imagetoolbox/feature/webp_tools/presentation/components/WebpParamsSelector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.webp_tools.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.PhotoSizeSelectLarge\nimport androidx.compose.material.icons.outlined.RepeatOne\nimport androidx.compose.material.icons.outlined.Timelapse\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.ResizeImageField\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.QualitySelector\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedSliderItem\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch\nimport com.t8rin.imagetoolbox.feature.webp_tools.domain.WebpParams\nimport kotlin.math.roundToInt\n\n@Composable\nfun WebpParamsSelector(\n    value: WebpParams,\n    onValueChange: (WebpParams) -> Unit\n) {\n    Column {\n        val size = value.size ?: IntegerSize.Undefined\n        AnimatedVisibility(size.isDefined()) {\n            ResizeImageField(\n                imageInfo = ImageInfo(size.width, size.height),\n                originalSize = null,\n                onWidthChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(width = it)\n                        )\n                    )\n                },\n                onHeightChange = {\n                    onValueChange(\n                        value.copy(\n                            size = size.copy(height = it)\n                        )\n                    )\n                }\n            )\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        PreferenceRowSwitch(\n            title = stringResource(id = R.string.use_size_of_first_frame),\n            subtitle = stringResource(id = R.string.use_size_of_first_frame_sub),\n            checked = value.size == null,\n            onClick = {\n                onValueChange(\n                    value.copy(size = if (it) null else IntegerSize(1000, 1000))\n                )\n            },\n            startIcon = Icons.Outlined.PhotoSizeSelectLarge,\n            modifier = Modifier.fillMaxWidth(),\n            containerColor = Color.Unspecified,\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        QualitySelector(\n            imageFormat = ImageFormat.Jpg,\n            quality = value.quality,\n            onQualityChange = {\n                onValueChange(\n                    value.copy(\n                        quality = Quality.Base(it.qualityValue)\n                    )\n                )\n            }\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.repeatCount,\n            icon = Icons.Outlined.RepeatOne,\n            title = stringResource(id = R.string.repeat_count),\n            valueRange = 1f..10f,\n            steps = 9,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        repeatCount = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        EnhancedSliderItem(\n            value = value.delay,\n            icon = Icons.Outlined.Timelapse,\n            title = stringResource(id = R.string.frame_delay),\n            valueRange = 1f..4000f,\n            internalStateTransformation = { it.roundToInt() },\n            onValueChange = {\n                onValueChange(\n                    value.copy(\n                        delay = it.roundToInt()\n                    )\n                )\n            },\n            shape = ShapeDefaults.extraLarge\n        )\n    }\n}"
  },
  {
    "path": "feature/webp-tools/src/main/java/com/t8rin/imagetoolbox/feature/webp_tools/presentation/screenLogic/WebpToolsComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.webp_tools.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFrames\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.webp_tools.domain.WebpConverter\nimport com.t8rin.imagetoolbox.feature.webp_tools.domain.WebpParams\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.onCompletion\n\nclass WebpToolsComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialType: Screen.WebpTools.Type?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val fileController: FileController,\n    private val webpConverter: WebpConverter,\n    private val shareProvider: ShareProvider,\n    defaultDispatchersHolder: DispatchersHolder\n) : BaseComponent(defaultDispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialType?.let(::setType)\n        }\n    }\n\n    private val _type: MutableState<Screen.WebpTools.Type?> = mutableStateOf(null)\n    val type by _type\n\n    private val _isLoading: MutableState<Boolean> = mutableStateOf(false)\n    val isLoading by _isLoading\n\n    private val _isLoadingWebpImages: MutableState<Boolean> = mutableStateOf(false)\n    val isLoadingWebpImages by _isLoadingWebpImages\n\n    private val _params: MutableState<WebpParams> = mutableStateOf(WebpParams.Default)\n    val params by _params\n\n    private val _convertedImageUris: MutableState<List<String>> = mutableStateOf(emptyList())\n    val convertedImageUris by _convertedImageUris\n\n    private val _imageFormat: MutableState<ImageFormat> = mutableStateOf(ImageFormat.Png.Lossless)\n    val imageFormat by _imageFormat\n\n    private val _imageFrames: MutableState<ImageFrames> = mutableStateOf(ImageFrames.All)\n    val imageFrames by _imageFrames\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private var webpData: ByteArray? = null\n\n    fun setType(type: Screen.WebpTools.Type) {\n        when (type) {\n            is Screen.WebpTools.Type.WebpToImage -> {\n                type.webpUri?.let { setWebpUri(it) } ?: _type.update { null }\n            }\n\n            is Screen.WebpTools.Type.ImageToWebp -> {\n                _type.update { type }\n            }\n        }\n    }\n\n    fun setImageUris(uris: List<Uri>) {\n        clearAll()\n        _type.update {\n            Screen.WebpTools.Type.ImageToWebp(uris)\n        }\n    }\n\n    private var collectionJob: Job? by smartJob {\n        _isLoading.update { false }\n    }\n\n    fun setWebpUri(uri: Uri) {\n        clearAll()\n        _type.update {\n            Screen.WebpTools.Type.WebpToImage(uri)\n        }\n        updateWebpFrames(ImageFrames.All)\n        collectionJob = componentScope.launch {\n            _isLoading.update { true }\n            _isLoadingWebpImages.update { true }\n            webpConverter.extractFramesFromWebp(\n                webpUri = uri.toString(),\n                imageFormat = imageFormat,\n                quality = params.quality\n            ).onCompletion {\n                _isLoading.update { false }\n                _isLoadingWebpImages.update { false }\n            }.collect { nextUri ->\n                if (isLoading) {\n                    _isLoading.update { false }\n                }\n                _convertedImageUris.update { it + nextUri }\n            }\n        }\n    }\n\n    fun clearAll() {\n        collectionJob = null\n        _type.update { null }\n        _convertedImageUris.update { emptyList() }\n        webpData = null\n        savingJob = null\n        updateParams(WebpParams.Default)\n        registerChangesCleared()\n    }\n\n    fun updateWebpFrames(imageFrames: ImageFrames) {\n        _imageFrames.update { imageFrames }\n        registerChanges()\n    }\n\n    fun clearConvertedImagesSelection() = updateWebpFrames(ImageFrames.ManualSelection(emptyList()))\n\n    fun selectAllConvertedImages() = updateWebpFrames(ImageFrames.All)\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveWebpTo(uri: Uri) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            webpData?.let { byteArray ->\n                fileController.writeBytes(\n                    uri = uri.toString(),\n                    block = { it.writeBytes(byteArray) }\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n            _isSaving.value = false\n            webpData = null\n        }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?,\n        onWebpSaveResult: (String) -> Unit\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.WebpTools.Type.WebpToImage -> {\n                    val results = mutableListOf<SaveResult>()\n                    type.webpUri?.toString()?.also { webpUri ->\n                        _left.value = 0\n                        webpConverter.extractFramesFromWebp(\n                            webpUri = webpUri,\n                            imageFormat = imageFormat,\n                            quality = params.quality\n                        ).onCompletion {\n                            parseSaveResults(results.onSuccess(::registerSave))\n                        }.collect { uri ->\n                            imageGetter.getImage(\n                                data = uri,\n                                originalSize = true\n                            )?.let { localBitmap ->\n                                if ((done + 1) in imageFrames.getFramePositions(convertedImageUris.size + 10)) {\n                                    val imageInfo = ImageInfo(\n                                        imageFormat = imageFormat,\n                                        width = localBitmap.width,\n                                        height = localBitmap.height\n                                    )\n\n                                    results.add(\n                                        fileController.save(\n                                            saveTarget = ImageSaveTarget(\n                                                imageInfo = imageInfo,\n                                                originalUri = uri,\n                                                sequenceNumber = _done.value + 1,\n                                                data = imageCompressor.compressAndTransform(\n                                                    image = localBitmap,\n                                                    imageInfo = ImageInfo(\n                                                        imageFormat = imageFormat,\n                                                        quality = params.quality,\n                                                        width = localBitmap.width,\n                                                        height = localBitmap.height\n                                                    )\n                                                )\n                                            ),\n                                            keepOriginalMetadata = false,\n                                            oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                                        )\n                                    )\n                                }\n                            } ?: results.add(\n                                SaveResult.Error.Exception(Throwable())\n                            )\n                            _done.value++\n                            updateProgress(\n                                done = done,\n                                total = left\n                            )\n                        }\n                    }\n                }\n\n                is Screen.WebpTools.Type.ImageToWebp -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    webpData = type.imageUris?.map { it.toString() }?.let { list ->\n                        webpConverter.createWebpFromImageUris(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            },\n                            onFailure = {\n                                parseSaveResults(listOf(SaveResult.Error.Exception(it)))\n                            }\n                        )?.also {\n                            onWebpSaveResult(\"WEBP_${timestamp()}.webp\")\n                            registerSave()\n                        }\n                    }\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun reorderImageUris(uris: List<Uri>?) {\n        if (type is Screen.WebpTools.Type.ImageToWebp) {\n            _type.update {\n                Screen.WebpTools.Type.ImageToWebp(uris)\n            }\n        }\n        registerChanges()\n    }\n\n    fun addImageToUris(uris: List<Uri>) {\n        val type = _type.value\n        if (type is Screen.WebpTools.Type.ImageToWebp) {\n            _type.update {\n                val newUris = type.imageUris?.plus(uris)?.toSet()?.toList()\n\n                Screen.WebpTools.Type.ImageToWebp(newUris)\n            }\n        }\n        registerChanges()\n    }\n\n    fun removeImageAt(index: Int) {\n        val type = _type.value\n        if (type is Screen.WebpTools.Type.ImageToWebp) {\n            _type.update {\n                val newUris = type.imageUris?.toMutableList()?.apply {\n                    removeAt(index)\n                }\n\n                Screen.WebpTools.Type.ImageToWebp(newUris)\n            }\n        }\n        registerChanges()\n    }\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        _imageFormat.update { imageFormat }\n        registerChanges()\n    }\n\n    fun setQuality(quality: Quality) {\n        updateParams(params.copy(quality = quality))\n    }\n\n    fun updateParams(params: WebpParams) {\n        _params.update { params }\n        registerChanges()\n    }\n\n    fun performSharing() {\n        cacheImages { uris ->\n            componentScope.launch {\n                shareProvider.shareUris(uris.map { it.toString() })\n                AppToastHost.showConfetti()\n            }\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        _isSaving.value = false\n        savingJob?.cancel()\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _left.value = 1\n            _done.value = 0\n            when (val type = _type.value) {\n                is Screen.WebpTools.Type.WebpToImage -> {\n                    _left.value = -1\n                    val positions =\n                        imageFrames.getFramePositions(convertedImageUris.size).map { it - 1 }\n                    val uris = convertedImageUris.filterIndexed { index, _ ->\n                        index in positions\n                    }\n                    onComplete(uris.map { it.toUri() })\n                }\n\n                is Screen.WebpTools.Type.ImageToWebp -> {\n                    _left.value = type.imageUris?.size ?: -1\n                    type.imageUris?.map { it.toString() }?.let { list ->\n                        webpConverter.createWebpFromImageUris(\n                            imageUris = list,\n                            params = params,\n                            onProgress = {\n                                _done.update { it + 1 }\n                                updateProgress(\n                                    done = done,\n                                    total = left\n                                )\n                            },\n                            onFailure = {}\n                        )?.also { byteArray ->\n                            shareProvider.cacheByteArray(\n                                byteArray = byteArray,\n                                filename = \"WEBP_${timestamp()}.webp\",\n                            )?.let {\n                                onComplete(listOf(it.toUri()))\n                            }\n                        }\n                    }\n                }\n\n                null -> Unit\n            }\n            _isSaving.value = false\n        }\n    }\n\n    val canSave: Boolean\n        get() = (imageFrames == ImageFrames.All)\n            .or(type is Screen.WebpTools.Type.ImageToWebp)\n            .or((imageFrames as? ImageFrames.ManualSelection)?.framePositions?.isNotEmpty() == true)\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialType: Screen.WebpTools.Type?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): WebpToolsComponent\n    }\n\n}"
  },
  {
    "path": "feature/weight-resize/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/weight-resize/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.weight_resize\""
  },
  {
    "path": "feature/weight-resize/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/weight-resize/src/main/java/com/t8rin/imagetoolbox/feature/weight_resize/data/AndroidWeightImageScaler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.weight_resize.data\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Quality\nimport com.t8rin.imagetoolbox.core.domain.model.IntegerSize\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.feature.weight_resize.domain.WeightImageScaler\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport kotlin.math.roundToInt\n\ninternal class AndroidWeightImageScaler @Inject constructor(\n    imageScaler: ImageScaler<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder,\n    ImageScaler<Bitmap> by imageScaler,\n    WeightImageScaler<Bitmap> {\n\n    override suspend fun scaleByMaxBytes(\n        image: Bitmap,\n        imageFormat: ImageFormat,\n        imageScaleMode: ImageScaleMode,\n        maxBytes: Long\n    ): Pair<ByteArray, ImageInfo>? = withContext(defaultDispatcher) {\n        runSuspendCatching {\n            val initialSize = imageCompressor.calculateImageSize(\n                image = image,\n                imageInfo = ImageInfo(\n                    width = image.width,\n                    height = image.height,\n                    imageFormat = imageFormat\n                )\n            )\n            val normalization = 2048 * (initialSize / (5 * 1024 * 1024)).coerceAtLeast(1)\n\n            val targetSize = (maxBytes - normalization).coerceAtLeast(1024)\n\n            if (initialSize > targetSize) {\n                var outArray = ByteArray(initialSize.toInt())\n                var compressQuality = 100\n                var newSize = image.size()\n\n                if (imageFormat.canChangeCompressionValue) {\n                    while (outArray.size > targetSize) {\n                        ensureActive()\n                        outArray = imageCompressor.compressAndTransform(\n                            image = image,\n                            imageInfo = ImageInfo(\n                                width = newSize.width,\n                                height = newSize.height,\n                                quality = Quality.Base(compressQuality),\n                                imageFormat = imageFormat\n                            )\n                        )\n                        compressQuality -= 1\n\n                        if (compressQuality < 15) break\n                    }\n\n                    compressQuality = 15\n                }\n\n                while (outArray.size > targetSize) {\n                    ensureActive()\n\n                    newSize = scaleImage(\n                        image = image,\n                        width = (newSize.width * 0.93f).roundToInt(),\n                        height = (newSize.height * 0.93f).roundToInt(),\n                        imageScaleMode = imageScaleMode\n                    ).size()\n\n                    outArray = imageCompressor.compressAndTransform(\n                        image = image,\n                        imageInfo = ImageInfo(\n                            quality = Quality.Base(compressQuality),\n                            imageFormat = imageFormat,\n                            width = newSize.width,\n                            height = newSize.height\n                        )\n                    )\n                }\n\n                outArray to ImageInfo(\n                    width = newSize.width,\n                    height = newSize.height,\n                    imageFormat = imageFormat\n                )\n            } else null\n        }.getOrNull()\n    }\n\n    private fun Bitmap.size(): IntegerSize = IntegerSize(width, height)\n}"
  },
  {
    "path": "feature/weight-resize/src/main/java/com/t8rin/imagetoolbox/feature/weight_resize/di/WeightResizeModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.weight_resize.di\n\nimport android.graphics.Bitmap\nimport com.t8rin.imagetoolbox.feature.weight_resize.data.AndroidWeightImageScaler\nimport com.t8rin.imagetoolbox.feature.weight_resize.domain.WeightImageScaler\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface WeightResizeModule {\n\n    @Singleton\n    @Binds\n    fun provideScaler(\n        scaler: AndroidWeightImageScaler\n    ): WeightImageScaler<Bitmap>\n\n}"
  },
  {
    "path": "feature/weight-resize/src/main/java/com/t8rin/imagetoolbox/feature/weight_resize/domain/WeightImageScaler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.weight_resize.domain\n\nimport com.t8rin.imagetoolbox.core.domain.image.ImageScaler\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\n\ninterface WeightImageScaler<I> : ImageScaler<I> {\n\n    suspend fun scaleByMaxBytes(\n        image: I,\n        imageFormat: ImageFormat,\n        imageScaleMode: ImageScaleMode,\n        maxBytes: Long\n    ): Pair<ByteArray, ImageInfo>?\n\n}"
  },
  {
    "path": "feature/weight-resize/src/main/java/com/t8rin/imagetoolbox/feature/weight_resize/presentation/WeightResizeContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.weight_resize.presentation\n\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormatGroup\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.Picker\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberImagePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.ImageUtils.restrict\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.PanModeButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ShareButton\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.ZoomButton\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.SaveExifWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ImageFormatSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.PresetSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.controls.selection.ScaleModeSelector\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeImagePickingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.OneTimeSaveLocationSelectionDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageContainer\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageCounter\nimport com.t8rin.imagetoolbox.core.ui.widget.image.ImageNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.detectSwipes\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.PickImageFromUrisSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.sheets.ZoomModalSheet\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.core.ui.widget.text.TopAppBarTitle\nimport com.t8rin.imagetoolbox.core.ui.widget.utils.AutoContentBasedColors\nimport com.t8rin.imagetoolbox.feature.weight_resize.presentation.components.ImageFormatAlert\nimport com.t8rin.imagetoolbox.feature.weight_resize.presentation.screenLogic.WeightResizeComponent\n\n@Composable\nfun WeightResizeContent(\n    component: WeightResizeComponent\n) {\n    AutoContentBasedColors(component.bitmap)\n\n    val imagePicker = rememberImagePicker { uris: List<Uri> ->\n        component.setUris(\n            uris = uris\n        )\n    }\n\n    val pickImage = imagePicker::pickImage\n\n    AutoFilePicker(\n        onAutoPick = pickImage,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.haveChanges) showExitDialog = true\n        else component.onGoBack()\n    }\n\n\n    val saveBitmaps: (oneTimeSaveLocationUri: String?) -> Unit = {\n        component.saveBitmaps(\n            oneTimeSaveLocationUri = it\n        )\n    }\n\n    var showPickImageFromUrisSheet by rememberSaveable { mutableStateOf(false) }\n\n    val isPortrait by isPortraitOrientationAsState()\n\n    var showZoomSheet by rememberSaveable { mutableStateOf(false) }\n\n    ZoomModalSheet(\n        data = component.previewBitmap,\n        visible = showZoomSheet,\n        onDismiss = {\n            showZoomSheet = false\n        }\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !component.haveChanges,\n        title = {\n            TopAppBarTitle(\n                title = stringResource(R.string.by_bytes_resize),\n                input = component.bitmap,\n                isLoading = component.isImageLoading,\n                size = component.imageSize\n            )\n        },\n        onGoBack = onBack,\n        actions = {},\n        topAppBarPersistentActions = {\n            if (component.bitmap == null) {\n                TopAppBarEmoji()\n            }\n            ZoomButton(\n                onClick = { showZoomSheet = true },\n                visible = component.bitmap != null,\n            )\n            if (component.previewBitmap != null) {\n                var editSheetData by remember {\n                    mutableStateOf(listOf<Uri>())\n                }\n                ShareButton(\n                    enabled = component.canSave,\n                    onShare = component::shareBitmaps,\n                    onCopy = {\n                        component.cacheCurrentImage(Clipboard::copy)\n                    },\n                    onEdit = {\n                        component.cacheImages {\n                            editSheetData = it\n                        }\n                    }\n                )\n                ProcessImagesPreferenceSheet(\n                    uris = editSheetData,\n                    visible = editSheetData.isNotEmpty(),\n                    onDismiss = {\n                        editSheetData = emptyList()\n                    },\n                    onNavigate = component.onNavigate\n                )\n            }\n        },\n        imagePreview = {\n            ImageContainer(\n                modifier = Modifier\n                    .detectSwipes(\n                        onSwipeRight = component::selectLeftUri,\n                        onSwipeLeft = component::selectRightUri\n                    ),\n                imageInside = isPortrait,\n                showOriginal = false,\n                previewBitmap = component.previewBitmap,\n                originalBitmap = component.bitmap,\n                isLoading = component.isImageLoading,\n                shouldShowPreview = true\n            )\n        },\n        controls = {\n            ImageCounter(\n                imageCount = component.uris?.size?.takeIf { it > 1 },\n                onRepick = {\n                    showPickImageFromUrisSheet = true\n                }\n            )\n            AnimatedContent(\n                targetState = component.handMode,\n                transitionSpec = {\n                    if (!targetState) {\n                        slideInVertically { it } + fadeIn() togetherWith slideOutVertically { -it } + fadeOut()\n                    } else {\n                        slideInVertically { -it } + fadeIn() togetherWith slideOutVertically { it } + fadeOut()\n                    }\n                }\n            ) { handMode ->\n                if (handMode) {\n                    RoundedTextField(\n                        modifier = Modifier\n                            .container(\n                                shape = MaterialTheme.shapes.large,\n                                resultPadding = 8.dp\n                            ),\n                        enabled = component.bitmap != null,\n                        value = (component.maxBytes / 1024).toString()\n                            .takeIf { it != \"0\" } ?: \"\",\n                        onValueChange = {\n                            component.updateMaxBytes(\n                                it.restrict(1_000_000)\n                            )\n                        },\n                        keyboardOptions = KeyboardOptions(\n                            keyboardType = KeyboardType.Number\n                        ),\n                        label = stringResource(R.string.max_bytes)\n                    )\n                } else {\n                    PresetSelector(\n                        value = component.presetSelected.takeIf { it > 0 }?.let {\n                            Preset.Percentage(it)\n                        } ?: Preset.None,\n                        includeTelegramOption = false,\n                        onValueChange = component::selectPreset,\n                        isBytesResize = true\n                    )\n                }\n            }\n            Spacer(Modifier.height(8.dp))\n            SaveExifWidget(\n                imageFormat = component.imageFormat,\n                checked = component.keepExif,\n                onCheckedChange = component::setKeepExif\n            )\n            AnimatedVisibility(\n                visible = component.imageFormat.canChangeCompressionValue\n            ) {\n                Spacer(Modifier.height(8.dp))\n            }\n            ImageFormatAlert(\n                format = component.imageFormat,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(vertical = 8.dp)\n            )\n            ImageFormatSelector(\n                value = component.imageFormat,\n                onValueChange = component::setImageFormat,\n                entries = remember {\n                    ImageFormatGroup.entries\n                        .minus(ImageFormatGroup.Png)\n                        .plus(\n                            ImageFormatGroup.Custom(\n                                title = \"PNG Lossless\",\n                                formats = listOf(\n                                    ImageFormat.Png.Lossless\n                                )\n                            )\n                        )\n                }\n            )\n            Spacer(Modifier.height(8.dp))\n            ScaleModeSelector(\n                value = component.imageScaleMode,\n                onValueChange = component::setImageScaleMode\n            )\n        },\n        buttons = {\n            var showFolderSelectionDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            var showOneTimeImagePickingDialog by rememberSaveable {\n                mutableStateOf(false)\n            }\n            BottomButtonsBlock(\n                isNoData = component.uris.isNullOrEmpty(),\n                onSecondaryButtonClick = pickImage,\n                onPrimaryButtonClick = {\n                    saveBitmaps(null)\n                },\n                onPrimaryButtonLongClick = {\n                    showFolderSelectionDialog = true\n                },\n                isPrimaryButtonVisible = component.canSave,\n                actions = {\n                    PanModeButton(\n                        selected = component.handMode,\n                        onClick = component::updateHandMode\n                    )\n                },\n                onSecondaryButtonLongClick = {\n                    showOneTimeImagePickingDialog = true\n                }\n            )\n            OneTimeSaveLocationSelectionDialog(\n                visible = showFolderSelectionDialog,\n                onDismiss = { showFolderSelectionDialog = false },\n                onSaveRequest = saveBitmaps,\n                formatForFilenameSelection = component.getFormatForFilenameSelection()\n            )\n            OneTimeImagePickingDialog(\n                onDismiss = { showOneTimeImagePickingDialog = false },\n                picker = Picker.Multiple,\n                imagePicker = imagePicker,\n                visible = showOneTimeImagePickingDialog\n            )\n        },\n        canShowScreenData = component.bitmap != null,\n        noDataControls = {\n            if (!component.isImageLoading) {\n                ImageNotPickedWidget(onPickImage = pickImage)\n            }\n        }\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.uris?.size ?: 1,\n        onCancelLoading = component::cancelSaving\n    )\n\n    PickImageFromUrisSheet(\n        visible = showPickImageFromUrisSheet,\n        onDismiss = {\n            showPickImageFromUrisSheet = false\n        },\n        uris = component.uris,\n        selectedUri = component.selectedUri,\n        onUriPicked = component::updateSelectedUri,\n        onUriRemoved = component::updateUrisSilently,\n        columns = if (isPortrait) 2 else 4,\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n}"
  },
  {
    "path": "feature/weight-resize/src/main/java/com/t8rin/imagetoolbox/feature/weight_resize/presentation/components/ImageFormatAlert.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.weight_resize.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\n\n@Composable\ninternal fun ImageFormatAlert(\n    format: ImageFormat,\n    modifier: Modifier = Modifier\n) {\n    AnimatedVisibility(!format.canChangeCompressionValue) {\n        Box(\n            modifier = modifier\n                .container(\n                    shape = ShapeDefaults.large,\n                    borderColor = MaterialTheme.colorScheme.onErrorContainer.copy(\n                        0.4f\n                    ),\n                    color = MaterialTheme.colorScheme.errorContainer.copy(\n                        alpha = 0.7f\n                    )\n                ),\n            contentAlignment = Alignment.Center\n        ) {\n            Text(\n                text = stringResource(R.string.warning_bytes, format.title),\n                fontSize = 12.sp,\n                modifier = Modifier.padding(8.dp),\n                textAlign = TextAlign.Center,\n                fontWeight = FontWeight.SemiBold,\n                lineHeight = 14.sp,\n                color = MaterialTheme.colorScheme.onErrorContainer.copy(alpha = 0.5f)\n            )\n        }\n    }\n}"
  },
  {
    "path": "feature/weight-resize/src/main/java/com/t8rin/imagetoolbox/feature/weight_resize/presentation/screenLogic/WeightResizeComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.weight_resize.presentation.screenLogic\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableLongStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.core.net.toUri\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ImageCompressor\nimport com.t8rin.imagetoolbox.core.domain.image.ImageGetter\nimport com.t8rin.imagetoolbox.core.domain.image.ImageShareProvider\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageData\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageInfo\nimport com.t8rin.imagetoolbox.core.domain.image.model.ImageScaleMode\nimport com.t8rin.imagetoolbox.core.domain.image.model.Preset\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.FilenameCreator\nimport com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget\nimport com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult\nimport com.t8rin.imagetoolbox.core.domain.saving.model.onSuccess\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.leftFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.ListUtils.rightFrom\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.weight_resize.domain.WeightImageScaler\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\n\nclass WeightResizeComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    @Assisted val onNavigate: (Screen) -> Unit,\n    private val fileController: FileController,\n    private val filenameCreator: FilenameCreator,\n    private val imageGetter: ImageGetter<Bitmap>,\n    private val imageCompressor: ImageCompressor<Bitmap>,\n    private val imageScaler: WeightImageScaler<Bitmap>,\n    private val shareProvider: ImageShareProvider<Bitmap>,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n        }\n    }\n\n    private val _imageScaleMode: MutableState<ImageScaleMode> =\n        mutableStateOf(ImageScaleMode.Default)\n    val imageScaleMode by _imageScaleMode\n\n    private val _imageSize: MutableState<Long> = mutableLongStateOf(0L)\n    val imageSize by _imageSize\n\n    private val _canSave = mutableStateOf(false)\n    val canSave by _canSave\n\n    private val _presetSelected: MutableState<Int> = mutableIntStateOf(-1)\n    val presetSelected by _presetSelected\n\n    private val _handMode = mutableStateOf(true)\n    val handMode by _handMode\n\n    private val _uris = mutableStateOf<List<Uri>?>(null)\n    val uris by _uris\n\n    private val _bitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val bitmap: Bitmap? by _bitmap\n\n    private val _keepExif = mutableStateOf(false)\n    val keepExif by _keepExif\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving: Boolean by _isSaving\n\n    private val _previewBitmap: MutableState<Bitmap?> = mutableStateOf(null)\n    val previewBitmap: Bitmap? by _previewBitmap\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _selectedUri: MutableState<Uri?> = mutableStateOf(null)\n    val selectedUri by _selectedUri\n\n    private val _maxBytes: MutableState<Long> = mutableLongStateOf(0L)\n    val maxBytes by _maxBytes\n\n    private val _imageFormat = mutableStateOf(ImageFormat.Default)\n    val imageFormat by _imageFormat\n\n    fun setImageFormat(imageFormat: ImageFormat) {\n        if (_imageFormat.value != imageFormat) {\n            _imageFormat.value = imageFormat\n            componentScope.launch {\n                _bitmap.value?.let {\n                    _isImageLoading.value = true\n                    _imageSize.value = imageCompressor.calculateImageSize(\n                        image = it,\n                        imageInfo = ImageInfo(imageFormat = imageFormat)\n                    )\n                    _isImageLoading.value = false\n                }\n            }\n            registerChanges()\n        }\n    }\n\n    fun setUris(\n        uris: List<Uri>?\n    ) {\n        _uris.value = null\n        _uris.value = uris\n        _selectedUri.value = uris?.firstOrNull()\n        if (uris != null) {\n            _isImageLoading.value = true\n            imageGetter.getImageAsync(\n                uri = uris[0].toString(),\n                originalSize = true,\n                onGetImage = ::setImageData,\n                onFailure = {\n                    _isImageLoading.value = false\n                    AppToastHost.showFailureToast(it)\n                }\n            )\n        }\n    }\n\n    fun updateUrisSilently(removedUri: Uri) {\n        componentScope.launch {\n            _uris.value = uris\n            if (_selectedUri.value == removedUri) {\n                val index = uris?.indexOf(removedUri) ?: -1\n                if (index == 0) {\n                    uris?.getOrNull(1)?.let {\n                        _selectedUri.value = it\n                        _bitmap.value = imageGetter.getImage(it.toString())?.image\n                    }\n                } else {\n                    uris?.getOrNull(index - 1)?.let {\n                        _selectedUri.value = it\n                        _bitmap.value = imageGetter.getImage(it.toString())?.image\n                    }\n                }\n            }\n            val u = _uris.value?.toMutableList()?.apply {\n                remove(removedUri)\n            }\n            _uris.value = u\n        }\n    }\n\n\n    private fun updateBitmap(bitmap: Bitmap?) {\n        componentScope.launch {\n            _isImageLoading.value = true\n            _bitmap.value = bitmap\n            _previewBitmap.value = imageScaler.scaleUntilCanShow(bitmap)\n            _isImageLoading.value = false\n        }\n    }\n\n    fun setKeepExif(boolean: Boolean) {\n        _keepExif.value = boolean\n        registerChanges()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun saveBitmaps(\n        oneTimeSaveLocationUri: String?\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            val results = mutableListOf<SaveResult>()\n            _done.value = 0\n            uris?.forEach { uri ->\n                runSuspendCatching {\n                    imageGetter.getImage(uri.toString())\n                }.getOrNull()?.image?.let { bitmap ->\n                    runSuspendCatching {\n                        if (handMode) {\n                            imageScaler.scaleByMaxBytes(\n                                image = bitmap,\n                                maxBytes = maxBytes,\n                                imageFormat = imageFormat,\n                                imageScaleMode = imageScaleMode\n                            )\n                        } else {\n                            imageScaler.scaleByMaxBytes(\n                                image = bitmap,\n                                maxBytes = (fileController.getSize(uri.toString()) ?: 0)\n                                    .times(presetSelected / 100f)\n                                    .toLong(),\n                                imageFormat = imageFormat,\n                                imageScaleMode = imageScaleMode\n                            )\n                        }\n                    }.getOrNull()?.let { (data, imageInfo) ->\n\n                        results.add(\n                            fileController.save(\n                                ImageSaveTarget(\n                                    imageInfo = imageInfo,\n                                    originalUri = uri.toString(),\n                                    sequenceNumber = _done.value + 1,\n                                    data = data\n                                ),\n                                keepOriginalMetadata = keepExif,\n                                oneTimeSaveLocationUri = oneTimeSaveLocationUri\n                            )\n                        )\n                    }\n                } ?: results.add(\n                    SaveResult.Error.Exception(Throwable())\n                )\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            parseSaveResults(results.onSuccess(::registerSave))\n            _isSaving.value = false\n        }\n    }\n\n    fun updateSelectedUri(\n        uri: Uri\n    ) {\n        runCatching {\n            componentScope.launch {\n                updateBitmap(\n                    imageGetter.getImage(\n                        uri = uri.toString(),\n                        originalSize = false\n                    )?.image\n                )\n                _selectedUri.value = uri\n            }\n        }.onFailure(AppToastHost::showFailureToast)\n    }\n\n    private fun updateCanSave() {\n        _canSave.value =\n            _bitmap.value != null && (_maxBytes.value != 0L && _handMode.value || !_handMode.value && _presetSelected.value != -1)\n\n        registerChanges()\n    }\n\n    fun updateMaxBytes(newBytes: String) {\n        val b = newBytes.toLongOrNull() ?: 0\n        _maxBytes.value = b * 1024\n        updateCanSave()\n    }\n\n    fun selectPreset(preset: Preset) {\n        preset.value()?.let { _presetSelected.value = it }\n        updateCanSave()\n    }\n\n    fun updateHandMode() {\n        _handMode.value = !_handMode.value\n        updateCanSave()\n    }\n\n    fun shareBitmaps() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            shareProvider.shareImages(\n                uris = uris?.map { it.toString() } ?: emptyList(),\n                imageLoader = { uri ->\n                    imageGetter.getImage(uri)?.image?.let { bitmap ->\n                        if (handMode) {\n                            imageScaler.scaleByMaxBytes(\n                                image = bitmap,\n                                maxBytes = maxBytes,\n                                imageFormat = imageFormat,\n                                imageScaleMode = imageScaleMode\n                            )\n                        } else {\n                            imageScaler.scaleByMaxBytes(\n                                image = bitmap,\n                                maxBytes = (fileController.getSize(uri) ?: 0)\n                                    .times(presetSelected / 100f)\n                                    .toLong(),\n                                imageFormat = imageFormat,\n                                imageScaleMode = imageScaleMode\n                            )\n                        }\n                    }?.let { (data, imageInfo) ->\n                        imageGetter.getImage(data)!! to imageInfo\n                    }\n                },\n                onProgressChange = {\n                    if (it == -1) {\n                        AppToastHost.showConfetti()\n                        _isSaving.value = false\n                        _done.value = 0\n                    } else {\n                        _done.value = it\n                    }\n                    updateProgress(\n                        done = done,\n                        total = uris.orEmpty().size\n                    )\n                }\n            )\n        }\n    }\n\n    private var job: Job? by smartJob {\n        _isImageLoading.update { false }\n    }\n\n    private fun setImageData(imageData: ImageData<Bitmap>) {\n        job = componentScope.launch {\n            _isImageLoading.value = true\n            imageScaler.scaleUntilCanShow(imageData.image)?.let {\n                _bitmap.value = imageData.image\n                _previewBitmap.value = it\n                _imageFormat.value = imageData.imageInfo.imageFormat\n                _imageSize.value = imageCompressor.calculateImageSize(\n                    image = imageData.image,\n                    imageInfo = ImageInfo(\n                        width = imageData.image.width,\n                        height = imageData.image.height,\n                        imageFormat = imageFormat\n                    )\n                )\n            }\n            _isImageLoading.value = false\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun setImageScaleMode(imageScaleMode: ImageScaleMode) {\n        _imageScaleMode.update { imageScaleMode }\n        updateCanSave()\n    }\n\n    fun cacheCurrentImage(onComplete: (Uri) -> Unit) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            selectedUri?.toString()?.let { uri ->\n                imageGetter.getImage(uri)?.image?.let { bitmap ->\n                    if (handMode) {\n                        imageScaler.scaleByMaxBytes(\n                            image = bitmap,\n                            maxBytes = maxBytes,\n                            imageFormat = imageFormat,\n                            imageScaleMode = imageScaleMode\n                        )\n                    } else {\n                        imageScaler.scaleByMaxBytes(\n                            image = bitmap,\n                            maxBytes = (fileController.getSize(uri) ?: 0)\n                                .times(presetSelected / 100f)\n                                .toLong(),\n                            imageFormat = imageFormat,\n                            imageScaleMode = imageScaleMode\n                        )\n                    }\n                }?.let { scaled ->\n                    scaled.first to scaled.second.copy(imageFormat = imageFormat)\n                }?.let { (image, imageInfo) ->\n                    shareProvider.cacheByteArray(\n                        byteArray = image,\n                        filename = filenameCreator.constructImageFilename(\n                            ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                originalUri = uri,\n                                sequenceNumber = _done.value + 1,\n                                data = image\n                            )\n                        )\n                    )?.let { uri ->\n                        onComplete(uri.toUri())\n                    }\n                }\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun cacheImages(\n        onComplete: (List<Uri>) -> Unit\n    ) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _done.value = 0\n            val list = mutableListOf<Uri>()\n            uris?.forEach { uri ->\n                imageGetter.getImage(uri.toString())?.image?.let { bitmap ->\n                    if (handMode) {\n                        imageScaler.scaleByMaxBytes(\n                            image = bitmap,\n                            maxBytes = maxBytes,\n                            imageFormat = imageFormat,\n                            imageScaleMode = imageScaleMode\n                        )\n                    } else {\n                        imageScaler.scaleByMaxBytes(\n                            image = bitmap,\n                            maxBytes = (fileController.getSize(uri.toString()) ?: 0)\n                                .times(presetSelected / 100f)\n                                .toLong(),\n                            imageFormat = imageFormat,\n                            imageScaleMode = imageScaleMode\n                        )\n                    }\n                }?.let { scaled ->\n                    scaled.first to scaled.second.copy(imageFormat = imageFormat)\n                }?.let { (image, imageInfo) ->\n                    shareProvider.cacheByteArray(\n                        byteArray = image,\n                        filename = filenameCreator.constructImageFilename(\n                            ImageSaveTarget(\n                                imageInfo = imageInfo,\n                                originalUri = uri.toString(),\n                                sequenceNumber = _done.value + 1,\n                                data = image\n                            )\n                        )\n                    )?.let { uri ->\n                        list.add(uri.toUri())\n                    }\n                }\n                _done.value += 1\n                updateProgress(\n                    done = done,\n                    total = uris.orEmpty().size\n                )\n            }\n            onComplete(list)\n            _isSaving.value = false\n        }\n    }\n\n    fun selectLeftUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.leftFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun selectRightUri() {\n        uris\n            ?.indexOf(selectedUri ?: Uri.EMPTY)\n            ?.takeIf { it >= 0 }\n            ?.let {\n                uris?.rightFrom(it)\n            }\n            ?.let(::updateSelectedUri)\n    }\n\n    fun getFormatForFilenameSelection(): ImageFormat? =\n        if (uris?.size == 1) imageFormat\n        else null\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n            onNavigate: (Screen) -> Unit,\n        ): WeightResizeComponent\n    }\n}"
  },
  {
    "path": "feature/zip/.gitignore",
    "content": "/build"
  },
  {
    "path": "feature/zip/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.feature)\n    alias(libs.plugins.image.toolbox.hilt)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.imagetoolbox.feature.zip\""
  },
  {
    "path": "feature/zip/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "feature/zip/src/main/java/com/t8rin/imagetoolbox/feature/zip/data/AndroidZipManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.zip.data\n\nimport android.content.Context\nimport androidx.core.net.toUri\nimport com.t8rin.imagetoolbox.core.data.saving.io.UriReadable\nimport com.t8rin.imagetoolbox.core.data.utils.outputStream\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.utils.createZip\nimport com.t8rin.imagetoolbox.core.utils.filename\nimport com.t8rin.imagetoolbox.core.utils.putEntry\nimport com.t8rin.imagetoolbox.feature.zip.domain.ZipManager\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\n\ninternal class AndroidZipManager @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val shareProvider: ShareProvider,\n    dispatchersHolder: DispatchersHolder\n) : DispatchersHolder by dispatchersHolder, ZipManager {\n\n    override suspend fun zip(\n        files: List<String>,\n        onProgress: () -> Unit\n    ): String = withContext(defaultDispatcher) {\n        shareProvider.cacheData(\n            writeData = { writeable ->\n                writeable.outputStream().createZip { output ->\n                    for (file in files) {\n                        output.putEntry(\n                            name = file.toUri().filename(context) ?: continue,\n                            input = UriReadable(file.toUri(), context).stream\n                        )\n                        onProgress()\n                    }\n                }\n            },\n            filename = files.firstOrNull()?.toUri()?.filename() ?: \"temp.zip\"\n        ) ?: throw IllegalArgumentException(\"Cached to null file\")\n    }\n\n}"
  },
  {
    "path": "feature/zip/src/main/java/com/t8rin/imagetoolbox/feature/zip/di/ZipModule.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.zip.di\n\nimport com.t8rin.imagetoolbox.feature.zip.data.AndroidZipManager\nimport com.t8rin.imagetoolbox.feature.zip.domain.ZipManager\nimport dagger.Binds\nimport dagger.Module\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\ninternal interface ZipModule {\n\n    @Singleton\n    @Binds\n    fun provideZipManager(\n        manager: AndroidZipManager\n    ): ZipManager\n\n}"
  },
  {
    "path": "feature/zip/src/main/java/com/t8rin/imagetoolbox/feature/zip/domain/ZipManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.zip.domain\n\ninterface ZipManager {\n\n    suspend fun zip(\n        files: List<String>,\n        onProgress: () -> Unit\n    ): String\n\n}"
  },
  {
    "path": "feature/zip/src/main/java/com/t8rin/imagetoolbox/feature/zip/presentation/ZipContent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.zip.presentation\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.FileOpen\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.AdaptiveLayoutScreen\nimport com.t8rin.imagetoolbox.core.ui.widget.buttons.BottomButtonsBlock\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.ExitWithoutSavingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.dialogs.LoadingDialog\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip\nimport com.t8rin.imagetoolbox.core.ui.widget.image.AutoFilePicker\nimport com.t8rin.imagetoolbox.core.ui.widget.image.FileNotPickedWidget\nimport com.t8rin.imagetoolbox.core.ui.widget.other.TopAppBarEmoji\nimport com.t8rin.imagetoolbox.core.ui.widget.text.marquee\nimport com.t8rin.imagetoolbox.feature.zip.presentation.components.ZipControls\nimport com.t8rin.imagetoolbox.feature.zip.presentation.screenLogic.ZipComponent\n\n\n@Composable\nfun ZipContent(\n    component: ZipComponent\n) {\n    var showExitDialog by rememberSaveable { mutableStateOf(false) }\n\n    val onBack = {\n        if (component.uris.isNotEmpty() && component.compressedArchiveUri != null) {\n            showExitDialog = true\n        } else component.onGoBack()\n    }\n\n    val filePicker = rememberFilePicker(onSuccess = component::setUris)\n\n    AutoFilePicker(\n        onAutoPick = filePicker::pickFile,\n        isPickedAlready = !component.initialUris.isNullOrEmpty()\n    )\n\n    AdaptiveLayoutScreen(\n        shouldDisableBackHandler = !(component.uris.isNotEmpty() && component.compressedArchiveUri != null),\n        title = {\n            Text(\n                text = stringResource(R.string.zip),\n                modifier = Modifier.marquee()\n            )\n        },\n        topAppBarPersistentActions = {\n            TopAppBarEmoji()\n        },\n        onGoBack = onBack,\n        actions = {},\n        imagePreview = {},\n        showImagePreviewAsStickyHeader = false,\n        placeImagePreview = false,\n        addHorizontalCutoutPaddingIfNoPreview = false,\n        noDataControls = {\n            FileNotPickedWidget(onPickFile = filePicker::pickFile)\n        },\n        controls = {\n            ZipControls(\n                component = component,\n                lazyListState = it\n            )\n        },\n        buttons = {\n            BottomButtonsBlock(\n                isNoData = component.uris.isEmpty(),\n                onSecondaryButtonClick = filePicker::pickFile,\n                secondaryButtonIcon = Icons.Rounded.FileOpen,\n                secondaryButtonText = stringResource(R.string.pick_file),\n                isPrimaryButtonVisible = component.uris.isNotEmpty(),\n                onPrimaryButtonClick = component::startCompression,\n                actions = {\n                    EnhancedChip(\n                        selected = true,\n                        onClick = null,\n                        selectedColor = MaterialTheme.colorScheme.secondaryContainer,\n                        modifier = Modifier.padding(8.dp)\n                    ) {\n                        Text(component.uris.size.toString())\n                    }\n                }\n            )\n        },\n        canShowScreenData = component.uris.isNotEmpty()\n    )\n\n    ExitWithoutSavingDialog(\n        onExit = component.onGoBack,\n        onDismiss = { showExitDialog = false },\n        visible = showExitDialog\n    )\n\n    LoadingDialog(\n        visible = component.isSaving,\n        done = component.done,\n        left = component.left,\n        onCancelLoading = component::cancelSaving\n    )\n\n}"
  },
  {
    "path": "feature/zip/src/main/java/com/t8rin/imagetoolbox/feature/zip/presentation/components/ZipControls.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.zip.presentation.components\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.rounded.CheckCircle\nimport androidx.compose.material.icons.rounded.FileDownload\nimport androidx.compose.material.icons.rounded.Share\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.imagetoolbox.core.domain.model.MimeType\nimport com.t8rin.imagetoolbox.core.domain.utils.timestamp\nimport com.t8rin.imagetoolbox.core.resources.R\nimport com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState\nimport com.t8rin.imagetoolbox.core.ui.theme.Green\nimport com.t8rin.imagetoolbox.core.ui.theme.outlineVariant\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFileCreator\nimport com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFilePicker\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.isPortraitOrientationAsState\nimport com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton\nimport com.t8rin.imagetoolbox.core.ui.widget.image.UrisPreview\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults\nimport com.t8rin.imagetoolbox.core.ui.widget.modifier.container\nimport com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText\nimport com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField\nimport com.t8rin.imagetoolbox.feature.zip.presentation.screenLogic.ZipComponent\n\n@Composable\ninternal fun ColumnScope.ZipControls(\n    component: ZipComponent,\n    lazyListState: LazyListState\n) {\n    val isPortrait by isPortraitOrientationAsState()\n    val settingsState = LocalSettingsState.current\n\n    val saveLauncher = rememberFileCreator(\n        mimeType = MimeType.Zip,\n        onSuccess = component::saveResultTo\n    )\n\n    val additionalFilePicker = rememberFilePicker(onSuccess = component::addUris)\n\n    AnimatedVisibility(visible = component.compressedArchiveUri != null) {\n        LaunchedEffect(lazyListState) {\n            lazyListState.animateScrollToItem(0)\n        }\n        Column(\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(top = 24.dp)\n                .container(\n                    shape = MaterialTheme.shapes.extraLarge,\n                    color = MaterialTheme\n                        .colorScheme\n                        .surfaceContainerHighest,\n                    resultPadding = 0.dp\n                )\n                .padding(16.dp)\n        ) {\n            Row(verticalAlignment = Alignment.CenterVertically) {\n                Icon(\n                    imageVector = Icons.Rounded.CheckCircle,\n                    contentDescription = null,\n                    tint = Green,\n                    modifier = Modifier\n                        .size(36.dp)\n                        .background(\n                            color = MaterialTheme.colorScheme.surface,\n                            shape = ShapeDefaults.circle\n                        )\n                        .border(\n                            width = settingsState.borderWidth,\n                            color = MaterialTheme.colorScheme.outlineVariant(),\n                            shape = ShapeDefaults.circle\n                        )\n                        .padding(4.dp)\n                )\n                Spacer(modifier = Modifier.width(16.dp))\n                Text(\n                    stringResource(R.string.file_proceed),\n                    fontSize = 17.sp,\n                    fontWeight = FontWeight.Medium\n                )\n            }\n            Text(\n                text = stringResource(R.string.store_file_desc),\n                fontSize = 13.sp,\n                color = LocalContentColor.current.copy(alpha = 0.7f),\n                lineHeight = 14.sp,\n                modifier = Modifier.padding(vertical = 16.dp)\n            )\n            var name by rememberSaveable(component.compressedArchiveUri, component.uris) {\n                val count = component.uris.size.let {\n                    if (it > 1) \"($it)\"\n                    else \"\"\n                }\n                mutableStateOf(\"ZIP${count}_${timestamp()}.zip\")\n            }\n            RoundedTextField(\n                modifier = Modifier\n                    .padding(top = 8.dp)\n                    .container(\n                        shape = MaterialTheme.shapes.large,\n                        resultPadding = 8.dp\n                    ),\n                value = name,\n                keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),\n                singleLine = false,\n                onValueChange = { name = it },\n                label = {\n                    Text(stringResource(R.string.filename))\n                }\n            )\n\n            Row(\n                modifier = Modifier\n                    .padding(top = 24.dp)\n                    .fillMaxWidth()\n            ) {\n                EnhancedButton(\n                    onClick = {\n                        saveLauncher.make(name)\n                    },\n                    modifier = Modifier\n                        .padding(end = 8.dp)\n                        .fillMaxWidth(0.5f)\n                        .height(50.dp),\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer\n                ) {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.Center\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.FileDownload,\n                            contentDescription = null\n                        )\n                        Spacer(modifier = Modifier.width(8.dp))\n                        AutoSizeText(\n                            text = stringResource(id = R.string.save),\n                            maxLines = 1\n                        )\n                    }\n                }\n                EnhancedButton(\n                    onClick = component::shareFile,\n                    modifier = Modifier\n                        .padding(start = 8.dp)\n                        .fillMaxWidth()\n                        .height(50.dp),\n                    containerColor = MaterialTheme.colorScheme.secondaryContainer\n                ) {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.Center\n                    ) {\n                        Icon(\n                            imageVector = Icons.Rounded.Share,\n                            contentDescription = stringResource(R.string.share)\n                        )\n                        Spacer(modifier = Modifier.width(8.dp))\n                        AutoSizeText(\n                            text = stringResource(id = R.string.share),\n                            maxLines = 1\n                        )\n                    }\n                }\n            }\n        }\n    }\n    Spacer(modifier = Modifier.height(24.dp))\n    UrisPreview(\n        uris = component.uris,\n        isPortrait = isPortrait,\n        onRemoveUri = component::removeUri,\n        onAddUris = additionalFilePicker::pickFile\n    )\n}"
  },
  {
    "path": "feature/zip/src/main/java/com/t8rin/imagetoolbox/feature/zip/presentation/screenLogic/ZipComponent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.imagetoolbox.feature.zip.presentation.screenLogic\n\nimport android.net.Uri\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport com.arkivanov.decompose.ComponentContext\nimport com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder\nimport com.t8rin.imagetoolbox.core.domain.image.ShareProvider\nimport com.t8rin.imagetoolbox.core.domain.saving.FileController\nimport com.t8rin.imagetoolbox.core.domain.saving.updateProgress\nimport com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching\nimport com.t8rin.imagetoolbox.core.domain.utils.smartJob\nimport com.t8rin.imagetoolbox.core.ui.utils.BaseComponent\nimport com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost\nimport com.t8rin.imagetoolbox.core.ui.utils.state.update\nimport com.t8rin.imagetoolbox.feature.zip.domain.ZipManager\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport kotlinx.coroutines.Job\n\nclass ZipComponent @AssistedInject internal constructor(\n    @Assisted componentContext: ComponentContext,\n    @Assisted val initialUris: List<Uri>?,\n    @Assisted val onGoBack: () -> Unit,\n    private val zipManager: ZipManager,\n    private val shareProvider: ShareProvider,\n    private val fileController: FileController,\n    dispatchersHolder: DispatchersHolder\n) : BaseComponent(dispatchersHolder, componentContext) {\n\n    init {\n        debounce {\n            initialUris?.let(::setUris)\n        }\n    }\n\n    private val _uris = mutableStateOf<List<Uri>>(emptyList())\n    val uris by _uris\n\n    private val _compressedArchiveUri = mutableStateOf<String?>(null)\n    val compressedArchiveUri by _compressedArchiveUri\n\n    private val _isSaving: MutableState<Boolean> = mutableStateOf(false)\n    val isSaving by _isSaving\n\n    private val _done: MutableState<Int> = mutableIntStateOf(0)\n    val done by _done\n\n    private val _left: MutableState<Int> = mutableIntStateOf(-1)\n    val left by _left\n\n    fun setUris(newUris: List<Uri>) {\n        _uris.update { newUris.distinct() }\n        resetCalculatedData()\n    }\n\n    private var savingJob: Job? by smartJob {\n        _isSaving.update { false }\n    }\n\n    fun startCompression() {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            if (uris.isEmpty()) {\n                return@trackProgress\n            }\n            runSuspendCatching {\n                _done.update { 0 }\n                _left.update { uris.size }\n                _compressedArchiveUri.value = zipManager.zip(\n                    files = uris.map { it.toString() },\n                    onProgress = {\n                        _done.update { it + 1 }\n                        updateProgress(\n                            done = done,\n                            total = left\n                        )\n                    }\n                )\n            }.onFailure(AppToastHost::showFailureToast)\n            _isSaving.value = false\n        }\n    }\n\n    private fun resetCalculatedData() {\n        _compressedArchiveUri.value = null\n    }\n\n    fun saveResultTo(uri: Uri) {\n        savingJob = trackProgress {\n            _isSaving.value = true\n            _compressedArchiveUri.value?.let { byteArray ->\n                fileController.transferBytes(\n                    fromUri = byteArray,\n                    toUri = uri.toString(),\n                ).also(::parseFileSaveResult).onSuccess(::registerSave)\n            }\n            _isSaving.value = false\n        }\n    }\n\n    fun shareFile() {\n        compressedArchiveUri?.let { uri ->\n            savingJob = trackProgress {\n                _done.update { 0 }\n                _left.update { 0 }\n\n                _isSaving.value = true\n                shareProvider.shareUri(\n                    uri = uri,\n                    onComplete = {\n                        _isSaving.value = false\n                        AppToastHost.showConfetti()\n                    }\n                )\n            }\n        }\n    }\n\n    fun cancelSaving() {\n        savingJob?.cancel()\n        savingJob = null\n        _isSaving.value = false\n    }\n\n    fun removeUri(uri: Uri) {\n        _uris.update { it - uri }\n    }\n\n    fun addUris(list: List<Uri>) = setUris(uris + list)\n\n\n    @AssistedFactory\n    fun interface Factory {\n        operator fun invoke(\n            componentContext: ComponentContext,\n            initialUris: List<Uri>?,\n            onGoBack: () -> Unit,\n        ): ZipComponent\n    }\n}"
  },
  {
    "path": "gradle/libs.versions.toml",
    "content": "[versions]\nandroidMinSdk = \"23\"\nandroidTargetSdk = \"36\"\nandroidCompileSdk = \"36\"\nandroidCompileSdkExtension = \"19\"\n\nversionName = \"3.8.1-beta01\"\nversionCode = \"227\"\n\njvmTarget = \"21\"\n\nimageToolboxLibs = \"6.2.0\"\ntrickle = \"1.6.1\"\nevaluator = \"1.0.0\"\nquickie = \"1.18.1\"\nfadingEdges = \"1.0.4\"\nlogger = \"1.0.2\"\n\navifCoder = \"2.2.0\"\navifCoderCoil = \"2.2.0\"\naire = \"0.18.1\"\njxlCoder = \"2.6.0\"\njxlCoderCoil = \"2.6.0\"\njpegliCoder = \"1.0.2\"\n\ntesseract = \"4.9.0\"\nmaterial3 = \"1.5.0-alpha17\"\ncomposeVersion = \"1.11.0-rc01\"\nmaterialIconsExtended = \"1.7.8\"\ndataStore = \"1.3.0-alpha07\"\nappUpdateKtx = \"2.1.0\"\nappUpdate = \"2.1.0\"\nshadowGadgets = \"2.4.0\"\nkonfettiCompose = \"2.0.5\"\nshadowsPlus = \"1.0.4\"\ngoogle-segmentationSelfie = \"16.0.0-beta6\"\ngoogle-subjectSegmentation = \"16.0.0-beta1\"\ndetekt = \"1.23.8\"\ndetektCompose = \"0.5.7\"\ndecompose = \"3.5.0\"\n\nkotlin = \"2.3.20\"\nagp = \"9.1.1\"\nhilt = \"2.59.2\"\ngms = \"4.4.4\"\n\nktor = \"3.4.2\"\ncoil = \"3.4.0\"\nappCompat = \"1.7.1\"\nandroidxCore = \"1.18.0\"\ndesugaring = \"2.1.5\"\nactivityCompose = \"1.13.0\"\nkotlinxCollectionsImmutable = \"0.4.0\"\nscrollbar = \"2.2.0\"\nreorderable = \"3.0.0\"\nreviewKtx = \"2.0.2\"\nsplashScreen = \"1.2.0\"\n\nespresso = \"3.7.0\"\nksp = \"2.3.6\"\n\nandroidx-test-ext-junit = \"1.3.0\"\ndocumentfile = \"1.1.0\"\nuiautomator = \"2.3.0\"\nandroidxMacroBenchmark = \"1.5.0-alpha05\"\n\nmaterial = \"1.14.0-beta01\"\njsoup = \"1.22.1\"\nandroidliquidglass = \"1.0.6\"\ncapsule = \"2.1.3\"\nsquircle-shape = \"5.2.0\"\n\nmlkitDocumentScanner = \"16.0.0\"\nmoshi = \"1.15.2\"\nbouncycastle = \"1.84\"\npdfviewer = \"1.0.0-alpha17\"\nfragmentCompose = \"1.8.9\"\naboutlibraries = \"14.0.1\"\nflinger = \"2.0.2\"\nzxingCore = \"3.5.4\"\npdfbox = \"2.0.27.0\"\n\nonnx = \"1.24.3\"\nopencv = \"4.13.0\"\n\ntiffdecoder = \"1.0.5\"\nmaterialKolor = \"5.0.0-alpha07\"\npaletteKtx = \"1.0.0\"\nkotlinxSerializationJson = \"1.11.0\"\nlifecycle = \"2.10.0\"\n\nfirebaseBom = \"34.12.0\"\nfirebaseCrashlyticsGradle = \"3.0.7\"\njunit = \"4.13.2\"\n\n[libraries]\nfirebase-bom = { module = \"com.google.firebase:firebase-bom\", version.ref = \"firebaseBom\" }\nfirebase-crashlytics = { module = \"com.google.firebase:firebase-crashlytics\" }\nfirebase-analytics = { module = \"com.google.firebase:firebase-analytics\" }\njunit = { module = \"junit:junit\", version.ref = \"junit\" }\nlifecycle-viewmodel = { module = \"androidx.lifecycle:lifecycle-viewmodel-ktx\", version.ref = \"lifecycle\" }\nkotlinx-serialization-json = { module = \"org.jetbrains.kotlinx:kotlinx-serialization-json\", version.ref = \"kotlinxSerializationJson\" }\nmaterialKolor = { module = \"com.materialkolor:material-kolor\", version.ref = \"materialKolor\" }\nandroidx-palette-ktx = { module = \"androidx.palette:palette-ktx\", version.ref = \"paletteKtx\" }\nopencv = { module = \"org.opencv:opencv\", version.ref = \"opencv\" }\nonnx-runtime = { module = \"com.microsoft.onnxruntime:onnxruntime-android\", version.ref = \"onnx\" }\npdfbox = { module = \"com.tom-roush:pdfbox-android\", version.ref = \"pdfbox\" }\nzxing-core = { module = \"com.google.zxing:core\", version.ref = \"zxingCore\" }\nflinger = { module = \"com.github.iamjosephmj.flinger:flinger\", version.ref = \"flinger\" }\nsquircle-shape = { group = \"com.stoyanvuchev\", name = \"squircle-shape-android\", version.ref = \"squircle-shape\" }\ncapsule = { module = \"io.github.kyant0:capsule\", version.ref = \"capsule\" }\nandroidliquidglass = { module = \"io.github.kyant0:backdrop\", version.ref = \"androidliquidglass\" }\nandroidx-fragment-compose = { module = \"androidx.fragment:fragment-compose\", version.ref = \"fragmentCompose\" }\nandroidx-pdfviewer-fragment = { module = \"androidx.pdf:pdf-viewer-fragment\", version.ref = \"pdfviewer\" }\nevaluator = { module = \"com.github.T8RIN:KotlinEvaluator\", version.ref = \"evaluator\" }\naboutlibraries-m3 = { module = \"com.mikepenz:aboutlibraries-compose-m3\", version.ref = \"aboutlibraries\" }\nmoshi = { module = \"com.squareup.moshi:moshi-kotlin\", version.ref = \"moshi\" }\nmoshi-adapters = { module = \"com.squareup.moshi:moshi-adapters\", version.ref = \"moshi\" }\nsymbol-processing-api = { module = \"com.google.devtools.ksp:symbol-processing-api\", version.ref = \"ksp\" }\ntrickle = { module = \"com.github.T8RIN:Trickle\", version.ref = \"trickle\" }\njsoup = { module = \"org.jsoup:jsoup\", version.ref = \"jsoup\" }\nmlkit-document-scanner = { module = \"com.google.android.gms:play-services-mlkit-document-scanner\", version.ref = \"mlkitDocumentScanner\" }\nquickie-bundled = { module = \"com.github.T8RIN.QuickieExtended:quickie-bundled\", version.ref = \"quickie\" }\nquickie-foss = { module = \"com.github.T8RIN.QuickieExtended:quickie-foss\", version.ref = \"quickie\" }\nlogger = { module = \"com.github.T8RIN:Logger\", version.ref = \"logger\" }\n\ntoolbox-gpuimage = { module = \"com.github.T8RIN.ImageToolboxLibs:gpuimage\", version.ref = \"imageToolboxLibs\" }\ntoolbox-androidwm = { module = \"com.github.T8RIN.ImageToolboxLibs:androidwm\", version.ref = \"imageToolboxLibs\" }\ntoolbox-gifConverter = { module = \"com.github.T8RIN.ImageToolboxLibs:gif-converter\", version.ref = \"imageToolboxLibs\" }\ntoolbox-apng = { module = \"com.github.T8RIN.ImageToolboxLibs:apng\", version.ref = \"imageToolboxLibs\" }\ntoolbox-svg = { module = \"com.github.T8RIN.ImageToolboxLibs:svg\", version.ref = \"imageToolboxLibs\" }\ntoolbox-jp2decoder = { module = \"com.github.T8RIN.ImageToolboxLibs:jp2decoder\", version.ref = \"imageToolboxLibs\" }\ntoolbox-qoiCoder = { module = \"com.github.T8RIN.ImageToolboxLibs:qoi-coder\", version.ref = \"imageToolboxLibs\" }\ntoolbox-awebp = { module = \"com.github.T8RIN.ImageToolboxLibs:awebp\", version.ref = \"imageToolboxLibs\" }\ntoolbox-psd = { module = \"com.github.T8RIN.ImageToolboxLibs:psd\", version.ref = \"imageToolboxLibs\" }\ntoolbox-djvuCoder = { module = \"com.github.T8RIN.ImageToolboxLibs:djvu-coder\", version.ref = \"imageToolboxLibs\" }\ntoolbox-fastNoise = { module = \"com.github.T8RIN.ImageToolboxLibs:fast-noise\", version.ref = \"imageToolboxLibs\" }\ntoolbox-histogram = { module = \"com.github.T8RIN.ImageToolboxLibs:histogram\", version.ref = \"imageToolboxLibs\" }\ntoolbox-uCrop = { module = \"com.github.T8RIN.ImageToolboxLibs:ucrop\", version.ref = \"imageToolboxLibs\" }\ntoolbox-exif = { module = \"com.github.T8RIN.ImageToolboxLibs:exif\", version.ref = \"imageToolboxLibs\" }\ntoolbox-jhlabs = { module = \"com.github.T8RIN.ImageToolboxLibs:jhlabs\", version.ref = \"imageToolboxLibs\" }\n\ntiffdecoder = { module = \"com.github.T8RIN:TiffDecoder\", version.ref = \"tiffdecoder\" }\naire = { module = \"com.github.awxkee:aire\", version.ref = \"aire\" }\njpegli-coder = { module = \"com.github.awxkee:jpegli-coder\", version.ref = \"jpegliCoder\" }\nkotlin-reflect = { module = \"org.jetbrains.kotlin:kotlin-reflect\", version.ref = \"kotlin\" }\nandroidx-compose-ui-graphics = { module = \"androidx.compose.ui:ui-graphics\", version.ref = \"composeVersion\" }\napp-update-ktx = { module = \"com.google.android.play:app-update-ktx\", version.ref = \"appUpdateKtx\" }\napp-update = { module = \"com.google.android.play:app-update\", version.ref = \"appUpdate\" }\navif-coder = { module = \"io.github.awxkee:avif-coder\", version.ref = \"avifCoder\" }\navif-coder-coil = { module = \"io.github.awxkee:avif-coder-coil\", version.ref = \"avifCoderCoil\" }\nshadowGadgets = { module = \"com.github.zed-alpha.shadow-gadgets:compose\", version.ref = \"shadowGadgets\" }\ndatastore-preferences-android = { module = \"androidx.datastore:datastore-preferences-android\", version.ref = \"dataStore\" }\ndatastore-core-android = { module = \"androidx.datastore:datastore-core-android\", version.ref = \"dataStore\" }\nfadingEdges = { module = \"com.github.t8rin:ComposeFadingEdges\", version.ref = \"fadingEdges\" }\nkonfetti-compose = { module = \"nl.dionsegijn:konfetti-compose\", version.ref = \"konfettiCompose\" }\ndecompose = { module = \"com.arkivanov.decompose:decompose\", version.ref = \"decompose\" }\ndecomposeExtensions = { module = \"com.arkivanov.decompose:extensions-compose\", version.ref = \"decompose\" }\nshadowsPlus = { module = \"com.github.GIGAMOLE:ComposeShadowsPlus\", version.ref = \"shadowsPlus\" }\n\nktor = { module = \"io.ktor:ktor-client-android\", version.ref = \"ktor\" }\nktor-logging = { module = \"io.ktor:ktor-client-logging\", version.ref = \"ktor\" }\ncoilNetwork = { module = \"io.coil-kt.coil3:coil-network-ktor3\", version.ref = \"coil\" }\ncoilCompose = { module = \"io.coil-kt.coil3:coil-compose\", version.ref = \"coil\" }\ncoilGif = { module = \"io.coil-kt.coil3:coil-gif\", version.ref = \"coil\" }\ncoilSvg = { module = \"io.coil-kt.coil3:coil-svg\", version.ref = \"coil\" }\ncoil = { module = \"io.coil-kt.coil3:coil\", version.ref = \"coil\" }\n\njxl-coder-coil = { module = \"io.github.awxkee:jxl-coder-coil\", version.ref = \"jxlCoderCoil\" }\njxl-coder = { module = \"io.github.awxkee:jxl-coder\", version.ref = \"jxlCoder\" }\nkotlinx-collections-immutable = { module = \"org.jetbrains.kotlinx:kotlinx-collections-immutable\", version.ref = \"kotlinxCollectionsImmutable\" }\nappCompat = { module = \"androidx.appcompat:appcompat\", version.ref = \"appCompat\" }\nandroidxCore = { module = \"androidx.core:core-ktx\", version.ref = \"androidxCore\" }\nscrollbar = { module = \"com.github.nanihadesuka:LazyColumnScrollbar\", version.ref = \"scrollbar\" }\nmlkit-segmentation-selfie = { module = \"com.google.mlkit:segmentation-selfie\", version.ref = \"google-segmentationSelfie\" }\nmlkit-subject-segmentation = { module = \"com.google.android.gms:play-services-mlkit-subject-segmentation\", version.ref = \"google-subjectSegmentation\" }\nreorderable = { module = \"sh.calvin.reorderable:reorderable\", version.ref = \"reorderable\" }\nreview-ktx = { module = \"com.google.android.play:review-ktx\", version.ref = \"reviewKtx\" }\nsplashScreen = { module = \"androidx.core:core-splashscreen\", version.ref = \"splashScreen\" }\nactivityCompose = { module = \"androidx.activity:activity-compose\", version.ref = \"activityCompose\" }\nmaterial = { group = \"com.google.android.material\", name = \"material\", version.ref = \"material\" }\nespresso = { module = \"androidx.test.espresso:espresso-core\", version.ref = \"espresso\" }\n\nandroidx-test-ext-junit = { group = \"androidx.test.ext\", name = \"junit\", version.ref = \"androidx-test-ext-junit\" }\nandroidx-documentfile = { group = \"androidx.documentfile\", name = \"documentfile\", version.ref = \"documentfile\" }\nuiautomator = { group = \"androidx.test.uiautomator\", name = \"uiautomator\", version.ref = \"uiautomator\" }\nbenchmark-macro-junit4 = { group = \"androidx.benchmark\", name = \"benchmark-macro-junit4\", version.ref = \"androidxMacroBenchmark\" }\ntesseract = { module = \"com.github.adaptech-cz.Tesseract4Android:tesseract4android-openmp\", version.ref = \"tesseract\" }\n\nbouncycastle-pkix = { module = \"org.bouncycastle:bcpkix-jdk15to18\", version.ref = \"bouncycastle\" }\nbouncycastle-provider = { module = \"org.bouncycastle:bcprov-jdk15to18\", version.ref = \"bouncycastle\" }\n\nfirebase-crashlytics-gradle = { module = \"com.google.firebase:firebase-crashlytics-gradle\", version.ref = \"firebaseCrashlyticsGradle\" }\nbaselineprofile-gradle = { group = \"androidx.benchmark\", name = \"benchmark-baseline-profile-gradle-plugin\", version.ref = \"androidxMacroBenchmark\" }\nkotlin-gradle = { module = \"org.jetbrains.kotlin:kotlin-gradle-plugin\", version.ref = \"kotlin\" }\nhilt-gradle = { module = \"com.google.dagger:hilt-android-gradle-plugin\", version.ref = \"hilt\" }\ngms-gradle = { module = \"com.google.gms:google-services\", version.ref = \"gms\" }\nkotlinx-serialization-gradle = { module = \"org.jetbrains.kotlin:kotlin-serialization\", version.ref = \"kotlin\" }\nksp-gradle = { module = \"com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin\", version.ref = \"ksp\" }\nagp-gradle = { module = \"com.android.tools.build:gradle\", version.ref = \"agp\" }\ndetekt-gradle = { module = \"io.gitlab.arturbosch.detekt:detekt-gradle-plugin\", version.ref = \"detekt\" }\naboutlibraries-gradle = { module = \"com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin\", version.ref = \"aboutlibraries\" }\ncompose-compiler-gradle = { module = \"org.jetbrains.kotlin:compose-compiler-gradle-plugin\", version.ref = \"kotlin\" }\n\n# Used in convention plugins\ndagger-hilt-compiler = { module = \"com.google.dagger:hilt-compiler\", version.ref = \"hilt\" }\ndagger-hilt-android = { module = \"com.google.dagger:hilt-android\", version.ref = \"hilt\" }\ndetekt-formatting = { module = \"io.gitlab.arturbosch.detekt:detekt-formatting\", version.ref = \"detekt\" }\ndetekt-compose = { module = \"io.nlopez.compose.rules:detekt\", version.ref = \"detektCompose\" }\n\nwindow-sizeclass = { module = \"androidx.compose.material3:material3-window-size-class\", version.ref = \"material3\" }\nicons-extended = { module = \"androidx.compose.material:material-icons-extended\", version.ref = \"materialIconsExtended\" }\nandroidx-material = { module = \"androidx.compose.material:material\", version.ref = \"composeVersion\" }\nandroidx-material3 = { module = \"androidx.compose.material3:material3\", version.ref = \"material3\" }\ncompose-preview = { module = \"androidx.compose.ui:ui-tooling-preview\", version.ref = \"composeVersion\" }\n\ndesugaring = { module = \"com.android.tools:desugar_jdk_libs\", version.ref = \"desugaring\" }\n\n[plugins]\nimage-toolbox-library = { id = \"image.toolbox.library\", version = \"unspecified\" }\nimage-toolbox-hilt = { id = \"image.toolbox.hilt\", version = \"unspecified\" }\nimage-toolbox-feature = { id = \"image.toolbox.feature\", version = \"unspecified\" }\nimage-toolbox-compose = { id = \"image.toolbox.compose\", version = \"unspecified\" }\nimage-toolbox-application = { id = \"image.toolbox.application\", version = \"unspecified\" }"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#\n# ImageToolbox is an image editor for android\n# Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n# You should have received a copy of the Apache License\n# along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n#\n\n#Fri Mar 28 22:24:32 MSK 2025\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-9.4.1-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "#\n# ImageToolbox is an image editor for android\n# Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n# You should have received a copy of the Apache License\n# along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n#\norg.gradle.jvmargs=-Xmx8g\nandroid.useAndroidX=true\n# Kotlin code style for this project: \"official\" or \"obsolete\":\nkotlin.code.style=official\n# Enables namespacing of each library's R class so that its R class includes only the\n# resources declared in the library itself and none from the library's dependencies,\n# thereby reducing the size of the R class for that library\nandroid.nonTransitiveRClass=true\nandroid.nonFinalResIds=true\norg.gradle.parallel=true\nkotlin.daemon.jvmargs=-Xmx16g\norg.gradle.configuration-cache=true"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\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='\"-Xmx64m\" \"-Xms64m\"'\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\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 or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\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=`expr $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\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "lib/ascii/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/ascii/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n}\n\nandroid.namespace = \"com.t8rin.ascii\""
  },
  {
    "path": "lib/ascii/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/ascii/src/main/java/com/t8rin/ascii/ASCIIConverter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.ascii\n\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.graphics.Paint\nimport android.graphics.Typeface\nimport androidx.core.graphics.alpha\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.blue\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.get\nimport androidx.core.graphics.green\nimport androidx.core.graphics.red\nimport androidx.core.graphics.scale\nimport kotlinx.coroutines.coroutineScope\nimport kotlin.math.min\nimport kotlin.math.roundToInt\n\ntypealias GradientMap = Map<String, Float>\n\n/**\n * Convert Bitmap into its ASCII equivalent [Bitmap] or [String].\n */\nclass ASCIIConverter(\n    private val fontSize: Float = 18.0f,\n    private val reverseLuma: Boolean = false,\n    private val mapper: AsciiMapper = AsciiMapper()\n) {\n    private var columns: Int = 0\n\n    suspend fun convertToAscii(\n        bitmap: Bitmap,\n    ): String = convert(bitmap) { grid ->\n        grid.rotate90AndMirror().joinToString(\"\\n\") { row ->\n            row.joinToString(\" \") {\n                it.luma()?.let(mapper::mapToAscii) ?: \" \"\n            }\n        }\n    }\n\n    suspend fun convertToAsciiBitmap(\n        bitmap: Bitmap,\n        typeface: Typeface = Typeface.DEFAULT,\n        backgroundColor: Int = Color.TRANSPARENT,\n        isGrayscale: Boolean = false,\n    ): Bitmap = convert(bitmap) { grid ->\n        prepareCanvas(\n            bitmap = bitmap,\n            backgroundColor = backgroundColor,\n            typeface = typeface\n        ) { paint ->\n            grid.forEachIndexed { row, blocks ->\n                blocks.forEachIndexed { col, color ->\n                    val luma = color.luma()\n\n                    if (isGrayscale && luma != null) {\n                        paint.alpha = (luma * 255.0f).toInt()\n                        paint.color = Color.GRAY\n                    } else {\n                        paint.color = color\n                    }\n\n                    drawText(\n                        luma?.let(mapper::mapToAscii) ?: \" \",\n                        row * fontSize,\n                        col * fontSize,\n                        paint\n                    )\n                }\n            }\n        }\n    }\n\n    private fun Grid.transpose(): Grid =\n        first().indices.map { y ->\n            indices.map { x -> this[x][y] }\n        }\n\n    private fun Grid.rotate90AndMirror(): Grid =\n        first().indices.map { x ->\n            indices.map { y ->\n                this[y][x]\n            }.reversed()\n        }.map { it.reversed() }\n\n    private inline fun prepareCanvas(\n        bitmap: Bitmap,\n        backgroundColor: Int,\n        typeface: Typeface,\n        action: Canvas.(Paint) -> Unit\n    ): Bitmap = createBitmap(bitmap.width, bitmap.height).applyCanvas {\n        if (backgroundColor != Color.TRANSPARENT) drawColor(backgroundColor)\n        action(\n            Paint().apply {\n                setTypeface(typeface)\n                textSize = fontSize\n            }\n        )\n    }\n\n    private suspend inline fun <T> convert(\n        bitmap: Bitmap,\n        crossinline action: suspend (Grid) -> T\n    ) = coroutineScope {\n        checkColumns(bitmap)\n        action(bitmap.resize().toGrid())\n    }\n\n    private fun checkColumns(bitmap: Bitmap) {\n        columns = bitmap.toColumns()\n        require(columns >= 5) { \"Columns count is very small. Font size needs to be reduced\" }\n    }\n\n    private fun Bitmap.toColumns(): Int =\n        if (columns < 5) (width / fontSize).roundToInt() else columns\n\n    private fun Bitmap.toGrid(): Grid {\n        require(width > 0 && height > 0) { \"Width and height must be positive values.\" }\n\n        return List(width) { x ->\n            List(height) { y ->\n                this[x, y]\n            }\n        }\n    }\n\n    private fun Bitmap.resize(): Bitmap {\n        if (columns <= 1) return this\n\n        val min = min(height, width)\n        val scaleFactor = if (columns > min) min else columns\n        val ratio = scaleFactor.toFloat() / width.toFloat()\n\n        return copy(Bitmap.Config.ARGB_8888, false).scale(\n            width = scaleFactor,\n            height = (ratio * height).toInt()\n        )\n    }\n\n    private fun Int.luma(): Float? {\n        if (alpha <= 0) return null\n\n        val luminance = (0.2126 * (red / 255f))\n            .plus(0.7152 * (green / 255f))\n            .plus(0.0722 * (blue / 255f))\n\n        return (if (reverseLuma) 1 - luminance else luminance).toFloat()\n    }\n}\n\nfun interface AsciiMapper {\n    fun mapToAscii(luma: Float): String\n}\n\n@JvmInline\nvalue class Gradient(val value: String) {\n\n    fun toMap(): GradientMap {\n        val length = value.length\n        return value.mapIndexed { index, char ->\n            char.toString() to (1.0f - index.toFloat() / (length - 1).coerceAtLeast(1))\n        }.toMap()\n    }\n\n    companion object {\n        val NORMAL = Gradient(\".:-=+*#%@\")\n        val NORMAL2 = Gradient(\" `.,-~+<>o=*%X@\")\n        val ARROWS = Gradient(\"↖←↙↓↘→↗↑\")\n        val OLD = Gradient(\"░▒▓█\")\n        val EXTENDED_HIGH = Gradient(\".:-~=+*^><)(][}{#%@\")\n        val MINIMAL = Gradient(\".-+#\")\n        val MATH = Gradient(\"π√∞≈≠=÷×-+\")\n        val NUMERICAL = Gradient(\"7132546980\")\n    }\n}\n\nfun String.toGradientMap(): GradientMap = Gradient(this).toMap()\n\nfun GradientMap.toMapper(): AsciiMapper = AsciiMapperImpl(map = this)\n\nfun Gradient.toMapper(): AsciiMapper = toMap().toMapper()\n\nfun AsciiMapper(map: GradientMap): AsciiMapper = map.toMapper()\n\nfun AsciiMapper(gradient: Gradient = Gradient.NORMAL): AsciiMapper = gradient.toMapper()\n\n\nprivate class AsciiMapperImpl(map: GradientMap) : AsciiMapper {\n    private val metrics: List<Pair<String, Float>> = map.toList().sortedByDescending { it.second }\n\n    override fun mapToAscii(\n        luma: Float\n    ): String = metrics.find {\n        luma >= it.second\n    }?.first ?: metrics.firstOrNull()?.first.orEmpty()\n}\n\nprivate typealias Grid = List<List<Int>>"
  },
  {
    "path": "lib/collages/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/collages/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.collages\"\n\ndependencies {\n    implementation(libs.appCompat)\n    implementation(libs.coilCompose)\n}"
  },
  {
    "path": "lib/collages/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/Collage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages\n\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\nimport android.net.Uri\nimport android.os.Bundle\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.viewinterop.AndroidView\nimport androidx.compose.ui.zIndex\nimport com.t8rin.collages.utils.CollageLayoutFactory.createCollageLayouts\nimport com.t8rin.collages.view.FramePhotoLayout\nimport kotlin.math.min\n\n@Composable\nfun Collage(\n    images: List<Uri>,\n    modifier: Modifier = Modifier,\n    spacing: Float = 0f,\n    cornerRadius: Float = 0f,\n    backgroundColor: Color = Color.White,\n    onCollageCreated: (Bitmap) -> Unit,\n    collageCreationTrigger: Boolean,\n    collageType: CollageType,\n    userInteractionEnabled: Boolean = true,\n    aspectRatio: Float = 1f,\n    outputScaleRatio: Float = 1.5f,\n    onImageTap: ((index: Int) -> Unit)? = null,\n    handleDrawable: Drawable? = null,\n    disableRotation: Boolean = false,\n    enableSnapToBorders: Boolean = false\n) {\n    var previousSize by rememberSaveable {\n        mutableIntStateOf(100)\n    }\n    var previousAspect by rememberSaveable {\n        mutableFloatStateOf(aspectRatio)\n    }\n    var previousImages by rememberSaveable {\n        mutableStateOf(listOf<Uri>())\n    }\n    var needToInvalidate by remember {\n        mutableStateOf(false)\n    }\n    val ownedCollageLayout by remember(collageType.layout?.title) {\n        mutableStateOf(\n            collageType.layout?.let { template ->\n                createCollageLayouts(template.title)\n            }\n        )\n    }\n\n    LaunchedEffect(collageType.layout?.title) {\n        needToInvalidate = true\n    }\n\n    AnimatedVisibility(\n        visible = ownedCollageLayout != null,\n        modifier = modifier,\n        enter = fadeIn(),\n        exit = fadeOut()\n    ) {\n        BoxWithConstraints {\n            val size = this.constraints.run { min(maxWidth, maxHeight) }\n            var viewInstance by remember {\n                mutableStateOf<FramePhotoLayout?>(null)\n            }\n            var viewState by rememberSaveable {\n                mutableStateOf(Bundle.EMPTY)\n            }\n            DisposableEffect(viewInstance) {\n                viewInstance?.restoreInstanceState(viewState)\n\n                onDispose {\n                    viewState = Bundle()\n                    viewInstance?.saveInstanceState(viewState)\n                }\n            }\n            SideEffect {\n                viewInstance?.setBackgroundColor(backgroundColor)\n                viewInstance?.setSpace(spacing, cornerRadius)\n                viewInstance?.setDisableRotation(disableRotation)\n                viewInstance?.setEnableSnapToBorders(enableSnapToBorders)\n            }\n            CompositionLocalProvider(\n                LocalLayoutDirection provides LayoutDirection.Ltr\n            ) {\n                AndroidView(\n                    factory = {\n                        FramePhotoLayout(\n                            context = it,\n                            mPhotoItems = ownedCollageLayout?.photoItemList ?: emptyList()\n                        ).apply {\n                            updateImages(images)\n                            previousImages = images\n                            setParamsManager(ownedCollageLayout?.paramsManager)\n\n                            val (width, height) = calculateDimensions(\n                                size,\n                                constraints,\n                                aspectRatio\n                            )\n                            viewInstance = this\n                            previousSize = size\n                            previousAspect = aspectRatio\n                            setBackgroundColor(backgroundColor)\n                            setOnItemTapListener(onImageTap)\n                            setHandleDrawable(handleDrawable)\n                            setDisableRotation(disableRotation)\n                            setEnableSnapToBorders(enableSnapToBorders)\n                            build(\n                                viewWidth = width,\n                                viewHeight = height,\n                                space = spacing,\n                                corner = cornerRadius\n                            )\n                        }\n                    },\n                    update = {\n                        if (needToInvalidate) {\n                            //Full rebuild\n                            needToInvalidate = false\n\n                            it.mPhotoItems = ownedCollageLayout?.photoItemList ?: emptyList()\n                            it.updateImages(images)\n                            previousImages = images\n                            it.setParamsManager(ownedCollageLayout?.paramsManager)\n\n                            it.setOnItemTapListener(onImageTap)\n                            it.setHandleDrawable(handleDrawable)\n                            previousSize = size\n                            previousAspect = aspectRatio\n\n                            val (width, height) = calculateDimensions(\n                                size,\n                                constraints,\n                                aspectRatio\n                            )\n                            it.build(\n                                viewWidth = width,\n                                viewHeight = height,\n                                space = spacing,\n                                corner = cornerRadius\n                            )\n                        } else {\n                            //Readjustments\n\n                            if (previousSize != size || previousAspect != aspectRatio) {\n                                val (width, height) = calculateDimensions(\n                                    size,\n                                    constraints,\n                                    aspectRatio\n                                )\n                                it.resize(width, height)\n\n                                previousSize = size\n                                previousAspect = aspectRatio\n                            }\n\n                            if (previousImages != images) {\n                                it.updateImages(images)\n                                previousImages = images\n                            }\n                        }\n                    }\n                )\n            }\n\n            if (!userInteractionEnabled) {\n                Surface(\n                    color = Color.Transparent,\n                    modifier = Modifier\n                        .matchParentSize()\n                        .zIndex(2f)\n                ) { }\n            }\n\n            LaunchedEffect(viewInstance, collageCreationTrigger) {\n                if (collageCreationTrigger) {\n                    viewInstance?.createImage(outputScaleRatio)?.let(onCollageCreated)\n                }\n            }\n        }\n    }\n}\n\nprivate fun calculateDimensions(\n    size: Int,\n    constraints: Constraints,\n    aspectRatio: Float\n): Pair<Int, Int> {\n    return if (size == constraints.maxWidth) {\n        val targetHeight =\n            (size / aspectRatio).toDouble().coerceAtMost(constraints.maxHeight.toDouble()).toInt()\n        val targetWidth = (targetHeight * aspectRatio).toInt()\n        targetWidth to targetHeight\n    } else {\n        val targetWidth =\n            (size * aspectRatio).toDouble().coerceAtMost(constraints.maxWidth.toDouble()).toInt()\n        val targetHeight = (targetWidth / aspectRatio).toInt()\n        targetWidth to targetHeight\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/CollageType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages\n\nimport com.t8rin.collages.model.CollageLayout\n\n@ConsistentCopyVisibility\ndata class CollageType internal constructor(\n    internal val layout: CollageLayout?,\n    internal val index: Int?\n) {\n    companion object {\n        val Empty by lazy {\n            CollageType(\n                layout = null,\n                index = null\n            )\n        }\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/CollageTypeSelection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.unit.dp\nimport coil3.compose.AsyncImage\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory.loadFrameImages\n\n@Composable\nfun CollageTypeSelection(\n    imagesCount: Int,\n    value: CollageType,\n    onValueChange: (CollageType) -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = RectangleShape,\n    itemModifierFactory: @Composable (isSelected: Boolean) -> Modifier = { Modifier },\n    state: LazyListState = rememberLazyListState(),\n    previewColor: Color = MaterialTheme.colorScheme.secondary,\n    contentPadding: PaddingValues = PaddingValues(16.dp)\n) {\n    var allFrames: List<CollageLayout> by remember {\n        mutableStateOf(emptyList())\n    }\n    val context = LocalContext.current\n\n    LaunchedEffect(context) {\n        allFrames = loadFrameImages(context)\n    }\n\n    val availableFrames by remember(allFrames, imagesCount) {\n        derivedStateOf {\n            allFrames.filter {\n                it.photoItemList.size == imagesCount\n            }\n        }\n    }\n\n    LaunchedEffect(availableFrames) {\n        if (\n            availableFrames.isNotEmpty() && (value == CollageType.Empty || (value.layout?.photoItemList?.size\n                ?: 0) != imagesCount)\n        ) {\n            onValueChange(\n                CollageType(\n                    layout = availableFrames.first(),\n                    index = 0\n                )\n            )\n        }\n    }\n\n    AnimatedVisibility(\n        visible = availableFrames.size > 1\n    ) {\n        LazyRow(\n            state = state,\n            modifier = modifier,\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.spacedBy(8.dp),\n            contentPadding = contentPadding\n        ) {\n            itemsIndexed(availableFrames) { index, layout ->\n                AsyncImage(\n                    model = layout.preview,\n                    contentDescription = null,\n                    contentScale = ContentScale.FillBounds,\n                    colorFilter = ColorFilter.tint(previewColor),\n                    modifier = Modifier\n                        .fillMaxHeight()\n                        .aspectRatio(1f)\n                        .clip(shape)\n                        .clickable {\n                            onValueChange(\n                                CollageType(\n                                    layout = layout,\n                                    index = index\n                                )\n                            )\n                        }\n                        .then(itemModifierFactory(value.index == index))\n                )\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/EightFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.view.PhotoItem\n\ninternal object EightFrameImage {\n    internal fun collage_8_16(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_8_16\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //sixth frame\n        photoItem = PhotoItem()\n        photoItem.index = 5\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //seventh frame\n        photoItem = PhotoItem()\n        photoItem.index = 6\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //eighth frame\n        photoItem = PhotoItem()\n        photoItem.index = 7\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_8_15(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_15\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_14(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_14\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_13(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_13\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y3], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_12(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_12\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_11(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_11\") {\n            val xTop = param(0.5f)\n            val xMid2 = param(0.6666f)\n            val xBot = param(0.3333f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(xTop),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[xTop], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xTop),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xTop], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xTop),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[xTop], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xTop),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xTop], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xMid2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[xMid2], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xMid2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[xMid2], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xBot),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[xBot], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xBot),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[xBot], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_10(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_10\") {\n            val x = param(0.5f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_9(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_9\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_8(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_8\") {\n            val xR = param(0.6666f)\n            val xM = param(0.3333f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n            val yMid = param(0.7f)\n\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[xM], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM, xR),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xM], 0f, vs[xR], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y1, yMid),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[xR], vs[yMid]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(yMid),\n                boxParams = { vs -> RectF(0f, vs[yMid], vs[xR], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xR], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xR], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[xR], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[xR], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_7(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_7\") {\n            val x1 = param(0.3f)\n            val x2 = param(0.6f)\n            val y1 = param(0.2f)\n            val y2 = param(0.6f)\n            val yR1 = param(0.3333f)\n            val yR2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yR1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[yR1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yR1, yR2),\n                boxParams = { vs -> RectF(vs[x2], vs[yR1], 1f, vs[yR2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yR2),\n                boxParams = { vs -> RectF(vs[x2], vs[yR2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_6(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_6\") {\n            val xMain = param(0.6f)\n            val xSmall = param(0.3f)\n            val yTop = param(0.5f)\n            val yR1 = param(0.3333f)\n            val yR2 = param(0.6666f)\n            val ySmall = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(xMain),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(0f, 0f, vs[xMain], vs[yTop]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xMain),\n                yParams = listOf(yR1),\n                boxParams = { vs -> RectF(vs[xMain], 0f, 1f, vs[yR1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xMain),\n                yParams = listOf(yR1, yR2),\n                boxParams = { vs -> RectF(vs[xMain], vs[yR1], 1f, vs[yR2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xMain),\n                yParams = listOf(yR2),\n                boxParams = { vs -> RectF(vs[xMain], vs[yR2], 1f, 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xSmall),\n                yParams = listOf(yTop, ySmall),\n                boxParams = { vs -> RectF(0f, vs[yTop], vs[xSmall], vs[ySmall]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xSmall, xMain),\n                yParams = listOf(yTop, ySmall),\n                boxParams = { vs -> RectF(vs[xSmall], vs[yTop], vs[xMain], vs[ySmall]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xSmall),\n                yParams = listOf(ySmall),\n                boxParams = { vs -> RectF(0f, vs[ySmall], vs[xSmall], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xSmall, xMain),\n                yParams = listOf(ySmall),\n                boxParams = { vs -> RectF(vs[xSmall], vs[ySmall], vs[xMain], 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_5(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_5\") {\n            val x0 = param(0.25f)\n            val x1 = param(0.5f)\n            val x2 = param(0.75f)\n            val y = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(x0),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(0f, 0f, vs[x0], vs[y]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x0, x1),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x0], 0f, vs[x1], vs[y]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x0),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(0f, vs[y], vs[x0], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x0, x1),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x0], vs[y], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x1], vs[y], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x2], vs[y], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_4(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_4\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val yTop = param(0.25f)\n            val yMid = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[yTop]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(0f, vs[yTop], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yMid),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[yMid]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yMid),\n                boxParams = { vs -> RectF(vs[x1], vs[yMid], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(vs[x2], 0f, vs[x3], vs[yTop]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(vs[x2], vs[yTop], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(yMid),\n                boxParams = { vs -> RectF(vs[x3], 0f, 1f, vs[yMid]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(yMid),\n                boxParams = { vs -> RectF(vs[x3], vs[yMid], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_3(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_3\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val y1 = param(0.25f)\n            val y2 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_2(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_2\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n            val yMid = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yMid),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[yMid]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yMid),\n                boxParams = { vs -> RectF(vs[x1], vs[yMid], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_1(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_1\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.5f)\n            val x3 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x3], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x3], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_8_0(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_8_0\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/ExtendedFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.utils.CollageLayoutFactory.collage\nimport com.t8rin.collages.utils.ParamsManagerBuilder\nimport com.t8rin.collages.view.PhotoItem\n\ninternal object ExtendedFrameImage {\n\n    private fun ParamsManagerBuilder.fixedRect(\n        left: Float,\n        top: Float,\n        right: Float,\n        bottom: Float,\n    ) {\n        addBoxedItem(boxParams = { RectF(left, top, right, bottom) })\n    }\n\n    private fun ParamsManagerBuilder.uniformGridInRegion(\n        rows: Int,\n        cols: Int,\n        regionLeft: Float = 0f,\n        regionTop: Float = 0f,\n        regionRight: Float = 1f,\n        regionBottom: Float = 1f,\n    ) {\n        val w = regionRight - regionLeft\n        val h = regionBottom - regionTop\n        val cw = w / cols\n        val rh = h / rows\n        for (r in 0 until rows) {\n            for (c in 0 until cols) {\n                fixedRect(\n                    regionLeft + c * cw,\n                    regionTop + r * rh,\n                    regionLeft + (c + 1) * cw,\n                    regionTop + (r + 1) * rh,\n                )\n            }\n        }\n    }\n\n    private fun ParamsManagerBuilder.rowStrip(\n        rowTop: Float,\n        rowBottom: Float,\n        cellCount: Int,\n        regionLeft: Float = 0f,\n        regionRight: Float = 1f,\n    ) {\n        val w = (regionRight - regionLeft) / cellCount\n        for (i in 0 until cellCount) {\n            fixedRect(\n                regionLeft + i * w,\n                rowTop,\n                regionLeft + (i + 1) * w,\n                rowBottom,\n            )\n        }\n    }\n\n    private fun ParamsManagerBuilder.parametricStackedRowStrips(\n        rowCounts: List<Int>,\n    ) {\n        val numRows = rowCounts.size\n        if (numRows == 0) return\n        val yRowParams = (1 until numRows).map { r -> param(r.toFloat() / numRows) }\n        val xRowParamsList = rowCounts.map { k ->\n            if (k <= 1) emptyList()\n            else (1 until k).map { j -> param(j.toFloat() / k) }\n        }\n        for (r in rowCounts.indices) {\n            val k = rowCounts[r]\n            if (k <= 0) continue\n            val xRowParams = xRowParamsList[r]\n            repeat(k) { i ->\n                val xp = buildList {\n                    if (i > 0) add(xRowParams[i - 1])\n                    if (i < k - 1) add(xRowParams[i])\n                }.distinct()\n                val yp = buildList {\n                    if (r > 0) add(yRowParams[r - 1])\n                    if (r < numRows - 1) add(yRowParams[r])\n                }.distinct()\n                addBoxedItem(\n                    xParams = xp,\n                    yParams = yp,\n                    boxParams = { vs ->\n                        val top = if (r == 0) 0f else vs[yRowParams[r - 1]]\n                        val bottom = if (r == numRows - 1) 1f else vs[yRowParams[r]]\n                        val left = if (i == 0) 0f else vs[xRowParams[i - 1]]\n                        val right = if (i == k - 1) 1f else vs[xRowParams[i]]\n                        RectF(left, top, right, bottom)\n                    },\n                )\n            }\n        }\n    }\n\n    internal fun collage_1_0(): CollageLayout {\n        return collage(\"collage_1_0\").copy(\n            photoItemList = listOf(\n                PhotoItem().apply {\n                    bound.set(0f, 0f, 1f, 1f)\n                    index = 0\n                    pointList.add(PointF(0f, 0f))\n                    pointList.add(PointF(1f, 0f))\n                    pointList.add(PointF(1f, 1f))\n                    pointList.add(PointF(0f, 1f))\n                }\n            )\n        )\n    }\n\n    internal fun collage_2_12(): CollageLayout {\n        return TwoFrameImage.collage_2_0(\"collage_2_12\", 0.38f)\n    }\n\n    internal fun collage_2_13(): CollageLayout {\n        return TwoFrameImage.collage_2_1(\"collage_2_13\", 0.42f)\n    }\n\n    internal fun collage_3_48(): CollageLayout {\n        return collage(\"collage_3_48\") {\n            val x1 = param(0.34f)\n            val y1 = param(0.5f)\n            addBoxedItem(\n                xParams = listOf(x1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], 1f) },\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, 1f, vs[y1]) },\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], 1f, 1f) },\n            )\n        }\n    }\n\n    internal fun collage_4_26(): CollageLayout {\n        return collage(\"collage_4_26\") {\n            val y1 = param(0.55f)\n            addBoxedItem(\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, 1f, vs[y1]) },\n            )\n            val x1 = param(0.3333f)\n            val x2 = param(0.6667f)\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], 1f) },\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], 1f) },\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, 1f) },\n            )\n        }\n    }\n\n    internal fun collage_4_27(): CollageLayout {\n        return collage(\"collage_4_27\") {\n            fixedRect(0f, 0f, 0.55f, 1f)\n            fixedRect(0.55f, 0f, 1f, 1f / 3f)\n            fixedRect(0.55f, 1f / 3f, 1f, 2f / 3f)\n            fixedRect(0.55f, 2f / 3f, 1f, 1f)\n        }\n    }\n\n    internal fun collage_5_32(): CollageLayout {\n        return collage(\"collage_5_32\") {\n            val x1 = param(0.28f)\n            val x2 = param(0.72f)\n            val y1 = param(0.28f)\n            val y2 = param(0.72f)\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) },\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) },\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) },\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) },\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) },\n            )\n        }\n    }\n\n    internal fun collage_5_33(): CollageLayout {\n        return collage(\"collage_5_33\") {\n            rowStrip(0f, 0.5f, 2)\n            rowStrip(0.5f, 1f, 3)\n        }\n    }\n\n    internal fun collage_6_15(): CollageLayout {\n        return collage(\"collage_6_15\") {\n            rowStrip(0f, 1f / 3f, 1)\n            rowStrip(1f / 3f, 2f / 3f, 2)\n            rowStrip(2f / 3f, 1f, 3)\n        }\n    }\n\n    internal fun collage_6_16(): CollageLayout {\n        return collage(\"collage_6_16\") {\n            rowStrip(0f, 1f / 3f, 2)\n            rowStrip(1f / 3f, 2f / 3f, 2)\n            rowStrip(2f / 3f, 1f, 2)\n        }\n    }\n\n    internal fun collage_6_17(): CollageLayout {\n        return collage(\"collage_6_17\") {\n            rowStrip(0f, 1f / 3f, 3)\n            rowStrip(1f / 3f, 2f / 3f, 2)\n            rowStrip(2f / 3f, 1f, 1)\n        }\n    }\n\n    internal fun collage_7_11(): CollageLayout {\n        return collage(\"collage_7_11\") {\n            rowStrip(0f, 1f / 3f, 3)\n            rowStrip(1f / 3f, 2f / 3f, 2)\n            rowStrip(2f / 3f, 1f, 2)\n        }\n    }\n\n    internal fun collage_7_12(): CollageLayout {\n        return collage(\"collage_7_12\") {\n            rowStrip(0f, 0.32f, 3)\n            rowStrip(0.32f, 0.55f, 1)\n            rowStrip(0.55f, 1f, 3)\n        }\n    }\n\n    internal fun collage_8_17(): CollageLayout {\n        return collage(\"collage_8_17\") {\n            rowStrip(0f, 0.35f, 3)\n            rowStrip(0.35f, 0.7f, 3)\n            rowStrip(0.7f, 1f, 2)\n        }\n    }\n\n    internal fun collage_8_18(): CollageLayout {\n        return collage(\"collage_8_18\") {\n            rowStrip(0f, 0.25f, 2)\n            rowStrip(0.25f, 0.5f, 2)\n            rowStrip(0.5f, 0.75f, 2)\n            rowStrip(0.75f, 1f, 2)\n        }\n    }\n\n    internal fun collage_9_12(): CollageLayout {\n        return collage(\"collage_9_12\") {\n            rowStrip(0f, 1f / 3f, 2)\n            rowStrip(1f / 3f, 2f / 3f, 3)\n            rowStrip(2f / 3f, 1f, 4)\n        }\n    }\n\n    internal fun collage_9_13(): CollageLayout {\n        return collage(\"collage_9_13\") {\n            rowStrip(0f, 1f / 3f, 3)\n            rowStrip(1f / 3f, 2f / 3f, 3)\n            rowStrip(2f / 3f, 1f, 3)\n        }\n    }\n\n    internal fun collage_10_9(): CollageLayout {\n        return collage(\"collage_10_9\") {\n            uniformGridInRegion(3, 3, 0f, 0f, 1f, 0.75f)\n            fixedRect(0f, 0.75f, 1f, 1f)\n        }\n    }\n\n    internal fun collage_10_10(): CollageLayout {\n        return collage(\"collage_10_10\") {\n            uniformGridInRegion(2, 5, 0f, 0f, 1f, 1f)\n        }\n    }\n\n    internal fun collage_11_0(): CollageLayout {\n        return collage(\"collage_11_0\") {\n            parametricStackedRowStrips(listOf(3, 4, 4))\n        }\n    }\n\n    internal fun collage_11_1(): CollageLayout {\n        return collage(\"collage_11_1\") {\n            parametricStackedRowStrips(listOf(5, 6))\n        }\n    }\n\n    internal fun collage_11_2(): CollageLayout {\n        return collage(\"collage_11_2\") {\n            parametricStackedRowStrips(listOf(4, 4, 3))\n        }\n    }\n\n    internal fun collage_11_3(): CollageLayout {\n        return collage(\"collage_11_3\") {\n            parametricStackedRowStrips(listOf(3, 3, 5))\n        }\n    }\n\n    internal fun collage_11_4(): CollageLayout {\n        return collage(\"collage_11_4\") {\n            parametricStackedRowStrips(listOf(4, 3, 4))\n        }\n    }\n\n    internal fun collage_11_5(): CollageLayout {\n        return collage(\"collage_11_5\") {\n            parametricStackedRowStrips(listOf(5, 3, 3))\n        }\n    }\n\n    internal fun collage_11_6(): CollageLayout {\n        return collage(\"collage_11_6\") {\n            rowStrip(0f, 0.24f, 3)\n            fixedRect(0f, 0.24f, 0.2f, 0.76f)\n            fixedRect(0.2f, 0.24f, 0.34f, 0.76f)\n            fixedRect(0.34f, 0.24f, 0.66f, 0.76f)\n            fixedRect(0.66f, 0.24f, 0.8f, 0.76f)\n            fixedRect(0.8f, 0.24f, 1f, 0.76f)\n            rowStrip(0.76f, 1f, 3)\n        }\n    }\n\n    internal fun collage_11_7(): CollageLayout {\n        return collage(\"collage_11_7\") {\n            parametricStackedRowStrips(listOf(2, 4, 5))\n        }\n    }\n\n    internal fun collage_11_8(): CollageLayout {\n        return collage(\"collage_11_8\") {\n            parametricStackedRowStrips(listOf(6, 3, 2))\n        }\n    }\n\n    internal fun collage_11_9(): CollageLayout {\n        return collage(\"collage_11_9\") {\n            rowStrip(0f, 0.26f, 3)\n            uniformGridInRegion(1, 5, 0f, 0.26f, 1f, 0.72f)\n            rowStrip(0.72f, 1f, 3)\n        }\n    }\n\n    internal fun collage_11_10(): CollageLayout {\n        return collage(\"collage_11_10\") {\n            rowStrip(0f, 0.24f, 4)\n            fixedRect(0f, 0.24f, 0.3f, 0.78f)\n            uniformGridInRegion(1, 3, 0.3f, 0.24f, 1f, 0.51f)\n            uniformGridInRegion(1, 2, 0.3f, 0.51f, 1f, 0.78f)\n            rowStrip(0.78f, 1f, 1)\n        }\n    }\n\n    internal fun collage_12_0(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_12_0\", rows = 3, cols = 4)\n    }\n\n    internal fun collage_12_1(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_12_1\", rows = 4, cols = 3)\n    }\n\n    internal fun collage_12_2(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_12_2\", rows = 2, cols = 6)\n    }\n\n    internal fun collage_12_3(): CollageLayout {\n        return collage(\"collage_12_3\") {\n            parametricStackedRowStrips(listOf(2, 3, 3, 4))\n        }\n    }\n\n    internal fun collage_12_4(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_12_4\", rows = 6, cols = 2)\n    }\n\n    internal fun collage_12_5(): CollageLayout {\n        return collage(\"collage_12_5\") {\n            parametricStackedRowStrips(listOf(4, 3, 3, 2))\n        }\n    }\n\n    internal fun collage_12_6(): CollageLayout {\n        return collage(\"collage_12_6\") {\n            rowStrip(0f, 0.2f, 4)\n            fixedRect(0f, 0.2f, 0.2f, 0.8f)\n            fixedRect(0.8f, 0.2f, 1f, 0.8f)\n            uniformGridInRegion(2, 2, 0.2f, 0.2f, 0.8f, 0.8f)\n            rowStrip(0.8f, 1f, 2)\n        }\n    }\n\n    internal fun collage_12_7(): CollageLayout {\n        return collage(\"collage_12_7\") {\n            parametricStackedRowStrips(listOf(3, 5, 4))\n        }\n    }\n\n    internal fun collage_12_8(): CollageLayout {\n        return collage(\"collage_12_8\") {\n            parametricStackedRowStrips(listOf(2, 5, 5))\n        }\n    }\n\n    internal fun collage_12_9(): CollageLayout {\n        return collage(\"collage_12_9\") {\n            parametricStackedRowStrips(listOf(4, 2, 4, 2))\n        }\n    }\n\n    internal fun collage_12_10(): CollageLayout {\n        return collage(\"collage_12_10\") {\n            rowStrip(0f, 0.22f, 4)\n            fixedRect(0f, 0.22f, 0.18f, 0.8f)\n            fixedRect(0.82f, 0.22f, 1f, 0.8f)\n            uniformGridInRegion(2, 2, 0.18f, 0.22f, 0.82f, 0.8f)\n            rowStrip(0.8f, 1f, 2)\n        }\n    }\n\n    internal fun collage_13_0(): CollageLayout {\n        return collage(\"collage_13_0\") {\n            parametricStackedRowStrips(listOf(4, 4, 5))\n        }\n    }\n\n    internal fun collage_13_1(): CollageLayout {\n        return collage(\"collage_13_1\") {\n            parametricStackedRowStrips(listOf(3, 3, 3, 4))\n        }\n    }\n\n    internal fun collage_13_2(): CollageLayout {\n        return collage(\"collage_13_2\") {\n            parametricStackedRowStrips(listOf(5, 4, 4))\n        }\n    }\n\n    internal fun collage_13_3(): CollageLayout {\n        return collage(\"collage_13_3\") {\n            parametricStackedRowStrips(listOf(3, 4, 6))\n        }\n    }\n\n    internal fun collage_13_4(): CollageLayout {\n        return collage(\"collage_13_4\") {\n            parametricStackedRowStrips(listOf(2, 5, 6))\n        }\n    }\n\n    internal fun collage_13_5(): CollageLayout {\n        return collage(\"collage_13_5\") {\n            parametricStackedRowStrips(listOf(4, 5, 4))\n        }\n    }\n\n    internal fun collage_13_6(): CollageLayout {\n        return collage(\"collage_13_6\") {\n            rowStrip(0f, 0.22f, 5)\n            fixedRect(0f, 0.22f, 0.22f, 0.78f)\n            fixedRect(0.78f, 0.22f, 1f, 0.78f)\n            uniformGridInRegion(2, 2, 0.22f, 0.22f, 0.78f, 0.78f)\n            rowStrip(0.78f, 1f, 2)\n        }\n    }\n\n    internal fun collage_13_7(): CollageLayout {\n        return collage(\"collage_13_7\") {\n            parametricStackedRowStrips(listOf(3, 5, 5))\n        }\n    }\n\n    internal fun collage_13_8(): CollageLayout {\n        return collage(\"collage_13_8\") {\n            parametricStackedRowStrips(listOf(6, 4, 3))\n        }\n    }\n\n    internal fun collage_13_9(): CollageLayout {\n        return collage(\"collage_13_9\") {\n            parametricStackedRowStrips(listOf(4, 3, 4, 2))\n        }\n    }\n\n    internal fun collage_13_10(): CollageLayout {\n        return collage(\"collage_13_10\") {\n            rowStrip(0f, 0.2f, 4)\n            fixedRect(0f, 0.2f, 0.22f, 0.82f)\n            fixedRect(0.22f, 0.2f, 0.5f, 0.5f)\n            fixedRect(0.5f, 0.2f, 0.78f, 0.5f)\n            fixedRect(0.78f, 0.2f, 1f, 0.82f)\n            fixedRect(0.22f, 0.5f, 0.5f, 0.82f)\n            fixedRect(0.5f, 0.5f, 0.78f, 0.82f)\n            rowStrip(0.82f, 1f, 3)\n        }\n    }\n\n    internal fun collage_14_0(): CollageLayout {\n        return collage(\"collage_14_0\") {\n            parametricStackedRowStrips(listOf(7, 7))\n        }\n    }\n\n    internal fun collage_14_1(): CollageLayout {\n        return collage(\"collage_14_1\") {\n            parametricStackedRowStrips(listOf(4, 5, 5))\n        }\n    }\n\n    internal fun collage_14_2(): CollageLayout {\n        return collage(\"collage_14_2\") {\n            parametricStackedRowStrips(listOf(3, 4, 4, 3))\n        }\n    }\n\n    internal fun collage_14_3(): CollageLayout {\n        return collage(\"collage_14_3\") {\n            parametricStackedRowStrips(listOf(5, 5, 4))\n        }\n    }\n\n    internal fun collage_14_4(): CollageLayout {\n        return collage(\"collage_14_4\") {\n            parametricStackedRowStrips(listOf(6, 4, 4))\n        }\n    }\n\n    internal fun collage_14_5(): CollageLayout {\n        return collage(\"collage_14_5\") {\n            parametricStackedRowStrips(listOf(4, 4, 3, 3))\n        }\n    }\n\n    internal fun collage_14_6(): CollageLayout {\n        return collage(\"collage_14_6\") {\n            rowStrip(0f, 0.18f, 4)\n            fixedRect(0f, 0.18f, 0.18f, 0.82f)\n            fixedRect(0.82f, 0.18f, 1f, 0.82f)\n            fixedRect(0.18f, 0.18f, 0.41f, 0.41f)\n            fixedRect(0.41f, 0.18f, 0.59f, 0.41f)\n            fixedRect(0.59f, 0.18f, 0.82f, 0.41f)\n            fixedRect(0.18f, 0.41f, 0.41f, 0.82f)\n            fixedRect(0.41f, 0.41f, 0.59f, 0.82f)\n            fixedRect(0.59f, 0.41f, 0.82f, 0.82f)\n            rowStrip(0.82f, 1f, 2)\n        }\n    }\n\n    internal fun collage_14_7(): CollageLayout {\n        return collage(\"collage_14_7\") {\n            parametricStackedRowStrips(listOf(3, 6, 5))\n        }\n    }\n\n    internal fun collage_14_8(): CollageLayout {\n        return collage(\"collage_14_8\") {\n            parametricStackedRowStrips(listOf(5, 4, 3, 2))\n        }\n    }\n\n    internal fun collage_14_9(): CollageLayout {\n        return collage(\"collage_14_9\") {\n            parametricStackedRowStrips(listOf(2, 4, 4, 4))\n        }\n    }\n\n    internal fun collage_14_10(): CollageLayout {\n        return collage(\"collage_14_10\") {\n            rowStrip(0f, 0.2f, 4)\n            fixedRect(0f, 0.2f, 0.2f, 0.82f)\n            fixedRect(0.2f, 0.2f, 0.4f, 0.51f)\n            fixedRect(0.4f, 0.2f, 0.6f, 0.51f)\n            fixedRect(0.6f, 0.2f, 0.8f, 0.51f)\n            fixedRect(0.8f, 0.2f, 1f, 0.82f)\n            fixedRect(0.2f, 0.51f, 0.4f, 0.82f)\n            fixedRect(0.4f, 0.51f, 0.6f, 0.82f)\n            fixedRect(0.6f, 0.51f, 0.8f, 0.82f)\n            rowStrip(0.82f, 1f, 2)\n        }\n    }\n\n    internal fun collage_15_0(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_15_0\", rows = 3, cols = 5)\n    }\n\n    internal fun collage_15_1(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_15_1\", rows = 5, cols = 3)\n    }\n\n    internal fun collage_15_2(): CollageLayout {\n        return collage(\"collage_15_2\") {\n            parametricStackedRowStrips(listOf(2, 3, 3, 4, 5))\n        }\n    }\n\n    internal fun collage_15_3(): CollageLayout {\n        return collage(\"collage_15_3\") {\n            parametricStackedRowStrips(listOf(4, 5, 6))\n        }\n    }\n\n    internal fun collage_15_4(): CollageLayout {\n        return collage(\"collage_15_4\") {\n            parametricStackedRowStrips(listOf(3, 5, 7))\n        }\n    }\n\n    internal fun collage_15_5(): CollageLayout {\n        return collage(\"collage_15_5\") {\n            parametricStackedRowStrips(listOf(4, 4, 4, 3))\n        }\n    }\n\n    internal fun collage_15_6(): CollageLayout {\n        return collage(\"collage_15_6\") {\n            rowStrip(0f, 0.2f, 5)\n            fixedRect(0f, 0.2f, 0.22f, 0.8f)\n            fixedRect(0.22f, 0.2f, 0.39f, 0.8f)\n            fixedRect(0.39f, 0.2f, 0.61f, 0.5f)\n            fixedRect(0.61f, 0.2f, 0.78f, 0.8f)\n            fixedRect(0.78f, 0.2f, 1f, 0.8f)\n            fixedRect(0.39f, 0.5f, 0.61f, 0.8f)\n            rowStrip(0.8f, 1f, 4)\n        }\n    }\n\n    internal fun collage_15_7(): CollageLayout {\n        return collage(\"collage_15_7\") {\n            parametricStackedRowStrips(listOf(3, 4, 5, 3))\n        }\n    }\n\n    internal fun collage_15_8(): CollageLayout {\n        return collage(\"collage_15_8\") {\n            parametricStackedRowStrips(listOf(2, 5, 5, 3))\n        }\n    }\n\n    internal fun collage_15_9(): CollageLayout {\n        return collage(\"collage_15_9\") {\n            parametricStackedRowStrips(listOf(6, 4, 3, 2))\n        }\n    }\n\n    internal fun collage_15_10(): CollageLayout {\n        return collage(\"collage_15_10\") {\n            rowStrip(0f, 0.18f, 5)\n            fixedRect(0f, 0.18f, 0.2f, 0.82f)\n            fixedRect(0.2f, 0.18f, 0.4f, 0.5f)\n            fixedRect(0.4f, 0.18f, 0.6f, 0.5f)\n            fixedRect(0.6f, 0.18f, 0.8f, 0.5f)\n            fixedRect(0.8f, 0.18f, 1f, 0.82f)\n            fixedRect(0.2f, 0.5f, 0.4f, 0.82f)\n            fixedRect(0.4f, 0.5f, 0.6f, 0.82f)\n            fixedRect(0.6f, 0.5f, 0.8f, 0.82f)\n            rowStrip(0.82f, 1f, 2)\n        }\n    }\n\n    internal fun collage_16_0(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_16_0\", rows = 4, cols = 4)\n    }\n\n    internal fun collage_16_1(): CollageLayout {\n        return collage(\"collage_16_1\") {\n            parametricStackedRowStrips(listOf(5, 5, 6))\n        }\n    }\n\n    internal fun collage_16_2(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_16_2\", rows = 8, cols = 2)\n    }\n\n    internal fun collage_16_3(): CollageLayout {\n        return collage(\"collage_16_3\") {\n            parametricStackedRowStrips(listOf(3, 4, 5, 4))\n        }\n    }\n\n    internal fun collage_16_4(): CollageLayout {\n        return collage(\"collage_16_4\") {\n            parametricStackedRowStrips(listOf(2, 4, 4, 6))\n        }\n    }\n\n    internal fun collage_16_5(): CollageLayout {\n        return collage(\"collage_16_5\") {\n            parametricStackedRowStrips(listOf(6, 5, 5))\n        }\n    }\n\n    internal fun collage_16_6(): CollageLayout {\n        return collage(\"collage_16_6\") {\n            parametricStackedRowStrips(listOf(3, 5, 5, 3))\n        }\n    }\n\n    internal fun collage_16_7(): CollageLayout {\n        return collage(\"collage_16_7\") {\n            parametricStackedRowStrips(listOf(3, 5, 4, 4))\n        }\n    }\n\n    internal fun collage_16_8(): CollageLayout {\n        return collage(\"collage_16_8\") {\n            parametricStackedRowStrips(listOf(2, 4, 6, 4))\n        }\n    }\n\n    internal fun collage_16_9(): CollageLayout {\n        return collage(\"collage_16_9\") {\n            rowStrip(0f, 0.18f, 4)\n            fixedRect(0f, 0.18f, 0.2f, 0.82f)\n            uniformGridInRegion(2, 3, 0.2f, 0.18f, 0.8f, 0.82f)\n            fixedRect(0.8f, 0.18f, 1f, 0.82f)\n            rowStrip(0.82f, 1f, 4)\n        }\n    }\n\n    internal fun collage_16_10(): CollageLayout {\n        return collage(\"collage_16_10\") {\n            rowStrip(0f, 0.22f, 5)\n            fixedRect(0f, 0.22f, 0.22f, 0.8f)\n            fixedRect(0.22f, 0.22f, 0.39f, 0.5f)\n            fixedRect(0.39f, 0.22f, 0.61f, 0.5f)\n            fixedRect(0.61f, 0.22f, 0.78f, 0.5f)\n            fixedRect(0.78f, 0.22f, 1f, 0.8f)\n            fixedRect(0.22f, 0.5f, 0.39f, 0.8f)\n            fixedRect(0.39f, 0.5f, 0.61f, 0.8f)\n            fixedRect(0.61f, 0.5f, 0.78f, 0.8f)\n            rowStrip(0.8f, 1f, 3)\n        }\n    }\n\n    internal fun collage_17_0(): CollageLayout {\n        return collage(\"collage_17_0\") {\n            parametricStackedRowStrips(listOf(4, 4, 4, 5))\n        }\n    }\n\n    internal fun collage_17_1(): CollageLayout {\n        return collage(\"collage_17_1\") {\n            parametricStackedRowStrips(listOf(6, 6, 5))\n        }\n    }\n\n    internal fun collage_17_2(): CollageLayout {\n        return collage(\"collage_17_2\") {\n            parametricStackedRowStrips(listOf(5, 6, 6))\n        }\n    }\n\n    internal fun collage_17_3(): CollageLayout {\n        return collage(\"collage_17_3\") {\n            parametricStackedRowStrips(listOf(4, 4, 5, 4))\n        }\n    }\n\n    internal fun collage_17_4(): CollageLayout {\n        return collage(\"collage_17_4\") {\n            parametricStackedRowStrips(listOf(7, 5, 5))\n        }\n    }\n\n    internal fun collage_17_5(): CollageLayout {\n        return collage(\"collage_17_5\") {\n            parametricStackedRowStrips(listOf(3, 4, 4, 6))\n        }\n    }\n\n    internal fun collage_17_6(): CollageLayout {\n        return collage(\"collage_17_6\") {\n            parametricStackedRowStrips(listOf(3, 5, 5, 4))\n        }\n    }\n\n    internal fun collage_17_7(): CollageLayout {\n        return collage(\"collage_17_7\") {\n            parametricStackedRowStrips(listOf(2, 5, 6, 4))\n        }\n    }\n\n    internal fun collage_17_8(): CollageLayout {\n        return collage(\"collage_17_8\") {\n            parametricStackedRowStrips(listOf(4, 4, 4, 3, 2))\n        }\n    }\n\n    internal fun collage_17_9(): CollageLayout {\n        return collage(\"collage_17_9\") {\n            rowStrip(0f, 0.24f, 5)\n            rowStrip(0.24f, 0.76f, 7)\n            rowStrip(0.76f, 1f, 5)\n        }\n    }\n\n    internal fun collage_17_10(): CollageLayout {\n        return collage(\"collage_17_10\") {\n            rowStrip(0f, 0.2f, 4)\n            fixedRect(0f, 0.2f, 0.2f, 0.8f)\n            fixedRect(0.2f, 0.2f, 0.4f, 0.5f)\n            fixedRect(0.4f, 0.2f, 0.6f, 0.5f)\n            fixedRect(0.6f, 0.2f, 0.8f, 0.5f)\n            fixedRect(0.8f, 0.2f, 1f, 0.8f)\n            fixedRect(0.2f, 0.5f, 0.4f, 0.8f)\n            fixedRect(0.4f, 0.5f, 0.6f, 0.8f)\n            fixedRect(0.6f, 0.5f, 0.8f, 0.8f)\n            rowStrip(0.8f, 1f, 5)\n        }\n    }\n\n    internal fun collage_18_0(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_18_0\", rows = 3, cols = 6)\n    }\n\n    internal fun collage_18_1(): CollageLayout {\n        return CollageLayoutFactory.collageParametricGrid(\"collage_18_1\", rows = 6, cols = 3)\n    }\n\n    internal fun collage_18_2(): CollageLayout {\n        return collage(\"collage_18_2\") {\n            parametricStackedRowStrips(listOf(6, 6, 6))\n        }\n    }\n\n    internal fun collage_18_3(): CollageLayout {\n        return collage(\"collage_18_3\") {\n            parametricStackedRowStrips(listOf(4, 5, 5, 4))\n        }\n    }\n\n    internal fun collage_18_4(): CollageLayout {\n        return collage(\"collage_18_4\") {\n            parametricStackedRowStrips(listOf(3, 5, 4, 6))\n        }\n    }\n\n    internal fun collage_18_5(): CollageLayout {\n        return collage(\"collage_18_5\") {\n            parametricStackedRowStrips(listOf(4, 4, 4, 3, 3))\n        }\n    }\n\n    internal fun collage_18_6(): CollageLayout {\n        return collage(\"collage_18_6\") {\n            parametricStackedRowStrips(listOf(3, 5, 6, 4))\n        }\n    }\n\n    internal fun collage_18_7(): CollageLayout {\n        return collage(\"collage_18_7\") {\n            parametricStackedRowStrips(listOf(2, 4, 6, 6))\n        }\n    }\n\n    internal fun collage_18_8(): CollageLayout {\n        return collage(\"collage_18_8\") {\n            parametricStackedRowStrips(listOf(5, 5, 4, 4))\n        }\n    }\n\n    internal fun collage_18_9(): CollageLayout {\n        return collage(\"collage_18_9\") {\n            rowStrip(0f, 0.18f, 4)\n            fixedRect(0f, 0.18f, 0.18f, 0.82f)\n            uniformGridInRegion(2, 4, 0.18f, 0.18f, 0.82f, 0.82f)\n            fixedRect(0.82f, 0.18f, 1f, 0.82f)\n            rowStrip(0.82f, 1f, 4)\n        }\n    }\n\n    internal fun collage_18_10(): CollageLayout {\n        return collage(\"collage_18_10\") {\n            rowStrip(0f, 0.2f, 5)\n            fixedRect(0f, 0.2f, 0.2f, 0.8f)\n            fixedRect(0.2f, 0.2f, 0.35f, 0.8f)\n            fixedRect(0.35f, 0.2f, 0.65f, 0.5f)\n            fixedRect(0.65f, 0.2f, 0.8f, 0.8f)\n            fixedRect(0.8f, 0.2f, 1f, 0.8f)\n            fixedRect(0.35f, 0.5f, 0.65f, 0.8f)\n            rowStrip(0.8f, 1f, 7)\n        }\n    }\n\n    internal fun collage_19_0(): CollageLayout {\n        return collage(\"collage_19_0\") {\n            parametricStackedRowStrips(listOf(5, 5, 5, 4))\n        }\n    }\n\n    internal fun collage_19_1(): CollageLayout {\n        return collage(\"collage_19_1\") {\n            parametricStackedRowStrips(listOf(4, 5, 5, 5))\n        }\n    }\n\n    internal fun collage_19_2(): CollageLayout {\n        return collage(\"collage_19_2\") {\n            parametricStackedRowStrips(listOf(6, 6, 7))\n        }\n    }\n\n    internal fun collage_19_3(): CollageLayout {\n        return collage(\"collage_19_3\") {\n            parametricStackedRowStrips(listOf(3, 4, 5, 7))\n        }\n    }\n\n    internal fun collage_19_4(): CollageLayout {\n        return collage(\"collage_19_4\") {\n            parametricStackedRowStrips(listOf(2, 6, 6, 5))\n        }\n    }\n\n    internal fun collage_19_5(): CollageLayout {\n        return collage(\"collage_19_5\") {\n            parametricStackedRowStrips(listOf(4, 4, 4, 4, 3))\n        }\n    }\n\n    internal fun collage_19_6(): CollageLayout {\n        return collage(\"collage_19_6\") {\n            parametricStackedRowStrips(listOf(3, 5, 6, 5))\n        }\n    }\n\n    internal fun collage_19_7(): CollageLayout {\n        return collage(\"collage_19_7\") {\n            parametricStackedRowStrips(listOf(4, 5, 5, 3, 2))\n        }\n    }\n\n    internal fun collage_19_8(): CollageLayout {\n        return collage(\"collage_19_8\") {\n            parametricStackedRowStrips(listOf(2, 4, 6, 4, 3))\n        }\n    }\n\n    internal fun collage_19_9(): CollageLayout {\n        return collage(\"collage_19_9\") {\n            rowStrip(0f, 0.16f, 5)\n            fixedRect(0f, 0.16f, 0.16f, 0.84f)\n            uniformGridInRegion(2, 4, 0.16f, 0.16f, 0.84f, 0.84f)\n            fixedRect(0.84f, 0.16f, 1f, 0.84f)\n            rowStrip(0.84f, 1f, 4)\n        }\n    }\n\n    internal fun collage_19_10(): CollageLayout {\n        return collage(\"collage_19_10\") {\n            rowStrip(0f, 0.2f, 5)\n            fixedRect(0f, 0.2f, 0.2f, 0.8f)\n            fixedRect(0.2f, 0.2f, 0.36f, 0.8f)\n            fixedRect(0.36f, 0.2f, 0.5f, 0.5f)\n            fixedRect(0.5f, 0.2f, 0.64f, 0.5f)\n            fixedRect(0.64f, 0.2f, 0.8f, 0.8f)\n            fixedRect(0.8f, 0.2f, 1f, 0.8f)\n            fixedRect(0.36f, 0.5f, 0.5f, 0.8f)\n            fixedRect(0.5f, 0.5f, 0.64f, 0.8f)\n            rowStrip(0.8f, 1f, 6)\n        }\n    }\n\n    internal fun collage_20_0(): CollageLayout {\n        return collage(\"collage_20_0\") {\n            parametricStackedRowStrips(listOf(7, 6, 7))\n        }\n    }\n\n    internal fun collage_20_1(): CollageLayout {\n        return collage(\"collage_20_1\") {\n            parametricStackedRowStrips(listOf(6, 5, 4, 3, 2))\n        }\n    }\n\n    internal fun collage_20_2(): CollageLayout {\n        return collage(\"collage_20_2\") {\n            parametricStackedRowStrips(listOf(4, 4, 4, 4, 4))\n        }\n    }\n\n    internal fun collage_20_3(): CollageLayout {\n        return collage(\"collage_20_3\") {\n            parametricStackedRowStrips(listOf(5, 5, 5, 5))\n        }\n    }\n\n    internal fun collage_20_4(): CollageLayout {\n        return collage(\"collage_20_4\") {\n            parametricStackedRowStrips(listOf(3, 7, 7, 3))\n        }\n    }\n\n    internal fun collage_20_5(): CollageLayout {\n        return collage(\"collage_20_5\") {\n            parametricStackedRowStrips(listOf(7, 6, 4, 3))\n        }\n    }\n\n    internal fun collage_20_6(): CollageLayout {\n        return collage(\"collage_20_6\") {\n            parametricStackedRowStrips(listOf(4, 6, 6, 4))\n        }\n    }\n\n    internal fun collage_20_7(): CollageLayout {\n        return collage(\"collage_20_7\") {\n            parametricStackedRowStrips(listOf(3, 5, 6, 4, 2))\n        }\n    }\n\n    internal fun collage_20_8(): CollageLayout {\n        return collage(\"collage_20_8\") {\n            parametricStackedRowStrips(listOf(5, 5, 4, 3, 3))\n        }\n    }\n\n    internal fun collage_20_9(): CollageLayout {\n        return collage(\"collage_20_9\") {\n            rowStrip(0f, 0.16f, 5)\n            fixedRect(0f, 0.16f, 0.16f, 0.84f)\n            uniformGridInRegion(2, 4, 0.16f, 0.16f, 0.84f, 0.84f)\n            fixedRect(0.84f, 0.16f, 1f, 0.84f)\n            rowStrip(0.84f, 1f, 5)\n        }\n    }\n\n    internal fun collage_20_10(): CollageLayout {\n        return collage(\"collage_20_10\") {\n            rowStrip(0f, 0.18f, 6)\n            fixedRect(0f, 0.18f, 0.18f, 0.82f)\n            fixedRect(0.18f, 0.18f, 0.34f, 0.82f)\n            fixedRect(0.34f, 0.18f, 0.5f, 0.5f)\n            fixedRect(0.5f, 0.18f, 0.66f, 0.5f)\n            fixedRect(0.66f, 0.18f, 0.82f, 0.82f)\n            fixedRect(0.82f, 0.18f, 1f, 0.82f)\n            fixedRect(0.34f, 0.5f, 0.5f, 0.82f)\n            fixedRect(0.5f, 0.5f, 0.66f, 0.82f)\n            rowStrip(0.82f, 1f, 6)\n        }\n    }\n\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/FiveFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.Path\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.view.PhotoItem\n\n/**\n * Created by admin on 6/24/2016.\n */\ninternal object FiveFrameImage {\n    internal fun collage_5_31(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_31\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.3333f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 0.6666f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.6666f, 1f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6666f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.6666f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6666f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.3333f, 0f))\n        photoItem.pointList.add(PointF(0.6666f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.3333f, 0.3333f, 0.6666f, 0.6666f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_30(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_30\") {\n            val wallTopY = param(0.3333f)\n            val wallBottomY = param(0.6666f)\n            val wallLeftX = param(0.3333f)\n            val wallRightX = param(0.6666f)\n\n            addBoxedItem(\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(0f, 0f, 1f, vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallLeftX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallTopY], vs[wallLeftX], vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallLeftX, wallRightX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs ->\n                    RectF(\n                        vs[wallLeftX],\n                        vs[wallTopY],\n                        vs[wallRightX],\n                        vs[wallBottomY]\n                    )\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wallRightX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(vs[wallRightX], vs[wallTopY], 1f, vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallBottomY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_29(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_29\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.4444f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.75f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0f, 1f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.1666f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0f, 0.3333f, 1f, 0.6666f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6666f, 0.6667f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.8333f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5556f, 0.6666f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.25f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_28(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_28\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.4f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6667f, 0.2f, 1f, 0.8f)\n        photoItem.pointList.add(PointF(0f, 0.1111f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.8888f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0.2667f, 0.6667f, 0.7333f)\n        photoItem.pointList.add(PointF(0f, 0.1428f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.8571f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.3333f, 0.3333f, 0.6667f)\n        photoItem.pointList.add(PointF(0f, 0.2f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.8f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_27(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_27\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.4f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.2f, 0.3333f, 0.8f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.1111f))\n        photoItem.pointList.add(PointF(1f, 0.8888f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0.2667f, 0.6667f, 0.7333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.1428f))\n        photoItem.pointList.add(PointF(1f, 0.8571f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6666f, 0.3333f, 1f, 0.6667f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.2f))\n        photoItem.pointList.add(PointF(1f, 0.8f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_26(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_26\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.6f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.8333f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0.2f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.3333f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.75f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.5f, 0.75f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.8333f, 1f))\n        photoItem.pointList.add(PointF(0.1666f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.6667f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.25f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_25(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_25\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.25f, 0f, 0.75f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_24(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_24\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.75f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.75f)\n        photoItem.pointList.add(PointF(0f, 0.3333f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0.6667f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.25f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.6667f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_23(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_23\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.6667f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6667f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.3333f, 0.3333f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6667f, 0.6667f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.3333f, 0.3333f, 0.6667f, 0.6667f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_22(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_22\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_21(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_21\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_20(): CollageLayout {\n        return collage_5_19(\n            name = \"collage_5_20\",\n            x1 = 0.5f,\n            x2 = 0.5f,\n            y1 = 0.3333f,\n            y2 = 0.6666f\n        )\n    }\n\n    internal fun collage_5_19(\n        name: String = \"collage_5_19\",\n        x1: Float = 0.6f,\n        x2: Float = 0.4f,\n        y1: Float = 0.3333f,\n        y2: Float = 0.6666f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wallTopSplitX = param(x1)\n            val wallBottomSplitX = param(x2)\n            val wallTopY = param(y1)\n            val wallBottomY = param(y2)\n\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallTopSplitX], vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(vs[wallTopSplitX], 0f, 1f, vs[wallTopY]) }\n            )\n            addBoxedItem(\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallTopY], 1f, vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallBottomSplitX),\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallBottomY], vs[wallBottomSplitX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallBottomSplitX),\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(vs[wallBottomSplitX], vs[wallBottomY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_18(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_18\") {\n            val wallTopSplitX = param(0.6f)\n            val wallMidSplitX = param(0.4f)\n            val wallTopY = param(0.3333f)\n            val wallBottomY = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallTopSplitX], vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(vs[wallTopSplitX], 0f, 1f, vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidSplitX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallTopY], vs[wallMidSplitX], vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidSplitX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(vs[wallMidSplitX], vs[wallTopY], 1f, vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallBottomY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_17(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_17\") {\n            val wallMidX = param(0.5f)\n            val wallTopY = param(0.3333f)\n            val wallBottomY = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallMidX], vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(vs[wallMidX], 0f, 1f, vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallTopY], vs[wallMidX], vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(vs[wallMidX], vs[wallTopY], 1f, vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallBottomY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_16(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_16\") {\n            val wallTopY = param(0.3333f)\n            val wallBottomY = param(0.6666f)\n            val wallMidX = param(0.5f)\n\n            addBoxedItem(\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(0f, 0f, 1f, vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallTopY], vs[wallMidX], vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(vs[wallMidX], vs[wallTopY], 1f, vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(0f, vs[wallBottomY], vs[wallMidX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(vs[wallMidX], vs[wallBottomY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_15(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_15\") {\n            val wallLeftX = param(0.6f)\n            val wallY1 = param(0.25f)\n            val wallY2 = param(0.5f)\n            val wallY3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(wallLeftX),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallLeftX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallLeftX),\n                yParams = listOf(wallY1),\n                boxParams = { vs -> RectF(vs[wallLeftX], 0f, 1f, vs[wallY1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallLeftX),\n                yParams = listOf(wallY1, wallY2),\n                boxParams = { vs -> RectF(vs[wallLeftX], vs[wallY1], 1f, vs[wallY2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallLeftX),\n                yParams = listOf(wallY2, wallY3),\n                boxParams = { vs -> RectF(vs[wallLeftX], vs[wallY2], 1f, vs[wallY3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallLeftX),\n                yParams = listOf(wallY3),\n                boxParams = { vs -> RectF(vs[wallLeftX], vs[wallY3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_14(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_14\") {\n            val wallX1 = param(0.3333f)\n            val wallX2 = param(0.6666f)\n            val wallY = param(0.4f)\n\n            addBoxedItem(\n                xParams = listOf(wallX1),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallX1], vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX1, wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX1], 0f, vs[wallX2], vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX2], 0f, 1f, vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(0f, vs[wallY], vs[wallX2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX2], vs[wallY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_13(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_13\") {\n            val wallX1 = param(0.3333f)\n            val wallX2 = param(0.6666f)\n            val wallY = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(wallX1),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallX1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX1, wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX1], 0f, vs[wallX2], vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX2], 0f, 1f, vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX1, wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX1], vs[wallY], vs[wallX2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX2], vs[wallY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_12(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_12\") {\n            val wallTopSplitX = param(0.4f)\n            val wallMidSplitX = param(0.6f)\n            val wallTopY = param(0.3333f)\n            val wallBottomY = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallTopSplitX], vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(vs[wallTopSplitX], 0f, 1f, vs[wallTopY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidSplitX),\n                yParams = listOf(wallTopY),\n                boxParams = { vs -> RectF(0f, vs[wallTopY], vs[wallMidSplitX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidSplitX),\n                yParams = listOf(wallTopY, wallBottomY),\n                boxParams = { vs -> RectF(vs[wallMidSplitX], vs[wallTopY], 1f, vs[wallBottomY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidSplitX),\n                yParams = listOf(wallBottomY),\n                boxParams = { vs -> RectF(vs[wallMidSplitX], vs[wallBottomY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_11(): CollageLayout {\n        return collage_5_10(name = \"collage_5_11\", y1 = 0.3333f)\n    }\n\n    internal fun collage_5_10(\n        name: String = \"collage_5_10\",\n        x1: Float = 0.3333f,\n        x2: Float = 0.6667f,\n        y1: Float = 0.5f,\n        y2: Float = 0.6667f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wallX1 = param(x1)\n            val wallX2 = param(x2)\n            val wallY1 = param(y1)\n            val wallY2 = param(y2)\n\n            addBoxedItem(\n                xParams = listOf(wallX1),\n                yParams = listOf(wallY1),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallX1], vs[wallY1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX1),\n                yParams = listOf(wallY1),\n                boxParams = { vs -> RectF(0f, vs[wallY1], vs[wallX1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX1),\n                yParams = listOf(wallY2),\n                boxParams = { vs -> RectF(vs[wallX1], 0f, 1f, vs[wallY2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX1, wallX2),\n                yParams = listOf(wallY2),\n                boxParams = { vs -> RectF(vs[wallX1], vs[wallY2], vs[wallX2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX2),\n                yParams = listOf(wallY2),\n                boxParams = { vs -> RectF(vs[wallX2], vs[wallY2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_9(): CollageLayout {\n        return collage_5_8(name = \"collage_5_9\", x1 = 0.3333f, x2 = 0.6667f)\n    }\n\n    internal fun collage_5_8(\n        name: String = \"collage_5_8\",\n        x1: Float = 0.6667f,\n        x2: Float = 0.3333f,\n        y1: Float = 0.3333f,\n        y2: Float = 0.6666f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wallTopSplitX = param(x1)\n            val wallBottomSplitX = param(x2)\n            val wallY1 = param(y1)\n            val wallY2 = param(y2)\n\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallY1),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallTopSplitX], vs[wallY1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallTopSplitX),\n                yParams = listOf(wallY1),\n                boxParams = { vs -> RectF(vs[wallTopSplitX], 0f, 1f, vs[wallY1]) }\n            )\n            addBoxedItem(\n                yParams = listOf(wallY1, wallY2),\n                boxParams = { vs -> RectF(0f, vs[wallY1], 1f, vs[wallY2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallBottomSplitX),\n                yParams = listOf(wallY2),\n                boxParams = { vs -> RectF(0f, vs[wallY2], vs[wallBottomSplitX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallBottomSplitX),\n                yParams = listOf(wallY2),\n                boxParams = { vs -> RectF(vs[wallBottomSplitX], vs[wallY2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_6(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_6\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //five frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_7(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_7\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(0.5f, 0.5f, 1.5f, 1.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(-0.5f, 0.5f, 0.5f, 1.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(-0.5f, -0.5f, 0.5f, 0.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(0.5f, -0.5f, 1.5f, 0.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //five frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.path = Path()\n        photoItem.path!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.pathRatioBound = RectF(0f, 0f, 1f, 1f)\n        photoItem.pathInCenterHorizontal = true\n        photoItem.pathInCenterVertical = true\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_5(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_5\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.clearPathRatioBound = RectF(0.5f, 0.5f, 1.5f, 1.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.clearPathRatioBound = RectF(-0.5f, 0.5f, 0.5f, 1.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.clearPathRatioBound = RectF(-0.5f, -0.5f, 0.5f, 0.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.clearPathRatioBound = RectF(0.5f, -0.5f, 1.5f, 0.5f)\n        photoItem.centerInClearBound = true\n        photoItemList.add(photoItem)\n        //five frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.path = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.pathRatioBound = RectF(0f, 0f, 1f, 1f)\n        photoItem.pathInCenterHorizontal = true\n        photoItem.pathInCenterVertical = true\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_4(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_4\") {\n            val wallX1 = param(0.3333f)\n            val wallX2 = param(0.6666f)\n            val wallX3 = param(0.5f)\n            val wallY = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(wallX1),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallX1], vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX1, wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX1], 0f, vs[wallX2], vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX2),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX2], 0f, 1f, vs[wallY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX3),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(0f, vs[wallY], vs[wallX3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallX3),\n                yParams = listOf(wallY),\n                boxParams = { vs -> RectF(vs[wallX3], vs[wallY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_3(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_3\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //five frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_2(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_2\") {\n            val wallMidX = param(0.5f)\n            val wallLeftY = param(0.5f)\n            val wallRightY1 = param(0.3333f)\n            val wallRightY2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallLeftY),\n                boxParams = { vs -> RectF(0f, 0f, vs[wallMidX], vs[wallLeftY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallLeftY),\n                boxParams = { vs -> RectF(0f, vs[wallLeftY], vs[wallMidX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallRightY1),\n                boxParams = { vs -> RectF(vs[wallMidX], 0f, 1f, vs[wallRightY1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallRightY1, wallRightY2),\n                boxParams = { vs -> RectF(vs[wallMidX], vs[wallRightY1], 1f, vs[wallRightY2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(wallMidX),\n                yParams = listOf(wallRightY2),\n                boxParams = { vs -> RectF(vs[wallMidX], vs[wallRightY2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_5_1(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_5_1\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //five frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.disableShrink = true\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(0.625f, 0.375f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.625f, 0.625f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0.375f, 0.625f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(0.375f, 0.375f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_5_0(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_5_0\") {\n            val wall1X = param(0.25f)\n            val wall2X = param(0.75f)\n            val wall3Y = param(0.25f)\n            val wall4Y = param(0.75f)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall4Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall4Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X, wall2X),\n                yParams = listOf(wall3Y, wall4Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall3Y], vs[wall2X], vs[wall4Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall2X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall2X], vs[wall3Y], 1f, 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall2X),\n                yParams = listOf(wall4Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall4Y], vs[wall2X], 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_5_1_1(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_5_1_1\",\n            count = 5,\n            isHorizontal = true\n        )\n    }\n\n    internal fun collage_5_1_2(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_5_1_2\",\n            count = 5,\n            isHorizontal = false\n        )\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/FourFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.view.PhotoItem\n\n/**\n * Created by admin on 6/20/2016.\n */\ninternal object FourFrameImage {\n    internal fun collage_4_25(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_25\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.6667f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.6667f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_24(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_24\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.3f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.6667f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.2f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 0.6667f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.4f, 1f, 0.8f)\n        photoItem.pointList.add(PointF(0f, 0.25f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.75f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.7f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_23(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_23\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.6f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.6667f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.8333f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.6f))\n        photoItem.pointList.add(PointF(0.25f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.3f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.2857f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.6667f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.2f))\n        photoItem.pointList.add(PointF(0.75f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_22(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_22\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.8f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.4f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.1666f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.2f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.6f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.8333f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_21(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_21\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.25f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.3333f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.25f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.75f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.75f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.75f))\n        photoItem.pointList.add(PointF(0.6667f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_20(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_20\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.75f, 0.6667f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.6667f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.3333f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.6667f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6667f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_19(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_19\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_18(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_18\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_17(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_17\") {\n            val wall1X = param(0.5f)\n            val wall2Y = param(0.25f)\n            val wall3Y = param(0.75f)\n            addBoxedItem(\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y, wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y, wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall2Y], 1f, vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall3Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_16(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_16\") {\n            val wall1X = param(0.3333f)\n            val wall2Y = param(0.3333f)\n            val wall3Y = param(0.6666f)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y, wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall3Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_15(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_15\") {\n            val wall1X = param(0.6667f)\n            val wall2Y = param(0.3333f)\n            val wall3Y = param(0.6666f)\n            addBoxedItem(\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y, wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall2Y], 1f, vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall3Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_14(): CollageLayout {\n        return collage_4_0(\"collage_4_14\", 0.3333f, 0.6667f)\n    }\n\n    internal fun collage_4_13(): CollageLayout {\n        return collage_4_0(\"collage_4_13\", 0.6667f, 0.3333f)\n    }\n\n    internal fun collage_4_12(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_12\") {\n            val wall1X = param(0.5f)\n            val wall2Y = param(0.3333f)\n            val wall3Y = param(0.6666f)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y, wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall3Y], vs[wall1X], 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_11(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_11\") {\n            val wall1X = param(0.5f)\n            val wall2Y = param(0.3333f)\n            val wall3Y = param(0.6666f)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y, wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall2Y], 1f, vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall3Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_10(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_10\") {\n            val wall1X = param(0.3333f)\n            val wall2X = param(0.6666f)\n            val wall3Y = param(0.5f)\n            addBoxedItem(\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall3Y], 1f, 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X, wall2X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, vs[wall2X], vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall2X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall2X], 0f, 1f, vs[wall3Y])\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_9(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_9\") {\n            val wall1X = param(0.3333f)\n            val wall2X = param(0.6666f)\n            val wallY = param(0.5f)\n\n            addBoxedItem(\n                yParams = listOf(wallY),\n                boxParams = { vs ->\n                    RectF(0f, 0f, 1f, vs[wallY])\n                }\n            )\n\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wallY),\n                boxParams = { vs ->\n                    RectF(0f, vs[wallY], vs[wall1X], 1f)\n                }\n            )\n\n            addBoxedItem(\n                xParams = listOf(wall1X, wall2X),\n                yParams = listOf(wallY),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wallY], vs[wall2X], 1f)\n                }\n            )\n\n            addBoxedItem(\n                xParams = listOf(wall2X),\n                yParams = listOf(wallY),\n                boxParams = { vs ->\n                    RectF(vs[wall2X], vs[wallY], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_8(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_8\") {\n            val wall1X = param(0.4f)\n            val wall2X = param(0.6f)\n            val wall3Y = param(0.4f)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall2X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall2X], vs[wall3Y], 1f, 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall2X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall3Y], vs[wall2X], 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_7(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_4_7\") {\n            val wall1X = param(0.5f)\n            val wall2Y = param(0.3333f)\n            val wall3Y = param(0.6667f)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall3Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall3Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall3Y], 1f, 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_4_6(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_6\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.3333f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0f, 1f, 0.6667f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0.6667f, 0.6667f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.3333f, 0.6667f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_5(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_5\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.6667f, 0.6667f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.6667f, 0f, 1f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0.3333f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.bound.set(0f, 0.6667f, 0.3333f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_4(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_4\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.6667f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0f, 1f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.1666f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.4444f, 0.3333f, 1f, 0.6666f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.2f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5555f, 0.6666f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.25f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_2(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_4_2\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.6667f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.75f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.6667f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.6667f)\n        photoItem.pointList.add(PointF(0.3333f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.75f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.25f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //four frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.3333f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.25f))\n        photoItem.pointList.add(PointF(0.6667f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_4_1(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_4_1\",\n            count = 4,\n            isHorizontal = true\n        )\n    }\n\n    internal fun collage_4_1_1(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_4_1_1\",\n            count = 4,\n            isHorizontal = false\n        )\n    }\n\n    internal fun collage_4_0(\n        name: String = \"collage_4_0\",\n        initialX: Float = 0.5f,\n        initialY: Float = 0.5f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wall1X = param(initialX)\n            val wall2Y = param(initialY)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall2Y], 1f, 1f)\n                }\n            )\n        }\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/NineFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.view.PhotoItem\n\n/**\n * All points of polygon must be ordered by clockwise along<br></br>\n * Created by admin on 7/3/2016.\n */\ninternal object NineFrameImage {\n    internal fun collage_9_11(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_9_11\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.2666f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.7519f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.2f, 0f, 0.8f, 0.3333f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.8889f, 1f))\n        photoItem.pointList.add(PointF(0.1111f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 8\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.7334f, 0f, 1f, 0.3333f)\n        photoItem.pointList.add(PointF(0.2481f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.3333f, 0.3333f, 0.6666f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.8f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.2666f, 0.3333f, 0.7334f, 0.6666f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.8572f, 1f))\n        photoItem.pointList.add(PointF(0.1428f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //sixth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6666f, 0.3333f, 1f, 0.6666f)\n        photoItem.pointList.add(PointF(0.2f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //seventh frame\n        photoItem = PhotoItem()\n        photoItem.index = 5\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6666f, 0.4f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.8333f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //eighth frame\n        photoItem = PhotoItem()\n        photoItem.index = 6\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.3333f, 0.6666f, 0.6666f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.8f, 1f))\n        photoItem.pointList.add(PointF(0.2f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //ninth frame\n        photoItem = PhotoItem()\n        photoItem.index = 7\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6f, 0.6666f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.1666f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_9_10(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_9_10\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.39645f, 0.39645f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.73881f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.6306f))\n        photoItem.pointList.add(PointF(0.6306f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.73881f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.2929f, 0f, 0.7071f, 0.25f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.75f, 1f))\n        photoItem.pointList.add(PointF(0.25f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 8\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.60355f, 0f, 1f, 0.39645f)\n        photoItem.pointList.add(PointF(0.26119f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.73881f))\n        photoItem.pointList.add(PointF(0.3694f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.6306f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.75f, 0.2929f, 1f, 0.7071f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.75f))\n        photoItem.pointList.add(PointF(0f, 0.25f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.60355f, 0.60355f, 1f, 1f)\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.26199f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.3694f))\n        photoItem.pointList.add(PointF(0.3694f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.26199f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //sixth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.2929f, 0.75f, 0.7071f, 1f)\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0.25f, 0f))\n        photoItem.pointList.add(PointF(0.75f, 0f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //seventh frame\n        photoItem = PhotoItem()\n        photoItem.index = 5\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.60355f, 0.39645f, 1f)\n        photoItem.pointList.add(PointF(0.6306f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.3694f))\n        photoItem.pointList.add(PointF(0.73881f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.26199f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //eighth frame\n        photoItem = PhotoItem()\n        photoItem.index = 6\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.2929f, 0.25f, 0.7071f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.25f))\n        photoItem.pointList.add(PointF(1f, 0.75f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //ninth frame\n        photoItem = PhotoItem()\n        photoItem.index = 7\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0.2929f, 0f))\n        photoItem.pointList.add(PointF(0.7071f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.2929f))\n        photoItem.pointList.add(PointF(1f, 0.7071f))\n        photoItem.pointList.add(PointF(0.7071f, 1f))\n        photoItem.pointList.add(PointF(0.2929f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.7071f))\n        photoItem.pointList.add(PointF(0f, 0.2929f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[6]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[7]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_9_9(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_9_9\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.3f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.6f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.3f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.6f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 8\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.3f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.4f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.7f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0.6f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.7f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.4f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //sixth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.7f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.4f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //seventh frame\n        photoItem = PhotoItem()\n        photoItem.index = 5\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.7f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0.6f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //eighth frame\n        photoItem = PhotoItem()\n        photoItem.index = 6\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.3f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.4f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //ninth frame\n        photoItem = PhotoItem()\n        photoItem.index = 7\n        photoItem.bound.set(0.3f, 0.3f, 0.7f, 0.7f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_9_8(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_8\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val x4 = param(0.3333f)\n            val x5 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, vs[x3], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x3], 0f, 1f, vs[y1]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(x4),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x4], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x4, x5),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x4], vs[y1], vs[x5], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x5),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x5], vs[y1], 1f, vs[y2]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_9_7(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_7\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val x4 = param(0.3333f)\n            val x5 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, vs[x3], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x3], 0f, 1f, vs[y1]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(x4),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x4], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x4, x5),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x4], vs[y2], vs[x5], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x5),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x5], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_9_6(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_6\") {\n            val x1 = param(0.2f)\n            val x2 = param(0.4f)\n            val x3 = param(0.6f)\n            val x4 = param(0.8f)\n            val y1 = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, vs[x3], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3, x4),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x3], 0f, vs[x4], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x4),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x4], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3, x4),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x3], vs[y1], vs[x4], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x4),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x4], vs[y1], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_9_5(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_5\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_9_4(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_4\") {\n            val xL = param(0.3333f)\n            val xQ1 = param(0.25f)\n            val xQ2 = param(0.5f)\n            val xQ3 = param(0.75f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[xL], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xL], 0f, 1f, vs[y1]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(xQ1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[xQ1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xQ1, xQ2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xQ1], vs[y1], vs[xQ2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xQ2, xQ3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xQ2], vs[y1], vs[xQ3], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xQ3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xQ3], vs[y1], 1f, vs[y2]) }\n            )\n\n            addBoxedItem(\n                xParams = listOf(xQ1, xQ2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[xQ1], vs[y2], vs[xQ2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xQ2, xQ3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[xQ2], vs[y2], vs[xQ3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xQ3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[xQ3], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_9_3(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_3\") {\n            val x1 = param(0.2f)\n            val x2 = param(0.4f)\n            val x3 = param(0.6f)\n            val x4 = param(0.8f)\n            val y1 = param(0.2f)\n            val y2 = param(0.4f)\n            val y3 = param(0.6f)\n            val y4 = param(0.8f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2, y4),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], vs[y4]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y4),\n                boxParams = { vs -> RectF(0f, vs[y4], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x4),\n                yParams = listOf(y4),\n                boxParams = { vs -> RectF(vs[x2], vs[y4], vs[x4], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x4),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x4], vs[y3], 1f, 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x4),\n                yParams = listOf(y1, y3),\n                boxParams = { vs -> RectF(vs[x4], vs[y1], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x3], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x3], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x4),\n                yParams = listOf(y1, y4),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x4], vs[y4]) }\n            )\n        }\n    }\n\n    internal fun collage_9_2(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_2\") {\n            val xM = param(0.5f)\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[xM], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xM], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[xM], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xM], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[xM], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[xM], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y3], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_9_1(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_1\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_9_0(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_9_0\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.75f)\n            val y1 = param(0.25f)\n            val y2 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/SevenFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.view.PhotoItem\n\n/**\n * Created by admin on 6/30/2016.\n */\ninternal object SevenFrameImage {\n    internal fun collage_7_10(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_7_10\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.25f, 0.6471f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.7727f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0f, 0.85f, 0.3529f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0.7f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.4118f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.75f, 0.3529f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.2273f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.15f, 0.6471f, 0.75f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //sixth frame\n        photoItem = PhotoItem()\n        photoItem.index = 5\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5882f))\n        photoItem.pointList.add(PointF(0.3f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //seventh frame\n        photoItem = PhotoItem()\n        photoItem.index = 6\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.2059f, 0.75f, 0.7941f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.25f))\n        photoItem.pointList.add(PointF(1f, 0.75f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.75f))\n        photoItem.pointList.add(PointF(0f, 0.25f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_7_9(): CollageLayout {\n        return collage_7_8(name = \"collage_7_9\", y = 0.25f)\n    }\n\n    internal fun collage_7_8(name: String = \"collage_7_8\", y: Float = 0.75f): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val x1 = param(0.3f)\n            val x2 = param(0.6f)\n            val yLeft = param(y)\n            val yR1 = param(0.3333f)\n            val yR2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(yLeft),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[yLeft]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yLeft),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[yLeft]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(yLeft),\n                boxParams = { vs -> RectF(0f, vs[yLeft], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yLeft),\n                boxParams = { vs -> RectF(vs[x1], vs[yLeft], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yR1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[yR1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yR1, yR2),\n                boxParams = { vs -> RectF(vs[x2], vs[yR1], 1f, vs[yR2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yR2),\n                boxParams = { vs -> RectF(vs[x2], vs[yR2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_7(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_7\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_6(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_6\") {\n            val x = param(0.6666f)\n            val y0 = param(0.3333f)\n            val y1 = param(0.6666f)\n            val r1 = param(0.25f)\n            val r2 = param(0.5f)\n            val r3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y0),\n                boxParams = { vs -> RectF(0f, 0f, vs[x], vs[y0]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y0, y1),\n                boxParams = { vs -> RectF(0f, vs[y0], vs[x], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(r1),\n                boxParams = { vs -> RectF(vs[x], 0f, 1f, vs[r1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(r1, r2),\n                boxParams = { vs -> RectF(vs[x], vs[r1], 1f, vs[r2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(r2, r3),\n                boxParams = { vs -> RectF(vs[x], vs[r2], 1f, vs[r3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x),\n                yParams = listOf(r3),\n                boxParams = { vs -> RectF(vs[x], vs[r3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_5(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_5\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val x3 = param(0.5f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x3], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_4(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_4\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_3(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_3\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_2(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_2\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_1(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_1\") {\n            val x0 = param(0.25f)\n            val x1 = param(0.5f)\n            val x2 = param(0.75f)\n            val y = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(x0),\n                boxParams = { vs -> RectF(0f, 0f, vs[x0], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x0, x1),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x0], 0f, vs[x1], vs[y]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x0, x1),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x0], vs[y], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x1], vs[y], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y),\n                boxParams = { vs -> RectF(vs[x2], vs[y], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_0(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_7_0\") {\n            val xL = param(0.3333f)\n            val xTopSplit = param(0.5555f)\n            val xRightSplit = param(0.7777f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[xL], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[xL], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[xL], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL, xTopSplit),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xL], 0f, vs[xTopSplit], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xTopSplit),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xTopSplit], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL, xRightSplit),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xL], vs[y1], vs[xRightSplit], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xRightSplit),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xRightSplit], vs[y1], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_7_1_1(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_7_1_1\",\n            count = 7,\n            isHorizontal = true\n        )\n    }\n\n    internal fun collage_7_1_2(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_7_1_2\",\n            count = 7,\n            isHorizontal = false\n        )\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/SixFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.view.PhotoItem\n\n/**\n * Created by admin on 6/26/2016.\n */\ninternal object SixFrameImage {\n    internal fun collage_6_14(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_6_14\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.4f, 0.6f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.625f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.4f, 0f, 1f, 0.3f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6f, 0f, 1f, 0.6f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.375f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.6f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //sixth frame\n        photoItem = PhotoItem()\n        photoItem.index = 5\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.25f, 0.3f, 0.75f, 0.8f)\n        photoItem.pointList.add(PointF(0.3f, 0f))\n        photoItem.pointList.add(PointF(0.7f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.6f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.6f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_6_13(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_6_13\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.35f, 0f, 1f, 0.4f)\n        photoItem.pointList.add(PointF(0.2308f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.3846f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.375f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //fourth frame\n        photoItem = PhotoItem()\n        photoItem.index = 3\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.15f, 0.6f, 1f)\n        photoItem.pointList.add(PointF(0.5833f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.2941f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.4118f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //fifth frame\n        photoItem = PhotoItem()\n        photoItem.index = 4\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6f, 0.65f, 1f)\n        photoItem.pointList.add(PointF(0.6154f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.625f))\n        photoItem.pointList.add(PointF(0.7692f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //sixth frame\n        photoItem = PhotoItem()\n        photoItem.index = 5\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.4f, 0f, 1f, 0.85f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5882f))\n        photoItem.pointList.add(PointF(0.4166f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.7059f))\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_6_12(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_12\") {\n            val topY = param(0.2f)\n            val midY = param(0.7f)\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val bottomSplitX = param(0.5f)\n\n            addBoxedItem(\n                yParams = listOf(topY),\n                boxParams = { vs -> RectF(0f, 0f, 1f, vs[topY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(topY, midY),\n                boxParams = { vs -> RectF(0f, vs[topY], vs[x1], vs[midY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(topY, midY),\n                boxParams = { vs -> RectF(vs[x1], vs[topY], vs[x2], vs[midY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(topY, midY),\n                boxParams = { vs -> RectF(vs[x2], vs[topY], 1f, vs[midY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(bottomSplitX),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(0f, vs[midY], vs[bottomSplitX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(bottomSplitX),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(vs[bottomSplitX], vs[midY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_11(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_11\") {\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n            val midX = param(0.5f)\n\n            addBoxedItem(\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(midX),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[midX], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(midX),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[midX], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(midX),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[midX], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(midX),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[midX], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_10(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_10\") {\n            val rightX = param(0.6666f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(rightX),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[rightX], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(rightX),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[rightX], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(rightX),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[rightX], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(rightX),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[rightX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(rightX),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[rightX], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(rightX),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[rightX], vs[y1], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_9(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_9\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val yTop = param(0.3333f)\n            val yRightSplit = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[yTop]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[yTop]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[yTop]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(0f, vs[yTop], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yTop, yRightSplit),\n                boxParams = { vs -> RectF(vs[x2], vs[yTop], 1f, vs[yRightSplit]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yRightSplit),\n                boxParams = { vs -> RectF(vs[x2], vs[yRightSplit], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_8(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_8\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val midY = param(0.5f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[midY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[midY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[midY]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(0f, vs[midY], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(vs[x1], vs[midY], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(midY),\n                boxParams = { vs -> RectF(vs[x2], vs[midY], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_7(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_7\") {\n            val x1 = param(0.3333f)\n            val x2 = param(0.6666f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n            val yTop = param(0.4f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(vs[x1], vs[yTop], 1f, 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[yTop]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(yTop),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[yTop]) }\n            )\n        }\n    }\n\n    internal fun collage_6_6(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_6\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_5(): CollageLayout {\n        return collage_6_1(name = \"collage_6_5\", x1 = 0.6667f, x2 = 0.3333f, x3 = 0.6667f)\n    }\n\n    internal fun collage_6_4(): CollageLayout {\n        return collage_6_3(name = \"collage_6_4\", initial_x1 = 0.5f)\n    }\n\n    internal fun collage_6_3(\n        name: String = \"collage_6_3\",\n        initial_x1: Float = 0.3333f,\n        initial_y1: Float = 0.3333f,\n        initial_y2: Float = 0.6666f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val x1 = param(initial_x1)\n            val y1 = param(initial_y1)\n            val y2 = param(initial_y2)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_2(): CollageLayout {\n        return collage_6_1(name = \"collage_6_2\", x3 = 0.3333f)\n    }\n\n    internal fun collage_6_1(\n        name: String = \"collage_6_1\",\n        x1: Float = 0.3333f,\n        x2: Float = 0.5f,\n        x3: Float = 0.6666f,\n        y1: Float = 0.3333f,\n        y2: Float = 0.6666f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val xTopSplit = param(x1)\n            val y1 = param(y1)\n            val midX = param(x2)\n            val y2 = param(y2)\n            val bottomSplitX = param(x3)\n\n            addBoxedItem(\n                xParams = listOf(xTopSplit),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[xTopSplit], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xTopSplit),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xTopSplit], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(midX),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[midX], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(midX),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[midX], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(bottomSplitX),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[bottomSplitX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(bottomSplitX),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[bottomSplitX], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_0(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_6_0\") {\n            val leftX = param(0.3333f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6667f)\n            val bottomSplitX = param(0.6667f)\n\n            addBoxedItem(\n                xParams = listOf(leftX),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, 0f, vs[leftX], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(leftX),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[leftX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(leftX),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[leftX], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(leftX),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[leftX], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(leftX, bottomSplitX),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[leftX], vs[y2], vs[bottomSplitX], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(bottomSplitX),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[bottomSplitX], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_6_1_1(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_6_1_1\",\n            count = 6,\n            isHorizontal = true\n        )\n    }\n\n    internal fun collage_6_1_2(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_6_1_2\",\n            count = 6,\n            isHorizontal = false\n        )\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/TenFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\n\n/**\n * Created by admin on 7/4/2016.\n */\ninternal object TenFrameImage {\n    internal fun collage_10_8(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_8\") {\n            val x1 = param(0.2f)\n            val x2 = param(0.5f)\n            val x3 = param(0.8f)\n            val y1 = param(0.2f)\n            val y2 = param(0.5f)\n            val y3 = param(0.8f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y1, y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], vs[x3], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x3], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x3], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_7(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_7\") {\n            val x1 = param(0.2f)\n            val x2 = param(0.6f)\n            val y1 = param(0.2f)\n            val y2 = param(0.5f)\n            val y3 = param(0.8f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_6(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_6\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val y1 = param(0.25f)\n            val y2 = param(0.5f)\n            val y3 = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y3),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], vs[x3], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y2], vs[x3], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1, y3),\n                boxParams = { vs -> RectF(vs[x3], vs[y1], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_5(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_5\") {\n            val xL = param(0.2f)\n            val xM = param(0.5f)\n            val xR = param(0.8f)\n            val yT = param(0.25f)\n            val yM = param(0.5f)\n            val yB = param(0.75f)\n\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(yT),\n                boxParams = { vs -> RectF(0f, 0f, vs[xM], vs[yT]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(yT),\n                boxParams = { vs -> RectF(vs[xM], 0f, 1f, vs[yT]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(yT, yM),\n                boxParams = { vs -> RectF(0f, vs[yT], vs[xL], vs[yM]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL, xR),\n                yParams = listOf(yT, yM),\n                boxParams = { vs -> RectF(vs[xL], vs[yT], vs[xR], vs[yM]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(yT, yM),\n                boxParams = { vs -> RectF(vs[xR], vs[yT], 1f, vs[yM]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(yM, yB),\n                boxParams = { vs -> RectF(0f, vs[yM], vs[xL], vs[yB]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL, xR),\n                yParams = listOf(yM, yB),\n                boxParams = { vs -> RectF(vs[xL], vs[yM], vs[xR], vs[yB]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(yM, yB),\n                boxParams = { vs -> RectF(vs[xR], vs[yM], 1f, vs[yB]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(yB),\n                boxParams = { vs -> RectF(0f, vs[yB], vs[xM], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(yB),\n                boxParams = { vs -> RectF(vs[xM], vs[yB], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_4(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_4\") {\n            val xM = param(0.5f)\n            val xR = param(0.8f)\n            val y1 = param(0.2f)\n            val y2 = param(0.5f)\n            val y3 = param(0.8f)\n\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, 0f, vs[xM], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[xM], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM, xR),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xM], 0f, vs[xR], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xR], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM, xR),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xM], vs[y1], vs[xR], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xR], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM, xR),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[xM], vs[y2], vs[xR], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[xR], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM, xR),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[xM], vs[y3], vs[xR], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[xR], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_3(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_3\") {\n            val xL = param(0.7f)\n            val xR = param(0.9f)\n            val xS = param(0.3f)\n            val y1 = param(0.3f)\n            val y2 = param(0.7f)\n            val y3 = param(0.9f)\n\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[xL], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[xL], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[xL], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL, xR),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xL], vs[y1], vs[xR], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[xR], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xS),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[xS], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xS),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[xS], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xS, xL),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[xS], vs[y2], vs[xL], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[xL], vs[y2], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[xL], vs[y3], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_2(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_2\") {\n            val xM = param(0.5f)\n            val xL = param(0.2f)\n            val xR = param(0.8f)\n            val yM = param(0.5f)\n            val yB = param(0.8f)\n\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(yM),\n                boxParams = { vs -> RectF(0f, 0f, vs[xM], vs[yM]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM),\n                yParams = listOf(yM),\n                boxParams = { vs -> RectF(vs[xM], 0f, 1f, vs[yM]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(yM, yB),\n                boxParams = { vs -> RectF(0f, vs[yM], vs[xL], vs[yB]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL, xM),\n                yParams = listOf(yM, yB),\n                boxParams = { vs -> RectF(vs[xL], vs[yM], vs[xM], vs[yB]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM, xR),\n                yParams = listOf(yM, yB),\n                boxParams = { vs -> RectF(vs[xM], vs[yM], vs[xR], vs[yB]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(yM, yB),\n                boxParams = { vs -> RectF(vs[xR], vs[yM], 1f, vs[yB]) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL),\n                yParams = listOf(yB),\n                boxParams = { vs -> RectF(0f, vs[yB], vs[xL], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xL, xM),\n                yParams = listOf(yB),\n                boxParams = { vs -> RectF(vs[xL], vs[yB], vs[xM], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xM, xR),\n                yParams = listOf(yB),\n                boxParams = { vs -> RectF(vs[xM], vs[yB], vs[xR], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(xR),\n                yParams = listOf(yB),\n                boxParams = { vs -> RectF(vs[xR], vs[yB], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_1(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_1\") {\n            val x1 = param(0.25f)\n            val x2 = param(0.5f)\n            val x3 = param(0.75f)\n            val y1 = param(0.3333f)\n            val y2 = param(0.6666f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x3], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x3], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2, x3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], vs[x3], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y1], 1f, vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(0f, vs[y2], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x3], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x3),\n                yParams = listOf(y2),\n                boxParams = { vs -> RectF(vs[x3], vs[y2], 1f, 1f) }\n            )\n        }\n    }\n\n    internal fun collage_10_0(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_10_0\") {\n            val x1 = param(0.2f)\n            val x2 = param(0.8f)\n            val y1 = param(0.2f)\n            val y2 = param(0.5f)\n            val y3 = param(0.8f)\n\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(0f, 0f, vs[x1], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x1], 0f, vs[x2], vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1),\n                boxParams = { vs -> RectF(vs[x2], 0f, 1f, vs[y1]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y1, y3),\n                boxParams = { vs -> RectF(0f, vs[y1], vs[x1], vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(0f, vs[y3], vs[x1], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y3], vs[x2], 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y3], 1f, 1f) }\n            )\n            addBoxedItem(\n                xParams = listOf(x2),\n                yParams = listOf(y1, y3),\n                boxParams = { vs -> RectF(vs[x2], vs[y1], 1f, vs[y3]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y1, y2),\n                boxParams = { vs -> RectF(vs[x1], vs[y1], vs[x2], vs[y2]) }\n            )\n            addBoxedItem(\n                xParams = listOf(x1, x2),\n                yParams = listOf(y2, y3),\n                boxParams = { vs -> RectF(vs[x1], vs[y2], vs[x2], vs[y3]) }\n            )\n        }\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/ThreeFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.Path\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.utils.GeometryUtils\nimport com.t8rin.collages.view.PhotoItem\n\n/**\n * Created by admin on 5/9/2016.\n */\ninternal object ThreeFrameImage {\n    internal fun collage_3_47(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_47\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.75f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(0.75f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_46(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_46\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.4167f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.6f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.25f, 0f, 0.75f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.8333f, 1f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0.6666f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0.25f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_45(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_45\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.4f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.2f, 0f, 0.8f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.6667f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.6f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_44(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_44\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.4167f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.6f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.25f, 1f, 0.75f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 0.8333f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6666f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.25f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_43(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_43\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.4f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.2f, 1f, 0.8f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.6667f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.3333f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_42(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_42\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.6f, 0.8f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.6667f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.75f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.4f, 0f, 1f, 0.7f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.3333f, 0.8571f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.6f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.6f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.25f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_41(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_41\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.6666f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0.3333f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.6667f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.6667f))\n        photoItem.pointList.add(PointF(0.75f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_40(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_40\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_39(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_39\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_38(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_38\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_37(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_37\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_36(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_36\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_35(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_35\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_34(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_34\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_33(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_33\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0.5f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_32(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_32\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0.5f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_31(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_31\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_30(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_30\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0.5f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_29(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_29\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_28(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_28\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_27(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_27\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_26(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_26\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_25(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_25\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_24(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_24\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_23(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_23\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_22(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_22\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_COMMON\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(1f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(2f, 1f)\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_21(): CollageLayout {\n        return collage_3_18(\"collage_3_21\", 0.5f, 0.3333f)\n    }\n\n    internal fun collage_3_20(): CollageLayout {\n        return collage_3_18(\"collage_3_20\", 0.5f, 0.6666f)\n    }\n\n    internal fun collage_3_19(): CollageLayout {\n        return collage_3_16(\"collage_3_19\", 0.25f, 0.75f)\n    }\n\n    internal fun collage_3_18(\n        name: String = \"collage_3_18\",\n        initialX: Float = 0.5f,\n        initialY: Float = 0.5f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wall1X = param(initialX)\n            val wall2Y = param(initialY)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_3_17(): CollageLayout {\n        return CollageLayoutFactory.collage(\"collage_3_17\") {\n            val wall1X = param(0.5f)\n            val wall2Y = param(0.3333f)\n            addBoxedItem(\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall2Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_3_16(\n        name: String = \"collage_3_16\",\n        initialY1: Float = 0.3333f,\n        initialY2: Float = 0.6666f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wall1Y = param(initialY1)\n            val wall2Y = param(initialY2)\n            addBoxedItem(\n                yParams = listOf(wall1Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, 1f, vs[wall1Y])\n                }\n            )\n            addBoxedItem(\n                yParams = listOf(wall1Y, wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall1Y], 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_3_15(): CollageLayout {\n        return collage_3_12(\"collage_3_15\", 0.6667f, 0.5f)\n    }\n\n    internal fun collage_3_14(): CollageLayout {\n        return collage_3_12(\"collage_3_14\", 0.3333f, 0.5f)\n    }\n\n    internal fun collage_3_13(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_13\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.fitBound = true\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addRect(0f, 0f, 512f, 512f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(0.5f, 0.25f, 1.5f, 0.75f)\n        photoItem.clearPathInCenterVertical = true\n        photoItem.cornerMethod = PhotoItem.CORNER_METHOD_3_13\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.fitBound = true\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addRect(0f, 0f, 512f, 512f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(-0.5f, 0.25f, 0.5f, 0.75f)\n        photoItem.clearPathInCenterVertical = true\n        photoItem.cornerMethod = PhotoItem.CORNER_METHOD_3_13\n        photoItemList.add(photoItem)\n        //third frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0.25f, 0f, 0.75f, 1f)\n        photoItem.path = Path()\n        photoItem.path!!.addRect(0f, 0f, 512f, 512f, Path.Direction.CCW)\n        photoItem.pathRatioBound = RectF(0f, 0.25f, 1f, 0.75f)\n        photoItem.pathInCenterVertical = true\n        photoItem.pathInCenterHorizontal = true\n        photoItem.fitBound = true\n        photoItem.cornerMethod = PhotoItem.CORNER_METHOD_3_13\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_12(\n        name: String = \"collage_3_12\",\n        initialX: Float = 0.5f,\n        initialY: Float = 0.5f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wall1X = param(initialX)\n            val wall2Y = param(initialY)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], vs[wall2Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_3_11(): CollageLayout {\n        return collage_3_5(\"collage_3_11\", 0.6667f, 0.5f)\n    }\n\n    internal fun collage_3_10(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_10\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_USING_MAP\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.75f, 1f))\n        photoItem.pointList.add(PointF(0.75f, 0.5f))\n        photoItem.pointList.add(PointF(0.25f, 0.5f))\n        photoItem.pointList.add(PointF(0.25f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(-2f, 2f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(-2f, -1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, -1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, -1f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(-1f, -1f)\n        photoItem.shrinkMap!![photoItem.pointList[6]] = PointF(-1f, -1f)\n        photoItem.shrinkMap!![photoItem.pointList[7]] = PointF(2f, -1f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_USING_MAP\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(0.25f, 0f))\n        photoItem.pointList.add(PointF(0.25f, 0.5f))\n        photoItem.pointList.add(PointF(0.75f, 0.5f))\n        photoItem.pointList.add(PointF(0.75f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        //shrink map\n        photoItem.shrinkMap = HashMap()\n        photoItem.shrinkMap!![photoItem.pointList[0]] = PointF(2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[1]] = PointF(-1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[2]] = PointF(-1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[3]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[4]] = PointF(1f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[5]] = PointF(-2f, 1f)\n        photoItem.shrinkMap!![photoItem.pointList[6]] = PointF(-2f, -2f)\n        photoItem.shrinkMap!![photoItem.pointList[7]] = PointF(2f, -2f)\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_9(): CollageLayout {\n        return collage_3_5(\"collage_3_9\", 0.5f, 0.6667f)\n    }\n\n    internal fun collage_3_8(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_8\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(0.5f, 0.25f, 1.5f, 0.75f)\n        photoItem.clearPathInCenterVertical = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(-0.5f, 0.25f, 0.5f, 0.75f)\n        photoItem.clearPathInCenterVertical = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_3_8\n        photoItem.bound.set(0.25f, 0f, 0.75f, 1f)\n        photoItem.path = Path()\n        photoItem.path!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.pathRatioBound = RectF(0f, 0.25f, 1f, 0.75f)\n        photoItem.pathInCenterVertical = true\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_7(): CollageLayout {\n        return collage_3_5(\"collage_3_7\", 0.3333f, 0.5f)\n    }\n\n    internal fun collage_3_6(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_6\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_3_6\n        photoItem.cornerMethod = PhotoItem.CORNER_METHOD_3_6\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        GeometryUtils.createRegularPolygonPath(photoItem.clearPath!!, 512f, 6, 0f)\n        photoItem.clearPathRatioBound = RectF(0.5f, 0.25f, 1.5f, 0.75f)\n        photoItem.clearPathInCenterVertical = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_3_6\n        photoItem.cornerMethod = PhotoItem.CORNER_METHOD_3_6\n        photoItem.index = 1\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        GeometryUtils.createRegularPolygonPath(photoItem.clearPath!!, 512f, 6, 0f)\n        photoItem.clearPathRatioBound = RectF(-0.5f, 0.25f, 0.5f, 0.75f)\n        photoItem.clearPathInCenterVertical = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_3_6\n        photoItem.cornerMethod = PhotoItem.CORNER_METHOD_3_6\n        photoItem.bound.set(0.25f, 0f, 0.75f, 1f)\n        photoItem.path = Path()\n        GeometryUtils.createRegularPolygonPath(photoItem.path!!, 512f, 6, 0f)\n        photoItem.pathRatioBound = RectF(0f, 0.25f, 1f, 0.75f)\n        photoItem.pathInCenterVertical = true\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_5(\n        name: String = \"collage_3_5\",\n        initialX: Float = 0.5f,\n        initialY: Float = 0.5f\n    ): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wall1X = param(initialX)\n            val wall2Y = param(initialY)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], vs[wall2Y])\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                yParams = listOf(wall2Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall2Y], vs[wall1X], 1f)\n                }\n            )\n        }\n    }\n\n    internal fun collage_3_4(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_4\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.clearPathRatioBound = RectF(0.25f, 0.5f, 0.75f, 1.5f)\n        photoItem.clearPathInCenterHorizontal = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.clearPathRatioBound = RectF(0.25f, -0.5f, 0.75f, 0.5f)\n        photoItem.clearPathInCenterHorizontal = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0f, 0.25f, 1f, 0.75f)\n        photoItem.path = CollageLayoutFactory.createHeartItem(0f, 512f)\n        photoItem.pathRatioBound = RectF(0f, 0f, 1f, 1f)\n        photoItem.pathInCenterHorizontal = true\n        photoItem.pathInCenterVertical = true\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_3(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_3\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_3_3\n        photoItem.bound.set(0f, 0f, 0.5f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.25f))\n        photoItem.pointList.add(PointF(0.5f, 0.5f))\n        photoItem.pointList.add(PointF(1f, 0.75f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_3_3\n        photoItem.bound.set(0.5f, 0f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.75f))\n        photoItem.pointList.add(PointF(0.5f, 0.5f))\n        photoItem.pointList.add(PointF(0f, 0.25f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.bound.set(0.25f, 0.25f, 0.75f, 0.75f)\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.5f))\n        photoItem.pointList.add(PointF(0.5f, 1f))\n        photoItem.pointList.add(PointF(0f, 0.5f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_1(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_3_1\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.5f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(0.25f, 0.5f, 0.75f, 1.5f)\n        photoItem.clearPathInCenterHorizontal = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.5f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItem.clearPath = Path()\n        photoItem.clearPath!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.clearPathRatioBound = RectF(0.25f, -0.5f, 0.75f, 0.5f)\n        photoItem.clearPathInCenterHorizontal = true\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 2\n        photoItem.shrinkMethod = PhotoItem.SHRINK_METHOD_3_8\n        photoItem.bound.set(0f, 0.25f, 1f, 0.75f)\n        photoItem.path = Path()\n        photoItem.path!!.addCircle(256f, 256f, 256f, Path.Direction.CCW)\n        photoItem.pathRatioBound = RectF(0.25f, 0f, 0.75f, 1f)\n        photoItem.pathInCenterVertical = true\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    internal fun collage_3_0(): CollageLayout {\n        return CollageLayoutFactory.collageLinear(\n            name = \"collage_3_0\",\n            count = 3,\n            isHorizontal = true\n        )\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/frames/TwoFrameImage.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.frames\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory\nimport com.t8rin.collages.view.PhotoItem\n\n/**\n * Created by admin on 5/8/2016.\n */\ninternal object TwoFrameImage {\n    fun collage_2_0(name: String = \"collage_2_0\", initialPosition: Float = 0.5f): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wall1X = param(initialPosition)\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                boxParams = { vs ->\n                    RectF(0f, 0f, vs[wall1X], 1f)\n                }\n            )\n            addBoxedItem(\n                xParams = listOf(wall1X),\n                boxParams = { vs ->\n                    RectF(vs[wall1X], 0f, 1f, 1f)\n                }\n            )\n        }\n    }\n\n    fun collage_2_1(name: String = \"collage_2_1\", initialPosition: Float = 0.5f): CollageLayout {\n        return CollageLayoutFactory.collage(name) {\n            val wall1Y = param(initialPosition)\n            addBoxedItem(\n                yParams = listOf(wall1Y),\n                boxParams = { vs ->\n                    RectF(0f, 0f, 1f, vs[wall1Y])\n                }\n            )\n            addBoxedItem(\n                yParams = listOf(wall1Y),\n                boxParams = { vs ->\n                    RectF(0f, vs[wall1Y], 1f, 1f)\n                }\n            )\n        }\n    }\n\n    fun collage_2_2(): CollageLayout {\n        return collage_2_1(\"collage_2_2\", 0.3333f)\n    }\n\n    fun collage_2_3(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_2_3\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        val photoItem1 = PhotoItem()\n        photoItem1.index = 0\n        photoItem1.bound.set(0f, 0f, 1f, 0.667f)\n        photoItem1.pointList.add(PointF(0f, 0f))\n        photoItem1.pointList.add(PointF(1f, 0f))\n        photoItem1.pointList.add(PointF(1f, 0.5f))\n        photoItem1.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem1)\n        //second frame\n        val photoItem2 = PhotoItem()\n        photoItem2.index = 1\n        photoItem2.bound.set(0f, 0.333f, 1f, 1f)\n        photoItem2.pointList.add(PointF(0f, 0.5f))\n        photoItem2.pointList.add(PointF(1f, 0f))\n        photoItem2.pointList.add(PointF(1f, 1f))\n        photoItem2.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem2)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    fun collage_2_4(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_2_4\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        //first frame\n        var photoItem = PhotoItem()\n        photoItem.index = 0\n        photoItem.bound.set(0f, 0f, 1f, 0.5714f)\n        photoItem.pointList.add(PointF(0f, 0f))\n        photoItem.pointList.add(PointF(1f, 0f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0.8333f, 0.75f))\n        photoItem.pointList.add(PointF(0.6666f, 1f))\n        photoItem.pointList.add(PointF(0.5f, 0.75f))\n        photoItem.pointList.add(PointF(0.3333f, 1f))\n        photoItem.pointList.add(PointF(0.1666f, 0.75f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        //second frame\n        photoItem = PhotoItem()\n        photoItem.index = 1\n        photoItem.bound.set(0f, 0.4286f, 1f, 1f)\n        photoItem.pointList.add(PointF(0f, 0.25f))\n        photoItem.pointList.add(PointF(0.1666f, 0f))\n        photoItem.pointList.add(PointF(0.3333f, 0.25f))\n        photoItem.pointList.add(PointF(0.5f, 0f))\n        photoItem.pointList.add(PointF(0.6666f, 0.25f))\n        photoItem.pointList.add(PointF(0.8333f, 0f))\n        photoItem.pointList.add(PointF(1f, 0.25f))\n        photoItem.pointList.add(PointF(1f, 1f))\n        photoItem.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    fun collage_2_5(): CollageLayout {\n        return collage_2_1(\"collage_2_5\", 0.6667f)\n    }\n\n    fun collage_2_6(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_2_6\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        val photoItem1 = PhotoItem()\n        photoItem1.index = 0\n        photoItem1.bound.set(0f, 0f, 1f, 0.667f)\n        photoItem1.pointList.add(PointF(0f, 0f))\n        photoItem1.pointList.add(PointF(1f, 0f))\n        photoItem1.pointList.add(PointF(1f, 1f))\n        photoItem1.pointList.add(PointF(0f, 0.5f))\n        photoItemList.add(photoItem1)\n        //second frame\n        val photoItem2 = PhotoItem()\n        photoItem2.index = 1\n        photoItem2.bound.set(0f, 0.333f, 1f, 1f)\n        photoItem2.pointList.add(PointF(0f, 0f))\n        photoItem2.pointList.add(PointF(1f, 0.5f))\n        photoItem2.pointList.add(PointF(1f, 1f))\n        photoItem2.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem2)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    fun collage_2_7(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_2_7\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        val photoItem1 = PhotoItem()\n        photoItem1.index = 0\n        photoItem1.bound.set(0f, 0f, 1f, 1f)\n        photoItem1.pointList.add(PointF(0f, 0f))\n        photoItem1.pointList.add(PointF(1f, 0f))\n        photoItem1.pointList.add(PointF(1f, 1f))\n        photoItem1.pointList.add(PointF(0f, 1f))\n        //clear area\n        photoItem1.clearAreaPoints = ArrayList()\n        photoItem1.clearAreaPoints!!.add(PointF(0.6f, 0.6f))\n        photoItem1.clearAreaPoints!!.add(PointF(0.9f, 0.6f))\n        photoItem1.clearAreaPoints!!.add(PointF(0.9f, 0.9f))\n        photoItem1.clearAreaPoints!!.add(PointF(0.6f, 0.9f))\n        photoItemList.add(photoItem1)\n        //second frame\n        val photoItem2 = PhotoItem()\n        photoItem2.index = 1\n        //photoItem2.hasBackground = true;\n        photoItem2.bound.set(0.6f, 0.6f, 0.9f, 0.9f)\n        photoItem2.pointList.add(PointF(0f, 0f))\n        photoItem2.pointList.add(PointF(1f, 0f))\n        photoItem2.pointList.add(PointF(1f, 1f))\n        photoItem2.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem2)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    fun collage_2_8(): CollageLayout {\n        return collage_2_0(\"collage_2_8\", 0.3333f)\n    }\n\n    fun collage_2_9(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_2_9\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        val photoItem1 = PhotoItem()\n        photoItem1.index = 0\n        photoItem1.bound.set(0f, 0f, 0.6667f, 1f)\n        photoItem1.pointList.add(PointF(0f, 0f))\n        photoItem1.pointList.add(PointF(0.5f, 0f))\n        photoItem1.pointList.add(PointF(1f, 1f))\n        photoItem1.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem1)\n        //second frame\n        val photoItem2 = PhotoItem()\n        photoItem2.index = 1\n        photoItem2.bound.set(0.3333f, 0f, 1f, 1f)\n        photoItem2.pointList.add(PointF(0f, 0f))\n        photoItem2.pointList.add(PointF(1f, 0f))\n        photoItem2.pointList.add(PointF(1f, 1f))\n        photoItem2.pointList.add(PointF(0.5f, 1f))\n        photoItemList.add(photoItem2)\n        return item.copy(photoItemList = photoItemList)\n    }\n\n    fun collage_2_10(): CollageLayout {\n        return collage_2_0(\"collage_2_10\", 0.6667f)\n    }\n\n    fun collage_2_11(): CollageLayout {\n        val item = CollageLayoutFactory.collage(\"collage_2_11\")\n        val photoItemList = mutableListOf<PhotoItem>()\n        //first frame\n        val photoItem1 = PhotoItem()\n        photoItem1.index = 0\n        photoItem1.bound.set(0f, 0f, 0.667f, 1f)\n        photoItem1.pointList.add(PointF(0f, 0f))\n        photoItem1.pointList.add(PointF(1f, 0f))\n        photoItem1.pointList.add(PointF(0.5f, 1f))\n        photoItem1.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem1)\n        //second frame\n        val photoItem2 = PhotoItem()\n        photoItem1.index = 1\n        photoItem2.bound.set(0.333f, 0f, 1f, 1f)\n        photoItem2.pointList.add(PointF(0.5f, 0f))\n        photoItem2.pointList.add(PointF(1f, 0f))\n        photoItem2.pointList.add(PointF(1f, 1f))\n        photoItem2.pointList.add(PointF(0f, 1f))\n        photoItemList.add(photoItem2)\n        return item.copy(photoItemList = photoItemList)\n    }\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/model/CollageLayout.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.model\n\nimport android.net.Uri\nimport com.t8rin.collages.utils.ParamsManager\nimport com.t8rin.collages.view.PhotoItem\n\ninternal data class CollageLayout(\n    val preview: Uri,\n    val title: String,\n    val paramsManager: ParamsManager? = null,\n    val photoItemList: List<PhotoItem> = emptyList()\n)"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/public/CollageConstants.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.public\n\nimport coil3.request.ImageRequest\nimport com.t8rin.collages.utils.CollageLayoutFactory\n\nobject CollageConstants {\n    const val MAX_IMAGE_COUNT: Int = 20\n\n    val layoutCount: Int = CollageLayoutFactory.COLLAGE_MAP.keys.size\n\n    internal var requestMapper: ImageRequest.Builder.() -> ImageRequest.Builder = { this }\n\n    fun requestMapper(mapper: ImageRequest.Builder.() -> ImageRequest.Builder) {\n        this.requestMapper = mapper\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/utils/CollageLayoutFactory.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.collages.utils\n\nimport android.content.Context\nimport android.graphics.Path\nimport android.graphics.RectF\nimport androidx.core.net.toUri\nimport com.t8rin.collages.frames.EightFrameImage\nimport com.t8rin.collages.frames.ExtendedFrameImage\nimport com.t8rin.collages.frames.FiveFrameImage\nimport com.t8rin.collages.frames.FourFrameImage\nimport com.t8rin.collages.frames.NineFrameImage\nimport com.t8rin.collages.frames.SevenFrameImage\nimport com.t8rin.collages.frames.SixFrameImage\nimport com.t8rin.collages.frames.TenFrameImage\nimport com.t8rin.collages.frames.ThreeFrameImage\nimport com.t8rin.collages.frames.TwoFrameImage\nimport com.t8rin.collages.model.CollageLayout\n\ninternal object CollageLayoutFactory {\n    private const val FRAME_FOLDER = \"frame\"\n\n    fun collage(\n        frameName: String\n    ): CollageLayout = CollageLayout(\n        preview = (\"file:///android_asset/$FRAME_FOLDER/$frameName.webp\").toUri(),\n        title = frameName\n    )\n\n    fun collage(\n        frameName: String,\n        setup: ParamsManagerBuilder.() -> Unit\n    ): CollageLayout {\n        val (paramsManager, photoItemList) = ParamsManagerBuilder().apply(setup).build()\n        return collage(frameName).copy(paramsManager = paramsManager, photoItemList = photoItemList)\n    }\n\n    fun createHeartItem(top: Float, size: Float): Path {\n        return Path().apply {\n            moveTo(top, top + size / 4)\n            quadTo(top, top, top + size / 4, top)\n            quadTo(top + size / 2, top, top + size / 2, top + size / 4)\n            quadTo(top + size / 2, top, top + size * 3 / 4, top)\n            quadTo(top + size, top, top + size, top + size / 4)\n            quadTo(top + size, top + size / 2, top + size * 3 / 4, top + size * 3 / 4)\n            lineTo(top + size / 2, top + size)\n            lineTo(top + size / 4, top + size * 3 / 4)\n            quadTo(top, top + size / 2, top, top + size / 4)\n        }\n    }\n\n    fun loadFrameImages(context: Context): List<CollageLayout> {\n        return runCatching {\n            context.assets.list(FRAME_FOLDER).orEmpty().mapNotNull {\n                createCollageLayouts(it.substringBeforeLast('.'))\n            }.sortedWith { lhs, rhs -> lhs.photoItemList.size - rhs.photoItemList.size }\n        }.onFailure {\n            it.printStackTrace()\n        }.getOrNull().orEmpty()\n    }\n\n    internal fun collageLinear(\n        name: String,\n        count: Int,\n        isHorizontal: Boolean,\n    ): CollageLayout {\n        return collage(name) {\n            if (count <= 0) return@collage\n\n            val params = (1 until count).map { i ->\n                param(i.toFloat() / count)\n            }\n\n            repeat(count) { index ->\n                addBoxedItem(\n                    xParams = if (isHorizontal) params else emptyList(),\n                    yParams = if (!isHorizontal) params else emptyList(),\n                    boxParams = { vs ->\n                        if (isHorizontal) {\n                            val left = if (index == 0) 0f else vs[params[index - 1]]\n                            val right = if (index == count - 1) 1f else vs[params[index]]\n                            RectF(left, 0f, right, 1f)\n                        } else {\n                            val top = if (index == 0) 0f else vs[params[index - 1]]\n                            val bottom = if (index == count - 1) 1f else vs[params[index]]\n                            RectF(0f, top, 1f, bottom)\n                        }\n                    }\n                )\n            }\n        }\n    }\n\n    internal fun collageParametricGrid(\n        name: String,\n        rows: Int,\n        cols: Int,\n    ): CollageLayout {\n        return collage(name) {\n            if (rows <= 0 || cols <= 0) return@collage\n            val xColParams = (1 until cols).map { c -> param(c.toFloat() / cols) }\n            val yRowParams = (1 until rows).map { r -> param(r.toFloat() / rows) }\n            for (r in 0 until rows) {\n                for (c in 0 until cols) {\n                    val xp = buildList {\n                        if (c > 0) add(xColParams[c - 1])\n                        if (c < cols - 1) add(xColParams[c])\n                    }.distinct()\n                    val yp = buildList {\n                        if (r > 0) add(yRowParams[r - 1])\n                        if (r < rows - 1) add(yRowParams[r])\n                    }.distinct()\n                    addBoxedItem(\n                        xParams = xp,\n                        yParams = yp,\n                        boxParams = { vs ->\n                            RectF(\n                                if (c == 0) 0f else vs[xColParams[c - 1]],\n                                if (r == 0) 0f else vs[yRowParams[r - 1]],\n                                if (c == cols - 1) 1f else vs[xColParams[c]],\n                                if (r == rows - 1) 1f else vs[yRowParams[r]],\n                            )\n                        },\n                    )\n                }\n            }\n        }\n    }\n\n    internal fun createCollageLayouts(frameName: String): CollageLayout? {\n        return COLLAGE_MAP[frameName]?.invoke()\n    }\n\n    internal val COLLAGE_MAP: Map<String, () -> CollageLayout> = mapOf(\n        \"collage_1_0\" to { ExtendedFrameImage.collage_1_0() },\n        \"collage_2_0\" to { TwoFrameImage.collage_2_0() },\n        \"collage_2_1\" to { TwoFrameImage.collage_2_1() },\n        \"collage_2_2\" to { TwoFrameImage.collage_2_2() },\n        \"collage_2_3\" to { TwoFrameImage.collage_2_3() },\n        \"collage_2_4\" to { TwoFrameImage.collage_2_4() },\n        \"collage_2_5\" to { TwoFrameImage.collage_2_5() },\n        \"collage_2_6\" to { TwoFrameImage.collage_2_6() },\n        \"collage_2_7\" to { TwoFrameImage.collage_2_7() },\n        \"collage_2_8\" to { TwoFrameImage.collage_2_8() },\n        \"collage_2_9\" to { TwoFrameImage.collage_2_9() },\n        \"collage_2_10\" to { TwoFrameImage.collage_2_10() },\n        \"collage_2_11\" to { TwoFrameImage.collage_2_11() },\n        \"collage_3_0\" to { ThreeFrameImage.collage_3_0() },\n        \"collage_3_1\" to { ThreeFrameImage.collage_3_1() },\n        \"collage_3_3\" to { ThreeFrameImage.collage_3_3() },\n        \"collage_3_4\" to { ThreeFrameImage.collage_3_4() },\n        \"collage_3_5\" to { ThreeFrameImage.collage_3_5() },\n        \"collage_3_6\" to { ThreeFrameImage.collage_3_6() },\n        \"collage_3_7\" to { ThreeFrameImage.collage_3_7() },\n        \"collage_3_8\" to { ThreeFrameImage.collage_3_8() },\n        \"collage_3_9\" to { ThreeFrameImage.collage_3_9() },\n        \"collage_3_10\" to { ThreeFrameImage.collage_3_10() },\n        \"collage_3_11\" to { ThreeFrameImage.collage_3_11() },\n        \"collage_3_12\" to { ThreeFrameImage.collage_3_12() },\n        \"collage_3_13\" to { ThreeFrameImage.collage_3_13() },\n        \"collage_3_14\" to { ThreeFrameImage.collage_3_14() },\n        \"collage_3_15\" to { ThreeFrameImage.collage_3_15() },\n        \"collage_3_16\" to { ThreeFrameImage.collage_3_16() },\n        \"collage_3_17\" to { ThreeFrameImage.collage_3_17() },\n        \"collage_3_18\" to { ThreeFrameImage.collage_3_18() },\n        \"collage_3_19\" to { ThreeFrameImage.collage_3_19() },\n        \"collage_3_20\" to { ThreeFrameImage.collage_3_20() },\n        \"collage_3_21\" to { ThreeFrameImage.collage_3_21() },\n        \"collage_3_22\" to { ThreeFrameImage.collage_3_22() },\n        \"collage_3_23\" to { ThreeFrameImage.collage_3_23() },\n        \"collage_3_24\" to { ThreeFrameImage.collage_3_24() },\n        \"collage_3_25\" to { ThreeFrameImage.collage_3_25() },\n        \"collage_3_26\" to { ThreeFrameImage.collage_3_26() },\n        \"collage_3_27\" to { ThreeFrameImage.collage_3_27() },\n        \"collage_3_28\" to { ThreeFrameImage.collage_3_28() },\n        \"collage_3_29\" to { ThreeFrameImage.collage_3_29() },\n        \"collage_3_30\" to { ThreeFrameImage.collage_3_30() },\n        \"collage_3_31\" to { ThreeFrameImage.collage_3_31() },\n        \"collage_3_32\" to { ThreeFrameImage.collage_3_32() },\n        \"collage_3_33\" to { ThreeFrameImage.collage_3_33() },\n        \"collage_3_34\" to { ThreeFrameImage.collage_3_34() },\n        \"collage_3_35\" to { ThreeFrameImage.collage_3_35() },\n        \"collage_3_36\" to { ThreeFrameImage.collage_3_36() },\n        \"collage_3_37\" to { ThreeFrameImage.collage_3_37() },\n        \"collage_3_38\" to { ThreeFrameImage.collage_3_38() },\n        \"collage_3_39\" to { ThreeFrameImage.collage_3_39() },\n        \"collage_3_40\" to { ThreeFrameImage.collage_3_40() },\n        \"collage_3_41\" to { ThreeFrameImage.collage_3_41() },\n        \"collage_3_42\" to { ThreeFrameImage.collage_3_42() },\n        \"collage_3_43\" to { ThreeFrameImage.collage_3_43() },\n        \"collage_3_44\" to { ThreeFrameImage.collage_3_44() },\n        \"collage_3_45\" to { ThreeFrameImage.collage_3_45() },\n        \"collage_3_46\" to { ThreeFrameImage.collage_3_46() },\n        \"collage_3_47\" to { ThreeFrameImage.collage_3_47() },\n        \"collage_4_0\" to { FourFrameImage.collage_4_0() },\n        \"collage_4_1\" to { FourFrameImage.collage_4_1() },\n        \"collage_4_1_1\" to { FourFrameImage.collage_4_1_1() },\n        \"collage_4_2\" to { FourFrameImage.collage_4_2() },\n        \"collage_4_4\" to { FourFrameImage.collage_4_4() },\n        \"collage_4_5\" to { FourFrameImage.collage_4_5() },\n        \"collage_4_6\" to { FourFrameImage.collage_4_6() },\n        \"collage_4_7\" to { FourFrameImage.collage_4_7() },\n        \"collage_4_8\" to { FourFrameImage.collage_4_8() },\n        \"collage_4_9\" to { FourFrameImage.collage_4_9() },\n        \"collage_4_10\" to { FourFrameImage.collage_4_10() },\n        \"collage_4_11\" to { FourFrameImage.collage_4_11() },\n        \"collage_4_12\" to { FourFrameImage.collage_4_12() },\n        \"collage_4_13\" to { FourFrameImage.collage_4_13() },\n        \"collage_4_14\" to { FourFrameImage.collage_4_14() },\n        \"collage_4_15\" to { FourFrameImage.collage_4_15() },\n        \"collage_4_16\" to { FourFrameImage.collage_4_16() },\n        \"collage_4_17\" to { FourFrameImage.collage_4_17() },\n        \"collage_4_18\" to { FourFrameImage.collage_4_18() },\n        \"collage_4_19\" to { FourFrameImage.collage_4_19() },\n        \"collage_4_20\" to { FourFrameImage.collage_4_20() },\n        \"collage_4_21\" to { FourFrameImage.collage_4_21() },\n        \"collage_4_22\" to { FourFrameImage.collage_4_22() },\n        \"collage_4_23\" to { FourFrameImage.collage_4_23() },\n        \"collage_4_24\" to { FourFrameImage.collage_4_24() },\n        \"collage_4_25\" to { FourFrameImage.collage_4_25() },\n        \"collage_5_1_1\" to { FiveFrameImage.collage_5_1_1() },\n        \"collage_5_1_2\" to { FiveFrameImage.collage_5_1_2() },\n        \"collage_5_0\" to { FiveFrameImage.collage_5_0() },\n        \"collage_5_1\" to { FiveFrameImage.collage_5_1() },\n        \"collage_5_2\" to { FiveFrameImage.collage_5_2() },\n        \"collage_5_3\" to { FiveFrameImage.collage_5_3() },\n        \"collage_5_4\" to { FiveFrameImage.collage_5_4() },\n        \"collage_5_5\" to { FiveFrameImage.collage_5_5() },\n        \"collage_5_6\" to { FiveFrameImage.collage_5_6() },\n        \"collage_5_7\" to { FiveFrameImage.collage_5_7() },\n        \"collage_5_8\" to { FiveFrameImage.collage_5_8() },\n        \"collage_5_9\" to { FiveFrameImage.collage_5_9() },\n        \"collage_5_10\" to { FiveFrameImage.collage_5_10() },\n        \"collage_5_11\" to { FiveFrameImage.collage_5_11() },\n        \"collage_5_12\" to { FiveFrameImage.collage_5_12() },\n        \"collage_5_13\" to { FiveFrameImage.collage_5_13() },\n        \"collage_5_14\" to { FiveFrameImage.collage_5_14() },\n        \"collage_5_15\" to { FiveFrameImage.collage_5_15() },\n        \"collage_5_16\" to { FiveFrameImage.collage_5_16() },\n        \"collage_5_17\" to { FiveFrameImage.collage_5_17() },\n        \"collage_5_18\" to { FiveFrameImage.collage_5_18() },\n        \"collage_5_19\" to { FiveFrameImage.collage_5_19() },\n        \"collage_5_20\" to { FiveFrameImage.collage_5_20() },\n        \"collage_5_21\" to { FiveFrameImage.collage_5_21() },\n        \"collage_5_22\" to { FiveFrameImage.collage_5_22() },\n        \"collage_5_23\" to { FiveFrameImage.collage_5_23() },\n        \"collage_5_24\" to { FiveFrameImage.collage_5_24() },\n        \"collage_5_25\" to { FiveFrameImage.collage_5_25() },\n        \"collage_5_26\" to { FiveFrameImage.collage_5_26() },\n        \"collage_5_27\" to { FiveFrameImage.collage_5_27() },\n        \"collage_5_28\" to { FiveFrameImage.collage_5_28() },\n        \"collage_5_29\" to { FiveFrameImage.collage_5_29() },\n        \"collage_5_30\" to { FiveFrameImage.collage_5_30() },\n        \"collage_5_31\" to { FiveFrameImage.collage_5_31() },\n        \"collage_6_1_1\" to { SixFrameImage.collage_6_1_1() },\n        \"collage_6_1_2\" to { SixFrameImage.collage_6_1_2() },\n        \"collage_6_0\" to { SixFrameImage.collage_6_0() },\n        \"collage_6_1\" to { SixFrameImage.collage_6_1() },\n        \"collage_6_2\" to { SixFrameImage.collage_6_2() },\n        \"collage_6_3\" to { SixFrameImage.collage_6_3() },\n        \"collage_6_4\" to { SixFrameImage.collage_6_4() },\n        \"collage_6_5\" to { SixFrameImage.collage_6_5() },\n        \"collage_6_6\" to { SixFrameImage.collage_6_6() },\n        \"collage_6_7\" to { SixFrameImage.collage_6_7() },\n        \"collage_6_8\" to { SixFrameImage.collage_6_8() },\n        \"collage_6_9\" to { SixFrameImage.collage_6_9() },\n        \"collage_6_10\" to { SixFrameImage.collage_6_10() },\n        \"collage_6_11\" to { SixFrameImage.collage_6_11() },\n        \"collage_6_12\" to { SixFrameImage.collage_6_12() },\n        \"collage_6_13\" to { SixFrameImage.collage_6_13() },\n        \"collage_6_14\" to { SixFrameImage.collage_6_14() },\n        \"collage_7_1_1\" to { SevenFrameImage.collage_7_1_1() },\n        \"collage_7_1_2\" to { SevenFrameImage.collage_7_1_2() },\n        \"collage_7_0\" to { SevenFrameImage.collage_7_0() },\n        \"collage_7_1\" to { SevenFrameImage.collage_7_1() },\n        \"collage_7_2\" to { SevenFrameImage.collage_7_2() },\n        \"collage_7_3\" to { SevenFrameImage.collage_7_3() },\n        \"collage_7_4\" to { SevenFrameImage.collage_7_4() },\n        \"collage_7_5\" to { SevenFrameImage.collage_7_5() },\n        \"collage_7_6\" to { SevenFrameImage.collage_7_6() },\n        \"collage_7_7\" to { SevenFrameImage.collage_7_7() },\n        \"collage_7_8\" to { SevenFrameImage.collage_7_8() },\n        \"collage_7_9\" to { SevenFrameImage.collage_7_9() },\n        \"collage_7_10\" to { SevenFrameImage.collage_7_10() },\n        \"collage_8_0\" to { EightFrameImage.collage_8_0() },\n        \"collage_8_1\" to { EightFrameImage.collage_8_1() },\n        \"collage_8_2\" to { EightFrameImage.collage_8_2() },\n        \"collage_8_3\" to { EightFrameImage.collage_8_3() },\n        \"collage_8_4\" to { EightFrameImage.collage_8_4() },\n        \"collage_8_5\" to { EightFrameImage.collage_8_5() },\n        \"collage_8_6\" to { EightFrameImage.collage_8_6() },\n        \"collage_8_7\" to { EightFrameImage.collage_8_7() },\n        \"collage_8_8\" to { EightFrameImage.collage_8_8() },\n        \"collage_8_9\" to { EightFrameImage.collage_8_9() },\n        \"collage_8_10\" to { EightFrameImage.collage_8_10() },\n        \"collage_8_11\" to { EightFrameImage.collage_8_11() },\n        \"collage_8_12\" to { EightFrameImage.collage_8_12() },\n        \"collage_8_13\" to { EightFrameImage.collage_8_13() },\n        \"collage_8_14\" to { EightFrameImage.collage_8_14() },\n        \"collage_8_15\" to { EightFrameImage.collage_8_15() },\n        \"collage_8_16\" to { EightFrameImage.collage_8_16() },\n        \"collage_9_0\" to { NineFrameImage.collage_9_0() },\n        \"collage_9_1\" to { NineFrameImage.collage_9_1() },\n        \"collage_9_2\" to { NineFrameImage.collage_9_2() },\n        \"collage_9_3\" to { NineFrameImage.collage_9_3() },\n        \"collage_9_4\" to { NineFrameImage.collage_9_4() },\n        \"collage_9_5\" to { NineFrameImage.collage_9_5() },\n        \"collage_9_6\" to { NineFrameImage.collage_9_6() },\n        \"collage_9_7\" to { NineFrameImage.collage_9_7() },\n        \"collage_9_8\" to { NineFrameImage.collage_9_8() },\n        \"collage_9_9\" to { NineFrameImage.collage_9_9() },\n        \"collage_9_10\" to { NineFrameImage.collage_9_10() },\n        \"collage_9_11\" to { NineFrameImage.collage_9_11() },\n        \"collage_10_0\" to { TenFrameImage.collage_10_0() },\n        \"collage_10_1\" to { TenFrameImage.collage_10_1() },\n        \"collage_10_2\" to { TenFrameImage.collage_10_2() },\n        \"collage_10_3\" to { TenFrameImage.collage_10_3() },\n        \"collage_10_4\" to { TenFrameImage.collage_10_4() },\n        \"collage_10_5\" to { TenFrameImage.collage_10_5() },\n        \"collage_10_6\" to { TenFrameImage.collage_10_6() },\n        \"collage_10_7\" to { TenFrameImage.collage_10_7() },\n        \"collage_10_8\" to { TenFrameImage.collage_10_8() },\n        \"collage_10_9\" to { ExtendedFrameImage.collage_10_9() },\n        \"collage_10_10\" to { ExtendedFrameImage.collage_10_10() },\n        \"collage_2_12\" to { ExtendedFrameImage.collage_2_12() },\n        \"collage_2_13\" to { ExtendedFrameImage.collage_2_13() },\n        \"collage_3_48\" to { ExtendedFrameImage.collage_3_48() },\n        \"collage_4_26\" to { ExtendedFrameImage.collage_4_26() },\n        \"collage_4_27\" to { ExtendedFrameImage.collage_4_27() },\n        \"collage_5_32\" to { ExtendedFrameImage.collage_5_32() },\n        \"collage_5_33\" to { ExtendedFrameImage.collage_5_33() },\n        \"collage_6_15\" to { ExtendedFrameImage.collage_6_15() },\n        \"collage_6_16\" to { ExtendedFrameImage.collage_6_16() },\n        \"collage_6_17\" to { ExtendedFrameImage.collage_6_17() },\n        \"collage_7_11\" to { ExtendedFrameImage.collage_7_11() },\n        \"collage_7_12\" to { ExtendedFrameImage.collage_7_12() },\n        \"collage_8_17\" to { ExtendedFrameImage.collage_8_17() },\n        \"collage_8_18\" to { ExtendedFrameImage.collage_8_18() },\n        \"collage_9_12\" to { ExtendedFrameImage.collage_9_12() },\n        \"collage_9_13\" to { ExtendedFrameImage.collage_9_13() },\n        \"collage_11_0\" to { ExtendedFrameImage.collage_11_0() },\n        \"collage_11_1\" to { ExtendedFrameImage.collage_11_1() },\n        \"collage_11_2\" to { ExtendedFrameImage.collage_11_2() },\n        \"collage_11_3\" to { ExtendedFrameImage.collage_11_3() },\n        \"collage_11_4\" to { ExtendedFrameImage.collage_11_4() },\n        \"collage_11_5\" to { ExtendedFrameImage.collage_11_5() },\n        \"collage_11_6\" to { ExtendedFrameImage.collage_11_6() },\n        \"collage_11_7\" to { ExtendedFrameImage.collage_11_7() },\n        \"collage_11_8\" to { ExtendedFrameImage.collage_11_8() },\n        \"collage_11_9\" to { ExtendedFrameImage.collage_11_9() },\n        \"collage_11_10\" to { ExtendedFrameImage.collage_11_10() },\n        \"collage_12_0\" to { ExtendedFrameImage.collage_12_0() },\n        \"collage_12_1\" to { ExtendedFrameImage.collage_12_1() },\n        \"collage_12_2\" to { ExtendedFrameImage.collage_12_2() },\n        \"collage_12_3\" to { ExtendedFrameImage.collage_12_3() },\n        \"collage_12_4\" to { ExtendedFrameImage.collage_12_4() },\n        \"collage_12_5\" to { ExtendedFrameImage.collage_12_5() },\n        \"collage_12_6\" to { ExtendedFrameImage.collage_12_6() },\n        \"collage_12_7\" to { ExtendedFrameImage.collage_12_7() },\n        \"collage_12_8\" to { ExtendedFrameImage.collage_12_8() },\n        \"collage_12_9\" to { ExtendedFrameImage.collage_12_9() },\n        \"collage_12_10\" to { ExtendedFrameImage.collage_12_10() },\n        \"collage_13_0\" to { ExtendedFrameImage.collage_13_0() },\n        \"collage_13_1\" to { ExtendedFrameImage.collage_13_1() },\n        \"collage_13_2\" to { ExtendedFrameImage.collage_13_2() },\n        \"collage_13_3\" to { ExtendedFrameImage.collage_13_3() },\n        \"collage_13_4\" to { ExtendedFrameImage.collage_13_4() },\n        \"collage_13_5\" to { ExtendedFrameImage.collage_13_5() },\n        \"collage_13_6\" to { ExtendedFrameImage.collage_13_6() },\n        \"collage_13_7\" to { ExtendedFrameImage.collage_13_7() },\n        \"collage_13_8\" to { ExtendedFrameImage.collage_13_8() },\n        \"collage_13_9\" to { ExtendedFrameImage.collage_13_9() },\n        \"collage_13_10\" to { ExtendedFrameImage.collage_13_10() },\n        \"collage_14_0\" to { ExtendedFrameImage.collage_14_0() },\n        \"collage_14_1\" to { ExtendedFrameImage.collage_14_1() },\n        \"collage_14_2\" to { ExtendedFrameImage.collage_14_2() },\n        \"collage_14_3\" to { ExtendedFrameImage.collage_14_3() },\n        \"collage_14_4\" to { ExtendedFrameImage.collage_14_4() },\n        \"collage_14_5\" to { ExtendedFrameImage.collage_14_5() },\n        \"collage_14_6\" to { ExtendedFrameImage.collage_14_6() },\n        \"collage_14_7\" to { ExtendedFrameImage.collage_14_7() },\n        \"collage_14_8\" to { ExtendedFrameImage.collage_14_8() },\n        \"collage_14_9\" to { ExtendedFrameImage.collage_14_9() },\n        \"collage_14_10\" to { ExtendedFrameImage.collage_14_10() },\n        \"collage_15_0\" to { ExtendedFrameImage.collage_15_0() },\n        \"collage_15_1\" to { ExtendedFrameImage.collage_15_1() },\n        \"collage_15_2\" to { ExtendedFrameImage.collage_15_2() },\n        \"collage_15_3\" to { ExtendedFrameImage.collage_15_3() },\n        \"collage_15_4\" to { ExtendedFrameImage.collage_15_4() },\n        \"collage_15_5\" to { ExtendedFrameImage.collage_15_5() },\n        \"collage_15_6\" to { ExtendedFrameImage.collage_15_6() },\n        \"collage_15_7\" to { ExtendedFrameImage.collage_15_7() },\n        \"collage_15_8\" to { ExtendedFrameImage.collage_15_8() },\n        \"collage_15_9\" to { ExtendedFrameImage.collage_15_9() },\n        \"collage_15_10\" to { ExtendedFrameImage.collage_15_10() },\n        \"collage_16_0\" to { ExtendedFrameImage.collage_16_0() },\n        \"collage_16_1\" to { ExtendedFrameImage.collage_16_1() },\n        \"collage_16_2\" to { ExtendedFrameImage.collage_16_2() },\n        \"collage_16_3\" to { ExtendedFrameImage.collage_16_3() },\n        \"collage_16_4\" to { ExtendedFrameImage.collage_16_4() },\n        \"collage_16_5\" to { ExtendedFrameImage.collage_16_5() },\n        \"collage_16_6\" to { ExtendedFrameImage.collage_16_6() },\n        \"collage_16_7\" to { ExtendedFrameImage.collage_16_7() },\n        \"collage_16_8\" to { ExtendedFrameImage.collage_16_8() },\n        \"collage_16_9\" to { ExtendedFrameImage.collage_16_9() },\n        \"collage_16_10\" to { ExtendedFrameImage.collage_16_10() },\n        \"collage_17_0\" to { ExtendedFrameImage.collage_17_0() },\n        \"collage_17_1\" to { ExtendedFrameImage.collage_17_1() },\n        \"collage_17_2\" to { ExtendedFrameImage.collage_17_2() },\n        \"collage_17_3\" to { ExtendedFrameImage.collage_17_3() },\n        \"collage_17_4\" to { ExtendedFrameImage.collage_17_4() },\n        \"collage_17_5\" to { ExtendedFrameImage.collage_17_5() },\n        \"collage_17_6\" to { ExtendedFrameImage.collage_17_6() },\n        \"collage_17_7\" to { ExtendedFrameImage.collage_17_7() },\n        \"collage_17_8\" to { ExtendedFrameImage.collage_17_8() },\n        \"collage_17_9\" to { ExtendedFrameImage.collage_17_9() },\n        \"collage_17_10\" to { ExtendedFrameImage.collage_17_10() },\n        \"collage_18_0\" to { ExtendedFrameImage.collage_18_0() },\n        \"collage_18_1\" to { ExtendedFrameImage.collage_18_1() },\n        \"collage_18_2\" to { ExtendedFrameImage.collage_18_2() },\n        \"collage_18_3\" to { ExtendedFrameImage.collage_18_3() },\n        \"collage_18_4\" to { ExtendedFrameImage.collage_18_4() },\n        \"collage_18_5\" to { ExtendedFrameImage.collage_18_5() },\n        \"collage_18_6\" to { ExtendedFrameImage.collage_18_6() },\n        \"collage_18_7\" to { ExtendedFrameImage.collage_18_7() },\n        \"collage_18_8\" to { ExtendedFrameImage.collage_18_8() },\n        \"collage_18_9\" to { ExtendedFrameImage.collage_18_9() },\n        \"collage_18_10\" to { ExtendedFrameImage.collage_18_10() },\n        \"collage_19_0\" to { ExtendedFrameImage.collage_19_0() },\n        \"collage_19_1\" to { ExtendedFrameImage.collage_19_1() },\n        \"collage_19_2\" to { ExtendedFrameImage.collage_19_2() },\n        \"collage_19_3\" to { ExtendedFrameImage.collage_19_3() },\n        \"collage_19_4\" to { ExtendedFrameImage.collage_19_4() },\n        \"collage_19_5\" to { ExtendedFrameImage.collage_19_5() },\n        \"collage_19_6\" to { ExtendedFrameImage.collage_19_6() },\n        \"collage_19_7\" to { ExtendedFrameImage.collage_19_7() },\n        \"collage_19_8\" to { ExtendedFrameImage.collage_19_8() },\n        \"collage_19_9\" to { ExtendedFrameImage.collage_19_9() },\n        \"collage_19_10\" to { ExtendedFrameImage.collage_19_10() },\n        \"collage_20_0\" to { ExtendedFrameImage.collage_20_0() },\n        \"collage_20_1\" to { ExtendedFrameImage.collage_20_1() },\n        \"collage_20_2\" to { ExtendedFrameImage.collage_20_2() },\n        \"collage_20_3\" to { ExtendedFrameImage.collage_20_3() },\n        \"collage_20_4\" to { ExtendedFrameImage.collage_20_4() },\n        \"collage_20_5\" to { ExtendedFrameImage.collage_20_5() },\n        \"collage_20_6\" to { ExtendedFrameImage.collage_20_6() },\n        \"collage_20_7\" to { ExtendedFrameImage.collage_20_7() },\n        \"collage_20_8\" to { ExtendedFrameImage.collage_20_8() },\n        \"collage_20_9\" to { ExtendedFrameImage.collage_20_9() },\n        \"collage_20_10\" to { ExtendedFrameImage.collage_20_10() },\n    )\n\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/utils/GeometryUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"LocalVariableName\", \"FunctionName\")\n\npackage com.t8rin.collages.utils\n\nimport android.graphics.Path\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport java.util.Arrays\nimport java.util.Objects\nimport java.util.function.Supplier\nimport kotlin.math.abs\nimport kotlin.math.acos\nimport kotlin.math.atan2\nimport kotlin.math.cos\nimport kotlin.math.sin\nimport kotlin.math.sqrt\n\n/**\n * @noinspection unused\n */\n/*\n * All points of polygon must be ordered by clockwise along<br>\n * Created by admin on 5/4/2016.\n */\nobject GeometryUtils {\n    fun isInCircle(center: PointF, radius: Float, p: PointF): Boolean {\n        return (sqrt(((center.x - p.x) * (center.x - p.x) + (center.y - p.y) * (center.y - p.y)).toDouble()) <= radius)\n    }\n\n    /**\n     * Return true if the given point is contained inside the boundary.\n     * See: [Short_Notes](http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html)\n     * \n     * @param test The point to check\n     * @return true if the point is inside the boundary, false otherwise\n     */\n    fun contains(points: List<PointF>, test: PointF): Boolean {\n        var j: Int\n        var result = false\n        var i = 0\n        j = points.size - 1\n        while (i < points.size) {\n            if ((points[i].y > test.y) != (points[j].y > test.y) &&\n                (test.x < (points[j].x - points[i].x) * (test.y - points[i].y) / (points[j].y - points[i].y) + points[i].x)\n            ) {\n                result = !result\n            }\n            j = i++\n        }\n        return result\n    }\n\n    fun createRectanglePath(outPath: Path, width: Float, height: Float, corner: Float) {\n        val pointList = ArrayList<PointF>()\n        pointList.add(PointF(0f, 0f))\n        pointList.add(PointF(width, 0f))\n        pointList.add(PointF(width, height))\n        pointList.add(PointF(0f, height))\n        createPathWithCircleCorner(outPath, pointList, corner)\n    }\n\n    fun createRegularPolygonPath(outPath: Path, size: Float, vertexCount: Int, corner: Float) {\n        createRegularPolygonPath(outPath, size, size / 2, size / 2, vertexCount, corner)\n    }\n\n    fun createRegularPolygonPath(\n        outPath: Path,\n        size: Float,\n        centerX: Float,\n        centerY: Float,\n        vertexCount: Int,\n        corner: Float\n    ) {\n        val section = (2.0 * Math.PI / vertexCount).toFloat()\n        val radius = size / 2\n        val pointList = ArrayList<PointF>()\n        pointList.add(\n            PointF(\n                (centerX + radius * cos(0.0)).toFloat(),\n                (centerY + radius * sin(0.0)).toFloat()\n            )\n        )\n        for (i in 1..<vertexCount) {\n            pointList.add(\n                PointF(\n                    (centerX + radius * cos((section * i).toDouble())).toFloat(),\n                    (centerY + radius * sin((section * i).toDouble())).toFloat()\n                )\n            )\n        }\n\n        createPathWithCircleCorner(outPath, pointList, corner)\n    }\n\n    fun shrinkPathCollageUsingMap(\n        pointList: MutableList<PointF>,\n        space: Float,\n        map: HashMap<PointF, PointF>\n    ): List<PointF> {\n        val result = ArrayList<PointF>()\n        for (p in pointList) {\n            val add: PointF = checkNotNull(map[p])\n            result.add(PointF(p.x + add.x * space, p.y + add.y * space))\n        }\n        return result\n    }\n\n    /**\n     * Resolve case frame collage 3_3\n     * \n     * @param pointList list\n     * @param space     space\n     * @param bound     bound\n     * @return shrink points\n     */\n    fun shrinkPathCollage_3_3(\n        pointList: List<PointF>,\n        centerPointIdx: Int,\n        space: Float,\n        bound: RectF?\n    ): List<PointF> {\n        val result = ArrayList<PointF>()\n        val center = pointList[centerPointIdx]\n        val left: PointF = if (centerPointIdx > 0) {\n            pointList[centerPointIdx - 1]\n        } else {\n            pointList[pointList.size - 1]\n        }\n\n        val right: PointF = if (centerPointIdx < pointList.size - 1) {\n            pointList[centerPointIdx + 1]\n        } else {\n            pointList[0]\n        }\n\n        var spaceX: Float\n        var spaceY: Float\n        for (p in pointList) {\n            val pointF = PointF()\n            spaceX = space\n            spaceY = space\n            if (bound != null) {\n                if ((bound.left == 0f && p.x < center.x) || (bound.right == 1f && p.x >= center.x)) {\n                    spaceX = 2 * space\n                }\n\n                if ((bound.top == 0f && p.y < center.y) || (bound.bottom == 1f && p.y >= center.y)) {\n                    spaceY = 2 * space\n                }\n            }\n\n            if (left.x == right.x) {\n                if (left.x < center.x) {\n                    if (p.x <= center.x) {\n                        pointF.x = p.x + spaceX\n                    } else {\n                        pointF.x = p.x - spaceX\n                    }\n                } else {\n                    if (p.x < center.x) {\n                        pointF.x = p.x + spaceX\n                    } else {\n                        pointF.x = p.x - spaceX\n                    }\n                }\n\n                if (p !== left && p !== right && p !== center) {\n                    if (p.y < center.y) {\n                        pointF.y = p.y + spaceY\n                    } else {\n                        pointF.y = p.y - spaceY\n                    }\n                } else if (p === left || p === right) {\n                    if (p.y < center.y) {\n                        pointF.y = p.y - space\n                    } else {\n                        pointF.y = p.y + space\n                    }\n                } else {\n                    pointF.y = p.y\n                }\n            }\n\n            result.add(pointF)\n        }\n\n        return result\n    }\n\n    fun shrinkPath(\n        pointList: List<PointF>,\n        space: Float,\n        bound: RectF?\n    ): List<PointF> {\n        val result = ArrayList<PointF>()\n        if (space == 0f) {\n            result.addAll(pointList)\n        } else {\n            val center = PointF(0f, 0f)\n            for (p in pointList) {\n                center.x += p.x\n                center.y += p.y\n            }\n\n            center.x /= pointList.size\n            center.y /= pointList.size\n            var spaceX: Float\n            var spaceY: Float\n            for (p in pointList) {\n                val pointF = PointF()\n                spaceX = space\n                spaceY = space\n                if (bound != null) {\n                    if ((bound.left == 0f && p.x < center.x) || (bound.right == 1f && p.x >= center.x)) {\n                        spaceX = 2 * space\n                    }\n\n                    if ((bound.top == 0f && p.y < center.y) || (bound.bottom == 1f && p.y >= center.y)) {\n                        spaceY = 2 * space\n                    }\n                }\n\n                if (abs(center.x - p.x) >= 1) {\n                    if (p.x < center.x) {\n                        pointF.x = p.x + spaceX\n                    } else if (p.x > center.x) {\n                        pointF.x = p.x - spaceX\n                    }\n                } else {\n                    pointF.x = p.x\n                }\n\n                if (abs(center.y - p.y) >= 1) {\n                    if (p.y < center.y) {\n                        pointF.y = p.y + spaceY\n                    } else if (p.y > center.y) {\n                        pointF.y = p.y - spaceY\n                    }\n                } else {\n                    pointF.y = p.y\n                }\n\n                result.add(pointF)\n            }\n        }\n        return result\n    }\n\n    fun commonShrinkPath(\n        pointList: List<PointF>,\n        space: Float,\n        shrunkPointLeftRightDistances: Map<PointF, PointF>\n    ): List<PointF> {\n        val result = ArrayList<PointF>()\n        if (space == 0f) {\n            result.addAll(pointList)\n        } else {\n            val convexHull = jarvis(pointList)\n            for (i in pointList.indices) {\n                val center = pointList[i]\n                var concave = true\n                for (point in convexHull) if (center === point) {\n                    concave = false\n                    break\n                }\n                val left: PointF = if (i == 0) {\n                    pointList[pointList.size - 1]\n                } else {\n                    pointList[i - 1]\n                }\n\n                val right: PointF = if (i == pointList.size - 1) {\n                    pointList[0]\n                } else {\n                    pointList[i + 1]\n                }\n\n                val leftRightDistance: PointF =\n                    checkNotNull(shrunkPointLeftRightDistances[center])\n                val pointF = shrinkPoint(\n                    center,\n                    left,\n                    right,\n                    leftRightDistance.x * space,\n                    leftRightDistance.y * space,\n                    !concave,\n                    !concave\n                )\n                result.add(\n                    Objects.requireNonNullElseGet<PointF>(\n                        pointF,\n                        Supplier { PointF(0f, 0f) }\n                    )\n                )\n            }\n        }\n        return result\n    }\n\n    fun createPathWithCubicCorner(path: Path, pointList: List<PointF>, corner: Float) {\n        path.reset()\n        for (i in pointList.indices) {\n            if (corner == 0f || pointList.size < 3) {\n                if (i == 0) {\n                    path.moveTo(pointList[i].x, pointList[i].y)\n                } else {\n                    path.lineTo(pointList[i].x, pointList[i].y)\n                }\n            } else {\n                val center = PointF(pointList[i].x, pointList[i].y)\n                val left = PointF()\n                val right = PointF()\n                if (i == 0) {\n                    left.x = pointList[pointList.size - 1].x\n                    left.y = pointList[pointList.size - 1].y\n                } else {\n                    left.x = pointList[i - 1].x\n                    left.y = pointList[i - 1].y\n                }\n\n                if (i == pointList.size - 1) {\n                    right.x = pointList[0].x\n                    right.y = pointList[0].y\n                } else {\n                    right.x = pointList[i + 1].x\n                    right.y = pointList[i + 1].y\n                }\n\n                val middleA = findPointOnSegment(center, left, corner.toDouble())\n                val middleB = findPointOnSegment(center, right, corner.toDouble())\n                val middle = findMiddlePoint(middleA, middleB, center)\n                if (i == 0) {\n                    path.moveTo(middleA.x, middleA.y)\n                } else {\n                    path.lineTo(middleA.x, middleA.y)\n                }\n                path.cubicTo(middleA.x, middleA.y, middle.x, middle.y, middleB.x, middleB.y)\n            }\n        }\n    }\n\n    private fun containPoint(points: List<PointF>, p: PointF): Boolean {\n        for (pointF in points) if ((pointF.x == p.x && pointF.y == p.y)) {\n            return true\n        }\n        return false\n    }\n\n    fun createPathWithCircleCorner(\n        path: Path,\n        pointList: List<PointF>,\n        cornerPointList: List<PointF>,\n        corner: Float\n    ): Map<PointF, Array<PointF>>? {\n        if (pointList.isEmpty()) {\n            return null\n        }\n        val cornerPointMap =\n            HashMap<PointF, Array<PointF>>()\n        path.reset()\n        var firstPoints = arrayOf(pointList[0], pointList[0], pointList[0])\n        val convexHull = jarvis(pointList)\n        for (i in pointList.indices) {\n            if (corner == 0f || pointList.size < 3) {\n                if (i == 0) {\n                    path.moveTo(pointList[i].x, pointList[i].y)\n                } else {\n                    path.lineTo(pointList[i].x, pointList[i].y)\n                }\n            } else {\n                var isCornerPoint = true\n                if (cornerPointList.isNotEmpty()) {\n                    isCornerPoint = containPoint(cornerPointList, pointList[i])\n                }\n\n                if (!isCornerPoint) {\n                    if (i == 0) {\n                        path.moveTo(pointList[i].x, pointList[i].y)\n                    } else {\n                        path.lineTo(pointList[i].x, pointList[i].y)\n                    }\n                    if (i == pointList.size - 1) {\n                        path.lineTo(firstPoints[1].x, firstPoints[1].y)\n                    }\n                } else {\n                    var concave = true\n                    for (p in convexHull) if (p === pointList[i]) {\n                        concave = false\n                        break\n                    }\n                    val center = PointF(pointList[i].x, pointList[i].y)\n                    val left = PointF()\n                    val right = PointF()\n                    if (i == 0) {\n                        left.x = pointList[pointList.size - 1].x\n                        left.y = pointList[pointList.size - 1].y\n                    } else {\n                        left.x = pointList[i - 1].x\n                        left.y = pointList[i - 1].y\n                    }\n\n                    if (i == pointList.size - 1) {\n                        right.x = pointList[0].x\n                        right.y = pointList[0].y\n                    } else {\n                        right.x = pointList[i + 1].x\n                        right.y = pointList[i + 1].y\n                    }\n\n                    val pointFs = Array(3) {\n                        PointF()\n                    }\n                    val angles = DoubleArray(2)\n                    createArc(center, left, right, corner, angles, pointFs, concave)\n                    if (i == 0) {\n                        path.moveTo(pointFs[1].x, pointFs[1].y)\n                    } else {\n                        path.lineTo(pointFs[1].x, pointFs[1].y)\n                    }\n\n                    val oval = RectF(\n                        pointFs[0].x - corner,\n                        pointFs[0].y - corner,\n                        pointFs[0].x + corner,\n                        pointFs[0].y + corner\n                    )\n                    path.arcTo(oval, angles[0].toFloat(), angles[1].toFloat(), false)\n\n                    if (i == 0) {\n                        firstPoints = pointFs\n                    }\n\n                    if (i == pointList.size - 1) {\n                        path.lineTo(firstPoints[1].x, firstPoints[1].y)\n                    }\n\n                    cornerPointMap[pointList[i]] = pointFs\n                }\n            }\n        }\n\n        return cornerPointMap\n    }\n\n    fun createPathWithCircleCorner(path: Path, pointList: List<PointF>, corner: Float) {\n        path.reset()\n        var firstPoints: Array<PointF>? = null\n        val convexHull = jarvis(pointList)\n        for (i in pointList.indices) {\n            if (corner == 0f || pointList.size < 3) {\n                if (i == 0) {\n                    path.moveTo(pointList[i].x, pointList[i].y)\n                } else {\n                    path.lineTo(pointList[i].x, pointList[i].y)\n                }\n            } else {\n                var concave = true\n                for (p in convexHull) if (p === pointList[i]) {\n                    concave = false\n                    break\n                }\n\n                val center = PointF(pointList[i].x, pointList[i].y)\n                val left = PointF()\n                val right = PointF()\n                if (i == 0) {\n                    left.x = pointList[pointList.size - 1].x\n                    left.y = pointList[pointList.size - 1].y\n                } else {\n                    left.x = pointList[i - 1].x\n                    left.y = pointList[i - 1].y\n                }\n\n                if (i == pointList.size - 1) {\n                    right.x = pointList[0].x\n                    right.y = pointList[0].y\n                } else {\n                    right.x = pointList[i + 1].x\n                    right.y = pointList[i + 1].y\n                }\n\n                val pointFs = Array(3) { PointF() }\n                val angles = DoubleArray(2)\n                createArc(center, left, right, corner, angles, pointFs, concave)\n                if (i == 0) {\n                    path.moveTo(pointFs[1].x, pointFs[1].y)\n                } else {\n                    path.lineTo(pointFs[1].x, pointFs[1].y)\n                }\n\n                val oval = RectF(\n                    pointFs[0].x - corner,\n                    pointFs[0].y - corner,\n                    pointFs[0].x + corner,\n                    pointFs[0].y + corner\n                )\n                path.arcTo(oval, angles[0].toFloat(), angles[1].toFloat(), false)\n\n                if (i == 0) {\n                    firstPoints = pointFs\n                }\n\n                if (i == pointList.size - 1) {\n                    checkNotNull(firstPoints)\n                    path.lineTo(firstPoints[1].x, firstPoints[1].y)\n                }\n            }\n        }\n    }\n\n    fun findPointOnSegment(A: PointF, B: PointF, dA: Double): PointF {\n        if (dA == 0.0) {\n            return PointF(A.x, A.y)\n        } else {\n            val result = PointF()\n            val dAB =\n                (sqrt(((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)).toDouble())).toFloat()\n            val dx = abs(A.x - B.x) * dA / dAB\n            val dy = abs(A.y - B.y) * dA / dAB\n            if (A.x > B.x) {\n                result.x = (A.x - dx).toFloat()\n            } else {\n                result.x = (A.x + dx).toFloat()\n            }\n\n            if (A.y > B.y) {\n                result.y = (A.y - dy).toFloat()\n            } else {\n                result.y = (A.y + dy).toFloat()\n            }\n\n            return result\n        }\n    }\n\n    fun findMiddlePoint(A: PointF, B: PointF, D: PointF): PointF {\n        val d =\n            (sqrt(((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)).toDouble()) / 2).toFloat()\n        return findMiddlePoint(A, B, d, D)\n    }\n\n    fun findMiddlePoint(A: PointF, B: PointF, d: Float, D: PointF): PointF {\n        val a = B.y - A.y\n        val b = A.x - B.x\n        val c = B.x * A.y - A.x * B.y\n        val middlePoints = findMiddlePoint(A, B, d)\n        val f = a * D.x + b * D.y + c\n        val f1 = a * middlePoints[0].x + b * middlePoints[0].y + c\n        return if (f * f1 > Float.MIN_VALUE) {\n            middlePoints[0]\n        } else {\n            middlePoints[1]\n        }\n    }\n\n\n    fun createArc(\n        A: PointF,\n        B: PointF,\n        C: PointF,\n        dA: Float,\n        outAngles: DoubleArray,\n        outPoints: Array<PointF>,\n        isConcave: Boolean\n    ) {\n        outPoints[0] = findPointOnBisector(A, B, C, dA) ?: return\n        var d =\n            (((A.x - outPoints[0].x) * (A.x - outPoints[0].x) + (A.y - outPoints[0].y) * (A.y - outPoints[0].y)) - dA * dA).toDouble()\n        d = sqrt(d)\n        outPoints[1] = findPointOnSegment(A, B, d)\n        outPoints[2] = findPointOnSegment(A, C, d)\n        //find angles\n        val dMA =\n            sqrt(((A.x - outPoints[0].x) * (A.x - outPoints[0].x) + (A.y - outPoints[0].y) * (A.y - outPoints[0].y)).toDouble())\n        val halfSweepAngle = acos(dA / dMA)\n        val startAngle = atan2(\n            (outPoints[1].y - outPoints[0].y).toDouble(),\n            (outPoints[1].x - outPoints[0].x).toDouble()\n        )\n        val endAngle = atan2(\n            (outPoints[2].y - outPoints[0].y).toDouble(),\n            (outPoints[2].x - outPoints[0].x).toDouble()\n        )\n        var sweepAngle = endAngle - startAngle\n        if (!isConcave) {\n            sweepAngle = 2 * halfSweepAngle\n        }\n\n        outAngles[0] = Math.toDegrees(startAngle)\n        outAngles[1] = Math.toDegrees(sweepAngle)\n        val tmp = Math.toDegrees(2 * halfSweepAngle)\n        if (abs(tmp - abs(outAngles[1])) > 1) {\n            outAngles[1] = -tmp\n        }\n    }\n\n    /**\n     * @param A  point\n     * @param B  point\n     * @param C  point\n     * @param dA point\n     * @return null if does not have solution, return PointF(Float.MaxValue, Float.MaxValue) if have infinite solution, other return the solution\n     */\n    fun findPointOnBisector(A: PointF, B: PointF, C: PointF, dA: Float): PointF? {\n        val lineAB = getCoefficients(A, B)\n        val lineAC = getCoefficients(A, C)\n        val vB = lineAC[0] * B.x + lineAC[1] * B.y + lineAC[2]\n        val vC = lineAB[0] * C.x + lineAB[1] * C.y + lineAB[2]\n        val square1 = sqrt(lineAB[0] * lineAB[0] + lineAB[1] * lineAB[1])\n        val square2 = sqrt(lineAC[0] * lineAC[0] + lineAC[1] * lineAC[1])\n        if (vC > 0) {\n            return if (vB > 0) {\n                findIntersectPoint(\n                    lineAB[0], lineAB[1], dA * square1 - lineAB[2],\n                    lineAC[0], lineAC[1], dA * square2 - lineAC[2]\n                )\n            } else {\n                findIntersectPoint(\n                    lineAB[0], lineAB[1], dA * square1 - lineAB[2],\n                    -lineAC[0], -lineAC[1], dA * square2 + lineAC[2]\n                )\n            }\n        } else {\n            return if (vB > 0) {\n                findIntersectPoint(\n                    -lineAB[0], -lineAB[1], dA * square1 + lineAB[2],\n                    lineAC[0], lineAC[1], dA * square2 - lineAC[2]\n                )\n            } else {\n                findIntersectPoint(\n                    -lineAB[0], -lineAB[1], dA * square1 + lineAB[2],\n                    -lineAC[0], -lineAC[1], dA * square2 + lineAC[2]\n                )\n            }\n        }\n    }\n\n    fun distanceToLine(line: DoubleArray, P: PointF): Double {\n        val bottom = sqrt(line[0] * line[0] + line[1] * line[1])\n        return abs((line[0] * P.x + line[1] * P.y + line[2]) / bottom)\n    }\n\n    /**\n     * @param A   point\n     * @param B   point\n     * @param C   point\n     * @param dAB is the distance from shrunk point to AB line\n     * @param dAC is the distance from shrunk point to AC line\n     * @param b   is true if shrunk point and point B located on same half-plane\n     * @param c   is true if shrunk point and point C located on same half-plane\n     * @return shrunk point of point A\n     */\n    fun shrinkPoint(\n        A: PointF,\n        B: PointF,\n        C: PointF,\n        dAB: Float,\n        dAC: Float,\n        b: Boolean,\n        c: Boolean\n    ): PointF? {\n        val ab = getCoefficients(A, B)\n        val ac = getCoefficients(A, C)\n        val sqrt = sqrt(ab[0] * ab[0] + ab[1] * ab[1])\n        val m = dAB * sqrt - ab[2]\n        val sqrt1 = sqrt(ac[0] * ac[0] + ac[1] * ac[1])\n        val n = dAC * sqrt1 - ac[2]\n        val p = -dAB * sqrt - ab[2]\n        val q = -dAC * sqrt1 - ac[2]\n        val P1 = findIntersectPoint(ab[0], ab[1], m, ac[0], ac[1], n)\n        val P2 = findIntersectPoint(ab[0], ab[1], m, ac[0], ac[1], q)\n        val P3 = findIntersectPoint(ab[0], ab[1], p, ac[0], ac[1], n)\n        val P4 = findIntersectPoint(ab[0], ab[1], p, ac[0], ac[1], q)\n        return if (testShrunkPoint(ab, ac, B, C, P1, b, c)) {\n            P1\n        } else if (testShrunkPoint(ab, ac, B, C, P2, b, c)) {\n            P2\n        } else if (testShrunkPoint(ab, ac, B, C, P3, b, c)) {\n            P3\n        } else if (testShrunkPoint(ab, ac, B, C, P4, b, c)) {\n            P4\n        } else {\n            null\n        }\n    }\n\n    private fun testShrunkPoint(\n        ab: DoubleArray,\n        ac: DoubleArray,\n        B: PointF,\n        C: PointF,\n        P: PointF?,\n        b: Boolean,\n        c: Boolean\n    ): Boolean {\n        if (P != null && P.x < Float.MAX_VALUE && P.y < Float.MAX_VALUE) {\n            val signC = (ab[0] * P.x + ab[1] * P.y + ab[2]) * (ab[0] * C.x + ab[1] * C.y + ab[2])\n            val signB = (ac[0] * P.x + ac[1] * P.y + ac[2]) * (ac[0] * B.x + ac[1] * B.y + ac[2])\n            val testC = signC > Double.MIN_VALUE\n            val testB = signB > Double.MIN_VALUE\n            return testC == c && testB == b\n        }\n        return false\n    }\n\n    /**\n     * Solve equations\n     * ax + by = c\n     * dx + ey = f\n     * \n     * @param a point\n     * @param b point\n     * @param c point\n     * @param d point\n     * @param e point\n     * @param f point\n     * @return null if this equations does not has solution.\n     * return PointF(Float.MaxValue, Float.MaxValue) if this equations has infinite solutions\n     * other return the solution of this equations.\n     */\n    fun findIntersectPoint(\n        a: Double,\n        b: Double,\n        c: Double,\n        d: Double,\n        e: Double,\n        f: Double\n    ): PointF? {\n        val D: Double = a * e - b * d\n        val Dx: Double = c * e - b * f\n        val Dy: Double = a * f - c * d\n        return when (D) {\n            0.0 if Dx == 0.0 -> {\n                PointF(Float.MAX_VALUE, Float.MAX_VALUE)\n            }\n\n            0.0 -> {\n                null\n            }\n\n            else -> {\n                PointF((Dx / D).toFloat(), (Dy / D).toFloat())\n            }\n        }\n    }\n\n    /**\n     * Find bisector of angle <BAC @param A point @param B point @param C point @return the Coefficients of bisector></BAC>\n     */\n    fun findBisector(A: PointF, B: PointF, C: PointF): DoubleArray {\n        val ab = getCoefficients(A, B)\n        val ac = getCoefficients(A, C)\n        val sqrt1 = sqrt(ab[0] * ab[0] + ab[1] * ab[1])\n        val sqrt2 = sqrt(ac[0] * ac[0] + ac[1] * ac[1])\n        val a1 = ab[0] / sqrt1 + ac[0] / sqrt2\n        val b1 = ab[1] / sqrt1 + ac[1] / sqrt2\n        val c1 = ab[2] / sqrt1 + ac[2] / sqrt2\n\n        val a2 = ab[0] / sqrt1 - ac[0] / sqrt2\n        val b2 = ab[1] / sqrt1 - ac[1] / sqrt2\n        val c2 = ab[2] / sqrt1 - ac[2] / sqrt2\n\n        val fB = a1 * B.x + b1 * B.y + c1\n        val fC = a1 * C.x + b1 * C.y + c1\n        return if (fB * fC > Double.MIN_VALUE) {\n            doubleArrayOf(a2, b2, c2)\n        } else {\n            doubleArrayOf(a1, b1, c1)\n        }\n    }\n\n    fun getCoefficients(A: PointF, B: PointF): DoubleArray {\n        val a = (B.y - A.y).toDouble()\n        val b = (A.x - B.x).toDouble()\n        val c = (B.x * A.y - A.x * B.y).toDouble()\n        return doubleArrayOf(a, b, c)\n    }\n\n    fun findMiddlePoint(A: PointF, B: PointF, d: Float): Array<PointF> {\n        val result0: PointF\n        val result1: PointF\n        val dx = B.x - A.x\n        val dy = B.y - A.y\n        val sx = (B.x + A.x) / 2.0f\n        val sy = (B.y + A.y) / 2.0f\n        if (dx == 0f) {\n            result0 = PointF(A.x + d, sy)\n            result1 = PointF(A.x - d, sy)\n        } else if (dy == 0f) {\n            result0 = PointF(sx, A.y + d)\n            result1 = PointF(sx, A.y - d)\n        } else {\n            val deltaY = (d / sqrt((1 + (dy * dy) / (dx * dx)).toDouble())).toFloat()\n            result0 = PointF(sx - dy / dx * deltaY, sy + deltaY)\n            result1 = PointF(sx + dy / dx * deltaY, sy - deltaY)\n        }\n\n        return arrayOf(result0, result1)\n    }\n\n    fun CCW(p: PointF, q: PointF, r: PointF): Boolean {\n        val `val` =\n            (q.y.toInt() - p.y.toInt()) * (r.x.toInt() - q.x.toInt()) - (q.x.toInt() - p.x.toInt()) * (r.y.toInt() - q.y.toInt())\n        return `val` < 0\n    }\n\n    /**\n     * Implement Jarvis Algorithm. Jarvis algorithm or the gift wrapping algorithm is an algorithm for computing the convex hull of a given set of points.\n     * \n     * @param points points\n     * @return the convex hull of a given set of points\n     */\n    fun jarvis(points: List<PointF>): ArrayList<PointF> {\n        val result = ArrayList<PointF>()\n        val n = points.size\n        /* if less than 3 points return **/\n        if (n < 3) {\n            result.addAll(points)\n            return result\n        }\n\n        val next = IntArray(n)\n        Arrays.fill(next, -1)\n\n        /* find the leftmost point **/\n        var leftMost = 0\n        for (i in 1..<n) if ((points[i].x).toInt() < (points[leftMost].x).toInt()) leftMost =\n            i\n        var p = leftMost\n        var q: Int\n        /* iterate till p becomes leftMost **/\n        do {\n            /* wrapping **/\n            q = (p + 1) % n\n            for (i in 0..<n) if (CCW(points[p], points[i], points[q])) q = i\n\n            next[p] = q\n            p = q\n        } while (p != leftMost)\n\n        for (i in next.indices) if (next[i] != -1) result.add(points[i])\n        return result\n    }\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/utils/Handle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.utils\n\nimport android.graphics.PointF\nimport kotlin.math.atan2\n\ninternal interface Handle {\n    fun getAngle(): Float\n    fun draggablePoint(manager: ParamsManager): PointF\n    fun tryDrag(point: PointF, manager: ParamsManager): PointF?\n\n    companion object {\n        fun horizontal(\n            yProvider: (values: FloatArray) -> Float,\n            managedParam: ParamT\n        ): Handle = XHandle(\n            yProvider = yProvider,\n            managedParam = managedParam\n        )\n\n        fun vertical(\n            xProvider: (values: FloatArray) -> Float,\n            managedParam: ParamT\n        ): Handle = YHandle(\n            xProvider = xProvider,\n            managedParam = managedParam\n        )\n    }\n}\n\nprivate abstract class LinearHandle(\n    private val managedParam: ParamT,\n    private val direction: PointF\n) : Handle {\n    override fun getAngle(): Float =\n        Math.toDegrees(atan2(direction.y, direction.x).toDouble()).toFloat()\n\n    protected abstract fun computeDraggablePoint(values: FloatArray): PointF\n    protected abstract fun pointToValue(point: PointF): Float\n\n    override fun draggablePoint(manager: ParamsManager): PointF =\n        computeDraggablePoint(manager.valuesRef())\n\n    override fun tryDrag(point: PointF, manager: ParamsManager): PointF? {\n        val values = manager.valuesRef()\n        val initialPoint = computeDraggablePoint(values)\n\n        val dx = point.x - initialPoint.x\n        val dy = point.y - initialPoint.y\n\n        val norm = direction.x * dx + direction.y * dy\n        val clippedPoint = PointF(\n            initialPoint.x + direction.x * norm,\n            initialPoint.y + direction.y * norm\n        )\n\n        val newValue = pointToValue(clippedPoint)\n\n        return try {\n            manager.updateParams(listOf(managedParam), floatArrayOf(newValue))\n            clippedPoint\n        } catch (e: ParamsManager.InvalidValues) {\n            e.printStackTrace()\n            null\n        }\n    }\n}\n\nprivate class XHandle(\n    private val yProvider: (values: FloatArray) -> Float,\n    private val managedParam: ParamT\n) : LinearHandle(managedParam, PointF(1f, 0f)) {\n    override fun computeDraggablePoint(values: FloatArray): PointF =\n        PointF(values[managedParam], yProvider(values))\n\n    override fun pointToValue(point: PointF): Float = point.x\n}\n\nprivate class YHandle(\n    private val xProvider: (values: FloatArray) -> Float,\n    private val managedParam: ParamT\n) : LinearHandle(managedParam, PointF(0f, 1f)) {\n    override fun computeDraggablePoint(values: FloatArray): PointF =\n        PointF(xProvider(values), values[managedParam])\n\n    override fun pointToValue(point: PointF): Float = point.y\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/utils/ImageDecoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.utils\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport coil3.imageLoader\nimport coil3.memory.MemoryCache\nimport coil3.request.ImageRequest\nimport coil3.request.allowHardware\nimport coil3.toBitmap\nimport com.t8rin.collages.public.CollageConstants.requestMapper\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\n\ninternal object ImageDecoder {\n    var SAMPLER_SIZE = 1536\n\n    suspend fun decodeFileToBitmap(\n        context: Context,\n        pathName: Uri\n    ): Bitmap? = withContext(Dispatchers.IO) {\n        val stringKey = pathName.toString() + SAMPLER_SIZE + \"ImageDecoder\"\n        val key = MemoryCache.Key(stringKey)\n\n        context.imageLoader.memoryCache?.get(key)?.image?.toBitmap() ?: context.imageLoader.execute(\n            ImageRequest.Builder(context)\n                .allowHardware(false)\n                .diskCacheKey(stringKey)\n                .memoryCacheKey(key)\n                .data(pathName)\n                .size(SAMPLER_SIZE)\n                .run(requestMapper)\n                .build()\n        ).image?.toBitmap()?.apply {\n            if (config != Bitmap.Config.ARGB_8888) {\n                setConfig(Bitmap.Config.ARGB_8888)\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/utils/ParamsManager.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.utils\n\nimport android.os.Bundle\nimport com.t8rin.collages.view.PhotoItem\n\ntypealias ParamT = Int\n\ninternal typealias ItemUpdate = (photoItem: PhotoItem, values: FloatArray) -> Unit\n\ninternal class ParamsManager(\n    private val values: FloatArray,\n    private val itemUpdateFunctions: List<ItemUpdate?>,\n    private val itemHandles: List<List<Handle>>,\n    private val itemsByIndex: List<PhotoItem?>,\n    private val paramToDependentItems: Array<IntArray>\n) {\n    class InvalidValues : RuntimeException()\n\n    companion object {\n        const val minSize: Float = 0.05f\n    }\n\n    var onItemUpdated: (Int) -> Unit = {}\n\n    fun getHandles(itemIndex: Int): List<Handle> =\n        if (itemIndex in itemHandles.indices) itemHandles[itemIndex] else emptyList()\n\n    fun snapshotValues(): FloatArray = values.copyOf()\n\n    // Only for handles registered with this manager\n    internal fun valuesRef(): FloatArray = values\n\n    fun updateParams(params: List<ParamT>, newValues: FloatArray, notify: Boolean = true) {\n        val previous = FloatArray(params.size) { i -> values[params[i]] }\n        try {\n            for (i in params.indices) {\n                values[params[i]] = newValues[i]\n            }\n\n            val affected: MutableSet<Int> = mutableSetOf()\n            for (param in params) {\n                val arr =\n                    if (param in paramToDependentItems.indices) paramToDependentItems[param] else intArrayOf()\n                for (item in arr) affected.add(item)\n            }\n            for (itemIndex in affected) {\n                val photoItem =\n                    if (itemIndex in itemsByIndex.indices) itemsByIndex[itemIndex] else null\n                val update =\n                    if (itemIndex in itemUpdateFunctions.indices) itemUpdateFunctions[itemIndex] else null\n                if (photoItem != null && update != null) update(photoItem, values)\n            }\n        } catch (e: InvalidValues) {\n            //rollback\n            updateParams(params, previous, false)\n            throw e\n        }\n\n        if (!notify) return\n\n        val notified: MutableSet<Int> = mutableSetOf()\n        for (param in params) {\n            val arr =\n                if (param in paramToDependentItems.indices) paramToDependentItems[param] else intArrayOf()\n            for (item in arr) if (notified.add(item)) onItemUpdated(item)\n        }\n    }\n\n    fun saveInstanceState(outState: Bundle) {\n        outState.putFloatArray(\"collage_params_values\", values.copyOf())\n    }\n\n    fun restoreInstanceState(savedInstanceState: Bundle) {\n        val saved = savedInstanceState.getFloatArray(\"collage_params_values\") ?: return\n        val count = minOf(saved.size, values.size)\n        if (count <= 0) return\n        val indices = (0 until count).toList()\n        val newValues = FloatArray(count) { i -> saved[i] }\n        updateParams(indices, newValues, notify = false)\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/utils/ParamsManagerBuilder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.utils\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.t8rin.collages.view.PhotoItem\n\ninternal class ParamsManagerBuilder {\n    private companion object {\n        const val MIN_DIMENSION_TOLERANCE: Float = 1e-4f\n    }\n\n    private val paramValues: MutableList<Float> = mutableListOf()\n    private val items: MutableList<PhotoItem> = mutableListOf()\n    private val itemUpdates: MutableMap<Int, ItemUpdate> = mutableMapOf()\n    private val itemHandles: MutableMap<Int, List<Handle>> = mutableMapOf()\n    private val paramToItems: MutableMap<Int, MutableSet<Int>> = mutableMapOf()\n\n    fun param(initial: Float): ParamT {\n        paramValues.add(initial)\n        return paramValues.lastIndex\n    }\n\n    fun addBoxedItem(\n        photoItem: PhotoItem? = null,\n        xParams: List<ParamT> = emptyList(),\n        yParams: List<ParamT> = emptyList(),\n        boxParams: (FloatArray) -> RectF,\n        action: (PhotoItem, FloatArray, RectF) -> Unit = { _, _, _ -> }\n    ): ParamsManagerBuilder {\n        val photoItem = photoItem ?: PhotoItem()\n        if (photoItem.pointList.isEmpty()) {\n            photoItem.pointList.add(PointF(0f, 0f))\n            photoItem.pointList.add(PointF(1f, 0f))\n            photoItem.pointList.add(PointF(1f, 1f))\n            photoItem.pointList.add(PointF(0f, 1f))\n        }\n\n        val handles = mutableListOf<Handle>()\n\n        for (xParam in xParams) {\n            handles.add(\n                Handle.horizontal(\n                    yProvider = {\n                        boxParams(it).run { (bottom + top) / 2f }\n                    },\n                    managedParam = xParam\n                )\n            )\n        }\n        for (yParam in yParams) {\n            handles.add(\n                Handle.vertical(\n                    xProvider = {\n                        boxParams(it).run { (right + left) / 2f }\n                    },\n                    managedParam = yParam\n                )\n            )\n        }\n\n        return add(\n            photoItem = photoItem,\n            params = xParams + yParams,\n            listener = { p, vs ->\n                val box = boxParams(vs)\n                if (box.left < 0) throw ParamsManager.InvalidValues()\n                if (box.top < 0) throw ParamsManager.InvalidValues()\n                if (box.right > 1f) throw ParamsManager.InvalidValues()\n                if (box.bottom > 1f) throw ParamsManager.InvalidValues()\n                if (box.right - box.left + MIN_DIMENSION_TOLERANCE < ParamsManager.minSize) {\n                    throw ParamsManager.InvalidValues()\n                }\n                if (box.bottom - box.top + MIN_DIMENSION_TOLERANCE < ParamsManager.minSize) {\n                    throw ParamsManager.InvalidValues()\n                }\n                p.bound.set(box)\n                action(p, vs, box)\n            },\n            handles = handles\n        )\n    }\n\n    fun add(\n        photoItem: PhotoItem,\n        params: List<ParamT> = emptyList(),\n        listener: ItemUpdate = { _, _ -> },\n        handles: List<Handle> = emptyList()\n    ): ParamsManagerBuilder {\n        photoItem.index = items.size\n        items.add(photoItem)\n        itemUpdates[photoItem.index] = listener\n        itemHandles[photoItem.index] = handles\n        for (p in params) paramToItems.getOrPut(p) { mutableSetOf() }.add(photoItem.index)\n        return this\n    }\n\n    fun build(): Pair<ParamsManager, List<PhotoItem>> {\n        val maxItemIndex = (items.maxOfOrNull { it.index } ?: -1) + 1\n        val valuesArray = paramValues.toFloatArray()\n        val itemUpdateArray = ArrayList<ItemUpdate?>(maxItemIndex).apply {\n            repeat(maxItemIndex) { add(null) }\n            for ((i, upd) in itemUpdates) if (i in 0 until maxItemIndex) this[i] = upd\n        }\n        val itemHandlesArray = ArrayList<List<Handle>>(maxItemIndex).apply {\n            repeat(maxItemIndex) { add(emptyList()) }\n            for ((i, hs) in itemHandles) if (i in 0 until maxItemIndex) this[i] = hs\n        }\n        val itemsByIndex = ArrayList<PhotoItem?>(maxItemIndex).apply {\n            repeat(maxItemIndex) { add(null) }\n            for (it in items) if (it.index in 0 until maxItemIndex) this[it.index] = it\n        }\n        val dependents: Array<IntArray> = Array(paramValues.size) { intArrayOf() }\n        for ((p, set) in paramToItems) {\n            dependents[p] = set.sorted().toIntArray()\n        }\n\n        val manager = ParamsManager(\n            values = valuesArray,\n            itemUpdateFunctions = itemUpdateArray,\n            itemHandles = itemHandlesArray,\n            itemsByIndex = itemsByIndex,\n            paramToDependentItems = dependents\n        )\n\n        val values = manager.snapshotValues()\n\n        // Apply initial updates\n        for (photoItem in items) {\n            val update = itemUpdateArray.getOrNull(photoItem.index)\n            if (update != null) update(photoItem, values)\n        }\n\n        return manager to items.toList()\n    }\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/utils/PreviewCollageGeneration.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.utils\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.horizontalScroll\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.systemBarsPadding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.keepScreenOn\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.dp\nimport androidx.core.graphics.applyCanvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.scale\nimport androidx.core.net.toUri\nimport com.t8rin.collages.Collage\nimport com.t8rin.collages.CollageType\nimport com.t8rin.collages.model.CollageLayout\nimport com.t8rin.collages.utils.CollageLayoutFactory.COLLAGE_MAP\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport java.io.File\nimport kotlin.math.pow\nimport kotlin.math.sqrt\n\n@Composable\nfun PreviewCollageGeneration(\n    startFrom: Int = 0\n) {\n    fun Bitmap.replaceColor(\n        fromColor: Color,\n        targetColor: Color,\n        tolerance: Float\n    ): Bitmap {\n        fun Color.distanceFrom(color: Color): Float {\n            return sqrt(\n                (red - color.red).pow(2) + (green - color.green).pow(2) + (blue - color.blue).pow(\n                    2\n                )\n            )\n        }\n\n        val width = width\n        val height = height\n        val pixels = IntArray(width * height)\n        getPixels(pixels, 0, width, 0, 0, width, height)\n        for (x in pixels.indices) {\n            pixels[x] = if (Color(pixels[x]).distanceFrom(fromColor) <= tolerance) {\n                targetColor.toArgb()\n            } else pixels[x]\n        }\n        val result = createBitmap(width, height)\n        result.setPixels(pixels, 0, width, 0, 0, width, height)\n        return result\n    }\n\n    var allFrames: List<CollageLayout> by remember {\n        mutableStateOf(emptyList())\n    }\n    val context = LocalContext.current\n\n    LaunchedEffect(context) {\n        allFrames =\n            COLLAGE_MAP.values.map { it.invoke() }.filter { it.photoItemList.size >= startFrom }\n    }\n\n    var previewImageUri by rememberSaveable {\n        mutableStateOf<Uri?>(null)\n    }\n\n    LaunchedEffect(previewImageUri) {\n        if (previewImageUri == null) {\n            val file = File(context.cacheDir, \"tmp.png\")\n\n            file.outputStream().use {\n                createBitmap(200, 200).applyCanvas {\n                    drawColor(Color.Black.toArgb())\n                }.compress(Bitmap.CompressFormat.PNG, 100, it)\n            }\n\n            previewImageUri = file.toUri()\n        }\n    }\n\n    val scope = rememberCoroutineScope {\n        Dispatchers.IO\n    }\n\n    val dir = remember {\n        File(context.cacheDir, \"frames\").apply {\n            deleteRecursively()\n            mkdirs()\n        }\n    }\n\n    if (previewImageUri != null) {\n        Row(\n            modifier = Modifier\n                .keepScreenOn()\n                .horizontalScroll(rememberScrollState())\n                .padding(vertical = 16.dp)\n                .systemBarsPadding()\n        ) {\n            val data = remember(allFrames) {\n                allFrames.groupBy { it.photoItemList.size }.toList().sortedBy { it.first }\n            }\n            data.forEachIndexed { index, (count, templates) ->\n                Text(\n                    count.toString(),\n                    color = Color.White,\n                    modifier = Modifier.background(Color.Black)\n                )\n                templates.forEach { template ->\n                    val (_, title, _, photoItemList) = template\n                    val density = LocalDensity.current\n                    val spacing = with(density) {\n                        1.5.dp.toPx()\n                    }\n\n                    var trigger by remember {\n                        mutableStateOf(false)\n                    }\n\n                    LaunchedEffect(Unit) {\n                        delay(500 + 10L * index)\n                        trigger = true\n                    }\n\n                    Collage(\n                        images = photoItemList.mapNotNull { previewImageUri },\n                        modifier = Modifier.size(64.dp),\n                        spacing = spacing,\n                        cornerRadius = 0f,\n                        onCollageCreated = { image ->\n                            scope.launch {\n                                val file = File(dir, \"$title.png\")\n\n                                file.createNewFile()\n\n                                file.outputStream().use {\n                                    image.scale(525, 525, false).replaceColor(\n                                        fromColor = Color.Black,\n                                        targetColor = Color.Transparent,\n                                        tolerance = 0.1f\n                                    ).compress(Bitmap.CompressFormat.PNG, 100, it)\n                                }\n                                println(\"DONE: $title\")\n                            }\n                        },\n                        outputScaleRatio = 10f,\n                        collageCreationTrigger = trigger,\n                        collageType = CollageType(\n                            layout = template,\n                            index = null\n                        ),\n                        userInteractionEnabled = false\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/view/FrameImageView.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.view\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.graphics.Matrix\nimport android.graphics.Paint\nimport android.graphics.Path\nimport android.graphics.PointF\nimport android.graphics.PorterDuff\nimport android.graphics.PorterDuffXfermode\nimport android.graphics.Rect\nimport android.graphics.RectF\nimport android.os.Bundle\nimport android.view.GestureDetector\nimport android.view.MotionEvent\nimport android.widget.RelativeLayout\nimport androidx.appcompat.widget.AppCompatImageView\nimport androidx.core.graphics.withClip\nimport androidx.core.graphics.withSave\nimport androidx.core.net.toUri\nimport com.t8rin.collages.utils.GeometryUtils\nimport com.t8rin.collages.utils.ImageDecoder\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport kotlin.math.abs\nimport kotlin.math.min\n\n@SuppressLint(\"ViewConstructor\")\ninternal class FrameImageView(\n    private val context: Context,\n    val photoItem: PhotoItem\n) : AppCompatImageView(context) {\n\n    private val mGestureDetector: GestureDetector = GestureDetector(\n        context,\n        object : GestureDetector.SimpleOnGestureListener() {\n            override fun onLongPress(e: MotionEvent) {\n                if (mOnImageClickListener != null) {\n                    mOnImageClickListener!!.onLongClickImage(this@FrameImageView)\n                }\n            }\n\n            override fun onDoubleTap(e: MotionEvent): Boolean {\n                if (mOnImageClickListener != null) {\n                    mOnImageClickListener!!.onDoubleClickImage(this@FrameImageView)\n                }\n                return true\n            }\n\n            override fun onSingleTapUp(e: MotionEvent): Boolean {\n                if (mOnImageClickListener != null) {\n                    mOnImageClickListener!!.onSingleTapImage(this@FrameImageView)\n                }\n                return super.onSingleTapUp(e)\n            }\n        }\n    )\n    private var mTouchHandler: MultiTouchHandler? = null\n    var image: Bitmap? = null\n    private val mPaint: Paint = Paint()\n    private val mImageMatrix: Matrix = Matrix()\n    private var viewWidth: Float = 0.toFloat()\n    private var viewHeight: Float = 0.toFloat()\n    private var mOnImageClickListener: OnImageClickListener? = null\n    private var mOriginalLayoutParams: RelativeLayout.LayoutParams? = null\n    private var mEnableTouch = true\n    private var corner = 0f\n    private var space = 0f\n    private val mPath = Path()\n    private val mBackgroundPath = Path()\n    private val mPolygon = ArrayList<PointF>()\n    private val mPathRect = Rect(0, 0, 0, 0)\n    private var mSelected = true\n    private val mConvertedPoints = ArrayList<PointF>()\n\n    private var mBackgroundColor = Color.WHITE\n\n    //Clear area\n    private val mClearPath = Path()\n    private val mConvertedClearPoints = ArrayList<PointF>()\n\n    // If true, user allowed empty space via gestures; don't auto-zoom it away on frame updates\n    private var userAllowedEmptySpace: Boolean = false\n\n    // Feature flags\n    private var rotationEnabled: Boolean = true\n    private var snapToBordersEnabled: Boolean = false\n    private var imageLoadJob: Job? = null\n    private var imageLoadToken: String? = null\n\n    fun setRotationEnabled(enabled: Boolean) {\n        rotationEnabled = enabled\n        mTouchHandler?.setEnableRotation(enabled)\n    }\n\n    fun setSnapToBordersEnabled(enabled: Boolean) {\n        snapToBordersEnabled = enabled\n        if (enabled) {\n            // Snap immediately\n            snapToBorders()\n        }\n    }\n\n    var originalLayoutParams: RelativeLayout.LayoutParams\n        get() {\n            if (mOriginalLayoutParams != null) {\n                val params = RelativeLayout.LayoutParams(\n                    mOriginalLayoutParams!!.width,\n                    mOriginalLayoutParams!!.height\n                )\n                params.leftMargin = mOriginalLayoutParams!!.leftMargin\n                params.topMargin = mOriginalLayoutParams!!.topMargin\n                return params\n            } else {\n                return layoutParams as RelativeLayout.LayoutParams\n            }\n        }\n        set(originalLayoutParams) {\n            mOriginalLayoutParams =\n                RelativeLayout.LayoutParams(originalLayoutParams.width, originalLayoutParams.height)\n            mOriginalLayoutParams!!.leftMargin = originalLayoutParams.leftMargin\n            mOriginalLayoutParams!!.topMargin = originalLayoutParams.topMargin\n        }\n\n    interface OnImageClickListener {\n        fun onLongClickImage(view: FrameImageView)\n\n        fun onDoubleClickImage(view: FrameImageView)\n\n        fun onSingleTapImage(view: FrameImageView)\n    }\n\n    private var viewState: Bundle = Bundle.EMPTY\n\n    init {\n        reloadImageFromPhotoItem()\n\n        mPaint.isFilterBitmap = true\n        mPaint.isAntiAlias = true\n        scaleType = ScaleType.MATRIX\n        setLayerType(LAYER_TYPE_SOFTWARE, mPaint)\n    }\n\n    fun saveInstanceState(outState: Bundle) {\n        val index = photoItem.index\n        val values = FloatArray(9)\n        mImageMatrix.getValues(values)\n        outState.putFloatArray(\"mImageMatrix_$index\", values)\n        outState.putFloat(\"mViewWidth_$index\", viewWidth)\n        outState.putFloat(\"mViewHeight_$index\", viewHeight)\n        outState.putFloat(\"mCorner_$index\", corner)\n        outState.putFloat(\"mSpace_$index\", space)\n        outState.putInt(\"mBackgroundColor_$index\", mBackgroundColor)\n    }\n\n    /**\n     * Called after init() function\n     *\n     * @param savedInstanceState\n     */\n    fun restoreInstanceState(savedInstanceState: Bundle) {\n        viewState = savedInstanceState\n        val index = photoItem.index\n        val values = savedInstanceState.getFloatArray(\"mImageMatrix_$index\")\n        if (values != null) {\n            mImageMatrix.setValues(values)\n        }\n        viewWidth = savedInstanceState.getFloat(\"mViewWidth_$index\", 1f)\n        viewHeight = savedInstanceState.getFloat(\"mViewHeight_$index\", 1f)\n        corner = savedInstanceState.getFloat(\"mCorner_$index\", 0f)\n        space = savedInstanceState.getFloat(\"mSpace_$index\", 0f)\n        mBackgroundColor = savedInstanceState.getInt(\"mBackgroundColor_$index\", Color.WHITE)\n        mTouchHandler!!.matrix = mImageMatrix\n        setSpace(space, corner)\n    }\n\n    fun swapImage(view: FrameImageView) {\n        if (image != null && view.image != null) {\n            val temp = view.image\n            view.image = image\n            image = temp\n\n            val tmpPath = view.photoItem.imagePath\n            view.photoItem.imagePath = photoItem.imagePath\n            photoItem.imagePath = tmpPath\n            resetImageMatrix()\n            view.resetImageMatrix()\n        }\n    }\n\n    fun reloadImageFromPhotoItem() {\n        val token = photoItem.imagePath?.toString()?.takeIf { it.isNotEmpty() }\n\n        // Skip if we're already loading the same image\n        if (token == imageLoadToken && imageLoadJob?.isActive == true) return\n\n        imageLoadJob?.cancel()\n        imageLoadToken = token\n\n        imageLoadJob = CoroutineScope(Dispatchers.Main.immediate).launch {\n            // Decode on IO if we have a token/uri; null otherwise\n            val bmp = withContext(Dispatchers.IO) {\n                token?.let { t ->\n                    runCatching {\n                        ImageDecoder.decodeFileToBitmap(\n                            context = context,\n                            pathName = t.toUri()\n                        )\n                    }.getOrNull()\n                }\n            }\n\n            // If another reload changed the token while we were decoding, bail out\n            if (token != imageLoadToken) return@launch\n\n            if (bmp == null) {\n                image = null\n                invalidate()\n            } else {\n                image = bmp\n                resetImageMatrix()\n                if (viewState != Bundle.EMPTY) {\n                    restoreInstanceState(viewState)\n                    viewState = Bundle.EMPTY\n                }\n            }\n\n            // Clear the job if we're still the latest load for this token\n            if (token == imageLoadToken) imageLoadJob = null\n        }\n    }\n\n    fun setOnImageClickListener(onImageClickListener: OnImageClickListener) {\n        mOnImageClickListener = onImageClickListener\n    }\n\n    override fun setBackgroundColor(backgroundColor: Int) {\n        mBackgroundColor = backgroundColor\n        invalidate()\n    }\n\n    override fun getImageMatrix(): Matrix {\n        return mImageMatrix\n    }\n\n    @JvmOverloads\n    fun init(\n        viewWidth: Float,\n        viewHeight: Float,\n        space: Float = 0f,\n        corner: Float = 0f\n    ) {\n        this.viewWidth = viewWidth\n        this.viewHeight = viewHeight\n        this.space = space\n        this.corner = corner\n\n        if (image != null) {\n            mImageMatrix.set(\n                createMatrixToDrawImageInCenterView(\n                    viewWidth = viewWidth,\n                    viewHeight = viewHeight,\n                    imageWidth = image!!.width.toFloat(),\n                    imageHeight = image!!.height.toFloat()\n                )\n            )\n        }\n\n        mTouchHandler = MultiTouchHandler()\n        mTouchHandler!!.matrix = mImageMatrix\n        mTouchHandler!!.setEnableRotation(rotationEnabled)\n\n        setSpace(this.space, this.corner)\n    }\n\n    fun setSpace(space: Float, corner: Float) {\n        this.space = space\n        this.corner = corner\n        setSpace(\n            viewWidth, viewHeight, photoItem,\n            mConvertedPoints, mConvertedClearPoints,\n            mPath, mClearPath, mBackgroundPath, mPolygon, mPathRect, space, corner\n        )\n        invalidate()\n    }\n\n    fun updateFrame(viewWidth: Float, viewHeight: Float) {\n        // --- Save previous state we need once\n        val oldW = this.viewWidth\n        val oldH = this.viewHeight\n\n        // Preserve center point\n        mImageMatrix.postTranslate((viewWidth - oldW) * 0.5f, (viewHeight - oldH) * 0.5f)\n\n        if (oldW > 0 && oldH > 0 && abs(viewWidth / oldW - viewHeight / oldH) < 0.00001f) {\n            // Simple center rescale\n\n            val scale = (viewWidth / oldW + viewHeight / oldH) / 2\n            mImageMatrix.postScale(scale, scale, viewWidth / 2, viewHeight / 2)\n        } else {\n            if (image != null) {\n                val hasEmptyAfter = hasEmptySpace(mImageMatrix, viewWidth, viewHeight)\n\n                // If empty space disappeared naturally due to frame change, clear the pin\n                if (!hasEmptyAfter) {\n                    userAllowedEmptySpace = false\n                }\n\n                // If empty space would appear and the user didn't pin it, zoom just enough to cover.\n                if (hasEmptyAfter && !userAllowedEmptySpace) {\n                    snapToBorders(onlyMatrixUpdate = true)\n                }\n            }\n        }\n\n        mTouchHandler?.matrix = mImageMatrix\n\n        // --- Apply new bounds and rebuild geometry\n        this.viewWidth = viewWidth\n        this.viewHeight = viewHeight\n\n        mConvertedPoints.clear()\n        mConvertedClearPoints.clear()\n        mPolygon.clear()\n        mPath.reset()\n        mClearPath.reset()\n        mBackgroundPath.reset()\n\n        // Invalidates the view\n        setSpace(this.space, this.corner)\n    }\n\n    private fun resetImageMatrix() {\n        if (image != null) {\n            mImageMatrix.set(\n                createMatrixToDrawImageInCenterView(\n                    viewWidth = viewWidth,\n                    viewHeight = viewHeight,\n                    imageWidth = image!!.width.toFloat(),\n                    imageHeight = image!!.height.toFloat()\n                )\n            )\n        }\n        mTouchHandler?.matrix = mImageMatrix\n        invalidate()\n    }\n\n    fun isSelected(x: Float, y: Float): Boolean {\n        return GeometryUtils.contains(mPolygon, PointF(x, y))\n    }\n\n    override fun onDraw(canvas: Canvas) {\n        super.onDraw(canvas)\n        drawImage(\n            canvas, mPath, mPaint, mPathRect, image, mImageMatrix,\n            width.toFloat(), height.toFloat(), mBackgroundColor, mBackgroundPath,\n            mClearPath, mPolygon\n        )\n    }\n\n    fun drawOutputImage(canvas: Canvas, outputScale: Float) {\n        val viewWidth = this.viewWidth * outputScale\n        val viewHeight = this.viewHeight * outputScale\n        val path = Path()\n        val clearPath = Path()\n        val backgroundPath = Path()\n        val pathRect = Rect()\n        val polygon = ArrayList<PointF>()\n        setSpace(\n            viewWidth, viewHeight, photoItem, ArrayList(),\n            ArrayList(), path, clearPath, backgroundPath, polygon, pathRect,\n            space * outputScale, corner * outputScale\n        )\n        val exportMatrix = Matrix(mImageMatrix).apply { postScale(outputScale, outputScale) }\n        drawImage(\n            canvas, path, mPaint, pathRect, image, exportMatrix,\n            viewWidth, viewHeight, mBackgroundColor, backgroundPath, clearPath, polygon\n        )\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    override fun onTouchEvent(event: MotionEvent): Boolean {\n        if (!mEnableTouch) {\n            return super.onTouchEvent(event)\n        } else {\n            if (event.action == MotionEvent.ACTION_DOWN) {\n                mSelected = GeometryUtils.contains(mPolygon, PointF(event.x, event.y))\n            }\n\n            if (mSelected) {\n                if (event.action == MotionEvent.ACTION_UP) {\n                    mSelected = false\n                }\n\n                mGestureDetector.onTouchEvent(event)\n                if (mTouchHandler != null && image != null && !image!!.isRecycled) {\n                    mTouchHandler!!.touch(event)\n                    mImageMatrix.set(mTouchHandler!!.matrix)\n\n                    if (event.action == MotionEvent.ACTION_UP) {\n                        if (snapToBordersEnabled) {\n                            snapToBorders()\n                        }\n                        // Update weather user allowed empty space based on current transform\n                        userAllowedEmptySpace = hasEmptySpace(mImageMatrix, viewWidth, viewHeight)\n                    }\n                    invalidate()\n                }\n                return true\n            } else {\n                return super.onTouchEvent(event)\n            }\n        }\n    }\n\n    private fun snapToBorders(onlyMatrixUpdate: Boolean = false) {\n        val img = image ?: return\n        if (viewWidth <= 0f || viewHeight <= 0f) return\n\n        fun mappedRect(): RectF =\n            RectF(0f, 0f, img.width.toFloat(), img.height.toFloat()).also {\n                mImageMatrix.mapRect(it)\n            }\n\n        var rect = mappedRect()\n        var changed = false\n\n        // 1) Minimal translation to reduce single-edge gaps (always apply if it reduces gap)\n        var dx = 0f\n        var dy = 0f\n        val leftGap = rect.left - space\n        val rightGap = (viewWidth - space) - rect.right\n        val topGap = rect.top - space\n        val bottomGap = (viewHeight - space) - rect.bottom\n\n        val leftNeeds = leftGap > 0f\n        val rightNeeds = rightGap > 0f\n        if (leftNeeds.xor(rightNeeds)) {\n            dx = if (leftNeeds) -leftGap else rightGap\n        }\n\n        val topNeeds = topGap > 0f\n        val bottomNeeds = bottomGap > 0f\n        if (topNeeds.xor(bottomNeeds)) {\n            dy = if (topNeeds) -topGap else bottomGap\n        }\n\n        if (dx != 0f || dy != 0f) {\n            mImageMatrix.postTranslate(dx, dy)\n            rect = mappedRect()\n            changed = true\n        }\n\n        // 2) Minimal uniform scale about view center to cover remaining gaps (capped)\n        val cx = viewWidth * 0.5f\n        val cy = viewHeight * 0.5f\n        var needed = 1f\n        if (rect.left > space) {\n            val denom = (cx - rect.left)\n            if (denom > 0f) needed = kotlin.math.max(needed, (cx - space) / denom)\n        }\n        if (rect.top > space) {\n            val denom = (cy - rect.top)\n            if (denom > 0f) needed = kotlin.math.max(needed, (cy - space) / denom)\n        }\n        if (rect.right < viewWidth - space) {\n            val denom = (rect.right - cx)\n            if (denom > 0f) needed = kotlin.math.max(needed, (cx - space) / denom)\n        }\n        if (rect.bottom < viewHeight - space) {\n            val denom = (rect.bottom - cy)\n            if (denom > 0f) needed = kotlin.math.max(needed, (cy - space) / denom)\n        }\n\n        val maxStep = 4f\n        val scale = min(needed, maxStep)\n        if (scale > 1.0005f) {\n            mImageMatrix.postScale(scale, scale, cx, cy)\n            rect = mappedRect()\n            changed = true\n        }\n\n        // 3) Final clamp to remove any residual tiny gaps\n        var cdx = 0f\n        var cdy = 0f\n        if (rect.left > space) cdx = space - rect.left\n        if (rect.top > space) cdy = space - rect.top\n        if (rect.right < viewWidth - space) cdx = (viewWidth - space) - rect.right\n        if (rect.bottom < viewHeight - space) cdy = (viewHeight - space) - rect.bottom\n        if (cdx != 0f || cdy != 0f) {\n            mImageMatrix.postTranslate(cdx, cdy)\n            changed = true\n        }\n\n        if (onlyMatrixUpdate) return\n\n        if (changed) {\n            mTouchHandler?.matrix = mImageMatrix\n            invalidate()\n        }\n    }\n\n    private fun hasEmptySpace(matrix: Matrix, vw: Float, vh: Float): Boolean {\n        if (image == null || vw <= 0f || vh <= 0f) return false\n        val rect = RectF(0f, 0f, image!!.width.toFloat(), image!!.height.toFloat())\n        matrix.mapRect(rect)\n        // if image rect does not fully cover the view rect, there is empty space\n        return rect.left > space || rect.top > space || rect.right < vw - space || rect.bottom < vh - space\n    }\n\n    companion object {\n        private fun setSpace(\n            viewWidth: Float, viewHeight: Float, photoItem: PhotoItem,\n            convertedPoints: MutableList<PointF>,\n            convertedClearPoints: MutableList<PointF>,\n            path: Path,\n            clearPath: Path,\n            backgroundPath: Path,\n            polygon: MutableList<PointF>,\n            pathRect: Rect,\n            space: Float, corner: Float\n        ) {\n            if (convertedPoints.isEmpty()) {\n                for (p in photoItem.pointList) {\n                    val convertedPoint = PointF(p.x * viewWidth, p.y * viewHeight)\n                    convertedPoints.add(convertedPoint)\n                    if (photoItem.shrinkMap != null) {\n\n                        photoItem.shrinkMap!![convertedPoint] = photoItem.shrinkMap!![p]!!\n\n                    }\n                }\n            }\n\n            if (photoItem.clearAreaPoints != null && photoItem.clearAreaPoints!!.isNotEmpty()) {\n                clearPath.reset()\n                if (convertedClearPoints.isEmpty())\n                    for (p in photoItem.clearAreaPoints!!) {\n                        convertedClearPoints.add(PointF(p.x * viewWidth, p.y * viewHeight))\n                    }\n                GeometryUtils.createPathWithCircleCorner(clearPath, convertedClearPoints, corner)\n            } else if (photoItem.clearPath != null) {\n                clearPath.reset()\n                buildRealClearPath(viewWidth, viewHeight, photoItem, clearPath, corner)\n            }\n\n            if (photoItem.path != null) {\n                buildRealPath(viewWidth, viewHeight, photoItem, path, space, corner)\n                polygon.clear()\n            } else {\n                val shrunkPoints: List<PointF>\n                when (photoItem.shrinkMethod) {\n                    PhotoItem.SHRINK_METHOD_3_3 -> {\n                        val centerPointIdx = findCenterPointIndex(photoItem)\n                        shrunkPoints = GeometryUtils.shrinkPathCollage_3_3(\n                            convertedPoints,\n                            centerPointIdx,\n                            space,\n                            photoItem.bound\n                        )\n                    }\n\n                    PhotoItem.SHRINK_METHOD_USING_MAP if photoItem.shrinkMap != null -> {\n                        shrunkPoints = GeometryUtils.shrinkPathCollageUsingMap(\n                            convertedPoints,\n                            space,\n                            photoItem.shrinkMap!!\n                        )\n                    }\n\n                    PhotoItem.SHRINK_METHOD_COMMON if photoItem.shrinkMap != null -> {\n                        shrunkPoints =\n                            GeometryUtils.commonShrinkPath(\n                                convertedPoints,\n                                space,\n                                photoItem.shrinkMap!!\n                            )\n                    }\n\n                    else -> {\n                        shrunkPoints = if (photoItem.disableShrink) {\n                            GeometryUtils.shrinkPath(convertedPoints, 0f, photoItem.bound)\n                        } else {\n                            GeometryUtils.shrinkPath(convertedPoints, space, photoItem.bound)\n                        }\n                    }\n                }\n                polygon.clear()\n                polygon.addAll(shrunkPoints)\n                GeometryUtils.createPathWithCircleCorner(path, shrunkPoints, corner)\n                if (photoItem.hasBackground) {\n                    backgroundPath.reset()\n                    GeometryUtils.createPathWithCircleCorner(\n                        backgroundPath,\n                        convertedPoints,\n                        corner\n                    )\n                }\n            }\n\n            pathRect.set(0, 0, 0, 0)\n        }\n\n        private fun findCenterPointIndex(photoItem: PhotoItem): Int {\n            var centerPointIdx = 0\n            if (photoItem.bound.left == 0f && photoItem.bound.top == 0f) {\n                var minX = 1f\n                for (idx in photoItem.pointList.indices) {\n                    val p = photoItem.pointList[idx]\n                    if (p.x > 0 && p.x < 1 && p.y > 0 && p.y < 1 && p.x < minX) {\n                        centerPointIdx = idx\n                        minX = p.x\n                    }\n                }\n            } else {\n                var maxX = 0f\n                for (idx in photoItem.pointList.indices) {\n                    val p = photoItem.pointList[idx]\n                    if (p.x > 0 && p.x < 1 && p.y > 0 && p.y < 1 && p.x > maxX) {\n                        centerPointIdx = idx\n                        maxX = p.x\n                    }\n                }\n            }\n\n            return centerPointIdx\n        }\n\n        private fun buildRealPath(\n            viewWidth: Float, viewHeight: Float,\n            photoItem: PhotoItem, outPath: Path,\n            space: Float, corner: Float\n        ) {\n            var newSpace = space\n            if (photoItem.path != null) {\n                val rect = RectF()\n                photoItem.path!!.computeBounds(rect, true)\n                val pathWidthPixels = rect.width()\n                val pathHeightPixels = rect.height()\n                newSpace *= 2\n                outPath.set(photoItem.path!!)\n                val m = Matrix()\n                val ratioX: Float\n                val ratioY: Float\n                if (photoItem.fitBound) {\n                    ratioX =\n                        photoItem.pathScaleRatio * (viewWidth * photoItem.pathRatioBound!!.width() - 2 * newSpace) / pathWidthPixels\n                    ratioY =\n                        photoItem.pathScaleRatio * (viewHeight * photoItem.pathRatioBound!!.height() - 2 * newSpace) / pathHeightPixels\n                } else {\n                    val ratio = min(\n                        photoItem.pathScaleRatio * (viewHeight - 2 * newSpace) / pathHeightPixels,\n                        photoItem.pathScaleRatio * (viewWidth - 2 * newSpace) / pathWidthPixels\n                    )\n                    ratioX = ratio\n                    ratioY = ratio\n                }\n                m.postScale(ratioX, ratioY)\n                outPath.transform(m)\n                val bound = RectF()\n                when (photoItem.cornerMethod) {\n                    PhotoItem.CORNER_METHOD_3_6 -> {\n                        outPath.computeBounds(bound, true)\n                        GeometryUtils.createRegularPolygonPath(\n                            outPath,\n                            min(bound.width(), bound.height()),\n                            6,\n                            corner\n                        )\n                        outPath.computeBounds(bound, true)\n                    }\n\n                    PhotoItem.CORNER_METHOD_3_13 -> {\n                        outPath.computeBounds(bound, true)\n                        GeometryUtils.createRectanglePath(\n                            outPath,\n                            bound.width(),\n                            bound.height(),\n                            corner\n                        )\n                        outPath.computeBounds(bound, true)\n                    }\n\n                    else -> {\n                        outPath.computeBounds(bound, true)\n                    }\n                }\n\n                var x: Float\n                var y: Float\n                if (photoItem.shrinkMethod == PhotoItem.SHRINK_METHOD_3_6 || photoItem.shrinkMethod == PhotoItem.SHRINK_METHOD_3_8) {\n                    x = viewWidth / 2 - bound.width() / 2\n                    y = viewHeight / 2 - bound.height() / 2\n                    m.reset()\n                    m.postTranslate(x, y)\n                    outPath.transform(m)\n                } else {\n                    if (photoItem.pathAlignParentRight) {\n                        x =\n                            photoItem.pathRatioBound!!.right * viewWidth - bound.width() - newSpace / ratioX\n                        y = photoItem.pathRatioBound!!.top * viewHeight + newSpace / ratioY\n                    } else {\n                        x = photoItem.pathRatioBound!!.left * viewWidth + newSpace / ratioX\n                        y = photoItem.pathRatioBound!!.top * viewHeight + newSpace / ratioY\n                    }\n\n                    if (photoItem.pathInCenterHorizontal) {\n                        x = viewWidth / 2.0f - bound.width() / 2.0f\n                    }\n\n                    if (photoItem.pathInCenterVertical) {\n                        y = viewHeight / 2.0f - bound.height() / 2.0f\n                    }\n\n                    m.reset()\n                    m.postTranslate(x, y)\n                    outPath.transform(m)\n                }\n            }\n        }\n\n        private fun buildRealClearPath(\n            viewWidth: Float,\n            viewHeight: Float,\n            photoItem: PhotoItem,\n            clearPath: Path,\n            corner: Float\n        ): Path? {\n            if (photoItem.clearPath != null) {\n                val rect = RectF()\n                photoItem.clearPath!!.computeBounds(rect, true)\n                val clearPathWidthPixels = rect.width()\n                val clearPathHeightPixels = rect.height()\n\n                clearPath.set(photoItem.clearPath!!)\n                val m = Matrix()\n                val ratioX: Float\n                val ratioY: Float\n                if (photoItem.fitBound) {\n                    ratioX =\n                        photoItem.clearPathScaleRatio * viewWidth * photoItem.clearPathRatioBound!!.width() / clearPathWidthPixels\n                    ratioY =\n                        photoItem.clearPathScaleRatio * viewHeight * photoItem.clearPathRatioBound!!.height() / clearPathHeightPixels\n                } else {\n                    val ratio = min(\n                        photoItem.clearPathScaleRatio * viewHeight / clearPathHeightPixels,\n                        photoItem.clearPathScaleRatio * viewWidth / clearPathWidthPixels\n                    )\n                    ratioX = ratio\n                    ratioY = ratio\n                }\n                m.postScale(ratioX, ratioY)\n                clearPath.transform(m)\n                val bound = RectF()\n                when (photoItem.cornerMethod) {\n                    PhotoItem.CORNER_METHOD_3_6 -> {\n                        clearPath.computeBounds(bound, true)\n                        GeometryUtils.createRegularPolygonPath(\n                            clearPath,\n                            min(bound.width(), bound.height()),\n                            6,\n                            corner\n                        )\n                        clearPath.computeBounds(bound, true)\n                    }\n\n                    PhotoItem.CORNER_METHOD_3_13 -> {\n                        clearPath.computeBounds(bound, true)\n                        GeometryUtils.createRectanglePath(\n                            clearPath,\n                            bound.width(),\n                            bound.height(),\n                            corner\n                        )\n                        clearPath.computeBounds(bound, true)\n                    }\n\n                    else -> {\n                        clearPath.computeBounds(bound, true)\n                    }\n                }\n\n                var x: Float\n                var y: Float\n                if (photoItem.shrinkMethod == PhotoItem.SHRINK_METHOD_3_6) {\n                    x = if (photoItem.clearPathRatioBound!!.left > 0) {\n                        viewWidth - bound.width() / 2\n                    } else {\n                        -bound.width() / 2\n                    }\n                    y = viewHeight / 2 - bound.height() / 2\n                } else {\n                    if (photoItem.centerInClearBound) {\n                        x =\n                            photoItem.clearPathRatioBound!!.left * viewWidth + (viewWidth / 2 - bound.width() / 2)\n                        y =\n                            photoItem.clearPathRatioBound!!.top * viewHeight + (viewHeight / 2 - bound.height() / 2)\n                    } else {\n                        x = photoItem.clearPathRatioBound!!.left * viewWidth\n                        y = photoItem.clearPathRatioBound!!.top * viewHeight\n                        if (photoItem.clearPathInCenterHorizontal) {\n                            x = viewWidth / 2.0f - bound.width() / 2.0f\n                        }\n                        if (photoItem.clearPathInCenterVertical) {\n                            y = viewHeight / 2.0f - bound.height() / 2.0f\n                        }\n                    }\n                }\n\n                m.reset()\n                m.postTranslate(x, y)\n                clearPath.transform(m)\n                return clearPath\n            } else {\n                return null\n            }\n        }\n\n        private fun drawImage(\n            canvas: Canvas,\n            path: Path,\n            paint: Paint,\n            pathRect: Rect,\n            image: Bitmap?,\n            imageMatrix: Matrix,\n            viewWidth: Float,\n            viewHeight: Float,\n            color: Int,\n            backgroundPath: Path?,\n            clearPath: Path?,\n            touchPolygon: MutableList<PointF>?\n        ) {\n            if (image != null && !image.isRecycled) {\n                canvas.drawBitmap(image, imageMatrix, paint)\n            }\n            //clip outside\n            if (pathRect.left == pathRect.right) {\n                canvas.withClip(path) {\n                    pathRect.set(clipBounds)\n                }\n            }\n\n            canvas.save()\n            paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)\n            canvas.drawARGB(0x00, 0x00, 0x00, 0x00)\n            paint.color = Color.BLACK\n            paint.style = Paint.Style.FILL\n            canvas.drawRect(0f, 0f, viewWidth, pathRect.top.toFloat(), paint)\n            canvas.drawRect(0f, 0f, pathRect.left.toFloat(), viewHeight, paint)\n            canvas.drawRect(pathRect.right.toFloat(), 0f, viewWidth, viewHeight, paint)\n            canvas.drawRect(0f, pathRect.bottom.toFloat(), viewWidth, viewHeight, paint)\n            paint.xfermode = null\n            canvas.restore()\n            //clip inside\n            canvas.save()\n            paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)\n            canvas.drawARGB(0x00, 0x00, 0x00, 0x00)\n            paint.color = Color.BLACK\n            paint.style = Paint.Style.FILL\n            val currentFillType = path.fillType\n            path.fillType = Path.FillType.INVERSE_WINDING\n            canvas.drawPath(path, paint)\n            paint.xfermode = null\n            canvas.restore()\n            path.fillType = currentFillType\n            //clear area\n            if (clearPath != null) {\n                canvas.withSave {\n                    paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)\n                    drawARGB(0x00, 0x00, 0x00, 0x00)\n                    paint.color = Color.BLACK\n                    paint.style = Paint.Style.FILL\n                    drawPath(clearPath, paint)\n                    paint.xfermode = null\n                }\n            }\n            //draw out side\n            if (backgroundPath != null) {\n                canvas.withSave {\n                    paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)\n                    drawARGB(0x00, 0x00, 0x00, 0x00)\n                    paint.color = color\n                    paint.style = Paint.Style.FILL\n                    drawPath(backgroundPath, paint)\n                    paint.xfermode = null\n                }\n            }\n            //touch polygon\n            if (touchPolygon != null && touchPolygon.isEmpty()) {\n                touchPolygon.add(PointF(pathRect.left.toFloat(), pathRect.top.toFloat()))\n                touchPolygon.add(PointF(pathRect.right.toFloat(), pathRect.top.toFloat()))\n                touchPolygon.add(PointF(pathRect.right.toFloat(), pathRect.bottom.toFloat()))\n                touchPolygon.add(PointF(pathRect.left.toFloat(), pathRect.bottom.toFloat()))\n            }\n        }\n    }\n\n    private fun createMatrixToDrawImageInCenterView(\n        viewWidth: Float,\n        viewHeight: Float,\n        imageWidth: Float,\n        imageHeight: Float\n    ): Matrix {\n        val ratioWidth = viewWidth / imageWidth\n        val ratioHeight = viewHeight / imageHeight\n        val ratio = ratioWidth.coerceAtLeast(ratioHeight)\n        val dx = (viewWidth - imageWidth) / 2.0f\n        val dy = (viewHeight - imageHeight) / 2.0f\n        val result = Matrix()\n        result.postTranslate(dx, dy)\n        result.postScale(ratio, ratio, viewWidth / 2, viewHeight / 2)\n        return result\n    }\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/view/FramePhotoLayout.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.view\n\nimport android.annotation.SuppressLint\nimport android.app.ActivityManager\nimport android.app.ActivityManager.MemoryInfo\nimport android.content.ClipData\nimport android.content.ClipDescription\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.Paint\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport android.graphics.drawable.Drawable\nimport android.graphics.drawable.GradientDrawable\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.view.DragEvent\nimport android.view.MotionEvent\nimport android.widget.RelativeLayout\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.content.getSystemService\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.withTranslation\nimport com.t8rin.collages.utils.Handle\nimport com.t8rin.collages.utils.ImageDecoder\nimport com.t8rin.collages.utils.ParamsManager\nimport kotlin.math.max\nimport androidx.compose.ui.graphics.Color as ComposeColor\n\n@SuppressLint(\"ViewConstructor\")\ninternal class FramePhotoLayout(\n    context: Context,\n    var mPhotoItems: List<PhotoItem>\n) : RelativeLayout(context), FrameImageView.OnImageClickListener {\n\n    private data class FrameMetrics(\n        val leftMargin: Int,\n        val topMargin: Int,\n        val width: Int,\n        val height: Int\n    )\n\n    private fun computeFrameMetrics(bound: RectF): FrameMetrics {\n        val leftMargin = (mViewWidth * bound.left).toInt()\n        val topMargin = (mViewHeight * bound.top).toInt()\n        val frameWidth: Int = if (bound.right == 1f) {\n            mViewWidth - leftMargin\n        } else {\n            (mViewWidth * bound.width() + 0.5f).toInt()\n        }\n\n        val frameHeight: Int = if (bound.bottom == 1f) {\n            mViewHeight - topMargin\n        } else {\n            (mViewHeight * bound.height() + 0.5f).toInt()\n        }\n\n        return FrameMetrics(\n            leftMargin = leftMargin,\n            topMargin = topMargin,\n            width = frameWidth,\n            height = frameHeight\n        )\n    }\n\n    private var mOnDragListener: OnDragListener = OnDragListener { v, event ->\n        if (event.action == DragEvent.ACTION_DROP) {\n            var target: FrameImageView? = v as FrameImageView\n            val selectedView = getSelectedFrameImageView(target!!, event)\n            if (selectedView != null) {\n                target = selectedView\n                val dragged = event.localState as FrameImageView\n                var targetPath: Uri? = target.photoItem.imagePath\n                var draggedPath: Uri? = dragged.photoItem.imagePath\n                if (targetPath == null) targetPath = Uri.EMPTY\n                if (draggedPath == null) draggedPath = Uri.EMPTY\n                if (targetPath != draggedPath) target.swapImage(dragged)\n            }\n        }\n\n        true\n    }\n    private val mItemImageViews: MutableList<FrameImageView> = ArrayList()\n    private var mViewWidth: Int = 0\n    private var mViewHeight: Int = 0\n    private var backgroundColor: ComposeColor = ComposeColor.White\n    private var onItemTapListener: ((index: Int) -> Unit)? = null\n\n    // Handle overlay state\n    private var selectedItemIndex: Int? = null\n    private var activeHandle: Handle? = null\n    private var paramsManager: ParamsManager? = null\n    private var handleDrawable: Drawable? = null\n\n    // Flags propagated from upper layers\n    private var disableRotation: Boolean = false\n    private var enableSnapToBorders: Boolean = false\n\n    private val isNotLargeThan1Gb: Boolean\n        get() = getMemoryInfo().run {\n            totalMem > 0 && totalMem / 1048576.0 <= 1024\n        }\n\n    init {\n        setLayerType(LAYER_TYPE_HARDWARE, null)\n        setWillNotDraw(false)\n        // Enable focus so we can detect focus loss and clear selection\n        isFocusable = true\n        isFocusableInTouchMode = true\n    }\n\n    fun setParamsManager(manager: ParamsManager?) {\n        paramsManager = manager\n        // Update item views whenever params change\n        paramsManager?.onItemUpdated = { itemIndex -> resizeItem(itemIndex) }\n    }\n\n    fun setDisableRotation(disable: Boolean) {\n        disableRotation = disable\n        // Update existing children\n        for (v in mItemImageViews) {\n            v.setRotationEnabled(!disableRotation)\n        }\n    }\n\n    fun setEnableSnapToBorders(enable: Boolean) {\n        enableSnapToBorders = enable\n        // Update existing children\n        for (v in mItemImageViews) {\n            v.setSnapToBordersEnabled(enableSnapToBorders)\n        }\n    }\n\n    private fun getSelectedFrameImageView(\n        target: FrameImageView,\n        event: DragEvent\n    ): FrameImageView? {\n        val dragged = event.localState as FrameImageView\n        val leftMargin = (mViewWidth * target.photoItem.bound.left).toInt()\n        val topMargin = (mViewHeight * target.photoItem.bound.top).toInt()\n        val globalX = leftMargin + event.x\n        val globalY = topMargin + event.y\n        for (idx in mItemImageViews.indices.reversed()) {\n            val view = mItemImageViews[idx]\n            val x = globalX - mViewWidth * view.photoItem.bound.left\n            val y = globalY - mViewHeight * view.photoItem.bound.top\n            if (view.isSelected(x, y)) {\n                return if (view === dragged) {\n                    null\n                } else {\n                    view\n                }\n            }\n        }\n        return null\n    }\n\n    fun saveInstanceState(outState: Bundle) {\n        paramsManager?.saveInstanceState(outState)\n        for (view in mItemImageViews)\n            view.saveInstanceState(outState)\n    }\n\n    fun restoreInstanceState(savedInstanceState: Bundle) {\n        paramsManager?.restoreInstanceState(savedInstanceState)\n        for (view in mItemImageViews)\n            view.restoreInstanceState(savedInstanceState)\n    }\n\n    @JvmOverloads\n    fun build(\n        viewWidth: Int,\n        viewHeight: Int,\n        space: Float = 0f,\n        corner: Float = 0f\n    ) {\n        mItemImageViews.clear()\n        removeAllViews()\n        if (viewWidth < 1 || viewHeight < 1) {\n            return\n        }\n\n        setBackgroundColor(backgroundColor.toArgb())\n\n        //add children views\n        mViewWidth = viewWidth\n        mViewHeight = viewHeight\n        mItemImageViews.clear()\n        //A circle view always is on top\n        if (mPhotoItems.size > 4 || isNotLargeThan1Gb) {\n            ImageDecoder.SAMPLER_SIZE = 1024\n        } else {\n            ImageDecoder.SAMPLER_SIZE = 1600\n        }\n        for (item in mPhotoItems) {\n            val imageView = addPhotoItemView(item, space, corner)\n            mItemImageViews.add(imageView)\n        }\n    }\n\n    fun resize(width: Int, height: Int) {\n        mViewWidth = width\n        mViewHeight = height\n        for (i in mItemImageViews.indices) {\n            resizeItem(i)\n        }\n    }\n\n    private fun resizeItem(index: Int) {\n        val view = mItemImageViews[index]\n        val item = mPhotoItems[index]\n        val metrics = computeFrameMetrics(item.bound)\n        val params = view.layoutParams as LayoutParams\n        params.leftMargin = metrics.leftMargin\n        params.topMargin = metrics.topMargin\n        params.width = metrics.width\n        params.height = metrics.height\n        view.layoutParams = params\n        view.updateFrame(metrics.width.toFloat(), metrics.height.toFloat())\n    }\n\n    fun setBackgroundColor(color: ComposeColor) {\n        backgroundColor = color\n        setBackgroundColor(backgroundColor.toArgb())\n        invalidate()\n    }\n\n    fun setOnItemTapListener(listener: ((index: Int) -> Unit)?) {\n        onItemTapListener = listener\n    }\n\n    fun setSpace(space: Float, corner: Float) {\n        for (img in mItemImageViews)\n            img.setSpace(space, corner)\n    }\n\n    fun setHandleDrawable(drawable: Drawable?) {\n        handleDrawable = drawable ?: createDefaultHandleDrawable()\n        invalidate()\n    }\n\n    fun updateImages(images: List<Uri>) {\n        val minSize = kotlin.math.min(images.size, mPhotoItems.size)\n        for (i in 0 until minSize) {\n            val newUri = images[i]\n            val item = mPhotoItems[i]\n            val oldUri = item.imagePath\n            val changed = (oldUri?.toString() ?: \"\") != (newUri.toString())\n            if (changed) {\n                item.imagePath = newUri\n                if (i < mItemImageViews.size) {\n                    mItemImageViews[i].reloadImageFromPhotoItem()\n                }\n            }\n        }\n    }\n\n    private fun createDefaultHandleDrawable(): Drawable {\n        val diameterPx = 72 // equals previous 36px radius circle\n        return GradientDrawable().apply {\n            shape = GradientDrawable.OVAL\n            setColor(android.graphics.Color.rgb(255, 165, 0))\n            setSize(diameterPx, diameterPx)\n        }\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    private fun addPhotoItemView(\n        item: PhotoItem,\n        space: Float,\n        corner: Float\n    ): FrameImageView {\n        val imageView = FrameImageView(context, item)\n        val metrics = computeFrameMetrics(item.bound)\n        imageView.setRotationEnabled(!disableRotation)\n        imageView.setSnapToBordersEnabled(enableSnapToBorders)\n        imageView.init(metrics.width.toFloat(), metrics.height.toFloat(), space, corner)\n        imageView.setOnImageClickListener(this)\n        imageView.setOnTouchListener { _, event ->\n            // Intercept to support handle dragging overlay\n            onTouchEvent(event)\n        }\n        if (mPhotoItems.size > 1)\n            imageView.setOnDragListener(mOnDragListener)\n\n        val params = LayoutParams(metrics.width, metrics.height)\n        params.leftMargin = metrics.leftMargin\n        params.topMargin = metrics.topMargin\n        imageView.originalLayoutParams = params\n        addView(imageView, params)\n        return imageView\n    }\n\n    @Throws(OutOfMemoryError::class)\n    fun createImage(outputScaleRatio: Float): Bitmap {\n        try {\n            val template = createBitmap(\n                (outputScaleRatio * mViewWidth).toInt(),\n                (outputScaleRatio * mViewHeight).toInt()\n            )\n            val canvas = Canvas(template)\n            canvas.drawColor(backgroundColor.toArgb())\n            for (view in mItemImageViews)\n                if (view.image != null && !view.image!!.isRecycled) {\n                    val left = (view.left * outputScaleRatio).toInt()\n                    val top = (view.top * outputScaleRatio).toInt()\n                    val width = (view.width * outputScaleRatio).toInt()\n                    val height = (view.height * outputScaleRatio).toInt()\n                    //draw image\n                    canvas.saveLayer(\n                        left.toFloat(),\n                        top.toFloat(),\n                        (left + width).toFloat(),\n                        (top + height).toFloat(),\n                        Paint()\n                    )\n                    canvas.translate(left.toFloat(), top.toFloat())\n                    canvas.clipRect(0, 0, width, height)\n                    view.drawOutputImage(canvas, outputScaleRatio)\n                    canvas.restore()\n                }\n\n            return template\n        } catch (error: OutOfMemoryError) {\n            throw error\n        }\n    }\n\n    override fun onLongClickImage(view: FrameImageView) {\n        if (mPhotoItems.size > 1) {\n            view.tag = \"\"\"x=${0f},y=${0f},path=${view.photoItem.imagePath}\"\"\"\n            val item = ClipData.Item(view.tag as CharSequence)\n            val mimeTypes = arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN)\n            val dragData = ClipData(view.tag.toString(), mimeTypes, item)\n            val myShadow = DragShadowBuilder(view)\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n                view.startDragAndDrop(dragData, myShadow, view, 0)\n            } else {\n                @Suppress(\"DEPRECATION\")\n                view.startDrag(dragData, myShadow, view, 0)\n            }\n        }\n    }\n\n    override fun onDoubleClickImage(view: FrameImageView) {\n\n    }\n\n    fun clearSelection() {\n        selectedItemIndex = null\n        activeHandle = null\n        onItemTapListener?.invoke(-1)\n        invalidate()\n    }\n\n    override fun onSingleTapImage(view: FrameImageView) {\n        if (selectedItemIndex == view.photoItem.index) {\n            clearSelection()\n        } else {\n            onItemTapListener?.invoke(view.photoItem.index)\n            selectedItemIndex = view.photoItem.index\n            requestFocus()\n            invalidate()\n        }\n    }\n\n    override fun onWindowFocusChanged(hasWindowFocus: Boolean) {\n        super.onWindowFocusChanged(hasWindowFocus)\n        if (!hasWindowFocus) {\n            // Clear selection when window focus is lost\n            if (selectedItemIndex != null) {\n                clearSelection()\n            }\n        }\n    }\n\n    override fun onFocusChanged(\n        gainFocus: Boolean,\n        direction: Int,\n        previouslyFocusedRect: android.graphics.Rect?\n    ) {\n        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)\n        if (!gainFocus) {\n            // Clear selection when view focus is lost\n            if (selectedItemIndex != null) {\n                clearSelection()\n            }\n        }\n    }\n\n    override fun dispatchDraw(canvas: Canvas) {\n        super.dispatchDraw(canvas)\n        // draw handles for selected item\n        val index = selectedItemIndex ?: return\n        val handles = paramsManager?.getHandles(index) ?: emptyList()\n        if (handles.isEmpty()) return\n        val drawable = handleDrawable ?: return\n        for (handle in handles) {\n            val dp = handle.draggablePoint(paramsManager!!)\n            val cx = mViewWidth * dp.x\n            val cy = mViewHeight * dp.y\n            val angle = handle.getAngle() + 90f\n            val diameter = max(\n                drawable.intrinsicWidth,\n                drawable.intrinsicHeight\n            ).takeIf { it > 0 }?.toFloat() ?: 72f\n            val half = diameter / 2f\n            canvas.withTranslation(cx, cy) {\n                canvas.rotate(angle)\n                drawable.setBounds((-half).toInt(), (-half).toInt(), half.toInt(), half.toInt())\n                drawable.draw(canvas)\n            }\n        }\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    override fun onTouchEvent(event: MotionEvent): Boolean {\n        val index = selectedItemIndex ?: return super.onTouchEvent(event)\n        mItemImageViews.firstOrNull { it.photoItem.index == index } ?: return super.onTouchEvent(\n            event\n        )\n        val manager = paramsManager ?: return super.onTouchEvent(event)\n        val handles = manager.getHandles(index)\n        if (handles.isEmpty()) return super.onTouchEvent(event)\n\n        // Compute coordinates in this layout's local space regardless of source view\n        val screenPos = IntArray(2)\n        getLocationOnScreen(screenPos)\n        val globalX = event.rawX - screenPos[0]\n        val globalY = event.rawY - screenPos[1]\n\n        when (event.action) {\n            MotionEvent.ACTION_DOWN -> {\n                val drawable = handleDrawable\n                if (drawable == null) {\n                    activeHandle = null\n                    return super.onTouchEvent(event)\n                }\n                val diameter = max(\n                    drawable.intrinsicWidth,\n                    drawable.intrinsicHeight\n                ).takeIf { it > 0 }?.toFloat() ?: 72f\n                val radius = diameter / 2f\n                activeHandle = handles.firstOrNull { handle ->\n                    val dp = handle.draggablePoint(manager)\n                    val hx = mViewWidth * dp.x\n                    val hy = mViewHeight * dp.y\n                    val dx = globalX - hx\n                    val dy = globalY - hy\n                    dx * dx + dy * dy <= radius * radius\n                }\n                return activeHandle != null || super.onTouchEvent(event)\n            }\n\n            MotionEvent.ACTION_MOVE -> {\n                val handle = activeHandle ?: return super.onTouchEvent(event)\n                val nx = (globalX / mViewWidth).coerceIn(0f, 1f)\n                val ny = (globalY / mViewHeight).coerceIn(0f, 1f)\n                handle.tryDrag(PointF(nx, ny), manager) ?: return true  // Drag failed\n                invalidate()\n                return true\n            }\n\n            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {\n                activeHandle = null\n                return super.onTouchEvent(event)\n            }\n        }\n        return super.onTouchEvent(event)\n    }\n\n    private fun getMemoryInfo(): MemoryInfo = MemoryInfo().apply {\n        context.getSystemService<ActivityManager>()?.getMemoryInfo(this)\n    }\n\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/view/MultiTouchHandler.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"DEPRECATION\")\n\npackage com.t8rin.collages.view\n\nimport android.graphics.Matrix\nimport android.graphics.PointF\nimport android.os.Parcel\nimport android.os.Parcelable\nimport android.view.MotionEvent\nimport kotlin.math.atan2\nimport kotlin.math.sqrt\n\ninternal class MultiTouchHandler : Parcelable {\n\n    // these matrices will be used to move and zoom image\n    private var mMatrix = Matrix()\n    private var mSavedMatrix = Matrix()\n\n    private var mMode = NONE\n\n    // remember some things for zooming\n    private var mStart = PointF()\n    private var mMid = PointF()\n    private var mOldDist = 1f\n    private var mD = 0f\n    private var mNewRot = 0f\n    private var mLastEvent: FloatArray? = null\n    private var mEnableRotation = false\n    private var mEnableZoom = true\n    private var mEnableTranslateX = true\n    private var mEnableTranslateY = true\n\n    private var mMaxPositionOffset = -1f\n    private var mOldImagePosition = PointF(0f, 0f)\n    private var mCheckingPosition = PointF(0f, 0f)\n\n    var matrix: Matrix\n        get() = mMatrix\n        set(matrix) {\n            this.mMatrix.set(matrix)\n            mSavedMatrix.set(matrix)\n        }\n\n    constructor()\n\n    fun reset() {\n        this.mMatrix.reset()\n        this.mSavedMatrix.reset()\n        mMode = NONE\n        mStart.set(0f, 0f)\n        mMid.set(0f, 0f)\n        mOldDist = 1f\n        mD = 0f\n        mNewRot = 0f\n        mLastEvent = null\n        mEnableRotation = false\n    }\n\n    fun setMaxPositionOffset(maxPositionOffset: Float) {\n        mMaxPositionOffset = maxPositionOffset\n    }\n\n    fun touch(event: MotionEvent) {\n        when (event.action and MotionEvent.ACTION_MASK) {\n            MotionEvent.ACTION_DOWN -> {\n                mSavedMatrix.set(mMatrix)\n                mStart.set(event.x, event.y)\n                mOldImagePosition.set(mCheckingPosition.x, mCheckingPosition.y)\n                mMode = DRAG\n                mLastEvent = null\n            }\n\n            MotionEvent.ACTION_POINTER_DOWN -> {\n                mOldDist = spacing(event)\n                if (mOldDist > 10f) {\n                    mSavedMatrix.set(mMatrix)\n                    midPoint(mMid, event)\n                    mMode = ZOOM\n                }\n                mLastEvent = FloatArray(4)\n                mLastEvent!![0] = event.getX(0)\n                mLastEvent!![1] = event.getX(1)\n                mLastEvent!![2] = event.getY(0)\n                mLastEvent!![3] = event.getY(1)\n                mD = rotation(event)\n            }\n\n            MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> {\n                mMode = NONE\n                mLastEvent = null\n            }\n\n            MotionEvent.ACTION_MOVE -> if (mMode == DRAG) {\n                mMatrix.set(mSavedMatrix)\n                mCheckingPosition.set(mOldImagePosition.x, mOldImagePosition.y)\n\n                var dx = event.x - mStart.x\n                var dy = event.y - mStart.y\n\n                mCheckingPosition.x += dx\n                mCheckingPosition.y += dy\n                if (!mEnableTranslateX) {\n                    dx = 0f\n                    if (mCheckingPosition.y > mMaxPositionOffset) {\n                        dy -= (mCheckingPosition.y - mMaxPositionOffset)\n                        mCheckingPosition.y = mMaxPositionOffset\n                    } else if (mCheckingPosition.y < -mMaxPositionOffset) {\n                        dy -= (mCheckingPosition.y + mMaxPositionOffset)\n                        mCheckingPosition.y = -mMaxPositionOffset\n                    }\n                }\n\n                if (!mEnableTranslateY) {\n                    dy = 0f\n                    if (mCheckingPosition.x > mMaxPositionOffset) {\n                        dx -= (mCheckingPosition.x - mMaxPositionOffset)\n                        mCheckingPosition.x = mMaxPositionOffset\n                    } else if (mCheckingPosition.x < -mMaxPositionOffset) {\n                        dx -= (mCheckingPosition.x + mMaxPositionOffset)\n                        mCheckingPosition.x = -mMaxPositionOffset\n                    }\n                }\n\n                mMatrix.postTranslate(dx, dy)\n            } else if (mMode == ZOOM && mEnableZoom) {\n                val newDist = spacing(event)\n                if (newDist > 10f) {\n                    mMatrix.set(mSavedMatrix)\n                    val scale = newDist / mOldDist\n                    mMatrix.postScale(scale, scale, mMid.x, mMid.y)\n                }\n\n                if (mEnableRotation && mLastEvent != null && event.pointerCount == 2) {\n                    mNewRot = rotation(event)\n                    midPoint(mMid, event)\n                    val r = mNewRot - mD\n                    mMatrix.postRotate(r, mMid.x, mMid.y)\n                }\n            }\n        }\n    }\n\n    fun setEnableRotation(enableRotation: Boolean) {\n        mEnableRotation = enableRotation\n    }\n\n    fun setEnableZoom(enableZoom: Boolean) {\n        mEnableZoom = enableZoom\n    }\n\n    fun setEnableTranslateX(enableTranslateX: Boolean) {\n        mEnableTranslateX = enableTranslateX\n    }\n\n    fun setEnableTranslateY(enableTranslateY: Boolean) {\n        mEnableTranslateY = enableTranslateY\n    }\n\n    /**\n     * Determine the space between the first two fingers\n     */\n    private fun spacing(event: MotionEvent): Float {\n        val x = event.getX(0) - event.getX(1)\n        val y = event.getY(0) - event.getY(1)\n        return sqrt((x * x + y * y).toDouble()).toFloat()\n    }\n\n    /**\n     * Calculate the mid point of the first two fingers\n     */\n    private fun midPoint(point: PointF, event: MotionEvent) {\n        val x = event.getX(0) + event.getX(1)\n        val y = event.getY(0) + event.getY(1)\n        point.set(x / 2, y / 2)\n    }\n\n    /**\n     * Calculate the degree to be rotated by.\n     *\n     * @param event\n     * @return Degrees\n     */\n    private fun rotation(event: MotionEvent): Float {\n        val deltaX = (event.getX(0) - event.getX(1)).toDouble()\n        val deltaY = (event.getY(0) - event.getY(1)).toDouble()\n        val radians = atan2(deltaY, deltaX)\n        return Math.toDegrees(radians).toFloat()\n    }\n\n    override fun describeContents(): Int {\n        return 0\n    }\n\n    private constructor(`in`: Parcel) {\n        var values = FloatArray(9)\n        `in`.readFloatArray(values)\n        mMatrix = Matrix()\n        mMatrix.setValues(values)\n\n        values = FloatArray(9)\n        `in`.readFloatArray(values)\n        mSavedMatrix = Matrix()\n        mSavedMatrix.setValues(values)\n\n        mMode = `in`.readInt()\n        mStart = `in`.readParcelable(PointF::class.java.classLoader)!!\n        mMid = `in`.readParcelable(PointF::class.java.classLoader)!!\n        mOldDist = `in`.readFloat()\n        mD = `in`.readFloat()\n        mNewRot = `in`.readFloat()\n        val b = BooleanArray(4)\n        `in`.readBooleanArray(b)\n        mEnableRotation = b[0]\n        mEnableZoom = b[1]\n        mEnableTranslateX = b[2]\n        mEnableTranslateY = b[3]\n\n        mMaxPositionOffset = `in`.readFloat()\n        mOldImagePosition = `in`.readParcelable(PointF::class.java.classLoader)!!\n        mCheckingPosition = `in`.readParcelable(PointF::class.java.classLoader)!!\n    }\n\n    override fun writeToParcel(dest: Parcel, flags: Int) {\n        var values = FloatArray(9)\n        mMatrix.getValues(values)\n        dest.writeFloatArray(values)\n\n        values = FloatArray(9)\n        mSavedMatrix.getValues(values)\n        dest.writeFloatArray(values)\n\n        dest.writeInt(mMode)\n        dest.writeParcelable(mStart, flags)\n        dest.writeParcelable(mMid, flags)\n        dest.writeFloat(mOldDist)\n        dest.writeFloat(mD)\n        dest.writeFloat(mNewRot)\n\n        val b = booleanArrayOf(mEnableRotation, mEnableZoom, mEnableTranslateX, mEnableTranslateY)\n        dest.writeBooleanArray(b)\n\n        dest.writeFloat(mMaxPositionOffset)\n        dest.writeParcelable(mOldImagePosition, flags)\n        dest.writeParcelable(mCheckingPosition, flags)\n    }\n\n    companion object CREATOR : Parcelable.Creator<MultiTouchHandler> {\n\n        private const val NONE = 0\n        private const val DRAG = 1\n        private const val ZOOM = 2\n\n        override fun createFromParcel(parcel: Parcel): MultiTouchHandler {\n            return MultiTouchHandler(parcel)\n        }\n\n        override fun newArray(size: Int): Array<MultiTouchHandler?> {\n            return arrayOfNulls(size)\n        }\n    }\n}\n"
  },
  {
    "path": "lib/collages/src/main/java/com/t8rin/collages/view/PhotoItem.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.collages.view\n\nimport android.graphics.Path\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport android.net.Uri\n\n\ninternal data class PhotoItem(\n    //Primary info\n    var index: Int = 0,\n    var imagePath: Uri? = null,\n    //Using point list to construct view. All points and width, height are in [0, 1] range.\n    var pointList: ArrayList<PointF> = ArrayList(),\n    var bound: RectF = RectF(),\n    //Using path to create\n    var path: Path? = null,\n    var pathRatioBound: RectF? = null,\n    var pathInCenterHorizontal: Boolean = false,\n    var pathInCenterVertical: Boolean = false,\n    var pathAlignParentRight: Boolean = false,\n    var pathScaleRatio: Float = 1f,\n    var fitBound: Boolean = false,\n    //other info\n    var hasBackground: Boolean = false,\n    var shrinkMethod: Int = SHRINK_METHOD_DEFAULT,\n    var cornerMethod: Int = CORNER_METHOD_DEFAULT,\n    var disableShrink: Boolean = false,\n    var shrinkMap: HashMap<PointF, PointF>? = null,\n    //Clear polygon or arc area\n    var clearAreaPoints: ArrayList<PointF>? = null,\n    //Clear an area using path\n    var clearPath: Path? = null,\n    var clearPathRatioBound: RectF? = null,\n    var clearPathInCenterHorizontal: Boolean = false,\n    var clearPathInCenterVertical: Boolean = false,\n    var clearPathScaleRatio: Float = 1f,\n    var centerInClearBound: Boolean = false,\n) {\n\n    companion object {\n        const val SHRINK_METHOD_DEFAULT = 0\n        const val SHRINK_METHOD_3_3 = 1\n        const val SHRINK_METHOD_USING_MAP = 2\n        const val SHRINK_METHOD_3_6 = 3\n        const val SHRINK_METHOD_3_8 = 4\n        const val SHRINK_METHOD_COMMON = 5\n        const val CORNER_METHOD_DEFAULT = 0\n        const val CORNER_METHOD_3_6 = 1\n        const val CORNER_METHOD_3_13 = 2\n    }\n}\n"
  },
  {
    "path": "lib/colors/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/colors/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.colors\"\n\ndependencies {\n    implementation(libs.androidx.palette.ktx)\n\n    implementation(projects.lib.gesture)\n    implementation(projects.lib.image)\n    implementation(projects.lib.zoomable)\n}"
  },
  {
    "path": "lib/colors/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/colors/src/main/assets/color_names.json",
    "content": "{\"#FF000000\": \"Black\", \"#FF000080\": \"Navy Blue\", \"#FF0000C8\": \"Dark Blue\", \"#FF0000FF\": \"Blue\", \"#FF000741\": \"Stratos\", \"#FF001B1C\": \"Swamp\", \"#FF002387\": \"Resolution Blue\", \"#FF002900\": \"Deep Fir\", \"#FF002E20\": \"Burnham\", \"#FF002FA7\": \"Klein Blue\", \"#FF003153\": \"Prussian Blue\", \"#FF003366\": \"Midnight Blue\", \"#FF003399\": \"Smalt\", \"#FF003532\": \"Deep Teal\", \"#FF003E40\": \"Cyprus\", \"#FF004620\": \"Kaitoke Green\", \"#FF0047AB\": \"Cobalt\", \"#FF004816\": \"Crusoe\", \"#FF004950\": \"Sherpa Blue\", \"#FF0056A7\": \"Endeavour\", \"#FF00581A\": \"Camarone\", \"#FF0066CC\": \"Science Blue\", \"#FF0066FF\": \"Blue Ribbon\", \"#FF00755E\": \"Tropical Rain Forest\", \"#FF0076A3\": \"Allports\", \"#FF007BA7\": \"Deep Cerulean\", \"#FF007EC7\": \"Lochmara\", \"#FF007FFF\": \"Azure Radiance\", \"#FF008080\": \"Teal\", \"#FF0095B6\": \"Bondi Blue\", \"#FF009DC4\": \"Pacific Blue\", \"#FF00A693\": \"Persian Green\", \"#FF00A86B\": \"Jade\", \"#FF00CC99\": \"Caribbean Green\", \"#FF00CCCC\": \"Robin's Egg Blue\", \"#FF00FF00\": \"Green\", \"#FF00FF7F\": \"Spring Green\", \"#FF00FFFF\": \"Cyan Aqua\", \"#FF010D1A\": \"Blue Charcoal\", \"#FF011635\": \"Midnight\", \"#FF011D13\": \"Holly\", \"#FF012731\": \"Daintree\", \"#FF01361C\": \"Cardin Green\", \"#FF01371A\": \"County Green\", \"#FF013E62\": \"Astronaut Blue\", \"#FF013F6A\": \"Regal Blue\", \"#FF014B43\": \"Aqua Deep\", \"#FF015E85\": \"Orient\", \"#FF016162\": \"Blue Stone\", \"#FF016D39\": \"Fun Green\", \"#FF01796F\": \"Pine Green\", \"#FF017987\": \"Blue Lagoon\", \"#FF01826B\": \"Deep Sea\", \"#FF01A368\": \"Green Haze\", \"#FF022D15\": \"English Holly\", \"#FF02402C\": \"Sherwood Green\", \"#FF02478E\": \"Congress Blue\", \"#FF024E46\": \"Evening Sea\", \"#FF026395\": \"Bahama Blue\", \"#FF02866F\": \"Observatory\", \"#FF02A4D3\": \"Cerulean\", \"#FF03163C\": \"Tangaroa\", \"#FF032B52\": \"Green Vogue\", \"#FF036A6E\": \"Mosque\", \"#FF041004\": \"Midnight Moss\", \"#FF041322\": \"Black Pearl\", \"#FF042E4C\": \"Blue Whale\", \"#FF044022\": \"Zuccini\", \"#FF044259\": \"Teal Blue\", \"#FF051040\": \"Deep Cove\", \"#FF051657\": \"Gulf Blue\", \"#FF055989\": \"Venice Blue\", \"#FF056F57\": \"Watercourse\", \"#FF062A78\": \"Catalina Blue\", \"#FF063537\": \"Tiber\", \"#FF069B81\": \"Gossamer\", \"#FF06A189\": \"Niagara\", \"#FF073A50\": \"Tarawera\", \"#FF080110\": \"Jaguar\", \"#FF081910\": \"Black Bean\", \"#FF082567\": \"Deep Sapphire\", \"#FF088370\": \"Elf Green\", \"#FF08E8DE\": \"Bright Turquoise\", \"#FF092256\": \"Downriver\", \"#FF09230F\": \"Palm Green\", \"#FF09255D\": \"Madison\", \"#FF093624\": \"Bottle Green\", \"#FF095859\": \"Deep Sea Green\", \"#FF097F4B\": \"Salem\", \"#FF0A001C\": \"Black Russian\", \"#FF0A480D\": \"Dark Fern\", \"#FF0A6906\": \"Japanese Laurel\", \"#FF0A6F75\": \"Atoll\", \"#FF0B0B0B\": \"Cod Gray\", \"#FF0B0F08\": \"Marshland\", \"#FF0B1107\": \"Gordons Green\", \"#FF0B1304\": \"Black Forest\", \"#FF0B6207\": \"San Felix\", \"#FF0BDA51\": \"Malachite\", \"#FF0C0B1D\": \"Ebony\", \"#FF0C0D0F\": \"Woodsmoke\", \"#FF0C1911\": \"Racing Green\", \"#FF0C7A79\": \"Surfie Green\", \"#FF0C8990\": \"Blue Chill\", \"#FF0D0332\": \"Black Rock\", \"#FF0D1117\": \"Bunker\", \"#FF0D1C19\": \"Aztec\", \"#FF0D2E1C\": \"Bush\", \"#FF0E0E18\": \"Cinder\", \"#FF0E2A30\": \"Firefly\", \"#FF0F2D9E\": \"Torea Bay\", \"#FF10121D\": \"Vulcan\", \"#FF101405\": \"Green Waterloo\", \"#FF105852\": \"Eden\", \"#FF110C6C\": \"Arapawa\", \"#FF120A8F\": \"Ultramarine\", \"#FF123447\": \"Elephant\", \"#FF126B40\": \"Jewel\", \"#FF130000\": \"Diesel\", \"#FF130A06\": \"Asphalt\", \"#FF13264D\": \"Blue Zodiac\", \"#FF134F19\": \"Parsley\", \"#FF140600\": \"Nero\", \"#FF1450AA\": \"Tory Blue\", \"#FF151F4C\": \"Bunting\", \"#FF1560BD\": \"Denim\", \"#FF15736B\": \"Genoa\", \"#FF161928\": \"Mirage\", \"#FF161D10\": \"Hunter Green\", \"#FF162A40\": \"Big Stone\", \"#FF163222\": \"Celtic\", \"#FF16322C\": \"Timber Green\", \"#FF163531\": \"Gable Green\", \"#FF171F04\": \"Pine Tree\", \"#FF175579\": \"Chathams Blue\", \"#FF182D09\": \"Deep Forest Green\", \"#FF18587A\": \"Blumine\", \"#FF19330E\": \"Palm Leaf\", \"#FF193751\": \"Nile Blue\", \"#FF1959A8\": \"Fun Blue\", \"#FF1A1A68\": \"Lucky Point\", \"#FF1AB385\": \"Mountain Meadow\", \"#FF1B0245\": \"Tolopea\", \"#FF1B1035\": \"Haiti\", \"#FF1B127B\": \"Deep Koamaru\", \"#FF1B1404\": \"Acadia\", \"#FF1B2F11\": \"Seaweed\", \"#FF1B3162\": \"Biscay\", \"#FF1B659D\": \"Matisse\", \"#FF1C1208\": \"Crowshead\", \"#FF1C1E13\": \"Rangoon Green\", \"#FF1C39BB\": \"Persian Blue\", \"#FF1C402E\": \"Everglade\", \"#FF1C7C7D\": \"Elm\", \"#FF1D6142\": \"Green Pea\", \"#FF1E0F04\": \"Creole\", \"#FF1E1609\": \"Karaka\", \"#FF1E1708\": \"El Paso\", \"#FF1E385B\": \"Cello\", \"#FF1E433C\": \"Te Papa Green\", \"#FF1E90FF\": \"Dodger Blue\", \"#FF1E9AB0\": \"Eastern Blue\", \"#FF1F120F\": \"Night Rider\", \"#FF1FC2C2\": \"Java\", \"#FF20208D\": \"Jacksons Purple\", \"#FF202E54\": \"Cloud Burst\", \"#FF204852\": \"Blue Dianne\", \"#FF211A0E\": \"Eternity\", \"#FF220878\": \"Deep Blue\", \"#FF228B22\": \"Forest Green\", \"#FF233418\": \"Mallard\", \"#FF240A40\": \"Violet\", \"#FF240C02\": \"Kilimanjaro\", \"#FF242A1D\": \"Log Cabin\", \"#FF242E16\": \"Black Olive\", \"#FF24500F\": \"Green House\", \"#FF251607\": \"Graphite\", \"#FF251706\": \"Cannon Black\", \"#FF251F4F\": \"Port Gore\", \"#FF25272C\": \"Shark\", \"#FF25311C\": \"Green Kelp\", \"#FF2596D1\": \"Curious Blue\", \"#FF260368\": \"Paua\", \"#FF26056A\": \"Paris M\", \"#FF261105\": \"Wood Bark\", \"#FF261414\": \"Gondola\", \"#FF262335\": \"Steel Gray\", \"#FF26283B\": \"Ebony Clay\", \"#FF273A81\": \"Bay of Many\", \"#FF27504B\": \"Plantation\", \"#FF278A5B\": \"Eucalyptus\", \"#FF281E15\": \"Oil\", \"#FF283A77\": \"Astronaut\", \"#FF286ACD\": \"Mariner\", \"#FF290C5E\": \"Violent Violet\", \"#FF292130\": \"Bastille\", \"#FF292319\": \"Zeus\", \"#FF292937\": \"Charade\", \"#FF297B9A\": \"Jelly Bean\", \"#FF29AB87\": \"Jungle Green\", \"#FF2A0359\": \"Cherry Pie\", \"#FF2A140E\": \"Coffee Bean\", \"#FF2A2630\": \"Baltic Sea\", \"#FF2A380B\": \"Turtle Green\", \"#FF2A52BE\": \"Cerulean Blue\", \"#FF2B0202\": \"Sepia Black\", \"#FF2B194F\": \"Valhalla\", \"#FF2B3228\": \"Heavy Metal\", \"#FF2C0E8C\": \"Blue Gem\", \"#FF2C1632\": \"Revolver\", \"#FF2C2133\": \"Bleached Cedar\", \"#FF2C8C84\": \"Lochinvar\", \"#FF2D2510\": \"Mikado\", \"#FF2D383A\": \"Outer Space\", \"#FF2D569B\": \"St Tropez\", \"#FF2E0329\": \"Jacaranda\", \"#FF2E1905\": \"Jacko Bean\", \"#FF2E3222\": \"Rangitoto\", \"#FF2E3F62\": \"Rhino\", \"#FF2E8B57\": \"Sea Green\", \"#FF2EBFD4\": \"Scooter\", \"#FF2F270E\": \"Onion\", \"#FF2F3CB3\": \"Governor Bay\", \"#FF2F519E\": \"Sapphire\", \"#FF2F5A57\": \"Spectra\", \"#FF2F6168\": \"Casal\", \"#FF300529\": \"Melanzane\", \"#FF301F1E\": \"Cocoa Brown\", \"#FF302A0F\": \"Woodrush\", \"#FF304B6A\": \"San Juan\", \"#FF30D5C8\": \"Turquoise\", \"#FF311C17\": \"Eclipse\", \"#FF314459\": \"Pickled Bluewood\", \"#FF315BA1\": \"Azure\", \"#FF31728D\": \"Calypso\", \"#FF317D82\": \"Paradiso\", \"#FF32127A\": \"Persian Indigo\", \"#FF32293A\": \"Blackcurrant\", \"#FF323232\": \"Mine Shaft\", \"#FF325D52\": \"Stromboli\", \"#FF327C14\": \"Bilbao\", \"#FF327DA0\": \"Astral\", \"#FF33036B\": \"Christalle\", \"#FF33292F\": \"Thunder\", \"#FF33CC99\": \"Shamrock\", \"#FF341515\": \"Tamarind\", \"#FF350036\": \"Mardi Gras\", \"#FF350E42\": \"Valentino\", \"#FF350E57\": \"Jagger\", \"#FF353542\": \"Tuna\", \"#FF354E8C\": \"Chambray\", \"#FF363050\": \"Martinique\", \"#FF363534\": \"Tuatara\", \"#FF363C0D\": \"Waiouru\", \"#FF36747D\": \"Ming\", \"#FF368716\": \"La Palma\", \"#FF370202\": \"Chocolate\", \"#FF371D09\": \"Clinker\", \"#FF37290E\": \"Brown Tumbleweed\", \"#FF373021\": \"Birch\", \"#FF377475\": \"Oracle\", \"#FF380474\": \"Blue Diamond\", \"#FF381A51\": \"Grape\", \"#FF383533\": \"Dune\", \"#FF384555\": \"Oxford Blue\", \"#FF384910\": \"Clover\", \"#FF394851\": \"Limed Spruce\", \"#FF396413\": \"Dell\", \"#FF3A0020\": \"Toledo\", \"#FF3A2010\": \"Sambuca\", \"#FF3A2A6A\": \"Jacarta\", \"#FF3A686C\": \"William\", \"#FF3A6A47\": \"Killarney\", \"#FF3AB09E\": \"Keppel\", \"#FF3B000B\": \"Temptress\", \"#FF3B0910\": \"Aubergine\", \"#FF3B1F1F\": \"Jon\", \"#FF3B2820\": \"Treehouse\", \"#FF3B7A57\": \"Amazon\", \"#FF3B91B4\": \"Boston Blue\", \"#FF3C0878\": \"Windsor\", \"#FF3C1206\": \"Rebel\", \"#FF3C1F76\": \"Meteorite\", \"#FF3C2005\": \"Dark Ebony\", \"#FF3C3910\": \"Camouflage\", \"#FF3C4151\": \"Bright Gray\", \"#FF3C4443\": \"Cape Cod\", \"#FF3C493A\": \"Lunar Green\", \"#FF3D0C02\": \"Bean\", \"#FF3D2B1F\": \"Bistre\", \"#FF3D7D52\": \"Goblin\", \"#FF3E0480\": \"Kingfisher Daisy\", \"#FF3E1C14\": \"Cedar\", \"#FF3E2B23\": \"English Walnut\", \"#FF3E2C1C\": \"Black Marlin\", \"#FF3E3A44\": \"Ship Gray\", \"#FF3EABBF\": \"Pelorous\", \"#FF3F2109\": \"Bronze\", \"#FF3F2500\": \"Cola\", \"#FF3F3002\": \"Madras\", \"#FF3F307F\": \"Minsk\", \"#FF3F4C3A\": \"Cabbage Pont\", \"#FF3F583B\": \"Tom Thumb\", \"#FF3F5D53\": \"Mineral Green\", \"#FF3FC1AA\": \"Puerto Rico\", \"#FF3FFF00\": \"Harlequin\", \"#FF401801\": \"Brown Pod\", \"#FF40291D\": \"Cork\", \"#FF403B38\": \"Masala\", \"#FF403D19\": \"Thatch Green\", \"#FF405169\": \"Fjord\", \"#FF40826D\": \"Viridian\", \"#FF40A860\": \"Chateau Green\", \"#FF410056\": \"Ripe Plum\", \"#FF411E10\": \"Paco\", \"#FF412010\": \"Deep Oak\", \"#FF413C37\": \"Merlin\", \"#FF414257\": \"Gun Powder\", \"#FF414C7D\": \"East Bay\", \"#FF4169E1\": \"Royal Blue\", \"#FF41AA78\": \"Ocean Green\", \"#FF420303\": \"Burnt Maroon\", \"#FF423921\": \"Lisbon Brown\", \"#FF427977\": \"Faded Jade\", \"#FF431560\": \"Scarlet Gum\", \"#FF433120\": \"Iroko\", \"#FF433E37\": \"Armadillo\", \"#FF434C59\": \"River Bed\", \"#FF436A0D\": \"Green Leaf\", \"#FF44012D\": \"Barossa\", \"#FF441D00\": \"Morocco Brown\", \"#FF444954\": \"Mako\", \"#FF454936\": \"Kelp\", \"#FF456CAC\": \"San Marino\", \"#FF45B1E8\": \"Picton Blue\", \"#FF460B41\": \"Loulou\", \"#FF462425\": \"Crater Brown\", \"#FF465945\": \"Gray Asparagus\", \"#FF4682B4\": \"Steel Blue\", \"#FF480404\": \"Rustic Red\", \"#FF480607\": \"Bulgarian Rose\", \"#FF480656\": \"Clairvoyant\", \"#FF481C1C\": \"Cocoa Bean\", \"#FF483131\": \"Woody Brown\", \"#FF483C32\": \"Taupe\", \"#FF49170C\": \"Van Cleef\", \"#FF492615\": \"Brown Derby\", \"#FF49371B\": \"Metallic Bronze\", \"#FF495400\": \"Verdun Green\", \"#FF496679\": \"Blue Bayoux\", \"#FF497183\": \"Bismark\", \"#FF4A2A04\": \"Bracken\", \"#FF4A3004\": \"Deep Bronze\", \"#FF4A3C30\": \"Mondo\", \"#FF4A4244\": \"Tundora\", \"#FF4A444B\": \"Gravel\", \"#FF4A4E5A\": \"Trout\", \"#FF4B0082\": \"Pigment Indigo\", \"#FF4B5D52\": \"Nandor\", \"#FF4C3024\": \"Saddle\", \"#FF4C4F56\": \"Abbey\", \"#FF4D0135\": \"Blackberry\", \"#FF4D0A18\": \"Cab Sav\", \"#FF4D1E01\": \"Indian Tan\", \"#FF4D282D\": \"Cowboy\", \"#FF4D282E\": \"Livid Brown\", \"#FF4D3833\": \"Rock\", \"#FF4D3D14\": \"Punga\", \"#FF4D400F\": \"Bronzetone\", \"#FF4D5328\": \"Woodland\", \"#FF4E0606\": \"Mahogany\", \"#FF4E2A5A\": \"Bossanova\", \"#FF4E3B41\": \"Matterhorn\", \"#FF4E420C\": \"Bronze Olive\", \"#FF4E4562\": \"Mulled Wine\", \"#FF4E6649\": \"Axolotl\", \"#FF4E7F9E\": \"Wedgewood\", \"#FF4EABD1\": \"Shakespeare\", \"#FF4F1C70\": \"Honey Flower\", \"#FF4F2398\": \"Daisy Bush\", \"#FF4F69C6\": \"Indigo\", \"#FF4F7942\": \"Fern Green\", \"#FF4F9D5D\": \"Fruit Salad\", \"#FF4FA83D\": \"Apple\", \"#FF504351\": \"Mortar\", \"#FF507096\": \"Kashmir Blue\", \"#FF507672\": \"Cutty Sark\", \"#FF50C878\": \"Emerald\", \"#FF514649\": \"Emperor\", \"#FF516E3D\": \"Chalet Green\", \"#FF517C66\": \"Como\", \"#FF51808F\": \"Smalt Blue\", \"#FF52001F\": \"Castro\", \"#FF520C17\": \"Maroon Oak\", \"#FF523C94\": \"Gigas\", \"#FF533455\": \"Voodoo\", \"#FF534491\": \"Victoria\", \"#FF53824B\": \"Hippie Green\", \"#FF541012\": \"Heath\", \"#FF544333\": \"Judge Gray\", \"#FF54534D\": \"Fuscous Gray\", \"#FF549019\": \"Vida Loca\", \"#FF55280C\": \"Cioccolato\", \"#FF555B10\": \"Saratoga\", \"#FF556D56\": \"Finlandia\", \"#FF5590D9\": \"Havelock Blue\", \"#FF56B4BE\": \"Fountain Blue\", \"#FF578363\": \"Spring Leaves\", \"#FF583401\": \"Saddle Brown\", \"#FF585562\": \"Scarpa Flow\", \"#FF587156\": \"Cactus\", \"#FF589AAF\": \"Hippie Blue\", \"#FF591D35\": \"Wine Berry\", \"#FF592804\": \"Brown Bramble\", \"#FF593737\": \"Congo Brown\", \"#FF594433\": \"Millbrook\", \"#FF5A6E9C\": \"Waikawa Gray\", \"#FF5A87A0\": \"Horizon\", \"#FF5B3013\": \"Jambalaya\", \"#FF5C0120\": \"Bordeaux\", \"#FF5C0536\": \"Mulberry Wood\", \"#FF5C2E01\": \"Carnaby Tan\", \"#FF5C5D75\": \"Comet\", \"#FF5D1E0F\": \"Redwood\", \"#FF5D4C51\": \"Don Juan\", \"#FF5D5C58\": \"Chicago\", \"#FF5D5E37\": \"Verdigris\", \"#FF5D7747\": \"Dingley\", \"#FF5DA19F\": \"Breaker Bay\", \"#FF5E483E\": \"Kabul\", \"#FF5E5D3B\": \"Hemlock\", \"#FF5F3D26\": \"Irish Coffee\", \"#FF5F5F6E\": \"Mid Gray\", \"#FF5F6672\": \"Shuttle Gray\", \"#FF5FA777\": \"Aqua Forest\", \"#FF5FB3AC\": \"Tradewind\", \"#FF604913\": \"Horses Neck\", \"#FF605B73\": \"Smoky\", \"#FF606E68\": \"Corduroy\", \"#FF6093D1\": \"Danube\", \"#FF612718\": \"Espresso\", \"#FF614051\": \"Eggplant\", \"#FF615D30\": \"Costa Del Sol\", \"#FF61845F\": \"Glade Green\", \"#FF622F30\": \"Buccaneer\", \"#FF623F2D\": \"Quincy\", \"#FF624E9A\": \"Butterfly Bush\", \"#FF625119\": \"West Coast\", \"#FF626649\": \"Finch\", \"#FF639A8F\": \"Patina\", \"#FF63B76C\": \"Fern\", \"#FF6456B7\": \"Blue Violet\", \"#FF646077\": \"Dolphin\", \"#FF646463\": \"Storm Dust\", \"#FF646A54\": \"Siam\", \"#FF646E75\": \"Nevada\", \"#FF6495ED\": \"Cornflower Blue\", \"#FF64CCDB\": \"Viking\", \"#FF65000B\": \"Rosewood\", \"#FF651A14\": \"Cherrywood\", \"#FF652DC1\": \"Purple Heart\", \"#FF657220\": \"Fern Frond\", \"#FF65745D\": \"Willow Grove\", \"#FF65869F\": \"Hoki\", \"#FF660045\": \"Pompadour\", \"#FF660099\": \"Purple\", \"#FF66023C\": \"Tyrian Purple\", \"#FF661010\": \"Dark Tan\", \"#FF66B58F\": \"Silver Tree\", \"#FF66FF00\": \"Bright Green\", \"#FF66FF66\": \"Screamin Green\", \"#FF67032D\": \"Black Rose\", \"#FF675FA6\": \"Scampi\", \"#FF676662\": \"Ironside Gray\", \"#FF678975\": \"Viridian Green\", \"#FF67A712\": \"Christi\", \"#FF683600\": \"Nutmeg Wood Finish\", \"#FF685558\": \"Zambezi\", \"#FF685E6E\": \"Salt Box\", \"#FF692545\": \"Tawny Port\", \"#FF692D54\": \"Finn\", \"#FF695F62\": \"Scorpion\", \"#FF697E9A\": \"Lynch\", \"#FF6A442E\": \"Spice\", \"#FF6A5D1B\": \"Himalaya\", \"#FF6A6051\": \"Soya Bean\", \"#FF6B2A14\": \"Hairy Heath\", \"#FF6B3FA0\": \"Royal Purple\", \"#FF6B4E31\": \"Shingle Fawn\", \"#FF6B5755\": \"Dorado\", \"#FF6B8BA2\": \"Bermuda Gray\", \"#FF6C3082\": \"Eminence\", \"#FF6CDAE7\": \"Turquoise Blue\", \"#FF6D0101\": \"Lonestar\", \"#FF6D5E54\": \"Pine Cone\", \"#FF6D6C6C\": \"Dove Gray\", \"#FF6D9292\": \"Juniper\", \"#FF6D92A1\": \"Gothic\", \"#FF6E0902\": \"Red Oxide\", \"#FF6E1D14\": \"Moccaccino\", \"#FF6E4826\": \"Pickled Bean\", \"#FF6E4B26\": \"Dallas\", \"#FF6E6D57\": \"Kokoda\", \"#FF6E7783\": \"Pale Sky\", \"#FF6F440C\": \"Cafe Royale\", \"#FF6F6A61\": \"Flint\", \"#FF6F8E63\": \"Highland\", \"#FF6F9D02\": \"Limeade\", \"#FF6FD0C5\": \"Downy\", \"#FF701C1C\": \"Persian Plum\", \"#FF704214\": \"Sepia\", \"#FF704A07\": \"Antique Bronze\", \"#FF704F50\": \"Ferra\", \"#FF706555\": \"Coffee\", \"#FF708090\": \"Slate Gray\", \"#FF711A00\": \"Cedar Wood Finish\", \"#FF71291D\": \"Metallic Copper\", \"#FF714693\": \"Affair\", \"#FF714AB2\": \"Studio\", \"#FF715D47\": \"Tobacco Brown\", \"#FF716338\": \"Yellow Metal\", \"#FF716B56\": \"Peat\", \"#FF716E10\": \"Olivetone\", \"#FF717486\": \"Storm Gray\", \"#FF718080\": \"Sirocco\", \"#FF71D9E2\": \"Aquamarine Blue\", \"#FF72010F\": \"Venetian Red\", \"#FF724A2F\": \"Old Copper\", \"#FF726D4E\": \"Go Ben\", \"#FF727B89\": \"Raven\", \"#FF731E8F\": \"Seance\", \"#FF734A12\": \"Raw Umber\", \"#FF736C9F\": \"Kimberly\", \"#FF736D58\": \"Crocodile\", \"#FF737829\": \"Crete\", \"#FF738678\": \"Xanadu\", \"#FF74640D\": \"Spicy Mustard\", \"#FF747D63\": \"Limed Ash\", \"#FF747D83\": \"Rolling Stone\", \"#FF748881\": \"Blue Smoke\", \"#FF749378\": \"Laurel\", \"#FF74C365\": \"Mantis\", \"#FF755A57\": \"Russett\", \"#FF7563A8\": \"Deluge\", \"#FF76395D\": \"Cosmic\", \"#FF7666C6\": \"Blue Marguerite\", \"#FF76BD17\": \"Lima\", \"#FF76D7EA\": \"Sky Blue\", \"#FF770F05\": \"Dark Burgundy\", \"#FF771F1F\": \"Crown of Thorns\", \"#FF773F1A\": \"Walnut\", \"#FF776F61\": \"Pablo\", \"#FF778120\": \"Pacifika\", \"#FF779E86\": \"Oxley\", \"#FF77DD77\": \"Pastel Green\", \"#FF780109\": \"Japanese Maple\", \"#FF782D19\": \"Mocha\", \"#FF782F16\": \"Peanut\", \"#FF78866B\": \"Camouflage Green\", \"#FF788A25\": \"Wasabi\", \"#FF788BBA\": \"Ship Cove\", \"#FF78A39C\": \"Sea Nymph\", \"#FF795D4C\": \"Roman Coffee\", \"#FF796878\": \"Old Lavender\", \"#FF796989\": \"Rum\", \"#FF796A78\": \"Fedora\", \"#FF796D62\": \"Sandstone\", \"#FF79DEEC\": \"Spray\", \"#FF7A013A\": \"Siren\", \"#FF7A58C1\": \"Fuchsia Blue\", \"#FF7A7A7A\": \"Boulder\", \"#FF7A89B8\": \"Wild Blue Yonder\", \"#FF7AC488\": \"De York\", \"#FF7B3801\": \"Red Beech\", \"#FF7B3F00\": \"Cinnamon\", \"#FF7B6608\": \"Yukon Gold\", \"#FF7B7874\": \"Tapa\", \"#FF7B7C94\": \"Waterloo\", \"#FF7B8265\": \"Flax Smoke\", \"#FF7B9F80\": \"Amulet\", \"#FF7BA05B\": \"Asparagus\", \"#FF7C1C05\": \"Kenyan Copper\", \"#FF7C7631\": \"Pesto\", \"#FF7C778A\": \"Topaz\", \"#FF7C7B7A\": \"Concord\", \"#FF7C7B82\": \"Jumbo\", \"#FF7C881A\": \"Trendy Green\", \"#FF7CA1A6\": \"Gumbo\", \"#FF7CB0A1\": \"Acapulco\", \"#FF7CB7BB\": \"Neptune\", \"#FF7D2C14\": \"Pueblo\", \"#FF7DA98D\": \"Bay Leaf\", \"#FF7DC8F7\": \"Malibu\", \"#FF7DD8C6\": \"Bermuda\", \"#FF7E3A15\": \"Copper Canyon\", \"#FF7F1734\": \"Claret\", \"#FF7F3A02\": \"Peru Tan\", \"#FF7F626D\": \"Falcon\", \"#FF7F7589\": \"Mobster\", \"#FF7F76D3\": \"Moody Blue\", \"#FF7FFF00\": \"Chartreuse\", \"#FF7FFFD4\": \"Aquamarine\", \"#FF800000\": \"Maroon\", \"#FF800B47\": \"Rose Bud Cherry\", \"#FF801818\": \"Falu Red\", \"#FF80341F\": \"Red Robin\", \"#FF803790\": \"Vivid Violet\", \"#FF80461B\": \"Russet\", \"#FF807E79\": \"Friar Gray\", \"#FF808000\": \"Olive\", \"#FF808080\": \"Gray\", \"#FF80B3AE\": \"Gulf Stream\", \"#FF80B3C4\": \"Glacier\", \"#FF80CCEA\": \"Seagull\", \"#FF81422C\": \"Nutmeg\", \"#FF816E71\": \"Spicy Pink\", \"#FF817377\": \"Empress\", \"#FF819885\": \"Spanish Green\", \"#FF826F65\": \"Sand Dune\", \"#FF828685\": \"Gunsmoke\", \"#FF828F72\": \"Battleship Gray\", \"#FF831923\": \"Merlot\", \"#FF837050\": \"Shadow\", \"#FF83AA5D\": \"Chelsea Cucumber\", \"#FF83D0C6\": \"Monte Carlo\", \"#FF843179\": \"Plum\", \"#FF84A0A0\": \"Granny Smith\", \"#FF8581D9\": \"Chetwode Blue\", \"#FF858470\": \"Bandicoot\", \"#FF859FAF\": \"Bali Hai\", \"#FF85C4CC\": \"Half Baked\", \"#FF860111\": \"Red Devil\", \"#FF863C3C\": \"Lotus\", \"#FF86483C\": \"Ironstone\", \"#FF864D1E\": \"Bull Shot\", \"#FF86560A\": \"Rusty Nail\", \"#FF868974\": \"Bitter\", \"#FF86949F\": \"Regent Gray\", \"#FF871550\": \"Disco\", \"#FF87756E\": \"Americano\", \"#FF877C7B\": \"Hurricane\", \"#FF878D91\": \"Oslo Gray\", \"#FF87AB39\": \"Sushi\", \"#FF885342\": \"Spicy Mix\", \"#FF886221\": \"Kumera\", \"#FF888387\": \"Suva Gray\", \"#FF888D65\": \"Avocado\", \"#FF893456\": \"Camelot\", \"#FF893843\": \"Solid Pink\", \"#FF894367\": \"Cannon Pink\", \"#FF897D6D\": \"Makara\", \"#FF8A3324\": \"Burnt Umber\", \"#FF8A73D6\": \"True V\", \"#FF8A8360\": \"Clay Creek\", \"#FF8A8389\": \"Monsoon\", \"#FF8A8F8A\": \"Stack\", \"#FF8AB9F1\": \"Jordy Blue\", \"#FF8B00FF\": \"Electric Violet\", \"#FF8B0723\": \"Monarch\", \"#FF8B6B0B\": \"Corn Harvest\", \"#FF8B8470\": \"Olive Haze\", \"#FF8B847E\": \"Schooner\", \"#FF8B8680\": \"Natural Gray\", \"#FF8B9C90\": \"Mantle\", \"#FF8B9FEE\": \"Portage\", \"#FF8BA690\": \"Envy\", \"#FF8BA9A5\": \"Cascade\", \"#FF8BE6D8\": \"Riptide\", \"#FF8C055E\": \"Cardinal Pink\", \"#FF8C472F\": \"Mule Fawn\", \"#FF8C5738\": \"Potters Clay\", \"#FF8C6495\": \"Trendy Pink\", \"#FF8D0226\": \"Paprika\", \"#FF8D3D38\": \"Sanguine Brown\", \"#FF8D3F3F\": \"Tosca\", \"#FF8D7662\": \"Cement\", \"#FF8D8974\": \"Granite Green\", \"#FF8D90A1\": \"Manatee\", \"#FF8DA8CC\": \"Polo Blue\", \"#FF8E0000\": \"Red Berry\", \"#FF8E4D1E\": \"Rope\", \"#FF8E6F70\": \"Opium\", \"#FF8E775E\": \"Domino\", \"#FF8E8190\": \"Mamba\", \"#FF8EABC1\": \"Nepal\", \"#FF8F021C\": \"Pohutukawa\", \"#FF8F3E33\": \"El Salva\", \"#FF8F4B0E\": \"Korma\", \"#FF8F8176\": \"Squirrel\", \"#FF8FD6B4\": \"Vista Blue\", \"#FF900020\": \"Burgundy\", \"#FF901E1E\": \"Old Brick\", \"#FF907874\": \"Hemp\", \"#FF907B71\": \"Almond Frost\", \"#FF908D39\": \"Sycamore\", \"#FF92000A\": \"Sangria\", \"#FF924321\": \"Cumin\", \"#FF926F5B\": \"Beaver\", \"#FF928573\": \"Stonewall\", \"#FF928590\": \"Venus\", \"#FF9370DB\": \"Medium Purple\", \"#FF93CCEA\": \"Cornflower\", \"#FF93DFB8\": \"Algae Green\", \"#FF944747\": \"Copper Rust\", \"#FF948771\": \"Arrowtown\", \"#FF950015\": \"Scarlett\", \"#FF956387\": \"Strikemaster\", \"#FF959396\": \"Mountain Mist\", \"#FF960018\": \"Carmine\", \"#FF964B00\": \"Brown\", \"#FF967059\": \"Leather\", \"#FF9678B6\": \"Purple Mountain\", \"#FF967BB6\": \"Lavender Purple\", \"#FF96A8A1\": \"Pewter\", \"#FF96BBAB\": \"Summer Green\", \"#FF97605D\": \"Au Chico\", \"#FF9771B5\": \"Wisteria\", \"#FF97CD2D\": \"Atlantis\", \"#FF983D61\": \"Vin Rouge\", \"#FF9874D3\": \"Lilac Bush\", \"#FF98777B\": \"Bazaar\", \"#FF98811B\": \"Hacienda\", \"#FF988D77\": \"Pale Oyster\", \"#FF98FF98\": \"Mint Green\", \"#FF990066\": \"Fresh Eggplant\", \"#FF991199\": \"Violet Eggplant\", \"#FF991613\": \"Tamarillo\", \"#FF991B07\": \"Totem Pole\", \"#FF996666\": \"Copper Rose\", \"#FF9966CC\": \"Amethyst\", \"#FF997A8D\": \"Mountbatten Pink\", \"#FF9999CC\": \"Blue Bell\", \"#FF9A3820\": \"Prairie Sand\", \"#FF9A6E61\": \"Toast\", \"#FF9A9577\": \"Gurkha\", \"#FF9AB973\": \"Olivine\", \"#FF9AC2B8\": \"Shadow Green\", \"#FF9B4703\": \"Oregon\", \"#FF9B9E8F\": \"Lemon Grass\", \"#FF9C3336\": \"Stiletto\", \"#FF9D5616\": \"Hawaiian Tan\", \"#FF9DACB7\": \"Gull Gray\", \"#FF9DC209\": \"Pistachio\", \"#FF9DE093\": \"Granny Smith Apple\", \"#FF9DE5FF\": \"Anakiwa\", \"#FF9E5302\": \"Chelsea Gem\", \"#FF9E5B40\": \"Sepia Skin\", \"#FF9EA587\": \"Sage\", \"#FF9EA91F\": \"Citron\", \"#FF9EB1CD\": \"Rock Blue\", \"#FF9EDEE0\": \"Morning Glory\", \"#FF9F381D\": \"Cognac\", \"#FF9F821C\": \"Reef Gold\", \"#FF9F9F9C\": \"Star Dust\", \"#FF9FA0B1\": \"Santas Gray\", \"#FF9FD7D3\": \"Sinbad\", \"#FF9FDD8C\": \"Feijoa\", \"#FFA02712\": \"Tabasco\", \"#FFA1750D\": \"Buttered Rum\", \"#FFA1ADB5\": \"Hit Gray\", \"#FFA1C50A\": \"Citrus\", \"#FFA1DAD7\": \"Aqua Island\", \"#FFA1E9DE\": \"Water Leaf\", \"#FFA2006D\": \"Flirt\", \"#FFA23B6C\": \"Rouge\", \"#FFA26645\": \"Cape Palliser\", \"#FFA2AAB3\": \"Gray Chateau\", \"#FFA2AEAB\": \"Edward\", \"#FFA3807B\": \"Pharlap\", \"#FFA397B4\": \"Amethyst Smoke\", \"#FFA3E3ED\": \"Blizzard Blue\", \"#FFA4A49D\": \"Delta\", \"#FFA4A6D3\": \"Wistful\", \"#FFA4AF6E\": \"Green Smoke\", \"#FFA50B5E\": \"Jazzberry Jam\", \"#FFA59B91\": \"Zorba\", \"#FFA5CB0C\": \"Bahia\", \"#FFA62F20\": \"Roof Terracotta\", \"#FFA65529\": \"Paarl\", \"#FFA68B5B\": \"Barley Corn\", \"#FFA69279\": \"Donkey Brown\", \"#FFA6A29A\": \"Dawn\", \"#FFA72525\": \"Mexican Red\", \"#FFA7882C\": \"Luxor Gold\", \"#FFA85307\": \"Rich Gold\", \"#FFA86515\": \"Reno Sand\", \"#FFA86B6B\": \"Coral Tree\", \"#FFA8989B\": \"Dusty Gray\", \"#FFA899E6\": \"Dull Lavender\", \"#FFA8A589\": \"Tallow\", \"#FFA8AE9C\": \"Bud\", \"#FFA8AF8E\": \"Locust\", \"#FFA8BD9F\": \"Norway\", \"#FFA8E3BD\": \"Chinook\", \"#FFA9A491\": \"Gray Olive\", \"#FFA9ACB6\": \"Aluminium\", \"#FFA9B2C3\": \"Cadet Blue\", \"#FFA9B497\": \"Schist\", \"#FFA9BDBF\": \"Tower Gray\", \"#FFA9BEF2\": \"Perano\", \"#FFA9C6C2\": \"Opal\", \"#FFAA375A\": \"Night Shadz\", \"#FFAA4203\": \"Fire\", \"#FFAA8B5B\": \"Muesli\", \"#FFAA8D6F\": \"Sandal\", \"#FFAAA5A9\": \"Shady Lady\", \"#FFAAA9CD\": \"Logan\", \"#FFAAABB7\": \"Spun Pearl\", \"#FFAAD6E6\": \"Regent St Blue\", \"#FFAAF0D1\": \"Magic Mint\", \"#FFAB0563\": \"Lipstick\", \"#FFAB3472\": \"Royal Heath\", \"#FFAB917A\": \"Sandrift\", \"#FFABA0D9\": \"Cold Purple\", \"#FFABA196\": \"Bronco\", \"#FFAC8A56\": \"Limed Oak\", \"#FFAC91CE\": \"East Side\", \"#FFAC9E22\": \"Lemon Ginger\", \"#FFACA494\": \"Napa\", \"#FFACA586\": \"Hillary\", \"#FFACA59F\": \"Cloudy\", \"#FFACACAC\": \"Silver Chalice\", \"#FFACB78E\": \"Swamp Green\", \"#FFACCBB1\": \"Spring Rain\", \"#FFACDD4D\": \"Conifer\", \"#FFACE1AF\": \"Celadon\", \"#FFAD781B\": \"Mandalay\", \"#FFADBED1\": \"Casper\", \"#FFADDFAD\": \"Moss Green\", \"#FFADE6C4\": \"Padua\", \"#FFADFF2F\": \"Green Yellow\", \"#FFAE4560\": \"Hippie Pink\", \"#FFAE6020\": \"Desert\", \"#FFAE809E\": \"Bouquet\", \"#FFAF4035\": \"Medium Carmine\", \"#FFAF4D43\": \"Apple Blossom\", \"#FFAF593E\": \"Brown Rust\", \"#FFAF8751\": \"Driftwood\", \"#FFAF8F2C\": \"Alpine\", \"#FFAF9F1C\": \"Lucky\", \"#FFAFA09E\": \"Martini\", \"#FFAFB1B8\": \"Bombay\", \"#FFAFBDD9\": \"Pigeon Post\", \"#FFB04C6A\": \"Cadillac\", \"#FFB05D54\": \"Matrix\", \"#FFB05E81\": \"Tapestry\", \"#FFB06608\": \"Mai Tai\", \"#FFB09A95\": \"Del Rio\", \"#FFB0E0E6\": \"Powder Blue\", \"#FFB0E313\": \"Inch Worm\", \"#FFB10000\": \"Bright Red\", \"#FFB14A0B\": \"Vesuvius\", \"#FFB1610B\": \"Pumpkin Skin\", \"#FFB16D52\": \"Santa Fe\", \"#FFB19461\": \"Teak\", \"#FFB1E2C1\": \"Fringy Flower\", \"#FFB1F4E7\": \"Ice Cold\", \"#FFB20931\": \"Shiraz\", \"#FFB2A1EA\": \"Biloba Flower\", \"#FFB32D29\": \"Tall Poppy\", \"#FFB35213\": \"Fiery Orange\", \"#FFB38007\": \"Hot Toddy\", \"#FFB3AF95\": \"Taupe Gray\", \"#FFB3C110\": \"La Rioja\", \"#FFB43332\": \"Well Read\", \"#FFB44668\": \"Blush\", \"#FFB4CFD3\": \"Jungle Mist\", \"#FFB57281\": \"Turkish Rose\", \"#FFB57EDC\": \"Lavender\", \"#FFB5A27F\": \"Mongoose\", \"#FFB5B35C\": \"Olive Green\", \"#FFB5D2CE\": \"Jet Stream\", \"#FFB5ECDF\": \"Cruise\", \"#FFB6316C\": \"Hibiscus\", \"#FFB69D98\": \"Thatch\", \"#FFB6B095\": \"Heathered Gray\", \"#FFB6BAA4\": \"Eagle\", \"#FFB6D1EA\": \"Spindle\", \"#FFB6D3BF\": \"Gum Leaf\", \"#FFB7410E\": \"Rust\", \"#FFB78E5C\": \"Muddy Waters\", \"#FFB7A214\": \"Sahara\", \"#FFB7A458\": \"Husk\", \"#FFB7B1B1\": \"Nobel\", \"#FFB7C3D0\": \"Heather\", \"#FFB7F0BE\": \"Madang\", \"#FFB81104\": \"Milano Red\", \"#FFB87333\": \"Copper\", \"#FFB8B56A\": \"Gimblet\", \"#FFB8C1B1\": \"Green Spring\", \"#FFB8C25D\": \"Celery\", \"#FFB8E0F9\": \"Sail\", \"#FFB94E48\": \"Chestnut\", \"#FFB95140\": \"Crail\", \"#FFB98D28\": \"Marigold\", \"#FFB9C46A\": \"Wild Willow\", \"#FFB9C8AC\": \"Rainee\", \"#FFBA0101\": \"Guardsman Red\", \"#FFBA450C\": \"Rock Spray\", \"#FFBA6F1E\": \"Bourbon\", \"#FFBA7F03\": \"Pirate Gold\", \"#FFBAB1A2\": \"Nomad\", \"#FFBAC7C9\": \"Submarine\", \"#FFBAEEF9\": \"Charlotte\", \"#FFBB3385\": \"Medium Red Violet\", \"#FFBB8983\": \"Brandy Rose\", \"#FFBBD009\": \"Rio Grande\", \"#FFBBD7C1\": \"Surf\", \"#FFBCC9C2\": \"Powder Ash\", \"#FFBD5E2E\": \"Tuscany\", \"#FFBD978E\": \"Quicksand\", \"#FFBDB1A8\": \"Silk\", \"#FFBDB2A1\": \"Malta\", \"#FFBDB3C7\": \"Chatelle\", \"#FFBDBBD7\": \"Lavender Gray\", \"#FFBDBDC6\": \"French Gray\", \"#FFBDC8B3\": \"Clay Ash\", \"#FFBDC9CE\": \"Loblolly\", \"#FFBDEDFD\": \"French Pass\", \"#FFBEA6C3\": \"London Hue\", \"#FFBEB5B7\": \"Pink Swan\", \"#FFBEDE0D\": \"Fuego\", \"#FFBF5500\": \"Rose of Sharon\", \"#FFBFB8B0\": \"Tide\", \"#FFBFBED8\": \"Blue Haze\", \"#FFBFC1C2\": \"Silver Sand\", \"#FFBFC921\": \"Key Lime Pie\", \"#FFBFDBE2\": \"Ziggurat\", \"#FFBFFF00\": \"Lime\", \"#FFC02B18\": \"Thunderbird\", \"#FFC04737\": \"Mojo\", \"#FFC08081\": \"Old Rose\", \"#FFC0C0C0\": \"Silver\", \"#FFC0D3B9\": \"Pale Leaf\", \"#FFC0D8B6\": \"Pixie Green\", \"#FFC1440E\": \"Tia Maria\", \"#FFC154C1\": \"Fuchsia Pink\", \"#FFC1A004\": \"Buddha Gold\", \"#FFC1B7A4\": \"Bison Hide\", \"#FFC1BAB0\": \"Tea\", \"#FFC1BECD\": \"Gray Suit\", \"#FFC1D7B0\": \"Sprout\", \"#FFC1F07C\": \"Sulu\", \"#FFC26B03\": \"Indochine\", \"#FFC2955D\": \"Twine\", \"#FFC2BDB6\": \"Cotton Seed\", \"#FFC2CAC4\": \"Pumice\", \"#FFC2E8E5\": \"Jagged Ice\", \"#FFC32148\": \"Maroon Flush\", \"#FFC3B091\": \"Indian Khaki\", \"#FFC3BFC1\": \"Pale Slate\", \"#FFC3C3BD\": \"Gray Nickel\", \"#FFC3CDE6\": \"Periwinkle Gray\", \"#FFC3D1D1\": \"Tiara\", \"#FFC3DDF9\": \"Tropical Blue\", \"#FFC41E3A\": \"Cardinal\", \"#FFC45655\": \"Fuzzy Wuzzy Brown\", \"#FFC45719\": \"Orange Roughy\", \"#FFC4C4BC\": \"Mist Gray\", \"#FFC4D0B0\": \"Coriander\", \"#FFC4F4EB\": \"Mint Tulip\", \"#FFC54B8C\": \"Mulberry\", \"#FFC59922\": \"Nugget\", \"#FFC5994B\": \"Tussock\", \"#FFC5DBCA\": \"Sea Mist\", \"#FFC5E17A\": \"Yellow Green\", \"#FFC62D42\": \"Brick Red\", \"#FFC6726B\": \"Contessa\", \"#FFC69191\": \"Oriental Pink\", \"#FFC6A84B\": \"Roti\", \"#FFC6C3B5\": \"Ash\", \"#FFC6C8BD\": \"Kangaroo\", \"#FFC6E610\": \"Las Palmas\", \"#FFC7031E\": \"Monza\", \"#FFC71585\": \"Red Violet\", \"#FFC7BCA2\": \"Coral Reef\", \"#FFC7C1FF\": \"Melrose\", \"#FFC7C4BF\": \"Cloud\", \"#FFC7C9D5\": \"Ghost\", \"#FFC7CD90\": \"Pine Glade\", \"#FFC7DDE5\": \"Botticelli\", \"#FFC88A65\": \"Antique Brass\", \"#FFC8A2C8\": \"Lilac\", \"#FFC8A528\": \"Hokey Pokey\", \"#FFC8AABF\": \"Lily\", \"#FFC8B568\": \"Laser\", \"#FFC8E3D7\": \"Edgewater\", \"#FFC96323\": \"Piper\", \"#FFC99415\": \"Pizza\", \"#FFC9A0DC\": \"Light Wisteria\", \"#FFC9B29B\": \"Rodeo Dust\", \"#FFC9B35B\": \"Sundance\", \"#FFC9B93B\": \"Earls Green\", \"#FFC9C0BB\": \"Silver Rust\", \"#FFC9D9D2\": \"Conch\", \"#FFC9FFA2\": \"Reef\", \"#FFC9FFE5\": \"Aero Blue\", \"#FFCA3435\": \"Flush Mahogany\", \"#FFCABB48\": \"Turmeric\", \"#FFCADCD4\": \"Paris White\", \"#FFCAE00D\": \"Bitter Lemon\", \"#FFCAE6DA\": \"Skeptic\", \"#FFCB8FA9\": \"Viola\", \"#FFCBCAB6\": \"Foggy Gray\", \"#FFCBD3B0\": \"Green Mist\", \"#FFCBDBD6\": \"Nebula\", \"#FFCC3333\": \"Persian Red\", \"#FFCC5501\": \"Burnt Orange\", \"#FFCC7722\": \"Ochre\", \"#FFCC8899\": \"Puce\", \"#FFCCCAA8\": \"Thistle Green\", \"#FFCCCCFF\": \"Periwinkle\", \"#FFCCFF00\": \"Electric Lime\", \"#FFCD5700\": \"Tenn\", \"#FFCD5C5C\": \"Chestnut Rose\", \"#FFCD8429\": \"Brandy Punch\", \"#FFCDF4FF\": \"Onahau\", \"#FFCEB98F\": \"Sorrell Brown\", \"#FFCEBABA\": \"Cold Turkey\", \"#FFCEC291\": \"Yuma\", \"#FFCEC7A7\": \"Chino\", \"#FFCFA39D\": \"Eunry\", \"#FFCFB53B\": \"Old Gold\", \"#FFCFDCCF\": \"Tasman\", \"#FFCFE5D2\": \"Surf Crest\", \"#FFCFF9F3\": \"Humming Bird\", \"#FFCFFAF4\": \"Scandal\", \"#FFD05F04\": \"Red Stage\", \"#FFD06DA1\": \"Hopbush\", \"#FFD07D12\": \"Meteor\", \"#FFD0BEF8\": \"Perfume\", \"#FFD0C0E5\": \"Prelude\", \"#FFD0F0C0\": \"Tea Green\", \"#FFD18F1B\": \"Geebung\", \"#FFD1BEA8\": \"Vanilla\", \"#FFD1C6B4\": \"Soft Amber\", \"#FFD1D2CA\": \"Celeste\", \"#FFD1D2DD\": \"Mischka\", \"#FFD1E231\": \"Pear\", \"#FFD2691E\": \"Hot Cinnamon\", \"#FFD27D46\": \"Raw Sienna\", \"#FFD29EAA\": \"Careys Pink\", \"#FFD2B48C\": \"Tan\", \"#FFD2DA97\": \"Deco\", \"#FFD2F6DE\": \"Blue Romance\", \"#FFD2F8B0\": \"Gossip\", \"#FFD3CBBA\": \"Sisal\", \"#FFD3CDC5\": \"Swirl\", \"#FFD47494\": \"Charm\", \"#FFD4B6AF\": \"Clam Shell\", \"#FFD4BF8D\": \"Straw\", \"#FFD4C4A8\": \"Akaroa\", \"#FFD4CD16\": \"Bird Flower\", \"#FFD4D7D9\": \"Iron\", \"#FFD4DFE2\": \"Geyser\", \"#FFD4E2FC\": \"Hawkes Blue\", \"#FFD54600\": \"Grenadier\", \"#FFD591A4\": \"Can Can\", \"#FFD59A6F\": \"Whiskey\", \"#FFD5D195\": \"Winter Hazel\", \"#FFD5F6E3\": \"Granny Apple\", \"#FFD69188\": \"My Pink\", \"#FFD6C562\": \"Tacha\", \"#FFD6CEF6\": \"Moon Raker\", \"#FFD6D6D1\": \"Quill Gray\", \"#FFD6FFDB\": \"Snowy Mint\", \"#FFD7837F\": \"New York Pink\", \"#FFD7C498\": \"Pavlova\", \"#FFD7D0FF\": \"Fog\", \"#FFD84437\": \"Valencia\", \"#FFD87C63\": \"Japonica\", \"#FFD8BFD8\": \"Thistle\", \"#FFD8C2D5\": \"Maverick\", \"#FFD8FCFA\": \"Foam\", \"#FFD94972\": \"Cabaret\", \"#FFD99376\": \"Burning Sand\", \"#FFD9B99B\": \"Cameo\", \"#FFD9D6CF\": \"Timberwolf\", \"#FFD9DCC1\": \"Tana\", \"#FFD9E4F5\": \"Link Water\", \"#FFD9F7FF\": \"Mabel\", \"#FFDA3287\": \"Cerise\", \"#FFDA5B38\": \"Flame Pea\", \"#FFDA6304\": \"Bamboo\", \"#FFDA6A41\": \"Red Damask\", \"#FFDA70D6\": \"Orchid\", \"#FFDA8A67\": \"Copperfield\", \"#FFDAA520\": \"Golden Grass\", \"#FFDAECD6\": \"Zanah\", \"#FFDAF4F0\": \"Iceberg\", \"#FFDAFAFF\": \"Oyster Bay\", \"#FFDB5079\": \"Cranberry\", \"#FFDB9690\": \"Petite Orchid\", \"#FFDB995E\": \"Di Serria\", \"#FFDBDBDB\": \"Alto\", \"#FFDBFFF8\": \"Frosted Mint\", \"#FFDC143C\": \"Crimson\", \"#FFDC4333\": \"Punch\", \"#FFDCB20C\": \"Galliano\", \"#FFDCB4BC\": \"Blossom\", \"#FFDCD747\": \"Wattle\", \"#FFDCD9D2\": \"Westar\", \"#FFDCDDCC\": \"Moon Mist\", \"#FFDCEDB4\": \"Caper\", \"#FFDCF0EA\": \"Swans Down\", \"#FFDDD6D5\": \"Swiss Coffee\", \"#FFDDF9F1\": \"White Ice\", \"#FFDE3163\": \"Cerise Red\", \"#FFDE6360\": \"Roman\", \"#FFDEA681\": \"Tumbleweed\", \"#FFDEBA13\": \"Gold Tips\", \"#FFDEC196\": \"Brandy\", \"#FFDECBC6\": \"Wafer\", \"#FFDED4A4\": \"Sapling\", \"#FFDED717\": \"Barberry\", \"#FFDEE5C0\": \"Beryl Green\", \"#FFDEF5FF\": \"Pattens Blue\", \"#FFDF73FF\": \"Heliotrope\", \"#FFDFBE6F\": \"Apache\", \"#FFDFCD6F\": \"Chenin\", \"#FFDFCFDB\": \"Lola\", \"#FFDFECDA\": \"Willow Brook\", \"#FFDFFF00\": \"Chartreuse Yellow\", \"#FFE0B0FF\": \"Mauve\", \"#FFE0B646\": \"Anzac\", \"#FFE0B974\": \"Harvest Gold\", \"#FFE0C095\": \"Calico\", \"#FFE0FFFF\": \"Baby Blue\", \"#FFE16865\": \"Sunglo\", \"#FFE1BC64\": \"Equator\", \"#FFE1C0C8\": \"Pink Flare\", \"#FFE1E6D6\": \"Periglacial Blue\", \"#FFE1EAD4\": \"Kidnapper\", \"#FFE1F6E8\": \"Tara\", \"#FFE25465\": \"Mandy\", \"#FFE2725B\": \"Terracotta\", \"#FFE28913\": \"Golden Bell\", \"#FFE292C0\": \"Shocking\", \"#FFE29418\": \"Dixie\", \"#FFE29CD2\": \"Light Orchid\", \"#FFE2D8ED\": \"Snuff\", \"#FFE2EBED\": \"Mystic\", \"#FFE2F3EC\": \"Apple Green\", \"#FFE30B5C\": \"Razzmatazz\", \"#FFE32636\": \"Alizarin Crimson\", \"#FFE34234\": \"Cinnabar\", \"#FFE3BEBE\": \"Cavern Pink\", \"#FFE3F5E1\": \"Peppermint\", \"#FFE3F988\": \"Mindaro\", \"#FFE47698\": \"Deep Blush\", \"#FFE49B0F\": \"Gamboge\", \"#FFE4C2D5\": \"Melanie\", \"#FFE4CFDE\": \"Twilight\", \"#FFE4D1C0\": \"Bone\", \"#FFE4D422\": \"Sunflower\", \"#FFE4D5B7\": \"Grain Brown\", \"#FFE4D69B\": \"Zombie\", \"#FFE4F6E7\": \"Frostee\", \"#FFE4FFD1\": \"Snow Flurry\", \"#FFE52B50\": \"Amaranth\", \"#FFE5841B\": \"Zest\", \"#FFE5CCC9\": \"Dust Storm\", \"#FFE5D7BD\": \"Stark White\", \"#FFE5D8AF\": \"Hampton\", \"#FFE5E0E1\": \"Bon Jour\", \"#FFE5E5E5\": \"Mercury\", \"#FFE5F9F6\": \"Polar\", \"#FFE64E03\": \"Trinidad\", \"#FFE6BE8A\": \"Gold Sand\", \"#FFE6BEA5\": \"Cashmere\", \"#FFE6D7B9\": \"Double Spanish White\", \"#FFE6E4D4\": \"Satin Linen\", \"#FFE6F2EA\": \"Harp\", \"#FFE6F8F3\": \"Off Green\", \"#FFE6FFE9\": \"Hint of Green\", \"#FFE6FFFF\": \"Tranquil\", \"#FFE77200\": \"Mango Tango\", \"#FFE7730A\": \"Christine\", \"#FFE79F8C\": \"Tony's Pink\", \"#FFE79FC4\": \"Kobi\", \"#FFE7BCB4\": \"Rose Fog\", \"#FFE7BF05\": \"Corn\", \"#FFE7CD8C\": \"Putty\", \"#FFE7ECE6\": \"Gray Nurse\", \"#FFE7F8FF\": \"Lily White\", \"#FFE7FEFF\": \"Bubbles\", \"#FFE89928\": \"Fire Bush\", \"#FFE8B9B3\": \"Shilo\", \"#FFE8E0D5\": \"Pearl Bush\", \"#FFE8EBE0\": \"Green White\", \"#FFE8F1D4\": \"Chrome White\", \"#FFE8F2EB\": \"Gin\", \"#FFE8F5F2\": \"Aqua Squeeze\", \"#FFE96E00\": \"Clementine\", \"#FFE97451\": \"Burnt Sienna\", \"#FFE97C07\": \"Tahiti Gold\", \"#FFE9CECD\": \"Oyster Pink\", \"#FFE9D75A\": \"Confetti\", \"#FFE9E3E3\": \"Ebb\", \"#FFE9F8ED\": \"Ottoman\", \"#FFE9FFFD\": \"Clear Day\", \"#FFEA88A8\": \"Carissma\", \"#FFEAAE69\": \"Porsche\", \"#FFEAB33B\": \"Tulip Tree\", \"#FFEAC674\": \"Rob Roy\", \"#FFEADAB8\": \"Raffia\", \"#FFEAE8D4\": \"White Rock\", \"#FFEAF6EE\": \"Panache\", \"#FFEAF6FF\": \"Solitude\", \"#FFEAF9F5\": \"Aqua Spring\", \"#FFEAFFFE\": \"Dew\", \"#FFEB9373\": \"Apricot\", \"#FFEBC2AF\": \"Zinnwaldite\", \"#FFECA927\": \"Fuel Yellow\", \"#FFECC54E\": \"Ronchi\", \"#FFECC7EE\": \"French Lilac\", \"#FFECCDB9\": \"Just Right\", \"#FFECE090\": \"Wild Rice\", \"#FFECEBBD\": \"Fall Green\", \"#FFECEBCE\": \"Aths Special\", \"#FFECF245\": \"Starship\", \"#FFED0A3F\": \"Red Ribbon\", \"#FFED7A1C\": \"Tango\", \"#FFED9121\": \"Carrot Orange\", \"#FFED989E\": \"Sea Pink\", \"#FFEDB381\": \"Tacao\", \"#FFEDC9AF\": \"Desert Sand\", \"#FFEDCDAB\": \"Pancho\", \"#FFEDDCB1\": \"Chamois\", \"#FFEDEA99\": \"Primrose\", \"#FFEDF5DD\": \"Frost\", \"#FFEDF5F5\": \"Aqua Haze\", \"#FFEDF6FF\": \"Zumthor\", \"#FFEDF9F1\": \"Narvik\", \"#FFEDFC84\": \"Honeysuckle\", \"#FFEE82EE\": \"Lavender Magenta\", \"#FFEEC1BE\": \"Beauty Bush\", \"#FFEED794\": \"Chalky\", \"#FFEED9C4\": \"Almond\", \"#FFEEDC82\": \"Flax\", \"#FFEEDEDA\": \"Bizarre\", \"#FFEEE3AD\": \"Double Colonial White\", \"#FFEEEEE8\": \"Cararra\", \"#FFEEEF78\": \"Manz\", \"#FFEEF0C8\": \"Tahuna Sands\", \"#FFEEF0F3\": \"Athens Gray\", \"#FFEEF3C3\": \"Tusk\", \"#FFEEF4DE\": \"Loafer\", \"#FFEEF6F7\": \"Catskill White\", \"#FFEEFDFF\": \"Twilight Blue\", \"#FFEEFF9A\": \"Jonquil\", \"#FFEEFFE2\": \"Rice Flower\", \"#FFEF863F\": \"Jaffa\", \"#FFEFEFEF\": \"Gallery\", \"#FFEFF2F3\": \"Porcelain\", \"#FFF091A9\": \"Mauvelous\", \"#FFF0D52D\": \"Golden Dream\", \"#FFF0DB7D\": \"Golden Sand\", \"#FFF0DC82\": \"Buff\", \"#FFF0E2EC\": \"Prim\", \"#FFF0E68C\": \"Khaki\", \"#FFF0EEFD\": \"Selago\", \"#FFF0EEFF\": \"Titan White\", \"#FFF0F8FF\": \"Alice Blue\", \"#FFF0FCEA\": \"Feta\", \"#FFF18200\": \"Gold Drop\", \"#FFF19BAB\": \"Wewak\", \"#FFF1E788\": \"Sahara Sand\", \"#FFF1E9D2\": \"Parchment\", \"#FFF1E9FF\": \"Blue Chalk\", \"#FFF1EEC1\": \"Mint Julep\", \"#FFF1F1F1\": \"Seashell\", \"#FFF1F7F2\": \"Saltpan\", \"#FFF1FFAD\": \"Tidal\", \"#FFF1FFC8\": \"Chiffon\", \"#FFF2552A\": \"Flamingo\", \"#FFF28500\": \"Tangerine\", \"#FFF2C3B2\": \"Mandy's Pink\", \"#FFF2F2F2\": \"Concrete\", \"#FFF2FAFA\": \"Black Squeeze\", \"#FFF34723\": \"Pomegranate\", \"#FFF3AD16\": \"Buttercup\", \"#FFF3D69D\": \"New Orleans\", \"#FFF3D9DF\": \"Vanilla Ice\", \"#FFF3E7BB\": \"Sidecar\", \"#FFF3E9E5\": \"Dawn Pink\", \"#FFF3EDCF\": \"Wheatfield\", \"#FFF3FB62\": \"Canary\", \"#FFF3FBD4\": \"Orinoco\", \"#FFF3FFD8\": \"Carla\", \"#FFF400A1\": \"Hollywood Cerise\", \"#FFF4A460\": \"Sandy brown\", \"#FFF4C430\": \"Saffron\", \"#FFF4D81C\": \"Ripe Lemon\", \"#FFF4EBD3\": \"Janna\", \"#FFF4F2EE\": \"Pampas\", \"#FFF4F4F4\": \"Wild Sand\", \"#FFF4F8FF\": \"Zircon\", \"#FFF57584\": \"Froly\", \"#FFF5C85C\": \"Cream Can\", \"#FFF5C999\": \"Manhattan\", \"#FFF5D5A0\": \"Maize\", \"#FFF5DEB3\": \"Wheat\", \"#FFF5E7A2\": \"Sandwisp\", \"#FFF5E7E2\": \"Pot Pourri\", \"#FFF5E9D3\": \"Albescent White\", \"#FFF5EDEF\": \"Soft Peach\", \"#FFF5F3E5\": \"Ecru White\", \"#FFF5F5DC\": \"Beige\", \"#FFF5FB3D\": \"Golden Fizz\", \"#FFF5FFBE\": \"Australian Mint\", \"#FFF64A8A\": \"French Rose\", \"#FFF653A6\": \"Brilliant Rose\", \"#FFF6A4C9\": \"Illusion\", \"#FFF6F0E6\": \"Merino\", \"#FFF6F7F7\": \"Black Haze\", \"#FFF6FFDC\": \"Spring Sun\", \"#FFF7468A\": \"Violet Red\", \"#FFF77703\": \"Chilean Fire\", \"#FFF77FBE\": \"Persian Pink\", \"#FFF7B668\": \"Rajah\", \"#FFF7C8DA\": \"Azalea\", \"#FFF7DBE6\": \"We Peep\", \"#FFF7F2E1\": \"Quarter Spanish White\", \"#FFF7F5FA\": \"Whisper\", \"#FFF7FAF7\": \"Snow Drift\", \"#FFF8B853\": \"Casablanca\", \"#FFF8C3DF\": \"Chantilly\", \"#FFF8D9E9\": \"Cherub\", \"#FFF8DB9D\": \"Marzipan\", \"#FFF8DD5C\": \"Energy Yellow\", \"#FFF8E4BF\": \"Givry\", \"#FFF8F0E8\": \"White Linen\", \"#FFF8F4FF\": \"Magnolia\", \"#FFF8F6F1\": \"Spring Wood\", \"#FFF8F7DC\": \"Coconut Cream\", \"#FFF8F7FC\": \"White Lilac\", \"#FFF8F8F7\": \"Desert Storm\", \"#FFF8F99C\": \"Texas\", \"#FFF8FACD\": \"Corn Field\", \"#FFF8FDD3\": \"Mimosa\", \"#FFF95A61\": \"Carnation\", \"#FFF9BF58\": \"Saffron Mango\", \"#FFF9E0ED\": \"Carousel Pink\", \"#FFF9E4BC\": \"Dairy Cream\", \"#FFF9E663\": \"Portica\", \"#FFF9EAF3\": \"Amour\", \"#FFF9F8E4\": \"Rum Swizzle\", \"#FFF9FF8B\": \"Dolly\", \"#FFF9FFF6\": \"Sugar Cane\", \"#FFFA7814\": \"Ecstasy\", \"#FFFA9D5A\": \"Tan Hide\", \"#FFFAD3A2\": \"Corvette\", \"#FFFADFAD\": \"Peach Yellow\", \"#FFFAE600\": \"Turbo\", \"#FFFAEAB9\": \"Astra\", \"#FFFAECCC\": \"Champagne\", \"#FFFAF0E6\": \"Linen\", \"#FFFAF3F0\": \"Fantasy\", \"#FFFAF7D6\": \"Citrine White\", \"#FFFAFAFA\": \"Alabaster\", \"#FFFAFDE4\": \"Hint of Yellow\", \"#FFFAFFA4\": \"Milan\", \"#FFFB607F\": \"Brink Pink\", \"#FFFB8989\": \"Geraldine\", \"#FFFBA0E3\": \"Lavender Rose\", \"#FFFBA129\": \"Sea Buckthorn\", \"#FFFBAC13\": \"Sun\", \"#FFFBAED2\": \"Lavender Pink\", \"#FFFBB2A3\": \"Rose Bud\", \"#FFFBBEDA\": \"Cupid\", \"#FFFBCCE7\": \"Classic Rose\", \"#FFFBCEB1\": \"Apricot Peach\", \"#FFFBE7B2\": \"Banana Mania\", \"#FFFBE870\": \"Marigold Yellow\", \"#FFFBE96C\": \"Festival\", \"#FFFBEA8C\": \"Sweet Corn\", \"#FFFBEC5D\": \"Candy Corn\", \"#FFFBF9F9\": \"Hint of Red\", \"#FFFBFFBA\": \"Shalimar\", \"#FFFC0FC0\": \"Shocking Pink\", \"#FFFC80A5\": \"Tickle Me Pink\", \"#FFFC9C1D\": \"Tree Poppy\", \"#FFFCC01E\": \"Lightning Yellow\", \"#FFFCD667\": \"Goldenrod\", \"#FFFCD917\": \"Candlelight\", \"#FFFCDA98\": \"Cherokee\", \"#FFFCF4D0\": \"Double Pearl Lusta\", \"#FFFCF4DC\": \"Pearl Lusta\", \"#FFFCF8F7\": \"Vista White\", \"#FFFCFBF3\": \"Bianca\", \"#FFFCFEDA\": \"Moon Glow\", \"#FFFCFFE7\": \"China Ivory\", \"#FFFCFFF9\": \"Ceramic\", \"#FFFD0E35\": \"Torch Red\", \"#FFFD5B78\": \"Wild Watermelon\", \"#FFFD7B33\": \"Crusta\", \"#FFFD7C07\": \"Sorbus\", \"#FFFD9FA2\": \"Sweet Pink\", \"#FFFDD5B1\": \"Light Apricot\", \"#FFFDD7E4\": \"Pig Pink\", \"#FFFDE1DC\": \"Cinderella\", \"#FFFDE295\": \"Golden Glow\", \"#FFFDE910\": \"Lemon\", \"#FFFDF5E6\": \"Old Lace\", \"#FFFDF6D3\": \"Half Colonial White\", \"#FFFDF7AD\": \"Drover\", \"#FFFDFEB8\": \"Pale Prim\", \"#FFFDFFD5\": \"Cumulus\", \"#FFFE28A2\": \"Persian Rose\", \"#FFFE4C40\": \"Sunset Orange\", \"#FFFE6F5E\": \"Bittersweet\", \"#FFFE9D04\": \"California\", \"#FFFEA904\": \"Yellow Sea\", \"#FFFEBAAD\": \"Melon\", \"#FFFED33C\": \"Bright Sun\", \"#FFFED85D\": \"Dandelion\", \"#FFFEDB8D\": \"Salomie\", \"#FFFEE5AC\": \"Cape Honey\", \"#FFFEEBF3\": \"Remy\", \"#FFFEEFCE\": \"Oasis\", \"#FFFEF0EC\": \"Bridesmaid\", \"#FFFEF2C7\": \"Beeswax\", \"#FFFEF3D8\": \"Bleach White\", \"#FFFEF4CC\": \"Pipi\", \"#FFFEF4DB\": \"Half Spanish White\", \"#FFFEF4F8\": \"Wisp Pink\", \"#FFFEF5F1\": \"Provincial Pink\", \"#FFFEF7DE\": \"Half Dutch White\", \"#FFFEF8E2\": \"Solitaire\", \"#FFFEF8FF\": \"White Pointer\", \"#FFFEF9E3\": \"Off Yellow\", \"#FFFEFCED\": \"Orange White\", \"#FFFF0000\": \"Red\", \"#FFFF007F\": \"Rose\", \"#FFFF00CC\": \"Purple Pizzazz\", \"#FFFF00FF\": \"Magenta / Fuchsia\", \"#FFFF2400\": \"Scarlet\", \"#FFFF3399\": \"Wild Strawberry\", \"#FFFF33CC\": \"Razzle Dazzle Rose\", \"#FFFF355E\": \"Radical Red\", \"#FFFF3F34\": \"Red Orange\", \"#FFFF4040\": \"Coral Red\", \"#FFFF4D00\": \"Vermilion\", \"#FFFF4F00\": \"International Orange\", \"#FFFF6037\": \"Outrageous Orange\", \"#FFFF6600\": \"Blaze Orange\", \"#FFFF66FF\": \"Pink Flamingo\", \"#FFFF681F\": \"Orange\", \"#FFFF69B4\": \"Hot Pink\", \"#FFFF6B53\": \"Persimmon\", \"#FFFF6FFF\": \"Blush Pink\", \"#FFFF7034\": \"Burning Orange\", \"#FFFF7518\": \"Pumpkin\", \"#FFFF7D07\": \"Flamenco\", \"#FFFF7F00\": \"Flush Orange\", \"#FFFF7F50\": \"Coral\", \"#FFFF8C69\": \"Salmon\", \"#FFFF9000\": \"Pizazz\", \"#FFFF910F\": \"West Side\", \"#FFFF91A4\": \"Pink Salmon\", \"#FFFF9933\": \"Neon Carrot\", \"#FFFF9966\": \"Atomic Tangerine\", \"#FFFF9980\": \"Vivid Tangerine\", \"#FFFF9E2C\": \"Sunshade\", \"#FFFFA000\": \"Orange Peel\", \"#FFFFA194\": \"Mona Lisa\", \"#FFFFA500\": \"Web Orange\", \"#FFFFA6C9\": \"Carnation Pink\", \"#FFFFAB81\": \"Hit Pink\", \"#FFFFAE42\": \"Yellow Orange\", \"#FFFFB0AC\": \"Cornflower Lilac\", \"#FFFFB1B3\": \"Sundown\", \"#FFFFB31F\": \"My Sin\", \"#FFFFB555\": \"Texas Rose\", \"#FFFFB7D5\": \"Cotton Candy\", \"#FFFFB97B\": \"Macaroni and Cheese\", \"#FFFFBA00\": \"Selective Yellow\", \"#FFFFBD5F\": \"Koromiko\", \"#FFFFBF00\": \"Amber\", \"#FFFFC0A8\": \"Wax Flower\", \"#FFFFC0CB\": \"Pink\", \"#FFFFC3C0\": \"Your Pink\", \"#FFFFC901\": \"Supernova\", \"#FFFFCBA4\": \"Flesh\", \"#FFFFCC33\": \"Sunglow\", \"#FFFFCC5C\": \"Golden Tainoi\", \"#FFFFCC99\": \"Peach Orange\", \"#FFFFCD8C\": \"Chardonnay\", \"#FFFFD1DC\": \"Pastel Pink\", \"#FFFFD2B7\": \"Romantic\", \"#FFFFD38C\": \"Grandis\", \"#FFFFD700\": \"Gold\", \"#FFFFD801\": \"School bus Yellow\", \"#FFFFD8D9\": \"Cosmos\", \"#FFFFDB58\": \"Mustard\", \"#FFFFDCD6\": \"Peach Schnapps\", \"#FFFFDDAF\": \"Caramel\", \"#FFFFDDCD\": \"Tuft Bush\", \"#FFFFDDCF\": \"Watusi\", \"#FFFFDDF4\": \"Pink Lace\", \"#FFFFDEAD\": \"Navajo White\", \"#FFFFDEB3\": \"Frangipani\", \"#FFFFE1DF\": \"Pippin\", \"#FFFFE1F2\": \"Pale Rose\", \"#FFFFE2C5\": \"Negroni\", \"#FFFFE5A0\": \"Cream Brulee\", \"#FFFFE5B4\": \"Peach\", \"#FFFFE6C7\": \"Tequila\", \"#FFFFE772\": \"Kournikova\", \"#FFFFEAC8\": \"Sandy Beach\", \"#FFFFEAD4\": \"Karry\", \"#FFFFEC13\": \"Broom\", \"#FFFFEDBC\": \"Colonial White\", \"#FFFFEED8\": \"Derby\", \"#FFFFEFA1\": \"Vis Vis\", \"#FFFFEFC1\": \"Egg White\", \"#FFFFEFD5\": \"Papaya Whip\", \"#FFFFEFEC\": \"Fair Pink\", \"#FFFFF0DB\": \"Peach Cream\", \"#FFFFF0F5\": \"Lavender blush\", \"#FFFFF14F\": \"Gorse\", \"#FFFFF1B5\": \"Buttermilk\", \"#FFFFF1D8\": \"Pink Lady\", \"#FFFFF1EE\": \"Forget Me Not\", \"#FFFFF1F9\": \"Tutu\", \"#FFFFF39D\": \"Picasso\", \"#FFFFF3F1\": \"Chardon\", \"#FFFFF46E\": \"Paris Daisy\", \"#FFFFF4CE\": \"Barley White\", \"#FFFFF4DD\": \"Egg Sour\", \"#FFFFF4E0\": \"Sazerac\", \"#FFFFF4E8\": \"Serenade\", \"#FFFFF4F3\": \"Chablis\", \"#FFFFF5EE\": \"Seashell Peach\", \"#FFFFF5F3\": \"Sauvignon\", \"#FFFFF6D4\": \"Milk Punch\", \"#FFFFF6DF\": \"Varden\", \"#FFFFF6F5\": \"Rose White\", \"#FFFFF8D1\": \"Baja White\", \"#FFFFF9E2\": \"Gin Fizz\", \"#FFFFF9E6\": \"Early Dawn\", \"#FFFFFACD\": \"Lemon Chiffon\", \"#FFFFFAF4\": \"Bridal Heath\", \"#FFFFFBDC\": \"Scotch Mist\", \"#FFFFFBF9\": \"Soapstone\", \"#FFFFFC99\": \"Witch Haze\", \"#FFFFFCEA\": \"Buttery White\", \"#FFFFFCEE\": \"Island Spice\", \"#FFFFFDD0\": \"Cream\", \"#FFFFFDE6\": \"Chilean Heath\", \"#FFFFFDE8\": \"Travertine\", \"#FFFFFDF3\": \"Orchid White\", \"#FFFFFDF4\": \"Quarter Pearl Lusta\", \"#FFFFFEE1\": \"Half and Half\", \"#FFFFFEEC\": \"Apricot White\", \"#FFFFFEF0\": \"Rice Cake\", \"#FFFFFEF6\": \"Black White\", \"#FFFFFEFD\": \"Romance\", \"#FFFFFF00\": \"Yellow\", \"#FFFFFF66\": \"Laser Lemon\", \"#FFFFFF99\": \"Pale Canary\", \"#FFFFFFB4\": \"Portafino\", \"#FFFFFFF0\": \"Ivory\", \"#FFFFFFFF\": \"White\", \"#FFFAEBD7\": \"Antique White\", \"#FFFFE4C4\": \"Bisque\", \"#FFFFEBCD\": \"Blanched Almond\", \"#FF8A2BE2\": \"Blue Violet Variant\", \"#FFDEB887\": \"Burly Wood\", \"#FF5F9EA0\": \"Cadet Blue Variant\", \"#FFFFF8DC\": \"Cornsilk\", \"#FF00008B\": \"Dark Blue Variant\", \"#FF008B8B\": \"Dark Cyan\", \"#FFB8860B\": \"Dark Goldenrod\", \"#FFA9A9A9\": \"Dark Gray\", \"#FF006400\": \"Dark Green\", \"#FFBDB76B\": \"Dark Khaki\", \"#FF8B008B\": \"Dark Magenta\", \"#FF556B2F\": \"Dark Olive Green\", \"#FFFF8C00\": \"Dark Orange\", \"#FF9932CC\": \"Dark Orchid\", \"#FF8B0000\": \"Dark Red\", \"#FFE9967A\": \"Dark Salmon\", \"#FF8FBC8F\": \"Dark Sea Green\", \"#FF483D8B\": \"Dark Slate Blue\", \"#FF2F4F4F\": \"Dark Slate Gray\", \"#FF00CED1\": \"Dark Turquoise\", \"#FF9400D3\": \"Dark Violet\", \"#FFFF1493\": \"Deep Pink\", \"#FF00BFFF\": \"Deep Sky Blue\", \"#FF696969\": \"Dim Gray\", \"#FFB22222\": \"Fire Brick\", \"#FFFFFAF0\": \"Floral White\", \"#FFDCDCDC\": \"Gainsboro\", \"#FFF8F8FF\": \"Ghost White\", \"#FFF0FFF0\": \"Honeydew\", \"#FF7CFC00\": \"Lawn Green\", \"#FFADD8E6\": \"Light Blue\", \"#FFF08080\": \"Light Coral\", \"#FFFAFAD2\": \"Light Goldenrod Yellow\", \"#FFD3D3D3\": \"Light Gray\", \"#FF90EE90\": \"Light Green\", \"#FFFFB6C1\": \"Light Pink\", \"#FFFFA07A\": \"Light Salmon\", \"#FF20B2AA\": \"Light Sea Green\", \"#FF87CEFA\": \"Light Sky Blue\", \"#FF778899\": \"Light Slate Gray\", \"#FFB0C4DE\": \"Light Steel Blue\", \"#FFFFFFE0\": \"Light Yellow\", \"#FF32CD32\": \"Lime Green\", \"#FF66CDAA\": \"Medium Aquamarine\", \"#FF0000CD\": \"Medium Blue\", \"#FFBA55D3\": \"Medium Orchid\", \"#FF3CB371\": \"Medium Sea Green\", \"#FF7B68EE\": \"Medium Slate Blue\", \"#FF00FA9A\": \"Medium Spring Green\", \"#FF48D1CC\": \"Medium Turquoise\", \"#FF191970\": \"Midnight Blue Variant\", \"#FFF5FFFA\": \"Mint Cream\", \"#FFFFE4E1\": \"Misty Rose\", \"#FFFFE4B5\": \"Navajo White Variant\", \"#FFFF4500\": \"Orange Red\", \"#FFEEE8AA\": \"Pale Goldenrod\", \"#FF98FB98\": \"Pale Green\", \"#FFAFEEEE\": \"Pale Turquoise\", \"#FFDB7093\": \"Pale Violet Red\", \"#FFFFDAB9\": \"Peach Puff\", \"#FF663399\": \"Rebecca Purple\", \"#FFBC8F8F\": \"Rosy Brown\", \"#FFFFFAFA\": \"Snow\", \"#FFF5F5F5\": \"White Smoke\", \"#FF9ACD32\": \"Yellow Green Variant\", \"#FF004225\": \"British Racing Green\", \"#FFFF2800\": \"Ferrari Red\", \"#FF00A550\": \"GO Green\", \"#FF2E5090\": \"Yale Blue\", \"#FFE0115F\": \"Raspberry\", \"#FF8000FF\": \"Electric Purple\", \"#FFFF8000\": \"Electric Orange\", \"#FF404040\": \"Dark Grey\", \"#FFFF3366\": \"Bright Pink\", \"#FF33FF66\": \"Bright Green Variant\", \"#FF3366FF\": \"Bright Blue\", \"#FFFFCC00\": \"Golden Yellow\", \"#FFCC6600\": \"Orange Brown\", \"#FF6600CC\": \"Purple Blue\", \"#FF00CC66\": \"Mint Green Variant\", \"#FF9900FF\": \"Violet Purple\", \"#FFFF9900\": \"Orange Yellow\", \"#FF00FF99\": \"Lime Variant\", \"#FF99FF00\": \"Yellow Green Tint\", \"#FF99FFFF\": \"Light Cyan\", \"#FF99FF99\": \"Light Green Variant\", \"#FFFF9999\": \"Light Pink Variant\", \"#FF9999FF\": \"Light Blue Variant\", \"#FF666666\": \"Medium Gray\", \"#FF111111\": \"Very Dark Gray\", \"#FF222222\": \"Charcoal\", \"#FF555555\": \"Dim Grey\", \"#FFAAAAAA\": \"Silver Gray\", \"#FFBBBBBB\": \"Light Silver\", \"#FFEEEEEE\": \"Almost White\", \"#FFFF6347\": \"Tomato\", \"#FF5D8AA8\": \"Air Force Blue\", \"#FFFF7E00\": \"Amber Sae Ece\", \"#FFFF033E\": \"American Rose\", \"#FFF2F3F4\": \"Anti Flash White\", \"#FF915C83\": \"Antique Fuchsia\", \"#FF7FFFD0\": \"Aquamarine1\", \"#FF4B5320\": \"Army Green\", \"#FF3B444B\": \"Arsenic\", \"#FFE9D66B\": \"Arylide Yellow\", \"#FFB2BEB5\": \"Ash Grey\", \"#FF6D351A\": \"Auburn\", \"#FFFDEE00\": \"Aureolin\", \"#FF6E7F80\": \"Aurometalsaurus\", \"#FFFF2052\": \"Awesome\", \"#FFA1CAF1\": \"Baby Blue Eyes\", \"#FFF4C2C2\": \"Baby Pink\", \"#FF21ABCD\": \"Ball Blue\", \"#FF848482\": \"Battleship Grey\", \"#FFBCD4E6\": \"Beau Blue\", \"#FF318CE7\": \"Bleu De France\", \"#FFFAF0BE\": \"Blond\", \"#FF6699CC\": \"Blue Gray\", \"#FF00DDDD\": \"Blue Green\", \"#FF333399\": \"Blue Pigment\", \"#FF0247FE\": \"Blue Ryb\", \"#FF79443B\": \"Bole\", \"#FFCC0000\": \"Boston University Red\", \"#FF0070FF\": \"Brandeis Blue\", \"#FF1DACD6\": \"Bright Cerulean\", \"#FFBF94E4\": \"Bright Lavender\", \"#FFD19FE8\": \"Bright Ube\", \"#FFF4BBFF\": \"Brilliant Lavender\", \"#FFFFC1CC\": \"Bubble Gum\", \"#FFBD33A4\": \"Byzantine\", \"#FF702963\": \"Byzantium\", \"#FF91A3B0\": \"Cadet Grey\", \"#FF006B3C\": \"Cadmium Green\", \"#FFED872D\": \"Cadmium Orange\", \"#FFE30022\": \"Cadmium Red\", \"#FFFFF600\": \"Cadmium Yellow\", \"#FF1E4D2B\": \"Cal Poly Pomona Green\", \"#FFA3C1AD\": \"Cambridge Blue\", \"#FFFFEF00\": \"Canary Yellow\", \"#FFFF0800\": \"Candy Apple Red\", \"#FFE4717A\": \"Candy Pink\", \"#FF592720\": \"Caput Mortuum\", \"#FFEB4C42\": \"Carmine Pink\", \"#FFFF0038\": \"Carmine Red\", \"#FFB31B1B\": \"Carnelian\", \"#FF99BADD\": \"Carolina Blue\", \"#FF92A1CF\": \"Ceil\", \"#FF4997D0\": \"Celestial Blue\", \"#FFEC3B83\": \"Cerise Pink\", \"#FFA0785A\": \"Chamoisee\", \"#FFFFB7C5\": \"Cherry Blossom Pink\", \"#FFFFA700\": \"Chrome Yellow\", \"#FF98817B\": \"Cinereous\", \"#FF9BDDFF\": \"Columbia Blue\", \"#FF002E63\": \"Cool Black\", \"#FF8C92AC\": \"Cool Grey\", \"#FFFF3800\": \"Coquelicot\", \"#FFF88379\": \"Coral Pink\", \"#FF893F45\": \"Cordovan\", \"#FFFFF8E7\": \"Cosmic Latte\", \"#FFBE0032\": \"Crimson Glory\", \"#FF00B7EB\": \"Cyan Process\", \"#FFFFFF31\": \"Daffodil\", \"#FF654321\": \"Dark Brown\", \"#FF5D3954\": \"Dark Byzantium\", \"#FFA40000\": \"Dark Candy Apple Red\", \"#FF08457E\": \"Dark Cerulean\", \"#FFC2B280\": \"Dark Champagne\", \"#FF986960\": \"Dark Chestnut\", \"#FFCD5B45\": \"Dark Coral\", \"#FF536878\": \"Dark Electric Blue\", \"#FF013220\": \"Dark Green1\", \"#FF1A2421\": \"Dark Jungle Green\", \"#FF734F96\": \"Dark Lavender\", \"#FF779ECB\": \"Dark Pastel Blue\", \"#FF03C03C\": \"Dark Pastel Green\", \"#FF966FD6\": \"Dark Pastel Purple\", \"#FFC23B22\": \"Dark Pastel Red\", \"#FFE75480\": \"Dark Pink\", \"#FF872657\": \"Dark Raspberry\", \"#FF560319\": \"Dark Scarlet\", \"#FF3C1414\": \"Dark Sienna\", \"#FF177245\": \"Dark Spring Green\", \"#FFFFA812\": \"Dark Tangerine\", \"#FFCC4E5C\": \"Dark Terra Cotta\", \"#FF00693E\": \"Dartmouth Green\", \"#FFD70A53\": \"Debian Red\", \"#FFA9203E\": \"Deep Carmine\", \"#FFEF3038\": \"Deep Carmine Pink\", \"#FFE9692C\": \"Deep Carrot Orange\", \"#FFFAD6A5\": \"Deep Champagne\", \"#FF004B49\": \"Deep Jungle Green\", \"#FF9955BB\": \"Deep Lilac\", \"#FFCC00CC\": \"Deep Magenta\", \"#FFD71868\": \"Dogwood Rose\", \"#FF85BB65\": \"Dollar Bill\", \"#FF00009C\": \"Duke Blue\", \"#FFE1A95F\": \"Earth Yellow\", \"#FFF0EAD6\": \"Eggshell\", \"#FF1034A6\": \"Egyptian Blue\", \"#FF7DF9FF\": \"Electric Blue\", \"#FFFF003F\": \"Electric Crimson\", \"#FF6F00FF\": \"Electric Indigo\", \"#FF3F00FF\": \"Electric Ultramarine\", \"#FF96C8A2\": \"Eton Blue\", \"#FFC19A6B\": \"Fallow\", \"#FFB53389\": \"Fandango\", \"#FF4D5D53\": \"Feldgrau\", \"#FF6C541E\": \"Field Drab\", \"#FFCE2029\": \"Fire Engine Red\", \"#FFFC8EAC\": \"Flamingo Pink\", \"#FFF7E98E\": \"Flavescent\", \"#FFFF004F\": \"Folly\", \"#FF014421\": \"Forest Green Traditional\", \"#FFA67B5B\": \"French Beige\", \"#FF0072BB\": \"French Blue\", \"#FFE48400\": \"Fulvous\", \"#FF6082B6\": \"Glaucous\", \"#FF996515\": \"Golden Brown\", \"#FFFCC200\": \"Golden Poppy\", \"#FFD4AF37\": \"Gold Metallic\", \"#FF66B032\": \"Green Ryb\", \"#FFA99A86\": \"Grullo\", \"#FF663854\": \"Halaya Ube\", \"#FF446CCF\": \"Han Blue\", \"#FF5218FA\": \"Han Purple\", \"#FFC90016\": \"Harvard Crimson\", \"#FF007000\": \"Hooker SGreen\", \"#FFFF1DCE\": \"Hot Magenta\", \"#FFFCF75E\": \"Icterine\", \"#FFB2EC5D\": \"Inchworm\", \"#FF138808\": \"India Green\", \"#FFE3A857\": \"Indian Yellow\", \"#FF00416A\": \"Indigo Dye\", \"#FFF4F0EC\": \"Isabelline\", \"#FF009000\": \"Islamic Green\", \"#FFD73B3E\": \"Jasper\", \"#FFBDDA57\": \"June Bud\", \"#FF4CBB17\": \"Kelly Green\", \"#FFD6CADD\": \"Languid Lavender\", \"#FF26619C\": \"Lapis Lazuli\", \"#FF087830\": \"La Salle Green\", \"#FFCF1020\": \"Lava\", \"#FF9457EB\": \"Lavender Indigo\", \"#FFB5651D\": \"Light Brown\", \"#FFE66771\": \"Light Carmine Pink\", \"#FFF984EF\": \"Light Fuchsia Pink\", \"#FFDCD0FF\": \"Light Mauve\", \"#FFB19CD9\": \"Light Pastel Purple\", \"#FFB38B6D\": \"Light Taupe\", \"#FFE68FAC\": \"Light Thulian Pink\", \"#FFFFFFED\": \"Light Yellow1\", \"#FF195905\": \"Lincoln Green\", \"#FF534B4F\": \"Liver\", \"#FFFFBD88\": \"Macaroni And Cheese\", \"#FFCA1F7B\": \"Magenta Dye\", \"#FFFF0090\": \"Magenta Process\", \"#FF6050DC\": \"Majorelle Blue\", \"#FFB03060\": \"Maroon X11\", \"#FF915F6D\": \"Mauve Taupe\", \"#FF73C2FB\": \"Maya Blue\", \"#FFE5B73B\": \"Meat Brown\", \"#FF66DDAA\": \"Medium Aquamarine1\", \"#FFE2062C\": \"Medium Candy Apple Red\", \"#FFF3E5AB\": \"Medium Champagne\", \"#FF035096\": \"Medium Electric Blue\", \"#FF1C352D\": \"Medium Jungle Green\", \"#FF0067A5\": \"Medium Persian Blue\", \"#FFC9DC87\": \"Medium Spring Bud\", \"#FF674C47\": \"Medium Taupe\", \"#FF004953\": \"Midnight Green Eagle Green\", \"#FFFFC40C\": \"Mikado Yellow\", \"#FF967117\": \"Mode Beige\", \"#FF73A9C2\": \"Moonstone Blue\", \"#FFAE0C00\": \"Mordant Red19\", \"#FF18453B\": \"Msu Green\", \"#FF21421E\": \"Myrtle\", \"#FFF6ADC6\": \"Nadeshiko Pink\", \"#FF2A8000\": \"Napier Green\", \"#FFFADA5E\": \"Naples Yellow\", \"#FFFE59C2\": \"Neon Fuchsia\", \"#FF39FF14\": \"Neon Green\", \"#FFA4DDED\": \"Non Photo Blue\", \"#FFCC7422\": \"Ocean Boat Blue\", \"#FF673147\": \"Old Mauve\", \"#FF0F0F0F\": \"Onyx\", \"#FFB784A7\": \"Opera Mauve\", \"#FFFB9902\": \"Orange Ryb\", \"#FF990000\": \"Ou Crimson Red\", \"#FF00421B\": \"Pakistan Green\", \"#FF273BE2\": \"Palatinate Blue\", \"#FF682860\": \"Palatinate Purple\", \"#FF987654\": \"Pale Brown\", \"#FF9BC4E2\": \"Pale Cerulean\", \"#FFDDADAF\": \"Pale Chestnut\", \"#FFABCDEF\": \"Pale Cornflower Blue\", \"#FFF984E5\": \"Pale Magenta\", \"#FFFADADD\": \"Pale Pink\", \"#FF96DED1\": \"Pale Robin Egg Blue\", \"#FFBC987E\": \"Pale Taupe\", \"#FF78184A\": \"Pansy Purple\", \"#FFAEC6CF\": \"Pastel Blue\", \"#FF836953\": \"Pastel Brown\", \"#FFCFCFC4\": \"Pastel Gray\", \"#FFF49AC2\": \"Pastel Magenta\", \"#FFFFB347\": \"Pastel Orange\", \"#FFB39EB5\": \"Pastel Purple\", \"#FFFF6961\": \"Pastel Red\", \"#FFCB99C9\": \"Pastel Violet\", \"#FFFDFD96\": \"Pastel Yellow\", \"#FF40404F\": \"Payne SGrey\", \"#FFE6E200\": \"Peridot\", \"#FFD99058\": \"Persian Orange\", \"#FFDF00FF\": \"Phlox\", \"#FF000F89\": \"Phthalo Blue\", \"#FF123524\": \"Phthalo Green\", \"#FFFDDDE6\": \"Piggy Pink\", \"#FFE7ACCF\": \"Pink Pearl\", \"#FFF78FA7\": \"Pink Sherbet\", \"#FFE5E4E2\": \"Platinum\", \"#FF8E4585\": \"Plum Traditional\", \"#FFFF5A36\": \"Portland Orange\", \"#FFFF8F00\": \"Princeton Orange\", \"#FF9F00C5\": \"Purple Munsell\", \"#FF50404D\": \"Purple Taupe\", \"#FFA020F0\": \"Purple X11\", \"#FFE25098\": \"Raspberry Pink\", \"#FFB3446C\": \"Raspberry Rose\", \"#FFF2003C\": \"Red Munsell\", \"#FFC40233\": \"Red Ncs\", \"#FFED1C24\": \"Red Pigment\", \"#FFFE2712\": \"Red Ryb\", \"#FF522D80\": \"Regalia\", \"#FF004040\": \"Rich Black\", \"#FFF1A7FE\": \"Rich Brilliant Lavender\", \"#FFD70040\": \"Rich Carmine\", \"#FF0892D0\": \"Rich Electric Blue\", \"#FFA76BCF\": \"Rich Lavender\", \"#FFB666D2\": \"Rich Lilac\", \"#FF414833\": \"Rifle Green\", \"#FFF9429E\": \"Rose Bonbon\", \"#FF674846\": \"Rose Ebony\", \"#FFB76E79\": \"Rose Gold\", \"#FFFF66CC\": \"Rose Pink\", \"#FFAA98A9\": \"Rose Quartz\", \"#FF905D5D\": \"Rose Taupe\", \"#FFAB4E52\": \"Rose Vale\", \"#FFD40000\": \"Rosso Corsa\", \"#FF0038A8\": \"Royal Azure\", \"#FF002366\": \"Royal Blue Traditional\", \"#FFCA2C92\": \"Royal Fuchsia\", \"#FFFF0028\": \"Ruddy\", \"#FFBB6528\": \"Ruddy Brown\", \"#FFE18E96\": \"Ruddy Pink\", \"#FFA81C07\": \"Rufous\", \"#FF00563F\": \"Sacramento State Green\", \"#FFFF6700\": \"Safety Orange Blaze Orange\", \"#FFECD540\": \"Sandstorm\", \"#FF507D2A\": \"Sap Green\", \"#FFCBA135\": \"Satin Sheen Gold\", \"#FFFFD800\": \"School Bus Yellow\", \"#FF321414\": \"Seal Brown\", \"#FF009E60\": \"Shamrock Green\", \"#FF882D17\": \"Sienna1\", \"#FFCB410B\": \"Sinopia\", \"#FF007474\": \"Skobeloff\", \"#FFCF71AF\": \"Sky Magenta\", \"#FF933D41\": \"Smokey Topaz\", \"#FF100C08\": \"Smoky Black\", \"#FF0FC0FC\": \"Spiro Disco Ball\", \"#FFFEFDFF\": \"Splashed White\", \"#FFA7FC00\": \"Spring Bud\", \"#FF23297A\": \"St.Patrick SBlue\", \"#FFF94D00\": \"Tangelo\", \"#FF006D5B\": \"Teal Green\", \"#FFDE6FA1\": \"Thulian Pink\", \"#FF0ABAB5\": \"Tiffany Blue\", \"#FFE08D3C\": \"Tiger SEye\", \"#FFEEE600\": \"Titanium Yellow\", \"#FF746CC0\": \"Toolbox\", \"#FF417DC1\": \"Tufts Blue\", \"#FFA0D6B4\": \"Turquoise Green\", \"#FF823535\": \"Tuscan Red\", \"#FF8A496B\": \"Twilight Lavender\", \"#FF0033AA\": \"Ua Blue\", \"#FFD9004C\": \"Ua Red\", \"#FF8878C3\": \"Ube\", \"#FF536895\": \"Ucla Blue\", \"#FFFFB300\": \"Ucla Gold\", \"#FF3CD070\": \"Ufo Green\", \"#FF4166F5\": \"Ultramarine Blue\", \"#FF5B92E5\": \"United Nations Blue\", \"#FF7B1113\": \"Up Maroon\", \"#FFAE2029\": \"Upsdell Red\", \"#FFE1AD21\": \"Urobilin\", \"#FFD3003F\": \"Utah Crimson\", \"#FFC5B358\": \"Vegas Gold\", \"#FF8F00FF\": \"Violet1\", \"#FF7F00FF\": \"Violet Color Wheel\", \"#FF8601AF\": \"Violet Ryb\", \"#FF922724\": \"Vivid Auburn\", \"#FF9F1D35\": \"Vivid Burgundy\", \"#FFDA1D81\": \"Vivid Cerise\", \"#FF004242\": \"Warm Black\", \"#FF645452\": \"Wenge\", \"#FFEFCC00\": \"Yellow Munsell\", \"#FFFFD300\": \"Yellow Ncs\", \"#FFFEFE33\": \"Yellow Ryb\", \"#FF0014A8\": \"Zaffre\", \"#FF2C1608\": \"Zinnwaldite Brown\", \"#FF0048BA\": \"Absolute Zero\", \"#FFB0BF1A\": \"Acid green\", \"#FF7CB9E8\": \"Aero\", \"#FFB284BE\": \"African violet\", \"#FF72A0C1\": \"Air superiority blue\", \"#FFDB2D43\": \"Alizarin\", \"#FFC46210\": \"Alloy orange\", \"#FF9F2B68\": \"Amaranth deep purple\", \"#FFF19CBB\": \"Amaranth pink\", \"#FFAB274F\": \"Amaranth purple\", \"#FF3DDC84\": \"Android green\", \"#FF665D1E\": \"Antique bronze\", \"#FF841B2D\": \"Antique ruby\", \"#FFD0FF14\": \"Arctic lime\", \"#FF4B6F44\": \"Artichoke green\", \"#FFF0FFFF\": \"Azure (X11/web color)\", \"#FF89CFF0\": \"Baby blue\", \"#FFFEFEFA\": \"Baby powder\", \"#FFFF91AF\": \"Baker-Miller pink\", \"#FFFAE7B5\": \"Banana Mania Variant\", \"#FFDA1884\": \"Barbie Pink\", \"#FF7C0A02\": \"Barn red\", \"#FF9F8170\": \"Beaver Variant\", \"#FF2E5894\": \"B'dazzled blue\", \"#FF9C2542\": \"Big dip o\\u2019ruby\", \"#FF54626F\": \"Black coral\", \"#FF3B3C36\": \"Black olive\", \"#FFBFAFB2\": \"Black Shadows\", \"#FFA57164\": \"Blast-off bronze\", \"#FFACE5EE\": \"Blizzard blue\", \"#FF660000\": \"Blood red\", \"#FF1F75FE\": \"Blue (Crayola)\", \"#FF0093AF\": \"Blue (Munsell)\", \"#FF0087BD\": \"Blue (NCS)\", \"#FF0018A8\": \"Blue (Pantone)\", \"#FFA2A2D0\": \"Blue bell\", \"#FF5DADEC\": \"Blue jeans\", \"#FF126180\": \"Blue sapphire\", \"#FF5072A7\": \"Blue yonder\", \"#FF3C69E7\": \"Bluetiful\", \"#FFDE5D83\": \"Blush Variant\", \"#FFE3DAC9\": \"Bone Variant\", \"#FFCB4154\": \"Brick red\", \"#FFD891EF\": \"Bright lilac\", \"#FFFFAA1D\": \"Bright yellow (Crayola)\", \"#FFCD7F32\": \"Bronze Variant\", \"#FFAF6E4D\": \"Brown sugar\", \"#FF7BB661\": \"Bud green\", \"#FFFFC680\": \"Buff Variant\", \"#FF800020\": \"Burgundy Variant\", \"#FFA17A74\": \"Burnished brown\", \"#FFCC5500\": \"Burnt orange\", \"#FF4B3621\": \"Caf\\u00e9 noir\", \"#FFEFBBCC\": \"Cameo pink\", \"#FF56A0D3\": \"Carolina blue\", \"#FF703642\": \"Catawba\", \"#FFC95A49\": \"Cedar Chest\", \"#FFB2FFFF\": \"Celeste Variant\", \"#FF6D9BC3\": \"Cerulean frost\", \"#FF0040FF\": \"Cerulean (RGB)\", \"#FFF7E7CE\": \"Champagne Variant\", \"#FFF1DDCF\": \"Champagne pink\", \"#FF36454F\": \"Charcoal Variant\", \"#FF80FF00\": \"Chartreuse (web)\", \"#FF954535\": \"Chestnut Variant\", \"#FFE23D28\": \"Chili red\", \"#FFAA381E\": \"Chinese red\", \"#FF856088\": \"Chinese violet\", \"#FFFFB200\": \"Chinese yellow\", \"#FFCD607E\": \"Cinnamon Satin\", \"#FFE4D00A\": \"Citrine\", \"#FF9FA91F\": \"Citron Variant\", \"#FF6F4E37\": \"Coffee Variant\", \"#FFB9D9EB\": \"Columbia Blue Variant\", \"#FFAD6F69\": \"Copper penny\", \"#FFCB6D51\": \"Copper red\", \"#FF2E2D88\": \"Cosmic cobalt\", \"#FF81613C\": \"Coyote brown\", \"#FFFFBCD9\": \"Cotton candy\", \"#FF9E1B32\": \"Crimson (UA)\", \"#FF58427C\": \"Cyber grape\", \"#FFF56FA1\": \"Cyclamen\", \"#FF543D37\": \"Dark liver (horses)\", \"#FF301934\": \"Dark purple\", \"#FF8CBED6\": \"Dark sky blue\", \"#FF4A646C\": \"Deep Space Sparkle\", \"#FF7E5E60\": \"Deep taupe\", \"#FF2243B6\": \"Denim blue\", \"#FF4A412A\": \"Drab dark brown\", \"#FFEFDFBB\": \"Dutch white\", \"#FF555D50\": \"Ebony Variant\", \"#FF1B1B1B\": \"Eerie black\", \"#FFBF00FF\": \"Electric purple\", \"#FFB48395\": \"English lavender\", \"#FFAB4B52\": \"English red\", \"#FFCC474B\": \"English vermillion\", \"#FF563C5C\": \"English violet\", \"#FF00FF40\": \"Erin\", \"#FFDE5285\": \"Fandango pink\", \"#FFE5AA70\": \"Fawn\", \"#FFFF5470\": \"Fiery rose\", \"#FF683068\": \"Finn Variant\", \"#FFE25822\": \"Flame\", \"#FF856D4D\": \"French bistre\", \"#FFFD3F92\": \"French fuchsia\", \"#FF86608E\": \"French lilac\", \"#FF9EFD38\": \"French lime\", \"#FFD473D4\": \"French mauve\", \"#FFFD6C9E\": \"French pink\", \"#FFC72C48\": \"French raspberry\", \"#FF77B5FE\": \"French sky blue\", \"#FF8806CE\": \"French violet\", \"#FFE936A7\": \"Frostbite\", \"#FF87421F\": \"Fuzzy Wuzzy\", \"#FF007F66\": \"Generic viridian\", \"#FFAB92B3\": \"Glossy grape\", \"#FF00AB66\": \"GO green\", \"#FF85754E\": \"Gold Fusion\", \"#FFFFDF00\": \"Golden yellow\", \"#FF00573F\": \"Gotham green\", \"#FF676767\": \"Granite gray\", \"#FFA8E4A0\": \"Granny Smith apple\", \"#FFBEBEBE\": \"Gray (X11 gray)\", \"#FF1CAC78\": \"Green (Crayola)\", \"#FF008000\": \"Green (web)\", \"#FF00A877\": \"Green (Munsell)\", \"#FF009F6B\": \"Green (NCS)\", \"#FF00AD43\": \"Green (Pantone)\", \"#FF1164B4\": \"Green-blue\", \"#FFA7F432\": \"Green Lizard\", \"#FF6EAEA1\": \"Green Sheen\", \"#FF2a3439\": \"Gunmetal\", \"#FFDA9100\": \"Harvest gold\", \"#FFFF7A00\": \"Heat Wave\", \"#FF006DB0\": \"Honolulu blue\", \"#FF49796B\": \"Hooker's green\", \"#FF355E3B\": \"Hunter green\", \"#FF71A6D2\": \"Iceberg Variant\", \"#FF319177\": \"Illuminating emerald\", \"#FFED2939\": \"Imperial red\", \"#FF4C516D\": \"Independence\", \"#FF6A5DFF\": \"Indigo Variant\", \"#FF130a8f\": \"International Klein Blue\", \"#FFBA160C\": \"International orange (engineering)\", \"#FFC0362C\": \"International orange (Golden Gate Bridge)\", \"#FF9D2933\": \"Japanese carmine\", \"#FF5B3256\": \"Japanese violet\", \"#FFF8DE7E\": \"Jasmine\", \"#FF343434\": \"Jet\", \"#FFF4CA16\": \"Jonquil Variant\", \"#FFE8F48C\": \"Key lime\", \"#FF6B4423\": \"Kobicha\", \"#FF512888\": \"KSU purple\", \"#FFA9BA9D\": \"Laurel green\", \"#FFE6E6FA\": \"Lavender (web)\", \"#FFC4C3D0\": \"Lavender gray\", \"#FFFFF700\": \"Lemon Variant\", \"#FFCCA01D\": \"Lemon curry\", \"#FFFDFF00\": \"Lemon glacier\", \"#FFF6EABE\": \"Lemon meringue\", \"#FFFFF44F\": \"Lemon yellow\", \"#FFFFFF9F\": \"Lemon yellow (Crayola)\", \"#FF545AA7\": \"Liberty\", \"#FFC8AD7F\": \"Light French beige\", \"#FFFED8B1\": \"Light orange\", \"#FFC5CBE1\": \"Light periwinkle\", \"#FFAE98AA\": \"Lilac Luster\", \"#FFDECC9C\": \"Lion\", \"#FF6CA0DC\": \"Little boy blue\", \"#FFB86D29\": \"Liver (dogs)\", \"#FF6C2E1F\": \"Liver (organ)\", \"#FF987456\": \"Liver chestnut\", \"#FFCC3336\": \"Madder Lake\", \"#FFD0417E\": \"Magenta (Pantone)\", \"#FF9F4576\": \"Magenta haze\", \"#FFF2E8D7\": \"Magnolia Variant\", \"#FFC04000\": \"Mahogany Variant\", \"#FFF2C649\": \"Maize (Crayola)\", \"#FF979AAA\": \"Manatee Variant\", \"#FFF37A48\": \"Mandarin\", \"#FFFDBE02\": \"Mango\", \"#FFFF8243\": \"Mango Tango Variant\", \"#FF880085\": \"Mardi Gras Variant\", \"#FFEAA221\": \"Marigold Variant\", \"#FF00488B\": \"Marian blue\", \"#FFEF98AA\": \"Mauvelous Variant\", \"#FF47ABCC\": \"Maximum blue\", \"#FF30BFBF\": \"Maximum blue green\", \"#FFACACE6\": \"Maximum blue purple\", \"#FF5E8C31\": \"Maximum green\", \"#FFD9E650\": \"Maximum green yellow\", \"#FF733380\": \"Maximum purple\", \"#FFD92121\": \"Maximum red\", \"#FFA63A79\": \"Maximum red purple\", \"#FFFAFA37\": \"Maximum yellow\", \"#FFF2BA49\": \"Maximum yellow red\", \"#FF4C9141\": \"May green\", \"#FFF8B878\": \"Mellow apricot\", \"#FFD3AF37\": \"Metallic gold\", \"#FF0A7E8C\": \"Metallic Seaweed\", \"#FF9C7C38\": \"Metallic Sunburst\", \"#FFE4007C\": \"Mexican pink\", \"#FF7ED4E6\": \"Middle blue\", \"#FF8DD9CC\": \"Middle blue green\", \"#FF8B72BE\": \"Middle blue purple\", \"#FF4D8C57\": \"Middle green\", \"#FFACBF60\": \"Middle green yellow\", \"#FFD982B5\": \"Middle purple\", \"#FFE58E73\": \"Middle red\", \"#FFA55353\": \"Middle red purple\", \"#FFFFEB00\": \"Middle yellow\", \"#FFECB176\": \"Middle yellow red\", \"#FF702670\": \"Midnight Variant\", \"#FFFFDAE9\": \"Mimi pink\", \"#FFF5E050\": \"Minion yellow\", \"#FF3EB489\": \"Mint\", \"#FFBBB477\": \"Misty moss\", \"#FFFF948E\": \"Mona Lisa Variant\", \"#FF8DA399\": \"Morning blue\", \"#FF8A9A5B\": \"Moss green\", \"#FF30BA8F\": \"Mountain Meadow Variant\", \"#FFC8509B\": \"Mulberry (Crayola)\", \"#FF317873\": \"Myrtle green\", \"#FFD65282\": \"Mystic Variant\", \"#FFAD4379\": \"Mystic maroon\", \"#FF1974D2\": \"Navy blue (Crayola)\", \"#FF4666FF\": \"Neon blue\", \"#FFFE4164\": \"Neon fuchsia\", \"#FF214FC6\": \"New Car\", \"#FF727472\": \"Nickel\", \"#FFE9FFDB\": \"Nyanza\", \"#FF43302E\": \"Old burgundy\", \"#FF353839\": \"Onyx Variant\", \"#FFA8C3BC\": \"Opal Variant\", \"#FFFF7538\": \"Orange (Crayola)\", \"#FFFF5800\": \"Orange (Pantone)\", \"#FFFF9F00\": \"Orange peel\", \"#FFFF5349\": \"Orange-red (Crayola)\", \"#FFFA5B3D\": \"Orange soda\", \"#FFF5BD1F\": \"Orange-yellow\", \"#FFF8D568\": \"Orange-yellow (Crayola)\", \"#FFF2BDCD\": \"Orchid pink\", \"#FFFF6E4A\": \"Outrageous Orange Variant\", \"#FF4A0000\": \"Oxblood\", \"#FF002147\": \"Oxford blue\", \"#FF841617\": \"OU Crimson red\", \"#FF1CA9C9\": \"Pacific blue\", \"#FF006600\": \"Pakistan green\", \"#FFBED3E5\": \"Pale aqua\", \"#FFED7A9B\": \"Pale Dogwood\", \"#FFFAE6FA\": \"Pale purple (Pantone)\", \"#FF009B7D\": \"Paolo Veronese green\", \"#FFE63E62\": \"Paradise pink\", \"#FFDEA5A4\": \"Pastel pink\", \"#FF800080\": \"Patriarch\", \"#FF1F005E\": \"Paua Variant\", \"#FFB768A2\": \"Pearly purple\", \"#FFE12C2C\": \"Permanent Geranium Lake\", \"#FFEC5800\": \"Persimmon Variant\", \"#FF470659\": \"Petunia\", \"#FF8BA8B7\": \"Pewter Blue\", \"#FF2E2787\": \"Picotee blue\", \"#FFC30B4E\": \"Pictorial carmine\", \"#FF2A2F23\": \"Pine green\", \"#FFD74894\": \"Pink (Pantone)\", \"#FFD8B2D1\": \"Pink lavender\", \"#FF93C572\": \"Pistachio Variant\", \"#FFDDA0DD\": \"Plum (web)\", \"#FF5946B2\": \"Plump Purple\", \"#FF5DA493\": \"Polished Pine\", \"#FFBE4F62\": \"Popstar\", \"#FFE1CA7A\": \"Prairie gold\", \"#FFF58025\": \"Princeton orange\", \"#FF00B9F2\": \"Process Cyan\", \"#FF644117\": \"Pullman Brown (UPS Brown)\", \"#FF6A0DAD\": \"Purple Variant\", \"#FF4E5180\": \"Purple navy\", \"#FFFE4EDA\": \"Purple pizzazz[broken anchor]\", \"#FF9C51B6\": \"Purple Plum\", \"#FF436B95\": \"Queen blue\", \"#FFE8CCD7\": \"Queen pink\", \"#FFA6A6A6\": \"Quick Silver\", \"#FF8E3A59\": \"Quinacridone magenta\", \"#FF242124\": \"Raisin black\", \"#FFFBAB60\": \"Rajah Variant\", \"#FFE30B5D\": \"Raspberry Variant\", \"#FFD68A59\": \"Raw sienna\", \"#FF826644\": \"Raw umber\", \"#FFE3256B\": \"Razzmatazz Variant\", \"#FF8D4E85\": \"Razzmic Berry\", \"#FFEE204D\": \"Red (Crayola)\", \"#FF913831\": \"Red ocher (Red ochre)[2]\", \"#FFE40078\": \"Red-purple\", \"#FFFD3A4A\": \"Red Salsa\", \"#FFC0448F\": \"Red-violet (Crayola)\", \"#FF922B3E\": \"Red-violet (Color wheel)\", \"#FFA45A52\": \"Redwood Variant\", \"#FF777696\": \"Rhythm\", \"#FF010B13\": \"Rich black (FOGRA29)\", \"#FF010203\": \"Rich black (FOGRA39)\", \"#FF444C38\": \"Rifle green\", \"#FF8A7F80\": \"Rocket metallic\", \"#FFA91101\": \"Rojo Spanish red\", \"#FF838996\": \"Roman silver\", \"#FFFF0080\": \"Rose Variant\", \"#FF9E5E6F\": \"Rose Dust\", \"#FFC21E56\": \"Rose red\", \"#FF7851A9\": \"Royal purple\", \"#FFCE4676\": \"Ruber\", \"#FFD10056\": \"Rubine red\", \"#FF9B111E\": \"Ruby red\", \"#FF679267\": \"Russian green\", \"#FF32174D\": \"Russian violet\", \"#FFDA2C43\": \"Rusty red\", \"#FF043927\": \"Sacramento State green\", \"#FF8B4513\": \"Saddle brown\", \"#FFFF7800\": \"Safety orange\", \"#FFEED202\": \"Safety yellow\", \"#FFBCB88A\": \"Sage Variant\", \"#FFFA8072\": \"Salmon Variant\", \"#FF0F52BA\": \"Sapphire Variant\", \"#FF2D5DA1\": \"Sapphire (Crayola)\", \"#FF00FFCD\": \"Sea green (Crayola)\", \"#FF612086\": \"Seance Variant\", \"#FF59260B\": \"Seal brown\", \"#FF764374\": \"Secret\", \"#FF8A795D\": \"Shadow Variant\", \"#FF778BA5\": \"Shadow blue\", \"#FF8FD400\": \"Sheen green\", \"#FFD98695\": \"Shimmering Blush\", \"#FF5FA778\": \"Shiny Shamrock\", \"#FFAAA9AD\": \"Silver (Metallic)\", \"#FFC4AEAD\": \"Silver pink\", \"#FFFF3855\": \"Sizzling Red\", \"#FFFFDB00\": \"Sizzling Sunrise\", \"#FF87CEEB\": \"Sky blue\", \"#FF6A5ACD\": \"Slate blue\", \"#FF299617\": \"Slimy green\", \"#FFC84186\": \"Smitten\", \"#FF757575\": \"Sonic silver\", \"#FF1D2951\": \"Space cadet\", \"#FF807532\": \"Spanish bistre\", \"#FF0070B8\": \"Spanish blue\", \"#FFD10047\": \"Spanish carmine\", \"#FF989898\": \"Spanish gray\", \"#FF009150\": \"Spanish green\", \"#FFE86100\": \"Spanish orange\", \"#FFF7BFBE\": \"Spanish pink\", \"#FFE60026\": \"Spanish red\", \"#FF00FFFE\": \"Spanish sky blue\", \"#FF4C2882\": \"Spanish violet\", \"#FF007F5C\": \"Spanish viridian\", \"#FF87FF2A\": \"Spring Frost\", \"#FF00FF80\": \"Spring green\", \"#FF007BB8\": \"Star command blue\", \"#FFCC33CC\": \"Steel pink\", \"#FFE4D96F\": \"Straw Variant\", \"#FFFA5053\": \"Strawberry\", \"#FFFF9361\": \"Strawberry Blonde\", \"#FF33CC33\": \"Strong Lime Green\", \"#FF914E75\": \"Sugar Plum\", \"#FFE3AB57\": \"Sunray\", \"#FFCF6BA9\": \"Super pink\", \"#FFA83731\": \"Sweet Brown\", \"#FFD44500\": \"Syracuse Orange\", \"#FFD99A6C\": \"Tan (Crayola)\", \"#FFFB4D46\": \"Tart Orange\", \"#FF8B8589\": \"Taupe gray\", \"#FF367588\": \"Teal blue\", \"#FF00FFBF\": \"Technobotanica\", \"#FFCF3476\": \"Telemagenta\", \"#FFFC89AC\": \"Tickle Me Pink Variant\", \"#FFDBD7D2\": \"Timberwolf Variant\", \"#FF86A1A9\": \"Tourmaline\", \"#FF2D68C4\": \"True Blue\", \"#FF1C05B3\": \"Trypan Blue\", \"#FF3E8EDE\": \"Tufts blue\", \"#FFDEAA88\": \"Tumbleweed Variant\", \"#FF40E0D0\": \"Turquoise Variant\", \"#FF00FFEF\": \"Turquoise blue\", \"#FF7C4848\": \"Tuscan red\", \"#FFC09999\": \"Tuscany Variant\", \"#FFFC6C85\": \"Ultra red\", \"#FF635147\": \"Umber\", \"#FFFFDDCA\": \"Unbleached silk\", \"#FF009EDB\": \"United Nations blue\", \"#FFA50021\": \"University of Pennsylvania red\", \"#FFAFDBF5\": \"Uranian blue\", \"#FF004F98\": \"USAFA blue\", \"#FF664228\": \"Van Dyke brown\", \"#FFF38FA9\": \"Vanilla ice\", \"#FF5271FF\": \"Vantg blue\", \"#FFC80815\": \"Venetian red\", \"#FF43B3AE\": \"Verdigris Variant\", \"#FFD9381E\": \"Vermilion Variant\", \"#FF963D7F\": \"Violet (crayola)\", \"#FF324AB2\": \"Violet-blue\", \"#FF766EC8\": \"Violet-blue (Crayola)\", \"#FFF75394\": \"Violet-red\", \"#FFF0599C\": \"Violet-red(PerBang)\", \"#FF009698\": \"Viridian green\", \"#FF00CCFF\": \"Vivid sky blue\", \"#FFFFA089\": \"Vivid tangerine\", \"#FF9F00FF\": \"Vivid violet\", \"#FFCEFF00\": \"Volt\", \"#FF189BCC\": \"Weezy Blue\", \"#FFA2ADD0\": \"Wild blue yonder\", \"#FFD470A2\": \"Wild orchid\", \"#FFFF43A4\": \"Wild Strawberry Variant\", \"#FFFD5800\": \"Willpower orange\", \"#FFA75502\": \"Windsor tan\", \"#FF722F37\": \"Wine\", \"#FFB11226\": \"Wine Red\", \"#FFFF007C\": \"Winter Sky\", \"#FF56887D\": \"Wintergreen Dream\", \"#FFEEED09\": \"Xanthic\", \"#FFF1B42F\": \"Xanthous\", \"#FF00356B\": \"Yale Blue Variant\", \"#FFFCE883\": \"Yellow (Crayola)\", \"#FFFEDF00\": \"Yellow (Pantone)\", \"#FFC5E384\": \"Yellow-green (Crayola)\", \"#FF30B21A\": \"Yellow-green (Color Wheel)\", \"#FFFF9505\": \"Yellow Orange (Color Wheel)\", \"#FFFFF000\": \"Yellow Rose\", \"#FFFDF8FF\": \"Zinc white\", \"#FF6C0277\": \"Zinzolin\", \"#FF39A78E\": \"Zomp\", \"#FFC93F38\": \"100 Mph\", \"#FFA59344\": \"18th Century Green\", \"#FF7B463B\": \"1975 Earth Red\", \"#FFDD3366\": \"1989 Miami Hotline\", \"#FF7FB9DD\": \"21st Century Blue\", \"#FFE56E24\": \"24 Carrot\", \"#FFDFC685\": \"24 Karat\", \"#FF330404\": \"3AM Breakup\", \"#FF225577\": \"3AM in Shibuya\", \"#FFC0A98E\": \"3AM Latte\", \"#FFD2D2C0\": \"400XT Film\", \"#FF9BAFAD\": \"5-Masted Preu\\u00dfen\", \"#FF3D1C02\": \"90% Cocoa\", \"#FF000099\": \"99 Years Blue\", \"#FFFFAABB\": \"A Brand New Day\", \"#FFD1EDEE\": \"A Certain Shade of Green\", \"#FFD3DDE4\": \"A Dime a Dozen\", \"#FF9F9978\": \"A Frond in Need\", \"#FFF2850D\": \"\\u00c0 l\\u2019Orange\", \"#FFF6ECDE\": \"A la Mode\", \"#FFFFBCC5\": \"A Lot of Love\", \"#FFBCDDB3\": \"A Mann\\u2019s Mint\", \"#FFB0B2BC\": \"A Month of Sundays\", \"#FFBFAF92\": \"A Pair of Brown Eyes\", \"#FFBB8AA7\": \"A Plum Job\", \"#FFF3E9D9\": \"A Smell of Bakery\", \"#FF88FFCC\": \"A State of Mint\", \"#FFBABCCF\": \"A Stitch in Time\", \"#FFA9BFC5\": \"A-List Blue\", \"#FF8BCECB\": \"Aaquatic Wonderland\", \"#FF00B89F\": \"Aare River\", \"#FF05A3AD\": \"Aare River Brienz\", \"#FF1150AF\": \"Aarhusian Sky\", \"#FF231F20\": \"Abaddon Black\", \"#FFF2F1E6\": \"Abaidh White\", \"#FFF8F3F6\": \"Abalone\", \"#FF94877E\": \"Abandoned Mansion\", \"#FF746E6A\": \"Abandoned Playground\", \"#FF747A8A\": \"Abandoned Spaceship\", \"#FFCD716B\": \"Abbey Pink\", \"#FFA79F92\": \"Abbey Road\", \"#FFABA798\": \"Abbey Stone\", \"#FFECE6D0\": \"Abbey White\", \"#FF4D3C2D\": \"Abbot\", \"#FF166461\": \"Abduction\", \"#FFF5ECDA\": \"Abel\", \"#FF5BA8FF\": \"\\u00c2bi Blue\", \"#FFEAE3D2\": \"Abilene Lace\", \"#FFC04641\": \"Ablaze\", \"#FFF1CBCD\": \"Abloom\", \"#FF77AA77\": \"Abomination\", \"#FFE0DDBE\": \"Above Board\", \"#FF966165\": \"Abra Cadabra\", \"#FFEEC400\": \"Abra Goldenrod\", \"#FF462E6E\": \"Abra Purple\", \"#FF15151C\": \"Absence of Light\", \"#FF7F8B30\": \"Absinthe Dreams\", \"#FF76B583\": \"Absinthe Green\", \"#FF008A60\": \"Absinthe Turquoise\", \"#FFFF9944\": \"Absolute Apricot\", \"#FF877D65\": \"Absolute Olive\", \"#FFE4CB97\": \"Abstract\", \"#FFEDE9DD\": \"Abstract White\", \"#FF629763\": \"Abundance\", \"#FFA19361\": \"Abura Green\", \"#FF8F9E9D\": \"Abyss\", \"#FF404C57\": \"Abyssal\", \"#FF1B2632\": \"Abyssal Anchorfish Blue\", \"#FF00035B\": \"Abyssal Blue\", \"#FF10246A\": \"Abyssal Depths\", \"#FF005765\": \"Abyssal Waters\", \"#FF3D5758\": \"Abysse\", \"#FF000033\": \"Abyssopelagic Water\", \"#FFDBCD64\": \"Acacia\", \"#FF486241\": \"Acacia Green\", \"#FF969C92\": \"Acacia Haze\", \"#FFA69D64\": \"Acacia Tree\", \"#FF2C3E56\": \"Academic Blue\", \"#FF79888E\": \"Academy Grey\", \"#FF525367\": \"Academy Purple\", \"#FF35312C\": \"Acadia Variant\", \"#FFE5B7BE\": \"Acadia Bloom\", \"#FF48295B\": \"Acai\", \"#FF42314B\": \"Acai Berry\", \"#FF942193\": \"Acai Juice\", \"#FF4C2F27\": \"Acajou\", \"#FF9899A7\": \"Acanthus\", \"#FF90977A\": \"Acanthus Leaf\", \"#FF75AA94\": \"Acapulco Variant\", \"#FF7FA8A7\": \"Acapulco Aqua\", \"#FF4E9AA8\": \"Acapulco Cliffs\", \"#FF65A7DD\": \"Acapulco Dive\", \"#FFEB8A44\": \"Acapulco Sun\", \"#FF208468\": \"Accent Green Blue\", \"#FFE56D00\": \"Accent Orange\", \"#FFD2C7B7\": \"Accessible Beige\", \"#FF7C94B2\": \"Accolade\", \"#FF090807\": \"Accursed Black\", \"#FFC7CCE7\": \"Ace\", \"#FF727A5F\": \"Aceituna Picante\", \"#FF4E4F48\": \"Aceto Balsamico\", \"#FF00FF22\": \"Acid\", \"#FFEFEDD7\": \"Acid Blond\", \"#FFA8C74D\": \"Acid Candy\", \"#FF11FF22\": \"Acid Drop\", \"#FF8FFE09\": \"Acid Green\", \"#FFB9DF31\": \"Acid Lime\", \"#FF00EE22\": \"Acid Pool\", \"#FF33EE66\": \"Acid Pops\", \"#FF30FF21\": \"Acid Reflux\", \"#FF4FC172\": \"Acid Sleazebag\", \"#FF9E9991\": \"Acier\", \"#FF9CA7B5\": \"Acier Tint\", \"#FFFFD8B1\": \"Acini di Pepe\", \"#FF7249D6\": \"Aconite Purple\", \"#FF9C52F2\": \"Aconite Violet\", \"#FF7F5E50\": \"Acorn\", \"#FFD48948\": \"Acorn Nut\", \"#FFB87439\": \"Acorn Spice\", \"#FFEDA740\": \"Acorn Squash\", \"#FF766B69\": \"Acoustic Brown\", \"#FFEFECE1\": \"Acoustic White\", \"#FFF8E2CA\": \"Acropolis\", \"#FFB3E1E8\": \"Across the Bay\", \"#FFFF44EE\": \"Actinic Light\", \"#FF00504B\": \"Action Green\", \"#FF00A67E\": \"Active Green\", \"#FF006F72\": \"Active Turquoise\", \"#FFBB1133\": \"Active Volcano\", \"#FFA7A6A3\": \"Actor\\u2019s Star\", \"#FF46ADF9\": \"Adamantine Blue\", \"#FF3B845E\": \"Adamite Green\", \"#FF661111\": \"Adana Kebab\\u0131\", \"#FF867E70\": \"Adaptive Shade\", \"#FF545651\": \"Addo\", \"#FF293947\": \"Adept\", \"#FF7C8286\": \"Adeptus Battlegrey\", \"#FF9E9CAB\": \"Adhesion\", \"#FFB7C1BE\": \"Adieu\", \"#FFB0B9C1\": \"Adirondack\", \"#FF74858F\": \"Adirondack Blue\", \"#FFC4AA9B\": \"Adirondack Path\", \"#FF50647F\": \"Admiral Blue\", \"#FF404E61\": \"Admiralty\", \"#FFF6F3D3\": \"Admiration\", \"#FFBD6C48\": \"Adobe\", \"#FFFB9587\": \"Adobe Avenue\", \"#FFDCBFA6\": \"Adobe Beige\", \"#FFC5703F\": \"Adobe Dusk\", \"#FFC99F93\": \"Adobe Glow\", \"#FFBA9F99\": \"Adobe Rose\", \"#FFE8DEC5\": \"Adobe Sand\", \"#FFE5C1A7\": \"Adobe South\", \"#FFC3A998\": \"Adobe Straw\", \"#FFD6AE9A\": \"Adobe Village\", \"#FFE6DBC4\": \"Adobe White\", \"#FFA99681\": \"Adolescent Rodent\", \"#FF64B5BF\": \"Adonis\", \"#FFEFBF4D\": \"Adonis Rose Yellow\", \"#FF8D8DC9\": \"Adora\", \"#FFE3BEB0\": \"Adorable\", \"#FFB8CACE\": \"Adorbs\", \"#FF014A69\": \"Adriatic\", \"#FF5C899B\": \"Adriatic Blue\", \"#FF96C6CD\": \"Adriatic Haze\", \"#FFD3ECE4\": \"Adriatic Mist\", \"#FF016081\": \"Adriatic Sea\", \"#FF4B9099\": \"Adrift\", \"#FF758181\": \"Adrift at Sea\", \"#FF93B8E3\": \"Adrift on the Nile\", \"#FF20726A\": \"Advantageous\", \"#FF34788C\": \"Adventure\", \"#FFF87858\": \"Adventure Island Pink\", \"#FF6F9FB9\": \"Adventure Isle\", \"#FF3063AF\": \"Adventure of the Seas\", \"#FFEDA367\": \"Adventure Orange\", \"#FF72664F\": \"Adventurer\", \"#FF7CAC88\": \"Adventurine\", \"#FFD8CB4B\": \"Advertisement Green\", \"#FF0081A8\": \"Advertising Blue\", \"#FF53A079\": \"Advertising Green\", \"#FFE6D3B6\": \"Aebleskiver\", \"#FF1B416F\": \"Aegean Blue\", \"#FF4C8C72\": \"Aegean Green\", \"#FF9CBBE2\": \"Aegean Mist\", \"#FF508FA2\": \"Aegean Sea\", \"#FFE48B59\": \"Aegean Sky\", \"#FF9BA0A4\": \"Aegean Splendour\", \"#FFA0B2C8\": \"Aerial View\", \"#FFC0E8D5\": \"Aero Blue Variant\", \"#FFA2C348\": \"Aerobic Fix\", \"#FFCACECD\": \"Aerodynamic\", \"#FF2B3448\": \"Aeronautic\", \"#FF355376\": \"Aerostatics\", \"#FFE3DDD3\": \"Aesthetic White\", \"#FF745085\": \"Affair Variant\", \"#FFAAFFFF\": \"Affen Turquoise\", \"#FFFED2A5\": \"Affinity\", \"#FF905E26\": \"Afghan Carpet\", \"#FFE2D7B5\": \"Afghan Hound\", \"#FFD3A95C\": \"Afghan Sand\", \"#FF78A3C2\": \"Afloat\", \"#FFC7927A\": \"African Bubinga\", \"#FF939899\": \"African Grey\", \"#FFCD4A4A\": \"African Mahogany\", \"#FF826C68\": \"African Mud\", \"#FF86714A\": \"African Plain\", \"#FFB16B40\": \"African Safari\", \"#FFCCAA88\": \"African Sand\", \"#FFB085B7\": \"African Violet\", \"#FFFD8B60\": \"After Burn\", \"#FF3C3535\": \"After Dark\", \"#FFE3F5E5\": \"After Dinner Mint\", \"#FF3D2E24\": \"After Eight\", \"#FFD6EAE8\": \"After Eight Filling\", \"#FF38393F\": \"After Midnight\", \"#FFFEC65F\": \"After Shock\", \"#FF8BC4D1\": \"After the Rain\", \"#FF33616A\": \"After the Storm\", \"#FF24246D\": \"After Work Blue\", \"#FFC95EFB\": \"After-Party Pink\", \"#FF85C0CD\": \"Aftercare\", \"#FFF2E3C5\": \"Afterglow\", \"#FFD91FFF\": \"Afterlife\", \"#FFFBCB78\": \"Afternoon\", \"#FF6E544B\": \"Afternoon Coffee\", \"#FFB7B5A4\": \"Afternoon Nap\", \"#FFD9C5A1\": \"Afternoon Stroll\", \"#FF594E40\": \"Afternoon Tea\", \"#FFBBC5DE\": \"Agapanthus\", \"#FF956A60\": \"Agate Brown\", \"#FF5A5B74\": \"Agate Violet\", \"#FF879D99\": \"Agave\", \"#FF5A6E6A\": \"Agave Frond\", \"#FF70766E\": \"Agave Green\", \"#FF879C67\": \"Agave Plant\", \"#FF886B2E\": \"Aged Antics\", \"#FF846262\": \"Aged Beech\", \"#FFD7CFC0\": \"Aged Beige\", \"#FF986456\": \"Aged Bourbon\", \"#FF87413F\": \"Aged Brandy\", \"#FF5F4947\": \"Aged Chocolate\", \"#FFE0DCDA\": \"Aged Cotton\", \"#FF898253\": \"Aged Eucalyptus\", \"#FFDD9944\": \"Aged Gouda\", \"#FFF9D5AF\": \"Aged Ivory\", \"#FF6C6956\": \"Aged Jade\", \"#FF73343A\": \"Aged Merlot\", \"#FF7E7E7E\": \"Aged Moustache Grey\", \"#FF6E6E30\": \"Aged Mustard Green\", \"#FF7E7666\": \"Aged Olive\", \"#FFCEB588\": \"Aged Papyrus\", \"#FFE9DDCA\": \"Aged Parchment\", \"#FF889999\": \"Aged Pewter\", \"#FF363E31\": \"Aged Pine\", \"#FFC99F99\": \"Aged Pink\", \"#FFFFFA86\": \"Aged Plastic Casing\", \"#FFA442A0\": \"Aged Purple\", \"#FFCCB27A\": \"Aged Seagrass\", \"#FF7A4134\": \"Aged Teak\", \"#FFA58EA9\": \"Aged\", \"#FF9D7147\": \"Aged Whisky\", \"#FFE8DECD\": \"Aged White\", \"#FF895460\": \"Aged Wine\", \"#FF6A5B4E\": \"Ageing Barrel\", \"#FFECECDF\": \"Ageless\", \"#FFE7A995\": \"Ageless Beauty\", \"#FF6FFFFF\": \"Aggressive Baby Blue\", \"#FFFF7799\": \"Aggressive Salmon\", \"#FF393121\": \"Agrax Earthshade\", \"#FF8E9683\": \"Agreeable Green\", \"#FFA17C59\": \"Agrellan Earth\", \"#FF00FBFF\": \"Agressive Aqua\", \"#FFF0E2D3\": \"Agrodolce\", \"#FF9FC5CC\": \"Agua Fr\\u00eda\", \"#FF00FA92\": \"Ahaetulla Prasina\", \"#FFC22147\": \"Ahmar Red\", \"#FF2A3149\": \"Ahoy\", \"#FF0082A1\": \"Ahoy! Blue\", \"#FF199EBD\": \"Ahriman Blue\", \"#FF274447\": \"Ai Indigo\", \"#FFECF7F7\": \"Aijiro White\", \"#FFEEE5E1\": \"Aimee\", \"#FF2E372E\": \"Aimiru Brown\", \"#FF69A3C1\": \"Air Blue\", \"#FFD7D1E9\": \"Air Castle\", \"#FFD8F2EE\": \"Air of Mint\", \"#FFF6DCD2\": \"Air-Kiss\", \"#FFA2C2D0\": \"Airborne\", \"#FFAA6C51\": \"Airbrushed Copper\", \"#FF354F58\": \"Aircraft Blue\", \"#FFD9E5E4\": \"Airflow\", \"#FF364D70\": \"Airforce\", \"#FFEDF2F8\": \"Airport\", \"#FFAEC1D4\": \"Airway\", \"#FFDAE6E9\": \"Airy\", \"#FF88CCEE\": \"Airy Blue\", \"#FFDBE0C4\": \"Airy Fields\", \"#FFFAECD9\": \"Ajo Lily\", \"#FFD3DE7B\": \"Ajwain Green\", \"#FFC3272B\": \"Akabeni\", \"#FFBC012E\": \"Akai Red\", \"#FFF07F5E\": \"Akak\\u014d Red\", \"#FFC90B42\": \"Akari Red\", \"#FFBEB29A\": \"Akaroa Variant\", \"#FFCF3A24\": \"Ake Blood\", \"#FF983FB2\": \"Akebi Purple\", \"#FFFA7B62\": \"Akebono Dawn\", \"#FF601EF9\": \"Akihabara Arcade\", \"#FFE12120\": \"Akira Red\", \"#FFD63136\": \"Akuma\", \"#FF871646\": \"Akuma\\u2019s Fury\", \"#FFB9D08B\": \"Al Green\", \"#FFA32638\": \"Alabama Crimson\", \"#FFF3E7DB\": \"Alabaster Variant\", \"#FFE9E3D2\": \"Alabaster Beauty\", \"#FFF0DEBD\": \"Alabaster Gleam\", \"#FF81585B\": \"Alaea\", \"#FF8E8C97\": \"Alaitoc Blue\", \"#FFFFAE52\": \"Alajuela Toad\", \"#FFCA9234\": \"Alameda Ochre\", \"#FF939B71\": \"Alamosa Green\", \"#FFEC0003\": \"Alarm\", \"#FF2CE335\": \"Alarming Slime\", \"#FFDADAD1\": \"Alaska\", \"#FF61A4CE\": \"Alaskan Blue\", \"#FFBCBEBC\": \"Alaskan Grey\", \"#FF7E9EC2\": \"Alaskan Ice\", \"#FFECF0E5\": \"Alaskan Mist\", \"#FF05472A\": \"Alaskan Moss\", \"#FFCDDCED\": \"Alaskan Skies\", \"#FFBAE3EB\": \"Alaskan Wind\", \"#FFCC0001\": \"Albanian Red\", \"#FF38546E\": \"Albeit\", \"#FF4F5845\": \"Albert Green\", \"#FFE1DACB\": \"Albescent\", \"#FFFBEEE5\": \"Albino\", \"#FFE7CF8C\": \"Alchemy\", \"#FFAAA492\": \"Aldabra\", \"#FFEFC1A6\": \"Alesan\", \"#FF4D7EAA\": \"Aleutian Isle\", \"#FFFF8F73\": \"Alexandria\", \"#FFFCEFC1\": \"Alexandria\\u2019s Lighthouse\", \"#FFBCD9DC\": \"Alexandrian Sky\", \"#FF598C74\": \"Alexandrite Green\", \"#FF72999E\": \"Alexandrite Teal\", \"#FFA55232\": \"Alfajor Brown\", \"#FFB3B299\": \"Alfalfa\", \"#FF78AD6D\": \"Alfalfa Bug\", \"#FF546940\": \"Alfalfa Extract\", \"#FF80365A\": \"Alfonso Olive\", \"#FF8DA98D\": \"Alga Moss\", \"#FF54AC68\": \"Algae\", \"#FF983D53\": \"Algae Red\", \"#FF21C36F\": \"Algal Fuel\", \"#FFFC5A50\": \"Algerian Coral\", \"#FF008DB0\": \"Algiers Blue\", \"#FFC1DBEC\": \"Algodon Azul\", \"#FF00A094\": \"Alhambra\", \"#FF00A465\": \"Alhambra Green\", \"#FFD4CBC4\": \"Alibi\", \"#FFC2CED2\": \"Alice White\", \"#FF415764\": \"Alien\", \"#FF0CFF0C\": \"Alien Abduction\", \"#FF84DE02\": \"Alien Armpit\", \"#FFB9CC81\": \"Alien Breed\", \"#FFF0A3BC\": \"Alien Conspiracy Pink\", \"#FF55FF33\": \"Alien Parasite\", \"#FF490648\": \"Alien Purple\", \"#FF00CC55\": \"Alienated\", \"#FF9790A4\": \"Alienator Grey\", \"#FF00728D\": \"Align\", \"#FFFEDAB9\": \"Alishan Dawn\", \"#FF676C58\": \"All About Olive\", \"#FFE6999D\": \"All Dressed Up\", \"#FFEFD7E7\": \"All Made Up\", \"#FF455454\": \"All Nighter\", \"#FFB30103\": \"All Systems Red\", \"#FF994411\": \"All the Leaves Are Brown\", \"#FFC68886\": \"All\\u2019s Ace\", \"#FF5A6A8C\": \"Allegiance\", \"#FFB4B2A9\": \"Allegory\", \"#FFB28959\": \"Allegro\", \"#FFB8C4D9\": \"Alley\", \"#FF656874\": \"Alley Cat\", \"#FF2B655F\": \"Alliance\", \"#FF886600\": \"Alligator\", \"#FFC5D17B\": \"Alligator Alley\", \"#FFEAEED7\": \"Alligator Egg\", \"#FF444411\": \"Alligator Gladiator\", \"#FFF1EAD4\": \"Allison Lace\", \"#FF9569A3\": \"Allium\", \"#FF908F92\": \"Alloy\", \"#FF1F6A7D\": \"Allports Variant\", \"#FFF8CDAA\": \"Allspice\", \"#FF8E443D\": \"Allspice Berry\", \"#FFED2E38\": \"Allura Red\", \"#FF7291B4\": \"Allure\", \"#FF9EC4CD\": \"Alluring Blue\", \"#FFF8DBC2\": \"Alluring Gesture\", \"#FFFFF7D8\": \"Alluring Light\", \"#FF977B4D\": \"Alluring Umber\", \"#FFEFE1D2\": \"Alluring White\", \"#FFBB934B\": \"Alluvial Inca\", \"#FFE8DEC9\": \"Almanack\", \"#FFC2A37E\": \"Almandine\", \"#FFF5E0C9\": \"Almeja\", \"#FFE8D6BD\": \"Almendra Tostada\", \"#FFEDDCC8\": \"Almond Variant\", \"#FFDFD5CA\": \"Almond Beige\", \"#FFE9C9A9\": \"Almond Biscuit\", \"#FFF2ACB8\": \"Almond Blossom\", \"#FFE5D3B9\": \"Almond Brittle\", \"#FFCCB590\": \"Almond Buff\", \"#FFD8C6A8\": \"Almond Butter\", \"#FFEEC87C\": \"Almond Cookie\", \"#FFF4C29F\": \"Almond Cream\", \"#FF9A8678\": \"Almond Frost Variant\", \"#FF595E4C\": \"Almond Green\", \"#FFEFE3D9\": \"Almond Icing\", \"#FFF6E3D4\": \"Almond Kiss\", \"#FFD6C0A4\": \"Almond Latte\", \"#FFD2C9B8\": \"Almond Milk\", \"#FFF4EFC1\": \"Almond Oil\", \"#FFE5DBC5\": \"Almond Paste\", \"#FFC8B960\": \"Almond Puff\", \"#FFF0E8E0\": \"Almond Roca\", \"#FFCC8888\": \"Almond Rose\", \"#FFE1CFB2\": \"Almond Silk\", \"#FFBF9E77\": \"Almond Toast\", \"#FF7D665B\": \"Almond Truffle\", \"#FFE6C9BC\": \"Almond Willow\", \"#FFD6CAB9\": \"Almond Wisp\", \"#FFFEDEBC\": \"Almondine\", \"#FFBFE5B1\": \"Almost Aloe\", \"#FFE0A787\": \"Almost Apricot\", \"#FF98DDC5\": \"Almost Aqua\", \"#FF6B7070\": \"Almost Charcoal\", \"#FF3A5457\": \"Almost Famous\", \"#FFE5D9D6\": \"Almost Mauve\", \"#FFF0E3DA\": \"Almost Pink\", \"#FFBEB0C2\": \"Almost Plum\", \"#FF6A2DED\": \"Almost Royal\", \"#FF817A60\": \"Aloe\", \"#FFC97863\": \"Aloe Blossom\", \"#FFDBE5B9\": \"Aloe Cream\", \"#FFECF1E2\": \"Aloe Essence\", \"#FF61643F\": \"Aloe Leaf\", \"#FFDCF2E3\": \"Aloe Mist\", \"#FFDFE2C9\": \"Aloe Nectar\", \"#FFB8BA87\": \"Aloe Plant\", \"#FF888B73\": \"Aloe Thorn\", \"#FF8A9480\": \"Aloe Tip\", \"#FF678779\": \"Aloe Vera\", \"#FF7E9B39\": \"Aloe Vera Green\", \"#FF848B71\": \"Aloe Vera Tea\", \"#FFD0D3B7\": \"Aloe Wash\", \"#FF6A432D\": \"Aloeswood\", \"#FF1DB394\": \"Aloha\", \"#FFE9AA91\": \"Aloha Sunset\", \"#FF000066\": \"Alone in the Dark\", \"#FFD4E2E6\": \"Aloof\", \"#FFC9C9C0\": \"Aloof Grey\", \"#FFD6C5A0\": \"Aloof Lama\", \"#FFF9EDE2\": \"Alpaca\", \"#FFD7B8A9\": \"Alpaca Mittens\", \"#FFF0BEB8\": \"Alpenglow\", \"#FF588BB4\": \"Alpha Blue\", \"#FF4D5778\": \"Alpha Centauri\", \"#FFAE8E5F\": \"Alpha Gold\", \"#FF715A45\": \"Alpha Male\", \"#FF628FB0\": \"Alpha Tango\", \"#FFFEDCBA\": \"Alphabet Soup\", \"#FFAD8A3B\": \"Alpine Variant\", \"#FFA9B4A9\": \"Alpine Air\", \"#FFBADBE6\": \"Alpine Alabaster\", \"#FFF7E0BA\": \"Alpine Berry Yellow\", \"#FFDBE4E5\": \"Alpine Blue\", \"#FF40464D\": \"Alpine Duck Grey\", \"#FF99EEFF\": \"Alpine Expedition\", \"#FF5F6D91\": \"Alpine Forget-Me-Not\", \"#FFE0DED2\": \"Alpine Frost\", \"#FFF1F2F8\": \"Alpine Goat\", \"#FF005F50\": \"Alpine Green\", \"#FFABBEC0\": \"Alpine Haze\", \"#FF449955\": \"Alpine Herbs\", \"#FF4598AB\": \"Alpine Lake\", \"#FF6AAE2E\": \"Alpine Meadow\", \"#FFDED3E6\": \"Alpine Moon\", \"#FFA6CCD8\": \"Alpine Morning Blue\", \"#FFD3DED5\": \"Alpine Peak\", \"#FF234162\": \"Alpine Race\", \"#FF051009\": \"Alpine Salamander\", \"#FF79B4CE\": \"Alpine Sky\", \"#FFA5A99A\": \"Alpine Summer\", \"#FF515A52\": \"Alpine Trail\", \"#FFFFAAA5\": \"Alright Then I Became a Princess\", \"#FFB1575F\": \"Alsike Clover Red\", \"#FFDFD5B1\": \"Alsot Olive\", \"#FF4D4C80\": \"Altar of Heaven\", \"#FF5F1A10\": \"Altar Wine\", \"#FF69656D\": \"Alter Ego\", \"#FFEFC7BE\": \"Altered Pink\", \"#FFCDC6C5\": \"Alto Variant\", \"#FF5A464B\": \"Alton Brown\", \"#FFDDBB00\": \"Alu Gobi\", \"#FF000055\": \"Alucard\\u2019s Night\", \"#FF848789\": \"Aluminium Variant\", \"#FFD2D9DB\": \"Aluminium Foil\", \"#FF8C8D91\": \"Aluminium Silver\", \"#FFADAFAF\": \"Aluminium Sky\", \"#FFA5C970\": \"Alverda\", \"#FFEBE5D2\": \"Always Almond\", \"#FFA0A667\": \"Always Apple\", \"#FFA2BACB\": \"Always Blue\", \"#FF479532\": \"Always Greener\", \"#FF11AA00\": \"Always Greener Grass\", \"#FF66778C\": \"Always Indigo\", \"#FFDFD7CB\": \"Always Neutral\", \"#FFE79DB3\": \"Always Rosey\", \"#FFF4E2D6\": \"Alyssa\", \"#FFF2D5D7\": \"Alyssum\", \"#FF417086\": \"Am I Blue?\", \"#FF016E85\": \"Amalfi\", \"#FF297CBF\": \"Amalfi Coast\", \"#FF033B9A\": \"Amalfitan Azure\", \"#FFE86EAD\": \"Amaranth Variant\", \"#FF7B2331\": \"Amaranth Blossom\", \"#FF723F89\": \"Amaranth Purple\", \"#FFD3212D\": \"Amaranth Red\", \"#FF5F4053\": \"Amaranthine\", \"#FFAB6F60\": \"Amaretto\", \"#FFC09856\": \"Amaretto Sour\", \"#FFFFF1D4\": \"Amarillo Bebito\", \"#FFFBF1C3\": \"Amarillo Yellow\", \"#FF551199\": \"Amarklor Violet\", \"#FFB85045\": \"Amaryllis\", \"#FF806568\": \"Amazing Amethyst\", \"#FFA9A797\": \"Amazing Boulder\", \"#FFBEB5A9\": \"Amazing Grey\", \"#FF017F9D\": \"Amazing Sky\", \"#FF387B54\": \"Amazon Variant\", \"#FFEBEBD6\": \"Amazon Breeze\", \"#FF505338\": \"Amazon Depths\", \"#FF31837E\": \"Amazon Drift\", \"#FF606553\": \"Amazon Foliage\", \"#FF786A4A\": \"Amazon Green\", \"#FF686747\": \"Amazon Jungle\", \"#FFECECDC\": \"Amazon Mist\", \"#FF7E8C7A\": \"Amazon Moss\", \"#FF80E45F\": \"Amazon Parrot\", \"#FF948F54\": \"Amazon Queen\", \"#FF777462\": \"Amazon River\", \"#FFE6B2B8\": \"Amazon River Dolphin\", \"#FF7E7873\": \"Amazon Stone\", \"#FFABAA97\": \"Amazon Vine\", \"#FFAA6644\": \"Amazonian\", \"#FFA7819D\": \"Amazonian Orchid\", \"#FF00C4B0\": \"Amazonite\", \"#FF0D2F5A\": \"Ambassador Blue\", \"#FFC69C6A\": \"Amber Autumn\", \"#FFD7A361\": \"Amber Brew\", \"#FFB46A4D\": \"Amber Brown\", \"#FFF6BC77\": \"Amber Dawn\", \"#FFBA843C\": \"Amber Essence\", \"#FFC79958\": \"Amber Glass\", \"#FFF29A39\": \"Amber Glow\", \"#FFC19552\": \"Amber Gold\", \"#FFAC8A41\": \"Amber Green\", \"#FFD0A592\": \"Amber Grey\", \"#FFBA9971\": \"Amber Leaf\", \"#FFEED1A5\": \"Amber Moon\", \"#FFF9D975\": \"Amber Pearl\", \"#FFB18140\": \"Amber Romance\", \"#FFC0863F\": \"Amber Sienna\", \"#FFFF9988\": \"Amber Sun\", \"#FFFFAFA3\": \"Amber Tide\", \"#FFD78B55\": \"Amber Wave\", \"#FFFAB75A\": \"Amber Yellow\", \"#FFAA8559\": \"Amberized\", \"#FFE7E7E6\": \"Ambience White\", \"#FFF8EDE0\": \"Ambient Glow\", \"#FFC2E2E7\": \"Ambient Light\", \"#FF97653F\": \"Ambit\", \"#FFDFB77D\": \"Ambitious\", \"#FFF0CB97\": \"Ambitious Amber\", \"#FFE9687E\": \"Ambitious Rose\", \"#FFC6E1BC\": \"Ambrosia\", \"#FFEEE9D3\": \"Ambrosia Coffee Cake\", \"#FFFFF4EB\": \"Ambrosia Ivory\", \"#FFF4DED3\": \"Ambrosia Salad\", \"#FF47AE9C\": \"Ambrosial Oceanside\", \"#FFBECCC2\": \"Amelia\", \"#FFFEA7BD\": \"Am\\u00e9lie\\u2019s Tutu\", \"#FF34546D\": \"America\\u2019s Cup\", \"#FF7595AB\": \"American Anthem\", \"#FFA73340\": \"American Beauty\", \"#FF3B3B6D\": \"American Blue\", \"#FF391802\": \"American Bronze\", \"#FF52352F\": \"American Mahogany\", \"#FF63403A\": \"American Milking Devon\", \"#FFFF8B00\": \"American Orange\", \"#FFFF9899\": \"American Pink\", \"#FF431C53\": \"American Purple\", \"#FFB32134\": \"American Red\", \"#FF626E71\": \"American River\", \"#FF995544\": \"American Roast\", \"#FF551B8C\": \"American Violet\", \"#FFEFDCD4\": \"American Yorkshire\", \"#FF0477B4\": \"Americana\", \"#FF463732\": \"Americano Variant\", \"#FFECEAEC\": \"Amethyst Cream\", \"#FF4F3C52\": \"Amethyst Dark Violet\", \"#FF776985\": \"Amethyst Gem\", \"#FF9085C4\": \"Amethyst Grey\", \"#FF9C89A1\": \"Amethyst Grey Violet\", \"#FFA0A0AA\": \"Amethyst Haze\", \"#FFD0C9C6\": \"Amethyst Ice\", \"#FFCFC2D1\": \"Amethyst Light Violet\", \"#FF926AA6\": \"Amethyst Orchid\", \"#FF9C8AA4\": \"Amethyst Paint\", \"#FF9B91A1\": \"Amethyst Phlox\", \"#FFBD97CF\": \"Amethyst Show\", \"#FF95879C\": \"Amethyst Smoke Variant\", \"#FFCDC7D5\": \"Amethyst Tint\", \"#FFDED1E0\": \"Ametrine Quartz\", \"#FF783E48\": \"Amfissa Olive\", \"#FFDF965B\": \"Amiable Orange\", \"#FFE6DDBE\": \"Amish Bread\", \"#FF3A5F4E\": \"Amish Green\", \"#FFA58D6D\": \"Ammonite Fossil\", \"#FFF8FBEB\": \"Amnesiac White\", \"#FFDDCC22\": \"Amok\", \"#FFEE3377\": \"Amor\", \"#FFBB22AA\": \"Amora Purple\", \"#FFAE2F48\": \"Amore\", \"#FF967D96\": \"Amorous\", \"#FFB1A7B7\": \"Amorphous Rose\", \"#FFEE5851\": \"Amour Variant\", \"#FFF5E6EA\": \"Amour Frais\", \"#FFC8C5D7\": \"Amourette\", \"#FFE0DFE8\": \"Amourette Eternelle\", \"#FF556CB5\": \"Amparo Blue\", \"#FF264C47\": \"Amphibian\", \"#FF384E47\": \"Amphitrite\", \"#FF9F8672\": \"Amphora\", \"#FF3F425A\": \"Amphystine\", \"#FF7D9D72\": \"Amulet Variant\", \"#FF01748E\": \"Amulet Gem\", \"#FF69045F\": \"Amygdala Purple\", \"#FF94568C\": \"\\u00c0n Z\\u01d0 Purple\", \"#FF00BB44\": \"Anaheim Pepper\", \"#FF8CCEEA\": \"Anakiwa Variant\", \"#FFBFB6A7\": \"Analytical Grey\", \"#FFDB304A\": \"Anarchist\", \"#FFDE0300\": \"Anarchy\", \"#FFD0C1C3\": \"Ancestral\", \"#FFDDCDA6\": \"Ancestral Gold\", \"#FFD8C7C2\": \"Ancestral Haze\", \"#FFD0D0D0\": \"Ancestral Water\", \"#FF9E90A7\": \"Ancestry Violet\", \"#FF7A5145\": \"Ancho Pepper\", \"#FF596062\": \"Anchor Grey\", \"#FF435D8B\": \"Anchor Point\", \"#FF2C3641\": \"Anchorman\", \"#FF9EBBCD\": \"Anchors Away\", \"#FF2B3441\": \"Anchors Aweigh\", \"#FF756F6B\": \"Anchovy\", \"#FFEFEEDC\": \"Ancient\", \"#FF73754C\": \"Ancient Bonsai\", \"#FFAA6611\": \"Ancient Brandy\", \"#FF9C5221\": \"Ancient Bronze\", \"#FF624147\": \"Ancient Burgundy\", \"#FF99522B\": \"Ancient Chest\", \"#FF9F543E\": \"Ancient Copper\", \"#FFDCC9A8\": \"Ancient Doeskin\", \"#FF746550\": \"Ancient Earth\", \"#FFBB9A71\": \"Ancient Fresco\", \"#FFA44769\": \"Ancient Fuchsia\", \"#FF73FDFF\": \"Ancient Ice\", \"#FFE3AF8E\": \"Ancient Inca\", \"#FFF1E6D1\": \"Ancient Ivory\", \"#FFD6D8CD\": \"Ancient Kingdom\", \"#FF837C6F\": \"Ancient Labyrinth\", \"#FF953D55\": \"Ancient Magenta\", \"#FFD1CCB9\": \"Ancient Marble\", \"#FF959651\": \"Ancient Maze\", \"#FF895B8A\": \"Ancient Murasaki Purple\", \"#FF6A5536\": \"Ancient Olive\", \"#FFDDD4CE\": \"Ancient Pages\", \"#FF898D91\": \"Ancient Pewter\", \"#FF444B43\": \"Ancient Pine\", \"#FF774411\": \"Ancient Planks\", \"#FF5A3D3F\": \"Ancient Prunus\", \"#FF922A31\": \"Ancient Red\", \"#FFCCC1AB\": \"Ancient Relic\", \"#FF70553D\": \"Ancient Root\", \"#FF843F5B\": \"Ancient Royal Banner\", \"#FFE0CAC0\": \"Ancient Ruins\", \"#FFF0E4D1\": \"Ancient Scroll\", \"#FF83696E\": \"Ancient Shelter\", \"#FF765640\": \"Ancient Spice\", \"#FFDED8D4\": \"Ancient Stone\", \"#FFE7D082\": \"Ancient Treasure\", \"#FFA09083\": \"Ancient Wonder\", \"#FFEECD00\": \"Ancient Yellow\", \"#FFAFCDC7\": \"Andean Opal Green\", \"#FF90B19D\": \"Andean Slate\", \"#FFC1A097\": \"Andes Ash\", \"#FF78D8D9\": \"Andes Sky\", \"#FF424036\": \"Andiron\", \"#FF633737\": \"Andorra\", \"#FFB58338\": \"Andouille\", \"#FFFAF0D3\": \"Andover Cream\", \"#FFA4C639\": \"Android Green\", \"#FFABCDEE\": \"Andromeda Blue\", \"#FF882D4C\": \"Anemone\", \"#FFF9EFE4\": \"Anemone White\", \"#FFBEB6AB\": \"Anew Grey\", \"#FFAFA8AE\": \"Angel Aura\", \"#FF83C5CD\": \"Angel Blue\", \"#FFDCAF9F\": \"Angel Breath\", \"#FFA3BDD3\": \"Angel Falls\", \"#FFB8ACB4\": \"Angel Finger\", \"#FFF0E8D9\": \"Angel Food\", \"#FFD7A14F\": \"Angel Food Cake\", \"#FFD2D6DB\": \"Angel Hair Silver\", \"#FFA17791\": \"Angel Heart\", \"#FFBBC6D9\": \"Angel in Blue Jeans\", \"#FFCEC7DC\": \"Angel Kiss\", \"#FFC6F0E7\": \"Angel of Death Victorious\", \"#FFE19640\": \"Angel Shark\", \"#FF9BC2D7\": \"Angel Sol\", \"#FFDDDFD8\": \"Angel Touch\", \"#FFF3DFD7\": \"Angel Wing\", \"#FFF3F1E6\": \"Angel\\u2019s Feather\", \"#FFE2D9D3\": \"Angel\\u2019s Sigh\", \"#FFF6DD34\": \"Angel\\u2019s Trumpet\", \"#FFDBDFD4\": \"Angel\\u2019s Whisper\", \"#FFF2DCD7\": \"Angelic\", \"#FFBBC6D6\": \"Angelic Blue\", \"#FFE9D9DC\": \"Angelic Choir\", \"#FFEECC33\": \"Angelic Descent\", \"#FFF4D9CB\": \"Angelic Pink\", \"#FFE3DFEA\": \"Angelic Sent\", \"#FFEBE9D8\": \"Angelic Starlet\", \"#FFF4EDE4\": \"Angelic White\", \"#FFF4EFEE\": \"Angelic Wings\", \"#FFF4DFA7\": \"Angelic Yellow\", \"#FFEACFC2\": \"Angelico\", \"#FFD8DEE7\": \"Ang\\u00e9lique Grey\", \"#FFDD0055\": \"Anger\", \"#FFDACAB1\": \"Angora\", \"#FFEDE7DE\": \"Angora Goat\", \"#FFEBDFEA\": \"Angora Pink\", \"#FFD9D6C3\": \"Angora Whisper\", \"#FFF4F6EC\": \"Angraecum Orchid\", \"#FFF04E45\": \"Angry Flamingo\", \"#FF9799A6\": \"Angry Gargoyle\", \"#FFEEBBBB\": \"Angry Ghost\", \"#FF37503D\": \"Angry Gremlin\", \"#FFEE9911\": \"Angry Hornet\", \"#FF4E6665\": \"Angry Ocean\", \"#FFFFCC55\": \"Angry Pasta\", \"#FFD82029\": \"Angry Tomato\", \"#FFB9ABAD\": \"Aniline Mauve\", \"#FFF4E6CE\": \"Animal Cracker\", \"#FFBCC09E\": \"Animal Kingdom\", \"#FFED9080\": \"Animated Coral\", \"#FFCCC14D\": \"Anime\", \"#FFFF7A83\": \"Anime Blush\", \"#FFE5D5AE\": \"Anise Biscotti\", \"#FFF4E3B5\": \"Anise Flower\", \"#FFB0AC98\": \"Anise Grey Yellow\", \"#FFCDA741\": \"Aniseed\", \"#FF8CB684\": \"Aniseed Leaf Green\", \"#FF91A0B7\": \"Anita\", \"#FFCDCA9F\": \"Anjou Pear\", \"#FFF5D547\": \"Anna Banana\", \"#FF8C5341\": \"Annatto\", \"#FF6B475D\": \"Annis\", \"#FFE17861\": \"Annular\", \"#FF89A4CD\": \"Anode\", \"#FFBDBFC8\": \"Anon\", \"#FFDADCD3\": \"Anonymous\", \"#FFC7BBA4\": \"Another One Bites the Dust\", \"#FF016884\": \"Ansel\", \"#FFB05D4A\": \"Ant Red\", \"#FF4B789B\": \"Antarctic Blue\", \"#FF0000BB\": \"Antarctic Circle\", \"#FF35383F\": \"Antarctic Deep\", \"#FFEDDEE6\": \"Antarctic Love\", \"#FFBFD2D0\": \"Antarctica\", \"#FFB19664\": \"Antelope\", \"#FF7F684E\": \"Anthill\", \"#FF28282D\": \"Anthracite\", \"#FF3D475E\": \"Anthracite Blue\", \"#FF373F42\": \"Anthracite Grey\", \"#FF73293B\": \"Anthracite Red\", \"#FFBEBDBC\": \"Anti Rainbow Grey\", \"#FF256D73\": \"Antigua\", \"#FF06B1C4\": \"Antigua Blue\", \"#FF83C2CD\": \"Antigua Sand\", \"#FFFFE7C8\": \"Antigua Sunrise\", \"#FFBDDFD8\": \"Antiguan\", \"#FF3B5E8D\": \"Antilles Blue\", \"#FF8AA277\": \"Antilles Garden\", \"#FFC7C8C1\": \"Antimony\", \"#FF946644\": \"Antiquarian Brown\", \"#FFBA8A45\": \"Antiquarian Gold\", \"#FF8D8AA0\": \"Antiquate\", \"#FF8B846D\": \"Antique\", \"#FF9C867B\": \"Antique Bear\", \"#FF926B43\": \"Antique Bourbon\", \"#FF6C461F\": \"Antique Brass Variant\", \"#FF553F2D\": \"Antique Brown\", \"#FFE4D2BB\": \"Antique Buff\", \"#FF352126\": \"Antique Burgundy\", \"#FFF0BAA4\": \"Antique Cameo\", \"#FFF4E1D6\": \"Antique Candle Light\", \"#FFA7856D\": \"Antique Chest\", \"#FFFDF6E7\": \"Antique China\", \"#FFB5B8A8\": \"Antique Coin\", \"#FF9E6649\": \"Antique Copper\", \"#FFFFC7B0\": \"Antique Coral\", \"#FF7E6C5F\": \"Antique Earth\", \"#FF8E5E5E\": \"Antique Garnet\", \"#FFB59E5F\": \"Antique Gold\", \"#FF2C6E62\": \"Antique Green\", \"#FF69576D\": \"Antique Grey\", \"#FFCDBACB\": \"Antique Heather\", \"#FFB39355\": \"Antique Honey\", \"#FFB07F9E\": \"Antique Hot Pink\", \"#FF7B7062\": \"Antique Iron\", \"#FFF9ECD3\": \"Antique Ivory\", \"#FFC5BBA8\": \"Antique Kilim\", \"#FFFDF2DB\": \"Antique Lace\", \"#FF9E8E7E\": \"Antique Leather\", \"#FFFAEEDB\": \"Antique Linen\", \"#FFF1E9D7\": \"Antique Marble\", \"#FFBBB0B1\": \"Antique Mauve\", \"#FF7A973B\": \"Antique Moss\", \"#FFF4F0E8\": \"Antique Paper\", \"#FFEAD8C1\": \"Antique Parchment\", \"#FFBAC5BB\": \"Antique Patina\", \"#FFEBD7CB\": \"Antique Pearl\", \"#FF957747\": \"Antique Penny\", \"#FFE8E3E3\": \"Antique Petal\", \"#FFC27A74\": \"Antique Pink\", \"#FF98211A\": \"Antique Port Wine\", \"#FF7D4F51\": \"Antique Red\", \"#FF997165\": \"Antique Rose\", \"#FF72393F\": \"Antique Rosewood\", \"#FF978466\": \"Antique Royal Gold\", \"#FF918E8C\": \"Antique Silver\", \"#FF6E7173\": \"Antique Tin\", \"#FFBB9973\": \"Antique Treasure\", \"#FF004E4E\": \"Antique Turquoise\", \"#FF928BA6\": \"Antique Viola\", \"#FFECE6D5\": \"Antique White Variant\", \"#FFF3D3A1\": \"Antique Wicker Basket\", \"#FFB6A38D\": \"Antique Windmill\", \"#FFBDCCC1\": \"Antiqued Aqua\", \"#FF8A6C57\": \"Antiquities\", \"#FFC1A87C\": \"Antiquity\", \"#FF957A76\": \"Antler\", \"#FF864F3E\": \"Antler Moth\", \"#FFC0AD96\": \"Antler Velvet\", \"#FFB09391\": \"Antoinette\", \"#FFE7C2B4\": \"Antoinette Pink\", \"#FF312231\": \"Anubis Black\", \"#FFC68E3F\": \"Anzac Variant\", \"#FF00800C\": \"Ao\", \"#FF27B692\": \"Aoife\\u2019s Green\", \"#FF006442\": \"Aotake Bamboo\", \"#FF31827B\": \"Apatite Blue\", \"#FFBBFF99\": \"Apatite Crystal Green\", \"#FF8A843B\": \"Apeland\", \"#FFE35A63\": \"Aphrodisiac\", \"#FF45E9C1\": \"Aphrodite Aqua\", \"#FFEEFFFF\": \"Aphrodite\\u2019s Pearls\", \"#FFDD14AB\": \"Aphroditean Fuchsia\", \"#FFB5D0A2\": \"Apium\", \"#FF284FBD\": \"Apnea Dive\", \"#FFF4711E\": \"Apocalyptic Orange\", \"#FF99CCFF\": \"Apocyan\", \"#FFC8C4C2\": \"Apollo\", \"#FF748697\": \"Apollo Bay\", \"#FFE5E5E1\": \"Apollo Landing\", \"#FFDDFFFF\": \"Apollo\\u2019s White\", \"#FFC6D6C4\": \"Apothecary Jar\", \"#FF848B80\": \"Appalachian Forest\", \"#FFCFB989\": \"Appalachian Trail\", \"#FF876E52\": \"Appaloosa Spots\", \"#FFC2BCA9\": \"Apparition\", \"#FF66AA00\": \"Appetising Asparagus\", \"#FFB1E5AA\": \"Appetite\", \"#FF858C9B\": \"Applause Please\", \"#FFDDBCA0\": \"Apple Blossom Variant\", \"#FFD5E69D\": \"Apple Bob\", \"#FF9C6757\": \"Apple Brown Betty\", \"#FF8E5151\": \"Apple Butter\", \"#FFF81404\": \"Apple Cherry\", \"#FFDA995F\": \"Apple Cider\", \"#FFA67950\": \"Apple Cinnamon\", \"#FFF4EED8\": \"Apple Core\", \"#FFB8D7A6\": \"Apple Cream\", \"#FFE19C55\": \"Apple Crisp\", \"#FFFEE5C9\": \"Apple Crunch\", \"#FFDBDBBC\": \"Apple Cucumber\", \"#FFFDDFAE\": \"Apple Custard\", \"#FFEDF4EB\": \"Apple Flower\", \"#FFCC9350\": \"Apple Fritter\", \"#FF4B4247\": \"Apple Herb Black\", \"#FFA69F8D\": \"Apple Hill\", \"#FFBDD0B1\": \"Apple Ice\", \"#FFBFCA87\": \"Apple II Beige\", \"#FF93D6BF\": \"Apple II Blue\", \"#FFDA680E\": \"Apple II Chocolate\", \"#FF04650D\": \"Apple II Green\", \"#FF25C40D\": \"Apple II Lime\", \"#FFDC41F1\": \"Apple II Magenta\", \"#FFAC667B\": \"Apple II Rose\", \"#FFDDAABB\": \"Apple Infusion\", \"#FF8B974E\": \"Apple Jack\", \"#FFBDAD13\": \"Apple Jade\", \"#FFF9FDD9\": \"Apple Martini\", \"#FF93C96A\": \"Apple Orchard\", \"#FFCAAB94\": \"Apple Pie\", \"#FF883E3F\": \"Apple Polish\", \"#FFF4EBD2\": \"Apple Sauce\", \"#FFC2A377\": \"Apple Sauce Cake\", \"#FFA77C53\": \"Apple Seed\", \"#FFF1F0BF\": \"Apple Slice\", \"#FFE8C194\": \"Apple Turnover\", \"#FFEA8386\": \"Apple Valley\", \"#FFB59F62\": \"Apple Wine\", \"#FF903F45\": \"Apple-a-Day\", \"#FF8AC479\": \"Applegate\", \"#FFCDEACD\": \"Applemint\", \"#FFF3F5E9\": \"Applemint Soda\", \"#FF929637\": \"Appletini\", \"#FF6EB478\": \"Appleton\", \"#FF8B97A5\": \"Approaching Dusk\", \"#FF039487\": \"Approval Green\", \"#FFCED5E4\": \"Apr\\u00e8s-Ski\", \"#FFFFB16D\": \"Apricot Variant\", \"#FFFEC382\": \"Apricot Appeal\", \"#FFFEAEA5\": \"Apricot Blush\", \"#FFBF6553\": \"Apricot Brandy\", \"#FFCC7E5B\": \"Apricot Brown\", \"#FFCD7E4D\": \"Apricot Buff\", \"#FFFFC782\": \"Apricot Butter\", \"#FFDA8923\": \"Apricot Chicken\", \"#FFF1BD89\": \"Apricot Cream\", \"#FFFFBB80\": \"Apricot Flower\", \"#FFEEDED8\": \"Apricot Foam\", \"#FFFFD2A0\": \"Apricot Fool\", \"#FFF3CFB7\": \"Apricot Freeze\", \"#FFFFC7A0\": \"Apricot Froth\", \"#FFF5D7AF\": \"Apricot Gelato\", \"#FFEEAA22\": \"Apricot Glazed Chicken\", \"#FFFFCE79\": \"Apricot Glow\", \"#FFFFAAAA\": \"Apricot Haze\", \"#FFFFF6E9\": \"Apricot Ice\", \"#FFF8CC9C\": \"Apricot Ice Cream\", \"#FFFBBE99\": \"Apricot Iced Tea\", \"#FFE2C3A6\": \"Apricot Illusion\", \"#FFEEA771\": \"Apricot Jam\", \"#FFFECFB5\": \"Apricot Lily\", \"#FFB47756\": \"Apricot Mix\", \"#FFC37248\": \"Apricot Mocha\", \"#FFFCDFAF\": \"Apricot Mousse\", \"#FFECAA79\": \"Apricot Nectar\", \"#FFF8C4B4\": \"Apricot Obsession\", \"#FFC86B3C\": \"Apricot Orange\", \"#FFEEB192\": \"Apricot Preserves\", \"#FFE8917D\": \"Apricot Red\", \"#FFFBCD9F\": \"Apricot Sherbet\", \"#FFE8A760\": \"Apricot Sorbet\", \"#FFF1C095\": \"Apricot Souffl\\u00e9\", \"#FFF1B393\": \"Apricot Spring\", \"#FFDA8C53\": \"Apricot Tan\", \"#FFFBA57D\": \"Apricot Wash\", \"#FFFAE0C2\": \"Apricot Whisper\", \"#FFF7F0DB\": \"Apricot White Variant\", \"#FFF7BD81\": \"Apricot Yellow\", \"#FFD8A48F\": \"Apricotta\", \"#FFF6D0D8\": \"April Blush\", \"#FF1FB57A\": \"April Fool\\u2019s Red\", \"#FFA9B062\": \"April Green\", \"#FF909245\": \"April Hills\", \"#FF8B3D2F\": \"April Love\", \"#FFCCD9C9\": \"April Mist\", \"#FF9BADA8\": \"April Rain\", \"#FFDADEB5\": \"April Showers\", \"#FFFBE198\": \"April Sunshine\", \"#FFB4CBD4\": \"April Tears\", \"#FFB1C1B8\": \"April Thicket\", \"#FFC5CFB1\": \"April Wedding\", \"#FFD5E2E5\": \"April Winds\", \"#FF0FF0FE\": \"Aqua\", \"#FFB5DFC9\": \"Aqua Bay\", \"#FF7ACAD0\": \"Aqua Belt\", \"#FF96D3D8\": \"Aqua Bloom\", \"#FF79B6BC\": \"Aqua Blue\", \"#FFD8E8E4\": \"Aqua Breeze\", \"#FF01F1F1\": \"Aqua Cyan\", \"#FF3896A7\": \"Aqua Dance\", \"#FFB7C9B5\": \"Aqua Dream\", \"#FF85C7A6\": \"Aqua Eden\", \"#FF038E85\": \"Aqua Experience\", \"#FF96E2E1\": \"Aqua Fiesta\", \"#FFA1BAAA\": \"Aqua Foam\", \"#FF4A9FA3\": \"Aqua Fresco\", \"#FFA9D1D7\": \"Aqua Frost\", \"#FFD2E8E0\": \"Aqua Glass\", \"#FF9DD5C8\": \"Aqua Glow\", \"#FF12E193\": \"Aqua Green\", \"#FF889FA5\": \"Aqua Grey\", \"#FFD9DDD5\": \"Aqua Haze Variant\", \"#FF30949D\": \"Aqua Lake\", \"#FFA0C9CB\": \"Aqua Mist\", \"#FF08787F\": \"Aqua Nation\", \"#FFBCE8DD\": \"Aqua Oasis\", \"#FF05696B\": \"Aqua Obscura\", \"#FFDDF2EE\": \"Aqua Pura\", \"#FF63A39C\": \"Aqua Rapids\", \"#FF539F91\": \"Aqua Revival\", \"#FF61A1A9\": \"Aqua Sea\", \"#FF70BBBF\": \"Aqua Sky\", \"#FF8C9FA0\": \"Aqua Smoke\", \"#FFD3E4E6\": \"Aqua Sparkle\", \"#FF85CED1\": \"Aqua Splash\", \"#FFA5DDDB\": \"Aqua Spray\", \"#FFE8F3E8\": \"Aqua Spring Variant\", \"#FFDBE4DC\": \"Aqua Squeeze Variant\", \"#FFE5F1EE\": \"Aqua Tint\", \"#FF00A29E\": \"Aqua Velvet\", \"#FF56B3C3\": \"Aqua Verde\", \"#FF7BBDC7\": \"Aqua Vitale\", \"#FF00937D\": \"Aqua Waters\", \"#FFBFDFDF\": \"Aqua Whisper\", \"#FFA0E3D1\": \"Aqua Wish\", \"#FF7CD8D6\": \"Aqua Zing\", \"#FF9CB0B3\": \"Aqua-Sphere\", \"#FFE1F0EA\": \"Aquacade\", \"#FF006F49\": \"Aquadazzle\", \"#FF7B9F82\": \"Aquadulce\", \"#FFE3ECED\": \"Aquafir\", \"#FF57B7C5\": \"Aqualogic\", \"#FF2EE8BB\": \"Aquamarine Variant\", \"#FFB3C4BA\": \"Aquamarine Dream\", \"#FF82CDAD\": \"Aquamarine Ocean\", \"#FF00A800\": \"Aquamentus Green\", \"#FF61AAB1\": \"Aquarelle\", \"#FFBFE0E4\": \"Aquarelle Blue\", \"#FFE2F4E4\": \"Aquarelle Green\", \"#FFEDC8FF\": \"Aquarelle Lilac\", \"#FFDBF4D8\": \"Aquarelle Mint\", \"#FFFBE8E0\": \"Aquarelle Orange\", \"#FFFBE9DE\": \"Aquarelle Pink\", \"#FFD8E1F1\": \"Aquarelle Purple\", \"#FFFEDDDD\": \"Aquarelle Red\", \"#FFBCE4EB\": \"Aquarelle Sky\", \"#FFF4EEDA\": \"Aquarelle Yellow\", \"#FF356B6F\": \"Aquarium\", \"#FF0A98AC\": \"Aquarium Diver\", \"#FF2DB0CE\": \"Aquarius\", \"#FF4D5AF3\": \"Aquarius Mood Indigo\", \"#FF559999\": \"Aquarius Reef Base\", \"#FF89C6B7\": \"Aquastone\", \"#FF99C1CC\": \"Aquatic\", \"#FF41A0B4\": \"Aquatic Cool\", \"#FFBFD6D1\": \"Aquatic Edge\", \"#FF49999A\": \"Aquatic Green\", \"#FFADE6DB\": \"Aquatic Mist\", \"#FFA6B5A9\": \"Aquatone\", \"#FF60B3BC\": \"Aqueduct\", \"#FF59B6D9\": \"Aquella\", \"#FF388D95\": \"Aqueous\", \"#FFE2ECED\": \"Aquifer\", \"#FF88ABB4\": \"Aquitaine\", \"#FFADAD9C\": \"Ara Glen\", \"#FF82ACC4\": \"Arabella\", \"#FFCD5F42\": \"Arabesque\", \"#FFCD9945\": \"Arabian Bake\", \"#FF016C84\": \"Arabian Nights\", \"#FFA14C3F\": \"Arabian Red\", \"#FFDDC6B1\": \"Arabian Sands\", \"#FF786E97\": \"Arabian Silk\", \"#FF934C36\": \"Arabian Spice\", \"#FFC9FFFA\": \"Arabian Veil\", \"#FF6F4D3F\": \"Arabic Coffee\", \"#FFC0FFEE\": \"Arabica Mint\", \"#FF7A552E\": \"Arable Brown\", \"#FFB06455\": \"Aragon\", \"#FF47BA87\": \"Aragon Green\", \"#FFE4E0D4\": \"Aragonite\", \"#FF6A95B1\": \"Aragonite Blue\", \"#FF948E96\": \"Aragonite Grey\", \"#FFF3F1F3\": \"Aragonite White\", \"#FFEC8254\": \"Araigaki Orange\", \"#FF3F4635\": \"Arame Seaweed Green\", \"#FFFF7013\": \"Arancio\", \"#FF274A5D\": \"Arapawa Variant\", \"#FF93A344\": \"Arathi Highlands\", \"#FFADD8E1\": \"Araucana Egg\", \"#FFA18D71\": \"Arava\", \"#FFCDA182\": \"Arbol de Tamarindo\", \"#FFBBC3AD\": \"Arbor Vitae\", \"#FF70BA9F\": \"Arboretum\", \"#FFC1C2B4\": \"Arbour Hollow\", \"#FFCCDDFF\": \"Arc Light\", \"#FFEE3311\": \"Arcade Fire\", \"#FF0022CC\": \"Arcade Glow\", \"#FFEDEBE2\": \"Arcade White\", \"#FF00AC8D\": \"Arcadia\", \"#FFA3C893\": \"Arcadian Green\", \"#FF3B6C3F\": \"Arcala Green\", \"#FF98687E\": \"Arcane\", \"#FF5260E1\": \"Arcane Brew\", \"#FF6A2F2F\": \"Arcane Red\", \"#FF6A0002\": \"Arcavia Red\", \"#FF8E785C\": \"Archaeological Site\", \"#FF6E6A5E\": \"Archaeology\", \"#FFCAC69D\": \"Archisa\", \"#FF6F6D5F\": \"Architect\", \"#FF7195A6\": \"Architecture Blue\", \"#FF6B6A69\": \"Architecture Grey\", \"#FF9F8C73\": \"Archivist\", \"#FF648589\": \"Arctic\", \"#FFCBD8E5\": \"Arctic Air\", \"#FFD9E5EB\": \"Arctic Blizzard\", \"#FF95D6DC\": \"Arctic Blue\", \"#FFB2CCD9\": \"Arctic Circle\", \"#FFE6E3DF\": \"Arctic Cotton\", \"#FFEBE4BE\": \"Arctic Daisy\", \"#FFE3E5E8\": \"Arctic Dawn\", \"#FF816678\": \"Arctic Dusk\", \"#FFAFBEC1\": \"Arctic Feelings\", \"#FFDAEAE4\": \"Arctic Flow\", \"#FFE7E7E2\": \"Arctic Fox\", \"#FFC9D1E9\": \"Arctic Glow\", \"#FF45BCB3\": \"Arctic Green\", \"#FFBBCCDD\": \"Arctic Grey\", \"#FFB6BDD0\": \"Arctic Ice\", \"#FF6F7872\": \"Arctic Lichen Green\", \"#FF345C61\": \"Arctic Nights\", \"#FF66C3D0\": \"Arctic Ocean\", \"#FFB8DFF8\": \"Arctic Paradise\", \"#FFC7DAED\": \"Arctic Rain\", \"#FFB7ABB0\": \"Arctic Rose\", \"#FF9BBACB\": \"Arctic Sunrise\", \"#FF6D584C\": \"Arctic Tundra\", \"#FF00FCFC\": \"Arctic Water\", \"#FFE9EAE7\": \"Arctic White\", \"#FFE2DEDF\": \"Ardcoat\", \"#FFE5756A\": \"Ardent Coral\", \"#FF232F2C\": \"Ard\\u00f3sia\", \"#FFDD2200\": \"Ares Red\", \"#FF62584C\": \"Ares Shadow\", \"#FF9D6646\": \"Argan Oil\", \"#FF888888\": \"Argent\", \"#FFCECAC3\": \"Argento\", \"#FFBDBDB7\": \"Argos\", \"#FF348A5D\": \"Argyle\", \"#FF895C79\": \"Argyle Purple\", \"#FFC48677\": \"Argyle Rose\", \"#FFE3E4E2\": \"Aria\", \"#FFF9E8D8\": \"Aria Ivory\", \"#FFDCD6C6\": \"Arid Landscape\", \"#FFB6B4A9\": \"Arid Plains\", \"#FFAED7EA\": \"Ariel\", \"#FFB2A5D3\": \"Ariel\\u2019s Delight\", \"#FFFAF0DF\": \"Aristocrat Ivory\", \"#FFECCEB9\": \"Aristocrat Peach\", \"#FF457E93\": \"Aristocratic\", \"#FF354655\": \"Aristocratic Blue\", \"#FFDDAACC\": \"Aristocratic Pink\", \"#FF980B4A\": \"Aristocratic Velvet\", \"#FFEEB377\": \"Arizona\", \"#FFAD735A\": \"Arizona Clay\", \"#FFDDAB93\": \"Arizona Dust\", \"#FF00655A\": \"Arizona Stone\", \"#FFEBBCB9\": \"Arizona Sunrise\", \"#FF669264\": \"Arizona Tree Frog\", \"#FFE8DAC3\": \"Arizona White\", \"#FF9F7B35\": \"Arlington Bronze\", \"#FF536762\": \"Armada\", \"#FF484A46\": \"Armadillo Variant\", \"#FF7D4638\": \"Armadillo Egg\", \"#FF926A25\": \"Armageddon Dunes\", \"#FFD3A907\": \"Armageddon Dust\", \"#FFAD916C\": \"Armagnac\", \"#FF74857F\": \"Armour\", \"#FF030303\": \"Armour Wash\", \"#FF747769\": \"Armoured Steel\", \"#FF6A6B65\": \"Armoury\", \"#FF5B6F61\": \"Army Canvas\", \"#FF6C7735\": \"Army Golf\", \"#FF8A806B\": \"Army Issue\", \"#FF838254\": \"Army Issue Green\", \"#FFBF8F37\": \"Arnica\", \"#FFE59B00\": \"Arnica Yellow\", \"#FFD3C1C5\": \"Aroma\", \"#FF96D2D6\": \"Aroma Blue\", \"#FFA1C4A8\": \"Aroma Garden\", \"#FFF9970C\": \"Aromango\", \"#FF706986\": \"Aromatic\", \"#FFFFCECB\": \"Aromatic Breeze\", \"#FF98C945\": \"Aromatic Herbs\", \"#FFF2FF26\": \"Aromatic Lemon\", \"#FF879BA3\": \"Arona\", \"#FFA1B670\": \"Around the Gills\", \"#FF776600\": \"Arousing Alligator\", \"#FF5C546E\": \"Arraign\", \"#FFBB8246\": \"Arrakis Spice\", \"#FF5A3532\": \"Arresting Auburn\", \"#FF927257\": \"Arrow Creek\", \"#FFC7A998\": \"Arrow Quiver\", \"#FFA28440\": \"Arrow Rock\", \"#FF5C503A\": \"Arrow Shaft\", \"#FF514B40\": \"Arrowhead\", \"#FF58728A\": \"Arrowhead Lake\", \"#FFF9EAEB\": \"Arrowhead White\", \"#FFF8DECF\": \"Arrowroot\", \"#FFE4DECF\": \"Arrowroote\", \"#FF827A67\": \"Arrowtown Variant\", \"#FFB3861E\": \"Arrowwood\", \"#FF896956\": \"Art and Craft\", \"#FFCDACA0\": \"Art Deco Pink\", \"#FF623745\": \"Art Deco Red\", \"#FF94897C\": \"Art District\", \"#FFC06F70\": \"Art House Pink\", \"#FFA29AA0\": \"Art Nouveau Glass\", \"#FF9C932F\": \"Art Nouveau Green\", \"#FFA08994\": \"Art Nouveau Violet\", \"#FFCA9D8D\": \"Artefact\", \"#FF65A98F\": \"Artemesia Green\", \"#FFD2A96E\": \"Artemis\", \"#FFDDDDEE\": \"Artemis Silver\", \"#FFE3EBEA\": \"Artemisia\", \"#FF711518\": \"Arterial\", \"#FFA6BEE1\": \"Artesian Pool\", \"#FF007DB6\": \"Artesian Water\", \"#FF5EB2AA\": \"Artesian Well\", \"#FFA8B1AD\": \"Artful\", \"#FF91B4B3\": \"Artful Aqua\", \"#FF80505D\": \"Artful Magenta\", \"#FFCC6C82\": \"Artful Pink\", \"#FF8F9779\": \"Artichoke\", \"#FFA19676\": \"Artichoke Dip\", \"#FF517345\": \"Artichoke Green\", \"#FFE4D588\": \"Artichoke Heart\", \"#FFC19AA5\": \"Artichoke Mauve\", \"#FFD9CA93\": \"Artichoke Mist\", \"#FFE6E2D3\": \"Artifice\", \"#FFA1A1A1\": \"Artificial Intelligence Grey\", \"#FF41B45C\": \"Artificial Turf\", \"#FF746F67\": \"Artillery\", \"#FF8F5C45\": \"Artisan\", \"#FFAFBFC4\": \"Artisan Blue\", \"#FFB99779\": \"Artisan Crafts\", \"#FF117471\": \"Artisan Green\", \"#FFAC5B50\": \"Artisan Red\", \"#FFB09879\": \"Artisan Tan\", \"#FFDAC2AF\": \"Artisan Tea\", \"#FF845E40\": \"Artisan Tile\", \"#FFF2AB46\": \"Artisans Gold\", \"#FF01343A\": \"Artist Blue\", \"#FFEEE4D2\": \"Artist\\u2019s Canvas\", \"#FF37393E\": \"Artist\\u2019s Charcoal\", \"#FFA1969B\": \"Artist\\u2019s Shadow\", \"#FF987387\": \"Artiste\", \"#FF434053\": \"Artistic Licence\", \"#FF5C6B65\": \"Artistic Stone\", \"#FFC3B1AC\": \"Artistic Taupe\", \"#FFD0D2E9\": \"Artistic Violet\", \"#FFF5C68B\": \"Arts & Crafts Gold\", \"#FF7D6549\": \"Arts and Crafts\", \"#FFCCA537\": \"Aru Ressha\", \"#FFD1DED3\": \"Aruba Aqua\", \"#FF7DD4D6\": \"Aruba Blue\", \"#FF54B490\": \"Aruba Green\", \"#FF75AD5B\": \"Arugula\", \"#FF48929B\": \"Asagi Blue\", \"#FF455559\": \"Asagi Koi\", \"#FFF7BB7D\": \"Asagi Yellow\", \"#FFFCEF01\": \"Asfar Yellow\", \"#FFBEBAA7\": \"Ash Variant\", \"#FFD7BEA5\": \"Ash Blonde\", \"#FF98623C\": \"Ash Brown\", \"#FFE8D3D1\": \"Ash Cherry Blossom\", \"#FF8C6F54\": \"Ash Gold\", \"#FFC1B5A9\": \"Ash Grey Variant\", \"#FFB9B3BF\": \"Ash Grove\", \"#FFA88E8B\": \"Ash Hollow\", \"#FFD9DDE5\": \"Ash in the Air\", \"#FF737486\": \"Ash Mauve\", \"#FF998E91\": \"Ash Pink\", \"#FFE8D3C7\": \"Ash Plum\", \"#FFB5817D\": \"Ash Rose\", \"#FFAABB99\": \"Ash Tree\", \"#FFCECFD6\": \"Ash Tree Bark\", \"#FF9695A4\": \"Ash Violet\", \"#FFE9E4D4\": \"Ash White\", \"#FFF0BD7E\": \"Ash Yellow\", \"#FFB495A4\": \"Ashberry\", \"#FFC9BFB2\": \"Ashen\", \"#FF994444\": \"Ashen Brown\", \"#FFB2A79D\": \"Ashen Grey\", \"#FF9B9092\": \"Ashen Plum\", \"#FFD3CABF\": \"Ashen Tan\", \"#FF8C7A7B\": \"Ashen Violet\", \"#FF646B7A\": \"Ashen Whisper\", \"#FF94A9B7\": \"Ashen Wind\", \"#FF104071\": \"Ashenvale Nights\", \"#FF45575E\": \"Asher Benjamin\", \"#FFB8B5AD\": \"Ashes\", \"#FFBBB3A2\": \"Ashes Variant\", \"#FFA3A1A5\": \"Ashland Heights\", \"#FF8398A9\": \"Ashley Blue\", \"#FFD2D9DA\": \"Ashlin Grey\", \"#FFA7A49F\": \"Ashlite\", \"#FF4A79BA\": \"Ashton Blue\", \"#FF7B8EB0\": \"Ashton Skies\", \"#FFEDD6AE\": \"Ashwood\", \"#FFDBD4C3\": \"Asiago\", \"#FFECE0CD\": \"Asian Fusion\", \"#FFE8E0CD\": \"Asian Ivory\", \"#FFD4B78F\": \"Asian Jute\", \"#FFAE9156\": \"Asian Pear\", \"#FF118822\": \"Asian Spice\", \"#FF8B818C\": \"Asian Violet\", \"#FFB8B0A5\": \"Ask Me Anything\", \"#FF88DDBB\": \"\\u0100sm\\u0101n\\u012b Sky\", \"#FF70B2CC\": \"Aspara\", \"#FF77AB56\": \"Asparagus Variant\", \"#FF96AF54\": \"Asparagus Cream\", \"#FFB9CB5A\": \"Asparagus Fern\", \"#FFD2CBB4\": \"Asparagus Green\", \"#FF576F44\": \"Asparagus Sprig\", \"#FFDAC98E\": \"Asparagus Yellow\", \"#FF83A494\": \"Aspen Aura\", \"#FFC6BCAD\": \"Aspen Branch\", \"#FFFFD662\": \"Aspen Gold\", \"#FF72926B\": \"Aspen Green\", \"#FFA39B92\": \"Aspen Grey\", \"#FF6A8D88\": \"Aspen Hush\", \"#FFCFD7CB\": \"Aspen Mist\", \"#FFF0F0E7\": \"Aspen Snow\", \"#FF687F7A\": \"Aspen Valley\", \"#FFEDF1E3\": \"Aspen Whisper\", \"#FFF6DF9F\": \"Aspen Yellow\", \"#FF474C55\": \"Asphalt Blue\", \"#FF5E5E5D\": \"Asphalt Grey\", \"#FFA08A80\": \"Aspiration\", \"#FFA2C1C0\": \"Aspiring Blue\", \"#FF2D4F83\": \"Assassin\", \"#FFF60206\": \"Assassin\\u2019s Red\", \"#FFE1D0B2\": \"Assateague Sand\", \"#FF1C4374\": \"Assault\", \"#FF867BA9\": \"Aster\", \"#FF9BACD8\": \"Aster Flower Blue\", \"#FFD4DAE2\": \"Aster Petal\", \"#FF8881B0\": \"Aster Purple\", \"#FF8F629A\": \"Aster Violetta\", \"#FFDD482B\": \"Astorath Red\", \"#FF7E7565\": \"Astoria Grey\", \"#FFEDD5A6\": \"Astra Variant\", \"#FF376F89\": \"Astral Variant\", \"#FF363151\": \"Astral Aura\", \"#FF203943\": \"Astral Nomad\", \"#FF8EC2E7\": \"Astral Spirit\", \"#FF77FF77\": \"Astro Arcade Green\", \"#FF899FB9\": \"Astro Bound\", \"#FF5383C3\": \"Astro Nautico\", \"#FF6D5ACF\": \"Astro Purple\", \"#FF937874\": \"Astro Sunset\", \"#FF797EB5\": \"Astro Zinger\", \"#FF757679\": \"Astrogranite\", \"#FF3B424C\": \"Astrogranite Debris\", \"#FF2D96CE\": \"Astrolabe Reef\", \"#FF445172\": \"Astronaut Variant\", \"#FF214559\": \"Astronaut Blue Variant\", \"#FF474B4A\": \"Astronomical\", \"#FF6B7C85\": \"Astronomicon Grey\", \"#FFAFB4B6\": \"Astroscopus Grey\", \"#FF67A159\": \"Astroturf\", \"#FF273E51\": \"Asurmen Blue Wash\", \"#FF17181C\": \"Aswad Black\", \"#FFE7EEE1\": \"At Ease\", \"#FF9E9985\": \"At Ease Soldier\", \"#FFE7D9B9\": \"At the Beach\", \"#FFA3ABB8\": \"Atelier\", \"#FF003A6C\": \"Ateneo Blue\", \"#FFDCD7CC\": \"Athena\", \"#FF66DDFF\": \"Athena Blue\", \"#FFE9B4C3\": \"Athena Pink\", \"#FF92A18A\": \"Athenian Green\", \"#FF3F74B1\": \"Athens\", \"#FFDCDDDD\": \"Athens Grey\", \"#FF6D8E44\": \"Athonian Camoshade\", \"#FFD5CBB2\": \"Aths Special Variant\", \"#FFFF7E02\": \"Ati-Ati Amber\", \"#FF008997\": \"Atlantic Blue\", \"#FFCBE1EE\": \"Atlantic Breeze\", \"#FF2B2F41\": \"Atlantic Charter\", \"#FF294F58\": \"Atlantic Deep\", \"#FF001166\": \"Atlantic Depths\", \"#FFD7CEB9\": \"Atlantic Fig Snail\", \"#FFA5B4AC\": \"Atlantic Foam\", \"#FF4B8EB0\": \"Atlantic Gull\", \"#FF00629A\": \"Atlantic Mystique\", \"#FF13336F\": \"Atlantic Navy\", \"#FFA7D8E4\": \"Atlantic Ocean\", \"#FFDCD5D2\": \"Atlantic Sand\", \"#FF3B5F83\": \"Atlantic Schooner\", \"#FF708189\": \"Atlantic Shoreline\", \"#FF3E586E\": \"Atlantic Tide\", \"#FFB598C3\": \"Atlantic Tulip\", \"#FF264243\": \"Atlantic Waves\", \"#FF336172\": \"Atlantis Variant\", \"#FF006477\": \"Atlantis Myth\", \"#FF5CA0A7\": \"Atlas Cedar\", \"#FF667A6E\": \"Atlas Cedar Green\", \"#FF82193A\": \"Atlas Red\", \"#FFEDE5CF\": \"Atlas White\", \"#FF0099DD\": \"Atmosphere\", \"#FF899697\": \"Atmospheric\", \"#FFC2D0E1\": \"Atmospheric Pressure\", \"#FFACE1F0\": \"Atmospheric Soft Blue\", \"#FF2B797A\": \"Atoll Variant\", \"#FFFFCF9E\": \"Atoll Sand\", \"#FF8F9CAC\": \"Atom Blue\", \"#FF3D4B52\": \"Atomic\", \"#FF0097C3\": \"Atomic Blue\", \"#FFB9FF03\": \"Atomic Lime\", \"#FFF88605\": \"Atomic Orange\", \"#FFFB7EFD\": \"Atomic Pink\", \"#FFF1EEE4\": \"Atrium White\", \"#FF994240\": \"Attar of Rose\", \"#FFCCBCA9\": \"Attic Linen\", \"#FFA1BCA9\": \"Attica\", \"#FFA48884\": \"Attitude\", \"#FF7C7D75\": \"Attitude Grey\", \"#FF3F4258\": \"Attorney\", \"#FF9E6759\": \"Au Chico Variant\", \"#FFF4F2E2\": \"Au Clair de la Lune\", \"#FFF6A694\": \"Au Contraire\", \"#FFFF9D45\": \"Au Gratin\", \"#FFB99D83\": \"Au Lait Ole\", \"#FFE5E1CE\": \"Au Natural\", \"#FFE8CAC0\": \"Au Naturel\", \"#FF3F3130\": \"Auberge\", \"#FF372528\": \"Aubergine Variant\", \"#FFF2E4DD\": \"Aubergine Flesh\", \"#FF8B762C\": \"Aubergine Green\", \"#FF6E5861\": \"Aubergine Grey\", \"#FF3B2741\": \"Aubergine Mauve\", \"#FF5500AA\": \"Aubergine Perl\", \"#FF712F2C\": \"Auburn Variant\", \"#FFB58271\": \"Auburn Glaze\", \"#FF78342F\": \"Auburn Lights\", \"#FFD8A394\": \"Auburn Wave\", \"#FFB5ACB7\": \"Audition\", \"#FFAE8087\": \"Audrey\\u2019s Blush\", \"#FF9F9292\": \"Auger Shell\", \"#FFE6E1D6\": \"August Moon\", \"#FFFFD79D\": \"August Morning\", \"#FF90AA0B\": \"Augustus Asparagus\", \"#FF7C7469\": \"Aumbry\", \"#FF7C0087\": \"Aunt Violet\", \"#FFB2A8A1\": \"Aura\", \"#FFDEE2E4\": \"Aura White\", \"#FFC48919\": \"Auric\", \"#FFE8BC6D\": \"Auric Armour Gold\", \"#FFAA6A44\": \"Auric Copper\", \"#FF32FFDC\": \"Aurichalcite\", \"#FF533552\": \"Auricula Purple\", \"#FFEBD147\": \"Aurora\", \"#FF556B87\": \"Aurora Borealis\", \"#FF6ADC99\": \"Aurora Green\", \"#FFD3C5C4\": \"Aurora Grey\", \"#FF963B60\": \"Aurora Magenta\", \"#FFEC7042\": \"Aurora Orange\", \"#FFE881A6\": \"Aurora Pink\", \"#FFC13435\": \"Aurora Red\", \"#FF595682\": \"Aurora Splendour\", \"#FF72B2AF\": \"Aurora Teal\", \"#FF438273\": \"Aussie Surf\", \"#FF726848\": \"Austere\", \"#FFBEBFB2\": \"Austere Grey\", \"#FFF4C4A5\": \"Australian Apricot\", \"#FF84A194\": \"Australian Jade\", \"#FFEFF8AA\": \"Australian Mint Variant\", \"#FFCC9911\": \"Australien\", \"#FFE7B53B\": \"Australium Gold\", \"#FFDEE6E7\": \"Austrian Ice\", \"#FF6B5446\": \"Authentic Brown\", \"#FFEADDC6\": \"Authentic Tan\", \"#FFC38743\": \"Automn Fox\", \"#FFC6C7C5\": \"Autonomous\", \"#FFAF865B\": \"Autumn\", \"#FFD2A888\": \"Autumn Air\", \"#FFCDA449\": \"Autumn Apple Yellow\", \"#FFF9986F\": \"Autumn Arrival\", \"#FF816B68\": \"Autumn Ashes\", \"#FFE3AD59\": \"Autumn Avenue\", \"#FF9D6F46\": \"Autumn Bark\", \"#FFD9922E\": \"Autumn Blaze\", \"#FFECCCA6\": \"Autumn Blonde\", \"#FFFFE0CB\": \"Autumn Bloom\", \"#FFFBE6C1\": \"Autumn Child\", \"#FF447744\": \"Autumn Crocodile\", \"#FFEA6F5B\": \"Autumn Enchantment\", \"#FF67423B\": \"Autumn Fall\", \"#FF507B49\": \"Autumn Fern\", \"#FFBE7D33\": \"Autumn Fest\", \"#FFA28B36\": \"Autumn Festival\", \"#FFC44E4F\": \"Autumn Fire\", \"#FFAFB8BA\": \"Autumn Fog\", \"#FFB3573F\": \"Autumn Glaze\", \"#FFE9874E\": \"Autumn Glimmer\", \"#FFFF8812\": \"Autumn Glory\", \"#FFE5C382\": \"Autumn Glow\", \"#FF7D623C\": \"Autumn Gold\", \"#FFE6AE76\": \"Autumn Gourd\", \"#FFB2ABA7\": \"Autumn Grey\", \"#FF827B53\": \"Autumn Grove\", \"#FFD4C2B1\": \"Autumn Haze\", \"#FFB9674E\": \"Autumn Ivy\", \"#FFE47227\": \"Autumn Landscape\", \"#FF9D8D66\": \"Autumn Laurel\", \"#FFB56A4C\": \"Autumn Leaf\", \"#FF7A560E\": \"Autumn Leaf Brown\", \"#FFD07A04\": \"Autumn Leaf Orange\", \"#FF623836\": \"Autumn Leaf Red\", \"#FF6E4440\": \"Autumn Leaves\", \"#FFCEA48E\": \"Autumn Malt\", \"#FFD26F16\": \"Autumn Maple\", \"#FFF7B486\": \"Autumn Mist\", \"#FF3B5861\": \"Autumn Night\", \"#FFEE9950\": \"Autumn Orange\", \"#FF9D9093\": \"Autumn Orchid\", \"#FF158078\": \"Autumn Pine Green\", \"#FF99451F\": \"Autumn Red\", \"#FF9B423F\": \"Autumn Ridge\", \"#FFC2452D\": \"Autumn Robin\", \"#FFA4746E\": \"Autumn Russet\", \"#FFAEA26E\": \"Autumn Sage\", \"#FFD19957\": \"Autumn Spice\", \"#FFFE9A50\": \"Autumn Splendour\", \"#FFF38554\": \"Autumn Sunset\", \"#FFAB662E\": \"Autumn Surprise\", \"#FFAE704F\": \"Autumn Umber\", \"#FFFAE2CF\": \"Autumn White\", \"#FFFBD1B6\": \"Autumn Wind\", \"#FFE99700\": \"Autumn Yellow\", \"#FFBA7A61\": \"Autumn\\u2019s Hill\", \"#FFAD5928\": \"Autumnal\", \"#FF106B21\": \"Avagddu Green\", \"#FF799B96\": \"Avalon\", \"#FFFF77EE\": \"Avant-Garde Pink\", \"#FF576E6A\": \"Aventurine\", \"#FFD2C2B0\": \"Avenue Tan\", \"#FFC6E3E8\": \"Aviary Blue\", \"#FF7D6049\": \"Aviator\", \"#FFF4C69F\": \"Avid Apricot\", \"#FFC5B47F\": \"Aviva\", \"#FF568203\": \"Avocado Variant\", \"#FFB7BF6B\": \"Avocado Cream\", \"#FF3E4826\": \"Avocado Dark Green\", \"#FF87A922\": \"Avocado Green\", \"#FF555337\": \"Avocado Pear\", \"#FF39373B\": \"Avocado Peel\", \"#FF4E3E1F\": \"Avocado Stone\", \"#FF90B134\": \"Avocado Toast\", \"#FFCDD6B1\": \"Avocado Whip\", \"#FFCCBDB4\": \"Avorio\", \"#FFA7A3BB\": \"Awaken\", \"#FFE3DAE9\": \"Awakened\", \"#FFBB9E9B\": \"Awakening\", \"#FF315886\": \"Award Blue\", \"#FF54617D\": \"Award Night\", \"#FFFEF0DE\": \"Award Winning White\", \"#FFE3EBB1\": \"Awareness\", \"#FFF0D6CF\": \"Awe\", \"#FFCCC1DA\": \"Awesome Aura\", \"#FFA7B2D4\": \"Awesome Violet\", \"#FFD208CC\": \"Awkward Purple\", \"#FF90413E\": \"Awning Red\", \"#FF6B4730\": \"Axe Handle\", \"#FF756050\": \"Axinite\", \"#FFBAB6CB\": \"Axis\", \"#FFFFF0DF\": \"Axolotl Variant\", \"#FF665500\": \"Ayahuasca Vine\", \"#FF763568\": \"Ayame Iris\", \"#FFA07254\": \"Ayrshire\", \"#FFD73B5D\": \"Azalea Variant\", \"#FFEFC0CB\": \"Azalea Flower\", \"#FF4A6871\": \"Azalea Leaf\", \"#FFF9C0C4\": \"Azalea Pink\", \"#FFBA7462\": \"Azalea Pot\", \"#FFA5B546\": \"Azeitona\", \"#FF7C968B\": \"Azores\", \"#FF0085A7\": \"Azores Blue\", \"#FF4C6CB3\": \"Azraq Blue\", \"#FFB13916\": \"Azshara Vein\", \"#FF293432\": \"Aztec Variant\", \"#FFFFEFBC\": \"Aztec Aura\", \"#FF9E8352\": \"Aztec Brick\", \"#FFC46943\": \"Aztec Copper\", \"#FFE7B347\": \"Aztec Glimmer\", \"#FFC39953\": \"Aztec Gold\", \"#FF33BB88\": \"Aztec Jade\", \"#FF4DB5D7\": \"Aztec Sky\", \"#FF84705B\": \"Aztec Temple\", \"#FF00D6E2\": \"Aztec Turquoise\", \"#FFBB0066\": \"Aztec Warrior\", \"#FF96514D\": \"Azuki Bean\", \"#FF672422\": \"Azuki Red\", \"#FF1D5DEC\": \"Azul\", \"#FF0089C4\": \"Azul Caribe\", \"#FFC9E3EB\": \"Azul Cielito Lindo\", \"#FF537FAF\": \"Azul Pavo Real\", \"#FFE2EFF2\": \"Azul Primavera\", \"#FFC0CFC7\": \"Azul Tequila\", \"#FF6ABAC4\": \"Azul Turquesa\", \"#FF211D49\": \"Azulado\", \"#FF4D91C6\": \"Azure Blue\", \"#FF053976\": \"Azure Dragon\", \"#FF006C81\": \"Azure Green Blue\", \"#FFDDDCE1\": \"Azure Hint\", \"#FF7BBBC8\": \"Azure Lake\", \"#FFF0FFF1\": \"Azure Mist\", \"#FF007F1F\": \"Azure Radiance Variant\", \"#FFB0E0F6\": \"Azure Sky\", \"#FF2B9890\": \"Azure Tide\", \"#FF59BAD9\": \"Azurean\", \"#FFDBE9F4\": \"Azureish White\", \"#FFCC81F0\": \"Azuremyst Isle\", \"#FF8FA0D5\": \"Azureno\", \"#FF497F73\": \"Azurite Water Green\", \"#FFEDB367\": \"Ba-Dum Ching!\", \"#FF610023\": \"Baal Red Wash\", \"#FFEEBB88\": \"Baba Ganoush\", \"#FFBECFCD\": \"Babbling Brook\", \"#FFA7BAD3\": \"Babbling Creek\", \"#FFDC7B7C\": \"Babe\", \"#FF876FA3\": \"Babiana\", \"#FFABCCC3\": \"Baby Aqua\", \"#FFE9E3CE\": \"Baby Artichoke\", \"#FFC3C3B8\": \"Baby Barn Owl\", \"#FF6F5944\": \"Baby Bear\", \"#FF9C4A62\": \"Baby Berries\", \"#FFFAEFE9\": \"Baby Blossom\", \"#FFA2CFFE\": \"Baby Blue Variant\", \"#FFBBB98A\": \"Baby Bok Choy\", \"#FFB7CADB\": \"Baby Boots\", \"#FFABCAEA\": \"Baby Bunting\", \"#FF8C665C\": \"Baby Burro\", \"#FF87BEA3\": \"Baby Cake\", \"#FFFFEDA2\": \"Baby Chick\", \"#FFF3ACB9\": \"Baby Fish Mouth\", \"#FFF0D0B0\": \"Baby Fragrance\", \"#FFC8BA63\": \"Baby Frog\", \"#FFFFDFE8\": \"Baby Girl\", \"#FF8ABD7B\": \"Baby Grass\", \"#FF8CFF9E\": \"Baby Green\", \"#FFD0A7A8\": \"Baby Jane\", \"#FFFFA468\": \"Baby Melon\", \"#FF8FCBDC\": \"Baby Motive\", \"#FFFFB7CE\": \"Baby Pink Variant\", \"#FFCA9BF7\": \"Baby Purple\", \"#FFA1A5A8\": \"Baby Seal\", \"#FF89A882\": \"Baby Spinach\", \"#FFA78B81\": \"Baby Sprout\", \"#FFF5C9DA\": \"Baby Steps\", \"#FFBABABA\": \"Baby Talk Grey\", \"#FF66B9D6\": \"Baby Tears\", \"#FFDCC2CB\": \"Baby Tone\", \"#FFEEFFDD\": \"Baby Tooth\", \"#FF5D6942\": \"Baby Vegetable\", \"#FF4D5588\": \"Baby Whale\", \"#FFFFAEC1\": \"Baby\\u2019s Blanket\", \"#FFE8C1C2\": \"Baby\\u2019s Booties\", \"#FFD8E4E8\": \"Baby\\u2019s Breath\", \"#FFEECCBB\": \"Babyccino\", \"#FFC8E4E7\": \"Babymoon Blue\", \"#FF945759\": \"Baca Berry\", \"#FF8A3A3C\": \"Bacchanalia Red\", \"#FF95122C\": \"Bacchic Burgundy\", \"#FF8FAACA\": \"Bachelor Blue\", \"#FF4ABBD5\": \"Bachelor Button\", \"#FFFDDEA5\": \"Bachimitsu Gold\", \"#FF16141C\": \"Back in Black\", \"#FF015F7F\": \"Back of Beyond\", \"#FF6B625B\": \"Back Stage\", \"#FF726747\": \"Back\", \"#FFBDB98F\": \"Back Variant\", \"#FFC1853B\": \"Back Tint\", \"#FF7C725F\": \"Backcountry\", \"#FFA7A799\": \"Backdrop\", \"#FFFCF0E5\": \"Backlight\", \"#FFFFDF4F\": \"Backlit Lemon\", \"#FFA19250\": \"Backroom Ember\", \"#FF687078\": \"Backwater\", \"#FF4A6546\": \"Backwoods\", \"#FF879877\": \"Backyard\", \"#FFDF3F32\": \"Bacon Strips\", \"#FFF1C983\": \"Bad Hair Day\", \"#FFF2E5B4\": \"Bad Moon Yellow\", \"#FF0A0908\": \"Badab Black Wash\", \"#FFB4DA55\": \"Badass Grass\", \"#FFB5695A\": \"Badlands\", \"#FFFF6316\": \"Badlands Orange\", \"#FF936A5B\": \"Badlands Sunset\", \"#FFD5BCB3\": \"Badlands Taupe\", \"#FFD3A194\": \"Badshahi Brown\", \"#FFE1BD88\": \"Bag of Gold\", \"#FFF6CD9B\": \"Bagel\", \"#FF1C5544\": \"Bagpiper\", \"#FFB5936A\": \"Baguette\", \"#FF25597F\": \"Bahama Blue Variant\", \"#FFB9D1DA\": \"Bahama Breezes\", \"#FF3FA49B\": \"Bahaman Bliss\", \"#FF12ABBE\": \"Bahaman Sea\", \"#FF58C1CD\": \"Baharroth Blue\", \"#FFA9C01C\": \"Bahia Variant\", \"#FFC4C5AD\": \"Bahia Grass\", \"#FFECEFEF\": \"B\\u00e1i S\\u00e8 White\", \"#FF887938\": \"Baik\\u014d Brown\", \"#FF8A8EC9\": \"Bailey Bells\", \"#FF8273FD\": \"Baingan\\u012b\", \"#FF4B5445\": \"Baize\", \"#FFC7CDA8\": \"Baize Green\", \"#FFD2C1A8\": \"Baja\", \"#FF66A6D9\": \"Baja Blue\", \"#FFB34646\": \"Baked Apple\", \"#FF9C4856\": \"Baked Bahama\", \"#FFB2754D\": \"Baked Bean\", \"#FFDAD3CC\": \"Baked Biscotti\", \"#FFDACBA9\": \"Baked Bread\", \"#FFEDE9D7\": \"Baked Brie\", \"#FFA35445\": \"Baked Clay\", \"#FF89674A\": \"Baked Cookie\", \"#FFEEC8BC\": \"Baked Ham\", \"#FFB69E87\": \"Baked Potato\", \"#FFDF9876\": \"Baked Salmon\", \"#FFE5D3BC\": \"Baked Scone\", \"#FF9B775E\": \"Baked Sienna\", \"#FFE6D4A5\": \"Bakelite\", \"#FFD7995D\": \"Bakelite Gold\", \"#FFC6B788\": \"Bakelite Yellow\", \"#FFBF8284\": \"Baker Rose\", \"#FFFF92AE\": \"Baker-Miller Pink\", \"#FFD0B393\": \"Baker\\u2019s Bread\", \"#FF5C3317\": \"Baker\\u2019s Chocolate\", \"#FFCEB997\": \"Baker\\u2019s Dozen\", \"#FFC98F70\": \"Baker\\u2019s Dream\", \"#FFF0F4F2\": \"Bakery Box\", \"#FFAB9078\": \"Bakery Brown\", \"#FFEFB435\": \"Baklava\", \"#FF273F4B\": \"Bakos Blue\", \"#FFD1DBC2\": \"Balance\", \"#FFC3C5A7\": \"Balance Green\", \"#FFD7D2D1\": \"Balanced\", \"#FFC0B2A2\": \"Balanced Beige\", \"#FFAFD3DA\": \"Balboa\", \"#FFE2BCB8\": \"Balcony Rose\", \"#FFD78E6B\": \"Balcony Sunset\", \"#FF165A90\": \"Baleine Blue\", \"#FFCF994B\": \"Bales of Brown\", \"#FF6F5937\": \"Bali Batik\", \"#FF5E9EA0\": \"Bali Bliss\", \"#FF8A8E93\": \"Bali Deep\", \"#FF849CA9\": \"Bali Hai Variant\", \"#FFF6E8D5\": \"Bali Sand\", \"#FFF1A177\": \"Balinese Sunset\", \"#FF525661\": \"Ball Gown\", \"#FFCAB6C6\": \"Ballad\", \"#FFF2CFDC\": \"Ballerina\", \"#FFE8DED6\": \"Ballerina Beauty\", \"#FFF9EAEA\": \"Ballerina Gown\", \"#FFF7B6BA\": \"Ballerina Pink\", \"#FFF0DEE0\": \"Ballerina Silk\", \"#FFF2BBB1\": \"Ballerina Tears\", \"#FFC8647F\": \"Ballerina Tutu\", \"#FFF7D5D4\": \"Ballet\", \"#FFFC8258\": \"Ballet Cream\", \"#FFD3ADB1\": \"Ballet Rose\", \"#FFFFC5B3\": \"Ballet Skirt\", \"#FFFCA2AD\": \"Ballet Slippers\", \"#FFF2E7D8\": \"Ballet White\", \"#FFB2B29C\": \"Ballie Scott Sage\", \"#FF323477\": \"Ballpoint Indigo\", \"#FFDAD3C8\": \"Ballroom Belle\", \"#FFA6B3C9\": \"Ballroom Blue\", \"#FF85928E\": \"Ballroom Slippers\", \"#FF58A83B\": \"Ballyhoo\", \"#FFC5D8DE\": \"Balmy\", \"#FF5C6F64\": \"Balmy Palm Tree\", \"#FFB4DCD3\": \"Balmy Seas\", \"#FF9C6B08\": \"Balor Brown\", \"#FFCBBB92\": \"Balsa Stone\", \"#FF9A7550\": \"Balsa Wood\", \"#FFBEC4B7\": \"Balsam\", \"#FF36574E\": \"Balsam Branch\", \"#FFCBA874\": \"Balsam Brown\", \"#FF909E91\": \"Balsam Fir\", \"#FF120D07\": \"Balsam of Peru\", \"#FFB19338\": \"Balsam Pear\", \"#FF434340\": \"Balsamic Reduction\", \"#FF130D07\": \"Balsamico\", \"#FFA47552\": \"Balthasar Gold\", \"#FF279D9F\": \"Baltic\", \"#FFFBB782\": \"Baltic Amber\", \"#FF6C969A\": \"Baltic Blue\", \"#FF9FBBDA\": \"Baltic Bream\", \"#FF3AA098\": \"Baltic Green\", \"#FF135952\": \"Baltic Prince\", \"#FF3C3D3E\": \"Baltic Sea Variant\", \"#FF125761\": \"Baltic Trench\", \"#FF00A49A\": \"Baltic Turquoise\", \"#FF8EDACC\": \"Bambino\", \"#FFE3DEC6\": \"Bamboo Variant\", \"#FFC1ABA0\": \"Bamboo Beige\", \"#FFC87F00\": \"Bamboo Brown\", \"#FF454A48\": \"Bamboo Charcoal\", \"#FFB1A979\": \"Bamboo Forest\", \"#FF82994C\": \"Bamboo Grass Green\", \"#FF99B243\": \"Bamboo Leaf\", \"#FFE5DA9F\": \"Bamboo Mat\", \"#FFBCAB8C\": \"Bamboo Screen\", \"#FFA3B6A4\": \"Bamboo Shoot\", \"#FFC6CFAD\": \"Bamboo White\", \"#FFAE884B\": \"Bamboo Yellow\", \"#FF5A1991\": \"Banaf\\u0161 Violet\", \"#FFFAF3A6\": \"Banan-Appeal\", \"#FFFFFC79\": \"Banana\", \"#FFEFE073\": \"Banana Ball\", \"#FFF8F739\": \"Banana Bandanna\", \"#FFFFDE7B\": \"Banana Biscuit\", \"#FF933E49\": \"Banana Blossom\", \"#FFFDC838\": \"Banana Boat\", \"#FFF7E82E\": \"Banana Bombshell\", \"#FFFFCF73\": \"Banana Bread\", \"#FFE8D82C\": \"Banana Brick\", \"#FFF7EAB9\": \"Banana Br\\u00fbl\\u00e9e\", \"#FFD6D963\": \"Banana Chalk\", \"#FFEEDD00\": \"Banana Clan\", \"#FFFFF49C\": \"Banana Cream\", \"#FFE7D3AD\": \"Banana Crepe\", \"#FFFCF3C5\": \"Banana Custard\", \"#FFF1D548\": \"Banana Drama\", \"#FFFFDF38\": \"Banana Farm\", \"#FFEEFE02\": \"Banana Flash\", \"#FFDDD5B6\": \"Banana Frapp\\u00e9\", \"#FFF1D3B2\": \"Banana Ice Cream\", \"#FFFFFB08\": \"Banana King\", \"#FF9D8F3A\": \"Banana Leaf\", \"#FFFAFE4B\": \"Banana Mash\", \"#FFFFF7AD\": \"Banana Milk\", \"#FFEDE6CB\": \"Banana Milkshake\", \"#FF95A263\": \"Banana Palm\", \"#FFFFE774\": \"Banana Peel\", \"#FFFDD630\": \"Banana Pepper\", \"#FFF7EFD7\": \"Banana Pie\", \"#FFD0C101\": \"Banana Powder\", \"#FFF3DB00\": \"Banana Propaganda\", \"#FFF4EFC3\": \"Banana Pudding\", \"#FFB29705\": \"Banana Puree\", \"#FFFFE292\": \"Banana Republic\", \"#FFF6F5D7\": \"Banana Sparkes\", \"#FFF7EEC8\": \"Banana Split\", \"#FFFFE135\": \"Banana Yellow\", \"#FFE4D466\": \"Bananarama\", \"#FFDBBE97\": \"Bananas Foster\", \"#FF00A86C\": \"Banaue Jade\", \"#FF666A47\": \"Bancha\", \"#FF816E54\": \"Bancroft Village\", \"#FFD7A97C\": \"Band-Aid\", \"#FF01578F\": \"Bandana\", \"#FFE0D3BD\": \"Banded Tulip\", \"#FF878466\": \"Bandicoot Variant\", \"#FF871466\": \"Bane of Royalty\", \"#FF937F6D\": \"Baneblade Brown\", \"#FFBC393B\": \"Bang\", \"#FFBBAA88\": \"Bangalore\", \"#FF006A4F\": \"Bangladesh Green\", \"#FFD2B762\": \"Banh Bot Loc Dumpling\", \"#FF745E6F\": \"Banished Brown\", \"#FF3E4652\": \"Bank Blue\", \"#FF757374\": \"Bank Vault\", \"#FFA6B29A\": \"Banksia\", \"#FF4B5539\": \"Banksia Leaf\", \"#FF016876\": \"Bankson Lake\", \"#FFA28557\": \"Banner Gold\", \"#FF806B5D\": \"Bannister Brown\", \"#FFE1E0D6\": \"Bannister White\", \"#FFDAF0E6\": \"Banshee\", \"#FFAF6C5D\": \"Bantam Egg\", \"#FF98AB8C\": \"Banyan Serenity\", \"#FF8D793E\": \"Banyan Tree\", \"#FFE6490B\": \"Baptism by Fire\", \"#FFE9546B\": \"Bara Red\", \"#FF551100\": \"Baragon Brown\", \"#FF4B2D2A\": \"Barako Brew\", \"#FF3E6676\": \"Barbados\", \"#FF006665\": \"Barbados Bay\", \"#FFB8A983\": \"Barbados Beige\", \"#FF2766AC\": \"Barbados Blue\", \"#FFAF0A30\": \"Barbados Cherry\", \"#FFFF0FF3\": \"Barbara\", \"#FFF78C5A\": \"Barbarian\", \"#FFA17308\": \"Barbarian Leather\", \"#FFA84734\": \"Barbarossa\", \"#FFC26157\": \"Barbecue\", \"#FF471C0F\": \"Barbecue Sauce\", \"#FF8B031C\": \"Barbera\", \"#FFEE1133\": \"Barberry Variant\", \"#FFD2C61F\": \"Barberry Bush\", \"#FFE1D4BC\": \"Barberry Sand\", \"#FFF3BD32\": \"Barberry Yellow\", \"#FFFE46A5\": \"Barbie Pink Variant\", \"#FFE15ACB\": \"Barbiecore\", \"#FFC4B39C\": \"Barcelona Beige\", \"#FF926A46\": \"Barcelona Brown\", \"#FFFF9500\": \"Barcelona Orange\", \"#FF817E6D\": \"Bare\", \"#FFE8D3C9\": \"Bare Beige\", \"#FFEEDDCC\": \"Bare Bone\", \"#FFDCD4C3\": \"Bare Market\", \"#FFD6E3E7\": \"Bare Mintimum\", \"#FFEFC9B7\": \"Bare Necessity\", \"#FFF2E1DD\": \"Bare Pink\", \"#FFBAE9E0\": \"Barely Aqua\", \"#FFE4CCD4\": \"Barely Berry\", \"#FFDDAADD\": \"Barely Bloomed\", \"#FFDDE0DF\": \"Barely Blue\", \"#FFDD6655\": \"Barely Brown\", \"#FFF8E9C2\": \"Barely Butter\", \"#FFCCBDB9\": \"Barely Mauve\", \"#FFFFE9C7\": \"Barely Peach\", \"#FFEDEBDB\": \"Barely Pear\", \"#FFF8D7DD\": \"Barely Pink\", \"#FFFFE3CB\": \"Barely Ripe Apricot\", \"#FFEDE0E3\": \"Barely Rose\", \"#FFE1E3DD\": \"Barely White\", \"#FFD5D3C0\": \"Barest Celadon\", \"#FFC5D9DB\": \"Barest Hint of Blue\", \"#FFD5D3C7\": \"Barest Hush\", \"#FF94AC02\": \"Barf Green\", \"#FF68534A\": \"Bargeboard Brown\", \"#FFBCAFA2\": \"Barista\", \"#FFBB8D4E\": \"Barista\\u2019s Favourite\", \"#FF9E7B5C\": \"Barite\", \"#FF708E95\": \"Baritone\", \"#FFF4E1C5\": \"Barium\", \"#FF8FFF9F\": \"Barium Green\", \"#FF5F5854\": \"Bark\", \"#FF73532A\": \"Bark Brown\", \"#FFAB9004\": \"Bark Sawdust\", \"#FFADC6DA\": \"Barking Creek\", \"#FFC5B497\": \"Barking Prairie Dog\", \"#FFD5B37E\": \"Barley\", \"#FFB6935C\": \"Barley Corn Variant\", \"#FFC7BCAE\": \"Barley Field\", \"#FFFBF2DB\": \"Barley Groats\", \"#FFF7E5B7\": \"Barley White Variant\", \"#FF8E5959\": \"Barn Door\", \"#FF8B4044\": \"Barn Red\", \"#FF4D332A\": \"Barn Swallow\", \"#FFAC1DB8\": \"Barney\", \"#FFA00498\": \"Barney Purple\", \"#FF9C9481\": \"Barnfloor\", \"#FF554D44\": \"Barnwood\", \"#FF87857E\": \"Barnwood Ash\", \"#FF9E9589\": \"Barnwood Grey\", \"#FF5DAC51\": \"Barnyard Grass\", \"#FF71000E\": \"Barolo\", \"#FF929899\": \"Barometer\", \"#FFA785A7\": \"Baroness\", \"#FF847098\": \"Baroness Mauve\", \"#FF5A4840\": \"Baronial Brown\", \"#FFDDAA22\": \"Baroque\", \"#FF95B6B5\": \"Baroque Blue\", \"#FFAECCCB\": \"Baroque Chalk Soft Blue\", \"#FF5F5D64\": \"Baroque Grey\", \"#FF7B4F5D\": \"Baroque Red\", \"#FFB35A66\": \"Baroque Rose\", \"#FF452E39\": \"Barossa Variant\", \"#FFF0B069\": \"Barrel\", \"#FF8B6945\": \"Barrel Aged\", \"#FF9E3C31\": \"Barrel Sponge\", \"#FF8E7E67\": \"Barrel Stove\", \"#FFB9ABA3\": \"Barren\", \"#FFF5D1B2\": \"Barrett Quince\", \"#FF84623E\": \"Barricade\", \"#FF009BB5\": \"Barrier Reef\", \"#FFA2A59E\": \"Barrister Grey\", \"#FF9F8E71\": \"Barro Verde\", \"#FF989998\": \"Basalt\", \"#FF4D423E\": \"Basalt Black\", \"#FFC15154\": \"Basashi Red\", \"#FF575C3A\": \"Base Camp\", \"#FFBB9955\": \"Base Sand\", \"#FFF4EADC\": \"Baseball Base\", \"#FFE3EDED\": \"Bashful\", \"#FF6994CF\": \"Bashful Blue\", \"#FFB2B0AC\": \"Bashful Emu\", \"#FFD0D2E3\": \"Bashful Lilac\", \"#FFD9CDE5\": \"Bashful Pansy\", \"#FFB88686\": \"Bashful Rose\", \"#FFDBC3B6\": \"Basic Coral\", \"#FFC3B69F\": \"Basic Khaki\", \"#FF879F84\": \"Basil\", \"#FF828249\": \"Basil Chiffonade\", \"#FF54622E\": \"Basil Green\", \"#FFE2E6DB\": \"Basil Icing\", \"#FF6C5472\": \"Basil Mauve\", \"#FF529D6E\": \"Basil Pesto\", \"#FFB7E1A1\": \"Basil Smash\", \"#FF4A9FA7\": \"Basilica Blue\", \"#FF9AB38D\": \"Basilisk\", \"#FFBCECAC\": \"Basilisk Lizard\", \"#FFB9DEE4\": \"Basin Blue\", \"#FFC0A98B\": \"Basket Beige\", \"#FFC8C0B8\": \"Basket of Bobbins\", \"#FFF4CC3C\": \"Basket of Gold\", \"#FFEE6730\": \"Basketball\", \"#FFBDA286\": \"Basketry\", \"#FFCAAD92\": \"Basketweave Beige\", \"#FFEBE1C9\": \"Basmati White\", \"#FF5F6033\": \"Basque Green\", \"#FFD3C1CB\": \"Bassinet\", \"#FFC9B196\": \"Basswood\", \"#FF839E83\": \"Basswood Green\", \"#FFFFCC88\": \"Bastard Amber\", \"#FF2C2C32\": \"Bastille Variant\", \"#FF4D4A4A\": \"Bastion Grey\", \"#FF7E7466\": \"Bat Wing\", \"#FFFEFF00\": \"Bat-Signal\", \"#FFEE3366\": \"Bat\\u2019s Blood Soup\", \"#FF87B2C9\": \"Batch Blue\", \"#FF45392F\": \"Batch Brew\", \"#FF1B7598\": \"Bateau\", \"#FF7A5F5A\": \"Bateau Brown\", \"#FFD8E9DB\": \"Bath\", \"#FF0A696A\": \"Bath Green\", \"#FF411900\": \"Bath in Chocolate\", \"#FFBBDED7\": \"Bath Salt Green\", \"#FF62BAA8\": \"Bath Turquoise\", \"#FF88EEEE\": \"Bath Water\", \"#FFC2E0E3\": \"Bathe Blue\", \"#FF93C9D0\": \"Bathing\", \"#FF428267\": \"Bathing Beauty\", \"#FF7E738B\": \"Batik Lilac\", \"#FF9C657E\": \"Batik Pink\", \"#FF656E72\": \"Batman\", \"#FF866F5A\": \"Baton\", \"#FFB8292B\": \"Baton Rouge\", \"#FF1F1518\": \"Bats Cloak\", \"#FFEDE2D4\": \"Battered Sausage\", \"#FF1DACD4\": \"Battery Charged Blue\", \"#FF74828F\": \"Battle Blue\", \"#FF2B7414\": \"Battle Cat\", \"#FF7E8270\": \"Battle Dress\", \"#FF9C9C82\": \"Battle Harbour\", \"#FF9C9895\": \"Battleship\", \"#FF6F7476\": \"Battleship Grey Variant\", \"#FF11CC55\": \"Battletoad\", \"#FF595438\": \"Batu Cave\", \"#FF3F4040\": \"Bauhaus\", \"#FF006392\": \"Bauhaus Blue\", \"#FFCFB49E\": \"Bauhaus Buff\", \"#FFB0986F\": \"Bauhaus Gold\", \"#FFCCC4AE\": \"Bauhaus Tan\", \"#FF4D5E42\": \"Bavarian\", \"#FF1C3382\": \"Bavarian Blue\", \"#FFFFF9DD\": \"Bavarian Cream\", \"#FF20006D\": \"Bavarian Gentian\", \"#FF749A54\": \"Bavarian Green\", \"#FFACBF93\": \"Bavarian Hops\", \"#FF4D3113\": \"Bavarian Sweet Mustard\", \"#FFB3E2D3\": \"Bay\", \"#FFAFA490\": \"Bay Area\", \"#FF773300\": \"Bay Brown\", \"#FF9899B0\": \"Bay Fog\", \"#FF214048\": \"Bay Isle Pointe\", \"#FF86793D\": \"Bay Leaf Variant\", \"#FF85C5C8\": \"Bay Mist\", \"#FFBFC9D0\": \"Bay of Hope\", \"#FF353E64\": \"Bay of Many Variant\", \"#FFD2CDBC\": \"Bay Salt\", \"#FFC5BEAE\": \"Bay Sands\", \"#FFFBE6CD\": \"Bay Scallop\", \"#FF325F8A\": \"Bay Site\", \"#FF018486\": \"Bay Teal\", \"#FF6A819E\": \"Bay View\", \"#FFBFC2BF\": \"Bay Waves\", \"#FF747F89\": \"Bay Wharf\", \"#FF7B9AAD\": \"Bay\\u2019s Water\", \"#FF275A5D\": \"Bayberry\", \"#FFD0D9C7\": \"Bayberry Frost\", \"#FFB6AA89\": \"Bayberry Wax\", \"#FF0098D4\": \"Bayern Blue\", \"#FF268483\": \"Bayou\", \"#FF017992\": \"Bayou Serenade\", \"#FFBEB48E\": \"Bayou Shade\", \"#FF89CEE0\": \"Bayshore\", \"#FF5FC9BF\": \"Bayside\", \"#FFC9D8E4\": \"Baywater Blue\", \"#FF8F7777\": \"Bazaar Variant\", \"#FFA35046\": \"BBQ\", \"#FFF4E3E7\": \"Be Mine\", \"#FFEC9DC3\": \"Be My Valentine\", \"#FFA5CB66\": \"Be Spontaneous\", \"#FF9B983D\": \"Be Yourself\", \"#FFEFE4BB\": \"Beach\", \"#FFADB864\": \"Beach Bag\", \"#FFEFC700\": \"Beach Ball\", \"#FFB2E4CD\": \"Beach Blanket\", \"#FF5F9CA2\": \"Beach Blue\", \"#FFCEAB90\": \"Beach Boardwalk\", \"#FF91CBBF\": \"Beach Breeze\", \"#FFA69081\": \"Beach Cabana\", \"#FF665A38\": \"Beach Casuarina\", \"#FFCAAB84\": \"Beach Coast Buff\", \"#FF94ADB0\": \"Beach Cottage\", \"#FFC6BB9C\": \"Beach Dune\", \"#FFCDE0E1\": \"Beach Foam\", \"#FF96DFCE\": \"Beach Glass\", \"#FFDCDDB8\": \"Beach Grass\", \"#FFEDD481\": \"Beach House\", \"#FFCCDCDE\": \"Beach House Blue\", \"#FFBDA2C4\": \"Beach Lilac\", \"#FFFBD05C\": \"Beach Party\", \"#FFFBB88B\": \"Beach Sand\", \"#FF71CBD2\": \"Beach Sparkle\", \"#FFFCE3B3\": \"Beach Towel\", \"#FFFEDECA\": \"Beach Trail\", \"#FF819AAA\": \"Beach Umbrella\", \"#FF4F7694\": \"Beach View\", \"#FFDCE1E2\": \"Beach Wind\", \"#FFCAC0B0\": \"Beach Woods\", \"#FFD8E3E5\": \"Beachcomber\", \"#FFE4C683\": \"Beachcombing\", \"#FFFBEDD7\": \"Beaches of Cancun\", \"#FFACDBDB\": \"Beachside Drive\", \"#FFC3B296\": \"Beachside Villa\", \"#FFD2B17A\": \"Beachwalk\", \"#FFE6D0B6\": \"Beachy Keen\", \"#FFEBE8B9\": \"Beacon\", \"#FF265C98\": \"Beacon Blue\", \"#FFF2C98A\": \"Beacon Yellow\", \"#FF494D8B\": \"Beaded Blue\", \"#FF8D6737\": \"Beagle Brown\", \"#FF33FFFF\": \"Beaming Blue\", \"#FFFFF8DF\": \"Beaming Sun\", \"#FF4A1207\": \"Bean Variant\", \"#FF68755D\": \"Bean Counter\", \"#FF685C27\": \"Bean Green\", \"#FF8B6B51\": \"Bean Pot\", \"#FF91923A\": \"Bean Shoot\", \"#FFF3F9E9\": \"Bean Sprout\", \"#FFEBF0E4\": \"Bean White\", \"#FF31AA74\": \"Beanstalk\", \"#FF766E65\": \"Bear\", \"#FFAE6B52\": \"Bear Claw\", \"#FF836452\": \"Bear Creek\", \"#FF796359\": \"Bear Hug\", \"#FF5B4A44\": \"Bear in Mind\", \"#FF5A4943\": \"Bear Rug\", \"#FF7D756D\": \"Bearsuit\", \"#FFB08F69\": \"Beast Hide\", \"#FF680C08\": \"Beastly Red\", \"#FF663300\": \"Beasty Brown\", \"#FF6E6A44\": \"Beat Around the Bush\", \"#FF73372D\": \"Beaten Copper\", \"#FF4E0550\": \"Beaten Purple\", \"#FFD1BE92\": \"Beaten Track\", \"#FF448844\": \"Beating Around the Bush\", \"#FF5F8748\": \"Beatnik\", \"#FF7DB39E\": \"Beau Monde\", \"#FF0C6064\": \"Beau Vert\", \"#FF80304C\": \"Beaujolais\", \"#FF92774C\": \"Beaumont Brown\", \"#FF553F44\": \"Beauport Aubergine\", \"#FF186DB6\": \"Beautiful Blue\", \"#FF686D70\": \"Beautiful Darkness\", \"#FFB6C7E3\": \"Beautiful Dream\", \"#FF8DA936\": \"Beautiful Mint\", \"#FF866B8D\": \"Beauty\", \"#FFC99680\": \"Beauty and the Beach\", \"#FFEBB9B3\": \"Beauty Bush Variant\", \"#FF834F44\": \"Beauty Patch\", \"#FFBE5C87\": \"Beauty Queen\", \"#FFC79EA2\": \"Beauty Secret\", \"#FF604938\": \"Beauty Spot\", \"#FF997867\": \"Beaver Fur\", \"#FF60564C\": \"Beaver Pelt\", \"#FFF4EEE0\": \"B\\u00e9chamel\", \"#FF607879\": \"Becker Blue\", \"#FF7F7353\": \"Becker Gold\", \"#FF85A699\": \"Beckett\", \"#FF4BEC13\": \"Becquerel\", \"#FFB893AB\": \"Bed of Roses\", \"#FFD3B9CC\": \"Bedazzled\", \"#FF968775\": \"Bedbox\", \"#FFAA8880\": \"Bedford Brown\", \"#FF9E9D99\": \"Bedrock\", \"#FFC3ACB2\": \"Bedroom Plum\", \"#FFADB7C1\": \"Bedside Manner\", \"#FFE1B090\": \"Bedtime Story\", \"#FFF1BA55\": \"Bee\", \"#FFFFAA33\": \"Bee Cluster\", \"#FFF2CC64\": \"Bee Hall\", \"#FF735B3B\": \"Bee Master\", \"#FFEBCA70\": \"Bee Pollen\", \"#FFFEFF32\": \"Bee Yellow\", \"#FFE8D9D2\": \"Bee\\u2019s Knees\", \"#FF5B4F3B\": \"Beech\", \"#FF574128\": \"Beech Brown\", \"#FF758067\": \"Beech Fern\", \"#FFD7B59A\": \"Beech-Nut\", \"#FF6E5955\": \"Beechwood\", \"#FFB64701\": \"Beef Bourguignon\", \"#FFA85D2E\": \"Beef Hotpot\", \"#FFA25768\": \"Beef Jerky\", \"#FF8A4512\": \"Beef Noodle Broth\", \"#FFBB5533\": \"Beef Patties\", \"#FFDEBEEF\": \"Beefy Pink\", \"#FFE1B781\": \"Beehive\", \"#FFF6E491\": \"Beekeeper\", \"#FFFCAA12\": \"Beer\", \"#FF449933\": \"Beer Garden\", \"#FF773311\": \"Beer Glazed Bacon\", \"#FFE9D7AB\": \"Beeswax Variant\", \"#FFBF7E41\": \"Beeswax Candle\", \"#FFF5D297\": \"Beeswing\", \"#FF7E203F\": \"Beet Red\", \"#FFD4265D\": \"Beet Wave\", \"#FF90306A\": \"Beetiful Magenta\", \"#FF55584C\": \"Beetle\", \"#FF663F44\": \"Beetroot\", \"#FFD33376\": \"Beetroot Purple\", \"#FFC58F9D\": \"Beetroot Rice\", \"#FF736A86\": \"Beets\", \"#FF96496D\": \"Befitting\", \"#FF4D6A77\": \"Before the Storm\", \"#FFBD6F56\": \"Before Winter\", \"#FF5A4D39\": \"Beggar\", \"#FFFA6E79\": \"Begonia\", \"#FFC3797F\": \"Begonia Rose\", \"#FF848E8A\": \"Beguile\", \"#FF5E6F8E\": \"Beguiling Blue\", \"#FFAFA7AC\": \"Beguiling Mauve\", \"#FFE6DAA6\": \"Beige Variant\", \"#FFBBC199\": \"Beige and Sage\", \"#FFD6C5B4\": \"Beige Chalk\", \"#FFCFB095\": \"Beige Ganesh\", \"#FFE0D8B0\": \"Beige Green\", \"#FFC5A88D\": \"Beige Intenso\", \"#FF987A5B\": \"Beige Intuition\", \"#FFE2DAC6\": \"Beige Linen\", \"#FFDE9408\": \"Beige Red\", \"#FFCFC8B8\": \"Beige Royal\", \"#FFFFC87C\": \"Beige Topaz\", \"#FFECCC9B\": \"Beignet\", \"#FF3E7DAA\": \"Beijing Blue\", \"#FFA9A2A3\": \"Beijing Moon\", \"#FF25A26F\": \"Bejewelled\", \"#FF819AC1\": \"Bel Air Blue\", \"#FF9BBCC3\": \"Bel Esprit\", \"#FF558D4F\": \"Belfast\", \"#FFBB937F\": \"Belfry Brick\", \"#FF9BA29E\": \"Belgian Block\", \"#FFF7EFD0\": \"Belgian Blonde\", \"#FFF9F1E2\": \"Belgian Cream\", \"#FF8D7560\": \"Belgian Sweet\", \"#FFF3DFB6\": \"Belgian Waffle\", \"#FFDBC7A8\": \"Believable Buff\", \"#FF7FD3D3\": \"Belize\", \"#FFB9C3B3\": \"Belize Green\", \"#FF618B97\": \"Bell Blue\", \"#FFA475B1\": \"Bell Heather\", \"#FFDAD0BB\": \"Bell Tower\", \"#FF574057\": \"Bella\", \"#FF93C3B1\": \"Bella Green\", \"#FFDAC5BD\": \"Bella Mia\", \"#FFE08194\": \"Bella Pink\", \"#FF40465D\": \"Bella Sera\", \"#FF0B695B\": \"Bella Vista\", \"#FF220011\": \"Belladonna\", \"#FFADC3A7\": \"Belladonna\\u2019s Leaf\", \"#FFB7DFF3\": \"Bellagio Fountains\", \"#FFF2B400\": \"Bellagio Gold\", \"#FFE3CBC0\": \"Belle of the Ball\", \"#FF5D66AA\": \"Bellflower\", \"#FFE1E9EF\": \"Bellflower Blue\", \"#FFB2A5B7\": \"Bellflower Violet\", \"#FFF4C9B1\": \"Bellini\", \"#FFF5C78E\": \"Bellini Fizz\", \"#FFEDE3A1\": \"Bells and Whistles Gold\", \"#FF773B38\": \"Belly Fire\", \"#FF00817F\": \"Belly Flop\", \"#FF626A60\": \"Belmont Green\", \"#FFB3B4DD\": \"Beloved\", \"#FFE9D3D4\": \"Beloved Pink\", \"#FFFFBA24\": \"Beloved Sunflower\", \"#FF0A2F7C\": \"Below the Surface\", \"#FF87CDED\": \"Below Zero\", \"#FFEFF2F1\": \"Beluga\", \"#FFD7D2D2\": \"Beluga Song\", \"#FFE3DBC3\": \"Belvedere Cream\", \"#FFF0F1E1\": \"Belyi White\", \"#FF694977\": \"Benevolence\", \"#FFDD1188\": \"Benevolent Pink\", \"#FFCC974D\": \"Bengal\", \"#FF38738B\": \"Bengal Blue\", \"#FF8E773F\": \"Bengal Grass\", \"#FF8F2E14\": \"Bengala Red\", \"#FF913225\": \"Bengara Red\", \"#FFB85241\": \"Beni Shoga\", \"#FFBB7796\": \"Benifuji\", \"#FFF35336\": \"Benihi Red\", \"#FF5A4F74\": \"Benikakehana Purple\", \"#FF44312E\": \"Benikeshinezumi Purple\", \"#FF78779B\": \"Benimidori Purple\", \"#FF007BAA\": \"Benitoite\", \"#FFFB8136\": \"Beniukon Bronze\", \"#FF000011\": \"Benthic Black\", \"#FFCC363C\": \"Bento Box\", \"#FF00D973\": \"Benzol Green\", \"#FFD8CFB6\": \"Berber\", \"#FF95C703\": \"Bergamot\", \"#FFF59D59\": \"Bergamot Orange\", \"#FFB8C7DB\": \"Beribboned\", \"#FF4B596E\": \"Bering Sea\", \"#FF3D6D84\": \"Bering Wave\", \"#FF7E613F\": \"Berkeley Hills\", \"#FFF0E1CF\": \"Berkshire Lace\", \"#FF5588CC\": \"Berlin Blue\", \"#FF1B7D8D\": \"Bermuda Variant\", \"#FF8CB1C2\": \"Bermuda Blue\", \"#FF9D5A8F\": \"Bermuda Onion\", \"#FFDACBBF\": \"Bermuda Sand\", \"#FFF9EEE3\": \"Bermuda Shell\", \"#FFF0E9BE\": \"Bermuda Son\", \"#FF6F8C9F\": \"Bermuda Triangle\", \"#FF6BC271\": \"Bermudagrass\", \"#FF386171\": \"Bermudan Blue\", \"#FFE20909\": \"Bern Red\", \"#FFAB7CB4\": \"Berries Galore\", \"#FFF2B8CA\": \"Berries N\\u2019 Cream\", \"#FF990F4B\": \"Berry\", \"#FF662277\": \"Berry Blackmail\", \"#FFFF017F\": \"Berry Blast\", \"#FF9E8295\": \"Berry Bliss\", \"#FF32607A\": \"Berry Blue\", \"#FF264B56\": \"Berry Blue Green\", \"#FFB88591\": \"Berry Blush\", \"#FFBB5588\": \"Berry Boost\", \"#FF7D5857\": \"Berry Brandy\", \"#FFA08497\": \"Berry Bright\", \"#FF544F4C\": \"Berry Brown\", \"#FFAC72AF\": \"Berry Burst\", \"#FF77424E\": \"Berry Bush\", \"#FFEFCEDC\": \"Berry Butter\", \"#FFA6AEBB\": \"Berry Chalk\", \"#FF4F4763\": \"Berry Charm\", \"#FFF8E3DD\": \"Berry Cheesecake\", \"#FF3F000F\": \"Berry Chocolate\", \"#FF765269\": \"Berry Conserve\", \"#FF9A8CA2\": \"Berry Cream\", \"#FFAA6772\": \"Berry Crush\", \"#FF9B1C5D\": \"Berry Curious\", \"#FFB3A1C6\": \"Berry Frapp\\u00e9\", \"#FFEBDED7\": \"Berry Frost\", \"#FFEDC3C5\": \"Berry Good\", \"#FF655883\": \"Berry Jam\", \"#FF673B66\": \"Berry Light\", \"#FF555A90\": \"Berry Mix\", \"#FFB6CACA\": \"Berry Mojito\", \"#FF84395D\": \"Berry Patch\", \"#FF4F6D8E\": \"Berry Pie\", \"#FFD6A5CD\": \"Berry Popsicle\", \"#FFA0688D\": \"Berry Pretty\", \"#FFE5A2AB\": \"Berry Riche\", \"#FF992244\": \"Berry Rossi\", \"#FF895360\": \"Berry Smoothie\", \"#FF64537C\": \"Berry Syrup\", \"#FFECD5D9\": \"Berry Taffy\", \"#FFD78BAD\": \"Berry Twist\", \"#FF624D55\": \"Berry Wine\", \"#FFD75E6C\": \"Berrylicious\", \"#FF45DCFF\": \"Berta Blue\", \"#FFBFE4D4\": \"Beru\", \"#FF7082A4\": \"Berwick Berry\", \"#FF71DCB8\": \"Beryl\", \"#FF2B322D\": \"Beryl Black Green\", \"#FFBCBFA8\": \"Beryl Green Variant\", \"#FFE2E3DF\": \"Beryl Pearl\", \"#FFA16381\": \"Beryl Red\", \"#FFE9E5D7\": \"Beryllonite\", \"#FFD4BA9D\": \"Bespoke\", \"#FF685E5B\": \"Bessie\", \"#FFC6B49C\": \"Best Beige\", \"#FF5D513E\": \"Best Bronze\", \"#FFB9B7BD\": \"Best in Show\", \"#FF01809F\": \"Best of Both Worlds\", \"#FFF7F2D9\": \"Best of Summer\", \"#FFBD5442\": \"Best of the Bunch\", \"#FFCD343D\": \"Bestial Blood\", \"#FF6B3900\": \"Bestial Brown\", \"#FF992211\": \"Bestial Red\", \"#FFD38A57\": \"Bestigor\", \"#FF7D655C\": \"Betalain Red\", \"#FF352925\": \"Betel Nut Dye\", \"#FFCADBBD\": \"Bethany\", \"#FFEE0022\": \"Bethlehem Red\", \"#FFEAEEDA\": \"Bethlehem Superstar\", \"#FF73C9D9\": \"Betsy\", \"#FF3A6B66\": \"Betta Fish\", \"#FFEBE2CB\": \"Better Than Beige\", \"#FFEDE1BE\": \"Beurre Blanc\", \"#FF7ACCB8\": \"Bevelled Glass\", \"#FF75AC16\": \"Bevelled Grass\", \"#FF6A393C\": \"Bewitched\", \"#FF75495E\": \"Bewitching\", \"#FFBBD0E3\": \"Bewitching Blue\", \"#FFAAEEFF\": \"Beyond the Clouds\", \"#FFF7D6BA\": \"Beyond the Pale\", \"#FF688049\": \"Beyond the Pines\", \"#FF005784\": \"Beyond the Sea\", \"#FF0A3251\": \"Beyond the Stars\", \"#FFD7E0EB\": \"Beyond the Wall\", \"#FFDBB0D3\": \"Bff\", \"#FF70C0E2\": \"Bff Blue\", \"#FF947706\": \"Bh\\u016br\\u0101 Brown\", \"#FF1C5022\": \"Bia\\u0142owie\\u017ca Forest\", \"#FFF4EFE0\": \"Bianca Variant\", \"#FF3DCFC2\": \"Bianchi Green\", \"#FFFFE58C\": \"Bicycle Yellow\", \"#FF802C3A\": \"Bicyclette\", \"#FFA9B9B5\": \"Bidwell Blue\", \"#FFB19C8F\": \"Bidwell Brown\", \"#FF507CA0\": \"Biedermeier Blue\", \"#FF1BA169\": \"Biel-Tan Green\", \"#FFF0908D\": \"Bierwurst\", \"#FF908C84\": \"Big Apple\", \"#FFAFABA0\": \"Big Band\", \"#FFFF0099\": \"Big Bang Pink\", \"#FFFFDA8B\": \"Big Bus Yellow\", \"#FF7ECBE2\": \"Big Chill\", \"#FFB98675\": \"Big Cypress\", \"#FF5D6B75\": \"Big Daddy Blue\", \"#FF41494B\": \"Big Dipper\", \"#FF99A38E\": \"Big Fish\", \"#FFDADBE1\": \"Big Fish Variant\", \"#FFE88E5A\": \"Big Foot Feet\", \"#FFB79E94\": \"Big Horn Mountains\", \"#FF34708F\": \"Big Ocean Wave\", \"#FFCDE2DE\": \"Big Sky\", \"#FF85C4C9\": \"Big Sky Country\", \"#FFACDDAF\": \"Big Spender\", \"#FF334046\": \"Big Stone Variant\", \"#FF886E54\": \"Big Stone Beach\", \"#FFB3CADC\": \"Big Sur\", \"#FF3F6E8E\": \"Big Sur Blue Jade\", \"#FF96D0D1\": \"Big Surf\", \"#FFFFEE22\": \"Big Yellow Streak\", \"#FFFFFF33\": \"Big Yellow Taxi\", \"#FF715145\": \"Bigfoot\", \"#FF20120E\": \"Bighorn Sheep\", \"#FF4E5E7F\": \"Bijou Blue\", \"#FFA33D3B\": \"Bijou Red\", \"#FF676B55\": \"Bijoux Green\", \"#FF7B222A\": \"Biking Red\", \"#FFC3C0B1\": \"Biking Trail\", \"#FF3E8027\": \"Bilbao Variant\", \"#FF71777E\": \"Bilberry\", \"#FFB5C306\": \"Bile\", \"#FFE39F08\": \"Bilious Brown\", \"#FFA9D171\": \"Bilious Green\", \"#FF1B6F81\": \"Billabong\", \"#FFAD7C35\": \"Billet\", \"#FF00AF9F\": \"Billiard\", \"#FF276B40\": \"Billiard Ball\", \"#FF305A4A\": \"Billiard Green\", \"#FF50846E\": \"Billiard Room\", \"#FF155843\": \"Billiard Table\", \"#FF01B44C\": \"Billiards Cloth\", \"#FF83C0E5\": \"Billow\", \"#FFD8DEE3\": \"Billowing Clouds\", \"#FFD2E3E3\": \"Billowing Sail\", \"#FF6E726A\": \"Billowing Smoke\", \"#FFAFC7CD\": \"Billowy Breeze\", \"#FFF6F0E9\": \"Billowy Clouds\", \"#FFEFF0E9\": \"Billowy Down\", \"#FF4C77A4\": \"Billycart Blue\", \"#FFAE99D2\": \"Biloba Flower Variant\", \"#FFF4E4CD\": \"Biloxi\", \"#FF0075B8\": \"Biloxi Blue\", \"#FFE3C9A1\": \"Biltmore Buff\", \"#FF410200\": \"Biltong\", \"#FF54682B\": \"Bimi Green\", \"#FF007A91\": \"Bimini Blue\", \"#FF010101\": \"Binary Black\", \"#FF616767\": \"Binary Star\", \"#FF8B3439\": \"Bindi Dot\", \"#FFB0003C\": \"Bindi Red\", \"#FFAF4967\": \"Bing Cherry Pie\", \"#FF433D3C\": \"Binrouji Black\", \"#FF465F9E\": \"Bio Blue\", \"#FFFBFB4C\": \"Biohazard Suit\", \"#FF91A135\": \"Biology Experiments\", \"#FF55EEFF\": \"Bioluminescence\", \"#FF66FF55\": \"Biopunk\", \"#FF889900\": \"BioShock\", \"#FFEEEE44\": \"Biotic Grasp\", \"#FFEEDD55\": \"Biotic Orb\", \"#FF3F3726\": \"Birch Variant\", \"#FFD9C3A1\": \"Birch Beige\", \"#FF899A8B\": \"Birch Forest\", \"#FF637E1D\": \"Birch Leaf Green\", \"#FFDFB45F\": \"Birch Strain\", \"#FFF6EEDF\": \"Birch White\", \"#FFCCBEAC\": \"Birchwood\", \"#FF806843\": \"Birchy Woods\", \"#FFCDDFE7\": \"Bird Bath Blue\", \"#FF7B929E\": \"Bird Blue\", \"#FF7F92A0\": \"Bird Blue Grey\", \"#FFD0C117\": \"Bird Flower Variant\", \"#FFFFF1CF\": \"Bird\\u2019s Child\", \"#FFAACCB9\": \"Bird\\u2019s Egg Green\", \"#FFCFBB9B\": \"Bird\\u2019s Nest\", \"#FFAB823D\": \"Bird\\u2019s-Eye\", \"#FFE4C495\": \"Bird\\u2019s-Eye Maple\", \"#FF6C483A\": \"Birdhouse Brown\", \"#FFE9E424\": \"Birdie\", \"#FF89ACDA\": \"Birdie Num Num\", \"#FFE2C28E\": \"Birdseed\", \"#FF2F3946\": \"Biro Blue\", \"#FF224634\": \"Bir\\u014ddo Green\", \"#FFFCE9DF\": \"Birth of a Star\", \"#FFF6EBC2\": \"Birth of Venus\", \"#FFE9D2CC\": \"Birthday Cake\", \"#FFCFA2AD\": \"Birthday Candle\", \"#FF9BDCB9\": \"Birthday King\", \"#FFE2C7B6\": \"Birthday Suit\", \"#FF79547A\": \"Birthstone\", \"#FF2F3C53\": \"Biscay Variant\", \"#FF097988\": \"Biscay Bay\", \"#FF55C6A9\": \"Biscay Green\", \"#FFD8C3A7\": \"Biscotti\", \"#FFFEEDCA\": \"Biscuit\", \"#FFE6BFA6\": \"Biscuit Beige\", \"#FFF9CCB7\": \"Biscuit Cream\", \"#FFE3CFB8\": \"Biscuit Crumbs\", \"#FFE8DBBD\": \"Biscuit Dough\", \"#FFC473A9\": \"Bishop Red\", \"#FF486C7A\": \"Bismarck\", \"#FF6E4F3A\": \"Bison\", \"#FF9F9180\": \"Bison Beige\", \"#FF584941\": \"Bison Brown\", \"#FFB5AC94\": \"Bison Hide Variant\", \"#FFE5D2B0\": \"Bisque Tan\", \"#FF705950\": \"Bistro\", \"#FF395551\": \"Bistro Green\", \"#FFECE3DC\": \"Bistro Napkin\", \"#FFE3B8B7\": \"Bistro Pink\", \"#FFECE8E1\": \"Bistro White\", \"#FFDD5599\": \"Bit of Berry\", \"#FFD9E3E5\": \"Bit of Blue\", \"#FFCAD7DE\": \"Bit of Heaven\", \"#FFE1E5AC\": \"Bit of Lime\", \"#FFF4F2EC\": \"Bit of Sugar\", \"#FFFFBB11\": \"Bitcoin\", \"#FFD47D72\": \"Bite My Tongue\", \"#FF88896C\": \"Bitter Variant\", \"#FF8D7470\": \"Bitter Briar\", \"#FF4F2923\": \"Bitter Chocolate\", \"#FF769789\": \"Bitter Clover Green\", \"#FF6ECB3C\": \"Bitter Dandelion\", \"#FFD2DB32\": \"Bitter Lemon Variant\", \"#FFCFFF00\": \"Bitter Lime\", \"#FF31CD31\": \"Bitter Lime and Defeat\", \"#FF262926\": \"Bitter Liquorice\", \"#FFCFD1B2\": \"Bitter Melon\", \"#FFD5762B\": \"Bitter Orange\", \"#FF97A18D\": \"Bitter Sage\", \"#FF856D9E\": \"Bitter Violet\", \"#FFFEA051\": \"Bittersweet Variant\", \"#FF4F2B17\": \"Bittersweet Chocolate\", \"#FF5B5354\": \"Bittersweet Molasses\", \"#FFBF4F51\": \"Bittersweet Shimmer\", \"#FFCBB49A\": \"Bittersweet Stem\", \"#FFE7D2C8\": \"Bizarre Variant\", \"#FF5B5D53\": \"Black Bamboo\", \"#FF474A4E\": \"Black Bay\", \"#FF4E4B4A\": \"Black Bean Variant\", \"#FF23262B\": \"Black Beauty\", \"#FF2F2F48\": \"Black Blueberry\", \"#FF454749\": \"Black Boudoir\", \"#FF0F282F\": \"Black Box\", \"#FF2E2F31\": \"Black Cat\", \"#FF102C33\": \"Black Chasm\", \"#FF2C1620\": \"Black Cherry\", \"#FF252321\": \"Black Chestnut Oak\", \"#FF441100\": \"Black Chocolate\", \"#FF3E3231\": \"Black Coffee\", \"#FF4E434D\": \"Black Dahlia\", \"#FF8A779A\": \"Black Diamond Apple\", \"#FF545562\": \"Black Dragon\\u2019s Cauldron\", \"#FF90ABD9\": \"Black Drop\", \"#FFA66E7A\": \"Black Elder\", \"#FF50484A\": \"Black Elegance\", \"#FF12221D\": \"Black Emerald\", \"#FF45524F\": \"Black Evergreen\", \"#FF112222\": \"Black Feather\", \"#FF484B5A\": \"Black Flame\", \"#FF5E6354\": \"Black Forest Variant\", \"#FF29485A\": \"Black Forest Blue\", \"#FF424740\": \"Black Forest Green\", \"#FF4F4842\": \"Black Fox\", \"#FF4E4444\": \"Black Garnet\", \"#FF001111\": \"Black Glaze\", \"#FF384E49\": \"Black Green\", \"#FF24272E\": \"Black Grey\", \"#FFE0DED7\": \"Black Haze Variant\", \"#FF9C856C\": \"Black Headed Gull\", \"#FF444647\": \"Black Heron\", \"#FFC89180\": \"Black Hills Gold\", \"#FF202030\": \"Black Howl\", \"#FF110033\": \"Black Htun\", \"#FF4D5051\": \"Black Ice\", \"#FF2B3042\": \"Black Iris\", \"#FF0F1519\": \"Black Is Back\", \"#FF74563D\": \"Black Jasmine Rice\", \"#FF351E1C\": \"Black Kite\", \"#FF3F3E3E\": \"Black Lacquer\", \"#FF474C4D\": \"Black Lead\", \"#FF253529\": \"Black Leather Jacket\", \"#FF3A3B3B\": \"Black Liquorice\", \"#FF646763\": \"Black Locust\", \"#FF4F4554\": \"Black Magic\", \"#FF858585\": \"Black Mana\", \"#FF222244\": \"Black Market\", \"#FF383740\": \"Black Marlin Variant\", \"#FF222211\": \"Black Mesa\", \"#FF060606\": \"Black Metal\", \"#FF4B4743\": \"Black Mocha\", \"#FF4E4F4E\": \"Black Oak\", \"#FF323639\": \"Black of Night\", \"#FF2A272C\": \"Black Onyx\", \"#FF525463\": \"Black Orchid\", \"#FF424242\": \"Black Panther\", \"#FF1E272C\": \"Black Pearl Variant\", \"#FF33654A\": \"Black Pine Green\", \"#FF77606F\": \"Black Plum\", \"#FF4F5552\": \"Black Pool\", \"#FF34342C\": \"Black Powder\", \"#FF654B37\": \"Black Power\", \"#FFA44A56\": \"Black Pudding\", \"#FF694D27\": \"Black Queen\", \"#FF16110D\": \"Black Raspberry\", \"#FF484C51\": \"Black Ribbon\", \"#FF343E54\": \"Black River Falls\", \"#FF2C2D3C\": \"Black Rock Variant\", \"#FF331111\": \"Black Rooster\", \"#FF532934\": \"Black Rose Variant\", \"#FF24252B\": \"Black Russian Variant\", \"#FF220022\": \"Black Sabbath\", \"#FF434B4D\": \"Black Sable\", \"#FF302833\": \"Black Safflower\", \"#FF5B4E4B\": \"Black Sand\", \"#FF434555\": \"Black Sapphire\", \"#FF052462\": \"Black Sea Night\", \"#FF0F0D0D\": \"Black Sheep\", \"#FF332211\": \"Black Slug\", \"#FF3E3E3F\": \"Black Smoke\", \"#FF19443C\": \"Black Soap\", \"#FF545354\": \"Black Space\", \"#FF4C5752\": \"Black Spruce\", \"#FFE5E6DF\": \"Black Squeeze Variant\", \"#FF0E191C\": \"Black Stallion\", \"#FF434342\": \"Black Suede\", \"#FF332200\": \"Black Swan\", \"#FF464647\": \"Black Tie\", \"#FF353235\": \"Black Tortoise\", \"#FF463D3E\": \"Black Truffle\", \"#FF2C4364\": \"Black Turmeric\", \"#FF1F1916\": \"Black Umber\", \"#FF222233\": \"Black Velvet\", \"#FF2B2C42\": \"Black Violet\", \"#FF5E4F46\": \"Black Walnut\", \"#FF0C0C0C\": \"Black Wash\", \"#FFE5E4DB\": \"Black White Variant\", \"#FFE5B6A2\": \"Black-Eyed Peach\", \"#FF3E1825\": \"Black-Hearted\", \"#FF292C2C\": \"Blackadder\", \"#FF43182F\": \"Blackberry Variant\", \"#FF2E2848\": \"Blackberry Black\", \"#FF4C3938\": \"Blackberry Burgundy\", \"#FF404D6A\": \"Blackberry Cobbler\", \"#FF4F3357\": \"Blackberry Cordial\", \"#FFD9D3DA\": \"Blackberry Cream\", \"#FF633654\": \"Blackberry Deep Red\", \"#FF62506B\": \"Blackberry Farm\", \"#FF504358\": \"Blackberry Harvest\", \"#FF87657E\": \"Blackberry Jam\", \"#FF507F6D\": \"Blackberry Leaf Green\", \"#FFA58885\": \"Blackberry Mocha\", \"#FF64242E\": \"Blackberry Pie\", \"#FFC1A3B9\": \"Blackberry Sorbet\", \"#FF563342\": \"Blackberry Tart\", \"#FF8F5973\": \"Blackberry Tint\", \"#FF5C3C55\": \"Blackberry Wine\", \"#FFE5BDDF\": \"Blackberry Yoghurt\", \"#FF3F444C\": \"Blackbird\", \"#FFFCE7E4\": \"Blackbird\\u2019s Egg\", \"#FF274C43\": \"Blackboard Green\", \"#FF2E183B\": \"Blackcurrant Variant\", \"#FF52383D\": \"Blackcurrant Conserve\", \"#FF5C4F6A\": \"Blackcurrant Elixir\", \"#FF442200\": \"Blackened Brown\", \"#FF504D53\": \"Blackened Pearl\", \"#FF77150E\": \"Blackened Sun\", \"#FF662266\": \"Blackest Berry\", \"#FF403330\": \"Blackest Brown\", \"#FF7A5901\": \"Blackfire Earth\", \"#FF453B32\": \"Blackish Brown\", \"#FF5D6161\": \"Blackish Green\", \"#FF5B5C61\": \"Blackish Grey\", \"#FF51504D\": \"Blackjack\", \"#FF221133\": \"Blacklist\", \"#FF220066\": \"Blackmail\", \"#FF020F03\": \"Blackn\\u2019t\", \"#FF0E0702\": \"Blackout\", \"#FFF7E856\": \"Blacksmith Fire\", \"#FF8470FF\": \"Blackthorn Berry\", \"#FF4C606B\": \"Blackthorn Blue\", \"#FF739C69\": \"Blackthorn Green\", \"#FF545663\": \"Blackwater\", \"#FF696268\": \"Blackwater Park\", \"#FF494E52\": \"Blackwood\", \"#FF6A9266\": \"Blade Green\", \"#FFD43C35\": \"Blade Runner Red\", \"#FF758269\": \"Bladed Grass\", \"#FF6A8561\": \"Bladerunner\", \"#FFA1BDE0\": \"Blair\", \"#FFD9D0C2\": \"Blanc\", \"#FFF1EEE2\": \"Blanc Cass\\u00e9\", \"#FFE4E7E4\": \"Blanc de Blanc\", \"#FFF8F9F4\": \"Blanca Peak\", \"#FFF6DCD0\": \"Blanched\", \"#FFCCBEB6\": \"Blanched Driftwood\", \"#FF949579\": \"Blanched Thyme\", \"#FFEBEAE5\": \"Blanco\", \"#FFAFA88B\": \"Bland\", \"#FF74915F\": \"Bland Celery\", \"#FFFFEFD6\": \"Blank Canvas\", \"#FF505150\": \"Blank Space\", \"#FF8B9CAC\": \"Blank Stare\", \"#FF9CD33C\": \"Blanka Green\", \"#FF9E8574\": \"Blanket Brown\", \"#FF00C08E\": \"Blarney\", \"#FF027944\": \"Blarney Stone\", \"#FF3356AA\": \"Blasphemous Blue\", \"#FFE57E37\": \"Blast Burn\", \"#FF6C3550\": \"Blasted Lands Rocks\", \"#FFFA8C4F\": \"Blaze\", \"#FF420420\": \"Blaze It Dark Magenta\", \"#FFFE6700\": \"Blaze Orange Variant\", \"#FFB8524B\": \"Blazer\", \"#FFE94E41\": \"Blazing\", \"#FFF3AD63\": \"Blazing Autumn\", \"#FFFFA035\": \"Blazing Bonfire\", \"#FFFF0054\": \"Blazing Dragonfruit\", \"#FFFFA64F\": \"Blazing Orange\", \"#FFFEE715\": \"Blazing Yellow\", \"#FFE35F1C\": \"Blazon Skies\", \"#FFEBE1CE\": \"Bleach White Variant\", \"#FFF3EAD5\": \"Bleached Almond\", \"#FFFBCAAD\": \"Bleached Apricot\", \"#FFBCE3DF\": \"Bleached Aqua\", \"#FFD0C7C3\": \"Bleached Bare\", \"#FF8B7F78\": \"Bleached Bark\", \"#FFDFDDD0\": \"Bleached Beige\", \"#FFEFD9A8\": \"Bleached Bone\", \"#FFFFD6D1\": \"Bleached Coral\", \"#FF6D76A1\": \"Bleached Denim\", \"#FF788878\": \"Bleached Grey\", \"#FFE2E6D1\": \"Bleached Jade\", \"#FFF3ECE1\": \"Bleached Linen\", \"#FFC7A06C\": \"Bleached Maple\", \"#FFEAE5D5\": \"Bleached Meadow\", \"#FF55BB88\": \"Bleached Olive\", \"#FFD9D1BA\": \"Bleached Pebble\", \"#FFD5C3AA\": \"Bleached Sand\", \"#FFF6E5DA\": \"Bleached Shell\", \"#FFF3F3F2\": \"Bleached Silk\", \"#FFBAD7AE\": \"Bleached Spruce\", \"#FFFBE8A8\": \"Bleached Sunflower\", \"#FFDDD2A9\": \"Bleached Wheat\", \"#FFDFE3E8\": \"Bleached White\", \"#FFC7C7C3\": \"Bleaches\", \"#FF9B1414\": \"Bleeding Crimson\", \"#FFC02E4C\": \"Bleeding Heart\", \"#FFA9C4C4\": \"Blende Blue\", \"#FFF8E3A4\": \"Blended Fruit\", \"#FFFFFBE8\": \"Blended Light\", \"#FF4499CC\": \"Blessed Blue\", \"#FF007BA1\": \"Bleu Ciel\", \"#FFAAC0C4\": \"Bleu Clair\", \"#FF9CC2BF\": \"Bleu Nattier\", \"#FF4488FF\": \"Bleuch\\u00e2tel Blue\", \"#FFBCAEA1\": \"Blind Date\", \"#FF223300\": \"Blind Forest\", \"#FF4A4F51\": \"Blindfold\", \"#FF5A5E61\": \"Blindfolded\", \"#FFEEF0CE\": \"Bling Bling\", \"#FF0033FF\": \"Blinking Blue\", \"#FF66CC00\": \"Blinking Terminal\", \"#FF7AC7E1\": \"Bliss Blue\", \"#FFDDC4D4\": \"Blissful\", \"#FFAA1188\": \"Blissful Berry\", \"#FFB2C8D8\": \"Blissful Blue\", \"#FFE5D2DD\": \"Blissful Light\", \"#FFD5DAEE\": \"Blissful Meditation\", \"#FFFFAC39\": \"Blissful Orange\", \"#FFEAEED8\": \"Blissful Serenity\", \"#FFDAB6CD\": \"Blissfully Mine\", \"#FFAAFFEE\": \"Blister Pearl\", \"#FFFF6C51\": \"Blistering Mars\", \"#FF0099D1\": \"Blithe\", \"#FF90BDBD\": \"Blithe Blue\", \"#FFC0C1B9\": \"Blithe Mood\", \"#FFE5EBED\": \"Blizzard\", \"#FFD6D8D1\": \"Blizzard Fog\", \"#FF1151B4\": \"Blizzy Blueberry\", \"#FFD0B8BF\": \"Blobfish\", \"#FFE8BC50\": \"Blockchain Gold\", \"#FFDCBD92\": \"Blonde\", \"#FFF2EFCD\": \"Blonde Beauty\", \"#FFEFE2C5\": \"Blonde Curl\", \"#FFEDC558\": \"Blonde Girl\", \"#FFD6B194\": \"Blonde Lace\", \"#FFF6EDCD\": \"Blonde Shell\", \"#FFAB7741\": \"Blonde Wood\", \"#FFE5D0B1\": \"Blonde Wool\", \"#FF770001\": \"Blood\", \"#FF770011\": \"Blood Brother\", \"#FFFF474C\": \"Blood Burst\", \"#FFEA1822\": \"Blood Donor\", \"#FF67080B\": \"Blood God\", \"#FFC30B0A\": \"Blood Kiss\", \"#FF543839\": \"Blood Mahogany\", \"#FFD83432\": \"Blood Moon\", \"#FF85323C\": \"Blood Oath\", \"#FFE0413A\": \"Blood of My Enemies\", \"#FF8A0303\": \"Blood Omen\", \"#FFD1001C\": \"Blood Orange\", \"#FFFE4B03\": \"Blood Orange Juice\", \"#FF630F0F\": \"Blood Organ\", \"#FF771111\": \"Blood Pact\", \"#FF73404D\": \"Blood Rose\", \"#FFAA2222\": \"Blood Rush\", \"#FFBB5511\": \"Bloodhound\", \"#FF882200\": \"Bloodline\", \"#FF6B1C1A\": \"Bloodlust\", \"#FFF02723\": \"Bloodmyst Isle\", \"#FFBA271A\": \"Bloodshed\", \"#FFB52F3A\": \"Bloodsport\", \"#FF413431\": \"Bloodstone\", \"#FF880011\": \"Bloodthirsty\", \"#FFF8D7D0\": \"Bloodthirsty Beige\", \"#FFC6101E\": \"Bloodthirsty Lips\", \"#FF9B0503\": \"Bloodthirsty Vampire\", \"#FFEC1837\": \"Bloodthirsty Warlock\", \"#FF703F00\": \"Bloodtracker Brown\", \"#FFBA0105\": \"Bloody Mary\", \"#FFAA1144\": \"Bloody Periphylla\", \"#FFFF004D\": \"Bloody Pico-8\", \"#FFCA1F1B\": \"Bloody Red\", \"#FFA81C1D\": \"Bloody Ruby\", \"#FFC53D43\": \"Bloody Safflower\", \"#FFCC4433\": \"Bloody Salmon\", \"#FFFFAF75\": \"Bloom\", \"#FFD7E2EE\": \"Blooming Aster\", \"#FFE77F71\": \"Blooming Dahlia\", \"#FFBA93AF\": \"Blooming Lilac\", \"#FFD89696\": \"Blooming Perfect\", \"#FF88777E\": \"Blooming Wisteria\", \"#FFA598C4\": \"Bloomsberry\", \"#FFFEE9D8\": \"Blossom Variant\", \"#FFAACCEE\": \"Blossom Blue\", \"#FFA3A7CC\": \"Blossom Mauve\", \"#FFC3B3B9\": \"Blossom Powder\", \"#FFE5D2C9\": \"Blossom Time\", \"#FFFBD6CA\": \"Blossom Tint\", \"#FFFFC9DB\": \"Blossom Tree\", \"#FFE1C77D\": \"Blossom Yellow\", \"#FFDE5346\": \"Blossoming Dynasty\", \"#FFE79ACB\": \"Blossoms in Spring\", \"#FF67B7C6\": \"Blouson Blue\", \"#FFF6DEE0\": \"Blowing Kisses\", \"#FFD2D1D0\": \"Blowing Smoke\", \"#FF658499\": \"Blowout\", \"#FF25415D\": \"Blue Accolade\", \"#FFB1C6C7\": \"Blue Agave\", \"#FF89A3AE\": \"Blue Alps\", \"#FF5A79BA\": \"Blue Android Base\", \"#FFF8B800\": \"Blue Angels Yellow\", \"#FFA7CFCB\": \"Blue Angora\", \"#FF0085A1\": \"Blue Arc\", \"#FFA9B7B8\": \"Blue Arrow\", \"#FF414654\": \"Blue Ash\", \"#FF406482\": \"Blue Ashes\", \"#FF50A7D9\": \"Blue Astro\", \"#FF00B3E1\": \"Blue Atoll\", \"#FF6C7386\": \"Blue Aura\", \"#FF7498BD\": \"Blue Ballad\", \"#FFB4C7DB\": \"Blue Ballerina\", \"#FF576B6B\": \"Blue Ballet\", \"#FF6976A3\": \"Blue Batik\", \"#FFABDEE3\": \"Blue Bauble\", \"#FF619AD6\": \"Blue Bay\", \"#FF2D5360\": \"Blue Bayberry\", \"#FFBEC4D3\": \"Blue Bayou\", \"#FF017CB8\": \"Blue Bazaar\", \"#FF5A809E\": \"Blue Beads\", \"#FF7498BF\": \"Blue Beauty\", \"#FF220099\": \"Blue Beetle\", \"#FF40638E\": \"Blue Beret\", \"#FF91B8D9\": \"Blue Beyond\", \"#FF00BBEE\": \"Blue Bikini\", \"#FF237FAC\": \"Blue Bird Day\", \"#FF86B8CB\": \"Blue Bird Morning\", \"#FF52593B\": \"Blue Black Crayfish\", \"#FF6B7F81\": \"Blue Blood\", \"#FF94A4B9\": \"Blue Blouse\", \"#FF2242C7\": \"Blue Blue\", \"#FFCBD1CF\": \"Blue Blush\", \"#FF6181A3\": \"Blue Boater\", \"#FF52B4CA\": \"Blue Bobbin\", \"#FF01A7AE\": \"Blue Bolero\", \"#FF00B9FB\": \"Blue Bolt\", \"#FFC8DDEE\": \"Blue Booties\", \"#FF0033EE\": \"Blue Bouquet\", \"#FFA4C3D7\": \"Blue Bows\", \"#FF70B8D0\": \"Blue Brocade\", \"#FFA6D7EB\": \"Blue Bubble\", \"#FF309CD0\": \"Blue Burst\", \"#FFA1A2BD\": \"Blue Buzz\", \"#FFA0B7BA\": \"Blue by You\", \"#FFA5CDE1\": \"Blue Calico\", \"#FF55A7B6\": \"Blue Calypso\", \"#FF2F36BA\": \"Blue Cardinal Flower\", \"#FF9CD0E4\": \"Blue Carpenter Bee\", \"#FF7B9EB0\": \"Blue Cascade\", \"#FF41788A\": \"Blue Catch\", \"#FF4B8CA9\": \"Blue Chaise\", \"#FF94C0CC\": \"Blue Chalk Variant\", \"#FF5671A7\": \"Blue Chamber\", \"#FF5599FF\": \"Blue Chaos\", \"#FF262B2F\": \"Blue Charcoal Variant\", \"#FF82C2DB\": \"Blue Charm\", \"#FF80693D\": \"Blue Cheese Olive\", \"#FF70A6B8\": \"Blue Chiffon\", \"#FF408F90\": \"Blue Chill Variant\", \"#FF1D5699\": \"Blue Chip\", \"#FF77B7D0\": \"Blue Chrysocolla\", \"#FF6B9194\": \"Blue Clay\", \"#FFA7D8E8\": \"Blue Click\", \"#FF627188\": \"Blue Cloud\", \"#FF2B3040\": \"Blue Coal\", \"#FF0088DC\": \"Blue Cola\", \"#FF4411DD\": \"Blue Copper Ore\", \"#FF1D5A6E\": \"Blue Coral\", \"#FF9EBDD6\": \"Blue Crab Escape\", \"#FF6591A8\": \"Blue Cruise\", \"#FF6FEBE3\": \"Blue Crystal Landscape\", \"#FF7EB4D1\": \"Blue Cuddle\", \"#FF84A5DC\": \"Blue Cue\", \"#FFCBDBD7\": \"Blue Cypress\", \"#FF44DDEE\": \"Blue Dacnis\", \"#FF415E9C\": \"Blue Dahlia\", \"#FFA2C6D3\": \"Blue Dam\", \"#FF2FA1DA\": \"Blue Damselfly\", \"#FF0094BB\": \"Blue Danube\", \"#FF0078F8\": \"Blue Darknut\", \"#FF518FD1\": \"Blue Dart\", \"#FF3A7A9B\": \"Blue Dart Frog\", \"#FF668DB7\": \"Blue Dazzle\", \"#FF4428BC\": \"Blue Depression\", \"#FF2C3A64\": \"Blue Depths\", \"#FF0B67BE\": \"Blue Diamond Variant\", \"#FF35514F\": \"Blue Dianne Variant\", \"#FFBCC5CF\": \"Blue Dolphin\", \"#FF76799E\": \"Blue Dove\", \"#FF879294\": \"Blue Driftwood\", \"#FF4A5C94\": \"Blue Dude\", \"#FF8C959D\": \"Blue Dusk\", \"#FF375673\": \"Blue Earth\", \"#FF8DBBC9\": \"Blue Echo\", \"#FF035E7B\": \"Blue Edge\", \"#FF97D5EA\": \"Blue Effervescence\", \"#FF6D9FD1\": \"Blue Electress\", \"#FF5588EE\": \"Blue Elemental\", \"#FF51529C\": \"Blue Ember\", \"#FF0F5A5E\": \"Blue Emerald\", \"#FFD1EDEF\": \"Blue Emulsion\", \"#FF0D6376\": \"Blue Enchantment\", \"#FF6DC1AC\": \"Blue Energy\", \"#FF384883\": \"Blue Estate\", \"#FF0652FF\": \"Blue et une Nuit\", \"#FF253F74\": \"Blue Expanse\", \"#FF2B2F43\": \"Blue Exult\", \"#FF75AEBD\": \"Blue Eye Samurai\", \"#FF7DABD0\": \"Blue Eyes\", \"#FF2C3B4D\": \"Blue Fantastic\", \"#FFAED9EC\": \"Blue Feather\", \"#FF324C61\": \"Blue Fedora\", \"#FFADB6AC\": \"Blue Fescue\", \"#FF577FAE\": \"Blue Fin\", \"#FF51645F\": \"Blue Fir\", \"#FF00AADD\": \"Blue Fire\", \"#FF007290\": \"Blue Fjord\", \"#FF3B506F\": \"Blue Flag\", \"#FF005E88\": \"Blue Flame\", \"#FFDDEBED\": \"Blue Flax\", \"#FFC8D2CD\": \"Blue Flower\", \"#FFB4CCC2\": \"Blue Fluorite\", \"#FF9BABBB\": \"Blue Fog\", \"#FFACB0A9\": \"Blue Fox\", \"#FF86D2C1\": \"Blue Frosting\", \"#FF2D4470\": \"Blue Funk\", \"#FFA2B8CE\": \"Blue Garter\", \"#FF4B3C8E\": \"Blue Gem Variant\", \"#FF6666FF\": \"Blue Genie\", \"#FFB8DCDC\": \"Blue Glass\", \"#FF56597C\": \"Blue Glaze\", \"#FF92C6D7\": \"Blue Glint\", \"#FFB2D4DD\": \"Blue Glow\", \"#FFCDD7DF\": \"Blue Gossamer\", \"#FF69A2D5\": \"Blue Gourami\", \"#FF76798D\": \"Blue Granite\", \"#FF3A383F\": \"Blue Graphite\", \"#FF007A7C\": \"Blue Grass\", \"#FF137E6D\": \"Blue Green Variant\", \"#FF7CCBC5\": \"Blue Green Gem\", \"#FFD8EEED\": \"Blue Green Rules\", \"#FF56B78F\": \"Blue Green Scene\", \"#FF758DA3\": \"Blue Grey\", \"#FF50A2CA\": \"Blue Grotto\", \"#FF9ABCDC\": \"Blue Grouse\", \"#FFBDBACE\": \"Blue Haze Variant\", \"#FF5566FF\": \"Blue Heath Butterfly\", \"#FFAEBBC1\": \"Blue Heather\", \"#FF5B7E98\": \"Blue Heaven\", \"#FF939CAB\": \"Blue Heeler\", \"#FF006384\": \"Blue Heist\", \"#FF6666EE\": \"Blue Hepatica\", \"#FF939EC5\": \"Blue Heron\", \"#FF324A8B\": \"Blue Highlight\", \"#FFD0EEFB\": \"Blue Hijab\", \"#FF1E454D\": \"Blue Hill\", \"#FF289DBE\": \"Blue Horizon\", \"#FFA2BAD2\": \"Blue Horror\", \"#FF2A6F73\": \"Blue Hosta\", \"#FF0034AB\": \"Blue Hour\", \"#FF394D60\": \"Blue Hue\", \"#FF8394C5\": \"Blue Hyacinth\", \"#FFBBC3DD\": \"Blue Hydrangea\", \"#FF539CCC\": \"Blue Iguana\", \"#FF535A7C\": \"Blue Indigo\", \"#FF566977\": \"Blue Insignia\", \"#FF7F809C\": \"Blue Intrigue\", \"#FF587EBE\": \"Blue Iolite\", \"#FF6264A6\": \"Blue Iris\", \"#FF22AAAA\": \"Blue Island\", \"#FF597193\": \"Blue Jacket\", \"#FF828596\": \"Blue Jasmine\", \"#FFC1EBFF\": \"Blue Java Banana\", \"#FF5588DD\": \"Blue Jay\", \"#FF01708A\": \"Blue Jay Crest\", \"#FF465383\": \"Blue Jewel\", \"#FF002D72\": \"Blue Jinn\\u2019s\", \"#FFBCE6E8\": \"Blue Karma\", \"#FF1D7881\": \"Blue Kelp\", \"#FFE2E5E2\": \"Blue Kiss\", \"#FF00626F\": \"Blue Lagoon Variant\", \"#FF2E5169\": \"Blue Lava\", \"#FF006284\": \"Blue League\", \"#FF032A62\": \"Blue Leviathan\", \"#FFACDFDD\": \"Blue Light\", \"#FF7FCCE2\": \"Blue Limewash\", \"#FF5A5E6A\": \"Blue Linen\", \"#FFA6BCE2\": \"Blue Lips\", \"#FF28314D\": \"Blue Lobelia\", \"#FF0055AA\": \"Blue Lobster\", \"#FF486D83\": \"Blue Loneliness\", \"#FFC8D7D2\": \"Blue Lullaby\", \"#FFB2C4CD\": \"Blue Luna\", \"#FF012389\": \"Blue Lust\", \"#FF007593\": \"Blue Luxury\", \"#FF5F34E7\": \"Blue Magenta\", \"#FF553592\": \"Blue Magenta Violet\", \"#FF9AC0DE\": \"Blue Magpie\", \"#FF68C2F5\": \"Blue Mana\", \"#FF6594BC\": \"Blue Marble\", \"#FF6A5BB1\": \"Blue Marguerite Variant\", \"#FF1FCECB\": \"Blue Martina\", \"#FF52B4D3\": \"Blue Martini\", \"#FFC9DCE7\": \"Blue Me Away\", \"#FF67A6AC\": \"Blue Mercury\", \"#FF014C76\": \"Blue Meridian\", \"#FF5A6370\": \"Blue Metal\", \"#FF5C6D7C\": \"Blue Mirage\", \"#FF5BACC3\": \"Blue Mist\", \"#FF637983\": \"Blue Monday\", \"#FF7A808D\": \"Blue Mood\", \"#FF3992A8\": \"Blue Moon\", \"#FF588496\": \"Blue Moon Bay\", \"#FF21426B\": \"Blue Mosque\", \"#FF759DBE\": \"Blue Mountain\", \"#FF2539BF\": \"Blue Murder\", \"#FF1199FF\": \"Blue Nebula\", \"#FF414657\": \"Blue Nights\", \"#FF779FB9\": \"Blue Nile\", \"#FFD2DDE0\": \"Blue Nuance\", \"#FF29518C\": \"Blue Nude\", \"#FF88A4AE\": \"Blue Nuthatch\", \"#FF647E9C\": \"Blue Oar\", \"#FF296D93\": \"Blue Oasis\", \"#FF26428B\": \"Blue Oblivion\", \"#FF4F6997\": \"Blue Odyssey\", \"#FF015193\": \"Blue Olympus\", \"#FF124168\": \"Blue Opal\", \"#FF0020EF\": \"Blue Overdose\", \"#FF5577EE\": \"Blue \\u00d6yster Cult\", \"#FF2282A8\": \"Blue Paisley\", \"#FF01546D\": \"Blue Palisade\", \"#FF5095C3\": \"Blue Paradise\", \"#FF8080FF\": \"Blue Party Parrot\", \"#FFC5D9E3\": \"Blue Pearl\", \"#FF2200FF\": \"Blue Pencil\", \"#FFBCD7DF\": \"Blue Perennial\", \"#FF075158\": \"Blue Period\", \"#FF5B92AC\": \"Blue Persia\", \"#FFD2E6E8\": \"Blue Phlox\", \"#FFB5A3C5\": \"Blue Pink\", \"#FF545E6A\": \"Blue Planet\", \"#FF5B7A9C\": \"Blue Plate\", \"#FF30363C\": \"Blue Plaza\", \"#FF95B9D6\": \"Blue Pointer\", \"#FFA1B1C2\": \"Blue Pot\", \"#FF64617B\": \"Blue Potato\", \"#FF6A808F\": \"Blue Prince\", \"#FFABC4DB\": \"Blue Prism\", \"#FF729CC2\": \"Blue Promise\", \"#FF5729CE\": \"Blue Purple\", \"#FF43505E\": \"Blue Quarry\", \"#FF335287\": \"Blue Quartz\", \"#FF4BA4A9\": \"Blue Racer\", \"#FF58CFD4\": \"Blue Radiance\", \"#FFC4D6E1\": \"Blue Raindrop\", \"#FF00177D\": \"Blue Ranger\", \"#FF0CBFE9\": \"Blue Raspberry\", \"#FF3AA2C6\": \"Blue Raspberry Seed\", \"#FFCCD7E1\": \"Blue Reflection\", \"#FFB0D8E7\": \"Blue Refrain\", \"#FF303048\": \"Blue Regal\", \"#FF376298\": \"Blue Regatta\", \"#FF285991\": \"Blue Regent\", \"#FF4E5878\": \"Blue Review\", \"#FF3E6490\": \"Blue Ribbon Beauty\", \"#FFB3D9F3\": \"Blue Rice\", \"#FF75A6BB\": \"Blue Ridge Mist\", \"#FFB7BDC6\": \"Blue Rinse\", \"#FF377D95\": \"Blue Rodeo\", \"#FFD8F0D2\": \"Blue Romance Variant\", \"#FF292D74\": \"Blue Rose\", \"#FF29217A\": \"Blue Royale\", \"#FF0066DD\": \"Blue Ruin\", \"#FF575F6A\": \"Blue Sabre\", \"#FF57747A\": \"Blue Sage\", \"#FF24549A\": \"Blue Sail\", \"#FF666A76\": \"Blue Sari\", \"#FF9AD6E8\": \"Blue Sarong\", \"#FF494D58\": \"Blue Sash\", \"#FF9EB6D0\": \"Blue Satin\", \"#FF0033BB\": \"Blue Screen of Death\", \"#FF546E77\": \"Blue Sentinel\", \"#FF293F54\": \"Blue Shade Wash\", \"#FF758CA4\": \"Blue Shadow\", \"#FFB9CACC\": \"Blue Shale\", \"#FFBACBC4\": \"Blue Shamrock\", \"#FF9BB3BC\": \"Blue Shell\", \"#FFB3DAE2\": \"Blue Shimmer\", \"#FF6B8C93\": \"Blue Shoal\", \"#FF7593CB\": \"Blue Shock\", \"#FF93BDE7\": \"Blue Shutters\", \"#FFD0DCE8\": \"Blue Silk\", \"#FF95AFDC\": \"Blue Skies Today\", \"#FF8CA6B5\": \"Blue Skylights\", \"#FF5A5F68\": \"Blue Slate\", \"#FF008793\": \"Blue Slushie\", \"#FF5786B4\": \"Blue Smart\", \"#FFD7E0E2\": \"Blue Smoke Variant\", \"#FF4A87CB\": \"Blue Sonki\", \"#FF404956\": \"Blue Sou\\u2019wester\", \"#FF0077FF\": \"Blue Sparkle\", \"#FF3B5C6C\": \"Blue Spell\", \"#FF2E85B1\": \"Blue Splash\", \"#FFADC5C9\": \"Blue Spruce\", \"#FF508A9A\": \"Blue Square\", \"#FF577284\": \"Blue Stone Variant\", \"#FF2266BB\": \"Blue Streak\", \"#FF95CDD8\": \"Blue Stream\", \"#FF687B92\": \"Blue Suede\", \"#FF484B62\": \"Blue Suede Shoes\", \"#FF829D99\": \"Blue Surf\", \"#FF1B4556\": \"Blue Syzygy\", \"#FF2A4B6E\": \"Blue Tang\", \"#FF3FA4D2\": \"Blue Tango\", \"#FF475C62\": \"Blue Tapestry\", \"#FF849DA2\": \"Blue Tea\", \"#FF5885A2\": \"Blue Team Spirit\", \"#FFADC0D6\": \"Blue Thistle\", \"#FF677F86\": \"Blue Thunder\", \"#FF9FD9D7\": \"Blue Tint\", \"#FF4466FF\": \"Blue Titmouse\", \"#FF0190C0\": \"Blue Variant\", \"#FFBABFC5\": \"Blue Tint\", \"#FF2B4057\": \"Blue Tone Ink\", \"#FF65AECE\": \"Blue Topaz\", \"#FF042993\": \"Blue Torus\", \"#FFA9B8C8\": \"Blue Tribute\", \"#FF4376AB\": \"Blue Triumph\", \"#FF5C4671\": \"Blue Tulip\", \"#FFC9DBE5\": \"Blue Tulle\", \"#FF6F95C1\": \"Blue Tuna\", \"#FF50ABAE\": \"Blue Turquoise\", \"#FF1E7EAE\": \"Blue Vacation\", \"#FF4E83BD\": \"Blue Vault\", \"#FFAECBE5\": \"Blue Veil\", \"#FF0D6183\": \"Blue Velvet\", \"#FF397C80\": \"Blue Venus\", \"#FF4E32B2\": \"Blue Violet Tint\", \"#FF3D4457\": \"Blue Vortex\", \"#FF1E3442\": \"Blue Whale Variant\", \"#FFA8BBBA\": \"Blue Willow\", \"#FF2E4556\": \"Blue Wing Teal\", \"#FF00827C\": \"Blue Winged Teal\", \"#FF404664\": \"Blue Wonder\", \"#FF5A77A8\": \"Blue Yonder\", \"#FF5B6676\": \"Blue Zephyr\", \"#FF3C4354\": \"Blue Zodiac Variant\", \"#FF24313D\": \"Blue-Black\", \"#FF005F7A\": \"Blue-Collar\", \"#FF2277CC\": \"Blue-Eyed Boy\", \"#FF5C767F\": \"Blue-Eyed Cryptid\", \"#FF0000DD\": \"Bluealicious\", \"#FFABB5C4\": \"Bluebeard\", \"#FF464196\": \"Blueberry\", \"#FF836268\": \"Blueberry Blush\", \"#FF8C99B3\": \"Blueberry Buckle\", \"#FF586E84\": \"Blueberry Dream\", \"#FF4D8CB9\": \"Blueberry Festival\", \"#FFCC66DD\": \"Blueberry Glaze\", \"#FFC6D8E4\": \"Blueberry Ice\", \"#FFD01343\": \"Blueberry Lemonade\", \"#FFCBCCDF\": \"Blueberry Mist\", \"#FF5588AB\": \"Blueberry Muffin\", \"#FF627099\": \"Blueberry Patch\", \"#FF314D67\": \"Blueberry Pie\", \"#FF5488C0\": \"Blueberry Popover\", \"#FF8290A6\": \"Blueberry Soda\", \"#FF5E96C3\": \"Blueberry Soft Blue\", \"#FF3F4050\": \"Blueberry Tart\", \"#FF24547D\": \"Blueberry Twist\", \"#FFD1D4DB\": \"Blueberry Whip\", \"#FF00A9B8\": \"Bluebird\", \"#FF6F9DB3\": \"Bluebird Feather\", \"#FF7395B8\": \"Bluebird\\u2019s Belly\", \"#FF1C1CF0\": \"Bluebonnet\", \"#FF8ECFE8\": \"Bluebottle\", \"#FF4F9297\": \"Bluebound\", \"#FF6ABCDA\": \"Bluebrite\", \"#FF535A61\": \"Blued Steel\", \"#FF324C64\": \"Bluedgeons\", \"#FF35637C\": \"Blueprint\", \"#FF6F8479\": \"Blueridge Fir\", \"#FF1F66FF\": \"Bluerocratic\", \"#FF296A9D\": \"Blues\", \"#FF2D47FF\": \"Blueshift\", \"#FF6081A2\": \"Bluestone Path\", \"#FF7C9AB5\": \"Bluesy Note\", \"#FF9EBED8\": \"Bluette\", \"#FFE2E6E0\": \"Bluewash\", \"#FF375978\": \"Bluey\", \"#FFD2BD9E\": \"Bluff Stone\", \"#FF2976BB\": \"Bluish\", \"#FF413F44\": \"Bluish Black\", \"#FF10A674\": \"Bluish Green\", \"#FF748B97\": \"Bluish Grey\", \"#FFD0D5D3\": \"Bluish Lilac Purple\", \"#FF703BE7\": \"Bluish Purple\", \"#FF6666BB\": \"Bluish Purple Anemone\", \"#FF89CFDB\": \"Bluish Water\", \"#FF305C71\": \"Blumine Variant\", \"#FFB5BBC7\": \"Blunt\", \"#FF8D6C7A\": \"Blunt Violet\", \"#FF5539CC\": \"Blurple\", \"#FFF29E8E\": \"Blush Tint\", \"#FFEDD5C7\": \"Blush Beige\", \"#FFDD99AA\": \"Blush Bomb\", \"#FFCC88DD\": \"Blush Essence\", \"#FFFF6F91\": \"Blush Hour\", \"#FFEABCC0\": \"Blush Kiss\", \"#FFD9E6E0\": \"Blush Mint\", \"#FFDCCBD1\": \"Blush of Hyacinth\", \"#FFDCD1D5\": \"Blush of Morn\", \"#FFF0BCBE\": \"Blush Rush\", \"#FFE2E0D8\": \"Blush Sand\", \"#FFDEE1ED\": \"Blush Sky\", \"#FFEE88CC\": \"Blushed Bombshell\", \"#FFF0E0D2\": \"Blushed Cotton\", \"#FFDEC5D3\": \"Blushed Velvet\", \"#FFF0D1C3\": \"Blushing\", \"#FFFBBCA7\": \"Blushing Apricot\", \"#FFEEDAD1\": \"Blushing Bride\", \"#FFDD9999\": \"Blushing Bud\", \"#FFFFCDAF\": \"Blushing Cherub\", \"#FFFFBF99\": \"Blushing Cinnamon\", \"#FFEBD5CA\": \"Blushing Coconut\", \"#FFD3D4E5\": \"Blushing Lilac\", \"#FFFFD79F\": \"Blushing Peach\", \"#FFE09B81\": \"Blushing Rose\", \"#FFF3CACB\": \"Blushing Senorita\", \"#FFD9B1D6\": \"Blushing Sky\", \"#FFE3A1B8\": \"Blushing Tulip\", \"#FF4A5A6F\": \"Bluster Blue\", \"#FF4411FF\": \"Blustering Blue\", \"#FFD6DFE7\": \"Blustery Day\", \"#FF6F848C\": \"Blustery Sky\", \"#FFB6C5C1\": \"Blustery Wind\", \"#FF1D5BD6\": \"Bnei Brak Bay\", \"#FF7F7755\": \"Boa\", \"#FFEDE7D5\": \"Board & Batten\", \"#FF757760\": \"Boardman\", \"#FFC7B6AA\": \"Boardwalk Sashay\", \"#FF6C6B6A\": \"Boat Anchor\", \"#FF2D5384\": \"Boat Blue\", \"#FF577190\": \"Boathouse\", \"#FF087170\": \"Boating Green\", \"#FF243256\": \"Boatswain\", \"#FF97C5DA\": \"Bobby Blue\", \"#FFEADFD0\": \"Bobcat Whiskers\", \"#FF22BB11\": \"Boboli Gardens\", \"#FF5D341A\": \"Bock\", \"#FFDF8F67\": \"Bockwurst\", \"#FFB2619D\": \"Bodacious\", \"#FF5E81C1\": \"Bodega Bay\", \"#FFB09870\": \"Bodhi Tree\", \"#FF3D4652\": \"Boeing Blue\", \"#FF973443\": \"Boerewors\", \"#FFBAB796\": \"Bog\", \"#FFBAC3B9\": \"Bog Fog\", \"#FF8B8274\": \"Bogart\", \"#FF116F26\": \"Bogey Green\", \"#FF663B3A\": \"Bogong Moth\", \"#FF3B373C\": \"Bohemian Black\", \"#FF0000AA\": \"Bohemian Blue\", \"#FF9D777C\": \"Bohemian Jazz\", \"#FFB8B3C8\": \"Bohemianism\", \"#FF7B684D\": \"Boho\", \"#FFE58787\": \"Boho Blush\", \"#FFB96033\": \"Boho Copper\", \"#FF00EE11\": \"Boiling Acid\", \"#FFFF3300\": \"Boiling Magma\", \"#FFA59C9B\": \"Boiling Mud\", \"#FFD7E9E8\": \"Boiling Point\", \"#FFBCCAB3\": \"Bok Choy\", \"#FF2A2725\": \"Bokara Grey\", \"#FF879550\": \"Bold Avocado\", \"#FF1D6575\": \"Bold Bolection\", \"#FF796660\": \"Bold Brandy\", \"#FF8C5E55\": \"Bold Brick\", \"#FF463D2F\": \"Bold Eagle\", \"#FFEAD56D\": \"Bold Gold\", \"#FF2A814D\": \"Bold Irish\", \"#FF7A4549\": \"Bold Sangria\", \"#FF88464A\": \"Bolero\", \"#FFDEBB32\": \"Bollywood\", \"#FFFFFBAB\": \"Bollywood Gold\", \"#FF9C6F6C\": \"Bologna\", \"#FFFFCFDC\": \"Bologna Sausage\", \"#FFBB4400\": \"Bolognese\", \"#FF393939\": \"Boltgun Metal\", \"#FFD8BABC\": \"Bombay Pink\", \"#FF5E496A\": \"Bon Vivant\", \"#FF8BAEB2\": \"Bon Voyage\", \"#FF304471\": \"Bona Fide\", \"#FFCBB9AB\": \"Bona Fide Beige\", \"#FFE6E2D7\": \"Bonaire\", \"#FF523B2C\": \"Bonanza\", \"#FF8C4268\": \"Bonbon Red\", \"#FF16698C\": \"Bondi\", \"#FFE0D7C6\": \"Bone Tint\", \"#FF9D7446\": \"Bone Brown\", \"#FFF3EDDE\": \"Bone China\", \"#FFD7D0C0\": \"Bone Trace\", \"#FFF1E1B0\": \"Bone White\", \"#FFE1F2F0\": \"Bone-Chilling\", \"#FFBB9977\": \"Boneyard\", \"#FFF78058\": \"Bonfire\", \"#FFD7951F\": \"Bonfire Glow\", \"#FFDE6A41\": \"Bonfire Night\", \"#FFD7AF7A\": \"Bonfire Toffee\", \"#FFD2C2B2\": \"Bongo Drum\", \"#FFDECE96\": \"Bongo Skin\", \"#FFDFD7D2\": \"Bonjour\", \"#FFF54D79\": \"Bonker Pink\", \"#FF3A4866\": \"Bonne Nuit\", \"#FF8DBBD1\": \"Bonnie Blue\", \"#FFFDEFD2\": \"Bonnie Cream\", \"#FFE4D1BC\": \"Bonnie Dune Beach\", \"#FF7C644A\": \"Bonnie\\u2019s Bench\", \"#FFC58EAB\": \"Bonny Belle\", \"#FF787B54\": \"Bonsai\", \"#FF9E9E7C\": \"Bonsai Garden\", \"#FFB8B19A\": \"Bonsai Pot\", \"#FFC5D1B2\": \"Bonsai Tint\", \"#FF6C6D62\": \"Bonsai Trunk\", \"#FFFFA00A\": \"Bonus Level\", \"#FF5E6B44\": \"Bonza Green\", \"#FF84AFD5\": \"Boo Blue\", \"#FF9BB53C\": \"Booger\", \"#FF00FF77\": \"Booger Buster\", \"#FF119944\": \"Boogie Blast\", \"#FF805D5B\": \"Book Binder\", \"#FF8C3432\": \"Bookstone\", \"#FFEBE3DE\": \"Bookworm\", \"#FFAFC2CF\": \"Boot Cut\", \"#FFDDAF8E\": \"Boot Hill Ghost\", \"#FF793721\": \"Bootstrap Leather\", \"#FF7FC6BE\": \"Booty Bay\", \"#FF92D0D0\": \"Bora Bora Shore\", \"#FF507EA4\": \"Borage\", \"#FF5566CC\": \"Borage Blue\", \"#FF7B002C\": \"Bordeaux Variant\", \"#FFEFBCDE\": \"Bordeaux Hint\", \"#FF5C3944\": \"Bordeaux Leaf\", \"#FF6F2C4F\": \"Bordeaux Red\", \"#FFC69B58\": \"Borderline\", \"#FFEE1166\": \"Borderline Pink\", \"#FF717E73\": \"Boreal\", \"#FFDEDD98\": \"Bored Accent Green\", \"#FF8C9C9C\": \"Boredom\", \"#FFFF8E51\": \"Boredom Buster\", \"#FF06470C\": \"Borg Drone\", \"#FF054907\": \"Borg Queen\", \"#FF63B365\": \"Boring Green\", \"#FFD9B1AA\": \"Borlotti Bean\", \"#FFA76244\": \"Borneo\", \"#FF8C2C24\": \"Borscht\", \"#FFC09056\": \"Bosc Pear\", \"#FF76A0AF\": \"Bosco Blue\", \"#FF552C1C\": \"Boson Brown\", \"#FFE7DBE1\": \"B\\u014ds\\u014dzoku Pink\", \"#FF008468\": \"Bosphorus\", \"#FF015D75\": \"Bosporus\", \"#FF4C3D4E\": \"Bossa Nova\", \"#FF767C9E\": \"Bossa Nova Blue\", \"#FFCB8EB1\": \"Bossy-Pants Pink\", \"#FF438EAC\": \"Boston Blue Variant\", \"#FF87544E\": \"Boston Brick\", \"#FF614432\": \"Boston Brown Bread\", \"#FF90966D\": \"Boston Fern\", \"#FF685043\": \"Boston Legacy\", \"#FFCC0002\": \"Boston University Red Variant\", \"#FFA2345C\": \"B\\u014dtan\", \"#FF4D6E2F\": \"Botanical\", \"#FF227700\": \"Botanical Beauty\", \"#FFA3BFB9\": \"Botanical Bliss\", \"#FF44AA11\": \"Botanical Garden\", \"#FF77976E\": \"Botanical Green\", \"#FF12403C\": \"Botanical Night\", \"#FFA7E6D4\": \"Botanical Tint\", \"#FF9AD28C\": \"Botanist\", \"#FFB70272\": \"Botticelli Variant\", \"#FFFBDFD6\": \"Botticelli Angel\", \"#FF238E50\": \"Bottle Glass\", \"#FF006A4E\": \"Bottle Green Variant\", \"#FFE8EDB0\": \"Bottlebrush Blossom\", \"#FF095BAF\": \"Bottled Sea\", \"#FF9B6944\": \"Bottled Ship\", \"#FFBFC4C9\": \"Bottlefly Wings\", \"#FF6A7074\": \"Bottlenose Dolphin\", \"#FFCC0077\": \"Bottom of My Heart\", \"#FFDAB27D\": \"Boudin\", \"#FFD9C0AB\": \"Boudoir Beige\", \"#FF7EA3D2\": \"Boudoir Blue\", \"#FF9884B9\": \"Bougainvillaea\", \"#FF576145\": \"Boughs of Pine\", \"#FF7C817C\": \"Boulder Variant\", \"#FF655E4E\": \"Boulder Brown\", \"#FF8C9496\": \"Boulder Creek\", \"#FFD40701\": \"Boulevardier\", \"#FF49A462\": \"Bouncy Ball Green\", \"#FF5B6D84\": \"Boundless\", \"#FF5A8299\": \"Bountiful Blue\", \"#FFE4C36C\": \"Bountiful Gold\", \"#FFA78199\": \"Bouquet Variant\", \"#FFAF6C3E\": \"Bourbon Variant\", \"#FFEC842F\": \"Bourbon Peach\", \"#FF6C5654\": \"Bourbon Truffle\", \"#FFEE0066\": \"Bourgeois\", \"#FF637A72\": \"Bournonite Green\", \"#FFE1CEAD\": \"Boutique Beige\", \"#FF8CC1D6\": \"Boutonniere\", \"#FF52585C\": \"Bovine\", \"#FFBE2633\": \"Bow Tie\", \"#FF126DA8\": \"Bowen Blue\", \"#FF006585\": \"Bowerbird Blue\", \"#FFBFDEAF\": \"Bowling Green\", \"#FFD7BD92\": \"Bowman Beige\", \"#FF587176\": \"Bowman Blue\", \"#FF536B1F\": \"Bowser Shell\", \"#FFD6D1C8\": \"Bowstring\", \"#FF898790\": \"Box Office\", \"#FF873D30\": \"Boxcar\", \"#FF707B71\": \"Boxwood\", \"#FFEFE4A5\": \"Boxwood Yellow\", \"#FF8CACD6\": \"Boy Blue\", \"#FFB3111D\": \"Boy Red\", \"#FF635C53\": \"Boycott\", \"#FF9F4E3E\": \"Boynton Canyon\", \"#FF873260\": \"Boysenberry\", \"#FFA1395D\": \"Boysenberry Pink\", \"#FFF1F3F9\": \"Boysenberry Shadow\", \"#FF2A96D5\": \"Boyzone\", \"#FF014182\": \"Bracing Blue\", \"#FF5B3D27\": \"Bracken Variant\", \"#FF31453B\": \"Bracken Fern\", \"#FF626F5D\": \"Bracken Green\", \"#FF84726C\": \"Bradford Brown\", \"#FF77675B\": \"Braid\", \"#FFE9B578\": \"Braided Mat\", \"#FFE1D0AF\": \"Braided Raffia\", \"#FF00EEFF\": \"Brain Freeze\", \"#FFF2AEB1\": \"Brain Pink\", \"#FFB5B5B5\": \"Brainstem Grey\", \"#FFD1D3C0\": \"Brainstorm\", \"#FF74685A\": \"Brainstorm Bronze\", \"#FF65635B\": \"Braintree\", \"#FFEE0033\": \"Brake Light Trails\", \"#FF503629\": \"Bramble Bush\", \"#FFC71581\": \"Bramble Jam\", \"#FF9BA29D\": \"Brampton Grey\", \"#FFA9704C\": \"Bran\", \"#FF9A7F55\": \"Branching-Out Olive\", \"#FF706F64\": \"Brandenburg Gate\", \"#FFA37C79\": \"Brandied Apple\", \"#FFC27275\": \"Brandied Apricot\", \"#FFCC7753\": \"Brandied Melon\", \"#FFEAE2D1\": \"Brandied Pears\", \"#FFDCB68A\": \"Brandy Variant\", \"#FFF3E2DC\": \"Brandy Alexander\", \"#FFAA5412\": \"Brandy Bear\", \"#FF73342A\": \"Brandy Brown\", \"#FFF3BB8F\": \"Brandy Butter\", \"#FFC07C40\": \"Brandy Punch Variant\", \"#FFB6857A\": \"Brandy Rose Variant\", \"#FFB58E8B\": \"Brandy Snaps\", \"#FF490206\": \"Brandywine\", \"#FF5555AA\": \"Brandywine Raspberry\", \"#FFE69DAD\": \"Brandywine Spritz\", \"#FFB5A642\": \"Brass\", \"#FFE7BD42\": \"Brass Balls\", \"#FFDFAC4C\": \"Brass Buttons\", \"#FFB9A70F\": \"Brass Knuckle\", \"#FFE1A84B\": \"Brass Mesh\", \"#FFDBBD76\": \"Brass Nail\", \"#FF773B2E\": \"Brass Scorpion\", \"#FFD3B280\": \"Brass Trumpet\", \"#FFB58735\": \"Brass Yellow\", \"#FFCFA743\": \"Brassed Off\", \"#FF788879\": \"Brassica\", \"#FFF3BC6B\": \"Brasso\", \"#FFD5AB2C\": \"Brassy\", \"#FF776022\": \"Brassy Brass\", \"#FFD8AB39\": \"Brassy Tint\", \"#FF454743\": \"Brattle Spruce\", \"#FF582F2B\": \"Bratwurst\", \"#FF897058\": \"Braun\", \"#FFA0524E\": \"Bravado Red\", \"#FF015B6D\": \"Brave New Teal\", \"#FFFF631C\": \"Brave Orange\", \"#FF968DB8\": \"Brave Purple\", \"#FFD3E7E9\": \"Bravo Blue\", \"#FF8C80B9\": \"Bravo!\", \"#FFA87F12\": \"Brazen\", \"#FF7B6623\": \"Brazen Brass\", \"#FFCE7850\": \"Brazen Orange\", \"#FF856765\": \"Brazil Nut\", \"#FF7F5131\": \"Brazilian Brown\", \"#FFAF915D\": \"Brazilian Citrine\", \"#FF296D23\": \"Brazilian Green\", \"#FFD8C6B4\": \"Brazilian Sand\", \"#FF31D652\": \"Brazilianite\", \"#FFFFD182\": \"Bread and Butter\", \"#FFAB8659\": \"Bread Basket\", \"#FFE4D4BE\": \"Bread Crumb\", \"#FFB78B43\": \"Bread Crust\", \"#FFDCD6D2\": \"Bread Flavour\", \"#FFE6BC89\": \"Bread Pudding\", \"#FFB48C56\": \"Breadstick\", \"#FFFFFABD\": \"Break of Day\", \"#FFB2E1EE\": \"Break the Ice\", \"#FFCEDAC3\": \"Breakaway\", \"#FF424D60\": \"Breakaway Blue\", \"#FFE5EDED\": \"Breaker\", \"#FF517B78\": \"Breaker Bay Variant\", \"#FFF6E3D3\": \"Breakfast Biscuit\", \"#FF6D5542\": \"Breakfast Blend\", \"#FFB8E4F5\": \"Breaking the Ice\", \"#FF00A0B0\": \"Breaking Wave\", \"#FFC4D9CE\": \"Breaktime\", \"#FFD1DEE4\": \"Breakwater\", \"#FFEBF1E9\": \"Breakwater White\", \"#FFDCE7CB\": \"Breath of Celery\", \"#FFEE0011\": \"Breath of Fire\", \"#FFC7DBE4\": \"Breath of Fresh Air\", \"#FFBDD1CE\": \"Breath of Green\", \"#FFE9E1A7\": \"Breath of Spring\", \"#FFD1D2B8\": \"Breathe\", \"#FF015348\": \"Breathe Deeply\", \"#FFDFDAE0\": \"Breathless\", \"#FF536193\": \"Breathtaking\", \"#FFC3ACB7\": \"Breathtaking Evening\", \"#FF809BAC\": \"Breathtaking View\", \"#FF5E9948\": \"Bredon Green\", \"#FF795D34\": \"Breen\", \"#FFAEC9EA\": \"Breeze\", \"#FFC4DFE8\": \"Breeze in June\", \"#FFF4706E\": \"Breeze of Chilli\", \"#FFCFFDBC\": \"Breeze of Green\", \"#FFD6DBC0\": \"Breezeway\", \"#FFC2DDE6\": \"Breezy\", \"#FFD9E4DE\": \"Breezy Aqua\", \"#FFF7F2D7\": \"Breezy Beige\", \"#FFBAD9E5\": \"Breezy Blue\", \"#FFBDC4B8\": \"Breezy Day\", \"#FFC1D9E9\": \"Breezy Touch\", \"#FFCECEDF\": \"Breezy Violet\", \"#FF2D567C\": \"Breonne Blue\", \"#FF0080FF\": \"Brescian Blue\", \"#FFAA5555\": \"Bretzel Brown\", \"#FF715243\": \"Brevity Brown\", \"#FFE68364\": \"Brewed Mustard\", \"#FF777788\": \"Brewing Storm\", \"#FF745443\": \"Briar\", \"#FFC07281\": \"Briar Rose\", \"#FF695451\": \"Briar Wood\", \"#FFA03623\": \"Brick\", \"#FF77603F\": \"Brick Brown\", \"#FFB22122\": \"Brick by Brick\", \"#FFAB685F\": \"Brick Dust\", \"#FFB38070\": \"Brick Fence\", \"#FF956159\": \"Brick Hearth\", \"#FFC14A09\": \"Brick Orange\", \"#FFC2977C\": \"Brick Path\", \"#FF93402F\": \"Brick Paver\", \"#FF8F1402\": \"Brick Red Variant\", \"#FFD2A161\": \"Brick Yellow\", \"#FFA75C3D\": \"Brick-A-Brack\", \"#FF864A36\": \"Brickhouse\", \"#FFDB5856\": \"Bricks of Hope\", \"#FF825943\": \"Bricktone\", \"#FF986971\": \"Brickwork Red\", \"#FFB33A22\": \"Bricky Brick\", \"#FFAB6A64\": \"Brickyard\", \"#FFEBBDB8\": \"Bridal Bouquet\", \"#FFF8EBDD\": \"Bridal Heath Variant\", \"#FFD1949C\": \"Bridal Rose\", \"#FFE5D3CC\": \"Bridal Scent\", \"#FFE7E1DE\": \"Bridal Veil\", \"#FFE5E7E5\": \"Bridal Wreath\", \"#FFEFE7EB\": \"Bride\", \"#FFFAE6DF\": \"Bridesmaid Variant\", \"#FF817F6E\": \"Bridge Troll Grey\", \"#FF004683\": \"Bridgeport\", \"#FF527065\": \"Bridgewater\", \"#FFBCD7E2\": \"Bridgewater Bay\", \"#FF575144\": \"Bridgewood\", \"#FF8F7D70\": \"Bridle Leather\", \"#FFA29682\": \"Bridle Path\", \"#FF545E4F\": \"Brierwood Green\", \"#FF4FA1C0\": \"Brig\", \"#FFDDCFBF\": \"Brig O\\u2019doon\", \"#FF365D73\": \"Brigade\", \"#FF0063A0\": \"Brigadier Blue\", \"#FFB5DDEB\": \"Bright and Breezy\", \"#FF0BF9EA\": \"Bright Aqua\", \"#FF0165FC\": \"Bright Blue Variant\", \"#FF9DA7CF\": \"Bright Bluebell\", \"#FF90B3C2\": \"Bright Bluebonnet\", \"#FFA05822\": \"Bright Bronze\", \"#FF533B32\": \"Bright Brown\", \"#FFFFC42A\": \"Bright Bubble\", \"#FFADBFC8\": \"Bright Chambray\", \"#FFDFFF11\": \"Bright Chartreuse\", \"#FFFFC6A5\": \"Bright Citrus\", \"#FFEFCF9B\": \"Bright Clove\", \"#FF3C6098\": \"Bright Cobalt\", \"#FF41FDFE\": \"Bright Cyan\", \"#FFCD5B26\": \"Bright Delight\", \"#FFEEE9F9\": \"Bright Dusk\", \"#FFFEFFCA\": \"Bright Ecru\", \"#FF5A4E88\": \"Bright Eggplant\", \"#FF728A51\": \"Bright Forest\", \"#FFCF9F52\": \"Bright Gold\", \"#FF3844F4\": \"Bright Greek\", \"#FFEBECF0\": \"Bright Grey\", \"#FFFFD266\": \"Bright Halo\", \"#FFECBE63\": \"Bright Idea\", \"#FF6F00FE\": \"Bright Indigo\", \"#FFF1E78C\": \"Bright Khaki\", \"#FF9F3645\": \"Bright Lady\", \"#FFF0EDD1\": \"Bright Laughter\", \"#FF8DCE65\": \"Bright Lettuce\", \"#FF2DFE54\": \"Bright Light Green\", \"#FF87FD05\": \"Bright Lime\", \"#FF65FE08\": \"Bright Lime Green\", \"#FFC1B9AA\": \"Bright Loam\", \"#FFFF08E8\": \"Bright Magenta\", \"#FFFF8830\": \"Bright Mango\", \"#FFEB7E00\": \"Bright Marigold\", \"#FF011993\": \"Bright Midnight\", \"#FFF6F1E5\": \"Bright Moon\", \"#FF225869\": \"Bright Nautilus\", \"#FF2D5E22\": \"Bright Nori\", \"#FFF0E8DA\": \"Bright Ocarina\", \"#FF9CBB04\": \"Bright Olive\", \"#FF549C38\": \"Bright Parrot\", \"#FFBE03FD\": \"Bright Purple\", \"#FFFF000D\": \"Bright Red Variant\", \"#FFC51959\": \"Bright Rose\", \"#FFFFCF09\": \"Bright Saffron\", \"#FFD1CEB4\": \"Bright Sage\", \"#FFFC0E34\": \"Bright Scarlet\", \"#FF9FE2BF\": \"Bright Sea Green\", \"#FFB1AA9C\": \"Bright Sepia\", \"#FF02CCFE\": \"Bright Sky Blue\", \"#FF76C1E1\": \"Bright Spark\", \"#FFDDE2E6\": \"Bright Star\", \"#FFECBD2C\": \"Bright Sun Variant\", \"#FF01F9C6\": \"Bright Teal\", \"#FFAD0AFD\": \"Bright Violet\", \"#FFF6F2F1\": \"Bright White\", \"#FFF5EFE8\": \"Bright Winter Cloud\", \"#FFFACE6D\": \"Bright Yarrow\", \"#FFFFFE42\": \"Bright Yellow\", \"#FF9DFF00\": \"Bright Yellow Green\", \"#FF757CAE\": \"Bright Zenith\", \"#FFE2681B\": \"Brihaspati Orange\", \"#FFDAB77F\": \"Brik Dough\", \"#FFFDFDFD\": \"Brilliance\", \"#FF0094A7\": \"Brilliant\", \"#FF3399FF\": \"Brilliant Azure\", \"#FFEFC5B5\": \"Brilliant Beige\", \"#FF0075B3\": \"Brilliant Blue\", \"#FFAD548F\": \"Brilliant Carmine\", \"#FFF0DBAA\": \"Brilliant Gold\", \"#FF88B407\": \"Brilliant Green\", \"#FFEFC600\": \"Brilliant Impression\", \"#FF545454\": \"Brilliant Liquorice\", \"#FF8C6143\": \"Brilliant Oak\", \"#FF009CB7\": \"Brilliant Sea\", \"#FFA9B0B4\": \"Brilliant Silver\", \"#FF00A68B\": \"Brilliant Turquoise\", \"#FFE8EEFE\": \"Brilliant White\", \"#FFE8E5D8\": \"Brilliant Yellow\", \"#FFA3DAD4\": \"Brilliante\", \"#FF7A958C\": \"Brimming Over\", \"#FFFFBD2B\": \"Brimstone\", \"#FFC2C190\": \"Brimstone Butterfly\", \"#FF82776B\": \"Brindle\", \"#FF08808E\": \"Briny\", \"#FFDFCFC3\": \"Brioche\", \"#FFE15F65\": \"Briquette\", \"#FF515051\": \"Briquette Grey\", \"#FFD2E0EF\": \"Brisa de Mar\", \"#FF6D829D\": \"Brisk Blue\", \"#FFAAA97F\": \"Brisk Olive\", \"#FF6E4534\": \"Brisket\", \"#FFA28450\": \"Bristle Grass\", \"#FF93836F\": \"Bristol Beige\", \"#FF558F91\": \"Bristol Blue\", \"#FF83A492\": \"Bristol Green\", \"#FFA09073\": \"Britches\", \"#FFFEDE8F\": \"Brite Gold\", \"#FF7D7081\": \"British Grey Mauve\", \"#FFBCAF97\": \"British Khaki\", \"#FF35427B\": \"British Mauve\", \"#FFFF0015\": \"British Phone Booth\", \"#FF05480D\": \"British Racing Green Variant\", \"#FFF4C8DB\": \"British Rose\", \"#FF4C7E86\": \"Brittany Blue\", \"#FFF3D8E0\": \"Brittany\\u2019s Bow\", \"#FFEAAE47\": \"Brittlebush\", \"#FF94975D\": \"Broad Bean\", \"#FFBBDDFF\": \"Broad Daylight\", \"#FF034A71\": \"Broadwater Blue\", \"#FF145775\": \"Broadway\", \"#FFFEE07C\": \"Broadway Lights\", \"#FF8C87C5\": \"Brocade\", \"#FF7B4D6B\": \"Brocade Violet\", \"#FF8FA277\": \"Broccoflower\", \"#FF87B364\": \"Broccoli\", \"#FF4B5338\": \"Broccoli Green\", \"#FF008833\": \"Broccoli Paradise\", \"#FF486262\": \"Brochantite Green\", \"#FFFFDD88\": \"Broiled Flounder\", \"#FF74BBFB\": \"Broken Blue\", \"#FF060310\": \"Broken Tube\", \"#FFEEEBE3\": \"Broken White\", \"#FFA79781\": \"Bronco Variant\", \"#FFA87900\": \"Bronze Tint\", \"#FF3A4856\": \"Bronze Blue\", \"#FFFBC378\": \"Bronze Blush\", \"#FF825E2F\": \"Bronze Brown\", \"#FFEB9552\": \"Bronze Cup\", \"#FF6E6654\": \"Bronze Fig\", \"#FF8D8752\": \"Bronze Green\", \"#FF585538\": \"Bronze Icon\", \"#FFAA8031\": \"Bronze Leaf\", \"#FF6D6240\": \"Bronze Medal\", \"#FFA37F44\": \"Bronze Mist\", \"#FF584C25\": \"Bronze Olive Variant\", \"#FFE6BE9C\": \"Bronze Sand\", \"#FFCC5533\": \"Bronze Satin\", \"#FFBC8040\": \"Bronze Storm\", \"#FF434C28\": \"Bronze Tone\", \"#FFB08D57\": \"Bronze Treasure\", \"#FF737000\": \"Bronze Yellow\", \"#FFDD6633\": \"Bronzed\", \"#FF9B7E4E\": \"Bronzed Brass\", \"#FFD78A6C\": \"Bronzed Orange\", \"#FF69605A\": \"Brood\", \"#FF5E6D6E\": \"Brooding Storm\", \"#FFAFDDCC\": \"Brook Green\", \"#FFDACECD\": \"Brook Trout\", \"#FFE7EEEE\": \"Brooklet\", \"#FF586766\": \"Brooklyn\", \"#FF6D4B3F\": \"Brooklyn Brownstone\", \"#FF5A7562\": \"Brookside\", \"#FF99B792\": \"Brookview\", \"#FFEECC24\": \"Broom Variant\", \"#FF74462D\": \"Broomstick\", \"#FFB0B7C6\": \"Brother Blue\", \"#FF653700\": \"Brown Variant\", \"#FF4A3F37\": \"Brown Bear\", \"#FF4A3832\": \"Brown Beauty\", \"#FFCC8833\": \"Brown Beige\", \"#FF53331E\": \"Brown Bramble Variant\", \"#FFB08F6A\": \"Brown Branch\", \"#FFD4C5A9\": \"Brown Bread\", \"#FFC2AE93\": \"Brown Bunny\", \"#FFAC7C00\": \"Brown Butter\", \"#FF876140\": \"Brown Button\", \"#FFC5C2AD\": \"Brown Buzz\", \"#FF995555\": \"Brown Cerberus\", \"#FF5F1933\": \"Brown Chocolate\", \"#FFC37C59\": \"Brown Clay\", \"#FF4A2C2A\": \"Brown Coffee\", \"#FF594537\": \"Brown Derby Variant\", \"#FF89491A\": \"Brown Eyed Girl\", \"#FF9E6B4A\": \"Brown Eyes\", \"#FF544A42\": \"Brown Fox\", \"#FF706C11\": \"Brown Green\", \"#FF8D8468\": \"Brown Grey\", \"#FFD3B793\": \"Brown Hare\", \"#FF5E442C\": \"Brown Hen\", \"#FFF485AC\": \"Brown Knapweed\", \"#FF97382C\": \"Brown Labrador\", \"#FF7B2039\": \"Brown Magenta\", \"#FF662211\": \"Brown Moelleux\", \"#FFD8CBB5\": \"Brown Mouse\", \"#FFDFAC59\": \"Brown Mustard\", \"#FFB96902\": \"Brown Orange\", \"#FFC2AA90\": \"Brown Owl\", \"#FF8A5640\": \"Brown Patina\", \"#FF4E403B\": \"Brown Pepper\", \"#FF3C241B\": \"Brown Pod Variant\", \"#FFAE8E65\": \"Brown Rabbit\", \"#FF922B05\": \"Brown Red\", \"#FFDABD84\": \"Brown Rice\", \"#FF735852\": \"Brown Ridge\", \"#FF8D736C\": \"Brown Rose\", \"#FFBC9B4E\": \"Brown Rum\", \"#FFF7945F\": \"Brown Sand\", \"#FF4A290D\": \"Brown Study\", \"#FF5B4F41\": \"Brown Suede\", \"#FFAB764E\": \"Brown Sugar\", \"#FFC8AE96\": \"Brown Sugar Coating\", \"#FFCF7A4B\": \"Brown Sugar Glaze\", \"#FFBCA792\": \"Brown Teepee\", \"#FF906151\": \"Brown Thrush\", \"#FF704E40\": \"Brown Velvet\", \"#FFB4674D\": \"Brown Wood\", \"#FFDD9966\": \"Brown Yellow\", \"#FFDDBDA3\": \"Brown-Bag It\", \"#FF79512C\": \"Brown-Noser\", \"#FFBB4433\": \"Browned Off\", \"#FF916D56\": \"Brownie Scout\", \"#FF9C6D57\": \"Brownish\", \"#FF413936\": \"Brownish Black\", \"#FF6A6E09\": \"Brownish Green\", \"#FF86775F\": \"Brownish Grey\", \"#FFCB7723\": \"Brownish Orange\", \"#FFC27E79\": \"Brownish Pink\", \"#FF76424E\": \"Brownish Purple\", \"#FF8D746F\": \"Brownish Purple Red\", \"#FF9E3623\": \"Brownish Red\", \"#FFC9B003\": \"Brownish Yellow\", \"#FF785441\": \"Brownstone\", \"#FF6E615F\": \"Browse Brown\", \"#FFD3B99B\": \"Bruin Spice\", \"#FF7E4071\": \"Bruise\", \"#FF5B4148\": \"Bruised Burgundy\", \"#FF3B1921\": \"Bruised Plum\", \"#FFC6C6C2\": \"Brume\", \"#FF664238\": \"Brunette\", \"#FF829E2C\": \"Bruni Green\", \"#FF2A1B0E\": \"Brunneophobia\", \"#FF5E4662\": \"Brunneous\", \"#FF9BA9CA\": \"Brunnera Blue\", \"#FF433430\": \"Bruno Brown\", \"#FF236649\": \"Brunswick\", \"#FF1B4D3E\": \"Brunswick Green\", \"#FFB2654E\": \"Bruschetta\", \"#FFB99684\": \"Brush\", \"#FFD4E1ED\": \"Brush Blue\", \"#FFDB9351\": \"Brushed Clay\", \"#FFC7C8C9\": \"Brushed Metal\", \"#FF7D7A79\": \"Brushed Nickel\", \"#FFF8A060\": \"Brushed Orange\", \"#FFF1DFBA\": \"Brushstroke\", \"#FF8C5939\": \"Brushwood\", \"#FFCC6611\": \"Brusque Brown\", \"#FFEE00FF\": \"Brusque Pink\", \"#FF6C7C6D\": \"Brussels\", \"#FF665E0D\": \"Brussels Sprout Green\", \"#FFAA9B78\": \"Brussels Sprouts\", \"#FFE61626\": \"Brutal Doom\", \"#FFFF00BB\": \"Brutal Pink\", \"#FF0022DD\": \"Brutally Blue\", \"#FFA6BEA6\": \"Bryophyte\", \"#FF9FE010\": \"Bryopsida Green\", \"#FFFFBADF\": \"Bubbelgum Heart\", \"#FF90E4C1\": \"Bubble Algae\", \"#FFE8E0E9\": \"Bubble Bath\", \"#FF00B800\": \"Bubble Bobble Green\", \"#FF0084FF\": \"Bubble Bobble P2\", \"#FFD3A49A\": \"Bubble Shell\", \"#FF43817A\": \"Bubble Turquoise\", \"#FFFF85FF\": \"Bubblegum\", \"#FFCC55EE\": \"Bubblegum Baby Girl\", \"#FFF887C7\": \"Bubblegum Beam\", \"#FFFF01B7\": \"Bubblegum Bright\", \"#FFEECCEE\": \"Bubblegum Crisis\", \"#FFF092D6\": \"Bubblegum Kisses\", \"#FFF6B0BA\": \"Bubblegum Pink\", \"#FFD3E3E5\": \"Bubbles in the Air\", \"#FFEAD8C0\": \"Bubbly\", \"#FF77CCFF\": \"Bubbly Barracuda\", \"#FFC68400\": \"Bubonic Brown\", \"#FFFDF5D7\": \"Bucatini Noodle\", \"#FF6E5150\": \"Buccaneer Variant\", \"#FF035B8D\": \"Buccaneer Blue\", \"#FFAA1111\": \"B\\u00fcchel Cherry\", \"#FF674834\": \"Buckeye\", \"#FF996655\": \"Bucking Bronco\", \"#FF89A068\": \"Buckingham Gardens\", \"#FF6B5140\": \"Buckingham Palace\", \"#FFD9C3A6\": \"Buckram Binding\", \"#FFD4BA8C\": \"Buckskin\", \"#FFC9A169\": \"Buckskin Pony\", \"#FFA76F1F\": \"Buckthorn Brown\", \"#FFD4DCD6\": \"Buckwheat\", \"#FFEFE2CF\": \"Buckwheat Flour\", \"#FFE0D8A7\": \"Buckwheat Groats\", \"#FFB9A4B0\": \"Buckwheat Mauve\", \"#FF1B6634\": \"Bucolic\", \"#FF98ACB0\": \"Bucolic Blue\", \"#FFA5A88F\": \"Bud Variant\", \"#FF79B465\": \"Bud Green\", \"#FFE9E3D3\": \"Bud\\u2019s Sails\", \"#FF553D3E\": \"Budapest Brown\", \"#FFE5E1E6\": \"Budapest Pastel\", \"#FFFCE2C4\": \"Budder Skin\", \"#FFBC9B1B\": \"Buddha Gold Variant\", \"#FF37B575\": \"Buddha Green\", \"#FFFFBB33\": \"Buddha\\u2019s Love Handles\", \"#FFDEEABD\": \"Budding Bloom\", \"#FFEDECD4\": \"Budding Fern\", \"#FFC4D1BF\": \"Budding Green\", \"#FFEEF0D7\": \"Budding Leaf\", \"#FFF3D4BF\": \"Budding Peach\", \"#FF976538\": \"Buddy Buddy\", \"#FF84C9E1\": \"Budgie Blue\", \"#FF63424B\": \"Bud\\u014dnezumi Grape\", \"#FFF4DCC1\": \"Buenos Aires\", \"#FFD9CFBE\": \"Buff It\", \"#FFAA7733\": \"Buff Leather\", \"#FFFFBB7C\": \"Buff Orange\", \"#FFE8D0B9\": \"Buff Tone\", \"#FFF0B967\": \"Buff Yellow\", \"#FFF25A1A\": \"Buffallo Sauce\", \"#FFAE9274\": \"Buffalo Bill\", \"#FF695645\": \"Buffalo Dance\", \"#FF705046\": \"Buffalo Herd\", \"#FFBB9F6A\": \"Buffalo Hide\", \"#FF95786C\": \"Buffalo Soldier\", \"#FFE2AC78\": \"Buffalo Trail\", \"#FFDD9475\": \"Buffed Copper\", \"#FFAEAFB9\": \"Buffed Plum\", \"#FFA79C81\": \"Buffhide\", \"#FF868929\": \"Buffy Citrine\", \"#FFBB8F4F\": \"Bugle Boy\", \"#FFD3973C\": \"Bugle Call\", \"#FFAFAFA7\": \"Building Block\", \"#FFE9E3DA\": \"Built on Sand\", \"#FF73A263\": \"Bulbasaur\", \"#FF94B1B6\": \"Bulfinch Blue\", \"#FF636153\": \"Bull Kelp\", \"#FF6B605B\": \"Bull Ring\", \"#FF75442B\": \"Bull Shot Variant\", \"#FFFAF1C8\": \"Bullet Hell\", \"#FFCD4646\": \"Bullfighters Red\", \"#FF8A966A\": \"Bullfrog\", \"#FFB9030A\": \"Bullseye\", \"#FF359E6B\": \"Bulma Hair\", \"#FF6D5837\": \"Bulrush\", \"#FF0777BC\": \"Bumangu\\u00e9s Blue\", \"#FFF5F1DE\": \"Bumble Baby\", \"#FFFFC82A\": \"Bumblebee\", \"#FF674961\": \"Bunchberry\", \"#FFFFC58A\": \"Bundaberg Sand\", \"#FFE5B584\": \"Bundle of Wheat\", \"#FFCBBEAA\": \"Bungalow Beige\", \"#FFAD947B\": \"Bungalow Brown\", \"#FFAD8047\": \"Bungalow Gold\", \"#FFE4C590\": \"Bungalow Maple\", \"#FFCEBE9F\": \"Bungalow Taupe\", \"#FFE4D3C8\": \"Bungalow White\", \"#FF696156\": \"Bungee Cord\", \"#FF988F7B\": \"Bunglehouse Beige\", \"#FF46616E\": \"Bunglehouse Blue\", \"#FF292C2F\": \"Bunker Variant\", \"#FF6C4522\": \"Bunni Brown\", \"#FFF1B5CC\": \"Bunny Cake\", \"#FFF9D9D2\": \"Bunny Ears\", \"#FFFB8DA6\": \"Bunny Fluff\", \"#FFF3ECEA\": \"Bunny Hop\", \"#FFDEC3C9\": \"Bunny Pink\", \"#FFD3BFC4\": \"Bunny Soft\", \"#FFFFE3F4\": \"Bunny Tail\", \"#FFFAD9DD\": \"Bunny\\u2019s Nose\", \"#FF2B3449\": \"Bunting Variant\", \"#FF35537C\": \"Bunting Blue\", \"#FF79B0B6\": \"Buoyancy\", \"#FF65707E\": \"Buoyant\", \"#FF84ADDB\": \"Buoyant Blue\", \"#FF717867\": \"Burdock\", \"#FF746C8F\": \"Bureaucracy\", \"#FFDADBA0\": \"Burgundy Grey\", \"#FF811D45\": \"Burgundy Orchid\", \"#FF7E7150\": \"Burgundy Snail\", \"#FF6C403E\": \"Burgundy Wine\", \"#FFDBBC4B\": \"Buried Gold\", \"#FF772200\": \"Buried Lust\", \"#FFD28B42\": \"Buried Treasure\", \"#FFD4DEE8\": \"Burj Khalifa Fountain\", \"#FF353E4F\": \"Burka Black\", \"#FF8B7753\": \"Burlap\", \"#FF81717E\": \"Burlap Grey\", \"#FF6E314F\": \"Burlat Red\", \"#FF8F4C3A\": \"Burled Redwood\", \"#FF695641\": \"Burley Wood\", \"#FFA17874\": \"Burlwood\", \"#FF94B1A0\": \"Burma Jade\", \"#FFBC8143\": \"Burmese Gold\", \"#FF520B00\": \"Burned\", \"#FF6F4B3E\": \"Burned Brown\", \"#FF234537\": \"Burnham Variant\", \"#FF884736\": \"Burning Brier\", \"#FFA0403E\": \"Burning Bush\", \"#FFF79D72\": \"Burning Coals\", \"#FFFF1166\": \"Burning Fireflies\", \"#FFFFB162\": \"Burning Flame\", \"#FFCCAA77\": \"Burning Gold\", \"#FF8F8B72\": \"Burning Idea\", \"#FFFF7124\": \"Burning Orange Variant\", \"#FFFF0599\": \"Burning Raspberry\", \"#FFD08363\": \"Burning Sand Variant\", \"#FF742100\": \"Burning Steppes\", \"#FFEB5030\": \"Burning Tomato\", \"#FFEE9922\": \"Burning Trail\", \"#FF150AEC\": \"Burning Ultrablue\", \"#FFC48D82\": \"Burnished Apricot\", \"#FF6A3D36\": \"Burnished Bark\", \"#FF8B664E\": \"Burnished Brandy\", \"#FF9C7E40\": \"Burnished Bronze\", \"#FFBE9167\": \"Burnished Caramel\", \"#FFD2CCC4\": \"Burnished Clay\", \"#FFBB8833\": \"Burnished Copper\", \"#FFFCE5BF\": \"Burnished Cream\", \"#FFAA9855\": \"Burnished Gold\", \"#FFC5AEB1\": \"Burnished Lilac\", \"#FF734842\": \"Burnished Mahogany\", \"#FFC8CBC8\": \"Burnished Metal\", \"#FF716A62\": \"Burnished Pewter\", \"#FF794029\": \"Burnished Russet\", \"#FF7B5847\": \"Burns Cave\", \"#FFD0A664\": \"Burnside\", \"#FFB0724A\": \"Burnt Almond\", \"#FF746572\": \"Burnt Ash\", \"#FF9A4E12\": \"Burnt Bagel\", \"#FF4D3B3C\": \"Burnt Bamboo\", \"#FFB45241\": \"Burnt Brick\", \"#FFA47C53\": \"Burnt Butter\", \"#FF846242\": \"Burnt Caramel\", \"#FF271B10\": \"Burnt Coffee\", \"#FFC56A39\": \"Burnt Copper\", \"#FFE57568\": \"Burnt Coral\", \"#FF582124\": \"Burnt Crimson\", \"#FF885533\": \"Burnt Crust\", \"#FF9D4531\": \"Burnt Earth\", \"#FF75625E\": \"Burnt Grape\", \"#FF8D4035\": \"Burnt Henna\", \"#FFA87F28\": \"Burnt Honey\", \"#FFBB4F35\": \"Burnt Ochre\", \"#FF736F54\": \"Burnt Olive\", \"#FF743D68\": \"Burnt Orchid\", \"#FFCA955C\": \"Burnt Pumpkin\", \"#FF9F2305\": \"Burnt Red\", \"#FF853C47\": \"Burnt Russet\", \"#FFA93400\": \"Burnt Sienna Variant\", \"#FF82634E\": \"Burnt Terra\", \"#FF774645\": \"Burnt Tile\", \"#FFAB7E5E\": \"Burnt Toffee\", \"#FFD5AB09\": \"Burnt Yellow\", \"#FF6832E3\": \"Burple\", \"#FFEED7C1\": \"Burrito\", \"#FF947764\": \"Burro\", \"#FFDEB368\": \"Burst of Gold\", \"#FFACD243\": \"Burst of Lime\", \"#FFFCE282\": \"Bursting Lemon\", \"#FFA28D82\": \"Bush Buck\", \"#FFA0BCD0\": \"Bush Viper\", \"#FF9FA993\": \"Bushel\", \"#FF7F7B73\": \"Bushland Grey\", \"#FFE5A1A0\": \"Bussell Lace\", \"#FF3E4B69\": \"Buster\", \"#FF3300CC\": \"Busty Blue\", \"#FFF4FF00\": \"Busy Bee\", \"#FFB69983\": \"Butcher Paper\", \"#FFFFFF81\": \"Butter\", \"#FFBA843A\": \"Butter & Syrup\", \"#FFC28A35\": \"Butter Base\", \"#FFC88849\": \"Butter Bronze\", \"#FFFDFF52\": \"Butter Cake\", \"#FFA67A4C\": \"Butter Caramel\", \"#FFF0E4B2\": \"Butter Cookie\", \"#FFFEE5BA\": \"Butter Creme\", \"#FFFFDD99\": \"Butter Cupcake\", \"#FFFCE9AD\": \"Butter Fingers\", \"#FFAA6600\": \"Butter Fudge\", \"#FFF5E5AB\": \"Butter Honey\", \"#FFF5E5DA\": \"Butter Icing\", \"#FFCFE7CB\": \"Butter Lettuce\", \"#FFF6DFB2\": \"Butter Muffin\", \"#FFF9E097\": \"Butter Ridge\", \"#FFC38650\": \"Butter Rum\", \"#FFFEE99F\": \"Butter Tart\", \"#FFF4E0BB\": \"Butter Up\", \"#FFFDDEBD\": \"Butter White\", \"#FFFFFD74\": \"Butter Yellow\", \"#FFFFF4C4\": \"Butterball\", \"#FFAF7934\": \"Butterbeer\", \"#FFF1C766\": \"Butterblond\", \"#FFC5AE7C\": \"Butterbrot\", \"#FFEFE0CD\": \"Buttercream\", \"#FFF5EDD7\": \"Buttercream Frosting\", \"#FFDA9429\": \"Buttercup Variant\", \"#FFF1F458\": \"Buttercup Glow\", \"#FFE3C2A3\": \"Buttercup Yellow\", \"#FFECE2B7\": \"Buttered\", \"#FFFFF0A4\": \"Buttered Popcorn\", \"#FF9D702E\": \"Buttered Rum Variant\", \"#FFF7F0D2\": \"Buttered Up\", \"#FFF7BE5B\": \"Butterfield\", \"#FFCADEA5\": \"Butterfly\", \"#FF2099BB\": \"Butterfly Blue\", \"#FF68578C\": \"Butterfly Bush Variant\", \"#FF908ABA\": \"Butterfly Garden\", \"#FF0B6863\": \"Butterfly Green\", \"#FFF0DEDC\": \"Butterfly Kisses\", \"#FFF8CFB4\": \"Butterfly Wing\", \"#FFFFF7DB\": \"Buttermelon\", \"#FFFFFEE4\": \"Buttermilk Variant\", \"#FFFFA177\": \"Butternut\", \"#FFD99E66\": \"Butternut Pie\", \"#FFE59752\": \"Butternut Pizazz\", \"#FFFC7604\": \"Butternut Squash\", \"#FFCF9A5D\": \"Butternut Tree\", \"#FF7E6F59\": \"Butternut Wood\", \"#FFFDB147\": \"Butterscotch\", \"#FFD3B090\": \"Butterscotch Amber\", \"#FFD7AD62\": \"Butterscotch Bliss\", \"#FFF1C882\": \"Butterscotch Cake\", \"#FFC48446\": \"Butterscotch Glaze\", \"#FFA97D54\": \"Butterscotch Mousse\", \"#FFB08843\": \"Butterscotch Ripple\", \"#FFDBB486\": \"Butterscotch Sundae\", \"#FFD9A05F\": \"Butterscotch Syrup\", \"#FFC68F65\": \"Butterum\", \"#FFFFC283\": \"Buttery\", \"#FFF6E19C\": \"Buttery Croissant\", \"#FFD4B185\": \"Buttery Leather\", \"#FFFFB19A\": \"Buttery Salmon\", \"#FFF1EBDA\": \"Buttery White Variant\", \"#FF24A0ED\": \"Button Blue\", \"#FF4F3A32\": \"Button Eyes\", \"#FFECE6C8\": \"Button Mushroom\", \"#FFF0C641\": \"Buzz\", \"#FFFFD756\": \"Buzz-In\", \"#FF5F563F\": \"Buzzard\", \"#FF017A79\": \"Buzzards Bay\", \"#FFE6B261\": \"Buzzworthy\", \"#FF816A38\": \"By Gum\", \"#FF8D999E\": \"By the Sea\", \"#FFA5BA93\": \"Byakuroku Green\", \"#FF918E8A\": \"Bygone\", \"#FFB6C4D2\": \"Bypass\", \"#FF31667D\": \"Byron Place\", \"#FFC5DCE0\": \"Byte Blue\", \"#FF006C6E\": \"Byzantine Blue\", \"#FFAB7141\": \"Byzantine Copper\", \"#FF6A79F7\": \"Byzantine Night Blue\", \"#FFC33140\": \"C-3PO\", \"#FF83BCE5\": \"C\\u2019est la Vie\", \"#FF003AFF\": \"C64 Blue\", \"#FF4E7FFF\": \"C64 NTSC\", \"#FF6F6ED1\": \"C64 Purple\", \"#FF4A2E32\": \"Cab Sav Variant\", \"#FF7F6473\": \"Cabal\", \"#FF8EC1C0\": \"Cabana Bay\", \"#FF5B9099\": \"Cabana Blue\", \"#FFDCA901\": \"Cabana Glow\", \"#FFC88567\": \"Cabana Melon\", \"#FFCD526C\": \"Cabaret Variant\", \"#FF7C8EA6\": \"Cabaret Charm\", \"#FF87D7BE\": \"Cabbage\", \"#FF724C7B\": \"Cabbage Blossom Violet\", \"#FF807553\": \"Cabbage Green\", \"#FFDFE8D0\": \"Cabbage Leaf\", \"#FF93C460\": \"Cabbage Patch\", \"#FF4C5544\": \"Cabbage Pont Variant\", \"#FFC59F91\": \"Cabbage Rose\", \"#FF8E5B68\": \"Cabernet\", \"#FF6D3445\": \"Cabernet Craving\", \"#FF5E5349\": \"Cabin Fever\", \"#FF5D4D47\": \"Cabin in the Woods\", \"#FF574038\": \"Cabin Plank\", \"#FFCEC0AA\": \"Cabo\", \"#FFA8A4A1\": \"Caboose\", \"#FF6B5848\": \"Cacao\", \"#FF80442F\": \"Cacao Nibs\", \"#FFB5CEE0\": \"Cache Blue\", \"#FFD3C296\": \"Cache of Camel\", \"#FFF3D9BA\": \"Cachet Cream\", \"#FF9F0000\": \"Cacodemon Red\", \"#FF5B6F55\": \"Cactus Variant\", \"#FFF6C79D\": \"Cactus Blooms\", \"#FFD8E5DD\": \"Cactus Blossom\", \"#FFAF416B\": \"Cactus Flower\", \"#FF7B8370\": \"Cactus Garden\", \"#FF56603D\": \"Cactus Green\", \"#FFB1A386\": \"Cactus Hill\", \"#FF9C9369\": \"Cactus Sand\", \"#FFC1E0A3\": \"Cactus Spike\", \"#FF88976B\": \"Cactus Valley\", \"#FFD0F7E4\": \"Cactus Water\", \"#FF009977\": \"Cadaverous\", \"#FF3E354D\": \"Caddies Silk\", \"#FF536872\": \"Cadet\", \"#FF3B5964\": \"Cadet Song\", \"#FF90766E\": \"Cadian\", \"#FF984961\": \"Cadillac Variant\", \"#FF0A1195\": \"Cadmium Blue\", \"#FFB60C26\": \"Cadmium Purple\", \"#FF7F3E98\": \"Cadmium Violet\", \"#FFFFEE66\": \"Caduceus Gold\", \"#FFEEDD22\": \"Caduceus Staff\", \"#FFECD0B1\": \"Caen Stone\", \"#FF986860\": \"Caf\\u00e9\", \"#FFAA8E74\": \"Caf\\u00e9 Am\\u00e9ricaine\", \"#FFA57C5B\": \"Caf\\u00e9 au Lait\", \"#FF8A9B98\": \"Caf\\u00e9 Blue\", \"#FFC79685\": \"Caf\\u00e9 Cr\\u00e8me\", \"#FF889944\": \"Caf\\u00e9 de Paris\", \"#FF5E4C48\": \"Cafe Expreso\", \"#FFD6C6B4\": \"Cafe Latte\", \"#FFB98F6F\": \"Caf\\u00e9 Miel\", \"#FF9A7F79\": \"Cafe Ole\", \"#FFECC1C2\": \"Cafe Pink\", \"#FFAE8774\": \"Caf\\u00e9 Renvers\\u00e9\", \"#FF6A4928\": \"Cafe Royale Variant\", \"#FF885511\": \"Caffeinated Cinnamon\", \"#FF8A796A\": \"Caffeine\", \"#FF26B7B5\": \"Caicos Turquoise\", \"#FF0A6B92\": \"Cairns\", \"#FFC46D29\": \"Cajeta\", \"#FF5F3E41\": \"Cajun Brown\", \"#FFA45A4A\": \"Cajun Red\", \"#FFC3705F\": \"Cajun Spice\", \"#FFF0EDDB\": \"Cake Batter\", \"#FFE8D4BB\": \"Cake Crumbs\", \"#FFFCE0A8\": \"Cake Dough\", \"#FFF9DFE5\": \"Cake Frosting\", \"#FFEDC9D0\": \"Cake Pop\", \"#FFF6CAC3\": \"Cake Pop Pink\", \"#FFF8C649\": \"Cakepop Sorbet\", \"#FF0AC2C2\": \"Cala Benirr\\u00e1s Blue\", \"#FFF8EB97\": \"Calabash\", \"#FF728478\": \"Calabash Clash\", \"#FFF4A6A3\": \"Calabrese\", \"#FFFCFFA4\": \"Calamansi\", \"#FFC4CC7A\": \"Calamansi Green\", \"#FF80FFCC\": \"Calamine Blue\", \"#FFE7E1DD\": \"Calc Sinter\", \"#FFDDEEFF\": \"Calcareous Sinter\", \"#FF94B2B2\": \"Calcite Blue\", \"#FF52605F\": \"Calcite Grey Green\", \"#FFF2F4E8\": \"Calcium\", \"#FFEEE9D9\": \"Calcium Rock\", \"#FFA1CCB1\": \"Calculus\", \"#FF31639C\": \"Caledor Sky\", \"#FFC1A188\": \"Calfskin\", \"#FF0485D1\": \"Calgar Blue\", \"#FFA57E98\": \"Cali Lily\", \"#FF005726\": \"Caliban Green\", \"#FFD5B185\": \"Calico Variant\", \"#FFC48E36\": \"Calico Cat\", \"#FF3D4E67\": \"Calico Dress\", \"#FF9C9584\": \"Calico Rock\", \"#FFE5C1B3\": \"Calico Rose\", \"#FF95594A\": \"Caliente\", \"#FFE98C3A\": \"California Variant\", \"#FFE6B76C\": \"California Chamois\", \"#FFE3AA94\": \"California Coral\", \"#FF93807F\": \"California Dreamin\\u2019\", \"#FFDEC569\": \"California Dreaming\", \"#FFFCA716\": \"California Girl\", \"#FF95743F\": \"California Gold Rush\", \"#FFBBC5E2\": \"California Lilac\", \"#FFFCBE6A\": \"California Peach\", \"#FFA83C3F\": \"California Poppy\", \"#FFA09574\": \"California Roll\", \"#FF959988\": \"California Sagebrush\", \"#FFC5AD9A\": \"California Stucco\", \"#FFCA1850\": \"California Sunset\", \"#FFCA4B65\": \"California Wine\", \"#FF42364C\": \"Call It a Night\", \"#FFF2DFB5\": \"Calla\", \"#FF747D3B\": \"Calla Green\", \"#FFE4EAED\": \"Calla Lily\", \"#FF59636A\": \"Calligraphy\", \"#FFC89A8D\": \"Calliope\", \"#FF798052\": \"Calliste Green\", \"#FFCACFD3\": \"Callisto\", \"#FFDFE9E6\": \"Calm\", \"#FFEED2AE\": \"Calm Air\", \"#FF5E9D47\": \"Calm Balm\", \"#FFE9ECE4\": \"Calm Breeze\", \"#FFD0D4CF\": \"Calm Cool and Collected\", \"#FFC6B0B9\": \"Calm Cupid\", \"#FF7CAACF\": \"Calm Day\", \"#FFA7B0D5\": \"Calm Interlude\", \"#FFDEE2EB\": \"Calm Iridescence\", \"#FFE5EDE2\": \"Calm Thoughts\", \"#FFEAE3E9\": \"Calm Tint\", \"#FFE7FAFA\": \"Calm Waters\", \"#FFCFD3A2\": \"Calming Effect\", \"#FFEEE0D1\": \"Calming Retreat\", \"#FFB2A2C1\": \"Calming Silver Lavender\", \"#FFAAB7C1\": \"Calming Space\", \"#FF68A895\": \"Calmness\", \"#FF6D5044\": \"Calthan Brown\", \"#FF3D7188\": \"Calypso Variant\", \"#FFC53A4B\": \"Calypso Berry\", \"#FFEC4A61\": \"Calypso Coral\", \"#FF2E5F60\": \"Calypso Green\", \"#FFD978F0\": \"Calypso Orchid\", \"#FFDE6B66\": \"Calypso Red\", \"#FFFE828C\": \"Camaron Pink\", \"#FF206937\": \"Camarone Variant\", \"#FF8C633C\": \"Cambridge Leather\", \"#FFACB8B4\": \"Cambridge Lily\", \"#FFC69F59\": \"Camel\", \"#FFA56639\": \"Camel Brown\", \"#FFCC9944\": \"Camel Cardinal\", \"#FFC5B39A\": \"Camel Coat\", \"#FFE0CB82\": \"Camel Cord\", \"#FFBB6600\": \"Camel Fur\", \"#FFDBB8A4\": \"Camel Hair\", \"#FFF5B784\": \"Camel Hair Coat\", \"#FFC1AA91\": \"Camel Hide\", \"#FFE5743B\": \"Camel Red\", \"#FFB68B45\": \"Camel Ride\", \"#FFAC8A2A\": \"Camel Toe\", \"#FFBAAE9D\": \"Camel Train\", \"#FF817667\": \"Camel\\u2019s Hump\", \"#FFC5AA85\": \"Camelback\", \"#FFD3B587\": \"Camelback Mountain\", \"#FFE2AF60\": \"Cameleer\", \"#FFF6685A\": \"Camellia\", \"#FFCD739D\": \"Camellia Pink\", \"#FFE94E6D\": \"Camellia Rose\", \"#FF803A4B\": \"Camelot Variant\", \"#FFFBF3DF\": \"Camembert\", \"#FFF2DEBC\": \"Cameo Variant\", \"#FFDFC1C3\": \"Cameo Appearance\", \"#FF7097A2\": \"Cameo Blue\", \"#FFBE847D\": \"Cameo Brown\", \"#FFF3E2C3\": \"Cameo Cream\", \"#FFDCE6E5\": \"Cameo Green\", \"#FFEBCFC9\": \"Cameo Peach\", \"#FFDDCAAF\": \"Cameo Role\", \"#FFF7DFD7\": \"Cameo Rose\", \"#FFEBDFD8\": \"Cameo Stone\", \"#FFEED8BA\": \"Cameo White\", \"#FF60746D\": \"Cameroon Green\", \"#FFEEB5B4\": \"Camille Pink\", \"#FFFCD9C7\": \"Camisole\", \"#FF7F8F4E\": \"Camo\", \"#FF8C8475\": \"Camo Beige\", \"#FF747F71\": \"Camo Clay\", \"#FFA5A542\": \"Camo Green\", \"#FF4B6113\": \"Camouflage Green Variant\", \"#FFA28F5C\": \"Camouflage Olive\", \"#FFFCF7DB\": \"Campanelle Noodle\", \"#FF3473B7\": \"Campanula\", \"#FF6C6D94\": \"Campanula Purple\", \"#FFCE5F38\": \"Campfire\", \"#FFDDD9CE\": \"Campfire Ash\", \"#FFB67656\": \"Campfire Blaze\", \"#FFD5D1CB\": \"Campfire Smoke\", \"#FFD0A569\": \"Campground\", \"#FFB4C2A2\": \"Camping Grounds\", \"#FFB6AFA0\": \"Camping Tent\", \"#FF67786E\": \"Camping Trip\", \"#FFD08A9B\": \"Can Can Variant\", \"#FFEAE2DD\": \"Canada Goose Eggs\", \"#FF415A53\": \"Canadian Fir\", \"#FF8F9AA4\": \"Canadian Lake\", \"#FFCAB266\": \"Canadian Maple\", \"#FFEDD8C3\": \"Canadian Pancake\", \"#FF2E7B52\": \"Canadian Pine\", \"#FF579ACA\": \"Canadian Tuxedo\", \"#FF9CC2C5\": \"Canal Blue\", \"#FF969281\": \"Canal Street\", \"#FF818C72\": \"Canaletto\", \"#FFFDFF63\": \"Canary Variant\", \"#FFFFCE52\": \"Canary Diamond\", \"#FFEFDE75\": \"Canary Feather\", \"#FFD0CCA9\": \"Canary Grass\", \"#FFCCD6BC\": \"Canary Green\", \"#FFE9D4A9\": \"Canary Island\", \"#FF91A1B5\": \"Canary Wharf\", \"#FF27A0A8\": \"Cancer Seagreen Scarab\", \"#FFBAC4D5\": \"Candela\", \"#FFE1C161\": \"Candelabra\", \"#FF6CC3E0\": \"Candid Blue\", \"#FFC3BC90\": \"Candidate\", \"#FFB95B6D\": \"Candied Apple\", \"#FF331166\": \"Candied Blueberry\", \"#FFBFA387\": \"Candied Ginger\", \"#FF838252\": \"Candied Lime\", \"#FFD8FFF3\": \"Candied Snow\", \"#FFF9A765\": \"Candied Yams\", \"#FFC3BDAA\": \"Candle Bark\", \"#FFFFF4A1\": \"Candle Flame\", \"#FFFFE8C3\": \"Candle Glow\", \"#FFF9EBBF\": \"Candle in the Wind\", \"#FFF2EACF\": \"Candle Wax\", \"#FFE09B6E\": \"Candle Yellow\", \"#FFCEB3BE\": \"Candlelight Dinner\", \"#FFFCF4E2\": \"Candlelight Ivory\", \"#FFF8A39D\": \"Candlelight Peach\", \"#FFF7F0C7\": \"Candlelight Yellow\", \"#FFF1EDE0\": \"Candlelit Beige\", \"#FFFFF1D5\": \"Candlestick Point\", \"#FFF2EBD3\": \"Candlewick\", \"#FFFF9B87\": \"Candy\", \"#FFF7BFC2\": \"Candy Cane\", \"#FFEF9FAA\": \"Candy Coated\", \"#FFFCFC5D\": \"Candy Corn Variant\", \"#FFE9AEF2\": \"Candy Dreams\", \"#FFC25D6A\": \"Candy Drop\", \"#FFE8A7E2\": \"Candy Floss\", \"#FFFFF0DE\": \"Candy Floss Cupcake\", \"#FF7755EE\": \"Candy Grape Fizz\", \"#FF33AA00\": \"Candy Grass\", \"#FF33CC00\": \"Candy Green\", \"#FFF5A2A1\": \"Candy Heart Pink\", \"#FFFABEB5\": \"Candy Kisses\", \"#FFF3DFE3\": \"Candy Mix\", \"#FFFF63E9\": \"Candy Pink Variant\", \"#FF895D8B\": \"Candy Violet\", \"#FFFF9E76\": \"Candyman\", \"#FFEDC9D8\": \"Candytuft\", \"#FFE3B982\": \"Cane Sugar\", \"#FFDDBB99\": \"Cane Sugar Glaze\", \"#FF977042\": \"Cane Toad\", \"#FF009BB3\": \"Caneel Bay\", \"#FFD7B69A\": \"Canewood\", \"#FFF7E4CC\": \"Cannellini Beans\", \"#FFBCB09E\": \"Cannery Park\", \"#FFEDECDB\": \"Cannoli Cream\", \"#FF484335\": \"Cannon Ball\", \"#FF3C4142\": \"Cannon Barrel\", \"#FF646C64\": \"Cannon Grey\", \"#FFDDC49E\": \"Canoe\", \"#FF1D5671\": \"Canoe Blue\", \"#FFF7EB7A\": \"Canola Oil\", \"#FF728F02\": \"Canopy\", \"#FFAABFD8\": \"Canopy Bed\", \"#FFFFD479\": \"Cantaloupe\", \"#FFFEB079\": \"Cantaloupe Slice\", \"#FFFFB355\": \"Cantaloupe Smile\", \"#FFAC8D74\": \"Cantankerous Coyote\", \"#FF96887F\": \"Cantankerous Hippo\", \"#FF5E5347\": \"Canteen\", \"#FFF6D3BB\": \"Canter Peach\", \"#FFCEC5AF\": \"Cantera\", \"#FFB9C3E6\": \"Canterbury Bells\", \"#FFB2AB94\": \"Canterbury Cathedral\", \"#FFE7E1D1\": \"Canterbury Cream\", \"#FF649C97\": \"Canton\", \"#FFBAE7C7\": \"Canton Jade\", \"#FFBB8855\": \"Canvas\", \"#FFE6DFD2\": \"Canvas Cloth\", \"#FFE2D7C6\": \"Canvas Luggage\", \"#FFCCB88D\": \"Canvas Satchel\", \"#FFDDD6C6\": \"Canvas Tan\", \"#FF607B8E\": \"Canyon Blue\", \"#FFCB7D6F\": \"Canyon Clay\", \"#FFECE3D1\": \"Canyon Cliffs\", \"#FFAEAFBB\": \"Canyon Cloud\", \"#FFDDC3B7\": \"Canyon Dusk\", \"#FFB18575\": \"Canyon Earth\", \"#FFE5E1CC\": \"Canyon Echo\", \"#FF97987F\": \"Canyon Falls\", \"#FFF1B8AC\": \"Canyon Hush\", \"#FF49548F\": \"Canyon Iris\", \"#FFA7A4C0\": \"Canyon Mist\", \"#FFEEDACB\": \"Canyon Peach\", \"#FFB47571\": \"Canyon Rose\", \"#FFF2D6AA\": \"Canyon Sand\", \"#FF93625B\": \"Canyon Stone\", \"#FFDD8869\": \"Canyon Sunset\", \"#FFD6B8A9\": \"Canyon Trail\", \"#FF8A7E5C\": \"Canyon Verde\", \"#FFC3B39F\": \"Canyon View\", \"#FFA14935\": \"Canyon Wall\", \"#FFE3E5DF\": \"Canyon Wind\", \"#FFF5DED1\": \"Canyonville\", \"#FF1FA774\": \"C\\u01ceo L\\u01dc Grass\", \"#FF4E5552\": \"Cape Cod Variant\", \"#FF557080\": \"Cape Cod Bay\", \"#FF91A2A6\": \"Cape Cod Blue\", \"#FFFEE0A5\": \"Cape Honey Variant\", \"#FFD8D6D7\": \"Cape Hope\", \"#FFFFB95A\": \"Cape Jasmine\", \"#FF50818B\": \"Cape Lee\", \"#FF75482F\": \"Cape Palliser Variant\", \"#FF0092AD\": \"Cape Pond\", \"#FFF6CDB8\": \"Cape Sands\", \"#FF3C4754\": \"Cape Storm\", \"#FF01554F\": \"Cape Verde\", \"#FFD9CED2\": \"Capella\", \"#FF847640\": \"Caper Green\", \"#FF78728C\": \"Capercaillie Mauve\", \"#FF897A3E\": \"Capers\", \"#FFFCEBCE\": \"Capetown Cream\", \"#FF1A4157\": \"Capital Blue\", \"#FFDBD0A8\": \"Capital Grains\", \"#FFE6BA45\": \"Capital Yellow\", \"#FF008F4C\": \"Capitalino Cactus\", \"#FFD9544D\": \"Capocollo\", \"#FF822A10\": \"Caponata\", \"#FF704A3A\": \"Cappuccino\", \"#FFB4897D\": \"Cappuccino Bombe\", \"#FFE1DDCD\": \"Cappuccino Cosmico\", \"#FFE0D0C2\": \"Cappuccino Foam\", \"#FFC8B089\": \"Cappuccino Froth\", \"#FF0089A8\": \"Capri Breeze\", \"#FFF1F0D6\": \"Capri Cream\", \"#FFAC839C\": \"Capri Fashion Pink\", \"#FFABE2D6\": \"Capri Water Blue\", \"#FFF1CD9F\": \"Capricious\", \"#FFBB00DD\": \"Capricious Purple\", \"#FFFECB51\": \"Capricorn Golden Key\", \"#FF7E7A75\": \"Caps\", \"#FF6D8A74\": \"Capsella\", \"#FF76392E\": \"Capsicum Red\", \"#FF007EB0\": \"Capstan\", \"#FF005171\": \"Captain Blue\", \"#FF9B870C\": \"Captain Kirk\", \"#FF828080\": \"Captain Nemo\", \"#FF557088\": \"Captains Blue\", \"#FF947CAE\": \"Captivated\", \"#FFD8CACE\": \"Captivating\", \"#FFF4D9B1\": \"Captivating Cream\", \"#FF005B6A\": \"Captive\", \"#FF2CBAA3\": \"Capture\", \"#FF6E6D4A\": \"Capulet Olive\", \"#FF5D473A\": \"Carafe\", \"#FF795F4D\": \"Cara\\u00efbe\", \"#FF552233\": \"Carambar\", \"#FFEFEBD1\": \"Carambola\", \"#FFAF6F09\": \"Caramel Variant\", \"#FFB87A59\": \"Caramel Apple\", \"#FFCC8654\": \"Caramel Bar\", \"#FFB18775\": \"Caramel Brown\", \"#FF8E5626\": \"Caramel Caf\\u00e9\", \"#FFB3715D\": \"Caramel Candy\", \"#FFD4AF85\": \"Caramel Cloud\", \"#FFBB7711\": \"Caramel Coating\", \"#FFF4B58F\": \"Caramel Cream\", \"#FFC39355\": \"Caramel Crumb\", \"#FFB98C5D\": \"Caramel Cupcake\", \"#FFB8623B\": \"Caramel Dream\", \"#FFD9AD7F\": \"Caramel Drizzle\", \"#FFE3AF64\": \"Caramel Essence\", \"#FFFFD59A\": \"Caramel Finish\", \"#FFB1936D\": \"Caramel Gold\", \"#FFEEC9AA\": \"Caramel Ice\", \"#FFB08A61\": \"Caramel Kiss\", \"#FF9D652B\": \"Caramel Kisses\", \"#FF8C6342\": \"Caramel Latte\", \"#FFC58D4B\": \"Caramel Macchiato\", \"#FFE5CAA4\": \"Caramel Mousse\", \"#FFEEBB99\": \"Caramel Powder\", \"#FFB3804D\": \"Caramel Sauce\", \"#FFA78045\": \"Caramel Suede\", \"#FFA9876A\": \"Caramel Sundae\", \"#FF8F6A4F\": \"Caramel Swirl\", \"#FFC27E43\": \"Caramel Toffee\", \"#FFD58A37\": \"Caramelise\", \"#FFBA947F\": \"Caramelised\", \"#FFAD5A28\": \"Caramelised Maple\", \"#FFEF924A\": \"Caramelised Orange\", \"#FFC56F2B\": \"Caramelised Peach\", \"#FFE7D5AD\": \"Caramelised Pears\", \"#FFA17B4D\": \"Caramelised Pecan\", \"#FF6E564A\": \"Caramelised Walnut\", \"#FFD69E6B\": \"Caramelo Dulce\", \"#FF9C0013\": \"Caraquenian Crimson\", \"#FF8C6E54\": \"Caravel Brown\", \"#FFA19473\": \"Caraway\", \"#FF6D563C\": \"Caraway Brown\", \"#FFDFD5BB\": \"Caraway Seeds\", \"#FFAB9975\": \"Caraway Shield\", \"#FF316382\": \"Carbide\", \"#FF333333\": \"Carbon\", \"#FF373C4F\": \"Carbon Blue\", \"#FF545554\": \"Carbon Copy\", \"#FF565B58\": \"Carbon Dating\", \"#FF2E2E2E\": \"Carbon Fibre\", \"#FF7B808B\": \"Carbon Footprint\", \"#FF00512C\": \"Card Table Green\", \"#FFAAAA77\": \"Cardamom\", \"#FFD7E2BC\": \"Cardamom Fragrance\", \"#FF989057\": \"Cardamom Green\", \"#FF837165\": \"Cardamom Spice\", \"#FFC19A6C\": \"Cardboard\", \"#FFE4DDCE\": \"Carded Wool\", \"#FF1B3427\": \"Cardin Green Variant\", \"#FF2C284C\": \"Cardinal Mauve\", \"#FFD10929\": \"Cardinal Rage\", \"#FF9B365E\": \"Cardinal Red\", \"#FFB33125\": \"Cardinal\\u2019s Cassock\", \"#FF9AAE8C\": \"Cardoon\", \"#FF957B38\": \"Cardueline Finch\", \"#FFDCE9E9\": \"Carefree\", \"#FFA6CDDE\": \"Carefree Sky\", \"#FFFAAFC8\": \"Caregiver Pink\", \"#FFC99AA0\": \"Careys Pink Variant\", \"#FF8F755B\": \"Cargo\", \"#FFC8C5A7\": \"Cargo Green\", \"#FFCDC4AE\": \"Cargo Pants\", \"#FFCFCDBB\": \"Cargo River\", \"#FFCAF0E5\": \"Caribbean\", \"#FF1AC1DD\": \"Caribbean Blue\", \"#FF93C5DD\": \"Caribbean Coast\", \"#FFC07761\": \"Caribbean Coral\", \"#FF3F9DA9\": \"Caribbean Cruise\", \"#FF006E6E\": \"Caribbean Current\", \"#FF007180\": \"Caribbean Dream\", \"#FFCADEEA\": \"Caribbean Mist\", \"#FFD5DCCE\": \"Caribbean Pleasure\", \"#FF0087A7\": \"Caribbean Sea\", \"#FF819ECB\": \"Caribbean Sky\", \"#FF00697C\": \"Caribbean Splash\", \"#FFF5DAAA\": \"Caribbean Sunrise\", \"#FF126366\": \"Caribbean Swim\", \"#FF009D94\": \"Caribbean Turquoise\", \"#FF147D87\": \"Caribe\", \"#FF816C5E\": \"Caribou\", \"#FFCDA563\": \"Caribou Herd\", \"#FFE68095\": \"Carissima\", \"#FFF5F9CB\": \"Carla Variant\", \"#FFA87376\": \"Carley\\u2019s Rose\", \"#FF45867C\": \"Carlisle\", \"#FF915F3D\": \"Carmel\", \"#FF927F76\": \"Carmel Mission\", \"#FF8D6B3B\": \"Carmel Woods\", \"#FFB98970\": \"Carmelite\", \"#FFBB534C\": \"Carmelito\", \"#FF7C383F\": \"Carmen\", \"#FF903E2F\": \"Carmen Miranda\", \"#FFD60036\": \"Carmine Variant\", \"#FFAD4B53\": \"Carmine Carnation\", \"#FFE35B8F\": \"Carmine Rose\", \"#FFB31C45\": \"Carmoisine\", \"#FF5B3A24\": \"Carnaby Tan Variant\", \"#FF940008\": \"Carnage Red\", \"#FFBB8866\": \"Carnal Brown\", \"#FFEF9CB5\": \"Carnal Pink\", \"#FFFD798F\": \"Carnation Variant\", \"#FFF9C0BE\": \"Carnation Bloom\", \"#FFF5C0D0\": \"Carnation Bouquet\", \"#FFEDB9AD\": \"Carnation Coral\", \"#FF915870\": \"Carnation Festival\", \"#FFCE94C2\": \"Carnation Rose\", \"#FFEB882C\": \"Carnival\", \"#FF98BEB5\": \"Carnival Glass\", \"#FF006E7A\": \"Carnival Night\", \"#FF991111\": \"Carnivore\", \"#FFFFCAC3\": \"Caro\", \"#FF885C4E\": \"Carob Brown\", \"#FF5A484B\": \"Carob Chip\", \"#FF338DAE\": \"Carol\", \"#FF77A135\": \"Carol\\u2019s Purr\", \"#FFCBEFCB\": \"Carolina\", \"#FF8AB8FE\": \"Carolina Blue Variant\", \"#FF008B6D\": \"Carolina Green\", \"#FFD8DF80\": \"Carolina Parakeet\", \"#FFFF1500\": \"Carolina Reaper\", \"#FFFFB850\": \"Carolling Candlelight\", \"#FFFBA52E\": \"Carona\", \"#FFFDB793\": \"Carotene\", \"#FFF8DBE0\": \"Carousel Pink Variant\", \"#FFDEE3C0\": \"Carpathian Dawn\", \"#FF905755\": \"Carpe Diem\", \"#FF00AA33\": \"Carpet Moss\", \"#FF905D36\": \"Carrageen Moss\", \"#FFEEEBE4\": \"Carrara\", \"#FFE8E7D7\": \"Carrara Marble\", \"#FF6C6358\": \"Carriage\", \"#FF958D79\": \"Carriage Door\", \"#FF254D48\": \"Carriage Green\", \"#FF8C403D\": \"Carriage Red\", \"#FF8A8DC4\": \"Carriage Ride\", \"#FF7E7265\": \"Carriage Stone\", \"#FF5D6367\": \"Carriage Wheel\", \"#FFFFB756\": \"Carriage Yellow\", \"#FF889398\": \"Carrier Pigeon Blue\", \"#FFA82A70\": \"Carroburg Crimson\", \"#FFFD6F3B\": \"Carrot\", \"#FFBF6F31\": \"Carrot Cake\", \"#FFFE7A04\": \"Carrot Curl\", \"#FFCBD3C1\": \"Carrot Flower\", \"#FFFC5A1F\": \"Carrot Lava\", \"#FFDF7836\": \"Carrot Stick\", \"#FFEEEEFF\": \"Carte Blanche\", \"#FF405978\": \"Carter\\u2019s Scroll\", \"#FFBB9E7E\": \"Carton\", \"#FFD01722\": \"Cartoon Violence\", \"#FF665537\": \"Cartwheel\", \"#FF937A62\": \"Carved Wood\", \"#FFF0C39F\": \"Carving Party\", \"#FFCF6837\": \"Casa de Oro\", \"#FFCACFE6\": \"Casa del Mar\", \"#FFC49CA5\": \"Casa Talec\", \"#FFABB790\": \"Casa Verde\", \"#FFF0B253\": \"Casablanca Variant\", \"#FF3F545A\": \"Casal Variant\", \"#FFFECE5A\": \"Casandora Yellow\", \"#FF7C4549\": \"Casandra\", \"#FFD4EDE6\": \"Cascade Variant\", \"#FFE7DBCA\": \"Cascade Beige\", \"#FFA1C2B9\": \"Cascade Green\", \"#FF697F8E\": \"Cascade Tour\", \"#FF234893\": \"Cascade Twilight\", \"#FFECF2EC\": \"Cascade White\", \"#FFF7F5F6\": \"Cascading White\", \"#FFEE4433\": \"Cascara\", \"#FFA47149\": \"Cashew\", \"#FFFCF9BD\": \"Cashew Cheese\", \"#FFEDCCB3\": \"Cashew Nut\", \"#FFD1B399\": \"Cashmere Variant\", \"#FFA5B8D0\": \"Cashmere Blue\", \"#FFCDA291\": \"Cashmere Clay\", \"#FFCB8097\": \"Cashmere Rose\", \"#FFFEF2D2\": \"Cashmere Sweater\", \"#FFD6B484\": \"Cashmere Wrap\", \"#FFF9F2B3\": \"Casino Lights\", \"#FFA49186\": \"Casket\", \"#FFAAB5B8\": \"Casper Variant\", \"#FF4F6F91\": \"Caspian Sea\", \"#FFAEC7DB\": \"Caspian Tide\", \"#FFBB7700\": \"Cassandra\\u2019s Curse\", \"#FFE7C084\": \"Cassava Cake\", \"#FFE0CDDA\": \"Cassia Buds\", \"#FFAED0C9\": \"Cassiopeia\", \"#FF623C1F\": \"Cassiterite Brown\", \"#FF64645A\": \"Cast Iron\", \"#FF6DBAC0\": \"Castaway\", \"#FFD0C19F\": \"Castaway Beach\", \"#FF7A9291\": \"Castaway Cove\", \"#FF607374\": \"Castaway Lagoon\", \"#FFCFAF83\": \"Castell Harlech\", \"#FF455440\": \"Castellan Green\", \"#FFA27040\": \"Castellina\", \"#FF677727\": \"Castelvetrano Olive\", \"#FFFFFFE8\": \"Caster Sugar\", \"#FFD4B3AA\": \"Castilian Pink\", \"#FF4586C7\": \"Casting Sea\", \"#FF9DA7A0\": \"Casting Shadow\", \"#FFE0D5CA\": \"Castle Beige\", \"#FF95827B\": \"Castle Hill\", \"#FFEFDCCA\": \"Castle in the Clouds\", \"#FFD1EAED\": \"Castle in the Sky\", \"#FFBDAEB7\": \"Castle Mist\", \"#FF8B6B47\": \"Castle Moat\", \"#FFC5BAAA\": \"Castle Path\", \"#FFEADEC7\": \"Castle Ridge\", \"#FF525746\": \"Castle Stone\", \"#FFC2BBA2\": \"Castle Wall\", \"#FFA0A5A5\": \"Castlegate\", \"#FF5F5E62\": \"Castlerock\", \"#FF00564F\": \"Castleton Green\", \"#FFA80020\": \"Castlevania Heart\", \"#FF676A64\": \"Castor Grey\", \"#FF44232F\": \"Castro Variant\", \"#FF498090\": \"Casual Blue\", \"#FF95BAC2\": \"Casual Day\", \"#FFDFD5C8\": \"Casual Elegance\", \"#FFA09D98\": \"Casual Grey\", \"#FFD3C5AF\": \"Casual Khaki\", \"#FF8FABD6\": \"Casual Water\", \"#FFECBAC0\": \"Cat Nose\", \"#FF636D70\": \"Cat Person\", \"#FFCDDFBB\": \"Cat Woman\", \"#FFE7E7E3\": \"Cat\\u2019s Cream\", \"#FFD6A75D\": \"Cat\\u2019s Eye Marble\", \"#FF0071A0\": \"Cat\\u2019s Purr\", \"#FF475742\": \"Catachan Green\", \"#FFE2DCCC\": \"Catacomb Bone\", \"#FFDBD7D0\": \"Catacomb Walls\", \"#FF429395\": \"Catalan\", \"#FF72A49F\": \"Catalina\", \"#FF5C7884\": \"Catalina Coast\", \"#FF859475\": \"Catalina Green\", \"#FFEFAC73\": \"Catalina Tile\", \"#FFC5D0D5\": \"Catalyst Grey\", \"#FF90C4B4\": \"Catarina Green\", \"#FF634049\": \"Catawba Grape\", \"#FF6C685E\": \"Catch of the Day\", \"#FFB5DCD8\": \"Catch the Wave\", \"#FF66A545\": \"Caterpillar\", \"#FF657D82\": \"Catfish\", \"#FF9D632D\": \"Cathay Spice\", \"#FFACAAA7\": \"Cathedral\", \"#FF7A999C\": \"Cathedral Glass\", \"#FFABA9A7\": \"Cathedral Grey\", \"#FF80796E\": \"Cathedral Stone\", \"#FF015158\": \"Cathedral View\", \"#FF00FF55\": \"Cathode Green\", \"#FFCCA800\": \"Catkin Yellow\", \"#FF9E4D28\": \"Catlinite\", \"#FFC9A8CE\": \"Catmint\", \"#FF80AA95\": \"Catnip\", \"#FF6F6066\": \"Catnip Wood\", \"#FF8EA5B6\": \"Cats and Dogs\", \"#FF595452\": \"Catskill Brown\", \"#FFE0E4DC\": \"Catskill White Variant\", \"#FF917546\": \"Cattail Brown\", \"#FFB64925\": \"Cattail Red\", \"#FFBB7B51\": \"Cattle Drive\", \"#FF4A4649\": \"Catwalk\", \"#FFBE4236\": \"Caught Red-Handed\", \"#FF599C99\": \"Caulerpa Lentillifera\", \"#FFEBE5D0\": \"Cauliflower\", \"#FFF2E4C7\": \"Cauliflower Cream\", \"#FF6F788F\": \"Causeway\", \"#FF11DD00\": \"Caustic Green\", \"#FFD5DDE5\": \"Cautious Blue\", \"#FFDFD8D9\": \"Cautious Grey\", \"#FFDAE4DE\": \"Cautious Jade\", \"#FF3F4C5A\": \"Cavalry\", \"#FF990003\": \"Cavalry Brown\", \"#FFDCE2CE\": \"Cavan\", \"#FF52B7C6\": \"Cave Lake\", \"#FF86736E\": \"Cave of the Winds\", \"#FFAA1100\": \"Cave Painting\", \"#FFD6E5E2\": \"Cave Pearl\", \"#FF625C58\": \"Caveman\", \"#FFFED200\": \"Cavendish\", \"#FFA08D7A\": \"Cavern\", \"#FFB69981\": \"Cavern Clay\", \"#FFCEC3B3\": \"Cavern Echo\", \"#FF92987D\": \"Cavern Moss\", \"#FFE0B8B1\": \"Cavern Pink Variant\", \"#FF947054\": \"Cavern Sand\", \"#FF515252\": \"Cavernous\", \"#FF2B2C30\": \"Caviar\", \"#FF533E39\": \"Caviar Black\", \"#FF772244\": \"Caviar Couture\", \"#FF72939E\": \"Cavolo Nero\", \"#FFA6D0D6\": \"Cay\", \"#FF941100\": \"Cayenne\", \"#FF52798D\": \"Cayman Bay\", \"#FF495A44\": \"Cayman Green\", \"#FF9271A7\": \"Ce Soir\", \"#FF463430\": \"Cedar Variant\", \"#FF788078\": \"Cedar Forest\", \"#FF686647\": \"Cedar Glen\", \"#FF69743E\": \"Cedar Green\", \"#FFBF6955\": \"Cedar Grove\", \"#FFB7BCAD\": \"Cedar Mill\", \"#FF8B786F\": \"Cedar Plank\", \"#FFA96A50\": \"Cedar Plank Salmon\", \"#FF9B6663\": \"Cedar Ridge\", \"#FF91493E\": \"Cedar Staff\", \"#FFA97367\": \"Cedar Wood\", \"#FFDDA896\": \"Cedarville\", \"#FFE9EBE7\": \"Ceiling Bright White\", \"#FFCCD4CB\": \"Celadon Glaze\", \"#FF2F847C\": \"Celadon Green\", \"#FF7EBEA5\": \"Celadon Porcelain\", \"#FFB1DAC6\": \"Celadon Sorbet\", \"#FFC6CAB8\": \"Celadon Tint\", \"#FFEBE667\": \"Celandine\", \"#FFB8BFAF\": \"Celandine Green\", \"#FF9D86AD\": \"Celeb City\", \"#FFE6C17A\": \"Celebration\", \"#FF008BC4\": \"Celebration Blue\", \"#FFB4C04C\": \"Celery Variant\", \"#FFD4E0B3\": \"Celery Bunch\", \"#FFC5CC7B\": \"Celery Green\", \"#FFE1D792\": \"Celery Heart\", \"#FFEAEBD1\": \"Celery Ice\", \"#FFC1FD95\": \"Celery Mousse\", \"#FFC5BDA5\": \"Celery Powder\", \"#FFD4E4BA\": \"Celery Root\", \"#FFD0D8BE\": \"Celery Satin\", \"#FFE1DF9A\": \"Celery Sceptre\", \"#FF9ED686\": \"Celery Sprig\", \"#FFCAEDD0\": \"Celery Stick\", \"#FFCCEEC2\": \"Celery Victor\", \"#FFDBD9CD\": \"Celery White\", \"#FF406374\": \"Celeste Blue\", \"#FF007894\": \"Celestial\", \"#FF11CC00\": \"Celestial Alien\", \"#FF2C4D69\": \"Celestial Blue Variant\", \"#FF0A2538\": \"Celestial Canvas\", \"#FFDAEAF6\": \"Celestial Cathedral\", \"#FFDD4455\": \"Celestial Coral\", \"#FFEAD97C\": \"Celestial Crown\", \"#FF992266\": \"Celestial Dragon\", \"#FFEAEBE9\": \"Celestial Glow\", \"#FF2DDFC1\": \"Celestial Green\", \"#FF7C94B3\": \"Celestial Horizon\", \"#FF091F92\": \"Celestial Indigo\", \"#FFC7DAE8\": \"Celestial Light\", \"#FFE3D4B9\": \"Celestial Moon\", \"#FF9C004A\": \"Celestial Pink\", \"#FF3C7AC2\": \"Celestial Plum\", \"#FF85C1C4\": \"Celestine\", \"#FF24A4C8\": \"Celestine Spring\", \"#FF99A7AB\": \"Celestra Grey\", \"#FFB5C7D2\": \"Celestyn\", \"#FF826167\": \"Celine\", \"#FF75553F\": \"Cellar Door\", \"#FFDDB582\": \"Cellini Gold\", \"#FF3A4E5F\": \"Cello Variant\", \"#FF515153\": \"Celluloid\", \"#FFE76A35\": \"Celosia Orange\", \"#FF2B3F36\": \"Celtic Variant\", \"#FF246BCE\": \"Celtic Blue\", \"#FF006940\": \"Celtic Clover\", \"#FF1F6954\": \"Celtic Green\", \"#FFC5D4CE\": \"Celtic Grey\", \"#FFF5E5CE\": \"Celtic Linen\", \"#FF00886B\": \"Celtic Queen\", \"#FF2E4C5B\": \"Celtic Rush\", \"#FFAADEB2\": \"Celtic Spring\", \"#FF8BAB68\": \"Celuce\", \"#FF725671\": \"Cembra Blossom\", \"#FFA5A391\": \"Cement Variant\", \"#FF7B737B\": \"Cement Feet\", \"#FFB5ABA4\": \"Cement Greige\", \"#FFC0C7D0\": \"Cemetery Ash\", \"#FF3E7FA5\": \"Cendre Blue\", \"#FF327A68\": \"Census\", \"#FF90673F\": \"Centaur\", \"#FF8B6A4F\": \"Centaur Brown\", \"#FFB3A7A6\": \"Centennial Rose\", \"#FFF7E077\": \"Cente\\u014dtl Yellow\", \"#FF008B56\": \"Center Field\", \"#FF6D2400\": \"Centipede Brown\", \"#FFC08F45\": \"Centra\", \"#FF685549\": \"Centre Earth\", \"#FF817A69\": \"Centre Ridge\", \"#FFC8C7CB\": \"Centre Stage\", \"#FF9C7B87\": \"Century\\u2019s Last Sunset\", \"#FFEDD1AC\": \"Ceramic Beige\", \"#FF16A29A\": \"Ceramic Blue Turquoise\", \"#FFA05843\": \"Ceramic Brown\", \"#FFE8A784\": \"Ceramic Glaze\", \"#FF3BB773\": \"Ceramic Green\", \"#FF908268\": \"Ceramic Pot\", \"#FFFEFEE0\": \"Ceramite White\", \"#FFEFD7AB\": \"Cereal Flake\", \"#FFCCCBCD\": \"Cerebellum Grey\", \"#FFCCCCCC\": \"Cerebral Grey\", \"#FFD69E59\": \"Ceremonial Gold\", \"#FF91998E\": \"Ceremonial Grey\", \"#FFC38B82\": \"Ceremonial Ochre\", \"#FF2A2756\": \"Ceremonial Purple\", \"#FF997B00\": \"Cerignola Olive\", \"#FFAD134E\": \"Cerise Variant\", \"#FFF2BDA2\": \"Certain Peach\", \"#FF55AAEE\": \"Cerulean Variant\", \"#FF8CC6CB\": \"Cerulean Skies\", \"#FFACBFCD\": \"Cerulean Tint\", \"#FF337EFF\": \"Ceruleite\", \"#FF001440\": \"Cetacean Blue\", \"#FF33431E\": \"Ceylanite\", \"#FFF3E9D6\": \"Ceylon Cream\", \"#FFD4AE40\": \"Ceylon Yellow\", \"#FF756858\": \"Ceylonese\", \"#FF007AA5\": \"CG Blue\", \"#FFE03C31\": \"CG Red\", \"#FF56FFFF\": \"CGA Blue\", \"#FF77926F\": \"Ch\\u00e1 L\\u01dc Green\", \"#FFFFDB92\": \"Cha-Cha-Cha\", \"#FFEC7D2C\": \"Chaat Masala\", \"#FFFDE9E0\": \"Chablis Variant\", \"#FFF6E0CF\": \"Chafed Wheat\", \"#FF008B62\": \"Chagall Green\", \"#FFEBCFAE\": \"Chai\", \"#FFF9CBA0\": \"Chai Latte\", \"#FFBD7C4F\": \"Chai Spice\", \"#FFA97B2D\": \"Chai Tea\", \"#FFEFD7B3\": \"Chai Tea Latte\", \"#FF847E78\": \"Chain Link\", \"#FF81777F\": \"Chain Mail\", \"#FFA4A6A4\": \"Chain Reaction\", \"#FFC1B2B3\": \"Chaise Mauve\", \"#FF8B5E8F\": \"Chakra\", \"#FFDDDD99\": \"Chalcedony\", \"#FF4B6057\": \"Chalcedony Green\", \"#FF6770AE\": \"Chalcedony Violet\", \"#FFC29867\": \"Chalet\", \"#FF5A6E41\": \"Chalet Green Variant\", \"#FFEDEAE5\": \"Chalk\", \"#FFEAEBE6\": \"Chalk Dust\", \"#FFE0CEB7\": \"Chalkware\", \"#FFDFC281\": \"Chalky Variant\", \"#FFD0EBF1\": \"Chalky Blue White\", \"#FFCD7A50\": \"Challah Bread\", \"#FF475877\": \"Chambray Variant\", \"#FF93AECE\": \"Chambray Blue\", \"#FFCEDAAC\": \"Chameleon\", \"#FFC0C2A0\": \"Chameleon Tango\", \"#FFE8CD9A\": \"Chamois Variant\", \"#FFF0E1D0\": \"Chamois Cloth\", \"#FFAD8867\": \"Chamois Leather\", \"#FFB3A385\": \"Chamois Tan\", \"#FF986E19\": \"Chamois Yellow\", \"#FFE4C697\": \"Chamomile\", \"#FFDAC395\": \"Chamomile Tea\", \"#FFE9D2AC\": \"Champagne Tint\", \"#FFD4C49E\": \"Champagne Beige\", \"#FFF0E1C5\": \"Champagne Bliss\", \"#FFDDCEAD\": \"Champagne Bubbles\", \"#FFF1E4CB\": \"Champagne Burst\", \"#FFE3D7AE\": \"Champagne Cocktail\", \"#FFEBD3E4\": \"Champagne Elegance\", \"#FFF6ECE2\": \"Champagne Flute\", \"#FFD7C1B4\": \"Champagne Glee\", \"#FFE8D6B3\": \"Champagne Gold\", \"#FFC5B067\": \"Champagne Grape\", \"#FFF3E5DD\": \"Champagne Ice\", \"#FFFFDFB0\": \"Champagne Orange\", \"#FFFADDC4\": \"Champagne Peach\", \"#FFE3D6CC\": \"Champagne Rose\", \"#FFF8EEC4\": \"Champagne Tickle\", \"#FFF4E1C6\": \"Champagne Toast\", \"#FFEFD4AE\": \"Champagne Wishes\", \"#FF949089\": \"Champignon\", \"#FF7B5986\": \"Champion\", \"#FF606788\": \"Champion Blue\", \"#FF435572\": \"Champlain Blue\", \"#FFA0A6A9\": \"Chance of Rain\", \"#FFA5BCBA\": \"Chance of Showers\", \"#FFECBA5D\": \"Chandra Cream\", \"#FFF4AFCD\": \"Changeling Pink\", \"#FFB6927C\": \"Changing Seasons\", \"#FFF1C3C2\": \"Channel\", \"#FF04D8B2\": \"Channel Marker Green\", \"#FFA0928D\": \"Channel Seal Grey\", \"#FFEEE8D2\": \"Chanoyu\", \"#FFFFC66E\": \"Chanterelle\", \"#FFA28776\": \"Chanterelle Sauce\", \"#FF870000\": \"Chanticleer\", \"#FFEDB8C7\": \"Chantilly Variant\", \"#FFF1E2DE\": \"Chantilly Lace\", \"#FF740600\": \"Chaotic Red\", \"#FFBB2266\": \"Chaotic Roses\", \"#FFE5D0B0\": \"Chaparral\", \"#FFDEE5EC\": \"Chapeau Violet\", \"#FFB0D2E7\": \"Chapel Blue\", \"#FFBBD1E2\": \"Chapel Choir\", \"#FFEDE2AC\": \"Chapel Wall\", \"#FF644B41\": \"Chaps\", \"#FF9F9369\": \"Chapter\", \"#FFB79779\": \"Char Latte\", \"#FF394043\": \"Charade Variant\", \"#FF504D4C\": \"Charadon Granite\", \"#FF343837\": \"Charcoal Tint\", \"#FF5D625C\": \"Charcoal Briquette\", \"#FF595758\": \"Charcoal Dust\", \"#FF5D5B56\": \"Charcoal Sketch\", \"#FF474F43\": \"Charcoal Smoke\", \"#FF60605E\": \"Charcoal Smudge\", \"#FF949D8D\": \"Charcoal Tint\", \"#FF48553F\": \"Chard\", \"#FFF8EADF\": \"Chardon Variant\", \"#FFEFE8BC\": \"Chardonnay Variant\", \"#FF632A60\": \"Charisma\", \"#FFE7C180\": \"Charismatic\", \"#FFEE2244\": \"Charismatic Red\", \"#FF9AC1DC\": \"Charismatic Sky\", \"#FF9F414B\": \"Charleston Cherry\", \"#FFC09278\": \"Charleston Chocolate\", \"#FF232B2B\": \"Charleston Green\", \"#FF995500\": \"Charlie Brown\", \"#FF948263\": \"Charlie Horse\", \"#FFE2E483\": \"Charlock\", \"#FFA4DCE6\": \"Charlotte Variant\", \"#FFD0748B\": \"Charm Variant\", \"#FFEBCFC7\": \"Charmed\", \"#FFA1A1A0\": \"Charmed Chalice\", \"#FF007F3A\": \"Charmed Green\", \"#FFFF90A2\": \"Charming Cherry\", \"#FFD4E092\": \"Charming Green\", \"#FF11BB44\": \"Charming Nature\", \"#FFF5AD75\": \"Charming Peach\", \"#FFEDD3D2\": \"Charming Pink\", \"#FF8C7281\": \"Charming Violet\", \"#FF6A577F\": \"Charoite Violet\", \"#FFF1EBEA\": \"Charolais Cattle\", \"#FFA1A29C\": \"Charon\", \"#FF3E0007\": \"Charred Brown\", \"#FF553B3D\": \"Charred Chocolate\", \"#FF885132\": \"Charred Clay\", \"#FF5B4E4A\": \"Charred Hickory\", \"#FFC01205\": \"Charsiu\", \"#FFB2CCE1\": \"Charted\", \"#FF69B2CF\": \"Charter\", \"#FF546E91\": \"Charter Blue\", \"#FFC1F80A\": \"Chartreuse Variant\", \"#FFE4DCC6\": \"Chartreuse Frost\", \"#FFDAD000\": \"Chartreuse Shot\", \"#FFB5CC18\": \"Chartreuse Spark\", \"#FF16A3CB\": \"Charybdis\", \"#FF876044\": \"Chasm\", \"#FF63B521\": \"Chasm Green\", \"#FF9944EE\": \"Chaste Blossoms\", \"#FFF79A3E\": \"Chat Orange\", \"#FFB5A28A\": \"Chateau\", \"#FF5B4B44\": \"Chateau Brown\", \"#FF419F59\": \"Chateau Green Variant\", \"#FF7C583A\": \"Ch\\u00e2teau Mantle\", \"#FFDBA3CE\": \"Chateau Rose\", \"#FFB3ABB6\": \"Chatelle Variant\", \"#FF2C5971\": \"Chathams Blue Variant\", \"#FFB0AB9C\": \"Chatroom\", \"#FF89B386\": \"Chatty Cricket\", \"#FFA09287\": \"Chatura Beige\", \"#FFC7E2C6\": \"Chayote\", \"#FFED214D\": \"Che Guevara Red\", \"#FFEEB15D\": \"Cheater\", \"#FFEE9A09\": \"Cheddar\", \"#FFD2AD87\": \"Cheddar Biscuit\", \"#FFF0843A\": \"Cheddar Cheese\", \"#FFF9C982\": \"Cheddar Chunk\", \"#FFF5D4B5\": \"Cheddar Corn\", \"#FFB67DAF\": \"Cheddar Pink Mauve\", \"#FFA55A55\": \"Cheek Red\", \"#FF7B4D3A\": \"Cheeky Chestnut\", \"#FFDCC7C0\": \"Cheerful Heart\", \"#FFFFE195\": \"Cheerful Hue\", \"#FFFDA471\": \"Cheerful Tangerine\", \"#FFD3D7E7\": \"Cheerful Whisper\", \"#FF7E4258\": \"Cheerful Wine\", \"#FFFFC723\": \"Cheerful Yellow\", \"#FFBCCB08\": \"Cheerly Kiwi\", \"#FFC09962\": \"Cheers!\", \"#FFF08A88\": \"Cheery\", \"#FFFFA600\": \"Cheese\", \"#FFFDDE45\": \"Cheese It Up\", \"#FFFF9613\": \"Cheese Please\", \"#FFFFE4BE\": \"Cheese Powder\", \"#FFFFB96F\": \"Cheese Puff\", \"#FFDFAD51\": \"Cheese Wiz\", \"#FFFFFCDA\": \"Cheesecake\", \"#FFFFCC77\": \"Cheesus\", \"#FFEEB033\": \"Cheesy Cheetah\", \"#FFF0E093\": \"Cheesy Frittata\", \"#FFFAE195\": \"Cheesy Grin\", \"#FFF3F4F5\": \"Chef\\u2019s Hat\", \"#FFCC3B3B\": \"Chef\\u2019s Kiss\", \"#FFA3D1E8\": \"Chefchaouen Blue\", \"#FF88A95B\": \"Chelsea Cucumber Variant\", \"#FF546D66\": \"Chelsea Garden\", \"#FF95532F\": \"Chelsea Gem Variant\", \"#FFB6B7B0\": \"Chelsea Grey\", \"#FFBEAC9F\": \"Chelsea Mauve\", \"#FFF94009\": \"Ch\\u00e9ng H\\u00f3ng S\\u00e8 Orange\", \"#FFA6CD91\": \"Chenille\", \"#FFF1E7D6\": \"Chenille Spread\", \"#FFF9EFE2\": \"Chenille White\", \"#FFDEC371\": \"Chenin Variant\", \"#FF22BBFF\": \"Cherenkov Radiation\", \"#FFF4E3CB\": \"Cherish Cream\", \"#FFE6E4DA\": \"Cherish Is the Word\", \"#FFCCACD7\": \"Cherish the Moment\", \"#FFBA97B1\": \"Cherished\", \"#FFFC9293\": \"Cherished One\", \"#FFAC0132\": \"Chernobog\", \"#FFE3DCDA\": \"Chernobog Breath\", \"#FFF5CD82\": \"Cherokee Variant\", \"#FFDD7722\": \"Cherokee Dignity\", \"#FF824E4A\": \"Cherokee Red\", \"#FFA22452\": \"Cherries Jubilee\", \"#FFCF0234\": \"Cherry\", \"#FF908279\": \"Cherry Bark\", \"#FF9F4D65\": \"Cherry Berry\", \"#FFAD5344\": \"Cherry Blink\", \"#FFF5C1D5\": \"Cherry Blossom\", \"#FFFFC9DD\": \"Cherry Blush\", \"#FFB73D3F\": \"Cherry Bomb\", \"#FFE26B81\": \"Cherry Brandy\", \"#FFFFBBB4\": \"Cherry Chip\", \"#FF883F41\": \"Cherry Cobbler\", \"#FF8E5E65\": \"Cherry Cocoa\", \"#FF894C3B\": \"Cherry Cola\", \"#FFEBBED3\": \"Cherry Cordial\", \"#FFC71414\": \"Cherry Crush\", \"#FFBD6973\": \"Cherry Fizz\", \"#FFFBDAE8\": \"Cherry Flower\", \"#FFF392A0\": \"Cherry Foam\", \"#FFCB6276\": \"Cherry Fruit\", \"#FFCC5160\": \"Cherry Hill\", \"#FFDD98A6\": \"Cherry Ice\", \"#FFBD9095\": \"Cherry Juice\", \"#FF6C2C45\": \"Cherry Juice Red\", \"#FFA32E39\": \"Cherry Kiss\", \"#FFB15E67\": \"Cherry Kisses\", \"#FFC8385A\": \"Cherry Lolly\", \"#FF6A332D\": \"Cherry Mahogany\", \"#FFA57C7A\": \"Cherry Mocha\", \"#FFAC495C\": \"Cherry on Top\", \"#FFFE314B\": \"Cherry Paddle Pop\", \"#FFF9E7F4\": \"Cherry Pearl\", \"#FF620B15\": \"Cherry Picking\", \"#FFBD2C22\": \"Cherry Pie Variant\", \"#FFC7607B\": \"Cherry Pink\", \"#FFA10047\": \"Cherry Plum\", \"#FFA64137\": \"Cherry Race\", \"#FFF7022A\": \"Cherry Red\", \"#FFC92435\": \"Cherry Sangria\", \"#FFD81D26\": \"Cherry Shine\", \"#FFFF0044\": \"Cherry Soda\", \"#FFE76178\": \"Cherry Static\", \"#FF933D3E\": \"Cherry Tart\", \"#FFB7938F\": \"Cherry Taupe\", \"#FFF2013F\": \"Cherry Tomato\", \"#FFDFB7B4\": \"Cherry Tree\", \"#FFE10646\": \"Cherry Velvet\", \"#FFB04556\": \"Cherry Wine\", \"#FFB22743\": \"Cherryade\", \"#FFF79890\": \"Cherrystone\", \"#FF848182\": \"Chert\", \"#FFF5D7DC\": \"Cherub Variant\", \"#FFFFE6F1\": \"Cherubic\", \"#FFABBD90\": \"Chervil Leaves\", \"#FFFFE9C5\": \"Chess Ivory\", \"#FF876B4B\": \"Chester Brown\", \"#FF742802\": \"Chestnut Tint\", \"#FF9A6844\": \"Chestnut Beach\", \"#FFC19C86\": \"Chestnut Bisque\", \"#FF6D1008\": \"Chestnut Brown\", \"#FFBCA486\": \"Chestnut Butter\", \"#FF8E5637\": \"Chestnut Chest\", \"#FFEBC795\": \"Chestnut Dressing\", \"#FF874E2D\": \"Chestnut Glaze\", \"#FFAB8508\": \"Chestnut Gold\", \"#FF2A4F21\": \"Chestnut Green\", \"#FF60281E\": \"Chestnut Leather\", \"#FF6D3C32\": \"Chestnut Peel\", \"#FF852E19\": \"Chestnut Plum\", \"#FF6C333F\": \"Chestnut Red\", \"#FFCD5252\": \"Chestnut Rose Variant\", \"#FF995D3B\": \"Chestnut Stallion\", \"#FFEAF1E6\": \"Chestnut White\", \"#FF516FA0\": \"Chesty Bond\", \"#FF666FB4\": \"Chetwode Blue Variant\", \"#FFF6F2E8\": \"Cheviot\", \"#FFE6B0AF\": \"Chewing Gum\", \"#FFE292B6\": \"Chewing Gum Pink\", \"#FF977043\": \"Chewy Caramel\", \"#FF9F918A\": \"Cheyenne Rock\", \"#FFD52B2D\": \"Chi-Gong\", \"#FFEEECB5\": \"Chia\", \"#FF734342\": \"Chianti\", \"#FFA4725A\": \"Chic Brick\", \"#FFD8EBD6\": \"Chic Green\", \"#FFCFCCC5\": \"Chic Grey\", \"#FFEDE1C8\": \"Chic Magnet\", \"#FFF0D1C8\": \"Chic Peach\", \"#FF7C9270\": \"Chic Shade\", \"#FFAA9788\": \"Chic Taupe\", \"#FF5B5D56\": \"Chicago Variant\", \"#FFB6DBE9\": \"Chicago Blue\", \"#FFCAC2BD\": \"Chicago Fog\", \"#FF96ADBA\": \"Chicago Skyline\", \"#FFE2C555\": \"Chicco d\\u2019Oro\", \"#FF7E6072\": \"Chicha Morada\", \"#FFBF7D80\": \"Chick Flick\", \"#FFFFCF65\": \"Chickadee\", \"#FFDD2222\": \"Chicken Comb\", \"#FFCC8822\": \"Chicken Masala\", \"#FFFBE98E\": \"Chickery Chick\", \"#FFEFE7DF\": \"Chickpea\", \"#FFD9DFE3\": \"Chickweed\", \"#FFD9EEB4\": \"Chicon\", \"#FFA78658\": \"Chicory\", \"#FF4D3730\": \"Chicory Coffee\", \"#FF66789A\": \"Chicory Flower\", \"#FFBBAB75\": \"Chicory Green\", \"#FF5F423F\": \"Chicory Root\", \"#FF6A5637\": \"Chieftain\", \"#FFF0F5BB\": \"Chiffon Variant\", \"#FFDBC963\": \"Chifle Yellow\", \"#FFEAE5C5\": \"Child of Heaven\", \"#FFF0F4F8\": \"Child of Light\", \"#FFC68D37\": \"Child of the Moon\", \"#FF220077\": \"Child of the Night\", \"#FFE7BCD4\": \"Child\\u2019s Play\", \"#FFE26D68\": \"Childhood Crush\", \"#FFA5A8D6\": \"Childish Wonder\", \"#FFE8C0CF\": \"Childlike\", \"#FFA1CED7\": \"Children\\u2019s Soft Blue\", \"#FFD05E34\": \"Chilean Fire Variant\", \"#FFF9F7DE\": \"Chilean Heath Variant\", \"#FFC9CBC1\": \"Chilean Sea Bass\", \"#FFD1D5E7\": \"Chill in the Air\", \"#FF256D8D\": \"Chill of the Night\", \"#FFEC4236\": \"Chilled Chilly\", \"#FFCBCDB2\": \"Chilled Cucumber\", \"#FFFFE696\": \"Chilled Lemonade\", \"#FFE4EFDE\": \"Chilled Mint\", \"#FF6D4052\": \"Chilled Wine\", \"#FFBE4B41\": \"Chilli\", \"#FF4B1C35\": \"Chilli Black Red\", \"#FFCC5544\": \"Chilli Cashew\", \"#FF985E2B\": \"Chilli Con Carne\", \"#FFE93A0E\": \"Chilli Crab\", \"#FFF0B692\": \"Chilli Dip\", \"#FF8D7040\": \"Chilli Green\", \"#FF9D453C\": \"Chilli Oil\", \"#FFAC1E3A\": \"Chilli Pepper\", \"#FFBC4E40\": \"Chilli Sauce\", \"#FFCA7C74\": \"Chilli Soda\", \"#FF8AAEC3\": \"Chilly Blue\", \"#FFFD9989\": \"Chilly Spice\", \"#FFE5F1ED\": \"Chilly White\", \"#FF74626D\": \"Chimaera\", \"#FFC89B75\": \"Chimaera Brown\", \"#FFB16355\": \"Chimayo Red\", \"#FFC7CA86\": \"Chimes\", \"#FF4A5257\": \"Chimney\", \"#FF3C4247\": \"Chimney Smoke\", \"#FF272F38\": \"Chimney Sweep\", \"#FFDD3355\": \"Chin-Chin Cherry\", \"#FF444C60\": \"China Aster\", \"#FF5A6C80\": \"China Blue\", \"#FF8A7054\": \"China Cinnamon\", \"#FF718B9A\": \"China Clay\", \"#FFF8F0E5\": \"China Cup\", \"#FFF3E4D5\": \"China Doll\", \"#FF3A6468\": \"China Green Blue\", \"#FFFBF3D3\": \"China Ivory Variant\", \"#FFBCC9C7\": \"China Light Green\", \"#FF3D5C77\": \"China Pattern\", \"#FFDF6EA1\": \"China Pink\", \"#FFAD2B10\": \"China Red\", \"#FFA8516E\": \"China Rose\", \"#FF034F7C\": \"China Seas\", \"#FFE3D1CC\": \"China Silk\", \"#FFEAE6D9\": \"China White\", \"#FF464960\": \"Chinaberry\", \"#FFD6C2D2\": \"Chinaberry Bloom\", \"#FF9C8E7B\": \"Chinchilla\", \"#FFD0BBA7\": \"Chinchilla Chenille\", \"#FF7F746E\": \"Chinchilla Grey\", \"#FF4D5AAF\": \"Chinese Bellflower\", \"#FF111100\": \"Chinese Black\", \"#FF365194\": \"Chinese Blue\", \"#FFCD8032\": \"Chinese Bronze\", \"#FFAB381F\": \"Chinese Brown\", \"#FFF1D7CB\": \"Chinese Cherry\", \"#FFCB5251\": \"Chinese Dragon\", \"#FF006967\": \"Chinese Garden\", \"#FFDDAA00\": \"Chinese Gold\", \"#FFD0DB61\": \"Chinese Green\", \"#FFEBDBCA\": \"Chinese Hamster\", \"#FFE09E87\": \"Chinese Ibis Brown\", \"#FF3F312B\": \"Chinese Ink\", \"#FFCBD1BA\": \"Chinese Jade\", \"#FF60C7C2\": \"Chinese Lacquer\", \"#FFF09056\": \"Chinese Lantern\", \"#FFCCD6B0\": \"Chinese Leaf\", \"#FFA4BE5C\": \"Chinese Money Plant\", \"#FFF37042\": \"Chinese Orange\", \"#FFDE70A1\": \"Chinese Pink\", \"#FF3A5F7D\": \"Chinese Porcelain\", \"#FF720B98\": \"Chinese Purple\", \"#FFCD071E\": \"Chinese Red\", \"#FFB94047\": \"Chinese Safflower\", \"#FFD8D3B2\": \"Chinese Silk\", \"#FFDDDCEF\": \"Chinese Silver\", \"#FFACAD98\": \"Chinese Tea Green\", \"#FF8FBFBD\": \"Chinese Tzu\", \"#FF92698F\": \"Chinese Violet\", \"#FFE2E5DE\": \"Chinese White\", \"#FFDBD2BB\": \"Chino Variant\", \"#FF7C8C87\": \"Chinois Green\", \"#FF9DD3A8\": \"Chinook Variant\", \"#FFC8987E\": \"Chinook Salmon\", \"#FF554747\": \"Chinotto\", \"#FFD5C7B9\": \"Chintz\", \"#FFECBCB6\": \"Chintz Rose\", \"#FFCFA14A\": \"Chipmunk\", \"#FFAA4433\": \"Chipolata\", \"#FF683E3B\": \"Chipotle Paste\", \"#FFDDD618\": \"Chips Provencale\", \"#FF026B67\": \"Chitin Green\", \"#FFAEB2C0\": \"Chivalrous\", \"#FFC7662A\": \"Chivalrous Fox\", \"#FF816558\": \"Chivalrous Walrus\", \"#FF5D99B1\": \"Chivalry\", \"#FFBF784E\": \"Chivalry Copper\", \"#FF4D5637\": \"Chive\", \"#FF4F3650\": \"Chive Bloom\", \"#FF86619F\": \"Chive Blossom\", \"#FFA193BF\": \"Chive Flower\", \"#FF56AE57\": \"Chlorella Green\", \"#FF93D8C2\": \"Chloride\", \"#FF5E8E82\": \"Chlorite\", \"#FF44891A\": \"Chlorophyll\", \"#FFB3D6C3\": \"Chlorophyll Cream\", \"#FF4AFF00\": \"Chlorophyll Green\", \"#FF75876E\": \"Chlorosis\", \"#FFB4835B\": \"Choco Biscuit\", \"#FF993311\": \"Choco Chic\", \"#FF63493E\": \"Choco Death\", \"#FF7D5F53\": \"Choco Loco\", \"#FFF9BC08\": \"Chocobo Feather\", \"#FF993300\": \"Chocoholic\", \"#FF773333\": \"Chocolate Bar\", \"#FF775130\": \"Chocolate Bells\", \"#FF782A2E\": \"Chocolate Bhut Jolokia\", \"#FF7F6054\": \"Chocolate Bliss\", \"#FF7E4F35\": \"Chocolate Bonbon\", \"#FF765841\": \"Chocolate Caliente\", \"#FF452207\": \"Chocolate Castle\", \"#FF8A4438\": \"Chocolate Cherry\", \"#FF928178\": \"Chocolate Chiffon\", \"#FFAB4231\": \"Chocolate Chilli\", \"#FF6E5F52\": \"Chocolate Chip\", \"#FF6B574A\": \"Chocolate Chunk\", \"#FF644D42\": \"Chocolate Coco\", \"#FF58111A\": \"Chocolate Cosmos\", \"#FF8B4121\": \"Chocolate Covered\", \"#FFA89581\": \"Chocolate Cream Pie\", \"#FF605647\": \"Chocolate Cupcake\", \"#FF916D5E\": \"Chocolate Curl\", \"#FF96786D\": \"Chocolate Delight\", \"#FF6B5947\": \"Chocolate Diamonds\", \"#FF674848\": \"Chocolate Eclair\", \"#FF623D2E\": \"Chocolate Escape\", \"#FF8E473B\": \"Chocolate Explosion\", \"#FF5C3612\": \"Chocolate Fantasies\", \"#FF603932\": \"Chocolate Fondant\", \"#FF9A3001\": \"Chocolate Fondue\", \"#FFDED5C8\": \"Chocolate Froth\", \"#FF8F786C\": \"Chocolate Heart\", \"#FF3C1421\": \"Chocolate Kiss\", \"#FF66433B\": \"Chocolate Lab\", \"#FF993322\": \"Chocolate Lust\", \"#FF7A463A\": \"Chocolate Magma\", \"#FF331100\": \"Chocolate Melange\", \"#FF976F4C\": \"Chocolate Milk\", \"#FF998069\": \"Chocolate Moment\", \"#FFB5A39C\": \"Chocolate Oatmeal\", \"#FFBB5544\": \"Chocolate Oatmeal Cookie\", \"#FF884400\": \"Chocolate Pancakes\", \"#FF3F2F31\": \"Chocolate Plum\", \"#FFA58C7B\": \"Chocolate Powder\", \"#FF66424D\": \"Chocolate Praline\", \"#FF60504B\": \"Chocolate Pretzel\", \"#FF6F6665\": \"Chocolate Pudding\", \"#FF714F29\": \"Chocolate Rain\", \"#FF4D3635\": \"Chocolate Red\", \"#FF76604E\": \"Chocolate Ripple\", \"#FF4E1B0B\": \"Chocolate Rush\", \"#FF5C4945\": \"Chocolate Soul\", \"#FF8C6C6F\": \"Chocolate Sparkle\", \"#FF6F4E43\": \"Chocolate Sprinkle\", \"#FF84563C\": \"Chocolate Stain\", \"#FF68574B\": \"Chocolate Swirl\", \"#FF956E5F\": \"Chocolate Temptation\", \"#FF5F4940\": \"Chocolate Therapy\", \"#FF403534\": \"Chocolate Torte\", \"#FF612E32\": \"Chocolate Truffle\", \"#FF7F7453\": \"Chocolate Velvet\", \"#FF937979\": \"Chocolaty\", \"#FFF2E1D1\": \"Choice Cream\", \"#FF8F583C\": \"Ch\\u014djicha Brown\", \"#FF867578\": \"Choo Choo\", \"#FFC7BCA1\": \"Chopped Almonds\", \"#FF336B4B\": \"Chopped Chive\", \"#FFB6C2A1\": \"Chopped Dill\", \"#FFE0D1B8\": \"Chopsticks\", \"#FFB77795\": \"Choral Singer\", \"#FFAA0011\": \"Chorizo\", \"#FF8E8987\": \"Chorus of Elephants\", \"#FF8C9632\": \"Chorus of Frogs\", \"#FFFF6301\": \"Chos Garden Marigold\", \"#FFB95754\": \"Ch\\u014dshun Red\", \"#FFEBCF7D\": \"Choux \\u00e0 la Cr\\u00e8me\", \"#FFE5D2B2\": \"Chowder Bowl\", \"#FF382161\": \"Christalle Variant\", \"#FF71A91D\": \"Christi Variant\", \"#FF009094\": \"Christina Brown\", \"#FF2A8FBD\": \"Christmas Blue\", \"#FF5D2B2C\": \"Christmas Brown\", \"#FFCAA906\": \"Christmas Gold\", \"#FF3C8D0D\": \"Christmas Green\", \"#FF68846A\": \"Christmas Holly\", \"#FF477266\": \"Christmas Ivy\", \"#FFD56C2B\": \"Christmas Orange\", \"#FF6E5A49\": \"Christmas Ornament\", \"#FFE34285\": \"Christmas Pink\", \"#FF564342\": \"Christmas Pudding\", \"#FF4D084B\": \"Christmas Purple\", \"#FFB01B2E\": \"Christmas Red\", \"#FFFFDDBB\": \"Christmas Rose\", \"#FFE1DFE0\": \"Christmas Silver\", \"#FFD4C5BA\": \"Christobel\", \"#FFF6BBCA\": \"Christy\\u2019s Smile\", \"#FF292929\": \"Chromaphobic Black\", \"#FFE1DFE1\": \"Chrome\", \"#FFA8A9AD\": \"Chrome Aluminium\", \"#FFCDC8D2\": \"Chrome Chalice\", \"#FFE7EDDD\": \"Chrome Green\", \"#FFCAC7B7\": \"Chrome White Variant\", \"#FF82CAFC\": \"Chromis Damsel Blue\", \"#FF06B48B\": \"Chromophobia Green\", \"#FF3E4265\": \"Chronicle\", \"#FF72A8D1\": \"Chronus Blue\", \"#FFC35458\": \"Chrysanthemum\", \"#FF9DB8AB\": \"Chrysanthemum Leaf\", \"#FF004F39\": \"Chrysocolla Dark Green\", \"#FF378661\": \"Chrysocolla Green\", \"#FF006B57\": \"Chrysocolla Medium Green\", \"#FF8E9849\": \"Chrysolite\", \"#FF39334A\": \"Chrysomela Goettingensis\", \"#FF8FB2A3\": \"Chrysopal Light Green\", \"#FF4A2200\": \"Chrysophobia\", \"#FFADBA98\": \"Chrysoprase\", \"#FF613521\": \"Chubby Chocolate\", \"#FFB43548\": \"Chubby Kiss\", \"#FFBF413A\": \"Chuckles\", \"#FF91C1C6\": \"Chuff Blue\", \"#FF1559DB\": \"Chun-Li Blue\", \"#FFFFC84B\": \"Chunky Bee\", \"#FFCFCDCF\": \"Chupacabra Grey\", \"#FF3D4161\": \"Church Blue\", \"#FFB3B5AF\": \"Church Mouse\", \"#FF4D4D58\": \"Churchill\", \"#FFA49A85\": \"Churchill Downs\", \"#FF9F5E4E\": \"Chutney\", \"#FFA97765\": \"Chutney Brown\", \"#FF0F0809\": \"Chyornyi Black\", \"#FFDE9D7C\": \"Ciao\", \"#FF938A43\": \"Cider Mill\", \"#FF8A946F\": \"Cider Pear Green\", \"#FFAE8167\": \"Cider Spice\", \"#FFB98033\": \"Cider Toddy\", \"#FFE7D6AF\": \"Cider Yellow\", \"#FFA5CEE8\": \"Cielo\", \"#FF7D4E38\": \"Cigar\", \"#FF9C7351\": \"Cigar Box\", \"#FF78857A\": \"Cigar Smoke\", \"#FFEE5500\": \"Cigarette Glow\", \"#FF4A5C52\": \"Cilantro\", \"#FFCECBAE\": \"Cilantro Cream\", \"#FF6B3D38\": \"Cimarron\", \"#FF242A2E\": \"Cinder Variant\", \"#FF7C787B\": \"Cinder Fox\", \"#FFFBD7CC\": \"Cinderella Variant\", \"#FFFFC6C4\": \"Cinderella Pink\", \"#FF95878E\": \"Cinema Screen\", \"#FF730113\": \"Cinnabar Variant\", \"#FF634D45\": \"Cinnabark\", \"#FFD26911\": \"Cinnamon Variant\", \"#FFCF8D6C\": \"Cinnamon Brandy\", \"#FF9E6A19\": \"Cinnamon Brown\", \"#FFFFBF6E\": \"Cinnamon Buff\", \"#FFAC4F06\": \"Cinnamon Bun\", \"#FFE8DDCF\": \"Cinnamon Cake\", \"#FFB15D63\": \"Cinnamon Candle\", \"#FF794344\": \"Cinnamon Cherry\", \"#FFD1A79C\": \"Cinnamon Cocoa\", \"#FF705742\": \"Cinnamon Crumble\", \"#FFA37D5A\": \"Cinnamon Crunch\", \"#FFA97673\": \"Cinnamon Diamonds\", \"#FFEDBC9B\": \"Cinnamon Foam\", \"#FFD3B191\": \"Cinnamon Frost\", \"#FFDBBBA7\": \"Cinnamon Ice\", \"#FFEBDAB5\": \"Cinnamon Milk\", \"#FFD5B199\": \"Cinnamon Mocha\", \"#FFBB9988\": \"Cinnamon Roast\", \"#FFC0737A\": \"Cinnamon Roll\", \"#FFC2612C\": \"Cinnamon Rufous\", \"#FFB78153\": \"Cinnamon Sand\", \"#FFBA9275\": \"Cinnamon Scone\", \"#FF9C5736\": \"Cinnamon Sparkle\", \"#FF935F43\": \"Cinnamon Spice\", \"#FFB05127\": \"Cinnamon Stick\", \"#FFC9543A\": \"Cinnamon Stone\", \"#FFB64C2D\": \"Cinnamon Sunset\", \"#FFDEC0AD\": \"Cinnamon Tea\", \"#FF8D7D77\": \"Cinnamon Toast\", \"#FF9F7250\": \"Cinnamon Twist\", \"#FFDAB2A4\": \"Cinnamon Whip\", \"#FFA6646F\": \"Cinnapink\", \"#FFFFFF88\": \"Cinque Foil\", \"#FF5D3B2E\": \"Cioccolato Variant\", \"#FFAA7691\": \"Cipher\", \"#FFC8CEC3\": \"Cipollino\", \"#FF6258C4\": \"Circumorbital Ring\", \"#FFFC5E30\": \"Circus\", \"#FFAD835C\": \"Circus Peanut\", \"#FF954A4C\": \"Circus Red\", \"#FFD6E4E1\": \"Cirrus Blue\", \"#FFA9B0B6\": \"Cistern\", \"#FF6A7F8B\": \"Citadel\", \"#FF9EABAD\": \"Citadel Blue\", \"#FFF6B906\": \"Citra\", \"#FF933709\": \"Citrine Brown\", \"#FFE9E89B\": \"Citrino\", \"#FFD5C757\": \"Citron Tint\", \"#FFDEFF00\": \"Citron Goby\", \"#FF66BB77\": \"Citronella\", \"#FFB8AF23\": \"Citronelle\", \"#FFC4AA27\": \"Citronette\", \"#FFDBB239\": \"Citronite\", \"#FFCD9C2B\": \"Citronne\", \"#FF9FB70A\": \"Citrus Variant\", \"#FFE1793A\": \"Citrus Blast\", \"#FFE4DE8E\": \"Citrus Butter\", \"#FFD0D557\": \"Citrus Delight\", \"#FFF9A78D\": \"Citrus Hill\", \"#FFF6B96B\": \"Citrus Honey\", \"#FFB3D157\": \"Citrus Leaf\", \"#FFC3DC68\": \"Citrus Lime\", \"#FFF7EDDE\": \"Citrus Mist\", \"#FFD26643\": \"Citrus Notes\", \"#FFB7BB6B\": \"Citrus Peel\", \"#FFFDEA83\": \"Citrus Punch\", \"#FFEDE0AE\": \"Citrus Rind\", \"#FFF2C6A7\": \"Citrus Sachet\", \"#FFE2CD52\": \"Citrus Spice\", \"#FFFFC400\": \"Citrus Splash\", \"#FFE6D943\": \"Citrus Sugar\", \"#FF8BC34A\": \"Citrus Surge\", \"#FFD7C275\": \"Citrus Yellow\", \"#FFEDC85A\": \"Citrus Zest\", \"#FF6E674B\": \"City Arboretum\", \"#FF675C49\": \"City Bench\", \"#FFE0E0DC\": \"City Brume\", \"#FFC0B9AC\": \"City Dweller\", \"#FF0022AA\": \"City Hunter Blue\", \"#FFDFE6EA\": \"City Lights\", \"#FFA79B8A\": \"City Loft\", \"#FFB3ADA4\": \"City of Bridges\", \"#FFFAE6CB\": \"City of Diamonds\", \"#FFE6B4A6\": \"City of Pink Angels\", \"#FF525C61\": \"City Rain\", \"#FF663333\": \"City Roast\", \"#FFD8D3C3\": \"City Steam\", \"#FF888C8C\": \"City Storm\", \"#FFBAB2AB\": \"City Street\", \"#FFD1A67D\": \"City Sunrise\", \"#FFAEABA5\": \"City Tower\", \"#FFDAE3E7\": \"Cityscape\", \"#FFC56138\": \"Civara\", \"#FFDBE9DF\": \"Clair de Lune\", \"#FF838493\": \"Clairvoyance\", \"#FFDAD1C0\": \"Clam\", \"#FFF4D9AF\": \"Clam Chowder\", \"#FFEBDBC1\": \"Clam Up\", \"#FFE0D1BB\": \"Clambake\", \"#FFEDD0B6\": \"Clamshell\", \"#FF680018\": \"Claret Variant\", \"#FFC84C61\": \"Claret Red\", \"#FFE69C23\": \"Clarified Butter\", \"#FFFEA15B\": \"Clarified Orange\", \"#FF002255\": \"Clarinet\", \"#FFEAF0E0\": \"Clarity\", \"#FF684976\": \"Clary\", \"#FFC7C0CE\": \"Clary Sage\", \"#FFBBAAA1\": \"Classic\", \"#FF6E7042\": \"Classic Avocado\", \"#FF7C5261\": \"Classic Berry\", \"#FF0F4E81\": \"Classic Blue\", \"#FFA38BBF\": \"Classic Bouquet\", \"#FF6D624E\": \"Classic Bronze\", \"#FF6A493D\": \"Classic Brown\", \"#FF6B8885\": \"Classic Calm\", \"#FFF4F4F0\": \"Classic Chalk\", \"#FF974146\": \"Classic Cherry\", \"#FF9197A3\": \"Classic Cloud\", \"#FFB7B2AC\": \"Classic Cool\", \"#FF7A9494\": \"Classic Damask\", \"#FF888782\": \"Classic French Grey\", \"#FFC9A367\": \"Classic Gold\", \"#FF3EB753\": \"Classic Green\", \"#FFA39D93\": \"Classic Grey\", \"#FFACACA7\": \"Classic Greyscale\", \"#FFF2E0C3\": \"Classic Ivory\", \"#FFDBC79F\": \"Classic Khaki\", \"#FFF0EADC\": \"Classic Light Buff\", \"#FF728284\": \"Classic Movie\", \"#FF685E3F\": \"Classic Olive\", \"#FFC52534\": \"Classic Red\", \"#FFD6BCAA\": \"Classic Sand\", \"#FFB9B9B4\": \"Classic Silver\", \"#FFD3BCA4\": \"Classic Taupe\", \"#FFE4CEAE\": \"Classic Terra\", \"#FF71588D\": \"Classic Waltz\", \"#FFEBB875\": \"Classical Gold\", \"#FF8B7989\": \"Classical Violet\", \"#FFECE1CB\": \"Classical White\", \"#FFF8D492\": \"Classical Yellow\", \"#FFAEACAD\": \"Classy\", \"#FFBB99AA\": \"Classy Mauve\", \"#FF887E82\": \"Classy Plum\", \"#FF911F21\": \"Classy Red\", \"#FFB66A50\": \"Clay\", \"#FFDACEBE\": \"Clay Angel\", \"#FFE1C68F\": \"Clay Bake\", \"#FF8A7D69\": \"Clay Bath\", \"#FFD5D1C3\": \"Clay Beige\", \"#FFA9765D\": \"Clay Court\", \"#FF897E59\": \"Clay Creek Variant\", \"#FFA48374\": \"Clay Dusk\", \"#FFF8DCA3\": \"Clay Dust\", \"#FFAF604D\": \"Clay Figure\", \"#FFC8C1B6\": \"Clay Figurine\", \"#FFD8A686\": \"Clay Fire\", \"#FFBD856C\": \"Clay Ground\", \"#FFA68779\": \"Clay Marble\", \"#FFD37959\": \"Clay Mug\", \"#FFAE895D\": \"Clay Ochre\", \"#FFBDB298\": \"Clay Pebble\", \"#FFD9C8B7\": \"Clay Pipe\", \"#FF774433\": \"Clay Play\", \"#FFC3663F\": \"Clay Pot\", \"#FF956A66\": \"Clay Ridge\", \"#FFCDCACE\": \"Clay Slate Wacke\", \"#FFD4823C\": \"Clay Terrace\", \"#FF83756C\": \"Clayton\", \"#FF969283\": \"Claytone\", \"#FFD8DDB6\": \"Clean Air\", \"#FFF6E9D3\": \"Clean Canvas\", \"#FF8FE0C6\": \"Clean Green\", \"#FF4EC0ED\": \"Clean Pool\", \"#FF577396\": \"Clean Slate\", \"#FFCCBCB0\": \"Clean Sweep\", \"#FFC4EAE0\": \"Clear Aqua\", \"#FF247AFD\": \"Clear Blue\", \"#FF60949B\": \"Clear Brook\", \"#FFF6E6E4\": \"Clear Calamine\", \"#FFDAE8E1\": \"Clear Camouflage Green\", \"#FFDFDBD8\": \"Clear Cinnamon\", \"#FFBAB6B2\": \"Clear Concrete\", \"#FF98CECD\": \"Clear Cove\", \"#FFDFEFEA\": \"Clear Day Variant\", \"#FF12732B\": \"Clear Green\", \"#FFA3BBDA\": \"Clear Lake Trail\", \"#FF766CB0\": \"Clear Mauve\", \"#FFFAF6EA\": \"Clear Moon\", \"#FF214F86\": \"Clear Night Sky\", \"#FFEE8800\": \"Clear Orange\", \"#FF64005E\": \"Clear Plum\", \"#FFB4CCCB\": \"Clear Pond\", \"#FF412A7A\": \"Clear Purple\", \"#FFCE261C\": \"Clear Red\", \"#FFEAE7DA\": \"Clear Sand\", \"#FFE8F7FD\": \"Clear Skies\", \"#FF8ECCFE\": \"Clear Sky\", \"#FFE0DDD3\": \"Clear Stone\", \"#FFCAD6DA\": \"Clear\", \"#FF008A81\": \"Clear Turquoise\", \"#FFE2EAE7\": \"Clear View\", \"#FFE7F0F7\": \"Clear Vision\", \"#FFA3BEC4\": \"Clear Vista\", \"#FFAAD5DB\": \"Clear Water\", \"#FF66BBDD\": \"Clear Weather\", \"#FFF1F1E6\": \"Clear Yellow\", \"#FFC4DBCB\": \"Clearly Aqua\", \"#FF7E6596\": \"Clematis\", \"#FF3C3D8A\": \"Clematis Blue\", \"#FF98B652\": \"Clematis Green\", \"#FFE05AEC\": \"Clematis Magenta\", \"#FFFF9D0A\": \"Clementine Earring\", \"#FFFFAD01\": \"Clementine Jelly\", \"#FF00507F\": \"Cleo\\u2019s Bath\", \"#FF007590\": \"Cleopatra\", \"#FF795088\": \"Cleopatra\\u2019s Gown\", \"#FFF4E6E0\": \"Clerestory\", \"#FFF6EBEE\": \"Clichy White\", \"#FF5D8FBD\": \"Cliff Blue\", \"#FFD0AB8C\": \"Cliff Brown\", \"#FFC5AE80\": \"Cliff Ridge\", \"#FFB19475\": \"Cliff Rock\", \"#FFECDDD4\": \"Cliff Swallow\", \"#FFDDC5AA\": \"Cliff\\u2019s View\", \"#FF6F8165\": \"Cliffside Park\", \"#FFE5E1CD\": \"Climate Change\", \"#FF466082\": \"Climate Control\", \"#FF58714A\": \"Climbing Ivy\", \"#FFB2CFD3\": \"Clinical Soft Blue\", \"#FF463623\": \"Clinker Variant\", \"#FF663145\": \"Clinker Red\", \"#FFA1B841\": \"Clipped Grass\", \"#FFA6937D\": \"Clippership Twill\", \"#FF550055\": \"Cloak and Dagger\", \"#FF605E63\": \"Cloak Grey\", \"#FF916660\": \"Cloak of Mystery\", \"#FF002211\": \"Clock Chimes Thirteen\", \"#FFE07630\": \"Clockwork Orange\", \"#FF72573D\": \"Clockworks\", \"#FF0773AF\": \"Cloisonn\\u00e9\", \"#FFA58235\": \"Cloisonn\\u00e9 Gold\", \"#FF99B090\": \"Cloistered Garden\", \"#FF5F6C84\": \"Clooney\", \"#FF361D0A\": \"Close but No Cigar\", \"#FFD5D6CF\": \"Close Knit\", \"#FF25252C\": \"Closed Shutter\", \"#FFE1DED9\": \"Closet Skeletons\", \"#FFF3EFCD\": \"Clotted Cream\", \"#FF991115\": \"Clotted Red\", \"#FFE4F0EF\": \"Cloud Variant\", \"#FFDFE7EB\": \"Cloud Abyss\", \"#FFF6F1FE\": \"Cloud Break\", \"#FFADB5BC\": \"Cloud Cover\", \"#FFF1EEE8\": \"Cloud Dancer\", \"#FFA4ABAB\": \"Cloud Mountain\", \"#FFF9CEC6\": \"Cloud Number Nine\", \"#FFF1E2C4\": \"Cloud of Cream\", \"#FFC2BCB1\": \"Cloud Over London\", \"#FFFAF9F8\": \"Cloud Petal\", \"#FFFFA168\": \"Cloudberry\", \"#FF7B7777\": \"Cloudburst\", \"#FF628468\": \"Clouded Pine\", \"#FF7D93A2\": \"Clouded Sky\", \"#FFD1D0D1\": \"Clouded Vision\", \"#FFD6EAFC\": \"Cloudless\", \"#FF9AB1BF\": \"Cloudless Day\", \"#FFD8D7D3\": \"Cloudy Variant\", \"#FFACC2D9\": \"Cloudy Blue\", \"#FF87715F\": \"Cloudy Cinnamon\", \"#FFDFE6DA\": \"Cloudy Day\", \"#FFB0A99F\": \"Cloudy Desert\", \"#FFECE3E1\": \"Cloudy Grey\", \"#FFE3BC6F\": \"Cloudy Honey\", \"#FF9D7AAC\": \"Cloudy Plum\", \"#FF6699AA\": \"Cloudy Sea\", \"#FFC2D5DA\": \"Cloudy Sky\", \"#FFE4BD76\": \"Cloudy Sunset\", \"#FFA6A096\": \"Cloudy Today\", \"#FFB1C6D6\": \"Cloudy Valley\", \"#FF4B5F56\": \"Cloudy Viridian\", \"#FF876155\": \"Clove\", \"#FF766051\": \"Clove Brown\", \"#FFC8805F\": \"Clove Bud\", \"#FFA96232\": \"Clove Dye\", \"#FF523F21\": \"Clove Yellow Brown\", \"#FFB0705D\": \"Clovedust\", \"#FF008F00\": \"Clover Variant\", \"#FF1C6A53\": \"Clover Brook\", \"#FF006C44\": \"Clover Green\", \"#FFF0E2BC\": \"Clover Honey\", \"#FF6FC288\": \"Clover Mist\", \"#FF4A9D5B\": \"Clover Patch\", \"#FFCD9BC4\": \"Clover Pink\", \"#FFC4D056\": \"Clown Green\", \"#FFE94257\": \"Clown Nose\", \"#FF8BC3E1\": \"Club Cruise\", \"#FF464159\": \"Club Grey\", \"#FF834370\": \"Club Mauve\", \"#FF6B977A\": \"Club Moss\", \"#FF3E4A54\": \"Club Navy\", \"#FFE2EDEB\": \"Club Soda\", \"#FF2B245A\": \"Cluedo Night\", \"#FFD3B683\": \"Clumsy Caramel\", \"#FFE8E2E0\": \"Clytemnestra\", \"#FF4978A9\": \"Co Pilot\", \"#FFCADFEC\": \"CO\\u2082\", \"#FF003527\": \"Coach Green\", \"#FF3B3B3D\": \"Coal Hard Truth\", \"#FF220033\": \"Coal Mine\", \"#FF777872\": \"Coal Miner\", \"#FF53555E\": \"Coal Tipple\", \"#FF181B26\": \"Coarse Wool\", \"#FFF6E6DB\": \"Coast Cream\", \"#FFBDD4D1\": \"Coast\", \"#FFF0EBD9\": \"Coastal Beige\", \"#FFE0F6FB\": \"Coastal Breeze\", \"#FF538F94\": \"Coastal Calm\", \"#FFB4C0AF\": \"Coastal Crush\", \"#FF727B76\": \"Coastal Dusk\", \"#FF505D7E\": \"Coastal Fjord\", \"#FFB0E5C9\": \"Coastal Foam\", \"#FFE5E8E4\": \"Coastal Fog\", \"#FF80B9C0\": \"Coastal Fringe\", \"#FF006E7F\": \"Coastal Jetty\", \"#FFD2E8EC\": \"Coastal Mist\", \"#FF9FA694\": \"Coastal Plain\", \"#FFC9A985\": \"Coastal Sand\", \"#FF9EA4A6\": \"Coastal Sea Fog\", \"#FF7D807B\": \"Coastal Storm\", \"#FF2D4982\": \"Coastal Surf\", \"#FFBDFFCA\": \"Coastal Trim\", \"#FF9E9486\": \"Coastal Villa\", \"#FF8293A0\": \"Coastal Vista\", \"#FF7DB7DB\": \"Coastal Waters\", \"#FF4398BC\": \"Coastline Blue\", \"#FF6E6C5B\": \"Coastline Trail\", \"#FF2E2F30\": \"Coated\", \"#FF030AA7\": \"Cobalt Variant\", \"#FF02367D\": \"Cobalt Blue Tarantula\", \"#FF4D585B\": \"Cobalt Cannon\", \"#FF4E719D\": \"Cobalt Flame\", \"#FF0072B5\": \"Cobalt Glaze\", \"#FF648FC4\": \"Cobalt Glow\", \"#FF94FF94\": \"Cobalt Green\", \"#FF353739\": \"Cobalt Night\", \"#FF0264AE\": \"Cobalt Stone\", \"#FF7A6455\": \"Cobble Brown\", \"#FFC4AB7D\": \"Cobbler\", \"#FFB2967E\": \"Cobbler Shop\", \"#FFA89A8E\": \"Cobblestone\", \"#FF9E8779\": \"Cobblestone Path\", \"#FFCFC7B9\": \"Cobblestone Street\", \"#FFB08E08\": \"Cobra Leather\", \"#FFB56D5D\": \"Cobrizo\", \"#FFBD9D95\": \"Coca Mocha\", \"#FFF8B862\": \"Cochin Chicken\", \"#FFDDCDB3\": \"Cochise\", \"#FFFF88BB\": \"Cochonnet\", \"#FF58C8B6\": \"Cockatoo\", \"#FFA46422\": \"Cockatrice Brown\", \"#FFE3C6AF\": \"Cockleshell\", \"#FFBC5378\": \"Cockscomb Red\", \"#FF5A7AA2\": \"Cocktail Blue\", \"#FF8EB826\": \"Cocktail Green\", \"#FFFD9A52\": \"Cocktail Hour\", \"#FF9FA36C\": \"Cocktail Olive\", \"#FFDCE2AD\": \"Cocktail Onion\", \"#FFD1BBA1\": \"Coco\", \"#FFE4DCC9\": \"Coco Malt\", \"#FF994A25\": \"Coco Muck\", \"#FF9B7757\": \"Coco Rum\", \"#FFEEDD88\": \"Coco-Lemon Tart\", \"#FF1C1C1A\": \"Coco\\u2019s Black\", \"#FF875F42\": \"Cocoa\", \"#FF4F3835\": \"Cocoa Bean Variant\", \"#FFA08882\": \"Cocoa Berry\", \"#FF35281E\": \"Cocoa Brown Variant\", \"#FFF5F4C1\": \"Cocoa Butter\", \"#FFB9A39A\": \"Cocoa Craving\", \"#FFDBC8B6\": \"Cocoa Cream\", \"#FF967859\": \"Cocoa Cupcake\", \"#FF8D725A\": \"Cocoa Delight\", \"#FFD0B7A4\": \"Cocoa Dust\", \"#FFC4AD96\": \"Cocoa Froth\", \"#FF7D675D\": \"Cocoa Milk\", \"#FFBC9F7E\": \"Cocoa Nib\", \"#FFA8816F\": \"Cocoa Nutmeg\", \"#FFDFCEC2\": \"Cocoa Parfait\", \"#FF967B5D\": \"Cocoa Pecan\", \"#FF766A5F\": \"Cocoa Powder\", \"#FF7E6657\": \"Cocoa Shell\", \"#FFA08E7E\": \"Cocoa Whip\", \"#FF784848\": \"Cocobolo\", \"#FFAA8F7A\": \"Cocoloco\", \"#FF965A3E\": \"Coconut\", \"#FFEBE8E7\": \"Coconut Agony\", \"#FFEEEEDD\": \"Coconut Aroma\", \"#FFF2EFE1\": \"Coconut Butter\", \"#FFE1DABB\": \"Coconut Cream Variant\", \"#FFF0E2CF\": \"Coconut Cream Pie\", \"#FFE2CEA6\": \"Coconut Crumble\", \"#FF676D43\": \"Coconut Grove\", \"#FF7D6044\": \"Coconut Husk\", \"#FFDDD4C7\": \"Coconut Ice\", \"#FFDACAC0\": \"Coconut Macaroon\", \"#FFEEEBE2\": \"Coconut Milk\", \"#FFFBF9E1\": \"Coconut Pulp\", \"#FFFEE4B6\": \"Coconut Scent\", \"#FF917A56\": \"Coconut Shell\", \"#FFF7F1E1\": \"Coconut Twist\", \"#FFE9EDF6\": \"Coconut White\", \"#FFDEDBCC\": \"Cocoon\", \"#FF2D3032\": \"Cod Grey\", \"#FF9C9C9C\": \"Codex Grey\", \"#FF524B2A\": \"Codium Fragile\", \"#FF8C4040\": \"Codman Claret\", \"#FF0E7F78\": \"Coelia Greenshade\", \"#FF497D93\": \"Coelin Blue\", \"#FF883300\": \"Coffee Addiction\", \"#FF775511\": \"Coffee Adept\", \"#FFDBD6D3\": \"Coffee Bag\", \"#FF825C43\": \"Coffee Bar\", \"#FF362D26\": \"Coffee Bean Variant\", \"#FF6F0C0D\": \"Coffee Brick\", \"#FFB5987F\": \"Coffee Cake\", \"#FFB7997C\": \"Coffee Clay\", \"#FFFFF2D7\": \"Coffee Cream\", \"#FFAB9B9C\": \"Coffee Custard\", \"#FFBEA88D\": \"Coffee Diva\", \"#FFBF9779\": \"Coffee Gelato\", \"#FF302010\": \"Coffee Grounds\", \"#FF6C5B4D\": \"Coffee House\", \"#FFB19576\": \"Coffee Kiss\", \"#FF6A513B\": \"Coffee Liqueur\", \"#FFA9898D\": \"Coffee Rose\", \"#FF725042\": \"Coffee Shop\", \"#FFDF9D5B\": \"Coffee Whip\", \"#FFA68966\": \"Coffee With Cream\", \"#FFD48C46\": \"Cognac Variant\", \"#FFB98563\": \"Cognac Brown\", \"#FFA17B49\": \"Cognac Tint\", \"#FF90534A\": \"Cogswell Cedar\", \"#FFE0D5E3\": \"Coin Purse\", \"#FFFF4411\": \"Coin Slot\", \"#FFC7DE88\": \"Coincidence\", \"#FF3C2F23\": \"Cola Variant\", \"#FF3C3024\": \"Cola Bubble\", \"#FFC1DCDB\": \"Cold Air Turquoise\", \"#FF154250\": \"Cold and Dark\", \"#FFBBEEEE\": \"Cold Blooded\", \"#FF88DDDD\": \"Cold Blue\", \"#FF785736\": \"Cold Brew Coffee\", \"#FFC75D42\": \"Cold Brew Tonic\", \"#FFDBFFFE\": \"Cold Canada\", \"#FF234272\": \"Cold Current\", \"#FFEFECE3\": \"Cold Foam\", \"#FF85B3B2\": \"Cold Front Green\", \"#FF008B3C\": \"Cold Green\", \"#FF9F9F9F\": \"Cold Grey\", \"#FF22DDEE\": \"Cold Heights\", \"#FFDDE3E6\": \"Cold Light\", \"#FF00EEEE\": \"Cold Light of Day\", \"#FF9BA0EF\": \"Cold Lips\", \"#FFE6E5E4\": \"Cold Morning\", \"#FF559C9B\": \"Cold North\", \"#FF0033DD\": \"Cold Pack\", \"#FFD09351\": \"Cold Pilsner\", \"#FFBCA5AD\": \"Cold Pink\", \"#FF6C2E09\": \"Cold Press Coffee\", \"#FF665B42\": \"Cold Pressed\", \"#FF9D8ABF\": \"Cold Purple Variant\", \"#FF32545E\": \"Cold Sea Currents\", \"#FFD4E0EF\": \"Cold Shoulder\", \"#FFACBAC5\": \"Cold Snap\", \"#FFFFF7FD\": \"Cold Snow\", \"#FFD9E7E6\": \"Cold Soft Blue\", \"#FF88BB66\": \"Cold Spring\", \"#FF7E8692\": \"Cold Trade Winds\", \"#FFCFE1EF\": \"Cold Turbulence\", \"#FFCAB5B2\": \"Cold Turkey Variant\", \"#FFA5D0CB\": \"Cold Turquoise\", \"#FFD9DFE0\": \"Cold Water\", \"#FF839FA3\": \"Cold Waterlogged Lab Coat\", \"#FFC2E2E3\": \"Cold Wave\", \"#FFC1E2E3\": \"Cold Well Water\", \"#FFEDFCFB\": \"Cold White\", \"#FFE1E3E4\": \"Cold Wind\", \"#FFB4BCD1\": \"Cold Winter\\u2019s Morn\", \"#FFCEC8B6\": \"Coliseum Marble\", \"#FF536861\": \"Collard Green\", \"#FF9B8467\": \"Collectible\", \"#FFEBECDA\": \"Colleen Green\", \"#FFBDB7CD\": \"Collensia\", \"#FF75BFD2\": \"Cologne\", \"#FFEFC944\": \"Colombian Yellow\", \"#FFBA7AB3\": \"Colombo Red Mauve\", \"#FFB68238\": \"Colonel Mustard\", \"#FFB2B1AD\": \"Colonnade Grey\", \"#FFC6C0B6\": \"Colonnade Stone\", \"#FFEE7766\": \"Colorado Bronze\", \"#FFE09CAB\": \"Colorado Dawn\", \"#FFE6994C\": \"Colorado Peach\", \"#FF9C9BA7\": \"Colorado Peak\", \"#FF88AAC4\": \"Colorado Springs\", \"#FFB49375\": \"Colorado Trail\", \"#FF625C91\": \"Colossus\", \"#FFC6D2DE\": \"Colour Blind\", \"#FF7CB77B\": \"Colour Me Green\", \"#FFAA5C43\": \"Colourful Leaves\", \"#FF009792\": \"Columbia\", \"#FFBEB861\": \"Columbian Gold\", \"#FFF5DAE3\": \"Columbine\", \"#FFD0CBCE\": \"Columbo\\u2019s Coat\", \"#FF5F758F\": \"Columbus\", \"#FF006F37\": \"Column of Oak Green\", \"#FF7F725C\": \"Colusa Wetlands\", \"#FFF4F0DE\": \"Combed Cotton\", \"#FF5C92C5\": \"Come Sail Away\", \"#FF636373\": \"Comet Variant\", \"#FFC1DAED\": \"Comet Tail\", \"#FFE3CEB8\": \"Comfort\", \"#FFBEC3BB\": \"Comfort Grey\", \"#FFD7C0AB\": \"Comforting\", \"#FFCC1144\": \"Comforting Cherry\", \"#FFD5E0CF\": \"Comforting Green\", \"#FFC5C3B4\": \"Comforting Grey\", \"#FF64856B\": \"Comfrey\", \"#FFE3D2B6\": \"Comfy Beige\", \"#FFF3D1C8\": \"Comical Coral\", \"#FFDE7485\": \"Coming up Roses\", \"#FF0B597C\": \"Commandes\", \"#FFEDECE6\": \"Commercial White\", \"#FF25476A\": \"Commodore\", \"#FF858F94\": \"Common Feldspar\", \"#FF946943\": \"Common Jasper\", \"#FF009193\": \"Common Teal\", \"#FFD0B997\": \"Community\", \"#FF4C785C\": \"Como Variant\", \"#FFCDCDCD\": \"Compact Disc Grey\", \"#FF8A877B\": \"Compass\", \"#FF35475B\": \"Compass Blue\", \"#FFE8C89E\": \"Compatible Cream\", \"#FF847975\": \"Complex Grey\", \"#FF9E91AE\": \"Compliment\", \"#FFBBC8B2\": \"Composed\", \"#FF7A6E7E\": \"Composer\\u2019s Magic\", \"#FF55CC00\": \"Composite Artefact Green\", \"#FF6C3877\": \"Comtesse\", \"#FFB12845\": \"Con Brio\", \"#FF263130\": \"Concealed Green\", \"#FF405852\": \"Concealment\", \"#FFD5BDA3\": \"Concept Beige\", \"#FF7AC34F\": \"Conceptual\", \"#FF9E6B75\": \"Concerto\", \"#FFA0B1AE\": \"Conch Variant\", \"#FFDBA496\": \"Conch Pink\", \"#FFFC8F9B\": \"Conch Shell\", \"#FFABB9D7\": \"Conclave\", \"#FF827F79\": \"Concord Variant\", \"#FFE2CEB0\": \"Concord Buff\", \"#FF855983\": \"Concord Grape\", \"#FF695A82\": \"Concord Jam\", \"#FFD2D1CD\": \"Concrete Variant\", \"#FF999988\": \"Concrete Jungle\", \"#FF5C606E\": \"Concrete Landscape\", \"#FF8D8A81\": \"Concrete Sidewalk\", \"#FFB98142\": \"Condiment\", \"#FFFFFFCC\": \"Conditioner\", \"#FF4A6169\": \"Cone Green Blue\", \"#FF6D7E7D\": \"Coney Island\", \"#FFF4ECDA\": \"Confection\", \"#FFD4B4D5\": \"Confectionary\", \"#FFDDCB46\": \"Confetti Variant\", \"#FFA98A6B\": \"Confidence\", \"#FFE4DFCE\": \"Confident White\", \"#FFFFCC13\": \"Confident Yellow\", \"#FF01C08D\": \"C\\u014dng L\\u01dc Green\", \"#FFE8C3BE\": \"Congo\", \"#FF654D49\": \"Congo Brown Variant\", \"#FF776959\": \"Congo Capture\", \"#FF00A483\": \"Congo Green\", \"#FFF98379\": \"Congo Pink\", \"#FF100438\": \"Congressional Navy\", \"#FFB1DD52\": \"Conifer Variant\", \"#FFFFDD49\": \"Conifer Blossom\", \"#FF885555\": \"Conifer Cone\", \"#FF747767\": \"Conifer Green\", \"#FFB94E41\": \"Conker\", \"#FF552200\": \"Conker Brown\", \"#FF654E44\": \"Connaisseur\", \"#FFEB6651\": \"Connect Red\", \"#FF898473\": \"Connected Grey\", \"#FFCCBBEE\": \"Connecticut Lilac\", \"#FF175A6C\": \"Connor\\u2019s Lakefront\", \"#FFF2D9B8\": \"Cono de Vainilla\", \"#FF796E54\": \"Conservation\", \"#FFD1D0C6\": \"Conservative Grey\", \"#FFE4CDAC\": \"Consomm\\u00e9\", \"#FF57465D\": \"Conspiracy Velvet\", \"#FFCD8E7F\": \"Constant Coral\", \"#FFBCCEDB\": \"Constellation\", \"#FF3C4670\": \"Constellation Blue\", \"#FFEE8442\": \"Construction Zone\", \"#FFF5811A\": \"Consumed by Fire\", \"#FFBB4745\": \"Conte Crayon\", \"#FFBEC6BB\": \"Contemplation\", \"#FF70766A\": \"Contemplative\", \"#FFBDC0B3\": \"Contented\", \"#FFC16F68\": \"Contessa Variant\", \"#FF98C6CB\": \"Continental Waters\", \"#FFDEDEFF\": \"Contrail\", \"#FFF2C200\": \"Contrasting Yellow\", \"#FFE9D6B0\": \"Convivial Yellow\", \"#FFCD98A3\": \"Cooing Doves\", \"#FF014E83\": \"Cook\\u2019s Bay\", \"#FFFFE2B7\": \"Cookie\", \"#FFB19778\": \"Cookie Crumb\", \"#FFE3B258\": \"Cookie Crust\", \"#FFAB7100\": \"Cookie Dough\", \"#FFEEE0B1\": \"Cookies and Cream\", \"#FF96B3B3\": \"Cool\", \"#FF28394D\": \"Cool Air of Debonair\", \"#FFA9D99C\": \"Cool Aloe\", \"#FFC6D86B\": \"Cool as a Cucumber\", \"#FF929291\": \"Cool Ashes\", \"#FFC4B47D\": \"Cool Avocado\", \"#FF18233D\": \"Cool Balaclavas Are Forever\", \"#FFC6B5A7\": \"Cool Beige\", \"#FF4984B8\": \"Cool Blue\", \"#FF6B927C\": \"Cool Bluegrass\", \"#FFAE996B\": \"Cool Camel\", \"#FF827566\": \"Cool Camo\", \"#FFF1D3CA\": \"Cool Cantaloupe\", \"#FF807B76\": \"Cool Charcoal\", \"#FFBA947B\": \"Cool Clay\", \"#FFD9D0C1\": \"Cool Concrete\", \"#FFAD8458\": \"Cool Copper\", \"#FFB0E6E3\": \"Cool Crayon\", \"#FFFBE5D9\": \"Cool Cream\", \"#FFB88035\": \"Cool Cream Spirit\", \"#FF283C44\": \"Cool Current\", \"#FF96AABA\": \"Cool Customer\", \"#FFFDFBF8\": \"Cool December\", \"#FF00606F\": \"Cool Dive\", \"#FF7B9DAD\": \"Cool Dusk\", \"#FFCFCFD0\": \"Cool Elegance\", \"#FFE7E6ED\": \"Cool Frost\", \"#FFABACA8\": \"Cool Granite\", \"#FF33B864\": \"Cool Green\", \"#FF8C93AD\": \"Cool Grey Variant\", \"#FFE1EEE6\": \"Cool Icicle\", \"#FFBEE7E0\": \"Cool Jazz\", \"#FF9ACABA\": \"Cool Juniper\", \"#FFE97C6B\": \"Cool Lava\", \"#FFB3A6A5\": \"Cool Lavender\", \"#FFEBD1CD\": \"Cool Melon\", \"#FFC6DAD5\": \"Cool Mint\", \"#FF384248\": \"Cool Operator\\u2019s Overalls\", \"#FFCAE4B2\": \"Cool Peridot\", \"#FFACAD97\": \"Cool Pine\", \"#FFE5CCD1\": \"Cool Pink\", \"#FFAA23FF\": \"Cool Purple\", \"#FFCBB5C6\": \"Cool Quiet\", \"#FFEAF0EB\": \"Cool Reflection\", \"#FFD9DBCA\": \"Cool Runnings\", \"#FFB4B9AB\": \"Cool Sea Air\", \"#FFCFE0E4\": \"Cool Sky\", \"#FFD0CCC5\": \"Cool Slate\", \"#FFBBD9C3\": \"Cool Spring\", \"#FF0091B3\": \"Cool Tide\", \"#FF7295C9\": \"Cool Touch\", \"#FFD5D7D3\": \"Cool Vapour\", \"#FF9BD9E5\": \"Cool Water Lake\", \"#FF487678\": \"Cool Waters\", \"#FFDAE6E2\": \"Cool White\", \"#FFEAEFCE\": \"Cool Yellow\", \"#FF499C9D\": \"Coolbox Ice Turquoise\", \"#FF75B9AE\": \"Cooled Blue\", \"#FFFADC97\": \"Cooled Cream\", \"#FF77BBFF\": \"Cooler Than Ever\", \"#FFE6E2E4\": \"Cooling Trend\", \"#FF006C8D\": \"Copacabana\", \"#FFE5D68E\": \"Copacabana Sand\", \"#FF57748D\": \"Copen Blue\", \"#FFADC8C0\": \"Copenhagen\", \"#FF21638B\": \"Copenhagen Blue\", \"#FFD0851D\": \"Copious Caramel\", \"#FFB1715A\": \"Copper Beech\", \"#FFE8C1AB\": \"Copper Blush\", \"#FF9A6051\": \"Copper Brown\", \"#FF77422C\": \"Copper Canyon Variant\", \"#FFF4BB92\": \"Copper Cloud\", \"#FFD89166\": \"Copper Cove\", \"#FFA35D31\": \"Copper Creek\", \"#FFD57E52\": \"Copper Harbor\", \"#FFC48C67\": \"Copper Hide\", \"#FFBF4000\": \"Copper Hopper\", \"#FFC09078\": \"Copper Lake\", \"#FFB2764C\": \"Copper Mine\", \"#FF398174\": \"Copper Mineral Green\", \"#FF945C54\": \"Copper Mining\", \"#FFC29978\": \"Copper Moon\", \"#FFAB714A\": \"Copper Mountain\", \"#FF9DB4A0\": \"Copper Patina\", \"#FF946877\": \"Copper Pink\", \"#FFDA8F67\": \"Copper Pipe\", \"#FF936647\": \"Copper Pot\", \"#FF3E4939\": \"Copper Pyrite Green\", \"#FFF7A270\": \"Copper River\", \"#FF6F978E\": \"Copper Roof Green\", \"#FF95524C\": \"Copper Rust Variant\", \"#FFDC8C5D\": \"Copper Tan\", \"#FFC18978\": \"Copper Trail\", \"#FF38887F\": \"Copper Turquoise\", \"#FFDB8B67\": \"Copper Wire\", \"#FFAD6342\": \"Copper-Metal Red\", \"#FFDA8A88\": \"Copperfield Variant\", \"#FFD68755\": \"Copperhead\", \"#FFCF8874\": \"Copperleaf\", \"#FFD98A3F\": \"Coppersmith\", \"#FF7F4330\": \"Coppery Orange\", \"#FF654636\": \"Copra\", \"#FFE5DCDC\": \"Coquette\", \"#FF9D8D8E\": \"Coquina\", \"#FFBB9A88\": \"Coquina Shell\", \"#FFE29D94\": \"Coral Almond\", \"#FFDC938D\": \"Coral Atoll\", \"#FFDA8C87\": \"Coral Banks\", \"#FFDDB8A3\": \"Coral Bay\", \"#FFFFBBAA\": \"Coral Beach\", \"#FFEF9A93\": \"Coral Bead\", \"#FFFBC5BB\": \"Coral Bells\", \"#FFF7C6B1\": \"Coral Bisque\", \"#FFF7BEA2\": \"Coral Blossom\", \"#FFE5A090\": \"Coral Blush\", \"#FFDD5544\": \"Coral Burst\", \"#FFF5D0C9\": \"Coral Candy\", \"#FFC2B1A1\": \"Coral Clay\", \"#FFDC958D\": \"Coral Cloud\", \"#FF068E9E\": \"Coral Coast\", \"#FFEE6666\": \"Coral Commander\", \"#FFFCCCA7\": \"Coral Confection\", \"#FFE9ADCA\": \"Coral Corn Snake\", \"#FFFEAD8C\": \"Coral Correlation\", \"#FFDDA69F\": \"Coral Cove\", \"#FFEAD6CE\": \"Coral Cream\", \"#FFFCD5C5\": \"Coral Dune\", \"#FFFFB48A\": \"Coral Dusk\", \"#FFEDAA86\": \"Coral Dust\", \"#FFD76A69\": \"Coral Expression\", \"#FFE3A9A2\": \"Coral Fountain\", \"#FFFFC39E\": \"Coral Gable\", \"#FFCF8179\": \"Coral Garden\", \"#FFCF714A\": \"Coral Gold\", \"#FFABE2CF\": \"Coral Green\", \"#FFE28980\": \"Coral Haze\", \"#FFFFDDC7\": \"Coral Kiss\", \"#FFFCD6CB\": \"Coral Mantle\", \"#FFE4694C\": \"Coral Orange\", \"#FFE76682\": \"Coral Paradise\", \"#FFF39081\": \"Coral Passion\", \"#FFF7685F\": \"Coral Quartz\", \"#FFF3774D\": \"Coral Rose\", \"#FFCA884E\": \"Coral Sand\", \"#FFF9A48E\": \"Coral Serenade\", \"#FFF2A37D\": \"Coral Silk\", \"#FFABD1AF\": \"Coral Springs\", \"#FFDDC3B6\": \"Coral Stone\", \"#FFFF8B87\": \"Coral Trails\", \"#FFAB6E67\": \"Coral Tree Variant\", \"#FFFEB890\": \"Coral Wisp\", \"#FFF08674\": \"Coralette\", \"#FFFF917A\": \"Coralistic\", \"#FFDD675A\": \"Coralite\", \"#FFF0DFCD\": \"Corallite\", \"#FFFEA89F\": \"Corally\", \"#FF9D6663\": \"Corazon\", \"#FF111122\": \"Corbeau\", \"#FF864C52\": \"Cordial\", \"#FF616665\": \"Cordite\", \"#FFEBE0C8\": \"Cordon Bleu Crust\", \"#FF7C3744\": \"Cordova Burgundy\", \"#FF57443D\": \"Cordovan Leather\", \"#FF404D49\": \"Corduroy Variant\", \"#FF594035\": \"Cordwood\", \"#FF008E8D\": \"Corfu Shallows\", \"#FF8993C3\": \"Corfu Sky\", \"#FF008AAD\": \"Corfu Waters\", \"#FFBBB58D\": \"Coriander Variant\", \"#FF7E7463\": \"Coriander Ochre\", \"#FFBA9C75\": \"Coriander Powder\", \"#FFBDAA6F\": \"Coriander Seed\", \"#FFDEDECF\": \"Corinthian Column\", \"#FFE1D1B1\": \"Corinthian Pillar\", \"#FFFFA6D9\": \"Corinthian Pink\", \"#FF5A4C42\": \"Cork Variant\", \"#FF7E6B43\": \"Cork Bark\", \"#FFCC8855\": \"Cork Brown\", \"#FFC1A98A\": \"Cork Wedge\", \"#FFCC7744\": \"Cork Wood\", \"#FF9D805D\": \"Corkboard\", \"#FFD1B9AB\": \"Corkscrew Willow\", \"#FFBD9B78\": \"Corky\", \"#FF437064\": \"Cormorant\", \"#FFEEC657\": \"Corn Bread\", \"#FFE1C595\": \"Corn Chowder\", \"#FFF8F3C4\": \"Corn Field Variant\", \"#FF8D702A\": \"Corn Harvest Variant\", \"#FFF2D6AE\": \"Corn Husk\", \"#FFCECD95\": \"Corn Husk Green\", \"#FFDEAA6E\": \"Corn Maze\", \"#FFEE4411\": \"Corn Poppy Cherry\", \"#FFAB6134\": \"Corn Snake\", \"#FFB31B11\": \"Cornell Red\", \"#FFBC8F5F\": \"Corner Caf\\u00e9\", \"#FFE3D7BB\": \"Cornerstone\", \"#FF5170D7\": \"Cornflower Variant\", \"#FF6C91C5\": \"Cornflower Blue Variant\", \"#FFFFD691\": \"Cornmeal\", \"#FFEBD5C5\": \"Cornmeal Beige\", \"#FFF4C96C\": \"Cornsilk Yellow\", \"#FFA7B25F\": \"Cornstalk\", \"#FFED9B44\": \"Cornucopia\", \"#FF908C53\": \"Cornus Green\", \"#FF4885AA\": \"Cornwall\", \"#FF949488\": \"Cornwall Slate\", \"#FFFFB437\": \"Corona\", \"#FFD5A68D\": \"Coronado Dunes\", \"#FF9BA591\": \"Coronado Moss\", \"#FFEDECEC\": \"Coronation\", \"#FF59529C\": \"Coronation Blue\", \"#FF59728E\": \"Coronet Blue\", \"#FF78A486\": \"Corporate Green\", \"#FF61513D\": \"Corral\", \"#FF937360\": \"Corral Brown\", \"#FFF18A76\": \"Corralize\", \"#FF4DA48B\": \"Corrosion Green\", \"#FF772F21\": \"Corrosion Red\", \"#FF54D905\": \"Corrosive Green\", \"#FF18576C\": \"Corsair\", \"#FF85AC9D\": \"Corsican\", \"#FF646093\": \"Corsican Blue\", \"#FF7A85AF\": \"Corsican Purple\", \"#FFA99592\": \"Cortex\", \"#FFA4896A\": \"Cortez Chocolate\", \"#FF4A6267\": \"Corundum Blue\", \"#FF95687D\": \"Corundum Red\", \"#FFE9BA81\": \"Corvette Variant\", \"#FFA2C7D7\": \"Corydalis Blue\", \"#FFA4C48E\": \"Cos\", \"#FFD3BED5\": \"Cosmetic Mauve\", \"#FFF3C1AB\": \"Cosmetic Peach\", \"#FFA56078\": \"Cosmetic Red\", \"#FFDD669D\": \"Cosmetologist\\u2019s Pink\", \"#FFB8B9CB\": \"Cosmic Variant\", \"#FFCFB3A6\": \"Cosmic Aura\", \"#FF8B4F90\": \"Cosmic Berry\", \"#FF001000\": \"Cosmic Bit Flip\", \"#FF93C3CB\": \"Cosmic Blue\", \"#FFE77E6C\": \"Cosmic Coral\", \"#FFDCE2E5\": \"Cosmic Dust\", \"#FF9392AB\": \"Cosmic Energy\", \"#FF551155\": \"Cosmic Explorer\", \"#FF30A877\": \"Cosmic Green\", \"#FF9601F4\": \"Cosmic Heart\", \"#FFE6A8D7\": \"Cosmic Pink\", \"#FF9EA19F\": \"Cosmic Quest\", \"#FFCADADA\": \"Cosmic Ray\", \"#FFDA244B\": \"Cosmic Red\", \"#FFAAAAC4\": \"Cosmic Sky\", \"#FF090533\": \"Cosmic Void\", \"#FFA09BC6\": \"Cosmo Purple\", \"#FF528BAB\": \"Cosmopolitan\", \"#FFFCD5CF\": \"Cosmos Variant\", \"#FF003249\": \"Cosmos Blue\", \"#FF4D8AA1\": \"Cossack Dancer\", \"#FF328E13\": \"Cossack Green\", \"#FF625D2A\": \"Costa Del Sol Variant\", \"#FF77BCE2\": \"Costa Rica Blue\", \"#FFC44041\": \"Costa Rican Palm\", \"#FF6477A0\": \"Costume Blue\", \"#FFC3A598\": \"Cosy Blanket\", \"#FFAA8F7D\": \"Cosy Cocoa\", \"#FFF2DDD8\": \"Cosy Cottage\", \"#FFE4C38F\": \"Cosy Cover\", \"#FFF0CCAD\": \"Cosy Coverlet\", \"#FFE0DBC7\": \"Cosy Cream\", \"#FFFBA765\": \"Cosy Nook\", \"#FFEB9F9F\": \"Cosy Summer Sunset\", \"#FFE8E1D0\": \"Cosy White\", \"#FFD1B99B\": \"Cosy Wool\", \"#FF017C85\": \"Cote D\\u2019Azur\", \"#FF340059\": \"Cotinga Purple\", \"#FFDBCDAD\": \"Cotswold Dill\", \"#FF789EC5\": \"Cottage Blue\", \"#FF357697\": \"Cottage by the Sea\", \"#FFAFBEB0\": \"Cottage Charm\", \"#FFEDDBBD\": \"Cottage Cream\", \"#FFDCECDC\": \"Cottage Green\", \"#FFACB397\": \"Cottage Hill\", \"#FF828676\": \"Cottage Lattice Green\", \"#FFD9A89A\": \"Cottage Rose\", \"#FFA85846\": \"Cottage Spice\", \"#FFA08E77\": \"Cottage Walk\", \"#FFF7EFDD\": \"Cottage White\", \"#FFFFDAD9\": \"Cottagecore Sunset\", \"#FFEDDBD7\": \"Cottingley Fairies\", \"#FFEEEBE1\": \"Cotton\", \"#FFDCC6BA\": \"Cotton & Flax\", \"#FFF2F7FD\": \"Cotton Ball\", \"#FFF5F1E4\": \"Cotton Blossom\", \"#FFE7EFFB\": \"Cotton Boll\", \"#FFF5BCDE\": \"Cotton Candy Aesthetic\", \"#FFFFC3CB\": \"Cotton Candy Comet\", \"#FFDD22FF\": \"Cotton Candy Explosions\", \"#FFDEC74B\": \"Cotton Candy Grape\", \"#FF7596B8\": \"Cotton Cardigan\", \"#FFFAF4D4\": \"Cotton Cloth\", \"#FFC2E1EC\": \"Cotton Clouds\", \"#FFF3E4D3\": \"Cotton Club\", \"#FF91ABBE\": \"Cotton Denim\", \"#FFF0EAD8\": \"Cotton Down\", \"#FFDAD0BD\": \"Cotton Fibre\", \"#FFF2F0E8\": \"Cotton Field\", \"#FF9090A2\": \"Cotton Flannel\", \"#FFF8F0C7\": \"Cotton Floss\", \"#FFF9F4E5\": \"Cotton Fluff\", \"#FFD1CCC3\": \"Cotton Grey\", \"#FF066976\": \"Cotton Indigo\", \"#FFE5DFD2\": \"Cotton Knit\", \"#FFEED09C\": \"Cotton Muslin\", \"#FFFFFFE7\": \"Cotton Puff\", \"#FFF1EBDB\": \"Cotton Ridge\", \"#FFF7EBDD\": \"Cotton Sheets\", \"#FFFFF8D7\": \"Cotton Tail\", \"#FFE5E1D5\": \"Cotton Tuft\", \"#FFFAF1DF\": \"Cotton Whisper\", \"#FFE4E3D8\": \"Cotton White\", \"#FF83ABD2\": \"Cotton Wool Blue\", \"#FFF5E6C7\": \"Cottonseed\", \"#FF4E2A20\": \"Couch\", \"#FFC2B4A7\": \"Couch Potato\", \"#FF9A7F78\": \"Cougar\", \"#FF5E2D10\": \"Count Chocula\", \"#FF772277\": \"Count\\u2019s Wardrobe\", \"#FF9FB6C6\": \"Country Air\", \"#FFEAE1CB\": \"Country Beige\", \"#FF717F9B\": \"Country Blue\", \"#FFE0D9D5\": \"Country Breeze\", \"#FFC7C0A7\": \"Country Charm\", \"#FF948675\": \"Country Club\", \"#FFB8A584\": \"Country Cork\", \"#FFD9C1B7\": \"Country Cottage\", \"#FFB0967C\": \"Country Dweller\", \"#FF414634\": \"Country House Green\", \"#FF5D7A85\": \"Country Lake\", \"#FFFCEAD1\": \"Country Lane\", \"#FF894340\": \"Country Lane Red\", \"#FFD7C2A6\": \"Country Linen\", \"#FF1A5A4E\": \"Country Meadow\", \"#FFDFEBE2\": \"Country Mist\", \"#FFD0BCA2\": \"Country Rubble\", \"#FF49545A\": \"Country Sky\", \"#FF7E4337\": \"Country Sleigh\", \"#FF124A42\": \"Country Squire\", \"#FFFFFBD7\": \"Country Summer\", \"#FF837B68\": \"Country Tweed\", \"#FF88C096\": \"Country Weekend\", \"#FFA4A404\": \"Countryside\", \"#FF1B4B35\": \"County Green Variant\", \"#FFDAA135\": \"Courgette Yellow\", \"#FFB9B7A0\": \"Court Green\", \"#FF926D9D\": \"Court Jester\", \"#FFCECB97\": \"Court-Bouillon\", \"#FFD2D3DE\": \"Courteous\", \"#FFBBAFC1\": \"Courtly Purple\", \"#FFC8BDA4\": \"Courtyard\", \"#FF718084\": \"Courtyard Blue\", \"#FF978D71\": \"Courtyard Green\", \"#FFE3D3BA\": \"Courtyard Tan\", \"#FFFFE29B\": \"Couscous\", \"#FF55A9D6\": \"Cousteau\", \"#FF86B097\": \"Covent Garden\", \"#FF8BA9BC\": \"Coventry Blue\", \"#FF494E4F\": \"Cover of Night\", \"#FF6A3C3B\": \"Covered Bridge\", \"#FFB9BABA\": \"Covered in Platinum\", \"#FF726449\": \"Covered Wagon\", \"#FF80765F\": \"Covert Green\", \"#FFD4CDD2\": \"Coverts Wood Pigeon\", \"#FF9BBDB2\": \"Coveted Blue\", \"#FFB6B3BF\": \"Coveted Gem\", \"#FFF1EDE5\": \"Cow\\u2019s Milk\", \"#FFFBF1C0\": \"Cowardly Custard\", \"#FFFFE481\": \"Cowbell\", \"#FF443736\": \"Cowboy Variant\", \"#FF695239\": \"Cowboy Boots\", \"#FFB27D50\": \"Cowboy Hat\", \"#FF7A7F82\": \"Cowboy Spur\", \"#FF763E2D\": \"Cowboy Suede\", \"#FF8D6B4B\": \"Cowboy Trails\", \"#FF6A87AB\": \"Cowgirl Blue\", \"#FF9E7C60\": \"Cowgirl Boots\", \"#FF92484A\": \"Cowhide\", \"#FF661100\": \"Cowpeas\", \"#FFF9DAD8\": \"Coy Pink\", \"#FFDC9B68\": \"Coyote\", \"#FFB08F7F\": \"Coyote Tracks\", \"#FFAE9671\": \"Coyote Wild\", \"#FF0AAFA4\": \"Cozumel\", \"#FFF0B599\": \"Crab Bisque\", \"#FFD94B28\": \"Crab Curry\", \"#FF004455\": \"Crab Nebula\", \"#FF87382F\": \"Crabapple\", \"#FF753531\": \"Crabby Apple\", \"#FFB0A470\": \"Crack Willow\", \"#FFC5B1A0\": \"Cracked Earth\", \"#FF4F5152\": \"Cracked Pepper\", \"#FF69656A\": \"Cracked Slate\", \"#FFF4DFBD\": \"Cracked Wheat\", \"#FFD1B088\": \"Cracker Bitz\", \"#FFD3B9B0\": \"Cracker Crumbs\", \"#FFF2E7D1\": \"Crackled\", \"#FFA27C4F\": \"Crackled Leather\", \"#FFB3C5CC\": \"Crackling Lake\", \"#FFF1D3D9\": \"Cradle Pillow\", \"#FFEAC9D5\": \"Cradle Pink\", \"#FF293B4A\": \"Craft\", \"#FFB7A083\": \"Craft Brown\", \"#FFE3C8AA\": \"Craft Juggler\", \"#FF8A6645\": \"Craft Paper\", \"#FF008193\": \"Craftsman Blue\", \"#FFAE9278\": \"Craftsman Brown\", \"#FFD3B78B\": \"Craftsman Gold\", \"#FFA65648\": \"Crail Variant\", \"#FF2B8288\": \"Cranach Blue\", \"#FFDB8079\": \"Cranapple\", \"#FFE6C4C5\": \"Cranapple Cream\", \"#FF9E003A\": \"Cranberry Variant\", \"#FF7494B1\": \"Cranberry Blue\", \"#FFAB7A71\": \"Cranberry Foule\", \"#FFA34F55\": \"Cranberry Jam\", \"#FFC27277\": \"Cranberry Pie\", \"#FF7E5350\": \"Cranberry Red\", \"#FFA53756\": \"Cranberry Sauce\", \"#FFDA5265\": \"Cranberry Splash\", \"#FF893E40\": \"Cranberry Tart\", \"#FF8E4541\": \"Cranberry Whip\", \"#FFA65570\": \"Cranbrook\", \"#FF954C52\": \"Crantini\", \"#FFEEEE66\": \"Crash Dummy\", \"#FFCC88FF\": \"Crash Pink\", \"#FF3E6F87\": \"Crashing Waves\", \"#FF75674F\": \"Crater\", \"#FF4D3E3C\": \"Crater Brown Variant\", \"#FFC8CED6\": \"Crater Crawler\", \"#FF63797E\": \"Crater Lake\", \"#FFEEEDD9\": \"Cravat\", \"#FF016496\": \"Craving Cobalt\", \"#FFBC763C\": \"Cray\", \"#FF1DAC78\": \"Crayola Green\", \"#FFFE7438\": \"Crayola Orange\", \"#FFE5CB3F\": \"Crazy\", \"#FFCC1177\": \"Crazy Ex\", \"#FF5EB68D\": \"Crazy Eyes\", \"#FFA57648\": \"Crazy Horse\", \"#FFF970AC\": \"Crazy Pink\", \"#FFFFFFC2\": \"Cream Variant\", \"#FFFEEEA5\": \"Cream and Butter\", \"#FFDDCFB9\": \"Cream and Sugar\", \"#FFF8C49A\": \"Cream Blush\", \"#FFE3D0AD\": \"Cream Cake\", \"#FFEEC051\": \"Cream Can Variant\", \"#FFD7D3A6\": \"Cream Cheese Avocado\", \"#FFF4EFE2\": \"Cream Cheese Frosting\", \"#FFF1F3DA\": \"Cream Clear\", \"#FFF2D7B0\": \"Cream Custard\", \"#FFEAE3D0\": \"Cream Delight\", \"#FFF5F1DA\": \"Cream Filling\", \"#FFDCC356\": \"Cream Gold\", \"#FFDFD2BE\": \"Cream in My Coffee\", \"#FFEBD1BE\": \"Cream of Mushroom\", \"#FFF6E4D9\": \"Cream Pink\", \"#FFFFBB99\": \"Cream Puff\", \"#FFEEE3C6\": \"Cream Silk\", \"#FFECCBA0\": \"Cream Snap\", \"#FFE4C7B8\": \"Cream Tan\", \"#FFA9AABD\": \"Cream Violet\", \"#FFF2E0C5\": \"Cream Washed\", \"#FFE8DBC5\": \"Cream Wave\", \"#FFF2EEE2\": \"Cream White\", \"#FF70804D\": \"Creamed Avocado\", \"#FFFFFCD3\": \"Creamed Butter\", \"#FFB79C94\": \"Creamed Caramel\", \"#FF8B6962\": \"Creamed Muscat\", \"#FFBD6883\": \"Creamed Raspberry\", \"#FFEDD2B7\": \"Creamery\", \"#FFEFE8DB\": \"Creamy\", \"#FFFFE8BD\": \"Creamy Apricot\", \"#FFD8F19C\": \"Creamy Avocado\", \"#FFFFDAE8\": \"Creamy Axolotl\", \"#FFFDE1C5\": \"Creamy Beige\", \"#FFDEBCCD\": \"Creamy Berry\", \"#FFF9EEDC\": \"Creamy Cameo\", \"#FFDBCCB5\": \"Creamy Cappuccino\", \"#FFB3956C\": \"Creamy Caramel\", \"#FFE1CFAF\": \"Creamy Chenille\", \"#FFFFF5E0\": \"Creamy Cloud Dreams\", \"#FFDD7788\": \"Creamy Coral\", \"#FFFFF2C2\": \"Creamy Corn\", \"#FFF9E7BF\": \"Creamy Custard\", \"#FFEBD0DB\": \"Creamy Freesia\", \"#FFECEFE3\": \"Creamy Garlic\", \"#FFF0E2C5\": \"Creamy Gelato\", \"#FFEEDDAA\": \"Creamy Ivory\", \"#FFFFF0B2\": \"Creamy Lemon\", \"#FFDCCAD8\": \"Creamy Mauve\", \"#FFAAFFAA\": \"Creamy Mint\", \"#FF988374\": \"Creamy Mocha\", \"#FFCABDAE\": \"Creamy Mushroom\", \"#FFD4B88F\": \"Creamy Nougat\", \"#FFFFE0AF\": \"Creamy Oat\", \"#FFFCE9D1\": \"Creamy Orange\", \"#FFFE9C7B\": \"Creamy Orange Blush\", \"#FFF4A384\": \"Creamy Peach\", \"#FFB2BFA6\": \"Creamy Spinach\", \"#FFCAC990\": \"Creamy Spinaci\", \"#FFFCD2DF\": \"Creamy Strawberry\", \"#FFFFFBB0\": \"Creamy Sunshine Pastel\", \"#FFF7C34C\": \"Creamy Sweet Corn\", \"#FFF2E5BF\": \"Creamy Vanilla\", \"#FFF0E9D6\": \"Creamy White\", \"#FF7A6D44\": \"Crease\", \"#FFC9CABF\": \"Create\", \"#FFDCBA42\": \"Credo\", \"#FFC1A44A\": \"Creed\", \"#FFAB9D89\": \"Creek Bay\", \"#FF928C87\": \"Creek Bend\", \"#FFDBD7D9\": \"Creek Pebble\", \"#FFB48AC2\": \"Creeping Bellflower\", \"#FFC16104\": \"Crema\", \"#FFFFFFB6\": \"Cr\\u00e8me\", \"#FFF8EDE2\": \"Creme Angels\", \"#FFFFE39B\": \"Cr\\u00e8me Br\\u00fbl\\u00e9e\", \"#FFD4B38F\": \"Cr\\u00e8me de Caramel\", \"#FFF3E7B4\": \"Cr\\u00e8me de la Cr\\u00e8me\", \"#FFF1FDE9\": \"Cr\\u00e8me de Menthe\", \"#FFFDF5E0\": \"Cr\\u00e8me de P\\u00eache\", \"#FFECEEE6\": \"Cr\\u00e8me Fra\\u00eeche\", \"#FFFDD77A\": \"Cr\\u00e8me P\\u00e2tissi\\u00e8re\", \"#FFF1F0E0\": \"Cr\\u00e8me Vanille\", \"#FFCFA33B\": \"Cremini\", \"#FFF0E2C4\": \"Cremini Mushroom\", \"#FF393227\": \"Creole Variant\", \"#FFE7B89A\": \"Creole Cottage\", \"#FFC69B4E\": \"Creole Mustard\", \"#FFF5D6CC\": \"Creole Pink\", \"#FFEE8833\": \"Creole Sauce\", \"#FFD4BC94\": \"Crepe\", \"#FFE399CA\": \"Crepe Myrtle\", \"#FFDBD7C4\": \"Cr\\u00eape Papier\", \"#FFF0EEE3\": \"Crepe Silk White\", \"#FFCABEAE\": \"Crepey Chest\", \"#FFE7DCCE\": \"Crepuscular\", \"#FFE3DF84\": \"Crescendo\", \"#FFEDD1B1\": \"Crescent Cream\", \"#FFF1E9CF\": \"Crescent Moon\", \"#FFBCA949\": \"Cress Green\", \"#FFBCB58A\": \"Cress Vinaigrette\", \"#FF8AAE7C\": \"Cressida\", \"#FF77A7A9\": \"Cresting Waves\", \"#FFB4BCBF\": \"Crestline\", \"#FF598784\": \"Cretan Green\", \"#FF96908B\": \"Crete Shore\", \"#FFCBB99B\": \"Crewel Tan\", \"#FFE4D5BC\": \"Cria Wool\", \"#FFA6A081\": \"Cricket\", \"#FFC7C10C\": \"Cricket Chirping\", \"#FFC3D29C\": \"Cricket Field\", \"#FF6A7B6B\": \"Cricket Green\", \"#FF908A78\": \"Cricket\\u2019s Cross\", \"#FFE2CDB1\": \"Crimini Mushroom\", \"#FF8C000F\": \"Crimson Variant\", \"#FFAD3D1E\": \"Crimson Blaze\", \"#FFB44933\": \"Crimson Boy\", \"#FFC32F40\": \"Crimson Cloud\", \"#FF982531\": \"Crimson Garland\", \"#FFC13939\": \"Crimson Glow\", \"#FF980001\": \"Crimson Red\", \"#FF9A2B43\": \"Crimson Shadows\", \"#FFB5413B\": \"Crimson Silk\", \"#FF9F2D47\": \"Crimson Strawberry\", \"#FFC01B0C\": \"Crimson Sunset\", \"#FFB53111\": \"Crimson Sword\", \"#FFB52604\": \"Crimson Velvet Sunset\", \"#FFB35138\": \"Crimson Warrior\", \"#FFBB2222\": \"Crisis Red\", \"#FFF4EBD0\": \"Crisp Candlelight\", \"#FF5D6E3B\": \"Crisp Capsicum\", \"#FFCDCCA6\": \"Crisp Celery\", \"#FFA6080E\": \"Crisp Christmas Cranberries\", \"#FFB1C8D2\": \"Crisp Collar\", \"#FFF4F0E7\": \"Crisp Cotton\", \"#FF22FFFF\": \"Crisp Cyan\", \"#FF729EB9\": \"Crisp French Blue\", \"#FFABC43A\": \"Crisp Green\", \"#FF4F9785\": \"Crisp Lettuce\", \"#FFE7E1D3\": \"Crisp Linen\", \"#FFE9E2D7\": \"Crisp Muslin\", \"#FFF3DCC6\": \"Crisp Wonton\", \"#FFE7DFC1\": \"Crispa\", \"#FFE2BD67\": \"Crisps\", \"#FFDDAA44\": \"Crispy Chicken Skin\", \"#FF7A8F68\": \"Crispy Crunch\", \"#FFEBE0CF\": \"Crispy Crust\", \"#FFBB7838\": \"Crispy Gingersnap\", \"#FFC49832\": \"Crispy Gold\", \"#FFFFBB66\": \"Crispy Samosa\", \"#FFB1A685\": \"Crocker Grove\", \"#FFA49887\": \"Crockery\", \"#FF706950\": \"Crocodile Variant\", \"#FFCADABD\": \"Crocodile Dreams\", \"#FF777722\": \"Crocodile Eye\", \"#FFB7AC87\": \"Crocodile Green\", \"#FF898E58\": \"Crocodile Smile\", \"#FF767437\": \"Crocodile Style\", \"#FFD6D69B\": \"Crocodile Tears\", \"#FFD1CCC2\": \"Crocodile Tooth\", \"#FFC071A8\": \"Crocus\", \"#FFB99BC5\": \"Crocus Petal\", \"#FFFDF1C7\": \"Crocus Tint\", \"#FFC4AB86\": \"Croissant\", \"#FFF8EFD8\": \"Croissant Crumbs\", \"#FFD69F60\": \"Cronut\", \"#FF797869\": \"Crooked River\", \"#FFE9BF63\": \"Crop Circle\", \"#FF5C7B97\": \"Cropper Blue\", \"#FFAC9877\": \"Croque Monsieur\", \"#FF4971AD\": \"Croquet Blue\", \"#FFA5A080\": \"Cross Country\", \"#FFAD2A2D\": \"Cross My Heart\", \"#FF60543F\": \"Crossbow\", \"#FFDDB596\": \"Crossed Fingers\", \"#FFEDD2A3\": \"Crossroads\", \"#FF180614\": \"Crow\", \"#FF263145\": \"Crow Black\", \"#FF112F4B\": \"Crow Black Blue\", \"#FF102329\": \"Crow Feather\", \"#FF220055\": \"Crowberry\", \"#FF003447\": \"Crowberry Blue\", \"#FF5B4459\": \"Crowd Pleaser\", \"#FF484E68\": \"Crown Blue\", \"#FF701DCE\": \"Crown Chakra\", \"#FFB48C60\": \"Crown Gold\", \"#FF946DAD\": \"Crown Jewels\", \"#FFA1A9A9\": \"Crown of Ash\", \"#FFD8B411\": \"Crown of Liechtenstein\", \"#FF763C33\": \"Crown of Thorns Variant\", \"#FFFFF0C1\": \"Crown Point Cream\", \"#FFD4B597\": \"Crowned One\", \"#FF5A4F6C\": \"Crowning\", \"#FF555B59\": \"Crucible\", \"#FFCC0044\": \"Crucified Red\", \"#FF21C40E\": \"Crude Banana\", \"#FFEE2288\": \"Cruel Jewel\", \"#FFDD3344\": \"Cruel Ruby\", \"#FF213638\": \"Cruel Sea\", \"#FFB4E2D5\": \"Cruise Variant\", \"#FF018498\": \"Cruising\", \"#FFEFCEA0\": \"Crumble Topping\", \"#FFA38565\": \"Crumbling Cork\", \"#FFCABFB4\": \"Crumbling Statue\", \"#FFEE66BB\": \"Crumbly Lipstick\", \"#FFF2B95F\": \"Crunch\", \"#FF997A5A\": \"Crunch Granola\", \"#FFEA5013\": \"Crunchy Carrot\", \"#FFDBC364\": \"Crusade King\", \"#FFD4CAC5\": \"Crushed Almond\", \"#FFD15B9B\": \"Crushed Berries\", \"#FF83515B\": \"Crushed Berry\", \"#FFFFEDD5\": \"Crushed Cashew\", \"#FFB7735E\": \"Crushed Cinnamon\", \"#FFAE7F71\": \"Crushed Clay\", \"#FF835A88\": \"Crushed Grape\", \"#FFF5A497\": \"Crushed Grapefruit\", \"#FFC4FFF7\": \"Crushed Ice\", \"#FFD6DDD3\": \"Crushed Limestone\", \"#FFD6B694\": \"Crushed Nutmeg\", \"#FFE37730\": \"Crushed Orange\", \"#FF635D46\": \"Crushed Oregano\", \"#FFE0CFC8\": \"Crushed Out\", \"#FFE4DDD8\": \"Crushed Peony\", \"#FFEFCC44\": \"Crushed Pineapple\", \"#FFB06880\": \"Crushed Raspberry\", \"#FFD8CFBE\": \"Crushed Silk\", \"#FFBCAA9F\": \"Crushed Stone\", \"#FF445397\": \"Crushed Velvet\", \"#FF673C4C\": \"Crushed Violets\", \"#FF165B31\": \"Crusoe Variant\", \"#FF898076\": \"Crust\", \"#FFF38653\": \"Crusta Variant\", \"#FFC04E01\": \"Crustose Lichen\", \"#FFC3D4E7\": \"Cry Baby Blue\", \"#FF427898\": \"Cry Me a River\", \"#FFB23C5D\": \"Cry of a Rose\", \"#FFDDECE0\": \"Cryo Freeze\", \"#FF373B40\": \"Crypt\", \"#FF6D434E\": \"Cryptic Light\", \"#FFFFE314\": \"Crypto Gold\", \"#FFA7D8DE\": \"Crystal\", \"#FFCEE9A0\": \"Crystal Apple\", \"#FFA1D4D1\": \"Crystal Aqua\", \"#FF365955\": \"Crystal Ball\", \"#FFDBE2E7\": \"Crystal Bay\", \"#FFEFEEEF\": \"Crystal Bell\", \"#FF68A0B0\": \"Crystal Blue\", \"#FFE4E6DC\": \"Crystal Brooke\", \"#FFF4E9EA\": \"Crystal Clear\", \"#FFFCCDC1\": \"Crystal Coral\", \"#FFF8F4ED\": \"Crystal Cut\", \"#FF6D2C32\": \"Crystal Dark Red\", \"#FFE1E6F2\": \"Crystal Falls\", \"#FF79D0A7\": \"Crystal Gem\", \"#FFDDFFEE\": \"Crystal Glass\", \"#FFA4D579\": \"Crystal Green\", \"#FFCFC1B8\": \"Crystal Grey\", \"#FFE7E2D6\": \"Crystal Haze\", \"#FF88B5C4\": \"Crystal Lake\", \"#FFA9A3A4\": \"Crystal Noir\", \"#FFAFC7BF\": \"Crystal Oasis\", \"#FFD3CFAB\": \"Crystal Palace\", \"#FFE8C3BF\": \"Crystal Pink\", \"#FFB2E4D0\": \"Crystal Rapids\", \"#FFB1E2EE\": \"Crystal River\", \"#FFFDC3C6\": \"Crystal Rose\", \"#FFD9E5DD\": \"Crystal Salt White\", \"#FF5DAFCE\": \"Crystal Seas\", \"#FF006E81\": \"Crystal Teal\", \"#FFB4CEDF\": \"Crystal Waters\", \"#FFE4D99F\": \"Crystal Yellow\", \"#FFE9E3DE\": \"Crystalline\", \"#FFD9E6E2\": \"Crystalline Falls\", \"#FFDEBBBF\": \"Crystalline Pink\", \"#FFECDFDF\": \"Crystallise\", \"#FF4FB3B3\": \"Crystalsong Blue\", \"#FF6E5C4B\": \"Cub\", \"#FF4E6341\": \"Cub Scout\", \"#FF623D3D\": \"Cuba Brown\", \"#FF73383C\": \"Cuba Libre\", \"#FF927247\": \"Cuban Cigar\", \"#FFC76D6B\": \"Cuban Plaza\", \"#FF9B555D\": \"Cuban Rhythm\", \"#FFBC9B83\": \"Cuban Sand\", \"#FFB2B6BE\": \"Cube Farm\", \"#FFBBDD11\": \"Cucumber Bomber\", \"#FFE4EBB1\": \"Cucumber Cream\", \"#FFA2AC86\": \"Cucumber Crush\", \"#FF466353\": \"Cucumber Green\", \"#FFCDD79D\": \"Cucumber Ice\", \"#FFC2F177\": \"Cucumber Milk\", \"#FF3C773C\": \"Cucumber Queen\", \"#FF9BA373\": \"Cucuzza Verde\", \"#FFBCCAE8\": \"Cuddle\", \"#FFC1E0BE\": \"Cuddle Bug\", \"#FFEFEFE6\": \"Cuddle Down\", \"#FFAD8068\": \"Cuddlepot\", \"#FFFFFCE4\": \"Cuddly Yarn\", \"#FF7BB6C1\": \"Culinary Blue\", \"#FFE69B3A\": \"Culpeo\", \"#FF331233\": \"Cultist Robe\", \"#FFF6F4F5\": \"Cultured\", \"#FFE5DCD6\": \"Cultured Pearl\", \"#FFE5867B\": \"Cultured Rose\", \"#FFDADBDF\": \"Cumberland Fog\", \"#FF68655D\": \"Cumberland Grey\", \"#FFE5DFDC\": \"Cumberland Sausage\", \"#FFA58459\": \"Cumin Variant\", \"#FFA06600\": \"Cumin Ochre\", \"#FF695A45\": \"Cummings Oak\", \"#FFF19B7D\": \"Cumquat Cream\", \"#FFF3F3E6\": \"Cumulus Variant\", \"#FFB0C6DF\": \"Cumulus Cloud\", \"#FFFEDD7D\": \"Cup Noodles\", \"#FFBAA087\": \"Cup of Cocoa\", \"#FFCAAE7B\": \"Cup of Tea\", \"#FF8A6E53\": \"Cupcake\", \"#FFE6C7B7\": \"Cupcake Rose\", \"#FFF5B2C5\": \"Cupid Variant\", \"#FFEE6B8B\": \"Cupid\\u2019s Arrow\", \"#FFFF22DD\": \"Cupid\\u2019s Eye\", \"#FFEEDCDF\": \"Cupid\\u2019s Revenge\", \"#FF406040\": \"Cupidity\", \"#FFDCBC8E\": \"Cupola Yellow\", \"#FFB09F8F\": \"Cuppa Coffee\", \"#FFB89871\": \"Cuppa Tea\", \"#FF008894\": \"Cura\\u00e7ao Blue\", \"#FFA6A6B6\": \"Curated Lilac\", \"#FFEAE1CE\": \"Curated White\", \"#FFF8E1BA\": \"Curd\", \"#FFBCA483\": \"Curds and Whey\", \"#FFAA6988\": \"Cure All\", \"#FF380835\": \"Cured Eggplant\", \"#FFD3D8D2\": \"Curio\", \"#FF988977\": \"Curio Brown\", \"#FFD9E49E\": \"Curious\", \"#FF3D85B8\": \"Curious Blue Variant\", \"#FFDABFA4\": \"Curious Chipmunk\", \"#FFD2BB98\": \"Curious Collection\", \"#FF766859\": \"Curlew\", \"#FF9C9D76\": \"Curly Grass\", \"#FFD8C8BE\": \"Curly Maple\", \"#FFB1A387\": \"Curly Willow\", \"#FF884A50\": \"Currant Jam\", \"#FF553E51\": \"Currant Violet\", \"#FFD6A332\": \"Curry\", \"#FF845038\": \"Curry Brown\", \"#FFF5B700\": \"Curry Bubbles\", \"#FFBE9E6F\": \"Curry Sauce\", \"#FFDDAA33\": \"Currywurst\", \"#FF131313\": \"Cursed Black\", \"#FF70666A\": \"Curtain Call\", \"#FFFFD6B8\": \"Curtsy\", \"#FFC1C8AF\": \"Cushion Bush\", \"#FFFFFD78\": \"Custard\", \"#FFFBEFD0\": \"Custard Cream\", \"#FFF8DCAA\": \"Custard Powder\", \"#FFFCEEAE\": \"Custard Puff\", \"#FF003839\": \"Customs Green\", \"#FF9E909E\": \"Cut Heather\", \"#FFA01C2D\": \"Cut Ruby\", \"#FFBA7F38\": \"Cut the Mustard\", \"#FFB391C8\": \"Cut Velvet\", \"#FFDD4444\": \"Cute Crab\", \"#FFF4E2E1\": \"Cute Little Pink\", \"#FF8D8D40\": \"Cute Pixie\", \"#FFE3A49A\": \"Cuticle Pink\", \"#FFF4DDA5\": \"Cutlery Polish\", \"#FF7FBBC2\": \"Cuttlefish\", \"#FF5C8173\": \"Cutty Sark Variant\", \"#FF4E82B4\": \"Cyan Azure\", \"#FF14A3C7\": \"Cyan Blue\", \"#FF28589C\": \"Cyan Cobalt Blue\", \"#FF188BC2\": \"Cyan Cornflower Blue\", \"#FF00B5B8\": \"Cyan Sky\", \"#FF779080\": \"Cyanara\", \"#FF001F33\": \"Cyanophobia\", \"#FF77C9C2\": \"Cyantific\", \"#FF00FF26\": \"Cyber Neon Green\", \"#FFFFD400\": \"Cyber Yellow\", \"#FFFF2077\": \"Cyberpink\", \"#FF44484D\": \"Cyberspace\", \"#FFD687BA\": \"Cyclamen Variant\", \"#FFA7598D\": \"Cyclamen Red\", \"#FFF3E4A7\": \"Cymophane Yellow\", \"#FF171717\": \"Cynical Black\", \"#FF585D40\": \"Cypress\", \"#FF6F3028\": \"Cypress Bark Red\", \"#FF667C71\": \"Cypress Garden\", \"#FF9E8F57\": \"Cypress Green\", \"#FF6A7786\": \"Cypress Grey Blue\", \"#FF5E6552\": \"Cypress Vine\", \"#FF0F4645\": \"Cyprus Variant\", \"#FF699A88\": \"Cyprus Green\", \"#FFACB7B0\": \"Cyprus Spring\", \"#FFCFC5A7\": \"Cyrus Grass\", \"#FF775859\": \"Czarina\", \"#FFDEC9A9\": \"Czech Bakery\", \"#FF030764\": \"D. Darx Blue\", \"#FF516172\": \"Da Blues\", \"#FFAA6179\": \"Daah-Ling\", \"#FF7E553E\": \"Dachshund\", \"#FF2F484E\": \"Dad\\u2019s Coupe\", \"#FFD3C1A0\": \"Dad\\u2019s Slippers\", \"#FFB0AF8A\": \"Daddy-O\", \"#FF696684\": \"Daemonette Hide\", \"#FFFFE285\": \"Daffodil Yellow\", \"#FFE8E1D5\": \"Dagger Moth\", \"#FF8B4189\": \"Dahlia\", \"#FFF8BBD3\": \"Dahlia Delight\", \"#FF765067\": \"Dahlia Matte Red\", \"#FFB05988\": \"Dahlia Mauve\", \"#FF8774B0\": \"Dahlia Purple\", \"#FFD4D4C4\": \"Daikon White\", \"#FFFDC592\": \"Dainty Apricot\", \"#FFF5DD9D\": \"Dainty Daisy\", \"#FFF4BDB3\": \"Dainty Debutante\", \"#FFE9DFE5\": \"Dainty Flower\", \"#FFDECFBB\": \"Dainty Lace\", \"#FFFFCDB9\": \"Dainty Peach\", \"#FFECBCCE\": \"Dainty Pink\", \"#FFC6D26E\": \"Daiquiri Green\", \"#FFF4E7D4\": \"Dairy Belle\", \"#FFEDD2A4\": \"Dairy Cream Variant\", \"#FFF0B33C\": \"Dairy Made\", \"#FFFED340\": \"Daisy\", \"#FF5B3E90\": \"Daisy Bush Variant\", \"#FFFFF09B\": \"Daisy Chain\", \"#FFFCDF8A\": \"Daisy Desi\", \"#FFF4F3E8\": \"Daisy Field\", \"#FF55643B\": \"Daisy Leaf\", \"#FFF8F3E3\": \"Daisy White\", \"#FFD3C29D\": \"Dakota Trail\", \"#FFE1BD8E\": \"Dakota Wheat\", \"#FF664A2D\": \"Dallas Variant\", \"#FFECE0D6\": \"Dallas Dust\", \"#FFFDDC00\": \"Dallol Yellow\", \"#FF97A3DA\": \"Dalmatian Sage\", \"#FFAFDADF\": \"Daly Waters\", \"#FF996D32\": \"Damascene\", \"#FFFCF2DF\": \"Damask\", \"#FFD1B3A9\": \"Damask Dunes\", \"#FF999BA8\": \"Dame Dignity\", \"#FF5F6171\": \"Damp Basement\", \"#FF4A4747\": \"Dampened Black\", \"#FFC69EAE\": \"Damsel\", \"#FF854C65\": \"Damson\", \"#FF583563\": \"Damson Mauve\", \"#FF576780\": \"Dana\", \"#FFE6D8CD\": \"Dance of the Goddesses\", \"#FF064D83\": \"Dance Studio\", \"#FFD7CBAC\": \"Dance With the Wind\", \"#FFDC9399\": \"Dancer\", \"#FF94734C\": \"Dancing Bear\", \"#FFFCF3C6\": \"Dancing Butterfly\", \"#FF254A47\": \"Dancing Crocodiles\", \"#FFEFC857\": \"Dancing Daisy\", \"#FF6E493D\": \"Dancing Dogs\", \"#FFC4BAA1\": \"Dancing Dolphin\", \"#FF006658\": \"Dancing Dragonfly\", \"#FFC5CD8F\": \"Dancing Green\", \"#FFABC5D6\": \"Dancing in the Rain\", \"#FF7B7289\": \"Dancing in the Spring\", \"#FF429B77\": \"Dancing Jewel\", \"#FFC8CC9E\": \"Dancing Kite\", \"#FFBFC8D8\": \"Dancing Mist\", \"#FF016459\": \"Dancing Peacock\", \"#FF1C4D8F\": \"Dancing Sea\", \"#FFC8A4BD\": \"Dancing Wand\", \"#FFFEDF08\": \"Dandelion Variant\", \"#FFEAE8EC\": \"Dandelion Floatie\", \"#FFF7EAC1\": \"Dandelion Tea\", \"#FFF0E130\": \"Dandelion Tincture\", \"#FFFFF0B5\": \"Dandelion Whisper\", \"#FFFCF2B9\": \"Dandelion Wine\", \"#FFE3BB65\": \"Dandelion Wish\", \"#FFFCD93B\": \"Dandelion Yellow\", \"#FFFACC51\": \"Dandy Lion\", \"#FFFF0E0E\": \"Danger\", \"#FF595539\": \"Danger Ridge\", \"#FFD00220\": \"Dangerous Affair\", \"#FFCBC5C6\": \"Dangerous Robot\", \"#FF616B89\": \"Dangerously Elegant\", \"#FF16F12D\": \"Dangerously Green\", \"#FFD84139\": \"Dangerously Red\", \"#FF5E4235\": \"Daniel Boone\", \"#FFBA9967\": \"Danish Pine\", \"#FFB4D5D5\": \"Dante Peak\", \"#FF5B89C0\": \"Danube Variant\", \"#FF116DB1\": \"Daphne\", \"#FF715B49\": \"Dapper\", \"#FFE2C299\": \"Dapper Dingo\", \"#FF697078\": \"Dapper Greyhound\", \"#FF947F65\": \"Dapper Tan\", \"#FF959486\": \"Dapple Grey\", \"#FFC5CC9F\": \"Dappled Daydream\", \"#FFF2E3C9\": \"Dappled Sunlight\", \"#FF3A4A3F\": \"Dard Hunter Green\", \"#FFAB4343\": \"Daredevil\", \"#FFDF644E\": \"Daring\", \"#FFF0DFE0\": \"Daring Deception\", \"#FF374874\": \"Daring Indigo\", \"#FF1B2431\": \"Dark\", \"#FF353F51\": \"Dark & Stormy\", \"#FF9698A3\": \"Dark Ages\", \"#FF4F5A62\": \"Dark and Stormy Night\", \"#FF495252\": \"Dark as Night\", \"#FF6A6D6D\": \"Dark Ash\", \"#FF5C464A\": \"Dark Berry\", \"#FF533958\": \"Dark Blackberry\", \"#FFA68A6E\": \"Dark Blond\", \"#FF315B7D\": \"Dark Blue Tint\", \"#FF92462F\": \"Dark Brazilian Topaz\", \"#FF4B4146\": \"Dark Burgundy Wine\", \"#FF513116\": \"Dark Catacombs\", \"#FF55504D\": \"Dark Cavern\", \"#FF333232\": \"Dark Charcoal\", \"#FF774D41\": \"Dark Cherry Mocha\", \"#FF624A49\": \"Dark Chocolate\", \"#FFAABB00\": \"Dark Citron\", \"#FF4C3D31\": \"Dark Clove\", \"#FF33578A\": \"Dark Cobalt Blue\", \"#FF843C41\": \"Dark Crimson\", \"#FF3F4551\": \"Dark Crypt\", \"#FF2F1212\": \"Dark Danger\", \"#FF005588\": \"Dark Denim\", \"#FF00334F\": \"Dark Denim Blue\", \"#FF5A3939\": \"Dark Drama\", \"#FF332266\": \"Dark Dreams\", \"#FF884455\": \"Dark Earth\", \"#FF3D2004\": \"Dark Ebony Variant\", \"#FF112244\": \"Dark Eclipse\", \"#FF3B3F42\": \"Dark Elf\", \"#FF00834E\": \"Dark Emerald\", \"#FF503D4D\": \"Dark Energy\", \"#FF3E3F41\": \"Dark Engine\", \"#FFA4A582\": \"Dark Envy\", \"#FF3E554F\": \"Dark Everglade\", \"#FF573B4C\": \"Dark Fig Violet\", \"#FF556962\": \"Dark Forest\", \"#FF4F443F\": \"Dark Granite\", \"#FF033500\": \"Dark Green Variant\", \"#FF363737\": \"Dark Grey Variant\", \"#FF4E4459\": \"Dark Grey Mauve\", \"#FF222429\": \"Dark Gunmetal\", \"#FF666699\": \"Dark Horizon\", \"#FF661122\": \"Dark Humour\", \"#FF4D5A7E\": \"Dark Iris\", \"#FF66856F\": \"Dark Ivy\", \"#FF5C8774\": \"Dark Jade\", \"#FF0B3021\": \"Dark Jungle\", \"#FF333438\": \"Dark Kettle Black\", \"#FF151931\": \"Dark Knight\", \"#FF6A7F7D\": \"Dark Lagoon\", \"#FF856798\": \"Dark Lavender Variant\", \"#FF8BBE1B\": \"Dark Lemon Lime\", \"#FF9C6DA5\": \"Dark Lilac\", \"#FF84B701\": \"Dark Lime\", \"#FF7EBD01\": \"Dark Lime Green\", \"#FF989A98\": \"Dark Limestone\", \"#FF5F574F\": \"Dark LUA Console\", \"#FF482029\": \"Dark Mahogany\", \"#FF994939\": \"Dark Marmalade\", \"#FF3C0008\": \"Dark Maroon\", \"#FF110101\": \"Dark Matter\", \"#FF003377\": \"Dark Midnight Blue\", \"#FF515763\": \"Dark Mineral\", \"#FF161718\": \"Dark Moon\", \"#FF40495B\": \"Dark Navy\", \"#FF404B57\": \"Dark Night\", \"#FF373E02\": \"Dark Olive\", \"#FF6E5160\": \"Dark Olive Paste\", \"#FF2E2D30\": \"Dark Onyx\", \"#FFC65102\": \"Dark Orange Variant\", \"#FF251B19\": \"Dark Orchestra\", \"#FF653D7C\": \"Dark Pansy\", \"#FF665FD1\": \"Dark Periwinkle\", \"#FF606865\": \"Dark Pewter\", \"#FF193232\": \"Dark Pine Green\", \"#FFCB416B\": \"Dark Pink Variant\", \"#FF603E53\": \"Dark Potion\", \"#FF6B6C89\": \"Dark Prince\", \"#FFD9308A\": \"Dark Princess Pink\", \"#FF2B0F2E\": \"Dark Prom Queen\", \"#FF4F3A3C\": \"Dark Puce\", \"#FF35063E\": \"Dark Purple\", \"#FF6E576B\": \"Dark Purple Grey\", \"#FF505838\": \"Dark Rainforest\", \"#FF3B5150\": \"Dark Reaper\", \"#FF840000\": \"Dark Red Variant\", \"#FF4A2125\": \"Dark Red Brown\", \"#FF434257\": \"Dark Renaissance\", \"#FF060B14\": \"Dark Rift\", \"#FF3E4445\": \"Dark River\", \"#FF4A2D2F\": \"Dark Roast\", \"#FFB5485D\": \"Dark Rose\", \"#FF02066F\": \"Dark Royalty\", \"#FF45362B\": \"Dark Rum\", \"#FF6D765B\": \"Dark Sage\", \"#FFA2646F\": \"Dark Sakura\", \"#FFC85A53\": \"Dark Salmon Variant\", \"#FFE8957A\": \"Dark Salmon Injustice\", \"#FF3F012C\": \"Dark Sanctuary\", \"#FFA88F59\": \"Dark Sand\", \"#FF4C5560\": \"Dark Sea\", \"#FF666655\": \"Dark Seagreen\", \"#FF113691\": \"Dark Seashore Night\", \"#FF3E5361\": \"Dark Secret\", \"#FF113311\": \"Dark Serpent\", \"#FF4A4B4D\": \"Dark Shadow\", \"#FF004444\": \"Dark Side\", \"#FF070D0D\": \"Dark Side of the Moon\", \"#FF909989\": \"Dark Sky\", \"#FF465352\": \"Dark Slate\", \"#FF214761\": \"Dark Slate Blue Variant\", \"#FF66AA11\": \"Dark Slimelime\", \"#FF4D52DE\": \"Dark Soft Violet\", \"#FF587A65\": \"Dark Sorrel\", \"#FF112255\": \"Dark Soul\", \"#FF414A4C\": \"Dark Space\", \"#FF303B4C\": \"Dark Spell\", \"#FF7E736D\": \"Dark Sting\", \"#FF819094\": \"Dark Storm Cloud\", \"#FF80444C\": \"Dark Strawberry\", \"#FF383839\": \"Dark Summoning\", \"#FF483C3C\": \"Dark Taupe\", \"#FF634E43\": \"Dark Tavern\", \"#FF014D4E\": \"Dark Teal\", \"#FF97765C\": \"Dark Toast\", \"#FF121212\": \"Dark Tone Ink\", \"#FF817C87\": \"Dark Topaz\", \"#FF594D46\": \"Dark Truffle\", \"#FF045C5A\": \"Dark Turquoise Variant\", \"#FF0D2B52\": \"Dark Tyrian Blue\", \"#FF932904\": \"Dark Umber\", \"#FF141311\": \"Dark Veil\", \"#FF34013F\": \"Dark Violet Variant\", \"#FF151517\": \"Dark Void\", \"#FF56443E\": \"Dark Walnut\", \"#FF855E42\": \"Dark Wood\", \"#FF4F301F\": \"Dark Wood Grain\", \"#FFE7BF8E\": \"Dark Yellow\", \"#FF660011\": \"Darkest Dungeon\", \"#FF223311\": \"Darkest Forest\", \"#FF625768\": \"Darkest Grape\", \"#FF43455E\": \"Darkest Navy\", \"#FF303F3D\": \"Darkest Spruce\", \"#FF16160E\": \"Darkness\", \"#FF3A4645\": \"Darkness Green\", \"#FF2D1608\": \"Darkout\", \"#FF2F1611\": \"Darkroom\", \"#FF464964\": \"Darkshore\", \"#FF4F4969\": \"Darlak\", \"#FFFF88FF\": \"Darling Bud\", \"#FFD29F7A\": \"Darling Clementine\", \"#FFC9ACD6\": \"Darling Lilac\", \"#FF1D045D\": \"Darth Torus\", \"#FF27252A\": \"Darth Vader\", \"#FFCDDCE3\": \"Dartmoor Mist\", \"#FF00703C\": \"Dartmouth Green Variant\", \"#FFCA6E5F\": \"Dash of Curry\", \"#FF928459\": \"Dash of Oregano\", \"#FFFBD2CF\": \"Dash of Pink\", \"#FFEAEBE8\": \"Dashing\", \"#FF0BDB43\": \"Dasyphyllous Green\", \"#FFAF642B\": \"Date Fruit Brown\", \"#FFCCAC86\": \"DaVanzo Beige\", \"#FF58936D\": \"DaVanzo Green\", \"#FF6C4226\": \"Davao Durian\", \"#FFB1D27B\": \"Davao Green\", \"#FF535554\": \"Davy\\u2019s Grey\", \"#FF9F9D91\": \"Dawn Variant\", \"#FFCACCCB\": \"Dawn Blue\", \"#FFCCFFFF\": \"Dawn Departs\", \"#FFFADFA9\": \"Dawn Light\", \"#FF770044\": \"Dawn of the Fairies\", \"#FFFEDFDC\": \"Dawn Patrol\", \"#FFE6D6CD\": \"Dawn Pink Variant\", \"#FFC9CED3\": \"Dawn\\u2019s Early Light\", \"#FF70756E\": \"Dawnstone\", \"#FFFFA373\": \"Day at the Zoo\", \"#FFD9CDC4\": \"Day Dreamer\", \"#FFEADD82\": \"Day Glow\", \"#FFEB5C34\": \"Day Glow Orange\", \"#FFFFF9EC\": \"Day Lily\", \"#FFD5D2D1\": \"Day on Mercury\", \"#FFEAEFED\": \"Day Spa\", \"#FF7E7597\": \"Daybreak\", \"#FFC7C9D8\": \"Daybreak Beckons\", \"#FFF7EECB\": \"Daybreak Sun\", \"#FFE3EBAE\": \"Daydream\", \"#FFF4F0E1\": \"Daydreaming\", \"#FF38A1DB\": \"Dayflower\", \"#FF758CBF\": \"Dayflower Blue\", \"#FF546C52\": \"Daylight Jungle\", \"#FFA385B3\": \"Daylight Lilac\", \"#FFF8F0D2\": \"Daylily Yellow\", \"#FFFFF8DA\": \"Daystar\", \"#FF5287B9\": \"Dazzle\", \"#FFD99B7B\": \"Dazzle and Delight\", \"#FFEDEBEA\": \"Dazzle Me\", \"#FF3850A0\": \"Dazzling Blue\", \"#FFD82C0D\": \"Dazzling Red\", \"#FF85CA87\": \"De York Variant\", \"#FF99DEAD\": \"Dead 99\", \"#FF0055CC\": \"Dead Blue Eyes\", \"#FF434B4F\": \"Dead Forest\", \"#FFE4DC8A\": \"Dead Grass\", \"#FF2E5A88\": \"Dead Lake\", \"#FFD2DAD0\": \"Dead Nettle White\", \"#FF3B3A3A\": \"Dead Pixel\", \"#FF77EEEE\": \"Dead Sea\", \"#FF3A403B\": \"Dead Sea Mud\", \"#FF8F666A\": \"Deadlock\", \"#FF111144\": \"Deadly Depths\", \"#FFDEAD11\": \"Deadly Mustard\", \"#FFC2A84B\": \"Deadsy\", \"#FF596D7F\": \"Deadwind Pass\", \"#FFA30112\": \"Dear Darling\", \"#FFFEECB3\": \"Dear Melissa\", \"#FFF5F3E6\": \"Dear Reader\", \"#FF60443F\": \"Death by Chocolate\", \"#FFE7D9DB\": \"Death Cap\", \"#FF9EB37B\": \"Death Guard\", \"#FF141313\": \"Death Metal\", \"#FFE760D2\": \"Death of a Star\", \"#FFDDBB88\": \"Death Valley Beige\", \"#FFB36853\": \"Deathclaw Brown\", \"#FF5C6730\": \"Deathworld Forest\", \"#FFAF9294\": \"Deauville Mauve\", \"#FF90A0A6\": \"Debonair\", \"#FFCBD0DD\": \"Debonaire\", \"#FFEE7744\": \"Debrito\", \"#FFED7468\": \"Debutante\", \"#FF6E8DBB\": \"Debutante Ball\", \"#FF73667B\": \"Decadence\", \"#FF513233\": \"Decadent Chocolate\", \"#FF8D3630\": \"Decadent Red\", \"#FFDECADE\": \"Decadial Pink\", \"#FFADA3BB\": \"Decanter\", \"#FFBFA1AD\": \"Decanting\", \"#FFD57835\": \"Decaying Leaf\", \"#FFDFE2EA\": \"December Dawn\", \"#FF415064\": \"December Eve\", \"#FFE0E8DB\": \"December Forest\", \"#FFD6DDDC\": \"December Rain\", \"#FFD5D7D9\": \"December Sky\", \"#FF9DCEE3\": \"December Solstice\", \"#FFBFB5CA\": \"Decency\", \"#FFB69FCC\": \"Dechala Lilac\", \"#FFD79E62\": \"Dechant Pear Yellow\", \"#FFFDCC4E\": \"Decisive Yellow\", \"#FF5E7CAC\": \"Deck Crew\", \"#FFCCCF82\": \"Deco Variant\", \"#FF89978E\": \"Deco Grey\", \"#FFF6C2CC\": \"Deco Pink\", \"#FF824942\": \"Deco Red\", \"#FF9E6370\": \"Deco Rose\", \"#FFF9D5C9\": \"Deco Shell\", \"#FF8FCBC0\": \"Deco-Rate\", \"#FF7B736B\": \"Deconstruction\", \"#FFF2E5CF\": \"D\\u00e9cor White\", \"#FFF6BB00\": \"Decor Yellow\", \"#FF3F74A3\": \"Decoration Blue\", \"#FF817181\": \"Decorative Iris\", \"#FFF6F4EC\": \"Decorator White\", \"#FF00829E\": \"Decore Splash\", \"#FFAC7559\": \"Decorous Amber\", \"#FFB39AA0\": \"Decorum\", \"#FFFEE2C8\": \"Dedication\", \"#FFD4CB83\": \"Deduction\", \"#FF5B3082\": \"Deep Amethyst\", \"#FF78DBE2\": \"Deep Aquamarine\", \"#FF004F57\": \"Deep Atlantic Blue\", \"#FF5C4A4D\": \"Deep Aubergine\", \"#FF3E5580\": \"Deep Azure\", \"#FFD99F50\": \"Deep Bamboo Yellow\", \"#FFC57776\": \"Deep Bloom\", \"#FF040273\": \"Deep Blue Variant\", \"#FF1A5D72\": \"Deep Blue Sea\", \"#FFE36F8A\": \"Deep Blush Variant\", \"#FF5E675A\": \"Deep Bottlebrush\", \"#FF27275F\": \"Deep Breath\", \"#FF51412D\": \"Deep Bronze Variant\", \"#FF342A2A\": \"Deep Brown\", \"#FF744456\": \"Deep Carmine Variant\", \"#FF007BBB\": \"Deep Cerulean Variant\", \"#FFFAD6C5\": \"Deep Champagne Variant\", \"#FF7A8790\": \"Deep Channel\", \"#FF6B473D\": \"Deep Cherrywood\", \"#FF771133\": \"Deep Claret\", \"#FFAE6A52\": \"Deep Clay Red\", \"#FF424769\": \"Deep Cobalt\", \"#FF7D4071\": \"Deep Commitment\", \"#FFDA7C55\": \"Deep Coral\", \"#FF007381\": \"Deep Current\", \"#FF322D2D\": \"Deep Daichi Black\", \"#FFE9E7E6\": \"Deep Daigi White\", \"#FF3311AA\": \"Deep Daijin Blue\", \"#FF7C2229\": \"Deep Dairei Red\", \"#FFF0CA00\": \"Deep Daishin Yellow\", \"#FF661177\": \"Deep Daitoku Purple\", \"#FF6688FF\": \"Deep Denim\", \"#FF545648\": \"Deep Depths\", \"#FF534C3E\": \"Deep Desert Shadow\", \"#FF2E5467\": \"Deep Dive\", \"#FF5E97A9\": \"Deep Diving\", \"#FF553D3A\": \"Deep Dungeon\", \"#FF4D4B4B\": \"Deep Earth\", \"#FF556551\": \"Deep Emerald\", \"#FF4C574B\": \"Deep Evergreen\", \"#FF614454\": \"Deep Exquisite\", \"#FF193925\": \"Deep Fir Variant\", \"#FFBF5C42\": \"Deep Fire\", \"#FF3C463E\": \"Deep Forest\", \"#FF393437\": \"Deep Forest Brown\", \"#FF335500\": \"Deep Forestial Escapade\", \"#FFF0B054\": \"Deep Fried\", \"#FFF6C75E\": \"Deep Fried Sunrays\", \"#FF414048\": \"Deep Galaxy\", \"#FF5A9274\": \"Deep Grass Green\", \"#FF02590F\": \"Deep Green\", \"#FF726A6E\": \"Deep Greige\", \"#FF4C567A\": \"Deep Indigo\", \"#FF306030\": \"Deep Into the Wood\", \"#FF3F564A\": \"Deep Jungle\", \"#FF343467\": \"Deep Koamaru Variant\", \"#FF005A6F\": \"Deep Lagoon\", \"#FF006C70\": \"Deep Lake\", \"#FF687189\": \"Deep Larkspur\", \"#FF565A7D\": \"Deep Lavender\", \"#FF747962\": \"Deep Lichen Green\", \"#FF2E5767\": \"Deep Loch\", \"#FFA0025C\": \"Deep Magenta Variant\", \"#FF634743\": \"Deep Mahogany\", \"#FF2E6469\": \"Deep Marine\", \"#FF623F45\": \"Deep Maroon\", \"#FF938565\": \"Deep Marsh\", \"#FF574958\": \"Deep Merlot\", \"#FF55AA66\": \"Deep Mint\", \"#FF3D4C46\": \"Deep Mooring\", \"#FF544954\": \"Deep Mulberry\", \"#FF494C59\": \"Deep Mystery\", \"#FF494C55\": \"Deep Night\", \"#FF2A4B5F\": \"Deep Ocean\", \"#FF2C4173\": \"Deep Ocean Floor\", \"#FFDC4D01\": \"Deep Orange\", \"#FF864735\": \"Deep Orange-Coloured Brown\", \"#FF525476\": \"Deep Orchid\", \"#FF006E62\": \"Deep Pacific\", \"#FF009286\": \"Deep Peacock Blue\", \"#FF7C83BC\": \"Deep Periwinkle\", \"#FF557138\": \"Deep Pine\", \"#FF4A2A59\": \"Deep Plum\", \"#FF014420\": \"Deep Pond\", \"#FF366D68\": \"Deep Pool Teal\", \"#FF36013F\": \"Deep Purple\", \"#FF9A0200\": \"Deep Red\", \"#FFBB603C\": \"Deep Reddish Orange\", \"#FF424F5F\": \"Deep Reservoir\", \"#FF7F5153\": \"Deep Rhubarb\", \"#FF4C6A68\": \"Deep Rift\", \"#FF0079B3\": \"Deep River\", \"#FF2D4243\": \"Deep River Green\", \"#FFB25550\": \"Deep Rose\", \"#FF364C68\": \"Deep Royal\", \"#FFFF9932\": \"Deep Saffron\", \"#FF195155\": \"Deep Sanction\", \"#FF082466\": \"Deep Sapphire Variant\", \"#FF167E65\": \"Deep Sea Variant\", \"#FF2C2C57\": \"Deep Sea Base\", \"#FF2A4B5A\": \"Deep Sea Blue\", \"#FFD86157\": \"Deep Sea Coral\", \"#FF376167\": \"Deep Sea Dive\", \"#FF255C61\": \"Deep Sea Diver\", \"#FF6A6873\": \"Deep Sea Dolphin\", \"#FF002D69\": \"Deep Sea Dream\", \"#FF2000B1\": \"Deep Sea Exploration\", \"#FF879293\": \"Deep Sea Grey\", \"#FF4F5A4C\": \"Deep Sea Shadow\", \"#FF5E5749\": \"Deep Sea Turtle\", \"#FF959889\": \"Deep Seagrass\", \"#FF37412A\": \"Deep Seaweed\", \"#FF7F6968\": \"Deep Serenity\", \"#FF514A3D\": \"Deep Shadow\", \"#FF737C84\": \"Deep Shale\", \"#FF0D75F8\": \"Deep Sky Blue Variant\", \"#FF0F261F\": \"Deep Slate Green\", \"#FF172713\": \"Deep Slate Olive\", \"#FF7D8392\": \"Deep Smoke Signal\", \"#FFB4989F\": \"Deep South\", \"#FF3F4143\": \"Deep Space\", \"#FF292E35\": \"Deep Space Echo\", \"#FF43363D\": \"Deep Space Frigate\", \"#FF332277\": \"Deep Space Rodeo\", \"#FF223382\": \"Deep Space Royal\", \"#FF726751\": \"Deep Tan\", \"#FF7B6660\": \"Deep Taupe\", \"#FF00555A\": \"Deep Teal Variant\", \"#FF8B483D\": \"Deep Terra Cotta\", \"#FF728787\": \"Deep Thoughts\", \"#FF01B0BD\": \"Deep Turquoise\", \"#FF375F71\": \"Deep Twilight Blue\", \"#FF404F95\": \"Deep Ultramarine\", \"#FF694D3D\": \"Deep Umber\", \"#FF017F9E\": \"Deep Universe\", \"#FF313248\": \"Deep Velvet\", \"#FF330066\": \"Deep Violet\", \"#FF4B6443\": \"Deep Viridian\", \"#FF615D58\": \"Deep Walnut\", \"#FF2A6FA1\": \"Deep Water\", \"#FF33313B\": \"Deep Well\", \"#FF444172\": \"Deep Wisteria\", \"#FF454669\": \"Deepest Fig\", \"#FF6D595A\": \"Deepest Mauve\", \"#FF44413C\": \"Deepest Nightmare\", \"#FF5C84B4\": \"Deepest Periwinkle\", \"#FF44534E\": \"Deepest River\", \"#FF444D56\": \"Deepest Sea\", \"#FF466174\": \"Deepest Water\", \"#FF6D4940\": \"Deeply Deanna\", \"#FFECB2B3\": \"Deeply Embarrassed\", \"#FF303F4C\": \"Deepsea Core\", \"#FF082599\": \"Deepsea Kraken\", \"#FFBA8759\": \"Deer\", \"#FF96847A\": \"Deer God\", \"#FFAC7434\": \"Deer Leather\", \"#FFB2A69A\": \"Deer Run\", \"#FFA1614C\": \"Deer Tracks\", \"#FF6A634C\": \"Deer Trail\", \"#FFC7A485\": \"Deer Valley\", \"#FF88FFEE\": \"Defence Matrix\", \"#FFC6D5E4\": \"Defenestration\", \"#FFB0C1C2\": \"Degas Blue\", \"#FFB37E8C\": \"Degas Pink\", \"#FF9CBCC6\": \"D\\u00e9j\\u00e0 Blue\", \"#FFBED1CC\": \"D\\u00e9j\\u00e0 Vu\", \"#FFB5998E\": \"Del Rio Variant\", \"#FFDABF92\": \"Del Sol Maize\", \"#FFAAB350\": \"Delaunay Green\", \"#FF76A09E\": \"Delaware Blue Hen\", \"#FFFDF901\": \"Delayed Yellow\", \"#FF9A92A7\": \"Delectable\", \"#FF3D5E8C\": \"Delft\", \"#FF3311EE\": \"Delft Blue\", \"#FFFDC1C5\": \"Delhi Dance Pink\", \"#FFA36A6D\": \"Delhi Spice\", \"#FFE8B523\": \"Deli Yellow\", \"#FFF5E3E2\": \"Delicacy\", \"#FFEBE2E5\": \"Delicacy White\", \"#FFC2D1E2\": \"Delicate Ballet Blue\", \"#FFEDE0D5\": \"Delicate Bliss\", \"#FFDBBFCE\": \"Delicate Bloom\", \"#FFBCDFE8\": \"Delicate Blue\", \"#FFBED7F0\": \"Delicate Blue Mist\", \"#FFEFD7D1\": \"Delicate Blush\", \"#FFA78C8B\": \"Delicate Brown\", \"#FFDDDFE8\": \"Delicate Cloud\", \"#FFE9EDC0\": \"Delicate Daisy\", \"#FFFED9BC\": \"Delicate Dawn\", \"#FFC5EAD3\": \"Delicate Frost\", \"#FF6AB2CA\": \"Delicate Girl Blue\", \"#FF93B0A9\": \"Delicate Green\", \"#FFBCAB99\": \"Delicate Honeysweet\", \"#FFB7D2E3\": \"Delicate Ice\", \"#FFF3E6D4\": \"Delicate Lace\", \"#FFEEDD77\": \"Delicate Lemon\", \"#FFB6AED6\": \"Delicate Lilac\", \"#FFD7D2E2\": \"Delicate Lilac Crystal\", \"#FFC5B5CA\": \"Delicate Mauve\", \"#FFDDF3E6\": \"Delicate Mint\", \"#FFE1EBE5\": \"Delicate Mist\", \"#FFE4CFD3\": \"Delicate Pink\", \"#FFEEC6C3\": \"Delicate Pink Rose\", \"#FFA95C68\": \"Delicate Prunus\", \"#FFF7E0D6\": \"Delicate Rose\", \"#FFD7F3DD\": \"Delicate Sapling\", \"#FFFFEFDD\": \"Delicate Seashell\", \"#FFD1E2D8\": \"Delicate Snow Goose\", \"#FFFDCDBD\": \"Delicate Sweet Apricot\", \"#FFAA9C8B\": \"Delicate Truffle\", \"#FFC0DFE2\": \"Delicate Turquoise\", \"#FFD7D6DC\": \"Delicate Viola\", \"#FF8C8DA8\": \"Delicate Violet\", \"#FFF1F2EE\": \"Delicate White\", \"#FF483B36\": \"Delicioso\", \"#FF585E46\": \"Delicious\", \"#FF654254\": \"Delicious Berry\", \"#FF77CC00\": \"Delicious Dill\", \"#FFFFAA11\": \"Delicious Mandarin\", \"#FFFFD7B0\": \"Delicious Melon\", \"#FF2E212D\": \"Delighted Chimp\", \"#FFD2B6BE\": \"Delightful\", \"#FFA5A943\": \"Delightful Camouflage\", \"#FFEEEE33\": \"Delightful Dandelion\", \"#FF00EE00\": \"Delightful Green\", \"#FFEBBE7C\": \"Delightful Moon\", \"#FFF9E7C8\": \"Delightful Pastry\", \"#FFFFEBD1\": \"Delightful Peach\", \"#FFDDCCCC\": \"Delirious Donkey\", \"#FF486531\": \"Dell Variant\", \"#FF7A9DCB\": \"Della Robbia Blue\", \"#FF8EC39E\": \"Delltone\", \"#FF169EC0\": \"Delos Blue\", \"#FF6198AE\": \"Delphinium Blue\", \"#FF4F92CD\": \"Delphinium Corsage\", \"#FF999B95\": \"Delta Variant\", \"#FF979147\": \"Delta Break\", \"#FF2D4A4C\": \"Delta Green\", \"#FFC5E6CF\": \"Delta Mint\", \"#FFA8917F\": \"Delta Sandbar\", \"#FFC4C2AB\": \"Delta Waters\", \"#FF0077AA\": \"Deluge Variant\", \"#FF66BBCC\": \"Delusional Dragonfly\", \"#FF8BC7E6\": \"Deluxe Days\", \"#FFE1B270\": \"Demerara Sugar\", \"#FFECDA9E\": \"Demeter\", \"#FF02CC02\": \"Demeter Green\", \"#FF493C31\": \"Demitasse\", \"#FF00AEF3\": \"Democrat\", \"#FF7A0006\": \"Demon\", \"#FF45538D\": \"Demon Blue\", \"#FFD2144B\": \"Demon Princess\", \"#FFBB2233\": \"Demonic\", \"#FFD02B48\": \"Demonic Kiss\", \"#FFD725DE\": \"Demonic Purple\", \"#FFFFE700\": \"Demonic Yellow\", \"#FFE8D4D5\": \"Demure\", \"#FFF7D2C4\": \"Demure Pink\", \"#FF7D775D\": \"Denali Green\", \"#FF2F6479\": \"Denim Blue\", \"#FF7C8D96\": \"Denim Drift\", \"#FFB8CAD5\": \"Denim Light\", \"#FF7F97B5\": \"Denim Tradition\", \"#FF636D65\": \"Dense Shrub\", \"#FF889911\": \"Densetsu Green\", \"#FFF2B717\": \"Dent Corn\", \"#FF99D590\": \"Dentist Green\", \"#FF7795C1\": \"Denver River\", \"#FFE7D8C7\": \"D\\u00e9paysement\", \"#FF355859\": \"Depth Charge\", \"#FF2C319B\": \"Depths of Night\", \"#FF253F4E\": \"Depths of the Nile\", \"#FFF9E4C6\": \"Derby Variant\", \"#FF599C89\": \"Derby Green\", \"#FF245E36\": \"Derbyshire\", \"#FFF9E1CF\": \"Derry Coast Sunrise\", \"#FF669999\": \"Desaturated Cyan\", \"#FF445155\": \"Descent Into the Catacombs\", \"#FFCCAD60\": \"Desert Variant\", \"#FFC28996\": \"Desert Bud\", \"#FFAFCA9D\": \"Desert Cactus\", \"#FFC2AE88\": \"Desert Camel\", \"#FF80474E\": \"Desert Canyon\", \"#FFD3A169\": \"Desert Caravan\", \"#FFC99C7D\": \"Desert Carnation\", \"#FF727A60\": \"Desert Chaparral\", \"#FF9E6E43\": \"Desert Clay\", \"#FFF7D497\": \"Desert Convoy\", \"#FFD16459\": \"Desert Coral\", \"#FFD0C8A9\": \"Desert Cover\", \"#FFEDDBE8\": \"Desert Dawn\", \"#FFFFBA6B\": \"Desert Dessert\", \"#FFB5AB9C\": \"Desert Dune\", \"#FFAD9A91\": \"Desert Dusk\", \"#FFE2BB8A\": \"Desert Dust\", \"#FFB6A29D\": \"Desert Echo\", \"#FFEFCDB8\": \"Desert Field\", \"#FFC6B183\": \"Desert Floor\", \"#FFFF8D82\": \"Desert Flower\", \"#FFD3BDAC\": \"Desert Fortress\", \"#FFC5B686\": \"Desert Grass\", \"#FFB8A487\": \"Desert Grey\", \"#FFC4C8AA\": \"Desert Hot Springs\", \"#FFF3F2E1\": \"Desert Iguana\", \"#FFD6CDB7\": \"Desert Khaki\", \"#FFBD9C9D\": \"Desert Lights\", \"#FFFEF5DB\": \"Desert Lily\", \"#FFA9A450\": \"Desert Locust\", \"#FFE8D2D6\": \"Desert Mauve\", \"#FFEFCFBC\": \"Desert Mesa\", \"#FFB9E0CF\": \"Desert Mirage\", \"#FFDEB181\": \"Desert Mist\", \"#FFD0BBB0\": \"Desert Morning\", \"#FFBEA166\": \"Desert Moss\", \"#FFE9DBD2\": \"Desert Mountain\", \"#FF5F727A\": \"Desert Night\", \"#FF675239\": \"Desert Palm\", \"#FFC0CABC\": \"Desert Panzer\", \"#FFAAAE9A\": \"Desert Pear\", \"#FFCAB698\": \"Desert Pebble\", \"#FFE5DDC9\": \"Desert Plain\", \"#FFFBEFDA\": \"Desert Powder\", \"#FFB3837F\": \"Desert Red\", \"#FFD5A884\": \"Desert Riverbed\", \"#FFD5C6BD\": \"Desert Rock\", \"#FFCD616B\": \"Desert Rose\", \"#FF90926F\": \"Desert Sage\", \"#FFB9A795\": \"Desert Sandstorm\", \"#FF9F927A\": \"Desert Shadows\", \"#FFE9E4CF\": \"Desert Smog\", \"#FFA15F3B\": \"Desert Soil\", \"#FFC66B30\": \"Desert Spice\", \"#FFDCDDCB\": \"Desert Springs\", \"#FFF9F0E1\": \"Desert Star\", \"#FFEDE7E0\": \"Desert Storm Variant\", \"#FFD5C7B3\": \"Desert Suede\", \"#FFBB7326\": \"Desert Sun\", \"#FFFCB58D\": \"Desert Sunrise\", \"#FFA38C6C\": \"Desert Tan\", \"#FF7F7166\": \"Desert Taupe\", \"#FFDDCC99\": \"Desert Temple\", \"#FF89734B\": \"Desert Willow\", \"#FFE5D295\": \"Desert Wind\", \"#FFA29259\": \"Desert Yellow\", \"#FFE7DBBF\": \"Deserted Beach\", \"#FF857C64\": \"Deserted Island\", \"#FFE7BF7B\": \"Deserted Path\", \"#FFA47BAC\": \"Design Delight\", \"#FFEFE5BB\": \"Designer Cream Yellow\", \"#FFE1BCD8\": \"Designer Pink\", \"#FFE7DED1\": \"Designer White\", \"#FFA93435\": \"Desirable\", \"#FFEA3C53\": \"Desire\", \"#FFEEC5D2\": \"Desire Pink\", \"#FFD8D7D9\": \"Desired Dawn\", \"#FFC4ADB8\": \"Desire\\u00e9\", \"#FFB5C1A9\": \"Desolace Dew\", \"#FFD3CBC6\": \"Desolate Field\", \"#FFF6E4D0\": \"Dessert Cream\", \"#FFFEDDB1\": \"Destined for Greatness\", \"#FFCFC9C6\": \"Destiny\", \"#FF98968D\": \"Destroyer Grey\", \"#FFE9E9E1\": \"Destroying Angels\", \"#FFFF3355\": \"Detailed Devil\", \"#FF8B8685\": \"Detective Coat\", \"#FF393C40\": \"Detective Thriller\", \"#FFC56639\": \"Determined Orange\", \"#FFBDD0D1\": \"Detroit\", \"#FFF7FCFE\": \"Deutzia White\", \"#FF006B4D\": \"Device Green\", \"#FF277594\": \"Devil Blue\", \"#FFFF3344\": \"Devil\\u2019s Advocate\", \"#FFBB4422\": \"Devil\\u2019s Butterfly\", \"#FF8F9805\": \"Devil\\u2019s Flower Mantis\", \"#FF44AA55\": \"Devil\\u2019s Grass\", \"#FF662A2C\": \"Devil\\u2019s Lip\", \"#FF423450\": \"Devil\\u2019s Plum\", \"#FFFECD82\": \"Deviled Eggs\", \"#FFDD3322\": \"Devilish\", \"#FFCE7790\": \"Devilish Diva\", \"#FF5A573F\": \"Devlan Mud\", \"#FF3C3523\": \"Devlan Mud Wash\", \"#FF3E5650\": \"Devon Green\", \"#FF717E6F\": \"Devon Rex\", \"#FFF5EFE7\": \"Devonshire\", \"#FFE7F2E9\": \"Dew Variant\", \"#FF97B391\": \"Dew Green\", \"#FFCEE3DC\": \"Dew Not Disturb\", \"#FFD7EDE8\": \"Dew Pointe\", \"#FF8B5987\": \"Dewberry\", \"#FFDDE4E3\": \"Dewdrop\", \"#FFB0B8AA\": \"Dewkissed Rain\", \"#FFC4D1C2\": \"Dewkist\", \"#FFDCEEDB\": \"Dewmist Delight\", \"#FFB2CED2\": \"Dewpoint\", \"#FFD6E1D8\": \"Dewy\", \"#FF6BB1B4\": \"Dexter\", \"#FFFAE432\": \"Dhalsim\\u2019s Yoga Flame\", \"#FFCABAA8\": \"Dhurrie Beige\", \"#FFCD0D01\": \"Diablo Red\", \"#FF1B8E13\": \"Diamine Green\", \"#FFFAF7E2\": \"Diamond\", \"#FF2B303E\": \"Diamond Black\", \"#FFE9E9F0\": \"Diamond Cut\", \"#FFF8F5E5\": \"Diamond Dust\", \"#FF3E474B\": \"Diamond Grey\", \"#FFEEE3CC\": \"Diamond Ice\", \"#FFD0EFF3\": \"Diamond League\", \"#FFDFE7EC\": \"Diamond Light\", \"#FFBCDAEC\": \"Diamond Soft Blue\", \"#FFDCDBDC\": \"Diamond Stud\", \"#FFE2EFF3\": \"Diamond White\", \"#FFE5E2E1\": \"Diamonds in the Sky\", \"#FFE9E8E0\": \"Diamonds Therapy\", \"#FFFCF6DC\": \"Diantha\", \"#FF8D6D89\": \"Dianthus Mauve\", \"#FFD0CAD7\": \"Diaphanous\", \"#FF60B8BE\": \"Dickie Bird\", \"#FF322C2B\": \"Diesel Variant\", \"#FFBC934D\": \"Different Gold\", \"#FFEBE5D5\": \"Diffused Light\", \"#FF93739E\": \"Diffused Orchid\", \"#FF8E6E57\": \"Dig It\", \"#FFA37336\": \"Digger\\u2019s Gold\", \"#FF636365\": \"Digital\", \"#FFB7B3A4\": \"Digital Garage\", \"#FFCAC0E1\": \"Digital Lavender\", \"#FFAA00FF\": \"Digital Violets\", \"#FFFFEB7E\": \"Digital Yellow\", \"#FF3B695F\": \"Dignified\", \"#FF716264\": \"Dignified Purple\", \"#FF094C73\": \"Dignity Blue\", \"#FF007044\": \"Diisha Green\", \"#FFA18251\": \"Dijon\", \"#FFE2CA73\": \"Dijon Mustard\", \"#FF9B8F55\": \"Dijonnaise\", \"#FF6F7755\": \"Dill\", \"#FFA2A57B\": \"Dill Grass\", \"#FFB6AC4B\": \"Dill Green\", \"#FF67744A\": \"Dill Pickle\", \"#FF9DA073\": \"Dill Powder\", \"#FFB3B295\": \"Dill Seed\", \"#FFD6E9E4\": \"Dillard\\u2019s Blue\", \"#FF35495A\": \"Dilly Blue\", \"#FFF6DB5D\": \"Dilly Dally\", \"#FFF46860\": \"Diluno Red\", \"#FFB8DEF2\": \"Diluted Blue\", \"#FFDDEAE0\": \"Diluted Green\", \"#FFDADFEA\": \"Diluted Lilac\", \"#FFE8EFDB\": \"Diluted Lime\", \"#FFDAF4EA\": \"Diluted Mint\", \"#FFFBE8E2\": \"Diluted Orange\", \"#FFE9DFE8\": \"Diluted Pink\", \"#FFE8DDE2\": \"Diluted Red\", \"#FFC8C2BE\": \"Dim\", \"#FFBCE1EB\": \"Diminished Blue\", \"#FFE3E6D6\": \"Diminished Green\", \"#FFE9F3DD\": \"Diminished Mint\", \"#FFFAE9E1\": \"Diminished Orange\", \"#FFF1E5E0\": \"Diminished Pink\", \"#FFE8D8DA\": \"Diminished Red\", \"#FFD3F2ED\": \"Diminished Sky\", \"#FF062E03\": \"Diminishing Green\", \"#FFF1DEDE\": \"Diminutive Pink\", \"#FFE9808B\": \"Dimple\", \"#FF607C47\": \"Dingley Variant\", \"#FFC53151\": \"Dingy Dungeon\", \"#FFE6F2A2\": \"Dingy Sticky Note\", \"#FFE8F3E4\": \"Dinner Mint\", \"#FF7F997D\": \"Dinosaur\", \"#FF827563\": \"Dinosaur Bone\", \"#FFCABAA9\": \"Dinosaur Egg\", \"#FF8391A0\": \"Diopside Blue\", \"#FF439E8D\": \"Dioptase Green\", \"#FF9DBFB1\": \"Diorite\", \"#FF68CFC1\": \"Dip in the Pool\", \"#FF3A445D\": \"Diplomatic\", \"#FFE9EEEE\": \"Dipped in Cloudy Dreams\", \"#FFFCF6EB\": \"Dipped in Cream\", \"#FF282828\": \"Dire Wolf\", \"#FF3F8A24\": \"Direct Green\", \"#FF0061A8\": \"Directoire Blue\", \"#FF5ACAA4\": \"Diroset\", \"#FF9B7653\": \"Dirt\", \"#FF836539\": \"Dirt Brown\", \"#FFBB6644\": \"Dirt Track\", \"#FF926E2E\": \"Dirt Yellow\", \"#FFDFC393\": \"Dirty Blonde\", \"#FF3F829D\": \"Dirty Blue\", \"#FFB5651E\": \"Dirty Brown\", \"#FF667E2C\": \"Dirty Green\", \"#FF430005\": \"Dirty Leather\", \"#FFDDD0B6\": \"Dirty Martini\", \"#FFC87606\": \"Dirty Orange\", \"#FFCA7B80\": \"Dirty Pink\", \"#FF734A65\": \"Dirty Purple\", \"#FFCDCED5\": \"Dirty Snow\", \"#FFE8E4C9\": \"Dirty White\", \"#FFCDC50A\": \"Dirty Yellow\", \"#FFBBDEE5\": \"Disappearing Island\", \"#FFEAE3E0\": \"Disappearing Memories\", \"#FF3F313A\": \"Disappearing Purple\", \"#FF006E9D\": \"Disarm\", \"#FF47C6AC\": \"Disc Jockey\", \"#FF892D4F\": \"Disco Variant\", \"#FFD4D4D4\": \"Disco Ball\", \"#FFBDB0A0\": \"Discover\", \"#FF4A934E\": \"Discover Deco\", \"#FF276878\": \"Discovery Bay\", \"#FFFFAD98\": \"Discreet Orange\", \"#FFF5E5E1\": \"Discreet Romance\", \"#FFDFDCDB\": \"Discreet White\", \"#FFEBDBDD\": \"Discrete Pink\", \"#FF9F6F62\": \"Discretion\", \"#FF5BB4D7\": \"Disembark\", \"#FFB7B698\": \"Disguise\", \"#FFED9190\": \"Dishy Coral\", \"#FFE2ECF2\": \"Dissolved Denim\", \"#FF566A73\": \"Distance\", \"#FF2C66A0\": \"Distant Blue\", \"#FFE5EAE6\": \"Distant Cloud\", \"#FFEAD1DA\": \"Distant Flare\", \"#FFDFE4DA\": \"Distant Haze\", \"#FFACDCEE\": \"Distant Homeworld\", \"#FFF1F8FA\": \"Distant Horizon\", \"#FFA68A71\": \"Distant Land\", \"#FFE1EFDD\": \"Distant Landscape\", \"#FFF2F3CE\": \"Distant Searchlight\", \"#FFC2D8E3\": \"Distant Shore\", \"#FF6F8DAF\": \"Distant Sky\", \"#FFBAC1C3\": \"Distant Star\", \"#FFCFBDA5\": \"Distant Tan\", \"#FF7F8688\": \"Distant Thunder\", \"#FFC2B79A\": \"Distant Valley\", \"#FFEAEFF2\": \"Distant Wind Chime\", \"#FFCCFFCC\": \"Distilled Moss\", \"#FFFFBBFF\": \"Distilled Rose\", \"#FFC7FDB5\": \"Distilled Venom\", \"#FFEDE3E0\": \"Distilled Watermelon\", \"#FFA294C9\": \"Distinct Purple\", \"#FF141513\": \"Distinctive Lack of Hue\", \"#FFF1E6CB\": \"Distressed White\", \"#FFFEB308\": \"Dithered Amber\", \"#FFBCDFFF\": \"Dithered Sky\", \"#FFC9A0FF\": \"Diva\", \"#FF0079C1\": \"Diva Blue\", \"#FFE1CBDA\": \"Diva Girl\", \"#FFB24E76\": \"Diva Glam\", \"#FFEE99EE\": \"Diva Mecha\", \"#FFFA427E\": \"Diva Pink\", \"#FFE8B9A5\": \"Diva Rouge\", \"#FF5077BA\": \"Diva Violet\", \"#FF3C4D85\": \"Dive In\", \"#FF27546E\": \"Diver Lady\", \"#FF3A797E\": \"Diver\\u2019s Eden\", \"#FFA99A89\": \"Diversion\", \"#FF9A7AA0\": \"Divine\", \"#FFE3E2D5\": \"Divine Cream\", \"#FFEEDDEE\": \"Divine Dove\", \"#FFD8E2E1\": \"Divine Inspiration\", \"#FFF4EFE1\": \"Divine Pleasure\", \"#FF69005F\": \"Divine Purple\", \"#FFE6DCCD\": \"Divine White\", \"#FF583E3E\": \"Divine Wine\", \"#FF47B07F\": \"Divot\", \"#FFCD8431\": \"Dixie Variant\", \"#FFD14E2F\": \"Dizzy Days\", \"#FF363B43\": \"Do Not Disturb\", \"#FF4B3C39\": \"Dobunezumi Brown\", \"#FF95AED0\": \"Dockside\", \"#FFA0B3BC\": \"Dockside Blue\", \"#FF813533\": \"Dockside Red\", \"#FFF9F9F9\": \"Doctor\", \"#FFA37355\": \"Dodge Pole\", \"#FF3E82FC\": \"Dodger Blue Variant\", \"#FFF79A12\": \"DodgeRoll Gold\", \"#FFFEF65B\": \"Dodie Yellow\", \"#FFB68761\": \"Doe\", \"#FFBE9F85\": \"Doe Eyes\", \"#FFFFF2E4\": \"Doeskin\", \"#FFCCC3BA\": \"Doeskin Grey\", \"#FFE5C1D9\": \"Dog Rose\", \"#FFFAEAE2\": \"Dogwood\", \"#FFC58F94\": \"Dogwood Bloom\", \"#FFF0D9E0\": \"Dolce Pink\", \"#FFFACFC1\": \"Doll House\", \"#FF7D8774\": \"Dollar\", \"#FFF590A0\": \"Dollie\", \"#FFF8EBD4\": \"Dollop of Cream\", \"#FFF5F171\": \"Dolly Variant\", \"#FFFCC9B6\": \"Dolly Cheek\", \"#FFFEE8F5\": \"Dolomite Crystal\", \"#FFC5769B\": \"Dolomite Red\", \"#FF86C4DA\": \"Dolphin Variant\", \"#FFB7B8BF\": \"Dolphin at Play\", \"#FF659FB5\": \"Dolphin Daze\", \"#FF6B6F78\": \"Dolphin Dream\", \"#FFCCCAC1\": \"Dolphin Fin\", \"#FFC7C7C2\": \"Dolphin Tales\", \"#FF9C9C6E\": \"Domain\", \"#FF5A5651\": \"Dominant Grey\", \"#FF6C5B4C\": \"Domino Variant\", \"#FF5A4F51\": \"Don Juan Variant\", \"#FFED2C1A\": \"Don\\u2019t Be Shy\", \"#FF115500\": \"Donegal Green\", \"#FFC19964\": \"Donegal Tweed\", \"#FFBB7766\": \"D\\u00f6ner Kebab\", \"#FF816E5C\": \"Donkey Brown Variant\", \"#FFAB4210\": \"Donkey Kong\", \"#FF8CAEA3\": \"Donnegal\", \"#FFEDCCD6\": \"Donquixote Doflamingo\", \"#FFFBDCA8\": \"Doodle\", \"#FF7C1E08\": \"Doombull Brown\", \"#FF6E5F56\": \"Dorado Variant\", \"#FFACA79E\": \"Dorian Grey\", \"#FFD0888E\": \"Doric Pink\", \"#FFD5CFBD\": \"Doric White\", \"#FFAD947C\": \"Dormer Brown\", \"#FF5D71A9\": \"Dormitory\", \"#FFFFF200\": \"Dorn Yellow\", \"#FF9D2C31\": \"Dorset Naga\", \"#FF6C6868\": \"Dotted Dove\", \"#FF009276\": \"D\\u00f2u L\\u01dc Green\", \"#FFA52939\": \"D\\u00f2u Sh\\u0101 S\\u00e8 Red\", \"#FFE998B1\": \"Double Bubble\", \"#FF6F5245\": \"Double Chocolate\", \"#FFD0D2D1\": \"Double Click\", \"#FFF2D9A3\": \"Double Cream\", \"#FF95BCE1\": \"Double Denim\", \"#FFFCA044\": \"Double Dragon\", \"#FF686858\": \"Double Duty\", \"#FF54423E\": \"Double Espresso\", \"#FF6D544B\": \"Double Fudge\", \"#FF6F676B\": \"Double Infinity\", \"#FF4D786C\": \"Double Jeopardy\", \"#FFA78C71\": \"Double Latte\", \"#FFE9DCBE\": \"Double Pearl Lusta Variant\", \"#FFECE3CF\": \"Double Scoop\", \"#FFD2C3A3\": \"Double Spanish White Variant\", \"#FFF6D0B6\": \"Dough Yellow\", \"#FFEDA057\": \"Doughnut\", \"#FF6F9881\": \"Douglas Fir Green\", \"#FF555500\": \"Douro\", \"#FFB3ADA7\": \"Dove\", \"#FF755D5B\": \"Dove Feather\", \"#FFE6E2D8\": \"Dove White\", \"#FFF4F2EA\": \"Dove\\u2019s Wing\", \"#FFF0E9D8\": \"Dover Cliffs\", \"#FF848585\": \"Dover Grey\", \"#FFCCAF92\": \"Dover Plains\", \"#FF326AB1\": \"Dover Straits\", \"#FFAEC3C4\": \"Dover Surf\", \"#FFF1EBDD\": \"Dover White\", \"#FF908A83\": \"Dovetail\", \"#FF838C82\": \"Dowager\", \"#FFBAAFB9\": \"Down Dog\", \"#FFFFF9E7\": \"Down Feathers\", \"#FFFFDF2B\": \"Down on the Sunflower Valley\", \"#FFCBC0BA\": \"Down-Home\", \"#FF5C6242\": \"Down-to-Earth\", \"#FF887B67\": \"Downing Earth\", \"#FFCBBCA5\": \"Downing Sand\", \"#FF777F86\": \"Downing Slate\", \"#FFA6A397\": \"Downing Stone\", \"#FFCAAB7D\": \"Downing Straw\", \"#FF4A4B57\": \"Downing Street\", \"#FF58D332\": \"Download Progress\", \"#FF43718B\": \"Downpour\", \"#FF7D6A58\": \"Downtown Benny Brown\", \"#FFADAAA2\": \"Downtown Grey\", \"#FF001100\": \"Downwell\", \"#FF6FD2BE\": \"Downy Variant\", \"#FFFEAA66\": \"Downy Feather\", \"#FFEDE9E4\": \"Downy Fluff\", \"#FF803F3F\": \"Dozen Roses\", \"#FF78587D\": \"Dr Who\", \"#FF828344\": \"Drab\", \"#FF749551\": \"Drab Green\", \"#FF808101\": \"Drably Olive\", \"#FF2C3539\": \"Dracula Orchid\", \"#FFFF9922\": \"Dragon Ball\", \"#FF5DA99F\": \"Dragon Bay\", \"#FF9C3418\": \"Dragon Dance\", \"#FFD75969\": \"Dragon Fruit\", \"#FF9E0200\": \"Dragon Red\", \"#FF877732\": \"Dragon Well\", \"#FFB84048\": \"Dragon\\u2019s Blood\", \"#FFD41003\": \"Dragon\\u2019s Breath\", \"#FFFC4A14\": \"Dragon\\u2019s Fire\", \"#FFE7E04E\": \"Dragon\\u2019s Gold\", \"#FFD50C15\": \"Dragon\\u2019s Lair\", \"#FFC189BC\": \"Dragonflies\", \"#FF314A76\": \"Dragonfly\", \"#FF45ABCA\": \"Dragonfly Blue\", \"#FF6241C7\": \"Dragonlord Purple\", \"#FFBBB0A4\": \"Drake Tooth\", \"#FF31668A\": \"Drake\\u2019s Neck\", \"#FF1F5DA0\": \"Drakenhof Nightshade\", \"#FFA37298\": \"Drama Queen\", \"#FFB883B0\": \"Drama Violet\", \"#FF240093\": \"Dramatic Blue\", \"#FF991100\": \"Dramatical Red\", \"#FF4B4775\": \"Dramatist\", \"#FF6C7179\": \"Draw Your Sword\", \"#FFD7E6EE\": \"Dream Blue\", \"#FFEBE2E8\": \"Dream Dust\", \"#FFDFDAC1\": \"Dream Grass\", \"#FF35836A\": \"Dream Green\", \"#FFF7CF26\": \"Dream of Spring\", \"#FFD5DEC3\": \"Dream Seascape\", \"#FFFF77BB\": \"Dream Setting\", \"#FFEFDDE1\": \"Dream State\", \"#FF9B868D\": \"Dream Sunset\", \"#FFCC99EE\": \"Dream Vapour\", \"#FFA5B2A9\": \"Dreamcatcher\", \"#FF8AC2D6\": \"Dreaming Blue\", \"#FFABC1BD\": \"Dreaming of the Day\", \"#FFB5B1BF\": \"Dreamland\", \"#FFFFD29D\": \"Dreams of Peach\", \"#FFC6C5C5\": \"Dreamscape Grey\", \"#FF9632CE\": \"Dreamscape Purple\", \"#FFF5D5C2\": \"Dreamsicle\", \"#FFD6E5EA\": \"Dreamstress\", \"#FFCCC6D7\": \"Dreamweaver\", \"#FFB195E4\": \"Dreamy Candy Forest\", \"#FFD7EEE4\": \"Dreamy Clouds\", \"#FF594158\": \"Dreamy Heaven\", \"#FFE8C3D9\": \"Dreamy Memory\", \"#FFDFABCD\": \"Dreamy Pink\", \"#FFFFAD61\": \"Dreamy Sunset\", \"#FF3D9C96\": \"Dreamy Teal\", \"#FFE3D8D5\": \"Dreamy White\", \"#FFA6C2D0\": \"Drenched\", \"#FFC1D1E2\": \"Drenched Rain\", \"#FF0086BB\": \"Dresden Blue\", \"#FF8CA8C6\": \"Dresden Doll\", \"#FF8EA7B9\": \"Dresden Dream\", \"#FF2A3244\": \"Dress Blues\", \"#FFF4EBEF\": \"Dress Pink\", \"#FFFAC7BF\": \"Dress Up\", \"#FF714640\": \"Dressed\", \"#FFBB5057\": \"Dressed Variant\", \"#FFB89D9A\": \"Dressy Rose\", \"#FFB2ABA1\": \"Dreyfus\", \"#FF898973\": \"Dried Basil\", \"#FF8C854F\": \"Dried Bay Leaf\", \"#FF4B0101\": \"Dried Blood\", \"#FFB6BF7F\": \"Dried Caspia\", \"#FFD1B375\": \"Dried Chamomile\", \"#FFB5BDA3\": \"Dried Chervil\", \"#FF7B7D69\": \"Dried Chive\", \"#FFEBE7D9\": \"Dried Coconut\", \"#FF4A423A\": \"Dried Dates\", \"#FFB19F80\": \"Dried Edamame\", \"#FF752653\": \"Dried Flower Purple\", \"#FFE2A829\": \"Dried Goldenrod\", \"#FFACA08D\": \"Dried Grass\", \"#FF847A59\": \"Dried Herb\", \"#FFEBE9EC\": \"Dried Lavender\", \"#FF77747F\": \"Dried Lavender Flowers\", \"#FF5C5043\": \"Dried Leaf\", \"#FFBBBBFF\": \"Dried Lilac\", \"#FFFF40FF\": \"Dried Magenta\", \"#FFC6AD6F\": \"Dried Moss\", \"#FF804A00\": \"Dried Mustard\", \"#FFE1DBAC\": \"Dried Palm\", \"#FFD8D6CC\": \"Dried Pipe Clay\", \"#FFE5CEA9\": \"Dried Plantain\", \"#FF683332\": \"Dried Plum\", \"#FFC33E29\": \"Dried Saffron\", \"#FFBBBCA1\": \"Dried Thyme\", \"#FFA0883B\": \"Dried Tobacco\", \"#FFAB6057\": \"Dried Tomatoes\", \"#FFDCD8D0\": \"Drift of Mist\", \"#FFBEB4A8\": \"Drifting\", \"#FFDBE0E1\": \"Drifting Cloud\", \"#FF61736F\": \"Drifting Downstream\", \"#FFCCBBE3\": \"Drifting Dream\", \"#FFA89F93\": \"Drifting Sand\", \"#FFDFEFEB\": \"Drifting Tide\", \"#FF5B4276\": \"Drifting Violet\", \"#FFA67A45\": \"Driftwood Variant\", \"#FFB6C1C8\": \"Driftwood Blues\", \"#FFA6CCD6\": \"Drip\", \"#FF7A280A\": \"Drip Coffee\", \"#FFF4E7A5\": \"Dripping Cheese\", \"#FFD2DFED\": \"Dripping Ice\", \"#FFBB99BB\": \"Dripping Wisteria\", \"#FFEEBB22\": \"Drippy Honey\", \"#FFA24857\": \"Drisheen\", \"#FFA62E30\": \"Drive-In Cherry\", \"#FFA0AF9D\": \"Drizzle\", \"#FF989D9F\": \"Drizzling Mist\", \"#FF523839\": \"Dro\\u00ebwors\", \"#FFE3C295\": \"Dromedary\", \"#FFCAAD87\": \"Dromedary Camel\", \"#FF69BD5A\": \"Drop Green\", \"#FFFCF1BD\": \"Drop of Lemon\", \"#FFAADDFF\": \"Droplet\", \"#FFBB3300\": \"Dropped Brick\", \"#FFD4AE76\": \"Drops of Honey\", \"#FFD5D1CC\": \"Drought\", \"#FFFBEB9B\": \"Drover Variant\", \"#FFD4DBE1\": \"Drowsy Lavender\", \"#FF842994\": \"Druchii Violet\", \"#FF427131\": \"Druid Green\", \"#FFA66E4B\": \"Drum Solo\", \"#FFE7D7B9\": \"Drumskin\", \"#FFDD11DD\": \"Drunk-Tank Pink\", \"#FF33DD88\": \"Drunken Dragonfly\", \"#FFFF55CC\": \"Drunken Flamingo\", \"#FFEADFCE\": \"Dry Bone\", \"#FF968374\": \"Dry Brown\", \"#FFB9BDAE\": \"Dry Catmint\", \"#FFBD5C00\": \"Dry Clay\", \"#FFD8C7B6\": \"Dry Creek\", \"#FF817665\": \"Dry Dock\", \"#FFEFDFCF\": \"Dry Dune\", \"#FFC6B693\": \"Dry Earth\", \"#FF9EA26B\": \"Dry Grass\", \"#FF909373\": \"Dry Hemlock\", \"#FF2BA727\": \"Dry Highlighter Green\", \"#FFCFBF8B\": \"Dry Leaf\", \"#FFC7D9CC\": \"Dry Lichen\", \"#FF769958\": \"Dry Moss\", \"#FF777672\": \"Dry Mud\", \"#FF948971\": \"Dry Pasture\", \"#FFDE7E5D\": \"Dry Peach\", \"#FFD2C5AE\": \"Dry Riverbed\", \"#FFC22F4D\": \"Dry Rose\", \"#FF8C8B76\": \"Dry Sage\", \"#FFEAE4D6\": \"Dry Sand\", \"#FFD4CECD\": \"Dry Season\", \"#FFC7DC68\": \"Dry Seedlings\", \"#FFB09A77\": \"Dry Starfish\", \"#FF33312D\": \"Dryad Bark\", \"#FFF25F66\": \"Dubarry\", \"#FFAE8B64\": \"Dubbin\", \"#FF73BE6E\": \"Dublin\", \"#FF6FAB92\": \"Dublin Jack\", \"#FFD5B688\": \"Dubloon\", \"#FF5B2C31\": \"Dubonnet\", \"#FF6F7766\": \"Dubuffet Green\", \"#FF763D35\": \"Ducal\", \"#FFCE9096\": \"Ducal Pink\", \"#FF16A0A6\": \"Ducati\", \"#FFD1DBC7\": \"Duchamp Light Green\", \"#FF9B909D\": \"Duchess Lilac\", \"#FFF7AA97\": \"Duchess Rose\", \"#FFDDC75B\": \"Duck Butter\", \"#FFC8E3D2\": \"Duck Egg Cream\", \"#FF53665C\": \"Duck Green\", \"#FF005800\": \"Duck Hunt\", \"#FFCC9922\": \"Duck Sauce\", \"#FFE9D6B1\": \"Duck Tail\", \"#FF6A695A\": \"Duck Willow\", \"#FFCCDFE8\": \"Duck\\u2019s Egg Blue\", \"#FFFFFF11\": \"Duckie Yellow\", \"#FFFCB057\": \"Duckling\", \"#FFFAFC5D\": \"Duckling Fluff\", \"#FFAEACAC\": \"Duct Tape Grey\", \"#FF464E3F\": \"Duffel Bag\", \"#FF71706E\": \"Dugong\", \"#FFD6851F\": \"Dulce de Leche\", \"#FF9AD4D8\": \"Dulcet\", \"#FFF0E2E4\": \"Dulcet Pink\", \"#FF59394C\": \"Dulcet Violet\", \"#FFD6D4E6\": \"Dulcinea\", \"#FF727171\": \"Dull\", \"#FFD09C97\": \"Dull Apricot\", \"#FF49759C\": \"Dull Blue\", \"#FF876E4B\": \"Dull Brown\", \"#FFDCD6D3\": \"Dull Desert\", \"#FF8F6D73\": \"Dull Dusky Pink\", \"#FF8A6F48\": \"Dull Gold\", \"#FF74A662\": \"Dull Green\", \"#FFE5D9B4\": \"Dull Light Yellow\", \"#FF8D4856\": \"Dull Magenta\", \"#FF7D7485\": \"Dull Mauve\", \"#FF7A7564\": \"Dull Olive\", \"#FFD8863B\": \"Dull Orange\", \"#FFD5869D\": \"Dull Pink\", \"#FF84597E\": \"Dull Purple\", \"#FFBB3F3F\": \"Dull Red\", \"#FFDBD4AB\": \"Dull Sage\", \"#FF5F9E8F\": \"Dull Teal\", \"#FF557D73\": \"Dull Turquoise\", \"#FFEEDC5B\": \"Dull Yellow\", \"#FFF7DDAA\": \"Dumpling\", \"#FF80B4DC\": \"Dun Morogh Blue\", \"#FFD5C0A1\": \"Dune Variant\", \"#FFC3A491\": \"Dune Beige\", \"#FFB88D70\": \"Dune Drift\", \"#FFCBC5B1\": \"Dune Grass\", \"#FFE9AA71\": \"Dune King\", \"#FF867665\": \"Dune Shadow\", \"#FFE2BB88\": \"Dune View\", \"#FF514F4A\": \"Dunes Manor\", \"#FFD9ECE6\": \"Dunnock Egg\", \"#FF6E6064\": \"Duomo\", \"#FF58A0BC\": \"Dupain\", \"#FF442211\": \"Duqqa Brown\", \"#FF566777\": \"Durango Blue\", \"#FFFBE3A1\": \"Durango Dust\", \"#FFFFB978\": \"Durazno Maduro\", \"#FFFFD8BB\": \"Durazno Palido\", \"#FF5D8A9B\": \"Durban Sky\", \"#FFB07939\": \"Durian\", \"#FFE5E0DB\": \"Durian Smell\", \"#FFE6D0AB\": \"Durian White\", \"#FFE1BD27\": \"Durian Yellow\", \"#FFF06126\": \"Durotar Fire\", \"#FF4E5481\": \"Dusk\", \"#FFD2CAC8\": \"Dusk in the Valley\", \"#FF9A7483\": \"Dusk Wine\", \"#FF123D55\": \"Duskwood\", \"#FFC3ABA8\": \"Dusky\", \"#FF296767\": \"Dusky Alpine Blue\", \"#FF774400\": \"Dusky Brown\", \"#FFE1C779\": \"Dusky Citron\", \"#FF7D6D70\": \"Dusky Cyclamen\", \"#FFB98478\": \"Dusky Damask\", \"#FFE5E1DE\": \"Dusky Dawn\", \"#FF877F95\": \"Dusky Grape\", \"#FF7A705B\": \"Dusky Green\", \"#FF8E969E\": \"Dusky Grouse\", \"#FFA77572\": \"Dusky Haze\", \"#FFB2A09E\": \"Dusky Hyacinth\", \"#FFD6CBDA\": \"Dusky Lilac\", \"#FFA39B7E\": \"Dusky Meadows\", \"#FF979BA8\": \"Dusky Mood\", \"#FFEDECD7\": \"Dusky Moon\", \"#FFD5CBC3\": \"Dusky Morn\", \"#FF873E1A\": \"Dusky Orange\", \"#FFA07A89\": \"Dusky Orchid\", \"#FF95978F\": \"Dusky Parakeet\", \"#FFCC7A8B\": \"Dusky Pink\", \"#FF895B7B\": \"Dusky Purple\", \"#FFBA6873\": \"Dusky Rose\", \"#FFE1CEC7\": \"Dusky Sand\", \"#FFC9BDB7\": \"Dusky Taupe\", \"#FFD0BFBE\": \"Dusky Violet\", \"#FFFFFF05\": \"Dusky Yellow\", \"#FFB2996E\": \"Dust\", \"#FFE2D8D3\": \"Dust Bowl\", \"#FFC8B6A6\": \"Dust Bunny\", \"#FFC6C8BE\": \"Dust Green\", \"#FFCFC9DF\": \"Dust of the Moon\", \"#FFE7D3B7\": \"Dust Storm Variant\", \"#FFBBBCBC\": \"Dust Variant\", \"#FF959BA0\": \"Dustblu\", \"#FFCC7357\": \"Dusted Clay\", \"#FFBEA775\": \"Dusted Olive\", \"#FF696BA0\": \"Dusted Peri\", \"#FF9C8373\": \"Dusted Truffle\", \"#FFE7ECE8\": \"Dusting Powder\", \"#FF685243\": \"Dustwallow Marsh\", \"#FFBDDACA\": \"Dusty Aqua\", \"#FFBFB6A3\": \"Dusty Attic\", \"#FF8093A4\": \"Dusty Blue\", \"#FFF3C090\": \"Dusty Boots\", \"#FF9A7E68\": \"Dusty Canyon\", \"#FFDD9592\": \"Dusty Cedar\", \"#FF847163\": \"Dusty Chestnut\", \"#FF888899\": \"Dusty Chimney\", \"#FFD29B83\": \"Dusty Coral\", \"#FF97A2A0\": \"Dusty Dream\", \"#FFB18377\": \"Dusty Duchess\", \"#FFD7B999\": \"Dusty Gold\", \"#FF76A973\": \"Dusty Green\", \"#FFCDCCD0\": \"Dusty Grey\", \"#FF8990A3\": \"Dusty Heather\", \"#FFF1DDBE\": \"Dusty Ivory\", \"#FF71AF98\": \"Dusty Jade Green\", \"#FFAC86A8\": \"Dusty Lavender\", \"#FFD3CACD\": \"Dusty Lilac\", \"#FF716D63\": \"Dusty Mountain\", \"#FF676658\": \"Dusty Olive\", \"#FFE16D4F\": \"Dusty Orange\", \"#FF8C7763\": \"Dusty Path\", \"#FFD58A94\": \"Dusty Pink\", \"#FFD7D0E1\": \"Dusty Plum\", \"#FF825F87\": \"Dusty Purple\", \"#FFB9484E\": \"Dusty Red\", \"#FFB56F76\": \"Dusty Rose\", \"#FFC0AA9F\": \"Dusty Rosewood\", \"#FFBDBAAE\": \"Dusty Sand\", \"#FF95A3A6\": \"Dusty Sky\", \"#FF4C9085\": \"Dusty Teal\", \"#FFC9BBA3\": \"Dusty Trail\", \"#FFC3B9A6\": \"Dusty Trail Rider\", \"#FF598A8F\": \"Dusty Turquoise\", \"#FFBAB7B3\": \"Dusty Warrior\", \"#FFCFC88F\": \"Dusty Yellow\", \"#FF4E6594\": \"Dutch Blue\", \"#FF8C706A\": \"Dutch Cocoa\", \"#FFA5ABB6\": \"Dutch Jug\", \"#FF404B56\": \"Dutch Licorice\", \"#FFDFA837\": \"Dutch Orange\", \"#FF9AABAB\": \"Dutch Tile Blue\", \"#FFF0DFBB\": \"Dutch White\", \"#FFC9A7AC\": \"Dutchess Dawn\", \"#FF0F8B8E\": \"Duvall\", \"#FF1D0200\": \"Dwarf Fortress\", \"#FFAF7B57\": \"Dwarf Pony\", \"#FFC8AC89\": \"Dwarf Rabbit\", \"#FF71847D\": \"Dwarf Spruce\", \"#FFBF652E\": \"Dwarven Bronze\", \"#FFEFDFE7\": \"Dwindling Damon\", \"#FFF9E9D6\": \"Dwindling Dandelion\", \"#FFCCE1EE\": \"Dwindling Denim\", \"#FF7B99B0\": \"Dyer\\u2019s Woad\", \"#FF364141\": \"Dying Light\", \"#FF669C7D\": \"Dying Moss\", \"#FF111166\": \"Dying Storm Blue\", \"#FFD5B266\": \"Dylan Velvet\", \"#FF6D5160\": \"Dynamic\", \"#FF1F1C1D\": \"Dynamic Black\", \"#FF0192C6\": \"Dynamic Blue\", \"#FFA7E142\": \"Dynamic Green\", \"#FF8A547F\": \"Dynamic Magenta\", \"#FFFFE36D\": \"Dynamic Yellow\", \"#FFFF4422\": \"Dynamite\", \"#FFDD3311\": \"Dynamite Red\", \"#FF953D68\": \"Dynamo\", \"#FFC7CBBE\": \"Dynasty Celadon\", \"#FFF8D77F\": \"E. Honda Beige\", \"#FFA26C36\": \"Eagle Variant\", \"#FF736665\": \"Eagle Eye\", \"#FF7D776C\": \"Eagle Ridge\", \"#FF5C5242\": \"Eagle Rock\", \"#FF8D7D68\": \"Eagle\\u2019s Meadow\", \"#FFD4CBCC\": \"Eagle\\u2019s View\", \"#FF8A693F\": \"Eagles Nest\", \"#FFE9D9C0\": \"Eaglet Beige\", \"#FF466B82\": \"Eames for Blue\", \"#FF416659\": \"Earhart Emerald\", \"#FF747A64\": \"Earl Green\", \"#FFA6978A\": \"Earl Grey\", \"#FFB8A722\": \"Earls Green Variant\", \"#FFFFE5ED\": \"Early Blossom\", \"#FFEAE7E7\": \"Early Crocus\", \"#FF797287\": \"Early Dawn Variant\", \"#FF44AA00\": \"Early Dew\", \"#FFD3D6E9\": \"Early Dog Violet\", \"#FFCAC7BF\": \"Early Evening\", \"#FFBAE5EE\": \"Early Forget-Me-Not\", \"#FFDAE3E9\": \"Early Frost\", \"#FFB9BE82\": \"Early Harvest\", \"#FFA5DDEA\": \"Early July\", \"#FFB1D2DF\": \"Early June\", \"#FFADCDDC\": \"Early September\", \"#FFFDF3E4\": \"Early Snow\", \"#FF96BC4A\": \"Early Spring\", \"#FF3C3FB1\": \"Early Spring Night\", \"#FFE6D7A0\": \"Early Sprout\", \"#FFF3E3D8\": \"Early Sunset\", \"#FFA2653E\": \"Earth\", \"#FF49433B\": \"Earth Black\", \"#FF4F1507\": \"Earth Brown\", \"#FF705364\": \"Earth Brown Violet\", \"#FFC7AF88\": \"Earth Chi\", \"#FF664B40\": \"Earth Chicory\", \"#FF8C4F42\": \"Earth Crust\", \"#FF71BAB4\": \"Earth Eclipse\", \"#FF785240\": \"Earth Fired Red\", \"#FFC6BA92\": \"Earth Friendly\", \"#FF545F5B\": \"Earth Green\", \"#FFE3EDC8\": \"Earth Happiness\", \"#FFB57770\": \"Earth Rose\", \"#FFA06E57\": \"Earth Tone\", \"#FFBF9F91\": \"Earth Warming\", \"#FFA48A80\": \"Earthbound\", \"#FF667971\": \"Earthen Cheer\", \"#FFA85E39\": \"Earthen Jug\", \"#FFD1AC71\": \"Earthen Sienna\", \"#FFA89373\": \"Earthenware\", \"#FFDED6C7\": \"Earthling\", \"#FFAB8A68\": \"Earthly Delight\", \"#FF693C3B\": \"Earthly Pleasures\", \"#FF9D8675\": \"Earthnut\", \"#FF8C7553\": \"Earthquake\", \"#FFC3816E\": \"Earthworm\", \"#FFB7A996\": \"Earthy Beige\", \"#FFC5B28B\": \"Earthy Cane\", \"#FF666600\": \"Earthy Khaki Green\", \"#FFB89E78\": \"Earthy Ochre\", \"#FFFAE3E3\": \"Eased Pink\", \"#FFB29D8A\": \"Easily Suede\", \"#FF878B46\": \"East Aurora\", \"#FF47526E\": \"East Bay Variant\", \"#FFB0EEE2\": \"East Cape\", \"#FFF8E587\": \"East of the Sun\", \"#FFAA8CBC\": \"East Side Variant\", \"#FFEBE5EB\": \"Easter Bunny\", \"#FF8E97C7\": \"Easter Egg\", \"#FF8CFD7E\": \"Easter Green\", \"#FFE6E1E2\": \"Easter Orchid\", \"#FFC071FE\": \"Easter Purple\", \"#FFC7BFC3\": \"Easter Rabbit\", \"#FFEBB67E\": \"Eastern Amber\", \"#FF5E5D3D\": \"Eastern Bamboo\", \"#FF00879F\": \"Eastern Blue Variant\", \"#FF748695\": \"Eastern Bluebird\", \"#FFDAE0E6\": \"Eastern Breeze\", \"#FFB89B6C\": \"Eastern Gold\", \"#FF8FC1D2\": \"Eastern Sky\", \"#FFDBA87F\": \"Eastern Spice\", \"#FFEDE6D5\": \"Eastern Wind\", \"#FF7C6042\": \"Eastlake\", \"#FFC28E61\": \"Eastlake Gold\", \"#FF887D79\": \"Eastlake Lavender\", \"#FFA9A482\": \"Eastlake Olive\", \"#FFBEB394\": \"Easy\", \"#FFAACDD8\": \"Easy Breezy\", \"#FF9EB1AE\": \"Easy Breezy Blue\", \"#FF9FB289\": \"Easy Green\", \"#FFF9ECB6\": \"Easy on the Eyes\", \"#FF98B389\": \"Easygoing Green\", \"#FF696845\": \"Eat Your Greens\", \"#FF80987A\": \"Eat Your Peas\", \"#FFBB9F60\": \"Eaton Gold\", \"#FFE4BBD1\": \"Eau de Rose\", \"#FFCECDAD\": \"Eaves\", \"#FFE6D8D4\": \"Ebb Variant\", \"#FF7893A0\": \"Ebb Tide\", \"#FF688D8A\": \"Ebbing Tide\", \"#FF773C30\": \"Ebi Brown\", \"#FF5E2824\": \"Ebicha Brown\", \"#FF6D2B50\": \"Ebizome Purple\", \"#FF313337\": \"Ebony Tint\", \"#FF323438\": \"Ebony Clay Variant\", \"#FF4A4741\": \"Ebony Keys\", \"#FFB06A40\": \"Ebony Lips\", \"#FF2C3227\": \"Ebony Wood\", \"#FFFFFFEE\": \"Eburnean\", \"#FFB576A7\": \"Eccentric Magenta\", \"#FF968A9F\": \"Eccentricity\", \"#FFE7D8BE\": \"Echelon Ecru\", \"#FFFFA565\": \"Echinoderm\", \"#FFFFA756\": \"Echinoidea Thorns\", \"#FFD7E7E0\": \"Echo\", \"#FFB6DFF4\": \"Echo Iris\", \"#FF95B5DB\": \"Echo Isles Water\", \"#FFD8DFDF\": \"Echo Mist\", \"#FF629DA6\": \"Echo One\", \"#FF758883\": \"Echo Park\", \"#FFE6E2D6\": \"Echo Valley\", \"#FFEEDEDD\": \"Echoes of Love\", \"#FF7E4930\": \"\\u00c9clair au Chocolat\", \"#FFAAAFBD\": \"Eclectic\", \"#FF8C6E67\": \"Eclectic Plum\", \"#FF483E45\": \"Eclectic Purple\", \"#FF3F3939\": \"Eclipse Variant\", \"#FF456074\": \"Eclipse Blue\", \"#FF1F2133\": \"Eclipse Elixir\", \"#FFA89768\": \"Eco Green\", \"#FF677F70\": \"Ecological\", \"#FFA8916C\": \"Ecosystem\", \"#FFA48D83\": \"Ecru Ochre\", \"#FFA08942\": \"Ecru Olive\", \"#FFD5CDB4\": \"Ecru Wealth\", \"#FFD6D1C0\": \"Ecru White Variant\", \"#FFC96138\": \"Ecstasy Variant\", \"#FFAA1122\": \"Ecstatic Red\", \"#FFFFFF7E\": \"Ecuadorian Banana\", \"#FF9CA389\": \"Edamame\", \"#FFEEE8D9\": \"Edelweiss\", \"#FF266255\": \"Eden Variant\", \"#FF95863C\": \"Eden Prairie\", \"#FF54585E\": \"Edge of Black\", \"#FF330044\": \"Edge of Space\", \"#FF303D3C\": \"Edge of the Galaxy\", \"#FFC1D8C5\": \"Edgewater Variant\", \"#FFB1975F\": \"Edgy Gold\", \"#FFBF9A67\": \"Edgy Green\", \"#FFBA3D3C\": \"Edgy Red\", \"#FFA13D2D\": \"Edocha\", \"#FFF6EDE0\": \"Edwardian Lace\", \"#FFCC9DA4\": \"Edwardian Rose\", \"#FFA9D6BA\": \"Eerie Glow\", \"#FFFBF4D1\": \"Effervescent\", \"#FF00315A\": \"Effervescent Blue\", \"#FF98DA2C\": \"Effervescent Lime\", \"#FF01FF07\": \"EGA Green\", \"#FFC1E7EB\": \"Egg Blue\", \"#FFFFD98C\": \"Egg Cream\", \"#FFDCCAA8\": \"Egg Liqueur\", \"#FFF1E3BD\": \"Egg Noodle\", \"#FFF9E4C5\": \"Egg Sour Variant\", \"#FFF2C911\": \"Egg Toast\", \"#FFE2E1C8\": \"Egg Wash\", \"#FFFFCE81\": \"Egg Yolk\", \"#FFFFDB0B\": \"Egg Yolk Sunrise\", \"#FFFDEA9F\": \"Eggnog\", \"#FF430541\": \"Eggplant Variant\", \"#FF656579\": \"Eggplant Ash\", \"#FF531B93\": \"Eggplant Tint\", \"#FFA3CCC9\": \"Eggshell Blue\", \"#FFF5EEDB\": \"Eggshell Cream\", \"#FFE2BE9F\": \"Eggshell Paper\", \"#FFBEA582\": \"Eggshell Pongee\", \"#FFF3E4DC\": \"Eggshell White\", \"#FFF4ECE1\": \"Egret\", \"#FFDFD9CF\": \"Egret White\", \"#FF005C69\": \"Egyptian Enamel\", \"#FFEFA84C\": \"Egyptian Gold\", \"#FF08847C\": \"Egyptian Green\", \"#FF7A4B3A\": \"Egyptian Jasper\", \"#FFFEBCAD\": \"Egyptian Javelin\", \"#FF70775C\": \"Egyptian Nile\", \"#FFC19A7D\": \"Egyptian Pyramid\", \"#FF983F4A\": \"Egyptian Red\", \"#FFBEAC90\": \"Egyptian Sand\", \"#FF008C8D\": \"Egyptian Teal\", \"#FFD6B378\": \"Egyptian Temple\", \"#FF3D496D\": \"Egyptian Violet\", \"#FFE5F1EC\": \"Egyptian White\", \"#FFE1DED7\": \"Eider White\", \"#FFE6DBC6\": \"Eiderdown\", \"#FF998E83\": \"Eiffel Tower\", \"#FF16161D\": \"Eigengrau\", \"#FF7799BB\": \"Eiger Nordwand\", \"#FF03050A\": \"Eight Ball\", \"#FF552299\": \"Eine Kleine Nachtmusik\", \"#FFD2BE9D\": \"Eire\", \"#FFB7A696\": \"El Capitan\", \"#FF946E48\": \"El Caramelo\", \"#FFA97F3C\": \"El Dorado\", \"#FFD0CACD\": \"El Ni\\u00f1o\", \"#FF39392C\": \"El Paso Variant\", \"#FF8F4E45\": \"El Salva Variant\", \"#FFDAC4A9\": \"Elafonisi Beach\", \"#FFECA6CA\": \"Elastic Pink\", \"#FFDFDCE5\": \"Elation\", \"#FFECC083\": \"Eldar\", \"#FFED8A09\": \"Elden Ring Orange\", \"#FFAFA892\": \"Elder Creek\", \"#FF2E2249\": \"Elderberry\", \"#FF1E323B\": \"Elderberry Black\", \"#FFAEA8B0\": \"Elderberry Grey\", \"#FFEAE5CF\": \"Elderberry White\", \"#FFFBF9E8\": \"Elderflower\", \"#FF40373E\": \"Eleanor Ann\", \"#FF110320\": \"Election Night\", \"#FF55B492\": \"Electra\", \"#FFF7F7CB\": \"Electric Arc\", \"#FFFBFF00\": \"Electric Banana\", \"#FFE23D2A\": \"Electric Blood\", \"#FFB56257\": \"Electric Brown\", \"#FF0FF0FC\": \"Electric Cyan\", \"#FF88BBEE\": \"Electric Eel\", \"#FFC9E423\": \"Electric Energy\", \"#FFFC74FD\": \"Electric Flamingo\", \"#FFFFD100\": \"Electric Glow\", \"#FF21FC0D\": \"Electric Green\", \"#FF6600FF\": \"Electric Indigo Variant\", \"#FF26FF2A\": \"Electric Laser Lime\", \"#FFF4BFFF\": \"Electric Lavender\", \"#FF89DD01\": \"Electric Leaf\", \"#FF5CDCF1\": \"Electric Lemonade\", \"#FF7BD181\": \"Electric Lettuce\", \"#FFF2E384\": \"Electric Light Orchestra\", \"#FFFF3503\": \"Electric Orange Variant\", \"#FFCD00FE\": \"Electric Orchid\", \"#FF00FF04\": \"Electric Pickle\", \"#FFFF0490\": \"Electric Pink\", \"#FFE60000\": \"Electric Red\", \"#FF55FFFF\": \"Electric Sheep\", \"#FF909FBA\": \"Electric Sky\", \"#FF9DB0B9\": \"Electric Slide\", \"#FF8F00F1\": \"Electric Violet Variant\", \"#FFFFFC00\": \"Electric Yellow\", \"#FF5665A0\": \"Electrify\", \"#FFD41C4E\": \"Electrifying Kiss\", \"#FF89D1CB\": \"Electro Chill\", \"#FF2E3840\": \"Electromagnetic\", \"#FF0881D1\": \"Electron Blue\", \"#FF556D88\": \"Electronic\", \"#FFE7C697\": \"Electrum\", \"#FFAC8E73\": \"Elegant Earth\", \"#FFC4B9B7\": \"Elegant Ice\", \"#FFF1E6D6\": \"Elegant Ivory\", \"#FFFDCACA\": \"Elegant Light Rose\", \"#FF5500BB\": \"Elegant Midnight\", \"#FF48516A\": \"Elegant Navy\", \"#FF552367\": \"Elegant Purple Gown\", \"#FF217F74\": \"Elegant Silk\", \"#FFF5F0E1\": \"Elegant White\", \"#FFD0D3D3\": \"Elemental\", \"#FF969783\": \"Elemental Green\", \"#FFA0A09F\": \"Elemental Grey\", \"#FFCAB79C\": \"Elemental Tan\", \"#FF817162\": \"Elephant Variant\", \"#FF9E958D\": \"Elephant Cub\", \"#FF988F85\": \"Elephant Ear\", \"#FF95918C\": \"Elephant Grey\", \"#FFA8A9A8\": \"Elephant in the Room\", \"#FF88817A\": \"Elephant Skin\", \"#FFC0E8D8\": \"Elephant Toothpaste\", \"#FFB3C3D4\": \"Elevated\", \"#FFB5CED5\": \"Elevation\", \"#FF1B8A6B\": \"Elf\", \"#FFF7C985\": \"Elf Cream\", \"#FF68B082\": \"Elf Shoe\", \"#FFA6A865\": \"Elf Slippers\", \"#FF9DD196\": \"Elfin Games\", \"#FFCAB4D4\": \"Elfin Herb\", \"#FFEDDBE9\": \"Elfin Magic\", \"#FFEBE885\": \"Elfin Yellow\", \"#FFD8D7B9\": \"Elise\", \"#FF1B3053\": \"Elite Blue\", \"#FF133700\": \"Elite Green\", \"#FFBB8DA8\": \"Elite Pink\", \"#FF133337\": \"Elite Teal\", \"#FF987FA9\": \"Elite Wisteria\", \"#FFF4D7DC\": \"Eliza Jane\", \"#FFA1B8D2\": \"Elizabeth Blue\", \"#FFFADFD2\": \"Elizabeth Rose\", \"#FFA58D72\": \"Elk\", \"#FFCABCA4\": \"Elk Antler\", \"#FFE9E2D3\": \"Elk Horn\", \"#FFEAE6DC\": \"Elk Skin\", \"#FF897269\": \"Elkhound\", \"#FFE2C8B7\": \"Ellen\", \"#FFAAA9A4\": \"Ellie Grey\", \"#FFADB6BD\": \"Elliott Bay\", \"#FF778070\": \"Ellis Mist\", \"#FF297B76\": \"Elm Variant\", \"#FFB25B09\": \"Elm Brown Red\", \"#FF577657\": \"Elm Green\", \"#FF264066\": \"Elmer\\u2019s Echo\", \"#FF8C7C61\": \"Elmwood\", \"#FFFFE8AB\": \"Elote\", \"#FFD2CFCC\": \"Elusion\", \"#FFFED7CF\": \"Elusive\", \"#FFDDE4E8\": \"Elusive Blue\", \"#FFD5BFAD\": \"Elusive Dawn\", \"#FFCDBFC6\": \"Elusive Dream\", \"#FFDEC4D2\": \"Elusive Mauve\", \"#FFD4C0C5\": \"Elusive Violet\", \"#FFE8E3D6\": \"Elusive White\", \"#FFF7CF8A\": \"Elven Beige\", \"#FF6CA024\": \"Elven Olympics\", \"#FF7A8716\": \"Elwynn Forest Olive\", \"#FF9AAE07\": \"Elysia Chlorotica\", \"#FFA5B145\": \"Elysian Green\", \"#FFCE9500\": \"Elysium Gold\", \"#FFB4A3BB\": \"Emanation\", \"#FF5D4643\": \"Embarcadero\", \"#FFEE7799\": \"Embarrassed\", \"#FF996611\": \"Embarrassed Frog\", \"#FFBBAAA5\": \"Embarrassed Shadow\", \"#FFFF7777\": \"Embarrassment\", \"#FF8BC7C8\": \"Embellished Blue\", \"#FFCBDEE2\": \"Embellishment\", \"#FF792445\": \"Ember Red\", \"#FFEA6759\": \"Emberglow\", \"#FFE8B8A7\": \"Embrace\", \"#FF246453\": \"Embracing\", \"#FFB8DCA7\": \"Embroidered Silk\", \"#FFD4BEBF\": \"Embroidery\", \"#FF028F1E\": \"Emerald Variant\", \"#FF4CBDAC\": \"Emerald Bliss\", \"#FF6A7E5F\": \"Emerald City\", \"#FF4F8129\": \"Emerald Clear Green\", \"#FF009185\": \"Emerald Coast\", \"#FF52C170\": \"Emerald Cory\", \"#FF007A5E\": \"Emerald Dream\", \"#FF018B79\": \"Emerald Enchantment\", \"#FF224347\": \"Emerald Forest\", \"#FF66BB00\": \"Emerald Glitter\", \"#FF046307\": \"Emerald Green\", \"#FF2AF589\": \"Emerald Ice Palace\", \"#FF019157\": \"Emerald Isle\", \"#FF069261\": \"Emerald Lake\", \"#FF00A267\": \"Emerald Light Green\", \"#FF67A195\": \"Emerald Oasis\", \"#FF155E60\": \"Emerald Pool\", \"#FF80C872\": \"Emerald Rain\", \"#FF578758\": \"Emerald Ring\", \"#FF50C777\": \"Emerald Rush\", \"#FF78944A\": \"Emerald Shimmer\", \"#FF095155\": \"Emerald Spring\", \"#FF11BB11\": \"Emerald Starling\", \"#FF016360\": \"Emerald Stone\", \"#FF55AAAA\": \"Emerald Succulent\", \"#FF2B5F3C\": \"Emerald Temple\", \"#FF4FB3A9\": \"Emerald Wave\", \"#FF2B8478\": \"Emerald Whispers\", \"#FF5C6B8F\": \"Emerald-Crested Manakin\", \"#FF911911\": \"Emergency\", \"#FFE36940\": \"Emergency Zone\", \"#FFE1E1CF\": \"Emerging Leaf\", \"#FFB8A196\": \"Emerging Taupe\", \"#FF3E6058\": \"Emerson\", \"#FFCAA78C\": \"Emery Board\", \"#FF6E3974\": \"Eminence Variant\", \"#FF7A6841\": \"Eminent Bronze\", \"#FFFFDE34\": \"Emoji Yellow\", \"#FFC65F47\": \"Emotional\", \"#FF856D70\": \"Emotive Ring\", \"#FF79573A\": \"Emperador\", \"#FF50494A\": \"Emperor Variant\", \"#FFAC2C32\": \"Emperor Cherry Red\", \"#FF007B75\": \"Emperor Jade\", \"#FF715A8D\": \"Emperor Jewel\", \"#FFF0A0B6\": \"Emperor\\u2019s Children\", \"#FFB0976D\": \"Emperor\\u2019s Gold\", \"#FF99959D\": \"Emperor\\u2019s Robe\", \"#FF00816A\": \"Emperor\\u2019s Silk\", \"#FF858070\": \"Empire\", \"#FF6193B4\": \"Empire Blue\", \"#FFC19F6E\": \"Empire Gold\", \"#FFE0DBD3\": \"Empire Porcelain\", \"#FF93826A\": \"Empire Ranch\", \"#FFE7C5C1\": \"Empire Rose\", \"#FFD9DBDF\": \"Empire State Grey\", \"#FF9264A2\": \"Empire Violet\", \"#FFF7D000\": \"Empire Yellow\", \"#FFB54644\": \"Empower\", \"#FF7C7173\": \"Empress Variant\", \"#FF2A9CA0\": \"Empress Envy\", \"#FFC7DEED\": \"Empress Lila\", \"#FF10605A\": \"Empress Teal\", \"#FFFCFDFC\": \"Emptiness\", \"#FF756E6D\": \"Emu\", \"#FF3D8481\": \"Emu Egg\", \"#FFD0C5BE\": \"En Plein Air\", \"#FF427F85\": \"Enamel Antique Green\", \"#FF00758E\": \"Enamel Blue\", \"#FFBACCA8\": \"Enamel Green\", \"#FF54C589\": \"Enamelled Dragon\", \"#FF045C61\": \"Enamelled Jewel\", \"#FFC67D84\": \"Enamoured\", \"#FFF7EBD6\": \"Encaje Aperlado\", \"#FFFD0202\": \"Encarnado\", \"#FFD1C6D2\": \"Enchant\", \"#FFC9E2CF\": \"Enchanted\", \"#FF047495\": \"Enchanted Blue\", \"#FF7ED89A\": \"Enchanted Emerald\", \"#FF79837F\": \"Enchanted Eve\", \"#FFD3E9EC\": \"Enchanted Evening\", \"#FF5C821A\": \"Enchanted Forest\", \"#FF166D29\": \"Enchanted Glen\", \"#FF8EC5C0\": \"Enchanted Isle\", \"#FFBFA3D9\": \"Enchanted Lavender\", \"#FFA893C1\": \"Enchanted Lilac\", \"#FFB1D4B7\": \"Enchanted Meadow\", \"#FF2D4A71\": \"Enchanted Navy\", \"#FFB5B5BD\": \"Enchanted Silver\", \"#FF3994AF\": \"Enchanted Well\", \"#FF94895F\": \"Enchanted Wood\", \"#FF82BADF\": \"Enchanting\", \"#FFAC7435\": \"Enchanting Ginger\", \"#FF315955\": \"Enchanting Ivy\", \"#FF276DD6\": \"Enchanting Sapphire\", \"#FF7886AA\": \"Enchanting Sky\", \"#FF5D3A47\": \"Enchantress\", \"#FF6D7383\": \"Encore\", \"#FF30525B\": \"Encore Teal\", \"#FFFF9552\": \"Encounter\", \"#FFCC8F15\": \"End of Summer\", \"#FFD2EED6\": \"End of the Rainbow\", \"#FFFFD8A1\": \"Endearment\", \"#FF29598B\": \"Endeavour Variant\", \"#FF8B6F64\": \"Ending Autumn\", \"#FFFCC9B9\": \"Ending Dawn\", \"#FF1C305C\": \"Ending Navy Blue\", \"#FFA9AF99\": \"Ending Spring\", \"#FFCEE1C8\": \"Endive\", \"#FF5B976A\": \"Endless\", \"#FF9DCDE5\": \"Endless Blue\", \"#FF000044\": \"Endless Galaxy\", \"#FFB1DBF5\": \"Endless Horizon\", \"#FF567AAD\": \"Endless River\", \"#FF32586E\": \"Endless Sea\", \"#FFDDDDBB\": \"Endless Silk\", \"#FFCAE3EA\": \"Endless Sky\", \"#FFB1AAB3\": \"Endless Slumber\", \"#FFF7CF00\": \"Endless Summer\", \"#FF5DA464\": \"Endo\", \"#FF586683\": \"Enduring\", \"#FF554C3E\": \"Enduring Bronze\", \"#FFEBE8DB\": \"Enduring Ice\", \"#FFD85739\": \"Energetic Orange\", \"#FFF3C6CC\": \"Energetic Pink\", \"#FFB300B3\": \"Energic Eggplant\", \"#FF7CCA6B\": \"Energise\", \"#FFD2D25A\": \"Energised\", \"#FFC0E740\": \"Energos\", \"#FFFF9532\": \"Energy Orange\", \"#FFBB5F60\": \"Energy Peak\", \"#FFF5D752\": \"Energy Yellow Variant\", \"#FFA73211\": \"Enfield Brown\", \"#FFC2C6C0\": \"Engagement Silver\", \"#FFA17548\": \"English Bartlett\", \"#FF441111\": \"English Breakfast\", \"#FF4E6173\": \"English Channel\", \"#FFCBD3E6\": \"English Channel Fog\", \"#FFC64A55\": \"English Coral\", \"#FFE2B66C\": \"English Custard\", \"#FFFFCA46\": \"English Daisy\", \"#FF606256\": \"English Forest\", \"#FF1B4D3F\": \"English Green\", \"#FF274234\": \"English Holly Variant\", \"#FFB5C9D2\": \"English Hollyhock\", \"#FF689063\": \"English Ivy\", \"#FF9D7BB0\": \"English Lavender\", \"#FF7181A4\": \"English Manor\", \"#FF028A52\": \"English Meadow\", \"#FF3C768A\": \"English River\", \"#FFF4C6C3\": \"English Rose\", \"#FFE9C9CB\": \"English Rosebud\", \"#FF8E6947\": \"English Saddle\", \"#FFE9CFBB\": \"English Scone\", \"#FF563D5D\": \"English Violet\", \"#FFF5F3E9\": \"Engulfed in Light\", \"#FFD2A5BE\": \"Enhance\", \"#FFBDBF35\": \"Enigma\", \"#FF7E7275\": \"Enigmatic\", \"#FFEAD4C4\": \"Enjoy\", \"#FFF5D6A9\": \"Enjoyable Yellow\", \"#FFE3EAD6\": \"Enlightened Lime\", \"#FFF8FAEE\": \"Enoki\", \"#FFFFEEDD\": \"Enokitake Mushroom\", \"#FF898C4A\": \"Enough Is Enough\", \"#FFEE0044\": \"Enraged\", \"#FFCB6649\": \"Ensh\\u016bcha Red\", \"#FF3C4F6E\": \"Ensign Blue\", \"#FFEC6D51\": \"Entan Red\", \"#FF65788C\": \"Enterprise\", \"#FFAC92B0\": \"Enthroned Above\", \"#FF00FFAA\": \"Enthusiasm\", \"#FFB74E4F\": \"Enticing Red\", \"#FFD5B498\": \"Entrada Sandstone\", \"#FF005961\": \"Entrapment\", \"#FF53983C\": \"Enviable\", \"#FFDDF3C2\": \"Envious Pastel\", \"#FFB1B5A0\": \"Environmental\", \"#FF006C4B\": \"Environmental Green\", \"#FF88BB00\": \"Environmental Study\", \"#FF96BFB7\": \"Envisage\", \"#FF8BA58F\": \"Envy Variant\", \"#FF2DD78D\": \"Envy\\u2019s Love\", \"#FFD4D3C9\": \"Eon\", \"#FFFF5EC4\": \"Eosin Pink\", \"#FF7A6270\": \"Ephemera\", \"#FFCBD4DF\": \"Ephemeral Blue\", \"#FFD6CED3\": \"Ephemeral Fog\", \"#FFC7CDD3\": \"Ephemeral Mist\", \"#FFFCE2D4\": \"Ephemeral Peach\", \"#FFE4CFD7\": \"Ephemeral Red\", \"#FF0E426F\": \"Epic Adventure\", \"#FF0066EE\": \"Epic Blue\", \"#FF8D8D75\": \"Epic Green\", \"#FFEA6A0A\": \"Epicurean Orange\", \"#FFAB924B\": \"Epidote Olvene Ore\", \"#FF4BB2D5\": \"Epimetheus\", \"#FFDD33FF\": \"Epink\", \"#FFDBC1DE\": \"Epiphany\", \"#FF829161\": \"Epsom\", \"#FF83A9B3\": \"Equanimity\", \"#FFDAB160\": \"Equator Variant\", \"#FFFFE6A0\": \"Equator Glow\", \"#FFFFCE84\": \"Equatorial\", \"#FF70855E\": \"Equatorial Forest\", \"#FFBEA781\": \"Equestrian\", \"#FF54654F\": \"Equestrian Green\", \"#FF5B5652\": \"Equestrian Leather\", \"#FFA07569\": \"Equestrienne\", \"#FFA49F9F\": \"Equilibrium\", \"#FF62696B\": \"Equinox\", \"#FFD7E3E5\": \"Era\", \"#FF060030\": \"Erebus Blue\", \"#FF836B4F\": \"Ermine\", \"#FFC84F68\": \"Eros Pink\", \"#FFDDD1BF\": \"Erosion\", \"#FFF2F2F4\": \"Errigal White\", \"#FF4A0505\": \"Erythrophobia\", \"#FFFC7AB0\": \"Erythrosine\", \"#FFA95F5C\": \"Escalante\", \"#FFCC8866\": \"Escalope\", \"#FFB89B59\": \"Escapade Gold\", \"#FFA8CDE4\": \"Escape\", \"#FFABAC9F\": \"Escape Grey\", \"#FFD5B79B\": \"Escarpment\", \"#FF4A4F52\": \"Eshin Grey\", \"#FF45BE76\": \"Esmeralda\", \"#FFC4B5A4\": \"Esoteric\", \"#FFABEDC9\": \"Esoteric Touch Green\", \"#FF2F5F3A\": \"Espalier\", \"#FF80F9AD\": \"Esper\\u2019s Fungus Green\", \"#FFD5BDA4\": \"Esplanade\", \"#FF4E312D\": \"Espresso Variant\", \"#FF5B3F34\": \"Espresso Bar\", \"#FF4C443E\": \"Espresso Beans\", \"#FFD09C43\": \"Espresso Crema\", \"#FF4F4744\": \"Espresso Macchiato\", \"#FF8C3A00\": \"Espresso Martini\", \"#FFC18B5B\": \"Espresso Tonic\", \"#FFBEBD99\": \"Esprit\", \"#FFFFC49D\": \"Esprit Peach\", \"#FF7D6848\": \"Essential Brown\", \"#FFBCB8B6\": \"Essential Grey\", \"#FF007377\": \"Essential Teal\", \"#FFFFDE9F\": \"Essentially Bright\", \"#FFB0CCDA\": \"Essex Blue\", \"#FFE2EDDD\": \"Establish Mint\", \"#FFDCCDB4\": \"Estate Limestone\", \"#FFF3E0C6\": \"Estate Vanilla\", \"#FF68454B\": \"Estate Vineyard\", \"#FFC3C1D2\": \"Estate Violet\", \"#FF54A9CA\": \"Estero Sky\", \"#FFA5AF76\": \"Estragon\", \"#FF9B101F\": \"Estroruby\", \"#FF70A5B7\": \"Estuary Blue\", \"#FFE1C6D4\": \"Etcetera\", \"#FFDDE2E2\": \"Etched Glass\", \"#FFDD0044\": \"Eternal Cherry\", \"#FFB3C3DD\": \"Eternal Elegance\", \"#FFA13F49\": \"Eternal Flame\", \"#FFD6C9D5\": \"Eternal Moonrise\", \"#FFF7E504\": \"Eternal Summer\", \"#FFFAF3DC\": \"Eternal White\", \"#FF9CFAFF\": \"Eternal Winter\", \"#FF2D2F28\": \"Eternity Variant\", \"#FF98B2B4\": \"Ether\", \"#FFA3928C\": \"Etherea\", \"#FFF9EECB\": \"Ethereal\", \"#FF5CA6CE\": \"Ethereal Blue\", \"#FF1A4A5A\": \"Ethereal Dance\", \"#FF3E2723\": \"Ethereal Espresso\", \"#FFF0E8C6\": \"Ethereal Green\", \"#FFB0B8CC\": \"Ethereal Mist\", \"#FFCCE7EB\": \"Ethereal Mood\", \"#FFD5E4EC\": \"Ethereal Moonlight\", \"#FFDEDEB6\": \"Ethereal One\", \"#FFE6F1F1\": \"Ethereal White\", \"#FF3E5E4E\": \"Ethereal Woods\", \"#FFB9C4DE\": \"Etherium Blue\", \"#FF968777\": \"Ethiopia\", \"#FF985629\": \"Ethiopian Wolf\", \"#FFAAD4D1\": \"Eton Blue Variant\", \"#FF9B583C\": \"Etruscan\", \"#FFBB986F\": \"Etruscan Bronze\", \"#FFC9303E\": \"Etruscan Red\", \"#FFD5D2D7\": \"Etude Lilac\", \"#FF55BB11\": \"\\u00c9tude Naturelle\", \"#FF4BC3A8\": \"Eucalipto\", \"#FF329760\": \"Eucalyptus Variant\", \"#FF1E675A\": \"Eucalyptus Green\", \"#FFBAD2B8\": \"Eucalyptus Leaf\", \"#FF88927E\": \"Eucalyptus Wreath\", \"#FFF2E8D4\": \"Eugenia\", \"#FFED3D66\": \"Eugenia Red\", \"#FFCDA59C\": \"Eunry Variant\", \"#FFBF36E0\": \"Eupatorium Purple\", \"#FFEEBBFF\": \"Euphoria\", \"#FFDAC7DA\": \"Euphoric Lilac\", \"#FF7F576D\": \"Euphoric Magenta\", \"#FF006796\": \"Europe Blue\", \"#FF756556\": \"European Pine\", \"#FF36FF9A\": \"Eva Green\", \"#FFD1D5D3\": \"Evaporation\", \"#FF998371\": \"Even Evan\", \"#FFB2AA7A\": \"Even Growth\", \"#FF2B2B41\": \"Evening Blue\", \"#FFC49087\": \"Evening Blush\", \"#FF454341\": \"Evening Canyon\", \"#FF4B535C\": \"Evening Cityscape\", \"#FF8E6B76\": \"Evening Crimson\", \"#FFC2BEAD\": \"Evening Dove\", \"#FFD1A19B\": \"Evening Dress\", \"#FF585E6A\": \"Evening East\", \"#FF8697A0\": \"Evening Eclipse\", \"#FF56736F\": \"Evening Emerald\", \"#FF4D4970\": \"Evening Fizz\", \"#FF8C9997\": \"Evening Fog\", \"#FF3A4A62\": \"Evening Glory\", \"#FFFDD792\": \"Evening Glow\", \"#FF7C7A3A\": \"Evening Green\", \"#FFB7B2C2\": \"Evening Haze\", \"#FF7B8CA8\": \"Evening Hush\", \"#FF938F9F\": \"Evening in Paris\", \"#FF5868AE\": \"Evening Lagoon\", \"#FF4D4469\": \"Evening Lavender\", \"#FF363E7D\": \"Evening Magic\", \"#FF463F67\": \"Evening Mauve\", \"#FFE3E9E8\": \"Evening Mist\", \"#FF434D66\": \"Evening Over the Ocean\", \"#FFA7879A\": \"Evening Pink\", \"#FFC2D61D\": \"Evening Primrose\", \"#FFDDB3AB\": \"Evening Sand\", \"#FF26604F\": \"Evening Sea Variant\", \"#FFA1838B\": \"Evening Shadow\", \"#FFA99EC1\": \"Evening Slipper\", \"#FFFFD160\": \"Evening Star\", \"#FF465058\": \"Evening Storm\", \"#FFFDDFB8\": \"Evening Sun\", \"#FFEDB06D\": \"Evening Sunset\", \"#FF51637B\": \"Evening Symphony\", \"#FFD8DBD7\": \"Evening White\", \"#FF656470\": \"Eventide\", \"#FFF0C8B6\": \"Everblooming\", \"#FFA0E3E0\": \"Everest\", \"#FF264334\": \"Everglade Variant\", \"#FF25464D\": \"Everglade Deck\", \"#FFB8C17E\": \"Everglade Glen\", \"#FFB7D7DE\": \"Everglade Mist\", \"#FF125B49\": \"Evergreen\", \"#FF535C55\": \"Evergreen Bough\", \"#FF47534F\": \"Evergreen Field\", \"#FF95978A\": \"Evergreen Fog\", \"#FF0E695F\": \"Evergreen Forest\", \"#FF045E17\": \"Evergreen Shade\", \"#FF6F7568\": \"Evergreen Trail\", \"#FFA1BED9\": \"Everlasting\", \"#FFF6FDFA\": \"Everlasting Ice\", \"#FF949587\": \"Everlasting Sage\", \"#FF463E3B\": \"Evermore\", \"#FFFFA62D\": \"Eversong Orange\", \"#FFE4DCD4\": \"Everyday White\", \"#FFD8ACA0\": \"Everything\\u2019s Rosy\", \"#FFAA2211\": \"Evil Centipede\", \"#FF522000\": \"Evil Cigar\", \"#FF884488\": \"Evil Curse\", \"#FF1100CC\": \"Evil Eye\", \"#FF770022\": \"Evil Forces\", \"#FFC2191F\": \"Evil Sunz Scarlet\", \"#FFFED903\": \"Evil-Lyn\", \"#FF9DBCC7\": \"Evocative Blue\", \"#FF704A3D\": \"Evolution\", \"#FF538B89\": \"Evora\", \"#FF454042\": \"Ewa\", \"#FFF0EDDD\": \"Ewe\", \"#FF676168\": \"Excalibur\", \"#FF22606E\": \"Excellence\", \"#FF908B85\": \"Excelsior\", \"#FFCCA65B\": \"Excitable\", \"#FFF0B07A\": \"Exciting Orange\", \"#FFF9F1DD\": \"Exclusive Elixir\", \"#FF38493E\": \"Exclusive Green\", \"#FFE2D8C3\": \"Exclusive Ivory\", \"#FF736F78\": \"Exclusive Plum\", \"#FFB9ADBB\": \"Exclusive Violet\", \"#FF6B515F\": \"Exclusively\", \"#FFF2AEB8\": \"Exclusively Yours\", \"#FF8F8A70\": \"Executive Course\", \"#FFD2CEC4\": \"Exhale\", \"#FF81C784\": \"Exhilarating Green\", \"#FFA78558\": \"Exhumed Gold\", \"#FF0A0A0A\": \"Existential Angst\", \"#FF55BB33\": \"Exit Light\", \"#FF6264DC\": \"Exodus Fruit\", \"#FFAC6292\": \"Exotic Bloom\", \"#FFFD9D43\": \"Exotic Blossom\", \"#FF705660\": \"Exotic Eggplant\", \"#FF96D9DF\": \"Exotic Escape\", \"#FF58516E\": \"Exotic Evening\", \"#FFFFA24C\": \"Exotic Flower\", \"#FFC47F33\": \"Exotic Honey\", \"#FFB86F73\": \"Exotic Incense\", \"#FFAE7543\": \"Exotic Life\", \"#FFD198B5\": \"Exotic Lilac\", \"#FFDE0C62\": \"Exotic Liras\", \"#FFF84F1D\": \"Exotic Orange\", \"#FF75566C\": \"Exotic Orchid\", \"#FF909969\": \"Exotic Palm\", \"#FF6A5078\": \"Exotic Purple\", \"#FF01A7B2\": \"Exotic Sea\", \"#FFE1A0CF\": \"Exotic Violet\", \"#FF938586\": \"Exotica\", \"#FF777E65\": \"Expanse\", \"#FFAF9C76\": \"Expedition\", \"#FFDBBF90\": \"Expedition Khaki\", \"#FF64ACB5\": \"Experience\", \"#FFE56CC0\": \"Explicit Pink\", \"#FFFED83A\": \"Exploding Star\", \"#FF55A860\": \"Exploration Green\", \"#FF30AABC\": \"Explore Blue\", \"#FF57A3B3\": \"Explorer Blue\", \"#FF8B9380\": \"Explorer Green\", \"#FFB6AC95\": \"Explorer Khaki\", \"#FF3A1F76\": \"Explorer of the Galaxies\", \"#FFAA9A79\": \"Exploring Khaki\", \"#FFC4C4C4\": \"Explosive Grey\", \"#FFCC11BB\": \"Explosive Purple\", \"#FF395A73\": \"Express Blue\", \"#FF39497B\": \"Expressionism\", \"#FF52BC9A\": \"Expressionism Green\", \"#FF695C62\": \"Expressive Plum\", \"#FFC8A3BB\": \"Exquisite\", \"#FF330033\": \"Exquisite Eggplant\", \"#FF338860\": \"Exquisite Emerald\", \"#FF11CCBB\": \"Exquisite Turquoise\", \"#FF9490B2\": \"Extinct\", \"#FF4A4F5A\": \"Extinct Volcano\", \"#FFEF347C\": \"Extra Fuchsia\", \"#FF6AB417\": \"Extra Life\", \"#FF91916D\": \"Extra Mile\", \"#FFEEEFEA\": \"Extra White\", \"#FFBDA6C5\": \"Extraordinaire\", \"#FFE6E6E6\": \"Extraordinary Abundance of Tinge\", \"#FF4E4850\": \"Extravagance\", \"#FFB55067\": \"Extravagant Blush\", \"#FF0011AA\": \"Extravehicular Activity\", \"#FF661188\": \"Extraviolet\", \"#FFFF7133\": \"Extreme Carrot\", \"#FFDFC5D5\": \"Extreme Lavender\", \"#FFFFB729\": \"Extreme Yellow\", \"#FFD45B00\": \"Exuberance\", \"#FFF0622F\": \"Exuberant Orange\", \"#FFB54D7F\": \"Exuberant Pink\", \"#FF1E80C7\": \"Eye Blue\", \"#FFDDB835\": \"Eye Catching\", \"#FF607B7B\": \"Eye Grey\", \"#FFAE3D3B\": \"Eye of Newt\", \"#FFD9E3D9\": \"Eye of the Storm\", \"#FF232121\": \"Eye Patch\", \"#FFBB0077\": \"Eye Popping Cherry\", \"#FFFFFBF8\": \"Eyeball\", \"#FF8DB6B7\": \"Eyefull\", \"#FF553300\": \"Eyelash Camel\", \"#FFF4C54B\": \"Eyelash Viper\", \"#FF440000\": \"Eyelids\", \"#FFEDE8EB\": \"Eyes White Shut\", \"#FFD9D9EA\": \"Eyeshadow\", \"#FF6B94C5\": \"Eyeshadow Blue\", \"#FF008980\": \"Eyeshadow Turquoise\", \"#FFADA6C2\": \"Eyeshadow Viola\", \"#FF8F9482\": \"Eyre\", \"#FFAA1177\": \"Fabric of Love\", \"#FF341758\": \"Fabric of Space\", \"#FFBA90AD\": \"Fabulous Fantasy\", \"#FFE5C1A3\": \"Fabulous Fawn\", \"#FFABE3C9\": \"Fabulous Find\", \"#FFDDCDAB\": \"Fabulous Forties\", \"#FF88CC00\": \"Fabulous Frog\", \"#FFEE1188\": \"Fabulous Fuchsia\", \"#FF9083A5\": \"Fabulous Grape\", \"#FFA92C29\": \"Fabulous Red\", \"#FFB6A591\": \"Fa\\u00e7ade\", \"#FFF7CF89\": \"Facemark\", \"#FF676965\": \"Fade\", \"#FF658CBB\": \"Faded Blue\", \"#FF7689A2\": \"Faded Denim\", \"#FFE5D9DC\": \"Faded Firebrick\", \"#FF9EB4C0\": \"Faded Flaxflower\", \"#FFE3E2D7\": \"Faded Forest\", \"#FFEDE2EE\": \"Faded Fuchsia\", \"#FF7BB274\": \"Faded Green\", \"#FFEAE8E4\": \"Faded Grey\", \"#FFB2C4D4\": \"Faded Indigo\", \"#FF5DBDCB\": \"Faded Jeans\", \"#FFA5975B\": \"Faded Khaki\", \"#FFBFAC86\": \"Faded Letter\", \"#FFF5E4DE\": \"Faded Light\", \"#FF92A2BB\": \"Faded Lilac\", \"#FFF0944D\": \"Faded Orange\", \"#FF887383\": \"Faded Orchid\", \"#FFDE9DAC\": \"Faded Pink\", \"#FF80DBEB\": \"Faded Poster\", \"#FF916E99\": \"Faded Purple\", \"#FFD3494E\": \"Faded Red\", \"#FFBE9480\": \"Faded Redwood\", \"#FFBF6464\": \"Faded Rose\", \"#FF8D9CAE\": \"Faded Sea\", \"#FFEBDCD7\": \"Faded Shells\", \"#FFFDCF6A\": \"Faded Sunlight\", \"#FFDDBEDD\": \"Faded Violet\", \"#FFFEFF7F\": \"Faded Yellow\", \"#FFDF691E\": \"Fading Ember\", \"#FFE8E4E0\": \"Fading Fog\", \"#FF442266\": \"Fading Horizon\", \"#FFC973A2\": \"Fading Love\", \"#FF3377CC\": \"Fading Night\", \"#FFECE6DC\": \"Fading Parchment\", \"#FFFAD0D1\": \"Fading Rose\", \"#FFB3B3C2\": \"Fading Sunset\", \"#FFF69A54\": \"Fading Torch\", \"#FFFBD2BB\": \"Fahrenheit\", \"#FF2A6D8B\": \"Faience\", \"#FF81762B\": \"Faience Green\", \"#FF99CCEE\": \"Fail Whale\", \"#FF908470\": \"Faint Allegory\", \"#FFD6DFEC\": \"Faint Blue\", \"#FFB2EED3\": \"Faint Clover\", \"#FFEEDED5\": \"Faint Coral\", \"#FFE2C59C\": \"Faint Fawn\", \"#FFDADBE0\": \"Faint Fern\", \"#FFE6DEEA\": \"Faint Fuchsia\", \"#FFB59410\": \"Faint Gold\", \"#FFA58B2C\": \"Faint Green\", \"#FFBAA391\": \"Faint Maple\", \"#FFF1AAA8\": \"Faint of Heart\", \"#FFF5DDC5\": \"Faint Peach\", \"#FFF6E4E4\": \"Faint Pink\", \"#FF1F2847\": \"Fainting Light\", \"#FF8C9151\": \"Fair and Square\", \"#FFB4E1D8\": \"Fair Aqua\", \"#FF92AF88\": \"Fair Green\", \"#FFFCE7CF\": \"Fair Ivory\", \"#FFF1E7DC\": \"Fair Maiden\", \"#FFBDA7BE\": \"Fair Orchid\", \"#FFF3E5DC\": \"Fair Pink Variant\", \"#FFF3E6D6\": \"Fair Winds\", \"#FF9D9C7E\": \"Fairbank Green\", \"#FFD3DFD1\": \"Fairest Jade\", \"#FF61463A\": \"Fairfax Brown\", \"#FFC9D3D7\": \"Fairfax Grey\", \"#FFA2BADB\": \"Fairies in America\", \"#FF6BA5A9\": \"Fairstar\", \"#FFDAC7C4\": \"Fairview Taupe\", \"#FF477050\": \"Fairway\", \"#FF26623F\": \"Fairway Green\", \"#FFCDE8B6\": \"Fairway Mist\", \"#FFFFEBFE\": \"Fairy Bubblegum Cloud\", \"#FFBCB0B1\": \"Fairy Bubbles\", \"#FFFFE8F4\": \"Fairy Dust\", \"#FFEBC9C6\": \"Fairy Floss\", \"#FFEED3CB\": \"Fairy Pink\", \"#FFF6DBDD\": \"Fairy Princess\", \"#FFFFE0F5\": \"Fairy Salt\", \"#FFB0E0F7\": \"Fairy Sparkles\", \"#FFECDDE5\": \"Fairy Tail\", \"#FFEFB4CA\": \"Fairy Tale\", \"#FF3E9ABD\": \"Fairy Tale Blue\", \"#FFFACFCC\": \"Fairy Tale Dream\", \"#FF88CC55\": \"Fairy Tale Green\", \"#FFAEA4C1\": \"Fairy Wand\", \"#FFDED4D8\": \"Fairy White\", \"#FFFFEBF2\": \"Fairy Wings\", \"#FF8A6FA9\": \"Fairy Wren\", \"#FFE2D7DA\": \"Fairy-Nuff\", \"#FF1F3636\": \"Fait Accompli\", \"#FFD5EBAC\": \"Faith\", \"#FFE7A7A0\": \"Faithful Rose\", \"#FFEFE6C1\": \"Fake Blonde\", \"#FFC88088\": \"Fake Crush\", \"#FF529875\": \"Fake Fern\", \"#FF13EAC9\": \"Fake Jade\", \"#FFCC77EE\": \"Fake Love\", \"#FFAA7711\": \"Falafel\", \"#FF6E5A5B\": \"Falcon Variant\", \"#FF898887\": \"Falcon Grey\", \"#FF007062\": \"Falcon Turquoise\", \"#FF76595E\": \"Falcon Wing\", \"#FFA5BEBD\": \"Falkland\", \"#FFC69896\": \"Fall Canyon\", \"#FFE1DDDB\": \"Fall Chill\", \"#FFC28359\": \"Fall Foliage\", \"#FFFFBC35\": \"Fall Gold\", \"#FFECFCBD\": \"Fall Green Variant\", \"#FFA78A59\": \"Fall Harvest\", \"#FFA49491\": \"Fall Heliotrope\", \"#FF7F6144\": \"Fall in Season\", \"#FFE5B7A5\": \"Fall Leaf\", \"#FFC17A3C\": \"Fall Leaves\", \"#FFE6C94C\": \"Fall Meadow\", \"#FFC2AC9B\": \"Fall Mood\", \"#FFF59344\": \"Fall River\", \"#FFFEE3C5\": \"Fall Straw\", \"#FFEDB2C4\": \"Fallen Blossoms\", \"#FFB85824\": \"Fallen Canopy\", \"#FF917347\": \"Fallen Leaves\", \"#FFF2E0DA\": \"Fallen Petals\", \"#FF8B8072\": \"Fallen Rock\", \"#FFA55A3B\": \"Falling Leaves\", \"#FFF0F1E7\": \"Falling Snow\", \"#FFCAD5C8\": \"Falling Star\", \"#FFC2D7DF\": \"Falling Tears\", \"#FFB6C121\": \"Fallout Green\", \"#FF889977\": \"Fallout Grey\", \"#FFC19A51\": \"Fallow Variant\", \"#FF9F8D57\": \"Fallow Deer\", \"#FF939B88\": \"False Cypress\", \"#FF784D4C\": \"False Morel\", \"#FFA57E52\": \"False Puce\", \"#FFDB9C7B\": \"Fame Orange\", \"#FFCAB3A0\": \"Familiar Beige\", \"#FFA7B191\": \"Family Tree\", \"#FFEE1199\": \"Fanatic Fuchsia\", \"#FFFFB1B0\": \"Fancy Flamingo\", \"#FFB4B780\": \"Fancy Flirt\", \"#FFFF0088\": \"Fancy Fuchsia\", \"#FFBDACCA\": \"Fancy Pansy\", \"#FFF3DAE1\": \"Fancy Pants\", \"#FFF6E9E8\": \"Fancy Pink\", \"#FFB40441\": \"Fancy Red Wine\", \"#FFC3833D\": \"Fancy Suede\", \"#FFE4DE65\": \"Fandangle\", \"#FFE04F80\": \"Fandango Pink\", \"#FFBB7B6D\": \"Faneuil Brick\", \"#FF008384\": \"Fanfare\", \"#FFBBAA97\": \"Fangtooth Fish\", \"#FFF2EEAF\": \"Fanlight\", \"#FF9F7E53\": \"Fantan\", \"#FF73788B\": \"Fantasia\", \"#FFE6C8C9\": \"Fantastic Pink\", \"#FFF2E6DD\": \"Fantasy Variant\", \"#FF29ADFF\": \"Fantasy Console Sky\", \"#FF8591A2\": \"Fantasy Grey\", \"#FFE83A72\": \"Fantasy Romance\", \"#FF7FA2BF\": \"Far Horizons\", \"#FFCEBEA2\": \"Far Side of the Mountain\", \"#FFE5EEEE\": \"Faraway Blue\", \"#FF8980C1\": \"Faraway Sky\", \"#FFE5D4C9\": \"Farfalle Noodle\", \"#FFDFC38D\": \"Farina\", \"#FF8E9B88\": \"Farm Fresh\", \"#FFEEE8D6\": \"Farm House\", \"#FFD5B54C\": \"Farm Straw\", \"#FFE7CFC1\": \"Farm-Fresh Eggs\", \"#FF8F917C\": \"Farmer\\u2019s Market\", \"#FF96A69F\": \"Farmers Green\", \"#FFEEE3D6\": \"Farmers Milk\", \"#FFBD8339\": \"Farmhouse Ochre\", \"#FFA34B41\": \"Farmhouse Red\", \"#FFA6917D\": \"Farmyard\", \"#FF456F6E\": \"Farrago\", \"#FFC1A485\": \"Farro\", \"#FFE5E3EF\": \"Farsighted\", \"#FF006B64\": \"Fashion Blue\", \"#FFB9A998\": \"Fashion District\", \"#FFB3D26D\": \"Fashion Green\", \"#FFA29C94\": \"Fashion Grey\", \"#FFB5A8A8\": \"Fashion Mauve\", \"#FF998988\": \"Fashion Week\", \"#FFEDC537\": \"Fashion Yellow\", \"#FFBDB8B8\": \"Fashionable Grey\", \"#FFB28CA9\": \"Fashionably Plum\", \"#FF66616F\": \"Fashionista\", \"#FFC7CBC8\": \"Fast as the Wind\", \"#FF8B94C7\": \"Fast Velvet\", \"#FF868D82\": \"Fat Cat\", \"#FFE6BC00\": \"Fat Gold\", \"#FFC1537D\": \"Fat Smooch\", \"#FF352235\": \"Fat Tuesday\", \"#FF008822\": \"Fatal Fields\", \"#FFDA321C\": \"Fatal Fury\", \"#FFFFF7ED\": \"Fatback\", \"#FF6BA0BF\": \"Fate\", \"#FFEE0077\": \"Fatty Fuchsia\", \"#FFEEC4B4\": \"Fatty Sashimi\", \"#FFC59DAA\": \"Fauna\", \"#FFBAD09D\": \"Fava Bean\", \"#FFFAE6CC\": \"Favoured One\", \"#FF9D723E\": \"Favourite Ale\", \"#FF877252\": \"Favourite Fudge\", \"#FF8AA3B1\": \"Favourite Jeans\", \"#FFE3C5D6\": \"Favourite Lady\", \"#FFD3A5D6\": \"Favourite Lavender\", \"#FF9BC4C4\": \"Favourite Sweater\", \"#FFC1AE91\": \"Favourite Tan\", \"#FFCFAF7B\": \"Fawn Variant\", \"#FFA7A094\": \"Fawn Brindle\", \"#FF71452A\": \"Fawn Brown\", \"#FFEE0088\": \"Feasty Fuchsia\", \"#FFDAD9CE\": \"Feather\", \"#FFF1C9CD\": \"Feather Boa\", \"#FF606972\": \"Feather Falls\", \"#FFD5DCD0\": \"Feather Fern\", \"#FFEDD382\": \"Feather Gold\", \"#FFA3D0B6\": \"Feather Green\", \"#FFB8AD9E\": \"Feather Grey\", \"#FFFFDCB2\": \"Feather Plume\", \"#FFA4A1A2\": \"Feather Quill\", \"#FFA2AEBF\": \"Feather Soft Blue\", \"#FF59A1EF\": \"Feather Star\", \"#FFE7EAE5\": \"Feather White\", \"#FFAFCBE5\": \"Featherbed\", \"#FFBCB7A5\": \"Feathers of a Dove\", \"#FFCDC7BB\": \"Featherstone\", \"#FFABC2C7\": \"Feathery Blue\", \"#FFECE7ED\": \"Feathery Lilac\", \"#FFE0DEE3\": \"February Frost\", \"#FF43628B\": \"Federal Blue\", \"#FF30594B\": \"Federal Fund\", \"#FF634041\": \"Federation Brown\", \"#FFB71010\": \"Federation of Love\", \"#FF625665\": \"Fedora Variant\", \"#FFAED3C7\": \"Feeling Lucky\", \"#FFFE420F\": \"F\\u0113i H\\u00f3ng Scarlet\", \"#FFA5D785\": \"Feijoa Variant\", \"#FFEDF2C3\": \"Feijoa Flower\", \"#FFD19275\": \"Feldspar\", \"#FFBCA885\": \"Feldspar Grey\", \"#FFA0ADA9\": \"Feldspar Silver\", \"#FF917292\": \"Felicia\", \"#FFE5E4DF\": \"Felicity\", \"#FFDBB694\": \"Feline Frolic\", \"#FF00608F\": \"Felix\", \"#FF247345\": \"Felt\", \"#FF6FC391\": \"Felt Green\", \"#FF979083\": \"Felted Wool\", \"#FF2BC51B\": \"Felwood Leaves\", \"#FF4F4352\": \"Feminin Nightshade\", \"#FFC4A8CF\": \"Feminine Fancy\", \"#FFC7C2CE\": \"Femininity\", \"#FF9D5783\": \"Feminism\", \"#FF948593\": \"Femme Fatale\", \"#FFFF6CB5\": \"F\\u011bn H\\u00f3ng Pink\", \"#FF09332C\": \"Fence Green\", \"#FFD7D9C2\": \"Feng Shui\", \"#FFAC9D83\": \"Fenland\", \"#FFDAD7C8\": \"Fennec Fox\", \"#FF8FCE9B\": \"Fennel\", \"#FFDDEEBB\": \"Fennel Bulb\", \"#FF00AA44\": \"Fennel Fiasco\", \"#FF00BB77\": \"Fennel Fiesta\", \"#FF77AAFF\": \"Fennel Flower\", \"#FF8F7F50\": \"Fennel Seed\", \"#FFDECFB1\": \"Fennel Splash\", \"#FFB1B6A3\": \"Fennel Stem\", \"#FFD2F4DD\": \"Fennel Tea\", \"#FF9A9E80\": \"Fennelly\", \"#FFCEDEE7\": \"Fenrisian Grey\", \"#FFBD8965\": \"Fenugreek\", \"#FF8DE07C\": \"Feralas Lime\", \"#FF7B7054\": \"Fermata\", \"#FF548D44\": \"Fern Variant\", \"#FF758A5F\": \"Fern Canopy\", \"#FF6AA84F\": \"Fern Flash\", \"#FF576A7D\": \"Fern Flower\", \"#FF009B54\": \"Fern Green Variant\", \"#FF536943\": \"Fern Grotto\", \"#FF837B53\": \"Fern Grove\", \"#FF595646\": \"Fern Gully\", \"#FF99A787\": \"Fern Leaf\", \"#FF797447\": \"Fern Shade\", \"#FFD6E1B4\": \"Fern Shadow\", \"#FF71AB62\": \"Ferntastic\", \"#FF977B2F\": \"Fernweh\", \"#FFE2261F\": \"Ferocious\", \"#FFEE00CC\": \"Ferocious Flamingo\", \"#FFE25D1B\": \"Ferocious Fox\", \"#FFAA00CC\": \"Ferocious Fuchsia\", \"#FF876A68\": \"Ferra Variant\", \"#FFAD7D76\": \"Ferris Wheel\", \"#FFCC926C\": \"Ferrous\", \"#FF383E44\": \"Ferry\", \"#FF8B8757\": \"Fertile Green\", \"#FF8E603C\": \"Fertile Soil\", \"#FF66FC00\": \"Fertility Green\", \"#FFBC9042\": \"Fervent Brass\", \"#FF469F4E\": \"Fervent Green\", \"#FFA1CDA6\": \"Fescue\", \"#FFCB8E00\": \"Festering Brown\", \"#FFEACC4A\": \"Festival Variant\", \"#FFB5E1DB\": \"Festival de Verano\", \"#FFAA2F78\": \"Festival Fuchsia\", \"#FF6EA43C\": \"Festival Green\", \"#FFDE5E3F\": \"Festival Orange\", \"#FF6E0F12\": \"Festive Bordeaux\", \"#FFFF5566\": \"Festive Fennec\", \"#FFDFDFE5\": \"Festive Ferret\", \"#FF008C6C\": \"Festive Green\", \"#FFA0BBB8\": \"Festoon Aqua\", \"#FFDBE0D0\": \"Feta Variant\", \"#FF86725F\": \"Fetched Stick\", \"#FFEA4C4C\": \"Fever\", \"#FFDD5577\": \"Fever Dream\", \"#FFDD6677\": \"Feverish\", \"#FFDE4D7B\": \"Feverish Passion\", \"#FFCB3E50\": \"Feverish Pink\", \"#FF112358\": \"Fibonacci Blue\", \"#FFBEC0AF\": \"Fibre Moss\", \"#FF8B851B\": \"Fickle Pickle\", \"#FF3B593A\": \"Ficus\", \"#FF006131\": \"Ficus Elastica\", \"#FFA6C875\": \"Fiddle-Leaf Fig\", \"#FFC8C387\": \"Fiddlehead Fern\", \"#FF5A9589\": \"Fiddler\", \"#FFBB9FB1\": \"Fiddlesticks\", \"#FF4477AA\": \"Field Blue\", \"#FFC5E6A4\": \"Field Day\", \"#FFCEE9E8\": \"Field Frost\", \"#FF60B922\": \"Field Green\", \"#FFB1A891\": \"Field Khaki\", \"#FF80884E\": \"Field Maple\", \"#FFDEB699\": \"Field of Wheat\", \"#FFD86F3C\": \"Field Poppy\", \"#FF649050\": \"Field Time Green\", \"#FFC5BD9C\": \"Fields Afar\", \"#FFB18446\": \"Fields of Glory\", \"#FF98A1CF\": \"Fields of Heather\", \"#FFA491A7\": \"Fields of Provence\", \"#FF807E77\": \"Fieldstone\", \"#FF7FC15C\": \"Fierce Mantis\", \"#FFCC0021\": \"Fierce Red\", \"#FF5D3831\": \"Fiery Brown\", \"#FFE26058\": \"Fiery Coral\", \"#FFF96D7B\": \"Fiery Flamingo\", \"#FFB7386E\": \"Fiery Fuchsia\", \"#FFB71E1E\": \"Fiery Garnet\", \"#FFF0531C\": \"Fiery Glow\", \"#FFB1592F\": \"Fiery Orange Variant\", \"#FFDD1E2E\": \"Fiery Red\", \"#FFF76564\": \"Fiery Salmon\", \"#FFF07046\": \"Fiery Sky\", \"#FFB74537\": \"Fiery Topaz\", \"#FFEDD8D2\": \"Fiesta\", \"#FF6FC0B1\": \"Fiesta Blue\", \"#FFD47194\": \"Fiesta Pink\", \"#FFB67C80\": \"Fiesta Rojo\", \"#FFA9A5C2\": \"Fife\", \"#FF8E8779\": \"Fifth Olive-Nue\", \"#FF505050\": \"Fiftieth Shade of Grey\", \"#FF5A3140\": \"Fig\", \"#FF550022\": \"Fig Balsamic\", \"#FF7A634D\": \"Fig Branches\", \"#FF784A65\": \"Fig Cluster\", \"#FFA98691\": \"Fig Fruit Mauve\", \"#FFBB8610\": \"Fig Mustard Yellow\", \"#FFA7989E\": \"Fig Preserves\", \"#FF605F4B\": \"Fig Tree\", \"#FFFF99AA\": \"Fight the Sunrise\", \"#FF939498\": \"Fighter Jet\", \"#FF9469A2\": \"Figue\", \"#FF962C54\": \"Figue Pulp\", \"#FFEEDAC3\": \"Figure Stone\", \"#FFE4D5C0\": \"Figurine\", \"#FF00AAAC\": \"Fiji\", \"#FF6B5F68\": \"Fiji Coral\", \"#FF636F22\": \"Fiji Green\", \"#FF528D3C\": \"Fiji Palm\", \"#FFD8CAA9\": \"Fiji Sands\", \"#FFDFE7E8\": \"Filigree\", \"#FFA5AF89\": \"Filigree Green\", \"#FF93877C\": \"Film Fest\", \"#FF473933\": \"Film Noir\", \"#FFD1D3C7\": \"Filmy Green\", \"#FFB7E1D2\": \"Filtered Forest\", \"#FFB1B2C4\": \"Filtered Light\", \"#FFECCA9A\": \"Filtered Moon\", \"#FFD0B064\": \"Filtered Rays\", \"#FFE8AA08\": \"Filthy Brown\", \"#FFF1F5DB\": \"Final Departure\", \"#FFD0BF9E\": \"Final Straw\", \"#FF75785A\": \"Finch Variant\", \"#FFECD3CB\": \"Fine Alabaster\", \"#FFB6E1E1\": \"Fine Blue\", \"#FF815158\": \"Fine Burgundy\", \"#FFB1D2D5\": \"Fine China\", \"#FFDAA826\": \"Fine Gold\", \"#FFD8CFC1\": \"Fine Grain\", \"#FFB5A998\": \"Fine Greige\", \"#FFFAF5C3\": \"Fine Linen\", \"#FF008800\": \"Fine Pine\", \"#FFFAF0E1\": \"Fine Porcelain\", \"#FF5E548D\": \"Fine Purple\", \"#FFF1D5AE\": \"Fine Sand\", \"#FF84989E\": \"Fine Tuned Blue\", \"#FFFAEDE1\": \"Fine White\", \"#FFE4D4C0\": \"Fine White Sand\", \"#FF744E5B\": \"Fine Wine\", \"#FF96A8C8\": \"Finesse\", \"#FFDD8888\": \"Finest Blush\", \"#FFF1E5D7\": \"Finest Silk\", \"#FFE1C12F\": \"Finger Banana\", \"#FF8A7E61\": \"Fingerpaint\", \"#FF555356\": \"Fingerprint\", \"#FFCBBFB3\": \"Finishing Touch\", \"#FF61755B\": \"Finlandia Variant\", \"#FF694554\": \"Finn Tint\", \"#FF425357\": \"Finnegan\", \"#FF5DB0BE\": \"Finnish Fiord\", \"#FFFFFCE3\": \"Fioletowy Beige\", \"#FFFC44A3\": \"Fioletowy Purple\", \"#FF4B5A62\": \"Fiord\", \"#FFBFBFAF\": \"Fiorito\", \"#FF3D7965\": \"Fir\", \"#FF67592A\": \"Fir Green\", \"#FF6D7969\": \"Fir Spruce Green\", \"#FF8F3F2A\": \"Fire Variant\", \"#FF7C383D\": \"Fire Agate\", \"#FFBE6400\": \"Fire Ant\", \"#FFCE1620\": \"Fire Axe Red\", \"#FFCC4411\": \"Fire Bolt\", \"#FFE09842\": \"Fire Bush Variant\", \"#FFD2806C\": \"Fire Chalk\", \"#FF92353A\": \"Fire Chi\", \"#FFE3B46F\": \"Fire Coral\", \"#FFE3D590\": \"Fire Dance\", \"#FFF97306\": \"Fire Dragon Bright\", \"#FFB98D68\": \"Fire Dust\", \"#FFFE0002\": \"Fire Engine\", \"#FFF68F37\": \"Fire Flower\", \"#FFFF0D00\": \"Fire Hydrant\", \"#FFD95137\": \"Fire Island\", \"#FFBB7733\": \"Fire Lord\", \"#FFFBD9C4\": \"Fire Mist\", \"#FFFD3C06\": \"Fire Opal\", \"#FFFF8E57\": \"Fire Orange\", \"#FF79483E\": \"Fire Roasted\", \"#FFFFB70B\": \"Fire Yellow\", \"#FFBF3747\": \"Fire-Breathing Dragon\", \"#FFDD5522\": \"Firebird Tail Lights\", \"#FFCD5C51\": \"Firebug\", \"#FFF2643A\": \"Firecracker\", \"#FFF36363\": \"Firecracker Salmon\", \"#FF793030\": \"Fired Brick\", \"#FF884444\": \"Fired Clay\", \"#FF3D3732\": \"Fired Earth\", \"#FFD37A38\": \"Fired Up\", \"#FFF6DAA7\": \"Fireflies\", \"#FF314643\": \"Firefly Variant\", \"#FFFFF3A1\": \"Firefly Glow\", \"#FFD65E40\": \"Fireglow\", \"#FFF9D97B\": \"Firelight\", \"#FFBC7256\": \"Firenze\", \"#FFD08B73\": \"Fireplace Glow\", \"#FFC5C9C7\": \"Fireplace Kitten\", \"#FF847C70\": \"Fireplace Mantel\", \"#FF6E4A44\": \"Fireside\", \"#FFB87427\": \"Fireside Chat\", \"#FFEE8866\": \"Firewatch\", \"#FFB38491\": \"Fireweed\", \"#FF44363D\": \"Fireworks\", \"#FF47654A\": \"Firm Green\", \"#FFDA93C1\": \"Firm Pink\", \"#FF11353F\": \"Firmament Blue\", \"#FFF4EDEC\": \"First Blush\", \"#FFDBE64C\": \"First Colours of Spring\", \"#FFF6E2EA\": \"First Crush\", \"#FFF5B1A2\": \"First Date\", \"#FFF7D2D8\": \"First Daughter\", \"#FFFADBA0\": \"First Day of School\", \"#FFF1E798\": \"First Day of Summer\", \"#FFCFE5F0\": \"First Frost\", \"#FFF4E5E7\": \"First Impression\", \"#FFC47967\": \"First Lady\", \"#FF59A6CF\": \"First Landing\", \"#FFD9E6EE\": \"First Light\", \"#FFE7D6ED\": \"First Lilac\", \"#FFCF758A\": \"First Love\", \"#FFE47901\": \"First of Fall\", \"#FFBCE6EF\": \"First of July\", \"#FF24D427\": \"First of the Month Green\", \"#FFF4CAC6\": \"First Peach\", \"#FFB87592\": \"First Plum\", \"#FF2FBDA1\": \"First Post\", \"#FFBDD8EC\": \"First Rain\", \"#FFCBE1F2\": \"First Shade of Blue\", \"#FFE8EFF8\": \"First Snow\", \"#FFDAD9D4\": \"First Star\", \"#FF00E8D8\": \"First Timer Green\", \"#FFFFE79C\": \"First Tulip\", \"#FFD5BCB2\": \"First Waltz\", \"#FF32A0B1\": \"Fischer Blue\", \"#FFE4D9C5\": \"Fish Bone\", \"#FF11DDDD\": \"Fish Boy\", \"#FF7A9682\": \"Fish Camp Woods\", \"#FFE1E1D5\": \"Fish Ceviche\", \"#FFEECC55\": \"Fish Finger\", \"#FF1E446E\": \"Fish Net Blue\", \"#FF86C8ED\": \"Fish Pond\", \"#FF258F90\": \"Fish Story\", \"#FF015E6A\": \"Fish Tale\", \"#FF5182B9\": \"Fisher King\", \"#FFD1C9BE\": \"Fisherman Knit\", \"#FFD7F5F6\": \"Fishious Rend\", \"#FF1BA590\": \"Fishy House\", \"#FF225599\": \"Fist of the North Star\", \"#FFA2A415\": \"Fistfull of Green\", \"#FF5BB9D2\": \"Fitness Blue\", \"#FFB3B6B0\": \"Fitzgerald Smoke\", \"#FFFFAA4A\": \"Five Star\", \"#FFB1DBAA\": \"Fizz\", \"#FFDDBCBC\": \"Fizzing Whizbees\", \"#FFD8E4DE\": \"Fizzle\", \"#FFF7F5C8\": \"Fizzy & Dizzy\", \"#FFF7BC5C\": \"Fizzy Peach\", \"#FF616242\": \"Fjord Variant\", \"#FF005043\": \"Fjord Green\", \"#FF717C00\": \"Flag Green\", \"#FFB3BFB0\": \"Flagstaff Green\", \"#FFACADAD\": \"Flagstone\", \"#FF9A9E88\": \"Flagstone Quartzite\", \"#FFFE6FFF\": \"Flamazing Pink\", \"#FFF73D37\": \"Flamboyant\", \"#FFF74480\": \"Flamboyant Flamingo\", \"#FF694E52\": \"Flamboyant Plum\", \"#FF129C8B\": \"Flamboyant Teal\", \"#FFE7A500\": \"Flambrosia\", \"#FFFD4C29\": \"Flame Angelfish\", \"#FFCE0644\": \"Flame Lily\", \"#FFDB3C02\": \"Flame of Prometheus\", \"#FFFB8B23\": \"Flame Orange\", \"#FFBE5C48\": \"Flame Pea Variant\", \"#FF86282E\": \"Flame Red\", \"#FFF4E25A\": \"Flame Seal\", \"#FFD65D45\": \"Flame Stitch\", \"#FFFFCF49\": \"Flame Yellow\", \"#FFEA8645\": \"Flamenco Variant\", \"#FFDF7B62\": \"Flamenco Pink\", \"#FFF6A374\": \"Flaming Cauldron\", \"#FFD4202A\": \"Flaming Cherry\", \"#FFDD55FF\": \"Flaming Flamingo\", \"#FFFF005D\": \"Flaming Hot Flamingoes\", \"#FFEEBB66\": \"Flaming June\", \"#FFEE6633\": \"Flaming Orange\", \"#FFD2864E\": \"Flaming Torch\", \"#FFE1634F\": \"Flamingo Variant\", \"#FFFF44DD\": \"Flamingo Diva\", \"#FFEE888B\": \"Flamingo Dream\", \"#FFF8BDD9\": \"Flamingo Feather\", \"#FFB42121\": \"Flamingo Fervour\", \"#FFDF01F0\": \"Flamingo Fury\", \"#FFF6E2D8\": \"Flamingo Peach\", \"#FFCC33FF\": \"Flamingo Queen\", \"#FFEF8E87\": \"Flamingo Red\", \"#FFF6E3B4\": \"Flan\", \"#FF9E917C\": \"Flannel\", \"#FF8B8D98\": \"Flannel Pyjamas\", \"#FF495762\": \"Flapper Dance\", \"#FFFCAF52\": \"Flare\", \"#FFFF4519\": \"Flare Gun\", \"#FFFFFB05\": \"Flash Gitz Yellow\", \"#FFFF9977\": \"Flash in the Pan\", \"#FFFFAA00\": \"Flash of Orange\", \"#FFF9EED6\": \"Flashlight\", \"#FF7CBD85\": \"Flashman\", \"#FFF9F2D1\": \"Flashpoint\", \"#FF2C538A\": \"Flashy Sapphire\", \"#FFC3C6CD\": \"Flat Aluminium\", \"#FFF7D48F\": \"Flat Beige\", \"#FF3C73A8\": \"Flat Blue\", \"#FF754600\": \"Flat Brown\", \"#FFAA5533\": \"Flat Earth\", \"#FF699D4C\": \"Flat Green\", \"#FFFFF005\": \"Flat Yellow\", \"#FFEE6655\": \"Flattered Flamingo\", \"#FF527E9C\": \"Flattering Blue\", \"#FFF4D3B3\": \"Flattering Peach\", \"#FF6B4424\": \"Flattery\", \"#FFFCE300\": \"Flatty Yellow\", \"#FF8FB67B\": \"Flavoparmelia Caperata\", \"#FFFFFBFC\": \"Flawed White\", \"#FFD4C3B3\": \"Flax Beige\", \"#FFD2D8F4\": \"Flax Bloom\", \"#FFE0D68E\": \"Flax Fibre\", \"#FFB7A99A\": \"Flax Fibre Grey\", \"#FF5577AA\": \"Flax Flower\", \"#FF4499DD\": \"Flax Flower Blue\", \"#FFCBAA7D\": \"Flax Straw\", \"#FFFBECC9\": \"Flaxen\", \"#FFE3DDBD\": \"Flaxen Fair\", \"#FFBBA684\": \"Flaxen Field\", \"#FFF7E6C6\": \"Flaxseed\", \"#FFFCFCDE\": \"Flayed One\", \"#FF97BBE1\": \"Fleck\", \"#FFF2C6BB\": \"Fleecy Dreams\", \"#FFD8E2D8\": \"Fleeting Green\", \"#FFADD0E0\": \"Flemish Blue\", \"#FF894585\": \"Flesh Fly\", \"#FFDCDDD8\": \"Fleur de Sel\", \"#FFDA8704\": \"Fleur de Sel Caramel\", \"#FFB090C7\": \"Fleur-De-Lis\", \"#FFB1A3A1\": \"Flexible Grey\", \"#FFF8F6E6\": \"Flickering Firefly\", \"#FFAA6E49\": \"Flickering Flame\", \"#FFC6A668\": \"Flickering Gold\", \"#FFFFF1DC\": \"Flickering Light\", \"#FF5566EE\": \"Flickering Sea\", \"#FF4F81FF\": \"Flickery C64\", \"#FF90F215\": \"Flickery CRT Green\", \"#FF216BD6\": \"Flickr Blue\", \"#FFFB0081\": \"Flickr Pink\", \"#FFCDB891\": \"Flier Lie\", \"#FF91786B\": \"Flight of Fancy\", \"#FFA3B8CE\": \"Flight Time\", \"#FF6D7058\": \"Flinders Green\", \"#FF8ECFD0\": \"Fling Green\", \"#FF716E61\": \"Flint Variant\", \"#FFD9623B\": \"Flint Corn Red\", \"#FFA09C98\": \"Flint Grey\", \"#FF42424D\": \"Flint Purple\", \"#FF989493\": \"Flint Rock\", \"#FF8F9395\": \"Flint Shard\", \"#FFA8B2B1\": \"Flint Smoke\", \"#FF677283\": \"Flintstone\", \"#FF434252\": \"Flintstone Blue\", \"#FF45747E\": \"Flip\", \"#FFCCDDCC\": \"Flip a Coin\", \"#FFF2C4A7\": \"Flip-Flop\", \"#FF7F726B\": \"Flipper\", \"#FF7A2E4D\": \"Flirt Variant\", \"#FFBE3C37\": \"Flirt Alert\", \"#FFFFD637\": \"Flirtatious\", \"#FFCC22FF\": \"Flirtatious Flamingo\", \"#FF473F2D\": \"Flirtatious Indigo Tea\", \"#FF9E88B1\": \"Flirty Pink\", \"#FFD65E93\": \"Flirty Rose\", \"#FFFA7069\": \"Flirty Salmon\", \"#FFFDD685\": \"Float Like a Butterfly\", \"#FF93C5B6\": \"Float Your Boat\", \"#FFB0C9CD\": \"Floating Blue\", \"#FFE9D8C2\": \"Floating Feather\", \"#FFECE5CF\": \"Floating Island\", \"#FFEDEBCE\": \"Floating Lily\", \"#FFCCC7A1\": \"Floating Lily Pad\", \"#FFEAF5E7\": \"Floaty Bubble\", \"#FFB6BFBD\": \"Flock of Seagulls\", \"#FF6677BB\": \"Flood\", \"#FF877966\": \"Flood Mud\", \"#FF579DAB\": \"Flood Out\", \"#FF6C98A2\": \"Flood Tide\", \"#FF110044\": \"Floppy Disk\", \"#FFE0E0EB\": \"Flor Lila\", \"#FF73FA79\": \"Flora\", \"#FF91AD8A\": \"Flora Green\", \"#FFC6AC9F\": \"Floral Arrangement\", \"#FFE7CFB9\": \"Floral Bluff\", \"#FFBACB7C\": \"Floral Bouquet\", \"#FFFFB94E\": \"Floral Leaf\", \"#FFF5E2DE\": \"Floral Linen\", \"#FFCDCFDB\": \"Floral Note\", \"#FFEEEDE9\": \"Floral Scent\", \"#FFC39191\": \"Floral Tapestry\", \"#FF96B576\": \"Florence\", \"#FF835740\": \"Florence Brown\", \"#FF753F38\": \"Florence Red\", \"#FF7A5544\": \"Florentine Brown\", \"#FFC1937A\": \"Florentine Clay\", \"#FF755C32\": \"Florentine Dream\", \"#FF1C5798\": \"Florentine Lapis\", \"#FFBEA4A2\": \"Florida Grey\", \"#FF56BEAB\": \"Florida Keys\", \"#FFED9F6C\": \"Florida Mango\", \"#FFF7AA6F\": \"Florida Sunrise\", \"#FF6BB8B1\": \"Florida Turquoise\", \"#FF2A4983\": \"Florida Waters\", \"#FF664422\": \"Florida\\u2019s Alligator\", \"#FFA54049\": \"Floriography\", \"#FFD7B3B9\": \"Floss\", \"#FF7BB0BA\": \"Flotation\", \"#FF4A8791\": \"Flounce\", \"#FFB9B297\": \"Flour Sack\", \"#FFEBDC9C\": \"Flourish\", \"#FFF27987\": \"Flower Blossom Pink\", \"#FFD9E8C9\": \"Flower Bulb\", \"#FFFDE6C6\": \"Flower Centre\", \"#FFD9A96F\": \"Flower Field\", \"#FFF498AD\": \"Flower Girl\", \"#FFEDE7E6\": \"Flower Girl Dress\", \"#FFF9D593\": \"Flower Hat Jellyfish\", \"#FFF5DFC5\": \"Flower of Oahu\", \"#FF8F4438\": \"Flower Pot\", \"#FFE6AED3\": \"Flower Power\", \"#FFFFC9D7\": \"Flower Spell\", \"#FFB5D5B0\": \"Flower Stem\", \"#FF988378\": \"Flower Wood\", \"#FFFFEBDA\": \"Flowerbed\", \"#FFF62E52\": \"Flowerhorn Cichlid Red\", \"#FFA2D4BD\": \"Flowering Cactus\", \"#FF875657\": \"Flowering Chestnut\", \"#FFA16C94\": \"Flowering Raspberry\", \"#FFE1D8B8\": \"Flowering Reed\", \"#FFE3D7E3\": \"Flowers of May\", \"#FFE4DCBF\": \"Flowery\", \"#FFFFF953\": \"Flowey Yellow\", \"#FFB9C6CB\": \"Flowing Breeze\", \"#FF335E6F\": \"Flowing River\", \"#FFFCDF39\": \"Fluffy Duckling\", \"#FFF7D6CB\": \"Fluffy Pink\", \"#FFD8E5E4\": \"Fluffy Slippers\", \"#FFC5D6EB\": \"Fluid Blue\", \"#FFA77D35\": \"Fluor Spar\", \"#FF89D178\": \"Fluorescence\", \"#FF984427\": \"Fluorescent Fire\", \"#FF08FF08\": \"Fluorescent Green\", \"#FFBDC233\": \"Fluorescent Lime\", \"#FFFFCF00\": \"Fluorescent Orange\", \"#FFFE1493\": \"Fluorescent Pink\", \"#FFFF5555\": \"Fluorescent Red\", \"#FFFC8427\": \"Fluorescent Red Orange\", \"#FF00FDFF\": \"Fluorescent Turquoise\", \"#FFCCFF02\": \"Fluorescent Yellow\", \"#FF8FAA8C\": \"Fluorine\", \"#FF0AFF02\": \"Fluro Green\", \"#FFF2EDE3\": \"Flurries\", \"#FFCA2425\": \"Flush Mahogany Variant\", \"#FFFF6F01\": \"Flush Orange Variant\", \"#FFF8CBC4\": \"Flush Pink\", \"#FFDD5555\": \"Flushed\", \"#FFC8DAF5\": \"Fly a Kite\", \"#FF85B3F3\": \"Fly Away\", \"#FF218D4B\": \"Fly the Green\", \"#FF1C1E4D\": \"Fly-by-Night\", \"#FF787489\": \"Flying Carpet\", \"#FF5376AB\": \"Flying Fish\", \"#FF024ACA\": \"Flying Fish Blue\", \"#FF5DB3D4\": \"Flyway\", \"#FFD0EAE8\": \"Foam Variant\", \"#FF90FDA9\": \"Foam Green\", \"#FF90D1DD\": \"Foaming Surf\", \"#FFDCE2BE\": \"Foamy Lime\", \"#FFF7F4F7\": \"Foamy Milk\", \"#FFB3D4DF\": \"Foamy Surf\", \"#FFE5E0D2\": \"Focus\", \"#FFFEF9D3\": \"Focus on Light\", \"#FF91C3BD\": \"Focus Point\", \"#FFD6D7D2\": \"Fog Variant\", \"#FFD8D6D1\": \"Fog Beacon\", \"#FF112233\": \"Fog of War\", \"#FFC4BAD2\": \"Fog Syringa\", \"#FFF1EFE4\": \"Fog White\", \"#FF57317E\": \"Foggy Amethyst\", \"#FF99AEBB\": \"Foggy Blue\", \"#FF7F8E1D\": \"Foggy Bog\", \"#FFE7E3DB\": \"Foggy Day\", \"#FFD1D5D0\": \"Foggy Dew\", \"#FFA7A69D\": \"Foggy Grey\", \"#FFE2C9FF\": \"Foggy Heath\", \"#FF5C5658\": \"Foggy London\", \"#FFD5C7E8\": \"Foggy Love\", \"#FFB19F9D\": \"Foggy Mauve\", \"#FFC8D1CC\": \"Foggy Mist\", \"#FFCAD0CE\": \"Foggy Morn\", \"#FF40494E\": \"Foggy Night\", \"#FFFBF6EF\": \"Foggy Pith\", \"#FFCFCBE5\": \"Foggy Plateau\", \"#FFB7A5AD\": \"Foggy Plum\", \"#FFBFA2A1\": \"Foggy Quartz\", \"#FFACBDB1\": \"Foggy Rain\", \"#FFA79C8E\": \"Foggy Sunrise\", \"#FF909FB2\": \"Foghorn\", \"#FFEEF0E7\": \"Fogtown\", \"#FFC0C3C4\": \"Foil\", \"#FFB0B99C\": \"Foille\", \"#FF95B388\": \"Foliage\", \"#FF3E6F58\": \"Foliage Green\", \"#FF547588\": \"Folk Blue\", \"#FF7A634F\": \"Folk Guitar\", \"#FF65A19F\": \"Folk Song\", \"#FFA5C1B6\": \"Folk Tales\", \"#FF684141\": \"Folklore\", \"#FF6D6562\": \"Folkstone\", \"#FF626879\": \"Folkstone Grey\", \"#FFD69969\": \"Folksy Gold\", \"#FFF7E5D0\": \"Follow the Leader\", \"#FFFD004D\": \"Folly Variant\", \"#FFC8BCB7\": \"Fond Memory\", \"#FFABA379\": \"Fond of Fronds\", \"#FFF4E2CF\": \"Fondant\", \"#FFFDF5C4\": \"Fondue\", \"#FF6D4B3E\": \"Fondue Fudge\", \"#FFCAD175\": \"Fool\\u2019s Gold\", \"#FF825736\": \"Football\", \"#FF7EAF34\": \"Football Field\", \"#FF528E39\": \"Football Pitch\", \"#FFCAB48E\": \"Foothill Drive\", \"#FFE1CFA5\": \"Foothills\", \"#FFE6CEE6\": \"Footie Pyjamas\", \"#FF457E87\": \"For the Love of Hue\", \"#FF323F75\": \"Forbidden Blackberry\", \"#FF215354\": \"Forbidden Forest\", \"#FFFE7B7C\": \"Forbidden Fruit\", \"#FF661020\": \"Forbidden Passion\", \"#FFA38052\": \"Forbidden Peanut\", \"#FF8A4646\": \"Forbidden Red\", \"#FF856363\": \"Forbidden Thrill\", \"#FFD5CE69\": \"Force of Nature\", \"#FFF29312\": \"Forceful Orange\", \"#FF94A8D3\": \"Foresight\", \"#FF0B5509\": \"Forest\", \"#FF956378\": \"Forest Berry\", \"#FF1D5952\": \"Forest Biome\", \"#FF0D4462\": \"Forest Blues\", \"#FF738F50\": \"Forest Bound\", \"#FF969582\": \"Forest Canopy\", \"#FF627B72\": \"Forest Edge\", \"#FF3D7016\": \"Forest Empress\", \"#FF555142\": \"Forest Floor\", \"#FF78766D\": \"Forest Floor Khaki\", \"#FFE1DFBB\": \"Forest Found\", \"#FF88BB95\": \"Forest Frolic\", \"#FF68393B\": \"Forest Fruit Pink\", \"#FF6E2759\": \"Forest Fruit Red\", \"#FF154406\": \"Forest Green Variant\", \"#FF3E645B\": \"Forest Greenery\", \"#FF9AA22B\": \"Forest Lichen\", \"#FF52B963\": \"Forest Maid\", \"#FF858F83\": \"Forest Moss\", \"#FF434237\": \"Forest Night\", \"#FF708D6C\": \"Forest Path\", \"#FF216957\": \"Forest Rain\", \"#FF006800\": \"Forest Ride\", \"#FF555D46\": \"Forest Ridge\", \"#FFC8CAA4\": \"Forest Sand\", \"#FF336644\": \"Forest Serenade\", \"#FF91AC80\": \"Forest Shade\", \"#FF015A49\": \"Forest Shadows\", \"#FF667028\": \"Forest Spirit\", \"#FF016E61\": \"Forest Splendour\", \"#FFA4BA8A\": \"Forest Tapestry\", \"#FFBBA748\": \"Forest Tent\", \"#FFA88B83\": \"Forest Trail\", \"#FF9AA77C\": \"Forester\", \"#FF007733\": \"Forestial\", \"#FF556611\": \"Forestial Outpost\", \"#FF2F441F\": \"Forestry\", \"#FF4D5346\": \"Forestwood\", \"#FFBBE1E6\": \"Forever\", \"#FF899BB8\": \"Forever Blue\", \"#FF778590\": \"Forever Denim\", \"#FFD2BBB2\": \"Forever Fairytale\", \"#FFEFE6E1\": \"Forever Faithful\", \"#FFAAB4A7\": \"Forever Green\", \"#FFAFA5C7\": \"Forever Lilac\", \"#FF018E8E\": \"Forever Teal\", \"#FF67616B\": \"Forge\", \"#FF555257\": \"Forged Iron\", \"#FF5B5B59\": \"Forged Steel\", \"#FF358094\": \"Forget-Me-Not Blue\", \"#FFE1E1BE\": \"Forgive Quickly\", \"#FFFF1199\": \"Forgiven Sin\", \"#FFC0E5EC\": \"Forgotten Blue\", \"#FFC7B89F\": \"Forgotten Gold\", \"#FF955AF2\": \"Forgotten Kyawthuite\", \"#FFE2D9DB\": \"Forgotten Mosque\", \"#FFFFD9D6\": \"Forgotten Pink\", \"#FF9878F8\": \"Forgotten Purple\", \"#FFAFA696\": \"Forgotten Sandstone\", \"#FFC4BBA5\": \"Forgotten Tusk\", \"#FF34466C\": \"Forlorn Cruise\", \"#FF848391\": \"Formal Affair\", \"#FF3A984D\": \"Formal Garden\", \"#FF97969A\": \"Formal Grey\", \"#FF70474B\": \"Formal Maroon\", \"#FFA69A51\": \"Formosan Green\", \"#FF4E5B52\": \"Forrester\", \"#FFFFC801\": \"Forsythia\", \"#FFF6D76E\": \"Forsythia Blossom\", \"#FFBBCC55\": \"Forsythia Bud\", \"#FFC6C5C1\": \"Fortitude\", \"#FFBEA58E\": \"Fortress\", \"#FFB8B8B8\": \"Fortress Grey\", \"#FF9F97A3\": \"Fortune\", \"#FFE0C5A1\": \"Fortune Cookie\", \"#FFB0534D\": \"Fortune Red\", \"#FFDAA994\": \"Fortune\\u2019s Prize\", \"#FF92345B\": \"Forward Fuchsia\", \"#FF867367\": \"Fossil\", \"#FFA78F65\": \"Fossil Butte\", \"#FF6C6A43\": \"Fossil Green\", \"#FFD2C8BB\": \"Fossil Sand\", \"#FFE3DDCC\": \"Fossil Stone\", \"#FFD1AF90\": \"Fossil Tan\", \"#FFDDCBAF\": \"Fossil White\", \"#FFB6B8B0\": \"Fossilised\", \"#FF756A43\": \"Fossilised Leaf\", \"#FF85C7A1\": \"Foul Green\", \"#FFDECFB3\": \"Found Fossil\", \"#FFF8E8C5\": \"Foundation\", \"#FFEFEEFF\": \"Foundation White\", \"#FF56B5CA\": \"Fountain\", \"#FF65ADB2\": \"Fountain Blue Variant\", \"#FF9CD4CF\": \"Fountain City\", \"#FFC6D0C6\": \"Fountain Foam\", \"#FFE4E4C5\": \"Fountain Frolic\", \"#FFCDEBEC\": \"Fountain Spout\", \"#FFB9DEF0\": \"Fountains of Budapest\", \"#FF738F5D\": \"Four Leaf Clover\", \"#FF6A7252\": \"Four Seasons Oolong\", \"#FF90908B\": \"Four-Wheel Grey\", \"#FFCA4E33\": \"Fox\", \"#FFC8AA92\": \"Fox Hill\", \"#FFBF8E7F\": \"Foxen\", \"#FF9F6949\": \"Foxfire Brown\", \"#FFA2ACC5\": \"Foxflower Viola\", \"#FFB57C8C\": \"Foxglove\", \"#FF454B40\": \"Foxhall Green\", \"#FFBC896E\": \"Foxtail\", \"#FFA85E53\": \"Foxy\", \"#FFD5A6AD\": \"Foxy Lady\", \"#FFDB95AB\": \"Foxy Pink\", \"#FF70625C\": \"Fozzie Bear\", \"#FFBBB8D0\": \"Fragile\", \"#FFE7D7C6\": \"Fragile Beauty\", \"#FFCFD1D3\": \"Fragile Blue\", \"#FFEFF2DB\": \"Fragile Fern\", \"#FF8E545C\": \"Fragrant Cherry\", \"#FFAC5E3A\": \"Fragrant Cloves\", \"#FFEABC83\": \"Fragrant Coriander\", \"#FFFBF6E7\": \"Fragrant Jasmine\", \"#FFCAA7BB\": \"Fragrant Lilac\", \"#FFDCBDC8\": \"Fragrant Orchid\", \"#FFA99FBA\": \"Fragrant Satchel\", \"#FFD5C5D4\": \"Fragrant Snowbell\", \"#FFADB1C1\": \"Fragrant Wand\", \"#FFEE88EE\": \"Frail Fuchsia\", \"#FFE40058\": \"Framboise\", \"#FFF4D5B2\": \"Frangipane\", \"#FFFFD7A0\": \"Frangipani Variant\", \"#FF225288\": \"Frank Blue\", \"#FFEFEBDB\": \"Frank Lloyd White\", \"#FFE5989C\": \"Franken Berry\", \"#FFDCAA6E\": \"Frankincense\", \"#FFE2DBCA\": \"Frankly Earnest\", \"#FFCEAE99\": \"Frapp\\u00e9\", \"#FF9A6840\": \"Frapp\\u00e9 au Chocolat\", \"#FF9B6F55\": \"Freckle Face\", \"#FFAF8B65\": \"Freckled Nose\", \"#FFD78775\": \"Freckles\", \"#FF74A690\": \"Free Green\", \"#FFD1CDCA\": \"Free Reign\", \"#FF029D74\": \"Free Speech Aquamarine\", \"#FF4156C5\": \"Free Speech Blue\", \"#FF09F911\": \"Free Speech Green\", \"#FFE35BD8\": \"Free Speech Magenta\", \"#FFC00000\": \"Free Speech Red\", \"#FFDEEEED\": \"Free Spirit\", \"#FFB29A8B\": \"Free Wheeling\", \"#FF3B5E68\": \"Freedom\", \"#FF657682\": \"Freedom Found\", \"#FF565266\": \"Freefall\", \"#FFF3C12C\": \"Freesia\", \"#FFB3B0D4\": \"Freesia Purple\", \"#FFDEE9F4\": \"Freeze Up\", \"#FFD4E9F5\": \"Freezing Vapour\", \"#FF99EEEE\": \"Freezy Breezy\", \"#FF99FFDD\": \"Freezy Wind\", \"#FF232F36\": \"Freinacht Black\", \"#FFF9F3D5\": \"French 75\", \"#FFA67B50\": \"French Beige Variant\", \"#FFF2D5D4\": \"French Bustle\", \"#FFCDC0B7\": \"French Castle\", \"#FF6A8EA2\": \"French Court\", \"#FFF2C9B1\": \"French Cream\", \"#FFF2E6CF\": \"French Creme\", \"#FF597191\": \"French Diamond\", \"#FFEBC263\": \"French Fry\", \"#FFBFBDC1\": \"French Grey\", \"#FFCAC8B6\": \"French Grey Linen\", \"#FFE9E2E0\": \"French Heirloom\", \"#FFDFC9D1\": \"French Lavender\", \"#FFDEB7D9\": \"French Lilac Variant\", \"#FFADBAE3\": \"French Lilac Blue\", \"#FFC0FF00\": \"French Lime\", \"#FFC9D6C2\": \"French Limestone\", \"#FFFEE6DC\": \"French Manicure\", \"#FFA2C7A3\": \"French Market\", \"#FFAD747D\": \"French Marron\", \"#FF446688\": \"French Mirage Blue\", \"#FF9FBBC3\": \"French Moire\", \"#FFBB9E7C\": \"French Oak\", \"#FFD4AB60\": \"French Pale Gold\", \"#FF9EA07D\": \"French Parsley\", \"#FFA4D2E0\": \"French Pass Variant\", \"#FFC4AA92\": \"French Pastry\", \"#FF9E9F7D\": \"French Pear\", \"#FF811453\": \"French Plum\", \"#FFF6F4F6\": \"French Porcelain\", \"#FFFAF1D7\": \"French Porcelain Clay\", \"#FF4E1609\": \"French Puce\", \"#FF644C48\": \"French Roast\", \"#FFBAB6A0\": \"French Shutter\", \"#FFC0C6D2\": \"French Silk\", \"#FFB8BCBC\": \"French Silver\", \"#FF667255\": \"French Tarragon\", \"#FFD3C2BF\": \"French Taupe\", \"#FFDD8822\": \"French Toast\", \"#FF896D61\": \"French Truffle\", \"#FFEFE1A7\": \"French Vanilla\", \"#FFFBE8CE\": \"French Vanilla Sorbet\", \"#FFF1E7DB\": \"French White\", \"#FFAC1E44\": \"French Wine\", \"#FF991133\": \"French Winery\", \"#FF814A5C\": \"Frenzied Red\", \"#FFFEB101\": \"Frenzy\", \"#FF9CC780\": \"Frenzy Plant\", \"#FFF4DBD9\": \"Fresco\", \"#FF034C67\": \"Fresco Blue\", \"#FFFCC9A6\": \"Fresco Cream\", \"#FF7BD9AD\": \"Fresco Green\", \"#FFD2693E\": \"Fresh Acorn\", \"#FFA6E7FF\": \"Fresh Air\", \"#FF97A346\": \"Fresh Apple\", \"#FFFFD7A5\": \"Fresh Apricot\", \"#FF7C8447\": \"Fresh Artichoke\", \"#FFA52A24\": \"Fresh Auburn\", \"#FFF8D7BE\": \"Fresh Baked Bread\", \"#FF5C5F4B\": \"Fresh Basil\", \"#FF8BD6E2\": \"Fresh Blue\", \"#FF069AF3\": \"Fresh Blue of Bel Air\", \"#FFBEEDDC\": \"Fresh Breeze\", \"#FFB8AA7D\": \"Fresh Brew\", \"#FFFF9C68\": \"Fresh Cantaloupe\", \"#FFA77F74\": \"Fresh Cedar\", \"#FF74754C\": \"Fresh Cilantro\", \"#FF995511\": \"Fresh Cinnamon\", \"#FFBE8035\": \"Fresh Clay\", \"#FFFCF7E0\": \"Fresh Cream\", \"#FFCC9F76\": \"Fresh Croissant\", \"#FF91CB7D\": \"Fresh Cut Grass\", \"#FFB5D9E5\": \"Fresh Dawn\", \"#FFDFE9E5\": \"Fresh Day\", \"#FFF0F4E5\": \"Fresh Dew\", \"#FFF2EBE6\": \"Fresh Dough\", \"#FF4F467E\": \"Fresh Eggplant Variant\", \"#FFFAF4CE\": \"Fresh Eggs\", \"#FFADBCB4\": \"Fresh Eucalyptus\", \"#FFDBE69D\": \"Fresh Frapp\\u00e9\", \"#FFD3691F\": \"Fresh Gingerbread\", \"#FF7FF217\": \"Fresh Granny Smith\", \"#FF69D84F\": \"Fresh Green\", \"#FFF0F7C4\": \"Fresh Grown\", \"#FFA2B07E\": \"Fresh Guacamole\", \"#FFFFAADD\": \"Fresh Gum\", \"#FFD1C1DD\": \"Fresh Heather\", \"#FF77913B\": \"Fresh Herb\", \"#FFF6EFC5\": \"Fresh Honeydew\", \"#FF006A5B\": \"Fresh Ivy Green\", \"#FF8E90B4\": \"Fresh Lavender\", \"#FF88AA00\": \"Fresh Lawn\", \"#FF93EF10\": \"Fresh Leaf\", \"#FFECE678\": \"Fresh Lemonade\", \"#FFB2D58C\": \"Fresh Lettuce\", \"#FFD8F1CB\": \"Fresh Lime\", \"#FFEBE8DA\": \"Fresh Linen\", \"#FF2A5443\": \"Fresh Mint\", \"#FF83D9C5\": \"Fresh Mist\", \"#FF93B654\": \"Fresh Mown\", \"#FFDAA674\": \"Fresh Nectar\", \"#FFFF11FF\": \"Fresh Neon Pink\", \"#FFA69E73\": \"Fresh Olive\", \"#FFFAA9BB\": \"Fresh on the Market\", \"#FF5B8930\": \"Fresh Onion\", \"#FF4FAA6C\": \"Fresh Oregano\", \"#FFF6B98A\": \"Fresh Peaches\", \"#FFD0DD84\": \"Fresh Pear\", \"#FFC2B079\": \"Fresh Peas\", \"#FFA0BD14\": \"Fresh Pesto\", \"#FF4F5B49\": \"Fresh Pine\", \"#FFF3D64F\": \"Fresh Pineapple\", \"#FFE19091\": \"Fresh Pink\", \"#FFF4F3E9\": \"Fresh Popcorn\", \"#FFE7BB95\": \"Fresh Praline\", \"#FF503E2C\": \"Fresh Roe\", \"#FFFF7356\": \"Fresh Salmon\", \"#FFC8A278\": \"Fresh Sawdust\", \"#FFF1C11C\": \"Fresh Scent\", \"#FFF6EFE1\": \"Fresh Snow\", \"#FF91A085\": \"Fresh Sod\", \"#FF6AB9BB\": \"Fresh Soft Blue\", \"#FFC7C176\": \"Fresh Sprout\", \"#FFFFAD00\": \"Fresh Squeezed\", \"#FFCFD4A4\": \"Fresh Start\", \"#FFEECC66\": \"Fresh Straw\", \"#FF505B93\": \"Fresh Take\", \"#FFAEBDA8\": \"Fresh Thyme\", \"#FFB2C7C0\": \"Fresh Tone\", \"#FFDFEBB1\": \"Fresh Up\", \"#FFC6E3F7\": \"Fresh Water\", \"#FFDF9689\": \"Fresh Watermelon\", \"#FFE1D9AA\": \"Fresh Willow\", \"#FFEAE6CC\": \"Fresh Wood Ashes\", \"#FFF7E190\": \"Fresh Yellow\", \"#FFF5E9CF\": \"Fresh Zest\", \"#FFE2BEAB\": \"Fresh-Baked\", \"#FFE9C180\": \"Freshly Baked\", \"#FF5C5083\": \"Freshly Purpleized\", \"#FF663322\": \"Freshly Roasted Coffee\", \"#FFE6F2C4\": \"Freshman\", \"#FF4DA6B2\": \"Freshwater\", \"#FFB5C7A4\": \"Freshwater Green\", \"#FF535644\": \"Freshwater Marsh\", \"#FFE3E1DD\": \"Freshwater Pearls\", \"#FFB2A490\": \"Fretwire\", \"#FFDDB994\": \"Friar Tuck\", \"#FF754E3E\": \"Friar\\u2019s Brown\", \"#FFFFE6C2\": \"Fricass\\u00e9e\", \"#FFB9A161\": \"Frickles\", \"#FFFFE464\": \"Fried Egg\", \"#FFE2F5E1\": \"Friendly Basilisk\", \"#FF3F663E\": \"Friendly Fairway\", \"#FFB3AC36\": \"Friendly Frog\", \"#FFBFFBFF\": \"Friendly Frost\", \"#FFDFDFDD\": \"Friendly Ghost\", \"#FFC8A992\": \"Friendly Homestead\", \"#FFC4A079\": \"Friendly Tan\", \"#FFF5E0B1\": \"Friendly Yellow\", \"#FFE8C5C1\": \"Friends\", \"#FFFED8C2\": \"Friendship\", \"#FF004499\": \"Fright Night\", \"#FFEE77FF\": \"Frijid Pink\", \"#FF939FA9\": \"Frilled Shark\", \"#FF8FA6C1\": \"Frills\", \"#FFB4E1BB\": \"Fringy Flower Variant\", \"#FFCCDDA1\": \"Frisky\", \"#FF7BB1C9\": \"Frisky Blue\", \"#FFBDB8BB\": \"Frisky Whiskers\", \"#FFFEEBC8\": \"Frittata\", \"#FFCFD2C7\": \"Frivolous Folly\", \"#FF58BC08\": \"Frog\", \"#FF00693C\": \"Frog Green\", \"#FF7DA270\": \"Frog Hollow\", \"#FF8FB943\": \"Frog on a Log\", \"#FF73B683\": \"Frog Pond\", \"#FFBBD75A\": \"Frog Prince\", \"#FF8C8449\": \"Frog\\u2019s Legs\", \"#FF8CD612\": \"Frogger\", \"#FF7FBA9E\": \"Froggy Pond\", \"#FFF9E7E1\": \"Frolic\", \"#FFE56D75\": \"Froly Variant\", \"#FF7B7F56\": \"Frond\", \"#FFCDCCC5\": \"Front Porch\", \"#FF314A49\": \"Frontier\", \"#FF9A8172\": \"Frontier Brown\", \"#FFC3B19F\": \"Frontier Fort\", \"#FFBCA59A\": \"Frontier Land\", \"#FF9A794A\": \"Frontier Paradise\", \"#FF655A4A\": \"Frontier Shadow\", \"#FF7B5F46\": \"Frontier Shingle\", \"#FFE1E4C5\": \"Frost Variant\", \"#FF5D9AA6\": \"Frost Blue\", \"#FFBBCFEF\": \"Frost Fairy\", \"#FF8ECB9E\": \"Frost Gum\", \"#FFDAEBEF\": \"Frost Wind\", \"#FFACFFFC\": \"Frostbite Variant\", \"#FFD2C2AC\": \"Frosted Almond\", \"#FF0055DD\": \"Frosted Blueberries\", \"#FFA89C91\": \"Frosted Cocoa\", \"#FF78B185\": \"Frosted Emerald\", \"#FFA7A796\": \"Frosted Fern\", \"#FFB4D5BD\": \"Frosted Fir\", \"#FFE2F7D9\": \"Frosted Garden\", \"#FFEAF0F0\": \"Frosted Glass\", \"#FFD4C4D2\": \"Frosted Grape\", \"#FFAAEEAA\": \"Frosted Hills\", \"#FFB1B9D9\": \"Frosted Iris\", \"#FFC2D1C4\": \"Frosted Jade\", \"#FFF0F4EB\": \"Frosted Juniper\", \"#FFFFEDC7\": \"Frosted Lemon\", \"#FFD3D1DC\": \"Frosted Lilac\", \"#FFE2F2E4\": \"Frosted Mint Variant\", \"#FFCCFFC2\": \"Frosted Mint Hills\", \"#FFBFB3D1\": \"Frosted Orchid\", \"#FFE0FFDF\": \"Frosted Plains\", \"#FFAD3D46\": \"Frosted Pomegranate\", \"#FFC6D1C4\": \"Frosted Sage\", \"#FFC5C9C5\": \"Frosted Silver\", \"#FFD5BCC2\": \"Frosted Sugar\", \"#FFF1DBBF\": \"Frosted Toffee\", \"#FFF6D8D7\": \"Frosted Tulip\", \"#FFDBE5D2\": \"Frostee Variant\", \"#FFFFFBEE\": \"Frosting Cream\", \"#FFDBF2D9\": \"Frostini\", \"#FFD1F0F6\": \"Frostproof\", \"#FFEFF1E3\": \"Frostwork\", \"#FFA1DED6\": \"Frosty\", \"#FFE1809A\": \"Frosty Berry\", \"#FFA4A78E\": \"Frosty Cedar\", \"#FFCBE9C9\": \"Frosty Dawn\", \"#FFCCEBF5\": \"Frosty Day\", \"#FFDEE1E9\": \"Frosty Fog\", \"#FFA0C0BF\": \"Frosty Glade\", \"#FFA3B5A6\": \"Frosty Green\", \"#FFDAE2B2\": \"Frosty Margarita\", \"#FFE2F7F1\": \"Frosty Mint\", \"#FFEFE8E8\": \"Frosty Morning\", \"#FF9497B3\": \"Frosty Nightfall\", \"#FFC7CFBE\": \"Frosty Pine\", \"#FFDFE9E3\": \"Frosty Pink\", \"#FFACCDE5\": \"Frosty Snow Cap\", \"#FFB4E0DE\": \"Frosty Soft Blue\", \"#FF578270\": \"Frosty Spruce\", \"#FFDDDDD6\": \"Frosty White\", \"#FFCCE9E4\": \"Frosty White Blue\", \"#FFC6B8AE\": \"Froth\", \"#FFFAEDE6\": \"Frothy Milk\", \"#FFE7EBE6\": \"Frothy Surf\", \"#FFFBF5D6\": \"Frozen Banana\", \"#FFA5C5D9\": \"Frozen Blue\", \"#FF00EEDD\": \"Frozen Boubble\", \"#FFE1F5E5\": \"Frozen Civilization\", \"#FFFBEABD\": \"Frozen Custard\", \"#FFD1CAA4\": \"Frozen Dew\", \"#FF9CA48A\": \"Frozen Edamame\", \"#FFCFE8B6\": \"Frozen Forest\", \"#FFDDC5D2\": \"Frozen Frapp\\u00e9\", \"#FFE1CA99\": \"Frozen Fruit\", \"#FFDEEADC\": \"Frozen Grass\", \"#FF7B9CB3\": \"Frozen Lake\", \"#FFAEE4FF\": \"Frozen Landscape\", \"#FFDFD9DA\": \"Frozen Mammoth\", \"#FFDBE2CC\": \"Frozen Margarita\", \"#FFC6BB81\": \"Frozen Marguerita\", \"#FFD8E8E6\": \"Frozen Mint\", \"#FFC4EAD5\": \"Frozen Pea\", \"#FFC9D1EF\": \"Frozen Periwinkle\", \"#FFA5B4AE\": \"Frozen Pond\", \"#FFFEA993\": \"Frozen Salmon\", \"#FF26F7FD\": \"Frozen State\", \"#FFE1DEE5\": \"Frozen Statues\", \"#FF30555D\": \"Frozen Stream\", \"#FFDD5533\": \"Frozen Tomato\", \"#FFA3BFCB\": \"Frozen Tundra\", \"#FF53F6FF\": \"Frozen Turquoise\", \"#FFECB3BE\": \"Frozen Veins\", \"#FF56ACCA\": \"Frozen Wave\", \"#FF8BBBDB\": \"Frozen Whisper\", \"#FFA5D7B2\": \"Frugal\", \"#FFFDC9D0\": \"Fruit Bowl\", \"#FFD08995\": \"Fruit Cocktail\", \"#FFCA4F70\": \"Fruit Dove\", \"#FF946985\": \"Fruit of Passion\", \"#FFFA8970\": \"Fruit Red\", \"#FF4BA351\": \"Fruit Salad Variant\", \"#FFF39D8D\": \"Fruit Shake\", \"#FF604241\": \"Fruit Yard\", \"#FFEAC064\": \"Fruit Yellow\", \"#FF773B3E\": \"Fruitful Orchard\", \"#FF448822\": \"Fruitless Fig Tree\", \"#FF9B6E71\": \"Fruitwood\", \"#FFF69092\": \"Fruity Licious\", \"#FFED0DD9\": \"Fuchsia\", \"#FF333322\": \"Fuchsia Berries\", \"#FFE47CB8\": \"Fuchsia Blush\", \"#FFF44772\": \"Fuchsia Felicity\", \"#FFFF5599\": \"Fuchsia Fever\", \"#FFBB22BB\": \"Fuchsia Flair\", \"#FFFF01CD\": \"Fuchsia Flame\", \"#FFDD55CC\": \"Fuchsia Flash\", \"#FFAB446B\": \"Fuchsia Flock\", \"#FFBB2299\": \"Fuchsia Flourish\", \"#FFD800CC\": \"F\\u00fachsia Intenso\", \"#FFCB6E98\": \"Fuchsia Kiss\", \"#FF7722AA\": \"Fuchsia Nebula\", \"#FF9F4CB7\": \"Fuchsia Pheromone\", \"#FFFF77FF\": \"Fuchsia Pink Variant\", \"#FFD33479\": \"Fuchsia Purple\", \"#FFB73879\": \"Fuchsia Red\", \"#FFC74375\": \"Fuchsia Rose\", \"#FFC255C1\": \"Fuchsia Tint\", \"#FFC3D9CE\": \"Fuchsite\", \"#FF5B7E70\": \"Fuchsite Green\", \"#FF583D43\": \"Fudge\", \"#FF997964\": \"Fudge Bar\", \"#FF572B16\": \"Fudge Brownie\", \"#FF604A3F\": \"Fudge Truffle\", \"#FFA88B7F\": \"Fudgecicle\", \"#FFAC6239\": \"Fudgesicle\", \"#FFC77E4D\": \"Fuegan Orange\", \"#FFEE5533\": \"Fuego Variant\", \"#FFEE6622\": \"Fuego Nuevo\", \"#FFC2D62E\": \"Fuego Verde\", \"#FF596472\": \"Fuel Town\", \"#FFD19033\": \"Fuel Yellow Variant\", \"#FFEE66AA\": \"Fugitive Flamingo\", \"#FFF6EEE2\": \"Fuji Peak\", \"#FF89729E\": \"Fuji Purple\", \"#FFF1EFE8\": \"Fuji Snow\", \"#FF766980\": \"Fujinezumi\", \"#FFF5B3CE\": \"Fulgrim Pink\", \"#FFE6B77E\": \"Fulgurite Copper\", \"#FFFBCDC3\": \"Full Bloom\", \"#FF662222\": \"Full City Roast\", \"#FFFAE4CE\": \"Full Cream\", \"#FF1CA350\": \"Full Energy\", \"#FF916B77\": \"Full Glass\", \"#FFF4F3E0\": \"Full Moon\", \"#FFCFEAE9\": \"Full Moon Grey\", \"#FFDE5F2F\": \"Full of Life\", \"#FF320094\": \"Full Swing Indigo\", \"#FFF9BC4F\": \"Full Yellow\", \"#FF514C7E\": \"Fully Purple\", \"#FF33789C\": \"Fun and Games\", \"#FF335083\": \"Fun Blue Variant\", \"#FF15633D\": \"Fun Green Variant\", \"#FFF7E594\": \"Fun Yellow\", \"#FFB6884D\": \"Funchal Yellow\", \"#FF3F6086\": \"Functional Blue\", \"#FFABA39A\": \"Functional Grey\", \"#FFCDD2C9\": \"Fundy Bay\", \"#FFCC00DD\": \"Fungal Hallucinations\", \"#FF8F8177\": \"Fungi\", \"#FFF3D9DC\": \"Funhouse\", \"#FF3EA380\": \"Funk\", \"#FFEE9999\": \"Funki Porcini\", \"#FF4A3C4A\": \"Funkie Friday\", \"#FF98BD3C\": \"Funky Frog\", \"#FFAD4E1A\": \"Funky Monkey\", \"#FFEDD26F\": \"Funky Yellow\", \"#FF113366\": \"Funnel Cloud\", \"#FFEDC8CE\": \"Funny Face\", \"#FFE35519\": \"Furious Fox\", \"#FF55EE00\": \"Furious Frog\", \"#FFEE2277\": \"Furious Fuchsia\", \"#FFE34D41\": \"Furious Pi\\u00f1ata\", \"#FFFF1100\": \"Furious Red\", \"#FFEA5814\": \"Furious Tiger\", \"#FFC30A12\": \"Furious Tomato\", \"#FFDD4124\": \"Furnace\", \"#FFF5EFEB\": \"Furry Lady\", \"#FFF09338\": \"Furry Lion\", \"#FFD2BB79\": \"Further Afield\", \"#FFFF0011\": \"Fury\", \"#FFB56E91\": \"Fuscia Fizz\", \"#FFF1E8D6\": \"Fusilli\", \"#FFB0AE26\": \"Fusion\", \"#FFFF8576\": \"Fusion Coral\", \"#FFFF6163\": \"Fusion Red\", \"#FFE6A3B9\": \"Fussy Pink\", \"#FF614E6E\": \"Futaai Indigo\", \"#FFEDF6DB\": \"Futon\", \"#FF15ABBE\": \"Future\", \"#FFFF2040\": \"Future Fuchsia\", \"#FF20B562\": \"Future Hair\", \"#FFBCB6BC\": \"Future Vision\", \"#FF998DA8\": \"Futuristic\", \"#FFFFEA70\": \"Fuzzy Duckling\", \"#FFFFD69F\": \"Fuzzy Navel\", \"#FFFFBB8F\": \"Fuzzy Peach\", \"#FFECD2B4\": \"Fuzzy Scruff\", \"#FFF0E9D1\": \"Fuzzy Sheep\", \"#FFEAE3DB\": \"Fuzzy Unicorn\", \"#FFCC6666\": \"Fuzzy Wuzzy Variant\", \"#FFAEB1AC\": \"Fynbos Leaf\", \"#FF96834A\": \"G.I.\", \"#FF2C4641\": \"Gable Green Variant\", \"#FF8C6450\": \"Gaboon Viper\", \"#FFDACCA8\": \"Gabriel\\u2019s Light\", \"#FFF8E6C6\": \"Gabriel\\u2019s Torch\", \"#FFFFC4AE\": \"Gadabout\", \"#FFA5B3AB\": \"Gaelic Garden\", \"#FFAC0C20\": \"Gahar\\u0101 L\\u0101l\", \"#FFD3BC9E\": \"Gaia\", \"#FFA4BE8D\": \"Gaia Stone\", \"#FFF4E4E5\": \"Gaiety\", \"#FF785D7A\": \"Gala Ball\", \"#FFB04B63\": \"Gala Pink\", \"#FF442288\": \"Galactic Civilization\", \"#FF48357B\": \"Galactic Compass\", \"#FF111188\": \"Galactic Cruise\", \"#FF0AFA1E\": \"Galactic Emerald\", \"#FF330077\": \"Galactic Federation\", \"#FF7F8CB8\": \"Galactic Gossamer\", \"#FF6B327B\": \"Galactic Grapevine\", \"#FF3311BB\": \"Galactic Highway\", \"#FFE0DFDB\": \"Galactic Mediator\", \"#FF472E97\": \"Galactic Purple\", \"#FFC0C4C6\": \"Galactic Tint\", \"#FF442255\": \"Galactic Wonder\", \"#FFC4DDE2\": \"Galactica\", \"#FF95A69F\": \"Galago\", \"#FFD28083\": \"Galah\", \"#FF085F6D\": \"Galapagos\", \"#FF29685F\": \"Galapagos Green\", \"#FF2E305E\": \"Galaxea\", \"#FF4F4A52\": \"Galaxy\", \"#FF2D5284\": \"Galaxy Blue\", \"#FF444499\": \"Galaxy Express\", \"#FF79AFAD\": \"Galaxy Green\", \"#FF35454E\": \"Gale Force\", \"#FF007844\": \"Gale of the Wind\", \"#FF64776E\": \"Galena\", \"#FF374B52\": \"Galenite Blue\", \"#FF8A8342\": \"Galia Melon\", \"#FFA4763C\": \"Gallant Gold\", \"#FF99AA66\": \"Gallant Green\", \"#FF3F95BF\": \"Galleon Blue\", \"#FF8FA4AC\": \"Galleria Blue\", \"#FFDCD7D1\": \"Gallery Variant\", \"#FF9BBCE4\": \"Gallery Blue\", \"#FF88A385\": \"Gallery Green\", \"#FFC5C2BE\": \"Gallery Grey\", \"#FF935A59\": \"Gallery Red\", \"#FFD0C5B8\": \"Gallery Taupe\", \"#FFEAEBE3\": \"Gallery White\", \"#FFD5AA5E\": \"Galley Gold\", \"#FFD8A723\": \"Galliano Variant\", \"#FFA36629\": \"Gallstone Yellow\", \"#FFE8C8B8\": \"Galveston Tan\", \"#FFC4DDBB\": \"Galway\", \"#FF95A7A4\": \"Galway Bay\", \"#FF996600\": \"Gamboge Brown\", \"#FFE6D058\": \"Gamboge Yellow\", \"#FFE1B047\": \"Gambol Gold\", \"#FF7E8181\": \"Game Over\", \"#FF0F380F\": \"Gameboy Contrast\", \"#FF9BBC0F\": \"Gameboy Light\", \"#FF8BAC0F\": \"Gameboy Screen\", \"#FF306230\": \"Gameboy Shade\", \"#FFBFD1AF\": \"Gamin\", \"#FFC9FF27\": \"G\\u01cen L\\u01cen Hu\\u00e1ng Olive\", \"#FF658B38\": \"G\\u01cen L\\u01cen L\\u01dc Green\", \"#FF372B2C\": \"Ganache\", \"#FF239D42\": \"Gangly Gremlin\", \"#FFFFDD22\": \"Gangsters Gold\", \"#FFA4E4FC\": \"Ganon Blue\", \"#FF8B7D82\": \"Ganymede\", \"#FFF1D5A5\": \"Garbanzo Bean\", \"#FFEEC684\": \"Garbanzo Paste\", \"#FF9FAC98\": \"Garden\", \"#FF9C6989\": \"Garden Aroma\", \"#FF778679\": \"Garden Bower\", \"#FF60784F\": \"Garden Club\", \"#FFD5C5A8\": \"Garden Country\", \"#FF506A48\": \"Garden Cucumber\", \"#FFF1F8EC\": \"Garden Dawn\", \"#FF93B59D\": \"Garden District\", \"#FFCCD4EC\": \"Garden Fairy\", \"#FFA892A8\": \"Garden Flower\", \"#FF729588\": \"Garden Fountain\", \"#FFDADCC1\": \"Garden Gate\", \"#FFABC0BB\": \"Garden Gazebo\", \"#FFD9D7A1\": \"Garden Glade\", \"#FFFFC1D0\": \"Garden Glory\", \"#FF7DCC98\": \"Garden Glow\", \"#FF9B2002\": \"Garden Gnome Red\", \"#FF99CEA0\": \"Garden Goddess\", \"#FF4E6539\": \"Garden Green\", \"#FF658369\": \"Garden Greenery\", \"#FF5E7F57\": \"Garden Grove\", \"#FF6F7D6D\": \"Garden Hedge\", \"#FFE1D4B4\": \"Garden Lattice\", \"#FFD7DEAC\": \"Garden Leek\", \"#FF87762B\": \"Garden Lettuce Green\", \"#FF55422B\": \"Garden Loam\", \"#FF28A873\": \"Garden Medley\", \"#FFCED9C4\": \"Garden Mint\", \"#FFC38E46\": \"Garden Ochre\", \"#FFA09F5B\": \"Garden of Earthly Delights\", \"#FF7FA771\": \"Garden of Eden\", \"#FF8A8D66\": \"Garden of Paradise\", \"#FFE3A4B8\": \"Garden Party\", \"#FF424330\": \"Garden Path\", \"#FFE4E4D5\": \"Garden Pebble\", \"#FFE4D195\": \"Garden Picket\", \"#FF9D8292\": \"Garden Plum\", \"#FFAFC09E\": \"Garden Pond\", \"#FFA4A99B\": \"Garden Promenade\", \"#FFCDBE96\": \"Garden Rain\", \"#FFACCFA9\": \"Garden Room\", \"#FFF7EAD4\": \"Garden Rose White\", \"#FFA18B62\": \"Garden Salt Green\", \"#FFEBE6C7\": \"Garden Seat\", \"#FF334400\": \"Garden Shadow\", \"#FFD6EFDA\": \"Garden Shed\", \"#FFCDB1AB\": \"Garden Snail\", \"#FFB1CA95\": \"Garden Spot\", \"#FFAB863A\": \"Garden Sprout\", \"#FFBFD4C4\": \"Garden Statue\", \"#FF7DC683\": \"Garden Stroll\", \"#FF8CBD97\": \"Garden Swing\", \"#FFA3BBB3\": \"Garden Twilight\", \"#FF66BB8D\": \"Garden Variety\", \"#FF89B89A\": \"Garden View\", \"#FF827799\": \"Garden Violets\", \"#FF9FB1AB\": \"Garden Vista\", \"#FFAEA492\": \"Garden Wall\", \"#FF786E38\": \"Garden Weed\", \"#FF5E602A\": \"Gardener Green\", \"#FF5C534D\": \"Gardener\\u2019s Soil\", \"#FFF1E8DF\": \"Gardenia\", \"#FFACBA8D\": \"Gardening\", \"#FF337700\": \"Gardens Sericourt\", \"#FFA75429\": \"Garfield\", \"#FFEEEE55\": \"Gargantua\", \"#FFABB39E\": \"Gargoyle\", \"#FFFFDF46\": \"Gargoyle Gas\", \"#FF00A4B1\": \"Garish Blue\", \"#FF51BF8A\": \"Garish Green\", \"#FF69887B\": \"Garland\", \"#FFB0AAA1\": \"Garlic Beige\", \"#FFEDDF5E\": \"Garlic Butter\", \"#FFE2D7C1\": \"Garlic Clove\", \"#FFECEACF\": \"Garlic Head\", \"#FFBFCF00\": \"Garlic Pesto\", \"#FFCDD2BC\": \"Garlic Suede\", \"#FFDDDD88\": \"Garlic Toast\", \"#FF733635\": \"Garnet\", \"#FF354A41\": \"Garnet Black Green\", \"#FF763B42\": \"Garnet Evening\", \"#FFCC7446\": \"Garnet Sand\", \"#FFC89095\": \"Garnet Shadow\", \"#FF384866\": \"Garnet Stone Blue\", \"#FF1E9752\": \"Garnish\", \"#FF756861\": \"Garret Brown\", \"#FF7B8588\": \"Garrison Grey\", \"#FFFFBB31\": \"Garuda Gold\", \"#FF98DCFF\": \"Gas Giant\", \"#FFFEFFEA\": \"Gaslight\", \"#FFD2935D\": \"Gates of Gold\", \"#FF88796C\": \"Gateway Arch\", \"#FFA0A09C\": \"Gateway Grey\", \"#FFB2AC9C\": \"Gateway Pillar\", \"#FFAB8F55\": \"Gathering Field\", \"#FFAD9466\": \"Gathering Place\", \"#FF665E43\": \"Gator Tail\", \"#FF8E3B2F\": \"Gatsby Brick\", \"#FFEED683\": \"Gatsby Glitter\", \"#FF78736E\": \"Gauntlet Grey\", \"#FF84C3AA\": \"Gauss Blaster Green\", \"#FFC8E1E9\": \"Gauzy Calico\", \"#FFE3DBD4\": \"Gauzy White\", \"#FF76826C\": \"Gazebo Green\", \"#FFD1D0CB\": \"Gazebo Grey\", \"#FF947E68\": \"Gazelle\", \"#FF9D913C\": \"Gecko\", \"#FF669900\": \"Gecko\\u2019s Dream\", \"#FFAAC69A\": \"Geddy Green\", \"#FF7F4C00\": \"G\\u00e9d\\u00e9on Brown\", \"#FF40534E\": \"Gedney Green\", \"#FFC5832E\": \"Geebung Variant\", \"#FFB0A677\": \"Geek Chic\", \"#FFDBA674\": \"Gehenna\\u2019s Gold\", \"#FFDD44FF\": \"Geisha Pink\", \"#FFB5ACB2\": \"Gellibrand\", \"#FF4D5B8A\": \"Gem\", \"#FF73C4A4\": \"Gem Silica\", \"#FF53C2C3\": \"Gem Turquoise\", \"#FFB4D6CB\": \"Gemini\", \"#FFFCA750\": \"Gemini Mustard Momento\", \"#FF004F6D\": \"Gemstone Blue\", \"#FF4B6331\": \"Gemstone Green\", \"#FFF4E386\": \"Gen Z Yellow\", \"#FF7761AB\": \"Genestealer Purple\", \"#FF18515D\": \"Genetic Code\", \"#FF1F7F76\": \"Geneva Green\", \"#FFBAB7B8\": \"Geneva Morn\", \"#FF33673F\": \"Genever Green\", \"#FFBCC4E0\": \"Genevieve\", \"#FF5F4871\": \"Gengiana\", \"#FF3E4364\": \"Genie\", \"#FF31796D\": \"Genoa Variant\", \"#FF698EB3\": \"Genteel Blue\", \"#FFE2E6EC\": \"Genteel Lavender\", \"#FF9079AD\": \"Gentian\", \"#FF312297\": \"Gentian Blue\", \"#FF57487F\": \"Gentian Violet\", \"#FFCEAF93\": \"Gentility\", \"#FF97CBD2\": \"Gentle Aquamarine\", \"#FFCDD2DE\": \"Gentle Blue\", \"#FFC4CEBF\": \"Gentle Calm\", \"#FFFCD7BA\": \"Gentle Caress\", \"#FFC3ECE9\": \"Gentle Cold\", \"#FFC3CC6E\": \"Gentle Dill\", \"#FFE8B793\": \"Gentle Doe\", \"#FFE6C9A4\": \"Gentle Fawn\", \"#FFDCE0CD\": \"Gentle Frost\", \"#FFB3EBE0\": \"Gentle Giant\", \"#FFF6E5B9\": \"Gentle Glow\", \"#FF908A9B\": \"Gentle Grape\", \"#FFDEE0E1\": \"Gentle Grey\", \"#FFEBC4BF\": \"Gentle Kiss\", \"#FFE3D9C8\": \"Gentle Lamb\", \"#FFA5CE8F\": \"Gentle Landscape\", \"#FF958C9E\": \"Gentle Mauve\", \"#FFCBC9C5\": \"Gentle Rain\", \"#FFB0C8D0\": \"Gentle Sea\", \"#FFD6CBBA\": \"Gentle Shadows\", \"#FF99BDD2\": \"Gentle Sky\", \"#FFE5D4BE\": \"Gentle Slumber\", \"#FFC3BFAE\": \"Gentle Soul\", \"#FFE3D5B8\": \"Gentle Touch\", \"#FFDAD5D9\": \"Gentle Violet\", \"#FF7AC0BB\": \"Gentle Wave\", \"#FFABD0EA\": \"Gentle Wind\", \"#FFFFF5BE\": \"Gentle Yellow\", \"#FFCA882C\": \"Gentleman\\u2019s Whiskey\", \"#FFF1E68C\": \"Gentlemann\\u2019s Business Pants\", \"#FFBDAE9E\": \"Gentry Grey\", \"#FF4B3F69\": \"Geode\", \"#FFB06144\": \"Georgia Clay\", \"#FFF97272\": \"Georgia Peach\", \"#FF22657F\": \"Georgian Bay\", \"#FFCF875E\": \"Georgian Leather\", \"#FFC6B8B4\": \"Georgian Pink\", \"#FF5B8D9F\": \"Georgian Revival Blue\", \"#FFD1974C\": \"Georgian Yellow\", \"#FFE77B75\": \"Geraldine Variant\", \"#FFDC465D\": \"Geranium\", \"#FFCFA1C7\": \"Geranium Bud\", \"#FF90AC74\": \"Geranium Leaf\", \"#FF9B8C7B\": \"German Camouflage Beige\", \"#FF53504E\": \"German Grey\", \"#FF89AC27\": \"German Hop\", \"#FF2E3749\": \"German Liquorice\", \"#FFCD7A00\": \"German Mustard\", \"#FF0094C8\": \"Germander Speedwell\", \"#FFDDC47E\": \"Germania\", \"#FF1A9D49\": \"Get up and Go\", \"#FFAC9B7B\": \"Getaway\", \"#FFC3DAE3\": \"Getting Wet\", \"#FFC7C1B7\": \"Gettysburg Grey\", \"#FFC4D7CF\": \"Geyser Variant\", \"#FFE3CAB5\": \"Geyser Basin\", \"#FFA9DCE2\": \"Geyser Pool\", \"#FFCBD0CF\": \"Geyser Steam\", \"#FFD8BC23\": \"Ghee Yellow\", \"#FFC0BFC7\": \"Ghost Variant\", \"#FFDFEDDA\": \"Ghost Lichen\", \"#FFC10102\": \"Ghost Pepper\", \"#FF887B6E\": \"Ghost Ship\", \"#FFE3E4DB\": \"Ghost Story\", \"#FFBEB6A8\": \"Ghost Town\", \"#FFCBD1D0\": \"Ghost Whisperer\", \"#FFBCB7AD\": \"Ghost Writer\", \"#FFE2E0DC\": \"Ghosted\", \"#FFCAC6BA\": \"Ghosting\", \"#FF113C42\": \"Ghostlands Coal\", \"#FFA7A09F\": \"Ghostly\", \"#FFD9D7B8\": \"Ghostly Green\", \"#FFCCCCD3\": \"Ghostly Grey\", \"#FF7B5D92\": \"Ghostly Purple\", \"#FFE2E6EF\": \"Ghostly Tuna\", \"#FFE2DBDB\": \"Ghostwaver\", \"#FF667744\": \"Ghoul\", \"#FFF1D236\": \"Giallo\", \"#FF88763F\": \"Giant Cactus Green\", \"#FF665D9E\": \"Giant Onion\", \"#FFB05C52\": \"Giant\\u2019s Club\", \"#FFFE5A1D\": \"Giants Orange\", \"#FF626970\": \"Gibraltar\", \"#FF6F6A68\": \"Gibraltar Grey\", \"#FF133A54\": \"Gibraltar Sea\", \"#FF9FC0CE\": \"Gift of the Sea\", \"#FF564786\": \"Gigas Variant\", \"#FFEFF0D3\": \"Giggle\", \"#FFF4DB4F\": \"Gilded\", \"#FFE4B46E\": \"Gilded Age\", \"#FFB39F8D\": \"Gilded Beige\", \"#FF956841\": \"Gilded Glamour\", \"#FFB58037\": \"Gilded Gold\", \"#FFEBA13C\": \"Gilded Leaves\", \"#FFDAD5C9\": \"Gilded Linen\", \"#FFC09E6C\": \"Gilded Pear\", \"#FFBBAF5E\": \"Gilded Pesto\", \"#FFCD9D99\": \"Gilman Rose\", \"#FF6C8396\": \"Gilneas Grey\", \"#FFE6AD67\": \"Gilt Trip\", \"#FFB9AD61\": \"Gimblet Variant\", \"#FFD9DFCD\": \"Gin Variant\", \"#FFA3B9B6\": \"Gin Berry\", \"#FFF8EACA\": \"Gin Fizz Variant\", \"#FFBA8E5A\": \"Gin Still\", \"#FFECEBE5\": \"Gin Tonic\", \"#FFB06500\": \"Ginger\", \"#FFC9A86A\": \"Ginger Ale\", \"#FFF5DFBC\": \"Ginger Ale Fizz\", \"#FFC27F38\": \"Ginger Beer\", \"#FFEFE0D7\": \"Ginger Cream\", \"#FFCE915A\": \"Ginger Crisp\", \"#FFCEAA64\": \"Ginger Crunch\", \"#FFB06D3B\": \"Ginger Dough\", \"#FF97653C\": \"Ginger Dy\", \"#FFCF524E\": \"Ginger Flower\", \"#FF996251\": \"Ginger Gold\", \"#FFB8A899\": \"Ginger Grey Yellow\", \"#FFC6A05E\": \"Ginger Jar\", \"#FFF1E991\": \"Ginger Lemon Cake\", \"#FFFFFFAA\": \"Ginger Lemon Tea\", \"#FFF7A454\": \"Ginger Milk\", \"#FFF9D09F\": \"Ginger Peach\", \"#FF9A7D61\": \"Ginger Pie\", \"#FFC17444\": \"Ginger Root\", \"#FFF0C48C\": \"Ginger Root Peel\", \"#FFBE8774\": \"Ginger Rose\", \"#FFCB8F7B\": \"Ginger Scent\", \"#FFE3CEC6\": \"Ginger Shortbread\", \"#FFB65D48\": \"Ginger Spice\", \"#FFDDDACE\": \"Ginger Sugar\", \"#FFB19D77\": \"Ginger Tea\", \"#FFCC8877\": \"Ginger Whisper\", \"#FF8C4A2F\": \"Gingerbread\", \"#FF956A43\": \"Gingerbread Brick\", \"#FF9C5E33\": \"Gingerbread Crumble\", \"#FFCA994E\": \"Gingerbread House\", \"#FFB39479\": \"Gingerbread Latte\", \"#FFFFDD11\": \"Gingerline\", \"#FFC79E73\": \"Gingersnap\", \"#FFB06C3E\": \"Gingery\", \"#FFA3C899\": \"Gingko\", \"#FFB3A156\": \"Gingko Leaf\", \"#FF918260\": \"Gingko Tree\", \"#FFA5ACA4\": \"Ginkgo Green\", \"#FF858F79\": \"Ginkgo Tree\", \"#FF97867C\": \"Ginnezumi\", \"#FFB3D5C0\": \"Ginninderra\", \"#FFF3E9BD\": \"Ginseng\", \"#FFE6CDB5\": \"Ginseng Root\", \"#FFBC2D29\": \"Ginshu\", \"#FFB3CEAB\": \"Gio Ponti Green\", \"#FFD1C0DC\": \"Girl Crush\", \"#FFD39BCB\": \"Girl Power\", \"#FFE4C7C8\": \"Girl Talk\", \"#FFFFD3CF\": \"Girlie\", \"#FF5A82AC\": \"Girls in Blue\", \"#FFF6E6E5\": \"Girly Nursery\", \"#FFEE88FF\": \"Give Me Your Love\", \"#FFEBD4AE\": \"Givry Variant\", \"#FFD4A1B5\": \"Gizmo\", \"#FFD1DAD7\": \"Glacial\", \"#FFDEF7FE\": \"Glacial Day\", \"#FFC3FBF4\": \"Glacial Drift\", \"#FF6FB7A8\": \"Glacial Green\", \"#FFEAE9E7\": \"Glacial Ice\", \"#FFBCD8E2\": \"Glacial Stream\", \"#FFEAF2ED\": \"Glacial Tint\", \"#FFC9EAD4\": \"Glacial Water Green\", \"#FF78B1BF\": \"Glacier Variant\", \"#FFDEF2EE\": \"Glacier Bay\", \"#FFA9C1C0\": \"Glacier Blue\", \"#FFBBBCBD\": \"Glacier Grey\", \"#FFEAF3E6\": \"Glacier Ivy\", \"#FF62B4C0\": \"Glacier Lake\", \"#FFAABCCB\": \"Glacier Mist\", \"#FFD1D2DC\": \"Glacier Pearl\", \"#FFB3D8E5\": \"Glacier Point\", \"#FFE2E3D7\": \"Glacier Valley\", \"#FFF5E1AC\": \"Glad Yellow\", \"#FF9CA687\": \"Glade\", \"#FF5F8151\": \"Glade Green Variant\", \"#FF7A8CA6\": \"Gladeye\", \"#FF6E6C5E\": \"Gladiator Grey\", \"#FFA95C3E\": \"Gladiator Leather\", \"#FFD54F43\": \"Gladiola\", \"#FF6370B6\": \"Gladiola Blue\", \"#FF6E5178\": \"Gladiola Violet\", \"#FFCF748C\": \"Glam\", \"#FFDACBA7\": \"Glamorgan Sausage\", \"#FFB74E64\": \"Glamorous\", \"#FFC5AEA6\": \"Glamorous Taupe\", \"#FFF0EAE0\": \"Glamorous White\", \"#FFDB9DA7\": \"Glamour\", \"#FF007488\": \"Glamour Green\", \"#FFFFFCEC\": \"Glamour White\", \"#FFBDB8AE\": \"Glasgow Fog\", \"#FFC7BEC4\": \"Glass Bead\", \"#FF880000\": \"Glass Bull\", \"#FFDCDFB0\": \"Glass Green\", \"#FFFCF3DD\": \"Glass of Milk\", \"#FFDBD8CB\": \"Glass Pebble\", \"#FFCDB69B\": \"Glass Sand\", \"#FF587B9B\": \"Glass Sapphire\", \"#FFCDD0C0\": \"Glass Tile\", \"#FFB7A2CC\": \"Glass Violet\", \"#FFD7E2E5\": \"Glassine\", \"#FF46B5C0\": \"Glassmith\", \"#FFD1D9DA\": \"Glassware\", \"#FF3A3F45\": \"Glaucophobia\", \"#FFB3E8C2\": \"Glaucous Green\", \"#FF967217\": \"Glazed Chestnut\", \"#FFA15C30\": \"Glazed Ginger\", \"#FF5B5E61\": \"Glazed Granite\", \"#FFEFE3D2\": \"Glazed Pears\", \"#FFD19564\": \"Glazed Pecan\", \"#FFD34E36\": \"Glazed Persimmon\", \"#FFAD7356\": \"Glazed Pot\", \"#FFA44B62\": \"Glazed Raspberry\", \"#FF89626D\": \"Glazed Ringlet\", \"#FFFFDCCC\": \"Glazed Sugar\", \"#FFB9CBA3\": \"Gleam\", \"#FFF8DED1\": \"Gleaming Shells\", \"#FFB88C63\": \"Gleaming Tan\", \"#FF9DBB7D\": \"Gleeful\", \"#FFA892B4\": \"Gleeful Joy\", \"#FF4AAC72\": \"Glen\", \"#FFACB8C1\": \"Glen Falls\", \"#FF82817C\": \"Glen Plaid\", \"#FFA1BB8B\": \"Glendale\", \"#FFA7D3B7\": \"Glenwood Green\", \"#FF5D6F80\": \"Glide Time\", \"#FFD7D8D9\": \"Gliding Feather\", \"#FFE1E8E3\": \"Glimmer\", \"#FF4FB9CE\": \"Glimpse\", \"#FF121210\": \"Glimpse Into Space\", \"#FFFFF3F4\": \"Glimpse of Pink\", \"#FF335588\": \"Glimpse of Void\", \"#FFF2EFDC\": \"Glisten Green\", \"#FFF5E6AC\": \"Glisten Yellow\", \"#FFEED288\": \"Glistening\", \"#FFF6BA25\": \"Glistening Dawn\", \"#FFB1B3BE\": \"Glistening Grey\", \"#FF2C5463\": \"Glitch\", \"#FFE6E8FA\": \"Glitter\", \"#FFFEDC57\": \"Glitter Is Not Gold\", \"#FF44BBFF\": \"Glitter Lake\", \"#FF88FFFF\": \"Glitter Shower\", \"#FFF8D75A\": \"Glitter Yellow\", \"#FF944A63\": \"Glitterati\", \"#FFDEC0E2\": \"Glittering Gemstone\", \"#FFD3AD77\": \"Glittering Sun\", \"#FFEEEDDB\": \"Glittery Glow\", \"#FFF9EECD\": \"Glittery Yellow\", \"#FF965F73\": \"Glitz and Glamour\", \"#FFD6A02B\": \"Glitzy Gold\", \"#FFAF413B\": \"Glitzy Red\", \"#FFB4BE93\": \"Gloaming Green\", \"#FF696E51\": \"Global Green\", \"#FFF1D7D3\": \"Global Warming\", \"#FF5F6C3C\": \"Globe Artichoke\", \"#FF998D8D\": \"Globe Thistle Grey Rose\", \"#FF3C416A\": \"Gloomy Blue\", \"#FF8756E4\": \"Gloomy Purple\", \"#FF4A657A\": \"Gloomy Sea\", \"#FFCBA956\": \"Glorious Gold\", \"#FFAAEE11\": \"Glorious Green Glitter\", \"#FFFE2F4A\": \"Glorious Red\", \"#FFF88517\": \"Glorious Sunset\", \"#FF110011\": \"Glossy Black\", \"#FFFFDD77\": \"Glossy Gold\", \"#FFEEE3DE\": \"Glossy Kiss\", \"#FF636340\": \"Glossy Olive\", \"#FFF9F2DA\": \"Glow\", \"#FFFBE8C1\": \"Glow Home\", \"#FFBEFDB7\": \"Glow in the Dark\", \"#FFBED565\": \"Glow Worm\", \"#FFEE4444\": \"Glowing Brake Disc\", \"#FFBC4D39\": \"Glowing Coals\", \"#FFAF5941\": \"Glowing Firelight\", \"#FFD0D4C0\": \"Glowing Green\", \"#FFFBB736\": \"Glowing Lantern\", \"#FFEE4400\": \"Glowing Meteor\", \"#FFFFD15A\": \"Glowing Reviews\", \"#FFBD4649\": \"Glowing Scarlet\", \"#FFFFF6B9\": \"Glowlight\", \"#FF693162\": \"Gloxinia\", \"#FF1A1B1C\": \"Gluon Grey\", \"#FFDDCC66\": \"Gluten\", \"#FF00754B\": \"Gnarls Green\", \"#FFFFEEBB\": \"Gnocchi Beige\", \"#FF81A19B\": \"Gnome\", \"#FFADC484\": \"Gnome Green\", \"#FFB09F84\": \"Gnu Tan\", \"#FF007F87\": \"Go Alpha\", \"#FFF7CA50\": \"Go Bananas\", \"#FF786E4C\": \"Go Ben Variant\", \"#FFFCECD5\": \"Go Go Glow\", \"#FF008A7D\": \"Go Go Green\", \"#FFC6BE6B\": \"Go Go Lime\", \"#FFFEB87E\": \"Go Go Mango\", \"#FFFDD8D4\": \"Go Go Pink\", \"#FFDCD8D7\": \"Go\", \"#FF342C21\": \"Go Variant\", \"#FFA89A91\": \"Goat\", \"#FF5E5A6A\": \"Gobelin Mauve\", \"#FFEBDACE\": \"Gobi Beige\", \"#FFCDBBA2\": \"Gobi Desert\", \"#FFCFA56D\": \"Gobi Gold\", \"#FFD4AA6F\": \"Gobi Sand\", \"#FFBBA587\": \"Gobi Tan\", \"#FFDB4731\": \"Goblet Waxcap\", \"#FF34533D\": \"Goblin Variant\", \"#FF5F7278\": \"Goblin Blue\", \"#FFEB8931\": \"Goblin Eyes\", \"#FF4EFD54\": \"Goblin Warboss\", \"#FF770000\": \"Gochujang Red\", \"#FF550066\": \"God of Nights\", \"#FF4466CC\": \"God of Rain\", \"#FFFAF4E0\": \"God-Given\", \"#FFF56991\": \"God\\u2019s Own Junkyard Pink\", \"#FFD0E1E8\": \"Goddess\", \"#FF904C6F\": \"Goddess of Dawn\", \"#FF5D7F9D\": \"Goddess of the Nile\", \"#FF3C4D03\": \"Godzilla\", \"#FF0087A1\": \"Gogo Blue\", \"#FF83807A\": \"Going Grey\", \"#FFAB858F\": \"Going Rouge\", \"#FFCC142F\": \"Goji Berry\", \"#FFF0833A\": \"Goku Orange\", \"#FFF3BC00\": \"Gold Abundance\", \"#FF2A2424\": \"Gold Black\", \"#FFECC481\": \"Gold Buff\", \"#FFEEDD99\": \"Gold Bullion\", \"#FFFFE8BB\": \"Gold Buttercup\", \"#FFAE9769\": \"Gold Canyon\", \"#FFC78538\": \"Gold Coast\", \"#FFDF9938\": \"Gold Crest\", \"#FFE0CE57\": \"Gold Deposit\", \"#FFD1B075\": \"Gold Digger\", \"#FFD56C30\": \"Gold Drop Variant\", \"#FFA4803F\": \"Gold Dust\", \"#FFDB9663\": \"Gold Earth\", \"#FF977A41\": \"Gold Estate\", \"#FFB44F22\": \"Gold Flame\", \"#FFD99F4D\": \"Gold Foil\", \"#FFEB9600\": \"Gold Fusion Variant\", \"#FFCFB352\": \"Gold Gleam\", \"#FFECE086\": \"Gold Grillz\", \"#FFE6C28C\": \"Gold Hearted\", \"#FFB1A57B\": \"Gold Infusion\", \"#FFEDBB26\": \"Gold Leaf\", \"#FFB17743\": \"Gold Metal\", \"#FFFFEAC7\": \"Gold of Midas\", \"#FFDB7210\": \"Gold Orange\", \"#FFECBC14\": \"Gold Ore\", \"#FFCAAF81\": \"Gold Perennial\", \"#FFC6795F\": \"Gold Pheasant\", \"#FFE6BD8F\": \"Gold Plate\", \"#FFB0834F\": \"Gold Plated\", \"#FFB39260\": \"Gold Ransom\", \"#FFEB5406\": \"Gold Red\", \"#FFC4A777\": \"Gold Rush\", \"#FFF7E5A9\": \"Gold Sand Variant\", \"#FFB19971\": \"Gold Season\", \"#FF786B3D\": \"Gold Sparkle\", \"#FFC19D61\": \"Gold Spell\", \"#FF907047\": \"Gold Spike\", \"#FFF3DFA6\": \"Gold Strand\", \"#FFBB9A39\": \"Gold Taffeta\", \"#FF9E865E\": \"Gold Tangiers\", \"#FFFEE8B0\": \"Gold Thread\", \"#FFDEC283\": \"Gold Tint\", \"#FFE2B227\": \"Gold Tips Variant\", \"#FFDBB40C\": \"Gold Tooth\", \"#FFBD955E\": \"Gold Torch\", \"#FFC9AB73\": \"Gold Tweed\", \"#FFB95E33\": \"Gold Varnish Brown\", \"#FFD6B956\": \"Gold Vein\", \"#FFEABA8A\": \"Gold Vessel\", \"#FFD4C19E\": \"Gold Wash\", \"#FFE6D682\": \"Gold Winged\", \"#FFFFC265\": \"Gold\\u2019s Great Touch\", \"#FF9C8A53\": \"Goldbrown\", \"#FFF5BF03\": \"Golden\", \"#FFCEAB77\": \"Golden Age\", \"#FFCEA644\": \"Golden Age Gilt\", \"#FFE6BE59\": \"Golden Appeal\", \"#FFF3D74F\": \"Golden Apples\", \"#FFDBA950\": \"Golden Apricot\", \"#FFD29E68\": \"Golden Aura\", \"#FFFFEE77\": \"Golden Aurelia\", \"#FFCDA64A\": \"Golden Avocado\", \"#FFFCC62A\": \"Golden Banner\", \"#FFDABA55\": \"Golden Bass\", \"#FFBA985F\": \"Golden Bear\", \"#FFCEA277\": \"Golden Beige\", \"#FFCA8136\": \"Golden Bell Variant\", \"#FFD9A400\": \"Golden Beryl Yellow\", \"#FFCCAA55\": \"Golden Blond\", \"#FFEFE17E\": \"Golden Blonde\", \"#FFFF1155\": \"Golden Blood\", \"#FFFFDD44\": \"Golden Boy\", \"#FFB27A01\": \"Golden Brown Variant\", \"#FFFFCC22\": \"Golden Buddha Belly\", \"#FFF8E6C8\": \"Golden Buff\", \"#FFFFD96D\": \"Golden Butter\", \"#FFAC864B\": \"Golden Cadillac\", \"#FFE7C068\": \"Golden Chalice\", \"#FFDDDD11\": \"Golden Chandelier\", \"#FFEEB574\": \"Golden Chime\", \"#FFF4CE74\": \"Golden Churro\", \"#FFECC799\": \"Golden City Moon\", \"#FF968651\": \"Golden Clay\", \"#FFFCD975\": \"Golden Coin\", \"#FFF0B672\": \"Golden Corn\", \"#FFF7B768\": \"Golden Cream\", \"#FFECC909\": \"Golden Crescent\", \"#FFF6CA69\": \"Golden Crest\", \"#FFCCDDBB\": \"Golden Crested Wren\", \"#FFD7B056\": \"Golden Cricket\", \"#FFD2D88F\": \"Golden Delicious\", \"#FFF1CC2B\": \"Golden Dream Variant\", \"#FFD8C39F\": \"Golden Ecru\", \"#FFB29155\": \"Golden Egg\", \"#FFBDD5B1\": \"Golden Elm\", \"#FFC39E44\": \"Golden Field\", \"#FFEBDE31\": \"Golden Fizz Variant\", \"#FFEDD9AA\": \"Golden Fleece\", \"#FFF0EAD2\": \"Golden Fog\", \"#FFCCCC00\": \"Golden Foil\", \"#FFBDD043\": \"Golden Foliage\", \"#FFEEEE99\": \"Golden Fragrance\", \"#FFE2B31B\": \"Golden Frame\", \"#FF876F4D\": \"Golden Freesia\", \"#FFD9C09C\": \"Golden Gate\", \"#FFC0362D\": \"Golden Gate Bridge\", \"#FFF9F525\": \"Golden Ginkgo\", \"#FFEEBB44\": \"Golden Glam\", \"#FFFBE573\": \"Golden Glitter\", \"#FFEAD771\": \"Golden Glitter Storm\", \"#FF9E7551\": \"Golden Glove\", \"#FFF9D77E\": \"Golden Glow Variant\", \"#FFFFD34E\": \"Golden Goose\", \"#FFC59137\": \"Golden Grain\", \"#FFB8996B\": \"Golden Granola\", \"#FFDAA631\": \"Golden Grass Variant\", \"#FFBDB369\": \"Golden Green\", \"#FFA99058\": \"Golden Griffon\", \"#FFE1C3BB\": \"Golden Guernsey\", \"#FFDDDD00\": \"Golden Gun\", \"#FFDA9E38\": \"Golden Hamster\", \"#FFFFCC44\": \"Golden Handshake\", \"#FF9F8046\": \"Golden Harmony\", \"#FFCCCC11\": \"Golden Harvest\", \"#FFEDDFC1\": \"Golden Haystack\", \"#FFFCD896\": \"Golden Haze\", \"#FFFFFFBB\": \"Golden Hermes\", \"#FFA37111\": \"Golden Hind\", \"#FFBB993A\": \"Golden History\", \"#FFEDC283\": \"Golden Hominy\", \"#FFFFDB29\": \"Golden Honey Suckle\", \"#FFCFDD7B\": \"Golden Hop\", \"#FFF1B457\": \"Golden Hour\", \"#FFFFEFCB\": \"Golden Impression\", \"#FFDD9911\": \"Golden Key\", \"#FFE0C84B\": \"Golden Kingdom\", \"#FFF2CF34\": \"Golden Kiwi\", \"#FFEAA34B\": \"Golden Koi\", \"#FFD8C7A2\": \"Golden Lake\", \"#FFC48B42\": \"Golden Leaf\", \"#FF928D35\": \"Golden Lime\", \"#FFF3CA6C\": \"Golden Lion\", \"#FFCA602A\": \"Golden Lion Tamarin\", \"#FFF5BC1D\": \"Golden Lock\", \"#FFE9DBC4\": \"Golden Lotus\", \"#FFFDCC37\": \"Golden Marguerite\", \"#FFF0BE3A\": \"Golden Mary\", \"#FFC49B35\": \"Golden Mean\", \"#FFD4C990\": \"Golden Mist\", \"#FFFFCF60\": \"Golden Moray Eel\", \"#FFB39B67\": \"Golden Moss\", \"#FFF4E8D1\": \"Golden Mushroom\", \"#FFFFDA68\": \"Golden Nectar\", \"#FFD78E48\": \"Golden Nugget\", \"#FFA96A28\": \"Golden Oak\", \"#FFECBE91\": \"Golden Oat Coloured\", \"#FFC56F3B\": \"Golden Ochre\", \"#FFAB9C40\": \"Golden Olive\", \"#FFF7C070\": \"Golden Opportunity\", \"#FFD7942D\": \"Golden Orange\", \"#FFD3B66C\": \"Golden Pagoda\", \"#FFA58705\": \"Golden Palm\", \"#FFB4BB31\": \"Golden Passionfruit\", \"#FFF4D9B9\": \"Golden Pastel\", \"#FFE4AA76\": \"Golden Patina\", \"#FFFEDB2D\": \"Golden Period\", \"#FFCF9632\": \"Golden Pheasant\", \"#FF956F3F\": \"Golden Pilsner\", \"#FFFBD073\": \"Golden Plumeria\", \"#FFEBCEBD\": \"Golden Pop\", \"#FFFFC64D\": \"Golden Promise\", \"#FFCA884B\": \"Golden Pumpkin\", \"#FFAA8A58\": \"Golden Quartz Ochre\", \"#FFFFB657\": \"Golden Rain Yellow\", \"#FFF8D878\": \"Golden Raspberry\", \"#FFF6DA74\": \"Golden Rays\", \"#FFE8CE49\": \"Golden Relic\", \"#FFEEDEC7\": \"Golden Retriever\", \"#FFE3D474\": \"Golden Rice\", \"#FFDAAE49\": \"Golden Rule\", \"#FFB09D73\": \"Golden Sage\", \"#FFDFAF2B\": \"Golden Samovar\", \"#FFEACE6A\": \"Golden Sand Variant\", \"#FFEED280\": \"Golden Sap\", \"#FFEDDB8E\": \"Golden Scarab\", \"#FFDDBB11\": \"Golden Schnitzel\", \"#FFCCA24D\": \"Golden Sheaf\", \"#FFB98841\": \"Golden Slumber\", \"#FFF1E346\": \"Golden Snitch\", \"#FFFECC36\": \"Golden Spell\", \"#FFC6973F\": \"Golden Spice\", \"#FFF6D263\": \"Golden Sprinkles\", \"#FFF7EB83\": \"Golden Staff\", \"#FFF5EDAE\": \"Golden Straw\", \"#FF816945\": \"Golden Summer\", \"#FFEBD8B3\": \"Golden Syrup\", \"#FFFFC152\": \"Golden Tainoi Variant\", \"#FFE9C89B\": \"Golden Talisman\", \"#FFCAA375\": \"Golden Thistle Yellow\", \"#FFE8C47A\": \"Golden Thread\", \"#FFF5CC23\": \"Golden Ticket\", \"#FFE1A451\": \"Golden Tiger\", \"#FFCAA444\": \"Golden Touch\", \"#FFFFB118\": \"Golden Treasure\", \"#FFE8C954\": \"Golden Trident\", \"#FFFFFEC6\": \"Golden Wash\", \"#FFEADCC0\": \"Golden Weave\", \"#FFECD251\": \"Golden Week\", \"#FFE9CA94\": \"Golden West\", \"#FFE2C74F\": \"Golden Yarrow\", \"#FFFDCB18\": \"Goldenrod Variant\", \"#FFF0B053\": \"Goldenrod Field\", \"#FFA17841\": \"Goldenrod Tea\", \"#FFFFCE8F\": \"Goldenrod Yellow\", \"#FFF8E462\": \"Goldfinch\", \"#FFEEBB11\": \"Goldfinger\", \"#FFF2AD62\": \"Goldfish\", \"#FFCEB790\": \"Goldfrapp\", \"#FFC89D3F\": \"Goldie\", \"#FFBAAD75\": \"Goldie Oldie\", \"#FFFFF39A\": \"Goldilocks\", \"#FFEEB550\": \"Goldsmith\", \"#FFE7DE54\": \"Goldvreneli 1882\", \"#FFCDD80D\": \"Goldzilla\", \"#FF836E59\": \"Golem\", \"#FF53A391\": \"Golf Blazer\", \"#FF5A9E4B\": \"Golf Course\", \"#FF5A8B3F\": \"Golf Day\", \"#FF009B75\": \"Golf Green\", \"#FF5E6841\": \"Golfer Green\", \"#FFD77E70\": \"Golgfag Brown\", \"#FF8BB9DD\": \"Goluboy Blue\", \"#FFCC9933\": \"Gomashio Yellow\", \"#FF373332\": \"Gondola Variant\", \"#FF5DB1C5\": \"Gondolier\", \"#FF52A8B2\": \"Gone Fishing\", \"#FFD9C737\": \"Gone Giddy\", \"#FF5D06E9\": \"Gonzo Violet\", \"#FFD3BA75\": \"Good as Gold\", \"#FFA09883\": \"Good Earth\", \"#FFF3F0D6\": \"Good Graces\", \"#FF333C76\": \"Good Karma\", \"#FF499674\": \"Good Luck\", \"#FF86C994\": \"Good Luck Charm\", \"#FFFCFCDA\": \"Good Morning\", \"#FFF4EAD5\": \"Good Morning Akihabara\", \"#FF46565F\": \"Good Night!\", \"#FF3F6782\": \"Good Samaritan\", \"#FFC2B99D\": \"Good\", \"#FFEDD2A7\": \"Good-Looking\", \"#FFD9CAC3\": \"Goodbye Kiss\", \"#FFCCD87A\": \"Goody Gumdrop\", \"#FFC2BA8E\": \"Goody Two Shoes\", \"#FF41C379\": \"Googol\", \"#FF93AF3C\": \"Googolplex\", \"#FFFFBA80\": \"Goose Bill\", \"#FFF4E7DF\": \"Goose Down\", \"#FFD2CDC4\": \"Goose Feathers\", \"#FF629B92\": \"Goose Pond Green\", \"#FFA89DAC\": \"Goose Wing Grey\", \"#FFA23F5D\": \"Gooseberry\", \"#FFACB75F\": \"Gooseberry Fool\", \"#FFC7A94A\": \"Gooseberry Yellow\", \"#FFF0F0E0\": \"Gor\\u0101 White\", \"#FFBF852B\": \"Gordal Olive\", \"#FF29332B\": \"Gordons Green Variant\", \"#FF8D9BA9\": \"Gorgeous Graphite\", \"#FF287C37\": \"Gorgeous Green\", \"#FFA495CB\": \"Gorgeous Hydrangea\", \"#FFE7DBD3\": \"Gorgeous White\", \"#FF4455CC\": \"Gorgonzola Blue\", \"#FFFDE336\": \"Gorse Variant\", \"#FFE99A3C\": \"Gorse Yellow Orange\", \"#FF654741\": \"Gorthor Brown\", \"#FFB42435\": \"Gory Movie\", \"#FFA30800\": \"Gory Red\", \"#FF444444\": \"Goshawk Grey\", \"#FF857668\": \"Gosling\", \"#FF399F86\": \"Gossamer Variant\", \"#FFB2CFBE\": \"Gossamer Green\", \"#FFFAC8C3\": \"Gossamer Pink\", \"#FF8AC8E2\": \"Gossamer Threads\", \"#FFD3CEC4\": \"Gossamer Veil\", \"#FFE8EEE9\": \"Gossamer Wings\", \"#FF9FD385\": \"Gossip Variant\", \"#FF807872\": \"Gotham\", \"#FF757C7D\": \"Gotham City\", \"#FF8A9192\": \"Gotham Grey\", \"#FF698890\": \"Gothic Variant\", \"#FFA38B93\": \"Gothic Amethyst\", \"#FFBB852F\": \"Gothic Gold\", \"#FF473951\": \"Gothic Grape\", \"#FF857555\": \"Gothic Olive\", \"#FF92838A\": \"Gothic Purple\", \"#FFA0A160\": \"Gothic Revival Green\", \"#FF7C6B6F\": \"Gothic Spire\", \"#FFD0C2B4\": \"Gotta Have It\", \"#FFEECC11\": \"Gouda Gold\", \"#FF8D6449\": \"Goulash\", \"#FF7D9EA2\": \"Gould Blue\", \"#FFBC9D70\": \"Gould Gold\", \"#FFE3CBA8\": \"Gourmet Honey\", \"#FF968D8C\": \"Gourmet Mushroom\", \"#FF32493E\": \"Government Green\", \"#FF51559B\": \"Governor Bay Variant\", \"#FFA8C0CE\": \"Graceful\", \"#FFDD897C\": \"Graceful Ballerina\", \"#FFBDDFB2\": \"Graceful Flower\", \"#FFCBA9D0\": \"Graceful Garden\", \"#FFA78A50\": \"Graceful Gazelle\", \"#FFACB7A8\": \"Graceful Green\", \"#FFBEB6AC\": \"Graceful Grey\", \"#FFDAEED5\": \"Graceful Mint\", \"#FF546C46\": \"Graceland Grass\", \"#FFC4D5CB\": \"Gracilis\", \"#FFF8EDD7\": \"Gracious\", \"#FFBAB078\": \"Gracious Glow\", \"#FFA5ABA1\": \"Gracious Grey\", \"#FFE3B7B1\": \"Gracious Rose\", \"#FFC0A480\": \"Graham Cracker\", \"#FF806240\": \"Graham Crust\", \"#FFCAB8A2\": \"Grain Brown Variant\", \"#FFD8C095\": \"Grain Mill\", \"#FFDFD2C0\": \"Grain of Rice\", \"#FFD8DBE1\": \"Grain of Salt\", \"#FFEFE3D8\": \"Grain White\", \"#FFB79E66\": \"Grainfield\", \"#FFF5F6F7\": \"Gram\\u2019s Hair\", \"#FFE9DEC8\": \"Gramp\\u2019s Tea Cup\", \"#FFA3896C\": \"Gramps Shoehorn\", \"#FFEE3300\": \"Gran Torino Red\", \"#FF5D81BB\": \"Granada Sky\", \"#FFE99F4C\": \"Granary Gold\", \"#FF665A48\": \"Grand Avenue\", \"#FF015482\": \"Grand Bleu\", \"#FF7E9CA0\": \"Grand Boulevard\", \"#FF3C797D\": \"Grand Canal\", \"#FFA05D4D\": \"Grand Canyon\", \"#FFEDCD62\": \"Grand Casino Gold\", \"#FFCB5C45\": \"Grand Duke\", \"#FFA8CCD5\": \"Grand Entrance\", \"#FF645764\": \"Grand Grape\", \"#FF86BB9D\": \"Grand Gusto\", \"#FFECECE1\": \"Grand Heron\", \"#FFD8D0BD\": \"Grand Piano\", \"#FF6C5657\": \"Grand Plum\", \"#FF864764\": \"Grand Poobah\", \"#FF496763\": \"Grand Prix\", \"#FF534778\": \"Grand Purple\", \"#FF38707E\": \"Grand Rapids\", \"#FFD9C2A8\": \"Grand Soiree\", \"#FFC38D87\": \"Grand Sunset\", \"#FF8DC07C\": \"Grand Valley\", \"#FF92576F\": \"Grandeur Plum\", \"#FFE0EBAF\": \"Grandiflora Rose\", \"#FFCAA84C\": \"Grandiose\", \"#FFFFCD73\": \"Grandis Variant\", \"#FFF7E7DD\": \"Grandma\\u2019s Cameo\", \"#FFE0B8C0\": \"Grandma\\u2019s Pink Tiles\", \"#FF6B927F\": \"Grandview\", \"#FF857767\": \"Grange Hall\", \"#FFB62758\": \"Granita\", \"#FF746A5E\": \"Granite\", \"#FF313238\": \"Granite Black\", \"#FF816F6B\": \"Granite Boulder\", \"#FF3D2D24\": \"Granite Brown\", \"#FF6C6F78\": \"Granite Canyon\", \"#FFD7CEC4\": \"Granite Dust\", \"#FF638496\": \"Granite Falls\", \"#FFB1BAC2\": \"Granite Fog\", \"#FF6B6869\": \"Granite Grey\", \"#FF606B75\": \"Granite Peak\", \"#FFC5C4C1\": \"Granitine\", \"#FFD0B690\": \"Granivorous\", \"#FFF6EEED\": \"Grannie\\u2019s Pearls\", \"#FFC5E7CD\": \"Granny Apple Variant\", \"#FF7B948C\": \"Granny Smith Variant\", \"#FFF5CE9F\": \"Granola\", \"#FF9E6858\": \"Granrojo Jellyfish\", \"#FF8F8461\": \"Grant Drab\", \"#FF918F8A\": \"Grant Grey\", \"#FF6C90B2\": \"Grant Village\", \"#FFA8B989\": \"Grant Wood Ivy\", \"#FFE3E0DA\": \"Granular Limestone\", \"#FFFFFDF2\": \"Granulated Sugar\", \"#FF6C3461\": \"Grape Variant\", \"#FFA598C7\": \"Grape Arbour\", \"#FF24486C\": \"Grape Blue\", \"#FF905284\": \"Grape Candy\", \"#FFDFE384\": \"Grape Cassata\", \"#FF725F7F\": \"Grape Compote\", \"#FFBEBBBB\": \"Grape Creme\", \"#FF6A587E\": \"Grape Expectations\", \"#FF64435F\": \"Grape Fizz\", \"#FFA19ABD\": \"Grape Gatsby\", \"#FFDCCAE0\": \"Grape Glimmer\", \"#FF6D6166\": \"Grape Grey\", \"#FF807697\": \"Grape Harvest\", \"#FF606A88\": \"Grape Haze\", \"#FF5533CC\": \"Grape Hyacinth\", \"#FFB4A6D5\": \"Grape Illusion\", \"#FF979AC4\": \"Grape Ivy\", \"#FF7F779A\": \"Grape Jam\", \"#FF7E667F\": \"Grape Jelly\", \"#FF772F6C\": \"Grape Juice\", \"#FF82476F\": \"Grape Kiss\", \"#FFC2C4D4\": \"Grape Lavender\", \"#FF5A5749\": \"Grape Leaf\", \"#FF576049\": \"Grape Leaves\", \"#FFC5C0C9\": \"Grape Mist\", \"#FF8D5C75\": \"Grape Nectar\", \"#FFD3D9CE\": \"Grape Oil Green\", \"#FF8677A9\": \"Grape Parfait\", \"#FF60406D\": \"Grape Popsicle\", \"#FF5D1451\": \"Grape Purple\", \"#FF9B4682\": \"Grape Riot\", \"#FF522F57\": \"Grape Royale\", \"#FF886971\": \"Grape Shake\", \"#FFB69ABC\": \"Grape Smoke\", \"#FFAE94A6\": \"Grape Soda\", \"#FFF4DAF1\": \"Grape Taffy\", \"#FF797F5A\": \"Grape Vine\", \"#FF64344B\": \"Grape Wine\", \"#FFBEAECF\": \"Grape\\u2019s Treasure\", \"#FFAA9FB2\": \"Grapeade\", \"#FFFD5956\": \"Grapefruit\", \"#FFEE6D8A\": \"Grapefruit Juice\", \"#FFDFA01A\": \"Grapefruit Yellow\", \"#FF714A8B\": \"Grapes of Italy\", \"#FF58424C\": \"Grapes of Wrath\", \"#FF71384B\": \"Grapeshot\", \"#FF880066\": \"Grapest\", \"#FF4C475E\": \"Grapewood\", \"#FF5C5E5F\": \"Graphic Charcoal\", \"#FF824E78\": \"Graphic Grape\", \"#FF0000FC\": \"Graphical 80\\u2019s Sky\", \"#FF383428\": \"Graphite Variant\", \"#FF262A2B\": \"Graphite Black\", \"#FF32494B\": \"Graphite Black Green\", \"#FF7C7666\": \"Graphite Grey Green\", \"#FFF5D9B1\": \"Grappa\", \"#FF92786A\": \"Grapple\", \"#FF786E70\": \"Grapy\", \"#FF92B300\": \"Grasping Grass\", \"#FF5CAC2D\": \"Grass\", \"#FF636F46\": \"Grass Blade\", \"#FFB8B97E\": \"Grass Cloth\", \"#FF088D46\": \"Grass Court\", \"#FFCEB02A\": \"Grass Daisy\", \"#FF3F9B0B\": \"Grass Is Greener\", \"#FFCA84FC\": \"Grass Pink Orchid\", \"#FFA1AFA0\": \"Grass Sands\", \"#FFE2DAC2\": \"Grass Skirt\", \"#FFC0FB2D\": \"Grass Stain Green\", \"#FFF4F7EE\": \"Grass Valley\", \"#FF77824A\": \"Grasshopper\", \"#FFBCDABB\": \"Grasshopper Pie\", \"#FF87866F\": \"Grasshopper Wing\", \"#FF407548\": \"Grasslands\", \"#FFD8C475\": \"Grassroots\", \"#FF968154\": \"Grassy Cliff\", \"#FF5C7D47\": \"Grassy Field\", \"#FFD8DDCA\": \"Grassy Glade\", \"#FF419C03\": \"Grassy Green\", \"#FF76A55B\": \"Grassy Meadow\", \"#FFB8A336\": \"Grassy Ochre\", \"#FF9B9279\": \"Grassy Savannah\", \"#FFA60E46\": \"Grated Beet\", \"#FF71714E\": \"Gratefully Grass\", \"#FFDAE2CD\": \"Gratifying Green\", \"#FFE0D2A9\": \"Gratin Dauphinois\", \"#FFE0EAD7\": \"Gratitude\", \"#FF85A3B2\": \"Grauzone\", \"#FF4A4B46\": \"Gravel Variant\", \"#FFCECBC5\": \"Gravel Drive\", \"#FFBAB9A9\": \"Gravel Dust\", \"#FF637A82\": \"Gravel Grey Blue\", \"#FF938576\": \"Gravelle\", \"#FFD3C7B8\": \"Gravelstone\", \"#FF68553A\": \"Graveyard Earth\", \"#FFB8BCBD\": \"Gravity\", \"#FFEC834F\": \"Gravlax\", \"#FFA1A19F\": \"Grayve-Yard\", \"#FFA2B35A\": \"Greasy Green Beans\", \"#FF117755\": \"Greasy Greens\", \"#FF838583\": \"Greasy Grey\", \"#FF576E8B\": \"Great Basin\", \"#FFD5E0EE\": \"Great Blue Heron\", \"#FF7F8488\": \"Great Coat Grey\", \"#FFD1A369\": \"Great Dane\", \"#FF9FA6B3\": \"Great Falls\", \"#FF719BA2\": \"Great Fennel Flower\", \"#FF908675\": \"Great Frontier\", \"#FF5CA16D\": \"Great Gazoo\", \"#FF6B6D85\": \"Great Grape\", \"#FFA5A6A1\": \"Great Graphite\", \"#FFABB486\": \"Great Green\", \"#FFD8E6CB\": \"Great Joy\", \"#FF4A72A3\": \"Great Serpent\", \"#FFE9E2DB\": \"Great Tit Eggs\", \"#FF3B5760\": \"Great Void\", \"#FF9E7E54\": \"Grecian Gold\", \"#FF8C6D46\": \"Grecian Helmet\", \"#FF00A49B\": \"Grecian Isle\", \"#FFD6CFBE\": \"Grecian Ivory\", \"#FF00AA66\": \"Greedo Green\", \"#FFAA9922\": \"Greedy Gecko\", \"#FFC4CE3B\": \"Greedy Gold\", \"#FFD1FFBD\": \"Greedy Green\", \"#FF3D0734\": \"Greek Aubergine\", \"#FF009FBD\": \"Greek Blue\", \"#FF0D5EAF\": \"Greek Flag Blue\", \"#FF8CCE86\": \"Greek Garden\", \"#FFEDE9EF\": \"Greek Goddess\", \"#FFBBDCF0\": \"Greek Isles\", \"#FF9B8FB0\": \"Greek Lavender\", \"#FFA08650\": \"Greek Olive\", \"#FF7C754C\": \"Greek Oregano\", \"#FF72A7E1\": \"Greek Sea\", \"#FFF0ECE2\": \"Greek Villa\", \"#FF3E3D29\": \"Green 383\", \"#FF53A144\": \"Green Acres\", \"#FF688878\": \"Green Adirondack\", \"#FF52928D\": \"Green Agate\", \"#FFC8CCBA\": \"Green Alabaster\", \"#FF98A893\": \"Green Amazons\", \"#FFAFC1A3\": \"Green Andara\", \"#FF5EDC1F\": \"Green Apple\", \"#FFD2C785\": \"Green Apple Martini\", \"#FF95D6A1\": \"Green Ash\", \"#FF80C4A9\": \"Green Balloon\", \"#FFA0AC9E\": \"Green Balsam\", \"#FFA8B453\": \"Green Banana\", \"#FF79B088\": \"Green Bank\", \"#FFA9C4A6\": \"Green Bark\", \"#FF7E9285\": \"Green Bay\", \"#FF566E57\": \"Green Bayou\", \"#FFB0A36E\": \"Green Bean Casserole\", \"#FF228800\": \"Green Bell Pepper\", \"#FF2D7F6C\": \"Green Belt\", \"#FF516A62\": \"Green Beret\", \"#FF373A3A\": \"Green Black\", \"#FF22DD00\": \"Green Blob\", \"#FF42B395\": \"Green Blue\", \"#FF358082\": \"Green Blue Slate\", \"#FF8BB490\": \"Green Bonnet\", \"#FFDAF1E0\": \"Green Brocade\", \"#FF696006\": \"Green Brown\", \"#FF32A7B5\": \"Green Buoy\", \"#FF7F8866\": \"Green Bush\", \"#FFBBEE11\": \"Green Cacophony\", \"#FF89CE01\": \"Green Cape\", \"#FF919365\": \"Green Cast\", \"#FF146B47\": \"Green Caterpillar\", \"#FFBCDF8A\": \"Green Chalk\", \"#FFE7DDA7\": \"Green Charm\", \"#FFCFBB75\": \"Green Citrine\", \"#FF889988\": \"Green Clay\", \"#FF868E65\": \"Green Coconut\", \"#FF465149\": \"Green Column\", \"#FF828039\": \"Green Commando\", \"#FFBEEF69\": \"Green Cow\", \"#FF62AE9E\": \"Green Crush\", \"#FFACB977\": \"Green Curry\", \"#FF009966\": \"Green Cyan\", \"#FF75BBFD\": \"Green Darner Tail\", \"#FFBBEE88\": \"Green Day\", \"#FF8BD3C6\": \"Green Daze\", \"#FF006C67\": \"Green Dragon\", \"#FFC1CAB0\": \"Green Dragon Spring\", \"#FF6E7A77\": \"Green Dusk\", \"#FF00988E\": \"Green Dynasty\", \"#FFE3ECC5\": \"Green Eggs\", \"#FFB3C39C\": \"Green Eggs & Cam\", \"#FF7CB68E\": \"Green Eggs and Ham\", \"#FFBBCC11\": \"Green Elisabeth \\u2161\", \"#FF00BB66\": \"Green Elliott\", \"#FFDAEAE2\": \"Green Emulsion\", \"#FF80905F\": \"Green Energy\", \"#FF77AA00\": \"Green Envy\", \"#FF7EFBB3\": \"Green Epiphany\", \"#FFE9EAC8\": \"Green Essence\", \"#FF7D956D\": \"Green Eyes\", \"#FF605E4F\": \"Green Fatigue\", \"#FFAAEE00\": \"Green Fiasco\", \"#FFB3A476\": \"Green Fig\", \"#FF297E6B\": \"Green Fingers\", \"#FF79C753\": \"Green Flash\", \"#FFBBAA22\": \"Green Flavour\", \"#FF55BBAA\": \"Green Fluorite\", \"#FF989A87\": \"Green Fog\", \"#FF319B64\": \"Green Fondant\", \"#FFD0D6BF\": \"Green Frost\", \"#FFD8F1EB\": \"Green Frosting\", \"#FF364847\": \"Green Gables\", \"#FF72C895\": \"Green Gala\", \"#FF72B874\": \"Green Galore\", \"#FF11BB00\": \"Green Gamora\", \"#FF009911\": \"Green Gardens\", \"#FF008176\": \"Green Garlands\", \"#FF61BA85\": \"Green Garter\", \"#FF676957\": \"Green Gate\", \"#FFC7C3A8\": \"Green Gaze\", \"#FFCDD47F\": \"Green Gecko\", \"#FFE7F0C2\": \"Green Glacier\", \"#FFEAF1E4\": \"Green Glaze\", \"#FF00BB00\": \"Green Glimmer\", \"#FFE7EAE3\": \"Green Glimpse\", \"#FFDCF1C7\": \"Green Glint\", \"#FFDDE26A\": \"Green Glitter\", \"#FF79AA87\": \"Green Globe\", \"#FF00955E\": \"Green Gloss\", \"#FFACC65D\": \"Green Glow\", \"#FF007722\": \"Green Glutton\", \"#FF505A39\": \"Green Goanna\", \"#FF11BB33\": \"Green Goblin\", \"#FF76AD83\": \"Green Goddess\", \"#FFC5B088\": \"Green Gold\", \"#FF73A236\": \"Green Gone Wild\", \"#FFB0DFA4\": \"Green Gooseberry\", \"#FF588266\": \"Green Goth Eyeshadow\", \"#FF7C9793\": \"Green Granite\", \"#FFC0DBC6\": \"Green Grapes\", \"#FF3DB9B2\": \"Green Grapple\", \"#FF39854A\": \"Green Grass\", \"#FF7EA07A\": \"Green Grey\", \"#FFAFA984\": \"Green Grey Mist\", \"#FF95E3C0\": \"Green Gum\", \"#FFA4C08A\": \"Green Herb\", \"#FF66CC22\": \"Green High\", \"#FF007800\": \"Green Hills\", \"#FF6A9D5D\": \"Green Hornet\", \"#FF587D79\": \"Green Hour\", \"#FFE8E8D4\": \"Green Iced Tea\", \"#FF6E6F56\": \"Green Illude\", \"#FFC4FE82\": \"Green Incandescence\", \"#FF11887B\": \"Green Ink\", \"#FF8C8E51\": \"Green Jalape\\u00f1o\", \"#FF7A796E\": \"Green Jeans\", \"#FF349B82\": \"Green Jelly\", \"#FF95DABD\": \"Green Jewel\", \"#FF3BDE39\": \"Green Juice\", \"#FF53FE5C\": \"Green Katamari\", \"#FF393D2A\": \"Green Kelp Variant\", \"#FF647F4A\": \"Green Knoll\", \"#FF8AD370\": \"Green Lacewing\", \"#FFCAD6C4\": \"Green Lane\", \"#FF9CD03B\": \"Green Lantern\", \"#FF008684\": \"Green Lapis\", \"#FF526B2D\": \"Green Leaf Variant\", \"#FF9C9463\": \"Green Lentils\", \"#FFC1CEC1\": \"Green Lily\", \"#FF26B467\": \"Green Mana\", \"#FF5B7C5B\": \"Green Mantle\", \"#FF8DBC8A\": \"Green Masquerade\", \"#FFB2B55F\": \"Green Me\", \"#FF8EA8A0\": \"Green Meets Blue\", \"#FFD7D7AD\": \"Green Mesh\", \"#FF4D5947\": \"Green Mile\", \"#FF8A9992\": \"Green Milieu\", \"#FF99DD00\": \"Green Minions\", \"#FFD7E2D5\": \"Green Mirror\", \"#FFBFC298\": \"Green Mist Variant\", \"#FF008888\": \"Green Moblin\", \"#FF33565E\": \"Green Moonstone\", \"#FF3A7968\": \"Green Moray\", \"#FF887E48\": \"Green Moss\", \"#FFBDBFAF\": \"Green Motif\", \"#FFC5E1C3\": \"Green Myth\", \"#FF404404\": \"Green Not Found\", \"#FFB0B454\": \"Green Oasis\", \"#FF005249\": \"Green Oblivion\", \"#FF9F8F55\": \"Green Ochre\", \"#FFCDFA56\": \"Green of Bhabua\", \"#FF8D8B55\": \"Green Olive\", \"#FFBDAA89\": \"Green Olive Pit\", \"#FFC1E089\": \"Green Onion\", \"#FF989A82\": \"Green Onyx\", \"#FFE1FE52\": \"Green Ooze\", \"#FFE5CE77\": \"Green Papaya\", \"#FF7BD5BF\": \"Green Parakeet\", \"#FFCFDDB9\": \"Green Parlour\", \"#FF0D6349\": \"Green Paw Paw\", \"#FF266242\": \"Green Pea Variant\", \"#FF79BE58\": \"Green Pear\", \"#FF388004\": \"Green People\", \"#FF97BC62\": \"Green Pepper\", \"#FF47694F\": \"Green Perennial\", \"#FFA7C668\": \"Green Peridot\", \"#FF98A76E\": \"Green Plaza\", \"#FFE2E1C6\": \"Green Power\", \"#FF11DD55\": \"Green Priestess\", \"#FFD1E5B5\": \"Green Reflection\", \"#FF7B8762\": \"Green Relict\", \"#FF009944\": \"Green Revolution\", \"#FF288F3D\": \"Green Ribbon\", \"#FF80AEA4\": \"Green Room\", \"#FF888866\": \"Green Savage\", \"#FF858365\": \"Green Scene\", \"#FF22FF00\": \"Green Screen\", \"#FF44AA33\": \"Green Seduction\", \"#FF77BB00\": \"Green Serpent\", \"#FF99DD22\": \"Green Serum\", \"#FF45523A\": \"Green Shade Wash\", \"#FFD7C94A\": \"Green Sheen Variant\", \"#FFCCFD7F\": \"Green Shimmer\", \"#FFA2C2B0\": \"Green Silk\", \"#FF859D66\": \"Green Sky\", \"#FF39766C\": \"Green Sleeves\", \"#FF9CA664\": \"Green Smoke Variant\", \"#FF9EB788\": \"Green Snow\", \"#FFD1E9C4\": \"Green Song\", \"#FF006474\": \"Green Spool\", \"#FF589F7E\": \"Green Spruce\", \"#FF2B553E\": \"Green Stain\", \"#FF73884D\": \"Green Suede\", \"#FF9E8528\": \"Green Sulphur\", \"#FF66AA22\": \"Green Symphony\", \"#FFB5B68F\": \"Green Tea\", \"#FF65AB7C\": \"Green Tea Candy\", \"#FF93B13D\": \"Green Tea Ice Cream\", \"#FF939A89\": \"Green Tea Leaf\", \"#FF90A96E\": \"Green Tea Mochi\", \"#FF0CB577\": \"Green Teal\", \"#FFE3EDE0\": \"Green Tease\", \"#FF779900\": \"Green Thumb\", \"#FFD5E0D0\": \"Green Tilberi\", \"#FF47553C\": \"Green Tone Ink\", \"#FF5EAB81\": \"Green Tourmaline\", \"#FFA0D9A3\": \"Green Trance\", \"#FF99A798\": \"Green Trellis\", \"#FF679591\": \"Green Turquoise\", \"#FF51755B\": \"Green Valley\", \"#FFE0F1C4\": \"Green Veil\", \"#FF25B68B\": \"Green Velour\", \"#FF127453\": \"Green Velvet\", \"#FFB8F818\": \"Green Venom\", \"#FFD4E7C3\": \"Green Vibes\", \"#FF23414E\": \"Green Vogue Variant\", \"#FFC6DDCD\": \"Green Wash\", \"#FF2C2D24\": \"Green Waterloo Variant\", \"#FFC3DCD5\": \"Green Wave\", \"#FF548F6F\": \"Green Weed\", \"#FFE3EEE3\": \"Green Whisper\", \"#FFDEDDCB\": \"Green White Variant\", \"#FF22BB33\": \"Green With Envy\", \"#FF7D7853\": \"Green Woodpecker Olive\", \"#FF13DA25\": \"Green Wrasse\", \"#FFC6F808\": \"Green Yellow Variant\", \"#FF90BE9D\": \"Green-Eyed Lady\", \"#FF346E23\": \"Green-Eyed Monster\", \"#FF00DD00\": \"Greenalicious\", \"#FF245D3F\": \"Greenbriar\", \"#FF60857A\": \"Greenella\", \"#FF495A4C\": \"Greener Pastures\", \"#FF80A546\": \"Greenery\", \"#FFDAECC5\": \"Greenette\", \"#FF60724F\": \"Greenfield\", \"#FFBDA928\": \"Greenfinch\", \"#FF84BE84\": \"Greengage\", \"#FFB2CC9A\": \"Greenhorn\", \"#FF3E6334\": \"Greenhouse\", \"#FFDFE4D5\": \"Greening\", \"#FF40A368\": \"Greenish\", \"#FFC9D179\": \"Greenish Beige\", \"#FF454445\": \"Greenish Black\", \"#FF0B8B87\": \"Greenish Blue\", \"#FF696112\": \"Greenish Brown\", \"#FF2AFEB7\": \"Greenish Cyan\", \"#FF96AE8D\": \"Greenish Grey\", \"#FF66675A\": \"Greenish Grey Bark\", \"#FFBCCB7A\": \"Greenish Tan\", \"#FF32BF84\": \"Greenish Teal\", \"#FF00FBB0\": \"Greenish Turquoise\", \"#FFD1F1DE\": \"Greenish White\", \"#FFCDFD02\": \"Greenish Yellow\", \"#FFCAE03B\": \"Greenivorous\", \"#FF008C7D\": \"Greenlake\", \"#FF737D6A\": \"Greenland\", \"#FF367F9A\": \"Greenland Blue\", \"#FF22ACAE\": \"Greenland Green\", \"#FFB9D7D6\": \"Greenland Ice\", \"#FF016844\": \"Greens\", \"#FF565C00\": \"Greensboro\", \"#FFA5CF7E\": \"Greenscape\", \"#FF419A7D\": \"Greenway\", \"#FF475B49\": \"Greenwich\", \"#FF82826A\": \"Greenwich Green\", \"#FFAFBFBE\": \"Greenwich Village\", \"#FFBCBAAB\": \"Greenwood\", \"#FF067376\": \"Greeny Glaze\", \"#FFCBC8DD\": \"Gregorio Garden\", \"#FFB0A999\": \"Greige\", \"#FF9C8C9A\": \"Greige Violet\", \"#FFA79954\": \"Gremlin\", \"#FF527E6D\": \"Gremolata\", \"#FF8E6268\": \"Grenache\", \"#FFC32149\": \"Grenade\", \"#FFC14D36\": \"Grenadier Variant\", \"#FFAC545E\": \"Grenadine\", \"#FFFF616B\": \"Grenadine Pink\", \"#FF5D6732\": \"Gretchin Green\", \"#FF596442\": \"Gretna Green\", \"#FFA8B1C0\": \"Grey Agate\", \"#FF8F9394\": \"Grey Area\", \"#FFC4C5BA\": \"Grey Ashlar\", \"#FF77A1B5\": \"Grey Blue\", \"#FF6C8096\": \"Grey Blueberry\", \"#FFB4BFC2\": \"Grey Brook\", \"#FF7F7053\": \"Grey Brown\", \"#FFA1988B\": \"Grey by Me\", \"#FF7A5063\": \"Grey Carmine\", \"#FF6E6969\": \"Grey Charcoal\", \"#FF9FA3A7\": \"Grey Chateau\", \"#FFCCC9C5\": \"Grey Cloth\", \"#FFB7B7B2\": \"Grey Clouds\", \"#FFBBC1CC\": \"Grey Dawn\", \"#FFC8C7C5\": \"Grey Dolphin\", \"#FF897F98\": \"Grey Dusk\", \"#FFB0BFB6\": \"Grey Embrace\", \"#FFA1A196\": \"Grey Expose\", \"#FFA2998F\": \"Grey Flanks\", \"#FF8D9A9E\": \"Grey Flannel\", \"#FF788480\": \"Grey Flannel Suit\", \"#FFB8BFC2\": \"Grey Frost\", \"#FFDDDCDA\": \"Grey Ghost\", \"#FFE0E4E2\": \"Grey Glimpse\", \"#FFA3A29B\": \"Grey Gloss\", \"#FF86A17D\": \"Grey Green\", \"#FF868790\": \"Grey Heather\", \"#FF89928A\": \"Grey Heron\", \"#FFB9BBAD\": \"Grey Jade\", \"#FFD4CACD\": \"Grey Lilac\", \"#FF72695E\": \"Grey Locks\", \"#FFB9B4B1\": \"Grey Marble\", \"#FFC87F89\": \"Grey Matter\", \"#FFCAB8AB\": \"Grey Mauve\", \"#FFABAFAE\": \"Grey Mirage\", \"#FF96ACAB\": \"Grey Mist\", \"#FF707C78\": \"Grey Monument\", \"#FFCABEB5\": \"Grey Morn\", \"#FF9EB0AA\": \"Grey Morning\", \"#FFD1D3CC\": \"Grey Nurse\", \"#FFA2A2A2\": \"Grey of Darkness\", \"#FFA19A7F\": \"Grey Olive\", \"#FF776F67\": \"Grey Owl\", \"#FFCED0CF\": \"Grey Pearl\", \"#FFB0B7BE\": \"Grey Pearl Sand\", \"#FFCFCAC1\": \"Grey Pebble\", \"#FF84827D\": \"Grey Pepper\", \"#FFC3909B\": \"Grey Pink\", \"#FF4E4E52\": \"Grey Pinstripe\", \"#FFDDDDE2\": \"Grey Placidity\", \"#FF86837A\": \"Grey Porcelain\", \"#FF826D8C\": \"Grey Purple\", \"#FF847986\": \"Grey Ridge\", \"#FF99A1A1\": \"Grey River Rock\", \"#FFC3C0BB\": \"Grey Roads\", \"#FFC6B6B2\": \"Grey Rose\", \"#FF8E9598\": \"Grey Russian\", \"#FFE5CAAF\": \"Grey Sand\", \"#FFB8B0AF\": \"Grey Scape\", \"#FFC6CACA\": \"Grey Screen\", \"#FFC2BDBA\": \"Grey Shadows\", \"#FFBAAAAA\": \"Grey Sheep\", \"#FFD6D9D8\": \"Grey Shimmer\", \"#FF949392\": \"Grey Shingle\", \"#FFB0A99A\": \"Grey Silt\", \"#FFC8C7C2\": \"Grey Spell\", \"#FF989081\": \"Grey Squirrel\", \"#FF807A77\": \"Grey Suit\", \"#FF959491\": \"Grey Summit\", \"#FF5E9B8A\": \"Grey Teal\", \"#FFACAEB1\": \"Grey Timberwolf\", \"#FF81807D\": \"Grey Tote\", \"#FFB0BAB5\": \"Grey Tweed\", \"#FF9B8E8E\": \"Grey Violet\", \"#FF616669\": \"Grey Web\", \"#FF625F5C\": \"Grey Werewolf\", \"#FFE6E4E4\": \"Grey Whisper\", \"#FFD7D5CB\": \"Grey White\", \"#FF9CA0A6\": \"Grey Wolf\", \"#FFE5E8E6\": \"Grey Wonder\", \"#FFA9BBBC\": \"Grey Wool\", \"#FF98916C\": \"Grey-Headed Woodpecker Green\", \"#FFD4D0C5\": \"Greybeard\", \"#FF92B8A0\": \"Greyed Jade\", \"#FFB2ACA2\": \"Greyhound\", \"#FFCFCAC7\": \"Greyish\", \"#FFA8A495\": \"Greyish Beige\", \"#FF555152\": \"Greyish Black\", \"#FF5E819D\": \"Greyish Blue\", \"#FF7A6A4F\": \"Greyish Brown\", \"#FF82A67D\": \"Greyish Green\", \"#FFB8B8FF\": \"Greyish Lavender\", \"#FFC88D94\": \"Greyish Pink\", \"#FF887191\": \"Greyish Purple\", \"#FF719F91\": \"Greyish Teal\", \"#FFD6DEE9\": \"Greyish White\", \"#FF877254\": \"Greyish Yellow\", \"#FF948C8D\": \"Greylac\", \"#FF596368\": \"Greys Harbor\", \"#FF85837E\": \"Greystoke\", \"#FFB7B9B5\": \"Greystone\", \"#FFAACCBB\": \"Greywacke\", \"#FF9D9586\": \"Greywood\", \"#FFC3571D\": \"Grieving Daylily\", \"#FF70393F\": \"Griffon Brown\", \"#FF863B2C\": \"Grill Master\", \"#FF633F2E\": \"Grilled\", \"#FFFFC85F\": \"Grilled Cheese\", \"#FFAF3519\": \"Grilled Tomato\", \"#FFE3DCD6\": \"Grim Grey\", \"#FFDEADAF\": \"Grim Pink\", \"#FF441188\": \"Grim Purple\", \"#FF0F1039\": \"Grim Reaper\", \"#FFF6F1F4\": \"Grim White\", \"#FF50314C\": \"Grimace\", \"#FF565143\": \"Grime\", \"#FF93B83D\": \"Grinch Green\", \"#FFA5A9A8\": \"Gris\", \"#FF8F8A91\": \"Gris Morado\", \"#FFBCC7CB\": \"Gris N\\u00e1utico\", \"#FF797371\": \"Gris Volcanico\", \"#FF91979F\": \"Grisaille\", \"#FFA29371\": \"Gristmill\", \"#FF636562\": \"Grizzle Grey\", \"#FF885818\": \"Grizzly\", \"#FF937043\": \"Grog Yellow\", \"#FFDE6491\": \"Groovy\", \"#FFEEAA11\": \"Groovy Giraffe\", \"#FFD6BE01\": \"Groovy Lemon Pie\", \"#FF63615D\": \"Gropius Grey\", \"#FFA0BF16\": \"Gross Green\", \"#FF64E986\": \"Grotesque Green\", \"#FF6F675C\": \"Grouchy Badger\", \"#FF604E42\": \"Ground Bean\", \"#FF63554B\": \"Ground Coffee\", \"#FF8A6C42\": \"Ground Cumin\", \"#FF7F5F00\": \"Ground Earth\", \"#FFCFCBC4\": \"Ground Fog\", \"#FFD9CA9F\": \"Ground Ginger\", \"#FFA05A3B\": \"Ground Nutmeg\", \"#FF766551\": \"Ground Pepper\", \"#FF757577\": \"Ground Truth\", \"#FF7B6F60\": \"Groundbreaking\", \"#FF64634D\": \"Groundcover\", \"#FFD18C62\": \"Grounded\", \"#FF1100AA\": \"Groundwater\", \"#FFE2C0A8\": \"Group Hug\", \"#FFF0E6D3\": \"Grow\", \"#FF88CC11\": \"Growing Nature\", \"#FFC3CDB0\": \"Growing Season\", \"#FF6CA178\": \"Growth\", \"#FF811412\": \"Grubby Red\", \"#FF4A5B51\": \"Grubenwald\", \"#FFC0CF3F\": \"Grunervetliner\", \"#FF838585\": \"Gryphon\", \"#FF883F11\": \"Gryphonne Sepia Wash\", \"#FF634950\": \"G\\u01d4 T\\u00f3ng H\\u0113i Copper\", \"#FF95986B\": \"Guacamole\", \"#FFD2D392\": \"Guacamole Ambrosia\", \"#FFE4E1EA\": \"Guardian Angel\", \"#FF88AA22\": \"Guardian of Gardens\", \"#FF952E31\": \"Guardsman Red Variant\", \"#FFFF982E\": \"Guava\", \"#FFEEC0D2\": \"Guava Glow\", \"#FFA18D0D\": \"Guava Green\", \"#FFE08771\": \"Guava Jam\", \"#FFEE9685\": \"Guava Jelly\", \"#FFF4B694\": \"Guava Juice\", \"#FF142D25\": \"Guerrilla Forest\", \"#FFE3E0D2\": \"Guesthouse\", \"#FFEB4962\": \"Guide Pink\", \"#FFFEE9DA\": \"Guiding Star\", \"#FFD2D1CB\": \"Guild Grey\", \"#FF987652\": \"Guinea Pig\", \"#FFE8E4D6\": \"Guinea Pig White\", \"#FF4A8140\": \"Guinean Green\", \"#FF6B4C37\": \"Guitar\", \"#FF8B2E19\": \"Gulab Brown\", \"#FFC772C0\": \"Gul\\u0101b\\u012b Pink\", \"#FF343F5C\": \"Gulf Blue Variant\", \"#FFDDDED3\": \"Gulf Breeze\", \"#FF015C77\": \"Gulf Coast\", \"#FF225E64\": \"Gulf Harbour\", \"#FF01858B\": \"Gulf Stream Variant\", \"#FF689FC1\": \"Gulf Stream Blue\", \"#FF2DA6BF\": \"Gulf Waters\", \"#FF686E43\": \"Gulf Weed\", \"#FF93B2B2\": \"Gulf Winds\", \"#FF918C8F\": \"Gull\", \"#FFC2C2BC\": \"Gull Feather\", \"#FFA4ADB0\": \"Gull Grey\", \"#FFABAEA9\": \"Gull Wing\", \"#FF777661\": \"Gully\", \"#FF4B6E3B\": \"Gully Green\", \"#FFACC9B2\": \"Gum Leaf Variant\", \"#FFE7B2D0\": \"Gumball\", \"#FF718F8A\": \"Gumbo Variant\", \"#FF2EA785\": \"Gumdrop Green\", \"#FFFFC69D\": \"Gumdrops\", \"#FF06A9CA\": \"Gummy Dolphins\", \"#FF979D9A\": \"Gun Barrel\", \"#FF6B593C\": \"Gun Corps Brown\", \"#FF484753\": \"Gun Powder Variant\", \"#FF959984\": \"Gundaroo Green\", \"#FF5D8CAE\": \"Gunj\\u014d Blue\", \"#FF536267\": \"Gunmetal Variant\", \"#FF908982\": \"Gunmetal Beige\", \"#FF777648\": \"Gunmetal Green\", \"#FF808C8C\": \"Gunmetal Grey\", \"#FFDCD3BC\": \"Gunny Sack\", \"#FFFF0077\": \"Guns N\\u2019 Roses\", \"#FF818070\": \"Gunsmith\", \"#FF7A7C76\": \"Gunsmoke Variant\", \"#FFBD7E08\": \"Guo Tie Dumpling\", \"#FFAE5883\": \"Guppy Violet\", \"#FF989171\": \"Gurkha Variant\", \"#FFA49691\": \"Gustav\", \"#FFF8AC1D\": \"Gusto Gold\", \"#FF705284\": \"Gutsy Grape\", \"#FF897A68\": \"Guy\", \"#FFDFB46F\": \"Gyoza Dumpling\", \"#FFEEEDE4\": \"Gypsum\", \"#FFE2C4AF\": \"Gypsum Rose\", \"#FFD6CFBF\": \"Gypsum Sand\", \"#FFBFE1E6\": \"H\\u2082O\", \"#FFF98513\": \"Haba\\u00f1ero\", \"#FFB8473D\": \"Haba\\u00f1ero Chile\", \"#FFFECF3C\": \"Haba\\u00f1ero Gold\", \"#FF9E8022\": \"Hacienda Variant\", \"#FF0087A8\": \"Hacienda Blue\", \"#FFBB7731\": \"Hacienda Del Sol\", \"#FFB86D64\": \"Hacienda Tile\", \"#FFF0EDE7\": \"Hacienda White\", \"#FF277ABA\": \"Haddock\\u2019s Sweater\", \"#FF1177FF\": \"Hadfield Blue\", \"#FF000022\": \"Hadopelagic Water\", \"#FFC61A1B\": \"Haemoglobin Red\", \"#FFE6C9A3\": \"Hagar Shores\", \"#FFC3C7B2\": \"Haggis\", \"#FF8B837D\": \"Hagstone Choir\", \"#FF2C75FF\": \"Hailey Blue\", \"#FFD0D1E1\": \"Hailstorm\", \"#FFBDBEB9\": \"Hailstorm Grey\", \"#FFC1D8D9\": \"Haint Blue\", \"#FF8B7859\": \"Hair Brown\", \"#FF939CC9\": \"Hair Ribbon\", \"#FF633528\": \"Hairy Heath Variant\", \"#FF2C2A35\": \"Haiti Variant\", \"#FF97495A\": \"Haitian Flower\", \"#FF88B378\": \"Hakusai Green\", \"#FFF0E483\": \"Halak\\u0101 P\\u012bl\\u0101\", \"#FFD1D1CE\": \"Halation\", \"#FFF7BB73\": \"Halcyon Days\", \"#FF9BAAA2\": \"Halcyon Green\", \"#FF558F93\": \"Half Baked Variant\", \"#FFFBF0D6\": \"Half Dutch White Variant\", \"#FFCCCDB9\": \"Half Moon\", \"#FFCDA894\": \"Half Moon Bay Blush\", \"#FF976F3C\": \"Half Orc Highlight\", \"#FFF1EAD7\": \"Half Pearl Lusta\", \"#FFA9B8BB\": \"Half Sea Fog\", \"#FFE6DBC7\": \"Half Spanish White Variant\", \"#FF604C3D\": \"Half-Caff\", \"#FFEE8855\": \"Half-Smoke\", \"#FFC5B583\": \"Halfway Green\", \"#FF09324A\": \"Halite Blue\", \"#FFE2EBE5\": \"Hallowed Hush\", \"#FFFE653C\": \"Halloween\", \"#FFEB6123\": \"Halloween Party\", \"#FFDD2211\": \"Halloween Punch\", \"#FFE2C392\": \"Halo\", \"#FFF4E5D2\": \"Halogen\", \"#FFB0BAD5\": \"Halogen Blue\", \"#FFFF6633\": \"Halt and Catch Fire\", \"#FFA34E25\": \"Hamburger\", \"#FF8A99A4\": \"Hamilton Blue\", \"#FF65DCD6\": \"Hammam Blue\", \"#FF834831\": \"Hammered Copper\", \"#FFCB9D5E\": \"Hammered Gold\", \"#FF7E7567\": \"Hammered Pewter\", \"#FF978A7F\": \"Hammered Silver\", \"#FF4E7496\": \"Hammerhead Shark\", \"#FF6D8687\": \"Hammock\", \"#FFD9CADF\": \"Hampstead Heath\", \"#FFE8D4A2\": \"Hampton Variant\", \"#FF9D603B\": \"Hampton Beach\", \"#FF4F604F\": \"Hampton Green\", \"#FF597681\": \"Hampton Surf\", \"#FFA6814C\": \"Hamster Fur\", \"#FFC4D6AF\": \"Hamster Habitat\", \"#FFB07426\": \"Hamtaro Brown\", \"#FF1D697C\": \"Hanaasagi Blue\", \"#FF044F67\": \"Hanada Blue\", \"#FFF2ABE1\": \"Hanami Pink\", \"#FF4D6968\": \"Hancock\", \"#FFCEECEE\": \"Hand Sanitizer\", \"#FF7F735F\": \"Handmade\", \"#FFDDD6B7\": \"Handmade Linen\", \"#FFA87678\": \"Handmade Red\", \"#FF355887\": \"Handsome Blue\", \"#FF5286BA\": \"Handsome Hue\", \"#FFBFA984\": \"Handwoven\", \"#FF11AA44\": \"Hanging Gardens of Babylon\", \"#FF5C7F76\": \"Hanging Moss\", \"#FF6E897D\": \"Hanging Vine\", \"#FF685D4A\": \"Hannover Hills\", \"#FFDAC5B1\": \"Hanover\", \"#FF885D53\": \"Hanover Brick\", \"#FF848472\": \"Hanover Pewter\", \"#FFE9D66C\": \"Hansa Yellow\", \"#FF55FFAA\": \"Hanuman Green\", \"#FFE3D6C7\": \"Hanyauku\", \"#FFF8D664\": \"Happy\", \"#FF6B8350\": \"Happy Camper\", \"#FF979EA1\": \"Happy Cement\", \"#FF72A86A\": \"Happy Cricket\", \"#FF506E82\": \"Happy Days\", \"#FFF7CF1B\": \"Happy Daze\", \"#FFFFD10B\": \"Happy Face\", \"#FFD46362\": \"Happy Hearts\", \"#FF818581\": \"Happy Hippo\", \"#FFE0DABF\": \"Happy Margarine\", \"#FFF6CBCA\": \"Happy Piglets\", \"#FFFFBE98\": \"Happy Prawn\", \"#FFFAEED7\": \"Happy Skeleton\", \"#FFD1DFEB\": \"Happy Thoughts\", \"#FFB67A63\": \"Happy Trails\", \"#FF96B957\": \"Happy Tune\", \"#FFFFC217\": \"Happy Yipee\", \"#FFBACAD3\": \"Happy-Go-Lucky\", \"#FFE2D4D6\": \"Hapsburg Court\", \"#FF55AA55\": \"Har\\u0101 Green\", \"#FF504A6F\": \"Harajuku Girl\", \"#FF495867\": \"Harbour\", \"#FFE0E9F3\": \"Harbour Afternoon\", \"#FF417491\": \"Harbour Blue\", \"#FFAFB1B4\": \"Harbour Fog\", \"#FFA8C0BB\": \"Harbour Grey\", \"#FFD7E0E7\": \"Harbour Light\", \"#FF88AAAA\": \"Harbour Mist\", \"#FF778071\": \"Harbour Mist Grey\", \"#FF757D75\": \"Harbour Rat\", \"#FF7EB6D0\": \"Harbour Sky\", \"#FF4E536B\": \"Harbourmaster\", \"#FFFFBBBB\": \"Hard Candy\", \"#FF656464\": \"Hard Coal\", \"#FF8B8372\": \"Hardware\", \"#FFB56C23\": \"Hardy Clay\", \"#FF006383\": \"Harem Silk\", \"#FFBCCF8F\": \"Haricot\", \"#FFA52A2A\": \"Harissa Red\", \"#FF46CB18\": \"Harlequin Green\", \"#FFC93413\": \"Harley Davidson Orange\", \"#FF8547B5\": \"Harley Hair Purple\", \"#FFBB0000\": \"Harlock\\u2019s Cape\", \"#FFC1B287\": \"Harmonic Tan\", \"#FFAFC195\": \"Harmonious\", \"#FFEACFA3\": \"Harmonious Gold\", \"#FFF29CB7\": \"Harmonious Rose\", \"#FFEBC9C1\": \"Harmony\", \"#FF6DA493\": \"Harmony in Green\", \"#FF6D6353\": \"Harold\", \"#FFCBCEC0\": \"Harp Variant\", \"#FFCBD0D1\": \"Harp Strings\", \"#FF283B4C\": \"Harpoon\", \"#FFDCB571\": \"Harpswell Green\", \"#FF493C2B\": \"Harpy Brown\", \"#FF989B9E\": \"Harrison Grey\", \"#FF9A5F3F\": \"Harrison Rust\", \"#FF7E8E90\": \"Harrow\\u2019s Gate\", \"#FFEACB9D\": \"Harvest\", \"#FFCB862C\": \"Harvest at Dusk\", \"#FFBA8E4E\": \"Harvest Blessing\", \"#FFB9A589\": \"Harvest Brown\", \"#FFA5997C\": \"Harvest Dance\", \"#FFEAB76A\": \"Harvest Gold Variant\", \"#FFDE6931\": \"Harvest Haze\", \"#FFCBAE84\": \"Harvest Home\", \"#FF554488\": \"Harvest Night\", \"#FF65564F\": \"Harvest Oak\", \"#FFCD632A\": \"Harvest Pumpkin\", \"#FFCF875F\": \"Harvest Time\", \"#FFF7D7C4\": \"Harvest Wreath\", \"#FFEDC38E\": \"Harvester\", \"#FFBFA46F\": \"Hashibami Brown\", \"#FF8D608C\": \"Hashita Purple\", \"#FFC9643B\": \"Hashut Copper\", \"#FF009E6D\": \"Hassan II Mosque\", \"#FF8F775D\": \"Hat Box Brown\", \"#FFCFEBDE\": \"Hatching Chameleon\", \"#FFB2D1D6\": \"Hatchling Blue\", \"#FF95859C\": \"Hatoba Pigeon\", \"#FF9E8B8E\": \"Hatoba-Nezumi Grey\", \"#FF929E9D\": \"Hatteras Grey\", \"#FF57446A\": \"Haunted Candelabra\", \"#FF333355\": \"Haunted Dreams\", \"#FF032E0E\": \"Haunted Forest\", \"#FF003311\": \"Haunted Hills\", \"#FF991177\": \"Haunted Purple\", \"#FFD3E0EC\": \"Haunting Hue\", \"#FF824855\": \"Haunting Melody\", \"#FFA0252A\": \"Haute Couture\", \"#FF545E49\": \"Haute Green\", \"#FF9F7B58\": \"Haute Hickory\", \"#FFD899B1\": \"Haute Pink\", \"#FFAA1829\": \"Haute Red\", \"#FF3B2B2C\": \"Havana\", \"#FFA5DBE5\": \"Havana Blue\", \"#FFAF884A\": \"Havana Cigar\", \"#FF554941\": \"Havana Coffee\", \"#FFF9E5C2\": \"Havana Cream\", \"#FF007993\": \"Havasu\", \"#FF0FAFC6\": \"Havasupai Falls\", \"#FF5784C1\": \"Havelock Blue Variant\", \"#FFA3B48C\": \"Haven\", \"#FF00BBFF\": \"Hawaii Morning\", \"#FFD24833\": \"Hawaiian Ahi Poke\", \"#FF75C7E0\": \"Hawaiian Breeze\", \"#FF6F4542\": \"Hawaiian Cinder\", \"#FF99522C\": \"Hawaiian Coconut\", \"#FFFAE8B8\": \"Hawaiian Cream\", \"#FF96300D\": \"Hawaiian Malasada\", \"#FF008DB9\": \"Hawaiian Ocean\", \"#FFFFA03E\": \"Hawaiian Passion\", \"#FFFDD773\": \"Hawaiian Pineapple\", \"#FFFF0051\": \"Hawaiian Raspberry\", \"#FFF3DBD9\": \"Hawaiian Shell\", \"#FF83A2BD\": \"Hawaiian Sky\", \"#FFC06714\": \"Hawaiian Sunset\", \"#FF008DBB\": \"Hawaiian Surf\", \"#FF1D7033\": \"Hawaiian Ti Leaf\", \"#FF77CABD\": \"Hawaiian Vacation\", \"#FFAE8C5C\": \"Hawk Feather\", \"#FF77757D\": \"Hawk Grey\", \"#FF00756A\": \"Hawk Turquoise\", \"#FF34363A\": \"Hawk\\u2019s Eye\", \"#FFFDDB6D\": \"Hawkbit\", \"#FFF4C26C\": \"Hawker\\u2019s Gold\", \"#FFD2DAED\": \"Hawkes Blue Variant\", \"#FF729183\": \"Hawkesbury\", \"#FFCC1111\": \"Hawthorn Berry\", \"#FFEEFFAA\": \"Hawthorn Blossom\", \"#FF884C5E\": \"Hawthorn Rose\", \"#FFCED7C1\": \"Hawthorne\", \"#FFD3CAA3\": \"Hay\", \"#FFDACD81\": \"Hay Day\", \"#FFCDAD59\": \"Hay Wain\", \"#FFC2A770\": \"Hay Yellow\", \"#FF5F5D50\": \"Hayden Valley\", \"#FFCDBA96\": \"Hayloft\", \"#FFD4AC99\": \"Hayride\", \"#FFCFAC47\": \"Haystack\", \"#FFC8C2C6\": \"Haze\", \"#FFC39E6D\": \"Hazed Nuts\", \"#FFA36B4B\": \"Hazel\", \"#FFEAE2DE\": \"Hazel Blush\", \"#FFB8BFB1\": \"Hazel Gaze\", \"#FFA8715A\": \"Hazelnut\", \"#FFD28A47\": \"Hazelnut Coffee\", \"#FFE6DFCF\": \"Hazelnut Cream\", \"#FF742719\": \"Hazelnut Kisses\", \"#FFEEAA77\": \"Hazelnut Milk\", \"#FFD9BE9D\": \"Hazelnut Parfait\", \"#FFFCE974\": \"Hazelnut Turkish Delight\", \"#FFFFF3D5\": \"Hazelwood\", \"#FFB4C2CF\": \"Hazy\", \"#FFBCC8CC\": \"Hazy Blue\", \"#FFF2CC99\": \"Hazy Day\", \"#FFA5B8C5\": \"Hazy Daze\", \"#FFD2BAA1\": \"Hazy Earth\", \"#FFF2F1DC\": \"Hazy Grove\", \"#FFC7BAC0\": \"Hazy Iris\", \"#FFC8C6CE\": \"Hazy Mauve\", \"#FFF1DCA1\": \"Hazy Moon\", \"#FFB39897\": \"Hazy Rose\", \"#FFADBBC4\": \"Hazy Skies\", \"#FFB7BDD6\": \"Hazy Sky\", \"#FFA6A5A0\": \"Hazy Stratus\", \"#FFD5C3B5\": \"Hazy Taupe\", \"#FFDCDACE\": \"Hazy Trail\", \"#FFEACEA0\": \"Hazy Yellow\", \"#FFE1DBE3\": \"He Loves Me\", \"#FF7F5E00\": \"H\\u00e8 S\\u00e8 Brown\", \"#FFD1DDE1\": \"Head in the Clouds\", \"#FFEBE2DE\": \"Head in the Sand\", \"#FF605972\": \"Head Over Heels\", \"#FFB9CAB3\": \"Healing Aloe\", \"#FF6C7D42\": \"Healing Plant\", \"#FFBAC2AA\": \"Healing Retreat\", \"#FFE1E2C2\": \"Healing Springs\", \"#FFD2DCCE\": \"Healthy Wealthy and Wise\", \"#FF5BBD7F\": \"Heart Chakra\", \"#FF9D7F4C\": \"Heart of Gold\", \"#FFF7FCFF\": \"Heart of Ice\", \"#FFD2CFA6\": \"Heart of Palm\", \"#FFA97FB1\": \"Heart Potion\", \"#FFEDE3DF\": \"Heart Stone\", \"#FFD4A9C3\": \"Heart\", \"#FFE2B5BD\": \"Heart\\u2019s Content\", \"#FFAC3E5F\": \"Heart\\u2019s Desire\", \"#FFAA0000\": \"Heartbeat\", \"#FFCC76A3\": \"Heartbreaker\", \"#FFFFADC9\": \"Heartfelt\", \"#FFE1CCA6\": \"Hearth\", \"#FFB2C4BB\": \"Hearth Frost\", \"#FFA17135\": \"Hearth Gold\", \"#FFC7BEB2\": \"Hearthstone\", \"#FFA7C297\": \"Heartland Frosty\", \"#FF623B70\": \"Heartless\", \"#FFD47A76\": \"Hearts Afire\", \"#FFCFC291\": \"Hearts of Palm\", \"#FF9BAFD0\": \"Heartsong\", \"#FFA82E33\": \"Heartthrob\", \"#FFBF1818\": \"Heartwarming\", \"#FF6F4232\": \"Heartwood\", \"#FF96BF83\": \"Hearty Hosta\", \"#FFB44B34\": \"Hearty Orange\", \"#FFE98D5B\": \"Heat of Summer\", \"#FFE3000E\": \"Heat Signature\", \"#FF4F2A2C\": \"Heath Variant\", \"#FF9ACDA9\": \"Heath Green\", \"#FFC9CBC2\": \"Heath Grey\", \"#FF9F5F9F\": \"Heath Spotted Orchid\", \"#FFA484AC\": \"Heather Variant\", \"#FFB8ACAF\": \"Heather Bay\", \"#FFC3ADC5\": \"Heather Feather\", \"#FF909095\": \"Heather Field\", \"#FFBBB0BB\": \"Heather Hill\", \"#FF998E8F\": \"Heather Moor\", \"#FFA39699\": \"Heather Plume\", \"#FF988E94\": \"Heather Red Grey\", \"#FFA76372\": \"Heather Rose\", \"#FF7B7173\": \"Heather Sachet\", \"#FFB18398\": \"Heather Violet\", \"#FFEE4422\": \"Heating Lamp\", \"#FFFF7788\": \"Heatstroke\", \"#FFB4CED5\": \"Heaven\", \"#FFC7F1FF\": \"Heaven Gates\", \"#FFEEE1EB\": \"Heaven Sent\", \"#FFCAD6DE\": \"Heaven Sent Storm\", \"#FF7EB2C5\": \"Heavenly\", \"#FFEEDFD5\": \"Heavenly Aromas\", \"#FFA3BBCD\": \"Heavenly Blue\", \"#FFBEA79D\": \"Heavenly Cocoa\", \"#FF93A394\": \"Heavenly Garden\", \"#FFD8D5E3\": \"Heavenly Haze\", \"#FFF4DEDE\": \"Heavenly Pink\", \"#FF6B90B3\": \"Heavenly Sky\", \"#FFFBD9C6\": \"Heavenly Song\", \"#FFEBE8E6\": \"Heavenly White\", \"#FF3A514D\": \"Heavy Black Green\", \"#FF2C5674\": \"Heavy Blue\", \"#FF9FABAF\": \"Heavy Blue Grey\", \"#FF73624A\": \"Heavy Brown\", \"#FF565350\": \"Heavy Charcoal\", \"#FFE8DDC6\": \"Heavy Cream\", \"#FFDDCCAA\": \"Heavy Gluten\", \"#FFBAAB74\": \"Heavy Goldbrown\", \"#FF49583E\": \"Heavy Green\", \"#FF82868A\": \"Heavy Grey\", \"#FFBEB9A2\": \"Heavy Hammock\", \"#FF771122\": \"Heavy Heart\", \"#FF5E6A34\": \"Heavy Khaki\", \"#FF46473E\": \"Heavy Metal Variant\", \"#FF888A8E\": \"Heavy Metal Armour\", \"#FF9B753D\": \"Heavy Ochre\", \"#FFEE4328\": \"Heavy Orange\", \"#FF898A86\": \"Heavy Rain\", \"#FF9E1212\": \"Heavy Red\", \"#FF735848\": \"Heavy Siena\", \"#FFEFF5F1\": \"Heavy Sugar\", \"#FF4F566C\": \"Heavy Violet\", \"#FFBDB3A7\": \"Heavy Warm Grey\", \"#FFF0E4D2\": \"Hectorite\", \"#FF768A75\": \"Hedge Green\", \"#FF00AA11\": \"Hedged Garden\", \"#FFC4AA5E\": \"Hedgehog Cactus Yellow Green\", \"#FFFAF0DA\": \"Hedgehog Mushroom\", \"#FF142030\": \"H\\u0113i S\\u00e8 Black\", \"#FF960117\": \"Heidelberg Red\", \"#FFC3BDB1\": \"Heifer\", \"#FFB67B71\": \"Heirloom\", \"#FFF4BEA6\": \"Heirloom Apricot\", \"#FFE3664C\": \"Heirloom Blush\", \"#FF327CCB\": \"Heirloom Hydrangea\", \"#FFF5E6D6\": \"Heirloom Lace\", \"#FF9D96B2\": \"Heirloom Lilac\", \"#FFAE9999\": \"Heirloom Orchid\", \"#FFDBD5D0\": \"Heirloom Pink\", \"#FFAB979A\": \"Heirloom Quilt\", \"#FF801F23\": \"Heirloom Red\", \"#FFD182A0\": \"Heirloom Rose\", \"#FFDCD8D4\": \"Heirloom Shade\", \"#FFB5B6AD\": \"Heirloom Silver\", \"#FF833633\": \"Heirloom Tomato\", \"#FF70D4FB\": \"Heisenberg Blue\", \"#FFC3B89F\": \"Helen of Troy\", \"#FFD28B72\": \"Helena Rose\", \"#FFD94FF5\": \"Heliotrope Variant\", \"#FFAB98A9\": \"Heliotrope Grey\", \"#FFAA00BB\": \"Heliotrope Magenta\", \"#FF9187BD\": \"Heliotropic Mauve\", \"#FFEAE5D8\": \"Helium\", \"#FFC40700\": \"Hell Rider\", \"#FFBA622A\": \"Hell\\u2019s Bells\", \"#FF710101\": \"Hellbound\", \"#FF646944\": \"Hellebore\", \"#FF87C5AE\": \"Hellion Green\", \"#FF802280\": \"Hello Darkness My Old Friend\", \"#FFF3C7D1\": \"Hello Dolly\", \"#FF995533\": \"Hello Fall\", \"#FF44DD66\": \"Hello Spring\", \"#FF55BBFF\": \"Hello Summer\", \"#FF99FFEE\": \"Hello Winter\", \"#FFFFE59D\": \"Hello Yellow\", \"#FFF00000\": \"Helvetia Red\", \"#FF5F615F\": \"Hematite\", \"#FFDC8C59\": \"Hematitic Sand\", \"#FF5285A4\": \"Hemisphere\", \"#FF69684B\": \"Hemlock Variant\", \"#FFECEEDF\": \"Hemlock Bud\", \"#FF987D73\": \"Hemp Variant\", \"#FFB5AD88\": \"Hemp Fabric\", \"#FFB9A379\": \"Hemp Rope\", \"#FF864941\": \"Henna\", \"#FF6E3530\": \"Henna Red\", \"#FFB3675D\": \"Henna Shade\", \"#FFC4B146\": \"Hep Green\", \"#FFFBE5EA\": \"Hepatica\", \"#FFE1D4B6\": \"Hephaestus\", \"#FFFF9911\": \"Hephaestus Gold\", \"#FF6F123C\": \"Her Fierceness\", \"#FF432E6F\": \"Her Highness\", \"#FFF9A4A4\": \"Her Majesty\", \"#FFBB5F62\": \"Her Velour\", \"#FF7777EE\": \"Hera Blue\", \"#FFA46366\": \"Herald of Spring\", \"#FFCE9F2F\": \"Herald\\u2019s Trumpet\", \"#FF444161\": \"Heraldic\", \"#FFE7E0D3\": \"Herare White\", \"#FF708452\": \"Herb\", \"#FF4B856C\": \"Herb Blend\", \"#FF6E7357\": \"Herb Cornucopia\", \"#FFE9F3E1\": \"Herb Garden\", \"#FF64654A\": \"Herb Garland\", \"#FFDDA0DF\": \"Herb Robert\", \"#FF9CAD60\": \"Herbal Garden\", \"#FFC9B23D\": \"Herbal Green\", \"#FF6BA520\": \"Herbal Lift\", \"#FFD2E6D3\": \"Herbal Mist\", \"#FF8E9B7C\": \"Herbal Scent\", \"#FFF9FEE9\": \"Herbal Tea\", \"#FFDDFFCC\": \"Herbal Vapours\", \"#FFA49B82\": \"Herbal Wash\", \"#FF6B6D4E\": \"Herbal Whispers\", \"#FF969E86\": \"Herbalist\", \"#FF119900\": \"Herbalist\\u2019s Garden\", \"#FFEEEE22\": \"Herbery Honey\", \"#FFA9A487\": \"Herbes\", \"#FF3A5F49\": \"Herbes de Provence\", \"#FF88EE77\": \"Herbivore\", \"#FFFCDF63\": \"Here Comes the Sun\", \"#FF5F3B36\": \"Hereford Bull\", \"#FFB0BACC\": \"Heritage\", \"#FF5296B7\": \"Heritage Blue\", \"#FFCAC2B8\": \"Heritage Grey\", \"#FF5C453D\": \"Heritage Oak\", \"#FF69756C\": \"Heritage Park\", \"#FF956F7B\": \"Heritage Taffeta\", \"#FF9A8EC1\": \"Hermosa\", \"#FFFFB3F0\": \"Hermosa Pink\", \"#FF005D6A\": \"Hero\", \"#FF1166FF\": \"Heroic Blue\", \"#FFCBD5E9\": \"Heroic Heron\", \"#FFD1191C\": \"Heroic Red\", \"#FF6A6887\": \"Heron\", \"#FFE5E1D8\": \"Heron Plume\", \"#FFB1C4CD\": \"Heron Wing\", \"#FFC6C8CF\": \"Herring Silver\", \"#FFFFE296\": \"Hesperide Apple Gold\", \"#FFEE2200\": \"Hestia Red\", \"#FF6E0060\": \"Hexed Lichen\", \"#FFFBFF0A\": \"Hexos Palesun\", \"#FF16F8FF\": \"Hey Blue!\", \"#FFCD8E43\": \"Hey Honey!\", \"#FFBEA932\": \"Hey Pesto\", \"#FFBBB465\": \"Hi Def Lime\", \"#FFACA69F\": \"Hibernate\", \"#FF6F5166\": \"Hibernation\", \"#FFFE9773\": \"Hibiscus Delight\", \"#FFBC555E\": \"Hibiscus Flower\", \"#FF6E826E\": \"Hibiscus Leaf\", \"#FFEDAAAC\": \"Hibiscus Petal\", \"#FFDD77DD\": \"Hibiscus Pop\", \"#FF5C3D45\": \"Hibiscus Punch\", \"#FFA33737\": \"Hibiscus Red\", \"#FFB7A28E\": \"Hickory\", \"#FFAB8274\": \"Hickory Branch\", \"#FF69482A\": \"Hickory Chips\", \"#FF7C6E6D\": \"Hickory Cliff\", \"#FF655341\": \"Hickory Grove\", \"#FF78614C\": \"Hickory Nut\", \"#FF614539\": \"Hickory Plank\", \"#FF997772\": \"Hickory Stick\", \"#FFBC916F\": \"Hickory Tint\", \"#FF9C949B\": \"Hidcote\", \"#FF8D7F64\": \"Hidden Cottage\", \"#FFCEC6BD\": \"Hidden Cove\", \"#FFD5DAE0\": \"Hidden Creek\", \"#FF305451\": \"Hidden Depths\", \"#FFEDE4CC\": \"Hidden Diary\", \"#FF4F5A51\": \"Hidden Forest\", \"#FF98AD8E\": \"Hidden Glade\", \"#FF60737D\": \"Hidden Harbour\", \"#FFC5D2B1\": \"Hidden Hills\", \"#FFEBF1E2\": \"Hidden Jade\", \"#FF96748A\": \"Hidden Mask\", \"#FFBBCC5A\": \"Hidden Meadow\", \"#FFAA7C4C\": \"Hidden Morel\", \"#FF5E8B3D\": \"Hidden Paradise\", \"#FF3C3005\": \"Hidden Passage\", \"#FFE4D5B9\": \"Hidden Path\", \"#FF727D7F\": \"Hidden Peak\", \"#FF445771\": \"Hidden Sapphire\", \"#FF6FD1C9\": \"Hidden Sea Glass\", \"#FF1B8CB6\": \"Hidden Springs\", \"#FF5F5B4D\": \"Hidden Trail\", \"#FFA59074\": \"Hidden Treasure\", \"#FFBB9900\": \"Hidden Tribe\", \"#FF689938\": \"Hidden Valley\", \"#FF225258\": \"Hidden Waters\", \"#FFC8C0AA\": \"Hideaway\", \"#FF5386B7\": \"Hideout\", \"#FF77A373\": \"Hierba Santa\", \"#FF334F7B\": \"High Altar\", \"#FFA9DEDA\": \"High Altitude\", \"#FF4CA8E0\": \"High Blue\", \"#FF75603D\": \"High Chaparral\", \"#FFA06974\": \"High Country Rose\", \"#FF59B9CC\": \"High Dive\", \"#FF9A3843\": \"High Drama\", \"#FF665D25\": \"High Forest Green\", \"#FFBBDD00\": \"High Grass\", \"#FFEAEBE4\": \"High Hide White\", \"#FFE0B44D\": \"High Honey\", \"#FFDEEAAA\": \"High Hopes\", \"#FFD88CB5\": \"High Maintenance\", \"#FFCFB999\": \"High Noon\", \"#FF867A88\": \"High Note\", \"#FFE4B37A\": \"High Plateau\", \"#FFBCD8D2\": \"High Point\", \"#FF643949\": \"High Priest\", \"#FF005A85\": \"High Profile\", \"#FF645453\": \"High Rank\", \"#FFF7F7F1\": \"High Reflective White\", \"#FFAEB2B5\": \"High Rise\", \"#FFC71F2D\": \"High Risk Red\", \"#FF445056\": \"High Salute\", \"#FF7DABD8\": \"High Seas\", \"#FFCEDEE2\": \"High Sierra\", \"#FFCAB7C0\": \"High Society\", \"#FFAC9825\": \"High Strung\", \"#FFA8B1D7\": \"High Style\", \"#FFE4D7C3\": \"High Style Beige\", \"#FF7F6F57\": \"High Tea\", \"#FF567063\": \"High Tea Green\", \"#FF85A6C8\": \"High Tide\", \"#FFEEFF11\": \"High Voltage\", \"#FF6D7074\": \"High-Speed Steel\", \"#FF928C3C\": \"Highball\", \"#FF305144\": \"Highland Green\", \"#FF8F714B\": \"Highland Ridge\", \"#FFB9A1AE\": \"Highland Thistle\", \"#FFD3DAE3\": \"Highland Winds\", \"#FF3A533D\": \"Highlander\", \"#FF449084\": \"Highlands\", \"#FF445500\": \"Highlands Moss\", \"#FF484A80\": \"Highlands Twilight\", \"#FFEEF0DE\": \"Highlight\", \"#FFDFC16D\": \"Highlight Gold\", \"#FFFFE536\": \"Highlighter\", \"#FF3AAFDC\": \"Highlighter Blue\", \"#FF1BFC06\": \"Highlighter Green\", \"#FF85569C\": \"Highlighter Lavender\", \"#FFD72E83\": \"Highlighter Lilac\", \"#FFF39539\": \"Highlighter Orange\", \"#FFEA5A79\": \"Highlighter Pink\", \"#FFE94F58\": \"Highlighter Red\", \"#FF009E6C\": \"Highlighter Turquoise\", \"#FFF1E740\": \"Highlighter Yellow\", \"#FFBDB388\": \"Highway\", \"#FFCD1102\": \"Highway Variant\", \"#FF752E23\": \"Hihada Brown\", \"#FFD2B395\": \"Hiker\\u2019s Delight\", \"#FF9D9866\": \"Hiking\", \"#FF5E5440\": \"Hiking Boots\", \"#FFA99170\": \"Hiking Trail\", \"#FFE0EEDF\": \"Hill Giant\", \"#FF8DC248\": \"Hill Lands\", \"#FFA7A07E\": \"Hillary Variant\", \"#FF417B42\": \"Hills of Ireland\", \"#FF7FA91F\": \"Hillsbrad Grass\", \"#FF8F9783\": \"Hillside Green\", \"#FF80BF69\": \"Hillside Grove\", \"#FF8DA090\": \"Hillside View\", \"#FF587366\": \"Hilltop\", \"#FF768AA1\": \"Hilo Bay\", \"#FF736330\": \"Himalaya Variant\", \"#FFAECDE0\": \"Himalaya Blue\", \"#FFE2EAF0\": \"Himalaya Peaks\", \"#FF7695C2\": \"Himalaya Sky\", \"#FFB9DEE9\": \"Himalaya White Blue\", \"#FFFF99CC\": \"Himalayan Balsam\", \"#FFE1F0ED\": \"Himalayan Mist\", \"#FFBEC6D6\": \"Himalayan Poppy\", \"#FFC07765\": \"Himalayan Salt\", \"#FFFCC800\": \"Himawari Yellow\", \"#FFBDC9E3\": \"Hindsight\", \"#FFEE4D83\": \"Hindu Lotus\", \"#FFF8DDB7\": \"Hinoki\", \"#FFBC002D\": \"Hinomaru Red\", \"#FFCEE1F2\": \"Hint of Blue\", \"#FFD5933D\": \"Hint of Caramel\", \"#FFDC6080\": \"Hint of Cherry\", \"#FFE4DED0\": \"Hint of Cream\", \"#FFDFEADE\": \"Hint of Green Variant\", \"#FFFFD66D\": \"Hint of Honey\", \"#FFE1DBD5\": \"Hint of Mauve\", \"#FFDFF1D6\": \"Hint of Mint\", \"#FFF8E6D9\": \"Hint of Orange\", \"#FFF1E4E1\": \"Hint of Pink\", \"#FFF6DFE0\": \"Hint of Red Variant\", \"#FFEEE8DC\": \"Hint of Vanilla\", \"#FFD2D5E1\": \"Hint of Violet\", \"#FFFAF1CD\": \"Hint of Yellow Variant\", \"#FF616C51\": \"Hinterland\", \"#FF304112\": \"Hinterlands Green\", \"#FFCED9DD\": \"Hinting Blue\", \"#FFE4E8A7\": \"Hip Hop\", \"#FF746A51\": \"Hip Waders\", \"#FF49889A\": \"Hippie Blue Variant\", \"#FF608A5A\": \"Hippie Green Variant\", \"#FFAB495C\": \"Hippie Pink Variant\", \"#FFC6AA2B\": \"Hippie Trail\", \"#FF5C3C0D\": \"Hippogriff Brown\", \"#FFCFC294\": \"Hippolyta\", \"#FFEAE583\": \"Hippy\", \"#FFF2F1D9\": \"Hipster\", \"#FFBFB3AB\": \"Hipster Hippo\", \"#FFFD7C6E\": \"Hipster Salmon\", \"#FF88513E\": \"Hipsterfication\", \"#FF9BB9E1\": \"His Eyes\", \"#FFABCED8\": \"Hisoku Blue\", \"#FFFDF3E3\": \"Historic Cream\", \"#FFADA791\": \"Historic Shade\", \"#FFA18A64\": \"Historic Town\", \"#FFEBE6D7\": \"Historic White\", \"#FFA7A699\": \"Historical Grey\", \"#FFBFB9A7\": \"Historical Ruins\", \"#FF38B48B\": \"Hisui Kingfisher\", \"#FFFDA470\": \"Hit Pink Variant\", \"#FFEEFFA9\": \"Hitchcock Milk\", \"#FFC48D69\": \"Hitching Post\", \"#FFEE66FF\": \"Hitsujiyama Pink\", \"#FFFFFF77\": \"Hive\", \"#FFF1C24B\": \"Hive Delight\", \"#FFDBECFB\": \"Hoarfrost\", \"#FF01AD8F\": \"Hobgoblin\", \"#FF59685F\": \"Hockham Green\", \"#FF57A9D4\": \"Hoeth Blue\", \"#FFDCD1BB\": \"Hog Bristle\", \"#FFFBE8E4\": \"Hog-Maw\", \"#FFDAD5C7\": \"Hog\\u2019s Pudding\", \"#FFBB8E34\": \"Hokey Pokey Variant\", \"#FF647D86\": \"Hoki Variant\", \"#FF7736D9\": \"Hokkaido Lavender\", \"#FF547D86\": \"Holbein Blue Grey\", \"#FF705446\": \"Hold Your Horses\", \"#FF4AAE97\": \"Hole in One\", \"#FF598069\": \"Holenso\", \"#FF81C3B4\": \"Holiday\", \"#FF32BCD1\": \"Holiday Blue\", \"#FF6D9E7A\": \"Holiday Camp\", \"#FFB1D1E2\": \"Holiday Road\", \"#FF8AC6BD\": \"Holiday Turquoise\", \"#FF206174\": \"Holiday Velvet\", \"#FFB78846\": \"Holiday Waffle\", \"#FFCB4543\": \"Holland Red\", \"#FFDD9789\": \"Holland Tile\", \"#FFF89851\": \"Holland Tulip\", \"#FFFFEE44\": \"Hollandaise\", \"#FFAC8E84\": \"Hollow Brown\", \"#FF330055\": \"Hollow Knight\", \"#FF25342B\": \"Holly Variant\", \"#FFB44E5D\": \"Holly Berry\", \"#FF355D51\": \"Holly Bush\", \"#FF8CB299\": \"Holly Fern\", \"#FFA2B7B5\": \"Holly Glen\", \"#FF0F9D76\": \"Holly Green\", \"#FFB50729\": \"Holly Jolly Christmas\", \"#FF2E5A50\": \"Holly Leaf\", \"#FF913881\": \"Hollyhock\", \"#FFB7737D\": \"Hollyhock Bloom\", \"#FFBD79A5\": \"Hollyhock Blossom Pink\", \"#FFC2A1B5\": \"Hollyhock Pink\", \"#FFC7AF4A\": \"Hollywood\", \"#FFDEE7D4\": \"Hollywood Asparagus\", \"#FFF400A0\": \"Hollywood Cerise Variant\", \"#FFECD8B1\": \"Hollywood Golden Age\", \"#FFF2D082\": \"Hollywood Starlet\", \"#FFDBBB9E\": \"Holmes Cream\", \"#FFF0E5F5\": \"Holographic Lavender\", \"#FFDB783E\": \"Holy Cannoli\", \"#FF332F2C\": \"Holy Crow\", \"#FFEFE9E6\": \"Holy Ghost\", \"#FFE8D720\": \"Holy Grail\", \"#FF466E77\": \"Holy Water\", \"#FF666D69\": \"Homburg Grey\", \"#FFE8CABA\": \"Home and Hearth\", \"#FFF3D2B2\": \"Home Body\", \"#FF897B66\": \"Home Brew\", \"#FFF7EEDB\": \"Home Plate\", \"#FFF2EEC7\": \"Home Song\", \"#FF9B7E65\": \"Home Sweet Home\", \"#FF726E69\": \"Homebush\", \"#FF63884A\": \"Homegrown\", \"#FFB18D75\": \"Homeland\", \"#FFAC8674\": \"Homestead\", \"#FF6F5F52\": \"Homestead Brown\", \"#FF986E6E\": \"Homestead Red\", \"#FFE9BF91\": \"Homeward Bound\", \"#FF2299DD\": \"Homeworld\", \"#FFF0D8AF\": \"Homey Cream\", \"#FF5F7C47\": \"Homoeopathic\", \"#FFDBE7E3\": \"Homoeopathic Blue\", \"#FFE1EBD8\": \"Homoeopathic Green\", \"#FFE5E0EC\": \"Homoeopathic Lavender\", \"#FFE1E0EB\": \"Homoeopathic Lilac\", \"#FFE9F6E2\": \"Homoeopathic Lime\", \"#FFE5EAD8\": \"Homoeopathic Mint\", \"#FFF2E6E1\": \"Homoeopathic Orange\", \"#FFECDBE0\": \"Homoeopathic Red\", \"#FFE8DBDD\": \"Homoeopathic Rose\", \"#FFEDE7D7\": \"Homoeopathic Yellow\", \"#FF9D9887\": \"Honed Soapstone\", \"#FF867C83\": \"Honed Steel\", \"#FF9BB8E2\": \"Honest\", \"#FF5A839E\": \"Honest Blue\", \"#FFDFEBE9\": \"Honesty\", \"#FFAE8934\": \"Honey\", \"#FFF1DDAD\": \"Honey and Cream\", \"#FFAAAA00\": \"Honey and Thyme\", \"#FFFFAA99\": \"Honey Baked Ham\", \"#FFE8C281\": \"Honey Bear\", \"#FFFCDFA4\": \"Honey Bee\", \"#FFD39F5F\": \"Honey Beehive\", \"#FFF3E2C6\": \"Honey Beige\", \"#FFFFD28D\": \"Honey Bird\", \"#FFF5CF9B\": \"Honey Blush\", \"#FFDAA47A\": \"Honey Bronze\", \"#FFDBB881\": \"Honey Bunny\", \"#FFF5D29B\": \"Honey Butter\", \"#FFFF9955\": \"Honey Carrot Cake\", \"#FF883344\": \"Honey Chilli\", \"#FFE9C160\": \"Honey Crisp\", \"#FFFFBB55\": \"Honey Crusted Chicken\", \"#FFEDEDC7\": \"Honey Do\", \"#FF5C3C6D\": \"Honey Flower Variant\", \"#FFD18E54\": \"Honey Fungus\", \"#FF884422\": \"Honey Garlic Beef\", \"#FFBA6219\": \"Honey Ginger\", \"#FFFFD775\": \"Honey Glaze\", \"#FFE8B447\": \"Honey Glow\", \"#FFE1B67C\": \"Honey Gold\", \"#FFBC886A\": \"Honey Graham\", \"#FFDCB149\": \"Honey Grove\", \"#FFBC9263\": \"Honey Haven\", \"#FFDDCCBB\": \"Honey Lime Chicken\", \"#FFFFC367\": \"Honey Locust\", \"#FFA46D5C\": \"Honey Maple\", \"#FFE5D9B2\": \"Honey Mist\", \"#FFFBECCC\": \"Honey Moth\", \"#FFB28C4B\": \"Honey Mustard\", \"#FFF1DDA2\": \"Honey Nectar\", \"#FFE0BB96\": \"Honey Nougat\", \"#FFFAEED9\": \"Honey Oat Bread\", \"#FFDBBF9A\": \"Honey Peach\", \"#FFCC99AA\": \"Honey Pink\", \"#FFDFBB86\": \"Honey Robber\", \"#FFD8BE89\": \"Honey Tea\", \"#FFEE6611\": \"Honey Teriyaki\", \"#FFF8DC9B\": \"Honey Tone\", \"#FFFFAA22\": \"Honey Wax\", \"#FFCA9456\": \"Honey Yellow\", \"#FF937016\": \"Honey Yellow Green\", \"#FFF3F0D9\": \"Honey Yoghurt Popsicles\", \"#FFDDAA11\": \"Honeycomb\", \"#FFE4CF99\": \"Honeycomb Glow\", \"#FFDE9C52\": \"Honeycomb Yellow\", \"#FFE6ECCC\": \"Honeydew Melon\", \"#FFD4FB79\": \"Honeydew Peel\", \"#FFEECE8D\": \"Honeydew Sand\", \"#FFEFC488\": \"Honeyed Glow\", \"#FFD7BB80\": \"Honeymoon\", \"#FFFFC863\": \"Honeypot\", \"#FFE8ED69\": \"Honeysuckle Variant\", \"#FFEACA90\": \"Honeysuckle Beige\", \"#FFB3833F\": \"Honeysuckle Blast\", \"#FFE8D4C9\": \"Honeysuckle Delight\", \"#FFDE8F8D\": \"Honeysuckle Rose\", \"#FFFBF1C8\": \"Honeysuckle Vine\", \"#FFF8ECD3\": \"Honeysuckle White\", \"#FFE9CFC8\": \"Honeysweet\", \"#FFE02006\": \"H\\u00f3ng B\\u01ceo Sh\\u016b Red\", \"#FF948E90\": \"Hong Kong Mist\", \"#FF676E7A\": \"Hong Kong Skyline\", \"#FFA8102A\": \"Hong Kong Taxi\", \"#FFCF3F4F\": \"H\\u00f3ng L\\u00f3u M\\u00e8ng Red\", \"#FFFF0809\": \"H\\u00f3ng S\\u00e8 Red\", \"#FF564A33\": \"H\\u00f3ng Z\\u014dng Brown\", \"#FFFCEFD1\": \"Honied White\", \"#FF446A8D\": \"Honky Tonk Blue\", \"#FF96CBF1\": \"Honolulu\", \"#FF007FBF\": \"Honolulu Blue\", \"#FF164576\": \"Honourable Blue\", \"#FFFFC9C4\": \"Hooked Mimosa\", \"#FF4455FF\": \"Hooloovoo Blue\", \"#FFCD6D93\": \"Hopbush Variant\", \"#FFE581A0\": \"Hope\", \"#FF875942\": \"Hope Chest\", \"#FFF2D4E2\": \"Hopeful\", \"#FFA2B9BF\": \"Hopeful Blue\", \"#FF95A9CD\": \"Hopeful Dream\", \"#FF174871\": \"Hopi Blue Corn\", \"#FF9E8163\": \"Hopsack\", \"#FFAFBB42\": \"Hopscotch\", \"#FFF2E9D9\": \"Horchata\", \"#FF789B73\": \"Horenso Green\", \"#FF648894\": \"Horizon Variant\", \"#FFAD7171\": \"Horizon Glow\", \"#FF9CA9AA\": \"Horizon Grey\", \"#FF80C1E2\": \"Horizon Haze\", \"#FFCDD4C6\": \"Horizon Island\", \"#FFC2C3D3\": \"Horizon Sky\", \"#FF51576F\": \"Hormagaunt Purple\", \"#FFBBA46D\": \"Horn of Plenty\", \"#FF332222\": \"Hornblende\", \"#FF234E4D\": \"Hornblende Green\", \"#FFC2AE87\": \"Horned Frog\", \"#FFE8EAD5\": \"Horned Lizard\", \"#FFD5DFD3\": \"Hornet Nest\", \"#FFFF0033\": \"Hornet Sting\", \"#FFA67C08\": \"Hornet Yellow\", \"#FFD34D4D\": \"Horror Snob\", \"#FFE6DFC4\": \"Horseradish\", \"#FFEEEADD\": \"Horseradish Cream\", \"#FFFFDEA9\": \"Horseradish Yellow\", \"#FF6D562C\": \"Horses Neck Variant\", \"#FF8B8893\": \"Horseshoe\", \"#FF3D5D42\": \"Horsetail\", \"#FF9A6C39\": \"Horsing Around\", \"#FF61435B\": \"Hortensia\", \"#FFDBB8BF\": \"Hosanna\", \"#FF9BE5AA\": \"Hospital Green\", \"#FFDCDDE7\": \"Hosta Flower\", \"#FF475A56\": \"Hostaleaf\", \"#FFAC4362\": \"Hot\", \"#FFB35547\": \"Hot and Spicy\", \"#FFFFB3DE\": \"Hot Aquarelle Pink\", \"#FFFFF6D9\": \"Hot Beach\", \"#FFCC5511\": \"Hot Bolognese\", \"#FF984218\": \"Hot Brown\", \"#FFE69D00\": \"Hot Butter\", \"#FFA5694F\": \"Hot Cacao\", \"#FFFA8D7C\": \"Hot Calypso\", \"#FFCC6E3B\": \"Hot Caramel\", \"#FFB7513A\": \"Hot Chilli\", \"#FF683939\": \"Hot Chocolate\", \"#FFD1691C\": \"Hot Cinnamon Variant\", \"#FF806257\": \"Hot Cocoa\", \"#FFF35B53\": \"Hot Coral\", \"#FFBB0033\": \"Hot Cuba\", \"#FF815B28\": \"Hot Curry\", \"#FFEAE4DA\": \"Hot Desert\", \"#FF717C3E\": \"Hot Dog Relish\", \"#FFF55931\": \"Hot Embers\", \"#FFD40301\": \"Hot Fever\", \"#FFDD180E\": \"Hot Flamin Chilli\", \"#FFB35966\": \"Hot Flamingo\", \"#FF5E2912\": \"Hot Fudge\", \"#FFA36736\": \"Hot Ginger\", \"#FFE07C89\": \"Hot Gossip\", \"#FF25FF29\": \"Hot Green\", \"#FFDD6622\": \"Hot Hazel\", \"#FFBB2244\": \"Hot Hibiscus\", \"#FFBC3033\": \"Hot Jazz\", \"#FFAA0033\": \"Hot Lava\", \"#FFC9312B\": \"Hot Lips\", \"#FF735C12\": \"Hot Mustard\", \"#FFF4893D\": \"Hot Orange\", \"#FF598039\": \"Hot Pepper Green\", \"#FFFF028D\": \"Hot Pink Variant\", \"#FFFE69B6\": \"Hot Pink Fusion\", \"#FFCB00F5\": \"Hot Purple\", \"#FFCCAA00\": \"Hot Sand\", \"#FFAB4F41\": \"Hot Sauce\", \"#FF3F3F75\": \"Hot Sauna\", \"#FFEC4F28\": \"Hot Shot\", \"#FFCC2211\": \"Hot Spice\", \"#FFABA89E\": \"Hot Stone\", \"#FFF9B82B\": \"Hot Sun\", \"#FFA24A3F\": \"Hot Tamale\", \"#FFA7752C\": \"Hot Toddy Variant\", \"#FFD26E2D\": \"Hot Wings\", \"#FF755468\": \"Hothouse Orchid\", \"#FFF1F3F2\": \"Hotot Bunny\", \"#FFFF4433\": \"Hotspot\", \"#FFE68A00\": \"Hotter Butter\", \"#FFFF4455\": \"Hotter Than Hell\", \"#FFFF80FF\": \"Hottest of Pinks\", \"#FFE5E0D5\": \"Hourglass\", \"#FFE2E0DB\": \"House Martin Eggs\", \"#FF9AA0BD\": \"House of Owen\", \"#FFD6D9DD\": \"House Sparrow\\u2019s Egg\", \"#FF4D495B\": \"House Stark Grey\", \"#FF58713F\": \"Houseplant\", \"#FFA0AEB8\": \"How Handsome\", \"#FF886150\": \"How Now\", \"#FFF9E4C8\": \"Howdy Neighbor\", \"#FFC6A698\": \"Howdy Partner\", \"#FF9C7F5A\": \"Howling Coyote\", \"#FFE50752\": \"Howling Pink\", \"#FF1DACD1\": \"H\\u00fa L\\u00e1n Blue\", \"#FFF8FF73\": \"Hu\\u00e1ng D\\u00ec Yellow\", \"#FFFADA6A\": \"Hu\\u00e1ng J\\u012bn Zh\\u014du Gold\", \"#FFF0F20C\": \"Hu\\u00e1ng S\\u00e8 Yellow\", \"#FFE9BF8C\": \"Hubbard Squash\", \"#FF559933\": \"Hubert\\u2019s Truck Green\", \"#FF5B4349\": \"Huckleberry\", \"#FF71563B\": \"Huckleberry Brown\", \"#FFEADBD2\": \"Hudson\", \"#FFFDEF02\": \"Hudson Bee\", \"#FF17A9E5\": \"Huelve\\u00f1o Horizon\", \"#FF9FA09F\": \"Hugh\\u2019s Hue\", \"#FFE6CFCC\": \"Hugo\", \"#FFC1C6D3\": \"H\\u016bi S\\u00e8 Grey\", \"#FF929264\": \"Hula Girl\", \"#FF726F6C\": \"Hulett Ore\", \"#FF4D140B\": \"Hull Red\", \"#FFE3DAD3\": \"Humble Beginnings\", \"#FFE3CDC2\": \"Humble Blush\", \"#FFEDC796\": \"Humble Gold\", \"#FFAAAA99\": \"Humble Hippo\", \"#FF1F6357\": \"Humboldt Redwoods\", \"#FFC9CCD2\": \"Humid Cave\", \"#FFCEEFE4\": \"Hummingbird\", \"#FF5B724A\": \"Hummingbird Green\", \"#FFEECC99\": \"Hummus\", \"#FFC6B836\": \"Humorous Green\", \"#FF473B3B\": \"Humpback Whale\", \"#FFB7A793\": \"Humus\", \"#FFB2B7D1\": \"Hundred Waters\", \"#FFF0000D\": \"Hungry Red\", \"#FFBB11FF\": \"Hunky Hummingbird\", \"#FF2A4F43\": \"Hunt Club\", \"#FF938370\": \"Hunt Club Brown\", \"#FF33534B\": \"Hunter\", \"#FF0B4008\": \"Hunter Green Variant\", \"#FF989A8D\": \"Hunter\\u2019s Hollow\", \"#FFDB472C\": \"Hunter\\u2019s Orange\", \"#FF6B5A54\": \"Hunting Boots\", \"#FF856829\": \"Hunting Jacket\", \"#FF96A782\": \"Huntington Garden\", \"#FF46554C\": \"Huntington Woods\", \"#FF8B7E77\": \"Hurricane Variant\", \"#FF254D54\": \"Hurricane Green Blue\", \"#FFBDBBAD\": \"Hurricane Haze\", \"#FFEBEEE8\": \"Hurricane Mist\", \"#FFC4BDBA\": \"Hush\", \"#FFE1DED8\": \"Hush Grey\", \"#FFF8E9E2\": \"Hush Pink\", \"#FFE4B095\": \"Hush Puppy\", \"#FFE5DAD4\": \"Hush White\", \"#FF5397B7\": \"Hush-A-Bye\", \"#FFA8857A\": \"Hushed Auburn\", \"#FFC8E0DB\": \"Hushed Green\", \"#FF6E8FB4\": \"Hushed Lilac\", \"#FFEEA5C1\": \"Hushed Rose\", \"#FFCDBBB9\": \"Hushed Violet\", \"#FFF1F2E4\": \"Hushed White\", \"#FFB2994B\": \"Husk Variant\", \"#FFE0EBFA\": \"Husky\", \"#FFBB613E\": \"Husky Orange\", \"#FFAE957C\": \"Hutchins Plaza\", \"#FF936CA7\": \"Hyacinth\", \"#FF6C6783\": \"Hyacinth Arbour\", \"#FF807388\": \"Hyacinth Dream\", \"#FFC8C8D2\": \"Hyacinth Ice\", \"#FF6F729F\": \"Hyacinth Mauve\", \"#FFA75536\": \"Hyacinth Red\", \"#FFB9C4D3\": \"Hyacinth Tint\", \"#FF9B4D93\": \"Hyacinth Violet\", \"#FFC1C7D7\": \"Hyacinth White Soft Blue\", \"#FFD0CDA9\": \"Hybrid\", \"#FF626045\": \"Hyde Park\", \"#FF006995\": \"Hydra\", \"#FF007A73\": \"Hydra Turquoise\", \"#FF768DC6\": \"Hydrangea\", \"#FFA6AEBE\": \"Hydrangea Blossom\", \"#FFCAA6A9\": \"Hydrangea Bouquet\", \"#FFE6EAE0\": \"Hydrangea Floret\", \"#FFCAA0FF\": \"Hydrangea Purple\", \"#FF9E194D\": \"Hydrangea Red\", \"#FF9B9B9B\": \"Hydrargyrum\", \"#FF49747F\": \"Hydro\", \"#FFA1F4F5\": \"Hydro Cannon\", \"#FF33476D\": \"Hydrogen Blue\", \"#FF89ACAC\": \"Hydrology\", \"#FF5E9CA1\": \"Hydroport\", \"#FFE0E1D8\": \"Hygge Green\", \"#FF5DBCB4\": \"Hygiene Green\", \"#FFF6F677\": \"Hyper Beam\", \"#FF015F97\": \"Hyper Blue\", \"#FF55FF00\": \"Hyper Green\", \"#FFEDDBDA\": \"Hyper Light Drifter\", \"#FFEC006C\": \"Hyper Pink\", \"#FF0000EE\": \"Hyperlink Blue\", \"#FF17F9A6\": \"Hyperpop Green\", \"#FF687783\": \"Hypnotic\", \"#FF73E608\": \"Hypnotic Green\", \"#FFCF0D14\": \"Hypnotic Red\", \"#FF00787F\": \"Hypnotic Sea\", \"#FF32584C\": \"Hypnotism\", \"#FF415D66\": \"Hypothalamus Grey\", \"#FF6D4976\": \"Hyssop\", \"#FFFFA917\": \"I Love\", \"#FFD97D8F\": \"I Love You Pink\", \"#FFDDDBC5\": \"I Miss You\", \"#FFD47F8D\": \"I Pink I Can\", \"#FF404034\": \"I R Dark Green\", \"#FFEBBF5C\": \"I\\u2019m a Local\", \"#FF482400\": \"Ibex Brown\", \"#FFF4B3C2\": \"Ibis\", \"#FFE4D2D8\": \"Ibis Mouse\", \"#FFFBD0B9\": \"Ibis Pink\", \"#FFCA628F\": \"Ibis Rose\", \"#FFF2ECE6\": \"Ibis White\", \"#FFF58F84\": \"Ibis Wing\", \"#FF0086BC\": \"Ibiza Blue\", \"#FFD6FFFA\": \"Ice\", \"#FFC6E4E9\": \"Ice Age\", \"#FFEADEE8\": \"Ice Ballet\", \"#FF739BD0\": \"Ice Blue\", \"#FF717787\": \"Ice Blue Grey\", \"#FFCCE2DD\": \"Ice Bomb\", \"#FFA2CDCB\": \"Ice Boutique Turquoise\", \"#FFB9E7DD\": \"Ice Cap Green\", \"#FFD5EDFB\": \"Ice Castle\", \"#FFA0BEDA\": \"Ice Cave\", \"#FFB2F8F8\": \"Ice Citadel\", \"#FF25E2CD\": \"Ice Climber\", \"#FFD2EAF1\": \"Ice Cold Variant\", \"#FFD9EBAC\": \"Ice Cold Green\", \"#FFB1D1FC\": \"Ice Cold Stare\", \"#FFE3D0BF\": \"Ice Cream Cone\", \"#FFF7D3AD\": \"Ice Cream Parlour\", \"#FFA6E3E0\": \"Ice Crystal Blue\", \"#FFAFE3D6\": \"Ice Cube\", \"#FFCEE5DF\": \"Ice Dagger\", \"#FF005456\": \"Ice Dark Turquoise\", \"#FFD1DCE8\": \"Ice Desert\", \"#FFEAEBE1\": \"Ice Dream\", \"#FFD3E2EE\": \"Ice Drop\", \"#FFBBEEFF\": \"Ice Effect\", \"#FFDCECF5\": \"Ice Fishing\", \"#FFD8E7E1\": \"Ice Floe\", \"#FFBDCBCB\": \"Ice Flow\", \"#FFC3E7EC\": \"Ice Flower\", \"#FFDBECE9\": \"Ice Folly\", \"#FFFFFFE9\": \"Ice Glow\", \"#FF87D8C3\": \"Ice Green\", \"#FFCAC7C4\": \"Ice Grey\", \"#FF9BB2BA\": \"Ice Gull Grey Blue\", \"#FFE4BDC2\": \"Ice Hot Pink\", \"#FFBAEBAE\": \"Ice Ice\", \"#FF00FFDD\": \"Ice Ice Baby\", \"#FFFFFBC1\": \"Ice Lemon\", \"#FFC9C2DD\": \"Ice Mauve\", \"#FFB6DBBF\": \"Ice Mist\", \"#FFA5DBE3\": \"Ice Pack\", \"#FFE2E4D7\": \"Ice Palace\", \"#FFCF7EAD\": \"Ice Plant\", \"#FFBBDDEE\": \"Ice Rink\", \"#FFC8D6DA\": \"Ice Rink Blue\", \"#FFE1E6E5\": \"Ice Sculpture\", \"#FFC1DEE2\": \"Ice Shard Soft Blue\", \"#FF11FFEE\": \"Ice Temple\", \"#FFCDEBE1\": \"Ice Water Green\", \"#FFFEFECD\": \"Ice Yellow\", \"#FFDFF0E2\": \"Ice-Cold White\", \"#FFDAE4EE\": \"Iceberg Tint\", \"#FF8C9C92\": \"Iceberg Green\", \"#FFB7C2CC\": \"Icebreaker\", \"#FFC3D6E0\": \"Icecap\", \"#FFFEF4DD\": \"Iced Almond\", \"#FFCBD3C3\": \"Iced Aniseed\", \"#FFEFD6C0\": \"Iced Apricot\", \"#FFA7D4D9\": \"Iced Aqua\", \"#FFC8E4B9\": \"Iced Avocado\", \"#FFE9819A\": \"Iced Berry\", \"#FF9C8866\": \"Iced Cappuccino\", \"#FFE5E9B7\": \"Iced Celery\", \"#FFE8C7BF\": \"Iced Cherry\", \"#FFAA895D\": \"Iced Coffee\", \"#FFD0AE9A\": \"Iced Copper\", \"#FF5A4A42\": \"Iced Espresso\", \"#FFECEBC9\": \"Iced Green Apple\", \"#FFC2C7DB\": \"Iced Lavender\", \"#FFE8DCE3\": \"Iced Mauve\", \"#FFA3846C\": \"Iced Mocha\", \"#FF8E7D89\": \"Iced Orchid\", \"#FFD6DCD7\": \"Iced Slate\", \"#FFB87253\": \"Iced Tea\", \"#FFAFA9AF\": \"Iced Tulip\", \"#FFE1A4B2\": \"Iced Vovo\", \"#FFD1AFB7\": \"Iced Watermelon\", \"#FF008B52\": \"Iceland Green\", \"#FFF37E27\": \"Iceland Poppy\", \"#FFDAE4EC\": \"Icelandic\", \"#FFA0A4BC\": \"Icelandic Blue\", \"#FF0011FF\": \"Icelandic Water\", \"#FFD7DEEB\": \"Icelandic Winds\", \"#FFD9E7E3\": \"Icelandic Winter\", \"#FFCCDFDC\": \"Icelandish\", \"#FFDADCD0\": \"Icepick\", \"#FFA5FCDC\": \"Icery\", \"#FFE8ECEE\": \"Icewind Dale\", \"#FFCFE8E6\": \"Icicle Mint\", \"#FFD9E7F2\": \"Icicle Veil\", \"#FFBCC5C9\": \"Icicles\", \"#FFD5B7CB\": \"Icing Flower\", \"#FFF8C4C5\": \"Icing on the Cake\", \"#FFF5EEE7\": \"Icing Rose\", \"#FF8FAE22\": \"Icky Green\", \"#FFBBC7D2\": \"Icy\", \"#FFE0E5E2\": \"Icy Bay\", \"#FFCCEDEA\": \"Icy Blue\", \"#FFC4ECF0\": \"Icy Breeze\", \"#FFC1CAD9\": \"Icy Brook\", \"#FFD4EAE1\": \"Icy Glacier\", \"#FFC5E6F7\": \"Icy Landscape\", \"#FFE2E2ED\": \"Icy Lavender\", \"#FFF4E8B2\": \"Icy Lemonade\", \"#FF55FFEE\": \"Icy Life\", \"#FFE6E9F9\": \"Icy Lilac\", \"#FFC6E3D3\": \"Icy Mint\", \"#FFB0D3D1\": \"Icy Morn\", \"#FFF5CED8\": \"Icy Pink\", \"#FFE6F2E9\": \"Icy Pistachio\", \"#FFCFDAFB\": \"Icy Plains\", \"#FFD6DFE8\": \"Icy Teal\", \"#FFF7F5EC\": \"Icy Tundra\", \"#FFBCE2E8\": \"Icy Water\", \"#FFC0D2D0\": \"Icy Waterfall\", \"#FFD3F1EE\": \"Icy Wind\", \"#FF7890AC\": \"Identity\", \"#FFCAE277\": \"Idocrase Green\", \"#FF645A8B\": \"Idol\", \"#FF598476\": \"Idyllic Island\", \"#FF94C8D2\": \"Idyllic Isle\", \"#FFC89EB7\": \"Idyllic Pink\", \"#FF6F5A4A\": \"If a Tree Fell \\u2026\", \"#FF6D68ED\": \"If I Could Fly\", \"#FFFDFCFA\": \"Igloo\", \"#FFC9E5EB\": \"Igloo Blue\", \"#FFF4D69A\": \"Igniting\", \"#FF2E776D\": \"Igua\\u00e7uense Waterfall\", \"#FF878757\": \"Iguana\", \"#FF71BC77\": \"Iguana Green\", \"#FFF08F90\": \"Ikkonzome Pink\", \"#FF00022E\": \"Illicit Darkness\", \"#FF56FCA2\": \"Illicit Green\", \"#FFFF5CCD\": \"Illicit Pink\", \"#FFBF77F6\": \"Illicit Purple\", \"#FFEAA601\": \"Illuminate Me\", \"#FFF9E5D8\": \"Illuminated\", \"#FF419168\": \"Illuminati Green\", \"#FFEEEE77\": \"Illuminating\", \"#FFDEE4E0\": \"Illuminating Experience\", \"#FFEF95AE\": \"Illusion Variant\", \"#FFC3CED8\": \"Illusion Blue\", \"#FF574F64\": \"Illusionist\", \"#FFE1D5C2\": \"Illusive Dream\", \"#FF92948D\": \"Illusive Green\", \"#FF5533BB\": \"Illustrious Indigo\", \"#FF330011\": \"Ilvaite Black\", \"#FF7A6E70\": \"Imagery\", \"#FF89687D\": \"Imaginary Mauve\", \"#FFDFE0EE\": \"Imagination\", \"#FFFAE199\": \"Imam Ali Gold\", \"#FFD0576B\": \"Imayou Pink\", \"#FFCEEBB2\": \"Imbued With Mint\", \"#FFAACC00\": \"Immaculate Iguana\", \"#FF204F54\": \"Immersed\", \"#FFC0A9CC\": \"Immortal\", \"#FFD8B7CF\": \"Immortal Indigo\", \"#FF945B7F\": \"Immortality\", \"#FFD4A207\": \"Immortelle Yellow\", \"#FFF4CF95\": \"Impala\", \"#FFF1D2D7\": \"Impatiens Petal\", \"#FFFFC4BC\": \"Impatiens Pink\", \"#FFC47D7C\": \"Impatient Heart\", \"#FFDB7B97\": \"Impatient Pink\", \"#FF602F6B\": \"Imperial\", \"#FF002395\": \"Imperial Blue\", \"#FF33746B\": \"Imperial Dynasty\", \"#FFE0B181\": \"Imperial Gold\", \"#FF408750\": \"Imperial Green\", \"#FF676A6A\": \"Imperial Grey\", \"#FFF1E8D2\": \"Imperial Ivory\", \"#FF693E42\": \"Imperial Jewel\", \"#FFA99FCF\": \"Imperial Lilac\", \"#FF604E7A\": \"Imperial Palace\", \"#FF596458\": \"Imperial Palm\", \"#FF21303E\": \"Imperial Primer\", \"#FF5B3167\": \"Imperial Purple\", \"#FFEC2938\": \"Imperial Red\", \"#FFE4D68C\": \"Impetuous\", \"#FF1A2578\": \"Impression of Obscurity\", \"#FF8AA4AC\": \"Impressionist\", \"#FFA7CAC9\": \"Impressionist Blue\", \"#FFB9CEE0\": \"Impressionist Sky\", \"#FFF4DEC3\": \"Impressive Ivory\", \"#FF6E7376\": \"Improbable\", \"#FF705F63\": \"Impromptu\", \"#FF005B87\": \"Impulse\", \"#FF006699\": \"Impulse Blue\", \"#FF624977\": \"Impulsive Purple\", \"#FFF5E7E3\": \"Impure White\", \"#FF67AED0\": \"Imrik Blue\", \"#FFB98052\": \"In a Nutshell\", \"#FF978C59\": \"In a Pickle\", \"#FF693C2A\": \"In Caffeine We Trust\", \"#FFEE8877\": \"In for a Penny\", \"#FFD2C4A9\": \"In for the Night\", \"#FFB6D4A0\": \"In Good Taste\", \"#FF9EB0BB\": \"In the Blue\", \"#FFD6CBBF\": \"In the Buff\", \"#FF3B3C41\": \"In the Dark\", \"#FF91A8A8\": \"In the Deep End\", \"#FFAEA69B\": \"In the Hills\", \"#FF859893\": \"In the Moment\", \"#FF2178A4\": \"In the Mood\", \"#FF283849\": \"In the Navy\", \"#FF2B6DAA\": \"In the Nick\", \"#FFF4C4D0\": \"In the Pink\", \"#FFFF2233\": \"In the Red\", \"#FFCBC4C0\": \"In the Shadows\", \"#FF9AD9D4\": \"In the Shallows\", \"#FFE2C3CF\": \"In the Slip\", \"#FFEDE6ED\": \"In the Spotlight\", \"#FFA3BC3A\": \"In the Tropics\", \"#FF84838E\": \"In the Twilight\", \"#FF5C457B\": \"In the Vines\", \"#FF72786F\": \"In the Woods\", \"#FFF6DDDD\": \"In Your Dreams\", \"#FFAA6D28\": \"Inca Gold\", \"#FF8C7B6C\": \"Inca Temple\", \"#FFFFD301\": \"Inca Yellow\", \"#FFF9DDC4\": \"Incan Treasure\", \"#FFFFBB22\": \"Incandescence\", \"#FFAA0022\": \"Incarnadine\", \"#FFAF9A7E\": \"Incense\", \"#FF65644A\": \"Incense Cedar\", \"#FFFF0022\": \"Incision\", \"#FF8E8E82\": \"Incognito\", \"#FFE3DED7\": \"Incredible White\", \"#FF123456\": \"Incremental Blue\", \"#FFDA1D38\": \"Incubation Red\", \"#FF0B474A\": \"Incubi Darkness\", \"#FF772222\": \"Incubus\", \"#FFD2BA83\": \"Independent Gold\", \"#FF008A8E\": \"India Blue\", \"#FF3C3D4C\": \"India Ink\", \"#FFE0A362\": \"India Trade\", \"#FFA5823D\": \"Indian Brass\", \"#FFF2D0C0\": \"Indian Clay\", \"#FFF49476\": \"Indian Dance\", \"#FF54332E\": \"Indian Fig\", \"#FF91955F\": \"Indian Green\", \"#FF3C3F4A\": \"Indian Ink\", \"#FFD3B09C\": \"Indian Khaki Variant\", \"#FFCC1A97\": \"Indian Lake\", \"#FFE4C14D\": \"Indian Maize\", \"#FFD5A193\": \"Indian Mesa\", \"#FFEAE3D8\": \"Indian Muslin\", \"#FF86B7A1\": \"Indian Ocean\", \"#FFFA9761\": \"Indian Paintbrush\", \"#FFD5BC26\": \"Indian Pale Ale\", \"#FF0044AA\": \"Indian Peafowl\", \"#FFAD5B78\": \"Indian Pink\", \"#FFDA846D\": \"Indian Princess\", \"#FF850E04\": \"Indian Red\", \"#FF9F7060\": \"Indian Reed\", \"#FF8A5773\": \"Indian Silk\", \"#FFAE8845\": \"Indian Spice\", \"#FFA85143\": \"Indian Summer\", \"#FFD98A7D\": \"Indian Sunset\", \"#FF3C586B\": \"Indian Teal\", \"#FFEFDAC2\": \"Indian White\", \"#FFE88A5B\": \"Indiana Clay\", \"#FF588C3A\": \"Indica\", \"#FF2E2364\": \"Indie Go\", \"#FF9892B8\": \"Indifferent\", \"#FF301885\": \"Indiglow\", \"#FF4467A7\": \"Indigo Batik\", \"#FF002E51\": \"Indigo Black\", \"#FF8A83DA\": \"Indigo Bloom\", \"#FF3A18B1\": \"Indigo Blue\", \"#FF006CA9\": \"Indigo Bunting\", \"#FF006EC7\": \"Indigo Carmine\", \"#FFA09FCC\": \"Indigo Child\", \"#FF204C6C\": \"Indigo Cloth\", \"#FF627C98\": \"Indigo Dreams\", \"#FF00416C\": \"Indigo Dye Variant\", \"#FF4D0E88\": \"Indigo Girls\", \"#FF234156\": \"Indigo Go-Go\", \"#FF1F4788\": \"Indigo Hamlet\", \"#FF474A4D\": \"Indigo Ink\", \"#FF393432\": \"Indigo Ink Brown\", \"#FF393F4C\": \"Indigo Iron\", \"#FF5D76CB\": \"Indigo Light\", \"#FF6C848D\": \"Indigo Mouse\", \"#FF4C5E87\": \"Indigo Navy Blue\", \"#FF324680\": \"Indigo Night\", \"#FF695A78\": \"Indigo Red\", \"#FF1F0954\": \"Indigo Sloth\", \"#FF4B0183\": \"Indigo Static\", \"#FF2A465B\": \"Indigo Streamer\", \"#FFEBF6F7\": \"Indigo White\", \"#FFAC3B3B\": \"Indiscreet\", \"#FFD4CDCA\": \"Individual White\", \"#FF6611AA\": \"Indiviolet Sunset\", \"#FF9C5B34\": \"Indochine Variant\", \"#FFB96B00\": \"Indocile Tiger\", \"#FFA29DAD\": \"Indolence\", \"#FF008C69\": \"Indonesian Jungle\", \"#FFD1B272\": \"Indonesian Rattan\", \"#FF729E42\": \"Indubitably Green\", \"#FF533D47\": \"Indulgence\", \"#FF66565F\": \"Indulgent\", \"#FFD1C5B7\": \"Indulgent Mocha\", \"#FFAEADAD\": \"Industrial Age\", \"#FF322B26\": \"Industrial Black\", \"#FF00898C\": \"Industrial Blue\", \"#FF114400\": \"Industrial Green\", \"#FF5B5A57\": \"Industrial Grey\", \"#FF737373\": \"Industrial Revolution\", \"#FFE09887\": \"Industrial Rose\", \"#FF877A65\": \"Industrial Strength\", \"#FF008A70\": \"Industrial Turquoise\", \"#FF4F9153\": \"Ineffable Forest\", \"#FF63F7B4\": \"Ineffable Green\", \"#FFCAEDE4\": \"Ineffable Ice Cap\", \"#FFE6E1C7\": \"Ineffable Linen\", \"#FFCC99CC\": \"Ineffable Magenta\", \"#FF820E3B\": \"Inescapable Lover\", \"#FF777985\": \"Infamous\", \"#FFF0D5EA\": \"Infatuation\", \"#FFBB1177\": \"Infectious Love\", \"#FFDA5736\": \"Inferno\", \"#FFFF4400\": \"Inferno Orange\", \"#FF435A6F\": \"Infinite Deep Sea\", \"#FF2F1064\": \"Infinite Inkwell\", \"#FF071037\": \"Infinite Night\", \"#FFBDDDE1\": \"Infinitesimal Blue\", \"#FFD7E4CC\": \"Infinitesimal Green\", \"#FF222831\": \"Infinity\", \"#FF6E7E99\": \"Infinity and Beyond\", \"#FF94D4E4\": \"Infinity Pool\", \"#FFF1E7D0\": \"Informal Ivory\", \"#FFFE85AB\": \"Informative Pink\", \"#FFFFCCEE\": \"Infra-White\", \"#FFFE486C\": \"Infrared\", \"#FFDD3333\": \"Infrared Burn\", \"#FFCC3344\": \"Infrared Flush\", \"#FFCC3355\": \"Infrared Gloze\", \"#FFDD2244\": \"Infrared Tang\", \"#FFC8D0CA\": \"Infusion\", \"#FF334C5D\": \"Ing\\u00e9nue Blue\", \"#FFAAA380\": \"Inglenook Olive\", \"#FFD7AE77\": \"Inheritance\", \"#FF252024\": \"Ink Black\", \"#FF00608B\": \"Ink Blotch\", \"#FF0C5A77\": \"Ink Blue\", \"#FF393F4B\": \"Inkblot\", \"#FF3B5066\": \"Inked\", \"#FFD9DCE4\": \"Inked Silk\", \"#FF44556B\": \"Inkjet\", \"#FF31363A\": \"Inkwell\", \"#FF1E1E21\": \"Inkwell Inception\", \"#FF4E7287\": \"Inky Blue\", \"#FF535266\": \"Inky Storm\", \"#FF747B9F\": \"Inky Violet\", \"#FF606B54\": \"Inland\", \"#FF7C939D\": \"Inland Waters\", \"#FF3F586E\": \"Inlet Harbour\", \"#FFBBAA7E\": \"Inner Cervela\", \"#FFF1BDB2\": \"Inner Child\", \"#FF6D69A1\": \"Inner Journey\", \"#FF78A6B5\": \"Inner Sanctum\", \"#FF285B5F\": \"Inner Space\", \"#FFBBAFBA\": \"Inner Touch\", \"#FF959272\": \"Inness Sage\", \"#FF229900\": \"Innisfree Garden\", \"#FFEBD1CF\": \"Innocence\", \"#FF91B3D0\": \"Innocent Blue\", \"#FF856F79\": \"Innocent Pink\", \"#FFD0C7FF\": \"Innocent Snowdrop\", \"#FFA4B0C4\": \"Innuendo\", \"#FF114477\": \"Inoffensive Blue\", \"#FF221122\": \"Inside\", \"#FFE0CFB5\": \"Inside Passage\", \"#FFC9B0AB\": \"Insightful Rose\", \"#FF285294\": \"Insignia\", \"#FFECF3F9\": \"Insignia White\", \"#FF06012C\": \"Insomnia\", \"#FF110077\": \"Insomniac Blue\", \"#FF4FA183\": \"Inspiration Peak\", \"#FFDFD9E4\": \"Inspired Lilac\", \"#FFD9CEC7\": \"Instant\", \"#FFE3DAC6\": \"Instant Classic\", \"#FFF4D493\": \"Instant Noodles\", \"#FFFF8D28\": \"Instant Orange\", \"#FFEDE7D2\": \"Instant Relief\", \"#FFADA7C8\": \"Instigate\", \"#FF405E95\": \"Integra\", \"#FF233E57\": \"Integrity\", \"#FF3F414C\": \"Intellectual\", \"#FFA8A093\": \"Intellectual Grey\", \"#FF7F5400\": \"Intense Brown\", \"#FF123328\": \"Intense Green\", \"#FF68C89D\": \"Intense Jade\", \"#FF682D63\": \"Intense Mauve\", \"#FFDF3163\": \"Intense Passion\", \"#FF4D4A6F\": \"Intense Purple\", \"#FF00978C\": \"Intense Teal\", \"#FFE19C35\": \"Intense Yellow\", \"#FFE4CAAD\": \"Interactive Cream\", \"#FFA0CDDE\": \"Intercoastal\", \"#FFA8B5BC\": \"Intercoastal Grey\", \"#FF360CCC\": \"Interdimensional Blue\", \"#FFD6E6E6\": \"Interdimensional Portal\", \"#FF9BAFB2\": \"Interesting Aqua\", \"#FFC1A392\": \"Interface Tan\", \"#FF4D516C\": \"Intergalactic\", \"#FFAFE0EF\": \"Intergalactic Blue\", \"#FF222266\": \"Intergalactic Cowboy\", \"#FF273287\": \"Intergalactic Highway\", \"#FF573935\": \"Intergalactic Ray\", \"#FF5B1E8B\": \"Intergalactic Settlement\", \"#FF536437\": \"Interior Green\", \"#FF564355\": \"Interlude\", \"#FF56626E\": \"Intermediate Blue\", \"#FF137730\": \"Intermediate Green\", \"#FF019694\": \"Intermezzo\", \"#FF3762A5\": \"International\", \"#FF002FA6\": \"International Klein Blue Variant\", \"#FF001155\": \"Interstellar Blue\", \"#FFCCBB99\": \"Intimate Journal\", \"#FFF0E1D8\": \"Intimate White\", \"#FF4F7BA7\": \"Into the Blue\", \"#FF0D6C49\": \"Into the Green\", \"#FF1E3642\": \"Into the Night\", \"#FF425267\": \"Into the Stratosphere\", \"#FF999885\": \"Into the Wild\", \"#FF11BB55\": \"Intoxicate\", \"#FFA1AC4D\": \"Intoxication\", \"#FF77B5AA\": \"Intracoastal\", \"#FFE0E2E0\": \"Intrepid Grey\", \"#FFEDDDCA\": \"Intricate Ivory\", \"#FF635951\": \"Intrigue\", \"#FFB24648\": \"Intrigue Red\", \"#FF6D6053\": \"Introspective\", \"#FFCFC6BC\": \"Intuitive\", \"#FF55A0B7\": \"Inuit\", \"#FFD8E4E7\": \"Inuit Blue\", \"#FFC2BDC2\": \"Inuit Ice\", \"#FFD1CDD0\": \"Inuit White\", \"#FF49017E\": \"Invasive Indigo\", \"#FFE89D6F\": \"Inventive Orange\", \"#FF576238\": \"Inverness\", \"#FFDCE3E2\": \"Inverness Grey\", \"#FFE47237\": \"Invigorate\", \"#FFF1EAB4\": \"Invigorating\", \"#FFA6773F\": \"Invitation Gold\", \"#FFCDC29D\": \"Inviting Gesture\", \"#FFF2D5B0\": \"Inviting Ivory\", \"#FFB9C4BC\": \"Inviting Veranda\", \"#FF7D89BB\": \"Iolite\", \"#FF368976\": \"Ionian\", \"#FFE7DFC5\": \"Ionic Ivory\", \"#FFD0EDE9\": \"Ionic Sky\", \"#FF55DDFF\": \"Ionized-Air Glow\", \"#FF93CFE3\": \"Iqaluit Ice\", \"#FF006C2E\": \"Ireland Green\", \"#FF3A5B52\": \"Iridescent\", \"#FF0153C8\": \"Iridescent Blue\", \"#FF48C072\": \"Iridescent Green\", \"#FF00707D\": \"Iridescent Peacock\", \"#FF7BFDC7\": \"Iridescent Turquoise\", \"#FF3D3C3A\": \"Iridium\", \"#FF5A4FCF\": \"Iris\", \"#FF5B649E\": \"Iris Bloom\", \"#FFADA0BD\": \"Iris Blossom\", \"#FF767694\": \"Iris Eyes\", \"#FFE0E3EF\": \"Iris Ice\", \"#FFE8E5EC\": \"Iris Isle\", \"#FFB39B94\": \"Iris Mauve\", \"#FFA767A2\": \"Iris Orchid\", \"#FF6B6273\": \"Iris Petal\", \"#FFCAB9BE\": \"Iris Pink\", \"#FF398A59\": \"Irish\", \"#FF007F59\": \"Irish Beauty\", \"#FF69905B\": \"Irish Charm\", \"#FF53734C\": \"Irish Clover\", \"#FF62422B\": \"Irish Coffee Variant\", \"#FFE9DBBE\": \"Irish Cream\", \"#FFD3E3BF\": \"Irish Folklore\", \"#FF019529\": \"Irish Green\", \"#FF7CB386\": \"Irish Hedge\", \"#FF66CC11\": \"Irish Jig\", \"#FFEEE4E0\": \"Irish Linen\", \"#FFE7E5DB\": \"Irish Mist\", \"#FFB5C0B3\": \"Irish Moor\", \"#FF9CA691\": \"Irish Paddock\", \"#FF90CCA3\": \"Irish Spring\", \"#FFA38D86\": \"Irish Tea\", \"#FF9DACB5\": \"Irogon Blue\", \"#FF5E5E5E\": \"Iron Variant\", \"#FF114B91\": \"Iron Blue\", \"#FF50676B\": \"Iron Creek\", \"#FF8AA1A6\": \"Iron Earth\", \"#FFCBCDCD\": \"Iron Fist\", \"#FF5D5B5B\": \"Iron Fixture\", \"#FF6E3B31\": \"Iron Flint\", \"#FF475A5E\": \"Iron Forge\", \"#FF6F797E\": \"Iron Frost\", \"#FF585A60\": \"Iron Gate\", \"#FF7C7F7C\": \"Iron Grey\", \"#FF344D56\": \"Iron Head\", \"#FFD6D1DC\": \"Iron Maiden\", \"#FF757574\": \"Iron Mountain\", \"#FFE7661E\": \"Iron Orange\", \"#FFAF5B46\": \"Iron Ore\", \"#FF835949\": \"Iron Oxide\", \"#FF4D504B\": \"Iron River\", \"#FF114E56\": \"Iron Teal\", \"#FF6A6B67\": \"Iron-ic\", \"#FF887F85\": \"Ironbreaker\", \"#FFA1A6A9\": \"Ironbreaker Metal\", \"#FF615C55\": \"Ironclad\", \"#FF7E8082\": \"Ironside\", \"#FF706E66\": \"Ironside Grey\", \"#FF865040\": \"Ironstone Variant\", \"#FFA19583\": \"Ironwood\", \"#FFDADEE6\": \"Irradiant Iris\", \"#FFAAFF55\": \"Irradiated Green\", \"#FFE6DDC6\": \"Irresistible Beige\", \"#FF786C57\": \"Irrigation\", \"#FF9955FF\": \"Irrigo Purple\", \"#FFEE1122\": \"Irritated Ibis\", \"#FF0022FF\": \"Is It Cold\", \"#FF9BD8C4\": \"Isabella\\u2019s Aqua\", \"#FF484450\": \"Ishtar\", \"#FF009900\": \"Islamic Green Variant\", \"#FF8ADACF\": \"Island Breeze\", \"#FFD8877A\": \"Island Coral\", \"#FF139BA2\": \"Island Dream\", \"#FFDED9B4\": \"Island Embrace\", \"#FFFFB59A\": \"Island Girl\", \"#FF2BAE66\": \"Island Green\", \"#FFF6E3D6\": \"Island Hopping\", \"#FFA7C9EB\": \"Island Light\", \"#FF008292\": \"Island Lush\", \"#FF3FB2A8\": \"Island Moment\", \"#FF88D9D8\": \"Island Oasis\", \"#FFED681F\": \"Island Orange\", \"#FF6C7E71\": \"Island Palm\", \"#FF81D7D0\": \"Island Sea\", \"#FFF8EDDB\": \"Island Spice Variant\", \"#FFF2D66C\": \"Island Sun\", \"#FFC3DDEE\": \"Island View\", \"#FF0099C9\": \"Isle of Capri\", \"#FFBCCCB5\": \"Isle of Dreams\", \"#FF3E6655\": \"Isle of Pines\", \"#FFF9DD13\": \"Isle of Sand\", \"#FF80D7CF\": \"Isle Royale\", \"#FFFFB278\": \"Isn\\u2019t It Just Peachy\", \"#FF494D55\": \"Isolation\", \"#FFDDFF55\": \"Isotonic Water\", \"#FFCFDAC3\": \"Issey-San\", \"#FFAF8A5B\": \"It Works\", \"#FFFFDAE2\": \"It\\u2019s a Girl!\", \"#FFCC7365\": \"It\\u2019s My Party\", \"#FFBC989E\": \"It\\u2019s Your Mauve\", \"#FF5F6957\": \"Italian Basil\", \"#FF6B8C23\": \"Italian Buckthorn\", \"#FFD79979\": \"Italian Clay\", \"#FFD0C8E6\": \"Italian Fitch\", \"#FF413D4B\": \"Italian Grape\", \"#FFE2E0D3\": \"Italian Ice\", \"#FFEDE9D4\": \"Italian Lace\", \"#FF93685A\": \"Italian Mocha\", \"#FF807243\": \"Italian Olive\", \"#FF59354A\": \"Italian Plum\", \"#FFB1403A\": \"Italian Red\", \"#FF221111\": \"Italian Roast\", \"#FFB2FCFF\": \"Italian Sky Blue\", \"#FFE7D3A1\": \"Italian Straw\", \"#FFAD5D5D\": \"Italian Villa\", \"#FFD16169\": \"Italiano Rose\", \"#FFCCE5E8\": \"Ivalo River\", \"#FFE4CEAC\": \"Ivoire\", \"#FFC4B8A9\": \"Ivory Brown\", \"#FFEBD999\": \"Ivory Buff\", \"#FFFFF6DA\": \"Ivory Charm\", \"#FFFAF5DE\": \"Ivory Coast\", \"#FFD5B89C\": \"Ivory Cream\", \"#FFE7D8BC\": \"Ivory Essence\", \"#FFFCEFD6\": \"Ivory Invitation\", \"#FFF8F7E6\": \"Ivory Keys\", \"#FFECE2CC\": \"Ivory Lace\", \"#FFE6E6D8\": \"Ivory Lashes\", \"#FFE6DDCD\": \"Ivory Memories\", \"#FFEFEADE\": \"Ivory Mist\", \"#FFF9E4C1\": \"Ivory Oats\", \"#FFEEEADC\": \"Ivory Palace\", \"#FFE6DECA\": \"Ivory Paper\", \"#FFEFE3CA\": \"Ivory Parchment\", \"#FFD9C9B8\": \"Ivory Ridge\", \"#FFF0EADA\": \"Ivory Steam\", \"#FFEEE1CC\": \"Ivory Stone\", \"#FFF8EAD8\": \"Ivory Tassel\", \"#FFFBF3F1\": \"Ivory Tower\", \"#FFEDEDE4\": \"Ivory Wedding\", \"#FF277B74\": \"Ivy\", \"#FF93A272\": \"Ivy Enchantment\", \"#FF818068\": \"Ivy Garden\", \"#FF585442\": \"Ivy Green\", \"#FF007958\": \"Ivy League\", \"#FF67614F\": \"Ivy Topiary\", \"#FF708D76\": \"Ivy Wreath\", \"#FF6B6F59\": \"Iwai Brown\", \"#FF5E5545\": \"Iwaicha Brown\", \"#FFA59A59\": \"Iyanden Darksun\", \"#FFCEB0B5\": \"Izmir Pink\", \"#FF4D426E\": \"Izmir Purple\", \"#FFA06856\": \"J\\u2019s Big Heart\", \"#FFAD6D68\": \"Jab\\u0142o\\u0144ski Brown\", \"#FF536871\": \"Jab\\u0142o\\u0144ski Grey\", \"#FFF9D7EE\": \"Jacaranda Variant\", \"#FF6C70A9\": \"Jacaranda Jazz\", \"#FFA8ACB7\": \"Jacaranda Light\", \"#FFC760FF\": \"Jacaranda Pink\", \"#FF440044\": \"Jacarta Variant\", \"#FFBCACCD\": \"Jacey\\u2019s Favourite\", \"#FF920F0E\": \"Jack and Coke\", \"#FF869F69\": \"Jack Bone\", \"#FFDAE6E3\": \"Jack Frost\", \"#FFC0B2B1\": \"Jack Rabbit\", \"#FFD37A51\": \"Jack-O-Lantern\", \"#FFA9A093\": \"Jackal\", \"#FFF7C680\": \"Jackfruit\", \"#FF413628\": \"Jacko Bean Variant\", \"#FFD19431\": \"Jackpot\", \"#FFC3BDA9\": \"Jackson Antique\", \"#FF3D3F7D\": \"Jacksons Purple Variant\", \"#FFD6B281\": \"Jacob\\u2019s Ladder\", \"#FFE4CCB0\": \"Jacobean Lace\", \"#FF5D4E50\": \"Jacqueline\", \"#FF007CAC\": \"Jacuzzi\", \"#FFC2D7AD\": \"Jade Bracelet\", \"#FFB0BDA2\": \"Jade Cameo\", \"#FF59B587\": \"Jade Cream\", \"#FF6AA193\": \"Jade Dragon\", \"#FFCEDDDA\": \"Jade Dust\", \"#FF779977\": \"Jade Green\", \"#FF247E81\": \"Jade Jewel\", \"#FFC1CAB7\": \"Jade Light Green\", \"#FF9DCA7B\": \"Jade Lime\", \"#FFD6E9D7\": \"Jade Mist\", \"#FF34C2A7\": \"Jade Mountain\", \"#FF166A45\": \"Jade Mussel Green\", \"#FF318F33\": \"Jade of Emeralds\", \"#FF00AAAA\": \"Jade Orchid\", \"#FFD0EED7\": \"Jade Palace\", \"#FF2BAF6A\": \"Jade Powder\", \"#FFB8E0D0\": \"Jade Sea\", \"#FF017B92\": \"Jade Shard\", \"#FFC1E5D5\": \"Jade Spell\", \"#FF74BB83\": \"Jade Stone Green\", \"#FFBBCCBC\": \"Jade Tinge\", \"#FF0092A1\": \"Jaded\", \"#FFAEDDD3\": \"Jaded Clouds\", \"#FFCC7766\": \"Jaded Ginger\", \"#FFBBD3AD\": \"Jaded Lime\", \"#FF38C6A1\": \"Jadeite\", \"#FF77A276\": \"Jadesheen\", \"#FF01A6A0\": \"Jadestone\", \"#FF61826C\": \"Jadite\", \"#FFE27945\": \"Jaffa Variant\", \"#FFD87839\": \"Jaffa Orange\", \"#FFFFCCCB\": \"Jagdwurst\", \"#FFCAE7E2\": \"Jagged Ice Variant\", \"#FF3F2E4C\": \"Jagger Variant\", \"#FF29292F\": \"Jaguar Variant\", \"#FFF1B3B6\": \"Jaguar Rose\", \"#FFA43323\": \"Jaipur\", \"#FFEFDDC3\": \"Jakarta\", \"#FF3D325D\": \"Jakarta Skyline\", \"#FF9A8D3F\": \"Jalape\\u00f1o\", \"#FF576648\": \"Jalape\\u00f1o Bouquet\", \"#FFB5AD70\": \"Jalape\\u00f1o Jelly\", \"#FFAC335E\": \"Jam Jar\", \"#FFD4CFD6\": \"Jam Session\", \"#FF95CBC4\": \"Jamaica Bay\", \"#FF04627A\": \"Jamaican Dream\", \"#FF64D1BE\": \"Jamaican Jade\", \"#FF26A5BA\": \"Jamaican Sea\", \"#FFF7B572\": \"Jambalaya Variant\", \"#FFF2E3B5\": \"James Blonde\", \"#FFE3C2FF\": \"Jane Purple\", \"#FFFF2211\": \"Janemba Red\", \"#FFCEB5C8\": \"Janey\\u2019s Party\", \"#FF2266CC\": \"Janitor\", \"#FF00A1B9\": \"January Blue\", \"#FFDFE2E5\": \"January Dawn\", \"#FF99C1DC\": \"January Frost\", \"#FF7B4141\": \"January Garnet\", \"#FFDDD6F3\": \"Japan Blush\", \"#FF829F96\": \"Japanese Bonsai\", \"#FF9F2832\": \"Japanese Carmine\", \"#FFC47A88\": \"Japanese Coral\", \"#FF965036\": \"Japanese Cypress\", \"#FFB5B94C\": \"Japanese Fern\", \"#FFA8BF93\": \"Japanese Horseradish\", \"#FF264348\": \"Japanese Indigo\", \"#FF7F5D3B\": \"Japanese Iris\", \"#FFCC6358\": \"Japanese Kimono\", \"#FFDB7842\": \"Japanese Koi\", \"#FF2F7532\": \"Japanese Laurel Variant\", \"#FFC4BAB7\": \"Japanese Poet\", \"#FFE4B6C4\": \"Japanese Rose Garden\", \"#FF313739\": \"Japanese Sable\", \"#FF53594B\": \"Japanese Seaweed\", \"#FFB77B57\": \"Japanese Wax Tree\", \"#FFEEE6D9\": \"Japanese White\", \"#FF522C35\": \"Japanese Wineberry\", \"#FFD8A373\": \"Japanese Yew\", \"#FFCE7259\": \"Japonica Variant\", \"#FFBDD0AB\": \"Jardin\", \"#FFC6CAA7\": \"Jardin de Hierbas\", \"#FF019A74\": \"Jardini\\u00e8re\", \"#FF53A38F\": \"Jargon Jade\", \"#FF827058\": \"Jarrah\", \"#FFFFF4BB\": \"Jasmine Variant\", \"#FFF4E8E1\": \"Jasmine Flower\", \"#FF79C63D\": \"Jasmine Green\", \"#FF7E7468\": \"Jasmine Hollow\", \"#FFDEE2D9\": \"Jasmine Rice\", \"#FFE7C89F\": \"Jasper Cane\", \"#FF57605A\": \"Jasper Green\", \"#FFDE8F4E\": \"Jasper Orange\", \"#FF4A6558\": \"Jasper Park\", \"#FFFA2B00\": \"Jasper Red\", \"#FF8D9E97\": \"Jasper Stone\", \"#FF8DC36A\": \"Jaunty Green\", \"#FF259797\": \"Java Variant\", \"#FF50859E\": \"Jay Bird\", \"#FF7994B5\": \"Jay Wing Feathers\", \"#FF464152\": \"Jazlyn\", \"#FF5F2C2F\": \"Jazz\", \"#FF3B4A6C\": \"Jazz Age Blues\", \"#FFF1BFB1\": \"Jazz Age Coral\", \"#FF1A6A9F\": \"Jazz Blue\", \"#FFD48740\": \"Jazz Brass\", \"#FF9892A8\": \"Jazz Tune\", \"#FF674247\": \"Jazzberry Jam Variant\", \"#FFB6E12A\": \"Jazzercise\", \"#FFC31E4E\": \"Jazzy\", \"#FF3A4C88\": \"Jazzy Blue\", \"#FF55DDCC\": \"Jazzy Jade\", \"#FF771C2B\": \"Jazzy Red\", \"#FFB36B92\": \"Je t\\u2019aime\", \"#FFBB0099\": \"Jealous Jellyfish\", \"#FF7FAB60\": \"Jealousy\", \"#FF7B90A2\": \"Jean Jacket Blue\", \"#FF6D8994\": \"Jeans Indigo\", \"#FF041108\": \"Jedi Night\", \"#FFF1E4C8\": \"Jefferson Cream\", \"#FF44798E\": \"Jelly Bean Variant\", \"#FFEE1177\": \"Jelly Berry\", \"#FFDE6646\": \"Jelly Slug\", \"#FFEDE6D9\": \"Jelly Yoghurt\", \"#FF9B6575\": \"Jellybean Pink\", \"#FF95CAD0\": \"Jellyfish Blue\", \"#FFEE6688\": \"Jellyfish Sting\", \"#FFF6D67F\": \"Jemima\", \"#FFDFB886\": \"Jerboa\", \"#FF4D8681\": \"Jericho Jade\", \"#FFF5DEBB\": \"Jersey Cream\", \"#FF25B387\": \"Jess\", \"#FF216879\": \"Jester Blue\", \"#FFAC112C\": \"Jester Red\", \"#FF353337\": \"Jet Black\", \"#FFD1EAEC\": \"Jet d\\u2019Eau\", \"#FF575654\": \"Jet Fuel\", \"#FF9D9A9A\": \"Jet Grey\", \"#FF2F3734\": \"Jet Set\", \"#FF5492AF\": \"Jet Ski\", \"#FFBBD0C9\": \"Jet Stream Variant\", \"#FFF2EDE2\": \"Jet White\", \"#FF005D96\": \"Jetski Race\", \"#FFA6D40D\": \"Jeune Citron\", \"#FF136843\": \"Jewel Variant\", \"#FF8CC90B\": \"Jewel Beetle\", \"#FFD374D5\": \"Jewel Caterpillar\", \"#FF3C4173\": \"Jewel Cave\", \"#FF46A795\": \"Jewel Weed\", \"#FFCFEEE1\": \"Jewel White\", \"#FFCED6E6\": \"Jewellery White\", \"#FFE6DDCA\": \"Jewett White\", \"#FFFFAAFF\": \"Jigglypuff\", \"#FF3D5D64\": \"Jimbaran Bay\", \"#FFF5D565\": \"J\\u012bn Hu\\u00e1ng Gold\", \"#FFA5A502\": \"J\\u012bn S\\u00e8 Gold\", \"#FF8E7618\": \"J\\u012bn Z\\u014dng Gold\", \"#FFEE827C\": \"Jinza Safflower\", \"#FFF7665A\": \"Jinzamomi Pink\", \"#FFBAC08A\": \"Jitterbug\", \"#FF019D6E\": \"Jitterbug Jade\", \"#FF8DB0AD\": \"Jitterbug Lure\", \"#FF77EEBB\": \"Jittery Jade\", \"#FF005B7A\": \"Job\\u2019s Tears\", \"#FF77CC99\": \"Jocose Jade\", \"#FFCCE2CA\": \"Jocular Green\", \"#FF9BD7E9\": \"Jodhpur Blue\", \"#FFDAD1C8\": \"Jodhpur Tan\", \"#FFEBDCB6\": \"Jodhpurs\", \"#FF433F39\": \"Joesmithite\", \"#FFC0B9A9\": \"Jogging Path\", \"#FFEEFF22\": \"John Lemon\", \"#FFBC86AF\": \"Joie de Vivre\", \"#FFD9BD7D\": \"Jojoba\", \"#FFEA5505\": \"Jokaero Orange\", \"#FFD70141\": \"Joker\\u2019s Smile\", \"#FFB2C1C2\": \"Jolene\", \"#FF5E774A\": \"Jolly Green\", \"#FF77CCBB\": \"Jolly Jade\", \"#FF82C785\": \"Jolt of Green\", \"#FF4ABCA0\": \"Jolt of Jade\", \"#FFEEF293\": \"Jonquil Tint\", \"#FFF7D395\": \"Jonquil Trail\", \"#FF037A3B\": \"Jordan Jazz\", \"#FF7AAAE0\": \"Jordy Blue Variant\", \"#FFD3C3BE\": \"Josephine\", \"#FF7FB377\": \"Joshua Tree\", \"#FFE6D3B2\": \"Journal White\", \"#FF016584\": \"Journey Into Night\", \"#FFCDECED\": \"Journey\", \"#FFBAC9D4\": \"Journey\\u2019s End\", \"#FF55AAFF\": \"Joust Blue\", \"#FFEEB9A7\": \"Jovial\", \"#FF88DDAA\": \"Jovial Jade\", \"#FFF6EEC0\": \"Joyful\", \"#FFE4D4E2\": \"Joyful Lilac\", \"#FFFA9335\": \"Joyful Orange\", \"#FFEBADA5\": \"Joyful Poppy\", \"#FF503136\": \"Joyful Ruby\", \"#FF006669\": \"Joyful Tears\", \"#FFFFEEB0\": \"Joyous\", \"#FFAE2719\": \"Joyous Red\", \"#FF5B365E\": \"Joyous Song\", \"#FFF9900F\": \"J\\u00fa Hu\\u00e1ng Tangerine\", \"#FF4B373C\": \"Jube\", \"#FF78CF86\": \"Jube Green\", \"#FF44AA77\": \"Jubilant Jade\", \"#FF7BB92B\": \"Jubilant Meadow\", \"#FFFBDD24\": \"Jubilation\", \"#FF7E6099\": \"Jubilee\", \"#FF7C7379\": \"Jubilee Grey\", \"#FF473739\": \"Judah Silk\", \"#FF5D5346\": \"Judge Grey\", \"#FFC3C8B3\": \"Jugendstil Green\", \"#FF9D6375\": \"Jugendstil Pink\", \"#FF5F9B9C\": \"Jugendstil Turquoise\", \"#FF255367\": \"Juggernaut\", \"#FF442238\": \"Juice Violet\", \"#FFD9787C\": \"Juicy Details\", \"#FF7D6C4A\": \"Juicy Fig\", \"#FFEEDD33\": \"Juicy Jackfruit\", \"#FFB1CF5D\": \"Juicy Lime\", \"#FFFFD08D\": \"Juicy Mango\", \"#FFF18870\": \"Juicy Passionfruit\", \"#FFD99290\": \"Juicy Peach\", \"#FF57AA80\": \"Julep\", \"#FFC7DBD9\": \"Julep Green\", \"#FFA73940\": \"Jules\", \"#FFA5BEC8\": \"Juliet Blue\", \"#FF8BD2E3\": \"July\", \"#FF773B4A\": \"July Ruby\", \"#FF878785\": \"Jumbo Variant\", \"#FF887636\": \"Jumping Juniper\", \"#FF9BC4D4\": \"June\", \"#FF264A48\": \"June Bug\", \"#FFFFE182\": \"June Day\", \"#FF416858\": \"June Ivy\", \"#FFF1F1DA\": \"June Vision\", \"#FF775496\": \"Juneberry\", \"#FF00A466\": \"Jungle\", \"#FF446D46\": \"Jungle Adventure\", \"#FF654F2D\": \"Jungle Beat\", \"#FF366C4E\": \"Jungle Book Green\", \"#FF53665A\": \"Jungle Camouflage\", \"#FF69673A\": \"Jungle Civilization\", \"#FF686959\": \"Jungle Cloak\", \"#FF565042\": \"Jungle Cover\", \"#FFB49356\": \"Jungle Expedition\", \"#FF048243\": \"Jungle Green Variant\", \"#FF115511\": \"Jungle Jam\", \"#FF58A64B\": \"Jungle Jewels\", \"#FFA4C161\": \"Jungle Juice\", \"#FFC7BEA7\": \"Jungle Khaki\", \"#FF4F4D32\": \"Jungle King\", \"#FF727736\": \"Jungle Look\", \"#FFB0C4C4\": \"Jungle Mist Variant\", \"#FFBDC3AC\": \"Jungle Moss\", \"#FF36716F\": \"Jungle Noises\", \"#FF938326\": \"Jungle Palm\", \"#FF6D6F42\": \"Jungle Trail\", \"#FF65801D\": \"Jungle Vibes\", \"#FF74918E\": \"Juniper Variant\", \"#FF798884\": \"Juniper Ash\", \"#FF547174\": \"Juniper Berries\", \"#FFB9B3C2\": \"Juniper Berry\", \"#FF3F626E\": \"Juniper Berry Blue\", \"#FFD9E0D8\": \"Juniper Breeze\", \"#FF567F69\": \"Juniper Green\", \"#FFC4D3C5\": \"Juniper Mist\", \"#FF6B8B75\": \"Juniper Oil\", \"#FFFBECD3\": \"Junket\", \"#FF998778\": \"Junkrat\", \"#FFE1E1E2\": \"Jupiter\", \"#FFAC8181\": \"Jupiter Brown\", \"#FFE6A351\": \"Jurassic Gold\", \"#FF0D601C\": \"Jurassic Moss\", \"#FF3C663E\": \"Jurassic Park\", \"#FF6C5D97\": \"Just a Fairytale\", \"#FFDBE0D6\": \"Just a Little\", \"#FFFBD6D2\": \"Just a Tease\", \"#FFE2E7D3\": \"Just About Green\", \"#FFE8E8E0\": \"Just About White\", \"#FFFAB4A4\": \"Just Blush\", \"#FFFFBA45\": \"Just Ducky\", \"#FFD6C4C1\": \"Just Gorgeous\", \"#FFF8C275\": \"Just Peachy\", \"#FFEAECD3\": \"Just Perfect\", \"#FFFFEBEE\": \"Just Pink Enough\", \"#FFDCBFAC\": \"Just Right Variant\", \"#FFC4A295\": \"Just Rosey\", \"#FF606B8E\": \"Justice\", \"#FFAD9773\": \"Jute\", \"#FF815D40\": \"Jute Brown\", \"#FF8ABBD0\": \"Juvie\", \"#FFA1D5F1\": \"Juzcar Blue\", \"#FF736354\": \"K\\u0101 F\\u0113i S\\u00e8 Brown\", \"#FFB14A30\": \"Kabacha Brown\", \"#FF038C67\": \"Kabalite Green\", \"#FF044A05\": \"Kabocha Green\", \"#FFA73A3E\": \"Kabuki\", \"#FFF0DEC1\": \"Kabuki Clay\", \"#FF6C5E53\": \"Kabul Variant\", \"#FFE94B7E\": \"Kacey\\u2019s Pink\", \"#FF393E4F\": \"Kachi Indigo\", \"#FF816D5A\": \"Kaffee\", \"#FFB7BFB0\": \"Kahili\", \"#FFBAB099\": \"Kahlua Milk\", \"#FF0093D6\": \"Kahu Blue\", \"#FFEED484\": \"Kaiser Cheese\", \"#FF245336\": \"Kaitoke Green Variant\", \"#FF7D806E\": \"Kakadu Trail\", \"#FF298256\": \"K\\u0101k\\u0101riki Green\", \"#FF3E62AD\": \"Kakitsubata Blue\", \"#FF201819\": \"K\\u0101l\\u0101 Black\", \"#FF46444C\": \"Kala Namak\", \"#FF9F5440\": \"Kalahari Sunset\", \"#FF6A6555\": \"Kalamata\", \"#FF648251\": \"Kale\", \"#FF4F6A56\": \"Kale Green\", \"#FF8DA8BE\": \"Kaleidoscope\", \"#FF00505A\": \"Kali Blue\", \"#FF552288\": \"Kalish Violet\", \"#FFB59808\": \"Kalliene Yellow\", \"#FF0FFEF9\": \"Kaltes Klares Wasser\", \"#FFC6C2B6\": \"Kamenozoki Grey\", \"#FFCCA483\": \"Kamut\", \"#FFDD8833\": \"Kanafeh\", \"#FF2D8284\": \"Kandinsky Turquoise\", \"#FFC5C3B0\": \"Kangaroo Variant\", \"#FFC4AD92\": \"Kangaroo Fur\", \"#FFDECAC5\": \"Kangaroo Paw\", \"#FFBDA289\": \"Kangaroo Pouch\", \"#FFE4D7CE\": \"Kangaroo Tan\", \"#FFFEE7CB\": \"Kansas Grain\", \"#FF001146\": \"Kantor Blue\", \"#FFFF8936\": \"Kanz\\u014d Orange\", \"#FFAD7D40\": \"Kaolin\", \"#FFC5DED1\": \"Kappa Green\", \"#FF783C1D\": \"Kara Cha Brown\", \"#FFB35C44\": \"Karacha Red\", \"#FFBB9662\": \"Karak Stone\", \"#FF2D2D24\": \"Karaka Variant\", \"#FFF04925\": \"Karaka Orange\", \"#FFC91F37\": \"Karakurenai Red\", \"#FF2196F3\": \"Karimun Blue\", \"#FF6E7955\": \"Kariyasu Green\", \"#FFB2A484\": \"Karma\", \"#FF9F78A9\": \"Karma Chameleon\", \"#FF545F8A\": \"Karmic Grape\", \"#FFFEDCC1\": \"Karry Variant\", \"#FF6F8D6A\": \"Kashmir\", \"#FF576D8E\": \"Kashmir Blue Variant\", \"#FFE9C8C3\": \"Kashmir Pink\", \"#FFF3DFD5\": \"Kasugai Peach\", \"#FF8FA099\": \"Kathleen\\u2019s Garden\", \"#FFAD9A5D\": \"Kathmandu\", \"#FFC9E3CC\": \"Katsura\", \"#FFAA0077\": \"Katy Berry\", \"#FF66BC91\": \"Katydid\", \"#FF5AC7AC\": \"Kauai\", \"#FFEAABBC\": \"Kawaii\", \"#FFFEC50C\": \"Kazakhstan Yellow\", \"#FFD49595\": \"Keel Joy\", \"#FFA49463\": \"Keemun\", \"#FF226600\": \"Keen Green\", \"#FFC0CED6\": \"Keepsake\", \"#FFB899A2\": \"Keepsake Lilac\", \"#FFB08693\": \"Keepsake Rose\", \"#FF0000BC\": \"Keese Blue\", \"#FFD5D5CE\": \"Kefir\", \"#FF02AB2E\": \"Kelley Green\", \"#FFDEC7CF\": \"Kellie Belle\", \"#FF339C5E\": \"Kelly Green Variant\", \"#FFBABD6C\": \"Kelly\\u2019s Flower\", \"#FF4D503C\": \"Kelp Variant\", \"#FF716246\": \"Kelp Brown\", \"#FF448811\": \"Kelp Forest\", \"#FF0092AE\": \"Kelp\\u2019thar Forest Blue\", \"#FF437B48\": \"Kemp Kelly\", \"#FFEC2C25\": \"Ken Masters Red\", \"#FF547867\": \"Kendal Green\", \"#FFF7CCCD\": \"Kendall Rose\", \"#FFD45871\": \"Kenny\\u2019s Kiss\", \"#FF543F32\": \"Kenp\\u014d Brown\", \"#FF2E211B\": \"Kenp\\u014dzome Black\", \"#FF6395BF\": \"Kentucky\", \"#FFA5B3CC\": \"Kentucky Blue\", \"#FF22AABB\": \"Kentucky Bluegrass\", \"#FFCCA179\": \"Kenya\", \"#FF6C322E\": \"Kenyan Copper Variant\", \"#FFBB8800\": \"Kenyan Sand\", \"#FF5FB69C\": \"Keppel Variant\", \"#FF5CB200\": \"Kermit Green\", \"#FFECB976\": \"Kernel\", \"#FFFFB210\": \"Kernel of Truth\", \"#FF524E4D\": \"Keshizumi Cinder\", \"#FFE0D6C8\": \"Kestrel White\", \"#FF9A382D\": \"Ketchup\", \"#FFA91C1C\": \"Ketchup Later\", \"#FF141314\": \"Kettle Black\", \"#FFF6E2BD\": \"Kettle Corn\", \"#FF9BCB96\": \"Kettle Drum\", \"#FF606061\": \"Kettleman\", \"#FFECD1A5\": \"Key Keeper\", \"#FF7FB6A4\": \"Key Largo\", \"#FFAEFF6E\": \"Key Lime\", \"#FFBB9B7C\": \"Key\", \"#FF759FC1\": \"Key West Zenith\", \"#FFD5AF91\": \"Key Wester\", \"#FFB39372\": \"Keystone\", \"#FFB6BBB2\": \"Keystone Grey\", \"#FF9E9284\": \"Keystone Taupe\", \"#FF954E2A\": \"Khaki Brown\", \"#FFFBE4AF\": \"Khaki Core\", \"#FF728639\": \"Khaki Green\", \"#FFD4C5AC\": \"Khaki Shade\", \"#FFC9BEAA\": \"Khaki Shell\", \"#FFB16840\": \"Khardic\", \"#FF76664C\": \"Khemri Brown\", \"#FFEE5555\": \"Khmer Curry\", \"#FF6A0001\": \"Khorne Red\", \"#FF7777CC\": \"Kickstart Purple\", \"#FFB6AEAE\": \"Kid Gloves\", \"#FFA81000\": \"Kid Icarus\", \"#FFED8732\": \"Kid\\u2019s Stuff\", \"#FFBFC0AB\": \"Kidnapper Variant\", \"#FFFEF263\": \"Kihada Yellow\", \"#FF2E4EBF\": \"Kikorangi Blue\", \"#FFE29C45\": \"Kikuchiba Gold\", \"#FF5D3F6A\": \"Kiky\\u014d Purple\", \"#FF843D38\": \"Kilauea Lava\", \"#FFD7C5AE\": \"Kilim Beige\", \"#FF3A3532\": \"Kilimanjaro Variant\", \"#FF498555\": \"Kilkenny\", \"#FF49764F\": \"Killarney Variant\", \"#FFC9D2D1\": \"Killer Fog\", \"#FFC6BEA9\": \"Kiln Clay\", \"#FFA89887\": \"Kiln Dried\", \"#FF386B7D\": \"Kimberley Sea\", \"#FF696FA5\": \"Kimberlite\", \"#FF695D87\": \"Kimberly Variant\", \"#FFED4B00\": \"Kimchi\", \"#FF896C39\": \"Kimirucha Brown\", \"#FF6D86B6\": \"Kimono\", \"#FF3D4C51\": \"Kimono Grey\", \"#FF75769B\": \"Kimono Violet\", \"#FFF39800\": \"Kin Gold\", \"#FFC66B27\": \"Kincha Brown\", \"#FFAAC2B3\": \"Kind Green\", \"#FFB8BFCA\": \"Kinder\", \"#FFA09174\": \"Kinderhook Clay\", \"#FF7A7068\": \"Kindling\", \"#FFD4B2C0\": \"Kindness\", \"#FF71A2D4\": \"Kindred\", \"#FF254D6A\": \"Kinetic Blue\", \"#FF64CDBE\": \"Kinetic Teal\", \"#FF5F686F\": \"King Creek Falls\", \"#FFC64A4A\": \"King Crimson\", \"#FF757166\": \"King Fischer\", \"#FFAA9977\": \"King Ghidorah\", \"#FF161410\": \"King Kong\", \"#FFADD900\": \"King Lime\", \"#FF77DD22\": \"King Lizard\", \"#FFFFB800\": \"King Nacho\", \"#FF7794C0\": \"King Neptune\", \"#FFC6DCE7\": \"King of Waves\", \"#FFD88668\": \"King Salmon\", \"#FF86B394\": \"King Theo\", \"#FF2A7279\": \"King Tide\", \"#FF3C85BE\": \"King Triton\", \"#FFC48692\": \"King\\u2019s Cloak\", \"#FF706D5E\": \"King\\u2019s Court\", \"#FFF2E887\": \"King\\u2019s Field\", \"#FFB3107A\": \"King\\u2019s Plum Pie\", \"#FFB59D77\": \"King\\u2019s Ransom\", \"#FF6274AB\": \"King\\u2019s Robe\", \"#FFD1A436\": \"Kingdom Gold\", \"#FFE9CFB7\": \"Kingdom\\u2019s Keys\", \"#FF3A5760\": \"Kingfisher\", \"#FF006491\": \"Kingfisher Blue\", \"#FF096872\": \"Kingfisher Bright\", \"#FF583580\": \"Kingfisher Daisy Variant\", \"#FF7E969F\": \"Kingfisher Grey\", \"#FF007FA2\": \"Kingfisher Sheen\", \"#FF7AB6B6\": \"Kingfisher Turquoise\", \"#FFDEDEDE\": \"Kingly Cloud\", \"#FFDE9930\": \"Kingpin Gold\", \"#FF2D8297\": \"Kings of Sea\", \"#FFEAD665\": \"Kings Yellow\", \"#FFD4DCD3\": \"Kingston\", \"#FF8FBCC4\": \"Kingston Aqua\", \"#FFBB00BB\": \"Kinky Koala\", \"#FFEE55CC\": \"Kinky Pinky\", \"#FF7F7793\": \"Kinlock\", \"#FF7D4E2D\": \"Kinsusutake Brown\", \"#FFB45877\": \"Kir Royale Rose\", \"#FF5C6116\": \"Kirchner Green\", \"#FFC5C5D3\": \"Kiri Mist\", \"#FF8B352D\": \"Kiriume Red\", \"#FFB2132B\": \"Kirsch\", \"#FF974953\": \"Kirsch Red\", \"#FFEFCDCB\": \"Kislev Pink\", \"#FFA18AB7\": \"Kismet\", \"#FFD28CA7\": \"Kiss\", \"#FFBEC187\": \"Kiss a Frog\", \"#FFD86773\": \"Kiss and Tell\", \"#FFAA854A\": \"Kiss Candy\", \"#FFE5C8D9\": \"Kiss Good Night\", \"#FFE7EEEC\": \"Kiss Me Kate\", \"#FFDE6B86\": \"Kiss Me More\", \"#FF8A0009\": \"Kiss of a Vampire\", \"#FFEAE2AC\": \"Kiss of Lime\", \"#FFBDCFB2\": \"Kiss of Mint\", \"#FFDC331A\": \"Kiss of the Scorpion\", \"#FFFD8F79\": \"Kissable\", \"#FFB15363\": \"Kissed by a Zombies\", \"#FFFCCCF5\": \"Kissed by Mist\", \"#FFFF66BB\": \"Kisses\", \"#FFFF6677\": \"Kisses and Hugs\", \"#FF8AB5BD\": \"Kitchen Blue\", \"#FFC0816E\": \"Kitchen Terra Cotta\", \"#FF95483F\": \"Kite Brown\", \"#FFD0C8B0\": \"Kitsilano Cookie\", \"#FFBB8141\": \"Kitsurubami Brown\", \"#FFD3C7BC\": \"Kitten\", \"#FF8AADF7\": \"Kitten\\u2019s Eye\", \"#FFDAA89B\": \"Kitten\\u2019s Paw\", \"#FFCCCCBB\": \"Kittiwake Gull\", \"#FFC7BDB3\": \"Kitty Kitty\", \"#FFB7B5B1\": \"Kitty Whiskers\", \"#FF749E4E\": \"Kiwi\", \"#FF7BC027\": \"Kiwi Crush\", \"#FF8EE53F\": \"Kiwi Green\", \"#FFE5E7A7\": \"Kiwi Ice Cream\", \"#FFEEF9C1\": \"Kiwi Kiss\", \"#FF9CEF43\": \"Kiwi Pulp\", \"#FFDEE8BE\": \"Kiwi Sorbet\", \"#FFD1EDCD\": \"Kiwi Squeeze\", \"#FF909495\": \"Kiwikiwi Grey\", \"#FF2987C7\": \"Klaxosaur Blue\", \"#FF3FA282\": \"Klimt Green\", \"#FF95896C\": \"Knapsack\", \"#FF4B5B40\": \"Knarloc Green\", \"#FF926CAC\": \"Knight Elf\", \"#FF0F0707\": \"Knight Rider\", \"#FF5C5D5D\": \"Knight\\u2019s Armour\", \"#FFAA91AE\": \"Knight\\u2019s Tale\", \"#FF3C3F52\": \"Knighthood\", \"#FFEDCC99\": \"Knightley Straw\", \"#FF403C39\": \"Knights of the Desert\", \"#FFC2CCC7\": \"Knightsbridge Mist\", \"#FF6D6C5F\": \"Knit Cardigan\", \"#FFC3C1BC\": \"Knitting Needles\", \"#FF9F9B84\": \"Knock on Wood\", \"#FFC42B2D\": \"Knockout\", \"#FFE16F3E\": \"Knockout Orange\", \"#FFFF399C\": \"Knockout Pink\", \"#FF988266\": \"Knot\", \"#FF837F67\": \"Knotweed\", \"#FFB9ACA0\": \"Koala\", \"#FFBDB7A3\": \"Koala Bear\", \"#FFDB5A6B\": \"K\\u014dbai Red\", \"#FFE093AB\": \"Kobi Variant\", \"#FFF0D2CF\": \"Kobold Pink\", \"#FF00AA22\": \"Kobra Khan\", \"#FFE8F5FC\": \"Kodama White\", \"#FFE97551\": \"Koeksister\", \"#FF883322\": \"Kofta Brown\", \"#FF773644\": \"K\\u00f6fte Brown\", \"#FFE5B321\": \"Kogane Gold\", \"#FFCA6924\": \"Kohaku Amber\", \"#FFC0B76C\": \"Kohlrabi\", \"#FFD9D9B1\": \"Kohlrabi Green\", \"#FFD2663B\": \"Koi\", \"#FF797F63\": \"Koi Pond\", \"#FFF6AD49\": \"Koji Orange\", \"#FF8B7D3A\": \"Koke Moss\", \"#FF7B3B3A\": \"Kokiake Brown\", \"#FF3A243B\": \"Kokimurasaki Purple\", \"#FF7B785A\": \"Kokoda Variant\", \"#FF171412\": \"Kokushoku Black\", \"#FF00477A\": \"Kolibri Blue\", \"#FF7B8D42\": \"Komatsuna Green\", \"#FF7E726D\": \"Kombu\", \"#FF3A4032\": \"Kombu Green\", \"#FFD89F66\": \"Kombucha\", \"#FF9D907E\": \"Kommando Khaki\", \"#FFA06814\": \"Komodo\", \"#FFB38052\": \"Komodo Dragon\", \"#FFBBC5B2\": \"Komorebi\", \"#FF192236\": \"Kon\", \"#FF574B50\": \"Kona\", \"#FF003171\": \"Konj\\u014d Blue\", \"#FF191F45\": \"Konkiky\\u014d Blue\", \"#FF58D854\": \"Koopa Green Shell\", \"#FF833D3E\": \"Kopi Luwak\", \"#FF203838\": \"K\\u014drainando Green\", \"#FFF2D1C3\": \"Koral Kicks\", \"#FF5D7D61\": \"Korean Mint\", \"#FF8D4512\": \"Korichnewyi Brown\", \"#FFD7E9C8\": \"Korila\", \"#FF804E2C\": \"Korma Variant\", \"#FFFEB552\": \"Koromiko Variant\", \"#FF592B1F\": \"K\\u014drozen\", \"#FF888877\": \"Kosher Khaki\", \"#FFF9D054\": \"Kournikova Variant\", \"#FFE1B029\": \"K\\u014dwhai Yellow\", \"#FFE1D956\": \"Kowloon\", \"#FFD5B59C\": \"Kraft Paper\", \"#FFCD48A9\": \"Krameria\", \"#FFEB2E28\": \"Krasnyi Red\", \"#FF633639\": \"Kremlin Red\", \"#FFC0BD81\": \"Krieg Khaki\", \"#FF01ABFD\": \"Krishna Blue\", \"#FFEA27C2\": \"Kriss Me Not Fuchsia\", \"#FFB8C0C3\": \"Krypton\", \"#FF83890E\": \"Krypton Green\", \"#FF439946\": \"Kryptonite Green\", \"#FFE8000D\": \"KU Crimson\", \"#FFFFDB4F\": \"Kuchinashi Yellow\", \"#FF87D3F8\": \"Kul Sharif Blue\", \"#FFFB9942\": \"Kumquat\", \"#FFD2CCDA\": \"Kundalini Bliss\", \"#FF643B42\": \"Kung Fu\", \"#FFDDB6C6\": \"Kunzite\", \"#FFD7003A\": \"Kurenai Red\", \"#FF001122\": \"Kuretake Black Manga\", \"#FF554738\": \"Kuri Black\", \"#FF583822\": \"Kuro Brown\", \"#FF1B2B1B\": \"Kuro Green\", \"#FF23191E\": \"Kurobeni\", \"#FF14151D\": \"Kuroi Black\", \"#FF9F7462\": \"Kurumizome Brown\", \"#FF5789A5\": \"Kuta Surf\", \"#FF55295B\": \"Kuwanomi Purple\", \"#FF59292C\": \"Kuwazome Red\", \"#FFC7610F\": \"Kvass\", \"#FF1560FB\": \"Kyanite\", \"#FFE8530F\": \"Kyawthuite\", \"#FF9D5B8B\": \"Kyo Purple\", \"#FFBEE3EA\": \"Kyoto\", \"#FF503000\": \"Kyoto House\", \"#FFDFD6D1\": \"Kyoto Pearl\", \"#FF4B5D16\": \"Kyuri Green\", \"#FF7A7A60\": \"La Grange\", \"#FFFC2647\": \"L\\u00e0 Ji\\u0101o H\\u00f3ng Red\", \"#FFA3498A\": \"La la Lavender\", \"#FFBF90BB\": \"La la Love\", \"#FFFFFFE5\": \"La Luna\", \"#FFFDDFA0\": \"La Luna Amarilla\", \"#FFF5E5DC\": \"La Minute\", \"#FF428929\": \"La Palma Variant\", \"#FFC1E5EA\": \"La Paz Siesta\", \"#FF577E88\": \"La Pineta\", \"#FFBAC00E\": \"La Rioja Variant\", \"#FFEA936E\": \"La Terra\", \"#FFEECCDD\": \"LA Vibes\", \"#FFC4A703\": \"La Vida\", \"#FFD2A5A3\": \"La Vie en Rose\", \"#FFC3B1BE\": \"La-De-Dah\", \"#FFF2ECD9\": \"Labrador\", \"#FFD6C575\": \"Labrador\\u2019s Locks\", \"#FF657B83\": \"Labradorite\", \"#FF547D80\": \"Labradorite Green\", \"#FFC9A487\": \"Labyrinth Walk\", \"#FFEBEAED\": \"Lace Cap\", \"#FFECEBEA\": \"Lace Veil\", \"#FFC2BBC0\": \"Lace Wisteria\", \"#FFCCEE99\": \"Laced Green\", \"#FFD7E3CA\": \"Lacewing\", \"#FFCAAEAB\": \"Lacey\", \"#FF1B322C\": \"Lacquer Green\", \"#FFF0CFE1\": \"Lacquer Mauve\", \"#FF383838\": \"Lacquered Liquorice\", \"#FF2E5C58\": \"Lacrosse\", \"#FF19504C\": \"Lacustral\", \"#FFA78490\": \"Lacy Mist\", \"#FFFF8E13\": \"Laddu Orange\", \"#FFD9DED8\": \"Ladoga Bottom\", \"#FFFDE2DE\": \"Lady Anne\", \"#FFFDE5A7\": \"Lady Banksia\", \"#FF8FA174\": \"Lady Fern\", \"#FFCCBBC0\": \"Lady Fingers\", \"#FFD0A4AE\": \"Lady Flower\", \"#FFCAA09E\": \"Lady Guinevere\", \"#FFB34B47\": \"Lady in Red\", \"#FF47613C\": \"Lady Luck\", \"#FFD6D6CD\": \"Lady Nicole\", \"#FF05498B\": \"Lady of the Night\", \"#FF0000CC\": \"Lady of the Sea\", \"#FFAEDCEC\": \"Lady-In-Waiting\", \"#FFC99BB0\": \"Lady\\u2019s Cushions Pink\", \"#FFE3E3EA\": \"Lady\\u2019s Slipper\", \"#FFBD474E\": \"Ladybug\", \"#FFFFC3BF\": \"Ladylike\", \"#FFF5C8DD\": \"Laelia Pink\", \"#FFF6F513\": \"Lager\", \"#FF1FB4C3\": \"Lago Blue\", \"#FF4B9B93\": \"Lagoon\", \"#FFEAEDEE\": \"Lagoon Mirror\", \"#FF8B7E64\": \"Lagoon Moss\", \"#FFA9B9BB\": \"Lagoon Reflection\", \"#FF43BCBE\": \"Lagoon Rock\", \"#FF76C6D3\": \"Lagoona Teal\", \"#FF36A5C9\": \"Laguna\", \"#FFE9D7C0\": \"Laguna Beach\", \"#FF5A7490\": \"Laguna Blue\", \"#FF01B1AF\": \"Laguna Green\", \"#FF5F5855\": \"Lahar\", \"#FFE2DAD1\": \"Lahmian Medium\", \"#FFFFF80A\": \"Lahn Yellow\", \"#FFB3AFA7\": \"Laid Back Grey\", \"#FF819EA1\": \"Laid-Back Blue\", \"#FF79853C\": \"Laird\", \"#FFA6D3E6\": \"Laissez-Faire\", \"#FF92CDCC\": \"Lake\", \"#FF155084\": \"Lake Baikal\", \"#FF009EAF\": \"Lake Blue\", \"#FFD9CFB5\": \"Lake Bluff Putty\", \"#FFAED4D2\": \"Lake Breeze\", \"#FF96B4B1\": \"Lake Forest\", \"#FF4181A6\": \"Lake Henry\", \"#FF689DB7\": \"Lake Lucerne\", \"#FF83A0B4\": \"Lake Okoboji\", \"#FFAEB9BC\": \"Lake Placid\", \"#FFB74A70\": \"Lake Red\", \"#FF9DD8DB\": \"Lake Reflection\", \"#FFEE55EE\": \"Lake Retba Pink\", \"#FF3E6B83\": \"Lake Stream\", \"#FF34B1B2\": \"Lake Tahoe Turquoise\", \"#FF44BBDD\": \"Lake Thun\", \"#FF2E4967\": \"Lake View\", \"#FF86ABA5\": \"Lake Water\", \"#FF80A1B0\": \"Lake Winnipeg\", \"#FF8B9CA5\": \"Lakefront\", \"#FF306F73\": \"Lakelike\", \"#FF5B96A2\": \"Lakeshore\", \"#FFADB8C0\": \"Lakeside\", \"#FFB7D1D1\": \"Lakeside Find\", \"#FFD7EEEF\": \"Lakeside Mist\", \"#FF566552\": \"Lakeside Pine\", \"#FF6C849B\": \"Lakeville\", \"#FFE6BF95\": \"Laksa\", \"#FFD85525\": \"L\\u0101l Red\", \"#FFE0BB95\": \"Lama\", \"#FF82502C\": \"Lamb Chop\", \"#FFC8CCBC\": \"Lamb\\u2019s Ears\", \"#FFFFFFE3\": \"Lamb\\u2019s Wool\", \"#FF3B5B92\": \"Lambent Lagoon\", \"#FFEBDCCA\": \"Lambskin\", \"#FFBAD0D5\": \"Lament Blue\", \"#FFFFFEB6\": \"Lamenters Yellow\", \"#FF3AFDDB\": \"Lamiaceae\", \"#FFBBD9BC\": \"Lamina\", \"#FF948C7E\": \"Laminated Wood\", \"#FF4A4F55\": \"Lamp Post\", \"#FFFFD140\": \"Lamplight\", \"#FFE4AF65\": \"Lamplit\", \"#FF805557\": \"Lampoon\", \"#FF4D4DFF\": \"L\\u00e1n S\\u00e8 Blue\", \"#FF97DDD4\": \"Land Ahoy!\", \"#FFBFBEAD\": \"Land Before Time\", \"#FFDFCAAA\": \"Land Light\", \"#FFEDABE6\": \"Land of Dreams\", \"#FFA99B88\": \"Land of Nod\", \"#FFE0D5B9\": \"Land of Trees\", \"#FFC9BBA1\": \"Land Rush Bone\", \"#FFEEE1D9\": \"Landing\", \"#FFAF403C\": \"Landj\\u00e4ger\", \"#FF746854\": \"Landmark\", \"#FF756657\": \"Landmark Brown\", \"#FFC1CFA9\": \"Landscape\", \"#FFB5AB9A\": \"Langdon Dove\", \"#FFDC5226\": \"Langoustine\", \"#FFCA6C56\": \"Langoustino\", \"#FFA4B7BD\": \"Languid Blue\", \"#FFCD0101\": \"Lannister Red\", \"#FFD87273\": \"Lantana\", \"#FFD7ECCD\": \"Lantana Lime\", \"#FFEFDDB8\": \"Lantern\", \"#FFFFD97D\": \"Lantern Gold\", \"#FFF6EBB9\": \"Lantern Light\", \"#FFC09972\": \"Lanyard\", \"#FFA6927F\": \"Lap Dog\", \"#FF515366\": \"Lap of Luxury\", \"#FF98BBB7\": \"Lap Pool Blue\", \"#FF00508D\": \"Lapis Blue\", \"#FF165D95\": \"Lapis Jewel\", \"#FF215F96\": \"Lapis Lazuli Blue\", \"#FF1F22D2\": \"Lapis on Neptune\", \"#FF7A7562\": \"Lapwing Grey Green\", \"#FFDFC6AA\": \"Larb Gai\", \"#FFFFAA77\": \"Larch Bolete\", \"#FF70BAA7\": \"Larchmere\", \"#FFD79A74\": \"Laredo\", \"#FFC7994F\": \"Laredo Road\", \"#FFE4E2D6\": \"Large Wild Convolvulus\", \"#FF551F2F\": \"Largest Black Slug\", \"#FF1D78AB\": \"Larimar Blue\", \"#FF93D3BC\": \"Larimar Green\", \"#FFB89B72\": \"Lark\", \"#FF8AC1A1\": \"Lark Green\", \"#FFC4CED1\": \"Lark Wing\", \"#FF3C7D90\": \"Larkspur\", \"#FF20AEB1\": \"Larkspur Blue\", \"#FF798BBD\": \"Larkspur Bouquet\", \"#FFB7C0EA\": \"Larkspur Bud\", \"#FF928AAE\": \"Larkspur Violet\", \"#FFC6DA36\": \"Las Palmas Variant\", \"#FFC6A95E\": \"Laser Variant\", \"#FFFF3F6A\": \"Laser Trap\", \"#FF475F94\": \"Last Light Blue\", \"#FFAADD66\": \"Last of Lettuce\", \"#FFCBBBCD\": \"Last of the Lilacs\", \"#FFE3DBCD\": \"Last Straw\", \"#FFD30F3F\": \"Last Warning\", \"#FFB36663\": \"Lasting Impression\", \"#FF88FF00\": \"Lasting Lime\", \"#FFD4E6B1\": \"Lasting Thoughts\", \"#FFF8AB33\": \"Late Afternoon\", \"#FFDB8959\": \"Late Bloomer\", \"#FFF2E08E\": \"Late Day Sun\", \"#FF3B2932\": \"Late Night Out\", \"#FF008A51\": \"Later Gator\", \"#FF3B9C98\": \"Latigo Bay\", \"#FF292E44\": \"Latin Charm\", \"#FFC5A582\": \"Latte\", \"#FFF3F0E8\": \"Latte Froth\", \"#FFE8E7E6\": \"Latteo\", \"#FFCECEC6\": \"Lattice\", \"#FF6F9843\": \"Lattice Green\", \"#FFB9E1C2\": \"Lattice Work\", \"#FF8CBF6F\": \"Laudable Lime\", \"#FFC9C3D2\": \"Laughing Jack\", \"#FFF0E5A4\": \"Laughing Liam\", \"#FFF49807\": \"Laughing Orange\", \"#FFC0E7EB\": \"Launderette Blue\", \"#FFA2ADB3\": \"Laundry Blue\", \"#FFF6F7F1\": \"Laundry White\", \"#FFA6979A\": \"Laura\", \"#FF800008\": \"Laura Potato\", \"#FF6E8D71\": \"Laurel Variant\", \"#FF68705C\": \"Laurel Garland\", \"#FFAAACA2\": \"Laurel Grey\", \"#FF969B8B\": \"Laurel Leaf\", \"#FFACB5A1\": \"Laurel Mist\", \"#FF55403E\": \"Laurel Nut Brown\", \"#FF918C7E\": \"Laurel Oak\", \"#FFF7E1DC\": \"Laurel Pink\", \"#FF889779\": \"Laurel Tree\", \"#FF44493D\": \"Laurel Woods\", \"#FF52A786\": \"Laurel Wreath\", \"#FFEFEAE7\": \"Lauren\\u2019s Lace\", \"#FFD5E5E7\": \"Lauren\\u2019s Surprise\", \"#FF868172\": \"Lauriston Stone\", \"#FFF3C64A\": \"Lauwiliwilinukunuku\\u2019oi\\u2019oi\", \"#FF352F36\": \"Lava Black\", \"#FF5A4239\": \"Lava Cake\", \"#FF764031\": \"Lava Core\", \"#FFDBD0CE\": \"Lava Geyser\", \"#FF5E686D\": \"Lava Grey\", \"#FFEB7135\": \"Lava Lamp\", \"#FFE5530E\": \"Lava Nectar\", \"#FFE46F34\": \"Lava Pit\", \"#FF535E64\": \"Lava Rock\", \"#FFD04014\": \"Lava Smoothie\", \"#FFAF9894\": \"Lavenbrun\", \"#FF8F818B\": \"Lavendaire\", \"#FFE9EBEE\": \"Lavendar Wisp\", \"#FFB56EDC\": \"Lavender Variant\", \"#FF9998A7\": \"Lavender Ash\", \"#FF9F99AA\": \"Lavender Aura\", \"#FFE5D9DA\": \"Lavender Bikini\", \"#FFB68FC3\": \"Lavender Blaze\", \"#FFD3B8C5\": \"Lavender Blessing\", \"#FFCEC3DD\": \"Lavender Bliss\", \"#FF8B88F8\": \"Lavender Blue Shadow\", \"#FF9994C0\": \"Lavender Bonnet\", \"#FFC7C2D0\": \"Lavender Bouquet\", \"#FFE4E1E3\": \"Lavender Breeze\", \"#FFFCB4D5\": \"Lavender Candy\", \"#FFB8ABB1\": \"Lavender Cloud\", \"#FFC79FEF\": \"Lavender Cream\", \"#FF956D9A\": \"Lavender Crystal\", \"#FFB4AECC\": \"Lavender Dream\", \"#FFAF92BD\": \"Lavender Earl\", \"#FF9D9399\": \"Lavender Elan\", \"#FF786C75\": \"Lavender Elegance\", \"#FFC0C3D7\": \"Lavender Escape\", \"#FFDFDAD9\": \"Lavender Essence\", \"#FFCAADD8\": \"Lavender Field Dreamer\", \"#FFC5B5CC\": \"Lavender Fog\", \"#FFDDBBFF\": \"Lavender Fragrance\", \"#FFBDABBE\": \"Lavender Frost\", \"#FFD3D0DD\": \"Lavender Haze\", \"#FFAD88A4\": \"Lavender Herb\", \"#FFC0C2D2\": \"Lavender Honour\", \"#FFA99BA7\": \"Lavender Illusion\", \"#FFD3B0CE\": \"Lavender Knoll\", \"#FFDFDDE0\": \"Lavender Lace\", \"#FFA198A2\": \"Lavender Lake\", \"#FF8C9180\": \"Lavender Leaf Green\", \"#FFA5969C\": \"Lavender Lily\", \"#FF8C9CC1\": \"Lavender Lustre\", \"#FFEE82ED\": \"Lavender Magenta Variant\", \"#FF687698\": \"Lavender Mauve\", \"#FFD3D3E2\": \"Lavender Memory\", \"#FFE5E5FA\": \"Lavender Mist\", \"#FFF2DDE3\": \"Lavender Moon\", \"#FF67636E\": \"Lavender Moor\", \"#FF857E86\": \"Lavender Mosaic\", \"#FFC0C0CA\": \"Lavender Oil\", \"#FFEDE5E8\": \"Lavender Pearl\", \"#FFCB82E3\": \"Lavender Perceptions\", \"#FFA6BADF\": \"Lavender Phlox\", \"#FFC5B9D3\": \"Lavender Pillow\", \"#FFE9E2E5\": \"Lavender Pizzazz\", \"#FFE9D2EF\": \"Lavender Princess\", \"#FFBD88AB\": \"Lavender Quartz\", \"#FFBEC2DA\": \"Lavender Sachet\", \"#FFC3B7BF\": \"Lavender Sand\", \"#FFEEDDFF\": \"Lavender Savour\", \"#FFBFACB1\": \"Lavender Scent\", \"#FFDBD7F2\": \"Lavender Sky\", \"#FFF1BFE2\": \"Lavender Soap\", \"#FFCFCEDC\": \"Lavender Sparkle\", \"#FF9392AD\": \"Lavender Spectacle\", \"#FFC6CBDB\": \"Lavender Steel\", \"#FFB4A5A0\": \"Lavender Suede\", \"#FFBD83BE\": \"Lavender Sweater\", \"#FFE6E6F1\": \"Lavender Syrup\", \"#FFD783FF\": \"Lavender Tea\", \"#FFCCBBFF\": \"Lavender Tonic\", \"#FFC8C1C9\": \"Lavender Vapour\", \"#FFD9BBD3\": \"Lavender Veil\", \"#FF767BA5\": \"Lavender Violet\", \"#FFE3D7E5\": \"Lavender Vista\", \"#FFAAB0D4\": \"Lavender Wash\", \"#FFD2C9DF\": \"Lavender Water\", \"#FFB86FC2\": \"Lavendless\", \"#FFBCA4CB\": \"Lavendula\", \"#FFA38154\": \"Lavish Gold\", \"#FF7ED0B7\": \"Lavish Green\", \"#FFC2AEC3\": \"Lavish Lavender\", \"#FFF9EFCA\": \"Lavish Lemon\", \"#FFB0C175\": \"Lavish Lime\", \"#FF8469BC\": \"Lavish Spending\", \"#FF4DA409\": \"Lawn Green Variant\", \"#FF5EB56A\": \"Lawn Party\", \"#FF5C7186\": \"Layers of Ocean\", \"#FFAB9BA5\": \"Laylock\", \"#FF174C60\": \"Lazurite Blue\", \"#FF97928B\": \"Lazy Afternoon\", \"#FFE2E5C7\": \"Lazy Caterpillar\", \"#FFF6EBA1\": \"Lazy Daisy\", \"#FF95AED1\": \"Lazy Day\", \"#FFBEC1C3\": \"Lazy Grey\", \"#FFA3A0B3\": \"Lazy Lavender\", \"#FF6E6E5C\": \"Lazy Lichen\", \"#FF9C9C4B\": \"Lazy Lizard\", \"#FFCC0011\": \"Lazy Shell Red\", \"#FFFEF3C3\": \"Lazy Summer Day\", \"#FFFEC784\": \"Lazy Sun\", \"#FFCAD3E7\": \"Lazy Sunday\", \"#FFE4CB6B\": \"Le Bon Dijon\", \"#FFBF4E46\": \"Le Corbusier Crush\", \"#FF244E94\": \"Le Grand Bleu\", \"#FF5E6869\": \"Le Luxe\", \"#FF85B2A1\": \"Le Max\", \"#FF212121\": \"Lead\", \"#FF6C809C\": \"Lead Cast\", \"#FFFFFAE5\": \"Lead Glass\", \"#FF8A7963\": \"Lead Grey\", \"#FF99AABB\": \"Lead Ore\", \"#FFCACACB\": \"Leadbelcher\", \"#FF888D8F\": \"Leadbelcher Metal\", \"#FF71AA34\": \"Leaf\", \"#FFEFF19D\": \"Leaf Bud\", \"#FFE1D38E\": \"Leaf Print\", \"#FF6CB506\": \"Leaf Sheep\", \"#FFE9D79E\": \"Leaf Yellow\", \"#FF8B987B\": \"Leaflet\", \"#FF679B6A\": \"Leafy\", \"#FFAACC11\": \"Leafy Canopy\", \"#FF80BB66\": \"Leafy Greens\", \"#FFC0F000\": \"Leafy Lemon\", \"#FF7D8574\": \"Leafy Lichen\", \"#FF08690E\": \"Leafy Lush\", \"#FF8D9679\": \"Leafy Rise\", \"#FFB6C406\": \"Leafy Seadragon\", \"#FFAABB11\": \"Leafy Woodland\", \"#FFA0B7A8\": \"Leamington Spa\", \"#FFC4D3E3\": \"Leap of Faith\", \"#FF41A94F\": \"Leapfrog\", \"#FF447A66\": \"Leaping Lizard\", \"#FF6F803B\": \"Leaps and Bounds\", \"#FFABC123\": \"Learning Green\", \"#FF906A54\": \"Leather Variant\", \"#FF76563E\": \"Leather & Lace\", \"#FF916E52\": \"Leather Bound\", \"#FF97502B\": \"Leather Brown\", \"#FFA3754C\": \"Leather Chair\", \"#FF744E42\": \"Leather Clutch\", \"#FF867354\": \"Leather Loafers\", \"#FF7C4F3A\": \"Leather Satchel\", \"#FFA48454\": \"Leather Tan\", \"#FF8A6347\": \"Leather Work\", \"#FF3C351F\": \"LeChuck\\u2019s Beard\", \"#FF0066A3\": \"LED Blue\", \"#FFD8CB32\": \"LED Green\", \"#FF98D98E\": \"Leek\", \"#FFBCA3B8\": \"Leek Blossom Pink\", \"#FF979C84\": \"Leek Green\", \"#FFB7B17A\": \"Leek Powder\", \"#FF7A9C58\": \"Leek Soup\", \"#FFCEDCCA\": \"Leek White\", \"#FFF5C71A\": \"Leery Lemon\", \"#FF4C2226\": \"Lees\", \"#FF699CAB\": \"Left Bank Blue\", \"#FFFF0303\": \"Left on Red\", \"#FF5E5A67\": \"Legacy\", \"#FF9EC9E2\": \"Legacy Blue\", \"#FF6D758F\": \"Legal Eagle\", \"#FF6F434A\": \"Legal Ribbon\", \"#FFC6BAAF\": \"Legendary\", \"#FF787976\": \"Legendary Grey\", \"#FF9D61D4\": \"Legendary Lavender\", \"#FFAD969D\": \"Legendary Lilac\", \"#FF4E4E63\": \"Legendary Purple\", \"#FF7F8384\": \"Legendary Sword\", \"#FF245A6A\": \"Legion Blue\", \"#FFD87B6A\": \"Lei Flower\", \"#FFC19634\": \"Leisure\", \"#FF6A8EA1\": \"Leisure Blue\", \"#FF438261\": \"Leisure Green\", \"#FF758C8F\": \"Leisure Time\", \"#FFEFE4AE\": \"Lemon Appeal\", \"#FFE5D9B6\": \"Lemon Balm\", \"#FF005228\": \"Lemon Balm Green\", \"#FFCEA02F\": \"Lemon Bar\", \"#FFFCECAD\": \"Lemon Blast\", \"#FFFCEBBF\": \"Lemon Bubble\", \"#FFFEF59F\": \"Lemon Bundt Cake\", \"#FFFED67E\": \"Lemon Burst\", \"#FFFCE99F\": \"Lemon Butter\", \"#FFF7DE9D\": \"Lemon Caipirinha\", \"#FFFAE8AB\": \"Lemon Candy\", \"#FFFFF7C4\": \"Lemon Chiffon Pie\", \"#FFFAAE00\": \"Lemon Chrome\", \"#FFFEE193\": \"Lemon Cream\", \"#FFFFEE11\": \"Lemon Curd\", \"#FFCDA323\": \"Lemon Curry\", \"#FFFCE699\": \"Lemon Delicious\", \"#FFEEA300\": \"Lemon Dream\", \"#FFFEE483\": \"Lemon Drizzle\", \"#FFFFE49D\": \"Lemon Drops\", \"#FFF4EFDE\": \"Lemon Edge\", \"#FFE2AE4D\": \"Lemon Essence\", \"#FFD4D292\": \"Lemon Fennel\", \"#FFF9E4A6\": \"Lemon Filling\", \"#FFF0E891\": \"Lemon Flesh\", \"#FF96FBC4\": \"Lemon Gate\", \"#FFF8EC9E\": \"Lemon Gelato\", \"#FF968428\": \"Lemon Ginger Variant\", \"#FFADF802\": \"Lemon Green\", \"#FFF6EBC8\": \"Lemon Icing\", \"#FFFFFFEC\": \"Lemon Juice\", \"#FFFAF4D9\": \"Lemon Lily\", \"#FFBFFE28\": \"Lemon Lime\", \"#FFCBBA61\": \"Lemon Lime Mojito\", \"#FFF6E199\": \"Lemon Meringue\", \"#FFF9F1DB\": \"Lemon Pearl\", \"#FFFFED80\": \"Lemon Peel\", \"#FFEBECA7\": \"Lemon Pepper\", \"#FFF1FF62\": \"Lemon Pie\", \"#FFE1AE58\": \"Lemon Poppy\", \"#FFFAF2D1\": \"Lemon Popsicle\", \"#FFFFDD93\": \"Lemon Pound Cake\", \"#FFFECF24\": \"Lemon Punch\", \"#FFFBE9AC\": \"Lemon Rose\", \"#FFFAF0CF\": \"Lemon Sachet\", \"#FFF1FFA8\": \"Lemon Sherbet\", \"#FFFFFBA8\": \"Lemon Slice\", \"#FFFFFCC4\": \"Lemon Soap\", \"#FFFFFAC0\": \"Lemon Sorbet\", \"#FFDCC68E\": \"Lemon Sorbet Yellow\", \"#FFFFE8AD\": \"Lemon Souffle\", \"#FFF9F6DE\": \"Lemon Splash\", \"#FFF7F0E1\": \"Lemon Sponge Cake\", \"#FFFBF7E0\": \"Lemon Stick\", \"#FFF0F6DD\": \"Lemon Sugar\", \"#FFE1BC5C\": \"Lemon Surprise\", \"#FFFFDD66\": \"Lemon Tart\", \"#FFE4CF86\": \"Lemon Thyme\", \"#FFFCF3CB\": \"Lemon Tint\", \"#FFEFEFB2\": \"Lemon Tonic\", \"#FFFED95D\": \"Lemon Twist\", \"#FFF2ED6B\": \"Lemon Verbena\", \"#FFFFE6BA\": \"Lemon Whip\", \"#FFFFB10D\": \"Lemon Whisper\", \"#FFFBF6E0\": \"Lemon White\", \"#FFF9D857\": \"Lemon Zest\", \"#FFEFE499\": \"Lemonade\", \"#FFF2CA3B\": \"Lemonade Stand\", \"#FF999A86\": \"Lemongrass\", \"#FFF9F3D7\": \"Lemonwood Place\", \"#FF695F4F\": \"Lemur\", \"#FFBFB9D4\": \"Lemures\", \"#FFCEE2E2\": \"Lens Flare Blue\", \"#FFB0FF9D\": \"Lens Flare Green\", \"#FFE4CBFF\": \"Lens Flare Pink\", \"#FF6FB5A8\": \"Lenticular Ore\", \"#FFDCC8B0\": \"Lentil\", \"#FFA09548\": \"Lentil Sprout\", \"#FFBA93D8\": \"Lenurple\", \"#FFE042D5\": \"Leo Royal Fuchsia\", \"#FFD09800\": \"Leopard\", \"#FF29906D\": \"Leprechaun\", \"#FF395549\": \"Leprechaun Green\", \"#FF8CC37D\": \"Leprechaun Laugh\", \"#FFD99631\": \"Leprous Brown\", \"#FFD0A000\": \"Lepton Gold\", \"#FF71635A\": \"Leroy\", \"#FF0F63B3\": \"Les Cavaliers Beach\", \"#FFE59D7B\": \"Les Demoiselles d\\u2019Avignon\", \"#FF756761\": \"Less Brown\", \"#FF5D6957\": \"Less Traveled\", \"#FFAFD1C4\": \"Lester\", \"#FFB6B8BD\": \"Let It Rain\", \"#FFCFAE74\": \"Let It Ring\", \"#FFD8F1F4\": \"Let It Snow\", \"#FF88FF11\": \"Lethal Lime\", \"#FF95BE76\": \"Leticiaz\", \"#FF8F8F8B\": \"Letter Grey\", \"#FFCEDDA2\": \"Lettuce Alone\", \"#FFB9D087\": \"Lettuce Green\", \"#FF92A772\": \"Lettuce Mound\", \"#FFF2F1ED\": \"Leukocyte White\", \"#FFE8E8E9\": \"Leukophobia\", \"#FFE4090B\": \"Level !\", \"#FF468741\": \"Level Up\", \"#FFEDCDC2\": \"Leverkaas\", \"#FF8B2A98\": \"Leviathan Purple\", \"#FFCEA269\": \"Lewis Gold\", \"#FFF8F1D3\": \"Lewisburg Lemon\", \"#FF675A49\": \"Lewisham\", \"#FF00E436\": \"Lexaloffle Green\", \"#FF7D9294\": \"Lexington Blue\", \"#FF8C3F52\": \"Liaison\", \"#FFF075E6\": \"Li\\u00e1n H\\u00f3ng Lotus Pink\", \"#FFCCB8D2\": \"Liberace\", \"#FF0C4792\": \"Liberalist\", \"#FFD8DDCC\": \"Liberated Lime\", \"#FFE8C447\": \"Liberator Gold\", \"#FFEFE2DB\": \"Liberia\", \"#FF514B98\": \"Liberty Variant\", \"#FF696B6D\": \"Liberty Bell Grey\", \"#FF0E1531\": \"Liberty Blue\", \"#FF16A74E\": \"Liberty Green\", \"#FFAFBFC9\": \"Liberty Grey\", \"#FF4CD5FF\": \"Libra Blue Morpho\", \"#FFE6C19F\": \"Library Card\", \"#FF68554E\": \"Library Leather\", \"#FF8F7459\": \"Library Oak\", \"#FF7F7263\": \"Library Pewter\", \"#FF5B3530\": \"Library Red\", \"#FFA9A694\": \"Lich Grey\", \"#FF730061\": \"Liche Purple\", \"#FF8EBAA6\": \"Lichen\", \"#FF5D89B3\": \"Lichen Blue\", \"#FFDDE7AE\": \"Lichen Gold\", \"#FF9DA693\": \"Lichen Green\", \"#FF697056\": \"Lichen Moss\", \"#FFEE5577\": \"Lick and Kiss\", \"#FFA6CC72\": \"Lick of Lime\", \"#FFB4496C\": \"Lickedy Lick\", \"#FFC3D997\": \"Lickety Split\", \"#FFC99C59\": \"Liddell\", \"#FF019294\": \"Lido Deck\", \"#FF92B498\": \"Liebermann Green\", \"#FFFDFF38\": \"Liechtenstein Yellow\", \"#FFA2B0A8\": \"Life Aquatic\", \"#FFAFC9DC\": \"Life at Sea\", \"#FF6FB7E0\": \"Life Force\", \"#FFE5CDBE\": \"Life Is a Peach\", \"#FFE19B42\": \"Life Is Good\", \"#FFC5CABE\": \"Life Lesson\", \"#FF81B6BC\": \"Lifeboat Blue\", \"#FFE50000\": \"Lifeguard\", \"#FF00DEAD\": \"Lifeless Green\", \"#FFE6D699\": \"Lifeless Planet\", \"#FF990033\": \"Lifeline\", \"#FFCDD6C2\": \"Ligado\", \"#FFC3C5C5\": \"Light Aluminium\", \"#FFED9A76\": \"Light Amber Orange\", \"#FFD4D3E0\": \"Light Amourette\", \"#FFFFD5A1\": \"Light and Fluffy\", \"#FFDAD4E4\": \"Light Angel Kiss\", \"#FFC9D4E1\": \"Light Angora Blue\", \"#FFF2DAD6\": \"Light Apricot Variant\", \"#FFDECFD2\": \"Light Aroma\", \"#FFC2A487\": \"Light Ash Brown\", \"#FFDAC6A1\": \"Light Bamboo\", \"#FFDED0D8\": \"Light Bassinet\", \"#FFABD5DC\": \"Light Bathing\", \"#FFE5DECA\": \"Light Beige\", \"#FF9DB567\": \"Light Birch Green\", \"#FFD5D4D0\": \"Light Bleaches\", \"#FFE8D3AF\": \"Light Blond\", \"#FFECDDD6\": \"Light Blossom Time\", \"#FFD2D3E1\": \"Light Blue Cloud\", \"#FFA8D3E1\": \"Light Blue Glint\", \"#FFB7C9E2\": \"Light Blue Grey\", \"#FFC6DDE4\": \"Light Blue Sloth\", \"#FFC0D8EB\": \"Light Blue Veil\", \"#FFA4DBE4\": \"Light Bluish Water\", \"#FFE9C4CC\": \"Light Blush\", \"#FFADD2E3\": \"Light Bobby Blue\", \"#FFCFE0F2\": \"Light Breeze\", \"#FF94D0E9\": \"Light Bright Spark\", \"#FFBC9468\": \"Light Bronzer\", \"#FFB08699\": \"Light Brown Drab\", \"#FFD6D5D2\": \"Light Brume\", \"#FF9ED6E8\": \"Light Budgie Blue\", \"#FFDECED1\": \"Light Bunny Soft\", \"#FFC6D4E1\": \"Light Cameo Blue\", \"#FFC9D2DF\": \"Light Candela\", \"#FF8BD4C3\": \"Light Capri Green\", \"#FFA38A83\": \"Light Caramel\", \"#FFDBD9C9\": \"Light Cargo River\", \"#FFF9DBCF\": \"Light Carob\", \"#FFD8F3D7\": \"Light Carolina\", \"#FFD8F2DC\": \"Light Celery Stick\", \"#FFD1C6BE\": \"Light Chamois Beige\", \"#FF726E68\": \"Light Charcoal\", \"#FFECEAD1\": \"Light Chervil\", \"#FFF4E7E5\": \"Light Chiffon\", \"#FFE0D5C9\": \"Light Chintz\", \"#FFDFD3CA\": \"Light Christobel\", \"#FFD5DAD1\": \"Light Cipollino\", \"#FFAFD5D8\": \"Light Continental Waters\", \"#FFC48F4B\": \"Light Copper\", \"#FFF3E2D1\": \"Light Corn\", \"#FFE0C3A2\": \"Light Corn Yellow\", \"#FFDDD7D1\": \"Light Crushed Almond\", \"#FFCBD7ED\": \"Light Cuddle\", \"#FFF9E9C9\": \"Light Curd\", \"#FFC2E4E7\": \"Light Daly Waters\", \"#FFC6DEDF\": \"Light Dante Peak\", \"#FFE2D9D2\": \"Light Daydreamer\", \"#FFFCE9D5\": \"Light Dedication\", \"#FF9ED1E3\": \"Light Delphin\", \"#FFA4D4EC\": \"Light Deluxe Days\", \"#FFCDDBDC\": \"Light Detroit\", \"#FFC4DADD\": \"Light Dewpoint\", \"#FFA7AEA5\": \"Light Drizzle\", \"#FFD4E3D7\": \"Light Dry Lichen\", \"#FFD5EBDD\": \"Light Duck Egg Cream\", \"#FFD4CED1\": \"Light Easter Rabbit\", \"#FFD9D2C9\": \"Light Eggshell Pink\", \"#FFEAD5C7\": \"Light Ellen\", \"#FFD8CDD3\": \"Light Elusive Dream\", \"#FFD6EADB\": \"Light Enchanted\", \"#FFF3DED7\": \"Light Fairy Pink\", \"#FFEAD3E0\": \"Light Favourite Lady\", \"#FFD3D9C5\": \"Light Feather Green\", \"#FFC1D8EB\": \"Light Featherbed\", \"#FFE6E6D0\": \"Light Fern Green\", \"#FFC9CFCC\": \"Light French Grey\", \"#FFC2C0BB\": \"Light French Taupe\", \"#FFE2F4D7\": \"Light Fresh Lime\", \"#FFECF4D2\": \"Light Freshman\", \"#FFEDE8D7\": \"Light Frost\", \"#FFD7EFD5\": \"Light Frosty Dawn\", \"#FFD2D9CD\": \"Light Gentle Calm\", \"#FFD7D3CA\": \"Light Ghosting\", \"#FFF7D28C\": \"Light Ginger Yellow\", \"#FFC0B5AA\": \"Light Glaze\", \"#FFE2DDCF\": \"Light Granite\", \"#FF70AA7C\": \"Light Grass Green\", \"#FF76FF7B\": \"Light Green Tint\", \"#FFD5D8C9\": \"Light Green Alabaster\", \"#FFD7DDCD\": \"Light Green Ash\", \"#FFE5F4D5\": \"Light Green Glint\", \"#FFE8F4D2\": \"Light Green Veil\", \"#FFD4E6D9\": \"Light Green Wash\", \"#FFE2F0D2\": \"Light Greenette\", \"#FFD7D4E4\": \"Light Gregorio Garden\", \"#FFD8DCD6\": \"Light Grey\", \"#FFCDD6EA\": \"Light Hindsight\", \"#FFDCCFCE\": \"Light Hint of Lavender\", \"#FFE5DDCB\": \"Light Hog Bristle\", \"#FFD0D2DE\": \"Light Horizon Sky\", \"#FFD8DED0\": \"Light Iced Aniseed\", \"#FFD0D4E3\": \"Light Iced Lavender\", \"#FFAED4D8\": \"Light Imagine\", \"#FFEFDCBE\": \"Light Incense\", \"#FFE2D9D4\": \"Light Instant\", \"#FFDBE4D1\": \"Light Issey-San\", \"#FFACD6DB\": \"Light Jellyfish Blue\", \"#FFD6EAD8\": \"Light Katsura\", \"#FF998D7C\": \"Light Khaki\", \"#FFD3D2DD\": \"Light Kiri Mist\", \"#FFD6D9CB\": \"Light Lamb\\u2019s Ears\", \"#FFEFC0FE\": \"Light Lavender\", \"#FFE3D2CF\": \"Light Lavender Blush\", \"#FFDDD6E7\": \"Light Lavender Water\", \"#FFBFB6A9\": \"Light Lichen\", \"#FFD9E0D0\": \"Light Ligado\", \"#FFEED2D7\": \"Light Light Blush\", \"#FFD3E7DC\": \"Light Light Lichen\", \"#FFDCC6D2\": \"Light Lilac\", \"#FFD8E6CE\": \"Light Lime Sherbet\", \"#FFDBD5CE\": \"Light Limed White\", \"#FFDAD1D7\": \"Light Limpid Light\", \"#FFE7D9D4\": \"Light Lip Gloss\", \"#FFD8D7CA\": \"Light Livingstone\", \"#FFD1F0DD\": \"Light Lost Lace\", \"#FFDCD5D3\": \"Light Lunette\", \"#FFDBD5DA\": \"Light Magnolia Rose\", \"#FF9B8B7C\": \"Light Mahogany\", \"#FFF6DDCE\": \"Light Maiden\\u2019s Blush\", \"#FFE3DBD0\": \"Light Male\", \"#FFF4DDDB\": \"Light Marshmallow Magic\", \"#FFD1EFDD\": \"Light Martian Moon\", \"#FFC292A1\": \"Light Mauve Variant\", \"#FFCEE1D9\": \"Light Meadow Lane\", \"#FFB6FFBB\": \"Light Mint\", \"#FFDCE1D5\": \"Light Mist\", \"#FFB18673\": \"Light Mocha\", \"#FFDED5E2\": \"Light Modesty\", \"#FFC4D9EB\": \"Light Morality\", \"#FFD8CDD0\": \"Light Mosque\", \"#FFD1CAE1\": \"Light Mulberry\", \"#FFF8611A\": \"Light My Fire\", \"#FFD6E4D4\": \"Light Mystified\", \"#FFFBE6C7\": \"Light Nougat\", \"#FFF4DCDC\": \"Light Nursery\", \"#FFE3D8D4\": \"Light Nut Milk\", \"#FFD2B183\": \"Light Oak\", \"#FFEAF3D0\": \"Light of New Hope\", \"#FFACBF69\": \"Light Olive\", \"#FFC1E8EA\": \"Light Opale\", \"#FFD6CDD0\": \"Light Orchid Haze\", \"#FFCDE7DD\": \"Light Otto Ice\", \"#FFD4CBCE\": \"Light Pale Pearl\", \"#FFDBDACB\": \"Light Pale Tendril\", \"#FFB2FBA5\": \"Light Pastel Green\", \"#FFC0C2B4\": \"Light Patina\", \"#FFD5D3E3\": \"Light Pax\", \"#FFFFE6D8\": \"Light Peach Rose\", \"#FFDCD6D1\": \"Light Pearl Ash\", \"#FFBEC8D8\": \"Light Pearl Soft Blue\", \"#FFE1CED4\": \"Light Pelican Bill\", \"#FFC8D4E7\": \"Light Penna\", \"#FFD0D0D7\": \"Light Pensive\", \"#FFC1C6FC\": \"Light Periwinkle\", \"#FFE0D5CD\": \"Light Perk Up\", \"#FFF0D7D7\": \"Light Petite Pink\", \"#FFECDBD6\": \"Light Pianissimo\", \"#FFCDE5DE\": \"Light Picnic Bay\", \"#FFFFD1DF\": \"Light Pink Tint\", \"#FFDDCED1\": \"Light Pink Linen\", \"#FFE9D3D5\": \"Light Pink Pandora\", \"#FFD8C9CC\": \"Light Pink Polar\", \"#FFE2DEC8\": \"Light Pistachio Tang\", \"#FFC8D8E8\": \"Light Placid Blue\", \"#FFEBE1CB\": \"Light Pollinate\", \"#FFE7DAD7\": \"Light Porcelain\", \"#FFC4D9EF\": \"Light Powder Blue\", \"#FFD1D6EB\": \"Light Powdered Granite\", \"#FFC5D0D9\": \"Light Pre School\", \"#FFD9CED5\": \"Light Puffball\", \"#FFC2A585\": \"Light Pumpkin Brown\", \"#FFC2D2D8\": \"Light Pure Blue\", \"#FFE0D5E9\": \"Light Purity\", \"#FFCDDED7\": \"Light Quaver\", \"#FFFDE1D4\": \"Light Quilt\", \"#FFC6D5EA\": \"Light Radar\", \"#FFDACDB6\": \"Light Raffia\", \"#FFD1C1AA\": \"Light Rattan\", \"#FFECDFCA\": \"Light Raw Cotton\", \"#FFFF7F7F\": \"Light Red\", \"#FFCADDDE\": \"Light Relax\", \"#FFC3D5E5\": \"Light Ridge Light\", \"#FF615544\": \"Light Roast\", \"#FFF4D4D6\": \"Light Rose\", \"#FFF9EBE4\": \"Light Rose Beige\", \"#FFFFCCA5\": \"Light Saffron Orange\", \"#FFB3B0A3\": \"Light Sage\", \"#FFCCF1E3\": \"Light Salome\", \"#FFBBD3DA\": \"Light Salt Spray\", \"#FFDEDCC6\": \"Light Sandbank\", \"#FFE1DACF\": \"Light Sandy Day\", \"#FFB7CDD9\": \"Light Sea Breeze\", \"#FFB9D4E7\": \"Light Sea Cliff\", \"#FFABD6DE\": \"Light Sea Spray\", \"#FFA0FEBF\": \"Light Sea-Foam\", \"#FFA7FFB5\": \"Light Seafoam Green\", \"#FFE0E9D0\": \"Light Security\", \"#FFF1E8CE\": \"Light Shell Haven\", \"#FFFCE0D6\": \"Light Shell Tint\", \"#FFE7DCCF\": \"Light Shetland Lace\", \"#FFA3D4EF\": \"Light Shimmer\", \"#FF8E8887\": \"Light Sh\\u014dchi Black\", \"#FF1155FF\": \"Light Sh\\u014djin Blue\", \"#FFD0181F\": \"Light Sh\\u014drei Red\", \"#FFCBE8DF\": \"Light Short Phase\", \"#FFF7E582\": \"Light Sh\\u014dshin Yellow\", \"#FFAA55EE\": \"Light Sh\\u014dtoku Purple\", \"#FFCEF2E4\": \"Light Shutterbug\", \"#FFD4DBD1\": \"Light Silver Grass\", \"#FFCEE3D9\": \"Light Silverton\", \"#FFA1D0E2\": \"Light Sky Babe\", \"#FFAFCFE0\": \"Light Sky Bus\", \"#FFBAD7DC\": \"Light Sky Chase\", \"#FFC2E3E8\": \"Light Skyway\", \"#FFCFD1D8\": \"Light Slipper Satin\", \"#FFCEDCD4\": \"Light Soft Celadon\", \"#FFCFE0D7\": \"Light Soft Fresco\", \"#FFCFDED7\": \"Light Spearmint Ice\", \"#FFB3A18E\": \"Light Spice\", \"#FFC3CAD3\": \"Light Spirit\", \"#FFD8EEE7\": \"Light Spirited\", \"#FFE0CFD2\": \"Light Sprig Muslin\", \"#FFD6E8D5\": \"Light Spring Burst\", \"#FFE3E3D7\": \"Light Sprinkle\", \"#FFC7D2DD\": \"Light Stargate\", \"#FFCBD0D7\": \"Light Starlight\", \"#FFD2CCD1\": \"Light Stately Frills\", \"#FFDCD1CC\": \"Light Stone\", \"#FFE4DAD3\": \"Light Subpoena\", \"#FFDEEDD4\": \"Light Tactile\", \"#FFB19D8D\": \"Light Taupe Variant\", \"#FFD5D0CB\": \"Light Taupe White\", \"#FFB1CCC5\": \"Light Teal\", \"#FFBBD6EA\": \"Light Template\", \"#FFDF9B81\": \"Light Terracotta\", \"#FFE2D8D4\": \"Light Thought\", \"#FFBCD6E9\": \"Light Tidal Foam\", \"#FFC5D2DF\": \"Light Time Travel\", \"#FFE1D0D8\": \"Light Tip Toes\", \"#FFD0756F\": \"Light Tomato\", \"#FFB08971\": \"Light Topaz Ochre\", \"#FFB5CDD7\": \"Light Topaz Soft Blue\", \"#FFF5ECDF\": \"Light Touch\", \"#FF7EF4CC\": \"Light Turquoise\", \"#FFBFE7EA\": \"Light Vandamint\", \"#FFB8CED9\": \"Light Vanilla Ice\", \"#FFD8D5D0\": \"Light Vanilla Quake\", \"#FFD6B4FC\": \"Light Violet\", \"#FFD4CCCE\": \"Light Wallis\", \"#FFACDCE7\": \"Light Washed Blue\", \"#FFBFD5EB\": \"Light Water Wash\", \"#FFC2F0E6\": \"Light Water Wings\", \"#FFB7DADD\": \"Light Watermark\", \"#FFE6DAD6\": \"Light Watermelon Milk\", \"#FFE0D4D0\": \"Light Weathered Hide\", \"#FF99D0E7\": \"Light Whimsy\", \"#FFCEDCD6\": \"Light White Box\", \"#FFBFBFB4\": \"Light Year\", \"#FFFFFE7A\": \"Light Yellow Variant\", \"#FFC2FF89\": \"Light Yellowish Green\", \"#FFEAD7D5\": \"Light Youth\", \"#FFD1DBD2\": \"Light Zen\", \"#FF75FD63\": \"Lighter Green\", \"#FFDFEBDD\": \"Lighter Mint\", \"#FFDCE4D6\": \"Lightest Sky\", \"#FFF7E0E1\": \"Lighthearted\", \"#FFEDD5DD\": \"Lighthearted Pink\", \"#FFC7A1A9\": \"Lighthearted Rose\", \"#FFF3F4F4\": \"Lighthouse\", \"#FFB4C4CA\": \"Lighthouse Shadows\", \"#FFD9DCD5\": \"Lighthouse View\", \"#FF3D7AFD\": \"Lightish Blue\", \"#FF61E160\": \"Lightish Green\", \"#FFA552E6\": \"Lightish Purple\", \"#FFF0EDA8\": \"Lightly Lime\", \"#FFE5EBE6\": \"Lightning Bolt\", \"#FFEFDE74\": \"Lightning Bug\", \"#FFF8EDD1\": \"Lightning White\", \"#FFF7A233\": \"Lightning Yellow Variant\", \"#FF01968B\": \"Lights at Sea\", \"#FFF8F2DE\": \"Lights of Shibuya\", \"#FF3D474B\": \"Lights Out\", \"#FF15F2FD\": \"Lightsaber Blue\", \"#FFF6E5C5\": \"Lightweight Beige\", \"#FF67765B\": \"Lignum Vit\\u0153 Foliage\", \"#FFD2B18F\": \"Ligonier Tan\", \"#FFD1B7A8\": \"Likeable Sand\", \"#FFCEA2FD\": \"Lilac Variant\", \"#FFD7CDCD\": \"Lilac Ash\", \"#FFC6CDE0\": \"Lilac Bisque\", \"#FFAFABB8\": \"Lilac Bloom\", \"#FF9A93A9\": \"Lilac Blossom\", \"#FF8293AC\": \"Lilac Blue\", \"#FFA590C0\": \"Lilac Breeze\", \"#FFD7BDBE\": \"Lilac Buds\", \"#FF9470C4\": \"Lilac Bush Variant\", \"#FFDFE1E6\": \"Lilac Champagne\", \"#FFDE9BC4\": \"Lilac Chiffon\", \"#FFCDD7EC\": \"Lilac Cotton Candy\", \"#FFCBC5D9\": \"Lilac Crystal\", \"#FF8F939D\": \"Lilac Fields\", \"#FFB2BADB\": \"Lilac Flare\", \"#FFC8A4BF\": \"Lilac Fluff\", \"#FFE8DEEA\": \"Lilac Frost\", \"#FFBB88FF\": \"Lilac Geode\", \"#FFD5B6D4\": \"Lilac Haze\", \"#FFCACBD5\": \"Lilac Hint\", \"#FFA7ADBE\": \"Lilac Hush\", \"#FF9A7EA7\": \"Lilac Intuition\", \"#FFC6A1CF\": \"Lilac Lace\", \"#FFDFCBDA\": \"Lilac Lane\", \"#FFFF3388\": \"Lilac Lotion\", \"#FFC3B9D8\": \"Lilac Lust\", \"#FFC3BABF\": \"Lilac Marble\", \"#FFD6D0D6\": \"Lilac Mauve\", \"#FFE4E4E7\": \"Lilac Mist\", \"#FFE5E6EA\": \"Lilac Murmur\", \"#FFE9E8E5\": \"Lilac Muse\", \"#FFDCBBBA\": \"Lilac Paradise\", \"#FFC09DC8\": \"Lilac Pink\", \"#FFA183C0\": \"Lilac Purple\", \"#FFBD4275\": \"Lilac Rose\", \"#FFABB6D7\": \"Lilac Sachet\", \"#FF9EABD0\": \"Lilac Scent Soft Blue\", \"#FFB6A3A0\": \"Lilac Smoke\", \"#FFDCC0D3\": \"Lilac Snow\", \"#FF8822CC\": \"Lilac Spring\", \"#FFBA9B97\": \"Lilac Suede\", \"#FFD4C7C4\": \"Lilac Tan\", \"#FFA4ABBF\": \"Lilac Time\", \"#FF754A80\": \"Lilac Violet\", \"#FFE9CFE5\": \"Lilacs in Spring\", \"#FFCC99FF\": \"Lil\\u00e1s\", \"#FFD4A1B0\": \"Lili Elbe\\u2019s Pink\", \"#FFC48EFD\": \"Liliac\", \"#FFE1BF03\": \"Lilikoi\", \"#FF874886\": \"Lilikoi Flower Purple\", \"#FF88DD55\": \"Lilliputian Lime\", \"#FFFCEBD8\": \"Lilting Laughter\", \"#FFC19FB3\": \"Lily Variant\", \"#FFEEC7D6\": \"Lily Legs\", \"#FF9191BB\": \"Lily of the Nile\", \"#FFE2E3D6\": \"Lily of the Valley White\", \"#FF818F84\": \"Lily Pad Pond\", \"#FF6DB083\": \"Lily Pads\", \"#FFDEEAD8\": \"Lily Pond\", \"#FF55707F\": \"Lily Pond Blue\", \"#FFE6E6BC\": \"Lily Scent Green\", \"#FFF5DEE2\": \"Lily the Pink\", \"#FFE0E1C1\": \"Lilylock\", \"#FFA9F971\": \"Lima Variant\", \"#FFE1D590\": \"Lima Bean\", \"#FF88BE69\": \"Lima Bean Green\", \"#FFB1B787\": \"Lima Green\", \"#FF7AAC21\": \"Lima Sombrio\", \"#FF988870\": \"Limbert Leather\", \"#FFAAFF32\": \"Lime Tint\", \"#FFF4F2D3\": \"Lime Blossom\", \"#FFDAE3D0\": \"Lime Cake\", \"#FFAAFF00\": \"Lime Candy Pearl\", \"#FFE5DDC8\": \"Lime Chalk\", \"#FFE6EFCC\": \"Lime Coco Cake\", \"#FFD0E3AD\": \"Lime Cream\", \"#FFDDE6D7\": \"Lime Daiquiri\", \"#FFC2ECBC\": \"Lime Dream\", \"#FFEAC13D\": \"Lime Drop\", \"#FFCFE838\": \"Lime Fizz\", \"#FFD2E3CC\": \"Lime Flip\", \"#FFE1ECD9\": \"Lime Glow\", \"#FFDCE1B8\": \"Lime Granita\", \"#FF8EAD2C\": \"Lime Green Variant\", \"#FFCDAEA5\": \"Lime Hawk Moth\", \"#FFD1DD86\": \"Lime Ice\", \"#FF8CA94A\": \"Lime It or Leave It\", \"#FFE3FF00\": \"Lime Jelly\", \"#FFE7E4D3\": \"Lime Juice\", \"#FFE5E896\": \"Lime Juice Green\", \"#FFBEFD73\": \"Lime Lightning\", \"#FFABD35D\": \"Lime Lizard\", \"#FFB4BD7A\": \"Lime Lollipop\", \"#FFE6ECD6\": \"Lime Meringue\", \"#FFDDFFAA\": \"Lime Mist\", \"#FF00FF0D\": \"Lime on Steroides\", \"#FF95C577\": \"Lime Parfait\", \"#FFC6C191\": \"Lime Peel\", \"#FFB6848C\": \"Lime Pink\", \"#FFCCCB2F\": \"Lime Pop\", \"#FFC1DB3B\": \"Lime Popsicle\", \"#FFC0D725\": \"Lime Punch\", \"#FFB5CE08\": \"Lime Rasp\", \"#FFAFB96A\": \"Lime Rickey\", \"#FFCDD78A\": \"Lime Sherbet\", \"#FF1DF914\": \"Lime Shot\", \"#FFF0FDED\": \"Lime Slice\", \"#FF7AF9AB\": \"Lime Soap\", \"#FFBEE5BE\": \"Lime Sorbet\", \"#FFC6CD7D\": \"Lime Sorbet Green\", \"#FFCFDB8D\": \"Lime Splash\", \"#FFDAE1CF\": \"Lime Spritz\", \"#FFBAD1B5\": \"Lime Taffy\", \"#FFEBE734\": \"Lime Time\", \"#FFD8D06B\": \"Lime Tree\", \"#FFC6D624\": \"Lime Twist\", \"#FFE9E4DF\": \"Lime White\", \"#FFD0FE1D\": \"Lime Yellow\", \"#FFDDFF00\": \"Lime Zest\", \"#FFE8E2D0\": \"Lime-Washed\", \"#FF5F9727\": \"Limeade Variant\", \"#FFCFC9C0\": \"Limed White\", \"#FFEEE96B\": \"Limelight\", \"#FFF8B109\": \"Lime\\u00f1o Lim\\u00f3n\", \"#FF76857B\": \"Limerick\", \"#FFE0D4B7\": \"Limescent\", \"#FFF2EABF\": \"Limesicle\", \"#FFDCD8C7\": \"Limestone\", \"#FFA5AF9D\": \"Limestone Green\", \"#FFD6D7DB\": \"Limestone Mauve\", \"#FFCFD9D4\": \"Limestone Path\", \"#FFF9F6DB\": \"Limestone Quarry\", \"#FFC5E0BD\": \"Limestone Slate\", \"#FFA7CCA4\": \"Limestoned\", \"#FF8E9A21\": \"Limetta\", \"#FFDBD5CB\": \"Limewash\", \"#FFBBB875\": \"Liminal Yellow\", \"#FFDAD79B\": \"Liminality\", \"#FFEAECB9\": \"Limited Lime\", \"#FFF0DDB8\": \"Limitless\", \"#FF4B4950\": \"Limo-Scene\", \"#FFF3E0DB\": \"Limoge Pink\", \"#FF243F6C\": \"Limoges\", \"#FF97B73A\": \"Limolicious\", \"#FFF7EB73\": \"Limon\", \"#FFCEBC55\": \"Lim\\u00f3n Fresco\", \"#FF11DD66\": \"Limonana\", \"#FFD6C443\": \"Limone\", \"#FFBE7F51\": \"Limonite\", \"#FF4B4433\": \"Limonite Brown\", \"#FF535F62\": \"Limousine Grey Blue\", \"#FF3B3C3B\": \"Limousine Leather\", \"#FF90DCD9\": \"Limpet Shell\", \"#FFCDC2CA\": \"Limpid Light\", \"#FFFEFC7E\": \"Limuyi Yellow\", \"#FFE3E6DA\": \"Lincolnshire Sausage\", \"#FFC1B76A\": \"Linden Green\", \"#FF8E9985\": \"Linden Spear\", \"#FF229922\": \"Linderhof Garden\", \"#FF172808\": \"Lindworm Green\", \"#FFF8F3DA\": \"Line Dried\", \"#FFF5EDED\": \"Line Dried Sheets\", \"#FF4C3430\": \"Lineage\", \"#FF164975\": \"Linear\", \"#FFD9BCA9\": \"Linen Cloth\", \"#FF466163\": \"Linen Grey\", \"#FFEFEBE3\": \"Linen Ruffle\", \"#FFB4D6E5\": \"Lingerie Blue\", \"#FFE6DEF0\": \"Lingering Lilac\", \"#FF858381\": \"Lingering Storm\", \"#FFFF255C\": \"Lingonberry\", \"#FFA95657\": \"Lingonberry Punch\", \"#FFCE4458\": \"Lingonberry Red\", \"#FF778290\": \"Link\", \"#FF01A049\": \"Link Green\", \"#FF7F7E72\": \"Link Grey\", \"#FFC7CDD8\": \"Link Water Variant\", \"#FF3EAF76\": \"Link\\u2019s Awakening\", \"#FFC2ABC4\": \"Linnea Blossom\", \"#FFC3BCB3\": \"Linnet\", \"#FFFFCCDD\": \"Linnet Egg Red\", \"#FF427C9D\": \"Linoleum Blue\", \"#FF3AA372\": \"Linoleum Green\", \"#FFB0A895\": \"Linseed\", \"#FFADB28D\": \"Lint\", \"#FFC19A62\": \"Lion Variant\", \"#FFF9CDA4\": \"Lion Cub\", \"#FFDD9933\": \"Lion King\", \"#FFDBD1B9\": \"Lion of Hadrian\", \"#FFEEAA66\": \"Lion of Menecrates\", \"#FF81522E\": \"Lion\\u2019s Lair\", \"#FFE8AF49\": \"Lion\\u2019s Mane\", \"#FF946B41\": \"Lion\\u2019s Mane Blonde\", \"#FFF5DAB3\": \"Lion\\u2019s Roar\", \"#FFBB9252\": \"Lion\\u2019s Slumber\", \"#FFE0AF47\": \"Lioness\", \"#FFA3A5AA\": \"Lionfish\", \"#FFE03C28\": \"Lionfish Red\", \"#FFD5B60A\": \"Lionhead\", \"#FFCC2222\": \"Lionheart\", \"#FFDFCDC7\": \"Lip Gloss\", \"#FFD16A68\": \"Lippie\", \"#FFC95B83\": \"Lipstick Variant\", \"#FFD4696D\": \"Lipstick Illusion\", \"#FFBD7F8A\": \"Lipstick Pink\", \"#FFC0022F\": \"Lipstick Red\", \"#FF61394B\": \"Liqueur Red\", \"#FF55B7CE\": \"Liquid Blue\", \"#FF2D3796\": \"Liquid Denim\", \"#FFFDC675\": \"Liquid Gold\", \"#FF3B7A5F\": \"Liquid Green Stuff\", \"#FFCEDFE0\": \"Liquid Hydrogen\", \"#FFF77511\": \"Liquid Lava\", \"#FFCDF80C\": \"Liquid Lime\", \"#FF757A80\": \"Liquid Mercury\", \"#FFC8FF00\": \"Liquid Neon\", \"#FFF3F3F4\": \"Liquid Nitrogen\", \"#FF0A0502\": \"Liquorice\", \"#FF2A4041\": \"Liquorice Green\", \"#FF740900\": \"Liquorice Red\", \"#FF222200\": \"Liquorice Root\", \"#FFB53E3D\": \"Liquorice Stick\", \"#FFE2C28D\": \"Lira\", \"#FFFFFB00\": \"Lisbon Lemon\", \"#FFDD5511\": \"Liselotte Syrup\", \"#FFFFFED8\": \"Lit\", \"#FFD6E8E1\": \"Lit\\u2019l Buoy Blew\", \"#FFE5DFCF\": \"Litewood\", \"#FF53626E\": \"Lithic Sand\", \"#FF9895C5\": \"Litmus\", \"#FFF8B9D4\": \"Little Baby Girl\", \"#FF604B42\": \"Little Bear\", \"#FFB6D3C5\": \"Little Beaux Blue\", \"#FF43484B\": \"Little Black Dress\", \"#FF8AC5BA\": \"Little Blue Box\", \"#FF3C4378\": \"Little Blue Heron\", \"#FFD37C99\": \"Little Bow Pink\", \"#FFC7D8DB\": \"Little Boy Blu\", \"#FF6495DA\": \"Little Boy Blue\", \"#FFE4E6EA\": \"Little Dipper\", \"#FFEBE0CE\": \"Little Dove\", \"#FFFF1414\": \"Little Ladybug\", \"#FFEAE6D7\": \"Little Lamb\", \"#FF6A9A8E\": \"Little League\", \"#FFE0D8DF\": \"Little Lilac\", \"#FF2D454A\": \"Little Mermaid\", \"#FFF4EFED\": \"Little Pinky\", \"#FFA6D1EB\": \"Little Pond\", \"#FFE6AAC1\": \"Little Princess\", \"#FFE50102\": \"Little Red Corvette\", \"#FFF8D0E8\": \"Little Smile\", \"#FFDAE9D6\": \"Little Sprout\", \"#FFF7C85F\": \"Little Sun Dress\", \"#FF73778F\": \"Little Theatre\", \"#FFE7CFE8\": \"Little Touch\", \"#FFA4A191\": \"Little Valley\", \"#FF87819B\": \"Live Jazz\", \"#FFCECEBD\": \"Liveable Green\", \"#FFFFDFB9\": \"Liveliness\", \"#FFE67C7A\": \"Lively Coral\", \"#FFB3AE87\": \"Lively Ivy\", \"#FFE1DD8E\": \"Lively Laugh\", \"#FF816F7A\": \"Lively Lavender\", \"#FFA18899\": \"Lively Light\", \"#FF9096B7\": \"Lively Lilac\", \"#FFBEB334\": \"Lively Lime\", \"#FFC8D8E5\": \"Lively Tune\", \"#FFF7F3E0\": \"Lively White\", \"#FFFFE9B1\": \"Lively Yellow\", \"#FF654A46\": \"Liver Variant\", \"#FF513E32\": \"Liver Brown\", \"#FFA8D275\": \"Livery Green\", \"#FF6688CC\": \"Livid\", \"#FF312A29\": \"Livid Brown Variant\", \"#FFB8E100\": \"Livid Lime\", \"#FFFF6A52\": \"Living Coral\", \"#FFC87163\": \"Living Large\", \"#FF37708C\": \"Living Stream\", \"#FFA39880\": \"Livingston\", \"#FFCBCBBB\": \"Livingstone\", \"#FF7B6943\": \"Lizard\", \"#FFCCCC33\": \"Lizard Belly\", \"#FFEDBB32\": \"Lizard Breath\", \"#FF795419\": \"Lizard Brown\", \"#FF7F6944\": \"Lizard Legs\", \"#FF917864\": \"Llama Wool\", \"#FFC35B99\": \"Llilacquered\", \"#FFDBD9C2\": \"Loafer Variant\", \"#FF443724\": \"Loam\", \"#FF9FC8B2\": \"Lobaria Lichen\", \"#FFA780B2\": \"Lobby Lilac\", \"#FF7498BE\": \"Lobelia\", \"#FFB3BBB7\": \"Loblolly Variant\", \"#FFBB240C\": \"Lobster\", \"#FFDB8981\": \"Lobster Bisque\", \"#FFA73836\": \"Lobster Brown\", \"#FFCC8811\": \"Lobster Butter Sauce\", \"#FFCB9E34\": \"Local Curry\", \"#FF609795\": \"Loch Blue\", \"#FFDFE5BF\": \"Loch Modan Moss\", \"#FF5F6DB0\": \"Loch Ness\", \"#FF489084\": \"Lochinvar Variant\", \"#FF316EA0\": \"Lochmara Variant\", \"#FFBE9AA2\": \"Lockhart\", \"#FF988171\": \"Locomotion\", \"#FFA2A580\": \"Locust Variant\", \"#FF7D6546\": \"Loden Blanket\", \"#FF788F74\": \"Loden Frost\", \"#FF747A59\": \"Loden Green\", \"#FF553A76\": \"Loden Purple\", \"#FFB68B13\": \"Loden Yellow\", \"#FFACA690\": \"Lodgepole Pines\", \"#FFDCCAB7\": \"Loft Light\", \"#FFCBCECD\": \"Loft Space\", \"#FFD9A9C6\": \"Lofty Delight\", \"#FF705A46\": \"Log Cabin Variant\", \"#FF9D9CB4\": \"Logan Variant\", \"#FF5F4B6F\": \"Loganberry\", \"#FFC4B7A5\": \"Loggia\", \"#FFE1EBDE\": \"Loggia Lights\", \"#FF577042\": \"Loire Valley\", \"#FFE7CD8B\": \"Lol Yellow\", \"#FFB9ACBB\": \"Lola Variant\", \"#FFBF2735\": \"Lolita\", \"#FFD91E3F\": \"Lollipop\", \"#FFFD978F\": \"Lolly\", \"#FFA6DAD0\": \"Lolly Ice\", \"#FFCDCCCF\": \"London Calling\", \"#FFBAB0AC\": \"London Coach\", \"#FF9D988C\": \"London Fog\", \"#FF666677\": \"London Grey\", \"#FFAE94AB\": \"London Hue Variant\", \"#FFD1DCE4\": \"London Lights\", \"#FF0055BB\": \"London Rain\", \"#FF7F878A\": \"London Road\", \"#FF7F909D\": \"London Square\", \"#FFA89F94\": \"London Stones\", \"#FF94C84C\": \"Lone Hunter\", \"#FF575A44\": \"Lone Pine\", \"#FF4A0A00\": \"Lonely Chocolate\", \"#FF947754\": \"Lonely Road\", \"#FF522426\": \"Lonestar Variant\", \"#FFFAEFDF\": \"Long Beach\", \"#FFA1759C\": \"Long Forgotten Purple\", \"#FF95D0FC\": \"Long Island Sound\", \"#FF68757E\": \"Long Lake\", \"#FFC97586\": \"Long Spring\", \"#FF425A5E\": \"Long Water\", \"#FF002277\": \"Long-Haul Flight\", \"#FFBD7A33\": \"Longan\", \"#FF442117\": \"Longan\\u2019s Kernel\", \"#FFCECEAF\": \"Longbeard Grey\", \"#FF60513A\": \"Longboat\", \"#FF90B1A3\": \"Longfellow\", \"#FFD88E5F\": \"Longhorn\", \"#FF4B9F5D\": \"Longing for Nature\", \"#FFADD5E4\": \"Longitude\", \"#FFEBD84B\": \"Longlure Frogfish\", \"#FF77928A\": \"Longmeadow\", \"#FFE3D3B5\": \"Loofah\", \"#FFFEBF01\": \"Look at the Bright Side\", \"#FF888786\": \"Looking Glass\", \"#FF454151\": \"Loom of Fate\", \"#FF2E6676\": \"Loon Turquoise\", \"#FF11FFFF\": \"Looney Blue\", \"#FFCBC0B3\": \"Loophole\", \"#FF84613D\": \"Loose Leather\", \"#FFAE7C4F\": \"Loquat Brown\", \"#FFB76764\": \"Lord Baltimore\", \"#FF664488\": \"Lords of the Night\", \"#FF50702D\": \"Loren Forest\", \"#FF8EBCBD\": \"Lorian\", \"#FF658477\": \"Lorna\", \"#FF8D9CA7\": \"Lost at Sea\", \"#FF5F7388\": \"Lost Atlantis\", \"#FF998E7A\": \"Lost Canyon\", \"#FF74AF54\": \"Lost Golfer\", \"#FF002489\": \"Lost in Heaven\", \"#FFDEE8E1\": \"Lost in Istanbul\", \"#FF151632\": \"Lost in Sadness\", \"#FF03386A\": \"Lost in Space\", \"#FF014426\": \"Lost in the Woods\", \"#FF9FAFBD\": \"Lost in Time\", \"#FFC2EBD1\": \"Lost Lace\", \"#FFB5ADB5\": \"Lost Lake\", \"#FF8D828C\": \"Lost Lavender Somewhere\", \"#FFE5D7D4\": \"Lost Love\", \"#FF929591\": \"Lost Soul Grey\", \"#FF969389\": \"Lost Space\", \"#FF887A6E\": \"Lost Summit\", \"#FFFEFDFA\": \"Lotion\", \"#FFE5ECB7\": \"Lots of Bubbles\", \"#FF768371\": \"Lottery Winnings\", \"#FFE40046\": \"Lotti Red\", \"#FF8B504B\": \"Lotus Variant\", \"#FFF4F0DA\": \"Lotus Flower\", \"#FF93A79E\": \"Lotus Leaf\", \"#FFF2E9DC\": \"Lotus Petal\", \"#FFE7D7C2\": \"Lotus Pod\", \"#FFD1717B\": \"Lotus Red\", \"#FF64EB65\": \"Loud Green\", \"#FF88FF22\": \"Loud Lime\", \"#FFD92FB4\": \"Loudicious Pink\", \"#FF655856\": \"Louisiana Mud\", \"#FF4C3347\": \"Loulou Variant\", \"#FFBB2288\": \"Loulou\\u2019s Purple\", \"#FF8BA97F\": \"Lounge Green\", \"#FF563E31\": \"Lounge Leather\", \"#FF5E336D\": \"Lounge Violet\", \"#FFDDC3A4\": \"Louvre\", \"#FFC87570\": \"Lovable\", \"#FF98B1A6\": \"Lovage Green\", \"#FFFFBEC8\": \"Love Affair\", \"#FFE5A5B1\": \"Love at First Sight\", \"#FFC6D0E3\": \"Love Crystal\", \"#FFEB94DA\": \"Love Dust\", \"#FFCD0106\": \"Love for All\", \"#FFFDD0D5\": \"Love Fumes\", \"#FFCD0D0D\": \"Love Goddess\", \"#FFE1B9C2\": \"Love in a Mist\", \"#FFCC1155\": \"Love Juice\", \"#FFE4658E\": \"Love Letter\", \"#FFC54673\": \"Love Lord\", \"#FFA06582\": \"Love Poem\", \"#FFCE145E\": \"Love Potion\", \"#FFBB55CC\": \"Love Priestess\", \"#FFFF496C\": \"Love Red\", \"#FFDD8877\": \"Love Sceptre\", \"#FFF8B4C4\": \"Love Spell\", \"#FFCE1D51\": \"Love Surge\", \"#FFEE0099\": \"Love Vessel\", \"#FFAEAEB7\": \"Love-Struck Chinchilla\", \"#FFF0C1C6\": \"Loveable\", \"#FFC76A77\": \"Lovebirds\", \"#FFC8ABA8\": \"Lovebug\", \"#FFEEBBEE\": \"Lovecloud\", \"#FFE6718D\": \"Loveland\", \"#FFA69A5C\": \"Loveliest Leaves\", \"#FFF7D6D8\": \"Lovelight\", \"#FFE2D0B3\": \"Lovely Bluff\", \"#FFF9D8E4\": \"Lovely Breeze\", \"#FFFFEEFF\": \"Lovely Euphoric Delight\", \"#FFF4DBDC\": \"Lovely Harmony\", \"#FFD6D2DD\": \"Lovely Lavender\", \"#FFE9DD22\": \"Lovely Lemonade\", \"#FFA7B0CC\": \"Lovely Lilac\", \"#FFDBCEAC\": \"Lovely Linen\", \"#FFE35F66\": \"Lovely Little Rosy\", \"#FFD8BFD4\": \"Lovely Pink\", \"#FFD0C6B5\": \"Lover\\u2019s Hideaway\", \"#FF8F3B3D\": \"Lover\\u2019s Kiss\", \"#FFF2DBDB\": \"Lover\\u2019s Knot\", \"#FF957E68\": \"Lover\\u2019s Leap\", \"#FFF4CED8\": \"Lover\\u2019s Retreat\", \"#FFB48CA3\": \"Lover\\u2019s Tryst\", \"#FF5A6141\": \"Lovers Pine\", \"#FF6A2E36\": \"Lovestruck\", \"#FF99D1A4\": \"Low Tide\", \"#FFE0EFE3\": \"Lower Green\", \"#FFDCDFEF\": \"Lower Lavender\", \"#FFE2D6D8\": \"Lower Lilac\", \"#FFE6F1DE\": \"Lower Lime\", \"#FFE0DCD8\": \"Lower Linen\", \"#FFEC9079\": \"Lox\", \"#FF01455E\": \"Loyal Blue\", \"#FF4E6175\": \"Loyalty\", \"#FF02C14D\": \"L\\u01dc S\\u00e8 Green\", \"#FF989746\": \"Luau Green\", \"#FF0B83B5\": \"Lucario Blue\", \"#FF7CAFE1\": \"Lucea\", \"#FF00FF33\": \"Lucent Lime\", \"#FFE4D0A5\": \"Lucent Yellow\", \"#FF77B87C\": \"Lucerne\", \"#FF7E8D9F\": \"Lucid Blue\", \"#FF632F92\": \"Lucid Dreams\", \"#FF1E4469\": \"Lucidity\", \"#FFA6BBB7\": \"Lucinda\", \"#FFBAA2CE\": \"Lucius Lilac\", \"#FF547839\": \"Luck of the Irish\", \"#FFAB9A1C\": \"Lucky Variant\", \"#FF93834B\": \"Lucky Bamboo\", \"#FF008400\": \"Lucky Clover\", \"#FF929A7D\": \"Lucky Day\", \"#FFD3C8BA\": \"Lucky Dog\", \"#FFF4ECD7\": \"Lucky Duck\", \"#FF238652\": \"Lucky Green\", \"#FF777777\": \"Lucky Grey\", \"#FFCC3322\": \"Lucky Lobster\", \"#FFFF7700\": \"Lucky Orange\", \"#FFBC6F37\": \"Lucky Penny\", \"#FF292D4F\": \"Lucky Point Variant\", \"#FFEFEAD8\": \"Lucky Potato\", \"#FF487A7B\": \"Lucky Shamrock\", \"#FFFAD9DA\": \"Lucky You\", \"#FF91B2BC\": \"Lucy Blue\", \"#FFBB8877\": \"Ludicrous Lemming\", \"#FFEBDAC0\": \"Ludlow Beige\", \"#FFF7A58B\": \"Lugganath Orange\", \"#FFC3D5E8\": \"Lull Wind\", \"#FFCBD4D4\": \"Lullaby\", \"#FFFFE4CD\": \"Lumber\", \"#FF9D4542\": \"Lumberjack\", \"#FFFFFEED\": \"Luminary\", \"#FFDEE799\": \"Luminary Green\", \"#FFA4DDE9\": \"Luminescent Blue\", \"#FF769C18\": \"Luminescent Green\", \"#FFB9FF66\": \"Luminescent Lime\", \"#FFCAFFFB\": \"Luminescent Sky\", \"#FFECBF55\": \"Luminous Apricot\", \"#FFBF8FE5\": \"Luminous Lavender\", \"#FFBBAEB9\": \"Luminous Light\", \"#FFCDDED5\": \"Luminous Mist\", \"#FFDC6C84\": \"Luminous Pink\", \"#FFFEE37F\": \"Luminous Yellow\", \"#FF4E5154\": \"Lump of Coal\", \"#FFD4D8CE\": \"Luna\", \"#FFC1E0C8\": \"Luna Green\", \"#FFC2CECA\": \"Luna Light\", \"#FFECEAE1\": \"Luna Moon\", \"#FF70C1C9\": \"Luna Moona\", \"#FF414D62\": \"Luna Pier\", \"#FF686B67\": \"Lunar Basalt\", \"#FF878786\": \"Lunar Base\", \"#FFCCCCDD\": \"Lunar Dust\", \"#FF415053\": \"Lunar Eclipse\", \"#FF868381\": \"Lunar Federation\", \"#FF4E5541\": \"Lunar Green Variant\", \"#FFDECE9E\": \"Lunar Lander\", \"#FFD2CFC1\": \"Lunar Landing\", \"#FF938673\": \"Lunar Launch Site\", \"#FF9B959C\": \"Lunar Light\", \"#FFFBF4D6\": \"Lunar Luxury\", \"#FF828287\": \"Lunar Outpost\", \"#FFCACED2\": \"Lunar Rays\", \"#FFC5C5C5\": \"Lunar Rock\", \"#FF707685\": \"Lunar Shadow\", \"#FFB6B9B6\": \"Lunar Surface\", \"#FF6F968B\": \"Lunar Tide\", \"#FFF7E7CD\": \"Lunaria\", \"#FFDDAA88\": \"Lunatic Lynx\", \"#FF76FDA8\": \"Lunatic Sky Dancer\", \"#FFF2CA95\": \"Lunch Box\", \"#FFD0C8C6\": \"Lunette\", \"#FFD1E0E9\": \"Lupin Grey\", \"#FFBE9CC1\": \"Lupine\", \"#FF6A96BA\": \"Lupine Blue\", \"#FFB4F319\": \"Lurid Lettuce\", \"#FFFF33EE\": \"Lurid Pink\", \"#FFFF4505\": \"Lurid Red\", \"#FF903D49\": \"Luscious\", \"#FF049945\": \"Luscious Green\", \"#FFD7C8A4\": \"Luscious Latte\", \"#FF696987\": \"Luscious Lavender\", \"#FFBBCC22\": \"Luscious Leek\", \"#FFEEBD6A\": \"Luscious Lemon\", \"#FF517933\": \"Luscious Lemongrass\", \"#FF91A673\": \"Luscious Lime\", \"#FFC5847C\": \"Luscious Lobster\", \"#FF605C71\": \"Luscious Purple\", \"#FFC5BDA0\": \"Lush\", \"#FF004466\": \"Lush Aqua\", \"#FFAFBB33\": \"Lush Bamboo\", \"#FF88AA77\": \"Lush Fields\", \"#FF008811\": \"Lush Garden\", \"#FF468D45\": \"Lush Grass\", \"#FFBBEE00\": \"Lush Green\", \"#FF7FF23E\": \"Lush Greenery\", \"#FF7A9461\": \"Lush Highlands\", \"#FFFCA81B\": \"Lush Honeycomb\", \"#FF6C765C\": \"Lush Hosta\", \"#FFE9F6E0\": \"Lush Life\", \"#FF9D7EB7\": \"Lush Lilac\", \"#FFA091B7\": \"Lush Mauve\", \"#FF007351\": \"Lush Meadow\", \"#FF2E7D32\": \"Lush Paradise\", \"#FF22BB22\": \"Lush Plains\", \"#FF7B8476\": \"Lush Sage\", \"#FF54A64D\": \"Lush Un\\u2019goro Crater\", \"#FFE62020\": \"Lust\", \"#FFBB3388\": \"Lust Priestess\", \"#FFCC4499\": \"Lustful Wishes\", \"#FFBECE61\": \"Lustre Green\", \"#FFF4F1EC\": \"Lustre White\", \"#FF415A09\": \"Lustrian Undergrowth\", \"#FFE6DA78\": \"Lustrous Yellow\", \"#FF8D5EB7\": \"Lusty Lavender\", \"#FFD5174E\": \"Lusty Lips\", \"#FF00BB11\": \"Lusty Lizard\", \"#FFE26D28\": \"Lusty Orange\", \"#FFB1383D\": \"Lusty Red\", \"#FFEFAFA7\": \"Lusty Salmon\", \"#FFFFCCCC\": \"Lusty-Gallant\", \"#FF516582\": \"Luxe Blue\", \"#FFC3BAB0\": \"Luxe Grey\", \"#FFA8A3B1\": \"Luxe Lilac\", \"#FFBDE9E5\": \"Luxor Blue\", \"#FFAB8D3F\": \"Luxor Gold Variant\", \"#FFD4B75D\": \"Luxurious\", \"#FF365F8C\": \"Luxurious Blue\", \"#FF88EE22\": \"Luxurious Lime\", \"#FF863A42\": \"Luxurious Red\", \"#FF818EB1\": \"Luxury\", \"#FF384172\": \"Lviv Blue\", \"#FF0182CC\": \"Lvivian Rain\", \"#FFADCF43\": \"Lyceum\", \"#FFCD0C41\": \"Lychee\", \"#FFC3A5A5\": \"Lychee Berry\", \"#FFF7F2DA\": \"Lychee Pulp\", \"#FF9E9478\": \"Lye\", \"#FF7F6B5D\": \"Lye Tinted\", \"#FFE5C7B9\": \"Lyman Camellia\", \"#FF697D89\": \"Lynch Variant\", \"#FF604D47\": \"Lynx\", \"#FF2CB1EB\": \"Lynx Screen Blue\", \"#FFF7F7F7\": \"Lynx White\", \"#FF005E76\": \"Lyons Blue\", \"#FF0087AD\": \"Lyrebird\", \"#FF728791\": \"Lyric Blue\", \"#FF72696F\": \"Lythrum\", \"#FFB4023D\": \"M. Bison\", \"#FFF4F7FD\": \"M\\u0101 White\", \"#FF001C3D\": \"Maastricht Blue\", \"#FFCBE8E8\": \"Mabel Variant\", \"#FFE4B070\": \"Mac N Cheese\", \"#FF880033\": \"Macabre\", \"#FFE1CCAF\": \"Macadamia\", \"#FFF7DFBA\": \"Macadamia Beige\", \"#FFBBA791\": \"Macadamia Brown\", \"#FFEEE3DD\": \"Macadamia Nut\", \"#FFF3D085\": \"Macaroni\", \"#FFB38B71\": \"Macaroon\", \"#FFFEE8D6\": \"Macaroon Cream\", \"#FFF75280\": \"Macaroon Rose\", \"#FF46C299\": \"Macau\", \"#FFFFBD24\": \"Macaw\", \"#FF9CAD3B\": \"Macaw Green\", \"#FF928168\": \"Macchiato\", \"#FFDD4400\": \"Macharius Solar Orange\", \"#FFA6A23F\": \"Machine Green\", \"#FF454545\": \"Machine Gun Metal\", \"#FFF1E782\": \"Machine Oil\", \"#FF9999AA\": \"Machinery\", \"#FF99BB33\": \"Machu Picchu Gardens\", \"#FFBFAE5B\": \"Mack Creek\", \"#FF007D82\": \"Macquarie\", \"#FF004577\": \"Macragge Blue\", \"#FFADA5A3\": \"Maculata Bark\", \"#FFEDA69E\": \"Mad About Maddie\", \"#FF94508E\": \"Mad About Magenta\", \"#FFA9324B\": \"Mad About You\", \"#FFF8A200\": \"Mad for Mango\", \"#FF9D8544\": \"Madagascar\", \"#FFD194A1\": \"Madagascar Pink\", \"#FF7CA7CB\": \"Madam Butterfly\", \"#FFB5ADB4\": \"Madame Mauve\", \"#FFB7E3A8\": \"Madang Variant\", \"#FF754C50\": \"Madder\", \"#FFB5B6CE\": \"Madder Blue\", \"#FF783738\": \"Madder Brown\", \"#FF80496E\": \"Madder Magenta\", \"#FFF1BEB0\": \"Madder Orange\", \"#FFB7282E\": \"Madder Red\", \"#FFEEBBCB\": \"Madder Rose\", \"#FF6B717A\": \"Made in the Shade\", \"#FF5B686F\": \"Made of Steel\", \"#FF8F4826\": \"Madeira Brown\", \"#FFF504C9\": \"Mademoiselle Pink\", \"#FFEED09D\": \"Madera\", \"#FF2D3C54\": \"Madison Variant\", \"#FF3D3E3E\": \"Madison Avenue\", \"#FF3F4250\": \"Madonna\", \"#FF71B5D1\": \"Madonna Blue\", \"#FFEEE6DB\": \"Madonna Lily\", \"#FF473E23\": \"Madras Variant\", \"#FF9AC3DA\": \"Madras Blue\", \"#FFECBF9F\": \"Madrid Beige\", \"#FF8F003A\": \"Madrile\\u00f1o Maroon\", \"#FFAA44DD\": \"Magenta Affair\", \"#FFFF55A3\": \"Magenta Crayon\", \"#FFDE0170\": \"Magenta Elephant\", \"#FFED24ED\": \"Magenta Fizz\", \"#FFA44775\": \"Magenta Haze\", \"#FF513D3C\": \"Magenta Ink\", \"#FF983166\": \"Magenta Manicure\", \"#FFB4559B\": \"Magenta Memoir\", \"#FFCC338B\": \"Magenta Pink\", \"#FF762A54\": \"Magenta Purple\", \"#FF913977\": \"Magenta Red\", \"#FF62416D\": \"Magenta Red Lips\", \"#FFFA5FF7\": \"Magenta Stream\", \"#FFBB989F\": \"Magenta Twilight\", \"#FF6C5389\": \"Magenta Violet\", \"#FFD521B8\": \"Magentella\", \"#FFAA11AA\": \"Magentle\", \"#FFAA22BB\": \"Magentleman\", \"#FFBF3CFF\": \"Magento\", \"#FFDDEEE2\": \"Maggie\\u2019s Magic\", \"#FF656B78\": \"Magic\", \"#FF44DD00\": \"Magic Blade\", \"#FF3E8BAA\": \"Magic Blue\", \"#FF9488BE\": \"Magic Carpet\", \"#FF817C85\": \"Magic Dust\", \"#FF1F75FF\": \"Magic Fountain\", \"#FF8E7282\": \"Magic Gem\", \"#FFC2A260\": \"Magic Lamp\", \"#FF7F4774\": \"Magic Magenta\", \"#FFA5887E\": \"Magic Malt\", \"#FFDE9851\": \"Magic Melon\", \"#FF3F3925\": \"Magic Metal\", \"#FF757CAF\": \"Magic Moment\", \"#FF717462\": \"Magic Mountain\", \"#FF3A3B5B\": \"Magic Night\", \"#FFFF4466\": \"Magic Potion\", \"#FF598556\": \"Magic Sage\", \"#FFE0D2BA\": \"Magic Sail\", \"#FFCCC9D7\": \"Magic Scent\", \"#FF544F66\": \"Magic Spell\", \"#FFC3D9E4\": \"Magic Wand\", \"#FF17034A\": \"Magic Whale\", \"#FFC1CEDA\": \"Magical\", \"#FFFF7A8F\": \"Magical Girl\", \"#FF22CC88\": \"Magical Malachite\", \"#FFBAA3A9\": \"Magical Mauve\", \"#FFE9E9D0\": \"Magical Melon\", \"#FF3D8ED0\": \"Magical Merlin\", \"#FFF0EEEB\": \"Magical Moonlight\", \"#FFEAEADB\": \"Magical Stardust\", \"#FF784467\": \"Magician\\u2019s Cloak\", \"#FFFF4E01\": \"Magma\", \"#FFDD0066\": \"Magna Cum Laude\", \"#FF64BFDC\": \"Magnesia Bay\", \"#FFC1C2C3\": \"Magnesium\", \"#FF525054\": \"Magnet\", \"#FF697987\": \"Magnet Dapple\", \"#FFB2B5AF\": \"Magnetic\", \"#FF054C8A\": \"Magnetic Blue\", \"#FF2B6867\": \"Magnetic Green\", \"#FF838789\": \"Magnetic Grey\", \"#FF3FBBB2\": \"Magnetic Magic\", \"#FFAA1D8E\": \"Magneto\\u2019s Magenta\", \"#FF7F556F\": \"Magnificence\", \"#FFEE22AA\": \"Magnificent Magenta\", \"#FFAE8D7B\": \"Magnitude\", \"#FFFFF9E4\": \"Magnolia Tint\", \"#FFF4E7CE\": \"Magnolia Blossom\", \"#FFF7EEE3\": \"Magnolia Petal\", \"#FFECB9B3\": \"Magnolia Pink\", \"#FFF6E6CB\": \"Magnolia Spray\", \"#FFF4F2E7\": \"Magnolia Spring\", \"#FFD8BFC8\": \"Magnolia White\", \"#FF003686\": \"Magnus Blue\", \"#FF69475A\": \"Magos\", \"#FF4C4B45\": \"Magpie\", \"#FF3F354F\": \"Maharaja\", \"#FF812308\": \"Mahogany Brown\", \"#FFAA5511\": \"Mahogany Finish\", \"#FFC39D90\": \"Mahogany Rose\", \"#FF5B4646\": \"Mahogany Spice\", \"#FF62788E\": \"Mahonia Berry Blue\", \"#FFA56531\": \"Mai Tai Variant\", \"#FFF5E9CA\": \"Maiden Hair\", \"#FFEFDCEB\": \"Maiden of the Mist\", \"#FFFF2FEB\": \"Maiden Pink\", \"#FF8AC7D4\": \"Maiden Voyage\", \"#FFF3D3BF\": \"Maiden\\u2019s Blush\", \"#FF44764A\": \"Maidenhair Fern\", \"#FFD8BAA6\": \"Maiko\", \"#FFB79400\": \"Main Mast Gold\", \"#FFC2792B\": \"Maine Coon Orange\", \"#FFA95249\": \"Maine-Anjou Cattle\", \"#FFD9DFE2\": \"Mainsail\", \"#FF2A2922\": \"Maire\", \"#FFD7D8DC\": \"Mais Oui\", \"#FFDFD2BF\": \"Maison Blanche\", \"#FFBB9B7D\": \"Maison de Campagne\", \"#FFE5F0D9\": \"Maison Verte\", \"#FFF4D054\": \"Maize Variant\", \"#FFFBEC5E\": \"Maizena\", \"#FF5D4250\": \"Majestic\", \"#FF3F425C\": \"Majestic Blue\", \"#FFF3BC80\": \"Majestic Dune\", \"#FF443388\": \"Majestic Eggplant\", \"#FFAD9A84\": \"Majestic Elk\", \"#FF7D8878\": \"Majestic Evergreen\", \"#FF607535\": \"Majestic Jungle\", \"#FFEE4488\": \"Majestic Magenta\", \"#FF555570\": \"Majestic Magic\", \"#FF7C8091\": \"Majestic Mount\", \"#FF447788\": \"Majestic Mountain\", \"#FF8D576D\": \"Majestic Orchid\", \"#FF806173\": \"Majestic Plum\", \"#FF65608C\": \"Majestic Purple\", \"#FFF2E9A5\": \"Majestic Treasures\", \"#FF9D9AC4\": \"Majestic Violet\", \"#FF673E6E\": \"Majesty\", \"#FFFFAACC\": \"Majin B\\u016b Pink\", \"#FF2D4B65\": \"Majolica Blue\", \"#FF976352\": \"Majolica Earthenware\", \"#FFAEB08F\": \"Majolica Green\", \"#FFA08990\": \"Majolica Mauve\", \"#FF289EC4\": \"Major Blue\", \"#FF61574E\": \"Major Brown\", \"#FFF246A7\": \"Major Magenta\", \"#FF001177\": \"Major Tom\", \"#FF4A9C95\": \"Majorca Blue\", \"#FF808337\": \"Majorca Green\", \"#FF337766\": \"Majorelle Gardens\", \"#FF695F50\": \"Makara Variant\", \"#FF335F8D\": \"Make-Up Blue\", \"#FF88BB55\": \"Makin It Rain\", \"#FF505555\": \"Mako Variant\", \"#FF6E2F2C\": \"Makore Veneer Red\", \"#FF688C43\": \"Makrut Lime\", \"#FFCFBEA9\": \"Malabar\", \"#FF0E4F4F\": \"Malachite Blue Turquoise\", \"#FF004E00\": \"Malachite Green\", \"#FFAB5871\": \"Malaga\", \"#FF6E7D6E\": \"Malarca\", \"#FFB8D1D0\": \"Malaysian Mist\", \"#FF00BBDD\": \"Maldives\", \"#FFD6CEC3\": \"Male\", \"#FF347699\": \"Male Betta\", \"#FFBB6688\": \"Malevolent Mauve\", \"#FF66B7E1\": \"Malibu Variant\", \"#FFC9C0B1\": \"Malibu Beige\", \"#FF00A9DA\": \"Malibu Blue\", \"#FFE7CFC2\": \"Malibu Coast\", \"#FFE7CEB5\": \"Malibu Dune\", \"#FFFDC8B3\": \"Malibu Peach\", \"#FFFFF2D9\": \"Malibu Sun\", \"#FF254855\": \"Mallard Variant\", \"#FF3F6378\": \"Mallard Blue\", \"#FF478865\": \"Mallard Green\", \"#FF91B9C2\": \"Mallard Lake\", \"#FFF8F2D8\": \"Mallard\\u2019s Egg\", \"#FF3A4531\": \"Mallardish\", \"#FF517B95\": \"Mallorca Blue\", \"#FFF8EBDE\": \"Mallow Root\", \"#FFA7D7FF\": \"Malm\\u00f6 FF\", \"#FFDDCFBC\": \"Malt\", \"#FFBBA87F\": \"Malt Shake\", \"#FFA59784\": \"Malta Variant\", \"#FFDBC8C0\": \"Malted\", \"#FFE8D9CE\": \"Malted Milk\", \"#FFBFD6C8\": \"Malted Mint\", \"#FF11DDAA\": \"Malted Mint Madness\", \"#FF551111\": \"Mama Africa\", \"#FF594F40\": \"Mama Racoon\", \"#FF005E8C\": \"Mamala Bay\", \"#FF766D7C\": \"Mamba Variant\", \"#FF77AD3B\": \"Mamba Green\", \"#FFFDD014\": \"Mamba Yellow\", \"#FFEBA180\": \"Mamey\", \"#FFB00B1E\": \"Mammary Red\", \"#FF3B6A7A\": \"Mammoth Mountain\", \"#FF995522\": \"Mammoth Wool\", \"#FF816045\": \"Man Cave\", \"#FF3C4C5D\": \"Man Friday\", \"#FFB09737\": \"Mana\", \"#FF94BBDA\": \"Manakin\", \"#FF65916D\": \"Manchester\", \"#FF504440\": \"Manchester Brown\", \"#FF992222\": \"Manchester Nights\", \"#FFB57B2E\": \"Mandalay Variant\", \"#FFA05F45\": \"Mandalay Road\", \"#FFEE9944\": \"Mandarin Essence\", \"#FFFF8800\": \"Mandarin Jelly\", \"#FFEC6A37\": \"Mandarin Orange\", \"#FFE84F3C\": \"Mandarin Red\", \"#FFF1903D\": \"Mandarin Rind\", \"#FFF6E7E1\": \"Mandarin Sugar\", \"#FFD8D4D3\": \"Mandarin Tusk\", \"#FF97691E\": \"Mandolin\", \"#FF8889A0\": \"Mandrake\", \"#FFC6C0A6\": \"Mandu Dumpling\", \"#FFCD525B\": \"Mandy Variant\", \"#FFF5B799\": \"Mandys Pink\", \"#FFF5B9D8\": \"Manga Pink\", \"#FFE781A6\": \"Mangala Pink\", \"#FF202F4B\": \"Manganese Black\", \"#FF9DBCD4\": \"M\\u00e5ngata\", \"#FFFFA62B\": \"Mango Variant\", \"#FFBB8434\": \"Mango Brown\", \"#FFFBEDDA\": \"Mango Cheesecake\", \"#FFFFB769\": \"Mango Creamsicles\", \"#FF96FF00\": \"Mango Green\", \"#FFF7BD8D\": \"Mango Ice\", \"#FFFFBB4D\": \"Mango Latte\", \"#FFFEB81C\": \"Mango Loco\", \"#FFFD8C23\": \"Mango Madness\", \"#FFF7B74E\": \"Mango Margarita\", \"#FFD1A229\": \"Mango Mojito\", \"#FFFFD49D\": \"Mango Nectar\", \"#FFFF8B58\": \"Mango Orange\", \"#FFFFB066\": \"Mango Salsa\", \"#FF8E6C39\": \"Mango Squash\", \"#FF383E5D\": \"Mangosteen\", \"#FF3A2732\": \"Mangosteen Violet\", \"#FF757461\": \"Mangrove\", \"#FF607C3D\": \"Mangrove Leaf\", \"#FF292938\": \"Mangu Black\", \"#FFB2896C\": \"Mangy Moose\", \"#FFE2AF80\": \"Manhattan Variant\", \"#FF404457\": \"Manhattan Blue\", \"#FFCCCFCF\": \"Manhattan Mist\", \"#FF97908E\": \"Mani\", \"#FF004058\": \"Maniac Mansion\", \"#FF899888\": \"Manifest\", \"#FF8A9BC2\": \"Manifest Destiny\", \"#FFE7C9A9\": \"Manila\", \"#FFFF6E61\": \"Manila Sunset\", \"#FFFFE2A7\": \"Manila Tint\", \"#FFDAC9B8\": \"Manilla Rope\", \"#FF5B92A2\": \"Manitou Blue\", \"#FFCF7336\": \"Mann Orange\", \"#FFFAE2BE\": \"Manna\", \"#FFEEDFDD\": \"Mannequin\", \"#FFF6E5CE\": \"Mannequin Cream\", \"#FFC19763\": \"Mannered Gold\", \"#FF665D57\": \"Manor House\", \"#FFFFBC02\": \"Mantella Frog\", \"#FF957840\": \"Manticore Brown\", \"#FFDD7711\": \"Manticore Wing\", \"#FF96A793\": \"Mantle Variant\", \"#FFDCE2DF\": \"Mantra\", \"#FF881144\": \"Manually Pressed Grapes\", \"#FFAD900D\": \"Manure\", \"#FFD1C9BA\": \"Manuscript\", \"#FF827E71\": \"Manuscript Ink\", \"#FFE4DB55\": \"Manz Variant\", \"#FF9E8F6B\": \"Manzanilla Olive\", \"#FF643C37\": \"Manzanita\", \"#FFB88E72\": \"Maple\", \"#FFFAD0A1\": \"Maple Beige\", \"#FFA38E6F\": \"Maple Brown Sugar\", \"#FFF6D193\": \"Maple Elixir\", \"#FFA76944\": \"Maple Glaze\", \"#FFD17B41\": \"Maple Leaf\", \"#FFE3D1BB\": \"Maple Pecan\", \"#FFBF514E\": \"Maple Red\", \"#FFC1967C\": \"Maple Sugar\", \"#FFBB9351\": \"Maple Syrup\", \"#FFC88554\": \"Maple Syrup Brown\", \"#FFD4A882\": \"Maple Tan\", \"#FFB49161\": \"Maple View\", \"#FFFF2600\": \"Maraschino\", \"#FFF3E5CB\": \"Marble Dust\", \"#FF646255\": \"Marble Garden\", \"#FFDEE2C7\": \"Marble Grape\", \"#FF8F9F97\": \"Marble Green\", \"#FF85928F\": \"Marble Green-Grey\", \"#FFE2DCD7\": \"Marble Quarry\", \"#FFA9606E\": \"Marble Red\", \"#FFF2F0E6\": \"Marble White\", \"#FFE3DACF\": \"March Breeze\", \"#FFD4CC00\": \"March Green\", \"#FFFF750F\": \"March Hare Orange\", \"#FFD8CDC5\": \"March Ice\", \"#FF9A7276\": \"March Pink\", \"#FFD4C978\": \"March Tulip Green\", \"#FFBAB9B6\": \"March Wind\", \"#FFF1D48A\": \"March Yellow\", \"#FF2E5464\": \"Marea Baja\", \"#FFF9ECDA\": \"Marfil\", \"#FFF2D930\": \"Margarine\", \"#FFA9BC81\": \"Margarita\", \"#FF445956\": \"Mariana Trench\", \"#FFFCC006\": \"Marigold Tint\", \"#FFF5CC3D\": \"Marigold Dust\", \"#FFE7C3AC\": \"Marilyn Monroe\", \"#FFC9001E\": \"Marilyn MonRouge\", \"#FF5A88C8\": \"Marina\", \"#FFB1C8BF\": \"Marina Isle\", \"#FFFF0008\": \"Marinara Red\", \"#FF042E60\": \"Marine\", \"#FF01386A\": \"Marine Blue\", \"#FF40A48E\": \"Marine Green\", \"#FFA5B2AA\": \"Marine Grey\", \"#FF6384B8\": \"Marine Ink\", \"#FFA5B4B6\": \"Marine Layer\", \"#FF515E62\": \"Marine Magic\", \"#FF008383\": \"Marine Teal\", \"#FF33A3B3\": \"Marine Tinge\", \"#FF1F7073\": \"Marine Wonder\", \"#FF42639F\": \"Mariner Variant\", \"#FFE4000F\": \"Mario\", \"#FF380282\": \"Marionberry\", \"#FFBDCFEA\": \"Maritime\", \"#FF2D3145\": \"Maritime Blue\", \"#FF8B9BA4\": \"Maritime Hush\", \"#FF1E4581\": \"Maritime Outpost\", \"#FF69B8C0\": \"Maritime Soft Blue\", \"#FFE5E6E0\": \"Maritime White\", \"#FFBFCBA2\": \"Marjoram\", \"#FF00869A\": \"Marker Blue\", \"#FF9DAF00\": \"Marker Green\", \"#FFE3969B\": \"Marker Pink\", \"#FFFBB377\": \"Market Melon\", \"#FF515B87\": \"Marlin\", \"#FF41A1AA\": \"Marlin Green\", \"#FFD46F14\": \"Marmalade\", \"#FFC27545\": \"Marmalade Glaze\", \"#FFDF7F73\": \"Marmalade Magic\", \"#FF46221B\": \"Marmite\", \"#FF928475\": \"Marmot\", \"#FFC32249\": \"Maroon Flush Variant\", \"#FFBF3160\": \"Maroon Light\", \"#FF8D5455\": \"Maroon Rover\", \"#FF86CDAB\": \"Marooned\", \"#FFF5EAD6\": \"Marquee White\", \"#FFD2783A\": \"Marquis Orange\", \"#FFF3D49D\": \"Marquisette\", \"#FF91734C\": \"Marrakech Brown\", \"#FF01B2BD\": \"Marrakech Mile\", \"#FF783B3C\": \"Marrakesh Red\", \"#FFCACAA3\": \"Marrett Apple\", \"#FF6E4C4B\": \"Marron\", \"#FFA7735A\": \"Marron Canela\", \"#FF008C8C\": \"Marrs Green\", \"#FFAD6242\": \"Mars\", \"#FFC92A37\": \"Mars Red\", \"#FF96534C\": \"Marsala\", \"#FFB7BBBB\": \"Marseilles\", \"#FF5C5337\": \"Marsh\", \"#FF6B8781\": \"Marsh Creek\", \"#FFB6CA90\": \"Marsh Fern\", \"#FFD4C477\": \"Marsh Field\", \"#FFC6D8C7\": \"Marsh Fog\", \"#FF82763D\": \"Marsh Grass\", \"#FFFFEF17\": \"Marsh Marigold\", \"#FFE8E1A1\": \"Marsh Mist\", \"#FF5A653A\": \"Marsh Mix\", \"#FFC4A3BF\": \"Marsh Orchid\", \"#FF3E4355\": \"Marshal Blue\", \"#FF2B2E26\": \"Marshland Variant\", \"#FFF0EEE4\": \"Marshmallow\", \"#FFDBC2B4\": \"Marshmallow Cocoa\", \"#FFF3E0D6\": \"Marshmallow Cream\", \"#FFFAF3DE\": \"Marshmallow Fluff\", \"#FFF9DCE3\": \"Marshmallow Heart\", \"#FFEFD2D0\": \"Marshmallow Magic\", \"#FFE0CAAA\": \"Marshmallow Mist\", \"#FFF7E5E6\": \"Marshmallow Rose\", \"#FFF9EFE0\": \"Marshmallow Whip\", \"#FF8E712E\": \"Marshy Green\", \"#FFB8AEA2\": \"Marshy Habitat\", \"#FFFDF200\": \"Marsupilami\", \"#FFAEA132\": \"Martian\", \"#FF57958B\": \"Martian Cerulean\", \"#FFE5750F\": \"Martian Colony\", \"#FF136C51\": \"Martian Green\", \"#FFADEACE\": \"Martian Haze\", \"#FFC15A4B\": \"Martian Ironearth\", \"#FFC3E9D3\": \"Martian Moon\", \"#FFF4E5B7\": \"Martica\", \"#FF8E8E41\": \"Martina Olive\", \"#FFB7A8A3\": \"Martini Variant\", \"#FFCE8C8D\": \"Martini East\", \"#FF3C3748\": \"Martinique Variant\", \"#FF6A7FB4\": \"Marvellous\", \"#FFE1C6D6\": \"Marvellous Magic\", \"#FF006A77\": \"Mary Blue\", \"#FFD1B5CA\": \"Mary Poppins\", \"#FFD7B1B0\": \"Mary Rose\", \"#FF69913D\": \"Mary\\u2019s Garden\", \"#FFA6D0EC\": \"Marzena Dream\", \"#FFEBC881\": \"Marzipan Variant\", \"#FFEEBABC\": \"Marzipan Pink\", \"#FFEBE5D8\": \"Marzipan White\", \"#FF57534B\": \"Masala Variant\", \"#FFEECCAA\": \"Masala Chai\", \"#FFECE6D4\": \"Mascarpone\", \"#FFAB878D\": \"Mask\", \"#FFC6B2BE\": \"Masked Mauve\", \"#FFD57C6B\": \"Masoho Red\", \"#FF3A4B61\": \"Master\", \"#FFE0CE80\": \"Master Gardener\", \"#FFDDCC88\": \"Master Key\", \"#FFFFB81B\": \"Master Nacho\", \"#FFE78303\": \"Master Round Yellow\", \"#FF00FFEE\": \"Master Sword Blue\", \"#FFA1A2AB\": \"Masterpiece\", \"#FF4D646C\": \"Masuhana Blue\", \"#FFFF48D0\": \"Mat Dazzle Rose\", \"#FF544859\": \"Mata Hari\", \"#FFCF6E66\": \"Matador\\u2019s Cape\", \"#FFD63756\": \"Match Head\", \"#FFFFAA44\": \"Match Strike\", \"#FFD8D458\": \"Matcha\", \"#FF9FAF6C\": \"Matcha Mecha\", \"#FF99BB00\": \"Matcha Picchu\", \"#FFA0D404\": \"Matcha Powder\", \"#FF7BB18D\": \"Mate Tea\", \"#FF590A01\": \"Mathematical Rage\", \"#FF365C7D\": \"Matisse Variant\", \"#FF7E6884\": \"Matriarch\", \"#FF454D32\": \"Matsuba Green\", \"#FF151515\": \"Matt Black\", \"#FF2C6FBB\": \"Matt Blue\", \"#FFDD4433\": \"Matt Demon\", \"#FF39AD48\": \"Matt Green\", \"#FFDEC6D3\": \"Matt Lilac\", \"#FFB2B9A5\": \"Matt Sage\", \"#FFFFFFD4\": \"Matt White\", \"#FF884433\": \"Mattar Paneer\", \"#FF8FB0CE\": \"Matte Blue\", \"#FFA17F67\": \"Matte Brown\", \"#FFA06570\": \"Matte Carmine\", \"#FFB4A8A4\": \"Matte Grey\", \"#FFB5CBBD\": \"Matte Jade Green\", \"#FF998F7F\": \"Matte Olive\", \"#FF8A9381\": \"Matte Sage Green\", \"#FF524B4B\": \"Matterhorn Variant\", \"#FFE0FEFE\": \"Matterhorn Snow\", \"#FFC4AFB3\": \"Mature\", \"#FF9A463D\": \"Mature Cognac\", \"#FF5F3F54\": \"Mature Grape\", \"#FF38796C\": \"Maturity\", \"#FF988286\": \"Maud\", \"#FF21A5BE\": \"Maui\", \"#FF52A2B4\": \"Maui Blue\", \"#FFB66044\": \"Maui Mai Tai\", \"#FFEEF2F3\": \"Maui Mist\", \"#FFB08A7D\": \"Maui Poi\", \"#FFE3D2DB\": \"Mauve Aquarelle\", \"#FFB69289\": \"Mauve Blush\", \"#FF62595F\": \"Mauve Brown\", \"#FFE5D0CF\": \"Mauve Chalk\", \"#FFAC8C8C\": \"Mauve Day\", \"#FF545883\": \"Mauve Dusk\", \"#FFCBB8C0\": \"Mauve Finery\", \"#FFD18489\": \"Mauve Glow\", \"#FFBB4466\": \"Mauve It\", \"#FF908186\": \"Mauve Jazz\", \"#FFAA7982\": \"Mauve Madness\", \"#FFBF91B2\": \"Mauve Magic\", \"#FFA69F9A\": \"Mauve Melody\", \"#FFA46A95\": \"Mauve Memento\", \"#FFC49BD4\": \"Mauve Mist\", \"#FF7D716E\": \"Mauve Mole\", \"#FFE7CCCD\": \"Mauve Morn\", \"#FFD9D0CF\": \"Mauve Morning\", \"#FFA98CA1\": \"Mauve Musk\", \"#FFB59EAD\": \"Mauve Muslin\", \"#FF685C61\": \"Mauve Mystery\", \"#FFBB4477\": \"Mauve Mystique\", \"#FFC0ADA6\": \"Mauve Nymph\", \"#FFAB728D\": \"Mauve Orchid\", \"#FFD9C4D0\": \"Mauve Organdie\", \"#FFBEBBC0\": \"Mauve Pansy\", \"#FFBB7788\": \"Mauve Seductress\", \"#FFAF8F9C\": \"Mauve Shadows\", \"#FFC4BAB6\": \"Mauve Stone\", \"#FFE7E1E1\": \"Mauve Tinge\", \"#FFDEE3E4\": \"Mauve White\", \"#FF653C4A\": \"Mauve Wine\", \"#FFEADDE1\": \"Mauve Wisp\", \"#FF90686C\": \"Mauve-a-Lish\", \"#FF8A6D8B\": \"Mauveine\", \"#FFD6B3C0\": \"Mauvelous Tint\", \"#FF9D8888\": \"Mauverine\", \"#FFC4B2A9\": \"Mauvette\", \"#FFAE6A78\": \"Mauvewood\", \"#FFBB8899\": \"Mauvey Nude\", \"#FF8C8188\": \"Mauvey Pink\", \"#FF86666B\": \"Mauving Up\", \"#FFC8B1C0\": \"Maverick Variant\", \"#FFEFE9DD\": \"Mawmaw\\u2019s Pearls\", \"#FF017478\": \"Maxi Teal\", \"#FF6B4A40\": \"Maximum Mocha\", \"#FFFF5B00\": \"Maximum Orange\", \"#FF92D599\": \"May Apple\", \"#FF53CBC4\": \"May Day\", \"#FFA19FC8\": \"May Mist\", \"#FFFAEAD0\": \"May Sun\", \"#FF98D2D9\": \"Maya Green\", \"#FF006B6C\": \"Mayan Blue\", \"#FF655046\": \"Mayan Chocolate\", \"#FFB68C37\": \"Mayan Gold\", \"#FF6C4A43\": \"Mayan Red\", \"#FF7D6950\": \"Mayan Ruins\", \"#FFCE9844\": \"Mayan Treasure\", \"#FFF6D48D\": \"Maybe Maui\", \"#FFE2D8CB\": \"Maybe Mushroom\", \"#FFEDDFC9\": \"Maybeck Muslin\", \"#FFE6F0DE\": \"Mayfair White\", \"#FFED93D7\": \"Mayflower Orchid\", \"#FF696841\": \"Mayfly\", \"#FFE1E6F0\": \"Mayon Mist\", \"#FFF6EED1\": \"Mayonnaise\", \"#FFBEE8D3\": \"Maypole\", \"#FF2A407E\": \"Mazarine Blue\", \"#FF5C5638\": \"Maze\", \"#FFB0907C\": \"Mazzone\", \"#FFBF5BB0\": \"Mazzy Star\", \"#FF8C6338\": \"McKenzie\", \"#FF33FF11\": \"McNuke\", \"#FFFFC878\": \"Mead\", \"#FF81B489\": \"Meadow\", \"#FF7AB2D4\": \"Meadow Blossom Blue\", \"#FFE2D4AD\": \"Meadow Dew\", \"#FF987184\": \"Meadow Flower\", \"#FFCCD1B2\": \"Meadow Glen\", \"#FFC1D6B1\": \"Meadow Grass\", \"#FF739957\": \"Meadow Green\", \"#FFC0D7CD\": \"Meadow Lane\", \"#FFDFE9DE\": \"Meadow Light\", \"#FFAC5D91\": \"Meadow Mauve\", \"#FFCCD8BA\": \"Meadow Mist\", \"#FFAEBEA6\": \"Meadow Morn\", \"#FFA8AFC7\": \"Meadow Phlox\", \"#FFC5ACD0\": \"Meadow Thistle\", \"#FF8D8168\": \"Meadow Trail\", \"#FF764F82\": \"Meadow Violet\", \"#FFF7DA90\": \"Meadow Yellow\", \"#FF60A0A3\": \"Meadowbrook\", \"#FF807A55\": \"Meadowland\", \"#FFE8D940\": \"Meadowlark\", \"#FF9DA28E\": \"Meadowood\", \"#FFD4E3E2\": \"Meadowsweet Mist\", \"#FFFF00AE\": \"Mean Girls Lipstick\", \"#FF8F8C79\": \"Meander\", \"#FFBEDBD8\": \"Meander Blue\", \"#FFF8EED3\": \"Meatbun\", \"#FF663311\": \"Meatloaf\", \"#FFC89134\": \"Mecca Gold\", \"#FFBD5745\": \"Mecca Orange\", \"#FF663F3F\": \"Mecca Red\", \"#FFBBDDDD\": \"Mech Suit\", \"#FF8D847F\": \"Mecha Grey\", \"#FFD0C4D3\": \"Mecha Kitty\", \"#FF848393\": \"Mecha Metal\", \"#FFDEDCE2\": \"Mechagodzilla\", \"#FF3D4B4D\": \"Mechanicus Standard Grey\", \"#FFA31713\": \"Mechrite Red\", \"#FFC3A679\": \"Medallion\", \"#FF696DB0\": \"Mediaeval\", \"#FF2E3858\": \"Mediaeval Blue\", \"#FF878573\": \"Mediaeval Cobblestone\", \"#FF007E6B\": \"Mediaeval Forest\", \"#FFAC7F48\": \"Mediaeval Gold\", \"#FFA79F5C\": \"Mediaeval Sulphur\", \"#FF8C7D88\": \"Mediaeval Wine\", \"#FFB8C4B8\": \"Median Green\", \"#FF95CCE4\": \"Medical Mask\", \"#FF104773\": \"Medici Blue\", \"#FFF3E9D7\": \"Medici Ivory\", \"#FF69556D\": \"Medicine Man\", \"#FF99A28C\": \"Medicine Wheel\", \"#FFA9AC9D\": \"Meditation\", \"#FFA7A987\": \"Meditation Time\", \"#FF96AAB0\": \"Meditative\", \"#FF39636A\": \"Mediterranea\", \"#FF60797D\": \"Mediterranean\", \"#FF1682B9\": \"Mediterranean Blue\", \"#FFA1CFEC\": \"Mediterranean Charm\", \"#FF007B84\": \"Mediterranean Cove\", \"#FFB3C3BD\": \"Mediterranean Dusk\", \"#FFE0E9D3\": \"Mediterranean Green\", \"#FFBCE9D6\": \"Mediterranean Mist\", \"#FF1E8CAB\": \"Mediterranean Sea\", \"#FFD0BABB\": \"Mediterranean Sunset\", \"#FF2999A2\": \"Mediterranean Swirl\", \"#FF444443\": \"Medium Black\", \"#FF7F5112\": \"Medium Brown\", \"#FFF3E5AC\": \"Medium Champagne Variant\", \"#FFEAEAAE\": \"Medium Goldenrod\", \"#FF418C53\": \"Medium Green\", \"#FF7D7F7C\": \"Medium Grey\", \"#FF4D6B53\": \"Medium Grey Green\", \"#FF3F4952\": \"Medium Gunship Grey\", \"#FFDDA0FD\": \"Medium Lavender Magenta\", \"#FFF36196\": \"Medium Pink\", \"#FF9E43A2\": \"Medium Purple Variant\", \"#FFAA4069\": \"Medium Ruby\", \"#FFFC2847\": \"Medium Scarlet\", \"#FF80DAEB\": \"Medium Sky Blue\", \"#FFDC9D8B\": \"Medium Terracotta\", \"#FF794431\": \"Medium Tuscan Red\", \"#FFD9603B\": \"Medium Vermilion\", \"#FFA68064\": \"Medium Wood\", \"#FFD5D7BF\": \"Medlar\", \"#FF998800\": \"Medusa Green\", \"#FF777711\": \"Medusa\\u2019s Snakes\", \"#FFEE7700\": \"Mee-hua Sunset\", \"#FF869F98\": \"Meek Moss Green\", \"#FFAB7647\": \"Meerkat\", \"#FF739DAD\": \"Meetinghouse Blue\", \"#FF366FA6\": \"Mega Blue\", \"#FFADA295\": \"Mega Greige\", \"#FFD767AD\": \"Mega Magenta\", \"#FFDFCBCF\": \"Mega Metal Mecha\", \"#FFC6CCD4\": \"Mega Metal Phoenix\", \"#FF0EE8A3\": \"Mega Teal\", \"#FF4A40AD\": \"Megadrive Screen\", \"#FF3CBCFC\": \"Megaman\", \"#FF0058F8\": \"Megaman Helmet\", \"#FFA10000\": \"Megido Red\", \"#FFFE023C\": \"M\\u00e9i G\\u016bi H\\u00f3ng Red\", \"#FFE03FD8\": \"M\\u00e9i G\\u016bi Z\\u01d0 Purple\", \"#FF123120\": \"M\\u00e9i H\\u0113i Coal\", \"#FF007FB9\": \"Meissen Blue\", \"#FF12390D\": \"Melancholia\", \"#FFAA1133\": \"Melancholic Macaw\", \"#FF53778F\": \"Melancholic Sea\", \"#FFDD8899\": \"Melancholy\", \"#FFC4C476\": \"M\\u00e9lange Green\", \"#FFE0B7C2\": \"Melanie Variant\", \"#FF282E27\": \"Melanite Black Green\", \"#FF01081C\": \"Melanophobia\", \"#FF342931\": \"Melanzane Variant\", \"#FF4C7C4B\": \"Melbourne\", \"#FF45C3AD\": \"Melbourne Cup\", \"#FFB5D96B\": \"Melissa\", \"#FFF0DDA2\": \"Mella Yella\", \"#FFC9E1E0\": \"Mellifluous Blue\", \"#FFD7E2DD\": \"Mellow Blue\", \"#FFD5AF92\": \"Mellow Buff\", \"#FFE0897E\": \"Mellow Coral\", \"#FFF8DE7F\": \"Mellow Dandelion\", \"#FFFFC65F\": \"Mellow Drama\", \"#FFF1DFE9\": \"Mellow Flower\", \"#FFFFCFAD\": \"Mellow Glow\", \"#FFD5D593\": \"Mellow Green\", \"#FFCC4400\": \"Mellow Mango\", \"#FFE8C2B4\": \"Mellow Marrow\", \"#FF9C6579\": \"Mellow Mauve\", \"#FFEE2266\": \"Mellow Melon\", \"#FFDDEDBD\": \"Mellow Mint\", \"#FFF2C996\": \"Mellow Moment\", \"#FFB1B7A1\": \"Mellow Mood\", \"#FFD9A6A1\": \"Mellow Rose\", \"#FFC3CDBA\": \"Mellow Spring\", \"#FFF5D39C\": \"Mellow Sun\", \"#FFE2A94F\": \"Mellowed Gold\", \"#FFB6B2A1\": \"Melmac Silver\", \"#FFEEE8E8\": \"Melodic White\", \"#FF7BB5AE\": \"Melodious\", \"#FFDD22AA\": \"Melodramatic Magenta\", \"#FFBECBD7\": \"Melody\", \"#FFA8ACD0\": \"Melody Purple\", \"#FFFF7855\": \"Melon Variant\", \"#FFF2BD85\": \"Melon Balls\", \"#FF74AC8D\": \"Melon Green\", \"#FFF4D9C8\": \"Melon Ice\", \"#FFF9C291\": \"Melon Melody\", \"#FFF2B88C\": \"Mel\\u00f3n Meloso\", \"#FFE88092\": \"Melon Mist\", \"#FFF08F48\": \"Melon Orange\", \"#FFF1D4C4\": \"Melon Pink\", \"#FFF69268\": \"Melon Red\", \"#FFF47869\": \"Melon Refresher\", \"#FF332C22\": \"Melon Seed\", \"#FFF8B797\": \"Melon Sorbet\", \"#FFFFCD9D\": \"Melon Sprinkle\", \"#FFF8E7D4\": \"Melon Tint\", \"#FFAA6864\": \"Melon Twist\", \"#FFFDBCB4\": \"Melon Water\", \"#FFEE8170\": \"Melondrama\", \"#FFC3B9DD\": \"Melrose Variant\", \"#FFB4CBE3\": \"Melt Ice\", \"#FFE3CFAB\": \"Melt With You\", \"#FFFFCF53\": \"Melted Butter\", \"#FF785F4C\": \"Melted Chocolate\", \"#FFCE8544\": \"Melted Copper\", \"#FFDCB7A6\": \"Melted Ice Cream\", \"#FFFEE2CC\": \"Melted Marshmallow\", \"#FFF6E6C5\": \"Melted Wax\", \"#FFE9F9F5\": \"Melting Glacier\", \"#FFCAE1D9\": \"Melting Ice\", \"#FFECEBE4\": \"Melting Icicles\", \"#FFBBA2B6\": \"Melting Moment\", \"#FFCBE1E4\": \"Melting Point\", \"#FFDAE5E0\": \"Melting Snowman\", \"#FFEAAB7D\": \"Melting Sunset\", \"#FFD4B8BF\": \"Melting Violet\", \"#FF79C0CC\": \"Meltwater\", \"#FF95A99E\": \"Melville\", \"#FFECF0DA\": \"Memoir\", \"#FFCF8A8D\": \"Memorable Rose\", \"#FFE8DEDA\": \"Memories\", \"#FF9197A4\": \"Memorise\", \"#FFC7D1DB\": \"Memory Lane\", \"#FFA7C3CE\": \"Memorybook Blue\", \"#FF5E9D7B\": \"Memphis Green\", \"#FF5D5F73\": \"Men\\u2019s Night\", \"#FF69788A\": \"Menacing Clouds\", \"#FF837A64\": \"Mendocino Hills\", \"#FFF3E8B8\": \"Menoth White Base\", \"#FFF0F1CE\": \"Menoth White Highlight\", \"#FFDEB4C5\": \"Mental Floss\", \"#FFEAEEDE\": \"Mental Note\", \"#FFC1F9A2\": \"Menthol\", \"#FF9CD2B4\": \"Menthol Green\", \"#FFA0E2D4\": \"Menthol Kiss\", \"#FF9A1115\": \"Mephiston Red\", \"#FFACA495\": \"Mercer Charcoal\", \"#FF0343DF\": \"Merchant Marine Blue\", \"#FFB6B0A9\": \"Mercurial\", \"#FFEBEBEB\": \"Mercury Variant\", \"#FFCEC9CA\": \"Mercury Glass\", \"#FF89C8C3\": \"Mercury Mist\", \"#FF650021\": \"Merguez\", \"#FF877272\": \"Meridian\", \"#FF7BC8B2\": \"Meridian Star\", \"#FFFF9408\": \"Merin\\u2019s Fire\", \"#FFF3E4B3\": \"Meringue\", \"#FFC2A080\": \"Meringue Tips\", \"#FFE1DBD0\": \"Merino Variant\", \"#FFCFC1AE\": \"Merino Wool\", \"#FFAAE1CE\": \"Meristem\", \"#FF4F4E48\": \"Merlin Variant\", \"#FFEFE2D9\": \"Merlin\\u2019s Beard\", \"#FF9F8898\": \"Merlin\\u2019s Choice\", \"#FF89556E\": \"Merlin\\u2019s Cloak\", \"#FF444C8F\": \"Merlin\\u2019s Robe\", \"#FF730039\": \"Merlot Variant\", \"#FF712735\": \"Merlot Fields\", \"#FFB64055\": \"Merlot Magic\", \"#FF817A65\": \"Mermaid\", \"#FF004477\": \"Mermaid Blues\", \"#FFFCB39A\": \"Mermaid Cheeks\", \"#FF0088BB\": \"Mermaid Dreams\", \"#FF00776F\": \"Mermaid Harbour\", \"#FF22CCCC\": \"Mermaid Net\", \"#FF297F6D\": \"Mermaid Sea\", \"#FF25AE8E\": \"Mermaid Song\", \"#FFD9E6A6\": \"Mermaid Tears\", \"#FF1FAFB4\": \"Mermaid Treasure\", \"#FF8AA786\": \"Mermaid\\u2019s Cove\", \"#FF59C8A5\": \"Mermaid\\u2019s Kiss\", \"#FF337B35\": \"Mermaid\\u2019s Tail\", \"#FF70859B\": \"Merman\", \"#FFCED3C1\": \"Merry Music\", \"#FFEAC8DA\": \"Merry Pink\", \"#FFA5D0AF\": \"Merrylyn\", \"#FFBCA177\": \"Mesa\", \"#FFF2EBD6\": \"Mesa Beige\", \"#FFC19180\": \"Mesa Peach\", \"#FFDDB1A8\": \"Mesa Pink\", \"#FF92555B\": \"Mesa Red\", \"#FF772F39\": \"Mesa Ridge\", \"#FFEEB5AF\": \"Mesa Rose\", \"#FFDCB49D\": \"Mesa Sand\", \"#FFEA8160\": \"Mesa Sunrise\", \"#FFA78B71\": \"Mesa Tan\", \"#FFCDBDAD\": \"Mesa Tumbleweed\", \"#FF7F976C\": \"Mesa Verde\", \"#FF9DB682\": \"Mesclun Green\", \"#FF1F0B1E\": \"Me\\u0161ki Black\", \"#FF8E9074\": \"Mesmerise\", \"#FF804040\": \"Mesopotamian Dagger\", \"#FF997700\": \"Mesozoic Green\", \"#FFE3C8B1\": \"Mesquite Powder\", \"#FF37B8AF\": \"Message Green\", \"#FF7D745E\": \"Messenger Bag\", \"#FFFEE2BE\": \"Messinesi\", \"#FFBABFBC\": \"Metal\", \"#FF9C9C9B\": \"Metal Chi\", \"#FF2F2E1F\": \"Metal Construction Green\", \"#FF244343\": \"Metal Deluxe\", \"#FF838782\": \"Metal Flake\", \"#FF837E74\": \"Metal Fringe\", \"#FFA2C3DB\": \"Metal Gear\", \"#FF677986\": \"Metal Grey\", \"#FFB090B2\": \"Metal Petal\", \"#FFEEFF99\": \"Metal Spark\", \"#FF34373C\": \"Metalise\", \"#FFBCC3C7\": \"Metallic\", \"#FF4F738E\": \"Metallic Blue\", \"#FF554A3C\": \"Metallic Bronze Variant\", \"#FF6E3D34\": \"Metallic Copper Variant\", \"#FF24855B\": \"Metallic Green\", \"#FFCDCCBE\": \"Metallic Mist\", \"#FFA9959F\": \"Metamorphosis\", \"#FFBB7431\": \"Meteor Variant\", \"#FF5533FF\": \"Meteor Shower\", \"#FF4A3B6A\": \"Meteorite Variant\", \"#FF414756\": \"Meteorite Black Blue\", \"#FF596D69\": \"Meteorological\", \"#FFCC2233\": \"Methadone\", \"#FF0074A8\": \"Methyl Blue\", \"#FF828393\": \"Metro\", \"#FFF83800\": \"Metroid Red\", \"#FF61584F\": \"Metropolis\", \"#FF99A1A5\": \"Metropolis Mood\", \"#FF3E4244\": \"Metropolitan Silhouette\", \"#FFEEECE7\": \"Metropolitan White\", \"#FFF9E1D4\": \"Mette Penne\", \"#FFDF7163\": \"Mettwurst\", \"#FFE39B99\": \"Mexicali Rose\", \"#FFD16D76\": \"Mexican Chile\", \"#FF6F5A48\": \"Mexican Chocolate\", \"#FFFFB9B2\": \"Mexican Milk\", \"#FFC99387\": \"Mexican Moonlight\", \"#FFFCD8DC\": \"Mexican Mudkip\", \"#FF5A3C55\": \"Mexican Purple\", \"#FF9B3D3D\": \"Mexican Red Variant\", \"#FFC6452F\": \"Mexican Red Papaya\", \"#FFAF9781\": \"Mexican Sand\", \"#FFDAD4C5\": \"Mexican Sand Dollar\", \"#FFCECEC8\": \"Mexican Silver\", \"#FFD68339\": \"Mexican Spirit\", \"#FFEC9F76\": \"Mexican Standoff\", \"#FFDAD7AD\": \"M\\u01d0 B\\u00e1i Beige\", \"#FFE8AF45\": \"M\\u00ec Ch\\u00e9ng Honey\", \"#FFFD8973\": \"Miami Coral\", \"#FF17917F\": \"Miami Jade\", \"#FFF7931A\": \"Miami Marmalade\", \"#FFF7C3DA\": \"Miami Pink\", \"#FF907A6E\": \"Miami Spice\", \"#FFF5D5B8\": \"Miami Stucco\", \"#FF6EC2B0\": \"Miami Teal\", \"#FFEDE4D3\": \"Miami Weiss\", \"#FFCCCCEE\": \"Miami White\", \"#FF70828F\": \"Mica Creek\", \"#FFC5DACC\": \"Micaceous Green\", \"#FFCDC7BD\": \"Micaceous Light Grey\", \"#FFB7B4B1\": \"Michigan Avenue\", \"#FFBABCC0\": \"Microchip\", \"#FF556E6B\": \"Micropolis\", \"#FFEE172B\": \"MicroProse Red\", \"#FF2D5254\": \"Microwave Blue\", \"#FF276AB3\": \"Mid Blue\", \"#FF553333\": \"Mid Century\", \"#FFAE5C1B\": \"Mid Century Furniture\", \"#FF779781\": \"Mid Cypress\", \"#FF50A747\": \"Mid Green\", \"#FFCFF7EF\": \"Mid Spring Morning\", \"#FFC4915E\": \"Mid Tan\", \"#FF81B39C\": \"Mid-century Gem\", \"#FFF6B404\": \"Midas Finger Gold\", \"#FFE8BD45\": \"Midas Touch\", \"#FFF7D78A\": \"Midday\", \"#FFFFE1A3\": \"Midday Sun\", \"#FF7C6942\": \"Middle Ditch\", \"#FF210837\": \"Middle Red Purple\", \"#FFC85179\": \"Middle Safflower\", \"#FFA2948D\": \"Middle-Earth\", \"#FFC7AB84\": \"Middlestone\", \"#FFAA8ED6\": \"Middy\\u2019s Purple\", \"#FF03012D\": \"Midnight Tint\", \"#FF534657\": \"Midnight Affair\", \"#FF853C69\": \"Midnight Aubergine\", \"#FF585960\": \"Midnight Badger\", \"#FF020035\": \"Midnight Blue Tint\", \"#FF979FBF\": \"Midnight Blush\", \"#FF706048\": \"Midnight Brown\", \"#FF3C574E\": \"Midnight Clover\", \"#FF112473\": \"Midnight Crest\", \"#FF002233\": \"Midnight Dreams\", \"#FF0C121B\": \"Midnight Edition\", \"#FF2B3458\": \"Midnight Escapade\", \"#FF403C40\": \"Midnight Escape\", \"#FF21263A\": \"Midnight Express\", \"#FF685D49\": \"Midnight Forest\", \"#FF637057\": \"Midnight Garden\", \"#FF666A6D\": \"Midnight Grey\", \"#FF3E505F\": \"Midnight Haze\", \"#FF3B484F\": \"Midnight Hour\", \"#FF4E5A59\": \"Midnight in NY\", \"#FFDD8866\": \"Midnight in Saigon\", \"#FF435964\": \"Midnight in the Tropics\", \"#FF000088\": \"Midnight in Tokyo\", \"#FF32496F\": \"Midnight Interlude\", \"#FF484D61\": \"Midnight Iris\", \"#FF0B0119\": \"Midnight Jam\", \"#FF46474A\": \"Midnight Magic\", \"#FF2C2E47\": \"Midnight Masquerade\", \"#FF002266\": \"Midnight Melancholia\", \"#FF880044\": \"Midnight Merlot\", \"#FF001F3F\": \"Midnight Mirage\", \"#FF1C0F33\": \"Midnight Monarch\", \"#FF3D5267\": \"Midnight Mosaic\", \"#FF242E28\": \"Midnight Moss Variant\", \"#FF364251\": \"Midnight Navy\", \"#FF0F2D4D\": \"Midnight Ocean\", \"#FF0B0C14\": \"Midnight Oil\", \"#FF5F6C74\": \"Midnight Pearl\", \"#FF372D52\": \"Midnight Pie\", \"#FF17240B\": \"Midnight Pines\", \"#FF280137\": \"Midnight Purple\", \"#FF565B8D\": \"Midnight Sea\", \"#FF41434E\": \"Midnight Serenade\", \"#FF566373\": \"Midnight Shadow\", \"#FF546473\": \"Midnight Show\", \"#FF424753\": \"Midnight Sky\", \"#FF243A5E\": \"Midnight Sleigh\", \"#FF225374\": \"Midnight Sonata\", \"#FF555B53\": \"Midnight Spruce\", \"#FF4E5A6D\": \"Midnight Sun\", \"#FF476062\": \"Midnight Teal\", \"#FF2A2243\": \"Midnight Velvet\", \"#FF6A75AD\": \"Midnight Violet\", \"#FF2A603B\": \"Midori\", \"#FF3EB370\": \"Midori Green\", \"#FFF6D9A9\": \"Midsummer\", \"#FF88CC44\": \"Midsummer Field\", \"#FFEAB034\": \"Midsummer Gold\", \"#FF0011EE\": \"Midsummer Nights\", \"#FFB1A4B4\": \"Midsummer Twilight\", \"#FFB4D0D9\": \"Midsummer\\u2019s Dream\", \"#FFB5A18A\": \"Midtown\", \"#FFDD1100\": \"Midwinter Fire\", \"#FFA5D4DC\": \"Midwinter Mist\", \"#FF8F7F85\": \"Mighty Mauve\", \"#FF000133\": \"Mighty Midnight\", \"#FF283482\": \"Migol Blue\", \"#FF3F3623\": \"Mikado Variant\", \"#FFA7A62D\": \"Mikado Green\", \"#FFF08300\": \"Mikan Orange\", \"#FF11EE55\": \"Mike Wazowski Green\", \"#FFEEE1DC\": \"Milady\", \"#FFF6F493\": \"Milan Variant\", \"#FFC1A181\": \"Milano\", \"#FF9E3332\": \"Milano Red Variant\", \"#FFCBD5DB\": \"Mild Blue\", \"#FF8EBBAC\": \"Mild Evergreen\", \"#FF789885\": \"Mild Green\", \"#FFF27362\": \"Mild Heart Attack\", \"#FF87F8A3\": \"Mild Menthol\", \"#FFDCE6E3\": \"Mild Mint\", \"#FFF3BB93\": \"Mild Orange\", \"#FF667960\": \"Mildura\", \"#FF829BA0\": \"Miles\", \"#FF7F848A\": \"Milestone\", \"#FF229955\": \"Militant Vegan\", \"#FF667C3E\": \"Military Green\", \"#FF706043\": \"Military Olive\", \"#FFFDFFF5\": \"Milk\", \"#FFE9E1DF\": \"Milk and Cookies\", \"#FFF7E4C2\": \"Milk and Honey\", \"#FFDCE3E7\": \"Milk Blue\", \"#FF8F7265\": \"Milk Brownie Dough\", \"#FF7F4E1E\": \"Milk Chocolate\", \"#FF966F5D\": \"Milk Coffee Brown\", \"#FFF6FFE8\": \"Milk Foam\", \"#FFFFEECC\": \"Milk Froth\", \"#FFFAF7F0\": \"Milk Jug\", \"#FFFAF3E6\": \"Milk Moustache\", \"#FFEFE9D9\": \"Milk Paint\", \"#FFFFF4D3\": \"Milk Punch Variant\", \"#FFF5DEAE\": \"Milk Quartz\", \"#FFF5EDE2\": \"Milk Star White\", \"#FF9E9B88\": \"Milk Thistle\", \"#FFD1B39C\": \"Milk Toast\", \"#FFDCD9CD\": \"Milk White\", \"#FFF0CDD2\": \"Milkshake Pink\", \"#FFE3E8D9\": \"Milkweed\", \"#FF95987E\": \"Milkweed Pod\", \"#FF916981\": \"Milkwort Red\", \"#FFE2DCD4\": \"Milky\", \"#FF038487\": \"Milky Aquamarine\", \"#FF72A8BA\": \"Milky Blue\", \"#FFC6D4C9\": \"Milky Green\", \"#FFAEA3D0\": \"Milky Lavender\", \"#FFF9D9A0\": \"Milky Maize\", \"#FFC3B1AF\": \"Milky Skies\", \"#FF6BB3DB\": \"Milky Waves\", \"#FFE8F4F7\": \"Milky Way\", \"#FFFAEFD5\": \"Milky Way Galaxy\", \"#FFF8DD74\": \"Milky Yellow\", \"#FF876E59\": \"Mill Creek\", \"#FF595648\": \"Millbrook Variant\", \"#FFEFC87D\": \"Mille-Feuille\", \"#FF939796\": \"Millennial Greige\", \"#FF7B7B7D\": \"Millennial Grey\", \"#FFF6C8C1\": \"Millennial Pink\", \"#FF8C9595\": \"Millennium Silver\", \"#FF999999\": \"Million Grey\", \"#FFB6843C\": \"Millionaire\", \"#FFB9D4DE\": \"Millstream\", \"#FF99BD91\": \"Milly Green\", \"#FF689663\": \"Milpa\", \"#FFB4B498\": \"Milton\", \"#FFBB7722\": \"Milvus Milvus Orange\", \"#FF2269CA\": \"Mimesia Blue\", \"#FFEE8811\": \"Mimolette Orange\", \"#FFF5E9D5\": \"Mimosa Variant\", \"#FFDFC633\": \"Mimosa Yellow\", \"#FFBDB387\": \"Minced Ginger\", \"#FFB66A3C\": \"Mincemeat\", \"#FFDAEA6F\": \"Mindaro Variant\", \"#FFC8AC82\": \"Mindful\", \"#FFBDB5AD\": \"Mindful Grey\", \"#FF8E8583\": \"Mine Rock\", \"#FF373E41\": \"Mine Shaft Variant\", \"#FF6C6B65\": \"Mined Coal\", \"#FFD3CEC5\": \"Miner\\u2019s Dust\", \"#FFD7D1C5\": \"Mineral\", \"#FFD8C49F\": \"Mineral Beige\", \"#FF6D9192\": \"Mineral Blue\", \"#FF4D3F33\": \"Mineral Brown\", \"#FFABB0AC\": \"Mineral Deposit\", \"#FFFCE8CE\": \"Mineral Glow\", \"#FF506355\": \"Mineral Green Variant\", \"#FFB2B6AC\": \"Mineral Grey\", \"#FFB35457\": \"Mineral Red\", \"#FFEDF2EC\": \"Mineral Spring\", \"#FFB18B32\": \"Mineral Umber\", \"#FFDFEBD6\": \"Mineral Water\", \"#FFDCE5D9\": \"Mineral White\", \"#FFD19A3B\": \"Mineral Yellow\", \"#FFB5DEDA\": \"Minerva\", \"#FFC72616\": \"Minestrone\", \"#FF8F1CAE\": \"Minesweeper\\u2019s Purple\", \"#FFFA0103\": \"Minesweeper\\u2019s Red\", \"#FF407577\": \"Ming Variant\", \"#FF41B57E\": \"Ming Green\", \"#FF8AADCF\": \"Mini Bay\", \"#FF96D7DB\": \"Mini Blue\", \"#FFFBF6DE\": \"Mini Cake\", \"#FF9FC5AA\": \"Mini Green\", \"#FFE5BEBA\": \"Miniature Posey\", \"#FFD3DFEA\": \"Minified Ballerina Blue\", \"#FFB3DBEA\": \"Minified Blue\", \"#FFF2DDE1\": \"Minified Blush\", \"#FFDED9DB\": \"Minified Cinnamon\", \"#FFDDE8E0\": \"Minified Green\", \"#FFC1E3E9\": \"Minified Jade\", \"#FFEBF5DE\": \"Minified Lime\", \"#FFE6DFE8\": \"Minified Magenta\", \"#FFDDF3E5\": \"Minified Malachite\", \"#FFE5DBDA\": \"Minified Maroon\", \"#FFE0DCE4\": \"Minified Mauve\", \"#FFE4EBDC\": \"Minified Mint\", \"#FFE3E8DB\": \"Minified Moss\", \"#FFE9E6D4\": \"Minified Mustard\", \"#FFE1DEE7\": \"Minified Purple\", \"#FFF4EBD4\": \"Minified Yellow\", \"#FFF3EECD\": \"Minimal\", \"#FF948D99\": \"Minimal Grey\", \"#FFF2CFE0\": \"Minimal Rose\", \"#FFCABEAD\": \"Minimalist\", \"#FFE9ECE5\": \"Minimalistic\", \"#FFE8D3BA\": \"Minimum Beige\", \"#FFFECE4E\": \"Minion Yellow\", \"#FFF3DD51\": \"Minions\", \"#FF8A7561\": \"Mink\", \"#FF67594C\": \"Mink Brown\", \"#FFD7CFC6\": \"Mink Frost\", \"#FFC5B29F\": \"Mink Haze\", \"#FF7F7674\": \"Mink Suede\", \"#FF9B9FB5\": \"Minnesota April\", \"#FFB7DFE8\": \"Minor Blue\", \"#FF734B42\": \"Minotaur Red\", \"#FF882211\": \"Minotaurus Brown\", \"#FF3E3267\": \"Minsk Variant\", \"#FF118800\": \"Minstrel of the Woods\", \"#FFC89697\": \"Minstrel Rose\", \"#FF7EFFBA\": \"Mint Bliss\", \"#FFD7C2CE\": \"Mint Blossom Rose\", \"#FFBCE0DF\": \"Mint Blue\", \"#FF7DB6A8\": \"Mint Bonbon Green\", \"#FFE6FDF1\": \"Mint Chiffon\", \"#FFCFEBEA\": \"Mint Chip\", \"#FFA9CEAA\": \"Mint Circle\", \"#FFB8E2B0\": \"Mint Cocktail Green\", \"#FFCCFFEE\": \"Mint Coffee\", \"#FF6CBBA0\": \"Mint Cold Green\", \"#FFDFFBF3\": \"Mint Condition\", \"#FFDFEADB\": \"Mint Emulsion\", \"#FFE6F3E7\": \"Mint Fizz\", \"#FFDCF4E6\": \"Mint Flash\", \"#FFD0EBC8\": \"Mint Frapp\\u00e9\", \"#FFC1BFA5\": \"Mint Frost\", \"#FFB1D9C4\": \"Mint Gala\", \"#FFC8F3CD\": \"Mint Gloss\", \"#FFE2F0E0\": \"Mint Grasshopper\", \"#FF487D4A\": \"Mint Green Tint\", \"#FFBDE8D8\": \"Mint Ice\", \"#FF98CDB5\": \"Mint Ice Cream\", \"#FFC9CAA1\": \"Mint Ice Green\", \"#FFC5DCC6\": \"Mint Intermezzo\", \"#FF45CEA2\": \"Mint Jelly\", \"#FFDEF0A3\": \"Mint Julep Variant\", \"#FF00CFB0\": \"Mint Leaf\", \"#FF6A7D4E\": \"Mint Leaves\", \"#FF7DD7C0\": \"Mint Majesty\", \"#FFB9E0D3\": \"Mint Mist\", \"#FF00DDCC\": \"Mint Morning\", \"#FFB4CCBD\": \"Mint Mousse\", \"#FFBBE6BB\": \"Mint Parfait\", \"#FFDAEED3\": \"Mint Shake\", \"#FFC5E6D1\": \"Mint Smoothie\", \"#FFCBD5B1\": \"Mint Soap\", \"#FF95B090\": \"Mint Stone\", \"#FFAFEEE1\": \"Mint Tea\", \"#FF98FF97\": \"Mint Variant\", \"#FF99EEAA\": \"Mint Tonic\", \"#FFC6EADD\": \"Mint Tulip Variant\", \"#FF98CBBA\": \"Mint Twist\", \"#FFDCE5D8\": \"Mint Wafer\", \"#FFC9E5DA\": \"Mint Whisper\", \"#FFCCFFDD\": \"Mint Zest\", \"#FFB6E9C8\": \"Mint-o-licious\", \"#FF78BFB2\": \"Mintage\", \"#FFAFFFD5\": \"Mintastic\", \"#FFE0EAD8\": \"Minted\", \"#FF26A6BE\": \"Minted Blue\", \"#FFB32651\": \"Minted Blueberry Lemonade\", \"#FF6EC9A3\": \"Minted Elegance\", \"#FFD8F3EB\": \"Minted Ice\", \"#FFC1C6A8\": \"Minted Lemon\", \"#FFABF4D2\": \"Mintie\", \"#FF7CBBAE\": \"Mintnight\", \"#FF80D9CC\": \"Mintos\", \"#FFD2E2D5\": \"Minty Delight\", \"#FFD2F2E7\": \"Minty Fresh\", \"#FFDBE8CF\": \"Minty Frosting\", \"#FF0BF77D\": \"Minty Green\", \"#FF00FFBB\": \"Minty Paradise\", \"#FFA5B6CF\": \"Minuet\", \"#FF777BA9\": \"Minuet Lilac\", \"#FFB38081\": \"Minuet Rose\", \"#FFE8E6E7\": \"Minuet White\", \"#FFD47791\": \"Minuette\", \"#FFF2E4F5\": \"Minute Mauve\", \"#FF886793\": \"Mirabella\", \"#FFF3BE67\": \"Mirabelle Yellow\", \"#FF898696\": \"Miracle\", \"#FF255BA2\": \"Miracle at Wrigley\", \"#FF799292\": \"Miracle Bay\", \"#FF617BA6\": \"Miracle Elixir\", \"#FFBCDCCD\": \"Mirador\", \"#FF373F43\": \"Mirage Variant\", \"#FF4F938F\": \"Mirage Lake\", \"#FF7B1C6E\": \"Mirage of Violets\", \"#FF614251\": \"Miranda\\u2019s Spike\", \"#FFD6D4D7\": \"Mirror Ball\", \"#FF7AA8CB\": \"Mirror Lake\", \"#FFA8B0B2\": \"Mirror Mirror\", \"#FF8E876E\": \"Mirrored Willow\", \"#FFC2AFBA\": \"Mischief\", \"#FF954738\": \"Mischief Maker\", \"#FFB7BAB9\": \"Mischief Mouse\", \"#FFDFF2DD\": \"Mischievous\", \"#FFA5A9B2\": \"Mischka Variant\", \"#FFD4BA9E\": \"Mish Mosh\", \"#FFEFF0C0\": \"Missed\", \"#FF6F5D57\": \"Missing Link\", \"#FF9BA9AB\": \"Mission Bay Blue\", \"#FF775C47\": \"Mission Brown\", \"#FF818387\": \"Mission Control\", \"#FFF3D1B3\": \"Mission Courtyard\", \"#FFB78D61\": \"Mission Gold\", \"#FFB29C7F\": \"Mission Hills\", \"#FF456252\": \"Mission Jewel\", \"#FFDAC5B6\": \"Mission Stone\", \"#FFDAC6A8\": \"Mission Tan\", \"#FF874C3E\": \"Mission Tile\", \"#FF857A64\": \"Mission Trail\", \"#FFE2D8C2\": \"Mission White\", \"#FF9E5566\": \"Mission Wildflower\", \"#FF99886F\": \"Mississippi Mud\", \"#FF3B638C\": \"Mississippi River\", \"#FFA6A19B\": \"Missouri Mud\", \"#FFE4EBE7\": \"Mist Spirit\", \"#FFF8EED6\": \"Mist Yellow\", \"#FFD7E7E6\": \"Misted Aqua\", \"#FFA2B7CF\": \"Misted Eve\", \"#FFE1ECD1\": \"Misted Fern\", \"#FFDAB965\": \"Misted Yellow\", \"#FF8AA282\": \"Mistletoe\", \"#FF98B489\": \"Mistletoe Kiss\", \"#FF5A8065\": \"Mistletoe Whisper\", \"#FFB8BFCC\": \"Mistral\", \"#FFCDD2D2\": \"Misty\", \"#FFC6DCC7\": \"Misty Afternoon\", \"#FFBCDBDB\": \"Misty Aqua\", \"#FFF1EEDF\": \"Misty Beach Cattle\", \"#FFD2D59B\": \"Misty Bead\", \"#FFB4C4C3\": \"Misty Blue\", \"#FFDDC9C6\": \"Misty Blush\", \"#FFD5D9D3\": \"Misty Coast\", \"#FF83BBC1\": \"Misty Cold Sea\", \"#FFE4E5E0\": \"Misty Dawn\", \"#FFADC2BE\": \"Misty Dreams\", \"#FFCDE7DB\": \"Misty Glen\", \"#FF65434D\": \"Misty Grape\", \"#FF65769A\": \"Misty Harbour\", \"#FFCEC9C3\": \"Misty Haze\", \"#FFDCE5CC\": \"Misty Hillside\", \"#FFC5E4DC\": \"Misty Isle\", \"#FFACD0BB\": \"Misty Jade\", \"#FFC2D5C4\": \"Misty Lake\", \"#FFDBD9E1\": \"Misty Lavender\", \"#FFDFFAE1\": \"Misty Lawn\", \"#FFB9B1C2\": \"Misty Lilac\", \"#FFE4BDA8\": \"Misty Loch\", \"#FFD3E1D3\": \"Misty Marsh\", \"#FFBEC0B0\": \"Misty Meadow\", \"#FFEAC3D2\": \"Misty Memories\", \"#FFCBCDBE\": \"Misty Memory\", \"#FFDBC6B9\": \"Misty Mink\", \"#FFDEECDA\": \"Misty Mint\", \"#FFE5E0CC\": \"Misty Moonstone\", \"#FF718981\": \"Misty Moor\", \"#FFE7E1E3\": \"Misty Morn\", \"#FFB2C8BD\": \"Misty Morning\", \"#FFBAC1CC\": \"Misty Morning Dew\", \"#FFC0D0E6\": \"Misty Mountains\", \"#FFF7EBD1\": \"Misty Mustard\", \"#FFB5C8C9\": \"Misty Surf\", \"#FFBDC389\": \"Misty Valley\", \"#FFDBD7E4\": \"Misty Violet\", \"#FF0D789F\": \"Mitchell Blue\", \"#FF878787\": \"Mithril\", \"#FFBBBBC1\": \"Mithril Silver\", \"#FFCCCCBA\": \"Mix or Match\", \"#FF96819A\": \"Mixed Berries\", \"#FF6A4652\": \"Mixed Berry Jam\", \"#FFF9BAB2\": \"Mixed Fruit\", \"#FF719166\": \"Mixed Veggies\", \"#FF6E8659\": \"Mixedwood Leaf\", \"#FFE4030F\": \"Miyamoto Red\", \"#FF6FEA3E\": \"Miyazaki Verdant\", \"#FF70C1E0\": \"Mizu\", \"#FFA7DBED\": \"Mizu Cyan\", \"#FF749F8D\": \"Mizuasagi Green\", \"#FF1A3F2C\": \"Mizukaze Green\", \"#FF3E6A6B\": \"Moat\", \"#FF605A67\": \"Mobster Variant\", \"#FFDDE8ED\": \"Moby Dick\", \"#FFFBEBD6\": \"Moccasin\", \"#FF9D7651\": \"Mocha Variant\", \"#FF8D8171\": \"Mocha Accent\", \"#FF847569\": \"Mocha Bean\", \"#FF9A6340\": \"Mocha Bisque\", \"#FF6B565E\": \"Mocha Brown\", \"#FFBEAF93\": \"Mocha Cake\", \"#FFF1D96E\": \"Mocha Dandelion\", \"#FF8E664E\": \"Mocha Delight\", \"#FFBBA28E\": \"Mocha Foam\", \"#FF773322\": \"Mocha Glow\", \"#FFDFD2CA\": \"Mocha Ice\", \"#FF82715F\": \"Mocha Latte\", \"#FF8B6B58\": \"Mocha Madness\", \"#FF88796D\": \"Mocha Magic\", \"#FF996E5B\": \"Mocha Mousse\", \"#FF926F53\": \"Mocha Syrup\", \"#FFAC9680\": \"Mocha Tan\", \"#FF918278\": \"Mocha Wisp\", \"#FF945200\": \"Mochaccino\", \"#FF8EFA00\": \"Mochito\", \"#FFFF9863\": \"Mock Orange\", \"#FFD8583C\": \"Mod Orange\", \"#FF31A6D1\": \"Modal\", \"#FF40A6AC\": \"Modal Blue\", \"#FF96711F\": \"Mode Beige Variant\", \"#FF484F49\": \"Model T\", \"#FFE9DECF\": \"Moderate White\", \"#FFAD9167\": \"Modern Avocado\", \"#FFBAD1E9\": \"Modern Blue\", \"#FFD5CEC2\": \"Modern Grey\", \"#FFBEA27D\": \"Modern History\", \"#FFF5ECDC\": \"Modern Ivory\", \"#FFA8AAB3\": \"Modern Lavender\", \"#FF88A395\": \"Modern Mint\", \"#FF9D8376\": \"Modern Mocha\", \"#FFE0DEB2\": \"Modern Zen\", \"#FF745B49\": \"Moderne Class\", \"#FF838492\": \"Modest Mauve\", \"#FFC7C0BC\": \"Modest Silver\", \"#FFE9E4EF\": \"Modest Violet\", \"#FFE6DDD4\": \"Modest White\", \"#FFEEA59D\": \"Modestly Peach\", \"#FFD4C7D9\": \"Modesty\", \"#FFC3B68B\": \"Modish Moss\", \"#FFF19172\": \"Moegi Green\", \"#FF553311\": \"Moelleux au Chocolat\", \"#FFC8A692\": \"Moenkopi Soil\", \"#FFDDCC00\": \"Mogwa-Cheong Yellow\", \"#FFBFA59E\": \"Mohair Mauve\", \"#FFA78594\": \"Mohair Pink\", \"#FF97B2B7\": \"Mohair Soft Blue Grey\", \"#FFA79B7E\": \"Mohalla\", \"#FFBEADB0\": \"Moire\", \"#FF665D63\": \"Moire Satin\", \"#FFDBDB70\": \"Moist Gold\", \"#FFE0E7DD\": \"Moist Silver\", \"#FF004422\": \"Moisty Mire\", \"#FFBEA684\": \"Mojave Desert\", \"#FFB99178\": \"Mojave Dusk\", \"#FFBF9C65\": \"Mojave Gold\", \"#FFAA6A53\": \"Mojave Sunset\", \"#FFE4F3E0\": \"Mojito\", \"#FF97463C\": \"Mojo Variant\", \"#FF574A47\": \"Molasses\", \"#FF8B714B\": \"Molasses Cookie\", \"#FF392D2B\": \"Mole\", \"#FF938F8A\": \"Mole Grey\", \"#FFB0A196\": \"Moleskin\", \"#FFE6BCA0\": \"Mollusca\", \"#FFE3EFE3\": \"Molly Green\", \"#FF4D8B72\": \"Molly Robins\", \"#FFC69C04\": \"Molten Bronze\", \"#FFBB7A39\": \"Molten Caramel\", \"#FFE8C690\": \"Molten Gold\", \"#FFE1EDE6\": \"Molten Ice\", \"#FFB5332E\": \"Molten Lava\", \"#FF686A69\": \"Molten Lead\", \"#FFEAB781\": \"Mom\\u2019s Apple Pie\", \"#FFFFD4BB\": \"Mom\\u2019s Love\", \"#FFF5C553\": \"Mom\\u2019s Pancake\", \"#FF8FC1E5\": \"Moment of Grace\", \"#FF57493D\": \"Momentous Occasion\", \"#FF746F5C\": \"Momentum\", \"#FFF47983\": \"Momo Peach\", \"#FF542D24\": \"Momoshio Brown\", \"#FFC45971\": \"Mon Cher Ami\", \"#FFFF9889\": \"Mona Lisa Tint\", \"#FFABD4E6\": \"Monaco\", \"#FF274376\": \"Monaco Blue\", \"#FF6B252C\": \"Monarch Variant\", \"#FFB7813C\": \"Monarch Gold\", \"#FFBF764C\": \"Monarch Migration\", \"#FFEFA06B\": \"Monarch Orange\", \"#FF543941\": \"Monarch Velvet\", \"#FFFF8D25\": \"Monarch Wing\", \"#FF8CB293\": \"Monarch\\u2019s Cocoon\", \"#FF4B62D2\": \"Monarchist\", \"#FF9093AD\": \"Monarchy\", \"#FF41363A\": \"Monastery Mantle\", \"#FFABA9D2\": \"Monastic\", \"#FFB78999\": \"Monastir\", \"#FF9BB9AE\": \"Moncur\", \"#FF554D42\": \"Mondo Variant\", \"#FF0F478C\": \"Mondrian Blue\", \"#FFC3CFDC\": \"Monet\", \"#FFCDD7E6\": \"Monet Lily\", \"#FFC1ACC3\": \"Monet Magic\", \"#FFEEF0D1\": \"Monet Moonrise\", \"#FF92DBC4\": \"Monet Vert\", \"#FFDDE0EA\": \"Monet\\u2019s Lavender\", \"#FF7B9A6D\": \"Money\", \"#FFAABE49\": \"Money Banks\", \"#FFC9937A\": \"Money Tree\", \"#FF777700\": \"Mongolian Plateau\", \"#FFA58B6F\": \"Mongoose Variant\", \"#FF6E6355\": \"Monk\\u2019s Cloth\", \"#FF553B39\": \"Monkey Island\", \"#FFBF6414\": \"Monkey King\", \"#FF63584C\": \"Monkey Madness\", \"#FFAC9894\": \"Monkeypod\", \"#FF704822\": \"Monks Robe\", \"#FF595747\": \"Monogram\", \"#FFA1BCD8\": \"Monologue\", \"#FFB8BCBB\": \"Monorail Silver\", \"#FFDEC1B8\": \"Monroe Kiss\", \"#FF7A7679\": \"Monsoon Variant\", \"#FF839AB0\": \"Monsoon Season\", \"#FF2F8351\": \"Monster Monstera\", \"#FF5F674B\": \"Monstera\", \"#FF75BF0A\": \"Monstera Deliciosa\", \"#FF22CC11\": \"Monstrous Green\", \"#FF9EB6D8\": \"Mont Blanc\", \"#FFF2E7E7\": \"Mont Blanc Peak\", \"#FF8190A4\": \"Montage\", \"#FF393B3C\": \"Montana\", \"#FF76627C\": \"Montana Grape\", \"#FF6AB0B9\": \"Montana Sky\", \"#FFE2AC6E\": \"Montana Wheat Field\", \"#FFBBAD9E\": \"Montauk Sands\", \"#FF7AC5B4\": \"Monte Carlo Variant\", \"#FFB6A180\": \"Montecito\", \"#FF3FBABD\": \"Montego Bay\", \"#FF946E5C\": \"Monterey Brown\", \"#FF7D4235\": \"Monterey Chestnut\", \"#FFE0DFEA\": \"Monterey Mist\", \"#FFD2CDB6\": \"Montezuma\", \"#FFEECC44\": \"Montezuma Gold\", \"#FFA6B2A4\": \"Montezuma Hills\", \"#FFD9AD9E\": \"Montezuma\\u2019s Castle\", \"#FF5879A2\": \"Montreux Blue\", \"#FF9D6A73\": \"Montrose Rose\", \"#FF84898C\": \"Monument\", \"#FFD3C190\": \"Monument Green\", \"#FFAD5C34\": \"Monument Valley\", \"#FFFBE5BD\": \"Moo\", \"#FF393F52\": \"Mood Indigo\", \"#FFFFE7D5\": \"Mood Lighting\", \"#FF7F90CB\": \"Mood Mode\", \"#FF49555D\": \"Moody Black\", \"#FF586E75\": \"Moody Blues\", \"#FF6586A5\": \"Moody Indigo\", \"#FFCAE2D9\": \"Moody Mist\", \"#FF4B7991\": \"Moody Teal\", \"#FF8F9294\": \"Moody Whitby\", \"#FFC7B8A9\": \"Mooloolaba\", \"#FF7D7D77\": \"Moon Base\", \"#FFC7BDC1\": \"Moon Buggy\", \"#FFFAEFBE\": \"Moon Dance\", \"#FFDDD5C9\": \"Moon Drop\", \"#FFDFE5E4\": \"Moon Garden\", \"#FFBCD1C7\": \"Moon Glass\", \"#FFF5F3CE\": \"Moon Glow Variant\", \"#FFCFC7D5\": \"Moon Goddess\", \"#FF8EB8CE\": \"Moon Jellyfish\", \"#FFA7A7A7\": \"Moon Landing\", \"#FFE6E6E7\": \"Moon Lily\", \"#FFFAF1DE\": \"Moon Maiden\", \"#FFF4F4E8\": \"Moon Rise\", \"#FF897D76\": \"Moon Rock\", \"#FF96A5B8\": \"Moon Shadow\", \"#FFE9E3D8\": \"Moon Shell\", \"#FFCBC5BB\": \"Moon Shot\", \"#FF6F8588\": \"Moon Tide\", \"#FFFCF1DE\": \"Moon Valley\", \"#FF8D99B1\": \"Moon Veil\", \"#FFEAF4FC\": \"Moon White\", \"#FFF0C420\": \"Moon Yellow\", \"#FFC2B8AE\": \"Moonbeam\", \"#FFF3DEBF\": \"Moondoggie\", \"#FF65FFFF\": \"Moonglade Water\", \"#FF1E2433\": \"Moonless Mystery\", \"#FF3C393D\": \"Moonless Night\", \"#FF444B4A\": \"Moonless Sky\", \"#FFF6EED5\": \"Moonlight\", \"#FF567090\": \"Moonlight Blue\", \"#FFD2E8D8\": \"Moonlight Green\", \"#FFC7E5DF\": \"Moonlight Jade\", \"#FFCA83A7\": \"Moonlight Mauve\", \"#FFAF73B0\": \"Moonlight Melody\", \"#FF4E468B\": \"Moonlight Sonata\", \"#FF999FB2\": \"Moonlight Stroll\", \"#FFF9F0DE\": \"Moonlight White\", \"#FFE1C38B\": \"Moonlight Yellow\", \"#FFF9F0E6\": \"Moonlit Beach\", \"#FF3E6D6A\": \"Moonlit Forest\", \"#FFD28FB0\": \"Moonlit Mauve\", \"#FF30445A\": \"Moonlit Ocean\", \"#FF949194\": \"Moonlit Orchid\", \"#FF205A61\": \"Moonlit Pool\", \"#FFEAEEEC\": \"Moonlit Snow\", \"#FFC9D9E0\": \"Moonmist\", \"#FF8D9596\": \"Moonquake\", \"#FFC0B2D7\": \"Moonraker\", \"#FFA53F48\": \"Moonrose\", \"#FF806B77\": \"Moonscape\", \"#FFC3C2B2\": \"Moonshine\", \"#FF3AA8C1\": \"Moonstone\", \"#FFFCF0C2\": \"Moonstruck\", \"#FFBEBEC4\": \"Moonwalk\", \"#FFA5AE9F\": \"Moonwort\", \"#FF6A584D\": \"Moor Oak Grey\", \"#FF3C6461\": \"Moor Pond Green\", \"#FF1F5429\": \"Moor-Monster\", \"#FFA6AB9B\": \"Moorland\", \"#FFCC94BE\": \"Moorland Heather\", \"#FFCFD1CA\": \"Moorstone\", \"#FF725440\": \"Moose Fur\", \"#FFCAB59F\": \"Moose Mousse\", \"#FF6B5445\": \"Moose Trail\", \"#FF5D5744\": \"Moosewood\", \"#FFA2DB10\": \"Moot Green\", \"#FF00EE33\": \"Moping Green\", \"#FF9955CC\": \"Morado Purple\", \"#FFCEB391\": \"Moraine\", \"#FFB4CDE5\": \"Morality\", \"#FF726138\": \"Morass\", \"#FFC8BD6A\": \"Moray\", \"#FF00A78B\": \"Moray Eel\", \"#FF9E0E64\": \"Morbid Princess\", \"#FF2A6671\": \"Mordant Blue\", \"#FF2F5684\": \"Mordian Blue\", \"#FFDFBF9A\": \"More Cowbell\", \"#FFD0AB70\": \"More Maple\", \"#FFE0E3C8\": \"More Melon\", \"#FFE6E8C5\": \"More Mint\", \"#FF8D8D8D\": \"More Than a Week\", \"#FF73645C\": \"Morel\", \"#FFDFCEC6\": \"Morganite\", \"#FF82979B\": \"Morning at Sea\", \"#FFF4DABB\": \"Morning Blossom\", \"#FFF9E8DF\": \"Morning Blush\", \"#FFE7E6DE\": \"Morning Bread\", \"#FFD5E3DE\": \"Morning Breeze\", \"#FFCEEEEF\": \"Morning Calm\", \"#FFCED5E3\": \"Morning Chill\", \"#FFB0B9AC\": \"Morning Dew\", \"#FFC6DBD6\": \"Morning Dew White\", \"#FFD0DBD7\": \"Morning Fog\", \"#FF6DAE81\": \"Morning Forest\", \"#FFEBF4DF\": \"Morning Frost\", \"#FF9ED1D3\": \"Morning Glory Variant\", \"#FFCA99B7\": \"Morning Glory Pink\", \"#FFEEF0D6\": \"Morning Glow\", \"#FF89BAB2\": \"Morning Green\", \"#FFE0E8ED\": \"Morning Haze\", \"#FFC9CCC9\": \"Morning Lake\", \"#FFE0EFE9\": \"Morning Light Wave\", \"#FFEE8A67\": \"Morning Marmalade\", \"#FFE5EDF1\": \"Morning Mist\", \"#FFADA7B9\": \"Morning Mist Grey\", \"#FFF7EECF\": \"Morning Moon\", \"#FFDAD6AE\": \"Morning Moor\", \"#FFACC0BD\": \"Morning Parlour\", \"#FFDEE4DC\": \"Morning Rush\", \"#FFF8EAED\": \"Morning Shine\", \"#FFD3DCEA\": \"Morning Shower\", \"#FFFCE9DE\": \"Morning Sigh\", \"#FFC7ECEA\": \"Morning Sky\", \"#FFF5F4ED\": \"Morning Snow\", \"#FFE4ECE9\": \"Morning Song\", \"#FFC3D1E5\": \"Morning Star\", \"#FFF3E6CE\": \"Morning Sun\", \"#FFFDEFCC\": \"Morning Sunlight\", \"#FFCABD94\": \"Morning Tea\", \"#FFE7D2A9\": \"Morning Wheat\", \"#FFCBCDB9\": \"Morning Zen\", \"#FFD9BE77\": \"Morning\\u2019s Egg\", \"#FFF3E2DF\": \"Morningside\", \"#FFDCC6B9\": \"Mornington\", \"#FF115674\": \"Moroccan Blue\", \"#FF75583D\": \"Moroccan Blunt\", \"#FF7C726C\": \"Moroccan Brown\", \"#FF6B5E5D\": \"Moroccan Dusk\", \"#FF6E5043\": \"Moroccan Henna\", \"#FF6D4444\": \"Moroccan Leather\", \"#FFB4C0C3\": \"Moroccan Moderne\", \"#FFEAE0D4\": \"Moroccan Moonlight\", \"#FF335E8B\": \"Moroccan Resort\", \"#FF8D504B\": \"Moroccan Ruby\", \"#FFBF7756\": \"Moroccan Sky\", \"#FF8F623B\": \"Moroccan Spice\", \"#FFB67267\": \"Morocco\", \"#FF442D21\": \"Morocco Brown Variant\", \"#FF96453B\": \"Morocco Red\", \"#FFECE3CC\": \"Morocco Sand\", \"#FFAC8F6C\": \"Morrel\", \"#FF8CB295\": \"Morris Artichoke\", \"#FFA0B8CE\": \"Morris Blue\", \"#FFC2D3AF\": \"Morris Leaf\", \"#FFADA193\": \"Morris Room Grey\", \"#FF546B78\": \"Morro Bay\", \"#FFFCFCCF\": \"Morrow White\", \"#FFDEAD00\": \"Mortal Yellow\", \"#FF565051\": \"Mortar Variant\", \"#FF9E9F9E\": \"Mortar Grey\", \"#FF00E6D3\": \"MoS\\u2082 Cyan\", \"#FF007C94\": \"Mosaic Blue\", \"#FF599F68\": \"Mosaic Green\", \"#FFE8CEC5\": \"Mosaic Pink\", \"#FF1C6B69\": \"Mosaic Tile\", \"#FF204652\": \"Moscow Midnight\", \"#FFEECC77\": \"Moscow Mule\", \"#FF937C00\": \"Moscow Papyrus\", \"#FF2E4E36\": \"Moselle Green\", \"#FF005F5B\": \"Mosque Variant\", \"#FF86A852\": \"Mosquito Fern\", \"#FF009051\": \"Moss\", \"#FFA0AA9A\": \"Moss Agate\", \"#FF6B7061\": \"Moss Beach\", \"#FF715B2E\": \"Moss Brown\", \"#FF8AA775\": \"Moss Candy\", \"#FF42544C\": \"Moss Cottage\", \"#FF7A7E66\": \"Moss Covered\", \"#FF768B59\": \"Moss Gardens\", \"#FF4A473F\": \"Moss Glen\", \"#FFAFAB97\": \"Moss Grey\", \"#FFC7CAC1\": \"Moss Ink\", \"#FFC8C6B4\": \"Moss Island\", \"#FF6D7E40\": \"Moss Landing\", \"#FFDEE1D3\": \"Moss Mist\", \"#FF7E8D60\": \"Moss Point Green\", \"#FFAFB796\": \"Moss Print\", \"#FF729067\": \"Moss Ring\", \"#FF5E5B4D\": \"Moss Rock\", \"#FF8F6D6B\": \"Moss Rose\", \"#FFB4A54B\": \"Moss Stone\", \"#FF38614C\": \"Moss Vale\", \"#FFB4C2B6\": \"Mossa\", \"#FF779966\": \"Mosslands\", \"#FF8C9D8F\": \"Mossleaf\", \"#FF7F805B\": \"Mosstone\", \"#FF857349\": \"Mossy\", \"#FF88806F\": \"Mossy Aura\", \"#FF8B8770\": \"Mossy Bank\", \"#FF83A28F\": \"Mossy Bench\", \"#FF525F48\": \"Mossy Bronze\", \"#FFA4A97B\": \"Mossy Cavern\", \"#FF789B4A\": \"Mossy Glossy\", \"#FF9C9273\": \"Mossy Gold\", \"#FF5A7C46\": \"Mossy Green\", \"#FF867E36\": \"Mossy Meadow\", \"#FF848178\": \"Mossy Oak\", \"#FF908C7E\": \"Mossy Pavement\", \"#FFA9965D\": \"Mossy Rock\", \"#FF7E6C44\": \"Mossy Shade\", \"#FFBAD147\": \"Mossy Shining Gold\", \"#FF828E74\": \"Mossy Statue\", \"#FFE7F2DE\": \"Mossy White\", \"#FF7A9703\": \"Mossy Woods\", \"#FFE3D6D4\": \"Most Delicate\", \"#FF575E5F\": \"Mostly Metal\", \"#FFC1C1C5\": \"Mote of Dust\", \"#FFCBC1A2\": \"Moth\", \"#FF007700\": \"Moth Green\", \"#FFDAD3CB\": \"Moth Grey\", \"#FFEDEBDE\": \"Moth Mist\", \"#FFD00172\": \"Moth Orchid\", \"#FFCFBDBA\": \"Moth Pink\", \"#FFEDF1DB\": \"Moth\\u2019s Wing\", \"#FF849C8D\": \"Mother Earth\", \"#FFA28761\": \"Mother Lode\", \"#FFBDE1C4\": \"Mother Nature\", \"#FFE9D5C3\": \"Mother of Pearl\", \"#FF8FD89F\": \"Mother of Pearl Green\", \"#FFD1C4C6\": \"Mother of Pearl Pink\", \"#FFCCD6E6\": \"Mother of Pearl Silver\", \"#FFF7EDCA\": \"Mother\\u2019s Milk\", \"#FFBCB667\": \"Motherland\", \"#FFEEDD82\": \"Mothra Wing\", \"#FFCEBBB3\": \"Mothy\", \"#FFA58E71\": \"Motif\", \"#FF495A6E\": \"Motor City Blue\", \"#FF917C6F\": \"Motto\", \"#FFD5A300\": \"Mouldy Ochre\", \"#FFE7EFE0\": \"Mount Eden\", \"#FF3D484C\": \"Mount Etna\", \"#FF3D703E\": \"Mount Hyjal\", \"#FFBAC0CD\": \"Mount Nirvana\", \"#FF716646\": \"Mount Olive\", \"#FFD4FFFF\": \"Mount Olympus\", \"#FFCAD3D4\": \"Mount Sterling\", \"#FF7C7B6A\": \"Mount Tam\", \"#FFE6E0E0\": \"Mountain Air\", \"#FFCC7700\": \"Mountain Ash\", \"#FF3C4B6C\": \"Mountain Blueberry\", \"#FF4C98C2\": \"Mountain Bluebird\", \"#FFBFB8B5\": \"Mountain Boulder\", \"#FFE2EFE8\": \"Mountain Crystal Silver\", \"#FFCFE2E0\": \"Mountain Dew\", \"#FF867965\": \"Mountain Elk\", \"#FFBDCAC0\": \"Mountain Falls\", \"#FF94B491\": \"Mountain Fern\", \"#FF383C49\": \"Mountain Fig\", \"#FF6C71A6\": \"Mountain Flower Mauve\", \"#FFF4DBC7\": \"Mountain Fog\", \"#FF4D663E\": \"Mountain Forest\", \"#FFB2B599\": \"Mountain Green\", \"#FFE8E3DB\": \"Mountain Grey\", \"#FF6C6E7E\": \"Mountain Haze\", \"#FFEEDAE6\": \"Mountain Heather\", \"#FFA2917B\": \"Mountain Hideaway\", \"#FF5C5687\": \"Mountain Iris\", \"#FF2D5975\": \"Mountain Lake\", \"#FF4CBCA7\": \"Mountain Lake Azure\", \"#FF85D4D4\": \"Mountain Lake Blue\", \"#FF75B996\": \"Mountain Lake Green\", \"#FFF4C8D5\": \"Mountain Laurel\", \"#FFA7AE9E\": \"Mountain Lichen\", \"#FF8DB8D0\": \"Mountain Main\", \"#FFEFCC7C\": \"Mountain Maize\", \"#FF418638\": \"Mountain Meadow Green\", \"#FF385058\": \"Mountain Midnight\", \"#FFA7E0C2\": \"Mountain Mint\", \"#FFA09F9C\": \"Mountain Mist Variant\", \"#FFD4DCD1\": \"Mountain Morn\", \"#FF94A293\": \"Mountain Moss\", \"#FF908456\": \"Mountain Olive\", \"#FF7F9F97\": \"Mountain Outlook\", \"#FF5C6A6A\": \"Mountain Pass\", \"#FFE9E0D4\": \"Mountain Peak\", \"#FF3B5257\": \"Mountain Pine\", \"#FF605B57\": \"Mountain Quail\", \"#FF53B8C9\": \"Mountain Range Blue\", \"#FF283123\": \"Mountain Range Green\", \"#FF75665E\": \"Mountain Ridge\", \"#FF475F77\": \"Mountain River\", \"#FF868578\": \"Mountain Road\", \"#FFA3AA8C\": \"Mountain Sage\", \"#FFB1AB9A\": \"Mountain Shade\", \"#FF8E877F\": \"Mountain Smoke\", \"#FFD9E1C1\": \"Mountain Spring\", \"#FF96AFB7\": \"Mountain Stream\", \"#FF615742\": \"Mountain Trail\", \"#FF394C3B\": \"Mountain View\", \"#FFD8D0E3\": \"Mountain\\u2019s Majesty\", \"#FFE9EAEB\": \"Mourn Mountain Snow\", \"#FF6F5749\": \"Mournfang Brown\", \"#FF1651BD\": \"Mourning Blue\", \"#FF928D88\": \"Mourning Dove\", \"#FF474354\": \"Mourning Violet\", \"#FF9E928F\": \"Mouse Catcher\", \"#FF727664\": \"Mouse Tail\", \"#FFBEB1B0\": \"Mouse Trap\", \"#FF6D2A13\": \"Moussaka\", \"#FFE8CEF6\": \"Mousse aux Pruneaux\", \"#FF5C4939\": \"Mousy Brown\", \"#FF5C544E\": \"Mousy Indigo\", \"#FFBF9005\": \"Moutarde de B\\u00e9nichon\", \"#FF4EFFCD\": \"Move Mint\", \"#FF9CCE9E\": \"Mover & Shaker\", \"#FFB2BFD5\": \"Movie Magic\", \"#FFC52033\": \"Movie Star\", \"#FFA9B49A\": \"Mow the Lawn\", \"#FF627948\": \"Mown Grass\", \"#FFE6D3BB\": \"Mown Hay\", \"#FFE5DAD8\": \"Moxie\", \"#FF485480\": \"Mozart\", \"#FFE39B7A\": \"Mozzarella Covered Chorizo\", \"#FFA3C5DB\": \"Mr Frosty\", \"#FFE4B857\": \"Mr Mustard\", \"#FFC0D5EF\": \"Mr. Glass\", \"#FFDBDBD4\": \"Mr. Kitty\", \"#FFD04127\": \"Mr. Krabs\", \"#FFFF00AA\": \"Ms. Pac-Man Kiss\", \"#FF597766\": \"Mt Burleigh\", \"#FFE7E9E6\": \"Mt. Hood White\", \"#FF7F8181\": \"Mt. Rushmore\", \"#FFF1F2D3\": \"M\\u01d4 L\\u00ec B\\u00e1i Oyster\", \"#FF70543E\": \"Mud\", \"#FF966544\": \"Mud Ball\", \"#FF7C6841\": \"Mud Bath\", \"#FFD0C8C4\": \"Mud Berry\", \"#FF60460F\": \"Mud Brown\", \"#FF606602\": \"Mud Green\", \"#FF847146\": \"Mud House\", \"#FF9D9588\": \"Mud Pack\", \"#FFDCC0C3\": \"Mud Pink\", \"#FFB6B5B1\": \"Mud Pots\", \"#FF9D958B\": \"Mud Puddle\", \"#FF60584B\": \"Mud Room\", \"#FFC18136\": \"Mud Yellow\", \"#FFA08B76\": \"Mud-Dell\", \"#FFA46960\": \"Mudbrick\", \"#FF5A5243\": \"Muddled Basil\", \"#FFA13905\": \"Muddy\", \"#FF886806\": \"Muddy Brown\", \"#FF3F6976\": \"Muddy Cyan\", \"#FF657432\": \"Muddy Green\", \"#FFE4B3CC\": \"Muddy Mauve\", \"#FFC3988B\": \"Muddy Mire\", \"#FF805C44\": \"Muddy Mississippi\", \"#FF4B5D46\": \"Muddy Olive\", \"#FF715D3D\": \"Muddy River\", \"#FFE2BEB4\": \"Muddy Rose\", \"#FFA9844F\": \"Muddy Waters Variant\", \"#FFBFAC05\": \"Muddy Yellow\", \"#FFB8D0DA\": \"Mudra\", \"#FF897A69\": \"Mudskipper\", \"#FF84735F\": \"Mudslide\", \"#FF84846F\": \"Mudstone\", \"#FF9E7E53\": \"Muesli Variant\", \"#FFF9DDC7\": \"Muffin Magic\", \"#FFF5E0D0\": \"Muffin Mix\", \"#FFDADBE2\": \"Muffled White\", \"#FF448800\": \"Mughal Green\", \"#FFA38961\": \"Mukluks\", \"#FF920A4E\": \"Mulberry Variant\", \"#FF956F29\": \"Mulberry Brown\", \"#FFAD6EA0\": \"Mulberry Bush\", \"#FF463F60\": \"Mulberry Mauve Black\", \"#FF9F556C\": \"Mulberry Mix\", \"#FF4A3C62\": \"Mulberry Purple\", \"#FF94766C\": \"Mulberry Silk\", \"#FFC6BABE\": \"Mulberry Stain\", \"#FFC57F2E\": \"Mulberry Thorn\", \"#FF997C85\": \"Mulberry Wine\", \"#FF4E4240\": \"Mulch\", \"#FF827B77\": \"Mule\", \"#FF884F40\": \"Mule Fawn Variant\", \"#FFC2B332\": \"Mulgore Mustard\", \"#FFA18162\": \"Mulled Cider\", \"#FF675A74\": \"Mulled Grape\", \"#FF763D57\": \"Mulled Plum\", \"#FFD5A579\": \"Mulled Spice\", \"#FF524D5B\": \"Mulled Wine Variant\", \"#FFCA4042\": \"Mullen Pink\", \"#FFC18654\": \"Mulling Spice\", \"#FFCCD0DD\": \"Multnomah Falls\", \"#FF55BB00\": \"Mulu Frog\", \"#FF824B27\": \"Mummy Brown\", \"#FF828E84\": \"Mummy\\u2019s Tomb\", \"#FFF23E67\": \"Munch on Melon\", \"#FF9BB139\": \"Munchkin\", \"#FFCAC76D\": \"Mung Bean\", \"#FFD2A172\": \"Muntok White Pepper\", \"#FFC5D6EE\": \"Murano Soft Blue\", \"#FF4F284B\": \"Murasaki\", \"#FF884898\": \"Murasaki Purple\", \"#FFAC7E04\": \"Murder Mustard\", \"#FFB3205F\": \"Murderous Magenta\", \"#FF5B8D6B\": \"Murdoch\", \"#FF847EB1\": \"Murex\", \"#FF02273A\": \"Murky Depths\", \"#FF6C7A0E\": \"Murky Green\", \"#FF7E8177\": \"Murky Sage\", \"#FFC7CFC7\": \"Murmur\", \"#FF6B3C39\": \"Murray Red\", \"#FFF4E5AB\": \"Muscadine\", \"#FFEBE2CF\": \"Muscat Blanc\", \"#FF5E5067\": \"Muscat Grape\", \"#FF7B6A68\": \"Muscatel\", \"#FF9B6957\": \"Muscovado Sugar\", \"#FFE9DECB\": \"Muscovite\", \"#FFA5857F\": \"Muse\", \"#FF685951\": \"Museum\", \"#FF2D4436\": \"Mushiao Green\", \"#FFBDACA3\": \"Mushroom\", \"#FF977A76\": \"Mushroom Basket\", \"#FFCAB49B\": \"Mushroom Bisque\", \"#FF906E58\": \"Mushroom Brown\", \"#FFD3BEAC\": \"Mushroom Cap\", \"#FF8E8062\": \"Mushroom Forest\", \"#FFDBD0CA\": \"Mushroom Risotto\", \"#FFF0E1CD\": \"Mushroom White\", \"#FFF8EAE6\": \"Musical Mist\", \"#FFCCA195\": \"Musk\", \"#FF7E5B58\": \"Musk Deer\", \"#FFCFBFB9\": \"Musk Dusk\", \"#FF774548\": \"Musk Memory\", \"#FF4D5052\": \"Muskeg Grey\", \"#FFA57545\": \"Muskelmannbraun\", \"#FF7D6D39\": \"Musket\", \"#FFE98447\": \"Muskmelon\", \"#FF7E6F4F\": \"Muskrat\", \"#FFD3D1C4\": \"Muslin\", \"#FFE0CDB1\": \"Muslin Tint\", \"#FF24342A\": \"Mussel Green\", \"#FFF0E2DE\": \"Mussel White\", \"#FF9B6B45\": \"Must Love Dogs\", \"#FF5E4A47\": \"Mustang\", \"#FFCEB301\": \"Mustard Variant\", \"#FFEF8144\": \"Mustard Crusted Salmon\", \"#FFD8B076\": \"Mustard Field\", \"#FFD2BD0A\": \"Mustard Flower\", \"#FFE7A733\": \"Mustard Glaze\", \"#FFA6894B\": \"Mustard Gold\", \"#FFA8B504\": \"Mustard Green\", \"#FF857139\": \"Mustard Magic\", \"#FFD5A129\": \"Mustard Musketeers\", \"#FFD5BD66\": \"Mustard Oil\", \"#FFDDCC33\": \"Mustard on Toast\", \"#FFEDBD68\": \"Mustard Sauce\", \"#FFC69F26\": \"Mustard Seed\", \"#FFC5A574\": \"Mustard Seed Beige\", \"#FFE1AD01\": \"Mustard Yellow\", \"#FFC29594\": \"Mutabilis\", \"#FF91788C\": \"Muted Berry\", \"#FF3B719F\": \"Muted Blue\", \"#FFCF8A78\": \"Muted Clay\", \"#FF515453\": \"Muted Ebony\", \"#FF5FA052\": \"Muted Green\", \"#FF3B5698\": \"Muted Lavender\", \"#FFD0C678\": \"Muted Lime\", \"#FFB3A9A3\": \"Muted Mauve\", \"#FF66626D\": \"Muted Mulberry\", \"#FFD1768F\": \"Muted Pink\", \"#FF805B87\": \"Muted Purple\", \"#FF954B51\": \"Muted Red\", \"#FF93907E\": \"Muted Sage\", \"#FFEE0000\": \"MVS Red\", \"#FFD3B395\": \"My Chai\", \"#FFF3C4C2\": \"My Fair Lady\", \"#FFCBB698\": \"My Guinea Pig\", \"#FFE1C6A8\": \"My Love\", \"#FFCABDCE\": \"My Mona\", \"#FFCFBAA4\": \"My Piazza\", \"#FFD68B80\": \"My Pink Variant\", \"#FF4F434E\": \"My Place or Yours\", \"#FFFDAE45\": \"My Sin Variant\", \"#FF6597AB\": \"My Skiff\", \"#FFF8E7DF\": \"My Sweetheart\", \"#FF387ABE\": \"Mykonos\", \"#FF005780\": \"Mykonos Blue\", \"#FF284C75\": \"Mykonos Reflection\", \"#FFE0218A\": \"Myoga Purple\", \"#FF00524C\": \"Myrtle Deep Green\", \"#FF9EB3DE\": \"Myrtle Flower\", \"#FFB77961\": \"Myrtle Pepper\", \"#FF8E6F76\": \"Myself\", \"#FF98817C\": \"Mystere\", \"#FF826F7A\": \"Mysteria\", \"#FF46394B\": \"Mysterioso\", \"#FF535E63\": \"Mysterious\", \"#FF3E7A85\": \"Mysterious Blue\", \"#FF060929\": \"Mysterious Depths\", \"#FFA6A3A9\": \"Mysterious Mauve\", \"#FF0F521A\": \"Mysterious Mixture\", \"#FF6F6A52\": \"Mysterious Moss\", \"#FF5C6070\": \"Mysterious Night\", \"#FF27454A\": \"Mysterious Waters\", \"#FFA4CDCC\": \"Mystery\", \"#FFBBEFD3\": \"Mystery Mint\", \"#FF063C89\": \"Mystery Oceans\", \"#FFD8DDDA\": \"Mystic Tint\", \"#FF48A8D0\": \"Mystic Blue\", \"#FFEAE9E1\": \"Mystic Fog\", \"#FFD8F878\": \"Mystic Green\", \"#FFD2E4EE\": \"Mystic Harbour\", \"#FF8596D2\": \"Mystic Iris\", \"#FFDDE5EC\": \"Mystic Light\", \"#FFE02E82\": \"Mystic Magenta\", \"#FFDBB7BA\": \"Mystic Mauve\", \"#FFEDEBB4\": \"Mystic Melon\", \"#FF4B2C74\": \"Mystic Nights\", \"#FFFBDDBE\": \"Mystic Opal\", \"#FFD5DDE2\": \"Mystic Pool\", \"#FFFF5500\": \"Mystic Red\", \"#FFB7CAE0\": \"Mystic River\", \"#FFF8C0BA\": \"Mystic Rose\", \"#FFB9E0DB\": \"Mystic Sea\", \"#FF5A4742\": \"Mystic Taupe\", \"#FFF9B3A3\": \"Mystic Tulip\", \"#FF00877B\": \"Mystic Turquoise\", \"#FFEBEBE9\": \"Mystic White\", \"#FF6E5881\": \"Mystical\", \"#FFB5AAA9\": \"Mystical Grey\", \"#FFE5E2E3\": \"Mystical Mist\", \"#FF745D83\": \"Mystical Purple\", \"#FFDCE3D1\": \"Mystical Sea\", \"#FF4C5364\": \"Mystical Shade\", \"#FF352B30\": \"Mystical Shadow\", \"#FF7A6A75\": \"Mystical Trip\", \"#FF2A4071\": \"Mystification\", \"#FFC9DBC7\": \"Mystified\", \"#FFC920B0\": \"Mystifying Magenta\", \"#FFA598A0\": \"Mystique\", \"#FF723D5B\": \"Mystique Violet\", \"#FF657175\": \"Myth\", \"#FF4A686C\": \"Mythic Forest\", \"#FF7E778E\": \"Mythical\", \"#FF93A8A7\": \"Mythical Blue\", \"#FF398467\": \"Mythical Forest\", \"#FF1C2E63\": \"Mythical Night\", \"#FFFF7F49\": \"Mythical Orange\", \"#FF7A0A14\": \"Mythical Wine\", \"#FFFFCB5D\": \"Nacho\", \"#FFFFBB00\": \"Nacho Cheese\", \"#FFE8E2D4\": \"Nacre\", \"#FFAFC9C0\": \"Nadia\", \"#FFC90406\": \"Naga Morich\", \"#FFED292B\": \"Naga Viper Pepper\", \"#FF3D3354\": \"Naggaroth Night\", \"#FFFDEDC3\": \"N\\u01cei Y\\u00f3u S\\u00e8 Cream\", \"#FFBD4E84\": \"Nail Polish Pink\", \"#FFD9A787\": \"Nairobi Dusk\", \"#FFFCE7D3\": \"Naive Peach\", \"#FFF6EBE6\": \"Naivete\", \"#FFC93756\": \"Nakabeni Pink\", \"#FFC8A397\": \"Naked Clay\", \"#FFF7CB6E\": \"Naked Noodle\", \"#FFEBB5B3\": \"Naked Rose\", \"#FF785E49\": \"Namakabe Brown\", \"#FF7B7C7D\": \"Namara Grey\", \"#FFBDD8C0\": \"Namaste\", \"#FF7C6D61\": \"Namibia\", \"#FFA08DA7\": \"Nana\", \"#FFDFCBC3\": \"Nana\\u2019s Pearls\", \"#FFDE9EAA\": \"Nana\\u2019s Rose\", \"#FF57B8DC\": \"Nancy\", \"#FF8F423D\": \"Nandi Bear\", \"#FF4E5D4E\": \"Nandor Variant\", \"#FFB89E82\": \"Nankeen\", \"#FFF2F0EA\": \"Nano White\", \"#FFE3B130\": \"Nanohanacha Gold\", \"#FF7D9192\": \"Nantucket Bay\", \"#FFD0BFAA\": \"Nantucket Dune\", \"#FFCABFBF\": \"Nantucket Mist\", \"#FFB4A89A\": \"Nantucket Sands\", \"#FFA39A87\": \"Napa Variant\", \"#FFE1D8D5\": \"Napa Dawn\", \"#FF5B5162\": \"Napa Grape\", \"#FF534853\": \"Napa Harvest\", \"#FFCD915C\": \"Napa Sunset\", \"#FF5D4149\": \"Napa Wine\", \"#FF6A5C7D\": \"Napa Winery\", \"#FFEFDDC1\": \"Napery\", \"#FFFADA5F\": \"Naples Yellow Variant\", \"#FF404149\": \"Napoleon\", \"#FF2C4170\": \"Napoleonic Blue\", \"#FFFF8050\": \"N\\u0101rang\\u012b Orange\", \"#FFC39449\": \"Narcissus\", \"#FFE6E3D8\": \"Narcomedusae\", \"#FFFFC14B\": \"N\\u00e2renji Orange\", \"#FFE9E6DC\": \"Narvik Variant\", \"#FF080813\": \"Narwhal Grey\", \"#FF746062\": \"Nasake\", \"#FFEDD4B1\": \"Nashi Pear Beige\", \"#FFFE5B2E\": \"Nasturtium\", \"#FFE64D1D\": \"Nasturtium Flower\", \"#FF87B369\": \"Nasturtium Leaf\", \"#FF869F49\": \"Nasturtium Shoot\", \"#FF70B23F\": \"Nasty Green\", \"#FF5D21D0\": \"Nasu Purple\", \"#FFA17917\": \"Nataneyu Gold\", \"#FFBA9F95\": \"Natchez\", \"#FFB1A76F\": \"Natchez Moss\", \"#FF3F6F98\": \"National Anthem\", \"#FFDC6B67\": \"Native Berry\", \"#FF9AA099\": \"Native Flora\", \"#FF848667\": \"Native Henna\", \"#FFD33300\": \"Native Hue of Resolution\", \"#FFA89AA7\": \"Native Lilac\", \"#FF887B69\": \"Native Soil\", \"#FF153043\": \"NATO Blue\", \"#FF555548\": \"NATO Olive\", \"#FFEBBC71\": \"Natrolite\", \"#FFC79843\": \"Natt\\u014d\", \"#FFA48B74\": \"Natural\", \"#FFDED2BB\": \"Natural Almond\", \"#FF6D574D\": \"Natural Bark\", \"#FFA29171\": \"Natural Bridge\", \"#FFBBA88B\": \"Natural Chamois\", \"#FFE3DED0\": \"Natural Choice\", \"#FF8B655A\": \"Natural Copper\", \"#FF976343\": \"Natural Cork\", \"#FFA27833\": \"Natural Evolution\", \"#FFBCCD91\": \"Natural Green\", \"#FFC4C0BB\": \"Natural Grey\", \"#FF82745C\": \"Natural Habitat\", \"#FF91AA90\": \"Natural Harmony\", \"#FF003740\": \"Natural Indigo\", \"#FF017374\": \"Natural Instinct Green\", \"#FFA80E00\": \"Natural Leather\", \"#FFF1EBC8\": \"Natural Light\", \"#FFECDFCF\": \"Natural Linen\", \"#FF4C9C77\": \"Natural Orchestra\", \"#FF77B033\": \"Natural Order\", \"#FF4A4A43\": \"Natural Pumice\", \"#FFE7DCC1\": \"Natural Radiance\", \"#FFDCC39F\": \"Natural Rice Beige\", \"#FFFCE7C5\": \"Natural Sheepskin\", \"#FFD3C5C0\": \"Natural Silk Grey\", \"#FFE5D8C2\": \"Natural Soap\", \"#FFAA838B\": \"Natural Spring\", \"#FF8A8287\": \"Natural Steel\", \"#FFAEA295\": \"Natural Stone\", \"#FFDCD2C3\": \"Natural Tan\", \"#FFDBC39B\": \"Natural Twine\", \"#FF006E4E\": \"Natural Watercourse\", \"#FFF0E8CF\": \"Natural Whisper\", \"#FFFBEDE2\": \"Natural White\", \"#FFFFF6D7\": \"Natural Wool\", \"#FFEED88B\": \"Natural Yellow\", \"#FFD7E5B4\": \"Natural Youth\", \"#FFF1E0CF\": \"Naturale\", \"#FF68685D\": \"Naturalism\", \"#FF8B8C83\": \"Naturalist Grey\", \"#FFCED0D9\": \"Naturally Calm\", \"#FFBFD5B3\": \"Nature\", \"#FFFEB7A5\": \"Nature Apricot\", \"#FF7DAF94\": \"Nature Green\", \"#FF6C7763\": \"Nature Lover\", \"#FF7B8787\": \"Nature Retreat\", \"#FFC8C8B4\": \"Nature Spirits\", \"#FF52634B\": \"Nature Surrounds\", \"#FFE6D7BB\": \"Nature Trail\", \"#FF7C7A7A\": \"Nature Walk\", \"#FFA6D292\": \"Nature\\u2019s Delight\", \"#FF666A60\": \"Nature\\u2019s Gate\", \"#FF99A399\": \"Nature\\u2019s Gift\", \"#FF006611\": \"Nature\\u2019s Masterpiece\", \"#FFC5D4CD\": \"Nature\\u2019s Reflection\", \"#FF117733\": \"Nature\\u2019s Strength\", \"#FFCBC0AD\": \"Naturel\", \"#FFBA403A\": \"Naughty Hottie\", \"#FFE3CCDC\": \"Naughty Marietta\", \"#FF2E4A7D\": \"Nautical\", \"#FF1A5091\": \"Nautical Blue\", \"#FF295C7A\": \"Nautical Creatures\", \"#FFAAB5B7\": \"Nautical Star\", \"#FF273C5A\": \"Nautilus\", \"#FF378FB3\": \"Navagio Bay\", \"#FFEFDCC3\": \"Navajo\", \"#FFA48679\": \"Navajo Horizon\", \"#FF007C78\": \"Navajo Turquoise\", \"#FF41729F\": \"Naval\", \"#FF072688\": \"Naval Adventures\", \"#FF384B6B\": \"Naval Blue\", \"#FF011C39\": \"Naval Night\", \"#FF386782\": \"Naval Passage\", \"#FFEC8430\": \"Navel\", \"#FF008A86\": \"Navigate\", \"#FF5D83AB\": \"Navigator\", \"#FF01153E\": \"Navy\", \"#FFE0DCCF\": \"Navy Bean\", \"#FF263032\": \"Navy Black\", \"#FF2A2E3F\": \"Navy Blazer\", \"#FF57415C\": \"Navy Cosmos\", \"#FF425166\": \"Navy Damask\", \"#FF004C6A\": \"Navy Dark Blue\", \"#FF9556EB\": \"Navy Genesis Evangelion\", \"#FF35530A\": \"Navy Green\", \"#FF223A5E\": \"Navy Peony\", \"#FF253A91\": \"Navy Seal\", \"#FF20576E\": \"Navy Teal\", \"#FF203462\": \"Navy Trim\", \"#FF5DC2DB\": \"Naxos Sky\", \"#FF9B7A78\": \"Neapolitan\", \"#FF4D7FAA\": \"Neapolitan Blue\", \"#FF5EE7DF\": \"Near Moon\", \"#FFA88E76\": \"Nearly Brown\", \"#FFEFDED1\": \"Nearly Peach\", \"#FFC8D5DD\": \"Nearsighted\", \"#FFA104C3\": \"Nebula Variant\", \"#FF281367\": \"Nebula Night\", \"#FF922B9C\": \"Nebula Outpost\", \"#FF2E62A7\": \"Nebulas Blue\", \"#FFC4B9B8\": \"Nebulous\", \"#FFB3B2BF\": \"Nebulous December\", \"#FFDEDFDC\": \"Nebulous White\", \"#FF828B8E\": \"Necron Compound\", \"#FFDEAD69\": \"Necrophilic Brown\", \"#FFECDACD\": \"Nectar\", \"#FFF0D38F\": \"Nectar Jackpot\", \"#FFE3A701\": \"Nectar of the Goddess\", \"#FF513439\": \"Nectar of the Gods\", \"#FF7F4C64\": \"Nectar Red\", \"#FFD38D72\": \"Nectarina\", \"#FFFF8656\": \"Nectarine\", \"#FFD29B8D\": \"Nectarine Spice\", \"#FFDD5566\": \"Nectarous Nectarine\", \"#FFB1D6DE\": \"Needed Escape\", \"#FF546670\": \"Needlepoint Navy\", \"#FFC5CED8\": \"Nefarious Blue\", \"#FFE6D1DC\": \"Nefarious Mauve\", \"#FF938B4B\": \"Negishi Green\", \"#FFEEC7A2\": \"Negroni Variant\", \"#FFF3C1A3\": \"Neighbourly Peach\", \"#FF337711\": \"Nemophilist\", \"#FFAAFFCC\": \"Neo Mint\", \"#FFBEC0C2\": \"Neo Tokyo Grey\", \"#FF04D9FF\": \"Neon Blue\", \"#FFDFC5FE\": \"Neon Boneyard\", \"#FFFF9832\": \"Neon Carrot Variant\", \"#FFFFD4A9\": \"Neon Cloud\", \"#FF09CDCD\": \"Neon Lagoon\", \"#FFFFDF5E\": \"Neon Light\", \"#FF95FF00\": \"Neon Lime\", \"#FF4FDCE1\": \"Neon Nazar\", \"#FFFE019A\": \"Neon Pink\", \"#FFBC13FE\": \"Neon Purple\", \"#FFFF073A\": \"Neon Red\", \"#FFE9023A\": \"Neon Romance\", \"#FFFF629F\": \"Neon Sunset\", \"#FF674876\": \"Neon Violet\", \"#FFCFFF04\": \"Neon Yellow\", \"#FF93AAB9\": \"Nepal Variant\", \"#FF6D9288\": \"Nephrite\", \"#FF007DAC\": \"Neptune Variant\", \"#FF2E5D9D\": \"Neptune Blue\", \"#FF7FBB9E\": \"Neptune Green\", \"#FF003368\": \"Neptune\\u2019s Dream\", \"#FF97C0D1\": \"Neptune\\u2019s Realm\", \"#FF11425D\": \"Neptune\\u2019s Wrath\", \"#FF4C793C\": \"Nereus\", \"#FF252525\": \"Nero Variant\", \"#FF318181\": \"Nero\\u2019s Green\", \"#FFFF6EC7\": \"Nervous Neon Pink\", \"#FFD7C65B\": \"Nervy Hue\", \"#FF716748\": \"Nessie\", \"#FF917B68\": \"Nest\", \"#FFEEEADA\": \"Nesting Dove\", \"#FFB6A194\": \"Net Worker\", \"#FF881111\": \"Netherworld\", \"#FFE0CFB0\": \"Netsuke\", \"#FFBBAC7D\": \"Nettle\", \"#FF364C2E\": \"Nettle Green\", \"#FFE4F7E7\": \"Nettle Rash\", \"#FFA0A5A7\": \"Network Grey\", \"#FFCAC1B1\": \"Neutra\", \"#FF9D928F\": \"Neutral Buff\", \"#FFAAA583\": \"Neutral Green\", \"#FF8E918F\": \"Neutral Grey\", \"#FFE2DACA\": \"Neutral Ground\", \"#FFFFE6C3\": \"Neutral Peach\", \"#FF8B694D\": \"Neutral Valley\", \"#FFECEDE8\": \"Neutral White\", \"#FF01248F\": \"Neutrino Blue\", \"#FF666F6F\": \"Nevada Variant\", \"#FFFFD5A7\": \"Nevada Morning\", \"#FFEAD5B9\": \"Nevada Sand\", \"#FFA1D9E7\": \"Nevada Sky\", \"#FF6E6455\": \"Never Cry Wolf\", \"#FFA67283\": \"Never Forget\", \"#FF666556\": \"Nevergreen\", \"#FF9CE5D6\": \"Neverland\", \"#FF7BC8F6\": \"Nevermind Nirvana\", \"#FF403940\": \"Nevermore\", \"#FF13181B\": \"Neverything\", \"#FF496EAD\": \"New Age Blue\", \"#FF6D3B24\": \"New Amber\", \"#FFBDB264\": \"New Avocado\", \"#FFD8DECE\": \"New Baby Smell\", \"#FFADAC84\": \"New Bamboo\", \"#FF934C3D\": \"New Brick\", \"#FF482427\": \"New Bulgarian Rose\", \"#FFA28367\": \"New Chestnut\", \"#FFEFC1B5\": \"New Clay\", \"#FFB89B6B\": \"New Cork\", \"#FFEDE0C0\": \"New Cream\", \"#FFDA9A21\": \"New England Autumn\", \"#FFAD7065\": \"New England Brick\", \"#FFAA7755\": \"New England Roast\", \"#FFC9A171\": \"New Fawn\", \"#FFC2BC90\": \"New Foliage\", \"#FF47514D\": \"New Forest\", \"#FFBACCA0\": \"New Frond\", \"#FFEAD151\": \"New Gold\", \"#FFB5AC31\": \"New Green\", \"#FFDBD5B7\": \"New Growth\", \"#FFEDDFC7\": \"New Harvest Moon\", \"#FFBD827F\": \"New Haven Rose\", \"#FFD0E5F2\": \"New Heights\", \"#FFE2EFC2\": \"New Hope\", \"#FFF1EDE7\": \"New House White\", \"#FF4A5F58\": \"New Hunter\", \"#FFD9C7AA\": \"New Khaki\", \"#FF7C916E\": \"New Life\", \"#FFC6BBDB\": \"New Love\", \"#FF48C09B\": \"New Meadow\", \"#FFDEAA89\": \"New Mexico Mesa\", \"#FFB2BDBB\": \"New Morn Fog\", \"#FFC6D6C7\": \"New Moss\", \"#FF3B4A55\": \"New Navy Blue\", \"#FFBEC0AA\": \"New Neutral\", \"#FFC3CDD2\": \"New North\", \"#FFE4C385\": \"New Orleans Variant\", \"#FF95A294\": \"New Patina\", \"#FFA27D66\": \"New Penny\", \"#FFB1D9E9\": \"New Prince\", \"#FFEEEEE5\": \"New Ream\", \"#FF691D6C\": \"New Riders of the Purple Sage\", \"#FF875251\": \"New Roof\", \"#FF869E3E\": \"New Shoot\", \"#FF933C3C\": \"New Sled\", \"#FF738595\": \"New Steel\", \"#FF90ABBB\": \"New Toile\", \"#FFD6C1DD\": \"New Violet\", \"#FF11FF11\": \"New Wave Green\", \"#FFFF22FF\": \"New Wave Pink\", \"#FFD2AF6F\": \"New Wheat\", \"#FFD6C3B9\": \"New Wool\", \"#FFE8C247\": \"New Yellow\", \"#FFDD8374\": \"New York Pink Variant\", \"#FFFF0059\": \"New York Sunset\", \"#FFF0E1DF\": \"New Youth\", \"#FFA0C4BE\": \"New-Age Green\", \"#FF616550\": \"Newbury Moss\", \"#FF445A79\": \"Newburyport\", \"#FFB2C7E1\": \"Newman\\u2019s Eye\", \"#FFEAE2DC\": \"Newmarket Sausage\", \"#FF1C8AC9\": \"Newport Blue\", \"#FF26566E\": \"Newport Grey\", \"#FF313D6C\": \"Newport Indigo\", \"#FF756F6D\": \"Newsprint\", \"#FF29A98B\": \"Niagara Variant\", \"#FFCBE3EE\": \"Niagara Falls\", \"#FFC5E8EE\": \"Niagara Mist\", \"#FF7DC734\": \"Niblet Green\", \"#FF107AB0\": \"Nice Blue\", \"#FFFAECD1\": \"Nice Cream\", \"#FFDBA37E\": \"Nice Tan\", \"#FFE6DDD5\": \"Nice White\", \"#FF65758F\": \"Niche\", \"#FF84979A\": \"Nichols Beach\", \"#FF909062\": \"Nick\\u2019s Nook\", \"#FF929292\": \"Nickel Variant\", \"#FF537E7E\": \"Nickel Ore Green\", \"#FFC1C6BF\": \"Nickel Plate\", \"#FFCC7755\": \"Nicotine Glaze\", \"#FFEEBB33\": \"Nicotine Gold\", \"#FFB6C3C4\": \"Niebla Azul\", \"#FF019187\": \"Nifty Turquoise\", \"#FF613E3D\": \"Night Bloom\", \"#FFF9F7EC\": \"Night Blooming Jasmine\", \"#FF040348\": \"Night Blue\", \"#FF44281B\": \"Night Brown\", \"#FF322D25\": \"Night Brown Black\", \"#FF494B4E\": \"Night Club\", \"#FF201B20\": \"Night Demons\", \"#FF003355\": \"Night Dive\", \"#FF20586D\": \"Night Edition\", \"#FF572E89\": \"Night Fever\", \"#FF434D5C\": \"Night Flight\", \"#FF2D1962\": \"Night Fog\", \"#FF49646D\": \"Night Folly\", \"#FF302F27\": \"Night Green\", \"#FF45444D\": \"Night Grey\", \"#FF615D5C\": \"Night Gull Grey\", \"#FF443300\": \"Night in the Woods\", \"#FF005572\": \"Night Kite\", \"#FFF8E8CD\": \"Night Light\", \"#FF4C6177\": \"Night Market\", \"#FF508793\": \"Night Masque\", \"#FF5D3B41\": \"Night Mauve\", \"#FF5E5C50\": \"Night Mission\", \"#FF234E86\": \"Night Mode\", \"#FF9C96AF\": \"Night Music\", \"#FF4F4F5E\": \"Night Night\", \"#FF898487\": \"Night on the Moors\", \"#FF656A6E\": \"Night Out\", \"#FF5D7B89\": \"Night Owl\", \"#FF11FFBB\": \"Night Pearl\", \"#FF3C2727\": \"Night Red\", \"#FF66787E\": \"Night Rendezvous\", \"#FF332E2E\": \"Night Rider Variant\", \"#FF715055\": \"Night Romance\", \"#FFB0807A\": \"Night Rose\", \"#FF0E737E\": \"Night Scape\", \"#FFA23D54\": \"Night Shadz Variant\", \"#FF2A5C6A\": \"Night Shift\", \"#FF292B31\": \"Night Sky\", \"#FF756968\": \"Night Skyscraper\", \"#FFAACCFF\": \"Night Snow\", \"#FF254A57\": \"Night Swim\", \"#FF6B7BA7\": \"Night Thistle\", \"#FF455360\": \"Night Tide\", \"#FF4B7689\": \"Night Train\", \"#FF003833\": \"Night Turquoise\", \"#FF465560\": \"Night View\", \"#FF77BB55\": \"Night Vision\", \"#FF3C4F4E\": \"Night Watch\", \"#FFE1E1DD\": \"Night White\", \"#FFD7E2DB\": \"Night Wind\", \"#FF313740\": \"Night Wizard\", \"#FF43535E\": \"Nightfall\", \"#FF0011DD\": \"Nightfall in Suburbia\", \"#FF615452\": \"Nighthawk\", \"#FF234C47\": \"Nighthawks\", \"#FF5C4827\": \"Nightingale\", \"#FFBAAEA3\": \"Nightingale Grey\", \"#FF27426B\": \"Nightlife\", \"#FF536078\": \"Nightly\", \"#FF9BEEC1\": \"Nightly Aurora\", \"#FF5A7D9A\": \"Nightly Blade\", \"#FF0433FF\": \"Nightly Escapade\", \"#FF221188\": \"Nightly Expedition\", \"#FF444940\": \"Nightly Ivy\", \"#FF4F5B93\": \"Nightly Silhouette\", \"#FF784384\": \"Nightly Violet\", \"#FF391531\": \"Nightly Voyager\", \"#FF544563\": \"Nightly Walk\", \"#FF112211\": \"Nightmare\", \"#FF293135\": \"Nightmare Fuel\", \"#FF3C464B\": \"Nightshade\", \"#FF1B1811\": \"Nightshade Berries\", \"#FF535872\": \"Nightshade Purple\", \"#FFA383AC\": \"Nightshade Violet\", \"#FF555971\": \"Nightshadow Blue\", \"#FF161D3B\": \"Nightwalker\", \"#FF931121\": \"Nigritella Red\", \"#FF0055FF\": \"N\\u012bl\\u0101 Blue\", \"#FFAFB982\": \"Nile\", \"#FF8B8174\": \"Nile Clay\", \"#FF99BE85\": \"Nile Green\", \"#FF968F5F\": \"Nile Reed\", \"#FF9AB6A9\": \"Nile River\", \"#FFBBAD94\": \"Nile Sand\", \"#FF61C9C1\": \"Nile Stone\", \"#FFF1EBE0\": \"Nilla Vanilla\", \"#FF747880\": \"Nimbostratus\", \"#FF4422FF\": \"Nimbus Blue\", \"#FFC8C8CC\": \"Nimbus Cloud\", \"#FFF5E3EA\": \"Nina\", \"#FF46434A\": \"Nine Iron\", \"#FFFFEF19\": \"N\\u00edng M\\u00e9ng Hu\\u00e1ng Lemon\", \"#FF020308\": \"Ninja\", \"#FF75528B\": \"Ninja Princess\", \"#FF94B1A9\": \"Ninja Turtle\", \"#FFBB7777\": \"Nipple\", \"#FFBC002C\": \"Nippon\", \"#FFA2919B\": \"Nirvana\", \"#FF64A5AD\": \"Nirvana Jewel\", \"#FF43242A\": \"Nisemurasaki Purple\", \"#FF056EEE\": \"N\\u00edu Z\\u01cei S\\u00e8 Denim\", \"#FFA33F40\": \"No More Drama\", \"#FFFFD6DD\": \"No Need\", \"#FFFBAA95\": \"No Way Ros\\u00e9\", \"#FFF8E888\": \"No$GMB Yellow\", \"#FFF8D68B\": \"\\u21165\", \"#FFA99D9D\": \"Nobel Variant\", \"#FFECDEC5\": \"Nobility\", \"#FF414969\": \"Nobility Blue\", \"#FF202124\": \"Noble Black\", \"#FF697991\": \"Noble Blue\", \"#FFE8B9B2\": \"Noble Blush\", \"#FF990C0D\": \"Noble Cause\", \"#FF7E1E9C\": \"Noble Cause Purple\", \"#FF6D4433\": \"Noble Chocolate\", \"#FFE1DACE\": \"Noble Cream\", \"#FF8D755D\": \"Noble Crown\", \"#FF627B44\": \"Noble Eric\", \"#FF5A736D\": \"Noble Fir\", \"#FFC1BEB9\": \"Noble Grey\", \"#FF51384A\": \"Noble Hatter\\u2019s Violet\", \"#FF69354F\": \"Noble Honour\", \"#FF394D78\": \"Noble Knight\", \"#FFB28392\": \"Noble Lilac\", \"#FF871F78\": \"Noble Plum\", \"#FFAFB1C5\": \"Noble Purple\", \"#FF92181D\": \"Noble Red\", \"#FF807070\": \"Noble Robe\", \"#FF73777F\": \"Noble Silver\", \"#FF884967\": \"Noble Tone\", \"#FF524B50\": \"Noblesse\", \"#FF463636\": \"Noblesse Oblige\", \"#FFBC8E6C\": \"Nobody but Ben\", \"#FF646B77\": \"Noctis\", \"#FF767D86\": \"Nocturnal\", \"#FF114C5A\": \"Nocturnal Expedition\", \"#FF675754\": \"Nocturnal Flight\", \"#FF2F3738\": \"Nocturnal Green\", \"#FFCC6699\": \"Nocturnal Rose\", \"#FF0E6071\": \"Nocturnal Sea\", \"#FF344D58\": \"Nocturne\", \"#FF37525F\": \"Nocturne Blue\", \"#FF7A4B56\": \"Nocturne Red\", \"#FF356FAD\": \"Nocturne Shade\", \"#FFBDBEBD\": \"Noghrei Silver\", \"#FF312B27\": \"Noir\", \"#FF150811\": \"Noir Fiction\", \"#FF1F180A\": \"Noir Mystique\", \"#FF866745\": \"Nom Nom\", \"#FFA19986\": \"Nomad Variant\", \"#FF7E736F\": \"Nomad Grey\", \"#FFAF9479\": \"Nomadic\", \"#FFC7B198\": \"Nomadic Desert\", \"#FFDBDEDB\": \"Nomadic Dream\", \"#FFD2C6AE\": \"Nomadic Taupe\", \"#FFE0C997\": \"Nomadic Travels\", \"#FF357567\": \"Nominee\", \"#FF8A8DAA\": \"Non Skid Grey\", \"#FFDD8811\": \"Non-Stop Orange\", \"#FFC3F400\": \"Non-Toxic Boyfriend\", \"#FFDEDDD1\": \"Nonchalant White\", \"#FFC1A65C\": \"Nonpareil Apple\", \"#FFF5DDC4\": \"Noodle Arms\", \"#FFF9E3B4\": \"Noodles\", \"#FF99A9AD\": \"Nor\\u2019wester\", \"#FF003333\": \"Nora\\u2019s Forest\", \"#FF1D393C\": \"Nordic\", \"#FFD3DDE7\": \"Nordic Breeze\", \"#FF317362\": \"Nordic Forest\", \"#FF1FAB58\": \"Nordic Grass Green\", \"#FF003344\": \"Nordic Noir\", \"#FF43694D\": \"Nordic Pine\", \"#FF7E95AB\": \"Nordland Blue\", \"#FF96AEC5\": \"Nordland Light Blue\", \"#FF2E7073\": \"Nordmann Fir\", \"#FF2E4B3C\": \"Norfolk Green\", \"#FF6CBAE7\": \"Norfolk Sky\", \"#FF112A12\": \"Nori Green\", \"#FF464826\": \"Nori Seaweed Green\", \"#FFE9C68E\": \"Norman Shaw Goldspar\", \"#FF3D9DC2\": \"Norse Blue\", \"#FF5E7B7F\": \"North Atlantic\", \"#FF3676B5\": \"North Atlantic Breeze\", \"#FF849C9D\": \"North Beach Blue\", \"#FF7A9595\": \"North Cape Grey\", \"#FF6A7777\": \"North Grey\", \"#FFBCB6B4\": \"North Island\", \"#FFD8A892\": \"North Rim\", \"#FF316C69\": \"North Sea\", \"#FF343C4C\": \"North Sea Blue\", \"#FFF2DEA4\": \"North Star\", \"#FF223399\": \"North Star Blue\", \"#FF059033\": \"North Texas Green\", \"#FF555A51\": \"North Woods\", \"#FF767962\": \"Northampton Trees\", \"#FFD1DCDD\": \"Northbound\", \"#FF948666\": \"Northeast Trail\", \"#FFDE743C\": \"Northern Barrens Dust\", \"#FFE9DAD2\": \"Northern Beach\", \"#FFBFC7D4\": \"Northern Exposure\", \"#FF536255\": \"Northern Glen\", \"#FF017466\": \"Northern Hemisphere\", \"#FF778F8E\": \"Northern Juniper\", \"#FFC5C1A3\": \"Northern Landscape\", \"#FFA7AEB4\": \"Northern Light Grey\", \"#FFE6F0EA\": \"Northern Lights\", \"#FFA3B9CD\": \"Northern Pond\", \"#FF8DACCC\": \"Northern Sky\", \"#FF9CBACD\": \"Northern Sky Blue\", \"#FFFFFFEA\": \"Northern Star\", \"#FF5E463C\": \"Northern Territory\", \"#FFAAA388\": \"Northgate Green\", \"#FF9E9181\": \"Northpointe\", \"#FFB9F2FF\": \"Northrend\", \"#FFCEE5E9\": \"Northwind\", \"#FFA4B88F\": \"Norway Variant\", \"#FF78888E\": \"Norwegian Blue\", \"#FF8896AA\": \"Norwegian Night\", \"#FFB4CDDE\": \"Norwegian Sky\", \"#FFACB597\": \"Norwich Green\", \"#FFFFE6EC\": \"Nosegay\", \"#FFA9A8A8\": \"Nosferatu\", \"#FF426579\": \"Noshime Flower\", \"#FFD6B8BD\": \"Nostalgia\", \"#FFDBDBF7\": \"Nostalgia Perfume\", \"#FFA2747D\": \"Nostalgia Rose\", \"#FF666C7E\": \"Nostalgic\", \"#FF47626F\": \"Nostalgic Evening\", \"#FF85C8D3\": \"Not a Cloud in Sight\", \"#FF7E7D78\": \"Not My Fault\", \"#FF6A6968\": \"Not so Innocent\", \"#FF090615\": \"Not Tonight\", \"#FFB1714C\": \"Not yet Caramel\", \"#FFFFC12C\": \"Not Yo Cheese\", \"#FF8BA7BB\": \"Notable Hue\", \"#FFE8EBE6\": \"Notebook Paper\", \"#FFD9BACC\": \"Noteworthy\", \"#FFF2DEB9\": \"Nothing Less\", \"#FFBA8686\": \"Notice Me\", \"#FFBDA998\": \"Notorious\", \"#FF664400\": \"Notorious Neanderthal\", \"#FFC6C5BC\": \"Notre Dame\", \"#FF585D4E\": \"Nottingham Forest\", \"#FFAE8A78\": \"Nougat\", \"#FF7C503F\": \"Nougat Brown\", \"#FF686F7E\": \"Nouveau\", \"#FFA05B42\": \"Nouveau Copper\", \"#FFB88127\": \"Nouveau Green\", \"#FF996872\": \"Nouveau Rose\", \"#FFFFBB77\": \"Nouveau-Riche\", \"#FFE1DCDA\": \"Nouvelle White\", \"#FFD94F9A\": \"Nova Pink\", \"#FFF8EED9\": \"Nova White\", \"#FFC2A4C2\": \"Novel Lilac\", \"#FF9DB9D3\": \"Novella Blue\", \"#FFE3C7B2\": \"Novelle Peach\", \"#FF515B62\": \"Novelty Navy\", \"#FFBE7767\": \"November\", \"#FF754D42\": \"November Foliage\", \"#FFF6B265\": \"November Gold\", \"#FF767764\": \"November Green\", \"#FFF1B690\": \"November Leaf\", \"#FFEDE6E8\": \"November Pink\", \"#FF7CAFB9\": \"November Skies\", \"#FF423F3B\": \"November Storms\", \"#FF89A203\": \"Noxious\", \"#FFE2E0D6\": \"Nuance\", \"#FFECF474\": \"Nuclear Acid\", \"#FFBBFF00\": \"Nuclear Blast\", \"#FFAA9900\": \"Nuclear Fallout\", \"#FFEE9933\": \"Nuclear Mango\", \"#FF44EE00\": \"Nuclear Meltdown\", \"#FF00DE00\": \"Nuclear Throne\", \"#FFE58F7C\": \"Nude Flamingo\", \"#FFB5948D\": \"Nude Lips\", \"#FFBC9229\": \"Nugget Variant\", \"#FFBF961F\": \"Nugget Gold\", \"#FF1E488F\": \"Nuit Blanche\", \"#FF14100E\": \"Nuln Oil\", \"#FF171310\": \"Nuln Oil Gloss\", \"#FF929BAC\": \"Numbers\", \"#FFE2E6DE\": \"Numero Uno\", \"#FFF8F6E9\": \"Nun Orchid\", \"#FF9B8F22\": \"Nurgle\\u2019s Rot\", \"#FFB8CC82\": \"Nurgling Green\", \"#FFEFD0D2\": \"Nursery\", \"#FFEDF0DE\": \"Nursery Green\", \"#FFF4D8E8\": \"Nursery Pink\", \"#FF9EBCB7\": \"Nursery Wall\", \"#FFD7DCD5\": \"Nurture\", \"#FF98B092\": \"Nurture Green\", \"#FFA1A97B\": \"Nurturing\", \"#FF9D896C\": \"Nurude Brown\", \"#FF9E8A6D\": \"Nut\", \"#FF86695E\": \"Nut Brown\", \"#FF816C5B\": \"Nut Cracker\", \"#FFD7BEA4\": \"Nut Flavour\", \"#FFD9CCC8\": \"Nut Milk\", \"#FF775D38\": \"Nut Oil\", \"#FF8E725F\": \"Nuthatch\", \"#FF445599\": \"Nuthatch Back\", \"#FF7E4A3B\": \"Nutmeg Variant\", \"#FFECD9CA\": \"Nutmeg Frost\", \"#FFD8B691\": \"Nutmeg Glow\", \"#FF75663E\": \"Nutria\", \"#FF514035\": \"Nutria Fur Brown\", \"#FF898C92\": \"Nuts and Bolts\", \"#FFA9856B\": \"Nutshell\", \"#FFF7D4C6\": \"Nutter Butter\", \"#FFD4BCA3\": \"Nutty Beige\", \"#FF8A6F44\": \"Nutty Brown\", \"#FFEFEAE8\": \"NYC Apartment Wall\", \"#FFF7B731\": \"NYC Taxi\", \"#FF0B0F1A\": \"Nyctophobia\", \"#FF4D587A\": \"Nyctophobia Blue\", \"#FFE9E3CB\": \"Nylon\", \"#FFAEC2A5\": \"Nymph Green\", \"#FF7B6C8E\": \"Nymph\\u2019s Delight\", \"#FFCEE0E3\": \"Nymphaeaceae\", \"#FF5F6E77\": \"NYPD\", \"#FFE1B8B5\": \"O Fortuna\", \"#FF005522\": \"O Tannenbaum\", \"#FFF3A347\": \"O\\u2019Brien Orange\", \"#FF58AC8F\": \"O\\u2019grady Green\", \"#FF395643\": \"O\\u2019Neal Green\", \"#FF715636\": \"Oak Barrel\", \"#FFA18D80\": \"Oak Brown\", \"#FFCF9C63\": \"Oak Buff\", \"#FF5D504A\": \"Oak Creek\", \"#FFCDB386\": \"Oak Harbour\", \"#FFBB6B41\": \"Oak Palace\", \"#FF5D4F39\": \"Oak Plank\", \"#FFC0B0AB\": \"Oak Ridge\", \"#FFEED8C2\": \"Oak Shaving\", \"#FFD0C7B6\": \"Oak Tone\", \"#FFE0B695\": \"Oakley Apricot\", \"#FF6D7244\": \"Oakmoss\", \"#FFBDA58B\": \"Oakwood\", \"#FF8F716E\": \"Oakwood Brown\", \"#FF648D95\": \"Oarsman Blue\", \"#FF0092A3\": \"Oasis Variant\", \"#FFFCEDC5\": \"Oasis Sand\", \"#FF47A3C6\": \"Oasis Spring\", \"#FFA2EBD8\": \"Oasis Stream\", \"#FFE1CAB3\": \"Oat Cake\", \"#FFC0AD89\": \"Oat Field\", \"#FFF7E4CD\": \"Oat Flour\", \"#FFDEDACD\": \"Oat Milk\", \"#FFF1D694\": \"Oat Straw\", \"#FFC8B9A4\": \"Oatbran\", \"#FF4A465A\": \"Oath\", \"#FFC9C1B1\": \"Oatmeal\", \"#FFDDC7A2\": \"Oatmeal Bath\", \"#FFB7A86D\": \"Oatmeal Biscuit\", \"#FFEADAC6\": \"Oatmeal Cookie\", \"#FFE7BF81\": \"Oats and Honey\", \"#FFFCD389\": \"Oberon\", \"#FFE7C492\": \"Oberon on the Beach\", \"#FFB0A3B6\": \"Obi Lilac\", \"#FFB7A8A8\": \"Object of Desire\", \"#FFBBC6DE\": \"Objectivity\", \"#FF54645C\": \"Obligation\", \"#FF000435\": \"Oblivion\", \"#FF88654E\": \"Obscure Ochre\", \"#FF771908\": \"Obscure Ogre\", \"#FF4A5D23\": \"Obscure Olive\", \"#FFBB5500\": \"Obscure Orange\", \"#FF9D0759\": \"Obscure Orchid\", \"#FF008F70\": \"Observatory Variant\", \"#FFAE9550\": \"Obsession\", \"#FF445055\": \"Obsidian\", \"#FF523E35\": \"Obsidian Brown\", \"#FF382B46\": \"Obsidian Lava Black\", \"#FF3F1D50\": \"Obsidian Orchid\", \"#FF372A38\": \"Obsidian Red\", \"#FF060313\": \"Obsidian Shard\", \"#FF441166\": \"Obsidian Shell\", \"#FF3C3F40\": \"Obsidian Stone\", \"#FFD7552A\": \"Obstinate Orange\", \"#FFFFB077\": \"Obtrusive Orange\", \"#FF4B1E87\": \"Occult\", \"#FF005493\": \"Ocean\", \"#FF221166\": \"Ocean Abyss\", \"#FFDAE4ED\": \"Ocean Air\", \"#FF0077BE\": \"Ocean Boat Blue Variant\", \"#FFA4C8C8\": \"Ocean Boulevard\", \"#FFD3E5EB\": \"Ocean Breeze\", \"#FF8CADCD\": \"Ocean Bubble\", \"#FF2B6C8E\": \"Ocean Call\", \"#FF7896BA\": \"Ocean City\", \"#FFD6DDDD\": \"Ocean Crest\", \"#FF9CD4E1\": \"Ocean Cruise\", \"#FF537783\": \"Ocean Current\", \"#FF00657F\": \"Ocean Depths\", \"#FFD4DDE2\": \"Ocean Dream\", \"#FFB0BEC5\": \"Ocean Drive\", \"#FFAFC3BC\": \"Ocean Droplet\", \"#FFA9C7CF\": \"Ocean Eyes\", \"#FFCAC8B4\": \"Ocean Foam\", \"#FF7A7878\": \"Ocean Frigate\", \"#FFB8E3ED\": \"Ocean Front\", \"#FFC1CCC2\": \"Ocean Froth\", \"#FF3D9973\": \"Ocean Green Variant\", \"#FF7FC1D8\": \"Ocean Horizon\", \"#FF68DFBB\": \"Ocean in a Bowl\", \"#FFA4C3C5\": \"Ocean Kiss\", \"#FF189086\": \"Ocean Liner\", \"#FF7D999F\": \"Ocean Melody\", \"#FF00748F\": \"Ocean Mirage\", \"#FF637195\": \"Ocean Night\", \"#FF006C68\": \"Ocean Oasis\", \"#FFD3CFBD\": \"Ocean Pearl\", \"#FF016072\": \"Ocean Radiance\", \"#FF1F989B\": \"Ocean Reef\", \"#FF7594B3\": \"Ocean Ridge\", \"#FFE4D5CD\": \"Ocean Sand\", \"#FF5B7886\": \"Ocean Shadow\", \"#FF34B5D5\": \"Ocean Sigh\", \"#FFC8DCD5\": \"Ocean Silk\", \"#FF41767B\": \"Ocean Slumber\", \"#FF00878F\": \"Ocean Soul\", \"#FF005379\": \"Ocean Spray\", \"#FF3F677E\": \"Ocean Storm\", \"#FF79A2BD\": \"Ocean Surf\", \"#FF727C7E\": \"Ocean Swell\", \"#FF2E526A\": \"Ocean Trapeze\", \"#FF62AEBA\": \"Ocean Trip\", \"#FF67A6D4\": \"Ocean Tropic\", \"#FF729BB3\": \"Ocean View\", \"#FF7DBCAA\": \"Ocean Wave\", \"#FF6C6541\": \"Ocean Weed\", \"#FF306A78\": \"Ocean\\u2019s Embrace\", \"#FF4F6D82\": \"Oceanic\", \"#FFBBC8C9\": \"Oceanic Climate\", \"#FF347284\": \"Oceanic Metropolis\", \"#FF1D5C83\": \"Oceanic Motion\", \"#FF172B36\": \"Oceanic Noir\", \"#FF9AD6E5\": \"Oceano\", \"#FF415F61\": \"Oceans Deep\", \"#FF015A6B\": \"Oceanside\", \"#FF90ABA8\": \"Oceanus\", \"#FFF1E2C9\": \"Ocelot\", \"#FF6B6047\": \"Ochicha Latte\", \"#FFD99E73\": \"Ochraceous Salmon\", \"#FF9F7B3E\": \"Ochre Brown\", \"#FFCC7733\": \"Ochre Maroon\", \"#FFC77135\": \"Ochre Pigment\", \"#FFEEC987\": \"Ochre Revival\", \"#FFE96D03\": \"Ochre Spice\", \"#FF085B73\": \"Octagon Ocean\", \"#FFCCDD00\": \"Octarine\", \"#FFC67533\": \"October\", \"#FFE3C6A3\": \"October Bounty\", \"#FFD1BB98\": \"October Harvest\", \"#FFF8AC8C\": \"October Haze\", \"#FF855743\": \"October Leaves\", \"#FF8FA2A2\": \"October Sky\", \"#FF357911\": \"Odd Pea Pod\", \"#FFB6E5D6\": \"Ode\", \"#FF9D404A\": \"Ode Variant\", \"#FFA798C2\": \"Ode Tint\", \"#FFFFDFBF\": \"Odious Orange\", \"#FF374A5A\": \"Odyssey\", \"#FF4C4E5D\": \"Odyssey Grey\", \"#FFD5C6CC\": \"Odyssey Lilac\", \"#FFE1C2C5\": \"Odyssey Plum\", \"#FF303030\": \"Off Black\", \"#FF5684AE\": \"Off Blue\", \"#FF433F3D\": \"Off Broadway\", \"#FF6BA353\": \"Off Green Variant\", \"#FFD1CCCB\": \"Off Shore\", \"#FF534C4B\": \"Off the Beaten Path\", \"#FF9F9049\": \"Off the Grid\", \"#FFFFFFE4\": \"Off White\", \"#FFF1F33F\": \"Off Yellow Variant\", \"#FF003723\": \"Off-Road Green\", \"#FFFFA259\": \"Off-The-Leash Orange\", \"#FFD6D0C6\": \"Offbeat\", \"#FF9C8B1F\": \"Offbeat Green\", \"#FF849DB4\": \"Office Blue\", \"#FF006C65\": \"Office Blue Green\", \"#FF00800F\": \"Office Green\", \"#FF635D54\": \"Office Grey\", \"#FFFF2277\": \"Office Neon Light\", \"#FF2E4182\": \"Official Violet\", \"#FFCAD8D8\": \"Offshore Mist\", \"#FFFF714E\": \"Often Orange\", \"#FFD7B235\": \"Ogen Melon\", \"#FFFD5240\": \"Ogre Odour\", \"#FF9DA94B\": \"Ogryn Camo\", \"#FFD1A14E\": \"Ogryn Wash\", \"#FFBBDAF8\": \"Oh Boy!\", \"#FFEDEEC5\": \"Oh Dahling\", \"#FFE3C81C\": \"Oh Em Ghee\", \"#FFEEBB55\": \"Oh My Gold\", \"#FFABCA99\": \"Oh Pistachio\", \"#FFF1C7D0\": \"Oh so Pink\", \"#FFEAC7CB\": \"Oh so Pretty\", \"#FFC74536\": \"Oh so Red\", \"#FF0180AB\": \"Oh so Vo\", \"#FF313330\": \"Oil Variant\", \"#FF678F8A\": \"Oil Blue\", \"#FF7B7F68\": \"Oil Green\", \"#FF3B3131\": \"Oil Grey\", \"#FFFF5511\": \"Oil on Fire\", \"#FF333144\": \"Oil Rush\", \"#FF031602\": \"Oil Slick\", \"#FFC2AB3F\": \"Oil Yellow\", \"#FF83BA8E\": \"Oilcloth Green\", \"#FF6C5A51\": \"Oiled Teak\", \"#FF996644\": \"Oiled up Kardashian\", \"#FFC2BE0E\": \"Oilseed Crops\", \"#FF2D0F47\": \"Oily Purple\", \"#FF99AAAA\": \"Oily Steel\", \"#FF5E644F\": \"Oitake Green\", \"#FFD07360\": \"OK Corral\", \"#FFCD4600\": \"\\u014ckaihau Express\", \"#FFF5E0BA\": \"Oklahoma Wheat\", \"#FFBA7D4C\": \"Okonomiyaki Brown\", \"#FF3E912D\": \"Okra\", \"#FF40533D\": \"Okroshka\", \"#FFEFCB96\": \"Oktoberfest\", \"#FF87868F\": \"Old Amethyst\", \"#FF616652\": \"Old Army Helmet\", \"#FF929000\": \"Old Asparagus\", \"#FF769164\": \"Old Bamboo\", \"#FF029386\": \"Old Benchmark\", \"#FFDBC2AB\": \"Old Bone\", \"#FF7C644B\": \"Old Boot\", \"#FF5E624A\": \"Old Botanical Garden\", \"#FF8A3335\": \"Old Brick Variant\", \"#FF330000\": \"Old Brown Crayon\", \"#FFA8A89D\": \"Old Celadon\", \"#FFE3D6E9\": \"Old Chalk\", \"#FFDD6644\": \"Old Cheddar\", \"#FF704241\": \"Old Coffee\", \"#FF73503B\": \"Old Copper Variant\", \"#FF784430\": \"Old Cumin\", \"#FFBDAB9B\": \"Old Doeskin\", \"#FF97694F\": \"Old Driftwood\", \"#FFCDC4BA\": \"Old Eggshell\", \"#FF82A2BE\": \"Old Faithful\", \"#FFF4C6CC\": \"Old Fashioned Pink\", \"#FF73486B\": \"Old Fashioned Purple\", \"#FFF2B7B5\": \"Old Flame\", \"#FF757D43\": \"Old Four Leaf Clover\", \"#FFC66787\": \"Old Geranium\", \"#FF002868\": \"Old Glory Blue\", \"#FFBF0A30\": \"Old Glory Red\", \"#FF839573\": \"Old Green\", \"#FFB4B6AD\": \"Old Grey Mare\", \"#FFB35E1F\": \"Old Guitar\", \"#FF0063EC\": \"Old Gungeon Red\", \"#FFE66A77\": \"Old Heart\", \"#FFFFFFCB\": \"Old Ivory\", \"#FFEFF5DC\": \"Old Kitchen White\", \"#FFFDFC74\": \"Old Laser Lemon\", \"#FFA88B66\": \"Old Leather\", \"#FFAEC571\": \"Old Lime\", \"#FF4A0100\": \"Old Mahogany\", \"#FF8E2323\": \"Old Mandarin\", \"#FFD5C9BC\": \"Old Map\", \"#FF343B4E\": \"Old Mill\", \"#FF6E6F82\": \"Old Mill Blue\", \"#FFD8C2CA\": \"Old Mission Pink\", \"#FF2C5C4F\": \"Old Money\", \"#FF5E5896\": \"Old Nan Yarn\", \"#FFF6EBD7\": \"Old Pearls\", \"#FFC77986\": \"Old Pink\", \"#FFEBA770\": \"Old Plaster\", \"#FF745947\": \"Old Porch\", \"#FF8272A4\": \"Old Prune\", \"#FFD8CBCF\": \"Old Red Crest\", \"#FF917B53\": \"Old Ruin\", \"#FFBBA582\": \"Old Salem\", \"#FF353C3D\": \"Old School\", \"#FF918D80\": \"Old Soul\", \"#FFCFD5D1\": \"Old Sterling\", \"#FF431705\": \"Old Study\", \"#FFBB8811\": \"Old Trail\", \"#FF0A888A\": \"Old Truck\", \"#FF6C574C\": \"Old Tudor\", \"#FF687760\": \"Old Vine\", \"#FFDDAA55\": \"Old Whiskey\", \"#FF756947\": \"Old Willow Leaf\", \"#FF90091F\": \"Old Wine\", \"#FF91A8CF\": \"Old World\", \"#FFFEED9A\": \"Old Yella\", \"#FFECE6D7\": \"Old Yellow Bricks\", \"#FF8F6C3E\": \"Olde World Gold\", \"#FFEEB76B\": \"Olden Amber\", \"#FFD6B63D\": \"Oldies but Goldies\", \"#FFEBD5CC\": \"Ole Pink\", \"#FFC79E5F\": \"Ole Yeller\", \"#FFF2CCC5\": \"Oleander\", \"#FFF85898\": \"Oleander Pink\", \"#FF665439\": \"Oliva Oscuro\", \"#FF6E592C\": \"Olivary\", \"#FF808010\": \"Olive Variant\", \"#FF5F5537\": \"Olive Bark\", \"#FF957C4C\": \"Olive Boat\", \"#FF646A45\": \"Olive Branch\", \"#FFC3BEBB\": \"Olive Bread\", \"#FF645403\": \"Olive Brown\", \"#FFBCD382\": \"Olive Buff\", \"#FFA6997A\": \"Olive Chutney\", \"#FFE4E5D8\": \"Olive Conquering White\", \"#FF5F5D48\": \"Olive Court\", \"#FFE8ECC0\": \"Olive Creed\", \"#FF6F7632\": \"Olive Drab\", \"#FFBFAC8B\": \"Olive Gold\", \"#FF716A4D\": \"Olive Grove\", \"#FF888064\": \"Olive Haze Variant\", \"#FFC9BD88\": \"Olive Hint\", \"#FF4E4B35\": \"Olive Leaf\", \"#FFC7B778\": \"Olive Marinade\", \"#FFCED2AB\": \"Olive Martini\", \"#FF88432E\": \"Olive Ni\\u00e7oise\", \"#FF565342\": \"Olive Night\", \"#FF837752\": \"Olive Ochre\", \"#FFBAB86C\": \"Olive Oil\", \"#FF83826D\": \"Olive Paste\", \"#FFA4A84D\": \"Olive Reserve\", \"#FFA39467\": \"Olive Rush\", \"#FF9ABF8D\": \"Olive Sand\", \"#FF7F7452\": \"Olive Sapling\", \"#FF7D7248\": \"Olive Shade\", \"#FF706041\": \"Olive Shadow\", \"#FF585545\": \"Olive Smudge\", \"#FF97A49A\": \"Olive Soap\", \"#FFACAF95\": \"Olive Sprig\", \"#FF6D8E2C\": \"Olive Thrill\", \"#FFEFEBD7\": \"Olive Tint\", \"#FF7E7957\": \"Olive Tint\", \"#FFABA77C\": \"Olive Tree\", \"#FF756244\": \"Olive Wood\", \"#FFC2B709\": \"Olive Yellow\", \"#FF333311\": \"Olivenite\", \"#FF747028\": \"Olivetone Variant\", \"#FF996622\": \"Olivia\", \"#FF655867\": \"Olivine Basalt\", \"#FF928E7C\": \"Olivine Grey\", \"#FFFFE6E2\": \"Olm Pink\", \"#FF84FBCE\": \"Olo\", \"#FF5A6647\": \"Olympia Ivy\", \"#FF1C4C8C\": \"Olympian Blue\", \"#FF4F8FE6\": \"Olympic Blue\", \"#FF9A724A\": \"Olympic Bronze\", \"#FF424C44\": \"Olympic Range\", \"#FFD4D8D7\": \"Olympus White\", \"#FF4A4E5D\": \"Ombre Blue\", \"#FF848998\": \"Ombre Grey\", \"#FF8CA891\": \"OMGreen\", \"#FFB5CEDF\": \"Omphalodes\", \"#FF019E91\": \"On a Whim\", \"#FFC2E7E8\": \"On Cloud Nine\", \"#FFD4C6DC\": \"On Location\", \"#FF948776\": \"On the Avenue\", \"#FF666D68\": \"On the Moor\", \"#FFB29AA7\": \"On the Nile\", \"#FFD0CEC8\": \"On the Rocks\", \"#FFD1E8F1\": \"On Thin Ice\", \"#FFC2E6EC\": \"Onahau Variant\", \"#FFBD2F10\": \"Once Bitten\", \"#FF0044BB\": \"Once in a Blue Moon\", \"#FF65362E\": \"One Dozen\", \"#FF003388\": \"One Minute\", \"#FFDCBDAD\": \"One\", \"#FF29465B\": \"One Year of Rain\", \"#FF48412B\": \"Onion Variant\", \"#FFECE2D4\": \"Onion Powder\", \"#FF47885E\": \"Onion Seedling\", \"#FFEEEDDF\": \"Onion Skin\", \"#FF4C5692\": \"Onion Skin Blue\", \"#FFE2D5C2\": \"Onion White\", \"#FFB0B5B5\": \"Online\", \"#FF468C3E\": \"Online Lime\", \"#FFE1BC99\": \"Only Natural\", \"#FFD4CDB5\": \"Only Oatmeal\", \"#FFCBCCB5\": \"Only Olive\", \"#FFF4D1B9\": \"Only Yesterday\", \"#FF66EEBB\": \"Onsen\", \"#FF777CB0\": \"Ontario Violet\", \"#FF464544\": \"Onyx Tint\", \"#FFDCBFD5\": \"Ooh la La\", \"#FFC2BEB6\": \"Ooid Sand\", \"#FFAEE0E4\": \"Opal Tint\", \"#FFFCEECE\": \"Opal Cream\", \"#FFE95C4B\": \"Opal Flame\", \"#FF157954\": \"Opal Green\", \"#FF9A9394\": \"Opal Grey\", \"#FF9DB9B2\": \"Opal Silk\", \"#FF96D1C3\": \"Opal Turquoise\", \"#FF7E8FBB\": \"Opal Violet\", \"#FFB1C6D1\": \"Opal Waters\", \"#FFB4C0B6\": \"Opalescence\", \"#FF3C94C1\": \"Opalescent\", \"#FFFFD2A9\": \"Opalescent Coral\", \"#FFC1D1C4\": \"Opaline\", \"#FFA3C57D\": \"Opaline Green\", \"#FFC6A0AB\": \"Opaline Pink\", \"#FFC7DFE0\": \"Open Air\", \"#FFF5F1E5\": \"Open Book\", \"#FFBBA990\": \"Open Canyon\", \"#FF91876B\": \"Open Range\", \"#FF83AFBC\": \"Open Seas\", \"#FFF8E2A9\": \"Open Sesame\", \"#FFD0E2E8\": \"Open Skies\", \"#FFBD6426\": \"Opening Night\", \"#FFBD273A\": \"Opening Ribbon\", \"#FF816575\": \"Opera\", \"#FF453E6E\": \"Opera Blue\", \"#FFE5F1EB\": \"Opera Glass\", \"#FF365360\": \"Opera Glasses\", \"#FFFF1B2D\": \"Opera Red\", \"#FF3A284C\": \"Operetta Mauve\", \"#FF987E7E\": \"Opium Variant\", \"#FF735362\": \"Opium Mauve\", \"#FFE9AB51\": \"Optimist Gold\", \"#FFF5E1A6\": \"Optimistic Yellow\", \"#FF465A7F\": \"Optimum Blue\", \"#FF130D0D\": \"Optophobia\", \"#FFD5892F\": \"Opulent\", \"#FF0055EE\": \"Opulent Blue\", \"#FF103222\": \"Opulent Green\", \"#FF88DD11\": \"Opulent Lime\", \"#FF462343\": \"Opulent Mauve\", \"#FFF2EBEA\": \"Opulent Opal\", \"#FFF16640\": \"Opulent Orange\", \"#FF775577\": \"Opulent Ostrich\", \"#FF673362\": \"Opulent Purple\", \"#FF88DDCC\": \"Opulent Turquoise\", \"#FFA09EC6\": \"Opulent Violet\", \"#FFCECAE1\": \"Opus\", \"#FFE3E1ED\": \"Opus Magnum\", \"#FF395555\": \"Oracle Variant\", \"#FFFAF8F7\": \"Orange Albedo\", \"#FFFF9682\": \"Orange Aura\", \"#FFFF8822\": \"Orange Avant-Garde\", \"#FFB56D41\": \"Orange Ballad\", \"#FFFF8844\": \"Orange Bell Pepper\", \"#FFF5C99B\": \"Orange Blast\", \"#FFB16002\": \"Orange Brown Variant\", \"#FFFF6E3A\": \"Orange Burst\", \"#FFFDD1A4\": \"Orange Canyon\", \"#FFDE954B\": \"Orange Caramel\", \"#FFFAD48B\": \"Orange Chalk\", \"#FFF9AE7D\": \"Orange Chiffon\", \"#FFF3C775\": \"Orange Chocolate\", \"#FFE6A57F\": \"Orange Clay\", \"#FFFF550E\": \"Orange Clown Fish\", \"#FFFBEBCF\": \"Orange Coloured White\", \"#FFF4E3D2\": \"Orange Confection\", \"#FFFFB710\": \"Orange Creamsicle\", \"#FFEE7733\": \"Orange Crush\", \"#FFDD6600\": \"Orange Danger\", \"#FFEB7D5D\": \"Orange Daylily\", \"#FFFFC355\": \"Orange Delight\", \"#FFE18E3F\": \"Orange Drop\", \"#FFD1907C\": \"Orange Essential\", \"#FFA96F55\": \"Orange Flambe\", \"#FFFE9E13\": \"Orange Fruit\", \"#FFFFCA7D\": \"Orange Glass\", \"#FFFFE2BD\": \"Orange Glow\", \"#FFEE7722\": \"Orange Gluttony\", \"#FFFBAF8D\": \"Orange Grove\", \"#FFFF9A45\": \"Orange Hibiscus\", \"#FFFFDEC1\": \"Orange Ice\", \"#FFFAC205\": \"Orange Jelly\", \"#FFFF9731\": \"Orange Jewel\", \"#FFCA5333\": \"Orange Keeper\", \"#FFBE7249\": \"Orange Lily\", \"#FFEDAA80\": \"Orange Liqueur\", \"#FFD3A083\": \"Orange Maple\", \"#FFFAAC72\": \"Orange Marmalade\", \"#FFFFBD8A\": \"Orange Mousse\", \"#FFCE8C4F\": \"Orange Nectar Bat\", \"#FFDA7631\": \"Orange Ochre\", \"#FFDD7700\": \"Orange Outburst\", \"#FFF49975\": \"Orange Pecan\", \"#FFCB8D5F\": \"Orange Pekoe\", \"#FFDA7D00\": \"Orange Pepper\", \"#FFFF6611\": \"Orange Pi\\u00f1ata\", \"#FFFF6F52\": \"Orange Pink\", \"#FFFFBC3E\": \"Orange Pop\", \"#FFE68750\": \"Orange Poppy\", \"#FFFF7913\": \"Orange Popsicle\", \"#FFF2A60F\": \"Orange Pospsicle\", \"#FFFEBC61\": \"Orange Quench\", \"#FFFE4401\": \"Orange Red Variant\", \"#FFA85335\": \"Orange Roughy Variant\", \"#FFC05200\": \"Orange Rufous\", \"#FFF0B073\": \"Orange Salmonberry\", \"#FFDD9900\": \"Orange Satisfaction\", \"#FFFEC49B\": \"Orange Sherbet\", \"#FFE2D6BD\": \"Orange Shimmer\", \"#FFDD7744\": \"Orange Shot\", \"#FFF4915C\": \"Orange Slice\", \"#FFFAE1C7\": \"Orange Sparkle\", \"#FFFEA060\": \"Orange Spice\", \"#FFC27635\": \"Orange Squash\", \"#FFE8A320\": \"Orange Sulphur\", \"#FFFF7435\": \"Orange Supreme\", \"#FFFF8379\": \"Orange Tea Rose\", \"#FFF95C14\": \"Orange Tiger\", \"#FFFFB452\": \"Orange Toffee\", \"#FFBC5339\": \"Orange Vermillion\", \"#FFEAE3CD\": \"Orange White Variant\", \"#FFB74923\": \"Orange Wood\", \"#FFFDB915\": \"Orange Yellow Variant\", \"#FFFFA601\": \"Orange You Glad\", \"#FFFD7F22\": \"Orange You Happy?\", \"#FFF07227\": \"Orange Zest\", \"#FFE35435\": \"Orangeade\", \"#FFEE5511\": \"Orangealicious\", \"#FFE6BCA9\": \"Orangery\", \"#FFE88354\": \"Orangevale\", \"#FFE57059\": \"Orangeville\", \"#FFFEC615\": \"Orangina\", \"#FFFD8D49\": \"Orangish\", \"#FFB25F03\": \"Orangish Brown\", \"#FFF43605\": \"Orangish Red\", \"#FFEE6237\": \"Oranzhewyi Orange\", \"#FF772299\": \"Orb of Discord\", \"#FFEEDD44\": \"Orb of Harmony\", \"#FF6D83BB\": \"Orbital\", \"#FF220088\": \"Orbital Kingdom\", \"#FFD0CCC9\": \"Orca White\", \"#FF9A858C\": \"Orchard Plum\", \"#FFAE230E\": \"Orchestra of Red\", \"#FF7A81FF\": \"Orchid Variant\", \"#FFC3CCD5\": \"Orchid Ash\", \"#FFC5AECF\": \"Orchid Bloom\", \"#FFE4E1E4\": \"Orchid Blossom\", \"#FFD6CBC7\": \"Orchid Blush\", \"#FFD1ACCE\": \"Orchid Bouquet\", \"#FFAA55AA\": \"Orchid Dottyback\", \"#FFBB4488\": \"Orchid Ecstasy\", \"#FFC9C1D0\": \"Orchid Fragrance\", \"#FF5E5871\": \"Orchid Grey\", \"#FFB0879B\": \"Orchid Haze\", \"#FFC3BBD4\": \"Orchid House\", \"#FFE5E999\": \"Orchid Hue\", \"#FFCEC3D2\": \"Orchid Hush\", \"#FFE0D0DB\": \"Orchid Ice\", \"#FFAC74A4\": \"Orchid Kiss\", \"#FFE5DDE7\": \"Orchid Lane\", \"#FF9C4A7D\": \"Orchid Lei\", \"#FFE8E6E8\": \"Orchid Mist\", \"#FFFFA180\": \"Orchid Orange\", \"#FF876281\": \"Orchid Orchestra\", \"#FFBFB4CB\": \"Orchid Petal\", \"#FFAD878D\": \"Orchid Red\", \"#FFE9D1DA\": \"Orchid Rose\", \"#FFCBC5C2\": \"Orchid Shadow\", \"#FFE1CCDF\": \"Orchid Shimmer\", \"#FFCD899E\": \"Orchid Smoke\", \"#FFD3C9D4\": \"Orchid Tint\", \"#FFDDE0E8\": \"Orchid Whisper\", \"#FFF1EBD9\": \"Orchid White Variant\", \"#FF938EA9\": \"Orchilla\", \"#FF998188\": \"Ordain\", \"#FF1A4C32\": \"Order Green\", \"#FF1C3339\": \"Ore Bluish Black\", \"#FF2B6551\": \"Ore Mountains Green\", \"#FFFAEECB\": \"Orecchiette\", \"#FF7F8353\": \"Oregano\", \"#FF4DA241\": \"Oregano Green\", \"#FF8D8764\": \"Oregano Spice\", \"#FF448EE4\": \"Oregon Blue\", \"#FF49354E\": \"Oregon Grape\", \"#FF916238\": \"Oregon Hazel\", \"#FFEFB91B\": \"Oregon Trail\", \"#FFFFCDA8\": \"Orenju Ogon Koi\", \"#FF9E9B85\": \"Orestes\", \"#FF747261\": \"Organic\", \"#FFE1CDA4\": \"Organic Bamboo\", \"#FFFEEDE0\": \"Organic Fibre\", \"#FFC6C2AB\": \"Organic Field\", \"#FFABA964\": \"Organic Garden\", \"#FF7FAC6E\": \"Organic Green\", \"#FFA99E54\": \"Organic Matter\", \"#FFA67E3E\": \"Organic Style\", \"#FFFFDEA6\": \"Organza\", \"#FFBBCCBD\": \"Organza Green\", \"#FFFBEEDA\": \"Organza Peach\", \"#FF7391CC\": \"Organza Violet\", \"#FFECE0C6\": \"Origami\", \"#FFE1E6C7\": \"Origami Clover\", \"#FFE5E2DA\": \"Origami White\", \"#FFF0E5D3\": \"Original White\", \"#FFD2D3B3\": \"Orinoco Variant\", \"#FFFF8008\": \"Oriole\", \"#FFF6D576\": \"Oriole Yellow\", \"#FFFB4F14\": \"Orioles Orange\", \"#FFDE55A9\": \"Orion\", \"#FF40525F\": \"Orion Blue\", \"#FF535558\": \"Orion Grey\", \"#FFA55AF4\": \"Orion Nebula\", \"#FF27221F\": \"Orka Black\", \"#FF3E5755\": \"Orkhide Shade\", \"#FFD91407\": \"Orko\", \"#FF97D5E7\": \"Orleans Tune\", \"#FF00867D\": \"Ornamental Turquoise\", \"#FF806D95\": \"Ornate\", \"#FFF77D25\": \"Ornery Tangerine\", \"#FFC29436\": \"Oro\", \"#FFD9D8DA\": \"Orochimaru\", \"#FFD17C3F\": \"Orpiment Orange\", \"#FFF9C89B\": \"Orpiment Yellow\", \"#FFBE855E\": \"Orpington Chicken\", \"#FFF9EACC\": \"Orzo Pasta\", \"#FFF4A045\": \"Osage Orange\", \"#FF5B5A4D\": \"Osiris\", \"#FFA6BDBE\": \"Oslo Blue\", \"#FF63564B\": \"Osprey\", \"#FFCCBAB1\": \"Osprey Nest\", \"#FFAD9769\": \"Osso Bucco\", \"#FFE9E3D5\": \"Ostrich\", \"#FFDCD0BB\": \"Ostrich Egg\", \"#FFEADFE6\": \"Ostrich Tail\", \"#FF665D59\": \"Oswego Tea\", \"#FFFF4E20\": \"\\u014ctan Red\", \"#FF633D38\": \"Otis Madeira\", \"#FF00A78D\": \"Ottawa Falls\", \"#FF7F674F\": \"Otter\", \"#FF654320\": \"Otter Brown\", \"#FF3F5A5D\": \"Otter Creek\", \"#FF938577\": \"Otter Tail\", \"#FF8C4512\": \"Otterly Brown\", \"#FFBEDFD3\": \"Otto Ice\", \"#FFD3DBCB\": \"Ottoman Variant\", \"#FFEE2222\": \"Ottoman Red\", \"#FF4F4944\": \"Oubliette\", \"#FFEE7948\": \"Ouni Red\", \"#FFA84B7A\": \"Our Little Secret\", \"#FFF26D8F\": \"Out of Fashion\", \"#FF2CED2B\": \"Out of Left Field\", \"#FF9C909C\": \"Out of Plumb\", \"#FF1199EE\": \"Out of the Blue\", \"#FFC9A375\": \"Outback\", \"#FF7E5D47\": \"Outback Brown\", \"#FF8D745E\": \"Outdoor Cafe\", \"#FFA07D5E\": \"Outdoor Land\", \"#FF6E6F4D\": \"Outdoor Oasis\", \"#FFB2974D\": \"Outdoorsy\", \"#FF654846\": \"Outer Boundary\", \"#FF2A6295\": \"Outer Reef\", \"#FF221177\": \"Outer Rim\", \"#FF314E64\": \"Outer Space Variant\", \"#FFB7A48B\": \"Outerbanks\", \"#FFE6955F\": \"Outgoing Orange\", \"#FFB67350\": \"Outlawed Orange\", \"#FF824438\": \"Outrageous\", \"#FF8AB733\": \"Outrageous Green\", \"#FF82714D\": \"Outrigger\", \"#FF9EB2B9\": \"Ovation\", \"#FF4D6D08\": \"Over the Hills\", \"#FFABB8D5\": \"Over the Moon\", \"#FF98D5EA\": \"Over the Sky\", \"#FFB09D8A\": \"Over the Taupe\", \"#FF61311C\": \"Overbaked\", \"#FF005555\": \"Overboard\", \"#FF73A3D0\": \"Overcast\", \"#FFB3583D\": \"Overcast Brick\", \"#FF8F99A2\": \"Overcast Day\", \"#FF42426F\": \"Overcast Night\", \"#FFA7B8C4\": \"Overcast Sky\", \"#FF0AE9B4\": \"Overchlorinated Pool\", \"#FF4400FF\": \"Overdue Blue\", \"#FFC7C3BE\": \"Overdue Grey\", \"#FFEFF4DC\": \"Overexposed Shot\", \"#FF88DD00\": \"Overgrown\", \"#FF888844\": \"Overgrown Citadel\", \"#FF8B8265\": \"Overgrown Granite\", \"#FF448833\": \"Overgrown Mausoleum\", \"#FF116611\": \"Overgrown Temple\", \"#FF6B6048\": \"Overgrown Trees\", \"#FF6A8988\": \"Overgrown Trellis\", \"#FF88CC33\": \"Overgrowth\", \"#FFEEC25F\": \"Overjoy\", \"#FF717481\": \"Overlook\", \"#FFFBF0DB\": \"Overnight Oats\", \"#FF97A554\": \"Overt Green\", \"#FF33557F\": \"Overtake\", \"#FFA4E3B3\": \"Overtone\", \"#FF8C7E49\": \"Ovoid Fruit\", \"#FFC0AF87\": \"Owl Manner Malt\", \"#FF90845F\": \"Owlet\", \"#FFC1E28A\": \"Oxalis\", \"#FF71383F\": \"Oxblood Red\", \"#FFB1BBC5\": \"Oxford\", \"#FF743B39\": \"Oxford Brick\", \"#FF504139\": \"Oxford Brown\", \"#FF001B2E\": \"Oxford by Night\", \"#FFDB7192\": \"Oxford Sausage\", \"#FFBDA07F\": \"Oxford Street\", \"#FFB8A99A\": \"Oxford Tan\", \"#FFBF7657\": \"Oxide\", \"#FF6D9A78\": \"Oxley Variant\", \"#FF92B6D5\": \"Oxygen Blue\", \"#FFE3D3BF\": \"Oyster\", \"#FFDBD0BB\": \"Oyster Bar\", \"#FF71818C\": \"Oyster Bay Variant\", \"#FFF2E5B1\": \"Oyster Bisque\", \"#FF4A4C45\": \"Oyster Catch\", \"#FFF4F0D2\": \"Oyster Cracker\", \"#FFCBC1AE\": \"Oyster Grey\", \"#FFE4DED2\": \"Oyster Haze\", \"#FFEFEFE5\": \"Oyster Island\", \"#FFB1AB96\": \"Oyster Linen\", \"#FFB8BCBE\": \"Oyster Mushroom\", \"#FFF5E6CC\": \"Oyster Omelette Cream\", \"#FFD4B5B0\": \"Oyster Pink Variant\", \"#FFBFB3A1\": \"Oyster Shoal\", \"#FFCBC4A2\": \"Oyster White\", \"#FF8B95A2\": \"Ozone\", \"#FFC7D3E0\": \"Ozone Blue\", \"#FF5E3A39\": \"Pa Red\", \"#FF864B36\": \"Paarl Variant\", \"#FF7A715C\": \"Pablo Variant\", \"#FFFFE737\": \"Pac-Man\", \"#FFECDFAD\": \"Paccheri\", \"#FFE5DDD0\": \"Pacer White\", \"#FF8F989D\": \"Pachyderm\", \"#FF24646B\": \"Pacific\", \"#FF96ACB8\": \"Pacific Bliss\", \"#FFC3A285\": \"Pacific Bluffs\", \"#FFC1DBE7\": \"Pacific Breeze\", \"#FF0052CC\": \"Pacific Bridge\", \"#FF5E85B1\": \"Pacific Coast\", \"#FF004488\": \"Pacific Depths\", \"#FFDCDCD5\": \"Pacific Fog\", \"#FF77B9DB\": \"Pacific Harbour\", \"#FF2D3544\": \"Pacific Line\", \"#FFCDD5D3\": \"Pacific Mist\", \"#FF25488A\": \"Pacific Navy\", \"#FF92CBF1\": \"Pacific Ocean\", \"#FF69A4B9\": \"Pacific Palisade\", \"#FFC0D6EA\": \"Pacific Panorama\", \"#FFE8EAE6\": \"Pacific Pearl\", \"#FF546B45\": \"Pacific Pine\", \"#FF167D97\": \"Pacific Pleasure\", \"#FF026B5D\": \"Pacific Queen\", \"#FFF1EBCD\": \"Pacific Sand\", \"#FF3E8083\": \"Pacific Sea Teal\", \"#FF3C4A56\": \"Pacific Spirit\", \"#FF035453\": \"Pacific Storm\", \"#FF4E77A3\": \"Pacifica\", \"#FFB7ACA0\": \"Packed Sand\", \"#FFBA9B5D\": \"Packing Paper\", \"#FF4F4037\": \"Paco Variant\", \"#FF859E94\": \"Padded Leaf\", \"#FF88724D\": \"Paddle Wheel\", \"#FFDA9585\": \"Paddy\", \"#FF99BB44\": \"Paddy Field\", \"#FF7EB394\": \"Padua Variant\", \"#FFDCC61F\": \"Paella\", \"#FFE1D7C2\": \"Paella Natural White\", \"#FF99DAC5\": \"Pageant Green\", \"#FFB6C3D1\": \"Pageant Song\", \"#FF68447C\": \"Pageantry Purple\", \"#FF127E93\": \"Pagoda\", \"#FF1B8192\": \"Pagoda Blue\", \"#FF8C8E65\": \"Paid in Full\", \"#FF6B4947\": \"Painite\", \"#FF11EEFF\": \"Paint the Sky\", \"#FFDDBA8F\": \"Painted Ash\", \"#FF5F3D32\": \"Painted Bark\", \"#FFEB8F6F\": \"Painted Clay\", \"#FFBEB8B6\": \"Painted Desert\", \"#FF6D544F\": \"Painted Leather\", \"#FFBB9471\": \"Painted Pony\", \"#FFCB5139\": \"Painted Poppy\", \"#FF008595\": \"Painted Sea\", \"#FFB28774\": \"Painted Skies\", \"#FF56745F\": \"Painted Turtle\", \"#FFF9F2DE\": \"Painter\\u2019s Canvas\", \"#FFF2EBDD\": \"Painter\\u2019s White\", \"#FF726F7E\": \"Paisley\", \"#FF8B79B1\": \"Paisley Purple\", \"#FFAD7362\": \"Pajarito Red\", \"#FF43456D\": \"Palace Arms\", \"#FF3973C0\": \"Palace Blue\", \"#FF426255\": \"Palace Green\", \"#FF799AAA\": \"Palace Intrigue\", \"#FF68457A\": \"Palace Purple\", \"#FF752745\": \"Palace Red\", \"#FFF8CAD5\": \"Palace Rose\", \"#FFA7A6B1\": \"Palace Walls\", \"#FFF4F0E5\": \"Palais White\", \"#FF888811\": \"Palak Paneer\", \"#FFEEDCD1\": \"Palatial\", \"#FFF9F2E4\": \"Palatial White\", \"#FFC9C7B6\": \"Palatine\", \"#FFFFF9D0\": \"Pale\", \"#FFF4E9BA\": \"Pale Adobe\", \"#FFFEF068\": \"Pale Ale\", \"#FFBCD4E1\": \"Pale Aqua\", \"#FFC9BFA8\": \"Pale Bamboo\", \"#FFF5E28D\": \"Pale Banana\", \"#FFCCC7B1\": \"Pale Beige\", \"#FFE2CCC7\": \"Pale Berries\", \"#FFE39E9C\": \"Pale Berry\", \"#FF98DED9\": \"Pale Beryl\", \"#FF4A475C\": \"Pale Blackish Purple\", \"#FFF0EAE1\": \"Pale Bloom\", \"#FFFDE1F0\": \"Pale Blossom\", \"#FFD0FEFE\": \"Pale Blue\", \"#FFA2ADB1\": \"Pale Blue Grey\", \"#FFDFAFA4\": \"Pale Blush\", \"#FFB1916E\": \"Pale Brown Variant\", \"#FFEEEBE8\": \"Pale Bud\", \"#FFF1EFA6\": \"Pale Canary Variant\", \"#FFE8DFD5\": \"Pale Cashmere\", \"#FFC9CBBE\": \"Pale Celadon\", \"#FFE9E9C7\": \"Pale Celery\", \"#FFEFE5D7\": \"Pale Chamois\", \"#FFFDEFF2\": \"Pale Cherry Blossom\", \"#FFDADEE9\": \"Pale Cloud\", \"#FFF0D0B4\": \"Pale Coral\", \"#FFAD6E44\": \"Pale Cordovan\", \"#FFCED9E1\": \"Pale Cornflower\", \"#FFD6D5BC\": \"Pale Cucumber\", \"#FFFDE89A\": \"Pale Daffodil\", \"#FFECCCC1\": \"Pale Dogwood Variant\", \"#FFFDE8D0\": \"Pale Egg\", \"#FFE7D1DD\": \"Pale Flamingo\", \"#FF698AAB\": \"Pale Flower\", \"#FFC7E1EE\": \"Pale Frost\", \"#FFEADDCA\": \"Pale Gingersnap\", \"#FFFDDE6C\": \"Pale Gold\", \"#FFC0A2C7\": \"Pale Grape\", \"#FF69B076\": \"Pale Green Variant\", \"#FF96907E\": \"Pale Green Grey\", \"#FFE2E2D2\": \"Pale Green Tea\", \"#FFFDFDFE\": \"Pale Grey\", \"#FFD4E2EB\": \"Pale Grey Blue\", \"#FFE7D8EA\": \"Pale Grey Magenta\", \"#FFF5D6AA\": \"Pale Honey\", \"#FF8895C5\": \"Pale Iris\", \"#FFD4CFB2\": \"Pale Ivy\", \"#FF77C3B4\": \"Pale Jade\", \"#FFFED6CC\": \"Pale Jasper\", \"#FF998877\": \"Pale Khaki\", \"#FFABF5ED\": \"Pale King\\u2019s Blue\", \"#FFBDCAA8\": \"Pale Leaf Variant\", \"#FFD8D4BF\": \"Pale Lichen\", \"#FFB1FC99\": \"Pale Light Green\", \"#FFD8B5BF\": \"Pale Lilac\", \"#FFF3ECE7\": \"Pale Lily\", \"#FFB1FF65\": \"Pale Lime Green\", \"#FFDFE497\": \"Pale Lime Yellow\", \"#FFEBE5D6\": \"Pale Linen\", \"#FFCCD2CA\": \"Pale Loden\", \"#FFC4ACB2\": \"Pale Lychee\", \"#FFF5E1BA\": \"Pale Maize\", \"#FFFFBB44\": \"Pale Marigold\", \"#FFC6A4A4\": \"Pale Mauve\", \"#FFAAC2A1\": \"Pale Mint\", \"#FFDCC797\": \"Pale Moss\", \"#FFD0DBC4\": \"Pale Moss Green\", \"#FFBAE1D3\": \"Pale Mountain Lake Turquoise\", \"#FFE4DDE7\": \"Pale Muse\", \"#FFFAF5E2\": \"Pale Narcissus\", \"#FFDCE0CF\": \"Pale Oak Grove\", \"#FFD3C7A1\": \"Pale Olive\", \"#FFDEDBE5\": \"Pale Orchid\", \"#FFF6E2EC\": \"Pale Orchid Petal\", \"#FFFDEBBC\": \"Pale Organza\", \"#FF9C8D72\": \"Pale Oyster Variant\", \"#FFE5DBCA\": \"Pale Palomino\", \"#FFD1C3AD\": \"Pale Parchment\", \"#FFE3D8BF\": \"Pale Parsnip\", \"#FF9ADEDB\": \"Pale Pastel\", \"#FFFFE5AD\": \"Pale Peach\", \"#FFF4DA6E\": \"Pale Pear\", \"#FFFFF2DE\": \"Pale Pearl\", \"#FFF7E0DE\": \"Pale Perfection\", \"#FFC8D2E2\": \"Pale Periwinkle\", \"#FFD4ACAD\": \"Pale Persimmon\", \"#FFD9BFCE\": \"Pale Petals\", \"#FFBA9BA5\": \"Pale Petticoat\", \"#FFF8C0C7\": \"Pale Petunia\", \"#FFCCD5FF\": \"Pale Phthalo Blue\", \"#FFEFCDDB\": \"Pale Pink Variant\", \"#FFE3E7D1\": \"Pale Pistachio\", \"#FFBCA8AD\": \"Pale Poppy\", \"#FFEEC8D3\": \"Pale Primrose\", \"#FFB790D4\": \"Pale Purple\", \"#FFEFEADA\": \"Pale Quartz\", \"#FFEBEBD7\": \"Pale Rebelka Jakub\", \"#FFEFD6DA\": \"Pale Rose Variant\", \"#FFACBDA1\": \"Pale Sage\", \"#FFD3D1B9\": \"Pale Sagebrush\", \"#FFE5D5BA\": \"Pale Sand\", \"#FFF0BCAD\": \"Pale Satin Peach\", \"#FFC3E7E8\": \"Pale Seafoam\", \"#FFCACFDC\": \"Pale Shale\", \"#FFF8DBD6\": \"Pale Shrimp\", \"#FFDFC7BC\": \"Pale Sienna\", \"#FFBDF6FE\": \"Pale Sky Variant\", \"#FF9FABAD\": \"Pale Slate Variant\", \"#FFB3BE98\": \"Pale Spring Morning\", \"#FFE4DED8\": \"Pale Starlet\", \"#FFF2C880\": \"Pale Sunshine\", \"#FF82CBB2\": \"Pale Teal\", \"#FFCECDBB\": \"Pale Tendril\", \"#FFEAAA96\": \"Pale Terra\", \"#FFC8DCBB\": \"Pale Tidepool\", \"#FFA5FBD5\": \"Pale Turquoise Variant\", \"#FF6F9892\": \"Pale Verdigris\", \"#FFC6C3D6\": \"Pale Violet\", \"#FFD8DECF\": \"Pale Vista\", \"#FFB6D3DF\": \"Pale Whale\", \"#FFD9C29F\": \"Pale Wheat\", \"#FF89AB98\": \"Pale Willow\", \"#FFBBC8E6\": \"Pale Wisteria\", \"#FFEAD2A2\": \"Pale Wood\", \"#FFF4EED1\": \"Palest of Lemon\", \"#FFDCCDB9\": \"Palest Satin\", \"#FFC3B497\": \"Palisade\", \"#FFAF8EA5\": \"Palisade Orchid\", \"#FFF7ECE1\": \"Palish Peach\", \"#FFEEE9DF\": \"Palladian\", \"#FFB1B1B1\": \"Palladium\", \"#FF314A4E\": \"Pallasite Blue\", \"#FFB3CDD4\": \"Pallid Blue\", \"#FFC1E0C1\": \"Pallid Green\", \"#FFCBDCB7\": \"Pallid Light Green\", \"#FFFCB99D\": \"Pallid Orange\", \"#FFF3DFDB\": \"Pallid Rose\", \"#FFCDCEBE\": \"Pallid Wych\", \"#FFAFAF5E\": \"Palm\", \"#FFDBE2C9\": \"Palm Breeze\", \"#FFAEAD5B\": \"Palm Frond\", \"#FF20392C\": \"Palm Green Variant\", \"#FFDDD8C2\": \"Palm Heart Cream\", \"#FF7A7363\": \"Palm Lane\", \"#FF36482F\": \"Palm Leaf Variant\", \"#FF20887A\": \"Palm Springs Splash\", \"#FFEDD69D\": \"Palm Sugar Yellow\", \"#FF74B560\": \"Palm Tree\", \"#FF577063\": \"Palmerin\", \"#FF6D9A9B\": \"Palmetto\", \"#FFCEB993\": \"Palmetto Bluff\", \"#FFEAEACF\": \"Palmito\", \"#FF5F6356\": \"Palo Verde\", \"#FF9F9C99\": \"Paloma\", \"#FFE9B679\": \"Paloma Tan\", \"#FFBB7744\": \"Palomino\", \"#FFDAAE00\": \"Palomino Gold\", \"#FFE6D6BA\": \"Palomino Mane\", \"#FF837871\": \"Palomino Pony\", \"#FFC2AA8D\": \"Palomino Tan\", \"#FFEAE4DC\": \"Pampas Variant\", \"#FFF5EAEB\": \"Pampered Princess\", \"#FFDCA356\": \"Pan de Coco\", \"#FF657AEF\": \"Pan Purple\", \"#FFE8BE99\": \"Pan Tostado\", \"#FFCFD0C5\": \"Pan\\u2019s Flute\", \"#FFDDDBC0\": \"Panacea\", \"#FFEBF7E4\": \"Panache Variant\", \"#FFEDC9D5\": \"Panache Pink\", \"#FFC6577C\": \"Panama Rose\", \"#FFF7D788\": \"Pancake\", \"#FFDFB992\": \"Pancho Variant\", \"#FFBFDB89\": \"Pancotto Pugliese\", \"#FF544F3A\": \"Panda\", \"#FF3C4748\": \"Panda Black\", \"#FFEAE2D4\": \"Panda White\", \"#FF9FB057\": \"Pandan Cake\", \"#FF616C44\": \"Pandanus\", \"#FFA1A4AE\": \"Pandemonium\", \"#FF71689A\": \"Pandora\", \"#FFE3D4CF\": \"Pandora Grey\", \"#FFFEDBB7\": \"Pandora\\u2019s Box\", \"#FF9B5227\": \"Panela\", \"#FF4E4F6A\": \"Pango Black\", \"#FFF4AA53\": \"Pani Puri\", \"#FFCDB9A7\": \"Panko\", \"#FF7895CC\": \"Pannikin\", \"#FF327A88\": \"Panorama\", \"#FF35BDC8\": \"Panorama Blue\", \"#FF7F8FCA\": \"Pansy Garden\", \"#FF5F4561\": \"Pansy Petal\", \"#FFBFA7B6\": \"Pansy Posie\", \"#FFBCA3B4\": \"Pansy Posy\", \"#FFADAFBA\": \"Pantomime\", \"#FF5A4A64\": \"Paparazzi\", \"#FFC6CBD1\": \"Paparazzi Flash\", \"#FFFE985C\": \"Papaya\", \"#FFFCA07F\": \"Papaya Punch\", \"#FFFFEAC5\": \"Papaya Sorbet\", \"#FFFFD1AF\": \"Papaya Whip Variant\", \"#FFD7AC7F\": \"Paper Brown\", \"#FFF0E5C7\": \"Paper Daisy\", \"#FFD6C5A9\": \"Paper Dog\", \"#FFC5D0E6\": \"Paper Elephant\", \"#FFB1A99F\": \"Paper Goat\", \"#FFCC4466\": \"Paper Hearts\", \"#FFF2EBE1\": \"Paper Lamb\", \"#FFF2E0C4\": \"Paper Lantern\", \"#FFEAD4A6\": \"Paper Moon\", \"#FFF1ECE0\": \"Paper Plane\", \"#FFB4A07A\": \"Paper Sack\", \"#FFFDF1AF\": \"Paper Tiger\", \"#FFF6EFDF\": \"Paper White\", \"#FF249148\": \"Paperboy\\u2019s Lawn\", \"#FFEFEADC\": \"Papier Blanc\", \"#FF8590AE\": \"Papilio Argeotus\", \"#FFF9EBCC\": \"Pappardelle Noodle\", \"#FF7C2D37\": \"Paprika Variant\", \"#FFC24325\": \"Paprika Kisses\", \"#FF999911\": \"Papyrus\", \"#FFC0AC92\": \"Papyrus Map\", \"#FFF5EDD6\": \"Papyrus Paper\", \"#FF507069\": \"Par Four\", \"#FFBEB755\": \"Parachute\", \"#FF362852\": \"Parachute Purple\", \"#FFFFE2B5\": \"Parachute Silk\", \"#FF00589B\": \"Parachuting\", \"#FFDEF1EA\": \"Paradise\", \"#FFFF8C55\": \"Paradise Bird\", \"#FF5F7475\": \"Paradise City\", \"#FF83988C\": \"Paradise Found\", \"#FF746565\": \"Paradise Grape\", \"#FFA3E493\": \"Paradise Green\", \"#FF5AA7A0\": \"Paradise Island\", \"#FF009494\": \"Paradise Landscape\", \"#FF398749\": \"Paradise of Greenery\", \"#FF006622\": \"Paradise Palms\", \"#FFE4445E\": \"Paradise Pink\", \"#FF66C6D0\": \"Paradise Sky\", \"#FF8DDEE1\": \"Paradisiacal Getaway\", \"#FF488084\": \"Paradiso Variant\", \"#FFA99A8A\": \"Parador Inn\", \"#FF908D86\": \"Parador Stone\", \"#FF78AE48\": \"Parakeet\", \"#FF7EB6FF\": \"Parakeet Blue\", \"#FFCBD3C6\": \"Parakeet Pete\", \"#FF5B6161\": \"Paramount\", \"#FFE4E2D5\": \"Paramount White\", \"#FF007D7C\": \"Parasailing\", \"#FF914B13\": \"Parasite Brown\", \"#FFE9DFDE\": \"Parasol\", \"#FF824A53\": \"Parauri Brown\", \"#FFFEFCAF\": \"Parchment Variant\", \"#FFF0E7D8\": \"Parchment Paper\", \"#FFF9EAE5\": \"Parchment White\", \"#FFC8A6A1\": \"Parfait\", \"#FF91A7BC\": \"Paris\", \"#FFB7DDED\": \"Paris Blue\", \"#FF888873\": \"Paris Creek\", \"#FFFBEB50\": \"Paris Daisy Variant\", \"#FF50C87C\": \"Paris Green\", \"#FFA6B7C8\": \"Paris Grey\", \"#FF312760\": \"Paris M Variant\", \"#FFC9C79A\": \"Paris Mint\", \"#FF737274\": \"Paris Paving\", \"#FFDA6D91\": \"Paris Pink\", \"#FFBFCDC0\": \"Paris White Variant\", \"#FF4F7CA4\": \"Parisian Blue\", \"#FF978478\": \"Parisian Caf\\u00e9\", \"#FFD1C7B8\": \"Parisian Cashmere\", \"#FF6B9C42\": \"Parisian Green\", \"#FF323341\": \"Parisian Night\", \"#FF7D9B89\": \"Parisian Patina\", \"#FF787093\": \"Parisian Violet\", \"#FF465048\": \"Park Avenue\", \"#FF537F6C\": \"Park Bench\", \"#FF88C9A6\": \"Park Green Flat\", \"#FF428F46\": \"Park Picnic\", \"#FF46483E\": \"Parkview\", \"#FF477BBD\": \"Parkwater\", \"#FF465F7E\": \"Parlour Blue\", \"#FFA12D5D\": \"Parlour Red\", \"#FFBAA1B2\": \"Parlour Rose\", \"#FFC8C197\": \"Parlour Sage\", \"#FFD4C6AF\": \"Parlour Taupe\", \"#FF806E85\": \"Parma Grey\", \"#FFF89882\": \"Parma Ham\", \"#FF5F5680\": \"Parma Mauve\", \"#FF5E3958\": \"Parma Plum Red\", \"#FF55455A\": \"Parma Violet\", \"#FF887CAB\": \"Parmentier\", \"#FFFFFFDD\": \"Parmesan\", \"#FFA9A237\": \"Parrot Feather\", \"#FF018DA1\": \"Parrot Flight\", \"#FF8DB051\": \"Parrot Green\", \"#FFD998A0\": \"Parrot Pink\", \"#FFEEBFD5\": \"Parrot Tulip\", \"#FFF8DC74\": \"Parrot Waxcap\", \"#FF028FC4\": \"Parrotfish Blue\", \"#FF305D35\": \"Parsley Variant\", \"#FF5A9F4D\": \"Parsley Green\", \"#FF3D7049\": \"Parsley Sprig\", \"#FFD6C69A\": \"Parsnip\", \"#FF9D892E\": \"Parsnip Root\", \"#FFFFEDF8\": \"Partial Pink\", \"#FFDEF3E6\": \"Particle Cannon\", \"#FFCB3215\": \"Particle Ioniser Red\", \"#FFD0D2C5\": \"Particular Mint\", \"#FF9DBBCD\": \"Partly Cloudy\", \"#FF844C44\": \"Partridge\", \"#FF919098\": \"Partridge Grey\", \"#FFA9875B\": \"Partridge Knoll\", \"#FFCAC1E2\": \"Party Hat\", \"#FFE6E4DE\": \"Party Ice\", \"#FFEE99FF\": \"Party Pig\", \"#FFEEDF91\": \"Party Sponge Cake\", \"#FFE3A9C4\": \"Party Time\", \"#FFA84A49\": \"Pasadena Rose\", \"#FF929178\": \"Paseo Verde\", \"#FFC3B7A4\": \"Pasha Brown\", \"#FF44413B\": \"Pasilla Chiles\", \"#FFB9BD97\": \"Paspalum Grass\", \"#FF5D98B3\": \"Pass Time Blue\", \"#FF647B86\": \"Passageway\", \"#FFEED786\": \"Passementerie\", \"#FFCBCAC0\": \"Passing Shadow\", \"#FF6F5698\": \"Passion Flower\", \"#FFDD0D06\": \"Passion for Revenge\", \"#FF907895\": \"Passion Fruit\", \"#FFE8AA9D\": \"Passion Fruit Punch\", \"#FFE57681\": \"Passion Pink\", \"#FFE398AF\": \"Passion Potion\", \"#FF59355E\": \"Passion Razz\", \"#FF725062\": \"Passionate\", \"#FF1F3465\": \"Passionate Blue\", \"#FF334159\": \"Passionate Blueberry\", \"#FFEDEFCB\": \"Passionate Pause\", \"#FFDD00CC\": \"Passionate Pink\", \"#FF753A58\": \"Passionate Plum\", \"#FF882299\": \"Passionate Purple\", \"#FF513E49\": \"Passionfruit Mauve\", \"#FFCBCCC9\": \"Passive\", \"#FFDBA29E\": \"Passive Pink\", \"#FF795365\": \"Passive Royal\", \"#FFF7DFAF\": \"Pasta\", \"#FFFAE17F\": \"Pasta Luego\", \"#FFEEC474\": \"Pasta Rasta\", \"#FFA2BFFE\": \"Pastel Blue Variant\", \"#FFF0E4E0\": \"Pastel China\", \"#FFDFD8E1\": \"Pastel Day\", \"#FFF2C975\": \"Pastel de Nata\", \"#FFBCCBB9\": \"Pastel Grey Green\", \"#FFD2F0E0\": \"Pastel Jade\", \"#FFD8A1C4\": \"Pastel Lavender\", \"#FFBDB0D0\": \"Pastel Lilac\", \"#FFB9D786\": \"Pastel Lime\", \"#FFA9C9AF\": \"Pastel Meadow\", \"#FFCEF0CC\": \"Pastel Mint\", \"#FFADD0B3\": \"Pastel Mint Green\", \"#FFFFF5D9\": \"Pastel Moon Creme\", \"#FFFF964F\": \"Pastel Orange Variant\", \"#FFDBCCC3\": \"Pastel Parchment\", \"#FFBEE7A5\": \"Pastel Pea\", \"#FFF1CAAD\": \"Pastel Peach\", \"#FFE4C5B0\": \"Pastel Rose Tan\", \"#FFD5C6B4\": \"Pastel Sand\", \"#FFDEECE1\": \"Pastel Smirk\", \"#FFEF4F4C\": \"Pastel Strawberry\", \"#FF99C5C4\": \"Pastel Turquoise\", \"#FFEDFAD9\": \"Pastoral\", \"#FFE87175\": \"Pastrami\", \"#FFF8DEB8\": \"Pastry\", \"#FFFAEDD5\": \"Pastry Dough\", \"#FFF8E1D0\": \"Pastry Pink\", \"#FFB77D58\": \"Pastry Shell\", \"#FF506351\": \"Pasture Green\", \"#FF3887BD\": \"Pat-A-Pep\", \"#FF225511\": \"Patch of Land\", \"#FF8A7D6B\": \"Patches\", \"#FFC4A89E\": \"Patchwork Pink\", \"#FF7E696A\": \"Patchwork Plum\", \"#FFC7C7C6\": \"Paternoster\", \"#FFC4EEE8\": \"Path\", \"#FFDBD6D2\": \"Pathway\", \"#FFE6DDD6\": \"Patience\", \"#FFFFABA5\": \"Patient Pink\", \"#FFEDE2DE\": \"Patient White\", \"#FF66D0C0\": \"Patina Variant\", \"#FFB6C4BD\": \"Patina Creek\", \"#FFB6C0BC\": \"Patina Grey\", \"#FF83BAA8\": \"Patina Hue\", \"#FF695A67\": \"Patina Violet\", \"#FF3F5A50\": \"Patio Green\", \"#FF6B655B\": \"Patio Stone\", \"#FFEDDBC8\": \"Patisserie\", \"#FF800070\": \"Patriarch Variant\", \"#FF8CD9A1\": \"Patrice\", \"#FF72527F\": \"Patrician Purple\", \"#FFD9B611\": \"Patrinia Flowers\", \"#FFF2F2B0\": \"Patrinia Scabiosaefolia\", \"#FF3C3C5F\": \"Patriot Blue\", \"#FFD3E5EF\": \"Pattens Blue Variant\", \"#FFBCC6B1\": \"Pattipan\", \"#FFEDB80F\": \"Pattypan\", \"#FF2A2551\": \"P\\u0101ua\", \"#FF245056\": \"P\\u0101ua Shell\", \"#FF80A4CD\": \"Paula Loves Paris\", \"#FF629191\": \"Pauley\", \"#FF343445\": \"Pauper\", \"#FF828782\": \"Paved Path\", \"#FFE8D284\": \"Paved With Gold\", \"#FF554F53\": \"Pavement\", \"#FFC9C4BA\": \"Pavestone\", \"#FFBEBF84\": \"Pavilion\", \"#FFC5B6A4\": \"Pavilion Beige\", \"#FFDF9C45\": \"Pavilion Peach\", \"#FFEDE4D4\": \"Pavillion\", \"#FFCBCCC4\": \"Paving Stones\", \"#FFBAAB87\": \"Pavlova Variant\", \"#FFFBD49C\": \"Paw Paw\", \"#FF827A6D\": \"Paw Print\", \"#FF473430\": \"Pawn Broker\", \"#FFC8C6DA\": \"Pax\", \"#FF70916C\": \"Paying Mantis\", \"#FF002D04\": \"PCB Green\", \"#FFA4BF20\": \"Pea\", \"#FF7C9865\": \"Pea Aubergine\", \"#FF929901\": \"Pea Soup\", \"#FF3F7074\": \"Peabody\", \"#FFA2B2BD\": \"Peace\", \"#FFE0DAC8\": \"Peace & Quiet\", \"#FFC1875F\": \"Peace of Mind\", \"#FFA8BFCC\": \"Peace River\", \"#FFEECF9E\": \"Peace Yellow\", \"#FFDDCCAC\": \"Peaceable Kingdom\", \"#FF9AB6C0\": \"Peaceful Blue\", \"#FF878E83\": \"Peaceful Glade\", \"#FFD6E7E3\": \"Peaceful Night\", \"#FF94D8AC\": \"Peaceful Pastures\", \"#FF579797\": \"Peaceful Pond\", \"#FF660088\": \"Peaceful Purple\", \"#FFF1FBF1\": \"Peaceful Rain\", \"#FF47A0D2\": \"Peaceful River\", \"#FFFFB07C\": \"Peach Variant\", \"#FFFB9F93\": \"Peach Amber\", \"#FFFFCCB6\": \"Peach and Quiet\", \"#FFEFC4BB\": \"Peach Ash\", \"#FFFDCFA1\": \"Peach Beach\", \"#FFE7C3AB\": \"Peach Beauty\", \"#FFCD9489\": \"Peach Beige\", \"#FFFEDCAD\": \"Peach Bellini\", \"#FFD89A78\": \"Peach Bloom\", \"#FFDC7A83\": \"Peach Blossom\", \"#FFEECFBF\": \"Peach Blossom Red\", \"#FFDCBEB5\": \"Peach Blush\", \"#FFFFECE5\": \"Peach Breeze\", \"#FFE5CCBD\": \"Peach Brick\", \"#FFFDB2AB\": \"Peach Bud\", \"#FFCC99BB\": \"Peach Buff\", \"#FFF39998\": \"Peach Burst\", \"#FFFFAC3A\": \"Peach Butter\", \"#FFC56A3D\": \"Peach Caramel\", \"#FFFFD9AA\": \"Peach Cider\", \"#FFFCE2D8\": \"Peach Cloud\", \"#FFFFA167\": \"Peach Cobbler\", \"#FFFFCBA7\": \"Peach Crayon\", \"#FFFFE19D\": \"Peach Cr\\u00e8me Br\\u00fbl\\u00e9e\", \"#FFF6C4A6\": \"Peach Damask\", \"#FFEFCDB4\": \"Peach Darling\", \"#FFF4DEBF\": \"Peach Dip\", \"#FFB3695F\": \"Peach Dunes\", \"#FFF0D8CC\": \"Peach Dust\", \"#FFF6725C\": \"Peach Echo\", \"#FFFEBC96\": \"Peach Encounter\", \"#FFF4E2D4\": \"Peach Everlasting\", \"#FFFCE9D6\": \"Peach Fade\", \"#FFFFA883\": \"Peach Fizz\", \"#FFE198B4\": \"Peach Flower\", \"#FFF88435\": \"Peach Fury\", \"#FFFFC7B9\": \"Peach Fuzz\", \"#FFEBD7D3\": \"Peach Glamour\", \"#FFFFDCAC\": \"Peach Glow\", \"#FFDFA479\": \"Peach Ice Cream\", \"#FFFFCFAB\": \"Peach Juice\", \"#FFFBE2CD\": \"Peach Kiss\", \"#FFE7C19F\": \"Peach Latte\", \"#FFC67464\": \"Peach Macaron\", \"#FFFBBDAF\": \"Peach Melba\", \"#FFF4A28C\": \"Peach Mimosa\", \"#FFFFAE96\": \"Peach Nectar\", \"#FFEDB48F\": \"Peach Nirvana\", \"#FFE3A385\": \"Peach Nougat\", \"#FFFFE2B4\": \"Peach of Mind\", \"#FFF6B895\": \"Peach Parfait\", \"#FFF3D5A1\": \"Peach Patch\", \"#FFFFB2A5\": \"Peach Pearl\", \"#FFD3B699\": \"Peach Petals\", \"#FFFF9A8A\": \"Peach Pink\", \"#FFDDAAAA\": \"Peach Poppy\", \"#FFE38372\": \"Peach Posey\", \"#FFE2BDB3\": \"Peach Powder\", \"#FFD29487\": \"Peach Preserve\", \"#FFF59997\": \"Peach Punch\", \"#FFEED0B6\": \"Peach Pur\\u00e9e\", \"#FFF4B087\": \"Peach Quartz\", \"#FFF9CDC4\": \"Peach Red\", \"#FFF6E3D5\": \"Peach Rose\", \"#FFF6D9C9\": \"Peach Sachet\", \"#FFFFBCBC\": \"Peach Scone\", \"#FFF3DFD4\": \"Peach Shortcake\", \"#FFFFE5BD\": \"Peach Smoothie\", \"#FFECBCB2\": \"Peach Souffle\", \"#FFEC9D75\": \"Peach Squared\", \"#FFF3E3D1\": \"Peach Surprise\", \"#FFF3B68E\": \"Peach Taffy\", \"#FFFFB559\": \"Peach Tea\", \"#FFF2C5B2\": \"Peach Temptation\", \"#FFFFDC8D\": \"Peach Tickle\", \"#FFEFA498\": \"Peach Tile\", \"#FFF2E3DC\": \"Peach Tone\", \"#FFF9E8CE\": \"Peach Umbrella\", \"#FFF7B28B\": \"Peach Velour\", \"#FFD8B6B0\": \"Peach Whip\", \"#FFF9BAB5\": \"Peach Whisper\", \"#FFFD9B88\": \"Peach\\u2019s Daydream\", \"#FFFADFC7\": \"Peachade\", \"#FFFFA361\": \"Peaches \\u00e0 la Cr\\u00e8me\", \"#FFD98586\": \"Peaches of Immortality\", \"#FFEEC9A6\": \"Peaches\\u2019n\\u2019Cream\", \"#FFDDB3B2\": \"Peachskin\", \"#FFF3DDCD\": \"Peachtree\", \"#FFFFA67A\": \"Peachy\", \"#FFFFD2B9\": \"Peachy Bon-Bon\", \"#FFFFC996\": \"Peachy Breezes\", \"#FFD4A88D\": \"Peachy Confection\", \"#FFFDE0DC\": \"Peachy Ethereal\", \"#FFED8666\": \"Peachy Feeling\", \"#FFFFDEDA\": \"Peachy Keen\", \"#FFE8956B\": \"Peachy Maroney\", \"#FFF3E0D8\": \"Peachy Milk\", \"#FFFFCCAA\": \"Peachy Pico\", \"#FFFF775E\": \"Peachy Pinky\", \"#FFFF9B80\": \"Peachy Salmon\", \"#FFFFDCB7\": \"Peachy Sand\", \"#FFDD7755\": \"Peachy Scene\", \"#FFF0CFA0\": \"Peachy Skin\", \"#FFFFD9A8\": \"Peachy Summer Skies\", \"#FFE3A381\": \"Peachy Tint\", \"#FFF1BF92\": \"Peachy-Kini\", \"#FF2D3146\": \"Peacoat\", \"#FF016795\": \"Peacock Blue\", \"#FF12939A\": \"Peacock Feather\", \"#FF006A50\": \"Peacock Green\", \"#FF2E4B44\": \"Peacock House\", \"#FF206D71\": \"Peacock Plume\", \"#FF006663\": \"Peacock Pride\", \"#FF513843\": \"Peacock Purple\", \"#FF6DA893\": \"Peacock Silk\", \"#FF01636D\": \"Peacock Tail\", \"#FF719E8A\": \"Peahen\", \"#FF768083\": \"Peak Point\", \"#FFFFDFC9\": \"Peak Season\", \"#FF7A4434\": \"Peanut Variant\", \"#FFA6893A\": \"Peanut Brittle\", \"#FFBE893F\": \"Peanut Butter\", \"#FFF7B565\": \"Peanut Butter Biscuit\", \"#FFFFB75F\": \"Peanut Butter Chicken\", \"#FFC8A38A\": \"Peanut Butter Crust\", \"#FFCE4A2D\": \"Peanut Butter Jelly\", \"#FF82B185\": \"Peapod\", \"#FF91AF88\": \"Pear Cactus\", \"#FFCCDD99\": \"Pear Perfume\", \"#FFF3EAC3\": \"Pear Sorbet\", \"#FFCBF85F\": \"Pear Spritz\", \"#FFE3DE92\": \"Pear Tint\", \"#FFEAE0C8\": \"Pearl\", \"#FF88D8C0\": \"Pearl Aqua\", \"#FFD0C9C3\": \"Pearl Ash\", \"#FF7FC6CC\": \"Pearl Bay\", \"#FF76727F\": \"Pearl Blackberry\", \"#FFF4CEC5\": \"Pearl Blush\", \"#FFE6E6E3\": \"Pearl Brite\", \"#FFDED1C6\": \"Pearl Bush Variant\", \"#FFDCE4E9\": \"Pearl City\", \"#FFF0EBE4\": \"Pearl Drops\", \"#FFEFE5D9\": \"Pearl Dust\", \"#FF377B70\": \"Pearl Green\", \"#FFEAE1C8\": \"Pearl Lusta Variant\", \"#FFFCF7EB\": \"Pearl Necklace\", \"#FFEEEFE1\": \"Pearl Onion\", \"#FFDDD6CB\": \"Pearl Oyster\", \"#FFDED7DA\": \"Pearl Pebble\", \"#FFFAFFED\": \"Pearl Powder\", \"#FFDFD3D4\": \"Pearl Rose\", \"#FFF4F1EB\": \"Pearl Sugar\", \"#FFE6E0E3\": \"Pearl Violet\", \"#FFF3F2ED\": \"Pearl White\", \"#FFF1E3BC\": \"Pearl Yellow\", \"#FFF2E9D5\": \"Pearled Couscous\", \"#FFF0DFCC\": \"Pearled Ivory\", \"#FFDCD0CB\": \"Pearls & Lace\", \"#FFF4E3DF\": \"Pearly\", \"#FFE8E6DE\": \"Pearly Gates\", \"#FFCEDBD5\": \"Pearly Jade\", \"#FFEE99CC\": \"Pearly Pink\", \"#FFDBD3BD\": \"Pearly Putty\", \"#FFE4E4DA\": \"Pearly Star\", \"#FFEEE9D8\": \"Pearly Swirly\", \"#FFFEEFD3\": \"Pearly White\", \"#FF8C7F3C\": \"Peas Please\", \"#FFDDC7A8\": \"Peasant Bread\", \"#FFC1EFC6\": \"Peasful Mint\", \"#FF8CAA95\": \"Peaslake\", \"#FF766D52\": \"Peat Variant\", \"#FF5A3D29\": \"Peat Brown\", \"#FF4A352B\": \"Peat Moss\", \"#FF6C5755\": \"Peat Red Brown\", \"#FF988C75\": \"Peat Swamp Forest\", \"#FF552211\": \"Peaty Brown\", \"#FF9D9880\": \"Pebble\", \"#FFDED8DC\": \"Pebble Beach\", \"#FFF3E1CA\": \"Pebble Cream\", \"#FFD5BC94\": \"Pebble Path\", \"#FFD3D7DC\": \"Pebble Soft Blue White\", \"#FFE0D9DA\": \"Pebble Stone\", \"#FFAFB2A7\": \"Pebble Walk\", \"#FFD8D0BC\": \"Pebblebrook\", \"#FFDECAB9\": \"Pebbled Courtyard\", \"#FFA0968D\": \"Pebbled Path\", \"#FFDBD5CA\": \"Pebbled Shore\", \"#FFA67253\": \"Pecan\", \"#FFF7DBA6\": \"Pecan Cream\", \"#FFF4DECB\": \"Pecan Sandie\", \"#FFE09F78\": \"Pecan Veneer\", \"#FFFDDCB7\": \"P\\u00eache\", \"#FFE1A080\": \"Pecos Spice\", \"#FFC5AF91\": \"Peculiarly Drab Tincture\", \"#FF00BB22\": \"Pedestrian Green\", \"#FFF7F72D\": \"Pedestrian Lemon\", \"#FFCC1122\": \"Pedestrian Red\", \"#FF31646E\": \"Pedigree\", \"#FF8F8E8C\": \"Pedigrey\", \"#FFD3CCC4\": \"Pediment\", \"#FFC5E1E1\": \"Peek-a-Blue\", \"#FF0173BB\": \"Peek-A-Boo Blue\", \"#FFE6DEE6\": \"Peekaboo\", \"#FF87A96B\": \"Peeled Asparagus\", \"#FFFFCF38\": \"Peeps\", \"#FFFF2266\": \"Peevish Red\", \"#FFE8E9E4\": \"Pegasus\", \"#FFEA9FB4\": \"Pegeen Peony\", \"#FFF5D2AC\": \"Pekin Chicken\", \"#FF355D83\": \"Pelagic\", \"#FFFF3333\": \"Pelati\", \"#FFC1BCAC\": \"Pelican\", \"#FF9EACB1\": \"Pelican Bay\", \"#FFD7C0C7\": \"Pelican Bill\", \"#FFE8C3C2\": \"Pelican Feather\", \"#FFFB9A30\": \"Pelican Pecker\", \"#FFE2A695\": \"Pelican Pink\", \"#FFC8A481\": \"Pelican Tan\", \"#FF2599B2\": \"Pelorus\", \"#FFDBB7BB\": \"Pencil Eraser\", \"#FF5C6274\": \"Pencil Lead\", \"#FFFD9F01\": \"Pencil Me In\", \"#FF595D61\": \"Pencil Point\", \"#FF999D9E\": \"Pencil Sketch\", \"#FF7B8267\": \"Pendula Garden\", \"#FFE3E3EB\": \"Penelope\", \"#FF9D6984\": \"Penelope Pink\", \"#FF37799C\": \"Peninsula\", \"#FFB9C8E0\": \"Penna\", \"#FFA97F5A\": \"Penny\", \"#FFA2583A\": \"Pennywise\", \"#FFC2C1CB\": \"Pensive\", \"#FFEAB6AD\": \"Pensive Pink\", \"#FF96CCD1\": \"Pentagon\", \"#FFDBB2BC\": \"Pentalon\", \"#FFCABFB3\": \"Penthouse View\", \"#FF627E75\": \"Penzance\", \"#FFEB8F9D\": \"Peony\", \"#FFD8C1BE\": \"Peony Blush\", \"#FF9F86B7\": \"Peony Mauve\", \"#FFFADDD4\": \"Peony Prize\", \"#FFB75754\": \"Pepper & Spice\", \"#FFCC2244\": \"Pepper Jelly\", \"#FF777568\": \"Pepper Mill\", \"#FF8E7059\": \"Pepper Spice\", \"#FF7E9242\": \"Pepper Sprout\", \"#FFC79D9B\": \"Pepperberry\", \"#FF725C5B\": \"Peppercorn\", \"#FF4F4337\": \"Peppercorn Rent\", \"#FF807548\": \"Peppered Moss\", \"#FF957D6F\": \"Peppered Pecan\", \"#FF767461\": \"Peppergrass\", \"#FFD7E7D0\": \"Peppermint Variant\", \"#FF81BCA8\": \"Peppermint Bar\", \"#FF64BE9F\": \"Peppermint Fresh\", \"#FFB8FFEB\": \"Peppermint Frosting\", \"#FFD1E6D5\": \"Peppermint Patty\", \"#FFAAC7C1\": \"Peppermint Pie\", \"#FF90CBAA\": \"Peppermint Spray\", \"#FFE8B9BE\": \"Peppermint Stick\", \"#FFD35D7D\": \"Peppermint Swirl\", \"#FF009933\": \"Peppermint Toad\", \"#FF96CED5\": \"Peppermint Twist\", \"#FFD8C553\": \"Pepperoncini\", \"#FFAA4400\": \"Pepperoni\", \"#FF5B5752\": \"Peppery\", \"#FF72D7B7\": \"Peppy\", \"#FF55CCBB\": \"Peppy Peacock\", \"#FFFFFF44\": \"Peppy Pineapple\", \"#FFA3CE27\": \"P\\u00eara Rocha\", \"#FFACB9E8\": \"Perano Variant\", \"#FFF0E8DD\": \"Percale\", \"#FFC1ADA9\": \"Perdu Pink\", \"#FFBC9B08\": \"Perennial\", \"#FF87A56F\": \"Perennial Garden\", \"#FFE6A7AC\": \"Perennial Phlox\", \"#FFCFC2B3\": \"Perfect Backdrop\", \"#FFD6CDBB\": \"Perfect Crust\", \"#FF313390\": \"Perfect Dark\", \"#FF49A0E7\": \"Perfect Days\", \"#FFB7AB9F\": \"Perfect Greige\", \"#FFB2A492\": \"Perfect Khaki\", \"#FF9EB2C3\": \"Perfect Landing\", \"#FF3062A0\": \"Perfect Ocean\", \"#FFE9E8BB\": \"Perfect Pear\", \"#FFA06A56\": \"Perfect Penny\", \"#FF6487B0\": \"Perfect Periwinkle\", \"#FFE5B3B2\": \"Perfect Pink\", \"#FFB72356\": \"Perfect Pout\", \"#FF4596CF\": \"Perfect Sky\", \"#FFF2EDD7\": \"Perfect Solution\", \"#FF9598A1\": \"Perfect Storm\", \"#FFCBAC88\": \"Perfect Tan\", \"#FFB6ACA0\": \"Perfect Taupe\", \"#FFF0EEEE\": \"Perfect White\", \"#FFD9D6E5\": \"Perfection\", \"#FF97D0E5\": \"Perfectly Blue\", \"#FF694878\": \"Perfectly Purple\", \"#FFCC22AA\": \"Perfectly Purple Place\", \"#FFC2A9DB\": \"Perfume Variant\", \"#FFE2C9CE\": \"Perfume Cloud\", \"#FFF3E9F7\": \"Perfume Haze\", \"#FFBFA58A\": \"Pergament\", \"#FFE4E0DC\": \"Pergament Shreds\", \"#FFE1E9DB\": \"Pergola Panorama\", \"#FFC62D2C\": \"Peri Peri\", \"#FFB6BDD3\": \"Peri Wink\", \"#FF904FEF\": \"Pericallis Hybrida\", \"#FFACB6B2\": \"Periglacial Blue Variant\", \"#FF524A46\": \"P\\u00e9rigord Truffle\", \"#FFEF8B38\": \"Peril\\u2019s Flames\", \"#FF52677B\": \"Periscope\", \"#FFAE905E\": \"Peristyle Brass\", \"#FF8E82FE\": \"Periwinkle Variant\", \"#FF8B9AB9\": \"Periwinkle Blossom\", \"#FF8F99FB\": \"Periwinkle Blue\", \"#FFB4C4DE\": \"Periwinkle Bud\", \"#FFB8CBE5\": \"Periwinkle Dream\", \"#FF8D9DB3\": \"Periwinkle Dusk\", \"#FF8CB7D7\": \"Periwinkle Sky\", \"#FFD3DDD6\": \"Periwinkle Tint\", \"#FFD6C7BE\": \"Perk Up\", \"#FF733C8E\": \"Perkin Mauve\", \"#FF408E7C\": \"Perky\", \"#FFFBF4D3\": \"Perky Tint\", \"#FFF2CA83\": \"Perky Yellow\", \"#FF4F4D51\": \"Perle Noir\", \"#FF98EFF9\": \"Permafrost\", \"#FF005437\": \"Permanent Green\", \"#FF584D75\": \"Perpetual Purple\", \"#FFBDB3C3\": \"Perplexed\", \"#FFDDAA99\": \"Perrigloss Tan\", \"#FF8F8CE7\": \"Perrywinkle\", \"#FFACB3C7\": \"Perseverance\", \"#FFC5988C\": \"Persian Bazaar\", \"#FF99AC4B\": \"Persian Belt\", \"#FFE3E1CC\": \"Persian Blinds\", \"#FFEFCADA\": \"Persian Delight\", \"#FFD4EBDD\": \"Persian Fable\", \"#FFE1C7A8\": \"Persian Flatbread\", \"#FF9B7939\": \"Persian Gold\", \"#FF6A7DBC\": \"Persian Jewel\", \"#FF990077\": \"Persian Luxury Purple\", \"#FFFFDCBF\": \"Persian Melon\", \"#FF206874\": \"Persian Mosaic\", \"#FFAA9499\": \"Persian Pastel\", \"#FF575B93\": \"Persian Plush\", \"#FF38343E\": \"Persian Prince\", \"#FF8C8EB2\": \"Persian Violet\", \"#FFFFB49B\": \"Persicus\", \"#FFE59B34\": \"Persimmon Tint\", \"#FFF7BD8F\": \"Persimmon Fade\", \"#FF934337\": \"Persimmon Juice\", \"#FFF47327\": \"Persimmon Orange\", \"#FFA74E4A\": \"Persimmon Red\", \"#FF9F563A\": \"Persimmon Varnish\", \"#FFCEBEDA\": \"Perspective\", \"#FFC4AE96\": \"Persuasion\", \"#FFCD853F\": \"Peru\", \"#FFCD7DB5\": \"Peruvian Lily\", \"#FF733D1F\": \"Peruvian Soil\", \"#FF7B7284\": \"Peruvian Violet\", \"#FF0099EE\": \"Pervenche\", \"#FF119922\": \"Pestering Pesto\", \"#FF9F8303\": \"Pestilence\", \"#FFC1B23E\": \"Pesto Variant\", \"#FF558800\": \"Pesto Alla Genovese\", \"#FFF49325\": \"Pesto Calabrese\", \"#FFB09D64\": \"Pesto di Noce\", \"#FFA7C437\": \"Pesto di Pistacchio\", \"#FF748A35\": \"Pesto di Rucola\", \"#FF9DC249\": \"Pesto Genovese\", \"#FF817553\": \"Pesto Green\", \"#FF898C66\": \"Pesto Paste\", \"#FFBB3333\": \"Pesto Rosso\", \"#FFAA9933\": \"Pestulance\", \"#FFF7D5DA\": \"Petal Bloom\", \"#FFF4DFCD\": \"Petal Dust\", \"#FF9F0630\": \"Petal of a Dying Rose\", \"#FFF4E5E0\": \"Petal Pink\", \"#FFDDAAEE\": \"Petal Plush\", \"#FFF8E3EE\": \"Petal Poise\", \"#FFF5A5B8\": \"Petal Power\", \"#FF53465D\": \"Petal Purple\", \"#FFE2DCD3\": \"Petal Smoke\", \"#FFFCD1BF\": \"Petal Soft\", \"#FFD9D9DF\": \"Petal Tip\", \"#FFF3BBC0\": \"Petals Unfolding\", \"#FF19A700\": \"Peter Pan\", \"#FF7FBAD1\": \"Petit Four\", \"#FFE9CDD8\": \"Petit Pink\", \"#FFDA9790\": \"Petite Orchid Variant\", \"#FFEACACB\": \"Petite Pink\", \"#FFCFBBD8\": \"Petite Purple\", \"#FF4076B4\": \"Petrel\", \"#FFA0AEBC\": \"Petrel Blue Grey\", \"#FF66CCCC\": \"Petrichor\", \"#FF9B846C\": \"Petrified Oak\", \"#FF9C87C1\": \"Petrified Purple\", \"#FF2F5961\": \"Petro Blue\", \"#FF005F6A\": \"Petrol\", \"#FF549B8C\": \"Petrol Green\", \"#FF243640\": \"Petrol Slumber\", \"#FF21211D\": \"Petroleum\", \"#FFFECDAC\": \"Petticoat\", \"#FF228822\": \"Pettifers\", \"#FF88806A\": \"Pettingill Sage\", \"#FFFFBAB0\": \"Petula\", \"#FF4D3466\": \"Petunia Variant\", \"#FF4B3C4B\": \"Petunia Patty\", \"#FFB8B0CF\": \"Petunia Trail\", \"#FF91A092\": \"Pewter Variant\", \"#FF9B9893\": \"Pewter Cast\", \"#FF5E6259\": \"Pewter Green\", \"#FFA7A19E\": \"Pewter Grey\", \"#FF8B8283\": \"Pewter Mug\", \"#FFBAB4A6\": \"Pewter Patter\", \"#FF8A8886\": \"Pewter Ring\", \"#FFA39B90\": \"Pewter Tankard\", \"#FFBDC5C0\": \"Pewter Tray\", \"#FFCECECB\": \"Pewter Vase\", \"#FFC5BBAE\": \"Peyote\", \"#FF5984A8\": \"Peyton\", \"#FFD03B52\": \"Pezzottaite\", \"#FF6E797B\": \"Phantom\", \"#FFD6E0D1\": \"Phantom Green\", \"#FF645D5E\": \"Phantom Hue\", \"#FF4B4441\": \"Phantom Mist\", \"#FF2F3434\": \"Phantom Ship\", \"#FF636285\": \"Pharaoh Purple\", \"#FF007367\": \"Pharaoh\\u2019s Gem\", \"#FFEAD765\": \"Pharaoh\\u2019s Gold\", \"#FF83D1A9\": \"Pharaoh\\u2019s Jade\", \"#FF59BBC2\": \"Pharaoh\\u2019s Seas\", \"#FF826663\": \"Pharlap Variant\", \"#FF087E34\": \"Pharmaceutical Green\", \"#FF005500\": \"Pharmacy Green\", \"#FFC17C54\": \"Pheasant\", \"#FF795435\": \"Pheasant Brown\", \"#FFE0DCD7\": \"Pheasant\\u2019s Egg\", \"#FFF3C13A\": \"Phellodendron Amurense\", \"#FFC4BDAD\": \"Phelps Putty\", \"#FFFFCBA2\": \"Phenomenal Peach\", \"#FFEE55FF\": \"Phenomenal Pink\", \"#FF3E729B\": \"Phenomenon\", \"#FF8822BB\": \"Pheromone Purple\", \"#FFE2D9DD\": \"Philanthropist Pink\", \"#FF0038A7\": \"Philippine Blue\", \"#FF6E3A07\": \"Philippine Bronze\", \"#FF5D1916\": \"Philippine Brown\", \"#FFB17304\": \"Philippine Gold\", \"#FFEEBB00\": \"Philippine Golden Yellow\", \"#FF008543\": \"Philippine Green\", \"#FFFF7300\": \"Philippine Orange\", \"#FFFA1A8E\": \"Philippine Pink\", \"#FFCE1127\": \"Philippine Red\", \"#FF81007F\": \"Philippine Violet\", \"#FFFECB00\": \"Philippine Yellow\", \"#FF008F80\": \"Philips Green\", \"#FF116356\": \"Philodendron\", \"#FF757B7D\": \"Philosophical\", \"#FF4D483D\": \"Philosophically Speaking\", \"#FF7F4F78\": \"Phlox Flower Violet\", \"#FFCE5E9A\": \"Phlox Pink\", \"#FFFAA21A\": \"Phoenix Flames\", \"#FFF8D99E\": \"Phoenix Fossil\", \"#FFD2813A\": \"Phoenix Rising\", \"#FF99B1A2\": \"Phoenix Tears\", \"#FFF7EFDE\": \"Phoenix Villa\", \"#FF00AA00\": \"Phosphor Green\", \"#FF11EEEE\": \"Phosphorescent Blue\", \"#FF11FF00\": \"Phosphorescent Green\", \"#FFA5D0C6\": \"Phosphorus\", \"#FFAEAD96\": \"Photo Grey\", \"#FF88DDEE\": \"Photon Barrier\", \"#FF88EEFF\": \"Photon Projector\", \"#FFF8F8E8\": \"Photon White\", \"#FF8892BF\": \"PHP Purple\", \"#FF0480BD\": \"Phuket Palette\", \"#FFEF9548\": \"Physalis\", \"#FFEBE1D4\": \"Physalis Aquarelle\", \"#FFE1D8BB\": \"Physalis Peal\", \"#FF314159\": \"Pi\", \"#FFE6D0CA\": \"Pianissimo\", \"#FF17171A\": \"Piano Black\", \"#FF5C4C4A\": \"Piano Brown\", \"#FFCFC4C7\": \"Piano Grey Rose\", \"#FFEEE5D4\": \"Piano Keys\", \"#FF9E8996\": \"Piano Mauve\", \"#FF765C52\": \"Picador\", \"#FFA04933\": \"Picante\", \"#FFF8EA97\": \"Picasso Variant\", \"#FF634878\": \"Picasso Lily\", \"#FF625D5D\": \"Piccadilly Grey\", \"#FF51588E\": \"Piccadilly Purple\", \"#FF8BD2E2\": \"Piccolo\", \"#FF566955\": \"Picholine\", \"#FF958251\": \"Picholine Olive\", \"#FFB8A49B\": \"Pick of the Litter\", \"#FFF1919A\": \"Pick Your Brain\", \"#FFBFF128\": \"Pick Your Poison\", \"#FFF3F2EA\": \"Picket Fence\", \"#FFC9F0D1\": \"Pickford\", \"#FF85A16A\": \"Pickle\", \"#FFBBA528\": \"Pickle Juice\", \"#FFB3A74B\": \"Pickled\", \"#FF99BB11\": \"Pickled Avocado\", \"#FFAA0044\": \"Pickled Beets\", \"#FF695E4B\": \"Pickled Capers\", \"#FF94A135\": \"Pickled Cucumber\", \"#FFFFDD55\": \"Pickled Ginger\", \"#FF775500\": \"Pickled Grape Leaves\", \"#FFDDCC11\": \"Pickled Lemon\", \"#FFBBBB11\": \"Pickled Limes\", \"#FF887647\": \"Pickled Okra\", \"#FFDBB532\": \"Pickled Peppers\", \"#FFEEFF33\": \"Pickled Pineapple\", \"#FFDA467D\": \"Pickled Pink\", \"#FF8E4785\": \"Pickled Plum\", \"#FFDDBBAA\": \"Pickled Pork\", \"#FF8E7AA1\": \"Pickled Purple\", \"#FFEE1144\": \"Pickled Radish\", \"#FFFF6655\": \"Pickled Salmon\", \"#FFCFD2B5\": \"Pickling Spice\", \"#FF99C285\": \"Picnic\", \"#FFBCDBD4\": \"Picnic Bay\", \"#FF00CCEE\": \"Picnic Day Sky\", \"#FFAB5236\": \"Pico Earth\", \"#FF7E2553\": \"Pico Eggplant\", \"#FFFFF1E8\": \"Pico Ivory\", \"#FFC2C3C7\": \"Pico Metal\", \"#FFFFA300\": \"Pico Orange\", \"#FFFFEC27\": \"Pico Sun\", \"#FF1D2B53\": \"Pico Void\", \"#FFFF77A8\": \"Pico-8 Pink\", \"#FF5BA0D0\": \"Picton Blue Variant\", \"#FF00804C\": \"Picture Book Green\", \"#FFFBF2D1\": \"Picture Perfect\", \"#FFF1D99F\": \"Pie Crust\", \"#FF877A64\": \"Pie Safe\", \"#FFEDE7C8\": \"Piece of Cake\", \"#FFFFAF38\": \"Pieces of Eight\", \"#FFBEBDC2\": \"Pied Wagtail Grey\", \"#FFC2CEC5\": \"Piedmont\", \"#FFEAC185\": \"Piedra de Sol\", \"#FF88857D\": \"Pier\", \"#FF647D8E\": \"Pier 17 Steel\", \"#FFDD00EE\": \"Piercing Pink\", \"#FFDD1122\": \"Piercing Red\", \"#FF43232C\": \"Piermont Stone Red\", \"#FFF4D68C\": \"Pierogi\", \"#FFA1C8DB\": \"Piezo Blue\", \"#FF484848\": \"Pig Iron\", \"#FFA9AFAA\": \"Pigeon\", \"#FFC1B4A0\": \"Pigeon Grey\", \"#FF9D857F\": \"Pigeon Pink\", \"#FFFFCCBB\": \"Piggy Bank\", \"#FFFFCBC4\": \"Piggy Dreams\", \"#FFF0DCE3\": \"Piggyback\", \"#FFFFC0C6\": \"Piglet\", \"#FF4D0082\": \"Pigment Indigo Variant\", \"#FFF9E9D7\": \"Pignoli\", \"#FFE8DAD1\": \"Pigskin Puffball\", \"#FFEEE92D\": \"Pika Yellow\", \"#FFEEDE73\": \"Pikachu Chu\", \"#FF6C7779\": \"Pike Lake\", \"#FF15B01A\": \"Pikkoro Green\", \"#FFFFFF55\": \"P\\u012bl\\u0101 Yellow\", \"#FF006981\": \"Pilot Blue\", \"#FFF8F753\": \"Pilsener\", \"#FFCC2200\": \"Piment Piquant\", \"#FFDC5D47\": \"Pimento\", \"#FF6C5738\": \"Pimento Grain Brown\", \"#FFDF9E9D\": \"Pimlico\", \"#FFC3585C\": \"Pimm\\u2019s\", \"#FFFFD97A\": \"Pina\", \"#FFF4DEB3\": \"Pina Colada\", \"#FF7198C0\": \"Pinafore Blue\", \"#FFF4C701\": \"Pinard Yellow\", \"#FFC17A62\": \"Pinata\", \"#FFC88CA4\": \"Pinch Me\", \"#FFD2916B\": \"Pinch of Clove\", \"#FFFFF8E3\": \"Pinch of Pearl\", \"#FF0F180A\": \"Pinch of Pepper\", \"#FFDDDDCC\": \"Pinch of Pistachio\", \"#FFB4ABAF\": \"Pinch Purple\", \"#FFAC989C\": \"Pincushion\", \"#FFBB4411\": \"Pindjur Red\", \"#FF2B5D34\": \"Pine\", \"#FF887468\": \"Pine Bark\", \"#FF645345\": \"Pine Cone Variant\", \"#FF675850\": \"Pine Cone Brown\", \"#FF5C6456\": \"Pine Cone Pass\", \"#FFB7B8A5\": \"Pine Crush\", \"#FF415241\": \"Pine Forest\", \"#FFDEEAE0\": \"Pine Frost\", \"#FF797E65\": \"Pine Garland\", \"#FFBDC07E\": \"Pine Glade Variant\", \"#FFEBC79E\": \"Pine Grain\", \"#FF0A481E\": \"Pine Green Variant\", \"#FF273F39\": \"Pine Grove\", \"#FF486358\": \"Pine Haven\", \"#FF204242\": \"Pine Hollow\", \"#FFECDBD2\": \"Pine Hutch\", \"#FF839B5C\": \"Pine Leaves\", \"#FFD5D8BC\": \"Pine Mist\", \"#FF5C685E\": \"Pine Mountain\", \"#FF334D41\": \"Pine Needle\", \"#FFEADAC2\": \"Pine Nut\", \"#FF776F56\": \"Pine Peak\", \"#FF6D9185\": \"Pine Ridge\", \"#FF4A6D42\": \"Pine Scent\", \"#FF066F6C\": \"Pine Scented Lagoon\", \"#FFD5BFA5\": \"Pine Strain\", \"#FF9C9F75\": \"Pine Trail\", \"#FFE5E7D5\": \"Pine Water\", \"#FFB3C6B9\": \"Pine Whisper\", \"#FF786D72\": \"Pineal Pink\", \"#FF563C0D\": \"Pineapple\", \"#FFB4655C\": \"Pineapple Blossom\", \"#FFEDBB6E\": \"Pineapple Cake\", \"#FFF2EAC3\": \"Pineapple Cream\", \"#FFEDDA8F\": \"Pineapple Crush\", \"#FFF0E7A9\": \"Pineapple Delight\", \"#FFF9F0D6\": \"Pineapple Fizz\", \"#FFFFC72C\": \"Pineapple Gold\", \"#FFEBEB57\": \"Pineapple High\", \"#FFF8E87B\": \"Pineapple Juice\", \"#FFEEEE88\": \"Pineapple Perfume\", \"#FF9C8F60\": \"Pineapple Sage\", \"#FFFD645F\": \"Pineapple Salmon\", \"#FFE7D791\": \"Pineapple Slice\", \"#FFE4E5CE\": \"Pineapple Soda\", \"#FFF7F4DA\": \"Pineapple Sorbet\", \"#FFEAD988\": \"Pineapple Whip\", \"#FFDBBC6C\": \"Pineapple Wine\", \"#FFF0D6DD\": \"Pineberry\", \"#FF2B7B66\": \"Pinehurst\", \"#FF57593F\": \"Pinetop\", \"#FF5B7349\": \"Pineweed\", \"#FF006655\": \"Piney Lake\", \"#FF70574F\": \"Piney Wood\", \"#FF23C48B\": \"P\\u00edng G\\u01d4o L\\u01dc Green\", \"#FFE9B8A4\": \"Pink Abalone\", \"#FFF4E2E9\": \"Pink Amour\", \"#FFFFC3C6\": \"Pink and Sleek\", \"#FFD7B8AB\": \"Pink Apatite\", \"#FFFFB2F0\": \"Pink Apotheosis\", \"#FFFE69B5\": \"Pink as Hell\", \"#FFA6427C\": \"Pink Ballad\", \"#FFF9D1CF\": \"Pink Bangles\", \"#FFF6C3A6\": \"Pink Beach\", \"#FFDCA7C2\": \"Pink Beauty\", \"#FFDD9CBD\": \"Pink Begonia\", \"#FFF2A9BA\": \"Pink Blessing\", \"#FFE3ABCE\": \"Pink Bliss\", \"#FFFBE9DD\": \"Pink Blossom\", \"#FFF4ACB6\": \"Pink Blush\", \"#FFDD77EE\": \"Pink Bonnet\", \"#FFEFE1E4\": \"Pink Booties\", \"#FFC5B5C3\": \"Pink Bravado\", \"#FFFDBAC4\": \"Pink Bubble Tea\", \"#FFECC9CA\": \"Pink Cardoon\", \"#FFED7A9E\": \"Pink Carnation\", \"#FFECBAB3\": \"Pink Cashmere\", \"#FFFFB2D0\": \"Pink Cattleya\", \"#FFF4DED9\": \"Pink Chablis\", \"#FFF2A3BD\": \"Pink Chalk\", \"#FFE8DFED\": \"Pink Champagne\", \"#FFDBC8C3\": \"Pink Chantilly\", \"#FFDD66BB\": \"Pink Charge\", \"#FFE4898A\": \"Pink Chi\", \"#FFEFBECF\": \"Pink Chintz\", \"#FFFFD5D1\": \"Pink Clay\", \"#FFD99294\": \"Pink Clay Pot\", \"#FFF5D1C8\": \"Pink Cloud\", \"#FFE9B7AC\": \"Pink Cocoa\", \"#FFD1A5A6\": \"Pink Cocoa Cupcake\", \"#FFFF99DD\": \"Pink Condition\", \"#FFF5D0D6\": \"Pink Cupcake\", \"#FFFED5E9\": \"Pink Currant\", \"#FFB94C66\": \"Pink Dahlia\", \"#FFD98580\": \"Pink Damask\", \"#FFC97376\": \"Pink Dazzle\", \"#FFFF8AD8\": \"Pink Delight\", \"#FFF5BFD1\": \"Pink Destiny\", \"#FFFED0FC\": \"Pink Diamond\", \"#FFFFF4F2\": \"Pink Diminishing\", \"#FFB499A1\": \"Pink Discord\", \"#FFF7D1D1\": \"Pink Dogwood\", \"#FFFEA5A2\": \"Pink Dream\", \"#FFE9B8DE\": \"Pink Drink\", \"#FFF8E7E4\": \"Pink Duet\", \"#FFE4B5B2\": \"Pink Dust\", \"#FFECDFD5\": \"Pink Dyed Blond\", \"#FFB08272\": \"Pink Earth\", \"#FFFF99EE\": \"Pink Elephants\", \"#FFF2E4E2\": \"Pink Emulsion\", \"#FFF3A09A\": \"Pink Eraser\", \"#FFF56F88\": \"Pink Explosion\", \"#FFDD77FF\": \"Pink Fetish\", \"#FFCC55FF\": \"Pink Fever\", \"#FFFC845D\": \"Pink Fire\", \"#FFF5A8B2\": \"Pink Fit\", \"#FFCD4E82\": \"Pink Flamb\\u00e9\", \"#FFB55A63\": \"Pink Flame\", \"#FFD8B4B6\": \"Pink Flare Variant\", \"#FFEB9A9D\": \"Pink Floyd\", \"#FFFBD3D9\": \"Pink Fluorite\", \"#FFF5A9BE\": \"Pink Flutter\", \"#FFE6D2DC\": \"Pink Frapp\\u00e9\", \"#FFEDB0C7\": \"Pink Frenzy\", \"#FFF7D7E2\": \"Pink Frosting\", \"#FFD2738F\": \"Pink Garnet\", \"#FFE6B5D7\": \"Pink Gems\", \"#FFF6909D\": \"Pink Geranium\", \"#FFDFA3BA\": \"Pink Gin\", \"#FFCFA798\": \"Pink Ginger\", \"#FFFF1DCD\": \"Pink Glamour\", \"#FFFDDFDA\": \"Pink Glitter\", \"#FFFFECE0\": \"Pink Glow\", \"#FFBD9E97\": \"Pink Granite\", \"#FFF3BAC9\": \"Pink Grapefruit\", \"#FFF2BDDF\": \"Pink Heath\", \"#FFB36C86\": \"Pink Hibiscus\", \"#FF90305D\": \"Pink Horror\", \"#FFF8C1BB\": \"Pink Hydrangea\", \"#FFFE01B1\": \"Pink Hysteria\", \"#FFCF9FA9\": \"Pink Ice\", \"#FFEEA0A6\": \"Pink Icing\", \"#FFD8B8F8\": \"Pink Illusion\", \"#FFFF1476\": \"Pink Ink\", \"#FFCC44FF\": \"Pink Insanity\", \"#FFD6B3CC\": \"Pink Ivory\", \"#FF9E6B89\": \"Pink Jazz\", \"#FFFF55AA\": \"Pink Katydid\", \"#FFFF22EE\": \"Pink Kitsch\", \"#FFF6CCD7\": \"Pink Lace Variant\", \"#FFF3D7B6\": \"Pink Lady Variant\", \"#FFD9AFCA\": \"Pink Lavender\", \"#FFFFEAEB\": \"Pink Lemonade\", \"#FFF8D0E7\": \"Pink Lily\", \"#FFD2BFC4\": \"Pink Linen\", \"#FFFADBD7\": \"Pink Lotus\", \"#FFEAACC6\": \"Pink Macaroon\", \"#FFC16C7B\": \"Pink Manhattan\", \"#FFE5D0CA\": \"Pink Marble\", \"#FFF4B6D1\": \"Pink Marshmallow\", \"#FFF4B6A8\": \"Pink Mimosa\", \"#FFF4EDE9\": \"Pink Mirage\", \"#FFE6BCCD\": \"Pink Mist\", \"#FFED9AAB\": \"Pink Moment\", \"#FFA98981\": \"Pink Moroccan\", \"#FFD8AAB7\": \"Pink Nectar\", \"#FFD6C3B7\": \"Pink Nudity\", \"#FF6844FC\": \"Pink OCD\", \"#FFEDC5DD\": \"Pink Odyssey\", \"#FFFF9066\": \"Pink Orange\", \"#FFFD82C3\": \"Pink Orchid Mantis\", \"#FFE1D6D8\": \"Pink Organdy\", \"#FFFF33FF\": \"Pink Overflow\", \"#FFEACED4\": \"Pink Pail\", \"#FFDF9F8F\": \"Pink Palazzo\", \"#FFD1B6C3\": \"Pink Pampas\", \"#FFE1C5C9\": \"Pink Pandora\", \"#FFD5877E\": \"Pink Papaya\", \"#FFB26BA2\": \"Pink Parade\", \"#FFAD546E\": \"Pink Parakeet\", \"#FFFADDD5\": \"Pink Parfait\", \"#FFFF55EE\": \"Pink Party\", \"#FFD3236F\": \"Pink Peacock\", \"#FFE1BED9\": \"Pink Peony\", \"#FFEF586C\": \"Pink Pepper\", \"#FF8E5565\": \"Pink Peppercorn\", \"#FFC034AF\": \"Pink Perennial\", \"#FFFFDBE5\": \"Pink Perfume\", \"#FFFFAD97\": \"Pink Persimmon\", \"#FFF62681\": \"Pink Piano\", \"#FFEFC9B8\": \"Pink Pieris\", \"#FFEE66EE\": \"Pink Ping\", \"#FFB45389\": \"Pink Pizzazz\", \"#FFFC80C3\": \"Pink Plastic Fantastic\", \"#FFFFDFE5\": \"Pink Pleasure\", \"#FFEAD2D2\": \"Pink Plum\", \"#FFA4819F\": \"Pink Plumeria\", \"#FFE4ADD3\": \"Pink Plunge\", \"#FFFF007E\": \"Pink Poison\", \"#FFCCBABE\": \"Pink Polar\", \"#FFEAC7DC\": \"Pink Pony\", \"#FF8E6E74\": \"Pink Poppy\", \"#FFEE9091\": \"Pink Porky\", \"#FFEADEE0\": \"Pink Posey\", \"#FFEFDBE2\": \"Pink Posies\", \"#FFCEAEBB\": \"Pink Potion\", \"#FFD5B6CD\": \"Pink Power\", \"#FFEE99AA\": \"Pink Prestige\", \"#FFEF1DE7\": \"Pink Pride\", \"#FFF1E0E8\": \"Pink Proposal\", \"#FFD04A70\": \"Pink Punch\", \"#FFD983BD\": \"Pink Punk\", \"#FFDB4BDA\": \"Pink Purple\", \"#FFDC9F9F\": \"Pink Pussycat\", \"#FFFFBBEE\": \"Pink Quartz\", \"#FFAB485B\": \"Pink Quince\", \"#FFF5054F\": \"Pink Red\", \"#FFF8DAE1\": \"Pink Ribbon\", \"#FFFEAB9A\": \"Pink Rose Bud\", \"#FFEEBCB8\": \"Pink Sachet\", \"#FFF6CDC6\": \"Pink Salt\", \"#FFDFB19B\": \"Pink Sand\", \"#FFF6DBD3\": \"Pink Sangria\", \"#FFFFBBDD\": \"Pink Satin\", \"#FFF2E0D4\": \"Pink Scallop\", \"#FFF6DACB\": \"Pink Sea Salt\", \"#FFF0D4CA\": \"Pink Sentiment\", \"#FFCD7584\": \"Pink Shade\", \"#FFA4877D\": \"Pink Shade Granite\", \"#FFBB3377\": \"Pink Shadow\", \"#FFF780A1\": \"Pink Sherbet Variant\", \"#FFFDE0DA\": \"Pink Shimmer\", \"#FFD58D8A\": \"Pink Slip\", \"#FFEACAD0\": \"Pink Slipper\", \"#FFDEB8BC\": \"Pink Softness\", \"#FFFFE9EB\": \"Pink Sparkle\", \"#FFE7C9CA\": \"Pink Spinel\", \"#FFA328B3\": \"Pink Spyro\", \"#FFDDABAB\": \"Pink Stock\", \"#FFEEAAFF\": \"Pink Sugar\", \"#FFFFD9E6\": \"Pink Supremecy\", \"#FFBFB3B2\": \"Pink Swan Variant\", \"#FFFCEAE6\": \"Pink Swirl\", \"#FFFF81C0\": \"Pink Tease\", \"#FFFFE6E4\": \"Pink Theory\", \"#FFD9C8BA\": \"Pink Tint\", \"#FFFAE2D6\": \"Pink Touch\", \"#FF985672\": \"Pink Tulip\", \"#FFDEB59A\": \"Pink Tulle\", \"#FFF9E4E9\": \"Pink Tutu\", \"#FFF5E6E6\": \"Pink Vibernum\", \"#FFE0C9C4\": \"Pink Water\", \"#FFFFAAEE\": \"Pink Wink\", \"#FFDDBBBB\": \"Pink Wraith\", \"#FFD13D82\": \"Pink Yarrow\", \"#FFF2D8CD\": \"Pink Zest\", \"#FFCB5C5B\": \"Pinkadelic\", \"#FFFF99FF\": \"Pinkalicious\", \"#FFF1BDBA\": \"Pinkathon\", \"#FFFE54A3\": \"Pinkella\", \"#FFE8C5AE\": \"Pinkham\", \"#FFE82A8E\": \"Pinkinity\", \"#FFD46A7E\": \"Pinkish\", \"#FFB17261\": \"Pinkish Brown\", \"#FFC8ACA9\": \"Pinkish Grey\", \"#FFFF724C\": \"Pinkish Orange\", \"#FFD648D7\": \"Pinkish Purple\", \"#FFF10C45\": \"Pinkish Red\", \"#FFD99B82\": \"Pinkish Tan\", \"#FFFFF1FA\": \"Pinkish White\", \"#FFEB84F5\": \"Pinkling\", \"#FFDD11FF\": \"Pinkman\", \"#FFF9CED1\": \"Pinktone\", \"#FFF2DBD2\": \"Pinkwash\", \"#FFFC86AA\": \"Pinky\", \"#FFC9AA98\": \"Pinky Beige\", \"#FFB96D8E\": \"Pinky Pickle\", \"#FFF5D1CF\": \"Pinky Promise\", \"#FFEEAAEE\": \"Pinky Swear\", \"#FFBEDDD5\": \"Pinnacle\", \"#FF605258\": \"Pinot Noir\", \"#FFECA2AD\": \"Pinque\", \"#FFB89EA8\": \"Pinterested\", \"#FFD2DCDE\": \"Pinwheel Geyser\", \"#FF625A42\": \"Pinyon Pine\", \"#FF480840\": \"Pion Purple\", \"#FFAA9076\": \"Pioneer Village\", \"#FF857165\": \"Pipe\", \"#FF999D99\": \"Pipe Dream\", \"#FF9D5432\": \"Piper Variant\", \"#FFF5E6C4\": \"Pipitschah\", \"#FFFCDBD2\": \"Pippin Variant\", \"#FF769358\": \"Piquant Green\", \"#FFEE00EE\": \"Piquant Pink\", \"#FF71424A\": \"Pirat\\u2019s Wine\", \"#FF363838\": \"Pirate Black\", \"#FFDDE7E2\": \"Pirate Coast\", \"#FFBA782A\": \"Pirate Gold Variant\", \"#FFB1905E\": \"Pirate Plunder\", \"#FF818988\": \"Pirate Silver\", \"#FFDDCA69\": \"Pirate Treasure\", \"#FF005176\": \"Pirate\\u2019s Haven\", \"#FFB08F42\": \"Pirate\\u2019s Hook\", \"#FF716970\": \"Pirate\\u2019s Trinket\", \"#FFAB46EC\": \"Pisces Vivid Amethyst\", \"#FFBEEB71\": \"Pisco Sour\", \"#FF9C7AA4\": \"Pishposh\", \"#FFF4D6A4\": \"Pismo Dunes\", \"#FFC5D498\": \"Pistachio Cream\", \"#FFA5CF8C\": \"Pistachio Dream\", \"#FF4F8F00\": \"Pistachio Flour\", \"#FFA9D39E\": \"Pistachio Green\", \"#FFA0B7AD\": \"Pistachio Ice Cream\", \"#FFC0FA8B\": \"Pistachio Mousse\", \"#FFC6D4AC\": \"Pistachio Pudding\", \"#FFCFC5AF\": \"Pistachio Shell\", \"#FFC7BB73\": \"Pistachio Shortbread\", \"#FFD7D2B8\": \"Pistachio Tang\", \"#FF00BB55\": \"Pistou Green\", \"#FF414958\": \"Pit Stop\", \"#FFF5E7D2\": \"Pita\", \"#FFDEC8A6\": \"Pita Bread\", \"#FFEDEB9A\": \"Pitapat\", \"#FF423937\": \"Pitch\", \"#FF483C41\": \"Pitch Black\", \"#FF2D3D4A\": \"Pitch Cobalt\", \"#FF283330\": \"Pitch Green\", \"#FF5C4033\": \"Pitch Mary Brown\", \"#FF7C7766\": \"Pitch Pine\", \"#FF4A148C\": \"Pitch Violet\", \"#FF003322\": \"Pitch-Black Forests\", \"#FFB5D1BE\": \"Pitcher\", \"#FFD0A32E\": \"Pitmaston Pear Yellow\", \"#FF9BC2BD\": \"Pitter Patter\", \"#FFBB0022\": \"Pixel Bleeding\", \"#FFF7D384\": \"Pixel Cream\", \"#FF008751\": \"Pixel Nature\", \"#FFDBDCDB\": \"Pixel White\", \"#FF009337\": \"Pixelated Grass\", \"#FFF6D5DC\": \"Pixie Dust\", \"#FFBBCDA5\": \"Pixie Green Variant\", \"#FF391285\": \"Pixie Powder\", \"#FFACB1D4\": \"Pixie Violet\", \"#FFE9E6EB\": \"Pixie Wing\", \"#FFB4A6C6\": \"Pixieland\", \"#FFE57F3D\": \"Pizazz Variant\", \"#FFF5C795\": \"Pizazz Peach\", \"#FFBF8D3C\": \"Pizza Variant\", \"#FFCD2217\": \"Pizza Flame\", \"#FFA06165\": \"Pizza Pie\", \"#FFC6C3C0\": \"Place of Dust\", \"#FFE7E7E7\": \"Placebo\", \"#FFEBF4FC\": \"Placebo Blue\", \"#FFF8EBFC\": \"Placebo Fuchsia\", \"#FFEBFCEC\": \"Placebo Green\", \"#FFF6FCEB\": \"Placebo Lime\", \"#FFFCEBF4\": \"Placebo Magenta\", \"#FFFCF5EB\": \"Placebo Orange\", \"#FFFCEBFA\": \"Placebo Pink\", \"#FFF0EBFC\": \"Placebo Purple\", \"#FFFCEBEB\": \"Placebo Red\", \"#FFEBFCFC\": \"Placebo Sky\", \"#FFEBFCF5\": \"Placebo Turquoise\", \"#FFFCFBEB\": \"Placebo Yellow\", \"#FF88A9D2\": \"Placid Blue\", \"#FF1CADBA\": \"Placid Sea\", \"#FFDFB900\": \"Plague Brown\", \"#FFAB8D44\": \"Plaguelands Beige\", \"#FFAD5F28\": \"Plaguelands Hazel\", \"#FFEBF0D6\": \"Plain and Simple\", \"#FF905100\": \"Plain Old Brown\", \"#FFF5DE85\": \"Plains\", \"#FF8A5024\": \"Plane Brown\", \"#FFDADDC3\": \"Planet Earth\", \"#FFAF313A\": \"Planet Fever\", \"#FF496A76\": \"Planet Green\", \"#FF883333\": \"Planet of the Apes\", \"#FF1C70AD\": \"Planetarium\", \"#FFCCCFCB\": \"Planetary Silver\", \"#FF00534C\": \"Plankton Green\", \"#FF777A44\": \"Plant Green\", \"#FF97943B\": \"Plantain\", \"#FFD6A550\": \"Plantain Chips\", \"#FF356554\": \"Plantain Green\", \"#FF3E594C\": \"Plantation Variant\", \"#FF9B8A44\": \"Plantation Island\", \"#FF6A5143\": \"Plantation Shutters\", \"#FF339900\": \"Planter\", \"#FFD59CFC\": \"Plasma Trail\", \"#FFEAEAEA\": \"Plaster\", \"#FFE1EAEC\": \"Plaster Cast\", \"#FFEAD1A6\": \"Plaster Mix\", \"#FFF65D20\": \"Plastic Carrot\", \"#FFFFCC04\": \"Plastic Cheese\", \"#FFF5F0F1\": \"Plastic Clouds\", \"#FFEDDC70\": \"Plastic Lime\", \"#FFAA2266\": \"Plastic Lips\", \"#FFFFDDCC\": \"Plastic Marble\", \"#FF55AA11\": \"Plastic Pines\", \"#FF22FF22\": \"Plastic Veggie\", \"#FF4A623B\": \"Plasticine\", \"#FF8C8589\": \"Plate Mail Metal\", \"#FFD3E7E5\": \"Plateau\", \"#FFF0E8D7\": \"Platinum Blonde\", \"#FF807F7E\": \"Platinum Granite\", \"#FF6A6D6F\": \"Platinum Grey\", \"#FFECE1D3\": \"Platinum Ogon Koi\", \"#FFD1CCB0\": \"Platinum Sage\", \"#FF88CCFF\": \"Platonic Blue\", \"#FF2A4845\": \"Platoon Green\", \"#FF39536C\": \"Plaudit\", \"#FFFF8877\": \"Play \\u2019til Dawn\", \"#FF638495\": \"Play Me a Melody\", \"#FFBAB6A9\": \"Play on Grey\", \"#FFCE5924\": \"Play School\", \"#FFB39BA9\": \"Play Time\", \"#FFDCC7B3\": \"Playa Arenosa\", \"#FFFCE3CA\": \"Playful Peach\", \"#FFCBBDD7\": \"Playful Petal\", \"#FFC46C73\": \"Playful Pink\", \"#FFBA99A2\": \"Playful Plum\", \"#FFBFB9D5\": \"Playful Purple\", \"#FF8B8C6B\": \"Playing Hooky\", \"#FFF4C0C3\": \"Plaza Pink\", \"#FFAEA393\": \"Plaza Taupe\", \"#FFA379AA\": \"Pleasant Dream\", \"#FF4D5A4C\": \"Pleasant Hill\", \"#FFCC3300\": \"Pleasant Pomegranate\", \"#FF8833AA\": \"Pleasant Purple\", \"#FF00A0A2\": \"Pleasant Stream\", \"#FFF5CDD2\": \"Pleasing Pink\", \"#FF80385C\": \"Pleasure\", \"#FF858BC2\": \"Pleated Mauve\", \"#FFB9C4D2\": \"Plein Air\", \"#FFD0ADD3\": \"Plink\", \"#FF56646B\": \"Plot Twist\", \"#FF6C6459\": \"Ploughed Earth\", \"#FF8F8373\": \"Plover Grey\", \"#FF66386A\": \"Plum Variant\", \"#FFF2A0A1\": \"Plum Blossom\", \"#FFB48A76\": \"Plum Blossom Dye\", \"#FF4B6176\": \"Plum Blue\", \"#FF4E4247\": \"Plum Brown\", \"#FF9C7EB7\": \"Plum Burst\", \"#FFD1BFDC\": \"Plum Cake\", \"#FF612246\": \"Plum Caspia\", \"#FF6A6A6F\": \"Plum Charcoal\", \"#FF670728\": \"Plum Cheese\", \"#FF716063\": \"Plum Crush\", \"#FF8B6878\": \"Plum Dandy\", \"#FFAA4C8F\": \"Plum Dust\", \"#FFB1A7B6\": \"Plum Frost\", \"#FF313048\": \"Plum Fuzz\", \"#FF695C39\": \"Plum Green\", \"#FF674555\": \"Plum Harvest\", \"#FF8B7574\": \"Plum Haze\", \"#FF885577\": \"Plum Highness\", \"#FF644348\": \"Plum Intended\", \"#FF463C4E\": \"Plum Island\", \"#FF704783\": \"Plum Jam\", \"#FFDEA1DD\": \"Plum Juice\", \"#FFAA3377\": \"Plum Kingdom\", \"#FF625B5C\": \"Plum Kitten\", \"#FF8E7482\": \"Plum Legacy\", \"#FF994548\": \"Plum Majesty\", \"#FFC099A0\": \"Plum Mouse\", \"#FF4E414B\": \"Plum Orbit\", \"#FFAA1166\": \"Plum Paradise\", \"#FF9B4B80\": \"Plum Passion\", \"#FFAA1155\": \"Plum Perfect\", \"#FFA489A3\": \"Plum Perfume\", \"#FFD4BDDF\": \"Plum Point\", \"#FF7E5E8D\": \"Plum Power\", \"#FF7C70AA\": \"Plum Preserve\", \"#FF644847\": \"Plum Raisin\", \"#FF64475E\": \"Plum Rich\", \"#FF876C7A\": \"Plum Royale\", \"#FF6A3939\": \"Plum Sauce\", \"#FF915D88\": \"Plum Savour\", \"#FF78738B\": \"Plum Shade\", \"#FF7C707C\": \"Plum Shadow\", \"#FF51304E\": \"Plum Skin\", \"#FF928E8E\": \"Plum Smoke\", \"#FF957E8E\": \"Plum Swirl\", \"#FFDDC1D7\": \"Plum Taffy\", \"#FFB6A19B\": \"Plum Taupe\", \"#FF6A5858\": \"Plum Truffle\", \"#FF734D58\": \"Plum Wine\", \"#FFDACEE8\": \"Plum\\u2019s the Word\", \"#FF00998C\": \"Plumage\", \"#FF5C7287\": \"Plumbeous\", \"#FF735054\": \"Plumberry\", \"#FF7D665F\": \"Plumburn\", \"#FFA5CFD5\": \"Plume\", \"#FFD9D5C5\": \"Plume Grass\", \"#FFC3B5D4\": \"Plumeria\", \"#FF675A75\": \"Plummy\", \"#FF604454\": \"Plummy Rouge\", \"#FF64A281\": \"Plumosa\", \"#FF9E8185\": \"Plumville\", \"#FF5072A9\": \"Plunder\", \"#FF035568\": \"Plunge\", \"#FF00FFCC\": \"Plunge Pool\", \"#FF8CD4DF\": \"Plunging Waterfall\", \"#FF78AC01\": \"Plus Ultra\", \"#FF3B3549\": \"Plush\", \"#FF5D4A61\": \"Plush Purple\", \"#FFB1928C\": \"Plush Suede\", \"#FFB49C83\": \"Plush Tan\", \"#FF7E737D\": \"Plush Velvet\", \"#FFEAB7A8\": \"Plushy Pink\", \"#FF34ACB1\": \"Pluto\", \"#FF35FA00\": \"Plutonium\", \"#FF66DDDD\": \"Pluviophile\", \"#FFDDD3C2\": \"Plymouth Beige\", \"#FFB1B695\": \"Plymouth Green\", \"#FFB0B1AC\": \"Plymouth Grey\", \"#FFCDB3AC\": \"Plymouth Notch\", \"#FFF5D893\": \"Poached Egg\", \"#FFFF8552\": \"Poached Rainbow Trout\", \"#FF077F1B\": \"Poblano\", \"#FFEE9977\": \"Pochard Duck Head\", \"#FFB5D5D7\": \"Pocket Lint\", \"#FFC2A781\": \"Pocket Watch\", \"#FFC3B8C3\": \"Pocketful of Posies\", \"#FFE1C7C6\": \"Pocketful of Promise\", \"#FF00A844\": \"Poetic Green\", \"#FFE4E8E1\": \"Poetic Licence\", \"#FFE2DED8\": \"Poetic Light\", \"#FFF8E1E4\": \"Poetic Princess\", \"#FFFFFED7\": \"Poetic Yellow\", \"#FFC2ACA5\": \"Poetry in Motion\", \"#FF886891\": \"Poetry Mauve\", \"#FF6F5C5F\": \"Poetry Plum\", \"#FF9FAEC9\": \"Poetry Reading\", \"#FFECE4D2\": \"Pogo Sands\", \"#FF651C26\": \"Pohutukawa Variant\", \"#FFDB372A\": \"Poinciana\", \"#FFCC3842\": \"Poinsettia\", \"#FF859587\": \"Pointed Cabbage Green\", \"#FF575D56\": \"Pointed Fir\", \"#FF646767\": \"Pointed Rock\", \"#FFA77693\": \"Poise\", \"#FFFFA99D\": \"Poised Peach\", \"#FF8C7E78\": \"Poised Taupe\", \"#FF40FD14\": \"Poison Green\", \"#FFB300FF\": \"Poison Purple Paradise\", \"#FF73403E\": \"Poisonberry\", \"#FF66FF11\": \"Poisoning Green\", \"#FF7F01FE\": \"Poisoning Purple\", \"#FF55FF11\": \"Poisonous\", \"#FF993333\": \"Poisonous Apple\", \"#FFD3DB39\": \"Poisonous Cloud\", \"#FF77FF66\": \"Poisonous Dart\", \"#FFD7D927\": \"Poisonous Ice Cream\", \"#FFCAE80A\": \"Poisonous Pesto\", \"#FF88EE11\": \"Poisonous Pistachio\", \"#FF99DD33\": \"Poisonous Potion\", \"#FF2A0134\": \"Poisonous Purple\", \"#FF35654D\": \"Poker Green\", \"#FFE5F2E7\": \"Polar Variant\", \"#FFEAE9E0\": \"Polar Bear\", \"#FFFCFFFF\": \"Polar Bear in a Blizzard\", \"#FFB3E0E7\": \"Polar Blue\", \"#FFCCD5DA\": \"Polar Drift\", \"#FFC9E7E3\": \"Polar Expedition\", \"#FFD2D0C9\": \"Polar Fox\", \"#FF5097FC\": \"Polar Glow\", \"#FFADAFBD\": \"Polar Mist\", \"#FFC2D6EC\": \"Polar Opposite\", \"#FF6B7B7B\": \"Polar Pond\", \"#FFACCDE2\": \"Polar Seas\", \"#FFD0DCDE\": \"Polar Soft Blue\", \"#FFD0D1CF\": \"Polar Star\", \"#FFE6EFEC\": \"Polar White\", \"#FFB4DFED\": \"Polar Wind\", \"#FFA0AEAD\": \"Polaris\", \"#FF6F8A8C\": \"Polaris Blue\", \"#FFEFC47F\": \"Polenta\", \"#FF374F6B\": \"Police Blue\", \"#FFBD7D94\": \"Polignac\", \"#FFE9E8E7\": \"Polish White\", \"#FFDED8CE\": \"Polished\", \"#FF862A2E\": \"Polished Apple\", \"#FF77BCB6\": \"Polished Aqua\", \"#FF985538\": \"Polished Brown\", \"#FF9E9793\": \"Polished Concrete\", \"#FFB66325\": \"Polished Copper\", \"#FFC7D4D7\": \"Polished Cotton\", \"#FF953640\": \"Polished Garnet\", \"#FFEEAA55\": \"Polished Gold\", \"#FFEDE0C8\": \"Polished Ivory\", \"#FF4F4041\": \"Polished Leather\", \"#FFDCD5C8\": \"Polished Limestone\", \"#FF432722\": \"Polished Mahogany\", \"#FFD0BC9D\": \"Polished Marble\", \"#FF819AB1\": \"Polished Metal\", \"#FFF8EDD3\": \"Polished Pearl\", \"#FF9C9A99\": \"Polished Pewter\", \"#FFFFF2EF\": \"Polished Pink\", \"#FFBCC3C2\": \"Polished Rock\", \"#FFC5D1DA\": \"Polished Silver\", \"#FF6F828A\": \"Polished Steel\", \"#FFBEB49E\": \"Polished Stone\", \"#FFE9DDD4\": \"Polite White\", \"#FF5A4458\": \"Polka Dot Plum\", \"#FFFDE2A0\": \"Polka Dot Skirt\", \"#FFEEEEAA\": \"Pollen\", \"#FFF0C588\": \"Pollen Grains\", \"#FFFBD187\": \"Pollen Powder\", \"#FFB8A02A\": \"Pollen Storm\", \"#FFE3D6BC\": \"Pollinate\", \"#FFEEDD66\": \"Pollination\", \"#FFE2CF24\": \"Polliwog\", \"#FFFFCAA4\": \"Polly\", \"#FF8AA7CC\": \"Polo Blue Variant\", \"#FFD09258\": \"Polo Pony\", \"#FFF4E5DD\": \"Polo Tan\", \"#FFE8B87F\": \"Polvo de Oro\", \"#FFFEFFCC\": \"Polyanthus Narcissus\", \"#FFEAEAE8\": \"Polypropylene\", \"#FF856F76\": \"Pomace Red\", \"#FFB53D45\": \"Pomegranate Variant\", \"#FF95313A\": \"Pomegranate Seeds\", \"#FFAB6F73\": \"Pomegranate Tea\", \"#FFE38FAC\": \"Pomelo Red\", \"#FFFCE8E3\": \"Pomelo Sugar\", \"#FFC30232\": \"Pomodoro\", \"#FFF2D4DF\": \"Pomodoro e Mozzarella\", \"#FF87608E\": \"Pomp and Power\", \"#FF6A1F44\": \"Pompadour Variant\", \"#FFC87763\": \"Pompeian Pink\", \"#FFA82A38\": \"Pompeian Red\", \"#FF6C757D\": \"Pompeii Ash\", \"#FF004C71\": \"Pompeii Blue\", \"#FFD1462C\": \"Pompeii Red\", \"#FF77A8AB\": \"Pompeius Blue\", \"#FFFF6666\": \"Pompelmo\", \"#FFCA93C1\": \"Pomtini\", \"#FFF75C75\": \"Ponceau\", \"#FFB49073\": \"Poncho\", \"#FF00827F\": \"Pond Bath\", \"#FF8BB6C6\": \"Pond Blue\", \"#FFD0D8D9\": \"Pond Frost\", \"#FFA18E6B\": \"Pond Green\", \"#FF939990\": \"Pond Leaves\", \"#FF486B67\": \"Pond Newt\", \"#FFB6C9B8\": \"Pond\\u2019s Edge\", \"#FFB88F88\": \"Ponder\", \"#FF29494E\": \"Ponderosa Pine\", \"#FFD7EFDE\": \"Pondscape\", \"#FF5F9228\": \"Pont Moss\", \"#FF0C608E\": \"Pontoon\", \"#FFC6AA81\": \"Pony\", \"#FF726A60\": \"Pony Express\", \"#FFD2BC9B\": \"Pony Tail\", \"#FF220000\": \"Ponzu Brown\", \"#FFEECEE6\": \"Poodle Pink\", \"#FFFFAEBB\": \"Poodle Skirt\", \"#FFEA927A\": \"Poodle Skirt Peach\", \"#FF824B2E\": \"Pookie Bear\", \"#FF8FABBD\": \"Pool Bar\", \"#FF67BCB3\": \"Pool Blue\", \"#FF7DAEE1\": \"Pool Floor\", \"#FF00AF9D\": \"Pool Green\", \"#FFBEE9E3\": \"Pool Party\", \"#FF039578\": \"Pool Table\", \"#FF70928E\": \"Pool Tide\", \"#FF2188FF\": \"Pool Water\", \"#FF8095A0\": \"Poolhouse\", \"#FF72ACAD\": \"Poolrooms\", \"#FFBEE0E2\": \"Poolside\", \"#FFA13741\": \"Pop of Poppy\", \"#FF93D4C0\": \"Pop Shop\", \"#FFF771B3\": \"Pop That Gum\", \"#FFF7D07A\": \"Popcorn\", \"#FFFCEBD1\": \"Popcorn Ball\", \"#FFA29F46\": \"Poplar\", \"#FF137953\": \"Poplar Forest\", \"#FFECE9E9\": \"Poplar Kitten\", \"#FFFED3E4\": \"Poplar Pink\", \"#FFDFE3D8\": \"Poplar White\", \"#FFC23C47\": \"Poppy\", \"#FFFBE9D8\": \"Poppy Crepe\", \"#FFF18C49\": \"Poppy Glow\", \"#FF88A496\": \"Poppy Leaf\", \"#FFF6A08C\": \"Poppy Petal\", \"#FF736157\": \"Poppy Pods\", \"#FFAE605B\": \"Poppy Prose\", \"#FFDD3845\": \"Poppy Red\", \"#FF4A4E54\": \"Poppy Seed\", \"#FFFF5630\": \"Poppy Surprise\", \"#FFCCD7DF\": \"Poppy\\u2019s Whiskers\", \"#FFD4CCC3\": \"Popular Beige\", \"#FFDDDCDB\": \"Porcelain Variant\", \"#FFD9D0C4\": \"Porcelain Basin\", \"#FF95C0CB\": \"Porcelain Blue\", \"#FFF0DBD5\": \"Porcelain Blush\", \"#FFE9B7A8\": \"Porcelain Crab\", \"#FFEEFFBB\": \"Porcelain Earth\", \"#FFA9998C\": \"Porcelain Figurines\", \"#FFE1DAD9\": \"Porcelain Goldfish\", \"#FF118C7E\": \"Porcelain Green\", \"#FFDFE2E4\": \"Porcelain Jasper\", \"#FFDBE7E1\": \"Porcelain Mint\", \"#FFEBE8E2\": \"Porcelain Mould\", \"#FFF5D8BA\": \"Porcelain Peach\", \"#FFECD9B9\": \"Porcelain Pink\", \"#FFEA6B6A\": \"Porcelain Rose\", \"#FF808078\": \"Porcelain Shale\", \"#FFFFE7EB\": \"Porcelain Skin\", \"#FFF7D8C4\": \"Porcelain Tan\", \"#FF95B0C6\": \"Porcelain Vase\", \"#FFFDDDA7\": \"Porcelain Yellow\", \"#FFFFBFAB\": \"Porcellana\", \"#FFA4B3B9\": \"Porch Ceiling\", \"#FF566F8C\": \"Porch Song\", \"#FF597175\": \"Porch Swing\", \"#FFD2CABE\": \"Porch Swing Beige\", \"#FFAA8736\": \"Porchetta Crust\", \"#FFD9AE86\": \"Porcini\", \"#FF917A75\": \"Porcupine Needles\", \"#FFF8E0E7\": \"Pork Belly\", \"#FFD4CEBF\": \"Porous Stone\", \"#FF2A0033\": \"Porphyrophobia\", \"#FF2792C3\": \"Porpita Porpita\", \"#FFDBDBDA\": \"Porpoise\", \"#FFC8CBCD\": \"Porpoise Fin\", \"#FF076A7E\": \"Porpoise Place\", \"#FF6D3637\": \"Port\", \"#FF006A93\": \"Port au Prince\", \"#FF54383B\": \"Port Glow\", \"#FF3B436C\": \"Port Gore Variant\", \"#FF54C3C1\": \"Port Hope\", \"#FF0E4D4E\": \"Port Malmesbury\", \"#FF532D36\": \"Port Royale\", \"#FF6E0C0D\": \"Port Wine\", \"#FF846342\": \"Port Wine Barrel\", \"#FF85677B\": \"Port Wine Stain\", \"#FF9A8273\": \"Portabella\", \"#FF947A62\": \"Portabello\", \"#FF8B98D8\": \"Portage Variant\", \"#FFF8F6DA\": \"Portal Entrance\", \"#FFF0D555\": \"Portica Variant\", \"#FFBBAB95\": \"Portico\", \"#FF767671\": \"Portland Twilight\", \"#FFA28C82\": \"Portobello\", \"#FF9D928A\": \"Portobello Mushroom\", \"#FFF4F09B\": \"Portofino\", \"#FFF0D3DF\": \"Portrait Pink\", \"#FFC4957A\": \"Portrait Tone\", \"#FF768482\": \"Portsmouth\", \"#FFA1ADAD\": \"Portsmouth Bay\", \"#FF5B7074\": \"Portsmouth Blue\", \"#FF6B6B44\": \"Portsmouth Olive\", \"#FFA75546\": \"Portsmouth Spice\", \"#FF3C5E95\": \"Portuguese Blue\", \"#FFC48F85\": \"Portuguese Dawn\", \"#FF717910\": \"Portuguese Green\", \"#FF143C5D\": \"Poseidon\", \"#FF66EEEE\": \"Poseidon Jr.\", \"#FFD9D6C7\": \"Poseidon\\u2019s Beard\", \"#FF227478\": \"Poseidon\\u2019s Castle\", \"#FFD59A54\": \"Poseidon\\u2019s Gold\", \"#FF4400EE\": \"Poseidon\\u2019s Territory\", \"#FFA5B4C6\": \"Posey Blue\", \"#FFEFB495\": \"Posh Peach\", \"#FF7D2621\": \"Posh Red\", \"#FFDFBBD9\": \"Posies\", \"#FFE1E2CF\": \"Positive Energy\", \"#FFAD2C34\": \"Positive Red\", \"#FF76745D\": \"Positively Palm\", \"#FFE7BFB6\": \"Positively Pink\", \"#FF7782A3\": \"Positively Purple\", \"#FF773355\": \"Possessed Plum\", \"#FF881166\": \"Possessed Purple\", \"#FFC2264D\": \"Possessed Red\", \"#FFF3DACE\": \"Possibly Pink\", \"#FFC8CDD8\": \"Post Apocalyptic Cloud\", \"#FF7A99AD\": \"Post Boy\", \"#FF0074B4\": \"Post It\", \"#FFFFEE01\": \"Post Yellow\", \"#FF134682\": \"Poster Blue\", \"#FF006B56\": \"Poster Green\", \"#FFECC100\": \"Poster Yellow\", \"#FFB39C8E\": \"Postmodern Mauve\", \"#FFC7C4CD\": \"Posture & Pose\", \"#FF466F97\": \"Postwar Boom\", \"#FFF3E1D3\": \"Posy\", \"#FF366254\": \"Posy Green\", \"#FFF3879C\": \"Posy Petal\", \"#FF6E6386\": \"Posy Purple\", \"#FF161616\": \"Pot Black\", \"#FFF9F4E6\": \"Pot of Cream\", \"#FFF6CD23\": \"Pot of Gold\", \"#FFE07757\": \"Potash\", \"#FFFDDC57\": \"Potato Chip\", \"#FF532D45\": \"Potent Purple\", \"#FFD5CDE3\": \"Potentially Purple\", \"#FF8F3129\": \"Potion \\u2116 9\", \"#FF9ECCA7\": \"Potted Plant\", \"#FF938A2A\": \"Potter Green\", \"#FFA64826\": \"Potter\\u2019s Clay\", \"#FFC2937B\": \"Potter\\u2019s Pink\", \"#FF845C40\": \"Potter\\u2019s Pot\", \"#FF88564C\": \"Potter\\u2019s Rock\", \"#FF54A6C2\": \"Pottery Blue\", \"#FFB9714A\": \"Pottery Clay\", \"#FFB05D59\": \"Pottery Red\", \"#FFAA866E\": \"Pottery Urn\", \"#FFCAAC91\": \"Pottery Wheel\", \"#FFA0A089\": \"Potting Moss\", \"#FF5B3E31\": \"Potting Soil\", \"#FFE68E96\": \"Poudretteite Pink\", \"#FFDECCE4\": \"Pouf of Pink\", \"#FFFDF1C3\": \"Pound Cake\", \"#FF818081\": \"Pound Sterling\", \"#FFFB9B82\": \"Pouring Copper\", \"#FFE4CCC3\": \"Pout\", \"#FFFF82CE\": \"Pout Pink\", \"#FFF9A7A4\": \"Pouty Pink\", \"#FFE7D7EF\": \"Pouty Purple\", \"#FFD8948B\": \"Powder Blush\", \"#FFDFD7CA\": \"Powder Cake\", \"#FFB7B7BC\": \"Powder Dust\", \"#FFBFC2CE\": \"Powder Lilac\", \"#FF9CB3B5\": \"Powder Mill\", \"#FFFDD6E5\": \"Powder Pink\", \"#FFFFEFF3\": \"Powder Puff\", \"#FF95396A\": \"Powder Red\", \"#FFEEE0DD\": \"Powder Room\", \"#FFF5B3BC\": \"Powder Rose\", \"#FFF7F1DD\": \"Powder Sand\", \"#FFB9C9D7\": \"Powder Soft Blue\", \"#FFCBC2D3\": \"Powder Viola\", \"#FFD9D3E5\": \"Powder Viola White\", \"#FFEBF1F5\": \"Powder White\", \"#FFF9F2E7\": \"Powdered\", \"#FFC9AB9A\": \"Powdered Allspice\", \"#FFF8DCDB\": \"Powdered Blush\", \"#FFAC9B9B\": \"Powdered Brick\", \"#FF341C02\": \"Powdered Cocoa\", \"#FFA0450E\": \"Powdered Coffee\", \"#FFE8D2B1\": \"Powdered Gold\", \"#FFC3C9E6\": \"Powdered Granite\", \"#FFC5C56A\": \"Powdered Green Tea\", \"#FFA0B0A4\": \"Powdered Gum\", \"#FFFDE2D1\": \"Powdered Peach\", \"#FFE3C7C6\": \"Powdered Petals\", \"#FFC7D6D0\": \"Powdered Pool\", \"#FFB7B38D\": \"Powdered Sage\", \"#FFF8F4E6\": \"Powdered Snow\", \"#FFE4E0EB\": \"Powdery Mist\", \"#FFA2A4A6\": \"Power Grey\", \"#FFD4D1C7\": \"Power Lunch\", \"#FF332244\": \"Power Outage\", \"#FFEE5588\": \"Power Peony\", \"#FF66303C\": \"Power Tie\", \"#FFBBB7AB\": \"Powered Rock\", \"#FF4C3F5D\": \"Powerful Mauve\", \"#FF372252\": \"Powerful Violet\", \"#FFC9B29C\": \"Practical Beige\", \"#FFE1CBB6\": \"Practical Tan\", \"#FF679A7C\": \"Practice Green\", \"#FFC2A593\": \"Pragmatic\", \"#FF0B9D6A\": \"Prairie\", \"#FF935444\": \"Prairie Clay\", \"#FF516678\": \"Prairie Denim\", \"#FF937067\": \"Prairie Dog\", \"#FFFBD5BD\": \"Prairie Dune\", \"#FFCEC5AD\": \"Prairie Dusk\", \"#FFB9AB8F\": \"Prairie Dust\", \"#FF996E5A\": \"Prairie Fire\", \"#FF6E5F45\": \"Prairie Foliage\", \"#FFB1A38E\": \"Prairie Grass\", \"#FF50A400\": \"Prairie Green\", \"#FF8E7D5D\": \"Prairie Grove\", \"#FFD3C9AD\": \"Prairie House\", \"#FFE2CC9C\": \"Prairie Land\", \"#FFAE5F55\": \"Prairie Poppy\", \"#FFF2C8BE\": \"Prairie Rose\", \"#FFB3A98C\": \"Prairie Sage\", \"#FF883C32\": \"Prairie Sand Variant\", \"#FFC6D7E0\": \"Prairie Sky\", \"#FFEEA372\": \"Prairie Sun\", \"#FFFFB199\": \"Prairie Sunset\", \"#FFD2D8B5\": \"Prairie Willow\", \"#FFE8E6D9\": \"Prairie Winds\", \"#FFB2B1AE\": \"Praise Giving\", \"#FF221155\": \"Praise of Shadow\", \"#FFF3F4D9\": \"Praise the Sun\", \"#FFAD8B75\": \"Praline\", \"#FFC58380\": \"Prancer\", \"#FF002F0F\": \"Prasinophobia\", \"#FFF6F7ED\": \"Praxeti White\", \"#FFD59C6A\": \"Prayer Flag\", \"#FFA5BE8F\": \"Praying Mantis\", \"#FFB5C2CD\": \"Pre School\", \"#FF8B7F7A\": \"Pre-Raphaelite\", \"#FFF1DAB2\": \"Precious\", \"#FF008389\": \"Precious Blue\", \"#FF885522\": \"Precious Copper\", \"#FFF5F5E4\": \"Precious Dewdrop\", \"#FF186E50\": \"Precious Emerald\", \"#FFB7757C\": \"Precious Garnet\", \"#FF613A57\": \"Precious Jewels\", \"#FFFFDE9C\": \"Precious Nectar\", \"#FF6D9A79\": \"Precious Oxley\", \"#FFF1F0EF\": \"Precious Pearls\", \"#FFBD4048\": \"Precious Peony\", \"#FFFF7744\": \"Precious Persimmon\", \"#FFF6B5B6\": \"Precious Pink\", \"#FFE16233\": \"Precious Pumpkin\", \"#FF328696\": \"Precious Stone\", \"#FF2C3944\": \"Precision\", \"#FFE8DEE3\": \"Precocious Red\", \"#FFE5DBCB\": \"Predictable\", \"#FF6D6E7B\": \"Prediction\", \"#FF5772B0\": \"Prefect\", \"#FF546762\": \"Prehistoric\", \"#FFEE2211\": \"Prehistoric Meteor\", \"#FFC3738D\": \"Prehistoric Pink\", \"#FF9AA0A3\": \"Prehistoric Stone\", \"#FF5E5239\": \"Prehistoric Wood\", \"#FFD0A700\": \"Prehnite Yellow\", \"#FFDFEBEE\": \"Prelude Variant\", \"#FFE1DEDA\": \"Prelude Tint\", \"#FFE6B6BE\": \"Premium Pink\", \"#FFD1668F\": \"Preppy Rose\", \"#FF665864\": \"Preservation Plum\", \"#FF4A3C50\": \"Preserve\", \"#FFB0655A\": \"Preserved Petals\", \"#FF3E4D59\": \"Presidential\", \"#FFEC9580\": \"Presidio Peach\", \"#FFBB9174\": \"Presidio Plaza\", \"#FF634875\": \"Presley Purple\", \"#FF606B77\": \"Press Agent\", \"#FFC2968B\": \"Pressed Blossoms\", \"#FFD492BD\": \"Pressed Flower\", \"#FFFEFE22\": \"Pressed Laser Lemon\", \"#FFEFABA6\": \"Pressed Rose\", \"#FF00CC11\": \"Pressing My Luck\", \"#FFB8A7A0\": \"Prestige\", \"#FF303742\": \"Prestige Blue\", \"#FF154647\": \"Prestige Green\", \"#FF4C213D\": \"Prestige Mauve\", \"#FF5E6277\": \"Presumption\", \"#FF4444FF\": \"Pretentious Peacock\", \"#FFE5A3C5\": \"Prettiest Pink\", \"#FFE9AF9B\": \"Pretty in Peach\", \"#FFFABFE4\": \"Pretty in Pink\", \"#FFCC5588\": \"Pretty in Plum\", \"#FF6B295A\": \"Pretty in Prune\", \"#FFC3A1B6\": \"Pretty Lady\", \"#FF849457\": \"Pretty Maiden\", \"#FFE3C6D6\": \"Pretty Pale\", \"#FFAC5D3E\": \"Pretty Parasol\", \"#FFDFCDB2\": \"Pretty Pastry\", \"#FFAE5D6D\": \"Pretty Peony\", \"#FFD6B7E2\": \"Pretty Petunia\", \"#FFEEAADD\": \"Pretty Pink Piggy\", \"#FFFFCCC8\": \"Pretty Please\", \"#FFBCBDE4\": \"Pretty Posie\", \"#FFF5A994\": \"Pretty Primrose\", \"#FF7B6065\": \"Pretty Puce\", \"#FFC4BBD6\": \"Pretty Purple\", \"#FFE4B197\": \"Pretty Rascal\", \"#FF254770\": \"Pretty Twilight Night\", \"#FFE5A68D\": \"Priceless Coral\", \"#FF46373F\": \"Priceless Purple\", \"#FFA89942\": \"Prickly Pear\", \"#FF69916E\": \"Prickly Pear Cactus\", \"#FFF42C93\": \"Prickly Pink\", \"#FFA264BA\": \"Prickly Purple\", \"#FFE2CDD5\": \"Prim Variant\", \"#FFCBA792\": \"Primal\", \"#FF0081B5\": \"Primal Blue\", \"#FF11875D\": \"Primal Green\", \"#FFF4301C\": \"Primal Rage\", \"#FFA92B4F\": \"Primal Red\", \"#FF0804F9\": \"Primary Blue\", \"#FF6FA77A\": \"Primavera\", \"#FF0064A1\": \"Prime Blue\", \"#FF92B979\": \"Prime Merchandise\", \"#FFFF8D86\": \"Prime Pink\", \"#FF656293\": \"Prime Purple\", \"#FF685E4E\": \"Primitive\", \"#FFDED6AC\": \"Primitive Green\", \"#FF663C55\": \"Primitive Plum\", \"#FF7CBC6C\": \"Primo\", \"#FFD6859F\": \"Primrose Variant\", \"#FFF3949B\": \"Primrose Garden\", \"#FFFFE262\": \"Primrose Path\", \"#FFE7C2CA\": \"Primrose Pink\", \"#FFECE4D0\": \"Primrose White\", \"#FFF6D155\": \"Primrose Yellow\", \"#FFCA9FA5\": \"Primula\", \"#FF4B384C\": \"Prince\", \"#FFCC2277\": \"Prince Charming\", \"#FFA0ADAC\": \"Prince Grey\", \"#FF9D7957\": \"Prince Paris\", \"#FF60606F\": \"Prince Royal\", \"#FF7D4961\": \"Princely\", \"#FF6D5C7B\": \"Princely Violet\", \"#FFF0A8B5\": \"Princess\", \"#FF0056A1\": \"Princess Blue\", \"#FFCCEEEE\": \"Princess Blue Feather\", \"#FFF4C1C1\": \"Princess Bride\", \"#FFF6E9EA\": \"Princess Elle\", \"#FFE5DBEB\": \"Princess Fairy Tale\", \"#FFFAEAD5\": \"Princess Ivory\", \"#FFF878F8\": \"Princess Peach\", \"#FFFF85CF\": \"Princess Perfume\", \"#FFDFB5B0\": \"Princess Pink\", \"#FF756F54\": \"Priory\", \"#FFF1D3DA\": \"Priscilla\", \"#FFAADCCD\": \"Prism\", \"#FFF0A1BF\": \"Prism Pink\", \"#FF53357D\": \"Prism Violet\", \"#FF117777\": \"Prismarine\", \"#FFEAE8DD\": \"Prismatic Pearl\", \"#FF005C77\": \"Prismatic Springs\", \"#FFFDAA48\": \"Prison Jumpsuit\", \"#FFF2E8DA\": \"Pristine\", \"#FF00CCBB\": \"Pristine Oceanic\", \"#FFD5E1E0\": \"Pristine Petal\", \"#FF007799\": \"Pristine Seas\", \"#FF807658\": \"Private Affair\", \"#FF4C4949\": \"Private Black\", \"#FF006E89\": \"Private Eye\", \"#FF4F531F\": \"Private Green\", \"#FF889DB2\": \"Private Jet\", \"#FF845469\": \"Private Tone\", \"#FFF3EBD9\": \"Private White\", \"#FFD9B2C7\": \"Private-Label Pink\", \"#FF768775\": \"Privet\", \"#FF588A79\": \"Privet Hedge\", \"#FF7A8775\": \"Privilege Green\", \"#FFF3EAD7\": \"Privileged\", \"#FF597695\": \"Privileged Elite\", \"#FFCC9DC6\": \"Prize Winning Orchid\", \"#FFA2C0B9\": \"Prized Celadon\", \"#FF393540\": \"Professor Plum\", \"#FF40243D\": \"Profound Mauve\", \"#FFC39297\": \"Profound Pink\", \"#FFDAA5AA\": \"Prom\", \"#FFE7C3E7\": \"Prom Corsage\", \"#FFC4A99D\": \"Prom Night\", \"#FFE9A9BB\": \"Prom Pink\", \"#FF9B1DCD\": \"Prom Queen\", \"#FFF8F6DF\": \"Promenade\", \"#FFF4581E\": \"Prometheus Orange\", \"#FF2B7DA6\": \"Prominent Blue\", \"#FFDA9EC5\": \"Prominent Pink\", \"#FFBB11EE\": \"Promiscuous Pink\", \"#FFACC0E2\": \"Promise\", \"#FFAFC7E8\": \"Promise Keeping\", \"#FF686278\": \"Promised Amethyst\", \"#FF5E7FB5\": \"Prompt\", \"#FFADA8A5\": \"Proper Grey\", \"#FF59476B\": \"Proper Purple\", \"#FFEDE5C7\": \"Proper Temperature\", \"#FF4B5667\": \"Property\", \"#FF6F58A6\": \"Prophet Violet\", \"#FFBE8B8F\": \"Prophetess\", \"#FF624F59\": \"Prophetic Purple\", \"#FF818B9C\": \"Prophetic Sea\", \"#FFE0B4A4\": \"Prosciutto\", \"#FF62584B\": \"Prospect\", \"#FF915F66\": \"Prosperity\", \"#FF66543E\": \"Prot\\u00e9g\\u00e9 Bronze\", \"#FFFF8866\": \"Protein High\", \"#FF840804\": \"Proton Red\", \"#FFE0C778\": \"Protoss\", \"#FF00AAFF\": \"Protoss Pylon\", \"#FF658DC6\": \"Provence\", \"#FF8A9C99\": \"Provence Blue\", \"#FFFFEDCB\": \"Provence Creme\", \"#FF827191\": \"Provence Violet\", \"#FF5C7B8C\": \"Providence\", \"#FFA8ACA2\": \"Provincial\", \"#FF5E7B91\": \"Provincial Blue\", \"#FFF6E3DA\": \"Provincial Pink Variant\", \"#FF4C5079\": \"Provocative\", \"#FFD4C6DB\": \"Prudence\", \"#FF701C11\": \"Prune\", \"#FF211640\": \"Prune Plum\", \"#FF6C445B\": \"Prune Purple\", \"#FF864788\": \"Prunella\", \"#FFDD4492\": \"Prunus Avium\", \"#FF3F585F\": \"Prussian\", \"#FF0B085F\": \"Prussian Nights\", \"#FF6F4B5C\": \"Prussian Plum\", \"#FFDD00FF\": \"Psychedelic Purple\", \"#FF625981\": \"Psychic\", \"#FFCE5DAE\": \"P\\u00fa T\\u00e1o Z\\u01d0 Purple\", \"#FFFF1177\": \"Pucker Up\", \"#FFA0A6A0\": \"Puddle\", \"#FF6A8389\": \"Puddle Jumper\", \"#FF6E3326\": \"Pueblo Variant\", \"#FFE9786E\": \"Pueblo Rose\", \"#FFE7C3A4\": \"Pueblo Sand\", \"#FFE5DFCD\": \"Pueblo White\", \"#FF54927E\": \"Puerto Princesa\", \"#FF59BAA3\": \"Puerto Rico Variant\", \"#FF635940\": \"Puff Dragon\", \"#FFFFCBEE\": \"Puff of Pink\", \"#FFFCCF8B\": \"Puff Pastry Yellow\", \"#FFCCBFC9\": \"Puffball\", \"#FFE2DADF\": \"Puffball Vapour\", \"#FFE95C20\": \"Puffins Bill\", \"#FFD2DEF2\": \"Puffy Cloud\", \"#FFD7EDEA\": \"Puffy Little Cloud\", \"#FFE7E5DE\": \"Puffy Pillow\", \"#FF7722CC\": \"Puissant Purple\", \"#FFCBB5B2\": \"Puka Shell\", \"#FF6E8D98\": \"Pulitzer Blue\", \"#FFF1D6BC\": \"Pulled Taffy\", \"#FF3B331C\": \"Pullman Green\", \"#FFE18289\": \"Pulp\", \"#FF01678D\": \"Pulsating Blue\", \"#FF96711C\": \"Puma\", \"#FFBAC0B4\": \"Pumice Variant\", \"#FF807375\": \"Pumice Grey\", \"#FFCAC2B9\": \"Pumice Stone\", \"#FF6C462D\": \"Pumpernickel\", \"#FFF7504A\": \"Pumping Spice\", \"#FFCBA077\": \"Pumpkin Butter\", \"#FFEB7B07\": \"Pumpkin Cat\", \"#FF8D2D13\": \"Pumpkin Choco\", \"#FFE6C8A9\": \"Pumpkin Cream\", \"#FFB96846\": \"Pumpkin Drizzle\", \"#FFF7DAC0\": \"Pumpkin Essence\", \"#FF286848\": \"Pumpkin Green\", \"#FF183425\": \"Pumpkin Green Black\", \"#FFF6A379\": \"Pumpkin Hue\", \"#FFF2C3A7\": \"Pumpkin Mousse\", \"#FFFB7D07\": \"Pumpkin Orange\", \"#FFD59466\": \"Pumpkin Patch\", \"#FFE99E56\": \"Pumpkin Pie\", \"#FFEDC994\": \"Pumpkin Pie Oh My!\", \"#FFFFFDD8\": \"Pumpkin Seed\", \"#FFE17701\": \"Pumpkin Soup\", \"#FFB2691A\": \"Pumpkin Spice\", \"#FFCE862F\": \"Pumpkin Squash\", \"#FFDE9456\": \"Pumpkin Toast\", \"#FFFFA74F\": \"Pumpkin Vapour\", \"#FFE99A10\": \"Pumpkin Yellow\", \"#FFECD086\": \"Punch of Yellow\", \"#FF6888FC\": \"Punch Out Glove\", \"#FFB68692\": \"Punched Pink\", \"#FF56414D\": \"Punchit Purple\", \"#FF856B71\": \"Punctuate\", \"#FF534931\": \"Punga Variant\", \"#FF8811FF\": \"Punk Rock Pink\", \"#FFBB11AA\": \"Punk Rock Purple\", \"#FFB2485B\": \"Punky Pink\", \"#FF070303\": \"Pupil\", \"#FF79CCB3\": \"Puppeteers\", \"#FFBCAEA0\": \"Puppy\", \"#FFE2BABF\": \"Puppy Love\", \"#FFEAD2BC\": \"Puppy Paws\", \"#FFC687D6\": \"Purception\", \"#FFDFC6A5\": \"Pure Almond\", \"#FF6AB54B\": \"Pure Apple\", \"#FFE9D0C4\": \"Pure Beige\", \"#FF595652\": \"Pure Black\", \"#FF0203E2\": \"Pure Blue\", \"#FFABA093\": \"Pure Cashmere\", \"#FF36BFA8\": \"Pure Cyan\", \"#FFA79480\": \"Pure Earth\", \"#FFFAEAE1\": \"Pure Frost\", \"#FFFF2255\": \"Pure Hedonist\", \"#FFFDF5CA\": \"Pure Laughter\", \"#FF036C91\": \"Pure Light Blue\", \"#FF6F5390\": \"Pure Mauve\", \"#FF112266\": \"Pure Midnight\", \"#FFB40039\": \"Pure Passion\", \"#FFF51360\": \"Pure Pleasure\", \"#FF751973\": \"Pure Purple\", \"#FFD22D1D\": \"Pure Red\", \"#FFFFEE15\": \"Pure Sunshine\", \"#FF7ABEC2\": \"Pure Turquoise\", \"#FFF8F8F2\": \"Pure White\", \"#FF58503C\": \"Pure Woody\", \"#FF615753\": \"Pure Zeal\", \"#FF67707D\": \"Purebred\", \"#FFC74222\": \"Pureed Pumpkin\", \"#FFC3DCE9\": \"Purification\", \"#FFA8B0AE\": \"Puritan Grey\", \"#FFD7C9E3\": \"Purity\", \"#FF988EB4\": \"Purple Agate\", \"#FF9190BA\": \"Purple Amethyst\", \"#FF8866FF\": \"Purple Anemone\", \"#FFC20078\": \"Purple Anxiety\", \"#FF8F8395\": \"Purple Ash\", \"#FF9D9EB4\": \"Purple Balance\", \"#FF625B87\": \"Purple Balloon\", \"#FF5C4450\": \"Purple Basil\", \"#FF4C4A74\": \"Purple Berry\", \"#FF4A455D\": \"Purple Blanket\", \"#FF544258\": \"Purple Bloom\", \"#FF661AEE\": \"Purple Blue Variant\", \"#FF673A3F\": \"Purple Brown\", \"#FF3D34A5\": \"Purple Cabbage\", \"#FFA83A9A\": \"Purple Cactus Flower\", \"#FFC4ADC9\": \"Purple Chalk\", \"#FFB67CA2\": \"Purple Cheeks\", \"#FF8800FF\": \"Purple Climax\", \"#FF6E6970\": \"Purple Comet\", \"#FF5A4E8F\": \"Purple Corallite\", \"#FF593C50\": \"Purple Cort\", \"#FFD7CBD7\": \"Purple Cream\", \"#FFE7E7EB\": \"Purple Crystal\", \"#FF771166\": \"Purple Curse\", \"#FF835177\": \"Purple Davenport\", \"#FF63647E\": \"Purple Daze\", \"#FF331144\": \"Purple Door\", \"#FF917F84\": \"Purple Dove\", \"#FF754260\": \"Purple Drab\", \"#FFC6BEDD\": \"Purple Dragon\", \"#FF660066\": \"Purple Dreamer\", \"#FF7C6B76\": \"Purple Dusk\", \"#FF624646\": \"Purple Earth\", \"#FF6633BB\": \"Purple Emperor\", \"#FF5A4D55\": \"Purple Empire\", \"#FFEADCE2\": \"Purple Emulsion\", \"#FFC2B1C8\": \"Purple Essence\", \"#FF943589\": \"Purple Excellency\", \"#FF594670\": \"Purple Feather\", \"#FF880099\": \"Purple Feather Boa\", \"#FF85598A\": \"Purple Fluorite\", \"#FFACB0CA\": \"Purple Freedom\", \"#FF50599F\": \"Purple Frenzy\", \"#FF747582\": \"Purple Funk\", \"#FF5C4D5C\": \"Purple Fury\", \"#FFC4ABD4\": \"Purple Gala\", \"#FF8397D0\": \"Purple Gentian\", \"#FFC1ABD4\": \"Purple Gladiola\", \"#FF736993\": \"Purple Grapes\", \"#FF866F85\": \"Purple Grey\", \"#FF6A6283\": \"Purple Gumball\", \"#FF835F79\": \"Purple Gumdrop\", \"#FF807396\": \"Purple Haze\", \"#FF69359C\": \"Purple Heart Variant\", \"#FFCC2288\": \"Purple Heart Kiwi\", \"#FFBAB8D3\": \"Purple Heather\", \"#FF8773BB\": \"Purple Hebe\", \"#FFAA66FF\": \"Purple Hedonist\", \"#FFCCAAFF\": \"Purple Hepatica\", \"#FFB6ADD8\": \"Purple Hibiscus\", \"#FF8E85A7\": \"Purple Hills\", \"#FFD96CAD\": \"Purple Hollyhock\", \"#FF8855FF\": \"Purple Honeycreeper\", \"#FF6E8FC0\": \"Purple Hyacinth\", \"#FFB8B8F8\": \"Purple Illusion\", \"#FFA675FE\": \"Purple Illusionist\", \"#FF7C89AB\": \"Purple Impression\", \"#FF9A2CA0\": \"Purple Ink\", \"#FF73626F\": \"Purple Kasbah\", \"#FF512C31\": \"Purple Kite\", \"#FFCC77CC\": \"Purple Kush\", \"#FFB88AAC\": \"Purple Lepidolite\", \"#FF653475\": \"Purple Magic\", \"#FF9A8891\": \"Purple Mauve\", \"#FFDBD1E2\": \"Purple Mist\", \"#FF7A70A8\": \"Purple Mountain Majesty\", \"#FF9D81BA\": \"Purple Mountains\\u2019 Majesty\", \"#FF815989\": \"Purple Mystery\", \"#FF322C56\": \"Purple Noir\", \"#FF643E65\": \"Purple Odyssey\", \"#FF60569A\": \"Purple Opulence\", \"#FFAD4D8C\": \"Purple Orchid\", \"#FF79669D\": \"Purple Paradise\", \"#FF645E77\": \"Purple Passage\", \"#FF784674\": \"Purple Passion\", \"#FF5C2E88\": \"Purple Patch\", \"#FF452E4A\": \"Purple Pennant\", \"#FF5B4763\": \"Purple People Eater\", \"#FF903F75\": \"Purple Peril\", \"#FF9483A8\": \"Purple Phantom\", \"#FFC83CB9\": \"Purple Pink\", \"#FFBB00AA\": \"Purple Pirate\", \"#FFC7CEE8\": \"Purple Pj\\u2019s\", \"#FF81459E\": \"Purple Pleasures\", \"#FF473854\": \"Purple Plumeria\", \"#FFDAB4CC\": \"Purple Poodle\", \"#FF4C4976\": \"Purple Pool\", \"#FFAA00AA\": \"Purple Potion\", \"#FFB9A0D2\": \"Purple Premiere\", \"#FFA274B5\": \"Purple Pride\", \"#FF5B4D54\": \"Purple Prince\", \"#FF7733AA\": \"Purple Pristine\", \"#FFBB9ECA\": \"Purple Prophet\", \"#FF543254\": \"Purple Prose\", \"#FF593569\": \"Purple Prot\\u00e9g\\u00e9\", \"#FF8822DD\": \"Purple Protest\", \"#FF523E49\": \"Purple Province\", \"#FF696374\": \"Purple Punch\", \"#FFC9C6DF\": \"Purple Purity\", \"#FF8C8798\": \"Purple Ragwort\", \"#FF7442C8\": \"Purple Rain\", \"#FF990147\": \"Purple Red\", \"#FF5C4971\": \"Purple Reign\", \"#FF8278AD\": \"Purple Rhapsody\", \"#FFAF9FCA\": \"Purple Rose\", \"#FF8B7880\": \"Purple Rubiate\", \"#FF75697E\": \"Purple Sage\", \"#FFC2B2F0\": \"Purple Sand\", \"#FF754B8F\": \"Purple Sapphire\", \"#FF522A6F\": \"Purple Seduction\", \"#FF4E2E53\": \"Purple Shade\", \"#FFC8BAD4\": \"Purple Shine\", \"#FF776D90\": \"Purple Silhouette\", \"#FF62547E\": \"Purple Sky\", \"#FFCC69E4\": \"Purple Snail\", \"#FF563948\": \"Purple Sphinx\", \"#FF746F9D\": \"Purple Spire\", \"#FF5E3B6A\": \"Purple Splendour\", \"#FFAB9BBC\": \"Purple Springs\", \"#FF845998\": \"Purple Squid\", \"#FFB16D90\": \"Purple Starburst\", \"#FF6E5755\": \"Purple Statement\", \"#FFA885B5\": \"Purple Statice\", \"#FF624154\": \"Purple Stiletto\", \"#FF605467\": \"Purple Stone\", \"#FFB183A8\": \"Purple Stripe\", \"#FF766478\": \"Purple Suede\", \"#FF853682\": \"Purple Sultan\", \"#FF9B95A9\": \"Purple Surf\", \"#FF835995\": \"Purple Tanzanite\", \"#FFF0B9BE\": \"Purple Thorn\", \"#FFA22DA4\": \"Purple Tone Ink\", \"#FF665261\": \"Purple Trinket\", \"#FFC364C5\": \"Purple Urn Orchid\", \"#FF665B80\": \"Purple Valley\", \"#FFD3D5E0\": \"Purple Veil\", \"#FF581A57\": \"Purple Velour\", \"#FF483B56\": \"Purple Velvet\", \"#FF46354B\": \"Purple Verbena\", \"#FFA29CC8\": \"Purple Vision\", \"#FF442244\": \"Purple Void\", \"#FFD4C0DF\": \"Purple Whisper\", \"#FFD3C2CF\": \"Purple White\", \"#FF97397F\": \"Purple Wine\", \"#FF5A395B\": \"Purple Wineberry\", \"#FFA846D7\": \"Purple Yam\", \"#FFDD1166\": \"Purple Yearning\", \"#FFA15589\": \"Purple Zergling\", \"#FFEEC3EE\": \"Purple\\u2019s Baby Sister\", \"#FFB6C4DD\": \"Purpletini\", \"#FF837F92\": \"Purpletone\", \"#FF602287\": \"Purplex\", \"#FFC8BDD2\": \"Purpling Dawn\", \"#FF98568D\": \"Purplish\", \"#FF6140EF\": \"Purplish Blue\", \"#FF6B4247\": \"Purplish Brown\", \"#FF7A687F\": \"Purplish Grey\", \"#FFDF4EC8\": \"Purplish Pink\", \"#FFB0054B\": \"Purplish Red\", \"#FFDFD3E3\": \"Purplish White\", \"#FF5E0DC2\": \"Purplue\", \"#FF776C76\": \"Purposeful\", \"#FF8D8485\": \"Purpura\", \"#FF9A4EAE\": \"Purpureus\", \"#FF864480\": \"Purpurite Red\", \"#FF57385E\": \"Purpurite Violet\", \"#FF898078\": \"Purri Sticks\", \"#FF879F6C\": \"Purslane\", \"#FFF1D260\": \"Pursuit of Happiness\", \"#FFCEBADA\": \"Pussyfoot\", \"#FFB2ADA4\": \"Pussywillow\", \"#FFA2A193\": \"Pussywillow Grey\", \"#FFC8DDEA\": \"Put on Ice\", \"#FF8D4362\": \"Putnam Plum\", \"#FF89A572\": \"Putrid Green\", \"#FFF1E4C9\": \"Putting Bench\", \"#FF3A9234\": \"Putting Green\", \"#FFCDAE70\": \"Putty Variant\", \"#FFBDA89C\": \"Putty Grey\", \"#FFA99891\": \"Putty Pearl\", \"#FF9D8E7F\": \"Putty Yellow\", \"#FFADA2CE\": \"Puturple\", \"#FF55FF55\": \"Puyo Blob Green\", \"#FFD6D0CF\": \"Pygmy Goat\", \"#FF6299AA\": \"Pyjama Blue\", \"#FF9FBADF\": \"Pylon\", \"#FF9F7D4F\": \"Pyramid\", \"#FFE5B572\": \"Pyramid Gold\", \"#FFF8C642\": \"Pyrite\", \"#FFAC9362\": \"Pyrite Gold\", \"#FF3A6364\": \"Pyrite Green\", \"#FF867452\": \"Pyrite Slate Green\", \"#FFC4BF33\": \"Pyrite Yellow\", \"#FF3776AB\": \"Python Blue\", \"#FFFFD343\": \"Python Yellow\", \"#FF7B5804\": \"Qahvei Brown\", \"#FFCF3C71\": \"Qermez Red\", \"#FF89A0B0\": \"Qi\\u0101n H\\u016bi Grey\", \"#FF4455EE\": \"Qing Dynasty Dragon\", \"#FFDD2266\": \"Qing Dynasty Fire\", \"#FFFFCC66\": \"Qing Yellow\", \"#FFFFE989\": \"Quack Quack\", \"#FF998811\": \"Quagmire Green\", \"#FF96838B\": \"Quail\", \"#FFE3DDCE\": \"Quail Egg\", \"#FF5C4E53\": \"Quail Hollow\", \"#FFACA397\": \"Quail Ridge\", \"#FFAB9673\": \"Quail Valley\", \"#FFEACDC1\": \"Quaint Peche\", \"#FF686C62\": \"Quaking Bog\", \"#FFBBC6A4\": \"Quaking Grass\", \"#FF6E799B\": \"Quantum Blue\", \"#FFB2DDC4\": \"Quantum Effect\", \"#FF7C948B\": \"Quantum Green\", \"#FF130173\": \"Quantum of Light\", \"#FFE7F1E6\": \"Quark White\", \"#FFEBE6D5\": \"Quarried Limestone\", \"#FF8A9399\": \"Quarry\", \"#FFAF9A91\": \"Quarry Quartz\", \"#FFF2EDDD\": \"Quarter Pearl Lusta Variant\", \"#FFEBE2D2\": \"Quarter Spanish White Variant\", \"#FF1272A3\": \"Quarterdeck\", \"#FF85695B\": \"Quartersawn Oak\", \"#FFD9D9F3\": \"Quartz\", \"#FF6E7C45\": \"Quartz Green\", \"#FFFDEAE6\": \"Quartz Light Pink\", \"#FFA9AAAB\": \"Quartz Sand\", \"#FFE8E8E5\": \"Quartz Stone\", \"#FFF3E8E1\": \"Quartz White\", \"#FF232E26\": \"Quartzite\", \"#FFC7D0DA\": \"Quarzo\", \"#FFBED3CB\": \"Quaver\", \"#FFFAB001\": \"Queen Anne\", \"#FFC0B6B4\": \"Queen Anne Lilac\", \"#FFF2EEDE\": \"Queen Anne\\u2019s Lace\", \"#FFE8BC95\": \"Queen Conch Shell\", \"#FF77613D\": \"Queen Lioness\", \"#FFBBDD55\": \"Queen of Gardens\", \"#FF98333A\": \"Queen of Hearts\", \"#FF817699\": \"Queen of Sheba\", \"#FF295776\": \"Queen of the Night\", \"#FF3D4585\": \"Queen of the Night Shift\", \"#FF1C401F\": \"Queen of Trees\", \"#FFD2EAEA\": \"Queen of Waves\", \"#FFAD9E4B\": \"Queen Palm\", \"#FF6C7068\": \"Queen Valley\", \"#FF7B6FA0\": \"Queen\\u2019s\", \"#FF9D433F\": \"Queen\\u2019s Coat\", \"#FF472557\": \"Queen\\u2019s Domain\", \"#FF8B5776\": \"Queen\\u2019s Honour\", \"#FF753A40\": \"Queen\\u2019s Rose\", \"#FFD3BCC5\": \"Queen\\u2019s Tart\", \"#FFCDB9C4\": \"Queen\\u2019s Violet\", \"#FFD3ACCE\": \"Queenly\", \"#FFF9ECD0\": \"Queenly Laugh\", \"#FF652793\": \"Queens of the Dead\", \"#FF88ACE0\": \"Queer Blue\", \"#FFB36FF6\": \"Queer Purple\", \"#FFB4E0E7\": \"Quench Blue\", \"#FFE5B03D\": \"Quercitron\", \"#FFBDC1C1\": \"Quest\", \"#FFADA5A5\": \"Quest Grey\", \"#FFEF9A49\": \"Question Mark Block\", \"#FF006868\": \"Quetzal Green\", \"#FFB393C0\": \"Quibble\", \"#FFFED56F\": \"Quiche Lorraine\", \"#FFBDDBE1\": \"Quick-Freeze\", \"#FFAC9884\": \"Quicksand Variant\", \"#FF160435\": \"Quiet Abyss\", \"#FF6597CC\": \"Quiet Bay\", \"#FF017AA6\": \"Quiet Cove\", \"#FFD7D9D5\": \"Quiet Dew\", \"#FFB7D0C5\": \"Quiet Drizzle\", \"#FF9EBC97\": \"Quiet Green\", \"#FFB9BABD\": \"Quiet Grey\", \"#FF5A789A\": \"Quiet Harbour\", \"#FFDDD7CC\": \"Quiet Interlude\", \"#FFB1E2CB\": \"Quiet Jade\", \"#FFCED3C7\": \"Quiet Mint\", \"#FF96AEB0\": \"Quiet Moment\", \"#FF3E8FBC\": \"Quiet Night\", \"#FFACDEEB\": \"Quiet Nook\", \"#FFE4E2DD\": \"Quiet on the Set\", \"#FFDBA39A\": \"Quiet Pink\", \"#FF94D8E2\": \"Quiet Pond\", \"#FFE7EFCF\": \"Quiet Rain\", \"#FFB69C97\": \"Quiet Refuge\", \"#FF686970\": \"Quiet Shade\", \"#FFF5EBD6\": \"Quiet Shore\", \"#FFFAE6CA\": \"Quiet Splendour\", \"#FFEECC9F\": \"Quiet Star\", \"#FF2F596D\": \"Quiet Storm\", \"#FFA9BAB1\": \"Quiet Teal\", \"#FFAAAD94\": \"Quiet Thicket\", \"#FFB8BCB8\": \"Quiet Time\", \"#FFEBD2A7\": \"Quiet Veranda\", \"#FFB9BEA3\": \"Quiet Waters\", \"#FFF1F3E8\": \"Quiet Whisper\", \"#FFADBBB2\": \"Quietude\", \"#FFDCD2B8\": \"Quill\", \"#FFCBC9C0\": \"Quill Grey\", \"#FF2D3359\": \"Quill Tip\", \"#FF612741\": \"Quills of Terico\", \"#FF7F9DAF\": \"Quilotoa Blue\", \"#FF70A38D\": \"Quilotoa Green\", \"#FFFCD9C6\": \"Quilt\", \"#FFEAC365\": \"Quilt Gold\", \"#FFCE9FB4\": \"Quilted Heart\", \"#FFD4CB60\": \"Quince\", \"#FFF89330\": \"Quince Jelly\", \"#FF6A5445\": \"Quincy Variant\", \"#FFB5B5AF\": \"Quincy Granite\", \"#FFF9ECD1\": \"Quinoa\", \"#FFF5E326\": \"Quinoline Yellow\", \"#FF008CA9\": \"Quintana\", \"#FFC2DBC6\": \"Quintessential\", \"#FFC76356\": \"Quite Coral\", \"#FF97171E\": \"Quite Red\", \"#FF9BE510\": \"Quithayran Green\", \"#FF886037\": \"Quiver\", \"#FF8E7F6A\": \"Quiver Tan\", \"#FF948491\": \"Quixotic\", \"#FF4A4653\": \"Quixotic Plum\", \"#FF5F575C\": \"Rabbit\", \"#FF885D62\": \"Rabbit Paws\", \"#FF6225B8\": \"Rabbit-Ear Iris\", \"#FFD2C1B5\": \"Rabbit\\u2019s Foot\", \"#FF735E56\": \"Raccoon Tail\", \"#FFCF4944\": \"Race Car Stripe\", \"#FFEEF3D0\": \"Race the Sun\", \"#FFCBBEB5\": \"Race Track\", \"#FFE8B9AE\": \"Rachel Pink\", \"#FF014600\": \"Racing Green Variant\", \"#FFC21727\": \"Racing Red\", \"#FFD6341E\": \"Rackham Red\", \"#FF5D8AAA\": \"Rackley\", \"#FF776A3C\": \"Racoon Eyes\", \"#FFB6C8E4\": \"Radar\", \"#FF96F97B\": \"Radar Blip Green\", \"#FFBB9157\": \"Radiance\", \"#FFECE2CE\": \"Radiant Dawn\", \"#FF5500FF\": \"Radiant Feather\", \"#FF659C35\": \"Radiant Foliage\", \"#FFFFEED2\": \"Radiant Glow\", \"#FF10F144\": \"Radiant Hulk\", \"#FFA489A0\": \"Radiant Lilac\", \"#FFE0E6F0\": \"Radiant Moon\", \"#FFAD5E99\": \"Radiant Orchid\", \"#FFE31B5D\": \"Radiant Raspberry\", \"#FFEED5D4\": \"Radiant Rose\", \"#FFD7B1B2\": \"Radiant Rouge\", \"#FF8F979D\": \"Radiant Silver\", \"#FFF0CC50\": \"Radiant Sun\", \"#FFEEBE1B\": \"Radiant Sunrise\", \"#FFFC9E21\": \"Radiant Yellow\", \"#FFFFA343\": \"Radiation Carrot\", \"#FF326A2B\": \"Radical Green\", \"#FF745166\": \"Radicchio\", \"#FF694D3A\": \"Radigan Conagher Brown\", \"#FF89FE05\": \"Radioactive\", \"#FFF9006F\": \"Radioactive Eggplant\", \"#FF2CFA1F\": \"Radioactive Green\", \"#FF66DD00\": \"Radioactive Lilypad\", \"#FFA42E41\": \"Radish\", \"#FFEE3355\": \"Radish Lips\", \"#FFEC4872\": \"Radishical\", \"#FFE5E7E6\": \"Radisson\", \"#FFFFD15C\": \"Radler\", \"#FFF1C7A1\": \"Radome Tan\", \"#FFDCC6A0\": \"Raffia Variant\", \"#FFCDA09A\": \"Raffia Cream\", \"#FFB3A996\": \"Raffia Greige\", \"#FFCBD9D8\": \"Raffia Light Grey\", \"#FFCBB08C\": \"Raffia Ribbon\", \"#FFEEEEE3\": \"Raffia White\", \"#FFCA9A5D\": \"Raffles Tan\", \"#FF3C5F9B\": \"Raftsman\", \"#FFFF1133\": \"Rage\", \"#FFF32507\": \"Rage of Quel\\u2019Danas\", \"#FF8D514C\": \"Ragin\\u2019 Cajun\", \"#FFB54E45\": \"Raging Bull\", \"#FFDD5500\": \"Raging Leaf\", \"#FFAA3333\": \"Raging Raisin\", \"#FF8D969E\": \"Raging Sea\", \"#FF004F63\": \"Raging Thunderstorm\", \"#FF5187A0\": \"Raging Tide\", \"#FF4A5E6C\": \"Ragtime Blues\", \"#FF513933\": \"Ragtop\", \"#FF7BE892\": \"Ragweed\", \"#FFF6AD3A\": \"Raichu Orange\", \"#FF0056A8\": \"Raiden Blue\", \"#FFE34029\": \"Raiden\\u2019s Fury\", \"#FF544540\": \"Railroad Ties\", \"#FFABBEBF\": \"Rain\", \"#FF8B795F\": \"Rain Barrel\", \"#FF354D65\": \"Rain Boots\", \"#FFB6D5DE\": \"Rain Check\", \"#FF919FA1\": \"Rain Cloud\", \"#FF685346\": \"Rain Drum\", \"#FFB5DCEA\": \"Rain or Shine\", \"#FF677276\": \"Rain Shadow\", \"#FFBCA849\": \"Rain Slicker\", \"#FFC5D5E9\": \"Rain Song\", \"#FFF6BFBC\": \"Rainbow\", \"#FF2863AD\": \"Rainbow Bright\", \"#FFFF975C\": \"Rainbow Trout\", \"#FFFF09FF\": \"Rainbow\\u2019s Inner Rim\", \"#FFFF0001\": \"Rainbow\\u2019s Outer Rim\", \"#FF819392\": \"Raindance\", \"#FF9EC6C6\": \"Raindrop\", \"#FFB3C1B1\": \"Rainee Variant\", \"#FF759180\": \"Rainford\", \"#FF009A70\": \"Rainforest\", \"#FFE6DAB1\": \"Rainforest Dew\", \"#FFCEC192\": \"Rainforest Fern\", \"#FFB2C346\": \"Rainforest Glow\", \"#FF446019\": \"Rainforest Matcha\", \"#FF002200\": \"Rainforest Nights\", \"#FF016D43\": \"Rainforest Retreat\", \"#FF7F795F\": \"Rainforest Zipline\", \"#FF558484\": \"Rainier Blue\", \"#FF485769\": \"Rainmaker\", \"#FF9CA4A9\": \"Rainmaster\", \"#FF244653\": \"Rainstorm\", \"#FFC2CDC5\": \"Rainwashed\", \"#FF87D9D2\": \"Rainwater\", \"#FF889A95\": \"Rainy Afternoon\", \"#FFCFC8BD\": \"Rainy Day\", \"#FFA5A5A5\": \"Rainy Grey\", \"#FF3F6C8F\": \"Rainy Lake\", \"#FF4499AA\": \"Rainy Mood\", \"#FF005566\": \"Rainy Morning\", \"#FFD1D8D6\": \"Rainy Season\", \"#FF9BAFBB\": \"Rainy Sidewalk\", \"#FF99BBDD\": \"Rainy Week\", \"#FF5D4A4E\": \"Raisin\", \"#FF78615C\": \"Raisin in the Sun\", \"#FFE6D9E2\": \"Rajah Rose\", \"#FF957D48\": \"Raked Leaves\", \"#FFBF794E\": \"Rakuda Brown\", \"#FF7EC083\": \"Rally Green\", \"#FFB7A9AC\": \"Ramadi Grey\", \"#FF5A804F\": \"Rambling Green\", \"#FFD98899\": \"Rambling Rose\", \"#FFA94737\": \"Rambutan\", \"#FFCDBDA2\": \"Ramie\", \"#FF4C73AF\": \"Ramjet\", \"#FF8F9A88\": \"Ramona\", \"#FF603231\": \"Rampant Rhubarb\", \"#FFBCB7B1\": \"Rampart\", \"#FF195456\": \"Ramsons\", \"#FFF3E7CF\": \"Ranch Acres\", \"#FF9E7454\": \"Ranch Brown\", \"#FF7B645A\": \"Ranch House\", \"#FF968379\": \"Ranch Mink\", \"#FFC8B7A1\": \"Ranch Tan\", \"#FFDFD8B3\": \"Rancho Verde\", \"#FFB7B7B4\": \"Rand Moon\", \"#FF756E60\": \"Randall\", \"#FF68BD56\": \"Range Land\", \"#FF6A8472\": \"Ranger Green\", \"#FF707651\": \"Ranger Station\", \"#FF2B2E25\": \"Rangoon Green Variant\", \"#FFF7ECD8\": \"Ranier White\", \"#FFF5DDE6\": \"Ranunculus White\", \"#FFD28239\": \"Rapakivi Granite\", \"#FFC19A13\": \"Rapeseed\", \"#FFFFEC47\": \"Rapeseed Blossom\", \"#FFA69425\": \"Rapeseed Oil\", \"#FFA39281\": \"Rapid Rock\", \"#FF52C7C7\": \"Rapids\", \"#FFD8DFDA\": \"Rapier Silver\", \"#FF45363A\": \"Rapt\", \"#FF114444\": \"Rapture\", \"#FFA7D6DD\": \"Rapture Blue\", \"#FFCF5A70\": \"Rapture Rose\", \"#FFF6F3E7\": \"Rapture\\u2019s Light\", \"#FFF6D77F\": \"Rapunzel\", \"#FFD2D2D4\": \"Rapunzel Silver\", \"#FF0044FF\": \"Rare Blue\", \"#FFE1DEE8\": \"Rare Crystal\", \"#FFAC8044\": \"Rare Find\", \"#FFA6A69B\": \"Rare Grey\", \"#FF8DACA0\": \"Rare Happening\", \"#FFDBDCE2\": \"Rare Orchid\", \"#FFDD1133\": \"Rare Red\", \"#FFCC0022\": \"Rare Rhubarb\", \"#FF00748E\": \"Rare Turquoise\", \"#FFE8E9CC\": \"Rare White Jade\", \"#FFE8DBDF\": \"Rare White Raven\", \"#FF55FFCC\": \"Rare Wind\", \"#FF3B2736\": \"Rare Wine\", \"#FF594C42\": \"Rare Wood\", \"#FFE1E6E6\": \"Rarified Air\", \"#FFB00149\": \"Raspberry Tint\", \"#FF875169\": \"Raspberry Crush\", \"#FF8E3643\": \"Raspberry Fool\", \"#FF915F6C\": \"Raspberry Glace\", \"#FFFF77AA\": \"Raspberry Glaze\", \"#FFD9CCC7\": \"Raspberry Ice\", \"#FF9F3753\": \"Raspberry Ice Red\", \"#FFCA3767\": \"Raspberry Jam\", \"#FF9B6287\": \"Raspberry Jelly Red\", \"#FFC9A196\": \"Raspberry Kahlua\", \"#FF044F3B\": \"Raspberry Leaf Green\", \"#FFE1AAAF\": \"Raspberry Lemonade\", \"#FF9A1A60\": \"Raspberry Magenta\", \"#FFEBD2D1\": \"Raspberry Milk\", \"#FFE06F8B\": \"Raspberry Mousse\", \"#FFB96482\": \"Raspberry Parfait\", \"#FFA34F66\": \"Raspberry Patch\", \"#FF94435A\": \"Raspberry Pudding\", \"#FF882D50\": \"Raspberry Radiance\", \"#FFF62217\": \"Raspberry Rave\", \"#FFCD827D\": \"Raspberry Ripple\", \"#FF972B51\": \"Raspberry Romantic\", \"#FFB3436C\": \"Raspberry Rose Variant\", \"#FFFF3888\": \"Raspberry Shortcake\", \"#FFD0A1B4\": \"Raspberry Smoothie\", \"#FFD2386C\": \"Raspberry Sorbet\", \"#FF8A5D55\": \"Raspberry Truffle\", \"#FFB3737F\": \"Raspberry Whip\", \"#FFB63753\": \"Raspberry Wine\", \"#FF885F01\": \"Rat Brown\", \"#FF6F6138\": \"Rationality\", \"#FFA58E61\": \"Rattan\", \"#FFA79069\": \"Rattan Basket\", \"#FF8F876B\": \"Rattan Palm\", \"#FF7F7667\": \"Rattlesnake\", \"#FFC35530\": \"Raucous Orange\", \"#FF54463F\": \"Rave Raisin\", \"#FFA13B34\": \"Rave Red\", \"#FF00619D\": \"Rave Regatta\", \"#FF3D3D3D\": \"Raven Black\", \"#FF6F747B\": \"Raven Grey\", \"#FF3B3F66\": \"Raven Night\", \"#FFBB2255\": \"Raven\\u2019s Banquet\", \"#FF030205\": \"Raven\\u2019s Coat\", \"#FF4B4045\": \"Raven\\u2019s Wing\", \"#FF0A0555\": \"Ravenclaw\", \"#FF464543\": \"Ravenwood\", \"#FFD3CEC7\": \"Ravine\", \"#FFFADE79\": \"Ravioli al Limone\", \"#FFE79580\": \"Ravishing Coral\", \"#FFBB2200\": \"Ravishing Rouge\", \"#FFF2EED3\": \"Raw Alabaster\", \"#FF544173\": \"Raw Amethyst\", \"#FFC8BEB1\": \"Raw Cashew Nut\", \"#FF662200\": \"Raw Chocolate\", \"#FF7D403B\": \"Raw Cinnabar\", \"#FFC46B51\": \"Raw Copper\", \"#FFE3D4BB\": \"Raw Cotton\", \"#FF9E7172\": \"Raw Edge\", \"#FF8B6C7E\": \"Raw Garnet Viola\", \"#FFCC8844\": \"Raw Linen\", \"#FFE4BC8C\": \"Raw Peanut\", \"#FF9A6200\": \"Raw Sienna Variant\", \"#FFE1D9C7\": \"Raw Silk\", \"#FFD8CAB2\": \"Raw Sugar\", \"#FFF95D2D\": \"Raw Sunset\", \"#FFA75E09\": \"Raw Umber Variant\", \"#FF865E49\": \"Rawhide\", \"#FF7A643F\": \"Rawhide Canoe\", \"#FFFDF2C0\": \"Ray of Light\", \"#FFF4C454\": \"Rayo de Sol\", \"#FF7197CB\": \"Razee\", \"#FFD1768C\": \"Razzberries\", \"#FFE1D5D4\": \"Razzberry Fizz\", \"#FFBA417B\": \"Razzle Dazzle\", \"#FFF08101\": \"R\\u00e8 D\\u00e0i Ch\\u00e9ng Orange\", \"#FFDD484E\": \"Re-Entry\", \"#FFCD0317\": \"Re-Entry Red\", \"#FF7D5D5E\": \"Reading Tea Leaves\", \"#FF7BA570\": \"Ready Lawn\", \"#FF563D2D\": \"Real Brown\", \"#FFC1A17F\": \"Real Cork\", \"#FF00577E\": \"Real Mccoy\", \"#FFDD79A2\": \"Real Raspberry\", \"#FFA90308\": \"Real Red\", \"#FFCCB896\": \"Real Simple\", \"#FF45657D\": \"Real Teal\", \"#FF008A4C\": \"Real Turquoise\", \"#FFD3C8BD\": \"Realist Beige\", \"#FFE9EADB\": \"Really Light Green\", \"#FFE8ECDB\": \"Really Rain\", \"#FFC2B1C5\": \"Really Romantic\", \"#FF016367\": \"Really Teal\", \"#FF796C70\": \"Realm\", \"#FF114411\": \"Realm of the Underworld\", \"#FF453430\": \"Rebel Variant\", \"#FFCD4035\": \"Rebel Red\", \"#FF9B7697\": \"Rebel Rouser\", \"#FFCC0404\": \"Rebellion Red\", \"#FF28A8CD\": \"Reboot\", \"#FFBAD56B\": \"Rebounder\", \"#FF4A4E5C\": \"Receding Night\", \"#FFBAB6AB\": \"Reclaimed Wood\", \"#FFB7D7BF\": \"Reclining Green\", \"#FF1A525B\": \"Recollection Blue\", \"#FFCDB6A0\": \"Recycled\", \"#FFB7C3B7\": \"Recycled Glass\", \"#FFFF0F0F\": \"Red Alert\", \"#FFE44E4D\": \"Red Arremer\", \"#FFBB0011\": \"Red Baron\", \"#FF8E3738\": \"Red Bay\", \"#FFDD3300\": \"Red Bell Pepper\", \"#FF701F28\": \"Red Berry Variant\", \"#FF9D2B22\": \"Red Birch\", \"#FFD13B40\": \"Red Bliss\", \"#FF8A3C38\": \"Red Blooded\", \"#FF824E46\": \"Red Bluff\", \"#FFA52A2F\": \"Red Brown\", \"#FF534A77\": \"Red Cabbage\", \"#FF833C3D\": \"Red Candle\", \"#FFFF3322\": \"Red Card\", \"#FFBC2026\": \"Red Carpet\", \"#FFD87678\": \"Red Cedar\", \"#FFAD654C\": \"Red Cent\", \"#FFED7777\": \"Red Chalk\", \"#FF883543\": \"Red Chicory\", \"#FF95372D\": \"Red Chilli\", \"#FF834C3E\": \"Red Chipotle\", \"#FFC10C27\": \"Red City of Morocco\", \"#FF8F4B41\": \"Red Clay\", \"#FF77413D\": \"Red Clay Hill\", \"#FFBB8580\": \"Red Clover\", \"#FFD43E38\": \"Red Clown\", \"#FFB33234\": \"Red Contrast\", \"#FF91433E\": \"Red Craft\", \"#FFE45E32\": \"Red Cray\", \"#FF8B5E52\": \"Red Curry\", \"#FF85222B\": \"Red Dahlia\", \"#FFCB6F4A\": \"Red Damask Variant\", \"#FFBB012D\": \"Red Dead Redemption\", \"#FFBA2A1A\": \"Red Death\", \"#FFAC0000\": \"Red Door\", \"#FFE8DEDB\": \"Red Dust\", \"#FFA2816E\": \"Red Earth\", \"#FF85464B\": \"Red Elegance\", \"#FFE9DBDE\": \"Red Emulsion\", \"#FF794D60\": \"Red Endive\", \"#FFD00000\": \"Red Epiphyllum\", \"#FFC54831\": \"Red Fang\", \"#FFFF2244\": \"Red Flag\", \"#FFD76968\": \"Red Geranium\", \"#FFB07473\": \"Red Gerbera\", \"#FF604046\": \"Red Gooseberry\", \"#FFAD1400\": \"Red Gore\", \"#FFB8866E\": \"Red Gravel\", \"#FFB83312\": \"Red Gravy\", \"#FF99686A\": \"Red Grey\", \"#FFAC3A3E\": \"Red Gumball\", \"#FF8A453B\": \"Red Hawk\", \"#FFDD1144\": \"Red Herring\", \"#FF845544\": \"Red Hook\", \"#FFDD0033\": \"Red Hot\", \"#FFDB1D27\": \"Red Hot Chili Pepper\", \"#FF773C31\": \"Red Hot Jazz\", \"#FFC93543\": \"Red Icon\", \"#FFBB1E1E\": \"Red Inferno\", \"#FFAC3235\": \"Red Ink\", \"#FF783F54\": \"Red Jade\", \"#FFC01141\": \"Red Jalape\\u00f1o\", \"#FF913228\": \"Red Kite\", \"#FFDD0011\": \"Red Knuckles\", \"#FFAB4D50\": \"Red Leather\", \"#FF881400\": \"Red Leever\", \"#FFFF0055\": \"Red Light Neon\", \"#FFD24B38\": \"Red Lightning\", \"#FFBFBAC0\": \"Red Lilac Purple\", \"#FFB4090D\": \"Red Lust\", \"#FF663B43\": \"Red Mahogany\", \"#FFF95554\": \"Red Mana\", \"#FF6D3D2A\": \"Red Mane\", \"#FF834C4B\": \"Red Maple Leaf\", \"#FFAA2121\": \"Red Menace\", \"#FFC92B1E\": \"Red Mist\", \"#FFFF8888\": \"Red Mull\", \"#FF880022\": \"Red Mulled Wine\", \"#FF994341\": \"Red My Mind\", \"#FFB63731\": \"Red Obsession\", \"#FF953334\": \"Red Ochre\", \"#FF773243\": \"Red Octopus\", \"#FF473442\": \"Red Onion\", \"#FFCD6D57\": \"Red Orpiment\", \"#FF5D1F1E\": \"Red Oxide Variant\", \"#FFC34B1B\": \"Red Panda\", \"#FFBB0044\": \"Red Paracentrotus\", \"#FF82383C\": \"Red Pear\", \"#FFDD0000\": \"Red Pegasus\", \"#FFA60000\": \"Red Pentacle\", \"#FF7A3F38\": \"Red Pepper\", \"#FFF6B894\": \"Red Perfume\", \"#FF72423F\": \"Red Pines\", \"#FFFA2A55\": \"Red Pink\", \"#FF7C2949\": \"Red Plum\", \"#FF995D50\": \"Red Potato\", \"#FFDD143D\": \"Red Potion\", \"#FFD63D3B\": \"Red Power\", \"#FF8E3928\": \"Red Prairie\", \"#FFBB1100\": \"Red Prayer Flag\", \"#FFD92849\": \"Red Prickly Pear\", \"#FFEE3344\": \"Red Radish\", \"#FFEE3322\": \"Red Rampage\", \"#FF91403D\": \"Red Red Red\", \"#FF814142\": \"Red Red Wine\", \"#FF800707\": \"Red Reign\", \"#FFFFE0DE\": \"Red Remains\", \"#FFD70200\": \"Red Republic\", \"#FFA8453B\": \"Red Revival\", \"#FFCA1B1B\": \"Red Rhapsody\", \"#FFB9271C\": \"Red Rider\", \"#FFFE2713\": \"Red Riding Hood\", \"#FFB95543\": \"Red River\", \"#FF7D4138\": \"Red Robin Variant\", \"#FFA65052\": \"Red Rock\", \"#FFA27253\": \"Red Rock Falls\", \"#FFB29E9D\": \"Red Rock Panorama\", \"#FF7E5146\": \"Red Rooster\", \"#FF693F43\": \"Red Rumour\", \"#FFE5CAC0\": \"Red Sandstorm\", \"#FFCC3B22\": \"Red Sauce Parlour\", \"#FFEE0128\": \"Red Savina Pepper\", \"#FFC92D21\": \"Red Seal\", \"#FFB9090F\": \"Red Sentinel\", \"#FF862808\": \"Red Shade Wash\", \"#FFFEE0DA\": \"Red Shimmer\", \"#FF874C62\": \"Red Shrivel\", \"#FFC8756D\": \"Red Sparowes\", \"#FFAA262A\": \"Red Square\", \"#FFAD522E\": \"Red Stage Variant\", \"#FFFF2222\": \"Red Stop\", \"#FFCC1133\": \"Red Tape\", \"#FFB8383B\": \"Red Team Spirit\", \"#FFAE4930\": \"Red Terra\", \"#FF6E3637\": \"Red Theatre\", \"#FFBE0119\": \"Red Tolumnia Orchid\", \"#FF8B2E08\": \"Red Tone Ink\", \"#FFC44D4F\": \"Red Trillium\", \"#FFB41B40\": \"Red Tuna Fruit\", \"#FF783B38\": \"Red Velvet\", \"#FF5F383C\": \"Red Vine\", \"#FF9E0168\": \"Red Violet Variant\", \"#FF9F1A1D\": \"Red Vitality\", \"#FF765952\": \"Red Wattle Hog\", \"#FF885A55\": \"Red Willow\", \"#FFDB5947\": \"Red Wire\", \"#FFEE1155\": \"Red Wrath\", \"#FFE0180C\": \"Red Wrath of Zeus\", \"#FFDD1155\": \"Red-Eye\", \"#FFDD2233\": \"Red-Handed\", \"#FFA91F29\": \"Red-Hot Mama\", \"#FFCC0055\": \"Red-Letter Day\", \"#FFA27547\": \"Red-Tailed-Hawk\", \"#FFBB2211\": \"Redalicious\", \"#FF94332F\": \"Redbox\", \"#FFAD5E65\": \"Redbud\", \"#FF88455E\": \"Redcurrant\", \"#FF9C6E63\": \"Reddened Earth\", \"#FF9B4045\": \"Reddest Red\", \"#FFC44240\": \"Reddish\", \"#FFFFBB88\": \"Reddish Banana\", \"#FF433635\": \"Reddish Black\", \"#FF7F2B0A\": \"Reddish Brown\", \"#FF997570\": \"Reddish Grey\", \"#FFF8481C\": \"Reddish Orange\", \"#FFFE2C54\": \"Reddish Pink\", \"#FF910951\": \"Reddish Purple\", \"#FFFFF8D5\": \"Reddish White\", \"#FF6E1005\": \"Reddy Brown\", \"#FFAE8E7E\": \"Redend Point\", \"#FFF5D6D8\": \"Redneck\", \"#FFEA8A7A\": \"Redolenc\", \"#FF9D4E34\": \"Redridge Brown\", \"#FFA24D47\": \"Redrock Canyon\", \"#FFFF3A2D\": \"Redshift\", \"#FFE46B71\": \"Redstone\", \"#FFD90B0B\": \"Redsurrection\", \"#FFAF4544\": \"Redtail\", \"#FFE7E9D8\": \"Reduced Green\", \"#FFEFDEDF\": \"Reduced Red\", \"#FFDAECE7\": \"Reduced Turquoise\", \"#FFF0EAD7\": \"Reduced Yellow\", \"#FFE55E58\": \"Reductant\", \"#FF98010D\": \"Redwing\", \"#FF5B342E\": \"Redwood Tint\", \"#FF916F5E\": \"Redwood Forest\", \"#FFFF2200\": \"Red\\u042fum\", \"#FFB0AD96\": \"Reed Bed\", \"#FFA1A14A\": \"Reed Green\", \"#FFCD5E3C\": \"Reed Mace\", \"#FFDCC79E\": \"Reed Yellow\", \"#FFA0BCA7\": \"Reeds\", \"#FF017371\": \"Reef Variant\", \"#FF93BDCF\": \"Reef Blue\", \"#FF00968F\": \"Reef Encounter\", \"#FF0474AD\": \"Reef Escape\", \"#FFA98D36\": \"Reef Gold Variant\", \"#FFA5E1C4\": \"Reef Green\", \"#FFD1EF9F\": \"Reef Refractions\", \"#FF274256\": \"Reef Resort\", \"#FF6F9FA9\": \"Reef Waters\", \"#FFF1EAE2\": \"Refer\", \"#FF8C1B3C\": \"Refined Chianti\", \"#FF384543\": \"Refined Green\", \"#FFF1F9EC\": \"Refined Mint\", \"#FFAF6879\": \"Refined Rose\", \"#FF234251\": \"Reflecting Pond\", \"#FFDCDFDC\": \"Reflecting Pool\", \"#FFDB899E\": \"Reflecting Rose\", \"#FFD3D5D3\": \"Reflection\", \"#FFCADBDF\": \"Reflection Pool\", \"#FFA1D4C8\": \"Refresh\", \"#FFCFE587\": \"Refreshed\", \"#FF617A74\": \"Refreshing Green\", \"#FFB7E6E6\": \"Refreshing Pool\", \"#FFD7FFFE\": \"Refreshing Primer\", \"#FFEBDDA6\": \"Refreshing Tea\", \"#FFBADFCD\": \"Refrigerator Green\", \"#FF607D84\": \"Refuge\", \"#FFDAC2B3\": \"Regal\", \"#FF6A76AF\": \"Regal Azure\", \"#FF2E508A\": \"Regal Destiny\", \"#FF655777\": \"Regal Gown\", \"#FFA282A9\": \"Regal Orchid\", \"#FF99484A\": \"Regal Red\", \"#FF9D7374\": \"Regal Rose\", \"#FF749E8F\": \"Regal View\", \"#FFA298A2\": \"Regal Violet\", \"#FF7DB5D3\": \"Regale Blue\", \"#FF664480\": \"Regality\", \"#FF5382BB\": \"Regatta\", \"#FF2D5367\": \"Regatta Bay\", \"#FFE1BB87\": \"Regency Cream\", \"#FFA78881\": \"Regency Rose\", \"#FF798488\": \"Regent Grey\", \"#FFA0CDD9\": \"Regent St Blue Variant\", \"#FFD2AA92\": \"Regina Peach\", \"#FF000200\": \"Registration Black\", \"#FF009999\": \"Regula Barbara Blue\", \"#FFF7250B\": \"Reign of Tomatoes\", \"#FF76679E\": \"Reign Over Me\", \"#FFCA6C4D\": \"Reikland\", \"#FFDAC0BA\": \"Reindeer\", \"#FFBDF8A3\": \"Reindeer Moss\", \"#FFC4C7A5\": \"Rejuvenate\", \"#FFA4A783\": \"Rejuvenation\", \"#FFB9D2D3\": \"Relax\", \"#FFA8D19E\": \"Relaxation Green\", \"#FF698A97\": \"Relaxed Blue\", \"#FFC8BBA3\": \"Relaxed Khaki\", \"#FF627377\": \"Relaxed Navy\", \"#FFBBAAAA\": \"Relaxed Rhino\", \"#FF899DAA\": \"Relaxing Blue\", \"#FFE0EADB\": \"Relaxing Green\", \"#FFAC7C2E\": \"Release the Hounds\", \"#FF71713E\": \"Relentless Olive\", \"#FFE8DED3\": \"Reliable White\", \"#FF88789B\": \"Relic\", \"#FF906A3A\": \"Relic Bronze\", \"#FFBF2133\": \"Relief\", \"#FFE9DBDF\": \"Relieved Red\", \"#FFFF2288\": \"Reliquial Rose\", \"#FFB3CBAA\": \"Relish\", \"#FF8A4C38\": \"Remaining Embers\", \"#FFEFE7D6\": \"Remarkable Beige\", \"#FF974F49\": \"Rembrandt Ruby\", \"#FF8A4536\": \"Remember Me Red\", \"#FFCA9E9C\": \"Remembrance\", \"#FFA25D4C\": \"Remington Rust\", \"#FFEBC8B8\": \"Renaissance Fresco\", \"#FF865560\": \"Renaissance Rose\", \"#FF820747\": \"Renanthera Orchid\", \"#FF9B4B20\": \"Rendang\", \"#FFABBED0\": \"Rendez-Blue\", \"#FF8F968B\": \"Renegade\", \"#FF9CB8B5\": \"Renew Blue\", \"#FFB55233\": \"Renga Brick\", \"#FF989F7A\": \"Renkon Beige\", \"#FFB87F84\": \"Rennie\\u2019s Rose\", \"#FFB26E33\": \"Reno Sand Variant\", \"#FFDABE9F\": \"Renoir Bisque\", \"#FFC3B09D\": \"Renwick Beige\", \"#FF504E47\": \"Renwick Brown\", \"#FF96724C\": \"Renwick Golden Oak\", \"#FF8B7D7B\": \"Renwick Heather\", \"#FF97896A\": \"Renwick Olive\", \"#FFAF8871\": \"Renwick Rose Beige\", \"#FFCCC9C0\": \"Repose Grey\", \"#FF24DA91\": \"Reptile Green\", \"#FF5E582B\": \"Reptile Revenge\", \"#FF009E82\": \"Reptilian Green\", \"#FF8F9961\": \"Reptilian Leader\", \"#FFDE0100\": \"Republican\", \"#FF4E3F44\": \"Requiem\", \"#FFB9B2A9\": \"Requisite Grey\", \"#FF9DA98C\": \"Reseda\", \"#FF75946B\": \"Reseda Green\", \"#FF8C7544\": \"Reservation\", \"#FFAC8A98\": \"Reserve\", \"#FFE2E1D6\": \"Reserved Beige\", \"#FFD2D8DE\": \"Reserved Blue\", \"#FFE0E0D9\": \"Reserved White\", \"#FF01638B\": \"Reservoir\", \"#FF85B0C4\": \"Resolute Blue\", \"#FF01A2C6\": \"Resonant Blue\", \"#FFF4D7C5\": \"Resort Sunrise\", \"#FF907D66\": \"Resort Tan\", \"#FFF4F1E4\": \"Resort White\", \"#FFCD8E89\": \"Resounding Rose\", \"#FF97B4C3\": \"Respite\", \"#FFB4A8B1\": \"Resplendent\", \"#FF3D8B37\": \"Resplendent Growth\", \"#FF9BBFC9\": \"Rest Assured\", \"#FFBBBBA4\": \"Restful\", \"#FF8C7E6F\": \"Restful Brown\", \"#FFF1F2DD\": \"Restful Rain\", \"#FFB1C7C9\": \"Restful Retreat\", \"#FFEEE8D7\": \"Restful White\", \"#FFBCC8BE\": \"Resting Place\", \"#FF38515D\": \"Restless Sea\", \"#FF939581\": \"Restoration\", \"#FFE9E1CA\": \"Restoration Ivory\", \"#FFD2B084\": \"Restrained Gold\", \"#FFD9CDC3\": \"Reticence\", \"#FFB6C7E0\": \"Retina Soft Blue\", \"#FFD5EAE8\": \"Retiring Blue\", \"#FF7A8076\": \"Retreat\", \"#FFC39E81\": \"Retributor Armour Metal\", \"#FF9BDC96\": \"Retro\", \"#FF958D45\": \"Retro Avocado\", \"#FF2B62F4\": \"Retro Blue\", \"#FF19CC89\": \"Retro Lime\", \"#FF9FCDB1\": \"Retro Mint\", \"#FFEF7D16\": \"Retro Nectarine\", \"#FFE85112\": \"Retro Orange\", \"#FFE7C0AD\": \"Retro Peach\", \"#FFB48286\": \"Retro Pink\", \"#FFFF0073\": \"Retro Pink Pop\", \"#FFCB9711\": \"Retro Vibe\", \"#FF5A758A\": \"Retro-Colonial Blue\", \"#FF936630\": \"Retrofit\", \"#FF4C6B8A\": \"Revel Blue\", \"#FF67B8CE\": \"Revelry Blue\", \"#FFC59782\": \"Revenant Brown\", \"#FF8A7C75\": \"Revere Greige\", \"#FFA78FAF\": \"Revered\", \"#FFF4E5E1\": \"Reverie Pink\", \"#FF080808\": \"Reversed Grey\", \"#FF5F81A4\": \"Revival\", \"#FF665043\": \"Revival Mahogany\", \"#FF7F4E47\": \"Revival of the Red\", \"#FFC09084\": \"Revival Rose\", \"#FFE8E097\": \"Reviving Green\", \"#FF37363F\": \"Revolver Variant\", \"#FFB46848\": \"Reynard\", \"#FFDC9E94\": \"Rhapsodic\", \"#FF9C83A8\": \"Rhapsody\", \"#FF002244\": \"Rhapsody in Blue\", \"#FFBABFDC\": \"Rhapsody Lilac\", \"#FF74676C\": \"Rhapsody Rap\", \"#FF969565\": \"Rhind Papyrus\", \"#FF5F5E5F\": \"Rhine Castle\", \"#FFE3EADB\": \"Rhine Falls\", \"#FFAB3560\": \"Rhine River Rose\", \"#FFC87291\": \"Rhine Wine\", \"#FF8E6C94\": \"Rhinestone\", \"#FF3D4653\": \"Rhino Variant\", \"#FFD4A278\": \"Rhino Tusk\", \"#FF727A7C\": \"Rhinoceros\", \"#FF440011\": \"Rhinoceros Beetle\", \"#FF493435\": \"Rhinox Hide\", \"#FF9B5B55\": \"Rhode Island Red\", \"#FF89C0E6\": \"Rhodes\", \"#FF7D2F45\": \"Rhododendron\", \"#FFF3B3C5\": \"Rhodonite\", \"#FF4D4141\": \"Rhodonite Brown\", \"#FF330018\": \"Rhodophobia\", \"#FF7F222E\": \"Rhubarb\", \"#FFD9A6C1\": \"Rhubarb Gin\", \"#FFBCA872\": \"Rhubarb Leaf Green\", \"#FFD78187\": \"Rhubarb Pie\", \"#FF8C474B\": \"Rhubarb Smoothie\", \"#FFCB7841\": \"Rhumba Orange\", \"#FF383867\": \"Rhynchites Nitens\", \"#FFBECEB4\": \"Rhys\", \"#FF767194\": \"Rhythm Variant\", \"#FF70767B\": \"Rhythm & Blues\", \"#FFB8D5D7\": \"Rhythmic Blue\", \"#FF914D57\": \"Rialto\", \"#FFF1E7D5\": \"Rice Bowl\", \"#FFEFECDE\": \"Rice Cake Variant\", \"#FFE0CCB6\": \"Rice Crackers\", \"#FFB2854A\": \"Rice Curry\", \"#FFE4D8AB\": \"Rice Fibre\", \"#FFEFF5D1\": \"Rice Flower Variant\", \"#FFDFD4B0\": \"Rice Paddy\", \"#FFFFFCDB\": \"Rice Paper\", \"#FFFFF0E3\": \"Rice Pudding\", \"#FFF5E7C8\": \"Rice Wine\", \"#FF977540\": \"Rich and Rare\", \"#FF948165\": \"Rich Biscuit\", \"#FF021BF9\": \"Rich Blue\", \"#FF514142\": \"Rich Bordeaux\", \"#FF925850\": \"Rich Brocade\", \"#FF715E4F\": \"Rich Brown\", \"#FFD70041\": \"Rich Carmine Variant\", \"#FF6F4136\": \"Rich Chocolate\", \"#FFBF7D52\": \"Rich Copper\", \"#FFFAEAC3\": \"Rich Cream\", \"#FFF57F4F\": \"Rich Gardenia\", \"#FFDE7A63\": \"Rich Georgia Clay\", \"#FFFFE8A0\": \"Rich Glow\", \"#FFAA8833\": \"Rich Gold Variant\", \"#FF218845\": \"Rich Green\", \"#FF324943\": \"Rich Grey Turquoise\", \"#FFF9BC7D\": \"Rich Honey\", \"#FFFFF0C4\": \"Rich Ivory\", \"#FF583D37\": \"Rich Loam\", \"#FF604944\": \"Rich Mahogany\", \"#FFB0306A\": \"Rich Maroon\", \"#FF745342\": \"Rich Mocha\", \"#FFA7855A\": \"Rich Oak\", \"#FF3E4740\": \"Rich Olive\", \"#FF6B7172\": \"Rich Pewter\", \"#FFB5C9D3\": \"Rich Porcelain Blue\", \"#FF720058\": \"Rich Purple\", \"#FFFF1144\": \"Rich Red\", \"#FF7C3651\": \"Rich Red Violet\", \"#FFB9A37F\": \"Rich Reward\", \"#FFA87C3E\": \"Rich Sorrel\", \"#FFB39C89\": \"Rich Taupe\", \"#FF645671\": \"Rich Texture\", \"#FF50578B\": \"Rich Violet\", \"#FF7C5F4A\": \"Rich Walnut\", \"#FF854C47\": \"Richardson Brick\", \"#FFA6A660\": \"Rickrack\", \"#FF817C74\": \"Ricochet\", \"#FFF3CF64\": \"Ride off Into the Sunset\", \"#FFB2C8DD\": \"Ridge Light\", \"#FFA3AAB8\": \"Ridge View\", \"#FFEF985C\": \"Ridgeback\", \"#FF9D8861\": \"Ridgecrest\", \"#FF7A5D46\": \"Ridgeline\", \"#FF734A35\": \"Riding Boots\", \"#FFA0A197\": \"Riding Star\", \"#FFBFB065\": \"Riesling Grape\", \"#FFB2B3A7\": \"Rigani\", \"#FFA0A082\": \"Rigby Ridge\", \"#FFC0E1E4\": \"Right as Rain\", \"#FF534A32\": \"Rikan Brown\", \"#FF826B58\": \"Riky\\u016b Brown\", \"#FF656255\": \"Riky\\u016bnezumi Brown\", \"#FFB0927A\": \"Riky\\u016bshira Brown\", \"#FFC7B39E\": \"Rincon Cove\", \"#FFB4D9D8\": \"Ring Box Blue\", \"#FFFBEDBE\": \"Ringlet\", \"#FFD5D9DD\": \"Rinse\", \"#FFFF7952\": \"Rinsed-Out Red\", \"#FFB7C61A\": \"Rio Grande Variant\", \"#FF92242E\": \"Rio Red\", \"#FF926956\": \"Rio Rust\", \"#FFCAE1DA\": \"Rio Sky\", \"#FFDFAB56\": \"Rip Cord\", \"#FF8FA4D2\": \"Rip Van Periwinkle\", \"#FF94312F\": \"Ripasso\", \"#FFCF9D41\": \"Ripe Banana\", \"#FF5C5666\": \"Ripe Berry\", \"#FFFBB363\": \"Ripe Cantaloupe\", \"#FFC3556F\": \"Ripe Cherry\", \"#FF8A3C3E\": \"Ripe Currant\", \"#FF492D35\": \"Ripe Eggplant\", \"#FF6A5254\": \"Ripe Fig\", \"#FF747A2C\": \"Ripe Green\", \"#FFA259CE\": \"Ripe Lavander\", \"#FFF5576C\": \"Ripe Malinka\", \"#FFFFC324\": \"Ripe Mango\", \"#FF62465B\": \"Ripe Mulberry\", \"#FF44483D\": \"Ripe Olive\", \"#FFBE6A3C\": \"Ripe Peach\", \"#FFE1E36E\": \"Ripe Pear\", \"#FFFFE07B\": \"Ripe Pineapple\", \"#FFFFAF37\": \"Ripe Pumpkin\", \"#FF7E3947\": \"Ripe Rhubarb\", \"#FFE3C494\": \"Ripe Wheat\", \"#FF6F3942\": \"Ripening Grape\", \"#FFD3DCDC\": \"Ripple\", \"#FFC4C5BC\": \"Rippled Rock\", \"#FFC4BEA8\": \"Rippling Stone\", \"#FF89D9C8\": \"Riptide Variant\", \"#FFFFE99E\": \"Rise and Shine\", \"#FF978888\": \"Rising Ash\", \"#FFF7F6D5\": \"Rising Star\", \"#FFCBD6D8\": \"Rising Tide\", \"#FF6A7E88\": \"Risk-Reward\", \"#FFF8F5E9\": \"Risotto\", \"#FF00AA55\": \"Rita Repulsa\", \"#FFBA7176\": \"Rita\\u2019s Rouge\", \"#FFFFEBA9\": \"Rite of Spring\", \"#FF293286\": \"Ritterlich Blue\", \"#FF767081\": \"Ritual\", \"#FF533844\": \"Ritual Experience\", \"#FFD79C5F\": \"Ritzy\", \"#FF38AFCD\": \"River Blue\", \"#FFC7B5A9\": \"River Clay\", \"#FF545B45\": \"River Forest\", \"#FF248591\": \"River Fountain\", \"#FF6C6C5F\": \"River God\", \"#FFD6E1D4\": \"River Mist\", \"#FFA08B71\": \"River Mud\", \"#FFAE9474\": \"River Oak\", \"#FFE4B55D\": \"River of Gold\", \"#FFA39C92\": \"River Pebble\", \"#FFDEDBC4\": \"River Reed\", \"#FFAE8D6B\": \"River Road\", \"#FFD8CDC4\": \"River Rock\", \"#FFEC9B9D\": \"River Rouge\", \"#FFDFDCD5\": \"River Shark\", \"#FF161820\": \"River Styx\", \"#FF848B99\": \"River Tour\", \"#FF94A5B7\": \"River Valley\", \"#FFD9E0DE\": \"River Veil\", \"#FFAE9E87\": \"Riverbank\", \"#FF86BEBE\": \"Riverbed\", \"#FF486B65\": \"Riverbend\", \"#FFBEC5BA\": \"Riverdale\", \"#FF84A27B\": \"Rivergrass\", \"#FFAFD9D7\": \"Rivers Edge\", \"#FF4E6F95\": \"Riverside\", \"#FF6CB4C3\": \"Riverside Blue\", \"#FF757878\": \"Riverstone\", \"#FF5D7274\": \"Riverway\", \"#FFB7A9A2\": \"Riveter Rose\", \"#FF189FAC\": \"Riviera\", \"#FFC0AE96\": \"Riviera Beach\", \"#FF65B4D8\": \"Riviera Blue\", \"#FFC9A88D\": \"Riviera Clay\", \"#FFE6D9CA\": \"Riviera Dune\", \"#FF009A9E\": \"Riviera Paradise\", \"#FFD9C0A6\": \"Riviera Retreat\", \"#FFF7B1A6\": \"Riviera Rose\", \"#FFDFC6A0\": \"Riviera Sand\", \"#FF1B8188\": \"Riviera Sea\", \"#FFD5DAE1\": \"Rivulet\", \"#FF605655\": \"Rix\", \"#FF8B7B6E\": \"Road Less-Travelled\", \"#FFC8C0B7\": \"Roadrunner\", \"#FFADA493\": \"Roadside\", \"#FFE1E0D7\": \"Roadster White\", \"#FFF3DEA2\": \"Roadster Yellow\", \"#FF857373\": \"Roaming Pony\", \"#FF885156\": \"Roan Rouge\", \"#FF372B25\": \"Roanoke\", \"#FF8F837D\": \"Roanoke Taupe\", \"#FFB39C9E\": \"Roaring Twenties\", \"#FF704341\": \"Roast Coffee\", \"#FF785246\": \"Roasted\", \"#FFD2B49C\": \"Roasted Almond\", \"#FF655A5C\": \"Roasted Black\", \"#FFEA993B\": \"Roasted Chestnut\", \"#FFAB8C72\": \"Roasted Coconut\", \"#FF684134\": \"Roasted Coffee\", \"#FFAF967D\": \"Roasted Hazelnut\", \"#FF574037\": \"Roasted Kona\", \"#FF604D42\": \"Roasted Nuts\", \"#FF93542B\": \"Roasted Pecan\", \"#FF890A01\": \"Roasted Pepper\", \"#FFC9B27C\": \"Roasted Pistachio\", \"#FFE1A175\": \"Roasted Seeds\", \"#FF625342\": \"Roasted Sepia\", \"#FFFEC36B\": \"Roasted Sesame\", \"#FFEA7E5D\": \"Roasted Sienna\", \"#FFE6A255\": \"Roasted Squash\", \"#FF692302\": \"Roastery\", \"#FFDDAD56\": \"Rob Roy Variant\", \"#FF654F4F\": \"Robeson Rose\", \"#FF6DEDFD\": \"Robin\\u2019s Egg\", \"#FFABC3CA\": \"Robin\\u2019s Pride\", \"#FF6E6A3B\": \"Robinhood\", \"#FFADADAD\": \"Robo Master\", \"#FFEEEE11\": \"Robot Grendizer Gold\", \"#FF94A2B1\": \"Robotic Gods\", \"#FFC4633E\": \"Robust Orange\", \"#FF5A4D41\": \"Rock Variant\", \"#FF93A2BA\": \"Rock Blue Variant\", \"#FF484C49\": \"Rock Bottom\", \"#FFDEE1DF\": \"Rock Candy\", \"#FFC0AF92\": \"Rock Cliffs\", \"#FF688082\": \"Rock Creek\", \"#FFCECBCB\": \"Rock Crystal\", \"#FF465448\": \"Rock Garden\", \"#FFF00B52\": \"Rock Lobster\", \"#FFA1968C\": \"Rock Slide\", \"#FFBDC2BD\": \"Rock Solid\", \"#FF9D442D\": \"Rock Spray Variant\", \"#FFC58BBA\": \"Rock Star Pink\", \"#FF8B785C\": \"Rock\\u2019n Oak\", \"#FFFC8AAA\": \"Rock\\u2019n\\u2019Rose\", \"#FF6C7186\": \"Rockabilly\", \"#FFF4E4E0\": \"Rockabye Baby\", \"#FFFEFBE5\": \"Rocket Fuel\", \"#FFBEBEC3\": \"Rocket Man\", \"#FFFF3311\": \"Rocket Science\", \"#FFAABBAA\": \"Rockfall\", \"#FFBC363C\": \"Rockin Red\", \"#FF721F37\": \"Rocking Chair\", \"#FF90413D\": \"Rocking Chair Red\", \"#FF31A2F2\": \"Rockman Blue\", \"#FFD3E0B1\": \"Rockmelon Rind\", \"#FF519EA1\": \"Rockpool\", \"#FF8E7D62\": \"Rocks of Normandy\", \"#FF6D7E42\": \"Rockwall Vine\", \"#FF443735\": \"Rockweed\", \"#FFC8E0BA\": \"Rockwood Jade\", \"#FFB3AEA8\": \"Rocky Bluffs\", \"#FFBABBAD\": \"Rocky Cliff\", \"#FF3E4D50\": \"Rocky Creek\", \"#FF567B8A\": \"Rocky Hill\", \"#FFA9867D\": \"Rocky Mountain\", \"#FFD4D4D2\": \"Rocky Mountain Mist\", \"#FF76443E\": \"Rocky Mountain Red\", \"#FFB5BFBD\": \"Rocky Mountain Sky\", \"#FFB27A47\": \"Rocky Racoon\", \"#FF918C86\": \"Rocky Ridge\", \"#FF5E706A\": \"Rocky River\", \"#FF64453C\": \"Rocky Road\", \"#FFB8BABA\": \"Rocky Shelter\", \"#FFC33846\": \"Rococco Red\", \"#FFDFD6C1\": \"Rococo Beige\", \"#FF977447\": \"Rococo Gold\", \"#FFFDDC5C\": \"Rodan Gold\", \"#FF7F5E46\": \"Rodeo\", \"#FFC7A384\": \"Rodeo Dust Variant\", \"#FFA24B3A\": \"Rodeo Red\", \"#FFA68E6D\": \"Rodeo Roundup\", \"#FFA78B74\": \"Rodeo Tan\", \"#FFB2B26C\": \"Rodham\", \"#FFA68370\": \"Roebuck\", \"#FF883311\": \"Rogan Josh\", \"#FF807A6C\": \"Rogue\", \"#FF4B5764\": \"Rogue Blue\", \"#FFBA9E88\": \"Rogue Cowboy\", \"#FFF8A4C0\": \"Rogue Pink\", \"#FF4E7376\": \"Rogue Waters\", \"#FF734A45\": \"Rohwurst\", \"#FFB57466\": \"Rojo Dust\", \"#FF4B3029\": \"Rojo Marr\\u00f3n\", \"#FF8D4942\": \"Rojo Oxide\", \"#FF665343\": \"Rok\\u014d Brown\", \"#FF8C7042\": \"Rokou Brown\", \"#FF407A52\": \"Rokush\\u014d Green\", \"#FFBB5522\": \"Roland-Garros\", \"#FF8C8578\": \"Roller Coaster\", \"#FF0078BE\": \"Roller Coaster Chariot\", \"#FF8CFFDB\": \"Roller Derby\", \"#FF6D5698\": \"Rollick\", \"#FFA9BE9E\": \"Rolling Glen\", \"#FF7C7E6A\": \"Rolling Hills\", \"#FFA09482\": \"Rolling Pebble\", \"#FFA29367\": \"Rolling Prairie\", \"#FF5A6D77\": \"Rolling Sea\", \"#FF6D7876\": \"Rolling Stone Variant\", \"#FFBFD1C9\": \"Rolling Waves\", \"#FFC0D2AD\": \"Romaine\", \"#FFA38E00\": \"Romaine Green\", \"#FFD8625B\": \"Roman Variant\", \"#FF8C97A3\": \"Roman Bath\", \"#FFAB7F5B\": \"Roman Brick\", \"#FF514100\": \"Roman Bronze\", \"#FF7D6757\": \"Roman Coffee Variant\", \"#FFAC8760\": \"Roman Coin\", \"#FFF6F0E2\": \"Roman Column\", \"#FFEE1111\": \"Roman Empire Red\", \"#FFD19B2F\": \"Roman Gold\", \"#FFDAD1CE\": \"Roman Mosaic\", \"#FFDDD2BF\": \"Roman Plaster\", \"#FF524765\": \"Roman Purple\", \"#FFC0B5A0\": \"Roman Ruins\", \"#FFA49593\": \"Roman Snail\", \"#FF4D517F\": \"Roman Violet\", \"#FFB0ADA0\": \"Roman Wall\", \"#FFDEEDEB\": \"Roman White\", \"#FFF4F0E6\": \"Romance Variant\", \"#FF7983A4\": \"Romanesque\", \"#FFD0AF7A\": \"Romanesque Gold\", \"#FF3B0346\": \"Romanic Scene\", \"#FFB97DA8\": \"Romanov Mauve\", \"#FFFFC69E\": \"Romantic Variant\", \"#FFE0BEDF\": \"Romantic Ballad\", \"#FFE7E0EE\": \"Romantic Cruise\", \"#FFEED1CD\": \"Romantic D\\u00e9j\\u00e0 Vu\", \"#FFB23E4F\": \"Romantic Embers\", \"#FFA497A1\": \"Romantic Holiday\", \"#FF007C75\": \"Romantic Isle\", \"#FF9076AE\": \"Romantic Moment\", \"#FFFCD5CB\": \"Romantic Morn\", \"#FFDDBBDD\": \"Romantic Morning\", \"#FF96353A\": \"Romantic Night\", \"#FFCAC0CE\": \"Romantic Poetry\", \"#FFAA4488\": \"Romantic Rose\", \"#FFA2101B\": \"Romantic Thriller\", \"#FF991166\": \"Romantic Vampire\", \"#FFDACFC5\": \"Romantic White\", \"#FFE3D2CE\": \"Romeo\", \"#FFA4233C\": \"Romeo O Romeo\", \"#FFF48101\": \"Romesco\", \"#FF983D48\": \"Romp\", \"#FFDFC1A8\": \"Romulus\", \"#FFEAB852\": \"Ronchi Variant\", \"#FFA60044\": \"Rondo of Blood\", \"#FFA14743\": \"Roof Terracotta Variant\", \"#FF043132\": \"Roof Tile Green\", \"#FF9EAD92\": \"Rooftop Garden\", \"#FFAE3C29\": \"Rooibos Tea\", \"#FFC08650\": \"Rookwood Amber\", \"#FFA58258\": \"Rookwood Antique Gold\", \"#FF738478\": \"Rookwood Blue Green\", \"#FF7F614A\": \"Rookwood Brown\", \"#FF9A7E64\": \"Rookwood Clay\", \"#FF5F4D43\": \"Rookwood Dark Brown\", \"#FF565C4A\": \"Rookwood Dark Green\", \"#FF4B2929\": \"Rookwood Dark Red\", \"#FF979F7F\": \"Rookwood Jade\", \"#FF6E5241\": \"Rookwood Medium Brown\", \"#FF622F2D\": \"Rookwood Red\", \"#FF506A67\": \"Rookwood Sash Green\", \"#FF303B39\": \"Rookwood Shutter Green\", \"#FF975840\": \"Rookwood Terra Cotta\", \"#FF96463F\": \"Rooster Comb\", \"#FF81544A\": \"Root Beer\", \"#FFCFA46B\": \"Root Beer Float\", \"#FF290E05\": \"Root Brew\", \"#FF6B3226\": \"Root Brown\", \"#FFC83A40\": \"Root Chakra\", \"#FF5F4F3E\": \"Rooted\", \"#FF4E3C32\": \"Rootstock\", \"#FF8E593C\": \"Rope Variant\", \"#FFFE86A4\": \"Rosa\", \"#FFEFD9E1\": \"Rosa Bonito\", \"#FFC77579\": \"Rosa Chinensis\", \"#FFF0E3DF\": \"Rosa Vieja\", \"#FFA38887\": \"Rosaline Pearl\", \"#FFFAEADD\": \"Rosarian\", \"#FFD9BEBB\": \"Rosario Ridge\", \"#FF998871\": \"Roscoe Village\", \"#FFF7746B\": \"Ros\\u00e9\", \"#FFB5ACAB\": \"Rose Ashes\", \"#FFF1C6CA\": \"Rose Aspect\", \"#FFE3CBC4\": \"Rose Beige\", \"#FFC6A499\": \"Rose Bisque\", \"#FF80565B\": \"Rose Branch\", \"#FF996C6E\": \"Rose Brocade\", \"#FFBC8E8F\": \"Rose Brown\", \"#FFF0738A\": \"Rose Cheeks\", \"#FFDAB09E\": \"Rose Cloud\", \"#FFDCB6B5\": \"Rose Coloured\", \"#FFE5C4C0\": \"Rose Coloured Glasses\", \"#FFEFE0DE\": \"Rose Cream\", \"#FFFF9EDE\": \"Rose Daphne\", \"#FFB38380\": \"Rose Dawn\", \"#FFCB8E81\": \"Rose de Mai\", \"#FFE099AD\": \"Rose Delight\", \"#FFEECFFE\": \"Rose Drag\\u00e9e\", \"#FFE5A192\": \"Rose Dusk\", \"#FFCDB2A5\": \"Rose Dust Variant\", \"#FFE9A1B8\": \"Rose Elegance\", \"#FFC59EA1\": \"Rose Embroidery\", \"#FFF29B89\": \"Rose Essence\", \"#FFF1E8EC\": \"Rose Fantasy\", \"#FFFFECE9\": \"Rose Frost\", \"#FFF96653\": \"Rose Fusion\", \"#FFDA9EC8\": \"Rose Garden\", \"#FF865A64\": \"Rose Garland\", \"#FF960145\": \"Rose Garnet\", \"#FFE585A5\": \"Rose Glory\", \"#FFFFDBEB\": \"Rose Glow\", \"#FFECC5C0\": \"Rose Haze\", \"#FFDBB9B6\": \"Rose Hip Tonic\", \"#FFA6465B\": \"Rose Laffy Taffy\", \"#FFE8AEA2\": \"Rose Linen\", \"#FFECD7C6\": \"Rose Lotion\", \"#FFE33636\": \"Rose Madder\", \"#FFF4AAC7\": \"Rose Mallow\", \"#FFCEB9C4\": \"Rose Marble\", \"#FFA76464\": \"Rose Marquee\", \"#FFDD94A1\": \"Rose Marquis\", \"#FFAF9690\": \"Rose Mauve\", \"#FFC4989E\": \"Rose Meadow\", \"#FFECBFC9\": \"Rose Melody\", \"#FFF6D2D4\": \"Rose Milk\", \"#FFFFE9ED\": \"Rose Mochi\", \"#FFAC512D\": \"Rose of Sharon Variant\", \"#FFDFD4CC\": \"Rose Pearl\", \"#FFE6C1BB\": \"Rose Petal\", \"#FF7C383E\": \"Rose Pink Villa\", \"#FFC9A59F\": \"Rose Potpourri\", \"#FFD0A29E\": \"Rose Pottery\", \"#FFF7CAC1\": \"Rose Quartz Variant\", \"#FFC92351\": \"Rose Red\", \"#FFF4C0C6\": \"Rose Reminder\", \"#FFDD2255\": \"Rose Rush\", \"#FFCE858F\": \"Rose Sachet\", \"#FFF9C2CD\": \"Rose Shadow\", \"#FFE7AFA8\": \"Rose Silk\", \"#FFCEADA3\": \"Rose Smoke\", \"#FFE08395\": \"Rose Soiree\", \"#FFFBD3CD\": \"Rose Sorbet\", \"#FFC290C5\": \"Rose Souvenir\", \"#FFD3B6BA\": \"Rose Stain\", \"#FFFAE6E5\": \"Rose Sugar\", \"#FFFAE8E1\": \"Rose Tan\", \"#FFE1A890\": \"Rose Tattoo\", \"#FFB48993\": \"Rose Tea\", \"#FFFFDDDD\": \"Rose Tonic\", \"#FFAB4E5F\": \"Rose Vale Variant\", \"#FFF2DBD6\": \"Rose Vapour\", \"#FFC44D97\": \"Rose Violet\", \"#FFFBEEE8\": \"Rose White Variant\", \"#FF9D5C75\": \"Rose Wine\", \"#FFD9BCB7\": \"Rose Yoghurt\", \"#FFF7E5DB\": \"Roseate\", \"#FFE7B6BC\": \"Roseate Hues\", \"#FFE0ADC4\": \"Roseate Spoonbill\", \"#FFCB9AAD\": \"Rosebay\", \"#FFF4A6A1\": \"Roseberry\", \"#FFE290B2\": \"Rosebloom\", \"#FFE0CDD1\": \"Rosebud\", \"#FF8A2D52\": \"Rosebud Cherry\", \"#FFEEBBDD\": \"Rosecco\", \"#FF7B7FA9\": \"Roseine Plum\", \"#FF926566\": \"Roseland\", \"#FFF0DEE4\": \"Roselle\", \"#FF819B4F\": \"Rosemarried\", \"#FF405E5C\": \"Rosemary\", \"#FF699B72\": \"Rosemary Green\", \"#FF626A52\": \"Rosemary Sprig\", \"#FFDFE3DB\": \"Rosemary White\", \"#FFBC8A90\": \"Rosenkavalier\", \"#FFAA3646\": \"Roses Are Red\", \"#FFE7AECD\": \"Roses in the Snow\", \"#FFBA8F7F\": \"Rosetta\", \"#FFCE8E8B\": \"Rosette\", \"#FFD7A491\": \"Rosettee\", \"#FFCF929A\": \"Rosetti\", \"#FFD8A2A5\": \"Rosetti Pink\", \"#FFB495B0\": \"Roseville\", \"#FFF6DBD8\": \"Rosewater\", \"#FFD39EA2\": \"Rosewood Apricot\", \"#FF72371C\": \"Rosewood Brown\", \"#FFEBBEB5\": \"Rosewood Dreams\", \"#FFFAC8CE\": \"Rosey Afterglow\", \"#FFFFBBCC\": \"Rosie\", \"#FFEFE4E9\": \"Rosie Posie\", \"#FFBE7583\": \"Rosily\", \"#FF39382F\": \"Rosin\", \"#FFB319AB\": \"Rosolanc Purple\", \"#FFC4091E\": \"Rossini Red\", \"#FFBE89A8\": \"Rosy\", \"#FFD8B3B9\": \"Rosy Aura\", \"#FFDC506E\": \"Rosy Cheeks\", \"#FFFEDECD\": \"Rosy Cloud\", \"#FFCF8974\": \"Rosy Copper\", \"#FFCC77FF\": \"Rosy Fluffy Bedspread\", \"#FFE7C0BC\": \"Rosy Glow\", \"#FFF7D994\": \"Rosy Highlight\", \"#FFD7C7D0\": \"Rosy Lavender\", \"#FFC6B4B2\": \"Rosy Linen\", \"#FFFEC9ED\": \"Rosy Maple Moth\", \"#FFF2C2E1\": \"Rosy Nectar\", \"#FFF5AB9E\": \"Rosy Outlook\", \"#FFD38469\": \"Rosy Pashmina\", \"#FFF6688E\": \"Rosy Pink\", \"#FFCF9384\": \"Rosy Queen\", \"#FF735551\": \"Rosy Sandstone\", \"#FFF7B978\": \"Rosy Skin\", \"#FFD95854\": \"Rosy Sunset\", \"#FFC8ABA7\": \"Rosy Tan\", \"#FFB69642\": \"Roti Variant\", \"#FFF5E0BF\": \"Rotunda Gold\", \"#FFD7D1C6\": \"Rotunda White\", \"#FFAB1239\": \"Rouge Variant\", \"#FF814D54\": \"Rouge Charm\", \"#FFA94064\": \"Rouge Like\", \"#FFE24666\": \"Rouge Red\", \"#FFEE2233\": \"Rouge Sarde\", \"#FFBDBEBF\": \"Rough Asphalt\", \"#FF7A8687\": \"Rough Ride\", \"#FF9EA2AA\": \"Rough Stone\", \"#FF97635F\": \"Roulette\", \"#FFEAD6AF\": \"Rousseau Gold\", \"#FF175844\": \"Rousseau Green\", \"#FF994400\": \"Roux\", \"#FFBFB8AD\": \"Row House\", \"#FFD2BB9D\": \"Row House Tan\", \"#FFCB0162\": \"Rowan\", \"#FFEAA007\": \"Rowdy Orange\", \"#FF8E8E6E\": \"Rowntree\", \"#FF7A5546\": \"Roxy Brown\", \"#FF0C1793\": \"Royal\", \"#FF550344\": \"Royal Ash\", \"#FFC74767\": \"Royal Banner\", \"#FF2F3844\": \"Royal Battle\", \"#FF105E80\": \"Royal Blood\", \"#FF082D4F\": \"Royal Blue Metallic\", \"#FF1600FC\": \"Royal Blue Tang\", \"#FFF26E54\": \"Royal Blush\", \"#FF275779\": \"Royal Breeze\", \"#FF523B35\": \"Royal Brown\", \"#FF16A5A3\": \"Royal Cloak\", \"#FF2E5686\": \"Royal Consort\", \"#FF3E3542\": \"Royal Coronation\", \"#FF4F325E\": \"Royal Crown\", \"#FF282A4A\": \"Royal Curtsy\", \"#FF403547\": \"Royal Decree\", \"#FF7B5867\": \"Royal Fig\", \"#FFA0365F\": \"Royal Flush\", \"#FFEE6600\": \"Royal Flycatcher Crest\", \"#FF747792\": \"Royal Fortune\", \"#FF653A3D\": \"Royal Garnet\", \"#FF9791BC\": \"Royal Glimmer\", \"#FFD4CA8E\": \"Royal Goblet\", \"#FFE1BC8A\": \"Royal Gold\", \"#FFD0A54E\": \"Royal Gold Pearl\", \"#FFA152BD\": \"Royal Gramma Purple\", \"#FF698396\": \"Royal Grey\", \"#FFB54B73\": \"Royal Heath Variant\", \"#FF4411EE\": \"Royal Hunter Blue\", \"#FF3F5948\": \"Royal Hunter Green\", \"#FF464B6A\": \"Royal Hyacinth\", \"#FF4E4260\": \"Royal Indigo\", \"#FF687094\": \"Royal Intrigue\", \"#FF553E42\": \"Royal Iris\", \"#FF787866\": \"Royal Ivy\", \"#FF84549B\": \"Royal Lilac\", \"#FF6E3D58\": \"Royal Lines\", \"#FF784D40\": \"Royal Liqueur\", \"#FFDA202A\": \"Royal Mail Red\", \"#FF543938\": \"Royal Maroon\", \"#FF545E97\": \"Royal Marquis\", \"#FFA1A0B7\": \"Royal Mile\", \"#FFF7CFB4\": \"Royal Milk Tea\", \"#FF45505B\": \"Royal Navy\", \"#FF1C3B42\": \"Royal Neptune\", \"#FF2B3191\": \"Royal Night\", \"#FF533CC6\": \"Royal Nightcore\", \"#FF879473\": \"Royal Oakleaf\", \"#FFFF7722\": \"Royal Oranje\", \"#FF5F6D59\": \"Royal Orchard\", \"#FF418D84\": \"Royal Palm\", \"#FF27ACE0\": \"Royal Peacock\", \"#FF355E5A\": \"Royal Pine\", \"#FF654161\": \"Royal Plum\", \"#FFA063A1\": \"Royal Pretender\", \"#FFAAA0BC\": \"Royal Proclamation\", \"#FF4B006E\": \"Royal Purple Variant\", \"#FF881177\": \"Royal Purpleness\", \"#FF806F72\": \"Royal Raisin\", \"#FF60456D\": \"Royal Rajah\", \"#FF8F7BB7\": \"Royal Raul\", \"#FF8E3C3F\": \"Royal Red Flush\", \"#FF678BC9\": \"Royal Regatta\", \"#FF614A7B\": \"Royal Robe\", \"#FFA54A4A\": \"Royal Rum\", \"#FF4B3841\": \"Royal Silk\", \"#FFE0DDDD\": \"Royal Silver\", \"#FFFEDE4F\": \"Royal Star\", \"#FF494256\": \"Royal Treatment\", \"#FF513E4D\": \"Royal Velvet\", \"#FF4433EE\": \"Royal Vessel\", \"#FF3E4967\": \"Royal Wave\", \"#FFFBE3E3\": \"Royal Wedding\", \"#FF463699\": \"Royal Wisteria\", \"#FFFADA50\": \"Royal Yellow\", \"#FF5930A9\": \"Royalty\", \"#FFAE58AB\": \"Royalty Loyalty\", \"#FFA76251\": \"Roycroft Adobe\", \"#FF324038\": \"Roycroft Bottle Green\", \"#FF7A6A51\": \"Roycroft Brass\", \"#FF575449\": \"Roycroft Bronze Green\", \"#FF7B3728\": \"Roycroft Copper Red\", \"#FFC2BDB1\": \"Roycroft Mist Grey\", \"#FF616564\": \"Roycroft Pewter\", \"#FFC08F80\": \"Roycroft Rose\", \"#FFA79473\": \"Roycroft Suede\", \"#FFE8D9BD\": \"Roycroft Vellum\", \"#FFF2A8B8\": \"Rozowy Pink\", \"#FFC11C84\": \"Rrosy-Fingered Dawn\", \"#FF5F5547\": \"Rub Elbows\", \"#FF815D37\": \"Rubber\", \"#FFFACF58\": \"Rubber Ducky\", \"#FFFFC5CB\": \"Rubber Rose\", \"#FFC04042\": \"Rubiate\", \"#FFC5B9B4\": \"Rubidium\", \"#FF6C383C\": \"Rubine\", \"#FFCA0147\": \"Ruby\", \"#FF975B60\": \"Ruby Crystal\", \"#FFD0A2A0\": \"Ruby Eye\", \"#FFF20769\": \"Ruby Fire\", \"#FF73525C\": \"Ruby Grey\", \"#FF813E45\": \"Ruby Lips\", \"#FF6F3B51\": \"Ruby Nights\", \"#FFC41A3B\": \"Ruby Passion\", \"#FFAA5B67\": \"Ruby Petals\", \"#FFB0063D\": \"Ruby Queen\", \"#FFA03D41\": \"Ruby Ring\", \"#FFA2566F\": \"Ruby Shade\", \"#FFBD1C30\": \"Ruby Shard\", \"#FF9C2E33\": \"Ruby Slippers\", \"#FFBB1122\": \"Ruby Star\", \"#FF5C384E\": \"Ruby Violet\", \"#FF85393D\": \"Ruby Wine\", \"#FFDB1459\": \"Rubylicious\", \"#FFEDB508\": \"Rucksack Tan\", \"#FFA5654E\": \"Ruddy Oak\", \"#FF894E45\": \"Rudraksha Beads\", \"#FF705749\": \"Rue Bourbon\", \"#FFF9F2DC\": \"Ruffled Clam\", \"#FFACC2D1\": \"Ruffled Feathers\", \"#FF9FA3C0\": \"Ruffled Iris\", \"#FFFBC0B4\": \"Ruffled Parasol\", \"#FFFBBBAE\": \"Ruffles\", \"#FFBB9D87\": \"Rugby Tan\", \"#FF998568\": \"Rugged\", \"#FF694336\": \"Rugged Brown\", \"#FF78736F\": \"Rugged Suede\", \"#FFB8A292\": \"Rugged Tan\", \"#FF254E5D\": \"Rugged Teal\", \"#FF484435\": \"Ruggero Grey\", \"#FF8C3F3E\": \"Ruggero Red\", \"#FF0F1012\": \"Ruined Smores\", \"#FFCADECE\": \"Ruins of Civilization\", \"#FF9B8B84\": \"Ruins of Metal\", \"#FF5E615B\": \"Ruins of Pompeii\", \"#FF774E55\": \"Rule Breaker\", \"#FF716675\": \"Rum Variant\", \"#FF450E15\": \"Rum Chocolate\", \"#FFE9CFAA\": \"Rum Custard\", \"#FFAA423A\": \"Rum Punch\", \"#FF683B3C\": \"Rum Raisin\", \"#FF990044\": \"Rum Riche\", \"#FFAA7971\": \"Rum Spice\", \"#FFF1EDD4\": \"Rum Swizzle Variant\", \"#FFC77B42\": \"Rumba Orange\", \"#FF902A40\": \"Rumba Red\", \"#FF5CA904\": \"Ruminant\\u2019s Paradise\", \"#FF744245\": \"Rumours\", \"#FFDA2811\": \"Run Lola Run\", \"#FFD3AA94\": \"Rundlet Peach\", \"#FFC4C4C7\": \"Runefang Steel\", \"#FFB6A89A\": \"Runelord Brass\", \"#FFCAB2C1\": \"Runic Mauve\", \"#FF326193\": \"Running Water\", \"#FF99AF73\": \"Rural Eyes\", \"#FF8D844D\": \"Rural Green\", \"#FFBB1144\": \"Rural Red\", \"#FF1E50A2\": \"Ruri Blue\", \"#FF1B294B\": \"Rurikon Blue\", \"#FF536770\": \"Rush Hour\", \"#FF549EB9\": \"Rushing Rapids\", \"#FF8B3643\": \"Rushing Red\", \"#FF5F7797\": \"Rushing River\", \"#FF65C3D6\": \"Rushing Stream\", \"#FFB7B2A6\": \"Rushmore Grey\", \"#FF866C5E\": \"Ruskie\", \"#FF546B75\": \"Ruskin Blue\", \"#FF4D4D41\": \"Ruskin Bronze\", \"#FF935242\": \"Ruskin Red\", \"#FFACA17D\": \"Ruskin Room Green\", \"#FF547587\": \"Russ Grey\", \"#FFE7D6B1\": \"Russeau Gold\", \"#FF823D38\": \"Russet Brown\", \"#FFE3D9A0\": \"Russet Green\", \"#FF965849\": \"Russet Leather\", \"#FFE47127\": \"Russet Orange\", \"#FF9F6859\": \"Russet Red\", \"#FF9AAEBB\": \"Russian Blue\", \"#FF726647\": \"Russian Olive\", \"#FF4D4244\": \"Russian Red\", \"#FFD0C4AF\": \"Russian Toffee\", \"#FF5F6D36\": \"Russian Uniform\", \"#FFA83C09\": \"Rust Variant\", \"#FFA46454\": \"Rust Coloured\", \"#FFBB3344\": \"Rust Effect\", \"#FF966684\": \"Rust Magenta\", \"#FFC45508\": \"Rust Orange\", \"#FFAA2704\": \"Rust Red\", \"#FF60372E\": \"Rusted Crimson\", \"#FF8B5134\": \"Rusted Earth\", \"#FFAA4411\": \"Rusted Lock\", \"#FF884B3D\": \"Rusted Nail\", \"#FFD39A72\": \"Rustic Adobe\", \"#FF935848\": \"Rustic Brown\", \"#FF705536\": \"Rustic Cabin\", \"#FFBA9A67\": \"Rustic City\", \"#FFF6EFE2\": \"Rustic Cream\", \"#FF93674C\": \"Rustic Earth\", \"#FF9C8E74\": \"Rustic Hacienda\", \"#FF996E58\": \"Rustic Oak\", \"#FFDF745B\": \"Rustic Pottery\", \"#FF8D794F\": \"Rustic Ranch\", \"#FF3A181A\": \"Rustic Red Variant\", \"#FFCBB6A4\": \"Rustic Rose\", \"#FF9D2626\": \"Rustic Rouge\", \"#FFCDB9A2\": \"Rustic Taupe\", \"#FF6E5949\": \"Rustic Tobacco\", \"#FFB18A56\": \"Rustic Wicker\", \"#FF8A3A2C\": \"Rustica\", \"#FFF5BFB2\": \"Rustique\", \"#FFAD6961\": \"Rustling Leaves\", \"#FF96512A\": \"Rusty\", \"#FFC6494C\": \"Rusty Chainmail\", \"#FF8D5F2C\": \"Rusty Coin\", \"#FFAF6649\": \"Rusty Gate\", \"#FFA04039\": \"Rusty Heart\", \"#FFCC5522\": \"Rusty Nail Variant\", \"#FFCD5909\": \"Rusty Orange\", \"#FFE3DCE0\": \"Rusty Pebble\", \"#FFAF2F0D\": \"Rusty Red\", \"#FFEDB384\": \"Rusty Sand\", \"#FFA4493D\": \"Rusty Sword\", \"#FF719DA8\": \"Rusty Tap\", \"#FFEAD5B6\": \"Rutabaga\", \"#FF8D734F\": \"Rutherford\", \"#FF573894\": \"Ruthless Empress\", \"#FFD1AE7B\": \"Rye\", \"#FFCDBEA1\": \"Rye Bread\", \"#FF807465\": \"Rye Brown\", \"#FF807365\": \"Rye Dough Brown\", \"#FFBBB286\": \"Ryegrass\", \"#FFDCCB18\": \"Ryoku-Ou-Shoku Yellow\", \"#FFF3F1E1\": \"Ryu\\u2019s Kimono\", \"#FFEC631A\": \"Ryza Dust\", \"#FFA87F5F\": \"S\\u2019mores\", \"#FF496A4E\": \"Sabal Palm\", \"#FF6A7F7A\": \"Sabiasagi Blue\", \"#FF455859\": \"Sabionando Grey\", \"#FF898A74\": \"Sabiseiji Grey\", \"#FF784841\": \"Sable\", \"#FFF6D8BE\": \"Sabl\\u00e9\", \"#FF946A52\": \"Sable Brown\", \"#FF505650\": \"Sable Calm\", \"#FFC4A7A1\": \"Sable Cloaked\", \"#FF5D5E58\": \"Sable Evening\", \"#FFECDFD6\": \"Sablewood\", \"#FF978D59\": \"Sabo Garden\", \"#FFD4B385\": \"Sabre Tooth\", \"#FFE69656\": \"Sabre-Toothed Tiger\", \"#FFA5D610\": \"Sabz Green\", \"#FFD4D8ED\": \"Sachet Cushion\", \"#FFEE9941\": \"Sacral Chakra\", \"#FF5E0E0B\": \"Sacramental Red\", \"#FF97B9E0\": \"Sacred Blue\", \"#FFB2865D\": \"Sacred Ground\", \"#FF7C8635\": \"Sacred Sapling\", \"#FF950C1B\": \"Sacred Scarlet\", \"#FFC7CBCE\": \"Sacred Spring\", \"#FF49B3A5\": \"Sacred Turquoise\", \"#FFA59C8D\": \"Sacred Vortex\", \"#FF2A5774\": \"Sacrifice\", \"#FF850101\": \"Sacrifice Altar\", \"#FF229911\": \"Sacro Bosco\", \"#FF5D4E46\": \"Saddle Variant\", \"#FF9F906E\": \"Saddle Soap\", \"#FFAB927A\": \"Saddle Up\", \"#FF8A534E\": \"Saddlebag\", \"#FFB6A58B\": \"Safari\", \"#FF8E7F6D\": \"Safari Beige\", \"#FF976C60\": \"Safari Brown\", \"#FFB7AA96\": \"Safari Chic\", \"#FF6C6D2F\": \"Safari Green\", \"#FFE2CCBA\": \"Safari Map\", \"#FFB4875E\": \"Safari Sun\", \"#FF8F7B51\": \"Safari Trail\", \"#FFB2A68F\": \"Safari Vest\", \"#FF1E8EA1\": \"Safe Harbour\", \"#FF5588AA\": \"Safe Haven\", \"#FFFDAE44\": \"Safflower\", \"#FFBB5548\": \"Safflower Bark\", \"#FF9A493F\": \"Safflower Kite\", \"#FFB44C97\": \"Safflower Purple\", \"#FFD9333F\": \"Safflower Red\", \"#FFE83929\": \"Safflower Scarlet\", \"#FFCCA6BF\": \"Safflower Wisteria\", \"#FF8491C3\": \"Safflowerish Sky\", \"#FF9C8AAB\": \"Saffron Blossom Mauve\", \"#FFE8E9CF\": \"Saffron Bread\", \"#FF584C77\": \"Saffron Crocus\", \"#FFC24359\": \"Saffron Desires\", \"#FFF08F00\": \"Saffron Gold\", \"#FFD49F4E\": \"Saffron Robe\", \"#FFFEB209\": \"Saffron Souffl\\u00e9\", \"#FFD39952\": \"Saffron Strands\", \"#FFDA9E35\": \"Saffron Sunset\", \"#FFFFB301\": \"Saffron Thread\", \"#FFF2EAD6\": \"Saffron Tint\", \"#FFA7843E\": \"Saffron Valley\", \"#FFD09B2C\": \"Saffron Yellow\", \"#FF932A25\": \"Saffronaut\", \"#FF75A0B1\": \"Saga Blue\", \"#FF6A31CA\": \"Sagat Purple\", \"#FF87AE73\": \"Sage Tint\", \"#FF948B76\": \"Sage Advice\", \"#FF4E78A9\": \"Sage Blossom Blue\", \"#FFBAD3C7\": \"Sage Bundle\", \"#FF7FAB70\": \"Sage Garden\", \"#FF887766\": \"Sage Green\", \"#FF69796A\": \"Sage Green Grey\", \"#FF73705E\": \"Sage Green Light\", \"#FF9EA49D\": \"Sage Grey\", \"#FF7B8B5D\": \"Sage Leaves\", \"#FFDBEBDE\": \"Sage Salt\", \"#FFB2E191\": \"Sage Sensation\", \"#FF5E6A61\": \"Sage Shadow\", \"#FF7D8277\": \"Sage Slate\", \"#FFE4E5D2\": \"Sage Splash\", \"#FFC3C6A4\": \"Sage Splendour\", \"#FFACA28F\": \"Sage the Day\", \"#FFDADED1\": \"Sage Tint\", \"#FF413C7B\": \"Sage Violet\", \"#FFAFAD96\": \"Sage Wisdom\", \"#FF947252\": \"Sagebrush\", \"#FF567572\": \"Sagebrush Green\", \"#FFA2AA8C\": \"Sagey\", \"#FFFA7F46\": \"Sagittarius Amber Artefact\", \"#FFD8CFC3\": \"Sago\", \"#FF94BE7F\": \"Sago Garden\", \"#FF655F2D\": \"Saguaro\", \"#FFB79826\": \"Sahara Variant\", \"#FFDFC08A\": \"Sahara Gravel\", \"#FFF0E1DB\": \"Sahara Light Red\", \"#FFE2AB60\": \"Sahara Shade\", \"#FF9B7448\": \"Sahara Splendour\", \"#FFC67363\": \"Sahara Sun\", \"#FFDFD4B7\": \"Sahara Wind\", \"#FFA5CEEC\": \"Sail Variant\", \"#FF55B4DE\": \"Sail Away\", \"#FF588FA0\": \"Sail Cover\", \"#FFCABAA4\": \"Sail Grey\", \"#FFA3BBDC\": \"Sail Into the Horizon\", \"#FF0E4D72\": \"Sail Maker\", \"#FF4575AD\": \"Sail On\", \"#FF99C3F0\": \"Sail Tint\", \"#FF314A72\": \"Sailboat\", \"#FFECE0C4\": \"Sailcloth\", \"#FF2E9CBB\": \"Sailfish\", \"#FF869CBB\": \"Sailing\", \"#FFAECBD9\": \"Sailing on the Bay\", \"#FF3A5161\": \"Sailing Safari\", \"#FFFFA857\": \"Sailing Tangerine\", \"#FF445780\": \"Sailor\", \"#FF0F445C\": \"Sailor Blue\", \"#FFAEBBD0\": \"Sailor Boy\", \"#FFFFEE00\": \"Sailor Moon\", \"#FF496F8E\": \"Sailor\\u2019s Bay\", \"#FF334B58\": \"Sailor\\u2019s Coat\", \"#FFB8A47A\": \"Sailor\\u2019s Knot\", \"#FFD39733\": \"Saimin Noodle Soup\", \"#FF66B89C\": \"Sainsbury\", \"#FFEEEE00\": \"Saint Seiya Gold\", \"#FFFF9BB7\": \"Saira Red\", \"#FFDFB1B6\": \"Sakura\", \"#FFCEA19F\": \"Sakura Mochi\", \"#FFE8DFE4\": \"Sakura Nezu\", \"#FF7B6C7C\": \"Sakura Night\", \"#FF8BA673\": \"Salad\", \"#FF7E8F69\": \"Saladin\", \"#FF637D74\": \"Salal Leaves\", \"#FF63775B\": \"Salamander\", \"#FFE25E31\": \"Salametti\", \"#FF820000\": \"Salami\", \"#FFDA655E\": \"Salami Slice\", \"#FF177B4D\": \"Salem Variant\", \"#FF45494D\": \"Salem Black\", \"#FF66A9D3\": \"Salem Blue\", \"#FFB4AB99\": \"Salem Clay\", \"#FFCAD2D4\": \"Salina Springs\", \"#FFC5E8E7\": \"Saline Water\", \"#FFDDD8C6\": \"Salisbury Stone\", \"#FFFF796C\": \"Salmon Tint\", \"#FFFBC6B6\": \"Salmon Beauty\", \"#FFFEA871\": \"Salmon Buff\", \"#FFEE867D\": \"Salmon Carpaccio\", \"#FFE9CFCF\": \"Salmon Cream\", \"#FFFEDDC5\": \"Salmon Creek\", \"#FFF7D560\": \"Salmon Eggs\", \"#FFF1C9CC\": \"Salmon Flush\", \"#FFFBB1A2\": \"Salmon Fresco\", \"#FFEBB9AF\": \"Salmon Glow\", \"#FFE3B6AA\": \"Salmon Grey\", \"#FFFCD1C3\": \"Salmon Mousse\", \"#FFF9906F\": \"Salmon Nigiri\", \"#FFD5847E\": \"Salmon Pate\", \"#FFFDC5B5\": \"Salmon Peach\", \"#FFE1958F\": \"Salmon Pink Red\", \"#FFEE7777\": \"Salmon Pok\\u00e9 Bowl\", \"#FFFF737E\": \"Salmon Rose\", \"#FFEDAF9C\": \"Salmon Run\", \"#FFE7968B\": \"Salmon Salt\", \"#FFD9AA8F\": \"Salmon Sand\", \"#FFFF7E79\": \"Salmon Sashimi\", \"#FFF1AC8D\": \"Salmon Slice\", \"#FFD4BFBD\": \"Salmon Smoke\", \"#FFFF9BAA\": \"Salmon Tartare\", \"#FFEFCCBF\": \"Salmon Tint\", \"#FFBBEDDB\": \"Salome\", \"#FFFFD67B\": \"Salomie Variant\", \"#FF7D8697\": \"Salon Bleu\", \"#FFAB7878\": \"Salon Rose\", \"#FFB31928\": \"Salsa\", \"#FFBB4F5C\": \"Salsa Diane\", \"#FFE35401\": \"Salsa Haba\\u00f1ero\", \"#FFA03413\": \"Salsa Mexicana\", \"#FFAB250B\": \"Salsa Picante\", \"#FFE97B3E\": \"Salsa Sizzle\", \"#FFCEC754\": \"Salsa Verde\", \"#FF2BB179\": \"Salsify Grass\", \"#FFDED8C4\": \"Salsify White\", \"#FFEFEDE6\": \"Salt\", \"#FF7D9C9D\": \"Salt Blue\", \"#FFD3934D\": \"Salt Caramel\", \"#FFDEE0D7\": \"Salt Cellar\", \"#FFF0EDE0\": \"Salt Crystal\", \"#FFCFD4CE\": \"Salt Glaze\", \"#FF757261\": \"Salt Island Green\", \"#FF74C6D3\": \"Salt Lake\", \"#FFD7FEFE\": \"Salt Mountain\", \"#FFF9ECEA\": \"Salt Pebble\", \"#FFD0C6AF\": \"Salt Scrub\", \"#FFA7C5CE\": \"Salt Spray\", \"#FFEEDDBB\": \"Salt Steppe\", \"#FFDCD9DB\": \"Salt-N-Pepa\", \"#FFF5E9D9\": \"Saltbox\", \"#FF648FA4\": \"Saltbox Blue\", \"#FFEBEADC\": \"Salted\", \"#FFA69151\": \"Salted Capers\", \"#FFEBB367\": \"Salted Caramel\", \"#FFFDB251\": \"Salted Caramel Popcorn\", \"#FF816B56\": \"Salted Pretzel\", \"#FFEEF3E5\": \"Saltpan Variant\", \"#FFC2D0DE\": \"Saltwater\", \"#FF145C78\": \"Saltwater Denim\", \"#FF52896B\": \"Saltwater Depth\", \"#FFD1AB99\": \"Saltwater Taffy\", \"#FFDDE2D7\": \"Salty Breeze\", \"#FFE2C681\": \"Salty Cracker\", \"#FF234058\": \"Salty Dog\", \"#FFCCE2F3\": \"Salty Ice\", \"#FF7C8B7F\": \"Salty Sea\", \"#FFC1B993\": \"Salty Seeds\", \"#FFBACAD4\": \"Salty Tears\", \"#FF96B403\": \"Salty Thyme\", \"#FFCBDEE3\": \"Salty Vapour\", \"#FF2F323D\": \"Salute\", \"#FFBAC9CF\": \"Salvaged Silk\", \"#FF514E5C\": \"Salvation\", \"#FFA8B59E\": \"Salvia\", \"#FF96BFE6\": \"Salvia Blue\", \"#FF929752\": \"Salvia Divinorum\", \"#FFF2D7E6\": \"Samantha\\u2019s Room\", \"#FFAA262B\": \"Samba\", \"#FFF0E0D4\": \"Samba de Coco\", \"#FF3B2E25\": \"Sambuca Variant\", \"#FF17182B\": \"Sambucus\", \"#FFFABC46\": \"Samoan Sun\", \"#FFB8BEBE\": \"Samovar Silver\", \"#FFF7F3E6\": \"Sampaguita Pearl\", \"#FF4DB560\": \"Samphire Green\", \"#FFA69474\": \"San Antonio Sage\", \"#FFD9BB8E\": \"San Carlos Plaza\", \"#FF2C6E31\": \"San Felix Variant\", \"#FFC4C2BC\": \"San Francisco Fog\", \"#FF936A6D\": \"San Francisco Mauve\", \"#FFBB33AA\": \"San Francisco Pink\", \"#FF2F6679\": \"San Gabriel Blue\", \"#FF445761\": \"San Juan Variant\", \"#FF4E6C9D\": \"San Marino Variant\", \"#FF527585\": \"San Miguel Blue\", \"#FFD4C9A6\": \"Sanctuary\", \"#FF66B2E4\": \"Sanctuary Spa\", \"#FF3C2F4E\": \"Sanctum of Shadows\", \"#FFE2CA76\": \"Sand\", \"#FFFFEEDA\": \"Sand Crystal\", \"#FFE6DDD2\": \"Sand Dagger\", \"#FFE0C8B9\": \"Sand Dance\", \"#FFFAE8BC\": \"Sand Diamond\", \"#FFDCCDBB\": \"Sand Dollar\", \"#FFFAE3C9\": \"Sand Dollar White\", \"#FFE5E0D3\": \"Sand Drift\", \"#FFE3D2C0\": \"Sand Dune Variant\", \"#FFE3E4D9\": \"Sand Grain\", \"#FFF4D1C2\": \"Sand Island\", \"#FFDDC6A8\": \"Sand Motif\", \"#FFB58853\": \"Sand Mountain\", \"#FFFFDFC2\": \"Sand Muffin\", \"#FFE7D4B6\": \"Sand Pearl\", \"#FFB09D7F\": \"Sand Pebble\", \"#FFE6E5D3\": \"Sand Puffs\", \"#FFDDCC77\": \"Sand Pyramid\", \"#FFC1B7B0\": \"Sand Ripples\", \"#FFE7D0A6\": \"Sand Sculpture\", \"#FF5A86AD\": \"Sand Shark\", \"#FFD0C6A1\": \"Sand Trail\", \"#FFBBA595\": \"Sand Trap\", \"#FF9D89BD\": \"Sand Verbena\", \"#FFA3876A\": \"Sandal Variant\", \"#FF615543\": \"Sandalwood\", \"#FFF2D1B1\": \"Sandalwood Beige\", \"#FF005160\": \"Sandalwood Grey Blue\", \"#FF907F68\": \"Sandalwood Tan\", \"#FFF2ECDE\": \"Sandalwood White\", \"#FFE9D5AD\": \"Sandbank\", \"#FFCBBFAD\": \"Sandbar\", \"#FFDECBAB\": \"Sandblast\", \"#FFE5D7C4\": \"Sandcastle\", \"#FFC8AB96\": \"Sanderling\", \"#FF93917F\": \"Sandgrass Green\", \"#FFEDDCBE\": \"Sandhill\", \"#FF015E60\": \"Sandhill Crane\", \"#FFEFEBDE\": \"Sanding Sugar\", \"#FFD7B1A5\": \"Sandpaper\", \"#FFEBDAC8\": \"Sandpiper\", \"#FF717474\": \"Sandpiper Cove\", \"#FF9E7C5E\": \"Sandpit\", \"#FFEACDB0\": \"Sandpoint\", \"#FFAF937D\": \"Sandrift Variant\", \"#FFC4B19A\": \"Sandrock\", \"#FFBCA38B\": \"Sands of Time\", \"#FFD6C8B8\": \"Sandshell\", \"#FFC9AE74\": \"Sandstone Variant\", \"#FFD2C9B7\": \"Sandstone Cliff\", \"#FF857266\": \"Sandstone Grey\", \"#FF88928C\": \"Sandstone Grey Green\", \"#FFD9CCB6\": \"Sandstone Palette\", \"#FF886E70\": \"Sandstone Red Grey\", \"#FFCBBE9C\": \"Sandwashed\", \"#FF706859\": \"Sandwashed Driftwood\", \"#FFDEE8E3\": \"Sandwashed Glassshard\", \"#FFDECB81\": \"Sandwisp Variant\", \"#FFF1DA7A\": \"Sandy\", \"#FFE4DED5\": \"Sandy Ash\", \"#FFFAD7B3\": \"Sandy Bay\", \"#FFF9E2D0\": \"Sandy Beach Variant\", \"#FFDDC6AB\": \"Sandy Beaches\", \"#FFACA088\": \"Sandy Bluff\", \"#FFDBD0BD\": \"Sandy Clay\", \"#FFCEB587\": \"Sandy Cove\", \"#FFD7CFC1\": \"Sandy Day\", \"#FFB7AC97\": \"Sandy Hair\", \"#FFD2C098\": \"Sandy Pail\", \"#FFDF7B35\": \"Sandy Peppers\", \"#FFA18E77\": \"Sandy Ridge\", \"#FFC7C2B4\": \"Sandy Sage\", \"#FF847563\": \"Sandy Shoes\", \"#FFF2E9BB\": \"Sandy Shore\", \"#FFFDD9B5\": \"Sandy Tan\", \"#FF967111\": \"Sandy Taupe\", \"#FFC7B8A4\": \"Sandy Toes\", \"#FFCABAA0\": \"Sandy Trail\", \"#FF771100\": \"Sang de Boeuf\", \"#FFF5B1AA\": \"Sango Pink\", \"#FFF8674F\": \"Sango Red\", \"#FF881100\": \"Sangoire Red\", \"#FFB14566\": \"Sangria Variant\", \"#FFF01A4D\": \"Sanguinary\", \"#FF6C110E\": \"Sanguine\", \"#FF6C3736\": \"Sanguine Brown Variant\", \"#FFE69332\": \"Sanskrit\", \"#FFAD2C15\": \"Santa Belly Red\", \"#FFEDDDD3\": \"Santa Fe Spirit\", \"#FFCC9469\": \"Santa Fe Sunrise\", \"#FFA75A4C\": \"Santa Fe Sunset\", \"#FFD5AD85\": \"Santa Fe Tan\", \"#FFE9E7DE\": \"Santa\\u2019s Beard\", \"#FF714636\": \"Santana Soul\", \"#FFE95F24\": \"Santiago Orange\", \"#FFD6D2CE\": \"Santo\", \"#FFE3D0D5\": \"Santolina Blooms\", \"#FF41B0D0\": \"Santorini\", \"#FF416D83\": \"Santorini Blue\", \"#FF019A8D\": \"Santorini Seascape\", \"#FF5C8B15\": \"Sap Green Variant\", \"#FFBEBDAC\": \"Sapless Green\", \"#FFA3C05A\": \"Sapling Variant\", \"#FF9E3D3F\": \"Sappanwood\", \"#FFA24F46\": \"Sappanwood Incense\", \"#FF4F5F7E\": \"Sapphire Earbobs\", \"#FF284B75\": \"Sapphire Earrings\", \"#FF99A8C9\": \"Sapphire Fog\", \"#FF0033CC\": \"Sapphire Glitter\", \"#FF235C8E\": \"Sapphire Lace\", \"#FFCDC7B4\": \"Sapphire Light Yellow\", \"#FF887084\": \"Sapphire Pink\", \"#FF5776AF\": \"Sapphire Shimmer Blue\", \"#FF662288\": \"Sapphire Siren\", \"#FF135E84\": \"Sapphire Sparkle\", \"#FF2425B9\": \"Sapphire Splendour\", \"#FF41495D\": \"Sapphire Stone\", \"#FFC9E5EE\": \"Sapphireberry\", \"#FF5B82A6\": \"Sapphired\", \"#FF00AAC1\": \"Sarah\\u2019s Garden\", \"#FF555B2C\": \"Saratoga Variant\", \"#FFF4EEBA\": \"Sarawak White Pepper\", \"#FFFFDDAA\": \"Sarcoline\", \"#FF28A4CB\": \"Sardinia Beaches\", \"#FF3D4A67\": \"Sargasso Sea\", \"#FFE47C64\": \"Sari\", \"#FF5B4C44\": \"Sarsaparilla\", \"#FF817265\": \"Saruk Grey\", \"#FFCFB4A8\": \"Sashay Sand\", \"#FFFF4681\": \"Sasquatch Socks\", \"#FF5A3940\": \"Sassafras\", \"#FFDBD8CA\": \"Sassafras Tea\", \"#FFC18862\": \"Sassy\", \"#FF7A8C31\": \"Sassy Grass\", \"#FFBBA86A\": \"Sassy Green\", \"#FFDFE289\": \"Sassy Lime\", \"#FF906B20\": \"Sassy Olive\", \"#FFFFB07F\": \"Sassy Peach\", \"#FFF6CEFC\": \"Sassy Pink\", \"#FFEE7C54\": \"Sassy Salmon\", \"#FFD5A272\": \"Sassy Sassafras\", \"#FFACB5DC\": \"Sassy Violet\", \"#FFF0C374\": \"Sassy Yellow\", \"#FFE63626\": \"Satan\", \"#FF9F8D89\": \"Satellite\", \"#FF4E5152\": \"Satin Black\", \"#FFFFE4C6\": \"Satin Blush\", \"#FF773344\": \"Satin Chocolate\", \"#FFFDF3D5\": \"Satin Cream White\", \"#FF1C1E21\": \"Satin Deep Black\", \"#FFB48FBD\": \"Satin Flower\", \"#FFC7DFB8\": \"Satin Green\", \"#FFFAD7B0\": \"Satin Latour\", \"#FF33EE00\": \"Satin Lime\", \"#FFFFF8EE\": \"Satin Purse\", \"#FFFFD8DC\": \"Satin Ribbon\", \"#FF9CADC7\": \"Satin Soft Blue\", \"#FF6B4836\": \"Satin Soil\", \"#FFEFE0BC\": \"Satin Souffle\", \"#FFE2CAC7\": \"Satin Teddy\", \"#FFF3EDD9\": \"Satin Weave\", \"#FFCFD5DB\": \"Satin White\", \"#FFC4C2CD\": \"Satire\", \"#FFB5BF50\": \"Sativa\", \"#FF644222\": \"Satoimo Brown\", \"#FF96466A\": \"Satsuma Imo Red\", \"#FFAA6622\": \"Sattle\", \"#FF4B4CFC\": \"Saturated Sky\", \"#FFFAE5BF\": \"Saturn\", \"#FFB8B19F\": \"Saturn Grey\", \"#FFDDDBCE\": \"Saturnia\", \"#FFBCA17A\": \"Satyr Brown\", \"#FFCA3F16\": \"Sauce Piquante\", \"#FF882C17\": \"Saucisson\", \"#FFC6B077\": \"Saucy\", \"#FFB6743B\": \"Saucy Gold\", \"#FF9E958A\": \"Saudi Sand\", \"#FFEEE0B9\": \"Sauerkraut\", \"#FFEDEBE1\": \"Sauna Steam\", \"#FFEBDFCD\": \"Sausage Roll\", \"#FFF4E5C5\": \"Sausalito\", \"#FF5D6F85\": \"Sausalito Port\", \"#FF6A5D53\": \"Sausalito Ridge\", \"#FFAB9378\": \"Sauteed Mushroom\", \"#FFC5A253\": \"Sauterne\", \"#FFF4EAE4\": \"Sauvignon Variant\", \"#FFB18276\": \"Sauvignon Blanc\", \"#FF5C9F59\": \"Savage Garden\", \"#FF874C44\": \"Savanna\", \"#FFD1BD92\": \"Savannah\", \"#FFBABC72\": \"Savannah Grass\", \"#FF47533F\": \"Savannah Moss\", \"#FFA36159\": \"Savannah Red\", \"#FFFFB989\": \"Savannah Sun\", \"#FFAA2200\": \"Saveloy\", \"#FFC0B7CF\": \"Savile Row\", \"#FF550011\": \"Saving Light\", \"#FFEED9B6\": \"Savon de Provence\", \"#FFF9DAA5\": \"Savoury Beige\", \"#FFD19C97\": \"Savoury Salmon\", \"#FF87B550\": \"Savoy\", \"#FF4B61D1\": \"Savoy Blue\", \"#FF7E4242\": \"Savoy House\", \"#FFF6E9CF\": \"Sawdust\", \"#FFD1CFC0\": \"Sawgrass\", \"#FFC3B090\": \"Sawgrass Basket\", \"#FFD3CDA2\": \"Sawgrass Cottage\", \"#FFAA7766\": \"Sawshark\", \"#FFEC956C\": \"Sawtooth Aak\", \"#FFABC1A0\": \"Saxon\", \"#FF435965\": \"Saxon Blue\", \"#FF216B88\": \"Saxony Blue\", \"#FFCEAF81\": \"Saxophone Gold\", \"#FFC7111E\": \"Say It With Red Roses\", \"#FF383739\": \"Sayward Pine\", \"#FFF5DEC4\": \"Sazerac Variant\", \"#FFFBD8C9\": \"Scallop Shell\", \"#FFF2D1A0\": \"Scalloped Oak\", \"#FFFCE3CF\": \"Scalloped Potato\", \"#FFF6D58B\": \"Scalloped Potatoes\", \"#FFF3E9E0\": \"Scalloped Shell\", \"#FFE5D5BD\": \"Scallywag\", \"#FF027275\": \"Scaly Green\", \"#FF6F63A0\": \"Scampi Variant\", \"#FF6B8CA9\": \"Scanda\", \"#FFADD9D1\": \"Scandal Variant\", \"#FFDFBDD0\": \"Scandalous Rose\", \"#FF1A1110\": \"Scandinavian Liquorice\", \"#FFC2D3D6\": \"Scandinavian Sky\", \"#FF6B6A6C\": \"Scapa Flow\", \"#FF2C3D37\": \"Scarab\", \"#FF414040\": \"Scarabaeus Sacer\", \"#FF7D8C55\": \"Scarab\\u0153us Nobilis\", \"#FF809391\": \"Scarborough\", \"#FFA55E2B\": \"Scarecrow Frown\", \"#FF922E4A\": \"Scarlet Apple\", \"#FFBB2D32\": \"Scarlet Beebalm\", \"#FFB21F1F\": \"Scarlet Blaze\", \"#FFF8D6CB\": \"Scarlet Butter\", \"#FFC70752\": \"Scarlet Cattleya Orchid\", \"#FF993366\": \"Scarlet Flame\", \"#FFCB0103\": \"Scarlet Glow\", \"#FF4A2D57\": \"Scarlet Gum Variant\", \"#FFF4601B\": \"Scarlet Ibis\", \"#FFA53B3D\": \"Scarlet Past\", \"#FFD44531\": \"Scarlet Rebels\", \"#FFB63E36\": \"Scarlet Red\", \"#FFA4334A\": \"Scarlet Ribbons\", \"#FFAA2335\": \"Scarlet Sage\", \"#FF7E2530\": \"Scarlet Shade\", \"#FFCC0C1B\": \"Scarlet Splendour\", \"#FFDA5640\": \"Scarlet Sun\", \"#FFB43B3D\": \"Scarlet Tanager\", \"#FF8CA468\": \"Scarpetta\", \"#FF647983\": \"Scatman Blue\", \"#FF7B8285\": \"Scattered Showers\", \"#FF81A79E\": \"Scenario\", \"#FFAF6D62\": \"Scene Stealer\", \"#FF486275\": \"Scenic Blue\", \"#FFCEC5B4\": \"Scenic Path\", \"#FF95BFB2\": \"Scenic View\", \"#FF88BBFF\": \"Scenic Water\", \"#FF907361\": \"Scented Candle\", \"#FF61524C\": \"Scented Clove\", \"#FFCAAEB8\": \"Scented Frill\", \"#FFDBC5D2\": \"Scented Soap\", \"#FFEED5EE\": \"Scented Spring\", \"#FFF3D9D6\": \"Scented Valentine\", \"#FF9DB4AA\": \"Sceptic\", \"#FFE2E2B5\": \"Schabziger Green\", \"#FFE84998\": \"Schiaparelli Pink\", \"#FF192961\": \"Schiava Blue\", \"#FF8B714C\": \"Schindler Brown\", \"#FF87876F\": \"Schist Variant\", \"#FFDD8855\": \"Schnipo\", \"#FF586A7D\": \"Scholarship\", \"#FF31373F\": \"School Ink\", \"#FF8D8478\": \"Schooner Variant\", \"#FF006666\": \"Sci-fi Petrol\", \"#FF00604B\": \"Sci-Fi Takeout\", \"#FF0076CC\": \"Science Blue Variant\", \"#FF97A53F\": \"Science Experiment\", \"#FF764663\": \"Scintillating Violet\", \"#FFAE935D\": \"Sconce\", \"#FF957340\": \"Sconce Gold\", \"#FF110055\": \"Scoop of Dark Matter\", \"#FF308EA0\": \"Scooter Variant\", \"#FF351F19\": \"Scorched\", \"#FF4D0001\": \"Scorched Brown\", \"#FF44403D\": \"Scorched Earth\", \"#FF423D27\": \"Scorched Metal\", \"#FFE75323\": \"Scorpio Scarlet Seal\", \"#FF6A6466\": \"Scorpion Variant\", \"#FF99AAC8\": \"Scorpion Grass Blue\", \"#FF62D84E\": \"Scorpion Green\", \"#FF97EA10\": \"Scorpion Venom\", \"#FF8EEF15\": \"Scorpy Green\", \"#FF544E03\": \"Scorzonera Brown\", \"#FF000077\": \"Scotch Blue\", \"#FFFE9F00\": \"Scotch Bonnet\", \"#FF649D85\": \"Scotch Lassie\", \"#FFEEE7C8\": \"Scotch Mist Variant\", \"#FF99719E\": \"Scotch Thistle\", \"#FFEBCCB9\": \"Scotchtone\", \"#FF87954F\": \"Scotland Isle\", \"#FF9BAA9A\": \"Scotland Road\", \"#FF5F653B\": \"Scots Pine\", \"#FF66A3C3\": \"Scott Base\", \"#FFC2CDCA\": \"Scottish Heath\", \"#FF7D9A7B\": \"Scottish Highlands\", \"#FF3B7960\": \"Scouring Rush\", \"#FFE34B26\": \"Scoville High\", \"#FF900405\": \"Scoville Highness\", \"#FFAB0040\": \"Screamer Pink\", \"#FFC16F45\": \"Screaming Bell Metal\", \"#FFF0F2D2\": \"Screaming Skull\", \"#FFEAE4D8\": \"Screech Owl\", \"#FF9A908A\": \"Screed Grey\", \"#FF9D7798\": \"Screen Gem\", \"#FF66EEAA\": \"Screen Glow\", \"#FF999EB0\": \"Screen Test\", \"#FF9FABB6\": \"Scribe\", \"#FF60616B\": \"Script Ink\", \"#FFDBDDDF\": \"Script White\", \"#FFDBA539\": \"Scrofulous Brown\", \"#FFEFE0CB\": \"Scroll\", \"#FFF3E5C0\": \"Scroll of Wisdom\", \"#FFE9DDC9\": \"Scrolled Parchment\", \"#FF3D4031\": \"Scrub\", \"#FF6392B7\": \"Scuba\", \"#FF00A2C5\": \"Scuba Blue\", \"#FFACD7C8\": \"Scud\", \"#FF0044EE\": \"Scuff Blue\", \"#FFC3BEB7\": \"Sculpting Clay\", \"#FFCCC3B4\": \"Sculptor Clay\", \"#FFD1DAD5\": \"Sculptural Silver\", \"#FF02737A\": \"Scurf Green\", \"#FFFC824A\": \"S\\u00e8 L\\u00e8i Orange\", \"#FF3C9992\": \"Sea\", \"#FFE8DAD6\": \"Sea Anemone\", \"#FF8BB8C3\": \"Sea Angel\", \"#FF62777E\": \"Sea Beast\", \"#FF29848D\": \"Sea Bed\", \"#FF41545C\": \"Sea Blithe\", \"#FF006994\": \"Sea Blue\", \"#FFC0E1DD\": \"Sea Breath\", \"#FFA4BFCE\": \"Sea Breeze\", \"#FFC9D9E7\": \"Sea Breeze Green\", \"#FFFFBF65\": \"Sea Buckthorn Variant\", \"#FF519D76\": \"Sea Cabbage\", \"#FF45868B\": \"Sea Caller\", \"#FFE4F3DF\": \"Sea Cap\", \"#FF61BDDC\": \"Sea Capture\", \"#FF005986\": \"Sea Cave\", \"#FF2C585C\": \"Sea Challenge\", \"#FFA5C7DF\": \"Sea Cliff\", \"#FF00586D\": \"Sea Creature\", \"#FF608BA6\": \"Sea Crystal\", \"#FF4C959D\": \"Sea Current\", \"#FF9ECDD5\": \"Sea Dew\", \"#FF4B7794\": \"Sea Drifter\", \"#FFC2D2E0\": \"Sea Drive\", \"#FF77675C\": \"Sea Elephant\", \"#FF975476\": \"Sea Fan Fuchsia\", \"#FF1A9597\": \"Sea Fantasy\", \"#FF656D54\": \"Sea Fern\", \"#FF87E0CF\": \"Sea Foam\", \"#FFCBDCE2\": \"Sea Foam Mist\", \"#FFDFDDD6\": \"Sea Fog\", \"#FF64B6E2\": \"Sea Frolic\", \"#FFD5DCDC\": \"Sea Frost\", \"#FF568E88\": \"Sea Garden\", \"#FFAFC1BF\": \"Sea Glass\", \"#FFA0E5D9\": \"Sea Glass Teal\", \"#FF216987\": \"Sea Goddess\", \"#FF2A2E44\": \"Sea Going\", \"#FF3300AA\": \"Sea Grape\", \"#FF53FCA1\": \"Sea Green Variant\", \"#FF6D716A\": \"Sea Grove\", \"#FFCBD9D4\": \"Sea Haze Grey\", \"#FFA7A291\": \"Sea Hazel\", \"#FF245878\": \"Sea Hunter\", \"#FFD7F2ED\": \"Sea Ice\", \"#FFA6D0C9\": \"Sea Inspired\", \"#FF30A299\": \"Sea Kale\", \"#FF354A55\": \"Sea Kelp\", \"#FFCFB1D8\": \"Sea Lavender\", \"#FF67A181\": \"Sea Lettuce\", \"#FF7F8793\": \"Sea Lion\", \"#FF8C6E60\": \"Sea Lion Brown\", \"#FF6E99D1\": \"Sea Loch\", \"#FF434A54\": \"Sea Mariner\", \"#FF92B6CF\": \"Sea Mark\", \"#FFDBEEE0\": \"Sea Mist Variant\", \"#FF658C7B\": \"Sea Monster\", \"#FF2C5252\": \"Sea Moss\", \"#FFF47633\": \"Sea Nettle\", \"#FF5482C2\": \"Sea Note\", \"#FF8AAEA4\": \"Sea Nymph Variant\", \"#FF2D535A\": \"Sea of Atlantis\", \"#FF0693D5\": \"Sea of Crete\", \"#FF466590\": \"Sea of Galilee\", \"#FF0B334D\": \"Sea of Stars\", \"#FF1D4DA0\": \"Sea of Tears\", \"#FF81D1DA\": \"Sea of Tranquillity\", \"#FF00507A\": \"Sea Paint\", \"#FF72897E\": \"Sea Palm\", \"#FF457973\": \"Sea Pea\", \"#FFE0E9E4\": \"Sea Pearl\", \"#FF4C6969\": \"Sea Pine\", \"#FFDB817E\": \"Sea Pink Variant\", \"#FF3E7984\": \"Sea Quest\", \"#FF799781\": \"Sea Radish\", \"#FF45A3CB\": \"Sea Ridge\", \"#FFA3D1E2\": \"Sea Rover\", \"#FFEEE1D7\": \"Sea Salt\", \"#FF5087BD\": \"Sea Salt Rivers\", \"#FFFFF5F7\": \"Sea Salt Sherbet\", \"#FF67B3BE\": \"Sea Serenade\", \"#FF4BC7CF\": \"Sea Serpent\", \"#FF5511CC\": \"Sea Serpent\\u2019s Tears\", \"#FF00789B\": \"Sea Sight\", \"#FF469BA7\": \"Sea Sparkle\", \"#FFD2EBEA\": \"Sea Spray\", \"#FFB7CCC7\": \"Sea Sprite\", \"#FFBAA243\": \"Sea Squash\", \"#FF4D939A\": \"Sea Star\", \"#FF018F6B\": \"Sea Swell\", \"#FF337F86\": \"Sea Swimmer\", \"#FF427A9A\": \"Sea Swirl\", \"#FF78D1B1\": \"Sea Treasure\", \"#FF818A40\": \"Sea Turtle\", \"#FF367D83\": \"Sea Urchin\", \"#FF83D6D4\": \"Sea Wave\", \"#FFACCAD5\": \"Sea Wind\", \"#FF0F9BC0\": \"Sea Wonder\", \"#FF85C2B2\": \"Seaborn\", \"#FF7AA5C9\": \"Seaborne\", \"#FF4B81AF\": \"Seabrook\", \"#FFCD7B00\": \"Seabuckthorn Yellow Brown\", \"#FF3E8896\": \"Seachange\", \"#FFB6C9A6\": \"Seacrest\", \"#FFB8F8D8\": \"Seafair Green\", \"#FF204D68\": \"Seafarer\", \"#FF78D1B6\": \"Seafoam Blue\", \"#FFC0CDC2\": \"Seafoam Dream\", \"#FF99BB88\": \"Seafoam Green\", \"#FFC2ECD8\": \"Seafoam Pearl\", \"#FFA6BCBE\": \"Seafoam Slate\", \"#FFB0EFCE\": \"Seafoam Splashes\", \"#FFDAEFCE\": \"Seafoam Spray\", \"#FF9DA49C\": \"Seafoam Storm\", \"#FFA1BDBF\": \"Seafoam Whisper\", \"#FFBCC6A2\": \"Seagrass\", \"#FF264E50\": \"Seagrass Green\", \"#FFE0DED8\": \"Seagull Variant\", \"#FFC9BBB4\": \"Seagull Beach\", \"#FFD9D9D2\": \"Seagull Grey\", \"#FFC7BDA8\": \"Seagull Wail\", \"#FF475663\": \"Seal Blue\", \"#FF8A9098\": \"Seal Grey\", \"#FF65869B\": \"Seal Pup\", \"#FF6B8B8B\": \"Sealegs\", \"#FF48423C\": \"Sealskin\", \"#FFE9ECE6\": \"Sealskin Shadow\", \"#FF15646D\": \"Seamount\", \"#FF69326E\": \"Seance Tint\", \"#FF3A3F41\": \"Seaplane Grey\", \"#FF006E8C\": \"Seaport\", \"#FFAECAC8\": \"Seaport Steam\", \"#FF6C7F9A\": \"Searching Blue\", \"#FFEFF0BF\": \"Searchlight\", \"#FF9A5633\": \"Seared Earth\", \"#FF495157\": \"Seared Grey\", \"#FF6B3B23\": \"Searing Gorge Brown\", \"#FF77A2AD\": \"Seascape\", \"#FFA6BAD1\": \"Seascape Blue\", \"#FFB5E4E4\": \"Seascape Green\", \"#FF104C77\": \"Seashell Cove\", \"#FFEDB9BD\": \"Seashell Froth\", \"#FFD5D4CF\": \"Seashell Grey\", \"#FFFFF6DE\": \"Seashell Peach Variant\", \"#FFF7C8C2\": \"Seashell Pink\", \"#FFB5DCEF\": \"Seashore Dreams\", \"#FF66A4B0\": \"Seaside\", \"#FFBDC3B5\": \"Seaside Fog\", \"#FFF2E9D7\": \"Seaside Sand\", \"#FFE9D5C9\": \"Seaside Villa\", \"#FFBEA27B\": \"Season Finale\", \"#FFE6B99F\": \"Seasonal Beige\", \"#FF7F6640\": \"Seasoned Acorn\", \"#FF8DB600\": \"Seasoned Green\", \"#FFCEC2A1\": \"Seasoned Salt\", \"#FF7D8B8A\": \"Seastone\", \"#FF777E90\": \"Seattle Haze\", \"#FF7D212A\": \"Seattle Red\", \"#FFA9C095\": \"Seawashed Glass\", \"#FF18D17B\": \"Seaweed Variant\", \"#FF35AD6B\": \"Seaweed Green\", \"#FF7D7B55\": \"Seaweed Salad\", \"#FF5D7759\": \"Seaweed Tea\", \"#FF4D473D\": \"Seaweed Wrap\", \"#FF125459\": \"Seaworld\", \"#FF314D58\": \"Seaworthy\", \"#FF84AEBA\": \"Sebastian Inlet\", \"#FFBD5701\": \"Sebright Chicken\", \"#FFCAC5B6\": \"Secluded Beach\", \"#FFC6876F\": \"Secluded Canyon\", \"#FF7B9893\": \"Secluded Garden\", \"#FF6F6D56\": \"Secluded Green\", \"#FF495A52\": \"Secluded Woods\", \"#FFE89AAD\": \"Second Blush\", \"#FF585642\": \"Second Nature\", \"#FF887CA4\": \"Second Pour\", \"#FFDFECE9\": \"Second Wind\", \"#FF50759E\": \"Secrecy\", \"#FFC41661\": \"Secret Affair\", \"#FFE1D2D5\": \"Secret Blush\", \"#FF68909D\": \"Secret Cove\", \"#FFD7DFD6\": \"Secret Crush\", \"#FF11AA66\": \"Secret Garden\", \"#FFB5B88D\": \"Secret Glade\", \"#FF7C6055\": \"Secret Journal\", \"#FF72754F\": \"Secret Meadow\", \"#FF777465\": \"Secret Mission\", \"#FFA2A59D\": \"Secret Moss\", \"#FF372A05\": \"Secret Passage\", \"#FF6D695E\": \"Secret Passageway\", \"#FF737054\": \"Secret Path\", \"#FF9FA89C\": \"Secret Retreat\", \"#FFC6BB68\": \"Secret Safari\", \"#FF7A0E0E\": \"Secret Scarlet\", \"#FFE3D7DC\": \"Secret Scent\", \"#FF464E5A\": \"Secret Society\", \"#FF5389A1\": \"Secure Blue\", \"#FFD6E1C2\": \"Security\", \"#FFD1CDBF\": \"Sedate Grey\", \"#FFB1A591\": \"Sedge\", \"#FF9A8841\": \"Sedge Grasses\", \"#FF707A68\": \"Sedge Green\", \"#FFB0A67E\": \"Sedia\", \"#FFB3A698\": \"Sediment\", \"#FFE7E0CF\": \"Sedona\", \"#FFBF7C45\": \"Sedona at Sunset\", \"#FF886244\": \"Sedona Brown\", \"#FFC16A55\": \"Sedona Canyon\", \"#FFD6B8A7\": \"Sedona Pink\", \"#FF686D6C\": \"Sedona Sage\", \"#FF665F70\": \"Sedona Shadow\", \"#FF8E462F\": \"Sedona Stone\", \"#FFFBF2BF\": \"Seduction\", \"#FFA2C748\": \"Seductive Thorns\", \"#FF734F39\": \"Seed Brown\", \"#FFD7CCC6\": \"Seed Cathedral\", \"#FFE6DAC4\": \"Seed Pearl\", \"#FFDAC43C\": \"Seed Pod\", \"#FFD3C3D4\": \"Seedless Grape\", \"#FFC0CBA1\": \"Seedling\", \"#FFA99BA9\": \"Seeress\", \"#FFAFBBC1\": \"Seersucker\", \"#FFFFF1F1\": \"Sefid White\", \"#FF903037\": \"Sehnsucht Red\", \"#FF3A6960\": \"Seiheki Green\", \"#FF819C8B\": \"Seiji Green\", \"#FF8B8074\": \"Seine\", \"#FFCCC4B0\": \"Seine and Sensibility\", \"#FFE5ABBE\": \"Sekichiku Pink\", \"#FF683F36\": \"Sekkasshoku Brown\", \"#FFE6DFE7\": \"Selago Variant\", \"#FF777E7A\": \"Selenium\", \"#FF8C7591\": \"Self Powered\", \"#FFC2B398\": \"Self-Destruct\", \"#FFD22B6D\": \"Self-Love\", \"#FF4488EE\": \"Seljuk Blue\", \"#FFD4AE5E\": \"Sell Gold\", \"#FF90A2B7\": \"Sell Out\", \"#FFAB9649\": \"Semi Opal\", \"#FF6B5250\": \"Semi Sweet\", \"#FF6B4226\": \"Semi Sweet Chocolate\", \"#FF659B97\": \"Semi-Precious\", \"#FFFFE2B6\": \"Semifreddo\", \"#FFC7AB8B\": \"Semolina\", \"#FFFFE8C7\": \"Semolina Pudding\", \"#FF4CA973\": \"S\\u0113n L\\u00edn L\\u01dc Forest\", \"#FF4A515F\": \"Senate\", \"#FF824B35\": \"Sencha Brown\", \"#FF9A927F\": \"Seneca Rock\", \"#FFFDECC7\": \"Senior Moment\", \"#FF494A41\": \"Sensai Brown\", \"#FF3B3429\": \"Sensaicha Brown\", \"#FF374231\": \"Sensaimidori Green\", \"#FFBFA38D\": \"Sensational Sand\", \"#FFEDB159\": \"Sense of Wonder\", \"#FFEAD7B4\": \"Sensible Hue\", \"#FFCC2266\": \"Sensitive Scorpion\", \"#FFCEC9CC\": \"Sensitive Tint\", \"#FFA1B0BE\": \"Sensitivity\", \"#FFCD68E2\": \"Sensual Fumes\", \"#FFFFD2B6\": \"Sensual Peach\", \"#FFB75E6B\": \"Sensuous\", \"#FF837D7F\": \"Sensuous Grey\", \"#FFE6D8D2\": \"Sentimental\", \"#FFE0D8C5\": \"Sentimental Beige\", \"#FFC4D3DC\": \"Sentimental Lady\", \"#FFF8EEF4\": \"Sentimental Pink\", \"#FFD2E0D6\": \"Sentinel\", \"#FF4B3526\": \"Sepia Brown\", \"#FFCBB499\": \"Sepia Filter\", \"#FFD4BBB6\": \"Sepia Rose\", \"#FF9F5C42\": \"Sepia Skin Variant\", \"#FF8C7562\": \"Sepia Tint\", \"#FFB8A88A\": \"Sepia Tone\", \"#FF995915\": \"Sepia Wash\", \"#FF8C7340\": \"Sepia Yellow\", \"#FFA8BEDD\": \"September Aster\", \"#FFD3C9B9\": \"September Fog\", \"#FF8D7548\": \"September Gold\", \"#FFEDE6B3\": \"September Morn\", \"#FFFFE9BB\": \"September Morning\", \"#FF597570\": \"September Sea\", \"#FFD5D8C8\": \"September Song\", \"#FFFDD7A2\": \"September Sun\", \"#FFD4D158\": \"Sequesta\", \"#FFE1C28D\": \"Sequin\", \"#FF84463B\": \"Sequoia\", \"#FF795953\": \"Sequoia Dusk\", \"#FFC5BBAF\": \"Sequoia Fog\", \"#FF935E4E\": \"Sequoia Grove\", \"#FF506C6B\": \"Sequoia Lake\", \"#FF763F3D\": \"Sequoia Redwood\", \"#FFD88B4D\": \"Serape\", \"#FFD7824B\": \"Seraphim Sepia\", \"#FF616F65\": \"Seraphinite\", \"#FF3E644F\": \"Serbian Green\", \"#FFCFD0C1\": \"Serena\", \"#FFFCE9D7\": \"Serenade Variant\", \"#FF4A4354\": \"Serendibite Black\", \"#FFBDE1D8\": \"Serendipity\", \"#FFA6CDDF\": \"Serendipity Blue\", \"#FFDCE3E4\": \"Serene\", \"#FF1199BB\": \"Serene Blue\", \"#FFBDD9D0\": \"Serene Breeze\", \"#FFCFD8D1\": \"Serene Journey\", \"#FFF5D3B7\": \"Serene Peach\", \"#FFF6C6B9\": \"Serene Pink\", \"#FF7B9F4B\": \"Serene Sage\", \"#FFD2C880\": \"Serene Scene\", \"#FF78A7C3\": \"Serene Sea\", \"#FFC5D2D9\": \"Serene Setting\", \"#FFC3E3EB\": \"Serene Sky\", \"#FF819DAA\": \"Serene Stream\", \"#FFC5C0AC\": \"Serene Thought\", \"#FFCED7D5\": \"Serenely\", \"#FFAB9579\": \"Serengeti\", \"#FFE7DBC9\": \"Serengeti Dust\", \"#FF77CC88\": \"Serengeti Green\", \"#FFFCE7D0\": \"Serengeti Sand\", \"#FF76BAA8\": \"Sereni Teal\", \"#FF91A8D0\": \"Serenity\", \"#FF507BCE\": \"Serenity\\u2019s Reign\", \"#FFDD3744\": \"Serial Kisses\", \"#FF7D848B\": \"Serious Cloud\", \"#FFCEC9C7\": \"Serious Grey\", \"#FFF9E0CD\": \"Serious Moonlight\", \"#FFDCCCB4\": \"Seriously Sand\", \"#FF817F6D\": \"Serpent\", \"#FFBBCC00\": \"Serpent Sceptre\", \"#FF9B8E54\": \"Serpentine\", \"#FFA2B37A\": \"Serpentine Green\", \"#FF003300\": \"Serpentine Shadow\", \"#FF556600\": \"Serrano Pepper\", \"#FF9CA9AD\": \"Seryi Grey\", \"#FFBAA38B\": \"Sesame\", \"#FFC26A35\": \"Sesame Crunch\", \"#FFE1D9B8\": \"Sesame Seed\", \"#FF00A870\": \"Sesame Street Green\", \"#FFE00012\": \"Setsugekka\", \"#FF5CCBC7\": \"Setting Sail\", \"#FF7E7970\": \"Settlement\", \"#FFD3DAE1\": \"Seven Days of Rain\", \"#FF4A5C6A\": \"Seven Seas\", \"#FFDCE2E0\": \"Seven Sisters\", \"#FFE3B8BD\": \"Seven Veils\", \"#FFEEE7DE\": \"Severe Seal\", \"#FF241005\": \"Severely Burnt Toast\", \"#FF955843\": \"Seville Scarlet\", \"#FFBB8A8E\": \"Shabby Chic\", \"#FFEFDDD6\": \"Shabby Chic Pink\", \"#FFAE7181\": \"Shade of Mauve\", \"#FF4E5147\": \"Shade-Grown\", \"#FF786947\": \"Shaded Fern\", \"#FF664348\": \"Shaded Fuchsia\", \"#FF8E824A\": \"Shaded Glen\", \"#FF859C9B\": \"Shaded Hammock\", \"#FFEBAEAC\": \"Shaded Primrose\", \"#FF005F6D\": \"Shaded Spruce\", \"#FFF3EBA5\": \"Shaded Sun\", \"#FF8AB18A\": \"Shaded Willow\", \"#FFBE2BDF\": \"Shades of Rhodonite\", \"#FF9C0009\": \"Shades of Ruby\", \"#FF605F5F\": \"Shades On\", \"#FFE96A97\": \"Shadow Azalea Pink\", \"#FF7A6F66\": \"Shadow Cliff\", \"#FF877D83\": \"Shadow Dance\", \"#FF788788\": \"Shadow Effect\", \"#FF686767\": \"Shadow Gargoyle\", \"#FF9AC0B6\": \"Shadow Green Variant\", \"#FFB09691\": \"Shadow Grey\", \"#FF395648\": \"Shadow Leaf\", \"#FFCCDE95\": \"Shadow Lime\", \"#FF585858\": \"Shadow Mountain\", \"#FF2A4F61\": \"Shadow of Night\", \"#FFA3A2A1\": \"Shadow of the Colossus\", \"#FF356454\": \"Shadow Pine\", \"#FF221144\": \"Shadow Planet\", \"#FF4E334E\": \"Shadow Purple\", \"#FF5B5343\": \"Shadow Ridge\", \"#FF9C917F\": \"Shadow Taupe\", \"#FF5E534A\": \"Shadow Woods\", \"#FF111155\": \"Shadowdancer\", \"#FF4B4B4B\": \"Shadowed Steel\", \"#FF6B6D6A\": \"Shadows\", \"#FF018466\": \"Shadows of Time\", \"#FFDBD6CB\": \"Shady\", \"#FF42808A\": \"Shady Blue\", \"#FF4C4B4C\": \"Shady Character\", \"#FF007865\": \"Shady Glade\", \"#FF635D4C\": \"Shady Green\", \"#FF849292\": \"Shady Grey\", \"#FF9F9B9D\": \"Shady Lady Variant\", \"#FF5555FF\": \"Shady Neon Blue\", \"#FF73694B\": \"Shady Oak\", \"#FF456B67\": \"Shady Palm\", \"#FFC4A1AF\": \"Shady Pink\", \"#FFF0E9DF\": \"Shady White\", \"#FF939689\": \"Shady Willow\", \"#FF645D41\": \"Shagbark Olive\", \"#FFB3AB98\": \"Shaggy Barked\", \"#FFC9B6A1\": \"Shaggy Dog\", \"#FFCBC99D\": \"Shagreen\", \"#FFC3BEA1\": \"Shaken or Stirred?\", \"#FF748C96\": \"Shaker Blue\", \"#FF6C6556\": \"Shaker Grey\", \"#FF886A3F\": \"Shaker Peg\", \"#FF609AB8\": \"Shakespeare Variant\", \"#FF7F4340\": \"Shakker Red\", \"#FFAA3311\": \"Shakshuka\", \"#FF752100\": \"Shaku-Do Copper\", \"#FF4A3F41\": \"Shale\", \"#FF6B886B\": \"Shale Green\", \"#FF899DA3\": \"Shale Grey\", \"#FFF8F6A8\": \"Shalimar Variant\", \"#FF7B8D73\": \"Shallot Bulb\", \"#FF505C3A\": \"Shallot Leaf\", \"#FFEEC378\": \"Shallot Peel\", \"#FFC5F5E8\": \"Shallow End\", \"#FF9AB8C2\": \"Shallow Sea\", \"#FF9DD6D4\": \"Shallow Shoal\", \"#FFB0DEC8\": \"Shallow Shore\", \"#FFBCC2C3\": \"Shallow Skies\", \"#FF8AF1FE\": \"Shallow Water\", \"#FF8CAEAC\": \"Shallow Water Ground\", \"#FFCC855A\": \"Shamanic Journey\", \"#FFFFCFF1\": \"Shampoo\", \"#FF358D52\": \"Shamrock Field\", \"#FF4EA77D\": \"Shamrock Green Variant\", \"#FFFA9A85\": \"Sh\\u0101n H\\u00fa H\\u00f3ng Coral\", \"#FFFFE670\": \"Shandy\", \"#FFAAD9BB\": \"Shanghai Jade\", \"#FFD79A91\": \"Shanghai Peach\", \"#FFC8DFC3\": \"Shanghai Silk\", \"#FFECD4D2\": \"Shangri La\", \"#FF4C1050\": \"Shani Purple\", \"#FFA18B5D\": \"Shank\", \"#FF9BE3D7\": \"Sharbah Fizz\", \"#FFFFA26B\": \"Sharegaki Persimmon\", \"#FFCADCDE\": \"Shark Variant\", \"#FFEE6699\": \"Shark Bait\", \"#FF969795\": \"Shark Fin\", \"#FFA5B4BA\": \"Shark Loop\", \"#FFE4E1D3\": \"Shark Tooth\", \"#FF35524A\": \"Sharknado\", \"#FF808184\": \"Sharkskin\", \"#FF2B3D54\": \"Sharp Blue\", \"#FF007D58\": \"Sharp Green\", \"#FFC9CAD1\": \"Sharp Grey\", \"#FFC0AD28\": \"Sharp Lime\", \"#FFDBD6D8\": \"Sharp Pebbles\", \"#FFECC043\": \"Sharp Yellow\", \"#FFEAE1D6\": \"Sharp-Rip Drill\", \"#FF355C74\": \"Shasta Lake\", \"#FFBB5577\": \"Shattan Gold\", \"#FFB5A088\": \"Shattell\", \"#FFDAEEE6\": \"Shattered Ice\", \"#FFEEE2E0\": \"Shattered Porcelain\", \"#FFD0DDE9\": \"Shattered Sky\", \"#FFF1F1E5\": \"Shattered White\", \"#FF5A4039\": \"Shaved Chocolate\", \"#FFA9B4BA\": \"Shaved Ice\", \"#FFE1E5E5\": \"Shaving Cream\", \"#FFDD9955\": \"Shawarma\", \"#FFE39B96\": \"She Loves Pink\", \"#FFAB214B\": \"She Pouts\", \"#FFF8F1EB\": \"Shea\", \"#FFD2AE84\": \"Sheaf\", \"#FFE8E1CE\": \"Shearling\", \"#FF5B5B6C\": \"Shearwater Black\", \"#FF81876F\": \"Shebang\", \"#FFD9B28B\": \"Sheepskin\", \"#FFAD9E87\": \"Sheepskin Gloves\", \"#FFCBBFA6\": \"Sheepskin Rug\", \"#FFF3C99D\": \"Sheer Apricot\", \"#FFE4D0C3\": \"Sheer Blouse\", \"#FFCFD8D5\": \"Sheer Elegance\", \"#FFB0C69A\": \"Sheer Green\", \"#FFEFE2F2\": \"Sheer Lavender\", \"#FFCDD2CE\": \"Sheer Light\", \"#FFB793C0\": \"Sheer Lilac\", \"#FFFFF7E7\": \"Sheer Peach\", \"#FFF6E5DB\": \"Sheer Pink\", \"#FFFFE8E5\": \"Sheer Rosebud\", \"#FFE3D6CA\": \"Sheer Scarf\", \"#FFFFFEDF\": \"Sheer Sunlight\", \"#FF52616F\": \"Sheet Blue\", \"#FF5E6063\": \"Sheet Metal\", \"#FF638F7B\": \"Sheffield\", \"#FF6B7680\": \"Sheffield Grey\", \"#FFEFECEE\": \"Sheikh White\", \"#FFE6EFEF\": \"Sheikh Zayed White\", \"#FFDCC5BC\": \"Shell\", \"#FFEEE7E6\": \"Shell Brook\", \"#FF56564B\": \"Shell Brown\", \"#FFE88D68\": \"Shell Coral\", \"#FFF9E4D6\": \"Shell Ginger\", \"#FFEBDFC0\": \"Shell Haven\", \"#FFF88180\": \"Shell Pink\", \"#FFFDD7CA\": \"Shell Tint\", \"#FFB6B6A8\": \"Shell Walk\", \"#FFF0EBE0\": \"Shell White\", \"#FFB8986C\": \"Shelter\", \"#FF758F9A\": \"Sheltered Bay\", \"#FFC03F20\": \"Sh\\u0113n Ch\\u00e9ng Orange\", \"#FFBE0620\": \"Sh\\u0113n H\\u00f3ng Red\", \"#FF5A8643\": \"Shepherd\\u2019s Green\", \"#FFC06F68\": \"Shepherd\\u2019s Warning\", \"#FF8F8666\": \"Sheraton Sage\", \"#FFF8C8BB\": \"Sherbet Fruit\", \"#FFFED5A3\": \"Sherbet Pop\", \"#FFEBCFAA\": \"Sheriff\", \"#FF735153\": \"Sheringa Rose\", \"#FF00494E\": \"Sherpa Blue Variant\", \"#FFF9E4DB\": \"Sherry Cream\", \"#FF555A4C\": \"Sherwood Forest\", \"#FF1B4636\": \"Sherwood Green Variant\", \"#FFC99B5F\": \"Shetland\", \"#FFDFD0C0\": \"Shetland Lace\", \"#FFD6A48D\": \"Shetland Pony\", \"#FFBBCFD4\": \"Shhh\\u2026\", \"#FFE29F31\": \"Sh\\u00ec Z\\u01d0 Ch\\u00e9ng Persimmon\", \"#FF9900AA\": \"Shiffurple\", \"#FFD6C0AB\": \"Shifting Sand\", \"#FFA5988A\": \"Shiitake\", \"#FF2B2028\": \"Shikon\", \"#FFE6B2A6\": \"Shilo Variant\", \"#FF88C7E9\": \"Shimmer\", \"#FF82DBCC\": \"Shimmering Blue\", \"#FF64B3D3\": \"Shimmering Brook\", \"#FFF3DEBC\": \"Shimmering Champagne\", \"#FF45E9FD\": \"Shimmering Expanse Cyan\", \"#FFA4943A\": \"Shimmering Glade\", \"#FFFF88CC\": \"Shimmering Love\", \"#FFD2EFE6\": \"Shimmering Pool\", \"#FF2B526A\": \"Shimmering Sea\", \"#FFDBD1E8\": \"Shimmering Sky\", \"#FF9A373F\": \"Shin Godzilla\", \"#FF59B9C6\": \"Shinbashi\", \"#FF006C7F\": \"Shinbashi Azure\", \"#FF00A990\": \"Shindig\", \"#FFA85E6E\": \"Shine Baby Shine\", \"#FF773CA7\": \"Shiner\", \"#FF745937\": \"Shingle Fawn Variant\", \"#FF908B8E\": \"Shining Armour\", \"#FFFCDA89\": \"Shining Bright\", \"#FFFFD200\": \"Shining Gold\", \"#FF989EA7\": \"Shining Knight\", \"#FFC7C7C9\": \"Shining Silver\", \"#FFF0E185\": \"Shinjuku Gold\", \"#FFDACDCD\": \"Shinkansen White\", \"#FF8F1D21\": \"Shinshu\", \"#FFA1A9A8\": \"Shiny Armour\", \"#FFAE9F65\": \"Shiny Gold\", \"#FFCEA190\": \"Shiny Kettle\", \"#FFDBDDDB\": \"Shiny Lustre\", \"#FFCCD3D8\": \"Shiny Nickel\", \"#FF3A363B\": \"Shiny Rubber\", \"#FFF7ECCA\": \"Shiny Silk\", \"#FFECAE58\": \"Shiny Trumpet\", \"#FF7988AB\": \"Ship Cove Variant\", \"#FF709797\": \"Ship Shape\", \"#FF62493B\": \"Ship Steering Wheel\", \"#FF4F84AF\": \"Ship\\u2019s Harbour\", \"#FF2D3A49\": \"Ship\\u2019s Officer\", \"#FF7AA3CC\": \"Shipmate\", \"#FF968772\": \"Shipwreck\", \"#FF4F6F85\": \"Shipyard\", \"#FFC48E69\": \"Shiracha Brown\", \"#FF842833\": \"Shiraz Variant\", \"#FF646B59\": \"Shire\", \"#FF68E52F\": \"Shire Green\", \"#FFF19000\": \"Shiritorier\\u2019s Orange\", \"#FFEBF5F0\": \"Shiroi White\", \"#FFFEDDCB\": \"Shironeri Silk\", \"#FF6598AF\": \"Shirt Blue\", \"#FF3C3B3C\": \"Shisha Coal\", \"#FFEFAB93\": \"Shishi Pink\", \"#FFBBF90F\": \"Shishito Pepper Green\", \"#FF63A950\": \"Shiso Green\", \"#FF99DBFE\": \"Shiva Blue\", \"#FF24DD7E\": \"Shivering Green\", \"#FFBB88AA\": \"Shock Jockey\", \"#FFE899BE\": \"Shocking Variant\", \"#FFFF0D04\": \"Shocking Crimson\", \"#FFFF6E1C\": \"Shocking Orange\", \"#FFFE02A2\": \"Shocking Pink Variant\", \"#FFFF006A\": \"Shocking Rose\", \"#FF72C8B8\": \"Shockwave\", \"#FF2B2B2B\": \"Shoe Wax\", \"#FFEAE4D9\": \"Shoelace\", \"#FFF6EBD3\": \"Shoelace Beige\", \"#FFDED5C7\": \"Sh\\u014dji\", \"#FFE2041B\": \"Shojo\\u2019s Blood\", \"#FFDC3023\": \"Sh\\u014dj\\u014dhi Red\", \"#FFECF0EB\": \"Shooting Star\", \"#FF5A4743\": \"Shopping Bag\", \"#FF81D5C6\": \"Shore\", \"#FF6797A2\": \"Shore Water\", \"#FFEAD9CB\": \"Shoreland\", \"#FF6C8791\": \"Shoreline\", \"#FF58C6AB\": \"Shoreline Green\", \"#FFD2CBBC\": \"Shoreline Haze\", \"#FFEDD1D3\": \"Short and Sweet\", \"#FFBBDFD5\": \"Short Phase\", \"#FFF5E6D3\": \"Shortbread\", \"#FFEACEB0\": \"Shortbread Cookie\", \"#FFEEDAAC\": \"Shortcake\", \"#FF9E957C\": \"Shortgrass Prairie\", \"#FF1D0D1D\": \"Shot in the Dark\", \"#FF4A5C69\": \"Shot Over\", \"#FF716B63\": \"Shot-Put\", \"#FF37C4FA\": \"Shovel Knight\", \"#FFDD835B\": \"Show Business\", \"#FFA42E37\": \"Show-Stopper\", \"#FF93AEBC\": \"Showcase Blue\", \"#FF9FADB7\": \"Shower\", \"#FF7737AA\": \"Shredder Lavender\", \"#FFE29A86\": \"Shrimp\", \"#FFF5BE9D\": \"Shrimp Boat\", \"#FFDBBFA3\": \"Shrimp Boudin\", \"#FFF4A461\": \"Shrimp Cocktail\", \"#FFFAAB77\": \"Shrimp Shell\", \"#FFF7C5A0\": \"Shrimp Toast\", \"#FFCC3388\": \"Shrine of Pleasures\", \"#FF5D84B1\": \"Shrinking Violet\", \"#FF003636\": \"Shrub Green\", \"#FFA9C08A\": \"Shrubbery\", \"#FFB5D1DB\": \"Shrubby Lichen\", \"#FFEB6101\": \"Shu Red\", \"#FFDCCCA3\": \"Shui Jiao Dumpling\", \"#FF2B64AD\": \"Shukra Blue\", \"#FF333344\": \"Shuriken\", \"#FF666E7F\": \"Shutter Blue\", \"#FFBB6622\": \"Shutter Copper\", \"#FF797F7D\": \"Shutter Grey\", \"#FFBBA262\": \"Shutterbug\", \"#FF6C705E\": \"Shutters\", \"#FF61666B\": \"Shuttle Grey\", \"#FFE2DED6\": \"Shy Beige\", \"#FFD3D8DE\": \"Shy Blunt\", \"#FFD6DDE6\": \"Shy Candela\", \"#FFDEA392\": \"Shy Champagne Blush\", \"#FFF0D6CA\": \"Shy Cupid\", \"#FFD7DADD\": \"Shy Denim\", \"#FFFFD7CF\": \"Shy Girl\", \"#FFE5E8D9\": \"Shy Green\", \"#FFAA0055\": \"Shy Guy Red\", \"#FFE0E4DB\": \"Shy Mint\", \"#FFAAAAFF\": \"Shy Moment\", \"#FFDFD9DC\": \"Shy Pink\", \"#FFDCBBBE\": \"Shy Smile\", \"#FFDDAC9A\": \"Shy Time\", \"#FFD6C7D6\": \"Shy Violet\", \"#FFDFB8BC\": \"Shy Young Salmon\", \"#FF5AB9A4\": \"Shylock\", \"#FFF3F3D9\": \"Shyness\", \"#FF686B50\": \"Siam Variant\", \"#FF896F40\": \"Siam Gold\", \"#FF9DAC79\": \"Siamese Green\", \"#FFEFE1D5\": \"Siamese Kitten\", \"#FFCF8D9A\": \"Sianna Rose\", \"#FFEEE2D5\": \"Siberian Fur\", \"#FF4E6157\": \"Siberian Green\", \"#FFC1CCD6\": \"Siberian Ice\", \"#FFFF44FF\": \"Sicilia Bougainvillaea\", \"#FFFCC792\": \"Sicilian Villa\", \"#FFC1C6AD\": \"Sicily Sea\", \"#FF502D86\": \"Sick Blue\", \"#FF9DB92C\": \"Sick Green\", \"#FF94B21C\": \"Sickly Green\", \"#FFD0E429\": \"Sickly Yellow\", \"#FFE9D9A9\": \"Sidecar Variant\", \"#FFBFC3AE\": \"Sidekick\", \"#FFA17858\": \"Sidesaddle\", \"#FFE2C591\": \"Sideshow\", \"#FFDBE9ED\": \"Sidewalk Chalk Blue\", \"#FFF7CCC4\": \"Sidewalk Chalk Pink\", \"#FF7B8F99\": \"Sidewalk Grey\", \"#FFA9561E\": \"Sienna\", \"#FFCDA589\": \"Sienna Buff\", \"#FFDCC4AC\": \"Sienna Dust\", \"#FFDE9F83\": \"Sienna Ochre\", \"#FFB1635E\": \"Sienna Red\", \"#FFBC735A\": \"Sienna Sky\", \"#FFF1D28C\": \"Sienna Yellow\", \"#FFA35C46\": \"Sierra\", \"#FFA28A67\": \"Sierra Foothills\", \"#FFC2BCAE\": \"Sierra Madre\", \"#FFED9181\": \"Sierra Pink\", \"#FF924E3C\": \"Sierra Redwood\", \"#FFAFA28F\": \"Sierra Sand\", \"#FFF0C3A7\": \"Siesta\", \"#FFC9A480\": \"Siesta Dreams\", \"#FFEC7878\": \"Siesta Rose\", \"#FFF1E6E0\": \"Siesta Sands\", \"#FFE9D8C8\": \"Siesta Tan\", \"#FFCBDADB\": \"Siesta White\", \"#FFABB6AC\": \"Sigh of Relief\", \"#FF76A4A6\": \"Sightful\", \"#FFCAAD76\": \"Sigmarite\", \"#FFE3EDE2\": \"Sign of Spring\", \"#FFFCE299\": \"Sign of the Crown\", \"#FF33FF00\": \"Signal Green\", \"#FF838684\": \"Signal Grey\", \"#FFB15384\": \"Signal Pink\", \"#FFECECE6\": \"Signal White\", \"#FF455371\": \"Signature Blue\", \"#FFEAEDE5\": \"Silence\", \"#FFC2A06D\": \"Silence Is Golden\", \"#FFE9F1EC\": \"Silent Breath\", \"#FFC6EAEC\": \"Silent Breeze\", \"#FFE5E7E8\": \"Silent Delight\", \"#FF9FA5A5\": \"Silent Film\", \"#FF526771\": \"Silent Night\", \"#FF231C4D\": \"Silent Orbit\", \"#FFABE3DE\": \"Silent Ripple\", \"#FFBAD9D9\": \"Silent River\", \"#FF729988\": \"Silent Sage\", \"#FFA99582\": \"Silent Sands\", \"#FF3A4A63\": \"Silent Sea\", \"#FFDBD7CE\": \"Silent Smoke\", \"#FFEEF7FA\": \"Silent Snowfall\", \"#FFC3C7BD\": \"Silent Storm\", \"#FF7C929A\": \"Silent Tide\", \"#FF0F084B\": \"Silent Twilight\", \"#FFE3E7E4\": \"Silent White\", \"#FFCCBBBB\": \"Silentropae Cloud\", \"#FFB29E81\": \"Silestone\", \"#FFCBCDC4\": \"Silhouette\", \"#FFDBD4BF\": \"Silica\", \"#FFEDE2E0\": \"Silica Sand\", \"#FF88B2A9\": \"Silicate Green\", \"#FFCDDAD3\": \"Silicate Light Turquoise\", \"#FF5A3D4A\": \"Siliceous Red\", \"#FFEBE0CA\": \"Silicone Seduction\", \"#FFDCDCCF\": \"Silicone Serena\", \"#FFD57B65\": \"Silithus Brown\", \"#FFBBADA1\": \"Silk Variant\", \"#FFCCBFC7\": \"Silk Chiffon\", \"#FF354E4B\": \"Silk Crepe Grey\", \"#FF6E7196\": \"Silk Crepe Mauve\", \"#FFEEE9DC\": \"Silk Dessou\", \"#FFF6E8DE\": \"Silk Elegance\", \"#FFECDDC9\": \"Silk for the Gods\", \"#FFFCEEDB\": \"Silk Gown\", \"#FF02517A\": \"Silk Jewel\", \"#FF70939E\": \"Silk Khimar\", \"#FF9188B5\": \"Silk Lilac\", \"#FFFCEFE0\": \"Silk Lining\", \"#FFF3F0EA\": \"Silk Pillow\", \"#FFC86E8B\": \"Silk Ribbon\", \"#FF97976F\": \"Silk Road\", \"#FFF6EECD\": \"Silk Sails\", \"#FF009283\": \"Silk Sari\", \"#FF8B4248\": \"Silk Satin\", \"#FFEFDDDF\": \"Silk Sheets\", \"#FFA5B2C7\": \"Silk Sox\", \"#FFF5EEC6\": \"Silk Star\", \"#FFCC9999\": \"Silk Stone\", \"#FFF0DFC9\": \"Silk Teddy\", \"#FFB77D5F\": \"Silken Chocolate\", \"#FFFCE17C\": \"Silken Gold\", \"#FF11A39E\": \"Silken Jade\", \"#FF427584\": \"Silken Peacock\", \"#FFD0D0C9\": \"Silken Pebble\", \"#FF495D5A\": \"Silken Pine\", \"#FFAA7D89\": \"Silken Raspberry\", \"#FFE81320\": \"Silken Ruby\", \"#FFD6BEA1\": \"Silken Stockings\", \"#FFFEF6D8\": \"Silken Tofu\", \"#FFDADCD4\": \"Silken Web\", \"#FFFDEFDB\": \"Silkie Chicken\", \"#FFEEEECC\": \"Silkworm\", \"#FFEAE0CD\": \"Silky Bamboo\", \"#FFBDC2BB\": \"Silky Green\", \"#FFD7ECD9\": \"Silky Mint\", \"#FFFFF5E4\": \"Silky Tofu\", \"#FFEFEBE2\": \"Silky White\", \"#FFF2F3CD\": \"Silky Yoghurt\", \"#FFF4B0BB\": \"Silly Puddy\", \"#FF8A7D72\": \"Silt\", \"#FFA3B9AC\": \"Silt Green\", \"#FFDDDBD0\": \"Silver Ash\", \"#FFB8B4B6\": \"Silver Bells\", \"#FFD2CFC4\": \"Silver Birch\", \"#FFFBF5F0\": \"Silver Bird\", \"#FF8A9A9A\": \"Silver Blue\", \"#FF5B7085\": \"Silver Blueberry\", \"#FFBABAB5\": \"Silver Bonnet\", \"#FFB6B5B8\": \"Silver Bullet\", \"#FFACAEA9\": \"Silver Chalice Variant\", \"#FFADB0B4\": \"Silver Charm\", \"#FFE2E4E9\": \"Silver City\", \"#FFA6AAA2\": \"Silver Clouds\", \"#FFD9DAD2\": \"Silver Creek\", \"#FFCDC5C2\": \"Silver Cross\", \"#FFC1C1D1\": \"Silver Dagger\", \"#FFBDB6AE\": \"Silver Dollar\", \"#FF9AB2A9\": \"Silver Drop\", \"#FFB4C8D2\": \"Silver Dusk\", \"#FFE8E7E0\": \"Silver Dust\", \"#FFCFCFCF\": \"Silver Eagle\", \"#FF899587\": \"Silver Eucalyptus\", \"#FFEDEBE7\": \"Silver Feather\", \"#FFE1DDBF\": \"Silver Fern\", \"#FF7F7C81\": \"Silver Filigree\", \"#FF7196A2\": \"Silver Fir Blue\", \"#FFBDBCC4\": \"Silver Fox\", \"#FFC6CEC3\": \"Silver Grass\", \"#FFDFE4DC\": \"Silver Grass Traces\", \"#FFD7D7C7\": \"Silver Green\", \"#FFA8A8A4\": \"Silver Grey\", \"#FF6D747B\": \"Silver Hill\", \"#FFDEDDDD\": \"Silver Lake\", \"#FF5686B4\": \"Silver Lake Blue\", \"#FFD8DCC8\": \"Silver Laurel\", \"#FF9DB7A5\": \"Silver Leaf\", \"#FF859382\": \"Silver Linden Grey\", \"#FFBBBFC3\": \"Silver Lined\", \"#FFB8B1A5\": \"Silver Lining\", \"#FFA8A798\": \"Silver Lustre\", \"#FF71776E\": \"Silver Maple Green\", \"#FFC8C8C0\": \"Silver Marlin\", \"#FFDBCCD3\": \"Silver Mauve\", \"#FFD6D6D6\": \"Silver Medal\", \"#FFBEC2C1\": \"Silver Mine\", \"#FF9F8D7C\": \"Silver Mink\", \"#FFB4B9B9\": \"Silver Mistral\", \"#FFD9D7C9\": \"Silver Moon\", \"#FFB6BCB2\": \"Silver Moss\", \"#FFE1C1B9\": \"Silver Peony\", \"#FFEBECF5\": \"Silver Phoenix\", \"#FF526E6B\": \"Silver Pine\", \"#FFD9A8A8\": \"Silver Pink\", \"#FFC6C6C6\": \"Silver Polish\", \"#FFD29EA6\": \"Silver Rose\", \"#FFC9A0DF\": \"Silver Rust Variant\", \"#FF8E8572\": \"Silver Sage\", \"#FFDADEDD\": \"Silver Sand Variant\", \"#FFC7C6C0\": \"Silver Sateen\", \"#FFA19FA5\": \"Silver Sconce\", \"#FFA6AEAA\": \"Silver Screen\", \"#FFB2AAAA\": \"Silver Service\", \"#FFD8DADB\": \"Silver Setting\", \"#FFD8DAD8\": \"Silver Shadow\", \"#FF87A1B1\": \"Silver Skate\", \"#FFEAECE9\": \"Silver Sky\", \"#FF8E9090\": \"Silver Snippet\", \"#FFD3D3D2\": \"Silver Spoon\", \"#FFB7BDC4\": \"Silver Springs\", \"#FFCADFDD\": \"Silver Spruce\", \"#FF98A0B8\": \"Silver Star\", \"#FF8599A8\": \"Silver Storm\", \"#FFB8C7CE\": \"Silver Strand\", \"#FFCACDCA\": \"Silver Strand Beach\", \"#FFF2C1C0\": \"Silver Strawberry\", \"#FF7E7D88\": \"Silver Surfer\", \"#FFC4C9E2\": \"Silver Sweetpea\", \"#FFB8B2A2\": \"Silver Taupe\", \"#FFE7D5C5\": \"Silver Thistle Beige\", \"#FFCAC9C2\": \"Silver Thistle Down\", \"#FFB6B3A9\": \"Silver Tinsel\", \"#FFBFC3BF\": \"Silver Tipped Sage\", \"#FFD9D9D3\": \"Silver Tradition\", \"#FF67BE90\": \"Silver Tree Variant\", \"#FFBBC5C4\": \"Silver Whiskers\", \"#FFE7E8E3\": \"Silver White\", \"#FF637C5B\": \"Silver Willow Green\", \"#FFCDC7C7\": \"Silver-Tongued\", \"#FF6A6472\": \"Silverado\", \"#FFA7A89B\": \"Silverado Ranch\", \"#FFB7BBC6\": \"Silverado Trail\", \"#FFCBCBCB\": \"Silverback\", \"#FF5A6A43\": \"Silverbeet\", \"#FFBEBBC9\": \"Silverberry\", \"#FF8D95AA\": \"Silverfish\", \"#FFB0B8B2\": \"Silvermist\", \"#FFC2C0BA\": \"Silverplate\", \"#FFD1D2CB\": \"Silverpointe\", \"#FFB1B3B3\": \"Silverstone\", \"#FFBFD9CE\": \"Silverton\", \"#FFB8B8BF\": \"Silverware\", \"#FFE6E5DC\": \"Silvery Moon\", \"#FFD5DBD5\": \"Silvery Streak\", \"#FF2F4E4E\": \"Similar\", \"#FF4C3D30\": \"Simmered Seaweed\", \"#FFCB9281\": \"Simmering Ridge\", \"#FFA99F96\": \"Simmering Smoke\", \"#FFA8C1D4\": \"Simpatico Blue\", \"#FFBABAAD\": \"Simple Grey\", \"#FFF9A3AA\": \"Simple Pink\", \"#FFF1D8B2\": \"Simple Pleasures\", \"#FF84737A\": \"Simple Plum\", \"#FFC8D9E5\": \"Simple Serenity\", \"#FF7A716E\": \"Simple Silhouette\", \"#FFCDC7B7\": \"Simple Stone\", \"#FFDFD9D2\": \"Simple White\", \"#FFCED0DB\": \"Simplicity\", \"#FFD6C7B9\": \"Simplify Beige\", \"#FF58CEB2\": \"Simply Aqua\", \"#FFADBBC9\": \"Simply Blue\", \"#FFFBAD90\": \"Simply Coral\", \"#FFFFD2C1\": \"Simply Delicious\", \"#FFCEDDE7\": \"Simply Elegant\", \"#FF00AA81\": \"Simply Green\", \"#FFDAC4DC\": \"Simply Lavender\", \"#FFFFC06C\": \"Simply Peachy\", \"#FF8CB9D4\": \"Simply Posh\", \"#FF715BB1\": \"Simply Purple\", \"#FFA7A996\": \"Simply Sage\", \"#FFC2852E\": \"Simply Sienna\", \"#FFB0C5E0\": \"Simply Sparkling\", \"#FFE6D2BF\": \"Simply Subtle Pink\", \"#FFAD9F93\": \"Simply Taupe\", \"#FFA6A1D7\": \"Simply Violet\", \"#FFEBEDE7\": \"Simply White\", \"#FF82856D\": \"Simpson Surprise\", \"#FFFFD90F\": \"Simpsons Yellow\", \"#FFCFA236\": \"Sin City\", \"#FFFFD500\": \"Sinag Gold\", \"#FF4675B7\": \"Sinatra\", \"#FFA6D5D0\": \"Sinbad Variant\", \"#FF645059\": \"Sinful\", \"#FF8E9C98\": \"Singing in the Rain\", \"#FF2B4D68\": \"Singing the Blues\", \"#FF713E39\": \"Single Origin\", \"#FF12110E\": \"Sinister\", \"#FF353331\": \"Sinister Minister\", \"#FFA89C94\": \"Sinister Mood\", \"#FF4C4DFF\": \"Siniy Blue\", \"#FF49716D\": \"Sinkhole\", \"#FFD8B778\": \"Sinking Sand\", \"#FFFEE5CB\": \"Sinner\\u2019s City\", \"#FFBB1111\": \"Sinoper Red\", \"#FFB6BD4A\": \"Sinsemilla\", \"#FFDEDFC9\": \"Sip of Mint\", \"#FFEAE2DF\": \"Sip of Nut Milk\", \"#FF20415D\": \"Sir Edmund\", \"#FF69293B\": \"Siren Variant\", \"#FF68A43C\": \"Siren of Nature\", \"#FFB21D1D\": \"Siren Scarlet\", \"#FFF3DECE\": \"Siren Song\", \"#FF68766E\": \"Sirocco Variant\", \"#FF884411\": \"Sis Kebab\", \"#FFC5BAA0\": \"Sisal Variant\", \"#FFC8C76F\": \"Siskin Green\", \"#FF7A942E\": \"Siskin Sprout\", \"#FF863F76\": \"Sister Loganberry Frost\", \"#FFDCDEDC\": \"Site White\", \"#FF3C2233\": \"Sitter Red\", \"#FFF4E2D9\": \"Sitting Pretty\", \"#FF3D322E\": \"Six Feet Under\", \"#FFFD02FF\": \"Sixteen Million Pink\", \"#FF0079A9\": \"Sixties Blue\", \"#FF1C1B1A\": \"Siy\\u00e2h Black\", \"#FF8E3537\": \"Sizzling Bacon\", \"#FFA36956\": \"Sizzling Hot\", \"#FFEB7E4D\": \"Sizzling Sunset\", \"#FFFA005C\": \"Sizzling Watermelon\", \"#FF5F9370\": \"Skarsnik Green\", \"#FF47413B\": \"Skavenblight Dinge\", \"#FFEBDECC\": \"Skeleton\", \"#FFF4EBBC\": \"Skeleton Bone\", \"#FF773399\": \"Skeletor\\u2019s Cape\", \"#FFC9133E\": \"Ski Patrol\", \"#FFE1E5E3\": \"Ski Slope\", \"#FFD2E3E5\": \"Ski White\", \"#FF4477DD\": \"Skies of Cyberspace\", \"#FF41332F\": \"Skilandis\", \"#FFFEFFE3\": \"Skimmed Milk White\", \"#FF5CBFCE\": \"Skink Blue\", \"#FFC3D7E0\": \"Skinny Dippin\\u2019\", \"#FF5588FF\": \"Skinny Jeans\", \"#FF748796\": \"Skipper\", \"#FF4C4D78\": \"Skipper Blue\", \"#FFD1D0C9\": \"Skipping Rocks\", \"#FFD0CBB6\": \"Skipping Stone\", \"#FF51B73B\": \"Skirret Green\", \"#FFB04E0F\": \"Skrag Brown\", \"#FFF1C78E\": \"Skullcrusher Brass\", \"#FFF9F5DA\": \"Skullfire\", \"#FF76D6FF\": \"Sky\", \"#FF88C1D8\": \"Sky Babe\", \"#FF9FB9E2\": \"Sky Blue Variant\", \"#FFDCBFE1\": \"Sky Blue Pink\", \"#FFA2DCD3\": \"Sky Blue View\", \"#FF99C1D6\": \"Sky Bus\", \"#FF242933\": \"Sky Captain\", \"#FFA5CAD1\": \"Sky Chase\", \"#FFA0BDD9\": \"Sky City\", \"#FFADDEE5\": \"Sky Cloud\", \"#FF4499FF\": \"Sky Dancer\", \"#FF8EAABD\": \"Sky Eyes\", \"#FF89C6DF\": \"Sky Fall\", \"#FFD1DCD8\": \"Sky Glass\", \"#FFB6C3C1\": \"Sky Grey\", \"#FFA7C2EB\": \"Sky High\", \"#FFCADADE\": \"Sky Light View\", \"#FF546977\": \"Sky Lodge\", \"#FF0099FF\": \"Sky of Magritte\", \"#FF82CDE5\": \"Sky of Ocean\", \"#FFA2BAD4\": \"Sky Pilot\", \"#FF4B7B87\": \"Sky Space\", \"#FFC9D3D3\": \"Sky Splash\", \"#FFB8DCED\": \"Sky Wanderer\", \"#FF8ACFD6\": \"Sky Watch\", \"#FFBBCEE0\": \"Sky\\u2019s the Limit\", \"#FF66CCFF\": \"Skyan\", \"#FF60BFD3\": \"Skydive\", \"#FFC6D6D7\": \"Skydiving\", \"#FF38A3CC\": \"Skydome\", \"#FF6BCCC1\": \"Skylar\", \"#FFC1E4F0\": \"Skylark\", \"#FFB8D6D7\": \"Skylight\", \"#FF959EB7\": \"Skyline\", \"#FFB9C0C3\": \"Skyline Steel\", \"#FF1F7CC2\": \"Skylla\", \"#FF818DB3\": \"Skysail Blue\", \"#FF6CB3D8\": \"Skyscape\", \"#FFD3DBE2\": \"Skyscraper\", \"#FFDCD7CD\": \"Skyvory\", \"#FFC1DEEA\": \"Skywalker\", \"#FF8FFE08\": \"Skywalker Green\", \"#FFA6C4CA\": \"Skyward\", \"#FFA6BBCF\": \"Skyway\", \"#FFC9E0EA\": \"Skywriter\", \"#FFDBD5E6\": \"Slaanesh Grey\", \"#FFC9CC4A\": \"Slap Happy\", \"#FF516572\": \"Slate\", \"#FF4B3D33\": \"Slate Black\", \"#FFA0987C\": \"Slate Brown\", \"#FF465355\": \"Slate Court\", \"#FF6E7F8D\": \"Slate Expectations\", \"#FF658D6D\": \"Slate Green\", \"#FF59656D\": \"Slate Grey\", \"#FF625C63\": \"Slate Mauve\", \"#FFB4ADA9\": \"Slate Pebble\", \"#FFB3586C\": \"Slate Pink\", \"#FF868988\": \"Slate Rock\", \"#FFBA6671\": \"Slate Rose\", \"#FFACB4AC\": \"Slate Stone\", \"#FF606E74\": \"Slate Tile\", \"#FF7A818D\": \"Slate Tint\", \"#FF989192\": \"Slate Violet\", \"#FF40535D\": \"Slate Wall\", \"#FF4C5055\": \"Sled\", \"#FF825D2A\": \"Sleek Otter\", \"#FFFAF6E9\": \"Sleek White\", \"#FF4579AC\": \"Sleep\", \"#FFBED1E1\": \"Sleep Baby Sleep\", \"#FF98BDDD\": \"Sleeping Easy\", \"#FF786D5E\": \"Sleeping Giant\", \"#FFD8D3CF\": \"Sleeping Inn\", \"#FFBADBED\": \"Sleepless Blue\", \"#FFB2B8B1\": \"Sleepy\", \"#FFBCCBCE\": \"Sleepy Blue\", \"#FF9B9028\": \"Sleepy Hamlet\", \"#FF839C6D\": \"Sleepy Hollow\", \"#FFDCC7D5\": \"Sleepy Kisses\", \"#FFA2A1A1\": \"Sleepy Kitten\", \"#FFB5A78D\": \"Sleepy Owlet\", \"#FF8A8C94\": \"Sleet\", \"#FFDEC29F\": \"Slender Reed\", \"#FFC0AA60\": \"Slender Stem\", \"#FFBD997A\": \"Slice of Brioche\", \"#FF0022EE\": \"Slice of Heaven\", \"#FFE1697C\": \"Slice of Watermelon\", \"#FFCCCFBF\": \"Sliced Cucumber\", \"#FFEDE5BC\": \"Slices of Happy\", \"#FF73CCD8\": \"Slick Blue\", \"#FF615D4C\": \"Slick Green\", \"#FFA66E49\": \"Slick Mud\", \"#FF97AEAF\": \"Sliding\", \"#FFCFC9C5\": \"Slight Mushroom\", \"#FFCB904E\": \"Slightly Golden\", \"#FFFCE6DB\": \"Slightly in Love\", \"#FFF1DDD8\": \"Slightly Peach\", \"#FFE6CFCE\": \"Slightly Rose\", \"#FF92D2ED\": \"Slightly Spritzig\", \"#FFDCE4DD\": \"Slightly Zen\", \"#FFA7C408\": \"Slime\", \"#FF00BB88\": \"Slime Girl\", \"#FFB8EBC5\": \"Slime Lime\", \"#FFAADD00\": \"Slimer Green\", \"#FF7DED17\": \"Slimy Green\", \"#FFBFC1CB\": \"Slipper Satin\", \"#FFBEBA82\": \"Slippery Moss\", \"#FFF87E63\": \"Slippery Salmon\", \"#FF7B766C\": \"Slippery Shale\", \"#FFEFEDD8\": \"Slippery Soap\", \"#FF8D6A4A\": \"Slippery Stone\", \"#FFD5F3EC\": \"Slippery Tub\", \"#FFC3D4E8\": \"Slipstream\", \"#FFD2B698\": \"Slopes\", \"#FFDBDCC4\": \"Slow Dance\", \"#FFDDE3DC\": \"Slow Down\", \"#FFC6D5C9\": \"Slow Green\", \"#FFD5D4CE\": \"Slow Perch\", \"#FFE1C2BE\": \"Slubbed Silk\", \"#FFCA6B02\": \"Sludge\", \"#FF42342B\": \"Slugger\", \"#FF2D517C\": \"Slumber\", \"#FFCDC5B5\": \"Slumber Sloth\", \"#FFD6CEC4\": \"Slush\", \"#FF804741\": \"Sly Fox\", \"#FFF8E2D9\": \"Sly Shrimp\", \"#FFAC9A7E\": \"Smallmouth Bass\", \"#FF496267\": \"Smalt Blue Variant\", \"#FF4A9976\": \"Smaragdine\", \"#FF8775A1\": \"Smashed Grape\", \"#FFE2D0B9\": \"Smashed Potatoes\", \"#FFFF6D3A\": \"Smashed Pumpkin\", \"#FFFF5522\": \"Smashing Pumpkins\", \"#FFD9DDCB\": \"Smell of Garlic\", \"#FFDCE0EA\": \"Smell of Lavender\", \"#FFBEF7CF\": \"Smell the Mint\", \"#FFBB7283\": \"Smell the Roses\", \"#FFD7CECD\": \"Smells of Fresh Bread\", \"#FFF0CCD9\": \"Smidgen of Love\", \"#FF313138\": \"Smiler\\u2019s Mist\", \"#FFFFC962\": \"Smiley Face\", \"#FF3B646C\": \"Smock Blue\", \"#FFBFC8C3\": \"Smoke\", \"#FF939789\": \"Smoke & Ash\", \"#FFD9E6E8\": \"Smoke and Mirrors\", \"#FFCC7788\": \"Smoke Bush\", \"#FFAD8177\": \"Smoke Bush Rose\", \"#FFADB6B9\": \"Smoke Cloud\", \"#FFCCBBAA\": \"Smoke Dragon\", \"#FFCEBAA8\": \"Smoke Grey\", \"#FFB1B8B2\": \"Smoke Infusion\", \"#FF9BACB3\": \"Smoke on the Water\", \"#FF446B61\": \"Smoke Pine\", \"#FFBB5F34\": \"Smoke Tree\", \"#FF84625A\": \"Smoked Almond\", \"#FF5A4351\": \"Smoked Amethyst\", \"#FF3B2F2F\": \"Smoked Black Coffee\", \"#FF583A39\": \"Smoked Claret\", \"#FF674244\": \"Smoked Flamingo\", \"#FFF2B381\": \"Smoked Ham\", \"#FFCEB5B3\": \"Smoked Lavender\", \"#FFA89C97\": \"Smoked Mauve\", \"#FF725F6C\": \"Smoked Mulberry\", \"#FF573F16\": \"Smoked Oak Brown\", \"#FFD9D2CD\": \"Smoked Oyster\", \"#FF793A30\": \"Smoked Paprika\", \"#FF6F6E70\": \"Smoked Pearl\", \"#FF444251\": \"Smoked Purple\", \"#FFDDBBCC\": \"Smoked Silver\", \"#FFAEA494\": \"Smoked Tan\", \"#FFD0C6BD\": \"Smoked Umber\", \"#FF716354\": \"Smokehouse\", \"#FF5E5755\": \"Smokescreen\", \"#FFBEB2A5\": \"Smokestack\", \"#FF647B84\": \"Smokey Blue\", \"#FF88716D\": \"Smokey Claret\", \"#FFE9DFD5\": \"Smokey Cream\", \"#FF747B92\": \"Smokey Denim\", \"#FF928996\": \"Smokey Lilac\", \"#FFCEBDB4\": \"Smokey Pink\", \"#FFA5B5AC\": \"Smokey Slate\", \"#FF9A9DA2\": \"Smokey Stone\", \"#FF9F8C7C\": \"Smokey Tan\", \"#FFA57B5B\": \"Smokey Topaz Variant\", \"#FFA7A5A3\": \"Smokey Wings\", \"#FF954A3D\": \"Smokin Hot\", \"#FFA29587\": \"Smoking Mirror\", \"#FF43454C\": \"Smoking Night Blue\", \"#FF992200\": \"Smoking Red\", \"#FF605D6B\": \"Smoky Variant\", \"#FF708D9E\": \"Smoky Azurite\", \"#FFB9A796\": \"Smoky Beige\", \"#FF7196A6\": \"Smoky Blue\", \"#FF34282C\": \"Smoky Charcoal\", \"#FFA49E93\": \"Smoky Day\", \"#FF4C726B\": \"Smoky Emerald\", \"#FF817D68\": \"Smoky Forest\", \"#FF9B8FA6\": \"Smoky Grape\", \"#FF939087\": \"Smoky Grey Green\", \"#FFD7D9C6\": \"Smoky Light\", \"#FF998BA5\": \"Smoky Mauve\", \"#FFAFA8A9\": \"Smoky Mountain\", \"#FF71ADB2\": \"Smoky Mountain Spring\", \"#FFE1D9DC\": \"Smoky Orchid\", \"#FFBB8D88\": \"Smoky Pink\", \"#FF5C6E7C\": \"Smoky Pitch\", \"#FF51484F\": \"Smoky Quartz\", \"#FFE2B6A7\": \"Smoky Salmon\", \"#FFA1A18F\": \"Smoky Slate\", \"#FF7E8590\": \"Smoky Studio\", \"#FFAA9793\": \"Smoky Sunrise\", \"#FF9D9E9D\": \"Smoky Tone\", \"#FF7E7668\": \"Smoky Topaz\", \"#FF857D72\": \"Smoky Trout\", \"#FF647D9E\": \"Smoky Violet\", \"#FFAEADA3\": \"Smoky White\", \"#FFB2ACA9\": \"Smoky Wings\", \"#FF7E2056\": \"Smooch\", \"#FFD13D4B\": \"Smooch Rouge\", \"#FFF4E4B3\": \"Smooth as Corn Silk\", \"#FFD3BB96\": \"Smooth Beech\", \"#FF5D4E4C\": \"Smooth Coffee\", \"#FFCABAB1\": \"Smooth Pebbles\", \"#FFA2D5D3\": \"Smooth Satin\", \"#FFF6EAD2\": \"Smooth Silk\", \"#FFBCB6B3\": \"Smooth Stone\", \"#FF97B2B1\": \"Smooth-Hound Shark\", \"#FF988E01\": \"Smoothie Green\", \"#FFB6321E\": \"Smouldering\", \"#FFAA6E4B\": \"Smouldering Copper\", \"#FFCA3434\": \"Smouldering Red\", \"#FFEE4466\": \"Smudged Lips\", \"#FFE9EEEB\": \"Snail Trail Silver\", \"#FFC8C1AA\": \"Snake Charmer\", \"#FFE9CB4C\": \"Snake Eyes\", \"#FFDB2217\": \"Snake Fruit\", \"#FF45698C\": \"Snake River\", \"#FFBB4444\": \"Snakebite\", \"#FFBAA208\": \"Snakebite Leather\", \"#FF889717\": \"Snakes in the Grass\", \"#FF786E61\": \"Snakeskin\", \"#FF8A8650\": \"Snap Pea Green\", \"#FF2B3E52\": \"Snap-Shot\", \"#FFFED777\": \"Snapdragon\", \"#FFBCF5A6\": \"Snappy Green\", \"#FFEB8239\": \"Snappy Happy\", \"#FFCC0088\": \"Snappy Violet\", \"#FF9AE37D\": \"Snarky Mint\", \"#FF840014\": \"Sneaky Devil\", \"#FF896A46\": \"Sneaky Sesame\", \"#FFF2B635\": \"Sneezeweeds\", \"#FF9D7938\": \"Sneezy\", \"#FF718854\": \"Snip of Parsley\", \"#FFDCCEBB\": \"Snip of Tannin\", \"#FF92B57B\": \"Snipped Chive\", \"#FFDD7733\": \"Snobby Shore\", \"#FF49556C\": \"Snoop\", \"#FF034F84\": \"Snorkel Blue\", \"#FF004F7D\": \"Snorkel Sea\", \"#FF222277\": \"Snorlax\", \"#FFACBB0D\": \"Snot\", \"#FF9DC100\": \"Snot Green\", \"#FFDEF1E7\": \"Snow Ballet\", \"#FFDDE3E8\": \"Snow Blanket\", \"#FFE5E9EB\": \"Snow Cloud\", \"#FFE4F0E8\": \"Snow Crystal Green\", \"#FFF7F5ED\": \"Snow Day\", \"#FFE3E3DC\": \"Snow Drift Variant\", \"#FFB3C0D3\": \"Snow Flurries\", \"#FFEAF7C9\": \"Snow Flurry Variant\", \"#FFF4F2E9\": \"Snow Globe\", \"#FFC3D9CB\": \"Snow Goose\", \"#FFC9DCDC\": \"Snow in June\", \"#FFCFDFDB\": \"Snow Leopard\", \"#FFEBE2CC\": \"Snow on the Pines\", \"#FFFCD0C7\": \"Snow Pa\", \"#FF6CCC7B\": \"Snow Pea\", \"#FFE0DCDB\": \"Snow Peak\", \"#FFEBC6C0\": \"Snow Pink\", \"#FFF4EAF0\": \"Snow Plum\", \"#FFD2D8DA\": \"Snow Quartz\", \"#FFD7E4ED\": \"Snow Shadow\", \"#FFEEEDEA\": \"Snow Storm\", \"#FFDADCE0\": \"Snow Tiger\", \"#FFEEFFEE\": \"Snow White\", \"#FFF8AFA9\": \"Snow White Blush\", \"#FFD9E9E5\": \"Snowball Effect\", \"#FFE8E9E9\": \"Snowbank\", \"#FFBED0DA\": \"Snowbell\", \"#FFEEF1EC\": \"Snowbelt\", \"#FFEFECED\": \"Snowberry\", \"#FF74A9B9\": \"Snowboard\", \"#FFDDEBE3\": \"Snowbound\", \"#FFDCE5EB\": \"Snowcap\", \"#FFD6E5F0\": \"Snowdrift Glow\", \"#FFEEFFCC\": \"Snowdrop\", \"#FFE0EFE1\": \"Snowdrop Explosion\", \"#FFE8E5DE\": \"Snowed In\", \"#FFE0DEDA\": \"Snowfall\", \"#FFEEEDE0\": \"Snowfall White\", \"#FFEFF0F0\": \"Snowflake\", \"#FFC8C8C4\": \"Snowglory\", \"#FFFEFAFB\": \"Snowman\", \"#FFC9E6E9\": \"Snowmelt\", \"#FFE7E3D6\": \"Snowshoe Hare\", \"#FF001188\": \"Snowstorm Space Shuttle\", \"#FFEDF2E0\": \"Snowy Evergreen\", \"#FFD6F0CD\": \"Snowy Mint Variant\", \"#FFF1EEEB\": \"Snowy Mount\", \"#FFF0EFE3\": \"Snowy Pine\", \"#FFD3DBEC\": \"Snowy Shadow\", \"#FFC5D8E9\": \"Snowy Summit\", \"#FFA5ADBD\": \"Snub\", \"#FFE4D7E5\": \"Snuff Variant\", \"#FFBEA998\": \"Snug as a Bug\", \"#FFFCDB80\": \"Snug Yellow\", \"#FFA58F73\": \"Snuggle Pie\", \"#FFE1B89B\": \"So Baja\", \"#FFD4D8E3\": \"So Blue-Berry\", \"#FFEC7A93\": \"So Charming\", \"#FFCECDC5\": \"So Chic!\", \"#FFDFC89D\": \"So Close\", \"#FFCDC0C9\": \"So Dainty\", \"#FFD8D4D7\": \"So Fresh so Clean\", \"#FFB17494\": \"So Long Shadow\", \"#FF84525A\": \"So Merlot\", \"#FFF1E0CB\": \"So Much Fawn\", \"#FFDAD5D6\": \"So Shy\", \"#FF00FF11\": \"So Sour\", \"#FF8B847C\": \"So Sublime\", \"#FFFFDEF2\": \"So This Is Love\", \"#FF006F47\": \"So-Sari\", \"#FFF7D163\": \"Soaked in Sun\", \"#FFCEC8EF\": \"Soap\", \"#FFB2DCEF\": \"Soap Bubble\", \"#FFA0B28E\": \"Soap Green\", \"#FFE5BFCA\": \"Soap Pink\", \"#FFECE5DA\": \"Soapstone Variant\", \"#FFDDF0F0\": \"Soar\", \"#FF9BADBE\": \"Soaring Eagle\", \"#FFB9E5E8\": \"Soaring Sky\", \"#FFD1B49F\": \"Soba\", \"#FF22BB00\": \"Soccer Turf\", \"#FFCF8C76\": \"Sociable\", \"#FFFAF2DC\": \"Social Butterfly\", \"#FF921A1C\": \"Socialist\", \"#FF907676\": \"Socialite\", \"#FFE49780\": \"Sockeye\", \"#FFC3C67E\": \"Soda Pop\", \"#FF2C447B\": \"Sodalite Blue\", \"#FF9B533F\": \"S\\u014ddenkaracha Brown\", \"#FF93806A\": \"Sofisticata\", \"#FFEAE0D6\": \"Soft & Warm\", \"#FFCFBEA5\": \"Soft Amber Variant\", \"#FFCFB7C9\": \"Soft Amethyst\", \"#FFE0B392\": \"Soft Apricot\", \"#FF897670\": \"Soft Bark\", \"#FFB9B5AF\": \"Soft Beige\", \"#FF6488EA\": \"Soft Blue\", \"#FF888CBA\": \"Soft Blue Lavender\", \"#FFDAE7E9\": \"Soft Blue White\", \"#FFE3BCBC\": \"Soft Blush\", \"#FFFFB737\": \"Soft Boiled\", \"#FFF6F0EB\": \"Soft Breeze\", \"#FF99656C\": \"Soft Bromeliad\", \"#FFA18666\": \"Soft Bronze\", \"#FFF4E1B6\": \"Soft Butter\", \"#FFFFEDBE\": \"Soft Buttercup\", \"#FFF7EACF\": \"Soft Candlelight\", \"#FFEFB6D8\": \"Soft Cashmere\", \"#FFBFCFC8\": \"Soft Celadon\", \"#FFC4CD87\": \"Soft Celery\", \"#FFDBB67A\": \"Soft Chamois\", \"#FF838298\": \"Soft Charcoal\", \"#FFE4BC5B\": \"Soft Cheddar\", \"#FFD0E3ED\": \"Soft Cloud\", \"#FF987B71\": \"Soft Cocoa\", \"#FFFFEEE0\": \"Soft Coral\", \"#FFF5EFD6\": \"Soft Cream\", \"#FFB9C6CA\": \"Soft Denim\", \"#FFE0CFB9\": \"Soft Doeskin\", \"#FFC2BBB2\": \"Soft Dove\", \"#FFB59778\": \"Soft Fawn\", \"#FFEFE4DC\": \"Soft Feather\", \"#FFC7D368\": \"Soft Fern\", \"#FF817714\": \"Soft Fig\", \"#FFE2EFDD\": \"Soft Focus\", \"#FFC0D5CA\": \"Soft Fresco\", \"#FFBDCCB3\": \"Soft Froth\", \"#FFD496BD\": \"Soft Fuchsia\", \"#FF7E7574\": \"Soft Fur\", \"#FFFBEEDE\": \"Soft Gossamer\", \"#FFC1DFC4\": \"Soft Grass\", \"#FF6FC276\": \"Soft Green\", \"#FFD7C3B5\": \"Soft Greige\", \"#FFC8D8D1\": \"Soft Haze\", \"#FFBEA8B7\": \"Soft Heather\", \"#FFE7CFCA\": \"Soft Ice Rose\", \"#FFB28EA8\": \"Soft Impact\", \"#FFA28B7E\": \"Soft Impala\", \"#FFE6E3EB\": \"Soft Iris\", \"#FFFBF1DF\": \"Soft Ivory\", \"#FFD1D2BE\": \"Soft Kind\", \"#FFF5EDE5\": \"Soft Lace\", \"#FFF6E5F6\": \"Soft Lavender\", \"#FFD9A077\": \"Soft Leather\", \"#FFE2D4DF\": \"Soft Lilac\", \"#FFBEDDBA\": \"Soft Lumen\", \"#FFDD99BB\": \"Soft Matte\", \"#FFBAB2B1\": \"Soft Metal\", \"#FFE6F9F1\": \"Soft Mint\", \"#FFEFECD7\": \"Soft Moonlight\", \"#FFCCE1C7\": \"Soft Moss\", \"#FFF7EADF\": \"Soft Muslin\", \"#FF59604F\": \"Soft Olive\", \"#FFEEC0AB\": \"Soft Orange\", \"#FFFFDCD2\": \"Soft Orange Bloom\", \"#FF555054\": \"Soft Panther\", \"#FFEEDFDE\": \"Soft Peach Variant\", \"#FFFFF3F0\": \"Soft Peach Mist\", \"#FFEFE7DB\": \"Soft Pearl\", \"#FFCDC1B2\": \"Soft Pelican\", \"#FFEBF8EF\": \"Soft Petals\", \"#FFFFF5E7\": \"Soft Pillow\", \"#FFFDB0C0\": \"Soft Pink\", \"#FFFDEBE5\": \"Soft Pink Mist\", \"#FF949EA2\": \"Soft Pumice\", \"#FFDC8E31\": \"Soft Pumpkin\", \"#FFA66FB5\": \"Soft Purple\", \"#FFC0BBA5\": \"Soft Putty\", \"#FF927C75\": \"Soft Rabbit Brown\", \"#FF412533\": \"Soft Red\", \"#FFFDD47E\": \"Soft Saffron\", \"#FFBCBCAE\": \"Soft Sage\", \"#FFEAAAA2\": \"Soft Salmon\", \"#FFEEC5CE\": \"Soft Satin\", \"#FF837E87\": \"Soft Savvy\", \"#FFD6D4CA\": \"Soft Secret\", \"#FFE8D5C6\": \"Soft Shoe\", \"#FFA2BBC1\": \"Soft Shore\", \"#FFD09F93\": \"Soft Sienna\", \"#FFE1DFE2\": \"Soft Silk\", \"#FFF7F9E9\": \"Soft Silver\", \"#FFE4B185\": \"Soft Skills\", \"#FFB5B5CB\": \"Soft Sky\", \"#FF404854\": \"Soft Steel\", \"#FFC6B8A5\": \"Soft Stones\", \"#FFF5D180\": \"Soft Straw\", \"#FFD8CBAD\": \"Soft Suede\", \"#FFA1D7EF\": \"Soft Summer Rain\", \"#FFF2E3D8\": \"Soft Sunrise\", \"#FFC3B3B2\": \"Soft Tone\", \"#FF9D6016\": \"Soft Tone Ink\", \"#FF639B95\": \"Soft Touch\", \"#FF74CED2\": \"Soft Turquoise\", \"#FFDDDEBE\": \"Soft Vellum\", \"#FFE9E6E2\": \"Soft Violet\", \"#FFD9BD9C\": \"Soft Wheat\", \"#FFECE8DD\": \"Soft Wool\", \"#FFE3CDB6\": \"Soft-Spoken\", \"#FFBBBCA7\": \"Softened Green\", \"#FFDACAB2\": \"Softer Tan\", \"#FFC9B7CE\": \"Softly Softly\", \"#FFF3CA40\": \"Softsun\", \"#FF7F8486\": \"Software\", \"#FFE0815E\": \"Sohi Orange\", \"#FFE35C38\": \"Sohi Red\", \"#FFAB6953\": \"Soho Red\", \"#FF845C00\": \"Soil of Avagddu\", \"#FF416F8B\": \"Sojourn Blue\", \"#FFFBEAB8\": \"Solar\", \"#FFCC6622\": \"Solar Ash\", \"#FFF7DA74\": \"Solar Energy\", \"#FFE67C41\": \"Solar Flare\", \"#FFDC9F46\": \"Solar Fusion\", \"#FFFAF1BD\": \"Solar Glow\", \"#FFFAF0C9\": \"Solar Light\", \"#FFF0CA4A\": \"Solar Plexus Chakra\", \"#FFF4B435\": \"Solar Power\", \"#FFD2AB51\": \"Solar Relic\", \"#FFFFC16C\": \"Solar Storm\", \"#FFFCE9B9\": \"Solar Wind\", \"#FFF5D68F\": \"Solaria\", \"#FFE1BA36\": \"Solarium\", \"#FFFBCF4F\": \"Solarized\", \"#FF545A2C\": \"Soldier Green\", \"#FFF7DDA1\": \"Sol\\u00e9\", \"#FFE9CB2E\": \"Soleil\", \"#FFD3D8D8\": \"Solemn Silence\", \"#FF635C59\": \"Solid Empire\", \"#FFB7D24B\": \"Solid Gold\", \"#FFEEEAE2\": \"Solid Opal\", \"#FFC78B95\": \"Solid Pink Variant\", \"#FFA1A58C\": \"Solid Snake\", \"#FFC6DECF\": \"Solitaire Variant\", \"#FF80796D\": \"Solitary Slate\", \"#FFC4C7C4\": \"Solitary State\", \"#FF539B6A\": \"Solitary Tree\", \"#FFE9ECF1\": \"Solitude Variant\", \"#FFCBD2D0\": \"Solo\", \"#FFBABDB8\": \"Solstice\", \"#FFCDD2BB\": \"Solstice Breeze\", \"#FF77ABAB\": \"Solution\", \"#FF6C5751\": \"Somali Brown\", \"#FFCBB489\": \"Sombre\", \"#FF005C2B\": \"Sombre Green\", \"#FF555470\": \"Sombre Grey\", \"#FF161E34\": \"Sombre Night\", \"#FFAF546B\": \"Sombre Roses\", \"#FFB39C8C\": \"Sombrero\", \"#FFCBA391\": \"Sombrero Tan\", \"#FFEFE4CC\": \"Someday\", \"#FFB0D6E6\": \"Something Blue\", \"#FFCC99DD\": \"Somewhere in a Fairytale\", \"#FF5D3736\": \"Sommelier\", \"#FFABC8D8\": \"Sonata\", \"#FF8A9EAE\": \"Sonata Blue\", \"#FF55AA44\": \"Sonata in Green Minor\", \"#FFFCE7B5\": \"Song of Summer\", \"#FF4A73A8\": \"Song of the Sea\", \"#FFAF987F\": \"Song Thrush\", \"#FFF2E5E0\": \"Song Thrush Egg\", \"#FFA3D1EB\": \"Songbird\", \"#FFF3C8C2\": \"Sonia Rose\", \"#FF17569B\": \"Sonic Blue\", \"#FFC5D061\": \"Sonic Lime\", \"#FF83599B\": \"Sonic Plum\", \"#FFA0D1EC\": \"Sonic Sky\", \"#FFC0C7C4\": \"Sonnet Grey\", \"#FFDDCB91\": \"Sonoma Chardonnay\", \"#FF90A58A\": \"Sonoma Sage\", \"#FFBFD1CA\": \"Sonoma Sky\", \"#FFE0B493\": \"Sonora Apricot\", \"#FFBEA77D\": \"Sonora Hills\", \"#FFE8D2E3\": \"Sonora Rose\", \"#FFC89672\": \"Sonora Shade\", \"#FFCFB8A1\": \"Sonoran Desert\", \"#FFDDD5C6\": \"Sonoran Sands\", \"#FFFAF0CB\": \"Sonorous Bells\", \"#FF7BB369\": \"Soon\", \"#FF550000\": \"Soooo Bloody\", \"#FF555E5F\": \"Soot\", \"#FF5D5E5C\": \"Soot Veil\", \"#FF9CC9D4\": \"Soothing Blue\", \"#FFB3BEC4\": \"Soothing Breeze\", \"#FFF2E7DE\": \"Soothing Pink\", \"#FFB4AE95\": \"Soothing Sage\", \"#FF307DD3\": \"Soothing Sapphire\", \"#FFBCE6DE\": \"Soothing Sea\", \"#FFBCCBC4\": \"Soothing Spring\", \"#FFE1EFE2\": \"Soothing Vapour\", \"#FFE1E2E4\": \"Soothing White\", \"#FF8092BC\": \"Soothsayer\", \"#FF141414\": \"Sooty\", \"#FF474D52\": \"Sooty Lashes\", \"#FF4D4B3A\": \"Sooty Willow Bamboo\", \"#FF956C87\": \"Sophisticated Lilac\", \"#FF5D5153\": \"Sophisticated Plum\", \"#FF537175\": \"Sophisticated Teal\", \"#FFBFB5A6\": \"Sophistication\", \"#FF7D7170\": \"Sophomore\", \"#FFA0D8EF\": \"Sora Blue\", \"#FF4D8FAC\": \"Sora Sky\", \"#FFA1A6D6\": \"Sorbet Ice Mauve\", \"#FFDAC100\": \"Sorbet Yellow\", \"#FFDD6B38\": \"Sorbus Variant\", \"#FF3398CE\": \"Sorcerer\", \"#FF9B6D51\": \"Sorrel Brown\", \"#FFA49688\": \"Sorrel Felt\", \"#FF887E64\": \"Sorrel Leaf\", \"#FF9D7F61\": \"Sorrell Brown Variant\", \"#FFF1D058\": \"Sorreno Lemon\", \"#FFFC0156\": \"Sorx Red\", \"#FF47788A\": \"Sotek Green\", \"#FFEDD1A8\": \"Souffl\\u00e9\", \"#FF5C1C39\": \"Soul Anchor\", \"#FF7EADC7\": \"Soul Blue\", \"#FF7E989D\": \"Soul Quenching\", \"#FF377290\": \"Soul Search\", \"#FF624C4C\": \"Soul Searching\", \"#FFFFAA55\": \"Soul Side\", \"#FFB2B5C8\": \"Soul Sister\", \"#FF58475E\": \"Soul Train\", \"#FF374357\": \"Soulful\", \"#FF757C91\": \"Soulful Blue\", \"#FFB8B5AA\": \"Soulful Grey\", \"#FF3B4457\": \"Soulful Music\", \"#FF1B150D\": \"Soulless\", \"#FF85777B\": \"Soulmate\", \"#FFFFC8E9\": \"Soulmate Pink\", \"#FF333B33\": \"Sound of Silence\", \"#FFA0C6D7\": \"Sound Waves\", \"#FFDFE5D7\": \"Sounds of Nature\", \"#FFE5EDB5\": \"Sour\", \"#FFA0AC4F\": \"Sour Apple\", \"#FFAAEE22\": \"Sour Apple Candy\", \"#FF33BB00\": \"Sour Apple Rings\", \"#FF8B844E\": \"Sour Bubba\", \"#FF66B348\": \"Sour Candy\", \"#FFE24736\": \"Sour Cherry\", \"#FFADC979\": \"Sour Face\", \"#FFC1E613\": \"Sour Green\", \"#FFC8FFB0\": \"Sour Green Cherry\", \"#FFFFEEA5\": \"Sour Lemon\", \"#FFACC326\": \"Sour Lime\", \"#FFF4D9C5\": \"Sour Patch Peach\", \"#FFFEE5C8\": \"Sour Tarts\", \"#FFFFFFBF\": \"Sour Veil\", \"#FFEEFF04\": \"Sour Yellow\", \"#FFCDEAE5\": \"Source Blue\", \"#FF84B6A2\": \"Source Green\", \"#FFC9B59A\": \"Sourdough\", \"#FFE8A05A\": \"South Haven\", \"#FF76614B\": \"South Kingston\", \"#FF698694\": \"South Pacific\", \"#FFEAD2BB\": \"South Peach\", \"#FFEADFD2\": \"South Peak\", \"#FFA6847B\": \"South Rim Trail\", \"#FFFFDC9E\": \"South Shore Sun\", \"#FFB98258\": \"Southern Barrens Mud\", \"#FFF7DDDB\": \"Southern Beauty\", \"#FFA6D6C3\": \"Southern Belle\", \"#FF365787\": \"Southern Blue\", \"#FFE4DFD1\": \"Southern Breeze\", \"#FF34657D\": \"Southern Evening\", \"#FFBCA66A\": \"Southern Moss\", \"#FFE5B792\": \"Southern Peach\", \"#FFACB4AB\": \"Southern Pine\", \"#FFD0D34D\": \"Southern Platyfish\", \"#FF9D766F\": \"Southern Road\", \"#FFDE9F85\": \"Southwest Stone\", \"#FFCC6758\": \"Southwestern Clay\", \"#FFEDE0CE\": \"Southwestern Sand\", \"#FF4B4356\": \"Sovereign\", \"#FFCE243F\": \"Sovereign Red\", \"#FF304E63\": \"Sovereignty\", \"#FFFFD900\": \"Soviet Gold\", \"#FFCD0000\": \"Soviet Red\", \"#FFD5D2C7\": \"Soy Milk\", \"#FF1A0600\": \"Soy Sauce\", \"#FFFAE3BC\": \"Soya\", \"#FF6F634B\": \"Soya Bean Variant\", \"#FFCAB68B\": \"Soybean\", \"#FFCEECE7\": \"Spa\", \"#FFD3DEDF\": \"Spa Blue\", \"#FF1993BE\": \"Spa Dream\", \"#FF529182\": \"Spa Green\", \"#FFD4E4E6\": \"Spa Retreat\", \"#FFD7C9A5\": \"Spa Sangria\", \"#FF3B4271\": \"Space Angel\", \"#FF440099\": \"Space Battle Blue\", \"#FF150F5B\": \"Space Colonisation\", \"#FF667788\": \"Space Convoy\", \"#FF002299\": \"Space Dust\", \"#FF001199\": \"Space Exploration\", \"#FF114499\": \"Space Explorer\", \"#FF110022\": \"Space Grey\", \"#FF139D08\": \"Space Invader\", \"#FF324471\": \"Space Missions\", \"#FF5511DD\": \"Space Opera\", \"#FF4B433B\": \"Space Shuttle\", \"#FF6C6D7A\": \"Space Station\", \"#FFDAE6EF\": \"Space Wolves Grey\", \"#FF5C6B6B\": \"Spacebox\", \"#FF5F6882\": \"Spaceman\", \"#FF222255\": \"Spacescape\", \"#FF877D75\": \"Spacious Grey\", \"#FF9A8557\": \"Spacious Plain\", \"#FFD5EAF2\": \"Spacious Skies\", \"#FFAEB5C7\": \"Spacious Sky\", \"#FF424142\": \"Spade Black\", \"#FFFEF69E\": \"Spaghetti\", \"#FFDDDDAA\": \"Spaghetti Carbonara\", \"#FFEECC88\": \"Spaghetti Monster\", \"#FF8D7F75\": \"Spalding Grey\", \"#FF36B14E\": \"Spandex Green\", \"#FFE5DBE5\": \"Spangle\", \"#FF7F5F52\": \"Spanish Chestnut\", \"#FFFCE5C0\": \"Spanish Cream\", \"#FFE51A4C\": \"Spanish Crimson\", \"#FF817863\": \"Spanish Galleon\", \"#FFB09A4F\": \"Spanish Gold\", \"#FF7B8976\": \"Spanish Green Variant\", \"#FFFCE8CA\": \"Spanish Lace\", \"#FF8E6A3F\": \"Spanish Leather\", \"#FF684B40\": \"Spanish Mustang\", \"#FFA1A867\": \"Spanish Olive\", \"#FFC57556\": \"Spanish Peanut\", \"#FF5C3357\": \"Spanish Plum\", \"#FF66033C\": \"Spanish Purple\", \"#FF61504E\": \"Spanish Raisin\", \"#FF111133\": \"Spanish Roast\", \"#FFAC6768\": \"Spanish Rose Shadow\", \"#FFCAB08E\": \"Spanish Sand\", \"#FF93765C\": \"Spanish Style\", \"#FF702425\": \"Spanish Tile\", \"#FFDBB39E\": \"Spanish Villa\", \"#FFDED1B7\": \"Spanish White\", \"#FFF6B511\": \"Spanish Yellow\", \"#FFE4E4DD\": \"Spare White\", \"#FFF5D2B5\": \"Sparkle Glow\", \"#FFFFEE99\": \"Sparkler\", \"#FF77B244\": \"Sparkling Apple\", \"#FFC15187\": \"Sparkling Blueberry Lemonade\", \"#FFDCEEE3\": \"Sparkling Brook\", \"#FFEFCF98\": \"Sparkling Champagne\", \"#FFFFFDEB\": \"Sparkling Cider\", \"#FFF9736E\": \"Sparkling Cosmo\", \"#FF2DA4B6\": \"Sparkling Cove\", \"#FF1F6C53\": \"Sparkling Emerald\", \"#FFD2D5DA\": \"Sparkling Frost\", \"#FF82387E\": \"Sparkling Grape\", \"#FF66EE00\": \"Sparkling Green\", \"#FFAFC5BC\": \"Sparkling Lake\", \"#FFEECCFF\": \"Sparkling Lavender\", \"#FFC3C3C7\": \"Sparkling Metal\", \"#FFA4DDD3\": \"Sparkling Mint\", \"#FFF5CEE6\": \"Sparkling Pink\", \"#FFCC11FF\": \"Sparkling Purple\", \"#FFEE3333\": \"Sparkling Red\", \"#FFD6EDF1\": \"Sparkling River\", \"#FFC7CBBC\": \"Sparkling Sage\", \"#FFCBD0CD\": \"Sparkling Silver\", \"#FFF5FEFD\": \"Sparkling Snow\", \"#FFD9E3E0\": \"Sparkling Spring\", \"#FFFF7711\": \"Sparks in the Dark\", \"#FF22EEFF\": \"Sparky Blue\", \"#FF69595C\": \"Sparrow\", \"#FF523E47\": \"Sparrow Grey Red\", \"#FFFF6622\": \"Sparrow\\u2019s Fire\", \"#FF76A4A7\": \"Spartacus\", \"#FF7A8898\": \"Spartan Blue\", \"#FF9E1316\": \"Spartan Crimson\", \"#FFAFA994\": \"Spartan Stone\", \"#FFC1EDD3\": \"Spatial Spirit\", \"#FFDEDDDB\": \"Spatial White\", \"#FFFFEE88\": \"Sp\\u00e4tzle Yellow\", \"#FFFFD9A6\": \"Speak\", \"#FF826A6C\": \"Speakeasy\", \"#FFA8415B\": \"Speaking of the Devil\", \"#FF885500\": \"Spear Shaft\", \"#FF5FB6BF\": \"Spearfish\", \"#FF64BFA4\": \"Spearmint\", \"#FF5CBE86\": \"Spearmint Burst\", \"#FF8DC2A8\": \"Spearmint Frosting\", \"#FF9CB8A6\": \"Spearmint Haze\", \"#FFBFD3CB\": \"Spearmint Ice\", \"#FFCBECE6\": \"Spearmint Leaf\", \"#FFDBE8DF\": \"Spearmint Scent\", \"#FFE8F0E2\": \"Spearmint Stick\", \"#FFB1EAE8\": \"Spearmint Water\", \"#FFBCE3C9\": \"Spearmints\", \"#FFA5B2B7\": \"Special Delivery\", \"#FF7B787D\": \"Special Grey\", \"#FF868B53\": \"Special Ops\", \"#FFEBC09B\": \"Special Peach\", \"#FFDCD867\": \"Species\", \"#FFD38798\": \"Speckled Easter Egg\", \"#FFEBD6BD\": \"Speckled Eggs\", \"#FFBB02FE\": \"Spectacular Purple\", \"#FFEDD924\": \"Spectacular Saffron\", \"#FFF72305\": \"Spectacular Scarlet\", \"#FF375D4F\": \"Spectra Variant\", \"#FF00A096\": \"Spectra Green\", \"#FFF6AA09\": \"Spectra Yellow\", \"#FFDFDCD8\": \"Spectral\", \"#FF008664\": \"Spectral Green\", \"#FF44448D\": \"Spectrum Blue\", \"#FFF20000\": \"Spectrum Red\", \"#FF90BFD4\": \"Speedboat\", \"#FFB4547E\": \"Speedwell\", \"#FF5E4F50\": \"Spell\", \"#FF4A373E\": \"Spell Caster\", \"#FFE7DFCE\": \"Spellbound\", \"#FFA38C6B\": \"Spelt Grain Brown\", \"#FF35465E\": \"Spelunking\", \"#FFA5AD44\": \"Sphagnales Moss\", \"#FF75693D\": \"Sphagnum Moss\", \"#FFF2E8CC\": \"Sphere\", \"#FFA99593\": \"Sphinx\", \"#FF6C4F3F\": \"Spice Variant\", \"#FF86613F\": \"Spice Bazaar\", \"#FFB87243\": \"Spice Cake\", \"#FFF0DED3\": \"Spice Cookie\", \"#FFF3E9CF\": \"Spice Delight\", \"#FFC9D6B4\": \"Spice Garden\", \"#FFE1C2C1\": \"Spice Girl\", \"#FFEBD0A4\": \"Spice Is Nice\", \"#FFF4EEDC\": \"Spice Ivory\", \"#FFB84823\": \"Spice Market\", \"#FF86493F\": \"Spice of Life\", \"#FFFFB088\": \"Spice Pink\", \"#FFC26E4B\": \"Spice Route\", \"#FF604941\": \"Spiceberry\", \"#FFBB715B\": \"Spiced\", \"#FF7F403A\": \"Spiced Apple\", \"#FFE9D2BB\": \"Spiced Beige\", \"#FF85443F\": \"Spiced Berry\", \"#FFBB9683\": \"Spiced Brandy\", \"#FFFFD978\": \"Spiced Butternut\", \"#FFA4624C\": \"Spiced Carrot\", \"#FFD3B080\": \"Spiced Cashews\", \"#FF915B41\": \"Spiced Cider\", \"#FF805B48\": \"Spiced Cinnamon\", \"#FFD55459\": \"Spiced Coral\", \"#FFA38061\": \"Spiced Honey\", \"#FF53433E\": \"Spiced Hot Chocolate\", \"#FF886C57\": \"Spiced Latte\", \"#FFB99563\": \"Spiced Mustard\", \"#FFFFBB72\": \"Spiced Nectarine\", \"#FFBC693E\": \"Spiced Nut\", \"#FF927D6C\": \"Spiced Nutmeg\", \"#FFEDC7B6\": \"Spiced Orange\", \"#FF764F80\": \"Spiced Plum\", \"#FF905D5F\": \"Spiced Potpourri\", \"#FFD88D56\": \"Spiced Pumpkin\", \"#FFBB1166\": \"Spiced Purple\", \"#FF8B4C3D\": \"Spiced Red\", \"#FFAD8B6A\": \"Spiced Rum\", \"#FFAB6162\": \"Spiced Tea\", \"#FFB14B38\": \"Spiced Up\", \"#FFE67A37\": \"Spiced up Orange\", \"#FFCDBA99\": \"Spiced Vinegar\", \"#FF664942\": \"Spiced Wine\", \"#FFFF1111\": \"Spicy\", \"#FFCC3366\": \"Spicy Berry\", \"#FF9B5B4F\": \"Spicy Cayenne\", \"#FFA85624\": \"Spicy Cinnamon\", \"#FF994B35\": \"Spicy Hue\", \"#FFEEBBAA\": \"Spicy Hummus\", \"#FF8B5F4D\": \"Spicy Mix Variant\", \"#FFDA482D\": \"Spicy Orange\", \"#FFF38F39\": \"Spicy Paella\", \"#FFFF1CAE\": \"Spicy Pink Variant\", \"#FFB9396E\": \"Spicy Purple\", \"#FF97413E\": \"Spicy Red\", \"#FFF6AC00\": \"Spicy Sweetcorn\", \"#FFC75433\": \"Spicy Tomato\", \"#FFE2E8DF\": \"Spider Cotton\", \"#FF656271\": \"Spike\", \"#FFFDDDB7\": \"Spiked Apricot\", \"#FF600000\": \"Spikey Red\", \"#FF9B351B\": \"Spill the Beans\", \"#FFE4E1DE\": \"Spilled Cappuccino\", \"#FFF4F4D1\": \"Spilt Milk\", \"#FF46A35A\": \"Spinach\", \"#FFAAAA55\": \"Spinach Banana Smoothie\", \"#FFB1CDAC\": \"Spinach Dip\", \"#FF909B4C\": \"Spinach Green\", \"#FF83825B\": \"Spinach Souffle\", \"#FF6E750E\": \"Spinach Soup\", \"#FFE4E8DA\": \"Spinach White\", \"#FFB3C4D8\": \"Spindle Variant\", \"#FF73FCD6\": \"Spindrift\", \"#FF464D4A\": \"Spinel Black\", \"#FF49424A\": \"Spinel Grey\", \"#FF59181C\": \"Spinel Red\", \"#FF272A3B\": \"Spinel Stone Black\", \"#FF38283D\": \"Spinel Violet\", \"#FFA3E2DD\": \"Spinnaker\", \"#FF018CB6\": \"Spinnaker Blue\", \"#FF5B6A7C\": \"Spinning Blue\", \"#FFF3DDBC\": \"Spinning Silk\", \"#FFF6EDDA\": \"Spinning Wheel\", \"#FFB2BBC6\": \"Spirit\", \"#FF323B6C\": \"Spirit Blue\", \"#FF514B80\": \"Spirit Dance\", \"#FF6A8B98\": \"Spirit Mountain\", \"#FF5F534E\": \"Spirit Rock\", \"#FFD45341\": \"Spirit Warrior\", \"#FFE3EEBF\": \"Spirit Whisper\", \"#FFFDE7E3\": \"Spirited Away\", \"#FFBDDEC7\": \"Spirited Green\", \"#FFFFDC83\": \"Spirited Yellow\", \"#FFFD411E\": \"Spiritstone Red\", \"#FF5A665C\": \"Spirulina\", \"#FF6F757D\": \"Spitsbergen Blue\", \"#FFF1D79E\": \"Splash\", \"#FFD8B98C\": \"Splash of Honey\", \"#FF5984B0\": \"Splash Palace\", \"#FFD4E8D8\": \"Splashdown\", \"#FF44DDFF\": \"Splashing Wave\", \"#FF019196\": \"Splashy\", \"#FFA9586C\": \"Splatter\", \"#FFD01A2C\": \"Splatter Movie\", \"#FFCCEE00\": \"Spleen Green\", \"#FF7598B5\": \"Splendid Blue\", \"#FF806E7C\": \"Splendiferous\", \"#FFF3DFCC\": \"Splendour\", \"#FF5870A4\": \"Splendour and Pride\", \"#FFFFB14E\": \"Splendour Gold\", \"#FFA3713F\": \"Splinter\", \"#FF3194CE\": \"Splish Splash\", \"#FF96983F\": \"Split Pea\", \"#FFC8B165\": \"Split Pea Soup\", \"#FF8E6C51\": \"Split Rail\", \"#FFE8FF2A\": \"Spoiled Egg\", \"#FFB6BFE5\": \"Spoiled Rotten\", \"#FFA0956F\": \"Sponge\", \"#FFFFFE40\": \"Sponge Cake\", \"#FFC2A048\": \"Spontaneous Sprig\", \"#FFD1D2BF\": \"Spooky\", \"#FFD4D1D9\": \"Spooky Ghost\", \"#FF685E4F\": \"Spooky Graveyard\", \"#FFFF6B00\": \"Spooky Tangerine\", \"#FFF5EAE3\": \"Spooled White\", \"#FFE7E9E3\": \"Spoonful of Sugar\", \"#FF7F8162\": \"Spores\", \"#FF00A27D\": \"Sport Green\", \"#FFEFD678\": \"Sport Yellow\", \"#FF434C47\": \"Sporting Green\", \"#FF399BB4\": \"Sports Blue\", \"#FFE08119\": \"Sports Fan\", \"#FF4D8064\": \"Sports Field Green\", \"#FF6A8AA4\": \"Sporty Blue\", \"#FFFAEACD\": \"Spotlight\", \"#FFBFBFBD\": \"Spotted Dove\", \"#FFB1D3E3\": \"Spotted Snake Eel\", \"#FF7ECDDD\": \"Spray Variant\", \"#FFAEA692\": \"Spray Green\", \"#FFBDD0C3\": \"Spray of Mint\", \"#FF007711\": \"Spreadsheet Green\", \"#FFD6C1C5\": \"Sprig Muslin\", \"#FF8BE0BA\": \"Sprig of Mint\", \"#FFF2F6DB\": \"Sprig of Sage\", \"#FF00F900\": \"Spring\", \"#FFB3BB6B\": \"Spring Ahead\", \"#FFE9EDBD\": \"Spring Blossom\", \"#FF69CD7F\": \"Spring Bouquet\", \"#FFD7B9CB\": \"Spring Boutique\", \"#FFA98C37\": \"Spring Branch\", \"#FFE8EBD9\": \"Spring Breeze\", \"#FFC9E0C8\": \"Spring Burst\", \"#FFFFF6C2\": \"Spring Buttercup\", \"#FFB7629B\": \"Spring Crocus\", \"#FFDBD7B7\": \"Spring Day\", \"#FFD9EEE1\": \"Spring Dew\", \"#FFE5E3BF\": \"Spring Fever\", \"#FFB3CDAC\": \"Spring Fields\", \"#FFECF1EC\": \"Spring Fog\", \"#FF67926F\": \"Spring Forest\", \"#FF11BB22\": \"Spring Forth\", \"#FFBABD29\": \"Spring Forward\", \"#FF558961\": \"Spring Garden\", \"#FFD3E0B8\": \"Spring Glow\", \"#FFD5CB7F\": \"Spring Grass\", \"#FF00FF7C\": \"Spring Green Variant\", \"#FFC5C6B3\": \"Spring Grey\", \"#FFBFD392\": \"Spring Has Sprung\", \"#FFFFFDDD\": \"Spring Heat\", \"#FFC4CBB2\": \"Spring Hill\", \"#FFCDD9BB\": \"Spring Joy\", \"#FF4A754A\": \"Spring Juniper\", \"#FFE3EFB2\": \"Spring Kiss\", \"#FFCBDD94\": \"Spring Lawn\", \"#FFA8C3AA\": \"Spring Leaves Variant\", \"#FFFCF4C8\": \"Spring Lily\", \"#FF9FC65E\": \"Spring Lime\", \"#FFE8A59D\": \"Spring Linen\", \"#FF640125\": \"Spring Lobster\", \"#FF6C2C2F\": \"Spring Lobster Brown\", \"#FF7A4171\": \"Spring Lobster Dye\", \"#FFC0B05D\": \"Spring Marsh\", \"#FFD3E0DE\": \"Spring Mist\", \"#FFE5F0D5\": \"Spring Morn\", \"#FFA99757\": \"Spring Moss\", \"#FF596C3C\": \"Spring Onion\", \"#FFF6E6E2\": \"Spring Petal\", \"#FFDFBCC9\": \"Spring Pink\", \"#FFA3BD9C\": \"Spring Rain Variant\", \"#FFA1BFAB\": \"Spring Reflection\", \"#FFC4A661\": \"Spring Roll\", \"#FFA06567\": \"Spring Rosewood\", \"#FFCCEECC\": \"Spring Savour\", \"#FFE2EDC1\": \"Spring Shoot\", \"#FFABDCEE\": \"Spring Shower\", \"#FFB8F8B8\": \"Spring Slumber Green\", \"#FFFACCBF\": \"Spring Song\", \"#FF9BA294\": \"Spring Spirits\", \"#FFA2C09B\": \"Spring Sprig\", \"#FF86BA4A\": \"Spring Sprout\", \"#FFA9C6CB\": \"Spring Storm\", \"#FF98BEB2\": \"Spring Stream\", \"#FFF1F1C6\": \"Spring Sun Variant\", \"#FFD9DCDD\": \"Spring Thaw\", \"#FFD8DCB3\": \"Spring Thyme\", \"#FF99CDE6\": \"Spring Tide\", \"#FFCED7C5\": \"Spring Valley\", \"#FF82A320\": \"Spring Vegetables\", \"#FFACB193\": \"Spring Walk\", \"#FF7AB5AE\": \"Spring Water Turquoise\", \"#FFE0EED4\": \"Spring Wheat\", \"#FFECFCEC\": \"Spring White\", \"#FFCDA4DE\": \"Spring Wisteria\", \"#FFE9E1D9\": \"Spring Wood Variant\", \"#FFF2E47D\": \"Spring Yellow\", \"#FF284C3C\": \"Springbok Green\", \"#FFC8CB8E\": \"Springtide Green\", \"#FF9AA955\": \"Springtide Melodies\", \"#FFE9E5B3\": \"Springtime\", \"#FFDB88AC\": \"Springtime Bloom\", \"#FFFFFFEF\": \"Springtime Dew\", \"#FFEBEEF3\": \"Springtime Rain\", \"#FF7EA15A\": \"Springview Green\", \"#FFEBDDEA\": \"Sprinkle\", \"#FFCFECEE\": \"Sprinkled With Dew\", \"#FFE7A2AE\": \"Sprinkled With Pink\", \"#FFB9DCC3\": \"Sprite Twist\", \"#FF76C5E7\": \"Spritzig\", \"#FFB8CA9D\": \"Sprout Variant\", \"#FFC8D5CF\": \"Sprout Green\", \"#FFF3D48B\": \"Sprouted\", \"#FF0A5F38\": \"Spruce\", \"#FF91A49D\": \"Spruce Shade\", \"#FF838A7A\": \"Spruce Shadow\", \"#FF9FC09C\": \"Spruce Stone\", \"#FFB35E97\": \"Spruce Tree Flower\", \"#FF6E6A51\": \"Spruce Woods\", \"#FFB77D42\": \"Spruce Yellow\", \"#FF9A7F28\": \"Spruced Up\", \"#FFBCCFA4\": \"Spumoni Green\", \"#FFF3ECDC\": \"Spun Cotton\", \"#FFEDAA6E\": \"Spun Gold\", \"#FFF4E4CF\": \"Spun Jute\", \"#FFDBD1DE\": \"Spun Moonbeams\", \"#FFA2A1AC\": \"Spun Pearl Variant\", \"#FFFAE2ED\": \"Spun Sugar\", \"#FFE3DED4\": \"Spun Wool\", \"#FF5E0092\": \"SQL Injection Purple\", \"#FF828383\": \"Squant\", \"#FFF2AB15\": \"Squash\", \"#FFE7B17C\": \"Squash Bisque\", \"#FFF8B438\": \"Squash Blossom\", \"#FF6CC4DA\": \"Squeaky\", \"#FF11EE00\": \"Squeeze Toy Alien\", \"#FF6E2233\": \"Squid Hat\", \"#FFF5B4BD\": \"Squid Pink\", \"#FF041330\": \"Squid\\u2019s Ink\", \"#FFAA4F44\": \"Squig Orange\", \"#FF8F7D6B\": \"Squirrel Variant\", \"#FF665E48\": \"Squirrel\\u2019s Nest\", \"#FF95BCC5\": \"Squirt\", \"#FFF56961\": \"Sriracha\", \"#FFADDAE3\": \"Srsly Blue\", \"#FFD0DDCC\": \"St. Augustine\", \"#FF577C88\": \"St. Bart\\u2019s\", \"#FFEEDDDD\": \"St. Nicholas Beard\", \"#FF2B8C4E\": \"St. Patrick\", \"#FFDEE8F3\": \"St. Petersburg\", \"#FF39527D\": \"St. Tropaz\", \"#FF325482\": \"St. Tropez\", \"#FFC1D0B2\": \"Stability\", \"#FFF6E0BE\": \"Stable Hay\", \"#FF858885\": \"Stack Variant\", \"#FFD1B992\": \"Stacked Limestone\", \"#FF918676\": \"Stacked Stone\", \"#FFD5F534\": \"Stadium Grass\", \"#FF9AF764\": \"Stadium Lawn\", \"#FF603B41\": \"Stag Beetle\", \"#FF9E6928\": \"Stage Gold\", \"#FFB081AA\": \"Stage Mauve\", \"#FFD8D9CA\": \"Stage Whisper\", \"#FF7F5A44\": \"Stagecoach\", \"#FF556682\": \"Stained Glass\", \"#FFB4BDC7\": \"Stainless Steel\", \"#FF67716E\": \"Stairway\", \"#FFD4C4A7\": \"Stalactite Brown\", \"#FF7CB26E\": \"Stalk\", \"#FFB0A8AD\": \"Stamina\", \"#FF638636\": \"Stamnank\\u00e1thi Green\", \"#FF2EA18C\": \"Stamp Pad Green\", \"#FFA0A09A\": \"Stamped Concrete\", \"#FF725D4B\": \"Stampede\", \"#FF7F8596\": \"Stand Out\", \"#FFFF0066\": \"Standby LED\", \"#FFBFB9BD\": \"Standing Ovation\", \"#FF9D6F4B\": \"Standing Still\", \"#FF005599\": \"Standing Waters\", \"#FF85979A\": \"Standish Blue\", \"#FF658F7C\": \"Stanford Green\", \"#FFBCAB9C\": \"Stanford Stone\", \"#FF9BC2B4\": \"Stanley\", \"#FFFFE500\": \"Star\", \"#FFC51F26\": \"Star and Crescent Red\", \"#FF5C5042\": \"Star Anise\", \"#FFA77B4D\": \"Star Anise Scent\", \"#FFE8DDAE\": \"Star Bright\", \"#FF5796A1\": \"Star City\", \"#FFF9F3DD\": \"Star Dust Variant\", \"#FFBEAA4A\": \"Star Fruit Yellow Green\", \"#FF75DBC1\": \"Star Grass\", \"#FFD8DCE6\": \"Star Jasmine\", \"#FFE4D8D8\": \"Star Magic\", \"#FFEEEFE2\": \"Star Magnolia\", \"#FFDAE2E9\": \"Star Map\", \"#FFB3C6CE\": \"Star Mist\", \"#FFF5EEDC\": \"Star of Bethlehem\", \"#FF0000F7\": \"Star of David\", \"#FFEBE3C7\": \"Star of Gold\", \"#FF057BC1\": \"Star of Life\", \"#FFEBBBBE\": \"Star of the Morning\", \"#FF9500FF\": \"Star Platinum Purple\", \"#FF3C6A9D\": \"Star Sapphire\", \"#FFF8F6E3\": \"Star Shine\", \"#FF3A5779\": \"Star Spangled\", \"#FFEFEFE8\": \"Star White\", \"#FFF7EBAC\": \"Star-Studded\", \"#FF016C4F\": \"Starboard\", \"#FFF5ECC9\": \"Starbright\", \"#FF6CB037\": \"Starbur\", \"#FFDCE7E5\": \"Starburst\", \"#FFAC9A6C\": \"Starch\", \"#FFA6B2B5\": \"Stardew\", \"#FFDDD3AE\": \"Stardust\", \"#FFDACFD4\": \"Stardust Ballroom\", \"#FFB8BFDC\": \"Stardust Evening\", \"#FFE5BCA5\": \"Starfish\", \"#FF0096FF\": \"Starfleet Blue\", \"#FF4E9AB0\": \"Starflower Blue\", \"#FFF0E8D5\": \"Starfox\", \"#FFE4D183\": \"Starfruit\", \"#FFB7C4D3\": \"Stargate\", \"#FF7777FF\": \"Stargate Shimmer\", \"#FF3F5865\": \"Stargazer\", \"#FF414549\": \"Stargazing\", \"#FFFAEEDE\": \"Starglider\", \"#FFD2C6B6\": \"Stark White Variant\", \"#FF3E4855\": \"Starless Night\", \"#FFEDC2DB\": \"Starlet Pink\", \"#FFBCC0CC\": \"Starlight\", \"#FFB5CED4\": \"Starlight Blue\", \"#FFE8DFD8\": \"Starling\\u2019s Egg\", \"#FF384351\": \"Starlit Eve\", \"#FF3B476B\": \"Starlit Night\", \"#FF286492\": \"Starry Night\", \"#FF4F5E7E\": \"Starry Sky Blue\", \"#FF758BA4\": \"Starset\", \"#FFE3DD39\": \"Starship Variant\", \"#FFCCE7E8\": \"Starship Tonic\", \"#FF229966\": \"Starship Trooper\", \"#FF4664A5\": \"Starstruck\", \"#FFE56131\": \"Startling Orange\", \"#FFC5BDC4\": \"Stately Frills\", \"#FFB0B0AA\": \"Stately Greystone\", \"#FF577A6C\": \"Stately Stems\", \"#FFFAF9EA\": \"Stately White\", \"#FFD5D3C3\": \"Static\", \"#FF9EA4A5\": \"Statuary\", \"#FF376D64\": \"Statue of Liberty\", \"#FFD0BCB1\": \"Statued\", \"#FFE0DFD9\": \"Statuesque\", \"#FFDC8A30\": \"Status Bronze\", \"#FF9FAC5C\": \"Stay in Lime\", \"#FF314662\": \"Stay the Night\", \"#FF4A5777\": \"Steadfast\", \"#FF8A6B4D\": \"Steady Brown\", \"#FF4B4844\": \"Stealth Jet\", \"#FFDDDDDD\": \"Steam\", \"#FFCCD0DA\": \"Steam Bath\", \"#FFEBE1A9\": \"Steam Chestnut\", \"#FFB2B2AD\": \"Steam Engine\", \"#FFE8E9E5\": \"Steam White\", \"#FFD2CCB4\": \"Steamboat Geyser\", \"#FFE0D4BD\": \"Steamed Chai\", \"#FFD3B17D\": \"Steamed Chestnut\", \"#FFEAD8BE\": \"Steamed Milk\", \"#FFEE8888\": \"Steamed Salmon\", \"#FFC39C55\": \"Steampunk Gold\", \"#FFB8C0C8\": \"Steampunk Grey\", \"#FF6F3B34\": \"Steampunk Leather\", \"#FFEAE9B4\": \"Steamy Dumpling\", \"#FFB1CFC7\": \"Steamy Spring\", \"#FF797979\": \"Steel\", \"#FF767275\": \"Steel Armour\", \"#FF7D94C6\": \"Steel Blue Eyes\", \"#FF436175\": \"Steel Blue Grey\", \"#FF43464B\": \"Steel Grey\", \"#FF7A744D\": \"Steel Legion Drab\", \"#FF5599B6\": \"Steel Light Blue\", \"#FFDDD5CE\": \"Steel Me\", \"#FFC6CEDA\": \"Steel Mist\", \"#FF71A6A1\": \"Steel Pan Mallet\", \"#FF5F8A8B\": \"Steel Teal\", \"#FF929894\": \"Steel Toe\", \"#FF767574\": \"Steel Wool\", \"#FF81919D\": \"Steele Blue\", \"#FFD43728\": \"Steelhead Redd\", \"#FF90979B\": \"Steely Grey\", \"#FF827E7C\": \"Steeple Grey\", \"#FF074863\": \"Stegadon Scale Green\", \"#FF415862\": \"Steiglitz Fog\", \"#FFF5D056\": \"Stella\", \"#FF46647E\": \"Stellar\", \"#FF9FB5CE\": \"Stellar Blue\", \"#FF002222\": \"Stellar Explorer\", \"#FFAB9D9C\": \"Stellar Mist\", \"#FFFF5C8D\": \"Stellar Strawberry\", \"#FF9A9959\": \"Stem\", \"#FFABDF8F\": \"Stem Green\", \"#FFB4CEDA\": \"Stencil Blue\", \"#FF7D7640\": \"Steppe Green\", \"#FFB2A18C\": \"Stepping Stones\", \"#FFFFF5CF\": \"Stereotypical Duck\", \"#FFD1D4D1\": \"Sterling\", \"#FFA2B9C2\": \"Sterling Blue\", \"#FFE9EBDE\": \"Sterling Shadow\", \"#FF9EAFC2\": \"Sterling Silver\", \"#FF9E7A58\": \"Stetson\", \"#FFC5B5A4\": \"Steveareno Beige\", \"#FFBAA482\": \"Sticks & Stones\", \"#FF131212\": \"Sticky Black Tarmac\", \"#FFCC8149\": \"Sticky Toffee\", \"#FF8D8F8E\": \"Stieglitz Silver\", \"#FFFADB5E\": \"Stil de Grain Yellow\", \"#FF323235\": \"Stiletto Variant\", \"#FFB6453E\": \"Stiletto Love\", \"#FFADAF9C\": \"Still\", \"#FFC154C0\": \"Still Fuchsia\", \"#FFABA9A0\": \"Still Grey\", \"#FFA1A39F\": \"Still Life in Grey\", \"#FFCBC4B2\": \"Still Moment\", \"#FFFFF8E1\": \"Still Morning\", \"#FF4A5D5F\": \"Still Waters Run Deep\", \"#FFD6EBE7\": \"Stillness\", \"#FF70A4B0\": \"Stillwater\", \"#FFC2D0DF\": \"Stillwater Lake\", \"#FFA29A6A\": \"Stilted Stalks\", \"#FF495D39\": \"Stinging Nettle\", \"#FFAEFD6C\": \"Stinging Wasabi\", \"#FFB0ABA3\": \"Stingray Grey\", \"#FF2A545C\": \"Stinkhorn\", \"#FFAE5A2C\": \"Stirland Battlemire\", \"#FF492B00\": \"Stirland Mud\", \"#FFF6B064\": \"Stirring Orange\", \"#FF900910\": \"Stizza\", \"#FF806852\": \"Stock Horse\", \"#FF104F4A\": \"Stockade Green\", \"#FFE9E5D8\": \"Stocking White\", \"#FF647B72\": \"Stockleaf\", \"#FF77454C\": \"Stoic\", \"#FFE0E0FF\": \"Stoic White\", \"#FFEFDCD3\": \"Stolen Kiss\", \"#FF0088B0\": \"Stomy Shower\", \"#FFADA587\": \"Stone\", \"#FFA29F9B\": \"Stone Age\", \"#FF7A3F2B\": \"Stone Age Queen\", \"#FF52706C\": \"Stone Bridge\", \"#FFB79983\": \"Stone Brown\", \"#FF888C90\": \"Stone Cairn\", \"#FF7D867C\": \"Stone Craft\", \"#FF8F9183\": \"Stone Creek\", \"#FF5F7D6C\": \"Stone Cypress Green\", \"#FF929C9C\": \"Stone Fence\", \"#FFC5C0B0\": \"Stone Fortress\", \"#FFF2A28C\": \"Stone Fruit\", \"#FFC2CBD2\": \"Stone Golem\", \"#FF658E67\": \"Stone Green\", \"#FF9F9484\": \"Stone Grey\", \"#FFD39831\": \"Stone Ground\", \"#FFCABA97\": \"Stone Guardians\", \"#FFE8E0D8\": \"Stone Harbour\", \"#FF93888C\": \"Stone Haze\", \"#FF636869\": \"Stone Hearth\", \"#FFB3A491\": \"Stone Lion\", \"#FFA29482\": \"Stone Manor\", \"#FF959897\": \"Stone Mason\", \"#FFB6B7AD\": \"Stone Mill\", \"#FF7A807A\": \"Stone Monument\", \"#FFE4EFE5\": \"Stone Path\", \"#FFEFE5D4\": \"Stone Pillar\", \"#FF665C46\": \"Stone Pine\", \"#FFECE4DC\": \"Stone Quarry\", \"#FF8BA8AE\": \"Stone Silver\", \"#FFA09484\": \"Stone Terrace\", \"#FF4D404F\": \"Stone Violet\", \"#FFB5B09E\": \"Stone Walkway\", \"#FF605C58\": \"Stone\\u2019s Throw\", \"#FFDDCEA7\": \"Stonebread\", \"#FFCBA97E\": \"Stonebriar\", \"#FFA08F6F\": \"Stonecrop\", \"#FF99917E\": \"Stonegate\", \"#FFA79D8D\": \"Stonehenge Greige\", \"#FFBAB1A3\": \"Stonelake\", \"#FF8D7A4D\": \"Stonetalon Mountains\", \"#FF807661\": \"Stonewall Variant\", \"#FFC1C1C1\": \"Stonewall Grey\", \"#FFA5978D\": \"Stoneware\", \"#FF74819A\": \"Stonewash\", \"#FFDDD7C5\": \"Stonewashed\", \"#FFDCCCC0\": \"Stonewashed Brown\", \"#FFF4EEE4\": \"Stonewashed Pink\", \"#FFCCB49A\": \"Stonish Beige\", \"#FF948F82\": \"Stony Creek\", \"#FF615547\": \"Stony Field\", \"#FFD3D3C8\": \"Stony Path\", \"#FFC33A36\": \"Stop\", \"#FFDD1111\": \"Stoplight\", \"#FFE5E1DD\": \"Storksbill\", \"#FFF2F2E2\": \"Storksbill White\", \"#FF000B44\": \"Storm\", \"#FF507B9C\": \"Storm Blue\", \"#FF938988\": \"Storm Break\", \"#FF808283\": \"Storm Cloud\", \"#FF807A7E\": \"Storm Front\", \"#FF113333\": \"Storm Green\", \"#FF3D3D63\": \"Storm Is Coming\", \"#FFF9E69C\": \"Storm Lightning\", \"#FF7F95A5\": \"Storm Petrel\", \"#FFA28A88\": \"Storm Red\", \"#FF999495\": \"Storm Rolling In\", \"#FF696863\": \"Storm Warning\", \"#FFE7B57F\": \"Stormeye\", \"#FF80A7C1\": \"Stormfang\", \"#FFBBC6C9\": \"Stormhost Silver\", \"#FF8D9390\": \"Storms Mountain\", \"#FF5C5954\": \"Stormvermin Fur\", \"#FFB0BCC3\": \"Stormy\", \"#FF9AAFAF\": \"Stormy Bay\", \"#FFADB5A3\": \"Stormy Day\", \"#FF7D7B7C\": \"Stormy Grey\", \"#FF777799\": \"Stormy Horizon\", \"#FF71738C\": \"Stormy Mauve\", \"#FF372354\": \"Stormy Night\", \"#FF70818E\": \"Stormy Oceans\", \"#FFC36666\": \"Stormy Passion\", \"#FFE3B5AD\": \"Stormy Pink\", \"#FF946658\": \"Stormy Plum\", \"#FF507B9A\": \"Stormy Ridge\", \"#FF6E8082\": \"Stormy Sea\", \"#FF90A1AA\": \"Stormy Skies\", \"#FF0F9B8E\": \"Stormy Strait Green\", \"#FF6B8BA4\": \"Stormy Strait Grey\", \"#FF84A9B0\": \"Stormy Waters\", \"#FF63707B\": \"Stormy Weather\", \"#FFC05F1C\": \"Storybook Sundown\", \"#FF0F0B0A\": \"Stout\", \"#FF7B8393\": \"Stowaway\", \"#FF52A550\": \"Straightforward Green\", \"#FF628026\": \"Straken Green\", \"#FFDBB060\": \"Stranglethorn Ochre\", \"#FF528A9A\": \"Stratford Blue\", \"#FF8C8670\": \"Stratford Sage\", \"#FF3799C8\": \"Stratos Blue\", \"#FF9EC1CC\": \"Stratosphere\", \"#FFACB8B2\": \"Stratton Blue\", \"#FF8193AA\": \"Stratus\", \"#FF996E74\": \"Stravinsky\", \"#FF77515A\": \"Stravinsky Pink\", \"#FFD9C69A\": \"Straw Basket\", \"#FFFCF679\": \"Straw Gold\", \"#FFDBC8A2\": \"Straw Harvest\", \"#FFF0D5A8\": \"Straw Hat\", \"#FFBDB268\": \"Straw Hut\", \"#FFF0D696\": \"Straw Yellow\", \"#FFF1E3C7\": \"Straw-Bale\", \"#FFFB2943\": \"Strawberry Variant\", \"#FFEF4F41\": \"Strawberry Avalanche\", \"#FFFFDADC\": \"Strawberry Blonde Variant\", \"#FFFFEBFA\": \"Strawberry Bonbon\", \"#FFF8B3FF\": \"Strawberry Buttercream\", \"#FFFFDBE9\": \"Strawberry Cheesecake\", \"#FFF4BFC6\": \"Strawberry Confection\", \"#FF990011\": \"Strawberry Cough\", \"#FFF0ADB3\": \"Strawberry Cream\", \"#FFA23D50\": \"Strawberry Daiquiri\", \"#FFFF88AA\": \"Strawberry Dreams\", \"#FFFFF0EA\": \"Strawberry Dust\", \"#FFFA8383\": \"Strawberry Field\", \"#FFFFA2AA\": \"Strawberry Frapp\\u00e9\", \"#FFC677A8\": \"Strawberry Freeze\", \"#FFFFDBF7\": \"Strawberry Frost\", \"#FFFF6FFC\": \"Strawberry Frosting\", \"#FFDAB7BE\": \"Strawberry Glaze\", \"#FFE78B90\": \"Strawberry Ice\", \"#FF86423E\": \"Strawberry Jam\", \"#FFC08591\": \"Strawberry Jubilee\", \"#FFD2ADB5\": \"Strawberry Latte\", \"#FFE0C1A7\": \"Strawberry Malt\", \"#FFE2958D\": \"Strawberry Memory\", \"#FFFFD9E7\": \"Strawberry Milk\", \"#FFD47186\": \"Strawberry Milkshake\", \"#FFE42D65\": \"Strawberry Mix\", \"#FFCF5570\": \"Strawberry Moon\", \"#FFA5647E\": \"Strawberry Mousse\", \"#FFF46C80\": \"Strawberry Pink\", \"#FFEE2255\": \"Strawberry Pop\", \"#FFB96364\": \"Strawberry Rhubarb\", \"#FFF7CDCE\": \"Strawberry Ripple\", \"#FFEEC6BF\": \"Strawberry Risotto\", \"#FFE29991\": \"Strawberry Rose\", \"#FFFA8E99\": \"Strawberry Shortcake\", \"#FFEE0055\": \"Strawberry Smash\", \"#FFE79EA6\": \"Strawberry Smoothie\", \"#FFF7879A\": \"Strawberry Soap\", \"#FFFA4224\": \"Strawberry Spinach Red\", \"#FFB9758D\": \"Strawberry Surprise\", \"#FFF9D7CD\": \"Strawberry Whip\", \"#FFCB6A6B\": \"Strawberry Wine\", \"#FFE9B3B4\": \"Strawberry Yoghurt\", \"#FFDDBDBA\": \"Strawflower\", \"#FF495E7B\": \"Stream\", \"#FF556061\": \"Stream Bed\", \"#FF5E7E7D\": \"Stream Burble\", \"#FFB9BAC0\": \"Streamlined Grey\", \"#FFD8E2DF\": \"Streetwise\", \"#FF2D2E33\": \"Stretch Limo\", \"#FF9DBBD0\": \"Stretch of Water\", \"#FFDFD8C8\": \"Stretched Canvas\", \"#FFD7AA60\": \"Streusel Cake\", \"#FF5A4659\": \"Strike a Pose\", \"#FFD7B55F\": \"Strike It Rich\", \"#FF946A81\": \"Strikemaster Variant\", \"#FF00667B\": \"Striking\", \"#FFCE7843\": \"Striking Orange\", \"#FF944E87\": \"Striking Purple\", \"#FFC03543\": \"Striking Red\", \"#FFAA9F96\": \"String\", \"#FFF1E8D8\": \"String Ball\", \"#FFFBF1DD\": \"String Cheese\", \"#FF7F7860\": \"String Deep\", \"#FFEBE3D8\": \"String of Pearls\", \"#FF406356\": \"Stromboli Variant\", \"#FF0C06F7\": \"Strong Blue\", \"#FF960056\": \"Strong Cerise\", \"#FF782E2C\": \"Strong Envy\", \"#FF5E5F7E\": \"Strong Iris\", \"#FF6F372D\": \"Strong Mocha\", \"#FFA88905\": \"Strong Mustard\", \"#FF646756\": \"Strong Olive\", \"#FFFF0789\": \"Strong Pink\", \"#FF2B6460\": \"Strong Sage\", \"#FF8A3E34\": \"Strong Strawberry\", \"#FF454129\": \"Strong Tone Wash\", \"#FF22578A\": \"Strong Will\", \"#FFA3A59B\": \"Strong Winds\", \"#FFA86F48\": \"Stroopwafel\", \"#FFF0E1E8\": \"Struck by Lightning\", \"#FF0E9BD1\": \"Structural Blue\", \"#FFA58D7F\": \"Stucco\", \"#FFF1B19D\": \"Stucco Wall\", \"#FFE2D3B9\": \"Stucco White\", \"#FF005577\": \"Studer Blue\", \"#FF724AA1\": \"Studio Variant\", \"#FFC1B2A1\": \"Studio Beige\", \"#FF6D817B\": \"Studio Blue Green\", \"#FFD9CCB8\": \"Studio Clay\", \"#FFEBDBAA\": \"Studio Cream\", \"#FFC6B9B8\": \"Studio Mauve\", \"#FFA59789\": \"Studio Taupe\", \"#FFE8DCD5\": \"Studio White\", \"#FFADAC7C\": \"Stuffed Olive\", \"#FFBF9B84\": \"Stuffing\", \"#FF5E5F4D\": \"Stump Green\", \"#FFDA9A5D\": \"Stunning Gold\", \"#FF185887\": \"Stunning Sapphire\", \"#FF676064\": \"Stunning Shade\", \"#FFBC9479\": \"Sturdy Bronze\", \"#FF9B856F\": \"Sturdy Brown\", \"#FF57544D\": \"Sturgis Grey\", \"#FFCEC1A5\": \"Stylish\", \"#FFBC3439\": \"Stylish Red\", \"#FF9FA0A0\": \"Su-Nezumi Grey\", \"#FFD1D8DD\": \"Suave Grey\", \"#FF57A1CE\": \"Sub-Zero\", \"#FF00576F\": \"Subaqueous\", \"#FFCCB8B3\": \"Subdue Red\", \"#FFC6B1AD\": \"Subdued Hue\", \"#FFCC896C\": \"Subdued Sienna\", \"#FFECEDE0\": \"Sublime\", \"#FF7A7778\": \"Submarine Variant\", \"#FF5566AA\": \"Submarine Base\", \"#FF4D585C\": \"Submarine Grey\", \"#FF4A7D82\": \"Submerged\", \"#FF00576E\": \"Submersible\", \"#FF012253\": \"Subnautical\", \"#FFD8CCC6\": \"Subpoena\", \"#FF4F4E4A\": \"Subterrain Kingdom\", \"#FF452C1F\": \"Subterranean\", \"#FF1F3B4D\": \"Subterranean River\", \"#FFDEDADB\": \"Subtle\", \"#FFD9E4E5\": \"Subtle Blue\", \"#FFF1DBC5\": \"Subtle Blush\", \"#FFB5D2D8\": \"Subtle Breeze\", \"#FFEBD7A7\": \"Subtle Glow\", \"#FFB5CBBB\": \"Subtle Green\", \"#FF554B4F\": \"Subtle Night Sky\", \"#FFFAE0C4\": \"Subtle Peach\", \"#FFD8D8D0\": \"Subtle Shadow\", \"#FFD0BD94\": \"Subtle Suede\", \"#FFE4D89A\": \"Subtle Sunshine\", \"#FFDBDBD9\": \"Subtle Touch\", \"#FF7A9693\": \"Subtle Turquoise\", \"#FFB29E9E\": \"Subtle Violet\", \"#FF87857C\": \"Subway\", \"#FF513B6E\": \"Succinct Violet\", \"#FF990022\": \"Succubus\", \"#FFBCCBB2\": \"Succulent Garden\", \"#FF5E9B86\": \"Succulent Green\", \"#FF8BA477\": \"Succulent Greenhouse\", \"#FF658E64\": \"Succulent Leaves\", \"#FFDCDD65\": \"Succulent Lime\", \"#FF007744\": \"Succulents\", \"#FFFBDDAF\": \"Such a Peach\", \"#FFC6C1C5\": \"Such Melodrama\", \"#FFBC752D\": \"Sudan Brown\", \"#FF6376A9\": \"Sudden Sapphire\", \"#FF1A5897\": \"Suddenly Sapphire\", \"#FFA6B4C5\": \"Suds\", \"#FFBA8864\": \"Suede\", \"#FFD9C7B9\": \"Suede Beige\", \"#FF857F7A\": \"Suede Grey\", \"#FF585D6D\": \"Suede Indigo\", \"#FF896757\": \"Suede Leather\", \"#FFD79043\": \"Suede Vest\", \"#FFD3DBE7\": \"Sueded Grey\", \"#FF235E80\": \"Suez Canal\", \"#FFECD0A1\": \"Suffragette Yellow\", \"#FF935529\": \"Sugar Almond\", \"#FF834253\": \"Sugar Beet\", \"#FFE3D4CD\": \"Sugar Berry\", \"#FFFFCCFF\": \"Sugar Chic\", \"#FFFFEDF1\": \"Sugar Coated\", \"#FFBB6611\": \"Sugar Coated Almond\", \"#FFF2E2A4\": \"Sugar Cookie\", \"#FFE8CFB1\": \"Sugar Cookie Crust\", \"#FFF56C73\": \"Sugar Coral\", \"#FFC96FA8\": \"Sugar Creek\", \"#FFF9EDE3\": \"Sugar Dust\", \"#FFFFF0E1\": \"Sugar Glaze\", \"#FFCC9955\": \"Sugar Glazed Cashew\", \"#FF9437FF\": \"Sugar Grape\", \"#FFEFC9EC\": \"Sugar High\", \"#FFDDAA66\": \"Sugar Honey Cashew\", \"#FFCDB141\": \"Sugar Leaves\", \"#FFFFF9F5\": \"Sugar Milk\", \"#FFC0E2C5\": \"Sugar Mint\", \"#FFC7A77B\": \"Sugar Pie\", \"#FF73776E\": \"Sugar Pine\", \"#FFAED6D4\": \"Sugar Pool\", \"#FFE58281\": \"Sugar Poppy\", \"#FFEBE5D7\": \"Sugar Quill\", \"#FFD85DA1\": \"Sugar Rush\", \"#FFCFB599\": \"Sugar Rush Peach Pepper\", \"#FFEED5B6\": \"Sugar Shack\", \"#FFEFE8DC\": \"Sugar Soap\", \"#FFECC4DC\": \"Sugar Sweet\", \"#FFEAE3D6\": \"Sugar Swizzle\", \"#FFD68F9F\": \"Sugar Tooth\", \"#FFA2999A\": \"Sugar Tree\", \"#FF8B2E16\": \"Sugar-Candied Peanuts\", \"#FFEDD1C7\": \"Sugarcane\", \"#FFF7C2BF\": \"Sugarcane Dahlia\", \"#FFB49D7B\": \"Sugared Almond\", \"#FFFDDCC6\": \"Sugared Peach\", \"#FFEBD5B7\": \"Sugared Pears\", \"#FF554400\": \"Sugarloaf Brown\", \"#FFFFDDFF\": \"Sugarpills\", \"#FFD1ABB5\": \"Sugarplum Dance\", \"#FFFDC5E3\": \"Sugarwinkle\", \"#FFA2999F\": \"Sugilite\", \"#FFA32E1D\": \"Sugo Della Nonna\", \"#FF2B3036\": \"Suit Blue\", \"#FF645A4B\": \"Suitable Brown\", \"#FFA58B34\": \"Sullen Gold\", \"#FFF7C5D1\": \"Sullivan\\u2019s Heart\", \"#FFBAA600\": \"Sulphine Yellow\", \"#FFCAB012\": \"Sulphur\", \"#FFE5CC69\": \"Sulphur Pit\", \"#FFD5D717\": \"Sulphur Spring\", \"#FFF2F3CF\": \"Sulphur Water\", \"#FFCCC050\": \"Sulphur Yellow\", \"#FFEEED56\": \"Sulphuric\", \"#FFF6AC17\": \"Sultan Gold\", \"#FFE89BC7\": \"Sultan of Pink\", \"#FFE3C9BE\": \"Sultan Sand\", \"#FF134558\": \"Sultan\\u2019s Silk\", \"#FF674668\": \"Sultana\", \"#FF567D84\": \"Sultry Bay\", \"#FF948D84\": \"Sultry Castle\", \"#FF506770\": \"Sultry Sea\", \"#FF73696F\": \"Sultry Smoke\", \"#FF716563\": \"Sultry Spell\", \"#FFC6EA80\": \"Sulu Variant\", \"#FFE08A1E\": \"Sumac Dyed\", \"#FFF6E8CC\": \"Sumatra\", \"#FF735D4B\": \"Sumatra Blend\", \"#FF4F666A\": \"Sumatra Chicken\", \"#FF595857\": \"Sumi Ink\", \"#FF7058A3\": \"Sumire Violet\", \"#FF3FAFCF\": \"Summer Air\", \"#FFDBC2B9\": \"Summer Beige\", \"#FFBBD5EF\": \"Summer Birthday\", \"#FFFCF1CF\": \"Summer Bliss\", \"#FFD1BEB4\": \"Summer Bloom\", \"#FF1880A1\": \"Summer Blue\", \"#FFF6DFD6\": \"Summer Blush\", \"#FFD3E5DB\": \"Summer Breeze\", \"#FFF8822A\": \"Summer Citrus\", \"#FFBBFFEE\": \"Summer Cloud\", \"#FFE5CFDE\": \"Summer Clover\", \"#FFECB6B5\": \"Summer Cocktails\", \"#FF57595D\": \"Summer Concrete\", \"#FFFAD1E0\": \"Summer Cosmos\", \"#FFF2D6DA\": \"Summer Crush\", \"#FFFFE078\": \"Summer Daffodil\", \"#FFEAAA62\": \"Summer Day\", \"#FF83ADA3\": \"Summer Dragonfly\", \"#FFE2C278\": \"Summer Field\", \"#FFC45940\": \"Summer Fig\", \"#FF7AAC80\": \"Summer Garden\", \"#FFEEAA44\": \"Summer Glow\", \"#FF8FB69C\": \"Summer Green Variant\", \"#FFE8E4DE\": \"Summer Grey\", \"#FFFFE69A\": \"Summer Harvest\", \"#FFC1A58D\": \"Summer Hill\", \"#FFC8EFE2\": \"Summer House\", \"#FFFFEFC2\": \"Summer Hue\", \"#FFCDA168\": \"Summer in the City\", \"#FFEEEBD6\": \"Summer Jasmine\", \"#FF0077A7\": \"Summer Lake\", \"#FFF8D374\": \"Summer Lily\", \"#FFEAD5AE\": \"Summer Melon\", \"#FFDF856E\": \"Summer Memory\", \"#FFCBEAEE\": \"Summer Mist\", \"#FFFDEDCF\": \"Summer Moon\", \"#FFFBEEC1\": \"Summer Morning\", \"#FFB8AF65\": \"Summer Moss\", \"#FF36576A\": \"Summer Night\", \"#FF74CDD8\": \"Summer of \\u201982\", \"#FFFFB653\": \"Summer Orange\", \"#FFF5F0D1\": \"Summer Pear\", \"#FFE1E8DB\": \"Summer Rain\", \"#FFF7EFBA\": \"Summer Resort\", \"#FFECE4CE\": \"Summer Sandcastle\", \"#FF66A9B1\": \"Summer Sea\", \"#FFD1D9D7\": \"Summer Shade\", \"#FFE5EBE3\": \"Summer Shower\", \"#FFB7E0B9\": \"Summer Sigh\", \"#FF38B0DE\": \"Summer Sky\", \"#FF94D3D1\": \"Summer Soft Blue\", \"#FFDED1A3\": \"Summer Solstice\", \"#FF816E63\": \"Summer Sparrow\", \"#FF80CFE5\": \"Summer Splash\", \"#FFB0C5DF\": \"Summer Storm\", \"#FFFFDC00\": \"Summer Sun\", \"#FFD88167\": \"Summer Sunset\", \"#FFF7E8C7\": \"Summer Sunshine\", \"#FF008572\": \"Summer Turquoise\", \"#FF4B9CAB\": \"Summer Turquoise Blue\", \"#FFAFA685\": \"Summer Valley\", \"#FF215399\": \"Summer Waters\", \"#FFBB8E55\": \"Summer Weasel\", \"#FFF4E9D6\": \"Summer White\", \"#FFDC9367\": \"Summer\\u2019s End\", \"#FFA97069\": \"Summer\\u2019s Eve\", \"#FFF9E699\": \"Summer\\u2019s Heat\", \"#FF376698\": \"Summerday Blue\", \"#FF84AAB8\": \"Summerhouse Blue\", \"#FFC47A3D\": \"Summerset\", \"#FFF2D178\": \"Summertime\", \"#FF8CBC9E\": \"Summertown\", \"#FF997651\": \"Summerville Brown\", \"#FFD4B28B\": \"Summerwood\", \"#FF8BB6B8\": \"Summit\", \"#FFE5B99B\": \"Sumptuous Peach\", \"#FF604C81\": \"Sumptuous Purple\", \"#FFB1B48C\": \"Sumptuous Sage\", \"#FFEF8E38\": \"Sun Variant\", \"#FFCD6E53\": \"Sun Baked\", \"#FFA36658\": \"Sun Baked Earth\", \"#FFE3EFE1\": \"Sun Bleached Mint\", \"#FFE3AB7B\": \"Sun Bleached Ochre\", \"#FFFFFED9\": \"Sun City\", \"#FFC4AA4D\": \"Sun Dance\", \"#FFF0DCA0\": \"Sun Deck\", \"#FFFFE7A3\": \"Sun Drenched\", \"#FFEAAF11\": \"Sun Drops\", \"#FFF6E0A4\": \"Sun Dust\", \"#FFD0D418\": \"Sun Flooded Woods\", \"#FFF1F4D1\": \"Sun Glare\", \"#FFFAF3D9\": \"Sun Glint\", \"#FFDFBA5A\": \"Sun God\", \"#FFEACDB7\": \"Sun Kiss\", \"#FFF37724\": \"Sun Orange\", \"#FFCCC2C6\": \"Sun Painter\", \"#FFE7C26F\": \"Sun Salutation\", \"#FFFFDE73\": \"Sun Shower\", \"#FFE9AD17\": \"Sun Song\", \"#FFFBD795\": \"Sun Splashed\", \"#FFFFF2A0\": \"Sun Surprise\", \"#FFFAD675\": \"Sun Touched\", \"#FF698538\": \"Sun Valley\", \"#FFB88B46\": \"Sun Valley Vista\", \"#FFECC033\": \"Sun Wukong\\u2019s Crown\", \"#FFFFDF22\": \"Sun Yellow\", \"#FFFFEEC2\": \"Sun-Kissed\", \"#FFF2BDA8\": \"Sun-Kissed Apricot\", \"#FFDEAB9B\": \"Sun-Kissed Beach\", \"#FFB75E41\": \"Sun-Kissed Brick\", \"#FFEA6777\": \"Sun-Kissed Coral\", \"#FFFED8BF\": \"Sun-Kissed Peach\", \"#FFFFE9BA\": \"Sun-Kissed Yellow\", \"#FFF6F2E5\": \"Sun\\u2019s Glory\", \"#FFA94E37\": \"Sun\\u2019s Rage\", \"#FFDCD3B2\": \"Suna White\", \"#FFAB9A6E\": \"Sunbaked Adobe\", \"#FFD1AB74\": \"Sunbaked Straw\", \"#FFF5DD98\": \"Sunbathed\", \"#FFFAD28F\": \"Sunbathed Beach\", \"#FF7E4730\": \"Sunbathing Beauty\", \"#FFF5EDB2\": \"Sunbeam\", \"#FFF0D39D\": \"Sunbeam Yellow\", \"#FFFEFF0F\": \"Sunblast Yellow\", \"#FFE5E0D7\": \"Sunbleached\", \"#FFF9D964\": \"Sunbound\", \"#FFB37256\": \"Sunburn\", \"#FFFF404C\": \"Sunburnt Cyclops\", \"#FFD79584\": \"Sunburnt Toes\", \"#FFF5B57B\": \"Sunburst\", \"#FFF6C778\": \"Sunday Afternoon\", \"#FFFCC9C7\": \"Sunday Best\", \"#FFDCC9AE\": \"Sunday Drive\", \"#FFD7BAD1\": \"Sunday Gloves\", \"#FF3D4035\": \"Sunday Niqab\", \"#FFC5D2D5\": \"Sunday Sky\", \"#FFFAE198\": \"Sundaze\", \"#FFE1CDAE\": \"Sundew\", \"#FFC0805D\": \"Sundial\", \"#FFF5C99E\": \"Sundown Variant\", \"#FFEBCF89\": \"Sundress\", \"#FFEABD5B\": \"Sundried\", \"#FF7D252C\": \"Sundried Tomato\", \"#FF6E5F57\": \"Sunezumi Brown\", \"#FFFFC512\": \"Sunflower Variant\", \"#FFFFE26A\": \"Sunflower Dandelion\", \"#FFEA9D4F\": \"Sunflower Field\", \"#FFFFCD01\": \"Sunflower Island\", \"#FFFFB700\": \"Sunflower Mango\", \"#FFFFE3A9\": \"Sunflower Seed\", \"#FFFDBD27\": \"Sunflower Valley\", \"#FFFFDA03\": \"Sunflower Yellow\", \"#FFC76155\": \"Sunglo Variant\", \"#FFFFCF48\": \"Sunglow Gecko\", \"#FF51574F\": \"Sunken Battleship\", \"#FF273E3E\": \"Sunken Cascades\", \"#FFB29700\": \"Sunken Gold\", \"#FF1C3D44\": \"Sunken Harbour\", \"#FF23505A\": \"Sunken Mystery\", \"#FFC8DDDA\": \"Sunken Pool\", \"#FF10252A\": \"Sunken Ship\", \"#FFCCCF86\": \"Sunken Treasure\", \"#FFEBCD95\": \"Sunlight\", \"#FFFFDB78\": \"Sunlit\", \"#FF9787BB\": \"Sunlit Allium\", \"#FF98D4A0\": \"Sunlit Glade\", \"#FF7D7103\": \"Sunlit Kelp Green\", \"#FFD8D8A9\": \"Sunlit Leaf\", \"#FFD4C350\": \"Sunlit Meadow\", \"#FFBBCFB9\": \"Sunlit Sea\", \"#FFDA8433\": \"Sunlounge\", \"#FFE8D7B1\": \"Sunning Deck\", \"#FFF2F27A\": \"Sunny\", \"#FFEADFAA\": \"Sunny Burrata\", \"#FFDBA637\": \"Sunny Disposition\", \"#FFFFC946\": \"Sunny Festival\", \"#FFEDE1CC\": \"Sunny Gazebo\", \"#FFE8D99C\": \"Sunny Glory\", \"#FFC5CD40\": \"Sunny Green\", \"#FFF8F0D8\": \"Sunny Honey\", \"#FFD0875A\": \"Sunny Horizon\", \"#FFE1EE82\": \"Sunny Lime\", \"#FFF5F5CC\": \"Sunny Mimosa\", \"#FFF7C84A\": \"Sunny Mood\", \"#FFF6D365\": \"Sunny Morning\", \"#FFD9D7D9\": \"Sunny Pavement\", \"#FFFFDC41\": \"Sunny Side Up\", \"#FFFFC900\": \"Sunny Summer\", \"#FFE3E9CF\": \"Sunny Summit\", \"#FFFEDF94\": \"Sunny Veranda\", \"#FFFFF917\": \"Sunny Yellow\", \"#FFF8D016\": \"Sunnyside\", \"#FFFFD18C\": \"Sunporch\", \"#FFCFC5B6\": \"Sunray Venus\", \"#FFF4BF77\": \"Sunrise\", \"#FFFEF0C5\": \"Sunrise Glow\", \"#FFCAA061\": \"Sunrise Heat\", \"#FFA69799\": \"Sunrise Over Tahiti\", \"#FFFFDB67\": \"Sunrose Yellow\", \"#FFC0514A\": \"Sunset\", \"#FFD0A584\": \"Sunset Beige\", \"#FFE95E2A\": \"Sunset Blaze\", \"#FFFF9607\": \"Sunset Boulevard\", \"#FFBE916D\": \"Sunset Cloud\", \"#FFDCB397\": \"Sunset Cove\", \"#FFFFBE94\": \"Sunset Cruise\", \"#FFD1A69B\": \"Sunset Curtains\", \"#FFEABBA2\": \"Sunset Drive\", \"#FFFFB52D\": \"Sunset Glow\", \"#FFF6C362\": \"Sunset Gold\", \"#FFBA87AA\": \"Sunset Horizon\", \"#FFF0C484\": \"Sunset in Italy\", \"#FFA5A796\": \"Sunset Meadow\", \"#FFFD5E53\": \"Sunset Orange Variant\", \"#FFFEAC89\": \"Sunset Over the Alps\", \"#FFFC7D64\": \"Sunset Papaya\", \"#FFF8A77F\": \"Sunset Peach\", \"#FFFAD6E5\": \"Sunset Pink\", \"#FF724770\": \"Sunset Purple\", \"#FF7F5158\": \"Sunset Red\", \"#FF594265\": \"Sunset Serenade\", \"#FFFFBC00\": \"Sunset Strip\", \"#FFFA873D\": \"Sunset Yellow\", \"#FFFA9D49\": \"Sunshade Variant\", \"#FFF9D376\": \"Sunshine\", \"#FFF5C20B\": \"Sunshine Mellow\", \"#FFFCB02F\": \"Sunshine Surprise\", \"#FF886688\": \"Sunshone Plum\", \"#FFFBCA69\": \"Sunspark\", \"#FFDDC283\": \"Sunspill\", \"#FFFEE2B2\": \"Sunstitch\", \"#FFC7887F\": \"Sunstone\", \"#FFD8A27A\": \"Sunswept Sand\", \"#FFD9B19F\": \"Suntan\", \"#FFBE8C74\": \"Suntan Glow\", \"#FFE3C1B3\": \"Sunwashed Brick\", \"#FF7E2639\": \"Su\\u014d\", \"#FFFFFE71\": \"Super Banana\", \"#FF221100\": \"Super Black\", \"#FFAA8822\": \"Super Gold\", \"#FFCA535B\": \"Super Hero\", \"#FFBA5E0F\": \"Super Leaf Brown\", \"#FFE2B238\": \"Super Lemon\", \"#FFCE6BA6\": \"Super Pink\", \"#FF14BAB4\": \"Super Rare Jade\", \"#FFCB1028\": \"Super Rose Red\", \"#FFFFDD00\": \"Super Saiyan\", \"#FFFFAA88\": \"Super Sepia\", \"#FF785F8E\": \"Super Violet\", \"#FFFFFF69\": \"Supercalifragilisticexpialidocious\", \"#FF3A5E73\": \"Superior Blue\", \"#FF786957\": \"Superior Bronze\", \"#FFFF1122\": \"Superman Red\", \"#FF00928C\": \"Supermint\", \"#FF313641\": \"Supernatural\", \"#FFEF760E\": \"Supernatural Saffron\", \"#FFD1D5E6\": \"Supernova Variant\", \"#FFD9ECE9\": \"Supernova Residues\", \"#FFFFCC11\": \"Superstar\", \"#FF5B6E74\": \"Superstition\", \"#FFAC91B5\": \"Superstitious\", \"#FFE8EAEA\": \"Superwhite\", \"#FF78A300\": \"Support Green\", \"#FFCFDDC7\": \"Supreme Green\", \"#FFD4D8DB\": \"Supreme Pontiff\", \"#FFAFBED4\": \"Supremely Cool\", \"#FFFC53FC\": \"Surati Pink\", \"#FFB8D4BB\": \"Surf Variant\", \"#FFC3D6BD\": \"Surf Crest Variant\", \"#FF427573\": \"Surf Green\", \"#FF0193C2\": \"Surf Rider\", \"#FFB4C8C2\": \"Surf Spray\", \"#FF20377F\": \"Surf the Web\", \"#FF87CECA\": \"Surf Wash\", \"#FF374755\": \"Surf\\u2019n\\u2019dive\", \"#FFC4D3E5\": \"Surf\\u2019s Surprise\", \"#FFC6E4EB\": \"Surf\\u2019s Up\", \"#FF70B8BA\": \"Surfer\", \"#FFDB6484\": \"Surfer Girl\", \"#FF007B77\": \"Surfie Green Variant\", \"#FF73C0D2\": \"Surfin\\u2019\", \"#FF9ACAD3\": \"Surfside\", \"#FF59A4C1\": \"Surgical\", \"#FFC9936F\": \"Surprise\", \"#FFEFB57A\": \"Surprise Amber\", \"#FFDCC89D\": \"Surrey Cream\", \"#FF70191F\": \"Surya Red\", \"#FF7C9F2F\": \"Sushi Variant\", \"#FFFFF7DF\": \"Sushi Rice\", \"#FF58BAC2\": \"Sussie\", \"#FF887F7A\": \"Susu Green\", \"#FF6F514C\": \"Susu-Take Bamboo\", \"#FF859D95\": \"Sutherland\", \"#FFC2963F\": \"Suzani Gold\", \"#FF9EA1A3\": \"Suzu Grey\", \"#FFAA4F37\": \"Suzume Brown\", \"#FF8C4736\": \"Suzumecha Brown\", \"#FFB8A3BB\": \"Svelte\", \"#FFB2AC96\": \"Svelte Sage\", \"#FFB1B8B5\": \"Swag Bag Silver\", \"#FF19B6B5\": \"Swagger\", \"#FF154962\": \"Swallow Blue\", \"#FFECE9DD\": \"Swallow-Tailed Moth\", \"#FFFFE690\": \"Swallowtail\", \"#FF7F755F\": \"Swamp Variant\", \"#FFB79D69\": \"Swamp Fox\", \"#FF748500\": \"Swamp Green Variant\", \"#FF094C49\": \"Swamp Mausoleum\", \"#FF005511\": \"Swamp Monster\", \"#FF252F2F\": \"Swamp Mosquito\", \"#FF698339\": \"Swamp Moss\", \"#FF857947\": \"Swamp Mud\", \"#FF36310D\": \"Swamp of Sorrows\", \"#FF93977F\": \"Swamp Sessions\", \"#FF6D753B\": \"Swamp Shrub\", \"#FF226633\": \"Swampland\", \"#FFBBAB6D\": \"Swampwater\", \"#FFE5E1BD\": \"Swan Dance\", \"#FFE5E4DD\": \"Swan Dive\", \"#FFC5E5E2\": \"Swan Lake\", \"#FFA6C1BF\": \"Swan Sea\", \"#FFF5F2E6\": \"Swan Wing\", \"#FFB5B1B5\": \"Swanky Grey\", \"#FF5F7963\": \"Swanndri\", \"#FFDAE6DD\": \"Swans Down Variant\", \"#FF1D4E8F\": \"Sweat Bee\", \"#FFCCCCC5\": \"Sweater Weather\", \"#FF007CC0\": \"Swedish Blue\", \"#FF7B8867\": \"Swedish Clover\", \"#FF184D43\": \"Swedish Green\", \"#FFFCE081\": \"Swedish Yellow\", \"#FFC4BF0B\": \"Sweet & Sour\", \"#FFF29EAB\": \"Sweet 60\", \"#FFCC9977\": \"Sweet Almond\", \"#FFE7C2DE\": \"Sweet Alyssum\", \"#FFE1C9D1\": \"Sweet and Sassy\", \"#FFF5C8BB\": \"Sweet Angel\", \"#FFE8D08E\": \"Sweet Angelica\", \"#FF9C946E\": \"Sweet Annie\", \"#FFFCC0A6\": \"Sweet Apricot\", \"#FFA7E8D3\": \"Sweet Aqua\", \"#FFE5EAE3\": \"Sweet Ariel\", \"#FFFFE9AC\": \"Sweet as Honey\", \"#FFC24F40\": \"Sweet Baby Rose\", \"#FFC6947C\": \"Sweet Beige\", \"#FFEEDADD\": \"Sweet Bianca\", \"#FFAEBED2\": \"Sweet Blue\", \"#FFE6BFC1\": \"Sweet Blush\", \"#FFC8DAE3\": \"Sweet Breeze\", \"#FFFFFCD7\": \"Sweet Butter\", \"#FFFCEEDD\": \"Sweet Buttermilk\", \"#FFD59875\": \"Sweet Cardamom\", \"#FF9C9480\": \"Sweet Carolina\", \"#FFF6AFBB\": \"Sweet Caroline\", \"#FFCC764F\": \"Sweet Carrot\", \"#FFDDAA77\": \"Sweet Cashew\", \"#FFFFE186\": \"Sweet Chamomile\", \"#FF9F4F4D\": \"Sweet Cherry\", \"#FF84172C\": \"Sweet Cherry Red\", \"#FFF5160B\": \"Sweet Chilli\", \"#FFDD84A3\": \"Sweet Chrysanthemum\", \"#FFBFC0AA\": \"Sweet Clover\", \"#FFF9E176\": \"Sweet Corn Variant\", \"#FFF0EAE7\": \"Sweet Cream\", \"#FF5F4C54\": \"Sweet Currant\", \"#FFE8A773\": \"Sweet Curry\", \"#FFAA33EE\": \"Sweet Desire\", \"#FFDBCBAB\": \"Sweet Dough\", \"#FFECCEE5\": \"Sweet Dreams\", \"#FFAB9368\": \"Sweet Earth\", \"#FFCBD1E1\": \"Sweet Emily\", \"#FF8844FF\": \"Sweet Escape\", \"#FF674196\": \"Sweet Flag\", \"#FF8A9B76\": \"Sweet Florence\", \"#FFE2E2EA\": \"Sweet Flower\", \"#FFFFF8E4\": \"Sweet Frosting\", \"#FF5FD1BA\": \"Sweet Garden\", \"#FFEFE4DA\": \"Sweet Gardenia\", \"#FF8B715A\": \"Sweet Georgia Brown\", \"#FF4D3D52\": \"Sweet Grape\", \"#FFB2B68A\": \"Sweet Grass\", \"#FFD9DDE7\": \"Sweet Harbour\", \"#FFE0E8EC\": \"Sweet Illusion\", \"#FFF9F4D4\": \"Sweet Jasmine\", \"#FFB8BFD2\": \"Sweet Juliet\", \"#FF8E8DB9\": \"Sweet Lavender\", \"#FFF7BF43\": \"Sweet Lemon\", \"#FFFFF45A\": \"Sweet Lemon Seed\", \"#FFE8B5CE\": \"Sweet Lilac\", \"#FFCCBBDD\": \"Sweet Lucid Dreams\", \"#FF9B4040\": \"Sweet Lychee\", \"#FFFFDEE2\": \"Sweet Mallow\", \"#FFD35E3A\": \"Sweet Mandarin\", \"#FFDDAF6C\": \"Sweet Maple\", \"#FFEBAF95\": \"Sweet Marmalade\", \"#FFECD5AA\": \"Sweet Marzipan\", \"#FFE87973\": \"Sweet Melon\", \"#FFFDC8CD\": \"Sweet Memories\", \"#FFC2E4BC\": \"Sweet Menthol\", \"#FFA7C74F\": \"Sweet Midori\", \"#FFB4CCBE\": \"Sweet Mint\", \"#FFBBEE99\": \"Sweet Mint Pesto\", \"#FFD5E3D0\": \"Sweet Mint Tea\", \"#FF4B423F\": \"Sweet Molasses\", \"#FFB57312\": \"Sweet Mulled Cider\", \"#FFECC5DF\": \"Sweet Murmur\", \"#FFD1B871\": \"Sweet Mustard\", \"#FFFABDAF\": \"Sweet Nectar\", \"#FFFAE6E1\": \"Sweet Nothing\", \"#FFEBCCB3\": \"Sweet Orange\", \"#FFEDC8B1\": \"Sweet Pastel\", \"#FF9BA15C\": \"Sweet Pea\", \"#FFA89E81\": \"Sweet Pea in a Pod\", \"#FFE2BCB3\": \"Sweet Peach\", \"#FFD49AB9\": \"Sweet Perfume\", \"#FFCBBAD0\": \"Sweet Petal\", \"#FFFE6346\": \"Sweet Pimento\", \"#FFEE918D\": \"Sweet Pink Variant\", \"#FFD5CAAA\": \"Sweet Porridge\", \"#FFD87C3B\": \"Sweet Potato\", \"#FF917798\": \"Sweet Potato Peel\", \"#FF93DAD3\": \"Sweet Rhapsody\", \"#FFFFC4DD\": \"Sweet Romance\", \"#FFEAE1DD\": \"Sweet Roses\", \"#FFFFD8F0\": \"Sweet Sachet\", \"#FFF1DBC2\": \"Sweet Sand\", \"#FFC7B7D0\": \"Sweet Scent\", \"#FFFFC5D5\": \"Sweet Serenade\", \"#FFF0B9A9\": \"Sweet Sheba\", \"#FFEEBDB6\": \"Sweet Sherry\", \"#FFFFC9D3\": \"Sweet Sixteen\", \"#FFD0DEDD\": \"Sweet Slumber\", \"#FFF8B8F8\": \"Sweet Slumber Pink\", \"#FFA8946B\": \"Sweet Sparrow\", \"#FF7B453E\": \"Sweet Spiceberry\", \"#FFD1E8C2\": \"Sweet Spring\", \"#FFD8AA86\": \"Sweet Sue\", \"#FFC9D0B8\": \"Sweet Surrender\", \"#FFECBCD4\": \"Sweet Taffy\", \"#FFEAAEA9\": \"Sweet Tart\", \"#FFC18244\": \"Sweet Tea\", \"#FF5F6255\": \"Sweet Tooth\", \"#FFF0DCD7\": \"Sweet Truffle\", \"#FFEEEBE6\": \"Sweet Vanilla\", \"#FFB6FF1A\": \"Sweet Venom\", \"#FF8C667A\": \"Sweet Violet\", \"#FFFC5669\": \"Sweet Watermelon\", \"#FF8892C1\": \"Sweet William\", \"#FFF1CA90\": \"Sweet!\", \"#FFA7BDBA\": \"Sweetest Damask\", \"#FFF3C3D8\": \"Sweetheart\", \"#FFE1BBDB\": \"Sweetie Pie\", \"#FFFFE5EF\": \"Sweetly\", \"#FFF8DBC4\": \"Sweetness\", \"#FFC39F87\": \"Sweetwood\", \"#FFE7CEE3\": \"Sweety Pie\", \"#FF82AADC\": \"Swift\", \"#FFE1BC73\": \"Swiftly Green\", \"#FF6BB8B5\": \"Swim\", \"#FF0A91BF\": \"Swimmer\", \"#FF2DC5BB\": \"Swimmers Pool\", \"#FFC2E5E5\": \"Swimming\", \"#FFA8CFC0\": \"Swimming Pool Green\", \"#FF947569\": \"Swing Brown\", \"#FFC2C0A9\": \"Swing Sage\", \"#FF706842\": \"Swinging Vine\", \"#FFD7CEC5\": \"Swirl Variant\", \"#FFCECAC1\": \"Swirling Smoke\", \"#FFE6E9E9\": \"Swirling Water\", \"#FFE4DACC\": \"Swiss Almond\", \"#FF6E5F53\": \"Swiss Brown\", \"#FFDD5E6D\": \"Swiss Chard\", \"#FFFFF4B9\": \"Swiss Cheese\", \"#FF8C6150\": \"Swiss Chocolate\", \"#FFD5C3AD\": \"Swiss Coffee Variant\", \"#FFECEAD9\": \"Swiss Cream\", \"#FFC6C3B4\": \"Swiss Livery\", \"#FFE8D5DD\": \"Swiss Rose\", \"#FF67667C\": \"Swollen Sky\", \"#FFD6D2DE\": \"Sword Steel\", \"#FF8BCBAB\": \"Sybarite Green\", \"#FF6A8779\": \"Sycamore Grove\", \"#FF959E8F\": \"Sycamore Stand\", \"#FF9C8A79\": \"Sycamore Tan\", \"#FF3F544F\": \"Sycamore Tree\", \"#FFCBB394\": \"Sycorax Bronze\", \"#FF97BBC8\": \"Sydney Harbour\", \"#FFADAAB1\": \"Sylph\", \"#FF979381\": \"Sylvan\", \"#FFE7EACB\": \"Sylvan Green\", \"#FFAC8262\": \"Sylvaneth Bark\", \"#FFB29EAD\": \"Symbolic\", \"#FF8FA0A7\": \"Symmetry\", \"#FFC0A887\": \"Symphony Gold\", \"#FF89A0A6\": \"Symphony of Blue\", \"#FF331133\": \"Synallactida\", \"#FFC7D4CE\": \"Synchronicity\", \"#FFF8C300\": \"Syndicalist\", \"#FF918151\": \"Syndicate Camouflage\", \"#FF48C2B0\": \"Synergy\", \"#FF9FFEB0\": \"Synthetic Mint\", \"#FF1EF876\": \"Synthetic Spearmint\", \"#FF792E35\": \"Syrah\", \"#FFA16717\": \"Syrah Soil\", \"#FFDFCAE4\": \"Syrian Violet\", \"#FFB18867\": \"Syrup\", \"#FF3A2EFE\": \"System Shock Blue\", \"#FF8020FF\": \"Sz\\u00f6ll\\u0151si Grape\", \"#FF6FC1AF\": \"T-Bird Turquoise\", \"#FF8E908D\": \"T-Rex Fossil\", \"#FFC7C4A5\": \"Ta Prohm\", \"#FF709572\": \"Tabbouleh\", \"#FF526525\": \"Tabbouleh Green\", \"#FF9A948D\": \"Tabby Cat Grey\", \"#FFF1E9DC\": \"Table Linen\", \"#FFE5C279\": \"Table Pear Yellow\", \"#FF005553\": \"Tabriz Teal\", \"#FFF6AE78\": \"Tacao Variant\", \"#FFD2B960\": \"Tacha Variant\", \"#FFF3C7B3\": \"Taco\", \"#FFD3E7C7\": \"Tactile\", \"#FF7AD7AD\": \"Tadorna Teal\", \"#FF7D7771\": \"Tadpole\", \"#FFAF797E\": \"Taffeta Darling\", \"#FF81825F\": \"Taffeta Sheen\", \"#FFF3E0EB\": \"Taffeta Tint\", \"#FFC39B6A\": \"Taffy\", \"#FFFEA6C8\": \"Taffy Pink\", \"#FFAAD0BA\": \"Taffy Twist\", \"#FFF9F2D4\": \"Tagliatelle\", \"#FFD9BEAA\": \"Tagsale Linen\", \"#FFDDBB77\": \"Tahini\", \"#FF9B856B\": \"Tahini Brown\", \"#FFDC722A\": \"Tahiti Gold Variant\", \"#FFB8E9E4\": \"Tahitian Breeze\", \"#FF263644\": \"Tahitian Pearl\", \"#FFF5DCB4\": \"Tahitian Sand\", \"#FFC9E9E7\": \"Tahitian Sky\", \"#FF00677E\": \"Tahitian Tide\", \"#FF00686D\": \"Tahitian Treat\", \"#FF94B8C1\": \"Tahoe Blue\", \"#FFD7E1E5\": \"Tahoe Snow\", \"#FFD8CC9B\": \"Tahuna Sands Variant\", \"#FF768078\": \"Taiga\", \"#FFDD4411\": \"Tail Lights\", \"#FFDFC2AA\": \"Tailor\\u2019s Buff\", \"#FFBD9D7E\": \"Tailored Tan\", \"#FFF5E8CF\": \"Tailwind\", \"#FFB54A4A\": \"Tainan Brick\", \"#FFEAD795\": \"Tainted Gold\", \"#FFBB5520\": \"Taisha Brown\", \"#FF9F5233\": \"Taisha Red\", \"#FF3377A2\": \"Taiwan Blue Magpie\", \"#FFC7AA71\": \"Taiwan Gold\", \"#FF734A33\": \"Taj\", \"#FFEDE9DF\": \"Taj Mahal\", \"#FF3D4D78\": \"Takaka\", \"#FFBACBC5\": \"Take a Hike\", \"#FFB3C9D3\": \"Take Five\", \"#FFD8D4DD\": \"Take the Plunge\", \"#FFE6CCB7\": \"Take-Out\", \"#FFA0928B\": \"Talavera\", \"#FFE7B25D\": \"Tal\\u00e2yi Gold\", \"#FF707E84\": \"Taliesin Blue\", \"#FF648149\": \"Talipot Palm\", \"#FF159F9B\": \"Talismanic Teal\", \"#FF853534\": \"Tall Poppy Variant\", \"#FF0E81B9\": \"Tall Ships\", \"#FF5C9BCC\": \"Tall Waves\", \"#FF947E74\": \"Tallarn Leather\", \"#FFA79B5E\": \"Tallarn Sand\", \"#FFA39977\": \"Tallow Variant\", \"#FFFCD575\": \"Tamago Egg\", \"#FFFFA631\": \"Tamago Orange\", \"#FF3B3F40\": \"Tamahagane\", \"#FFF0E4C6\": \"Tamale\", \"#FFF8E7B7\": \"Tamale Maize\", \"#FFDEAA9B\": \"Tamanegi Peel\", \"#FFF2DD55\": \"Tamarack Yellow\", \"#FF11DDEE\": \"Tamarama\", \"#FF752B2F\": \"Tamarillo Variant\", \"#FF75503B\": \"Tamarind Fruit\", \"#FF8E604B\": \"Tamarind Tart\", \"#FF7C7D57\": \"Tambo Tank\", \"#FFBDC8AF\": \"Tamboon\", \"#FFF0EDD6\": \"Tambourine\", \"#FF658498\": \"Tambua Bay\", \"#FFC1E6DF\": \"Tame Teal\", \"#FFC5C5AC\": \"Tame Thyme\", \"#FF9C2626\": \"Tamed Beast\", \"#FFCFBCCF\": \"Tamed Beauty\", \"#FFD1B26F\": \"Tan Variant\", \"#FFA38D6D\": \"Tan 686A\", \"#FFAB7E4C\": \"Tan Brown\", \"#FFA9BE70\": \"Tan Green\", \"#FF323939\": \"T\\u00e0n H\\u0113i Soot\", \"#FFC2AA87\": \"Tan Oak\", \"#FFC19E78\": \"Tan Plan\", \"#FFCDB59C\": \"Tan Suede\", \"#FFF0BD9E\": \"Tan Temptation\", \"#FFA3755D\": \"Tan Wagon\", \"#FFF1D7CE\": \"Tan Whirl\", \"#FFB5905A\": \"Tan Your Hide\", \"#FFB8B5A1\": \"Tana Variant\", \"#FFA43834\": \"Tanager\", \"#FF8DD8E7\": \"Tanager Turquoise\", \"#FFD0B25C\": \"Tanami Desert\", \"#FFE9B581\": \"Tanaris Beige\", \"#FF896656\": \"Tanbark\", \"#FF766451\": \"Tanbark Trail\", \"#FF4A766E\": \"Tandayapa Cloud Forest\", \"#FFBB5C4D\": \"Tandoori\", \"#FFD25762\": \"Tandoori Red\", \"#FF9F4440\": \"Tandoori Spice\", \"#FF97725F\": \"Tangara\", \"#FF1E2F3C\": \"Tangaroa Variant\", \"#FFF2E9DE\": \"Tangelo Cream\", \"#FFEAD3A2\": \"Tangent\", \"#FF50507F\": \"Tangent Periwinkle\", \"#FFFF9300\": \"Tangerine Variant\", \"#FFD86130\": \"Tangerine Bliss\", \"#FFFF8449\": \"Tangerine Dream\", \"#FFE57F5B\": \"Tangerine Flake\", \"#FFDE8417\": \"Tangerine Haze\", \"#FFFFCC95\": \"Tangerine Silk\", \"#FFFF9E4B\": \"Tangerine Tango\", \"#FFF8AD1B\": \"Tangerine Twist\", \"#FFFECD01\": \"Tangerine Yellow\", \"#FFA97164\": \"Tangier\", \"#FF7C7C65\": \"Tangle\", \"#FFB19466\": \"Tangled Twine\", \"#FFCAC19A\": \"Tangled Vines\", \"#FFB2B2B2\": \"Tangled Web\", \"#FFA58F85\": \"Tanglewood\", \"#FFE7CEB8\": \"Tanglewood Park\", \"#FFD46F31\": \"Tango Variant\", \"#FFE47F7A\": \"Tango Pink\", \"#FFB10E2A\": \"Tango Red\", \"#FFE3C382\": \"Tangy\", \"#FF9A9147\": \"Tangy Dill\", \"#FFBB9B52\": \"Tangy Green\", \"#FFE7CAC3\": \"Tangy Taffy\", \"#FF5C6141\": \"Tank\", \"#FF848481\": \"Tank Grey\", \"#FF9AA0A2\": \"Tank Head\", \"#FFEFC93D\": \"Tank Yellow\", \"#FF7D7463\": \"Tankard Grey\", \"#FFF2C108\": \"Tanned Leather\", \"#FF8F6E4B\": \"Tanned Wood\", \"#FF5C493E\": \"Tannery Brown\", \"#FFA68B6D\": \"Tannin\", \"#FFAE6C37\": \"Tanooki Suit Brown\", \"#FFC7C844\": \"Tansy\", \"#FF95945C\": \"Tansy Green\", \"#FF669CCB\": \"Tantalise\", \"#FF87DCCE\": \"Tantalising Teal\", \"#FF857158\": \"Tantanmen Brown\", \"#FFFCD215\": \"Tanzanian Gold\", \"#FF1478A7\": \"Tanzanite\", \"#FF114A6B\": \"Tanzanite Blue\", \"#FF7983D7\": \"Tanzine\", \"#FFBFA77F\": \"Taos Taupe\", \"#FF2B8C8A\": \"Taos Turquoise\", \"#FF2F3032\": \"Tap Shoe\", \"#FF7C7C72\": \"Tapa Variant\", \"#FF906528\": \"Tapenade\", \"#FFF7F2DD\": \"Tapering Light\", \"#FFB37084\": \"Tapestry Variant\", \"#FFB8AC9E\": \"Tapestry Beige\", \"#FFB4966B\": \"Tapestry Gold\", \"#FFC06960\": \"Tapestry Red\", \"#FF4D7F86\": \"Tapestry Teal\", \"#FFDAC9B9\": \"Tapioca\", \"#FFDEF1DD\": \"Tara Variant\", \"#FF767A49\": \"Tara\\u2019s Drapes\", \"#FF253C48\": \"Tarawera Variant\", \"#FF105673\": \"Tardis\", \"#FF003B6F\": \"Tardis Blue\", \"#FFA1CDBF\": \"Tareyton\", \"#FF5A5348\": \"Tarmac\", \"#FF477F4A\": \"Tarmac Green\", \"#FF7F6C24\": \"Tarnished Brass\", \"#FF797B80\": \"Tarnished Silver\", \"#FFB9A47E\": \"Tarnished Treasure\", \"#FFD5B176\": \"Tarnished Trumpet\", \"#FFC1B55C\": \"Tarpon Green\", \"#FFA4AE77\": \"Tarragon\", \"#FFB4AC84\": \"Tarragon Tease\", \"#FF825E61\": \"Tarsier\", \"#FFB6D27E\": \"Tart Apple\", \"#FFF6EEC9\": \"Tart Gelato\", \"#FFB1282A\": \"Tartan Red\", \"#FFBF5B3C\": \"Tartare\", \"#FFFDDCD9\": \"Tartlet\", \"#FFF7D917\": \"Tartrazine\", \"#FF919585\": \"Tarzan Green\", \"#FFBAC0B3\": \"Tasman Variant\", \"#FFE6C562\": \"Tasman Honey Yellow\", \"#FF658A8A\": \"Tasmanian Sea\", \"#FFC6884A\": \"Tassel\", \"#FFF9C0CE\": \"Tassel Flower\", \"#FF9F9291\": \"Tassel Taupe\", \"#FFC8A3B8\": \"Taste of Berry\", \"#FFF2AE73\": \"Taste of Summer\", \"#FF9B6D54\": \"Tasty Toffee\", \"#FFDECCAF\": \"Tatami\", \"#FFAF9D83\": \"Tatami Mat\", \"#FFBA8C64\": \"Tatami Tan\", \"#FF976E9A\": \"Tatarian Aster\", \"#FF988F63\": \"Tate Olive\", \"#FFA2806F\": \"Tattered Teddy\", \"#FF80736A\": \"Tattletail\", \"#FF376D03\": \"Tatzelwurm Green\", \"#FFF7D60D\": \"Tau Light Ochre\", \"#FFA3813F\": \"Tau Sept Ochre\", \"#FFB9A281\": \"Taupe Variant\", \"#FF483C30\": \"Taupe Brown\", \"#FFE1D9D0\": \"Taupe Mist\", \"#FF705A56\": \"Taupe Night\", \"#FFDAD2C6\": \"Taupe of the Morning\", \"#FFC3A79A\": \"Taupe Tapestry\", \"#FFE0D9CF\": \"Taupe Tease\", \"#FFADA090\": \"Taupe Tone\", \"#FFC7C1BB\": \"Taupe White\", \"#FFBAAEA8\": \"Taupedo\", \"#FF77BE52\": \"Taurus Forest Fern\", \"#FFB7A594\": \"Tavern\", \"#FF957046\": \"Tavern Creek\", \"#FF9E938F\": \"Tavern Taupe\", \"#FFD19776\": \"Tawny Amber\", \"#FFAA7B65\": \"Tawny Birch\", \"#FFAB856F\": \"Tawny Brown\", \"#FFEEE4D1\": \"Tawny Daylily\", \"#FFA7947C\": \"Tawny Ember\", \"#FFB39997\": \"Tawny Mushroom\", \"#FFC4962C\": \"Tawny Olive\", \"#FFD37F6F\": \"Tawny Orange\", \"#FF978B71\": \"Tawny Owl\", \"#FF643A48\": \"Tawny Port Variant\", \"#FFCCB299\": \"Tawny Tan\", \"#FF496569\": \"Tax Break\", \"#FF5C3937\": \"Taxite\", \"#FF5F5879\": \"Taylor\", \"#FF2B4B40\": \"Te Papa Green Variant\", \"#FFBFB5A2\": \"Tea Variant\", \"#FF726259\": \"Tea Bag\", \"#FFF5EBE1\": \"Tea Biscuit\", \"#FFB5A9AC\": \"Tea Blossom Pink\", \"#FF605547\": \"Tea Chest\", \"#FFF4E1C0\": \"Tea Cookie\", \"#FF8F8667\": \"Tea Leaf\", \"#FFA59564\": \"Tea Leaf Brown\", \"#FF888E7E\": \"Tea Leaf Mouse\", \"#FFF8E4C2\": \"Tea Light\", \"#FFFFD7D0\": \"Tea Party\", \"#FFDCB5B0\": \"Tea Room\", \"#FFF883C2\": \"Tea Rose\", \"#FFCAC6B5\": \"Tea Stain\", \"#FFC5A5C7\": \"Tea Towel\", \"#FFDC3855\": \"Teaberry\", \"#FFB44940\": \"Teaberry Blossom\", \"#FFAB8953\": \"Teak Variant\", \"#FF8D7E6D\": \"Teakwood\", \"#FF71999B\": \"Teal & Tonic\", \"#FF57A1A0\": \"Teal Bayou\", \"#FF01889F\": \"Teal Blue Variant\", \"#FF0F4D5C\": \"Teal Dark Blue\", \"#FF006D57\": \"Teal Dark Green\", \"#FF99E6B3\": \"Teal Deer\", \"#FF24604F\": \"Teal Drama\", \"#FF3DA3AE\": \"Teal Essence\", \"#FF405B5D\": \"Teal Forest\", \"#FF1A6C76\": \"Teal Fury\", \"#FF3E9EAC\": \"Teal Glacier\", \"#FF25A36F\": \"Teal Green Variant\", \"#FFD1EFE9\": \"Teal Ice\", \"#FF0DACA7\": \"Teal Me No Lies\", \"#FFC8EDE2\": \"Teal Melody\", \"#FF50B7CF\": \"Teal Moir\\u00e9\", \"#FF406976\": \"Teal Mosaic\", \"#FF006D73\": \"Teal Motif\", \"#FF032425\": \"Teal Spill\", \"#FF627F7B\": \"Teal Stencil\", \"#FFD9F2E3\": \"Teal Treat\", \"#FF94B9B4\": \"Teal Tree\", \"#FF4E939D\": \"Teal Trinket\", \"#FF00A093\": \"Teal Trip\", \"#FF02708C\": \"Teal Tune\", \"#FF007765\": \"Teal Waters\", \"#FF8B9EA1\": \"Teal Wave\", \"#FF2B7B6C\": \"Teal We Meet Again\", \"#FF01697A\": \"Teal With It\", \"#FF24BCA8\": \"Tealish\", \"#FF0CDC73\": \"Tealish Green\", \"#FF416986\": \"Team Spirit\", \"#FFE2E2E1\": \"Teapot\", \"#FFB5D8DF\": \"Tear\", \"#FFD1EAEA\": \"Teardrop\", \"#FFF0F1DA\": \"Tears of Joy\", \"#FFDED2E8\": \"Teary Eyed\", \"#FFCEAEFA\": \"Teasel Dipsacus\", \"#FFF1E1D7\": \"Teasing Peach\", \"#FFBE9B79\": \"Teatime\", \"#FFC8A89E\": \"Teatime Mauve\", \"#FF4C7A9D\": \"Tech Wave\", \"#FF9FA1A1\": \"Techile\", \"#FF587C8D\": \"Technical Blue\", \"#FF006B8B\": \"Techno Blue\", \"#FF69AC58\": \"Techno Green\", \"#FFDD95B4\": \"Techno Pink\", \"#FFBFB9AA\": \"Techno Taupe\", \"#FF60BD8E\": \"Techno Turquoise\", \"#FFFF80F9\": \"Technolust\", \"#FFA3BAE3\": \"Teclis Blue\", \"#FFAC8067\": \"Teddy\", \"#FF9D8164\": \"Teddy Bear\", \"#FFCEB79D\": \"Teddy Bears & Cream\", \"#FFBCAC9F\": \"Teddy\\u2019s Taupe\", \"#FFC00C20\": \"Tedious Red\", \"#FF68855A\": \"Tee Off\", \"#FFA67498\": \"Teen Queen\", \"#FF326395\": \"Teeny Bikini\", \"#FFF2DBD7\": \"Teewurst\", \"#FFC1B65F\": \"Tegreen\", \"#FFAD66D2\": \"Teldrassil Purple\", \"#FFAA22CC\": \"Telemagenta Variant\", \"#FFF0F3F1\": \"Tell Me a Secret\", \"#FF2D2541\": \"Telopea\", \"#FF47626A\": \"Tempe Star\", \"#FF2B8725\": \"Temperamental Green\", \"#FFBFB1AA\": \"Temperate Taupe\", \"#FF987E70\": \"Tempered Allspice\", \"#FF772211\": \"Tempered Chocolate\", \"#FFA1AEB1\": \"Tempered Grey\", \"#FFE3DBB7\": \"Tempered Sage\", \"#FF79839B\": \"Tempest\", \"#FF303A40\": \"Tempest in a Teapot\", \"#FFF2E688\": \"Templar\\u2019s Gold\", \"#FFA6C9E3\": \"Template\", \"#FF339A8D\": \"Temple Guard Blue\", \"#FFEE7755\": \"Temple of Orange\", \"#FFA9855D\": \"Temple Tile\", \"#FF33ABB2\": \"Tempo\", \"#FF018C94\": \"Tempo Teal\", \"#FF987465\": \"Temptation\", \"#FFFF7733\": \"Temptatious Tangerine\", \"#FFDD8CB5\": \"Tempting Pink\", \"#FFCCAA99\": \"Tempting Taupe\", \"#FF3C2126\": \"Temptress Variant\", \"#FF98F6B0\": \"Tenacious Tentacles\", \"#FFF7E8D7\": \"Tender\", \"#FFC5CFB6\": \"Tender Greens\", \"#FFE0D4E0\": \"Tender Limerence\", \"#FFF8D5B8\": \"Tender Peach\", \"#FFDDC6BD\": \"Tender Shell\", \"#FFACCB35\": \"Tender Shoot\", \"#FFE8E287\": \"Tender Sprout\", \"#FFC4B198\": \"Tender Taupe\", \"#FFD5C6D6\": \"Tender Touch\", \"#FF82D9C5\": \"Tender Turquoise\", \"#FFA17E64\": \"Tender Twig\", \"#FFB7CFE2\": \"Tender Twilight\", \"#FFD4C3DA\": \"Tender Violet\", \"#FFBADBDF\": \"Tender Waves\", \"#FFE8EBAF\": \"Tender Yellow\", \"#FFC8DBCE\": \"Tenderness\", \"#FF869C65\": \"Tendril\", \"#FFDFFF4F\": \"Tennis Ball\", \"#FF7CB5C6\": \"Tennis Blue\", \"#FFC8450C\": \"Tennis Court\", \"#FFA35732\": \"Tense Terracotta\", \"#FFA89F86\": \"Tent Green\", \"#FFFFBACD\": \"Tentacle Pink\", \"#FF9ECFD9\": \"Tenzing\", \"#FFF4D0A4\": \"Tequila Variant\", \"#FFEB6238\": \"Teri-Gaki Persimmon\", \"#FFDCDFE5\": \"Terminator Chrome\", \"#FFBDB192\": \"Terminatus Stone\", \"#FFDDBB66\": \"Termite Beige\", \"#FFD5CDBD\": \"Tern Grey\", \"#FF5A382D\": \"Terra Brun\", \"#FFE2B5A6\": \"Terra Cotta Blush\", \"#FFD08F73\": \"Terra Cotta Clay\", \"#FFD38D71\": \"Terra Cotta Pot\", \"#FFC94D42\": \"Terra Cotta Red\", \"#FF9C675F\": \"Terra Cotta Sun\", \"#FFB06F60\": \"Terra Cotta Urn\", \"#FF844C47\": \"Terra Cove\", \"#FFD59982\": \"Terra Earth\", \"#FFCC7661\": \"Terra Orange\", \"#FFBB6569\": \"Terra Rosa\", \"#FF9F6D66\": \"Terra Rose\", \"#FFE8B57B\": \"Terra Sol\", \"#FFB6706B\": \"Terra Tone\", \"#FF73544D\": \"Terrace Brown\", \"#FFA1D8E0\": \"Terrace Pool\", \"#FFB2AB9C\": \"Terrace Taupe\", \"#FF275B60\": \"Terrace Teal\", \"#FFCAD0BF\": \"Terrace View\", \"#FFCB6843\": \"Terracotta Variant\", \"#FFC47C5E\": \"Terracotta Chip\", \"#FF976A66\": \"Terracotta Red Brown\", \"#FFD6BA9B\": \"Terracotta Sand\", \"#FF708157\": \"Terrain\", \"#FFA1965E\": \"Terran Khaki\", \"#FF807F4A\": \"Terrapin\", \"#FF5F6D5C\": \"Terrarium\", \"#FFA28873\": \"Terrazzo Brown\", \"#FFBE8973\": \"Terrazzo Tan\", \"#FF276757\": \"Terrestrial\", \"#FF1D4769\": \"Terror From the Deep\", \"#FFDDAAFF\": \"Testosterose\", \"#FFD90166\": \"T\\u00eate-\\u00e0-T\\u00eate\", \"#FF8D99A1\": \"Teton Blue\", \"#FFDFEAE8\": \"Teton Breeze\", \"#FF1E20C7\": \"Tetraammine\", \"#FF8E6F73\": \"Tetrarose\", \"#FF2B3733\": \"Tetsu Black\", \"#FF005243\": \"Tetsu Green\", \"#FF455765\": \"Tetsu Iron\", \"#FF281A14\": \"Tetsu-Guro Black\", \"#FF17184B\": \"Tetsu-Kon Blue\", \"#FF2B3736\": \"Tetsuonando Black\", \"#FFE2DDD1\": \"Texan Angel\", \"#FFECE67E\": \"Texas Variant\", \"#FF8B6947\": \"Texas Boots\", \"#FFA54E37\": \"Texas Heatwave\", \"#FFC9926E\": \"Texas Hills\", \"#FFA0522D\": \"Texas Ranger Brown\", \"#FFF1D2C9\": \"Texas Rose Variant\", \"#FFB9A77C\": \"Texas Sage\", \"#FFFC9625\": \"Texas Sunset\", \"#FF794840\": \"Texas Sweet Tea\", \"#FF5500EE\": \"Tezcatlip\\u014dca Blue\", \"#FF7A7F3F\": \"Thai Basil\", \"#FFCE0001\": \"Thai Chilli\", \"#FFBD6B1C\": \"Thai Curry\", \"#FFFE1C06\": \"Thai Hot\", \"#FFE0A878\": \"Thai Ice Tea\", \"#FFBB4455\": \"Thai Spice\", \"#FF624435\": \"Thai Teak\", \"#FF2E8689\": \"Thai Teal\", \"#FFE7C630\": \"Thai Temple\", \"#FF53B1BA\": \"Thalassa\", \"#FF44AADD\": \"Thalassophile\", \"#FF58F898\": \"Thallium Flame\", \"#FF181818\": \"Thamar Black\", \"#FF62676A\": \"Thames Dusk\", \"#FF949586\": \"Thames Fog\", \"#FFB56E4A\": \"Thanksgiving\", \"#FFB0B08E\": \"That\\u2019s Atomic\", \"#FF8E3350\": \"That\\u2019s My Jam\", \"#FFDCD290\": \"That\\u2019s My Lime\", \"#FFB1948F\": \"Thatch Variant\", \"#FF867057\": \"Thatch Brown\", \"#FF544E31\": \"Thatch Green Variant\", \"#FFD6C7A6\": \"Thatched Cottage\", \"#FFEFE0C6\": \"Thatched Roof\", \"#FFE1EEEC\": \"Thawed Out\", \"#FFDD0088\": \"The Art of Seduction\", \"#FFBBFFFF\": \"The Big Freeze\", \"#FF214DAA\": \"The Blues Brothers\", \"#FFFFC8C2\": \"The Bluff\", \"#FFD0A492\": \"The Boulevard\", \"#FF837663\": \"The Cottage\", \"#FF102030\": \"The Count\\u2019s Black\", \"#FF22C1D5\": \"The Crowd Roars!\", \"#FFA75455\": \"The Ego Has Landed\", \"#FF2A2A2A\": \"The End\", \"#FFEED508\": \"The End Is Beer\", \"#FF585673\": \"The Fang\", \"#FF436174\": \"The Fang Grey\", \"#FFF0E22C\": \"The Fifth Sun\", \"#FFFFF08C\": \"The First Daffodil\", \"#FFE9D2AF\": \"The Golden State\", \"#FFAAA651\": \"The Goods\", \"#FFBB00FF\": \"The Grape War of 97\\u2019\", \"#FF558844\": \"The Legend of Green\", \"#FF70F15E\": \"The Matrix\", \"#FFFF8400\": \"The New Black\", \"#FF818580\": \"The North Wind Blows\", \"#FF4466EE\": \"The Rainbow Fish\", \"#FFF6F4EF\": \"The Speed of Light\", \"#FF110066\": \"The Vast of Night\", \"#FFCDBB63\": \"The Weight of Gold\", \"#FFDADDED\": \"The White Death\", \"#FF118844\": \"The Wild Apothecary\", \"#FF21467A\": \"Theatre Blue\", \"#FFEEF4DB\": \"Theatre District Lights\", \"#FF274242\": \"Theatre Dress\", \"#FFA76924\": \"Theatre Gold\", \"#FFE2D4D4\": \"Theatre Powder Rose\", \"#FFE2B13C\": \"Themeda Japonica\", \"#FFEE7711\": \"Therapeutic Toucan\", \"#FF002288\": \"There Is Light\", \"#FFAD9569\": \"There\\u2019s No Place Like Home\", \"#FF3F5052\": \"Thermal\", \"#FF9CCEBE\": \"Thermal Aqua\", \"#FF589489\": \"Thermal Spring\", \"#FFEB3318\": \"Thermic Orange\", \"#FF8FADBD\": \"Thermocline\", \"#FFD2BB95\": \"Thermos\", \"#FFFBE4B3\": \"They Call It Mellow\", \"#FF5566DD\": \"Thick Blue\", \"#FFDCD3CE\": \"Thick Fog\", \"#FF88CC22\": \"Thick Green\", \"#FFCC55DD\": \"Thick Pink\", \"#FF8833DD\": \"Thick Purple\", \"#FFB30D0D\": \"Thick Red\", \"#FFF1D512\": \"Thick Yellow\", \"#FF69865B\": \"Thicket\", \"#FF93840F\": \"Thicket Green\", \"#FFA05D8B\": \"Thimble Red\", \"#FFE34B50\": \"Thimbleberry\", \"#FFAFA97D\": \"Thimbleberry Leaf\", \"#FFC6FCFF\": \"Thin Air\", \"#FFD4DCDA\": \"Thin Cloud\", \"#FFCAE0DF\": \"Thin Heights\", \"#FF834841\": \"Think Brick\", \"#FF4D8871\": \"Think Leaf\", \"#FFE5A5C1\": \"Think Pink\", \"#FF243BCD\": \"Third Eye Chakra\", \"#FF726E9B\": \"Thirsty Thursday\", \"#FF9499BB\": \"Thistle Down\", \"#FFC0B6A8\": \"Thistle Grey\", \"#FF834D7C\": \"Thistle Mauve\", \"#FF8AB3BF\": \"Thistleblossom Soft Blue\", \"#FF44CCFF\": \"Thor\\u2019s Thunder\", \"#FFB5A197\": \"Thorn Crown\", \"#FF9C2D5D\": \"Thorne Wines\", \"#FF4C4A41\": \"Thorny Branch\", \"#FF7F716A\": \"Thorny Brush\", \"#FF5B3D34\": \"Thoroughfare\", \"#FFD8CDC8\": \"Thought\", \"#FF317589\": \"Thousand Herb\", \"#FFFFD9BB\": \"Thousand Needles Sand\", \"#FFE9E8E1\": \"Thousand Shells\", \"#FF02D8E9\": \"Thousand Sons Blue\", \"#FF316745\": \"Thousand Years Green\", \"#FF4F6446\": \"Thraka Green Wash\", \"#FFCEC2AA\": \"Threaded Loom\", \"#FFC30305\": \"Threatening Red\", \"#FF73C4D7\": \"Thredbo\", \"#FFFDDBB6\": \"Three Ring Circus\", \"#FFBDC4BB\": \"Three Wishes\", \"#FF93CCE7\": \"Thresher Shark\", \"#FFAC9A8A\": \"Threshold Taupe\", \"#FF8C283B\": \"Thrill Ride\", \"#FF8CC34B\": \"Thrilling Lime\", \"#FF281F3F\": \"Throat\", \"#FF6ACED4\": \"Throat Chakra\", \"#FFADA274\": \"Throw Rug\", \"#FF936B4F\": \"Thrush\", \"#FFA4B6A7\": \"Thrush Egg\", \"#FF11610F\": \"Thuja Green\", \"#FFDF6FA1\": \"Thulian Pink Variant\", \"#FFDDC2BA\": \"Thulite Rose\", \"#FFBDADA4\": \"Thumper\", \"#FFE88A76\": \"Thundelarra\", \"#FF4D4D4B\": \"Thunder Variant\", \"#FFF9F5DB\": \"Thunder & Lightning\", \"#FFCBD9D7\": \"Thunder Bay\", \"#FFAAC4D4\": \"Thunder Chi\", \"#FF57534C\": \"Thunder Grey\", \"#FFCE1B1F\": \"Thunder Mountain Longhorn Pepper\", \"#FF1A4876\": \"Thunder Night\", \"#FF923830\": \"Thunderbird Variant\", \"#FFFDEFAD\": \"Thunderbolt\", \"#FF8A99A3\": \"Thundercat\", \"#FF698589\": \"Thundercloud\", \"#FFF6F3A7\": \"Thunderdome\", \"#FF417074\": \"Thunderhawk Blue\", \"#FF597388\": \"Thundering Clouds\", \"#FF6D6C62\": \"Thunderous\", \"#FFD2D1CE\": \"Thundersnow\", \"#FF9098A1\": \"Thunderstorm\", \"#FF5F5755\": \"Thunderstruck\", \"#FF7F7B60\": \"Thurman\", \"#FF98514A\": \"Thy Flesh Consumed\", \"#FF50574C\": \"Thyme\", \"#FF6F8770\": \"Thyme and Place\", \"#FF629A31\": \"Thyme and Salt\", \"#FF737B6C\": \"Thyme Green\", \"#FF97422D\": \"Tia Maria Variant\", \"#FF9BB2AA\": \"Tiamo\", \"#FF5DB3FF\": \"Ti\\u0101n L\\u00e1n Sky\", \"#FF566B38\": \"Ti\\u0101nt\\u0101i Mountain Green\", \"#FFB9C3BE\": \"Tiara Variant\", \"#FFEAE0E8\": \"Tiara Jewel\", \"#FFDAA6CF\": \"Tiara Pink\", \"#FF184343\": \"Tiber Variant\", \"#FF6A6264\": \"Tibetan Cloak\", \"#FFF6F3E1\": \"Tibetan Jasmine\", \"#FFAE5848\": \"Tibetan Orange\", \"#FF88FFDD\": \"Tibetan Plateau\", \"#FF8B3145\": \"Tibetan Red\", \"#FF9C8A52\": \"Tibetan Silk\", \"#FFDBEAED\": \"Tibetan Sky\", \"#FF74B7C1\": \"Tibetan Stone\", \"#FF814D50\": \"Tibetan Temple\", \"#FF0084A6\": \"Tibetan Turquoise\", \"#FF268BCC\": \"Ticino Blue\", \"#FFEFA7BF\": \"Tickled Pink\", \"#FFF0F590\": \"Tidal Variant\", \"#FF78B3CC\": \"Tidal Basin\", \"#FFBFB9A3\": \"Tidal Foam\", \"#FFCDCA98\": \"Tidal Green\", \"#FFE5E9E1\": \"Tidal Mist\", \"#FF005E59\": \"Tidal Pool\", \"#FF43A7AA\": \"Tidal Teal\", \"#FF8B866B\": \"Tidal Thicket\", \"#FF355978\": \"Tidal Wave\", \"#FFBEB4AB\": \"Tide Variant\", \"#FF0A6F69\": \"Tide Pools\", \"#FF809899\": \"Tidepool Wonder\", \"#FF002400\": \"Tides of Darkness\", \"#FFC2E3DD\": \"Tidewater\", \"#FF343450\": \"Ti\\u011b H\\u0113i Metal\", \"#FFC2DDD3\": \"Tierra Del Fuego Sea Green\", \"#FFB58141\": \"Tiffany Amber\", \"#FFFDE4B4\": \"Tiffany Light\", \"#FFD2A694\": \"Tiffany Rose\", \"#FFBE9C67\": \"Tiger\", \"#FFCDA035\": \"Tiger Cat\", \"#FFE1DACA\": \"Tiger Claw\", \"#FFDEAE46\": \"Tiger Cub\", \"#FFDD9922\": \"Tiger King\", \"#FFE1583F\": \"Tiger Lily\", \"#FFF8F2DD\": \"Tiger Moth\", \"#FFDD6611\": \"Tiger Moth Orange\", \"#FFFF8855\": \"Tiger of Mysore\", \"#FFBF6F39\": \"Tiger Stripe\", \"#FFFEE9C4\": \"Tiger Tail\", \"#FFFFDE7E\": \"Tiger Yellow\", \"#FF9A7C63\": \"Tiger\\u2019s Eye\", \"#FFAA5500\": \"Tijolo\", \"#FF8A6E45\": \"Tiki Hut\", \"#FFB9A37E\": \"Tiki Straw\", \"#FFBB9E3F\": \"Tiki Torch\", \"#FF0094A5\": \"Tile Blue\", \"#FF7A958E\": \"Tile Green\", \"#FFC76B4A\": \"Tile Red\", \"#FF60397F\": \"Tillandsia Purple\", \"#FF80624E\": \"Tilled Earth\", \"#FF6B4D35\": \"Tilled Soil\", \"#FF87815F\": \"Tilleul de No\\u00e9mie\", \"#FFEE5522\": \"Tilted Pinball\", \"#FF991122\": \"Tilted Red\", \"#FFA0855C\": \"Timber Beam\", \"#FF605652\": \"Timber Brown\", \"#FFC0B09C\": \"Timber Dust\", \"#FF324336\": \"Timber Green Variant\", \"#FF908D85\": \"Timber Town\", \"#FFA1755C\": \"Timber Trail\", \"#FF73573F\": \"Timberline\", \"#FFB4ACA3\": \"Timberwolf Tint\", \"#FFA59888\": \"Time Capsule\", \"#FF7F6D37\": \"Time Honoured\", \"#FFFADEB8\": \"Time Out\", \"#FFB3C4D5\": \"Time Travel\", \"#FF9397A3\": \"Time Warp\", \"#FFB1D8DB\": \"Timeless\", \"#FFB6273E\": \"Timeless Beauty\", \"#FF976D59\": \"Timeless Copper\", \"#FFECE9E8\": \"Timeless Day\", \"#FFAFB2C4\": \"Timeless Lilac\", \"#FF9A4149\": \"Timeless Ruby\", \"#FFAFE4E2\": \"Timeless Seafoam\", \"#FF908379\": \"Timeless Taupe\", \"#FF20C073\": \"Times Square Screens\", \"#FFDADFB0\": \"Timid Absinthe\", \"#FFE5E0DD\": \"Timid Beige\", \"#FFD9E0EE\": \"Timid Blue\", \"#FFDCDDE5\": \"Timid Cloud\", \"#FFE1E2D6\": \"Timid Green\", \"#FFE4E0DA\": \"Timid Lime\", \"#FFDFDFEA\": \"Timid Purple\", \"#FF66A9B0\": \"Timid Sea\", \"#FFE4E0DD\": \"Timid Sheep\", \"#FFDED3DD\": \"Timid Violet\", \"#FFADB274\": \"Timothy Grass\", \"#FF919191\": \"Tin\", \"#FF48452B\": \"Tin Bitz\", \"#FFACB0B0\": \"Tin Foil\", \"#FF928A98\": \"Tin Lizzie\", \"#FFA4A298\": \"Tin Man\", \"#FFA3898A\": \"Tin Pink\", \"#FFE6541B\": \"Tingle\", \"#FFFBEDB8\": \"Tinker Light\", \"#FFFCF0C3\": \"Tinkerbell Trail\", \"#FF4B492D\": \"Tinny Tin\", \"#FFB88A3E\": \"Tinsel\", \"#FFC3D1D9\": \"Tinsel Beam\", \"#FFDCE0DC\": \"Tinsmith\", \"#FFCE9480\": \"Tint of Earth\", \"#FFDAE9DC\": \"Tint of Green\", \"#FFFFCBC9\": \"Tint of Rose\", \"#FF41BFB5\": \"Tint of Turquoise\", \"#FFCFF6F4\": \"Tinted Ice\", \"#FFC4B7D8\": \"Tinted Iris\", \"#FF9DA9D0\": \"Tinted Lilac\", \"#FFE3E7C4\": \"Tinted Mint\", \"#FFE1C8D1\": \"Tinted Rosewood\", \"#FF0088AB\": \"Tiny Bubbles\", \"#FFE0BFA5\": \"Tiny Calf\", \"#FFC08B6D\": \"Tiny Fawn\", \"#FFD4CFCC\": \"Tiny Ghost Town\", \"#FFB8D3E4\": \"Tiny Mr Frosty\", \"#FFFFD6C7\": \"Tiny Pink\", \"#FFB98FAF\": \"Tiny Ribbons\", \"#FF8A8D69\": \"Tiny Seedling\", \"#FFBBE4EA\": \"Tip of the Iceberg\", \"#FFD8C2CD\": \"Tip Toes\", \"#FF744B3E\": \"Tiramisu\", \"#FFD3BDA4\": \"Tiramisu Cream\", \"#FF75DE2F\": \"Tirisfal Lime\", \"#FF9E915C\": \"Tirol\", \"#FFDDD6E1\": \"Titan White Variant\", \"#FFAD8F0F\": \"Titanite Yellow\", \"#FF888586\": \"Titanium\", \"#FF5B798E\": \"Titanium Blue\", \"#FF545B62\": \"Titanium Grey\", \"#FFBCB9C0\": \"Titanium Man\", \"#FFE4E4E4\": \"Titanium White\", \"#FF646048\": \"Titanoboa\", \"#FFBD5620\": \"Titian Red\", \"#FFB8B2BE\": \"Titmouse Grey\", \"#FFF9F3DF\": \"Tizzy\", \"#FF316F82\": \"Tl\\u0101loc Blue\", \"#FF25212A\": \"To Hell and Black\", \"#FF748D70\": \"Toad\", \"#FF3D6C54\": \"Toad King\", \"#FFB8282F\": \"Toadstool\", \"#FFD7E7DA\": \"Toadstool Dot\", \"#FF988088\": \"Toadstool Soup\", \"#FF016C75\": \"Toadstool Teal\", \"#FF9F715F\": \"Toast Variant\", \"#FFD2AD84\": \"Toast and Butter\", \"#FFB59274\": \"Toasted\", \"#FFDACFBA\": \"Toasted Almond\", \"#FF986B4D\": \"Toasted Bagel\", \"#FFE7DDCB\": \"Toasted Barley\", \"#FFDAB7A8\": \"Toasted Beige\", \"#FFE2D0B8\": \"Toasted Cashew\", \"#FFA7775B\": \"Toasted Chestnut\", \"#FFE9C2A1\": \"Toasted Coconut\", \"#FFA24A3B\": \"Toasted Cranberry\", \"#FFC5A986\": \"Toasted Grain\", \"#FFED8A53\": \"Toasted Husk\", \"#FFEFE0D4\": \"Toasted Marshmallow\", \"#FFFFF9EB\": \"Toasted Marshmallow Fluff\", \"#FFC08768\": \"Toasted Nut\", \"#FFA47365\": \"Toasted Nutmeg\", \"#FFEFDECC\": \"Toasted Oatmeal\", \"#FFA34631\": \"Toasted Paprika\", \"#FF765143\": \"Toasted Pecan\", \"#FFDCC6A6\": \"Toasted Pine Nut\", \"#FFAF9A73\": \"Toasted Sesame\", \"#FFAA3344\": \"Toasted Truffle\", \"#FF746A5A\": \"Toasted Walnut\", \"#FFC9AF96\": \"Toasted Wheat\", \"#FF957258\": \"Toasty\", \"#FFD1CCC0\": \"Toasty Grey\", \"#FF684F3C\": \"Tobacco\", \"#FF6D5843\": \"Tobacco Brown Variant\", \"#FF8C724F\": \"Tobacco Leaf\", \"#FF44362D\": \"Tobago\", \"#FFD39898\": \"Tobermory\", \"#FF077A7D\": \"Tobernite\", \"#FFAD785C\": \"Tobey Rattan\", \"#FF4C221B\": \"Tobi Brown\", \"#FFE45C10\": \"Tobiko Orange\", \"#FFF8DCBF\": \"Toes in the Sand\", \"#FF755139\": \"Toffee\", \"#FF947255\": \"Toffee Bar\", \"#FFD98B51\": \"Toffee Cream\", \"#FF995E39\": \"Toffee Crunch\", \"#FF968678\": \"Toffee Fingers\", \"#FFA5654A\": \"Toffee Glaze\", \"#FFB17426\": \"Toffee Sauce\", \"#FFC8A883\": \"Toffee Tan\", \"#FFC08950\": \"Toffee Tart\", \"#FFE6BAA9\": \"Tofino\", \"#FF03719C\": \"Tofino Belue\", \"#FFE6E5D6\": \"Tofu\", \"#FF94BEE1\": \"Toile Blue\", \"#FF8B534E\": \"Toile Red\", \"#FFB88884\": \"Toki Brown\", \"#FF007B43\": \"Tokiwa Green\", \"#FFECF3D8\": \"Tokyo Underground\", \"#FF6C5846\": \"Tol Barad Green\", \"#FF4E4851\": \"Tol Barad Grey\", \"#FF3E2631\": \"Toledo Variant\", \"#FFDECBB1\": \"Toledo Cuoio\", \"#FF4F6348\": \"Tom Thumb Variant\", \"#FFE9D988\": \"Tomatillo\", \"#FFCAD3C1\": \"Tomatillo Peel\", \"#FFBBB085\": \"Tomatillo Salsa\", \"#FFEF4026\": \"Tomato Variant\", \"#FFE10D18\": \"Tomato Baby\", \"#FFD15915\": \"Tomato Bisque\", \"#FFD6201A\": \"Tomato Burst\", \"#FFF6561C\": \"Tomato Concass\\u00e9\", \"#FFBF753B\": \"Tomato Cream\", \"#FFE84A2E\": \"Tomato Curry\", \"#FFFF4444\": \"Tomato Frog\", \"#FFC9344C\": \"Tomato Puree\", \"#FFDD4422\": \"Tomato Queen\", \"#FFEC2D01\": \"Tomato Red\", \"#FFB21807\": \"Tomato Sauce\", \"#FFE44458\": \"Tomato Sceptre\", \"#FFA2423D\": \"Tomato Slices\", \"#FFAA251B\": \"Tomato Sunrise\", \"#FF0099CC\": \"Tomb Blue\", \"#FFCEC5B6\": \"Tombstone Grey\", \"#FFFAA945\": \"T\\u014dmorokoshi Corn\", \"#FFEEC362\": \"T\\u014dmorokoshi Yellow\", \"#FFFFC5A3\": \"Tomorrow\\u2019s Coral\", \"#FFD14155\": \"T\\u014dnatiuh Red\", \"#FFD1908E\": \"Tongue\", \"#FFDEDDAA\": \"Tonic\", \"#FF975437\": \"Tonicha\", \"#FF6B524C\": \"Tonka Bean\", \"#FFEDAC36\": \"Tonkatsu\", \"#FFB1A290\": \"Tony Taupe\", \"#FFE79E88\": \"Tonys Pink\", \"#FF9596A4\": \"Too Big\", \"#FF3D6695\": \"Too Blue\", \"#FF0088FF\": \"Too Blue Variant\", \"#FF0011BB\": \"Too Dark Tonight\", \"#FFFFB61E\": \"T\\u014d\\u014d Gold\", \"#FFBF6153\": \"Too Hot\", \"#FFD6BA66\": \"Tookie Bird\", \"#FF637985\": \"Tool Blue\", \"#FF7F7711\": \"Tool Green\", \"#FFBF843B\": \"Toothpick\", \"#FFF9DBE2\": \"Tootie Fruity\", \"#FFFAD873\": \"Top Banana\", \"#FFC1A393\": \"Top Hat Tan\", \"#FF82889C\": \"Top Shelf\", \"#FFD04838\": \"Top Tomato\", \"#FFCF7E40\": \"Topaz Variant\", \"#FFC5DDD0\": \"Topaz Green\", \"#FF92653F\": \"Topaz Mountain\", \"#FFEB975E\": \"Topaz Yellow\", \"#FF8E9655\": \"Topiary\", \"#FF6F7C00\": \"Topiary Garden\", \"#FF667700\": \"Topiary Green\", \"#FF618A4D\": \"Topiary Sculpture\", \"#FFBBC9B2\": \"Topiary Tint\", \"#FFAA5C71\": \"Topinambur Root\", \"#FFDAE2E0\": \"Topsail\", \"#FFE7E2DA\": \"Toque White\", \"#FFFD0D35\": \"Torch Red Variant\", \"#FFFFC985\": \"Torchlight\", \"#FF353D75\": \"Torea Bay Variant\", \"#FFCD123F\": \"Toreador\", \"#FFDB3E00\": \"Torii Red\", \"#FFD1D3CF\": \"Tornado\", \"#FF5E5B60\": \"Tornado Cloud\", \"#FF4D7179\": \"Tornado Season\", \"#FFABA698\": \"Tornado Watch\", \"#FF60635F\": \"Tornado Wind\", \"#FFFFDECD\": \"Toronja\", \"#FF4E241E\": \"Torrefacto Roast\", \"#FF55784F\": \"Torrey Pine\", \"#FF00938B\": \"Torrid Turquoise\", \"#FF5E8E91\": \"Tort\", \"#FFEFDBA7\": \"Tortilla\", \"#FF7C4937\": \"Tortoise Shell\", \"#FF9C5F22\": \"Tortoiseshell Specs\", \"#FF84816F\": \"Tortuga\", \"#FF374E88\": \"Tory Blue Variant\", \"#FFD6685F\": \"Tory Red\", \"#FF744042\": \"Tosca Variant\", \"#FF9F846B\": \"Toscana\", \"#FFE3C19C\": \"Tostada\", \"#FFA67E4B\": \"Tosty Crust\", \"#FF303543\": \"Total Eclipse\", \"#FFF6EAD8\": \"Total Recall\", \"#FF3F4041\": \"Totally Black\", \"#FF909853\": \"Totally Broccoli\", \"#FFCCA683\": \"Totally Tan\", \"#FF01868C\": \"Totally Teal\", \"#FFDD9977\": \"Totally Toffee\", \"#FFF09650\": \"Toucan\", \"#FFFBC90D\": \"Toucan Gentleman\", \"#FFC2D7E9\": \"Touch of Blue\", \"#FFF6DED5\": \"Touch of Blush\", \"#FF8E6F6E\": \"Touch of Class\", \"#FFC5E5DD\": \"Touch of Frost\", \"#FFDD8844\": \"Touch of Glamour\", \"#FFDBE9D5\": \"Touch of Green\", \"#FFD1CFCA\": \"Touch of Grey\", \"#FFE1E5D7\": \"Touch of Lime\", \"#FFF8FFF8\": \"Touch of Mint\", \"#FFD5C7BA\": \"Touch of Sand\", \"#FFC8D4CC\": \"Touch of Spring\", \"#FFFAF7E9\": \"Touch of Sun\", \"#FFEED9D1\": \"Touch of Tan\", \"#FFF7E4D0\": \"Touch of Topaz\", \"#FFA1D4CF\": \"Touch of Turquoise\", \"#FFECDFD8\": \"Touchable Pink\", \"#FFC3E4E8\": \"Touched by the Sea\", \"#FFF4E1D7\": \"Touching White\", \"#FFC7AC7D\": \"Toupe\", \"#FF83A1A7\": \"Tourmaline Variant\", \"#FFBDA3A5\": \"Tourmaline Mauve\", \"#FF4F9E96\": \"Tourmaline Turquoise\", \"#FF99D3DF\": \"Tourmaline Water Blue\", \"#FF54836B\": \"Tournament Field\", \"#FF7BA0A0\": \"Tower Bridge\", \"#FF9CACA5\": \"Tower Grey\", \"#FFD5B59B\": \"Tower Tan\", \"#FF897565\": \"Towering Cliffs\", \"#FFC3AA8C\": \"Townhall Tan\", \"#FFC19859\": \"Townhouse Tan\", \"#FFBBB09B\": \"Townhouse Taupe\", \"#FFCCFF11\": \"Toxic Boyfriend\", \"#FFCCEEBB\": \"Toxic Essence\", \"#FF61DE2A\": \"Toxic Green\", \"#FFE1F8E7\": \"Toxic Latte\", \"#FF43E85F\": \"Toxic Slime\", \"#FF00BB33\": \"Toxic Sludge\", \"#FFC1FDC9\": \"Toxic Steam\", \"#FF00889F\": \"Toy Blue\", \"#FF117700\": \"Toy Camouflage\", \"#FF776EA2\": \"Toy Mauve\", \"#FF005280\": \"Toy Submarine Blue\", \"#FF6D6F4F\": \"Toy Tank Green\", \"#FFDBB9A0\": \"Tracery\", \"#FFD66352\": \"Track and Field\", \"#FF849E88\": \"Track Green\", \"#FF00BFFE\": \"Tractor Beam\", \"#FF1C6A51\": \"Tractor Green\", \"#FFFD0F35\": \"Tractor Red\", \"#FF6A7978\": \"Trade Secret\", \"#FFB7C5C6\": \"Trade Winds\", \"#FFBB8D3B\": \"Trading Post\", \"#FF776255\": \"Traditional\", \"#FF1F648D\": \"Traditional Blue\", \"#FFC7C7C1\": \"Traditional Grey\", \"#FF6F4F3E\": \"Traditional Leather\", \"#FFBE013C\": \"Traditional Rose\", \"#FF0504AA\": \"Traditional Royal Blue\", \"#FFD6D2C0\": \"Traditional Tan\", \"#FF55FF22\": \"Traffic Green\", \"#FF8C9900\": \"Traffic Light Green\", \"#FFFF1C1C\": \"Traffic Red\", \"#FFF1F0EA\": \"Traffic White\", \"#FFFEDC39\": \"Traffic Yellow\", \"#FF927383\": \"Tragic Juliet\", \"#FFD0C4AC\": \"Trail Dust\", \"#FF6B6662\": \"Trail Print\", \"#FFC0B28E\": \"Trailblazer\", \"#FF776C61\": \"Trailhead\", \"#FFCFD5A7\": \"Trailing Vine\", \"#FF8F97A5\": \"Trance\", \"#FFDDEDE9\": \"Tranquil Variant\", \"#FF7C9AA0\": \"Tranquil Aqua\", \"#FF74B8DE\": \"Tranquil Bay\", \"#FFD3B2C3\": \"Tranquil Dusk\", \"#FFECE7F2\": \"Tranquil Eve\", \"#FFA4AF9E\": \"Tranquil Green\", \"#FFFCE2D7\": \"Tranquil Peach\", \"#FF768294\": \"Tranquil Pond\", \"#FF88DDFF\": \"Tranquil Pool\", \"#FFDBD2CF\": \"Tranquil Retreat\", \"#FFD2D2DF\": \"Tranquil Sea\", \"#FF629091\": \"Tranquil Seashore\", \"#FFB0A596\": \"Tranquil Taupe\", \"#FF8AC7BB\": \"Tranquil Teal\", \"#FF6C9DA9\": \"Tranquili Teal\", \"#FF8E9B96\": \"Tranquillity\", \"#FF307D67\": \"Trans Tasman\", \"#FFC3AC98\": \"Transcend\", \"#FFF8F4D8\": \"Transcendence\", \"#FFA5ACB7\": \"Transformer\", \"#FFEA1833\": \"Transfusion\", \"#FFFFE9E1\": \"Translucent Silk\", \"#FFFFEDEF\": \"Translucent Unicorn\", \"#FFE5EFD7\": \"Translucent Vision\", \"#FFE4E3E9\": \"Translucent White\", \"#FFF4ECC2\": \"Transparent Beige\", \"#FFDDDDFF\": \"Transparent Blue\", \"#FFDDFFDD\": \"Transparent Green\", \"#FFB4A6BF\": \"Transparent Mauve\", \"#FFFFAA66\": \"Transparent Orange\", \"#FFFFDDEE\": \"Transparent Pink\", \"#FFCBDCCB\": \"Transparent White\", \"#FFFFEEAA\": \"Transparent Yellow\", \"#FF004F54\": \"Transporter Green\", \"#FF0E1D32\": \"Trapped Darkness\", \"#FF005239\": \"Trapper Green\", \"#FFF4E8B6\": \"Trapunto\", \"#FFE2DDC7\": \"Travertine Variant\", \"#FFB5AB8F\": \"Travertine Path\", \"#FFDDF5E7\": \"Treacherous Blizzard\", \"#FF885D2D\": \"Treacle\", \"#FFDE9832\": \"Treacle Fudge\", \"#FF9B7856\": \"Treasure Casket\", \"#FF998866\": \"Treasure Chamber\", \"#FF726854\": \"Treasure Chest\", \"#FF47493B\": \"Treasure Island\", \"#FF609D91\": \"Treasure Isle\", \"#FFD0BB9D\": \"Treasure Map\", \"#FF658FAA\": \"Treasure Map Waters\", \"#FF3F363D\": \"Treasure Seeker\", \"#FF9C7947\": \"Treasured\", \"#FFBB2277\": \"Treasured Love\", \"#FF52C1B3\": \"Treasured Teal\", \"#FF006633\": \"Treasured Wilderness\", \"#FFBA8B36\": \"Treasures\", \"#FFDBD186\": \"Treasury\", \"#FF715E58\": \"Tree Bark\", \"#FF665B4E\": \"Tree Bark Brown\", \"#FF304B4A\": \"Tree Bark Green\", \"#FF8A7362\": \"Tree Branch\", \"#FF7FB489\": \"Tree Fern\", \"#FF9FB32E\": \"Tree Frog\", \"#FF7CA14E\": \"Tree Frog Green\", \"#FF2A7E19\": \"Tree Green\", \"#FF79774A\": \"Tree Hugger\", \"#FFC3DB8D\": \"Tree Line\", \"#FFDCDBCA\": \"Tree Moss\", \"#FF595D45\": \"Tree of Life\", \"#FFA4345D\": \"Tree Peony\", \"#FFE2813B\": \"Tree Poppy Variant\", \"#FFBDC7BC\": \"Tree Pose\", \"#FF22CC00\": \"Tree Python\", \"#FFCC7711\": \"Tree Sap\", \"#FF476A30\": \"Tree Shade\", \"#FF726144\": \"Tree Swing\", \"#FFD1B7A7\": \"Treeless\", \"#FF609F6E\": \"Treelet\", \"#FF91B6AC\": \"Treetop\", \"#FF2F4A15\": \"Treetop Cathedral\", \"#FF47562F\": \"Trefoil\", \"#FFD1AE9A\": \"Trek Tan\", \"#FF4E606D\": \"Trekking Blue\", \"#FF3D5C54\": \"Trekking Green\", \"#FFEAEFE5\": \"Trellis\", \"#FF7F753C\": \"Trellis Climber\", \"#FF5D7F74\": \"Trellis Vine\", \"#FF9AA097\": \"Trellised Ivy\", \"#FFAF9770\": \"Trench\", \"#FF7E8424\": \"Trendy Green Variant\", \"#FF805D80\": \"Trendy Pink Variant\", \"#FFA82F2E\": \"Tr\\u00e8s Bien\", \"#FFDCC7AD\": \"Tres Naturale\", \"#FFC2DFE2\": \"Trevi Fountain\", \"#FFF2D1C4\": \"Tri-Tip\", \"#FF94A089\": \"Triamble\", \"#FF67422D\": \"Triassic\", \"#FF807943\": \"Tribal\", \"#FF514843\": \"Tribal Drum\", \"#FFA78876\": \"Tribal Pottery\", \"#FFA4918D\": \"Tribeca\", \"#FF33373B\": \"Tribecca Corner\", \"#FF74B8DA\": \"Tribute\", \"#FFEAB38A\": \"Trick or Treat\", \"#FF2F2F30\": \"Tricorn Black\", \"#FFDCD3E3\": \"Tricot Lilac White\", \"#FFB09994\": \"Tricycle Taupe\", \"#FF494F62\": \"Tried & True Blue\", \"#FFF5F5DA\": \"Triforce Shine\", \"#FFF0F00F\": \"Triforce Yellow\", \"#FFA89896\": \"Trillium\", \"#FF756D44\": \"Trim\", \"#FFC54F33\": \"Trinidad Variant\", \"#FFD0343D\": \"Trinidad Moruga Scorpion\", \"#FFB9B79B\": \"Trinity Islands\", \"#FFD69835\": \"Trinket\", \"#FFA7885F\": \"Trinket Gold\", \"#FFC96272\": \"Triple Berry\", \"#FFE5E3E5\": \"Tripoli White\", \"#FFCC00EE\": \"Trippy Velvet\", \"#FF8EB9C4\": \"Trisha\\u2019s Eyes\", \"#FF0C0C1F\": \"Tristesse\", \"#FFF4F0E3\": \"Trite White\", \"#FF705676\": \"Trixter\", \"#FF775020\": \"Trojan Horse Brown\", \"#FF014E2E\": \"Troll Green\", \"#FFF4A34C\": \"Troll Slayer Orange\", \"#FFAE5F51\": \"Trolley Dash\", \"#FF818181\": \"Trolley Grey\", \"#FF708386\": \"Trooper\", \"#FF73B7C2\": \"Tropez Blue\", \"#FF4889AC\": \"Tropic\", \"#FFBCC23C\": \"Tropic Canary\", \"#FF016F92\": \"Tropic Sea\", \"#FF6CC1BB\": \"Tropic Tide\", \"#FF6AB5A4\": \"Tropic Turquoise\", \"#FFA8E8CB\": \"Tropical\", \"#FF9DB7AF\": \"Tropical Bay\", \"#FFD7967E\": \"Tropical Blooms\", \"#FFAEC9EB\": \"Tropical Blue Variant\", \"#FFEBEDEE\": \"Tropical Breeze\", \"#FF8CA8A0\": \"Tropical Cascade\", \"#FFB9CABD\": \"Tropical Cyclone\", \"#FFD9EAE5\": \"Tropical Dream\", \"#FF33FF22\": \"Tropical Elements\", \"#FF4DBBAF\": \"Tropical Escape\", \"#FF3E6252\": \"Tropical Foliage\", \"#FF024A43\": \"Tropical Forest\", \"#FF228B21\": \"Tropical Forest Green\", \"#FF99DDCC\": \"Tropical Freeze\", \"#FFFDD3A7\": \"Tropical Fruit\", \"#FF55DD00\": \"Tropical Funk\", \"#FF17806D\": \"Tropical Green\", \"#FFC2343C\": \"Tropical Heat\", \"#FF9C6071\": \"Tropical Hibiscus\", \"#FF17A99E\": \"Tropical Hideaway\", \"#FF8FCDC7\": \"Tropical Holiday\", \"#FF009D7D\": \"Tropical Kelp\", \"#FF1E98AE\": \"Tropical Lagoon\", \"#FF9CD572\": \"Tropical Light\", \"#FFCAE8E8\": \"Tropical Mist\", \"#FFD2C478\": \"Tropical Moss\", \"#FF2A2E4C\": \"Tropical Night Blue\", \"#FF98523D\": \"Tropical Nut\", \"#FF579AA5\": \"Tropical Oasis\", \"#FFA0828A\": \"Tropical Orchid\", \"#FFF7A082\": \"Tropical Paradise\", \"#FFFFC4B2\": \"Tropical Peach\", \"#FFBFDEEF\": \"Tropical Pool\", \"#FF447777\": \"Tropical Rain\", \"#FF03A598\": \"Tropical Sea\", \"#FFDDC073\": \"Tropical Siesta\", \"#FF155D66\": \"Tropical Skies\", \"#FFC5556D\": \"Tropical Smoothie\", \"#FF70CBCE\": \"Tropical Splash\", \"#FFFBB719\": \"Tropical Sun\", \"#FFE0DEB8\": \"Tropical Tale\", \"#FFCBB391\": \"Tropical Tan\", \"#FF008794\": \"Tropical Teal\", \"#FF5ECAAE\": \"Tropical Tide\", \"#FF50A074\": \"Tropical Tone\", \"#FF89D1B5\": \"Tropical Trail\", \"#FF20AEA7\": \"Tropical Tree\", \"#FF04CDFF\": \"Tropical Turquoise\", \"#FF837946\": \"Tropical Twist\", \"#FFCDA5DF\": \"Tropical Violet\", \"#FFBEE7E2\": \"Tropical Waterfall\", \"#FF007C7E\": \"Tropical Waters\", \"#FFBA8F68\": \"Tropical Wood\", \"#FF603B2A\": \"Tropical Wood Brown\", \"#FF447700\": \"Tropicana\", \"#FF009B8E\": \"Tropics\", \"#FF726D40\": \"Trough Shell\", \"#FF918754\": \"Trough Shell Brown\", \"#FF00666D\": \"Trouser Blue\", \"#FF4C5356\": \"Trout Variant\", \"#FFF75300\": \"Trout Caviar\", \"#FFCB7077\": \"Trout Pout\", \"#FFDCC49B\": \"True Blonde\", \"#FF010FCC\": \"True Blue Variant\", \"#FF8B5643\": \"True Copper\", \"#FFA22042\": \"True Crimson\", \"#FF089404\": \"True Green\", \"#FFB8AE98\": \"True Khaki\", \"#FF7E89C8\": \"True Lavender\", \"#FFE27E8A\": \"True Love\", \"#FF465784\": \"True Navy\", \"#FF65318E\": \"True Purple\", \"#FFC81A3A\": \"True Red\", \"#FF4D456A\": \"True Romance\", \"#FF24A6C2\": \"True Sky Blue\", \"#FFA8A095\": \"True Taupewood\", \"#FF0A8391\": \"True Teal\", \"#FFCDD3A3\": \"True\", \"#FF8E72C7\": \"True V Variant\", \"#FF967A67\": \"True Walnut\", \"#FFB46C42\": \"Truepenny\", \"#FF99BBFF\": \"Truesky Gloxym\", \"#FFC2A78E\": \"Truffle\", \"#FFA35139\": \"Truffle Trouble\", \"#FF777250\": \"Truly Olive\", \"#FFAC9E97\": \"Truly Taupe\", \"#FFFAA76C\": \"Trump Tan\", \"#FFD1B669\": \"Trumpet\", \"#FFE49977\": \"Trumpet Flower\", \"#FFE9B413\": \"Trumpet Gold\", \"#FF5A7D7A\": \"Trumpet Teal\", \"#FF907BAA\": \"Trumpeter\", \"#FF9B5FC0\": \"Trunks Hair\", \"#FF527498\": \"Trustee\", \"#FFB59F8F\": \"Trusty Tan\", \"#FF344989\": \"Truth\", \"#FF34B334\": \"Try Your Luck\", \"#FF8B7F7B\": \"Tsar\", \"#FFD1B4C6\": \"Tsarina\", \"#FF869BAF\": \"Tsunami\", \"#FFCFD4D3\": \"Tsunami Sky\", \"#FF9BA88D\": \"Tsurubami Green\", \"#FF574D35\": \"T\\u01d4 H\\u0113i Black\", \"#FF454642\": \"Tuatara Variant\", \"#FF0E8787\": \"Tubbataha Teal\", \"#FFFFFAEC\": \"Tuberose\", \"#FF00858B\": \"Tucson Teal\", \"#FF5F572B\": \"Tucum\\u00e1n Green\", \"#FFC1CECF\": \"Tudor Ice\", \"#FFB68960\": \"Tudor Tan\", \"#FFA59788\": \"Tuffet\", \"#FFCBC2AD\": \"Tuft\", \"#FFF9D3BE\": \"Tuft Bush Variant\", \"#FFB96C46\": \"Tufted Leather\", \"#FFCCDDEE\": \"Tu\\u011f\\u00e7e Silver\", \"#FFB89CBC\": \"Tuileries Tint\", \"#FF573B2A\": \"Tuk Tuk\", \"#FFFF878D\": \"Tulip\", \"#FFFBF4DA\": \"Tulip Petals\", \"#FF531938\": \"Tulip Poplar Purple\", \"#FFB8516A\": \"Tulip Red\", \"#FFC3C4D6\": \"Tulip Soft Blue\", \"#FFE3AC3D\": \"Tulip Tree Variant\", \"#FFF1E5D1\": \"Tulip White\", \"#FF966993\": \"Tulipan Violet\", \"#FF86586A\": \"Tulipwood\", \"#FFF1BA91\": \"Tulle\", \"#FF8D9098\": \"Tulle Grey\", \"#FFD9E7E5\": \"Tulle Soft Blue\", \"#FFFBEDE5\": \"Tulle White\", \"#FFCDBB9C\": \"Tumblin\\u2019 Tumbleweed\", \"#FFCEBF9C\": \"Tumbling Tumbleweed\", \"#FF46494E\": \"Tuna Variant\", \"#FFCF6275\": \"Tuna Sashimi\", \"#FF585452\": \"Tundora Variant\", \"#FFD6D9D7\": \"Tundra\", \"#FFE1E1DB\": \"Tundra Frost\", \"#FFB5AC9F\": \"Tungsten\", \"#FF00CC00\": \"Tunic Green\", \"#FFFFDDB5\": \"Tunisian Stone\", \"#FFC0A04D\": \"Tupelo Honey\", \"#FF9C9152\": \"Tupelo Tree\", \"#FFF9BB59\": \"Turbinado Sugar\", \"#FF555C63\": \"Turbulence\", \"#FF536A79\": \"Turbulent Sea\", \"#FF415B36\": \"Turf\", \"#FF2A8948\": \"Turf Green\", \"#FF009922\": \"Turf Master\", \"#FF738050\": \"Turf War\", \"#FF006169\": \"Turkish Aqua\", \"#FFBB937B\": \"Turkish Bath\", \"#FF007FAE\": \"Turkish Blue\", \"#FF0E9CA5\": \"Turkish Boy\", \"#FF483F39\": \"Turkish Coffee\", \"#FFF7F3BD\": \"Turkish Ginger\", \"#FF2B888D\": \"Turkish Jade\", \"#FFA56E75\": \"Turkish Rose Variant\", \"#FF194F90\": \"Turkish Sea\", \"#FF2F7A92\": \"Turkish Stone\", \"#FF72CAC1\": \"Turkish Teal\", \"#FF007E9F\": \"Turkish Tile\", \"#FFD9D9D1\": \"Turkish Tower\", \"#FF77DDE7\": \"Turkish Turquoise\", \"#FFF3D8BE\": \"Turkscap\", \"#FFAE9041\": \"Turmeric Variant\", \"#FFC18116\": \"Turmeric Brown\", \"#FFCA7A40\": \"Turmeric Red\", \"#FFFEAE0D\": \"Turmeric Root\", \"#FFD88E2D\": \"Turmeric Tea\", \"#FF8D7448\": \"Turned Leaf\", \"#FF93BCBB\": \"Turner\\u2019s Light\", \"#FFE6C26F\": \"Turner\\u2019s Yellow\", \"#FFCED9C3\": \"Turning Leaf\", \"#FFEDE1A8\": \"Turning Oakleaf\", \"#FFB9AAA1\": \"Turning Tables\", \"#FFEFC6A1\": \"Turnip Boy\", \"#FFBB9ECD\": \"Turnip Crown\", \"#FFE5717B\": \"Turnip the Pink\", \"#FFD3CFBF\": \"Turnstone\", \"#FF448899\": \"Turquesa\", \"#FF01A192\": \"Turquish\", \"#FF06C2AC\": \"Turquoise Tint\", \"#FF6FE7DB\": \"Turquoise Chalk\", \"#FF0E7C61\": \"Turquoise Cyan\", \"#FF6DAFA7\": \"Turquoise Fantasies\", \"#FF04F489\": \"Turquoise Green Variant\", \"#FFB4CECF\": \"Turquoise Grey\", \"#FF89F5E3\": \"Turquoise Pearl\", \"#FF00C5CD\": \"Turquoise Surf\", \"#FF13BBAF\": \"Turquoise Topaz\", \"#FF457B74\": \"Turquoise Tortoise\", \"#FFA8E3CC\": \"Turquoise Tower\", \"#FF73D4C2\": \"Turquoise Twist\", \"#FFCFE9DC\": \"Turquoise White\", \"#FF523F31\": \"Turtle\", \"#FF84897F\": \"Turtle Bay\", \"#FFCED8C1\": \"Turtle Chalk\", \"#FF65926D\": \"Turtle Creek\", \"#FF75B84F\": \"Turtle Green Variant\", \"#FF73B7A5\": \"Turtle Lake\", \"#FF939717\": \"Turtle Moss\", \"#FF897C64\": \"Turtle Shell\", \"#FF363E1D\": \"Turtle Skin\", \"#FFB6B5A0\": \"Turtle Trail\", \"#FF35B76D\": \"Turtle Warrior\", \"#FFD6CEBB\": \"Turtledove\", \"#FFFBD5A6\": \"Tuscan\", \"#FFE7D2AD\": \"Tuscan Bread\", \"#FF6F4C37\": \"Tuscan Brown\", \"#FFAA5E5A\": \"Tuscan Clay\", \"#FF658362\": \"Tuscan Herbs\", \"#FF746E38\": \"Tuscan Hills\", \"#FFDC938C\": \"Tuscan Image\", \"#FFA08D71\": \"Tuscan Mosaic\", \"#FF5D583E\": \"Tuscan Olive\", \"#FF9C6350\": \"Tuscan Rooftops\", \"#FF723D3B\": \"Tuscan Russet\", \"#FFFFD84D\": \"Tuscan Sun\", \"#FFBB7C3F\": \"Tuscan Sunset\", \"#FFFCC492\": \"Tuscan Wall\", \"#FF008893\": \"Tuscana Blue\", \"#FFB98C7B\": \"Tuscany Tint\", \"#FF7E875F\": \"Tuscany Hillside\", \"#FF0082AD\": \"Tusche Blue\", \"#FF9996B3\": \"Tusi Grey\", \"#FFE3E5B1\": \"Tusk Variant\", \"#FF883636\": \"Tuskgor Fur\", \"#FFEDC5D7\": \"Tussie-Mussie\", \"#FFBF914B\": \"Tussock Variant\", \"#FFBC587B\": \"Tutti Frutti\", \"#FFF8E4E3\": \"Tutu Variant\", \"#FFE95295\": \"Tutuji Pink\", \"#FF3F3C43\": \"Tuxedo\", \"#FF937B56\": \"Tweed\", \"#FFCCB586\": \"Tweed Jacket\", \"#FF8F7B5B\": \"Tweedy\", \"#FFFFBE4C\": \"Twenty Carat\", \"#FFCA999E\": \"Twice Shy\", \"#FF77623A\": \"Twig Basket\", \"#FF4E518B\": \"Twilight Variant\", \"#FFC8BFB5\": \"Twilight Beige\", \"#FFCFB4C2\": \"Twilight Bloom\", \"#FF0A437A\": \"Twilight Blue Variant\", \"#FFB59A9C\": \"Twilight Blush\", \"#FF3F5363\": \"Twilight Chimes\", \"#FF606079\": \"Twilight Dusk\", \"#FF1C3378\": \"Twilight Express\", \"#FF54574F\": \"Twilight Forest\", \"#FFD1D6D6\": \"Twilight Grey\", \"#FF7E664B\": \"Twilight Jungle\", \"#FFDAC0CD\": \"Twilight Light\", \"#FF977D7F\": \"Twilight Mauve\", \"#FF51A5A4\": \"Twilight Meadow\", \"#FFBDC9E4\": \"Twilight Mist\", \"#FFBFBCD2\": \"Twilight Pearl\", \"#FF65648B\": \"Twilight Purple\", \"#FF71898D\": \"Twilight Stroll\", \"#FFA79994\": \"Twilight Taupe\", \"#FF7B85C6\": \"Twilight Twinkle\", \"#FFE5E6D7\": \"Twilight Twist\", \"#FF191916\": \"Twilight Zone\", \"#FFA3957C\": \"Twill\", \"#FFBEDBED\": \"Twin Blue\", \"#FFA4C7C8\": \"Twin Cities\", \"#FF684344\": \"Twinberry\", \"#FFC19156\": \"Twine Variant\", \"#FF74A69B\": \"Twining Vine\", \"#FFADC6D3\": \"Twinkle\", \"#FFD0D7DF\": \"Twinkle Blue\", \"#FFFCE79A\": \"Twinkle Little Star\", \"#FF636CA8\": \"Twinkle Night\", \"#FFFBD8CC\": \"Twinkle Pink\", \"#FFE2D39B\": \"Twinkle Toes\", \"#FFFCF0C5\": \"Twinkle Twinkle\", \"#FFE9DBE4\": \"Twinkled Pink\", \"#FFFFFAC1\": \"Twinkling Lights\", \"#FFCF4796\": \"Twinkly Pinkily\", \"#FF76C4D1\": \"Twisted Blue\", \"#FF9A845E\": \"Twisted Tail\", \"#FF7F6C6E\": \"Twisted Time\", \"#FF655F50\": \"Twisted Vine\", \"#FF854A2E\": \"Two Cents\", \"#FFBED3E1\": \"Two Harbours\", \"#FFA5CA4F\": \"Two Peas in a Pod\", \"#FF4C5053\": \"Typewriter Ink\", \"#FF463D2B\": \"Typhus Corrosion\", \"#FFCDC586\": \"Tyrant Skull\", \"#FF4E4D59\": \"Tyrian\", \"#FF9448B0\": \"Tyrian Shimmer\", \"#FFB3CDBF\": \"Tyrol\", \"#FF00A499\": \"Tyrolite Blue-Green\", \"#FF736458\": \"Tyson Taupe\", \"#FFDDEECC\": \"Tzatziki Green\", \"#FF7B5838\": \"\\u00dcber Umber\", \"#FF989FA3\": \"UFO\", \"#FF88AA11\": \"UFO Defense Green\", \"#FF645530\": \"Uguisu Brown\", \"#FF928C36\": \"Uguisu Green\", \"#FFFABF14\": \"Ukon Saffron\", \"#FFFCC680\": \"Uldum Beige\", \"#FFC7E0D9\": \"Ulthuan Grey\", \"#FFA9A8A9\": \"Ultimate Grey\", \"#FFFF4200\": \"Ultimate Orange\", \"#FFFF55FF\": \"Ultimate Pink\", \"#FF7EBA4D\": \"Ultra Green\", \"#FF4433FF\": \"Ultra Indigo\", \"#FFA3EFB8\": \"Ultra Mint\", \"#FFD1F358\": \"Ultra Moss\", \"#FFF06FFF\": \"Ultra Pink\", \"#FFF8F8F3\": \"Ultra Pure White\", \"#FF7366BD\": \"Ultra Violet\", \"#FFAA22AA\": \"Ultra Violet Lentz\", \"#FFF6F6F0\": \"Ultra White\", \"#FF770088\": \"Ultraberry\", \"#FF1805DB\": \"Ultramarine Variant\", \"#FF657ABB\": \"Ultramarine Blue Variant\", \"#FF007A64\": \"Ultramarine Green\", \"#FF2E328F\": \"Ultramarine Highlight\", \"#FF090045\": \"Ultramarine Shadow\", \"#FF1D2A58\": \"Ultramarine Violet\", \"#FF654EA3\": \"Ultrapurple Merge\", \"#FFBB44CC\": \"Ultraviolet Berl\", \"#FFBB44BB\": \"Ultraviolet Cryner\", \"#FFBB44AA\": \"Ultraviolet Nusp\", \"#FFBB44DD\": \"Ultraviolet Onsible\", \"#FF921D0F\": \"Uluru Red\", \"#FF704336\": \"Uluru Sunset\", \"#FFB26400\": \"Umber Variant\", \"#FF613936\": \"Umber Brown\", \"#FF765138\": \"Umber Rust\", \"#FF4E4D2F\": \"Umber Shade Wash\", \"#FFECE7DD\": \"Umber Style\", \"#FF211E1F\": \"Umbra\", \"#FF87706B\": \"Umbra Sand\", \"#FF520200\": \"Umbral Umber\", \"#FFA2AF70\": \"Umbrella Green\", \"#FFB54753\": \"Umbria Red\", \"#FF8F4155\": \"Umemurasaki Purple\", \"#FF97645A\": \"Umenezumi Plum\", \"#FFFA9258\": \"Umezome Pink\", \"#FF75A14F\": \"Unakite\", \"#FFFBFAF5\": \"Unbleached\", \"#FFF5D8BB\": \"Unbleached Calico\", \"#FFFBE7E6\": \"Unburdened Pink\", \"#FFA9B0B1\": \"Uncertain Grey\", \"#FF19565E\": \"Uncharted\", \"#FFC7AB90\": \"Uncommon Coir\", \"#FF476E42\": \"Under the Radar\", \"#FF395D68\": \"Under the Sea\", \"#FFEFD100\": \"Under the Sun\", \"#FFBE9E48\": \"Underbrush\", \"#FF428C49\": \"Underclover\", \"#FFA38479\": \"Undercooked Bacon\", \"#FF7FC3E1\": \"Undercool\", \"#FF665A51\": \"Underground\", \"#FF524B4C\": \"Underground Civilization\", \"#FF87968B\": \"Underground Gardens\", \"#FF120A65\": \"Underground Stream\", \"#FFB2AC88\": \"Underhive Ash\", \"#FFCC4422\": \"Underpass Shrine\", \"#FF90B1AE\": \"Undersea\", \"#FFD4C9BB\": \"Understated\", \"#FFC3C4AC\": \"Understory\", \"#FF779999\": \"Undertow\", \"#FFCFEEE8\": \"Underwater\", \"#FF0022BB\": \"Underwater Falling\", \"#FF06D078\": \"Underwater Fern\", \"#FFE78EA5\": \"Underwater Flare\", \"#FF4488AA\": \"Underwater Moonlight\", \"#FF243062\": \"Underwater Realm\", \"#FF657F7A\": \"Underwater World\", \"#FF1E231C\": \"Underworld\", \"#FF89C1BA\": \"Undine\", \"#FF69667C\": \"Unexplained\", \"#FFE7D8DE\": \"Unfading Dusk\", \"#FF986962\": \"Unfired Clay\", \"#FFDDCCB1\": \"Unforgettable\", \"#FFAE8245\": \"Unforgettably Gold\", \"#FFD6C8C0\": \"Unfussy Beige\", \"#FFD6A766\": \"Ungor Beige\", \"#FFFF2F92\": \"Unicorn Dust\", \"#FFE8E8E8\": \"Unicorn Silver\", \"#FFA7B7CA\": \"Uniform\", \"#FF6E5D3E\": \"Uniform Brown\", \"#FF4C4623\": \"Uniform Green\", \"#FF5F7B7E\": \"Uniform Green Grey\", \"#FFA8A8A8\": \"Uniform Grey\", \"#FF8C7EB9\": \"Unimaginable\", \"#FFB5D1C7\": \"Uninhibited\", \"#FF9C9680\": \"Union Springs\", \"#FFC7C5BA\": \"Union Station\", \"#FFCBC9C9\": \"Unique Grey\", \"#FF264D8E\": \"Unity\", \"#FF006B38\": \"Universal Green\", \"#FFB8A992\": \"Universal Khaki\", \"#FF9C8168\": \"Universal Umber\", \"#FFB78727\": \"University of California Gold\", \"#FFF77F00\": \"University of Tennessee Orange\", \"#FFD2CAB7\": \"Unmarked Trail\", \"#FFB12D35\": \"Unmatched Beauty\", \"#FFFEFE66\": \"Unmellow Yellow\", \"#FF4B4840\": \"Unplugged\", \"#FF7B746B\": \"Unpredictable Hue\", \"#FF5C6E70\": \"Unreal Teal\", \"#FFF0FF57\": \"Unripe Banana\", \"#FFB1BEA8\": \"Unroasted Coffee\", \"#FFDE5730\": \"Untamed Orange\", \"#FFDD0022\": \"Untamed Red\", \"#FFA3A7A0\": \"Unusual Grey\", \"#FFF2F8ED\": \"Unwind\", \"#FF014431\": \"UP Forest Green\", \"#FF6E706D\": \"Up in Smoke\", \"#FFC2D5D8\": \"Up in the Air\", \"#FF6F9587\": \"Up North\", \"#FFF1D9A5\": \"Upbeat\", \"#FFEB9724\": \"Uplifting Yellow\", \"#FFA3758B\": \"Upper Crust\", \"#FF8D6051\": \"Upper East Side\", \"#FFEE1100\": \"Uproar Red\", \"#FFA8ADC2\": \"Upscale\", \"#FFB52923\": \"Upset Tomato\", \"#FFCAC7B8\": \"Upstate\", \"#FFFFA8A6\": \"Upstream Salmon\", \"#FFA791A8\": \"Uptown Girl\", \"#FFF1E4D7\": \"Uptown Taupe\", \"#FFBDC9D2\": \"Upward\", \"#FFBCB58C\": \"Urahayanagi Green\", \"#FF93B778\": \"Uran Mica\", \"#FF7C4A2C\": \"Urban Auburn\", \"#FFDDD4C5\": \"Urban Bird\", \"#FFAEA28C\": \"Urban Charm\", \"#FF424C4A\": \"Urban Chic\", \"#FF89776E\": \"Urban Exploration\", \"#FF7C7466\": \"Urban Garden\", \"#FF005042\": \"Urban Green\", \"#FFCACACC\": \"Urban Grey\", \"#FFA4947E\": \"Urban Jungle\", \"#FF67585F\": \"Urban Legend\", \"#FFD3DBD9\": \"Urban Mist\", \"#FF374F54\": \"Urban Oasis\", \"#FFB0B1A9\": \"Urban Putty\", \"#FFBDCBCA\": \"Urban Raincoat\", \"#FF978B6E\": \"Urban Safari\", \"#FFDBD8DA\": \"Urban Snowfall\", \"#FFBDBEBA\": \"Urban Sunrise\", \"#FFC9BDB6\": \"Urban Taupe\", \"#FF8899AA\": \"Urban Vibes\", \"#FF696447\": \"Urbane\", \"#FF54504A\": \"Urbane Bronze\", \"#FF4D5659\": \"Urbanite\", \"#FFFFD72E\": \"Uri Yellow\", \"#FFFFECC2\": \"Urnebes Beige\", \"#FF00308F\": \"US Air Force Blue\", \"#FF716140\": \"US Field Drab\", \"#FF990010\": \"USC Cardinal\", \"#FF231712\": \"Used Oil\", \"#FFCFCABD\": \"Useful Beige\", \"#FFBBBB7F\": \"Ushabti Bone\", \"#FF373D31\": \"USMC Green\", \"#FFE597B2\": \"Usu Koubai Blossom\", \"#FFA87CA0\": \"Usu Pink\", \"#FF8C9C76\": \"Usuao Blue\", \"#FFF2666C\": \"Usubeni Red\", \"#FFFCA474\": \"Usugaki Persimmon\", \"#FFFEA464\": \"Usuk\\u014d\", \"#FF8DB255\": \"Usumoegi Green\", \"#FFA58F7B\": \"Utaupeia\", \"#FF32B6C7\": \"Utopia Beckons\", \"#FFB5A597\": \"Utterly Beige\", \"#FFA8C6DE\": \"Utterly Blue\", \"#FFF5C8D8\": \"Utterly Pink\", \"#FF0098C8\": \"UV Light\", \"#FFEFD5CF\": \"Va Va Bloom\", \"#FFE3B34C\": \"Va Va Voom\", \"#FFD1D991\": \"Vacation Island\", \"#FFFDE882\": \"Vacherin Cheese\", \"#FFAA8877\": \"Vagabond\", \"#FFD1C5C4\": \"Vaguely Mauve\", \"#FFDBE1EF\": \"Vaguely Violet\", \"#FFD4574E\": \"Valencia Variant\", \"#FF837048\": \"Valencia Moss\", \"#FFA53A4E\": \"Valentine\", \"#FFBA789E\": \"Valentine Heart\", \"#FFBA0728\": \"Valentine Lava\", \"#FF9B233B\": \"Valentine Red\", \"#FFA63864\": \"Valentine\\u2019s Day\", \"#FFB63364\": \"Valentine\\u2019s Kiss\", \"#FFB64476\": \"Valentino Variant\", \"#FF382C38\": \"Valentino Nero\", \"#FF9F7A93\": \"Valerian\", \"#FFFDE6E7\": \"Valerie\", \"#FF2A2B41\": \"Valhalla Variant\", \"#FFF2EDE7\": \"Valhallan Blizzard\", \"#FFBC3C2C\": \"Valiant Poppy\", \"#FF3E4371\": \"Valiant Violet\", \"#FF80502B\": \"Valise\", \"#FFEECC22\": \"Valkyrie\", \"#FF35709D\": \"Vallarta Blue\", \"#FF848D85\": \"Valley Floor\", \"#FFFFDD9D\": \"Valley Flower\", \"#FF848A83\": \"Valley Hills\", \"#FFC9D5CB\": \"Valley Mist\", \"#FFFF8A4A\": \"Valley of Fire\", \"#FF2D7E96\": \"Valley of Glaciers\", \"#FFD1E1E4\": \"Valley of Tears\", \"#FFB0C376\": \"Valley View\", \"#FF8A763D\": \"Valley Vineyards\", \"#FF79C9D1\": \"Valonia\", \"#FFA3BCDB\": \"Valour\", \"#FFCC2255\": \"Vampire Fangs\", \"#FF9B0F11\": \"Vampire Fiction\", \"#FF610507\": \"Vampire Hunter\", \"#FFDD0077\": \"Vampire Love Story\", \"#FFDD4132\": \"Vampire Red\", \"#FFCC1100\": \"Vampire State Building\", \"#FF9B2848\": \"Vampirella\", \"#FFCC0066\": \"Vampiric Bloodlust\", \"#FF5C0C0C\": \"Vampiric Council\", \"#FFBFB6AA\": \"Vampiric Shadow\", \"#FF523936\": \"Van Cleef Variant\", \"#FFFAF7EB\": \"Van de Cane\", \"#FFABDDF1\": \"Van Gogh Blue\", \"#FF65CE95\": \"Van Gogh Green\", \"#FF759465\": \"Van Gogh Olives\", \"#FF00A3E0\": \"Vanadyl Blue\", \"#FFD8CBB3\": \"Vanderbilt Beach\", \"#FFABDEE4\": \"Vandermint\", \"#FF7B5349\": \"Vandyck Brown\", \"#FF362C1D\": \"Vanilla Bean Brown\", \"#FFFCEDE4\": \"Vanilla Blush\", \"#FFFCF0CA\": \"Vanilla Cake\", \"#FFF8E3AB\": \"Vanilla Cream\", \"#FFF3E0BE\": \"Vanilla Custard\", \"#FFF5E8D5\": \"Vanilla Delight\", \"#FFFFFFEB\": \"Vanilla Drop\", \"#FFE9DFCF\": \"Vanilla Flower\", \"#FFFFD2AB\": \"Vanilla Fran\\u00e7aise\", \"#FFFDE9C5\": \"Vanilla Frost\", \"#FFFDF2D1\": \"Vanilla Ice Variant\", \"#FFFFE6B3\": \"Vanilla Ice Cream\", \"#FFC9DAE2\": \"Vanilla Ice Smoke\", \"#FFDAC2AA\": \"Vanilla Iced Coffee\", \"#FFE6E0CC\": \"Vanilla Love\", \"#FFF1ECE2\": \"Vanilla Milkshake\", \"#FFEBDBC8\": \"Vanilla Mocha\", \"#FFF3E7D3\": \"Vanilla Paste\", \"#FFFAF3DD\": \"Vanilla Powder\", \"#FFF7E26B\": \"Vanilla Pudding\", \"#FFCBC8C2\": \"Vanilla Quake\", \"#FFCCB69B\": \"Vanilla Seed\", \"#FFFFFBF0\": \"Vanilla Shake\", \"#FFDED5CC\": \"Vanilla Steam\", \"#FFFFE6E7\": \"Vanilla Strawberry\", \"#FFF1E8DC\": \"Vanilla Sugar\", \"#FFF1E9DD\": \"Vanilla Tan\", \"#FFF3EAD2\": \"Vanilla Wafer\", \"#FFF6EEE5\": \"Vanilla White\", \"#FFF2E3CA\": \"Vanillin\", \"#FF331155\": \"Vanishing\", \"#FFCFDFEF\": \"Vanishing Blue\", \"#FF990088\": \"Vanishing Night\", \"#FFDDEEDD\": \"Vanishing Point\", \"#FF5692B2\": \"Vanity\", \"#FFE6CCDD\": \"Vanity Pink\", \"#FF000100\": \"Vantablack\", \"#FFE8E8D7\": \"Vape Smoke\", \"#FFCBF4F8\": \"Vaporised\", \"#FFD8D6CE\": \"Vaporous Grey\", \"#FFFF66EE\": \"Vaporwave\", \"#FF22DDFF\": \"Vaporwave Blue\", \"#FF99EEBB\": \"Vaporwave Pool\", \"#FFBEBDBD\": \"Vapour Blue\", \"#FFF5EEDF\": \"Vapour Trail\", \"#FF855F43\": \"Vaquero Boots\", \"#FFFDEFD3\": \"Varden Variant\", \"#FF747D5A\": \"Variegated Frond\", \"#FFE6DCCC\": \"Varnished Ivory\", \"#FFC9BDB8\": \"Vast\", \"#FFC2B197\": \"Vast Desert\", \"#FFD2C595\": \"Vast Escape\", \"#FFA9C9D7\": \"Vast Sky\", \"#FFAA55FF\": \"Vega Violet\", \"#FF22BB88\": \"Vegan\", \"#FF006C47\": \"Vegan Green\", \"#FF22BB55\": \"Vegan Mastermind\", \"#FFAA9911\": \"Vegan Villain\", \"#FF316738\": \"Vegas Green\", \"#FF26538D\": \"Vegeta Blue\", \"#FF8B8C40\": \"Vegetable Garden\", \"#FF22AA00\": \"Vegetarian\", \"#FF78945A\": \"Vegetarian Veteran\", \"#FFCCCC99\": \"Vegetarian Vulture\", \"#FF5CCD97\": \"Vegetation\", \"#FF4C433D\": \"Vehicle Body Grey\", \"#FF784F50\": \"Veil of Cinder\", \"#FFDAD8C9\": \"Veil of Dusk\", \"#FF80B690\": \"Veiled Chameleon\", \"#FFB2B0BD\": \"Veiled Delight\", \"#FFF9DFD7\": \"Veiled Pink\", \"#FFF7CDC8\": \"Veiled Rose\", \"#FFCFD5D7\": \"Veiled Spotlight\", \"#FFF6EDB6\": \"Veiled Treasure\", \"#FF5B5962\": \"Veiled Vinyl\", \"#FFB19BB0\": \"Veiled Violet\", \"#FFD4EAFF\": \"Veiling Waterfalls\", \"#FFA17D61\": \"Velddrif\", \"#FFEFE4D9\": \"Vellum Parchment\", \"#FFBAA7BF\": \"Velour\", \"#FF8E5164\": \"Velour Scar\", \"#FFD7D8C3\": \"Veltliner White\", \"#FFD6CEB9\": \"Velum Smoke\", \"#FF750851\": \"Velvet\", \"#FFD0C5B1\": \"Velvet Beige\", \"#FF5C466B\": \"Velvet Beret\", \"#FF241F20\": \"Velvet Black\", \"#FFE3D5D8\": \"Velvet Blush\", \"#FF9D253D\": \"Velvet Cake\", \"#FF623941\": \"Velvet Cape\", \"#FF656D63\": \"Velvet Clover\", \"#FF441144\": \"Velvet Cosmos\", \"#FF9291BC\": \"Velvet Crest\", \"#FFAA0066\": \"Velvet Cupcake\", \"#FF7E85A3\": \"Velvet Curtain\", \"#FFBDB0BC\": \"Velvet Dawn\", \"#FFC5ADB4\": \"Velvet Ears\", \"#FF33505E\": \"Velvet Evening\", \"#FFACAAB3\": \"Velvet Grey\", \"#FFD39ED2\": \"Velvet Horizon\", \"#FF96C193\": \"Velvet Leaf\", \"#FFBB1155\": \"Velvet Magic\", \"#FFE58D3F\": \"Velvet Marigold\", \"#FF692B57\": \"Velvet Mauve\", \"#FF6C769B\": \"Velvet Morning\", \"#FF6B1B2A\": \"Velvet Outbreak\", \"#FF573A56\": \"Velvet Plum\", \"#FF939DCC\": \"Velvet Robe\", \"#FF36526A\": \"Velvet Rope\", \"#FF7E374C\": \"Velvet Rose\", \"#FFE3DFEC\": \"Velvet Scarf\", \"#FFC5D3DD\": \"Velvet Sky\", \"#FF846C76\": \"Velvet Slipper\", \"#FF523544\": \"Velvet Touch\", \"#FF6B605A\": \"Velvet Umber\", \"#FFAB0102\": \"Velvet Volcano\", \"#FF540D6E\": \"Velvet Vortex\", \"#FF9A435D\": \"Velvet Wine\", \"#FF936064\": \"Velveteen Crush\", \"#FFA2877D\": \"Velvety Chestnut\", \"#FF794143\": \"Velvety Merlot\", \"#FFABC88C\": \"Venerable Verde\", \"#FFF7F5F3\": \"Venerable White\", \"#FF928083\": \"Venetian\", \"#FF9CB08A\": \"Venetian Glass\", \"#FFB39142\": \"Venetian Gold\", \"#FFF7EDDA\": \"Venetian Lace\", \"#FFE7CEB6\": \"Venetian Mask\", \"#FF7755FF\": \"Venetian Nights\", \"#FFD2EAD5\": \"Venetian Pearl\", \"#FFBB8E84\": \"Venetian Pink\", \"#FFE0A28D\": \"Venetian Plaster\", \"#FFEFC6E1\": \"Venetian Rose\", \"#FF949486\": \"Venetian Wall\", \"#FFF6E3A1\": \"Venetian Yellow\", \"#FF2C5778\": \"Venice Blue Variant\", \"#FF76AFB2\": \"Venice Escape\", \"#FF6BFFB3\": \"Venice Green\", \"#FFE6C591\": \"Venice Square\", \"#FFA9A52A\": \"Venom\", \"#FF01FF01\": \"Venom Dart\", \"#FF607038\": \"Venom Wyrm\", \"#FF66FF22\": \"Venomous Green\", \"#FFC6EC7A\": \"Venomous Sting\", \"#FF3F3033\": \"Venous Blood Red\", \"#FFCDE6E8\": \"Ventilated\", \"#FF7381B3\": \"Venture Violet\", \"#FFEED053\": \"Venus Variant\", \"#FF8F7974\": \"Venus Deva\", \"#FF9EA6CF\": \"Venus Flower\", \"#FF94B44C\": \"Venus Flytrap\", \"#FF5F606E\": \"Venus Mist\", \"#FFF0E5E5\": \"Venus Pink\", \"#FF85A4A2\": \"Venus Teal\", \"#FF7A6DC0\": \"Venus Violet\", \"#FF71384C\": \"Venusian\", \"#FF61A9A5\": \"Veranda\", \"#FF66B6B0\": \"Veranda Blue\", \"#FF9EB1AF\": \"Veranda Charm\", \"#FFAF9968\": \"Veranda Gold\", \"#FF8E977E\": \"Veranda Green\", \"#FFCCB994\": \"Veranda Hills\", \"#FF9DA4BE\": \"Veranda Iris\", \"#FFE4B773\": \"Veranda Yellow\", \"#FFF1DFDF\": \"Verbena\", \"#FF847E35\": \"Verdant\", \"#FF5AD33E\": \"Verdant Fields\", \"#FF28615D\": \"Verdant Forest\", \"#FF167D60\": \"Verdant Green\", \"#FF84A97C\": \"Verdant Haven\", \"#FF4E5A4A\": \"Verdant Hush\", \"#FF817C4A\": \"Verdant Leaf\", \"#FF62C46C\": \"Verdant Oasis\", \"#FF90A197\": \"Verdant Retreat\", \"#FF7F9E5B\": \"Verdant Serenade\", \"#FF0E7C36\": \"Verdant Vale\", \"#FF75794A\": \"Verdant Views\", \"#FF7FB383\": \"Verde\", \"#FF877459\": \"Verde Marr\\u00f3n\", \"#FFEDF5E7\": \"Verde Pastel\", \"#FFA7AD8D\": \"Verde Tortuga\", \"#FF758000\": \"Verde Tropa\", \"#FF81A595\": \"Verdigreen\", \"#FF62BE77\": \"Verdigris Coloured\", \"#FF62603E\": \"Verdigris Fonc\\u00e9\", \"#FF61AC86\": \"Verdigris Green\", \"#FF558367\": \"Verdigris Roundhead\", \"#FF00BBAA\": \"Verditer\", \"#FF55AABB\": \"Verditer Blue\", \"#FF48531A\": \"Verdun Green Variant\", \"#FF937496\": \"Veri Berri\", \"#FF232324\": \"Verified Black\", \"#FF00844B\": \"Veritably Verdant\", \"#FF2B7CAF\": \"Vermeer Blue\", \"#FFDABE82\": \"Vermicelles\", \"#FFD1B791\": \"Vermicelli\", \"#FFF4320C\": \"Vermilion Tint\", \"#FFF24433\": \"Vermilion Bird\", \"#FFE34244\": \"Vermilion Cinnabar\", \"#FF474230\": \"Vermilion Green\", \"#FFF9603B\": \"Vermilion Orange\", \"#FFB5493A\": \"Vermilion Red\", \"#FFD1062B\": \"Vermilion Scarlet\", \"#FF973A36\": \"Vermilion Seabass\", \"#FFD46036\": \"Vermilion Waxcap\", \"#FF8F7303\": \"Vermin Brown\", \"#FF55CC11\": \"Verminal\", \"#FFA16954\": \"Verminlord Hide\", \"#FFF8F5E8\": \"Vermont Cream\", \"#FF48535A\": \"Vermont Slate\", \"#FFE9D3BA\": \"Verona Beach\", \"#FFECBFA8\": \"Veronese Peach\", \"#FFA020FF\": \"Veronica\", \"#FF7E3075\": \"Veronica Purple\", \"#FFACDFAD\": \"Vers de Terre\", \"#FFC4B0AD\": \"Versailles Rose\", \"#FFC1B6AB\": \"Versatile Taupe\", \"#FF18880D\": \"Verse Green\", \"#FF4A615C\": \"Vert Pierre\", \"#FF990055\": \"Vertigo Cherry\", \"#FFFCEDD8\": \"Verve\", \"#FF944F80\": \"Verve Violet\", \"#FFBB3381\": \"Very Berry\", \"#FF34363E\": \"Very Black\", \"#FF33365B\": \"Very Blue\", \"#FF664411\": \"Very Coffee\", \"#FF927288\": \"Very Grape\", \"#FF3A4859\": \"Very Navy\", \"#FFF3D19F\": \"Vespa Yellow\", \"#FF0011CC\": \"Vesper\", \"#FF99A0B2\": \"Vesper Violet\", \"#FFCDC8BF\": \"Vessel\", \"#FF8A8B8F\": \"Vessel Grey\", \"#FF937899\": \"Vestige\", \"#FF879860\": \"Vesuvian Green\", \"#FFA28A9F\": \"Vesuvian Violet\", \"#FFA85533\": \"Vesuvius Variant\", \"#FF2E58E8\": \"Veteran\\u2019s Day Blue\", \"#FF807D6F\": \"Vetiver\", \"#FFC1BBB1\": \"Viaduct\", \"#FFD9D140\": \"Viameter\", \"#FFFFD44D\": \"Vibrant\", \"#FFD1902E\": \"Vibrant Amber\", \"#FFEBE541\": \"Vibrant Arsenic\", \"#FF0339F8\": \"Vibrant Blue\", \"#FF0ADD08\": \"Vibrant Green\", \"#FFFFBD31\": \"Vibrant Honey\", \"#FF00FFE5\": \"Vibrant Mint\", \"#FFFF6216\": \"Vibrant Orange\", \"#FF804B81\": \"Vibrant Orchid\", \"#FFAD03DE\": \"Vibrant Purple\", \"#FFC24C6A\": \"Vibrant Red\", \"#FF88D6DC\": \"Vibrant Soft Blue\", \"#FFBB0088\": \"Vibrant Velvet\", \"#FF4B373A\": \"Vibrant Vine\", \"#FF9400D4\": \"Vibrant Violet\", \"#FF6C6068\": \"Vibrant Vision\", \"#FFEAEDEB\": \"Vibrant White\", \"#FFFFDA29\": \"Vibrant Yellow\", \"#FFC7FFFF\": \"VIC 20 Blue\", \"#FFFFFFB2\": \"VIC 20 Creme\", \"#FF94E089\": \"VIC 20 Green\", \"#FFEA9FF6\": \"VIC 20 Pink\", \"#FF87D6DD\": \"VIC 20 Sky\", \"#FF664E62\": \"Vicarious Violet\", \"#FFEE00DD\": \"Vice City\", \"#FF8F509D\": \"Vicious Violet\", \"#FF564985\": \"Victoria Variant\", \"#FF0853A7\": \"Victoria Blue\", \"#FF006A4D\": \"Victoria Green\", \"#FF007755\": \"Victoria Peak\", \"#FF6A3C3A\": \"Victoria Red\", \"#FF988F97\": \"Victorian\", \"#FFD4C5CA\": \"Victorian Cottage\", \"#FFC38B36\": \"Victorian Crown\", \"#FF558E4C\": \"Victorian Garden\", \"#FFA2783B\": \"Victorian Gold\", \"#FF00B191\": \"Victorian Greenhouse\", \"#FF6D657E\": \"Victorian Iris\", \"#FFEFE1CD\": \"Victorian Lace\", \"#FFB68B88\": \"Victorian Mauve\", \"#FF104A65\": \"Victorian Peacock\", \"#FFF1E3D8\": \"Victorian Pearl\", \"#FF828388\": \"Victorian Pewter\", \"#FF8E6278\": \"Victorian Plum\", \"#FF966B6F\": \"Victorian Rose\", \"#FFD28085\": \"Victorian Rouge\", \"#FF6C7773\": \"Victorian Tapestry\", \"#FFAE6AA1\": \"Victorian Valentine\", \"#FFB079A7\": \"Victorian Violet\", \"#FFD6B2AD\": \"Victoriana\", \"#FF3A405A\": \"Victory Blue\", \"#FF92ABD8\": \"Victory Lake\", \"#FFA1DDD4\": \"Vidalia\", \"#FFD2A88F\": \"Vienna Beige\", \"#FFF7EFEF\": \"Vienna Dawn\", \"#FFE9D9D4\": \"Vienna Lace\", \"#FF330022\": \"Vienna Roast\", \"#FFFED1BD\": \"Vienna Sausage\", \"#FF8C8185\": \"Viennese\", \"#FF4278AF\": \"Viennese Blue\", \"#FFEEC172\": \"Vietnamese Lantern\", \"#FF81796F\": \"Vigilant\", \"#FF645681\": \"Vigorous Violet\", \"#FF8B9D30\": \"Vigorous Wasabi\", \"#FF4DB1C8\": \"Viking Variant\", \"#FF757266\": \"Viking Castle\", \"#FFCABAE0\": \"Viking Diva\", \"#FF8FCDB0\": \"Vile Green\", \"#FF789695\": \"Villa Blue\", \"#FFCCC4B4\": \"Villa Grey\", \"#FF817362\": \"Villa Oliva\", \"#FFEFEAE1\": \"Villa White\", \"#FFAB9769\": \"Village Crier\", \"#FF7E867C\": \"Village Green\", \"#FF825F40\": \"Village Lane\", \"#FF7B6F61\": \"Village Square\", \"#FF728F66\": \"Villandry\", \"#FFB47463\": \"Vin Cuit\", \"#FF955264\": \"Vin Rouge Variant\", \"#FFF59994\": \"Vinaceous\", \"#FFF48B8B\": \"Vinaceous Cinnamon\", \"#FFC74300\": \"Vinaceous Tawny\", \"#FFEFDAAE\": \"Vinaigrette\", \"#FFACB3AE\": \"Vinalhaven\", \"#FF5778A7\": \"Vinca\", \"#FF45584C\": \"Vinca & Vine\", \"#FF483743\": \"Vincotto\", \"#FFAE7579\": \"Vindaloo\", \"#FF338544\": \"Vine\", \"#FF4D5F4F\": \"Vine Leaf\", \"#FF819E84\": \"Vineyard\", \"#FFEE4455\": \"Vineyard Autumn\", \"#FF5F7355\": \"Vineyard Green\", \"#FF777146\": \"Vineyard View\", \"#FF684047\": \"Vineyard Wine\", \"#FFB31A38\": \"Vinho do Porto\", \"#FF4B7378\": \"Vining Ivy\", \"#FF4C1C24\": \"Vino Tinto\", \"#FF847592\": \"Vintage\", \"#FFDFE1CC\": \"Vintage Beige\", \"#FFC0B0D0\": \"Vintage Bloom\", \"#FF87B8B5\": \"Vintage Blue\", \"#FF78726E\": \"Vintage Boots\", \"#FF966B34\": \"Vintage Caramel\", \"#FFC7B0A7\": \"Vintage Charm\", \"#FFA3B22E\": \"Vintage Chartreuse\", \"#FF9D5F46\": \"Vintage Copper\", \"#FFD68C76\": \"Vintage Coral\", \"#FFD8CEB9\": \"Vintage Ephemera\", \"#FF4F4D48\": \"Vintage Frame\", \"#FFCBD8B9\": \"Vintage Glass\", \"#FFB79E78\": \"Vintage Gold\", \"#FF6F636D\": \"Vintage Grape\", \"#FF505D74\": \"Vintage Indigo\", \"#FF958B80\": \"Vintage Khaki\", \"#FFF1E7D2\": \"Vintage Lace\", \"#FFB07B40\": \"Vintage Lincoln\", \"#FFE3DCCA\": \"Vintage Linen\", \"#FFBAAFAC\": \"Vintage Mauve\", \"#FF763D4B\": \"Vintage Merlot\", \"#FFFFB05F\": \"Vintage Orange\", \"#FFFDCFB0\": \"Vintage Peach\", \"#FF675D62\": \"Vintage Plum\", \"#FFF2EDEC\": \"Vintage Porcelain\", \"#FFA66C47\": \"Vintage Pottery\", \"#FF9E3641\": \"Vintage Red\", \"#FF9097B4\": \"Vintage Ribbon\", \"#FFCDBFB9\": \"Vintage Taupe\", \"#FF669699\": \"Vintage Teal\", \"#FF485169\": \"Vintage Velvet\", \"#FF94B2A6\": \"Vintage Vessel\", \"#FF888F4F\": \"Vintage Vibe\", \"#FFE59DAC\": \"Vintage Victorian\", \"#FF634F62\": \"Vintage Violet\", \"#FFF4EFE4\": \"Vintage White\", \"#FF65344E\": \"Vintage Wine\", \"#FF72491E\": \"Vintage Wood\", \"#FF68546A\": \"Vintner\", \"#FF966EBD\": \"Viola Variant\", \"#FF2F2A41\": \"Viola Black\", \"#FF8C6897\": \"Viola Grey\", \"#FFC6C8D0\": \"Viola Ice Grey\", \"#FFB9A5BD\": \"Viola Sororia\", \"#FFBF8FC4\": \"Violaceous\", \"#FF881188\": \"Violaceous Greti\", \"#FF9A0EEA\": \"Violet Variant\", \"#FF838BA4\": \"Violet Aura\", \"#FFBAB3CB\": \"Violet Beauty\", \"#FF49434A\": \"Violet Black\", \"#FF510AC9\": \"Violet Blue\", \"#FFB9B1C8\": \"Violet Bouquet\", \"#FFDCDCE5\": \"Violet Breeze\", \"#FF531745\": \"Violet Carmine\", \"#FF8F7DA5\": \"Violet Chalk\", \"#FFEFECEF\": \"Violet Clues\", \"#FFD8D3E6\": \"Violet Crush\", \"#FFA89B9C\": \"Violet Dawn\", \"#FFB59C9C\": \"Violet Dusk\", \"#FFDFDEE5\": \"Violet Echo\", \"#FFA387AC\": \"Violet Eclipse\", \"#FFE6E5E6\": \"Violet Essence\", \"#FF65677A\": \"Violet Evening\", \"#FFDEE2EC\": \"Violet Extract\", \"#FFBA97A9\": \"Violet Fantasy\", \"#FFA66DA1\": \"Violet Femmes\", \"#FFB8A4C8\": \"Violet Fields\", \"#FF926EAE\": \"Violet Frog\", \"#FFC4C0E9\": \"Violet Gems\", \"#FF4422EE\": \"Violet Glow\", \"#FF675B72\": \"Violet Haze\", \"#FFCDB7FA\": \"Violet Heaven\", \"#FF330099\": \"Violet Hickey\", \"#FFE5E2E7\": \"Violet Hush\", \"#FFC0A9AD\": \"Violet Ice\", \"#FF482D67\": \"Violet Indigo\", \"#FF4D4456\": \"Violet Intense\", \"#FFF0A0D1\": \"Violet Kiss\", \"#FF64338B\": \"Violet Magician\", \"#FF644982\": \"Violet Majesty\", \"#FFDACCDE\": \"Violet Mist\", \"#FFACA8CD\": \"Violet Mix\", \"#FFCA7988\": \"Violet Orchid\", \"#FF927B97\": \"Violet Persuasion\", \"#FFFB5FFC\": \"Violet Pink\", \"#FF8601BF\": \"Violet Poison\", \"#FF60394D\": \"Violet Posy\", \"#FFC7CCD8\": \"Violet Powder\", \"#FF3A2F52\": \"Violet Purple Variant\", \"#FF8B4963\": \"Violet Quartz\", \"#FFA50055\": \"Violet Red Variant\", \"#FFBCC6DF\": \"Violet Scent Soft Blue\", \"#FF4D4860\": \"Violet Shadow\", \"#FF5C619D\": \"Violet Storm\", \"#FFC7C5DC\": \"Violet Sweet Pea\", \"#FF9E91C3\": \"Violet Tulip\", \"#FFBA86B5\": \"Violet Tulle\", \"#FFDAAFD1\": \"Violet Vamp\", \"#FFE5DAE1\": \"Violet Vapour\", \"#FF898CA3\": \"Violet Verbena\", \"#FF898098\": \"Violet Vibes\", \"#FFD8E0EA\": \"Violet Vignette\", \"#FFB7BDD1\": \"Violet Vision\", \"#FFB09F9E\": \"Violet Vista\", \"#FF883377\": \"Violet Vixen\", \"#FFE9E1E8\": \"Violet Vogue\", \"#FF1A161D\": \"Violet Void\", \"#FFA669DB\": \"Violet Voltage\", \"#FFD2D6E6\": \"Violet Water\", \"#FF833E82\": \"Violet Webcap\", \"#FFDAD6DF\": \"Violet Whimsey\", \"#FFB48BB8\": \"Violet Whimsy\", \"#FFE2E3E9\": \"Violet White\", \"#FFC8D4E4\": \"Violet Wisp\", \"#FFACA7CB\": \"Violeta Silvestre\", \"#FF5A226F\": \"Violethargic\", \"#FF7487C6\": \"Violets Are Blue\", \"#FFAC6B98\": \"Violetta\", \"#FF882055\": \"Violettuce\", \"#FF674403\": \"Violin Brown\", \"#FF008F3C\": \"Viper Green\", \"#FFE2DCAB\": \"Virgin Olive Oil\", \"#FFECBDB0\": \"Virgin Peach\", \"#FFB7C3D7\": \"Virginia Blue\", \"#FF538F4E\": \"Virgo Green Goddess\", \"#FF99CC00\": \"Viric Green\", \"#FF1E9167\": \"Viridian Variant\", \"#FFBCD7D4\": \"Viridian Green Variant\", \"#FFC8E0AB\": \"Viridine Green\", \"#FF00846D\": \"Viridis\", \"#FFFE0215\": \"Virtual Boy\", \"#FF8AA56E\": \"Virtual Forest\", \"#FFC1EE13\": \"Virtual Golf\", \"#FFCF184B\": \"Virtual Pink\", \"#FF8A7A6A\": \"Virtual Taupe\", \"#FF66537F\": \"Virtual Violet\", \"#FF5D5558\": \"Virtuoso\", \"#FF9F7BA9\": \"Virtuous\", \"#FFB7B0BF\": \"Virtuous Violet\", \"#FFF9E496\": \"Vis Vis Variant\", \"#FFD2CCE5\": \"Vision\", \"#FFDFD3CB\": \"Vision of Light\", \"#FF9B94C2\": \"Vision Quest\", \"#FF83477D\": \"Visiona Red\", \"#FFF6E0A9\": \"Visionary\", \"#FFCBACAB\": \"Vista\", \"#FF97D5B3\": \"Vista Blue Variant\", \"#FFE3DFD9\": \"Vista White Variant\", \"#FF5C2C45\": \"Vistoris Lake\", \"#FF138859\": \"Vital Green\", \"#FFEDE0C5\": \"Vital Yellow\", \"#FF8F9B5B\": \"Vitality\", \"#FF2AAA45\": \"Vitalize\", \"#FFE3AC72\": \"Viva Gold\", \"#FFB39953\": \"Viva Las Vegas\", \"#FFA0488C\": \"Viva Magenta\", \"#FFA7295F\": \"Vivacious\", \"#FFDC89A8\": \"Vivacious Pink\", \"#FF804665\": \"Vivacious Violet\", \"#FFEF3939\": \"Vivaldi Red\", \"#FF995468\": \"Vive L\\u2019amour\", \"#FF97BEE2\": \"Vive le Bleu\", \"#FFAED1E8\": \"Vive le Vent\", \"#FFCC9900\": \"Vivid Amber\", \"#FF152EFF\": \"Vivid Blue\", \"#FF00AAEE\": \"Vivid Cerulean\", \"#FFCC0033\": \"Vivid Crimson\", \"#FFB13AAD\": \"Vivid Fuchsia\", \"#FF2FEF10\": \"Vivid Green\", \"#FFA6D608\": \"Vivid Lime Green\", \"#FF00CC33\": \"Vivid Malachite\", \"#FFB80CE3\": \"Vivid Mulberry\", \"#FFFF5F00\": \"Vivid Orange\", \"#FFFFA102\": \"Vivid Orange Peel\", \"#FFCC00FF\": \"Vivid Orchid\", \"#FF9900FA\": \"Vivid Purple\", \"#FFFF006C\": \"Vivid Raspberry\", \"#FFF70D1A\": \"Vivid Red\", \"#FFDF6124\": \"Vivid Red Tangelo\", \"#FF87C95F\": \"Vivid Spring\", \"#FFF07427\": \"Vivid Tangelo\", \"#FFE56024\": \"Vivid Vermilion\", \"#FFA4407E\": \"Vivid Viola\", \"#FF5E4B62\": \"Vivid Vision\", \"#FFFFE302\": \"Vivid Yellow\", \"#FF573D37\": \"Vixen\", \"#FF7B9E98\": \"Vizcaya\", \"#FF47644B\": \"Vizcaya Palm\", \"#FFBFC0EE\": \"Vodka\", \"#FF050D25\": \"Void\", \"#FF41373A\": \"Void Wellness Coach\", \"#FFAF8BA8\": \"Voila!\", \"#FFA55749\": \"Volcanic\", \"#FF6F7678\": \"Volcanic Ash\", \"#FFE15835\": \"Volcanic Blast\", \"#FF72453A\": \"Volcanic Brick\", \"#FF615C60\": \"Volcanic Glass\", \"#FF605244\": \"Volcanic Island\", \"#FF6B6965\": \"Volcanic Rock\", \"#FF404048\": \"Volcanic Sand\", \"#FF45433B\": \"Volcanic Stone Green\", \"#FFBE462F\": \"Volcanic Unrest\", \"#FF4E2728\": \"Volcano\", \"#FF2D135F\": \"Voldemort\", \"#FF3B4956\": \"Voltage\", \"#FF673033\": \"Voluptuous\", \"#FF7711DD\": \"Voluptuous Violet\", \"#FF445A5E\": \"Volute\", \"#FF443240\": \"Voodoo Variant\", \"#FF824D8F\": \"Voodoo Violet\", \"#FFFEEEED\": \"Voracious White\", \"#FF83769C\": \"Voxatron Purple\", \"#FF719CA4\": \"Voyage\", \"#FF4D5062\": \"Voyager\", \"#FF9A937F\": \"Voysey Grey\", \"#FF36383C\": \"Vulcan Variant\", \"#FF5F3E42\": \"Vulcan Burgundy\", \"#FFE6390D\": \"Vulcan Fire\", \"#FF897F79\": \"Vulcan Mud\", \"#FF424443\": \"Vulcanised\", \"#FFC8C8B5\": \"Wabi-Sabi\", \"#FFEEAACC\": \"Waddles Pink\", \"#FFD4BBB1\": \"Wafer Variant\", \"#FFE2C779\": \"Waffle Cone\", \"#FFCDBDBA\": \"Wafting Grey\", \"#FF6D4D27\": \"Wagon Train\", \"#FFC2B79E\": \"Wagon Wheel\", \"#FF272D4E\": \"Wahoo\", \"#FF5B6E91\": \"Waikawa Grey\", \"#FF218BA0\": \"Waikiki\", \"#FF004411\": \"Wailing Woods\", \"#FF4CA2D9\": \"Waimea Blue\", \"#FF9C9D85\": \"Wainscot Green\", \"#FF4C4E31\": \"Waiouru Variant\", \"#FF654BC9\": \"Waiporoporo Purple\", \"#FF9D9D9D\": \"Waiting\", \"#FF00656E\": \"Wakame Green\", \"#FF6B9362\": \"Wakatake Green\", \"#FFF6D559\": \"Wake Me Up\", \"#FF295468\": \"Wakefield\", \"#FF789BB6\": \"Walden Pond\", \"#FF88BB11\": \"Walk in the Park\", \"#FF3BB08F\": \"Walk in the Woods\", \"#FF496568\": \"Walk Me Home\", \"#FF3D87BB\": \"Walker Lake\", \"#FFFAF5FA\": \"Walkie Chalkie\", \"#FF849B63\": \"Walking Dead\", \"#FFFCFC9D\": \"Walking on Sunshine\", \"#FFA2785D\": \"Walking Stick\", \"#FFA3999C\": \"Walkway\", \"#FFABAE86\": \"Wall Green\", \"#FF656D73\": \"Wall Street\", \"#FF11CC44\": \"Walled Garden\", \"#FF9B5953\": \"Walleye\", \"#FFA0848A\": \"Wallflower\", \"#FFE4E3E6\": \"Wallflower White\", \"#FFC6BDBF\": \"Wallis\", \"#FFE9EDF1\": \"Walls of Santorini\", \"#FF4C0400\": \"Walnut Brown\", \"#FFF5D8B2\": \"Walnut Cream\", \"#FF5C5644\": \"Walnut Grove\", \"#FF5D5242\": \"Walnut Hull\", \"#FFFFF0CF\": \"Walnut Milkies\", \"#FFEECB88\": \"Walnut Oil\", \"#FFAA8344\": \"Walnut Shell\", \"#FFA68B6E\": \"Walnut Shell Brown\", \"#FF774E37\": \"Walnut Wood\", \"#FF999B9B\": \"Walrus\", \"#FFC8D9DD\": \"Wan Blue\", \"#FFE4E2DC\": \"Wan White\", \"#FF5E5648\": \"Wanderer\", \"#FFCDB573\": \"Wandering\", \"#FF73A4C6\": \"Wandering River\", \"#FF876D5E\": \"Wandering Road\", \"#FFA6A897\": \"Wandering Willow\", \"#FF426267\": \"Wanderlust\", \"#FF643530\": \"War God\", \"#FFDC571D\": \"War Paint Red\", \"#FFB50038\": \"Warlock Red\", \"#FFBA0033\": \"Warlord\", \"#FF654740\": \"Warm Air of Debonair\", \"#FFCDB49F\": \"Warm Alpaca\", \"#FFCBB68F\": \"Warm and Toasty\", \"#FFFFB865\": \"Warm Apricot\", \"#FFCFC9C7\": \"Warm Ashes\", \"#FF9C9395\": \"Warm Asphalt\", \"#FF3B1F23\": \"Warm Balaclavas Are Forever\", \"#FFE3CDAC\": \"Warm Biscuits\", \"#FF4B57DB\": \"Warm Blue\", \"#FFF9E6D3\": \"Warm Bread\", \"#FFA1BEC1\": \"Warm Breezes\", \"#FF964E02\": \"Warm Brown\", \"#FF604840\": \"Warm Brownie\", \"#FFD8BFA2\": \"Warm Buff\", \"#FFE6D5BA\": \"Warm Buttercream\", \"#FFD0B082\": \"Warm Butterscotch\", \"#FFBF6A52\": \"Warm Cider\", \"#FFF9D09C\": \"Warm Cocoon\", \"#FFA88168\": \"Warm Cognac\", \"#FFB38A82\": \"Warm Comfort\", \"#FFB97254\": \"Warm Copper\", \"#FFC36C2D\": \"Warm Cream Spirit\", \"#FFE4CEB5\": \"Warm Croissant\", \"#FF927558\": \"Warm Earth\", \"#FF93817E\": \"Warm Embrace\", \"#FF7E8272\": \"Warm Eucalyptus\", \"#FFDED3CA\": \"Warm Fog\", \"#FFF6E2CE\": \"Warm Fuzzies\", \"#FFF1CF8A\": \"Warm Glow\", \"#FFA49E97\": \"Warm Granite\", \"#FF978A84\": \"Warm Grey\", \"#FFACA49A\": \"Warm Grey Flannel\", \"#FF736967\": \"Warm Haze\", \"#FFF6B3A7\": \"Warm Heart\", \"#FFBE9677\": \"Warm Hearth\", \"#FFC89F59\": \"Warm Leather\", \"#FFFFF9D8\": \"Warm Light\", \"#FF6D4741\": \"Warm Mahogany\", \"#FFF6F1E1\": \"Warm Milk\", \"#FFE1BE8B\": \"Warm Muffin\", \"#FFC1B19D\": \"Warm Neutral\", \"#FF8F6A50\": \"Warm Nutmeg\", \"#FFD9CEC0\": \"Warm Oatmeal\", \"#FFD8CFBA\": \"Warm Oats\", \"#FFC7B63C\": \"Warm Olive\", \"#FF4C4845\": \"Warm Onyx\", \"#FF483838\": \"Warm Operator\\u2019s Overalls\", \"#FFB4ADA6\": \"Warm Pewter\", \"#FFFB5581\": \"Warm Pink\", \"#FF513938\": \"Warm Port\", \"#FF5C4E44\": \"Warm Pumpernickel\", \"#FF952E8F\": \"Warm Purple\", \"#FFD2C8B9\": \"Warm Putty\", \"#FFC5AE91\": \"Warm Sand\", \"#FFB2B1AF\": \"Warm Shale\", \"#FFDDC9B1\": \"Warm Shell\", \"#FF987744\": \"Warm Spice\", \"#FF4286BC\": \"Warm Spring\", \"#FFA79A8A\": \"Warm Stone\", \"#FFFAF6DB\": \"Warm Sun\", \"#FFF1CA95\": \"Warm Sunshine\", \"#FFAB917D\": \"Warm Taupe\", \"#FFC1775E\": \"Warm Terra Cotta\", \"#FFF3F5DC\": \"Warm Turbulence\", \"#FF9E6654\": \"Warm Up\", \"#FFA66E68\": \"Warm Wassail\", \"#FFA89A8C\": \"Warm Waterlogged Lab Coat\", \"#FF7EBBC2\": \"Warm Waters\", \"#FFEA9073\": \"Warm Welcome\", \"#FF8D894A\": \"Warm Wetlands\", \"#FFEFEBD8\": \"Warm White\", \"#FFD4EDE3\": \"Warm Winter\", \"#FFD0B55A\": \"Warm Woollen\", \"#FF5C3839\": \"Warmed Wine\", \"#FFD44B3B\": \"Warming Heart\", \"#FFE4B9A2\": \"Warming Peach\", \"#FF9F552D\": \"Warmth\", \"#FF803020\": \"Warmth of Teamwork\", \"#FFE5D5C9\": \"Warp & Weft\", \"#FFEAF2F1\": \"Warp Drive\", \"#FF6B6A74\": \"Warpfiend Grey\", \"#FF515131\": \"Warplock Bronze\", \"#FF927D7B\": \"Warplock Bronze Metal\", \"#FF168340\": \"Warpstone Glow\", \"#FFB8966E\": \"Warrant\", \"#FF6B654E\": \"Warren Tavern\", \"#FF7D685B\": \"Warrior\", \"#FFA32D48\": \"Warrior Queen\", \"#FFAFD77F\": \"Wasabi Variant\", \"#FFA9AD74\": \"Wasabi Green\", \"#FF333300\": \"Wasabi Nori\", \"#FF849137\": \"Wasabi Nuts\", \"#FFB4C79C\": \"Wasabi Peanut\", \"#FFBDB38F\": \"Wasabi Powder\", \"#FFD2CCA0\": \"Wasabi Zing\", \"#FFFAFBFD\": \"Wash Me\", \"#FF1F262A\": \"Washed Black\", \"#FF94D1DF\": \"Washed Blue\", \"#FFF3F0DA\": \"Washed Canvas\", \"#FF819DBE\": \"Washed Denim\", \"#FFE1E3D7\": \"Washed Dollar\", \"#FFCCD1C8\": \"Washed Green\", \"#FFFAE8C8\": \"Washed in Light\", \"#FFCAC2AF\": \"Washed Khaki\", \"#FFC5C0A3\": \"Washed Olive\", \"#FFDEDFCC\": \"Washed Sage\", \"#FFFFB3A7\": \"Washed-Out Crimson\", \"#FFC3D8E4\": \"Washing Powder Soft Blue\", \"#FFC2DCE3\": \"Washing Powder White\", \"#FFDCB89D\": \"Wassail\", \"#FF9C8855\": \"Wasteland\", \"#FF89C3EB\": \"Wasurenagusa Blue\", \"#FF8FBABC\": \"Watchet\", \"#FFD4F1F9\": \"Water\", \"#FF5AB5CB\": \"Water Baby\", \"#FFCFDFDD\": \"Water Baptism\", \"#FF0E87CC\": \"Water Blue\", \"#FF4999A1\": \"Water Carrier\", \"#FFEDE4CF\": \"Water Chestnut\", \"#FF355873\": \"Water Chi\", \"#FF75A7AD\": \"Water Cooler\", \"#FFE1E5DC\": \"Water Droplet\", \"#FF75B790\": \"Water Fern\", \"#FF7AC6D9\": \"Water Flow\", \"#FF77B6D5\": \"Water Fountain\", \"#FF76AFB6\": \"Water Glitter\", \"#FF81B89A\": \"Water Green\", \"#FFA0A3D2\": \"Water Hyacinth\", \"#FFE2E3EB\": \"Water Iris\", \"#FFB6ECDE\": \"Water Leaf Variant\", \"#FFDDE3D5\": \"Water Lily\", \"#FFC7D8E3\": \"Water Mist\", \"#FF6FB0BE\": \"Water Music\", \"#FF81D0DF\": \"Water Nymph\", \"#FF4F5156\": \"Water Ouzel\", \"#FF54AF9C\": \"Water Park\", \"#FFB56C60\": \"Water Persimmon\", \"#FF0083C8\": \"Water Raceway\", \"#FFB0AB80\": \"Water Reed\", \"#FF949381\": \"Water Scrub\", \"#FF65A5D5\": \"Water Spirit\", \"#FF44BBCC\": \"Water Sports\", \"#FFE5EECC\": \"Water Sprout\", \"#FFD8EBEA\": \"Water Squirt\", \"#FFA9BDB8\": \"Water Surface\", \"#FF958F88\": \"Water Tower\", \"#FFACC7E5\": \"Water Wash\", \"#FFA28566\": \"Water Wheel\", \"#FF80D5CC\": \"Water Wings\", \"#FF80D4D0\": \"Water Wonder\", \"#FF084D58\": \"Watercolour Blue\", \"#FFD6C9DE\": \"Watercolour Grape\", \"#FF96B47E\": \"Watercolour Green\", \"#FFB9D9E7\": \"Watercolour Sky\", \"#FFDBE5DB\": \"Watercolour White\", \"#FF5CCBD6\": \"Watercourse Variant\", \"#FF6E9377\": \"Watercress\", \"#FFC7C7A1\": \"Watercress Pesto\", \"#FF748C69\": \"Watercress Spice\", \"#FF3AB0A2\": \"Waterfall\", \"#FFE4EEEA\": \"Waterfall Mist\", \"#FFD4E4E5\": \"Waterfront\", \"#FF2F3F53\": \"Waterhen Back\", \"#FF436BAD\": \"Waterline Blue\", \"#FFDEE9DF\": \"Watermark\", \"#FFFD4659\": \"Watermelon\", \"#FFBF6C6E\": \"Watermelon Crush\", \"#FFC0686E\": \"Watermelon Gelato\", \"#FFF05C85\": \"Watermelon Juice\", \"#FFDFCFCA\": \"Watermelon Milk\", \"#FFFBE0E8\": \"Watermelon Mousse\", \"#FFC77690\": \"Watermelon Pink\", \"#FFE08880\": \"Watermelon Punch\", \"#FFBF4147\": \"Watermelon Red\", \"#FFE42B73\": \"Watermelon Sugar\", \"#FFEB4652\": \"Watermelonade\", \"#FFD3CCCD\": \"Watermill Wood\", \"#FFDCECE7\": \"Waterscape\", \"#FFB0CEC2\": \"Watershed\", \"#FFD2F3EB\": \"Waterslide\", \"#FFA4F4F9\": \"Waterspout\", \"#FF637FBB\": \"Watertown\", \"#FF7EB7BF\": \"Waterway\", \"#FF00718A\": \"Waterworld\", \"#FFAEBDBB\": \"Watery\", \"#FF88BFE7\": \"Watery Sea\", \"#FF74AEBA\": \"Watson Lake\", \"#FFD6CA3D\": \"Wattle Variant\", \"#FFF2CDBB\": \"Watusi Variant\", \"#FFA5CED5\": \"Wave\", \"#FFDCE9EA\": \"Wave Crest\", \"#FF9AAAB6\": \"Wave Goodbye\", \"#FF6C919F\": \"Wave Jumper\", \"#FFA0764A\": \"Wave of Grain\", \"#FFA7C9C0\": \"Wave Runner\", \"#FFCBE4E7\": \"Wave Splash\", \"#FFAFD9D3\": \"Wave Top\", \"#FF7DC4CD\": \"Wavelet\", \"#FFC7AA7C\": \"Waves of Grain\", \"#FFAEA266\": \"Wavy Glass\", \"#FF006597\": \"Wavy Navy\", \"#FFDDBB33\": \"Wax\", \"#FF00A4A6\": \"Wax Crayon Blue\", \"#FFEEB39E\": \"Wax Flower Variant\", \"#FFD8DB8B\": \"Wax Green\", \"#FFF1E6CC\": \"Wax Poetic\", \"#FFE2D5BD\": \"Wax Sculpture\", \"#FFD3B667\": \"Wax Way\", \"#FFEAE8A0\": \"Wax Yellow\", \"#FFB38241\": \"Waxen Moon\", \"#FFC0C2C0\": \"Waxwing\", \"#FFF8B500\": \"Waxy Corn\", \"#FF1188CC\": \"Way Beyond the Blue\", \"#FF00C000\": \"Waystone Green\", \"#FFD9DCD1\": \"Wayward Willow\", \"#FFDEDFE2\": \"Wayward Wind\", \"#FF99CC04\": \"Waywatcher Green\", \"#FF5E5A59\": \"Waza Bear\", \"#FFB21B00\": \"Wazdakka Red\", \"#FFFDD7D8\": \"We Peep Variant\", \"#FFE1F2DF\": \"Weak Green\", \"#FFEADEE4\": \"Weak Mauve\", \"#FFE0F0E5\": \"Weak Mint\", \"#FFFAEDE3\": \"Weak Orange\", \"#FFECDEE5\": \"Weak Pink\", \"#FFB47B27\": \"Weapon Bronze\", \"#FF9F947D\": \"Weather Board\", \"#FF593A27\": \"Weathered Bamboo\", \"#FFD2E2F2\": \"Weathered Blue\", \"#FF59504C\": \"Weathered Brown\", \"#FFEAD0A9\": \"Weathered Coral\", \"#FF988A72\": \"Weathered Fossil\", \"#FFD5C6C2\": \"Weathered Hide\", \"#FF90614A\": \"Weathered Leather\", \"#FFE4F5E1\": \"Weathered Mint\", \"#FFBABBB3\": \"Weathered Moss\", \"#FF7B9093\": \"Weathered Pebble\", \"#FFEADFE8\": \"Weathered Pink\", \"#FF867C61\": \"Weathered Plank\", \"#FFF9F4D9\": \"Weathered Plastic\", \"#FFB5745C\": \"Weathered Saddle\", \"#FFDFC0A6\": \"Weathered Sandstone\", \"#FF937F68\": \"Weathered Shingle\", \"#FFC4C5C6\": \"Weathered Stone\", \"#FFE6E3D9\": \"Weathered White\", \"#FF97774D\": \"Weathered Wicker\", \"#FFB19C86\": \"Weathered Wood\", \"#FFBDAE95\": \"Weatherhead\", \"#FF2C201A\": \"Weathervane\", \"#FFBFB18A\": \"Weaver\\u2019s Spool\", \"#FF9D7F62\": \"Weaver\\u2019s Tool\", \"#FF8F684B\": \"Webcap Brown\", \"#FFEDEADC\": \"Wedded Bliss\", \"#FFEDE6E9\": \"Wedding\", \"#FFEEE2C9\": \"Wedding Cake\", \"#FFE7E8E1\": \"Wedding Cake White\", \"#FFFEFEE7\": \"Wedding Dress\", \"#FFBCB6CB\": \"Wedding Flowers\", \"#FFFFFEE5\": \"Wedding in White\", \"#FFB5C1AC\": \"Wedding Mint\", \"#FFF6DFD8\": \"Wedding Pink\", \"#FFE1ECA5\": \"Wedge of Lime\", \"#FF4C6B88\": \"Wedgewood Variant\", \"#FF9FE4AA\": \"Weekend Gardener\", \"#FFE9C2AD\": \"Weekend Retreat\", \"#FF5D8727\": \"Weeping Fig\", \"#FFB3B17B\": \"Weeping Willow\", \"#FFD7DDEC\": \"Weeping Wisteria\", \"#FF5A06EF\": \"W\\u00e8i L\\u00e1n Azure\", \"#FF9C8D7D\": \"Weimaraner\", \"#FF3AE57F\": \"Weird Green\", \"#FFB3833B\": \"Weissbier\", \"#FFE4E1D6\": \"Weisswurst White\", \"#FFC09C6A\": \"Welcome Home\", \"#FFD4C6A7\": \"Welcome Walkway\", \"#FFF3E3CA\": \"Welcome White\", \"#FFEEAA00\": \"Welcoming Wasp\", \"#FFF1E3CA\": \"Welcoming White\", \"#FF6F6F6D\": \"Welded Iron\", \"#FF7C98AB\": \"Weldon Blue\", \"#FF00888B\": \"Well Blue\", \"#FF7E633F\": \"Well Read Variant\", \"#FF63ADB9\": \"Well Water\", \"#FF564537\": \"Well-Bred Brown\", \"#FF54606A\": \"Wellerman\", \"#FF4F6364\": \"Wellington\", \"#FFB9B5A4\": \"Wells Grey\", \"#FF26AD8D\": \"Wells of Wonder\", \"#FF22BB66\": \"Welsh Onion\", \"#FF3E2A2C\": \"Wenge Black\", \"#FF345362\": \"Wentworth\", \"#FF7E6152\": \"Werewolf Fur\", \"#FF5C512F\": \"West Coast Variant\", \"#FFE5823A\": \"West Side Variant\", \"#FF586D77\": \"West Winds\", \"#FFD4CFC5\": \"Westar Variant\", \"#FFA49D70\": \"Westcar Papyrus\", \"#FF797978\": \"Westchester Grey\", \"#FFE0D5CC\": \"Westchester White\", \"#FF5D3B31\": \"Western Brown\", \"#FF8B6A65\": \"Western Clay\", \"#FFBA816E\": \"Western Pink\", \"#FF8D5E41\": \"Western Pursuit\", \"#FF9B6959\": \"Western Red\", \"#FF8D876D\": \"Western Reserve\", \"#FFB28B80\": \"Western Ridge\", \"#FFBEAA99\": \"Western Sandstone\", \"#FFFADCA7\": \"Western Sky\", \"#FFDAA36F\": \"Western Sunrise\", \"#FFCDBB8D\": \"Western Wear\", \"#FFFCD450\": \"Westfall Yellow\", \"#FF2A4442\": \"Westhaven\", \"#FFF3EEE3\": \"Westhighland White\", \"#FF9C7C5B\": \"Westminster\", \"#FFA3623B\": \"Wet Adobe\", \"#FF5A6457\": \"Wet Aloeswood\", \"#FF989CAB\": \"Wet Asphalt\", \"#FF89877F\": \"Wet Cement\", \"#FF222023\": \"Wet Charcoal\", \"#FFA49690\": \"Wet Clay\", \"#FF353838\": \"Wet Concrete\", \"#FFD1584C\": \"Wet Coral\", \"#FF000B00\": \"Wet Crow\\u2019s Wing\", \"#FFA36C64\": \"Wet Desert Clay\", \"#FF162825\": \"Wet Foliage\", \"#FF001144\": \"Wet Latex\", \"#FFB9A023\": \"Wet Leaf\", \"#FF9E9F97\": \"Wet Pavement\", \"#FFE0816F\": \"Wet Pottery Clay\", \"#FF897870\": \"Wet River Rock\", \"#FFAE8F60\": \"Wet Sand\", \"#FF786D5F\": \"Wet Sandstone\", \"#FF8A96A0\": \"Wet Seal\", \"#FF50493C\": \"Wet Suit\", \"#FF907E6C\": \"Wet Taupe\", \"#FF929090\": \"Wet Weather\", \"#FF706B71\": \"Wetbar\", \"#FF7D949E\": \"Wethers Field\", \"#FF859488\": \"Wethersfield Moss\", \"#FFC1A98F\": \"Wetland Clay\", \"#FFA49F80\": \"Wetland Stone\", \"#FF71736A\": \"Wetlands\", \"#FF372418\": \"Wetlands Swamp\", \"#FF7C8181\": \"Whale\", \"#FFE5E7E4\": \"Whale Bone\", \"#FF59676B\": \"Whale Grey\", \"#FF607C8E\": \"Whale Shark\", \"#FF86878C\": \"Whale Tail\", \"#FFA5A495\": \"Whale Watching\", \"#FFC7D3D5\": \"Whale\\u2019s Mouth\", \"#FF115A82\": \"Whale\\u2019s Tale\", \"#FF2E7176\": \"Whaling Waters\", \"#FF65737E\": \"Wharf View\", \"#FFBBBCAE\": \"Wharf Wind\", \"#FF441122\": \"What We Do in the Shadows\", \"#FFFBDD7E\": \"Wheat Variant\", \"#FFBF923B\": \"Wheat Beer\", \"#FFDFBB7E\": \"Wheat Bread\", \"#FFDDD6CA\": \"Wheat Flour White\", \"#FFC7C088\": \"Wheat Grass\", \"#FF976B53\": \"Wheat Penny\", \"#FFE3D1C8\": \"Wheat Seed\", \"#FFDFD4C4\": \"Wheat Sheaf\", \"#FFD8B998\": \"Wheat Toast\", \"#FFA49A79\": \"Wheat Tortilla\", \"#FFAD935B\": \"Wheatacre\", \"#FFC8865E\": \"Wheatberry\", \"#FFFBEBBB\": \"Wheaten White\", \"#FFDFD7BD\": \"Wheatfield Variant\", \"#FF9E8451\": \"Wheatmeal\", \"#FFFFCD00\": \"Wheel of Dharma\", \"#FFB8BEBF\": \"Wheels Up!\", \"#FF584165\": \"When Blue Met Red\", \"#FF564375\": \"When Red Met Blue\", \"#FF585C79\": \"When Worlds Collide\", \"#FFC19851\": \"Where Buffalo Roam\", \"#FFC7CCCE\": \"Where There Is Smoke\", \"#FFDD262B\": \"Whero Red\", \"#FFD8D6C5\": \"Whetstone\", \"#FF9F6F55\": \"Whetstone Brown\", \"#FFDEE9CF\": \"Whiff of Green\", \"#FF00EBFF\": \"Whimsical Blue\", \"#FFECE4E2\": \"Whimsical White\", \"#FFED9987\": \"Whimsy\", \"#FFB0DCED\": \"Whimsy Blue\", \"#FFA09176\": \"Whipcord\", \"#FFC74547\": \"Whiplash\", \"#FFFFD299\": \"Whipped Apricot\", \"#FFF0EDD2\": \"Whipped Citron\", \"#FFEDECE7\": \"Whipped Coconut Cream\", \"#FFF2F0E7\": \"Whipped Cream\", \"#FFC7DDD6\": \"Whipped Mint\", \"#FFFACCAD\": \"Whipped Peach\", \"#FF9CCA84\": \"Whipped Pistachio\", \"#FFD8CBE0\": \"Whipped Plum\", \"#FFC9565A\": \"Whipped Strawberry\", \"#FFA1A8D5\": \"Whipped Violet\", \"#FFF2EEE0\": \"Whipped White\", \"#FFCEC1B5\": \"Whippet\", \"#FFFAF5E7\": \"Whipping Cream\", \"#FF9BA868\": \"Whirled Peas\", \"#FFE6CDCA\": \"Whirligig\", \"#FFDFD4C0\": \"Whirligig Geyser\", \"#FFA5D8CD\": \"Whirlpool\", \"#FFA7D0C5\": \"Whirlpool Green\", \"#FFE2D5D3\": \"Whirlwind\", \"#FFF6F1E2\": \"Whiskers\", \"#FFD29062\": \"Whiskey Variant\", \"#FF49463F\": \"Whiskey and Wine\", \"#FF85705F\": \"Whiskey Barrel\", \"#FFD4915D\": \"Whiskey Sour\", \"#FFC2877B\": \"Whisky\", \"#FF96745B\": \"Whisky Barrel\", \"#FF772233\": \"Whisky Cola\", \"#FFEEAA33\": \"Whisky Sour\", \"#FFEFE6E6\": \"Whisper Variant\", \"#FFE5E8F2\": \"Whisper Blue\", \"#FFCBEDE5\": \"Whisper of Grass\", \"#FFD4AFDA\": \"Whisper of Plum\", \"#FFCDA2AC\": \"Whisper of Rose\", \"#FFCBCECF\": \"Whisper of Smoke\", \"#FFEADBCA\": \"Whisper of White\", \"#FFD4C5B4\": \"Whisper Pink\", \"#FFC9C3B5\": \"Whisper Ridge\", \"#FFC7C0C5\": \"Whisper Soft\", \"#FFDFDED9\": \"Whisper Softly\", \"#FFFFE5B9\": \"Whisper Yellow\", \"#FF3F4855\": \"Whispered Secret\", \"#FFC8DCDC\": \"Whispering Blue\", \"#FFD7E5D8\": \"Whispering Frost\", \"#FFAC9D64\": \"Whispering Grasslands\", \"#FF536151\": \"Whispering Oaks\", \"#FFFEDCC3\": \"Whispering Peach\", \"#FFC8CAB5\": \"Whispering Pine\", \"#FFECECDA\": \"Whispering Rain\", \"#FFD8D8D4\": \"Whispering Smoke\", \"#FFE3E6DB\": \"Whispering Waterfall\", \"#FF919C81\": \"Whispering Willow\", \"#FFB7C3BF\": \"Whispering Winds\", \"#FFD6E9E6\": \"Whispery Breeze\", \"#FFC49E8F\": \"Whistler Rose\", \"#FFD7A98C\": \"White Acorn\", \"#FFEFEBE7\": \"White Alyssum\", \"#FFFEFEFE\": \"White as Heaven\", \"#FFECEABE\": \"White Asparagus\", \"#FFE4DFD0\": \"White Basics\", \"#FFE8EFEC\": \"White Bass\", \"#FFF5EFE5\": \"White Beach\", \"#FFE8D0B2\": \"White Bean Hummus\", \"#FFEBDFDD\": \"White Beet\", \"#FFE3E7E1\": \"White Blaze\", \"#FFF4ECDB\": \"White Blossom\", \"#FFCDD6DB\": \"White Blue\", \"#FFFBECD8\": \"White Blush\", \"#FFBFD0CB\": \"White Box\", \"#FFE3E0E8\": \"White Bud\", \"#FFDFDFDA\": \"White Bullet\", \"#FFB0B49B\": \"White Cabbage\", \"#FFFAECE1\": \"White Canvas\", \"#FFDBD5D1\": \"White Castle\", \"#FFF5DEC2\": \"White Cedar\", \"#FFF6F4F1\": \"White Chalk\", \"#FFE7DBDD\": \"White Cherry\", \"#FFF0E3C7\": \"White Chocolate\", \"#FFF4E8E8\": \"White Christmas\", \"#FFD6D0CC\": \"White City\", \"#FFE8E1D3\": \"White Clay\", \"#FFE8E3C9\": \"White Cliffs\", \"#FFF2F2ED\": \"White Cloud\", \"#FFE6E0D4\": \"White Coffee\", \"#FFF4F2F4\": \"White Convolvulus\", \"#FFF0D498\": \"White Corn\", \"#FFF9F8EF\": \"White Crest\", \"#FFF9EBC5\": \"White Currant\", \"#FFFDFAF1\": \"White Desert\", \"#FFEFEAE6\": \"White Dogwood\", \"#FFF5EEDE\": \"White Down\", \"#FFCECABA\": \"White Duck\", \"#FFEDEDED\": \"White Edgar\", \"#FFDEDEE5\": \"White Elephant\", \"#FFF2E9D3\": \"White Fence\", \"#FFFBF4E8\": \"White Fever\", \"#FFC8C2C0\": \"White Flag\", \"#FFF5EDE0\": \"White Flour\", \"#FFDEE6EC\": \"White Frost\", \"#FFF1EFE7\": \"White Fur\", \"#FFC9C2BD\": \"White Gauze\", \"#FFF1F1E1\": \"White Geranium\", \"#FFDDEEEE\": \"White Glaze\", \"#FFFFEEEE\": \"White Gloss\", \"#FFF0EFED\": \"White Glove\", \"#FFC8D1C4\": \"White Granite\", \"#FFBBCC99\": \"White Grape\", \"#FFFCF0DE\": \"White Grapefruit\", \"#FFD6E9CA\": \"White Green\", \"#FFE2E6D7\": \"White Hamburg Grapes\", \"#FFFDF9EF\": \"White Heat\", \"#FFE7E1D7\": \"White Heron\", \"#FFEAD8BB\": \"White Hot Chocolate\", \"#FFF3E5D1\": \"White Hyacinth\", \"#FFF9F6DD\": \"White Hydrangea\", \"#FFDFE2E7\": \"White Iris\", \"#FFD0D6A8\": \"White Jade\", \"#FFF7F4DF\": \"White Jasmine\", \"#FFDFDFDB\": \"White Kitten\", \"#FFE2E7E7\": \"White Lake\", \"#FFE1E2EB\": \"White Lavender\", \"#FFDEDEDC\": \"White Lie\", \"#FFE7E5E8\": \"White Lilac Variant\", \"#FFFAF0DB\": \"White Lily\", \"#FFEEE7DD\": \"White Linen Variant\", \"#FFE2DCD2\": \"White Luxe\", \"#FFF7F0E5\": \"White Luxury\", \"#FFF2E6DF\": \"White Meadow\", \"#FFECF3E1\": \"White Mecca\", \"#FFD1D1CF\": \"White Metal\", \"#FFEFEEE9\": \"White Mink\", \"#FFE0E7DA\": \"White Mint\", \"#FFF5F4E6\": \"White Mirage\", \"#FFE7DCCC\": \"White Mocha\", \"#FFEBEAE2\": \"White Moderne\", \"#FFD8D6C0\": \"White Moss\", \"#FFF6EDDB\": \"White Mountain\", \"#FFB9A193\": \"White Mouse\", \"#FFF8F6D8\": \"White Nectar\", \"#FFCE9F6F\": \"White Oak\", \"#FFE7E2DD\": \"White Opal\", \"#FFF5F3F5\": \"White Owl\", \"#FFF9E6DA\": \"White Peach\", \"#FFEDE1D1\": \"White Pearl\", \"#FFAE9E86\": \"White Pepper\", \"#FFF0EFEB\": \"White Picket Fence\", \"#FFDAD6CC\": \"White Pointer Variant\", \"#FFF8FBF8\": \"White Porcelain\", \"#FFC3BDAB\": \"White Primer\", \"#FFF6E8DF\": \"White Pudding\", \"#FFF8EEE7\": \"White Rabbit\", \"#FFE2E8CF\": \"White Radish\", \"#FFE5C28B\": \"White Raisin\", \"#FFD4CFB4\": \"White Rock Variant\", \"#FFF0E0DC\": \"White Russian\", \"#FFD2D4C3\": \"White Sage\", \"#FFEBEBE7\": \"White Sail\", \"#FFF5EBD8\": \"White Sand\", \"#FFE4EEEB\": \"White Sapphire\", \"#FFD9DED6\": \"White Sash\", \"#FF8C9FA1\": \"White Scar\", \"#FFD7E5EA\": \"White Sea\", \"#FFE4DBCE\": \"White Sesame\", \"#FFD1D3E0\": \"White Shadow\", \"#FFF1F0EC\": \"White Shoulders\", \"#FFEBE6D8\": \"White Silence\", \"#FFF4F5FA\": \"White Solid\", \"#FF9FBDAD\": \"White Spruce\", \"#FFFDE3B5\": \"White Strawberry\", \"#FFF1FAEA\": \"White Sulphur\", \"#FFF7F1E2\": \"White Swan\", \"#FFC5B8A8\": \"White Tiger\", \"#FFEFDBCD\": \"White Truffle\", \"#FF83CCD2\": \"White Ultramarine\", \"#FFC5DCB3\": \"White Vienna\", \"#FFEFE6D1\": \"White Warm Wool\", \"#FFEDEEEF\": \"White Whale\", \"#FFECF4DD\": \"White Willow\", \"#FFDEDBCE\": \"White Wisp\", \"#FFDED8D2\": \"White Woodruff\", \"#FFF2EFDE\": \"White Wool\", \"#FFF8EEE3\": \"White Zin\", \"#FFDEDBDE\": \"White-Collar\", \"#FFF3E8EA\": \"White-Red\", \"#FFDEE3DE\": \"Whitecap Foam\", \"#FFDBD0BC\": \"Whitecap Grey\", \"#FFFFFDFD\": \"Whitecap Snow\", \"#FF050D02\": \"Whiten\\u2019t\", \"#FFDEE0D2\": \"Whitened Sage\", \"#FFFBFBFB\": \"Whiteout\", \"#FFF8F9F5\": \"Whitest White\", \"#FFF4EEE5\": \"Whitetail\", \"#FFFEFFFC\": \"Whitewash\", \"#FFCAC9C0\": \"Whitewash Oak\", \"#FFFAF2E3\": \"Whitewashed Fence\", \"#FFAEC9DC\": \"Whiting Cottage\", \"#FFB2A188\": \"Whitney Oaks\", \"#FF8B7181\": \"Who-Dun-It\", \"#FFD4AE7E\": \"Whole Grain\", \"#FFA48B73\": \"Whole Wheat\", \"#FFAAA662\": \"Wholemeal Cookie\", \"#FFBEC1CF\": \"Whomp Grey\", \"#FF9BCA47\": \"Wicked Green\", \"#FF37115C\": \"Wicked Purple\", \"#FF5B984F\": \"Wicked Witch\", \"#FF847567\": \"Wicker Basket\", \"#FFFCE4AF\": \"Wickerware\", \"#FFC19E80\": \"Wickerwork\", \"#FF4F6C8F\": \"Wickford Bay\", \"#FF416FAF\": \"Wide Sky\", \"#FFF9D9D7\": \"Wide-Eyed\", \"#FF99AAFF\": \"Widowmaker\", \"#FF874E3C\": \"Wiener Dog\", \"#FFEE9900\": \"Wiener Schnitzel\", \"#FFFEF9D7\": \"Wild Apple\", \"#FFA53783\": \"Wild Aster\", \"#FF63775A\": \"Wild Axolotl\", \"#FFEAC37E\": \"Wild Bamboo\", \"#FF6B8372\": \"Wild Beet Leaf\", \"#FF7E3A3C\": \"Wild Berry\", \"#FF795745\": \"Wild Bill Brown\", \"#FF553322\": \"Wild Boar\", \"#FF5A4747\": \"Wild Boysenberry\", \"#FF47241A\": \"Wild Brown\", \"#FF1CD3A2\": \"Wild Caribbean Green\", \"#FF916D5D\": \"Wild Cattail\", \"#FFBC5D58\": \"Wild Chestnut\", \"#FF665134\": \"Wild Chocolate\", \"#FF93A3C1\": \"Wild Clary\", \"#FF6E3C42\": \"Wild Cranberry\", \"#FF7C3239\": \"Wild Currant\", \"#FFF4D967\": \"Wild Daffodil\", \"#FF8B8C89\": \"Wild Dove\", \"#FF545989\": \"Wild Elderberry\", \"#FF38914A\": \"Wild Forest\", \"#FF986A79\": \"Wild Geranium\", \"#FF825059\": \"Wild Ginger\", \"#FF80805D\": \"Wild Ginseng\", \"#FF5E496C\": \"Wild Grapes\", \"#FF998643\": \"Wild Grass\", \"#FF95856D\": \"Wild Hawk\", \"#FF9D7B74\": \"Wild Hemp\", \"#FFCEC7AA\": \"Wild Hillside\", \"#FFEECC00\": \"Wild Honey\", \"#FF8D6747\": \"Wild Horses\", \"#FF2F2F4A\": \"Wild Iris\", \"#FF6F7142\": \"Wild Jungle\", \"#FFA47FA3\": \"Wild Lavender\", \"#FFA5C1C0\": \"Wild Life\", \"#FFBEB8CD\": \"Wild Lilac\", \"#FFC4CD4F\": \"Wild Lime\", \"#FF684944\": \"Wild Manzanita\", \"#FFFFE2C7\": \"Wild Maple\", \"#FFA96388\": \"Wild Mulberry\", \"#FF84704B\": \"Wild Mushroom\", \"#FF695649\": \"Wild Mustang\", \"#FFCAA867\": \"Wild Mustard Seed\", \"#FFECDBC3\": \"Wild Oats\", \"#FF9C8042\": \"Wild Olive\", \"#FFD979A2\": \"Wild Orchid\", \"#FFB4B6DA\": \"Wild Orchid Blue\", \"#FF6373B4\": \"Wild Pansy\", \"#FFB97A77\": \"Wild Party\", \"#FF9EA5C3\": \"Wild Phlox\", \"#FF767C6B\": \"Wild Pigeon\", \"#FF83455D\": \"Wild Plum\", \"#FFB85B57\": \"Wild Poppy\", \"#FFD6C0AA\": \"Wild Porcini\", \"#FFEBDD99\": \"Wild Primrose\", \"#FF614746\": \"Wild Raisin\", \"#FFD5BFB4\": \"Wild Rice Variant\", \"#FF447382\": \"Wild River\", \"#FFCB7D96\": \"Wild Rose\", \"#FFB5A38C\": \"Wild Rye\", \"#FF7E877D\": \"Wild Sage\", \"#FFE7E4DE\": \"Wild Sand Variant\", \"#FF8A6F45\": \"Wild Seaweed\", \"#FF7C5644\": \"Wild Stallion\", \"#FF654243\": \"Wild Thing\", \"#FF9E9FB6\": \"Wild Thistle\", \"#FF7E9C6F\": \"Wild Thyme\", \"#FF463F3C\": \"Wild Truffle\", \"#FF63209B\": \"Wild Violet\", \"#FFFC6D84\": \"Wild Watermelon Variant\", \"#FF7E5C52\": \"Wild West\", \"#FFE0E1D1\": \"Wild Wheat\", \"#FF91857C\": \"Wild Wilderness\", \"#FFBECA60\": \"Wild Willow Variant\", \"#FF686B93\": \"Wild Wisteria\", \"#FFF5EEC0\": \"Wildcat Grey\", \"#FF8F886C\": \"Wilderness\", \"#FFC2BAA8\": \"Wilderness Grey\", \"#FFFF8833\": \"Wildfire\", \"#FF927D9B\": \"Wildflower\", \"#FFFFB3B1\": \"Wildflower Bouquet\", \"#FFC69C5D\": \"Wildflower Honey\", \"#FFCCCFE2\": \"Wildflower Prairie\", \"#FF5D9865\": \"Wildness Mint\", \"#FFCDB99B\": \"Wildwood\", \"#FFAA83A4\": \"Wilhelminian Pink\", \"#FFD7D8DD\": \"Will o\\u2019 the Wisp\", \"#FFDDC765\": \"Williams Pear Yellow\", \"#FF8C7A48\": \"Willow\", \"#FF59754D\": \"Willow Bough\", \"#FFDFE6CF\": \"Willow Brook Variant\", \"#FF93B881\": \"Willow Dyed\", \"#FFC3CABF\": \"Willow Green\", \"#FF817B69\": \"Willow Grey\", \"#FF69755C\": \"Willow Grove Variant\", \"#FF84C299\": \"Willow Hedge\", \"#FFA1A46D\": \"Willow Leaf\", \"#FF5B6356\": \"Willow Sooty Bamboo\", \"#FFE7E6E0\": \"Willow Springs\", \"#FF9E8F66\": \"Willow Tree\", \"#FFC8D5BB\": \"Willow Tree Mouse\", \"#FFD5DCA9\": \"Willow Wind\", \"#FF58504D\": \"Willow Wood\", \"#FFF0D29D\": \"Willow-Flower Yellow\", \"#FF929D81\": \"Willowbrook Manor\", \"#FF914681\": \"Willowherb\", \"#FFF3F2E8\": \"Willowside\", \"#FF886144\": \"Wilmington\", \"#FFBD9872\": \"Wilmington Tan\", \"#FFAB4C3D\": \"Wilted Brown\", \"#FFEEDAC9\": \"Wilted Leaf\", \"#FF626D5B\": \"Wimbledon\", \"#FFDDE3E7\": \"Wind Blown\", \"#FFB1C9DF\": \"Wind Blue\", \"#FF686C7B\": \"Wind Cave\", \"#FFDFE0E2\": \"Wind Chime\", \"#FFD5E2EE\": \"Wind Force\", \"#FFD0D8CF\": \"Wind Fresh White\", \"#FFC8DEEA\": \"Wind of Change\", \"#FFE8BABD\": \"Wind Rose\", \"#FFBFD6D9\": \"Wind Speed\", \"#FF6875B7\": \"Wind Star\", \"#FFC7DFE6\": \"Wind Tunnel\", \"#FFC5D1D8\": \"Wind Weaver\", \"#FFD5D8D7\": \"Windchill\", \"#FF84A7CE\": \"Windfall\", \"#FFBC9CA2\": \"Windflower\", \"#FF5B584C\": \"Windgate Hill\", \"#FFF5E6C9\": \"Windham Cream\", \"#FFC6BBA2\": \"Winding Path\", \"#FF62A5DF\": \"Windjammer\", \"#FFF5ECE7\": \"Windmill\", \"#FFA79B83\": \"Windmill Park\", \"#FFF0F1EC\": \"Windmill Wings\", \"#FFBCAFBB\": \"Window Box\", \"#FF989EA1\": \"Window Grey\", \"#FFE4ECDF\": \"Window Pane\", \"#FF7C8899\": \"Window Screen\", \"#FF018281\": \"Windows 95 Desktop\", \"#FF3778BF\": \"Windows Blue\", \"#FFCEBCAE\": \"Windrift Beige\", \"#FF5E6C62\": \"Windrock\", \"#FFDBD3C6\": \"Windrush\", \"#FFE0E1DA\": \"Winds Breath\", \"#FF462C77\": \"Windsor Variant\", \"#FFC4B49C\": \"Windsor Greige\", \"#FF626066\": \"Windsor Grey\", \"#FFA697A7\": \"Windsor Haze\", \"#FF545C4A\": \"Windsor Moss\", \"#FFC9AFD0\": \"Windsor Purple\", \"#FFCABBA1\": \"Windsor Tan\", \"#FFCCB490\": \"Windsor Toffee\", \"#FF9FC9E4\": \"Windsor Way\", \"#FF5F2E3D\": \"Windsor Wine\", \"#FF6D98C4\": \"Windstorm\", \"#FF91AAB8\": \"Windsurf\", \"#FF718BAE\": \"Windsurf Blue\", \"#FFD7E2DE\": \"Windsurfer\", \"#FF3A7099\": \"Windsurfing\", \"#FFD1F1F5\": \"Windswept\", \"#FFE3E4E5\": \"Windswept Beach\", \"#FFDBA480\": \"Windswept Canyon\", \"#FF9EB8BB\": \"Windswept Clouds\", \"#FFB7926B\": \"Windswept Leaves\", \"#FFC2E5E0\": \"Windwood Spring\", \"#FFBDD1D2\": \"Windy\", \"#FFAABAC6\": \"Windy Blue\", \"#FF88A3C2\": \"Windy City\", \"#FF8CB0CB\": \"Windy Day\", \"#FFB0A676\": \"Windy Meadow\", \"#FF3D604A\": \"Windy Pine\", \"#FF667F8B\": \"Windy Seas\", \"#FFE8EBE7\": \"Windy Sky\", \"#FF80013F\": \"Wine Variant\", \"#FFA33540\": \"Wine & Roses\", \"#FF772C30\": \"Wine and Unwind\", \"#FFAA5522\": \"Wine Barrel\", \"#FFD3D6C4\": \"Wine Bottle\", \"#FF254636\": \"Wine Bottle Green\", \"#FF5F3E3E\": \"Wine Brown\", \"#FF913338\": \"Wine Cask\", \"#FF70403D\": \"Wine Cellar\", \"#FF866D4C\": \"Wine Cork\", \"#FF602234\": \"Wine Country\", \"#FF96837D\": \"Wine Crush\", \"#FF673145\": \"Wine Dregs\", \"#FFE5D8E1\": \"Wine Frost\", \"#FF643B46\": \"Wine Goblet\", \"#FF941751\": \"Wine Grape\", \"#FF67334C\": \"Wine Gummy Red\", \"#FF355E4B\": \"Wine Leaf\", \"#FF864C58\": \"Wine Not\", \"#FF7B0323\": \"Wine Red Variant\", \"#FF69444F\": \"Wine Stain\", \"#FF8F7191\": \"Wine Stroll\", \"#FF492A34\": \"Wine Tasting\", \"#FF653B66\": \"Wine Tour\", \"#FFD7C485\": \"Wine Yellow\", \"#FF663366\": \"Wineberry\", \"#FF433748\": \"Wineshade\", \"#FF0065AC\": \"Wing Commander\", \"#FF5A6868\": \"Wing Man\", \"#FFEBE4E2\": \"Winged Victory\", \"#FFEFE8D7\": \"Wings of an Angel\", \"#FF9EBBDA\": \"Wings of Pegasus\", \"#FFBAD5D4\": \"Wingsuit Wind\", \"#FF7792AF\": \"Wink\", \"#FF365771\": \"Winner\\u2019s Circle\", \"#FFF0DCCB\": \"Winners Shower\", \"#FF894144\": \"Winning Red\", \"#FF636653\": \"Winning Ticket\", \"#FFE0CFC2\": \"Winsome Beige\", \"#FFE7E9E4\": \"Winsome Grey\", \"#FFA7D8E1\": \"Winsome Hue\", \"#FFCCACC1\": \"Winsome Orchid\", \"#FFC28BA1\": \"Winsome Rose\", \"#FFB0A6C2\": \"Winter Amethyst\", \"#FF314747\": \"Winter Balsam\", \"#FFB8C8D3\": \"Winter Blizzard\", \"#FF582D48\": \"Winter Bloom\", \"#FFBDB5B3\": \"Winter Calm\", \"#FF8ECED8\": \"Winter Chill\", \"#FF83C7DF\": \"Winter Chime\", \"#FF45494C\": \"Winter Coat\", \"#FFBAAAA7\": \"Winter Cocoa\", \"#FF6E7A7C\": \"Winter Could Grey\", \"#FFDEDAD8\": \"Winter Dawn\", \"#FFE3E7E9\": \"Winter Day\", \"#FF9B8767\": \"Winter Delta\", \"#FFF5F1EA\": \"Winter Doldrums\", \"#FFB8B8CB\": \"Winter Dusk\", \"#FFB4E5EC\": \"Winter Escape\", \"#FF476476\": \"Winter Evening\", \"#FFBCAF9E\": \"Winter Feather\", \"#FF9CA4A5\": \"Winter Flannel\", \"#FFD6EEDD\": \"Winter Fresh\", \"#FFE4DECD\": \"Winter Frost\", \"#FFC4D2D0\": \"Winter Garden\", \"#FFEAEBE0\": \"Winter Glaze\", \"#FF48907B\": \"Winter Green\", \"#FF5E737D\": \"Winter Harbor\", \"#FFE1E6EB\": \"Winter Haven\", \"#FFCEC9C1\": \"Winter Haze\", \"#FFD0C383\": \"Winter Hazel Variant\", \"#FF798772\": \"Winter Hedge\", \"#FFDBDFE9\": \"Winter Ice\", \"#FFD8D2C7\": \"Winter in New York\", \"#FF6E878B\": \"Winter in Paris\", \"#FF5C97CF\": \"Winter Lake\", \"#FFB7FFFA\": \"Winter Meadow\", \"#FFE7FBEC\": \"Winter Mist\", \"#FFD1C295\": \"Winter Mood\", \"#FFD9D9D6\": \"Winter Morn\", \"#FFFDEBD8\": \"Winter Morning\", \"#FFA7B3B5\": \"Winter Morning Mist\", \"#FF676449\": \"Winter Moss\", \"#FFA99F97\": \"Winter Nap\", \"#FF63594B\": \"Winter Oak\", \"#FFF2FAED\": \"Winter Oasis\", \"#FFE7E3E7\": \"Winter Orchid\", \"#FF41638A\": \"Winter Palace\", \"#FF95928D\": \"Winter Park\", \"#FF8E9549\": \"Winter Pea Green\", \"#FFEBD9D0\": \"Winter Peach\", \"#FFB0B487\": \"Winter Pear\", \"#FFC7A55F\": \"Winter Pear Beige\", \"#FFAE3C3D\": \"Winter Poinsettia\", \"#FFAAA99D\": \"Winter Rye\", \"#FFAA9D80\": \"Winter Sage\", \"#FFDAC7BA\": \"Winter Savanna\", \"#FFBECEDB\": \"Winter Scene\", \"#FF303E55\": \"Winter Sea\", \"#FF4F6B79\": \"Winter Shadow\", \"#FFE3EFDD\": \"Winter Shamrock\", \"#FFA9C0CB\": \"Winter Sky Variant\", \"#FF49545C\": \"Winter Solstice\", \"#FFACB99F\": \"Winter Squash\", \"#FF4B7079\": \"Winter Storm\", \"#FFE8DADD\": \"Winter Sunrise\", \"#FFCA6636\": \"Winter Sunset\", \"#FF7FB9AE\": \"Winter Surf\", \"#FF4090A2\": \"Winter Time\", \"#FF877C6D\": \"Winter Twig\", \"#FF80A9B8\": \"Winter Twilight\", \"#FFE0E7E0\": \"Winter Veil\", \"#FFD8D5CC\": \"Winter Walk\", \"#FF21424D\": \"Winter Waves\", \"#FF3E474C\": \"Winter Way\", \"#FFF1E4DC\": \"Winter Wedding\", \"#FFDCBE97\": \"Winter Wheat\", \"#FFF5ECD2\": \"Winter White\", \"#FFC1D8AC\": \"Winter Willow Green\", \"#FFA0E6FF\": \"Winter Wizard\", \"#FFB3BFC8\": \"Winter Wonderland\", \"#FFDEECED\": \"Winter\\u2019s Breath\", \"#FFB4474D\": \"Winterberry Frost\", \"#FF20F986\": \"Wintergreen\", \"#FFC6E5CA\": \"Wintergreen Mint\", \"#FF4F9E81\": \"Wintergreen Shadow\", \"#FF94D2BF\": \"Wintermint\", \"#FFBDD4DE\": \"Winterscape\", \"#FFB5AFFF\": \"Winterspring Lilac\", \"#FF786DAA\": \"Wintertime Mauve\", \"#FF8BA494\": \"Wintessa\", \"#FFFDE6D6\": \"Winthrop Peach\", \"#FFA7AFAC\": \"Wintry Sky\", \"#FF8B7180\": \"Wiped Out\", \"#FF3E8094\": \"Wipeout\", \"#FFE2E3D8\": \"Wisdom\", \"#FFCDBBA5\": \"Wise Owl\", \"#FFB6BCDF\": \"Wish\", \"#FF447F8A\": \"Wish Upon a Star\", \"#FF53786A\": \"Wishard\", \"#FFD8DDE6\": \"Wishful Blue\", \"#FFC8E2CC\": \"Wishful Green\", \"#FFFCDADF\": \"Wishful Thinking\", \"#FFF4F1E8\": \"Wishful White\", \"#FF604F5A\": \"Wishing Star\", \"#FF9A834B\": \"Wishing Troll\", \"#FFD0D1C1\": \"Wishing Well\", \"#FFEBDEDB\": \"Wishy-Washy Beige\", \"#FFC6E0E1\": \"Wishy-Washy Blue\", \"#FFD1C2C2\": \"Wishy-Washy Brown\", \"#FFDFEAE1\": \"Wishy-Washy Green\", \"#FFDEEDE4\": \"Wishy-Washy Lichen\", \"#FFF5DFE7\": \"Wishy-Washy Lilies\", \"#FFEEF5DB\": \"Wishy-Washy Lime\", \"#FFEDDDE4\": \"Wishy-Washy Mauve\", \"#FFDDE2D9\": \"Wishy-Washy Mint\", \"#FFF0DEE7\": \"Wishy-Washy Pink\", \"#FFE1DADD\": \"Wishy-Washy Red\", \"#FFE9E9D5\": \"Wishy-Washy Yellow\", \"#FFF2A599\": \"Wisley Pink\", \"#FFA9BADD\": \"Wisp\", \"#FFC2DCB4\": \"Wisp Green\", \"#FFD9C6B2\": \"Wisp of Cocoa\", \"#FFE5E7E9\": \"Wisp of Smoke\", \"#FFF9E8E2\": \"Wisp Pink Variant\", \"#FFC6AEAA\": \"Wispy Mauve\", \"#FFBCC7A4\": \"Wispy Mint\", \"#FFF3EBEA\": \"Wispy Pink\", \"#FFD8DCE1\": \"Wispy Skies\", \"#FFFFC196\": \"Wispy White\", \"#FFA87DC2\": \"Wisteria Variant\", \"#FF84A2D4\": \"Wisteria Blue\", \"#FFBBBCDE\": \"Wisteria Fragrance\", \"#FFA6A8C5\": \"Wisteria Light Soft Blue\", \"#FFE6C8FF\": \"Wisteria Powder\", \"#FF875F9A\": \"Wisteria Purple\", \"#FFCED9DC\": \"Wisteria Snow\", \"#FFB2ADBF\": \"Wisteria Trellis\", \"#FFE4CADC\": \"Wisteria Whisper\", \"#FFF7C114\": \"Wisteria Yellow\", \"#FFB2A7CC\": \"Wisteria-Wise\", \"#FFA29ECD\": \"Wistful Variant\", \"#FFEADDD7\": \"Wistful Beige\", \"#FFE33928\": \"Wistful Longing\", \"#FF966F77\": \"Wistful Mauve\", \"#FFAA9966\": \"Wistman\\u2019s Wood\", \"#FF888738\": \"Witch Brew\", \"#FFFBF073\": \"Witch Hazel\", \"#FF8E8976\": \"Witch Hazel Leaf\", \"#FF692746\": \"Witch Soup\", \"#FF113300\": \"Witch Wart\", \"#FF7C4A33\": \"Witch Wood\", \"#FF4C3D29\": \"Witch\\u2019s Cottage\", \"#FF474C50\": \"Witchcraft\", \"#FF35343F\": \"Witches Cauldron\", \"#FF4F4552\": \"Witching\", \"#FFD1D1BB\": \"With a Twist\", \"#FFBCA380\": \"With the Grain\", \"#FFC5B692\": \"Withered Moss\", \"#FFA26766\": \"Withered Rose\", \"#FF90C0C9\": \"Witness\", \"#FFB1D99D\": \"Witty Green\", \"#FF4D5B88\": \"Wizard\", \"#FF0073CF\": \"Wizard Blue\", \"#FF525E68\": \"Wizard Grey\", \"#FF6D4660\": \"Wizard Time\", \"#FFDFF1FD\": \"Wizard White\", \"#FFA090B8\": \"Wizard\\u2019s Brew\", \"#FF5D6098\": \"Wizard\\u2019s Potion\", \"#FF584B4E\": \"Wizard\\u2019s Spell\", \"#FF007C76\": \"Wizards Orb\", \"#FF597FB9\": \"Woad Blue\", \"#FF6C9898\": \"Woad Indigo\", \"#FF584769\": \"Woad Purple\", \"#FF788389\": \"Wolf\", \"#FFA8FF04\": \"Wolf Lichen\", \"#FF78776F\": \"Wolf Pack\", \"#FF3D343F\": \"Wolf\\u2019s Bane\", \"#FF5C5451\": \"Wolf\\u2019s Fur\", \"#FFB5B6B7\": \"Wolfram\", \"#FF91989D\": \"Wolverine\", \"#FFEF8E9F\": \"Wonder Lust\", \"#FFA085A6\": \"Wonder Violet\", \"#FF635D63\": \"Wonder Wine\", \"#FFA97898\": \"Wonder Wish\", \"#FFABCB7B\": \"Wonder Woods\", \"#FF718A70\": \"Wonderland\", \"#FFB8CDDD\": \"Wondrous Blue\", \"#FFA3B1F2\": \"Wondrous Wisteria\", \"#FF4A2559\": \"Wonka Purple\", \"#FFD0A46D\": \"Wonton Dumpling\", \"#FF645A56\": \"Wood Acres\", \"#FFD7CAB0\": \"Wood Ash\", \"#FFFBEEAC\": \"Wood Avens\", \"#FF302621\": \"Wood Bark Variant\", \"#FF464646\": \"Wood Charcoal\", \"#FF90835E\": \"Wood Chi\", \"#FF7A7229\": \"Wood Garlic\", \"#FFA78C59\": \"Wood Green\", \"#FFA08475\": \"Wood Lake\", \"#FFEBA0A7\": \"Wood Nymph\", \"#FFAABBCC\": \"Wood Pigeon\", \"#FF796A4E\": \"Wood Stain Brown\", \"#FFA47D43\": \"Wood Thrush\", \"#FF78426F\": \"Wood Violet\", \"#FF584043\": \"Wood-Black Red\", \"#FF61633F\": \"Wood\\u2019s Creek\", \"#FF8A8A36\": \"Woodbine\", \"#FF847451\": \"Woodbridge\", \"#FFB3987D\": \"Woodbridge Trail\", \"#FF463629\": \"Woodburn\", \"#FF8E746C\": \"Woodchuck\", \"#FF8F847A\": \"Woodcraft\", \"#FFB59B7E\": \"Wooded Acre\", \"#FF765A3F\": \"Wooden Cabin\", \"#FF745C51\": \"Wooden Nutmeg\", \"#FFA89983\": \"Wooden Peg\", \"#FFA58563\": \"Wooden Swing\", \"#FFDFB07E\": \"Wooden Sword\", \"#FF815A48\": \"Wooden Wagon\", \"#FF996633\": \"Woodgrain\", \"#FF9E7B6C\": \"Woodhaven\", \"#FF96856A\": \"Woodkraft\", \"#FF626746\": \"Woodland Variant\", \"#FF5F4737\": \"Woodland Brown\", \"#FF004400\": \"Woodland Grass\", \"#FF5C645C\": \"Woodland Moss\", \"#FF475C5D\": \"Woodland Night\", \"#FF69804B\": \"Woodland Nymph\", \"#FFA4A393\": \"Woodland Sage\", \"#FF127A49\": \"Woodland Soul\", \"#FFB09B89\": \"Woodland Stone\", \"#FF8B8D63\": \"Woodland Walk\", \"#FFD8D5D2\": \"Woodland Wildflower\", \"#FF0D6323\": \"Woodland Wonder\", \"#FF405B50\": \"Woodlawn Green\", \"#FF4B5D31\": \"Woodman\", \"#FFAC8989\": \"Woodrose\", \"#FF8B9916\": \"Woodruff Green\", \"#FF45402B\": \"Woodrush Variant\", \"#FF2B3230\": \"Woodsmoke Variant\", \"#FF9B8A5F\": \"Woodstock\", \"#FFE9CAB6\": \"Woodstock Rose\", \"#FF3D271D\": \"Woodsy Brown\", \"#FF755F4A\": \"Woodward Park\", \"#FF6E2D2B\": \"Woody Brown Variant\", \"#FF40446C\": \"Wooed\", \"#FF5F655A\": \"Woohringa\", \"#FFAD9A90\": \"Wool Coat\", \"#FFD9CFBA\": \"Wool Skein\", \"#FF005152\": \"Wool Turquoise\", \"#FF917747\": \"Wool Tweed\", \"#FF5E5587\": \"Wool Violet\", \"#FFDBBDAA\": \"Wool-Milk Pig\", \"#FFB59F55\": \"Woollen Mittens\", \"#FFDCC9AD\": \"Woollen Sox\", \"#FFB0A582\": \"Woollen Vest\", \"#FFE7D5C9\": \"Woolly Beige\", \"#FFF1EBE4\": \"Woolly Lamb\", \"#FFBB9C7C\": \"Woolly Mammoth\", \"#FFBDE7CF\": \"Woolly Mint\", \"#FF907E63\": \"Woolly Thyme\", \"#FFA5A192\": \"Wooster Smoke\", \"#FF572B26\": \"Worcestershire Sauce\", \"#FFF2BE96\": \"Word of Mouth\", \"#FF004D67\": \"Work Blue\", \"#FFCDA366\": \"Workbench\", \"#FFBFE6D2\": \"Workout Green\", \"#FFFFD789\": \"Workout Routine\", \"#FF02667B\": \"Workshop Blue\", \"#FF005477\": \"World Peace\", \"#FF03667B\": \"World\\u2019s Away\", \"#FFCEC6BF\": \"Worldly Grey\", \"#FF98978D\": \"Worlds Away\", \"#FF9FAE9E\": \"Wormwood Green\", \"#FF4282C6\": \"Worn Denim\", \"#FFD4DED4\": \"Worn Jade Tiles\", \"#FFA69C81\": \"Worn Khaki\", \"#FF6F6C0A\": \"Worn Olive\", \"#FFE8DBD3\": \"Worn Wood\", \"#FF634333\": \"Worn Wooden\", \"#FFAB9379\": \"Worsted Tan\", \"#FFE0D1A0\": \"Woven\", \"#FF8E7B58\": \"Woven Basket\", \"#FFCABBB4\": \"Woven Cashmere\", \"#FFDCB639\": \"Woven Gold\", \"#FFC9AB96\": \"Woven Jute\", \"#FFCEAD8E\": \"Woven Navajo\", \"#FFF1DFC0\": \"Woven Raffia\", \"#FFDDDCBF\": \"Woven Reed\", \"#FFC1AC8B\": \"Woven Straw\", \"#FFB99974\": \"Woven Wicker\", \"#FFECEAD0\": \"Wrack White\", \"#FF5F6D6E\": \"Wrapped in Twilight\", \"#FF76856A\": \"Wreath\", \"#FF4A4139\": \"Wren\", \"#FF71635E\": \"Wright Brown\", \"#FFE9D6BD\": \"Writer\\u2019s Parchment\", \"#FFF1E6CF\": \"Writing Paper\", \"#FF474749\": \"Wrought Iron\", \"#FFF8D106\": \"Wu-Tang Gold\", \"#FFCE7639\": \"Wulfenite\", \"#FF86A96F\": \"Wyvern Green\", \"#FFE6474A\": \"X Marks the Spot\", \"#FFFEF2DC\": \"X\\u00e2kestari White\", \"#FFFFEE55\": \"Xanthe Yellow\", \"#FFF4E216\": \"Xanthic Variant\", \"#FF4A3E00\": \"Xanthophobia\", \"#FF6AB4E0\": \"Xavier Blue\", \"#FF30A9FF\": \"Xed\", \"#FF847E54\": \"Xena\", \"#FFB7C0D7\": \"Xenon Blue\", \"#FF7D0061\": \"Xereus Purple\", \"#FFE60626\": \"Xi\\u0101n H\\u00f3ng Red\", \"#FFECE6D1\": \"Xi\\u00e0ng Y\\u00e1 B\\u00e1i Ivory\", \"#FFBCB7B0\": \"Xiao Long Bao Dumpling\", \"#FFFCE166\": \"X\\u00ecng Hu\\u00e1ng Yellow\", \"#FFCC1166\": \"X\\u012bpe Tot\\u0113c Red\", \"#FF990020\": \"Xmas Candy\", \"#FFF08497\": \"Xoxo\", \"#FF679BB3\": \"Yacht Blue\", \"#FF566062\": \"Yacht Club\", \"#FF485783\": \"Yacht Club Blue\", \"#FF7C9DAE\": \"Yacht Harbour\", \"#FFFABBA9\": \"Yahoo\", \"#FFECAB3F\": \"Yakitori\", \"#FF0F4D92\": \"Yale Blue Tint\", \"#FFC98431\": \"Yam\", \"#FFFFA400\": \"Yamabuki Gold\", \"#FFCB7E1F\": \"Yamabukicha Gold\", \"#FF9C8A4D\": \"Yanagicha\", \"#FF8C9E5E\": \"Yanagizome Green\", \"#FFF1A141\": \"Y\\u00e1ng Ch\\u00e9ng Orange\", \"#FFEDE8DD\": \"Yang Mist\", \"#FF4D5A6B\": \"Yankee Doodle\", \"#FF1C2841\": \"Yankees Blue\", \"#FF9E826A\": \"Yardbird\", \"#FFDCCFB6\": \"Yarmouth Oyster\", \"#FFD8AD39\": \"Yarrow\", \"#FF547497\": \"Yawl\", \"#FF7C6C57\": \"Ye Olde Rustic Colour\", \"#FFAD896A\": \"Yearling\", \"#FF061088\": \"Yearning\", \"#FFCA135E\": \"Yearning Desire\", \"#FFFAE1AC\": \"Yeast\", \"#FFFFFE00\": \"Yell for Yellow\", \"#FFB68D4C\": \"Yellow Acorn\", \"#FFF5F5D9\": \"Yellow Avarice\", \"#FFF9EED0\": \"Yellow Beam\", \"#FFE3C08D\": \"Yellow Beige\", \"#FFFFDD33\": \"Yellow Bell Pepper\", \"#FFF1CD7B\": \"Yellow Bird\", \"#FFF4EABA\": \"Yellow Bliss\", \"#FFFDF4BB\": \"Yellow Blitz\", \"#FFFAF3CF\": \"Yellow Bombinate\", \"#FFF9F6E8\": \"Yellow Bonnet\", \"#FFEAC853\": \"Yellow Brick Road\", \"#FFAE8B0C\": \"Yellow Brown\", \"#FFEEDD11\": \"Yellow Buzzing\", \"#FFFFEAAC\": \"Yellow Canary\", \"#FFF5F9AD\": \"Yellow Chalk\", \"#FFEDB856\": \"Yellow Coneflower\", \"#FFFFDE88\": \"Yellow Corn\", \"#FFEED36C\": \"Yellow Cream\", \"#FFF7C66B\": \"Yellow Currant\", \"#FFF6F1D7\": \"Yellow Diamond\", \"#FFF8E47E\": \"Yellow Dragon\", \"#FFD8E63C\": \"Yellow Duranta\", \"#FFF0F0D9\": \"Yellow Emulsion\", \"#FFD2CC81\": \"Yellow Endive\", \"#FFFCE1B6\": \"Yellow Essence\", \"#FFFFB102\": \"Yellow Exhilaration\", \"#FFFFCA00\": \"Yellow Flash\", \"#FFFFE1A0\": \"Yellow Geranium\", \"#FFBE8400\": \"Yellow Gold\", \"#FFC8FD3D\": \"Yellow Green Soft\", \"#FFF7B930\": \"Yellow Groove\", \"#FFEDE68A\": \"Yellow Iris\", \"#FFFFCC3A\": \"Yellow Jacket\", \"#FFDAA436\": \"Yellow Jasper\", \"#FFFFD379\": \"Yellow Jubilee\", \"#FFDAB46F\": \"Yellow Lab\", \"#FFF6D099\": \"Yellow Lotus\", \"#FFCCAA4D\": \"Yellow Lupine\", \"#FFDCC449\": \"Yellow Magic Orchestra\", \"#FFC0A85A\": \"Yellow Maize\", \"#FFFDFCBF\": \"Yellow Mana\", \"#FFD28034\": \"Yellow Mandarin\", \"#FFF6D255\": \"Yellow Mask\", \"#FFF0D31E\": \"Yellow Mellow\", \"#FF73633E\": \"Yellow Metal Variant\", \"#FF95804A\": \"Yellow Nile\", \"#FFC39143\": \"Yellow Ochre\", \"#FFEAAD04\": \"Yellow of Izamal\", \"#FFFCB001\": \"Yellow Orange Variant\", \"#FFEADCC6\": \"Yellow Page\", \"#FFE9DF8A\": \"Yellow Pear\", \"#FFEEEF06\": \"Yellow Pepper\", \"#FFF0E74B\": \"Yellow Petal\", \"#FFE4E4CB\": \"Yellow Phosphenes\", \"#FFFCB867\": \"Yellow Polka Dot\", \"#FFFCFD74\": \"Yellow Powder\", \"#FFE6E382\": \"Yellow Press\", \"#FFFFF47C\": \"Yellow Salmonberry\", \"#FFFDEE73\": \"Yellow Sand\", \"#FFF49F35\": \"Yellow Sea Variant\", \"#FFD19932\": \"Yellow Shout\", \"#FFFFFF14\": \"Yellow Submarine\", \"#FFE19447\": \"Yellow Sumac\", \"#FFF9B500\": \"Yellow Summer\", \"#FFFFF601\": \"Yellow Sunshine\", \"#FFF7EDB7\": \"Yellow Taffy\", \"#FFFFF29D\": \"Yellow Tail\", \"#FFF9D988\": \"Yellow Trumpet\", \"#FFF6D06E\": \"Yellow Tulip\", \"#FFEAB565\": \"Yellow Varnish\", \"#FFFFBA6F\": \"Yellow Warbler\", \"#FFC69035\": \"Yellow Warning\", \"#FFEDE5B7\": \"Yellow Wax Pepper\", \"#FFFEF6BE\": \"Yellow Yarn\", \"#FFFFEE33\": \"Yellow-Bellied\", \"#FFC8CD37\": \"Yellow-Green Grosbeak\", \"#FFEEBB77\": \"Yellow-Rumped Warbler\", \"#FFF6F1C4\": \"Yellowed Bone\", \"#FFFAEE66\": \"Yellowish\", \"#FF9B7A01\": \"Yellowish Brown\", \"#FFB0DD16\": \"Yellowish Green\", \"#FFEDEEDA\": \"Yellowish Grey\", \"#FFFFAB0F\": \"Yellowish Orange\", \"#FFFCFC81\": \"Yellowish Tan\", \"#FFE9F1D0\": \"Yellowish White\", \"#FFF3D80E\": \"Yellowl\", \"#FFCEB736\": \"Yellowstone\", \"#FFE4D6BA\": \"Yellowstone Park\", \"#FFC8C48F\": \"Yerba Mate\", \"#FFC7D7E0\": \"Yeti Footprint\", \"#FFABBC01\": \"Yew\", \"#FF656952\": \"Yew Hedge\", \"#FFE0E1E2\": \"Y\\u00edn B\\u00e1i Silver\", \"#FF848999\": \"Yin H\\u016bi Silver\", \"#FF3B3C3C\": \"Yin Mist\", \"#FFB1C4CB\": \"Y\\u00edn S\\u00e8 Silver\", \"#FF05FFA6\": \"Y\\u00edng Gu\\u0101ng S\\u00e8 Green\", \"#FFFF69AF\": \"Y\\u00edng Gu\\u0101ng S\\u00e8 Pink\", \"#FF632DE9\": \"Y\\u00edng Gu\\u0101ng S\\u00e8 Purple\", \"#FF265EF7\": \"YInMn Blue\", \"#FFF9F59F\": \"Yippie Ya Yellow\", \"#FFFFFF84\": \"Yippie Yellow\", \"#FFE3E4D2\": \"Yoga Daze\", \"#FFFFECC3\": \"Yoghurt\", \"#FFF5E9CE\": \"Yoghurt Br\\u00fbl\\u00e9e\", \"#FF8A8C66\": \"Yogi\", \"#FFA291BA\": \"Yolanda\", \"#FFD5A585\": \"Yolande\", \"#FFEEC701\": \"Yolk\", \"#FFE2B051\": \"Yolk Yellow\", \"#FFAA987F\": \"York Beige\", \"#FFF3D9C7\": \"York Bisque\", \"#FFD3BFE5\": \"York Plum\", \"#FF67706D\": \"York River Green\", \"#FF735C53\": \"Yorkshire Brown\", \"#FFBAC3CC\": \"Yorkshire Cloud\", \"#FF55AA00\": \"Yoshi\", \"#FFEE7776\": \"You\\u2019re Blushing\", \"#FFFCD8B5\": \"Young Apricot\", \"#FFD5A1A9\": \"Young at Heart\", \"#FF68BE8D\": \"Young Bamboo\", \"#FF86AF38\": \"Young Bud\", \"#FF938C83\": \"Young Colt\", \"#FFF6A09D\": \"Young Crab\", \"#FFC3B4B3\": \"Young Fawn\", \"#FF71BC78\": \"Young Fern\", \"#FFAAC0AD\": \"Young Gecko\", \"#FFC3D825\": \"Young Grass\", \"#FFAACF53\": \"Young Green Onion\", \"#FF97D499\": \"Young Greens\", \"#FFB0C86F\": \"Young Leaf\", \"#FF232323\": \"Young Night\", \"#FFF2E1D2\": \"Young Peach\", \"#FFACC729\": \"Young Plum\", \"#FFB28EBC\": \"Young Prince\", \"#FFBC64A4\": \"Young Purple\", \"#FFFFB6B4\": \"Young Salmon\", \"#FFFFA474\": \"Young Tangerine\", \"#FFC9AFA9\": \"Young Turk\", \"#FFDCDF9D\": \"Young Wheat\", \"#FFB9B58E\": \"Young Willow\", \"#FF220044\": \"Your Darkness\", \"#FF61496E\": \"Your Majesty\", \"#FFFFC5BB\": \"Your Pink Variant\", \"#FF787E93\": \"Your Shadow\", \"#FFFBD9CD\": \"Yours Truly\", \"#FFE2C9C8\": \"Youth\", \"#FFEE8073\": \"Youthful Coral\", \"#FFA7B3B7\": \"Yreka!\", \"#FFC0E2E1\": \"Y\\u00f9 Sh\\u00ed B\\u00e1i White\", \"#FFE9AF78\": \"Yucatan\", \"#FFF2EFE0\": \"Yucatan White Haba\\u00f1ero\", \"#FF75978F\": \"Yucca\", \"#FFA1D7C9\": \"Yucca Cream\", \"#FFF2EAD5\": \"Yucca White\", \"#FF2138AB\": \"Yu\\u00e8 Gu\\u0101ng L\\u00e1n Blue\", \"#FF5959AB\": \"Yu\\u00e8 Gu\\u0101ng L\\u00e1n Moonlight\", \"#FF826A21\": \"Yukon Gold Variant\", \"#FFC58A78\": \"Yum Raw Spam\", \"#FFC7B882\": \"Yuma Variant\", \"#FFFFD678\": \"Yuma Gold\", \"#FFCFC5AE\": \"Yuma Sand\", \"#FF1F911F\": \"Yushan Green\", \"#FFFDD200\": \"Yuzu Jam\", \"#FFFFD766\": \"Yuzu Marmalade\", \"#FF112200\": \"Yuzu Soy\", \"#FFD4DE49\": \"Yuzukosh\\u014d\", \"#FFEC6D71\": \"Zahri Pink\", \"#FF6B5A5A\": \"Zambezi Variant\", \"#FFFF990E\": \"Zambia\", \"#FFDDA026\": \"Zamesi Desert\", \"#FFB2C6B1\": \"Zanah Variant\", \"#FFD38977\": \"Zanci\", \"#FFA39A61\": \"Zandri Dust\", \"#FF823C3D\": \"Zangief\\u2019s Chest\", \"#FFE47486\": \"Zany Pink\", \"#FF7E6765\": \"Zanzibar\", \"#FF8E7163\": \"Zanzibar Spice\", \"#FFC1264C\": \"Z\\u01ceo H\\u00f3ng Maroon\", \"#FFF1F3F3\": \"Zappy Zebra\", \"#FFFDE634\": \"Zard Yellow\", \"#FF60A448\": \"Zatar Leaf\", \"#FFCEC6BB\": \"Zebra Finch\", \"#FF9DA286\": \"Zebra Grass\", \"#FF0090AD\": \"Zeftron\", \"#FF016612\": \"Zelyony Green\", \"#FFCFD9DE\": \"Zen\", \"#FF99A4BA\": \"Zen Blue\", \"#FFC6BFA7\": \"Zen Essence\", \"#FFD1DAC0\": \"Zen Garden\", \"#FF445533\": \"Zen Garden Olive\", \"#FFBAB8AD\": \"Zen Pebble\", \"#FF5B5D5C\": \"Zen Retreat\", \"#FF497A9F\": \"Zenith\", \"#FFA6C8C7\": \"Zenith Heights\", \"#FF424F3B\": \"Zepheniah\\u2019s Greed\", \"#FFC39EA3\": \"Zephyr\", \"#FF7AB091\": \"Zephyr Green\", \"#FFDDD9C4\": \"Zero Degrees\", \"#FF332233\": \"Zero Gravity\", \"#FFC6723B\": \"Zest Variant\", \"#FF92A360\": \"Zesty Apple\", \"#FF3B3C38\": \"Zeus Variant\", \"#FF3C343D\": \"Zeus Palace\", \"#FF660077\": \"Zeus Purple\", \"#FF6C94CD\": \"Zeus Temple\", \"#FFEEFF00\": \"Zeus\\u2019s Bolt\", \"#FFFEF200\": \"Zheleznogorsk Yellow\", \"#FFF8F8F9\": \"Zh\\u0113n Zh\\u016b B\\u00e1i Pearl\", \"#FFE4C500\": \"Zhohltyi Yellow\", \"#FFCB464A\": \"Zh\\u016b H\\u00f3ng Vermillion\", \"#FF9F0FEF\": \"Z\\u01d0 L\\u00fao L\\u00e1n S\\u00e8 Violet\", \"#FFC94CBE\": \"Z\\u01d0 S\\u00e8 Purple\", \"#FF082903\": \"Zia Olive\", \"#FF81A6AA\": \"Ziggurat Variant\", \"#FF16B8F3\": \"Zima Blue\", \"#FF6A5287\": \"Zimidar\", \"#FF92898A\": \"Zinc\", \"#FFA3907E\": \"Zinc Blend\", \"#FF84948B\": \"Zinc Blue\", \"#FF5B5C5A\": \"Zinc Dust\", \"#FF655B55\": \"Zinc Grey\", \"#FF8C8373\": \"Zinc Lustre\", \"#FF5A2538\": \"Zinfandel\", \"#FF5A3844\": \"Zinfandel Red\", \"#FFFBC17B\": \"Zing\", \"#FFDAC01A\": \"Zingiber\", \"#FFFFA111\": \"Zinnia\", \"#FFFFD781\": \"Zinnia Gold\", \"#FFBCC5AA\": \"Zion\", \"#FF838567\": \"Zipline Green\", \"#FFDEE3E3\": \"Zircon Variant\", \"#FF00849D\": \"Zircon Blue\", \"#FF807473\": \"Zircon Grey\", \"#FFD0E4E5\": \"Zircon Ice\", \"#FF2C7C79\": \"Zirconia Teal\", \"#FFF4F3CD\": \"Zitronenzucker\", \"#FF8B9196\": \"Zodiac\", \"#FFEE8844\": \"Zodiac Constellation\", \"#FFDADEAD\": \"Zombie Variant\", \"#FF54C571\": \"Zombie Green\", \"#FFCA6641\": \"Z\\u014dng H\\u00f3ng Red\", \"#FFB8BF71\": \"Zoodles\", \"#FFA29589\": \"Zorba Variant\", \"#FF17462E\": \"Zucchini\", \"#FF97A98B\": \"Zucchini Cream\", \"#FFE8A64E\": \"Zucchini Flower\", \"#FFAFA170\": \"Zucchini Garden\", \"#FFC8D07F\": \"Zucchini Noodles\", \"#FFCDD5D5\": \"Zumthor Variant\", \"#FF6BC026\": \"Zunda Green\", \"#FF008996\": \"Zuni\", \"#FF248BCC\": \"Z\\u00fcrich Blue\", \"#FFE6E1D9\": \"Z\\u00fcrich White\", \"#FF2B61A0\": \"Zydeco Blue\", \"#FFEFC872\": \"Hit the Hay\", \"#FF838996\": \"Roman Silver\"}"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/ImageColorDetector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.colors\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.magnifier\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.geometry.isFinite\nimport androidx.compose.ui.geometry.isSpecified\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.IntRect\nimport androidx.compose.ui.unit.dp\nimport androidx.core.graphics.get\nimport com.t8rin.gesture.observePointersCountWithOffset\nimport com.t8rin.gesture.pointerMotionEvents\nimport com.t8rin.image.ImageWithConstraints\nimport net.engawapg.lib.zoomable.ZoomableDefaults.defaultZoomOnDoubleTap\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\n\n\n@Composable\nfun ImageColorDetector(\n    modifier: Modifier = Modifier,\n    color: Color,\n    panEnabled: Boolean = false,\n    imageBitmap: ImageBitmap,\n    isMagnifierEnabled: Boolean,\n    boxModifier: Modifier = Modifier,\n    onColorChange: (Color) -> Unit\n) {\n    var pickerOffset by remember {\n        mutableStateOf(Offset.Unspecified)\n    }\n\n    val zoomState = rememberZoomState(maxScale = 20f)\n\n    val magnifierEnabled by remember(zoomState.scale, isMagnifierEnabled, panEnabled) {\n        derivedStateOf {\n            zoomState.scale <= 3f && !panEnabled && isMagnifierEnabled\n        }\n    }\n    var globalTouchPosition by remember { mutableStateOf(Offset.Unspecified) }\n    var globalTouchPointersCount by remember { mutableIntStateOf(0) }\n\n    Box(\n        modifier = boxModifier\n            .observePointersCountWithOffset { size, offset ->\n                globalTouchPointersCount = size\n                globalTouchPosition = offset\n            }\n            .then(\n                if (magnifierEnabled && globalTouchPointersCount == 1) {\n                    Modifier.magnifier(\n                        sourceCenter = {\n                            if (pickerOffset.isSpecified) {\n                                globalTouchPosition\n                            } else Offset.Unspecified\n                        },\n                        magnifierCenter = {\n                            globalTouchPosition - Offset(0f, 100.dp.toPx())\n                        },\n                        size = DpSize(height = 100.dp, width = 100.dp),\n                        zoom = 2f / zoomState.scale,\n                        cornerRadius = 50.dp,\n                        elevation = 2.dp\n                    )\n                } else Modifier\n            )\n            .zoomable(\n                zoomState = zoomState,\n                zoomEnabled = (globalTouchPointersCount >= 2 || panEnabled),\n                enableOneFingerZoom = panEnabled,\n                onDoubleTap = { pos ->\n                    if (panEnabled) zoomState.defaultZoomOnDoubleTap(pos)\n                }\n            ),\n        contentAlignment = Alignment.Center\n    ) {\n        ImageWithConstraints(\n            modifier = modifier,\n            imageBitmap = imageBitmap\n        ) {\n\n            val density = LocalDensity.current.density\n\n            val size = rememberUpdatedState(\n                newValue = Size(\n                    width = imageWidth.value * density,\n                    height = imageHeight.value * density\n                )\n            )\n\n            fun updateOffset(pointerInputChange: PointerInputChange): Offset {\n                val offsetX = pointerInputChange.position.x\n                    .coerceIn(0f, size.value.width)\n                val offsetY = pointerInputChange.position.y\n                    .coerceIn(0f, size.value.height)\n                pointerInputChange.consume()\n                return Offset(offsetX, offsetY)\n            }\n\n            if (!panEnabled) {\n                var touchStartedWithOnePointer by remember {\n                    mutableStateOf(false)\n                }\n                Box(\n                    modifier = Modifier\n                        .size(imageWidth, imageHeight)\n                        .pointerMotionEvents(\n                            onDown = {\n                                touchStartedWithOnePointer = globalTouchPointersCount <= 1\n\n                                if (touchStartedWithOnePointer) pickerOffset = updateOffset(it)\n                            },\n                            onMove = {\n                                if (touchStartedWithOnePointer) pickerOffset = updateOffset(it)\n                            },\n                            onUp = {\n                                if (touchStartedWithOnePointer) pickerOffset = updateOffset(it)\n                            },\n                            delayAfterDownInMillis = 20\n                        )\n                )\n            }\n\n            if (pickerOffset.isSpecified && pickerOffset.isFinite) {\n                onColorChange(\n                    calculateColorInPixel(\n                        offsetX = pickerOffset.x,\n                        offsetY = pickerOffset.y,\n                        rect = rect,\n                        width = imageWidth.value * density,\n                        height = imageHeight.value * density,\n                        bitmap = imageBitmap.asAndroidBitmap()\n                    )\n                )\n            }\n\n            ColorSelectionDrawing(\n                modifier = Modifier\n                    .size(imageWidth, imageHeight),\n                selectedColor = color,\n                zoom = zoomState.scale,\n                offset = pickerOffset\n            )\n        }\n    }\n}\n\n@Composable\ninternal fun ColorSelectionDrawing(\n    modifier: Modifier,\n    selectedColor: Color = Color.Black,\n    zoom: Float = 1f,\n    offset: Offset,\n) {\n    val color = animateColorAsState(\n        if (selectedColor.luminance() > 0.3f) Color.Black else Color.White\n    ).value\n\n    Canvas(modifier = modifier.fillMaxSize()) {\n\n        if (offset.isSpecified) {\n            val radius: Float = 8.dp.toPx() / zoom\n\n            // Draw touch position circle\n            drawCircle(\n                color,\n                radius = radius * 0.3f,\n                center = offset\n            )\n            drawCircle(\n                color,\n                radius = radius * 1.6f,\n                center = offset,\n                style = Stroke(radius * 0.6f)\n            )\n        }\n    }\n}\n\n/**\n * Calculate color of a pixel in a [Bitmap] that is drawn to a Composable with\n * [width] and [height]. [startImageX]\n *\n * @param offsetX x coordinate in Composable from top left corner\n * @param offsetY y coordinate in Composable from top left corner\n * @param startImageX x coordinate of top left position of image\n * @param startImageY y coordinate of top left position of image\n * @param rect contains coordinates of original bitmap to be used as. Full bitmap has\n * rect with (0,0) top left and size of [bitmap]\n * @param width of the Composable that draws this [bitmap]\n * @param height of the Composable that draws this [bitmap]\n * @param bitmap of picture/image that to detect color of a specific pixel in\n */\nprivate fun calculateColorInPixel(\n    offsetX: Float,\n    offsetY: Float,\n    startImageX: Float = 0f,\n    startImageY: Float = 0f,\n    rect: IntRect,\n    width: Float,\n    height: Float,\n    bitmap: Bitmap,\n): Color {\n\n    val bitmapWidth = bitmap.width\n    val bitmapHeight = bitmap.height\n\n    if (bitmapWidth == 0 || bitmapHeight == 0) return Color.Unspecified\n\n    // End positions, this might be less than Image dimensions if bitmap doesn't fit Image\n    val endImageX = width - startImageX\n    val endImageY = height - startImageY\n\n    val scaledX = scale(\n        start1 = startImageX,\n        end1 = endImageX,\n        pos = offsetX,\n        start2 = rect.left.toFloat(),\n        end2 = rect.right.toFloat()\n    ).toInt().coerceIn(0, bitmapWidth - 1)\n\n    val scaledY = scale(\n        start1 = startImageY,\n        end1 = endImageY,\n        pos = offsetY,\n        start2 = rect.top.toFloat(),\n        end2 = rect.bottom.toFloat()\n    ).toInt().coerceIn(0, bitmapHeight - 1)\n\n    val pixel: Int = bitmap[scaledX, scaledY]\n\n    val red = android.graphics.Color.red(pixel)\n    val green = android.graphics.Color.green(pixel)\n    val blue = android.graphics.Color.blue(pixel)\n\n    return (Color(red, green, blue))\n}\n\n\n/**\n * [Linear Interpolation](https://en.wikipedia.org/wiki/Linear_interpolation) function that moves\n * amount from it's current position to start and amount\n * @param start of interval\n * @param end of interval\n * @param amount e closed unit interval [0, 1]\n */\nprivate fun lerp(start: Float, end: Float, amount: Float): Float {\n    return (1 - amount) * start + amount * end\n}\n\n/**\n * Scale x1 from start1..end1 range to start2..end2 range\n\n */\nprivate fun scale(start1: Float, end1: Float, pos: Float, start2: Float, end2: Float) =\n    lerp(start2, end2, calculateFraction(start1, end1, pos))\n\n/**\n * Calculate fraction for value between a range [end] and [start] coerced into 0f-1f range\n */\nprivate fun calculateFraction(start: Float, end: Float, pos: Float) =\n    (if (end - start == 0f) 0f else (pos - start) / (end - start)).coerceIn(0f, 1f)\n"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/ImageColorPaletteState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.colors\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.luminance\nimport androidx.palette.graphics.Palette\nimport com.t8rin.colors.model.ColorData\nimport com.t8rin.colors.parser.ColorNameParser\nimport com.t8rin.colors.util.ColorUtil\n\ndata class PaletteData(\n    val colorData: ColorData,\n    val percent: Float\n)\n\n@Composable\nfun rememberImageColorPaletteState(\n    imageBitmap: ImageBitmap,\n    maximumColorCount: Int = 32,\n): ImageColorPaletteState {\n    return remember(imageBitmap, maximumColorCount) {\n        derivedStateOf {\n            ImageColorPaletteStateImpl(\n                image = imageBitmap,\n                maximumColorCount = maximumColorCount\n            )\n        }\n    }.value\n}\n\ninterface ImageColorPaletteState {\n    val image: ImageBitmap\n    val maximumColorCount: Int\n    val paletteData: List<PaletteData>\n}\n\nprivate class ImageColorPaletteStateImpl(\n    override val image: ImageBitmap,\n    override val maximumColorCount: Int\n) : ImageColorPaletteState {\n    override val paletteData: List<PaletteData> = run {\n        val paletteData = mutableListOf<PaletteData>()\n        val palette = Palette\n            .from(image.asAndroidBitmap())\n            .maximumColorCount(maximumColorCount)\n            .generate()\n\n\n        val numberOfPixels: Float = palette.swatches.sumOf {\n            it.population\n        }.toFloat()\n\n        palette.swatches.forEach { paletteSwatch ->\n            paletteSwatch?.let { swatch ->\n                val color = Color(swatch.rgb)\n                val name = ColorNameParser.parseColorName(color)\n                val colorData = ColorData(color, name)\n                val percent: Float = swatch.population / numberOfPixels\n                paletteData.add(PaletteData(colorData = colorData, percent))\n            }\n        }\n\n        paletteData.distinctBy {\n            it.colorData.name\n        }.sortedWith(\n            compareBy(\n                { it.colorData.color.luminance() },\n                { ColorUtil.colorToHSV(it.colorData.color)[0] },\n            )\n        )\n    }\n}"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/model/ColorData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.colors.model\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.colors.util.ColorUtil\n\n@Immutable\ndata class ColorData(val color: Color, val name: String) {\n    val hexText: String = ColorUtil.colorToHex(color = color)\n}"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/parser/ColorNameParser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.colors.parser\n\nimport android.content.Context\nimport android.util.JsonReader\nimport androidx.compose.ui.graphics.Color\nimport com.t8rin.colors.util.ColorUtil\nimport com.t8rin.colors.util.HexUtil\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.withContext\nimport kotlin.math.sqrt\n\ninterface ColorNameParser {\n    val colorNames: Map<String, ColorWithName>\n\n    fun parseColorName(color: Color): String\n    fun parseColorFromName(name: String): List<ColorWithName>\n    fun parseColorFromNameSingle(name: String): Color\n\n    suspend fun init(\n        context: Context,\n        colorsAsset: String = \"color_names.json\"\n    )\n\n    companion object : ColorNameParser by ColorNameParserImpl\n}\n\n/**\n * Parses color name from [Color]\n */\nprivate object ColorNameParserImpl : ColorNameParser {\n\n    override val colorNames: MutableMap<String, ColorWithName> = mutableMapOf()\n\n    /**\n     * Parse name of [Color]\n     */\n    override fun parseColorName(color: Color): String {\n        val hex = ColorUtil.colorToHex(color).uppercase().replace(\"#\", \"#FF\")\n        return colorNames[hex]?.name ?: run {\n            val red = color.red\n            val green = color.green\n            val blue = color.blue\n\n            colorNames.values.minByOrNull { color ->\n                sqrt(\n                    (color.red - red) * (color.red - red) +\n                            (color.green - green) * (color.green - green) +\n                            (color.blue - blue) * (color.blue - blue)\n                )\n            }?.name ?: \"?????\"\n        }\n    }\n\n    override fun parseColorFromName(\n        name: String\n    ): List<ColorWithName> = colorNames.values.filter {\n        it.name.contains(\n            other = name,\n            ignoreCase = true\n        ) || name.contains(\n            other = it.name,\n            ignoreCase = true\n        )\n    }.ifEmpty {\n        listOf(\n            ColorWithName(\n                color = Color.Black,\n                name = \"Black\"\n            )\n        )\n    }\n\n    override fun parseColorFromNameSingle(name: String): Color {\n        val normalizedName = name.trim().lowercase()\n        val values = colorNames.values\n\n        return values.firstOrNull { color ->\n            color.name.lowercase() == normalizedName\n        }?.color ?: values.firstOrNull { color ->\n            color.name.lowercase().contains(normalizedName)\n                    || normalizedName.contains(color.name.lowercase())\n        }?.color ?: Color.Black\n    }\n\n    override suspend fun init(\n        context: Context,\n        colorsAsset: String\n    ) = withContext(Dispatchers.IO) {\n        try {\n            JsonReader(context.assets.open(colorsAsset).bufferedReader()).use { reader ->\n                reader.beginObject()\n\n                while (reader.hasNext() && isActive) {\n                    val hex = reader.nextName()\n                    val name = reader.nextString()\n                    val color = HexUtil.hexToColor(hex)\n\n                    colorNames[hex] = ColorWithName(\n                        color = color,\n                        name = name\n                    )\n                }\n\n                reader.endObject()\n            }\n        } catch (t: Throwable) {\n            t.printStackTrace()\n        }\n    }\n\n}\n\ndata class ColorWithName(\n    val color: Color,\n    val name: String\n) {\n    val red get() = color.red\n    val green get() = color.green\n    val blue get() = color.blue\n}"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/util/ColorUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.colors.util\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.ColorUtils\n\n\nobject ColorUtil {\n\n    /**\n     * Convert Jetpack Compose [Color] to HSV (hue-saturation-value) components.\n     * ```\n     * Hue is [0 .. 360)\n     * Saturation is [0...1]\n     * Value is [0...1]\n     * ```\n     * @param hslIn 3 element array which holds the input HSL components.\n     */\n    fun colorToHSV(color: Color, hslIn: FloatArray) {\n        val rgbArray: IntArray = colorIntToRGBArray(color.toArgb())\n        val red = rgbArray[0]\n        val green = rgbArray[1]\n        val blue = rgbArray[2]\n        RGBUtil.rgbToHSV(red, green, blue, hslIn)\n    }\n\n    /**\n     * Convert Jetpack Compose [Color] to HSV (hue-saturation-value) components.\n     * ```\n     * Hue is [0 .. 360)\n     * Saturation is [0...1]\n     * Value is [0...1]\n     * ```\n     */\n    fun colorToHSV(color: Color): FloatArray {\n        val rgbArray: IntArray = colorIntToRGBArray(color.toArgb())\n        val red = rgbArray[0]\n        val green = rgbArray[1]\n        val blue = rgbArray[2]\n        return RGBUtil.rgbToHSV(red, green, blue)\n    }\n\n    /**\n     * Convert Jetpack Compose [Color] to HSV (hue-saturation-value) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     * @param hslIn 3 element array which holds the input HSL components.\n     */\n    fun colorToHSL(color: Color, hslIn: FloatArray) {\n        val rgbArray: IntArray = colorIntToRGBArray(color.toArgb())\n        val red = rgbArray[0]\n        val green = rgbArray[1]\n        val blue = rgbArray[2]\n        RGBUtil.rgbToHSL(red, green, blue, hslIn)\n    }\n\n    /**\n     * Convert Jetpack Compose [Color] to HSV (hue-saturation-value) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     */\n    fun colorToHSL(color: Color): FloatArray {\n        val rgbArray: IntArray = colorIntToRGBArray(color.toArgb())\n        val red = rgbArray[0]\n        val green = rgbArray[1]\n        val blue = rgbArray[2]\n        return RGBUtil.rgbToHSL(red, green, blue)\n    }\n\n    /*\n        COLOR-RGB Conversions\n     */\n\n    /**\n     * Convert Jetpack [Color] into 3 element array of red, green, and blue\n     *```\n     * rgb[0] is Red [0 .. 255]\n     * rgb[1] is Green [0...255]\n     * rgb[2] is Blue [0...255]\n     * ```\n     * @param color Jetpack Compose [Color]\n     * @return 3 element array which holds the input RGB components.\n     */\n    fun colorToARGBArray(color: Color): IntArray {\n        return colorIntToRGBArray(color.toArgb())\n    }\n\n    /**\n     * Convert Jetpack [Color] into 3 element array of red, green, and blue\n     *```\n     * rgb[0] is Red [0 .. 255]\n     * rgb[1] is Green [0...255]\n     * rgb[2] is Blue [0...255]\n     * ```\n     * @param color Jetpack Compose [Color]\n     * @return 3 element array which holds the input RGB components.\n     */\n    fun colorToRGBArray(color: Color): IntArray {\n        return colorIntToRGBArray(color.toArgb())\n    }\n\n    /**\n     * Convert Jetpack [Color] into 3 element array of red, green, and blue\n     *```\n     * rgb[0] is Red [0 .. 255]\n     * rgb[1] is Green [0...255]\n     * rgb[2] is Blue [0...255]\n     * ```\n     * @param color Jetpack Compose [Color]\n     * @param rgbIn 3 element array which holds the input RGB components.\n     */\n    fun colorToRGBArray(color: Color, rgbIn: IntArray) {\n        val argbArray = colorIntToRGBArray(color.toArgb())\n        rgbIn[0] = argbArray[0]\n        rgbIn[1] = argbArray[1]\n        rgbIn[2] = argbArray[2]\n    }\n\n\n    fun colorToHex(color: Color): String {\n        return RGBUtil.rgbToHex(color.red, color.green, color.blue)\n    }\n\n    fun colorToHexAlpha(color: Color): String {\n        return RGBUtil.argbToHex(color.alpha, color.red, color.green, color.blue)\n    }\n\n    /**\n     * Convert a RGB color in [Integer] form to HSV (hue-saturation-value) components.\n     *  * For instance, red =255, green =0, blue=0 is -65536\n     * ```\n     * hsv[0] is Hue [0 .. 360)\n     * hsv[1] is Saturation [0...1]\n     * hsv[2] is Value [0...1]\n     * ```\n     */\n    fun colorIntToHSV(color: Int): FloatArray {\n        val hsvOut = floatArrayOf(0f, 0f, 0f)\n        android.graphics.Color.colorToHSV(color, hsvOut)\n        return hsvOut\n    }\n\n    /**\n     * Convert a RGB color in [Integer] form to HSV (hue-saturation-value) components.\n     *  * For instance, red =255, green =0, blue=0 is -65536\n     *\n     * ```\n     * hsv[0] is Hue [0 .. 360)\n     * hsv[1] is Saturation [0...1]\n     * hsv[2] is Value [0...1]\n     * ```\n     * @param hsvIn 3 element array which holds the input HSV components.\n     */\n    fun colorIntToHSV(color: Int, hsvIn: FloatArray) {\n        android.graphics.Color.colorToHSV(color, hsvIn)\n    }\n\n\n    /**\n     * Convert RGB color [Integer] to HSL (hue-saturation-lightness) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     */\n    fun colorIntToHSL(color: Int): FloatArray {\n        val hslOut = floatArrayOf(0f, 0f, 0f)\n        ColorUtils.colorToHSL(color, hslOut)\n        return hslOut\n    }\n\n    /**\n     * Convert RGB color [Integer] to HSL (hue-saturation-lightness) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     */\n    fun colorIntToHSL(color: Int, hslIn: FloatArray) {\n        ColorUtils.colorToHSL(color, hslIn)\n    }\n\n\n    /*\n        ColorInt-RGB Conversions\n     */\n    /**\n     * Convert Color [Integer] into 3 element array of red, green, and blue\n     *```\n     * rgb[0] is Red [0 .. 255]\n     * rgb[1] is Green [0...255]\n     * rgb[2] is Blue [0...255]\n     * ```\n     * @return 3 element array which holds the input RGB components.\n     */\n    fun colorIntToRGBArray(color: Int): IntArray {\n        val red = android.graphics.Color.red(color)\n        val green = android.graphics.Color.green(color)\n        val blue = android.graphics.Color.blue(color)\n        return intArrayOf(red, green, blue)\n    }\n\n    /**\n     * Convert Color [Integer] into 3 element array of red, green, and blue\n     *```\n     * rgb[0] is Red [0 .. 255]\n     * rgb[1] is Green [0...255]\n     * rgb[2] is Blue [0...255]\n     * ```\n     * @param rgbIn 3 element array which holds the input RGB components.\n     */\n    fun colorIntToRGBArray(color: Int, rgbIn: IntArray) {\n        val red = android.graphics.Color.red(color)\n        val green = android.graphics.Color.green(color)\n        val blue = android.graphics.Color.blue(color)\n\n        rgbIn[0] = red\n        rgbIn[1] = green\n        rgbIn[2] = blue\n    }\n\n    /**\n     * Convert Color [Integer] into 4 element array of alpha red, green, and blue\n     *```\n     * rgb[0] is Alpha [0 .. 255]\n     * rgb[1] is Red [0 .. 255]\n     * rgb[2] is Green [0...255]\n     * rgb[3] is Blue [0...255]\n     * ```\n     * @return 4 element array which holds the input ARGB components.\n     */\n    fun colorIntToARGBArray(color: Int): IntArray {\n        val alpha = android.graphics.Color.alpha(color)\n        val red = android.graphics.Color.red(color)\n        val green = android.graphics.Color.green(color)\n        val blue = android.graphics.Color.blue(color)\n        return intArrayOf(alpha, red, green, blue)\n    }\n\n    /**\n     * Convert Color [Integer] into 4 element array of alpha red, green, and blue\n     *```\n     * rgb[0] is Alpha [0 .. 255]\n     * rgb[1] is Red [0 .. 255]\n     * rgb[2] is Green [0...255]\n     * rgb[3] is Blue [0...255]\n     * ```\n     * @param argbIn 4 element array which holds the input ARGB components.\n     */\n    fun colorIntToARGBArray(color: Int, argbIn: IntArray) {\n        val alpha = android.graphics.Color.alpha(color)\n        val red = android.graphics.Color.red(color)\n        val green = android.graphics.Color.green(color)\n        val blue = android.graphics.Color.blue(color)\n\n        argbIn[0] = alpha\n        argbIn[1] = red\n        argbIn[2] = green\n        argbIn[3] = blue\n    }\n}"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/util/HexRegex.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.colors.util\n\n// Regex for checking if this string is a 6 char hex or 8 char hex\nval hexWithAlphaRegex = \"^#?([0-9a-fA-F]{6}|[0-9a-fA-F]{8})\\$\".toRegex()\nval hexRegex = \"^#?([0-9a-fA-F]{6})\\$\".toRegex()\n\n// Check only on char if it's in range of 0-9, a-f, A-F\nval hexRegexSingleChar = \"[a-fA-F0-9]\".toRegex()"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/util/HexUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.colors.util\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.core.graphics.toColorInt\n\nobject HexUtil {\n    /*\n    HEX-ColorInt Conversion\n */\n    fun hexToColorInt(colorString: String): Int {\n        val completeColorString = if (colorString.first() == '#') colorString else \"#$colorString\"\n        return completeColorString.toColorInt()\n    }\n\n    /*\n        HEX-RGB Conversion\n     */\n    fun hexToRGB(colorString: String): IntArray {\n        val colorInt = hexToColorInt(colorString)\n        return ColorUtil.colorIntToRGBArray(colorInt)\n    }\n\n    fun hexToRGB(colorString: String, rgbIn: IntArray) {\n        val colorInt = hexToColorInt(colorString)\n        ColorUtil.colorIntToRGBArray(colorInt, rgbIn)\n    }\n\n    fun hexToARGB(colorString: String): IntArray {\n        val colorInt = hexToColorInt(colorString)\n        return ColorUtil.colorIntToARGBArray(colorInt)\n    }\n\n    fun hexToARGB(colorString: String, argbIn: IntArray) {\n        val colorInt = hexToColorInt(colorString)\n        ColorUtil.colorIntToARGBArray(colorInt, argbIn)\n    }\n\n\n    fun hexToColor(colorString: String): Color {\n        return Color(hexToColorInt(colorString))\n    }\n\n}"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/util/HexVisualTransformation.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.colors.util\n\nimport androidx.compose.ui.text.AnnotatedString\nimport androidx.compose.ui.text.input.OffsetMapping\nimport androidx.compose.ui.text.input.TransformedText\nimport androidx.compose.ui.text.input.VisualTransformation\n\nclass HexVisualTransformation(private val useAlpha: Boolean) : VisualTransformation {\n\n    override fun filter(text: AnnotatedString): TransformedText {\n\n        val limit = if (useAlpha) 8 else 6\n\n        val trimmed =\n            if (text.text.length >= limit) text.text.substring(0 until limit) else text.text\n\n        val output = if (trimmed.isEmpty()) {\n            trimmed\n        } else {\n            if (!useAlpha || trimmed.length < 7) {\n                \"#${trimmed.uppercase()}\"\n            } else {\n                \"#${\n                    trimmed.substring(0, 2).lowercase() +\n                            trimmed.substring(2, trimmed.length).uppercase()\n                }\"\n            }\n        }\n\n        return TransformedText(\n            AnnotatedString(output),\n            if (useAlpha) hexAlphaOffsetMapping else hexOffsetMapping\n        )\n    }\n\n    private val hexOffsetMapping = object : OffsetMapping {\n\n        override fun originalToTransformed(offset: Int): Int {\n\n            // when empty return only 1 char for #\n            if (offset == 0) return offset\n            if (offset <= 5) return offset + 1\n            return 7\n        }\n\n        override fun transformedToOriginal(offset: Int): Int {\n            if (offset == 0) return offset\n            // #ABCABC\n            if (offset <= 6) return offset - 1\n            return 6\n        }\n    }\n\n    private val hexAlphaOffsetMapping = object : OffsetMapping {\n\n        override fun originalToTransformed(offset: Int): Int {\n\n            // when empty return only 1 char for #\n            if (offset == 0) return offset\n            if (offset <= 7) return offset + 1\n            return 9\n        }\n\n        override fun transformedToOriginal(offset: Int): Int {\n            if (offset == 0) return offset\n            // #ffABCABC\n            if (offset <= 8) return offset - 1\n            return 8\n        }\n    }\n}\n"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/util/RGBUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.colors.util\n\nimport android.graphics.Color\nimport androidx.core.graphics.ColorUtils\nimport java.util.Locale\n\nobject RGBUtil {\n\n    /**\n     * Convert RGB red, green blue to HSV (hue-saturation-value) components.\n     * ```\n     * hsv[0] is Hue [0 .. 360)\n     * hsv[1] is Saturation [0...1]\n     * hsv[2] is Value [0...1]\n     * ```\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     */\n    fun rgbToHSV(\n        red: Int,\n        green: Int,\n        blue: Int\n    ): FloatArray {\n        val hsvOut = floatArrayOf(0f, 0f, 0f)\n        Color.RGBToHSV(red, green, blue, hsvOut)\n        return hsvOut\n    }\n\n    /**\n     * Convert RGB red, green blue to HSV (hue-saturation-value) components.\n     * ```\n     * hsv[0] is Hue [0 .. 360)\n     * hsv[1] is Saturation [0...1]\n     * hsv[2] is Value [0...1]\n     * ```\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     * @param hsvIn 3 element array which holds the output HSV components.\n     */\n    fun rgbToHSV(\n        red: Int,\n        green: Int,\n        blue: Int,\n        hsvIn: FloatArray\n    ) {\n        Color.RGBToHSV(red, green, blue, hsvIn)\n    }\n\n\n    /**\n     * Convert RGB red, green blue to HSL (hue-saturation-lightness) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     */\n    fun rgbToHSL(\n        red: Int,\n        green: Int,\n        blue: Int\n    ): FloatArray {\n        val outHsl = floatArrayOf(0f, 0f, 0f)\n        ColorUtils.RGBToHSL(red, green, blue, outHsl)\n        return outHsl\n    }\n\n    /**\n     * Convert RGB red, green blue to HSL (hue-saturation-lightness) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     * @param hslIn 3 element array which holds the input HSL components.\n     */\n    fun rgbToHSL(\n        red: Int,\n        green: Int,\n        blue: Int,\n        hslIn: FloatArray\n    ) {\n        ColorUtils.RGBToHSL(red, green, blue, hslIn)\n    }\n\n    /**\n     * Convert RGB red, green, blue components in [0f..1f] range to\n     * HSV (hue-saturation-value) components.\n     *\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     * @return 3 element array which holds the output RGB components.\n     */\n    fun rgbFloatToHSV(\n        red: Float,\n        green: Float,\n        blue: Float\n    ): FloatArray {\n        val colorInt = rgbToColorInt(red = red, green = green, blue = blue)\n        val outHsl = floatArrayOf(0f, 0f, 0f)\n        ColorUtil.colorIntToHSV(colorInt, outHsl)\n        return outHsl\n    }\n\n    /**\n     * Convert RGB red, green, blue components in [0f..1f] range to\n     * HSV (hue-saturation-value) components.\n     *\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     * @param hsvIn 3 element array which holds the output HSV components.\n     */\n    fun rgbFloatToHSV(\n        red: Float,\n        green: Float,\n        blue: Float,\n        hsvIn: FloatArray\n    ) {\n        val colorInt = rgbToColorInt(red = red, green = green, blue = blue)\n        ColorUtil.colorIntToHSV(colorInt, hsvIn)\n    }\n\n\n    /**\n     * Convert RGB red, green blue in [0f..1f] range to HSL (hue-saturation-lightness) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     * @param red  Red component [0f..1f] of the color\n     * @param green  Green component [0f..1f] of the color\n     * @param blue Blue component [0f..1f] of the color\n     */\n    fun rgbFloatToHSL(\n        red: Float,\n        green: Float,\n        blue: Float\n    ): FloatArray {\n        val colorInt = rgbToColorInt(red = red, green = green, blue = blue)\n        val outHsl = floatArrayOf(0f, 0f, 0f)\n        ColorUtil.colorIntToHSL(colorInt, outHsl)\n        return outHsl\n    }\n\n    /**\n     * Convert RGB red, green blue in [0f..1f] range to HSL (hue-saturation-lightness) components.\n     * ```\n     * hsl[0] is Hue [0 .. 360)\n     * hsl[1] is Saturation [0...1]\n     * hsl[2] is Lightness [0...1]\n     * ```\n     * @param red  Red component [0f..1f] of the color\n     * @param green  Green component [0f..1f] of the color\n     * @param blue Blue component [0f..1f] of the color\n     * @param hslIn 3 element array which holds the input HSL components.\n     */\n    fun rgbFloatToHSL(\n        red: Float,\n        green: Float,\n        blue: Float,\n        hslIn: FloatArray\n    ) {\n        val colorInt = rgbToColorInt(red = red, green = green, blue = blue)\n        ColorUtil.colorIntToHSL(colorInt, hslIn)\n    }\n\n\n    /**\n     * Return a color-int from alpha, red, green, blue components.\n     * These component values should be [0..255], but there is no range check performed,\n     * so if they are out of range, the returned color is undefined.\n     *\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     */\n    fun rgbToColorInt(\n        red: Int,\n        green: Int,\n        blue: Int\n    ): Int {\n        return Color.rgb(red, green, blue)\n    }\n\n    /**\n     * Return a color-int from alpha, red, green, blue components.\n     * These component values should be [0f..1f], but there is no range check performed,\n     * so if they are out of range, the returned color is undefined.\n     *\n     * @param red  Red component [0f..1f] of the color\n     * @param green  Green component [0..1f] of the color\n     * @param blue Blue component [0..1f] of the color\n     *\n     */\n    fun rgbToColorInt(\n        red: Float,\n        green: Float,\n        blue: Float\n    ): Int {\n        val redInt = red.fractionToRGBRange()\n        val greenInt = green.fractionToRGBRange()\n        val blueInt = blue.fractionToRGBRange()\n        return Color.rgb(redInt, greenInt, blueInt)\n    }\n\n\n    /**\n     * Convert red, green, blue components [0..255] range in [Integer] to Hex format String\n     */\n    fun rgbToHex(\n        red: Int,\n        green: Int,\n        blue: Int\n    ): String {\n        return \"#\" +\n                Integer.toHexString(red).toStringComponent() +\n                Integer.toHexString(green).toStringComponent() +\n                Integer.toHexString(blue).toStringComponent()\n    }\n\n    /**\n     * Convert rgb array to Hex format String\n     * ```\n     * rgb[0] is Red [0 .. 255]\n     * rgb[1] is Green [0...255]\n     * rgb[2] is Blue [0...255]\n     * ```\n     */\n    fun rgbToHex(rgb: IntArray): String {\n        return \"#\" +\n                Integer.toHexString(rgb[0]).toStringComponent() +\n                Integer.toHexString(rgb[1]).toStringComponent() +\n                Integer.toHexString(rgb[2]).toStringComponent()\n    }\n\n    /**\n     * Convert red, green, blue components [0f..1f] range in [Float] to Hex format String\n     */\n    fun rgbToHex(\n        red: Float,\n        green: Float,\n        blue: Float\n    ): String {\n        return \"#\" +\n                Integer.toHexString(red.fractionToRGBRange()).toStringComponent() +\n                Integer.toHexString(green.fractionToRGBRange()).toStringComponent() +\n                Integer.toHexString(blue.fractionToRGBRange()).toStringComponent()\n    }\n\n\n    /**\n     * Return a color-int from alpha, red, green, blue components.\n     * These component values should be [0..255], but there is no range check performed,\n     * so if they are out of range, the returned color is undefined.\n     *\n     * @param alpha  Alpha component [0..255] of the color\n     * @param red  Red component [0..255] of the color\n     * @param green  Green component [0..255] of the color\n     * @param blue Blue component [0..255] of the color\n     */\n    fun argbToColorInt(\n        alpha: Int,\n        red: Int,\n        green: Int,\n        blue: Int\n    ): Int {\n        return Color.argb(alpha, red, green, blue)\n    }\n\n    /**\n     * Return a color-int from alpha, red, green, blue components.\n     * These component values should be [0f..1f], but there is no range check performed,\n     * so if they are out of range, the returned color is undefined.\n     *\n     * @param alpha  Alpha component [0f..1f] of the color\n     * @param red  Red component [0f..1f] of the color\n     * @param green  Green component [0..1f] of the color\n     * @param blue Blue component [0..1f] of the color\n     */\n    fun argbToColorInt(\n        alpha: Float,\n        red: Float,\n        green: Float,\n        blue: Float\n    ): Int {\n        val alphaInt = alpha.fractionToRGBRange()\n        val redInt = red.fractionToRGBRange()\n        val greenInt = green.fractionToRGBRange()\n        val blueInt = blue.fractionToRGBRange()\n        return Color.argb(alphaInt, redInt, greenInt, blueInt)\n    }\n\n\n    /**\n     * Convert alpha, red, green, blue components in [0..255] range argb to Hex format String\n     *\n     * ```\n     * Alpha is [0 .. 255]\n     * Red is [0 .. 255]\n     * Green is [0...255]\n     * Blue is [0...255]\n     * ```\n     */\n    fun argbToHex(\n        alpha: Int,\n        red: Int,\n        green: Int,\n        blue: Int\n    ): String {\n        return \"#\" +\n                Integer.toHexString(alpha).toStringComponent() +\n                Integer.toHexString(red).toStringComponent() +\n                Integer.toHexString(green).toStringComponent() +\n                Integer.toHexString(blue).toStringComponent()\n    }\n\n    /**\n     * Convert alpha, red, green, blue components in [0f..1f] range in [Float] argb to Hex format String\n     *\n     * ```\n     * Alpha is [0f .. 1f]\n     * Red is [0f .. 1f]\n     * Green is [0...1f]\n     * Blue is [0...1f]\n     * ```\n     */\n    fun argbToHex(\n        alpha: Float,\n        red: Float,\n        green: Float,\n        blue: Float\n    ): String {\n        return \"#\" +\n                Integer.toHexString(alpha.fractionToRGBRange()).toStringComponent() +\n                Integer.toHexString(red.fractionToRGBRange()).toStringComponent() +\n                Integer.toHexString(green.fractionToRGBRange()).toStringComponent() +\n                Integer.toHexString(blue.fractionToRGBRange()).toStringComponent()\n    }\n\n    /*\n        RGB-HEX Conversions\n     */\n    /**\n     * Get hex representation of a rgb Color in [Integer] format\n     */\n    fun Int.toRgbString(): String =\n        (\"#\" +\n                red.toStringComponent() +\n                green.toStringComponent() +\n                blue.toStringComponent())\n            .uppercase(Locale.getDefault())\n\n    /**\n     * Get hex representation of a argb Color in [Integer] format\n     */\n    fun Int.toArgbString(): String =\n        (\"#\" +\n                alpha.toStringComponent() +\n                red.toStringComponent() +\n                green.toStringComponent() +\n                blue.toStringComponent()\n                ).uppercase(Locale.getDefault())\n\n    private fun String.toStringComponent() =\n        this.let { if (it.length == 1) \"0${it}\" else it }\n\n    private fun Int.toStringComponent(): String =\n        this.toString(16).let { if (it.length == 1) \"0${it}\" else it }\n\n    inline val Int.alpha: Int\n        get() = (this shr 24) and 0xFF\n\n    inline val Int.red: Int\n        get() = (this shr 16) and 0xFF\n\n    inline val Int.green: Int\n        get() = (this shr 8) and 0xFF\n\n    inline val Int.blue: Int\n        get() = this and 0xFF\n\n}"
  },
  {
    "path": "lib/colors/src/main/java/com/t8rin/colors/util/RoundngUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.colors.util\n\nimport kotlin.math.roundToInt\n\n/**\n * Converts alpha, red, green or blue values from range of [0f-1f] to [0-255].\n */\nfun Float.fractionToRGBRange() = (this * 255.0f).toInt()\n\n/**\n * Converts alpha, red, green or blue values from range of [0f-1f] to [0-255] and returns\n * it as [String].\n */\nfun Float.fractionToRGBString() = this.fractionToRGBRange().toString()\n\n/**\n * Rounds this [Float] to another with 2 significant numbers\n * 0.1234 is rounded to 0.12\n * 0.127 is rounded to 0.13\n */\nfun Float.roundToTwoDigits() = (this * 100.0f).roundToInt() / 100.0f\n\n/**\n * Rounds this [Float] to closest int.\n */\nfun Float.round() = this.roundToInt()\n\n/**\n * Converts **HSV** or **HSL** colors that are in range of [0f-1f] to [0-100] range in [Integer]\n * with [Float.roundToInt]\n */\nfun Float.fractionToPercent() = (this * 100.0f).roundToInt()\n\n/**\n * Converts **HSV** or **HSL** colors that are in range of [0f-1f] to [0-100] range in [Integer]\n * with [Float.toInt]\n */\nfun Float.fractionToIntPercent() = (this * 100.0f).toInt()\n"
  },
  {
    "path": "lib/cropper/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/cropper/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.cropper\"\n\ndependencies {\n    implementation(projects.lib.gesture)\n}"
  },
  {
    "path": "lib/cropper/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/CropModifier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper\n\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.platform.debugInspectorInfo\nimport com.t8rin.cropper.model.CropData\nimport com.t8rin.cropper.state.CropState\nimport com.t8rin.cropper.state.cropData\nimport com.t8rin.cropper.util.ZoomLevel\nimport com.t8rin.cropper.util.getNextZoomLevel\nimport com.t8rin.cropper.util.update\nimport com.t8rin.gesture.detectMotionEventsAsList\nimport com.t8rin.gesture.detectTransformGestures\nimport kotlinx.coroutines.launch\n\n/**\n * Modifier that zooms in or out of Composable set to. This zoom modifier has option\n * to move back to bounds with an animation or option to have fling gesture when user removes\n * from screen while velocity is higher than threshold to have smooth touch effect.\n *\n * @param keys are used for [Modifier.pointerInput] to restart closure when any keys assigned\n * change\n * empty space on sides or edges of parent.\n * @param cropState State of the zoom that contains option to set initial, min, max zoom,\n * enabling rotation, pan or zoom and contains current [CropData]\n * event propagations. Also contains [Rect] of visible area based on pan, zoom and rotation\n * @param zoomOnDoubleTap lambda that returns current [ZoomLevel] and based on current level\n * enables developer to define zoom on double tap gesture\n * @param onGestureStart callback to to notify gesture has started and return current\n * [CropData]  of this modifier\n * @param onGesture callback to notify about ongoing gesture and return current\n * [CropData]  of this modifier\n * @param onGestureEnd callback to notify that gesture finished return current\n * [CropData]  of this modifier\n */\nfun Modifier.crop(\n    vararg keys: Any?,\n    cropState: CropState,\n    zoomOnDoubleTap: (ZoomLevel) -> Float = cropState.DefaultOnDoubleTap,\n    onDown: ((CropData) -> Unit)? = null,\n    onMove: ((CropData) -> Unit)? = null,\n    onUp: ((CropData) -> Unit)? = null,\n    onGestureStart: ((CropData) -> Unit)? = null,\n    onGesture: ((CropData) -> Unit)? = null,\n    onGestureEnd: ((CropData) -> Unit)? = null\n) = composed(\n\n    factory = {\n\n        LaunchedEffect(key1 = cropState) {\n            cropState.init()\n        }\n\n        val coroutineScope = rememberCoroutineScope()\n\n        // Current Zoom level\n        var zoomLevel by remember { mutableStateOf(ZoomLevel.Min) }\n\n        val transformModifier = Modifier.pointerInput(*keys) {\n            detectTransformGestures(\n                consume = false,\n                onGestureStart = {\n                    onGestureStart?.invoke(cropState.cropData)\n                },\n                onGestureEnd = {\n                    coroutineScope.launch {\n                        cropState.onGestureEnd {\n                            onGestureEnd?.invoke(cropState.cropData)\n                        }\n                    }\n                },\n                onGesture = { centroid, pan, zoom, rotate, mainPointer, pointerList ->\n\n                    coroutineScope.launch {\n                        cropState.onGesture(\n                            centroid = centroid,\n                            panChange = pan,\n                            zoomChange = zoom,\n                            rotationChange = rotate,\n                            mainPointer = mainPointer,\n                            changes = pointerList\n                        )\n                    }\n                    onGesture?.invoke(cropState.cropData)\n                    mainPointer.consume()\n                }\n            )\n        }\n\n        val tapModifier = Modifier.pointerInput(*keys) {\n            detectTapGestures(\n                onDoubleTap = { offset: Offset ->\n                    coroutineScope.launch {\n                        zoomLevel = getNextZoomLevel(zoomLevel)\n                        val newZoom = zoomOnDoubleTap(zoomLevel)\n                        cropState.onDoubleTap(\n                            offset = offset,\n                            zoom = newZoom\n                        ) {\n                            onGestureEnd?.invoke(cropState.cropData)\n                        }\n                    }\n                }\n            )\n        }\n\n        val touchModifier = Modifier.pointerInput(*keys) {\n            detectMotionEventsAsList(\n                onDown = {\n                    coroutineScope.launch {\n                        cropState.onDown(it)\n                        onDown?.invoke(cropState.cropData)\n                    }\n                },\n                onMove = {\n                    coroutineScope.launch {\n                        cropState.onMove(it)\n                        onMove?.invoke(cropState.cropData)\n                    }\n                },\n                onUp = {\n                    coroutineScope.launch {\n                        cropState.onUp(it)\n                        onUp?.invoke(cropState.cropData)\n                    }\n                }\n            )\n        }\n\n        val graphicsModifier = Modifier.graphicsLayer {\n            this.update(cropState)\n        }\n\n        this.then(\n            Modifier\n                .clipToBounds()\n                .then(tapModifier)\n                .then(transformModifier)\n                .then(touchModifier)\n                .then(graphicsModifier)\n        )\n    },\n    inspectorInfo = debugInspectorInfo {\n        name = \"crop\"\n        // add name and value of each argument\n        properties[\"keys\"] = keys\n        properties[\"onDown\"] = onGestureStart\n        properties[\"onMove\"] = onGesture\n        properties[\"onUp\"] = onGestureEnd\n    }\n)\n\ninternal val CropState.DefaultOnDoubleTap: (ZoomLevel) -> Float\n    get() = { zoomLevel: ZoomLevel ->\n        when (zoomLevel) {\n            ZoomLevel.Min -> 1f\n            ZoomLevel.Mid -> 3f.coerceIn(zoomMin, zoomMax)\n            ZoomLevel.Max -> 5f.coerceAtLeast(zoomMax)\n        }\n    }\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/ImageCropper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper\n\nimport android.content.res.Configuration\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.LinearEasing\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalConfiguration\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.cropper.crop.CropAgent\nimport com.t8rin.cropper.draw.DrawingOverlay\nimport com.t8rin.cropper.draw.ImageDrawCanvas\nimport com.t8rin.cropper.image.ImageWithConstraints\nimport com.t8rin.cropper.image.getScaledImageBitmap\nimport com.t8rin.cropper.model.CropOutline\nimport com.t8rin.cropper.settings.CropDefaults\nimport com.t8rin.cropper.settings.CropProperties\nimport com.t8rin.cropper.settings.CropStyle\nimport com.t8rin.cropper.settings.CropType\nimport com.t8rin.cropper.state.DynamicCropState\nimport com.t8rin.cropper.state.rememberCropState\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.launchIn\nimport kotlinx.coroutines.flow.onEach\nimport kotlinx.coroutines.flow.onStart\n\n@Composable\nfun ImageCropper(\n    modifier: Modifier = Modifier,\n    imageBitmap: ImageBitmap,\n    contentDescription: String? = null,\n    cropStyle: CropStyle = CropDefaults.style(),\n    cropProperties: CropProperties,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    crop: Boolean = false,\n    onCropStart: () -> Unit,\n    onZoomChange: (Float) -> Unit,\n    onCropSuccess: (ImageBitmap) -> Unit,\n    backgroundModifier: Modifier = Modifier\n) {\n\n    ImageWithConstraints(\n        modifier = modifier.clipToBounds(),\n        contentScale = cropProperties.contentScale,\n        contentDescription = contentDescription,\n        filterQuality = filterQuality,\n        imageBitmap = imageBitmap,\n        drawImage = false\n    ) {\n\n        // No crop operation is applied by ScalableImage so rect points to bounds of original\n        // bitmap\n        val scaledImageBitmap = getScaledImageBitmap(\n            imageWidth = imageWidth,\n            imageHeight = imageHeight,\n            rect = rect,\n            bitmap = imageBitmap,\n            contentScale = cropProperties.contentScale,\n        )\n\n        // Container Dimensions\n        val containerWidthPx = constraints.maxWidth\n        val containerHeightPx = constraints.maxHeight\n\n        val containerWidth: Dp\n        val containerHeight: Dp\n\n        // Bitmap Dimensions\n        val bitmapWidth = scaledImageBitmap.width\n        val bitmapHeight = scaledImageBitmap.height\n\n        // Dimensions of Composable that displays Bitmap\n        val imageWidthPx: Int\n        val imageHeightPx: Int\n\n        with(LocalDensity.current) {\n            imageWidthPx = imageWidth.roundToPx()\n            imageHeightPx =\n                imageHeight.roundToPx() - if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) 0\n                else WindowInsets.navigationBars.getBottom(LocalDensity.current)\n            containerWidth = containerWidthPx.toDp()\n            containerHeight = containerHeightPx.toDp()\n        }\n\n        val cropType = cropProperties.cropType\n        val contentScale = cropProperties.contentScale\n        val fixedAspectRatio = cropProperties.fixedAspectRatio\n        val cropOutline = cropProperties.cropOutlineProperty.cropOutline\n\n        // these keys are for resetting cropper when image width/height, contentScale or\n        // overlay aspect ratio changes\n        val resetKeys =\n            getResetKeys(\n                scaledImageBitmap,\n                imageWidthPx,\n                imageHeightPx,\n                contentScale,\n                cropType,\n                fixedAspectRatio\n            )\n\n        val cropState = rememberCropState(\n            imageSize = IntSize(bitmapWidth, bitmapHeight),\n            containerSize = IntSize(containerWidthPx, containerHeightPx),\n            drawAreaSize = IntSize(imageWidthPx, imageHeightPx),\n            cropProperties = cropProperties,\n            keys = resetKeys\n        )\n\n        onZoomChange(cropState.zoom)\n\n        val isHandleTouched by remember(cropState) {\n            derivedStateOf {\n                cropState is DynamicCropState && handlesTouched(cropState.touchRegion)\n            }\n        }\n\n        val pressedStateColor = remember(cropStyle.backgroundColor) {\n            cropStyle.backgroundColor\n                .copy(cropStyle.backgroundColor.alpha * .7f)\n        }\n\n        val transparentColor by animateColorAsState(\n            animationSpec = tween(300, easing = LinearEasing),\n            targetValue = if (isHandleTouched) pressedStateColor else cropStyle.backgroundColor\n        )\n\n        // Crops image when user invokes crop operation\n        Crop(\n            crop,\n            scaledImageBitmap,\n            cropState.cropRect,\n            cropOutline,\n            onCropStart,\n            onCropSuccess\n        )\n\n        val imageModifier = Modifier\n            .size(containerWidth, containerHeight)\n            .crop(\n                keys = resetKeys,\n                cropState = cropState\n            )\n\n        LaunchedEffect(key1 = cropProperties) {\n            cropState.updateProperties(cropProperties)\n        }\n\n        /// Create a MutableTransitionState<Boolean> for the AnimatedVisibility.\n        var visible by remember { mutableStateOf(false) }\n\n        LaunchedEffect(Unit) {\n            delay(100)\n            visible = true\n        }\n\n        ImageCropper(\n            modifier = imageModifier,\n            visible = visible,\n            imageBitmap = imageBitmap,\n            containerWidth = containerWidth,\n            containerHeight = containerHeight,\n            imageWidthPx = imageWidthPx,\n            imageHeightPx = imageHeightPx,\n            handleSize = cropProperties.handleSize,\n            middleHandleSize = cropProperties.middleHandleSize,\n            overlayRect = cropState.overlayRect,\n            cropType = cropType,\n            cropOutline = cropOutline,\n            cropStyle = cropStyle,\n            transparentColor = transparentColor,\n            backgroundModifier = backgroundModifier\n        )\n    }\n}\n\n@Composable\nprivate fun ImageCropper(\n    modifier: Modifier,\n    visible: Boolean,\n    imageBitmap: ImageBitmap,\n    containerWidth: Dp,\n    containerHeight: Dp,\n    imageWidthPx: Int,\n    imageHeightPx: Int,\n    handleSize: Float,\n    middleHandleSize: Float,\n    cropType: CropType,\n    cropOutline: CropOutline,\n    cropStyle: CropStyle,\n    overlayRect: Rect,\n    transparentColor: Color,\n    backgroundModifier: Modifier\n) {\n    Box(\n        modifier = Modifier\n            .fillMaxSize()\n            .then(backgroundModifier)\n    ) {\n\n        AnimatedVisibility(\n            visible = visible,\n            enter = fadeIn(tween(500))\n        ) {\n            ImageCropperImpl(\n                modifier = modifier,\n                imageBitmap = imageBitmap,\n                containerWidth = containerWidth,\n                containerHeight = containerHeight,\n                imageWidthPx = imageWidthPx,\n                imageHeightPx = imageHeightPx,\n                cropType = cropType,\n                cropOutline = cropOutline,\n                handleSize = handleSize,\n                middleHandleSize = middleHandleSize,\n                cropStyle = cropStyle,\n                rectOverlay = overlayRect,\n                transparentColor = transparentColor\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun ImageCropperImpl(\n    modifier: Modifier,\n    imageBitmap: ImageBitmap,\n    containerWidth: Dp,\n    containerHeight: Dp,\n    imageWidthPx: Int,\n    imageHeightPx: Int,\n    cropType: CropType,\n    cropOutline: CropOutline,\n    handleSize: Float,\n    middleHandleSize: Float,\n    cropStyle: CropStyle,\n    transparentColor: Color,\n    rectOverlay: Rect\n) {\n\n    Box(contentAlignment = Alignment.Center) {\n\n        // Draw Image\n        ImageDrawCanvas(\n            modifier = modifier,\n            imageBitmap = imageBitmap,\n            imageWidth = imageWidthPx,\n            imageHeight = imageHeightPx\n        )\n\n        val drawOverlay = cropStyle.drawOverlay\n\n        val drawGrid = cropStyle.drawGrid\n        val overlayColor = cropStyle.overlayColor\n        val handleColor = cropStyle.handleColor\n        val drawHandles = cropType == CropType.Dynamic\n        val strokeWidth = cropStyle.strokeWidth\n\n        DrawingOverlay(\n            modifier = Modifier.size(containerWidth, containerHeight),\n            drawOverlay = drawOverlay,\n            rect = rectOverlay,\n            cropOutline = cropOutline,\n            drawGrid = drawGrid,\n            overlayColor = overlayColor,\n            handleColor = handleColor,\n            strokeWidth = strokeWidth,\n            drawHandles = drawHandles,\n            handleSize = handleSize,\n            middleHandleSize = middleHandleSize,\n            transparentColor = transparentColor,\n        )\n\n    }\n}\n\n@Composable\nprivate fun Crop(\n    crop: Boolean,\n    scaledImageBitmap: ImageBitmap,\n    cropRect: Rect,\n    cropOutline: CropOutline,\n    onCropStart: () -> Unit,\n    onCropSuccess: (ImageBitmap) -> Unit\n) {\n\n    val density = LocalDensity.current\n    val layoutDirection = LocalLayoutDirection.current\n\n    // Crop Agent is responsible for cropping image\n    val cropAgent = remember { CropAgent() }\n\n    LaunchedEffect(crop) {\n        if (crop) {\n            flow {\n                emit(\n                    cropAgent.crop(\n                        scaledImageBitmap,\n                        cropRect,\n                        cropOutline,\n                        layoutDirection,\n                        density\n                    )\n                )\n            }\n                .flowOn(Dispatchers.Default)\n                .onStart {\n                    onCropStart()\n                    delay(400)\n                }\n                .onEach {\n                    onCropSuccess(it)\n                }\n                .launchIn(this)\n        }\n    }\n}\n\n@Composable\nprivate fun getResetKeys(\n    scaledImageBitmap: ImageBitmap,\n    imageWidthPx: Int,\n    imageHeightPx: Int,\n    contentScale: ContentScale,\n    cropType: CropType,\n    fixedAspectRatio: Boolean,\n) = remember(\n    scaledImageBitmap,\n    imageWidthPx,\n    imageHeightPx,\n    contentScale,\n    cropType,\n    fixedAspectRatio,\n) {\n    arrayOf(\n        scaledImageBitmap,\n        imageWidthPx,\n        imageHeightPx,\n        contentScale,\n        cropType,\n        fixedAspectRatio,\n    )\n}"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/TouchRegion.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper\n\n/**\n * Enum for detecting which section of Composable user has initially touched\n */\nenum class TouchRegion {\n    TopLeft, TopRight, BottomLeft, BottomRight,\n    TopCenter, CenterRight, BottomCenter, CenterLeft,\n    Inside, None\n}\n\nfun handlesTouched(touchRegion: TouchRegion) =\n    touchRegion != TouchRegion.None && touchRegion != TouchRegion.Inside\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/crop/CropAgent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.crop\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Paint\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.addOutline\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.nativeCanvas\nimport androidx.compose.ui.graphics.toComposeRect\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.core.graphics.scale\nimport com.t8rin.cropper.model.CropImageMask\nimport com.t8rin.cropper.model.CropOutline\nimport com.t8rin.cropper.model.CropPath\nimport com.t8rin.cropper.model.CropShape\n\n\n/**\n * Crops imageBitmap based on path that is passed in [crop] function\n */\ninternal class CropAgent {\n\n    private val imagePaint = Paint().apply {\n        blendMode = BlendMode.SrcIn\n    }\n\n    private val paint = Paint()\n\n\n    fun crop(\n        imageBitmap: ImageBitmap,\n        cropRect: Rect,\n        cropOutline: CropOutline,\n        layoutDirection: LayoutDirection,\n        density: Density,\n    ): ImageBitmap {\n        return runCatching {\n            val croppedBitmap: Bitmap = Bitmap.createBitmap(\n                imageBitmap.asAndroidBitmap(),\n                cropRect.left.toInt(),\n                cropRect.top.toInt(),\n                cropRect.width.toInt(),\n                cropRect.height.toInt(),\n            )\n\n            val imageToCrop = croppedBitmap\n                .copy(Bitmap.Config.ARGB_8888, true)!!\n                .asImageBitmap()\n\n            drawCroppedImage(cropOutline, cropRect, layoutDirection, density, imageToCrop)\n\n            imageToCrop\n        }.getOrNull() ?: imageBitmap\n    }\n\n    private fun drawCroppedImage(\n        cropOutline: CropOutline,\n        cropRect: Rect,\n        layoutDirection: LayoutDirection,\n        density: Density,\n        imageToCrop: ImageBitmap,\n    ) {\n\n        when (cropOutline) {\n            is CropShape -> {\n\n                val path = Path().apply {\n                    val outline =\n                        cropOutline.shape.createOutline(cropRect.size, layoutDirection, density)\n                    addOutline(outline)\n                }\n\n                Canvas(image = imageToCrop).run {\n                    saveLayer(nativeCanvas.clipBounds.toComposeRect(), imagePaint)\n\n                    // Destination\n                    drawPath(path, paint)\n\n                    // Source\n                    drawImage(\n                        image = imageToCrop,\n                        topLeftOffset = Offset.Zero,\n                        paint = imagePaint\n                    )\n                    restore()\n                }\n            }\n\n            is CropPath -> {\n\n                val path = Path().apply {\n\n                    addPath(cropOutline.path)\n\n                    val pathSize = getBounds().size\n                    val rectSize = cropRect.size\n\n                    val matrix = android.graphics.Matrix()\n                    matrix.postScale(\n                        rectSize.width / pathSize.width,\n                        cropRect.height / pathSize.height\n                    )\n                    this.asAndroidPath().transform(matrix)\n\n                    val left = getBounds().left\n                    val top = getBounds().top\n\n                    translate(Offset(-left, -top))\n                }\n\n                Canvas(image = imageToCrop).run {\n                    saveLayer(nativeCanvas.clipBounds.toComposeRect(), imagePaint)\n\n                    // Destination\n                    drawPath(path, paint)\n\n                    // Source\n                    drawImage(image = imageToCrop, topLeftOffset = Offset.Zero, imagePaint)\n                    restore()\n                }\n            }\n\n            is CropImageMask -> {\n\n                val imageMask = cropOutline.image.asAndroidBitmap()\n                    .scale(cropRect.width.toInt(), cropRect.height.toInt()).asImageBitmap()\n\n                Canvas(image = imageToCrop).run {\n                    saveLayer(nativeCanvas.clipBounds.toComposeRect(), imagePaint)\n\n                    // Destination\n                    drawImage(imageMask, topLeftOffset = Offset.Zero, paint)\n\n                    // Source\n                    drawImage(image = imageToCrop, topLeftOffset = Offset.Zero, imagePaint)\n\n                    restore()\n                }\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/draw/ImageDrawCanvas.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.draw\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.IntSize\nimport kotlin.math.roundToInt\n\n/**\n * Draw image to be cropped\n */\n@Composable\ninternal fun ImageDrawCanvas(\n    modifier: Modifier,\n    imageBitmap: ImageBitmap,\n    imageWidth: Int,\n    imageHeight: Int\n) {\n    Canvas(modifier = modifier) {\n\n        val canvasWidth = size.width.roundToInt()\n        val canvasHeight = size.height.roundToInt()\n\n        drawImage(\n            image = imageBitmap,\n            srcSize = IntSize(imageBitmap.width, imageBitmap.height),\n            dstSize = IntSize(imageWidth, imageHeight),\n            dstOffset = IntOffset(\n                x = (canvasWidth - imageWidth) / 2,\n                y = (canvasHeight - imageHeight) / 2\n            )\n        )\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/draw/Overlay.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.draw\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.StrokeJoin\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport com.t8rin.cropper.model.CropImageMask\nimport com.t8rin.cropper.model.CropOutline\nimport com.t8rin.cropper.model.CropPath\nimport com.t8rin.cropper.model.CropShape\nimport com.t8rin.cropper.util.drawGrid\nimport com.t8rin.cropper.util.drawWithLayer\nimport com.t8rin.cropper.util.scaleAndTranslatePath\n\n/**\n * Draw overlay composed of 9 rectangles. When [drawHandles]\n * is set draw handles for changing drawing rectangle\n */\n@Composable\ninternal fun DrawingOverlay(\n    modifier: Modifier,\n    drawOverlay: Boolean,\n    rect: Rect,\n    cropOutline: CropOutline,\n    drawGrid: Boolean,\n    transparentColor: Color,\n    overlayColor: Color,\n    handleColor: Color,\n    strokeWidth: Dp,\n    drawHandles: Boolean,\n    handleSize: Float,\n    middleHandleSize: Float,\n) {\n    val density = LocalDensity.current\n    val layoutDirection: LayoutDirection = LocalLayoutDirection.current\n\n    val strokeWidthPx = LocalDensity.current.run { strokeWidth.toPx() }\n\n    val pathHandles = remember {\n        Path()\n    }\n\n    val middlePathHandles = remember {\n        Path()\n    }\n\n    when (cropOutline) {\n        is CropShape -> {\n\n            val outline = remember(rect, cropOutline) {\n                cropOutline.shape.createOutline(rect.size, layoutDirection, density)\n            }\n\n            DrawingOverlayImpl(\n                modifier = modifier,\n                drawOverlay = drawOverlay,\n                rect = rect,\n                drawGrid = drawGrid,\n                transparentColor = transparentColor,\n                overlayColor = overlayColor,\n                handleColor = handleColor,\n                strokeWidth = strokeWidthPx,\n                drawHandles = drawHandles,\n                handleSize = handleSize,\n                middleHandleSize = middleHandleSize,\n                pathHandles = pathHandles,\n                middlePathHandles = middlePathHandles,\n                outline = outline\n            )\n        }\n\n        is CropPath -> {\n            val path = remember(rect, cropOutline) {\n                Path().apply {\n                    addPath(cropOutline.path)\n                    scaleAndTranslatePath(rect.width, rect.height)\n                }\n            }\n\n\n            DrawingOverlayImpl(\n                modifier = modifier,\n                drawOverlay = drawOverlay,\n                rect = rect,\n                drawGrid = drawGrid,\n                transparentColor = transparentColor,\n                overlayColor = overlayColor,\n                handleColor = handleColor,\n                strokeWidth = strokeWidthPx,\n                drawHandles = drawHandles,\n                handleSize = handleSize,\n                middleHandleSize = middleHandleSize,\n                pathHandles = pathHandles,\n                middlePathHandles = middlePathHandles,\n                path = path\n            )\n        }\n\n        is CropImageMask -> {\n            val imageBitmap = cropOutline.image\n\n            DrawingOverlayImpl(\n                modifier = modifier,\n                drawOverlay = drawOverlay,\n                rect = rect,\n                drawGrid = drawGrid,\n                transparentColor = transparentColor,\n                overlayColor = overlayColor,\n                handleColor = handleColor,\n                strokeWidth = strokeWidthPx,\n                drawHandles = drawHandles,\n                handleSize = handleSize,\n                middleHandleSize = middleHandleSize,\n                pathHandles = pathHandles,\n                middlePathHandles = middlePathHandles,\n                image = imageBitmap\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun DrawingOverlayImpl(\n    modifier: Modifier,\n    drawOverlay: Boolean,\n    rect: Rect,\n    drawGrid: Boolean,\n    transparentColor: Color,\n    overlayColor: Color,\n    handleColor: Color,\n    strokeWidth: Float,\n    drawHandles: Boolean,\n    handleSize: Float,\n    middleHandleSize: Float,\n    pathHandles: Path,\n    middlePathHandles: Path,\n    outline: Outline,\n) {\n    Canvas(modifier = modifier) {\n        drawOverlay(\n            drawOverlay = drawOverlay,\n            rect = rect,\n            drawGrid = drawGrid,\n            transparentColor = transparentColor,\n            overlayColor = overlayColor,\n            handleColor = handleColor,\n            strokeWidth = strokeWidth,\n            drawHandles = drawHandles,\n            handleSize = handleSize,\n            middleHandleSize = middleHandleSize,\n            pathHandles = pathHandles,\n            middlePathHandles = middlePathHandles\n        ) {\n            drawCropOutline(outline = outline)\n        }\n    }\n}\n\n@Composable\nprivate fun DrawingOverlayImpl(\n    modifier: Modifier,\n    drawOverlay: Boolean,\n    rect: Rect,\n    drawGrid: Boolean,\n    transparentColor: Color,\n    overlayColor: Color,\n    handleColor: Color,\n    strokeWidth: Float,\n    drawHandles: Boolean,\n    handleSize: Float,\n    middleHandleSize: Float,\n    pathHandles: Path,\n    middlePathHandles: Path,\n    path: Path,\n) {\n    Canvas(modifier = modifier) {\n        drawOverlay(\n            drawOverlay = drawOverlay,\n            rect = rect,\n            drawGrid = drawGrid,\n            transparentColor = transparentColor,\n            overlayColor = overlayColor,\n            handleColor = handleColor,\n            strokeWidth = strokeWidth,\n            drawHandles = drawHandles,\n            handleSize = handleSize,\n            middleHandleSize = middleHandleSize,\n            pathHandles = pathHandles,\n            middlePathHandles = middlePathHandles\n        ) {\n            drawCropPath(path)\n        }\n    }\n}\n\n@Composable\nprivate fun DrawingOverlayImpl(\n    modifier: Modifier,\n    drawOverlay: Boolean,\n    rect: Rect,\n    drawGrid: Boolean,\n    transparentColor: Color,\n    overlayColor: Color,\n    handleColor: Color,\n    strokeWidth: Float,\n    drawHandles: Boolean,\n    handleSize: Float,\n    middleHandleSize: Float,\n    pathHandles: Path,\n    middlePathHandles: Path,\n    image: ImageBitmap,\n) {\n    Canvas(modifier = modifier) {\n        drawOverlay(\n            drawOverlay = drawOverlay,\n            rect = rect,\n            drawGrid = drawGrid,\n            transparentColor = transparentColor,\n            overlayColor = overlayColor,\n            handleColor = handleColor,\n            strokeWidth = strokeWidth,\n            drawHandles = drawHandles,\n            handleSize = handleSize,\n            middleHandleSize = middleHandleSize,\n            pathHandles = pathHandles,\n            middlePathHandles = middlePathHandles\n        ) {\n            drawCropImage(rect, image)\n        }\n    }\n}\n\nprivate fun DrawScope.drawOverlay(\n    drawOverlay: Boolean,\n    rect: Rect,\n    drawGrid: Boolean,\n    transparentColor: Color,\n    overlayColor: Color,\n    handleColor: Color,\n    strokeWidth: Float,\n    drawHandles: Boolean,\n    handleSize: Float,\n    middleHandleSize: Float,\n    pathHandles: Path,\n    middlePathHandles: Path,\n    drawBlock: DrawScope.() -> Unit\n) {\n    drawWithLayer {\n\n        // Destination\n        drawRect(transparentColor)\n\n        // Source\n        translate(left = rect.left, top = rect.top) {\n            drawBlock()\n        }\n\n        if (drawGrid) {\n            drawGrid(\n                rect = rect,\n                strokeWidth = strokeWidth,\n                color = overlayColor\n            )\n        }\n    }\n\n    if (drawOverlay) {\n        drawRect(\n            topLeft = rect.topLeft,\n            size = rect.size,\n            color = overlayColor,\n            style = Stroke(width = strokeWidth)\n        )\n\n        if (drawHandles) {\n            pathHandles.apply {\n                reset()\n                updateHandlePath(rect, handleSize)\n            }\n\n            middlePathHandles.apply {\n                reset()\n                updateMiddleHandlePath(rect, middleHandleSize)\n            }\n\n            drawPath(\n                path = middlePathHandles,\n                color = handleColor.copy(0.9f).compositeOver(Color.Black),\n                style = Stroke(\n                    width = strokeWidth * 4,\n                    cap = StrokeCap.Round,\n                    join = StrokeJoin.Round\n                )\n            )\n\n            drawPath(\n                path = pathHandles,\n                color = handleColor,\n                style = Stroke(\n                    width = strokeWidth * 4,\n                    cap = StrokeCap.Round,\n                    join = StrokeJoin.Round\n                )\n            )\n        }\n    }\n}\n\nprivate fun DrawScope.drawCropImage(\n    rect: Rect,\n    imageBitmap: ImageBitmap,\n    blendMode: BlendMode = BlendMode.DstOut\n) {\n    drawImage(\n        image = imageBitmap,\n        dstSize = IntSize(rect.size.width.toInt(), rect.size.height.toInt()),\n        blendMode = blendMode\n    )\n}\n\nprivate fun DrawScope.drawCropOutline(\n    outline: Outline,\n    blendMode: BlendMode = BlendMode.SrcOut\n) {\n    drawOutline(\n        outline = outline,\n        color = Color.Transparent,\n        blendMode = blendMode\n    )\n}\n\nprivate fun DrawScope.drawCropPath(\n    path: Path,\n    blendMode: BlendMode = BlendMode.SrcOut\n) {\n    drawPath(\n        path = path,\n        color = Color.Transparent,\n        blendMode = blendMode\n    )\n}\n\nprivate fun Path.updateHandlePath(\n    rect: Rect,\n    handleSize: Float\n) {\n    if (rect != Rect.Zero) {\n        // Top left lines\n        moveTo(rect.topLeft.x, rect.topLeft.y + handleSize)\n        lineTo(rect.topLeft.x, rect.topLeft.y)\n        lineTo(rect.topLeft.x + handleSize, rect.topLeft.y)\n\n        // Top right lines\n        moveTo(rect.topRight.x - handleSize, rect.topRight.y)\n        lineTo(rect.topRight.x, rect.topRight.y)\n        lineTo(rect.topRight.x, rect.topRight.y + handleSize)\n\n        // Bottom right lines\n        moveTo(rect.bottomRight.x, rect.bottomRight.y - handleSize)\n        lineTo(rect.bottomRight.x, rect.bottomRight.y)\n        lineTo(rect.bottomRight.x - handleSize, rect.bottomRight.y)\n\n        // Bottom left lines\n        moveTo(rect.bottomLeft.x + handleSize, rect.bottomLeft.y)\n        lineTo(rect.bottomLeft.x, rect.bottomLeft.y)\n        lineTo(rect.bottomLeft.x, rect.bottomLeft.y - handleSize)\n    }\n}\n\n\nprivate fun Path.updateMiddleHandlePath(\n    rect: Rect,\n    handleSize: Float\n) {\n    if (rect != Rect.Zero) {\n        // Top middle lines\n        moveTo(rect.topCenter.x - handleSize / 2, rect.topCenter.y)\n        lineTo(rect.topCenter.x + handleSize / 2, rect.topCenter.y)\n\n        // Right middle lines\n        moveTo(rect.centerRight.x, rect.centerRight.y - handleSize / 2)\n        lineTo(rect.centerRight.x, rect.centerRight.y + handleSize / 2)\n\n        // Bottom middle lines\n        moveTo(rect.bottomCenter.x - handleSize / 2, rect.bottomCenter.y)\n        lineTo(rect.bottomCenter.x + handleSize / 2, rect.bottomCenter.y)\n\n        // Left middle lines\n        moveTo(rect.centerLeft.x, rect.centerLeft.y - handleSize / 2)\n        lineTo(rect.centerLeft.x, rect.centerLeft.y + handleSize / 2)\n    }\n}"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/image/ImageScope.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.image\n\nimport android.graphics.Bitmap\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntRect\n\n\n/**\n * Receiver scope being used by the children parameter of [ImageWithConstraints]\n */\n@Stable\ninterface ImageScope {\n    /**\n     * The constraints given by the parent layout in pixels.\n     *\n     * Use [minWidth], [maxWidth], [minHeight] or [maxHeight] if you need value in [Dp].\n     */\n    val constraints: Constraints\n\n    /**\n     * The minimum width in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val minWidth: Dp\n\n    /**\n     * The maximum width in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val maxWidth: Dp\n\n    /**\n     * The minimum height in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val minHeight: Dp\n\n    /**\n     * The maximum height in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val maxHeight: Dp\n\n    /**\n     * Width of area inside BoxWithConstraints that is scaled based on [ContentScale]\n     * This is width of the [Canvas] draw [ImageBitmap]\n     */\n    val imageWidth: Dp\n\n    /**\n     * Height of area inside BoxWithConstraints that is scaled based on [ContentScale]\n     * This is height of the [Canvas] draw [ImageBitmap]\n     */\n    val imageHeight: Dp\n\n    /**\n     * [IntRect] that covers boundaries of [ImageBitmap]\n     */\n    val rect: IntRect\n}\n\ninternal data class ImageScopeImpl(\n    private val density: Density,\n    override val constraints: Constraints,\n    override val imageWidth: Dp,\n    override val imageHeight: Dp,\n    override val rect: IntRect,\n) : ImageScope {\n\n    override val minWidth: Dp get() = with(density) { constraints.minWidth.toDp() }\n\n    override val maxWidth: Dp\n        get() = with(density) {\n            if (constraints.hasBoundedWidth) constraints.maxWidth.toDp() else Dp.Infinity\n        }\n\n    override val minHeight: Dp get() = with(density) { constraints.minHeight.toDp() }\n\n    override val maxHeight: Dp\n        get() = with(density) {\n            if (constraints.hasBoundedHeight) constraints.maxHeight.toDp() else Dp.Infinity\n        }\n}\n\n@Composable\ninternal fun getScaledImageBitmap(\n    imageWidth: Dp,\n    imageHeight: Dp,\n    rect: IntRect,\n    bitmap: ImageBitmap,\n    contentScale: ContentScale\n): ImageBitmap {\n\n    val scaledBitmap =\n        remember(bitmap, rect, imageWidth, imageHeight, contentScale) {\n            // This bitmap is needed when we crop original bitmap due to scaling mode\n            // and aspect ratio result of cropping\n            // We might have center section of the image after cropping, and\n            // because of that thumbLayout either should have rectangle and some\n            // complex calculation for srcOffset and srcSide along side with touch offset\n            // or we can create a new bitmap that only contains area bounded by rectangle\n            runCatching {\n                Bitmap.createBitmap(\n                    bitmap.asAndroidBitmap(),\n                    rect.left,\n                    rect.top,\n                    rect.width,\n                    rect.height\n                ).asImageBitmap()\n            }.getOrNull() ?: bitmap\n        }\n    return scaledBitmap\n}"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/image/ImageWithConstraints.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.image\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.DefaultAlpha\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.contentDescription\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntRect\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.cropper.util.getParentSize\nimport com.t8rin.cropper.util.getScaledBitmapRect\n\n\n/**\n * A composable that lays out and draws a given [ImageBitmap]. This will attempt to\n * size the composable according to the [ImageBitmap]'s given width and height. However, an\n * optional [Modifier] parameter can be provided to adjust sizing or draw additional content (ex.\n * background). Any unspecified dimension will leverage the [ImageBitmap]'s size as a minimum\n * constraint.\n *\n * [ImageScope] returns constraints, width and height of the drawing area based on [contentScale]\n * and rectangle of [imageBitmap] drawn. When a bitmap is displayed scaled to fit area of Composable\n * space used for drawing image is represented with [ImageScope.imageWidth] and\n * [ImageScope.imageHeight].\n *\n * When we display a bitmap 1000x1000px with [ContentScale.Crop] if it's cropped to 500x500px\n * [ImageScope.rect] returns `IntRect(250,250,750,750)`.\n *\n * @param alignment determines where image will be aligned inside [BoxWithConstraints]\n * This is observable when bitmap image/width ratio differs from [Canvas] that draws [ImageBitmap]\n * @param contentDescription text used by accessibility services to describe what this image\n * represents. This should always be provided unless this image is used for decorative purposes,\n * and does not represent a meaningful action that a user can take. This text should be\n * localized, such as by using [androidx.compose.ui.res.stringResource] or similar\n * @param contentScale how image should be scaled inside Canvas to match parent dimensions.\n * [ContentScale.Fit] for instance maintains src ratio and scales image to fit inside the parent.\n * @param alpha Opacity to be applied to [imageBitmap] from 0.0f to 1.0f representing\n * fully transparent to fully opaque respectively\n * @param colorFilter ColorFilter to apply to the [imageBitmap] when drawn into the destination\n * @param filterQuality Sampling algorithm applied to the [imageBitmap] when it is scaled and drawn\n * into the destination. The default is [FilterQuality.Low] which scales using a bilinear\n * sampling algorithm\n * @param content is a Composable that can be matched at exact position where [imageBitmap] is drawn.\n * This is useful for drawing thumbs, cropping or another layout that should match position\n * with the image that is scaled is drawn\n * @param drawImage flag to draw image on canvas. Some Composables might only require\n * the calculation and rectangle bounds of image after scaling but not drawing.\n * Composables like image cropper that scales or\n * rotates image. Drawing here again have 2 drawings overlap each other.\n */\n@Composable\ninternal fun ImageWithConstraints(\n    modifier: Modifier = Modifier,\n    imageBitmap: ImageBitmap,\n    alignment: Alignment = Alignment.Center,\n    contentScale: ContentScale = ContentScale.Fit,\n    contentDescription: String? = null,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    drawImage: Boolean = true,\n    content: @Composable ImageScope.() -> Unit = {}\n) {\n\n    val semantics = if (contentDescription != null) {\n        Modifier.semantics {\n            this.contentDescription = contentDescription\n            this.role = Role.Image\n        }\n    } else {\n        Modifier\n    }\n\n    BoxWithConstraints(\n        modifier = modifier\n            .then(semantics),\n        contentAlignment = alignment,\n    ) {\n\n        val bitmapWidth = imageBitmap.width\n        val bitmapHeight = imageBitmap.height\n\n        val (boxWidth: Int, boxHeight: Int) = getParentSize(bitmapWidth, bitmapHeight)\n\n        // Src is Bitmap, Dst is the container(Image) that Bitmap will be displayed\n        val srcSize = Size(bitmapWidth.toFloat(), bitmapHeight.toFloat())\n        val dstSize = Size(boxWidth.toFloat(), boxHeight.toFloat())\n\n        val scaleFactor = contentScale.computeScaleFactor(srcSize, dstSize)\n\n        // Image is the container for bitmap that is located inside Box\n        // image bounds can be smaller or bigger than its parent based on how it's scaled\n        val imageWidth = bitmapWidth * scaleFactor.scaleX\n        val imageHeight = bitmapHeight * scaleFactor.scaleY\n\n        val bitmapRect = getScaledBitmapRect(\n            boxWidth = boxWidth,\n            boxHeight = boxHeight,\n            imageWidth = imageWidth,\n            imageHeight = imageHeight,\n            bitmapWidth = bitmapWidth,\n            bitmapHeight = bitmapHeight\n        )\n\n        ImageLayout(\n            constraints = constraints,\n            imageBitmap = imageBitmap,\n            bitmapRect = bitmapRect,\n            imageWidth = imageWidth,\n            imageHeight = imageHeight,\n            boxWidth = boxWidth,\n            boxHeight = boxHeight,\n            alpha = alpha,\n            colorFilter = colorFilter,\n            filterQuality = filterQuality,\n            drawImage = drawImage,\n            content = content\n        )\n    }\n}\n\n@Composable\nprivate fun ImageLayout(\n    constraints: Constraints,\n    imageBitmap: ImageBitmap,\n    bitmapRect: IntRect,\n    imageWidth: Float,\n    imageHeight: Float,\n    boxWidth: Int,\n    boxHeight: Int,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    drawImage: Boolean = true,\n    content: @Composable ImageScope.() -> Unit\n) {\n    val density = LocalDensity.current\n\n    // Dimensions of canvas that will draw this Bitmap\n    val canvasWidthInDp: Dp\n    val canvasHeightInDp: Dp\n\n    with(density) {\n        canvasWidthInDp = imageWidth.coerceAtMost(boxWidth.toFloat()).toDp()\n        canvasHeightInDp = imageHeight.coerceAtMost(boxHeight.toFloat()).toDp()\n    }\n\n    // Send rectangle of Bitmap drawn to Canvas as bitmapRect, content scale modes like\n    // crop might crop image from center so Rect can be such as IntRect(250,250,500,500)\n\n    // canvasWidthInDp, and  canvasHeightInDp are Canvas dimensions coerced to Box size\n    // that covers Canvas\n    val imageScopeImpl = ImageScopeImpl(\n        density = density,\n        constraints = constraints,\n        imageWidth = canvasWidthInDp,\n        imageHeight = canvasHeightInDp,\n        rect = bitmapRect\n    )\n\n    // width and height params for translating draw position if scaled Image dimensions are\n    // bigger than Canvas dimensions\n    if (drawImage) {\n        ImageImpl(\n            modifier = Modifier.size(canvasWidthInDp, canvasHeightInDp),\n            imageBitmap = imageBitmap,\n            alpha = alpha,\n            width = imageWidth.toInt(),\n            height = imageHeight.toInt(),\n            colorFilter = colorFilter,\n            filterQuality = filterQuality\n        )\n    }\n\n    imageScopeImpl.content()\n}\n\n@Composable\nprivate fun ImageImpl(\n    modifier: Modifier,\n    imageBitmap: ImageBitmap,\n    width: Int,\n    height: Int,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n) {\n    val bitmapWidth = imageBitmap.width\n    val bitmapHeight = imageBitmap.height\n\n    Canvas(modifier = modifier.clipToBounds()) {\n\n        val canvasWidth = size.width.toInt()\n        val canvasHeight = size.height.toInt()\n\n        // Translate to left or down when Image size is bigger than this canvas.\n        // ImageSize is bigger when scale modes like Crop is used which enlarges image\n        // For instance 1000x1000 image can be 1000x2000 for a Canvas with 1000x1000\n        // so top is translated -500 to draw center of ImageBitmap\n        translate(\n            top = (-height + canvasHeight) / 2f,\n            left = (-width + canvasWidth) / 2f,\n\n            ) {\n            drawImage(\n                imageBitmap,\n                srcSize = IntSize(bitmapWidth, bitmapHeight),\n                dstSize = IntSize(width, height),\n                alpha = alpha,\n                colorFilter = colorFilter,\n                filterQuality = filterQuality\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/model/AspectRatios.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.model\n\nimport com.t8rin.cropper.util.createRectShape\n\n/**\n * Aspect ratio list with pre-defined aspect ratios\n */\nval aspectRatios = listOf(\n    CropAspectRatio(\n        title = \"9:16\",\n        shape = createRectShape(AspectRatio(9 / 16f)),\n        aspectRatio = AspectRatio(9 / 16f)\n    ),\n    CropAspectRatio(\n        title = \"2:3\",\n        shape = createRectShape(AspectRatio(2 / 3f)),\n        aspectRatio = AspectRatio(2 / 3f)\n    ),\n    CropAspectRatio(\n        title = \"Original\",\n        shape = createRectShape(AspectRatio.Original),\n        aspectRatio = AspectRatio.Original\n    ),\n    CropAspectRatio(\n        title = \"1:1\",\n        shape = createRectShape(AspectRatio(1 / 1f)),\n        aspectRatio = AspectRatio(1 / 1f)\n    ),\n    CropAspectRatio(\n        title = \"16:9\",\n        shape = createRectShape(AspectRatio(16 / 9f)),\n        aspectRatio = AspectRatio(16 / 9f)\n    ),\n    CropAspectRatio(\n        title = \"1.91:1\",\n        shape = createRectShape(AspectRatio(1.91f / 1f)),\n        aspectRatio = AspectRatio(1.91f / 1f)\n    ),\n    CropAspectRatio(\n        title = \"3:2\",\n        shape = createRectShape(AspectRatio(3 / 2f)),\n        aspectRatio = AspectRatio(3 / 2f)\n    ),\n    CropAspectRatio(\n        title = \"3:4\",\n        shape = createRectShape(AspectRatio(3 / 4f)),\n        aspectRatio = AspectRatio(3 / 4f)\n    ),\n    CropAspectRatio(\n        title = \"3:5\",\n        shape = createRectShape(AspectRatio(3 / 5f)),\n        aspectRatio = AspectRatio(3 / 5f)\n    )\n)"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/model/CropAspectRatio.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.model\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.graphics.Shape\n\n/**\n * Model for drawing title with shape for crop selection menu. Aspect ratio is used\n * for setting overlay in state and UI\n */\n@Immutable\ndata class CropAspectRatio(\n    val title: String,\n    val shape: Shape,\n    val aspectRatio: AspectRatio = AspectRatio.Original,\n    val icons: List<Int> = listOf()\n)\n\n/**\n * Value class for containing aspect ratio\n * and [AspectRatio.Original] for comparing\n */\n@Immutable\ndata class AspectRatio(val value: Float) {\n    companion object {\n        val Original = AspectRatio(-1f)\n    }\n}"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/model/CropData.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.model\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\n\n\n/**\n * Class that contains information about\n * current zoom, pan and rotation, and rectangle of zoomed and panned area for cropping [cropRect],\n * and area of overlay as[overlayRect]\n *\n */\n@Immutable\ndata class CropData(\n    val zoom: Float = 1f,\n    val pan: Offset = Offset.Zero,\n    val rotation: Float = 0f,\n    val overlayRect: Rect,\n    val cropRect: Rect\n)\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/model/CropOutline.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.model\n\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.foundation.shape.CutCornerShape\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport com.t8rin.cropper.util.createPolygonShape\n\n/**\n * Common ancestor for list of shapes, paths or images to crop inside [CropOutlineContainer]\n */\ninterface CropOutline {\n    val id: Int\n    val title: String\n}\n\n/**\n * Crop outline that contains a [Shape] like [RectangleShape] to draw frame for cropping\n */\ninterface CropShape : CropOutline {\n    val shape: Shape\n}\n\n/**\n * Crop outline that contains a [Path] to draw frame for cropping\n */\ninterface CropPath : CropOutline {\n    val path: Path\n}\n\n/**\n * Crop outline that contains a [ImageBitmap]  to draw frame for cropping. And blend modes\n * to draw\n */\ninterface CropImageMask : CropOutline {\n    val image: ImageBitmap\n}\n\n/**\n * Wrapper class that implements [CropOutline] and is a shape\n * wrapper that contains [RectangleShape]\n */\n@Immutable\ndata class RectCropShape(\n    override val id: Int,\n    override val title: String,\n) : CropShape {\n    override val shape: Shape = RectangleShape\n}\n\n/**\n * Wrapper class that implements [CropOutline] and is a shape\n * wrapper that contains [RoundedCornerShape]\n */\n@Immutable\ndata class RoundedCornerCropShape(\n    override val id: Int,\n    override val title: String,\n    val cornerRadius: CornerRadiusProperties = CornerRadiusProperties(),\n    override val shape: RoundedCornerShape = RoundedCornerShape(\n        topStartPercent = cornerRadius.topStartPercent,\n        topEndPercent = cornerRadius.topEndPercent,\n        bottomEndPercent = cornerRadius.bottomEndPercent,\n        bottomStartPercent = cornerRadius.bottomStartPercent\n    )\n) : CropShape\n\n/**\n * Wrapper class that implements [CropOutline] and is a shape\n * wrapper that contains [CutCornerShape]\n */\n@Immutable\ndata class CutCornerCropShape(\n    override val id: Int,\n    override val title: String,\n    val cornerRadius: CornerRadiusProperties = CornerRadiusProperties(),\n    override val shape: CutCornerShape = CutCornerShape(\n        topStartPercent = cornerRadius.topStartPercent,\n        topEndPercent = cornerRadius.topEndPercent,\n        bottomEndPercent = cornerRadius.bottomEndPercent,\n        bottomStartPercent = cornerRadius.bottomStartPercent\n    )\n) : CropShape\n\n/**\n * Wrapper class that implements [CropOutline] and is a shape\n * wrapper that contains [CircleShape]\n */\n@Immutable\ndata class OvalCropShape(\n    override val id: Int,\n    override val title: String,\n    val ovalProperties: OvalProperties = OvalProperties(),\n    override val shape: Shape = CircleShape\n) : CropShape\n\n\n/**\n * Wrapper class that implements [CropOutline] and is a shape\n * wrapper that contains [CircleShape]\n */\n@Immutable\ndata class PolygonCropShape(\n    override val id: Int,\n    override val title: String,\n    val polygonProperties: PolygonProperties = PolygonProperties(),\n    override val shape: Shape = createPolygonShape(polygonProperties.sides, polygonProperties.angle)\n) : CropShape\n\n/**\n * Wrapper class that implements [CropOutline] and is a [Path] wrapper to crop using drawable\n * files converted fom svg or Vector Drawable to [Path]\n */\n@Immutable\ndata class CustomPathOutline(\n    override val id: Int,\n    override val title: String,\n    override val path: Path\n) : CropPath\n\n/**\n * Wrapper class that implements [CropOutline] and is a [ImageBitmap] wrapper to crop\n * using a reference png and blend modes to crop\n */\n@Immutable\ndata class ImageMaskOutline(\n    override val id: Int,\n    override val title: String,\n    override val image: ImageBitmap,\n) : CropImageMask\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/model/CropOutlineContainer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.model\n\n/**\n * Interface for containing multiple [CropOutline]s, currently selected item and index\n * for displaying on settings UI\n */\ninterface CropOutlineContainer<O : CropOutline> {\n    var selectedIndex: Int\n    val outlines: List<O>\n    val selectedItem: O\n        get() = outlines[selectedIndex]\n    val size: Int\n        get() = outlines.size\n}\n\n/**\n * Container for [RectCropShape]\n */\ndata class RectOutlineContainer(\n    override var selectedIndex: Int = 0,\n    override val outlines: List<RectCropShape>\n) : CropOutlineContainer<RectCropShape>\n\n/**\n * Container for [RoundedCornerCropShape]s\n */\ndata class RoundedRectOutlineContainer(\n    override var selectedIndex: Int = 0,\n    override val outlines: List<RoundedCornerCropShape>\n) : CropOutlineContainer<RoundedCornerCropShape>\n\n/**\n * Container for [CutCornerCropShape]s\n */\ndata class CutCornerRectOutlineContainer(\n    override var selectedIndex: Int = 0,\n    override val outlines: List<CutCornerCropShape>\n) : CropOutlineContainer<CutCornerCropShape>\n\n/**\n * Container for [OvalCropShape]s\n */\ndata class OvalOutlineContainer(\n    override var selectedIndex: Int = 0,\n    override val outlines: List<OvalCropShape>\n) : CropOutlineContainer<OvalCropShape>\n\n/**\n * Container for [PolygonCropShape]s\n */\ndata class PolygonOutlineContainer(\n    override var selectedIndex: Int = 0,\n    override val outlines: List<PolygonCropShape>\n) : CropOutlineContainer<PolygonCropShape>\n\n/**\n * Container for [CustomPathOutline]s\n */\ndata class CustomOutlineContainer(\n    override var selectedIndex: Int = 0,\n    override val outlines: List<CustomPathOutline>\n) : CropOutlineContainer<CustomPathOutline>\n\n/**\n * Container for [ImageMaskOutline]s\n */\ndata class ImageMaskOutlineContainer(\n    override var selectedIndex: Int = 0,\n    override val outlines: List<ImageMaskOutline>\n) : CropOutlineContainer<ImageMaskOutline>\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/model/CropOutlineProperties.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.model\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.geometry.Offset\n\n@Immutable\ndata class CornerRadiusProperties(\n    val topStartPercent: Int = 20,\n    val topEndPercent: Int = 20,\n    val bottomStartPercent: Int = 20,\n    val bottomEndPercent: Int = 20\n)\n\n@Immutable\ndata class PolygonProperties(\n    val sides: Int = 6,\n    val angle: Float = 0f,\n    val offset: Offset = Offset.Zero\n)\n\n@Immutable\ndata class OvalProperties(\n    val startAngle: Float = 0f,\n    val sweepAngle: Float = 360f,\n    val offset: Offset = Offset.Zero\n)\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/model/OutlineType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.model\n\nenum class OutlineType {\n    Rect, RoundedRect, CutCorner, Oval, Polygon, Custom, ImageMask\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/settings/CropDefaults.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.settings\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.cropper.ImageCropper\nimport com.t8rin.cropper.crop\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.model.CropOutline\nimport com.t8rin.cropper.model.OutlineType\nimport com.t8rin.cropper.model.aspectRatios\nimport com.t8rin.cropper.state.CropState\n\n/**\n * Contains the default values used by [ImageCropper]\n */\nobject CropDefaults {\n\n    /**\n     * Properties effect crop behavior that should be passed to [CropState]\n     */\n    fun properties(\n        cropType: CropType = CropType.Dynamic,\n        handleSize: Float = 60f,\n        middleHandleSize: Float = handleSize * 1.5f,\n        maxZoom: Float = 10f,\n        contentScale: ContentScale = ContentScale.Fit,\n        cropOutlineProperty: CropOutlineProperty,\n        aspectRatio: AspectRatio = aspectRatios[2].aspectRatio,\n        overlayRatio: Float = .9f,\n        pannable: Boolean = true,\n        fling: Boolean = false,\n        zoomable: Boolean = true,\n        rotatable: Boolean = false,\n        minDimension: IntSize? = null,\n        fixedAspectRatio: Boolean = false,\n    ): CropProperties {\n        return CropProperties(\n            cropType = cropType,\n            handleSize = handleSize,\n            middleHandleSize = middleHandleSize,\n            contentScale = contentScale,\n            cropOutlineProperty = cropOutlineProperty,\n            maxZoom = maxZoom,\n            aspectRatio = aspectRatio,\n            overlayRatio = overlayRatio,\n            pannable = pannable,\n            fling = fling,\n            zoomable = zoomable,\n            rotatable = rotatable,\n            minDimension = minDimension,\n            fixedAspectRatio = fixedAspectRatio,\n        )\n    }\n\n    /**\n     * Style is cosmetic changes that don't effect how [CropState] behaves because of that\n     * none of these properties are passed to [CropState]\n     */\n    fun style(\n        drawOverlay: Boolean = true,\n        drawGrid: Boolean = true,\n        strokeWidth: Dp = 1.dp,\n        overlayColor: Color = DefaultOverlayColor,\n        handleColor: Color = DefaultHandleColor,\n        backgroundColor: Color = DefaultBackgroundColor\n    ): CropStyle {\n        return CropStyle(\n            drawOverlay = drawOverlay,\n            drawGrid = drawGrid,\n            strokeWidth = strokeWidth,\n            overlayColor = overlayColor,\n            handleColor = handleColor,\n            backgroundColor = backgroundColor\n        )\n    }\n}\n\n/**\n * Data class for selecting cropper properties. Fields of this class control inner work\n * of [CropState] while some such as [cropType], [aspectRatio], [handleSize]\n * is shared between ui and state.\n */\n@Immutable\ndata class CropProperties(\n    val cropType: CropType,\n    val handleSize: Float,\n    val middleHandleSize: Float,\n    val contentScale: ContentScale,\n    val cropOutlineProperty: CropOutlineProperty,\n    val aspectRatio: AspectRatio,\n    val overlayRatio: Float,\n    val pannable: Boolean,\n    val fling: Boolean,\n    val rotatable: Boolean,\n    val zoomable: Boolean,\n    val maxZoom: Float,\n    val minDimension: IntSize? = null,\n    val fixedAspectRatio: Boolean = false,\n)\n\n/**\n * Data class for cropper styling only. None of the properties of this class is used\n * by [CropState] or [Modifier.crop]\n */\n@Immutable\ndata class CropStyle(\n    val drawOverlay: Boolean,\n    val drawGrid: Boolean,\n    val strokeWidth: Dp,\n    val overlayColor: Color,\n    val handleColor: Color,\n    val backgroundColor: Color,\n    val cropTheme: CropTheme = CropTheme.Dark\n)\n\n/**\n * Property for passing [CropOutline] between settings UI to [ImageCropper]\n */\n@Immutable\ndata class CropOutlineProperty(\n    val outlineType: OutlineType,\n    val cropOutline: CropOutline\n)\n\n/**\n * Light, Dark or system controlled theme\n */\nenum class CropTheme {\n    Light,\n    Dark,\n    System\n}\n\nprivate val DefaultBackgroundColor = Color(0x99000000)\nprivate val DefaultOverlayColor = Color.Gray\nprivate val DefaultHandleColor = Color.White"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/settings/CropType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.settings\n\n/**\n * Type of cropping operation\n *\n * If [CropType.Static] is selected overlay is stationary, image is movable.\n * If [CropType.Dynamic] is selected overlay can be moved, resized, image is stationary.\n */\nenum class CropType {\n    Static, Dynamic\n}"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/settings/Paths.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.settings\n\nimport androidx.compose.ui.graphics.Path\n\nobject Paths {\n    val Favorite\n        get() = Path().apply {\n            moveTo(12.0f, 21.35f)\n            relativeLineTo(-1.45f, -1.32f)\n            cubicTo(5.4f, 15.36f, 2.0f, 12.28f, 2.0f, 8.5f)\n            cubicTo(2.0f, 5.42f, 4.42f, 3.0f, 7.5f, 3.0f)\n            relativeCubicTo(1.74f, 0.0f, 3.41f, 0.81f, 4.5f, 2.09f)\n            cubicTo(13.09f, 3.81f, 14.76f, 3.0f, 16.5f, 3.0f)\n            cubicTo(19.58f, 3.0f, 22.0f, 5.42f, 22.0f, 8.5f)\n            relativeCubicTo(0.0f, 3.78f, -3.4f, 6.86f, -8.55f, 11.54f)\n            lineTo(12.0f, 21.35f)\n            close()\n        }\n\n    val Star = Path().apply {\n        moveTo(12.0f, 17.27f)\n        lineTo(18.18f, 21.0f)\n        relativeLineTo(-1.64f, -7.03f)\n        lineTo(22.0f, 9.24f)\n        relativeLineTo(-7.19f, -0.61f)\n        lineTo(12.0f, 2.0f)\n        lineTo(9.19f, 8.63f)\n        lineTo(2.0f, 9.24f)\n        relativeLineTo(5.46f, 4.73f)\n        lineTo(5.82f, 21.0f)\n        close()\n    }\n}\n\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/state/CropState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.state\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.cropper.settings.CropProperties\nimport com.t8rin.cropper.settings.CropType\n\n\n/**\n * Create and [remember] the [CropState] based on the currently appropriate transform\n * configuration to allow changing pan, zoom, and rotation.\n * @param imageSize size of the **Bitmap**\n * @param containerSize size of the Composable that draws **Bitmap**\n * @param cropProperties wrapper class that contains crop state properties such as\n * crop type,\n * @param keys are used to reset remember block to initial calculations. This can be used\n * when image, contentScale or any property changes which requires values to be reset to initial\n * values\n */\n@Composable\nfun rememberCropState(\n    imageSize: IntSize,\n    containerSize: IntSize,\n    drawAreaSize: IntSize,\n    cropProperties: CropProperties,\n    vararg keys: Any?\n): CropState {\n\n    // Properties of crop state\n    val handleSize = cropProperties.handleSize\n    val cropType = cropProperties.cropType\n    val aspectRatio = cropProperties.aspectRatio\n    val overlayRatio = cropProperties.overlayRatio\n    val maxZoom = cropProperties.maxZoom\n    val fling = cropProperties.fling\n    val zoomable = cropProperties.zoomable\n    val pannable = cropProperties.pannable\n    val rotatable = cropProperties.rotatable\n    val minDimension = cropProperties.minDimension\n    val fixedAspectRatio = cropProperties.fixedAspectRatio\n\n    return remember(*keys) {\n        when (cropType) {\n            CropType.Static -> {\n                StaticCropState(\n                    imageSize = imageSize,\n                    containerSize = containerSize,\n                    drawAreaSize = drawAreaSize,\n                    aspectRatio = aspectRatio,\n                    overlayRatio = overlayRatio,\n                    maxZoom = maxZoom,\n                    fling = fling,\n                    zoomable = zoomable,\n                    pannable = pannable,\n                    rotatable = rotatable,\n                    limitPan = false\n                )\n            }\n\n            else -> {\n                DynamicCropState(\n                    imageSize = imageSize,\n                    containerSize = containerSize,\n                    drawAreaSize = drawAreaSize,\n                    aspectRatio = aspectRatio,\n                    overlayRatio = overlayRatio,\n                    maxZoom = maxZoom,\n                    handleSize = handleSize,\n                    fling = fling,\n                    zoomable = zoomable,\n                    pannable = pannable,\n                    rotatable = rotatable,\n                    limitPan = true,\n                    minDimension = minDimension,\n                    fixedAspectRatio = fixedAspectRatio,\n                )\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/state/CropStateImpl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.state\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.VectorConverter\nimport androidx.compose.animation.core.tween\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.cropper.TouchRegion\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.model.CropData\nimport com.t8rin.cropper.settings.CropProperties\n\nval CropState.cropData: CropData\n    get() = CropData(\n        zoom = animatableZoom.targetValue,\n        pan = Offset(animatablePanX.targetValue, animatablePanY.targetValue),\n        rotation = animatableRotation.targetValue,\n        overlayRect = overlayRect,\n        cropRect = cropRect\n    )\n\n/**\n * Base class for crop operations. Any class that extends this class gets access to pan, zoom,\n * rotation values and animations via [TransformState], fling and moving back to bounds animations.\n * @param imageSize size of the **Bitmap**\n * @param containerSize size of the Composable that draws **Bitmap**. This is full size\n * of the Composable. [drawAreaSize] can be smaller than [containerSize] initially based\n * on content scale of Image composable\n * @param drawAreaSize size of the area that **Bitmap** is drawn\n * @param maxZoom maximum zoom value\n * @param fling when set to true dragging pointer builds up velocity. When last\n * pointer leaves Composable a movement invoked against friction till velocity drops below\n * to threshold\n * @param zoomable when set to true zoom is enabled\n * @param pannable when set to true pan is enabled\n * @param rotatable when set to true rotation is enabled\n * @param limitPan limits pan to bounds of parent Composable. Using this flag prevents creating\n * empty space on sides or edges of parent\n */\nabstract class CropState internal constructor(\n    imageSize: IntSize,\n    containerSize: IntSize,\n    drawAreaSize: IntSize,\n    maxZoom: Float,\n    internal var fling: Boolean = true,\n    internal var aspectRatio: AspectRatio,\n    internal var overlayRatio: Float,\n    zoomable: Boolean = true,\n    pannable: Boolean = true,\n    rotatable: Boolean = false,\n    limitPan: Boolean = false\n) : TransformState(\n    imageSize = imageSize,\n    containerSize = containerSize,\n    drawAreaSize = drawAreaSize,\n    initialZoom = 1f,\n    initialRotation = 0f,\n    maxZoom = maxZoom,\n    zoomable = zoomable,\n    pannable = pannable,\n    rotatable = rotatable,\n    limitPan = limitPan\n) {\n\n    private val animatableRectOverlay = Animatable(\n        getOverlayFromAspectRatio(\n            containerSize.width.toFloat(),\n            containerSize.height.toFloat(),\n            drawAreaSize.width.toFloat(),\n            aspectRatio,\n            overlayRatio\n        ),\n        Rect.VectorConverter\n    )\n\n    val overlayRect: Rect\n        get() = animatableRectOverlay.value\n\n    var cropRect: Rect = Rect.Zero\n        get() = getCropRectangle(\n            imageSize.width,\n            imageSize.height,\n            drawAreaRect,\n            animatableRectOverlay.targetValue\n        )\n        private set\n\n\n    private var initialized: Boolean = false\n\n    /**\n     * Region of touch inside, corners of or outside of overlay rectangle\n     */\n    var touchRegion by mutableStateOf(TouchRegion.None)\n\n    internal suspend fun init() {\n        // When initial aspect ratio doesn't match drawable area\n        // overlay gets updated so updates draw area as well\n        animateTransformationToOverlayBounds(overlayRect, animate = true)\n        initialized = true\n    }\n\n    /**\n     * Update properties of [CropState] and animate to valid intervals if required\n     */\n    internal open suspend fun updateProperties(\n        cropProperties: CropProperties,\n        forceUpdate: Boolean = false\n    ) {\n\n        if (!initialized) return\n\n        fling = cropProperties.fling\n        pannable = cropProperties.pannable\n        zoomable = cropProperties.zoomable\n        rotatable = cropProperties.rotatable\n\n        val maxZoom = cropProperties.maxZoom\n\n        // Update overlay rectangle\n        val aspectRatio = cropProperties.aspectRatio\n\n        // Ratio of overlay to screen\n        val overlayRatio = cropProperties.overlayRatio\n\n        if (\n            this.aspectRatio.value != aspectRatio.value ||\n            maxZoom != zoomMax ||\n            this.overlayRatio != overlayRatio ||\n            forceUpdate\n        ) {\n            this.aspectRatio = aspectRatio\n            this.overlayRatio = overlayRatio\n\n            zoomMax = maxZoom\n            animatableZoom.updateBounds(zoomMin, zoomMax)\n\n            val currentZoom = if (zoom > zoomMax) zoomMax else zoom\n\n            // Set new zoom\n            snapZoomTo(currentZoom)\n\n            // Calculate new region of image is drawn. It can be drawn left of 0 and right\n            // of container width depending on transformation\n            drawAreaRect = updateImageDrawRectFromTransformation()\n\n            // Update overlay rectangle based on current draw area and new aspect ratio\n            animateOverlayRectTo(\n                getOverlayFromAspectRatio(\n                    containerSize.width.toFloat(),\n                    containerSize.height.toFloat(),\n                    drawAreaSize.width.toFloat(),\n                    aspectRatio,\n                    overlayRatio\n                )\n            )\n        }\n\n        // Animate zoom, pan, rotation to move draw area to cover overlay rect\n        // inside draw area rect\n        animateTransformationToOverlayBounds(overlayRect, animate = true)\n    }\n\n    /**\n     * Animate overlay rectangle to target value\n     */\n    internal suspend fun animateOverlayRectTo(\n        rect: Rect,\n        animationSpec: AnimationSpec<Rect> = tween(400)\n    ) {\n        animatableRectOverlay.animateTo(\n            targetValue = rect,\n            animationSpec = animationSpec\n        )\n    }\n\n    /**\n     * Snap overlay rectangle to target value\n     */\n    internal suspend fun snapOverlayRectTo(rect: Rect) {\n        animatableRectOverlay.snapTo(rect)\n    }\n\n    /*\n        Touch gestures\n     */\n    internal abstract suspend fun onDown(change: PointerInputChange)\n\n    internal abstract suspend fun onMove(changes: List<PointerInputChange>)\n\n    internal abstract suspend fun onUp(change: PointerInputChange)\n\n    /*\n        Transform gestures\n     */\n    internal abstract suspend fun onGesture(\n        centroid: Offset,\n        panChange: Offset,\n        zoomChange: Float,\n        rotationChange: Float,\n        mainPointer: PointerInputChange,\n        changes: List<PointerInputChange>\n    )\n\n    internal abstract suspend fun onGestureStart()\n\n    internal abstract suspend fun onGestureEnd(onBoundsCalculated: () -> Unit)\n\n    // Double Tap\n    internal abstract suspend fun onDoubleTap(\n        offset: Offset,\n        zoom: Float = 1f,\n        onAnimationEnd: () -> Unit\n    )\n\n    /**\n     * Check if area that image is drawn covers [overlayRect]\n     */\n    internal fun isOverlayInImageDrawBounds(): Boolean {\n        return drawAreaRect.left <= overlayRect.left &&\n                drawAreaRect.top <= overlayRect.top &&\n                drawAreaRect.right >= overlayRect.right &&\n                drawAreaRect.bottom >= overlayRect.bottom\n    }\n\n    /**\n     * Check if [rect] is inside container bounds\n     */\n    internal fun isRectInContainerBounds(rect: Rect): Boolean {\n        return rect.left >= 0 &&\n                rect.right <= containerSize.width &&\n                rect.top >= 0 &&\n                rect.bottom <= containerSize.height\n    }\n\n    /**\n     * Update rectangle for area that image is drawn. This rect changes when zoom and\n     * pan changes and position of image changes on screen as result of transformation.\n     *\n     * This function is called\n     *\n     * * when [onGesture] is called to update rect when zoom or pan changes\n     *  and if [fling] is true just after **fling** gesture starts with target\n     *  value in  [StaticCropState].\n     *\n     *  * when [updateProperties] is called in [CropState]\n     *\n     *  * when [onUp] is called in [DynamicCropState] to match [overlayRect] that could be\n     *  changed and animated if it's out of [containerSize] bounds or its grow\n     *  bigger than previous size\n     */\n    internal fun updateImageDrawRectFromTransformation(): Rect {\n        val containerWidth = containerSize.width\n        val containerHeight = containerSize.height\n\n        val originalDrawWidth = drawAreaSize.width\n        val originalDrawHeight = drawAreaSize.height\n\n        val panX = animatablePanX.targetValue\n        val panY = animatablePanY.targetValue\n\n        val left = (containerWidth - originalDrawWidth) / 2\n        val top = (containerHeight - originalDrawHeight) / 2\n\n        val zoom = animatableZoom.targetValue\n\n        val newWidth = originalDrawWidth * zoom\n        val newHeight = originalDrawHeight * zoom\n\n        return Rect(\n            offset = Offset(\n                left - (newWidth - originalDrawWidth) / 2 + panX,\n                top - (newHeight - originalDrawHeight) / 2 + panY,\n            ),\n            size = Size(newWidth, newHeight)\n        )\n    }\n\n    // TODO Add resetting back to bounds for rotated state as well\n    /**\n     * Resets to bounds with animation and resets tracking for fling animation.\n     * Changes pan, zoom and rotation to valid bounds based on [drawAreaRect] and [overlayRect]\n     */\n    internal suspend fun animateTransformationToOverlayBounds(\n        overlayRect: Rect,\n        animate: Boolean,\n        animationSpec: AnimationSpec<Float> = tween(400)\n    ) {\n        // Keep current zoom\n        // val zoom = zoom.coerceAtLeast(1f)\n\n        // Calculate new pan based on overlay\n        val newDrawAreaRect = calculateValidImageDrawRect(overlayRect, drawAreaRect)\n\n        val newZoom =\n            calculateNewZoom(oldRect = drawAreaRect, newRect = newDrawAreaRect, zoom = zoom)\n\n        val leftChange = newDrawAreaRect.left - drawAreaRect.left\n        val topChange = newDrawAreaRect.top - drawAreaRect.top\n\n        val widthChange = newDrawAreaRect.width - drawAreaRect.width\n        val heightChange = newDrawAreaRect.height - drawAreaRect.height\n\n        val panXChange = leftChange + widthChange / 2\n        val panYChange = topChange + heightChange / 2\n\n        val newPanX = pan.x + panXChange\n        val newPanY = pan.y + panYChange\n\n        // Update draw area based on new pan and zoom values\n        drawAreaRect = newDrawAreaRect\n\n        if (animate) {\n            resetWithAnimation(\n                pan = Offset(newPanX, newPanY),\n                zoom = newZoom,\n                animationSpec = animationSpec\n            )\n        } else {\n            snapPanXto(newPanX)\n            snapPanYto(newPanY)\n            snapZoomTo(newZoom)\n        }\n\n        resetTracking()\n    }\n\n    /**\n     * If new overlay is bigger, when crop type is dynamic, we need to increase zoom at least\n     * size of bigger dimension for image draw area([drawAreaRect]) to cover overlay([overlayRect])\n     */\n    private fun calculateNewZoom(oldRect: Rect, newRect: Rect, zoom: Float): Float {\n\n        if (oldRect.size == Size.Zero || newRect.size == Size.Zero) return zoom\n\n        val widthChange = (newRect.width / oldRect.width)\n            .coerceAtLeast(1f)\n        val heightChange = (newRect.height / oldRect.height)\n            .coerceAtLeast(1f)\n\n        return widthChange.coerceAtLeast(heightChange) * zoom\n    }\n\n    /**\n     * Calculate valid position for image draw rectangle when pointer is up. Overlay rectangle\n     * should fit inside draw image rectangle to have valid bounds when calculation is completed.\n     *\n     * @param rectOverlay rectangle of overlay that is used for cropping\n     * @param rectDrawArea rectangle of image that is being drawn\n     */\n    private fun calculateValidImageDrawRect(rectOverlay: Rect, rectDrawArea: Rect): Rect {\n\n        var width = rectDrawArea.width\n        var height = rectDrawArea.height\n\n        if (width < rectOverlay.width) {\n            width = rectOverlay.width\n        }\n\n        if (height < rectOverlay.height) {\n            height = rectOverlay.height\n        }\n\n        var rectImageArea = Rect(offset = rectDrawArea.topLeft, size = Size(width, height))\n\n        if (rectImageArea.left > rectOverlay.left) {\n            rectImageArea = rectImageArea.translate(rectOverlay.left - rectImageArea.left, 0f)\n        }\n\n        if (rectImageArea.right < rectOverlay.right) {\n            rectImageArea = rectImageArea.translate(rectOverlay.right - rectImageArea.right, 0f)\n        }\n\n        if (rectImageArea.top > rectOverlay.top) {\n            rectImageArea = rectImageArea.translate(0f, rectOverlay.top - rectImageArea.top)\n        }\n\n        if (rectImageArea.bottom < rectOverlay.bottom) {\n            rectImageArea = rectImageArea.translate(0f, rectOverlay.bottom - rectImageArea.bottom)\n        }\n\n        return rectImageArea\n    }\n\n    /**\n     * Create [Rect] to draw overlay based on selected aspect ratio\n     */\n    internal fun getOverlayFromAspectRatio(\n        containerWidth: Float,\n        containerHeight: Float,\n        drawAreaWidth: Float,\n        aspectRatio: AspectRatio,\n        coefficient: Float\n    ): Rect {\n\n        if (aspectRatio == AspectRatio.Original) {\n            val imageAspectRatio = imageSize.width.toFloat() / imageSize.height.toFloat()\n\n            // Maximum width and height overlay rectangle can be measured with\n            val overlayWidthMax = drawAreaWidth.coerceAtMost(containerWidth * coefficient)\n            val overlayHeightMax =\n                (overlayWidthMax / imageAspectRatio).coerceAtMost(containerHeight * coefficient)\n\n            val offsetX = (containerWidth - overlayWidthMax) / 2f\n            val offsetY = (containerHeight - overlayHeightMax) / 2f\n\n            return Rect(\n                offset = Offset(offsetX, offsetY),\n                size = Size(overlayWidthMax, overlayHeightMax)\n            )\n        }\n\n        val overlayWidthMax = containerWidth * coefficient\n        val overlayHeightMax = containerHeight * coefficient\n\n        val aspectRatioValue = aspectRatio.value\n\n        var width = overlayWidthMax\n        var height = overlayWidthMax / aspectRatioValue\n\n        if (height > overlayHeightMax) {\n            height = overlayHeightMax\n            width = height * aspectRatioValue\n        }\n\n        val offsetX = (containerWidth - width) / 2f\n        val offsetY = (containerHeight - height) / 2f\n\n        return Rect(offset = Offset(offsetX, offsetY), size = Size(width, height))\n    }\n\n    /**\n     * Get crop rectangle\n     */\n    private fun getCropRectangle(\n        bitmapWidth: Int,\n        bitmapHeight: Int,\n        drawAreaRect: Rect,\n        overlayRect: Rect\n    ): Rect {\n\n        if (drawAreaRect == Rect.Zero || overlayRect == Rect.Zero) return Rect(\n            offset = Offset.Zero,\n            Size(bitmapWidth.toFloat(), bitmapHeight.toFloat())\n        )\n\n        // Calculate latest image draw area based on overlay position\n        // This is valid rectangle that contains crop area inside overlay\n        val newRect = calculateValidImageDrawRect(overlayRect, drawAreaRect)\n\n        val overlayWidth = overlayRect.width\n        val overlayHeight = overlayRect.height\n\n        val drawAreaWidth = newRect.width\n        val drawAreaHeight = newRect.height\n\n        val widthRatio = overlayWidth / drawAreaWidth\n        val heightRatio = overlayHeight / drawAreaHeight\n\n        val diffLeft = overlayRect.left - newRect.left\n        val diffTop = overlayRect.top - newRect.top\n\n        val croppedBitmapLeft = (diffLeft * (bitmapWidth / drawAreaWidth))\n        val croppedBitmapTop = (diffTop * (bitmapHeight / drawAreaHeight))\n\n        val croppedBitmapWidth = bitmapWidth * widthRatio\n        val croppedBitmapHeight = bitmapHeight * heightRatio\n\n        return Rect(\n            offset = Offset(croppedBitmapLeft, croppedBitmapTop),\n            size = Size(croppedBitmapWidth, croppedBitmapHeight)\n        )\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/state/DynamicCropState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.state\n\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.positionChangeIgnoreConsumed\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.cropper.TouchRegion\nimport com.t8rin.cropper.model.AspectRatio\nimport com.t8rin.cropper.settings.CropProperties\nimport kotlinx.coroutines.coroutineScope\nimport kotlin.math.roundToInt\n\n/**\n * State for cropper with dynamic overlay. Overlay of this state can be moved or resized\n * using handles or touching inner position of overlay. When overlay overflow out of image bounds\n * or moves out of bounds it animates back to valid size and position\n *\n * @param handleSize size of the handle to control, move or scale dynamic overlay\n * @param imageSize size of the **Bitmap**\n * @param containerSize size of the Composable that draws **Bitmap**\n * @param maxZoom maximum zoom value\n * @param fling when set to true dragging pointer builds up velocity. When last\n * pointer leaves Composable a movement invoked against friction till velocity drops below\n * to threshold\n * @param zoomable when set to true zoom is enabled\n * @param pannable when set to true pan is enabled\n * @param rotatable when set to true rotation is enabled\n * @param limitPan limits pan to bounds of parent Composable. Using this flag prevents creating\n * @param minDimension minimum size of the overlay, if null defaults to handleSize * 2\n * @param fixedAspectRatio when set to true aspect ratio of overlay is fixed\n * empty space on sides or edges of parent\n */\nclass DynamicCropState internal constructor(\n    private var handleSize: Float,\n    imageSize: IntSize,\n    containerSize: IntSize,\n    drawAreaSize: IntSize,\n    aspectRatio: AspectRatio,\n    overlayRatio: Float,\n    maxZoom: Float,\n    fling: Boolean,\n    zoomable: Boolean,\n    pannable: Boolean,\n    rotatable: Boolean,\n    limitPan: Boolean,\n    private val minDimension: IntSize?,\n    private val fixedAspectRatio: Boolean,\n) : CropState(\n    imageSize = imageSize,\n    containerSize = containerSize,\n    drawAreaSize = drawAreaSize,\n    aspectRatio = aspectRatio,\n    overlayRatio = overlayRatio,\n    maxZoom = maxZoom,\n    fling = fling,\n    zoomable = zoomable,\n    pannable = pannable,\n    rotatable = rotatable,\n    limitPan = limitPan\n) {\n\n    /**\n     * Rectangle that covers bounds of Composable. This is a rectangle uses [containerSize] as\n     * size and [Offset.Zero] as top left corner\n     */\n    private val rectBounds = Rect(\n        offset = Offset.Zero,\n        size = Size(containerSize.width.toFloat(), containerSize.height.toFloat())\n    )\n\n    // This rectangle is needed to set bounds set at first touch position while\n    // moving to constraint current bounds to temp one from first down\n    // When pointer is up\n    private var rectTemp = Rect.Zero\n\n    // Touch position for edge of the rectangle, used for not jumping to edge of rectangle\n    // when user moves a handle. We set positionActual as position of selected handle\n    // and using this distance as offset to not have a jump from touch position\n    private var distanceToEdgeFromTouch = Offset.Zero\n\n    private var doubleTapped = false\n\n    // Check if transform gesture has been invoked\n    // inside overlay but with multiple pointers to zoom\n    private var gestureInvoked = false\n\n    override suspend fun updateProperties(cropProperties: CropProperties, forceUpdate: Boolean) {\n        handleSize = cropProperties.handleSize\n        super.updateProperties(cropProperties, forceUpdate)\n    }\n\n    override suspend fun onDown(change: PointerInputChange) {\n\n        rectTemp = overlayRect.copy()\n\n        val position = change.position\n        val touchPositionScreenX = position.x\n        val touchPositionScreenY = position.y\n\n        val touchPositionOnScreen = Offset(touchPositionScreenX, touchPositionScreenY)\n\n        // Get whether user touched outside, handles of rectangle or inner region or overlay\n        // rectangle. Depending on where is touched we can move or scale overlay\n        touchRegion = getTouchRegion(\n            position = touchPositionOnScreen,\n            rect = overlayRect,\n            threshold = handleSize * 1.5f\n        )\n\n        // This is the difference between touch position and edge\n        // This is required for not moving edge of draw rect to touch position on move\n        distanceToEdgeFromTouch =\n            getDistanceToEdgeFromTouch(touchRegion, rectTemp, touchPositionOnScreen)\n    }\n\n    override suspend fun onMove(changes: List<PointerInputChange>) {\n\n        if (changes.isEmpty()) {\n            touchRegion = TouchRegion.None\n            return\n        }\n\n        gestureInvoked = changes.size > 1 && (touchRegion == TouchRegion.Inside)\n\n        // If overlay is touched and pointer size is one update\n        // or pointer size is bigger than one but touched any handles update\n        if (touchRegion != TouchRegion.None && changes.size == 1 && !gestureInvoked) {\n\n            val change = changes.first()\n\n            // Default min dimension is handle size * 5\n            val doubleHandleSize = handleSize * 5\n            val defaultMinDimension =\n                IntSize(doubleHandleSize.roundToInt(), doubleHandleSize.roundToInt())\n\n            // update overlay rectangle based on where its touched and touch position to corners\n            // This function moves and/or scales overlay rectangle\n            val newRect = updateOverlayRect(\n                distanceToEdgeFromTouch = distanceToEdgeFromTouch,\n                touchRegion = touchRegion,\n                minDimension = minDimension ?: defaultMinDimension,\n                rectTemp = rectTemp,\n                overlayRect = overlayRect,\n                change = change,\n                aspectRatio = getAspectRatio(),\n                fixedAspectRatio = fixedAspectRatio,\n            )\n\n            snapOverlayRectTo(newRect)\n        }\n    }\n\n    private fun getAspectRatio(): Float {\n        return if (aspectRatio == AspectRatio.Original) {\n            imageSize.width / imageSize.height.toFloat()\n        } else {\n            aspectRatio.value\n        }\n    }\n\n    override suspend fun onUp(change: PointerInputChange) = coroutineScope {\n        if (touchRegion != TouchRegion.None) {\n\n            val isInContainerBounds = isRectInContainerBounds(overlayRect)\n            if (!isInContainerBounds) {\n\n                // Calculate new overlay since it's out of Container bounds\n                rectTemp = calculateOverlayRectInBounds(rectBounds, overlayRect)\n\n                // Animate overlay to new bounds inside container\n                animateOverlayRectTo(rectTemp)\n            }\n\n            // Update and animate pan, zoom and image draw area after overlay position is updated\n            animateTransformationToOverlayBounds(overlayRect, true)\n\n            // Update image draw area after animating pan, zoom or rotation is completed\n            drawAreaRect = updateImageDrawRectFromTransformation()\n\n            touchRegion = TouchRegion.None\n        }\n\n        gestureInvoked = false\n    }\n\n    override suspend fun onGesture(\n        centroid: Offset,\n        panChange: Offset,\n        zoomChange: Float,\n        rotationChange: Float,\n        mainPointer: PointerInputChange,\n        changes: List<PointerInputChange>\n    ) {\n\n        if (touchRegion == TouchRegion.None || gestureInvoked) {\n            doubleTapped = false\n\n            val newPan = if (gestureInvoked) Offset.Zero else panChange\n\n            updateTransformState(\n                centroid = centroid,\n                zoomChange = zoomChange,\n                panChange = newPan,\n                rotationChange = rotationChange\n            )\n\n            // Update image draw rectangle based on pan, zoom or rotation change\n            drawAreaRect = updateImageDrawRectFromTransformation()\n\n            // Fling Gesture\n            if (pannable && fling) {\n                if (changes.size == 1) {\n                    addPosition(mainPointer.uptimeMillis, mainPointer.position)\n                }\n            }\n        }\n    }\n\n    override suspend fun onGestureStart() = Unit\n\n    override suspend fun onGestureEnd(onBoundsCalculated: () -> Unit) {\n\n        if (touchRegion == TouchRegion.None || gestureInvoked) {\n\n            // Gesture end might be called after second tap and we don't want to fling\n            // or animate back to valid bounds when doubled tapped\n            if (!doubleTapped) {\n\n                if (pannable && fling && !gestureInvoked && zoom > 1) {\n                    fling {\n                        // We get target value on start instead of updating bounds after\n                        // gesture has finished\n                        drawAreaRect = updateImageDrawRectFromTransformation()\n                        onBoundsCalculated()\n                    }\n                } else {\n                    onBoundsCalculated()\n                }\n\n                animateTransformationToOverlayBounds(overlayRect, animate = true)\n            }\n        }\n    }\n\n    override suspend fun onDoubleTap(\n        offset: Offset,\n        zoom: Float,\n        onAnimationEnd: () -> Unit\n    ) {\n        doubleTapped = true\n\n        if (fling) {\n            resetTracking()\n        }\n        resetWithAnimation(pan = pan, zoom = zoom, rotation = rotation)\n\n        // We get target value on start instead of updating bounds after\n        // gesture has finished\n        drawAreaRect = updateImageDrawRectFromTransformation()\n\n\n        if (!isOverlayInImageDrawBounds()) {\n            // Moves rectangle to bounds inside drawArea Rect while keeping aspect ratio\n            // of current overlay rect\n            animateOverlayRectTo(\n                getOverlayFromAspectRatio(\n                    containerSize.width.toFloat(),\n                    containerSize.height.toFloat(),\n                    drawAreaSize.width.toFloat(),\n                    aspectRatio,\n                    overlayRatio\n                )\n            )\n\n            animateTransformationToOverlayBounds(overlayRect, false)\n        }\n        onAnimationEnd()\n    }\n\n\n//    //TODO Change pan when zoom is bigger than 1f and touchRegion is inside overlay rect\n//    private suspend fun moveOverlayToBounds(change: PointerInputChange, newRect: Rect) {\n//        val bounds = drawAreaRect\n//\n//        val positionChange = change.positionChangeIgnoreConsumed()\n//\n//        // When zoom is bigger than 100% and dynamic overlay is not at any edge of\n//        // image we can pan in the same direction motion goes towards when touch region\n//        // of rectangle is not one of the handles but region inside\n//        val isPanRequired = touchRegion == TouchRegion.Inside && zoom > 1f\n//\n//        // Overlay moving right\n//        if (isPanRequired && newRect.right < bounds.right) {\n//            println(\"Moving right newRect $newRect, bounds: $bounds\")\n//            snapOverlayRectTo(newRect.translate(-positionChange.x, 0f))\n//            snapPanXto(pan.x - positionChange.x * zoom)\n//            // Overlay moving left\n//        } else if (isPanRequired && pan.x < bounds.left && newRect.left <= 0f) {\n//            snapOverlayRectTo(newRect.translate(-positionChange.x, 0f))\n//            snapPanXto(pan.x - positionChange.x * zoom)\n//        } else if (isPanRequired && pan.y < bounds.top && newRect.top <= 0f) {\n//            // Overlay moving top\n//            snapOverlayRectTo(newRect.translate(0f, -positionChange.y))\n//            snapPanYto(pan.y - positionChange.y * zoom)\n//        } else if (isPanRequired && -pan.y < bounds.bottom && newRect.bottom >= containerSize.height) {\n//            // Overlay moving bottom\n//            snapOverlayRectTo(newRect.translate(0f, -positionChange.y))\n//            snapPanYto(pan.y - positionChange.y * zoom)\n//        } else {\n//            snapOverlayRectTo(newRect)\n//        }\n//        if (touchRegion != TouchRegion.None) {\n//            change.consume()\n//        }\n//    }\n\n    /**\n     * When pointer is up calculate valid position and size overlay can be updated to inside\n     * a virtual rect between `topLeft = (0,0)` to `bottomRight=(containerWidth, containerHeight)`\n     *\n     * [overlayRect] might be shrunk or moved up/down/left/right to container bounds when\n     * it's out of Composable region\n     */\n    private fun calculateOverlayRectInBounds(rectBounds: Rect, rectCurrent: Rect): Rect {\n\n        var width = rectCurrent.width\n        var height = rectCurrent.height\n\n        if (width > rectBounds.width) {\n            width = rectBounds.width\n        }\n\n        if (height > rectBounds.height) {\n            height = rectBounds.height\n        }\n\n        var rect = Rect(offset = rectCurrent.topLeft, size = Size(width, height))\n\n        if (rect.left < rectBounds.left) {\n            rect = rect.translate(rectBounds.left - rect.left, 0f)\n        }\n\n        if (rect.top < rectBounds.top) {\n            rect = rect.translate(0f, rectBounds.top - rect.top)\n        }\n\n        if (rect.right > rectBounds.right) {\n            rect = rect.translate(rectBounds.right - rect.right, 0f)\n        }\n\n        if (rect.bottom > rectBounds.bottom) {\n            rect = rect.translate(0f, rectBounds.bottom - rect.bottom)\n        }\n\n        return rect\n    }\n\n    private fun updateOverlayRect(\n        distanceToEdgeFromTouch: Offset,\n        touchRegion: TouchRegion,\n        minDimension: IntSize,\n        rectTemp: Rect,\n        overlayRect: Rect,\n        change: PointerInputChange,\n        aspectRatio: Float,\n        fixedAspectRatio: Boolean,\n    ): Rect {\n\n        val position = change.position\n        val screenX = position.x + distanceToEdgeFromTouch.x\n        val screenY = position.y + distanceToEdgeFromTouch.y\n\n        val minW = minDimension.width.toFloat()\n        val minH = minDimension.height.toFloat()\n\n        val bounds = rectBounds\n\n        fun clampNonFixed(left: Float, top: Float, right: Float, bottom: Float): Rect {\n            val l = left.coerceIn(bounds.left, bounds.right - minW)\n            val t = top.coerceIn(bounds.top, bounds.bottom - minH)\n            val r = right.coerceIn(l + minW, bounds.right)\n            val b = bottom.coerceIn(t + minH, bounds.bottom)\n            return Rect(l, t, r, b)\n        }\n\n        fun anchoredCornerTopLeft(anchorR: Float, anchorB: Float, candidateLeft: Float): Rect {\n            var width = (anchorR - candidateLeft).coerceAtLeast(minW)\n            val maxWidth = (anchorR - bounds.left).coerceAtLeast(minW)\n            width = width.coerceAtMost(maxWidth)\n            var height = width / aspectRatio\n            val maxHeight = (anchorB - bounds.top).coerceAtLeast(minH)\n            if (height > maxHeight) {\n                height = maxHeight\n                width = (height * aspectRatio).coerceAtLeast(minW)\n            }\n            val left = anchorR - width\n            val top = anchorB - height\n            return Rect(\n                left.coerceAtLeast(bounds.left),\n                top.coerceAtLeast(bounds.top),\n                anchorR.coerceAtMost(bounds.right),\n                anchorB.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        fun anchoredCornerBottomLeft(anchorR: Float, anchorT: Float, candidateLeft: Float): Rect {\n            var width = (anchorR - candidateLeft).coerceAtLeast(minW)\n            val maxWidth = (anchorR - bounds.left).coerceAtLeast(minW)\n            width = width.coerceAtMost(maxWidth)\n            var height = width / aspectRatio\n            val maxHeight = (bounds.bottom - anchorT).coerceAtLeast(minH)\n            if (height > maxHeight) {\n                height = maxHeight\n                width = (height * aspectRatio).coerceAtLeast(minW)\n            }\n            val left = anchorR - width\n            val bottom = anchorT + height\n            return Rect(\n                left.coerceAtLeast(bounds.left),\n                anchorT.coerceAtLeast(bounds.top),\n                anchorR.coerceAtMost(bounds.right),\n                bottom.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        fun anchoredCornerTopRight(anchorL: Float, anchorB: Float, candidateRight: Float): Rect {\n            var width = (candidateRight - anchorL).coerceAtLeast(minW)\n            val maxWidth = (bounds.right - anchorL).coerceAtLeast(minW)\n            width = width.coerceAtMost(maxWidth)\n            var height = width / aspectRatio\n            val maxHeight = (anchorB - bounds.top).coerceAtLeast(minH)\n            if (height > maxHeight) {\n                height = maxHeight\n                width = (height * aspectRatio).coerceAtLeast(minW)\n            }\n            val right = anchorL + width\n            val top = anchorB - height\n            return Rect(\n                anchorL.coerceAtLeast(bounds.left),\n                top.coerceAtLeast(bounds.top),\n                right.coerceAtMost(bounds.right),\n                anchorB.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        fun anchoredCornerBottomRight(anchorL: Float, anchorT: Float, candidateRight: Float): Rect {\n            var width = (candidateRight - anchorL).coerceAtLeast(minW)\n            val maxWidth = (bounds.right - anchorL).coerceAtLeast(minW)\n            width = width.coerceAtMost(maxWidth)\n            var height = width / aspectRatio\n            val maxHeight = (bounds.bottom - anchorT).coerceAtLeast(minH)\n            if (height > maxHeight) {\n                height = maxHeight\n                width = (height * aspectRatio).coerceAtLeast(minW)\n            }\n            val right = anchorL + width\n            val bottom = anchorT + height\n            return Rect(\n                anchorL.coerceAtLeast(bounds.left),\n                anchorT.coerceAtLeast(bounds.top),\n                right.coerceAtMost(bounds.right),\n                bottom.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        fun centerTop(anchorB: Float, candidateTop: Float): Rect {\n            var height = (anchorB - candidateTop).coerceAtLeast(minH)\n            val maxHeight = (anchorB - bounds.top).coerceAtLeast(minH)\n            height = height.coerceAtMost(maxHeight)\n            var width = height * aspectRatio\n            val halfMaxWidth =\n                minOf(bounds.right - rectTemp.center.x, rectTemp.center.x - bounds.left)\n            val maxWidth = halfMaxWidth * 2f\n            if (width > maxWidth) {\n                width = maxWidth\n                height = (width / aspectRatio).coerceAtLeast(minH)\n            }\n            val left = rectTemp.center.x - width / 2f\n            val right = rectTemp.center.x + width / 2f\n            val top = anchorB - height\n            return Rect(\n                left.coerceAtLeast(bounds.left),\n                top.coerceAtLeast(bounds.top),\n                right.coerceAtMost(bounds.right),\n                anchorB.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        fun centerBottom(anchorT: Float, candidateBottom: Float): Rect {\n            var height = (candidateBottom - anchorT).coerceAtLeast(minH)\n            val maxHeight = (bounds.bottom - anchorT).coerceAtLeast(minH)\n            height = height.coerceAtMost(maxHeight)\n            var width = height * aspectRatio\n            val halfMaxWidth =\n                minOf(bounds.right - rectTemp.center.x, rectTemp.center.x - bounds.left)\n            val maxWidth = halfMaxWidth * 2f\n            if (width > maxWidth) {\n                width = maxWidth\n                height = (width / aspectRatio).coerceAtLeast(minH)\n            }\n            val left = rectTemp.center.x - width / 2f\n            val right = rectTemp.center.x + width / 2f\n            val bottom = anchorT + height\n            return Rect(\n                left.coerceAtLeast(bounds.left),\n                anchorT.coerceAtLeast(bounds.top),\n                right.coerceAtMost(bounds.right),\n                bottom.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        fun centerLeft(anchorR: Float, candidateLeft: Float): Rect {\n            var width = (anchorR - candidateLeft).coerceAtLeast(minW)\n            val maxWidth = (anchorR - bounds.left).coerceAtLeast(minW)\n            width = width.coerceAtMost(maxWidth)\n            var height = width / aspectRatio\n            val halfMaxHeight =\n                minOf(rectTemp.center.y - bounds.top, bounds.bottom - rectTemp.center.y)\n            val maxHeight = halfMaxHeight * 2f\n            if (height > maxHeight) {\n                height = maxHeight\n                width = (height * aspectRatio).coerceAtLeast(minW)\n            }\n            val left = anchorR - width\n            val top = rectTemp.center.y - height / 2f\n            val bottom = rectTemp.center.y + height / 2f\n            return Rect(\n                left.coerceAtLeast(bounds.left),\n                top.coerceAtLeast(bounds.top),\n                anchorR.coerceAtMost(bounds.right),\n                bottom.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        fun centerRight(anchorL: Float, candidateRight: Float): Rect {\n            var width = (candidateRight - anchorL).coerceAtLeast(minW)\n            val maxWidth = (bounds.right - anchorL).coerceAtLeast(minW)\n            width = width.coerceAtMost(maxWidth)\n            var height = width / aspectRatio\n            val halfMaxHeight =\n                minOf(rectTemp.center.y - bounds.top, bounds.bottom - rectTemp.center.y)\n            val maxHeight = halfMaxHeight * 2f\n            if (height > maxHeight) {\n                height = maxHeight\n                width = (height * aspectRatio).coerceAtLeast(minW)\n            }\n            val right = anchorL + width\n            val top = rectTemp.center.y - height / 2f\n            val bottom = rectTemp.center.y + height / 2f\n            return Rect(\n                anchorL.coerceAtLeast(bounds.left),\n                top.coerceAtLeast(bounds.top),\n                right.coerceAtMost(bounds.right),\n                bottom.coerceAtMost(bounds.bottom)\n            )\n        }\n\n        val result = when (touchRegion) {\n            TouchRegion.TopLeft -> {\n                val anchorR = rectTemp.right.coerceAtMost(bounds.right)\n                if (fixedAspectRatio) anchoredCornerTopLeft(\n                    anchorR,\n                    rectTemp.bottom.coerceAtMost(bounds.bottom),\n                    screenX.coerceAtMost(anchorR - minW)\n                )\n                else {\n                    val left = screenX.coerceIn(bounds.left, anchorR - minW)\n                    val top = screenY.coerceIn(\n                        bounds.top,\n                        rectTemp.bottom.coerceAtMost(bounds.bottom) - minH\n                    )\n                    clampNonFixed(left, top, anchorR, rectTemp.bottom.coerceAtMost(bounds.bottom))\n                }\n            }\n\n            TouchRegion.BottomLeft -> {\n                val anchorR = rectTemp.right.coerceAtMost(bounds.right)\n                if (fixedAspectRatio) anchoredCornerBottomLeft(\n                    anchorR,\n                    rectTemp.top.coerceAtLeast(bounds.top),\n                    screenX.coerceAtMost(anchorR - minW)\n                )\n                else {\n                    val left = screenX.coerceIn(bounds.left, anchorR - minW)\n                    val bottom = screenY.coerceIn(\n                        rectTemp.top.coerceAtLeast(bounds.top) + minH,\n                        bounds.bottom\n                    )\n                    clampNonFixed(left, rectTemp.top.coerceAtLeast(bounds.top), anchorR, bottom)\n                }\n            }\n\n            TouchRegion.TopRight -> {\n                val anchorL = rectTemp.left.coerceAtLeast(bounds.left)\n                if (fixedAspectRatio) anchoredCornerTopRight(\n                    anchorL,\n                    rectTemp.bottom.coerceAtMost(bounds.bottom),\n                    screenX.coerceAtLeast(anchorL + minW)\n                )\n                else {\n                    val right = screenX.coerceIn(anchorL + minW, bounds.right)\n                    val top = screenY.coerceIn(\n                        bounds.top,\n                        rectTemp.bottom.coerceAtMost(bounds.bottom) - minH\n                    )\n                    clampNonFixed(anchorL, top, right, rectTemp.bottom.coerceAtMost(bounds.bottom))\n                }\n            }\n\n            TouchRegion.BottomRight -> {\n                val anchorL = rectTemp.left.coerceAtLeast(bounds.left)\n                if (fixedAspectRatio) anchoredCornerBottomRight(\n                    anchorL,\n                    rectTemp.top.coerceAtLeast(bounds.top),\n                    screenX.coerceAtLeast(anchorL + minW)\n                )\n                else {\n                    val right = screenX.coerceIn(anchorL + minW, bounds.right)\n                    val bottom = screenY.coerceIn(\n                        rectTemp.top.coerceAtLeast(bounds.top) + minH,\n                        bounds.bottom\n                    )\n                    clampNonFixed(anchorL, rectTemp.top.coerceAtLeast(bounds.top), right, bottom)\n                }\n            }\n\n            TouchRegion.TopCenter -> {\n                if (fixedAspectRatio) centerTop(\n                    rectTemp.bottom.coerceAtMost(bounds.bottom),\n                    screenY.coerceAtMost(rectTemp.bottom - minH)\n                )\n                else {\n                    val top = screenY.coerceIn(\n                        bounds.top,\n                        rectTemp.bottom.coerceAtMost(bounds.bottom) - minH\n                    )\n                    clampNonFixed(\n                        rectTemp.left.coerceAtLeast(bounds.left),\n                        top,\n                        rectTemp.right.coerceAtMost(bounds.right),\n                        rectTemp.bottom.coerceAtMost(bounds.bottom)\n                    )\n                }\n            }\n\n            TouchRegion.BottomCenter -> {\n                if (fixedAspectRatio) centerBottom(\n                    rectTemp.top.coerceAtLeast(bounds.top),\n                    screenY.coerceAtLeast(rectTemp.top + minH)\n                )\n                else {\n                    val bottom = screenY.coerceIn(\n                        rectTemp.top.coerceAtLeast(bounds.top) + minH,\n                        bounds.bottom\n                    )\n                    clampNonFixed(\n                        rectTemp.left.coerceAtLeast(bounds.left),\n                        rectTemp.top.coerceAtLeast(bounds.top),\n                        rectTemp.right.coerceAtMost(bounds.right),\n                        bottom\n                    )\n                }\n            }\n\n            TouchRegion.CenterLeft -> {\n                val anchorR = rectTemp.right.coerceAtMost(bounds.right)\n                if (fixedAspectRatio) centerLeft(anchorR, screenX.coerceAtMost(anchorR - minW))\n                else {\n                    val left = screenX.coerceIn(bounds.left, anchorR - minW)\n                    clampNonFixed(\n                        left,\n                        rectTemp.top.coerceAtLeast(bounds.top),\n                        anchorR,\n                        rectTemp.bottom.coerceAtMost(bounds.bottom)\n                    )\n                }\n            }\n\n            TouchRegion.CenterRight -> {\n                val anchorL = rectTemp.left.coerceAtLeast(bounds.left)\n                if (fixedAspectRatio) centerRight(anchorL, screenX.coerceAtLeast(anchorL + minW))\n                else {\n                    val right = screenX.coerceIn(anchorL + minW, bounds.right)\n                    clampNonFixed(\n                        anchorL,\n                        rectTemp.top.coerceAtLeast(bounds.top),\n                        right,\n                        rectTemp.bottom.coerceAtMost(bounds.bottom)\n                    )\n                }\n            }\n\n            TouchRegion.Inside -> {\n                val drag = change.positionChangeIgnoreConsumed()\n                val newLeft = (overlayRect.left + drag.x).coerceIn(\n                    bounds.left,\n                    bounds.right - overlayRect.width\n                )\n                val newTop = (overlayRect.top + drag.y).coerceIn(\n                    bounds.top,\n                    bounds.bottom - overlayRect.height\n                )\n                Rect(newLeft, newTop, newLeft + overlayRect.width, newTop + overlayRect.height)\n            }\n\n            else -> overlayRect\n        }\n\n        return result\n    }\n\n    /**\n     * get [TouchRegion] based on touch position on screen relative to [overlayRect].\n     */\n    private fun getTouchRegion(\n        position: Offset,\n        rect: Rect,\n        threshold: Float\n    ): TouchRegion {\n\n        val closedTouchRange = -threshold / 2..threshold\n        val centerX = rect.left + rect.width / 2\n        val centerY = rect.top + rect.height / 2\n\n        return when {\n            position.x - rect.left in closedTouchRange &&\n                    position.y - rect.top in closedTouchRange -> TouchRegion.TopLeft\n\n            rect.right - position.x in closedTouchRange &&\n                    position.y - rect.top in closedTouchRange -> TouchRegion.TopRight\n\n            rect.right - position.x in closedTouchRange &&\n                    rect.bottom - position.y in closedTouchRange -> TouchRegion.BottomRight\n\n            position.x - rect.left in closedTouchRange &&\n                    rect.bottom - position.y in closedTouchRange -> TouchRegion.BottomLeft\n\n            centerX - position.x in closedTouchRange &&\n                    position.y - rect.top in closedTouchRange -> TouchRegion.TopCenter\n\n            rect.right - position.x in closedTouchRange &&\n                    position.y - centerY in closedTouchRange -> TouchRegion.CenterRight\n\n            position.x - rect.left in closedTouchRange &&\n                    position.y - centerY in closedTouchRange -> TouchRegion.CenterLeft\n\n            centerX - position.x in closedTouchRange &&\n                    rect.bottom - position.y in closedTouchRange -> TouchRegion.BottomCenter\n\n            else -> {\n                if (rect.contains(offset = position)) TouchRegion.Inside\n                else TouchRegion.None\n            }\n        }\n    }\n\n    /**\n     * Returns how far user touched to corner or center of sides of the screen. [TouchRegion]\n     * where user exactly has touched is already passed to this function. For instance user\n     * touched top left then this function returns distance to top left from user's position so\n     * we can add an offset to not jump edge to position user touched.\n     */\n    private fun getDistanceToEdgeFromTouch(\n        touchRegion: TouchRegion,\n        rect: Rect,\n        touchPosition: Offset\n    ) = when (touchRegion) {\n        TouchRegion.TopLeft -> {\n            rect.topLeft - touchPosition\n        }\n\n        TouchRegion.TopRight -> {\n            rect.topRight - touchPosition\n        }\n\n        TouchRegion.BottomLeft -> {\n            rect.bottomLeft - touchPosition\n        }\n\n        TouchRegion.BottomRight -> {\n            rect.bottomRight - touchPosition\n        }\n\n        TouchRegion.TopCenter -> {\n            rect.topCenter - touchPosition\n        }\n\n        TouchRegion.CenterRight -> {\n            rect.centerRight - touchPosition\n        }\n\n        TouchRegion.BottomCenter -> {\n            rect.bottomCenter - touchPosition\n        }\n\n        TouchRegion.CenterLeft -> {\n            rect.centerLeft - touchPosition\n        }\n\n        else -> {\n            Offset.Zero\n        }\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/state/StaticCropState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.state\n\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.cropper.model.AspectRatio\nimport kotlinx.coroutines.coroutineScope\n\n/**\n *  * State for cropper with dynamic overlay. When this state is selected instead of overlay\n *  image is moved while overlay is stationary.\n *\n * @param imageSize size of the **Bitmap**\n * @param containerSize size of the Composable that draws **Bitmap**\n * @param maxZoom maximum zoom value\n * @param fling when set to true dragging pointer builds up velocity. When last\n * pointer leaves Composable a movement invoked against friction till velocity drops below\n * to threshold\n * @param zoomable when set to true zoom is enabled\n * @param pannable when set to true pan is enabled\n * @param rotatable when set to true rotation is enabled\n * @param limitPan limits pan to bounds of parent Composable. Using this flag prevents creating\n * empty space on sides or edges of parent\n */\nclass StaticCropState internal constructor(\n    imageSize: IntSize,\n    containerSize: IntSize,\n    drawAreaSize: IntSize,\n    aspectRatio: AspectRatio,\n    overlayRatio: Float,\n    maxZoom: Float = 5f,\n    fling: Boolean = false,\n    zoomable: Boolean = true,\n    pannable: Boolean = true,\n    rotatable: Boolean = false,\n    limitPan: Boolean = false\n) : CropState(\n    imageSize = imageSize,\n    containerSize = containerSize,\n    drawAreaSize = drawAreaSize,\n    aspectRatio = aspectRatio,\n    overlayRatio = overlayRatio,\n    maxZoom = maxZoom,\n    fling = fling,\n    zoomable = zoomable,\n    pannable = pannable,\n    rotatable = rotatable,\n    limitPan = limitPan\n) {\n\n    override suspend fun onDown(change: PointerInputChange) = Unit\n    override suspend fun onMove(changes: List<PointerInputChange>) = Unit\n    override suspend fun onUp(change: PointerInputChange) = Unit\n\n    private var doubleTapped = false\n\n    /*\n        Transform gestures\n    */\n    override suspend fun onGesture(\n        centroid: Offset,\n        panChange: Offset,\n        zoomChange: Float,\n        rotationChange: Float,\n        mainPointer: PointerInputChange,\n        changes: List<PointerInputChange>\n    ) = coroutineScope {\n        doubleTapped = false\n\n        updateTransformState(\n            centroid = centroid,\n            zoomChange = zoomChange,\n            panChange = panChange,\n            rotationChange = rotationChange\n        )\n\n        // Update image draw rectangle based on pan, zoom or rotation change\n        drawAreaRect = updateImageDrawRectFromTransformation()\n\n        // Fling Gesture\n        if (pannable && fling) {\n            if (changes.size == 1) {\n                addPosition(mainPointer.uptimeMillis, mainPointer.position)\n            }\n        }\n    }\n\n    override suspend fun onGestureStart() = coroutineScope {}\n\n    override suspend fun onGestureEnd(onBoundsCalculated: () -> Unit) {\n\n        // Gesture end might be called after second tap and we don't want to fling\n        // or animate back to valid bounds when doubled tapped\n        if (!doubleTapped) {\n\n            if (pannable && fling && zoom > 1) {\n                fling {\n                    // We get target value on start instead of updating bounds after\n                    // gesture has finished\n                    drawAreaRect = updateImageDrawRectFromTransformation()\n                    onBoundsCalculated()\n                }\n            } else {\n                onBoundsCalculated()\n            }\n\n            animateTransformationToOverlayBounds(overlayRect, animate = true)\n        }\n    }\n\n    // Double Tap\n    override suspend fun onDoubleTap(\n        offset: Offset,\n        zoom: Float,\n        onAnimationEnd: () -> Unit\n    ) {\n        doubleTapped = true\n\n        if (fling) {\n            resetTracking()\n        }\n        resetWithAnimation(pan = pan, zoom = zoom, rotation = rotation)\n        drawAreaRect = updateImageDrawRectFromTransformation()\n        animateTransformationToOverlayBounds(overlayRect, true)\n        onAnimationEnd()\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/state/TransformState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.state\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.exponentialDecay\nimport androidx.compose.animation.core.tween\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.input.pointer.util.VelocityTracker\nimport androidx.compose.ui.unit.IntSize\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.launch\n\n/**\n * State of the pan, zoom and rotation. Allows to change zoom, pan via [Animatable]\n * objects' [Animatable.animateTo], [Animatable.snapTo].\n * @param initialZoom initial zoom level\n * @param initialRotation initial angle in degrees\n * @param minZoom minimum zoom\n * @param maxZoom maximum zoom\n * @param zoomable when set to true zoom is enabled\n * @param pannable when set to true pan is enabled\n * @param rotatable when set to true rotation is enabled\n * @param limitPan limits pan to bounds of parent Composable. Using this flag prevents creating\n * empty space on sides or edges of parent.\n *\n */\n@Stable\nopen class TransformState(\n    internal val imageSize: IntSize,\n    val containerSize: IntSize,\n    val drawAreaSize: IntSize,\n    initialZoom: Float = 1f,\n    initialRotation: Float = 0f,\n    minZoom: Float = 0.5f, // Definitely\n    maxZoom: Float = 10f,\n    internal var zoomable: Boolean = true,\n    internal var pannable: Boolean = true,\n    internal var rotatable: Boolean = true,\n    internal var limitPan: Boolean = false\n) {\n\n    var drawAreaRect: Rect by mutableStateOf(\n        Rect(\n            offset = Offset(\n                x = ((containerSize.width - drawAreaSize.width) / 2).toFloat(),\n                y = ((containerSize.height - drawAreaSize.height) / 2).toFloat()\n            ),\n            size = Size(drawAreaSize.width.toFloat(), drawAreaSize.height.toFloat())\n        )\n    )\n\n    internal val zoomMin = minZoom.coerceAtLeast(0.5f) // Definitely\n    internal var zoomMax = maxZoom.coerceAtLeast(1f)\n    private val zoomInitial = initialZoom.coerceIn(zoomMin, zoomMax)\n    private val rotationInitial = initialRotation % 360\n\n    internal val animatablePanX = Animatable(0f)\n    internal val animatablePanY = Animatable(0f)\n    internal val animatableZoom = Animatable(zoomInitial)\n    internal val animatableRotation = Animatable(rotationInitial)\n\n    private val velocityTracker = VelocityTracker()\n\n    init {\n        animatableZoom.updateBounds(zoomMin, zoomMax)\n        require(zoomMax >= zoomMin)\n    }\n\n    val pan: Offset\n        get() = Offset(animatablePanX.value, animatablePanY.value)\n\n    val zoom: Float\n        get() = animatableZoom.value\n\n    val rotation: Float\n        get() = animatableRotation.value\n\n    val isZooming: Boolean\n        get() = animatableZoom.isRunning\n\n    val isPanning: Boolean\n        get() = animatablePanX.isRunning || animatablePanY.isRunning\n\n    val isRotating: Boolean\n        get() = animatableRotation.isRunning\n\n    val isAnimationRunning: Boolean\n        get() = isZooming || isPanning || isRotating\n\n    internal open fun updateBounds(lowerBound: Offset?, upperBound: Offset?) {\n        animatablePanX.updateBounds(lowerBound?.x, upperBound?.x)\n        animatablePanY.updateBounds(lowerBound?.y, upperBound?.y)\n    }\n\n    /**\n     * Update centroid, pan, zoom and rotation of this state when transform gestures are\n     * invoked with one or multiple pointers\n     */\n    internal open suspend fun updateTransformState(\n        centroid: Offset,\n        panChange: Offset,\n        zoomChange: Float,\n        rotationChange: Float = 1f,\n    ) {\n        val newZoom = (this.zoom * zoomChange).coerceIn(zoomMin, zoomMax)\n\n        snapZoomTo(newZoom)\n        val newRotation = if (rotatable) {\n            this.rotation + rotationChange\n        } else {\n            0f\n        }\n        snapRotationTo(newRotation)\n\n        if (pannable) {\n            val newPan = this.pan + panChange.times(this.zoom / newZoom)\n            snapPanXto(newPan.x)\n            snapPanYto(newPan.y)\n        }\n    }\n\n    /**\n     * Reset [pan], [zoom] and [rotation] with animation.\n     */\n    internal suspend fun resetWithAnimation(\n        pan: Offset = Offset.Zero,\n        zoom: Float = 1f,\n        rotation: Float = 0f,\n        animationSpec: AnimationSpec<Float> = tween(400)\n    ) = coroutineScope {\n        launch { animatePanXto(pan.x, animationSpec) }\n        launch { animatePanYto(pan.y, animationSpec) }\n        launch { animateZoomTo(zoom, animationSpec) }\n        launch { animateRotationTo(rotation, animationSpec) }\n    }\n\n    internal suspend fun animatePanXto(\n        panX: Float,\n        animationSpec: AnimationSpec<Float> = tween(400)\n    ) {\n        if (pannable && pan.x != panX) {\n            animatablePanX.animateTo(panX, animationSpec)\n        }\n    }\n\n    internal suspend fun animatePanYto(\n        panY: Float,\n        animationSpec: AnimationSpec<Float> = tween(400)\n    ) {\n        if (pannable && pan.y != panY) {\n            animatablePanY.animateTo(panY, animationSpec)\n        }\n    }\n\n    internal suspend fun animateZoomTo(\n        zoom: Float,\n        animationSpec: AnimationSpec<Float> = tween(400)\n    ) {\n        if (zoomable && this.zoom != zoom) {\n            val newZoom = zoom.coerceIn(zoomMin, zoomMax)\n            animatableZoom.animateTo(newZoom, animationSpec)\n        }\n    }\n\n    suspend fun animateRotationTo(\n        rotation: Float,\n        animationSpec: AnimationSpec<Float> = tween(400)\n    ) {\n        if (rotatable && this.rotation != rotation) {\n            animatableRotation.animateTo(rotation, animationSpec)\n        }\n    }\n\n    internal suspend fun snapPanXto(panX: Float) {\n        if (pannable) {\n            animatablePanX.snapTo(panX)\n        }\n    }\n\n    internal suspend fun snapPanYto(panY: Float) {\n        if (pannable) {\n            animatablePanY.snapTo(panY)\n        }\n    }\n\n    internal suspend fun snapZoomTo(zoom: Float) {\n        if (zoomable) {\n            animatableZoom.snapTo(zoom.coerceIn(zoomMin, zoomMax))\n        }\n    }\n\n    internal suspend fun snapRotationTo(rotation: Float) {\n        if (rotatable) {\n            animatableRotation.snapTo(rotation)\n        }\n    }\n\n    /*\n    Fling gesture\n */\n    internal fun addPosition(timeMillis: Long, position: Offset) {\n        velocityTracker.addPosition(\n            timeMillis = timeMillis,\n            position = position\n        )\n    }\n\n    /**\n     * Create a fling gesture when user removes finger from scree to have continuous movement\n     * until [velocityTracker] speed reached to lower bound\n     */\n    internal suspend fun fling(onFlingStart: () -> Unit) = coroutineScope {\n        val velocityTracker = velocityTracker.calculateVelocity()\n        val velocity = Offset(velocityTracker.x, velocityTracker.y)\n        var flingStarted = false\n\n        launch {\n            animatablePanX.animateDecay(\n                velocity.x,\n                exponentialDecay(absVelocityThreshold = 20f),\n                block = {\n                    // This callback returns target value of fling gesture initially\n                    if (!flingStarted) {\n                        onFlingStart()\n                        flingStarted = true\n                    }\n                }\n            )\n        }\n\n        launch {\n            animatablePanY.animateDecay(\n                velocity.y,\n                exponentialDecay(absVelocityThreshold = 20f),\n                block = {\n                    // This callback returns target value of fling gesture initially\n                    if (!flingStarted) {\n                        onFlingStart()\n                        flingStarted = true\n                    }\n                }\n            )\n        }\n    }\n\n    internal fun resetTracking() {\n        velocityTracker.resetTracking()\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/util/DimensionUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.util\n\n/**\n * [Linear Interpolation](https://en.wikipedia.org/wiki/Linear_interpolation) function that moves\n * amount from it's current position to start and amount\n * @param start of interval\n * @param stop of interval\n * @param fraction closed unit interval [0, 1]\n */\nfun lerp(start: Float, stop: Float, fraction: Float): Float {\n    return (1 - fraction) * start + fraction * stop\n}\n\n/**\n * Scale x1 from start1..end1 range to start2..end2 range\n\n */\nfun scale(start1: Float, end1: Float, pos: Float, start2: Float, end2: Float) =\n    lerp(start2, end2, calculateFraction(start1, end1, pos))\n\n/**\n * Scale x.start, x.endInclusive from a1..b1 range to a2..b2 range\n */\nfun scale(\n    start1: Float,\n    end1: Float,\n    range: ClosedFloatingPointRange<Float>,\n    start2: Float,\n    end2: Float\n) =\n    scale(start1, end1, range.start, start2, end2)..scale(\n        start1,\n        end1,\n        range.endInclusive,\n        start2,\n        end2\n    )\n\n\n/**\n * Calculate fraction for value between a range [end] and [start] coerced into 0f-1f range\n */\nfun calculateFraction(start: Float, end: Float, pos: Float) =\n    (if (end - start == 0f) 0f else (pos - start) / (end - start)).coerceIn(0f, 1f)\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/util/DrawScopeUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.util\n\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.nativeCanvas\n\n/**\n * Draw grid that is divided by 2 vertical and 2 horizontal lines for overlay\n */\nfun DrawScope.drawGrid(rect: Rect, strokeWidth: Float, color: Color) {\n\n    val width = rect.width\n    val height = rect.height\n    val gridWidth = width / 3\n    val gridHeight = height / 3\n\n    // Horizontal lines\n    for (i in 1..2) {\n        drawLine(\n            color = color,\n            start = Offset(rect.left, rect.top + i * gridHeight),\n            end = Offset(rect.right, rect.top + i * gridHeight),\n            strokeWidth = strokeWidth\n        )\n    }\n\n    // Vertical lines\n    for (i in 1..2) {\n        drawLine(\n            color,\n            start = Offset(rect.left + i * gridWidth, rect.top),\n            end = Offset(rect.left + i * gridWidth, rect.bottom),\n            strokeWidth = strokeWidth\n        )\n    }\n}\n\n/**\n * Draw with layer to use [BlendMode]s\n */\nfun DrawScope.drawWithLayer(block: DrawScope.() -> Unit) {\n    with(drawContext.canvas.nativeCanvas) {\n        val checkPoint = saveLayer(null, null)\n        block()\n        restoreToCount(checkPoint)\n    }\n}"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/util/ImageContentScaleUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.util\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.BoxWithConstraintsScope\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.IntRect\nimport androidx.compose.ui.unit.IntSize\n\n/**\n * Get Rectangle of [ImageBitmap] with [bitmapWidth] and [bitmapHeight] that is drawn inside\n * Canvas with [imageWidth] and [imageHeight]. [boxWidth] and [boxHeight] belong\n * to [BoxWithConstraints] that contains Canvas.\n *  @param boxWidth width of the parent container\n *  @param boxHeight height of the parent container\n *  @param imageWidth width of the [Canvas] that draws [ImageBitmap]\n *  @param imageHeight height of the [Canvas] that draws [ImageBitmap]\n *  @param bitmapWidth intrinsic width of the [ImageBitmap]\n *  @param bitmapHeight intrinsic height of the [ImageBitmap]\n *  @return [IntRect] that covers [ImageBitmap] bounds. When image [ContentScale] is crop\n *  this rectangle might return smaller rectangle than actual [ImageBitmap] and left or top\n *  of the rectangle might be bigger than zero.\n */\ninternal fun getScaledBitmapRect(\n    boxWidth: Int,\n    boxHeight: Int,\n    imageWidth: Float,\n    imageHeight: Float,\n    bitmapWidth: Int,\n    bitmapHeight: Int\n): IntRect {\n    // Get scale of box to width of the image\n    // We need a rect that contains Bitmap bounds to pass if any child requires it\n    // For a image with 100x100 px with 300x400 px container and image with crop 400x400px\n    // So we need to pass top left as 0,50 and size\n    val scaledBitmapX = boxWidth / imageWidth\n    val scaledBitmapY = boxHeight / imageHeight\n\n    val topLeft = IntOffset(\n        x = (bitmapWidth * (imageWidth - boxWidth) / imageWidth / 2)\n            .coerceAtLeast(0f).toInt(),\n        y = (bitmapHeight * (imageHeight - boxHeight) / imageHeight / 2)\n            .coerceAtLeast(0f).toInt()\n    )\n\n    val size = IntSize(\n        width = (bitmapWidth * scaledBitmapX).toInt().coerceAtMost(bitmapWidth),\n        height = (bitmapHeight * scaledBitmapY).toInt().coerceAtMost(bitmapHeight)\n    )\n\n    return IntRect(offset = topLeft, size = size)\n}\n\n/**\n * Get [IntSize] of the parent or container that contains [Canvas] that draws [ImageBitmap]\n *  @param bitmapWidth intrinsic width of the [ImageBitmap]\n *  @param bitmapHeight intrinsic height of the [ImageBitmap]\n *  @return size of parent Composable. When Modifier is assigned with fixed or finite size\n *  they are used, but when any dimension is set to infinity intrinsic dimensions of\n *  [ImageBitmap] are returned\n */\ninternal fun BoxWithConstraintsScope.getParentSize(\n    bitmapWidth: Int,\n    bitmapHeight: Int\n): IntSize {\n    // Check if Composable has fixed size dimensions\n    val hasBoundedDimens = constraints.hasBoundedWidth && constraints.hasBoundedHeight\n    // Check if Composable has infinite dimensions\n    val hasFixedDimens = constraints.hasFixedWidth && constraints.hasFixedHeight\n\n    // Box is the parent(BoxWithConstraints) that contains Canvas under the hood\n    // Canvas aspect ratio or size might not match parent but it's upper bounds are\n    // what are passed from parent. Canvas cannot be bigger or taller than BoxWithConstraints\n    val boxWidth: Int = if (hasBoundedDimens || hasFixedDimens) {\n        constraints.maxWidth\n    } else {\n        constraints.minWidth.coerceAtLeast(bitmapWidth)\n    }\n    val boxHeight: Int = if (hasBoundedDimens || hasFixedDimens) {\n        constraints.maxHeight\n    } else {\n        constraints.minHeight.coerceAtLeast(bitmapHeight)\n    }\n    return IntSize(boxWidth, boxHeight)\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/util/OffsetUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.util\n\nimport androidx.compose.ui.geometry.Offset\n\n\n/**\n * Coerce an [Offset] x value in [horizontalRange] and y value in [verticalRange]\n */\nfun Offset.coerceIn(\n    horizontalRange: ClosedRange<Float>,\n    verticalRange: ClosedRange<Float>\n) = Offset(this.x.coerceIn(horizontalRange), this.y.coerceIn(verticalRange))"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/util/ShapeUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.util\n\nimport android.graphics.Matrix\nimport androidx.compose.foundation.shape.GenericShape\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.asAndroidPath\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\nimport com.t8rin.cropper.model.AspectRatio\nimport kotlin.math.cos\nimport kotlin.math.sin\n\n\n/**\n * Creates a polygon with number of [sides] centered at ([cx],[cy]) with [radius].\n * ```\n *  To generate regular polygons (i.e. where each interior angle is the same),\n *  polar coordinates are extremely useful. You can calculate the angle necessary\n *  to produce the desired number of sides (as the interior angles total 360º)\n *  and then use multiples of this angle with the same radius to describe each point.\n * val x = radius * Math.cos(angle);\n * val y = radius * Math.sin(angle);\n *\n * For instance to draw triangle loop thrice with angle\n * 0, 120, 240 degrees in radians and draw lines from each coordinate.\n * ```\n */\nfun createPolygonPath(cx: Float, cy: Float, sides: Int, radius: Float): Path {\n\n    val angle = 2.0 * Math.PI / sides\n\n    return Path().apply {\n        moveTo(\n            cx + (radius * cos(0.0)).toFloat(),\n            cy + (radius * sin(0.0)).toFloat()\n        )\n        for (i in 1 until sides) {\n            lineTo(\n                cx + (radius * cos(angle * i)).toFloat(),\n                cy + (radius * sin(angle * i)).toFloat()\n            )\n        }\n        close()\n    }\n}\n\n\n/**\n * Create a polygon shape\n */\nfun createPolygonShape(sides: Int, degrees: Float = 0f): GenericShape {\n    return GenericShape { size: Size, _: LayoutDirection ->\n\n        val radius = size.width.coerceAtMost(size.height) / 2\n        addPath(\n            createPolygonPath(\n                cx = size.width / 2,\n                cy = size.height / 2,\n                sides = sides,\n                radius = radius\n            )\n        )\n        val matrix = Matrix()\n        matrix.postRotate(degrees, size.width / 2, size.height / 2)\n        this.asAndroidPath().transform(matrix)\n    }\n}\n\n/**\n * Creates a [Rect] shape with given aspect ratio.\n */\nfun createRectShape(aspectRatio: AspectRatio): GenericShape {\n    return GenericShape { size: Size, _: LayoutDirection ->\n        val value = aspectRatio.value\n\n        val width = size.width\n        val height = size.height\n        val shapeSize =\n            if (aspectRatio == AspectRatio.Original) Size(width, height)\n            else if (value > 1) Size(width = width, height = width / value)\n            else Size(width = height * value, height = height)\n\n        addRect(Rect(offset = Offset.Zero, size = shapeSize))\n    }\n}\n\n/**\n * Scales this path to [width] and [height] from [Path.getBounds] and translates\n * as difference between scaled path and original path\n */\nfun Path.scaleAndTranslatePath(\n    width: Float,\n    height: Float,\n) {\n    val pathSize = getBounds().size\n\n    val matrix = Matrix()\n    matrix.postScale(\n        width / pathSize.width,\n        height / pathSize.height\n    )\n\n    this.asAndroidPath().transform(matrix)\n\n    val left = getBounds().left\n    val top = getBounds().top\n\n    translate(Offset(-left, -top))\n}\n\n/**\n * Build an outline from a shape using aspect ratio, shape and coefficient to scale\n *\n * @return [Triple] that contains left, top offset and [Outline]\n */\nfun buildOutline(\n    aspectRatio: AspectRatio,\n    coefficient: Float,\n    shape: Shape,\n    size: Size,\n    layoutDirection: LayoutDirection,\n    density: Density\n): Pair<Offset, Outline> {\n\n    val (shapeSize, offset) = calculateSizeAndOffsetFromAspectRatio(aspectRatio, coefficient, size)\n\n    val outline = shape.createOutline(\n        size = shapeSize,\n        layoutDirection = layoutDirection,\n        density = density\n    )\n    return Pair(offset, outline)\n}\n\n\n/**\n * Calculate new size and offset based on [size], [coefficient] and [aspectRatio]\n *\n * For 4/3f aspect ratio with 1000px width, 1000px height with coefficient 1f\n * it returns Size(1000f, 750f), Offset(0f, 125f).\n */\nfun calculateSizeAndOffsetFromAspectRatio(\n    aspectRatio: AspectRatio,\n    coefficient: Float,\n    size: Size,\n): Pair<Size, Offset> {\n    val width = size.width\n    val height = size.height\n\n    val value = aspectRatio.value\n\n    val newSize = if (aspectRatio == AspectRatio.Original) {\n        Size(width * coefficient, height * coefficient)\n    } else if (value > 1) {\n        Size(\n            width = coefficient * width,\n            height = coefficient * width / value\n        )\n    } else {\n        Size(width = coefficient * height * value, height = coefficient * height)\n    }\n\n    val left = (width - newSize.width) / 2\n    val top = (height - newSize.height) / 2\n\n    return Pair(newSize, Offset(left, top))\n}"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/util/ZoomLevel.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.util\n\n/**\n * Enum class for zoom levels\n */\nenum class ZoomLevel {\n    Min, Mid, Max\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/util/ZoomUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.util\n\nimport androidx.compose.ui.graphics.GraphicsLayerScope\nimport com.t8rin.cropper.state.TransformState\n\n/**\n * Calculate zoom level and zoom value when user double taps\n */\ninternal fun calculateZoom(\n    zoomLevel: ZoomLevel,\n    initial: Float,\n    min: Float,\n    max: Float\n): Pair<ZoomLevel, Float> {\n\n    val newZoomLevel: ZoomLevel\n    val newZoom: Float\n\n    when (zoomLevel) {\n        ZoomLevel.Mid -> {\n            newZoomLevel = ZoomLevel.Max\n            newZoom = max.coerceAtMost(3f)\n        }\n\n        ZoomLevel.Max -> {\n            newZoomLevel = ZoomLevel.Min\n            newZoom = if (min == initial) initial else min\n        }\n\n        else -> {\n            newZoomLevel = ZoomLevel.Mid\n            newZoom = if (min == initial) (min + max.coerceAtMost(3f)) / 2 else initial\n        }\n    }\n    return Pair(newZoomLevel, newZoom)\n}\n\ninternal fun getNextZoomLevel(zoomLevel: ZoomLevel): ZoomLevel = when (zoomLevel) {\n    ZoomLevel.Mid -> {\n        ZoomLevel.Max\n    }\n\n    ZoomLevel.Max -> {\n        ZoomLevel.Min\n    }\n\n    else -> {\n        ZoomLevel.Mid\n    }\n}\n\n/**\n * Update graphic layer with [transformState]\n */\ninternal fun GraphicsLayerScope.update(transformState: TransformState) {\n\n    // Set zoom\n    val zoom = transformState.zoom\n    this.scaleX = zoom\n    this.scaleY = zoom\n\n    // Set pan\n    val pan = transformState.pan\n    val translationX = pan.x\n    val translationY = pan.y\n    this.translationX = translationX\n    this.translationY = translationY\n\n    // Set rotation\n    this.rotationZ = transformState.rotation\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/widget/AspectRatioSlectionCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.widget\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawWithCache\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.cropper.model.CropAspectRatio\n\n@Composable\nfun AspectRatioSelectionCard(\n    modifier: Modifier = Modifier,\n    contentColor: Color = MaterialTheme.colorScheme.surface,\n    color: Color,\n    cropAspectRatio: CropAspectRatio,\n    onClick: ((List<Int>) -> Unit)? = null\n) {\n    Box(\n        modifier = modifier\n            .background(contentColor)\n            .padding(4.dp)\n    ) {\n        Column(horizontalAlignment = Alignment.CenterHorizontally) {\n            val density = LocalDensity.current\n            val layoutDirection = LocalLayoutDirection.current\n            Box(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(4.dp)\n                    .aspectRatio(1f)\n                    .drawWithCache {\n\n                        val outline = cropAspectRatio.shape.createOutline(\n                            size = size, layoutDirection = layoutDirection, density = density\n                        )\n\n                        val width = size.width\n                        val height = size.height\n                        val outlineWidth = outline.bounds.width\n                        val outlineHeight = outline.bounds.height\n\n                        onDrawWithContent {\n\n                            translate(\n                                left = (width - outlineWidth) / 2,\n                                top = (height - outlineHeight) / 2\n                            ) {\n                                drawOutline(\n                                    outline = outline, color = color, style = Stroke(3.dp.toPx())\n                                )\n                            }\n                            drawContent()\n                        }\n                    },\n                contentAlignment = Alignment.Center\n            ) {\n                GridImageLayout(\n                    modifier = Modifier\n                        .matchParentSize()\n                        .padding(5.dp),\n                    thumbnails = cropAspectRatio.icons,\n                    onClick = onClick\n                )\n            }\n            if (cropAspectRatio.title.isNotEmpty()) {\n                Text(\n                    text = cropAspectRatio.title,\n                    color = color,\n                    fontSize = 14.sp,\n                    overflow = TextOverflow.Ellipsis,\n                    maxLines = 1\n                )\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/widget/CropFrameDisplayCard.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.widget\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Edit\nimport androidx.compose.material.icons.outlined.FavoriteBorder\nimport androidx.compose.material.icons.outlined.Image\nimport androidx.compose.material.icons.outlined.StarBorder\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawWithCache\nimport androidx.compose.ui.draw.scale\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.TextUnit\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.t8rin.cropper.model.CropOutline\nimport com.t8rin.cropper.model.CropPath\nimport com.t8rin.cropper.model.CropShape\nimport com.t8rin.cropper.settings.Paths\nimport com.t8rin.cropper.util.scale\n\n@Composable\nfun CropFrameDisplayCard(\n    modifier: Modifier = Modifier,\n    editable: Boolean,\n    scale: Float,\n    outlineColor: Color,\n    editButtonBackgroundColor: Color = MaterialTheme.colorScheme.tertiary,\n    editButtonContentColor: Color = MaterialTheme.colorScheme.onTertiary,\n    fontSize: TextUnit = 12.sp,\n    title: String,\n    cropOutline: CropOutline,\n    onEditClick: () -> Unit = {},\n) {\n\n    Box(\n        modifier = modifier,\n        contentAlignment = Alignment.Center\n    ) {\n        Column(\n            Modifier\n                .graphicsLayer {\n                    scaleX = scale\n                    scaleY = scale\n                },\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n\n            CropFrameDisplay(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(4.dp)\n                    .aspectRatio(1f),\n                cropOutline = cropOutline,\n                color = outlineColor\n            ) {\n\n                if (editable) {\n                    Icon(\n                        modifier = Modifier\n                            .graphicsLayer {\n                                val iconScale =\n                                    scale(\n                                        start1 = .9f,\n                                        end1 = 1f,\n                                        pos = scale.coerceAtLeast(.9f),\n                                        start2 = 0f,\n                                        end2 = 1f\n                                    )\n                                scaleX = iconScale\n                                scaleY = iconScale\n\n                                val translation = this.density.run { 12.dp.toPx() }\n                                translationX = translation\n                                translationY = -translation\n                                clip = true\n                                shape = CircleShape\n\n                                this.density\n                            }\n                            .clickable {\n                                onEditClick()\n                            }\n                            .padding(8.dp)\n                            .background(editButtonBackgroundColor, CircleShape)\n                            .size(20.dp)\n                            .padding(4.dp),\n                        imageVector = Icons.Default.Edit,\n                        tint = editButtonContentColor,\n                        contentDescription = \"Edit\"\n                    )\n                }\n            }\n\n\n            if (title.isNotEmpty()) {\n                Text(\n                    text = title,\n                    color = outlineColor,\n                    fontSize = fontSize,\n                    maxLines = 1,\n                    overflow = TextOverflow.Ellipsis\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun CropFrameDisplay(\n    modifier: Modifier,\n    cropOutline: CropOutline,\n    color: Color,\n    content: @Composable () -> Unit\n) {\n\n    val density = LocalDensity.current\n    val layoutDirection = LocalLayoutDirection.current\n\n    when (cropOutline) {\n\n        is CropShape -> {\n            val shape = remember { cropOutline.shape }\n\n            Box(\n                modifier.drawWithCache {\n\n                    val outline = shape.createOutline(\n                        size = size,\n                        layoutDirection = layoutDirection,\n                        density = density\n                    )\n\n                    onDrawWithContent {\n                        val width = size.width\n                        val height = size.height\n                        val outlineWidth = outline.bounds.width\n                        val outlineHeight = outline.bounds.height\n\n                        translate(\n                            left = (width - outlineWidth) / 2,\n                            top = (height - outlineHeight) / 2\n                        ) {\n                            drawOutline(\n                                outline = outline,\n                                color = color,\n                                style = Stroke(6.dp.toPx())\n                            )\n                        }\n                        drawContent()\n                    }\n                },\n                contentAlignment = Alignment.TopEnd\n            ) {\n                content()\n            }\n        }\n\n        is CropPath -> {\n            Box(\n                modifier = modifier,\n                contentAlignment = Alignment.TopEnd\n            ) {\n                if (cropOutline.path == Paths.Star) {\n                    Icon(\n                        modifier = Modifier\n                            .matchParentSize()\n                            .scale(1.3f),\n                        imageVector = Icons.Outlined.StarBorder,\n                        tint = color,\n                        contentDescription = \"Crop with Path\"\n                    )\n                } else {\n                    Icon(\n                        modifier = Modifier\n                            .matchParentSize()\n                            .scale(1.3f),\n                        imageVector = Icons.Outlined.FavoriteBorder,\n                        tint = color,\n                        contentDescription = \"Crop with Path\"\n                    )\n                }\n\n                content()\n            }\n        }\n\n        else -> {\n            Box(\n                modifier = modifier,\n                contentAlignment = Alignment.TopEnd\n            ) {\n                Icon(\n                    modifier = Modifier\n                        .matchParentSize()\n                        .scale(1.3f),\n                    imageVector = Icons.Outlined.Image,\n                    tint = color,\n                    contentDescription = \"Crop with Image Mask\"\n                )\n\n                content()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "lib/cropper/src/main/java/com/t8rin/cropper/widget/GridImageLayout.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.cropper.widget\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasurePolicy\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\n\n/**\n * Composable that positions and displays [Image]s based on count as one element,\n * horizontal two images, 2 images as quarter of parent and one has lower hals, 4 quarter images\n * 3 images and [Text] that displays number of images that are not visible.\n * @param thumbnails images or icons to be displayed with resource ids\n * @param divider divider space between items when number of items is bigger than 1\n * @param onClick callback for returning images when this composable is clicked\n */\n@Composable\nfun GridImageLayout(\n    modifier: Modifier = Modifier,\n    thumbnails: List<Int>,\n    divider: Dp = 2.dp,\n    onClick: ((List<Int>) -> Unit)? = null\n) {\n    if (thumbnails.isNotEmpty()) {\n\n        ImageDrawLayout(\n            modifier = modifier\n                .clickable {\n                    onClick?.invoke(thumbnails)\n                },\n            divider = divider,\n            itemCount = thumbnails.size\n        ) {\n\n            val size = thumbnails.size\n            if (size < 5) {\n                thumbnails.forEach {\n                    Image(\n                        painter = painterResource(id = it),\n                        contentDescription = \"Icon\",\n                        contentScale = ContentScale.Crop,\n                    )\n                }\n            } else {\n                thumbnails.take(3).forEach {\n                    Image(\n                        painter = painterResource(id = it),\n                        contentDescription = \"Icon\",\n                        contentScale = ContentScale.Crop,\n                    )\n\n                }\n\n                Box(\n                    contentAlignment = Alignment.Center\n                ) {\n                    val carry = size - 3\n                    Text(text = \"+$carry\", fontSize = 20.sp)\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun ImageDrawLayout(\n    modifier: Modifier = Modifier,\n    itemCount: Int,\n    divider: Dp,\n    content: @Composable () -> Unit\n) {\n\n    val spacePx = LocalDensity.current.run { (divider).roundToPx() }\n\n    val measurePolicy = remember(itemCount, spacePx) {\n        MeasurePolicy { measurables, constraints ->\n\n            val newConstraints = when (itemCount) {\n                1 -> constraints\n                2 -> Constraints.fixed(\n                    width = constraints.maxWidth / 2 - spacePx / 2,\n                    height = constraints.maxHeight\n                )\n\n                else -> Constraints.fixed(\n                    width = constraints.maxWidth / 2 - spacePx / 2,\n                    height = constraints.maxHeight / 2 - spacePx / 2\n                )\n            }\n\n            val placeables: List<Placeable> = if (measurables.size != 3) {\n                measurables.map { measurable: Measurable ->\n                    measurable.measure(constraints = newConstraints)\n                }\n            } else {\n                measurables\n                    .take(2)\n                    .map { measurable: Measurable ->\n                        measurable.measure(constraints = newConstraints)\n                    } +\n                        measurables\n                            .last()\n                            .measure(\n                                constraints = Constraints.fixed(\n                                    constraints.maxWidth,\n                                    constraints.maxHeight / 2 - spacePx\n                                )\n                            )\n            }\n\n            layout(constraints.maxWidth, constraints.maxHeight) {\n                when (itemCount) {\n                    1 -> {\n                        placeables.forEach { placeable: Placeable ->\n                            placeable.placeRelative(0, 0)\n                        }\n                    }\n\n                    2 -> {\n                        var xPos = 0\n                        placeables.forEach { placeable: Placeable ->\n                            placeable.placeRelative(xPos, 0)\n                            xPos += placeable.width + spacePx\n                        }\n                    }\n\n                    else -> {\n                        var xPos = 0\n                        var yPos = 0\n\n                        placeables.forEachIndexed { index: Int, placeable: Placeable ->\n                            placeable.placeRelative(xPos, yPos)\n\n                            if (index % 2 == 0) {\n                                xPos += placeable.width + spacePx\n                            } else {\n                                xPos = 0\n                            }\n\n                            if (index % 2 == 1) {\n                                yPos += placeable.height + spacePx\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    Layout(\n        modifier = modifier,\n        content = content,\n        measurePolicy = measurePolicy\n    )\n}\n"
  },
  {
    "path": "lib/curves/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/curves/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.curves\"\n\ndependencies {\n    implementation(libs.coilCompose)\n    implementation(libs.toolbox.gpuimage)\n    implementation(libs.toolbox.histogram)\n}"
  },
  {
    "path": "lib/curves/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/curves/src/main/java/com/t8rin/curves/ImageCurvesEditor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.curves\n\nimport android.app.Activity\nimport android.graphics.Bitmap\nimport android.view.TextureView\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.RadioButton\nimport androidx.compose.material3.RadioButtonDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.CompositingStrategy\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.input.pointer.RequestDisallowInterceptTouchEvent\nimport androidx.compose.ui.input.pointer.pointerInteropFilter\nimport androidx.compose.ui.layout.onGloballyPositioned\nimport androidx.compose.ui.layout.positionInParent\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.viewinterop.AndroidView\nimport com.t8rin.curves.utils.safeAspectRatio\nimport com.t8rin.curves.view.PhotoFilterCurvesControl\nimport jp.co.cyberagent.android.gpuimage.GLTextureView\nimport jp.co.cyberagent.android.gpuimage.GPUImage\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageContrastFilter\n\n\n@Composable\nfun ImageCurvesEditor(\n    bitmap: Bitmap?,\n    state: ImageCurvesEditorState = remember {\n        ImageCurvesEditorState.Default\n    },\n    onStateChange: (ImageCurvesEditorState) -> Unit,\n    imageObtainingTrigger: Boolean,\n    onImageObtained: (Bitmap) -> Unit,\n    modifier: Modifier = Modifier,\n    containerModifier: Modifier = Modifier,\n    contentPadding: PaddingValues = PaddingValues(16.dp),\n    curvesSelectionText: @Composable (curveType: Int) -> Unit = {},\n    colors: ImageCurvesEditorColors = ImageCurvesEditorDefaults.Colors,\n    drawNotActiveCurves: Boolean = true,\n    placeControlsAtTheEnd: Boolean = false,\n    showOriginal: Boolean = false,\n    shape: Shape = RoundedCornerShape(2.dp),\n    disallowInterceptTouchEvents: Boolean = true,\n) {\n    val context = LocalContext.current as Activity\n\n    AnimatedContent(\n        modifier = containerModifier,\n        targetState = bitmap,\n        transitionSpec = { fadeIn() togetherWith fadeOut() }\n    ) { image ->\n        if (image != null) {\n            Box(\n                contentAlignment = Alignment.Center,\n                modifier = modifier\n            ) {\n                var imageHeight by remember(image) {\n                    mutableFloatStateOf(image.height.toFloat())\n                }\n                var imageWidth by remember(image) {\n                    mutableFloatStateOf(image.width.toFloat())\n                }\n                var imageOffset by remember(image) {\n                    mutableStateOf(Offset.Zero)\n                }\n                var textureView by remember(image) {\n                    mutableStateOf<TextureView?>(null)\n                }\n\n                val gpuImage by remember(context, image) {\n                    mutableStateOf(\n                        GPUImage(context).apply {\n                            setImage(image)\n                            setFilter(state.buildFilter())\n                        }\n                    )\n                }\n\n                LaunchedEffect(showOriginal, state) {\n                    gpuImage.setFilter(\n                        if (showOriginal) {\n                            GPUImageContrastFilter(1f)\n                        } else {\n                            state.buildFilter()\n                        }\n                    )\n                }\n\n                LaunchedEffect(imageObtainingTrigger, gpuImage) {\n                    if (imageObtainingTrigger) {\n                        onImageObtained(gpuImage.bitmapWithFilterApplied)\n                    }\n                }\n\n                var controlsPadding by remember {\n                    mutableStateOf(0.dp)\n                }\n\n                val space = with(LocalDensity.current) {\n                    1.dp.toPx()\n                }\n                AndroidView(\n                    modifier = Modifier\n                        .padding(contentPadding)\n                        .then(\n                            if (placeControlsAtTheEnd) Modifier.padding(end = controlsPadding)\n                            else Modifier.padding(bottom = controlsPadding)\n                        )\n                        .aspectRatio(image.safeAspectRatio)\n                        .onGloballyPositioned {\n                            imageHeight = it.size.height.toFloat()\n                            imageWidth = it.size.width.toFloat() - space\n                            imageOffset = Offset(\n                                x = it.positionInParent().x,\n                                y = it.positionInParent().y\n                            )\n                        }\n                        .clip(shape)\n                        .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)\n                        .drawWithContent {\n                            drawContent()\n                            drawRect(\n                                topLeft = Offset(\n                                    x = size.width - space,\n                                    y = 0f\n                                ),\n                                color = Color.Transparent,\n                                blendMode = BlendMode.Clear\n                            )\n                        },\n                    factory = {\n                        GLTextureView(it).apply {\n                            textureView = this\n                            gpuImage.setGLTextureView(this)\n                        }\n                    }\n                )\n                var curvesView by remember {\n                    mutableStateOf<PhotoFilterCurvesControl?>(null)\n                }\n                val disallowIntercept = remember { RequestDisallowInterceptTouchEvent() }\n\n                AndroidView(\n                    modifier = Modifier\n                        .matchParentSize()\n                        .pointerInteropFilter(\n                            requestDisallowInterceptTouchEvent = disallowIntercept,\n                            onTouchEvent = {\n                                curvesView?.onTouchEvent(it)\n                                disallowIntercept.invoke(disallowInterceptTouchEvents)\n                                true\n                            }\n                        ),\n                    factory = {\n                        PhotoFilterCurvesControl(\n                            context = it,\n                            value = state.curvesToolValue\n                        ).apply {\n                            curvesView = this\n                            setColors(\n                                lumaCurveColor = colors.lumaCurveColor.toArgb(),\n                                redCurveColor = colors.redCurveColor.toArgb(),\n                                greenCurveColor = colors.greenCurveColor.toArgb(),\n                                blueCurveColor = colors.blueCurveColor.toArgb(),\n                                defaultCurveColor = colors.defaultCurveColor.toArgb(),\n                                guidelinesColor = colors.guidelinesColor.toArgb()\n                            )\n                            setDrawNotActiveCurves(drawNotActiveCurves)\n                            setActualArea(imageOffset.x, imageOffset.y, imageWidth, imageHeight)\n                            setDelegate {\n                                onStateChange(state.copy())\n                                gpuImage.setFilter(state.buildFilter())\n                            }\n                        }\n                    },\n                    update = {\n                        it.updateValue(state.curvesToolValue)\n                        it.setActualArea(imageOffset.x, imageOffset.y, imageWidth, imageHeight)\n                        it.setDelegate {\n                            onStateChange(state.copy())\n                            gpuImage.setFilter(state.buildFilter())\n                        }\n                        it.setColors(\n                            lumaCurveColor = colors.lumaCurveColor.toArgb(),\n                            redCurveColor = colors.redCurveColor.toArgb(),\n                            greenCurveColor = colors.greenCurveColor.toArgb(),\n                            blueCurveColor = colors.blueCurveColor.toArgb(),\n                            defaultCurveColor = colors.defaultCurveColor.toArgb(),\n                            guidelinesColor = colors.guidelinesColor.toArgb()\n                        )\n                        it.setDrawNotActiveCurves(drawNotActiveCurves)\n                    }\n                )\n\n                val direction = LocalLayoutDirection.current\n                val density = LocalDensity.current\n                val controlsModifier = Modifier\n                    .align(\n                        if (placeControlsAtTheEnd) Alignment.CenterEnd\n                        else Alignment.BottomCenter\n                    )\n                    .then(\n                        if (placeControlsAtTheEnd) {\n                            Modifier.padding(\n                                top = contentPadding.calculateTopPadding(),\n                                bottom = contentPadding.calculateBottomPadding(),\n                                start = 0.dp,\n                                end = contentPadding.calculateEndPadding(direction)\n                            )\n                        } else {\n                            Modifier.padding(\n                                top = 0.dp,\n                                bottom = contentPadding.calculateBottomPadding(),\n                                start = contentPadding.calculateStartPadding(direction),\n                                end = contentPadding.calculateEndPadding(direction)\n                            )\n                        }\n                    )\n                    .onGloballyPositioned {\n                        controlsPadding = with(density) {\n                            if (placeControlsAtTheEnd) {\n                                it.size.width\n                            } else {\n                                it.size.height\n                            }.toDp()\n                        }\n                    }\n\n                if (placeControlsAtTheEnd) {\n                    Column(\n                        verticalArrangement = Arrangement.spacedBy(\n                            space = 8.dp,\n                            alignment = Alignment.CenterVertically\n                        ),\n                        modifier = controlsModifier\n                    ) {\n                        val invalidations = remember(state) {\n                            mutableIntStateOf(0)\n                        }\n\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.lumaCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeLuminance,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.redCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeRed,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.greenCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeGreen,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.blueCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeBlue,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                    }\n                } else {\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.spacedBy(\n                            space = 8.dp,\n                            alignment = Alignment.CenterHorizontally\n                        ),\n                        modifier = controlsModifier\n                    ) {\n                        val invalidations = remember(state) {\n                            mutableIntStateOf(0)\n                        }\n\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.lumaCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeLuminance,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.redCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeRed,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.greenCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeGreen,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                        CurvesSelectionRadioButton(\n                            state = state,\n                            color = colors.blueCurveColor,\n                            type = PhotoFilterCurvesControl.CurvesToolValue.CurvesTypeBlue,\n                            curvesSelectionText = curvesSelectionText,\n                            invalidations = invalidations\n                        )\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun RowScope.CurvesSelectionRadioButton(\n    state: ImageCurvesEditorState,\n    color: Color,\n    type: Int,\n    invalidations: MutableState<Int>,\n    curvesSelectionText: @Composable (type: Int) -> Unit\n) {\n    val interactionSource = remember { MutableInteractionSource() }\n    Column(\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally,\n        modifier = Modifier\n            .weight(1f, false)\n            .clickable(\n                indication = null,\n                interactionSource = interactionSource\n            ) {\n                state.curvesToolValue.activeType = type\n                invalidations.value++\n            }\n    ) {\n        val isSelected by remember(invalidations.value) {\n            mutableStateOf(state.curvesToolValue.activeType == type)\n        }\n        RadioButton(\n            selected = isSelected,\n            onClick = {\n                state.curvesToolValue.activeType = type\n                invalidations.value++\n            },\n            colors = RadioButtonDefaults.colors(\n                selectedColor = color,\n                unselectedColor = color\n            ),\n            interactionSource = interactionSource\n        )\n        CompositionLocalProvider(LocalContentColor provides color) {\n            curvesSelectionText(type)\n        }\n    }\n}\n\n@Composable\nprivate fun ColumnScope.CurvesSelectionRadioButton(\n    state: ImageCurvesEditorState,\n    color: Color,\n    type: Int,\n    invalidations: MutableState<Int>,\n    curvesSelectionText: @Composable (type: Int) -> Unit\n) {\n    val interactionSource = remember { MutableInteractionSource() }\n    Row(\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.Center,\n        modifier = Modifier\n            .weight(1f, false)\n            .clickable(\n                indication = null,\n                interactionSource = interactionSource\n            ) {\n                state.curvesToolValue.activeType = type\n                invalidations.value++\n            }\n    ) {\n        val isSelected by remember(invalidations.value) {\n            mutableStateOf(state.curvesToolValue.activeType == type)\n        }\n        RadioButton(\n            selected = isSelected,\n            onClick = {\n                state.curvesToolValue.activeType = type\n                invalidations.value++\n            },\n            colors = RadioButtonDefaults.colors(\n                selectedColor = color,\n                unselectedColor = color\n            ),\n            interactionSource = interactionSource\n        )\n        CompositionLocalProvider(LocalContentColor provides color) {\n            curvesSelectionText(type)\n        }\n    }\n}"
  },
  {
    "path": "lib/curves/src/main/java/com/t8rin/curves/ImageCurvesEditorColors.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.curves\n\nimport androidx.compose.ui.graphics.Color\n\ndata class ImageCurvesEditorColors(\n    val lumaCurveColor: Color,\n    val redCurveColor: Color,\n    val greenCurveColor: Color,\n    val blueCurveColor: Color,\n    val guidelinesColor: Color,\n    val defaultCurveColor: Color\n)"
  },
  {
    "path": "lib/curves/src/main/java/com/t8rin/curves/ImageCurvesEditorDefaults.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.curves\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.ColorUtils\n\nobject ImageCurvesEditorDefaults {\n\n    val Colors: ImageCurvesEditorColors\n        @Composable\n        get() {\n            return ImageCurvesEditorColors(\n                lumaCurveColor = Color.White.blend(MaterialTheme.colorScheme.primary),\n                redCurveColor = Color(-0x12c2b4).blend(MaterialTheme.colorScheme.primary),\n                greenCurveColor = Color(-0xef1163).blend(MaterialTheme.colorScheme.primary),\n                blueCurveColor = Color(-0xcc8805).blend(MaterialTheme.colorScheme.primary),\n                guidelinesColor = Color(-0x66000001).blend(MaterialTheme.colorScheme.primary),\n                defaultCurveColor = Color(-0x66000001).blend(MaterialTheme.colorScheme.primary)\n            )\n        }\n\n\n    private fun Color.blend(\n        color: Color,\n        @FloatRange(from = 0.0, to = 1.0) fraction: Float = 0.25f\n    ): Color = Color(ColorUtils.blendARGB(this.toArgb(), color.toArgb(), fraction))\n}"
  },
  {
    "path": "lib/curves/src/main/java/com/t8rin/curves/ImageCurvesEditorState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.curves\n\nimport android.graphics.PointF\nimport com.t8rin.curves.view.PhotoFilterCurvesControl.CurvesToolValue\nimport com.t8rin.curves.view.PhotoFilterCurvesControl.CurvesValue\nimport jp.co.cyberagent.android.gpuimage.filter.GPUImageToneCurveFilter\n\n@ConsistentCopyVisibility\ndata class ImageCurvesEditorState internal constructor(\n    internal val curvesToolValue: CurvesToolValue\n) {\n    constructor(controlPoints: List<List<Float>>) : this(CurvesToolValue()) {\n        initControlPoints(controlPoints)\n    }\n\n    fun copy(\n        controlPoints: List<List<Float>>\n    ): ImageCurvesEditorState = ImageCurvesEditorState(controlPoints)\n\n    internal fun buildFilter(): GPUImageToneCurveFilter = GPUImageToneCurveFilter().apply {\n        setAllControlPoints(getControlPointsImpl())\n    }\n\n    fun isDefault(): Boolean = listOf(\n        curvesToolValue.luminanceCurve,\n        curvesToolValue.redCurve,\n        curvesToolValue.greenCurve,\n        curvesToolValue.blueCurve\n    ).all { it.isDefault }\n\n    val controlPoints: List<List<Float>>\n        get() = getControlPointsImpl().map { list -> list.map { it.y } }\n\n    private fun initControlPoints(controlPoints: List<List<Float>>) {\n        curvesToolValue.luminanceCurve.setPoints(controlPoints[0])\n        curvesToolValue.redCurve.setPoints(controlPoints[1])\n        curvesToolValue.greenCurve.setPoints(controlPoints[2])\n        curvesToolValue.blueCurve.setPoints(controlPoints[3])\n    }\n\n    private fun getControlPointsImpl(): List<Array<PointF>> = listOf(\n        curvesToolValue.luminanceCurve.toPoints(),\n        curvesToolValue.redCurve.toPoints(),\n        curvesToolValue.greenCurve.toPoints(),\n        curvesToolValue.blueCurve.toPoints()\n    )\n\n    private fun CurvesValue.setPoints(points: List<Float>) {\n        blacksLevel = points[0] * 100f\n        shadowsLevel = points[1] * 100f\n        midtonesLevel = points[2] * 100f\n        highlightsLevel = points[3] * 100f\n        whitesLevel = points[4] * 100f\n    }\n\n    private fun CurvesValue.toPoints(): Array<PointF> = listOf(\n        PointF(0.0f, blacksLevel / 100f),\n        PointF(0.25f, shadowsLevel / 100f),\n        PointF(0.5f, midtonesLevel / 100f),\n        PointF(0.75f, highlightsLevel / 100f),\n        PointF(1.0f, whitesLevel / 100f),\n    ).toTypedArray()\n\n    companion object {\n        val Default: ImageCurvesEditorState\n            get() = ImageCurvesEditorState(CurvesToolValue())\n    }\n}\n\nfun GPUImageToneCurveFilter(\n    controlPoints: List<List<Float>>\n): GPUImageToneCurveFilter = GPUImageToneCurveFilter(\n    state = ImageCurvesEditorState(controlPoints)\n)\n\nfun GPUImageToneCurveFilter(\n    state: ImageCurvesEditorState\n): GPUImageToneCurveFilter = state.buildFilter()"
  },
  {
    "path": "lib/curves/src/main/java/com/t8rin/curves/utils/Utils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.curves.utils\n\nimport android.graphics.Bitmap\n\ninternal val Bitmap.aspectRatio: Float get() = width / height.toFloat()\n\ninternal val Bitmap.safeAspectRatio: Float\n    get() = aspectRatio\n        .coerceAtLeast(0.005f)\n        .coerceAtMost(1000f)"
  },
  {
    "path": "lib/curves/src/main/java/com/t8rin/curves/view/PhotoFilterCurvesControl.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"ConstPropertyName\")\n\npackage com.t8rin.curves.view\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.res.Resources\nimport android.graphics.Canvas\nimport android.graphics.Paint\nimport android.graphics.Path\nimport android.graphics.RectF\nimport android.text.TextPaint\nimport android.view.MotionEvent\nimport android.view.View\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport java.util.Locale\nimport kotlin.math.abs\nimport kotlin.math.ceil\nimport kotlin.math.floor\nimport kotlin.math.max\nimport kotlin.math.min\n\n\ninternal class PhotoFilterCurvesControl @JvmOverloads constructor(\n    context: Context?,\n    value: CurvesToolValue = CurvesToolValue()\n) : View(context) {\n    private var activeSegment = CurvesSegmentNone\n    private var isMoving = false\n    private var checkForMoving = true\n    private var lastX = 0f\n    private var lastY = 0f\n    private val actualArea = Rect()\n    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)\n    private val paintDash = Paint(Paint.ANTI_ALIAS_FLAG)\n    private val paintCurve = Paint(Paint.ANTI_ALIAS_FLAG)\n    private val paintNotActiveCurve = Paint(Paint.ANTI_ALIAS_FLAG)\n    private val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)\n    private val path = Path()\n    private var delegate: PhotoFilterCurvesControlDelegate? = null\n    private var curveValue: CurvesToolValue\n\n    fun updateValue(\n        value: CurvesToolValue\n    ) {\n        curveValue = value\n        invalidate()\n    }\n\n    private var drawNotActiveCurves: Boolean = true\n    private var lumaCurveColor = -0x1\n    private var redCurveColor = -0x12c2b4\n    private var greenCurveColor = -0xef1163\n    private var blueCurveColor = -0xcc8805\n    private var defaultCurveColor = -0x66000001\n    private var guidelinesColor = -0x66000001\n\n    init {\n        setWillNotDraw(false)\n\n        curveValue = value\n\n        paint.color = guidelinesColor\n        paint.strokeWidth = dp(1f).toFloat()\n        paint.style = Paint.Style.STROKE\n\n        paintDash.color = defaultCurveColor\n        paintDash.strokeWidth = dp(2f).toFloat()\n        paintDash.style = Paint.Style.STROKE\n        paintDash.strokeCap = Paint.Cap.ROUND\n\n        paintCurve.color = lumaCurveColor\n        paintCurve.strokeWidth = dp(2f).toFloat()\n        paintCurve.style = Paint.Style.STROKE\n        paintCurve.strokeCap = Paint.Cap.ROUND\n        paintCurve.setShadowLayer(2f, 0f, 0f, Color.Black.copy(0.5f).toArgb())\n\n        paintNotActiveCurve.color = lumaCurveColor\n        paintNotActiveCurve.strokeWidth = dp(1f).toFloat()\n        paintNotActiveCurve.style = Paint.Style.STROKE\n        paintNotActiveCurve.strokeCap = Paint.Cap.ROUND\n        paintNotActiveCurve.setShadowLayer(1f, 0f, 0f, Color.Black.copy(0.5f).toArgb())\n\n        textPaint.color = Color(defaultCurveColor).copy(1f).toArgb()\n        textPaint.textSize = dp(13f).toFloat()\n    }\n\n    fun setDrawNotActiveCurves(\n        drawNotActiveCurves: Boolean\n    ) {\n        this.drawNotActiveCurves = drawNotActiveCurves\n        invalidate()\n    }\n\n    fun setColors(\n        lumaCurveColor: Int,\n        redCurveColor: Int,\n        greenCurveColor: Int,\n        blueCurveColor: Int,\n        defaultCurveColor: Int,\n        guidelinesColor: Int\n    ) {\n        this.lumaCurveColor = lumaCurveColor\n        this.redCurveColor = redCurveColor\n        this.greenCurveColor = greenCurveColor\n        this.blueCurveColor = blueCurveColor\n        this.guidelinesColor = guidelinesColor\n        this.defaultCurveColor = defaultCurveColor\n        paint.color = guidelinesColor\n        paintDash.color = defaultCurveColor\n        textPaint.color = Color(defaultCurveColor).copy(1f).toArgb()\n\n        invalidate()\n    }\n\n    fun setDelegate(photoFilterCurvesControlDelegate: PhotoFilterCurvesControlDelegate?) {\n        delegate = photoFilterCurvesControlDelegate\n    }\n\n    fun setActualArea(x: Float, y: Float, width: Float, height: Float) {\n        actualArea.x = x\n        actualArea.y = y\n        actualArea.width = width\n        actualArea.height = height\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    override fun onTouchEvent(event: MotionEvent): Boolean {\n        val action = event.actionMasked\n\n        when (action) {\n            MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_DOWN -> {\n                if (event.pointerCount == 1) {\n                    if (checkForMoving && !isMoving) {\n                        val locationX = event.x\n                        val locationY = event.y\n                        lastX = locationX\n                        lastY = locationY\n                        if (locationX >= actualArea.x && locationX <= actualArea.x + actualArea.width && locationY >= actualArea.y && locationY <= actualArea.y + actualArea.height) {\n                            isMoving = true\n                        }\n                        checkForMoving = false\n                        if (isMoving) {\n                            handlePan(GestureStateBegan, event)\n                        }\n                    }\n                } else {\n                    if (isMoving) {\n                        handlePan(GestureStateEnded, event)\n                        checkForMoving = true\n                        isMoving = false\n                    }\n                }\n            }\n\n            MotionEvent.ACTION_POINTER_UP, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {\n                if (isMoving) {\n                    handlePan(GestureStateEnded, event)\n                    isMoving = false\n                }\n                checkForMoving = true\n            }\n\n            MotionEvent.ACTION_MOVE -> {\n                if (isMoving) {\n                    handlePan(GestureStateChanged, event)\n                }\n            }\n        }\n        return true\n    }\n\n    private fun handlePan(state: Int, event: MotionEvent) {\n        val locationX = event.x\n        val locationY = event.y\n\n        when (state) {\n            GestureStateBegan -> {\n                selectSegmentWithPoint(locationX)\n            }\n\n            GestureStateChanged -> {\n                val delta = min(2.0, ((lastY - locationY) / 8.0f).toDouble())\n                    .toFloat()\n\n                var curveValue: CurvesValue? = null\n                when (this.curveValue.activeType) {\n                    CurvesToolValue.CurvesTypeLuminance -> curveValue =\n                        this.curveValue.luminanceCurve\n\n                    CurvesToolValue.CurvesTypeRed -> curveValue = this.curveValue.redCurve\n                    CurvesToolValue.CurvesTypeGreen -> curveValue = this.curveValue.greenCurve\n                    CurvesToolValue.CurvesTypeBlue -> curveValue = this.curveValue.blueCurve\n                    else -> {}\n                }\n                checkNotNull(curveValue)\n                when (activeSegment) {\n                    CurvesSegmentBlacks -> curveValue.blacksLevel =\n                        max(0.0, min(100.0, (curveValue.blacksLevel + delta).toDouble()))\n                            .toFloat()\n\n                    CurvesSegmentShadows -> curveValue.shadowsLevel =\n                        max(0.0, min(100.0, (curveValue.shadowsLevel + delta).toDouble()))\n                            .toFloat()\n\n                    CurvesSegmentMidtones -> curveValue.midtonesLevel =\n                        max(0.0, min(100.0, (curveValue.midtonesLevel + delta).toDouble()))\n                            .toFloat()\n\n                    CurvesSegmentHighlights -> curveValue.highlightsLevel =\n                        max(0.0, min(100.0, (curveValue.highlightsLevel + delta).toDouble()))\n                            .toFloat()\n\n                    CurvesSegmentWhites -> curveValue.whitesLevel =\n                        max(0.0, min(100.0, (curveValue.whitesLevel + delta).toDouble()))\n                            .toFloat()\n\n                    else -> {}\n                }\n                invalidate()\n\n                if (delegate != null) {\n                    delegate!!.valueChanged()\n                }\n\n                lastX = locationX\n                lastY = locationY\n            }\n\n            GestureStateEnded, GestureStateCancelled, GestureStateFailed -> {\n                unselectSegments()\n            }\n\n            else -> {}\n        }\n    }\n\n    private fun selectSegmentWithPoint(pointX: Float) {\n        var pointx = pointX\n        if (activeSegment != CurvesSegmentNone) {\n            return\n        }\n        val segmentWidth = actualArea.width / 5.0f\n        pointx -= actualArea.x\n        activeSegment = floor(((pointx / segmentWidth) + 1).toDouble()).toInt()\n    }\n\n    private fun unselectSegments() {\n        if (activeSegment == CurvesSegmentNone) {\n            return\n        }\n        activeSegment = CurvesSegmentNone\n    }\n\n    @SuppressLint(\"DrawAllocation\")\n    override fun onDraw(canvas: Canvas) {\n        val segmentWidth = actualArea.width / 5.0f\n\n        canvas.drawRect(\n            RectF(\n                actualArea.x,\n                actualArea.y + actualArea.height - dp(20f),\n                actualArea.x + actualArea.width,\n                actualArea.y + actualArea.height\n            ),\n            Paint().apply {\n                color = Color.Black.copy(0.5f).toArgb()\n            }\n        )\n\n        for (i in 0..3) {\n            canvas.drawLine(\n                actualArea.x + segmentWidth + i * segmentWidth,\n                actualArea.y,\n                actualArea.x + segmentWidth + i * segmentWidth,\n                actualArea.y + actualArea.height,\n                paint\n            )\n        }\n\n        canvas.drawLine(\n            actualArea.x,\n            actualArea.y + actualArea.height,\n            actualArea.x + actualArea.width,\n            actualArea.y,\n            paintDash\n        )\n\n        var curvesValue: CurvesValue? = null\n        when (curveValue.activeType) {\n            CurvesToolValue.CurvesTypeLuminance -> {\n                paintCurve.color = lumaCurveColor\n                curvesValue = curveValue.luminanceCurve\n            }\n\n            CurvesToolValue.CurvesTypeRed -> {\n                paintCurve.color = redCurveColor\n                curvesValue = curveValue.redCurve\n            }\n\n            CurvesToolValue.CurvesTypeGreen -> {\n                paintCurve.color = greenCurveColor\n                curvesValue = curveValue.greenCurve\n            }\n\n            CurvesToolValue.CurvesTypeBlue -> {\n                paintCurve.color = blueCurveColor\n                curvesValue = curveValue.blueCurve\n            }\n\n            else -> Unit\n        }\n        for (a in 0..4) {\n            checkNotNull(curvesValue)\n            val str = when (a) {\n                0 -> String.format(Locale.US, \"%.2f\", curvesValue.blacksLevel / 100.0f)\n                1 -> String.format(Locale.US, \"%.2f\", curvesValue.shadowsLevel / 100.0f)\n                2 -> String.format(Locale.US, \"%.2f\", curvesValue.midtonesLevel / 100.0f)\n                3 -> String.format(Locale.US, \"%.2f\", curvesValue.highlightsLevel / 100.0f)\n                4 -> String.format(Locale.US, \"%.2f\", curvesValue.whitesLevel / 100.0f)\n                else -> \"\"\n            }\n            val width = textPaint.measureText(str)\n            canvas.drawText(\n                str,\n                actualArea.x + (segmentWidth - width) / 2 + segmentWidth * a,\n                actualArea.y + actualArea.height - dp(4f),\n                textPaint\n            )\n        }\n\n        var points: FloatArray\n\n        if (drawNotActiveCurves) {\n            listOf(\n                curveValue.luminanceCurve to lumaCurveColor,\n                curveValue.redCurve to redCurveColor,\n                curveValue.greenCurve to greenCurveColor,\n                curveValue.blueCurve to blueCurveColor\n            ).filter { it.first != curvesValue && !it.first.isDefault }.forEach { (curve, color) ->\n                paintNotActiveCurve.color = Color(color).copy(0.7f).toArgb()\n                points = curve.interpolateCurve()\n                invalidate()\n                path.reset()\n                for (a in 0 until points.size / 2) {\n                    if (a == 0) {\n                        path.moveTo(\n                            actualArea.x + points[0] * actualArea.width,\n                            actualArea.y + (1.0f - points[1]) * actualArea.height\n                        )\n                    } else {\n                        path.lineTo(\n                            actualArea.x + points[a * 2] * actualArea.width,\n                            actualArea.y + (1.0f - points[a * 2 + 1]) * actualArea.height\n                        )\n                    }\n                }\n\n                canvas.drawPath(path, paintNotActiveCurve)\n            }\n        }\n\n        points = curvesValue!!.interpolateCurve()\n        invalidate()\n        path.reset()\n        for (a in 0 until points.size / 2) {\n            if (a == 0) {\n                path.moveTo(\n                    actualArea.x + points[0] * actualArea.width,\n                    actualArea.y + (1.0f - points[1]) * actualArea.height\n                )\n            } else {\n                path.lineTo(\n                    actualArea.x + points[a * 2] * actualArea.width,\n                    actualArea.y + (1.0f - points[a * 2 + 1]) * actualArea.height\n                )\n            }\n        }\n\n        canvas.drawPath(path, paintCurve)\n    }\n\n    fun interface PhotoFilterCurvesControlDelegate {\n        fun valueChanged()\n    }\n\n    internal class CurvesValue {\n        var blacksLevel: Float = 0.0f\n        var shadowsLevel: Float = 25.0f\n        var midtonesLevel: Float = 50.0f\n        var highlightsLevel: Float = 75.0f\n        var whitesLevel: Float = 100.0f\n\n        private var cachedDataPoints: FloatArray? = null\n\n        val dataPoints: FloatArray?\n            get() {\n                if (cachedDataPoints == null) {\n                    interpolateCurve()\n                }\n                return cachedDataPoints\n            }\n\n        fun interpolateCurve(): FloatArray {\n            val points = floatArrayOf(\n                -0.001f, blacksLevel / 100.0f,\n                0.0f, blacksLevel / 100.0f,\n                0.25f, shadowsLevel / 100.0f,\n                0.5f, midtonesLevel / 100.0f,\n                0.75f, highlightsLevel / 100.0f,\n                1f, whitesLevel / 100.0f,\n                1.001f, whitesLevel / 100.0f\n            )\n\n            val dataPoints = ArrayList<Float>(100)\n            val interpolatedPoints = ArrayList<Float>(100)\n\n            interpolatedPoints.add(points[0])\n            interpolatedPoints.add(points[1])\n\n            for (index in 1 until points.size / 2 - 2) {\n                val point0x = points[(index - 1) * 2]\n                val point0y = points[(index - 1) * 2 + 1]\n                val point1x = points[index * 2]\n                val point1y = points[index * 2 + 1]\n                val point2x = points[(index + 1) * 2]\n                val point2y = points[(index + 1) * 2 + 1]\n                val point3x = points[(index + 2) * 2]\n                val point3y = points[(index + 2) * 2 + 1]\n\n\n                for (i in 1 until curveGranularity) {\n                    val t = i.toFloat() * (1.0f / curveGranularity.toFloat())\n                    val tt = t * t\n                    val ttt = tt * t\n\n                    val pix =\n                        0.5f * (2 * point1x + (point2x - point0x) * t + (2 * point0x - 5 * point1x + 4 * point2x - point3x) * tt + (3 * point1x - point0x - 3 * point2x + point3x) * ttt)\n                    var piy =\n                        0.5f * (2 * point1y + (point2y - point0y) * t + (2 * point0y - 5 * point1y + 4 * point2y - point3y) * tt + (3 * point1y - point0y - 3 * point2y + point3y) * ttt)\n\n                    piy = max(0.0, min(1.0, piy.toDouble())).toFloat()\n\n                    if (pix > point0x) {\n                        interpolatedPoints.add(pix)\n                        interpolatedPoints.add(piy)\n                    }\n\n                    if ((i - 1) % curveDataStep == 0) {\n                        dataPoints.add(piy)\n                    }\n                }\n                interpolatedPoints.add(point2x)\n                interpolatedPoints.add(point2y)\n            }\n            interpolatedPoints.add(points[12])\n            interpolatedPoints.add(points[13])\n\n            cachedDataPoints = FloatArray(dataPoints.size)\n            for (a in cachedDataPoints!!.indices) {\n                cachedDataPoints!![a] = dataPoints[a]\n            }\n            val retValue = FloatArray(interpolatedPoints.size)\n            for (a in retValue.indices) {\n                retValue[a] = interpolatedPoints[a]\n            }\n            return retValue\n        }\n\n        val isDefault: Boolean\n            get() = abs((blacksLevel - 0).toDouble()) < 0.00001 && abs((shadowsLevel - 25).toDouble()) < 0.00001 && abs(\n                (midtonesLevel - 50).toDouble()\n            ) < 0.00001 && abs((highlightsLevel - 75).toDouble()) < 0.00001 && abs(\n                (whitesLevel - 100).toDouble()\n            ) < 0.00001\n    }\n\n    internal class CurvesToolValue {\n        var luminanceCurve: CurvesValue = CurvesValue()\n        var redCurve: CurvesValue = CurvesValue()\n        var greenCurve: CurvesValue = CurvesValue()\n        var blueCurve: CurvesValue = CurvesValue()\n        var activeType: Int = CurvesTypeLuminance\n\n        companion object {\n            const val CurvesTypeLuminance: Int = 0\n            const val CurvesTypeRed: Int = 1\n            const val CurvesTypeGreen: Int = 2\n            const val CurvesTypeBlue: Int = 3\n        }\n    }\n\n    companion object {\n        private const val curveGranularity = 100\n        private const val curveDataStep = 2\n        private val density = Resources.getSystem().displayMetrics.density\n        private const val CurvesSegmentNone = 0\n        private const val CurvesSegmentBlacks = 1\n        private const val CurvesSegmentShadows = 2\n        private const val CurvesSegmentMidtones = 3\n        private const val CurvesSegmentHighlights = 4\n        private const val CurvesSegmentWhites = 5\n        private const val GestureStateBegan = 1\n        private const val GestureStateChanged = 2\n        private const val GestureStateEnded = 3\n        private const val GestureStateCancelled = 4\n        private const val GestureStateFailed = 5\n        fun dp(value: Float): Int {\n            if (value == 0f) {\n                return 0\n            }\n            return ceil((density * value).toDouble())\n                .toInt()\n        }\n    }\n}"
  },
  {
    "path": "lib/curves/src/main/java/com/t8rin/curves/view/Rect.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.curves.view\n\ninternal class Rect {\n    @JvmField\n    var x: Float = 0f\n\n    @JvmField\n    var y: Float = 0f\n\n    @JvmField\n    var width: Float = 0f\n\n    @JvmField\n    var height: Float = 0f\n\n    constructor()\n\n    constructor(x: Float, y: Float, width: Float, height: Float) {\n        this.x = x\n        this.y = y\n        this.width = width\n        this.height = height\n    }\n}"
  },
  {
    "path": "lib/documentscanner/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/documentscanner/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n}\n\nandroid.namespace = \"com.websitebeaver.documentscanner\"\n\ndependencies {\n    implementation(libs.opencv)\n    implementation(libs.appCompat)\n    implementation(libs.toolbox.exif)\n\n    implementation(projects.lib.opencvTools)\n}"
  },
  {
    "path": "lib/documentscanner/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <uses-feature\n        android:name=\"android.hardware.camera\"\n        android:required=\"true\" />\n\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <application>\n        <activity\n            android:name=\".DocumentScannerActivity\"\n            android:configChanges=\"orientation|screenSize\"\n            android:screenOrientation=\"portrait\"\n            android:theme=\"@style/Theme.FullScreen\" />\n\n        <provider\n            android:name=\"com.websitebeaver.documentscanner.DocumentScannerFileProvider\"\n            android:authorities=\"${applicationId}.DocumentScannerFileProvider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/file_paths\" />\n        </provider>\n    </application>\n</manifest>"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/DocumentScanner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner\n\nimport android.app.Activity\nimport android.content.Intent\nimport androidx.activity.ComponentActivity\nimport androidx.activity.result.ActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport com.websitebeaver.documentscanner.constants.DefaultSetting\nimport com.websitebeaver.documentscanner.constants.DocumentScannerExtra\nimport com.websitebeaver.documentscanner.constants.ResponseType\nimport com.websitebeaver.documentscanner.extensions.toBase64\nimport com.websitebeaver.documentscanner.utils.ImageUtil\nimport java.io.File\n\n/**\n * This class is used to start a document scan. It accepts parameters used to customize\n * the document scan, and callback parameters.\n *\n * @param activity the current activity\n * @param successHandler event handler that gets called on document scan success\n * @param errorHandler event handler that gets called on document scan error\n * @param cancelHandler event handler that gets called when a user cancels the document scan\n * @param responseType the cropped image gets returned in this format\n * @param letUserAdjustCrop whether or not the user can change the auto detected document corners\n * @param maxNumDocuments the maximum number of documents a user can scan at once\n * @param croppedImageQuality the 0 - 100 quality of the cropped image\n * @constructor creates document scanner\n */\nclass DocumentScanner(\n    private val activity: ComponentActivity,\n    private val successHandler: ((documentScanResults: ArrayList<String>) -> Unit)? = null,\n    private val errorHandler: ((errorMessage: String) -> Unit)? = null,\n    private val cancelHandler: (() -> Unit)? = null,\n    private var responseType: String? = null,\n    private var letUserAdjustCrop: Boolean? = null,\n    private var maxNumDocuments: Int? = null,\n    private var croppedImageQuality: Int? = null\n) {\n    init {\n        responseType = responseType ?: DefaultSetting.RESPONSE_TYPE\n        croppedImageQuality = croppedImageQuality ?: DefaultSetting.CROPPED_IMAGE_QUALITY\n    }\n\n    /**\n     * create intent to launch document scanner and set custom options\n     */\n    fun createDocumentScanIntent(): Intent {\n        val documentScanIntent = Intent(activity, DocumentScannerActivity::class.java)\n        documentScanIntent.putExtra(\n            DocumentScannerExtra.EXTRA_CROPPED_IMAGE_QUALITY,\n            croppedImageQuality\n        )\n        documentScanIntent.putExtra(\n            DocumentScannerExtra.EXTRA_LET_USER_ADJUST_CROP,\n            letUserAdjustCrop\n        )\n        documentScanIntent.putExtra(\n            DocumentScannerExtra.EXTRA_MAX_NUM_DOCUMENTS,\n            maxNumDocuments\n        )\n\n        return documentScanIntent\n    }\n\n    /**\n     * handle response from document scanner\n     *\n     * @param result the document scanner activity result\n     */\n    fun handleDocumentScanIntentResult(result: ActivityResult) = try {\n        // make sure responseType is valid\n        if (!arrayOf(\n                ResponseType.BASE64,\n                ResponseType.IMAGE_FILE_PATH\n            ).contains(responseType)\n        ) {\n            throw Exception(\n                \"responseType must be either ${ResponseType.BASE64} \" +\n                        \"or ${ResponseType.IMAGE_FILE_PATH}\"\n            )\n        }\n\n        when (result.resultCode) {\n            Activity.RESULT_OK -> {\n                // check for errors\n                val error = result.data?.extras?.getString(\"error\")\n                if (error != null) {\n                    throw Exception(\"error - $error\")\n                }\n\n                // get an array with scanned document file paths\n                val croppedImageResults: ArrayList<String> =\n                    result.data?.getStringArrayListExtra(\n                        \"croppedImageResults\"\n                    ) ?: throw Exception(\"No cropped images returned\")\n\n                // if responseType is imageFilePath return an array of file paths\n                var successResponse: ArrayList<String> = croppedImageResults\n\n                // if responseType is base64 return an array of base64 images\n                if (responseType == ResponseType.BASE64) {\n                    val base64CroppedImages =\n                        croppedImageResults.map { croppedImagePath ->\n                            // read cropped image from file path, and convert to base 64\n                            val base64Image = ImageUtil().readBitmapFromFileUriString(\n                                croppedImagePath,\n                                activity.contentResolver\n                            ).toBase64(croppedImageQuality!!)\n\n                            // delete cropped image from android device to avoid\n                            // accumulating photos\n                            File(croppedImagePath).delete()\n\n                            base64Image\n                        }\n\n                    successResponse = base64CroppedImages as ArrayList<String>\n                }\n\n                // trigger the success event handler with an array of cropped images\n                successHandler?.let { it(successResponse) }\n            }\n\n            Activity.RESULT_CANCELED -> {\n                // user closed camera\n                cancelHandler?.let { it() }\n            }\n\n            else -> Unit\n        }\n    } catch (exception: Exception) {\n        // trigger the error event handler\n        errorHandler?.let { it(exception.localizedMessage ?: \"An error happened\") }\n    }\n\n    /**\n     * add document scanner result handler and launch the document scanner\n     */\n    fun startScan() {\n        activity.registerForActivityResult(\n            ActivityResultContracts.StartActivityForResult()\n        ) { result: ActivityResult -> handleDocumentScanIntentResult(result) }\n            .launch(createDocumentScanIntent())\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/DocumentScannerActivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"DEPRECATION\")\n\npackage com.websitebeaver.documentscanner\n\nimport android.content.Intent\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport android.os.Bundle\nimport android.view.View\nimport android.widget.ImageButton\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.content.FileProvider\nimport com.t8rin.opencv_tools.document_detector.DocumentDetector\nimport com.websitebeaver.documentscanner.constants.DefaultSetting\nimport com.websitebeaver.documentscanner.constants.DocumentScannerExtra\nimport com.websitebeaver.documentscanner.extensions.move\nimport com.websitebeaver.documentscanner.extensions.onClick\nimport com.websitebeaver.documentscanner.extensions.saveToFile\nimport com.websitebeaver.documentscanner.extensions.screenHeight\nimport com.websitebeaver.documentscanner.extensions.screenWidth\nimport com.websitebeaver.documentscanner.models.Document\nimport com.websitebeaver.documentscanner.models.Quad\nimport com.websitebeaver.documentscanner.ui.ImageCropView\nimport com.websitebeaver.documentscanner.utils.FileUtil\nimport com.websitebeaver.documentscanner.utils.ImageUtil\nimport org.opencv.android.OpenCVLoader\nimport org.opencv.core.Point\nimport java.io.File\nimport java.io.IOException\n\n/**\n * This class contains the main document scanner code. It opens the camera, lets the user\n * take a photo of a document (homework paper, business card, etc.), detects document corners,\n * allows user to make adjustments to the detected corners, depending on options, and saves\n * the cropped document. It allows the user to do this for 1 or more documents.\n *\n * @constructor creates document scanner activity\n */\nclass DocumentScannerActivity : AppCompatActivity() {\n    /**\n     * @property maxNumDocuments maximum number of documents a user can scan at a time\n     */\n    private var maxNumDocuments = DefaultSetting.MAX_NUM_DOCUMENTS\n\n    /**\n     * @property letUserAdjustCrop whether or not to let user move automatically detected corners\n     */\n    private var letUserAdjustCrop = DefaultSetting.LET_USER_ADJUST_CROP\n\n    /**\n     * @property croppedImageQuality the 0 - 100 quality of the cropped image\n     */\n    private var croppedImageQuality = DefaultSetting.CROPPED_IMAGE_QUALITY\n\n    /**\n     * @property cropperOffsetWhenCornersNotFound if we can't find document corners, we set\n     * corners to image size with a slight margin\n     */\n    private val cropperOffsetWhenCornersNotFound = 100.0\n\n    /**\n     * @property document This is the current document. Initially it's null. Once we capture\n     * the photo, and find the corners we update document.\n     */\n    private var document: Document? = null\n\n    /**\n     * @property documents a list of documents (original photo file path, original photo\n     * dimensions and 4 corner points)\n     */\n    private val documents = mutableListOf<Document>()\n\n    /**\n     * @property imageView container with original photo and cropper\n     */\n    private lateinit var imageView: ImageCropView\n\n    /**\n     * called when activity is created\n     *\n     * @param savedInstanceState persisted data that maintains state\n     */\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        try {\n            OpenCVLoader.initLocal()\n        } catch (exception: Exception) {\n            finishIntentWithError(\n                \"error starting OpenCV: ${exception.message}\"\n            )\n        }\n\n        // Show cropper, accept crop button, add new document button, and\n        // retake photo button. Since we open the camera in a few lines, the user\n        // doesn't see this until they finish taking a photo\n        setContentView(R.layout.activity_image_crop)\n        imageView = findViewById(R.id.image_view)\n\n        try {\n            // validate maxNumDocuments option, and update default if user sets it\n            var userSpecifiedMaxImages: Int? = null\n            intent.extras?.get(DocumentScannerExtra.EXTRA_MAX_NUM_DOCUMENTS)?.let {\n                if (it.toString().toIntOrNull() == null) {\n                    throw Exception(\n                        \"${DocumentScannerExtra.EXTRA_MAX_NUM_DOCUMENTS} must be a positive number\"\n                    )\n                }\n                userSpecifiedMaxImages = it as Int\n                maxNumDocuments = userSpecifiedMaxImages\n            }\n\n            // validate letUserAdjustCrop option, and update default if user sets it\n            intent.extras?.get(DocumentScannerExtra.EXTRA_LET_USER_ADJUST_CROP)?.let {\n                if (!arrayOf(\"true\", \"false\").contains(it.toString())) {\n                    throw Exception(\n                        \"${DocumentScannerExtra.EXTRA_LET_USER_ADJUST_CROP} must true or false\"\n                    )\n                }\n                letUserAdjustCrop = it as Boolean\n            }\n\n            // if we don't want user to move corners, we can let the user only take 1 photo\n            if (!letUserAdjustCrop) {\n                maxNumDocuments = 1\n\n                if (userSpecifiedMaxImages != null && userSpecifiedMaxImages != 1) {\n                    throw Exception(\n                        \"${DocumentScannerExtra.EXTRA_MAX_NUM_DOCUMENTS} must be 1 when \" +\n                                \"${DocumentScannerExtra.EXTRA_LET_USER_ADJUST_CROP} is false\"\n                    )\n                }\n            }\n\n            // validate croppedImageQuality option, and update value if user sets it\n            intent.extras?.get(DocumentScannerExtra.EXTRA_CROPPED_IMAGE_QUALITY)?.let {\n                if (it !is Int || it < 0 || it > 100) {\n                    throw Exception(\n                        \"${DocumentScannerExtra.EXTRA_CROPPED_IMAGE_QUALITY} must be a number \" +\n                                \"between 0 and 100\"\n                    )\n                }\n                croppedImageQuality = it\n            }\n        } catch (exception: Exception) {\n            finishIntentWithError(\n                \"invalid extra: ${exception.message}\"\n            )\n            return\n        }\n\n        // set click event handlers for new document button, accept and crop document button,\n        // and retake document photo button\n        val newPhotoButton: ImageButton = findViewById(R.id.new_photo_button)\n        val completeDocumentScanButton: ImageButton = findViewById(\n            R.id.complete_document_scan_button\n        )\n        val retakePhotoButton: ImageButton = findViewById(R.id.retake_photo_button)\n\n        newPhotoButton.onClick { onClickNew() }\n        completeDocumentScanButton.onClick { onClickDone() }\n        retakePhotoButton.onClick { onClickRetake() }\n\n        // open camera, so user can snap document photo\n        try {\n            openCamera()\n        } catch (exception: Exception) {\n            finishIntentWithError(\n                \"error opening camera: ${exception.message}\"\n            )\n        }\n    }\n\n    /**\n     * Pass in a photo of a document, and get back 4 corner points (top left, top right, bottom\n     * right, bottom left). This tries to detect document corners, but falls back to photo corners\n     * with slight margin in case we can't detect document corners.\n     *\n     * @param photo the original photo with a rectangular document\n     * @return a List of 4 OpenCV points (document corners)\n     */\n    private fun getDocumentCorners(photo: Bitmap): List<Point> {\n        val cornerPoints: List<Point>? = DocumentDetector.findDocumentCorners(photo)\n\n        // if cornerPoints is null then default the corners to the photo bounds with a margin\n        return cornerPoints ?: listOf(\n            Point(0.0, 0.0).move(\n                cropperOffsetWhenCornersNotFound,\n                cropperOffsetWhenCornersNotFound\n            ),\n            Point(photo.width.toDouble(), 0.0).move(\n                -cropperOffsetWhenCornersNotFound,\n                cropperOffsetWhenCornersNotFound\n            ),\n            Point(0.0, photo.height.toDouble()).move(\n                cropperOffsetWhenCornersNotFound,\n                -cropperOffsetWhenCornersNotFound\n            ),\n            Point(photo.width.toDouble(), photo.height.toDouble()).move(\n                -cropperOffsetWhenCornersNotFound,\n                -cropperOffsetWhenCornersNotFound\n            )\n        )\n    }\n\n    /**\n     * Set document to null since we're capturing a new document, and open the camera. If the\n     * user captures a photo successfully document gets updated.\n     */\n    /**\n     * @property photoFilePath the photo file path\n     */\n    private lateinit var photoFilePath: String\n\n    /**\n     * @property startForResult used to launch camera\n     */\n    private val startForResult = registerForActivityResult(\n        ActivityResultContracts.TakePicture()\n    ) { isSuccess ->\n        if (isSuccess) {\n            // send back photo file path on capture success\n            val originalPhotoPath = photoFilePath\n            // user takes photo\n\n            // if maxNumDocuments is 3 and this is the 3rd photo, hide the new photo button since\n            // we reach the allowed limit\n            if (documents.size == maxNumDocuments - 1) {\n                val newPhotoButton: ImageButton = findViewById(R.id.new_photo_button)\n                newPhotoButton.isClickable = false\n                newPhotoButton.visibility = View.INVISIBLE\n            }\n\n            // get bitmap from photo file path\n            val photo: Bitmap = ImageUtil().getImageFromFilePath(originalPhotoPath)\n\n            // get document corners by detecting them, or falling back to photo corners with\n            // slight margin if we can't find the corners\n            val corners = try {\n                val (topLeft, topRight, bottomLeft, bottomRight) = getDocumentCorners(photo)\n                Quad(topLeft, topRight, bottomRight, bottomLeft)\n            } catch (exception: Exception) {\n                finishIntentWithError(\n                    \"unable to get document corners: ${exception.message}\"\n                )\n                return@registerForActivityResult\n            }\n\n            document = Document(originalPhotoPath, photo.width, photo.height, corners)\n\n            if (letUserAdjustCrop) {\n                // user is allowed to move corners to make corrections\n                try {\n                    // set preview image height based off of photo dimensions\n                    imageView.setImagePreviewBounds(photo, screenWidth, screenHeight)\n\n                    // display original photo, so user can adjust detected corners\n                    imageView.setImage(photo)\n\n                    // document corner points are in original image coordinates, so we need to\n                    // scale and move the points to account for blank space (caused by photo and\n                    // photo container having different aspect ratios)\n                    val cornersInImagePreviewCoordinates = corners\n                        .mapOriginalToPreviewImageCoordinates(\n                            imageView.imagePreviewBounds,\n                            imageView.imagePreviewBounds.height() / photo.height\n                        )\n\n                    // display cropper, and allow user to move corners\n                    imageView.setCropper(cornersInImagePreviewCoordinates)\n                } catch (exception: Exception) {\n                    finishIntentWithError(\n                        \"unable get image preview ready: ${exception.message}\"\n                    )\n                    return@registerForActivityResult\n                }\n            } else {\n                // user isn't allowed to move corners, so accept automatically detected corners\n                document?.let { document ->\n                    documents.add(document)\n                }\n\n                // create cropped document image, and return file path to complete document scan\n                cropDocumentAndFinishIntent()\n            }\n        } else {\n            // delete the photo since the user didn't finish taking the photo\n            File(photoFilePath).delete()\n            // user exits camera\n            // complete document scan if this is the first document since we can't go to crop view\n            // until user takes at least 1 photo\n            if (documents.isEmpty()) {\n                onClickCancel()\n            }\n        }\n    }\n\n    /**\n     * open the camera by launching an image capture intent\n     *\n     * @param pageNumber the current document page number\n     */\n    @Throws(IOException::class)\n    private fun openCamera(pageNumber: Int = documents.size) {\n        // create new file for photo\n        val photoFile: File = FileUtil().createImageFile(this, pageNumber)\n\n        // store the photo file path, and send it back once the photo is saved\n        photoFilePath = photoFile.absolutePath\n\n        // photo gets saved to this file path\n        // open camera\n        startForResult.launch(\n            FileProvider.getUriForFile(\n                this,\n                \"${packageName}.DocumentScannerFileProvider\",\n                photoFile\n            )\n        )\n    }\n\n    /**\n     * Once user accepts by pressing check button, or by pressing add new document button, add\n     * original photo path and 4 document corners to documents list. If user isn't allowed to\n     * adjust corners, call this automatically.\n     */\n    private fun addSelectedCornersAndOriginalPhotoPathToDocuments() {\n        // only add document it's not null (the current document photo capture, and corner\n        // detection are successful)\n        document?.let { document ->\n            // convert corners from image preview coordinates to original photo coordinates\n            // (original image is probably bigger than the preview image)\n            val cornersInOriginalImageCoordinates = imageView.corners\n                .mapPreviewToOriginalImageCoordinates(\n                    imageView.imagePreviewBounds,\n                    imageView.imagePreviewBounds.height() / document.originalPhotoHeight\n                )\n            document.corners = cornersInOriginalImageCoordinates\n            documents.add(document)\n        }\n    }\n\n    /**\n     * This gets called when a user presses the new document button. Store current photo path\n     * with document corners. Then open the camera, so user can take a photo of the next\n     * page or document\n     */\n    private fun onClickNew() {\n        addSelectedCornersAndOriginalPhotoPathToDocuments()\n        openCamera()\n    }\n\n    /**\n     * This gets called when a user presses the done button. Store current photo path with\n     * document corners. Then crop document using corners, and return cropped image paths\n     */\n    private fun onClickDone() {\n        addSelectedCornersAndOriginalPhotoPathToDocuments()\n        cropDocumentAndFinishIntent()\n    }\n\n    /**\n     * This gets called when a user presses the retake photo button. The user presses this in\n     * case the original document photo isn't good, and they need to take it again.\n     */\n    private fun onClickRetake() {\n        // we're going to retake the photo, so delete the one we just took\n        document?.let { document -> File(document.originalPhotoFilePath).delete() }\n        openCamera()\n    }\n\n    /**\n     * This gets called when a user doesn't want to complete the document scan after starting.\n     * For example a user can quit out of the camera before snapping a photo of the document.\n     */\n    private fun onClickCancel() {\n        setResult(RESULT_CANCELED)\n        finish()\n    }\n\n    /**\n     * This crops original document photo, saves cropped document photo, deletes original\n     * document photo, and returns cropped document photo file path. It repeats that for\n     * all document photos.\n     */\n    private fun cropDocumentAndFinishIntent() {\n        val croppedImageResults = arrayListOf<String>()\n        for ((pageNumber, document) in documents.withIndex()) {\n            // crop document photo by using corners\n            val croppedImage: Bitmap = try {\n                ImageUtil().crop(\n                    document.originalPhotoFilePath,\n                    document.corners\n                )\n            } catch (exception: Exception) {\n                finishIntentWithError(\"unable to crop image: ${exception.message}\")\n                return\n            }\n\n            // delete original document photo\n            File(document.originalPhotoFilePath).delete()\n\n            // save cropped document photo\n            try {\n                val croppedImageFile = FileUtil().createImageFile(this, pageNumber)\n                croppedImage.saveToFile(croppedImageFile, croppedImageQuality)\n                croppedImageResults.add(Uri.fromFile(croppedImageFile).toString())\n            } catch (exception: Exception) {\n                finishIntentWithError(\n                    \"unable to save cropped image: ${exception.message}\"\n                )\n            }\n        }\n\n        // return array of cropped document photo file paths\n        setResult(\n            RESULT_OK,\n            Intent().putExtra(\"croppedImageResults\", croppedImageResults)\n        )\n        finish()\n    }\n\n    /**\n     * This ends the document scanner activity, and returns an error message that can be\n     * used to debug error\n     *\n     * @param errorMessage an error message\n     */\n    private fun finishIntentWithError(errorMessage: String) {\n        setResult(\n            RESULT_OK,\n            Intent().putExtra(\"error\", errorMessage)\n        )\n        finish()\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/DocumentScannerFileProvider.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner\n\nimport androidx.core.content.FileProvider\n\nclass DocumentScannerFileProvider : FileProvider()"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/constants/DefaultSetting.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.constants\n\n/**\n * This class contains default document scanner options\n */\nclass DefaultSetting {\n    companion object {\n        const val CROPPED_IMAGE_QUALITY = 100\n        const val LET_USER_ADJUST_CROP = true\n        const val MAX_NUM_DOCUMENTS = 24\n        const val RESPONSE_TYPE = ResponseType.IMAGE_FILE_PATH\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/constants/DocumentScannerExtra.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.constants\n\n/**\n * This class contains constants meant to be used as intent extras\n */\nclass DocumentScannerExtra {\n    companion object {\n        const val EXTRA_CROPPED_IMAGE_QUALITY = \"croppedImageQuality\"\n        const val EXTRA_LET_USER_ADJUST_CROP = \"letUserAdjustCrop\"\n        const val EXTRA_MAX_NUM_DOCUMENTS = \"maxNumDocuments\"\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/constants/ResponseType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.constants\n\n/**\n * constants that represent all possible document scanner response formats\n */\nclass ResponseType {\n    companion object {\n        const val BASE64 = \"base64\"\n        const val IMAGE_FILE_PATH = \"imageFilePath\"\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/enums/QuadCorner.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.enums\n\n/**\n * enums for all 4 quad corners\n */\nenum class QuadCorner {\n    TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/extensions/AppCompatActivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.extensions\n\nimport android.graphics.Rect\nimport androidx.appcompat.app.AppCompatActivity\n\n@Suppress(\"DEPRECATION\")\n        /**\n         * @property screenBounds the screen bounds (used to get screen width and height)\n         */\nval AppCompatActivity.screenBounds: Rect\n    get() {\n        // currentWindowMetrics was added in Android R\n        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\n            return windowManager.currentWindowMetrics.bounds\n        }\n\n        // fall back to get screen width and height if using a version before Android R\n        return Rect(\n            0, 0, windowManager.defaultDisplay.width, windowManager.defaultDisplay.height\n        )\n    }\n\n/**\n * @property screenWidth the screen width\n */\nval AppCompatActivity.screenWidth: Int get() = screenBounds.width()\n\n/**\n * @property screenHeight the screen height\n */\nval AppCompatActivity.screenHeight: Int get() = screenBounds.height()"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/extensions/Bitmap.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.extensions\n\nimport android.graphics.Bitmap\nimport android.util.Base64\nimport java.io.ByteArrayOutputStream\nimport java.io.File\nimport java.io.FileOutputStream\nimport kotlin.math.sqrt\n\n/**\n * This converts the bitmap to base64\n *\n * @return image as a base64 string\n */\nfun Bitmap.toBase64(quality: Int): String {\n    val byteArrayOutputStream = ByteArrayOutputStream()\n    compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream)\n    return Base64.encodeToString(\n        byteArrayOutputStream.toByteArray(),\n        Base64.DEFAULT\n    )\n}\n\n/**\n * This converts the bitmap to base64\n *\n * @param file the bitmap gets saved to this file\n */\nfun Bitmap.saveToFile(file: File, quality: Int) {\n    val fileOutputStream = FileOutputStream(file)\n    compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream)\n    fileOutputStream.close()\n}\n\n/**\n * This resizes the image, so that the byte count is a little less than targetBytes\n *\n * @param targetBytes the returned bitmap has a size a little less than targetBytes\n */\nfun Bitmap.changeByteCountByResizing(targetBytes: Int): Bitmap {\n    val scale = sqrt(targetBytes.toDouble() / byteCount.toDouble())\n    return Bitmap.createScaledBitmap(\n        this,\n        (width * scale).toInt(),\n        (height * scale).toInt(),\n        true\n    )\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/extensions/Canvas.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.extensions\n\nimport android.graphics.Canvas\nimport android.graphics.Matrix\nimport android.graphics.Paint\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport android.graphics.drawable.Drawable\nimport com.websitebeaver.documentscanner.enums.QuadCorner\nimport com.websitebeaver.documentscanner.models.Line\nimport com.websitebeaver.documentscanner.models.Quad\n\n/**\n * This draws a quad (used to draw cropper). It draws 4 circles and\n * 4 connecting lines\n *\n * @param quad 4 corners\n * @param pointRadius corner circle radius\n * @param cropperLinesAndCornersStyles quad style (color, thickness for example)\n * @param cropperSelectedCornerFillStyles style for selected corner\n * @param selectedCorner selected corner\n */\nfun Canvas.drawQuad(\n    quad: Quad,\n    pointRadius: Float,\n    cropperLinesAndCornersStyles: Paint,\n    cropperSelectedCornerFillStyles: Paint,\n    selectedCorner: QuadCorner?,\n    imagePreviewBounds: RectF,\n    ratio: Float,\n    selectedCornerRadiusMagnification: Float,\n    selectedCornerBackgroundMagnification: Float,\n) {\n    // draw 4 corner points\n    for ((quadCorner: QuadCorner, cornerPoint: PointF) in quad.corners) {\n        var circleRadius = pointRadius\n\n        if (quadCorner === selectedCorner) {\n            // the cropper corner circle grows when you touch and drag it\n            circleRadius = selectedCornerRadiusMagnification * pointRadius\n            val matrix = Matrix()\n            matrix.postScale(ratio, ratio, ratio / cornerPoint.x, ratio / cornerPoint.y)\n            matrix.postTranslate(imagePreviewBounds.left, imagePreviewBounds.top)\n            matrix.postScale(\n                selectedCornerBackgroundMagnification,\n                selectedCornerBackgroundMagnification,\n                cornerPoint.x,\n                cornerPoint.y\n            )\n            cropperSelectedCornerFillStyles.shader.setLocalMatrix(matrix)\n            // fill selected corner circle with magnified image, so it's easier to crop\n            drawCircle(cornerPoint.x, cornerPoint.y, circleRadius, cropperSelectedCornerFillStyles)\n        }\n\n        // draw corner circles\n        drawCircle(\n            cornerPoint.x,\n            cornerPoint.y,\n            circleRadius,\n            cropperLinesAndCornersStyles\n        )\n    }\n\n    // draw 4 connecting lines\n    for (edge: Line in quad.edges) {\n        drawLine(edge.from.x, edge.from.y, edge.to.x, edge.to.y, cropperLinesAndCornersStyles)\n    }\n}\n\n/**\n * This draws the check icon on the finish document scan button. It's needed\n * because the inner circle covers the check icon.\n *\n * @param buttonCenterX the button center x coordinate\n * @param buttonCenterY the button center y coordinate\n * @param drawable the check icon\n */\nfun Canvas.drawCheck(buttonCenterX: Float, buttonCenterY: Float, drawable: Drawable) {\n    val mutate = drawable.constantState?.newDrawable()?.mutate()\n    mutate?.setBounds(\n        (buttonCenterX - drawable.intrinsicWidth.toFloat() / 2).toInt(),\n        (buttonCenterY - drawable.intrinsicHeight.toFloat() / 2).toInt(),\n        (buttonCenterX + drawable.intrinsicWidth.toFloat() / 2).toInt(),\n        (buttonCenterY + drawable.intrinsicHeight.toFloat() / 2).toInt()\n    )\n    mutate?.draw(this)\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/extensions/ImageButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.extensions\n\nimport android.widget.ImageButton\n\n/**\n * This function adds an on click listener to the button. It makes the button not clickable,\n * calls the on click function, and then makes the button clickable. This prevents the on click\n * function from being called while it runs.\n *\n * @param onClick the click event handler\n */\nfun ImageButton.onClick(onClick: () -> Unit) {\n    setOnClickListener {\n        isClickable = false\n        onClick()\n        isClickable = true\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/extensions/Point.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.extensions\n\nimport android.graphics.PointF\nimport org.opencv.core.Point\nimport kotlin.math.pow\nimport kotlin.math.sqrt\n\n/**\n * converts an OpenCV point to Android point\n *\n * @return Android point\n */\nfun Point.toPointF(): PointF {\n    return PointF(x.toFloat(), y.toFloat())\n}\n\n/**\n * calculates the distance between 2 OpenCV points\n *\n * @param point the 2nd OpenCV point\n * @return the distance between this point and the 2nd point\n */\nfun Point.distance(point: Point): Double {\n    return sqrt((point.x - x).pow(2) + (point.y - y).pow(2))\n}\n\n/**\n * offset the OpenCV point by (dx, dy)\n *\n * @param dx horizontal offset\n * @param dy vertical offset\n * @return the OpenCV point after moving it (dx, dy)\n */\nfun Point.move(dx: Double, dy: Double): Point {\n    return Point(x + dx, y + dy)\n}\n\n/**\n * converts an Android point to OpenCV point\n *\n * @return OpenCV point\n */\nfun PointF.toOpenCVPoint(): Point {\n    return Point(x.toDouble(), y.toDouble())\n}\n\n/**\n * multiply an Android point by magnitude\n *\n * @return Android point after multiplying by magnitude\n */\nfun PointF.multiply(magnitude: Float): PointF {\n    return PointF(magnitude * x, magnitude * y)\n}\n\n/**\n * offset the Android point by (dx, dy)\n *\n * @param dx horizontal offset\n * @param dy vertical offset\n * @return the Android point after moving it (dx, dy)\n */\nfun PointF.move(dx: Float, dy: Float): PointF {\n    return PointF(x + dx, y + dy)\n}\n\n/**\n * calculates the distance between 2 Android points\n *\n * @param point the 2nd Android point\n * @return the distance between this point and the 2nd point\n */\nfun PointF.distance(point: PointF): Float {\n    return sqrt((point.x - x).pow(2) + (point.y - y).pow(2))\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/models/Document.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.models\n\n/**\n * This class contains the original document photo, and a cropper. The user can drag the corners\n * to make adjustments to the detected corners.\n *\n * @param originalPhotoFilePath the photo file path before cropping\n * @param originalPhotoWidth the original photo width\n * @param originalPhotoHeight the original photo height\n * @param corners the document's 4 corner points\n * @constructor creates a document\n */\nclass Document(\n    val originalPhotoFilePath: String,\n    private val originalPhotoWidth: Int,\n    val originalPhotoHeight: Int,\n    var corners: Quad\n)"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/models/Line.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.models\n\nimport android.graphics.PointF\n\n/**\n * represents a line connecting 2 Android points\n *\n * @param fromPoint the 1st point\n * @param toPoint the 2nd point\n * @constructor creates a line connecting 2 points\n */\nclass Line(fromPoint: PointF, toPoint: PointF) {\n    val from: PointF = fromPoint\n    val to: PointF = toPoint\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/models/Quad.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.models\n\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport com.websitebeaver.documentscanner.enums.QuadCorner\nimport com.websitebeaver.documentscanner.extensions.distance\nimport com.websitebeaver.documentscanner.extensions.move\nimport com.websitebeaver.documentscanner.extensions.multiply\nimport com.websitebeaver.documentscanner.extensions.toPointF\nimport org.opencv.core.Point\n\n/**\n * This class is used to represent the cropper. It contains 4 corners.\n *\n * @param topLeftCorner the top left corner\n * @param topRightCorner the top right corner\n * @param bottomRightCorner the bottom right corner\n * @param bottomLeftCorner the bottom left corner\n * @constructor creates a quad from Android points\n */\nclass Quad(\n    val topLeftCorner: PointF,\n    val topRightCorner: PointF,\n    val bottomRightCorner: PointF,\n    val bottomLeftCorner: PointF\n) {\n    /**\n     * @constructor creates a quad from OpenCV points\n     */\n    constructor(\n        topLeftCorner: Point,\n        topRightCorner: Point,\n        bottomRightCorner: Point,\n        bottomLeftCorner: Point\n    ) : this(\n        topLeftCorner.toPointF(),\n        topRightCorner.toPointF(),\n        bottomRightCorner.toPointF(),\n        bottomLeftCorner.toPointF()\n    )\n\n    /**\n     * @property corners lets us get the point coordinates for any corner\n     */\n    var corners: MutableMap<QuadCorner, PointF> = mutableMapOf(\n        QuadCorner.TOP_LEFT to topLeftCorner,\n        QuadCorner.TOP_RIGHT to topRightCorner,\n        QuadCorner.BOTTOM_RIGHT to bottomRightCorner,\n        QuadCorner.BOTTOM_LEFT to bottomLeftCorner\n    )\n\n    /**\n     * @property edges 4 lines that connect the 4 corners\n     */\n    val edges: Array<Line>\n        get() = arrayOf(\n            Line(topLeftCorner, topRightCorner),\n            Line(topRightCorner, bottomRightCorner),\n            Line(bottomRightCorner, bottomLeftCorner),\n            Line(bottomLeftCorner, topLeftCorner)\n        )\n\n    /**\n     * This finds the corner that's closest to a point. When a user touches to drag\n     * the cropper, that point is used to determine which corner to move.\n     *\n     * @param point we want to find the corner closest to this point\n     * @return the closest corner\n     */\n    fun getCornerClosestToPoint(point: PointF): QuadCorner {\n        return corners.minByOrNull { corner -> corner.value.distance(point) }?.key!!\n    }\n\n    /**\n     * This moves a corner by (dx, dy)\n     *\n     * @param corner the corner that needs to be moved\n     * @param dx the corner moves dx horizontally\n     * @param dy the corner moves dy vertically\n     */\n    fun moveCorner(corner: QuadCorner, dx: Float, dy: Float) {\n        corners[corner]?.offset(dx, dy)\n    }\n\n    /**\n     * This maps original image coordinates to preview image coordinates. The original image\n     * is probably larger than the preview image.\n     *\n     * @param imagePreviewBounds offset the point by the top left of imagePreviewBounds\n     * @param ratio multiply the point by ratio\n     * @return the 4 corners after mapping coordinates\n     */\n    fun mapOriginalToPreviewImageCoordinates(imagePreviewBounds: RectF, ratio: Float): Quad {\n        return Quad(\n            topLeftCorner.multiply(ratio).move(\n                imagePreviewBounds.left,\n                imagePreviewBounds.top\n            ),\n            topRightCorner.multiply(ratio).move(\n                imagePreviewBounds.left,\n                imagePreviewBounds.top\n            ),\n            bottomRightCorner.multiply(ratio).move(\n                imagePreviewBounds.left,\n                imagePreviewBounds.top\n            ),\n            bottomLeftCorner.multiply(ratio).move(\n                imagePreviewBounds.left,\n                imagePreviewBounds.top\n            )\n        )\n    }\n\n    /**\n     * This maps preview image coordinates to original image coordinates. The original image\n     * is probably larger than the preview image.\n     *\n     * @param imagePreviewBounds reverse offset the point by the top left of imagePreviewBounds\n     * @param ratio divide the point by ratio\n     * @return the 4 corners after mapping coordinates\n     */\n    fun mapPreviewToOriginalImageCoordinates(imagePreviewBounds: RectF, ratio: Float): Quad {\n        return Quad(\n            topLeftCorner.move(\n                -imagePreviewBounds.left,\n                -imagePreviewBounds.top\n            ).multiply(1 / ratio),\n            topRightCorner.move(\n                -imagePreviewBounds.left,\n                -imagePreviewBounds.top\n            ).multiply(1 / ratio),\n            bottomRightCorner.move(\n                -imagePreviewBounds.left,\n                -imagePreviewBounds.top\n            ).multiply(1 / ratio),\n            bottomLeftCorner.move(\n                -imagePreviewBounds.left,\n                -imagePreviewBounds.top\n            ).multiply(1 / ratio)\n        )\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/ui/CircleButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.ui\n\nimport android.content.Context\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.graphics.Paint\nimport android.util.AttributeSet\nimport androidx.appcompat.widget.AppCompatImageButton\nimport com.websitebeaver.documentscanner.R\n\n/**\n * This class creates a circular done button by modifying an image button. This is used for the\n * add new document button and retake photo button.\n *\n * @param context image button context\n * @param attrs image button attributes\n * @constructor creates circle button\n */\nclass CircleButton(\n    context: Context,\n    attrs: AttributeSet\n) : AppCompatImageButton(context, attrs) {\n    /**\n     * @property ring the button's outer ring\n     */\n    private val ring = Paint(Paint.ANTI_ALIAS_FLAG)\n\n    init {\n        // set outer ring style\n        ring.color = Color.WHITE\n        ring.style = Paint.Style.STROKE\n        ring.strokeWidth = resources.getDimension(R.dimen.small_button_ring_thickness)\n    }\n\n    /**\n     * This gets called repeatedly. We use it to draw the button\n     *\n     * @param canvas the image button canvas\n     */\n    override fun onDraw(canvas: Canvas) {\n        super.onDraw(canvas)\n\n        // draw outer ring\n        canvas.drawCircle(\n            (width / 2).toFloat(),\n            (height / 2).toFloat(),\n            (width.toFloat() - ring.strokeWidth) / 2,\n            ring\n        )\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/ui/DoneButton.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.ui\n\nimport android.content.Context\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.graphics.Paint\nimport android.util.AttributeSet\nimport androidx.appcompat.widget.AppCompatImageButton\nimport androidx.core.content.ContextCompat\nimport com.websitebeaver.documentscanner.R\nimport com.websitebeaver.documentscanner.extensions.drawCheck\n\n/**\n * This class creates a circular done button by modifying an image button. The user presses\n * this button once they finish cropping an image\n *\n * @param context image button context\n * @param attrs image button attributes\n * @constructor creates done button\n */\nclass DoneButton(\n    context: Context,\n    attrs: AttributeSet\n) : AppCompatImageButton(context, attrs) {\n    /**\n     * @property ring the button's outer ring\n     */\n    private val ring = Paint(Paint.ANTI_ALIAS_FLAG)\n\n    /**\n     * @property circle the button's inner circle\n     */\n    private val circle = Paint(Paint.ANTI_ALIAS_FLAG)\n\n    init {\n        // set outer ring style\n        ring.color = Color.WHITE\n        ring.style = Paint.Style.STROKE\n        ring.strokeWidth = resources.getDimension(R.dimen.large_button_ring_thickness)\n\n        // set inner circle style\n        circle.color = ContextCompat.getColor(context, R.color.done_button_inner_circle_color)\n        circle.style = Paint.Style.FILL\n    }\n\n    /**\n     * This gets called repeatedly. We use it to draw the done button.\n     *\n     * @param canvas the image button canvas\n     */\n    override fun onDraw(canvas: Canvas) {\n        super.onDraw(canvas)\n\n        // calculate button center point, outer ring radius, and inner circle radius\n        val centerX = width.toFloat() / 2\n        val centerY = height.toFloat() / 2\n        val outerRadius = (width.toFloat() - ring.strokeWidth) / 2\n        val innerRadius = outerRadius - resources.getDimension(\n            R.dimen.large_button_outer_ring_offset\n        )\n\n        // draw outer ring\n        canvas.drawCircle(centerX, centerY, outerRadius, ring)\n\n        // draw inner circle\n        canvas.drawCircle(centerX, centerY, innerRadius, circle)\n\n        // draw check icon since it gets covered by inner circle\n        canvas.drawCheck(centerX, centerY, drawable)\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/ui/ImageCropView.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.ui\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.BitmapShader\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.graphics.Paint\nimport android.graphics.PointF\nimport android.graphics.RectF\nimport android.graphics.Shader\nimport android.util.AttributeSet\nimport android.view.MotionEvent\nimport androidx.appcompat.widget.AppCompatImageView\nimport androidx.core.graphics.drawable.toBitmap\nimport com.websitebeaver.documentscanner.R\nimport com.websitebeaver.documentscanner.enums.QuadCorner\nimport com.websitebeaver.documentscanner.extensions.changeByteCountByResizing\nimport com.websitebeaver.documentscanner.extensions.drawQuad\nimport com.websitebeaver.documentscanner.models.Quad\n\n/**\n * This class contains the original document photo, and a cropper. The user can drag the corners\n * to make adjustments to the detected corners.\n *\n * @param context view context\n * @param attrs view attributes\n * @constructor creates image crop view\n */\nclass ImageCropView(context: Context, attrs: AttributeSet) : AppCompatImageView(context, attrs) {\n\n    /**\n     * @property quad the 4 document corners\n     */\n    private var quad: Quad? = null\n\n    /**\n     * @property prevTouchPoint keep track of where the user touches, so we know how much\n     * to move corners on drag\n     */\n    private var prevTouchPoint: PointF? = null\n\n    /**\n     * @property closestCornerToTouch if the user touches close to the top left corner for\n     * example, that corner should move on drag\n     */\n    private var closestCornerToTouch: QuadCorner? = null\n\n    /**\n     * @property cropperLinesAndCornersStyles paint style for 4 corners and connecting lines\n     */\n    private val cropperLinesAndCornersStyles = Paint(Paint.ANTI_ALIAS_FLAG)\n\n    /**\n     * @property cropperSelectedCornerFillStyles when you tap and drag a cropper corner the circle\n     * acts like a magnifying glass\n     */\n    private val cropperSelectedCornerFillStyles = Paint()\n\n    /**\n     * @property imagePreviewHeight this is needed because height doesn't update immediately\n     * after we set the image\n     */\n    private var imagePreviewHeight = height\n\n    /**\n     * @property imagePreviewWidth this is needed because width doesn't update immediately\n     * after we set the image\n     */\n    private var imagePreviewWidth = width\n\n    /**\n     * @property ratio image container height to image height ratio used to map container\n     * to image coordinates and vice versa\n     */\n    private val ratio: Float get() = imagePreviewBounds.height() / drawable.intrinsicHeight\n\n    /**\n     * @property corners document corners in image preview coordinates\n     */\n    val corners: Quad get() = quad!!\n\n    /**\n     * @property imagePreviewMaxSizeInBytes if the photo is too big, we need to scale it down\n     * before we display it\n     */\n    private val imagePreviewMaxSizeInBytes = 100 * 1024 * 1024\n\n    init {\n        // set cropper style\n        cropperLinesAndCornersStyles.color = Color.WHITE\n        cropperLinesAndCornersStyles.style = Paint.Style.STROKE\n        cropperLinesAndCornersStyles.strokeWidth = 3f\n    }\n\n    /**\n     * Initially the image preview height is 0. This calculates the height by using the photo\n     * dimensions. It maintains the photo aspect ratio (we likely need to scale the photo down\n     * to fit the preview container).\n     *\n     * @param photo the original photo with a rectangular document\n     * @param screenWidth the device width\n     */\n    fun setImagePreviewBounds(photo: Bitmap, screenWidth: Int, screenHeight: Int) {\n        // image width to height aspect ratio\n        val imageRatio = photo.width.toFloat() / photo.height.toFloat()\n        val buttonsViewMinHeight = context.resources.getDimension(\n            R.dimen.buttons_container_min_height\n        ).toInt()\n\n        imagePreviewHeight = if (photo.height > photo.width) {\n            // if user takes the photo in portrait\n            (screenWidth.toFloat() / imageRatio).toInt()\n        } else {\n            // if user takes the photo in landscape\n            (screenWidth.toFloat() * imageRatio).toInt()\n        }\n\n        // set a cap on imagePreviewHeight, so that the bottom buttons container isn't hidden\n        imagePreviewHeight = Integer.min(\n            imagePreviewHeight,\n            screenHeight - buttonsViewMinHeight\n        )\n\n        imagePreviewWidth = screenWidth\n\n        // image container initially has a 0 width and 0 height, calculate both and set them\n        layoutParams.height = imagePreviewHeight\n        layoutParams.width = imagePreviewWidth\n\n        // refresh layout after we change height\n        requestLayout()\n    }\n\n    /**\n     * Insert bitmap in image view, and trigger onSetImage event handler\n     */\n    fun setImage(photo: Bitmap) {\n        var previewImagePhoto = photo\n        // if the image is too large, we need to scale it down before displaying it\n        if (photo.byteCount > imagePreviewMaxSizeInBytes) {\n            previewImagePhoto = photo.changeByteCountByResizing(imagePreviewMaxSizeInBytes)\n        }\n        this.setImageBitmap(previewImagePhoto)\n        this.onSetImage()\n    }\n\n    /**\n     * Once the user takes a photo, we try to detect corners. This function stores them as quad.\n     *\n     * @param cropperCorners 4 corner points in original photo coordinates\n     */\n    fun setCropper(cropperCorners: Quad) {\n        quad = cropperCorners\n    }\n\n    /**\n     * @property imagePreviewBounds image coordinates - if the image ratio is different than\n     * the image container ratio then there's blank space either at the top and bottom of the\n     * image or the left and right of the image\n     */\n    val imagePreviewBounds: RectF\n        get() {\n            // image container width to height ratio\n            val imageViewRatio: Float = imagePreviewWidth.toFloat() / imagePreviewHeight.toFloat()\n\n            // image width to height ratio\n            val imageRatio = drawable.intrinsicWidth.toFloat() / drawable.intrinsicHeight.toFloat()\n\n            var left = 0f\n            var top = 0f\n            var right = imagePreviewWidth.toFloat()\n            var bottom = imagePreviewHeight.toFloat()\n\n            if (imageRatio > imageViewRatio) {\n                // if the image is really wide, there's blank space at the top and bottom\n                val offset = (imagePreviewHeight - (imagePreviewWidth / imageRatio)) / 2\n                top += offset\n                bottom -= offset\n            } else {\n                // if the image is really tall, there's blank space at the left and right\n                // it's also possible that the image ratio matches the image container ratio\n                // in which case there's no blank space\n                val offset = (imagePreviewWidth - (imagePreviewHeight * imageRatio)) / 2\n                left += offset\n                right -= offset\n            }\n\n            return RectF(left, top, right, bottom)\n        }\n\n    /**\n     * This ensures that the user doesn't drag a corner outside the image\n     *\n     * @param point a point\n     * @return true if the point is inside the image preview container, false it's not\n     */\n    private fun isPointInsideImage(point: PointF): Boolean {\n        return (point.x >= imagePreviewBounds.left\n                && point.y >= imagePreviewBounds.top\n                && point.x <= imagePreviewBounds.right\n                && point.y <= imagePreviewBounds.bottom)\n    }\n\n    /**\n     * This gets called once we insert an image in this image view\n     */\n    private fun onSetImage() {\n        cropperSelectedCornerFillStyles.style = Paint.Style.FILL\n        cropperSelectedCornerFillStyles.shader = BitmapShader(\n            drawable.toBitmap(),\n            Shader.TileMode.CLAMP,\n            Shader.TileMode.CLAMP\n        )\n    }\n\n    /**\n     * This gets called constantly, and we use it to update the cropper corners\n     *\n     * @param canvas the image preview canvas\n     */\n    override fun onDraw(canvas: Canvas) {\n        super.onDraw(canvas)\n\n        if (quad !== null) {\n            // draw 4 corners and connecting lines\n            canvas.drawQuad(\n                quad!!,\n                resources.getDimension(R.dimen.cropper_corner_radius),\n                cropperLinesAndCornersStyles,\n                cropperSelectedCornerFillStyles,\n                closestCornerToTouch,\n                imagePreviewBounds,\n                ratio,\n                resources.getDimension(R.dimen.cropper_selected_corner_radius_magnification),\n                resources.getDimension(R.dimen.cropper_selected_corner_background_magnification)\n            )\n        }\n\n    }\n\n    /**\n     * This gets called when the user touches, drags, and stops touching screen. We use this\n     * to figure out which corner we need to move, and how far we need to move it.\n     *\n     * @param event the touch event\n     */\n    @SuppressLint(\"ClickableViewAccessibility\")\n    override fun onTouchEvent(event: MotionEvent): Boolean {\n        // keep track of the touched point\n        val touchPoint = PointF(event.x, event.y)\n\n        when (event.action) {\n            MotionEvent.ACTION_DOWN -> {\n                // when the user touches the screen record the point, and find the closest\n                // corner to the touch point\n                prevTouchPoint = touchPoint\n                closestCornerToTouch = quad!!.getCornerClosestToPoint(touchPoint)\n            }\n\n            MotionEvent.ACTION_UP -> {\n                // when the user stops touching the screen reset these values\n                prevTouchPoint = null\n                closestCornerToTouch = null\n            }\n\n            MotionEvent.ACTION_MOVE -> {\n                // when the user drags their finger, update the closest corner position\n                val touchMoveXDistance = touchPoint.x - prevTouchPoint!!.x\n                val touchMoveYDistance = touchPoint.y - prevTouchPoint!!.y\n                val cornerNewPosition = PointF(\n                    quad!!.corners[closestCornerToTouch]!!.x + touchMoveXDistance,\n                    quad!!.corners[closestCornerToTouch]!!.y + touchMoveYDistance\n                )\n\n                // make sure the user doesn't drag the corner outside the image preview container\n                if (isPointInsideImage(cornerNewPosition)) {\n                    quad!!.moveCorner(\n                        closestCornerToTouch!!,\n                        touchMoveXDistance,\n                        touchMoveYDistance\n                    )\n                }\n\n                // record the point touched, so we can use it to calculate how far to move corner\n                // next time the user drags (assuming they don't stop touching the screen)\n                prevTouchPoint = touchPoint\n            }\n        }\n\n        // force refresh view\n        invalidate()\n\n        return true\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/utils/FileUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.utils\n\nimport androidx.activity.ComponentActivity\nimport java.io.File\nimport java.io.IOException\nimport java.text.SimpleDateFormat\nimport java.util.Date\nimport java.util.Locale\n\n/**\n * This class contains a helper function creating temporary files\n *\n * @constructor creates file util\n */\nclass FileUtil {\n    /**\n     * create a temporary file\n     *\n     * @param activity the current activity\n     * @param pageNumber the current document page number\n     */\n    @Throws(IOException::class)\n    fun createImageFile(activity: ComponentActivity, pageNumber: Int): File {\n        // use current time to make file name more unique\n        val dateTime: String = SimpleDateFormat(\n            \"yyyyMMdd_HHmmss\",\n            Locale.US\n        ).format(Date())\n\n        return File.createTempFile(\n            \"DOCUMENT_SCAN_${pageNumber}_${dateTime}\",\n            \".jpg\",\n            activity.cacheDir\n        )\n    }\n}\n"
  },
  {
    "path": "lib/documentscanner/src/main/java/com/websitebeaver/documentscanner/utils/ImageUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.websitebeaver.documentscanner.utils\n\nimport android.content.ContentResolver\nimport android.graphics.Bitmap\nimport android.graphics.BitmapFactory\nimport android.graphics.Matrix\nimport androidx.core.graphics.createBitmap\nimport androidx.core.net.toUri\nimport com.t8rin.exif.ExifInterface\nimport com.websitebeaver.documentscanner.extensions.distance\nimport com.websitebeaver.documentscanner.extensions.toOpenCVPoint\nimport com.websitebeaver.documentscanner.models.Quad\nimport org.opencv.android.Utils\nimport org.opencv.core.Mat\nimport org.opencv.core.MatOfPoint2f\nimport org.opencv.core.Point\nimport org.opencv.core.Size\nimport org.opencv.imgcodecs.Imgcodecs\nimport org.opencv.imgproc.Imgproc\nimport java.io.File\nimport kotlin.math.min\n\n/**\n * This class contains helper functions for processing images\n *\n * @constructor creates image util\n */\nclass ImageUtil {\n    /**\n     * get image matrix from file path\n     *\n     * @param filePath image is saved here\n     * @return image matrix\n     */\n    private fun getImageMatrixFromFilePath(filePath: String): Mat {\n        // read image as matrix using OpenCV\n        val image: Mat = Imgcodecs.imread(filePath)\n\n        // if OpenCV fails to read the image then it's empty\n        if (!image.empty()) {\n            // convert image to RGB color space since OpenCV reads it using BGR color space\n            Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2RGB)\n            return image\n        }\n\n        if (!File(filePath).exists()) {\n            throw Exception(\"File doesn't exist - $filePath\")\n        }\n\n        if (!File(filePath).canRead()) {\n            throw Exception(\"You don't have permission to read $filePath\")\n        }\n\n        // try reading image without OpenCV\n        var imageBitmap = BitmapFactory.decodeFile(filePath)\n        val rotation = when (ExifInterface(filePath).getAttributeInt(\n            ExifInterface.TAG_ORIENTATION,\n            ExifInterface.ORIENTATION_NORMAL\n        )) {\n            ExifInterface.ORIENTATION_ROTATE_90 -> 90\n            ExifInterface.ORIENTATION_ROTATE_180 -> 180\n            ExifInterface.ORIENTATION_ROTATE_270 -> 270\n            else -> 0\n        }\n        imageBitmap = Bitmap.createBitmap(\n            imageBitmap,\n            0,\n            0,\n            imageBitmap.width,\n            imageBitmap.height,\n            Matrix().apply { postRotate(rotation.toFloat()) },\n            true\n        )\n        Utils.bitmapToMat(imageBitmap, image)\n\n        return image\n    }\n\n    /**\n     * get bitmap image from file path\n     *\n     * @param filePath image is saved here\n     * @return image bitmap\n     */\n    fun getImageFromFilePath(filePath: String): Bitmap {\n        // read image as matrix using OpenCV\n        val image: Mat = this.getImageMatrixFromFilePath(filePath)\n\n        // convert image matrix to bitmap\n        val bitmap = createBitmap(image.cols(), image.rows())\n        Utils.matToBitmap(image, bitmap)\n        return bitmap\n    }\n\n    /**\n     * take a photo with a document, crop everything out but document, and force it to display\n     * as a rectangle\n     *\n     * @param photoFilePath original image is saved here\n     * @param corners the 4 document corners\n     * @return bitmap with cropped and warped document\n     */\n    fun crop(photoFilePath: String, corners: Quad): Bitmap {\n        // read image with OpenCV\n        val image = this.getImageMatrixFromFilePath(photoFilePath)\n\n        // convert top left, top right, bottom right, and bottom left document corners from\n        // Android points to OpenCV points\n        val tLC = corners.topLeftCorner.toOpenCVPoint()\n        val tRC = corners.topRightCorner.toOpenCVPoint()\n        val bRC = corners.bottomRightCorner.toOpenCVPoint()\n        val bLC = corners.bottomLeftCorner.toOpenCVPoint()\n\n        // Calculate the document edge distances. The user might take a skewed photo of the\n        // document, so the top left corner to top right corner distance might not be the same\n        // as the bottom left to bottom right corner. We could take an average of the 2, but\n        // this takes the smaller of the 2. It does the same for height.\n        val width = min(tLC.distance(tRC), bLC.distance(bRC))\n        val height = min(tLC.distance(bLC), tRC.distance(bRC))\n\n        // create empty image matrix with cropped and warped document width and height\n        val croppedImage = MatOfPoint2f(\n            Point(0.0, 0.0),\n            Point(width, 0.0),\n            Point(width, height),\n            Point(0.0, height),\n        )\n\n        // This crops the document out of the rest of the photo. Since the user might take a\n        // skewed photo instead of a straight on photo, the document might be rotated and\n        // skewed. This corrects that problem. output is an image matrix that contains the\n        // corrected image after this fix.\n        val output = Mat()\n        Imgproc.warpPerspective(\n            image,\n            output,\n            Imgproc.getPerspectiveTransform(\n                MatOfPoint2f(tLC, tRC, bRC, bLC),\n                croppedImage\n            ),\n            Size(width, height)\n        )\n\n        // convert output image matrix to bitmap\n        val croppedBitmap = createBitmap(output.cols(), output.rows())\n        Utils.matToBitmap(output, croppedBitmap)\n\n        return croppedBitmap\n    }\n\n    /**\n     * get bitmap image from file uri\n     *\n     * @param fileUriString image is saved here and starts with file:///\n     * @return bitmap image\n     */\n    fun readBitmapFromFileUriString(\n        fileUriString: String,\n        contentResolver: ContentResolver\n    ): Bitmap {\n        return BitmapFactory.decodeStream(\n            contentResolver.openInputStream(fileUriString.toUri())\n        )\n    }\n}"
  },
  {
    "path": "lib/documentscanner/src/main/res/animator/button_grow_animation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_pressed=\"true\">\n        <set>\n            <objectAnimator\n                android:duration=\"@integer/button_grow_animation_duration\"\n                android:propertyName=\"scaleX\"\n                android:valueTo=\"@dimen/grown_button_zoom\"\n                android:valueType=\"floatType\" />\n            <objectAnimator\n                android:duration=\"@integer/button_grow_animation_duration\"\n                android:propertyName=\"scaleY\"\n                android:valueTo=\"@dimen/grown_button_zoom\"\n                android:valueType=\"floatType\" />\n            <objectAnimator\n                android:duration=\"@integer/button_grow_animation_duration\"\n                android:propertyName=\"elevation\"\n                android:valueTo=\"@dimen/grown_button_elevation\"\n                android:valueType=\"floatType\" />\n        </set>\n    </item>\n    <item android:state_pressed=\"false\">\n        <set>\n            <objectAnimator\n                android:duration=\"@integer/button_shrink_animation_duration\"\n                android:propertyName=\"scaleX\"\n                android:valueTo=\"@dimen/button_zoom\"\n                android:valueType=\"floatType\" />\n            <objectAnimator\n                android:duration=\"@integer/button_shrink_animation_duration\"\n                android:propertyName=\"scaleY\"\n                android:valueTo=\"@dimen/button_zoom\"\n                android:valueType=\"floatType\" />\n            <objectAnimator\n                android:duration=\"@integer/button_shrink_animation_duration\"\n                android:propertyName=\"elevation\"\n                android:valueTo=\"@dimen/button_elevation\"\n                android:valueType=\"floatType\" />\n        </set>\n    </item>\n</selector>"
  },
  {
    "path": "lib/documentscanner/src/main/res/drawable/ic_baseline_add_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />\n</vector>"
  },
  {
    "path": "lib/documentscanner/src/main/res/drawable/ic_baseline_arrow_back_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:autoMirrored=\"true\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z\" />\n</vector>"
  },
  {
    "path": "lib/documentscanner/src/main/res/drawable/ic_baseline_check_24.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z\" />\n</vector>"
  },
  {
    "path": "lib/documentscanner/src/main/res/layout/activity_image_crop.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@color/black\"\n    android:paddingVertical=\"@dimen/image_crop_view_vertical_padding\"\n    tools:context=\".DocumentScannerActivity\">\n\n    <com.websitebeaver.documentscanner.ui.ImageCropView\n        android:id=\"@+id/image_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/image_crop_view_initial_height\"\n        android:contentDescription=\"@string/image_with_cropper\" />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@+id/image_view\"\n        android:layout_alignParentBottom=\"true\"\n        android:baselineAligned=\"false\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\"\n        android:paddingHorizontal=\"@dimen/buttons_container_horizontal_padding\"\n        android:paddingBottom=\"@dimen/buttons_container_bottom_padding\">\n\n        <FrameLayout\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\">\n\n            <com.websitebeaver.documentscanner.ui.CircleButton\n                android:id=\"@+id/retake_photo_button\"\n                android:layout_width=\"@dimen/small_button_diameter\"\n                android:layout_height=\"@dimen/small_button_diameter\"\n                android:layout_gravity=\"center\"\n                android:background=\"@android:color/transparent\"\n                android:src=\"@drawable/ic_baseline_arrow_back_24\"\n                android:stateListAnimator=\"@animator/button_grow_animation\" />\n\n        </FrameLayout>\n\n        <FrameLayout\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\">\n\n            <com.websitebeaver.documentscanner.ui.DoneButton\n                android:id=\"@+id/complete_document_scan_button\"\n                android:layout_width=\"@dimen/large_button_diameter\"\n                android:layout_height=\"@dimen/large_button_diameter\"\n                android:layout_gravity=\"center\"\n                android:background=\"@android:color/transparent\"\n                android:src=\"@drawable/ic_baseline_check_24\"\n                android:stateListAnimator=\"@animator/button_grow_animation\" />\n\n        </FrameLayout>\n\n        <FrameLayout\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\">\n\n            <com.websitebeaver.documentscanner.ui.CircleButton\n                android:id=\"@+id/new_photo_button\"\n                android:layout_width=\"@dimen/small_button_diameter\"\n                android:layout_height=\"@dimen/small_button_diameter\"\n                android:layout_gravity=\"center\"\n                android:background=\"@android:color/transparent\"\n                android:src=\"@drawable/ic_baseline_add_24\"\n                android:stateListAnimator=\"@animator/button_grow_animation\" />\n\n        </FrameLayout>\n\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "lib/documentscanner/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <color name=\"black\">#000000</color>\n    <color name=\"done_button_inner_circle_color\">#D0E4FF</color>\n</resources>"
  },
  {
    "path": "lib/documentscanner/src/main/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <dimen name=\"button_elevation\">0dp</dimen>\n    <dimen name=\"button_zoom\">1</dimen>\n    <dimen name=\"buttons_container_bottom_padding\">0.1dp</dimen>\n    <dimen name=\"buttons_container_horizontal_padding\">5dp</dimen>\n    <dimen name=\"buttons_container_min_height\">200dp</dimen>\n    <dimen name=\"cropper_corner_radius\">25px</dimen>\n    <dimen name=\"cropper_selected_corner_radius_magnification\">4px</dimen>\n    <dimen name=\"cropper_selected_corner_background_magnification\">5px</dimen>\n    <dimen name=\"grown_button_elevation\">1dp</dimen>\n    <dimen name=\"grown_button_zoom\">1.07</dimen>\n    <dimen name=\"image_crop_view_initial_height\">0dp</dimen>\n    <dimen name=\"image_crop_view_vertical_padding\">15.4dp</dimen>\n    <dimen name=\"large_button_diameter\">75dp</dimen>\n    <dimen name=\"large_button_ring_thickness\">2.91dp</dimen>\n    <dimen name=\"large_button_outer_ring_offset\">8dp</dimen>\n    <dimen name=\"small_button_diameter\">54.5dp</dimen>\n    <dimen name=\"small_button_ring_thickness\">2dp</dimen>\n</resources>"
  },
  {
    "path": "lib/documentscanner/src/main/res/values/integers.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <integer name=\"button_grow_animation_duration\">100</integer>\n    <integer name=\"button_shrink_animation_duration\">150</integer>\n</resources>"
  },
  {
    "path": "lib/documentscanner/src/main/res/values/strings.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n    <string name=\"image_with_cropper\">Original Image With Cropper</string>\n</resources>"
  },
  {
    "path": "lib/documentscanner/src/main/res/values/themes.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<resources>\n\n    <style name=\"Theme.FullScreen\" parent=\"@style/Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"android:windowFullscreen\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n        <item name=\"android:layout_width\">fill_parent</item>\n        <item name=\"android:layout_height\">fill_parent</item>\n    </style>\n</resources>"
  },
  {
    "path": "lib/documentscanner/src/main/res/xml/file_paths.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<paths>\n    <external-files-path\n        name=\"images\"\n        path=\"Pictures\" />\n</paths>"
  },
  {
    "path": "lib/dynamic-theme/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/dynamic-theme/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.dynamic.theme\"\n\n\ndependencies {\n    implementation(libs.androidx.palette.ktx)\n    implementation(libs.materialKolor)\n}"
  },
  {
    "path": "lib/dynamic-theme/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n</manifest>\n"
  },
  {
    "path": "lib/dynamic-theme/src/main/java/com/t8rin/dynamic/theme/ColorBlindUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.dynamic.theme\n\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.ui.graphics.Color\n\nfun Color.toColorBlind(type: ColorBlindType): Color {\n    val (r, g, b) = listOf(this.red, this.green, this.blue)\n    val newColor = when (type) {\n        ColorBlindType.Protanomaly -> {\n            val matrix = listOf(\n                0.817, 0.183, 0.0,\n                0.333, 0.667, 0.0,\n                0.0, 0.125, 0.875\n            )\n            transformColor(r, g, b, matrix)\n        }\n\n        ColorBlindType.Deuteranomaly -> {\n            val matrix = listOf(\n                0.8, 0.2, 0.0,\n                0.258, 0.742, 0.0,\n                0.0, 0.142, 0.858\n            )\n            transformColor(r, g, b, matrix)\n        }\n\n        ColorBlindType.Tritanomaly -> {\n            val matrix = listOf(\n                0.967, 0.033, 0.0,\n                0.0, 0.733, 0.267,\n                0.0, 0.183, 0.817\n            )\n            transformColor(r, g, b, matrix)\n        }\n\n        ColorBlindType.Protanopia -> {\n            val matrix = listOf(\n                0.567, 0.433, 0.0,\n                0.558, 0.442, 0.0,\n                0.0, 0.242, 0.758\n            )\n            transformColor(r, g, b, matrix)\n        }\n\n        ColorBlindType.Deuteranopia -> {\n            val matrix = listOf(\n                0.625, 0.375, 0.0,\n                0.7, 0.3, 0.0,\n                0.0, 0.3, 0.7\n            )\n            transformColor(r, g, b, matrix)\n        }\n\n        ColorBlindType.Tritanopia -> {\n            val matrix = listOf(\n                0.95, 0.05, 0.0,\n                0.0, 0.433, 0.567,\n                0.0, 0.475, 0.525\n            )\n            transformColor(r, g, b, matrix)\n        }\n\n        ColorBlindType.Achromatomaly -> {\n            val matrix = listOf(\n                0.618, 0.320, 0.062,\n                0.163, 0.775, 0.062,\n                0.163, 0.320, 0.516\n            )\n            transformColor(r, g, b, matrix)\n        }\n\n        ColorBlindType.Achromatopsia -> {\n            val matrix = listOf(\n                0.299, 0.587, 0.114,\n                0.299, 0.587, 0.114,\n                0.299, 0.587, 0.114\n            )\n            transformColor(r, g, b, matrix)\n        }\n    }\n    return Color(newColor[0], newColor[1], newColor[2], this.alpha)\n}\n\nprivate fun transformColor(r: Float, g: Float, b: Float, matrix: List<Double>): List<Float> {\n    val newR = (matrix[0] * r + matrix[1] * g + matrix[2] * b).toFloat()\n    val newG = (matrix[3] * r + matrix[4] * g + matrix[5] * b).toFloat()\n    val newB = (matrix[6] * r + matrix[7] * g + matrix[8] * b).toFloat()\n    return listOf(newR.coerceIn(0f, 1f), newG.coerceIn(0f, 1f), newB.coerceIn(0f, 1f))\n}\n\nenum class ColorBlindType {\n    Protanomaly,\n    Deuteranomaly,\n    Tritanomaly,\n    Protanopia,\n    Deuteranopia,\n    Tritanopia,\n    Achromatomaly,\n    Achromatopsia\n}\n\nfun ColorScheme.toColorBlind(type: ColorBlindType?): ColorScheme {\n    if (type == null) return this\n\n    return this.copy(\n        primary = primary.toColorBlind(type),\n        onPrimary = onPrimary.toColorBlind(type),\n        primaryContainer = primaryContainer.toColorBlind(type),\n        onPrimaryContainer = onPrimaryContainer.toColorBlind(type),\n        inversePrimary = inversePrimary.toColorBlind(type),\n        secondary = secondary.toColorBlind(type),\n        onSecondary = onSecondary.toColorBlind(type),\n        secondaryContainer = secondaryContainer.toColorBlind(type),\n        onSecondaryContainer = onSecondaryContainer.toColorBlind(type),\n        tertiary = tertiary.toColorBlind(type),\n        onTertiary = onTertiary.toColorBlind(type),\n        tertiaryContainer = tertiaryContainer.toColorBlind(type),\n        onTertiaryContainer = onTertiaryContainer.toColorBlind(type),\n        background = background.toColorBlind(type),\n        onBackground = onBackground.toColorBlind(type),\n        surface = surface.toColorBlind(type),\n        onSurface = onSurface.toColorBlind(type),\n        surfaceVariant = surfaceVariant.toColorBlind(type),\n        onSurfaceVariant = onSurfaceVariant.toColorBlind(type),\n        surfaceTint = surfaceTint.toColorBlind(type),\n        inverseSurface = inverseSurface.toColorBlind(type),\n        inverseOnSurface = inverseOnSurface.toColorBlind(type),\n        error = error.toColorBlind(type),\n        onError = onError.toColorBlind(type),\n        errorContainer = errorContainer.toColorBlind(type),\n        onErrorContainer = onErrorContainer.toColorBlind(type),\n        outline = outline.toColorBlind(type),\n        outlineVariant = outlineVariant.toColorBlind(type),\n        surfaceBright = surfaceBright.toColorBlind(type),\n        surfaceDim = surfaceDim.toColorBlind(type),\n        surfaceContainer = surfaceContainer.toColorBlind(type),\n        surfaceContainerHigh = surfaceContainerHigh.toColorBlind(type),\n        surfaceContainerHighest = surfaceContainerHighest.toColorBlind(type),\n        surfaceContainerLow = surfaceContainerLow.toColorBlind(type),\n        surfaceContainerLowest = surfaceContainerLowest.toColorBlind(type),\n        primaryFixed = primaryFixed.toColorBlind(type),\n        primaryFixedDim = primaryFixedDim.toColorBlind(type),\n        onPrimaryFixed = onPrimaryFixed.toColorBlind(type),\n        onPrimaryFixedVariant = onPrimaryFixedVariant.toColorBlind(type),\n        secondaryFixed = secondaryFixed.toColorBlind(type),\n        secondaryFixedDim = secondaryFixedDim.toColorBlind(type),\n        onSecondaryFixed = onSecondaryFixed.toColorBlind(type),\n        onSecondaryFixedVariant = onSecondaryFixedVariant.toColorBlind(type),\n        tertiaryFixed = tertiaryFixed.toColorBlind(type),\n        tertiaryFixedDim = tertiaryFixedDim.toColorBlind(type),\n        onTertiaryFixed = onTertiaryFixed.toColorBlind(type),\n        onTertiaryFixedVariant = onTertiaryFixedVariant.toColorBlind(type),\n    )\n}"
  },
  {
    "path": "lib/dynamic-theme/src/main/java/com/t8rin/dynamic/theme/DynamicTheme.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\", \"MemberVisibilityCanBePrivate\", \"KotlinConstantConditions\")\n\npackage com.t8rin.dynamic.theme\n\nimport android.Manifest\nimport android.annotation.SuppressLint\nimport android.app.WallpaperManager\nimport android.content.Context\nimport android.content.pm.PackageManager\nimport android.graphics.Bitmap\nimport android.graphics.Canvas\nimport android.graphics.ColorMatrix\nimport android.graphics.ColorMatrixColorFilter\nimport android.graphics.Paint\nimport android.os.Build\nimport androidx.annotation.FloatRange\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Typography\nimport androidx.compose.material3.dynamicDarkColorScheme\nimport androidx.compose.material3.dynamicLightColorScheme\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.listSaver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalConfiguration\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.dp\nimport androidx.core.app.ActivityCompat\nimport androidx.core.graphics.ColorUtils\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.drawable.toBitmap\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleEventObserver\nimport androidx.lifecycle.compose.LocalLifecycleOwner\nimport androidx.palette.graphics.Palette\nimport com.materialkolor.dynamiccolor.MaterialDynamicColors\nimport com.materialkolor.hct.Hct\nimport com.materialkolor.palettes.TonalPalette\nimport com.materialkolor.scheme.DynamicScheme\nimport com.materialkolor.scheme.SchemeContent\nimport com.materialkolor.scheme.SchemeExpressive\nimport com.materialkolor.scheme.SchemeFidelity\nimport com.materialkolor.scheme.SchemeFruitSalad\nimport com.materialkolor.scheme.SchemeMonochrome\nimport com.materialkolor.scheme.SchemeNeutral\nimport com.materialkolor.scheme.SchemeRainbow\nimport com.materialkolor.scheme.SchemeVibrant\nimport com.materialkolor.scheme.Variant\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\n\n/**\n * DynamicTheme allows you to dynamically change the color scheme of the content hierarchy.\n * To do this you just need to update [DynamicThemeState].\n * @param state - current instance of [DynamicThemeState]\n * */\n@Composable\nfun DynamicTheme(\n    state: DynamicThemeState,\n    typography: Typography = MaterialTheme.typography,\n    density: Density = LocalDensity.current,\n    defaultColorTuple: ColorTuple,\n    dynamicColor: Boolean = true,\n    amoledMode: Boolean = false,\n    isDarkTheme: Boolean,\n    style: PaletteStyle = PaletteStyle.TonalSpot,\n    contrastLevel: Double = 0.0,\n    isInvertColors: Boolean = false,\n    colorBlindType: ColorBlindType? = null,\n    colorAnimationSpec: AnimationSpec<Color> = tween(300),\n    dynamicColorsOverride: ((isDarkTheme: Boolean) -> ColorTuple?)? = null,\n    content: @Composable () -> Unit,\n) {\n    val colorTuple = rememberAppColorTuple(\n        defaultColorTuple = defaultColorTuple,\n        dynamicColor = dynamicColor,\n        darkTheme = isDarkTheme\n    )\n    val configuration = LocalConfiguration.current\n    var prevOrientation by rememberSaveable { mutableIntStateOf(configuration.orientation) }\n\n    LaunchedEffect(colorTuple, prevOrientation) {\n        if (prevOrientation == configuration.orientation) {\n            state.updateColorTuple(colorTuple)\n        } else prevOrientation = configuration.orientation\n    }\n\n    val lightTheme = !isDarkTheme\n    val systemUiController = rememberSystemUiController()\n    val useDarkIcons = if (dynamicColor) {\n        lightTheme\n    } else if (isInvertColors) {\n        isDarkTheme\n    } else {\n        lightTheme\n    }\n\n    SideEffect {\n        systemUiController.setSystemBarsColor(\n            color = Color.Transparent,\n            darkIcons = useDarkIcons,\n            isNavigationBarContrastEnforced = false\n        )\n    }\n\n    CompositionLocalProvider(\n        values = arrayOf(\n            LocalDynamicThemeState provides state,\n            LocalDensity provides density\n        ),\n        content = {\n            MaterialTheme(\n                typography = typography,\n                colorScheme = rememberColorScheme(\n                    amoledMode = amoledMode,\n                    isDarkTheme = isDarkTheme,\n                    colorTuple = state.colorTuple.value,\n                    style = style,\n                    contrastLevel = contrastLevel,\n                    dynamicColor = dynamicColor,\n                    isInvertColors = isInvertColors,\n                    colorBlindType = colorBlindType,\n                    dynamicColorsOverride = dynamicColorsOverride\n                ).animateAllColors(colorAnimationSpec),\n                content = content\n            )\n        }\n    )\n}\n\n/**Composable representing ColorTuple object **/\n@Composable\nfun ColorTupleItem(\n    modifier: Modifier = Modifier,\n    backgroundColor: Color = MaterialTheme.colorScheme.surface,\n    colorTuple: ColorTuple,\n    shape: Shape = CircleShape,\n    containerShape: Shape = MaterialTheme.shapes.medium,\n    contentPadding: PaddingValues = PaddingValues(8.dp),\n    content: (@Composable BoxScope.() -> Unit)? = null\n) {\n    val (primary, secondary, tertiary) = remember(colorTuple) {\n        derivedStateOf {\n            colorTuple.run {\n                val hct = Hct.fromInt(colorTuple.primary.toArgb())\n                val hue = hct.hue\n                val chroma = hct.chroma\n\n                val secondary = colorTuple.secondary?.toArgb().let {\n                    if (it != null) {\n                        TonalPalette.fromInt(it)\n                    } else {\n                        TonalPalette.fromHueAndChroma(hue, chroma / 3.0)\n                    }\n                }\n                val tertiary = colorTuple.tertiary?.toArgb().let {\n                    if (it != null) {\n                        TonalPalette.fromInt(it)\n                    } else {\n                        TonalPalette.fromHueAndChroma(hue + 60.0, chroma / 2.0)\n                    }\n                }\n\n                Triple(\n                    primary,\n                    colorTuple.secondary ?: Color(secondary.tone(70)),\n                    colorTuple.tertiary ?: Color(tertiary.tone(70))\n                )\n            }\n        }\n    }.value.run {\n        Triple(\n            animateColorAsState(targetValue = first).value,\n            animateColorAsState(targetValue = second).value,\n            animateColorAsState(targetValue = third).value\n        )\n    }\n\n    Surface(\n        modifier = modifier,\n        color = backgroundColor,\n        shape = containerShape\n    ) {\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(contentPadding)\n                .clip(shape),\n            contentAlignment = Alignment.Center\n        ) {\n            Column(Modifier.fillMaxSize()) {\n                Box(\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .weight(1f)\n                        .background(primary)\n                )\n                Row(\n                    modifier = Modifier\n                        .weight(1f)\n                        .fillMaxWidth()\n                ) {\n                    Box(\n                        modifier = Modifier\n                            .weight(1f)\n                            .fillMaxHeight()\n                            .background(tertiary)\n                    )\n                    Box(\n                        modifier = Modifier\n                            .weight(1f)\n                            .fillMaxHeight()\n                            .background(secondary)\n                    )\n                }\n            }\n            content?.invoke(this)\n        }\n    }\n}\n\nfun Color.calculateSecondaryColor(): Int {\n    val hct = Hct.fromInt(this.toArgb())\n    val hue = hct.hue\n    val chroma = hct.chroma\n\n    return TonalPalette.fromHueAndChroma(hue, chroma / 3.0).tone(80)\n}\n\nfun Color.calculateTertiaryColor(): Int {\n    val hct = Hct.fromInt(this.toArgb())\n    val hue = hct.hue\n    val chroma = hct.chroma\n\n    return TonalPalette.fromHueAndChroma(hue + 60.0, chroma / 2.0).tone(80)\n}\n\nfun Color.calculateSurfaceColor(): Int {\n    val hct = Hct.fromInt(this.toArgb())\n    val hue = hct.hue\n    val chroma = hct.chroma\n\n    return TonalPalette.fromHueAndChroma(hue, (chroma / 12.0).coerceAtMost(4.0)).tone(90)\n}\n\n\n@SuppressLint(\"MissingPermission\")\n@Composable\nfun rememberAppColorTuple(\n    defaultColorTuple: ColorTuple,\n    dynamicColor: Boolean,\n    darkTheme: Boolean\n): ColorTuple {\n    val context = LocalContext.current\n    return remember(\n        LocalLifecycleOwner.current.lifecycle.observeAsState().value,\n        dynamicColor,\n        darkTheme,\n        defaultColorTuple\n    ) {\n        derivedStateOf {\n            runCatching {\n                val wallpaperManager = WallpaperManager.getInstance(context)\n                val wallColors =\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {\n                        wallpaperManager\n                            .getWallpaperColors(WallpaperManager.FLAG_SYSTEM)\n                    } else null\n\n                when {\n                    dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {\n                        if (darkTheme) {\n                            dynamicDarkColorScheme(context)\n                        } else {\n                            dynamicLightColorScheme(context)\n                        }.run {\n                            ColorTuple(\n                                primary = primary,\n                                secondary = secondary,\n                                tertiary = tertiary,\n                                surface = surface\n                            )\n                        }\n                    }\n\n                    dynamicColor && wallColors != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 -> {\n                        ColorTuple(\n                            primary = Color(wallColors.primaryColor.toArgb()),\n                            secondary = wallColors.secondaryColor?.toArgb()?.let { Color(it) },\n                            tertiary = wallColors.tertiaryColor?.toArgb()?.let { Color(it) }\n                        )\n                    }\n\n                    dynamicColor && ActivityCompat.checkSelfPermission(\n                        context,\n                        Manifest.permission.READ_EXTERNAL_STORAGE\n                    ) == PackageManager.PERMISSION_GRANTED -> {\n                        val primary = wallpaperManager.drawable?.toBitmap()?.extractPrimaryColor()\n\n                        primary?.let {\n                            ColorTuple(\n                                primary = primary\n                            )\n                        }\n                    }\n\n                    else -> defaultColorTuple\n                }\n            }.getOrNull() ?: defaultColorTuple\n        }\n    }.value\n}\n\n@Composable\nfun Lifecycle.observeAsState(): State<Lifecycle.Event> {\n    val state = remember { mutableStateOf(Lifecycle.Event.ON_ANY) }\n    DisposableEffect(this) {\n        val observer = LifecycleEventObserver { _, event ->\n            state.value = event\n        }\n        this@observeAsState.addObserver(observer)\n        onDispose {\n            this@observeAsState.removeObserver(observer)\n        }\n    }\n    return state\n}\n\n/**\n * This function animates colors when current color scheme changes.\n *\n * @param animationSpec Animation that will be applied when theming option changes.\n * @return [ColorScheme] with animated colors.\n */\n@Composable\nfun ColorScheme.animateAllColors(animationSpec: AnimationSpec<Color>): ColorScheme {\n\n    /**\n     * Wraps color into [animateColorAsState].\n     *\n     * @return Animated [Color].\n     */\n    @Composable\n    fun Color.animateColor() = animateColorAsState(this, animationSpec).value\n\n    return this.copy(\n        primary = primary.animateColor(),\n        onPrimary = onPrimary.animateColor(),\n        primaryContainer = primaryContainer.animateColor(),\n        onPrimaryContainer = onPrimaryContainer.animateColor(),\n        inversePrimary = inversePrimary.animateColor(),\n        secondary = secondary.animateColor(),\n        onSecondary = onSecondary.animateColor(),\n        secondaryContainer = secondaryContainer.animateColor(),\n        onSecondaryContainer = onSecondaryContainer.animateColor(),\n        tertiary = tertiary.animateColor(),\n        onTertiary = onTertiary.animateColor(),\n        tertiaryContainer = tertiaryContainer.animateColor(),\n        onTertiaryContainer = onTertiaryContainer.animateColor(),\n        background = background.animateColor(),\n        onBackground = onBackground.animateColor(),\n        surface = surface.animateColor(),\n        onSurface = onSurface.animateColor(),\n        surfaceVariant = surfaceVariant.animateColor(),\n        onSurfaceVariant = onSurfaceVariant.animateColor(),\n        surfaceTint = surfaceTint.animateColor(),\n        inverseSurface = inverseSurface.animateColor(),\n        inverseOnSurface = inverseOnSurface.animateColor(),\n        error = error.animateColor(),\n        onError = onError.animateColor(),\n        errorContainer = errorContainer.animateColor(),\n        onErrorContainer = onErrorContainer.animateColor(),\n        outline = outline.animateColor(),\n        outlineVariant = outlineVariant.animateColor(),\n        scrim = scrim.animateColor(),\n        surfaceBright = surfaceBright.animateColor(),\n        surfaceDim = surfaceDim.animateColor(),\n        surfaceContainer = surfaceContainer.animateColor(),\n        surfaceContainerHigh = surfaceContainerHigh.animateColor(),\n        surfaceContainerHighest = surfaceContainerHighest.animateColor(),\n        surfaceContainerLow = surfaceContainerLow.animateColor(),\n        surfaceContainerLowest = surfaceContainerLowest.animateColor()\n    )\n}\n\nprivate fun Int.blend(\n    color: Int,\n    @FloatRange(from = 0.0, to = 1.0) fraction: Float = 0.5f\n): Int = ColorUtils.blendARGB(this, color, fraction)\n\nfun Bitmap.extractPrimaryColor(default: Int = 0, blendWithVibrant: Boolean = true): Color {\n    val palette = Palette\n        .from(this)\n        .generate()\n\n    return Color(\n        palette.getDominantColor(default).run {\n            if (blendWithVibrant) blend(palette.getVibrantColor(default), 0.5f)\n            else this\n        }\n    )\n}\n\n/** Class that represents App color scheme based on three main colors\n *  @param primary primary color\n *  @param secondary secondary color\n *  @param tertiary tertiary color\n */\ndata class ColorTuple(\n    val primary: Color,\n    val secondary: Color? = null,\n    val tertiary: Color? = null,\n    val surface: Color? = null\n) {\n    override fun toString(): String =\n        \"ColorTuple(primary=${primary.toArgb()}, secondary=${secondary?.toArgb()}, tertiary=${tertiary?.toArgb()}, surface=${surface?.toArgb()})\"\n}\n\n/**\n * Creates and remember [DynamicThemeState] instance\n * */\n@Composable\nfun rememberDynamicThemeState(\n    initialColorTuple: ColorTuple = ColorTuple(\n        primary = MaterialTheme.colorScheme.primary,\n        secondary = MaterialTheme.colorScheme.secondary,\n        tertiary = MaterialTheme.colorScheme.tertiary,\n        surface = MaterialTheme.colorScheme.surface\n    )\n): DynamicThemeState = rememberSaveable(saver = DynamicThemeStateSaver) {\n    DynamicThemeState(initialColorTuple)\n}\n\nval DynamicThemeStateSaver = listSaver(\n    save = {\n        val colorTuple = it.colorTuple.value\n        val list: List<Int> = listOf(\n            colorTuple.primary.toArgb(),\n            colorTuple.secondary?.toArgb() ?: -1,\n            colorTuple.tertiary?.toArgb() ?: -1,\n            colorTuple.surface?.toArgb() ?: -1\n        )\n\n        list\n    },\n    restore = { ints: List<Int> ->\n        DynamicThemeState(\n            initialColorTuple = ColorTuple(\n                primary = Color(ints[0]),\n                secondary = ints[1].takeIf { it != -1 }?.let { Color(it) },\n                tertiary = ints[2].takeIf { it != -1 }?.let { Color(it) },\n                surface = ints[3].takeIf { it != -1 }?.let { Color(it) },\n            )\n        )\n    }\n)\n\n@Stable\nclass DynamicThemeState(\n    initialColorTuple: ColorTuple\n) {\n    private val _colorTuple: MutableState<ColorTuple> = mutableStateOf(initialColorTuple)\n    val colorTuple: State<ColorTuple> = _colorTuple\n\n    fun updateColor(color: Color) {\n        _colorTuple.value = ColorTuple(primary = color, secondary = null, tertiary = null)\n    }\n\n    fun updateColorTuple(newColorTuple: ColorTuple) {\n        _colorTuple.value = newColorTuple\n    }\n\n    fun updateColorByImage(bitmap: Bitmap) {\n        CoroutineScope(Dispatchers.Main).launch {\n            updateColor(bitmap.saturate(2f).extractPrimaryColor())\n        }\n    }\n\n    private suspend fun Bitmap.saturate(saturation: Float): Bitmap = withContext(Dispatchers.IO) {\n        val src = this@saturate\n        val w = src.width.coerceAtMost(600)\n        val h = src.height.coerceAtMost(600)\n        val bitmapResult = createBitmap(w, h)\n        val canvasResult = Canvas(bitmapResult)\n        val paint = Paint()\n        val colorMatrix = ColorMatrix()\n        colorMatrix.setSaturation(saturation)\n        val filter = ColorMatrixColorFilter(colorMatrix)\n        paint.setColorFilter(filter)\n        canvasResult.drawBitmap(src, 0f, 0f, paint)\n        return@withContext bitmapResult\n    }\n}\n\n@Composable\nfun rememberColorScheme(\n    isDarkTheme: Boolean,\n    amoledMode: Boolean,\n    colorTuple: ColorTuple,\n    style: PaletteStyle,\n    contrastLevel: Double,\n    dynamicColor: Boolean,\n    isInvertColors: Boolean,\n    colorBlindType: ColorBlindType? = null,\n    dynamicColorsOverride: ((isDarkTheme: Boolean) -> ColorTuple?)? = null,\n): ColorScheme {\n    val context = LocalContext.current\n    return remember(\n        colorTuple,\n        isDarkTheme,\n        amoledMode,\n        contrastLevel,\n        dynamicColor,\n        style,\n        isInvertColors,\n        colorBlindType,\n        dynamicColorsOverride\n    ) {\n        derivedStateOf {\n            context.getColorScheme(\n                isDarkTheme = isDarkTheme,\n                amoledMode = amoledMode,\n                colorTuple = colorTuple,\n                style = style,\n                contrastLevel = contrastLevel,\n                dynamicColor = dynamicColor,\n                isInvertColors = isInvertColors,\n                colorBlindType = colorBlindType,\n                dynamicColorsOverride = dynamicColorsOverride\n            )\n        }\n    }.value\n}\n\nfun Context.getColorScheme(\n    isDarkTheme: Boolean,\n    amoledMode: Boolean,\n    colorTuple: ColorTuple,\n    style: PaletteStyle,\n    contrastLevel: Double,\n    dynamicColor: Boolean,\n    isInvertColors: Boolean,\n    colorBlindType: ColorBlindType? = null,\n    dynamicColorsOverride: ((isDarkTheme: Boolean) -> ColorTuple?)? = null,\n): ColorScheme {\n    val overridden = if (dynamicColor) dynamicColorsOverride?.invoke(isDarkTheme) else null\n    val colorTuple = overridden ?: colorTuple\n\n    val colorScheme =\n        if (dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && overridden == null) {\n            if (isDarkTheme) {\n                dynamicDarkColorScheme(this)\n            } else {\n                dynamicLightColorScheme(this)\n            }\n        } else {\n            val hct = Hct.fromInt(colorTuple.primary.toArgb())\n            val hue = hct.hue\n            val chroma = hct.chroma\n\n            val a1 = colorTuple.primary.let { TonalPalette.fromInt(it.toArgb()) }\n\n            val a2 = colorTuple.secondary?.toArgb().let {\n                if (it != null) {\n                    TonalPalette.fromInt(it)\n                } else {\n                    TonalPalette.fromHueAndChroma(hue, chroma / 3.0)\n                }\n            }\n\n            val a3 = colorTuple.tertiary?.toArgb().let {\n                if (it != null) {\n                    TonalPalette.fromInt(it)\n                } else {\n                    TonalPalette.fromHueAndChroma(hue + 60.0, chroma / 2.0)\n                }\n            }\n\n            val n1 = colorTuple.surface?.toArgb().let {\n                if (it != null) {\n                    TonalPalette.fromInt(it)\n                } else {\n                    TonalPalette.fromHueAndChroma(hue, (chroma / 12.0).coerceAtMost(4.0))\n                }\n            }\n\n            val n2 = TonalPalette.fromInt(n1.tone(90))\n\n            val scheme = when (style) {\n                PaletteStyle.TonalSpot -> DynamicScheme(\n                    hct, Variant.TONAL_SPOT, isDarkTheme, contrastLevel, a1, a2, a3, n1, n2\n                )\n\n                PaletteStyle.Neutral -> SchemeNeutral(hct, isDarkTheme, contrastLevel)\n                PaletteStyle.Vibrant -> SchemeVibrant(hct, isDarkTheme, contrastLevel)\n                PaletteStyle.Expressive -> SchemeExpressive(hct, isDarkTheme, contrastLevel)\n                PaletteStyle.Rainbow -> SchemeRainbow(hct, isDarkTheme, contrastLevel)\n                PaletteStyle.FruitSalad -> SchemeFruitSalad(hct, isDarkTheme, contrastLevel)\n                PaletteStyle.Monochrome -> SchemeMonochrome(hct, isDarkTheme, contrastLevel)\n                PaletteStyle.Fidelity -> SchemeFidelity(hct, isDarkTheme, contrastLevel)\n                PaletteStyle.Content -> SchemeContent(hct, isDarkTheme, contrastLevel)\n            }\n\n            scheme.toColorScheme()\n        }\n\n\n    return colorScheme\n        .toAmoled(amoledMode && isDarkTheme)\n        .toColorBlind(colorBlindType)\n        .invertColors(isInvertColors && !dynamicColor)\n        .run {\n            copy(\n                outlineVariant = onSecondaryContainer\n                    .copy(alpha = 0.2f)\n                    .compositeOver(surfaceColorAtElevation(6.dp))\n            )\n        }\n}\n\nprivate fun ColorScheme.invertColors(\n    enabled: Boolean\n): ColorScheme {\n\n    fun Color.invertColor(): Color = if (enabled) {\n        Color(this.toArgb() xor 0x00ffffff)\n    } else this\n\n    return this.copy(\n        primary = primary.invertColor(),\n        onPrimary = onPrimary.invertColor(),\n        primaryContainer = primaryContainer.invertColor(),\n        onPrimaryContainer = onPrimaryContainer.invertColor(),\n        inversePrimary = inversePrimary.invertColor(),\n        secondary = secondary.invertColor(),\n        onSecondary = onSecondary.invertColor(),\n        secondaryContainer = secondaryContainer.invertColor(),\n        onSecondaryContainer = onSecondaryContainer.invertColor(),\n        tertiary = tertiary.invertColor(),\n        onTertiary = onTertiary.invertColor(),\n        tertiaryContainer = tertiaryContainer.invertColor(),\n        onTertiaryContainer = onTertiaryContainer.invertColor(),\n        background = background.invertColor(),\n        onBackground = onBackground.invertColor(),\n        surface = surface.invertColor(),\n        onSurface = onSurface.invertColor(),\n        surfaceVariant = surfaceVariant.invertColor(),\n        onSurfaceVariant = onSurfaceVariant.invertColor(),\n        surfaceTint = surfaceTint.invertColor(),\n        inverseSurface = inverseSurface.invertColor(),\n        inverseOnSurface = inverseOnSurface.invertColor(),\n        error = error.invertColor(),\n        onError = onError.invertColor(),\n        errorContainer = errorContainer.invertColor(),\n        onErrorContainer = onErrorContainer.invertColor(),\n        outline = outline.invertColor(),\n        outlineVariant = outlineVariant.invertColor(),\n        surfaceBright = surfaceBright.invertColor(),\n        surfaceDim = surfaceDim.invertColor(),\n        surfaceContainer = surfaceContainer.invertColor(),\n        surfaceContainerHigh = surfaceContainerHigh.invertColor(),\n        surfaceContainerHighest = surfaceContainerHighest.invertColor(),\n        surfaceContainerLow = surfaceContainerLow.invertColor(),\n        surfaceContainerLowest = surfaceContainerLowest.invertColor(),\n        primaryFixed = primaryFixed.invertColor(),\n        primaryFixedDim = primaryFixedDim.invertColor(),\n        onPrimaryFixed = onPrimaryFixed.invertColor(),\n        onPrimaryFixedVariant = onPrimaryFixedVariant.invertColor(),\n        secondaryFixed = secondaryFixed.invertColor(),\n        secondaryFixedDim = secondaryFixedDim.invertColor(),\n        onSecondaryFixed = onSecondaryFixed.invertColor(),\n        onSecondaryFixedVariant = onSecondaryFixedVariant.invertColor(),\n        tertiaryFixed = tertiaryFixed.invertColor(),\n        tertiaryFixedDim = tertiaryFixedDim.invertColor(),\n        onTertiaryFixed = onTertiaryFixed.invertColor(),\n        onTertiaryFixedVariant = onTertiaryFixedVariant.invertColor(),\n    )\n}\n\nprivate fun DynamicScheme.toColorScheme(): ColorScheme {\n    val colors = MaterialDynamicColors()\n    val scheme = this\n    return ColorScheme(\n        primary = Color(colors.primary().getArgb(scheme)),\n        onPrimary = Color(colors.onPrimary().getArgb(scheme)),\n        primaryContainer = Color(colors.primaryContainer().getArgb(scheme)),\n        onPrimaryContainer = Color(colors.onPrimaryContainer().getArgb(scheme)),\n        inversePrimary = Color(colors.inversePrimary().getArgb(scheme)),\n        secondary = Color(colors.secondary().getArgb(scheme)),\n        onSecondary = Color(colors.onSecondary().getArgb(scheme)),\n        secondaryContainer = Color(colors.secondaryContainer().getArgb(scheme)),\n        onSecondaryContainer = Color(colors.onSecondaryContainer().getArgb(scheme)),\n        tertiary = Color(colors.tertiary().getArgb(scheme)),\n        onTertiary = Color(colors.onTertiary().getArgb(scheme)),\n        tertiaryContainer = Color(colors.tertiaryContainer().getArgb(scheme)),\n        onTertiaryContainer = Color(colors.onTertiaryContainer().getArgb(scheme)),\n        background = Color(colors.background().getArgb(scheme)),\n        onBackground = Color(colors.onBackground().getArgb(scheme)),\n        surface = Color(colors.surface().getArgb(scheme)),\n        onSurface = Color(colors.onSurface().getArgb(scheme)),\n        surfaceVariant = Color(colors.surfaceVariant().getArgb(scheme)),\n        onSurfaceVariant = Color(colors.onSurfaceVariant().getArgb(scheme)),\n        surfaceTint = Color(colors.surfaceTint().getArgb(scheme)),\n        inverseSurface = Color(colors.inverseSurface().getArgb(scheme)),\n        inverseOnSurface = Color(colors.inverseOnSurface().getArgb(scheme)),\n        error = Color(colors.error().getArgb(scheme)),\n        onError = Color(colors.onError().getArgb(scheme)),\n        errorContainer = Color(colors.errorContainer().getArgb(scheme)),\n        onErrorContainer = Color(colors.onErrorContainer().getArgb(scheme)),\n        outline = Color(colors.outline().getArgb(scheme)),\n        outlineVariant = Color(colors.outlineVariant().getArgb(scheme)),\n        scrim = Color(colors.scrim().getArgb(scheme)),\n        surfaceBright = Color(colors.surfaceBright().getArgb(scheme)),\n        surfaceDim = Color(colors.surfaceDim().getArgb(scheme)),\n        surfaceContainer = Color(colors.surfaceContainer().getArgb(scheme)),\n        surfaceContainerHigh = Color(colors.surfaceContainerHigh().getArgb(scheme)),\n        surfaceContainerHighest = Color(colors.surfaceContainerHighest().getArgb(scheme)),\n        surfaceContainerLow = Color(colors.surfaceContainerLow().getArgb(scheme)),\n        surfaceContainerLowest = Color(colors.surfaceContainerLowest().getArgb(scheme)),\n        primaryFixed = Color(colors.primaryFixed().getArgb(scheme)),\n        primaryFixedDim = Color(colors.primaryFixedDim().getArgb(scheme)),\n        onPrimaryFixed = Color(colors.onPrimaryFixed().getArgb(scheme)),\n        onPrimaryFixedVariant = Color(colors.onPrimaryFixedVariant().getArgb(scheme)),\n        secondaryFixed = Color(colors.secondaryFixed().getArgb(scheme)),\n        secondaryFixedDim = Color(colors.secondaryFixedDim().getArgb(scheme)),\n        onSecondaryFixed = Color(colors.onSecondaryFixed().getArgb(scheme)),\n        onSecondaryFixedVariant = Color(colors.onSecondaryFixedVariant().getArgb(scheme)),\n        tertiaryFixed = Color(colors.tertiaryFixed().getArgb(scheme)),\n        tertiaryFixedDim = Color(colors.tertiaryFixedDim().getArgb(scheme)),\n        onTertiaryFixed = Color(colors.onTertiaryFixed().getArgb(scheme)),\n        onTertiaryFixedVariant = Color(colors.onTertiaryFixedVariant().getArgb(scheme)),\n    )\n}\n\n\nprivate fun ColorScheme.toAmoled(amoledMode: Boolean): ColorScheme {\n    fun Color.darken(fraction: Float = 0.5f): Color =\n        Color(toArgb().blend(Color.Black.toArgb(), fraction))\n\n    return if (amoledMode) {\n        copy(\n            primary = primary.darken(0.3f),\n            onPrimary = onPrimary.darken(0.1f),\n            primaryContainer = primaryContainer.darken(0.3f),\n            onPrimaryContainer = onPrimaryContainer.darken(0.1f),\n            inversePrimary = inversePrimary.darken(0.3f),\n            secondary = secondary.darken(0.3f),\n            onSecondary = onSecondary.darken(0.1f),\n            secondaryContainer = secondaryContainer.darken(0.3f),\n            onSecondaryContainer = onSecondaryContainer.darken(0.1f),\n            tertiary = tertiary.darken(0.3f),\n            onTertiary = onTertiary.darken(0.1f),\n            tertiaryContainer = tertiaryContainer.darken(0.3f),\n            onTertiaryContainer = onTertiaryContainer.darken(0.1f),\n            background = Color.Black,\n            onBackground = onBackground.darken(0.1f),\n            surface = Color.Black,\n            onSurface = onSurface.darken(0.1f),\n            surfaceVariant = surfaceVariant.darken(0.1f),\n            onSurfaceVariant = onSurfaceVariant.darken(0.1f),\n            surfaceTint = surfaceTint,\n            inverseSurface = inverseSurface.darken(),\n            inverseOnSurface = inverseOnSurface.darken(0.1f),\n            error = error.darken(0.3f),\n            onError = onError.darken(0.1f),\n            errorContainer = errorContainer.darken(0.3f),\n            onErrorContainer = onErrorContainer.darken(0.1f),\n            outline = outline.darken(0.2f),\n            outlineVariant = outlineVariant.darken(0.2f),\n            scrim = scrim.darken(),\n            surfaceBright = surfaceBright.darken(),\n            surfaceDim = surfaceDim.darken(),\n            surfaceContainer = surfaceContainer.darken(),\n            surfaceContainerHigh = surfaceContainerHigh.darken(),\n            surfaceContainerHighest = surfaceContainerHighest.darken(),\n            surfaceContainerLow = surfaceContainerLow.darken(),\n            surfaceContainerLowest = surfaceContainerLowest.darken(),\n            primaryFixed = primaryFixed.darken(0.3f),\n            primaryFixedDim = primaryFixedDim.darken(0.3f),\n            onPrimaryFixed = onPrimaryFixed.darken(0.1f),\n            onPrimaryFixedVariant = onPrimaryFixedVariant.darken(0.1f),\n            secondaryFixed = secondaryFixed.darken(0.3f),\n            secondaryFixedDim = secondaryFixedDim.darken(0.3f),\n            onSecondaryFixed = onSecondaryFixed.darken(0.1f),\n            onSecondaryFixedVariant = onSecondaryFixedVariant.darken(0.1f),\n            tertiaryFixed = tertiaryFixed.darken(0.3f),\n            tertiaryFixedDim = tertiaryFixedDim.darken(0.3f),\n            onTertiaryFixed = onTertiaryFixed.darken(0.1f),\n            onTertiaryFixedVariant = onTertiaryFixedVariant.darken(0.1f),\n        )\n    } else this\n}\n\nval LocalDynamicThemeState: ProvidableCompositionLocal<DynamicThemeState> =\n    compositionLocalOf { error(\"DynamicThemeState not present\") }"
  },
  {
    "path": "lib/dynamic-theme/src/main/java/com/t8rin/dynamic/theme/PaletteStyle.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.dynamic.theme\n\nenum class PaletteStyle {\n    TonalSpot,\n    Neutral,\n    Vibrant,\n    Expressive,\n    Rainbow,\n    FruitSalad,\n    Monochrome,\n    Fidelity,\n    Content\n}"
  },
  {
    "path": "lib/dynamic-theme/src/main/java/com/t8rin/dynamic/theme/SystemUiController.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"PrivatePropertyName\", \"DEPRECATION\", \"unused\")\n\npackage com.t8rin.dynamic.theme\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.ContextWrapper\nimport android.os.Build\nimport android.view.View\nimport android.view.Window\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalView\nimport androidx.compose.ui.window.DialogWindowProvider\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.WindowInsetsControllerCompat\n\n\n@Stable\ninterface SystemUiController {\n\n    /**\n     * Control for the behavior of the system bars. This value should be one of the\n     * [WindowInsetsControllerCompat] behavior constants:\n     * [WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH] (Deprecated),\n     * [WindowInsetsControllerCompat.BEHAVIOR_DEFAULT] and\n     * [WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE].\n     */\n    var systemBarsBehavior: Int\n\n    /**\n     * Property which holds the status bar visibility. If set to true, show the status bar,\n     * otherwise hide the status bar.\n     */\n    var isStatusBarVisible: Boolean\n\n    /**\n     * Property which holds the navigation bar visibility. If set to true, show the navigation bar,\n     * otherwise hide the navigation bar.\n     */\n    var isNavigationBarVisible: Boolean\n\n    /**\n     * Property which holds the status & navigation bar visibility. If set to true, show both bars,\n     * otherwise hide both bars.\n     */\n    var isSystemBarsVisible: Boolean\n        get() = isNavigationBarVisible && isStatusBarVisible\n        set(value) {\n            isStatusBarVisible = value\n            isNavigationBarVisible = value\n        }\n\n    /**\n     * Set the status bar color.\n     *\n     * @param color The **desired** [Color] to set. This may require modification if running on an\n     * API level that only supports white status bar icons.\n     * @param darkIcons Whether dark status bar icons would be preferable.\n     * @param transformColorForLightContent A lambda which will be invoked to transform [color] if\n     * dark icons were requested but are not available. Defaults to applying a black scrim.\n     *\n     * @see statusBarDarkContentEnabled\n     */\n    fun setStatusBarColor(\n        color: Color,\n        darkIcons: Boolean = color.luminance() > 0.5f,\n        transformColorForLightContent: (Color) -> Color = BlackScrimmed\n    )\n\n    /**\n     * Set the navigation bar color.\n     *\n     * @param color The **desired** [Color] to set. This may require modification if running on an\n     * API level that only supports white navigation bar icons. Additionally this will be ignored\n     * and [Color.Transparent] will be used on API 29+ where gesture navigation is preferred or the\n     * system UI automatically applies background protection in other navigation modes.\n     * @param darkIcons Whether dark navigation bar icons would be preferable.\n     * @param navigationBarContrastEnforced Whether the system should ensure that the navigation\n     * bar has enough contrast when a fully transparent background is requested. Only supported on\n     * API 29+.\n     * @param transformColorForLightContent A lambda which will be invoked to transform [color] if\n     * dark icons were requested but are not available. Defaults to applying a black scrim.\n     *\n     * @see navigationBarDarkContentEnabled\n     * @see navigationBarContrastEnforced\n     */\n    fun setNavigationBarColor(\n        color: Color,\n        darkIcons: Boolean = color.luminance() > 0.5f,\n        navigationBarContrastEnforced: Boolean = true,\n        transformColorForLightContent: (Color) -> Color = BlackScrimmed\n    )\n\n    /**\n     * Set the status and navigation bars to [color].\n     *\n     * @see setStatusBarColor\n     * @see setNavigationBarColor\n     */\n    fun setSystemBarsColor(\n        color: Color,\n        darkIcons: Boolean = color.luminance() > 0.5f,\n        isNavigationBarContrastEnforced: Boolean = true,\n        transformColorForLightContent: (Color) -> Color = BlackScrimmed\n    ) {\n        setStatusBarColor(color, darkIcons, transformColorForLightContent)\n        setNavigationBarColor(\n            color,\n            darkIcons,\n            isNavigationBarContrastEnforced,\n            transformColorForLightContent\n        )\n    }\n\n    /**\n     * Property which holds whether the status bar icons + content are 'dark' or not.\n     */\n    var statusBarDarkContentEnabled: Boolean\n\n    /**\n     * Property which holds whether the navigation bar icons + content are 'dark' or not.\n     */\n    var navigationBarDarkContentEnabled: Boolean\n\n    /**\n     * Property which holds whether the status & navigation bar icons + content are 'dark' or not.\n     */\n    var systemBarsDarkContentEnabled: Boolean\n        get() = statusBarDarkContentEnabled && navigationBarDarkContentEnabled\n        set(value) {\n            statusBarDarkContentEnabled = value\n            navigationBarDarkContentEnabled = value\n        }\n\n    /**\n     * Property which holds whether the system is ensuring that the navigation bar has enough\n     * contrast when a fully transparent background is requested. Only has an affect when running\n     * on Android API 29+ devices.\n     */\n    var isNavigationBarContrastEnforced: Boolean\n}\n\n/**\n * Remembers a [SystemUiController] for the given [window].\n *\n * If no [window] is provided, an attempt to find the correct [Window] is made.\n *\n * First, if the [LocalView]'s parent is a [DialogWindowProvider], then that dialog's [Window] will\n * be used.\n *\n * Second, we attempt to find [Window] for the [Activity] containing the [LocalView].\n *\n * If none of these are found (such as may happen in a preview), then the functionality of the\n * returned [SystemUiController] will be degraded, but won't throw an exception.\n */\n@Composable\nfun rememberSystemUiController(\n    window: Window? = findWindow(),\n): SystemUiController {\n    val view = LocalView.current\n    return remember(view, window) { AndroidSystemUiController(view, window) }\n}\n\n@Composable\nprivate fun findWindow(): Window? =\n    (LocalView.current.parent as? DialogWindowProvider)?.window\n        ?: LocalView.current.context.findWindow()\n\nprivate tailrec fun Context.findWindow(): Window? =\n    when (this) {\n        is Activity -> window\n        is ContextWrapper -> baseContext.findWindow()\n        else -> null\n    }\n\n/**\n * A helper class for setting the navigation and status bar colors for a [View], gracefully\n * degrading behavior based upon API level.\n *\n * Typically you would use [rememberSystemUiController] to remember an instance of this.\n */\ninternal class AndroidSystemUiController(\n    private val view: View,\n    private val window: Window?\n) : SystemUiController {\n    private val windowInsetsController = window?.let {\n        WindowCompat.getInsetsController(it, view)\n    }\n\n    override fun setStatusBarColor(\n        color: Color,\n        darkIcons: Boolean,\n        transformColorForLightContent: (Color) -> Color\n    ) {\n        statusBarDarkContentEnabled = darkIcons\n\n        window?.statusBarColor = when {\n            darkIcons && windowInsetsController?.isAppearanceLightStatusBars != true -> {\n                // If we're set to use dark icons, but our windowInsetsController call didn't\n                // succeed (usually due to API level), we instead transform the color to maintain\n                // contrast\n                transformColorForLightContent(color)\n            }\n\n            else -> color\n        }.toArgb()\n    }\n\n    override fun setNavigationBarColor(\n        color: Color,\n        darkIcons: Boolean,\n        navigationBarContrastEnforced: Boolean,\n        transformColorForLightContent: (Color) -> Color\n    ) {\n        navigationBarDarkContentEnabled = darkIcons\n        isNavigationBarContrastEnforced = navigationBarContrastEnforced\n\n        window?.navigationBarColor = when {\n            darkIcons && windowInsetsController?.isAppearanceLightNavigationBars != true -> {\n                // If we're set to use dark icons, but our windowInsetsController call didn't\n                // succeed (usually due to API level), we instead transform the color to maintain\n                // contrast\n                transformColorForLightContent(color)\n            }\n\n            else -> color\n        }.toArgb()\n    }\n\n    override var systemBarsBehavior: Int\n        get() = windowInsetsController?.systemBarsBehavior ?: 0\n        set(value) {\n            windowInsetsController?.systemBarsBehavior = value\n        }\n\n    override var isStatusBarVisible: Boolean\n        get() {\n            return ViewCompat.getRootWindowInsets(view)\n                ?.isVisible(WindowInsetsCompat.Type.statusBars()) == true\n        }\n        set(value) {\n            if (value) {\n                windowInsetsController?.show(WindowInsetsCompat.Type.statusBars())\n            } else {\n                windowInsetsController?.hide(WindowInsetsCompat.Type.statusBars())\n            }\n        }\n\n    override var isNavigationBarVisible: Boolean\n        get() {\n            return ViewCompat.getRootWindowInsets(view)\n                ?.isVisible(WindowInsetsCompat.Type.navigationBars()) == true\n        }\n        set(value) {\n            if (value) {\n                windowInsetsController?.show(WindowInsetsCompat.Type.navigationBars())\n            } else {\n                windowInsetsController?.hide(WindowInsetsCompat.Type.navigationBars())\n            }\n        }\n\n    override var statusBarDarkContentEnabled: Boolean\n        get() = windowInsetsController?.isAppearanceLightStatusBars == true\n        set(value) {\n            windowInsetsController?.isAppearanceLightStatusBars = value\n        }\n\n    override var navigationBarDarkContentEnabled: Boolean\n        get() = windowInsetsController?.isAppearanceLightNavigationBars == true\n        set(value) {\n            windowInsetsController?.isAppearanceLightNavigationBars = value\n        }\n\n    override var isNavigationBarContrastEnforced: Boolean\n        get() = Build.VERSION.SDK_INT >= 29 && window?.isNavigationBarContrastEnforced == true\n        set(value) {\n            if (Build.VERSION.SDK_INT >= 29) {\n                window?.isNavigationBarContrastEnforced = value\n            }\n        }\n}\n\nprivate val BlackScrim = Color(0f, 0f, 0f, 0.3f) // 30% opaque black\nprivate val BlackScrimmed: (Color) -> Color = { original ->\n    BlackScrim.compositeOver(original)\n}"
  },
  {
    "path": "lib/gesture/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/gesture/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.gesture\""
  },
  {
    "path": "lib/gesture/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/gesture/src/main/java/com/t8rin/gesture/AwaitPointerMotionEvent.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.gesture\n\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEvent\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerEventPass.Final\nimport androidx.compose.ui.input.pointer.PointerEventPass.Initial\nimport androidx.compose.ui.input.pointer.PointerEventPass.Main\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n/**\n * Reads [awaitFirstDown], and [AwaitPointerEventScope.awaitPointerEvent] to\n * get [PointerInputChange] and motion event states\n * [onDown], [onMove], and [onUp].\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove one or multiple pointers are being moved on screen.\n * @param onUp last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n */\nsuspend fun PointerInputScope.detectMotionEvents(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (PointerInputChange) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main\n) {\n    coroutineScope {\n        awaitEachGesture {\n            // Wait for at least one pointer to press down, and set first contact position\n            val down: PointerInputChange = awaitFirstDown(requireUnconsumed)\n\n\n            var pointer = down\n            // Main pointer is the one that is down initially\n            var pointerId = down.id\n\n            // If a move event is followed fast enough down is skipped, especially by Canvas\n            // to prevent it we add delay after first touch\n            var waitedAfterDown = false\n\n            launch {\n                delay(delayAfterDownInMillis)\n                onDown(down)\n                waitedAfterDown = true\n            }\n\n            while (true) {\n\n                val event: PointerEvent = awaitPointerEvent(pass)\n\n                val anyPressed = event.changes.any { it.pressed }\n\n                // There are at least one pointer pressed\n                if (anyPressed) {\n                    // Get pointer that is down, if first pointer is up\n                    // get another and use it if other pointers are also down\n                    // event.changes.first() doesn't return same order\n                    val pointerInputChange =\n                        event.changes.firstOrNull { it.id == pointerId }\n                            ?: event.changes.first()\n\n                    // Next time will check same pointer with this id\n                    pointerId = pointerInputChange.id\n                    pointer = pointerInputChange\n\n                    if (waitedAfterDown) {\n                        onMove(pointer)\n                    }\n                } else {\n                    // All of the pointers are up\n                    onUp(pointer)\n                    break\n                }\n            }\n        }\n    }\n}\n\n/**\n * Reads [awaitFirstDown], and [AwaitPointerEventScope.awaitPointerEvent] to\n * get [PointerInputChange] and motion event states\n * [onDown], [onMove], and [onUp]. Unlike overload of this function [onMove] returns\n * list of [PointerInputChange] to get data about all pointers that are on the screen.\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove one or multiple pointers are being moved on screen.\n * @param onUp last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n *\n */\nsuspend fun PointerInputScope.detectMotionEventsAsList(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (List<PointerInputChange>) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main\n) {\n\n    coroutineScope {\n        awaitEachGesture {\n            // Wait for at least one pointer to press down, and set first contact position\n            val down: PointerInputChange = awaitFirstDown(requireUnconsumed)\n            onDown(down)\n\n            var pointer = down\n            // Main pointer is the one that is down initially\n            var pointerId = down.id\n\n            // If a move event is followed fast enough down is skipped, especially by Canvas\n            // to prevent it we add delay after first touch\n            var waitedAfterDown = false\n\n            launch {\n                delay(delayAfterDownInMillis)\n                waitedAfterDown = true\n            }\n\n            while (true) {\n\n                val event: PointerEvent = awaitPointerEvent(pass)\n\n                val anyPressed = event.changes.any { it.pressed }\n\n                // There are at least one pointer pressed\n                if (anyPressed) {\n                    // Get pointer that is down, if first pointer is up\n                    // get another and use it if other pointers are also down\n                    // event.changes.first() doesn't return same order\n                    val pointerInputChange =\n                        event.changes.firstOrNull { it.id == pointerId }\n                            ?: event.changes.first()\n\n                    // Next time will check same pointer with this id\n                    pointerId = pointerInputChange.id\n                    pointer = pointerInputChange\n\n                    if (waitedAfterDown) {\n                        onMove(event.changes)\n                    }\n\n                } else {\n                    // All of the pointers are up\n                    onUp(pointer)\n                    break\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "lib/gesture/src/main/java/com/t8rin/gesture/PointerMotionModifier.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.gesture\n\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerEventPass.Final\nimport androidx.compose.ui.input.pointer.PointerEventPass.Initial\nimport androidx.compose.ui.input.pointer.PointerEventPass.Main\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.pointerInput\n\n/**\n * Create a modifier for processing pointer motion input within the region of the modified element.\n *\n * After [AwaitPointerEventScope.awaitFirstDown] returned a [PointerInputChange] then\n * [onDown] is called at first pointer contact.\n * Moving any pointer causes [AwaitPointerEventScope.awaitPointerEvent] then [onMove] is called.\n * When last pointer is up [onUp] is called.\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove is invoked when one or multiple pointers are being moved on screen.\n * @param onUp is invoked when last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n *\n * The pointer input handling block will be cancelled and re-started when pointerInput\n * is recomposed with a different [key1].\n */\nfun Modifier.pointerMotionEvents(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (PointerInputChange) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main,\n    key1: Any? = Unit\n) = this.then(\n    Modifier.pointerInput(key1) {\n        detectMotionEvents(\n            onDown,\n            onMove,\n            onUp,\n            delayAfterDownInMillis,\n            requireUnconsumed,\n            pass\n        )\n    }\n)\n\n/**\n * Create a modifier for processing pointer motion input within the region of the modified element.\n *\n * After [AwaitPointerEventScope.awaitFirstDown] returned a [PointerInputChange] then\n * [onDown] is called at first pointer contact.\n * Moving any pointer causes [AwaitPointerEventScope.awaitPointerEvent] then [onMove] is called.\n * When last pointer is up [onUp] is called.\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove is invoked when one or multiple pointers are being moved on screen.\n * @param onUp is invoked when last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n *\n * The pointer input handling block will be cancelled and re-started when pointerInput\n * is recomposed with a different [key1] or [key2].\n */\nfun Modifier.pointerMotionEvents(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (PointerInputChange) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main,\n    key1: Any?,\n    key2: Any?\n) = this.then(\n    Modifier.pointerInput(key1, key2) {\n        detectMotionEvents(\n            onDown,\n            onMove,\n            onUp,\n            delayAfterDownInMillis,\n            requireUnconsumed,\n            pass\n        )\n    }\n)\n\n/**\n * Create a modifier for processing pointer motion input within the region of the modified element.\n *\n * After [AwaitPointerEventScope.awaitFirstDown] returned a [PointerInputChange] then\n * [onDown] is called at first pointer contact.\n * Moving any pointer causes [AwaitPointerEventScope.awaitPointerEvent] then [onMove] is called.\n * When last pointer is up [onUp] is called.\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove is invoked when one or multiple pointers are being moved on screen.\n * @param onUp is invoked when last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n *\n * The pointer input handling block will be cancelled and re-started when pointerInput\n * is recomposed with any different [keys].\n */\nfun Modifier.pointerMotionEvents(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (PointerInputChange) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main,\n    vararg keys: Any?,\n) = this.then(\n    Modifier.pointerInput(*keys) {\n        detectMotionEvents(\n            onDown,\n            onMove,\n            onUp,\n            delayAfterDownInMillis,\n            requireUnconsumed,\n            pass\n        )\n    }\n)\n\n/**\n * Create a modifier for processing pointer motion input within the region of the modified element.\n *\n * After [AwaitPointerEventScope.awaitFirstDown] returned a [PointerInputChange] then\n * [onDown] is called at first pointer contact.\n * Moving any pointer causes [AwaitPointerEventScope.awaitPointerEvent] then [onMove] is called.\n * When last pointer is up [onUp] is called.\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove is invoked when one or multiple pointers are being moved on screen.\n * @param onUp is invoked when last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n *\n *  The pointer input handling block will be cancelled and re-started when pointerInput\n *  is recomposed with a different [key1].\n */\nfun Modifier.pointerMotionEventList(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (List<PointerInputChange>) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main,\n    key1: Any? = Unit\n) = this.then(\n    Modifier.pointerInput(key1) {\n        detectMotionEventsAsList(\n            onDown,\n            onMove,\n            onUp,\n            delayAfterDownInMillis,\n            requireUnconsumed,\n            pass\n        )\n    }\n)\n\n/**\n * Create a modifier for processing pointer motion input within the region of the modified element.\n *\n * After [AwaitPointerEventScope.awaitFirstDown] returned a [PointerInputChange] then\n * [onDown] is called at first pointer contact.\n * Moving any pointer causes [AwaitPointerEventScope.awaitPointerEvent] then [onMove] is called.\n * When last pointer is up [onUp] is called.\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove is invoked when one or multiple pointers are being moved on screen.\n * @param onUp is invoked when last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n *\n * The pointer input handling block will be cancelled and re-started when pointerInput\n * is recomposed with a different [key1] or [key2].\n */\nfun Modifier.pointerMotionEventList(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (List<PointerInputChange>) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main,\n    key1: Any? = Unit,\n    key2: Any? = Unit\n) = this.then(\n    Modifier.pointerInput(key1, key2) {\n        detectMotionEventsAsList(\n            onDown,\n            onMove,\n            onUp,\n            delayAfterDownInMillis,\n            requireUnconsumed,\n            pass\n        )\n    }\n)\n\n/**\n * Create a modifier for processing pointer motion input within the region of the modified element.\n *\n * After [AwaitPointerEventScope.awaitFirstDown] returned a [PointerInputChange] then\n * [onDown] is called at first pointer contact.\n * Moving any pointer causes [AwaitPointerEventScope.awaitPointerEvent] then [onMove] is called.\n * When last pointer is up [onUp] is called.\n *\n * To prevent other pointer functions that call [awaitFirstDown]\n * or [AwaitPointerEventScope.awaitPointerEvent]\n * (scroll, swipe, detect functions)\n * receiving changes call [PointerInputChange.consume]  in [onMove]  or call\n * [PointerInputChange.consume] in [onDown] to prevent events\n * that check first pointer interaction.\n *\n * @param onDown is invoked when first pointer is down initially.\n * @param onMove is invoked when one or multiple pointers are being moved on screen.\n * @param onUp is invoked when last pointer is up\n * @param delayAfterDownInMillis is optional delay after [onDown] This delay might be\n * required Composables like **Canvas** to process [onDown] before [onMove]\n * @param requireUnconsumed is `true` and the first\n * down is consumed in the [PointerEventPass.Main] pass, that gesture is ignored.\n * @param pass The enumeration of passes where [PointerInputChange]\n * traverses up and down the UI tree.\n *\n * PointerInputChanges traverse throw the hierarchy in the following passes:\n *\n * 1. [Initial]: Down the tree from ancestor to descendant.\n * 2. [Main]: Up the tree from descendant to ancestor.\n * 3. [Final]: Down the tree from ancestor to descendant.\n *\n * These passes serve the following purposes:\n *\n * 1. Initial: Allows ancestors to consume aspects of [PointerInputChange] before descendants.\n * This is where, for example, a scroller may block buttons from getting tapped by other fingers\n * once scrolling has started.\n * 2. Main: The primary pass where gesture filters should react to and consume aspects of\n * [PointerInputChange]s. This is the primary path where descendants will interact with\n * [PointerInputChange]s before parents. This allows for buttons to respond to a tap before a\n * container of the bottom to respond to a tap.\n * 3. Final: This pass is where children can learn what aspects of [PointerInputChange]s were\n * consumed by parents during the [Main] pass. For example, this is how a button determines that\n * it should no longer respond to fingers lifting off of it because a parent scroller has\n * consumed movement in a [PointerInputChange].\n *\n * The pointer input handling block will be cancelled and re-started when pointerInput\n * is recomposed with any different [keys].\n */\nfun Modifier.pointerMotionEventList(\n    onDown: (PointerInputChange) -> Unit = {},\n    onMove: (List<PointerInputChange>) -> Unit = {},\n    onUp: (PointerInputChange) -> Unit = {},\n    delayAfterDownInMillis: Long = 0L,\n    requireUnconsumed: Boolean = true,\n    pass: PointerEventPass = Main,\n    vararg keys: Any?\n) = this.then(\n    Modifier.pointerInput(*keys) {\n        detectMotionEventsAsList(\n            onDown,\n            onMove,\n            onUp,\n            delayAfterDownInMillis,\n            requireUnconsumed,\n            pass\n        )\n    }\n)\n"
  },
  {
    "path": "lib/gesture/src/main/java/com/t8rin/gesture/TransformGesture.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.gesture\n\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.gestures.calculateCentroid\nimport androidx.compose.foundation.gestures.calculateCentroidSize\nimport androidx.compose.foundation.gestures.calculatePan\nimport androidx.compose.foundation.gestures.calculateRotation\nimport androidx.compose.foundation.gestures.calculateZoom\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.input.pointer.positionChanged\nimport androidx.compose.ui.util.fastAny\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.isActive\nimport kotlin.coroutines.cancellation.CancellationException\nimport kotlin.math.PI\nimport kotlin.math.abs\n\nenum class PointerRequisite {\n    LessThan, EqualTo, GreaterThan, None\n}\n\n/**\n * A gesture detector for rotation, panning, and zoom. Once touch slop has been reached, the\n * user can use rotation, panning and zoom gestures. [onGesture] will be called when any of the\n * rotation, zoom or pan occurs, passing the rotation angle in degrees, zoom in scale factor and\n * pan as an offset in pixels. Each of these changes is a difference between the previous call\n * and the current gesture. This will consume all position changes after touch slop has\n * been reached. [onGesture] will also provide centroid of all the pointers that are down.\n *\n * After gesture started  when last pointer is up [onGestureEnd] is triggered.\n *\n * @param consume flag consume [PointerInputChange]s this gesture uses. Consuming\n * returns [PointerInputChange.isConsumed] true which is observed by other gestures such\n * as drag, scroll and transform. When this flag is true other gesture don't receive events\n * @param onGestureStart callback for notifying transform gesture has started with initial\n * pointer\n * @param onGesture callback for passing centroid, pan, zoom, rotation and  main pointer and\n * pointer size to caller. Main pointer is the one that touches screen first. If it's lifted\n * next one that is down is the main pointer.\n * @param onGestureEnd callback that notifies last pointer is up and gesture is ended if it's\n * started by fulfilling requisite.\n *\n */\nsuspend fun PointerInputScope.detectTransformGestures(\n    panZoomLock: Boolean = false,\n    consume: Boolean = true,\n    onGestureStart: (PointerInputChange) -> Unit = {},\n    onGesture: (\n        centroid: Offset,\n        pan: Offset,\n        zoom: Float,\n        rotation: Float,\n        mainPointer: PointerInputChange,\n        changes: List<PointerInputChange>\n    ) -> Unit,\n    onGestureEnd: (PointerInputChange) -> Unit = {}\n) {\n    awaitEachGesture {\n        var rotation = 0f\n        var zoom = 1f\n        var pan = Offset.Zero\n        var pastTouchSlop = false\n        val touchSlop = viewConfiguration.touchSlop\n        var lockedToPanZoom = false\n\n\n        // Wait for at least one pointer to press down, and set first contact position\n        val down: PointerInputChange = awaitFirstDown(requireUnconsumed = false)\n        onGestureStart(down)\n\n        var pointer = down\n        // Main pointer is the one that is down initially\n        var pointerId = down.id\n\n        do {\n            val event = awaitPointerEvent()\n\n            // If any position change is consumed from another PointerInputChange\n            // or pointer count requirement is not fulfilled\n            val canceled =\n                event.changes.any { it.isConsumed }\n\n            if (!canceled) {\n\n                // Get pointer that is down, if first pointer is up\n                // get another and use it if other pointers are also down\n                // event.changes.first() doesn't return same order\n                val pointerInputChange =\n                    event.changes.firstOrNull { it.id == pointerId }\n                        ?: event.changes.first()\n\n                // Next time will check same pointer with this id\n                pointerId = pointerInputChange.id\n                pointer = pointerInputChange\n\n                val zoomChange = event.calculateZoom()\n                val rotationChange = event.calculateRotation()\n                val panChange = event.calculatePan()\n\n                if (!pastTouchSlop) {\n                    zoom *= zoomChange\n                    rotation += rotationChange\n                    pan += panChange\n\n                    val centroidSize = event.calculateCentroidSize(useCurrent = false)\n                    val zoomMotion = abs(1 - zoom) * centroidSize\n                    val rotationMotion =\n                        abs(rotation * PI.toFloat() * centroidSize / 180f)\n                    val panMotion = pan.getDistance()\n\n                    if (zoomMotion > touchSlop ||\n                        rotationMotion > touchSlop ||\n                        panMotion > touchSlop\n                    ) {\n                        pastTouchSlop = true\n                        lockedToPanZoom = panZoomLock && rotationMotion < touchSlop\n                    }\n                }\n\n                if (pastTouchSlop) {\n                    val centroid = event.calculateCentroid(useCurrent = false)\n                    val effectiveRotation = if (lockedToPanZoom) 0f else rotationChange\n                    if (effectiveRotation != 0f ||\n                        zoomChange != 1f ||\n                        panChange != Offset.Zero\n                    ) {\n                        onGesture(\n                            centroid,\n                            panChange,\n                            zoomChange,\n                            effectiveRotation,\n                            pointer,\n                            event.changes\n                        )\n                    }\n\n                    if (consume) {\n                        event.changes.forEach {\n                            if (it.positionChanged()) {\n                                it.consume()\n                            }\n                        }\n                    }\n                }\n            }\n        } while (!canceled && event.changes.any { it.pressed })\n        onGestureEnd(pointer)\n    }\n}\n\n/**\n * A gesture detector for rotation, panning, and zoom. Once touch slop has been reached, the\n * user can use rotation, panning and zoom gestures. [onGesture] will be called when any of the\n * rotation, zoom or pan occurs, passing the rotation angle in degrees, zoom in scale factor and\n * pan as an offset in pixels. Each of these changes is a difference between the previous call\n * and the current gesture. This will consume all position changes after touch slop has\n * been reached. [onGesture] will also provide centroid of all the pointers that are down.\n *\n * After gesture started  when last pointer is up [onGestureEnd] is triggered.\n *\n *\n * @param numberOfPointers number of pointer required to be down for gestures to commence. Value\n * of this parameter cannot be lower than 1\n * @param requisite determines whether number of pointer down should be equal to less than or\n * greater than [numberOfPointers] for this gesture.\n * If [PointerRequisite.None] is set [numberOfPointers] is\n * not taken into consideration\n * @param consume flag consume [PointerInputChange]s this gesture uses. Consuming\n * returns [PointerInputChange.isConsumed] true which is observed by other gestures such\n * as drag, scroll and transform. When this flag is true other gesture don't receive events\n * @param onGestureStart callback for notifying transform gesture has started with initial\n * pointer\n * @param onGesture callback for passing centroid, pan, zoom, rotation and pointer size to\n * caller\n * @param onGestureEnd callback that notifies last pointer is up and gesture is ended if it's\n * started by fulfilling requisite.\n *\n */\nsuspend fun PointerInputScope.detectPointerTransformGestures(\n    panZoomLock: Boolean = false,\n    numberOfPointers: Int = 1,\n    requisite: PointerRequisite = PointerRequisite.None,\n    consume: Boolean = true,\n    onGestureStart: (PointerInputChange) -> Unit = {},\n    onGesture:\n        (\n        centroid: Offset,\n        pan: Offset,\n        zoom: Float,\n        rotation: Float,\n        mainPointer: PointerInputChange,\n        changes: List<PointerInputChange>\n    ) -> Unit,\n    onGestureEnd: (PointerInputChange) -> Unit = {},\n    onGestureCancel: () -> Unit = {},\n) {\n\n    require(numberOfPointers > 0)\n\n    awaitEachGesture {\n        var rotation = 0f\n        var zoom = 1f\n        var pan = Offset.Zero\n        var pastTouchSlop = false\n        val touchSlop = viewConfiguration.touchSlop\n        var lockedToPanZoom = false\n\n        var gestureStarted = false\n\n        // Wait for at least one pointer to press down, and set first contact position\n        val down: PointerInputChange = awaitFirstDown(requireUnconsumed = false)\n        onGestureStart(down)\n\n        var pointer = down\n        // Main pointer is the one that is down initially\n        var pointerId = down.id\n\n\n        do {\n            val event = awaitPointerEvent()\n\n            val downPointerCount = event.changes.map {\n                it.pressed\n            }.size\n\n            val requirementFulfilled = when (requisite) {\n                PointerRequisite.LessThan -> {\n                    (downPointerCount < numberOfPointers)\n                }\n\n                PointerRequisite.EqualTo -> {\n                    (downPointerCount == numberOfPointers)\n                }\n\n                PointerRequisite.GreaterThan -> {\n                    (downPointerCount > numberOfPointers)\n                }\n\n                else -> true\n            }\n\n            // If any position change is consumed from another PointerInputChange\n            // or pointer count requirement is not fulfilled\n            val canceled =\n                event.changes.any { it.isConsumed }\n\n            if (!canceled && requirementFulfilled) {\n\n                gestureStarted = true\n                // Get pointer that is down, if first pointer is up\n                // get another and use it if other pointers are also down\n                // event.changes.first() doesn't return same order\n                val pointerInputChange =\n                    event.changes.firstOrNull { it.id == pointerId }\n                        ?: event.changes.first()\n\n                // Next time will check same pointer with this id\n                pointerId = pointerInputChange.id\n                pointer = pointerInputChange\n\n                val zoomChange = event.calculateZoom()\n                val rotationChange = event.calculateRotation()\n                val panChange = event.calculatePan()\n\n                if (!pastTouchSlop) {\n                    zoom *= zoomChange\n                    rotation += rotationChange\n                    pan += panChange\n\n                    val centroidSize = event.calculateCentroidSize(useCurrent = false)\n                    val zoomMotion = abs(1 - zoom) * centroidSize\n                    val rotationMotion =\n                        abs(rotation * PI.toFloat() * centroidSize / 180f)\n                    val panMotion = pan.getDistance()\n\n                    if (zoomMotion > touchSlop ||\n                        rotationMotion > touchSlop ||\n                        panMotion > touchSlop\n                    ) {\n                        pastTouchSlop = true\n                        lockedToPanZoom = panZoomLock && rotationMotion < touchSlop\n                    }\n                }\n\n                if (pastTouchSlop) {\n                    val centroid = event.calculateCentroid(useCurrent = false)\n                    val effectiveRotation = if (lockedToPanZoom) 0f else rotationChange\n                    if (effectiveRotation != 0f ||\n                        zoomChange != 1f ||\n                        panChange != Offset.Zero\n                    ) {\n                        onGesture(\n                            centroid,\n                            panChange,\n                            zoomChange,\n                            effectiveRotation,\n                            pointer,\n                            event.changes\n                        )\n                    }\n\n                    if (consume) {\n                        event.changes.forEach {\n                            if (it.positionChanged()) {\n                                it.consume()\n                            }\n                        }\n                    }\n                }\n            }\n        } while (!canceled && event.changes.any { it.pressed })\n\n        if (gestureStarted) {\n            onGestureEnd(pointer)\n        } else {\n            onGestureCancel()\n        }\n    }\n}\n\n\nfun Modifier.observePointersCountWithOffset(\n    enabled: Boolean = true,\n    onChange: (Int, Offset) -> Unit\n) = this then if (enabled) Modifier.pointerInput(Unit) {\n    onEachGesture {\n        val context = currentCoroutineContext()\n        awaitPointerEventScope {\n            do {\n                val event = awaitPointerEvent()\n                onChange(\n                    event.changes.size,\n                    event.changes.firstOrNull()?.position ?: Offset.Unspecified\n                )\n            } while (event.changes.any { it.pressed } && context.isActive)\n            onChange(0, Offset.Unspecified)\n        }\n    }\n} else Modifier\n\nsuspend fun PointerInputScope.onEachGesture(block: suspend PointerInputScope.() -> Unit) {\n    val currentContext = currentCoroutineContext()\n    while (currentContext.isActive) {\n        try {\n            block()\n\n            // Wait for all pointers to be up. Gestures start when a finger goes down.\n            awaitAllPointersUp()\n        } catch (e: CancellationException) {\n            if (currentContext.isActive) {\n                // The current gesture was canceled. Wait for all fingers to be \"up\" before looping\n                // again.\n                awaitAllPointersUp()\n            } else {\n                // forEachGesture was cancelled externally. Rethrow the cancellation exception to\n                // propagate it upwards.\n                throw e\n            }\n        }\n    }\n}\n\nprivate suspend fun PointerInputScope.awaitAllPointersUp() {\n    awaitPointerEventScope { awaitAllPointersUp() }\n}\n\nprivate suspend fun AwaitPointerEventScope.awaitAllPointersUp() {\n    if (!allPointersUp()) {\n        do {\n            val events = awaitPointerEvent(PointerEventPass.Final)\n        } while (events.changes.fastAny { it.pressed })\n    }\n}\n\nprivate fun AwaitPointerEventScope.allPointersUp(): Boolean =\n    !currentEvent.changes.fastAny { it.pressed }"
  },
  {
    "path": "lib/image/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/image/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.image\"\n\ndependencies {\n    implementation(projects.lib.gesture)\n    implementation(libs.androidx.palette.ktx)\n}"
  },
  {
    "path": "lib/image/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/image/src/main/java/com/t8rin/image/ImageScope.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.image\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntRect\n\n\n/**\n * Receiver scope being used by the children parameter of [ImageWithConstraints]\n */\n@Stable\ninterface ImageScope {\n    /**\n     * The constraints given by the parent layout in pixels.\n     *\n     * Use [minWidth], [maxWidth], [minHeight] or [maxHeight] if you need value in [Dp].\n     */\n    val constraints: Constraints\n\n    /**\n     * The minimum width in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val minWidth: Dp\n\n    /**\n     * The maximum width in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val maxWidth: Dp\n\n    /**\n     * The minimum height in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val minHeight: Dp\n\n    /**\n     * The maximum height in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val maxHeight: Dp\n\n    /**\n     * Width of area inside BoxWithConstraints that is scaled based on [ContentScale]\n     * This is width of the [Canvas] draw [ImageBitmap]\n     */\n    val imageWidth: Dp\n\n    /**\n     * Height of area inside BoxWithConstraints that is scaled based on [ContentScale]\n     * This is height of the [Canvas] draw [ImageBitmap]\n     */\n    val imageHeight: Dp\n\n    /**\n     * [IntRect] that covers boundaries of [ImageBitmap]\n     */\n    val rect: IntRect\n}\n\ninternal data class ImageScopeImpl(\n    private val density: Density,\n    override val constraints: Constraints,\n    override val imageWidth: Dp,\n    override val imageHeight: Dp,\n    override val rect: IntRect,\n) : ImageScope {\n\n    override val minWidth: Dp get() = with(density) { constraints.minWidth.toDp() }\n\n    override val maxWidth: Dp\n        get() = with(density) {\n            if (constraints.hasBoundedWidth) constraints.maxWidth.toDp() else Dp.Infinity\n        }\n\n    override val minHeight: Dp get() = with(density) { constraints.minHeight.toDp() }\n\n    override val maxHeight: Dp\n        get() = with(density) {\n            if (constraints.hasBoundedHeight) constraints.maxHeight.toDp() else Dp.Infinity\n        }\n}"
  },
  {
    "path": "lib/image/src/main/java/com/t8rin/image/ImageWithConstraints.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.image\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.DefaultAlpha\nimport androidx.compose.ui.graphics.FilterQuality\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.contentDescription\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntRect\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.image.util.getParentSize\nimport com.t8rin.image.util.getScaledBitmapRect\n\n\n/**\n * A composable that lays out and draws a given [ImageBitmap]. This will attempt to\n * size the composable according to the [ImageBitmap]'s given width and height. However, an\n * optional [Modifier] parameter can be provided to adjust sizing or draw additional content (ex.\n * background). Any unspecified dimension will leverage the [ImageBitmap]'s size as a minimum\n * constraint.\n *\n * [ImageScope] returns constraints, width and height of the drawing area based on [contentScale]\n * and rectangle of [imageBitmap] drawn. When a bitmap is displayed scaled to fit area of Composable\n * space used for drawing image is represented with [ImageScope.imageWidth] and\n * [ImageScope.imageHeight].\n *\n * When we display a bitmap 1000x1000px with [ContentScale.Crop] if it's cropped to 500x500px\n * [ImageScope.rect] returns `IntRect(250,250,750,750)`.\n *\n * @param alignment determines where image will be aligned inside [BoxWithConstraints]\n * This is observable when bitmap image/width ratio differs from [Canvas] that draws [ImageBitmap]\n * @param contentDescription text used by accessibility services to describe what this image\n * represents. This should always be provided unless this image is used for decorative purposes,\n * and does not represent a meaningful action that a user can take. This text should be\n * localized, such as by using [androidx.compose.ui.res.stringResource] or similar\n * @param contentScale how image should be scaled inside Canvas to match parent dimensions.\n * [ContentScale.Fit] for instance maintains src ratio and scales image to fit inside the parent.\n * @param alpha Opacity to be applied to [imageBitmap] from 0.0f to 1.0f representing\n * fully transparent to fully opaque respectively\n * @param colorFilter ColorFilter to apply to the [imageBitmap] when drawn into the destination\n * @param filterQuality Sampling algorithm applied to the [imageBitmap] when it is scaled and drawn\n * into the destination. The default is [FilterQuality.Low] which scales using a bilinear\n * sampling algorithm\n * @param content is a Composable that can be matched at exact position where [imageBitmap] is drawn.\n * This is useful for drawing thumbs, cropping or another layout that should match position\n * with the image that is scaled is drawn\n * @param drawImage flag to draw image on canvas. Some Composables might only require\n * the calculation and rectangle bounds of image after scaling but not drawing.\n * Composables like image cropper that scales or\n * rotates image. Drawing here again have 2 drawings overlap each other.\n */\n@Composable\nfun ImageWithConstraints(\n    modifier: Modifier = Modifier,\n    imageBitmap: ImageBitmap,\n    alignment: Alignment = Alignment.Center,\n    contentScale: ContentScale = ContentScale.Fit,\n    contentDescription: String? = null,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    drawImage: Boolean = true,\n    content: @Composable ImageScope.() -> Unit = {}\n) {\n\n    val semantics = if (contentDescription != null) {\n        Modifier.semantics {\n            this.contentDescription = contentDescription\n            this.role = Role.Image\n        }\n    } else {\n        Modifier\n    }\n\n    BoxWithConstraints(\n        modifier = modifier\n            .then(semantics),\n        contentAlignment = alignment,\n    ) {\n\n        val bitmapWidth = imageBitmap.width\n        val bitmapHeight = imageBitmap.height\n\n        val (boxWidth: Int, boxHeight: Int) = getParentSize(bitmapWidth, bitmapHeight)\n\n        // Src is Bitmap, Dst is the container(Image) that Bitmap will be displayed\n        val srcSize = Size(bitmapWidth.toFloat(), bitmapHeight.toFloat())\n        val dstSize = Size(boxWidth.toFloat(), boxHeight.toFloat())\n\n        val scaleFactor = contentScale.computeScaleFactor(srcSize, dstSize)\n\n        // Image is the container for bitmap that is located inside Box\n        // image bounds can be smaller or bigger than its parent based on how it's scaled\n        val imageWidth = bitmapWidth * scaleFactor.scaleX\n        val imageHeight = bitmapHeight * scaleFactor.scaleY\n\n        val bitmapRect = getScaledBitmapRect(\n            boxWidth = boxWidth,\n            boxHeight = boxHeight,\n            imageWidth = imageWidth,\n            imageHeight = imageHeight,\n            bitmapWidth = bitmapWidth,\n            bitmapHeight = bitmapHeight\n        )\n\n        ImageLayout(\n            constraints = constraints,\n            imageBitmap = imageBitmap,\n            bitmapRect = bitmapRect,\n            imageWidth = imageWidth,\n            imageHeight = imageHeight,\n            boxWidth = boxWidth,\n            boxHeight = boxHeight,\n            alpha = alpha,\n            colorFilter = colorFilter,\n            filterQuality = filterQuality,\n            drawImage = drawImage,\n            content = content\n        )\n    }\n}\n\n@Composable\nprivate fun ImageLayout(\n    constraints: Constraints,\n    imageBitmap: ImageBitmap,\n    bitmapRect: IntRect,\n    imageWidth: Float,\n    imageHeight: Float,\n    boxWidth: Int,\n    boxHeight: Int,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    drawImage: Boolean = true,\n    content: @Composable ImageScope.() -> Unit\n) {\n    val density = LocalDensity.current\n\n    // Dimensions of canvas that will draw this Bitmap\n    val canvasWidthInDp: Dp\n    val canvasHeightInDp: Dp\n\n    with(density) {\n        canvasWidthInDp = imageWidth.coerceAtMost(boxWidth.toFloat()).toDp()\n        canvasHeightInDp = imageHeight.coerceAtMost(boxHeight.toFloat()).toDp()\n    }\n\n    // Send rectangle of Bitmap drawn to Canvas as bitmapRect, content scale modes like\n    // crop might crop image from center so Rect can be such as IntRect(250,250,500,500)\n\n    // canvasWidthInDp, and  canvasHeightInDp are Canvas dimensions coerced to Box size\n    // that covers Canvas\n    val imageScopeImpl = ImageScopeImpl(\n        density = density,\n        constraints = constraints,\n        imageWidth = canvasWidthInDp,\n        imageHeight = canvasHeightInDp,\n        rect = bitmapRect\n    )\n\n    // width and height params for translating draw position if scaled Image dimensions are\n    // bigger than Canvas dimensions\n    if (drawImage) {\n        ImageImpl(\n            modifier = Modifier.size(canvasWidthInDp, canvasHeightInDp),\n            imageBitmap = imageBitmap,\n            alpha = alpha,\n            width = imageWidth.toInt(),\n            height = imageHeight.toInt(),\n            colorFilter = colorFilter,\n            filterQuality = filterQuality\n        )\n    }\n\n    imageScopeImpl.content()\n}\n\n@Composable\nprivate fun ImageImpl(\n    modifier: Modifier,\n    imageBitmap: ImageBitmap,\n    width: Int,\n    height: Int,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n) {\n    val bitmapWidth = imageBitmap.width\n    val bitmapHeight = imageBitmap.height\n\n    Canvas(modifier = modifier.clipToBounds()) {\n\n        val canvasWidth = size.width.toInt()\n        val canvasHeight = size.height.toInt()\n\n        // Translate to left or down when Image size is bigger than this canvas.\n        // ImageSize is bigger when scale modes like Crop is used which enlarges image\n        // For instance 1000x1000 image can be 1000x2000 for a Canvas with 1000x1000\n        // so top is translated -500 to draw center of ImageBitmap\n        translate(\n            top = (-height + canvasHeight) / 2f,\n            left = (-width + canvasWidth) / 2f,\n\n            ) {\n            drawImage(\n                imageBitmap,\n                srcSize = IntSize(bitmapWidth, bitmapHeight),\n                dstSize = IntSize(width, height),\n                alpha = alpha,\n                colorFilter = colorFilter,\n                filterQuality = filterQuality\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "lib/image/src/main/java/com/t8rin/image/util/ImageContentScaleUtil.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.image.util\n\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.BoxWithConstraintsScope\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.IntRect\nimport androidx.compose.ui.unit.IntSize\n\n/**\n * Get Rectangle of [ImageBitmap] with [bitmapWidth] and [bitmapHeight] that is drawn inside\n * Canvas with [imageWidth] and [imageHeight]. [boxWidth] and [boxHeight] belong\n * to [BoxWithConstraints] that contains Canvas.\n *  @param boxWidth width of the parent container\n *  @param boxHeight height of the parent container\n *  @param imageWidth width of the [Canvas] that draws [ImageBitmap]\n *  @param imageHeight height of the [Canvas] that draws [ImageBitmap]\n *  @param bitmapWidth intrinsic width of the [ImageBitmap]\n *  @param bitmapHeight intrinsic height of the [ImageBitmap]\n *  @return [IntRect] that covers [ImageBitmap] bounds. When image [ContentScale] is crop\n *  this rectangle might return smaller rectangle than actual [ImageBitmap] and left or top\n *  of the rectangle might be bigger than zero.\n */\ninternal fun getScaledBitmapRect(\n    boxWidth: Int,\n    boxHeight: Int,\n    imageWidth: Float,\n    imageHeight: Float,\n    bitmapWidth: Int,\n    bitmapHeight: Int\n): IntRect {\n    // Get scale of box to width of the image\n    // We need a rect that contains Bitmap bounds to pass if any child requires it\n    // For a image with 100x100 px with 300x400 px container and image with crop 400x400px\n    // So we need to pass top left as 0,50 and size\n    val scaledBitmapX = boxWidth / imageWidth\n    val scaledBitmapY = boxHeight / imageHeight\n\n    val topLeft = IntOffset(\n        x = (bitmapWidth * (imageWidth - boxWidth) / imageWidth / 2)\n            .coerceAtLeast(0f).toInt(),\n        y = (bitmapHeight * (imageHeight - boxHeight) / imageHeight / 2)\n            .coerceAtLeast(0f).toInt()\n    )\n\n    val size = IntSize(\n        width = (bitmapWidth * scaledBitmapX).toInt().coerceAtMost(bitmapWidth),\n        height = (bitmapHeight * scaledBitmapY).toInt().coerceAtMost(bitmapHeight)\n    )\n\n    return IntRect(offset = topLeft, size = size)\n}\n\n/**\n * Get [IntSize] of the parent or container that contains [Canvas] that draws [ImageBitmap]\n *  @param bitmapWidth intrinsic width of the [ImageBitmap]\n *  @param bitmapHeight intrinsic height of the [ImageBitmap]\n *  @return size of parent Composable. When Modifier is assigned with fixed or finite size\n *  they are used, but when any dimension is set to infinity intrinsic dimensions of\n *  [ImageBitmap] are returned\n */\ninternal fun BoxWithConstraintsScope.getParentSize(\n    bitmapWidth: Int,\n    bitmapHeight: Int\n): IntSize {\n    // Check if Composable has fixed size dimensions\n    val hasBoundedDimens = constraints.hasBoundedWidth && constraints.hasBoundedHeight\n    // Check if Composable has infinite dimensions\n    val hasFixedDimens = constraints.hasFixedWidth && constraints.hasFixedHeight\n\n    // Box is the parent(BoxWithConstraints) that contains Canvas under the hood\n    // Canvas aspect ratio or size might not match parent but it's upper bounds are\n    // what are passed from parent. Canvas cannot be bigger or taller than BoxWithConstraints\n    val boxWidth: Int = if (hasBoundedDimens || hasFixedDimens) {\n        constraints.maxWidth\n    } else {\n        constraints.minWidth.coerceAtLeast(bitmapWidth)\n    }\n    val boxHeight: Int = if (hasBoundedDimens || hasFixedDimens) {\n        constraints.maxHeight\n    } else {\n        constraints.minHeight.coerceAtLeast(bitmapHeight)\n    }\n    return IntSize(boxWidth, boxHeight)\n}\n"
  },
  {
    "path": "lib/modalsheet/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/modalsheet/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.modalsheet\"\n\ndependencies {\n    implementation(libs.lifecycle.viewmodel)\n}\n"
  },
  {
    "path": "lib/modalsheet/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest package=\"com.t8rin.modalsheet\" />\n"
  },
  {
    "path": "lib/modalsheet/src/main/java/com/t8rin/modalsheet/FullscreenPopup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.modalsheet\n\nimport android.annotation.SuppressLint\nimport android.app.Activity\nimport android.content.Context\nimport android.content.ContextWrapper\nimport android.view.KeyEvent\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionContext\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCompositionContext\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.R\nimport androidx.compose.ui.platform.AbstractComposeView\nimport androidx.compose.ui.platform.LocalView\nimport androidx.compose.ui.platform.ViewRootForInspector\nimport androidx.compose.ui.semantics.popup\nimport androidx.compose.ui.semantics.semantics\nimport androidx.core.view.children\nimport androidx.lifecycle.findViewTreeLifecycleOwner\nimport androidx.lifecycle.findViewTreeViewModelStoreOwner\nimport androidx.lifecycle.setViewTreeLifecycleOwner\nimport androidx.lifecycle.setViewTreeViewModelStoreOwner\nimport androidx.savedstate.findViewTreeSavedStateRegistryOwner\nimport androidx.savedstate.setViewTreeSavedStateRegistryOwner\nimport java.util.UUID\n\n/**\n * Opens a popup with the given content.\n * The popup is visible as long as it is part of the composition hierarchy.\n *\n * Note: This is highly reduced version of the official Popup composable with some changes:\n * * Fixes an issue with action mode (copy-paste) menu, see https://issuetracker.google.com/issues/216662636\n * * Adds the view to the decor view of the window, instead of the window itself.\n * * Do not have properties, as Popup is laid out as fullscreen.\n *\n * @param onDismiss Executes when the user clicks outside of the popup.\n * @param content The content to be displayed inside the popup.\n */\n@Composable\nfun FullscreenPopup(\n    onDismiss: (() -> Unit)? = null,\n    placeAboveAll: Boolean = false,\n    content: @Composable () -> Unit\n) {\n    val view = LocalView.current\n    val parentComposition = rememberCompositionContext()\n    val currentContent by rememberUpdatedState(content)\n    val popupId = rememberSaveable { UUID.randomUUID() }\n    val popupLayout = remember {\n        PopupLayout(\n            onDismiss = onDismiss,\n            composeView = view,\n            popupId = popupId,\n            placeAboveAll = placeAboveAll\n        ).apply {\n            setContent(parentComposition) {\n                Box(Modifier.semantics { this.popup() }) {\n                    currentContent()\n                }\n            }\n        }\n    }\n\n    DisposableEffect(popupLayout) {\n        popupLayout.show()\n        popupLayout.updateParameters(\n            onDismiss = onDismiss,\n            placeAboveAll = placeAboveAll\n        )\n        onDispose {\n            popupLayout.disposeComposition()\n            // Remove the window\n            popupLayout.dismiss()\n        }\n    }\n\n    SideEffect {\n        popupLayout.updateParameters(\n            onDismiss = onDismiss,\n            placeAboveAll = placeAboveAll\n        )\n    }\n}\n\n/**\n * The layout the popup uses to display its content.\n */\n@SuppressLint(\"ViewConstructor\")\nprivate class PopupLayout(\n    private var onDismiss: (() -> Unit)?,\n    composeView: View,\n    popupId: UUID,\n    private var placeAboveAll: Boolean\n) : AbstractComposeView(composeView.context), ViewRootForInspector {\n\n    private val ABOVE_ALL_Z = Float.MAX_VALUE\n\n    private val decorView = findOwner<Activity>(composeView.context)?.window?.decorView as ViewGroup\n\n    override val subCompositionView: AbstractComposeView get() = this\n\n    init {\n        id = android.R.id.content\n        setViewTreeLifecycleOwner(composeView.findViewTreeLifecycleOwner())\n        setViewTreeViewModelStoreOwner(composeView.findViewTreeViewModelStoreOwner())\n        setViewTreeSavedStateRegistryOwner(composeView.findViewTreeSavedStateRegistryOwner())\n        // Set unique id for AbstractComposeView. This allows state restoration for the state\n        // defined inside the Popup via rememberSaveable()\n        setTag(R.id.compose_view_saveable_id_tag, \"Popup:$popupId\")\n        setTag(R.id.consume_window_insets_tag, false)\n    }\n\n    private var content: @Composable () -> Unit by mutableStateOf({})\n\n    override var shouldCreateCompositionOnAttachedToWindow: Boolean = false\n        private set\n\n    fun show() {\n        // Place popup above all current views\n        var placeAboveAllView: View? = null\n        val topView = decorView.children.maxBy {\n            if (it.z == ABOVE_ALL_Z) {\n                placeAboveAllView = it\n                -ABOVE_ALL_Z\n            } else it.z\n        }\n\n        z = if (placeAboveAll) ABOVE_ALL_Z\n        else topView.z + 1\n\n        decorView.addView(\n            this,\n            0,\n            MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)\n        )\n\n        placeAboveAllView?.bringToFront()\n        (decorView as View).invalidate()\n\n        requestFocus()\n    }\n\n    fun setContent(parent: CompositionContext, content: @Composable () -> Unit) {\n        setParentCompositionContext(parent)\n        this.content = content\n        shouldCreateCompositionOnAttachedToWindow = true\n    }\n\n    @Composable\n    override fun Content() {\n        content()\n    }\n\n    @Suppress(\"ReturnCount\")\n    override fun dispatchKeyEvent(event: KeyEvent): Boolean {\n        if (event.keyCode == KeyEvent.KEYCODE_BACK && onDismiss != null) {\n            if (keyDispatcherState == null) {\n                return super.dispatchKeyEvent(event)\n            }\n            if (event.action == KeyEvent.ACTION_DOWN && event.repeatCount == 0) {\n                val state = keyDispatcherState\n                state?.startTracking(event, this)\n                return true\n            } else if (event.action == KeyEvent.ACTION_UP) {\n                val state = keyDispatcherState\n                if (state != null && state.isTracking(event) && !event.isCanceled) {\n                    onDismiss?.invoke()\n                    return true\n                }\n            }\n        }\n        return super.dispatchKeyEvent(event)\n    }\n\n    fun updateParameters(\n        onDismiss: (() -> Unit)?,\n        placeAboveAll: Boolean\n    ) {\n        this.onDismiss = onDismiss\n        this.placeAboveAll = placeAboveAll\n    }\n\n    fun dismiss() {\n        setViewTreeLifecycleOwner(null)\n        decorView.removeView(this)\n    }\n}\n\nprivate inline fun <reified T> findOwner(context: Context): T? {\n    var innerContext = context\n    while (innerContext is ContextWrapper) {\n        if (innerContext is T) {\n            return innerContext\n        }\n        innerContext = innerContext.baseContext\n    }\n    return null\n}\n"
  },
  {
    "path": "lib/modalsheet/src/main/java/com/t8rin/modalsheet/ModalSheet.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.modalsheet\n\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.material3.BottomSheetDefaults\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.zIndex\n\n\n/**\n * Modal sheet that behaves like bottom sheet and draws over system UI.\n * Should be used on with the content which is not dependent on the outer data. For dynamic content use [ModalSheet]\n * overload with a 'data' parameter.\n *\n * @param visible True if modal should be visible.\n * @param onVisibleChange Called when visibility changes.\n * @param cancelable When true, this modal sheet can be closed with swipe gesture, tap on scrim or tap on hardware back\n * button. Note: passing 'false' does not disable the interaction with the sheet. Only the resulting state after the\n * sheet settles.\n * @param shape The shape of the bottom sheet.\n * @param elevation The elevation of the bottom sheet.\n * @param containerColor The background color of the bottom sheet.\n * @param contentColor The preferred content color provided by the bottom sheet to its\n * children. Defaults to the matching content color for [containerColor], or if that is not\n * a color from the theme, this will keep the same content color set above the bottom sheet.\n * @param scrimColor The color of the scrim that is applied to the rest of the screen when the\n * bottom sheet is visible. If the color passed is [Color.Unspecified], then a scrim will no\n * longer be applied and the bottom sheet will not block interaction with the rest of the screen\n * when visible.\n * @param content The content of the bottom sheet.\n */\n@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)\n@Composable\nfun ModalSheet(\n    visible: Boolean,\n    onVisibleChange: (Boolean) -> Unit,\n    modifier: Modifier = Modifier,\n    dragHandle: @Composable ColumnScope.() -> Unit = {\n        Row(\n            modifier = Modifier.fillMaxWidth(),\n            horizontalArrangement = Arrangement.Center\n        ) {\n            BottomSheetDefaults.DragHandle()\n        }\n    },\n    nestedScrollEnabled: Boolean = false,\n    animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,\n    sheetModifier: Modifier = Modifier,\n    cancelable: Boolean = true,\n    skipHalfExpanded: Boolean = true,\n    shape: Shape = BottomSheetDefaults.ExpandedShape,\n    elevation: Dp = BottomSheetDefaults.Elevation,\n    containerColor: Color = BottomSheetDefaults.ContainerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    scrimColor: Color = BottomSheetDefaults.ScrimColor,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    // Hold cancelable flag internally and set to true when modal sheet is dismissed via \"visible\" property in\n    // non-cancellable modal sheet. This ensures that \"confirmValueChange\" will return true when sheet is set to hidden\n    // state.\n    val internalCancelable = remember { mutableStateOf(cancelable) }\n    val sheetState = rememberModalBottomSheetState(\n        skipHalfExpanded = skipHalfExpanded,\n        initialValue = ModalBottomSheetValue.Hidden,\n        animationSpec = animationSpec,\n        confirmValueChange = {\n            // Intercept and disallow hide gesture / action\n            if (it == ModalBottomSheetValue.Hidden && !internalCancelable.value) {\n                return@rememberModalBottomSheetState false\n            }\n            true\n        },\n    )\n\n    LaunchedEffect(visible, cancelable) {\n        if (visible) {\n            internalCancelable.value = cancelable\n            sheetState.show()\n        } else {\n            internalCancelable.value = true\n            sheetState.hide()\n        }\n    }\n\n    LaunchedEffect(sheetState.currentValue, sheetState.targetValue, sheetState.progress) {\n        if (sheetState.progress == 1f && sheetState.currentValue == sheetState.targetValue) {\n            val newVisible = sheetState.isVisible\n            if (newVisible != visible) {\n                onVisibleChange(newVisible)\n            }\n        }\n    }\n\n    if (!visible && sheetState.currentValue == sheetState.targetValue && !sheetState.isVisible) {\n        return\n    }\n\n    ModalSheet(\n        sheetState = sheetState,\n        onDismiss = {\n            if (cancelable) {\n                onVisibleChange(false)\n            }\n        },\n        dragHandle = dragHandle,\n        nestedScrollEnabled = nestedScrollEnabled,\n        sheetModifier = sheetModifier,\n        modifier = modifier,\n        shape = shape,\n        elevation = elevation,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        scrimColor = scrimColor,\n        content = content,\n    )\n}\n\n/**\n * Modal sheet that behaves like bottom sheet and draws over system UI.\n * Takes [ModalSheetState] as parameter to fine-tune sheet behavior.\n *\n * Note: In this case [ModalSheet] is always added to the composition. See [ModalSheet] overload with visible parameter,\n * or data object to conditionally add / remove modal sheet to / from the composition.\n *\n * @param sheetState The state of the underlying Material bottom sheet.\n * @param onDismiss Called when user taps on the hardware back button.\n * @param shape The shape of the bottom sheet.\n * @param elevation The elevation of the bottom sheet.\n * @param containerColor The background color of the bottom sheet.\n * @param contentColor The preferred content color provided by the bottom sheet to its\n * children. Defaults to the matching content color for [containerColor], or if that is not\n * a color from the theme, this will keep the same content color set above the bottom sheet.\n * @param scrimColor The color of the scrim that is applied to the rest of the screen when the\n * bottom sheet is visible. If the color passed is [Color.Unspecified], then a scrim will no\n * longer be applied and the bottom sheet will not block interaction with the rest of the screen\n * when visible.\n * @param content The content of the bottom sheet.\n */\n@ExperimentalMaterial3Api\n@Composable\nfun ModalSheet(\n    modifier: Modifier = Modifier,\n    sheetModifier: Modifier = Modifier,\n    dragHandle: @Composable ColumnScope.() -> Unit = {\n        Row(\n            modifier = Modifier.fillMaxWidth(),\n            horizontalArrangement = Arrangement.Center\n        ) {\n            BottomSheetDefaults.DragHandle()\n        }\n    },\n    sheetState: ModalSheetState,\n    onDismiss: (() -> Unit)?,\n    nestedScrollEnabled: Boolean = false,\n    shape: Shape = BottomSheetDefaults.ExpandedShape,\n    elevation: Dp = BottomSheetDefaults.Elevation,\n    containerColor: Color = BottomSheetDefaults.ContainerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    scrimColor: Color = BottomSheetDefaults.ScrimColor,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    FullscreenPopup(\n        onDismiss = onDismiss,\n    ) {\n        Box(Modifier.fillMaxSize()) {\n            ModalSheetLayout(\n                nestedScrollEnabled = nestedScrollEnabled,\n                sheetModifier = sheetModifier,\n                dragHandle = {\n                    Column(Modifier.zIndex(100f)) {\n                        dragHandle()\n                    }\n                },\n                modifier = modifier.align(Alignment.BottomCenter),\n                sheetState = sheetState,\n                sheetShape = shape,\n                sheetElevation = elevation,\n                sheetContainerColor = containerColor,\n                sheetContentColor = contentColor,\n                scrimColor = scrimColor,\n                sheetContent = {\n                    Column(Modifier.zIndex(-100f)) {\n                        content()\n                    }\n                },\n                content = {}\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "lib/modalsheet/src/main/java/com/t8rin/modalsheet/ModalSheetLayout.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.modalsheet\n\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.SpringSpec\nimport androidx.compose.animation.core.TweenSpec\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxWithConstraints\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.material.Surface\nimport androidx.compose.material.contentColorFor\nimport androidx.compose.material3.BottomSheetDefaults\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.isSpecified\nimport androidx.compose.ui.input.nestedscroll.NestedScrollConnection\nimport androidx.compose.ui.input.nestedscroll.NestedScrollSource\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.semantics.collapse\nimport androidx.compose.ui.semantics.dismiss\nimport androidx.compose.ui.semantics.expand\nimport androidx.compose.ui.semantics.onClick\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.Velocity\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.modalsheet.ModalBottomSheetValue.Expanded\nimport com.t8rin.modalsheet.ModalBottomSheetValue.HalfExpanded\nimport com.t8rin.modalsheet.ModalBottomSheetValue.Hidden\nimport com.t8rin.modalsheet.ModalSheetState.Companion.Saver\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.launch\nimport kotlin.math.max\nimport kotlin.math.roundToInt\n\n\nenum class ModalBottomSheetValue {\n    /**\n     * The bottom sheet is not visible.\n     */\n    Hidden,\n\n    /**\n     * The bottom sheet is visible at full height.\n     */\n    Expanded,\n\n    /**\n     * The bottom sheet is partially visible at 50% of the screen height. This state is only\n     * enabled if the height of the bottom sheet is more than 50% of the screen height.\n     */\n    HalfExpanded\n}\n\n\n/**\n * State of the [ModalSheetLayout] composable.\n *\n * @param initialValue The initial value of the state. <b>Must not be set to\n * [ModalBottomSheetValue.HalfExpanded] if [isSkipHalfExpanded] is set to true.</b>\n * @param animationSpec The default animation that will be used to animate to a new state.\n * @param isSkipHalfExpanded Whether the half expanded state, if the sheet is tall enough, should\n * be skipped. If true, the sheet will always expand to the [Expanded] state and move to the\n * [Hidden] state when hiding the sheet, either programmatically or by user interaction.\n * <b>Must not be set to true if the initialValue is [ModalBottomSheetValue.HalfExpanded].</b>\n * If supplied with [ModalBottomSheetValue.HalfExpanded] for the initialValue, an\n * [IllegalArgumentException] will be thrown.\n * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.\n */\n@ExperimentalMaterial3Api\n@OptIn(ExperimentalMaterialApi::class)\nclass ModalSheetState(\n    initialValue: ModalBottomSheetValue,\n    animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,\n    confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },\n    val isSkipHalfExpanded: Boolean = false\n) {\n\n    val swipeableState = SwipeableV2State(\n        initialValue = initialValue,\n        animationSpec = animationSpec,\n        confirmValueChange = confirmValueChange,\n        positionalThreshold = PositionalThreshold,\n        velocityThreshold = VelocityThreshold\n    )\n\n    val currentValue: ModalBottomSheetValue\n        get() = swipeableState.currentValue\n\n    val targetValue: ModalBottomSheetValue\n        get() = swipeableState.targetValue\n\n    val progress: Float\n        get() = swipeableState.progress\n\n    /**\n     * Whether the bottom sheet is visible.\n     */\n    val isVisible: Boolean\n        get() = swipeableState.currentValue != Hidden\n\n    val hasHalfExpandedState: Boolean\n        get() = swipeableState.hasAnchorForValue(HalfExpanded)\n\n    init {\n        if (isSkipHalfExpanded) {\n            require(initialValue != HalfExpanded) {\n                \"The initial value must not be set to HalfExpanded if skipHalfExpanded is set to\" +\n                        \" true.\"\n            }\n        }\n    }\n\n    /**\n     * Show the bottom sheet with animation and suspend until it's shown. If the sheet is taller\n     * than 50% of the parent's height, the bottom sheet will be half expanded. Otherwise it will be\n     * fully expanded.\n     *\n     * @throws [CancellationException] if the animation is interrupted\n     */\n    suspend fun show() {\n        val targetValue = when {\n            hasHalfExpandedState -> HalfExpanded\n            else -> Expanded\n        }\n        animateTo(targetValue)\n    }\n\n    /**\n     * Half expand the bottom sheet if half expand is enabled with animation and suspend until it\n     * animation is complete or cancelled\n     *\n     * @throws [CancellationException] if the animation is interrupted\n     */\n    suspend fun halfExpand() {\n        if (!hasHalfExpandedState) {\n            return\n        }\n        animateTo(HalfExpanded)\n    }\n\n    /**\n     * Fully expand the bottom sheet with animation and suspend until it if fully expanded or\n     * animation has been cancelled.\n     * *\n     * @throws [CancellationException] if the animation is interrupted\n     */\n    suspend fun expand() {\n        if (!swipeableState.hasAnchorForValue(Expanded)) {\n            return\n        }\n        animateTo(Expanded)\n    }\n\n    /**\n     * Hide the bottom sheet with animation and suspend until it if fully hidden or animation has\n     * been canceled.\n     *\n     * @throws [CancellationException] if the animation is interrupted\n     */\n    suspend fun hide() = animateTo(Hidden)\n\n    suspend fun animateTo(\n        target: ModalBottomSheetValue,\n        velocity: Float = swipeableState.lastVelocity\n    ) = swipeableState.animateTo(target, velocity)\n\n    suspend fun snapTo(target: ModalBottomSheetValue) = swipeableState.snapTo(target)\n\n    fun requireOffset() = swipeableState.requireOffset()\n\n    val lastVelocity: Float get() = swipeableState.lastVelocity\n\n    val isAnimationRunning: Boolean get() = swipeableState.isAnimationRunning\n\n    companion object {\n        /**\n         * The default [Saver] implementation for [ModalSheetState].\n         * Saves the [currentValue] and recreates a [ModalSheetState] with the saved value as\n         * initial value.\n         */\n        fun Saver(\n            animationSpec: AnimationSpec<Float>,\n            confirmValueChange: (ModalBottomSheetValue) -> Boolean,\n            skipHalfExpanded: Boolean,\n        ): Saver<ModalSheetState, *> = Saver(\n            save = { it.currentValue },\n            restore = {\n                ModalSheetState(\n                    initialValue = it,\n                    animationSpec = animationSpec,\n                    isSkipHalfExpanded = skipHalfExpanded,\n                    confirmValueChange = confirmValueChange\n                )\n            }\n        )\n    }\n}\n\n/**\n * Create a [ModalSheetState] and [remember] it.\n *\n * @param initialValue The initial value of the state.\n * @param animationSpec The default animation that will be used to animate to a new state.\n * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.\n * @param skipHalfExpanded Whether the half expanded state, if the sheet is tall enough, should\n * be skipped. If true, the sheet will always expand to the [Expanded] state and move to the\n * [Hidden] state when hiding the sheet, either programmatically or by user interaction.\n * <b>Must not be set to true if the [initialValue] is [ModalBottomSheetValue.HalfExpanded].</b>\n * If supplied with [ModalBottomSheetValue.HalfExpanded] for the [initialValue], an\n * [IllegalArgumentException] will be thrown.\n */\n@OptIn(ExperimentalMaterialApi::class)\n@ExperimentalMaterial3Api\n@Composable\nfun rememberModalBottomSheetState(\n    initialValue: ModalBottomSheetValue,\n    animationSpec: AnimationSpec<Float> = SpringSpec(),\n    confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },\n    skipHalfExpanded: Boolean = false,\n): ModalSheetState {\n    // Key the rememberSaveable against the initial value. If it changed we don't want to attempt\n    // to restore as the restored value could have been saved with a now invalid set of anchors.\n    // b/152014032\n    return key(initialValue) {\n        rememberSaveable(\n            initialValue, animationSpec, skipHalfExpanded, confirmValueChange,\n            saver = Saver(\n                animationSpec = animationSpec,\n                skipHalfExpanded = skipHalfExpanded,\n                confirmValueChange = confirmValueChange\n            )\n        ) {\n            ModalSheetState(\n                initialValue = initialValue,\n                animationSpec = animationSpec,\n                isSkipHalfExpanded = skipHalfExpanded,\n                confirmValueChange = confirmValueChange\n            )\n        }\n    }\n}\n\n/**\n * <a href=\"https://material.io/components/sheets-bottom#modal-bottom-sheet\" class=\"external\" target=\"_blank\">Material Design modal bottom sheet</a>.\n *\n * Modal bottom sheets present a set of choices while blocking interaction with the rest of the\n * screen. They are an alternative to inline menus and simple dialogs, providing\n * additional room for content, iconography, and actions.\n *\n * ![Modal bottom sheet image](https://developer.android.com/images/reference/androidx/compose/material/modal-bottom-sheet.png)\n *\n * A simple example of a modal bottom sheet looks like this:\n *\n *\n * @param sheetContent The content of the bottom sheet.\n * @param modifier Optional [Modifier] for the entire component.\n * @param sheetState The state of the bottom sheet.\n * @param sheetShape The shape of the bottom sheet.\n * @param sheetElevation The elevation of the bottom sheet.\n * @param sheetContainerColor The background color of the bottom sheet.\n * @param sheetContentColor The preferred content color provided by the bottom sheet to its\n * children. Defaults to the matching content color for [sheetContainerColor], or if that is not\n * a color from the theme, this will keep the same content color set above the bottom sheet.\n * @param scrimColor The color of the scrim that is applied to the rest of the screen when the\n * bottom sheet is visible. If the color passed is [Color.Unspecified], then a scrim will no\n * longer be applied and the bottom sheet will not block interaction with the rest of the screen\n * when visible.\n * @param content The content of rest of the screen.\n */\n@OptIn(ExperimentalMaterialApi::class)\n@ExperimentalMaterial3Api\n@Composable\nfun ModalSheetLayout(\n    sheetContent: @Composable ColumnScope.() -> Unit,\n    modifier: Modifier = Modifier,\n    dragHandle: @Composable ColumnScope.() -> Unit = {\n        Row(\n            modifier = Modifier.fillMaxWidth(),\n            horizontalArrangement = Arrangement.Center\n        ) {\n            BottomSheetDefaults.DragHandle()\n        }\n    },\n    nestedScrollEnabled: Boolean = true,\n    sheetModifier: Modifier = Modifier,\n    sheetState: ModalSheetState = rememberModalBottomSheetState(Hidden),\n    sheetShape: Shape = BottomSheetDefaults.ExpandedShape,\n    sheetElevation: Dp = BottomSheetDefaults.Elevation,\n    sheetContainerColor: Color = BottomSheetDefaults.ContainerColor,\n    sheetContentColor: Color = contentColorFor(sheetContainerColor),\n    scrimColor: Color = BottomSheetDefaults.ScrimColor,\n    content: @Composable () -> Unit\n) {\n    val scope = rememberCoroutineScope()\n    val orientation = Orientation.Vertical\n    val anchorChangeHandler = remember(sheetState, scope) {\n        ModalBottomSheetAnchorChangeHandler(\n            state = sheetState,\n            animateTo = { target, velocity ->\n                scope.launch { sheetState.animateTo(target, velocity = velocity) }\n            },\n            snapTo = { target -> scope.launch { sheetState.snapTo(target) } }\n        )\n    }\n    BoxWithConstraints(modifier) {\n        val fullHeight = constraints.maxHeight.toFloat()\n        Box(Modifier.fillMaxSize()) {\n            content()\n            Scrim(\n                color = scrimColor,\n                onDismiss = {\n                    if (sheetState.swipeableState.confirmValueChange(Hidden)) {\n                        scope.launch { sheetState.hide() }\n                    }\n                },\n                visible = sheetState.swipeableState.targetValue != Hidden\n            )\n        }\n        Surface(\n            Modifier\n                .align(Alignment.TopCenter) // We offset from the top so we'll center from there\n                .widthIn(max = MaxModalBottomSheetWidth)\n                .fillMaxWidth()\n                .then(\n                    if (nestedScrollEnabled) {\n                        Modifier.nestedScroll(\n                            remember(sheetState.swipeableState, orientation) {\n                                ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection(\n                                    state = sheetState.swipeableState,\n                                    orientation = orientation\n                                )\n                            }\n                        )\n                    } else Modifier)\n                .offset {\n                    IntOffset(\n                        0,\n                        sheetState.swipeableState\n                            .requireOffset()\n                            .roundToInt()\n                    )\n                }\n                .swipeableV2(\n                    state = sheetState.swipeableState,\n                    orientation = orientation,\n                    enabled = sheetState.swipeableState.currentValue != Hidden,\n                )\n                .swipeAnchors(\n                    state = sheetState.swipeableState,\n                    possibleValues = setOf(Hidden, HalfExpanded, Expanded),\n                    anchorChangeHandler = anchorChangeHandler\n                ) { state, sheetSize ->\n                    when (state) {\n                        Hidden -> fullHeight\n                        HalfExpanded -> when {\n                            sheetSize.height < fullHeight / 2f -> null\n                            sheetState.isSkipHalfExpanded -> null\n                            else -> fullHeight / 2f\n                        }\n\n                        Expanded -> if (sheetSize.height != 0) {\n                            max(0f, fullHeight - sheetSize.height)\n                        } else null\n                    }\n                }\n                .semantics {\n                    if (sheetState.isVisible) {\n                        dismiss {\n                            if (sheetState.swipeableState.confirmValueChange(Hidden)) {\n                                scope.launch { sheetState.hide() }\n                            }\n                            true\n                        }\n                        if (sheetState.swipeableState.currentValue == HalfExpanded) {\n                            expand {\n                                if (sheetState.swipeableState.confirmValueChange(Expanded)) {\n                                    scope.launch { sheetState.expand() }\n                                }\n                                true\n                            }\n                        } else if (sheetState.hasHalfExpandedState) {\n                            collapse {\n                                if (sheetState.swipeableState.confirmValueChange(HalfExpanded)) {\n                                    scope.launch { sheetState.halfExpand() }\n                                }\n                                true\n                            }\n                        }\n                    }\n                }\n                .then(sheetModifier),\n            shape = sheetShape,\n            elevation = sheetElevation,\n            color = sheetContainerColor,\n            contentColor = sheetContentColor\n        ) {\n            Column(\n                content = {\n                    dragHandle()\n                    sheetContent()\n                }\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun Scrim(\n    color: Color,\n    onDismiss: () -> Unit,\n    visible: Boolean\n) {\n    if (color.isSpecified) {\n        val alpha by animateFloatAsState(\n            targetValue = if (visible) 1f else 0f,\n            animationSpec = TweenSpec()\n        )\n        val dismissModifier = if (visible) {\n            Modifier\n                .pointerInput(onDismiss) { detectTapGestures { onDismiss() } }\n                .semantics(mergeDescendants = true) {\n                    onClick { onDismiss(); true }\n                }\n        } else {\n            Modifier\n        }\n\n        Canvas(\n            Modifier\n                .fillMaxSize()\n                .then(dismissModifier)\n        ) {\n            drawRect(color = color, alpha = alpha)\n        }\n    }\n}\n\n@OptIn(ExperimentalMaterialApi::class)\nprivate fun ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection(\n    state: SwipeableV2State<*>,\n    orientation: Orientation\n): NestedScrollConnection = object : NestedScrollConnection {\n    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {\n        val delta = available.toFloat()\n        return if (delta < 0 && source == NestedScrollSource.UserInput) {\n            state.dispatchRawDelta(delta).toOffset()\n        } else {\n            Offset.Zero\n        }\n    }\n\n    override fun onPostScroll(\n        consumed: Offset,\n        available: Offset,\n        source: NestedScrollSource\n    ): Offset {\n        return if (source == NestedScrollSource.UserInput) {\n            state.dispatchRawDelta(available.toFloat()).toOffset()\n        } else {\n            Offset.Zero\n        }\n    }\n\n    override suspend fun onPreFling(available: Velocity): Velocity {\n        val toFling = available.toFloat()\n        val currentOffset = state.requireOffset()\n        return if (toFling < 0 && currentOffset > state.minOffset) {\n            state.settle(velocity = toFling)\n            // since we go to the anchor with tween settling, consume all for the best UX\n            available\n        } else {\n            Velocity.Zero\n        }\n    }\n\n    override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {\n        state.settle(velocity = available.toFloat())\n        return available\n    }\n\n    private fun Float.toOffset(): Offset = Offset(\n        x = if (orientation == Orientation.Horizontal) this else 0f,\n        y = if (orientation == Orientation.Vertical) this else 0f\n    )\n\n    @JvmName(\"velocityToFloat\")\n    private fun Velocity.toFloat() = if (orientation == Orientation.Horizontal) x else y\n\n    @JvmName(\"offsetToFloat\")\n    private fun Offset.toFloat(): Float = if (orientation == Orientation.Horizontal) x else y\n}\n\n@ExperimentalMaterial3Api\n@OptIn(ExperimentalMaterialApi::class)\nprivate fun ModalBottomSheetAnchorChangeHandler(\n    state: ModalSheetState,\n    animateTo: (target: ModalBottomSheetValue, velocity: Float) -> Unit,\n    snapTo: (target: ModalBottomSheetValue) -> Unit,\n) = AnchorChangeHandler<ModalBottomSheetValue> { previousTarget, previousAnchors, newAnchors ->\n    val previousTargetOffset = previousAnchors[previousTarget]\n    val newTarget = when (previousTarget) {\n        Hidden -> Hidden\n        HalfExpanded, Expanded -> {\n            val hasHalfExpandedState = newAnchors.containsKey(HalfExpanded)\n            val newTarget = if (hasHalfExpandedState) HalfExpanded\n            else if (newAnchors.containsKey(Expanded)) Expanded else Hidden\n            newTarget\n        }\n    }\n    val newTargetOffset = newAnchors.getValue(newTarget)\n    if (newTargetOffset != previousTargetOffset) {\n        if (state.isAnimationRunning) {\n            // Re-target the animation to the new offset if it changed\n            animateTo(newTarget, state.lastVelocity)\n        } else {\n            // Snap to the new offset value of the target if no animation was running\n            snapTo(newTarget)\n        }\n    }\n}\n\nprivate val PositionalThreshold: Density.(Float) -> Float = { 56.dp.toPx() }\nprivate val VelocityThreshold = 125.dp\nprivate val MaxModalBottomSheetWidth = 640.dp"
  },
  {
    "path": "lib/modalsheet/src/main/java/com/t8rin/modalsheet/SwipeableV2.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"FunctionName\")\n\npackage com.t8rin.modalsheet\n\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.SpringSpec\nimport androidx.compose.animation.core.animate\nimport androidx.compose.foundation.gestures.DraggableState\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.draggable\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.layout.LayoutModifier\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.OnRemeasuredModifier\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.InspectorValueInfo\nimport androidx.compose.ui.platform.debugInspectorInfo\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.dp\nimport com.t8rin.modalsheet.SwipeableV2State.Companion.Saver\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.launch\nimport kotlin.math.abs\n\n/**\n * Enable swipe gestures between a set of predefined values.\n *\n * When a swipe is detected, the offset of the [SwipeableV2State] will be updated with the swipe\n * delta. You should use this offset to move your content accordingly (see [Modifier.offset]).\n * When the swipe ends, the offset will be animated to one of the anchors and when that anchor is\n * reached, the value of the [SwipeableV2State] will also be updated to the value corresponding to\n * the new anchor.\n *\n * Swiping is constrained between the minimum and maximum anchors.\n *\n * @param state The associated [SwipeableV2State].\n * @param orientation The orientation in which the swipeable can be swiped.\n * @param enabled Whether this [swipeableV2] is enabled and should react to the user's input.\n * @param reverseDirection Whether to reverse the direction of the swipe, so a top to bottom\n * swipe will behave like bottom to top, and a left to right swipe will behave like right to left.\n * @param interactionSource Optional [MutableInteractionSource] that will passed on to\n * the internal [Modifier.draggable].\n */\n@ExperimentalMaterialApi\ninternal fun <T> Modifier.swipeableV2(\n    state: SwipeableV2State<T>,\n    orientation: Orientation,\n    enabled: Boolean = true,\n    reverseDirection: Boolean = false,\n    interactionSource: MutableInteractionSource? = null\n) = draggable(\n    state = state.draggableState,\n    orientation = orientation,\n    enabled = enabled,\n    interactionSource = interactionSource,\n    reverseDirection = reverseDirection,\n    startDragImmediately = state.isAnimationRunning,\n    onDragStopped = { velocity -> launch { state.settle(velocity) } }\n)\n\n/**\n * Define anchor points for a given [SwipeableV2State] based on this node's layout size and update\n * the state with them.\n *\n * @param state The associated [SwipeableV2State]\n * @param possibleValues All possible values the [SwipeableV2State] could be in.\n * @param anchorChangeHandler A callback to be invoked when the anchors have changed,\n * `null` by default. Components with custom reconciliation logic should implement this callback,\n * i.e. to re-target an in-progress animation.\n * @param calculateAnchor This method will be invoked to calculate the position of all\n * [possibleValues], given this node's layout size. Return the anchor's offset from the initial\n * anchor, or `null` to indicate that a value does not have an anchor.\n */\n@ExperimentalMaterialApi\ninternal fun <T> Modifier.swipeAnchors(\n    state: SwipeableV2State<T>,\n    possibleValues: Set<T>,\n    anchorChangeHandler: AnchorChangeHandler<T>? = null,\n    calculateAnchor: (value: T, layoutSize: IntSize) -> Float?,\n) = this.then(\n    SwipeAnchorsModifier(\n        onDensityChanged = { state.density = it },\n        onSizeChanged = { layoutSize ->\n            val previousAnchors = state.anchors\n            val newAnchors = mutableMapOf<T, Float>()\n            possibleValues.forEach {\n                val anchorValue = calculateAnchor(it, layoutSize)\n                if (anchorValue != null) {\n                    newAnchors[it] = anchorValue\n                }\n            }\n            if (previousAnchors != newAnchors) {\n                val previousTarget = state.targetValue\n                val stateRequiresCleanup = state.updateAnchors(newAnchors)\n                if (stateRequiresCleanup) {\n                    anchorChangeHandler?.onAnchorsChanged(\n                        previousTarget,\n                        previousAnchors,\n                        newAnchors\n                    )\n                }\n            }\n        },\n        inspectorInfo = debugInspectorInfo {\n            name = \"swipeAnchors\"\n            properties[\"state\"] = state\n            properties[\"possibleValues\"] = possibleValues\n            properties[\"anchorChangeHandler\"] = anchorChangeHandler\n            properties[\"calculateAnchor\"] = calculateAnchor\n        }\n    ))\n\n/**\n * State of the [swipeableV2] modifier.\n *\n * This contains necessary information about any ongoing swipe or animation and provides methods\n * to change the state either immediately or by starting an animation. To create and remember a\n * [SwipeableV2State] use [rememberSwipeableV2State].\n *\n * @param initialValue The initial value of the state.\n * @param animationSpec The default animation that will be used to animate to a new state.\n * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.\n * @param positionalThreshold The positional threshold to be used when calculating the target state\n * while a swipe is in progress and when settling after the swipe ends. This is the distance from\n * the start of a transition. It will be, depending on the direction of the interaction, added or\n * subtracted from/to the origin offset. It should always be a positive value. See the\n * [fractionalPositionalThreshold] and [fixedPositionalThreshold] methods.\n * @param velocityThreshold The velocity threshold (in dp per second) that the end velocity has to\n * exceed in order to animate to the next state, even if the [positionalThreshold] has not been\n * reached.\n */\n@Stable\n@ExperimentalMaterialApi\nclass SwipeableV2State<T>(\n    initialValue: T,\n    val animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,\n    val confirmValueChange: (newValue: T) -> Boolean = { true },\n    val positionalThreshold: Density.(totalDistance: Float) -> Float =\n        SwipeableV2Defaults.PositionalThreshold,\n    val velocityThreshold: Dp = SwipeableV2Defaults.VelocityThreshold,\n) {\n\n    /**\n     * The current value of the [SwipeableV2State].\n     */\n    var currentValue: T by mutableStateOf(initialValue)\n        private set\n\n    /**\n     * The target value. This is the closest value to the current offset (taking into account\n     * positional thresholds). If no interactions like animations or drags are in progress, this\n     * will be the current value.\n     */\n    val targetValue: T by derivedStateOf {\n        animationTarget ?: run {\n            val currentOffset = offset\n            if (currentOffset != null) {\n                computeTarget(currentOffset, currentValue, velocity = 0f)\n            } else currentValue\n        }\n    }\n\n    /**\n     * The current offset, or null if it has not been initialized yet.\n     *\n     * The offset will be initialized during the first measurement phase of the node that the\n     * [swipeableV2] modifier is attached to. These are the phases:\n     * Composition { -> Effects } -> Layout { Measurement -> Placement } -> Drawing\n     * During the first composition, the offset will be null. In subsequent compositions, the offset\n     * will be derived from the anchors of the previous pass.\n     * Always prefer accessing the offset from a LaunchedEffect as it will be scheduled to be\n     * executed the next frame, after layout.\n     *\n     * To guarantee stricter semantics, consider using [requireOffset].\n     */\n    @get:Suppress(\"AutoBoxing\")\n    var offset: Float? by mutableStateOf(null)\n        private set\n\n    /**\n     * Require the current offset.\n     *\n     * @throws IllegalStateException If the offset has not been initialized yet\n     */\n    fun requireOffset(): Float = checkNotNull(offset) {\n        \"The offset was read before being initialized. Did you access the offset in a phase \" +\n                \"before layout, like effects or composition?\"\n    }\n\n    /**\n     * Whether an animation is currently in progress.\n     */\n    val isAnimationRunning: Boolean get() = animationTarget != null\n\n    /**\n     * The fraction of the progress going from [currentValue] to [targetValue], within [0f..1f]\n     * bounds.\n     */\n    /*@FloatRange(from = 0f, to = 1f)*/\n    val progress: Float by derivedStateOf {\n        val a = anchors[currentValue] ?: 0f\n        val b = anchors[targetValue] ?: 0f\n        val distance = abs(b - a)\n        if (distance > 1e-6f) {\n            val progress = (this.requireOffset() - a) / (b - a)\n            // If we are very close to 0f or 1f, we round to the closest\n            if (progress < 1e-6f) 0f else if (progress > 1 - 1e-6f) 1f else progress\n        } else 1f\n    }\n\n    /**\n     * The velocity of the last known animation. Gets reset to 0f when an animation completes\n     * successfully, but does not get reset when an animation gets interrupted.\n     * You can use this value to provide smooth reconciliation behavior when re-targeting an\n     * animation.\n     */\n    var lastVelocity: Float by mutableStateOf(0f)\n        private set\n\n    /**\n     * The minimum offset this state can reach. This will be the smallest anchor, or\n     * [Float.NEGATIVE_INFINITY] if the anchors are not initialized yet.\n     */\n    val minOffset by derivedStateOf { anchors.minOrNull() ?: Float.NEGATIVE_INFINITY }\n\n    /**\n     * The maximum offset this state can reach. This will be the biggest anchor, or\n     * [Float.POSITIVE_INFINITY] if the anchors are not initialized yet.\n     */\n    val maxOffset by derivedStateOf { anchors.maxOrNull() ?: Float.POSITIVE_INFINITY }\n\n    private var animationTarget: T? by mutableStateOf(null)\n    val draggableState = DraggableState {\n        offset = ((offset ?: 0f) + it).coerceIn(minOffset, maxOffset)\n    }\n\n    internal var anchors by mutableStateOf(emptyMap<T, Float>())\n\n    internal var density: Density? = null\n\n    /**\n     * Update the anchors.\n     * If the previous set of anchors was empty, attempt to update the offset to match the initial\n     * value's anchor.\n     *\n     * @return true if the state needs to be adjusted after updating the anchors, e.g. if the\n     * initial value is not found in the initial set of anchors. false if no further updates are\n     * needed.\n     */\n    internal fun updateAnchors(newAnchors: Map<T, Float>): Boolean {\n        val previousAnchorsEmpty = anchors.isEmpty()\n        anchors = newAnchors\n        val initialValueHasAnchor = if (previousAnchorsEmpty) {\n            val initialValueAnchor = anchors[currentValue]\n            val initialValueHasAnchor = initialValueAnchor != null\n            if (initialValueHasAnchor) offset = initialValueAnchor\n            initialValueHasAnchor\n        } else true\n        return !initialValueHasAnchor || !previousAnchorsEmpty\n    }\n\n    /**\n     * Whether the [value] has an anchor associated with it.\n     */\n    fun hasAnchorForValue(value: T): Boolean = anchors.containsKey(value)\n\n    /**\n     * Snap to a [targetValue] without any animation.\n     * If the [targetValue] is not in the set of anchors, the [currentValue] will be updated to the\n     * [targetValue] without updating the offset.\n     *\n     * @throws CancellationException if the interaction interrupted by another interaction like a\n     * gesture interaction or another programmatic interaction like a [animateTo] or [snapTo] call.\n     *\n     * @param targetValue The target value of the animation\n     */\n    suspend fun snapTo(targetValue: T) {\n        val targetOffset = anchors[targetValue]\n        if (targetOffset != null) {\n            try {\n                draggableState.drag {\n                    animationTarget = targetValue\n                    dragBy(targetOffset - requireOffset())\n                }\n                this.currentValue = targetValue\n            } finally {\n                animationTarget = null\n            }\n        } else {\n            currentValue = targetValue\n        }\n    }\n\n    /**\n     * Animate to a [targetValue].\n     * If the [targetValue] is not in the set of anchors, the [currentValue] will be updated to the\n     * [targetValue] without updating the offset.\n     *\n     * @throws CancellationException if the interaction interrupted by another interaction like a\n     * gesture interaction or another programmatic interaction like a [animateTo] or [snapTo] call.\n     *\n     * @param targetValue The target value of the animation\n     * @param velocity The velocity the animation should start with, [lastVelocity] by default\n     */\n    suspend fun animateTo(\n        targetValue: T,\n        velocity: Float = lastVelocity,\n    ) {\n        val targetOffset = anchors[targetValue]\n        if (targetOffset != null) {\n            try {\n                draggableState.drag {\n                    animationTarget = targetValue\n                    var prev = offset ?: 0f\n                    animate(prev, targetOffset, velocity, animationSpec) { value, velocity ->\n                        // Our onDrag coerces the value within the bounds, but an animation may\n                        // overshoot, for example a spring animation or an overshooting interpolator\n                        // We respect the user's intention and allow the overshoot, but still use\n                        // DraggableState's drag for its mutex.\n                        offset = value\n                        prev = value\n                        lastVelocity = velocity\n                    }\n                    lastVelocity = 0f\n                }\n            } finally {\n                animationTarget = null\n                val endOffset = requireOffset()\n                val endState = anchors\n                    .entries\n                    .firstOrNull { (_, anchorOffset) -> abs(anchorOffset - endOffset) < 0.5f }\n                    ?.key\n                this.currentValue = endState ?: currentValue\n            }\n        } else {\n            currentValue = targetValue\n        }\n    }\n\n    /**\n     * Find the closest anchor taking into account the velocity and settle at it with an animation.\n     */\n    suspend fun settle(velocity: Float) {\n        val previousValue = this.currentValue\n        val targetValue = computeTarget(\n            offset = requireOffset(),\n            currentValue = previousValue,\n            velocity = velocity\n        )\n        if (confirmValueChange(targetValue)) {\n            animateTo(targetValue, velocity)\n        } else {\n            // If the user vetoed the state change, rollback to the previous state.\n            animateTo(previousValue, velocity)\n        }\n    }\n\n    /**\n     * Swipe by the [delta], coerce it in the bounds and dispatch it to the [draggableState].\n     *\n     * @return The delta the [draggableState] will consume\n     */\n    fun dispatchRawDelta(delta: Float): Float {\n        val currentDragPosition = offset ?: 0f\n        val potentiallyConsumed = currentDragPosition + delta\n        val clamped = potentiallyConsumed.coerceIn(minOffset, maxOffset)\n        val deltaToConsume = clamped - currentDragPosition\n        if (abs(deltaToConsume) > 0) {\n            draggableState.dispatchRawDelta(deltaToConsume)\n        }\n        return deltaToConsume\n    }\n\n    private fun computeTarget(\n        offset: Float,\n        currentValue: T,\n        velocity: Float\n    ): T {\n        val currentAnchors = anchors\n        val currentAnchor = currentAnchors[currentValue]\n        val currentDensity = requireDensity()\n        val velocityThresholdPx = with(currentDensity) { velocityThreshold.toPx() }\n        return if (currentAnchor == offset || currentAnchor == null) {\n            currentValue\n        } else if (currentAnchor < offset) {\n            // Swiping from lower to upper (positive).\n            if (velocity >= velocityThresholdPx) {\n                currentAnchors.closestAnchor(offset, true)\n            } else {\n                val upper = currentAnchors.closestAnchor(offset, true)\n                val distance = abs(currentAnchors.getValue(upper) - currentAnchor)\n                val relativeThreshold = abs(positionalThreshold(currentDensity, distance))\n                val absoluteThreshold = abs(currentAnchor + relativeThreshold)\n                if (offset < absoluteThreshold) currentValue else upper\n            }\n        } else {\n            // Swiping from upper to lower (negative).\n            if (velocity <= -velocityThresholdPx) {\n                currentAnchors.closestAnchor(offset, false)\n            } else {\n                val lower = currentAnchors.closestAnchor(offset, false)\n                val distance = abs(currentAnchor - currentAnchors.getValue(lower))\n                val relativeThreshold = abs(positionalThreshold(currentDensity, distance))\n                val absoluteThreshold = abs(currentAnchor - relativeThreshold)\n                if (offset < 0) {\n                    // For negative offsets, larger absolute thresholds are closer to lower anchors\n                    // than smaller ones.\n                    if (abs(offset) < absoluteThreshold) currentValue else lower\n                } else {\n                    if (offset > absoluteThreshold) currentValue else lower\n                }\n            }\n        }\n    }\n\n    private fun requireDensity() = requireNotNull(density) {\n        \"SwipeableState did not have a density attached. Are you using Modifier.swipeable with \" +\n                \"this=$this SwipeableState?\"\n    }\n\n    companion object {\n        /**\n         * The default [Saver] implementation for [SwipeableV2State].\n         */\n        @ExperimentalMaterialApi\n        fun <T : Any> Saver(\n            animationSpec: AnimationSpec<Float>,\n            confirmValueChange: (T) -> Boolean,\n            positionalThreshold: Density.(distance: Float) -> Float,\n            velocityThreshold: Dp\n        ) = Saver<SwipeableV2State<T>, T>(\n            save = { it.currentValue },\n            restore = {\n                SwipeableV2State(\n                    initialValue = it,\n                    animationSpec = animationSpec,\n                    confirmValueChange = confirmValueChange,\n                    positionalThreshold = positionalThreshold,\n                    velocityThreshold = velocityThreshold\n                )\n            }\n        )\n    }\n}\n\n/**\n * Create and remember a [SwipeableV2State].\n *\n * @param initialValue The initial value.\n * @param animationSpec The default animation that will be used to animate to a new value.\n * @param confirmValueChange Optional callback invoked to confirm or veto a pending value change.\n */\n@Composable\n@ExperimentalMaterialApi\ninternal fun <T : Any> rememberSwipeableV2State(\n    initialValue: T,\n    animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,\n    confirmValueChange: (newValue: T) -> Boolean = { true }\n): SwipeableV2State<T> {\n    return rememberSaveable(\n        initialValue, animationSpec, confirmValueChange,\n        saver = Saver(\n            animationSpec = animationSpec,\n            confirmValueChange = confirmValueChange,\n            positionalThreshold = SwipeableV2Defaults.PositionalThreshold,\n            velocityThreshold = SwipeableV2Defaults.VelocityThreshold\n        ),\n    ) {\n        SwipeableV2State(\n            initialValue = initialValue,\n            animationSpec = animationSpec,\n            confirmValueChange = confirmValueChange,\n            positionalThreshold = SwipeableV2Defaults.PositionalThreshold,\n            velocityThreshold = SwipeableV2Defaults.VelocityThreshold\n        )\n    }\n}\n\n/**\n * Expresses a fixed positional threshold of [threshold] dp. This will be the distance from an\n * anchor that needs to be reached for [SwipeableV2State] to settle to the next closest anchor.\n *\n * @see [fractionalPositionalThreshold] for a fractional positional threshold\n */\n@ExperimentalMaterialApi\ninternal fun fixedPositionalThreshold(threshold: Dp): Density.(distance: Float) -> Float = {\n    threshold.toPx()\n}\n\n/**\n * Expresses a relative positional threshold of the [fraction] of the distance to the closest anchor\n * in the current direction. This will be the distance from an anchor that needs to be reached for\n * [SwipeableV2State] to settle to the next closest anchor.\n *\n * @see [fixedPositionalThreshold] for a fixed positional threshold\n */\n@ExperimentalMaterialApi\ninternal fun fractionalPositionalThreshold(\n    fraction: Float\n): Density.(distance: Float) -> Float = { distance -> distance * fraction }\n\n/**\n * Contains useful defaults for [swipeableV2] and [SwipeableV2State].\n */\n@Stable\n@ExperimentalMaterialApi\ninternal object SwipeableV2Defaults {\n    /**\n     * The default animation used by [SwipeableV2State].\n     */\n    @ExperimentalMaterialApi\n    val AnimationSpec = SpringSpec<Float>()\n\n    /**\n     * The default velocity threshold (1.8 dp per millisecond) used by [rememberSwipeableV2State].\n     */\n    @ExperimentalMaterialApi\n    val VelocityThreshold: Dp = 125.dp\n\n    /**\n     * The default positional threshold (56 dp) used by [rememberSwipeableV2State]\n     */\n    @ExperimentalMaterialApi\n    val PositionalThreshold: Density.(totalDistance: Float) -> Float =\n        fixedPositionalThreshold(56.dp)\n\n    /**\n     * A [AnchorChangeHandler] implementation that attempts to reconcile an in-progress animation\n     * by re-targeting it if necessary or finding the closest new anchor.\n     * If the previous anchor is not in the new set of anchors, this implementation will snap to the\n     * closest anchor.\n     *\n     * Consider implementing a custom handler for more complex components like sheets.\n     * The [animate] and [snap] lambdas hoist the animation and snap logic. Usually these will just\n     * delegate to [SwipeableV2State].\n     *\n     * @param state The [SwipeableV2State] the change handler will read from\n     * @param animate A lambda that gets invoked to start an animation to a new target\n     * @param snap A lambda that gets invoked to snap to a new target\n     */\n    @ExperimentalMaterialApi\n    internal fun <T> ReconcileAnimationOnAnchorChangeHandler(\n        state: SwipeableV2State<T>,\n        animate: (target: T, velocity: Float) -> Unit,\n        snap: (target: T) -> Unit\n    ) = AnchorChangeHandler { previousTarget, previousAnchors, newAnchors ->\n        val previousTargetOffset = previousAnchors[previousTarget]\n        val newTargetOffset = newAnchors[previousTarget]\n        if (previousTargetOffset != newTargetOffset) {\n            if (newTargetOffset != null) {\n                animate(previousTarget, state.lastVelocity)\n            } else {\n                snap(newAnchors.closestAnchor(offset = state.requireOffset()))\n            }\n        }\n    }\n}\n\n/**\n * Defines a callback that is invoked when the anchors have changed.\n *\n * Components with custom reconciliation logic should implement this callback, for example to\n * re-target an in-progress animation when the anchors change.\n *\n * @see SwipeableV2Defaults.ReconcileAnimationOnAnchorChangeHandler for a default implementation\n */\n@ExperimentalMaterialApi\ninternal fun interface AnchorChangeHandler<T> {\n\n    /**\n     * Callback that is invoked when the anchors have changed, after the [SwipeableV2State] has been\n     * updated with them. Use this hook to re-launch animations or interrupt them if needed.\n     *\n     * @param previousTargetValue The target value before the anchors were updated\n     * @param previousAnchors The previously set anchors\n     * @param newAnchors The newly set anchors\n     */\n    fun onAnchorsChanged(\n        previousTargetValue: T,\n        previousAnchors: Map<T, Float>,\n        newAnchors: Map<T, Float>\n    )\n}\n\n@Stable\nprivate class SwipeAnchorsModifier(\n    private val onDensityChanged: (density: Density) -> Unit,\n    private val onSizeChanged: (layoutSize: IntSize) -> Unit,\n    inspectorInfo: InspectorInfo.() -> Unit,\n) : LayoutModifier, OnRemeasuredModifier, InspectorValueInfo(inspectorInfo) {\n\n    private var lastDensity: Float = -1f\n    private var lastFontScale: Float = -1f\n\n    override fun MeasureScope.measure(\n        measurable: Measurable,\n        constraints: Constraints\n    ): MeasureResult {\n        if (density != lastDensity || fontScale != lastFontScale) {\n            onDensityChanged(Density(density, fontScale))\n            lastDensity = density\n            lastFontScale = fontScale\n        }\n        val placeable = measurable.measure(constraints)\n        return layout(placeable.width, placeable.height) { placeable.place(0, 0) }\n    }\n\n    override fun onRemeasured(size: IntSize) {\n        onSizeChanged(size)\n    }\n\n    override fun toString() = \"SwipeAnchorsModifierImpl(updateDensity=$onDensityChanged, \" +\n            \"onSizeChanged=$onSizeChanged)\"\n}\n\nprivate fun <T> Map<T, Float>.closestAnchor(\n    offset: Float = 0f,\n    searchUpwards: Boolean = false\n): T {\n    require(isNotEmpty()) { \"The anchors were empty when trying to find the closest anchor\" }\n    return minBy { (_, anchor) ->\n        val delta = if (searchUpwards) anchor - offset else offset - anchor\n        if (delta < 0) Float.POSITIVE_INFINITY else delta\n    }.key\n}\n\nprivate fun <T> Map<T, Float>.minOrNull() = minOfOrNull { (_, offset) -> offset }\nprivate fun <T> Map<T, Float>.maxOrNull() = maxOfOrNull { (_, offset) -> offset }\nprivate fun <T> Map<T, Float>.requireAnchor(value: T) = requireNotNull(this[value]) {\n    \"Required anchor $value was not found in anchors. Current anchors: ${this.toMap()}\"\n}\n"
  },
  {
    "path": "lib/neural-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/neural-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid {\n    namespace = \"com.t8rin.neural_tools\"\n}\n\ndependencies {\n    api(libs.onnx.runtime)\n    implementation(libs.ktor)\n    implementation(libs.ktor.logging)\n    implementation(libs.aire)\n}"
  },
  {
    "path": "lib/neural-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <uses-sdk\n        android:minSdkVersion=\"24\"\n        tools:overrideLibrary=\"ai.onnxruntime\" />\n</manifest>"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/DownloadProgress.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools\n\ndata class DownloadProgress(\n    val currentPercent: Float,\n    val currentTotalSize: Long\n)"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/NeuralTool.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools\n\nimport android.app.Application\nimport io.ktor.client.HttpClient\nimport io.ktor.client.plugins.logging.LogLevel\nimport io.ktor.client.plugins.logging.Logging\n\nabstract class NeuralTool {\n    protected val context get() = application\n\n    companion object {\n        private var _httpClient: HttpClient = HttpClient {\n            install(Logging) {\n                level = LogLevel.INFO\n            }\n        }\n        internal val httpClient: HttpClient get() = _httpClient\n\n        internal var baseUrl = \"\"\n\n        private var _context: Application? = null\n        internal val application: Application\n            get() = _context\n                ?: throw NullPointerException(\"Call NeuralTool.init() in Application onCreate to use this feature\")\n\n        fun init(\n            context: Application,\n            httpClient: HttpClient? = null,\n            baseUrl: String\n        ) {\n            _httpClient = httpClient ?: _httpClient\n            this.baseUrl = baseUrl\n            _context = context\n        }\n    }\n}"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/BgRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.bgremover\n\nimport android.graphics.Bitmap\nimport com.t8rin.neural_tools.DownloadProgress\nimport com.t8rin.neural_tools.NeuralTool\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.channelFlow\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.debounce\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport java.util.concurrent.ConcurrentHashMap\n\nobject BgRemover : NeuralTool() {\n\n    enum class Type {\n        RMBG1_4,\n        InSPyReNet,\n        U2NetP,\n        U2Net,\n        BiRefNet,\n        BiRefNetTiny,\n        ISNet\n    }\n\n    val downloadedModels: StateFlow<List<Type>> = channelFlow {\n        val map = ConcurrentHashMap<Type, Boolean>()\n\n        Type.entries.forEach { type ->\n            if (type == Type.U2NetP) {\n                map[type] = true\n                send(map.filterValues { it }.keys.toList())\n            }\n\n            launch {\n                getRemover(type).isDownloaded.collectLatest { isDownloaded ->\n                    map[type] = isDownloaded\n                    send(map.filterValues { it }.keys.toList())\n                }\n            }\n        }\n    }.debounce(500).stateIn(\n        scope = CoroutineScope(Dispatchers.IO),\n        started = SharingStarted.Eagerly,\n        initialValue = listOf(Type.U2NetP)\n    )\n\n    fun downloadModel(\n        type: Type\n    ): Flow<DownloadProgress> = getRemover(type).startDownload()\n\n    fun removeBackground(\n        image: Bitmap,\n        type: Type\n    ): Bitmap? = runCatching {\n        getRemover(type).removeBackground(image)\n    }.getOrNull()\n\n    fun closeAll() {\n        Type.entries.forEach {\n            getRemover(it).close()\n        }\n    }\n\n    fun getRemover(type: Type) = when (type) {\n        Type.RMBG1_4 -> RMBGBackgroundRemover\n        Type.InSPyReNet -> InSPyReNetBackgroundRemover\n        Type.U2NetP -> U2NetPortableBackgroundRemover\n        Type.U2Net -> U2NetFullBackgroundRemover\n        Type.BiRefNet -> BiRefNetBackgroundRemover\n        Type.BiRefNetTiny -> BiRefNetTinyBackgroundRemover\n        Type.ISNet -> ISNetBackgroundRemover\n    }\n\n}"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/BiRefNetBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.bgremover\n\ninternal object BiRefNetBackgroundRemover : GenericBackgroundRemover(\n    path = \"birefnet_fp16.ort\",\n    trainedSize = 1024\n)"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/BiRefNetTinyBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.bgremover\n\ninternal object BiRefNetTinyBackgroundRemover : GenericBackgroundRemover(\n    path = \"birefnet_swin_tiny.ort\",\n    trainedSize = 1024\n)"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/GenericBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UNCHECKED_CAST\", \"PropertyName\")\n\npackage com.t8rin.neural_tools.bgremover\n\nimport ai.onnxruntime.OnnxTensor\nimport ai.onnxruntime.OrtEnvironment\nimport ai.onnxruntime.OrtSession\nimport android.graphics.Bitmap\nimport android.graphics.Color\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.set\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ResizeFunction\nimport com.awxkee.aire.ScaleColorSpace\nimport com.t8rin.neural_tools.DownloadProgress\nimport com.t8rin.neural_tools.NeuralTool\nimport io.ktor.client.request.prepareGet\nimport io.ktor.client.statement.bodyAsChannel\nimport io.ktor.http.contentLength\nimport io.ktor.utils.io.readRemaining\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.callbackFlow\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.update\nimport kotlinx.io.readByteArray\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.nio.FloatBuffer\nimport kotlin.math.roundToInt\n\nabstract class GenericBackgroundRemover(\n    path: String,\n    val trainedSize: Int?\n) : NeuralTool() {\n\n    private val downloadLink = baseUrl.replace(\n        oldValue = \"*\",\n        newValue = path\n    )\n\n    protected val env: OrtEnvironment by lazy { OrtEnvironment.getEnvironment() }\n    protected var session: OrtSession? = null\n\n    val directory: File\n        get() = File(context.filesDir, \"ai_models\").apply(File::mkdirs)\n\n    val modelFile\n        get() = File(\n            directory,\n            downloadLink.substringAfterLast('/')\n        )\n\n    protected open val _isDownloaded =\n        MutableStateFlow(modelFile.exists() && modelFile.length() > 0)\n    val isDownloaded: StateFlow<Boolean> = _isDownloaded\n\n    open fun checkModel(): Boolean {\n        if (!modelFile.exists() || modelFile.length() <= 0) {\n            _isDownloaded.update { false }\n            modelFile.delete()\n            close()\n            return false\n        }\n\n        _isDownloaded.update { true }\n        return true\n    }\n\n    open fun removeBackground(\n        image: Bitmap,\n        modelPath: String = modelFile.path,\n        trainedSize: Int? = this.trainedSize\n    ): Bitmap? {\n        if (!modelFile.exists() || modelFile.length() <= 0) {\n            _isDownloaded.update { false }\n            modelFile.delete()\n            close()\n            return null\n        }\n\n        val session = session ?: env.createSession(modelPath, OrtSession.SessionOptions()).also {\n            session = it\n        }\n\n        val dstWidth = trainedSize ?: image.width\n        val dstHeight = trainedSize ?: image.height\n\n        val scaled = if (trainedSize == null) {\n            image\n        } else {\n            Aire.scale(\n                bitmap = image,\n                dstWidth = dstWidth,\n                dstHeight = dstHeight,\n                scaleMode = ResizeFunction.Bilinear,\n                colorSpace = ScaleColorSpace.SRGB\n            )\n        }\n\n        val input = bitmapToFloatBuffer(scaled, dstWidth, dstHeight)\n        val inputName = session.inputNames.first()\n        val inputTensor = OnnxTensor.createTensor(\n            env,\n            input,\n            longArrayOf(1, 3, dstWidth.toLong(), dstHeight.toLong())\n        )\n\n        val output = session.run(mapOf(inputName to inputTensor))\n        val outputArray = (output[0].value as Array<Array<Array<FloatArray>>>)[0][0]\n\n        val maskBmp = createBitmap(dstWidth, dstHeight)\n        var i = 0\n        for (y in 0 until dstHeight) {\n            for (x in 0 until dstWidth) {\n                val alpha = (outputArray[y][x] * 255f).roundToInt().coerceIn(0, 255)\n                maskBmp[x, y] = Color.argb(alpha, 255, 255, 255)\n                i++\n            }\n        }\n\n        val maskScaled = if (trainedSize == null) {\n            maskBmp\n        } else {\n            Aire.scale(\n                bitmap = maskBmp,\n                dstWidth = image.width,\n                dstHeight = image.height,\n                scaleMode = ResizeFunction.Bilinear,\n                colorSpace = ScaleColorSpace.SRGB\n            )\n        }\n\n        val pixels = IntArray(image.width * image.height)\n        val maskPixels = IntArray(image.width * image.height)\n        image.getPixels(pixels, 0, image.width, 0, 0, image.width, image.height)\n        maskScaled.getPixels(maskPixels, 0, image.width, 0, 0, image.width, image.height)\n\n        for (idx in pixels.indices) {\n            val alpha = Color.alpha(maskPixels[idx])\n            val src = pixels[idx]\n            pixels[idx] =\n                Color.argb(alpha, Color.red(src), Color.green(src), Color.blue(src))\n        }\n\n        val result = createBitmap(image.width, image.height)\n        result.setPixels(pixels, 0, image.width, 0, 0, image.width, image.height)\n        result.setHasAlpha(true)\n\n        inputTensor.close()\n        output.close()\n\n        return result\n    }\n\n    open fun startDownload(forced: Boolean = false): Flow<DownloadProgress> = callbackFlow {\n        if (modelFile.exists() || modelFile.length() > 0) {\n            if (!forced) _isDownloaded.update { true }\n        }\n        httpClient.prepareGet(downloadLink).execute { response ->\n            val total = response.contentLength() ?: -1L\n\n            val tmp = File(modelFile.parentFile, modelFile.name + \".tmp\")\n\n            val channel = response.bodyAsChannel()\n            var downloaded = 0L\n\n            FileOutputStream(tmp).use { fos ->\n                try {\n                    while (!channel.isClosedForRead) {\n                        val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())\n                        while (!packet.exhausted()) {\n                            val bytes = packet.readByteArray()\n                            downloaded += bytes.size\n                            fos.write(bytes)\n                            trySend(\n                                DownloadProgress(\n                                    currentPercent = if (total > 0) downloaded.toFloat() / total else 0f,\n                                    currentTotalSize = downloaded\n                                )\n                            )\n                        }\n                    }\n\n                    tmp.renameTo(modelFile)\n                    _isDownloaded.update { true }\n                    close()\n                } catch (e: Throwable) {\n                    tmp.delete()\n                    close(e)\n                }\n            }\n        }\n    }.flowOn(Dispatchers.IO)\n\n    fun close() {\n        session?.close()\n        session = null\n    }\n\n    protected fun bitmapToFloatBuffer(\n        bitmap: Bitmap,\n        width: Int,\n        height: Int\n    ): FloatBuffer {\n        val pixels = IntArray(width * height)\n        bitmap.getPixels(pixels, 0, width, 0, 0, width, height)\n\n        val buffer = FloatBuffer.allocate(3 * width * height)\n        var offsetR = 0\n        var offsetG = width * height\n        var offsetB = 2 * width * height\n\n        for (p in pixels) {\n            buffer.put(offsetR++, Color.red(p) / 255f)\n            buffer.put(offsetG++, Color.green(p) / 255f)\n            buffer.put(offsetB++, Color.blue(p) / 255f)\n        }\n\n        return buffer\n    }\n\n}"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/ISNetBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.bgremover\n\ninternal object ISNetBackgroundRemover : GenericBackgroundRemover(\n    path = \"isnet-general-use.onnx\",\n    trainedSize = 1024\n)"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/InSPyReNetBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.bgremover\n\ninternal object InSPyReNetBackgroundRemover : GenericBackgroundRemover(\n    path = \"onnx/bgremove/inspyrenet.onnx\",\n    trainedSize = 1024\n)"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/RMBGBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.bgremover\n\ninternal object RMBGBackgroundRemover : GenericBackgroundRemover(\n    path = \"onnx/bgremove/RMBG_1.4.ort\",\n    trainedSize = 1024\n)"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/U2NetFullBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.bgremover\n\ninternal object U2NetFullBackgroundRemover : GenericBackgroundRemover(\n    path = \"onnx/bgremove/u2net.onnx\",\n    trainedSize = 320\n)"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/bgremover/U2NetPortableBackgroundRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UNCHECKED_CAST\")\n\npackage com.t8rin.neural_tools.bgremover\n\nimport android.graphics.Bitmap\nimport com.t8rin.neural_tools.DownloadProgress\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.callbackFlow\nimport kotlinx.coroutines.flow.update\nimport java.io.FileOutputStream\n\ninternal object U2NetPortableBackgroundRemover : GenericBackgroundRemover(\n    path = \"onnx/bgremove/u2netp.onnx\",\n    trainedSize = 320\n) {\n\n    init {\n        extract()\n    }\n\n    override fun startDownload(forced: Boolean): Flow<DownloadProgress> = callbackFlow {\n        extract()\n        close()\n    }\n\n    override fun removeBackground(image: Bitmap, modelPath: String, trainedSize: Int?): Bitmap? {\n        extract()\n        return super.removeBackground(\n            image = image,\n            modelPath = modelPath,\n            trainedSize = trainedSize\n        )\n    }\n\n    override fun checkModel(): Boolean {\n        extract()\n        return super.checkModel()\n    }\n\n    private fun extract() {\n        if (!modelFile.exists() || modelFile.length() <= 0) {\n            context.assets.open(\"u2netp.onnx\").use { input ->\n                FileOutputStream(modelFile).use { output -> input.copyTo(output) }\n            }\n        }\n        _isDownloaded.update { true }\n    }\n}\n"
  },
  {
    "path": "lib/neural-tools/src/main/java/com/t8rin/neural_tools/inpaint/LaMaProcessor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.neural_tools.inpaint\n\nimport ai.onnxruntime.OnnxTensor\nimport ai.onnxruntime.OrtEnvironment\nimport ai.onnxruntime.OrtSession\nimport android.graphics.Bitmap\nimport android.util.Log\nimport com.awxkee.aire.Aire\nimport com.awxkee.aire.ResizeFunction\nimport com.awxkee.aire.ScaleColorSpace\nimport com.t8rin.neural_tools.DownloadProgress\nimport com.t8rin.neural_tools.NeuralTool\nimport io.ktor.client.request.prepareGet\nimport io.ktor.client.statement.bodyAsChannel\nimport io.ktor.http.contentLength\nimport io.ktor.utils.io.readRemaining\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.callbackFlow\nimport kotlinx.coroutines.flow.flowOn\nimport kotlinx.coroutines.flow.update\nimport kotlinx.io.readByteArray\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.nio.FloatBuffer\n\nobject LaMaProcessor : NeuralTool() {\n\n    private const val TRAINED_SIZE = 512\n\n    private var isFastModel: Boolean = false\n\n    private val MODEL_DOWNLOAD_LINK\n        get() = baseUrl.replace(\n            oldValue = \"*\",\n            newValue = if (isFastModel) {\n                \"onnx/inpaint/lama/LaMa_512_FAST.onnx\"\n            } else {\n                \"onnx/inpaint/lama/LaMa_512.onnx\"\n            }\n        )\n\n    private val directory: File\n        get() = File(context.filesDir, \"onnx\").apply {\n            mkdirs()\n        }\n\n    private val modelFile\n        get() = File(\n            directory,\n            MODEL_DOWNLOAD_LINK.substringAfterLast('/')\n        )\n\n    private var sessionHolder: OrtSession? = null\n    private val session: OrtSession\n        get() = sessionHolder ?: run {\n            val options = OrtSession.SessionOptions().apply {\n                runCatching { addCUDA() }\n                runCatching { setOptimizationLevel(OrtSession.SessionOptions.OptLevel.ALL_OPT) }\n                runCatching { setInterOpNumThreads(8) }\n                runCatching { setIntraOpNumThreads(8) }\n                runCatching { setMemoryPatternOptimization(true) }\n            }\n            OrtEnvironment.getEnvironment().createSession(modelFile.absolutePath, options)\n        }.also { sessionHolder = it }\n\n    private val _isDownloaded = MutableStateFlow(modelFile.exists())\n    val isDownloaded: StateFlow<Boolean> = _isDownloaded\n\n    fun setIsFastModel(boolean: Boolean) {\n        isFastModel = boolean\n        _isDownloaded.update { modelFile.exists() }\n        sessionHolder?.close()\n        sessionHolder = null\n    }\n\n    fun startDownload(): Flow<DownloadProgress> = callbackFlow {\n        httpClient.prepareGet(MODEL_DOWNLOAD_LINK).execute { response ->\n            val total = response.contentLength() ?: -1L\n\n            val tmp = File(modelFile.parentFile, modelFile.name + \".tmp\")\n\n            val channel = response.bodyAsChannel()\n            var downloaded = 0L\n\n            FileOutputStream(tmp).use { fos ->\n                try {\n                    while (!channel.isClosedForRead) {\n                        val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())\n                        while (!packet.exhausted()) {\n                            val bytes = packet.readByteArray()\n                            downloaded += bytes.size\n                            fos.write(bytes)\n                            trySend(\n                                DownloadProgress(\n                                    currentPercent = if (total > 0) downloaded.toFloat() / total else 0f,\n                                    currentTotalSize = downloaded\n                                )\n                            )\n                        }\n                    }\n\n                    tmp.renameTo(modelFile)\n                    _isDownloaded.update { true }\n                    close()\n                } catch (e: Throwable) {\n                    tmp.delete()\n                    close(e)\n                }\n            }\n        }\n    }.flowOn(Dispatchers.IO)\n\n    fun inpaint(\n        image: Bitmap,\n        mask: Bitmap\n    ): Bitmap? = runCatching {\n        if (!modelFile.exists()) {\n            _isDownloaded.update { false }\n            return null\n        }\n\n        val inputImage = if (image.width != TRAINED_SIZE || image.height != TRAINED_SIZE) {\n            Aire.scale(\n                bitmap = image,\n                dstWidth = TRAINED_SIZE,\n                dstHeight = TRAINED_SIZE,\n                scaleMode = ResizeFunction.Lanczos3,\n                colorSpace = ScaleColorSpace.LAB\n            )\n        } else {\n            image\n        }\n\n        val inputMask = if (mask.width != TRAINED_SIZE || mask.height != TRAINED_SIZE) {\n            Aire.scale(\n                bitmap = mask,\n                dstWidth = TRAINED_SIZE,\n                dstHeight = TRAINED_SIZE,\n                scaleMode = ResizeFunction.Nearest,\n                colorSpace = ScaleColorSpace.SRGB\n            )\n        } else {\n            mask\n        }\n\n        val tensorImg = bitmapToOnnxTensor(bitmap = inputImage)\n        val tensorMask = bitmapToMaskTensor(bitmap = inputMask)\n\n        val inputs = mapOf(\"image\" to tensorImg, \"mask\" to tensorMask)\n\n        session.run(inputs).use { res ->\n            val outValue = res[0]\n            val outTensor = outValue as? OnnxTensor\n                ?: throw IllegalStateException(\"Model output is not OnnxTensor\")\n\n            val resultBitmap = outputTensorToBitmap(outTensor)\n\n            tensorImg.close()\n            tensorMask.close()\n\n            if (image.width != TRAINED_SIZE || image.height != TRAINED_SIZE) {\n                return Aire.scale(\n                    bitmap = resultBitmap,\n                    dstWidth = image.width,\n                    dstHeight = image.height,\n                    scaleMode = ResizeFunction.Lanczos3,\n                    colorSpace = ScaleColorSpace.LAB\n                )\n            }\n            return resultBitmap\n        }\n    }.onFailure { Log.e(\"LaMaProcessor\", \"failure\", it) }.getOrNull()\n\n    private fun bitmapToMaskTensor(\n        bitmap: Bitmap\n    ): OnnxTensor {\n        val env = OrtEnvironment.getEnvironment()\n        val w = bitmap.width\n        val h = bitmap.height\n        val pixels = IntArray(w * h)\n        bitmap.getPixels(pixels, 0, w, 0, 0, w, h)\n\n        val data = FloatArray(w * h)\n        for (i in pixels.indices) {\n            val p = pixels[i]\n            val r = (p shr 16) and 0xFF\n            data[i] = if (r > 0) 1f else 0f\n        }\n\n        return OnnxTensor.createTensor(\n            env,\n            FloatBuffer.wrap(data),\n            longArrayOf(1, 1, h.toLong(), w.toLong())\n        )\n    }\n\n    private fun bitmapToOnnxTensor(\n        bitmap: Bitmap\n    ): OnnxTensor {\n        val env = OrtEnvironment.getEnvironment()\n        val w = bitmap.width\n        val h = bitmap.height\n\n        val pixels = IntArray(w * h)\n        bitmap.getPixels(pixels, 0, w, 0, 0, w, h)\n\n        val size = 3 * w * h\n        val data = FloatArray(size)\n\n        val channelSize = w * h\n        for (i in 0 until channelSize) {\n            val p = pixels[i]\n            val r = ((p shr 16) and 0xFF) / 255f\n            val g = ((p shr 8) and 0xFF) / 255f\n            val b = (p and 0xFF) / 255f\n\n            data[i] = r\n            data[channelSize + i] = g\n            data[2 * channelSize + i] = b\n        }\n\n        return OnnxTensor.createTensor(\n            env,\n            FloatBuffer.wrap(data),\n            longArrayOf(1, 3, h.toLong(), w.toLong())\n        )\n    }\n\n    private fun outputTensorToBitmap(\n        tensor: OnnxTensor\n    ): Bitmap {\n        val buffer = tensor.floatBuffer\n        val data = FloatArray(buffer.capacity())\n        buffer.get(data)\n\n        val width = TRAINED_SIZE\n        val height = TRAINED_SIZE\n        val size = width * height\n\n        val pixels = IntArray(size)\n\n        val amp = if (isFastModel) 255 else 1\n\n        for (i in 0 until size) {\n            val r = (data[i] * amp).toInt().coerceIn(0, 255)\n            val g = (data[size + i] * amp).toInt().coerceIn(0, 255)\n            val b = (data[2 * size + i] * amp).toInt().coerceIn(0, 255)\n\n            pixels[i] = (0xFF shl 24) or (r shl 16) or (g shl 8) or b\n        }\n\n        return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888)\n    }\n}"
  },
  {
    "path": "lib/opencv-tools/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/opencv-tools/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.opencv_tools\"\n\ndependencies {\n    api(libs.opencv)\n    implementation(libs.coilCompose)\n    implementation(projects.lib.image)\n    implementation(projects.lib.zoomable)\n    implementation(projects.lib.gesture)\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/opencv-tools/src/main/assets/haarcascade_eye.xml",
    "content": "<?xml version=\"1.0\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<opencv_storage>\n    <haarcascade_frontaleye type_id=\"opencv-haar-classifier\">\n        <size>20 20</size>\n        <stages>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 20 12 -1.</_>\n                                    <_>0 14 20 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1296395957469940</threshold>\n                            <left_val>-0.7730420827865601</left_val>\n                            <right_val>0.6835014820098877</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 1 4 15 -1.</_>\n                                    <_>9 6 4 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0463268086314201</threshold>\n                            <left_val>0.5735275149345398</left_val>\n                            <right_val>-0.4909768998622894</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 10 9 2 -1.</_>\n                                    <_>9 10 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0161730907857418</threshold>\n                            <left_val>0.6025434136390686</left_val>\n                            <right_val>-0.3161070942878723</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 0 10 9 -1.</_>\n                                    <_>7 3 10 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0458288416266441</threshold>\n                            <left_val>0.6417754888534546</left_val>\n                            <right_val>-0.1554504036903381</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 2 2 18 -1.</_>\n                                    <_>12 8 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0537596195936203</threshold>\n                            <left_val>0.5421931743621826</left_val>\n                            <right_val>-0.2048082947731018</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 6 8 6 -1.</_>\n                                    <_>8 9 8 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0341711901128292</threshold>\n                            <left_val>-0.2338819056749344</left_val>\n                            <right_val>0.4841090142726898</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.4562760591506958</stage_threshold>\n                <parent>-1</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 17 18 -1.</_>\n                                    <_>2 6 17 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.2172762006521225</threshold>\n                            <left_val>0.7109889984130859</left_val>\n                            <right_val>-0.5936073064804077</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 10 1 8 -1.</_>\n                                    <_>10 14 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0120719699189067</threshold>\n                            <left_val>-0.2824048101902008</left_val>\n                            <right_val>0.5901355147361755</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 10 9 2 -1.</_>\n                                    <_>10 10 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0178541392087936</threshold>\n                            <left_val>0.5313752293586731</left_val>\n                            <right_val>-0.2275896072387695</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 1 6 6 -1.</_>\n                                    <_>5 3 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0223336108028889</threshold>\n                            <left_val>-0.1755609959363937</left_val>\n                            <right_val>0.6335613727569580</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 1 15 9 -1.</_>\n                                    <_>3 4 15 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0914200171828270</threshold>\n                            <left_val>0.6156309247016907</left_val>\n                            <right_val>-0.1689953058958054</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 3 9 6 -1.</_>\n                                    <_>6 5 9 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0289736501872540</threshold>\n                            <left_val>-0.1225007995963097</left_val>\n                            <right_val>0.7440117001533508</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 17 6 3 -1.</_>\n                                    <_>10 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.8203463926911354e-003</threshold>\n                            <left_val>0.1697437018156052</left_val>\n                            <right_val>-0.6544165015220642</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 10 9 1 -1.</_>\n                                    <_>12 10 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0203404892235994</threshold>\n                            <left_val>-0.1255664974451065</left_val>\n                            <right_val>0.8271045088768005</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 7 6 11 -1.</_>\n                                    <_>3 7 2 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0119261499494314</threshold>\n                            <left_val>0.3860568106174469</left_val>\n                            <right_val>-0.2099234014749527</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 18 3 1 -1.</_>\n                                    <_>10 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.7281101625412703e-004</threshold>\n                            <left_val>-0.6376119256019592</left_val>\n                            <right_val>0.1295239031314850</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 16 1 2 -1.</_>\n                                    <_>16 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.8322050891583785e-005</threshold>\n                            <left_val>-0.3463147878646851</left_val>\n                            <right_val>0.2292426973581314</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 17 6 3 -1.</_>\n                                    <_>11 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.0854417756199837e-003</threshold>\n                            <left_val>-0.6366580128669739</left_val>\n                            <right_val>0.1307865977287293</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.2550230026245117</stage_threshold>\n                <parent>0</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 0 5 18 -1.</_>\n                                    <_>8 6 5 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1181226968765259</threshold>\n                            <left_val>0.6784452199935913</left_val>\n                            <right_val>-0.5004578232765198</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 9 7 -1.</_>\n                                    <_>9 7 3 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0343327596783638</threshold>\n                            <left_val>0.6718636155128479</left_val>\n                            <right_val>-0.3574487864971161</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 6 6 10 -1.</_>\n                                    <_>16 6 2 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0215307995676994</threshold>\n                            <left_val>0.7222070097923279</left_val>\n                            <right_val>-0.1819241940975189</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 8 9 5 -1.</_>\n                                    <_>12 8 3 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0219099707901478</threshold>\n                            <left_val>0.6652938723564148</left_val>\n                            <right_val>-0.2751022875308991</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 7 9 6 -1.</_>\n                                    <_>6 7 3 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0287135392427444</threshold>\n                            <left_val>0.6995570063591003</left_val>\n                            <right_val>-0.1961558014154434</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 7 6 6 -1.</_>\n                                    <_>3 7 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0114674801006913</threshold>\n                            <left_val>0.5926734805107117</left_val>\n                            <right_val>-0.2209735065698624</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 4 18 -1.</_>\n                                    <_>16 6 4 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0226111691445112</threshold>\n                            <left_val>0.3448306918144226</left_val>\n                            <right_val>-0.3837955892086029</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 17 3 3 -1.</_>\n                                    <_>0 18 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.9308089977130294e-003</threshold>\n                            <left_val>-0.7944571971893311</left_val>\n                            <right_val>0.1562865972518921</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 2 1 -1.</_>\n                                    <_>17 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.6419910833938047e-005</threshold>\n                            <left_val>-0.3089601099491119</left_val>\n                            <right_val>0.3543108999729157</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.3728189468383789</stage_threshold>\n                <parent>1</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 20 12 -1.</_>\n                                    <_>0 14 20 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1988652050495148</threshold>\n                            <left_val>-0.5286070108413696</left_val>\n                            <right_val>0.3553672134876251</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 6 9 8 -1.</_>\n                                    <_>9 6 3 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0360089391469955</threshold>\n                            <left_val>0.4210968911647797</left_val>\n                            <right_val>-0.3934898078441620</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 3 12 9 -1.</_>\n                                    <_>5 6 12 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0775698497891426</threshold>\n                            <left_val>0.4799154102802277</left_val>\n                            <right_val>-0.2512216866016388</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 16 1 2 -1.</_>\n                                    <_>4 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.2630853285081685e-005</threshold>\n                            <left_val>-0.3847548961639404</left_val>\n                            <right_val>0.3184922039508820</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 10 2 1 -1.</_>\n                                    <_>19 10 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.2773229759186506e-004</threshold>\n                            <left_val>-0.2642731964588165</left_val>\n                            <right_val>0.3254724144935608</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 8 6 5 -1.</_>\n                                    <_>11 8 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0185748506337404</threshold>\n                            <left_val>0.4673658907413483</left_val>\n                            <right_val>-0.1506727039813995</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 2 1 -1.</_>\n                                    <_>1 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.0008762122597545e-005</threshold>\n                            <left_val>0.2931315004825592</left_val>\n                            <right_val>-0.2536509931087494</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 6 6 -1.</_>\n                                    <_>8 8 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0185521300882101</threshold>\n                            <left_val>0.4627366065979004</left_val>\n                            <right_val>-0.1314805001020432</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 7 6 7 -1.</_>\n                                    <_>13 7 2 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0130304200574756</threshold>\n                            <left_val>0.4162721931934357</left_val>\n                            <right_val>-0.1775148957967758</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 14 1 2 -1.</_>\n                                    <_>19 15 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.5694141085259616e-005</threshold>\n                            <left_val>-0.2803510129451752</left_val>\n                            <right_val>0.2668074071407318</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 1 2 -1.</_>\n                                    <_>6 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.7005260451696813e-004</threshold>\n                            <left_val>-0.2702724933624268</left_val>\n                            <right_val>0.2398165017366409</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 7 2 7 -1.</_>\n                                    <_>15 7 1 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.3129199873656034e-003</threshold>\n                            <left_val>0.4441143870353699</left_val>\n                            <right_val>-0.1442888975143433</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 2 4 -1.</_>\n                                    <_>7 8 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.7583490116521716e-003</threshold>\n                            <left_val>-0.1612619012594223</left_val>\n                            <right_val>0.4294076859951019</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 8 12 6 -1.</_>\n                                    <_>5 10 12 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0251947492361069</threshold>\n                            <left_val>0.4068729877471924</left_val>\n                            <right_val>-0.1820258051156998</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 17 1 3 -1.</_>\n                                    <_>2 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.4031709870323539e-003</threshold>\n                            <left_val>0.0847597867250443</left_val>\n                            <right_val>-0.8001856803894043</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 3 6 -1.</_>\n                                    <_>7 7 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.3991729877889156e-003</threshold>\n                            <left_val>0.5576609969139099</left_val>\n                            <right_val>-0.1184315979480743</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.2879480123519897</stage_threshold>\n                <parent>2</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 9 12 -1.</_>\n                                    <_>9 7 3 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0299430806189775</threshold>\n                            <left_val>0.3581081032752991</left_val>\n                            <right_val>-0.3848763108253479</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 2 11 12 -1.</_>\n                                    <_>6 6 11 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1256738007068634</threshold>\n                            <left_val>0.3931693136692047</left_val>\n                            <right_val>-0.3001225888729096</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 12 5 8 -1.</_>\n                                    <_>1 16 5 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.3635272197425365e-003</threshold>\n                            <left_val>-0.4390861988067627</left_val>\n                            <right_val>0.1925701051950455</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 7 6 7 -1.</_>\n                                    <_>16 7 2 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.0971820279955864e-003</threshold>\n                            <left_val>0.3990666866302490</left_val>\n                            <right_val>-0.2340787053108215</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 8 6 6 -1.</_>\n                                    <_>12 8 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0165979098528624</threshold>\n                            <left_val>0.4209528863430023</left_val>\n                            <right_val>-0.2267484068870544</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 18 4 2 -1.</_>\n                                    <_>16 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.0199299324303865e-003</threshold>\n                            <left_val>-0.7415673136711121</left_val>\n                            <right_val>0.1260118931531906</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 2 3 -1.</_>\n                                    <_>18 18 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5202340437099338e-003</threshold>\n                            <left_val>-0.7615460157394409</left_val>\n                            <right_val>0.0863736122846603</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 7 3 7 -1.</_>\n                                    <_>10 7 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.9663940444588661e-003</threshold>\n                            <left_val>0.4218223989009857</left_val>\n                            <right_val>-0.1790491938591003</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 6 6 8 -1.</_>\n                                    <_>7 6 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0192076005041599</threshold>\n                            <left_val>0.4689489901065826</left_val>\n                            <right_val>-0.1437875032424927</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 6 6 11 -1.</_>\n                                    <_>4 6 2 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0122226802632213</threshold>\n                            <left_val>0.3284207880496979</left_val>\n                            <right_val>-0.2180214971303940</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 10 12 8 -1.</_>\n                                    <_>8 14 12 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0575486682355404</threshold>\n                            <left_val>-0.3676880896091461</left_val>\n                            <right_val>0.2435711026191711</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 17 6 3 -1.</_>\n                                    <_>9 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.5794079825282097e-003</threshold>\n                            <left_val>-0.7224506735801697</left_val>\n                            <right_val>0.0636645630002022</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 9 3 3 -1.</_>\n                                    <_>11 9 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9545740690082312e-003</threshold>\n                            <left_val>0.3584643900394440</left_val>\n                            <right_val>-0.1669632941484451</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 8 3 6 -1.</_>\n                                    <_>9 8 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.2017991654574871e-003</threshold>\n                            <left_val>0.3909480869770050</left_val>\n                            <right_val>-0.1204179003834724</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 0 6 5 -1.</_>\n                                    <_>9 0 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0136249903589487</threshold>\n                            <left_val>-0.5876771807670593</left_val>\n                            <right_val>0.0884047299623489</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 1 3 -1.</_>\n                                    <_>6 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.2853112467564642e-005</threshold>\n                            <left_val>-0.2634845972061157</left_val>\n                            <right_val>0.2141927927732468</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 4 2 -1.</_>\n                                    <_>0 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6782939676195383e-003</threshold>\n                            <left_val>-0.7839016914367676</left_val>\n                            <right_val>0.0805269628763199</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 11 9 -1.</_>\n                                    <_>4 4 11 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0705971792340279</threshold>\n                            <left_val>0.4146926105022430</left_val>\n                            <right_val>-0.1398995965719223</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 1 14 9 -1.</_>\n                                    <_>3 4 14 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0920936465263367</threshold>\n                            <left_val>-0.1305518001317978</left_val>\n                            <right_val>0.5043578147888184</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 6 4 -1.</_>\n                                    <_>2 9 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.8004386052489281e-003</threshold>\n                            <left_val>0.3660975098609924</left_val>\n                            <right_val>-0.1403664946556091</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 13 1 2 -1.</_>\n                                    <_>18 14 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5080977694597095e-005</threshold>\n                            <left_val>-0.2970443964004517</left_val>\n                            <right_val>0.2070294022560120</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 5 3 11 -1.</_>\n                                    <_>14 5 1 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9870450962334871e-003</threshold>\n                            <left_val>0.3561570048332214</left_val>\n                            <right_val>-0.1544596999883652</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 8 2 -1.</_>\n                                    <_>0 18 4 1 2.</_>\n                                    <_>4 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6441509835422039e-003</threshold>\n                            <left_val>-0.5435351729393005</left_val>\n                            <right_val>0.1029511019587517</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.2179850339889526</stage_threshold>\n                <parent>3</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 8 12 5 -1.</_>\n                                    <_>9 8 4 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0478624701499939</threshold>\n                            <left_val>0.4152823984622955</left_val>\n                            <right_val>-0.3418582081794739</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 7 11 10 -1.</_>\n                                    <_>4 12 11 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0873505324125290</threshold>\n                            <left_val>-0.3874978125095367</left_val>\n                            <right_val>0.2420420050621033</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 9 6 4 -1.</_>\n                                    <_>16 9 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0168494991958141</threshold>\n                            <left_val>0.5308247804641724</left_val>\n                            <right_val>-0.1728291064500809</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 7 6 8 -1.</_>\n                                    <_>3 7 3 8 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0288700293749571</threshold>\n                            <left_val>0.3584350943565369</left_val>\n                            <right_val>-0.2240259051322937</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 16 3 3 -1.</_>\n                                    <_>0 17 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.5679389946162701e-003</threshold>\n                            <left_val>0.1499049961566925</left_val>\n                            <right_val>-0.6560940742492676</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 11 12 1 -1.</_>\n                                    <_>11 11 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0241166595369577</threshold>\n                            <left_val>0.5588967800140381</left_val>\n                            <right_val>-0.1481028050184250</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 8 9 4 -1.</_>\n                                    <_>7 8 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0328266583383083</threshold>\n                            <left_val>0.4646868109703064</left_val>\n                            <right_val>-0.1078552976250649</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 16 6 4 -1.</_>\n                                    <_>7 16 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0152330603450537</threshold>\n                            <left_val>-0.7395442724227905</left_val>\n                            <right_val>0.0562368817627430</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 1 3 -1.</_>\n                                    <_>18 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.0209511169232428e-004</threshold>\n                            <left_val>-0.4554882049560547</left_val>\n                            <right_val>0.0970698371529579</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 1 3 -1.</_>\n                                    <_>18 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5365108205005527e-004</threshold>\n                            <left_val>0.0951472967863083</left_val>\n                            <right_val>-0.5489501953125000</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 9 4 10 -1.</_>\n                                    <_>4 9 2 5 2.</_>\n                                    <_>6 14 2 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0106389503926039</threshold>\n                            <left_val>0.4091297090053558</left_val>\n                            <right_val>-0.1230840981006622</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 8 6 4 -1.</_>\n                                    <_>6 8 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.5217830017209053e-003</threshold>\n                            <left_val>0.4028914868831635</left_val>\n                            <right_val>-0.1604878008365631</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 2 2 18 -1.</_>\n                                    <_>10 8 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1067709997296333</threshold>\n                            <left_val>0.6175932288169861</left_val>\n                            <right_val>-0.0730911865830421</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 8 6 -1.</_>\n                                    <_>0 5 4 3 2.</_>\n                                    <_>4 8 4 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0162569191306829</threshold>\n                            <left_val>-0.1310368031263351</left_val>\n                            <right_val>0.3745365142822266</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 0 6 5 -1.</_>\n                                    <_>8 0 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0206793602555990</threshold>\n                            <left_val>-0.7140290737152100</left_val>\n                            <right_val>0.0523900091648102</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 0 2 14 -1.</_>\n                                    <_>18 7 2 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0170523691922426</threshold>\n                            <left_val>0.1282286047935486</left_val>\n                            <right_val>-0.3108068108558655</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 18 4 2 -1.</_>\n                                    <_>10 18 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.7122060097754002e-003</threshold>\n                            <left_val>-0.6055650711059570</left_val>\n                            <right_val>0.0818847566843033</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 17 6 3 -1.</_>\n                                    <_>1 18 6 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.0851430235779844e-005</threshold>\n                            <left_val>-0.2681298851966858</left_val>\n                            <right_val>0.1445384025573731</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 8 3 5 -1.</_>\n                                    <_>12 8 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.9284431412816048e-003</threshold>\n                            <left_val>-0.0787953510880470</left_val>\n                            <right_val>0.5676258206367493</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 8 3 4 -1.</_>\n                                    <_>12 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.5217379443347454e-003</threshold>\n                            <left_val>0.3706862926483154</left_val>\n                            <right_val>-0.1362057030200958</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 0 6 5 -1.</_>\n                                    <_>13 0 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0224261991679668</threshold>\n                            <left_val>-0.6870499849319458</left_val>\n                            <right_val>0.0510628595948219</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 7 6 7 -1.</_>\n                                    <_>3 7 2 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.6451441273093224e-003</threshold>\n                            <left_val>0.2349222004413605</left_val>\n                            <right_val>-0.1790595948696137</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 13 1 3 -1.</_>\n                                    <_>0 14 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.1175329564139247e-003</threshold>\n                            <left_val>-0.5986905097961426</left_val>\n                            <right_val>0.0743244364857674</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 2 9 6 -1.</_>\n                                    <_>3 4 9 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0192127898335457</threshold>\n                            <left_val>-0.1570255011320114</left_val>\n                            <right_val>0.2973746955394745</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 6 9 2 -1.</_>\n                                    <_>8 7 9 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.6293429806828499e-003</threshold>\n                            <left_val>-0.0997690185904503</left_val>\n                            <right_val>0.4213027060031891</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 14 3 6 -1.</_>\n                                    <_>0 16 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.5671862363815308e-003</threshold>\n                            <left_val>-0.6085879802703857</left_val>\n                            <right_val>0.0735062584280968</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 11 6 4 -1.</_>\n                                    <_>3 11 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0112179601565003</threshold>\n                            <left_val>-0.1032081022858620</left_val>\n                            <right_val>0.4190984964370728</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.2905240058898926</stage_threshold>\n                <parent>4</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 9 9 3 -1.</_>\n                                    <_>9 9 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0174864400178194</threshold>\n                            <left_val>0.3130728006362915</left_val>\n                            <right_val>-0.3368118107318878</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 0 9 6 -1.</_>\n                                    <_>6 2 9 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0307146497070789</threshold>\n                            <left_val>-0.1876619011163712</left_val>\n                            <right_val>0.5378080010414124</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 5 6 6 -1.</_>\n                                    <_>8 7 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0221887193620205</threshold>\n                            <left_val>0.3663788139820099</left_val>\n                            <right_val>-0.1612481027841568</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 12 2 1 -1.</_>\n                                    <_>2 12 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.0700771680567414e-005</threshold>\n                            <left_val>0.2124571055173874</left_val>\n                            <right_val>-0.2844462096691132</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 10 6 2 -1.</_>\n                                    <_>12 10 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.0170420221984386e-003</threshold>\n                            <left_val>0.3954311013221741</left_val>\n                            <right_val>-0.1317359060049057</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 8 6 6 -1.</_>\n                                    <_>15 8 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.8563609384000301e-003</threshold>\n                            <left_val>0.3037385940551758</left_val>\n                            <right_val>-0.2065781950950623</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 16 6 4 -1.</_>\n                                    <_>8 16 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0141292596235871</threshold>\n                            <left_val>-0.7650300860404968</left_val>\n                            <right_val>0.0982131883502007</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 0 9 9 -1.</_>\n                                    <_>8 3 9 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0479154810309410</threshold>\n                            <left_val>0.4830738902091980</left_val>\n                            <right_val>-0.1300680935382843</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 1 3 -1.</_>\n                                    <_>18 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.7032979637151584e-005</threshold>\n                            <left_val>-0.2521657049655914</left_val>\n                            <right_val>0.2438668012619019</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 1 3 -1.</_>\n                                    <_>18 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0221180273219943e-003</threshold>\n                            <left_val>0.0688576027750969</left_val>\n                            <right_val>-0.6586114168167114</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 10 3 3 -1.</_>\n                                    <_>8 10 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6056109927594662e-003</threshold>\n                            <left_val>0.4294202923774719</left_val>\n                            <right_val>-0.1302246004343033</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 14 2 2 -1.</_>\n                                    <_>9 14 1 1 2.</_>\n                                    <_>10 15 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.4505340813193470e-005</threshold>\n                            <left_val>-0.1928862035274506</left_val>\n                            <right_val>0.2895849943161011</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 14 2 2 -1.</_>\n                                    <_>9 14 1 1 2.</_>\n                                    <_>10 15 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.6721157054416835e-005</threshold>\n                            <left_val>0.3029071092605591</left_val>\n                            <right_val>-0.1985436975955963</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 19 12 -1.</_>\n                                    <_>0 14 19 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.2628143131732941</threshold>\n                            <left_val>-0.2329394072294235</left_val>\n                            <right_val>0.2369246035814285</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 6 9 14 -1.</_>\n                                    <_>10 6 3 14 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0235696695744991</threshold>\n                            <left_val>0.1940104067325592</left_val>\n                            <right_val>-0.2848461866378784</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 8 3 4 -1.</_>\n                                    <_>14 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.9120172150433064e-003</threshold>\n                            <left_val>0.5537897944450378</left_val>\n                            <right_val>-0.0956656783819199</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 17 1 3 -1.</_>\n                                    <_>4 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0788799853762612e-005</threshold>\n                            <left_val>-0.2391265928745270</left_val>\n                            <right_val>0.2179948985576630</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 9 6 3 -1.</_>\n                                    <_>6 9 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.8732017427682877e-003</threshold>\n                            <left_val>0.4069742858409882</left_val>\n                            <right_val>-0.1276804059743881</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 18 5 2 -1.</_>\n                                    <_>2 19 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6778609715402126e-003</threshold>\n                            <left_val>-0.5774465799331665</left_val>\n                            <right_val>0.0973247885704041</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 8 2 2 -1.</_>\n                                    <_>7 8 1 1 2.</_>\n                                    <_>8 9 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6832430739887059e-004</threshold>\n                            <left_val>0.2902188003063202</left_val>\n                            <right_val>-0.1683126986026764</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 8 2 2 -1.</_>\n                                    <_>7 8 1 1 2.</_>\n                                    <_>8 9 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.8687182394787669e-005</threshold>\n                            <left_val>-0.1955157071352005</left_val>\n                            <right_val>0.2772096991539002</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 10 13 2 -1.</_>\n                                    <_>5 11 13 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0129535002633929</threshold>\n                            <left_val>-0.0968383178114891</left_val>\n                            <right_val>0.4032387137413025</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 8 1 9 -1.</_>\n                                    <_>10 11 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0130439596250653</threshold>\n                            <left_val>0.4719856977462769</left_val>\n                            <right_val>-0.0892875492572784</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 8 2 12 -1.</_>\n                                    <_>15 8 1 6 2.</_>\n                                    <_>16 14 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.0261781066656113e-003</threshold>\n                            <left_val>-0.1362338066101074</left_val>\n                            <right_val>0.3068627119064331</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 3 5 -1.</_>\n                                    <_>5 0 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.0438038781285286e-003</threshold>\n                            <left_val>-0.7795410156250000</left_val>\n                            <right_val>0.0573163107037544</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 6 3 7 -1.</_>\n                                    <_>13 6 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2507249377667904e-003</threshold>\n                            <left_val>0.3087705969810486</left_val>\n                            <right_val>-0.1500630974769592</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 16 6 4 -1.</_>\n                                    <_>9 16 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0158268101513386</threshold>\n                            <left_val>0.0645518898963928</left_val>\n                            <right_val>-0.7245556712150574</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 16 2 1 -1.</_>\n                                    <_>10 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.5864507632795721e-005</threshold>\n                            <left_val>-0.1759884059429169</left_val>\n                            <right_val>0.2321038991212845</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.1600480079650879</stage_threshold>\n                <parent>5</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 10 9 2 -1.</_>\n                                    <_>9 10 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0278548691421747</threshold>\n                            <left_val>0.4551844894886017</left_val>\n                            <right_val>-0.1809991002082825</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 6 15 14 -1.</_>\n                                    <_>0 13 15 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1289504021406174</threshold>\n                            <left_val>-0.5256553292274475</left_val>\n                            <right_val>0.1618890017271042</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 1 5 6 -1.</_>\n                                    <_>9 3 5 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0244031809270382</threshold>\n                            <left_val>-0.1497496068477631</left_val>\n                            <right_val>0.4235737919807434</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 9 3 4 -1.</_>\n                                    <_>4 9 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4458570405840874e-003</threshold>\n                            <left_val>0.3294866979122162</left_val>\n                            <right_val>-0.1744769066572189</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 7 3 6 -1.</_>\n                                    <_>6 7 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5336529836058617e-003</threshold>\n                            <left_val>0.4742664098739624</left_val>\n                            <right_val>-0.0736183598637581</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 16 1 2 -1.</_>\n                                    <_>17 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.1358150813030079e-005</threshold>\n                            <left_val>-0.3042193055152893</left_val>\n                            <right_val>0.1563327014446259</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 8 6 12 -1.</_>\n                                    <_>11 8 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0162256807088852</threshold>\n                            <left_val>0.2300218045711517</left_val>\n                            <right_val>-0.2035982012748718</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 10 6 1 -1.</_>\n                                    <_>8 10 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.6007009223103523e-003</threshold>\n                            <left_val>0.4045926928520203</left_val>\n                            <right_val>-0.1348544061183929</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 17 9 3 -1.</_>\n                                    <_>10 17 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0219289995729923</threshold>\n                            <left_val>-0.6872448921203613</left_val>\n                            <right_val>0.0806842669844627</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 18 6 2 -1.</_>\n                                    <_>14 19 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.8971210122108459e-003</threshold>\n                            <left_val>-0.6961960792541504</left_val>\n                            <right_val>0.0485452190041542</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 5 3 14 -1.</_>\n                                    <_>10 5 1 14 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.4074649922549725e-003</threshold>\n                            <left_val>0.2516626119613648</left_val>\n                            <right_val>-0.1623664945363998</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 16 9 4 -1.</_>\n                                    <_>11 16 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0284371692687273</threshold>\n                            <left_val>0.0603942610323429</left_val>\n                            <right_val>-0.6674445867538452</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 4 14 -1.</_>\n                                    <_>0 7 4 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0832128822803497</threshold>\n                            <left_val>0.0643579214811325</left_val>\n                            <right_val>-0.5362604260444641</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 6 3 -1.</_>\n                                    <_>10 1 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0124193299561739</threshold>\n                            <left_val>-0.7081686258316040</left_val>\n                            <right_val>0.0575266107916832</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 3 4 -1.</_>\n                                    <_>7 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.6992599964141846e-003</threshold>\n                            <left_val>0.5125433206558228</left_val>\n                            <right_val>-0.0873508006334305</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 8 3 4 -1.</_>\n                                    <_>5 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.8025809489190578e-004</threshold>\n                            <left_val>0.2668766081333160</left_val>\n                            <right_val>-0.1796150952577591</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 1 6 5 -1.</_>\n                                    <_>7 1 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0197243392467499</threshold>\n                            <left_val>-0.6756373047828674</left_val>\n                            <right_val>0.0729419067502022</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 18 1 2 -1.</_>\n                                    <_>1 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0269250487908721e-003</threshold>\n                            <left_val>0.0539193190634251</left_val>\n                            <right_val>-0.5554018020629883</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 0 6 6 -1.</_>\n                                    <_>7 2 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0259571895003319</threshold>\n                            <left_val>0.5636252760887146</left_val>\n                            <right_val>-0.0718983933329582</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 4 2 -1.</_>\n                                    <_>0 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.2552699772641063e-003</threshold>\n                            <left_val>-0.5034663081169128</left_val>\n                            <right_val>0.0896914526820183</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 3 8 12 -1.</_>\n                                    <_>12 7 8 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0499705784022808</threshold>\n                            <left_val>0.1768511980772018</left_val>\n                            <right_val>-0.2230195999145508</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 9 3 4 -1.</_>\n                                    <_>13 9 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9899610672146082e-003</threshold>\n                            <left_val>0.3912242054939270</left_val>\n                            <right_val>-0.1014975011348724</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 8 3 5 -1.</_>\n                                    <_>13 8 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.8546842299401760e-003</threshold>\n                            <left_val>-0.1177017986774445</left_val>\n                            <right_val>0.4219093918800354</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 2 1 -1.</_>\n                                    <_>17 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0448860120959580e-004</threshold>\n                            <left_val>-0.1733397990465164</left_val>\n                            <right_val>0.2234444022178650</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 17 1 3 -1.</_>\n                                    <_>5 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.9689260524464771e-005</threshold>\n                            <left_val>-0.2340963035821915</left_val>\n                            <right_val>0.1655824035406113</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 2 3 6 -1.</_>\n                                    <_>10 4 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0134239196777344</threshold>\n                            <left_val>0.4302381873130798</left_val>\n                            <right_val>-0.0997236520051956</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 17 2 3 -1.</_>\n                                    <_>4 18 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.2581999655812979e-003</threshold>\n                            <left_val>0.0727209895849228</left_val>\n                            <right_val>-0.5750101804733276</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 7 1 9 -1.</_>\n                                    <_>12 10 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0125462803989649</threshold>\n                            <left_val>0.3618457913398743</left_val>\n                            <right_val>-0.1145701035857201</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 6 3 9 -1.</_>\n                                    <_>8 6 1 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.8705769218504429e-003</threshold>\n                            <left_val>0.2821053862571716</left_val>\n                            <right_val>-0.1236755028367043</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 13 3 6 -1.</_>\n                                    <_>17 15 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0197856407612562</threshold>\n                            <left_val>0.0478767491877079</left_val>\n                            <right_val>-0.8066623806953430</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 7 3 8 -1.</_>\n                                    <_>8 7 1 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.7588930465281010e-003</threshold>\n                            <left_val>-0.1092538982629776</left_val>\n                            <right_val>0.3374697864055634</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 0 3 5 -1.</_>\n                                    <_>6 0 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.9974269717931747e-003</threshold>\n                            <left_val>-0.8029593825340271</left_val>\n                            <right_val>0.0457067005336285</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 6 9 8 -1.</_>\n                                    <_>7 6 3 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0130334803834558</threshold>\n                            <left_val>0.1868043988943100</left_val>\n                            <right_val>-0.1768891066312790</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 9 3 3 -1.</_>\n                                    <_>3 9 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3742579612880945e-003</threshold>\n                            <left_val>0.2772547900676727</left_val>\n                            <right_val>-0.1280900985002518</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 18 4 2 -1.</_>\n                                    <_>16 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7657810132950544e-003</threshold>\n                            <left_val>0.0907589420676231</left_val>\n                            <right_val>-0.4259473979473114</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 10 3 10 -1.</_>\n                                    <_>17 15 3 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.8941841446794569e-004</threshold>\n                            <left_val>-0.3881632983684540</left_val>\n                            <right_val>0.0892677977681160</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.2257250547409058</stage_threshold>\n                <parent>6</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 9 6 4 -1.</_>\n                                    <_>10 9 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0144692296162248</threshold>\n                            <left_val>0.3750782907009125</left_val>\n                            <right_val>-0.2492828965187073</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 2 10 12 -1.</_>\n                                    <_>5 6 10 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1331762969493866</threshold>\n                            <left_val>0.3016637861728668</left_val>\n                            <right_val>-0.2241407036781311</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 9 6 3 -1.</_>\n                                    <_>8 9 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0101321600377560</threshold>\n                            <left_val>0.3698559105396271</left_val>\n                            <right_val>-0.1785001009702683</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 7 3 7 -1.</_>\n                                    <_>12 7 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.8511182218790054e-003</threshold>\n                            <left_val>0.4608676135540009</left_val>\n                            <right_val>-0.1293139010667801</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 8 6 4 -1.</_>\n                                    <_>14 8 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0142958397045732</threshold>\n                            <left_val>0.4484142959117889</left_val>\n                            <right_val>-0.1022624000906944</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 8 6 5 -1.</_>\n                                    <_>16 8 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.9606940485537052e-003</threshold>\n                            <left_val>0.2792798876762390</left_val>\n                            <right_val>-0.1532382965087891</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 12 2 4 -1.</_>\n                                    <_>12 14 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0109327696263790</threshold>\n                            <left_val>-0.1514174044132233</left_val>\n                            <right_val>0.3988964855670929</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 15 1 2 -1.</_>\n                                    <_>3 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0430990086169913e-005</threshold>\n                            <left_val>-0.2268157005310059</left_val>\n                            <right_val>0.2164438962936401</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 7 3 4 -1.</_>\n                                    <_>13 7 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.8431681245565414e-003</threshold>\n                            <left_val>0.4542014896869659</left_val>\n                            <right_val>-0.1258715987205505</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 0 6 6 -1.</_>\n                                    <_>12 0 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0223462097346783</threshold>\n                            <left_val>-0.6269019246101379</left_val>\n                            <right_val>0.0824031233787537</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 6 3 8 -1.</_>\n                                    <_>11 6 1 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.8836669884622097e-003</threshold>\n                            <left_val>0.2635925114154816</left_val>\n                            <right_val>-0.1468663066625595</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 17 1 2 -1.</_>\n                                    <_>16 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5506002758629620e-005</threshold>\n                            <left_val>-0.2450702041387558</left_val>\n                            <right_val>0.1667888015508652</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 16 1 3 -1.</_>\n                                    <_>16 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.9026997294276953e-004</threshold>\n                            <left_val>-0.4264996051788330</left_val>\n                            <right_val>0.0899735614657402</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 11 1 2 -1.</_>\n                                    <_>11 12 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.4861579984426498e-003</threshold>\n                            <left_val>-0.1204025000333786</left_val>\n                            <right_val>0.3009765148162842</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 7 6 9 -1.</_>\n                                    <_>5 7 2 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0119883399456739</threshold>\n                            <left_val>0.2785247862339020</left_val>\n                            <right_val>-0.1224434003233910</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 18 9 1 -1.</_>\n                                    <_>7 18 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0105022396892309</threshold>\n                            <left_val>0.0404527597129345</left_val>\n                            <right_val>-0.7405040860176086</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 11 4 9 -1.</_>\n                                    <_>0 14 4 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0309630092233419</threshold>\n                            <left_val>-0.6284269094467163</left_val>\n                            <right_val>0.0480137616395950</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 17 6 3 -1.</_>\n                                    <_>11 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0114145204424858</threshold>\n                            <left_val>0.0394052118062973</left_val>\n                            <right_val>-0.7167412042617798</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 8 6 12 -1.</_>\n                                    <_>9 8 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0123370001092553</threshold>\n                            <left_val>0.1994132995605469</left_val>\n                            <right_val>-0.1927430033683777</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 3 4 -1.</_>\n                                    <_>7 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.9942267835140228e-003</threshold>\n                            <left_val>0.5131816267967224</left_val>\n                            <right_val>-0.0616580583155155</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 17 1 3 -1.</_>\n                                    <_>3 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.1923230485990644e-003</threshold>\n                            <left_val>-0.7260529994964600</left_val>\n                            <right_val>0.0506527200341225</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 9 6 4 -1.</_>\n                                    <_>13 9 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.4582789093255997e-003</threshold>\n                            <left_val>0.2960307896137238</left_val>\n                            <right_val>-0.1175478994846344</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 1 3 2 -1.</_>\n                                    <_>7 1 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7877509128302336e-003</threshold>\n                            <left_val>0.0450687110424042</left_val>\n                            <right_val>-0.6953541040420532</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 2 1 -1.</_>\n                                    <_>2 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2503209766000509e-004</threshold>\n                            <left_val>0.2004725039005280</left_val>\n                            <right_val>-0.1577524989843369</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 2 14 -1.</_>\n                                    <_>1 0 1 7 2.</_>\n                                    <_>2 7 1 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.0367889925837517e-003</threshold>\n                            <left_val>0.2929981946945190</left_val>\n                            <right_val>-0.1170049980282784</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 5 11 8 -1.</_>\n                                    <_>5 9 11 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0747421607375145</threshold>\n                            <left_val>-0.1139231994748116</left_val>\n                            <right_val>0.3025662004947662</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 3 5 6 -1.</_>\n                                    <_>9 5 5 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0202555190771818</threshold>\n                            <left_val>-0.1051589027047157</left_val>\n                            <right_val>0.4067046046257019</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 9 5 10 -1.</_>\n                                    <_>7 14 5 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0442145094275475</threshold>\n                            <left_val>-0.2763164043426514</left_val>\n                            <right_val>0.1236386969685555</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 10 2 2 -1.</_>\n                                    <_>16 10 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.7259558495134115e-004</threshold>\n                            <left_val>0.2435503005981445</left_val>\n                            <right_val>-0.1330094933509827</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 8 2 -1.</_>\n                                    <_>0 19 8 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4453739169985056e-003</threshold>\n                            <left_val>-0.5386617183685303</left_val>\n                            <right_val>0.0625106468796730</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 17 1 3 -1.</_>\n                                    <_>7 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.2725353422574699e-005</threshold>\n                            <left_val>-0.2077220976352692</left_val>\n                            <right_val>0.1627043932676315</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 2 11 6 -1.</_>\n                                    <_>7 4 11 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0366271100938320</threshold>\n                            <left_val>0.3656840920448303</left_val>\n                            <right_val>-0.0903302803635597</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 3 9 3 -1.</_>\n                                    <_>8 4 9 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.0996399000287056e-003</threshold>\n                            <left_val>-0.1318302005529404</left_val>\n                            <right_val>0.2535429894924164</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 2 2 -1.</_>\n                                    <_>0 10 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4709280114620924e-003</threshold>\n                            <left_val>-0.5685349702835083</left_val>\n                            <right_val>0.0535054318606853</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 3 6 -1.</_>\n                                    <_>0 7 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0141146704554558</threshold>\n                            <left_val>-0.4859901070594788</left_val>\n                            <right_val>0.0584852509200573</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 2 2 -1.</_>\n                                    <_>6 7 1 1 2.</_>\n                                    <_>7 8 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.4537261864170432e-004</threshold>\n                            <left_val>-0.0800936371088028</left_val>\n                            <right_val>0.4026564955711365</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 6 3 6 -1.</_>\n                                    <_>8 6 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.1098632179200649e-003</threshold>\n                            <left_val>0.4470323920249939</left_val>\n                            <right_val>-0.0629474371671677</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 1 6 4 -1.</_>\n                                    <_>14 1 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0191259607672691</threshold>\n                            <left_val>-0.6642286777496338</left_val>\n                            <right_val>0.0498227700591087</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 11 6 8 -1.</_>\n                                    <_>11 11 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.0773010589182377e-003</threshold>\n                            <left_val>0.1737940013408661</left_val>\n                            <right_val>-0.1685059964656830</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 15 3 3 -1.</_>\n                                    <_>17 16 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9198289848864079e-003</threshold>\n                            <left_val>-0.6011028289794922</left_val>\n                            <right_val>0.0574279390275478</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 6 3 9 -1.</_>\n                                    <_>6 9 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0249021500349045</threshold>\n                            <left_val>0.2339798063039780</left_val>\n                            <right_val>-0.1181845963001251</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 8 6 -1.</_>\n                                    <_>0 5 4 3 2.</_>\n                                    <_>4 8 4 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0201477799564600</threshold>\n                            <left_val>-0.0894598215818405</left_val>\n                            <right_val>0.3602440059185028</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 6 1 3 -1.</_>\n                                    <_>0 7 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.7597640398889780e-003</threshold>\n                            <left_val>0.0494584403932095</left_val>\n                            <right_val>-0.6310262084007263</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 0 2 6 -1.</_>\n                                    <_>18 0 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3812039978802204e-003</threshold>\n                            <left_val>-0.1521805971860886</left_val>\n                            <right_val>0.1897173970937729</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 17 6 3 -1.</_>\n                                    <_>12 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0109045403078198</threshold>\n                            <left_val>-0.5809738039970398</left_val>\n                            <right_val>0.0448627285659313</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 15 2 2 -1.</_>\n                                    <_>13 15 1 1 2.</_>\n                                    <_>14 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5157178798690438e-005</threshold>\n                            <left_val>-0.1377734988927841</left_val>\n                            <right_val>0.1954316049814224</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 12 3 -1.</_>\n                                    <_>4 1 12 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.8649770431220531e-003</threshold>\n                            <left_val>-0.1030222997069359</left_val>\n                            <right_val>0.2537496984004974</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.2863140106201172</stage_threshold>\n                <parent>7</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 3 10 9 -1.</_>\n                                    <_>5 6 10 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1021588966250420</threshold>\n                            <left_val>0.4168125987052918</left_val>\n                            <right_val>-0.1665562987327576</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 7 9 7 -1.</_>\n                                    <_>10 7 3 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0519398190081120</threshold>\n                            <left_val>0.3302395045757294</left_val>\n                            <right_val>-0.2071571052074432</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 8 9 6 -1.</_>\n                                    <_>8 8 3 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0427177809178829</threshold>\n                            <left_val>0.2609373033046722</left_val>\n                            <right_val>-0.1601389050483704</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 16 6 2 -1.</_>\n                                    <_>0 17 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.3890418601222336e-004</threshold>\n                            <left_val>-0.3475053012371063</left_val>\n                            <right_val>0.1391891986131668</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 6 7 14 -1.</_>\n                                    <_>12 13 7 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0242643896490335</threshold>\n                            <left_val>-0.4255205988883972</left_val>\n                            <right_val>0.1357838064432144</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 7 6 8 -1.</_>\n                                    <_>15 7 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0238205995410681</threshold>\n                            <left_val>0.3174980878829956</left_val>\n                            <right_val>-0.1665204018354416</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 10 6 3 -1.</_>\n                                    <_>4 10 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.0518180727958679e-003</threshold>\n                            <left_val>0.3094717860221863</left_val>\n                            <right_val>-0.1333830058574677</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 1 3 -1.</_>\n                                    <_>18 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.8517157342284918e-004</threshold>\n                            <left_val>-0.6008226275444031</left_val>\n                            <right_val>0.0877470001578331</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 1 6 2 -1.</_>\n                                    <_>7 2 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.3705149330198765e-003</threshold>\n                            <left_val>-0.1231144964694977</left_val>\n                            <right_val>0.3833355009555817</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 0 6 4 -1.</_>\n                                    <_>6 2 6 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0134035395458341</threshold>\n                            <left_val>0.3387736976146698</left_val>\n                            <right_val>-0.1014048978686333</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 18 6 2 -1.</_>\n                                    <_>10 18 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.6856360062956810e-003</threshold>\n                            <left_val>-0.6119359731674194</left_val>\n                            <right_val>0.0477402210235596</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 6 5 2 -1.</_>\n                                    <_>7 7 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.2887418530881405e-003</threshold>\n                            <left_val>0.2527579069137573</left_val>\n                            <right_val>-0.1443451046943665</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 3 6 -1.</_>\n                                    <_>7 7 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0108767496421933</threshold>\n                            <left_val>0.5477573275566101</left_val>\n                            <right_val>-0.0594554804265499</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 18 2 2 -1.</_>\n                                    <_>18 18 1 1 2.</_>\n                                    <_>19 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.7882640026509762e-004</threshold>\n                            <left_val>0.0834103003144264</left_val>\n                            <right_val>-0.4422636926174164</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 8 3 7 -1.</_>\n                                    <_>17 8 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4550149682909250e-003</threshold>\n                            <left_val>0.2333099991083145</left_val>\n                            <right_val>-0.1396448016166687</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 16 2 3 -1.</_>\n                                    <_>0 17 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.2721839593723416e-003</threshold>\n                            <left_val>0.0604802891612053</left_val>\n                            <right_val>-0.4945608973503113</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 19 6 1 -1.</_>\n                                    <_>7 19 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.8933159559965134e-003</threshold>\n                            <left_val>-0.6683326959609985</left_val>\n                            <right_val>0.0462184995412827</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 5 6 6 -1.</_>\n                                    <_>9 7 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0264499895274639</threshold>\n                            <left_val>-0.0732353627681732</left_val>\n                            <right_val>0.4442596137523651</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 10 2 4 -1.</_>\n                                    <_>0 12 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.3706070389598608e-003</threshold>\n                            <left_val>-0.4246433973312378</left_val>\n                            <right_val>0.0686765611171722</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 4 3 -1.</_>\n                                    <_>2 9 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9559480026364326e-003</threshold>\n                            <left_val>0.1621803939342499</left_val>\n                            <right_val>-0.1822299957275391</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 10 6 9 -1.</_>\n                                    <_>3 10 2 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0306199099868536</threshold>\n                            <left_val>-0.0586433410644531</left_val>\n                            <right_val>0.5326362848281860</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 0 6 2 -1.</_>\n                                    <_>11 0 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.5765907317399979e-003</threshold>\n                            <left_val>-0.6056268215179443</left_val>\n                            <right_val>0.0533459894359112</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 1 2 1 -1.</_>\n                                    <_>15 1 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.6372493165545166e-005</threshold>\n                            <left_val>-0.1668083965778351</left_val>\n                            <right_val>0.1928416043519974</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 1 4 -1.</_>\n                                    <_>0 10 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0975950434803963e-003</threshold>\n                            <left_val>0.0441195107996464</left_val>\n                            <right_val>-0.5745884180068970</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 6 2 2 -1.</_>\n                                    <_>15 6 1 1 2.</_>\n                                    <_>16 7 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.7112718564458191e-004</threshold>\n                            <left_val>-0.1108639985322952</left_val>\n                            <right_val>0.2310539036989212</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 5 3 6 -1.</_>\n                                    <_>8 5 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.6607588455080986e-003</threshold>\n                            <left_val>0.4045628905296326</left_val>\n                            <right_val>-0.0624460913240910</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 17 1 3 -1.</_>\n                                    <_>19 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.7489158613607287e-004</threshold>\n                            <left_val>0.0648751482367516</left_val>\n                            <right_val>-0.4487104117870331</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 10 3 1 -1.</_>\n                                    <_>8 10 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.1120870476588607e-003</threshold>\n                            <left_val>-0.0938614606857300</left_val>\n                            <right_val>0.3045391142368317</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 1 6 6 -1.</_>\n                                    <_>14 1 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0238378196954727</threshold>\n                            <left_val>-0.5888742804527283</left_val>\n                            <right_val>0.0466594211757183</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 5 2 1 -1.</_>\n                                    <_>16 5 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.2272899514064193e-004</threshold>\n                            <left_val>-0.1489859968423843</left_val>\n                            <right_val>0.1770195066928864</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 2 7 4 -1.</_>\n                                    <_>8 4 7 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0244674701243639</threshold>\n                            <left_val>-0.0557896010577679</left_val>\n                            <right_val>0.4920830130577087</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 14 15 -1.</_>\n                                    <_>4 5 14 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1423932015895844</threshold>\n                            <left_val>0.1519200056791306</left_val>\n                            <right_val>-0.1877889931201935</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 8 6 6 -1.</_>\n                                    <_>9 8 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0201231203973293</threshold>\n                            <left_val>0.2178010046482086</left_val>\n                            <right_val>-0.1208190023899078</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 17 1 3 -1.</_>\n                                    <_>11 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.1513679783092812e-004</threshold>\n                            <left_val>-0.1685658991336823</left_val>\n                            <right_val>0.1645192950963974</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 16 2 4 -1.</_>\n                                    <_>12 16 1 2 2.</_>\n                                    <_>13 18 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.7556740678846836e-003</threshold>\n                            <left_val>-0.6944203972816467</left_val>\n                            <right_val>0.0394494682550430</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 13 2 1 -1.</_>\n                                    <_>11 13 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.5843912782147527e-005</threshold>\n                            <left_val>0.1894136965274811</left_val>\n                            <right_val>-0.1518384069204330</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 8 3 3 -1.</_>\n                                    <_>12 8 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.0697711780667305e-003</threshold>\n                            <left_val>0.4706459939479828</left_val>\n                            <right_val>-0.0579276196658611</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 6 8 -1.</_>\n                                    <_>4 0 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0373931787908077</threshold>\n                            <left_val>-0.7589244842529297</left_val>\n                            <right_val>0.0341160483658314</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 5 6 6 -1.</_>\n                                    <_>3 5 3 3 2.</_>\n                                    <_>6 8 3 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0159956105053425</threshold>\n                            <left_val>0.3067046999931335</left_val>\n                            <right_val>-0.0875255763530731</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 8 3 3 -1.</_>\n                                    <_>11 8 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.1183990649878979e-003</threshold>\n                            <left_val>0.2619537115097046</left_val>\n                            <right_val>-0.0912148877978325</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 17 4 2 -1.</_>\n                                    <_>5 18 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0651360498741269e-003</threshold>\n                            <left_val>-0.1742756068706513</left_val>\n                            <right_val>0.1527764052152634</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 16 5 2 -1.</_>\n                                    <_>8 17 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6029420075938106e-003</threshold>\n                            <left_val>0.3561263084411621</left_val>\n                            <right_val>-0.0766299962997437</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 4 3 3 -1.</_>\n                                    <_>0 5 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.3619908392429352e-003</threshold>\n                            <left_val>0.0493569709360600</left_val>\n                            <right_val>-0.5922877192497253</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 3 6 2 -1.</_>\n                                    <_>8 3 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0107799097895622</threshold>\n                            <left_val>-0.6392217874526978</left_val>\n                            <right_val>0.0332045406103134</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 4 9 3 -1.</_>\n                                    <_>7 4 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.3590869754552841e-003</threshold>\n                            <left_val>0.1610738933086395</left_val>\n                            <right_val>-0.1522132009267807</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 13 1 4 -1.</_>\n                                    <_>0 15 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.4596069753170013e-003</threshold>\n                            <left_val>0.0331729613244534</left_val>\n                            <right_val>-0.7500774264335632</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 17 8 3 -1.</_>\n                                    <_>0 18 8 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.1385448575019836e-003</threshold>\n                            <left_val>0.0263252798467875</left_val>\n                            <right_val>-0.7173116207122803</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 1 11 6 -1.</_>\n                                    <_>6 3 11 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0333384908735752</threshold>\n                            <left_val>0.3353661000728607</left_val>\n                            <right_val>-0.0708035901188850</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.1189440488815308</stage_threshold>\n                <parent>8</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 10 6 2 -1.</_>\n                                    <_>6 10 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0195539798587561</threshold>\n                            <left_val>-0.1043972000479698</left_val>\n                            <right_val>0.5312895178794861</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 8 1 12 -1.</_>\n                                    <_>10 14 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0221229195594788</threshold>\n                            <left_val>-0.2474727034568787</left_val>\n                            <right_val>0.2084725052118301</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 8 3 4 -1.</_>\n                                    <_>6 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.1829389519989491e-003</threshold>\n                            <left_val>0.3828943967819214</left_val>\n                            <right_val>-0.1471157968044281</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 17 1 3 -1.</_>\n                                    <_>0 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.6381728760898113e-004</threshold>\n                            <left_val>-0.6263288855552673</left_val>\n                            <right_val>0.1199325993657112</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 17 1 3 -1.</_>\n                                    <_>0 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.9958612332120538e-004</threshold>\n                            <left_val>0.0925734713673592</left_val>\n                            <right_val>-0.5516883134841919</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 8 3 4 -1.</_>\n                                    <_>14 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.1527570039033890e-003</threshold>\n                            <left_val>-0.0729298070073128</left_val>\n                            <right_val>0.5551251173019409</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 5 5 4 -1.</_>\n                                    <_>1 7 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.9388681761920452e-003</threshold>\n                            <left_val>0.2019603997468948</left_val>\n                            <right_val>-0.2091203927993774</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 14 1 2 -1.</_>\n                                    <_>18 15 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.4613410166930407e-004</threshold>\n                            <left_val>-0.2786181867122650</left_val>\n                            <right_val>0.1381741017103195</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 8 2 4 -1.</_>\n                                    <_>14 8 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.1691689509898424e-003</threshold>\n                            <left_val>0.3668589890003204</left_val>\n                            <right_val>-0.0763082429766655</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 6 6 8 -1.</_>\n                                    <_>12 6 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0221893899142742</threshold>\n                            <left_val>0.3909659981727600</left_val>\n                            <right_val>-0.1097154021263123</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 6 6 10 -1.</_>\n                                    <_>10 6 2 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.4523608200252056e-003</threshold>\n                            <left_val>0.1283859014511108</left_val>\n                            <right_val>-0.2415986955165863</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 16 1 3 -1.</_>\n                                    <_>17 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.7997002517804503e-004</threshold>\n                            <left_val>0.0719780698418617</left_val>\n                            <right_val>-0.4397650063037872</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 7 2 10 -1.</_>\n                                    <_>2 7 1 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.6783639118075371e-003</threshold>\n                            <left_val>0.2156984955072403</left_val>\n                            <right_val>-0.1420592069625855</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 9 6 3 -1.</_>\n                                    <_>7 9 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0151886399835348</threshold>\n                            <left_val>0.3645878136157990</left_val>\n                            <right_val>-0.0826759263873100</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 5 12 -1.</_>\n                                    <_>0 14 5 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0619798712432384e-003</threshold>\n                            <left_val>-0.3438040912151337</left_val>\n                            <right_val>0.0920682325959206</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 11 1 3 -1.</_>\n                                    <_>0 12 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7351920250803232e-003</threshold>\n                            <left_val>-0.6172549724578857</left_val>\n                            <right_val>0.0492144785821438</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 16 6 4 -1.</_>\n                                    <_>8 16 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0124234501272440</threshold>\n                            <left_val>-0.5855895280838013</left_val>\n                            <right_val>0.0461126007139683</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 6 2 6 -1.</_>\n                                    <_>0 8 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0130314296111465</threshold>\n                            <left_val>-0.5971078872680664</left_val>\n                            <right_val>0.0406724587082863</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 18 2 1 -1.</_>\n                                    <_>12 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.2369629694148898e-003</threshold>\n                            <left_val>-0.6833416819572449</left_val>\n                            <right_val>0.0331561788916588</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 1 9 2 -1.</_>\n                                    <_>5 2 9 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.1022108420729637e-003</threshold>\n                            <left_val>-0.0947292372584343</left_val>\n                            <right_val>0.3010224103927612</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 1 2 -1.</_>\n                                    <_>0 1 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.6952849738299847e-004</threshold>\n                            <left_val>0.0818168669939041</left_val>\n                            <right_val>-0.3519603013992310</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 9 3 3 -1.</_>\n                                    <_>16 9 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7970580374822021e-003</threshold>\n                            <left_val>0.2371897995471954</left_val>\n                            <right_val>-0.1176870986819267</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 16 1 3 -1.</_>\n                                    <_>18 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.1074528386816382e-004</threshold>\n                            <left_val>-0.4476378858089447</left_val>\n                            <right_val>0.0576824806630611</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 10 6 1 -1.</_>\n                                    <_>13 10 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.9126471169292927e-003</threshold>\n                            <left_val>0.4342541098594666</left_val>\n                            <right_val>-0.0668685734272003</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 3 4 4 -1.</_>\n                                    <_>3 3 2 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.3132149837911129e-003</threshold>\n                            <left_val>0.1815001070499420</left_val>\n                            <right_val>-0.1418032050132752</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 2 1 18 -1.</_>\n                                    <_>11 8 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0608146600425243</threshold>\n                            <left_val>0.4722171127796173</left_val>\n                            <right_val>-0.0614106394350529</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 1 5 12 -1.</_>\n                                    <_>9 5 5 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0967141836881638</threshold>\n                            <left_val>0.2768316864967346</left_val>\n                            <right_val>-0.0944900363683701</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 0 8 1 -1.</_>\n                                    <_>16 0 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.9073550142347813e-003</threshold>\n                            <left_val>-0.1227853000164032</left_val>\n                            <right_val>0.2105740010738373</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 6 3 10 -1.</_>\n                                    <_>9 6 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.0431869029998779e-003</threshold>\n                            <left_val>0.3564156889915466</left_val>\n                            <right_val>-0.0778062269091606</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 2 1 6 -1.</_>\n                                    <_>19 4 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.8800031654536724e-003</threshold>\n                            <left_val>-0.4103479087352753</left_val>\n                            <right_val>0.0696943774819374</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 6 2 2 -1.</_>\n                                    <_>18 7 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.3547428213059902e-003</threshold>\n                            <left_val>-0.7301788926124573</left_val>\n                            <right_val>0.0366551503539085</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 7 3 4 -1.</_>\n                                    <_>8 7 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6500627696514130e-003</threshold>\n                            <left_val>0.5518112778663635</left_val>\n                            <right_val>-0.0531680807471275</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 0 6 5 -1.</_>\n                                    <_>7 0 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0173973105847836</threshold>\n                            <left_val>-0.5708423256874085</left_val>\n                            <right_val>0.0502140894532204</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 3 7 3 -1.</_>\n                                    <_>0 4 7 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.8304329179227352e-003</threshold>\n                            <left_val>-0.4618028104305267</left_val>\n                            <right_val>0.0502026900649071</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 6 2 1 -1.</_>\n                                    <_>2 6 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.3255619928240776e-004</threshold>\n                            <left_val>-0.0953627303242683</left_val>\n                            <right_val>0.2598375976085663</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 8 2 10 -1.</_>\n                                    <_>4 8 1 5 2.</_>\n                                    <_>5 13 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.3100529797375202e-003</threshold>\n                            <left_val>0.2287247031927109</left_val>\n                            <right_val>-0.1053353026509285</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 18 18 2 -1.</_>\n                                    <_>2 18 9 1 2.</_>\n                                    <_>11 19 9 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.5426651164889336e-003</threshold>\n                            <left_val>-0.5699051022529602</left_val>\n                            <right_val>0.0488634593784809</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 7 4 4 -1.</_>\n                                    <_>2 7 2 2 2.</_>\n                                    <_>4 9 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.2723060362040997e-003</threshold>\n                            <left_val>0.3514518141746521</left_val>\n                            <right_val>-0.0823901072144508</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 3 3 4 -1.</_>\n                                    <_>18 3 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.8578968271613121e-003</threshold>\n                            <left_val>-0.6041762232780457</left_val>\n                            <right_val>0.0445394404232502</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 9 2 8 -1.</_>\n                                    <_>16 9 1 4 2.</_>\n                                    <_>17 13 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.5867310576140881e-003</threshold>\n                            <left_val>-0.1034090965986252</left_val>\n                            <right_val>0.2328201979398727</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 7 1 6 -1.</_>\n                                    <_>15 9 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.7427811659872532e-003</threshold>\n                            <left_val>0.2849028110504150</left_val>\n                            <right_val>-0.0980904996395111</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 2 2 2 -1.</_>\n                                    <_>14 3 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3515240279957652e-003</threshold>\n                            <left_val>0.2309643030166626</left_val>\n                            <right_val>-0.1136184036731720</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 0 2 3 -1.</_>\n                                    <_>17 1 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.2526069078594446e-003</threshold>\n                            <left_val>0.0644783228635788</left_val>\n                            <right_val>-0.4220589101314545</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 18 2 2 -1.</_>\n                                    <_>16 18 1 1 2.</_>\n                                    <_>17 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8038659840822220e-004</threshold>\n                            <left_val>-0.3807620108127594</left_val>\n                            <right_val>0.0600432902574539</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 4 4 3 -1.</_>\n                                    <_>10 5 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.9043921753764153e-003</threshold>\n                            <left_val>-0.0761049985885620</left_val>\n                            <right_val>0.3323217034339905</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 2 8 6 -1.</_>\n                                    <_>4 2 4 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.0969670563936234e-003</threshold>\n                            <left_val>0.1428779065608978</left_val>\n                            <right_val>-0.1688780039548874</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 14 6 6 -1.</_>\n                                    <_>7 16 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.9317929446697235e-003</threshold>\n                            <left_val>0.2725540995597839</left_val>\n                            <right_val>-0.0928795635700226</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 15 2 2 -1.</_>\n                                    <_>11 16 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.1471060570329428e-003</threshold>\n                            <left_val>-0.1527305990457535</left_val>\n                            <right_val>0.1970240026712418</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 1 9 4 -1.</_>\n                                    <_>10 1 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0376628898084164</threshold>\n                            <left_val>-0.5932043790817261</left_val>\n                            <right_val>0.0407386012375355</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 7 3 7 -1.</_>\n                                    <_>10 7 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.8165571428835392e-003</threshold>\n                            <left_val>0.2549408972263336</left_val>\n                            <right_val>-0.0940819606184959</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 2 2 -1.</_>\n                                    <_>6 17 1 1 2.</_>\n                                    <_>7 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.6205562325194478e-004</threshold>\n                            <left_val>0.0467957183718681</left_val>\n                            <right_val>-0.4845437109470367</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 6 3 9 -1.</_>\n                                    <_>5 6 1 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.2202551849186420e-003</threshold>\n                            <left_val>0.2468214929103851</left_val>\n                            <right_val>-0.0946739763021469</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 10 19 10 -1.</_>\n                                    <_>0 15 19 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0689865127205849</threshold>\n                            <left_val>-0.6651480197906494</left_val>\n                            <right_val>0.0359263904392719</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 17 6 1 -1.</_>\n                                    <_>7 17 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.1707608401775360e-003</threshold>\n                            <left_val>0.0258333198726177</left_val>\n                            <right_val>-0.7268627285957336</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 12 6 3 -1.</_>\n                                    <_>3 12 3 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0105362497270107</threshold>\n                            <left_val>-0.0818289965391159</left_val>\n                            <right_val>0.2976079881191254</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.1418989896774292</stage_threshold>\n                <parent>9</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 5 18 5 -1.</_>\n                                    <_>8 5 6 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0627587288618088</threshold>\n                            <left_val>0.2789908051490784</left_val>\n                            <right_val>-0.2965610921382904</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 15 6 4 -1.</_>\n                                    <_>1 17 6 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.4516479354351759e-003</threshold>\n                            <left_val>-0.3463588058948517</left_val>\n                            <right_val>0.2090384066104889</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 10 6 6 -1.</_>\n                                    <_>16 10 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.8699486330151558e-003</threshold>\n                            <left_val>0.2414488941431046</left_val>\n                            <right_val>-0.1920557022094727</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 14 4 3 -1.</_>\n                                    <_>0 15 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.4624869003891945e-003</threshold>\n                            <left_val>-0.5915178060531616</left_val>\n                            <right_val>0.1248644962906838</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 7 6 11 -1.</_>\n                                    <_>3 7 2 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.4818761572241783e-003</threshold>\n                            <left_val>0.1839154064655304</left_val>\n                            <right_val>-0.2485826015472412</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 17 7 2 -1.</_>\n                                    <_>13 18 7 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.3226840130519122e-004</threshold>\n                            <left_val>-0.3304725885391235</left_val>\n                            <right_val>0.1099926009774208</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 14 2 3 -1.</_>\n                                    <_>0 15 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.8101120367646217e-003</threshold>\n                            <left_val>0.0987440124154091</left_val>\n                            <right_val>-0.4963478147983551</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 6 2 -1.</_>\n                                    <_>3 0 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.4422430694103241e-003</threshold>\n                            <left_val>0.2934441864490509</left_val>\n                            <right_val>-0.1309475004673004</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 1 6 3 -1.</_>\n                                    <_>3 1 3 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.4148122221231461e-003</threshold>\n                            <left_val>-0.1476269960403442</left_val>\n                            <right_val>0.3327716886997223</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 2 6 -1.</_>\n                                    <_>0 10 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0155651401728392</threshold>\n                            <left_val>-0.6840490102767944</left_val>\n                            <right_val>0.0998726934194565</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 2 6 14 -1.</_>\n                                    <_>1 2 3 7 2.</_>\n                                    <_>4 9 3 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0287205204367638</threshold>\n                            <left_val>-0.1483328044414520</left_val>\n                            <right_val>0.3090257942676544</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 5 2 2 -1.</_>\n                                    <_>17 5 1 1 2.</_>\n                                    <_>18 6 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.6687392215244472e-005</threshold>\n                            <left_val>-0.1743104010820389</left_val>\n                            <right_val>0.2140295952558518</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 10 9 4 -1.</_>\n                                    <_>14 10 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0523710586130619</threshold>\n                            <left_val>-0.0701568573713303</left_val>\n                            <right_val>0.4922299087047577</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 9 12 4 -1.</_>\n                                    <_>6 9 4 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0864856913685799</threshold>\n                            <left_val>0.5075724720954895</left_val>\n                            <right_val>-0.0752942115068436</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 10 12 2 -1.</_>\n                                    <_>11 10 4 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0421698689460754</threshold>\n                            <left_val>0.4568096101284027</left_val>\n                            <right_val>-0.0902199000120163</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 13 1 2 -1.</_>\n                                    <_>2 14 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.5369830331765115e-005</threshold>\n                            <left_val>-0.2653827965259552</left_val>\n                            <right_val>0.1618953943252564</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 7 4 3 -1.</_>\n                                    <_>16 8 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.2918000146746635e-003</threshold>\n                            <left_val>0.0748901516199112</left_val>\n                            <right_val>-0.5405467152595520</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 16 1 3 -1.</_>\n                                    <_>19 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.5511651812121272e-004</threshold>\n                            <left_val>-0.4926199018955231</left_val>\n                            <right_val>0.0587239488959312</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 11 1 2 -1.</_>\n                                    <_>18 12 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5108138844370842e-005</threshold>\n                            <left_val>-0.2143210023641586</left_val>\n                            <right_val>0.1407776027917862</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 7 8 2 -1.</_>\n                                    <_>12 7 4 1 2.</_>\n                                    <_>16 8 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.9981209449470043e-003</threshold>\n                            <left_val>-0.0905473381280899</left_val>\n                            <right_val>0.3571606874465942</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 9 2 4 -1.</_>\n                                    <_>15 9 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.4929979806765914e-003</threshold>\n                            <left_val>0.2562345862388611</left_val>\n                            <right_val>-0.1422906965017319</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 2 6 4 -1.</_>\n                                    <_>14 2 3 2 2.</_>\n                                    <_>17 4 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7239411137998104e-003</threshold>\n                            <left_val>-0.1564925014972687</left_val>\n                            <right_val>0.2108871042728424</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 0 6 1 -1.</_>\n                                    <_>17 0 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.2218320518732071e-003</threshold>\n                            <left_val>-0.1507298946380615</left_val>\n                            <right_val>0.2680186927318573</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 12 2 1 -1.</_>\n                                    <_>4 12 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.3993072146549821e-004</threshold>\n                            <left_val>0.2954699099063873</left_val>\n                            <right_val>-0.1069239005446434</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 2 3 1 -1.</_>\n                                    <_>18 2 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.0113459322601557e-003</threshold>\n                            <left_val>0.0506143495440483</left_val>\n                            <right_val>-0.7168337106704712</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 16 18 2 -1.</_>\n                                    <_>7 16 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0114528704434633</threshold>\n                            <left_val>-0.1271906942129135</left_val>\n                            <right_val>0.2415277957916260</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 19 8 1 -1.</_>\n                                    <_>6 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0782170575112104e-003</threshold>\n                            <left_val>0.2481300979852676</left_val>\n                            <right_val>-0.1346119940280914</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 17 4 3 -1.</_>\n                                    <_>1 18 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.3417691010981798e-003</threshold>\n                            <left_val>0.0535783097147942</left_val>\n                            <right_val>-0.5227416753768921</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 13 1 2 -1.</_>\n                                    <_>19 14 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.9398651248775423e-005</threshold>\n                            <left_val>-0.2169874012470245</left_val>\n                            <right_val>0.1281217932701111</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 16 10 4 -1.</_>\n                                    <_>9 16 5 2 2.</_>\n                                    <_>14 18 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.0982551872730255e-003</threshold>\n                            <left_val>0.2440188974142075</left_val>\n                            <right_val>-0.1157058998942375</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 9 2 4 -1.</_>\n                                    <_>12 9 1 2 2.</_>\n                                    <_>13 11 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6289720078930259e-003</threshold>\n                            <left_val>0.2826147079467773</left_val>\n                            <right_val>-0.1065946966409683</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 11 1 9 -1.</_>\n                                    <_>19 14 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0139848599210382</threshold>\n                            <left_val>0.0427158996462822</left_val>\n                            <right_val>-0.7364631295204163</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.1255199909210205</stage_threshold>\n                <parent>10</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 6 14 14 -1.</_>\n                                    <_>6 13 14 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1641651988029480</threshold>\n                            <left_val>-0.4896030128002167</left_val>\n                            <right_val>0.1760770976543427</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 17 4 2 -1.</_>\n                                    <_>2 18 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.3413062384352088e-004</threshold>\n                            <left_val>-0.2822043001651764</left_val>\n                            <right_val>0.2419957965612412</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 2 1 3 -1.</_>\n                                    <_>0 3 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7193210078403354e-003</threshold>\n                            <left_val>-0.7148588895797730</left_val>\n                            <right_val>0.0861622169613838</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 12 1 3 -1.</_>\n                                    <_>0 13 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5654950402677059e-003</threshold>\n                            <left_val>-0.7297238111495972</left_val>\n                            <right_val>0.0940706729888916</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 15 4 4 -1.</_>\n                                    <_>15 17 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.9124479731544852e-003</threshold>\n                            <left_val>-0.3118715882301331</left_val>\n                            <right_val>0.1814339011907578</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 5 18 7 -1.</_>\n                                    <_>8 5 6 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1351236999034882</threshold>\n                            <left_val>0.2957729995250702</left_val>\n                            <right_val>-0.2217925041913986</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 16 5 3 -1.</_>\n                                    <_>1 17 5 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.0300549007952213e-003</threshold>\n                            <left_val>-0.6659513711929321</left_val>\n                            <right_val>0.0854310169816017</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 4 2 3 -1.</_>\n                                    <_>0 5 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.8640460222959518e-003</threshold>\n                            <left_val>-0.6208636164665222</left_val>\n                            <right_val>0.0531060211360455</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 6 2 6 -1.</_>\n                                    <_>1 6 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.4065420255064964e-003</threshold>\n                            <left_val>0.2234628945589066</left_val>\n                            <right_val>-0.2021100968122482</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 14 4 3 -1.</_>\n                                    <_>16 15 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5820449702441692e-003</threshold>\n                            <left_val>-0.5403040051460266</left_val>\n                            <right_val>0.0682136192917824</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 10 6 -1.</_>\n                                    <_>0 0 5 3 2.</_>\n                                    <_>5 3 5 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0415444709360600</threshold>\n                            <left_val>-0.0652158409357071</left_val>\n                            <right_val>0.6210923194885254</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 2 3 6 -1.</_>\n                                    <_>3 2 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.1709550470113754e-003</threshold>\n                            <left_val>-0.7555329799652100</left_val>\n                            <right_val>0.0526404492557049</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 3 10 -1.</_>\n                                    <_>3 0 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.1552738770842552e-003</threshold>\n                            <left_val>0.0909394025802612</left_val>\n                            <right_val>-0.4424613118171692</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 5 2 2 -1.</_>\n                                    <_>5 6 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0043520014733076e-003</threshold>\n                            <left_val>0.2429233044385910</left_val>\n                            <right_val>-0.1866979002952576</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 6 4 4 -1.</_>\n                                    <_>12 8 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0115198297426105</threshold>\n                            <left_val>-0.1176315024495125</left_val>\n                            <right_val>0.3672345876693726</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 5 7 3 -1.</_>\n                                    <_>13 6 7 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.9040733873844147e-003</threshold>\n                            <left_val>-0.4893133044242859</left_val>\n                            <right_val>0.1089702025055885</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 13 1 2 -1.</_>\n                                    <_>10 14 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.3973670583218336e-004</threshold>\n                            <left_val>-0.2185039967298508</left_val>\n                            <right_val>0.1848998963832855</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 16 4 2 -1.</_>\n                                    <_>18 16 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3727260520681739e-003</threshold>\n                            <left_val>-0.1507291048765183</left_val>\n                            <right_val>0.2917312979698181</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 12 4 7 -1.</_>\n                                    <_>18 12 2 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0108073903247714</threshold>\n                            <left_val>0.4289745092391968</left_val>\n                            <right_val>-0.1028013974428177</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 17 1 3 -1.</_>\n                                    <_>16 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.2670770520344377e-003</threshold>\n                            <left_val>0.0741921588778496</left_val>\n                            <right_val>-0.6420825123786926</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 9 1 3 -1.</_>\n                                    <_>19 10 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.2991129662841558e-003</threshold>\n                            <left_val>0.0471002794802189</left_val>\n                            <right_val>-0.7233523130416870</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 7 2 6 -1.</_>\n                                    <_>19 7 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7187510859221220e-003</threshold>\n                            <left_val>-0.1708686947822571</left_val>\n                            <right_val>0.2351350933313370</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 3 4 -1.</_>\n                                    <_>9 1 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.6619180142879486e-003</threshold>\n                            <left_val>-0.7897542715072632</left_val>\n                            <right_val>0.0450846701860428</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 0 6 9 -1.</_>\n                                    <_>16 0 2 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0482666492462158</threshold>\n                            <left_val>-0.6957991719245911</left_val>\n                            <right_val>0.0419760793447495</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 2 10 2 -1.</_>\n                                    <_>9 2 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0152146900072694</threshold>\n                            <left_val>-0.1081828027963638</left_val>\n                            <right_val>0.3646062016487122</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 12 8 4 -1.</_>\n                                    <_>2 12 4 2 2.</_>\n                                    <_>6 14 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.0080131515860558e-003</threshold>\n                            <left_val>0.3097099065780640</left_val>\n                            <right_val>-0.1135921031236649</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 4 7 3 -1.</_>\n                                    <_>0 5 7 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.6127157770097256e-003</threshold>\n                            <left_val>0.0806653425097466</left_val>\n                            <right_val>-0.4665853083133698</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 14 3 3 -1.</_>\n                                    <_>15 14 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.9607013612985611e-003</threshold>\n                            <left_val>-0.8720194101333618</left_val>\n                            <right_val>0.0367745906114578</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 3 4 3 -1.</_>\n                                    <_>2 3 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.8847199175506830e-003</threshold>\n                            <left_val>-0.1166628971695900</left_val>\n                            <right_val>0.3307026922702789</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 2 7 -1.</_>\n                                    <_>2 0 1 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0988810099661350e-003</threshold>\n                            <left_val>0.2387257069349289</left_val>\n                            <right_val>-0.1765675991773605</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.1729990243911743</stage_threshold>\n                <parent>11</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 16 4 4 -1.</_>\n                                    <_>15 18 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.5903379321098328e-003</threshold>\n                            <left_val>-0.2368807941675186</left_val>\n                            <right_val>0.2463164031505585</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 8 12 4 -1.</_>\n                                    <_>5 10 12 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.4815930090844631e-003</threshold>\n                            <left_val>-0.3137362003326416</left_val>\n                            <right_val>0.1867575943470001</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 17 1 2 -1.</_>\n                                    <_>3 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.3048402555286884e-005</threshold>\n                            <left_val>-0.2764435112476349</left_val>\n                            <right_val>0.1649623960256577</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 1 3 4 -1.</_>\n                                    <_>7 1 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8514640182256699e-003</threshold>\n                            <left_val>-0.5601450800895691</left_val>\n                            <right_val>0.1129473969340324</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 2 3 4 -1.</_>\n                                    <_>7 2 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.8588210009038448e-003</threshold>\n                            <left_val>0.0398489981889725</left_val>\n                            <right_val>-0.5807185769081116</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 9 12 -1.</_>\n                                    <_>9 8 3 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0246512200683355</threshold>\n                            <left_val>0.1675501018762589</left_val>\n                            <right_val>-0.2534367144107819</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 8 6 -1.</_>\n                                    <_>8 3 8 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0472455210983753</threshold>\n                            <left_val>-0.1066208034753799</left_val>\n                            <right_val>0.3945198059082031</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 2 6 3 -1.</_>\n                                    <_>17 2 3 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.5964651294052601e-003</threshold>\n                            <left_val>-0.1774425059556961</left_val>\n                            <right_val>0.2728019058704376</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 6 1 3 -1.</_>\n                                    <_>0 7 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3177490327507257e-003</threshold>\n                            <left_val>-0.5427265167236328</left_val>\n                            <right_val>0.0486065894365311</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 0 10 2 -1.</_>\n                                    <_>15 0 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.0261709839105606e-003</threshold>\n                            <left_val>0.2439424991607666</left_val>\n                            <right_val>-0.1314364969730377</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 0 3 2 -1.</_>\n                                    <_>12 0 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.4632768947631121e-003</threshold>\n                            <left_val>0.0690493434667587</left_val>\n                            <right_val>-0.7033624053001404</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 19 10 1 -1.</_>\n                                    <_>8 19 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.1692588925361633e-003</threshold>\n                            <left_val>-0.1328946053981781</left_val>\n                            <right_val>0.2209852933883667</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 4 7 16 -1.</_>\n                                    <_>0 12 7 8 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0293958708643913</threshold>\n                            <left_val>-0.2853052020072937</left_val>\n                            <right_val>0.1354399025440216</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 16 1 3 -1.</_>\n                                    <_>2 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6181448316201568e-004</threshold>\n                            <left_val>-0.5804138183593750</left_val>\n                            <right_val>0.0374506488442421</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 8 12 6 -1.</_>\n                                    <_>11 8 4 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1082099974155426</threshold>\n                            <left_val>0.3946728110313416</left_val>\n                            <right_val>-0.0786559432744980</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 9 6 7 -1.</_>\n                                    <_>16 9 2 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0180248692631722</threshold>\n                            <left_val>0.2735562920570374</left_val>\n                            <right_val>-0.1341529935598373</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 17 6 1 -1.</_>\n                                    <_>14 17 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.2509840354323387e-003</threshold>\n                            <left_val>0.0233880598098040</left_val>\n                            <right_val>-0.8008859157562256</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 1 3 1 -1.</_>\n                                    <_>17 1 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6088379779830575e-003</threshold>\n                            <left_val>-0.5676252245903015</left_val>\n                            <right_val>0.0412156693637371</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 17 8 2 -1.</_>\n                                    <_>0 17 4 1 2.</_>\n                                    <_>4 18 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.7564752427861094e-004</threshold>\n                            <left_val>-0.1489126980304718</left_val>\n                            <right_val>0.1908618062734604</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 0 2 1 -1.</_>\n                                    <_>18 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.7122338300105184e-005</threshold>\n                            <left_val>-0.1555753052234650</left_val>\n                            <right_val>0.1942822039127350</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 15 6 5 -1.</_>\n                                    <_>6 15 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0207553207874298</threshold>\n                            <left_val>-0.6300653219223023</left_val>\n                            <right_val>0.0361343808472157</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 2 8 2 -1.</_>\n                                    <_>7 3 8 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.2931738793849945e-003</threshold>\n                            <left_val>0.2560924887657166</left_val>\n                            <right_val>-0.1058826968073845</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 8 4 -1.</_>\n                                    <_>4 3 8 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0108441496267915</threshold>\n                            <left_val>-0.1012485027313232</left_val>\n                            <right_val>0.3032212853431702</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 19 2 1 -1.</_>\n                                    <_>6 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.3752777350600809e-005</threshold>\n                            <left_val>0.1911157965660095</left_val>\n                            <right_val>-0.1384923011064529</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 19 2 1 -1.</_>\n                                    <_>6 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.6480963141657412e-005</threshold>\n                            <left_val>-0.1520525068044663</left_val>\n                            <right_val>0.2170630991458893</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 17 1 3 -1.</_>\n                                    <_>16 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3560829684138298e-003</threshold>\n                            <left_val>0.0494317896664143</left_val>\n                            <right_val>-0.6427984237670898</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 11 2 3 -1.</_>\n                                    <_>1 11 1 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.0662558795884252e-004</threshold>\n                            <left_val>0.1798201054334641</left_val>\n                            <right_val>-0.1404460966587067</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 19 4 1 -1.</_>\n                                    <_>2 19 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0473709553480148e-003</threshold>\n                            <left_val>-0.1093354970216751</left_val>\n                            <right_val>0.2426594048738480</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 4 2 -1.</_>\n                                    <_>2 18 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0243969736620784e-003</threshold>\n                            <left_val>0.2716268002986908</left_val>\n                            <right_val>-0.1182091981172562</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 17 1 3 -1.</_>\n                                    <_>2 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.2024149764329195e-003</threshold>\n                            <left_val>-0.7015110254287720</left_val>\n                            <right_val>0.0394898988306522</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 7 11 2 -1.</_>\n                                    <_>5 8 11 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.6911649666726589e-003</threshold>\n                            <left_val>-0.0922189131379128</left_val>\n                            <right_val>0.3104628920555115</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 2 4 10 -1.</_>\n                                    <_>9 7 4 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1396654993295670</threshold>\n                            <left_val>0.6897938847541809</left_val>\n                            <right_val>-0.0397061184048653</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 2 4 3 -1.</_>\n                                    <_>0 3 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.1276050247251987e-003</threshold>\n                            <left_val>0.0972776114940643</left_val>\n                            <right_val>-0.2884179949760437</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 19 10 1 -1.</_>\n                                    <_>15 19 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.7594310231506824e-003</threshold>\n                            <left_val>0.2416867017745972</left_val>\n                            <right_val>-0.1127782016992569</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 17 8 3 -1.</_>\n                                    <_>15 17 4 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.2236132323741913e-003</threshold>\n                            <left_val>-0.1143027991056442</left_val>\n                            <right_val>0.2425678074359894</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 19 3 1 -1.</_>\n                                    <_>9 19 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.2590440455824137e-003</threshold>\n                            <left_val>-0.5967938899993897</left_val>\n                            <right_val>0.0476639606058598</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 0 3 4 -1.</_>\n                                    <_>15 0 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.7192099262028933e-003</threshold>\n                            <left_val>-0.4641413092613220</left_val>\n                            <right_val>0.0528476908802986</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 6 4 3 -1.</_>\n                                    <_>10 7 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.9696151874959469e-003</threshold>\n                            <left_val>-0.0732442885637283</left_val>\n                            <right_val>0.3874309062957764</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 3 2 -1.</_>\n                                    <_>0 9 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.1776720210909843e-003</threshold>\n                            <left_val>-0.7419322729110718</left_val>\n                            <right_val>0.0404967106878757</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 12 3 6 -1.</_>\n                                    <_>7 14 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0035100430250168e-003</threshold>\n                            <left_val>-0.1388880014419556</left_val>\n                            <right_val>0.1876762062311173</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 18 1 2 -1.</_>\n                                    <_>1 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.2013457752764225e-004</threshold>\n                            <left_val>-0.5494061708450317</left_val>\n                            <right_val>0.0494178496301174</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 12 4 4 -1.</_>\n                                    <_>2 12 2 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.3168768063187599e-003</threshold>\n                            <left_val>-0.0824829787015915</left_val>\n                            <right_val>0.3174056112766266</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 8 6 7 -1.</_>\n                                    <_>3 8 2 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0147745897993445</threshold>\n                            <left_val>0.2081609964370728</left_val>\n                            <right_val>-0.1211555972695351</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 4 5 -1.</_>\n                                    <_>2 8 2 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0414164513349533</threshold>\n                            <left_val>-0.8243780732154846</left_val>\n                            <right_val>0.0333291888237000</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.0368299484252930</stage_threshold>\n                <parent>12</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 16 1 3 -1.</_>\n                                    <_>19 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.0962520334869623e-004</threshold>\n                            <left_val>0.0845799669623375</left_val>\n                            <right_val>-0.5611841082572937</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 5 18 6 -1.</_>\n                                    <_>7 5 6 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0561397895216942</threshold>\n                            <left_val>0.1534174978733063</left_val>\n                            <right_val>-0.2696731984615326</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 15 4 2 -1.</_>\n                                    <_>2 16 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0292009683325887e-003</threshold>\n                            <left_val>-0.2048998028039932</left_val>\n                            <right_val>0.2015317976474762</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 6 2 11 -1.</_>\n                                    <_>19 6 1 11 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.8783010784536600e-003</threshold>\n                            <left_val>-0.1735114008188248</left_val>\n                            <right_val>0.2129794955253601</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 12 2 6 -1.</_>\n                                    <_>0 14 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.4144392274320126e-003</threshold>\n                            <left_val>-0.5962486863136292</left_val>\n                            <right_val>0.0470779500901699</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 5 3 2 -1.</_>\n                                    <_>12 6 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.4831849839538336e-003</threshold>\n                            <left_val>0.1902461051940918</left_val>\n                            <right_val>-0.1598639041185379</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 3 2 3 -1.</_>\n                                    <_>1 4 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.5968941412866116e-003</threshold>\n                            <left_val>0.0314471311867237</left_val>\n                            <right_val>-0.6869434118270874</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 14 4 4 -1.</_>\n                                    <_>16 16 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.4255330208688974e-003</threshold>\n                            <left_val>-0.2360935956239700</left_val>\n                            <right_val>0.1103610992431641</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 12 5 -1.</_>\n                                    <_>10 8 4 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0849505662918091</threshold>\n                            <left_val>0.2310716062784195</left_val>\n                            <right_val>-0.1377653032541275</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 7 2 7 -1.</_>\n                                    <_>14 7 1 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.0145681016147137e-003</threshold>\n                            <left_val>0.3867610991001129</left_val>\n                            <right_val>-0.0562173798680305</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 8 2 6 -1.</_>\n                                    <_>2 8 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.1482061129063368e-003</threshold>\n                            <left_val>0.1819159984588623</left_val>\n                            <right_val>-0.1761569976806641</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 0 3 7 -1.</_>\n                                    <_>16 0 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0103967702016234</threshold>\n                            <left_val>-0.7535138130187988</left_val>\n                            <right_val>0.0240919701755047</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 2 6 2 -1.</_>\n                                    <_>6 2 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0134667502716184</threshold>\n                            <left_val>-0.7211886048316956</left_val>\n                            <right_val>0.0349493697285652</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 20 9 -1.</_>\n                                    <_>0 12 20 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0844354778528214</threshold>\n                            <left_val>-0.3379263877868652</left_val>\n                            <right_val>0.0711138173937798</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 14 2 2 -1.</_>\n                                    <_>10 15 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.4771490134298801e-003</threshold>\n                            <left_val>-0.1176510974764824</left_val>\n                            <right_val>0.2254198938608170</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 5 10 4 -1.</_>\n                                    <_>6 7 10 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0158280506730080</threshold>\n                            <left_val>-0.0695362165570259</left_val>\n                            <right_val>0.3139536976814270</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 1 5 9 -1.</_>\n                                    <_>6 4 5 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0649169832468033</threshold>\n                            <left_val>-0.0750435888767242</left_val>\n                            <right_val>0.4067733883857727</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 18 2 2 -1.</_>\n                                    <_>16 18 1 1 2.</_>\n                                    <_>17 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.9652469675056636e-004</threshold>\n                            <left_val>0.0739533603191376</left_val>\n                            <right_val>-0.3454400897026062</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 14 2 4 -1.</_>\n                                    <_>0 16 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3129520229995251e-003</threshold>\n                            <left_val>-0.1690943986177445</left_val>\n                            <right_val>0.1525837033987045</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 8 2 5 -1.</_>\n                                    <_>11 8 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.8032129891216755e-003</threshold>\n                            <left_val>0.3526014983654022</left_val>\n                            <right_val>-0.0834440663456917</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 7 12 7 -1.</_>\n                                    <_>7 7 4 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1479167938232422</threshold>\n                            <left_val>0.4300465881824493</left_val>\n                            <right_val>-0.0573099292814732</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 6 6 -1.</_>\n                                    <_>3 0 3 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0165841504931450</threshold>\n                            <left_val>0.2343268990516663</left_val>\n                            <right_val>-0.1090764030814171</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 4 4 -1.</_>\n                                    <_>3 0 2 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.0183270573616028e-003</threshold>\n                            <left_val>-0.1360093951225281</left_val>\n                            <right_val>0.2640928924083710</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 6 8 -1.</_>\n                                    <_>2 0 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0364719182252884</threshold>\n                            <left_val>-0.6280974149703980</left_val>\n                            <right_val>0.0435451082885265</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 2 1 -1.</_>\n                                    <_>1 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.3119226726703346e-005</threshold>\n                            <left_val>0.1647063046693802</left_val>\n                            <right_val>-0.1646378040313721</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 3 3 -1.</_>\n                                    <_>0 1 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.6719450727105141e-003</threshold>\n                            <left_val>-0.4742136001586914</left_val>\n                            <right_val>0.0485869199037552</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 4 2 4 -1.</_>\n                                    <_>5 6 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.0151178836822510e-003</threshold>\n                            <left_val>0.1822218000888825</left_val>\n                            <right_val>-0.1409751027822495</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 10 9 1 -1.</_>\n                                    <_>5 10 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0199480205774307</threshold>\n                            <left_val>-0.0697876587510109</left_val>\n                            <right_val>0.3670746088027954</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 17 1 3 -1.</_>\n                                    <_>1 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.6699437340721488e-004</threshold>\n                            <left_val>0.0557292997837067</left_val>\n                            <right_val>-0.4458543062210083</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 17 2 3 -1.</_>\n                                    <_>0 18 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.1806039838120341e-003</threshold>\n                            <left_val>-0.4687662124633789</left_val>\n                            <right_val>0.0489022210240364</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 15 16 3 -1.</_>\n                                    <_>8 15 8 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0158473495393991</threshold>\n                            <left_val>-0.1212020963430405</left_val>\n                            <right_val>0.2056653052568436</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 4 1 -1.</_>\n                                    <_>2 5 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.1985700111836195e-003</threshold>\n                            <left_val>0.2026209980249405</left_val>\n                            <right_val>-0.1282382011413574</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 6 20 -1.</_>\n                                    <_>3 0 2 20 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1096495985984802</threshold>\n                            <left_val>-0.8661919236183167</left_val>\n                            <right_val>0.0303518492728472</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 5 4 6 -1.</_>\n                                    <_>2 5 2 3 2.</_>\n                                    <_>4 8 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.2532606795430183e-003</threshold>\n                            <left_val>0.2934311926364899</left_val>\n                            <right_val>-0.0853619500994682</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 16 6 3 -1.</_>\n                                    <_>11 16 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0146865304559469</threshold>\n                            <left_val>0.0327986218035221</left_val>\n                            <right_val>-0.7755656242370606</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 17 6 1 -1.</_>\n                                    <_>14 17 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3514430029317737e-003</threshold>\n                            <left_val>0.2442699968814850</left_val>\n                            <right_val>-0.1150325015187264</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 17 15 2 -1.</_>\n                                    <_>8 17 5 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.3728090822696686e-003</threshold>\n                            <left_val>0.2168767005205154</left_val>\n                            <right_val>-0.1398448050022125</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 0 2 3 -1.</_>\n                                    <_>18 1 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.4263390116393566e-003</threshold>\n                            <left_val>0.0456142202019691</left_val>\n                            <right_val>-0.5456771254539490</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 1 7 4 -1.</_>\n                                    <_>13 3 7 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8404068909585476e-003</threshold>\n                            <left_val>0.1494950056076050</left_val>\n                            <right_val>-0.1506250947713852</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 6 4 4 -1.</_>\n                                    <_>13 6 2 2 2.</_>\n                                    <_>15 8 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.7988980766385794e-003</threshold>\n                            <left_val>-0.0873016268014908</left_val>\n                            <right_val>0.2548153102397919</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 6 3 4 -1.</_>\n                                    <_>17 8 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.0094281062483788e-003</threshold>\n                            <left_val>0.1725907027721405</left_val>\n                            <right_val>-0.1428847014904022</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 9 2 2 -1.</_>\n                                    <_>15 9 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4370709434151649e-003</threshold>\n                            <left_val>0.2684809863567352</left_val>\n                            <right_val>-0.0818982198834419</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 17 1 3 -1.</_>\n                                    <_>17 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0485399980098009e-003</threshold>\n                            <left_val>0.0461132600903511</left_val>\n                            <right_val>-0.4724327921867371</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 19 8 1 -1.</_>\n                                    <_>7 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.7460780218243599e-003</threshold>\n                            <left_val>-0.1103043034672737</left_val>\n                            <right_val>0.2037972956895828</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 3 6 -1.</_>\n                                    <_>0 12 3 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.8608627878129482e-003</threshold>\n                            <left_val>-0.1561965942382813</left_val>\n                            <right_val>0.1592743992805481</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 7 15 5 -1.</_>\n                                    <_>9 7 5 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0277249794453382</threshold>\n                            <left_val>0.1134911999106407</left_val>\n                            <right_val>-0.2188514024019241</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 9 9 5 -1.</_>\n                                    <_>9 9 3 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0470806397497654</threshold>\n                            <left_val>-0.0416887290775776</left_val>\n                            <right_val>0.5363004803657532</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 6 2 -1.</_>\n                                    <_>10 1 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.9283770173788071e-003</threshold>\n                            <left_val>-0.5359513163566589</left_val>\n                            <right_val>0.0442375093698502</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 12 2 -1.</_>\n                                    <_>10 0 6 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0128805404528975</threshold>\n                            <left_val>0.2323794960975647</left_val>\n                            <right_val>-0.1024625003337860</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 0 10 3 -1.</_>\n                                    <_>12 0 5 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0236047692596912</threshold>\n                            <left_val>-0.0882914364337921</left_val>\n                            <right_val>0.3056105971336365</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 0 9 6 -1.</_>\n                                    <_>5 2 9 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0159022007137537</threshold>\n                            <left_val>-0.1223810985684395</left_val>\n                            <right_val>0.1784912049770355</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 3 6 4 -1.</_>\n                                    <_>8 5 6 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.9939495772123337e-003</threshold>\n                            <left_val>-0.0837290063500404</left_val>\n                            <right_val>0.3231959044933319</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 4 2 3 -1.</_>\n                                    <_>17 5 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.7100867852568626e-003</threshold>\n                            <left_val>0.0384792089462280</left_val>\n                            <right_val>-0.6813815236091614</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.0492420196533203</stage_threshold>\n                <parent>13</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 2 4 3 -1.</_>\n                                    <_>5 3 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.2480720654129982e-003</threshold>\n                            <left_val>-0.1641687005758286</left_val>\n                            <right_val>0.4164853096008301</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 9 2 6 -1.</_>\n                                    <_>6 9 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.5813550241291523e-003</threshold>\n                            <left_val>-0.1246595978736877</left_val>\n                            <right_val>0.4038512110710144</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 10 2 6 -1.</_>\n                                    <_>15 10 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6073239967226982e-003</threshold>\n                            <left_val>0.2608245909214020</left_val>\n                            <right_val>-0.2028252035379410</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 4 3 3 -1.</_>\n                                    <_>7 5 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.5205370038747787e-003</threshold>\n                            <left_val>-0.1055722981691361</left_val>\n                            <right_val>0.3666911125183106</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 4 8 2 -1.</_>\n                                    <_>12 4 4 1 2.</_>\n                                    <_>16 5 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.4119189474731684e-003</threshold>\n                            <left_val>-0.1387760043144226</left_val>\n                            <right_val>0.2995991110801697</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 8 1 6 -1.</_>\n                                    <_>15 10 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.7156179100275040e-003</threshold>\n                            <left_val>-0.0776834636926651</left_val>\n                            <right_val>0.4848192036151886</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 17 11 3 -1.</_>\n                                    <_>4 18 11 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.1093840952962637e-003</threshold>\n                            <left_val>-0.1122900024056435</left_val>\n                            <right_val>0.2921550869941711</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 0 16 20 -1.</_>\n                                    <_>3 10 16 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0868366286158562</threshold>\n                            <left_val>-0.3677960038185120</left_val>\n                            <right_val>0.0725972428917885</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 4 4 6 -1.</_>\n                                    <_>12 6 4 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.2652182057499886e-003</threshold>\n                            <left_val>-0.1089029014110565</left_val>\n                            <right_val>0.3179126083850861</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 0 6 6 -1.</_>\n                                    <_>13 0 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0199135299772024</threshold>\n                            <left_val>-0.5337343811988831</left_val>\n                            <right_val>0.0705857127904892</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 1 6 4 -1.</_>\n                                    <_>13 1 3 2 2.</_>\n                                    <_>16 3 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.8297839928418398e-003</threshold>\n                            <left_val>-0.1357591003179550</left_val>\n                            <right_val>0.2278887927532196</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 0 6 4 -1.</_>\n                                    <_>13 0 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0104318596422672</threshold>\n                            <left_val>0.0887979120016098</left_val>\n                            <right_val>-0.4795897006988525</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 6 6 9 -1.</_>\n                                    <_>10 6 2 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0200404394418001</threshold>\n                            <left_val>0.1574553996324539</left_val>\n                            <right_val>-0.1777157038450241</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 0 3 4 -1.</_>\n                                    <_>8 0 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.2967290394008160e-003</threshold>\n                            <left_val>-0.6843491792678833</left_val>\n                            <right_val>0.0356714613735676</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 17 14 2 -1.</_>\n                                    <_>0 17 7 1 2.</_>\n                                    <_>7 18 7 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.1624139044433832e-003</threshold>\n                            <left_val>0.2831803858280182</left_val>\n                            <right_val>-0.0985112786293030</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 18 2 2 -1.</_>\n                                    <_>6 18 1 1 2.</_>\n                                    <_>7 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5464888787828386e-004</threshold>\n                            <left_val>-0.3707734048366547</left_val>\n                            <right_val>0.0809329524636269</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 1 3 -1.</_>\n                                    <_>18 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.8152060511056334e-004</threshold>\n                            <left_val>-0.3220703005790710</left_val>\n                            <right_val>0.0775510594248772</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 18 2 2 -1.</_>\n                                    <_>17 18 1 1 2.</_>\n                                    <_>18 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.7563021285459399e-004</threshold>\n                            <left_val>-0.3244127929210663</left_val>\n                            <right_val>0.0879494771361351</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 7 1 9 -1.</_>\n                                    <_>5 10 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.3823810778558254e-003</threshold>\n                            <left_val>-0.0889247134327888</left_val>\n                            <right_val>0.3172721862792969</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 3 6 4 -1.</_>\n                                    <_>7 3 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0111509095877409</threshold>\n                            <left_val>0.0710198432207108</left_val>\n                            <right_val>-0.4049403965473175</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 9 6 2 -1.</_>\n                                    <_>1 9 3 1 2.</_>\n                                    <_>4 10 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0593760525807738e-003</threshold>\n                            <left_val>0.2605066895484924</left_val>\n                            <right_val>-0.1176564022898674</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 9 2 3 -1.</_>\n                                    <_>7 9 1 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.3906480055302382e-003</threshold>\n                            <left_val>-0.0843886211514473</left_val>\n                            <right_val>0.3123055100440979</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 6 12 -1.</_>\n                                    <_>8 8 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0110007496550679</threshold>\n                            <left_val>0.1915224939584732</left_val>\n                            <right_val>-0.1521002054214478</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 18 2 2 -1.</_>\n                                    <_>4 18 1 1 2.</_>\n                                    <_>5 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4643228971399367e-004</threshold>\n                            <left_val>-0.3176515996456146</left_val>\n                            <right_val>0.0865822583436966</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 1 6 6 -1.</_>\n                                    <_>9 3 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0230532698333263</threshold>\n                            <left_val>-0.1008976027369499</left_val>\n                            <right_val>0.2576929032802582</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 6 2 -1.</_>\n                                    <_>6 18 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2135660983622074e-003</threshold>\n                            <left_val>0.4568921029567719</left_val>\n                            <right_val>-0.0524047911167145</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 18 16 2 -1.</_>\n                                    <_>3 19 16 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.7139709396287799e-004</threshold>\n                            <left_val>-0.3551838099956513</left_val>\n                            <right_val>0.0800943821668625</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 0 3 11 -1.</_>\n                                    <_>4 0 1 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.5676229959353805e-003</threshold>\n                            <left_val>0.1009142026305199</left_val>\n                            <right_val>-0.2160304039716721</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 18 3 1 -1.</_>\n                                    <_>14 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5460801599547267e-004</threshold>\n                            <left_val>0.0578961782157421</left_val>\n                            <right_val>-0.4046111106872559</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 0 9 6 -1.</_>\n                                    <_>6 2 9 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0206989701837301</threshold>\n                            <left_val>0.3154363036155701</left_val>\n                            <right_val>-0.0807130485773087</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 2 12 4 -1.</_>\n                                    <_>1 2 6 2 2.</_>\n                                    <_>7 4 6 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0206199400126934</threshold>\n                            <left_val>0.2718166112899780</left_val>\n                            <right_val>-0.0763586163520813</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 3 6 4 -1.</_>\n                                    <_>5 3 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0216111298650503</threshold>\n                            <left_val>0.0394934490323067</left_val>\n                            <right_val>-0.5942965149879456</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 0 8 1 -1.</_>\n                                    <_>16 0 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.5676742233335972e-003</threshold>\n                            <left_val>-0.0983536690473557</left_val>\n                            <right_val>0.2364927977323532</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 0 6 2 -1.</_>\n                                    <_>11 0 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.8434796780347824e-003</threshold>\n                            <left_val>-0.5252342820167542</left_val>\n                            <right_val>0.0430999211966991</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 3 12 1 -1.</_>\n                                    <_>9 3 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.4260741025209427e-003</threshold>\n                            <left_val>0.2466513067483902</left_val>\n                            <right_val>-0.0941307172179222</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 7 6 2 -1.</_>\n                                    <_>2 7 3 1 2.</_>\n                                    <_>5 8 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.9830230157822371e-003</threshold>\n                            <left_val>0.2674370110034943</left_val>\n                            <right_val>-0.0900693163275719</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 4 6 -1.</_>\n                                    <_>0 10 4 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7358399927616119e-003</threshold>\n                            <left_val>0.1594001948833466</left_val>\n                            <right_val>-0.1578941047191620</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 6 3 7 -1.</_>\n                                    <_>10 6 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0135138696059585</threshold>\n                            <left_val>0.4079233109951019</left_val>\n                            <right_val>-0.0642231181263924</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 6 6 13 -1.</_>\n                                    <_>11 6 2 13 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0193940103054047</threshold>\n                            <left_val>0.1801564991474152</left_val>\n                            <right_val>-0.1373140066862106</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 12 6 1 -1.</_>\n                                    <_>13 12 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.2684770412743092e-003</threshold>\n                            <left_val>0.2908039093017578</left_val>\n                            <right_val>-0.0801619067788124</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 9 2 6 -1.</_>\n                                    <_>18 12 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.1773589327931404e-004</threshold>\n                            <left_val>-0.2141298055648804</left_val>\n                            <right_val>0.1127343997359276</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 2 3 9 -1.</_>\n                                    <_>18 2 1 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.6351119205355644e-003</threshold>\n                            <left_val>-0.4536595940589905</left_val>\n                            <right_val>0.0546250604093075</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 8 4 6 -1.</_>\n                                    <_>13 8 2 3 2.</_>\n                                    <_>15 11 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.3652976900339127e-003</threshold>\n                            <left_val>0.2647292017936707</left_val>\n                            <right_val>-0.0943341106176376</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 2 12 6 -1.</_>\n                                    <_>10 2 6 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0277684498578310</threshold>\n                            <left_val>-0.1013671010732651</left_val>\n                            <right_val>0.2074397951364517</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 14 16 6 -1.</_>\n                                    <_>12 14 8 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0548912286758423</threshold>\n                            <left_val>0.2884030938148499</left_val>\n                            <right_val>-0.0753120407462120</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 19 10 1 -1.</_>\n                                    <_>11 19 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.5793339591473341e-003</threshold>\n                            <left_val>-0.1108852997422218</left_val>\n                            <right_val>0.2172496020793915</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 1 3 -1.</_>\n                                    <_>6 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.6196516854688525e-005</threshold>\n                            <left_val>-0.1887210011482239</left_val>\n                            <right_val>0.1444068998098373</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 14 10 3 -1.</_>\n                                    <_>4 15 10 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0907251425087452e-003</threshold>\n                            <left_val>-0.0776012316346169</left_val>\n                            <right_val>0.2939837872982025</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 0 12 12 -1.</_>\n                                    <_>6 4 12 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1044425964355469</threshold>\n                            <left_val>0.2013310939073563</left_val>\n                            <right_val>-0.1090397015213966</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 7 4 2 -1.</_>\n                                    <_>5 7 2 1 2.</_>\n                                    <_>7 8 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.7273090826347470e-004</threshold>\n                            <left_val>0.1794590055942535</left_val>\n                            <right_val>-0.1202367022633553</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 5 3 2 -1.</_>\n                                    <_>18 5 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.2412849832326174e-003</threshold>\n                            <left_val>0.0406881310045719</left_val>\n                            <right_val>-0.5460057258605957</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.1122100353240967</stage_threshold>\n                <parent>14</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 13 6 3 -1.</_>\n                                    <_>8 14 6 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.2965320646762848e-003</threshold>\n                            <left_val>-0.1215452998876572</left_val>\n                            <right_val>0.6442037224769592</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 13 5 3 -1.</_>\n                                    <_>8 14 5 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.5326260365545750e-003</threshold>\n                            <left_val>0.5123322010040283</left_val>\n                            <right_val>-0.1110825985670090</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 2 1 18 -1.</_>\n                                    <_>13 11 1 9 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9183230362832546e-003</threshold>\n                            <left_val>-0.5061542987823486</left_val>\n                            <right_val>0.1150197982788086</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 10 9 2 -1.</_>\n                                    <_>9 10 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0236923396587372</threshold>\n                            <left_val>0.3716728091239929</left_val>\n                            <right_val>-0.1467268019914627</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 0 7 4 -1.</_>\n                                    <_>11 2 7 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0201774705201387</threshold>\n                            <left_val>-0.1738884001970291</left_val>\n                            <right_val>0.4775949120521545</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 6 8 -1.</_>\n                                    <_>3 0 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0217232108116150</threshold>\n                            <left_val>-0.4388009011745453</left_val>\n                            <right_val>0.1357689946889877</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 15 3 3 -1.</_>\n                                    <_>9 16 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.8369780629873276e-003</threshold>\n                            <left_val>-0.1251206994056702</left_val>\n                            <right_val>0.4678902924060822</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 17 9 3 -1.</_>\n                                    <_>9 18 9 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7148420922458172e-003</threshold>\n                            <left_val>-0.0880188569426537</left_val>\n                            <right_val>0.3686651885509491</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 12 3 3 -1.</_>\n                                    <_>12 13 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.2625689636915922e-003</threshold>\n                            <left_val>-0.0853353068232536</left_val>\n                            <right_val>0.5164473056793213</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 3 5 -1.</_>\n                                    <_>5 1 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5618850961327553e-003</threshold>\n                            <left_val>-0.4450393021106720</left_val>\n                            <right_val>0.0917381718754768</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 14 2 3 -1.</_>\n                                    <_>10 15 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.9227749435231090e-003</threshold>\n                            <left_val>-0.1107731014490128</left_val>\n                            <right_val>0.3941699862480164</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 2 2 -1.</_>\n                                    <_>18 17 1 1 2.</_>\n                                    <_>19 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5111969918943942e-004</threshold>\n                            <left_val>-0.3777570128440857</left_val>\n                            <right_val>0.1216617003083229</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 18 2 2 -1.</_>\n                                    <_>18 18 1 1 2.</_>\n                                    <_>19 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.9121779769193381e-004</threshold>\n                            <left_val>0.0748160183429718</left_val>\n                            <right_val>-0.4076710045337677</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 18 2 2 -1.</_>\n                                    <_>18 18 1 1 2.</_>\n                                    <_>19 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6525629800744355e-004</threshold>\n                            <left_val>-0.3315171897411346</left_val>\n                            <right_val>0.1129112020134926</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 10 9 1 -1.</_>\n                                    <_>7 10 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0200867000967264</threshold>\n                            <left_val>-0.0615981183946133</left_val>\n                            <right_val>0.5612881779670715</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 9 6 5 -1.</_>\n                                    <_>5 9 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0367832481861115</threshold>\n                            <left_val>-0.0602513886988163</left_val>\n                            <right_val>0.5219249129295349</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 8 1 12 -1.</_>\n                                    <_>18 14 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3941619545221329e-003</threshold>\n                            <left_val>-0.3550305068492889</left_val>\n                            <right_val>0.1086302027106285</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 2 8 6 -1.</_>\n                                    <_>0 2 4 3 2.</_>\n                                    <_>4 5 4 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0151816699653864</threshold>\n                            <left_val>0.2273965030908585</left_val>\n                            <right_val>-0.1625299006700516</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 4 3 3 -1.</_>\n                                    <_>9 5 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.6796840615570545e-003</threshold>\n                            <left_val>-0.0575350411236286</left_val>\n                            <right_val>0.4812423884868622</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 18 2 2 -1.</_>\n                                    <_>3 18 1 1 2.</_>\n                                    <_>4 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7988319450523704e-004</threshold>\n                            <left_val>-0.3058767020702362</left_val>\n                            <right_val>0.1086815968155861</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 4 4 3 -1.</_>\n                                    <_>6 5 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5850999411195517e-003</threshold>\n                            <left_val>0.3859694004058838</left_val>\n                            <right_val>-0.0921940729022026</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 7 4 2 -1.</_>\n                                    <_>16 7 2 1 2.</_>\n                                    <_>18 8 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0793360415846109e-003</threshold>\n                            <left_val>-0.1119038984179497</left_val>\n                            <right_val>0.3112520873546600</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 17 1 3 -1.</_>\n                                    <_>5 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.3285802500322461e-005</threshold>\n                            <left_val>-0.2023991048336029</left_val>\n                            <right_val>0.1558668017387390</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 15 20 -1.</_>\n                                    <_>2 10 15 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1367873996496201</threshold>\n                            <left_val>-0.2167285978794098</left_val>\n                            <right_val>0.1442039012908936</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 11 6 4 -1.</_>\n                                    <_>8 11 3 2 2.</_>\n                                    <_>11 13 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0117292599752545</threshold>\n                            <left_val>0.4350377023220062</left_val>\n                            <right_val>-0.0748865306377411</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 16 4 3 -1.</_>\n                                    <_>8 17 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.9230841211974621e-003</threshold>\n                            <left_val>-0.0502893291413784</left_val>\n                            <right_val>0.5883116126060486</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 18 2 2 -1.</_>\n                                    <_>8 18 1 1 2.</_>\n                                    <_>9 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9819121118634939e-004</threshold>\n                            <left_val>-0.3823240101337433</left_val>\n                            <right_val>0.0924511328339577</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 16 13 3 -1.</_>\n                                    <_>2 17 13 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.7992770560085773e-003</threshold>\n                            <left_val>0.4848878979682922</left_val>\n                            <right_val>-0.0731365233659744</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 16 2 2 -1.</_>\n                                    <_>16 16 1 1 2.</_>\n                                    <_>17 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.0155890271998942e-004</threshold>\n                            <left_val>-0.3575735986232758</left_val>\n                            <right_val>0.1058188006281853</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 6 3 -1.</_>\n                                    <_>10 1 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0103907696902752</threshold>\n                            <left_val>0.0529204681515694</left_val>\n                            <right_val>-0.5724965929985046</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 7 2 2 -1.</_>\n                                    <_>16 7 1 1 2.</_>\n                                    <_>17 8 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.4488041941076517e-004</threshold>\n                            <left_val>0.4496682882308960</left_val>\n                            <right_val>-0.0830755233764648</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 7 4 2 -1.</_>\n                                    <_>14 7 2 1 2.</_>\n                                    <_>16 8 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.2651870492845774e-003</threshold>\n                            <left_val>-0.0966954380273819</left_val>\n                            <right_val>0.3130227029323578</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 14 1 -1.</_>\n                                    <_>11 0 7 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0170945394784212</threshold>\n                            <left_val>-0.0812489762902260</left_val>\n                            <right_val>0.3611383140087128</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 4 8 2 -1.</_>\n                                    <_>10 4 4 1 2.</_>\n                                    <_>14 5 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.5973359588533640e-003</threshold>\n                            <left_val>-0.1133835017681122</left_val>\n                            <right_val>0.2223394960165024</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 2 3 2 -1.</_>\n                                    <_>9 2 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.4527440071105957e-003</threshold>\n                            <left_val>0.0697504431009293</left_val>\n                            <right_val>-0.3672071099281311</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 11 6 3 -1.</_>\n                                    <_>12 12 6 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.7638658434152603e-003</threshold>\n                            <left_val>-0.0657889619469643</left_val>\n                            <right_val>0.3832854032516480</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 5 1 4 -1.</_>\n                                    <_>1 7 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.2501081265509129e-003</threshold>\n                            <left_val>-0.7075446844100952</left_val>\n                            <right_val>0.0383501984179020</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 1 1 18 -1.</_>\n                                    <_>1 7 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.1765329185873270e-003</threshold>\n                            <left_val>0.1375540047883987</left_val>\n                            <right_val>-0.2324002981185913</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 13 3 2 -1.</_>\n                                    <_>11 14 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.2191169448196888e-003</threshold>\n                            <left_val>-0.1293545067310333</left_val>\n                            <right_val>0.2273788005113602</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 1 12 2 -1.</_>\n                                    <_>0 1 6 1 2.</_>\n                                    <_>6 2 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.6365579366683960e-003</threshold>\n                            <left_val>0.3806715011596680</left_val>\n                            <right_val>-0.0672468394041061</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 18 2 2 -1.</_>\n                                    <_>10 18 1 1 2.</_>\n                                    <_>11 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.3844049428589642e-004</threshold>\n                            <left_val>-0.3112238049507141</left_val>\n                            <right_val>0.0838383585214615</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 5 4 4 -1.</_>\n                                    <_>4 5 2 2 2.</_>\n                                    <_>6 7 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.1017560288310051e-003</threshold>\n                            <left_val>0.2606728076934815</left_val>\n                            <right_val>-0.1044974029064179</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 1 3 -1.</_>\n                                    <_>6 8 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3336989795789123e-003</threshold>\n                            <left_val>-0.0582501403987408</left_val>\n                            <right_val>0.4768244028091431</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 10 6 2 -1.</_>\n                                    <_>16 10 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.2090239906683564e-003</threshold>\n                            <left_val>0.1483450978994370</left_val>\n                            <right_val>-0.1732946932315826</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.2529590129852295</stage_threshold>\n                <parent>15</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 8 3 6 -1.</_>\n                                    <_>17 8 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.1760931015014648e-003</threshold>\n                            <left_val>0.3333333134651184</left_val>\n                            <right_val>-0.1664234995841980</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 10 6 2 -1.</_>\n                                    <_>6 10 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0248580798506737</threshold>\n                            <left_val>-0.0727288722991943</left_val>\n                            <right_val>0.5667458176612854</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 5 3 7 -1.</_>\n                                    <_>7 5 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.7597280032932758e-003</threshold>\n                            <left_val>0.4625856876373291</left_val>\n                            <right_val>-0.0931121781468391</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 13 6 6 -1.</_>\n                                    <_>0 16 6 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.8239021822810173e-003</threshold>\n                            <left_val>-0.2741461098194122</left_val>\n                            <right_val>0.1324304938316345</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 5 1 9 -1.</_>\n                                    <_>12 8 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0109488395974040</threshold>\n                            <left_val>0.2234548032283783</left_val>\n                            <right_val>-0.1496544927358627</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 9 3 3 -1.</_>\n                                    <_>6 9 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.4349008928984404e-003</threshold>\n                            <left_val>0.3872498869895935</left_val>\n                            <right_val>-0.0661217272281647</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 5 6 13 -1.</_>\n                                    <_>9 5 2 13 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0311562903225422</threshold>\n                            <left_val>0.2407827973365784</left_val>\n                            <right_val>-0.1140690967440605</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 8 1 10 -1.</_>\n                                    <_>19 13 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.1100519914180040e-003</threshold>\n                            <left_val>-0.2820797860622406</left_val>\n                            <right_val>0.1327542960643768</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 18 6 1 -1.</_>\n                                    <_>13 18 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.1762740109115839e-003</threshold>\n                            <left_val>0.0345859304070473</left_val>\n                            <right_val>-0.5137431025505066</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 7 6 12 -1.</_>\n                                    <_>11 7 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0279774591326714</threshold>\n                            <left_val>0.2392677962779999</left_val>\n                            <right_val>-0.1325591951608658</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 7 6 6 -1.</_>\n                                    <_>14 7 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0230979397892952</threshold>\n                            <left_val>0.3901962041854858</left_val>\n                            <right_val>-0.0784780085086823</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 8 3 4 -1.</_>\n                                    <_>16 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.9731930010020733e-003</threshold>\n                            <left_val>0.3069106936454773</left_val>\n                            <right_val>-0.0706014037132263</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 11 4 2 -1.</_>\n                                    <_>6 12 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.0335749033838511e-003</threshold>\n                            <left_val>-0.1400219053030014</left_val>\n                            <right_val>0.1913485974073410</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 6 6 8 -1.</_>\n                                    <_>3 6 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0108443703502417</threshold>\n                            <left_val>0.1654873043298721</left_val>\n                            <right_val>-0.1565777957439423</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 15 6 5 -1.</_>\n                                    <_>13 15 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0181505102664232</threshold>\n                            <left_val>-0.6324359178543091</left_val>\n                            <right_val>0.0395618192851543</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 17 4 2 -1.</_>\n                                    <_>15 18 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.1052298881113529e-004</threshold>\n                            <left_val>-0.1851557046175003</left_val>\n                            <right_val>0.1340880990028381</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 11 6 1 -1.</_>\n                                    <_>15 11 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0108933402225375</threshold>\n                            <left_val>-0.0267302300781012</left_val>\n                            <right_val>0.6097180247306824</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 18 2 2 -1.</_>\n                                    <_>5 18 1 1 2.</_>\n                                    <_>6 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.8780900174751878e-004</threshold>\n                            <left_val>-0.3006514012813568</left_val>\n                            <right_val>0.0731714591383934</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 8 4 4 -1.</_>\n                                    <_>4 8 2 2 2.</_>\n                                    <_>6 10 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5855069290846586e-003</threshold>\n                            <left_val>0.2621760964393616</left_val>\n                            <right_val>-0.0797140970826149</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 7 9 3 -1.</_>\n                                    <_>11 8 9 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0197592806071043</threshold>\n                            <left_val>-0.5903922915458679</left_val>\n                            <right_val>0.0406989715993404</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 3 10 4 -1.</_>\n                                    <_>0 3 5 2 2.</_>\n                                    <_>5 5 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0108452104032040</threshold>\n                            <left_val>0.1636455953121185</left_val>\n                            <right_val>-0.1258606016635895</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 18 6 1 -1.</_>\n                                    <_>9 18 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.3183090165257454e-003</threshold>\n                            <left_val>-0.5747488141059876</left_val>\n                            <right_val>0.0376443117856979</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 3 3 -1.</_>\n                                    <_>0 9 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.4913700288161635e-003</threshold>\n                            <left_val>0.0609134696424007</left_val>\n                            <right_val>-0.3022292852401733</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 6 8 -1.</_>\n                                    <_>0 0 3 4 2.</_>\n                                    <_>3 4 3 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0156756993383169</threshold>\n                            <left_val>-0.0731459110975266</left_val>\n                            <right_val>0.2937945127487183</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 6 3 8 -1.</_>\n                                    <_>8 6 1 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0110335601493716</threshold>\n                            <left_val>0.3931880891323090</left_val>\n                            <right_val>-0.0470843203365803</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 7 7 3 -1.</_>\n                                    <_>13 8 7 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.8555756956338882e-003</threshold>\n                            <left_val>0.0376013815402985</left_val>\n                            <right_val>-0.4910849034786224</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 3 2 2 -1.</_>\n                                    <_>3 4 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.9665671112015843e-004</threshold>\n                            <left_val>0.1795202046632767</left_val>\n                            <right_val>-0.1108623966574669</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 3 3 3 -1.</_>\n                                    <_>0 4 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.0592409893870354e-003</threshold>\n                            <left_val>-0.4442946016788483</left_val>\n                            <right_val>0.0510054305195808</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 3 5 2 -1.</_>\n                                    <_>9 4 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.3201179727911949e-003</threshold>\n                            <left_val>-0.0528410896658897</left_val>\n                            <right_val>0.3719710111618042</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 5 9 4 -1.</_>\n                                    <_>9 5 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0206828303635120</threshold>\n                            <left_val>0.0576671697199345</left_val>\n                            <right_val>-0.3690159916877747</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 12 3 -1.</_>\n                                    <_>7 10 4 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0998226627707481</threshold>\n                            <left_val>-0.0373770184814930</left_val>\n                            <right_val>0.5816559195518494</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 7 3 6 -1.</_>\n                                    <_>9 7 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.5854229032993317e-003</threshold>\n                            <left_val>0.2850944101810455</left_val>\n                            <right_val>-0.0609780699014664</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 5 6 5 -1.</_>\n                                    <_>8 5 3 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0609003007411957</threshold>\n                            <left_val>-0.5103176832199097</left_val>\n                            <right_val>0.0377874001860619</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 2 3 -1.</_>\n                                    <_>0 6 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9991709161549807e-003</threshold>\n                            <left_val>-0.4794301092624664</left_val>\n                            <right_val>0.0388338901102543</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 7 3 4 -1.</_>\n                                    <_>10 7 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.8906438797712326e-003</threshold>\n                            <left_val>0.4060907959938049</left_val>\n                            <right_val>-0.0478696487843990</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 6 15 -1.</_>\n                                    <_>3 0 2 15 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0826889276504517</threshold>\n                            <left_val>-0.7067118287086487</left_val>\n                            <right_val>0.0274877492338419</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 1 3 5 -1.</_>\n                                    <_>16 1 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0060399807989597e-003</threshold>\n                            <left_val>0.0282084401696920</left_val>\n                            <right_val>-0.5290969014167786</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 2 3 10 -1.</_>\n                                    <_>10 2 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.1695030890405178e-003</threshold>\n                            <left_val>-0.0545548610389233</left_val>\n                            <right_val>0.3283798098564148</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 8 6 12 -1.</_>\n                                    <_>10 8 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.3914761152118444e-003</threshold>\n                            <left_val>0.0921176671981812</left_val>\n                            <right_val>-0.2163711041212082</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 4 3 4 -1.</_>\n                                    <_>16 6 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6131230406463146e-003</threshold>\n                            <left_val>0.1365101933479309</left_val>\n                            <right_val>-0.1378113031387329</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 7 2 2 -1.</_>\n                                    <_>16 7 1 1 2.</_>\n                                    <_>17 8 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.0490659456700087e-004</threshold>\n                            <left_val>-0.0686371102929115</left_val>\n                            <right_val>0.3358106911182404</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 0 6 9 -1.</_>\n                                    <_>13 3 6 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0381065085530281</threshold>\n                            <left_val>0.2944543063640595</left_val>\n                            <right_val>-0.0682392269372940</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 17 1 3 -1.</_>\n                                    <_>7 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.2450799052603543e-005</threshold>\n                            <left_val>-0.1675013005733490</left_val>\n                            <right_val>0.1217823028564453</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 1 4 2 -1.</_>\n                                    <_>12 2 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.5837959945201874e-003</threshold>\n                            <left_val>-0.0920428484678268</left_val>\n                            <right_val>0.2134899049997330</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 3 1 3 -1.</_>\n                                    <_>17 4 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.2924340553581715e-003</threshold>\n                            <left_val>0.0629172325134277</left_val>\n                            <right_val>-0.3617450892925263</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 16 9 3 -1.</_>\n                                    <_>0 17 9 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.9146775901317596e-003</threshold>\n                            <left_val>0.0195340607315302</left_val>\n                            <right_val>-0.8101503849029541</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 6 2 4 -1.</_>\n                                    <_>3 6 1 2 2.</_>\n                                    <_>4 8 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7086310544982553e-003</threshold>\n                            <left_val>0.2552523910999298</left_val>\n                            <right_val>-0.0682294592261314</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 18 3 1 -1.</_>\n                                    <_>14 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.1844399161636829e-003</threshold>\n                            <left_val>0.0233140494674444</left_val>\n                            <right_val>-0.8429678082466126</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 4 2 -1.</_>\n                                    <_>2 18 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.4244330599904060e-003</threshold>\n                            <left_val>0.2721368968486786</left_val>\n                            <right_val>-0.0763952285051346</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 19 2 1 -1.</_>\n                                    <_>2 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7591470279730856e-004</threshold>\n                            <left_val>-0.1074284017086029</left_val>\n                            <right_val>0.2288897037506104</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 4 2 -1.</_>\n                                    <_>0 19 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.0005177510902286e-004</threshold>\n                            <left_val>-0.2985421121120453</left_val>\n                            <right_val>0.0634797364473343</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 17 1 3 -1.</_>\n                                    <_>2 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.5001438916660845e-004</threshold>\n                            <left_val>-0.2717896997928619</left_val>\n                            <right_val>0.0696150064468384</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 8 3 5 -1.</_>\n                                    <_>5 8 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.8751391954720020e-003</threshold>\n                            <left_val>-0.0571858994662762</left_val>\n                            <right_val>0.3669595122337341</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 1 6 7 -1.</_>\n                                    <_>4 1 2 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0127619002014399</threshold>\n                            <left_val>0.0679556876420975</left_val>\n                            <right_val>-0.2853415012359619</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 6 2 8 -1.</_>\n                                    <_>3 6 1 4 2.</_>\n                                    <_>4 10 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.4752789866179228e-003</threshold>\n                            <left_val>0.2068066000938416</left_val>\n                            <right_val>-0.1005939021706581</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 5 11 10 -1.</_>\n                                    <_>4 10 11 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1213881969451904</threshold>\n                            <left_val>-0.0971267968416214</left_val>\n                            <right_val>0.1978961974382401</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 13 20 2 -1.</_>\n                                    <_>10 13 10 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0500812791287899</threshold>\n                            <left_val>0.2841717898845673</left_val>\n                            <right_val>-0.0678799971938133</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 13 16 3 -1.</_>\n                                    <_>9 13 8 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0314549505710602</threshold>\n                            <left_val>-0.0894686728715897</left_val>\n                            <right_val>0.2129842042922974</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 4 4 4 -1.</_>\n                                    <_>16 4 2 2 2.</_>\n                                    <_>18 6 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.8878319533541799e-003</threshold>\n                            <left_val>-0.1165644004940987</left_val>\n                            <right_val>0.1666352003812790</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 4 12 -1.</_>\n                                    <_>16 0 2 6 2.</_>\n                                    <_>18 6 2 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.7211960665881634e-003</threshold>\n                            <left_val>0.2370214015245438</left_val>\n                            <right_val>-0.0907766073942184</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 15 3 1 -1.</_>\n                                    <_>15 15 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.8076719425152987e-004</threshold>\n                            <left_val>0.1795192956924439</left_val>\n                            <right_val>-0.1079348027706146</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 4 12 10 -1.</_>\n                                    <_>3 9 12 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1976184993982315</threshold>\n                            <left_val>0.4567429125308991</left_val>\n                            <right_val>-0.0404801592230797</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 18 2 2 -1.</_>\n                                    <_>9 18 1 1 2.</_>\n                                    <_>10 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.3846809926908463e-004</threshold>\n                            <left_val>-0.2373300939798355</left_val>\n                            <right_val>0.0759221613407135</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 18 2 2 -1.</_>\n                                    <_>9 18 1 1 2.</_>\n                                    <_>10 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.1540730085689574e-004</threshold>\n                            <left_val>0.0816880166530609</left_val>\n                            <right_val>-0.2868503034114838</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 4 2 14 -1.</_>\n                                    <_>13 4 1 7 2.</_>\n                                    <_>14 11 1 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0101630901917815</threshold>\n                            <left_val>-0.0412500202655792</left_val>\n                            <right_val>0.4803834855556488</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 2 6 4 -1.</_>\n                                    <_>7 2 3 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.2184870950877666e-003</threshold>\n                            <left_val>0.1745858043432236</left_val>\n                            <right_val>-0.1014650017023087</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 18 20 -1.</_>\n                                    <_>0 0 9 10 2.</_>\n                                    <_>9 10 9 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.2426317036151886</threshold>\n                            <left_val>0.0534264817833900</left_val>\n                            <right_val>-0.3231852948665619</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 11 1 2 -1.</_>\n                                    <_>15 12 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.9304101634770632e-004</threshold>\n                            <left_val>-0.1149917989969254</left_val>\n                            <right_val>0.1479393988847733</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 10 2 4 -1.</_>\n                                    <_>16 10 1 2 2.</_>\n                                    <_>17 12 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.5475199110805988e-003</threshold>\n                            <left_val>-0.0394249781966209</left_val>\n                            <right_val>0.5312618017196655</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 2 2 -1.</_>\n                                    <_>18 17 1 1 2.</_>\n                                    <_>19 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.1403690334409475e-004</threshold>\n                            <left_val>0.0697538331151009</left_val>\n                            <right_val>-0.2731958031654358</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 17 1 2 -1.</_>\n                                    <_>9 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.7119462871924043e-004</threshold>\n                            <left_val>0.3436990082263947</left_val>\n                            <right_val>-0.0576990097761154</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 4 9 6 -1.</_>\n                                    <_>11 4 3 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.6290069371461868e-003</threshold>\n                            <left_val>0.1175848990678787</left_val>\n                            <right_val>-0.1502013951539993</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.1188739538192749</stage_threshold>\n                <parent>16</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 9 9 10 -1.</_>\n                                    <_>9 9 3 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0265134498476982</threshold>\n                            <left_val>0.2056864053010941</left_val>\n                            <right_val>-0.2647390067577362</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 0 5 4 -1.</_>\n                                    <_>5 2 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.7727458924055099e-003</threshold>\n                            <left_val>-0.1119284033775330</left_val>\n                            <right_val>0.3257054984569550</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 7 11 4 -1.</_>\n                                    <_>5 9 11 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0322903506457806</threshold>\n                            <left_val>-0.0985747575759888</left_val>\n                            <right_val>0.3177917003631592</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 4 2 14 -1.</_>\n                                    <_>3 4 1 14 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.8103240765631199e-003</threshold>\n                            <left_val>0.1521389931440353</left_val>\n                            <right_val>-0.1968640983104706</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 6 3 5 -1.</_>\n                                    <_>9 6 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0109914299100637</threshold>\n                            <left_val>0.5140765905380249</left_val>\n                            <right_val>-0.0437072105705738</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 4 3 9 -1.</_>\n                                    <_>9 4 1 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.3133831135928631e-003</threshold>\n                            <left_val>-0.0927810221910477</left_val>\n                            <right_val>0.3470247089862824</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 20 6 -1.</_>\n                                    <_>0 10 20 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0871059820055962</threshold>\n                            <left_val>0.0300536490976810</left_val>\n                            <right_val>-0.8281481862068176</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 16 6 1 -1.</_>\n                                    <_>17 16 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.1799359926953912e-003</threshold>\n                            <left_val>-0.1292842030525208</left_val>\n                            <right_val>0.2064612060785294</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 18 2 2 -1.</_>\n                                    <_>17 19 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.3056890182197094e-004</threshold>\n                            <left_val>-0.5002143979072571</left_val>\n                            <right_val>0.0936669930815697</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 17 6 3 -1.</_>\n                                    <_>10 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0136871701106429</threshold>\n                            <left_val>-0.7935814857482910</left_val>\n                            <right_val>-6.6733639687299728e-003</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 9 15 -1.</_>\n                                    <_>7 1 3 15 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0759174525737762</threshold>\n                            <left_val>0.3046964108943939</left_val>\n                            <right_val>-0.0796558931469917</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 5 3 12 -1.</_>\n                                    <_>12 5 1 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.8559709899127483e-003</threshold>\n                            <left_val>0.2096146047115326</left_val>\n                            <right_val>-0.1273255050182343</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 15 4 3 -1.</_>\n                                    <_>0 16 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.0231510065495968e-003</threshold>\n                            <left_val>-0.6581727862358093</left_val>\n                            <right_val>0.0506836399435997</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 15 1 -1.</_>\n                                    <_>5 0 5 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0175580400973558</threshold>\n                            <left_val>-0.0853826925158501</left_val>\n                            <right_val>0.3617455959320068</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 0 6 4 -1.</_>\n                                    <_>8 0 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0219882391393185</threshold>\n                            <left_val>0.0629436969757080</left_val>\n                            <right_val>-0.7089633941650391</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 9 3 -1.</_>\n                                    <_>5 0 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.8599589131772518e-003</threshold>\n                            <left_val>0.1468378007411957</left_val>\n                            <right_val>-0.1646597981452942</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 6 3 7 -1.</_>\n                                    <_>14 6 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0100308498367667</threshold>\n                            <left_val>0.4957993924617767</left_val>\n                            <right_val>-0.0271883402019739</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 6 4 2 -1.</_>\n                                    <_>7 7 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.9560329429805279e-003</threshold>\n                            <left_val>0.2797777950763702</left_val>\n                            <right_val>-0.0779533311724663</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 18 6 1 -1.</_>\n                                    <_>8 18 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8356808945536613e-003</threshold>\n                            <left_val>-0.5816398262977600</left_val>\n                            <right_val>0.0357399396598339</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 6 2 2 -1.</_>\n                                    <_>18 7 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.2647319603711367e-003</threshold>\n                            <left_val>-0.4994508028030396</left_val>\n                            <right_val>0.0469864904880524</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 4 7 3 -1.</_>\n                                    <_>6 5 7 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.8412350267171860e-003</threshold>\n                            <left_val>0.3453283011913300</left_val>\n                            <right_val>-0.0688104033470154</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 7 3 1 -1.</_>\n                                    <_>13 7 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.1718113506212831e-005</threshold>\n                            <left_val>0.1504171043634415</left_val>\n                            <right_val>-0.1414667963981628</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 1 2 10 -1.</_>\n                                    <_>15 1 1 5 2.</_>\n                                    <_>16 6 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.2448628917336464e-003</threshold>\n                            <left_val>0.2272451072931290</left_val>\n                            <right_val>-0.0928602069616318</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 2 2 -1.</_>\n                                    <_>0 19 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.8561151167377830e-004</threshold>\n                            <left_val>-0.4431901872158051</left_val>\n                            <right_val>0.0578124411404133</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 4 1 8 -1.</_>\n                                    <_>19 8 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.2474247533828020e-004</threshold>\n                            <left_val>0.1395238935947418</left_val>\n                            <right_val>-0.1466871947050095</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 17 1 3 -1.</_>\n                                    <_>1 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.2942948746494949e-004</threshold>\n                            <left_val>-0.2990157008171082</left_val>\n                            <right_val>0.0760667398571968</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 15 6 4 -1.</_>\n                                    <_>0 15 3 2 2.</_>\n                                    <_>3 17 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.2605739757418633e-003</threshold>\n                            <left_val>-0.1612560003995895</left_val>\n                            <right_val>0.1395380049943924</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 0 1 18 -1.</_>\n                                    <_>19 6 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0516670197248459</threshold>\n                            <left_val>-0.5314283967018127</left_val>\n                            <right_val>0.0407195203006268</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 2 6 2 -1.</_>\n                                    <_>12 2 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0152856195345521</threshold>\n                            <left_val>-0.7820637822151184</left_val>\n                            <right_val>0.0271837692707777</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 8 12 2 -1.</_>\n                                    <_>6 8 4 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0690298229455948</threshold>\n                            <left_val>-0.0364270210266113</left_val>\n                            <right_val>0.7110251784324646</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 4 1 -1.</_>\n                                    <_>18 0 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.4522749697789550e-003</threshold>\n                            <left_val>-0.0968905165791512</left_val>\n                            <right_val>0.2166842073202133</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 4 2 6 -1.</_>\n                                    <_>8 7 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4765590205788612e-003</threshold>\n                            <left_val>0.1164531037211418</left_val>\n                            <right_val>-0.1822797954082489</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 5 2 10 -1.</_>\n                                    <_>15 5 1 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5134819550439715e-003</threshold>\n                            <left_val>0.1786397993564606</left_val>\n                            <right_val>-0.1221496984362602</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 4 2 2 -1.</_>\n                                    <_>13 5 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5099470037966967e-003</threshold>\n                            <left_val>0.1808623969554901</left_val>\n                            <right_val>-0.1144606992602348</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 1 3 6 -1.</_>\n                                    <_>11 3 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.7054620012640953e-003</threshold>\n                            <left_val>0.2510659992694855</left_val>\n                            <right_val>-0.0918714627623558</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 9 12 2 -1.</_>\n                                    <_>10 9 4 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0140752000734210</threshold>\n                            <left_val>0.1370750963687897</left_val>\n                            <right_val>-0.1733350008726120</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 16 4 2 -1.</_>\n                                    <_>9 17 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2400720044970512e-003</threshold>\n                            <left_val>0.4009298086166382</left_val>\n                            <right_val>-0.0475768782198429</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 14 15 4 -1.</_>\n                                    <_>5 16 15 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0197823699563742</threshold>\n                            <left_val>-0.1904035061597824</left_val>\n                            <right_val>0.1492341011762619</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 16 2 2 -1.</_>\n                                    <_>18 17 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.6002870872616768e-003</threshold>\n                            <left_val>0.0469717681407928</left_val>\n                            <right_val>-0.4330765902996063</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 18 2 2 -1.</_>\n                                    <_>16 18 1 1 2.</_>\n                                    <_>17 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.3445628145709634e-004</threshold>\n                            <left_val>-0.4374423027038574</left_val>\n                            <right_val>0.0415201894938946</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 4 3 8 -1.</_>\n                                    <_>7 4 1 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0174665097147226</threshold>\n                            <left_val>0.6581817269325256</left_val>\n                            <right_val>-0.0344474911689758</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 9 3 1 -1.</_>\n                                    <_>6 9 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.0425589755177498e-003</threshold>\n                            <left_val>0.3965792953968048</left_val>\n                            <right_val>-0.0440524294972420</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 1 6 -1.</_>\n                                    <_>0 10 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.6661779265850782e-003</threshold>\n                            <left_val>0.0587709583342075</left_val>\n                            <right_val>-0.3280636966228485</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 2 9 6 -1.</_>\n                                    <_>14 2 3 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0559823699295521</threshold>\n                            <left_val>-0.5173547267913818</left_val>\n                            <right_val>0.0357918404042721</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 2 6 4 -1.</_>\n                                    <_>14 2 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5066330088302493e-003</threshold>\n                            <left_val>0.1512386947870255</left_val>\n                            <right_val>-0.1252018064260483</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 7 2 4 -1.</_>\n                                    <_>1 9 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0114723695442081</threshold>\n                            <left_val>-0.6293053030967712</left_val>\n                            <right_val>0.0347043313086033</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 1 6 4 -1.</_>\n                                    <_>13 3 6 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0234096292406321</threshold>\n                            <left_val>-0.0580633506178856</left_val>\n                            <right_val>0.3866822123527527</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 10 2 10 -1.</_>\n                                    <_>4 10 1 5 2.</_>\n                                    <_>5 15 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.3243729956448078e-003</threshold>\n                            <left_val>0.1875409930944443</left_val>\n                            <right_val>-0.0983946695923805</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 16 9 3 -1.</_>\n                                    <_>5 16 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0290392991155386</threshold>\n                            <left_val>-0.5448690056800842</left_val>\n                            <right_val>0.0409263409674168</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 2 3 9 -1.</_>\n                                    <_>2 2 1 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0144746499136090</threshold>\n                            <left_val>-0.6724839210510254</left_val>\n                            <right_val>0.0231288503855467</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 7 1 4 -1.</_>\n                                    <_>19 9 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.2086091600358486e-003</threshold>\n                            <left_val>-0.4327144026756287</left_val>\n                            <right_val>0.0437806509435177</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 11 6 8 -1.</_>\n                                    <_>14 11 3 4 2.</_>\n                                    <_>17 15 3 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.9382899887859821e-003</threshold>\n                            <left_val>-0.1087862029671669</left_val>\n                            <right_val>0.1934258937835693</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 12 4 6 -1.</_>\n                                    <_>15 12 2 3 2.</_>\n                                    <_>17 15 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.3193930760025978e-003</threshold>\n                            <left_val>0.2408093065023422</left_val>\n                            <right_val>-0.1038080006837845</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 15 2 2 -1.</_>\n                                    <_>16 15 1 1 2.</_>\n                                    <_>17 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.3705669445917010e-004</threshold>\n                            <left_val>-0.0873490720987320</left_val>\n                            <right_val>0.2046623975038528</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 16 2 2 -1.</_>\n                                    <_>17 16 1 1 2.</_>\n                                    <_>18 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.7858079778961837e-004</threshold>\n                            <left_val>0.0456245802342892</left_val>\n                            <right_val>-0.3885467052459717</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 16 2 2 -1.</_>\n                                    <_>17 16 1 1 2.</_>\n                                    <_>18 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.5342838428914547e-004</threshold>\n                            <left_val>-0.5507794022560120</left_val>\n                            <right_val>0.0358258895576000</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 3 2 2 -1.</_>\n                                    <_>2 3 1 1 2.</_>\n                                    <_>3 4 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.4772121075075120e-005</threshold>\n                            <left_val>-0.1122523993253708</left_val>\n                            <right_val>0.1750351935625076</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 10 3 3 -1.</_>\n                                    <_>11 10 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8445889949798584e-003</threshold>\n                            <left_val>0.2452670037746429</left_val>\n                            <right_val>-0.0811325684189796</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 9 7 8 -1.</_>\n                                    <_>5 13 7 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0401284582912922</threshold>\n                            <left_val>-0.6312270760536194</left_val>\n                            <right_val>0.0269726701080799</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 16 2 2 -1.</_>\n                                    <_>7 16 1 1 2.</_>\n                                    <_>8 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7886360001284629e-004</threshold>\n                            <left_val>0.1985509991645813</left_val>\n                            <right_val>-0.1033368036150932</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 16 2 2 -1.</_>\n                                    <_>7 16 1 1 2.</_>\n                                    <_>8 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.7668239888735116e-004</threshold>\n                            <left_val>-0.0913590118288994</left_val>\n                            <right_val>0.1984872072935104</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 8 10 3 -1.</_>\n                                    <_>14 8 5 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0727633833885193</threshold>\n                            <left_val>0.0500755794346333</left_val>\n                            <right_val>-0.3385263085365295</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 4 8 -1.</_>\n                                    <_>6 7 2 4 2.</_>\n                                    <_>8 11 2 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0101816300302744</threshold>\n                            <left_val>-0.0932299792766571</left_val>\n                            <right_val>0.2005959004163742</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 6 4 3 -1.</_>\n                                    <_>1 7 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.4409969337284565e-003</threshold>\n                            <left_val>0.0646366328001022</left_val>\n                            <right_val>-0.2692174017429352</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 10 6 10 -1.</_>\n                                    <_>8 10 2 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.6227488890290260e-003</threshold>\n                            <left_val>0.1316989064216614</left_val>\n                            <right_val>-0.1251484006643295</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 6 3 6 -1.</_>\n                                    <_>5 6 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3635610230267048e-003</threshold>\n                            <left_val>0.1635046005249023</left_val>\n                            <right_val>-0.1066593974828720</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.0888810157775879</stage_threshold>\n                <parent>17</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 4 4 -1.</_>\n                                    <_>3 10 2 2 2.</_>\n                                    <_>5 12 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6991164609789848e-003</threshold>\n                            <left_val>0.6112532019615173</left_val>\n                            <right_val>-0.0662253126502037</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 4 4 -1.</_>\n                                    <_>3 10 2 2 2.</_>\n                                    <_>5 12 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6426531672477722e-003</threshold>\n                            <left_val>-1.</left_val>\n                            <right_val>2.7699959464371204e-003</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 4 4 -1.</_>\n                                    <_>3 10 2 2 2.</_>\n                                    <_>5 12 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6381865441799164e-003</threshold>\n                            <left_val>1.</left_val>\n                            <right_val>-2.9904270195402205e-004</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 8 2 6 -1.</_>\n                                    <_>15 8 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.2553939856588840e-003</threshold>\n                            <left_val>0.2846438884735107</left_val>\n                            <right_val>-0.1554012000560761</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 4 4 -1.</_>\n                                    <_>3 10 2 2 2.</_>\n                                    <_>5 12 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6223521977663040e-003</threshold>\n                            <left_val>-1.</left_val>\n                            <right_val>0.0439991801977158</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 4 4 -1.</_>\n                                    <_>3 10 2 2 2.</_>\n                                    <_>5 12 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.1231241822242737e-003</threshold>\n                            <left_val>0.8686934113502502</left_val>\n                            <right_val>-2.7267890982329845e-003</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 4 3 9 -1.</_>\n                                    <_>13 4 1 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.6240433156490326e-003</threshold>\n                            <left_val>0.4535248875617981</left_val>\n                            <right_val>-0.0860713794827461</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 3 1 12 -1.</_>\n                                    <_>12 7 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.9324144646525383e-003</threshold>\n                            <left_val>0.1337555944919586</left_val>\n                            <right_val>-0.2601251900196075</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 18 1 -1.</_>\n                                    <_>8 0 6 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0142078101634979</threshold>\n                            <left_val>0.3207764029502869</left_val>\n                            <right_val>-0.0972264111042023</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 0 10 6 -1.</_>\n                                    <_>10 0 5 3 2.</_>\n                                    <_>15 3 5 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0259110108017921</threshold>\n                            <left_val>-0.1296408027410507</left_val>\n                            <right_val>0.2621864974498749</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 16 2 2 -1.</_>\n                                    <_>18 17 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.0531509653665125e-004</threshold>\n                            <left_val>-0.1240428015589714</left_val>\n                            <right_val>0.2106295973062515</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 5 4 2 -1.</_>\n                                    <_>3 5 2 1 2.</_>\n                                    <_>5 6 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.4795680625829846e-005</threshold>\n                            <left_val>0.1197429969906807</left_val>\n                            <right_val>-0.2320127934217453</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 8 3 3 -1.</_>\n                                    <_>12 8 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.8555199541151524e-003</threshold>\n                            <left_val>-0.0632761269807816</left_val>\n                            <right_val>0.4104425013065338</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 7 3 5 -1.</_>\n                                    <_>12 7 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0122530404478312</threshold>\n                            <left_val>0.5488333106040955</left_val>\n                            <right_val>-0.0397311002016068</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 19 15 1 -1.</_>\n                                    <_>8 19 5 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.9058770053088665e-003</threshold>\n                            <left_val>0.2419098019599915</left_val>\n                            <right_val>-0.0970960110425949</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 13 3 2 -1.</_>\n                                    <_>8 14 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7560980524867773e-003</threshold>\n                            <left_val>-0.1256967931985855</left_val>\n                            <right_val>0.1945665031671524</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 12 8 4 -1.</_>\n                                    <_>2 12 4 2 2.</_>\n                                    <_>6 14 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.7662160620093346e-003</threshold>\n                            <left_val>0.2976570129394531</left_val>\n                            <right_val>-0.0968181565403938</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 16 2 2 -1.</_>\n                                    <_>16 16 1 1 2.</_>\n                                    <_>17 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.8997188676148653e-004</threshold>\n                            <left_val>0.0621884018182755</left_val>\n                            <right_val>-0.4204089939594269</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 0 3 2 -1.</_>\n                                    <_>8 0 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.3579880837351084e-003</threshold>\n                            <left_val>0.0474981404840946</left_val>\n                            <right_val>-0.6321688294410706</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 2 5 -1.</_>\n                                    <_>7 7 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0167455393821001</threshold>\n                            <left_val>0.7109813094139099</left_val>\n                            <right_val>-0.0391573496162891</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 0 2 17 -1.</_>\n                                    <_>19 0 1 17 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.5409899689257145e-003</threshold>\n                            <left_val>-0.3504317104816437</left_val>\n                            <right_val>0.0706169530749321</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 16 1 3 -1.</_>\n                                    <_>16 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.0016340315341949e-004</threshold>\n                            <left_val>0.0919024571776390</left_val>\n                            <right_val>-0.2461867034435272</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 8 3 7 -1.</_>\n                                    <_>15 8 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0149189904332161</threshold>\n                            <left_val>-0.0519094504415989</left_val>\n                            <right_val>0.5663604140281677</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 17 2 2 -1.</_>\n                                    <_>10 17 1 1 2.</_>\n                                    <_>11 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.8153079114854336e-004</threshold>\n                            <left_val>0.0646595582365990</left_val>\n                            <right_val>-0.3659060895442963</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 9 1 3 -1.</_>\n                                    <_>4 10 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.0211321427486837e-004</threshold>\n                            <left_val>0.1792656928300858</left_val>\n                            <right_val>-0.1141066029667854</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 10 2 3 -1.</_>\n                                    <_>18 11 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.8521419628523290e-004</threshold>\n                            <left_val>0.1034561991691589</left_val>\n                            <right_val>-0.2007246017456055</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 1 3 10 -1.</_>\n                                    <_>13 1 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.0837132409214973e-003</threshold>\n                            <left_val>-0.0660734623670578</left_val>\n                            <right_val>0.3028424978256226</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 12 9 1 -1.</_>\n                                    <_>11 12 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0228049699217081</threshold>\n                            <left_val>0.5296235084533691</left_val>\n                            <right_val>-0.0401189997792244</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 18 2 2 -1.</_>\n                                    <_>5 18 1 1 2.</_>\n                                    <_>6 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.9440450705587864e-004</threshold>\n                            <left_val>0.0818548202514648</left_val>\n                            <right_val>-0.2466336041688919</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 6 1 9 -1.</_>\n                                    <_>19 9 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0128480903804302</threshold>\n                            <left_val>-0.3497331142425537</left_val>\n                            <right_val>0.0569162294268608</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 7 2 4 -1.</_>\n                                    <_>4 7 1 2 2.</_>\n                                    <_>5 9 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0937290498986840e-003</threshold>\n                            <left_val>0.2336868047714233</left_val>\n                            <right_val>-0.0916048064827919</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 4 6 14 -1.</_>\n                                    <_>3 4 2 14 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0032650316134095e-003</threshold>\n                            <left_val>0.1185218021273613</left_val>\n                            <right_val>-0.1846919059753418</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 5 9 3 -1.</_>\n                                    <_>13 5 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0446884296834469</threshold>\n                            <left_val>-0.6436246037483215</left_val>\n                            <right_val>0.0303632691502571</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 7 2 6 -1.</_>\n                                    <_>18 9 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.1657543778419495e-003</threshold>\n                            <left_val>0.0436746589839458</left_val>\n                            <right_val>-0.4300208985805512</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 6 2 7 -1.</_>\n                                    <_>6 6 1 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0117178102955222</threshold>\n                            <left_val>0.4178147912025452</left_val>\n                            <right_val>-0.0482336990535259</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 4 6 8 -1.</_>\n                                    <_>13 4 3 8 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0842771306633949</threshold>\n                            <left_val>0.0534612797200680</left_val>\n                            <right_val>-0.3795219063758850</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 2 9 -1.</_>\n                                    <_>0 11 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0142118399962783</threshold>\n                            <left_val>0.0449009388685226</left_val>\n                            <right_val>-0.4298149943351746</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 7 5 3 -1.</_>\n                                    <_>0 8 5 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.5028340276330709e-003</threshold>\n                            <left_val>0.0822276398539543</left_val>\n                            <right_val>-0.2470639944076538</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 7 2 -1.</_>\n                                    <_>8 2 7 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0100035797804594</threshold>\n                            <left_val>-0.0572216697037220</left_val>\n                            <right_val>0.3460937142372131</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 5 3 5 -1.</_>\n                                    <_>8 5 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.0706320479512215e-003</threshold>\n                            <left_val>0.4505808949470520</left_val>\n                            <right_val>-0.0427953191101551</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 2 1 2 -1.</_>\n                                    <_>19 3 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.3141620224341750e-004</threshold>\n                            <left_val>0.1833691000938416</left_val>\n                            <right_val>-0.1075994968414307</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 10 11 -1.</_>\n                                    <_>11 7 5 11 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1972327977418900</threshold>\n                            <left_val>-0.0303638298064470</left_val>\n                            <right_val>0.6642342805862427</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 19 6 1 -1.</_>\n                                    <_>11 19 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.1258801035583019e-003</threshold>\n                            <left_val>-0.8922504782676697</left_val>\n                            <right_val>0.0256699901074171</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 0 12 1 -1.</_>\n                                    <_>7 0 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.6921341717243195e-003</threshold>\n                            <left_val>-0.0707643702626228</left_val>\n                            <right_val>0.2821052968502045</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 6 5 -1.</_>\n                                    <_>6 1 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.9262127876281738e-003</threshold>\n                            <left_val>0.0710782334208488</left_val>\n                            <right_val>-0.3023256063461304</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 12 12 6 -1.</_>\n                                    <_>10 12 4 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0572860091924667</threshold>\n                            <left_val>0.0509741306304932</left_val>\n                            <right_val>-0.3919695019721985</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 13 2 3 -1.</_>\n                                    <_>16 14 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.7920880131423473e-003</threshold>\n                            <left_val>0.0338419415056705</left_val>\n                            <right_val>-0.5101628899574280</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 14 4 2 -1.</_>\n                                    <_>7 15 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.4508679741993546e-003</threshold>\n                            <left_val>0.3087914884090424</left_val>\n                            <right_val>-0.0638450831174850</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 14 2 2 -1.</_>\n                                    <_>7 15 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.8390132188796997e-004</threshold>\n                            <left_val>-0.1302956938743591</left_val>\n                            <right_val>0.1460441052913666</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 2 4 -1.</_>\n                                    <_>3 10 1 2 2.</_>\n                                    <_>4 12 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7221809830516577e-003</threshold>\n                            <left_val>0.2915700972080231</left_val>\n                            <right_val>-0.0685495585203171</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 3 2 6 -1.</_>\n                                    <_>0 5 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0109482500702143</threshold>\n                            <left_val>0.0343514084815979</left_val>\n                            <right_val>-0.4770225882530212</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 10 2 2 -1.</_>\n                                    <_>1 10 1 1 2.</_>\n                                    <_>2 11 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7176309484057128e-005</threshold>\n                            <left_val>0.1605526953935623</left_val>\n                            <right_val>-0.1169084012508392</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 4 4 3 -1.</_>\n                                    <_>16 5 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.4884208366274834e-003</threshold>\n                            <left_val>-0.4341588914394379</left_val>\n                            <right_val>0.0461062416434288</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 10 2 4 -1.</_>\n                                    <_>5 10 1 2 2.</_>\n                                    <_>6 12 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.0975250992923975e-003</threshold>\n                            <left_val>0.3794333934783936</left_val>\n                            <right_val>-0.0568605512380600</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 11 13 2 -1.</_>\n                                    <_>5 12 13 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.4182081259787083e-003</threshold>\n                            <left_val>-0.1585821062326431</left_val>\n                            <right_val>0.1233541965484619</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 2 3 11 -1.</_>\n                                    <_>11 2 1 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0118312397971749</threshold>\n                            <left_val>-0.0409292913973331</left_val>\n                            <right_val>0.4587895870208740</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 2 4 4 -1.</_>\n                                    <_>10 4 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0135404998436570</threshold>\n                            <left_val>-0.0537255592644215</left_val>\n                            <right_val>0.3505612015724182</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 8 6 2 -1.</_>\n                                    <_>10 8 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.5932150892913342e-003</threshold>\n                            <left_val>0.1101052016019821</left_val>\n                            <right_val>-0.1675221025943756</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 2 3 3 -1.</_>\n                                    <_>12 2 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.6856270376592875e-003</threshold>\n                            <left_val>0.0665743574500084</left_val>\n                            <right_val>-0.3083502054214478</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 18 14 2 -1.</_>\n                                    <_>6 18 7 1 2.</_>\n                                    <_>13 19 7 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.6524690911173820e-003</threshold>\n                            <left_val>0.0663184821605682</left_val>\n                            <right_val>-0.2786133885383606</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 7 1 12 -1.</_>\n                                    <_>17 11 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.7341729775071144e-003</threshold>\n                            <left_val>0.1971835941076279</left_val>\n                            <right_val>-0.1078291982412338</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 5 10 3 -1.</_>\n                                    <_>10 6 10 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0944271497428417e-003</threshold>\n                            <left_val>0.0853374898433685</left_val>\n                            <right_val>-0.2484700977802277</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 1 3 3 -1.</_>\n                                    <_>7 1 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9162371065467596e-003</threshold>\n                            <left_val>-0.4747635126113892</left_val>\n                            <right_val>0.0335664898157120</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 8 3 1 -1.</_>\n                                    <_>14 8 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.0121419113129377e-003</threshold>\n                            <left_val>-0.0475753806531429</left_val>\n                            <right_val>0.4258680045604706</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 14 2 6 -1.</_>\n                                    <_>10 16 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.1694869976490736e-003</threshold>\n                            <left_val>-0.1051945015788078</left_val>\n                            <right_val>0.1716345995664597</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 12 14 -1.</_>\n                                    <_>8 1 4 14 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.2232756018638611</threshold>\n                            <left_val>-0.0143702095374465</left_val>\n                            <right_val>0.9248365163803101</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 1 6 14 -1.</_>\n                                    <_>16 1 2 14 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0955850481987000</threshold>\n                            <left_val>-0.7420663833618164</left_val>\n                            <right_val>0.0278189703822136</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 16 2 2 -1.</_>\n                                    <_>3 16 1 1 2.</_>\n                                    <_>4 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.4773729566950351e-005</threshold>\n                            <left_val>-0.1276578009128571</left_val>\n                            <right_val>0.1292666941881180</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 16 2 2 -1.</_>\n                                    <_>0 17 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.2459770308341831e-005</threshold>\n                            <left_val>-0.1651857942342758</left_val>\n                            <right_val>0.1003680974245071</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.0408929586410522</stage_threshold>\n                <parent>18</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 6 4 6 -1.</_>\n                                    <_>15 6 2 3 2.</_>\n                                    <_>17 9 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.5778270363807678e-003</threshold>\n                            <left_val>0.3381525874137878</left_val>\n                            <right_val>-0.1528190970420837</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 5 2 2 -1.</_>\n                                    <_>12 6 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0922809597104788e-003</threshold>\n                            <left_val>0.2228236943483353</left_val>\n                            <right_val>-0.1930849999189377</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 6 6 13 -1.</_>\n                                    <_>9 6 2 13 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0297595895826817</threshold>\n                            <left_val>0.2595987021923065</left_val>\n                            <right_val>-0.1540940999984741</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 9 6 5 -1.</_>\n                                    <_>3 9 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0131475403904915</threshold>\n                            <left_val>0.1903381049633026</left_val>\n                            <right_val>-0.1654399931430817</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 3 4 -1.</_>\n                                    <_>0 7 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.4396329643204808e-003</threshold>\n                            <left_val>0.2007171064615250</left_val>\n                            <right_val>-0.1233894005417824</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 16 2 -1.</_>\n                                    <_>4 1 8 1 2.</_>\n                                    <_>12 2 8 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5928250290453434e-003</threshold>\n                            <left_val>0.2398552000522614</left_val>\n                            <right_val>-0.1292214989662170</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 18 4 2 -1.</_>\n                                    <_>1 18 2 1 2.</_>\n                                    <_>3 19 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5314699849113822e-003</threshold>\n                            <left_val>-0.4901489913463593</left_val>\n                            <right_val>0.1027503013610840</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 7 3 4 -1.</_>\n                                    <_>8 7 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.2372139655053616e-003</threshold>\n                            <left_val>0.3121463954448700</left_val>\n                            <right_val>-0.1140562966465950</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 4 9 3 -1.</_>\n                                    <_>6 4 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0333646498620510</threshold>\n                            <left_val>-0.4952087998390198</left_val>\n                            <right_val>0.0513284504413605</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 6 6 10 -1.</_>\n                                    <_>6 6 2 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0228276997804642</threshold>\n                            <left_val>0.3255882859230042</left_val>\n                            <right_val>-0.0650893077254295</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 0 8 10 -1.</_>\n                                    <_>13 0 4 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0861990973353386</threshold>\n                            <left_val>-0.6764633059501648</left_val>\n                            <right_val>0.0269856993108988</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 0 8 1 -1.</_>\n                                    <_>12 0 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.1065981127321720e-003</threshold>\n                            <left_val>0.2245243042707443</left_val>\n                            <right_val>-0.1261022984981537</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 2 8 16 -1.</_>\n                                    <_>6 2 4 8 2.</_>\n                                    <_>10 10 4 8 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0391201488673687</threshold>\n                            <left_val>0.1132939979434013</left_val>\n                            <right_val>-0.2686063051223755</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 10 2 10 -1.</_>\n                                    <_>14 10 1 5 2.</_>\n                                    <_>15 15 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.5082739777863026e-003</threshold>\n                            <left_val>-0.1135995984077454</left_val>\n                            <right_val>0.2564977109432221</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 11 1 2 -1.</_>\n                                    <_>12 12 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.9289898490533233e-004</threshold>\n                            <left_val>-0.1494296938180924</left_val>\n                            <right_val>0.1640983968973160</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 3 8 -1.</_>\n                                    <_>17 0 1 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.1766850305721164e-004</threshold>\n                            <left_val>0.0999056920409203</left_val>\n                            <right_val>-0.2196796983480454</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 0 6 10 -1.</_>\n                                    <_>17 0 3 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0218036007136106</threshold>\n                            <left_val>-0.3171172142028809</left_val>\n                            <right_val>0.0828895866870880</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 3 5 -1.</_>\n                                    <_>17 0 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.2962779514491558e-003</threshold>\n                            <left_val>-0.3804872930049896</left_val>\n                            <right_val>0.0608193799853325</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 5 11 2 -1.</_>\n                                    <_>4 6 11 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.4196270387619734e-003</threshold>\n                            <left_val>-0.0960130169987679</left_val>\n                            <right_val>0.2854058146476746</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 2 1 -1.</_>\n                                    <_>2 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.4187481398694217e-004</threshold>\n                            <left_val>0.2212793976068497</left_val>\n                            <right_val>-0.0974349081516266</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 2 3 -1.</_>\n                                    <_>0 1 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.4523929934948683e-003</threshold>\n                            <left_val>0.0375531204044819</left_val>\n                            <right_val>-0.5796905159950256</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 6 6 11 -1.</_>\n                                    <_>13 6 2 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0218346007168293</threshold>\n                            <left_val>0.2956213951110840</left_val>\n                            <right_val>-0.0800483003258705</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 0 3 1 -1.</_>\n                                    <_>15 0 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.1309500152710825e-004</threshold>\n                            <left_val>0.2281450927257538</left_val>\n                            <right_val>-0.1011418998241425</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 7 1 2 -1.</_>\n                                    <_>19 8 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6166249988600612e-003</threshold>\n                            <left_val>-0.5054119825363159</left_val>\n                            <right_val>0.0447645410895348</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 0 3 9 -1.</_>\n                                    <_>18 0 1 9 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5959609821438789e-003</threshold>\n                            <left_val>0.0459865406155586</left_val>\n                            <right_val>-0.4119768142700195</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 7 3 4 -1.</_>\n                                    <_>13 7 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.8601809646934271e-003</threshold>\n                            <left_val>-0.0865631699562073</left_val>\n                            <right_val>0.2480999976396561</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 1 14 2 -1.</_>\n                                    <_>0 1 7 1 2.</_>\n                                    <_>7 2 7 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.0622231103479862e-003</threshold>\n                            <left_val>-0.0755573734641075</left_val>\n                            <right_val>0.2843326032161713</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 1 3 2 -1.</_>\n                                    <_>4 1 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7097420059144497e-003</threshold>\n                            <left_val>-0.3529582023620606</left_val>\n                            <right_val>0.0584104992449284</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 15 2 -1.</_>\n                                    <_>9 0 5 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0165155790746212</threshold>\n                            <left_val>-0.0804869532585144</left_val>\n                            <right_val>0.2353743016719818</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 2 6 1 -1.</_>\n                                    <_>12 2 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.8465100117027760e-003</threshold>\n                            <left_val>0.0418952181935310</left_val>\n                            <right_val>-0.4844304919242859</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 4 6 11 -1.</_>\n                                    <_>11 4 2 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0311671700328588</threshold>\n                            <left_val>0.1919230967760086</left_val>\n                            <right_val>-0.1026815995573998</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 16 2 4 -1.</_>\n                                    <_>2 18 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.1892281519249082e-004</threshold>\n                            <left_val>-0.2108577042818070</left_val>\n                            <right_val>0.0938869267702103</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 6 3 -1.</_>\n                                    <_>8 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0119463102892041</threshold>\n                            <left_val>0.0390961691737175</left_val>\n                            <right_val>-0.6224862933158875</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 9 6 2 -1.</_>\n                                    <_>9 9 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.5677200220525265e-003</threshold>\n                            <left_val>0.1593683958053589</left_val>\n                            <right_val>-0.1225078031420708</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 9 2 -1.</_>\n                                    <_>9 8 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0537474118173122</threshold>\n                            <left_val>-0.5562217831611633</left_val>\n                            <right_val>0.0411900095641613</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 6 2 10 -1.</_>\n                                    <_>6 6 1 5 2.</_>\n                                    <_>7 11 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0155135300010443</threshold>\n                            <left_val>-0.0398268811404705</left_val>\n                            <right_val>0.6240072846412659</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 11 2 3 -1.</_>\n                                    <_>0 12 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.5246650436893106e-003</threshold>\n                            <left_val>0.0701386779546738</left_val>\n                            <right_val>-0.3078907132148743</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 15 4 1 -1.</_>\n                                    <_>13 15 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.8315100139006972e-004</threshold>\n                            <left_val>0.1788765937089920</left_val>\n                            <right_val>-0.1095862016081810</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 1 2 -1.</_>\n                                    <_>6 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.7374739293009043e-003</threshold>\n                            <left_val>0.0274785906076431</left_val>\n                            <right_val>-0.8848956823348999</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 6 20 -1.</_>\n                                    <_>2 0 2 20 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0657877177000046</threshold>\n                            <left_val>-0.4643214046955109</left_val>\n                            <right_val>0.0350371487438679</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 2 2 -1.</_>\n                                    <_>4 10 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.2409730115905404e-003</threshold>\n                            <left_val>-0.0964792370796204</left_val>\n                            <right_val>0.2877922058105469</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 7 3 5 -1.</_>\n                                    <_>5 7 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.1398809561505914e-004</threshold>\n                            <left_val>0.1151171997189522</left_val>\n                            <right_val>-0.1676616072654724</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 12 6 2 -1.</_>\n                                    <_>5 12 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0239018201828003</threshold>\n                            <left_val>-0.0326031893491745</left_val>\n                            <right_val>0.6001734733581543</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 15 7 4 -1.</_>\n                                    <_>6 17 7 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0275566000491381</threshold>\n                            <left_val>-0.0661373436450958</left_val>\n                            <right_val>0.2999447882175446</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 16 2 2 -1.</_>\n                                    <_>17 16 1 1 2.</_>\n                                    <_>18 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8070970913395286e-004</threshold>\n                            <left_val>-0.3388118147850037</left_val>\n                            <right_val>0.0644507706165314</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 1 3 16 -1.</_>\n                                    <_>16 1 1 16 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3335429830476642e-003</threshold>\n                            <left_val>0.1458866000175476</left_val>\n                            <right_val>-0.1321762055158615</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 16 6 3 -1.</_>\n                                    <_>8 16 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.3507990241050720e-003</threshold>\n                            <left_val>-0.5117782950401306</left_val>\n                            <right_val>0.0349694713950157</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 14 3 2 -1.</_>\n                                    <_>15 15 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.6215229928493500e-003</threshold>\n                            <left_val>0.0232495293021202</left_val>\n                            <right_val>-0.6961941123008728</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 16 1 2 -1.</_>\n                                    <_>12 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.3407860832521692e-005</threshold>\n                            <left_val>0.2372737973928452</left_val>\n                            <right_val>-0.0869107097387314</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 2 4 4 -1.</_>\n                                    <_>0 2 2 2 2.</_>\n                                    <_>2 4 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5332329785451293e-003</threshold>\n                            <left_val>0.1922841072082520</left_val>\n                            <right_val>-0.1042239964008331</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 1 6 4 -1.</_>\n                                    <_>1 1 3 2 2.</_>\n                                    <_>4 3 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.3135890737175941e-003</threshold>\n                            <left_val>-0.0962195470929146</left_val>\n                            <right_val>0.2560121119022369</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 18 1 2 -1.</_>\n                                    <_>1 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.3042880638968199e-004</threshold>\n                            <left_val>-0.3156475126743317</left_val>\n                            <right_val>0.0588385984301567</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 7 2 3 -1.</_>\n                                    <_>4 8 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.8411828726530075e-003</threshold>\n                            <left_val>-0.6634092926979065</left_val>\n                            <right_val>0.0245009995996952</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 9 14 -1.</_>\n                                    <_>1 7 9 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1710374057292938</threshold>\n                            <left_val>0.0338314995169640</left_val>\n                            <right_val>-0.4561594128608704</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 9 2 6 -1.</_>\n                                    <_>4 9 1 3 2.</_>\n                                    <_>5 12 1 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6011140542104840e-003</threshold>\n                            <left_val>0.2157489061355591</left_val>\n                            <right_val>-0.0836225301027298</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 9 4 3 -1.</_>\n                                    <_>5 9 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0105357803404331</threshold>\n                            <left_val>0.2455231994390488</left_val>\n                            <right_val>-0.0823844894766808</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 2 4 -1.</_>\n                                    <_>0 11 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.8351638726890087e-003</threshold>\n                            <left_val>-0.4780732989311218</left_val>\n                            <right_val>0.0440862216055393</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 6 3 10 -1.</_>\n                                    <_>17 6 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0187061093747616</threshold>\n                            <left_val>-0.6002402901649475</left_val>\n                            <right_val>0.0214100405573845</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 11 2 1 -1.</_>\n                                    <_>17 11 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.3307439237833023e-004</threshold>\n                            <left_val>0.2432359009981155</left_val>\n                            <right_val>-0.0741657167673111</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.0566600561141968</stage_threshold>\n                <parent>19</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 7 4 4 -1.</_>\n                                    <_>5 9 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0106462296098471</threshold>\n                            <left_val>-0.1386138945817947</left_val>\n                            <right_val>0.2649407088756561</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 11 9 2 -1.</_>\n                                    <_>13 11 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0352982692420483</threshold>\n                            <left_val>-0.0758217275142670</left_val>\n                            <right_val>0.3902106881141663</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 10 2 2 -1.</_>\n                                    <_>15 10 1 1 2.</_>\n                                    <_>16 11 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.5638387352228165e-004</threshold>\n                            <left_val>-0.0955214425921440</left_val>\n                            <right_val>0.2906199991703033</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 6 6 14 -1.</_>\n                                    <_>10 13 6 7 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0924977064132690</threshold>\n                            <left_val>-0.2770423889160156</left_val>\n                            <right_val>0.0794747024774551</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 7 3 5 -1.</_>\n                                    <_>15 7 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9340879991650581e-003</threshold>\n                            <left_val>0.2298953980207443</left_val>\n                            <right_val>-0.0785500109195709</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 11 12 3 -1.</_>\n                                    <_>10 11 4 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0865358486771584</threshold>\n                            <left_val>0.4774481058120728</left_val>\n                            <right_val>-6.8231220357120037e-003</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 16 1 2 -1.</_>\n                                    <_>17 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.4699288739357144e-005</threshold>\n                            <left_val>-0.2264260947704315</left_val>\n                            <right_val>0.0881921127438545</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 5 5 4 -1.</_>\n                                    <_>8 7 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0365925207734108</threshold>\n                            <left_val>0.2735387086868286</left_val>\n                            <right_val>-0.0986067429184914</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 6 4 2 -1.</_>\n                                    <_>11 7 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.6469118893146515e-003</threshold>\n                            <left_val>-0.0440839789807796</left_val>\n                            <right_val>0.3144528865814209</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 4 8 2 -1.</_>\n                                    <_>3 4 4 1 2.</_>\n                                    <_>7 5 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.4271810911595821e-003</threshold>\n                            <left_val>0.2382272928953171</left_val>\n                            <right_val>-0.0867842733860016</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 8 6 6 -1.</_>\n                                    <_>2 8 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.1882481202483177e-003</threshold>\n                            <left_val>0.1504276990890503</left_val>\n                            <right_val>-0.1267210990190506</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 4 6 2 -1.</_>\n                                    <_>7 5 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.5530400238931179e-003</threshold>\n                            <left_val>-0.0559450201690197</left_val>\n                            <right_val>0.3650163114070892</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 3 6 3 -1.</_>\n                                    <_>9 3 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0145624103024602</threshold>\n                            <left_val>0.0363977700471878</left_val>\n                            <right_val>-0.5355919003486633</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 17 3 3 -1.</_>\n                                    <_>2 18 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.8677567469421774e-005</threshold>\n                            <left_val>-0.1747962981462479</left_val>\n                            <right_val>0.1106870993971825</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 10 6 1 -1.</_>\n                                    <_>5 10 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.9744901955127716e-003</threshold>\n                            <left_val>0.3107787072658539</left_val>\n                            <right_val>-0.0665302276611328</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 2 6 2 -1.</_>\n                                    <_>9 2 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.8691250160336494e-003</threshold>\n                            <left_val>-0.3190149068832398</left_val>\n                            <right_val>0.0639318302273750</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 11 9 1 -1.</_>\n                                    <_>7 11 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0111403102055192</threshold>\n                            <left_val>0.2436479032039642</left_val>\n                            <right_val>-0.0809351801872253</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 7 11 12 -1.</_>\n                                    <_>7 13 11 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0586435310542583</threshold>\n                            <left_val>-0.7608326077461243</left_val>\n                            <right_val>0.0308096297085285</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 2 3 4 -1.</_>\n                                    <_>4 2 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.6097282320261002e-003</threshold>\n                            <left_val>-0.4531502127647400</left_val>\n                            <right_val>0.0298790596425533</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 7 9 3 -1.</_>\n                                    <_>12 7 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.3032103031873703e-003</threshold>\n                            <left_val>0.1451337933540344</left_val>\n                            <right_val>-0.1103316992521286</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 11 2 6 -1.</_>\n                                    <_>15 11 1 3 2.</_>\n                                    <_>16 14 1 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3253629440441728e-003</threshold>\n                            <left_val>-0.0976989567279816</left_val>\n                            <right_val>0.1964644044637680</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 5 3 -1.</_>\n                                    <_>0 6 5 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.9800761044025421e-003</threshold>\n                            <left_val>0.0336480811238289</left_val>\n                            <right_val>-0.3979220986366272</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 6 12 -1.</_>\n                                    <_>10 1 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.6542161405086517e-003</threshold>\n                            <left_val>0.0908419936895370</left_val>\n                            <right_val>-0.1596754938364029</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 7 15 13 -1.</_>\n                                    <_>8 7 5 13 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.3892059028148651</threshold>\n                            <left_val>-0.6657109260559082</left_val>\n                            <right_val>0.0190288294106722</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 9 9 -1.</_>\n                                    <_>0 12 9 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1001966968178749</threshold>\n                            <left_val>-0.5755926966667175</left_val>\n                            <right_val>0.0242827795445919</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 3 8 -1.</_>\n                                    <_>17 0 1 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.3541211895644665e-004</threshold>\n                            <left_val>0.0879198014736176</left_val>\n                            <right_val>-0.1619534045457840</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 2 4 2 -1.</_>\n                                    <_>18 2 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.4802639856934547e-003</threshold>\n                            <left_val>0.2606449127197266</left_val>\n                            <right_val>-0.0602008104324341</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 0 6 5 -1.</_>\n                                    <_>16 0 3 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.4000425413250923e-003</threshold>\n                            <left_val>-0.1097972989082336</left_val>\n                            <right_val>0.1570730954408646</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 1 3 2 -1.</_>\n                                    <_>16 1 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.3786011151969433e-003</threshold>\n                            <left_val>0.0360582396388054</left_val>\n                            <right_val>-0.4727719128131867</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 8 3 2 -1.</_>\n                                    <_>12 8 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.3831682093441486e-003</threshold>\n                            <left_val>-0.0357563607394695</left_val>\n                            <right_val>0.4949859082698822</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 8 2 12 -1.</_>\n                                    <_>1 8 1 6 2.</_>\n                                    <_>2 14 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.2115620560944080e-003</threshold>\n                            <left_val>-0.1012556031346321</left_val>\n                            <right_val>0.1574798971414566</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 1 6 12 -1.</_>\n                                    <_>2 1 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0782096683979034</threshold>\n                            <left_val>-0.7662708163261414</left_val>\n                            <right_val>0.0229658298194408</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 17 1 3 -1.</_>\n                                    <_>19 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.3303989261621609e-005</threshold>\n                            <left_val>-0.1341435015201569</left_val>\n                            <right_val>0.1111491993069649</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 3 3 10 -1.</_>\n                                    <_>12 3 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6419155597686768e-003</threshold>\n                            <left_val>0.2506802976131439</left_val>\n                            <right_val>-0.0666081383824348</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 9 8 -1.</_>\n                                    <_>11 1 3 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0710926726460457</threshold>\n                            <left_val>-0.4005681872367859</left_val>\n                            <right_val>0.0402977913618088</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 16 2 2 -1.</_>\n                                    <_>18 16 1 1 2.</_>\n                                    <_>19 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.5171560011804104e-004</threshold>\n                            <left_val>0.0418611802160740</left_val>\n                            <right_val>-0.3296119868755341</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 16 2 2 -1.</_>\n                                    <_>18 16 1 1 2.</_>\n                                    <_>19 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.3458150574006140e-004</threshold>\n                            <left_val>-0.2602983117103577</left_val>\n                            <right_val>0.0678927376866341</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 13 2 6 -1.</_>\n                                    <_>6 15 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.1451421566307545e-003</threshold>\n                            <left_val>0.2396769970655441</left_val>\n                            <right_val>-0.0720933377742767</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 14 2 2 -1.</_>\n                                    <_>9 15 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.1754500232636929e-003</threshold>\n                            <left_val>-0.0712352693080902</left_val>\n                            <right_val>0.2412845045328140</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 10 2 4 -1.</_>\n                                    <_>14 10 1 2 2.</_>\n                                    <_>15 12 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.5184490047395229e-003</threshold>\n                            <left_val>0.5032023787498474</left_val>\n                            <right_val>-0.0296866800636053</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 15 2 2 -1.</_>\n                                    <_>0 15 1 1 2.</_>\n                                    <_>1 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.0242869979701936e-004</threshold>\n                            <left_val>0.2487905025482178</left_val>\n                            <right_val>-0.0567585788667202</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 7 2 2 -1.</_>\n                                    <_>6 7 1 1 2.</_>\n                                    <_>7 8 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3125919504091144e-003</threshold>\n                            <left_val>0.3174780011177063</left_val>\n                            <right_val>-0.0418458618223667</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 18 2 2 -1.</_>\n                                    <_>11 18 1 1 2.</_>\n                                    <_>12 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.7123570907860994e-004</threshold>\n                            <left_val>-0.2704207003116608</left_val>\n                            <right_val>0.0568289905786514</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 6 4 -1.</_>\n                                    <_>0 0 3 2 2.</_>\n                                    <_>3 2 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.3241777718067169e-003</threshold>\n                            <left_val>0.2755667865276337</left_val>\n                            <right_val>-0.0542529709637165</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 6 6 -1.</_>\n                                    <_>6 1 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0168517101556063</threshold>\n                            <left_val>-0.3485291004180908</left_val>\n                            <right_val>0.0453689992427826</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 13 5 4 -1.</_>\n                                    <_>15 15 5 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0299021005630493</threshold>\n                            <left_val>0.0316210798919201</left_val>\n                            <right_val>-0.4311437010765076</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 17 6 1 -1.</_>\n                                    <_>9 17 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.8902660124003887e-003</threshold>\n                            <left_val>0.0380299612879753</left_val>\n                            <right_val>-0.3702709972858429</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 19 4 1 -1.</_>\n                                    <_>18 19 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.9242949783802032e-003</threshold>\n                            <left_val>0.2480027973651886</left_val>\n                            <right_val>-0.0593332983553410</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 16 4 4 -1.</_>\n                                    <_>18 16 2 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.9354149959981441e-003</threshold>\n                            <left_val>-0.0830684006214142</left_val>\n                            <right_val>0.2204380929470062</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 8 9 4 -1.</_>\n                                    <_>10 8 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0820756033062935</threshold>\n                            <left_val>-0.0194134395569563</left_val>\n                            <right_val>0.6908928751945496</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 18 2 2 -1.</_>\n                                    <_>16 18 1 1 2.</_>\n                                    <_>17 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4699489586055279e-004</threshold>\n                            <left_val>-0.2466056942939758</left_val>\n                            <right_val>0.0647764503955841</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 9 2 4 -1.</_>\n                                    <_>2 9 1 2 2.</_>\n                                    <_>3 11 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.8365769647061825e-003</threshold>\n                            <left_val>0.2883616089820862</left_val>\n                            <right_val>-0.0533904582262039</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 3 8 4 -1.</_>\n                                    <_>0 3 4 2 2.</_>\n                                    <_>4 5 4 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.9553811550140381e-003</threshold>\n                            <left_val>0.1274082958698273</left_val>\n                            <right_val>-0.1255941987037659</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 1 8 1 -1.</_>\n                                    <_>4 1 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.3086621016263962e-003</threshold>\n                            <left_val>0.2347811013460159</left_val>\n                            <right_val>-0.0716764926910400</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 8 9 -1.</_>\n                                    <_>4 5 4 9 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1087991967797279</threshold>\n                            <left_val>-0.2599223852157593</left_val>\n                            <right_val>0.0586897395551205</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 18 6 2 -1.</_>\n                                    <_>9 18 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.6786450594663620e-003</threshold>\n                            <left_val>-0.7072042822837830</left_val>\n                            <right_val>0.0187492594122887</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 4 1 12 -1.</_>\n                                    <_>0 8 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0271368306130171</threshold>\n                            <left_val>-0.5838422775268555</left_val>\n                            <right_val>0.0216841306537390</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 13 1 6 -1.</_>\n                                    <_>19 15 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.5389778465032578e-003</threshold>\n                            <left_val>-0.5974891185760498</left_val>\n                            <right_val>0.0214803107082844</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 8 6 8 -1.</_>\n                                    <_>4 8 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0120956301689148</threshold>\n                            <left_val>0.1326903998851776</left_val>\n                            <right_val>-0.0997227206826210</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 9 17 -1.</_>\n                                    <_>3 0 3 17 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1677609980106354</threshold>\n                            <left_val>-0.5665506720542908</left_val>\n                            <right_val>0.0321230888366699</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 9 6 8 -1.</_>\n                                    <_>9 9 2 8 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0132625503465533</threshold>\n                            <left_val>0.1149559020996094</left_val>\n                            <right_val>-0.1173838973045349</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 10 9 4 -1.</_>\n                                    <_>8 10 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0767445191740990</threshold>\n                            <left_val>-0.0314132310450077</left_val>\n                            <right_val>0.5993549227714539</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 0 8 3 -1.</_>\n                                    <_>5 1 8 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0785229541361332e-003</threshold>\n                            <left_val>-0.0529119409620762</left_val>\n                            <right_val>0.2334239929914475</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 6 4 4 -1.</_>\n                                    <_>16 6 2 2 2.</_>\n                                    <_>18 8 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.1800279393792152e-003</threshold>\n                            <left_val>-0.0777343884110451</left_val>\n                            <right_val>0.1765290945768356</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 4 2 8 -1.</_>\n                                    <_>17 4 1 4 2.</_>\n                                    <_>18 8 1 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7729829996824265e-003</threshold>\n                            <left_val>0.1959162950515747</left_val>\n                            <right_val>-0.0797521993517876</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 16 1 3 -1.</_>\n                                    <_>2 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.8560940194875002e-004</threshold>\n                            <left_val>-0.2880037128925324</left_val>\n                            <right_val>0.0490471199154854</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 16 1 3 -1.</_>\n                                    <_>2 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.6554320831783116e-004</threshold>\n                            <left_val>0.0679228976368904</left_val>\n                            <right_val>-0.2249943017959595</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 0 1 3 -1.</_>\n                                    <_>11 1 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6938671362586319e-004</threshold>\n                            <left_val>0.1658217012882233</left_val>\n                            <right_val>-0.0897440984845161</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 2 9 7 -1.</_>\n                                    <_>14 2 3 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0786842331290245</threshold>\n                            <left_val>0.0260816793888807</left_val>\n                            <right_val>-0.5569373965263367</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 2 3 6 -1.</_>\n                                    <_>11 2 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.3774810880422592e-004</threshold>\n                            <left_val>0.1403687000274658</left_val>\n                            <right_val>-0.1180030032992363</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 9 15 2 -1.</_>\n                                    <_>5 10 15 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0239578299224377</threshold>\n                            <left_val>0.0304707400500774</left_val>\n                            <right_val>-0.4615997970104218</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 16 6 2 -1.</_>\n                                    <_>8 17 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6239080578088760e-003</threshold>\n                            <left_val>0.2632707953453064</left_val>\n                            <right_val>-0.0567653700709343</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 16 10 2 -1.</_>\n                                    <_>9 16 5 1 2.</_>\n                                    <_>14 17 5 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.0819748584181070e-004</threshold>\n                            <left_val>0.1546245962381363</left_val>\n                            <right_val>-0.1108706966042519</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 17 2 2 -1.</_>\n                                    <_>9 17 1 1 2.</_>\n                                    <_>10 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.9806248969398439e-004</threshold>\n                            <left_val>0.0556303709745407</left_val>\n                            <right_val>-0.2833195924758911</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 15 6 4 -1.</_>\n                                    <_>10 15 3 2 2.</_>\n                                    <_>13 17 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.0506449509412050e-003</threshold>\n                            <left_val>-0.0916048362851143</left_val>\n                            <right_val>0.1758553981781006</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 5 15 12 -1.</_>\n                                    <_>9 5 5 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0267425496131182</threshold>\n                            <left_val>0.0620030313730240</left_val>\n                            <right_val>-0.2448700070381165</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 13 2 3 -1.</_>\n                                    <_>11 14 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.1497008856385946e-003</threshold>\n                            <left_val>0.2944929897785187</left_val>\n                            <right_val>-0.0532181486487389</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 13 7 3 -1.</_>\n                                    <_>8 14 7 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.6671658530831337e-003</threshold>\n                            <left_val>-0.0642982423305511</left_val>\n                            <right_val>0.2490568011999130</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 12 1 2 -1.</_>\n                                    <_>1 13 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.8317902332637459e-005</threshold>\n                            <left_val>-0.1681963056325913</left_val>\n                            <right_val>0.0965485796332359</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 18 2 2 -1.</_>\n                                    <_>16 18 1 1 2.</_>\n                                    <_>17 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.7600439605303109e-004</threshold>\n                            <left_val>0.0653080120682716</left_val>\n                            <right_val>-0.2426788061857224</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 19 18 1 -1.</_>\n                                    <_>7 19 6 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.1861608624458313e-003</threshold>\n                            <left_val>-0.0979885831475258</left_val>\n                            <right_val>0.1805288940668106</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 17 6 1 -1.</_>\n                                    <_>4 17 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.1808340679854155e-003</threshold>\n                            <left_val>0.1923127025365830</left_val>\n                            <right_val>-0.0941239297389984</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 3 1 12 -1.</_>\n                                    <_>1 9 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0217304006218910</threshold>\n                            <left_val>0.0355785116553307</left_val>\n                            <right_val>-0.4508853852748871</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 3 6 -1.</_>\n                                    <_>0 11 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0147802699357271</threshold>\n                            <left_val>-0.4392701089382172</left_val>\n                            <right_val>0.0317355915904045</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 4 3 10 -1.</_>\n                                    <_>6 4 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.6145891062915325e-003</threshold>\n                            <left_val>0.1981147974729538</left_val>\n                            <right_val>-0.0777014195919037</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 17 2 1 -1.</_>\n                                    <_>7 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.8892709631472826e-003</threshold>\n                            <left_val>0.0199624393135309</left_val>\n                            <right_val>-0.7204172015190125</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 6 12 -1.</_>\n                                    <_>3 0 2 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.3822480104863644e-003</threshold>\n                            <left_val>0.0984669476747513</left_val>\n                            <right_val>-0.1488108038902283</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 7 9 2 -1.</_>\n                                    <_>7 7 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.9505911991000175e-003</threshold>\n                            <left_val>0.1159323006868362</left_val>\n                            <right_val>-0.1279197037220001</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-0.9769343137741089</stage_threshold>\n                <parent>20</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 11 9 1 -1.</_>\n                                    <_>9 11 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0193955395370722</threshold>\n                            <left_val>0.4747475087642670</left_val>\n                            <right_val>-0.1172109022736549</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 10 2 10 -1.</_>\n                                    <_>17 15 2 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0131189199164510</threshold>\n                            <left_val>-0.2555212974548340</left_val>\n                            <right_val>0.1637880057096481</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 10 2 10 -1.</_>\n                                    <_>4 10 1 5 2.</_>\n                                    <_>5 15 1 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.1606801571324468e-004</threshold>\n                            <left_val>0.1945261955261231</left_val>\n                            <right_val>-0.1744889020919800</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 3 3 12 -1.</_>\n                                    <_>13 3 1 12 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0131841599941254</threshold>\n                            <left_val>0.4418145120143890</left_val>\n                            <right_val>-0.0900487527251244</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 3 4 6 -1.</_>\n                                    <_>15 3 2 3 2.</_>\n                                    <_>17 6 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.4657081123441458e-003</threshold>\n                            <left_val>-0.1347709000110626</left_val>\n                            <right_val>0.1805634051561356</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 8 3 3 -1.</_>\n                                    <_>13 8 1 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.2980200164020061e-003</threshold>\n                            <left_val>-0.0541649796068668</left_val>\n                            <right_val>0.3603338003158569</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 14 2 4 -1.</_>\n                                    <_>4 16 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.6879989998415112e-003</threshold>\n                            <left_val>-0.1999794989824295</left_val>\n                            <right_val>0.1202159970998764</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 16 1 3 -1.</_>\n                                    <_>6 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.6039709812030196e-004</threshold>\n                            <left_val>0.1052414029836655</left_val>\n                            <right_val>-0.2411606013774872</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 1 2 3 -1.</_>\n                                    <_>2 1 1 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5276849735528231e-003</threshold>\n                            <left_val>0.2813552916049957</left_val>\n                            <right_val>-0.0689648166298866</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 2 4 1 -1.</_>\n                                    <_>2 2 2 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.5033570602536201e-003</threshold>\n                            <left_val>-0.0825195834040642</left_val>\n                            <right_val>0.4071359038352966</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 17 12 3 -1.</_>\n                                    <_>12 17 4 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.7337161377072334e-003</threshold>\n                            <left_val>0.1972700953483582</left_val>\n                            <right_val>-0.1171014010906220</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 16 6 4 -1.</_>\n                                    <_>11 16 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0115571497008204</threshold>\n                            <left_val>-0.5606111288070679</left_val>\n                            <right_val>0.0681709572672844</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 6 3 6 -1.</_>\n                                    <_>4 9 3 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0274457205086946</threshold>\n                            <left_val>0.4971862137317658</left_val>\n                            <right_val>-0.0623801499605179</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 2 12 9 -1.</_>\n                                    <_>6 5 12 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0528257787227631</threshold>\n                            <left_val>0.1692122071981430</left_val>\n                            <right_val>-0.1309355050325394</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 0 14 20 -1.</_>\n                                    <_>6 0 7 10 2.</_>\n                                    <_>13 10 7 10 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.2984969913959503</threshold>\n                            <left_val>-0.6464967131614685</left_val>\n                            <right_val>0.0400768183171749</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 16 2 2 -1.</_>\n                                    <_>15 16 1 1 2.</_>\n                                    <_>16 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6307269581593573e-004</threshold>\n                            <left_val>0.2512794137001038</left_val>\n                            <right_val>-0.0894948393106461</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 16 2 2 -1.</_>\n                                    <_>15 16 1 1 2.</_>\n                                    <_>16 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.3261709429789335e-004</threshold>\n                            <left_val>-0.0868439897894859</left_val>\n                            <right_val>0.2383197993040085</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 8 1 3 -1.</_>\n                                    <_>19 9 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.3631360090803355e-004</threshold>\n                            <left_val>0.1155446022748947</left_val>\n                            <right_val>-0.1893634945154190</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 4 1 2 -1.</_>\n                                    <_>13 5 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.0742209162563086e-003</threshold>\n                            <left_val>-0.0485948510468006</left_val>\n                            <right_val>0.5748599171638489</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 4 4 2 -1.</_>\n                                    <_>0 5 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.0308889262378216e-003</threshold>\n                            <left_val>-0.5412080883979797</left_val>\n                            <right_val>0.0487437509000301</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 5 1 6 -1.</_>\n                                    <_>19 7 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.2652270793914795e-003</threshold>\n                            <left_val>0.0264945197850466</left_val>\n                            <right_val>-0.6172845959663391</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 0 2 1 -1.</_>\n                                    <_>17 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.0042760297656059e-004</threshold>\n                            <left_val>-0.1176863014698029</left_val>\n                            <right_val>0.1633386015892029</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 1 1 3 -1.</_>\n                                    <_>13 2 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.6470040427520871e-003</threshold>\n                            <left_val>-0.0599549189209938</left_val>\n                            <right_val>0.3517970144748688</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 17 1 3 -1.</_>\n                                    <_>17 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5642538568936288e-004</threshold>\n                            <left_val>-0.3442029953002930</left_val>\n                            <right_val>0.0649482533335686</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 4 8 8 -1.</_>\n                                    <_>5 4 4 4 2.</_>\n                                    <_>9 8 4 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0309358704835176</threshold>\n                            <left_val>0.1997970044612885</left_val>\n                            <right_val>-0.0976936966180801</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 2 2 2 -1.</_>\n                                    <_>1 2 1 1 2.</_>\n                                    <_>2 3 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.3578772824257612e-004</threshold>\n                            <left_val>-0.3148139119148254</left_val>\n                            <right_val>0.0594250410795212</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 0 8 6 -1.</_>\n                                    <_>0 0 4 3 2.</_>\n                                    <_>4 3 4 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0118621801957488</threshold>\n                            <left_val>0.2004369050264359</left_val>\n                            <right_val>-0.0894475430250168</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 3 4 2 -1.</_>\n                                    <_>6 4 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.1508930996060371e-003</threshold>\n                            <left_val>-0.0390060618519783</left_val>\n                            <right_val>0.5332716107368469</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 0 3 3 -1.</_>\n                                    <_>1 1 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.0059191156178713e-003</threshold>\n                            <left_val>-0.2846972048282623</left_val>\n                            <right_val>0.0707236081361771</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 1 7 2 -1.</_>\n                                    <_>6 2 7 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>3.6412389017641544e-003</threshold>\n                            <left_val>-0.1066031977534294</left_val>\n                            <right_val>0.2494480013847351</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 6 12 6 -1.</_>\n                                    <_>6 6 4 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1346742957830429</threshold>\n                            <left_val>0.4991008043289185</left_val>\n                            <right_val>-0.0403322204947472</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 16 9 2 -1.</_>\n                                    <_>4 16 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2547659464180470e-003</threshold>\n                            <left_val>0.1685169041156769</left_val>\n                            <right_val>-0.1111928001046181</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 15 6 4 -1.</_>\n                                    <_>9 15 2 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.3842289596796036e-003</threshold>\n                            <left_val>0.0861394926905632</left_val>\n                            <right_val>-0.2743177115917206</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 15 12 1 -1.</_>\n                                    <_>12 15 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.3361168615520000e-003</threshold>\n                            <left_val>0.2487521022558212</left_val>\n                            <right_val>-0.0959191620349884</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 17 1 3 -1.</_>\n                                    <_>17 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.4666912658140063e-004</threshold>\n                            <left_val>0.0674315765500069</left_val>\n                            <right_val>-0.3375408053398132</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 15 2 2 -1.</_>\n                                    <_>17 15 1 1 2.</_>\n                                    <_>18 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.2983769304119051e-004</threshold>\n                            <left_val>-0.0839030519127846</left_val>\n                            <right_val>0.2458409965038300</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 13 3 3 -1.</_>\n                                    <_>3 14 3 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.7039071582257748e-003</threshold>\n                            <left_val>0.0290793292224407</left_val>\n                            <right_val>-0.6905593872070313</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 17 1 3 -1.</_>\n                                    <_>10 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0734888645820320e-005</threshold>\n                            <left_val>-0.1569671928882599</left_val>\n                            <right_val>0.1196542978286743</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 14 8 -1.</_>\n                                    <_>11 0 7 8 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.2033555954694748</threshold>\n                            <left_val>-0.6950634717941284</left_val>\n                            <right_val>0.0275075193494558</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 12 2 -1.</_>\n                                    <_>6 0 4 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.4939414411783218e-003</threshold>\n                            <left_val>-0.0874493718147278</left_val>\n                            <right_val>0.2396833002567291</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 0 4 3 -1.</_>\n                                    <_>4 0 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.4055240210145712e-003</threshold>\n                            <left_val>0.2115096002817154</left_val>\n                            <right_val>-0.1314893066883087</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 1 1 2 -1.</_>\n                                    <_>13 2 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.1342419747961685e-004</threshold>\n                            <left_val>0.1523378938436508</left_val>\n                            <right_val>-0.1272590011358261</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 5 3 6 -1.</_>\n                                    <_>8 5 1 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0149922100827098</threshold>\n                            <left_val>-0.0341279692947865</left_val>\n                            <right_val>0.5062407255172730</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 2 2 2 -1.</_>\n                                    <_>18 2 1 1 2.</_>\n                                    <_>19 3 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.4068200774490833e-004</threshold>\n                            <left_val>0.0487647503614426</left_val>\n                            <right_val>-0.4022532105445862</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 1 2 14 -1.</_>\n                                    <_>16 1 1 14 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.2459447868168354e-003</threshold>\n                            <left_val>0.2155476063489914</left_val>\n                            <right_val>-0.0871269926428795</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 6 2 2 -1.</_>\n                                    <_>15 6 1 1 2.</_>\n                                    <_>16 7 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>6.8655109498649836e-004</threshold>\n                            <left_val>-0.0754187181591988</left_val>\n                            <right_val>0.2640590965747833</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 1 6 3 -1.</_>\n                                    <_>5 1 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0167514607310295</threshold>\n                            <left_val>-0.6772903203964233</left_val>\n                            <right_val>0.0329187288880348</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 16 2 2 -1.</_>\n                                    <_>7 16 1 1 2.</_>\n                                    <_>8 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6301678735762835e-004</threshold>\n                            <left_val>0.2272586971521378</left_val>\n                            <right_val>-0.0905348733067513</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 17 2 2 -1.</_>\n                                    <_>5 17 1 1 2.</_>\n                                    <_>6 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.3398610432632267e-004</threshold>\n                            <left_val>0.0558943785727024</left_val>\n                            <right_val>-0.3559266924858093</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 10 6 10 -1.</_>\n                                    <_>11 10 2 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0201501492410898</threshold>\n                            <left_val>0.1916276067495346</left_val>\n                            <right_val>-0.0949299708008766</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 17 6 3 -1.</_>\n                                    <_>12 17 2 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0144521296024323</threshold>\n                            <left_val>-0.6851034164428711</left_val>\n                            <right_val>0.0254221707582474</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 5 2 10 -1.</_>\n                                    <_>14 10 2 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0211497396230698</threshold>\n                            <left_val>0.3753319084644318</left_val>\n                            <right_val>-0.0514965802431107</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 12 6 2 -1.</_>\n                                    <_>11 13 6 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0211377702653408</threshold>\n                            <left_val>0.0290830805897713</left_val>\n                            <right_val>-0.8943036794662476</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 1 1 3 -1.</_>\n                                    <_>8 2 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.1524349683895707e-003</threshold>\n                            <left_val>-0.0696949362754822</left_val>\n                            <right_val>0.2729980051517487</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 15 2 2 -1.</_>\n                                    <_>12 15 1 1 2.</_>\n                                    <_>13 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.9070580310653895e-004</threshold>\n                            <left_val>0.1822811961174011</left_val>\n                            <right_val>-0.0983670726418495</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 8 6 4 -1.</_>\n                                    <_>6 8 3 2 2.</_>\n                                    <_>9 10 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0363496318459511</threshold>\n                            <left_val>-0.8369309902191162</left_val>\n                            <right_val>0.0250557605177164</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 5 3 5 -1.</_>\n                                    <_>8 5 1 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.0632075443863869e-003</threshold>\n                            <left_val>0.4146350026130676</left_val>\n                            <right_val>-0.0544134490191936</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 5 7 3 -1.</_>\n                                    <_>0 6 7 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.0535490475594997e-003</threshold>\n                            <left_val>-0.1975031048059464</left_val>\n                            <right_val>0.1050689965486527</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-1.0129359960556030</stage_threshold>\n                <parent>21</parent>\n                <next>-1</next>\n            </_>\n            <_>\n                <trees>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 9 6 6 -1.</_>\n                                    <_>9 9 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0227170195430517</threshold>\n                            <left_val>0.2428855001926422</left_val>\n                            <right_val>-0.1474552005529404</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 7 8 8 -1.</_>\n                                    <_>5 11 8 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0255059506744146</threshold>\n                            <left_val>-0.2855173945426941</left_val>\n                            <right_val>0.1083720996975899</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 9 2 6 -1.</_>\n                                    <_>4 9 1 3 2.</_>\n                                    <_>5 12 1 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.6640091091394424e-003</threshold>\n                            <left_val>0.2927573025226593</left_val>\n                            <right_val>-0.1037271022796631</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 11 6 1 -1.</_>\n                                    <_>12 11 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8115289062261581e-003</threshold>\n                            <left_val>0.2142689973115921</left_val>\n                            <right_val>-0.1381113976240158</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 6 6 11 -1.</_>\n                                    <_>15 6 2 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0167326908558607</threshold>\n                            <left_val>0.2655026018619537</left_val>\n                            <right_val>-0.0439113304018974</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 17 2 2 -1.</_>\n                                    <_>8 17 1 1 2.</_>\n                                    <_>9 18 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.9277010839432478e-004</threshold>\n                            <left_val>0.0211045593023300</left_val>\n                            <right_val>-0.4297136068344116</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 12 12 1 -1.</_>\n                                    <_>8 12 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0366911105811596</threshold>\n                            <left_val>0.5399242043495178</left_val>\n                            <right_val>-0.0436488017439842</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 17 3 2 -1.</_>\n                                    <_>11 18 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.2615970335900784e-003</threshold>\n                            <left_val>-0.1293386965990067</left_val>\n                            <right_val>0.1663877069950104</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 17 6 1 -1.</_>\n                                    <_>10 17 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.4106856957077980e-003</threshold>\n                            <left_val>-0.9469841122627258</left_val>\n                            <right_val>0.0214658491313457</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 1 14 6 -1.</_>\n                                    <_>4 3 14 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0649027228355408</threshold>\n                            <left_val>-0.0717277601361275</left_val>\n                            <right_val>0.2661347985267639</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 2 2 12 -1.</_>\n                                    <_>14 8 2 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0303050000220537</threshold>\n                            <left_val>-0.0827824920415878</left_val>\n                            <right_val>0.2769432067871094</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 13 3 2 -1.</_>\n                                    <_>12 14 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.5875340215861797e-003</threshold>\n                            <left_val>-0.1296616941690445</left_val>\n                            <right_val>0.1775663048028946</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 1 6 1 -1.</_>\n                                    <_>8 1 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.0240451022982597e-003</threshold>\n                            <left_val>-0.6424317955970764</left_val>\n                            <right_val>0.0399432107806206</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 6 6 1 -1.</_>\n                                    <_>12 6 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.0099769569933414e-003</threshold>\n                            <left_val>0.1417661011219025</left_val>\n                            <right_val>-0.1165997013449669</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 19 2 1 -1.</_>\n                                    <_>4 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.1179071558872238e-005</threshold>\n                            <left_val>0.1568766981363297</left_val>\n                            <right_val>-0.1112734004855156</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 16 2 2 -1.</_>\n                                    <_>18 16 1 1 2.</_>\n                                    <_>19 17 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.7293151146732271e-004</threshold>\n                            <left_val>-0.3355455994606018</left_val>\n                            <right_val>0.0459777303040028</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 11 3 7 -1.</_>\n                                    <_>17 11 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.7178079579025507e-003</threshold>\n                            <left_val>0.1695290952920914</left_val>\n                            <right_val>-0.1057806983590126</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 5 1 6 -1.</_>\n                                    <_>19 8 1 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0133331697434187</threshold>\n                            <left_val>-0.5825781226158142</left_val>\n                            <right_val>0.0309784300625324</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 8 4 3 -1.</_>\n                                    <_>9 9 4 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.8783430568873882e-003</threshold>\n                            <left_val>0.1426687985658646</left_val>\n                            <right_val>-0.1113125979900360</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 8 4 4 -1.</_>\n                                    <_>16 8 2 2 2.</_>\n                                    <_>18 10 2 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.5765981562435627e-003</threshold>\n                            <left_val>0.2756136059761047</left_val>\n                            <right_val>-0.0531003288924694</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 8 2 2 -1.</_>\n                                    <_>2 8 1 1 2.</_>\n                                    <_>3 9 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.7210381277836859e-005</threshold>\n                            <left_val>0.1324024051427841</left_val>\n                            <right_val>-0.1116779968142510</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 5 6 4 -1.</_>\n                                    <_>3 5 3 2 2.</_>\n                                    <_>6 7 3 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0219685398042202</threshold>\n                            <left_val>-0.0269681606441736</left_val>\n                            <right_val>0.5006716847419739</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 3 8 16 -1.</_>\n                                    <_>2 3 4 8 2.</_>\n                                    <_>6 11 4 8 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0274457503110170</threshold>\n                            <left_val>-0.2408674061298370</left_val>\n                            <right_val>0.0604782700538635</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 17 1 3 -1.</_>\n                                    <_>17 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.8305849456228316e-005</threshold>\n                            <left_val>-0.1333488970994949</left_val>\n                            <right_val>0.1012346968054771</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 2 8 11 -1.</_>\n                                    <_>11 2 4 11 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0701906830072403</threshold>\n                            <left_val>-0.0548637807369232</left_val>\n                            <right_val>0.2480994015932083</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 3 6 14 -1.</_>\n                                    <_>16 3 3 14 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0719021335244179</threshold>\n                            <left_val>-0.3784669041633606</left_val>\n                            <right_val>0.0422109998762608</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 18 2 -1.</_>\n                                    <_>6 9 6 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1078097969293594</threshold>\n                            <left_val>-0.3748658895492554</left_val>\n                            <right_val>0.0428334400057793</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 10 14 3 -1.</_>\n                                    <_>6 11 14 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.4364200178533792e-003</threshold>\n                            <left_val>0.0804763585329056</left_val>\n                            <right_val>-0.1726378947496414</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 9 9 3 -1.</_>\n                                    <_>13 9 3 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0682891905307770</threshold>\n                            <left_val>-0.0355957895517349</left_val>\n                            <right_val>0.4076131880283356</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 5 4 6 -1.</_>\n                                    <_>3 5 2 3 2.</_>\n                                    <_>5 8 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.8037179298698902e-003</threshold>\n                            <left_val>0.1923379004001617</left_val>\n                            <right_val>-0.0823680236935616</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 7 3 7 -1.</_>\n                                    <_>4 7 1 7 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.6193489581346512e-004</threshold>\n                            <left_val>0.1305712014436722</left_val>\n                            <right_val>-0.1435514986515045</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 8 11 6 -1.</_>\n                                    <_>2 10 11 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0582766495645046</threshold>\n                            <left_val>-0.3012543916702271</left_val>\n                            <right_val>0.0528196506202221</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 9 6 3 -1.</_>\n                                    <_>8 10 6 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.1205718666315079e-003</threshold>\n                            <left_val>0.2204390019178391</left_val>\n                            <right_val>-0.0756917521357536</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 3 3 11 -1.</_>\n                                    <_>4 3 1 11 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0135943097993732</threshold>\n                            <left_val>-0.3904936015605927</left_val>\n                            <right_val>0.0418571084737778</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 19 6 1 -1.</_>\n                                    <_>3 19 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.3626200379803777e-003</threshold>\n                            <left_val>-0.0953634232282639</left_val>\n                            <right_val>0.1497032046318054</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 18 1 2 -1.</_>\n                                    <_>18 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.5074219845701009e-004</threshold>\n                            <left_val>-0.2394558042287827</left_val>\n                            <right_val>0.0647983327507973</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 0 12 6 -1.</_>\n                                    <_>8 0 6 3 2.</_>\n                                    <_>14 3 6 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0774142593145370</threshold>\n                            <left_val>0.5594198107719421</left_val>\n                            <right_val>-0.0245168805122375</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 5 1 3 -1.</_>\n                                    <_>19 6 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.2117872554808855e-004</threshold>\n                            <left_val>0.0549288615584373</left_val>\n                            <right_val>-0.2793481051921845</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>5 8 2 1 -1.</_>\n                                    <_>6 8 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.0250780032947659e-003</threshold>\n                            <left_val>-0.0621673092246056</left_val>\n                            <right_val>0.2497636973857880</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 11 2 1 -1.</_>\n                                    <_>14 11 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-8.1174750812351704e-004</threshold>\n                            <left_val>0.2343793958425522</left_val>\n                            <right_val>-0.0657258108258247</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 6 15 13 -1.</_>\n                                    <_>8 6 5 13 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0834310203790665</threshold>\n                            <left_val>0.0509548000991344</left_val>\n                            <right_val>-0.3102098107337952</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 3 6 2 -1.</_>\n                                    <_>6 3 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-9.2014456167817116e-003</threshold>\n                            <left_val>-0.3924253880977631</left_val>\n                            <right_val>0.0329269506037235</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 18 1 2 -1.</_>\n                                    <_>0 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9086650465615094e-004</threshold>\n                            <left_val>-0.3103975057601929</left_val>\n                            <right_val>0.0497118197381496</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 8 2 6 -1.</_>\n                                    <_>8 8 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.7576898038387299e-003</threshold>\n                            <left_val>-0.0440407507121563</left_val>\n                            <right_val>0.3643135130405426</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 0 6 19 -1.</_>\n                                    <_>5 0 2 19 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.1246609017252922</threshold>\n                            <left_val>-0.8195707798004150</left_val>\n                            <right_val>0.0191506408154964</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>3 1 6 5 -1.</_>\n                                    <_>5 1 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0132425501942635</threshold>\n                            <left_val>0.0389888398349285</left_val>\n                            <right_val>-0.3323068022727966</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 14 3 6 -1.</_>\n                                    <_>17 16 3 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.6770128905773163e-003</threshold>\n                            <left_val>-0.3579013943672180</left_val>\n                            <right_val>0.0404602102935314</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 13 2 6 -1.</_>\n                                    <_>18 13 1 6 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.7479929849505424e-003</threshold>\n                            <left_val>0.2525390088558197</left_val>\n                            <right_val>-0.0564278215169907</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 18 2 2 -1.</_>\n                                    <_>18 18 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>8.2659651525318623e-004</threshold>\n                            <left_val>-0.0719886571168900</left_val>\n                            <right_val>0.2278047949075699</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 14 9 4 -1.</_>\n                                    <_>14 14 3 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0501534007489681</threshold>\n                            <left_val>-0.6303647160530090</left_val>\n                            <right_val>0.0274620503187180</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 8 4 6 -1.</_>\n                                    <_>15 8 2 3 2.</_>\n                                    <_>17 11 2 3 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>7.4203149415552616e-003</threshold>\n                            <left_val>-0.0666107162833214</left_val>\n                            <right_val>0.2778733968734741</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 16 1 3 -1.</_>\n                                    <_>1 17 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.7951780511066318e-004</threshold>\n                            <left_val>-0.3632706105709076</left_val>\n                            <right_val>0.0427954308688641</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 0 3 14 -1.</_>\n                                    <_>8 0 1 14 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.9305750029161572e-003</threshold>\n                            <left_val>0.1419623047113419</left_val>\n                            <right_val>-0.1075998023152351</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 0 2 1 -1.</_>\n                                    <_>13 0 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.8132671033963561e-004</threshold>\n                            <left_val>0.2159176021814346</left_val>\n                            <right_val>-0.0702026635408401</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 9 6 5 -1.</_>\n                                    <_>10 9 3 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0709903463721275</threshold>\n                            <left_val>0.4526660144329071</left_val>\n                            <right_val>-0.0407504811882973</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 5 4 9 -1.</_>\n                                    <_>17 5 2 9 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0533680804073811</threshold>\n                            <left_val>-0.6767405867576599</left_val>\n                            <right_val>0.0192883405834436</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 0 6 6 -1.</_>\n                                    <_>13 0 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0200648494064808</threshold>\n                            <left_val>-0.4336543083190918</left_val>\n                            <right_val>0.0318532884120941</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 15 2 2 -1.</_>\n                                    <_>16 15 1 1 2.</_>\n                                    <_>17 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.1976360110566020e-003</threshold>\n                            <left_val>-0.0265598706901073</left_val>\n                            <right_val>0.5079718232154846</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 15 2 2 -1.</_>\n                                    <_>16 15 1 1 2.</_>\n                                    <_>17 16 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2697300300933421e-004</threshold>\n                            <left_val>0.1801259964704514</left_val>\n                            <right_val>-0.0836065486073494</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>13 2 2 18 -1.</_>\n                                    <_>13 11 2 9 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.0152626996859908</threshold>\n                            <left_val>-0.2023892998695374</left_val>\n                            <right_val>0.0674220174551010</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 4 8 10 -1.</_>\n                                    <_>8 9 8 5 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.2081176936626434</threshold>\n                            <left_val>0.6694386005401611</left_val>\n                            <right_val>-0.0224521104246378</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 3 2 3 -1.</_>\n                                    <_>8 4 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>1.5514369588345289e-003</threshold>\n                            <left_val>-0.0751218423247337</left_val>\n                            <right_val>0.1732691973447800</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 1 6 9 -1.</_>\n                                    <_>11 4 6 3 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0529240109026432</threshold>\n                            <left_val>0.2499251961708069</left_val>\n                            <right_val>-0.0628791674971581</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>15 4 5 6 -1.</_>\n                                    <_>15 6 5 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0216488502919674</threshold>\n                            <left_val>-0.2919428050518036</left_val>\n                            <right_val>0.0526144914329052</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 18 2 2 -1.</_>\n                                    <_>12 18 1 1 2.</_>\n                                    <_>13 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2905069636180997e-004</threshold>\n                            <left_val>-0.2211730033159256</left_val>\n                            <right_val>0.0631683394312859</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 17 1 3 -1.</_>\n                                    <_>1 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.0170070608146489e-005</threshold>\n                            <left_val>-0.1151070967316628</left_val>\n                            <right_val>0.1161144003272057</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 19 2 1 -1.</_>\n                                    <_>13 19 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-1.6416069411206990e-004</threshold>\n                            <left_val>0.1587152034044266</left_val>\n                            <right_val>-0.0826006010174751</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>8 10 6 6 -1.</_>\n                                    <_>10 10 2 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0120032895356417</threshold>\n                            <left_val>0.1221809014678001</left_val>\n                            <right_val>-0.1122969985008240</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 2 6 5 -1.</_>\n                                    <_>16 2 2 5 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0177841000258923</threshold>\n                            <left_val>-0.3507278859615326</left_val>\n                            <right_val>0.0313419215381145</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 5 2 6 -1.</_>\n                                    <_>9 7 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-6.3457582145929337e-003</threshold>\n                            <left_val>0.1307806968688965</left_val>\n                            <right_val>-0.1057441011071205</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 15 2 2 -1.</_>\n                                    <_>2 15 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.9523242311552167e-004</threshold>\n                            <left_val>0.1720467060804367</left_val>\n                            <right_val>-0.0860019922256470</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 17 1 3 -1.</_>\n                                    <_>18 18 1 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.1029590172693133e-004</threshold>\n                            <left_val>-0.2843317091464996</left_val>\n                            <right_val>0.0518171191215515</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>10 14 4 6 -1.</_>\n                                    <_>10 16 4 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0170537102967501</threshold>\n                            <left_val>0.3924242854118347</left_val>\n                            <right_val>-0.0401432700455189</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 7 3 2 -1.</_>\n                                    <_>10 7 1 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.6504959464073181e-003</threshold>\n                            <left_val>-0.0318375602364540</left_val>\n                            <right_val>0.4123769998550415</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 9 6 2 -1.</_>\n                                    <_>6 9 3 1 2.</_>\n                                    <_>9 10 3 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0103587601333857</threshold>\n                            <left_val>-0.5699319839477539</left_val>\n                            <right_val>0.0292483791708946</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 2 1 12 -1.</_>\n                                    <_>0 6 1 4 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0221962407231331</threshold>\n                            <left_val>-0.4560528993606567</left_val>\n                            <right_val>0.0262859892100096</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 0 15 1 -1.</_>\n                                    <_>9 0 5 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-7.0536029525101185e-003</threshold>\n                            <left_val>0.1599832028150559</left_val>\n                            <right_val>-0.0915948599576950</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>9 0 8 2 -1.</_>\n                                    <_>9 0 4 1 2.</_>\n                                    <_>13 1 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-5.7094299700111151e-004</threshold>\n                            <left_val>-0.1407632976770401</left_val>\n                            <right_val>0.1028741970658302</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>12 2 8 1 -1.</_>\n                                    <_>16 2 4 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.2152599412947893e-003</threshold>\n                            <left_val>0.1659359931945801</left_val>\n                            <right_val>-0.0852739885449409</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>7 1 10 6 -1.</_>\n                                    <_>7 3 10 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0280848909169436</threshold>\n                            <left_val>0.2702234089374542</left_val>\n                            <right_val>-0.0558738112449646</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>18 6 2 3 -1.</_>\n                                    <_>18 7 2 1 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.1515151020139456e-003</threshold>\n                            <left_val>0.0424728915095329</left_val>\n                            <right_val>-0.3200584948062897</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>4 12 2 2 -1.</_>\n                                    <_>4 12 1 1 2.</_>\n                                    <_>5 13 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-2.9733829433098435e-004</threshold>\n                            <left_val>0.1617716997861862</left_val>\n                            <right_val>-0.0851155892014503</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 6 6 2 -1.</_>\n                                    <_>8 6 2 2 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0166947804391384</threshold>\n                            <left_val>-0.4285877048969269</left_val>\n                            <right_val>0.0305416099727154</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>0 9 9 6 -1.</_>\n                                    <_>3 9 3 6 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.1198299005627632</threshold>\n                            <left_val>-0.0162772908806801</left_val>\n                            <right_val>0.7984678149223328</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>17 18 2 2 -1.</_>\n                                    <_>18 18 1 2 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-3.5499420482665300e-004</threshold>\n                            <left_val>0.1593593955039978</left_val>\n                            <right_val>-0.0832728818058968</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>11 2 6 16 -1.</_>\n                                    <_>13 2 2 16 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0182262696325779</threshold>\n                            <left_val>0.1952728033065796</left_val>\n                            <right_val>-0.0739398896694183</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 4 15 13 -1.</_>\n                                    <_>7 4 5 13 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-4.0238600922748446e-004</threshold>\n                            <left_val>0.0791018083691597</left_val>\n                            <right_val>-0.2080612927675247</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>16 2 3 10 -1.</_>\n                                    <_>17 2 1 10 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>4.0892060496844351e-004</threshold>\n                            <left_val>0.1003663018345833</left_val>\n                            <right_val>-0.1512821018695831</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>6 10 2 1 -1.</_>\n                                    <_>7 10 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>9.5368112670257688e-004</threshold>\n                            <left_val>-0.0730116665363312</left_val>\n                            <right_val>0.2175202071666718</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>1 1 18 16 -1.</_>\n                                    <_>10 1 9 16 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>0.4308179914951325</threshold>\n                            <left_val>-0.0274506993591785</left_val>\n                            <right_val>0.5706158280372620</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>14 4 3 15 -1.</_>\n                                    <_>15 4 1 15 3.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>5.3564831614494324e-004</threshold>\n                            <left_val>0.1158754006028175</left_val>\n                            <right_val>-0.1279056072235107</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>19 13 1 2 -1.</_>\n                                    <_>19 14 1 1 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>2.4430730263702571e-005</threshold>\n                            <left_val>-0.1681662946939468</left_val>\n                            <right_val>0.0804499834775925</right_val>\n                        </_>\n                    </_>\n                    <_>\n                        <_>\n                            <feature>\n                                <rects>\n                                    <_>2 6 5 8 -1.</_>\n                                    <_>2 10 5 4 2.</_>\n                                </rects>\n                                <tilted>0</tilted>\n                            </feature>\n                            <threshold>-0.0553456507623196</threshold>\n                            <left_val>0.4533894956111908</left_val>\n                            <right_val>-0.0312227793037891</right_val>\n                        </_>\n                    </_>\n                </trees>\n                <stage_threshold>-0.9774749279022217</stage_threshold>\n                <parent>22</parent>\n                <next>-1</next>\n            </_>\n        </stages>\n    </haarcascade_frontaleye>\n</opencv_storage>"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/auto_straight/AutoStraighten.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.auto_straight\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.geometry.Offset\nimport com.t8rin.opencv_tools.auto_straight.model.Corners\nimport com.t8rin.opencv_tools.auto_straight.model.StraightenMode\nimport com.t8rin.opencv_tools.free_corners_crop.FreeCrop\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Core\nimport org.opencv.core.Mat\nimport org.opencv.core.MatOfPoint\nimport org.opencv.core.MatOfPoint2f\nimport org.opencv.core.Point\nimport org.opencv.core.Rect\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\nimport org.opencv.photo.Photo\nimport kotlin.math.abs\nimport kotlin.math.atan2\nimport kotlin.math.cos\nimport kotlin.math.pow\nimport kotlin.math.sin\nimport kotlin.math.sqrt\n\nobject AutoStraighten : OpenCV() {\n\n    fun process(\n        input: Bitmap,\n        mode: StraightenMode\n    ): Bitmap = when (mode) {\n        is StraightenMode.Perspective -> autoPerspective(input = input)\n\n        is StraightenMode.Deskew -> autoDeskew(\n            input = input,\n            maxSkew = mode.maxSkew,\n            allowCrop = mode.allowCrop\n        )\n\n        is StraightenMode.Manual -> perspectiveFromPoints(input = input, corners = mode.corners)\n    }\n\n    private fun autoDeskew(input: Bitmap, maxSkew: Int, allowCrop: Boolean): Bitmap {\n        val srcMat = input.toMat()\n        val gray = Mat()\n        Imgproc.cvtColor(srcMat, gray, Imgproc.COLOR_BGR2GRAY)\n        Photo.fastNlMeansDenoising(gray, gray, 3f)\n\n        val binary = Mat()\n        Imgproc.threshold(\n            gray, binary, 0.0, 255.0,\n            Imgproc.THRESH_BINARY_INV or Imgproc.THRESH_OTSU\n        )\n\n        val lines = Mat()\n        Imgproc.HoughLinesP(\n            binary,\n            lines,\n            1.0,\n            Math.PI / 180,\n            200,\n            srcMat.width() / 12.0,\n            srcMat.width() / 150.0\n        )\n\n        if (lines.rows() == 0) return input\n\n        val angles = mutableListOf<Double>()\n        for (i in 0 until lines.rows()) {\n            val l = lines.get(i, 0)\n            val x1 = l[0]\n            val y1 = l[1]\n            val x2 = l[2]\n            val y2 = l[3]\n            angles += atan2(y2 - y1, x2 - x1)\n        }\n\n        val landscape = angles.count { abs(it) > Math.PI / 4 } > angles.size / 2\n\n        val filtered = if (landscape) {\n            angles.filter {\n                val deg = abs(Math.toDegrees(it))\n                deg > (90 - maxSkew) && deg < (90 + maxSkew)\n            }\n        } else {\n            angles.filter { abs(Math.toDegrees(it)) < maxSkew }\n        }\n\n        if (filtered.size < 5) return input\n\n        var angleDeg = Math.toDegrees(filtered.median())\n\n        val rotated = Mat()\n\n        if (landscape) {\n            angleDeg = if (angleDeg < 0) {\n                Core.rotate(srcMat, rotated, Core.ROTATE_90_CLOCKWISE)\n                angleDeg + 90\n            } else {\n                Core.rotate(srcMat, rotated, Core.ROTATE_90_COUNTERCLOCKWISE)\n                angleDeg - 90\n            }\n        } else {\n            srcMat.copyTo(rotated)\n        }\n\n        val center = Point(rotated.width() / 2.0, rotated.height() / 2.0)\n        val rotMat = Imgproc.getRotationMatrix2D(center, angleDeg, 1.0)\n\n        val angleRad = Math.toRadians(angleDeg)\n        val absSin = abs(sin(angleRad))\n        val absCos = abs(cos(angleRad))\n        val newWidth = (rotated.height() * absSin + rotated.width() * absCos).toInt()\n        val newHeight = (rotated.height() * absCos + rotated.width() * absSin).toInt()\n\n        rotMat.put(0, 2, rotMat.get(0, 2)[0] + (newWidth / 2.0 - center.x))\n        rotMat.put(1, 2, rotMat.get(1, 2)[0] + (newHeight / 2.0 - center.y))\n\n        val rotatedFull = Mat()\n        Imgproc.warpAffine(\n            rotated,\n            rotatedFull,\n            rotMat,\n            Size(newWidth.toDouble(), newHeight.toDouble()),\n            Imgproc.INTER_LINEAR,\n            Core.BORDER_REPLICATE,\n        )\n\n        return if (allowCrop) {\n            val cropRect = getLargestRotatedRect(\n                width = rotated.width(),\n                height = rotated.height(),\n                angle = angleRad\n            )\n\n            Mat(rotatedFull, cropRect).clone()\n        } else {\n            rotatedFull\n        }.toBitmap()\n    }\n\n    private fun autoPerspective(input: Bitmap): Bitmap {\n        val srcMat = input.toMat()\n        val gray = Mat()\n        Imgproc.cvtColor(srcMat, gray, Imgproc.COLOR_BGR2GRAY)\n        Photo.fastNlMeansDenoising(gray, gray, 3f)\n\n        val binary = Mat()\n        Imgproc.threshold(\n            gray, binary, 0.0, 255.0,\n            Imgproc.THRESH_BINARY or Imgproc.THRESH_OTSU\n        )\n\n        val contours = mutableListOf<MatOfPoint>()\n        Imgproc.findContours(\n            binary.clone(),\n            contours,\n            Mat(),\n            Imgproc.RETR_EXTERNAL,\n            Imgproc.CHAIN_APPROX_SIMPLE\n        )\n\n        val biggest = contours\n            .mapNotNull { contour ->\n                val approx = MatOfPoint2f()\n                val c2f = MatOfPoint2f(*contour.toArray())\n                Imgproc.approxPolyDP(c2f, approx, Imgproc.arcLength(c2f, true) * 0.02, true)\n                if (approx.total() == 4L && Imgproc.isContourConvex(MatOfPoint(*approx.toArray())))\n                    approx\n                else null\n            }\n            .maxByOrNull { Imgproc.contourArea(MatOfPoint(*it.toArray())) }\n            ?: return input\n\n        val sorted = sortCorners(biggest.toArray())\n        val widthA = distance(sorted[0], sorted[1])\n        val widthB = distance(sorted[2], sorted[3])\n        val maxWidth = maxOf(widthA, widthB).toInt()\n\n        val heightA = distance(sorted[0], sorted[3])\n        val heightB = distance(sorted[1], sorted[2])\n        val maxHeight = maxOf(heightA, heightB).toInt()\n\n        val dst = MatOfPoint2f(\n            Point(0.0, 0.0),\n            Point(maxWidth.toDouble(), 0.0),\n            Point(maxWidth.toDouble(), maxHeight.toDouble()),\n            Point(0.0, maxHeight.toDouble())\n        )\n\n        val transform = Imgproc.getPerspectiveTransform(MatOfPoint2f(*sorted), dst)\n        val out = Mat()\n        Imgproc.warpPerspective(\n            srcMat,\n            out,\n            transform,\n            Size(maxWidth.toDouble(), maxHeight.toDouble())\n        )\n\n        return out.toBitmap()\n    }\n\n    private fun perspectiveFromPoints(input: Bitmap, corners: Corners): Bitmap {\n        val width = input.width\n        val height = input.height\n\n        val absPoints = if (corners.isAbsolute) {\n            corners.points.map {\n                Offset(\n                    x = it.x.toFloat(),\n                    y = it.y.toFloat()\n                )\n            }\n        } else {\n            corners.points.map {\n                Offset(\n                    x = (it.x * width).toFloat(),\n                    y = (it.y * height).toFloat()\n                )\n            }\n        }\n\n        return FreeCrop.crop(\n            bitmap = input,\n            points = absPoints\n        )\n    }\n\n    private fun sortCorners(pts: Array<Point>): Array<Point> {\n        val sum = pts.sortedBy { it.y + it.x }\n        val diff = pts.sortedBy { it.y - it.x }\n        return arrayOf(\n            sum.first(),\n            diff.first(),\n            sum.last(),\n            diff.last()\n        )\n    }\n\n    private fun distance(p1: Point, p2: Point): Double =\n        sqrt((p1.x - p2.x).pow(2.0) + (p1.y - p2.y).pow(2.0))\n\n    private fun getLargestRotatedRect(width: Int, height: Int, angle: Double): Rect {\n        val absSin = abs(sin(angle))\n        val absCos = abs(cos(angle))\n\n        val boundWidth = (width * absCos - height * absSin).coerceAtLeast(0.0)\n        val boundHeight = (height * absCos - width * absSin).coerceAtLeast(0.0)\n\n        val newWidth = (height * absSin + width * absCos)\n        val newHeight = (height * absCos + width * absSin)\n\n        val x = ((newWidth - boundWidth) / 2.0).toInt()\n        val y = ((newHeight - boundHeight) / 2.0).toInt()\n\n        return Rect(x, y, boundWidth.toInt(), boundHeight.toInt())\n    }\n\n    private fun List<Double>.median(): Double {\n        if (isEmpty()) return 0.0\n        val sorted = this.sorted()\n        return if (size % 2 == 0)\n            (sorted[size / 2 - 1] + sorted[size / 2]) / 2\n        else\n            sorted[size / 2]\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/auto_straight/model/Corners.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.auto_straight.model\n\ndata class Corners(\n    val topLeft: PointD,\n    val topRight: PointD,\n    val bottomRight: PointD,\n    val bottomLeft: PointD,\n    val isAbsolute: Boolean = true\n) {\n    val points = listOf(topLeft, topRight, bottomRight, bottomLeft)\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/auto_straight/model/PointD.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.auto_straight.model\n\ndata class PointD(val x: Double, val y: Double)"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/auto_straight/model/StraightenMode.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.auto_straight.model\n\nimport androidx.annotation.IntRange\n\nsealed class StraightenMode {\n    data object Perspective : StraightenMode()\n\n    data class Deskew(\n        @param:IntRange(0, 90) val maxSkew: Int = 10,\n        val allowCrop: Boolean = true\n    ) : StraightenMode()\n\n    data class Manual(val corners: Corners) : StraightenMode()\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/autocrop/AutoCropper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.autocrop\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.autocrop.model.CropEdges\nimport com.t8rin.opencv_tools.autocrop.model.CropParameters\nimport com.t8rin.opencv_tools.autocrop.model.CropSensitivity\nimport com.t8rin.opencv_tools.autocrop.model.edgeCandidateThreshold\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.multiChannelMean\nimport com.t8rin.opencv_tools.utils.singleChannelMean\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.CvType\nimport org.opencv.core.Mat\nimport org.opencv.imgproc.Imgproc\n\n\nobject AutoCropper : OpenCV() {\n\n    fun crop(\n        bitmap: Bitmap,\n        @CropSensitivity sensitivity: Int\n    ): Bitmap? = bitmap.findEdges(sensitivity)?.run {\n        bitmap.cropByEdges(edges)\n    }\n\n    private fun Bitmap.cropByEdges(\n        edges: CropEdges\n    ): Bitmap = Bitmap.createBitmap(\n        this,\n        0,\n        edges.top + 1,\n        width,\n        edges.height - 1\n    )\n\n    private fun Bitmap.findEdges(\n        @CropSensitivity sensitivity: Int\n    ): CropParameters? {\n        val matRGBA = toMat()\n        return getEdgeCandidates(matRGBA, sensitivity)?.let {\n            CropParameters(\n                edges = getMaxScoreCropEdges(candidates = it, matRGBA = matRGBA),\n                candidates = it\n            )\n        }\n    }\n\n    private fun getEdgeCandidates(matRGBA: Mat, @CropSensitivity sensitivity: Int): List<Int>? {\n        // Convert to gray scale\n        val matGrayScale = Mat()\n        Imgproc.cvtColor(matRGBA, matGrayScale, Imgproc.COLOR_RGBA2GRAY)\n        Imgproc.medianBlur(matGrayScale, matGrayScale, 3)\n\n        // Get canny edge detected matrix\n        val matCanny = Mat()\n        Imgproc.Canny(matGrayScale, matCanny, 100.0, 200.0)\n\n        // Convert sensitivity to threshold\n        val threshold = edgeCandidateThreshold(sensitivity)\n\n        return (0 until matCanny.rows()).filter { i ->\n            matCanny.row(i).singleChannelMean() > threshold\n        }\n            .run {\n                if (isEmpty())\n                    null\n                else\n                    listOf(0) + this + listOf(matCanny.rows())\n            }\n    }\n\n    private fun getMaxScoreCropEdges(candidates: List<Int>, matRGBA: Mat): CropEdges {\n        val matSobel = Mat()\n        Imgproc.Sobel(matRGBA, matSobel, CvType.CV_16U, 2, 2, 5)\n\n        var maxScore = 0f\n        var maxScoreEdges: CropEdges? = null\n\n        candidates.windowed(2)\n            .map { CropEdges(it) }\n            .forEach { edges ->\n                val cropAreaMean: Float =\n                    matSobel.rowRange(edges.top, edges.bottom).multiChannelMean().toFloat()\n                val heightPortion: Float = edges.height.toFloat() / matSobel.rows().toFloat()\n                val score: Float = cropAreaMean * heightPortion\n\n                if (score > maxScore) {\n                    maxScore = score\n                    maxScoreEdges = edges\n                }\n            }\n\n        return maxScoreEdges!!\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/autocrop/model/CropEdges.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.autocrop.model\n\nimport android.os.Parcelable\nimport kotlinx.parcelize.Parcelize\n\n@Parcelize\ndata class CropEdges(val top: Int, val bottom: Int) : Parcelable {\n\n    constructor(edges: Pair<Int, Int>) : this(edges.first, edges.second)\n\n    constructor(edges: List<Int>) : this(edges.first(), edges.last())\n\n    val height: Int\n        get() = bottom - top\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/autocrop/model/CropParameters.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.autocrop.model\n\ndata class CropParameters(\n    val edges: CropEdges,\n    val candidates: List<Int>\n)"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/autocrop/model/CropSensitivity.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.autocrop.model\n\nimport androidx.annotation.IntRange\n\n/**\n * := (255 - [EDGE_CANDIDATE_THRESHOLD_MIN]) / [CROP_SENSITIVITY_MAX]\n */\nprivate const val EDGE_CANDIDATE_THRESHOLD_PER_SENSITIVITY_STEP: Float = 20.5f\nprivate const val EDGE_CANDIDATE_THRESHOLD_MIN: Int = 50\nprivate const val CROP_SENSITIVITY_MAX: Int = 10\n\n@Retention(AnnotationRetention.BINARY)\n@IntRange(from = 0, to = CROP_SENSITIVITY_MAX.toLong())\nannotation class CropSensitivity\n\n@IntRange(50, 255)\ninternal fun edgeCandidateThreshold(@CropSensitivity cropSensitivity: Int): Int =\n    ((CROP_SENSITIVITY_MAX - cropSensitivity) * EDGE_CANDIDATE_THRESHOLD_PER_SENSITIVITY_STEP).toInt() + EDGE_CANDIDATE_THRESHOLD_MIN"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/color_map/ColorMap.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.color_map\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.color_map.model.ColorMapType\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Mat\nimport org.opencv.imgproc.Imgproc\n\nobject ColorMap : OpenCV() {\n\n    fun apply(\n        bitmap: Bitmap,\n        map: ColorMapType = ColorMapType.JET\n    ): Bitmap {\n        val grayMat = bitmap.toMat()\n\n        Imgproc.cvtColor(grayMat, grayMat, Imgproc.COLOR_RGBA2BGR)\n        Imgproc.cvtColor(grayMat, grayMat, Imgproc.COLOR_BGR2GRAY)\n\n        val colorMat = Mat()\n\n        Imgproc.applyColorMap(grayMat, colorMat, map.ordinal)\n\n        Imgproc.cvtColor(colorMat, colorMat, Imgproc.COLOR_BGR2RGBA)\n\n        grayMat.release()\n        return colorMat.toBitmap()\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/color_map/model/ColorMapType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.color_map.model\n\nenum class ColorMapType {\n    AUTUMN,\n    BONE,\n    JET,\n    WINTER,\n    RAINBOW,\n    OCEAN,\n    SUMMER,\n    SPRING,\n    COOL,\n    HSV,\n    PINK,\n    HOT,\n    PARULA,\n    MAGMA,\n    INFERNO,\n    PLASMA,\n    VIRIDIS,\n    CIVIDIS,\n    TWILIGHT,\n    TWILIGHT_SHIFTED,\n    TURBO,\n    DEEPGREEN\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/document_detector/DocumentDetector.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.document_detector\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Core\nimport org.opencv.core.CvType\nimport org.opencv.core.Mat\nimport org.opencv.core.MatOfPoint\nimport org.opencv.core.MatOfPoint2f\nimport org.opencv.core.Point\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\n\n/**\n * This class uses OpenCV to find document corners.\n *\n * @constructor creates document detector\n */\nobject DocumentDetector : OpenCV() {\n\n    /**\n     * take a photo with a document, and find the document's corners\n     *\n     * @param image a photo with a document\n     * @return a list with document corners (top left, top right, bottom right, bottom left)\n     */\n    fun findDocumentCorners(image: Bitmap): List<Point>? {\n\n        // convert bitmap to OpenCV matrix\n        val mat = image.toMat()\n\n        // shrink photo to make it easier to find document corners\n        val shrunkImageHeight = 500.0\n        Imgproc.resize(\n            mat,\n            mat,\n            Size(\n                shrunkImageHeight * image.width / image.height,\n                shrunkImageHeight\n            )\n        )\n\n        // convert photo to LUV colorspace to avoid glares caused by lights\n        Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGR2Luv)\n\n        // separate photo into 3 parts, (L, U, and V)\n        val imageSplitByColorChannel: List<Mat> = mutableListOf()\n        Core.split(mat, imageSplitByColorChannel)\n\n        // find corners for each color channel, then pick the quad with the largest\n        // area, and scale point to account for shrinking image before document detection\n        val documentCorners: List<Point>? = imageSplitByColorChannel\n            .mapNotNull { findCorners(it) }\n            .maxByOrNull { Imgproc.contourArea(it) }\n            ?.toList()\n            ?.map {\n                Point(\n                    it.x * image.height / shrunkImageHeight,\n                    it.y * image.height / shrunkImageHeight\n                )\n            }\n\n        // sort points to force this order (top left, top right, bottom left, bottom right)\n        return documentCorners\n            ?.sortedBy { it.y }\n            ?.chunked(2)\n            ?.map { it.sortedBy { point -> point.x } }\n            ?.flatten()\n    }\n\n    /**\n     * take an image matrix with a document, and find the document's corners\n     *\n     * @param image a photo with a document in matrix format (only 1 color space)\n     * @return a matrix with document corners or null if we can't find corners\n     */\n    private fun findCorners(image: Mat): MatOfPoint? {\n        val outputImage = Mat()\n\n        // blur image to help remove noise\n        Imgproc.GaussianBlur(image, outputImage, Size(5.0, 5.0), 0.0)\n\n        // convert all pixels to either black or white (document should be black after this), but\n        // there might be other parts of the photo that turn black\n        Imgproc.threshold(\n            outputImage,\n            outputImage,\n            0.0,\n            255.0,\n            Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU\n        )\n\n        // detect the document's border using the Canny edge detection algorithm\n        Imgproc.Canny(outputImage, outputImage, 50.0, 200.0)\n\n        // the detect edges might have gaps, so try to close those\n        Imgproc.morphologyEx(\n            outputImage,\n            outputImage,\n            Imgproc.MORPH_CLOSE,\n            Mat.ones(Size(5.0, 5.0), CvType.CV_8U)\n        )\n\n        // get outline of document edges, and outlines of other shapes in photo\n        val contours: MutableList<MatOfPoint> = mutableListOf()\n        Imgproc.findContours(\n            outputImage,\n            contours,\n            Mat(),\n            Imgproc.RETR_LIST,\n            Imgproc.CHAIN_APPROX_SIMPLE\n        )\n\n        // approximate outlines using polygons\n        var approxContours = contours.map {\n            val approxContour = MatOfPoint2f()\n            val contour2f = MatOfPoint2f(*it.toArray())\n            Imgproc.approxPolyDP(\n                contour2f,\n                approxContour,\n                0.02 * Imgproc.arcLength(contour2f, true),\n                true\n            )\n            MatOfPoint(*approxContour.toArray())\n        }\n\n        // We now have many polygons, so remove polygons that don't have 4 sides since we\n        // know the document has 4 sides. Calculate areas for all remaining polygons, and\n        // remove polygons with small areas. We assume that the document takes up a large portion\n        // of the photo. Remove polygons that aren't convex since a document can't be convex.\n        approxContours = approxContours.filter {\n            it.height() == 4 && Imgproc.contourArea(it) > 1000 && Imgproc.isContourConvex(it)\n        }\n\n        // Once we have all large, convex, 4-sided polygons find and return the 1 with the\n        // largest area\n        return approxContours.maxByOrNull { Imgproc.contourArea(it) }\n    }\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/forensics/ImageForensics.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.forensics\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.android.Utils\nimport org.opencv.core.Core\nimport org.opencv.core.CvType\nimport org.opencv.core.CvType.CV_32F\nimport org.opencv.core.CvType.CV_8U\nimport org.opencv.core.Mat\nimport org.opencv.core.MatOfByte\nimport org.opencv.core.MatOfInt\nimport org.opencv.core.Scalar\nimport org.opencv.imgcodecs.Imgcodecs\nimport org.opencv.imgproc.Imgproc\nimport java.util.Random\nimport kotlin.math.abs\nimport kotlin.math.atan2\nimport kotlin.math.cos\nimport kotlin.math.hypot\nimport kotlin.math.sin\n\nobject ImageForensics : OpenCV() {\n\n    fun errorLevelAnalysis(\n        input: Bitmap,\n        quality: Int = 90\n    ): Bitmap {\n        val src = input.toMat()\n        Utils.bitmapToMat(input, src)\n        Imgproc.cvtColor(src, src, Imgproc.COLOR_RGBA2BGR)\n\n        val buf = MatOfByte()\n        val params = MatOfInt(Imgcodecs.IMWRITE_JPEG_QUALITY, quality)\n        Imgcodecs.imencode(\".jpg\", src, buf, params)\n\n        val resaved = Imgcodecs.imdecode(buf, Imgcodecs.IMREAD_COLOR)\n\n        val diff = Mat()\n        Core.absdiff(src, resaved, diff)\n\n        val dst = Mat()\n        Core.normalize(diff, dst, 0.0, 255.0, Core.NORM_MINMAX)\n        dst.convertTo(dst, CvType.CV_8UC3)\n\n        Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2RGBA)\n        val outBmp = dst.toBitmap()\n\n        src.release()\n        resaved.release()\n        diff.release()\n        dst.release()\n        buf.release()\n\n        return outBmp\n    }\n\n    fun luminanceGradient(input: Bitmap): Bitmap {\n        val src = input.toMat()\n        Imgproc.cvtColor(src, src, Imgproc.COLOR_RGBA2BGR)\n\n        val gray = Mat()\n        Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY)\n        gray.convertTo(gray, CV_32F)\n\n        val sobelX = Mat()\n        val sobelY = Mat()\n        Imgproc.Sobel(gray, sobelX, CV_32F, 1, 0, 3, 1.0, 0.0)\n        Imgproc.Sobel(gray, sobelY, CV_32F, 0, 1, 3, 1.0, 0.0)\n\n        val magnitude = Mat()\n        Core.magnitude(sobelX, sobelY, magnitude)\n\n        val rows = magnitude.rows()\n        val cols = magnitude.cols()\n\n        val dst = Mat(rows, cols, CvType.CV_32FC3)\n\n        val sxRow = FloatArray(cols)\n        val syRow = FloatArray(cols)\n        val magRow = FloatArray(cols)\n\n        for (r in 0 until rows) {\n            sobelX.get(r, 0, sxRow)\n            sobelY.get(r, 0, syRow)\n            magnitude.get(r, 0, magRow)\n            val outRow = FloatArray(cols * 3)\n            for (c in 0 until cols) {\n                val angle = atan2(sxRow[c].toDouble(), syRow[c].toDouble()).toFloat()\n                val mag = magRow[c]\n                val g = (-sin(angle.toDouble()) / 2.0 + 0.5).toFloat()\n                val rchan = (-cos(angle.toDouble()) / 2.0 + 0.5).toFloat()\n                outRow[c * 3 + 0] = mag\n                outRow[c * 3 + 1] = g\n                outRow[c * 3 + 2] = rchan\n            }\n            dst.put(r, 0, outRow)\n        }\n\n        val channels = ArrayList<Mat>(3)\n        Core.split(dst, channels)\n        Core.normalize(channels[0], channels[0], 0.0, 1.0, Core.NORM_MINMAX)\n        Core.merge(channels, dst)\n\n        dst.convertTo(dst, CvType.CV_8UC3, 255.0)\n        Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2RGBA)\n        val outBmp = dst.toBitmap()\n\n        gray.release()\n        sobelX.release()\n        sobelY.release()\n        magnitude.release()\n\n        for (m in channels) m.release()\n\n        dst.release()\n        src.release()\n\n        return outBmp\n    }\n\n    fun averageDistance(input: Bitmap): Bitmap {\n        val src = input.toMat()\n        Imgproc.cvtColor(src, src, Imgproc.COLOR_RGBA2BGR)\n\n        val src32 = Mat()\n        src.convertTo(src32, CV_32F, 1.0 / 255.0)\n\n        val kernel = Mat(3, 3, CV_32F)\n        kernel.put(0, 0, 0.0, 0.25, 0.0)\n        kernel.put(1, 0, 0.25, 0.0, 0.25)\n        kernel.put(2, 0, 0.0, 0.25, 0.0)\n\n        val filtered = Mat()\n        Imgproc.filter2D(src32, filtered, -1, kernel)\n\n        val diff = Mat()\n        Core.absdiff(src32, filtered, diff)\n        Core.normalize(diff, diff, 0.0, 1.0, Core.NORM_MINMAX)\n\n        diff.convertTo(diff, CvType.CV_8UC3, 255.0)\n        Imgproc.cvtColor(diff, diff, Imgproc.COLOR_BGR2RGBA)\n        val outBmp = diff.toBitmap()\n\n        src.release()\n        src32.release()\n        kernel.release()\n        filtered.release()\n\n        diff.release()\n        return outBmp\n    }\n\n    fun detectCopyMove(\n        input: Bitmap,\n        retain: Int = 4,\n        qCoefficent: Double = 1.0\n    ): Bitmap {\n        val srcColor = input.toMat()\n        val srcGray = Mat()\n        Imgproc.cvtColor(srcColor, srcGray, Imgproc.COLOR_BGR2GRAY)\n        srcGray.convertTo(srcGray, CV_32F)\n\n        val blockSize = 16\n        val blocksHeight = srcGray.rows() - blockSize + 1\n        val blocksWidth = srcGray.cols() - blockSize + 1\n        val totalBlocks = blocksHeight * blocksWidth\n        val blocks = ArrayList<Mat>(totalBlocks)\n        val tmp = Mat()\n\n        for (y in 0 until blocksHeight) {\n            for (x in 0 until blocksWidth) {\n                val roi = srcGray.submat(y, y + blockSize, x, x + blockSize)\n                Core.dct(roi, tmp)\n                Core.divide(tmp, Scalar(qCoefficent), tmp)\n                tmp.convertTo(tmp, CV_8U)\n                blocks.add(tmp.submat(0, retain, 0, retain).clone())\n            }\n        }\n\n        val index = Array(totalBlocks) { it }\n        index.sortWith { a, b ->\n            val aBytes = ByteArray(retain * retain)\n            val bBytes = ByteArray(retain * retain)\n            blocks[a].get(0, 0, aBytes)\n            blocks[b].get(0, 0, bBytes)\n            for (i in aBytes.indices) {\n                val diff = aBytes[i].toInt() - bBytes[i].toInt()\n                if (diff != 0) return@sortWith diff\n            }\n            0\n        }\n\n        val sCount = IntArray(srcGray.rows() * srcGray.cols() * 2)\n        val rectBuffer = srcColor.clone()\n\n        for (i in 0 until totalBlocks - 1) {\n            val aBytes = ByteArray(retain * retain)\n            val bBytes = ByteArray(retain * retain)\n            blocks[index[i]].get(0, 0, aBytes)\n            blocks[index[i + 1]].get(0, 0, bBytes)\n            if (aBytes.contentEquals(bBytes)) {\n                val curX = index[i] % blocksWidth\n                val curY = index[i] / blocksWidth\n                val nextX = index[i + 1] % blocksWidth\n                val nextY = index[i + 1] / blocksWidth\n                val shiftX = abs(curX - nextX)\n                var shiftY = abs(curY - nextY)\n                val magnitude = hypot(shiftX.toDouble(), shiftY.toDouble())\n                shiftY += srcGray.rows()\n                if (magnitude > blockSize) sCount[shiftY * srcGray.cols() + shiftX]++\n            }\n        }\n\n        for (i in 0 until totalBlocks - 1) {\n            val aBytes = ByteArray(retain * retain)\n            val bBytes = ByteArray(retain * retain)\n            blocks[index[i]].get(0, 0, aBytes)\n            blocks[index[i + 1]].get(0, 0, bBytes)\n            if (aBytes.contentEquals(bBytes)) {\n                val curX = index[i] % blocksWidth\n                val curY = index[i] / blocksWidth\n                val nextX = index[i + 1] % blocksWidth\n                val nextY = index[i + 1] / blocksWidth\n                val shiftX = abs(curX - nextX)\n                var shiftY = abs(curY - nextY)\n                val magnitude = hypot(shiftX.toDouble(), shiftY.toDouble())\n                shiftY += srcGray.rows()\n                if (sCount[shiftY * srcGray.cols() + shiftX] > 10) {\n                    val rng = Random(magnitude.toLong())\n                    val color = Scalar(\n                        rng.nextInt(256).toDouble(),\n                        rng.nextInt(256).toDouble(),\n                        rng.nextInt(256).toDouble()\n                    )\n                    for (ii in 0 until blockSize) {\n                        for (jj in 0 until blockSize) {\n                            rectBuffer.put(curY + ii, curX + jj, *color.`val`)\n                            rectBuffer.put(nextY + ii, nextX + jj, *color.`val`)\n                        }\n                    }\n                }\n            }\n        }\n\n        val dst = Mat()\n        Core.addWeighted(srcColor, 0.2, rectBuffer, 0.8, 0.0, dst)\n        return dst.toBitmap()\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/free_corners_crop/FreeCrop.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.free_corners_crop\n\nimport android.graphics.Bitmap\nimport android.graphics.PointF\nimport androidx.compose.ui.geometry.Offset\nimport com.t8rin.opencv_tools.free_corners_crop.model.Quad\nimport com.t8rin.opencv_tools.free_corners_crop.model.distance\nimport com.t8rin.opencv_tools.free_corners_crop.model.toOpenCVPoint\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Mat\nimport org.opencv.core.MatOfPoint2f\nimport org.opencv.core.Point\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\nimport kotlin.math.min\n\nobject FreeCrop : OpenCV() {\n\n    fun crop(\n        bitmap: Bitmap,\n        points: List<Offset>\n    ): Bitmap {\n        val corners = Quad(\n            topLeftCorner = PointF(points[0].x, points[0].y),\n            topRightCorner = PointF(points[1].x, points[1].y),\n            bottomRightCorner = PointF(points[2].x, points[2].y),\n            bottomLeftCorner = PointF(points[3].x, points[3].y)\n        )\n\n        val image = bitmap.toMat()\n\n        // convert top left, top right, bottom right, and bottom left document corners from\n        // Android points to OpenCV points\n        val tLC = corners.topLeftCorner.toOpenCVPoint()\n        val tRC = corners.topRightCorner.toOpenCVPoint()\n        val bRC = corners.bottomRightCorner.toOpenCVPoint()\n        val bLC = corners.bottomLeftCorner.toOpenCVPoint()\n\n        val width = min(tLC.distance(tRC), bLC.distance(bRC))\n        val height = min(tLC.distance(bLC), tRC.distance(bRC))\n\n        // create empty image matrix with cropped and warped document width and height\n        val croppedImage = MatOfPoint2f(\n            Point(0.0, 0.0),\n            Point(width, 0.0),\n            Point(width, height),\n            Point(0.0, height),\n        )\n\n        val output = Mat()\n        Imgproc.warpPerspective(\n            image,\n            output,\n            Imgproc.getPerspectiveTransform(\n                MatOfPoint2f(tLC, tRC, bRC, bLC),\n                croppedImage\n            ),\n            Size(width, height)\n        )\n\n        return output.toBitmap()\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/free_corners_crop/compose/FreeCornersCropper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.free_corners_crop.compose\n\nimport android.graphics.Bitmap\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.gestures.detectDragGestures\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.magnifier\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.isSpecified\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.CompositingStrategy\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.layout.onGloballyPositioned\nimport androidx.compose.ui.layout.positionInParent\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.dp\nimport coil3.imageLoader\nimport coil3.request.ImageRequest\nimport coil3.request.allowHardware\nimport coil3.toBitmap\nimport com.t8rin.gesture.observePointersCountWithOffset\nimport com.t8rin.image.ImageWithConstraints\nimport com.t8rin.opencv_tools.free_corners_crop.FreeCrop\nimport net.engawapg.lib.zoomable.rememberZoomState\nimport net.engawapg.lib.zoomable.zoomable\nimport kotlin.math.roundToInt\n\n@Composable\nfun FreeCornersCropper(\n    imageModel: Any?,\n    croppingTrigger: Boolean,\n    onCropped: (Bitmap) -> Unit,\n    modifier: Modifier = Modifier,\n    showMagnifier: Boolean = true,\n    handlesSize: Dp = 8.dp,\n    frameStrokeWidth: Dp = 1.2.dp,\n    coercePointsToImageArea: Boolean = true,\n    overlayColor: Color = Color.Black.copy(0.5f),\n    contentPadding: PaddingValues = PaddingValues(24.dp),\n    containerModifier: Modifier = Modifier,\n    onLoadingStateChange: (Boolean) -> Unit = {}\n) {\n    var bitmap by remember {\n        mutableStateOf<Bitmap?>(null)\n    }\n    val context = LocalContext.current\n\n    LaunchedEffect(imageModel) {\n        bitmap = if (imageModel is Bitmap?) imageModel\n        else {\n            onLoadingStateChange(true)\n            context.imageLoader.execute(\n                ImageRequest.Builder(context).data(imageModel)\n                    .allowHardware(false).build()\n            ).image?.toBitmap()\n        }\n        onLoadingStateChange(false)\n    }\n\n    AnimatedContent(\n        targetState = bitmap,\n        modifier = containerModifier,\n        transitionSpec = { fadeIn() togetherWith fadeOut() }\n    ) { image ->\n        if (image != null) {\n            FreeCornersCropper(\n                bitmap = image,\n                croppingTrigger = croppingTrigger,\n                onCropped = onCropped,\n                modifier = modifier,\n                showMagnifier = showMagnifier,\n                contentPadding = contentPadding,\n                coercePointsToImageArea = coercePointsToImageArea,\n                handlesSize = handlesSize,\n                frameStrokeWidth = frameStrokeWidth,\n                overlayColor = overlayColor\n            )\n        }\n    }\n}\n\n@Composable\nfun FreeCornersCropper(\n    bitmap: Bitmap,\n    croppingTrigger: Boolean,\n    onCropped: (Bitmap) -> Unit,\n    modifier: Modifier = Modifier,\n    showMagnifier: Boolean = true,\n    handlesSize: Dp = 8.dp,\n    frameStrokeWidth: Dp = 1.2.dp,\n    coercePointsToImageArea: Boolean = true,\n    overlayColor: Color = Color.Black.copy(0.5f),\n    contentPadding: PaddingValues = PaddingValues(24.dp)\n) {\n    val density = LocalDensity.current\n\n    val handleRadiusPx = with(density) {\n        handlesSize.toPx()\n    }\n    val frameStrokeWidthPx = with(density) {\n        frameStrokeWidth.toPx()\n    }\n\n    val touchIndex = remember {\n        mutableIntStateOf(-1)\n    }\n    var globalTouchPointersCount by remember { mutableIntStateOf(0) }\n\n    val colorScheme = MaterialTheme.colorScheme\n\n    val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }\n\n    var magnifierCenter by remember { mutableStateOf(Offset.Unspecified) }\n\n    ImageWithConstraints(\n        modifier = modifier\n            .clipToBounds()\n            .observePointersCountWithOffset { size, _ ->\n                globalTouchPointersCount = size\n            }\n            .drawBehind {\n                drawRect(overlayColor)\n            }\n            .zoomable(\n                zoomState = rememberZoomState(maxScale = 10f),\n                zoomEnabled = globalTouchPointersCount >= 2\n            ),\n        imageBitmap = imageBitmap,\n        drawImage = false\n    ) {\n        var imageWidth by remember {\n            mutableIntStateOf(bitmap.width)\n        }\n\n        var imageHeight by remember {\n            mutableIntStateOf(bitmap.height)\n        }\n\n        val internalPaddingDp = 16.dp\n        val internalPadding = with(density) { internalPaddingDp.toPx() }\n\n        var topOffset by remember {\n            mutableIntStateOf(0)\n        }\n\n        var startOffset by remember {\n            mutableIntStateOf(0)\n        }\n\n        val drawPoints = rememberSaveable(\n            topOffset,\n            startOffset,\n            imageWidth,\n            imageHeight,\n            contentPadding,\n            stateSaver = OffsetListSaver\n        ) {\n            mutableStateOf(\n                listOf(\n                    Offset(\n                        x = internalPadding + startOffset,\n                        y = internalPadding + topOffset\n                    ),\n                    Offset(\n                        x = imageWidth - internalPadding + startOffset,\n                        y = internalPadding + topOffset\n                    ),\n                    Offset(\n                        x = imageWidth - internalPadding + startOffset,\n                        y = imageHeight - internalPadding + topOffset\n                    ),\n                    Offset(\n                        x = internalPadding + startOffset,\n                        y = imageHeight - internalPadding + topOffset\n                    )\n                )\n            )\n        }\n\n        val pointScales = List(drawPoints.value.size) {\n            animateFloatAsState(if (it == touchIndex.intValue) 1.4f else 1f)\n        }\n\n        LaunchedEffect(croppingTrigger) {\n            if (croppingTrigger) {\n                val widthScale = bitmap.width.toFloat() / imageWidth\n                val heightScale = bitmap.height.toFloat() / imageHeight\n                onCropped(\n                    FreeCrop.crop(\n                        bitmap = bitmap,\n                        points = drawPoints.value.map {\n                            Offset(\n                                x = ((it.x - startOffset) * widthScale).roundToInt()\n                                    .coerceIn(0, bitmap.width).toFloat(),\n                                y = ((it.y - topOffset) * heightScale).roundToInt()\n                                    .coerceIn(0, bitmap.height).toFloat()\n                            )\n                        }\n                    )\n                )\n            }\n        }\n\n        Image(\n            bitmap = imageBitmap,\n            contentDescription = null,\n            modifier = Modifier\n                .padding(internalPaddingDp)\n                .padding(contentPadding)\n                .aspectRatio(bitmap.width / bitmap.height.toFloat())\n                .onGloballyPositioned {\n                    topOffset = it.positionInParent().y.toInt()\n                    startOffset = it.positionInParent().x.toInt()\n                    imageWidth = it.size.width\n                    imageHeight = it.size.height\n                },\n            contentScale = ContentScale.FillBounds\n        )\n\n        fun Offset.coerceToImageBounds(): Offset = coerceIn(\n            horizontalRange = (startOffset).toFloat()..((imageWidth + startOffset).toFloat()),\n            verticalRange = (topOffset).toFloat()..((imageHeight + topOffset).toFloat())\n        )\n\n        LaunchedEffect(coercePointsToImageArea) {\n            drawPoints.value = drawPoints.value.map {\n                it.coerceToImageBounds()\n            }\n        }\n\n        Canvas(\n            modifier = Modifier\n                .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)\n                .size(maxWidth, maxHeight)\n                .then(\n                    if (showMagnifier && magnifierCenter.isSpecified) {\n                        Modifier.magnifier(\n                            magnifierCenter = {\n                                magnifierCenter - Offset(0f, 100.dp.toPx())\n                            },\n                            sourceCenter = {\n                                magnifierCenter\n                            },\n                            size = DpSize(100.dp, 100.dp),\n                            cornerRadius = 50.dp,\n                            elevation = 2.dp\n                        )\n                    } else Modifier\n                )\n                .pointerInput(\n                    contentPadding,\n                    coercePointsToImageArea,\n                    handleRadiusPx,\n                    bitmap,\n                    showMagnifier\n                ) {\n                    detectDragGestures(\n                        onDragStart = { offset ->\n                            touchIndex.intValue = -1\n                            drawPoints.value.forEachIndexed { index, drawProperties ->\n                                val isTouched = isTouched(\n                                    center = drawProperties,\n                                    touchPosition = offset,\n                                    radius = handleRadiusPx\n                                )\n\n                                if (isTouched) {\n                                    touchIndex.intValue = index\n                                }\n                            }\n\n                            magnifierCenter =\n                                if (showMagnifier && touchIndex.intValue != -1) offset\n                                else Offset.Unspecified\n                        },\n                        onDrag = { _, dragAmount ->\n                            drawPoints.value\n                                .getOrNull(touchIndex.intValue)\n                                ?.let { point ->\n                                    drawPoints.value = drawPoints.value\n                                        .toMutableList()\n                                        .apply {\n                                            this[touchIndex.intValue] = point\n                                                .plus(dragAmount)\n                                                .let {\n                                                    if (coercePointsToImageArea) {\n                                                        it.coerceToImageBounds()\n                                                    } else it\n                                                }\n                                                .also { newPoint ->\n                                                    if (showMagnifier) magnifierCenter = newPoint\n                                                }\n                                        }\n                                }\n                        },\n                        onDragEnd = {\n                            drawPoints.value\n                                .getOrNull(touchIndex.intValue)\n                                ?.let { point ->\n                                    drawPoints.value = drawPoints.value\n                                        .toMutableList()\n                                        .apply {\n                                            this[touchIndex.intValue] = point\n                                        }\n                                }\n                            touchIndex.intValue = -1\n                            magnifierCenter = Offset.Unspecified\n                        },\n                        onDragCancel = {\n                            drawPoints.value\n                                .getOrNull(touchIndex.intValue)\n                                ?.let { point ->\n                                    drawPoints.value = drawPoints.value\n                                        .toMutableList()\n                                        .apply {\n                                            this[touchIndex.intValue] = point\n                                        }\n                                }\n                            touchIndex.intValue = -1\n                            magnifierCenter = Offset.Unspecified\n                        }\n                    )\n                }\n        ) {\n            val (x, y) = drawPoints.value[0]\n            val (x1, y1) = drawPoints.value[1]\n            val (x2, y2) = drawPoints.value[2]\n            val (x3, y3) = drawPoints.value[3]\n\n            val framePath = Path().apply {\n                moveTo(x, y)\n                lineTo(x1, y1)\n                lineTo(x2, y2)\n                lineTo(x3, y3)\n                close()\n            }\n\n            drawPath(\n                path = framePath,\n                brush = SolidColor(Color.Transparent),\n                blendMode = BlendMode.Clear\n            )\n\n            drawPath(\n                path = framePath,\n                brush = SolidColor(colorScheme.primaryContainer),\n                style = Stroke(frameStrokeWidthPx)\n            )\n\n            drawPoints.value.forEachIndexed { index, point ->\n                val scale = pointScales[index].value\n\n                drawCircle(\n                    color = colorScheme.primary,\n                    center = point,\n                    radius = handleRadiusPx * scale\n                )\n                drawCircle(\n                    color = colorScheme.primaryContainer,\n                    center = point,\n                    radius = handleRadiusPx * 0.8f * scale\n                )\n            }\n        }\n    }\n}\n\nprivate fun isTouched(center: Offset, touchPosition: Offset, radius: Float): Boolean {\n    return center.minus(touchPosition).getDistanceSquared() < radius * radius * radius\n}\n\nprivate val OffsetListSaver: Saver<List<Offset>, String> = Saver(\n    save = { list ->\n        list.joinToString(\",\") { (x, y) ->\n            \"$x:$y\"\n        }\n    },\n    restore = { string ->\n        string.split(\",\").map { o ->\n            val (x, y) = o.split(\":\").map { it.toFloat() }\n            Offset(x, y)\n        }\n    }\n)\n\nprivate fun Offset.coerceIn(\n    horizontalRange: ClosedRange<Float>,\n    verticalRange: ClosedRange<Float>\n) = Offset(this.x.coerceIn(horizontalRange), this.y.coerceIn(verticalRange))"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/free_corners_crop/model/Quad.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.free_corners_crop.model\n\nimport android.graphics.PointF\nimport org.opencv.core.Point\nimport kotlin.math.pow\nimport kotlin.math.sqrt\n\nclass Quad(\n    val topLeftCorner: PointF,\n    val topRightCorner: PointF,\n    val bottomRightCorner: PointF,\n    val bottomLeftCorner: PointF\n)\n\nfun PointF.toOpenCVPoint(): Point {\n    return Point(x.toDouble(), y.toDouble())\n}\n\nfun Point.distance(point: Point): Double {\n    return sqrt((point.x - x).pow(2) + (point.y - y).pow(2))\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/image_comparison/ImageDiffTool.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.image_comparison\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.opencv_tools.image_comparison.model.ComparisonType\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.resizeAndPad\nimport com.t8rin.opencv_tools.utils.toScalar\nimport org.opencv.android.Utils\nimport org.opencv.core.Core\nimport org.opencv.core.Mat\nimport org.opencv.core.Scalar\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\nimport kotlin.math.log10\nimport kotlin.math.sqrt\n\n\nobject ImageDiffTool : OpenCV() {\n\n    fun highlightDifferences(\n        input: Bitmap,\n        other: Bitmap,\n        comparisonType: ComparisonType,\n        highlightColor: Int,\n        threshold: Float = 4f\n    ): Bitmap {\n        val bitmap1 = input.copy(Bitmap.Config.ARGB_8888, false)\n        val bitmap2 = other.copy(Bitmap.Config.ARGB_8888, false)\n\n        val mat1 = Mat()\n        val mat2Raw = Mat()\n        Utils.bitmapToMat(bitmap1, mat1)\n        Utils.bitmapToMat(bitmap2, mat2Raw)\n\n        val mat2 = mat2Raw.resizeAndPad(mat1.size())\n\n        if (mat1.size() != mat2.size() || mat1.type() != mat2.type()) {\n            throw IllegalArgumentException(\"Bitmaps must have the same size and type\")\n        }\n\n        val diff = Mat()\n        val thresholdValue = (threshold.coerceIn(0f, 100f) * 2.55).coerceIn(0.0, 255.0)\n\n        when (comparisonType) {\n            ComparisonType.SSIM -> {\n                val blurred1 = Mat()\n                val blurred2 = Mat()\n                Imgproc.GaussianBlur(mat1, blurred1, Size(11.0, 11.0), 1.5)\n                Imgproc.GaussianBlur(mat2, blurred2, Size(11.0, 11.0), 1.5)\n\n                val ssimMap = Mat()\n                Core.absdiff(blurred1, blurred2, ssimMap)\n\n                Imgproc.threshold(ssimMap, diff, 20.0, 255.0, Imgproc.THRESH_BINARY)\n            }\n\n            ComparisonType.AE -> {\n                Core.absdiff(mat1, mat2, diff)\n                Core.compare(diff, Scalar(thresholdValue), diff, Core.CMP_GT)\n            }\n\n            ComparisonType.MAE -> {\n                Core.absdiff(mat1, mat2, diff)\n                val meanScalar = Core.mean(diff)\n                val meanValue =\n                    (meanScalar.`val`[0] + meanScalar.`val`[1] + meanScalar.`val`[2]) / 3.0\n                Core.compare(diff, Scalar(meanValue + thresholdValue), diff, Core.CMP_GT)\n            }\n\n            ComparisonType.NCC -> {\n                val result = Mat()\n                Imgproc.matchTemplate(mat1, mat2, result, Imgproc.TM_CCORR_NORMED)\n                Core.absdiff(mat1, mat2, diff)\n                Core.compare(diff, Scalar(thresholdValue), diff, Core.CMP_GT)\n            }\n\n            ComparisonType.PSNR -> {\n                val mse = Mat()\n                Core.absdiff(mat1, mat2, mse)\n                Core.pow(mse, 2.0, mse)\n                val meanMse = Core.mean(mse).`val`[0]\n                val psnr = if (meanMse == 0.0) 100.0 else 10.0 * log10(255.0 * 255.0 / meanMse)\n                Core.absdiff(mat1, mat2, diff)\n                if (psnr > 30) Core.multiply(diff, Scalar(0.2), diff)\n                Core.compare(diff, Scalar(thresholdValue), diff, Core.CMP_GT)\n            }\n\n            ComparisonType.RMSE -> {\n                val mse = Mat()\n                Core.absdiff(mat1, mat2, mse)\n                Core.pow(mse, 2.0, mse)\n                val meanMse = Core.mean(mse).`val`[0]\n                val rmse = sqrt(meanMse)\n                Core.absdiff(mat1, mat2, diff)\n                if (rmse < 10) Core.multiply(diff, Scalar(0.2), diff)\n                Core.compare(diff, Scalar(thresholdValue), diff, Core.CMP_GT)\n            }\n        }\n\n        val mask = Mat()\n        Imgproc.cvtColor(diff, mask, Imgproc.COLOR_BGR2GRAY)\n        Imgproc.threshold(mask, mask, 1.0, 255.0, Imgproc.THRESH_BINARY)\n\n        val result = mat1.clone()\n        result.setTo(highlightColor.toScalar(), mask)\n\n        val outputBitmap = createBitmap(bitmap1.width, bitmap1.height)\n        Utils.matToBitmap(result, outputBitmap)\n\n        return outputBitmap\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/image_comparison/model/ComparisonType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.image_comparison.model\n\nenum class ComparisonType { SSIM, AE, MAE, NCC, PSNR, RMSE }"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/image_processing/ImageProcessing.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.image_processing\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Mat\nimport org.opencv.imgproc.Imgproc\n\nobject ImageProcessing : OpenCV() {\n\n    fun canny(\n        bitmap: Bitmap,\n        thresholdOne: Float,\n        thresholdTwo: Float\n    ): Bitmap {\n        val matGrayScale = Mat()\n        Imgproc.cvtColor(bitmap.toMat(), matGrayScale, Imgproc.COLOR_RGBA2GRAY)\n        Imgproc.medianBlur(matGrayScale, matGrayScale, 3)\n\n        val matCanny = Mat()\n        Imgproc.Canny(matGrayScale, matCanny, thresholdOne.toDouble(), thresholdTwo.toDouble())\n\n        return matCanny.toBitmap()\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/lens_correction/LensCorrection.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"LocalVariableName\", \"unused\")\n\npackage com.t8rin.opencv_tools.lens_correction\n\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport android.util.Log\nimport com.t8rin.opencv_tools.lens_correction.model.LCException\nimport com.t8rin.opencv_tools.lens_correction.model.LCException.InvalidCalibDimensions\nimport com.t8rin.opencv_tools.lens_correction.model.LCException.InvalidDistortionCoeffs\nimport com.t8rin.opencv_tools.lens_correction.model.LCException.InvalidMatrixSize\nimport com.t8rin.opencv_tools.lens_correction.model.LCException.MissingFisheyeParams\nimport com.t8rin.opencv_tools.lens_correction.model.LensProfile\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.json.JSONArray\nimport org.json.JSONObject\nimport org.opencv.calib3d.Calib3d\nimport org.opencv.core.CvType\nimport org.opencv.core.Mat\nimport org.opencv.imgproc.Imgproc\nimport java.io.InputStream\nimport java.io.Reader\nimport kotlin.contracts.contract\n\nobject LensCorrection : OpenCV() {\n\n    fun undistort(\n        bitmap: Bitmap,\n        lensDataUri: Uri,\n        intensity: Double = 1.0\n    ): Bitmap = undistort(\n        bitmap = bitmap,\n        lensData = context.contentResolver.openInputStream(lensDataUri)!!,\n        intensity = intensity\n    )\n\n    fun undistort(\n        bitmap: Bitmap,\n        lensData: InputStream,\n        intensity: Double = 1.0\n    ): Bitmap = undistort(\n        bitmap = bitmap,\n        lensDataJson = lensData.bufferedReader().use(Reader::readText),\n        intensity = intensity\n    )\n\n    fun undistort(\n        bitmap: Bitmap,\n        lensDataJson: String,\n        intensity: Double = 1.0\n    ): Bitmap = undistort(\n        bitmap = bitmap,\n        lensProfile = LensProfile.fromJson(lensDataJson).withIntensity(intensity)\n    )\n\n    fun undistort(\n        bitmap: Bitmap,\n        lensProfile: LensProfile\n    ): Bitmap = undistortImpl(\n        bitmap = bitmap,\n        cameraMatrix = lensProfile.cameraMatrix,\n        distortionCoeffs = lensProfile.distortionCoeffs,\n        calibWidth = lensProfile.calibWidth,\n        calibHeight = lensProfile.calibHeight\n    )\n\n\n    private fun undistortImpl(\n        bitmap: Bitmap,\n        cameraMatrix: List<List<Double>>,\n        distortionCoeffs: List<Double>,\n        calibWidth: Int,\n        calibHeight: Int\n    ): Bitmap {\n        lcCheck(\n            value = distortionCoeffs.size == 4,\n            message = InvalidDistortionCoeffs()\n        )\n\n        val rgbaMat = bitmap.toMat()\n        val K = Mat(3, 3, CvType.CV_64F)\n        val D = Mat(4, 1, CvType.CV_64F)\n        val undistorted = Mat()\n\n        try {\n            Imgproc.cvtColor(rgbaMat, rgbaMat, Imgproc.COLOR_RGBA2RGB)\n\n            cameraMatrix.forEachIndexed { i, row ->\n                lcCheck(\n                    value = row.size == 3,\n                    message = InvalidMatrixSize()\n                )\n\n                row.forEachIndexed { j, value ->\n                    K.put(i, j, value)\n                }\n            }\n\n            distortionCoeffs.forEachIndexed { i, v -> D.put(i, 0, -v) }\n\n            val scaleX = bitmap.width.toDouble() / calibWidth\n            val scaleY = bitmap.height.toDouble() / calibHeight\n\n            K.put(0, 0, K.get(0, 0)[0] * scaleX) // fx\n            K.put(0, 2, K.get(0, 2)[0] * scaleX) // cx\n            K.put(1, 1, K.get(1, 1)[0] * scaleY) // fy\n            K.put(1, 2, K.get(1, 2)[0] * scaleY) // cy\n\n            Calib3d.fisheye_undistortImage(rgbaMat, undistorted, K, D, K, rgbaMat.size())\n\n            Imgproc.cvtColor(undistorted, undistorted, Imgproc.COLOR_RGB2RGBA)\n\n            return undistorted.toBitmap()\n        } finally {\n            rgbaMat.release()\n            K.release()\n            D.release()\n        }\n    }\n\n    fun LensProfile.Companion.fromJson(json: String): LensProfile = JSONObject(json).run {\n        if (has(\"name\")) Log.d(\"LensCorrection\", \"name detected: ${get(\"name\")}\")\n\n        lcCheck(\n            value = has(\"fisheye_params\"),\n            message = MissingFisheyeParams()\n        )\n\n        val fisheyeParams = getJSONObject(\"fisheye_params\")\n\n        lcCheck(\n            value = fisheyeParams.has(\"camera_matrix\"),\n            message = InvalidMatrixSize()\n        )\n\n        lcCheck(\n            value = fisheyeParams.has(\"distortion_coeffs\"),\n            message = InvalidDistortionCoeffs()\n        )\n\n        val calibDim = lcCheck(\n            value = safeJSONObject(\"calib_dimension\")\n                ?: safeJSONObject(\"orig_dimension\")\n                ?: safeJSONObject(\"output_dimension\"),\n            message = InvalidCalibDimensions()\n        )\n\n        val calibW = calibDim.getInt(\"w\")\n        val calibH = calibDim.getInt(\"h\")\n\n        lcCheck(\n            value = calibW > 0 && calibH > 0,\n            message = InvalidCalibDimensions()\n        )\n\n        return LensProfile(\n            cameraMatrix = fisheyeParams.getCameraMatrix(),\n            distortionCoeffs = fisheyeParams.getDistortionCoeffs(),\n            calibWidth = calibW,\n            calibHeight = calibH\n        )\n    }\n\n    private fun JSONObject.getDistortionCoeffs(): List<Double> {\n        val distCoeffsArray = safeJSONArray(\"distortion_coeffs\")\n\n        lcCheck(\n            value = distCoeffsArray?.length() == 4,\n            message = InvalidDistortionCoeffs()\n        )\n\n        return List(size = 4, init = distCoeffsArray::getDouble)\n    }\n\n    private fun JSONObject.getCameraMatrix(): List<List<Double>> {\n        val cameraMatrixArray = safeJSONArray(\"camera_matrix\")\n\n        lcCheck(\n            value = cameraMatrixArray?.length() == 3,\n            message = InvalidMatrixSize()\n        )\n\n        return List(3) { i ->\n            List(3) { j ->\n                cameraMatrixArray.getJSONArray(i).getDouble(j)\n            }\n        }\n    }\n\n    private fun lcCheck(value: Boolean, message: LCException) {\n        contract { returns() implies value }\n        if (!value) throw message\n    }\n\n    private fun <T> lcCheck(value: T?, message: LCException): T {\n        contract { returns() implies (value != null) }\n        if (value == null) throw message else return value\n    }\n\n    private fun JSONObject.safeJSONObject(key: String): JSONObject? =\n        runCatching { getJSONObject(key) }.getOrNull()\n\n    private fun JSONObject.safeJSONArray(key: String): JSONArray? =\n        runCatching { getJSONArray(key) }.getOrNull()\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/lens_correction/model/LCException.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.lens_correction.model\n\n@Suppress(\"JavaIoSerializableObjectMustHaveReadResolve\")\nsealed class LCException(message: String) : Exception(message) {\n    class MissingFisheyeParams : LCException(\"No fisheye_params in JSON\")\n    class InvalidMatrixSize : LCException(\"Incorrect camera_matrix size (pass 3x3)\")\n    class InvalidCalibDimensions : LCException(\"Invalid calibration dimensions\")\n    class InvalidDistortionCoeffs : LCException(\"Bad distortion coefficients (pass only 4)\")\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/lens_correction/model/LensProfile.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.lens_correction.model\n\ndata class LensProfile(\n    val cameraMatrix: List<List<Double>>,\n    val distortionCoeffs: List<Double>,\n    val calibWidth: Int,\n    val calibHeight: Int\n) {\n    fun withIntensity(\n        intensity: Double\n    ): LensProfile = copy(\n        distortionCoeffs = distortionCoeffs.map { it * intensity }\n    )\n\n    companion object\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/lens_correction/model/Sample.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnusedReceiverParameter\")\n\npackage com.t8rin.opencv_tools.lens_correction.model\n\nimport com.t8rin.opencv_tools.lens_correction.LensCorrection\n\nval LensCorrection.SAMPLE_LENS_PROFILE\n    get() = \"{\\\"name\\\":\\\"Canon_200d Mark II_EFS 17-55mm_Lens And Body Stabilization on_1080p_16by9_1920x1080-25.00fps\\\",\\\"note\\\":\\\"Lens And Body Stabilization on\\\",\\\"calibrated_by\\\":\\\"Kane McCarthy\\\",\\\"camera_brand\\\":\\\"Canon\\\",\\\"camera_model\\\":\\\"200d Mark II\\\",\\\"lens_model\\\":\\\"EFS 17-55mm\\\",\\\"camera_setting\\\":\\\"\\\",\\\"calib_dimension\\\":{\\\"w\\\":1920,\\\"h\\\":1080},\\\"orig_dimension\\\":{\\\"w\\\":1920,\\\"h\\\":1080},\\\"output_dimension\\\":{\\\"w\\\":1920,\\\"h\\\":1080},\\\"frame_readout_time\\\":null,\\\"gyro_lpf\\\":null,\\\"input_horizontal_stretch\\\":1.0,\\\"input_vertical_stretch\\\":1.0,\\\"num_images\\\":15,\\\"fps\\\":25.0,\\\"crop\\\":null,\\\"official\\\":false,\\\"asymmetrical\\\":false,\\\"fisheye_params\\\":{\\\"RMS_error\\\":0.6572613277627248,\\\"camera_matrix\\\":[[1672.4188601991846,0.0,933.6098162432148],[0.0,1677.6413802774082,539.4748019935479],[0.0,0.0,1.0]],\\\"distortion_coeffs\\\":[0.25149531135525693,-0.4430334263157348,3.9251216996331664,-8.164669122998902],\\\"radial_distortion_limit\\\":null},\\\"identifier\\\":\\\"\\\",\\\"calibrator_version\\\":\\\"1.5.4\\\",\\\"date\\\":\\\"2024-01-05\\\",\\\"compatible_settings\\\":[],\\\"sync_settings\\\":null,\\\"distortion_model\\\":null,\\\"digital_lens\\\":null,\\\"digital_lens_params\\\":null,\\\"interpolations\\\":null,\\\"focal_length\\\":null,\\\"crop_factor\\\":null,\\\"global_shutter\\\":false}\"\n"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/moire/Moire.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"SameParameterValue\", \"unused\")\n\npackage com.t8rin.opencv_tools.moire\n\nimport android.graphics.Bitmap\nimport android.util.Log\nimport com.t8rin.opencv_tools.moire.model.MoireType\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Core\nimport org.opencv.core.CvType\nimport org.opencv.core.Mat\nimport org.opencv.core.Point\nimport org.opencv.core.Rect\nimport org.opencv.core.Scalar\nimport org.opencv.core.Size\nimport kotlin.math.abs\nimport kotlin.math.atan2\nimport kotlin.math.pow\nimport kotlin.math.sqrt\n\nobject Moire : OpenCV() {\n\n    fun remove(\n        bitmap: Bitmap,\n        type: MoireType = MoireType.AUTO\n    ): Bitmap {\n        val rgba = bitmap.toMat()\n\n        val channels = mutableListOf<Mat>()\n        Core.split(rgba, channels)\n\n        val filteredChannels = channels.take(3).map { channel ->\n            val floatMat = Mat()\n            channel.convertTo(floatMat, CvType.CV_32F)\n\n            val planes = mutableListOf(floatMat, Mat.zeros(channel.size(), CvType.CV_32F))\n            val complex = Mat()\n            Core.merge(planes, complex)\n            Core.dft(complex, complex)\n            shiftDFT(complex)\n\n            val detected = detectNoiseType(complex)\n            val appliedType =\n                type.takeIf { it != MoireType.AUTO } ?: (detected ?: MoireType.VERTICAL)\n\n            Log.d(\"Moire\", \"Detected: $detected, Applied: $appliedType\")\n\n            applyMask(complex, appliedType)\n\n            val butterworth = butterworthLP(size = channel.size(), d0 = 80.0, n = 10)\n            val filterPlanes = mutableListOf(butterworth, butterworth.clone())\n            val filter = Mat()\n            Core.merge(filterPlanes, filter)\n            Core.mulSpectrums(complex, filter, complex, 0)\n\n            shiftDFT(complex)\n\n            val inverse = Mat()\n            Core.idft(complex, inverse, Core.DFT_SCALE or Core.DFT_REAL_OUTPUT, 0)\n            inverse.convertTo(inverse, CvType.CV_8U)\n            inverse\n        }\n\n        // Собираем каналы обратно + alpha если был\n        val outputChannels = ArrayList(filteredChannels)\n        if (channels.size == 4) {\n            outputChannels.add(channels[3]) // alpha\n        }\n\n        val merged = Mat()\n        Core.merge(outputChannels, merged)\n\n        return merged.toBitmap()\n    }\n\n    private fun detectNoiseType(dftMat: Mat): MoireType? {\n        val planes = mutableListOf<Mat>()\n        Core.split(dftMat, planes)\n        val mag = Mat()\n        Core.magnitude(planes[0], planes[1], mag)\n\n        Core.add(mag, Scalar.all(1.0), mag)\n        Core.log(mag, mag)\n\n        Core.normalize(mag, mag, 0.0, 255.0, Core.NORM_MINMAX)\n        mag.convertTo(mag, CvType.CV_8U)\n\n        val center = Point(mag.cols() / 2.0, mag.rows() / 2.0)\n\n        val threshold = 180.0\n        val peaks = mutableListOf<Point>()\n\n        for (y in 0 until mag.rows()) {\n            for (x in 0 until mag.cols()) {\n                val value = mag.get(y, x)[0]\n                if (value > threshold) {\n                    val dx = abs(x - center.x)\n                    val dy = abs(y - center.y)\n                    if (dx > 10 || dy > 10) {\n                        peaks.add(Point(x.toDouble(), y.toDouble()))\n                    }\n                }\n            }\n        }\n\n        Log.d(\"Moire\", \"Detected peaks: ${peaks.size}\")\n        if (peaks.size < 2) return null\n\n        val dataPts = Mat(peaks.size, 2, CvType.CV_64F)\n        for (i in peaks.indices) {\n            dataPts.put(i, 0, peaks[i].x)\n            dataPts.put(i, 1, peaks[i].y)\n        }\n\n        val mean = Mat()\n        val eigenvectors = Mat()\n        Core.PCACompute(dataPts, mean, eigenvectors)\n\n        val vx = eigenvectors.get(0, 0)[0]\n        val vy = eigenvectors.get(0, 1)[0]\n\n        val angle = atan2(vy, vx) * 180.0 / Math.PI\n        Log.d(\"Moire\", \"Angle: $angle\")\n\n        return when {\n            abs(angle) < 15 -> MoireType.VERTICAL\n            abs(angle) > 70 && abs(angle) < 110 -> MoireType.HORIZONTAL\n            angle in 15.0..60.0 -> MoireType.RIGHT_DIAGONAL\n            angle in -60.0..-30.0 -> MoireType.LEFT_DIAGONAL\n            else -> null\n        }\n    }\n\n    private fun butterworthLP(size: Size, d0: Double, n: Int): Mat {\n        val rows = size.height.toInt()\n        val cols = size.width.toInt()\n        val centerX = rows / 2.0\n        val centerY = cols / 2.0\n\n        val filter = Mat(rows, cols, CvType.CV_32F)\n        for (i in 0 until rows) {\n            for (j in 0 until cols) {\n                val d = sqrt((i - centerX).pow(2) + (j - centerY).pow(2))\n                val value = 1.0 / (1.0 + (d / d0).pow(2.0 * n))\n                filter.put(i, j, value)\n            }\n        }\n        return filter\n    }\n\n    private fun applyMask(dftMat: Mat, type: MoireType?) {\n        if (type == null || type == MoireType.AUTO) return\n\n        val rows = dftMat.rows()\n        val cols = dftMat.cols()\n        val crow = rows / 2\n        val ccol = cols / 2\n\n        val radius = 8\n\n        fun suppressCircle(cx: Int, cy: Int) {\n            for (y in -radius..radius) {\n                for (x in -radius..radius) {\n                    val dx = cx + x\n                    val dy = cy + y\n                    if (dx in 0 until cols && dy in 0 until rows) {\n                        if (x * x + y * y <= radius * radius) {\n                            dftMat.put(dy, dx, 0.0, 0.0)\n                        }\n                    }\n                }\n            }\n        }\n\n        val planes = mutableListOf<Mat>()\n        Core.split(dftMat, planes)\n        val mag = Mat()\n        Core.magnitude(planes[0], planes[1], mag)\n\n        Core.add(mag, Scalar.all(1.0), mag)\n        Core.log(mag, mag)\n        Core.normalize(mag, mag, 0.0, 255.0, Core.NORM_MINMAX)\n        mag.convertTo(mag, CvType.CV_8U)\n\n        val center = Point(ccol.toDouble(), crow.toDouble())\n        val threshold = 180.0\n        val peaks = mutableListOf<Point>()\n\n        for (y in 0 until rows) {\n            for (x in 0 until cols) {\n                val value = mag.get(y, x)[0]\n                if (value > threshold) {\n                    val dx = x - center.x\n                    val dy = y - center.y\n                    if (abs(dx) > 10 || abs(dy) > 10) {\n                        peaks.add(Point(x.toDouble(), y.toDouble()))\n                    }\n                }\n            }\n        }\n\n        Log.d(\"Moire\", \"Masking ${peaks.size} peaks for $type\")\n\n        for (peak in peaks) {\n            val dx = peak.x - center.x\n            val dy = peak.y - center.y\n            val angle = atan2(dy, dx) * 180.0 / Math.PI\n\n            val matched = when (type) {\n                MoireType.VERTICAL -> abs(angle) !in 15.0..165.0\n                MoireType.HORIZONTAL -> abs(angle - 90) < 15 || abs(angle + 90) < 15\n                MoireType.RIGHT_DIAGONAL -> abs(angle - 45) < 15 || abs(angle + 135) < 15\n                MoireType.LEFT_DIAGONAL -> abs(angle + 45) < 15 || abs(angle - 135) < 15\n            }\n\n            if (matched) {\n                suppressCircle(peak.x.toInt(), peak.y.toInt())\n            }\n        }\n    }\n\n    private fun shiftDFT(mat: Mat) {\n        val cx = mat.cols() / 2\n        val cy = mat.rows() / 2\n\n        val q0 = Mat(mat, Rect(0, 0, cx, cy))        // Top-Left\n        val q1 = Mat(mat, Rect(cx, 0, cx, cy))       // Top-Right\n        val q2 = Mat(mat, Rect(0, cy, cx, cy))       // Bottom-Left\n        val q3 = Mat(mat, Rect(cx, cy, cx, cy))      // Bottom-Right\n\n        val tmp = Mat()\n        q0.copyTo(tmp)\n        q3.copyTo(q0)\n        tmp.copyTo(q3)\n\n        q1.copyTo(tmp)\n        q2.copyTo(q1)\n        tmp.copyTo(q2)\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/moire/model/MoireType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.moire.model\n\nenum class MoireType {\n    AUTO,\n    VERTICAL,\n    HORIZONTAL,\n    RIGHT_DIAGONAL,\n    LEFT_DIAGONAL\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/qr_prepare/QrPrepareHelper.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.qr_prepare\n\nimport android.graphics.Bitmap\nimport androidx.core.graphics.createBitmap\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport org.opencv.android.Utils\nimport org.opencv.core.Mat\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\n\nobject QrPrepareHelper : OpenCV() {\n\n    fun prepareQrForDecode(bitmap: Bitmap): Bitmap {\n        // 1. Bitmap -> Mat\n        val src = Mat()\n        Utils.bitmapToMat(bitmap, src)\n\n        // 2. В grayscale\n        val gray = Mat()\n        Imgproc.cvtColor(src, gray, Imgproc.COLOR_RGBA2GRAY)\n\n        // 3. CLAHE для локального контраста\n        val claheMat = Mat()\n        val clahe = Imgproc.createCLAHE()\n        clahe.clipLimit = 2.0\n        clahe.tilesGridSize = Size(8.0, 8.0)\n        clahe.apply(gray, claheMat)\n\n        // 4. Глобальная бинаризация через Otsu (полностью заливает модули)\n        val binary = Mat()\n        Imgproc.threshold(\n            claheMat,\n            binary,\n            0.0,\n            255.0,\n            Imgproc.THRESH_BINARY or Imgproc.THRESH_OTSU\n        )\n\n        // 5. Морфология для устранения дырок\n        val kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, Size(3.0, 3.0))\n        Imgproc.morphologyEx(binary, binary, Imgproc.MORPH_CLOSE, kernel)\n\n        // 6. Конвертируем в Bitmap\n        val result = createBitmap(binary.cols(), binary.rows())\n        Imgproc.cvtColor(binary, binary, Imgproc.COLOR_GRAY2RGBA)\n        Utils.matToBitmap(binary, result)\n\n        // 7. Освобождаем память\n        src.release()\n        gray.release()\n        claheMat.release()\n        binary.release()\n\n        return result\n    }\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/red_eye/RedEyeRemover.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.red_eye\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Core\nimport org.opencv.core.CvType\nimport org.opencv.core.Mat\nimport org.opencv.core.MatOfRect\nimport org.opencv.core.Point\nimport org.opencv.core.Rect\nimport org.opencv.core.Scalar\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\nimport org.opencv.objdetect.CascadeClassifier\nimport java.io.File\nimport java.io.FileOutputStream\n\nobject RedEyeRemover : OpenCV() {\n\n    fun removeRedEyes(\n        bitmap: Bitmap,\n        minEyeSize: Double = 50.0,\n        redThreshold: Double = 150.0\n    ): Bitmap {\n        val srcMat = bitmap.toMat()\n\n        Imgproc.cvtColor(srcMat, srcMat, Imgproc.COLOR_RGBA2BGR)\n        val resultMat = srcMat.clone()\n\n        val grayMat = Mat()\n        Imgproc.cvtColor(srcMat, grayMat, Imgproc.COLOR_BGR2GRAY)\n\n        val eyes = MatOfRect()\n\n        loadCascade().detectMultiScale(\n            grayMat, eyes,\n            1.3, 4, 0,\n            Size(minEyeSize, minEyeSize), Size()\n        )\n\n        for (rect in eyes.toArray()) {\n            val roi = Rect(rect.x, rect.y, rect.width, rect.height)\n            val eyeMat = srcMat.submat(roi).clone()\n\n            val channels = ArrayList<Mat>()\n            Core.split(eyeMat, channels)\n            val blue = channels[0]\n            val green = channels[1]\n            val red = channels[2]\n\n            val bg = Mat()\n            Core.add(blue, green, bg)\n\n            val maskRed = Mat()\n            Imgproc.threshold(red, maskRed, redThreshold, 255.0, Imgproc.THRESH_BINARY)\n\n            val maskCmp = Mat()\n            Core.compare(red, bg, maskCmp, Core.CMP_GT)\n\n            val redEyeMask = Mat()\n            Core.bitwise_and(maskRed, maskCmp, redEyeMask)\n\n            val filledMask = fillHoles(redEyeMask)\n            val dilatedMask = Mat()\n            Imgproc.dilate(filledMask, dilatedMask, Mat(), Point(-1.0, -1.0), 3)\n\n            val meanMat = Mat()\n            Core.divide(bg, Scalar(2.0), meanMat)\n\n            val mean3 = Mat()\n            Core.merge(listOf(meanMat, meanMat, meanMat), mean3)\n\n            val eyeOut = eyeMat.clone()\n            mean3.copyTo(eyeOut, dilatedMask)\n\n            eyeOut.copyTo(resultMat.submat(roi))\n        }\n\n        Imgproc.cvtColor(resultMat, resultMat, Imgproc.COLOR_BGR2RGBA)\n\n        return resultMat.toBitmap()\n    }\n\n    private fun fillHoles(mask: Mat): Mat {\n        val maskFloodfill = mask.clone()\n        val rows = maskFloodfill.rows()\n        val cols = maskFloodfill.cols()\n        val floodfillMask = Mat.zeros(rows + 2, cols + 2, CvType.CV_8UC1)\n        Imgproc.floodFill(maskFloodfill, floodfillMask, Point(0.0, 0.0), Scalar(255.0))\n        val maskInv = Mat()\n        Core.bitwise_not(maskFloodfill, maskInv)\n        val filledMask = Mat()\n        Core.bitwise_or(maskInv, mask, filledMask)\n        return filledMask\n    }\n\n    private fun loadCascade(): CascadeClassifier {\n        val inputStream = context.assets.open(EYE_DETECTION)\n        val cascadeFile = File(context.cacheDir, EYE_DETECTION)\n        FileOutputStream(cascadeFile).use { output ->\n            inputStream.copyTo(output)\n        }\n        return CascadeClassifier(cascadeFile.absolutePath)\n    }\n\n    private const val EYE_DETECTION = \"haarcascade_eye.xml\"\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/seam_carving/SeamCarver.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.seam_carving\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Core\nimport org.opencv.core.CvType\nimport org.opencv.core.Mat\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\nimport kotlin.math.min\n\nobject SeamCarver : OpenCV() {\n\n    /**\n     * Main entry:\n     * input: bitmap, desiredWidth, desiredHeight\n     * returns: processed Bitmap (content-aware reduced). If desired dimensions are larger than source,\n     * result will be upscaled with normal resizing after seam carving.\n     */\n    fun carve(bitmap: Bitmap, desiredWidth: Int, desiredHeight: Int): Bitmap {\n        var mat = bitmap.toMat()\n\n        val targetW = desiredWidth.coerceAtLeast(1)\n        val targetH = desiredHeight.coerceAtLeast(1)\n\n        // If target dims are bigger than current, we will only seam-carve to min(current, target) and then resize up.\n        val targetWClamp = min(targetW, mat.cols())\n        val targetHClamp = min(targetH, mat.rows())\n\n        // reduce width\n        while (mat.cols() > targetWClamp) {\n            val energy = computeEnergy(mat)\n            val seam = findVerticalSeam(energy)\n            mat = removeVerticalSeam(mat, seam)\n        }\n\n        // reduce height via transpose trick\n        mat = transposeMat(mat)\n        while (mat.cols() > targetHClamp) {\n            val energy = computeEnergy(mat)\n            val seam = findVerticalSeam(energy)\n            mat = removeVerticalSeam(mat, seam)\n        }\n        mat = transposeMat(mat)\n\n        // If the user requested larger dimensions than we could seam-carve to, upscale with interpolation.\n        val finalMat = if (mat.cols() != targetW || mat.rows() != targetH) {\n            val dst = Mat()\n            Imgproc.resize(\n                mat,\n                dst,\n                Size(targetW.toDouble(), targetH.toDouble()),\n                0.0,\n                0.0,\n                Imgproc.INTER_CUBIC\n            )\n            dst\n        } else {\n            mat\n        }\n\n        return finalMat.toBitmap()\n    }\n\n    private fun transposeMat(src: Mat): Mat {\n        val dst = Mat()\n        Core.transpose(src, dst)\n        return dst\n    }\n\n    /**\n     * Compute energy map using gradient magnitude (Sobel)\n     * returns Mat of type CV_64F with shape rows x cols\n     */\n    private fun computeEnergy(src: Mat): Mat {\n        val gray = Mat()\n        Imgproc.cvtColor(src, gray, Imgproc.COLOR_RGB2GRAY)\n        gray.convertTo(gray, CvType.CV_64F)\n\n        val gradX = Mat()\n        val gradY = Mat()\n        Imgproc.Sobel(gray, gradX, CvType.CV_64F, 1, 0, 3, 1.0, 0.0, Core.BORDER_DEFAULT)\n        Imgproc.Sobel(gray, gradY, CvType.CV_64F, 0, 1, 3, 1.0, 0.0, Core.BORDER_DEFAULT)\n\n        val gradXSq = Mat()\n        val gradYSq = Mat()\n        Core.multiply(gradX, gradX, gradXSq)\n        Core.multiply(gradY, gradY, gradYSq)\n\n        val energy = Mat()\n        Core.add(gradXSq, gradYSq, energy)\n        Core.sqrt(energy, energy) // sqrt(gx^2 + gy^2)\n        return energy\n    }\n\n    /**\n     * Find vertical seam (one pixel per row) with minimum cumulative energy.\n     * energy: CV_64F Mat.\n     * returns IntArray of length rows where each element is column index of seam in that row.\n     */\n    private fun findVerticalSeam(energy: Mat): IntArray {\n        val rows = energy.rows()\n        val cols = energy.cols()\n\n        // read energy into 2D double array\n        val e = Array(rows) { DoubleArray(cols) }\n        val buf = DoubleArray(cols)\n        for (r in 0 until rows) {\n            energy.get(r, 0, buf)\n            for (c in 0 until cols) e[r][c] = buf[c]\n        }\n\n        // dp cumulative energy\n        val dp = Array(rows) { DoubleArray(cols) { Double.POSITIVE_INFINITY } }\n        val backtrack = Array(rows) { IntArray(cols) }\n\n        // initialize first row\n        for (c in 0 until cols) dp[0][c] = e[0][c]\n\n        for (r in 1 until rows) {\n            for (c in 0 until cols) {\n                // consider three pixels from previous row\n                var minPrev = dp[r - 1][c]\n                var idx = c\n                if (c > 0 && dp[r - 1][c - 1] < minPrev) {\n                    minPrev = dp[r - 1][c - 1]; idx = c - 1\n                }\n                if (c < cols - 1 && dp[r - 1][c + 1] < minPrev) {\n                    minPrev = dp[r - 1][c + 1]; idx = c + 1\n                }\n                dp[r][c] = e[r][c] + minPrev\n                backtrack[r][c] = idx\n            }\n        }\n\n        // find min in last row\n        var minCol = 0\n        var minVal = dp[rows - 1][0]\n        for (c in 1 until cols) {\n            if (dp[rows - 1][c] < minVal) {\n                minVal = dp[rows - 1][c]\n                minCol = c\n            }\n        }\n\n        // reconstruct seam\n        val seam = IntArray(rows)\n        var cur = minCol\n        for (r in rows - 1 downTo 0) {\n            seam[r] = cur\n            if (r > 0) cur = backtrack[r][cur]\n        }\n        return seam\n    }\n\n    /**\n     * Remove vertical seam from src (3-channel RGB Mat) and return new Mat with cols-1.\n     */\n    private fun removeVerticalSeam(src: Mat, seam: IntArray): Mat {\n        val rows = src.rows()\n        val cols = src.cols()\n        val dst = Mat(rows, cols - 1, src.type())\n\n        // We'll copy row by row\n        val rowBuf = ByteArray(cols * src.channels())\n        val outBuf = ByteArray((cols - 1) * src.channels())\n\n        val channels = src.channels()\n\n        for (r in 0 until rows) {\n            src.get(r, 0, rowBuf)\n            val skipCol = seam[r]\n            var dstIdx = 0\n            var srcIdx = 0\n            for (c in 0 until cols) {\n                if (c == skipCol) {\n                    srcIdx += channels\n                    continue\n                }\n                // copy channels\n                for (ch in 0 until channels) {\n                    outBuf[dstIdx++] = rowBuf[srcIdx++]\n                }\n            }\n            dst.put(r, 0, outBuf)\n        }\n        return dst\n    }\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/spot_heal/SpotHealer.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.spot_heal\n\nimport android.graphics.Bitmap\nimport com.t8rin.opencv_tools.spot_heal.model.HealType\nimport com.t8rin.opencv_tools.utils.OpenCV\nimport com.t8rin.opencv_tools.utils.toBitmap\nimport com.t8rin.opencv_tools.utils.toMat\nimport org.opencv.core.Mat\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\nimport org.opencv.photo.Photo\n\nobject SpotHealer : OpenCV() {\n\n    fun heal(\n        image: Bitmap,\n        mask: Bitmap,\n        radius: Float,\n        type: HealType\n    ): Bitmap {\n        val src = image.toMat()\n        val inpaintMask = Mat()\n\n        Imgproc.resize(\n            mask.toMat(),\n            inpaintMask,\n            Size(image.width.toDouble(), image.height.toDouble())\n        )\n\n        Imgproc.cvtColor(src, src, Imgproc.COLOR_RGB2XYZ)\n        Imgproc.cvtColor(inpaintMask, inpaintMask, Imgproc.COLOR_BGR2GRAY)\n\n        val dst = Mat()\n\n        Photo.inpaint(\n            src,\n            inpaintMask,\n            dst,\n            radius.toDouble(),\n            type.ordinal\n        )\n\n        Imgproc.cvtColor(dst, dst, Imgproc.COLOR_XYZ2RGB)\n\n        return dst.toBitmap()\n    }\n\n\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/spot_heal/model/HealType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.opencv_tools.spot_heal.model\n\nenum class HealType {\n    NS, TELEA\n}"
  },
  {
    "path": "lib/opencv-tools/src/main/java/com/t8rin/opencv_tools/utils/OpenCVUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"unused\")\n\npackage com.t8rin.opencv_tools.utils\n\nimport android.app.Application\nimport android.graphics.Bitmap\nimport androidx.core.graphics.createBitmap\nimport org.opencv.android.OpenCVLoader\nimport org.opencv.android.Utils\nimport org.opencv.core.Core\nimport org.opencv.core.Mat\nimport org.opencv.core.Rect\nimport org.opencv.core.Scalar\nimport org.opencv.core.Size\nimport org.opencv.imgproc.Imgproc\n\nfun Bitmap.toMat(): Mat = Mat().apply {\n    Utils.bitmapToMat(copy(Bitmap.Config.ARGB_8888, false), this)\n}\n\nfun Mat.toBitmap(): Bitmap = createBitmap(cols(), rows()).apply {\n    Utils.matToBitmap(this@toBitmap, this)\n    release()\n}\n\nfun Mat.multiChannelMean(): Double =\n    Core.mean(this).`val`.average()\n\nfun Mat.singleChannelMean(): Double =\n    Core.mean(this).`val`.first()\n\nfun Mat.resizeAndCrop(targetSize: Size): Mat {\n    val aspectRatio = this.width().toDouble() / this.height()\n    val targetAspectRatio = targetSize.width / targetSize.height\n\n    val resizedMat = Mat()\n    if (aspectRatio > targetAspectRatio) {\n        val newWidth = (this.height() * targetAspectRatio).toInt()\n        Imgproc.resize(this, resizedMat, Size(newWidth.toDouble(), this.height().toDouble()))\n    } else {\n        val newHeight = (this.width() / targetAspectRatio).toInt()\n        Imgproc.resize(this, resizedMat, Size(this.width().toDouble(), newHeight.toDouble()))\n    }\n\n    val xOffset = (resizedMat.width() - targetSize.width).toInt() / 2\n    val yOffset = (resizedMat.height() - targetSize.height).toInt() / 2\n    return Mat(\n        resizedMat,\n        Rect(xOffset, yOffset, targetSize.width.toInt(), targetSize.height.toInt())\n    )\n}\n\nfun Mat.resizeAndPad(targetSize: Size): Mat {\n    val aspectRatio = this.width().toDouble() / this.height()\n    val targetAspectRatio = targetSize.width / targetSize.height\n\n    val resizedMat = Mat()\n    if (aspectRatio > targetAspectRatio) {\n        val newHeight = (targetSize.width / aspectRatio).toInt()\n        Imgproc.resize(this, resizedMat, Size(targetSize.width, newHeight.toDouble()))\n    } else {\n        val newWidth = (targetSize.height * aspectRatio).toInt()\n        Imgproc.resize(this, resizedMat, Size(newWidth.toDouble(), targetSize.height))\n    }\n\n    val paddedMat = Mat(targetSize, this.type(), Scalar(0.0, 0.0, 0.0))\n\n    resizedMat.copyTo(paddedMat.submat(Rect(0, 0, resizedMat.width(), resizedMat.height())))\n\n    return paddedMat\n}\n\nfun Int.toScalar(): Scalar {\n    val alpha = (this shr 24 and 0xFF).toDouble()\n    val red = (this shr 16 and 0xFF).toDouble()\n    val green = (this shr 8 and 0xFF).toDouble()\n    val blue = (this and 0xFF).toDouble()\n\n    return Scalar(red, green, blue, alpha)\n}\n\nabstract class OpenCV {\n    init {\n        OpenCVLoader.initLocal()\n    }\n\n    protected val context get() = application\n\n    companion object {\n        private var _context: Application? = null\n        internal val application: Application\n            get() = _context\n                ?: throw NullPointerException(\"Call OpenCV.init() in Application onCreate to use this feature\")\n\n        fun init(context: Application) {\n            _context = context\n        }\n    }\n}"
  },
  {
    "path": "lib/palette/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/palette/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n    kotlin(\"plugin.serialization\")\n}\n\nandroid.namespace = \"com.t8rin.palette\"\n\ndependencies {\n    implementation(libs.kotlinx.serialization.json)\n    testImplementation(kotlin(\"test\"))\n    testImplementation(libs.junit)\n}"
  },
  {
    "path": "lib/palette/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/ColorByteFormat.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\n/**\n * Byte ordering for RGB\n */\nenum class ColorByteFormat {\n    RGB,\n    BGR,\n    ARGB,\n    RGBA,\n    ABGR,\n    BGRA\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/ColorGroup.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nimport kotlinx.serialization.Serializable\nimport java.util.UUID\n\n/**\n * A grouping of colors\n */\n@Serializable\ndata class ColorGroup(\n    val id: String = UUID.randomUUID().toString(),\n    val name: String = \"\",\n    val colors: List<PaletteColor> = mutableListOf()\n)"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/ColorSpace.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nimport kotlinx.serialization.Serializable\n\n/**\n * Color space representation\n */\n@Serializable\nenum class ColorSpace {\n    CMYK,\n    RGB,\n    LAB,\n    Gray\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/ColorType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nimport kotlinx.serialization.Serializable\n\n/**\n * The type of the color (normal, spot, global)\n */\n@Serializable\nenum class ColorType {\n    Global,\n    Spot,\n    Normal\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/Palette.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nimport kotlinx.serialization.Serializable\nimport java.util.UUID\n\n/**\n * Color grouping within a palette\n */\nsealed class ColorGrouping {\n    object Global : ColorGrouping()\n    data class Group(val index: Int) : ColorGrouping()\n}\n\n/**\n * A color palette\n */\n@Serializable\ndata class Palette(\n    val name: String = \"\",\n    val colors: List<PaletteColor> = listOf(),\n    val groups: List<ColorGroup> = listOf()\n) {\n    val id: String = UUID.randomUUID().toString()\n\n    /**\n     * The total number of colors in the palette\n     */\n    val totalColorCount: Int\n        get() = colors.size + groups.sumOf { it.colors.size }\n\n    /**\n     * Returns all the groups for the palette. Global colors are represented in a group called 'global'\n     */\n    val allGroups: List<ColorGroup>\n        get() = listOf(ColorGroup(colors = colors, name = \"global\")) + groups\n\n    /**\n     * Returns all the colors in the palette as a flat array of colors (all group information is lost)\n     */\n    fun allColors(): List<PaletteColor> {\n        val results = colors.toMutableList()\n        groups.forEach { results.addAll(it.colors) }\n        return results\n    }\n\n    /**\n     * Find the first instance of a color by name within the palette\n     */\n    fun color(name: String, caseSensitive: Boolean = false): PaletteColor? {\n        return if (caseSensitive) {\n            allColors().firstOrNull { it.name == name }\n        } else {\n            val lowerName = name.lowercase()\n            allColors().firstOrNull { it.name.lowercase() == lowerName }\n        }\n    }\n\n    /**\n     * Return an array of colors for the specified palette group type\n     */\n    fun colors(groupType: ColorGrouping): List<PaletteColor> {\n        return when (groupType) {\n            is ColorGrouping.Global -> colors\n            is ColorGrouping.Group -> {\n                if (groupType.index >= 0 && groupType.index < groups.size) {\n                    groups[groupType.index].colors\n                } else {\n                    throw PaletteCoderException.IndexOutOfRange()\n                }\n            }\n        }\n    }\n\n    /**\n     * An index for a color within the palette\n     */\n    data class ColorIndex(\n        val group: ColorGrouping = ColorGrouping.Global,\n        val colorIndex: Int\n    )\n\n    /**\n     * Retrieve a color from the palette\n     */\n    fun color(group: ColorGrouping = ColorGrouping.Global, colorIndex: Int): PaletteColor {\n        return when (group) {\n            is ColorGrouping.Global -> {\n                if (colorIndex >= 0 && colorIndex < colors.size) {\n                    colors[colorIndex]\n                } else {\n                    throw PaletteCoderException.IndexOutOfRange()\n                }\n            }\n\n            is ColorGrouping.Group -> {\n                if (group.index >= 0 && group.index < groups.size &&\n                    colorIndex >= 0 && colorIndex < groups[group.index].colors.size\n                ) {\n                    groups[group.index].colors[colorIndex]\n                } else {\n                    throw PaletteCoderException.IndexOutOfRange()\n                }\n            }\n        }\n    }\n\n    /**\n     * Retrieve a color from the palette using ColorIndex\n     */\n    fun color(index: ColorIndex): PaletteColor {\n        return color(index.group, index.colorIndex)\n    }\n\n    /**\n     * Update a color\n     */\n    fun updateColor(\n        group: ColorGrouping = ColorGrouping.Global,\n        colorIndex: Int,\n        color: PaletteColor\n    ): Palette {\n        val builder = newBuilder()\n        when (group) {\n            is ColorGrouping.Global -> {\n                if (colorIndex >= 0 && colorIndex < colors.size) {\n                    builder.colors[colorIndex] = color\n                } else {\n                    throw PaletteCoderException.IndexOutOfRange()\n                }\n            }\n\n            is ColorGrouping.Group -> {\n                if (group.index >= 0 && group.index < groups.size &&\n                    colorIndex >= 0 && colorIndex < groups[group.index].colors.size\n                ) {\n                    builder.groups[group.index] = groups[group.index].copy(\n                        colors = colors.toMutableList().apply {\n                            set(colorIndex, color)\n                        }\n                    )\n                } else {\n                    throw PaletteCoderException.IndexOutOfRange()\n                }\n            }\n        }\n\n        return builder.build()\n    }\n\n    /**\n     * Update a color using ColorIndex\n     */\n    fun updateColor(index: ColorIndex, color: PaletteColor): Palette =\n        updateColor(index.group, index.colorIndex, color)\n\n    /**\n     * Returns a bucketed color for a time value mapped within an evenly spaced array of colors\n     */\n    fun bucketedColor(at: Double, type: ColorGrouping = ColorGrouping.Global): PaletteColor {\n        val colorList = colors(type)\n        if (colorList.isEmpty()) throw PaletteCoderException.TooFewColors()\n\n        val clampedT = at.coerceIn(0.0, 1.0)\n        val index = (clampedT * (colorList.size - 1)).toInt().coerceIn(0, colorList.size - 1)\n        return colorList[index]\n    }\n\n    /**\n     * Returns an interpolated color for a time value mapped within an evenly spaced array of colors\n     */\n    fun interpolatedColor(at: Double, type: ColorGrouping = ColorGrouping.Global): PaletteColor {\n        val colorList = colors(type)\n        if (colorList.isEmpty()) throw PaletteCoderException.TooFewColors()\n        if (colorList.size == 1) return colorList[0]\n\n        val clampedT = at.coerceIn(0.0, 1.0)\n        val position = clampedT * (colorList.size - 1)\n        val index = position.toInt().coerceIn(0, colorList.size - 2)\n        val fraction = position - index\n\n        val c1 = colorList[index]\n        val c2 = colorList[index + 1]\n\n        // Simple linear interpolation in RGB space\n        val rgb1 = c1.toRgb()\n        val rgb2 = c2.toRgb()\n\n        return PaletteColor.rgb(\n            r = rgb1.rf + (rgb2.rf - rgb1.rf) * fraction,\n            g = rgb1.gf + (rgb2.gf - rgb1.gf) * fraction,\n            b = rgb1.bf + (rgb2.bf - rgb1.bf) * fraction,\n            a = rgb1.af + (rgb2.af - rgb1.af) * fraction\n        )\n    }\n\n    companion object Companion {\n        /**\n         * Return a palette containing random colors\n         */\n        fun random(\n            count: Int,\n            colorSpace: ColorSpace = ColorSpace.RGB,\n            colorType: ColorType = ColorType.Global\n        ): Palette {\n            require(count > 0) { \"Count must be greater than 0\" }\n            return Palette(\n                colors = (0 until count).map {\n                    PaletteColor.random(\n                        colorSpace = colorSpace,\n                        colorType = colorType,\n                        name = \"Color_$it\"\n                    )\n                }.toMutableList()\n            )\n        }\n\n        /**\n         * Create a palette by interpolating between two colors\n         */\n        fun interpolated(\n            startColor: PaletteColor,\n            endColor: PaletteColor,\n            count: Int,\n            useOkLab: Boolean = false,\n            name: String = \"\"\n        ): Palette {\n            require(count > 0) { \"Count must be greater than 0\" }\n\n            val colors = if (useOkLab) {\n                // TODO: Implement OkLab interpolation\n                simpleInterpolate(startColor, endColor, count)\n            } else {\n                simpleInterpolate(startColor, endColor, count)\n            }\n\n            return Palette(colors = colors.toMutableList(), name = name)\n        }\n\n        private fun simpleInterpolate(\n            start: PaletteColor,\n            end: PaletteColor,\n            count: Int\n        ): List<PaletteColor> {\n            val startRgb = start.toRgb()\n            val endRgb = end.toRgb()\n\n            return (0 until count).map { i ->\n                val t = if (count > 1) i / (count - 1.0) else 0.0\n                PaletteColor.rgb(\n                    r = startRgb.rf + (endRgb.rf - startRgb.rf) * t,\n                    g = startRgb.gf + (endRgb.gf - startRgb.gf) * t,\n                    b = startRgb.bf + (endRgb.bf - startRgb.bf) * t,\n                    a = startRgb.af + (endRgb.af - startRgb.af) * t\n                )\n            }\n        }\n    }\n\n    class Builder(\n        var name: String = \"\",\n        var colors: MutableList<PaletteColor> = mutableListOf(),\n        var groups: MutableList<ColorGroup> = mutableListOf()\n    ) {\n        fun build() = Palette(\n            name = name,\n            colors = colors,\n            groups = groups\n        )\n    }\n\n    fun newBuilder(): Builder = Builder(\n        name = name,\n        colors = colors.toMutableList(),\n        groups = groups.toMutableList()\n    )\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/PaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nimport android.content.Context\nimport android.net.Uri\nimport java.io.ByteArrayInputStream\nimport java.io.ByteArrayOutputStream\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Protocol for palette coders\n */\ninterface PaletteCoder {\n    /**\n     * Decode a palette from input stream\n     */\n    fun decode(input: InputStream): Palette\n\n    /**\n     * Encode a palette to output stream\n     */\n    fun encode(palette: Palette, output: OutputStream)\n}\n\n/**\n * Decode a palette from byte array\n */\nfun PaletteCoder.decode(data: ByteArray): Palette = decode(ByteArrayInputStream(data).buffered())\n\n/**\n * Encode a palette to byte array\n */\nfun PaletteCoder.encode(palette: Palette): ByteArray = ByteArrayOutputStream().use {\n    encode(palette, it)\n    it.toByteArray()\n}\n\ninline fun <T> PaletteCoder.use(action: PaletteCoder.() -> T): Result<T> = runCatching { action() }\n\nfun PaletteCoder.decode(uri: Uri, context: Context) =\n    decode(context.contentResolver.openInputStream(uri)!!)"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/PaletteCoderException.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nsealed class PaletteCoderException(message: String) : Throwable(message) {\n    class UnsupportedPaletteType : PaletteCoderException(\"Unsupported palette type\")\n    class InvalidFormat : PaletteCoderException(\"Invalid format\")\n    class InvalidASEHeader : PaletteCoderException(\"Invalid ASE header\")\n    class InvalidColorComponentCountForModelType :\n        PaletteCoderException(\"Invalid color component count for model type\")\n\n    class UnknownBlockType : PaletteCoderException(\"Unknown block type\")\n    class GroupAlreadyOpen : PaletteCoderException(\"Group already open\")\n    class GroupNotOpen : PaletteCoderException(\"Group not open\")\n    class UnsupportedColorSpace : PaletteCoderException(\"Unsupported color space\")\n    class InvalidVersion : PaletteCoderException(\"Invalid version\")\n    class InvalidBOM : PaletteCoderException(\"Invalid BOM\")\n    class NotImplemented : PaletteCoderException(\"Not implemented\")\n    class CannotCreateColor : PaletteCoderException(\"Cannot create color\")\n    class TooFewColors : PaletteCoderException(\"Too few colors\")\n    class IndexOutOfRange : PaletteCoderException(\"Index out of range\")\n\n    data class UnknownColorMode(val mode: String) :\n        PaletteCoderException(\"Unknown color mode: $mode\")\n\n    data class UnknownColorType(val type: Int) : PaletteCoderException(\"Unknown color type: $type\")\n    data class InvalidRGBHexString(val string: String) :\n        PaletteCoderException(\"Invalid RGB hex string: $string\")\n\n    data class InvalidRGBAHexString(val string: String) :\n        PaletteCoderException(\"Invalid RGBA hex string: $string\")\n\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/PaletteColor.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.core.graphics.ColorUtils\nimport com.t8rin.palette.utils.extractHexRGBA\nimport kotlinx.serialization.Serializable\nimport java.util.UUID\n\n/**\n * A color in the palette\n */\n@Serializable\ndata class PaletteColor(\n    val name: String = \"\",\n    val colorType: ColorType = ColorType.Global,\n    val colorSpace: ColorSpace,\n    val colorComponents: List<Double>,\n    val alpha: Double = 1.0\n) {\n    val id: String = UUID.randomUUID().toString()\n\n    init {\n        checkValidity()\n    }\n\n    /**\n     * Returns true if the underlying color structure is valid for its colorspace\n     */\n    val isValid: Boolean\n        get() = when (colorSpace) {\n            ColorSpace.CMYK -> colorComponents.size == 4\n            ColorSpace.RGB -> colorComponents.size == 3\n            ColorSpace.LAB -> colorComponents.size == 3\n            ColorSpace.Gray -> colorComponents.size == 1\n        }\n\n    /**\n     * Throws an error if the color is in an invalid state\n     */\n    fun checkValidity() {\n        if (!isValid) {\n            throw PaletteCoderException.InvalidColorComponentCountForModelType()\n        }\n    }\n\n    /**\n     * Convert to Jetpack Compose Color (ARGB Int)\n     */\n    fun toComposeColor(): Color {\n        return when (colorSpace) {\n            ColorSpace.RGB -> {\n                Color(\n                    red = colorComponents[0].coerceIn(0.0, 1.0).toFloat(),\n                    green = colorComponents[1].coerceIn(0.0, 1.0).toFloat(),\n                    blue = colorComponents[2].coerceIn(0.0, 1.0).toFloat(),\n                    alpha = alpha.coerceIn(0.0, 1.0).toFloat()\n                )\n            }\n\n            ColorSpace.CMYK -> {\n                // Convert CMYK to RGB\n                val c = colorComponents[0].coerceIn(0.0, 1.0).toFloat()\n                val m = colorComponents[1].coerceIn(0.0, 1.0).toFloat()\n                val y = colorComponents[2].coerceIn(0.0, 1.0).toFloat()\n                val k = colorComponents[3].coerceIn(0.0, 1.0).toFloat()\n\n                Color(\n                    red = (1f - c) * (1f - k),\n                    green = (1f - m) * (1f - k),\n                    blue = (1f - y) * (1f - k),\n                    alpha = alpha.coerceIn(0.0, 1.0).toFloat()\n                )\n            }\n\n            ColorSpace.Gray -> {\n                val gray = colorComponents[0].coerceIn(0.0, 1.0).toFloat()\n                val a = alpha.coerceIn(0.0, 1.0).toFloat()\n                Color(\n                    red = gray,\n                    green = gray,\n                    blue = gray,\n                    alpha = a\n                )\n            }\n\n            ColorSpace.LAB -> {\n                // Convert LAB to RGB (simplified)\n\n                Color(\n                    ColorUtils.LABToColor(\n                        colorComponents[0],\n                        colorComponents[1],\n                        colorComponents[2]\n                    )\n                ).copy(\n                    alpha = alpha.coerceIn(0.0, 1.0).toFloat()\n                )\n            }\n        }\n    }\n\n    /**\n     * Convert to ARGB Int\n     */\n    fun toArgb(): Int = toComposeColor().toArgb()\n\n    /**\n     * Create from ARGB Int\n     */\n    companion object Companion {\n        /**\n         * Create RGB color\n         */\n        fun rgb(\n            r: Double,\n            g: Double,\n            b: Double,\n            a: Double = 1.0,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            return PaletteColor(\n                name = name,\n                colorType = colorType,\n                colorSpace = ColorSpace.RGB,\n                colorComponents = listOf(\n                    r.coerceIn(0.0, 1.0),\n                    g.coerceIn(0.0, 1.0),\n                    b.coerceIn(0.0, 1.0)\n                ),\n                alpha = a.coerceIn(0.0, 1.0)\n            )\n        }\n\n        /**\n         * Create CMYK color\n         */\n        fun cmyk(\n            c: Double,\n            m: Double,\n            y: Double,\n            k: Double,\n            alpha: Double = 1.0,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            return PaletteColor(\n                name = name,\n                colorType = colorType,\n                colorSpace = ColorSpace.CMYK,\n                colorComponents = listOf(\n                    c.coerceIn(0.0, 1.0),\n                    m.coerceIn(0.0, 1.0),\n                    y.coerceIn(0.0, 1.0),\n                    k.coerceIn(0.0, 1.0)\n                ),\n                alpha = alpha.coerceIn(0.0, 1.0)\n            )\n        }\n\n        /**\n         * Create Gray color\n         */\n        fun gray(\n            white: Double,\n            alpha: Double = 1.0,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            return PaletteColor(\n                name = name,\n                colorType = colorType,\n                colorSpace = ColorSpace.Gray,\n                colorComponents = listOf(white.coerceIn(0.0, 1.0)),\n                alpha = alpha.coerceIn(0.0, 1.0)\n            )\n        }\n\n        /**\n         * Create LAB color\n         */\n        fun lab(\n            l: Double,\n            a: Double,\n            b: Double,\n            alpha: Double = 1.0,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            return PaletteColor(\n                name = name,\n                colorType = colorType,\n                colorSpace = ColorSpace.LAB,\n                colorComponents = listOf(l, a, b),\n                alpha = alpha.coerceIn(0.0, 1.0)\n            )\n        }\n\n        /**\n         * Create HSB color (converts to RGB)\n         * @param hf Hue (0.0 ... 1.0)\n         * @param sf Saturation (0.0 ... 1.0)\n         * @param bf Brightness (0.0 ... 1.0)\n         */\n        fun hsb(\n            hf: Double,\n            sf: Double,\n            bf: Double,\n            alpha: Double = 1.0,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            val h = hf.coerceIn(0.0, 1.0)\n            val s = sf.coerceIn(0.0, 1.0)\n            val b = bf.coerceIn(0.0, 1.0)\n\n            // Convert HSB to RGB\n            val c = b * s\n            val x = c * (1 - kotlin.math.abs((h * 6) % 2 - 1))\n            val m = b - c\n\n            val (r, g, bl) = when {\n                h < 1.0 / 6 -> Triple(c, x, 0.0)\n                h < 2.0 / 6 -> Triple(x, c, 0.0)\n                h < 3.0 / 6 -> Triple(0.0, c, x)\n                h < 4.0 / 6 -> Triple(0.0, x, c)\n                h < 5.0 / 6 -> Triple(x, 0.0, c)\n                else -> Triple(c, 0.0, x)\n            }\n\n            return rgb(\n                r = (r + m).coerceIn(0.0, 1.0),\n                g = (g + m).coerceIn(0.0, 1.0),\n                b = (bl + m).coerceIn(0.0, 1.0),\n                a = alpha,\n                name = name,\n                colorType = colorType\n            )\n        }\n\n        /**\n         * Create HSL color (converts to RGB)\n         * @param hf Hue (0.0 ... 1.0)\n         * @param sf Saturation (0.0 ... 1.0)\n         * @param lf Lightness (0.0 ... 1.0)\n         */\n        fun hsl(\n            hf: Double,\n            sf: Double,\n            lf: Double,\n            alpha: Double = 1.0,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            val h = hf.coerceIn(0.0, 1.0)\n            val s = sf.coerceIn(0.0, 1.0)\n            val l = lf.coerceIn(0.0, 1.0)\n\n            // Convert HSL to RGB\n            val c = (1 - kotlin.math.abs(2 * l - 1)) * s\n            val x = c * (1 - kotlin.math.abs((h * 6) % 2 - 1))\n            val m = l - c / 2\n\n            val (r, g, b) = when {\n                h < 1.0 / 6 -> Triple(c, x, 0.0)\n                h < 2.0 / 6 -> Triple(x, c, 0.0)\n                h < 3.0 / 6 -> Triple(0.0, c, x)\n                h < 4.0 / 6 -> Triple(0.0, x, c)\n                h < 5.0 / 6 -> Triple(x, 0.0, c)\n                else -> Triple(c, 0.0, x)\n            }\n\n            return rgb(\n                r = (r + m).coerceIn(0.0, 1.0),\n                g = (g + m).coerceIn(0.0, 1.0),\n                b = (b + m).coerceIn(0.0, 1.0),\n                a = alpha,\n                name = name,\n                colorType = colorType\n            )\n        }\n\n        /**\n         * Create color with white (gray) value\n         */\n        fun white(\n            white: Double,\n            alpha: Double = 1.0,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            return gray(white, alpha, name, colorType)\n        }\n\n        /**\n         * Generate a random color\n         */\n        fun random(\n            colorSpace: ColorSpace = ColorSpace.RGB,\n            name: String = \"\",\n            colorType: ColorType = ColorType.Global\n        ): PaletteColor {\n            return when (colorSpace) {\n                ColorSpace.RGB -> rgb(\n                    r = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    g = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    b = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    name = name,\n                    colorType = colorType\n                )\n\n                ColorSpace.CMYK -> cmyk(\n                    c = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    m = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    y = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    k = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    name = name,\n                    colorType = colorType\n                )\n\n                ColorSpace.Gray -> gray(\n                    white = kotlin.random.Random.nextDouble(0.0, 1.0),\n                    name = name,\n                    colorType = colorType\n                )\n\n                ColorSpace.LAB -> throw PaletteCoderException.NotImplemented()\n            }\n        }\n    }\n\n    /**\n     * Return a copy with modified alpha\n     */\n    fun withAlpha(newAlpha: Double): PaletteColor {\n        return copy(alpha = newAlpha.coerceIn(0.0, 1.0))\n    }\n\n    /**\n     * Return a copy with modified name\n     */\n    fun named(newName: String): PaletteColor {\n        return copy(name = newName)\n    }\n\n    /**\n     * Convert color to another colorspace\n     */\n    fun converted(colorspace: ColorSpace): PaletteColor {\n        if (this.colorSpace == colorspace) return this\n\n        return when (colorspace) {\n            ColorSpace.CMYK -> {\n                val cmyk = toCmyk()\n                cmyk(\n                    c = cmyk.cf,\n                    m = cmyk.mf,\n                    y = cmyk.yf,\n                    k = cmyk.kf,\n                    alpha = cmyk.af,\n                    name = name,\n                    colorType = colorType\n                )\n            }\n\n            ColorSpace.RGB -> {\n                val rgb = toRgb()\n                rgb(\n                    r = rgb.rf,\n                    g = rgb.gf,\n                    b = rgb.bf,\n                    a = rgb.af,\n                    name = name,\n                    colorType = colorType\n                )\n            }\n\n            ColorSpace.LAB -> {\n                val lab = toLab()\n                lab(\n                    l = lab.l,\n                    a = lab.a,\n                    b = lab.b,\n                    alpha = lab.alpha,\n                    name = name,\n                    colorType = colorType\n                )\n            }\n\n            ColorSpace.Gray -> {\n                val rgb = toRgb()\n\n                val gray = 0.299 * rgb.rf + 0.587 * rgb.gf + 0.114 * rgb.bf\n                gray(\n                    white = gray,\n                    alpha = rgb.af,\n                    name = name,\n                    colorType = colorType\n                )\n            }\n        }\n    }\n\n    /**\n     * Convert color to RGB components\n     */\n    fun toRgb(): RGB {\n        return when (colorSpace) {\n            ColorSpace.RGB -> RGB(\n                r = colorComponents[0],\n                g = colorComponents[1],\n                b = colorComponents[2],\n                a = alpha\n            )\n\n            ColorSpace.CMYK -> {\n                val c = colorComponents[0]\n                val m = colorComponents[1]\n                val y = colorComponents[2]\n                val k = colorComponents[3]\n                RGB(\n                    r = (1.0 - c) * (1.0 - k),\n                    g = (1.0 - m) * (1.0 - k),\n                    b = (1.0 - y) * (1.0 - k),\n                    a = alpha\n                )\n            }\n\n            ColorSpace.Gray -> {\n                val gray = colorComponents[0]\n                RGB(r = gray, g = gray, b = gray, a = alpha)\n            }\n\n            ColorSpace.LAB -> {\n                val labToRgb = Color(\n                    ColorUtils.LABToColor(\n                        colorComponents[0],\n                        colorComponents[1],\n                        colorComponents[2]\n                    )\n                )\n                RGB(\n                    r = labToRgb.red.toDouble(),\n                    g = labToRgb.green.toDouble(),\n                    b = labToRgb.blue.toDouble(),\n                    a = alpha\n                )\n            }\n        }\n    }\n\n    /**\n     * Convert color to CMYK components\n     */\n    fun toCmyk(): CMYK {\n        val cmyk = if (colorSpace == ColorSpace.CMYK) {\n            this.colorComponents\n        } else {\n            val rgb = toRgb()\n            val r = rgb.rf\n            val g = rgb.gf\n            val b = rgb.bf\n\n            val k = 1.0 - maxOf(r, g, b)\n            val c = if (k < 1.0) (1.0 - r - k) / (1.0 - k) else 0.0\n            val m = if (k < 1.0) (1.0 - g - k) / (1.0 - k) else 0.0\n            val y = if (k < 1.0) (1.0 - b - k) / (1.0 - k) else 0.0\n\n            listOf(c, m, y, k)\n        }\n        return CMYK(\n            c = cmyk[0],\n            m = cmyk[1],\n            y = cmyk[2],\n            k = cmyk[3],\n            a = alpha\n        )\n    }\n\n    /**\n     * Convert color to LAB components\n     */\n    fun toLab(): LAB {\n        val lab = if (colorSpace == ColorSpace.LAB) this.colorComponents else {\n            val arr = DoubleArray(3)\n            ColorUtils.colorToLAB(toArgb(), arr)\n            arr.toList()\n        }\n        return LAB(\n            l = lab[0],\n            a = lab[1],\n            b = lab[2],\n            alpha = alpha\n        )\n    }\n\n    /**\n     * Convert color to HSB components\n     */\n    fun toHsb(): HSB {\n        val rgb = toRgb()\n        val r = rgb.rf\n        val g = rgb.gf\n        val b = rgb.bf\n\n        val max = maxOf(r, g, b)\n        val min = minOf(r, g, b)\n        val delta = max - min\n\n        val h = when {\n            delta == 0.0 -> 0.0\n            max == r -> ((g - b) / delta) % 6.0 * 60.0\n            max == g -> ((b - r) / delta + 2.0) * 60.0\n            else -> ((r - g) / delta + 4.0) * 60.0\n        }.let { if (it < 0) it + 360.0 else it } / 360.0\n\n        val s = if (max == 0.0) 0.0 else delta / max\n\n        return HSB(\n            h = h,\n            s = s,\n            b = max,\n            a = alpha\n        )\n    }\n\n    /**\n     * RGB color components\n     */\n    data class RGB(\n        val r: Double,\n        val g: Double,\n        val b: Double,\n        val a: Double = 1.0\n    ) {\n        val rf: Double get() = r.coerceIn(0.0, 1.0)\n        val gf: Double get() = g.coerceIn(0.0, 1.0)\n        val bf: Double get() = b.coerceIn(0.0, 1.0)\n        val af: Double get() = a.coerceIn(0.0, 1.0)\n\n        val r255: Int get() = (rf * 255).toInt()\n        val g255: Int get() = (gf * 255).toInt()\n        val b255: Int get() = (bf * 255).toInt()\n        val a255: Int get() = (af * 255).toInt()\n    }\n\n    /**\n     * CMYK color components\n     */\n    data class CMYK(\n        val c: Double,\n        val m: Double,\n        val y: Double,\n        val k: Double,\n        val a: Double = 1.0\n    ) {\n        val cf: Double get() = c.coerceIn(0.0, 1.0)\n        val mf: Double get() = m.coerceIn(0.0, 1.0)\n        val yf: Double get() = y.coerceIn(0.0, 1.0)\n        val kf: Double get() = k.coerceIn(0.0, 1.0)\n        val af: Double get() = a.coerceIn(0.0, 1.0)\n    }\n\n    /**\n     * LAB color components\n     */\n    data class LAB(\n        val l: Double,\n        val a: Double,\n        val b: Double,\n        val alpha: Double = 1.0\n    )\n\n    /**\n     * HSB color components\n     */\n    data class HSB(\n        val h: Double,\n        val s: Double,\n        val b: Double,\n        val a: Double = 1.0\n    ) {\n        val hf: Double get() = h.coerceIn(0.0, 1.0)\n        val sf: Double get() = s.coerceIn(0.0, 1.0)\n        val bf: Double get() = b.coerceIn(0.0, 1.0)\n        val af: Double get() = a.coerceIn(0.0, 1.0)\n    }\n}\n\n/**\n * Create from hex string\n */\nfun PaletteColor(\n    rgbHexString: String,\n    format: ColorByteFormat = ColorByteFormat.RGBA,\n    name: String = \"\",\n    colorType: ColorType = ColorType.Normal\n): PaletteColor {\n    val rgb = extractHexRGBA(rgbHexString, format)\n        ?: throw PaletteCoderException.InvalidRGBHexString(rgbHexString)\n\n    return PaletteColor(\n        name = name,\n        colorType = colorType,\n        colorSpace = ColorSpace.RGB,\n        colorComponents = listOf(rgb.rf, rgb.gf, rgb.bf),\n        alpha = rgb.af\n    )\n}\n\n/**\n * Create from CMYK hex string\n */\nfun PaletteColor(\n    cmykHexString: String,\n    name: String = \"\",\n    colorType: ColorType = ColorType.Normal\n): PaletteColor {\n    var hex = cmykHexString.lowercase().replace(Regex(\"[^0-9a-f]\"), \"\")\n    if (hex.startsWith(\"0x\") || hex.startsWith(\"#\")) {\n        hex = hex.substring(2)\n    }\n    if (hex.startsWith(\"#\")) {\n        hex = hex.substring(1)\n    }\n\n    if (hex.length != 8) {\n        throw PaletteCoderException.InvalidFormat()\n    }\n\n    val `val` = hex.toLongOrNull(16) ?: throw PaletteCoderException.InvalidFormat()\n\n    val c = ((`val` shr 24) and 0xFF) / 255.0\n    val m = ((`val` shr 16) and 0xFF) / 255.0\n    val y = ((`val` shr 8) and 0xFF) / 255.0\n    val k = (`val` and 0xFF) / 255.0\n\n    return PaletteColor(\n        name = name,\n        colorType = colorType,\n        colorSpace = ColorSpace.CMYK,\n        colorComponents = listOf(c, m, y, k),\n        alpha = 1.0\n    )\n}\n\n/**\n * Create from CMYK hex string\n */\nfun PaletteColor(\n    color: Color,\n    name: String = \"\",\n    colorType: ColorType = ColorType.Global\n): PaletteColor = PaletteColor(\n    name = name,\n    colorType = colorType,\n    colorSpace = ColorSpace.RGB,\n    colorComponents = listOf(\n        color.red.toDouble(),\n        color.green.toDouble(),\n        color.blue.toDouble()\n    ),\n    alpha = color.alpha.toDouble()\n)\n\n/**\n * Create PaletteColor from Jetpack Compose Color\n */\nfun Color.toPaletteColor(\n    name: String = \"\",\n    colorType: ColorType = ColorType.Global\n): PaletteColor = PaletteColor(\n    color = this,\n    name = name,\n    colorType = colorType\n)"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/PaletteFormat.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette\n\nimport com.t8rin.palette.coders.PaletteFormatCoder\n\n/**\n * Supported palette formats\n */\nenum class PaletteFormat(\n    val fileExtension: List<String>,\n    val withPaletteName: Boolean\n) {\n    ACB(\n        fileExtension = listOf(\"acb\"),\n        withPaletteName = true\n    ), // Adobe Color Book\n\n    ACO(\n        fileExtension = listOf(\"aco\"),\n        withPaletteName = true\n    ), // Adobe Photoshop Swatch\n\n    ACT(\n        fileExtension = listOf(\"act\"),\n        withPaletteName = false\n    ), // Adobe Color Tables\n\n    ANDROID_XML(\n        fileExtension = listOf(\"xml\"),\n        withPaletteName = false\n    ), // Android XML Palette file\n\n    ASE(\n        fileExtension = listOf(\"ase\"),\n        withPaletteName = true\n    ), // Adobe Swatch Exchange\n\n    BASIC_XML(\n        fileExtension = listOf(\"xml\"),\n        withPaletteName = true\n    ), // Basic XML palette format\n\n    COREL_PAINTER(\n        fileExtension = listOf(\"txt\"),\n        withPaletteName = false\n    ), // Corel Painter Swatches\n\n    COREL_DRAW(\n        fileExtension = listOf(\"xml\"),\n        withPaletteName = true\n    ), // CorelDraw XML\n\n    SCRIBUS_XML(\n        fileExtension = listOf(\"xml\"),\n        withPaletteName = true\n    ), // Scribus XML swatches\n\n    COREL_PALETTE(\n        fileExtension = listOf(\"cpl\"),\n        withPaletteName = true\n    ), // Corel Palette\n\n    CSV(\n        fileExtension = listOf(\"csv\"),\n        withPaletteName = false\n    ), // CSV Palette\n\n    DCP(\n        fileExtension = listOf(\"dcp\"),\n        withPaletteName = true\n    ), // ColorPaletteCodable binary format\n\n    GIMP(\n        fileExtension = listOf(\"gpl\"),\n        withPaletteName = true\n    ), // GIMP gpl format\n\n    HEX_RGBA(\n        fileExtension = listOf(\"hex\"),\n        withPaletteName = false\n    ), // Hex RGBA coded files\n\n    IMAGE(\n        fileExtension = listOf(\"png\", \"jpg\", \"jpeg\"),\n        withPaletteName = false\n    ), // image-based palette coder\n\n    JSON(\n        fileExtension = listOf(\"jsoncolorpalette\", \"json\"),\n        withPaletteName = true\n    ), // ColorPaletteCodable JSON format\n\n    OPEN_OFFICE(\n        fileExtension = listOf(\"soc\"),\n        withPaletteName = false\n    ), // OpenOffice palette format (.soc)\n\n    PAINT_NET(\n        fileExtension = listOf(\"txt\"),\n        withPaletteName = true\n    ), // Paint.NET palette file (.txt)\n\n    PAINT_SHOP_PRO(\n        fileExtension = listOf(\"psppalette\", \"pal\"),\n        withPaletteName = true\n    ), // Paint Shop Pro palette (.pal, .psppalette)\n\n    RGBA(\n        fileExtension = listOf(\"rgba\", \"txt\"),\n        withPaletteName = false\n    ), // RGBA encoded text files (.rgba, .txt)\n\n    RGB(\n        fileExtension = listOf(\"rgb\", \"txt\"),\n        withPaletteName = false\n    ), // RGB encoded text files (.rgb, .txt)\n\n    RIFF(\n        fileExtension = listOf(\"pal\"),\n        withPaletteName = false\n    ), // Microsoft RIFF palette (.pal)\n\n    SKETCH(\n        fileExtension = listOf(\"sketchpalette\"),\n        withPaletteName = false\n    ), // Sketch palette file (.sketchpalette)\n\n    SKP(\n        fileExtension = listOf(\"skp\"),\n        withPaletteName = false\n    ), // SKP Palette\n\n    SVG(\n        fileExtension = listOf(\"svg\"),\n        withPaletteName = true\n    ), // Scalable Vector Graphics palette (.svg)\n\n    SWIFT(\n        fileExtension = listOf(\"swift\"),\n        withPaletteName = true\n    ), // (export only) Swift source file (.swift)\n\n    KOTLIN(\n        fileExtension = listOf(\"kt\"),\n        withPaletteName = true\n    ), // (export only) Kotlin/Jetpack Compose source file (.kt)\n\n    COREL_DRAW_V3(\n        fileExtension = listOf(\"pal\"),\n        withPaletteName = true\n    ), // Corel Draw V3 file (.pal)\n\n    CLF(\n        fileExtension = listOf(\"clf\"),\n        withPaletteName = true\n    ), // LAB colors\n\n    SWATCHES(\n        fileExtension = listOf(\"swatches\"),\n        withPaletteName = true\n    ), // Procreate swatches\n\n    AUTODESK_COLOR_BOOK(\n        fileExtension = listOf(\"acb\"),\n        withPaletteName = true\n    ), // Autodesk Color Book (unencrypted only) (.acb)\n\n    SIMPLE_PALETTE(\n        fileExtension = listOf(\"color-palette\"),\n        withPaletteName = true\n    ), // Simple Palette format\n\n    SWATCHBOOKER(\n        fileExtension = listOf(\"sbz\"),\n        withPaletteName = true\n    ), // Swatchbooker .sbz file\n\n    AFPALETTE(\n        fileExtension = listOf(\"afpalette\"),\n        withPaletteName = true\n    ), // Affinity Designer .afpalette file\n\n    XARA(\n        fileExtension = listOf(\"jcw\"),\n        withPaletteName = true\n    ), // Xara palette file (.jcw)\n\n    KOFFICE(\n        fileExtension = listOf(\"colors\"),\n        withPaletteName = false\n    ), // KOffice palette file (.colors)\n\n    HPL(\n        fileExtension = listOf(\"hpl\"),\n        withPaletteName = true\n    ), // Homesite Palette file (.hpl)\n\n    SKENCIL(\n        fileExtension = listOf(\"spl\"),\n        withPaletteName = true\n    ), // Skencil Palette file (.spl)\n\n    VGA_24BIT(\n        fileExtension = listOf(\"vga24\"),\n        withPaletteName = false\n    ), // 24-bit RGB VGA (3 bytes RRGGBB)\n\n    VGA_18BIT(\n        fileExtension = listOf(\"vga18\"),\n        withPaletteName = false\n    ), // 18-bit RGB VGA (3 bytes RRGGBB)\n\n    KRITA(\n        fileExtension = listOf(\"kpl\"),\n        withPaletteName = true\n    ); // KRITA Palette file (.kpl)\n\n    companion object {\n        /**\n         * Get format from file extension\n         * Searches through all enum entries to find matching file extension\n         */\n        fun fromFilename(filename: String): PaletteFormat? =\n            PaletteFormat.entries.firstOrNull { format ->\n                format.fileExtension.isNotEmpty() && format.fileExtension.any(filename::endsWith)\n            }\n    }\n}\n\n/**\n * Get coder for format\n */\nfun PaletteFormat.getCoder(): PaletteCoder = PaletteFormatCoder(this)"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/ACBPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Adobe Color Book (ACB) palette coder (decode only)\n */\nclass ACBPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val parser = BytesReader(input)\n        val result = Palette.Builder()\n\n        // Check BOM \"8BCB\"\n        val bom = parser.readStringASCII(4)\n        if (bom != \"8BCB\") {\n            throw PaletteCoderException.InvalidBOM()\n        }\n\n        // Version\n        val version = parser.readUInt16(ByteOrder.BIG_ENDIAN)\n        if (version.toInt() != 1) {\n            // Log warning but continue\n        }\n\n        // Identifier\n        parser.readUInt16(ByteOrder.BIG_ENDIAN)\n\n        // Title\n        var title = parser.readAdobePascalStyleString()\n        if (title.startsWith(\"$$$\")) {\n            title = title.split(\"=\").lastOrNull() ?: title\n        }\n        result.name = title\n\n        // Prefix, suffix, description (skip)\n        parser.readAdobePascalStyleString()\n        parser.readAdobePascalStyleString()\n        parser.readAdobePascalStyleString()\n\n        // Color count\n        val colorCount = parser.readUInt16(ByteOrder.BIG_ENDIAN).toInt()\n\n        // Page size, page selector offset (skip)\n        parser.readUInt16(ByteOrder.BIG_ENDIAN)\n        parser.readUInt16(ByteOrder.BIG_ENDIAN)\n\n        // Color space\n        val colorSpace = parser.readUInt16(ByteOrder.BIG_ENDIAN).toInt()\n\n        val colorspace: ColorSpace\n        val componentCount: Int\n        when (colorSpace) {\n            0 -> { // RGB\n                colorspace = ColorSpace.RGB\n                componentCount = 3\n            }\n\n            2 -> { // CMYK\n                colorspace = ColorSpace.CMYK\n                componentCount = 4\n            }\n\n            7 -> { // LAB\n                colorspace = ColorSpace.LAB\n                componentCount = 3\n            }\n\n            8 -> { // Grayscale\n                colorspace = ColorSpace.Gray\n                componentCount = 1\n            }\n\n            else -> throw PaletteCoderException.UnsupportedColorSpace()\n        }\n\n        // Read colors\n        for (i in 0 until colorCount) {\n            val colorName = parser.readAdobePascalStyleString()\n            val colorCode = parser.readStringASCII(6)\n\n            // Color channels\n            val channels = parser.readBytes(componentCount)\n\n            if (colorName.trim().isEmpty() && colorCode.trim().isEmpty()) {\n                continue\n            }\n\n            val mapped = channels.map { it.toUByte().toDouble() }\n            val components: List<Double>\n\n            when (colorspace) {\n                ColorSpace.CMYK -> {\n                    components = listOf(\n                        ((255.0 - mapped[0]) / 255.0).coerceIn(0.0, 1.0),\n                        ((255.0 - mapped[1]) / 255.0).coerceIn(0.0, 1.0),\n                        ((255.0 - mapped[2]) / 255.0).coerceIn(0.0, 1.0),\n                        ((255.0 - mapped[3]) / 255.0).coerceIn(0.0, 1.0)\n                    )\n                }\n\n                ColorSpace.RGB -> {\n                    components = listOf(\n                        (mapped[0] / 255.0).coerceIn(0.0, 1.0),\n                        (mapped[1] / 255.0).coerceIn(0.0, 1.0),\n                        (mapped[2] / 255.0).coerceIn(0.0, 1.0)\n                    )\n                }\n\n                ColorSpace.LAB -> {\n                    components = listOf(\n                        mapped[0] / 2.55,   // 0...100\n                        mapped[1] - 128.0,  // -128...128\n                        mapped[2] - 128.0   // -128...128\n                    )\n                }\n\n                ColorSpace.Gray -> {\n                    components = listOf((mapped[0] / 255.0).coerceIn(0.0, 1.0))\n                }\n            }\n\n            try {\n                val color = PaletteColor(\n                    name = colorName,\n                    colorSpace = colorspace,\n                    colorComponents = components,\n                    alpha = 1.0\n                )\n                result.colors.add(color)\n            } catch (_: Throwable) {\n                // Skip invalid colors\n            }\n        }\n\n        // Spot identifier (may or may not be present)\n        try {\n            parser.readStringASCII(8)\n        } catch (_: Throwable) {\n            // Ignore if not present\n        }\n\n        return result.build()\n    }\n\n\n    @Suppress(\"VariableNeverRead\", \"AssignedValueIsNeverRead\")\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n        val allColors = palette.allColors()\n        val colorCount = allColors.size\n\n        if (colorCount == 0) {\n            throw PaletteCoderException.TooFewColors()\n        }\n\n        // Determine color space - use first color's space, or convert all to RGB\n        // ACB supports RGB (0), CMYK (2), LAB (7), Grayscale (8)\n        var targetColorSpace = allColors[0].colorSpace\n        var acbColorSpace: Int\n        var componentCount: Int\n\n        // Check if all colors can be in the same space, otherwise convert to RGB\n        val allSameSpace = allColors.all { it.colorSpace == targetColorSpace }\n        if (!allSameSpace || targetColorSpace !in listOf(\n                ColorSpace.RGB,\n                ColorSpace.CMYK,\n                ColorSpace.LAB,\n                ColorSpace.Gray\n            )\n        ) {\n            targetColorSpace = ColorSpace.RGB\n        }\n\n        when (targetColorSpace) {\n            ColorSpace.RGB -> {\n                acbColorSpace = 0\n                componentCount = 3\n            }\n\n            ColorSpace.CMYK -> {\n                acbColorSpace = 2\n                componentCount = 4\n            }\n\n            ColorSpace.LAB -> {\n                acbColorSpace = 7\n                componentCount = 3\n            }\n\n            ColorSpace.Gray -> {\n                acbColorSpace = 8\n                componentCount = 1\n            }\n        }\n\n        // BOM \"8BCB\" (4 bytes)\n        writer.writeStringASCII(\"8BCB\")\n\n        // Version (2 bytes, big endian) - typically 1\n        writer.writeUInt16(1u, ByteOrder.BIG_ENDIAN)\n\n        // Identifier (2 bytes, big endian) - typically 0\n        writer.writeUInt16(0u, ByteOrder.BIG_ENDIAN)\n\n        // Title (Adobe Pascal style string)\n        val title = palette.name.ifEmpty { \"Palette\" }\n        writer.writeAdobePascalStyleString(title)\n\n        // Prefix (Adobe Pascal style string) - empty\n        writer.writeAdobePascalStyleString(\"\")\n\n        // Suffix (Adobe Pascal style string) - empty\n        writer.writeAdobePascalStyleString(\"\")\n\n        // Description (Adobe Pascal style string) - empty\n        writer.writeAdobePascalStyleString(\"\")\n\n        // Color count (2 bytes, big endian)\n        writer.writeUInt16(colorCount.toUShort(), ByteOrder.BIG_ENDIAN)\n\n        // Page size (2 bytes, big endian) - typically 0\n        writer.writeUInt16(0u, ByteOrder.BIG_ENDIAN)\n\n        // Page selector offset (2 bytes, big endian) - typically 0\n        writer.writeUInt16(0u, ByteOrder.BIG_ENDIAN)\n\n        // Color space (2 bytes, big endian)\n        writer.writeUInt16(acbColorSpace.toUShort(), ByteOrder.BIG_ENDIAN)\n\n        // Write colors\n        allColors.forEach { color ->\n            // Convert color to target color space\n            val convertedColor = if (color.colorSpace == targetColorSpace) {\n                color\n            } else {\n                try {\n                    color.converted(targetColorSpace)\n                } catch (_: Throwable) {\n                    // Fallback: convert to RGB\n                    color.converted(ColorSpace.RGB)\n                }\n            }\n\n            // Color name (Adobe Pascal style string)\n            val colorName = convertedColor.name.ifEmpty { \"Color\" }\n            writer.writeAdobePascalStyleString(colorName)\n\n            // Color code (6 bytes ASCII) - typically empty or hex code\n            val hexCode = try {\n                val rgb = convertedColor.toRgb()\n                String.format(\n                    \"%02X%02X%02X\",\n                    (rgb.rf * 255).toInt().coerceIn(0, 255),\n                    (rgb.gf * 255).toInt().coerceIn(0, 255),\n                    (rgb.bf * 255).toInt().coerceIn(0, 255)\n                )\n            } catch (_: Throwable) {\n                \"000000\"\n            }\n            writer.writeStringASCII(hexCode.padEnd(6, '0').take(6))\n\n            // Color channels\n            val channels = when (targetColorSpace) {\n                ColorSpace.CMYK -> {\n                    // CMYK: 0 = 100% ink, so invert\n                    listOf(\n                        ((1.0 - convertedColor.colorComponents[0]) * 255).toInt().coerceIn(0, 255)\n                            .toByte(),\n                        ((1.0 - convertedColor.colorComponents[1]) * 255).toInt().coerceIn(0, 255)\n                            .toByte(),\n                        ((1.0 - convertedColor.colorComponents[2]) * 255).toInt().coerceIn(0, 255)\n                            .toByte(),\n                        ((1.0 - convertedColor.colorComponents[3]) * 255).toInt().coerceIn(0, 255)\n                            .toByte()\n                    )\n                }\n\n                ColorSpace.RGB -> {\n                    listOf(\n                        (convertedColor.colorComponents[0] * 255).toInt().coerceIn(0, 255).toByte(),\n                        (convertedColor.colorComponents[1] * 255).toInt().coerceIn(0, 255).toByte(),\n                        (convertedColor.colorComponents[2] * 255).toInt().coerceIn(0, 255).toByte()\n                    )\n                }\n\n                ColorSpace.LAB -> {\n                    listOf(\n                        (convertedColor.colorComponents[0] * 2.55).toInt().coerceIn(0, 255)\n                            .toByte(),\n                        ((convertedColor.colorComponents[1] + 128.0).toInt()\n                            .coerceIn(0, 255)).toByte(),\n                        ((convertedColor.colorComponents[2] + 128.0).toInt()\n                            .coerceIn(0, 255)).toByte()\n                    )\n                }\n\n                ColorSpace.Gray -> {\n                    listOf(\n                        (convertedColor.colorComponents[0] * 255).toInt().coerceIn(0, 255).toByte()\n                    )\n                }\n            }\n\n            writer.writeData(channels.toByteArray())\n        }\n    }\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/ACOPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.InputStream\nimport java.io.OutputStream\nimport kotlin.math.abs\n\n/**\n * Adobe Photoshop Swatch (ACO) palette coder\n */\nclass ACOPaletteCoder : PaletteCoder {\n    private enum class ACOColorspace(val rawValue: UShort) {\n        RGB(0u),\n        HSB(1u),\n        CMYK(2u),\n        LAB(7u),\n        GRAYSCALE(8u)\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val reader = BytesReader(input)\n        val result = Palette.Builder()\n\n        val v1Colors = mutableListOf<PaletteColor>()\n        val v2Colors = mutableListOf<PaletteColor>()\n\n        for (type in 1..2) {\n            try {\n                val version = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n                if (version.toInt() != type) {\n                    throw PaletteCoderException.InvalidVersion()\n                }\n            } catch (_: Throwable) {\n                // Version 1 file only\n                result.colors = v1Colors\n                return result.build()\n            }\n\n            val numberOfColors = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n\n            repeat(numberOfColors.toInt()) {\n                val colorSpace = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n                val c0 = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n                val c1 = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n                val c2 = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n                val c3 = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n\n                val name = if (type == 2) {\n                    reader.readAdobePascalStyleString()\n                } else {\n                    \"\"\n                }\n\n                val acoSpace = ACOColorspace.entries.find { it.rawValue == colorSpace }\n                val color = when (acoSpace) {\n                    ACOColorspace.RGB -> PaletteColor.rgb(\n                        r = c0.toDouble() / 65535.0,\n                        g = c1.toDouble() / 65535.0,\n                        b = c2.toDouble() / 65535.0,\n                        name = name\n                    )\n\n                    ACOColorspace.CMYK -> PaletteColor.cmyk(\n                        c = (65535 - c0.toInt()).toDouble() / 65535.0,\n                        m = (65535 - c1.toInt()).toDouble() / 65535.0,\n                        y = (65535 - c2.toInt()).toDouble() / 65535.0,\n                        k = (65535 - c3.toInt()).toDouble() / 65535.0,\n                        name = name\n                    )\n\n                    ACOColorspace.GRAYSCALE -> PaletteColor.gray(\n                        white = c0.toDouble() / 10000.0,\n                        name = name\n                    )\n\n                    ACOColorspace.LAB -> PaletteColor.lab(\n                        l = c0.toDouble() / 100.0,\n                        a = c1.toDouble() / 100.0,\n                        b = c2.toDouble() / 100.0,\n                        name = name\n                    )\n\n                    ACOColorspace.HSB -> {\n                        // Convert HSB to RGB\n                        val h = c0.toDouble() / 65535.0\n                        val s = c1.toDouble() / 65535.0\n                        val b = c2.toDouble() / 65535.0\n                        // Simple HSB to RGB conversion\n                        val rgb = hsbToRgb(h, s, b)\n                        PaletteColor.rgb(rgb.first, rgb.second, rgb.third, name = name)\n                    }\n\n                    null -> PaletteColor.rgb(1.0, 0.0, 0.0, 0.5, name = \"Unsupported Colorspace\")\n                }\n\n                if (type == 1) {\n                    v1Colors.add(color)\n                } else {\n                    v2Colors.add(color)\n                }\n            }\n        }\n\n        if (v2Colors.isNotEmpty()) {\n            result.colors = v2Colors\n        } else {\n            result.colors = v1Colors\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n        val allColors = palette.allColors()\n\n        // Write both v1 and v2\n        for (type in 1..2) {\n            writer.writeUInt16(type.toUShort(), ByteOrder.BIG_ENDIAN)\n            writer.writeUInt16(allColors.size.toUShort(), ByteOrder.BIG_ENDIAN)\n\n            allColors.forEach { color ->\n                val (c0, c1, c2, c3, acoModel) = when (color.colorSpace) {\n                    ColorSpace.RGB -> {\n                        val rgb = color.toRgb()\n                        Quad(\n                            (rgb.rf * 65535).toInt().toUShort(),\n                            (rgb.gf * 65535).toInt().toUShort(),\n                            (rgb.bf * 65535).toInt().toUShort(),\n                            0u,\n                            ACOColorspace.RGB\n                        )\n                    }\n\n                    ColorSpace.CMYK -> {\n                        Quad(\n                            (65535 - (color.colorComponents[0] * 65535).toInt()).toUShort(),\n                            (65535 - (color.colorComponents[1] * 65535).toInt()).toUShort(),\n                            (65535 - (color.colorComponents[2] * 65535).toInt()).toUShort(),\n                            (65535 - (color.colorComponents[3] * 65535).toInt()).toUShort(),\n                            ACOColorspace.CMYK\n                        )\n                    }\n\n                    ColorSpace.Gray -> {\n                        Quad(\n                            (color.colorComponents[0] * 10000).toInt().toUShort(),\n                            0u, 0u, 0u,\n                            ACOColorspace.GRAYSCALE\n                        )\n                    }\n\n                    ColorSpace.LAB -> {\n                        // Convert LAB to RGB for ACO\n                        val converted = color.converted(ColorSpace.RGB)\n                        val rgb = converted.toRgb()\n                        Quad(\n                            (rgb.rf * 65535).toInt().toUShort(),\n                            (rgb.gf * 65535).toInt().toUShort(),\n                            (rgb.bf * 65535).toInt().toUShort(),\n                            0u,\n                            ACOColorspace.RGB\n                        )\n                    }\n                }\n\n                writer.writeUInt16(acoModel.rawValue, ByteOrder.BIG_ENDIAN)\n                writer.writeUInt16(c0, ByteOrder.BIG_ENDIAN)\n                writer.writeUInt16(c1, ByteOrder.BIG_ENDIAN)\n                writer.writeUInt16(c2, ByteOrder.BIG_ENDIAN)\n                writer.writeUInt16(c3, ByteOrder.BIG_ENDIAN)\n\n                if (type == 2) {\n                    writer.writeAdobePascalStyleString(color.name)\n                }\n            }\n        }\n    }\n\n    private data class Quad(\n        val a: UShort,\n        val b: UShort,\n        val c: UShort,\n        val d: UShort,\n        val model: ACOColorspace\n    )\n\n    private fun hsbToRgb(h: Double, s: Double, b: Double): Triple<Double, Double, Double> {\n        val c = b * s\n        val x = c * (1 - abs((h * 6) % 2 - 1))\n        val m = b - c\n\n        val (r, g, bl) = when {\n            h < 1.0 / 6 -> Triple(c, x, 0.0)\n            h < 2.0 / 6 -> Triple(x, c, 0.0)\n            h < 3.0 / 6 -> Triple(0.0, c, x)\n            h < 4.0 / 6 -> Triple(0.0, x, c)\n            h < 5.0 / 6 -> Triple(x, 0.0, c)\n            else -> Triple(c, 0.0, x)\n        }\n\n        return Triple(r + m, g + m, bl + m)\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/ACTPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.nio.charset.StandardCharsets\n\n/**\n * Adobe Color Table (ACT) palette coder\n */\nclass ACTPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val allData = input.readBytes()\n        val reader = BytesReader(allData)\n        val result = Palette.Builder()\n\n        // Read 256 RGB colors (768 bytes)\n        repeat(256) {\n            val rgb = reader.readData(3)\n            val r = rgb[0].toUByte().toInt()\n            val g = rgb[1].toUByte().toInt()\n            val b = rgb[2].toUByte().toInt()\n            val color = PaletteColor.rgb(\n                r = r / 255.0,\n                g = g / 255.0,\n                b = b / 255.0\n            )\n            result.colors.add(color)\n        }\n\n        var numColors: Int\n        // Try to read number of colors (optional)\n        try {\n            val numColorsBytes = reader.readData(2)\n            numColors =\n                ((numColorsBytes[0].toUByte().toInt() shl 8) or numColorsBytes[1].toUByte()\n                    .toInt()).toShort().toInt()\n            if (numColors in 1..<256) {\n                result.colors = result.colors.take(numColors).toMutableList()\n            }\n        } catch (_: Throwable) {\n            // No number of colors field\n        }\n\n        // Try to read transparency index (optional)\n        try {\n            val alphaIndexBytes = reader.readData(2)\n            val alphaIndex =\n                ((alphaIndexBytes[0].toUByte().toInt() shl 8) or alphaIndexBytes[1].toUByte()\n                    .toInt()).toShort()\n            if (alphaIndex >= 0 && alphaIndex < result.colors.size) {\n                result.colors[alphaIndex.toInt()] = result.colors[alphaIndex.toInt()].withAlpha(0.0)\n            }\n        } catch (_: Throwable) {\n            // No transparency index field\n        }\n\n        // Try to read color names from extension (non-standard)\n        try {\n            val remainingData = allData.sliceArray(reader.readPosition.toInt() until allData.size)\n            val remainingText = String(remainingData, StandardCharsets.UTF_8)\n            val nameLine = remainingText.lines().find { it.startsWith(\"; ACT_NAMES:\") }\n            if (nameLine != null) {\n                val namesStr = nameLine.substring(\"; ACT_NAMES: \".length).trim()\n                val names = namesStr.split(\"|\")\n                names.forEachIndexed { index, name ->\n                    if (index < result.colors.size && name.isNotEmpty()) {\n                        result.colors[index] = result.colors[index].named(name)\n                    }\n                }\n            }\n        } catch (_: Throwable) {\n            // No names extension, continue without names\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n        val flattenedColors = palette.allColors().map { it.toRgb() }\n        val colors = flattenedColors.take(256)\n        val maxColors = colors.size\n\n        // Write 256 colors (pad with zeros if needed)\n        repeat(256) { index ->\n            if (index < maxColors) {\n                val c = colors[index]\n                writer.writeData(\n                    byteArrayOf(\n                        (c.rf * 255).toInt().coerceIn(0, 255).toByte(),\n                        (c.gf * 255).toInt().coerceIn(0, 255).toByte(),\n                        (c.bf * 255).toInt().coerceIn(0, 255).toByte()\n                    )\n                )\n            } else {\n                writer.writeData(byteArrayOf(0, 0, 0))\n            }\n        }\n\n        // Write number of colors if less than 256\n        if (maxColors < 256) {\n            writer.writeUInt16(maxColors.toUShort(), ByteOrder.BIG_ENDIAN)\n            writer.writeUInt16(0xFFFFu, ByteOrder.BIG_ENDIAN)\n        }\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/AFPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Affinity Designer Palette (AFPalette) coder — более терпимый парсер:\n * - пытается определить BOM в разных эндианах\n * - вместо жёсткой ошибки ищет маркеры в потоке\n * - при проблемах возвращает корректную ошибку\n */\nclass AFPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val allData = input.readBytes()\n        val parser = BytesReader(allData)\n        val result = Palette.Builder()\n\n        var hasUnsupportedColorType = false\n\n        // Helper: try both byte orders for a 4-byte ASCII marker\n        fun findMarkerAnyOrder(markerLE: ByteArray, markerBE: ByteArray): Int {\n            // findPattern returns index or -1\n            val idx1 = parser.findPattern(markerLE)\n            if (idx1 >= 0) return idx1\n            val idx2 = parser.findPattern(markerBE)\n            return idx2\n        }\n\n        // MARK: BOM / NClP\n        try {\n            // try BOM little-endian first\n            val startPos = parser.readPosition.toInt()\n            try {\n                val bom = parser.readUInt32(ByteOrder.LITTLE_ENDIAN).toInt()\n                if (bom != 0x414BFF00 && bom != 0x00FF4B41) {\n                    // not recognized -> fallthrough to searching markers\n                    parser.seekSet(startPos)\n                    throw Throwable(\"not bom\")\n                }\n                // ok — BOM accepted, continue from current position\n            } catch (_: Throwable) {\n                // try to find NClP marker in data (accept both byte orders)\n                parser.seekSet(0)\n                val nclpLE = byteArrayOf(0x4E, 0x43, 0x6C, 0x50) // 'NClP'\n                val nclpBE = byteArrayOf(0x50, 0x6C, 0x43, 0x4E) // reversed form sometimes used\n                val found = findMarkerAnyOrder(nclpLE, nclpBE)\n                if (found < 0) throw PaletteCoderException.InvalidBOM()\n                // position should be just after marker\n                parser.seekSet(found + 4)\n            }\n        } catch (e: PaletteCoderException) {\n            throw e\n        } catch (_: Throwable) {\n            throw PaletteCoderException.InvalidBOM()\n        }\n\n        // Now we expect NClP somewhere after current position.\n        // Ensure we're positioned right after an NClP-like marker.\n        try {\n            // If current bytes are not NClP, try to locate it from current pos\n            runCatching {\n                parser.readUInt32(ByteOrder.LITTLE_ENDIAN)\n                    .toInt()\n                parser.seekSet((parser.readPosition - 4).toInt())\n            }\n            // Simpler: just try to find marker from current pos\n            try {\n                parser.seekToNextInstanceOfPattern(0x4E, 0x43, 0x6C, 0x50) // 'NClP'\n                // move cursor to just after marker\n                parser.seek(4)\n            } catch (_: Throwable) {\n                // try reversed marker\n                try {\n                    parser.seekToNextInstanceOfPattern(0x50, 0x6C, 0x43, 0x4E)\n                    parser.seek(4)\n                } catch (_: Throwable) {\n                    // if we can't find it, it's invalid\n                    throw PaletteCoderException.InvalidFormat()\n                }\n            }\n        } catch (e: PaletteCoderException) {\n            throw e\n        }\n\n        // Filename length (uint32 little-endian) + name ASCII\n        val filenameLen = try {\n            parser.readUInt32(ByteOrder.LITTLE_ENDIAN).toInt()\n        } catch (_: Throwable) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n        val filename = try {\n            if (filenameLen <= 0) \"\" else parser.readStringASCII(filenameLen)\n        } catch (_: Throwable) {\n            \"\"\n        }\n        result.name = filename\n\n        // Найти VlaP (pattern can be in two byte orders)\n        try {\n            try {\n                parser.seekToNextInstanceOfPattern(0x56, 0x6C, 0x61, 0x50) // maybe reversed\n            } catch (_: Throwable) {\n                parser.seekToNextInstanceOfPattern(0x50, 0x61, 0x6C, 0x56) // other order\n            }\n            // position is at start of marker; move after it\n            parser.seek(4)\n        } catch (_: Throwable) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val colorCount = try {\n            parser.readUInt32(ByteOrder.LITTLE_ENDIAN).toInt()\n        } catch (_: Throwable) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val colors = mutableListOf<PaletteColor>()\n\n        for (index in 0 until colorCount) {\n            index + 1\n            try {\n                // Find \"rloC\" marker (either ASCII or bytes), then set cursor to start\n                try {\n                    parser.seekToNextInstanceOfASCII(\"rloC\")\n                } catch (_: Throwable) {\n                    // try bytes variant\n                    try {\n                        parser.seekToNextInstanceOfPattern(0x72, 0x6C, 0x6F, 0x43)\n                    } catch (_: Throwable) {\n                        // couldn't find marker for this color — break/handle\n                        if (colors.isEmpty()) throw PaletteCoderException.InvalidFormat()\n                        break\n                    }\n                }\n                // We're at start of \"rloC\"\n                // advance past marker\n                parser.seek(4)\n\n                // Safe skip 6 bytes if available (unknown data)\n                parser.trySkipBytes(6)\n\n                // Read color type (4 ASCII chars)\n                val colorType = try {\n                    parser.readStringASCII(4)\n                } catch (_: Throwable) {\n                    // cannot read type -> break\n                    if (colors.isEmpty()) throw PaletteCoderException.InvalidFormat()\n                    break\n                }\n\n                when (colorType) {\n                    \"ABGR\" -> {\n                        // Find \"Dloc_\" (marker) - accept ASCII search\n                        try {\n                            parser.seekToNextInstanceOfASCII(\"Dloc_\")\n                            parser.seek(5) // move after 'Dloc_'\n                        } catch (_: Throwable) {\n                            // if not found, continue — maybe values are right here\n                        }\n                        val r = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        val g = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        val b = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        colors.add(PaletteColor.rgb(r = r, g = g, b = b))\n                    }\n\n                    \"ABAL\" -> {\n                        try {\n                            parser.seekToNextInstanceOfASCII(\"<loc_\")\n                            parser.seek(5)\n                        } catch (_: Throwable) {\n                            // continue even if marker absent\n                        }\n                        val l = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt()\n                        val a = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt()\n                        val b = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt()\n                        val lab = PaletteColor.lab(\n                            l = l / 65535.0 * 100.0,\n                            a = a / 65535.0 * 256.0 - 128.0,\n                            b = b / 65535.0 * 256.0 - 128.0\n                        )\n                        colors.add(lab.converted(ColorSpace.RGB))\n                    }\n\n                    \"KYMC\" -> {\n                        try {\n                            parser.seekToNextInstanceOfASCII(\"Hloc_\"); parser.seek(5)\n                        } catch (_: Throwable) {\n                        }\n                        val c = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        val m = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        val y = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        val k = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        colors.add(PaletteColor.cmyk(c = c, m = m, y = y, k = k))\n                    }\n\n                    \"ALSH\" -> {\n                        try {\n                            parser.seekToNextInstanceOfASCII(\"Dloc_\"); parser.seek(5)\n                        } catch (_: Throwable) {\n                        }\n                        val h = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        val s = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        val l = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        colors.add(PaletteColor.hsl(hf = h, sf = s, lf = l))\n                    }\n\n                    \"YARG\" -> {\n                        try {\n                            parser.seekToNextInstanceOfASCII(\"<loc_\"); parser.seek(5)\n                        } catch (_: Throwable) {\n                        }\n                        val g1 = parser.readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n                        colors.add(PaletteColor.white(white = g1))\n                    }\n\n                    else -> {\n                        hasUnsupportedColorType = true\n                        throw PaletteCoderException.CannotCreateColor()\n                    }\n                }\n            } catch (_: PaletteCoderException) {\n                if (hasUnsupportedColorType) throw PaletteCoderException.UnsupportedPaletteType()\n                if (colors.isEmpty()) throw PaletteCoderException.InvalidFormat()\n                break\n            } catch (_: Throwable) {\n                if (colors.isEmpty()) throw PaletteCoderException.InvalidFormat()\n                break\n            }\n        }\n\n        // Read names section (VNaP) if present\n        try {\n            // try finding either order of VNaP\n            val vnapIdx = parser.findPattern(byteArrayOf(0x56, 0x4e, 0x61, 0x50)).takeIf { it >= 0 }\n                ?: parser.findPattern(byteArrayOf(0x50, 0x61, 0x4E, 0x56)).takeIf { it >= 0 }\n            if (vnapIdx != null) {\n                parser.seekSet(vnapIdx + 4)\n                // unknown offset\n                parser.readUInt32(ByteOrder.LITTLE_ENDIAN)\n                val nameCount = parser.readUInt32(ByteOrder.LITTLE_ENDIAN).toInt()\n                for (i in 0 until minOf(nameCount, colors.size)) {\n                    try {\n                        val colorNameLen = parser.readUInt32(ByteOrder.LITTLE_ENDIAN).toInt()\n                        val colorName = parser.readStringUTF8(colorNameLen)\n                        colors[i] = colors[i].copy(\n                            name = colorName\n                        )\n                    } catch (_: Throwable) {\n                        break\n                    }\n                }\n            }\n        } catch (_: Throwable) {\n            // ignore — names optional\n        }\n\n        if (colors.isEmpty()) throw PaletteCoderException.InvalidFormat()\n        result.colors = colors\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n        val allColors = palette.allColors()\n        val colorCount = allColors.size\n        if (colorCount == 0) throw PaletteCoderException.TooFewColors()\n\n        // BOM (как раньше), версия, и т.д.\n        writer.writeUInt32(0x414BFF00u, ByteOrder.LITTLE_ENDIAN)\n        writer.writeUInt32(11u, ByteOrder.LITTLE_ENDIAN)\n        writer.writePattern(0x50, 0x6C, 0x43, 0x4E) // NClP\n        val filename = palette.name.ifEmpty { \"Palette\" }\n        writer.writeStringASCIIWithLength(filename, ByteOrder.LITTLE_ENDIAN)\n        writer.writePattern(0x50, 0x61, 0x6C, 0x56) // VlaP\n        writer.writeUInt32(colorCount.toUInt(), ByteOrder.LITTLE_ENDIAN)\n\n        allColors.forEach { color ->\n            writer.writePattern(0x72, 0x6C, 0x6F, 0x43) // rloC\n            writer.writePattern(0x00, 0x00, 0x00, 0x00, 0x00, 0x00) // skip 6\n            writer.writePattern(0x41, 0x42, 0x47, 0x52) // ABGR\n            writer.writePattern(0x44, 0x6C, 0x6F, 0x63, 0x5F) // Dloc_\n            val rgb = color.toRgb()\n            writer.writeFloat32(rgb.rf.toFloat(), ByteOrder.LITTLE_ENDIAN)\n            writer.writeFloat32(rgb.gf.toFloat(), ByteOrder.LITTLE_ENDIAN)\n            writer.writeFloat32(rgb.bf.toFloat(), ByteOrder.LITTLE_ENDIAN)\n        }\n\n        writer.writePattern(0x50, 0x61, 0x4E, 0x56) // VNaP\n        writer.writeUInt32(0u, ByteOrder.LITTLE_ENDIAN)\n        writer.writeUInt32(colorCount.toUInt(), ByteOrder.LITTLE_ENDIAN)\n        allColors.forEach { color ->\n            val colorName = color.name.ifEmpty { \"Color\" }\n            writer.writeStringUTF8WithLength(colorName, ByteOrder.LITTLE_ENDIAN)\n        }\n    }\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/ASEPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.ColorType\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.ByteArrayOutputStream\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Adobe Swatch Exchange (ASE) palette coder\n */\nclass ASEPaletteCoder : PaletteCoder {\n    companion object {\n        private val ASE_HEADER_DATA = byteArrayOf(65, 83, 69, 70) // \"ASEF\"\n        private val ASE_GROUP_START: UShort = 0xC001u\n        private val ASE_GROUP_END: UShort = 0xC002u\n        private val ASE_BLOCK_COLOR: UShort = 0x0001u\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val reader = BytesReader(input)\n        val result = Palette.Builder()\n\n        // Read and validate header\n        val header = reader.readData(4)\n        if (!header.contentEquals(ASE_HEADER_DATA)) {\n            throw PaletteCoderException.InvalidASEHeader()\n        }\n\n        // Read version\n        val version0 = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n        val version1 = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n        if (version0.toUInt() != 1u || version1.toUInt() != 0u) {\n            // Unknown version, but continue\n        }\n\n        // Read number of blocks\n        val numberOfBlocks = reader.readUInt32(ByteOrder.BIG_ENDIAN)\n\n        var currentGroup: ColorGroup? = null\n\n        // Read all blocks\n        repeat(numberOfBlocks.toInt()) {\n            val type = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n            reader.readUInt32(ByteOrder.BIG_ENDIAN)\n\n            when (type) {\n                ASE_GROUP_START -> {\n                    if (currentGroup != null) {\n                        throw PaletteCoderException.GroupAlreadyOpen()\n                    }\n                    currentGroup = readStartGroupBlock(reader)\n                }\n\n                ASE_GROUP_END -> {\n                    if (currentGroup == null) {\n                        throw PaletteCoderException.GroupNotOpen()\n                    }\n                    result.groups.add(currentGroup)\n                    currentGroup = null\n                }\n\n                ASE_BLOCK_COLOR -> {\n                    val color = readColor(reader)\n                    if (currentGroup != null) {\n                        currentGroup = currentGroup.copy(\n                            colors = currentGroup.colors + color\n                        )\n                    } else {\n                        result.colors.add(color)\n                    }\n                }\n\n                else -> throw PaletteCoderException.UnknownBlockType()\n            }\n        }\n\n        // If there's still an open group, add it\n        if (currentGroup != null) {\n            result.groups.add(currentGroup)\n        }\n\n        return result.build()\n    }\n\n    private fun readStartGroupBlock(reader: BytesReader): ColorGroup {\n        reader.readUInt16(ByteOrder.BIG_ENDIAN)\n        val name = reader.readStringUTF16NullTerminated(ByteOrder.BIG_ENDIAN)\n        return ColorGroup(name = name)\n    }\n\n    private fun readColor(reader: BytesReader): PaletteColor {\n        reader.readUInt16(ByteOrder.BIG_ENDIAN)\n        val name = reader.readStringUTF16NullTerminated(ByteOrder.BIG_ENDIAN)\n\n        val colorModel = when (val mode = reader.readStringASCII(4)) {\n            \"CMYK\" -> ASEColorModel.CMYK\n            \"RGB \" -> ASEColorModel.RGB\n            \"LAB \" -> ASEColorModel.LAB\n            \"Gray\" -> ASEColorModel.Gray\n            else -> throw PaletteCoderException.UnknownColorMode(mode)\n        }\n\n        val colors: List<Double>\n        val colorspace: ColorSpace\n\n        when (colorModel) {\n            ASEColorModel.CMYK -> {\n                colorspace = ColorSpace.CMYK\n                colors = listOf(\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble(),\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble(),\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble(),\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble()\n                )\n            }\n\n            ASEColorModel.RGB -> {\n                colorspace = ColorSpace.RGB\n                colors = listOf(\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble(),\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble(),\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble()\n                )\n            }\n\n            ASEColorModel.LAB -> {\n                colorspace = ColorSpace.LAB\n                colors = listOf(\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble() * 100.0,\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble(),\n                    reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble()\n                )\n            }\n\n            ASEColorModel.Gray -> {\n                colorspace = ColorSpace.Gray\n                colors = listOf(reader.readFloat32(ByteOrder.BIG_ENDIAN).toDouble())\n            }\n        }\n\n        val colorTypeValue = reader.readUInt16(ByteOrder.BIG_ENDIAN)\n        val colorType = when (colorTypeValue.toInt()) {\n            0 -> ColorType.Global\n            1 -> ColorType.Spot\n            2 -> ColorType.Normal\n            else -> throw PaletteCoderException.UnknownColorType(colorTypeValue.toInt())\n        }\n\n        return PaletteColor(\n            colorSpace = colorspace,\n            colorComponents = colors,\n            name = name,\n            colorType = colorType\n        )\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n\n        // Write header\n        writer.writeData(ASE_HEADER_DATA)\n        writer.writeUInt16(1u, ByteOrder.BIG_ENDIAN)\n        writer.writeUInt16(0u, ByteOrder.BIG_ENDIAN)\n\n        var totalBlocks = palette.colors.size + (palette.groups.size * 2)\n        palette.groups.forEach { totalBlocks += it.colors.size }\n\n        writer.writeUInt32(totalBlocks.toUInt(), ByteOrder.BIG_ENDIAN)\n\n        // Write global colors\n        palette.colors.forEach { color ->\n            writeColorData(writer, color)\n        }\n\n        // Write groups\n        palette.groups.forEach { group ->\n            // Group header\n            writer.writeUInt16(ASE_GROUP_START, ByteOrder.BIG_ENDIAN)\n\n            val groupData = ByteArrayOutputStream()\n            val groupWriter = BytesWriter(groupData)\n            val groupNameBytes = group.name.toByteArray(java.nio.charset.StandardCharsets.UTF_16BE)\n            val groupNameLen = (group.name.length + 1).toUShort()\n            groupWriter.writeUInt16(groupNameLen, ByteOrder.BIG_ENDIAN)\n            if (groupNameBytes.isNotEmpty()) {\n                groupWriter.writeData(groupNameBytes)\n            }\n            groupWriter.writeData(byteArrayOf(0, 0)) // null terminator\n\n            writer.writeUInt32(groupData.size().toUInt(), ByteOrder.BIG_ENDIAN)\n            writer.writeData(groupData.toByteArray())\n\n            // Group colors\n            group.colors.forEach { color ->\n                writeColorData(writer, color)\n            }\n\n            // Group footer\n            writer.writeUInt16(ASE_GROUP_END, ByteOrder.BIG_ENDIAN)\n            writer.writeUInt32(0u, ByteOrder.BIG_ENDIAN)\n        }\n    }\n\n    private fun writeColorData(writer: BytesWriter, color: PaletteColor) {\n        writer.writeUInt16(ASE_BLOCK_COLOR, ByteOrder.BIG_ENDIAN)\n\n        val colorData = ByteArrayOutputStream()\n        val colorWriter = BytesWriter(colorData)\n\n        // Write name\n        val colorNameBytes = color.name.toByteArray(java.nio.charset.StandardCharsets.UTF_16BE)\n        val colorNameLen = (color.name.length + 1).toUShort()\n        colorWriter.writeUInt16(colorNameLen, ByteOrder.BIG_ENDIAN)\n        if (colorNameBytes.isNotEmpty()) {\n            colorWriter.writeData(colorNameBytes)\n        }\n        colorWriter.writeData(byteArrayOf(0, 0)) // null terminator\n\n        // Write model\n        val colorModel = when (color.colorSpace) {\n            ColorSpace.RGB -> ASEColorModel.RGB\n            ColorSpace.CMYK -> ASEColorModel.CMYK\n            ColorSpace.LAB -> ASEColorModel.LAB\n            ColorSpace.Gray -> ASEColorModel.Gray\n        }\n        colorWriter.writeStringASCII(colorModel.rawValue)\n\n        // Write components\n        when (color.colorSpace) {\n            ColorSpace.CMYK -> {\n                color.colorComponents.forEach { comp ->\n                    colorWriter.writeFloat32(comp.toFloat(), ByteOrder.BIG_ENDIAN)\n                }\n            }\n\n            ColorSpace.RGB -> {\n                color.colorComponents.forEach { comp ->\n                    colorWriter.writeFloat32(comp.toFloat(), ByteOrder.BIG_ENDIAN)\n                }\n            }\n\n            ColorSpace.LAB -> {\n                colorWriter.writeFloat32(\n                    (color.colorComponents[0] / 100.0).toFloat(),\n                    ByteOrder.BIG_ENDIAN\n                )\n                colorWriter.writeFloat32(color.colorComponents[1].toFloat(), ByteOrder.BIG_ENDIAN)\n                colorWriter.writeFloat32(color.colorComponents[2].toFloat(), ByteOrder.BIG_ENDIAN)\n            }\n\n            ColorSpace.Gray -> {\n                colorWriter.writeFloat32(color.colorComponents[0].toFloat(), ByteOrder.BIG_ENDIAN)\n            }\n        }\n\n        // Write color type\n        val colorTypeValue: UShort = when (color.colorType) {\n            ColorType.Global -> 0u\n            ColorType.Spot -> 1u\n            ColorType.Normal -> 2u\n        }\n        colorWriter.writeUInt16(colorTypeValue, ByteOrder.BIG_ENDIAN)\n\n        writer.writeUInt32(colorData.size().toUInt(), ByteOrder.BIG_ENDIAN)\n        writer.writeData(colorData.toByteArray())\n    }\n\n    private enum class ASEColorModel(val rawValue: String) {\n        CMYK(\"CMYK\"),\n        RGB(\"RGB \"),\n        LAB(\"LAB \"),\n        Gray(\"Gray\")\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/AndroidColorsXMLCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.xmlDecoded\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport javax.xml.parsers.SAXParserFactory\n\n/**\n * Android colors.xml palette coder\n */\nclass AndroidColorsXMLCoder(\n    private val includeAlphaDuringExport: Boolean = true\n) : PaletteCoder {\n\n    private class AndroidXMLHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n        private var currentElement = \"\"\n        private var currentName: String? = null\n        private var isInsideResourcesBlock = false\n        private var currentChars = StringBuilder()\n        private fun elementName(localName: String, qName: String?): String =\n            localName.ifBlank { qName ?: \"\" }.substringAfter(':').lowercase()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            when (elementName(localName, qName)) {\n                \"resources\" -> isInsideResourcesBlock = true\n                \"color\" -> {\n                    currentElement = \"color\"\n                    currentName = attributes.getValue(\"name\")?.xmlDecoded()\n                }\n            }\n        }\n\n        override fun endElement(uri: String?, localName: String, qName: String?) {\n            when (elementName(localName, qName)) {\n                \"resources\" -> isInsideResourcesBlock = false\n                \"color\" -> {\n                    if (isInsideResourcesBlock && currentElement == \"color\") {\n                        val colorString = currentChars.toString().trim()\n                        val colorName = currentName ?: \"color_${palette.colors.size}\"\n                        try {\n                            val color = PaletteColor(\n                                rgbHexString = colorString,\n                                format = ColorByteFormat.ARGB,\n                                name = colorName\n                            )\n                            palette.colors.add(color)\n                        } catch (_: Throwable) {\n                            // Skip invalid colors\n                        }\n                    }\n                    currentElement = \"\"\n                    currentName = null\n                }\n            }\n            currentChars.clear()\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val handler = AndroidXMLHandler()\n        val factory = SAXParserFactory.newInstance()\n        val parser = factory.newSAXParser()\n        parser.parse(input, handler)\n\n        if (handler.palette.colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return handler.palette.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var xml = \"\"\"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\"\"\"\n\n        palette.allColors().forEachIndexed { index, color ->\n            var name = color.name.ifEmpty { \"color_$index\" }\n            name = name.replace(\" \", \"_\").xmlEscaped()\n\n            val format = if (includeAlphaDuringExport) ColorByteFormat.ARGB else ColorByteFormat.RGB\n            val hex = color.hexString(format, hashmark = true, uppercase = true)\n\n            xml += \"   <color name=\\\"$name\\\">$hex</color>\\n\"\n        }\n\n        xml += \"</resources>\\n\"\n\n        output.write(xml.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/AutodeskColorBookCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.xmlDecoded\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.nio.charset.StandardCharsets\nimport javax.xml.parsers.SAXParserFactory\n\nclass AutodeskColorBookCoder : PaletteCoder {\n\n    private class AutodeskXMLHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n        private var currentGroup: ColorGroup? = null\n        private var colorName: String? = null\n        private var r: Int? = null\n        private var g: Int? = null\n        private var b: Int? = null\n        private val xmlStack = mutableListOf<String>()\n        private var currentChars = StringBuilder()\n\n        private fun elm(localName: String?, qName: String?) = (qName ?: localName ?: \"\").trim()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            val elementName = elm(localName, qName)\n            when (elementName.lowercase()) {\n                \"colorpage\" -> {\n                    val groupName = attributes.getValue(\"name\")?.xmlDecoded() ?: \"\"\n                    currentGroup = ColorGroup(name = groupName)\n                }\n\n                \"colorentry\", \"pagecolor\" -> {\n                    r = null; g = null; b = null; colorName = null\n                }\n            }\n            xmlStack.add(elementName)\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n\n        override fun endElement(uri: String?, localName: String, qName: String?) {\n            val elementName = elm(localName, qName)\n            val content = currentChars.toString().trim()\n            when (elementName.lowercase()) {\n                \"bookname\" -> if (content.isNotEmpty()) palette.name = content\n                \"colorname\" -> if (content.isNotEmpty()) colorName = content\n                \"red\" -> r = content.toIntOrNull()?.coerceIn(0, 255)\n                \"green\" -> g = content.toIntOrNull()?.coerceIn(0, 255)\n                \"blue\" -> b = content.toIntOrNull()?.coerceIn(0, 255)\n                \"colorentry\", \"pagecolor\" -> {\n                    if (r != null && g != null && b != null) {\n                        val color = PaletteColor.rgb(\n                            r = r!! / 255.0,\n                            g = g!! / 255.0,\n                            b = b!! / 255.0,\n                            name = colorName ?: \"\"\n                        )\n                        if (currentGroup == null) currentGroup = ColorGroup()\n                        currentGroup?.let {\n                            currentGroup = it.copy(\n                                colors = it.colors + color\n                            )\n                        }\n                    }\n                    r = null; g = null; b = null; colorName = null\n                }\n\n                \"colorpage\" -> {\n                    currentGroup?.let { group ->\n                        if (group.colors.isNotEmpty()) {\n                            if (palette.colors.isEmpty() && palette.groups.isEmpty()) {\n                                palette.colors.addAll(group.colors)\n                                if (group.name.isNotEmpty() && palette.name.isEmpty()) palette.name =\n                                    group.name\n                            } else {\n                                palette.groups.add(\n                                    if (group.name.isEmpty()) {\n                                        group.copy(\n                                            name = \"Color Page ${palette.groups.size + 1}\"\n                                        )\n                                    } else group\n                                )\n                            }\n                        }\n                    }\n                    currentGroup = null\n                }\n            }\n            if (xmlStack.isNotEmpty()) xmlStack.removeAt(xmlStack.size - 1)\n            currentChars.clear()\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        return try {\n            val handler = AutodeskXMLHandler()\n            val factory = SAXParserFactory.newInstance()\n            factory.isNamespaceAware = true\n            val parser = factory.newSAXParser()\n            parser.parse(input, handler)\n\n            // Если нет главного цвета, но есть группы, возьмём первую группу\n            if (handler.palette.colors.isEmpty() && handler.palette.groups.isNotEmpty()) {\n                val firstGroup = handler.palette.groups[0]\n                handler.palette.colors.addAll(firstGroup.colors)\n                handler.palette.groups.removeAt(0)\n            }\n\n            if (handler.palette.colors.isEmpty() && handler.palette.groups.isEmpty()) {\n                throw PaletteCoderException.InvalidFormat()\n            }\n\n            handler.palette.build()\n        } catch (_: Throwable) {\n            // Не удалось распарсить — не падаем, возвращаем пустой palette\n            Palette()\n        }\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val sb = StringBuilder()\n        sb.append(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\")\n        sb.append(\"<colorBook>\\n\")\n        val name = palette.name.ifEmpty { \"Untitled\" }\n        sb.append(\"   <bookName>${name.xmlEscaped()}</bookName>\\n\")\n        sb.append(\"   <majorVersion>1</majorVersion>\\n\")\n        sb.append(\"   <minorVersion>0</minorVersion>\\n\")\n\n        val allGroups = palette.allGroups\n        allGroups.forEach { group ->\n            if (group.colors.isEmpty()) return@forEach\n            sb.append(\"   <colorPage>\\n\")\n            group.colors.forEach { color ->\n                val colorName = color.name.ifEmpty { \"Color\" }\n                sb.append(\"      <colorEntry>\\n\")\n                sb.append(\"         <colorName>${colorName.xmlEscaped()}</colorName>\\n\")\n                sb.append(encodeColor(color))\n                sb.append(\"      </colorEntry>\\n\")\n            }\n            sb.append(\"   </colorPage>\\n\")\n        }\n        sb.append(\"</colorBook>\\n\")\n        output.write(sb.toString().toByteArray(StandardCharsets.UTF_8))\n    }\n\n    private fun encodeColor(color: PaletteColor): String {\n        val rgb = color.toRgb()\n        return \"\"\"         <RGB8>\n            <red>${rgb.r255}</red>\n            <green>${rgb.g255}</green>\n            <blue>${rgb.b255}</blue>\n         </RGB8>\n\"\"\"\n    }\n}\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/BasicXMLCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.xmlDecoded\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport javax.xml.parsers.SAXParserFactory\n\n/**\n * Basic XML palette coder\n */\nclass BasicXMLCoder : PaletteCoder {\n\n    private class BasicXMLHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n        private var currentChars = StringBuilder()\n        private fun elementName(localName: String, qName: String?): String =\n            localName.ifBlank { qName ?: \"\" }.substringAfter(':').lowercase()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            when (elementName(localName, qName)) {\n                \"palette\" -> {\n                    val name = attributes.getValue(\"name\")?.xmlDecoded()\n                    if (name != null) {\n                        palette.name = name\n                    }\n                }\n\n                \"color\" -> {\n                    val name = attributes.getValue(\"name\")?.xmlDecoded() ?: \"\"\n                    val hex = attributes.getValue(\"hex\")\n                    val r = attributes.getValue(\"r\")?.toIntOrNull()\n                    val g = attributes.getValue(\"g\")?.toIntOrNull()\n                    val b = attributes.getValue(\"b\")?.toIntOrNull()\n                    val a = attributes.getValue(\"a\")?.toIntOrNull() ?: 255\n\n                    try {\n                        val color = if (hex != null) {\n                            PaletteColor(\n                                rgbHexString = hex,\n                                format = ColorByteFormat.RGBA,\n                                name = name\n                            )\n                        } else if (r != null && g != null && b != null) {\n                            PaletteColor.rgb(\n                                r = r / 255.0,\n                                g = g / 255.0,\n                                b = b / 255.0,\n                                a = a / 255.0,\n                                name = name\n                            )\n                        } else {\n                            null\n                        }\n\n                        if (color != null) {\n                            palette.colors.add(color)\n                        }\n                    } catch (_: Throwable) {\n                        // Skip invalid colors\n                    }\n                }\n            }\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val handler = BasicXMLHandler()\n        val factory = SAXParserFactory.newInstance()\n        val parser = factory.newSAXParser()\n        parser.parse(input, handler)\n\n        val palette = handler.palette.build()\n\n        if (palette.totalColorCount == 0) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return palette\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var xml = \"<?xml version=\\\"1.0\\\"?>\\n\"\n        xml += \"<palette\"\n        if (palette.name.isNotEmpty()) {\n            xml += \" name=\\\"${palette.name.xmlEscaped()}\\\"\"\n        }\n        xml += \">\\n\"\n\n        palette.allColors().forEach { color ->\n            val rgb = color.toRgb()\n            val hex = rgb.hexString(ColorByteFormat.RGBA, hashmark = false, uppercase = false)\n\n            xml += \"<color\"\n            if (color.name.isNotEmpty()) {\n                xml += \" name=\\\"${color.name.xmlEscaped()}\\\"\"\n            }\n            xml += \" hex=\\\"$hex\\\"\"\n            xml += \" r=\\\"${rgb.r255}\\\" g=\\\"${rgb.g255}\\\" b=\\\"${rgb.b255}\\\" a=\\\"${rgb.a255}\\\"\"\n            xml += \" />\\n\"\n        }\n\n        xml += \"</palette>\\n\"\n\n        output.write(xml.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/CLFPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * CLF Lab Colors coder (decode only)\n */\nclass CLFPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val result = Palette.Builder()\n\n        text.lines().forEach { line ->\n            val components = line.split(\"\\t\")\n            if (components.size == 4) {\n                val name = components[0]\n                val ls = components[1].replace(\",\", \".\")\n                val `as` = components[2].replace(\",\", \".\")\n                val bs = components[3].replace(\",\", \".\")\n\n                val l = ls.trim().toDoubleOrNull() ?: return@forEach\n                val a = `as`.trim().toDoubleOrNull() ?: return@forEach\n                val b = bs.trim().toDoubleOrNull() ?: return@forEach\n\n                try {\n                    val color = PaletteColor.lab(\n                        l = l,\n                        a = a,\n                        b = b,\n                        name = name\n                    )\n                    result.colors.add(color)\n                } catch (_: Throwable) {\n                    // Skip invalid colors\n                }\n            }\n        }\n\n        if (result.colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val allColors = palette.allColors()\n        val lines = allColors.map { color ->\n            // Convert to LAB if not already\n            val lab = if (color.colorSpace == ColorSpace.LAB) {\n                color\n            } else {\n                try {\n                    color.converted(ColorSpace.LAB)\n                } catch (_: Throwable) {\n                    // If conversion fails, try to create a LAB color from RGB\n                    val rgb = color.toRgb()\n                    // Approximate conversion to LAB (simplified)\n                    PaletteColor.lab(\n                        l = (rgb.rf * 0.299 + rgb.gf * 0.587 + rgb.bf * 0.114) * 100,\n                        a = (rgb.rf - rgb.gf) * 127,\n                        b = (rgb.gf - rgb.bf) * 127,\n                        name = color.name\n                    )\n                }\n            }\n\n            val name = color.name.ifEmpty { \"Color\" }\n            val l = lab.colorComponents[0]\n            val a = lab.colorComponents[1]\n            val b = lab.colorComponents[2]\n\n            // Format: name[tab]L[tab]a[tab]b\n            // Replace comma with dot for decimal separator\n            \"$name\\t${l.toString().replace(',', '.')}\\t${\n                a.toString().replace(',', '.')\n            }\\t${b.toString().replace(',', '.')}\"\n        }\n\n        val text = lines.joinToString(\"\\n\")\n        output.write(text.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/CPLPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.ColorType\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.nio.charset.Charset\n\n/**\n * Corel Palette (CPL) coder\n */\nclass CPLPaletteCoder : PaletteCoder {\n    companion object {\n        private val spotPaletteTypes = listOf(\n            3u,\n            8u,\n            9u,\n            10u,\n            11u,\n            16u,\n            17u,\n            18u,\n            20u,\n            21u,\n            22u,\n            23u,\n            26u,\n            27u,\n            28u,\n            29u,\n            30u,\n            31u,\n            32u,\n            35u,\n            36u,\n            37u\n        )\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val data = input.readBytes()\n        val parser = BytesReader(data)\n        val result = Palette.Builder()\n\n        var spot = false\n        var paletteType: UShort = 0u\n\n        val version = parser.readUInt16(ByteOrder.BIG_ENDIAN)\n        val numberOfColors: UShort\n\n        when (version.toInt()) {\n            0xDCDC -> {\n                // This version has a palette name\n                val filenamelength = parser.readUInt8().toInt()\n                if (filenamelength > 0) {\n                    result.name = parser.readStringASCII(filenamelength)\n                }\n                numberOfColors = parser.readUInt16(ByteOrder.LITTLE_ENDIAN)\n            }\n\n            0xCCBC, 0xCCDC -> {\n                // This version doesn't have a palette name, just colors\n                numberOfColors = parser.readUInt16(ByteOrder.LITTLE_ENDIAN)\n            }\n\n            else -> {\n                // Read in headers\n                val headerCount = parser.readInt32(ByteOrder.LITTLE_ENDIAN)\n\n                data class Header(val hid: Int, val offset: Int)\n\n                val headers = mutableListOf<Header>()\n                repeat(headerCount) {\n                    val hid = parser.readInt32(ByteOrder.LITTLE_ENDIAN)\n                    val offset = parser.readInt32(ByteOrder.LITTLE_ENDIAN)\n                    headers.add(Header(hid, offset))\n                }\n\n                // Name\n                if (headers.isNotEmpty()) {\n                    parser.seekSet(headers[0].offset)\n                    val filenamelength = parser.readUInt8().toInt()\n                    var name = \"\"\n                    if (filenamelength > 0) {\n                        if (version.toInt() == 0xCDDC) {\n                            val nameData = parser.readBytes(filenamelength)\n                            name = try {\n                                String(nameData, Charset.forName(\"ISO-8859-1\"))\n                            } catch (_: Throwable) {\n                                String(nameData, java.nio.charset.StandardCharsets.US_ASCII)\n                            }\n                        } else {\n                            name = parser.readStringUTF16(ByteOrder.LITTLE_ENDIAN, filenamelength)\n                        }\n                    }\n                    result.name = name\n                }\n\n                // Palette Type\n                if (headers.size > 1) {\n                    parser.seekSet(headers[1].offset)\n                    paletteType = parser.readUInt16(ByteOrder.LITTLE_ENDIAN)\n                }\n\n                // Number of colors\n                if (headers.size > 2) {\n                    parser.seekSet(headers[2].offset)\n                    numberOfColors = parser.readUInt16(ByteOrder.LITTLE_ENDIAN)\n\n                    // Check if we are a spot palette\n                    spot = spotPaletteTypes.contains(paletteType.toUInt())\n\n                    parser.seekSet(headers[2].offset + 2)\n                } else {\n                    numberOfColors = 0u\n                }\n            }\n        }\n\n        val long = listOf(0xCDBC, 0xCDDC, 0xCDDD).contains(version.toInt()) &&\n                paletteType.toInt() < 38 &&\n                paletteType.toInt() != 5 &&\n                paletteType.toInt() != 16\n\n        for (i in 0 until numberOfColors.toInt()) {\n            if (long) {\n                parser.readUInt32(ByteOrder.LITTLE_ENDIAN)\n            }\n\n            val model = parser.readUInt16(ByteOrder.LITTLE_ENDIAN)\n            parser.seek(2)\n\n            var colorspace: ColorSpace? = null\n            var colorComponents: List<Double>? = null\n\n            var colorspace2: ColorSpace? = null\n            var colorComponents2: List<Double>? = null\n\n            when (model.toInt()) {\n                2 -> {\n                    // CMYK percentages\n                    parser.seek(4)\n                    val cmyk = parser.readBytes(4)\n                    colorspace = ColorSpace.CMYK\n                    colorComponents = listOf(\n                        cmyk[0].toUByte().toDouble() / 100.0,\n                        cmyk[1].toUByte().toDouble() / 100.0,\n                        cmyk[2].toUByte().toDouble() / 100.0,\n                        cmyk[3].toUByte().toDouble() / 100.0\n                    )\n                }\n\n                3, 17 -> {\n                    // CMYK fractions\n                    parser.seek(4)\n                    val cmyk = parser.readBytes(4)\n                    colorspace = ColorSpace.CMYK\n                    colorComponents = listOf(\n                        cmyk[0].toUByte().toDouble() / 255.0,\n                        cmyk[1].toUByte().toDouble() / 255.0,\n                        cmyk[2].toUByte().toDouble() / 255.0,\n                        cmyk[3].toUByte().toDouble() / 255.0\n                    )\n                }\n\n                4 -> {\n                    // CMY fractions\n                    parser.seek(4)\n                    val cmyk = parser.readBytes(4)\n                    colorspace = ColorSpace.CMYK\n                    colorComponents = listOf(\n                        cmyk[0].toUByte().toDouble() / 255.0,\n                        cmyk[1].toUByte().toDouble() / 255.0,\n                        cmyk[2].toUByte().toDouble() / 255.0,\n                        0.0\n                    )\n                }\n\n                5, 21 -> {\n                    // BGR fractions\n                    parser.seek(4)\n                    val bgr = parser.readBytes(3)\n                    colorspace = ColorSpace.RGB\n                    colorComponents = listOf(\n                        bgr[2].toUByte().toDouble() / 255.0,\n                        bgr[1].toUByte().toDouble() / 255.0,\n                        bgr[0].toUByte().toDouble() / 255.0\n                    )\n                    parser.seek(1)\n                }\n\n                9 -> {\n                    // Grayscale\n                    parser.seek(4)\n                    val k = parser.readUInt8().toInt()\n                    colorspace = ColorSpace.Gray\n                    colorComponents = listOf((255 - k) / 255.0)\n                    parser.seek(3)\n                }\n\n                else -> {\n                    // Unknown type, try to recover\n                    parser.seek(8)\n                }\n            }\n\n            if (long) {\n                val model2 = parser.readUInt16(ByteOrder.LITTLE_ENDIAN)\n                when (model2.toInt()) {\n                    2 -> {\n                        parser.seek(4)\n                        val cmyk = parser.readBytes(4)\n                        colorspace2 = ColorSpace.CMYK\n                        colorComponents2 = listOf(\n                            cmyk[0].toUByte().toDouble() / 100.0,\n                            cmyk[1].toUByte().toDouble() / 100.0,\n                            cmyk[2].toUByte().toDouble() / 100.0,\n                            cmyk[3].toUByte().toDouble() / 100.0\n                        )\n                    }\n\n                    3, 17 -> {\n                        parser.seek(4)\n                        val cmyk = parser.readBytes(4)\n                        colorspace2 = ColorSpace.CMYK\n                        colorComponents2 = listOf(\n                            cmyk[0].toUByte().toDouble() / 255.0,\n                            cmyk[1].toUByte().toDouble() / 255.0,\n                            cmyk[2].toUByte().toDouble() / 255.0,\n                            cmyk[3].toUByte().toDouble() / 255.0\n                        )\n                    }\n\n                    4 -> {\n                        parser.seek(4)\n                        val cmyk = parser.readBytes(4)\n                        colorspace2 = ColorSpace.CMYK\n                        colorComponents2 = listOf(\n                            cmyk[0].toUByte().toDouble() / 255.0,\n                            cmyk[1].toUByte().toDouble() / 255.0,\n                            cmyk[2].toUByte().toDouble() / 255.0,\n                            0.0\n                        )\n                    }\n\n                    5, 21 -> {\n                        parser.seek(4)\n                        val bgr = parser.readBytes(3)\n                        colorspace2 = ColorSpace.RGB\n                        colorComponents2 = listOf(\n                            bgr[2].toUByte().toDouble() / 255.0,\n                            bgr[1].toUByte().toDouble() / 255.0,\n                            bgr[0].toUByte().toDouble() / 255.0\n                        )\n                        parser.seek(1)\n                    }\n\n                    9 -> {\n                        parser.seek(4)\n                        val k = parser.readUInt8().toInt()\n                        colorspace2 = ColorSpace.Gray\n                        colorComponents2 = listOf((255 - k) / 255.0)\n                        parser.seek(3)\n                    }\n\n                    else -> {\n                        parser.seek(8)\n                    }\n                }\n            }\n\n            val nameLength = parser.readUInt8().toInt()\n            var colorName = \"\"\n            if (nameLength > 0) {\n                if (version.toInt() in listOf(0xCDDC, 0xDCDC, 0xCCDC)) {\n                    val nameData = parser.readBytes(nameLength)\n                    colorName = try {\n                        String(nameData, Charset.forName(\"ISO-8859-1\"))\n                    } catch (_: Throwable) {\n                        String(nameData, java.nio.charset.StandardCharsets.US_ASCII)\n                    }\n                } else {\n                    colorName = parser.readStringUTF16(ByteOrder.LITTLE_ENDIAN, nameLength)\n                }\n            }\n\n            if (colorspace != null && colorComponents != null) {\n                try {\n                    val readColor = PaletteColor(\n                        name = colorName,\n                        colorSpace = colorspace,\n                        colorComponents = colorComponents,\n                        colorType = if (spot) ColorType.Spot else ColorType.Normal\n                    )\n                    result.colors.add(readColor)\n                } catch (_: Throwable) {\n                    // Skip invalid colors\n                }\n            }\n\n            if (colorspace2 != null && colorComponents2 != null) {\n                try {\n                    val readColor = PaletteColor(\n                        name = colorName,\n                        colorSpace = colorspace2,\n                        colorComponents = colorComponents2,\n                        colorType = if (spot) ColorType.Spot else ColorType.Normal\n                    )\n                    result.colors.add(readColor)\n                } catch (_: Throwable) {\n                    // Skip invalid colors\n                }\n            }\n\n            if (version.toInt() == 0xCDDD) {\n                // row and column\n                parser.readUInt32(ByteOrder.LITTLE_ENDIAN)\n                parser.readUInt32(ByteOrder.LITTLE_ENDIAN)\n                parser.readUInt32(ByteOrder.LITTLE_ENDIAN)\n            }\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n        val allColors = palette.allColors()\n        val colorCount = allColors.size\n\n        if (colorCount == 0) {\n            throw PaletteCoderException.TooFewColors()\n        }\n\n        // Use version 0xDCDC (has palette name)\n        writer.writeUInt16(0xDCDCu.toUShort(), ByteOrder.BIG_ENDIAN)\n\n        // Filename length and name\n        val filename = palette.name.ifEmpty { \"Palette\" }\n        val filenameBytes = filename.toByteArray(Charset.forName(\"ISO-8859-1\"))\n        val filenameLength = filenameBytes.size.coerceIn(0, 255)\n        writer.writeUInt8(filenameLength.toUByte())\n        if (filenameLength > 0) {\n            writer.writeData(filenameBytes.sliceArray(0 until filenameLength))\n        }\n\n        // Number of colors (2 bytes, little endian)\n        writer.writeUInt16(colorCount.toUShort(), ByteOrder.LITTLE_ENDIAN)\n\n        // Write colors - use model 5 (BGR fractions) for RGB colors\n        allColors.forEach { color ->\n            val rgb = color.toRgb()\n\n            // Model (2 bytes, little endian) - 5 = BGR fractions\n            writer.writeUInt16(5u.toUShort(), ByteOrder.LITTLE_ENDIAN)\n\n            // Skip 2 bytes\n            writer.writePattern(0x00, 0x00)\n\n            // Skip 4 bytes (unknown)\n            writer.writePattern(0x00, 0x00, 0x00, 0x00)\n\n            // BGR values (3 bytes) - reversed order\n            writer.writeByte((rgb.bf * 255).toInt().coerceIn(0, 255).toByte())\n            writer.writeByte((rgb.gf * 255).toInt().coerceIn(0, 255).toByte())\n            writer.writeByte((rgb.rf * 255).toInt().coerceIn(0, 255).toByte())\n\n            // Skip 1 byte\n            writer.writeByte(0)\n\n            // Color name length\n            val colorName = color.name.ifEmpty { \"\" }\n            val colorNameBytes =\n                colorName.toByteArray(Charset.forName(\"ISO-8859-1\"))\n            val colorNameLength = colorNameBytes.size.coerceIn(0, 255)\n            writer.writeUInt8(colorNameLength.toUByte())\n\n            // Color name\n            if (colorNameLength > 0) {\n                writer.writeData(colorNameBytes.sliceArray(0 until colorNameLength))\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/CSVPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.CSVParser\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * CSV palette coder\n */\nclass CSVPaletteCoder(\n    private val hexFormat: ColorByteFormat = ColorByteFormat.RGB\n) : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val records = CSVParser.parse(text)\n\n        if (records.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val colors = when (records.size) {\n            1 -> {\n                // Single line of hex colors\n                records[0].mapNotNull { field ->\n                    try {\n                        PaletteColor(field.trim(), ColorByteFormat.RGBA)\n                    } catch (_: Throwable) {\n                        null\n                    }\n                }\n            }\n\n            else -> {\n                records.mapNotNull { record ->\n                    when {\n                        record.isEmpty() -> null\n                        record.size == 1 -> {\n                            try {\n                                PaletteColor(record[0].trim(), ColorByteFormat.RGBA)\n                            } catch (_: Throwable) {\n                                null\n                            }\n                        }\n\n                        else -> {\n                            try {\n                                PaletteColor(\n                                    record[0].trim(),\n                                    ColorByteFormat.RGBA,\n                                    record[1].trim()\n                                )\n                            } catch (_: Throwable) {\n                                null\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return Palette(colors = colors.toMutableList())\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val allColors = palette.allColors()\n        var results = \"\"\n\n        allColors.forEach { color ->\n            results += color.hexString(hexFormat, hashmark = true, uppercase = false)\n            if (color.name.isNotEmpty()) {\n                results += \", ${color.name}\"\n            }\n            results += \"\\n\"\n        }\n\n        output.write(results.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/CorelDraw3PaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Corel Draw V3 Palette coder\n */\nclass CorelDraw3PaletteCoder : PaletteCoder {\n    companion object {\n        private val regex =\n            Regex(\"\\\"(.*)\\\"[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t]*\")\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val result = Palette.Builder()\n\n        text.lines().forEach { line ->\n            val trimmed = line.trim()\n            regex.find(trimmed)?.let { match ->\n                val name = match.groupValues[1]\n                val cyan = match.groupValues[2].toDoubleOrNull() ?: return@let\n                val magenta = match.groupValues[3].toDoubleOrNull() ?: return@let\n                val yellow = match.groupValues[4].toDoubleOrNull() ?: return@let\n                val black = match.groupValues[5].toDoubleOrNull() ?: return@let\n\n                val color = PaletteColor.cmyk(\n                    c = (cyan / 100.0).coerceIn(0.0, 1.0),\n                    m = (magenta / 100.0).coerceIn(0.0, 1.0),\n                    y = (yellow / 100.0).coerceIn(0.0, 1.0),\n                    k = (black / 100.0).coerceIn(0.0, 1.0),\n                    name = name\n                )\n                result.colors.add(color)\n            }\n        }\n\n        val palette = result.build()\n\n        if (palette.allColors().isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return palette\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var result = \"\"\n\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.CMYK) color else color.converted(ColorSpace.CMYK)\n        }\n\n        colors.forEach { color ->\n            val cmyk = color.toCmyk()\n            val ci = ((cmyk.cf * 100).roundToInt())\n            val mi = ((cmyk.mf * 100).roundToInt())\n            val yi = ((cmyk.yf * 100).roundToInt())\n            val ki = ((cmyk.kf * 100).roundToInt())\n\n            result += \"\\\"${color.name}\\\"    $ci    $mi    $yi    $ki\\r\\n\"\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n\n    private fun Double.roundToInt(): Int {\n        return kotlin.math.round(this).toInt()\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/CorelPainterCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Corel Painter Swatch coder\n */\nclass CorelPainterCoder : PaletteCoder {\n    companion object {\n        private val regex =\n            Regex(\"[ \\\\t]*R[ \\\\t]*:[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t,]*G[ \\\\t]*:[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t,]*B[ \\\\t]*:[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t,]*(?:HV[ \\\\t]*:[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t,]*)?(?:SV[ \\\\t]*:[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t,]*)?(?:VV[ \\\\t]*:[ \\\\t]*(\\\\d*\\\\.?\\\\d+)[ \\\\t,]*)?(.*)\")\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n\n        if (!text.startsWith(\"ROWS \")) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val lines = text.lines()\n        if (lines.size < 7) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        if (!lines[0].startsWith(\"ROWS\") ||\n            !lines[1].startsWith(\"COLS\") ||\n            !lines[2].startsWith(\"WIDTH\") ||\n            !lines[3].startsWith(\"HEIGHT\") ||\n            !lines[4].startsWith(\"TEXTHEIGHT\") ||\n            !lines[5].startsWith(\"SPACING\")\n        ) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n\n        for (line in lines.drop(6)) {\n            val trimmed = line.trim()\n            regex.find(trimmed)?.let { match ->\n                val r = match.groupValues[1].toIntOrNull() ?: return@let\n                val g = match.groupValues[2].toIntOrNull() ?: return@let\n                val b = match.groupValues[3].toIntOrNull() ?: return@let\n                val name = match.groupValues[7].trim()\n\n                val color = PaletteColor.rgb(\n                    r = (r / 255.0).coerceIn(0.0, 1.0),\n                    g = (g / 255.0).coerceIn(0.0, 1.0),\n                    b = (b / 255.0).coerceIn(0.0, 1.0),\n                    name = name\n                )\n                result.colors.add(color)\n            }\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var result = \"\"\"ROWS 12\nCOLS 22\nWIDTH 16\nHEIGHT 16\nTEXTHEIGHT 0\nSPACING 1\n\n\"\"\"\n\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        colors.forEach { color ->\n            val rgb = color.toRgb()\n            result += \"R: ${rgb.r255}, G:${rgb.g255}, B:${rgb.b255}  HV:0.00, SV:0.00, VV:0.00\"\n            if (color.name.isNotEmpty()) {\n                result += \"  ${color.name}\"\n            }\n            result += \"\\n\"\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/CorelXMLPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.xmlDecoded\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.util.Locale\nimport javax.xml.parsers.SAXParserFactory\n\n/**\n * CorelDraw XML palette coder (исправлена обработка имён элементов и поиск colorspaces по регистру)\n */\nclass CorelXMLPaletteCoder : PaletteCoder {\n\n    private class CorelXMLHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n        private var currentGroup: ColorGroup? = null\n        private var isInColorsSection = false\n        private var isInColorspaceSection = false\n        private val colorspaces = mutableListOf<Colorspace>()\n        private var currentChars = StringBuilder()\n\n        private class Colorspace(val name: String) {\n            val colors = mutableListOf<PaletteColor>()\n        }\n\n        private fun elmName(localName: String?, qName: String?) =\n            (qName ?: localName ?: \"\").trim()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            when (elmName(localName, qName).lowercase()) {\n                \"palette\" -> {\n                    val name = attributes.getValue(\"name\")?.xmlDecoded()\n                    if (!name.isNullOrEmpty()) {\n                        palette.name = name\n                    }\n                }\n\n                \"colorspaces\" -> isInColorspaceSection = true\n                \"cs\" -> {\n                    val name = attributes.getValue(\"name\")?.xmlDecoded() ?: \"\"\n                    colorspaces.add(Colorspace(name.lowercase()))\n                }\n\n                \"colors\" -> isInColorsSection = true\n                \"page\" -> {\n                    val name = attributes.getValue(\"name\")?.xmlDecoded() ?: \"\"\n                    currentGroup = ColorGroup(name = name)\n                }\n\n                \"color\" -> {\n                    val csRaw = attributes.getValue(\"cs\")\n                    val cs = csRaw?.lowercase()\n                    val name = attributes.getValue(\"name\")?.xmlDecoded() ?: \"\"\n                    val tints = attributes.getValue(\"tints\") ?: \"\"\n                    val components = tints.split(\",\").mapNotNull { it.trim().toDoubleOrNull() }\n\n                    val color: PaletteColor? = when (cs) {\n                        \"cmyk\" -> {\n                            if (components.size >= 4) {\n                                try {\n                                    PaletteColor.cmyk(\n                                        c = components[0],\n                                        m = components[1],\n                                        y = components[2],\n                                        k = components[3],\n                                        name = name\n                                    )\n                                } catch (_: Throwable) {\n                                    null\n                                }\n                            } else null\n                        }\n\n                        \"rgb\" -> {\n                            if (components.size >= 3) {\n                                try {\n                                    PaletteColor.rgb(\n                                        r = components[0],\n                                        g = components[1],\n                                        b = components[2],\n                                        name = name\n                                    )\n                                } catch (_: Throwable) {\n                                    null\n                                }\n                            } else null\n                        }\n\n                        \"lab\" -> {\n                            if (components.size >= 3) {\n                                try {\n                                    val l = components[0] * 100.0\n                                    val a = components[1] * 256.0 - 128.0\n                                    val b = components[2] * 256.0 - 128.0\n                                    PaletteColor.lab(l = l, a = a, b = b, name = name)\n                                } catch (_: Throwable) {\n                                    null\n                                }\n                            } else null\n                        }\n\n                        \"gray\", \"grey\" -> {\n                            if (components.isNotEmpty()) {\n                                try {\n                                    PaletteColor.gray(white = components[0], name = name)\n                                } catch (_: Throwable) {\n                                    null\n                                }\n                            } else null\n                        }\n\n                        else -> {\n                            // Если указан colorspace (cs) и он описан в секции colorspaces,\n                            // берём первый цвет из описанной colorspace как шаблон.\n                            if (!cs.isNullOrEmpty()) {\n                                colorspaces.find { it.name == cs }?.colors?.firstOrNull()\n                                    ?.let { existingColor ->\n                                        try {\n                                            PaletteColor(\n                                                name = name,\n                                                colorSpace = existingColor.colorSpace,\n                                                colorComponents = existingColor.colorComponents.toMutableList(),\n                                                alpha = existingColor.alpha,\n                                                colorType = existingColor.colorType\n                                            )\n                                        } catch (_: Throwable) {\n                                            null\n                                        }\n                                    }\n                            } else null\n                        }\n                    }\n\n                    if (color != null) {\n                        if (isInColorspaceSection) {\n                            colorspaces.lastOrNull()?.colors?.add(color)\n                        } else {\n                            if (currentGroup == null) currentGroup = ColorGroup()\n                            currentGroup?.let {\n                                currentGroup = it.copy(\n                                    colors = it.colors + color\n                                )\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        override fun endElement(uri: String?, localName: String, qName: String?) {\n            when (elmName(localName, qName).lowercase()) {\n                \"page\" -> {\n                    currentGroup?.let { group ->\n                        if (group.colors.isNotEmpty()) {\n                            if (group.name.isEmpty() && palette.colors.isEmpty() && palette.groups.isEmpty()) {\n                                palette.colors.addAll(group.colors)\n                            } else if (group.name.isNotEmpty()) {\n                                palette.groups.add(group)\n                            } else {\n                                palette.colors.addAll(group.colors)\n                            }\n                        }\n                    }\n                    currentGroup = null\n                }\n\n                \"colors\" -> isInColorsSection = false\n                \"colorspaces\" -> isInColorspaceSection = false\n            }\n            currentChars.clear()\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val handler = CorelXMLHandler()\n        val factory = SAXParserFactory.newInstance()\n        factory.isNamespaceAware = true\n        factory.isValidating = false\n        val parser = factory.newSAXParser()\n        parser.parse(input, handler)\n\n        if (handler.palette.colors.isEmpty() && handler.palette.groups.isNotEmpty()) {\n            val firstGroup = handler.palette.groups[0]\n            handler.palette.colors.addAll(firstGroup.colors)\n            handler.palette.groups.removeAt(0)\n        }\n\n        if (handler.palette.colors.isEmpty() && handler.palette.groups.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return handler.palette.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val sb = StringBuilder()\n        sb.append(\"<?xml version=\\\"1.0\\\"?>\\n\")\n        sb.append(\"<palette guid=\\\"${java.util.UUID.randomUUID()}\\\"\")\n        if (palette.name.isNotEmpty()) sb.append(\" name=\\\"${palette.name.xmlEscaped()}\\\"\")\n        sb.append(\">\\n\")\n        sb.append(\"<colors>\\n\")\n\n        if (palette.colors.isNotEmpty()) {\n            sb.append(pageData(name = \"\", colors = palette.colors))\n        }\n\n        palette.groups.forEach { group ->\n            sb.append(pageData(name = group.name, colors = group.colors))\n        }\n\n        sb.append(\"</colors>\\n\")\n        sb.append(\"</palette>\\n\")\n\n        output.write(sb.toString().toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n\n    private fun pageData(name: String, colors: List<PaletteColor>): String {\n        val locale = Locale.US\n        val result = StringBuilder()\n        result.append(\"<page\")\n        if (name.isNotEmpty()) result.append(\" name=\\\"${name.xmlEscaped()}\\\"\")\n        result.append(\">\")\n        colors.forEach { color ->\n            result.append(\"<color\")\n            if (color.name.isNotEmpty()) result.append(\" name=\\\"${color.name.xmlEscaped()}\\\"\")\n\n            val (cs, tints) = when (color.colorSpace) {\n                ColorSpace.CMYK -> {\n                    \"CMYK\" to color.colorComponents.joinToString(\",\") { \"%.6f\".format(locale, it) }\n                }\n\n                ColorSpace.RGB -> {\n                    \"RGB\" to color.colorComponents.joinToString(\",\") { \"%.6f\".format(locale, it) }\n                }\n\n                ColorSpace.Gray -> {\n                    \"GRAY\" to color.colorComponents.joinToString(\",\") { \"%.6f\".format(locale, it) }\n                }\n\n                ColorSpace.LAB -> {\n                    if (color.colorComponents.size < 3) {\n                        \"LAB\" to \"\"\n                    } else {\n                        \"LAB\" to listOf(\n                            color.colorComponents[0] / 100.0,\n                            (color.colorComponents[1] + 128.0) / 256.0,\n                            (color.colorComponents[2] + 128.0) / 256.0\n                        ).joinToString(\",\") { \"%.6f\".format(locale, it) }\n                    }\n                }\n\n            }\n\n            result.append(\" cs=\\\"$cs\\\"\")\n            if (tints.isNotEmpty()) result.append(\" tints=\\\"$tints\\\"\")\n            result.append(\"/>\\n\")\n        }\n        result.append(\"</page>\\n\")\n        return result.toString()\n    }\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/DCPPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.ColorType\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.ByteArrayInputStream\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * ColorPaletteCodable binary format (DCP) coder\n */\nclass DCPPaletteCoder : PaletteCoder {\n    companion object {\n        const val BOM: UShort = 32156u\n        const val VERSION: UShort = 1u\n        const val GROUP_IDENTIFIER: UByte = 0xEAu\n        const val COLOR_IDENTIFIER: UByte = 0xC0u\n    }\n\n    override fun decode(input: InputStream): Palette {\n        // Read all data first for seek support\n        val data = input.readBytes()\n        val parser = BytesReader(ByteArrayInputStream(data))\n        val result = Palette.Builder()\n\n        // Read BOM\n        if (parser.readUInt16(ByteOrder.LITTLE_ENDIAN) != BOM) {\n            throw PaletteCoderException.InvalidBOM()\n        }\n\n        // Read version\n        if (parser.readUInt16(ByteOrder.LITTLE_ENDIAN) != VERSION) {\n            throw PaletteCoderException.InvalidBOM()\n        }\n\n        // Palette name\n        result.name = parser.readPascalStringUTF16(ByteOrder.LITTLE_ENDIAN)\n\n        // Read the expected number of groups\n        val expectedGroupCount = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt()\n\n        // Read in the groups\n        val groups = mutableListOf<ColorGroup>()\n        for (i in 0 until expectedGroupCount) {\n            // Read a group identifier tag\n            if (parser.readByte() != GROUP_IDENTIFIER.toByte()) {\n                throw PaletteCoderException.InvalidBOM()\n            }\n\n            // Read the group name\n            val groupName = parser.readPascalStringUTF16(ByteOrder.LITTLE_ENDIAN)\n\n            // Read the expected number of colors\n            val expectedColorCount = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt()\n\n            // The groups colors\n            val colors = mutableListOf<PaletteColor>()\n            for (j in 0 until expectedColorCount) {\n                colors.add(parser.readColor())\n            }\n\n            groups.add(ColorGroup(colors = colors, name = groupName))\n        }\n\n        // First group is always the 'global' colors\n        if (groups.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        result.colors = groups[0].colors.toMutableList()\n        result.groups = groups.drop(1).toMutableList()\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n\n        // Expected BOM\n        writer.writeUInt16(BOM, ByteOrder.LITTLE_ENDIAN)\n\n        // Version\n        writer.writeUInt16(VERSION, ByteOrder.LITTLE_ENDIAN)\n\n        // Write the palette name\n        writer.writePascalStringUTF16(palette.name, ByteOrder.LITTLE_ENDIAN)\n\n        // Write the number of groups (global colors + groups)\n        val allGroups = palette.allGroups\n        writer.writeUInt16(allGroups.size.toUShort(), ByteOrder.LITTLE_ENDIAN)\n\n        allGroups.forEach { group ->\n            // Write a group identifier tag\n            writer.writeByte(GROUP_IDENTIFIER.toByte())\n\n            // Write the group name\n            writer.writePascalStringUTF16(group.name, ByteOrder.LITTLE_ENDIAN)\n\n            // Write the number of colors in the group\n            writer.writeUInt16(group.colors.size.toUShort(), ByteOrder.LITTLE_ENDIAN)\n\n            group.colors.forEach { color ->\n                writer.writeColor(color)\n            }\n        }\n    }\n}\n\nprivate fun BytesReader.readColor(): PaletteColor {\n    // Read a color identifier tag\n    if (readByte() != DCPPaletteCoder.COLOR_IDENTIFIER.toByte()) {\n        throw PaletteCoderException.InvalidBOM()\n    }\n\n    // Read the color name\n    val colorName = readPascalStringUTF16(ByteOrder.LITTLE_ENDIAN)\n\n    val colorspaceID = readUInt8()\n\n    val colorSpace: ColorSpace\n    val components: List<Double>\n\n    when (colorspaceID.toInt()) {\n        1 -> {\n            // CMYK\n            colorSpace = ColorSpace.CMYK\n            components = listOf(\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble(),\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble(),\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble(),\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n            )\n        }\n\n        2 -> {\n            // RGB\n            colorSpace = ColorSpace.RGB\n            components = listOf(\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble(),\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble(),\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n            )\n        }\n\n        3 -> {\n            // LAB\n            colorSpace = ColorSpace.LAB\n            components = listOf(\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble(),\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble(),\n                readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n            )\n        }\n\n        4 -> {\n            // Gray\n            colorSpace = ColorSpace.Gray\n            components = listOf(readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble())\n        }\n\n        else -> throw PaletteCoderException.InvalidFormat()\n    }\n\n    // Alpha component\n    val alpha = readFloat32(ByteOrder.LITTLE_ENDIAN).toDouble()\n\n    // Color type\n    val type = readUInt8()\n    val colorType: ColorType = when (type.toInt()) {\n        1 -> ColorType.Global\n        2 -> ColorType.Spot\n        3 -> ColorType.Normal\n        else -> throw PaletteCoderException.InvalidFormat()\n    }\n\n    return PaletteColor(\n        name = colorName,\n        colorType = colorType,\n        colorSpace = colorSpace,\n        colorComponents = components,\n        alpha = alpha\n    )\n}\n\nprivate fun BytesWriter.writeColor(color: PaletteColor) {\n    // Write a color identifier tag\n    writeByte(DCPPaletteCoder.COLOR_IDENTIFIER.toByte())\n\n    // Color name\n    writePascalStringUTF16(color.name, ByteOrder.LITTLE_ENDIAN)\n\n    // Write the colorspace identifier\n    val colorspaceID: UByte = when (color.colorSpace) {\n        ColorSpace.CMYK -> 1u\n        ColorSpace.RGB -> 2u\n        ColorSpace.LAB -> 3u\n        ColorSpace.Gray -> 4u\n    }\n    writeUInt8(colorspaceID)\n\n    // Write the color components\n    color.colorComponents.forEach { comp ->\n        writeFloat32(comp.toFloat(), ByteOrder.LITTLE_ENDIAN)\n    }\n\n    // Color alpha\n    writeFloat32(color.alpha.toFloat(), ByteOrder.LITTLE_ENDIAN)\n\n    // Color type\n    val type: UByte = when (color.colorType) {\n        ColorType.Global -> 1u\n        ColorType.Spot -> 2u\n        ColorType.Normal -> 3u\n    }\n    writeUInt8(type)\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/GIMPPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\nimport kotlin.math.roundToInt\n\n/**\n * GIMP Palette (GPL) coder\n */\nclass GIMPPaletteCoder : PaletteCoder {\n    companion object {\n        private val nameRegex = Regex(\"^Name:\\\\s*(.*)$\", RegexOption.IGNORE_CASE)\n        private val colorRegex = Regex(\"^\\\\s*(\\\\d{1,3})\\\\s+(\\\\d{1,3})\\\\s+(\\\\d{1,3})(?:\\\\s+(.*))?$\")\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n\n        val header = lines.firstOrNull()?.removePrefix(\"\\uFEFF\")?.trim() ?: \"\"\n        if (!header.equals(\"GIMP Palette\", ignoreCase = true)) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n\n        for (line in lines.drop(1)) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) continue\n            if (trimmed.startsWith(\"#\")) continue\n            if (trimmed.startsWith(\"Columns:\", ignoreCase = true)) continue\n\n            // Check for name\n            nameRegex.find(trimmed)?.let { match ->\n                result.name = match.groupValues[1].trim()\n                continue\n            }\n\n            // Check for color\n            colorRegex.find(trimmed)?.let { match ->\n                val r = match.groupValues[1].toIntOrNull() ?: continue\n                val g = match.groupValues[2].toIntOrNull() ?: continue\n                val b = match.groupValues[3].toIntOrNull() ?: continue\n                if (r !in 0..255 || g !in 0..255 || b !in 0..255) continue\n\n                val name = match.groupValues.getOrElse(4) { \"\" }.trim()\n\n                val color = PaletteColor.rgb(\n                    r = (r / 255.0).coerceIn(0.0, 1.0),\n                    g = (g / 255.0).coerceIn(0.0, 1.0),\n                    b = (b / 255.0).coerceIn(0.0, 1.0),\n                    name = name\n                )\n                result.colors.add(color)\n            }\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val originalColors = palette.allColors()\n        val result = buildString {\n            appendLine(\"GIMP Palette\")\n            appendLine(\"Name: ${sanitizeGimpText(palette.name)}\")\n            appendLine(\"Columns: 0\")\n            appendLine(\"#Colors: ${originalColors.size}\")\n\n            originalColors.forEach { color ->\n                val rgb = if (color.colorSpace == ColorSpace.RGB) color.toRgb()\n                else color.converted(ColorSpace.RGB).toRgb()\n\n                val r = (rgb.rf * 255.0).roundToInt().coerceIn(0, 255)\n                val g = (rgb.gf * 255.0).roundToInt().coerceIn(0, 255)\n                val b = (rgb.bf * 255.0).roundToInt().coerceIn(0, 255)\n\n                append(\"$r\\t$g\\t$b\")\n                val colorName = sanitizeGimpText(color.name)\n                if (colorName.isNotEmpty()) {\n                    append('\\t')\n                    append(colorName)\n                }\n                append('\\n')\n            }\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n\n    private fun sanitizeGimpText(value: String): String =\n        value.replace(Regex(\"[\\\\r\\\\n\\\\t]+\"), \" \").trim()\n}\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/HEXPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Hex RGBA palette coder\n */\nclass HEXPaletteCoder : PaletteCoder {\n    companion object {\n        private val validHexChars = \"#0123456789abcdefABCDEF\"\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n        val result = Palette.Builder()\n\n        var currentName = \"\"\n        for (line in lines) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) continue\n\n            if (trimmed.firstOrNull() == ';') {\n                // Comment - might be a color name\n                val commentText = trimmed.substring(1).trim()\n                if (commentText.isNotEmpty()) {\n                    currentName = commentText\n                }\n                continue\n            }\n\n            var current = \"\"\n            for (char in line) {\n                if (validHexChars.contains(char)) {\n                    current += char\n                } else {\n                    if (current.isNotEmpty()) {\n                        try {\n                            val color =\n                                PaletteColor(current, ColorByteFormat.RGBA, name = currentName)\n                            result.colors.add(color)\n                            currentName = \"\"\n                        } catch (_: Throwable) {\n                            // Skip invalid hex\n                        }\n                        current = \"\"\n                    }\n                }\n            }\n\n            if (current.isNotEmpty()) {\n                try {\n                    val color = PaletteColor(current, ColorByteFormat.RGBA, name = currentName)\n                    result.colors.add(color)\n                    currentName = \"\"\n                } catch (_: Throwable) {\n                    // Skip invalid hex\n                }\n            }\n        }\n\n        if (result.colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val rgbColors = palette.allColors().map {\n            if (it.colorSpace == ColorSpace.RGB) it else it.converted(ColorSpace.RGB)\n        }\n        var content = \"\"\n\n        rgbColors.forEach { color ->\n            val rgb = color.toRgb()\n            val format = if (rgb.af < 1.0) ColorByteFormat.RGBA else ColorByteFormat.RGB\n            val hex = color.hexString(format, hashmark = true, uppercase = false)\n            if (color.name.isNotEmpty()) {\n                content += \"; ${color.name}\\n\"\n            }\n            content += \"$hex\\n\"\n        }\n\n        output.write(content.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/HPLPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Homesite Palette coder\n */\nclass HPLPaletteCoder : PaletteCoder {\n    companion object {\n        private val colorRegex = Regex(\"^\\\\s*(\\\\d+)\\\\s+(\\\\d+)\\\\s+(\\\\d+).*$\")\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n\n        if (lines.isEmpty() || !lines[0].contains(\"Palette\") || lines.size < 2 || !lines[1].contains(\n                \"Version 4.0\"\n            )\n        ) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n        var currentName = \"\"\n\n        for (line in lines.drop(3)) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) continue\n\n            if (trimmed.startsWith(\";\")) {\n                // Comment - might be a color name\n                val commentText = trimmed.substring(1).trim()\n                if (commentText.isNotEmpty()) {\n                    currentName = commentText\n                }\n                continue\n            }\n\n            colorRegex.find(line)?.let { match ->\n                val r = match.groupValues[1].toIntOrNull() ?: return@let\n                val g = match.groupValues[2].toIntOrNull() ?: return@let\n                val b = match.groupValues[3].toIntOrNull() ?: return@let\n\n                val color = PaletteColor.rgb(\n                    r = (r / 255.0).coerceIn(0.0, 1.0),\n                    g = (g / 255.0).coerceIn(0.0, 1.0),\n                    b = (b / 255.0).coerceIn(0.0, 1.0),\n                    name = currentName\n                )\n                result.colors.add(color)\n                currentName = \"\"\n            }\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var result = \"Palette\\nVersion 4.0\\n-----------\\n\"\n\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        colors.forEach { color ->\n            if (color.name.isNotEmpty()) {\n                result += \"; ${color.name}\\n\"\n            }\n            val rgb = color.toRgb()\n            val r = ((rgb.rf * 255).coerceIn(0.0, 255.0).toInt())\n            val g = ((rgb.gf * 255).coerceIn(0.0, 255.0).toInt())\n            val b = ((rgb.bf * 255).coerceIn(0.0, 255.0).toInt())\n            result += \"$r $g $b\\n\"\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/ImagePaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport android.graphics.Bitmap\nimport android.graphics.BitmapFactory\nimport android.graphics.Canvas\nimport androidx.core.graphics.createBitmap\nimport androidx.core.graphics.get\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport java.io.InputStream\nimport java.io.OutputStream\nimport android.graphics.Color as AndroidColor\n\n/**\n * Image-based palette coder\n * Note: This requires Android Bitmap API\n */\nclass ImagePaletteCoder : PaletteCoder {\n\n    override fun decode(input: InputStream): Palette {\n        val data = input.readBytes()\n        val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)\n            ?: throw PaletteCoderException.InvalidFormat()\n\n        val result = Palette.Builder()\n        val colorOrder = mutableListOf<ColorPixel>()\n\n        // Read first row of pixels - one pixel per color swatch\n        val width = bitmap.width\n        val swatchWidth = 32 // Each color is 32 pixels wide\n        val numColors = width / swatchWidth\n\n        // Read one pixel from the center of each swatch\n        for (i in 0 until numColors) {\n            val x = i * swatchWidth + swatchWidth / 2\n            if (x < width) {\n                val pixel = bitmap[x, 0]\n                val a = AndroidColor.alpha(pixel) / 255.0\n                val r = AndroidColor.red(pixel) / 255.0\n                val g = AndroidColor.green(pixel) / 255.0\n                val b = AndroidColor.blue(pixel) / 255.0\n\n                val colorPixel = ColorPixel(r, g, b, a)\n                colorOrder.add(colorPixel)\n            }\n        }\n\n        // Try to read color names from PNG text chunk or extension\n        val colorNames = mutableListOf<String>()\n        try {\n            // Check if there's a JSON extension after PNG data\n            val pngEndMarker = byteArrayOf(\n                0x49, 0x45, 0x4E, 0x44, 0xAE.toByte(), 0x42, 0x60,\n                0x82.toByte()\n            ) // IEND chunk\n            val pngEndIndex = data.indexOfSlice(pngEndMarker)\n            if (pngEndIndex >= 0 && pngEndIndex + 8 < data.size) {\n                val extensionData = data.sliceArray(pngEndIndex + 8 until data.size)\n                val extensionText = String(extensionData, java.nio.charset.StandardCharsets.UTF_8)\n                if (extensionText.startsWith(\"\\n; IMAGE_NAMES: \")) {\n                    val namesLine = extensionText.lines().find { it.startsWith(\"; IMAGE_NAMES:\") }\n                    if (namesLine != null) {\n                        val namesStr = namesLine.substring(\"; IMAGE_NAMES: \".length).trim()\n                        colorNames.addAll(namesStr.split(\"|\"))\n                    }\n                }\n            }\n        } catch (_: Throwable) {\n            // No names extension\n        }\n\n        // Convert to PaletteColor, preserving order and names\n        // Don't filter duplicates - preserve all colors in order\n        colorOrder.forEachIndexed { index, pixel ->\n            val colorName = if (index < colorNames.size) colorNames[index] else \"\"\n            val color = PaletteColor.rgb(\n                r = pixel.r,\n                g = pixel.g,\n                b = pixel.b,\n                a = pixel.a,\n                name = colorName\n            )\n            result.colors.add(color)\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val colors = palette.allColors()\n        if (colors.isEmpty()) {\n            throw PaletteCoderException.TooFewColors()\n        }\n\n        val swatchWidth = 32\n        val swatchHeight = 32\n        val bitmapWidth = colors.size * swatchWidth\n\n        val bitmap = createBitmap(bitmapWidth, swatchHeight)\n        val canvas = Canvas(bitmap)\n\n        colors.forEachIndexed { index, color ->\n            val rgb = color.toRgb()\n            val androidColor = AndroidColor.argb(\n                (rgb.af * 255).toInt().coerceIn(0, 255),\n                (rgb.rf * 255).toInt().coerceIn(0, 255),\n                (rgb.gf * 255).toInt().coerceIn(0, 255),\n                (rgb.bf * 255).toInt().coerceIn(0, 255)\n            )\n\n            val x = index * swatchWidth\n            canvas.drawRect(\n                x.toFloat(), 0f,\n                (x + swatchWidth).toFloat(), swatchHeight.toFloat(),\n                android.graphics.Paint().apply {\n                    this.color = androidColor\n                    style = android.graphics.Paint.Style.FILL\n                }\n            )\n        }\n\n        val pngOutputStream = java.io.ByteArrayOutputStream()\n        bitmap.compress(Bitmap.CompressFormat.PNG, 100, pngOutputStream)\n        val pngData = pngOutputStream.toByteArray()\n        output.write(pngData)\n\n        // Append color names as extension (non-standard but preserves names)\n        // Save all names, including empty ones, to preserve order\n        val names = colors.map { it.name }\n        val nameText = \"\\n; IMAGE_NAMES: ${names.joinToString(\"|\")}\\n\"\n        output.write(nameText.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n\n    private data class ColorPixel(\n        val r: Double,\n        val g: Double,\n        val b: Double,\n        val a: Double\n    )\n}\n\nprivate fun ByteArray.indexOfSlice(slice: ByteArray, startIndex: Int = 0): Int {\n    if (slice.isEmpty() || this.isEmpty() || slice.size > this.size) return -1\n    outer@ for (i in startIndex..this.size - slice.size) {\n        for (j in slice.indices) {\n            if (this[i + j] != slice[j]) continue@outer\n        }\n        return i\n    }\n    return -1\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/JCWPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.ColorType\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.nio.charset.Charset\n\n/**\n * Xara Palette (JCW) coder\n */\nclass JCWPaletteCoder : PaletteCoder {\n    enum class SupportedColorSpace {\n        CMYK, RGB, HSB\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val parser = BytesReader(input)\n        val result = Palette.Builder()\n\n        // Check BOM \"JCW\"\n        val bom = parser.readStringASCII(3)\n        if (bom != \"JCW\") {\n            throw PaletteCoderException.InvalidBOM()\n        }\n\n        // Version\n        val version = parser.readUInt8()\n        if (version.toInt() != 1) {\n            // Log warning but continue\n        }\n\n        // Number of colors\n        val numColors = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt()\n\n        // Expected color space for ALL colors\n        val colorSpace = parser.readUInt8().toInt()\n\n        // Expected length of color names\n        val nameLength = parser.readUInt8().toInt()\n\n        data class SupportedCS(val space: SupportedColorSpace, val type: ColorType)\n\n        val ct: SupportedCS = when (colorSpace) {\n            1, 8 -> SupportedCS(SupportedColorSpace.CMYK, ColorType.Normal)\n            9 -> SupportedCS(SupportedColorSpace.CMYK, ColorType.Spot)\n            2, 10 -> SupportedCS(SupportedColorSpace.RGB, ColorType.Normal)\n            11 -> SupportedCS(SupportedColorSpace.RGB, ColorType.Spot)\n            3, 12 -> SupportedCS(SupportedColorSpace.HSB, ColorType.Normal)\n            13 -> SupportedCS(SupportedColorSpace.HSB, ColorType.Spot)\n            else -> throw PaletteCoderException.InvalidFormat()\n        }\n\n        for (index in 0 until numColors) {\n            val c0 = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt().coerceIn(0, 10000)\n            val c1 = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt().coerceIn(0, 10000)\n            val c2 = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt().coerceIn(0, 10000)\n            val c3 = parser.readUInt16(ByteOrder.LITTLE_ENDIAN).toInt().coerceIn(0, 10000)\n\n            // Read the bytes for the name\n            val nameData = parser.readBytes(nameLength)\n\n            // Try to convert to string (ISO Latin1 or ASCII)\n            val name = try {\n                String(nameData, Charset.forName(\"ISO-8859-1\"))\n            } catch (_: Throwable) {\n                String(nameData, java.nio.charset.StandardCharsets.US_ASCII)\n            }.trimEnd { it.code == 0 }.ifEmpty { \"c$index\" }\n\n            val color = when (ct.space) {\n                SupportedColorSpace.RGB -> {\n                    PaletteColor.rgb(\n                        r = c0 / 10000.0,\n                        g = c1 / 10000.0,\n                        b = c2 / 10000.0,\n                        name = name,\n                        colorType = ct.type\n                    )\n                }\n\n                SupportedColorSpace.CMYK -> {\n                    PaletteColor.cmyk(\n                        c = c0 / 10000.0,\n                        m = c1 / 10000.0,\n                        y = c2 / 10000.0,\n                        k = c3 / 10000.0,\n                        name = name,\n                        colorType = ct.type\n                    )\n                }\n\n                SupportedColorSpace.HSB -> {\n                    PaletteColor.hsb(\n                        hf = c0 / 10000.0,\n                        sf = c1 / 10000.0,\n                        bf = c2 / 10000.0,\n                        name = name,\n                        colorType = ct.type\n                    )\n                }\n            }\n\n            result.colors.add(color)\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n\n        // Palette colors (all RGB for the first attempt)\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        // BOM\n        writer.writeStringASCII(\"JCW\")\n        // version\n        writer.writeUInt8(1u)\n\n        // The number of colors (all RGB for the moment)\n        writer.writeUInt16(colors.size.toUShort(), ByteOrder.LITTLE_ENDIAN)\n\n        // Colorspace (basic RGB)\n        writer.writeUInt8(10u)\n\n        // Name length (14 bytes)\n        writer.writeUInt8(14u)\n\n        colors.forEach { color ->\n            // Color components\n            val rgb = color.toRgb()\n            writer.writeUInt16((rgb.rf * 10000).toInt().toUShort(), ByteOrder.LITTLE_ENDIAN)\n            writer.writeUInt16((rgb.gf * 10000).toInt().toUShort(), ByteOrder.LITTLE_ENDIAN)\n            writer.writeUInt16((rgb.bf * 10000).toInt().toUShort(), ByteOrder.LITTLE_ENDIAN)\n            writer.writeUInt16(0u, ByteOrder.LITTLE_ENDIAN)\n\n            // Write the name (ISO-Latin1, trimmed to 14 bytes, padded with zeros)\n            val nameBytes = try {\n                color.name.toByteArray(Charset.forName(\"ISO-8859-1\"))\n            } catch (_: Throwable) {\n                color.name.toByteArray(java.nio.charset.StandardCharsets.US_ASCII)\n            }\n\n            val paddedName = ByteArray(14) { index ->\n                if (index < nameBytes.size) nameBytes[index] else 0\n            }\n            writer.writeData(paddedName)\n        }\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/JSONPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport kotlinx.serialization.json.Json\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * JSON palette coder\n */\nclass JSONPaletteCoder : PaletteCoder {\n    private val json = Json {\n        ignoreUnknownKeys = true\n        encodeDefaults = false\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.bufferedReader().use { it.readText() }\n        return json.decodeFromString(Palette.serializer(), text)\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val text = json.encodeToString(Palette.serializer(), palette)\n        output.bufferedWriter().use { it.write(text) }\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/KOfficePaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * KOffice Palette coder\n */\nclass KOfficePaletteCoder : PaletteCoder {\n    companion object {\n        private val colorRegex = Regex(\"^\\\\s*(\\\\d+)\\\\s+(\\\\d+)\\\\s+(\\\\d+)(.*)$\")\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n\n        if (lines.isEmpty() || !lines[0].contains(\"KDE RGB Palette\")) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n\n        for (line in lines.drop(1)) {\n            colorRegex.find(line)?.let { match ->\n                val r = match.groupValues[1].toIntOrNull() ?: return@let\n                val g = match.groupValues[2].toIntOrNull() ?: return@let\n                val b = match.groupValues[3].toIntOrNull() ?: return@let\n                val name = match.groupValues[4].trim()\n\n                val color = PaletteColor.rgb(\n                    r = (r / 255.0).coerceIn(0.0, 1.0),\n                    g = (g / 255.0).coerceIn(0.0, 1.0),\n                    b = (b / 255.0).coerceIn(0.0, 1.0),\n                    name = name\n                )\n                result.colors.add(color)\n            }\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var result = \"KDE RGB Palette\\n\"\n\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        colors.forEach { color ->\n            val rgb = color.toRgb()\n            val r = ((rgb.rf * 255).coerceIn(0.0, 255.0).toInt())\n            val g = ((rgb.gf * 255).coerceIn(0.0, 255.0).toInt())\n            val b = ((rgb.bf * 255).coerceIn(0.0, 255.0).toInt())\n            result += \"$r\\t$g\\t$b\"\n            if (color.name.isNotEmpty()) {\n                result += \"\\t${color.name}\"\n            }\n            result += \"\\n\"\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/KRITAPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.ColorType\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.xmlDecoded\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.text.DecimalFormat\nimport java.text.DecimalFormatSymbols\nimport java.util.Locale\nimport java.util.zip.CRC32\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipInputStream\nimport java.util.zip.ZipOutputStream\nimport javax.xml.parsers.SAXParserFactory\nimport kotlin.math.ceil\nimport kotlin.math.sqrt\n\n/**\n * KRITA Palette (KPL) coder\n * KPL is a ZIP archive containing a mimetype entry, colorset.xml and profiles.xml.\n */\nclass KRITAPaletteCoder : PaletteCoder {\n\n    private data class PositionedColor(\n        val row: Int,\n        val column: Int,\n        val color: PaletteColor\n    )\n\n    private class ColorsetHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n\n        private data class GroupState(\n            val name: String,\n            val colors: MutableList<PositionedColor> = mutableListOf()\n        )\n\n        private val globalColors = mutableListOf<PositionedColor>()\n        private var currentGroup: GroupState? = null\n        private var currentEntryName = \"\"\n        private var currentEntrySpot = false\n        private var currentEntryColor: PaletteColor? = null\n        private var currentEntryRow = Int.MAX_VALUE\n        private var currentEntryColumn = Int.MAX_VALUE\n\n        private fun elementName(localName: String, qName: String?): String =\n            localName.ifBlank { qName ?: \"\" }.substringAfter(':').trim().lowercase()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            when (elementName(localName, qName)) {\n                \"colorset\" -> {\n                    val name = attributes.getValue(\"name\")?.xmlDecoded()\n                    if (!name.isNullOrEmpty()) {\n                        palette.name = name\n                    }\n                }\n\n                \"group\" -> {\n                    currentGroup = GroupState(\n                        name = attributes.getValue(\"name\")?.xmlDecoded().orEmpty()\n                    )\n                }\n\n                \"colorsetentry\" -> {\n                    currentEntryName = attributes.getValue(\"name\")?.xmlDecoded().orEmpty()\n                    currentEntrySpot = attributes.getValue(\"spot\")\n                        ?.equals(\"true\", ignoreCase = true) == true\n                    currentEntryColor = null\n                    currentEntryRow = Int.MAX_VALUE\n                    currentEntryColumn = Int.MAX_VALUE\n                }\n\n                \"position\" -> {\n                    currentEntryRow = attributes.getValue(\"row\")?.toIntOrNull() ?: Int.MAX_VALUE\n                    currentEntryColumn =\n                        attributes.getValue(\"column\")?.toIntOrNull() ?: Int.MAX_VALUE\n                }\n\n                \"srgb\", \"rgb\" -> {\n                    currentEntryColor = createRgbColor(attributes)\n                }\n\n                \"cmyk\" -> {\n                    currentEntryColor = createCmykColor(attributes)\n                }\n\n                \"lab\" -> {\n                    currentEntryColor = createLabColor(attributes)\n                }\n\n                \"gray\" -> {\n                    currentEntryColor = createGrayColor(attributes)\n                }\n            }\n        }\n\n        override fun endElement(uri: String?, localName: String, qName: String?) {\n            when (elementName(localName, qName)) {\n                \"colorsetentry\" -> {\n                    currentEntryColor?.let { color ->\n                        val positionedColor = PositionedColor(\n                            row = currentEntryRow,\n                            column = currentEntryColumn,\n                            color = color\n                        )\n                        currentGroup?.colors?.add(positionedColor) ?: globalColors.add(\n                            positionedColor\n                        )\n                    }\n\n                    currentEntryColor = null\n                    currentEntryName = \"\"\n                    currentEntrySpot = false\n                    currentEntryRow = Int.MAX_VALUE\n                    currentEntryColumn = Int.MAX_VALUE\n                }\n\n                \"group\" -> {\n                    currentGroup?.let { group ->\n                        if (group.colors.isNotEmpty()) {\n                            palette.groups.add(\n                                ColorGroup(\n                                    name = group.name,\n                                    colors = group.colors.sorted().map { it.color }\n                                )\n                            )\n                        }\n                    }\n                    currentGroup = null\n                }\n            }\n        }\n\n        fun buildPalette(): Palette {\n            palette.colors = globalColors.sorted().map { it.color }.toMutableList()\n            if (palette.colors.isEmpty() && palette.groups.isEmpty()) {\n                throw PaletteCoderException.InvalidFormat()\n            }\n            return palette.build()\n        }\n\n        private fun createRgbColor(attributes: Attributes): PaletteColor? {\n            val r = attributes.getValue(\"r\")?.toDoubleOrNull() ?: return null\n            val g = attributes.getValue(\"g\")?.toDoubleOrNull() ?: return null\n            val b = attributes.getValue(\"b\")?.toDoubleOrNull() ?: return null\n\n            return PaletteColor.rgb(\n                r = r.coerceIn(0.0, 1.0),\n                g = g.coerceIn(0.0, 1.0),\n                b = b.coerceIn(0.0, 1.0),\n                name = currentEntryName,\n                colorType = currentEntryColorType()\n            )\n        }\n\n        private fun createCmykColor(attributes: Attributes): PaletteColor? {\n            val c = attributes.getValue(\"c\")?.toDoubleOrNull() ?: return null\n            val m = attributes.getValue(\"m\")?.toDoubleOrNull() ?: return null\n            val y = attributes.getValue(\"y\")?.toDoubleOrNull() ?: return null\n            val k = attributes.getValue(\"k\")?.toDoubleOrNull() ?: return null\n\n            return PaletteColor.cmyk(\n                c = c.coerceIn(0.0, 1.0),\n                m = m.coerceIn(0.0, 1.0),\n                y = y.coerceIn(0.0, 1.0),\n                k = k.coerceIn(0.0, 1.0),\n                name = currentEntryName,\n                colorType = currentEntryColorType()\n            )\n        }\n\n        private fun createLabColor(attributes: Attributes): PaletteColor? {\n            val l = (attributes.getValue(\"L\") ?: attributes.getValue(\"l\"))\n                ?.toDoubleOrNull() ?: return null\n            val a = attributes.getValue(\"a\")?.toDoubleOrNull() ?: return null\n            val b = attributes.getValue(\"b\")?.toDoubleOrNull() ?: return null\n\n            return PaletteColor.lab(\n                l = l,\n                a = a,\n                b = b,\n                name = currentEntryName,\n                colorType = currentEntryColorType()\n            )\n        }\n\n        private fun createGrayColor(attributes: Attributes): PaletteColor? {\n            val gray = (attributes.getValue(\"g\") ?: attributes.getValue(\"gray\"))\n                ?.toDoubleOrNull() ?: return null\n\n            return PaletteColor.gray(\n                white = gray.coerceIn(0.0, 1.0),\n                name = currentEntryName,\n                colorType = currentEntryColorType()\n            )\n        }\n\n        private fun currentEntryColorType(): ColorType =\n            if (currentEntrySpot) ColorType.Spot else ColorType.Normal\n\n        private fun List<PositionedColor>.sorted(): List<PositionedColor> =\n            sortedWith(compareBy({ it.row }, { it.column }))\n    }\n\n    private val numberFormatter = DecimalFormat(\"0.######\", DecimalFormatSymbols(Locale.US))\n\n    override fun decode(input: InputStream): Palette {\n        var colorsetXmlData: ByteArray? = null\n\n        ZipInputStream(input.buffered()).use { zipInputStream ->\n            var entry = zipInputStream.nextEntry\n            while (entry != null) {\n                if (entry.name.equals(\"colorset.xml\", ignoreCase = true) ||\n                    entry.name.lowercase().endsWith(\"/colorset.xml\")\n                ) {\n                    colorsetXmlData = zipInputStream.readBytes()\n                    break\n                }\n                zipInputStream.closeEntry()\n                entry = zipInputStream.nextEntry\n            }\n        }\n\n        val xmlData = colorsetXmlData ?: throw PaletteCoderException.InvalidFormat()\n        val handler = ColorsetHandler()\n        val factory = SAXParserFactory.newInstance()\n        factory.isNamespaceAware = true\n        factory.isValidating = false\n        val parser = factory.newSAXParser()\n        parser.parse(xmlData.inputStream(), handler)\n\n        return handler.buildPalette()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        if (palette.totalColorCount == 0) {\n            throw PaletteCoderException.TooFewColors()\n        }\n\n        val colorsetXml = buildColorsetXml(palette)\n        val profilesXml = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Profiles/>\n\"\"\"\n\n        ZipOutputStream(output).use { zipOutputStream ->\n            writeStoredEntry(\n                zipOutputStream = zipOutputStream,\n                name = \"mimetype\",\n                data = KPL_MIME_TYPE.toByteArray(Charsets.US_ASCII)\n            )\n            writeTextEntry(zipOutputStream, \"colorset.xml\", colorsetXml)\n            writeTextEntry(zipOutputStream, \"profiles.xml\", profilesXml)\n        }\n    }\n\n    private fun buildColorsetXml(palette: Palette): String {\n        val maxColorCount = maxOf(\n            palette.colors.size,\n            palette.groups.maxOfOrNull { it.colors.size } ?: 0,\n            1\n        )\n        val columns = ceil(sqrt(maxColorCount.toDouble())).toInt().coerceAtLeast(1)\n\n        return buildString {\n            appendLine(\"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\"\"\")\n            appendLine(\n                \"\"\"<Colorset name=\"${sanitizeXmlText(palette.name).xmlEscaped()}\" comment=\"\" columns=\"$columns\" rows=\"${\n                    rowCount(\n                        palette.colors.size,\n                        columns\n                    )\n                }\" readonly=\"false\" version=\"1.0\">\"\"\"\n            )\n\n            appendColorEntries(\n                colors = palette.colors,\n                columns = columns,\n                indent = \"  \",\n                idPrefix = \"global\"\n            )\n\n            palette.groups.forEachIndexed { index, group ->\n                appendLine(\n                    \"\"\"  <Group name=\"${sanitizeXmlText(group.name).xmlEscaped()}\" rows=\"${\n                        rowCount(\n                            group.colors.size,\n                            columns\n                        )\n                    }\">\"\"\"\n                )\n                appendColorEntries(\n                    colors = group.colors,\n                    columns = columns,\n                    indent = \"    \",\n                    idPrefix = \"group_${index + 1}\"\n                )\n                appendLine(\"  </Group>\")\n            }\n\n            appendLine(\"</Colorset>\")\n        }\n    }\n\n    private fun StringBuilder.appendColorEntries(\n        colors: List<PaletteColor>,\n        columns: Int,\n        indent: String,\n        idPrefix: String\n    ) {\n        colors.forEachIndexed { index, color ->\n            val row = index / columns\n            val column = index % columns\n            val colorName = sanitizeXmlText(color.name)\n            val colorId = sanitizeId(\"${idPrefix}_${index + 1}\")\n            val rgb = color.toRgb()\n\n            appendLine(\n                \"\"\"${indent}<ColorSetEntry name=\"${colorName.xmlEscaped()}\" id=\"$colorId\" bitdepth=\"F32\" spot=\"${color.colorType == ColorType.Spot}\">\"\"\"\n            )\n            appendLine(\n                \"\"\"${indent}  <sRGB r=\"${formatUnit(rgb.rf)}\" g=\"${formatUnit(rgb.gf)}\" b=\"${\n                    formatUnit(\n                        rgb.bf\n                    )\n                }\"/>\"\"\"\n            )\n            appendLine(\"\"\"${indent}  <Position row=\"$row\" column=\"$column\"/>\"\"\")\n            appendLine(\"${indent}</ColorSetEntry>\")\n        }\n    }\n\n    private fun writeStoredEntry(\n        zipOutputStream: ZipOutputStream,\n        name: String,\n        data: ByteArray\n    ) {\n        val crc32 = CRC32().apply { update(data) }\n        val entry = ZipEntry(name).apply {\n            method = ZipEntry.STORED\n            size = data.size.toLong()\n            compressedSize = data.size.toLong()\n            crc = crc32.value\n        }\n        zipOutputStream.putNextEntry(entry)\n        zipOutputStream.write(data)\n        zipOutputStream.closeEntry()\n    }\n\n    private fun writeTextEntry(\n        zipOutputStream: ZipOutputStream,\n        name: String,\n        content: String\n    ) {\n        zipOutputStream.putNextEntry(ZipEntry(name))\n        zipOutputStream.write(content.toByteArray(Charsets.UTF_8))\n        zipOutputStream.closeEntry()\n    }\n\n    private fun formatUnit(value: Double): String = numberFormatter.format(value.coerceIn(0.0, 1.0))\n\n    private fun rowCount(colorCount: Int, columns: Int): Int =\n        if (colorCount <= 0) 0 else ceil(colorCount / columns.toDouble()).toInt()\n\n    private fun sanitizeXmlText(value: String): String =\n        value.replace(Regex(\"[\\\\r\\\\n\\\\t]+\"), \" \").trim()\n\n    private fun sanitizeId(value: String): String =\n        value.replace(Regex(\"[^A-Za-z0-9_.-]+\"), \"_\").trim('_').ifEmpty { \"color\" }\n\n    companion object {\n        private const val KPL_MIME_TYPE = \"application/x-krita-palette\"\n    }\n}\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/KotlinPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Kotlin/Jetpack Compose code generator\n */\nclass KotlinPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val result = Palette.Builder()\n\n        // Parse Color(0xAARRGGBB) or Color(0xRRGGBB)\n        // Also try to capture variable names: val name: Color = Color(0x...)\n        val colorRegex = Regex(\n            \"\"\"(?:val\\s+(\\w+)\\s*:\\s*Color\\s*=\\s*)?Color\\s*\\(\\s*0x([0-9A-Fa-f]{6,8})\\s*\\)\"\"\",\n            RegexOption.IGNORE_CASE\n        )\n\n        // Use Set to track unique colors by RGB values to avoid duplicates\n        val seenColors = mutableSetOf<Triple<Int, Int, Int>>()\n        var colorIndex = 0\n\n        colorRegex.findAll(text).forEach { match ->\n            try {\n                val colorName = match.groupValues[1].takeIf { it.isNotEmpty() } ?: \"\"\n                val hexValue = match.groupValues[2]\n                val value = hexValue.toLongOrNull(16) ?: return@forEach\n\n                val (r, g, b, a) = if (hexValue.length == 8) {\n                    // AARRGGBB\n                    val aVal = ((value shr 24) and 0xFF) / 255.0\n                    val rVal = ((value shr 16) and 0xFF) / 255.0\n                    val gVal = ((value shr 8) and 0xFF) / 255.0\n                    val bVal = (value and 0xFF) / 255.0\n                    Quad(rVal, gVal, bVal, aVal)\n                } else {\n                    // RRGGBB\n                    val rVal = ((value shr 16) and 0xFF) / 255.0\n                    val gVal = ((value shr 8) and 0xFF) / 255.0\n                    val bVal = (value and 0xFF) / 255.0\n                    Quad(rVal, gVal, bVal, 1.0)\n                }\n\n                // Check for duplicates by RGB values (rounded to avoid floating point issues)\n                val rInt = (r * 255).toInt()\n                val gInt = (g * 255).toInt()\n                val bInt = (b * 255).toInt()\n                val colorKey = Triple(rInt, gInt, bInt)\n\n                if (colorKey !in seenColors) {\n                    seenColors.add(colorKey)\n\n                    val finalName = if (colorName.isNotEmpty()) {\n                        colorName\n                    } else {\n                        \"Color_$colorIndex\"\n                    }\n\n                    val color = PaletteColor.rgb(\n                        r = r.coerceIn(0.0, 1.0),\n                        g = g.coerceIn(0.0, 1.0),\n                        b = b.coerceIn(0.0, 1.0),\n                        a = a.coerceIn(0.0, 1.0),\n                        name = finalName\n                    )\n                    result.colors.add(color)\n                    colorIndex++\n                }\n            } catch (_: Throwable) {\n                // Skip invalid colors\n            }\n        }\n\n        // Try to extract palette name from comments or object name\n        val objectNameMatch = Regex(\"\"\"object\\s+(\\w+)\"\"\").find(text)\n        if (objectNameMatch != null) {\n            result.name = objectNameMatch.groupValues[1]\n        } else {\n            val commentMatch = Regex(\"\"\"Exported palette:\\s*(.+)\"\"\").find(text)\n            if (commentMatch != null) {\n                result.name = commentMatch.groupValues[1].trim()\n            }\n        }\n\n        if (result.colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return result.build()\n    }\n\n    private data class Quad(val r: Double, val g: Double, val b: Double, val a: Double)\n\n    private fun sanitizeName(name: String): String {\n        // Remove invalid characters and make it a valid Kotlin identifier\n        return name\n            .replace(Regex(\"[^a-zA-Z0-9_]\"), \"_\")\n            .replace(Regex(\"^[0-9]\"), \"_$0\") // Can't start with digit\n            .takeIf { it.isNotEmpty() } ?: \"color\"\n    }\n\n    private fun formatColor(rgb: PaletteColor.RGB): String {\n        val r = (rgb.rf * 255).toInt().coerceIn(0, 255)\n        val g = (rgb.gf * 255).toInt().coerceIn(0, 255)\n        val b = (rgb.bf * 255).toInt().coerceIn(0, 255)\n        val a = (rgb.af * 255).toInt().coerceIn(0, 255)\n\n        // Format: Color(0xAARRGGBB)\n        val argb = (a shl 24) or (r shl 16) or (g shl 8) or b\n        return \"Color(0x${argb.toUInt().toString(16).uppercase().padStart(8, '0')})\"\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val packageName = if (palette.name.isNotEmpty()) {\n            palette.name.lowercase()\n                .replace(Regex(\"[^a-z0-9]\"), \"\")\n                .takeIf { it.isNotEmpty() && it[0].isLetter() }\n                ?: \"palette\"\n        } else {\n            \"palette\"\n        }\n\n        var result = \"package $packageName\\n\\n\"\n        result += \"import androidx.compose.ui.graphics.Color\\n\\n\"\n        result += \"/**\\n\"\n        result += \" * Exported palette: ${palette.name.ifEmpty { \"Untitled\" }}\\n\"\n        result += \" * Total colors: ${palette.totalColorCount}\\n\"\n        result += \" */\\n\"\n        result += \"object ExportedPalette {\\n\\n\"\n\n        // Generate individual color constants with names\n        val allColorsList = palette.allColors()\n        if (allColorsList.isNotEmpty()) {\n            result += \"    // Individual color constants\\n\"\n            allColorsList.forEachIndexed { index, color ->\n                try {\n                    val converted =\n                        if (color.colorSpace == ColorSpace.RGB) color else color.converted(\n                            ColorSpace.RGB\n                        )\n                    val rgb = converted.toRgb()\n                    val colorName = if (color.name.isNotEmpty()) {\n                        sanitizeName(color.name)\n                    } else {\n                        \"color$index\"\n                    }\n                    result += \"    val $colorName: Color = ${formatColor(rgb)}\\n\"\n                } catch (_: Throwable) {\n                    // Skip invalid colors\n                }\n            }\n            result += \"\\n\"\n        }\n\n        // Generate groups\n        palette.allGroups.forEachIndexed { groupIndex, group ->\n            if (group.colors.isEmpty()) return@forEachIndexed\n\n            val groupName = if (group.name.isNotEmpty() && group.name != \"global\") {\n                sanitizeName(group.name)\n            } else {\n                \"group$groupIndex\"\n            }\n\n            result += \"    // Group: ${group.name}\\n\"\n            result += \"    val $groupName: List<Color> = listOf(\\n\"\n\n            group.colors.forEachIndexed { index, color ->\n                try {\n                    val converted =\n                        if (color.colorSpace == ColorSpace.RGB) color else color.converted(\n                            ColorSpace.RGB\n                        )\n                    val rgb = converted.toRgb()\n                    val indent = \"        \"\n                    result += \"$indent${formatColor(rgb)}\"\n\n                    if (index < group.colors.size - 1) {\n                        result += \",\"\n                    }\n                    result += \"\\n\"\n                } catch (_: Throwable) {\n                    // Skip invalid colors\n                }\n            }\n\n            result += \"    )\\n\\n\"\n        }\n\n        // Generate allColors list\n        val allColors = allColorsList.mapNotNull { color ->\n            try {\n                val converted =\n                    if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n                converted.toRgb()\n            } catch (_: Throwable) {\n                null\n            }\n        }\n\n        if (allColors.isNotEmpty()) {\n            result += \"    /**\\n\"\n            result += \"     * All colors from all groups\\n\"\n            result += \"     */\\n\"\n            result += \"    val allColors: List<Color> = listOf(\\n\"\n\n            allColors.forEachIndexed { index, rgb ->\n                val indent = \"        \"\n                result += \"$indent${formatColor(rgb)}\"\n\n                if (index < allColors.size - 1) {\n                    result += \",\"\n                }\n                result += \"\\n\"\n            }\n\n            result += \"    )\\n\"\n        }\n\n        result += \"}\\n\"\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/OpenOfficePaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.xmlDecoded\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.nio.charset.StandardCharsets\nimport javax.xml.parsers.SAXParserFactory\n\n/**\n * OpenOffice palette coder\n */\nclass OpenOfficePaletteCoder : PaletteCoder {\n\n    private class OpenOfficeXMLHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n        private var currentChars = StringBuilder()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            if (localName == \"draw:color\" || qName == \"draw:color\") {\n                val name = attributes.getValue(\"draw:name\")?.xmlDecoded() ?: \"\"\n                val colorString = attributes.getValue(\"draw:color\") ?: \"\"\n\n                try {\n                    val color = PaletteColor(\n                        rgbHexString = colorString,\n                        format = ColorByteFormat.RGB,\n                        name = name\n                    )\n                    palette.colors.add(color)\n                } catch (_: Throwable) {\n                    // Skip invalid colors\n                }\n            }\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val handler = OpenOfficeXMLHandler()\n        val factory = SAXParserFactory.newInstance()\n        factory.isNamespaceAware = true\n        val parser = factory.newSAXParser()\n        parser.parse(input, handler)\n\n        val palette = handler.palette.build()\n\n        if (palette.totalColorCount == 0) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return palette\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var xml = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<office:color-table xmlns:office=\"http://openoffice.org/2000/office\" xmlns:style=\"http://openoffice.org/2000/style\" xmlns:text=\"http://openoffice.org/2000/text\" xmlns:table=\"http://openoffice.org/2000/table\" xmlns:draw=\"http://openoffice.org/2000/drawing\" xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:meta=\"http://openoffice.org/2000/meta\" xmlns:number=\"http://openoffice.org/2000/datastyle\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:chart=\"http://openoffice.org/2000/chart\" xmlns:dr3d=\"http://openoffice.org/2000/dr3d\" xmlns:math=\"http://www.w3.org/1998/Math/MathML\" xmlns:form=\"http://openoffice.org/2000/form\" xmlns:script=\"http://openoffice.org/2000/script\">\n\"\"\"\n\n        palette.allColors().forEach { color ->\n            try {\n                val hex = color.hexString(ColorByteFormat.RGB, hashmark = true, uppercase = true)\n                xml += \"<draw:color draw:name=\\\"${color.name.xmlEscaped()}\\\" draw:color=\\\"$hex\\\"/>\\n\"\n            } catch (_: Throwable) {\n                // Skip colors that can't be converted\n            }\n        }\n\n        xml += \"</office:color-table>\\n\"\n\n        output.write(xml.toByteArray(StandardCharsets.UTF_8))\n    }\n}\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/PaintNETPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Paint.NET palette coder\n */\nclass PaintNETPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val allData = input.readBytes()\n\n        // Check for UTF-8 BOM\n        val data = if (allData.size >= 3 &&\n            allData[0].toInt() == 0xEF &&\n            allData[1].toInt() == 0xBB &&\n            allData[2].toInt() == 0xBF\n        ) {\n            allData.drop(3).toByteArray()\n        } else {\n            allData\n        }\n\n        val content = String(data, java.nio.charset.StandardCharsets.UTF_8)\n        val result = Palette.Builder()\n\n        var currentName = \"\"\n        for (line in content.lines()) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) {\n                continue\n            }\n\n            if (trimmed.startsWith(\";\")) {\n                // Comment - might be a color name\n                val commentText = trimmed.substring(1).trim()\n                if (commentText.startsWith(\"Palette Name\", ignoreCase = true) ||\n                    commentText.startsWith(\"Palette:\", ignoreCase = true)\n                ) {\n                    val name = commentText.substringAfter(\":\").trim()\n                    if (name.isNotBlank()) {\n                        result.name = name\n                    }\n                    continue\n                }\n                if (commentText.isNotEmpty() && !commentText.contains(\"paint.net\") && !commentText.contains(\n                        \"Colors are written\"\n                    ) && !commentText.contains(\n                        \"Downloaded\"\n                    ) && !commentText.contains(\n                        \"Description\"\n                    ) && !commentText.contains(\n                        \"Colors\"\n                    )\n                ) {\n                    currentName = commentText\n                }\n                continue\n            }\n\n            if (trimmed.length != 8) {\n                throw PaletteCoderException.InvalidFormat()\n            }\n\n            // Parse AARRGGBB\n            val a = trimmed.take(2).toIntOrNull(16) ?: continue\n            val r = trimmed.substring(2, 4).toIntOrNull(16) ?: continue\n            val g = trimmed.substring(4, 6).toIntOrNull(16) ?: continue\n            val b = trimmed.substring(6, 8).toIntOrNull(16) ?: continue\n\n            val color = PaletteColor.rgb(\n                r = r / 255.0,\n                g = g / 255.0,\n                b = b / 255.0,\n                a = a / 255.0,\n                name = currentName\n            )\n            result.colors.add(color)\n            currentName = \"\"\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val rgbColors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        var content = \"\"\"; paint.net Palette File\n; Lines that start with a semicolon are comments\n; Colors are written as 8-digit hexadecimal numbers: aarrggbb\n\"\"\"\n        if (palette.name.isNotEmpty()) {\n            content += \"; Palette Name: ${palette.name}\\r\\n\"\n        }\n        rgbColors.forEach { color ->\n            color.toRgb()\n            if (color.name.isNotEmpty()) {\n                content += \"; ${color.name}\\r\\n\"\n            }\n            val hex = color.hexString(ColorByteFormat.ARGB, hashmark = false, uppercase = true)\n            content += \"$hex\\r\\n\"\n        }\n\n        output.write(content.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/PaintShopProPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Paint Shop Pro (JASC-PAL) palette coder\n */\nclass PaintShopProPaletteCoder : PaletteCoder {\n    companion object {\n        private val colorRegex = Regex(\"^\\\\s*(\\\\d+)\\\\s+(\\\\d+)\\\\s+(\\\\d+)\\\\s*$\")\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n\n        if (lines.size < 3) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        // Check BOM\n        if (!lines[0].contains(\"JASC-PAL\")) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        // Check version\n        if (lines[1] != \"0100\") {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        // Get color count\n        lines[2].toIntOrNull() ?: throw PaletteCoderException.InvalidFormat()\n\n        val result = Palette.Builder()\n        var currentName = \"\"\n\n        for (line in lines.drop(3)) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) continue\n\n            if (trimmed.startsWith(\";\")) {\n                // Comment - might be a color name\n                val commentText = trimmed.substring(1).trim()\n                if (commentText.isNotEmpty()) {\n                    currentName = commentText\n                }\n                continue\n            }\n\n            colorRegex.find(line)?.let { match ->\n                val r = match.groupValues[1].toIntOrNull() ?: return@let\n                val g = match.groupValues[2].toIntOrNull() ?: return@let\n                val b = match.groupValues[3].toIntOrNull() ?: return@let\n\n                val color = PaletteColor.rgb(\n                    r = (r / 255.0).coerceIn(0.0, 1.0),\n                    g = (g / 255.0).coerceIn(0.0, 1.0),\n                    b = (b / 255.0).coerceIn(0.0, 1.0),\n                    name = currentName\n                )\n                result.colors.add(color)\n                currentName = \"\"\n            }\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val flattenedColors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        var result = \"JASC-PAL\\n0100\\n${flattenedColors.size}\\n\"\n\n        flattenedColors.forEach { color ->\n            if (color.name.isNotEmpty()) {\n                result += \"; ${color.name}\\n\"\n            }\n            val rgb = color.toRgb()\n            val r = ((rgb.rf * 255).coerceIn(0.0, 255.0).toInt())\n            val g = ((rgb.gf * 255).coerceIn(0.0, 255.0).toInt())\n            val b = ((rgb.bf * 255).coerceIn(0.0, 255.0).toInt())\n            result += \"$r $g $b\\n\"\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/PaletteFormatCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteFormat\n\nclass PaletteFormatCoder(\n    val paletteFormat: PaletteFormat\n) : PaletteCoder by when (paletteFormat) {\n    PaletteFormat.ACB -> ACBPaletteCoder()\n    PaletteFormat.ACO -> ACOPaletteCoder()\n    PaletteFormat.ACT -> ACTPaletteCoder()\n    PaletteFormat.ANDROID_XML -> AndroidColorsXMLCoder()\n    PaletteFormat.ASE -> ASEPaletteCoder()\n    PaletteFormat.BASIC_XML -> BasicXMLCoder()\n    PaletteFormat.COREL_PAINTER -> CorelPainterCoder()\n    PaletteFormat.COREL_DRAW -> CorelXMLPaletteCoder()\n    PaletteFormat.SCRIBUS_XML -> ScribusXMLPaletteCoder()\n    PaletteFormat.COREL_PALETTE -> CPLPaletteCoder()\n    PaletteFormat.CSV -> CSVPaletteCoder()\n    PaletteFormat.DCP -> DCPPaletteCoder()\n    PaletteFormat.GIMP -> GIMPPaletteCoder()\n    PaletteFormat.HEX_RGBA -> HEXPaletteCoder()\n    PaletteFormat.IMAGE -> ImagePaletteCoder()\n    PaletteFormat.JSON -> JSONPaletteCoder()\n    PaletteFormat.OPEN_OFFICE -> OpenOfficePaletteCoder()\n    PaletteFormat.PAINT_NET -> PaintNETPaletteCoder()\n    PaletteFormat.PAINT_SHOP_PRO -> PaintShopProPaletteCoder()\n    PaletteFormat.RGBA -> RGBAPaletteCoder()\n    PaletteFormat.RGB -> RGBPaletteCoder()\n    PaletteFormat.RIFF -> RIFFPaletteCoder()\n    PaletteFormat.SKETCH -> SketchPaletteCoder()\n    PaletteFormat.SVG -> SVGPaletteCoder()\n    PaletteFormat.SKP -> SKPPaletteCoder()\n    PaletteFormat.SWIFT -> SwiftPaletteCoder()\n    PaletteFormat.KOTLIN -> KotlinPaletteCoder()\n    PaletteFormat.COREL_DRAW_V3 -> CorelDraw3PaletteCoder()\n    PaletteFormat.CLF -> CLFPaletteCoder()\n    PaletteFormat.SWATCHES -> ProcreateSwatchesCoder()\n    PaletteFormat.AUTODESK_COLOR_BOOK -> AutodeskColorBookCoder()\n    PaletteFormat.SIMPLE_PALETTE -> SimplePaletteCoder()\n    PaletteFormat.SWATCHBOOKER -> SwatchbookerCoder()\n    PaletteFormat.AFPALETTE -> AFPaletteCoder()\n    PaletteFormat.XARA -> JCWPaletteCoder()\n    PaletteFormat.KOFFICE -> KOfficePaletteCoder()\n    PaletteFormat.HPL -> HPLPaletteCoder()\n    PaletteFormat.SKENCIL -> SkencilPaletteCoder()\n    PaletteFormat.VGA_24BIT -> VGA24BitPaletteCoder()\n    PaletteFormat.VGA_18BIT -> VGA18BitPaletteCoder()\n    PaletteFormat.KRITA -> KRITAPaletteCoder()\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/ProcreateSwatchesCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport kotlinx.serialization.Serializable\nimport kotlinx.serialization.json.Json\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipInputStream\nimport java.util.zip.ZipOutputStream\n\n/**\n * Procreate Swatches coder\n */\nclass ProcreateSwatchesCoder : PaletteCoder {\n    private val json = Json {\n        ignoreUnknownKeys = true\n    }\n\n    @Serializable\n    private data class Swatch(\n        val name: String? = null,\n        val hue: Double,\n        val saturation: Double,\n        val brightness: Double,\n        val alpha: Double = 1.0,\n        val colorSpace: Int? = null,\n        val origin: Int? = null,\n        val colorModel: Int? = null,\n        val colorProfile: String? = null,\n        val version: String? = null,\n        val components: List<Double>? = null\n    )\n\n    @Serializable\n    private data class SwatchPalette(\n        val name: String,\n        val swatches: List<Swatch?>\n    )\n\n    override fun decode(input: InputStream): Palette {\n        val data = input.readBytes()\n        val zipInputStream = ZipInputStream(java.io.ByteArrayInputStream(data))\n\n        var jsonData = ByteArray(0)\n        var entry: ZipEntry? = zipInputStream.nextEntry\n        while (entry != null) {\n            if (entry.name == \"Swatches.json\") {\n                jsonData = zipInputStream.readBytes()\n                break\n            }\n            entry = zipInputStream.nextEntry\n        }\n        zipInputStream.close()\n\n        if (jsonData.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val jsonText = String(jsonData, java.nio.charset.StandardCharsets.UTF_8)\n\n        val swatches: List<SwatchPalette> = try {\n            json.decodeFromString<List<SwatchPalette>>(jsonText)\n        } catch (_: Throwable) {\n            // Try single palette\n            try {\n                listOf(json.decodeFromString(SwatchPalette.serializer(), jsonText))\n            } catch (_: Throwable) {\n                throw PaletteCoderException.InvalidFormat()\n            }\n        }\n\n        val result = Palette.Builder()\n\n        swatches.forEach { palette ->\n            val groupColors = palette.swatches\n                .filterNotNull()\n                .map { swatch ->\n                    val color = PaletteColor.hsb(\n                        hf = swatch.hue,\n                        sf = swatch.saturation,\n                        bf = swatch.brightness,\n                        alpha = swatch.alpha,\n                        name = swatch.name ?: \"\"\n                    )\n                    color\n                }\n\n            if (groupColors.isNotEmpty()) {\n                // Add colors to main palette if it's the first group or if palette name is empty\n                if (result.colors.isEmpty() && result.groups.isEmpty()) {\n                    result.colors.addAll(groupColors)\n                    result.name = palette.name\n                } else {\n                    val group =\n                        ColorGroup(colors = groupColors.toMutableList(), name = palette.name)\n                    result.groups.add(group)\n                }\n            }\n        }\n\n        val palette = result.build()\n\n        if (palette.totalColorCount == 0) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return palette\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        if (palette.totalColorCount == 0) {\n            throw PaletteCoderException.TooFewColors()\n        }\n\n        // Map each group in the palette\n        val groups =\n            listOf(ColorGroup(colors = palette.colors, name = palette.name)) + palette.groups\n\n        val mapped: List<SwatchPalette> = groups.mapNotNull { group ->\n            if (group.colors.isEmpty()) {\n                return@mapNotNull null\n            }\n\n            SwatchPalette(\n                name = group.name,\n                swatches = group.colors.map { color ->\n                    val hsb = color.toHsb()\n                    Swatch(\n                        name = color.name.ifEmpty { null },\n                        hue = hsb.hf,\n                        saturation = hsb.sf,\n                        brightness = hsb.bf,\n                        alpha = hsb.af\n                    )\n                }\n            )\n        }\n\n        val jsonData = json.encodeToString<List<SwatchPalette>>(mapped)\n\n        // Create ZIP archive\n        val zipOutputStream = ZipOutputStream(output)\n        val entry = ZipEntry(\"Swatches.json\")\n        zipOutputStream.putNextEntry(entry)\n        zipOutputStream.write(jsonData.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n        zipOutputStream.closeEntry()\n        zipOutputStream.close()\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/RGBAPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * RGBA text palette coder\n */\nclass RGBAPaletteCoder : PaletteCoder {\n    companion object {\n        private val regex = Regex(\"^#?\\\\s*([a-f0-9]{3,8})\\\\s*(.*)\\\\s*\", RegexOption.IGNORE_CASE)\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n        val result = Palette.Builder()\n\n        for (line in lines) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) continue\n\n            val matches = regex.findAll(trimmed).toList()\n            if (matches.isEmpty()) {\n                throw PaletteCoderException.InvalidRGBAHexString(trimmed)\n            }\n\n            matches.forEach { match ->\n                val hex = match.groupValues[1]\n                val name = match.groupValues[2].trim()\n\n                try {\n                    val color = PaletteColor(hex, ColorByteFormat.RGBA, name)\n                    result.colors.add(color)\n                } catch (_: Throwable) {\n                    throw PaletteCoderException.InvalidRGBAHexString(hex)\n                }\n            }\n        }\n\n        val palette = result.build()\n\n        if (palette.allColors().isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return palette\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val flattenedColors = palette.allColors().map {\n            if (it.colorSpace == ColorSpace.RGB) it else it.converted(ColorSpace.RGB)\n        }\n        var result = \"\"\n\n        flattenedColors.forEach { color ->\n            if (result.isNotEmpty()) {\n                result += \"\\r\\n\"\n            }\n            val rgb = color.toRgb()\n            result += rgb.hexString(\n                format = ColorByteFormat.RGBA,\n                hashmark = true,\n                uppercase = false\n            )\n            if (color.name.isNotEmpty()) {\n                result += \" ${color.name}\"\n            }\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/RGBPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * RGB text palette coder\n */\nclass RGBPaletteCoder : PaletteCoder {\n    companion object {\n        private val regex = Regex(\"^#?\\\\s*([a-f0-9]{3,8})\\\\s*(.*)\\\\s*\", RegexOption.IGNORE_CASE)\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n        val result = Palette.Builder()\n\n        for (line in lines) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) continue\n\n            regex.findAll(trimmed).forEach { match ->\n                val hex = match.groupValues[1]\n                val name = match.groupValues[2].trim()\n\n                try {\n                    val color = PaletteColor(hex, ColorByteFormat.RGB, name)\n                    result.colors.add(color)\n                } catch (_: Throwable) {\n                    // Skip invalid color\n                }\n            }\n        }\n\n        val palette = result.build()\n\n        if (palette.allColors().isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return palette\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val flattenedColors = palette.allColors().map {\n            if (it.colorSpace == ColorSpace.RGB) it else it.converted(ColorSpace.RGB)\n        }\n        var result = \"\"\n\n        flattenedColors.forEach { color ->\n            if (result.isNotEmpty()) {\n                result += \"\\r\\n\"\n            }\n            result += color.hexString(\n                format = ColorByteFormat.RGB,\n                hashmark = true,\n                uppercase = false\n            )\n            if (color.name.isNotEmpty()) {\n                result += \" ${color.name}\"\n            }\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/RIFFPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.ByteOrder\nimport com.t8rin.palette.utils.BytesReader\nimport com.t8rin.palette.utils.BytesWriter\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Microsoft RIFF palette coder\n */\nclass RIFFPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val parser = BytesReader(input)\n        val result = Palette.Builder()\n\n        val header = parser.readStringASCII(4)\n        if (header != \"RIFF\") {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        parser.readInt32(ByteOrder.LITTLE_ENDIAN)\n\n        val riffType = parser.readStringASCII(4)\n        if (riffType != \"PAL \") {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val dataHeader = parser.readStringASCII(4)\n        parser.readInt32(ByteOrder.LITTLE_ENDIAN)\n        if (dataHeader != \"data\") {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        parser.readInt16(ByteOrder.LITTLE_ENDIAN) // palVersion\n        val palNumEntries = parser.readInt16(ByteOrder.LITTLE_ENDIAN)\n\n        for (i in 0 until palNumEntries) {\n            val rgb = parser.readData(4)\n            val r = rgb[0].toUByte().toInt()\n            val g = rgb[1].toUByte().toInt()\n            val b = rgb[2].toUByte().toInt()\n            // rgb[3] is unused\n\n            val color = PaletteColor.rgb(\n                r = r / 255.0,\n                g = g / 255.0,\n                b = b / 255.0\n            )\n            result.colors.add(color)\n        }\n\n        // Try to read color names from \"name\" chunk (non-standard extension)\n        try {\n            val nameHeader = parser.readInt32(ByteOrder.BIG_ENDIAN)\n            if (nameHeader == 0x6E616D65) { // \"name\" in ASCII\n                val nameChunkSize = parser.readInt32(ByteOrder.LITTLE_ENDIAN)\n                val nameData = parser.readData(nameChunkSize)\n                val nameText =\n                    String(nameData, java.nio.charset.StandardCharsets.UTF_8).trimEnd('\\u0000')\n                val names = nameText.split(\"\\n\")\n                names.forEachIndexed { index, name ->\n                    if (index < result.colors.size && name.isNotEmpty()) {\n                        result.colors[index] = result.colors[index].named(name)\n                    }\n                }\n            } else {\n                // Not a name chunk, reset position\n                parser.seekSet((parser.readPosition - 4).toInt())\n            }\n        } catch (_: Throwable) {\n            // No names chunk, continue without names\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val writer = BytesWriter(output)\n        val sourceColors = palette.allColors()\n        val allColors = sourceColors.map { it.toRgb() }\n        val colorCount = allColors.size\n\n        val dataChunkSize = 2 + 2 + colorCount * 4\n        val dataChunkTotalSize = 8 + dataChunkSize\n\n        val names = sourceColors.map { it.name }\n        val hasNames = names.any { it.isNotEmpty() }\n        val nameBytes = if (hasNames) {\n            names.joinToString(\"\\n\").toByteArray(java.nio.charset.StandardCharsets.UTF_8)\n        } else {\n            ByteArray(0)\n        }\n        val nameChunkPadding = if (hasNames && nameBytes.size % 2 != 0) 1 else 0\n        val nameChunkTotalSize = if (hasNames) 8 + nameBytes.size + nameChunkPadding else 0\n        val fileSizeMinus8 = 4 + dataChunkTotalSize + nameChunkTotalSize\n\n        writer.writeInt32(0x52494646, ByteOrder.BIG_ENDIAN)\n        writer.writeInt32(fileSizeMinus8, ByteOrder.LITTLE_ENDIAN)\n        writer.writeInt32(0x50414C20, ByteOrder.BIG_ENDIAN)\n        writer.writeInt32(0x64617461, ByteOrder.BIG_ENDIAN)\n        writer.writeInt32(dataChunkSize, ByteOrder.LITTLE_ENDIAN)\n\n        // palVersion (2 bytes, little endian) - typically 3\n        writer.writeInt16(3, ByteOrder.LITTLE_ENDIAN)\n\n        // palNumEntries (2 bytes, little endian)\n        writer.writeInt16(colorCount.toShort(), ByteOrder.LITTLE_ENDIAN)\n\n        // Write colors (4 bytes each: R, G, B, unused)\n        allColors.forEach { rgb ->\n            writer.writeByte((rgb.rf * 255).toInt().coerceIn(0, 255).toByte())\n            writer.writeByte((rgb.gf * 255).toInt().coerceIn(0, 255).toByte())\n            writer.writeByte((rgb.bf * 255).toInt().coerceIn(0, 255).toByte())\n            writer.writeByte(0) // unused\n        }\n\n        if (hasNames) {\n            writer.writeInt32(0x6E616D65, ByteOrder.BIG_ENDIAN)\n            writer.writeInt32(nameBytes.size, ByteOrder.LITTLE_ENDIAN)\n            writer.writeData(nameBytes)\n            if (nameChunkPadding != 0) {\n                writer.writeByte(0)\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/SKPPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * SK1 Color Palette coder\n */\nclass SKPPaletteCoder : PaletteCoder {\n    companion object {\n        private val rgbColorRegex =\n            Regex(\"color\\\\(\\\\['RGB', \\\\[(\\\\d+(?:\\\\.\\\\d+)?), (\\\\d+(?:\\\\.\\\\d+)?), (\\\\d+(?:\\\\.\\\\d+)?)], (\\\\d+(?:\\\\.\\\\d+)?),.*?'(.*?)'\")\n        private val paletteNameRegex = Regex(\"set_name\\\\(.*?'(.*?)'\\\\)\")\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n\n        if (lines.isEmpty() || !lines[0].contains(\"##sK1 palette\")) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n\n        for (line in lines.drop(1)) {\n            val trimmed = line.trim()\n            if (trimmed.isEmpty()) continue\n\n            // Check for palette name\n            paletteNameRegex.find(trimmed)?.let { match ->\n                val name = match.groupValues[1]\n                if (name.isNotEmpty()) {\n                    result.name = name\n                }\n            }\n\n            // Check for color definition\n            rgbColorRegex.find(trimmed)?.let { match ->\n                val r = match.groupValues[1].toDoubleOrNull() ?: return@let\n                val g = match.groupValues[2].toDoubleOrNull() ?: return@let\n                val b = match.groupValues[3].toDoubleOrNull() ?: return@let\n                val a = match.groupValues[4].toDoubleOrNull() ?: return@let\n                val name = match.groupValues[5]\n\n                val color = PaletteColor.rgb(\n                    r = r.coerceIn(0.0, 1.0),\n                    g = g.coerceIn(0.0, 1.0),\n                    b = b.coerceIn(0.0, 1.0),\n                    a = a.coerceIn(0.0, 1.0),\n                    name = name\n                )\n                result.colors.add(color)\n            }\n        }\n\n        val palette = result.build()\n\n        if (palette.allColors().isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return palette\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var result = \"##sK1 palette\\n\"\n        result += \"Palette.Builder()\\n\"\n        result += \"set_name('${palette.name.replace(\"'\", \"_\").replace(\"\\\"\", \"_\")}')\\n\"\n        result += \"set_source('ColorPaletteCodable')\\n\"\n        result += \"set_columns(4)\\n\"\n\n        palette.allColors().forEach { color ->\n            val rgb = color.toRgb()\n            val colorName = color.name.replace(\"'\", \"_\").replace(\"\\\"\", \"_\")\n            result += \"color(['RGB', [${rgb.rf}, ${rgb.gf}, ${rgb.bf}], ${rgb.af}, '$colorName'])\\n\"\n        }\n\n        result += \"palette_end()\\n\"\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/SVGPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.extractHexRGBA\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.nio.charset.StandardCharsets\nimport java.text.DecimalFormat\nimport javax.xml.parsers.SAXParserFactory\n\n/**\n * SVG palette coder\n */\nclass SVGPaletteCoder(\n    private val swatchSize: Size = Size(width = 40.0, height = 40.0),\n    private val maxExportWidth: Double = 600.0,\n    private val edgeInset: EdgeInsets = EdgeInsets(top = 4.0, left = 4.0, bottom = 4.0, right = 4.0)\n) : PaletteCoder {\n\n    data class Size(val width: Double, val height: Double)\n    data class EdgeInsets(val top: Double, val left: Double, val bottom: Double, val right: Double)\n\n    private val formatter = DecimalFormat(\"#.###\").apply {\n        decimalFormatSymbols = java.text.DecimalFormatSymbols(java.util.Locale.US)\n    }\n\n    private class SVGHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n        private var currentChars = StringBuilder()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            val elementName = (qName ?: localName).trim().lowercase()\n\n            if (elementName == \"rect\") {\n                val fill = attributes.getValue(\"fill\")\n                val fillOpacity = attributes.getValue(\"fill-opacity\")?.toDoubleOrNull() ?: 1.0\n                val name = attributes.getValue(\"id\") ?: \"\"\n\n                if (fill != null && fill.isNotEmpty()) {\n                    try {\n                        val color = when {\n                            fill.startsWith(\"#\") -> {\n                                val rgb = extractHexRGBA(fill, ColorByteFormat.RGB)\n                                if (rgb != null) {\n                                    PaletteColor.rgb(\n                                        r = rgb.rf,\n                                        g = rgb.gf,\n                                        b = rgb.bf,\n                                        a = fillOpacity,\n                                        name = name\n                                    )\n                                } else null\n                            }\n\n                            fill.startsWith(\"rgb\") -> {\n                                // Parse rgb(r, g, b) or rgba(r, g, b, a)\n                                val rgbMatch =\n                                    Regex(\"\"\"rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)\"\"\")\n                                        .find(fill)\n                                if (rgbMatch != null) {\n                                    val r = rgbMatch.groupValues[1].toIntOrNull() ?: 0\n                                    val g = rgbMatch.groupValues[2].toIntOrNull() ?: 0\n                                    val b = rgbMatch.groupValues[3].toIntOrNull() ?: 0\n                                    val a = rgbMatch.groupValues[4].toDoubleOrNull() ?: fillOpacity\n                                    PaletteColor.rgb(\n                                        r = (r / 255.0).coerceIn(0.0, 1.0),\n                                        g = (g / 255.0).coerceIn(0.0, 1.0),\n                                        b = (b / 255.0).coerceIn(0.0, 1.0),\n                                        a = a.coerceIn(0.0, 1.0),\n                                        name = name\n                                    )\n                                } else null\n                            }\n\n                            else -> null\n                        }\n\n                        if (color != null) {\n                            palette.colors.add(color)\n                        }\n                    } catch (_: Throwable) {\n                        // Skip invalid colors\n                    }\n                }\n            }\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val handler = SVGHandler()\n        val factory = SAXParserFactory.newInstance()\n        factory.isNamespaceAware = true\n        factory.isValidating = false\n        val parser = factory.newSAXParser()\n        parser.parse(input, handler)\n\n        if (handler.palette.colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return handler.palette.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var xOffset = edgeInset.left\n        var yOffset = edgeInset.top\n\n        fun exportGrouping(colors: List<PaletteColor>): String {\n            var result = \"\"\n            colors.forEach { color ->\n                val rgb = color.toRgb()\n                val hex = rgb.hexString(\n                    format = ColorByteFormat.RGB,\n                    hashmark = true,\n                    uppercase = true\n                )\n\n                result += \"      <rect x=\\\"${formatter.format(xOffset)}\\\" y=\\\"${\n                    formatter.format(\n                        yOffset\n                    )\n                }\\\" \"\n                result += \"width=\\\"${formatter.format(swatchSize.width)}\\\" height=\\\"${\n                    formatter.format(\n                        swatchSize.height\n                    )\n                }\\\" \"\n                if (color.name.isNotEmpty()) {\n                    result += \"id=\\\"${color.name.xmlEscaped()}\\\" \"\n                }\n                result += \"fill=\\\"$hex\\\" fill-opacity=\\\"${formatter.format(color.alpha)}\\\"\"\n                result += \" />\\n\"\n\n                xOffset += swatchSize.width + 1\n                if (xOffset + swatchSize.width + edgeInset.right > maxExportWidth) {\n                    yOffset += swatchSize.height + 1\n                    xOffset = edgeInset.left\n                }\n            }\n            return result\n        }\n\n        var colorsXml = \"\"\n        // Global colors first\n        colorsXml += exportGrouping(palette.colors)\n\n        palette.groups.forEach { group ->\n            xOffset = edgeInset.left\n            colorsXml += exportGrouping(group.colors)\n\n            if (group.name.isNotEmpty()) {\n                yOffset += swatchSize.height + 10\n                colorsXml += \"      <text x='5' y='${formatter.format(yOffset)}' font-size='8' alignment-baseline='middle'>${group.name.xmlEscaped()}</text>\\n\\n\"\n            }\n\n            yOffset += 10\n        }\n\n        yOffset += edgeInset.bottom\n\n        val result = \"\"\"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" viewBox=\"0 0 ${\n            formatter.format(\n                maxExportWidth\n            )\n        } ${formatter.format(yOffset + swatchSize.height)}\" xml:space=\"preserve\">\n\n\"\"\"\n        output.write(result.toByteArray(StandardCharsets.UTF_8))\n        output.write(colorsXml.toByteArray(StandardCharsets.UTF_8))\n        output.write(\"</svg>\\n\".toByteArray(StandardCharsets.UTF_8))\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/ScribusXMLPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.hexString\nimport com.t8rin.palette.utils.xmlDecoded\nimport com.t8rin.palette.utils.xmlEscaped\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.nio.charset.StandardCharsets\nimport javax.xml.parsers.SAXParserFactory\n\n/**\n * Scribus XML palette coder\n */\nclass ScribusXMLPaletteCoder : PaletteCoder {\n\n    private class ScribusXMLHandler : DefaultHandler() {\n        val palette = Palette.Builder()\n        private var currentChars = StringBuilder()\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            val elementName = (qName ?: localName).lowercase()\n\n            if (elementName == \"scribuscolors\" || elementName == \"scolors\") {\n                val name = attributes.getValue(\"Name\") ?: attributes.getValue(\"name\") ?: \"\"\n                palette.name = name.xmlDecoded()\n            } else if (elementName == \"color\") {\n                val name =\n                    (attributes.getValue(\"NAME\") ?: attributes.getValue(\"name\") ?: \"\").xmlDecoded()\n                val rgbHex = attributes.getValue(\"RGB\") ?: attributes.getValue(\"rgb\")\n                val cmykHex = attributes.getValue(\"CMYK\") ?: attributes.getValue(\"cmyk\")\n\n                try {\n                    val color = if (rgbHex != null) {\n                        PaletteColor(\n                            rgbHexString = rgbHex,\n                            format = ColorByteFormat.RGB,\n                            name = name\n                        )\n                    } else if (cmykHex != null) {\n                        // CMYK hex format - parse it\n                        PaletteColor(cmykHexString = cmykHex, name = name)\n                    } else {\n                        null\n                    }\n\n                    if (color != null) {\n                        palette.colors.add(color)\n                    }\n                } catch (_: Throwable) {\n                    // Skip invalid colors\n                }\n            }\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val handler = ScribusXMLHandler()\n        val factory = SAXParserFactory.newInstance()\n        factory.isNamespaceAware = false\n        val parser = factory.newSAXParser()\n        parser.parse(input, handler)\n\n        if (handler.palette.colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return handler.palette.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var xml = \"<?xml version=\\\"1.0\\\"?>\\n\"\n        xml += \"<SCRIBUSCOLORS\"\n        if (palette.name.isNotEmpty()) {\n            xml += \" Name=\\\"${palette.name.xmlEscaped()}\\\"\"\n        }\n        xml += \" >\\n\"\n\n        palette.allColors().forEach { color ->\n            try {\n                if (color.colorSpace == ColorSpace.CMYK) {\n                    val cmyk = color.toCmyk()\n                    // CMYK hex representation (simplified)\n                    val c = (cmyk.c * 255).toInt().coerceIn(0, 255)\n                    val m = (cmyk.m * 255).toInt().coerceIn(0, 255)\n                    val y = (cmyk.y * 255).toInt().coerceIn(0, 255)\n                    val k = (cmyk.k * 255).toInt().coerceIn(0, 255)\n                    val hex = String.format(\"#%02x%02x%02x%02x\", c, m, y, k)\n                    xml += \"<COLOR CMYK=\\\"$hex\\\"\"\n                } else {\n                    val rgb = color.toRgb()\n                    val hex = rgb.hexString(ColorByteFormat.RGB, hashmark = true, uppercase = false)\n                    xml += \"<COLOR RGB=\\\"$hex\\\"\"\n                }\n\n                if (color.name.isNotEmpty()) {\n                    xml += \" NAME=\\\"${color.name.xmlEscaped()}\\\"\"\n                }\n                xml += \" />\\n\"\n            } catch (_: Throwable) {\n                // Skip colors that can't be converted\n            }\n        }\n\n        xml += \"</SCRIBUSCOLORS>\\n\"\n\n        output.write(xml.toByteArray(StandardCharsets.UTF_8))\n    }\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/SimplePaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport kotlinx.serialization.Serializable\nimport kotlinx.serialization.json.Json\nimport java.io.InputStream\nimport java.io.OutputStream\nimport kotlin.math.pow\n\n/**\n * Simple Color Palette coder\n * https://sindresorhus.com/simple-color-palette\n */\nclass SimplePaletteCoder : PaletteCoder {\n    private val json = Json {\n        ignoreUnknownKeys = true\n        prettyPrint = true\n    }\n\n    @Serializable\n    private data class SimplePaletteColor(\n        val name: String? = null,\n        val components: List<Double>\n    )\n\n    @Serializable\n    private data class SimplePalette(\n        val name: String? = null,\n        val colors: List<SimplePaletteColor>\n    )\n\n    companion object {\n        private const val MAX_DECIMAL_PLACES = 4\n\n        private fun Double.roundToPlaces(places: Int): Double {\n            if (places <= 0) return this\n            val multiplier = 10.0.pow(places.toDouble())\n            return (this * multiplier).let { kotlin.math.round(it) } / multiplier\n        }\n\n        private fun sRGB2Linear(value: Double): Double {\n            return if (value <= 0.04045) {\n                value / 12.92\n            } else {\n                ((value + 0.055) / 1.055).pow(2.4)\n            }\n        }\n\n        private fun linearSRGB2SRGB(value: Double): Double {\n            return if (value <= 0.0031308) {\n                value * 12.92\n            } else {\n                1.055 * value.pow(1.0 / 2.4) - 0.055\n            }\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val s = json.decodeFromString(SimplePalette.serializer(), text)\n\n        val result = Palette.Builder()\n        result.name = s.name ?: \"\"\n\n        val colors = s.colors.mapNotNull { colorData ->\n            val components = colorData.components.map { it.roundToPlaces(MAX_DECIMAL_PLACES) }\n            if (components.size < 3 || components.size > 4) return@mapNotNull null\n\n            val lr = components[0]\n            val lg = components[1]\n            val lb = components[2]\n            val la = if (components.size == 4) components[3].coerceIn(0.0, 1.0) else 1.0\n\n            // Convert from linear extended sRGB to sRGB\n            val r = linearSRGB2SRGB(lr)\n            val g = linearSRGB2SRGB(lg)\n            val b = linearSRGB2SRGB(lb)\n\n            PaletteColor.rgb(\n                r = r,\n                g = g,\n                b = b,\n                a = la,\n                name = colorData.name ?: \"\"\n            )\n        }\n\n        result.colors = colors.toMutableList()\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val name: String? = palette.name.ifEmpty { null }\n\n        val colors = palette.allColors().map { color ->\n            val rgb = color.toRgb()\n\n            // Convert to linear (extended)\n            val components = mutableListOf(\n                sRGB2Linear(rgb.rf).roundToPlaces(MAX_DECIMAL_PLACES),\n                sRGB2Linear(rgb.gf).roundToPlaces(MAX_DECIMAL_PLACES),\n                sRGB2Linear(rgb.bf).roundToPlaces(MAX_DECIMAL_PLACES)\n            )\n\n            // Add alpha if not 1.0\n            if (rgb.af.roundToPlaces(MAX_DECIMAL_PLACES) != 1.0) {\n                components.add(rgb.af.roundToPlaces(MAX_DECIMAL_PLACES))\n            }\n\n            SimplePaletteColor(\n                name = color.name.ifEmpty { null },\n                components = components\n            )\n        }\n\n        val result = SimplePalette(name = name, colors = colors)\n        val encoded = json.encodeToString(SimplePalette.serializer(), result)\n        output.write(encoded.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/SkencilPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.text.DecimalFormat\nimport java.text.DecimalFormatSymbols\nimport java.util.Locale\n\n/**\n * Skencil Palette coder\n */\nclass SkencilPaletteCoder : PaletteCoder {\n    companion object {\n        private val colorRegex =\n            Regex(\"^\\\\s*(\\\\d*\\\\.?\\\\d+|\\\\d+)\\\\s+(\\\\d*\\\\.?\\\\d+|\\\\d+)\\\\s+(\\\\d*\\\\.?\\\\d+|\\\\d+)\\\\s+(.*)$\")\n        private val formatter = DecimalFormat(\"0.000000\", DecimalFormatSymbols(Locale.US))\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val lines = text.lines()\n\n        if (lines.isEmpty() || !lines[0].contains(\"##Sketch RGBPalette 0\")) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n\n        for (line in lines.drop(1)) {\n            colorRegex.find(line)?.let { match ->\n                val r = match.groupValues[1].toDoubleOrNull() ?: return@let\n                val g = match.groupValues[2].toDoubleOrNull() ?: return@let\n                val b = match.groupValues[3].toDoubleOrNull() ?: return@let\n                val name = match.groupValues[4].trim()\n\n                val color = PaletteColor.rgb(\n                    r = r.coerceIn(0.0, 1.0),\n                    g = g.coerceIn(0.0, 1.0),\n                    b = b.coerceIn(0.0, 1.0),\n                    name = name\n                )\n                result.colors.add(color)\n            }\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        var result = \"##Sketch RGBPalette 0\\n\"\n\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        colors.forEach { color ->\n            val rgb = color.toRgb()\n            val rs = formatter.format(rgb.rf.coerceIn(0.0, 1.0))\n            val gs = formatter.format(rgb.gf.coerceIn(0.0, 1.0))\n            val bs = formatter.format(rgb.bf.coerceIn(0.0, 1.0))\n            result += \"$rs $gs $bs\"\n            if (color.name.isNotEmpty()) {\n                result += \" ${color.name}\"\n            }\n            result += \"\\n\"\n        }\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/SketchPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport kotlinx.serialization.Serializable\nimport kotlinx.serialization.json.Json\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * Sketch palette coder\n */\nclass SketchPaletteCoder : PaletteCoder {\n    private val json = Json {\n        ignoreUnknownKeys = true\n    }\n\n    @Serializable\n    private data class SketchColor(\n        val red: Double,\n        val green: Double,\n        val blue: Double,\n        val alpha: Double\n    )\n\n    @Serializable\n    private data class SketchFile(\n        val compatibleVersion: String,\n        val pluginVersion: String,\n        val colors: List<SketchColor>\n    )\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n\n        // Try to decode with names first\n        val result = Palette.Builder()\n        try {\n            val sketchFileWithNames = json.decodeFromString(SketchFileWithNames.serializer(), text)\n            result.colors = sketchFileWithNames.colors.map { sketchColor ->\n                PaletteColor.rgb(\n                    r = sketchColor.red,\n                    g = sketchColor.green,\n                    b = sketchColor.blue,\n                    a = sketchColor.alpha,\n                    name = sketchColor.name ?: \"\"\n                )\n            }.toMutableList()\n        } catch (_: Throwable) {\n            // Fall back to old format without names\n            val sketchFile = json.decodeFromString(SketchFile.serializer(), text)\n            result.colors = sketchFile.colors.map { sketchColor ->\n                PaletteColor.rgb(\n                    r = sketchColor.red,\n                    g = sketchColor.green,\n                    b = sketchColor.blue,\n                    a = sketchColor.alpha\n                )\n            }.toMutableList()\n        }\n\n        return result.build()\n    }\n\n    @Serializable\n    private data class SketchColorWithName(\n        val name: String? = null,\n        val red: Double,\n        val green: Double,\n        val blue: Double,\n        val alpha: Double\n    )\n\n    @Serializable\n    private data class SketchFileWithNames(\n        val compatibleVersion: String,\n        val pluginVersion: String,\n        val colors: List<SketchColorWithName>\n    )\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val colors = palette.allColors().map { color ->\n            val rgb = color.toRgb()\n            SketchColorWithName(\n                name = if (color.name.isNotEmpty()) color.name else null,\n                red = rgb.rf,\n                green = rgb.gf,\n                blue = rgb.bf,\n                alpha = rgb.af\n            )\n        }\n\n        val file = SketchFileWithNames(\n            compatibleVersion = \"1.4\",\n            pluginVersion = \"1.4\",\n            colors = colors\n        )\n\n        val encoded = json.encodeToString(SketchFileWithNames.serializer(), file)\n        output.write(encoded.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/SwatchbookerCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteColor\nimport org.xml.sax.Attributes\nimport org.xml.sax.helpers.DefaultHandler\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipInputStream\nimport java.util.zip.ZipOutputStream\nimport javax.xml.parsers.SAXParserFactory\n\nclass SwatchbookerCoder : PaletteCoder {\n\n    private class SwatchbookerXMLHandler : DefaultHandler() {\n        var palette = Palette.Builder()\n        private val nodeStack = mutableListOf<Node>()\n        private var colorTitle: String? = null\n        private var colorID: String? = null\n        private var colorMode: String? = null\n        private var colorComponents = mutableListOf<Double>()\n        val colorMaterialMap = mutableMapOf<String, String>()\n        val colorMaterialOrdering = mutableListOf<String>()\n        private var currentChars = StringBuilder()\n\n        private data class Node(\n            val name: String,\n            val attrs: Map<String, String>,\n            var content: String = \"\"\n        )\n\n        private fun attributesToMap(attributes: Attributes): Map<String, String> {\n            val map = mutableMapOf<String, String>()\n            for (i in 0 until attributes.length) {\n                val key = attributes.getQName(i).ifEmpty { attributes.getLocalName(i) }\n                map[key] = attributes.getValue(i)\n            }\n            return map\n        }\n\n        override fun startElement(\n            uri: String?,\n            localName: String,\n            qName: String?,\n            attributes: Attributes\n        ) {\n            currentChars.clear()\n            val elementName = (qName ?: localName).trim()\n            if (elementName.isEmpty()) return\n            val attrs = attributesToMap(attributes)\n            nodeStack.add(Node(elementName, attrs))\n            when {\n                elementName.equals(\n                    \"color\",\n                    ignoreCase = true\n                ) && nodeStack.any { it.name.equals(\"materials\", ignoreCase = true) } -> {\n                    colorTitle = null\n                    colorID = null\n                    colorMode = null\n                    colorComponents.clear()\n                }\n\n                elementName.equals(\"values\", ignoreCase = true) -> {\n                    colorMode = attrs[\"model\"] ?: attrs[\"MODEL\"] ?: attrs[\"Model\"]\n                    colorComponents.clear()\n                }\n\n                elementName.equals(\n                    \"swatch\",\n                    ignoreCase = true\n                ) && nodeStack.any { it.name.equals(\"book\", ignoreCase = true) } -> {\n                    attrs[\"material\"]?.let { colorMaterialOrdering.add(it.trim()) }\n                }\n            }\n        }\n\n        override fun endElement(uri: String?, localName: String, qName: String?) {\n            val elementName = (qName ?: localName).trim()\n            if (elementName.isEmpty()) {\n                if (nodeStack.isNotEmpty()) nodeStack.removeAt(nodeStack.size - 1)\n                return\n            }\n            nodeStack.lastOrNull() ?: run {\n                if (nodeStack.isNotEmpty()) nodeStack.removeAt(nodeStack.size - 1)\n                return\n            }\n            val content = currentChars.toString().trim()\n            when {\n                elementName.equals(\"dc:title\", ignoreCase = true) -> {\n                    if (nodeStack.any { it.name.equals(\"materials\", ignoreCase = true) }) {\n                        colorTitle = content\n                    } else {\n                        palette.name = content\n                    }\n                }\n\n                elementName.equals(\"dc:identifier\", ignoreCase = true) -> colorID = content\n                elementName.equals(\"values\", ignoreCase = true) -> {\n                    colorComponents =\n                        content.split(Regex(\"\\\\s+\")).mapNotNull { it.toDoubleOrNull() }\n                            .toMutableList()\n                }\n\n                elementName.equals(\n                    \"color\",\n                    ignoreCase = true\n                ) && nodeStack.any { it.name.equals(\"materials\", ignoreCase = true) } -> {\n                    val name = colorTitle ?: colorID ?: \"Color ${palette.colors.size + 1}\"\n                    val color: PaletteColor? = when {\n                        colorMode.equals(\"RGB\", true) && colorComponents.size >= 3 -> {\n                            val r = colorComponents[0]\n                            val g = colorComponents[1]\n                            val b = colorComponents[2]\n                            val a = if (colorComponents.size >= 4) colorComponents[3] else 1.0\n                            PaletteColor.rgb(r, g, b, a, name)\n                        }\n\n                        colorMode.equals(\n                            \"Lab\",\n                            true\n                        ) && colorComponents.size >= 3 -> PaletteColor.lab(\n                            colorComponents[0],\n                            colorComponents[1],\n                            colorComponents[2],\n                            1.0,\n                            name\n                        )\n\n                        colorMode.equals(\n                            \"CMYK\",\n                            true\n                        ) && colorComponents.size >= 4 -> PaletteColor.cmyk(\n                            colorComponents[0],\n                            colorComponents[1],\n                            colorComponents[2],\n                            colorComponents[3],\n                            1.0,\n                            name\n                        )\n\n                        colorMode.equals(\n                            \"GRAY\",\n                            true\n                        ) && colorComponents.isNotEmpty() -> PaletteColor.gray(\n                            colorComponents[0],\n                            1.0,\n                            name\n                        )\n\n                        colorMode.equals(\n                            \"HSV\",\n                            true\n                        ) && colorComponents.size >= 3 -> PaletteColor.hsb(\n                            colorComponents[0],\n                            colorComponents[1],\n                            colorComponents[2],\n                            1.0,\n                            name\n                        )\n\n                        colorMode.equals(\n                            \"HSL\",\n                            true\n                        ) && colorComponents.size >= 3 -> PaletteColor.hsl(\n                            colorComponents[0],\n                            colorComponents[1],\n                            colorComponents[2],\n                            1.0,\n                            name\n                        )\n\n                        else -> null\n                    }\n                    if (color != null) {\n                        val id = colorID ?: \"color_${palette.colors.size}\"\n                        palette.colors.add(color)\n                        colorMaterialMap[id] = color.id\n                    }\n                }\n            }\n            if (nodeStack.isNotEmpty()) nodeStack.removeAt(nodeStack.size - 1)\n            currentChars.clear()\n        }\n\n        override fun characters(ch: CharArray, start: Int, length: Int) {\n            currentChars.appendRange(ch, start, start + length)\n        }\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val data = input.readBytes()\n        val zipInputStream = ZipInputStream(data.inputStream())\n        var xmlData = ByteArray(0)\n        var entry: ZipEntry? = zipInputStream.nextEntry\n        while (entry != null) {\n            if (entry.name.equals(\"swatchbook.xml\", true)) {\n                xmlData = zipInputStream.readBytes()\n                break\n            }\n            entry = zipInputStream.nextEntry\n        }\n        zipInputStream.close()\n        if (xmlData.isEmpty()) return Palette()\n        val handler = SwatchbookerXMLHandler()\n        val factory = SAXParserFactory.newInstance()\n        factory.isNamespaceAware = true\n        factory.newSAXParser().parse(xmlData.inputStream(), handler)\n        val ordered = mutableListOf<PaletteColor>()\n        val remaining = handler.palette.colors.toMutableList()\n        handler.colorMaterialOrdering.forEach { materialID ->\n            val colorID = handler.colorMaterialMap[materialID]\n            if (colorID != null) {\n                val idx = remaining.indexOfFirst { it.id == colorID }\n                if (idx >= 0) ordered.add(remaining.removeAt(idx))\n            }\n        }\n        ordered.addAll(remaining)\n        handler.palette.colors = ordered\n        return handler.palette.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val zipOutputStream = ZipOutputStream(output)\n        zipOutputStream.putNextEntry(ZipEntry(\"swatchbook.xml\"))\n        val xml = buildString {\n            appendLine(\"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\"\"\")\n            appendLine(\"\"\"<SwatchBook xmlns=\"http://www.selapa.net/swatchbook/1.0/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\"\"\")\n            appendLine(\"  <metadata>\")\n            appendLine(\"    <dc:title>${escapeXml(palette.name)}</dc:title>\")\n            appendLine(\"  </metadata>\")\n            appendLine(\"  <materials>\")\n            palette.allColors().forEachIndexed { index, color ->\n                appendLine(\"    <color usage=\\\"standard\\\">\")\n                appendLine(\"      <metadata>\")\n                appendLine(\"        <dc:title>${escapeXml(color.name)}</dc:title>\")\n                appendLine(\"        <dc:identifier>color_$index</dc:identifier>\")\n                appendLine(\"      </metadata>\")\n                appendLine(\"      <values model=\\\"${getColorModel(color)}\\\">\")\n                appendLine(\"        ${getColorValues(color)}\")\n                appendLine(\"      </values>\")\n                appendLine(\"    </color>\")\n            }\n            appendLine(\"  </materials>\")\n            appendLine(\"  <book>\")\n            palette.allColors()\n                .forEachIndexed { index, _ -> appendLine(\"    <swatch material=\\\"color_$index\\\"/>\") }\n            appendLine(\"  </book>\")\n            appendLine(\"</SwatchBook>\")\n        }\n        zipOutputStream.write(xml.toByteArray(Charsets.UTF_8))\n        zipOutputStream.closeEntry()\n        zipOutputStream.close()\n    }\n\n    private fun escapeXml(text: String): String =\n        text.replace(\"&\", \"&amp;\").replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\").replace(\"\\\"\", \"&quot;\")\n            .replace(\"'\", \"&apos;\")\n\n    private fun getColorModel(color: PaletteColor): String = when (color.colorSpace) {\n        ColorSpace.RGB -> \"RGB\"\n        ColorSpace.CMYK -> \"CMYK\"\n        ColorSpace.LAB -> \"Lab\"\n        ColorSpace.Gray -> \"GRAY\"\n    }\n\n    private fun getColorValues(color: PaletteColor): String {\n        val comps = color.colorComponents.toMutableList()\n        if (color.colorSpace == ColorSpace.RGB) comps.add(color.alpha)\n        return comps.joinToString(\" \")\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/SwiftPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.utils.readText\nimport java.io.InputStream\nimport java.io.OutputStream\nimport java.text.DecimalFormat\n\n/**\n * Swift code generator\n */\nclass SwiftPaletteCoder : PaletteCoder {\n    private val formatter = DecimalFormat(\"0.0000\").apply {\n        decimalFormatSymbols = java.text.DecimalFormatSymbols(java.util.Locale.US)\n    }\n\n    override fun decode(input: InputStream): Palette {\n        val text = input.readText()\n        val result = Palette.Builder()\n\n        // Parse #colorLiteral(red: x, green: y, blue: z, alpha: w)\n        // Also try to capture comments with color names after the colorLiteral: , // name\n        // Format: #colorLiteral(...), // name\n        // Use non-greedy match to stop at next #colorLiteral or end of line\n        val colorLiteralRegex = Regex(\n            pattern = \"\"\"#colorLiteral\\s*\\(\\s*red:\\s*([\\d.]+)\\s*,\\s*green:\\s*([\\d.]+)\\s*,\\s*blue:\\s*([\\d.]+)\\s*,\\s*alpha:\\s*([\\d.]+)\\s*\\)\\s*,?\\s*//\\s*([^#\\n]*?)(?=\\s*#colorLiteral|$)\"\"\",\n            options = setOf(\n                RegexOption.IGNORE_CASE,\n                RegexOption.MULTILINE\n            )\n        )\n\n        var colorIndex = 0\n        colorLiteralRegex.findAll(text).forEach { match ->\n            try {\n                val r = match.groupValues[1].toDoubleOrNull() ?: 0.0\n                val g = match.groupValues[2].toDoubleOrNull() ?: 0.0\n                val b = match.groupValues[3].toDoubleOrNull() ?: 0.0\n                val a = match.groupValues[4].toDoubleOrNull() ?: 1.0\n                val colorName = match.groupValues[5].trim().takeIf { it.isNotEmpty() } ?: \"\"\n\n                val finalName = colorName.ifEmpty {\n                    \"Color_$colorIndex\"\n                }\n\n                val color = PaletteColor.rgb(\n                    r = r.coerceIn(0.0, 1.0),\n                    g = g.coerceIn(0.0, 1.0),\n                    b = b.coerceIn(0.0, 1.0),\n                    a = a.coerceIn(0.0, 1.0),\n                    name = finalName\n                )\n                result.colors.add(color)\n                colorIndex++\n            } catch (_: Throwable) {\n                // Skip invalid colors\n            }\n        }\n\n        // Try to extract palette name from comments or struct name\n        val paletteCommentMatch = Regex(pattern = \"\"\"(?m)^\\s*//\\s*Palette:\\s*(.+)\\s*$\"\"\").find(text)\n        if (paletteCommentMatch != null) {\n            result.name = paletteCommentMatch.groupValues[1].trim()\n        } else {\n            val structNameMatch = Regex(\"\"\"struct\\s+(\\w+)\"\"\").find(text)\n            if (structNameMatch != null) {\n                result.name = structNameMatch.groupValues[1]\n            }\n        }\n\n        if (result.colors.isEmpty()) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        fun mapColors(group: ColorGroup, offset: Int): String {\n            val mapped = group.colors.mapNotNull { color ->\n                try {\n                    val converted =\n                        if (color.colorSpace == ColorSpace.RGB) color else color.converted(\n                            ColorSpace.RGB\n                        )\n                    converted.toRgb()\n                } catch (_: Throwable) {\n                    null\n                }\n            }\n\n            if (mapped.isEmpty()) return \"\"\n\n            var result = \"   // Group (${group.name})\\n\"\n            result += \"   static let group$offset: [CGColor] = [\"\n\n            mapped.forEachIndexed { index, rgb ->\n                // Add comment with color name if available (on same line before colorLiteral)\n                val originalColor = group.colors.getOrNull(index)\n                val colorNameComment =\n                    if (originalColor != null && originalColor.name.isNotEmpty()) {\n                        \" // ${originalColor.name}\"\n                    } else {\n                        \"\"\n                    }\n\n                if (index % 8 == 0) {\n                    result += \"\\n     \"\n                }\n\n                val rs = formatter.format(rgb.rf)\n                val gs = formatter.format(rgb.gf)\n                val bs = formatter.format(rgb.bf)\n                val aas = formatter.format(rgb.af)\n                result += \" #colorLiteral(red: $rs, green: $gs, blue: $bs, alpha: $aas),$colorNameComment\"\n            }\n\n            result += \"\\n   ]\\n\\n\"\n            return result\n        }\n\n        var result = \"\"\n        if (palette.name.isNotEmpty()) {\n            result += \"// Palette: ${palette.name}\\n\"\n        }\n        result += \"struct ExportedPalettes {\\n\"\n\n        palette.allGroups.forEachIndexed { index, group ->\n            result += mapColors(group, index)\n        }\n\n        result += \"}\\n\"\n\n        output.write(result.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/VGA18BitPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * VGA 18-bit RGB palette coder (3 bytes per color, 6-bit per channel)\n */\nclass VGA18BitPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val allData = input.readBytes()\n\n        // Check if there's a text header with names\n        var data = allData\n        val names = mutableListOf<String>()\n        try {\n            val text = String(allData, java.nio.charset.StandardCharsets.UTF_8)\n            if (text.startsWith(\"; Names: \")) {\n                val firstNewline = text.indexOf('\\n')\n                if (firstNewline > 0) {\n                    val nameLine = text.substring(0, firstNewline)\n                    val namesStr = nameLine.substring(\"; Names: \".length)\n                    names.addAll(namesStr.split(\", \").map { it.trim() })\n                    data = allData.sliceArray(firstNewline + 1 until allData.size)\n                }\n            }\n        } catch (_: Throwable) {\n            // Not a text header, use binary data as-is\n            data = allData\n        }\n\n        if (data.size % 3 != 0) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n\n        for (i in data.indices step 3) {\n            val r = data[i].toUByte().toInt()\n            val g = data[i + 1].toUByte().toInt()\n            val b = data[i + 2].toUByte().toInt()\n\n            if (r > 63 || g > 63 || b > 63) {\n                throw PaletteCoderException.InvalidFormat()\n            }\n\n            val colorIndex = i / 3\n            val colorName = if (colorIndex < names.size) names[colorIndex] else \"\"\n            val color = PaletteColor.rgb(\n                r = r / 63.0,\n                g = g / 63.0,\n                b = b / 63.0,\n                name = colorName\n            )\n            result.colors.add(color)\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        // VGA format doesn't support names, but we can write them as a comment header\n        val names = colors.mapNotNull { if (it.name.isNotEmpty()) it.name else null }\n        if (names.isNotEmpty()) {\n            val nameHeader = \"; Names: ${names.joinToString(\", \")}\\n\"\n            output.write(nameHeader.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n        }\n\n        colors.forEach { color ->\n            val rgb = color.toRgb()\n            val r = ((rgb.rf * 63).roundToInt().coerceIn(0, 63))\n            val g = ((rgb.gf * 63).roundToInt().coerceIn(0, 63))\n            val b = ((rgb.bf * 63).roundToInt().coerceIn(0, 63))\n            output.write(byteArrayOf(r.toByte(), g.toByte(), b.toByte()))\n        }\n    }\n\n    private fun Double.roundToInt(): Int {\n        return kotlin.math.round(this).toInt()\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/coders/VGA24BitPaletteCoder.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorSpace\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteCoder\nimport com.t8rin.palette.PaletteCoderException\nimport com.t8rin.palette.PaletteColor\nimport java.io.InputStream\nimport java.io.OutputStream\n\n/**\n * VGA 24-bit RGB palette coder (3 bytes per color: RRGGBB)\n */\nclass VGA24BitPaletteCoder : PaletteCoder {\n    override fun decode(input: InputStream): Palette {\n        val allData = input.readBytes()\n\n        // Check if there's a text header with names\n        var data = allData\n        val names = mutableListOf<String>()\n        try {\n            val text = String(allData, java.nio.charset.StandardCharsets.UTF_8)\n            if (text.startsWith(\"; Names: \")) {\n                val firstNewline = text.indexOf('\\n')\n                if (firstNewline > 0) {\n                    val nameLine = text.substring(0, firstNewline)\n                    val namesStr = nameLine.substring(\"; Names: \".length)\n                    names.addAll(namesStr.split(\", \").map { it.trim() })\n                    data = allData.sliceArray(firstNewline + 1 until allData.size)\n                }\n            }\n        } catch (_: Throwable) {\n            // Not a text header, use binary data as-is\n            data = allData\n        }\n\n        if (data.size % 3 != 0) {\n            throw PaletteCoderException.InvalidFormat()\n        }\n\n        val result = Palette.Builder()\n\n        for (i in data.indices step 3) {\n            val r = data[i].toUByte().toInt()\n            val g = data[i + 1].toUByte().toInt()\n            val b = data[i + 2].toUByte().toInt()\n\n            val colorIndex = i / 3\n            val colorName = if (colorIndex < names.size) names[colorIndex] else \"\"\n            val color = PaletteColor.rgb(\n                r = r / 255.0,\n                g = g / 255.0,\n                b = b / 255.0,\n                name = colorName\n            )\n            result.colors.add(color)\n        }\n\n        return result.build()\n    }\n\n    override fun encode(palette: Palette, output: OutputStream) {\n        val colors = palette.allColors().map { color ->\n            if (color.colorSpace == ColorSpace.RGB) color else color.converted(ColorSpace.RGB)\n        }\n\n        // VGA format doesn't support names, but we can write them as a comment header\n        val names = colors.mapNotNull { if (it.name.isNotEmpty()) it.name else null }\n        if (names.isNotEmpty()) {\n            val nameHeader = \"; Names: ${names.joinToString(\", \")}\\n\"\n            output.write(nameHeader.toByteArray(java.nio.charset.StandardCharsets.UTF_8))\n        }\n\n        colors.forEach { color ->\n            val rgb = color.toRgb()\n            val r = ((rgb.rf * 255).coerceIn(0.0, 255.0).toInt())\n            val g = ((rgb.gf * 255).coerceIn(0.0, 255.0).toInt())\n            val b = ((rgb.bf * 255).coerceIn(0.0, 255.0).toInt())\n            output.write(byteArrayOf(r.toByte(), g.toByte(), b.toByte()))\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/utils/BytesReader.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.utils\n\nimport java.io.InputStream\nimport java.nio.ByteBuffer\n\n/**\n * Byte order for reading/writing\n */\ninternal enum class ByteOrder {\n    BIG_ENDIAN,\n    LITTLE_ENDIAN\n}\n\n/**\n * Reader for binary data streams\n */\ninternal class BytesReader(inputStream: InputStream) {\n    // Always read all data for seek support\n    private val data: ByteArray = inputStream.readBytes()\n    private var position: Int = 0\n\n    constructor(data: ByteArray) : this(java.io.ByteArrayInputStream(data))\n\n    /**\n     * Read a specified number of bytes\n     */\n    fun readData(count: Int): ByteArray {\n        if (position + count > data.size) {\n            throw java.io.EOFException(\"Unexpected end of stream\")\n        }\n        val result = data.copyOfRange(position, position + count)\n        position += count\n        return result\n    }\n\n    /**\n     * Seek to absolute position\n     */\n    fun seekSet(pos: Int) {\n        if (pos < 0 || pos > data.size) {\n            throw java.io.EOFException(\"Position out of range\")\n        }\n        position = pos\n    }\n\n    fun trySkipBytes(count: Int): Boolean {\n        return if (position + count <= data.size) {\n            position += count\n            true\n        } else {\n            false\n        }\n    }\n\n    fun findPattern(pattern: ByteArray): Int {\n        outer@ for (i in position until data.size - pattern.size + 1) {\n            for (j in pattern.indices) {\n                if (data[i + j] != pattern[j]) continue@outer\n            }\n            return i\n        }\n        return -1\n    }\n\n    /**\n     * Read UInt8\n     */\n    fun readUInt8(): UByte {\n        if (position >= data.size) throw java.io.EOFException(\"Unexpected end of stream\")\n        return data[position++].toUByte()\n    }\n\n    /**\n     * Read byte\n     */\n    fun readByte(): Byte {\n        if (position >= data.size) throw java.io.EOFException(\"Unexpected end of stream\")\n        return data[position++]\n    }\n\n    /**\n     * Read Int16\n     */\n    fun readInt16(order: ByteOrder = ByteOrder.BIG_ENDIAN): Short {\n        val data = readData(2)\n        val bb = ByteBuffer.wrap(data)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        return bb.short\n    }\n\n    /**\n     * Read Int32\n     */\n    fun readInt32(order: ByteOrder = ByteOrder.BIG_ENDIAN): Int {\n        val data = readData(4)\n        val bb = ByteBuffer.wrap(data)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        return bb.int\n    }\n\n    /**\n     * Read UInt16\n     */\n    fun readUInt16(order: ByteOrder = ByteOrder.BIG_ENDIAN): UShort {\n        val data = readData(2)\n        val bb = ByteBuffer.wrap(data)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        return bb.short.toUShort()\n    }\n\n    /**\n     * Read UInt32\n     */\n    fun readUInt32(order: ByteOrder = ByteOrder.BIG_ENDIAN): UInt {\n        val data = readData(4)\n        val bb = ByteBuffer.wrap(data)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        return bb.int.toUInt()\n    }\n\n    /**\n     * Read Float32\n     */\n    fun readFloat32(order: ByteOrder = ByteOrder.BIG_ENDIAN): Float {\n        val data = readData(4)\n        val bb = ByteBuffer.wrap(data)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        return bb.float\n    }\n\n    /**\n     * Read UTF-16 string (null-terminated)\n     */\n    fun readStringUTF16NullTerminated(order: ByteOrder = ByteOrder.BIG_ENDIAN): String {\n        val bytes = mutableListOf<Byte>()\n        while (position + 1 < data.size) {\n            val b1 = data[position++].toInt().and(0xFF)\n            val b2 = data[position++].toInt().and(0xFF)\n            if (b1 == 0 && b2 == 0) break // null terminator\n            bytes.add(b1.toByte())\n            bytes.add(b2.toByte())\n        }\n        val charset = if (order == ByteOrder.BIG_ENDIAN)\n            java.nio.charset.StandardCharsets.UTF_16BE\n        else\n            java.nio.charset.StandardCharsets.UTF_16LE\n        return String(bytes.toByteArray(), charset)\n    }\n\n    /**\n     * Read ASCII string with specified length\n     */\n    fun readStringASCII(length: Int): String {\n        val data = readData(length)\n        return String(data, java.nio.charset.StandardCharsets.US_ASCII)\n    }\n\n    /**\n     * Read ISO Latin1 string with specified length\n     */\n    fun readStringISOLatin1(length: Int): String {\n        val data = readData(length)\n        return String(data, java.nio.charset.Charset.forName(\"ISO-8859-1\"))\n    }\n\n    /**\n     * Read Adobe Pascal-style string (UInt32 length in UTF-16 code units + UTF-16 string + 2 byte null)\n     */\n    fun readAdobePascalStyleString(): String {\n        val length = readUInt32(ByteOrder.BIG_ENDIAN).toInt()\n        if (length == 0) return \"\"\n        val stringData = mutableListOf<Byte>()\n        repeat(length) {\n            if (position + 1 >= data.size) throw java.io.EOFException(\"Unexpected end of stream\")\n            stringData.add(data[position++])\n            stringData.add(data[position++])\n        }\n        // Remove trailing null if present\n        val result = String(stringData.toByteArray(), java.nio.charset.StandardCharsets.UTF_16BE)\n        return result.trimEnd('\\u0000')\n    }\n\n    /**\n     * Read UTF-8 string (null-terminated)\n     */\n    fun readStringUTF8NullTerminated(): String {\n        val bytes = mutableListOf<Byte>()\n        while (position < data.size) {\n            val b = data[position++]\n            if (b.toInt() == 0) break\n            bytes.add(b)\n        }\n        return String(bytes.toByteArray(), java.nio.charset.StandardCharsets.UTF_8)\n    }\n\n    fun seekToNextInstanceOfPattern(vararg pattern: Int) {\n        val searchPattern = pattern.map { it.toByte() }.toByteArray()\n        var patternIndex = 0\n        val startPos = position\n\n        while (position < data.size) {\n            val b = data[position].toInt().and(0xFF)\n            position++\n\n            if (b == searchPattern[patternIndex].toInt().and(0xFF)) {\n                patternIndex++\n                if (patternIndex >= searchPattern.size) {\n                    // нашли совпадение, откатываем на начало паттерна\n                    position -= searchPattern.size\n                    return\n                }\n            } else {\n                patternIndex = 0\n            }\n        }\n\n        // если не нашли — вернём позицию на место и бросим EOF\n        position = startPos\n        throw java.io.EOFException(\"Pattern not found\")\n    }\n\n    fun seekToNextInstanceOfASCII(pattern: String) {\n        val searchPattern = pattern.toByteArray(Charsets.US_ASCII)\n        var patternIndex = 0\n        val startPos = position\n\n        while (position < data.size) {\n            val b = data[position].toInt().and(0xFF)\n            position++\n\n            if (b == searchPattern[patternIndex].toInt().and(0xFF)) {\n                patternIndex++\n                if (patternIndex >= searchPattern.size) {\n                    position -= searchPattern.size\n                    return\n                }\n            } else {\n                patternIndex = 0\n            }\n        }\n\n        position = startPos\n        throw java.io.EOFException(\"Pattern not found\")\n    }\n\n    /**\n     * Read UTF-8 string with byte count\n     */\n    fun readStringUTF8(byteCount: Int): String {\n        val data = readData(byteCount)\n        return String(data, java.nio.charset.StandardCharsets.UTF_8)\n    }\n\n    /**\n     * Read UTF-16 string with specified length (in characters)\n     */\n    fun readStringUTF16(order: ByteOrder, length: Int): String {\n        val byteCount = length * 2\n        val data = readData(byteCount)\n        val charset = if (order == ByteOrder.BIG_ENDIAN)\n            java.nio.charset.StandardCharsets.UTF_16BE\n        else\n            java.nio.charset.StandardCharsets.UTF_16LE\n        return String(data, charset)\n    }\n\n    /**\n     * Read Pascal-style UTF-16 string (UInt16 length in characters + UTF-16 string)\n     */\n    fun readPascalStringUTF16(order: ByteOrder): String {\n        val length = readUInt16(order).toInt()\n        if (length == 0) return \"\"\n        val byteCount = length * 2\n        val stringData = readData(byteCount)\n        val charset = if (order == ByteOrder.BIG_ENDIAN)\n            java.nio.charset.StandardCharsets.UTF_16BE\n        else\n            java.nio.charset.StandardCharsets.UTF_16LE\n        return String(stringData, charset)\n    }\n\n    /**\n     * Read bytes count\n     */\n    fun readBytes(count: Int): ByteArray {\n        return readData(count)\n    }\n\n    /**\n     * Skip bytes\n     */\n    fun seek(count: Int) {\n        if (position + count > data.size) {\n            throw java.io.EOFException(\"Unexpected end of stream\")\n        }\n        position += count\n    }\n\n    /**\n     * Current read position\n     */\n    val readPosition: Long\n        get() = position.toLong()\n}\n\n/**\n * Helper to read text from InputStream\n */\nfun InputStream.readText(): String {\n    return bufferedReader().use { it.readText() }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/utils/BytesWriter.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.utils\n\nimport java.io.OutputStream\nimport java.nio.ByteBuffer\n\n/**\n * Writer for binary data streams\n */\ninternal class BytesWriter(private val outputStream: OutputStream) {\n\n    /**\n     * Write bytes\n     */\n    fun writeData(data: ByteArray) {\n        outputStream.write(data)\n    }\n\n    /**\n     * Write UInt8\n     */\n    fun writeUInt8(value: UByte) {\n        outputStream.write(value.toInt())\n    }\n\n    /**\n     * Write byte\n     */\n    fun writeByte(value: Byte) {\n        outputStream.write(value.toInt())\n    }\n\n    /**\n     * Write Int16\n     */\n    fun writeInt16(value: Short, order: ByteOrder = ByteOrder.BIG_ENDIAN) {\n        val bb = ByteBuffer.allocate(2)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        bb.putShort(value)\n        outputStream.write(bb.array())\n    }\n\n    /**\n     * Write Int32\n     */\n    fun writeInt32(value: Int, order: ByteOrder = ByteOrder.BIG_ENDIAN) {\n        val bb = ByteBuffer.allocate(4)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        bb.putInt(value)\n        outputStream.write(bb.array())\n    }\n\n    /**\n     * Write UInt16\n     */\n    fun writeUInt16(value: UShort, order: ByteOrder = ByteOrder.BIG_ENDIAN) {\n        val bb = ByteBuffer.allocate(2)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        bb.putShort(value.toShort())\n        outputStream.write(bb.array())\n    }\n\n    /**\n     * Write UInt32\n     */\n    fun writeUInt32(value: UInt, order: ByteOrder = ByteOrder.BIG_ENDIAN) {\n        val bb = ByteBuffer.allocate(4)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        bb.putInt(value.toInt())\n        outputStream.write(bb.array())\n    }\n\n    /**\n     * Write Float32\n     */\n    fun writeFloat32(value: Float, order: ByteOrder = ByteOrder.BIG_ENDIAN) {\n        val bb = ByteBuffer.allocate(4)\n        bb.order(if (order == ByteOrder.BIG_ENDIAN) java.nio.ByteOrder.BIG_ENDIAN else java.nio.ByteOrder.LITTLE_ENDIAN)\n        bb.putFloat(value)\n        outputStream.write(bb.array())\n    }\n\n    /**\n     * Write UTF-16 string (null-terminated)\n     */\n    fun writeStringUTF16NullTerminated(value: String, order: ByteOrder = ByteOrder.BIG_ENDIAN) {\n        val charset = if (order == ByteOrder.BIG_ENDIAN)\n            java.nio.charset.StandardCharsets.UTF_16BE\n        else\n            java.nio.charset.StandardCharsets.UTF_16LE\n        val bytes = value.toByteArray(charset)\n        outputStream.write(bytes)\n        // Write null terminator\n        outputStream.write(0)\n        outputStream.write(0)\n    }\n\n    /**\n     * Write ASCII string\n     */\n    fun writeStringASCII(value: String) {\n        val bytes = value.toByteArray(java.nio.charset.StandardCharsets.US_ASCII)\n        outputStream.write(bytes)\n    }\n\n    /**\n     * Write Adobe Pascal-style string (UInt32 length in UTF-16 characters + UTF-16BE string)\n     */\n    fun writeAdobePascalStyleString(value: String) {\n        val utf16Bytes = value.toByteArray(java.nio.charset.StandardCharsets.UTF_16BE)\n        val length = utf16Bytes.size / 2 // UTF-16 is 2 bytes per character\n        writeUInt32(length.toUInt(), ByteOrder.BIG_ENDIAN)\n        if (utf16Bytes.isNotEmpty()) {\n            outputStream.write(utf16Bytes)\n        }\n    }\n\n    /**\n     * Write ASCII string with length prefix (UInt32, little endian)\n     */\n    fun writeStringASCIIWithLength(value: String, order: ByteOrder = ByteOrder.LITTLE_ENDIAN) {\n        val bytes = value.toByteArray(java.nio.charset.StandardCharsets.US_ASCII)\n        writeUInt32(bytes.size.toUInt(), order)\n        if (bytes.isNotEmpty()) {\n            outputStream.write(bytes)\n        }\n    }\n\n    /**\n     * Write UTF-8 string (null-terminated)\n     */\n    fun writeStringUTF8NullTerminated(value: String) {\n        val bytes = value.toByteArray(java.nio.charset.StandardCharsets.UTF_8)\n        outputStream.write(bytes)\n        outputStream.write(0) // null terminator\n    }\n\n    /**\n     * Write UTF-8 string with length prefix (UInt32, little endian)\n     */\n    fun writeStringUTF8WithLength(value: String, order: ByteOrder = ByteOrder.LITTLE_ENDIAN) {\n        val bytes = value.toByteArray(java.nio.charset.StandardCharsets.UTF_8)\n        writeUInt32(bytes.size.toUInt(), order)\n        if (bytes.isNotEmpty()) {\n            outputStream.write(bytes)\n        }\n    }\n\n    /**\n     * Write pattern bytes\n     */\n    fun writePattern(vararg bytes: Int) {\n        bytes.forEach { outputStream.write(it) }\n    }\n\n    /**\n     * Write Pascal-style UTF-16 string (UInt16 length in characters + UTF-16 string)\n     */\n    fun writePascalStringUTF16(value: String, order: ByteOrder) {\n        val charset = if (order == ByteOrder.BIG_ENDIAN)\n            java.nio.charset.StandardCharsets.UTF_16BE\n        else\n            java.nio.charset.StandardCharsets.UTF_16LE\n        val utf16Bytes = value.toByteArray(charset)\n        val length = utf16Bytes.size / 2 // UTF-16 is 2 bytes per character\n        if (length > 65535) {\n            throw IllegalArgumentException(\"String too long for Pascal UTF-16 (max 65535 characters)\")\n        }\n        writeUInt16(length.toUShort(), order)\n        if (utf16Bytes.isNotEmpty()) {\n            outputStream.write(utf16Bytes)\n        }\n    }\n\n    /**\n     * Write Float32 array\n     */\n    fun writeFloat32(values: List<Float>, order: ByteOrder) {\n        values.forEach { writeFloat32(it, order) }\n    }\n}\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/utils/CSVParser.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.utils\n\n/**\n * Simple CSV parser\n */\ninternal object CSVParser {\n    /**\n     * Parse CSV text into records\n     */\n    fun parse(text: String): List<List<String>> {\n        val records = mutableListOf<List<String>>()\n        val lines = text.lines()\n\n        for (line in lines) {\n            if (line.isBlank()) continue\n            val fields = line.split(',').map { it.trim() }\n            if (fields.isNotEmpty()) {\n                records.add(fields)\n            }\n        }\n\n        return records\n    }\n}\n\n\n"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/utils/HexUtils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.utils\n\nimport com.t8rin.palette.ColorByteFormat\nimport com.t8rin.palette.PaletteColor\n\n/**\n * Hex color utilities\n */\n\nprivate data class Quad(val a: Long, val b: Long, val c: Long, val d: Long)\n\n/**\n * Extract RGBA from hex string\n */\ninternal fun extractHexRGBA(rgbHexString: String, format: ColorByteFormat): PaletteColor.RGB? {\n    var hex = rgbHexString.lowercase().replace(Regex(\"[^0-9a-f]\"), \"\")\n    if (hex.startsWith(\"0x\")) {\n        hex = hex.substring(2)\n    }\n\n    val `val` = hex.toLongOrNull(16) ?: return null\n\n    val hasAlpha = hex.length == 4 || hex.length == 8\n\n    val quad = when (hex.length) {\n        3 -> { // RGB (12-bit)\n            val r = ((`val` shr 8) and 0xF) * 17\n            val g = ((`val` shr 4) and 0xF) * 17\n            val b = (`val` and 0xF) * 17\n            Quad(r, g, b, 255L)\n        }\n\n        4 -> { // RGBA (12-bit)\n            val r = ((`val` shr 12) and 0xF) * 17\n            val g = ((`val` shr 8) and 0xF) * 17\n            val b = ((`val` shr 4) and 0xF) * 17\n            val a = (`val` and 0xF) * 17\n            Quad(r, g, b, a)\n        }\n\n        6 -> { // RRGGBB (24-bit)\n            val r = (`val` shr 16) and 0xFF\n            val g = (`val` shr 8) and 0xFF\n            val b = `val` and 0xFF\n            Quad(r, g, b, 255L)\n        }\n\n        8 -> { // RRGGBBAA (32-bit)\n            val r = (`val` shr 24) and 0xFF\n            val g = (`val` shr 16) and 0xFF\n            val b = (`val` shr 8) and 0xFF\n            val a = `val` and 0xFF\n            Quad(r, g, b, a)\n        }\n\n        else -> return null\n    }\n\n    val c0 = quad.a\n    val c1 = quad.b\n    val c2 = quad.c\n    val c3 = quad.d\n\n    return when (format) {\n        ColorByteFormat.RGB -> PaletteColor.RGB(\n            r = c0 / 255.0,\n            g = c1 / 255.0,\n            b = c2 / 255.0,\n            a = 1.0\n        )\n\n        ColorByteFormat.BGR -> PaletteColor.RGB(\n            r = c2 / 255.0,\n            g = c1 / 255.0,\n            b = c0 / 255.0,\n            a = 1.0\n        )\n\n        ColorByteFormat.RGBA -> PaletteColor.RGB(\n            r = c0 / 255.0,\n            g = c1 / 255.0,\n            b = c2 / 255.0,\n            a = if (hasAlpha) c3 / 255.0 else 1.0\n        )\n\n        ColorByteFormat.ARGB -> PaletteColor.RGB(\n            r = c1 / 255.0,\n            g = c2 / 255.0,\n            b = c3 / 255.0,\n            a = if (hasAlpha) c0 / 255.0 else 1.0\n        )\n\n        ColorByteFormat.BGRA -> PaletteColor.RGB(\n            r = c2 / 255.0,\n            g = c1 / 255.0,\n            b = c0 / 255.0,\n            a = if (hasAlpha) c3 / 255.0 else 1.0\n        )\n\n        ColorByteFormat.ABGR -> PaletteColor.RGB(\n            r = c3 / 255.0,\n            g = c2 / 255.0,\n            b = c1 / 255.0,\n            a = if (hasAlpha) c0 / 255.0 else 1.0\n        )\n    }\n}\n\n/**\n * Generate hex string\n */\ninternal fun hexRGBString(\n    r255: Int,\n    g255: Int,\n    b255: Int,\n    a255: Int = 255,\n    format: ColorByteFormat,\n    hashmark: Boolean = true,\n    uppercase: Boolean = false\n): String {\n    val prefix = if (hashmark) \"#\" else \"\"\n    val fmt = if (uppercase) \"%02X%02X%02X%02X\" else \"%02x%02x%02x%02x\"\n    val fmt3 = if (uppercase) \"%02X%02X%02X\" else \"%02x%02x%02x\"\n\n    return when (format) {\n        ColorByteFormat.RGB -> prefix + String.format(fmt3, r255, g255, b255)\n        ColorByteFormat.BGR -> prefix + String.format(fmt3, b255, g255, r255)\n        ColorByteFormat.ARGB -> prefix + String.format(fmt, a255, r255, g255, b255)\n        ColorByteFormat.RGBA -> prefix + String.format(fmt, r255, g255, b255, a255)\n        ColorByteFormat.ABGR -> prefix + String.format(fmt, a255, b255, g255, r255)\n        ColorByteFormat.BGRA -> prefix + String.format(fmt, b255, g255, r255, a255)\n    }\n}\n\n/**\n * Extension functions for PaletteColor hex support\n */\nfun PaletteColor.hexString(format: ColorByteFormat, hashmark: Boolean, uppercase: Boolean): String {\n    val rgb = toRgb()\n    return hexRGBString(\n        r255 = (rgb.rf * 255).toInt().coerceIn(0, 255),\n        g255 = (rgb.gf * 255).toInt().coerceIn(0, 255),\n        b255 = (rgb.bf * 255).toInt().coerceIn(0, 255),\n        a255 = (rgb.af * 255).toInt().coerceIn(0, 255),\n        format = format,\n        hashmark = hashmark,\n        uppercase = uppercase\n    )\n}\n\n/**\n * Extension functions for PaletteColor.RGB hex support\n */\nfun PaletteColor.RGB.hexString(\n    format: ColorByteFormat,\n    hashmark: Boolean,\n    uppercase: Boolean\n): String {\n    return hexRGBString(\n        r255 = (rf * 255).toInt().coerceIn(0, 255),\n        g255 = (gf * 255).toInt().coerceIn(0, 255),\n        b255 = (bf * 255).toInt().coerceIn(0, 255),\n        a255 = (af * 255).toInt().coerceIn(0, 255),\n        format = format,\n        hashmark = hashmark,\n        uppercase = uppercase\n    )\n}"
  },
  {
    "path": "lib/palette/src/main/java/com/t8rin/palette/utils/Xml.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.utils\n\ninternal fun String.xmlDecoded(): String {\n    return this.replace(\"&amp;\", \"&\")\n        .replace(\"&lt;\", \"<\")\n        .replace(\"&gt;\", \">\")\n        .replace(\"&quot;\", \"\\\"\")\n        .replace(\"&apos;\", \"'\")\n}\n\ninternal fun String.xmlEscaped(): String {\n    return this.replace(\"&\", \"&amp;\")\n        .replace(\"<\", \"&lt;\")\n        .replace(\">\", \"&gt;\")\n        .replace(\"\\\"\", \"&quot;\")\n        .replace(\"'\", \"&apos;\")\n}"
  },
  {
    "path": "lib/palette/src/test/java/com/t8rin/palette/coders/PaletteCoderCompatibilityTest.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.palette.coders\n\nimport com.t8rin.palette.ColorGroup\nimport com.t8rin.palette.Palette\nimport com.t8rin.palette.PaletteColor\nimport com.t8rin.palette.encode\nimport org.junit.Test\nimport java.nio.ByteBuffer\nimport java.nio.ByteOrder\nimport java.util.zip.CRC32\nimport java.util.zip.ZipEntry\nimport java.util.zip.ZipInputStream\nimport java.util.zip.ZipOutputStream\nimport kotlin.test.assertContains\nimport kotlin.test.assertEquals\n\nclass PaletteCoderCompatibilityTest {\n\n    @Test\n    fun `krita decoder reads documented colorset structure`() {\n        val colorsetXml = \"\"\"\n            <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n            <Colorset name=\"Demo Palette\" comment=\"\" columns=\"2\" rows=\"1\" readonly=\"false\" version=\"1.0\">\n              <ColorSetEntry name=\"Red\" id=\"red_1\" bitdepth=\"F32\" spot=\"false\">\n                <Position row=\"0\" column=\"0\"/>\n                <sRGB r=\"1.0\" g=\"0.0\" b=\"0.0\"/>\n              </ColorSetEntry>\n              <Group name=\"Group One\" rows=\"1\">\n                <ColorSetEntry name=\"Green Spot\" id=\"green_1\" bitdepth=\"F32\" spot=\"true\">\n                  <Position row=\"0\" column=\"0\"/>\n                  <CMYK c=\"1.0\" m=\"0.0\" y=\"1.0\" k=\"0.0\"/>\n                </ColorSetEntry>\n              </Group>\n            </Colorset>\n        \"\"\".trimIndent()\n\n        val data = zipOf(\n            \"mimetype\" to \"application/x-krita-palette\".toByteArray(Charsets.US_ASCII),\n            \"colorset.xml\" to colorsetXml.toByteArray(Charsets.UTF_8),\n            \"profiles.xml\" to \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?><Profiles/>\"\"\".toByteArray(\n                Charsets.UTF_8\n            )\n        )\n\n        val palette = KRITAPaletteCoder().decode(data.inputStream())\n\n        assertEquals(\"Demo Palette\", palette.name)\n        assertEquals(1, palette.colors.size)\n        assertEquals(\"Red\", palette.colors.first().name)\n        assertEquals(1, palette.groups.size)\n        assertEquals(\"Group One\", palette.groups.first().name)\n        assertEquals(\"Green Spot\", palette.groups.first().colors.first().name)\n        assertEquals(\n            com.t8rin.palette.ColorType.Spot,\n            palette.groups.first().colors.first().colorType\n        )\n    }\n\n    @Test\n    fun `krita encoder writes mimetype and documented xml`() {\n        val palette = Palette(\n            name = \"Krita Export\",\n            colors = listOf(PaletteColor.rgb(1.0, 0.0, 0.0, name = \"Red\")),\n            groups = listOf(\n                ColorGroup(\n                    name = \"Group One\",\n                    colors = listOf(PaletteColor.cmyk(1.0, 0.0, 1.0, 0.0, name = \"CMYK Color\"))\n                )\n            )\n        )\n\n        val data = KRITAPaletteCoder().encode(palette)\n        val entries = unzip(data)\n\n        assertEquals(\"mimetype\", entries.first().first)\n        assertEquals(ZipEntry.STORED, entries.first().second.method)\n        assertEquals(\n            \"application/x-krita-palette\",\n            entries.first().third.toString(Charsets.US_ASCII)\n        )\n\n        val colorsetXml =\n            entries.first { it.first == \"colorset.xml\" }.third.toString(Charsets.UTF_8)\n        assertContains(colorsetXml, \"<Colorset\")\n        assertContains(colorsetXml, \"<ColorSetEntry\")\n        assertContains(\n            colorsetXml,\n            \"<sRGB r=\\\"1\\\" g=\\\"0\\\" b=\\\"0\\\"/>\\n    <Position row=\\\"0\\\" column=\\\"0\\\"/>\"\n        )\n\n        val decoded = KRITAPaletteCoder().decode(data.inputStream())\n        assertEquals(2, decoded.totalColorCount)\n        assertEquals(\"Krita Export\", decoded.name)\n        assertEquals(\"Group One\", decoded.groups.first().name)\n    }\n\n    @Test\n    fun `gimp encoder always writes version 2 header`() {\n        val encoded = GIMPPaletteCoder().encode(\n            Palette(\n                colors = listOf(PaletteColor.rgb(1.0, 0.0, 0.0, name = \"Primary\\tRed\"))\n            )\n        ).toString(Charsets.UTF_8)\n\n        val lines = encoded.lines()\n        assertEquals(\"GIMP Palette\", lines[0])\n        assertEquals(\"Name: \", lines[1])\n        assertEquals(\"Columns: 0\", lines[2])\n        assertEquals(\"#Colors: 1\", lines[3])\n        assertEquals(\"255\\t0\\t0\\tPrimary Red\", lines[4])\n    }\n\n    @Test\n    fun `basic xml decoder works without namespace aware parser`() {\n        val xml = \"\"\"\n            <?xml version=\"1.0\" encoding=\"utf-8\"?>\n            <palette name=\"Basic\">\n              <color name=\"Red\" r=\"255\" g=\"0\" b=\"0\" a=\"255\" />\n            </palette>\n        \"\"\".trimIndent()\n\n        val palette = BasicXMLCoder().decode(xml.byteInputStream())\n\n        assertEquals(\"Basic\", palette.name)\n        assertEquals(1, palette.colors.size)\n        assertEquals(\"Red\", palette.colors.first().name)\n    }\n\n    @Test\n    fun `android colors xml decoder reads plain resources`() {\n        val xml = \"\"\"\n            <?xml version=\"1.0\" encoding=\"utf-8\"?>\n            <resources>\n              <color name=\"accent\">#80FF0000</color>\n            </resources>\n        \"\"\".trimIndent()\n\n        val palette = AndroidColorsXMLCoder().decode(xml.byteInputStream())\n\n        assertEquals(1, palette.colors.size)\n        assertEquals(\"accent\", palette.colors.first().name)\n    }\n\n    @Test\n    fun `act encoder stays within standard file size`() {\n        val data = ACTPaletteCoder().encode(\n            Palette(\n                colors = listOf(PaletteColor.rgb(1.0, 0.0, 0.0, name = \"Named Color\"))\n            )\n        )\n\n        assertEquals(772, data.size)\n    }\n\n    @Test\n    fun `riff encoder writes little endian chunk size`() {\n        val data = RIFFPaletteCoder().encode(\n            Palette(\n                colors = listOf(\n                    PaletteColor.rgb(1.0, 0.0, 0.0, name = \"Red\"),\n                    PaletteColor.rgb(0.0, 1.0, 0.0)\n                )\n            )\n        )\n\n        val riffSize = ByteBuffer.wrap(data, 4, 4).order(ByteOrder.LITTLE_ENDIAN).int\n        assertEquals(data.size - 8, riffSize)\n    }\n\n    private fun zipOf(vararg entries: Pair<String, ByteArray>): ByteArray {\n        val output = java.io.ByteArrayOutputStream()\n        ZipOutputStream(output).use { zipOutputStream ->\n            entries.forEachIndexed { index, (name, data) ->\n                val entry = ZipEntry(name)\n                if (index == 0 && name == \"mimetype\") {\n                    val crc = CRC32().apply { update(data) }\n                    entry.method = ZipEntry.STORED\n                    entry.size = data.size.toLong()\n                    entry.compressedSize = data.size.toLong()\n                    entry.crc = crc.value\n                }\n                zipOutputStream.putNextEntry(entry)\n                zipOutputStream.write(data)\n                zipOutputStream.closeEntry()\n            }\n        }\n        return output.toByteArray()\n    }\n\n    private fun unzip(data: ByteArray): List<Triple<String, ZipEntry, ByteArray>> {\n        val entries = mutableListOf<Triple<String, ZipEntry, ByteArray>>()\n        ZipInputStream(data.inputStream()).use { zipInputStream ->\n            var entry = zipInputStream.nextEntry\n            while (entry != null) {\n                entries.add(Triple(entry.name, entry, zipInputStream.readBytes()))\n                entry = zipInputStream.nextEntry\n            }\n        }\n        return entries\n    }\n}\n"
  },
  {
    "path": "lib/qrose/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/qrose/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"io.github.alexzhirkevich\""
  },
  {
    "path": "lib/qrose/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/CachedPainter.kt",
    "content": "package io.github.alexzhirkevich.qrose\n\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.drawscope.CanvasDrawScope\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.toSize\nimport kotlin.math.ceil\n\nabstract class CachedPainter : Painter() {\n\n    private var alpha = 1f\n    private var colorFilter: ColorFilter? = null\n\n    private var cachedSize: Size? = null\n\n    private var cacheDrawScope = DrawCache()\n\n    override fun applyAlpha(alpha: Float): Boolean {\n        this.alpha = alpha\n        return true\n    }\n\n    override fun applyColorFilter(colorFilter: ColorFilter?): Boolean {\n        this.colorFilter = colorFilter\n        return true\n    }\n\n    abstract fun DrawScope.onCache()\n\n    private val block: DrawScope.() -> Unit = { onCache() }\n\n    override fun DrawScope.onDraw() {\n        if (cachedSize != size) {\n\n            cacheDrawScope.drawCachedImage(\n                size = IntSize(ceil(size.width).toInt(), ceil(size.height).toInt()),\n                density = this,\n                layoutDirection = layoutDirection,\n                block = block\n            )\n            cachedSize = size\n        }\n        cacheDrawScope.drawInto(\n            target = this,\n            alpha = alpha,\n            colorFilter = colorFilter\n        )\n    }\n}\n\n/**\n * Creates a drawing environment that directs its drawing commands to an [ImageBitmap]\n * which can be drawn directly in another [DrawScope] instance. This is useful to cache\n * complicated drawing commands across frames especially if the content has not changed.\n * Additionally some drawing operations such as rendering paths are done purely in\n * software so it is beneficial to cache the result and render the contents\n * directly through a texture as done by [DrawScope.drawImage]\n */\nprivate class DrawCache {\n\n    var mCachedImage: ImageBitmap? = null\n    private var cachedCanvas: Canvas? = null\n    private var scopeDensity: Density? = null\n    private var layoutDirection: LayoutDirection = LayoutDirection.Ltr\n    private var size: IntSize = IntSize.Zero\n\n    private val cacheScope = CanvasDrawScope()\n\n    /**\n     * Draw the contents of the lambda with receiver scope into an [ImageBitmap] with the provided\n     * size. If the same size is provided across calls, the same [ImageBitmap] instance is\n     * re-used and the contents are cleared out before drawing content in it again\n     */\n    fun drawCachedImage(\n        size: IntSize,\n        density: Density,\n        layoutDirection: LayoutDirection,\n        block: DrawScope.() -> Unit\n    ) {\n        this.scopeDensity = density\n        this.layoutDirection = layoutDirection\n        var targetImage = mCachedImage\n        var targetCanvas = cachedCanvas\n        if (targetImage == null ||\n            targetCanvas == null ||\n            size.width > targetImage.width ||\n            size.height > targetImage.height\n        ) {\n            targetImage = ImageBitmap(size.width, size.height)\n            targetCanvas = Canvas(targetImage)\n\n            mCachedImage = targetImage\n            cachedCanvas = targetCanvas\n        }\n        this.size = size\n        cacheScope.draw(density, layoutDirection, targetCanvas, size.toSize()) {\n            clear()\n            block()\n        }\n        targetImage.prepareToDraw()\n    }\n\n    /**\n     * Draw the cached content into the provided [DrawScope] instance\n     */\n    fun drawInto(\n        target: DrawScope,\n        alpha: Float = 1.0f,\n        colorFilter: ColorFilter? = null\n    ) {\n        val targetImage = mCachedImage\n        check(targetImage != null) {\n            \"drawCachedImage must be invoked first before attempting to draw the result \" +\n                    \"into another destination\"\n        }\n        target.drawImage(targetImage, srcSize = size, alpha = alpha, colorFilter = colorFilter)\n    }\n\n    /**\n     * Helper method to clear contents of the draw environment from the given bounds of the\n     * DrawScope\n     */\n    private fun DrawScope.clear() {\n        drawRect(color = Color.Black, blendMode = BlendMode.Clear)\n    }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/Converters.kt",
    "content": "package io.github.alexzhirkevich.qrose\n\nimport android.graphics.Bitmap\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.asAndroidBitmap\nimport androidx.compose.ui.graphics.drawscope.CanvasDrawScope\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\nimport java.io.ByteArrayOutputStream\n\nenum class ImageFormat {\n    PNG, JPEG, WEBP\n}\n\n/**\n * Converts [ImageBitmap] to image with desired [format] and returns its bytes.\n * */\nfun ImageBitmap.toByteArray(format: ImageFormat = ImageFormat.PNG): ByteArray =\n    asAndroidBitmap().run {\n        ByteArrayOutputStream().use {\n            compress(\n                when (format) {\n                    ImageFormat.PNG -> Bitmap.CompressFormat.PNG\n                    ImageFormat.JPEG -> Bitmap.CompressFormat.JPEG\n                    ImageFormat.WEBP -> Bitmap.CompressFormat.WEBP\n                },\n                100,\n                it\n            )\n\n            it.toByteArray()\n        }\n    }\n\n/**\n * Converts [Painter] to image with desired [width], [height] and [format] and returns its bytes.\n * */\nfun Painter.toByteArray(width: Int, height: Int, format: ImageFormat = ImageFormat.PNG): ByteArray =\n    toImageBitmap(width, height).toByteArray(format)\n\n/**\n * Converts [Painter] to [ImageBitmap] with desired [width], [height], [alpha] and [colorFilter]\n * */\nfun Painter.toImageBitmap(\n    width: Int,\n    height: Int,\n    alpha: Float = 1f,\n    colorFilter: ColorFilter? = null\n): ImageBitmap {\n\n    val bmp = ImageBitmap(width, height)\n    val canvas = Canvas(bmp)\n\n    CanvasDrawScope().draw(\n        density = Density(1f, 1f),\n        layoutDirection = LayoutDirection.Ltr,\n        canvas = canvas,\n        size = Size(width.toFloat(), height.toFloat())\n    ) {\n        draw(this@draw.size, alpha, colorFilter)\n    }\n\n    return bmp\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/DelicateQRoseApi.kt",
    "content": "package io.github.alexzhirkevich.qrose\n\n@RequiresOptIn(\n    message = \"This API may negatively impact QR code functionality\",\n    level = RequiresOptIn.Level.WARNING\n)\nannotation class DelicateQRoseApi"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/QrCodePainter.kt",
    "content": "package io.github.alexzhirkevich.qrose\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Matrix\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.PathOperation\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.graphics.painter.Painter\nimport io.github.alexzhirkevich.qrose.options.Neighbors\nimport io.github.alexzhirkevich.qrose.options.QrBrush\nimport io.github.alexzhirkevich.qrose.options.QrBrushMode\nimport io.github.alexzhirkevich.qrose.options.QrCodeMatrix\nimport io.github.alexzhirkevich.qrose.options.QrColors\nimport io.github.alexzhirkevich.qrose.options.QrErrorCorrectionLevel\nimport io.github.alexzhirkevich.qrose.options.QrLogo\nimport io.github.alexzhirkevich.qrose.options.QrLogoPadding\nimport io.github.alexzhirkevich.qrose.options.QrOptions\nimport io.github.alexzhirkevich.qrose.options.QrShapeModifier\nimport io.github.alexzhirkevich.qrose.options.QrShapes\nimport io.github.alexzhirkevich.qrose.options.dsl.QrOptionsBuilderScope\nimport io.github.alexzhirkevich.qrose.options.isSpecified\nimport io.github.alexzhirkevich.qrose.options.neighbors\nimport io.github.alexzhirkevich.qrose.options.newPath\nimport io.github.alexzhirkevich.qrose.qrcode.ErrorCorrectionLevel\nimport io.github.alexzhirkevich.qrose.qrcode.QRCode\nimport kotlin.math.roundToInt\n\n/**\n * Create and remember QR code painter\n *\n * @param data QR code payload\n * @param keys keys of the [options] block. QR code will be re-generated when any key is changed.\n * @param options [QrOptions] builder block\n * */\n@Composable\nfun rememberQrCodePainter(\n    data: String,\n    vararg keys: Any?,\n    onSuccess: () -> Unit = {},\n    onFailure: (Throwable) -> Unit = {},\n    options: QrOptionsBuilderScope.() -> Unit\n): QrCodePainter = rememberQrCodePainter(\n    data = data,\n    options = remember(keys) { QrOptions(options) },\n    onFailure = onFailure,\n    onSuccess = onSuccess\n)\n\n/**\n * Create and remember QR code painter\n *\n * @param data QR code payload\n * @param options QR code styling options\n * */\n@Composable\nfun rememberQrCodePainter(\n    data: String,\n    options: QrOptions,\n    onSuccess: () -> Unit = {},\n    onFailure: (Throwable) -> Unit = {}\n): QrCodePainter = remember(data, options, onFailure, onSuccess) {\n    QrCodePainter(\n        data = data,\n        options = options,\n        onFailure = onFailure,\n        onSuccess = onSuccess\n    )\n}\n\n@Composable\nfun rememberQrCodePainter(\n    data: String,\n    shapes: QrShapes = QrShapes(),\n    colors: QrColors = QrColors(),\n    logo: QrLogo = QrLogo(),\n    errorCorrectionLevel: QrErrorCorrectionLevel = QrErrorCorrectionLevel.Auto,\n    fourEyed: Boolean = false,\n    onFailure: (Throwable) -> Unit = {},\n    onSuccess: () -> Unit = {},\n): QrCodePainter = rememberQrCodePainter(\n    data = data,\n    options = remember(shapes, colors, logo, errorCorrectionLevel, fourEyed) {\n        QrOptions(\n            shapes = shapes,\n            colors = colors,\n            logo = logo,\n            errorCorrectionLevel = errorCorrectionLevel,\n            fourEyed = fourEyed\n        )\n    },\n    onFailure = onFailure,\n    onSuccess = onSuccess\n)\n\n/**\n * Encodes [data] payload and renders it into the compose [Painter] using styling [options]\n * */\n@Immutable\nclass QrCodePainter(\n    val data: String,\n    val options: QrOptions = QrOptions(),\n    val onSuccess: () -> Unit,\n    val onFailure: (Throwable) -> Unit\n) : CachedPainter() {\n    private val initialMatrixSize: Int\n\n    private val actualCodeMatrix = options.shapes.code.run {\n\n        val initialMatrix = runCatching {\n            QRCode(\n                data = data,\n                errorCorrectionLevel =\n                    if (options.errorCorrectionLevel == QrErrorCorrectionLevel.Auto)\n                        options.errorCorrectionLevel.fit(options).lvl\n                    else options.errorCorrectionLevel.lvl\n            ).encode(maskPattern = options.maskPattern)\n        }.onFailure(onFailure).onSuccess {\n            if (it.size == 0) onFailure(IllegalArgumentException(\"Failed to generate QR code\"))\n            else onSuccess()\n        }.getOrDefault(QrCodeMatrix(1))\n\n        initialMatrixSize = initialMatrix.size\n\n        initialMatrix.transform()\n    }\n\n    private var codeMatrix = actualCodeMatrix\n\n    override val intrinsicSize: Size = Size(\n        codeMatrix.size.toFloat() * 10f,\n        codeMatrix.size.toFloat() * 10f\n    )\n\n\n    private val shapeIncrease = (codeMatrix.size - initialMatrixSize) / 2\n\n    private val balls = mutableListOf(\n        2 + shapeIncrease to 2 + shapeIncrease,\n        2 + shapeIncrease to initialMatrixSize - 5 + shapeIncrease,\n        initialMatrixSize - 5 + shapeIncrease to 2 + shapeIncrease\n    ).apply {\n        if (options.fourEyed)\n            this += initialMatrixSize - 5 + shapeIncrease to initialMatrixSize - 5 + shapeIncrease\n    }.toList()\n\n    private val frames = mutableListOf(\n        shapeIncrease to shapeIncrease,\n        shapeIncrease to initialMatrixSize - 7 + shapeIncrease,\n        initialMatrixSize - 7 + shapeIncrease to shapeIncrease\n    ).apply {\n        if (options.fourEyed) {\n            this += initialMatrixSize - 7 + shapeIncrease to initialMatrixSize - 7 + shapeIncrease\n        }\n    }.toList()\n\n    private val shouldSeparateDarkPixels\n        get() = options.colors.dark.mode == QrBrushMode.Separate\n\n    private val shouldSeparateLightPixels\n        get() = options.colors.light.mode == QrBrushMode.Separate\n\n    private val shouldSeparateFrames\n        get() = options.colors.frame.isSpecified || shouldSeparateDarkPixels\n\n    private val shouldSeparateBalls\n        get() = options.colors.ball.isSpecified || shouldSeparateDarkPixels\n\n    override fun toString(): String {\n        return \"QrCodePainter(data = $data)\"\n    }\n\n    override fun hashCode(): Int {\n        return data.hashCode() * 31 + options.hashCode()\n    }\n\n    private val DrawScope.logoSize\n        get() = size * options.logo.size\n\n    private val DrawScope.logoPaddingSize\n        get() = logoSize.width * (1 + options.logo.padding.size)\n\n    private val DrawScope.pixelSize: Float\n        get() = minOf(size.width, size.height) / codeMatrix.size\n\n\n    override fun DrawScope.onCache() {\n        draw()\n    }\n\n    private fun DrawScope.draw() {\n        if (actualCodeMatrix.size > 1) {\n            runCatching {\n                drawRect(\n                    options.colors.background.brush(\n                        size = maxOf(size.width, size.height),\n                        neighbors = Neighbors.Empty\n                    )\n                )\n\n                val pixelSize = pixelSize\n\n                prepareLogo(pixelSize)\n\n                val (dark, light) = createMainElements(pixelSize)\n\n                if (shouldSeparateDarkPixels || shouldSeparateLightPixels) {\n                    drawSeparatePixels(pixelSize)\n                }\n\n                if (!shouldSeparateLightPixels) {\n                    drawPath(\n                        path = light,\n                        brush = options.colors.light\n                            .brush(pixelSize * codeMatrix.size, Neighbors.Empty),\n                    )\n                }\n\n                if (!shouldSeparateDarkPixels) {\n                    drawPath(\n                        path = dark,\n                        brush = options.colors.dark\n                            .brush(pixelSize * codeMatrix.size, Neighbors.Empty),\n                    )\n                }\n\n                if (shouldSeparateFrames) {\n                    drawFrames(pixelSize)\n                }\n\n                if (shouldSeparateBalls) {\n                    drawBalls(pixelSize)\n                }\n\n                drawLogo()\n            }.onFailure(onFailure)\n        }\n    }\n\n    private fun DrawScope.drawSeparatePixels(\n        pixelSize: Float,\n    ) {\n        val darkPaint = darkPaintFactory(pixelSize)\n        val lightPaint = lightPaintFactory(pixelSize)\n\n        val darkPixelPath = darkPixelPathFactory(pixelSize)\n        val lightPixelPath = lightPixelPathFactory(pixelSize)\n\n        repeat(codeMatrix.size) { i ->\n            repeat(codeMatrix.size) inner@{ j ->\n                if (isInsideFrameOrBall(i, j))\n                    return@inner\n\n                translate(\n                    left = i * pixelSize,\n                    top = j * pixelSize\n                ) {\n                    if (shouldSeparateDarkPixels && codeMatrix[i, j] == QrCodeMatrix.PixelType.DarkPixel) {\n                        val n = codeMatrix.neighbors(i, j)\n                        drawPath(\n                            path = darkPixelPath.next(n),\n                            brush = darkPaint.next(n),\n                        )\n                    }\n                    if (shouldSeparateLightPixels && codeMatrix[i, j] == QrCodeMatrix.PixelType.LightPixel) {\n                        val n = codeMatrix.neighbors(i, j)\n\n                        drawPath(\n                            path = lightPixelPath.next(n),\n                            brush = lightPaint.next(n),\n                        )\n                    }\n                }\n            }\n        }\n    }\n\n\n    private fun DrawScope.prepareLogo(pixelSize: Float) {\n\n        val ps = logoPaddingSize\n\n        if (options.logo.padding is QrLogoPadding.Natural) {\n            val logoPath = options.logo.shape.newPath(\n                size = ps,\n                neighbors = Neighbors.Empty\n            ).apply {\n                translate(\n                    Offset(\n                        (size.width - ps) / 2f,\n                        (size.height - ps) / 2f,\n                    )\n                )\n            }\n\n            val darkPathF = darkPixelPathFactory(pixelSize)\n            val lightPathF = lightPixelPathFactory(pixelSize)\n\n            val logoPixels = (codeMatrix.size *\n                    options.logo.size.coerceIn(0f, 1f) *\n                    (1 + options.logo.padding.size.coerceIn(0f, 1f))).roundToInt() + 1\n\n            val xRange =\n                (codeMatrix.size - logoPixels) / 2 until (codeMatrix.size + logoPixels) / 2\n            val yRange =\n                (codeMatrix.size - logoPixels) / 2 until (codeMatrix.size + logoPixels) / 2\n\n            for (x in xRange) {\n                for (y in yRange) {\n                    val neighbors = codeMatrix.neighbors(x, y)\n                    val offset = Offset(x * pixelSize, y * pixelSize)\n\n                    val darkPath = darkPathF.next(neighbors).apply {\n                        translate(offset)\n                    }\n                    val lightPath = lightPathF.next(neighbors).apply {\n                        translate(offset)\n                    }\n\n                    if (\n                        codeMatrix[x, y] == QrCodeMatrix.PixelType.DarkPixel &&\n                        logoPath.intersects(darkPath) ||\n                        codeMatrix[x, y] == QrCodeMatrix.PixelType.LightPixel &&\n                        logoPath.intersects(lightPath)\n                    ) {\n                        codeMatrix[x, y] = QrCodeMatrix.PixelType.Logo\n                    }\n                }\n            }\n        }\n    }\n\n    private fun DrawScope.drawLogo() {\n\n        val ps = logoPaddingSize\n\n        if (options.logo.padding is QrLogoPadding.Accurate) {\n            val path = options.logo.shape.newPath(\n                size = ps,\n                neighbors = Neighbors.Empty\n            )\n\n            translate(\n                left = center.x - ps / 2,\n                top = center.y - ps / 2\n            ) {\n                drawPath(path, Color.Black, blendMode = BlendMode.Clear)\n            }\n        }\n\n        options.logo.painter?.let {\n            it.run {\n                translate(\n                    left = center.x - logoSize.width / 2,\n                    top = center.y - logoSize.height / 2\n                ) {\n                    draw(logoSize)\n                }\n            }\n        }\n    }\n\n\n    private fun DrawScope.drawBalls(\n        pixelSize: Float\n    ) {\n        val brush by ballBrushFactory(pixelSize)\n        val path by ballShapeFactory(pixelSize)\n\n        balls.forEach {\n\n            translate(\n                it.first * pixelSize,\n                it.second * pixelSize\n            ) {\n                drawPath(\n                    path = path,\n                    brush = brush,\n                )\n            }\n        }\n    }\n\n\n    private fun DrawScope.drawFrames(\n        pixelSize: Float\n    ) {\n        val ballBrush by frameBrushFactory(pixelSize)\n        val ballPath by frameShapeFactory(pixelSize)\n\n        frames.forEach {\n\n            translate(\n                it.first * pixelSize,\n                it.second * pixelSize\n            ) {\n                drawPath(\n                    path = ballPath,\n                    brush = ballBrush,\n                )\n            }\n        }\n    }\n\n    private fun createMainElements(\n        pixelSize: Float\n    ): Pair<Path, Path> {\n\n        val darkPath = Path().apply {\n            fillType = PathFillType.EvenOdd\n        }\n        val lightPath = Path().apply {\n            fillType = PathFillType.EvenOdd\n        }\n\n        val rotatedFramePath by frameShapeFactory(pixelSize)\n        val rotatedBallPath by ballShapeFactory(pixelSize)\n\n        val darkPixelPathFactory = darkPixelPathFactory(pixelSize)\n        val lightPixelPathFactory = lightPixelPathFactory(pixelSize)\n\n        for (x in 0 until codeMatrix.size) {\n            for (y in 0 until codeMatrix.size) {\n\n                val neighbors = codeMatrix.neighbors(x, y)\n\n                when {\n                    !shouldSeparateFrames && isFrameStart(x, y) ->\n                        darkPath\n                            .addPath(\n                                path = rotatedFramePath,\n                                offset = Offset(x * pixelSize, y * pixelSize)\n                            )\n\n\n                    !shouldSeparateBalls && isBallStart(x, y) ->\n                        darkPath\n                            .addPath(\n                                path = rotatedBallPath,\n                                offset = Offset(x * pixelSize, y * pixelSize)\n                            )\n\n                    isInsideFrameOrBall(x, y) -> Unit\n\n                    !shouldSeparateDarkPixels && codeMatrix[x, y] == QrCodeMatrix.PixelType.DarkPixel ->\n                        darkPath\n                            .addPath(\n                                path = darkPixelPathFactory.next(neighbors),\n                                offset = Offset(x * pixelSize, y * pixelSize)\n                            )\n\n                    !shouldSeparateLightPixels && codeMatrix[x, y] == QrCodeMatrix.PixelType.LightPixel ->\n                        lightPath\n                            .addPath(\n                                path = lightPixelPathFactory.next(neighbors),\n                                offset = Offset(x * pixelSize, y * pixelSize)\n                            )\n\n                }\n            }\n        }\n        return darkPath to lightPath\n    }\n\n\n    private fun isFrameStart(x: Int, y: Int) =\n        x - shapeIncrease == 0 && y - shapeIncrease == 0 ||\n                x - shapeIncrease == 0 && y - shapeIncrease == initialMatrixSize - 7 ||\n                x - shapeIncrease == initialMatrixSize - 7 && y - shapeIncrease == 0 ||\n                options.fourEyed && x - shapeIncrease == initialMatrixSize - 7 && y - shapeIncrease == initialMatrixSize - 7\n\n    private fun isBallStart(x: Int, y: Int) =\n        x - shapeIncrease == 2 && y - shapeIncrease == initialMatrixSize - 5 ||\n                x - shapeIncrease == initialMatrixSize - 5 && y - shapeIncrease == 2 ||\n                x - shapeIncrease == 2 && y - shapeIncrease == 2 ||\n                options.fourEyed && x - shapeIncrease == initialMatrixSize - 5 && y - shapeIncrease == initialMatrixSize - 5\n\n    private fun isInsideFrameOrBall(x: Int, y: Int): Boolean {\n        return x - shapeIncrease in -1..7 && y - shapeIncrease in -1..7 ||\n                x - shapeIncrease in -1..7 && y - shapeIncrease in initialMatrixSize - 8 until initialMatrixSize + 1 ||\n                x - shapeIncrease in initialMatrixSize - 8 until initialMatrixSize + 1 && y - shapeIncrease in -1..7 ||\n                options.fourEyed && x - shapeIncrease in initialMatrixSize - 8 until initialMatrixSize + 1 && y - shapeIncrease in initialMatrixSize - 8 until initialMatrixSize + 1\n    }\n\n    private fun darkPaintFactory(pixelSize: Float) =\n        pixelBrushFactory(\n            brush = options.colors.dark,\n            separate = shouldSeparateDarkPixels,\n            pixelSize = pixelSize\n        )\n\n    private fun lightPaintFactory(pixelSize: Float) =\n        pixelBrushFactory(\n            brush = options.colors.light,\n            separate = shouldSeparateLightPixels,\n            pixelSize = pixelSize\n        )\n\n    private fun ballBrushFactory(pixelSize: Float) =\n        eyeBrushFactory(brush = options.colors.ball, pixelSize = pixelSize)\n\n    private fun frameBrushFactory(pixelSize: Float) =\n        eyeBrushFactory(brush = options.colors.frame, pixelSize = pixelSize)\n\n\n    private fun ballShapeFactory(pixelSize: Float): Lazy<Path> =\n        rotatedPathFactory(\n            shape = options.shapes.ball,\n            shapeSize = pixelSize * BALL_SIZE\n        )\n\n    private fun frameShapeFactory(pixelSize: Float): Lazy<Path> =\n        rotatedPathFactory(\n            shape = options.shapes.frame,\n            shapeSize = pixelSize * FRAME_SIZE\n        )\n\n    private fun darkPixelPathFactory(pixelSize: Float) =\n        pixelPathFactory(\n            shape = options.shapes.darkPixel,\n            pixelSize = pixelSize\n        )\n\n    private fun lightPixelPathFactory(pixelSize: Float) =\n        pixelPathFactory(\n            shape = options.shapes.lightPixel,\n            pixelSize = pixelSize\n        )\n\n    private fun pixelPathFactory(\n        shape: QrShapeModifier,\n        pixelSize: Float\n    ): NeighborsBasedFactory<Path> {\n        val path = Path()\n\n        return NeighborsBasedFactory {\n            path.rewind()\n            path.apply {\n                shape.run {\n                    path(pixelSize, it)\n                }\n            }\n            path\n        }\n    }\n\n    private fun rotatedPathFactory(\n        shape: QrShapeModifier,\n        shapeSize: Float,\n    ): Lazy<Path> {\n\n        var number = 0\n\n        val path = Path()\n\n        val factory = NeighborsBasedFactory {\n            path.apply {\n                rewind()\n                fillType = PathFillType.EvenOdd\n                shape.run { path(shapeSize, it) }\n            }\n        }\n\n        return Recreating {\n            factory.next(Neighbors.forEyeWithNumber(number, options.fourEyed)).apply {\n                if (options.shapes.centralSymmetry) {\n                    val angle = when (number) {\n                        0 -> 0f\n                        1 -> -90f\n                        2 -> 90f\n                        else -> 180f\n                    }\n                    rotate(angle, Offset(shapeSize / 2, shapeSize / 2))\n                }\n            }.also {\n                number = (number + 1) % if (options.fourEyed) 4 else 3\n            }\n        }\n    }\n\n\n    private fun eyeBrushFactory(\n        brush: QrBrush,\n        pixelSize: Float\n    ): Lazy<Brush> {\n        val b = brush\n            .takeIf { it.isSpecified }\n            ?: QrBrush.Default\n\n        var number = 0\n\n        val factory = {\n            b.brush(\n                size = pixelSize,\n                neighbors = Neighbors.forEyeWithNumber(number, options.fourEyed)\n            ).also {\n                number = (number + 1) % if (options.fourEyed) 4 else 3\n            }\n        }\n\n        return Recreating(factory)\n    }\n\n    private fun pixelBrushFactory(\n        brush: QrBrush,\n        separate: Boolean,\n        pixelSize: Float,\n    ): NeighborsBasedFactory<Brush> {\n\n        val size = if (separate)\n            pixelSize\n        else codeMatrix.size * pixelSize\n\n        val joinBrush by lazy { brush.brush(size, Neighbors.Empty) }\n\n        return NeighborsBasedFactory {\n            if (separate)\n                brush.brush(size, it)\n            else joinBrush\n        }\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || this::class != other::class) return false\n\n        other as QrCodePainter\n\n        if (data != other.data) return false\n        if (options != other.options) return false\n\n        return true\n    }\n}\n\nprivate const val BALL_SIZE = 3\nprivate const val FRAME_SIZE = 7\n\n\nprivate fun Path.rotate(degree: Float, pivot: Offset) {\n    translate(-pivot)\n    transform(Matrix().apply { rotateZ(degree) })\n    translate(pivot)\n}\n\nprivate fun Path.intersects(other: Path) =\n    Path.combine(\n        operation = PathOperation.Intersect,\n        path1 = this,\n        path2 = other\n    ).isEmpty.not()\n\nprivate class Recreating<T>(\n    private val factory: () -> T\n) : Lazy<T> {\n    override val value: T\n        get() = factory()\n\n    override fun isInitialized(): Boolean = true\n}\n\nprivate fun Neighbors.Companion.forEyeWithNumber(\n    number: Int,\n    fourthEyeEnabled: Boolean\n): Neighbors {\n    return when (number) {\n        0 -> Neighbors(bottom = true, right = true, bottomRight = fourthEyeEnabled)\n        1 -> Neighbors(bottom = fourthEyeEnabled, left = true, bottomLeft = true)\n        2 -> Neighbors(top = true, topRight = true, right = fourthEyeEnabled)\n        3 -> Neighbors(top = true, left = true, topLeft = true)\n\n        else -> throw IllegalStateException(\"Incorrect eye number: $number\")\n    }\n}\n\nprivate fun interface NeighborsBasedFactory<T> {\n    fun next(neighbors: Neighbors): T\n}\n\n\nprivate fun QrErrorCorrectionLevel.fit(\n    options: QrOptions\n): QrErrorCorrectionLevel {\n\n    val logoSize = options.logo.size *\n            (1 + options.logo.padding.size) //*\n//            options.shapes.code.shapeSizeIncrease\n\n    val hasLogo = options.logo.padding != QrLogoPadding.Empty\n\n    return if (this == QrErrorCorrectionLevel.Auto)\n        when {\n            !hasLogo -> QrErrorCorrectionLevel.Low\n            logoSize > .3 -> QrErrorCorrectionLevel.High\n            logoSize in .2.. .3 && lvl < ErrorCorrectionLevel.Q ->\n                QrErrorCorrectionLevel.MediumHigh\n\n            logoSize > .05f && lvl < ErrorCorrectionLevel.M ->\n                QrErrorCorrectionLevel.Medium\n\n            else -> this\n        } else this\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/QrData.kt",
    "content": "@file:Suppress(\"UnusedReceiverParameter\", \"unused\")\n\npackage io.github.alexzhirkevich.qrose\n\nobject QrData\n\nfun QrData.text(text: String): String = text\n\nfun QrData.phone(phoneNumber: String): String = \"TEL:$phoneNumber\"\n\nfun QrData.email(\n    email: String,\n    copyTo: String? = null,\n    subject: String? = null,\n    body: String? = null\n): String = buildString {\n    append(\"mailto:$email\")\n\n    if (listOf(copyTo, subject, body).any { it.isNullOrEmpty().not() }) {\n        append(\"?\")\n    }\n    val queries = buildList {\n        if (copyTo.isNullOrEmpty().not()) {\n            add(\"cc=$copyTo\")\n        }\n        if (subject.isNullOrEmpty().not()) {\n            add(\"subject=${escape(subject)}\")\n        }\n        if (body.isNullOrEmpty().not()) {\n            add(\"body=${escape(body)}\")\n        }\n    }\n    append(queries.joinToString(separator = \"&\"))\n}\n\nfun QrData.sms(\n    phoneNumber: String,\n    subject: String,\n    isMMS: Boolean\n): String = \"${if (isMMS) \"MMS\" else \"SMS\"}:\" +\n        \"$phoneNumber${if (subject.isNotEmpty()) \":$subject\" else \"\"}\"\n\n\nfun QrData.meCard(\n    name: String? = null,\n    address: String? = null,\n    phoneNumber: String? = null,\n    email: String? = null,\n): String = buildString {\n    append(\"MECARD:\")\n    if (name != null)\n        append(\"N:$name;\")\n\n    if (address != null)\n        append(\"ADR:$address;\")\n\n    if (phoneNumber != null)\n        append(\"TEL:$phoneNumber;\")\n\n    if (email != null)\n        append(\"EMAIL:$email;\")\n\n    append(\";\")\n}\n\nfun QrData.vCard(\n    name: String? = null,\n    company: String? = null,\n    title: String? = null,\n    phoneNumber: String? = null,\n    email: String? = null,\n    address: String? = null,\n    website: String? = null,\n    note: String? = null,\n): String = buildString {\n    append(\"BEGIN:VCARD\\n\")\n    append(\"VERSION:3.0\\n\")\n    if (name != null)\n        append(\"N:$name\\n\")\n\n    if (company != null)\n        append(\"ORG:$company\\n\")\n\n    if (title != null)\n        append(\"TITLE$title\\n\")\n\n    if (phoneNumber != null)\n        append(\"TEL:$phoneNumber\\n\")\n\n    if (website != null)\n        append(\"URL:$website\\n\")\n\n    if (email != null)\n        append(\"EMAIL:$email\\n\")\n\n    if (address != null)\n        append(\"ADR:$address\\n\")\n\n    if (note != null) {\n        append(\"NOTE:$note\\n\")\n    }\n    append(\"END:VCARD\")\n}\n\nfun QrData.bizCard(\n    firstName: String? = null,\n    secondName: String? = null,\n    job: String? = null,\n    company: String? = null,\n    address: String? = null,\n    phone: String? = null,\n    email: String? = null,\n): String = buildString {\n    append(\"BIZCARD:\")\n    if (firstName != null)\n        append(\"N:$firstName;\")\n\n    if (secondName != null)\n        append(\"X:$secondName;\")\n\n    if (job != null)\n        append(\"T:$job;\")\n\n    if (company != null)\n        append(\"C:$company;\")\n\n    if (address != null)\n        append(\"A:$address;\")\n\n    if (phone != null)\n        append(\"B:$phone;\")\n\n    if (email != null)\n        append(\"E:$email;\")\n\n    append(\";\")\n}\n\nfun QrData.wifi(\n    authentication: String? = null,\n    ssid: String? = null,\n    psk: String? = null,\n    hidden: Boolean = false,\n): String = buildString {\n    append(\"WIFI:\")\n    if (ssid != null)\n        append(\"S:${escape(ssid)};\")\n\n    if (authentication != null)\n        append(\"T:${authentication};\")\n\n    if (psk != null)\n        append(\"P:${escape(psk)};\")\n\n    append(\"H:$hidden;\")\n}\n\nfun QrData.enterpriseWifi(\n    ssid: String? = null,\n    psk: String? = null,\n    hidden: Boolean = false,\n    user: String? = null,\n    eap: String? = null,\n    phase: String? = null,\n): String = buildString {\n    append(\"WIFI:\")\n    if (ssid != null)\n        append(\"S:${escape(ssid)};\")\n\n    if (user != null)\n        append(\"U:${escape(user)};\")\n\n    if (psk != null)\n        append(\"P:${escape(psk)};\")\n\n    if (eap != null)\n        append(\"E:${escape(eap)};\")\n\n    if (phase != null)\n        append(\"PH:${escape(phase)};\")\n\n    append(\"H:$hidden;\")\n}\n\n\nfun QrData.event(\n    uid: String? = null,\n    stamp: String? = null,\n    organizer: String? = null,\n    start: String? = null,\n    end: String? = null,\n    summary: String? = null,\n): String = buildString {\n    append(\"BEGIN:VEVENT\\n\")\n    if (uid != null)\n        append(\"UID:$uid\\n\")\n    if (stamp != null)\n        append(\"DTSTAMP:$stamp\\n\")\n    if (organizer != null)\n        append(\"ORGANIZER:$organizer\\n\")\n\n    if (start != null)\n        append(\"DTSTART:$start\\n\")\n\n    if (end != null)\n        append(\"DTEND:$end\\n\")\n    if (summary != null)\n        append(\"SUMMARY:$summary\\n\")\n\n    append(\"END:VEVENT\")\n}\n\nfun QrData.location(\n    lat: Float,\n    lon: Float\n): String = \"GEO:$lat,$lon\"\n\n\nprivate fun escape(text: String): String {\n    return text.replace(\"\\\\\", \"\\\\\\\\\")\n        .replace(\",\", \"\\\\,\")\n        .replace(\";\", \"\\\\;\")\n        .replace(\".\", \"\\\\.\")\n        .replace(\"\\\"\", \"\\\\\\\"\")\n        .replace(\"'\", \"\\\\'\")\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/BarcodeEncoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\n/**\n * Single dimension barcode encoder.\n * */\ninterface BarcodeEncoder {\n\n    /**\n     * Encodes string [contents] into barcode [BooleanArray] where 1 is a black bar and 0 is a white bar.\n     *\n     * Illegal contents can throw exceptions\n     * */\n    fun encode(contents: String): BooleanArray\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/BarcodePainter.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.painter.Painter\nimport io.github.alexzhirkevich.qrose.CachedPainter\n\n\ntypealias BarcodePathBuilder = (size: Size, code: BooleanArray) -> Path\n\n/**\n * Remember barcode painter\n *\n * @param data code contents. Invalid contents can throw an exception\n * @param type barcode type\n * @param brush code brush\n * @param onError called when input content is invalid\n * @param builder build code path using painter size and encoded boolean list\n *\n * @see BarcodePainter\n * */\n@Composable\n@Stable\nfun rememberBarcodePainter(\n    data: String,\n    type: BarcodeType,\n    brush: Brush = SolidColor(Color.Black),\n    onError: (Throwable) -> Painter = { throw it },\n    builder: BarcodePathBuilder = ::defaultBarcodeBuilder\n): Painter {\n\n    val updatedBuilder by rememberUpdatedState(builder)\n\n    return remember(data, brush) {\n        runCatching {\n            BarcodePainter(\n                data = data,\n                type = type,\n                brush = brush,\n                builder = { size, code ->\n                    updatedBuilder(size, code)\n                },\n            )\n        }.getOrElse(onError)\n    }\n}\n\n\n/**\n * Create barcode painter\n *\n * @param code encoded barcode data\n * @param brush code brush\n * @param builder build code path using painter size and encoded boolean list\n *\n * @see rememberBarcodePainter\n * */\n@Immutable\nclass BarcodePainter(\n    private val code: BooleanArray,\n    private val brush: Brush = SolidColor(Color.Black),\n    private val builder: BarcodePathBuilder = ::defaultBarcodeBuilder\n) : CachedPainter() {\n\n    /**\n     * Create barcode painter\n     *\n     * @param data code contents. Invalid contents can throw an exception\n     * @param type barcode type\n     * @param brush code brush\n     * @param builder build code path using painter size and encoded boolean list\n     *\n     * @see rememberBarcodePainter\n     * */\n    constructor(\n        data: String,\n        type: BarcodeType,\n        brush: Brush = SolidColor(Color.Black),\n        builder: BarcodePathBuilder = ::defaultBarcodeBuilder\n    ) : this(\n        code = type.encoder.encode(data),\n        brush = brush,\n        builder = builder\n    )\n\n    override fun DrawScope.onCache() {\n        drawPath(\n            path = builder(size, code),\n            brush = brush\n        )\n    }\n\n    override val intrinsicSize: Size = Size(\n        width = 6f * code.size,\n        height = 120f\n    )\n}\n\n@PublishedApi\n@Stable\ninternal fun defaultBarcodeBuilder(size: Size, data: BooleanArray): Path = Path().apply {\n\n    val width = size.width / data.size\n\n    data.forEachIndexed { i, b ->\n        if (b) {\n            addRect(\n                Rect(\n                    left = i * width,\n                    top = 0f,\n                    right = (i + 1) * width,\n                    bottom = size.height\n                )\n            )\n        }\n    }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/BarcodeType.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\nenum class BarcodeType(val encoder: BarcodeEncoder) {\n\n    Codabar(CodabarEncoder),\n    Code39(Code39Encoder),\n    Code93(Code93Encoder),\n    Code128(Code128Encoder),\n    EAN8(CodeEAN8Encoder),\n    EAN13(CodeEAN13Encoder),\n    ITF(CodeITFEncoder),\n    UPCA(CodeUPCAEncoder),\n    UPCE(CodeUPCEEncoder)\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/CodabarEncoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\ninternal object CodabarEncoder : BarcodeEncoder {\n\n    override fun encode(contents: String): BooleanArray {\n        var actualContents = contents\n        if (actualContents.length < 2) {\n            // Can't have a start/end guard, so tentatively add default guards\n            actualContents = DEFAULT_GUARD.toString() + actualContents + DEFAULT_GUARD\n        } else {\n            // Verify input and calculate decoded length.\n            val firstChar = actualContents[0].uppercaseChar()\n            val lastChar = actualContents[actualContents.length - 1].uppercaseChar()\n            val startsNormal: Boolean = firstChar in START_END_CHARS\n            val endsNormal: Boolean = lastChar in START_END_CHARS\n            val startsAlt: Boolean = firstChar in ALT_START_END_CHARS\n            val endsAlt: Boolean = lastChar in ALT_START_END_CHARS\n            if (startsNormal) {\n                if (!endsNormal) {\n                    throw IllegalArgumentException(\"Invalid start/end guards: $actualContents\")\n                }\n                // else already has valid start/end\n            } else if (startsAlt) {\n                if (!endsAlt) {\n                    throw IllegalArgumentException(\"Invalid start/end guards: $actualContents\")\n                }\n                // else already has valid start/end\n            } else {\n                // Doesn't start with a guard\n                if (endsNormal || endsAlt) {\n                    throw IllegalArgumentException(\"Invalid start/end guards: $actualContents\")\n                }\n                // else doesn't end with guard either, so add a default\n                actualContents = DEFAULT_GUARD.toString() + actualContents + DEFAULT_GUARD\n            }\n        }\n\n        // The start character and the end character are decoded to 10 length each.\n        var resultLength = 20\n        for (i in 1 until actualContents.length - 1) {\n            resultLength += if (actualContents[i].isDigit() || actualContents[i] == '-' || actualContents[i] == '$') {\n                9\n            } else if (actualContents[i] in CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED) {\n                10\n            } else {\n                throw IllegalArgumentException(\"Cannot encode : '\" + actualContents[i] + '\\'')\n            }\n        }\n        // A blank is placed between each character.\n        resultLength += actualContents.length - 1\n        val result = BooleanArray(resultLength)\n        var position = 0\n        for (index in actualContents.indices) {\n            var c = actualContents[index].uppercaseChar()\n            if (index == 0 || index == actualContents.length - 1) {\n                // The start/end chars are not in the CodaBarReader.ALPHABET.\n                when (c) {\n                    'T' -> c = 'A'\n                    'N' -> c = 'B'\n                    '*' -> c = 'C'\n                    'E' -> c = 'D'\n                }\n            }\n            var code = 0\n            for (i in ALPHABET.indices) {\n                // Found any, because I checked above.\n                if (c == ALPHABET[i]) {\n                    code = CHARACTER_ENCODINGS[i]\n                    break\n                }\n            }\n            var color = true\n            var counter = 0\n            var bit = 0\n            while (bit < 7) { // A character consists of 7 digit.\n                result[position] = color\n                position++\n                if (code shr 6 - bit and 1 == 0 || counter == 1) {\n                    color = !color // Flip the color.\n                    bit++\n                    counter = 0\n                } else {\n                    counter++\n                }\n            }\n            if (index < actualContents.length - 1) {\n                result[position] = false\n                position++\n            }\n        }\n        return result\n    }\n\n    private val START_END_CHARS = charArrayOf('A', 'B', 'C', 'D')\n    private val ALT_START_END_CHARS = charArrayOf('T', 'N', '*', 'E')\n    private val CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED = charArrayOf('/', ':', '+', '.')\n    private val DEFAULT_GUARD = START_END_CHARS[0]\n\n    private const val ALPHABET_STRING = \"0123456789-$:/.+ABCD\"\n    private val ALPHABET = ALPHABET_STRING.toCharArray()\n\n    /**\n     * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of\n     * each int correspond to the pattern of wide and narrow, with 1s representing \"wide\" and 0s representing narrow.\n     */\n    private val CHARACTER_ENCODINGS = intArrayOf(\n        0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048,  // 0-9\n        0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E\n    )\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/Code128Encoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\ninternal object Code128Encoder : BarcodeEncoder {\n    // Results of minimal lookahead for code C\n    private enum class CType {\n        UNCODABLE,\n        ONE_DIGIT,\n        TWO_DIGITS,\n        FNC_1\n    }\n\n    override fun encode(contents: String): BooleanArray {\n        return encode(\n            contents = contents,\n            compact = true,\n            codeSet = null\n        )\n    }\n\n    fun encode(\n        contents: String,\n        compact: Boolean = true,\n        codeSet: Code128Type? = null\n    ): BooleanArray {\n        val forcedCodeSet = check(contents, codeSet)\n\n        return if (compact) {\n            MinimalEncoder().encode(contents)\n        } else {\n            encodeFast(\n                contents,\n                forcedCodeSet\n            )\n        }\n    }\n\n    /**\n     * Encodes minimally using Divide-And-Conquer with Memoization\n     */\n    private class MinimalEncoder {\n        private enum class Charset {\n            A,\n            B,\n            C,\n            NONE\n        }\n\n        private enum class Latch {\n            A,\n            B,\n            C,\n            SHIFT,\n            NONE\n        }\n\n        private var memoizedCost: Array<IntArray>? = null\n        private var minPath: Array<Array<Latch?>>? = null\n\n        fun encode(contents: String): BooleanArray {\n            memoizedCost = Array(4) { IntArray(contents.length) }\n            minPath = Array(4) {\n                arrayOfNulls(\n                    contents.length\n                )\n            }\n            encode(contents, Charset.NONE, 0)\n            val patterns: MutableCollection<IntArray> = ArrayList<IntArray>()\n            val checkSum = intArrayOf(0)\n            val checkWeight = intArrayOf(1)\n            val length = contents.length\n            var charset = Charset.NONE\n            var i = 0\n            while (i < length) {\n                val latch = minPath!![charset.ordinal][i]\n                when (latch) {\n                    Latch.A -> {\n                        charset = Charset.A\n                        addPattern(\n                            patterns,\n                            if (i == 0) CODE_START_A else CODE_CODE_A,\n                            checkSum,\n                            checkWeight,\n                            i\n                        )\n                    }\n\n                    Latch.B -> {\n                        charset = Charset.B\n                        addPattern(\n                            patterns,\n                            if (i == 0) CODE_START_B else CODE_CODE_B,\n                            checkSum,\n                            checkWeight,\n                            i\n                        )\n                    }\n\n                    Latch.C -> {\n                        charset = Charset.C\n                        addPattern(\n                            patterns,\n                            if (i == 0) CODE_START_C else CODE_CODE_C,\n                            checkSum,\n                            checkWeight,\n                            i\n                        )\n                    }\n\n                    Latch.SHIFT -> addPattern(patterns, CODE_SHIFT, checkSum, checkWeight, i)\n                    else -> {}\n                }\n                if (charset == Charset.C) {\n                    if (contents[i] == ESCAPE_FNC_1) {\n                        addPattern(patterns, CODE_FNC_1, checkSum, checkWeight, i)\n                    } else {\n                        addPattern(\n                            patterns,\n                            contents.substring(i, i + 2).toInt(),\n                            checkSum,\n                            checkWeight,\n                            i\n                        )\n                        require(i + 1 < length) //the algorithm never leads to a single trailing digit in character set C\n\n                        if (i + 1 < length) {\n                            i++\n                        }\n                    }\n                } else { // charset A or B\n                    var patternIndex: Int\n                    patternIndex =\n                        when (contents[i]) {\n                            ESCAPE_FNC_1 -> CODE_FNC_1\n                            ESCAPE_FNC_2 -> CODE_FNC_2\n                            ESCAPE_FNC_3 -> CODE_FNC_3\n                            ESCAPE_FNC_4 -> if (charset == Charset.A && latch != Latch.SHIFT ||\n                                charset == Charset.B && latch == Latch.SHIFT\n                            ) {\n                                CODE_FNC_4_A\n                            } else {\n                                CODE_FNC_4_B\n                            }\n\n                            else -> contents[i].code - ' '.code\n                        }\n                    if ((charset == Charset.A && latch != Latch.SHIFT ||\n                                charset == Charset.B && latch == Latch.SHIFT) &&\n                        patternIndex < 0\n                    ) {\n                        patternIndex += '`'.code\n                    }\n                    addPattern(patterns, patternIndex, checkSum, checkWeight, i)\n                }\n                i++\n            }\n            memoizedCost = null\n            minPath = null\n            return produceResult(patterns, checkSum[0])\n        }\n\n        private fun canEncode(contents: CharSequence, charset: Charset, position: Int): Boolean {\n            val c = contents[position]\n            return when (charset) {\n                Charset.A -> c == ESCAPE_FNC_1 || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 || A.indexOf(\n                    c\n                ) >= 0\n\n                Charset.B -> c == ESCAPE_FNC_1 || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 || B.indexOf(\n                    c\n                ) >= 0\n\n                Charset.C -> c == ESCAPE_FNC_1 || position + 1 < contents.length &&\n                        isDigit(c) && isDigit(contents[position + 1])\n\n                else -> false\n            }\n        }\n\n        /**\n         * Encode the string starting at position position starting with the character set charset\n         */\n        private fun encode(contents: CharSequence, charset: Charset, position: Int): Int {\n            require(position < contents.length)\n            val mCost = memoizedCost!![charset.ordinal][position]\n            if (mCost > 0) {\n                return mCost\n            }\n            var minCost = Int.MAX_VALUE\n            var minLatch: Latch? = Latch.NONE\n            val atEnd = position + 1 >= contents.length\n            val sets = arrayOf(Charset.A, Charset.B)\n            for (i in 0..1) {\n                if (canEncode(contents, sets[i], position)) {\n                    var cost = 1\n                    var latch = Latch.NONE\n                    if (charset != sets[i]) {\n                        cost++\n                        latch = Latch.valueOf(\n                            sets[i].toString()\n                        )\n                    }\n                    if (!atEnd) {\n                        cost += encode(contents, sets[i], position + 1)\n                    }\n                    if (cost < minCost) {\n                        minCost = cost\n                        minLatch = latch\n                    }\n                    cost = 1\n                    if (charset == sets[(i + 1) % 2]) {\n                        cost++\n                        latch = Latch.SHIFT\n                        if (!atEnd) {\n                            cost += encode(contents, charset, position + 1)\n                        }\n                        if (cost < minCost) {\n                            minCost = cost\n                            minLatch = latch\n                        }\n                    }\n                }\n            }\n            if (canEncode(contents, Charset.C, position)) {\n                var cost = 1\n                var latch = Latch.NONE\n                if (charset != Charset.C) {\n                    cost++\n                    latch = Latch.C\n                }\n                val advance = if (contents[position] == ESCAPE_FNC_1) 1 else 2\n                if (position + advance < contents.length) {\n                    cost += encode(contents, Charset.C, position + advance)\n                }\n                if (cost < minCost) {\n                    minCost = cost\n                    minLatch = latch\n                }\n            }\n            if (minCost == Int.MAX_VALUE) {\n                throw IllegalArgumentException(\"Bad character in input: ASCII value=\" + contents[position].code)\n            }\n            memoizedCost!![charset.ordinal][position] = minCost\n            minPath!![charset.ordinal][position] = minLatch\n            return minCost\n        }\n\n        companion object {\n            const val A =\n                \" !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\\u0000\\u0001\\u0002\" +\n                        \"\\u0003\\u0004\\u0005\\u0006\\u0007\\u0008\\u0009\\n\\u000B\\u000C\\r\\u000E\\u000F\\u0010\\u0011\" +\n                        \"\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\" +\n                        \"\\u00FF\"\n            const val B =\n                \" !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqr\" +\n                        \"stuvwxyz{|}~\\u007F\\u00FF\"\n            private const val CODE_SHIFT = 98\n\n            private fun addPattern(\n                patterns: MutableCollection<IntArray>,\n                patternIndex: Int,\n                checkSum: IntArray,\n                checkWeight: IntArray,\n                position: Int,\n            ) {\n                patterns.add(CODE_PATTERNS.get(patternIndex))\n                if (position != 0) {\n                    checkWeight[0]++\n                }\n                checkSum[0] += patternIndex * checkWeight[0]\n            }\n\n            private fun isDigit(c: Char): Boolean {\n                return c in '0'..'9'\n            }\n        }\n    }\n\n\n    private const val CODE_START_A = 103\n    private const val CODE_START_B = 104\n    private const val CODE_START_C = 105\n    internal const val CODE_CODE_A = 101\n    internal const val CODE_CODE_B = 100\n    internal const val CODE_CODE_C = 99\n    private const val CODE_STOP = 106\n\n    // Dummy characters used to specify control characters in input\n    private const val ESCAPE_FNC_1 = '\\u00f1'\n    private const val ESCAPE_FNC_2 = '\\u00f2'\n    private const val ESCAPE_FNC_3 = '\\u00f3'\n    private const val ESCAPE_FNC_4 = '\\u00f4'\n    private const val CODE_FNC_1 = 102 // Code A, Code B, Code C\n    private const val CODE_FNC_2 = 97 // Code A, Code B\n    private const val CODE_FNC_3 = 96 // Code A, Code B\n    private const val CODE_FNC_4_A = 101 // Code A\n    private const val CODE_FNC_4_B = 100 // Code B\n\n    private fun check(contents: String, codeSet: Code128Type?): Int {\n\n        // Check content\n        val length = contents.length\n        for (i in 0 until length) {\n            val c = contents[i]\n            when (c) {\n                ESCAPE_FNC_1, ESCAPE_FNC_2, ESCAPE_FNC_3, ESCAPE_FNC_4 -> {}\n                else -> if (c.code > 127) {\n                    // no full Latin-1 character set available at the moment\n                    // shift and manual code change are not supported\n                    throw IllegalArgumentException(\"Bad character in input: ASCII value=\" + c.code)\n                }\n            }\n            when (codeSet) {\n                Code128Type.A ->           // allows no ascii above 95 (no lower caps, no special symbols)\n                    if (c.code in 96..127) {\n                        throw IllegalArgumentException(\"Bad character in input for forced code set A: ASCII value=\" + c.code)\n                    }\n\n                Code128Type.B ->           // allows no ascii below 32 (terminal symbols)\n                    if (c.code < 32) {\n                        throw IllegalArgumentException(\"Bad character in input for forced code set B: ASCII value=\" + c.code)\n                    }\n\n                Code128Type.C ->           // allows only numbers and no FNC 2/3/4\n                    if (c.code < 48 || c.code in 58..127 || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4) {\n                        throw IllegalArgumentException(\"Bad character in input for forced code set C: ASCII value=\" + c.code)\n                    }\n\n                else -> {}\n            }\n        }\n        return codeSet?.v ?: -1\n    }\n\n    private fun encodeFast(contents: String, forcedCodeSet: Int): BooleanArray {\n        val length = contents.length\n        val patterns: MutableCollection<IntArray> = ArrayList() // temporary storage for patterns\n        var checkSum = 0\n        var checkWeight = 1\n        var codeSet = 0 // selected code (CODE_CODE_B or CODE_CODE_C)\n        var position = 0 // position in contents\n        while (position < length) {\n            //Select code to use\n            var newCodeSet: Int\n            newCodeSet = if (forcedCodeSet == -1) {\n                chooseCode(contents, position, codeSet)\n            } else {\n                forcedCodeSet\n            }\n\n            //Get the pattern index\n            var patternIndex: Int\n            if (newCodeSet == codeSet) {\n                // Encode the current character\n                // First handle escapes\n                when (contents[position]) {\n                    ESCAPE_FNC_1 -> patternIndex = CODE_FNC_1\n                    ESCAPE_FNC_2 -> patternIndex = CODE_FNC_2\n                    ESCAPE_FNC_3 -> patternIndex = CODE_FNC_3\n                    ESCAPE_FNC_4 -> patternIndex = if (codeSet == CODE_CODE_A) {\n                        CODE_FNC_4_A\n                    } else {\n                        CODE_FNC_4_B\n                    }\n\n                    else -> when (codeSet) {\n                        CODE_CODE_A -> {\n                            patternIndex = contents[position].code - ' '.code\n                            if (patternIndex < 0) {\n                                // everything below a space character comes behind the underscore in the code patterns table\n                                patternIndex += '`'.code\n                            }\n                        }\n\n                        CODE_CODE_B -> patternIndex = contents[position].code - ' '.code\n                        else -> {\n                            // CODE_CODE_C\n                            if (position + 1 == length) {\n                                // this is the last character, but the encoding is C, which always encodes two characers\n                                throw IllegalArgumentException(\"Bad number of characters for digit only encoding.\")\n                            }\n                            patternIndex = contents.substring(position, position + 2).toInt()\n                            position++ // Also incremented below\n                        }\n                    }\n                }\n                position++\n            } else {\n                // Should we change the current code?\n                // Do we have a code set?\n                patternIndex = if (codeSet == 0) {\n                    // No, we don't have a code set\n                    when (newCodeSet) {\n                        CODE_CODE_A -> CODE_START_A\n                        CODE_CODE_B -> CODE_START_B\n                        else -> CODE_START_C\n                    }\n                } else {\n                    // Yes, we have a code set\n                    newCodeSet\n                }\n                codeSet = newCodeSet\n            }\n\n            // Get the pattern\n            patterns.add(CODE_PATTERNS[patternIndex])\n\n            // Compute checksum\n            checkSum += patternIndex * checkWeight\n            if (position != 0) {\n                checkWeight++\n            }\n        }\n        return produceResult(patterns, checkSum)\n    }\n\n    fun produceResult(patterns: MutableCollection<IntArray>, checkSum: Int): BooleanArray {\n        // Compute and append checksum\n        val checkSumMod = checkSum % 103\n        if (checkSumMod < 0) {\n            throw IllegalArgumentException(\"Unable to compute a valid input checksum\")\n        }\n        patterns.add(CODE_PATTERNS[checkSumMod])\n\n        // Append stop code\n        patterns.add(CODE_PATTERNS[CODE_STOP])\n\n        // Compute code width\n        var codeWidth = 0\n        for (pattern in patterns) {\n            for (width in pattern) {\n                codeWidth += width\n            }\n        }\n\n        // Compute result\n        val result = BooleanArray(codeWidth)\n        var pos = 0\n        for (pattern in patterns) {\n            pos += appendPattern(result, pos, pattern, true)\n        }\n        return result\n    }\n\n    private fun findCType(value: CharSequence, start: Int): CType {\n        val last = value.length\n        if (start >= last) {\n            return CType.UNCODABLE\n        }\n        var c = value[start]\n        if (c == ESCAPE_FNC_1) {\n            return CType.FNC_1\n        }\n        if (c < '0' || c > '9') {\n            return CType.UNCODABLE\n        }\n        if (start + 1 >= last) {\n            return CType.ONE_DIGIT\n        }\n        c = value[start + 1]\n        return if (c < '0' || c > '9') {\n            CType.ONE_DIGIT\n        } else CType.TWO_DIGITS\n    }\n\n    private fun chooseCode(value: CharSequence, start: Int, oldCode: Int): Int {\n        var lookahead = findCType(value, start)\n        if (lookahead == CType.ONE_DIGIT) {\n            return if (oldCode == CODE_CODE_A) {\n                CODE_CODE_A\n            } else CODE_CODE_B\n        }\n        if (lookahead == CType.UNCODABLE) {\n            if (start < value.length) {\n                val c = value[start]\n                if (c < ' ' || oldCode == CODE_CODE_A && (c < '`' || c >= ESCAPE_FNC_1 && c <= ESCAPE_FNC_4)) {\n                    // can continue in code A, encodes ASCII 0 to 95 or FNC1 to FNC4\n                    return CODE_CODE_A\n                }\n            }\n            return CODE_CODE_B // no choice\n        }\n        if (oldCode == CODE_CODE_A && lookahead == CType.FNC_1) {\n            return CODE_CODE_A\n        }\n        if (oldCode == CODE_CODE_C) { // can continue in code C\n            return CODE_CODE_C\n        }\n        if (oldCode == CODE_CODE_B) {\n            if (lookahead == CType.FNC_1) {\n                return CODE_CODE_B // can continue in code B\n            }\n            // Seen two consecutive digits, see what follows\n            lookahead = findCType(value, start + 2)\n            if (lookahead == CType.UNCODABLE || lookahead == CType.ONE_DIGIT) {\n                return CODE_CODE_B // not worth switching now\n            }\n            if (lookahead == CType.FNC_1) { // two digits, then FNC_1...\n                lookahead = findCType(value, start + 3)\n                return if (lookahead == CType.TWO_DIGITS) { // then two more digits, switch\n                    CODE_CODE_C\n                } else {\n                    CODE_CODE_B // otherwise not worth switching\n                }\n            }\n            // At this point, there are at least 4 consecutive digits.\n            // Look ahead to choose whether to switch now or on the next round.\n            var index = start + 4\n            while (findCType(value, index).also { lookahead = it } == CType.TWO_DIGITS) {\n                index += 2\n            }\n            return if (lookahead == CType.ONE_DIGIT) { // odd number of digits, switch later\n                CODE_CODE_B\n            } else CODE_CODE_C\n            // even number of digits, switch now\n        }\n        // Here oldCode == 0, which means we are choosing the initial code\n        if (lookahead == CType.FNC_1) { // ignore FNC_1\n            lookahead = findCType(value, start + 1)\n        }\n        return if (lookahead == CType.TWO_DIGITS) { // at least two digits, start in code C\n            CODE_CODE_C\n        } else CODE_CODE_B\n    }\n}\n\ninternal fun appendPattern(\n    target: BooleanArray,\n    pos: Int,\n    pattern: IntArray,\n    startColor: Boolean,\n): Int {\n    var pos = pos\n    var color = startColor\n    var numAdded = 0\n    for (len in pattern) {\n        for (j in 0 until len) {\n            target[pos++] = color\n        }\n        numAdded += len\n        color = !color // flip color after each segment\n    }\n    return numAdded\n}\n\nprivate val CODE_PATTERNS by lazy {\n    arrayOf(\n        intArrayOf(2, 1, 2, 2, 2, 2),\n        intArrayOf(2, 2, 2, 1, 2, 2),\n        intArrayOf(2, 2, 2, 2, 2, 1),\n        intArrayOf(1, 2, 1, 2, 2, 3),\n        intArrayOf(1, 2, 1, 3, 2, 2),\n        intArrayOf(1, 3, 1, 2, 2, 2),\n        intArrayOf(1, 2, 2, 2, 1, 3),\n        intArrayOf(1, 2, 2, 3, 1, 2),\n        intArrayOf(1, 3, 2, 2, 1, 2),\n        intArrayOf(2, 2, 1, 2, 1, 3),\n        intArrayOf(2, 2, 1, 3, 1, 2),\n        intArrayOf(2, 3, 1, 2, 1, 2),\n        intArrayOf(1, 1, 2, 2, 3, 2),\n        intArrayOf(1, 2, 2, 1, 3, 2),\n        intArrayOf(1, 2, 2, 2, 3, 1),\n        intArrayOf(1, 1, 3, 2, 2, 2),\n        intArrayOf(1, 2, 3, 1, 2, 2),\n        intArrayOf(1, 2, 3, 2, 2, 1),\n        intArrayOf(2, 2, 3, 2, 1, 1),\n        intArrayOf(2, 2, 1, 1, 3, 2),\n        intArrayOf(2, 2, 1, 2, 3, 1),\n        intArrayOf(2, 1, 3, 2, 1, 2),\n        intArrayOf(2, 2, 3, 1, 1, 2),\n        intArrayOf(3, 1, 2, 1, 3, 1),\n        intArrayOf(3, 1, 1, 2, 2, 2),\n        intArrayOf(3, 2, 1, 1, 2, 2),\n        intArrayOf(3, 2, 1, 2, 2, 1),\n        intArrayOf(3, 1, 2, 2, 1, 2),\n        intArrayOf(3, 2, 2, 1, 1, 2),\n        intArrayOf(3, 2, 2, 2, 1, 1),\n        intArrayOf(2, 1, 2, 1, 2, 3),\n        intArrayOf(2, 1, 2, 3, 2, 1),\n        intArrayOf(2, 3, 2, 1, 2, 1),\n        intArrayOf(1, 1, 1, 3, 2, 3),\n        intArrayOf(1, 3, 1, 1, 2, 3),\n        intArrayOf(1, 3, 1, 3, 2, 1),\n        intArrayOf(1, 1, 2, 3, 1, 3),\n        intArrayOf(1, 3, 2, 1, 1, 3),\n        intArrayOf(1, 3, 2, 3, 1, 1),\n        intArrayOf(2, 1, 1, 3, 1, 3),\n        intArrayOf(2, 3, 1, 1, 1, 3),\n        intArrayOf(2, 3, 1, 3, 1, 1),\n        intArrayOf(1, 1, 2, 1, 3, 3),\n        intArrayOf(1, 1, 2, 3, 3, 1),\n        intArrayOf(1, 3, 2, 1, 3, 1),\n        intArrayOf(1, 1, 3, 1, 2, 3),\n        intArrayOf(1, 1, 3, 3, 2, 1),\n        intArrayOf(1, 3, 3, 1, 2, 1),\n        intArrayOf(3, 1, 3, 1, 2, 1),\n        intArrayOf(2, 1, 1, 3, 3, 1),\n        intArrayOf(2, 3, 1, 1, 3, 1),\n        intArrayOf(2, 1, 3, 1, 1, 3),\n        intArrayOf(2, 1, 3, 3, 1, 1),\n        intArrayOf(2, 1, 3, 1, 3, 1),\n        intArrayOf(3, 1, 1, 1, 2, 3),\n        intArrayOf(3, 1, 1, 3, 2, 1),\n        intArrayOf(3, 3, 1, 1, 2, 1),\n        intArrayOf(3, 1, 2, 1, 1, 3),\n        intArrayOf(3, 1, 2, 3, 1, 1),\n        intArrayOf(3, 3, 2, 1, 1, 1),\n        intArrayOf(3, 1, 4, 1, 1, 1),\n        intArrayOf(2, 2, 1, 4, 1, 1),\n        intArrayOf(4, 3, 1, 1, 1, 1),\n        intArrayOf(1, 1, 1, 2, 2, 4),\n        intArrayOf(1, 1, 1, 4, 2, 2),\n        intArrayOf(1, 2, 1, 1, 2, 4),\n        intArrayOf(1, 2, 1, 4, 2, 1),\n        intArrayOf(1, 4, 1, 1, 2, 2),\n        intArrayOf(1, 4, 1, 2, 2, 1),\n        intArrayOf(1, 1, 2, 2, 1, 4),\n        intArrayOf(1, 1, 2, 4, 1, 2),\n        intArrayOf(1, 2, 2, 1, 1, 4),\n        intArrayOf(1, 2, 2, 4, 1, 1),\n        intArrayOf(1, 4, 2, 1, 1, 2),\n        intArrayOf(1, 4, 2, 2, 1, 1),\n        intArrayOf(2, 4, 1, 2, 1, 1),\n        intArrayOf(2, 2, 1, 1, 1, 4),\n        intArrayOf(4, 1, 3, 1, 1, 1),\n        intArrayOf(2, 4, 1, 1, 1, 2),\n        intArrayOf(1, 3, 4, 1, 1, 1),\n        intArrayOf(1, 1, 1, 2, 4, 2),\n        intArrayOf(1, 2, 1, 1, 4, 2),\n        intArrayOf(1, 2, 1, 2, 4, 1),\n        intArrayOf(1, 1, 4, 2, 1, 2),\n        intArrayOf(1, 2, 4, 1, 1, 2),\n        intArrayOf(1, 2, 4, 2, 1, 1),\n        intArrayOf(4, 1, 1, 2, 1, 2),\n        intArrayOf(4, 2, 1, 1, 1, 2),\n        intArrayOf(4, 2, 1, 2, 1, 1),\n        intArrayOf(2, 1, 2, 1, 4, 1),\n        intArrayOf(2, 1, 4, 1, 2, 1),\n        intArrayOf(4, 1, 2, 1, 2, 1),\n        intArrayOf(1, 1, 1, 1, 4, 3),\n        intArrayOf(1, 1, 1, 3, 4, 1),\n        intArrayOf(1, 3, 1, 1, 4, 1),\n        intArrayOf(1, 1, 4, 1, 1, 3),\n        intArrayOf(1, 1, 4, 3, 1, 1),\n        intArrayOf(4, 1, 1, 1, 1, 3),\n        intArrayOf(4, 1, 1, 3, 1, 1),\n        intArrayOf(1, 1, 3, 1, 4, 1),\n        intArrayOf(1, 1, 4, 1, 3, 1),\n        intArrayOf(3, 1, 1, 1, 4, 1),\n        intArrayOf(4, 1, 1, 1, 3, 1),\n        intArrayOf(2, 1, 1, 4, 1, 2),\n        intArrayOf(2, 1, 1, 2, 1, 4),\n        intArrayOf(2, 1, 1, 2, 3, 2),\n        intArrayOf(2, 3, 3, 1, 1, 1, 2)\n    )\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/Code128Painter.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.painter.Painter\n\n\n/**\n * Code 128 barcode painter\n *\n * @param brush code brush\n * @param compact Specifies whether to use compact mode for Code-128 code.\n * This can yield slightly smaller bar codes. This option and [forceCodeSet] are mutually exclusive.\n * @param forceCodeSet Forces which encoding will be used. This option and [compact] are mutually exclusive.\n * @param onError called when input content is invalid.\n * @param builder build code path using painter size and encoded boolean list.\n *\n * @see Code128Painter\n * */\n@Composable\ninternal fun rememberCode128Painter(\n    data: String,\n    brush: Brush = SolidColor(Color.Black),\n    compact: Boolean = true,\n    forceCodeSet: Code128Type? = null,\n    onError: (Throwable) -> Painter = { throw it },\n    builder: BarcodePathBuilder = ::defaultBarcodeBuilder\n): Painter {\n\n    val updatedBuilder by rememberUpdatedState(builder)\n\n    return remember(data, brush, forceCodeSet) {\n        runCatching {\n            Code128Painter(\n                data = data,\n                brush = brush,\n                compact = compact,\n                codeSet = forceCodeSet,\n                builder = { size, code ->\n                    updatedBuilder(size, code)\n                },\n            )\n        }.getOrElse(onError)\n    }\n}\n\nenum class Code128Type(internal val v: Int) {\n    A(Code128Encoder.CODE_CODE_A),\n    B(Code128Encoder.CODE_CODE_B),\n    C(Code128Encoder.CODE_CODE_C)\n}\n\n@Stable\nfun Code128Painter(\n    data: String,\n    brush: Brush = SolidColor(Color.Black),\n    compact: Boolean = true,\n    codeSet: Code128Type? = null,\n    builder: BarcodePathBuilder = ::defaultBarcodeBuilder\n) = BarcodePainter(\n    code = Code128Encoder.encode(data, compact, codeSet),\n    brush = brush,\n    builder = builder\n)\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/Code39Encoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\ninternal object Code39Encoder : BarcodeEncoder {\n\n    override fun encode(contents: String): BooleanArray {\n        var actualContent = contents\n        var length = actualContent.length\n        if (length > 80) {\n            throw IllegalArgumentException(\n                \"Requested contents should be less than 80 digits long, but got $length\"\n            )\n        }\n        for (i in 0 until length) {\n            val indexInString: Int = ALPHABET_STRING.indexOf(actualContent[i])\n            if (indexInString < 0) {\n                actualContent = tryToConvertToExtendedMode(actualContent)\n                length = actualContent.length\n                if (length > 80) {\n                    throw IllegalArgumentException(\n                        \"Requested contents should be less than 80 digits long, but got \" +\n                                length + \" (extended full ASCII mode)\"\n                    )\n                }\n                break\n            }\n        }\n        val widths = IntArray(9)\n        val codeWidth = 24 + 1 + (13 * length)\n        val result = BooleanArray(codeWidth)\n        toIntArray(ASTERISK_ENCODING, widths)\n        var pos = appendPattern(result, 0, widths, true)\n        val narrowWhite = intArrayOf(1)\n        pos += appendPattern(result, pos, narrowWhite, false)\n        //append next character to byte matrix\n        for (i in 0 until length) {\n            val indexInString: Int = ALPHABET_STRING.indexOf(actualContent[i])\n            toIntArray(CHARACTER_ENCODINGS[indexInString], widths)\n            pos += appendPattern(result, pos, widths, true)\n            pos += appendPattern(result, pos, narrowWhite, false)\n        }\n        toIntArray(ASTERISK_ENCODING, widths)\n        appendPattern(result, pos, widths, true)\n        return result\n    }\n\n\n    const val ALPHABET_STRING = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. \\$/+%\"\n\n    val CHARACTER_ENCODINGS by lazy {\n        intArrayOf(\n            0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9\n            // 0-9\n            0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J\n            // A-J\n            0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T\n            // K-T\n            0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x0A8, // U-$\n            // U-$\n            0x0A2, 0x08A, 0x02A // /-%\n            // /-%\n        )\n    }\n\n    val ASTERISK_ENCODING = 0x094\n\n    private fun toIntArray(a: Int, toReturn: IntArray) {\n        for (i in 0..8) {\n            val temp = a and (1 shl (8 - i))\n            toReturn[i] = if (temp == 0) 1 else 2\n        }\n    }\n\n    private fun tryToConvertToExtendedMode(contents: String): String {\n        val length = contents.length\n        val extendedContent = StringBuilder()\n        for (i in 0 until length) {\n            val character = contents[i]\n            when (character) {\n                '\\u0000' -> extendedContent.append(\"%U\")\n                ' ', '-', '.' -> extendedContent.append(character)\n                '@' -> extendedContent.append(\"%V\")\n                '`' -> extendedContent.append(\"%W\")\n                else -> if (character.code <= 26) {\n                    extendedContent.append('$')\n                    extendedContent.append(('A'.code + (character.code - 1)).toChar())\n                } else if (character < ' ') {\n                    extendedContent.append('%')\n                    extendedContent.append(('A'.code + (character.code - 27)).toChar())\n                } else if ((character <= ',') || (character == '/') || (character == ':')) {\n                    extendedContent.append('/')\n                    extendedContent.append(('A'.code + (character.code - 33)).toChar())\n                } else if (character <= '9') {\n                    extendedContent.append(('0'.code + (character.code - 48)).toChar())\n                } else if (character <= '?') {\n                    extendedContent.append('%')\n                    extendedContent.append(('F'.code + (character.code - 59)).toChar())\n                } else if (character <= 'Z') {\n                    extendedContent.append(('A'.code + (character.code - 65)).toChar())\n                } else if (character <= '_') {\n                    extendedContent.append('%')\n                    extendedContent.append(('K'.code + (character.code - 91)).toChar())\n                } else if (character <= 'z') {\n                    extendedContent.append('+')\n                    extendedContent.append(('A'.code + (character.code - 97)).toChar())\n                } else if (character.code <= 127) {\n                    extendedContent.append('%')\n                    extendedContent.append(('P'.code + (character.code - 123)).toChar())\n                } else {\n                    throw IllegalArgumentException(\n                        \"Requested content contains a non-encodable character: '\" + contents[i] + \"'\"\n                    )\n                }\n            }\n        }\n        return extendedContent.toString()\n    }\n}\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/Code93Encoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\n\ninternal object Code93Encoder : BarcodeEncoder {\n\n    override fun encode(contents: String): BooleanArray {\n        var actualContents = contents\n        var length = actualContents.length\n        if (length > 80) {\n            throw IllegalArgumentException(\n                \"Requested contents should be less than 80 digits long, but got $length\"\n            )\n        }\n        for (i in 0 until length) {\n            val indexInString: Int = Code39Encoder.ALPHABET_STRING.indexOf(actualContents[i])\n            if (indexInString < 0) {\n                actualContents = tryToConvertToExtendedMode(actualContents)\n                length = actualContents.length\n                if (length > 80) {\n                    throw IllegalArgumentException(\n                        \"Requested contents should be less than 80 digits long, but got \" +\n                                length + \" (extended full ASCII mode)\"\n                    )\n                }\n                break\n            }\n        }\n        val widths = IntArray(9)\n        val codeWidth = 24 + 1 + (13 * length)\n        val result = BooleanArray(codeWidth)\n        toIntArray(Code39Encoder.ASTERISK_ENCODING, widths)\n        var pos = appendPattern(result, 0, widths, true)\n        val narrowWhite = intArrayOf(1)\n        pos += appendPattern(result, pos, narrowWhite, false)\n        //append next character to byte matrix\n        for (i in 0 until length) {\n            val indexInString: Int = Code39Encoder.ALPHABET_STRING.indexOf(actualContents[i])\n            toIntArray(Code39Encoder.CHARACTER_ENCODINGS.get(indexInString), widths)\n            pos += appendPattern(result, pos, widths, true)\n            pos += appendPattern(result, pos, narrowWhite, false)\n        }\n        toIntArray(Code39Encoder.ASTERISK_ENCODING, widths)\n        appendPattern(result, pos, widths, true)\n        return result\n    }\n\n    private fun toIntArray(a: Int, toReturn: IntArray) {\n        for (i in 0..8) {\n            val temp = a and (1 shl (8 - i))\n            toReturn[i] = if (temp == 0) 1 else 2\n        }\n    }\n\n    private fun tryToConvertToExtendedMode(contents: String): String {\n        val length = contents.length\n        val extendedContent: StringBuilder = StringBuilder()\n        for (i in 0 until length) {\n            val character = contents[i]\n            when (character) {\n                '\\u0000' -> extendedContent.append(\"%U\")\n                ' ', '-', '.' -> extendedContent.append(character)\n                '@' -> extendedContent.append(\"%V\")\n                '`' -> extendedContent.append(\"%W\")\n                else -> if (character.code <= 26) {\n                    extendedContent.append('$')\n                    extendedContent.append(('A'.code + (character.code - 1)).toChar())\n                } else if (character < ' ') {\n                    extendedContent.append('%')\n                    extendedContent.append(('A'.code + (character.code - 27)).toChar())\n                } else if ((character <= ',') || (character == '/') || (character == ':')) {\n                    extendedContent.append('/')\n                    extendedContent.append(('A'.code + (character.code - 33)).toChar())\n                } else if (character <= '9') {\n                    extendedContent.append(('0'.code + (character.code - 48)).toChar())\n                } else if (character <= '?') {\n                    extendedContent.append('%')\n                    extendedContent.append(('F'.code + (character.code - 59)).toChar())\n                } else if (character <= 'Z') {\n                    extendedContent.append(('A'.code + (character.code - 65)).toChar())\n                } else if (character <= '_') {\n                    extendedContent.append('%')\n                    extendedContent.append(('K'.code + (character.code - 91)).toChar())\n                } else if (character <= 'z') {\n                    extendedContent.append('+')\n                    extendedContent.append(('A'.code + (character.code - 97)).toChar())\n                } else if (character.code <= 127) {\n                    extendedContent.append('%')\n                    extendedContent.append(('P'.code + (character.code - 123)).toChar())\n                } else {\n                    throw IllegalArgumentException(\n                        \"Requested content contains a non-encodable character: '\" + contents[i] + \"'\"\n                    )\n                }\n            }\n        }\n        return extendedContent.toString()\n    }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/CodeEAN13Encoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\n\ninternal object CodeEAN13Encoder : BarcodeEncoder {\n\n    private val CODE_WIDTH = 3 + 7 * 6 +  // left bars\n            5 + 7 * 6 +  // right bars\n            3 // end guard\n\n\n    override fun encode(contents: String): BooleanArray {\n        var actualContents = contents\n        val length = actualContents.length\n        when (length) {\n            12 -> {\n                actualContents += getStandardUPCEANChecksum(actualContents)\n            }\n\n            13 -> if (!checkStandardUPCEANChecksum(actualContents)) {\n                throw IllegalArgumentException(\"Contents do not pass checksum\")\n            }\n\n            else -> throw IllegalArgumentException(\n                \"Requested contents should be 12 or 13 digits long, but got $length\"\n            )\n        }\n        actualContents.requireNumeric()\n        val firstDigit = actualContents[0].digitToIntOrNull() ?: -1\n        val parities: Int = UpcEan.FIRST_DIGIT_ENCODINGS[firstDigit]\n        val result = BooleanArray(CODE_WIDTH)\n        var pos = 0\n        pos += appendPattern(result, pos, UpcEan.START_END_PATTERN, true)\n\n        // See EAN13Reader for a description of how the first digit & left bars are encoded\n        for (i in 1..6) {\n            var digit = actualContents[i].digitToIntOrNull() ?: -1\n            if (parities shr 6 - i and 1 == 1) {\n                digit += 10\n            }\n            pos += appendPattern(\n                result,\n                pos,\n                UpcEan.L_AND_G_PATTERNS.get(digit),\n                false\n            )\n        }\n        pos += appendPattern(result, pos, UpcEan.MIDDLE_PATTERN, false)\n        for (i in 7..12) {\n            val digit = actualContents[i].digitToIntOrNull() ?: -1\n            pos += appendPattern(result, pos, UpcEan.L_PATTERNS[digit], true)\n        }\n        appendPattern(result, pos, UpcEan.START_END_PATTERN, true)\n        return result\n    }\n\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/CodeEAN8Encoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\ninternal object CodeEAN8Encoder : BarcodeEncoder {\n    private val CODE_WIDTH = 3 + 7 * 4 +  // left bars\n            5 + 7 * 4 +  // right bars\n            3 // end guard\n\n\n    override fun encode(contents: String): BooleanArray {\n        var actualContentns = contents\n        val length = actualContentns.length\n        when (length) {\n            7 -> {\n                // No check digit present, calculate it and add it\n                val check: Int = getStandardUPCEANChecksum(actualContentns)\n                actualContentns += check\n            }\n\n            8 -> if (!checkStandardUPCEANChecksum(actualContentns)) {\n                throw IllegalArgumentException(\"Contents do not pass checksum\")\n            }\n\n            else -> throw IllegalArgumentException(\n                \"Requested contents should be 7 or 8 digits long, but got $length\"\n            )\n        }\n        actualContentns.requireNumeric()\n        val result = BooleanArray(CODE_WIDTH)\n        var pos = 0\n        pos += appendPattern(result, pos, UpcEan.START_END_PATTERN, true)\n        for (i in 0..3) {\n            val digit = actualContentns[i].digitToIntOrNull() ?: -1\n            pos += appendPattern(\n                result,\n                pos,\n                UpcEan.L_PATTERNS[digit],\n                false\n            )\n        }\n        pos += appendPattern(\n            result,\n            pos,\n            UpcEan.MIDDLE_PATTERN,\n            false\n        )\n        for (i in 4..7) {\n            val digit = actualContentns[i].digitToIntOrNull() ?: -1\n            pos += appendPattern(result, pos, UpcEan.L_PATTERNS[digit], true)\n        }\n        appendPattern(result, pos, UpcEan.START_END_PATTERN, true)\n        return result\n    }\n\n}\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/CodeITFEncoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\n\ninternal object CodeITFEncoder : BarcodeEncoder {\n\n    override fun encode(contents: String): BooleanArray {\n        val length = contents.length\n        if (length % 2 != 0) {\n            throw IllegalArgumentException(\"The length of the input should be even\")\n        }\n        if (length > 80) {\n            throw IllegalArgumentException(\n                \"Requested contents should be less than 80 digits long, but got $length\"\n            )\n        }\n        contents.requireNumeric()\n        val result = BooleanArray(9 + 9 * length)\n        var pos = appendPattern(result, 0, START_PATTERN, true)\n        var i = 0\n        while (i < length) {\n            val one = contents[i].digitToIntOrNull() ?: -1\n            val two = contents[i + 1].digitToIntOrNull() ?: -1\n            val encoding = IntArray(10)\n            for (j in 0..4) {\n                encoding[2 * j] = PATTERNS[one][j]\n                encoding[2 * j + 1] = PATTERNS[two][j]\n            }\n            pos += appendPattern(result, pos, encoding, true)\n            i += 2\n        }\n        appendPattern(result, pos, END_PATTERN, true)\n        return result\n    }\n\n    private val START_PATTERN = intArrayOf(1, 1, 1, 1)\n    private val END_PATTERN = intArrayOf(3, 1, 1)\n    private const val W = 3 // Pixel width of a 3x wide line\n    private const val N = 1 // Pixed width of a narrow line\n\n    // See ITFReader.PATTERNS\n    private val PATTERNS = arrayOf(\n        intArrayOf(N, N, W, W, N),\n        intArrayOf(W, N, N, N, W),\n        intArrayOf(\n            N, W, N, N, W\n        ),\n        intArrayOf(W, W, N, N, N),\n        intArrayOf(N, N, W, N, W),\n        intArrayOf(W, N, W, N, N),\n        intArrayOf(\n            N, W, W, N, N\n        ),\n        intArrayOf(N, N, N, W, W),\n        intArrayOf(W, N, N, W, N),\n        intArrayOf(N, W, N, W, N)\n    )\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/CodeUPCAEncoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\ninternal object CodeUPCAEncoder : BarcodeEncoder {\n    override fun encode(contents: String) = CodeEAN13Encoder.encode(\"0$contents\")\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/CodeUPCEEncoder.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\n\ninternal object CodeUPCEEncoder : BarcodeEncoder {\n\n    private const val CODE_WIDTH = 3 + 7 * 6 +  // bars\n            6 // end guard\n\n    override fun encode(contents: String): BooleanArray {\n        var contents = contents\n        val length = contents.length\n        when (length) {\n            7 -> {\n                // No check digit present, calculate it and add it\n                val check: Int = getStandardUPCEANChecksum(convertUPCEtoUPCA(contents))\n                contents += check\n            }\n\n            8 -> if (!checkStandardUPCEANChecksum(convertUPCEtoUPCA(contents))) {\n                throw IllegalArgumentException(\"Contents do not pass checksum\")\n            }\n\n            else -> throw IllegalArgumentException(\n                \"Requested contents should be 7 or 8 digits long, but got $length\"\n            )\n        }\n        contents.requireNumeric()\n        val firstDigit = contents[0].digitToIntOrNull() ?: -1\n        if (firstDigit != 0 && firstDigit != 1) {\n            throw IllegalArgumentException(\"Number system must be 0 or 1\")\n        }\n        val checkDigit = contents[7].digitToIntOrNull() ?: -1\n        val parities: Int =\n            UpcEan.NUMSYS_AND_CHECK_DIGIT_PATTERNS.get(firstDigit).get(checkDigit)\n        val result = BooleanArray(CODE_WIDTH)\n        var pos = appendPattern(result, 0, UpcEan.START_END_PATTERN, true)\n        for (i in 1..6) {\n            var digit = contents[i].digitToIntOrNull() ?: -1\n            if (parities shr 6 - i and 1 == 1) {\n                digit += 10\n            }\n            pos += appendPattern(result, pos, UpcEan.L_AND_G_PATTERNS.get(digit), false)\n        }\n        appendPattern(result, pos, UpcEan.END_PATTERN, false)\n        return result\n    }\n\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/oned/UpcEanUtils.kt",
    "content": "package io.github.alexzhirkevich.qrose.oned\n\ninternal object UpcEan {\n\n    val NUMSYS_AND_CHECK_DIGIT_PATTERNS = arrayOf(\n        intArrayOf(0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25),\n        intArrayOf(0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A)\n    )\n\n    /**\n     * Start/end guard pattern.\n     */\n    val START_END_PATTERN by lazy {\n        intArrayOf(1, 1, 1)\n    }\n\n    /**\n     * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.\n     */\n    val MIDDLE_PATTERN by lazy {\n        intArrayOf(1, 1, 1, 1, 1)\n    }\n\n    /**\n     * end guard pattern.\n     */\n    val END_PATTERN by lazy {\n        intArrayOf(1, 1, 1, 1, 1, 1)\n    }\n\n    /**\n     * \"Odd\", or \"L\" patterns used to encode UPC/EAN digits.\n     */\n    val L_PATTERNS by lazy {\n        arrayOf(\n            intArrayOf(3, 2, 1, 1),\n            intArrayOf(2, 2, 2, 1),\n            intArrayOf(2, 1, 2, 2),\n            intArrayOf(1, 4, 1, 1),\n            intArrayOf(1, 1, 3, 2),\n            intArrayOf(1, 2, 3, 1),\n            intArrayOf(1, 1, 1, 4),\n            intArrayOf(1, 3, 1, 2),\n            intArrayOf(1, 2, 1, 3),\n            intArrayOf(3, 1, 1, 2)\n        )\n    }\n\n    val L_AND_G_PATTERNS by lazy {\n        buildList(20) {\n            addAll(L_PATTERNS)\n\n            for (i in 10..19) {\n                val widths: IntArray = L_PATTERNS[i - 10]\n                val reversedWidths = IntArray(widths.size)\n                for (j in widths.indices) {\n                    reversedWidths[j] = widths[widths.size - j - 1]\n                }\n                add(reversedWidths)\n            }\n        }\n    }\n\n    val FIRST_DIGIT_ENCODINGS by lazy {\n        intArrayOf(\n            0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A\n        )\n    }\n}\n\ninternal fun String.requireNumeric() = require(all { it.isDigit() }) {\n    \"Input should only contain digits 0-9\"\n}\n\ninternal fun convertUPCEtoUPCA(upce: String): String {\n    val upceChars = upce.toCharArray(1, 7)\n    val result = StringBuilder(12)\n    result.append(upce[0])\n    val lastChar = upceChars[5]\n    when (lastChar) {\n        '0', '1', '2' -> {\n            result.appendRange(upceChars, 0, 0 + 2)\n            result.append(lastChar)\n            result.append(\"0000\")\n            result.appendRange(upceChars, 2, 3)\n        }\n\n        '3' -> {\n            result.appendRange(upceChars, 0, 3)\n            result.append(\"00000\")\n            result.appendRange(upceChars, 3, 2)\n        }\n\n        '4' -> {\n            result.appendRange(upceChars, 0, 4)\n            result.append(\"00000\")\n            result.append(upceChars[4])\n        }\n\n        else -> {\n            result.appendRange(upceChars, 0, 5)\n            result.append(\"0000\")\n            result.append(lastChar)\n        }\n    }\n    // Only append check digit in conversion if supplied\n    if (upce.length >= 8) {\n        result.append(upce[7])\n    }\n    return result.toString()\n}\n\ninternal fun checkStandardUPCEANChecksum(s: CharSequence): Boolean {\n    val length = s.length\n    if (length == 0) {\n        return false\n    }\n    val check = s[length - 1].digitToIntOrNull() ?: -1\n    return getStandardUPCEANChecksum(s.subSequence(0, length - 1)) == check\n}\n\ninternal fun getStandardUPCEANChecksum(s: CharSequence): Int {\n    val length = s.length\n    var sum = 0\n    run {\n        var i = length - 1\n        while (i >= 0) {\n            val digit = s[i].code - '0'.code\n            if (digit < 0 || digit > 9) {\n                throw IllegalStateException(\"Illegal contents\")\n            }\n            sum += digit\n            i -= 2\n        }\n    }\n    sum *= 3\n    var i = length - 2\n    while (i >= 0) {\n        val digit = s[i].code - '0'.code\n        if (digit < 0 || digit > 9) {\n            throw IllegalStateException(\"Illegal contents\")\n        }\n        sum += digit\n        i -= 2\n    }\n    return (1000 - sum) % 10\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/Neighbors.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\n\n\n/**\n * Status of the neighbor QR code pixels or eyes\n * */\n\n@Immutable\nclass Neighbors(\n    val topLeft: Boolean = false,\n    val topRight: Boolean = false,\n    val left: Boolean = false,\n    val top: Boolean = false,\n    val right: Boolean = false,\n    val bottomLeft: Boolean = false,\n    val bottom: Boolean = false,\n    val bottomRight: Boolean = false,\n) {\n\n    companion object {\n        val Empty = Neighbors()\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || this::class != other::class) return false\n\n        other as Neighbors\n\n        if (topLeft != other.topLeft) return false\n        if (topRight != other.topRight) return false\n        if (left != other.left) return false\n        if (top != other.top) return false\n        if (right != other.right) return false\n        if (bottomLeft != other.bottomLeft) return false\n        if (bottom != other.bottom) return false\n        if (bottomRight != other.bottomRight) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = topLeft.hashCode()\n        result = 31 * result + topRight.hashCode()\n        result = 31 * result + left.hashCode()\n        result = 31 * result + top.hashCode()\n        result = 31 * result + right.hashCode()\n        result = 31 * result + bottomLeft.hashCode()\n        result = 31 * result + bottom.hashCode()\n        result = 31 * result + bottomRight.hashCode()\n        return result\n    }\n}\n\nval Neighbors.hasAny: Boolean\n    get() = topLeft || topRight || left || top ||\n            right || bottomLeft || bottom || bottomRight\n\nval Neighbors.hasAllNearest\n    get() = top && bottom && left && right\n\nval Neighbors.hasAll: Boolean\n    get() = topLeft && topRight && left && top &&\n            right && bottomLeft && bottom && bottomRight\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrBallShape.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Path\n\n/**\n * Style of the qr-code eye internal ball.\n * */\ninterface QrBallShape : QrShapeModifier {\n\n    companion object {\n        val Default: QrBallShape = square()\n    }\n}\n\nfun QrBallShape.Companion.square(size: Float = 1f): QrBallShape =\n    object : QrBallShape, QrShapeModifier by SquareShape(size) {}\n\nfun QrBallShape.Companion.circle(size: Float = 1f): QrBallShape =\n    object : QrBallShape, QrShapeModifier by CircleShape(size) {}\n\nfun QrBallShape.Companion.roundCorners(\n    radius: Float,\n    topLeft: Boolean = true,\n    bottomLeft: Boolean = true,\n    topRight: Boolean = true,\n    bottomRight: Boolean = true,\n): QrBallShape = object : QrBallShape, QrShapeModifier by RoundCornersShape(\n    cornerRadius = radius,\n    topLeft = topLeft,\n    bottomLeft = bottomLeft,\n    topRight = topRight,\n    bottomRight = bottomRight,\n    withNeighbors = false\n) {}\n\nfun QrBallShape.Companion.asPixel(pixelShape: QrPixelShape): QrBallShape =\n    AsPixelBallShape(pixelShape)\n\n\n@Immutable\nprivate class AsPixelBallShape(\n    private val pixelShape: QrPixelShape\n) : QrBallShape {\n\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n\n        val matrix = QrCodeMatrix(3, QrCodeMatrix.PixelType.DarkPixel)\n\n        repeat(3) { i ->\n            repeat(3) { j ->\n                addPath(\n                    pixelShape.newPath(\n                        size / 3,\n                        matrix.neighbors(i, j)\n                    ),\n                    Offset(size / 3 * i, size / 3 * j)\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrBrush.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.ImageShader\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.ShaderBrush\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.TileMode\nimport androidx.compose.ui.graphics.isUnspecified\nimport androidx.compose.ui.graphics.painter.Painter\nimport io.github.alexzhirkevich.qrose.options.QrBrushMode.Separate\nimport io.github.alexzhirkevich.qrose.toImageBitmap\nimport kotlin.random.Random\n\nenum class QrBrushMode {\n\n    /**\n     * If applied to QR code pattern, the whole pattern will be combined to the single [Path]\n     * and then painted using produced [Brush] with large size and [Neighbors.Empty].\n     *\n     * Balls and frames with [QrBrush.Unspecified] will also be joined with this path.\n     * If balls or frames have specified [QrBrush] then [Neighbors] parameter will be passed\n     * according to eye position\n     * */\n    Join,\n\n    /**\n     * If applied to QR code pattern, each QR code pixel will be painted separately and for each\n     * pixel new [Brush] will be created. In this scenario [Neighbors] parameter for pixels will\n     * be chosen according to the actual pixel neighbors.\n     *\n     * Balls and frames with [QrBrush.Unspecified] will be painted with [QrBrush.Default].\n     * */\n    Separate\n}\n\n/**\n * Color [Brush] factory for a QR code part.\n * */\ninterface QrBrush {\n\n    /**\n     * Brush [mode] indicates the way this brush is applied to the QR code part.\n     * */\n    val mode: QrBrushMode\n\n    /**\n     * Factory method of the [Brush] for the element with given [size] and [neighbors].\n     * */\n    fun brush(size: Float, neighbors: Neighbors): Brush\n\n    companion object {\n\n        /**\n         * Delegates painting to other most suitable brush\n         * */\n        val Unspecified: QrBrush = solid(Color.Unspecified)\n\n        /**\n         * Default solid black brush\n         * */\n        val Default: QrBrush = solid(Color.Black)\n    }\n}\n\n\n/**\n * Check if this brush is not specified\n * */\nval QrBrush.isUnspecified\n    get() = this === QrBrush.Unspecified || this is Solid && this.color.isUnspecified\n\n/**\n * Check if this brush is specified\n * */\nval QrBrush.isSpecified: Boolean\n    get() = !isUnspecified\n\n/**\n * [SolidColor] brush from [color]\n * */\nfun QrBrush.Companion.solid(color: Color): QrBrush = Solid(color)\n\n/**\n * Any Compose brush constructed in [builder] with specific QR code part size.\n * This can be gradient brushes like, shader brush or any other.\n *\n * Example:\n * ```\n * QrBrush.brush {\n *     Brush.linearGradient(\n *         0f to Color.Red,\n *         1f to Color.Blue,\n *         end = Offset(it,it)\n *     )\n * }\n * ```\n * */\nfun QrBrush.Companion.brush(\n    builder: (size: Float) -> Brush\n): QrBrush = BrushColor(builder)\n\n/**\n * Random solid color picked from given [probabilities].\n * Custom source of [random]ness can be used.\n *\n * Note: This brush uses [Separate] brush mode.\n *\n * Example:\n * ```\n *  QrBrush.random(\n *      0.05f to Color.Red,\n *      1f to Color.Black\n *  )\n * ```\n * */\nfun QrBrush.Companion.random(\n    vararg probabilities: Pair<Float, Color>,\n    random: Random = Random(13)\n): QrBrush = Random(probabilities.toList(), random)\n\n/**\n * Shader brush that resizes the image [painter] to the required size.\n * [painter] resolution should be square for better result.\n * */\nfun QrBrush.Companion.image(\n    painter: Painter,\n    alpha: Float = 1f,\n    colorFilter: ColorFilter? = null\n): QrBrush = Image(painter, alpha, colorFilter)\n\n\n@Immutable\nprivate class Image(\n    private val painter: Painter,\n    private val alpha: Float = 1f,\n    private val colorFilter: ColorFilter? = null\n) : QrBrush {\n\n    override val mode: QrBrushMode\n        get() = QrBrushMode.Join\n\n    private var cachedBrush: Brush? = null\n    private var cachedSize: Int = -1\n\n    override fun brush(size: Float, neighbors: Neighbors): Brush {\n\n        val intSize = size.toInt()\n\n        if (cachedBrush != null && cachedSize == intSize) {\n            return cachedBrush!!\n        }\n\n        val bmp = painter.toImageBitmap(intSize, intSize, alpha, colorFilter)\n\n        cachedBrush = ShaderBrush(ImageShader(bmp, TileMode.Decal, TileMode.Decal))\n        cachedSize = intSize\n\n        return cachedBrush!!\n    }\n}\n\n@Immutable\nprivate class Solid(val color: Color) : QrBrush by BrushColor({ SolidColor(color) })\n\n@Immutable\nprivate class BrushColor(private val builder: (size: Float) -> Brush) : QrBrush {\n    override val mode: QrBrushMode\n        get() = QrBrushMode.Join\n\n    override fun brush(size: Float, neighbors: Neighbors): Brush = this.builder(size)\n}\n\n@Immutable\nprivate class Random(\n    private val probabilities: List<Pair<Float, Color>>,\n    private val random: Random\n) : QrBrush {\n\n    private val _probabilities = mutableListOf<Pair<ClosedFloatingPointRange<Float>, Color>>()\n\n    init {\n        require(probabilities.isNotEmpty()) {\n            \"Random color list can't be empty\"\n        }\n        (listOf(0f) + probabilities.map { it.first }).reduceIndexed { index, sum, i ->\n            _probabilities.add(sum..(sum + i) to probabilities[index - 1].second)\n            sum + i\n        }\n    }\n\n\n    override val mode: QrBrushMode = Separate\n\n    override fun brush(size: Float, neighbors: Neighbors): Brush {\n        val random = random.nextFloat() * _probabilities.last().first.endInclusive\n\n        val idx = _probabilities.binarySearch {\n            when {\n                random < it.first.start -> 1\n                random > it.first.endInclusive -> -1\n                else -> 0\n            }\n        }\n\n        return SolidColor(probabilities[idx].second)\n    }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrCodeMatrix.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\n\nclass QrCodeMatrix(val size: Int, initialFill: PixelType = PixelType.Background) {\n\n    constructor(list: List<List<PixelType>>) : this(list.size) {\n        types = list.flatten().toMutableList()\n    }\n\n    enum class PixelType { DarkPixel, LightPixel, Background, Logo }\n\n    private var types = MutableList(size * size) {\n        initialFill\n    }\n\n    operator fun get(i: Int, j: Int): PixelType {\n\n        val outOfBound = when {\n            i !in 0 until size -> i\n            j !in 0 until size -> j\n            else -> null\n        }\n\n        if (outOfBound != null)\n            throw IndexOutOfBoundsException(\n                \"Index $outOfBound is out of 0..${size - 1} matrix bound\"\n            )\n\n        return types[i + j * size]\n    }\n\n    operator fun set(i: Int, j: Int, type: PixelType) {\n\n        val outOfBound = when {\n            i !in 0 until size -> i\n            j !in 0 until size -> j\n            else -> null\n        }\n\n        if (outOfBound != null)\n            throw IndexOutOfBoundsException(\n                \"Index $outOfBound is out of 0..${size - 1} matrix bound\"\n            )\n\n        types[i + j * size] = type\n    }\n\n    fun copy(): QrCodeMatrix = QrCodeMatrix(size).apply {\n        types = ArrayList(this@QrCodeMatrix.types)\n    }\n}\n\ninternal fun QrCodeMatrix.neighbors(i: Int, j: Int): Neighbors {\n\n    fun cmp(i2: Int, j2: Int) = kotlin.runCatching {\n        this[i2, j2] == this[i, j]\n    }.getOrDefault(false)\n\n    return Neighbors(\n        topLeft = cmp(i - 1, j - 1),\n        topRight = cmp(i + 1, j - 1),\n        left = cmp(i - 1, j),\n        top = cmp(i, j - 1),\n        right = cmp(i + 1, j),\n        bottomLeft = cmp(i - 1, j + 1),\n        bottom = cmp(i, j + 1),\n        bottomRight = cmp(i + 1, j + 1)\n    )\n}\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrCodeShape.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport io.github.alexzhirkevich.qrose.options.QrCodeShape.Companion.Default\nimport kotlin.math.abs\nimport kotlin.math.cos\nimport kotlin.math.roundToInt\nimport kotlin.math.sin\nimport kotlin.math.sqrt\nimport kotlin.random.Random\n\n\n/**\n * Shape of the QR-code pattern.\n *\n * Limitations:\n * - The [Default] shape is the smallest available.\n * Any custom shapes must have bigger size.\n * - QR code pattern must always be at the center of the matrix.\n * - QR code matrix is always square.\n * */\ninterface QrCodeShape {\n\n    /**\n     * How much was QR code size increased in fraction related to default size (1.0).\n     * */\n    val shapeSizeIncrease: Float\n\n    /**\n     * Transform receiver matrix or create new with bigger size.\n     * */\n    fun QrCodeMatrix.transform(): QrCodeMatrix\n\n    companion object {\n        val Default = object : QrCodeShape {\n            override val shapeSizeIncrease: Float = 1f\n\n            override fun QrCodeMatrix.transform(): QrCodeMatrix = this\n        }\n    }\n}\n\n\nfun QrCodeShape.Companion.circle(\n    padding: Float = 1.1f,\n    precise: Boolean = true,\n    random: Random = Random(233),\n): QrCodeShape = Circle(\n    padding = padding,\n    random = random,\n    precise = precise\n)\n\nfun QrCodeShape.Companion.hexagon(\n    rotation: Float = 30f,\n    precise: Boolean = true,\n    random: Random = Random(233),\n): QrCodeShape = Hexagon(\n    rotationDegree = rotation,\n    random = random,\n    precise = precise\n)\n\n\n@Immutable\nprivate class Circle(\n    private val padding: Float,\n    private val random: Random,\n    private val precise: Boolean\n) : QrCodeShape {\n\n    override val shapeSizeIncrease: Float =\n        1 + (padding * sqrt(2.0) - 1).toFloat()\n\n    override fun QrCodeMatrix.transform(): QrCodeMatrix {\n\n        val padding = padding.coerceIn(1f, 2f)\n        val added = (((size * padding * sqrt(2.0)) - size) / 2).roundToInt()\n\n        val newSize = size + 2 * added\n        val newMatrix = QrCodeMatrix(newSize)\n\n        val center = newSize / 2f\n\n\n        for (i in 0 until newSize) {\n            for (j in 0 until newSize) {\n\n                val notInSquare = (i <= added - 1 ||\n                        j <= added - 1 ||\n                        i >= added + size ||\n                        j >= added + size)\n\n                val inLargeCircle = isInCircle(center, i.toFloat(), j.toFloat(), center)\n                if (notInSquare && inLargeCircle) {\n\n                    val inSmallCircle = !precise || isInCircle(\n                        center,\n                        i.toFloat(),\n                        j.toFloat(),\n                        center - 1\n                    )\n                    newMatrix[i, j] = if (!inSmallCircle || random.nextBoolean())\n                        QrCodeMatrix.PixelType.DarkPixel\n                    else QrCodeMatrix.PixelType.LightPixel\n                }\n            }\n        }\n\n        for (i in 0 until size) {\n            for (j in 0 until size) {\n                newMatrix[added + i, added + j] = this[i, j]\n            }\n        }\n        return newMatrix\n    }\n\n    fun isInCircle(center: Float, i: Float, j: Float, radius: Float): Boolean {\n        return sqrt((center - i) * (center - i) + (center - j) * (center - j)) < radius\n    }\n}\n\n@Immutable\nprivate class Hexagon(\n    rotationDegree: Float,\n    private val random: Random,\n    private val precise: Boolean\n) : QrCodeShape {\n\n    override val shapeSizeIncrease: Float = 1.6f\n\n    override fun QrCodeMatrix.transform(): QrCodeMatrix {\n\n        val a = sqrt(size * size / 1.268 / 1.268)\n\n        val newSize = (1.575f * size).toInt()\n\n        val newMatrix = QrCodeMatrix(newSize)\n\n        val (x1, y1) = rotate(newSize / 2, newSize / 2)\n\n        repeat(newSize) { i ->\n            repeat(newSize) { j ->\n                val (x, y) = rotate(i, j)\n\n                val inLarge = isInHexagon(x, y, x1, y1, a)\n\n                if (inLarge) {\n                    val inSmall = !precise || isInHexagon(x, y, x1, y1, a - 1.1)\n\n                    newMatrix[i, j] = if (!inSmall || random.nextBoolean())\n                        QrCodeMatrix.PixelType.DarkPixel else QrCodeMatrix.PixelType.LightPixel\n                }\n            }\n        }\n\n        val diff = (newSize - size) / 2\n\n        repeat(size) { i ->\n            repeat(size) { j ->\n                newMatrix[diff + i, diff + j] = this[i, j]\n            }\n        }\n\n        return newMatrix\n    }\n\n    private fun isInHexagon(x1: Double, y1: Double, x2: Double, y2: Double, z: Double): Boolean {\n        val x = abs(x1 - x2)\n        val y = abs(y1 - y2)\n        val py1 = z * 0.86602540378\n        val px2 = z * 0.5088190451\n        val py2 = z * 0.8592582628\n\n        val p_angle_01 = -x * (py1 - y) - x * y\n        val p_angle_20 = -y * (px2 - x) + x * (py2 - y)\n        val p_angle_03 = y * z\n        val p_angle_12 = -x * (py2 - y) - (px2 - x) * (py1 - y)\n        val p_angle_32 = (z - x) * (py2 - y) + y * (px2 - x)\n        val is_inside_1 = (p_angle_01 * p_angle_12 >= 0) && (p_angle_12 * p_angle_20 >= 0)\n        val is_inside_2 = (p_angle_03 * p_angle_32 >= 0) && (p_angle_32 * p_angle_20 >= 0)\n\n        return is_inside_1 || is_inside_2\n    }\n\n    private val rad = rotationDegree * 0.0174533\n\n    private val si = sin(rad)\n    private val co = cos(rad)\n\n    private val isModulo60 = rotationDegree.roundToInt() % 60 == 0\n\n    private fun rotate(x: Int, y: Int): Pair<Double, Double> {\n\n        if (isModulo60) {\n            return x.toDouble() to y.toDouble()\n        }\n        return (x * co - y * si) to (x * si + y * co)\n    }\n\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrColors.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\n\n\n/**\n * Colors of QR code elements\n *\n * @param dark brush of the dark QR code pixels\n * @param light brush of the light QR code pixels\n * @param ball brush of the QR code eye balls\n * @param frame brush of the QR code eye frames\n */\n@Immutable\ndata class QrColors(\n    val dark: QrBrush = QrBrush.Default,\n    val light: QrBrush = QrBrush.Unspecified,\n    val ball: QrBrush = QrBrush.Unspecified,\n    val frame: QrBrush = QrBrush.Unspecified,\n    val background: QrBrush = QrBrush.Unspecified\n)"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrErrorCorrectionLevel.kt",
    "content": "@file:Suppress(\"UNUSED\")\n\npackage io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport io.github.alexzhirkevich.qrose.qrcode.ErrorCorrectionLevel\n\n\n/**\n * QR code allows you to read encoded information even if a\n * part of the QR code image is damaged. It also allows to have logo\n * inside the code as a part of \"damage\".\n * */\n@Immutable\nenum class QrErrorCorrectionLevel(\n    internal val lvl: ErrorCorrectionLevel\n) {\n\n    /**\n     * Minimum possible level will be used.\n     * */\n    Auto(ErrorCorrectionLevel.L),\n\n    /**\n     * ~7% of QR code can be damaged (or used as logo).\n     * */\n    Low(ErrorCorrectionLevel.L),\n\n    /**\n     * ~15% of QR code can be damaged (or used as logo).\n     * */\n    Medium(ErrorCorrectionLevel.M),\n\n    /**\n     * ~25% of QR code can be damaged (or used as logo).\n     * */\n    MediumHigh(ErrorCorrectionLevel.Q),\n\n    /**\n     * ~30% of QR code can be damaged (or used as logo).\n     * */\n    High(ErrorCorrectionLevel.H)\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrFrameShape.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.geometry.CornerRadius\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.RoundRect\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathOperation\n\n/**\n * Style of the qr-code eye frame.\n */\ninterface QrFrameShape : QrShapeModifier {\n\n    companion object {\n        val Default: QrFrameShape = square()\n    }\n}\n\nfun QrFrameShape.Companion.square(size: Float = 1f): QrFrameShape =\n    SquareFrameShape(size)\n\nfun QrFrameShape.Companion.circle(size: Float = 1f): QrFrameShape =\n    CircleFrameShape(size)\n\nfun QrFrameShape.Companion.roundCorners(\n    corner: Float,\n    width: Float = 1f,\n    topLeft: Boolean = true,\n    bottomLeft: Boolean = true,\n    topRight: Boolean = true,\n    bottomRight: Boolean = true,\n): QrFrameShape = RoundCornersFrameShape(\n    corner = corner,\n    width = width,\n    topLeft = topLeft,\n    bottomLeft = bottomLeft,\n    topRight = topRight,\n    bottomRight = bottomRight\n)\n\n/**\n * [corner] from 0f to 0.35f\n */\nfun QrFrameShape.Companion.cutCorners(\n    corner: Float,\n    width: Float = 1f,\n    topLeft: Boolean = true,\n    bottomLeft: Boolean = true,\n    topRight: Boolean = true,\n    bottomRight: Boolean = true,\n): QrFrameShape = CutCornersFrameShape(\n    corner = corner,\n    width = width,\n    topLeft = topLeft,\n    bottomLeft = bottomLeft,\n    topRight = topRight,\n    bottomRight = bottomRight\n)\n\n\nfun QrFrameShape.Companion.asPixel(pixelShape: QrPixelShape): QrFrameShape =\n    AsPixelFrameShape(pixelShape)\n\n\n@Immutable\nprivate class AsPixelFrameShape(\n    val pixelShape: QrPixelShape\n) : QrFrameShape {\n\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n\n        val matrix = QrCodeMatrix(7)\n\n        repeat(7) { i ->\n            repeat(7) { j ->\n                matrix[i, j] = if (i == 0 || j == 0 || i == 6 || j == 6)\n                    QrCodeMatrix.PixelType.DarkPixel else QrCodeMatrix.PixelType.Background\n            }\n        }\n\n        repeat(7) { i ->\n            repeat(7) { j ->\n                if (matrix[i, j] == QrCodeMatrix.PixelType.DarkPixel)\n                    addPath(\n                        pixelShape.newPath(\n                            size / 7,\n                            matrix.neighbors(i, j)\n                        ),\n                        Offset(size / 7 * i, size / 7 * j)\n                    )\n            }\n        }\n    }\n}\n\n@Immutable\nprivate class SquareFrameShape(\n    private val size: Float = 1f\n) : QrFrameShape {\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n        val width = size / 7f * this@SquareFrameShape.size.coerceAtLeast(0f)\n\n        addRect(\n            Rect(0f, 0f, size, size)\n        )\n        addRect(\n            Rect(width, width, size - width, size - width)\n        )\n    }\n}\n\n\n@Immutable\nprivate class CircleFrameShape(\n    private val size: Float = 1f\n) : QrFrameShape {\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n        val width = size / 7f * this@CircleFrameShape.size.coerceAtLeast(0f)\n\n        addOval(\n            Rect(0f, 0f, size, size)\n        )\n        addOval(\n            Rect(width, width, size - width, size - width)\n        )\n    }\n}\n\n@Immutable\nprivate class CutCornersFrameShape(\n    private val corner: Float,\n    private val width: Float = 1f,\n    private val topLeft: Boolean = true,\n    private val bottomLeft: Boolean = true,\n    private val topRight: Boolean = true,\n    private val bottomRight: Boolean = true,\n) : QrFrameShape {\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n        val strokeWidth = (size / 7f) * width.coerceAtLeast(0f)\n        val realCorner = corner.coerceIn(0f, 0.5f)\n        val outerCut = realCorner * size\n\n        val outerRect = Rect(0f, 0f, size, size)\n        val innerRect = Rect(strokeWidth, strokeWidth, size - strokeWidth, size - strokeWidth)\n\n        val scale = (size - 2 * strokeWidth) / size\n        val innerCut = outerCut * scale\n\n        val outerPath =\n            buildCutRectPath(outerRect, outerCut, topLeft, topRight, bottomLeft, bottomRight)\n        val innerPath =\n            buildCutRectPath(innerRect, innerCut, topLeft, topRight, bottomLeft, bottomRight)\n\n        op(outerPath, innerPath, PathOperation.Difference)\n    }\n\n    private fun buildCutRectPath(\n        rect: Rect,\n        cut: Float,\n        topLeft: Boolean,\n        topRight: Boolean,\n        bottomLeft: Boolean,\n        bottomRight: Boolean\n    ): Path = Path().apply {\n        with(rect) {\n            moveTo(left + if (topLeft) cut else 0f, top)\n            lineTo(right - if (topRight) cut else 0f, top)\n            if (topRight) lineTo(right, top + cut)\n            lineTo(right, bottom - if (bottomRight) cut else 0f)\n            if (bottomRight) lineTo(right - cut, bottom)\n            lineTo(left + if (bottomLeft) cut else 0f, bottom)\n            if (bottomLeft) lineTo(left, bottom - cut)\n            lineTo(left, top + if (topLeft) cut else 0f)\n            if (topLeft) lineTo(left + cut, top)\n            close()\n        }\n    }\n}\n\n@Immutable\nprivate class RoundCornersFrameShape(\n    private val corner: Float,\n    private val width: Float = 1f,\n    private val topLeft: Boolean = true,\n    private val bottomLeft: Boolean = true,\n    private val topRight: Boolean = true,\n    private val bottomRight: Boolean = true,\n) : QrFrameShape {\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n\n        val strokeWidth = (size / 7f) * width.coerceAtLeast(0f)\n        val realCorner = corner.coerceIn(0f, 0.5f)\n\n        // радиус внешнего круга\n        val outerCorner = realCorner * size\n        // радиус внутреннего круга = внешний радиус - толщина, чтобы бордер не ломался\n        val innerCorner = (outerCorner - strokeWidth).coerceAtLeast(0f)\n\n        val outer = CornerRadius(outerCorner, outerCorner)\n        val inner = CornerRadius(innerCorner, innerCorner)\n\n        val outerRect = Rect(0f, 0f, size, size)\n        val innerRect = Rect(strokeWidth, strokeWidth, size - strokeWidth, size - strokeWidth)\n\n        val outerPath = Path().apply {\n            addRoundRect(\n                RoundRect(\n                    outerRect,\n                    topLeft = if (topLeft) outer else CornerRadius.Zero,\n                    topRight = if (topRight) outer else CornerRadius.Zero,\n                    bottomLeft = if (bottomLeft) outer else CornerRadius.Zero,\n                    bottomRight = if (bottomRight) outer else CornerRadius.Zero\n                )\n            )\n        }\n\n        val innerPath = Path().apply {\n            addRoundRect(\n                RoundRect(\n                    innerRect,\n                    topLeft = if (topLeft) inner else CornerRadius.Zero,\n                    topRight = if (topRight) inner else CornerRadius.Zero,\n                    bottomLeft = if (bottomLeft) inner else CornerRadius.Zero,\n                    bottomRight = if (bottomRight) inner else CornerRadius.Zero\n                )\n            )\n        }\n\n        op(outerPath, innerPath, PathOperation.Difference)\n    }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrLogo.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.graphics.painter.Painter\n\n/**\n * Logo (middle image) of the QR code.\n *\n * @param painter middle image.\n * @param size image size in fraction relative to QR code size\n * @param padding style and size of the QR code padding.\n * Can be used without [painter] if you want to place a logo manually.\n * @param shape shape of the logo padding\n * */\n@Immutable\ndata class QrLogo(\n    val painter: Painter? = null,\n    val size: Float = 0.25f,\n    val padding: QrLogoPadding = QrLogoPadding.Empty,\n    val shape: QrLogoShape = QrLogoShape.Default,\n)\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrLogoPadding.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\n\n/**\n * Type of padding applied to the logo.\n * Helps to highlight the logo inside the QR code pattern.\n * Padding can be added regardless of the presence of a logo.\n * */\nsealed interface QrLogoPadding {\n\n    /**\n     * Padding size relatively to the size of logo\n     * */\n    val size: Float\n\n\n    /**\n     * Logo will be drawn on top of QR code without any padding.\n     * QR code pixels might be visible through transparent logo.\n     *\n     * Prefer empty padding if your qr code encodes large amount of data\n     * to avoid performance issues.\n     * */\n    @Immutable\n    data object Empty : QrLogoPadding {\n        override val size: Float get() = 0f\n    }\n\n\n    /**\n     * Padding will be applied precisely according to the shape of logo\n     * */\n    @Immutable\n    class Accurate(override val size: Float) : QrLogoPadding\n\n\n    /**\n     * Works like [Accurate] but all clipped pixels will be removed.\n     *\n     * WARNING: this padding can cause performance issues\n     * for QR codes with large amount out data\n     * */\n    @Immutable\n    class Natural(override val size: Float) : QrLogoPadding\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrLogoShape.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\ninterface QrLogoShape : QrShapeModifier {\n\n    companion object {\n        val Default: QrLogoShape = object : QrLogoShape, QrShapeModifier by SquareShape() {}\n    }\n\n}\n\nfun QrLogoShape.Companion.circle(): QrLogoShape =\n    object : QrLogoShape, QrShapeModifier by CircleShape(1f) {}\n\nfun QrLogoShape.Companion.roundCorners(radius: Float): QrLogoShape =\n    object : QrLogoShape, QrShapeModifier by RoundCornersShape(radius, false) {}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrOptions.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport io.github.alexzhirkevich.qrose.options.dsl.InternalQrOptionsBuilderScope\nimport io.github.alexzhirkevich.qrose.options.dsl.QrOptionsBuilderScope\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern\n\nfun QrOptions(block: QrOptionsBuilderScope.() -> Unit): QrOptions {\n    val builder = QrOptions.Builder()\n    InternalQrOptionsBuilderScope(builder).apply(block)\n    return builder.build()\n}\n\n/**\n * Styling options of the QR code\n *\n * @param shapes shapes of the QR code pattern and its parts\n * @param colors colors of the QR code parts\n * @param logo middle image\n * @param errorCorrectionLevel level of error correction\n * @param fourEyed enable fourth eye\n * */\n@Immutable\ndata class QrOptions(\n    val shapes: QrShapes = QrShapes(),\n    val colors: QrColors = QrColors(),\n    val logo: QrLogo = QrLogo(),\n    val errorCorrectionLevel: QrErrorCorrectionLevel = QrErrorCorrectionLevel.Auto,\n    val maskPattern: MaskPattern? = null,\n    val fourEyed: Boolean = false,\n) {\n\n    internal class Builder {\n\n        var shapes: QrShapes = QrShapes()\n        var colors: QrColors = QrColors()\n        var logo: QrLogo = QrLogo()\n        var errorCorrectionLevel: QrErrorCorrectionLevel = QrErrorCorrectionLevel.Auto\n        var fourthEyeEnabled: Boolean = false\n        var maskPattern: MaskPattern? = null\n\n        fun build(): QrOptions = QrOptions(\n            shapes = shapes,\n            colors = colors,\n            logo = logo,\n            errorCorrectionLevel = errorCorrectionLevel,\n            maskPattern = maskPattern,\n            fourEyed = fourthEyeEnabled\n        )\n    }\n\n}\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrPixelShape.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\n/**\n * Style of the qr-code pixels.\n * */\nfun interface QrPixelShape : QrShapeModifier {\n\n    companion object {\n        val Default: QrPixelShape = square()\n    }\n}\n\nfun QrPixelShape.Companion.square(size: Float = 1f): QrPixelShape =\n    object : QrPixelShape, QrShapeModifier by SquareShape(size) {}\n\nfun QrPixelShape.Companion.circle(size: Float = 1f): QrPixelShape =\n    object : QrPixelShape, QrShapeModifier by CircleShape(size) {}\n\nfun QrPixelShape.Companion.roundCorners(radius: Float = .5f): QrPixelShape =\n    object : QrPixelShape, QrShapeModifier by RoundCornersShape(radius, true) {}\n\nfun QrPixelShape.Companion.verticalLines(width: Float = 1f): QrPixelShape =\n    object : QrPixelShape, QrShapeModifier by VerticalLinesShape(width) {}\n\nfun QrPixelShape.Companion.horizontalLines(width: Float = 1f): QrPixelShape =\n    object : QrPixelShape, QrShapeModifier by HorizontalLinesShape(width) {}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrShapeModifier.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathFillType.Companion.EvenOdd\n\nfun interface QrShapeModifier {\n\n    /**\n     * Modify current path or create new one.\n     *\n     * Receiver path is empty and reused for optimization.\n     * Most benefit this optimization gives when the shape is used for pixels with [QrBrushMode.Separate].\n     *\n     * Note: parent path has [EvenOdd] fill type! And this path will inherit it.\n     * */\n    fun Path.path(size: Float, neighbors: Neighbors): Path\n}\n\ninternal fun QrShapeModifier.newPath(size: Float, neighbors: Neighbors): Path = Path().apply {\n    path(size, neighbors)\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrShapeModifiers.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.geometry.CornerRadius\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.RoundRect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Path\n\n\n@Immutable\ninternal class SquareShape(\n    val size: Float = 1f\n) : QrShapeModifier {\n\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n        val s = size * this@SquareShape.size.coerceIn(0f, 1f)\n        val offset = (size - s) / 2\n\n        addRect(\n            Rect(\n                Offset(offset, offset),\n                Size(s, s)\n            )\n        )\n    }\n}\n\n@Immutable\ninternal class CircleShape(\n    val size: Float\n) : QrShapeModifier {\n\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n        val s = size * this@CircleShape.size.coerceIn(0f, 1f)\n        val offset = (size - s) / 2\n\n        addOval(\n            Rect(\n                Offset(offset, offset),\n                Size(s, s)\n            )\n        )\n    }\n}\n\n@Immutable\ninternal class RoundCornersShape(\n    val cornerRadius: Float,\n    val withNeighbors: Boolean,\n    val topLeft: Boolean = true,\n    val bottomLeft: Boolean = true,\n    val topRight: Boolean = true,\n    val bottomRight: Boolean = true,\n) : QrShapeModifier {\n\n\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n\n        val corner = (cornerRadius.coerceIn(0f, .5f) * size).let { CornerRadius(it, it) }\n\n        addRoundRect(\n            RoundRect(\n                Rect(0f, 0f, size, size),\n                topLeft = if (topLeft && (withNeighbors.not() || neighbors.top.not() && neighbors.left.not()))\n                    corner else CornerRadius.Zero,\n                topRight = if (topRight && (withNeighbors.not() || neighbors.top.not() && neighbors.right.not()))\n                    corner else CornerRadius.Zero,\n                bottomRight = if (bottomRight && (withNeighbors.not() || neighbors.bottom.not() && neighbors.right.not()))\n                    corner else CornerRadius.Zero,\n                bottomLeft = if (bottomLeft && (withNeighbors.not() || neighbors.bottom.not() && neighbors.left.not()))\n                    corner else CornerRadius.Zero\n            )\n        )\n    }\n\n}\n\n@Immutable\ninternal class VerticalLinesShape(\n    private val width: Float\n) : QrShapeModifier {\n\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n\n        val padding = (size * (1 - width.coerceIn(0f, 1f)))\n\n        if (neighbors.top) {\n            addRect(Rect(Offset(padding, 0f), Size(size - padding * 2, size / 2)))\n        } else {\n            addArc(Rect(Offset(padding, 0f), Size(size - padding * 2, size)), 180f, 180f)\n        }\n\n        if (neighbors.bottom) {\n            addRect(Rect(Offset(padding, size / 2), Size(size - padding * 2, size / 2)))\n        } else {\n            addArc(Rect(Offset(padding, 0f), Size(size - padding * 2, size)), 0f, 180f)\n        }\n    }\n}\n\n@Immutable\ninternal class HorizontalLinesShape(\n    private val width: Float\n) : QrShapeModifier {\n\n    override fun Path.path(size: Float, neighbors: Neighbors): Path = apply {\n\n        val padding = (size * (1 - width.coerceIn(0f, 1f)))\n\n        if (neighbors.left) {\n            addRect(Rect(Offset(0f, padding), Size(size / 2, size - padding * 2)))\n        } else {\n            addArc(Rect(Offset(0f, padding), Size(size, size - padding * 2)), 90f, 180f)\n\n        }\n\n        if (neighbors.right) {\n            addRect(Rect(Offset(size / 2, padding), Size(size / 2, size - padding * 2)))\n        } else {\n            addArc(Rect(Offset(0f, padding), Size(size, size - padding * 2)), -90f, 180f)\n        }\n    }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/QrShapes.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.runtime.Immutable\n\n/**\n * Shapes of QR code elements\n *\n * @param code shape of the QR code pattern.\n * @param darkPixel shape of the dark QR code pixels\n * @param lightPixel shape of the light QR code pixels\n * @param ball shape of the QR code eye balls\n * @param frame shape of the QR code eye frames\n * @param centralSymmetry if true, [ball] and [frame] shapes will be turned\n * to the center according to the current corner\n * */\n@Immutable\nclass QrShapes(\n    val code: QrCodeShape = QrCodeShape.Default,\n    val darkPixel: QrPixelShape = QrPixelShape.Default,\n    val lightPixel: QrPixelShape = QrPixelShape.Default,\n    val ball: QrBallShape = QrBallShape.Default,\n    val frame: QrFrameShape = QrFrameShape.Default,\n    val centralSymmetry: Boolean = true\n) {\n    fun copy(\n        code: QrCodeShape = this.code,\n        darkPixel: QrPixelShape = this.darkPixel,\n        lightPixel: QrPixelShape = this.lightPixel,\n        ball: QrBallShape = this.ball,\n        frame: QrFrameShape = this.frame,\n        centralSymmetry: Boolean = this.centralSymmetry\n    ) = QrShapes(\n        code = code,\n        darkPixel = darkPixel,\n        lightPixel = lightPixel,\n        ball = ball,\n        frame = frame,\n        centralSymmetry = centralSymmetry\n    )\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/Util.kt",
    "content": "package io.github.alexzhirkevich.qrose.options\n\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.painter.Painter\n\nobject EmptyPainter : Painter() {\n    override val intrinsicSize: Size\n        get() = Size.Zero\n\n    override fun DrawScope.onDraw() {\n    }\n\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/InternalQrColorsBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport io.github.alexzhirkevich.qrose.options.QrBrush\nimport io.github.alexzhirkevich.qrose.options.QrOptions\n\ninternal class InternalQrColorsBuilderScope(\n    private val builder: QrOptions.Builder\n) : QrColorsBuilderScope {\n\n    override var dark: QrBrush\n        get() = builder.colors.dark\n        set(value) = with(builder) {\n            colors = colors.copy(\n                dark = value\n            )\n        }\n\n    override var light: QrBrush\n        get() = builder.colors.light\n        set(value) = with(builder) {\n            colors = colors.copy(\n                light = value\n            )\n        }\n\n    override var frame: QrBrush\n        get() = builder.colors.frame\n        set(value) = with(builder) {\n            colors = colors.copy(\n                frame = value\n            )\n        }\n\n\n    override var ball: QrBrush\n        get() = builder.colors.ball\n        set(value) = with(builder) {\n            colors = colors.copy(\n                ball = value\n            )\n        }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/InternalQrLogoBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport androidx.compose.ui.graphics.painter.Painter\nimport io.github.alexzhirkevich.qrose.options.QrLogoPadding\nimport io.github.alexzhirkevich.qrose.options.QrLogoShape\nimport io.github.alexzhirkevich.qrose.options.QrOptions\n\ninternal class InternalQrLogoBuilderScope(\n    private val builder: QrOptions.Builder,\n) : QrLogoBuilderScope {\n\n    override var painter: Painter?\n        get() = builder.logo.painter\n        set(value) = with(builder) {\n            logo = logo.copy(painter = value)\n        }\n    override var size: Float\n        get() = builder.logo.size\n        set(value) = with(builder) {\n            logo = logo.copy(size = value)\n        }\n\n    override var padding: QrLogoPadding\n        get() = builder.logo.padding\n        set(value) = with(builder) {\n            logo = logo.copy(padding = value)\n        }\n    override var shape: QrLogoShape\n        get() = builder.logo.shape\n        set(value) = with(builder) {\n            logo = logo.copy(shape = value)\n        }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/InternalQrOptionsBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport io.github.alexzhirkevich.qrose.DelicateQRoseApi\nimport io.github.alexzhirkevich.qrose.options.QrErrorCorrectionLevel\nimport io.github.alexzhirkevich.qrose.options.QrOptions\n\n\ninternal class InternalQrOptionsBuilderScope(\n    private val builder: QrOptions.Builder\n) : QrOptionsBuilderScope {\n\n    override var errorCorrectionLevel: QrErrorCorrectionLevel\n        get() = builder.errorCorrectionLevel\n        set(value) {\n            builder.errorCorrectionLevel = value\n        }\n\n    @DelicateQRoseApi\n    override var fourEyed: Boolean\n        get() = builder.fourthEyeEnabled\n        set(value) {\n            builder.fourthEyeEnabled = value\n        }\n\n    override fun shapes(\n        centralSymmetry: Boolean,\n        block: QrShapesBuilderScope.() -> Unit\n    ) {\n        InternalQrShapesBuilderScope(builder, centralSymmetry)\n            .apply(block)\n    }\n\n    override fun colors(block: QrColorsBuilderScope.() -> Unit) {\n        InternalQrColorsBuilderScope(builder).apply(block)\n    }\n\n\n    override fun logo(block: QrLogoBuilderScope.() -> Unit) {\n        InternalQrLogoBuilderScope(builder)\n            .apply(block)\n    }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/InternalQrShapesBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport io.github.alexzhirkevich.qrose.options.QrBallShape\nimport io.github.alexzhirkevich.qrose.options.QrCodeShape\nimport io.github.alexzhirkevich.qrose.options.QrFrameShape\nimport io.github.alexzhirkevich.qrose.options.QrOptions\nimport io.github.alexzhirkevich.qrose.options.QrPixelShape\n\n\ninternal class InternalQrShapesBuilderScope(\n    private val builder: QrOptions.Builder,\n    centralSymmetry: Boolean,\n) : QrShapesBuilderScope {\n\n    init {\n        builder.shapes = builder.shapes.copy(\n            centralSymmetry = centralSymmetry\n        )\n    }\n\n    override var pattern: QrCodeShape\n        get() = builder.shapes.code\n        set(value) = with(builder) {\n            shapes = shapes.copy(\n                code = value\n            )\n        }\n\n\n    override var darkPixel: QrPixelShape\n        get() = builder.shapes.darkPixel\n        set(value) = with(builder) {\n            shapes = shapes.copy(\n                darkPixel = value\n            )\n        }\n\n    override var lightPixel: QrPixelShape\n        get() = builder.shapes.lightPixel\n        set(value) = with(builder) {\n            shapes = shapes.copy(\n                lightPixel = value\n            )\n        }\n\n    override var ball: QrBallShape\n        get() = builder.shapes.ball\n        set(value) = with(builder) {\n            shapes = shapes.copy(\n                ball = value\n            )\n        }\n\n    override var frame: QrFrameShape\n        get() = builder.shapes.frame\n        set(value) = with(builder) {\n            shapes = shapes.copy(\n                frame = value\n            )\n        }\n}"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/QrColorsBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport io.github.alexzhirkevich.qrose.options.QrBrush\n\n/**\n * Colors of QR code elements\n *\n * @property dark Brush of the dark QR code pixels\n * @property light Brush of the light QR code pixels\n * @property ball Brush of the QR code eye balls\n * @property frame Brush of the QR code eye frames\n */\nsealed interface QrColorsBuilderScope {\n    var dark: QrBrush\n    var light: QrBrush\n    var frame: QrBrush\n    var ball: QrBrush\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/QrLogoBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport androidx.compose.ui.graphics.painter.Painter\nimport io.github.alexzhirkevich.qrose.options.QrLogoPadding\nimport io.github.alexzhirkevich.qrose.options.QrLogoShape\n\n/**\n * Logo (middle image) of the QR code.\n *\n * @property painter Middle image.\n * @property size Image size in fraction relative to QR code size\n * @property padding Style and size of the QR code padding.\n * Can be used without [painter] if you want to place a logo manually.\n * @property shape Shape of the logo padding\n * */\nsealed interface QrLogoBuilderScope {\n    var painter: Painter?\n    var size: Float\n    var padding: QrLogoPadding\n    var shape: QrLogoShape\n}\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/QrOptionsBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport io.github.alexzhirkevich.qrose.DelicateQRoseApi\nimport io.github.alexzhirkevich.qrose.options.QrErrorCorrectionLevel\nimport io.github.alexzhirkevich.qrose.options.QrErrorCorrectionLevel.Auto\n\nsealed interface QrOptionsBuilderScope {\n\n    /**\n     * Level of error correction.\n     * [Auto] by default\n     * */\n    var errorCorrectionLevel: QrErrorCorrectionLevel\n\n    /**\n     * Enable 4th qr code eye. False by default\n     * */\n    @DelicateQRoseApi\n    var fourEyed: Boolean\n\n    /**\n     * Shapes of the QR code pattern and its parts.\n     * */\n    fun shapes(centralSymmetry: Boolean = true, block: QrShapesBuilderScope.() -> Unit)\n\n    /**\n     * Colors of QR code parts.\n     * */\n    fun colors(block: QrColorsBuilderScope.() -> Unit)\n\n    /**\n     * Middle image.\n     * */\n    fun logo(block: QrLogoBuilderScope.() -> Unit)\n}\n\n\n\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/options/dsl/QrShapesBuilderScope.kt",
    "content": "package io.github.alexzhirkevich.qrose.options.dsl\n\nimport io.github.alexzhirkevich.qrose.options.QrBallShape\nimport io.github.alexzhirkevich.qrose.options.QrCodeShape\nimport io.github.alexzhirkevich.qrose.options.QrFrameShape\nimport io.github.alexzhirkevich.qrose.options.QrPixelShape\n\n/**\n * Shapes of QR code elements\n *\n * @property pattern Shape of the QR code pattern.\n * @property darkPixel Shape of the dark QR code pixels\n * @property lightPixel Shape of the light QR code pixels\n * @property ball Shape of the QR code eye balls\n * @property frame Shape of the QR code eye frames\n * */\nsealed interface QrShapesBuilderScope {\n    var darkPixel: QrPixelShape\n    var lightPixel: QrPixelShape\n    var ball: QrBallShape\n    var frame: QrFrameShape\n    var pattern: QrCodeShape\n}\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/QRCode.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode\n\nimport io.github.alexzhirkevich.qrose.options.QrCodeMatrix\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType.DEFAULT\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType.NUMBERS\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType.UPPER_ALPHA_NUM\nimport io.github.alexzhirkevich.qrose.qrcode.internals.BitBuffer\nimport io.github.alexzhirkevich.qrose.qrcode.internals.Polynomial\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QR8BitByte\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRAlphaNum\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.applyMaskPattern\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.setupBottomLeftPositionProbePattern\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.setupPositionAdjustPattern\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.setupTimingPattern\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.setupTopLeftPositionProbePattern\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.setupTopRightPositionProbePattern\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.setupTypeInfo\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSetup.setupTypeNumber\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSquare\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRData\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRNumber\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRUtil\nimport io.github.alexzhirkevich.qrose.qrcode.internals.RSBlock\n\ninternal class QRCode @JvmOverloads constructor(\n    private val data: String,\n    private val errorCorrectionLevel: ErrorCorrectionLevel = ErrorCorrectionLevel.M,\n    private val dataType: QRCodeDataType = QRUtil.getDataType(data)\n) {\n    private val qrCodeData: QRData = when (dataType) {\n        NUMBERS -> QRNumber(data)\n        UPPER_ALPHA_NUM -> QRAlphaNum(data)\n        DEFAULT -> QR8BitByte(data)\n    }\n\n    companion object {\n        const val DEFAULT_CELL_SIZE = 1\n        private const val PAD0 = 0xEC\n        private const val PAD1 = 0x11\n\n        /**\n         * Calculates a suitable value for the [dataType] field for you.\n         */\n        @JvmStatic\n        @JvmOverloads\n        fun typeForDataAndECL(\n            data: String,\n            errorCorrectionLevel: ErrorCorrectionLevel,\n            dataType: QRCodeDataType = QRUtil.getDataType(data)\n        ): Int {\n            val qrCodeData = when (dataType) {\n                NUMBERS -> QRNumber(data)\n                UPPER_ALPHA_NUM -> QRAlphaNum(data)\n                DEFAULT -> QR8BitByte(data)\n            }\n            val dataLength = qrCodeData.length()\n\n            for (typeNum in 1 until errorCorrectionLevel.maxTypeNum) {\n                if (dataLength <= QRUtil.getMaxLength(typeNum, dataType, errorCorrectionLevel)) {\n                    return typeNum\n                }\n            }\n\n            return 40\n        }\n    }\n\n\n    @JvmOverloads\n    fun encode(\n        type: Int = 0,\n        maskPattern: MaskPattern?\n    ): QrCodeMatrix {\n        val finalType = if (type > 0) type else typeForDataAndECL(data, errorCorrectionLevel)\n\n        val maskPattern = if (maskPattern == null) {\n            var bestScore = Int.MAX_VALUE\n            var bestPattern = MaskPattern.PATTERN000\n\n            for (pattern in MaskPattern.entries) {\n                val matrix = encode(type, pattern)\n                val score = calculateMaskPenalty(matrix)\n                if (score < bestScore) {\n                    bestScore = score\n                    bestPattern = pattern\n                }\n            }\n\n            bestPattern\n        } else maskPattern\n\n        val moduleCount = finalType * 4 + 17\n        val modules: Array<Array<QRCodeSquare?>> =\n            Array(moduleCount) { Array(moduleCount) { null } }\n\n        setupTopLeftPositionProbePattern(modules)\n        setupTopRightPositionProbePattern(modules)\n        setupBottomLeftPositionProbePattern(modules)\n\n        setupPositionAdjustPattern(finalType, modules)\n        setupTimingPattern(moduleCount, modules)\n        setupTypeInfo(errorCorrectionLevel, maskPattern, moduleCount, modules)\n\n        if (finalType >= 7) {\n            setupTypeNumber(finalType, moduleCount, modules)\n        }\n\n        val data = try {\n            createData(finalType)\n        } catch (e: IllegalArgumentException) {\n            if (finalType < 40) {\n                return encode(finalType + 1, maskPattern)\n            } else {\n                throw e\n            }\n        }\n\n        applyMaskPattern(data, maskPattern, moduleCount, modules)\n\n        return QrCodeMatrix(\n            modules.map { row ->\n                row.map { pixel ->\n                    if (pixel?.dark == true)\n                        QrCodeMatrix.PixelType.DarkPixel\n                    else QrCodeMatrix.PixelType.LightPixel\n                }\n            }\n        )\n    }\n\n    private fun calculateMaskPenalty(matrix: QrCodeMatrix): Int {\n        val size = matrix.size\n        var penalty = 0\n\n        // Rule 1: длинные ряды одинакового цвета (по горизонтали)\n        for (y in 0 until size) {\n            var runColor = matrix[0, y]\n            var runLength = 1\n            for (x in 1 until size) {\n                val color = matrix[x, y]\n                if (color == runColor) {\n                    runLength++\n                } else {\n                    if (runLength >= 5) penalty += 3 + (runLength - 5)\n                    runColor = color\n                    runLength = 1\n                }\n            }\n            if (runLength >= 5) penalty += 3 + (runLength - 5)\n        }\n\n        // Rule 1 (вертикали)\n        for (x in 0 until size) {\n            var runColor = matrix[x, 0]\n            var runLength = 1\n            for (y in 1 until size) {\n                val color = matrix[x, y]\n                if (color == runColor) {\n                    runLength++\n                } else {\n                    if (runLength >= 5) penalty += 3 + (runLength - 5)\n                    runColor = color\n                    runLength = 1\n                }\n            }\n            if (runLength >= 5) penalty += 3 + (runLength - 5)\n        }\n\n        // Rule 2: квадраты 2x2 одного цвета\n        for (y in 0 until size - 1) {\n            for (x in 0 until size - 1) {\n                val color = matrix[x, y]\n                if (color == matrix[x + 1, y] &&\n                    color == matrix[x, y + 1] &&\n                    color == matrix[x + 1, y + 1]\n                ) {\n                    penalty += 3\n                }\n            }\n        }\n\n        // Rule 3: паттерны типа 1011101 (finder-like)\n        for (y in 0 until size) {\n            for (x in 0 until size - 6) {\n                if (matrix[x, y] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x + 1, y] == QrCodeMatrix.PixelType.LightPixel &&\n                    matrix[x + 2, y] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x + 3, y] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x + 4, y] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x + 5, y] == QrCodeMatrix.PixelType.LightPixel &&\n                    matrix[x + 6, y] == QrCodeMatrix.PixelType.DarkPixel\n                ) {\n                    penalty += 40\n                }\n            }\n        }\n\n        for (x in 0 until size) {\n            for (y in 0 until size - 6) {\n                if (matrix[x, y] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x, y + 1] == QrCodeMatrix.PixelType.LightPixel &&\n                    matrix[x, y + 2] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x, y + 3] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x, y + 4] == QrCodeMatrix.PixelType.DarkPixel &&\n                    matrix[x, y + 5] == QrCodeMatrix.PixelType.LightPixel &&\n                    matrix[x, y + 6] == QrCodeMatrix.PixelType.DarkPixel\n                ) {\n                    penalty += 40\n                }\n            }\n        }\n\n        // Rule 4: баланс тёмных и светлых (должно быть около 50%)\n        var darkCount = 0\n        for (y in 0 until size) {\n            for (x in 0 until size) {\n                if (matrix[x, y] == QrCodeMatrix.PixelType.DarkPixel) darkCount++\n            }\n        }\n        val total = size * size\n        val percent = darkCount * 100 / total\n        penalty += (kotlin.math.abs(percent - 50) / 5) * 10\n\n        return penalty\n    }\n\n    private fun createData(type: Int): IntArray {\n        val rsBlocks = RSBlock.getRSBlocks(type, errorCorrectionLevel)\n        val buffer = BitBuffer()\n\n        buffer.put(qrCodeData.dataType.value, 4)\n        buffer.put(qrCodeData.length(), qrCodeData.getLengthInBits(type))\n        qrCodeData.write(buffer)\n\n        val totalDataCount = rsBlocks.sumOf { it.dataCount } * 8\n\n        if (buffer.lengthInBits > totalDataCount) {\n            throw IllegalArgumentException(\"Code length overflow (${buffer.lengthInBits} > $totalDataCount)\")\n        }\n\n        if (buffer.lengthInBits + 4 <= totalDataCount) {\n            buffer.put(0, 4)\n        }\n\n        while (buffer.lengthInBits % 8 != 0) {\n            buffer.put(false)\n        }\n\n        while (true) {\n            if (buffer.lengthInBits >= totalDataCount) {\n                break\n            }\n\n            buffer.put(PAD0, 8)\n\n            if (buffer.lengthInBits >= totalDataCount) {\n                break\n            }\n\n            buffer.put(PAD1, 8)\n        }\n\n        return createBytes(buffer, rsBlocks)\n    }\n\n    private fun createBytes(buffer: BitBuffer, rsBlocks: Array<RSBlock>): IntArray {\n        var offset = 0\n        var maxDcCount = 0\n        var maxEcCount = 0\n        var totalCodeCount = 0\n        val dcData = Array(rsBlocks.size) { IntArray(0) }\n        val ecData = Array(rsBlocks.size) { IntArray(0) }\n\n        rsBlocks.forEachIndexed { i, it ->\n            val dcCount = it.dataCount\n            val ecCount = it.totalCount - dcCount\n\n            totalCodeCount += it.totalCount\n            maxDcCount = maxDcCount.coerceAtLeast(dcCount)\n            maxEcCount = maxEcCount.coerceAtLeast(ecCount)\n\n            // Init dcData[i]\n            dcData[i] = IntArray(dcCount) { idx -> 0xff and buffer.buffer[idx + offset] }\n            offset += dcCount\n\n            // Init ecData[i]\n            val rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)\n            val rawPoly = Polynomial(dcData[i], rsPoly.len() - 1)\n            val modPoly = rawPoly.mod(rsPoly)\n            val ecDataSize = rsPoly.len() - 1\n\n            ecData[i] = IntArray(ecDataSize) { idx ->\n                val modIndex = idx + modPoly.len() - ecDataSize\n                if ((modIndex >= 0)) modPoly[modIndex] else 0\n            }\n        }\n\n        var index = 0\n        val data = IntArray(totalCodeCount)\n\n        for (i in 0 until maxDcCount) {\n            for (r in rsBlocks.indices) {\n                if (i < dcData[r].size) {\n                    data[index++] = dcData[r][i]\n                }\n            }\n        }\n\n        for (i in 0 until maxEcCount) {\n            for (r in rsBlocks.indices) {\n                if (i < ecData[r].size) {\n                    data[index++] = ecData[r][i]\n                }\n            }\n        }\n\n        return data\n    }\n\n    override fun toString(): String =\n        \"QRCode(data=$data\" +\n                \", errorCorrectionLevel=$errorCorrectionLevel\" +\n                \", dataType=$dataType\" +\n                \", qrCodeData=${qrCodeData::class.simpleName}\" +\n                \")\"\n}\n\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/QRCodeEnums.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode\n\nimport io.github.alexzhirkevich.qrose.qrcode.ErrorCorrectionLevel.H\nimport io.github.alexzhirkevich.qrose.qrcode.ErrorCorrectionLevel.Q\n\n/**\n * The level of Error Correction to apply to the QR Code image. The Higher the Error Correction, the lower quality\n * **print** the QRCode can be (think of \"wow, even with the paper a bit crumpled, it still read the QR Code!\" - that\n * is likely a [Q] or [H] error correction).\n *\n * The trade-off is the amount of data you can encode. The higher the error correction level, the less amount of data\n * you'll be able to encode.\n *\n * Please consult [Kazuhiko's Online Demo](https://kazuhikoarase.github.io/qrcode-generator/js/demo/) where at the time\n * of writing a handy table showed how many bytes can be encoded given a data type ([QRCodeDataType]) and Error Correction Level.\n *\n * This library automatically tries to fit ~2048 bytes into the QR Code regardless of error correction level. That is\n * the reason and meaning of [maxTypeNum].\n *\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/ErrorCorrectionLevel.java)\n *\n * @param value Value associated with this error correction level\n * @param maxTypeNum Maximum `type` value which can fit 2048 bytes. Used to automatically calculate the `type` value.\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal enum class ErrorCorrectionLevel(val value: Int, val maxTypeNum: Int) {\n    L(1, 21),\n    M(0, 25),\n    Q(3, 30),\n    H(2, 34)\n}\n\n/**\n * Patterns to apply to the QRCode. They change how the QRCode looks in the end.\n *\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/MaskPattern.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\nenum class MaskPattern {\n    /** This is the default pattern (no pattern is applied) */\n    PATTERN000,\n    PATTERN001,\n    PATTERN010,\n    PATTERN011,\n    PATTERN100,\n    PATTERN101,\n    PATTERN110,\n    PATTERN111\n}\n\n/**\n * QRCode Modes. Basically represents which kind of data is being encoded.\n *\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/Mode.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal enum class QRCodeDataType(val value: Int) {\n    /** Strictly numerical data. Like huge integers. These can be way bigger than [Long.MAX_VALUE]. */\n    NUMBERS(1 shl 0),\n\n    /** Represents Uppercase Alphanumerical data. Allowed characters: `[0-9A-Z $%*+\\-./:]`. */\n    UPPER_ALPHA_NUM(1 shl 1),\n\n    /** This can be any kind of data. With this you can encode Strings, URLs, images, files, anything. */\n    DEFAULT(1 shl 2)\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/BitBuffer.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/BitBuffer.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal class BitBuffer {\n    var buffer: IntArray\n        private set\n    var lengthInBits: Int\n        private set\n    private val increments = 32\n\n    private operator fun get(index: Int): Boolean =\n        buffer[index / 8] ushr 7 - index % 8 and 1 == 1\n\n    fun put(num: Int, length: Int) {\n        for (i in 0 until length) {\n            put(num ushr length - i - 1 and 1 == 1)\n        }\n    }\n\n    fun put(bit: Boolean) {\n        if (lengthInBits == buffer.size * 8) {\n            buffer = buffer.copyOf(buffer.size + increments)\n        }\n        if (bit) {\n            buffer[lengthInBits / 8] = buffer[lengthInBits / 8] or (0x80 ushr lengthInBits % 8)\n        }\n        lengthInBits++\n    }\n\n    init {\n        buffer = IntArray(increments)\n        lengthInBits = 0\n    }\n\n    override fun toString(): String {\n        val buffer = StringBuilder()\n        for (i in 0 until lengthInBits) {\n            buffer.append(if (get(i)) '1' else '0')\n        }\n        return buffer.toString()\n    }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/ErrorMessage.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\n/**\n * Helps generates error messages.\n *\n * @author Rafael Lins - g0dkar\n */\ninternal object ErrorMessage {\n    private const val BUG_REPORT_URL =\n        \"https://github.com/g0dkar/qrcode-kotlin/issues/new?assignees=g0dkar&labels=bug&template=bug_report.md&title=\"\n\n    /** Generates an error message with a \"Please report\" appended to it. */\n    fun error(string: String) =\n        \"$string - Please, report this error via this URL: $BUG_REPORT_URL\"\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/Polynomial.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRMath.gexp\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRMath.glog\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/Polynomial.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal class Polynomial(num: IntArray, shift: Int = 0) {\n    private val data: IntArray\n\n    init {\n        val offset = num.indexOfFirst { it != 0 }.coerceAtLeast(0)\n        this.data = IntArray(num.size - offset + shift) { 0 }\n        arraycopy(num, offset, this.data, 0, num.size - offset)\n    }\n\n    private fun arraycopy(from: IntArray, fromPos: Int, to: IntArray, toPos: Int, length: Int) {\n        for (i in 0 until length) {\n            to[toPos + i] = from[fromPos + i]\n        }\n    }\n\n    operator fun get(i: Int) = data[i]\n\n    fun len(): Int = data.size\n\n    fun multiply(other: Polynomial): Polynomial =\n        IntArray(len() + other.len() - 1) { 0 }\n            .let {\n                for (i in 0 until len()) {\n                    for (j in 0 until other.len()) {\n                        it[i + j] = it[i + j] xor gexp(glog(this[i]) + glog(other[j]))\n                    }\n                }\n\n                Polynomial(it)\n            }\n\n    fun mod(other: Polynomial): Polynomial =\n        if (len() - other.len() < 0) {\n            this\n        } else {\n            val ratio = glog(this[0]) - glog(other[0])\n            val result = data.copyOf()\n\n            other.data.forEachIndexed { i, it ->\n                result[i] = result[i] xor gexp(glog(it) + ratio)\n            }\n\n            Polynomial(result).mod(other)\n        }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/QRCodeSetup.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\nimport io.github.alexzhirkevich.qrose.qrcode.ErrorCorrectionLevel\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.BOTTOM_LEFT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.BOTTOM_MID\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.BOTTOM_RIGHT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.CENTER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.LEFT_MID\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.MARGIN\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.RIGHT_MID\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.TOP_LEFT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.TOP_MID\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.TOP_RIGHT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSquareType.POSITION_PROBE\n\n/**\n * Object with helper methods and constants to setup stuff into the QRCode such as Position Probes and Timing Probes.\n *\n * @author Rafael Lins - g0dkar\n */\ninternal object QRCodeSetup {\n    private const val DEFAULT_PROBE_SIZE = 7\n\n    fun setupTopLeftPositionProbePattern(\n        modules: Array<Array<QRCodeSquare?>>,\n        probeSize: Int = DEFAULT_PROBE_SIZE\n    ) {\n        setupPositionProbePattern(0, 0, modules, probeSize)\n    }\n\n    fun setupTopRightPositionProbePattern(\n        modules: Array<Array<QRCodeSquare?>>,\n        probeSize: Int = DEFAULT_PROBE_SIZE\n    ) {\n        setupPositionProbePattern(modules.size - probeSize, 0, modules, probeSize)\n    }\n\n    fun setupBottomLeftPositionProbePattern(\n        modules: Array<Array<QRCodeSquare?>>,\n        probeSize: Int = DEFAULT_PROBE_SIZE\n    ) {\n        setupPositionProbePattern(0, modules.size - probeSize, modules, probeSize)\n    }\n\n    fun setupPositionProbePattern(\n        rowOffset: Int,\n        colOffset: Int,\n        modules: Array<Array<QRCodeSquare?>>,\n        probeSize: Int = DEFAULT_PROBE_SIZE\n    ) {\n        val modulesSize = modules.size\n\n        for (row in -1..probeSize) {\n            for (col in -1..probeSize) {\n                if (!isInsideModules(row, rowOffset, col, colOffset, modulesSize)) {\n                    continue\n                }\n\n                val isDark = isTopBottomRowSquare(row, col, probeSize) ||\n                        isLeftRightColSquare(row, col, probeSize) ||\n                        isMidSquare(row, col, probeSize)\n\n                val region = findSquareRegion(row, col, probeSize)\n\n                modules[row + rowOffset][col + colOffset] = QRCodeSquare(\n                    dark = isDark,\n                    row = row + rowOffset,\n                    col = col + colOffset,\n                    squareInfo = QRCodeSquareInfo(POSITION_PROBE, region),\n                    moduleSize = modulesSize\n                )\n            }\n        }\n    }\n\n    private fun isInsideModules(\n        row: Int,\n        rowOffset: Int,\n        col: Int,\n        colOffset: Int,\n        modulesSize: Int\n    ) =\n        row + rowOffset in 0 until modulesSize && col + colOffset in 0 until modulesSize\n\n    private fun isTopBottomRowSquare(row: Int, col: Int, probeSize: Int) =\n        col in 0 until probeSize && (row == 0 || row == probeSize - 1)\n\n    private fun isLeftRightColSquare(row: Int, col: Int, probeSize: Int) =\n        row in 0 until probeSize && (col == 0 || col == probeSize - 1)\n\n    private fun isMidSquare(row: Int, col: Int, probeSize: Int) =\n        row in 2 until (probeSize - 2) && 2 <= col && col <= probeSize - 3\n\n    private fun findSquareRegion(row: Int, col: Int, probeSize: Int) =\n        when (row) {\n            0 -> when (col) { // 0 x ?: ┌───┐\n                0 -> TOP_LEFT_CORNER // 0 x 0: ┌\n                probeSize - 1 -> TOP_RIGHT_CORNER // 0 x MAX: ┐\n                probeSize -> MARGIN // Outside boundaries\n                else -> TOP_MID // between: ─\n            }\n\n            probeSize - 1 -> when (col) { // MAX x ?: └───┘\n                0 -> BOTTOM_LEFT_CORNER // MAX x 0: └\n                probeSize - 1 -> BOTTOM_RIGHT_CORNER // MAX x MAX: ┘\n                probeSize -> MARGIN // Outside boundaries\n                else -> BOTTOM_MID // between: ─\n            }\n\n            probeSize -> MARGIN // Outside boundaries\n            else -> when (col) { // Inside boundaries but not in any edge\n                0 -> LEFT_MID\n                probeSize - 1 -> RIGHT_MID\n                probeSize -> MARGIN // Outside boundaries\n                else -> CENTER // Middle/Center square\n            }\n        }\n\n    fun setupPositionAdjustPattern(type: Int, modules: Array<Array<QRCodeSquare?>>) {\n        val pos = QRUtil.getPatternPosition(type)\n\n        for (i in pos.indices) {\n            for (j in pos.indices) {\n                val row = pos[i]\n                val col = pos[j]\n\n                if (modules[row][col] != null) {\n                    continue\n                }\n\n                for (r in -2..2) {\n                    for (c in -2..2) {\n                        modules[row + r][col + c] = QRCodeSquare(\n                            dark = r == -2 || r == 2 || c == -2 || c == 2 || r == 0 && c == 0,\n                            row = row + r,\n                            col = col + c,\n                            squareInfo = QRCodeSquareInfo(\n                                QRCodeSquareType.POSITION_ADJUST,\n                                QRCodeRegion.UNKNOWN\n                            ),\n                            moduleSize = modules.size\n                        )\n                    }\n                }\n            }\n        }\n    }\n\n    fun setupTimingPattern(moduleCount: Int, modules: Array<Array<QRCodeSquare?>>) {\n        for (r in 8 until moduleCount - 8) {\n            if (modules[r][6] != null) {\n                continue\n            }\n\n            modules[r][6] = QRCodeSquare(\n                dark = r % 2 == 0,\n                row = r,\n                col = 6,\n                squareInfo = QRCodeSquareInfo(\n                    QRCodeSquareType.TIMING_PATTERN,\n                    QRCodeRegion.UNKNOWN\n                ),\n                moduleSize = modules.size\n            )\n        }\n\n        for (c in 8 until moduleCount - 8) {\n            if (modules[6][c] != null) {\n                continue\n            }\n\n            modules[6][c] = QRCodeSquare(\n                dark = c % 2 == 0,\n                row = 6,\n                col = c,\n                squareInfo = QRCodeSquareInfo(\n                    QRCodeSquareType.TIMING_PATTERN,\n                    QRCodeRegion.UNKNOWN\n                ),\n                moduleSize = modules.size\n            )\n        }\n    }\n\n    fun setupTypeInfo(\n        errorCorrectionLevel: ErrorCorrectionLevel,\n        maskPattern: MaskPattern,\n        moduleCount: Int,\n        modules: Array<Array<QRCodeSquare?>>\n    ) {\n        val data = errorCorrectionLevel.value shl 3 or maskPattern.ordinal\n        val bits = QRUtil.getBCHTypeInfo(data)\n\n        for (i in 0..14) {\n            val mod = bits shr i and 1 == 1\n\n            if (i < 6) {\n                set(i, 8, mod, modules)\n            } else if (i < 8) {\n                set(i + 1, 8, mod, modules)\n            } else {\n                set(moduleCount - 15 + i, 8, mod, modules)\n            }\n        }\n\n        for (i in 0..14) {\n            val mod = bits shr i and 1 == 1\n\n            if (i < 8) {\n                set(8, moduleCount - i - 1, mod, modules)\n            } else if (i < 9) {\n                set(8, 15 - i, mod, modules)\n            } else {\n                set(8, 15 - i - 1, mod, modules)\n            }\n        }\n\n        set(moduleCount - 8, 8, true, modules)\n    }\n\n    fun setupTypeNumber(type: Int, moduleCount: Int, modules: Array<Array<QRCodeSquare?>>) {\n        val bits = QRUtil.getBCHTypeNumber(type)\n\n        for (i in 0..17) {\n            val mod = bits shr i and 1 == 1\n            set(i / 3, i % 3 + moduleCount - 8 - 3, mod, modules)\n        }\n\n        for (i in 0..17) {\n            val mod = bits shr i and 1 == 1\n            set(i % 3 + moduleCount - 8 - 3, i / 3, mod, modules)\n        }\n    }\n\n    fun applyMaskPattern(\n        data: IntArray,\n        maskPattern: MaskPattern,\n        moduleCount: Int,\n        modules: Array<Array<QRCodeSquare?>>\n    ) {\n        var inc = -1\n        var bitIndex = 7\n        var byteIndex = 0\n        var row = moduleCount - 1\n        var col = moduleCount - 1\n\n        while (col > 0) {\n            if (col == 6) {\n                col--\n            }\n\n            while (true) {\n                for (c in 0..1) {\n                    if (modules[row][col - c] == null) {\n                        var dark = false\n\n                        if (byteIndex < data.size) {\n                            dark = (data[byteIndex] ushr bitIndex) and 1 == 1\n                        }\n\n                        val mask = QRUtil.getMask(maskPattern, row, col - c)\n                        if (mask) {\n                            dark = !dark\n                        }\n\n                        set(row, col - c, dark, modules)\n\n                        bitIndex--\n                        if (bitIndex == -1) {\n                            byteIndex++\n                            bitIndex = 7\n                        }\n                    }\n                }\n\n                row += inc\n                if (row < 0 || moduleCount <= row) {\n                    row -= inc\n                    inc = -inc\n                    break\n                }\n            }\n\n            col -= 2\n        }\n    }\n\n    private fun set(row: Int, col: Int, value: Boolean, modules: Array<Array<QRCodeSquare?>>) {\n        val qrCodeSquare = modules[row][col]\n\n        if (qrCodeSquare != null) {\n            qrCodeSquare.dark = value\n        } else {\n            modules[row][col] = QRCodeSquare(\n                dark = value,\n                row = row,\n                col = col,\n                moduleSize = modules.size\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/QRCodeSquare.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.BOTTOM_LEFT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.BOTTOM_RIGHT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.TOP_LEFT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.TOP_RIGHT_CORNER\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeRegion.UNKNOWN\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSquareType.DEFAULT\nimport io.github.alexzhirkevich.qrose.qrcode.internals.QRCodeSquareType.MARGIN\n\n/**\n * Represents a single QRCode square unit. It has information about its \"color\" (either dark or bright),\n * its position (row and column) and what it represents.\n *\n * It can be part of a position probe (aka those big squares at the extremities), part of a position\n * adjustment square, part of a timing pattern or just another square as any other :)\n *\n * @author Rafael Lins - g0dkar\n */\ninternal class QRCodeSquare(\n    /** Is this a painted square? */\n    var dark: Boolean,\n    /** The row (top-to-bottom) that this square represents. */\n    val row: Int,\n    /** The column (left-to-right) that this square represents. */\n    val col: Int,\n    /** How big is the whole QRCode matrix? (e.g. if this is \"16\" then this is part of a 16x16 matrix) */\n    val moduleSize: Int,\n    /** What does this square represent within the QRCode? */\n    val squareInfo: QRCodeSquareInfo = QRCodeSquareInfo(DEFAULT, UNKNOWN)\n)\n\n/**\n * Returns information on the square itself. It has the [type] of square and its [region] within its relative type.\n *\n * For example, if `type = POSITION_PROBE` then [region] will represent where within the Position Probe this square\n * is positioned. A [region] of [QRCodeRegion.TOP_LEFT_CORNER] for example represents the top left corner of the\n * position probe this particular square is part of (a QRCode have 3 position probes).\n */\ninternal class QRCodeSquareInfo(\n    private val type: QRCodeSquareType,\n    private val region: QRCodeRegion\n) {\n    companion object {\n        internal fun margin() = QRCodeSquareInfo(MARGIN, QRCodeRegion.MARGIN)\n    }\n}\n\n/**\n * The types available for squares in a QRCode.\n *\n * @author Rafael Lins - g0dkar\n */\ninternal enum class QRCodeSquareType {\n    /** Part of a position probe: one of those big squares at the extremities of the QRCode. */\n    POSITION_PROBE,\n\n    /** Part of a position adjustment pattern: just like a position probe, but much smaller. */\n    POSITION_ADJUST,\n\n    /** Part of the timing pattern. Make it a square like any other :) */\n    TIMING_PATTERN,\n\n    /** Anything special. Just a square. */\n    DEFAULT,\n\n    /** Used to point out that this is part of the margin. */\n    MARGIN\n}\n\n/**\n * Represents which part/region of a given square type a particular, single square is.\n *\n * For example, a position probe is visually composed of multiple squares that form a bigger one.\n *\n * For example, this is what a position probe normally looks like (squares spaced for ease of understanding):\n *\n * ```\n * A■■■■B\n * ■ ■■ ■\n * ■ ■■ ■\n * C■■■■D\n * ```\n *\n * The positions marked with `A`, `B`, `C` and `D` would be regions [TOP_LEFT_CORNER], [TOP_RIGHT_CORNER],\n * [BOTTOM_LEFT_CORNER] and [BOTTOM_RIGHT_CORNER] respectively.\n */\ninternal enum class QRCodeRegion {\n    TOP_LEFT_CORNER,\n    TOP_RIGHT_CORNER,\n    TOP_MID,\n    LEFT_MID,\n    RIGHT_MID,\n    CENTER,\n    BOTTOM_LEFT_CORNER,\n    BOTTOM_RIGHT_CORNER,\n    BOTTOM_MID,\n    MARGIN,\n    UNKNOWN\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/QRData.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType.DEFAULT\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType.NUMBERS\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType.UPPER_ALPHA_NUM\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/QRData.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal abstract class QRData(val dataType: QRCodeDataType, val data: String) {\n    abstract fun length(): Int\n\n    abstract fun write(buffer: BitBuffer)\n\n    fun getLengthInBits(type: Int): Int =\n        when (type) {\n            in 1..9 -> {\n                when (dataType) {\n                    NUMBERS -> 10\n                    UPPER_ALPHA_NUM -> 9\n                    DEFAULT -> 8\n                }\n            }\n\n            in 1..26 -> {\n                when (dataType) {\n                    NUMBERS -> 12\n                    UPPER_ALPHA_NUM -> 11\n                    DEFAULT -> 16\n                }\n            }\n\n            in 1..40 -> {\n                when (dataType) {\n                    NUMBERS -> 14\n                    UPPER_ALPHA_NUM -> 13\n                    DEFAULT -> 16\n                }\n            }\n\n            else -> {\n                throw IllegalArgumentException(\"'type' must be greater than 0 and cannot be greater than 40: $type\")\n            }\n        }\n}\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/QR8BitByte.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal class QR8BitByte(data: String) : QRData(DEFAULT, data) {\n    private val dataBytes = data.encodeToByteArray()\n\n    override fun write(buffer: BitBuffer) {\n        for (i in dataBytes.indices) {\n            buffer.put(dataBytes[i].toInt(), 8)\n        }\n    }\n\n    override fun length(): Int =\n        dataBytes.size\n}\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/QRAlphaNum.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal class QRAlphaNum(data: String) : QRData(UPPER_ALPHA_NUM, data) {\n    override fun write(buffer: BitBuffer) {\n        var i = 0\n        val dataLength = data.length\n        while (i + 1 < dataLength) {\n            buffer.put(charCode(data[i]) * 45 + charCode(data[i + 1]), 11)\n            i += 2\n        }\n        if (i < dataLength) {\n            buffer.put(charCode(data[i]), 6)\n        }\n    }\n\n    override fun length(): Int = data.length\n\n    private fun charCode(c: Char): Int =\n        when (c) {\n            in '0'..'9' -> c - '0'\n            in 'A'..'Z' -> c - 'A' + 10\n            else -> {\n                when (c) {\n                    ' ' -> 36\n                    '$' -> 37\n                    '%' -> 38\n                    '*' -> 39\n                    '+' -> 40\n                    '-' -> 41\n                    '.' -> 42\n                    '/' -> 43\n                    ':' -> 44\n                    else -> throw IllegalArgumentException(\"Illegal character: $c\")\n                }\n            }\n        }\n}\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/QRNumber.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal class QRNumber(data: String) : QRData(NUMBERS, data) {\n    override fun write(buffer: BitBuffer) {\n        var i = 0\n        val len = length()\n\n        while (i + 2 < len) {\n            val num = data.substring(i, i + 3).toInt()\n            buffer.put(num, 10)\n            i += 3\n        }\n\n        if (i < len) {\n            if (len - i == 1) {\n                val num = data.substring(i, i + 1).toInt()\n                buffer.put(num, 4)\n            } else if (len - i == 2) {\n                val num = data.substring(i, i + 2).toInt()\n                buffer.put(num, 7)\n            }\n        }\n    }\n\n    override fun length(): Int = data.length\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/QRMath.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/QRMath.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal object QRMath {\n    private val EXP_TABLE = IntArray(256)\n    private val LOG_TABLE = IntArray(256)\n\n    fun glog(n: Int): Int = LOG_TABLE[n]\n\n    fun gexp(n: Int): Int {\n        var i = n\n        while (i < 0) {\n            i += 255\n        }\n        while (i >= 256) {\n            i -= 255\n        }\n        return EXP_TABLE[i]\n    }\n\n    init {\n        for (i in 0..7) {\n            EXP_TABLE[i] = 1 shl i\n        }\n\n        for (i in 8..255) {\n            EXP_TABLE[i] = (\n                    EXP_TABLE[i - 4]\n                            xor EXP_TABLE[i - 5]\n                            xor EXP_TABLE[i - 6]\n                            xor EXP_TABLE[i - 8]\n                    )\n        }\n\n        for (i in 0..254) {\n            LOG_TABLE[EXP_TABLE[i]] = i\n        }\n    }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/QRUtil.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\nimport io.github.alexzhirkevich.qrose.qrcode.ErrorCorrectionLevel\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN000\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN001\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN010\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN011\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN100\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN101\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN110\nimport io.github.alexzhirkevich.qrose.qrcode.MaskPattern.PATTERN111\nimport io.github.alexzhirkevich.qrose.qrcode.QRCodeDataType\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/QRUtil.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal object QRUtil {\n    fun getPatternPosition(typeNumber: Int): IntArray = PATTERN_POSITION_TABLE[typeNumber - 1]\n\n    private val PATTERN_POSITION_TABLE = arrayOf(\n        intArrayOf(),\n        intArrayOf(6, 18),\n        intArrayOf(6, 22),\n        intArrayOf(6, 26),\n        intArrayOf(6, 30),\n        intArrayOf(6, 34),\n        intArrayOf(6, 22, 38),\n        intArrayOf(6, 24, 42),\n        intArrayOf(6, 26, 46),\n        intArrayOf(6, 28, 50),\n        intArrayOf(6, 30, 54),\n        intArrayOf(6, 32, 58),\n        intArrayOf(6, 34, 62),\n        intArrayOf(6, 26, 46, 66),\n        intArrayOf(6, 26, 48, 70),\n        intArrayOf(6, 26, 50, 74),\n        intArrayOf(6, 30, 54, 78),\n        intArrayOf(6, 30, 56, 82),\n        intArrayOf(6, 30, 58, 86),\n        intArrayOf(6, 34, 62, 90),\n        intArrayOf(6, 28, 50, 72, 94),\n        intArrayOf(6, 26, 50, 74, 98),\n        intArrayOf(6, 30, 54, 78, 102),\n        intArrayOf(6, 28, 54, 80, 106),\n        intArrayOf(6, 32, 58, 84, 110),\n        intArrayOf(6, 30, 58, 86, 114),\n        intArrayOf(6, 34, 62, 90, 118),\n        intArrayOf(6, 26, 50, 74, 98, 122),\n        intArrayOf(6, 30, 54, 78, 102, 126),\n        intArrayOf(6, 26, 52, 78, 104, 130),\n        intArrayOf(6, 30, 56, 82, 108, 134),\n        intArrayOf(6, 34, 60, 86, 112, 138),\n        intArrayOf(6, 30, 58, 86, 114, 142),\n        intArrayOf(6, 34, 62, 90, 118, 146),\n        intArrayOf(6, 30, 54, 78, 102, 126, 150),\n        intArrayOf(6, 24, 50, 76, 102, 128, 154),\n        intArrayOf(6, 28, 54, 80, 106, 132, 158),\n        intArrayOf(6, 32, 58, 84, 110, 136, 162),\n        intArrayOf(6, 26, 54, 82, 110, 138, 166),\n        intArrayOf(6, 30, 58, 86, 114, 142, 170)\n    )\n\n    private val MAX_LENGTH = arrayOf(\n        arrayOf(\n            intArrayOf(41, 25, 17, 10),\n            intArrayOf(34, 20, 14, 8),\n            intArrayOf(27, 16, 11, 7),\n            intArrayOf(17, 10, 7, 4)\n        ),\n        arrayOf(\n            intArrayOf(77, 47, 32, 20),\n            intArrayOf(63, 38, 26, 16),\n            intArrayOf(48, 29, 20, 12),\n            intArrayOf(34, 20, 14, 8)\n        ),\n        arrayOf(\n            intArrayOf(127, 77, 53, 32),\n            intArrayOf(101, 61, 42, 26),\n            intArrayOf(77, 47, 32, 20),\n            intArrayOf(58, 35, 24, 15)\n        ),\n        arrayOf(\n            intArrayOf(187, 114, 78, 48),\n            intArrayOf(149, 90, 62, 38),\n            intArrayOf(111, 67, 46, 28),\n            intArrayOf(82, 50, 34, 21)\n        ),\n        arrayOf(\n            intArrayOf(255, 154, 106, 65),\n            intArrayOf(202, 122, 84, 52),\n            intArrayOf(144, 87, 60, 37),\n            intArrayOf(106, 64, 44, 27)\n        ),\n        arrayOf(\n            intArrayOf(322, 195, 134, 82),\n            intArrayOf(255, 154, 106, 65),\n            intArrayOf(178, 108, 74, 45),\n            intArrayOf(139, 84, 58, 36)\n        ),\n        arrayOf(\n            intArrayOf(370, 224, 154, 95),\n            intArrayOf(293, 178, 122, 75),\n            intArrayOf(207, 125, 86, 53),\n            intArrayOf(154, 93, 64, 39)\n        ),\n        arrayOf(\n            intArrayOf(461, 279, 192, 118),\n            intArrayOf(365, 221, 152, 93),\n            intArrayOf(259, 157, 108, 66),\n            intArrayOf(202, 122, 84, 52)\n        ),\n        arrayOf(\n            intArrayOf(552, 335, 230, 141),\n            intArrayOf(432, 262, 180, 111),\n            intArrayOf(312, 189, 130, 80),\n            intArrayOf(235, 143, 98, 60)\n        ),\n        arrayOf(\n            intArrayOf(652, 395, 271, 167),\n            intArrayOf(513, 311, 213, 131),\n            intArrayOf(364, 221, 151, 93),\n            intArrayOf(288, 174, 119, 74)\n        ),\n        arrayOf(\n            intArrayOf(772, 468, 321, 198),\n            intArrayOf(604, 366, 251, 155),\n            intArrayOf(427, 259, 177, 109),\n            intArrayOf(331, 200, 137, 85)\n        ),\n        arrayOf(\n            intArrayOf(883, 535, 367, 226),\n            intArrayOf(691, 419, 287, 177),\n            intArrayOf(489, 296, 203, 125),\n            intArrayOf(374, 227, 155, 96)\n        ),\n        arrayOf(\n            intArrayOf(1022, 619, 425, 262),\n            intArrayOf(796, 483, 331, 204),\n            intArrayOf(580, 352, 241, 149),\n            intArrayOf(427, 259, 177, 109)\n        ),\n        arrayOf(\n            intArrayOf(1101, 667, 458, 282),\n            intArrayOf(871, 528, 362, 223),\n            intArrayOf(621, 376, 258, 159),\n            intArrayOf(468, 283, 194, 120)\n        ),\n        arrayOf(\n            intArrayOf(1250, 758, 520, 320),\n            intArrayOf(991, 600, 412, 254),\n            intArrayOf(703, 426, 292, 180),\n            intArrayOf(530, 321, 220, 136)\n        ),\n        arrayOf(\n            intArrayOf(1408, 854, 586, 361),\n            intArrayOf(1082, 656, 450, 277),\n            intArrayOf(775, 470, 322, 198),\n            intArrayOf(602, 365, 250, 154)\n        ),\n        arrayOf(\n            intArrayOf(1548, 938, 644, 397),\n            intArrayOf(1212, 734, 504, 310),\n            intArrayOf(876, 531, 364, 224),\n            intArrayOf(674, 408, 280, 173)\n        ),\n        arrayOf(\n            intArrayOf(1725, 1046, 718, 442),\n            intArrayOf(1346, 816, 560, 345),\n            intArrayOf(948, 574, 394, 243),\n            intArrayOf(746, 452, 310, 191)\n        ),\n        arrayOf(\n            intArrayOf(1903, 1153, 792, 488),\n            intArrayOf(1500, 909, 624, 384),\n            intArrayOf(1063, 644, 442, 272),\n            intArrayOf(813, 493, 338, 208)\n        ),\n        arrayOf(\n            intArrayOf(2061, 1249, 858, 528),\n            intArrayOf(1600, 970, 666, 410),\n            intArrayOf(1159, 702, 482, 297),\n            intArrayOf(919, 557, 382, 235)\n        ),\n        arrayOf(\n            intArrayOf(2232, 1352, 929, 572),\n            intArrayOf(1708, 1035, 711, 438),\n            intArrayOf(1224, 742, 509, 314),\n            intArrayOf(969, 587, 403, 248)\n        ),\n        arrayOf(\n            intArrayOf(2409, 1460, 1003, 618),\n            intArrayOf(1872, 1134, 779, 480),\n            intArrayOf(1358, 823, 565, 348),\n            intArrayOf(1056, 640, 439, 270)\n        ),\n        arrayOf(\n            intArrayOf(2620, 1588, 1091, 672),\n            intArrayOf(2059, 1248, 857, 528),\n            intArrayOf(1468, 890, 611, 376),\n            intArrayOf(1108, 672, 461, 284)\n        ),\n        arrayOf(\n            intArrayOf(2812, 1704, 1171, 721),\n            intArrayOf(2188, 1326, 911, 561),\n            intArrayOf(1588, 963, 661, 407),\n            intArrayOf(1228, 744, 511, 315)\n        ),\n        arrayOf(\n            intArrayOf(3057, 1853, 1273, 784),\n            intArrayOf(2395, 1451, 997, 614),\n            intArrayOf(1718, 1041, 715, 440),\n            intArrayOf(1286, 779, 535, 330)\n        ),\n        arrayOf(\n            intArrayOf(3283, 1990, 1367, 842),\n            intArrayOf(2544, 1542, 1059, 652),\n            intArrayOf(1804, 1094, 751, 462),\n            intArrayOf(1425, 864, 593, 365)\n        ),\n        arrayOf(\n            intArrayOf(3517, 2132, 1465, 902),\n            intArrayOf(2701, 1637, 1125, 692),\n            intArrayOf(1933, 1172, 805, 496),\n            intArrayOf(1501, 910, 625, 385)\n        ),\n        arrayOf(\n            intArrayOf(3669, 2223, 1528, 940),\n            intArrayOf(2857, 1732, 1190, 732),\n            intArrayOf(2085, 1263, 868, 534),\n            intArrayOf(1581, 958, 658, 405)\n        ),\n        arrayOf(\n            intArrayOf(3909, 2369, 1628, 1002),\n            intArrayOf(3035, 1839, 1264, 778),\n            intArrayOf(2181, 1322, 908, 559),\n            intArrayOf(1677, 1016, 698, 430)\n        ),\n        arrayOf(\n            intArrayOf(4158, 2520, 1732, 1066),\n            intArrayOf(3289, 1994, 1370, 843),\n            intArrayOf(2358, 1429, 982, 604),\n            intArrayOf(1782, 1080, 742, 457)\n        ),\n        arrayOf(\n            intArrayOf(4417, 2677, 1840, 1132),\n            intArrayOf(3486, 2113, 1452, 894),\n            intArrayOf(2473, 1499, 1030, 634),\n            intArrayOf(1897, 1150, 790, 486)\n        ),\n        arrayOf(\n            intArrayOf(4686, 2840, 1952, 1201),\n            intArrayOf(3693, 2238, 1538, 947),\n            intArrayOf(2670, 1618, 1112, 684),\n            intArrayOf(2022, 1226, 842, 518)\n        ),\n        arrayOf(\n            intArrayOf(4965, 3009, 2068, 1273),\n            intArrayOf(3909, 2369, 1628, 1002),\n            intArrayOf(2805, 1700, 1168, 719),\n            intArrayOf(2157, 1307, 898, 553)\n        ),\n        arrayOf(\n            intArrayOf(5253, 3183, 2188, 1347),\n            intArrayOf(4134, 2506, 1722, 1060),\n            intArrayOf(2949, 1787, 1228, 756),\n            intArrayOf(2301, 1394, 958, 590)\n        )\n    )\n\n    fun getMaxLength(\n        typeNumber: Int,\n        dataType: QRCodeDataType,\n        errorCorrectionLevel: ErrorCorrectionLevel\n    ): Int =\n        MAX_LENGTH[typeNumber - 1][errorCorrectionLevel.ordinal][dataType.ordinal]\n\n    fun getErrorCorrectPolynomial(errorCorrectLength: Int): Polynomial {\n        var a = Polynomial(intArrayOf(1))\n        for (i in 0 until errorCorrectLength) {\n            a = a.multiply(Polynomial(intArrayOf(1, QRMath.gexp(i))))\n        }\n        return a\n    }\n\n    /**\n     * Each Mask Pattern [applies a different formula](https://www.thonky.com/qr-code-tutorial/mask-patterns).\n     */\n    fun getMask(maskPattern: MaskPattern, i: Int, j: Int): Boolean =\n        when (maskPattern) {\n            PATTERN000 -> (i + j) % 2 == 0\n            PATTERN001 -> i % 2 == 0\n            PATTERN010 -> j % 3 == 0\n            PATTERN011 -> (i + j) % 3 == 0\n            PATTERN100 -> (i / 2 + j / 3) % 2 == 0\n            PATTERN101 -> (i * j) % 2 + (i * j) % 3 == 0\n            PATTERN110 -> ((i * j) % 2 + (i * j) % 3) % 2 == 0\n            PATTERN111 -> ((i * j) % 3 + (i + j) % 2) % 2 == 0\n        }\n\n    /**\n     * Returns a suitable [QRCodeDataType] to the given input String based on a simple matching.\n     *\n     * @see QRCodeDataType\n     */\n    fun getDataType(s: String): QRCodeDataType =\n        if (isAlphaNum(s)) {\n            if (isNumber(s)) {\n                QRCodeDataType.NUMBERS\n            } else {\n                QRCodeDataType.UPPER_ALPHA_NUM\n            }\n        } else {\n            QRCodeDataType.DEFAULT\n        }\n\n    private fun isNumber(s: String) = s.matches(Regex(\"^\\\\d+$\"))\n    private fun isAlphaNum(s: String) = s.matches(Regex(\"^[0-9A-Z $%*+\\\\-./:]+$\"))\n\n    private const val G15 = (\n            1 shl 10 or (1 shl 8) or (1 shl 5)\n                    or (1 shl 4) or (1 shl 2) or (1 shl 1) or (1 shl 0)\n            )\n    private const val G18 = (\n            1 shl 12 or (1 shl 11) or (1 shl 10)\n                    or (1 shl 9) or (1 shl 8) or (1 shl 5) or (1 shl 2) or (1 shl 0)\n            )\n    private const val G15_MASK = (\n            1 shl 14 or (1 shl 12) or (1 shl 10)\n                    or (1 shl 4) or (1 shl 1)\n            )\n\n    fun getBCHTypeInfo(data: Int): Int {\n        var d = data shl 10\n        while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {\n            d = d xor (G15 shl getBCHDigit(d) - getBCHDigit(G15))\n        }\n        return data shl 10 or d xor G15_MASK\n    }\n\n    fun getBCHTypeNumber(data: Int): Int {\n        var d = data shl 12\n        while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {\n            d = d xor (G18 shl getBCHDigit(d) - getBCHDigit(G18))\n        }\n        return data shl 12 or d\n    }\n\n    private fun getBCHDigit(data: Int): Int {\n        var i = data\n        var digit = 0\n        while (i != 0) {\n            digit++\n            i = i ushr 1\n        }\n        return digit\n    }\n}\n"
  },
  {
    "path": "lib/qrose/src/main/java/io/github/alexzhirkevich/qrose/qrcode/internals/RSBlock.kt",
    "content": "package io.github.alexzhirkevich.qrose.qrcode.internals\n\nimport io.github.alexzhirkevich.qrose.qrcode.ErrorCorrectionLevel\n\n/**\n * Rewritten in Kotlin from the [original (GitHub)](https://github.com/kazuhikoarase/qrcode-generator/blob/master/java/src/main/java/com/d_project/qrcode/RSBlock.java)\n *\n * @author Rafael Lins - g0dkar\n * @author Kazuhiko Arase - kazuhikoarase\n */\ninternal class RSBlock(val totalCount: Int, val dataCount: Int) {\n    companion object {\n        private val RS_BLOCK_TABLE = arrayOf(\n            intArrayOf(1, 26, 19),\n            intArrayOf(1, 26, 16),\n            intArrayOf(1, 26, 13),\n            intArrayOf(1, 26, 9),\n            intArrayOf(1, 44, 34),\n            intArrayOf(1, 44, 28),\n            intArrayOf(1, 44, 22),\n            intArrayOf(1, 44, 16),\n            intArrayOf(1, 70, 55),\n            intArrayOf(1, 70, 44),\n            intArrayOf(2, 35, 17),\n            intArrayOf(2, 35, 13),\n            intArrayOf(1, 100, 80),\n            intArrayOf(2, 50, 32),\n            intArrayOf(2, 50, 24),\n            intArrayOf(4, 25, 9),\n            intArrayOf(1, 134, 108),\n            intArrayOf(2, 67, 43),\n            intArrayOf(2, 33, 15, 2, 34, 16),\n            intArrayOf(2, 33, 11, 2, 34, 12),\n            intArrayOf(2, 86, 68),\n            intArrayOf(4, 43, 27),\n            intArrayOf(4, 43, 19),\n            intArrayOf(4, 43, 15),\n            intArrayOf(2, 98, 78),\n            intArrayOf(4, 49, 31),\n            intArrayOf(2, 32, 14, 4, 33, 15),\n            intArrayOf(4, 39, 13, 1, 40, 14),\n            intArrayOf(2, 121, 97),\n            intArrayOf(2, 60, 38, 2, 61, 39),\n            intArrayOf(4, 40, 18, 2, 41, 19),\n            intArrayOf(4, 40, 14, 2, 41, 15),\n            intArrayOf(2, 146, 116),\n            intArrayOf(3, 58, 36, 2, 59, 37),\n            intArrayOf(4, 36, 16, 4, 37, 17),\n            intArrayOf(4, 36, 12, 4, 37, 13),\n            intArrayOf(2, 86, 68, 2, 87, 69),\n            intArrayOf(4, 69, 43, 1, 70, 44),\n            intArrayOf(6, 43, 19, 2, 44, 20),\n            intArrayOf(6, 43, 15, 2, 44, 16),\n            intArrayOf(4, 101, 81),\n            intArrayOf(1, 80, 50, 4, 81, 51),\n            intArrayOf(4, 50, 22, 4, 51, 23),\n            intArrayOf(3, 36, 12, 8, 37, 13),\n            intArrayOf(2, 116, 92, 2, 117, 93),\n            intArrayOf(6, 58, 36, 2, 59, 37),\n            intArrayOf(4, 46, 20, 6, 47, 21),\n            intArrayOf(7, 42, 14, 4, 43, 15),\n            intArrayOf(4, 133, 107),\n            intArrayOf(8, 59, 37, 1, 60, 38),\n            intArrayOf(8, 44, 20, 4, 45, 21),\n            intArrayOf(12, 33, 11, 4, 34, 12),\n            intArrayOf(3, 145, 115, 1, 146, 116),\n            intArrayOf(4, 64, 40, 5, 65, 41),\n            intArrayOf(11, 36, 16, 5, 37, 17),\n            intArrayOf(11, 36, 12, 5, 37, 13),\n            intArrayOf(5, 109, 87, 1, 110, 88),\n            intArrayOf(5, 65, 41, 5, 66, 42),\n            intArrayOf(5, 54, 24, 7, 55, 25),\n            intArrayOf(11, 36, 12, 7, 37, 13),\n            intArrayOf(5, 122, 98, 1, 123, 99),\n            intArrayOf(7, 73, 45, 3, 74, 46),\n            intArrayOf(15, 43, 19, 2, 44, 20),\n            intArrayOf(3, 45, 15, 13, 46, 16),\n            intArrayOf(1, 135, 107, 5, 136, 108),\n            intArrayOf(10, 74, 46, 1, 75, 47),\n            intArrayOf(1, 50, 22, 15, 51, 23),\n            intArrayOf(2, 42, 14, 17, 43, 15),\n            intArrayOf(5, 150, 120, 1, 151, 121),\n            intArrayOf(9, 69, 43, 4, 70, 44),\n            intArrayOf(17, 50, 22, 1, 51, 23),\n            intArrayOf(2, 42, 14, 19, 43, 15),\n            intArrayOf(3, 141, 113, 4, 142, 114),\n            intArrayOf(3, 70, 44, 11, 71, 45),\n            intArrayOf(17, 47, 21, 4, 48, 22),\n            intArrayOf(9, 39, 13, 16, 40, 14),\n            intArrayOf(3, 135, 107, 5, 136, 108),\n            intArrayOf(3, 67, 41, 13, 68, 42),\n            intArrayOf(15, 54, 24, 5, 55, 25),\n            intArrayOf(15, 43, 15, 10, 44, 16),\n            intArrayOf(4, 144, 116, 4, 145, 117),\n            intArrayOf(17, 68, 42),\n            intArrayOf(17, 50, 22, 6, 51, 23),\n            intArrayOf(19, 46, 16, 6, 47, 17),\n            intArrayOf(2, 139, 111, 7, 140, 112),\n            intArrayOf(17, 74, 46),\n            intArrayOf(7, 54, 24, 16, 55, 25),\n            intArrayOf(34, 37, 13),\n            intArrayOf(4, 151, 121, 5, 152, 122),\n            intArrayOf(4, 75, 47, 14, 76, 48),\n            intArrayOf(11, 54, 24, 14, 55, 25),\n            intArrayOf(16, 45, 15, 14, 46, 16),\n            intArrayOf(6, 147, 117, 4, 148, 118),\n            intArrayOf(6, 73, 45, 14, 74, 46),\n            intArrayOf(11, 54, 24, 16, 55, 25),\n            intArrayOf(30, 46, 16, 2, 47, 17),\n            intArrayOf(8, 132, 106, 4, 133, 107),\n            intArrayOf(8, 75, 47, 13, 76, 48),\n            intArrayOf(7, 54, 24, 22, 55, 25),\n            intArrayOf(22, 45, 15, 13, 46, 16),\n            intArrayOf(10, 142, 114, 2, 143, 115),\n            intArrayOf(19, 74, 46, 4, 75, 47),\n            intArrayOf(28, 50, 22, 6, 51, 23),\n            intArrayOf(33, 46, 16, 4, 47, 17),\n            intArrayOf(8, 152, 122, 4, 153, 123),\n            intArrayOf(22, 73, 45, 3, 74, 46),\n            intArrayOf(8, 53, 23, 26, 54, 24),\n            intArrayOf(12, 45, 15, 28, 46, 16),\n            intArrayOf(3, 147, 117, 10, 148, 118),\n            intArrayOf(3, 73, 45, 23, 74, 46),\n            intArrayOf(4, 54, 24, 31, 55, 25),\n            intArrayOf(11, 45, 15, 31, 46, 16),\n            intArrayOf(7, 146, 116, 7, 147, 117),\n            intArrayOf(21, 73, 45, 7, 74, 46),\n            intArrayOf(1, 53, 23, 37, 54, 24),\n            intArrayOf(19, 45, 15, 26, 46, 16),\n            intArrayOf(5, 145, 115, 10, 146, 116),\n            intArrayOf(19, 75, 47, 10, 76, 48),\n            intArrayOf(15, 54, 24, 25, 55, 25),\n            intArrayOf(23, 45, 15, 25, 46, 16),\n            intArrayOf(13, 145, 115, 3, 146, 116),\n            intArrayOf(2, 74, 46, 29, 75, 47),\n            intArrayOf(42, 54, 24, 1, 55, 25),\n            intArrayOf(23, 45, 15, 28, 46, 16),\n            intArrayOf(17, 145, 115),\n            intArrayOf(10, 74, 46, 23, 75, 47),\n            intArrayOf(10, 54, 24, 35, 55, 25),\n            intArrayOf(19, 45, 15, 35, 46, 16),\n            intArrayOf(17, 145, 115, 1, 146, 116),\n            intArrayOf(14, 74, 46, 21, 75, 47),\n            intArrayOf(29, 54, 24, 19, 55, 25),\n            intArrayOf(11, 45, 15, 46, 46, 16),\n            intArrayOf(13, 145, 115, 6, 146, 116),\n            intArrayOf(14, 74, 46, 23, 75, 47),\n            intArrayOf(44, 54, 24, 7, 55, 25),\n            intArrayOf(59, 46, 16, 1, 47, 17),\n            intArrayOf(12, 151, 121, 7, 152, 122),\n            intArrayOf(12, 75, 47, 26, 76, 48),\n            intArrayOf(39, 54, 24, 14, 55, 25),\n            intArrayOf(22, 45, 15, 41, 46, 16),\n            intArrayOf(6, 151, 121, 14, 152, 122),\n            intArrayOf(6, 75, 47, 34, 76, 48),\n            intArrayOf(46, 54, 24, 10, 55, 25),\n            intArrayOf(2, 45, 15, 64, 46, 16),\n            intArrayOf(17, 152, 122, 4, 153, 123),\n            intArrayOf(29, 74, 46, 14, 75, 47),\n            intArrayOf(49, 54, 24, 10, 55, 25),\n            intArrayOf(24, 45, 15, 46, 46, 16),\n            intArrayOf(4, 152, 122, 18, 153, 123),\n            intArrayOf(13, 74, 46, 32, 75, 47),\n            intArrayOf(48, 54, 24, 14, 55, 25),\n            intArrayOf(42, 45, 15, 32, 46, 16),\n            intArrayOf(20, 147, 117, 4, 148, 118),\n            intArrayOf(40, 75, 47, 7, 76, 48),\n            intArrayOf(43, 54, 24, 22, 55, 25),\n            intArrayOf(10, 45, 15, 67, 46, 16),\n            intArrayOf(19, 148, 118, 6, 149, 119),\n            intArrayOf(18, 75, 47, 31, 76, 48),\n            intArrayOf(34, 54, 24, 34, 55, 25),\n            intArrayOf(20, 45, 15, 61, 46, 16)\n        )\n\n        fun getRSBlocks(\n            typeNumber: Int,\n            errorCorrectionLevel: ErrorCorrectionLevel\n        ): Array<RSBlock> =\n            RS_BLOCK_TABLE[(typeNumber - 1) * 4 + errorCorrectionLevel.ordinal]\n                .let { rsBlock ->\n                    if (rsBlock.size == 3) {\n                        val block = RSBlock(rsBlock[1], rsBlock[2])\n                        Array(rsBlock[0]) { block }\n                    } else {\n                        val blocksSize = rsBlock[0] + rsBlock[3]\n                        val firstBlock = RSBlock(rsBlock[1], rsBlock[2])\n                        val secondBlock = RSBlock(rsBlock[4], rsBlock[5])\n\n                        Array(blocksSize) {\n                            if (it < rsBlock[0]) {\n                                firstBlock\n                            } else {\n                                secondBlock\n                            }\n                        }\n                    }\n                }\n    }\n}\n"
  },
  {
    "path": "lib/snowfall/.gitignore",
    "content": "/build"
  },
  {
    "path": "lib/snowfall/build.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\nplugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"com.t8rin.snowfall\""
  },
  {
    "path": "lib/snowfall/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<manifest />"
  },
  {
    "path": "lib/snowfall/src/main/java/com/t8rin/snowfall/Constants.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.snowfall\n\ninternal object Constants {\n    internal const val angleRange = 0.1f\n    internal const val angleDivisor = 10000.0f\n    internal const val angleSeed = 100.0f\n    internal const val baseFrameDurationMillis = 16\n    internal const val snowflakeDensity = 0.05\n    internal const val defaultAlpha = 0.65f\n\n    internal val incrementRange = 0.2f..0.8f\n    internal val sizeRange = 20f..40f\n    internal val angleSeedRange = -angleSeed..angleSeed\n}"
  },
  {
    "path": "lib/snowfall/src/main/java/com/t8rin/snowfall/SnowAnimState.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.snowfall\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.drawscope.ContentDrawScope\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.snowfall.Constants.angleRange\nimport com.t8rin.snowfall.Constants.angleSeed\nimport com.t8rin.snowfall.Constants.incrementRange\nimport com.t8rin.snowfall.Constants.sizeRange\nimport com.t8rin.snowfall.types.AnimType\nimport kotlin.math.PI\nimport kotlin.math.roundToInt\n\ninternal data class SnowAnimState(\n    var tickNanos: Long,\n    val snowflakes: List<Snowflake>,\n    val painters: List<Painter>,\n    val animType: AnimType,\n    val colors: List<Color>,\n    val density: Double,\n    val alpha: Float,\n) {\n    constructor(\n        tick: Long,\n        canvasSize: IntSize,\n        painters: List<Painter>,\n        animType: AnimType,\n        colors: List<Color>,\n        density: Double,\n        alpha: Float\n    ) : this(\n        tickNanos = tick,\n        snowflakes = createSnowFlakes(\n            flakesProvider = painters,\n            canvasSize = canvasSize,\n            animType = animType,\n            colors = colors,\n            density = density,\n            alpha = alpha\n        ),\n        painters = painters,\n        animType = animType,\n        colors = colors,\n        density = density,\n        alpha = alpha\n    )\n\n    fun draw(contentDrawScope: ContentDrawScope) {\n        snowflakes.forEach {\n            it.draw(contentDrawScope)\n        }\n    }\n\n    fun resize(newSize: IntSize) = copy(\n        snowflakes = createSnowFlakes(\n            flakesProvider = painters,\n            canvasSize = newSize,\n            animType = animType,\n            colors = colors,\n            density = density,\n            alpha = alpha\n        )\n    )\n\n    companion object {\n\n        fun createSnowFlakes(\n            flakesProvider: List<Painter>,\n            canvasSize: IntSize,\n            animType: AnimType,\n            colors: List<Color>,\n            density: Double,\n            alpha: Float,\n        ): List<Snowflake> =\n            when (animType) {\n                AnimType.Falling -> createFallingSnowflakes(\n                    canvasSize = canvasSize,\n                    painters = flakesProvider,\n                    colors = colors,\n                    snowflakeDensity = density,\n                    alpha = alpha\n                )\n\n                AnimType.Melting -> createMeltingSnowflakes(\n                    canvasSize = canvasSize,\n                    painters = flakesProvider,\n                    colors = colors,\n                    snowflakeDensity = density,\n                )\n            }\n\n        private fun createMeltingSnowflakes(\n            canvasSize: IntSize,\n            painters: List<Painter>,\n            colors: List<Color>,\n            snowflakeDensity: Double,\n        ): List<MeltingSnowflake> {\n            if (canvasSize.height == 0 || canvasSize.width == 0 || snowflakeDensity == 0.0) {\n                return emptyList()\n            }\n\n            val canvasArea = canvasSize.width * canvasSize.height\n            val normalizedDensity = snowflakeDensity.coerceIn(0.0..1.0) / 2000.0\n            val count = (canvasArea * normalizedDensity).roundToInt()\n            val snowflakesCount = count.coerceIn(painters.size.coerceAtMost(count), count)\n\n            return List(snowflakesCount) {\n                MeltingSnowflake(\n                    incrementFactor = incrementRange.random(),\n                    canvasSize = canvasSize,\n                    maxAlpha = (0.1f..0.7f).random(),\n                    painter = painters[it % painters.size],\n                    initialPosition = canvasSize.randomPosition(),\n                    color = colors.random(),\n                )\n            }\n        }\n\n        private fun createFallingSnowflakes(\n            canvasSize: IntSize,\n            painters: List<Painter>,\n            colors: List<Color>,\n            snowflakeDensity: Double,\n            alpha: Float,\n        ): List<FallingSnowflake> {\n            val canvasArea = canvasSize.width * canvasSize.height\n            val normalizedDensity = snowflakeDensity.coerceIn(0.0..1.0) / 1000.0\n            val snowflakesCount = (canvasArea * normalizedDensity).roundToInt()\n\n            return List(snowflakesCount) {\n                FallingSnowflake(\n                    incrementFactor = incrementRange.random(),\n                    size = sizeRange.random(),\n                    canvasSize = canvasSize,\n                    initialPosition = canvasSize.randomPosition(),\n                    angle = angleSeed.random() / angleSeed * angleRange + (PI / 2.0) - (angleRange / 2.0),\n                    painter = painters[it % painters.size],\n                    color = colors.random(),\n                    alpha = alpha,\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "lib/snowfall/src/main/java/com/t8rin/snowfall/Snowfall.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.snowfall\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.withFrameNanos\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.unit.IntSize\nimport androidx.lifecycle.Lifecycle\nimport com.t8rin.snowfall.Constants.defaultAlpha\nimport com.t8rin.snowfall.Constants.snowflakeDensity\nimport com.t8rin.snowfall.types.AnimType\nimport com.t8rin.snowfall.types.FlakeType\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.isActive\nimport kotlin.time.Duration.Companion.nanoseconds\n\n/**\n * Creates flakes falling animation base on `FlakeType` param.\n * @param type type of flake.\n * @param colors list of Colors for Flakes\n * @param density density of Flakes must be between 0.0 (no Flakes) or 1.0 (a lot of Flakes). Default is 0.05\n * @param alpha transparency of the falling flakes\n *\n */\nfun Modifier.snowfall(\n    type: FlakeType = FlakeType.Snowflakes,\n    colors: List<Color>,\n    density: Double = snowflakeDensity,\n    alpha: Float = defaultAlpha,\n): Modifier =\n    letItSnow(\n        flakeType = type,\n        animType = AnimType.Falling, colors = colors,\n        density = density,\n        alpha = alpha\n    )\n\n/**\n * Creates flakes falling animation base on `FlakeType` param.\n * @param type type of flake.\n * @param color single Color for Flakes\n * @param density density of Flakes must be between 0.0 (no Flakes) or 1.0 (a lot of Flakes). Default is 0.05\n * @param alpha transparency of the falling flakes\n *\n */\nfun Modifier.snowfall(\n    type: FlakeType = FlakeType.Snowflakes,\n    color: Color = Color.Unspecified,\n    density: Double = snowflakeDensity,\n    alpha: Float = defaultAlpha,\n): Modifier =\n    letItSnow(\n        flakeType = type,\n        animType = AnimType.Falling, colors = listOf(color),\n        density = density,\n        alpha = alpha\n    )\n\n/**\n * Creates flakes melting animation base on `FlakeType` param.\n * @param type - type of flake.\n * @param colors - list of Colors for Flakes\n * @param density - density of Flakes must be between 0.0 (no Flakes) or 1.0 (a lot of Flakes). Default is 0.05\n *\n */\nfun Modifier.snowmelt(\n    type: FlakeType = FlakeType.Snowflakes,\n    colors: List<Color>,\n    density: Double = snowflakeDensity,\n): Modifier =\n    letItSnow(type, AnimType.Melting, colors = colors, density = density)\n\n/**\n * Creates flakes melting animation base on `FlakeType` param.\n * @param type - type of flake.\n * @param color - single Color for Flakes\n * @param density - density of Flakes must be between 0.0 (no Flakes) or 1.0 (a lot of Flakes). Default is 0.05\n *\n */\nfun Modifier.snowmelt(\n    type: FlakeType = FlakeType.Snowflakes,\n    color: Color = Color.Unspecified,\n    density: Double = snowflakeDensity,\n): Modifier =\n    letItSnow(type, AnimType.Melting, colors = listOf(color), density = density)\n\n\nprivate fun Modifier.letItSnow(\n    flakeType: FlakeType,\n    animType: AnimType,\n    colors: List<Color>,\n    density: Double,\n    alpha: Float = 1f,\n) = composed {\n    val flakes = when (flakeType) {\n        is FlakeType.Custom -> flakeType.data\n        is FlakeType.Snowflakes -> getDefaultFlakes()\n    }\n    var snowAnimState by remember {\n        mutableStateOf(\n            SnowAnimState(\n                tick = -1,\n                canvasSize = IntSize(0, 0),\n                painters = flakes,\n                animType = animType,\n                colors = colors,\n                density = density,\n                alpha = alpha,\n            )\n        )\n    }\n    val lifecycleOwner = androidx.lifecycle.compose.LocalLifecycleOwner.current\n\n    LaunchedEffect(Unit) {\n        while (isActive) {\n            if (lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {\n                withFrameNanos { frameTimeNanos ->\n                    val elapsedMillis =\n                        (frameTimeNanos - snowAnimState.tickNanos).nanoseconds.inWholeMilliseconds\n                    val isFirstRun = snowAnimState.tickNanos < 0\n                    snowAnimState.tickNanos = frameTimeNanos\n                    if (isFirstRun) return@withFrameNanos 0\n                    snowAnimState.snowflakes.forEach {\n                        it.update(elapsedMillis)\n                    }\n                    return@withFrameNanos frameTimeNanos\n                }\n            } else {\n                withFrameNanos { frameTimeNanos ->\n                    snowAnimState.tickNanos = frameTimeNanos\n                }\n            }\n            delay(8L)\n        }\n    }\n    onSizeChanged { newSize ->\n        snowAnimState = snowAnimState.resize(newSize)\n    }\n        .clipToBounds()\n        .drawWithContent {\n            drawContent()\n            snowAnimState.draw(this)\n        }\n}\n\n@Composable\nprivate fun getDefaultFlakes(): List<Painter> = listOf(\n    painterResource(id = R.drawable.ic_flake_1),\n    painterResource(id = R.drawable.ic_flake_2),\n    painterResource(id = R.drawable.ic_flake_3),\n    painterResource(id = R.drawable.ic_flake_4),\n    painterResource(id = R.drawable.ic_flake_5),\n    painterResource(id = R.drawable.ic_flake_6),\n    painterResource(id = R.drawable.ic_flake_7),\n    painterResource(id = R.drawable.ic_flake_8),\n    painterResource(id = R.drawable.ic_flake_9),\n    painterResource(id = R.drawable.ic_flake_10),\n)"
  },
  {
    "path": "lib/snowfall/src/main/java/com/t8rin/snowfall/Snowflake.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.snowfall\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableDoubleStateOf\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.drawscope.ContentDrawScope\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.unit.IntSize\nimport com.t8rin.snowfall.Constants.angleDivisor\nimport com.t8rin.snowfall.Constants.angleSeedRange\nimport com.t8rin.snowfall.Constants.baseFrameDurationMillis\nimport kotlin.math.cos\nimport kotlin.math.sin\n\ninternal interface Snowflake {\n    fun update(elapsedMillis: Long)\n    fun draw(contentDrawScope: ContentDrawScope)\n}\n\ninternal class MeltingSnowflake(\n    private val initialPosition: Offset,\n    private val incrementFactor: Float,\n    private val canvasSize: IntSize,\n    private val maxAlpha: Float,\n    private val painter: Painter,\n    private val color: Color,\n) : Snowflake {\n\n    init {\n        require(maxAlpha in 0.1..1.0)\n    }\n\n    private var position by mutableStateOf(initialPosition)\n    private var alpha by mutableFloatStateOf(0.001f)\n    private var isIncreasing by mutableStateOf(true)\n\n    override fun update(elapsedMillis: Long) {\n        val increment = incrementFactor * (elapsedMillis / baseFrameDurationMillis) / 100f\n        alpha = (if (isIncreasing) {\n            alpha + increment\n        } else {\n            alpha - increment\n        }).coerceIn(0f, maxAlpha)\n\n        if (alpha == maxAlpha) {\n            isIncreasing = false\n        }\n\n        if (alpha == 0f) {\n            isIncreasing = true\n            alpha = 0.001f\n            position = canvasSize.randomPosition()\n        }\n    }\n\n    override fun draw(contentDrawScope: ContentDrawScope) {\n        with(contentDrawScope) {\n            translate(\n                left = position.x,\n                top = position.y\n            ) {\n                with(painter) {\n                    draw(\n                        size = intrinsicSize,\n                        alpha = alpha,\n                        colorFilter = if (color == Color.Unspecified) null else ColorFilter.tint(\n                            color\n                        )\n                    )\n                }\n            }\n        }\n    }\n}\n\ninternal class FallingSnowflake(\n    private val incrementFactor: Float,\n    private val size: Float,\n    private val canvasSize: IntSize,\n    initialPosition: Offset,\n    angle: Double,\n    private val painter: Painter,\n    private val color: Color,\n    private val alpha: Float,\n) : Snowflake {\n    private val baseSpeedPxAt60Fps = 5\n    private var position by mutableStateOf(initialPosition)\n    private var angle by mutableDoubleStateOf(angle)\n\n    override fun update(elapsedMillis: Long) {\n        val increment =\n            incrementFactor * (elapsedMillis / baseFrameDurationMillis) * baseSpeedPxAt60Fps\n        val xDelta = (increment * cos(angle)).toFloat()\n        val yDelta = (increment * sin(angle)).toFloat()\n        position = Offset(position.x + xDelta, position.y + yDelta)\n        angle += angleSeedRange.random() / angleDivisor\n\n        if (position.y > canvasSize.height + size) {\n            position =\n                Offset(canvasSize.width.random().toFloat(), -size - painter.intrinsicSize.height)\n        }\n    }\n\n    override fun draw(contentDrawScope: ContentDrawScope) {\n        with(contentDrawScope) {\n            translate(\n                position.x,\n                position.y\n            ) {\n                with(painter) {\n                    draw(\n                        size = intrinsicSize,\n                        alpha = alpha,\n                        colorFilter = if (color == Color.Unspecified) null else ColorFilter.tint(\n                            color\n                        )\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "lib/snowfall/src/main/java/com/t8rin/snowfall/Utils.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.snowfall\n\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.unit.IntSize\nimport java.util.concurrent.ThreadLocalRandom\n\n\ninternal fun ClosedRange<Float>.random() =\n    ThreadLocalRandom.current().nextFloat() * (endInclusive - start) + start\n\ninternal fun Float.random() =\n    ThreadLocalRandom.current().nextFloat() * this\n\ninternal fun Int.random() =\n    ThreadLocalRandom.current().nextInt(this)\n\ninternal fun IntSize.randomPosition() =\n    Offset(width.random().toFloat(), height.random().toFloat())"
  },
  {
    "path": "lib/snowfall/src/main/java/com/t8rin/snowfall/types/AnimType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.snowfall.types\n\ninternal enum class AnimType {\n    Falling,\n    Melting\n}"
  },
  {
    "path": "lib/snowfall/src/main/java/com/t8rin/snowfall/types/FlakeType.kt",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\npackage com.t8rin.snowfall.types\n\nimport androidx.compose.ui.graphics.painter.Painter\n\n/**\n * Type of flake used for animation.\n */\nsealed interface FlakeType {\n    data object Snowflakes : FlakeType\n    class Custom(val data: List<Painter>) : FlakeType\n}"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_1.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.997,2V13.04\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.002,6.376L15.249,3.129\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.002,9.161L15.249,5.914\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.702,3.144L11.948,6.39\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.702,5.929L11.948,9.175\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.699,16.562L13.2,10.941\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.463,14.33L3.015,13.189\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.859,12.912L5.412,11.771\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.361,18.816L7.502,14.369\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.758,17.398L9.899,12.951\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.347,16.485L10.797,10.946\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.559,14.294L17.738,18.731\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.15,12.896L15.329,17.334\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M21.011,13.061L16.573,14.24\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.602,11.663L14.164,12.843\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.003,21.295V10.255\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.998,16.919L8.751,20.165\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.998,14.134L8.751,17.381\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.298,20.151L12.052,16.904\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.298,17.366L12.052,14.12\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.301,6.732L10.8,12.354\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.538,8.965L20.985,10.106\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.141,10.383L18.588,11.524\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.639,4.478L16.498,8.926\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.242,5.897L14.101,10.344\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.654,6.809L13.203,12.348\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.441,9.001L6.262,4.563\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.85,10.398L8.671,5.961\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M2.989,10.234L7.427,9.054\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.398,11.631L9.836,10.452\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_10.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.047,3.376L12.047,12.092\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,2.797C13.898,2.958 13.644,3.473 13.169,3.948C12.694,4.423 12.179,4.677 12.017,4.516C11.856,4.354 11.71,4.218 12.184,3.743C12.659,3.268 13.193,3.491 13.737,2.797Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,8.668C13.898,8.829 13.644,9.345 13.169,9.82C12.694,10.294 12.179,10.548 12.017,10.387C11.856,10.226 11.71,10.089 12.184,9.615C12.659,9.14 13.193,9.362 13.737,8.668Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,2.797C10.102,2.958 10.356,3.473 10.831,3.948C11.306,4.423 11.821,4.677 11.983,4.516C12.144,4.354 12.29,4.218 11.816,3.743C11.341,3.268 10.807,3.491 10.263,2.797Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,8.668C10.102,8.829 10.356,9.345 10.831,9.82C11.306,10.294 11.821,10.548 11.983,10.387C12.144,10.226 12.29,10.089 11.816,9.615C11.341,9.14 10.807,9.362 10.263,8.668Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.981,4.02C8.662,4.131 9.041,4.715 9.829,5.324C10.616,5.933 11.513,6.336 11.832,6.225C12.152,6.113 12.44,6.022 11.653,5.413C10.865,4.804 9.858,4.866 8.981,4.02Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.019,4.02C15.338,4.131 14.959,4.715 14.171,5.324C13.384,5.933 12.487,6.336 12.168,6.225C11.848,6.113 11.56,6.022 12.347,5.413C13.135,4.804 14.142,4.866 15.019,4.02Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,4.798a1.216,0.183 90,1 0,0 -2.431a1.216,0.183 90,1 0,0 2.431z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,2.413m-0.413,0a0.413,0.413 0,1 1,0.826 0a0.413,0.413 0,1 1,-0.826 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.047,20.624L12.047,11.908\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,21.204C13.898,21.042 13.644,20.527 13.169,20.052C12.694,19.577 12.179,19.323 12.017,19.484C11.856,19.646 11.71,19.782 12.184,20.257C12.659,20.732 13.193,20.509 13.737,21.204Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,15.332C13.898,15.171 13.644,14.655 13.169,14.18C12.694,13.706 12.179,13.452 12.017,13.613C11.856,13.774 11.71,13.911 12.184,14.385C12.659,14.86 13.193,14.638 13.737,15.332Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,21.204C10.102,21.042 10.356,20.527 10.831,20.052C11.306,19.577 11.821,19.323 11.983,19.484C12.144,19.646 12.29,19.782 11.816,20.257C11.341,20.732 10.807,20.509 10.263,21.204Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,15.332C10.102,15.171 10.356,14.655 10.831,14.18C11.306,13.706 11.821,13.452 11.983,13.613C12.144,13.774 12.29,13.911 11.816,14.385C11.341,14.86 10.807,14.638 10.263,15.332Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.981,19.98C8.662,19.869 9.041,19.285 9.829,18.676C10.616,18.067 11.513,17.664 11.832,17.775C12.152,17.887 12.44,17.978 11.653,18.587C10.865,19.196 9.858,19.134 8.981,19.98Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.019,19.98C15.338,19.869 14.959,19.285 14.171,18.676C13.384,18.067 12.487,17.664 12.168,17.775C11.848,17.887 11.56,17.978 12.347,18.587C13.135,19.196 14.142,19.134 15.019,19.98Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,19.202a1.216,0.183 90,1 1,0 2.431a1.216,0.183 90,1 1,0 -2.431z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,21.587m-0.413,-0a0.413,0.413 0,1 0,0.826 -0a0.413,0.413 0,1 0,-0.826 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.376,11.953L12.092,11.953\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.797,10.263C2.958,10.102 3.473,10.356 3.948,10.831C4.423,11.306 4.677,11.821 4.516,11.983C4.354,12.144 4.218,12.29 3.743,11.816C3.268,11.341 3.491,10.807 2.797,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.668,10.263C8.829,10.102 9.345,10.356 9.82,10.831C10.294,11.306 10.548,11.821 10.387,11.983C10.226,12.144 10.089,12.29 9.615,11.816C9.14,11.341 9.362,10.807 8.668,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.797,13.737C2.958,13.898 3.473,13.644 3.948,13.169C4.423,12.694 4.677,12.179 4.516,12.017C4.354,11.856 4.218,11.71 3.743,12.184C3.268,12.659 3.491,13.193 2.797,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.668,13.737C8.829,13.898 9.345,13.644 9.82,13.169C10.294,12.694 10.548,12.179 10.387,12.017C10.226,11.856 10.089,11.71 9.615,12.184C9.14,12.659 9.362,13.193 8.668,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.02,15.019C4.131,15.338 4.715,14.959 5.324,14.171C5.933,13.384 6.336,12.487 6.225,12.167C6.113,11.848 6.022,11.56 5.413,12.347C4.804,13.135 4.866,14.142 4.02,15.019Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.02,8.981C4.131,8.662 4.715,9.041 5.324,9.829C5.933,10.616 6.336,11.513 6.225,11.833C6.113,12.152 6.022,12.44 5.413,11.653C4.804,10.865 4.866,9.858 4.02,8.981Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.798,11.999a0.183,1.216 90,1 0,-2.431 -0a0.183,1.216 90,1 0,2.431 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.413,11.999m0,0.413a0.413,0.413 0,1 1,0 -0.826a0.413,0.413 0,1 1,0 0.826\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.624,11.953L11.908,11.953\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.204,10.263C21.042,10.102 20.527,10.356 20.052,10.831C19.577,11.306 19.323,11.821 19.484,11.983C19.646,12.144 19.782,12.29 20.257,11.816C20.732,11.341 20.509,10.807 21.204,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.332,10.263C15.171,10.102 14.655,10.356 14.18,10.831C13.706,11.306 13.452,11.821 13.613,11.983C13.774,12.144 13.911,12.29 14.385,11.816C14.86,11.341 14.638,10.807 15.332,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.204,13.737C21.042,13.898 20.527,13.644 20.052,13.169C19.577,12.694 19.323,12.179 19.484,12.017C19.646,11.856 19.782,11.71 20.257,12.184C20.732,12.659 20.509,13.193 21.204,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.332,13.737C15.171,13.898 14.655,13.644 14.18,13.169C13.706,12.694 13.452,12.179 13.613,12.017C13.774,11.856 13.911,11.71 14.385,12.184C14.86,12.659 14.638,13.193 15.332,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.98,15.019C19.869,15.338 19.285,14.959 18.676,14.171C18.067,13.384 17.664,12.487 17.775,12.168C17.887,11.848 17.978,11.56 18.587,12.347C19.196,13.135 19.134,14.142 19.98,15.019Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.98,8.981C19.869,8.662 19.285,9.041 18.676,9.829C18.067,10.616 17.664,11.513 17.775,11.833C17.887,12.152 17.978,12.44 18.587,11.653C19.196,10.865 19.134,9.858 19.98,8.981Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.202,11.999a0.183,1.216 90,1 1,2.431 -0a0.183,1.216 90,1 1,-2.431 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.587,11.999m-0,0.413a0.413,0.413 0,1 0,-0 -0.826a0.413,0.413 0,1 0,-0 0.826\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.132,5.935L11.968,12.098\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.736,6.72C19.736,6.948 19.192,7.133 18.52,7.133C17.849,7.133 17.305,6.948 17.305,6.72C17.305,6.492 17.298,6.292 17.969,6.292C18.64,6.292 18.861,6.827 19.736,6.72Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.584,10.872C15.584,11.1 15.04,11.285 14.368,11.285C13.697,11.285 13.153,11.1 13.153,10.872C13.153,10.644 13.146,10.444 13.817,10.444C14.488,10.444 14.709,10.979 15.584,10.872Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.28,4.264C17.052,4.264 16.867,4.808 16.867,5.48C16.867,6.151 17.052,6.695 17.28,6.695C17.508,6.695 17.708,6.703 17.708,6.031C17.708,5.36 17.173,5.139 17.28,4.264Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.128,8.416C12.9,8.416 12.715,8.96 12.715,9.632C12.715,10.303 12.9,10.847 13.128,10.847C13.356,10.847 13.556,10.854 13.556,10.183C13.556,9.512 13.021,9.291 13.128,8.416Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.508,4.222C15.203,4.075 15.059,4.757 15.185,5.744C15.311,6.732 15.661,7.651 15.965,7.798C16.27,7.945 16.539,8.084 16.412,7.097C16.286,6.109 15.53,5.44 15.508,4.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.778,8.492C19.925,8.797 19.243,8.941 18.256,8.815C17.268,8.688 16.349,8.339 16.202,8.035C16.055,7.73 15.916,7.461 16.903,7.588C17.891,7.714 18.56,8.47 19.778,8.492Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.093,6.908a0.183,1.216 45,1 0,1.719 -1.719a0.183,1.216 45,1 0,-1.719 1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.78,5.221m-0.292,-0.292a0.413,0.413 90,1 1,0.584 0.584a0.413,0.413 90,1 1,-0.584 -0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.935,18.132L12.098,11.968\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.72,19.736C6.948,19.736 7.133,19.191 7.133,18.52C7.133,17.849 6.948,17.305 6.72,17.305C6.492,17.305 6.292,17.297 6.292,17.969C6.292,18.64 6.827,18.861 6.72,19.736Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.872,15.584C11.1,15.584 11.285,15.04 11.285,14.368C11.285,13.697 11.1,13.153 10.872,13.153C10.644,13.153 10.444,13.146 10.444,13.817C10.444,14.488 10.979,14.709 10.872,15.584Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.264,17.28C4.264,17.052 4.808,16.867 5.48,16.867C6.151,16.867 6.695,17.052 6.695,17.28C6.695,17.508 6.703,17.708 6.031,17.708C5.36,17.708 5.139,17.173 4.264,17.28Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.416,13.128C8.416,12.9 8.96,12.715 9.632,12.715C10.303,12.715 10.847,12.9 10.847,13.128C10.847,13.356 10.854,13.556 10.183,13.556C9.512,13.556 9.291,13.021 8.416,13.128Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.222,15.508C4.075,15.203 4.757,15.059 5.744,15.185C6.732,15.311 7.651,15.661 7.798,15.965C7.945,16.27 8.084,16.539 7.097,16.412C6.109,16.286 5.44,15.53 4.222,15.508Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.492,19.778C8.797,19.925 8.941,19.243 8.815,18.256C8.688,17.268 8.339,16.349 8.035,16.202C7.73,16.055 7.461,15.916 7.588,16.903C7.714,17.891 8.47,18.56 8.492,19.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.908,17.093a1.216,0.183 135,1 1,-1.719 1.719a1.216,0.183 135,1 1,1.719 -1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.221,18.78m-0.292,-0.292a0.413,0.413 0,1 0,0.584 0.584a0.413,0.413 0,1 0,-0.584 -0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.935,5.868L12.098,12.032\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.72,4.264C6.948,4.264 7.133,4.808 7.133,5.48C7.133,6.151 6.948,6.695 6.72,6.695C6.492,6.695 6.292,6.703 6.292,6.031C6.292,5.36 6.827,5.139 6.72,4.264Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.872,8.416C11.1,8.416 11.285,8.96 11.285,9.632C11.285,10.303 11.1,10.847 10.872,10.847C10.644,10.847 10.444,10.854 10.444,10.183C10.444,9.512 10.979,9.291 10.872,8.416Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.264,6.72C4.264,6.948 4.808,7.133 5.48,7.133C6.151,7.133 6.695,6.948 6.695,6.72C6.695,6.492 6.703,6.292 6.031,6.292C5.36,6.292 5.139,6.827 4.264,6.72Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.416,10.872C8.416,11.1 8.96,11.285 9.632,11.285C10.303,11.285 10.847,11.1 10.847,10.872C10.847,10.644 10.854,10.444 10.183,10.444C9.512,10.444 9.291,10.979 8.416,10.872Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.222,8.492C4.075,8.797 4.757,8.941 5.744,8.815C6.732,8.688 7.651,8.339 7.798,8.035C7.945,7.73 8.084,7.461 7.097,7.588C6.109,7.714 5.44,8.47 4.222,8.492Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.492,4.222C8.797,4.075 8.941,4.757 8.815,5.744C8.688,6.732 8.339,7.651 8.035,7.798C7.73,7.945 7.461,8.084 7.588,7.097C7.714,6.109 8.47,5.44 8.492,4.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.908,6.907a1.216,0.183 45,1 0,-1.719 -1.719a1.216,0.183 45,1 0,1.719 1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.221,5.22m-0.292,0.292a0.413,0.413 90,1 1,0.584 -0.584a0.413,0.413 0,1 1,-0.584 0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.132,18.065L11.968,11.902\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.736,17.28C19.736,17.052 19.192,16.867 18.52,16.867C17.849,16.867 17.305,17.052 17.305,17.28C17.305,17.508 17.298,17.708 17.969,17.708C18.64,17.708 18.861,17.173 19.736,17.28Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.584,13.128C15.584,12.9 15.04,12.715 14.368,12.715C13.697,12.715 13.153,12.9 13.153,13.128C13.153,13.356 13.146,13.556 13.817,13.556C14.488,13.556 14.709,13.021 15.584,13.128Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.28,19.736C17.052,19.736 16.867,19.192 16.867,18.52C16.867,17.849 17.052,17.305 17.28,17.305C17.508,17.305 17.708,17.297 17.708,17.969C17.708,18.64 17.173,18.861 17.28,19.736Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.128,15.584C12.9,15.584 12.715,15.04 12.715,14.368C12.715,13.697 12.9,13.153 13.128,13.153C13.356,13.153 13.556,13.146 13.556,13.817C13.556,14.488 13.021,14.709 13.128,15.584Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.508,19.778C15.203,19.925 15.059,19.243 15.185,18.256C15.311,17.268 15.661,16.349 15.965,16.202C16.27,16.055 16.539,15.916 16.412,16.903C16.286,17.891 15.53,18.56 15.508,19.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.778,15.508C19.925,15.203 19.243,15.059 18.256,15.185C17.268,15.311 16.349,15.661 16.202,15.965C16.055,16.27 15.916,16.539 16.903,16.412C17.891,16.286 18.56,15.53 19.778,15.508Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.093,17.092a0.183,1.216 135,1 1,1.719 1.719a0.183,1.216 135,1 1,-1.719 -1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.78,18.779m-0.292,0.292a0.413,0.413 0,1 0,0.584 -0.584a0.413,0.413 0,1 0,-0.584 0.584\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_2.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12,4.047L12.011,11.654\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12,19.185L12.011,11.577\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.005,6L12.05,7.831\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.297,17.288L12.05,15.401\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.984,7.36L12.049,9.066\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.297,16.052L12.05,14.165\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.709,5.953L11.999,7.841\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.005,17L11.999,15.391\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.709,7.189L11.999,9.077\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.973,15.967L12.022,14.193\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12,3.081m-0.781,0a0.781,0.781 0,1 1,1.563 0a0.781,0.781 0,1 1,-1.563 0\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12,20.15m-0.781,-0a0.781,0.781 0,1 0,1.563 -0a0.781,0.781 0,1 0,-1.563 -0\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.189,6.943a0.811,0.811 0,1 0,1.622 0a0.811,0.811 0,1 0,-1.622 0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.189,16.289a0.811,0.811 0,1 1,1.622 -0a0.811,0.811 0,1 1,-1.622 -0z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12,4.047L12.011,11.654\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12,19.185L12.011,11.577\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.297,17.288L12.05,15.401\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.297,16.052L12.05,14.165\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.709,5.953L11.999,7.841\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.709,7.189L11.999,9.077\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12,20.15m-0.781,-0a0.781,0.781 0,1 0,1.563 -0a0.781,0.781 0,1 0,-1.563 -0\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.189,6.943a0.811,0.811 0,1 0,1.622 0a0.811,0.811 0,1 0,-1.622 0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.189,16.289a0.811,0.811 0,1 1,1.622 -0a0.811,0.811 0,1 1,-1.622 -0z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.389,7.94L12.042,11.63\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.617,15.301L11.974,11.592\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.65,5.981L8.719,9.737\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.562,11.497L15.334,13.418\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.73,6.582L9.799,10.338\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.482,10.896L14.255,12.817\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.454,11.743L8.704,9.786\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.35,17.25L15.301,13.457\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.534,12.344L9.784,10.387\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.271,16.649L14.221,12.856\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.02,8.415a1.081,1.081 74.096,1 0,1.052 -1.89a1.081,1.081 74.096,1 0,-1.052 1.89z\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.461,15.77m-0.38,0.683a0.781,0.781 74.096,1 0,0.76 -1.365a0.781,0.781 74.096,1 0,-0.76 1.365\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.92,9.348m-0.394,0.709a0.811,0.811 74.096,1 1,0.789 -1.417a0.811,0.811 74.096,1 1,-0.789 1.417\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.692,14.601a0.811,0.811 74.096,1 1,0.789 -1.417a0.811,0.811 74.096,1 1,-0.789 1.417z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.437,7.624L11.976,11.641\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.569,15.599L12.041,11.6\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.56,11.426L15.246,9.659\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.005,17L8.811,13.647\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.51,12.077L14.196,10.31\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.912,16.382L9.811,12.997\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.005,6L15.211,9.622\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.456,11.796L8.793,13.599\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.996,6.699L14.161,10.273\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.506,11.145L9.844,12.948\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.257,7.116m-0.412,-0.664a0.781,0.781 103.213,1 1,0.823 1.328a0.781,0.781 103.213,1 1,-0.823 -1.328\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.748,16.107m-0.412,-0.664a0.781,0.781 103.213,1 0,0.823 1.328a0.781,0.781 103.213,1 0,-0.823 -1.328\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.548,8.461a0.811,0.811 103.213,1 0,0.854 1.379a0.811,0.811 103.213,1 0,-0.854 -1.379z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.604,13.384a0.811,0.811 103.213,1 1,0.854 1.379a0.811,0.811 103.213,1 1,-0.854 -1.379z\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_3.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.102,3L12.102,12.255\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.102,3L12.102,12.255\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.623,3.855L11.896,5.168\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.377,3.855L12.104,5.168\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.102,21L12.102,11.745\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.102,21L12.102,11.745\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.623,20.145L11.896,18.832\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.377,20.145L12.104,18.832\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3,11.898L12.255,11.898\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3,11.898L12.255,11.898\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.855,14.377L5.168,12.104\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.855,9.623L5.168,11.896\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M21,11.898L11.745,11.898\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M21,11.898L11.745,11.898\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.145,14.377L18.832,12.104\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.145,9.623L18.832,11.896\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.436,5.709L11.892,12.253\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.436,5.709L11.892,12.253\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.078,4.56L16.758,7.096\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.44,7.922L16.904,7.242\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.709,18.436L12.253,11.892\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.709,18.436L12.253,11.892\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.56,16.078L7.096,16.758\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.922,19.44L7.242,16.904\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.709,5.564L12.253,12.108\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.709,5.564L12.253,12.108\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.56,7.922L7.096,7.242\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.922,4.56L7.242,7.096\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.436,18.291L11.892,11.747\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.436,18.291L11.892,11.747\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.078,19.44L16.758,16.904\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.44,16.078L16.904,16.758\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_4.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,4.033L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,10.003C12.356,9.57 13.23,8.965 14.134,10.003\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,11.674C12.246,11.458 12.821,11.155 13.417,11.674\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.985,7.042C11.62,6.283 10.385,5.466 9.453,7.042\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,7.042C12.397,6.283 13.632,5.466 14.564,7.042\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,10.003C11.716,9.57 10.862,8.965 9.979,10.003\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.985,11.674C11.779,11.422 11.223,11.069 10.647,11.674\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.656,4.797m-0.239,0a0.239,0.239 0,1 1,0.478 0a0.239,0.239 0,1 1,-0.478 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.032,3.173m-0.239,0a0.239,0.239 0,1 1,0.478 0a0.239,0.239 0,1 1,-0.478 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.797,4.176m-0.143,0a0.143,0.143 0,1 1,0.287 0a0.143,0.143 0,1 1,-0.287 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.173,4.176m-0.143,0a0.143,0.143 0,1 1,0.287 0a0.143,0.143 0,1 1,-0.287 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.313,4.797m-0.239,0a0.239,0.239 0,1 1,0.478 0a0.239,0.239 0,1 1,-0.478 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,19.984L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,14.014C12.356,14.447 13.23,15.052 14.134,14.014\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,12.343C12.246,12.559 12.821,12.862 13.417,12.343\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.985,16.976C11.62,17.734 10.385,18.552 9.453,16.976\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,16.976C12.397,17.734 13.632,18.552 14.564,16.976\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.032,14.014C11.716,14.447 10.862,15.052 9.979,14.014\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.985,12.343C11.779,12.595 11.223,12.948 10.647,12.343\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.656,19.22m-0.239,-0a0.239,0.239 0,1 0,0.478 -0a0.239,0.239 0,1 0,-0.478 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.032,20.844m-0.239,-0a0.239,0.239 0,1 0,0.478 -0a0.239,0.239 0,1 0,-0.478 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.797,19.841m-0.143,-0a0.143,0.143 0,1 0,0.287 -0a0.143,0.143 0,1 0,-0.287 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.173,19.841m-0.143,-0a0.143,0.143 0,1 0,0.287 -0a0.143,0.143 0,1 0,-0.287 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.313,19.22m-0.239,-0a0.239,0.239 0,1 0,0.478 -0a0.239,0.239 0,1 0,-0.478 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.033,11.985L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.003,11.985C9.57,11.661 8.965,10.787 10.003,9.883\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.674,11.985C11.458,11.771 11.155,11.196 11.674,10.6\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.042,12.032C6.283,12.397 5.466,13.632 7.042,14.564\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.042,11.985C6.283,11.62 5.466,10.385 7.042,9.453\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.003,11.985C9.57,12.301 8.965,13.155 10.003,14.038\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.674,12.032C11.422,12.238 11.069,12.794 11.674,13.37\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.797,10.361m0,0.239a0.239,0.239 0,1 1,0 -0.478a0.239,0.239 0,1 1,0 0.478\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.173,11.985m0,0.239a0.239,0.239 0,1 1,0 -0.478a0.239,0.239 0,1 1,0 0.478\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.176,11.22m0,0.143a0.143,0.143 0,1 1,0 -0.287a0.143,0.143 0,1 1,0 0.287\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.176,12.844m0,0.143a0.143,0.143 0,1 1,0 -0.287a0.143,0.143 0,1 1,0 0.287\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.797,13.704m0,0.239a0.239,0.239 0,1 1,0 -0.478a0.239,0.239 0,1 1,0 0.478\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.984,11.985L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.014,11.985C14.447,11.661 15.052,10.787 14.014,9.883\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.343,11.985C12.559,11.771 12.862,11.196 12.343,10.6\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.975,12.032C17.734,12.397 18.552,13.632 16.975,14.564\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.975,11.985C17.734,11.62 18.552,10.385 16.975,9.453\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.014,11.985C14.447,12.301 15.052,13.155 14.014,14.038\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.343,12.032C12.595,12.238 12.948,12.794 12.343,13.37\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.22,10.361m-0,0.239a0.239,0.239 0,1 0,-0 -0.478a0.239,0.239 0,1 0,-0 0.478\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.844,11.985m-0,0.239a0.239,0.239 0,1 0,-0 -0.478a0.239,0.239 0,1 0,-0 0.478\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.841,11.221m-0,0.143a0.143,0.143 0,1 0,-0 -0.287a0.143,0.143 0,1 0,-0 0.287\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.841,12.844m-0,0.143a0.143,0.143 0,1 0,-0 -0.287a0.143,0.143 0,1 0,-0 0.287\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.22,13.704m-0,0.239a0.239,0.239 0,1 0,-0 -0.478a0.239,0.239 0,1 0,-0 0.478\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.386,6.352L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.607,10.573C10.53,10.039 10.72,8.993 12.093,9.087\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.789,11.755C11.787,11.451 11.98,10.83 12.768,10.776\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.48,8.513C7.686,8.235 6.234,8.53 6.69,10.303\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.513,8.48C8.235,7.686 8.53,6.234 10.303,6.69\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.607,10.573C10.078,10.491 9.046,10.667 9.155,12.025\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.755,11.789C11.431,11.756 10.788,11.9 10.81,12.735\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.074,5.744m-0.169,0.169a0.239,0.239 90,1 1,0.338 -0.338a0.239,0.239 90,1 1,-0.338 0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.778,5.744m-0.169,0.169a0.239,0.239 90,1 1,0.338 -0.338a0.239,0.239 90,1 1,-0.338 0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.027,5.913m-0.101,0.101a0.143,0.143 90,1 1,0.203 -0.203a0.143,0.143 90,1 1,-0.203 0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.879,7.061m-0.101,0.101a0.143,0.143 0,1 1,0.203 -0.203a0.143,0.143 90,1 1,-0.203 0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.71,8.108m-0.169,0.169a0.239,0.239 90,1 1,0.338 -0.338a0.239,0.239 90,1 1,-0.338 0.338\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.665,17.631L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.444,13.41C13.979,13.487 15.024,13.297 14.93,11.924\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.262,12.228C12.566,12.23 13.187,12.037 13.241,11.249\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.504,15.538C15.782,16.331 15.487,17.783 13.714,17.327\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.538,15.504C16.331,15.782 17.783,15.487 17.327,13.714\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.444,13.41C13.526,13.939 13.35,14.971 11.992,14.862\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.228,12.262C12.261,12.586 12.118,13.229 11.283,13.207\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.273,15.943m-0.169,0.169a0.239,0.239 90,1 0,0.338 -0.338a0.239,0.239 90,1 0,-0.338 0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.273,18.239m-0.169,0.169a0.239,0.239 90,1 0,0.338 -0.338a0.239,0.239 90,1 0,-0.338 0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.104,16.99m-0.101,0.101a0.143,0.143 90,1 0,0.203 -0.203a0.143,0.143 90,1 0,-0.203 0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M16.956,18.138m-0.101,0.101a0.143,0.143 90,1 0,0.203 -0.203a0.143,0.143 90,1 0,-0.203 0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.909,18.307m-0.169,0.169a0.239,0.239 0,1 0,0.338 -0.338a0.239,0.239 0,1 0,-0.338 0.338\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.665,6.386L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.444,10.607C13.979,10.53 15.024,10.72 14.93,12.093\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.262,11.789C12.566,11.787 13.187,11.98 13.241,12.768\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.504,8.48C15.782,7.686 15.487,6.234 13.714,6.69\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.538,8.513C16.331,8.235 17.783,8.53 17.327,10.303\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.444,10.607C13.526,10.078 13.35,9.046 11.992,9.155\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.228,11.755C12.261,11.431 12.118,10.788 11.283,10.81\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.273,8.074m-0.169,-0.169a0.239,0.239 0,1 1,0.338 0.338a0.239,0.239 0,1 1,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.273,5.778m-0.169,-0.169a0.239,0.239 0,1 1,0.338 0.338a0.239,0.239 0,1 1,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.104,7.027m-0.101,-0.101a0.143,0.143 0,1 1,0.203 0.203a0.143,0.143 0,1 1,-0.203 -0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M16.956,5.879m-0.101,-0.101a0.143,0.143 0,1 1,0.203 0.203a0.143,0.143 0,1 1,-0.203 -0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.909,5.71m-0.169,-0.169a0.239,0.239 90,1 1,0.338 0.338a0.239,0.239 0,1 1,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.386,17.665L12.009,12.009\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.607,13.444C10.53,13.979 10.72,15.024 12.093,14.93\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.789,12.262C11.787,12.566 11.98,13.187 12.768,13.241\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.48,15.504C7.686,15.782 6.234,15.487 6.69,13.714\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.513,15.538C8.235,16.331 8.53,17.783 10.303,17.327\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.607,13.444C10.078,13.526 9.046,13.35 9.155,11.992\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.755,12.228C11.431,12.261 10.788,12.118 10.81,11.283\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.074,18.273m-0.169,-0.169a0.239,0.239 90,1 0,0.338 0.338a0.239,0.239 90,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.982,16.836m-0.169,-0.169a0.239,0.239 90,1 0,0.338 0.338a0.239,0.239 90,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.164,14.018m-0.169,-0.169a0.239,0.239 0,1 0,0.338 0.338a0.239,0.239 0,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.164,10.006m-0.169,-0.169a0.239,0.239 0,1 0,0.338 0.338a0.239,0.239 0,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.982,7.188m-0.169,-0.169a0.239,0.239 0,1 0,0.338 0.338a0.239,0.239 0,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.994,7.188m-0.169,-0.169a0.239,0.239 0,1 0,0.338 0.338a0.239,0.239 0,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M16.812,10.006m-0.169,-0.169a0.239,0.239 0,1 0,0.338 0.338a0.239,0.239 0,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M16.812,14.018m-0.169,-0.169a0.239,0.239 0,1 0,0.338 0.338a0.239,0.239 0,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.994,16.836m-0.169,-0.169a0.239,0.239 90,1 0,0.338 0.338a0.239,0.239 90,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.778,18.273m-0.169,-0.169a0.239,0.239 90,1 0,0.338 0.338a0.239,0.239 90,1 0,-0.338 -0.338\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.027,18.104m-0.101,-0.101a0.143,0.143 90,1 0,0.203 0.203a0.143,0.143 90,1 0,-0.203 -0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.879,16.956m-0.101,-0.101a0.143,0.143 90,1 0,0.203 0.203a0.143,0.143 90,1 0,-0.203 -0.203\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.71,15.909m-0.169,-0.169a0.239,0.239 0,1 0,0.338 0.338a0.239,0.239 0,1 0,-0.338 -0.338\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_5.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.047,3.376L12.047,12.092\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,2.797C13.898,2.958 13.644,3.473 13.169,3.948C12.694,4.423 12.179,4.677 12.017,4.516C11.856,4.354 11.71,4.218 12.184,3.743C12.659,3.268 13.193,3.491 13.737,2.797Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,8.668C13.898,8.829 13.644,9.345 13.169,9.82C12.694,10.294 12.179,10.548 12.017,10.387C11.856,10.226 11.71,10.089 12.184,9.615C12.659,9.14 13.193,9.362 13.737,8.668Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,2.797C10.102,2.958 10.356,3.473 10.831,3.948C11.306,4.423 11.821,4.677 11.983,4.516C12.144,4.354 12.29,4.218 11.816,3.743C11.341,3.268 10.807,3.491 10.263,2.797Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,8.668C10.102,8.829 10.356,9.345 10.831,9.82C11.306,10.294 11.821,10.548 11.983,10.387C12.144,10.226 12.29,10.089 11.816,9.615C11.341,9.14 10.807,9.362 10.263,8.668Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.981,4.02C8.662,4.131 9.041,4.715 9.829,5.324C10.616,5.933 11.513,6.336 11.832,6.225C12.152,6.113 12.44,6.022 11.653,5.413C10.865,4.804 9.858,4.866 8.981,4.02Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.229,6.222C8.936,6.333 9.284,6.917 10.007,7.526C10.73,8.135 11.554,8.538 11.847,8.427C12.14,8.315 12.405,8.224 11.682,7.615C10.959,7.006 10.034,7.068 9.229,6.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.019,4.02C15.338,4.131 14.959,4.715 14.171,5.324C13.384,5.933 12.487,6.336 12.168,6.225C11.848,6.113 11.56,6.022 12.347,5.413C13.135,4.804 14.142,4.866 15.019,4.02Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.773,6.222C15.066,6.333 14.717,6.917 13.994,7.526C13.271,8.135 12.448,8.538 12.155,8.427C11.862,8.315 11.597,8.224 12.319,7.615C13.042,7.006 13.968,7.068 14.773,6.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,4.798a1.216,0.183 90,1 0,0 -2.431a1.216,0.183 90,1 0,0 2.431z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,2.413m-0.413,0a0.413,0.413 0,1 1,0.826 0a0.413,0.413 0,1 1,-0.826 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.047,20.624L12.047,11.908\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,21.204C13.898,21.042 13.644,20.527 13.169,20.052C12.694,19.577 12.179,19.323 12.017,19.484C11.856,19.646 11.71,19.782 12.184,20.257C12.659,20.732 13.193,20.509 13.737,21.204Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,15.332C13.898,15.171 13.644,14.655 13.169,14.18C12.694,13.706 12.179,13.452 12.017,13.613C11.856,13.774 11.71,13.911 12.184,14.385C12.659,14.86 13.193,14.638 13.737,15.332Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,21.204C10.102,21.042 10.356,20.527 10.831,20.052C11.306,19.577 11.821,19.323 11.983,19.484C12.144,19.646 12.29,19.782 11.816,20.257C11.341,20.732 10.807,20.509 10.263,21.204Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,15.332C10.102,15.171 10.356,14.655 10.831,14.18C11.306,13.706 11.821,13.452 11.983,13.613C12.144,13.774 12.29,13.911 11.816,14.385C11.341,14.86 10.807,14.638 10.263,15.332Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.981,19.98C8.662,19.869 9.041,19.285 9.829,18.676C10.616,18.067 11.513,17.664 11.832,17.775C12.152,17.887 12.44,17.978 11.653,18.587C10.865,19.196 9.858,19.134 8.981,19.98Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.229,17.778C8.936,17.667 9.284,17.083 10.007,16.474C10.73,15.865 11.554,15.462 11.847,15.573C12.14,15.685 12.405,15.776 11.682,16.385C10.959,16.994 10.034,16.933 9.229,17.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.019,19.98C15.338,19.869 14.959,19.285 14.171,18.676C13.384,18.067 12.487,17.664 12.168,17.775C11.848,17.887 11.56,17.978 12.347,18.587C13.135,19.196 14.142,19.134 15.019,19.98Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.773,17.778C15.066,17.667 14.717,17.083 13.994,16.474C13.271,15.865 12.448,15.462 12.155,15.573C11.862,15.685 11.597,15.776 12.319,16.385C13.042,16.994 13.968,16.933 14.773,17.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,19.202a1.216,0.183 90,1 1,0 2.431a1.216,0.183 90,1 1,0 -2.431z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,21.587m-0.413,-0a0.413,0.413 0,1 0,0.826 -0a0.413,0.413 0,1 0,-0.826 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.376,11.953L12.092,11.953\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.797,10.263C2.958,10.102 3.473,10.356 3.948,10.831C4.423,11.306 4.677,11.821 4.516,11.983C4.354,12.144 4.218,12.29 3.743,11.816C3.268,11.341 3.491,10.807 2.797,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.668,10.263C8.829,10.102 9.345,10.356 9.82,10.831C10.294,11.306 10.548,11.821 10.387,11.983C10.226,12.144 10.089,12.29 9.615,11.816C9.14,11.341 9.362,10.807 8.668,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.797,13.737C2.958,13.898 3.473,13.644 3.948,13.169C4.423,12.694 4.677,12.179 4.516,12.017C4.354,11.856 4.218,11.71 3.743,12.184C3.268,12.659 3.491,13.193 2.797,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.668,13.737C8.829,13.898 9.345,13.644 9.82,13.169C10.294,12.694 10.548,12.179 10.387,12.017C10.226,11.856 10.089,11.71 9.615,12.184C9.14,12.659 9.362,13.193 8.668,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.02,15.019C4.131,15.338 4.715,14.959 5.324,14.171C5.933,13.384 6.336,12.487 6.225,12.167C6.113,11.848 6.022,11.56 5.413,12.347C4.804,13.135 4.866,14.142 4.02,15.019Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.222,14.771C6.333,15.064 6.917,14.716 7.526,13.993C8.135,13.27 8.538,12.446 8.427,12.153C8.315,11.86 8.224,11.595 7.615,12.318C7.006,13.041 7.067,13.966 6.222,14.771Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.02,8.981C4.131,8.662 4.715,9.041 5.324,9.829C5.933,10.616 6.336,11.513 6.225,11.832C6.113,12.152 6.022,12.44 5.413,11.653C4.804,10.865 4.866,9.858 4.02,8.981Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.222,9.227C6.333,8.934 6.917,9.283 7.526,10.006C8.135,10.729 8.538,11.552 8.427,11.845C8.315,12.138 8.224,12.404 7.615,11.681C7.006,10.958 7.067,10.032 6.222,9.227Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.798,11.999a0.183,1.216 90,1 0,-2.431 -0a0.183,1.216 90,1 0,2.431 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.413,11.999m0,0.413a0.413,0.413 0,1 1,0 -0.826a0.413,0.413 0,1 1,0 0.826\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.624,11.953L11.908,11.953\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.204,10.263C21.042,10.102 20.527,10.356 20.052,10.831C19.577,11.306 19.323,11.821 19.484,11.983C19.646,12.144 19.782,12.29 20.257,11.816C20.732,11.341 20.509,10.807 21.204,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.332,10.263C15.171,10.102 14.655,10.356 14.18,10.831C13.706,11.306 13.452,11.821 13.613,11.983C13.774,12.144 13.911,12.29 14.385,11.816C14.86,11.341 14.638,10.807 15.332,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.204,13.737C21.042,13.898 20.527,13.644 20.052,13.169C19.577,12.694 19.323,12.179 19.484,12.017C19.646,11.856 19.782,11.71 20.257,12.184C20.732,12.659 20.509,13.193 21.204,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.332,13.737C15.171,13.898 14.655,13.644 14.18,13.169C13.706,12.694 13.452,12.179 13.613,12.017C13.774,11.856 13.911,11.71 14.385,12.184C14.86,12.659 14.638,13.193 15.332,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.98,15.019C19.869,15.338 19.285,14.959 18.676,14.171C18.067,13.384 17.664,12.487 17.775,12.167C17.887,11.848 17.978,11.56 18.587,12.347C19.196,13.135 19.134,14.142 19.98,15.019Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.778,14.771C17.667,15.064 17.083,14.716 16.474,13.993C15.865,13.27 15.462,12.446 15.573,12.153C15.685,11.86 15.776,11.595 16.385,12.318C16.994,13.041 16.933,13.966 17.778,14.771Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.98,8.981C19.869,8.662 19.285,9.041 18.676,9.829C18.067,10.616 17.664,11.513 17.775,11.833C17.887,12.152 17.978,12.44 18.587,11.653C19.196,10.865 19.134,9.858 19.98,8.981Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.778,9.227C17.667,8.934 17.083,9.283 16.474,10.006C15.865,10.729 15.462,11.552 15.573,11.845C15.685,12.138 15.776,12.404 16.385,11.681C16.994,10.958 16.933,10.032 17.778,9.227Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.202,11.999a0.183,1.216 90,1 1,2.431 -0a0.183,1.216 90,1 1,-2.431 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.587,11.999m-0,0.413a0.413,0.413 0,1 0,-0 -0.826a0.413,0.413 0,1 0,-0 0.826\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.132,5.935L11.968,12.098\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.736,6.72C19.736,6.948 19.192,7.133 18.52,7.133C17.849,7.133 17.305,6.948 17.305,6.72C17.305,6.492 17.298,6.292 17.969,6.292C18.64,6.292 18.861,6.827 19.736,6.72Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.584,10.872C15.584,11.1 15.04,11.285 14.368,11.285C13.697,11.285 13.153,11.1 13.153,10.872C13.153,10.644 13.146,10.444 13.817,10.444C14.488,10.444 14.709,10.979 15.584,10.872Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.28,4.264C17.052,4.264 16.867,4.808 16.867,5.48C16.867,6.151 17.052,6.695 17.28,6.695C17.508,6.695 17.708,6.703 17.708,6.031C17.708,5.36 17.173,5.139 17.28,4.264Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.128,8.416C12.9,8.416 12.715,8.96 12.715,9.632C12.715,10.303 12.9,10.847 13.128,10.847C13.356,10.847 13.556,10.854 13.556,10.183C13.556,9.512 13.021,9.291 13.128,8.416Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.508,4.222C15.203,4.075 15.059,4.757 15.185,5.744C15.311,6.732 15.661,7.651 15.965,7.798C16.27,7.945 16.539,8.084 16.412,7.097C16.286,6.109 15.53,5.44 15.508,4.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.126,5.954C13.84,5.826 13.674,6.485 13.754,7.427C13.835,8.369 14.132,9.237 14.418,9.365C14.705,9.493 14.957,9.616 14.876,8.674C14.795,7.733 14.097,7.122 14.126,5.954Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.778,8.492C19.925,8.797 19.243,8.941 18.256,8.815C17.268,8.688 16.349,8.339 16.202,8.035C16.055,7.73 15.916,7.461 16.903,7.588C17.891,7.714 18.56,8.47 19.778,8.492Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.047,9.875C18.175,10.161 17.516,10.327 16.574,10.247C15.632,10.166 14.764,9.869 14.636,9.583C14.508,9.296 14.385,9.044 15.327,9.125C16.268,9.206 16.879,9.904 18.047,9.875Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.093,6.908a0.183,1.216 45,1 0,1.719 -1.719a0.183,1.216 45,1 0,-1.719 1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.78,5.221m-0.292,-0.292a0.413,0.413 90,1 1,0.584 0.584a0.413,0.413 90,1 1,-0.584 -0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.935,18.132L12.098,11.968\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.72,19.736C6.948,19.736 7.133,19.191 7.133,18.52C7.133,17.849 6.948,17.305 6.72,17.305C6.492,17.305 6.292,17.297 6.292,17.969C6.292,18.64 6.827,18.861 6.72,19.736Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.872,15.584C11.1,15.584 11.285,15.04 11.285,14.368C11.285,13.697 11.1,13.153 10.872,13.153C10.644,13.153 10.444,13.146 10.444,13.817C10.444,14.488 10.979,14.709 10.872,15.584Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.264,17.28C4.264,17.052 4.808,16.867 5.48,16.867C6.151,16.867 6.695,17.052 6.695,17.28C6.695,17.508 6.703,17.708 6.031,17.708C5.36,17.708 5.139,17.173 4.264,17.28Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.416,13.128C8.416,12.9 8.96,12.715 9.632,12.715C10.303,12.715 10.847,12.9 10.847,13.128C10.847,13.356 10.854,13.556 10.183,13.556C9.512,13.556 9.291,13.021 8.416,13.128Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.222,15.508C4.075,15.203 4.757,15.059 5.744,15.185C6.732,15.311 7.651,15.661 7.798,15.965C7.945,16.27 8.084,16.539 7.097,16.412C6.109,16.286 5.44,15.53 4.222,15.508Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.954,14.126C5.826,13.84 6.485,13.674 7.427,13.755C8.369,13.835 9.237,14.132 9.365,14.419C9.493,14.705 9.616,14.957 8.674,14.876C7.733,14.795 7.122,14.097 5.954,14.126Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.492,19.778C8.797,19.925 8.941,19.243 8.815,18.256C8.688,17.268 8.339,16.349 8.035,16.202C7.73,16.055 7.461,15.916 7.588,16.903C7.714,17.891 8.47,18.56 8.492,19.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.875,18.047C10.161,18.175 10.327,17.516 10.247,16.574C10.166,15.632 9.869,14.764 9.582,14.636C9.296,14.508 9.044,14.385 9.125,15.327C9.206,16.268 9.904,16.879 9.875,18.047Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.908,17.093a1.216,0.183 135,1 1,-1.719 1.719a1.216,0.183 135,1 1,1.719 -1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.221,18.78m-0.292,-0.292a0.413,0.413 0,1 0,0.584 0.584a0.413,0.413 0,1 0,-0.584 -0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.935,5.868L12.098,12.032\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.72,4.264C6.948,4.264 7.133,4.808 7.133,5.48C7.133,6.151 6.948,6.695 6.72,6.695C6.492,6.695 6.292,6.703 6.292,6.031C6.292,5.36 6.827,5.139 6.72,4.264Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.872,8.416C11.1,8.416 11.285,8.96 11.285,9.632C11.285,10.303 11.1,10.847 10.872,10.847C10.644,10.847 10.444,10.854 10.444,10.183C10.444,9.512 10.979,9.291 10.872,8.416Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.264,6.72C4.264,6.948 4.808,7.133 5.48,7.133C6.151,7.133 6.695,6.948 6.695,6.72C6.695,6.492 6.703,6.292 6.031,6.292C5.36,6.292 5.139,6.827 4.264,6.72Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.416,10.872C8.416,11.1 8.96,11.285 9.632,11.285C10.303,11.285 10.847,11.1 10.847,10.872C10.847,10.644 10.854,10.444 10.183,10.444C9.512,10.444 9.291,10.979 8.416,10.872Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.222,8.492C4.075,8.797 4.757,8.941 5.744,8.815C6.732,8.688 7.651,8.339 7.798,8.035C7.945,7.73 8.084,7.461 7.097,7.588C6.109,7.714 5.44,8.47 4.222,8.492Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.954,9.874C5.826,10.16 6.485,10.326 7.427,10.245C8.369,10.165 9.237,9.867 9.365,9.581C9.493,9.295 9.616,9.043 8.674,9.124C7.733,9.205 7.122,9.903 5.954,9.874Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.492,4.222C8.797,4.075 8.941,4.757 8.815,5.744C8.688,6.732 8.339,7.651 8.035,7.798C7.73,7.945 7.461,8.084 7.588,7.097C7.714,6.109 8.47,5.44 8.492,4.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.875,5.953C10.161,5.825 10.327,6.484 10.247,7.426C10.166,8.368 9.869,9.236 9.582,9.364C9.296,9.492 9.044,9.615 9.125,8.673C9.206,7.731 9.904,7.121 9.875,5.953Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.908,6.907a1.216,0.183 45,1 0,-1.719 -1.719a1.216,0.183 45,1 0,1.719 1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.221,5.22m-0.292,0.292a0.413,0.413 90,1 1,0.584 -0.584a0.413,0.413 0,1 1,-0.584 0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.132,18.065L11.968,11.902\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.736,17.28C19.736,17.052 19.192,16.867 18.52,16.867C17.849,16.867 17.305,17.052 17.305,17.28C17.305,17.508 17.298,17.708 17.969,17.708C18.64,17.708 18.861,17.173 19.736,17.28Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.584,13.128C15.584,12.9 15.04,12.715 14.368,12.715C13.697,12.715 13.153,12.9 13.153,13.128C13.153,13.356 13.146,13.556 13.817,13.556C14.488,13.556 14.709,13.021 15.584,13.128Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.28,19.736C17.052,19.736 16.867,19.192 16.867,18.52C16.867,17.849 17.052,17.305 17.28,17.305C17.508,17.305 17.708,17.297 17.708,17.969C17.708,18.64 17.173,18.861 17.28,19.736Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.128,15.584C12.9,15.584 12.715,15.04 12.715,14.368C12.715,13.697 12.9,13.153 13.128,13.153C13.356,13.153 13.556,13.146 13.556,13.817C13.556,14.488 13.021,14.709 13.128,15.584Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.508,19.778C15.203,19.925 15.059,19.243 15.185,18.256C15.311,17.268 15.661,16.349 15.965,16.202C16.27,16.055 16.539,15.916 16.412,16.903C16.286,17.891 15.53,18.56 15.508,19.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.126,18.046C13.84,18.174 13.674,17.514 13.754,16.573C13.835,15.631 14.132,14.763 14.418,14.635C14.705,14.507 14.957,14.384 14.876,15.326C14.795,16.267 14.097,16.878 14.126,18.046Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.778,15.508C19.925,15.203 19.243,15.059 18.256,15.185C17.268,15.311 16.349,15.661 16.202,15.965C16.055,16.27 15.916,16.539 16.903,16.412C17.891,16.286 18.56,15.53 19.778,15.508Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.047,14.125C18.175,13.839 17.516,13.673 16.574,13.753C15.632,13.834 14.764,14.131 14.636,14.417C14.508,14.703 14.385,14.956 15.327,14.875C16.268,14.794 16.879,14.096 18.047,14.125Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.093,17.092a0.183,1.216 135,1 1,1.719 1.719a0.183,1.216 135,1 1,-1.719 -1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.78,18.779m-0.292,0.292a0.413,0.413 0,1 0,0.584 -0.584a0.413,0.413 0,1 0,-0.584 0.584\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_6.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.967,2.613V12.012\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.009,9.106L14.773,6.342\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.126,6.305L11.891,9.069\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.343,11.573a0.613,0.613 0,1 0,1.225 0a0.613,0.613 0,1 0,-1.225 0z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.97,6.338L14.735,3.574\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.066,5.255m-0.498,0a0.498,0.498 0,1 1,0.996 0a0.498,0.498 0,1 1,-0.996 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.062,4.259m-0.498,0a0.498,0.498 0,1 1,0.996 0a0.498,0.498 0,1 1,-0.996 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.56,3.359a0.402,0.402 0,1 0,0.804 0a0.402,0.402 0,1 0,-0.804 0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.535,2.402a0.402,0.402 0,1 0,0.804 0a0.402,0.402 0,1 0,-0.804 0z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.956,6.338L9.192,3.574\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.86,5.255m0.498,0a0.498,0.498 0,1 0,-0.996 0a0.498,0.498 0,1 0,0.996 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.864,4.259m0.498,0a0.498,0.498 0,1 0,-0.996 0a0.498,0.498 0,1 0,0.996 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.367,3.359a0.402,0.402 0,1 1,-0.804 0a0.402,0.402 0,1 1,0.804 0z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.774,7.064L11.629,11.755\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.168,10.341L17.943,11.357\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.157,6.446L14.141,10.22\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.698,10.995a0.613,0.613 105.061,1 0,0.612 1.062a0.613,0.613 105.061,1 0,-0.612 -1.062z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.547,8.927L20.322,9.942\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.784,8.904a0.498,0.498 105.061,1 0,0.497 0.863a0.498,0.498 105.061,1 0,-0.497 -0.863z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.144,9.27a0.498,0.498 105.061,1 0,0.497 0.863a0.498,0.498 105.061,1 0,-0.497 -0.863z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.421,9.684a0.402,0.402 105.061,1 0,0.401 0.697a0.402,0.402 105.061,1 0,-0.401 -0.697z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.741,6.584a0.402,0.402 105.061,1 0,0.401 0.697a0.402,0.402 105.061,1 0,-0.401 -0.697z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.54,8.914L17.555,5.139\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.18,7.855a0.498,0.498 105.061,1 1,-0.497 -0.863a0.498,0.498 105.061,1 1,0.497 0.863z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.546,6.495a0.498,0.498 105.061,1 1,-0.497 -0.863a0.498,0.498 105.061,1 1,0.497 0.863z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.829,5.184a0.402,0.402 105.061,1 1,-0.401 -0.697a0.402,0.402 105.061,1 1,0.401 0.697z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.349,6.996L12.41,11.829\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.896,10.371L6.104,11.32\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.976,6.459L9.925,10.251\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.354,11.069a0.613,0.613 75.948,1 1,-0.63 1.051a0.613,0.613 75.948,1 1,0.63 -1.051z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.542,8.915L3.75,9.864\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.05,9.298m0.256,-0.427a0.498,0.498 75.948,1 0,-0.512 0.854a0.498,0.498 75.948,1 0,0.512 -0.854\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.684,9.64m0.256,-0.427a0.498,0.498 75.948,1 0,-0.512 0.854a0.498,0.498 75.948,1 0,0.512 -0.854\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.656,9.604a0.402,0.402 75.948,1 1,-0.414 0.69a0.402,0.402 75.948,1 1,0.414 -0.69z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.391,6.517a0.402,0.402 75.948,1 1,-0.414 0.69a0.402,0.402 75.948,1 1,0.414 -0.69z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.55,8.903L6.601,5.11\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.184,7.406m-0.256,0.427a0.498,0.498 75.948,1 1,0.512 -0.854a0.498,0.498 75.948,1 1,-0.512 0.854\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.842,6.04m-0.256,0.427a0.498,0.498 75.948,1 1,0.512 -0.854a0.498,0.498 75.948,1 1,-0.512 0.854\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.326,5.15a0.402,0.402 75.948,1 0,0.414 -0.69a0.402,0.402 75.948,1 0,-0.414 0.69z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.75,15.879L11.542,11.299\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.059,12.752L15.126,16.512\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.909,11.599L14.149,12.666\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.931,11.503m0.299,-0.535a0.613,0.613 74.162,1 1,-0.597 1.07a0.613,0.613 74.162,1 1,0.597 -1.07\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.494,14.067L17.561,17.827\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M16.907,15.552m0.243,-0.435a0.498,0.498 74.162,1 1,-0.485 0.869a0.498,0.498 74.162,1 1,0.485 -0.869\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.291,16.906m0.243,-0.435a0.498,0.498 74.162,1 1,-0.485 0.869a0.498,0.498 74.162,1 1,0.485 -0.869\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.834,17.779a0.402,0.402 74.162,1 0,-0.392 0.702a0.402,0.402 74.162,1 0,0.392 -0.702z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.144,15.604a0.402,0.402 74.162,1 0,-0.392 0.702a0.402,0.402 74.162,1 0,0.392 -0.702z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M16.501,14.054L20.262,12.987\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.982,13.625m-0.243,0.435a0.498,0.498 74.162,1 0,0.485 -0.869a0.498,0.498 74.162,1 0,-0.485 0.869\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.336,13.241m-0.243,0.435a0.498,0.498 74.162,1 0,0.485 -0.869a0.498,0.498 74.162,1 0,-0.485 0.869\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.365,13.244a0.402,0.402 74.162,1 1,0.392 -0.702a0.402,0.402 74.162,1 1,-0.392 0.702z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.138,15.776L12.439,11.368\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.892,12.768L8.747,16.506\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.067,11.536L9.804,12.681\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.759,11.023a0.613,0.613 107.029,1 1,0.575 1.082a0.613,0.613 107.029,1 1,-0.575 -1.082z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.43,14.032L6.285,17.77\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.987,15.508m-0.233,-0.44a0.498,0.498 107.029,1 0,0.467 0.879a0.498,0.498 107.029,1 0,-0.467 -0.879\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.575,16.854m-0.233,-0.44a0.498,0.498 107.029,1 0,0.467 0.879a0.498,0.498 107.029,1 0,-0.467 -0.879\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.013,17.716a0.402,0.402 107.029,1 1,0.377 0.71a0.402,0.402 107.029,1 1,-0.377 -0.71z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.749,15.493a0.402,0.402 107.029,1 1,0.377 0.71a0.402,0.402 107.029,1 1,-0.377 -0.71z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M7.423,14.019L3.685,12.874\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.952,13.56m0.233,0.44a0.498,0.498 107.029,1 1,-0.467 -0.879a0.498,0.498 107.029,1 1,0.467 0.879\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.606,13.147m0.233,0.44a0.498,0.498 107.029,1 1,-0.467 -0.879a0.498,0.498 107.029,1 1,0.467 0.879\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.578,13.13a0.402,0.402 107.029,1 0,-0.377 -0.71a0.402,0.402 107.029,1 0,0.377 0.71z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.967,20.456V11.057\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.009,13.963L14.773,16.728\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.127,16.764L11.891,14\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.343,11.496a0.613,0.613 0,1 1,1.225 -0a0.613,0.613 0,1 1,-1.225 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.255,16.472a0.613,0.613 0,1 1,1.225 -0a0.613,0.613 0,1 1,-1.225 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.441,16.431a0.613,0.613 0,1 1,1.225 -0a0.613,0.613 0,1 1,-1.225 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.758,11.389a0.613,0.613 0,1 1,1.225 -0a0.613,0.613 0,1 1,-1.225 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.142,11.389a0.613,0.613 0,1 1,1.225 -0a0.613,0.613 0,1 1,-1.225 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.255,6.557a0.613,0.613 0,1 1,1.225 -0a0.613,0.613 0,1 1,-1.225 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.604,6.557a0.613,0.613 0,1 1,1.225 -0a0.613,0.613 0,1 1,-1.225 -0z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.97,16.731L14.735,19.495\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.066,17.814m-0.498,-0a0.498,0.498 0,1 0,0.996 -0a0.498,0.498 0,1 0,-0.996 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.062,18.81m-0.498,-0a0.498,0.498 0,1 0,0.996 -0a0.498,0.498 0,1 0,-0.996 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.56,19.71a0.402,0.402 0,1 1,0.804 -0a0.402,0.402 0,1 1,-0.804 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.535,20.667a0.402,0.402 0,1 1,0.804 -0a0.402,0.402 0,1 1,-0.804 -0z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.956,16.731L9.192,19.495\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.86,17.814m0.498,-0a0.498,0.498 0,1 1,-0.996 -0a0.498,0.498 0,1 1,0.996 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.864,18.81m0.498,-0a0.498,0.498 0,1 1,-0.996 -0a0.498,0.498 0,1 1,0.996 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.367,19.71a0.402,0.402 0,1 0,-0.804 -0a0.402,0.402 0,1 0,0.804 -0z\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_7.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.003,3L12.003,12.633\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.469,3.865L12.017,8.112\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.003,3L12.003,12.633\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.986,7.984L9.18,4.007\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.469,3.865L12.017,8.112\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.701,7.545L11.573,12.715\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.445,10.177L17.383,5.712\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.294,10.089L15.394,10.3\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.091,7.545L12.219,12.715\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.318,10.197L6.443,5.705\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.497,10.089L8.397,10.3\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.825,17.255L11.502,12.405\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.541,14.63L20.403,14.405\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.836,18.95L15.401,14.693\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.225,17.255L12.547,12.405\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.509,14.633L3.647,14.402\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.213,18.95L8.648,14.693\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.003,21.648L12.003,12.016\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.99,16.666L9.176,20.637\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.469,20.784L12.017,16.536\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.003,21.648L12.003,12.016\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.469,20.784L12.017,16.536\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#ffffff\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_8.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.042,4.812L12.042,9.256\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.042,2.782L12.042,3.73\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.042,10.406L12.042,11.354\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.01,2.211m-0.211,0a0.211,0.211 0,1 1,0.421 0a0.211,0.211 0,1 1,-0.421 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.01,4.275m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.01,9.793m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.635,3.155m-0.119,0.119a0.168,0.168 0,1 1,0.238 -0.238a0.168,0.168 0,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.663,4.227L8.993,3.557\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.065,4.584m-0.119,0.119a0.168,0.168 90,1 1,0.238 -0.238a0.168,0.168 90,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.045,5.61L10.422,4.986\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.448,5.967m-0.119,0.119a0.168,0.168 90,1 1,0.238 -0.238a0.168,0.168 90,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.365,3.155m-0.119,-0.119a0.168,0.168 90,1 1,0.238 0.238a0.168,0.168 90,1 1,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.292,4.182L14.963,3.512\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.935,4.584m-0.119,-0.119a0.168,0.168 90,1 1,0.238 0.238a0.168,0.168 90,1 1,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.91,5.565L13.533,4.942\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.552,5.967m-0.119,-0.119a0.168,0.168 90,1 1,0.238 0.238a0.168,0.168 90,1 1,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.042,19.188L12.042,14.744\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.042,21.218L12.042,20.27\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.042,13.594L12.042,12.646\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.01,21.789m-0.211,-0a0.211,0.211 0,1 0,0.421 -0a0.211,0.211 0,1 0,-0.421 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.01,19.725m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.01,14.207m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.635,20.845m-0.119,-0.119a0.168,0.168 0,1 0,0.238 0.238a0.168,0.168 0,1 0,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9.663,19.773L8.993,20.443\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.065,19.416m-0.119,-0.119a0.168,0.168 0,1 0,0.238 0.238a0.168,0.168 0,1 0,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M11.046,18.39L10.422,19.014\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M11.447,18.033m-0.119,-0.119a0.168,0.168 0,1 0,0.238 0.238a0.168,0.168 0,1 0,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.365,20.845m-0.119,0.119a0.168,0.168 90,1 0,0.238 -0.238a0.168,0.168 90,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M14.292,19.818L14.963,20.488\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.935,19.416m-0.119,0.119a0.168,0.168 90,1 0,0.238 -0.238a0.168,0.168 90,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.91,18.435L13.533,19.058\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.552,18.033m-0.119,0.119a0.168,0.168 90,1 0,0.238 -0.238a0.168,0.168 90,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.812,11.958L9.256,11.958\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M2.782,11.958L3.73,11.958\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.406,11.958L11.354,11.958\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.211,11.99m0,0.211a0.211,0.211 0,1 1,0 -0.421a0.211,0.211 0,1 1,0 0.421\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.275,11.99m0,0.168a0.168,0.168 0,1 1,0 -0.337a0.168,0.168 0,1 1,0 0.337\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M9.793,11.99m0,0.168a0.168,0.168 0,1 1,0 -0.337a0.168,0.168 0,1 1,0 0.337\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.155,15.365m0.119,0.119a0.168,0.168 0,1 1,-0.238 -0.238a0.168,0.168 90,1 1,0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.227,14.337L3.557,15.007\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.584,13.935m0.119,0.119a0.168,0.168 0,1 1,-0.238 -0.238a0.168,0.168 0,1 1,0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.61,12.955L4.986,13.578\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.967,12.552m0.119,0.119a0.168,0.168 90,1 1,-0.238 -0.238a0.168,0.168 90,1 1,0.238 0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.155,8.635m-0.119,0.119a0.168,0.168 90,1 1,0.238 -0.238a0.168,0.168 0,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.182,9.707L3.512,9.037\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.584,10.065m-0.119,0.119a0.168,0.168 0,1 1,0.238 -0.238a0.168,0.168 0,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.565,11.09L4.942,10.467\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.967,11.448m-0.119,0.119a0.168,0.168 0,1 1,0.238 -0.238a0.168,0.168 0,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.188,11.958L14.744,11.958\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M21.218,11.958L20.27,11.958\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.594,11.958L12.646,11.958\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.789,11.99m-0,0.211a0.211,0.211 0,1 0,-0 -0.421a0.211,0.211 0,1 0,-0 0.421\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.725,11.99m-0,0.168a0.168,0.168 0,1 0,-0 -0.337a0.168,0.168 0,1 0,-0 0.337\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M14.207,11.99m-0,0.168a0.168,0.168 0,1 0,-0 -0.337a0.168,0.168 0,1 0,-0 0.337\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.845,15.365m-0.119,0.119a0.168,0.168 0,1 0,0.238 -0.238a0.168,0.168 0,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.773,14.337L20.443,15.007\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.416,13.935m-0.119,0.119a0.168,0.168 0,1 0,0.238 -0.238a0.168,0.168 0,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.39,12.954L19.014,13.578\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.033,12.553m-0.119,0.119a0.168,0.168 0,1 0,0.238 -0.238a0.168,0.168 0,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.845,8.635m0.119,0.119a0.168,0.168 90,1 0,-0.238 -0.238a0.168,0.168 90,1 0,0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.818,9.707L20.488,9.037\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.416,10.065m0.119,0.119a0.168,0.168 90,1 0,-0.238 -0.238a0.168,0.168 90,1 0,0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.435,11.09L19.058,10.467\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.033,11.448m0.119,0.119a0.168,0.168 90,1 0,-0.238 -0.238a0.168,0.168 90,1 0,0.238 0.238\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.112,6.946L13.97,10.089\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.548,5.511L17.877,6.181\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.157,10.902L12.486,11.572\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.929,5.085m-0.149,-0.149a0.211,0.211 0,1 1,0.298 0.298a0.211,0.211 0,1 1,-0.298 -0.298\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.47,6.544m-0.119,-0.119a0.168,0.168 0,1 1,0.238 0.238a0.168,0.168 0,1 1,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.568,10.446m-0.119,-0.119a0.168,0.168 90,1 1,0.238 0.238a0.168,0.168 90,1 1,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.875,3.366m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.844,4.851L15.844,3.903\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.875,5.388m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.844,6.806L15.844,5.925\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.875,7.343m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.634,8.125m-0,-0.168a0.168,0.168 0,1 1,-0 0.337a0.168,0.168 0,1 1,-0 -0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.149,8.093L20.097,8.093\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.612,8.125m-0,-0.168a0.168,0.168 0,1 1,-0 0.337a0.168,0.168 0,1 1,-0 -0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.194,8.093L18.075,8.093\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M16.657,8.125m-0,-0.168a0.168,0.168 0,1 1,-0 0.337a0.168,0.168 0,1 1,-0 -0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.946,17.112L10.089,13.97\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.511,18.548L6.181,17.877\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.902,13.157L11.572,12.486\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.085,18.929m-0.149,-0.149a0.211,0.211 0,1 0,0.298 0.298a0.211,0.211 0,1 0,-0.298 -0.298\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.544,17.47m-0.119,-0.119a0.168,0.168 0,1 0,0.238 0.238a0.168,0.168 0,1 0,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.446,13.568m-0.119,-0.119a0.168,0.168 90,1 0,0.238 0.238a0.168,0.168 90,1 0,-0.238 -0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.366,15.875m0,-0.168a0.168,0.168 0,1 0,0 0.337a0.168,0.168 0,1 0,0 -0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.851,15.844L3.903,15.844\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.388,15.875m0,-0.168a0.168,0.168 0,1 0,0 0.337a0.168,0.168 0,1 0,0 -0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.806,15.844L5.925,15.844\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.343,15.875m0,-0.168a0.168,0.168 0,1 0,0 0.337a0.168,0.168 0,1 0,0 -0.337\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.125,20.634m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.093,19.149L8.093,20.097\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.125,18.612m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.093,17.194L8.093,18.075\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.125,16.657m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.946,6.888L10.089,10.03\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.511,5.452L6.181,6.123\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M10.902,10.843L11.572,11.514\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.085,5.071m-0.149,0.149a0.211,0.211 90,1 1,0.298 -0.298a0.211,0.211 90,1 1,-0.298 0.298\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.544,6.53m-0.119,0.119a0.168,0.168 90,1 1,0.238 -0.238a0.168,0.168 90,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.446,10.432m-0.119,0.119a0.168,0.168 0,1 1,0.238 -0.238a0.168,0.168 0,1 1,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M3.366,8.125m0,0.168a0.168,0.168 0,1 1,0 -0.337a0.168,0.168 0,1 1,0 0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M4.851,8.156L3.903,8.156\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.388,8.125m0,0.168a0.168,0.168 0,1 1,0 -0.337a0.168,0.168 0,1 1,0 0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M6.806,8.156L5.925,8.156\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M7.343,8.125m0,0.168a0.168,0.168 0,1 1,0 -0.337a0.168,0.168 0,1 1,0 0.337\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.125,3.366m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.093,4.851L8.093,3.903\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.125,5.388m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M8.093,6.806L8.093,5.925\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.125,7.343m-0.168,0a0.168,0.168 0,1 1,0.337 0a0.168,0.168 0,1 1,-0.337 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.112,17.054L13.97,13.911\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.548,18.489L17.877,17.819\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M13.157,13.098L12.486,12.428\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.929,18.915m-0.149,0.149a0.211,0.211 0,1 0,0.298 -0.298a0.211,0.211 0,1 0,-0.298 0.298\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.47,17.456m-0.119,0.119a0.168,0.168 0,1 0,0.238 -0.238a0.168,0.168 0,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.568,13.554m-0.119,0.119a0.168,0.168 90,1 0,0.238 -0.238a0.168,0.168 90,1 0,-0.238 0.238\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.875,20.634m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.844,19.149L15.844,20.097\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.875,18.612m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M15.844,17.194L15.844,18.075\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.875,16.657m-0.168,-0a0.168,0.168 0,1 0,0.337 -0a0.168,0.168 0,1 0,-0.337 -0\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M20.634,15.875m-0,0.168a0.168,0.168 0,1 0,-0 -0.337a0.168,0.168 0,1 0,-0 0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19.149,15.907L20.097,15.907\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.612,15.875m-0,0.168a0.168,0.168 0,1 0,-0 -0.337a0.168,0.168 0,1 0,-0 0.337\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M17.194,15.907L18.075,15.907\"\n        android:strokeWidth=\"0.4\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M16.657,15.875m-0,0.168a0.168,0.168 0,1 0,-0 -0.337a0.168,0.168 0,1 0,-0 0.337\" />\n</vector>\n"
  },
  {
    "path": "lib/snowfall/src/main/res/drawable/ic_flake_9.xml",
    "content": "<!--\n  ~ ImageToolbox is an image editor for android\n  ~ Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  ~ You should have received a copy of the Apache License\n  ~ along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.047,3.376L12.047,12.092\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,2.797C13.898,2.958 13.644,3.473 13.169,3.948C12.694,4.423 12.179,4.677 12.017,4.516C11.856,4.354 11.71,4.218 12.184,3.743C12.659,3.268 13.193,3.491 13.737,2.797Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,8.668C13.898,8.829 13.644,9.345 13.169,9.82C12.694,10.294 12.179,10.548 12.017,10.387C11.856,10.226 11.71,10.089 12.184,9.615C12.659,9.14 13.193,9.362 13.737,8.668Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,2.797C10.102,2.958 10.356,3.473 10.831,3.948C11.306,4.423 11.821,4.677 11.983,4.516C12.144,4.354 12.29,4.218 11.816,3.743C11.341,3.268 10.807,3.491 10.263,2.797Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,8.668C10.102,8.829 10.356,9.345 10.831,9.82C11.306,10.294 11.821,10.548 11.983,10.387C12.144,10.226 12.29,10.089 11.816,9.615C11.341,9.14 10.807,9.362 10.263,8.668Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.981,4.02C8.662,4.131 9.041,4.715 9.829,5.324C10.616,5.933 11.513,6.336 11.832,6.225C12.152,6.113 12.44,6.022 11.653,5.413C10.865,4.804 9.858,4.866 8.981,4.02Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.019,4.02C15.338,4.131 14.959,4.715 14.171,5.324C13.384,5.933 12.487,6.336 12.168,6.225C11.848,6.113 11.56,6.022 12.347,5.413C13.135,4.804 14.142,4.866 15.019,4.02Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,4.798a1.216,0.183 90,1 0,0 -2.431a1.216,0.183 90,1 0,0 2.431z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,2.413m-0.413,0a0.413,0.413 0,1 1,0.826 0a0.413,0.413 0,1 1,-0.826 0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M12.047,20.624L12.047,11.908\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,21.204C13.898,21.042 13.644,20.527 13.169,20.052C12.694,19.577 12.179,19.323 12.017,19.484C11.856,19.646 11.71,19.782 12.184,20.257C12.659,20.732 13.193,20.509 13.737,21.204Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.737,15.332C13.898,15.171 13.644,14.655 13.169,14.18C12.694,13.706 12.179,13.452 12.017,13.613C11.856,13.774 11.71,13.911 12.184,14.385C12.659,14.86 13.193,14.638 13.737,15.332Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,21.204C10.102,21.042 10.356,20.527 10.831,20.052C11.306,19.577 11.821,19.323 11.983,19.484C12.144,19.646 12.29,19.782 11.816,20.257C11.341,20.732 10.807,20.509 10.263,21.204Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.263,15.332C10.102,15.171 10.356,14.655 10.831,14.18C11.306,13.706 11.821,13.452 11.983,13.613C12.144,13.774 12.29,13.911 11.816,14.385C11.341,14.86 10.807,14.638 10.263,15.332Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.981,19.98C8.662,19.869 9.041,19.285 9.829,18.676C10.616,18.067 11.513,17.664 11.832,17.775C12.152,17.887 12.44,17.978 11.653,18.587C10.865,19.196 9.858,19.134 8.981,19.98Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.019,19.98C15.338,19.869 14.959,19.285 14.171,18.676C13.384,18.067 12.487,17.664 12.168,17.775C11.848,17.887 11.56,17.978 12.347,18.587C13.135,19.196 14.142,19.134 15.019,19.98Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,19.202a1.216,0.183 90,1 1,0 2.431a1.216,0.183 90,1 1,0 -2.431z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M12.001,21.587m-0.413,-0a0.413,0.413 0,1 0,0.826 -0a0.413,0.413 0,1 0,-0.826 -0\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M3.376,11.953L12.092,11.953\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.797,10.263C2.958,10.102 3.473,10.356 3.948,10.831C4.423,11.306 4.677,11.821 4.516,11.983C4.354,12.144 4.218,12.29 3.743,11.816C3.268,11.341 3.491,10.807 2.797,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.668,10.263C8.829,10.102 9.345,10.356 9.82,10.831C10.294,11.306 10.548,11.821 10.387,11.983C10.226,12.144 10.089,12.29 9.615,11.816C9.14,11.341 9.362,10.807 8.668,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.797,13.737C2.958,13.898 3.473,13.644 3.948,13.169C4.423,12.694 4.677,12.179 4.516,12.017C4.354,11.856 4.218,11.71 3.743,12.184C3.268,12.659 3.491,13.193 2.797,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.668,13.737C8.829,13.898 9.345,13.644 9.82,13.169C10.294,12.694 10.548,12.179 10.387,12.017C10.226,11.856 10.089,11.71 9.615,12.184C9.14,12.659 9.362,13.193 8.668,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.02,15.019C4.131,15.338 4.715,14.959 5.324,14.171C5.933,13.384 6.336,12.487 6.225,12.167C6.113,11.848 6.022,11.56 5.413,12.347C4.804,13.135 4.866,14.142 4.02,15.019Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.02,8.981C4.131,8.662 4.715,9.041 5.324,9.829C5.933,10.616 6.336,11.513 6.225,11.833C6.113,12.152 6.022,12.44 5.413,11.653C4.804,10.865 4.866,9.858 4.02,8.981Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.798,11.999a0.183,1.216 90,1 0,-2.431 -0a0.183,1.216 90,1 0,2.431 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M2.413,11.999m0,0.413a0.413,0.413 0,1 1,0 -0.826a0.413,0.413 0,1 1,0 0.826\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M20.624,11.953L11.908,11.953\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.204,10.263C21.042,10.102 20.527,10.356 20.052,10.831C19.577,11.306 19.323,11.821 19.484,11.983C19.646,12.144 19.782,12.29 20.257,11.816C20.732,11.341 20.509,10.807 21.204,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.332,10.263C15.171,10.102 14.655,10.356 14.18,10.831C13.706,11.306 13.452,11.821 13.613,11.983C13.774,12.144 13.911,12.29 14.385,11.816C14.86,11.341 14.638,10.807 15.332,10.263Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.204,13.737C21.042,13.898 20.527,13.644 20.052,13.169C19.577,12.694 19.323,12.179 19.484,12.017C19.646,11.856 19.782,11.71 20.257,12.184C20.732,12.659 20.509,13.193 21.204,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.332,13.737C15.171,13.898 14.655,13.644 14.18,13.169C13.706,12.694 13.452,12.179 13.613,12.017C13.774,11.856 13.911,11.71 14.385,12.184C14.86,12.659 14.638,13.193 15.332,13.737Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.98,15.019C19.869,15.338 19.285,14.959 18.676,14.171C18.067,13.384 17.664,12.487 17.775,12.168C17.887,11.848 17.978,11.56 18.587,12.347C19.196,13.135 19.134,14.142 19.98,15.019Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.98,8.981C19.869,8.662 19.285,9.041 18.676,9.829C18.067,10.616 17.664,11.513 17.775,11.833C17.887,12.152 17.978,12.44 18.587,11.653C19.196,10.865 19.134,9.858 19.98,8.981Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.202,11.999a0.183,1.216 90,1 1,2.431 -0a0.183,1.216 90,1 1,-2.431 -0z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M21.587,11.999m-0,0.413a0.413,0.413 0,1 0,-0 -0.826a0.413,0.413 0,1 0,-0 0.826\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.132,5.935L11.968,12.098\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.736,6.72C19.736,6.948 19.192,7.133 18.52,7.133C17.849,7.133 17.305,6.948 17.305,6.72C17.305,6.492 17.298,6.292 17.969,6.292C18.64,6.292 18.861,6.827 19.736,6.72Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.584,10.872C15.584,11.1 15.04,11.285 14.368,11.285C13.697,11.285 13.153,11.1 13.153,10.872C13.153,10.644 13.146,10.444 13.817,10.444C14.488,10.444 14.709,10.979 15.584,10.872Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.28,4.264C17.052,4.264 16.867,4.808 16.867,5.48C16.867,6.151 17.052,6.695 17.28,6.695C17.508,6.695 17.708,6.703 17.708,6.031C17.708,5.36 17.173,5.139 17.28,4.264Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.128,8.416C12.9,8.416 12.715,8.96 12.715,9.632C12.715,10.303 12.9,10.847 13.128,10.847C13.356,10.847 13.556,10.854 13.556,10.183C13.556,9.512 13.021,9.291 13.128,8.416Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.508,4.222C15.203,4.075 15.059,4.757 15.185,5.744C15.311,6.732 15.661,7.651 15.965,7.798C16.27,7.945 16.539,8.084 16.412,7.097C16.286,6.109 15.53,5.44 15.508,4.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.778,8.492C19.925,8.797 19.243,8.941 18.256,8.815C17.268,8.688 16.349,8.339 16.202,8.035C16.055,7.73 15.916,7.461 16.903,7.588C17.891,7.714 18.56,8.47 19.778,8.492Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.093,6.908a0.183,1.216 45,1 0,1.719 -1.719a0.183,1.216 45,1 0,-1.719 1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.78,5.221m-0.292,-0.292a0.413,0.413 90,1 1,0.584 0.584a0.413,0.413 90,1 1,-0.584 -0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.935,18.132L12.098,11.968\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.72,19.736C6.948,19.736 7.133,19.191 7.133,18.52C7.133,17.849 6.948,17.305 6.72,17.305C6.492,17.305 6.292,17.297 6.292,17.969C6.292,18.64 6.827,18.861 6.72,19.736Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.872,15.584C11.1,15.584 11.285,15.04 11.285,14.368C11.285,13.697 11.1,13.153 10.872,13.153C10.644,13.153 10.444,13.146 10.444,13.817C10.444,14.488 10.979,14.709 10.872,15.584Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.264,17.28C4.264,17.052 4.808,16.867 5.48,16.867C6.151,16.867 6.695,17.052 6.695,17.28C6.695,17.508 6.703,17.708 6.031,17.708C5.36,17.708 5.139,17.173 4.264,17.28Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.416,13.128C8.416,12.9 8.96,12.715 9.632,12.715C10.303,12.715 10.847,12.9 10.847,13.128C10.847,13.356 10.854,13.556 10.183,13.556C9.512,13.556 9.291,13.021 8.416,13.128Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.222,15.508C4.075,15.203 4.757,15.059 5.744,15.185C6.732,15.311 7.651,15.661 7.798,15.965C7.945,16.27 8.084,16.539 7.097,16.412C6.109,16.286 5.44,15.53 4.222,15.508Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.492,19.778C8.797,19.925 8.941,19.243 8.815,18.256C8.688,17.268 8.339,16.349 8.035,16.202C7.73,16.055 7.461,15.916 7.588,16.903C7.714,17.891 8.47,18.56 8.492,19.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.908,17.093a1.216,0.183 135,1 1,-1.719 1.719a1.216,0.183 135,1 1,1.719 -1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.221,18.78m-0.292,-0.292a0.413,0.413 0,1 0,0.584 0.584a0.413,0.413 0,1 0,-0.584 -0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M5.935,5.868L12.098,12.032\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.72,4.264C6.948,4.264 7.133,4.808 7.133,5.48C7.133,6.151 6.948,6.695 6.72,6.695C6.492,6.695 6.292,6.703 6.292,6.031C6.292,5.36 6.827,5.139 6.72,4.264Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M10.872,8.416C11.1,8.416 11.285,8.96 11.285,9.632C11.285,10.303 11.1,10.847 10.872,10.847C10.644,10.847 10.444,10.854 10.444,10.183C10.444,9.512 10.979,9.291 10.872,8.416Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.264,6.72C4.264,6.948 4.808,7.133 5.48,7.133C6.151,7.133 6.695,6.948 6.695,6.72C6.695,6.492 6.703,6.292 6.031,6.292C5.36,6.292 5.139,6.827 4.264,6.72Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.416,10.872C8.416,11.1 8.96,11.285 9.632,11.285C10.303,11.285 10.847,11.1 10.847,10.872C10.847,10.644 10.854,10.444 10.183,10.444C9.512,10.444 9.291,10.979 8.416,10.872Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M4.222,8.492C4.075,8.797 4.757,8.941 5.744,8.815C6.732,8.688 7.651,8.339 7.798,8.035C7.945,7.73 8.084,7.461 7.097,7.588C6.109,7.714 5.44,8.47 4.222,8.492Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M8.492,4.222C8.797,4.075 8.941,4.757 8.815,5.744C8.688,6.732 8.339,7.651 8.035,7.798C7.73,7.945 7.461,8.084 7.588,7.097C7.714,6.109 8.47,5.44 8.492,4.222Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M6.908,6.907a1.216,0.183 45,1 0,-1.719 -1.719a1.216,0.183 45,1 0,1.719 1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M5.221,5.22m-0.292,0.292a0.413,0.413 90,1 1,0.584 -0.584a0.413,0.413 0,1 1,-0.584 0.584\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M18.132,18.065L11.968,11.902\"\n        android:strokeWidth=\"0.6\"\n        android:strokeColor=\"#ffffff\"\n        android:strokeLineCap=\"round\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.736,17.28C19.736,17.052 19.192,16.867 18.52,16.867C17.849,16.867 17.305,17.052 17.305,17.28C17.305,17.508 17.298,17.708 17.969,17.708C18.64,17.708 18.861,17.173 19.736,17.28Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.584,13.128C15.584,12.9 15.04,12.715 14.368,12.715C13.697,12.715 13.153,12.9 13.153,13.128C13.153,13.356 13.146,13.556 13.817,13.556C14.488,13.556 14.709,13.021 15.584,13.128Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.28,19.736C17.052,19.736 16.867,19.192 16.867,18.52C16.867,17.849 17.052,17.305 17.28,17.305C17.508,17.305 17.708,17.297 17.708,17.969C17.708,18.64 17.173,18.861 17.28,19.736Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M13.128,15.584C12.9,15.584 12.715,15.04 12.715,14.368C12.715,13.697 12.9,13.153 13.128,13.153C13.356,13.153 13.556,13.146 13.556,13.817C13.556,14.488 13.021,14.709 13.128,15.584Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M15.508,19.778C15.203,19.925 15.059,19.243 15.185,18.256C15.311,17.268 15.661,16.349 15.965,16.202C16.27,16.055 16.539,15.916 16.412,16.903C16.286,17.891 15.53,18.56 15.508,19.778Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M19.778,15.508C19.925,15.203 19.243,15.059 18.256,15.185C17.268,15.311 16.349,15.661 16.202,15.965C16.055,16.27 15.916,16.539 16.903,16.412C17.891,16.286 18.56,15.53 19.778,15.508Z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M17.093,17.092a0.183,1.216 135,1 1,1.719 1.719a0.183,1.216 135,1 1,-1.719 -1.719z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M18.78,18.779m-0.292,0.292a0.413,0.413 0,1 0,0.584 -0.584a0.413,0.413 0,1 0,-0.584 0.584\" />\n</vector>\n"
  },
  {
    "path": "lib/zoomable/.gitignore",
    "content": "/build\n/.idea/\n/.idea"
  },
  {
    "path": "lib/zoomable/build.gradle.kts",
    "content": "plugins {\n    alias(libs.plugins.image.toolbox.library)\n    alias(libs.plugins.image.toolbox.compose)\n}\n\nandroid.namespace = \"net.engawapg.lib.zoomable\""
  },
  {
    "path": "lib/zoomable/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2022 usuiat\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~ http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<manifest>\n\n</manifest>"
  },
  {
    "path": "lib/zoomable/src/main/java/net/engawapg/lib/zoomable/ZoomState.kt",
    "content": "/*\n * Copyright 2022 usuiat\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage net.engawapg.lib.zoomable\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.DecayAnimationSpec\nimport androidx.compose.animation.core.exponentialDecay\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.input.pointer.util.VelocityTracker\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.awaitAll\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.launch\nimport java.lang.Float.max\nimport kotlin.math.abs\n\n/**\n * A state object that manage scale and offset.\n *\n * @param maxScale The maximum scale of the content.\n * @param contentSize Size of content (i.e. image size.) If Zero, the composable layout size will\n * be used as content size.\n * @param velocityDecay The decay animation spec for fling behaviour.\n */\n@Stable\nclass ZoomState(\n    @FloatRange(from = 1.0) val maxScale: Float = 5f,\n    @FloatRange(from = 0.0) val minScale: Float = 1f,\n    private var contentSize: Size = Size.Zero,\n    private val velocityDecay: DecayAnimationSpec<Float> = exponentialDecay(),\n) {\n    init {\n        require(maxScale >= 1.0f) { \"maxScale must be at least 1.0.\" }\n        require(minScale > 0.0f) { \"minScale must be at least 0.0.\" }\n    }\n\n    private var _scale = Animatable(minScale).apply {\n        updateBounds(0.9f, maxScale)\n    }\n\n    /**\n     * The scale of the content.\n     */\n    val scale: Float\n        get() = _scale.value\n\n    private var _offsetX = Animatable(0f)\n\n    /**\n     * The horizontal offset of the content.\n     */\n    val offsetX: Float\n        get() = _offsetX.value\n\n    private var _offsetY = Animatable(0f)\n\n    /**\n     * The vertical offset of the content.\n     */\n    val offsetY: Float\n        get() = _offsetY.value\n\n    private var layoutSize = Size.Zero\n\n    /**\n     * Set composable layout size.\n     *\n     * Basically This function is called from [Modifier.zoomable] only.\n     *\n     * @param size The size of composable layout size.\n     */\n    fun setLayoutSize(size: Size) {\n        layoutSize = size\n        updateFitContentSize()\n    }\n\n    /**\n     * Set the content size.\n     *\n     * @param size The content size, for example an image size in pixel.\n     */\n    fun setContentSize(size: Size) {\n        contentSize = size\n        updateFitContentSize()\n    }\n\n    private var fitContentSize = Size.Zero\n    private fun updateFitContentSize() {\n        if (layoutSize == Size.Zero) {\n            fitContentSize = Size.Zero\n            return\n        }\n\n        if (contentSize == Size.Zero) {\n            fitContentSize = layoutSize\n            return\n        }\n\n        val contentAspectRatio = contentSize.width / contentSize.height\n        val layoutAspectRatio = layoutSize.width / layoutSize.height\n\n        fitContentSize = if (contentAspectRatio > layoutAspectRatio) {\n            contentSize * (layoutSize.width / contentSize.width)\n        } else {\n            contentSize * (layoutSize.height / contentSize.height)\n        }\n    }\n\n    /**\n     * Reset the scale and the offsets.\n     */\n    suspend fun reset() = coroutineScope {\n        launch { _scale.snapTo(minScale) }\n        _offsetX.updateBounds(0f, 0f)\n        launch { _offsetX.snapTo(0f) }\n        _offsetY.updateBounds(0f, 0f)\n        launch { _offsetY.snapTo(0f) }\n    }\n\n    private val velocityTracker = VelocityTracker()\n\n    internal fun startGesture() {\n        velocityTracker.resetTracking()\n    }\n\n    internal fun willChangeOffset(pan: Offset): Boolean {\n        var willChange = true\n        val ratio = (abs(pan.x) / abs(pan.y))\n        if (ratio > 3) {   // Horizontal drag\n            if ((pan.x < 0) && (_offsetX.value == _offsetX.lowerBound)) {\n                // Drag R to L when right edge of the content is shown.\n                willChange = false\n            }\n            if ((pan.x > 0) && (_offsetX.value == _offsetX.upperBound)) {\n                // Drag L to R when left edge of the content is shown.\n                willChange = false\n            }\n        } else if (ratio < 0.33) { // Vertical drag\n            if ((pan.y < 0) && (_offsetY.value == _offsetY.lowerBound)) {\n                // Drag bottom to top when bottom edge of the content is shown.\n                willChange = false\n            }\n            if ((pan.y > 0) && (_offsetY.value == _offsetY.upperBound)) {\n                // Drag top to bottom when top edge of the content is shown.\n                willChange = false\n            }\n        }\n        return willChange\n    }\n\n    internal suspend fun applyGesture(\n        pan: Offset,\n        zoom: Float,\n        position: Offset,\n        timeMillis: Long\n    ) = coroutineScope {\n        val newScale = (scale * zoom).coerceIn(0.9f, maxScale)\n        val newOffset = calculateNewOffset(newScale, position, pan)\n        val newBounds = calculateNewBounds(newScale)\n\n        _offsetX.updateBounds(newBounds.left, newBounds.right)\n        launch {\n            _offsetX.snapTo(newOffset.x)\n        }\n\n        _offsetY.updateBounds(newBounds.top, newBounds.bottom)\n        launch {\n            _offsetY.snapTo(newOffset.y)\n        }\n\n        launch {\n            _scale.snapTo(newScale)\n        }\n\n        if (zoom == minScale) {\n            velocityTracker.addPosition(timeMillis, position)\n        } else {\n            velocityTracker.resetTracking()\n        }\n    }\n\n    /**\n     * Change the scale with animation.\n     *\n     * Zoom in or out to [targetScale] around the [position].\n     *\n     * @param targetScale The target scale value.\n     * @param position Zoom around this point.\n     * @param animationSpec The animation configuration.\n     */\n    suspend fun changeScale(\n        targetScale: Float,\n        position: Offset,\n        animationSpec: AnimationSpec<Float> = spring(),\n    ) = coroutineScope {\n        val newScale = targetScale.coerceIn(1f, maxScale)\n        val newOffset = calculateNewOffset(newScale, position, Offset.Zero)\n        val newBounds = calculateNewBounds(newScale)\n\n        val x = newOffset.x.coerceIn(newBounds.left, newBounds.right)\n        launch {\n            _offsetX.updateBounds(null, null)\n            _offsetX.animateTo(x, animationSpec)\n            _offsetX.updateBounds(newBounds.left, newBounds.right)\n        }\n\n        val y = newOffset.y.coerceIn(newBounds.top, newBounds.bottom)\n        launch {\n            _offsetY.updateBounds(null, null)\n            _offsetY.animateTo(y, animationSpec)\n            _offsetY.updateBounds(newBounds.top, newBounds.bottom)\n        }\n\n        launch {\n            _scale.animateTo(newScale, animationSpec)\n        }\n    }\n\n    private fun calculateNewOffset(\n        newScale: Float,\n        position: Offset,\n        pan: Offset,\n    ): Offset {\n        val size = fitContentSize * scale\n        val newSize = fitContentSize * newScale\n        val deltaWidth = newSize.width - size.width\n        val deltaHeight = newSize.height - size.height\n\n        // Position with the origin at the left top corner of the content.\n        val xInContent = position.x - offsetX + (size.width - layoutSize.width) * 0.5f\n        val yInContent = position.y - offsetY + (size.height - layoutSize.height) * 0.5f\n        // Amount of offset change required to zoom around the position.\n        val deltaX = (deltaWidth * 0.5f) - (deltaWidth * xInContent / size.width)\n        val deltaY = (deltaHeight * 0.5f) - (deltaHeight * yInContent / size.height)\n\n        val x = offsetX + pan.x + deltaX\n        val y = offsetY + pan.y + deltaY\n\n        return Offset(x, y)\n    }\n\n    private fun calculateNewBounds(\n        newScale: Float,\n    ): Rect {\n        val newSize = fitContentSize * newScale\n        val boundX = max((newSize.width - layoutSize.width), 0f) * 0.5f\n        val boundY = max((newSize.height - layoutSize.height), 0f) * 0.5f\n        return Rect(-boundX, -boundY, boundX, boundY)\n    }\n\n    internal suspend fun startFling() = coroutineScope {\n        val velocity = velocityTracker.calculateVelocity()\n        if (velocity.x != 0f) {\n            launch {\n                _offsetX.animateDecay(velocity.x, velocityDecay)\n            }\n        }\n        if (velocity.y != 0f) {\n            launch {\n                _offsetY.animateDecay(velocity.y, velocityDecay)\n            }\n        }\n    }\n\n    /**\n     * Animates the centering of content by modifying the offset and scale based on content coordinates.\n     *\n     * @param offset The offset to apply for centering the content.\n     * @param scale The scale to apply for zooming the content.\n     * @param animationSpec AnimationSpec for centering and scaling.\n     */\n    suspend fun centerByContentCoordinate(\n        offset: Offset,\n        scale: Float = 3f,\n        animationSpec: AnimationSpec<Float> = tween(700),\n    ) = coroutineScope {\n        val fitContentSizeFactor = fitContentSize.width / contentSize.width\n\n        val boundX = max((fitContentSize.width * scale - layoutSize.width), 0f) / 2f\n        val boundY = max((fitContentSize.height * scale - layoutSize.height), 0f) / 2f\n\n        suspend fun executeZoomWithAnimation() {\n            listOf(\n                async {\n                    val fixedTargetOffsetX =\n                        ((fitContentSize.width / 2 - offset.x * fitContentSizeFactor) * scale)\n                            .coerceIn(\n                                minimumValue = -boundX,\n                                maximumValue = boundX,\n                            ) // Adjust zoom target position to prevent execute zoom animation to out of content boundaries\n                    _offsetX.animateTo(fixedTargetOffsetX, animationSpec)\n                },\n                async {\n                    val fixedTargetOffsetY =\n                        ((fitContentSize.height / 2 - offset.y * fitContentSizeFactor) * scale)\n                            .coerceIn(minimumValue = -boundY, maximumValue = boundY)\n                    _offsetY.animateTo(fixedTargetOffsetY, animationSpec)\n                },\n                async {\n                    _scale.animateTo(scale, animationSpec)\n                },\n            ).awaitAll()\n        }\n\n        if (scale > _scale.value) {\n            _offsetX.updateBounds(-boundX, boundX)\n            _offsetY.updateBounds(-boundY, boundY)\n            executeZoomWithAnimation()\n        } else {\n            executeZoomWithAnimation()\n            _offsetX.updateBounds(-boundX, boundX)\n            _offsetY.updateBounds(-boundY, boundY)\n        }\n    }\n\n    /**\n     * Animates the centering of content by modifying the offset and scale based on layout coordinates.\n     *\n     * @param offset The offset to apply for centering the content.\n     * @param scale The scale to apply for zooming the content.\n     * @param animationSpec AnimationSpec for centering and scaling.\n     */\n    suspend fun centerByLayoutCoordinate(\n        offset: Offset,\n        scale: Float = 3f,\n        animationSpec: AnimationSpec<Float> = tween(700),\n    ) = coroutineScope {\n\n        val boundX = max((fitContentSize.width * scale - layoutSize.width), 0f) / 2f\n        val boundY = max((fitContentSize.height * scale - layoutSize.height), 0f) / 2f\n\n        suspend fun executeZoomWithAnimation() {\n            listOf(\n                async {\n                    val fixedTargetOffsetX =\n                        ((layoutSize.width / 2 - offset.x) * scale)\n                            .coerceIn(\n                                minimumValue = -boundX,\n                                maximumValue = boundX,\n                            ) // Adjust zoom target position to prevent execute zoom animation to out of content boundaries\n                    _offsetX.animateTo(fixedTargetOffsetX, animationSpec)\n                },\n                async {\n                    val fixedTargetOffsetY = ((layoutSize.height / 2 - offset.y) * scale)\n                        .coerceIn(minimumValue = -boundY, maximumValue = boundY)\n                    _offsetY.animateTo(fixedTargetOffsetY, animationSpec)\n                },\n                async {\n                    _scale.animateTo(scale, animationSpec)\n                },\n            ).awaitAll()\n        }\n\n        if (scale > _scale.value) {\n            _offsetX.updateBounds(-boundX, boundX)\n            _offsetY.updateBounds(-boundY, boundY)\n            executeZoomWithAnimation()\n        } else {\n            executeZoomWithAnimation()\n            _offsetX.updateBounds(-boundX, boundX)\n            _offsetY.updateBounds(-boundY, boundY)\n        }\n    }\n}\n\n/**\n * Creates a [ZoomState] that is remembered across compositions.\n *\n * @param maxScale The maximum scale of the content.\n * @param minScale The minimum scale of the content.\n * @param contentSize Size of content (i.e. image size.) If Zero, the composable layout size will\n * be used as content size.\n * @param velocityDecay The decay animation spec for fling behaviour.\n * @param key remembering composition key\n */\n@Composable\nfun rememberZoomState(\n    @FloatRange(from = 1.0) maxScale: Float = 5f,\n    @FloatRange(from = 0.0) minScale: Float = 1f,\n    contentSize: Size = Size.Zero,\n    velocityDecay: DecayAnimationSpec<Float> = exponentialDecay(),\n    key: Any? = null\n) = remember(key) {\n    ZoomState(\n        maxScale = maxScale,\n        minScale = minScale,\n        contentSize = contentSize,\n        velocityDecay = velocityDecay\n    )\n}"
  },
  {
    "path": "lib/zoomable/src/main/java/net/engawapg/lib/zoomable/Zoomable.kt",
    "content": "/*\n * Copyright 2022 usuiat\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage net.engawapg.lib.zoomable\n\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.spring\nimport androidx.compose.foundation.gestures.awaitEachGesture\nimport androidx.compose.foundation.gestures.awaitFirstDown\nimport androidx.compose.foundation.gestures.calculateCentroid\nimport androidx.compose.foundation.gestures.calculatePan\nimport androidx.compose.foundation.gestures.calculateZoom\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEvent\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode\nimport androidx.compose.ui.input.pointer.positionChanged\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.LayoutModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.PointerInputModifierNode\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.toSize\nimport androidx.compose.ui.util.fastAny\nimport androidx.compose.ui.util.fastForEach\nimport kotlinx.coroutines.launch\n\n/**\n * Customized transform gesture detector.\n *\n * A caller of this function can choose if the pointer events will be consumed.\n * And the caller can implement [onGestureStart] and [onGestureEnd] event.\n *\n * @param canConsumeGesture Lambda that asks the caller whether the gesture can be consumed.\n * @param onGesture This lambda is called when [canConsumeGesture] returns true.\n * @param onGestureStart This lambda is called when a gesture starts.\n * @param onGestureEnd This lambda is called when a gesture ends.\n * @param onTap will be called when single tap is detected.\n * @param onDoubleTap will be called when double tap is detected.\n * @param enableOneFingerZoom If true, enable one finger zoom gesture, double tap followed by\n * vertical scrolling.\n */\nprivate suspend fun PointerInputScope.detectTransformGestures(\n    cancelIfZoomCanceled: Boolean,\n    canConsumeGesture: (pan: Offset, zoom: Float) -> Boolean,\n    onGesture: (centroid: Offset, pan: Offset, zoom: Float, timeMillis: Long) -> Unit,\n    onGestureStart: () -> Unit = {},\n    onGestureEnd: () -> Unit = {},\n    onTap: (position: Offset) -> Unit = {},\n    onDoubleTap: (position: Offset) -> Unit = {},\n    enableOneFingerZoom: Boolean = true,\n) = awaitEachGesture {\n    val firstDown = awaitFirstDown(requireUnconsumed = false)\n    onGestureStart()\n\n    var firstUp: PointerInputChange = firstDown\n    var hasMoved = false\n    var isMultiTouch = false\n    var isLongPressed = false\n    var isCanceled = false\n    forEachPointerEventUntilReleased(\n        onCancel = { isCanceled = true },\n    ) { event, isTouchSlopPast ->\n        if (isTouchSlopPast) {\n            val zoomChange = event.calculateZoom()\n            val panChange = event.calculatePan()\n            if (zoomChange != 1f || panChange != Offset.Zero) {\n                val centroid = event.calculateCentroid(useCurrent = true)\n                val timeMillis = event.changes[0].uptimeMillis\n                if (canConsumeGesture(panChange, zoomChange)) {\n                    onGesture(centroid, panChange, zoomChange, timeMillis)\n                    event.consumePositionChanges()\n                }\n            }\n            hasMoved = true\n        }\n        if (event.changes.size > 1) {\n            isMultiTouch = true\n        }\n        firstUp = event.changes[0]\n        val cancelGesture = cancelIfZoomCanceled && isMultiTouch && event.changes.size == 1\n        !cancelGesture\n    }\n\n    if (firstUp.uptimeMillis - firstDown.uptimeMillis > viewConfiguration.longPressTimeoutMillis) {\n        isLongPressed = true\n    }\n\n    val isTap = !hasMoved && !isMultiTouch && !isLongPressed && !isCanceled\n    // Vertical scrolling following a double tap is treated as a zoom gesture.\n    if (isTap) {\n        val secondDown = awaitSecondDown(firstUp)\n        if (secondDown == null) {\n            onTap(firstUp.position)\n        } else {\n            var isDoubleTap = true\n            var isSecondCanceled = false\n            var secondUp: PointerInputChange = secondDown\n            forEachPointerEventUntilReleased(\n                onCancel = { isSecondCanceled = true }\n            ) { event, isTouchSlopPast ->\n                if (isTouchSlopPast) {\n                    if (enableOneFingerZoom) {\n                        val panChange = event.calculatePan()\n                        val zoomChange = 1f + panChange.y * 0.004f\n                        if (zoomChange != 1f) {\n                            val centroid = event.calculateCentroid(useCurrent = true)\n                            val timeMillis = event.changes[0].uptimeMillis\n                            if (canConsumeGesture(Offset.Zero, zoomChange)) {\n                                onGesture(centroid, Offset.Zero, zoomChange, timeMillis)\n                                event.consumePositionChanges()\n                            }\n                        }\n                    }\n                    isDoubleTap = false\n                }\n                if (event.changes.size > 1) {\n                    isDoubleTap = false\n                }\n                secondUp = event.changes[0]\n                true\n            }\n\n            if (secondUp.uptimeMillis - secondDown.uptimeMillis > viewConfiguration.longPressTimeoutMillis) {\n                isDoubleTap = false\n            }\n\n            if (isDoubleTap && !isSecondCanceled) {\n                onDoubleTap(secondUp.position)\n            }\n        }\n    }\n    onGestureEnd()\n}\n\n/**\n * Invoke action for each PointerEvent until all pointers are released.\n *\n * @param onCancel Callback function that will be called if PointerEvents is consumed by other composable.\n * @param action Callback function that will be called every PointerEvents occur.\n */\nprivate suspend fun AwaitPointerEventScope.forEachPointerEventUntilReleased(\n    onCancel: () -> Unit,\n    action: (event: PointerEvent, isTouchSlopPast: Boolean) -> Boolean,\n) {\n    val touchSlop = TouchSlop(viewConfiguration.touchSlop)\n    do {\n        val mainEvent = awaitPointerEvent(pass = PointerEventPass.Main)\n        if (mainEvent.changes.fastAny { it.isConsumed }) {\n            break\n        }\n\n        val isTouchSlopPast = touchSlop.isPast(mainEvent)\n        val canContinue = action(mainEvent, isTouchSlopPast)\n        if (!canContinue) {\n            break\n        }\n        if (isTouchSlopPast) {\n            continue\n        }\n\n        val finalEvent = awaitPointerEvent(pass = PointerEventPass.Final)\n        if (finalEvent.changes.fastAny { it.isConsumed }) {\n            onCancel()\n            break\n        }\n    } while (mainEvent.changes.fastAny { it.pressed })\n}\n\n/**\n * Await second down or timeout from first up\n *\n * @param firstUp The first up event\n * @return If the second down event comes before timeout, returns it. If not, returns null.\n */\nprivate suspend fun AwaitPointerEventScope.awaitSecondDown(\n    firstUp: PointerInputChange\n): PointerInputChange? = withTimeoutOrNull(viewConfiguration.doubleTapTimeoutMillis) {\n    val minUptime = firstUp.uptimeMillis + viewConfiguration.doubleTapMinTimeMillis\n    var change: PointerInputChange\n    // The second tap doesn't count if it happens before DoubleTapMinTime of the first tap\n    do {\n        change = awaitFirstDown()\n    } while (change.uptimeMillis < minUptime)\n    change\n}\n\n/**\n * Consume event if the position is changed.\n */\nprivate fun PointerEvent.consumePositionChanges() {\n    changes.fastForEach {\n        if (it.positionChanged()) {\n            it.consume()\n        }\n    }\n}\n\n/**\n * Touch slop detector.\n *\n * This class holds accumulated zoom and pan value to see if touch slop is past.\n *\n * @param threshold Threshold of movement of gesture after touch down. If the movement exceeds this\n * value, it is judged to be a swipe or zoom gesture.\n */\nprivate class TouchSlop(private val threshold: Float) {\n    private var pan = Offset.Zero\n    private var _isPast = false\n\n    /**\n     * Judge the touch slop is past.\n     *\n     * @param event Event that occurs this time.\n     * @return True if the accumulated zoom or pan exceeds the threshold.\n     */\n    fun isPast(event: PointerEvent): Boolean {\n        if (_isPast) {\n            return true\n        }\n\n        if (event.changes.size > 1) {\n            // If there are two or more fingers, we determine the touch slop is past immediately.\n            _isPast = true\n        } else {\n            pan += event.calculatePan()\n            _isPast = pan.getDistance() > threshold\n        }\n\n        return _isPast\n    }\n}\n\n/**\n * [ScrollGesturePropagation] defines when [Modifier.zoomable] propagates scroll gestures to the\n * parent composable element.\n */\nenum class ScrollGesturePropagation {\n\n    /**\n     * Propagates the scroll gesture to the parent composable element when the content is scrolled\n     * to the edge and attempts to scroll further.\n     */\n    ContentEdge,\n\n    /**\n     * Propagates the scroll gesture to the parent composable element when the content is not zoomed.\n     */\n    NotZoomed,\n}\n\n/**\n * Modifier function that make the content zoomable.\n *\n * @param zoomState A [ZoomState] object.\n * @param zoomEnabled specifies if zoom behaviour is enabled or disabled. Even if this is false,\n * [onTap] and [onDoubleTap] will be called.\n * @param enableOneFingerZoom If true, enable one finger zoom gesture, double tap followed by\n * vertical scrolling.\n * @param scrollGesturePropagation specifies when scroll gestures are propagated to the parent\n * composable element.\n * @param onTap will be called when single tap is detected on the element.\n * @param onDoubleTap will be called when double tap is detected on the element. This is a suspend\n * function and called in a coroutine scope. The default is to toggle the scale between 1.0f and\n * 2.5f with animation.\n */\nfun Modifier.zoomable(\n    zoomState: ZoomState,\n    zoomEnabled: Boolean = true,\n    enableOneFingerZoom: Boolean = true,\n    scrollGesturePropagation: ScrollGesturePropagation = ScrollGesturePropagation.ContentEdge,\n    onTap: (position: Offset) -> Unit = {},\n    onDoubleTap: suspend (position: Offset) -> Unit = { position ->\n        if (zoomEnabled) zoomState.toggleScale(\n            5f,\n            position\n        )\n    },\n): Modifier = this then ZoomableElement(\n    zoomState = zoomState,\n    zoomEnabled = zoomEnabled,\n    enableOneFingerZoom = enableOneFingerZoom,\n    snapBackEnabled = false,\n    scrollGesturePropagation = scrollGesturePropagation,\n    onTap = onTap,\n    onDoubleTap = onDoubleTap,\n)\n\nfun Modifier.snapBackZoomable(\n    zoomState: ZoomState,\n    zoomEnabled: Boolean = true,\n    onTap: (position: Offset) -> Unit = {},\n    onDoubleTap: suspend (position: Offset) -> Unit = {},\n): Modifier = this then ZoomableElement(\n    zoomState = zoomState,\n    zoomEnabled = zoomEnabled,\n    enableOneFingerZoom = false,\n    snapBackEnabled = true,\n    scrollGesturePropagation = ScrollGesturePropagation.NotZoomed,\n    onTap = onTap,\n    onDoubleTap = onDoubleTap,\n)\n\nprivate data class ZoomableElement(\n    val zoomState: ZoomState,\n    val zoomEnabled: Boolean,\n    val enableOneFingerZoom: Boolean,\n    val snapBackEnabled: Boolean,\n    val scrollGesturePropagation: ScrollGesturePropagation,\n    val onTap: (position: Offset) -> Unit,\n    val onDoubleTap: suspend (position: Offset) -> Unit,\n) : ModifierNodeElement<ZoomableNode>() {\n    override fun create(): ZoomableNode = ZoomableNode(\n        zoomState = zoomState,\n        zoomEnabled = zoomEnabled,\n        enableOneFingerZoom = enableOneFingerZoom,\n        snapBackEnabled = snapBackEnabled,\n        scrollGesturePropagation = scrollGesturePropagation,\n        onTap = onTap,\n        onDoubleTap = onDoubleTap,\n    )\n\n    override fun update(node: ZoomableNode) {\n        node.update(\n            zoomState = zoomState,\n            zoomEnabled = zoomEnabled,\n            enableOneFingerZoom = enableOneFingerZoom,\n            snapBackEnabled = snapBackEnabled,\n            scrollGesturePropagation = scrollGesturePropagation,\n            onTap = onTap,\n            onDoubleTap = onDoubleTap,\n        )\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"zoomable\"\n        properties[\"zoomState\"] = zoomState\n        properties[\"zoomEnabled\"] = zoomEnabled\n        properties[\"enableOneFingerZoom\"] = enableOneFingerZoom\n        properties[\"snapBackEnabled\"] = snapBackEnabled\n        properties[\"scrollGesturePropagation\"] = scrollGesturePropagation\n        properties[\"onTap\"] = onTap\n        properties[\"onDoubleTap\"] = onDoubleTap\n    }\n}\n\nprivate class ZoomableNode(\n    var zoomState: ZoomState,\n    var zoomEnabled: Boolean,\n    var enableOneFingerZoom: Boolean,\n    var snapBackEnabled: Boolean,\n    var scrollGesturePropagation: ScrollGesturePropagation,\n    var onTap: (position: Offset) -> Unit,\n    var onDoubleTap: suspend (position: Offset) -> Unit,\n) : PointerInputModifierNode, LayoutModifierNode, DelegatingNode() {\n    var measuredSize = Size.Zero\n\n    fun update(\n        zoomState: ZoomState,\n        zoomEnabled: Boolean,\n        enableOneFingerZoom: Boolean,\n        snapBackEnabled: Boolean,\n        scrollGesturePropagation: ScrollGesturePropagation,\n        onTap: (position: Offset) -> Unit,\n        onDoubleTap: suspend (position: Offset) -> Unit,\n    ) {\n        if (this.zoomState != zoomState) {\n            zoomState.setLayoutSize(measuredSize)\n            this.zoomState = zoomState\n        }\n        this.zoomEnabled = zoomEnabled\n        this.enableOneFingerZoom = enableOneFingerZoom\n        this.scrollGesturePropagation = scrollGesturePropagation\n        this.snapBackEnabled = snapBackEnabled\n        this.onTap = onTap\n        this.onDoubleTap = onDoubleTap\n    }\n\n    val pointerInputNode = delegate(\n        SuspendingPointerInputModifierNode {\n            detectTransformGestures(\n                cancelIfZoomCanceled = snapBackEnabled,\n                onGestureStart = {\n                    resetConsumeGesture()\n                    zoomState.startGesture()\n                },\n                canConsumeGesture = { pan, zoom ->\n                    zoomEnabled && canConsumeGesture(pan, zoom)\n                },\n                onGesture = { centroid, pan, zoom, timeMillis ->\n                    if (zoomEnabled) {\n                        coroutineScope.launch {\n                            zoomState.applyGesture(\n                                pan = pan,\n                                zoom = zoom,\n                                position = centroid,\n                                timeMillis = timeMillis,\n                            )\n                        }\n                    }\n                },\n                onGestureEnd = {\n                    coroutineScope.launch {\n                        if (snapBackEnabled || zoomState.scale < 1f) {\n                            zoomState.changeScale(1f, Offset.Zero)\n                        } else {\n                            zoomState.startFling()\n                        }\n                    }\n                },\n                onTap = onTap,\n                onDoubleTap = { position ->\n                    coroutineScope.launch {\n                        onDoubleTap(position)\n                    }\n                },\n                enableOneFingerZoom = enableOneFingerZoom,\n            )\n        }\n    )\n\n    private var consumeGesture: Boolean? = null\n\n    private fun resetConsumeGesture() {\n        consumeGesture = null\n    }\n\n    private fun canConsumeGesture(pan: Offset, zoom: Float): Boolean {\n        val currentValue = consumeGesture\n        if (currentValue != null) {\n            return currentValue\n        }\n\n        val newValue = when {\n            zoom != 1f -> true\n            zoomState.scale == 1f -> false\n            scrollGesturePropagation == ScrollGesturePropagation.NotZoomed -> true\n            else -> zoomState.willChangeOffset(pan)\n        }\n        consumeGesture = newValue\n        return newValue\n    }\n\n    override fun onPointerEvent(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        bounds: IntSize\n    ) {\n        pointerInputNode.onPointerEvent(pointerEvent, pass, bounds)\n    }\n\n    override fun onCancelPointerInput() {\n        pointerInputNode.onCancelPointerInput()\n    }\n\n    override fun MeasureScope.measure(\n        measurable: Measurable,\n        constraints: Constraints\n    ): MeasureResult {\n        val placeable = measurable.measure(constraints)\n        measuredSize = IntSize(placeable.measuredWidth, placeable.measuredHeight).toSize()\n        zoomState.setLayoutSize(measuredSize)\n        return layout(placeable.width, placeable.height) {\n            placeable.placeWithLayer(x = 0, y = 0) {\n                scaleX = zoomState.scale\n                scaleY = zoomState.scale\n                translationX = zoomState.offsetX\n                translationY = zoomState.offsetY\n            }\n        }\n    }\n}\n\n/**\n * Toggle the scale between [targetScale] and 1.0f.\n *\n * @param targetScale Scale to be set if this function is called when the scale is 1.0f.\n * @param position Zoom around this point.\n * @param animationSpec The animation configuration.\n */\nsuspend fun ZoomState.toggleScale(\n    targetScale: Float,\n    position: Offset,\n    animationSpec: AnimationSpec<Float> = spring(),\n) {\n    val newScale = if (scale == minScale) targetScale else minScale\n    changeScale(newScale, position, animationSpec)\n}"
  },
  {
    "path": "lib/zoomable/src/main/java/net/engawapg/lib/zoomable/ZoomableDefaults.kt",
    "content": "package net.engawapg.lib.zoomable\n\nimport androidx.compose.ui.geometry.Offset\n\nobject ZoomableDefaults {\n\n    val ZoomState.defaultZoomOnDoubleTap: suspend (position: Offset) -> Unit\n        get() = { position -> toggleScale(targetScale = 5f, position = position) }\n\n    val ZoomState.threeLevelZoomOnDoubleTap: suspend (position: Offset) -> Unit\n        get() = { position ->\n            val scale = scale\n            val minScale = minScale\n            val maxScale = maxScale\n            val midScale = (maxScale - minScale) / 2f\n\n            val newScale = when (scale) {\n                in minScale..<midScale -> (maxScale - minScale) / 2f\n                in midScale..<maxScale -> maxScale\n                else -> minScale\n            }\n            changeScale(newScale, position)\n        }\n\n    val DefaultEnabled: (Float, Offset) -> Boolean get() = { _, _ -> true }\n}"
  },
  {
    "path": "settings.gradle.kts",
    "content": "/*\n * ImageToolbox is an image editor for android\n * Copyright (c) 2026 T8RIN (Malik Mukhametzyanov)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * You should have received a copy of the Apache License\n * along with this program.  If not, see <http://www.apache.org/licenses/LICENSE-2.0>.\n */\n\n@file:Suppress(\"UnstableApiUsage\")\n\npluginManagement {\n    repositories {\n        includeBuild(\"build-logic\")\n        gradlePluginPortal()\n        google {\n            content {\n                includeGroupByRegex(\"com\\\\.android.*\")\n                includeGroupByRegex(\"com\\\\.google.*\")\n                includeGroupByRegex(\"androidx.*\")\n            }\n        }\n        mavenCentral()\n        maven(\"https://jitpack.io\") { name = \"JitPack\" }\n    }\n}\ndependencyResolutionManagement {\n    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)\n    repositories {\n        google {\n            content {\n                includeGroupByRegex(\"com\\\\.android.*\")\n                includeGroupByRegex(\"com\\\\.google.*\")\n                includeGroupByRegex(\"androidx.*\")\n            }\n        }\n        maven(\"https://androidx.dev/storage/compose-compiler/repository\") {\n            name = \"Compose Compiler Snapshots\"\n            content { includeGroup(\"androidx.compose.compiler\") }\n        }\n        mavenCentral()\n        maven(\"https://jitpack.io\") { name = \"JitPack\" }\n        maven(\"https://oss.sonatype.org/content/repositories/snapshots/\") {\n            name = \"Sonatype Snapshots\"\n            mavenContent {\n                snapshotsOnly()\n            }\n        }\n    }\n}\nenableFeaturePreview(\"TYPESAFE_PROJECT_ACCESSORS\")\n\nrootProject.name = \"ImageToolbox\"\n\ninclude(\":app\")\n\ninclude(\":feature:main\")\ninclude(\":feature:pick-color\")\ninclude(\":feature:image-stitch\")\ninclude(\":core:filters\")\ninclude(\":feature:filters\")\ninclude(\":feature:draw\")\ninclude(\":feature:erase-background\")\ninclude(\":feature:single-edit\")\ninclude(\":feature:pdf-tools\")\ninclude(\":feature:resize-convert\")\ninclude(\":feature:palette-tools\")\ninclude(\":feature:delete-exif\")\ninclude(\":feature:compare\")\ninclude(\":feature:weight-resize\")\ninclude(\":feature:image-preview\")\ninclude(\":feature:cipher\")\ninclude(\":feature:limits-resize\")\ninclude(\":feature:crop\")\ninclude(\":feature:load-net-image\")\ninclude(\":feature:recognize-text\")\ninclude(\":feature:watermarking\")\ninclude(\":feature:gradient-maker\")\ninclude(\":feature:gif-tools\")\ninclude(\":feature:apng-tools\")\ninclude(\":feature:zip\")\ninclude(\":feature:jxl-tools\")\ninclude(\":feature:media-picker\")\ninclude(\":feature:quick-tiles\")\ninclude(\":feature:settings\")\ninclude(\":feature:easter-egg\")\ninclude(\":feature:svg-maker\")\ninclude(\":feature:format-conversion\")\ninclude(\":feature:document-scanner\")\ninclude(\":feature:scan-qr-code\")\ninclude(\":feature:image-stacking\")\ninclude(\":feature:image-splitting\")\ninclude(\":feature:color-tools\")\ninclude(\":feature:webp-tools\")\ninclude(\":feature:noise-generation\")\ninclude(\":feature:collage-maker\")\ninclude(\":feature:libraries-info\")\ninclude(\":feature:markup-layers\")\ninclude(\":feature:base64-tools\")\ninclude(\":feature:checksum-tools\")\ninclude(\":feature:mesh-gradients\")\ninclude(\":feature:edit-exif\")\ninclude(\":feature:image-cutting\")\ninclude(\":feature:audio-cover-extractor\")\ninclude(\":feature:library-details\")\ninclude(\":feature:wallpapers-export\")\ninclude(\":feature:ascii-art\")\ninclude(\":feature:ai-tools\")\ninclude(\":feature:color-library\")\n\ninclude(\":feature:root\")\n\ninclude(\":core:settings\")\ninclude(\":core:resources\")\ninclude(\":core:data\")\ninclude(\":core:domain\")\ninclude(\":core:ui\")\ninclude(\":core:di\")\ninclude(\":core:crash\")\ninclude(\":core:ksp\")\ninclude(\":core:utils\")\n\ninclude(\":lib:neural-tools\")\ninclude(\":lib:collages\")\ninclude(\":lib:ascii\")\ninclude(\":lib:opencv-tools\")\ninclude(\":lib:documentscanner\")\ninclude(\":lib:snowfall\")\ninclude(\":lib:curves\")\ninclude(\":lib:dynamic-theme\")\ninclude(\":lib:palette\")\ninclude(\":lib:modalsheet\")\ninclude(\":lib:qrose\")\ninclude(\":lib:cropper\")\ninclude(\":lib:colors\")\ninclude(\":lib:gesture\")\ninclude(\":lib:image\")\ninclude(\":lib:zoomable\")\n\ninclude(\":benchmark\")"
  }
]